summaryrefslogtreecommitdiffstats
path: root/src/pybind/mgr/dashboard/frontend
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/pybind/mgr/dashboard/frontend
parentInitial commit. (diff)
downloadceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.tar.xz
ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/pybind/mgr/dashboard/frontend')
-rw-r--r--src/pybind/mgr/dashboard/frontend/.browserslistrc11
-rw-r--r--src/pybind/mgr/dashboard/frontend/.editorconfig13
-rw-r--r--src/pybind/mgr/dashboard/frontend/.gherkin-lintrc33
-rw-r--r--src/pybind/mgr/dashboard/frontend/.gitignore49
-rw-r--r--src/pybind/mgr/dashboard/frontend/.htmllintrc70
-rw-r--r--src/pybind/mgr/dashboard/frontend/.npmrc2
-rw-r--r--src/pybind/mgr/dashboard/frontend/.prettierignore1
-rw-r--r--src/pybind/mgr/dashboard/frontend/.prettierrc6
-rw-r--r--src/pybind/mgr/dashboard/frontend/.stylelintrc43
-rw-r--r--src/pybind/mgr/dashboard/frontend/angular.json227
-rw-r--r--src/pybind/mgr/dashboard/frontend/applitools.config.js21
-rw-r--r--src/pybind/mgr/dashboard/frontend/babel.config.js11
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/cd.js166
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress.json22
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/fixtures/block-rbd-status.json1
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/fixtures/nfs-ganesha-status.json4
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/fixtures/orchestrator/inventory.json390
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/fixtures/orchestrator/services.json523
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/fixtures/rgw-status.json1
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/block/images.e2e-spec.ts95
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/block/images.po.ts110
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/block/iscsi.e2e-spec.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/block/iscsi.po.ts7
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/block/mirroring.e2e-spec.ts54
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/block/mirroring.po.ts35
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/configuration.e2e-spec.ts78
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/configuration.po.ts75
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/create-cluster.po.ts56
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/crush-map.e2e-spec.ts37
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/crush-map.po.ts13
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/hosts.e2e-spec.ts35
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/hosts.po.ts184
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/inventory.po.ts22
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/logs.e2e-spec.ts58
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/logs.po.ts70
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/mgr-modules.e2e-spec.ts78
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/mgr-modules.po.ts57
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/monitors.e2e-spec.ts62
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/monitors.po.ts7
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/osds.e2e-spec.ts57
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/osds.po.ts84
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/services.po.ts204
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/common/01-global.feature.po.ts188
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/common/create-cluster/create-cluster.feature.po.ts12
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/common/grafana.feature.po.ts86
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/common/urls.po.ts44
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/filesystems/filesystems.e2e-spec.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/filesystems/filesystems.po.ts5
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/01-hosts.e2e-spec.ts86
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/03-inventory.e2e-spec.ts26
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/04-osds.e2e-spec.ts50
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/05-services.e2e-spec.ts36
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/grafana/grafana.feature63
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/01-create-cluster-welcome.feature26
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/02-create-cluster-add-host.feature74
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/03-create-cluster-create-services.e2e-spec.ts47
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/04-create-cluster-create-osds.e2e-spec.ts41
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/05-create-cluster-review.e2e-spec.ts67
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/06-cluster-check.e2e-spec.ts99
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/07-osds.e2e-spec.ts24
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/08-hosts.e2e-spec.ts49
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/09-services.e2e-spec.ts114
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/10-nfs-exports.e2e-spec.ts83
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/nfs/nfs-export.po.ts52
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/page-helper.po.ts309
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/pools/pools.e2e-spec.ts54
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/pools/pools.po.ts70
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/buckets.e2e-spec.ts62
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/buckets.po.ts193
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/daemons.e2e-spec.ts35
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/daemons.po.ts34
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/users.e2e-spec.ts46
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/users.po.ts139
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/ui/api-docs.e2e-spec.ts15
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/ui/api-docs.po.ts5
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/ui/dashboard.e2e-spec.ts124
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/ui/dashboard.po.ts31
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/ui/language.e2e-spec.ts20
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/ui/language.po.ts15
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/ui/login.e2e-spec.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/ui/login.po.ts22
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/ui/navigation.e2e-spec.ts24
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/ui/navigation.po.ts69
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/ui/notification.e2e-spec.ts59
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/ui/notification.po.ts45
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/ui/role-mgmt.e2e-spec.ts37
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/ui/role-mgmt.po.ts40
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/ui/user-mgmt.e2e-spec.ts37
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/ui/user-mgmt.po.ts39
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/visualTests/dashboard.vrt-spec.ts22
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/integration/visualTests/login.vrt-spec.ts19
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/plugins/index.js26
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/support/commands.ts59
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/support/eyes-index.d.ts1
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/support/index.ts11
-rw-r--r--src/pybind/mgr/dashboard/frontend/cypress/tsconfig.json16
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/117.9781bbf8cc6a4aaa7e8e.js1
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/281.0d0cd268ddc6a6760dd4.js1
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/3rdpartylicenses.txt3508
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/483.f42c1d67e206231ecdac.js1
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/Ceph_Logo.487a0001b327fa7f5232.svg71
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Ceph_Logo_with_text_red_white.svg69
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Ceph_Logo_with_text_white.svg69
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo.svg71
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/assets/ceph_background.gifbin0 -> 98115 bytes
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/dist/en-US/assets/loading.gifbin0 -> 35386 bytes
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/assets/logo-mini.pngbin0 -> 1811 bytes
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/assets/prometheus_logo.svg50
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/ceph_background.e82dd79127290ddbe8cb.gifbin0 -> 98115 bytes
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/favicon.icobin0 -> 1150 bytes
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.2dfb5f36fc148e26e398.woffbin0 -> 115148 bytes
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.7c20758e3e7c7dff7c8d.woff2bin0 -> 91624 bytes
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.86541105409e56d17291.svg2849
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.e182ad6df04f9177b326.eotbin0 -> 188946 bytes
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.ee4d8bfd0af89fc714a2.ttfbin0 -> 188756 bytes
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/index.html23
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/main.c3b711a3156fe72f66f4.js3
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/polyfills.2068f3f22a496426465b.js1
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/prometheus_logo.8b3183e5a2db0e87bb2b.svg50
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/runtime.dfeb6a20b4d203b567dc.js1
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/scripts.6bda3fa7e09a87cd4228.js7
-rw-r--r--src/pybind/mgr/dashboard/frontend/dist/en-US/styles.f05c06a6a64f4730faae.css20
-rw-r--r--src/pybind/mgr/dashboard/frontend/html-linter.config.json12
-rw-r--r--src/pybind/mgr/dashboard/frontend/i18n.config.json12
-rw-r--r--src/pybind/mgr/dashboard/frontend/ngcc.config.js10
-rw-r--r--src/pybind/mgr/dashboard/frontend/package-lock.json28313
-rw-r--r--src/pybind/mgr/dashboard/frontend/package.json157
-rw-r--r--src/pybind/mgr/dashboard/frontend/proxy.conf.json.sample12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/app-routing.module.ts392
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/app.component.html1
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/app.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/app.component.spec.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/app.component.ts18
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/app.module.ts51
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts205
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.html57
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.spec.ts37
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.ts31
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html14
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.spec.ts28
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.ts11
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html41
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.spec.ts207
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts346
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html132
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.spec.ts133
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts123
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html692
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.scss3
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.spec.ts593
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts822
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html92
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.spec.ts98
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.ts87
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html32
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.spec.ts71
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.ts60
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html53
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.spec.ts309
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts242
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.html49
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.spec.ts83
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.ts117
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html87
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.scss3
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.spec.ts113
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.ts153
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html96
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.spec.ts131
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.ts187
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.html13
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.spec.ts28
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts62
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.html63
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.spec.ts36
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.ts99
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirror-health-color.pipe.spec.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirror-health-color.pipe.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirroring.module.ts42
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.html66
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.spec.ts79
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.ts122
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html44
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.spec.ts86
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts111
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-response.model.ts3
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html100
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.spec.ts148
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.ts141
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-response.model.ts7
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.html23
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.spec.ts37
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.ts174
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html74
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.scss4
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.spec.ts294
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.ts166
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html29
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.spec.ts99
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts65
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html180
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.spec.ts30
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.ts31
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-feature.interface.ts9
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-clone-request.model.ts13
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-copy-request.model.ts14
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-create-request.model.ts5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-edit-request.model.ts14
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-mode.enum.ts5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-response.model.ts7
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.html395
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.spec.ts480
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts815
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.model.ts26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-parent.model.ts6
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.html128
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.scss5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.spec.ts438
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.ts629
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-model.ts15
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html79
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.spec.ts39
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts144
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.html18
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.spec.ts41
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts157
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.html6
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.spec.ts30
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.ts8
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html41
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.spec.ts62
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts137
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts131
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.spec.ts305
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts336
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot.model.ts9
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.html23
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.spec.ts27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.ts19
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html52
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.spec.ts172
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts225
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html57
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.spec.ts94
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.ts94
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html46
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.spec.ts105
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.ts74
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html41
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.spec.ts81
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.ts65
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/ceph.module.ts23
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.html12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.scss8
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.spec.ts81
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.ts196
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.html13
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.spec.ts83
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts102
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html42
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.scss3
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.spec.ts55
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts91
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html75
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.scss17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.spec.ts1111
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts733
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.html14
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.spec.ts35
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts61
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html47
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.spec.ts215
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.ts130
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs.module.ts28
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/cluster.module.ts123
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html105
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.scss0
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.spec.ts26
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts29
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form-create-request.model.ts4
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html160
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.scss12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.spec.ts106
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts172
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.html26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.scss16
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.spec.ts46
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.ts149
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.html54
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.scss5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.spec.ts29
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.ts72
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.html98
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.scss22
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.spec.ts154
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.ts231
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.html39
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.scss3
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.spec.ts137
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.ts122
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/fixtures/host_list_response.json32
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.html59
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.spec.ts68
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.ts20
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.html107
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.spec.ts168
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.ts171
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.html77
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.spec.ts419
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts535
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/fixtures/inventory_list_response.json324
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-device.model.ts20
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.html16
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.scss12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.spec.ts194
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts254
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-host.model.ts6
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.html14
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.spec.ts67
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.ts90
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.html159
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.scss54
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.spec.ts169
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.ts157
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.html4
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.spec.ts27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html110
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.spec.ts80
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts135
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.html20
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.spec.ts155
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts198
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-modules.module.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.html61
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.spec.ts105
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.ts74
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html20
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.spec.ts38
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.ts62
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.html67
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.spec.ts31
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.ts44
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/devices-selection-change-event.interface.ts5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/devices-selection-clear-event.interface.ts6
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html51
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.scss3
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.spec.ts125
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts135
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html42
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.spec.ts109
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.ts92
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html48
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.spec.ts353
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts134
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html41
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.spec.ts99
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts156
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/drive-group.model.ts97
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-feature.interface.ts4
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.html213
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.spec.ts309
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.ts285
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/fixtures/osd_list_response.json605
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.html150
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.spec.ts641
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.ts624
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html45
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.spec.ts64
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts68
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.options.ts36
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html92
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.scss0
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts317
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts238
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html38
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.spec.ts56
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.ts43
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html22
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.spec.ts50
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts52
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html41
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.spec.ts103
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts101
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-list-helper.ts24
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html18
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.spec.ts27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.ts11
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html22
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.spec.ts40
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts44
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html224
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.scss3
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.spec.ts598
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts340
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html34
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.spec.ts140
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts191
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html85
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.spec.ts209
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.ts107
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/placement.pipe.spec.ts78
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/placement.pipe.ts41
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html102
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.scss14
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.spec.ts253
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts347
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-details/service-details.component.html4
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-details/service-details.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-details/service-details.component.spec.ts43
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-details/service-details.component.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.html696
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.spec.ts550
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts678
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.html25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.spec.ts97
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.ts259
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.html322
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.spec.ts188
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.ts244
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard.module.ts43
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.html28
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.scss3
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.spec.ts28
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.ts10
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.html16
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.scss22
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.spec.ts75
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.ts198
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html237
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.scss41
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.spec.ts348
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.ts278
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card-popover.scss42
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.html18
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss40
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.spec.ts65
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.html26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.scss8
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.spec.ts35
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.ts14
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-summary.pipe.spec.ts72
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-summary.pipe.ts78
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-summary.pipe.spec.ts52
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-summary.pipe.ts48
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.spec.ts40
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-summary.pipe.spec.ts193
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-summary.pipe.ts91
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/models/nfs.fsal.ts5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.html32
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.spec.ts102
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.ts68
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html109
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.spec.ts71
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts95
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html400
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.scss11
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.spec.ts238
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts535
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.html30
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.spec.ts195
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.ts199
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs.module.ts26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter.module.ts14
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.html4
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.spec.ts29
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html15
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.spec.ts62
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts72
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html123
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.spec.ts210
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts108
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html420
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.spec.ts688
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts459
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.html51
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.spec.ts171
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.ts80
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form-data.ts37
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.html609
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.spec.ts1466
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.ts919
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.html57
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.scss19
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.spec.ts518
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.ts332
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-stat.ts16
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool.module.ts57
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool.ts73
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-bucket-mfa-delete.ts4
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-bucket-versioning.ts4
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-daemon.ts10
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-capabilities.ts15
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-capability.ts4
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-s3-key.ts6
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-subuser.ts6
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-swift-key.ts4
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html127
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.scss7
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.spec.ts42
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.ts24
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html291
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.spec.ts300
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts264
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html44
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.spec.ts178
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts188
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html38
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.spec.ts42
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.ts46
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html46
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.spec.ts106
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts82
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html70
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.spec.ts30
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts92
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html178
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.spec.ts94
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts120
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html668
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.spec.ts339
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts756
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html44
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.spec.ts166
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts180
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html125
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.spec.ts30
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts84
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html128
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.spec.ts71
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts130
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html54
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.spec.ts31
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts30
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw.module.ts108
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/ceph-shared.module.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/device-list/device-list.component.html26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/device-list/device-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/device-list/device-list.component.spec.ts26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/device-list/device-list.component.ts84
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/pg-category.model.ts71
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/pg-category.service.spec.ts56
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/pg-category.service.ts63
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/fixtures/smart_data_version_1_0_ata_response.json570
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/fixtures/smart_data_version_1_0_nvme_response.json134
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/fixtures/smart_data_version_1_0_scsi_response.json208
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.html110
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.spec.ts264
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.ts212
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/auth.module.ts87
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.html95
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.scss68
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.spec.ts77
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.ts51
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.html64
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.scss54
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.spec.ts58
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.ts76
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.html11
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.scss9
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.spec.ts67
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.ts79
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form-mode.enum.ts3
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.html121
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.scss4
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.spec.ts222
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.ts315
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.model.ts5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.html21
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.spec.ts83
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.ts169
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form-mode.enum.ts3
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form-role.model.ts14
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.html263
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.spec.ts258
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.ts305
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.model.ts10
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.html22
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.spec.ts82
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.ts164
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-password-form/user-password-form.component.html121
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-password-form/user-password-form.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-password-form/user-password-form.component.spec.ts83
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-password-form/user-password-form.component.ts119
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.html14
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.spec.ts29
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.ts13
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/context/context.component.html27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/context/context.component.scss5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/context/context.component.spec.ts100
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/context/context.component.ts70
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/core.module.ts34
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.html63
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.scss18
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.spec.ts49
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.ts96
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/error/error.ts27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/layouts/blank-layout/blank-layout.component.html1
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/layouts/blank-layout/blank-layout.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/layouts/blank-layout/blank-layout.component.spec.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/layouts/blank-layout/blank-layout.component.ts8
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.html34
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.scss61
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.spec.ts28
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.ts14
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.html10
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.scss12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.spec.ts35
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.ts39
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.html47
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.scss43
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.spec.ts60
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.ts70
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.html22
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.spec.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.ts22
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/api-docs/api-docs.component.html3
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/api-docs/api-docs.component.scss7
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/api-docs/api-docs.component.ts18
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.html11
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.scss12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.spec.ts131
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.ts141
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.html25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.spec.ts27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.ts31
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.html27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.spec.ts27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.ts27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation.module.ts43
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.html272
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.scss263
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.spec.ts237
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.ts123
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.html11
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.scss27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.spec.ts58
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.ts47
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/api-client.spec.ts11
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/api-client.ts5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/auth.service.spec.ts57
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/auth.service.ts53
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/ceph-service.service.ts63
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/cephfs.service.spec.ts98
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/cephfs.service.ts76
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/cluster.service.spec.ts42
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/cluster.service.ts27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/configuration.service.spec.ts99
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/configuration.service.ts59
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/crush-rule.service.spec.ts47
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/crush-rule.service.ts32
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/custom-login-banner.service.spec.ts35
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/custom-login-banner.service.ts15
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/daemon.service.spec.ts39
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/daemon.service.ts28
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/erasure-code-profile.service.spec.ts55
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/erasure-code-profile.service.ts110
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/health.service.spec.ts40
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/health.service.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/host.service.spec.ts91
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/host.service.ts154
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/iscsi.service.spec.ts97
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/iscsi.service.ts60
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/logging.service.spec.ts39
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/logging.service.ts18
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/logs.service.spec.ts34
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/logs.service.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/mgr-module.service.spec.ts66
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/mgr-module.service.ts65
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/monitor.service.spec.ts34
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/monitor.service.ts13
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/motd.service.spec.ts34
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/motd.service.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/nfs.service.spec.ts74
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/nfs.service.ts108
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/orchestrator.service.spec.ts35
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/orchestrator.service.ts46
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/osd.service.spec.ts183
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/osd.service.ts190
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/performance-counter.service.spec.ts45
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/performance-counter.service.ts29
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/pool.service.spec.ts123
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/pool.service.ts74
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/prometheus.service.spec.ts247
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/prometheus.service.ts82
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd-mirroring.service.spec.ts164
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd-mirroring.service.ts114
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.model.ts30
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.spec.ts181
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.ts198
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-bucket.service.spec.ts102
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-bucket.service.ts128
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-daemon.service.spec.ts90
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-daemon.service.ts82
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-site.service.spec.ts43
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-site.service.ts38
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-user.service.spec.ts170
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-user.service.ts179
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/role.service.spec.ts75
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/role.service.ts49
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/scope.service.spec.ts34
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/scope.service.ts13
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/settings.service.spec.ts154
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/settings.service.ts77
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/telemetry.service.spec.ts58
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/telemetry.service.ts23
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/user.service.spec.ts104
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/api/user.service.ts62
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/classes/cd-helper.class.spec.ts66
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/classes/cd-helper.class.ts28
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/classes/crush.node.selection.class.spec.ts220
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/classes/crush.node.selection.class.ts221
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/classes/css-helper.ts5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/classes/list-with-details.class.ts29
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status-view-cache.spec.ts40
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status-view-cache.ts37
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status.spec.ts15
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status.ts3
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.html42
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.scss12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.spec.ts26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.ts70
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.html5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.spec.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.ts24
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts132
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.html77
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.scss10
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.spec.ts295
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.ts120
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.model.ts12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.types.spec.ts272
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.types.ts147
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.html27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.spec.ts185
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.ts65
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html7
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.spec.ts65
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.ts55
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html55
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.scss11
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.spec.ts235
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.ts63
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/custom-login-banner/custom-login-banner.component.html2
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/custom-login-banner/custom-login-banner.component.scss5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/custom-login-banner/custom-login-banner.component.spec.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/custom-login-banner/custom-login-banner.component.ts20
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/date-time-picker/date-time-picker.component.html13
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/date-time-picker/date-time-picker.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/date-time-picker/date-time-picker.component.spec.ts58
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/date-time-picker/date-time-picker.component.ts67
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.html2
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.spec.ts27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.ts28
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.html23
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.spec.ts39
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.ts31
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-button-panel/form-button-panel.component.html11
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-button-panel/form-button-panel.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-button-panel/form-button-panel.component.spec.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-button-panel/form-button-panel.component.ts59
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.html69
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.scss0
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.spec.ts149
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.ts110
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.html78
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.scss33
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.spec.ts81
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.ts201
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.html11
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.scss7
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.spec.ts26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.ts18
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.html17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.spec.ts85
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.ts40
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/supported-languages.enum.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.html9
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.spec.ts26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.ts12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.html19
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.scss23
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.spec.ts54
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.ts31
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/motd/motd.component.html8
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/motd/motd.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/motd/motd.component.spec.ts26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/motd/motd.component.ts33
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html131
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.scss68
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.spec.ts194
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.ts167
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html10
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.spec.ts29
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.ts13
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html16
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.scss3
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.spec.ts107
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.ts55
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.html19
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.spec.ts27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.ts32
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.html22
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.scss9
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.spec.ts57
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.ts35
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select-messages.model.ts23
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select-option.model.ts13
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.html79
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.scss26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.spec.ts276
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.ts149
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.html15
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.scss5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.spec.ts52
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.ts130
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.html11
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.spec.ts27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.ts99
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.html12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.scss17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.spec.ts107
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.ts62
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.html27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.scss35
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.spec.ts27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.ts43
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/wizard/wizard.component.html19
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/wizard/wizard.component.scss34
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/wizard/wizard.component.spec.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/components/wizard/wizard.component.ts39
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/constants/app.constants.ts305
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/datatable.module.ts31
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.html43
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.scss8
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.spec.ts213
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.ts161
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.html12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.scss0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.spec.ts351
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.ts224
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html327
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.scss295
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.spec.ts799
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts927
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/decorators/cd-encode.spec.ts41
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/decorators/cd-encode.ts80
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/autofocus.directive.spec.ts90
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/autofocus.directive.ts28
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.spec.ts12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.ts132
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary.directive.spec.ts12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary.directive.ts122
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/directives.module.ts53
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.spec.ts75
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.ts27
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-loading.directive.spec.ts89
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-loading.directive.ts51
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-scope.directive.spec.ts8
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-scope.directive.ts8
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/iops.directive.spec.ts8
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/iops.directive.ts31
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/milliseconds.directive.spec.ts8
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/milliseconds.directive.ts31
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-control.directive.spec.ts37
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-control.directive.ts82
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-group.directive.spec.ts37
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-group.directive.ts76
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-validation.directive.spec.ts35
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-validation.directive.ts62
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/password-button.directive.spec.ts8
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/password-button.directive.ts45
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/stateful-tab.directive.spec.ts28
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/stateful-tab.directive.ts31
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/trim.directive.spec.ts50
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/trim.directive.ts21
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/enum/cell-template.enum.ts54
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/enum/components.enum.ts9
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/enum/health-color.enum.ts5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/enum/icons.enum.ts84
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/enum/notification-type.enum.ts5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/enum/unix_errno.enum.ts4
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/enum/view-cache-status.enum.ts6
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-builder.spec.ts33
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-builder.ts20
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-group.spec.ts184
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-group.ts75
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form.spec.ts32
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form.ts26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-validators.spec.ts906
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-validators.ts612
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/alertmanager-silence.ts23
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/breadcrumbs.ts59
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-form-modal-field-config.ts32
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-notification.spec.ts95
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-notification.ts48
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-pwd-expiration-settings.ts11
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-pwd-policy-settings.ts23
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-action.ts44
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-column-filter.ts7
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-column-filters-change.ts22
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-column.ts38
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-fetch-data-context.ts44
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-paging.ts20
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-selection.ts45
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-user-config.ts11
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/cephfs-directory-models.ts21
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/chart-tooltip.ts115
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/configuration.ts43
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/credentials.ts4
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/crush-node.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/crush-rule.ts18
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/crush-step.ts7
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/daemon.interface.ts12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/devices.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/erasure-code-profile.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/executing-task.ts6
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/finished-task.ts15
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/flag.ts8
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/image-spec.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/inventory-device-type.model.ts9
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/login-response.ts7
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/mirroring-summary.ts5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/orchestrator.enum.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/orchestrator.interface.ts9
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/osd-deployment-options.ts24
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/osd-settings.ts4
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/permission.spec.ts62
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/permissions.ts50
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/pool-form-info.ts20
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/prometheus-alerts.ts84
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/service.interface.ts45
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/smart.ts253
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/summary.model.ts15
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/task-exception.ts9
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/task.ts10
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/models/wizard-steps.ts4
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/shared/pipes/array.pipe.spec.ts21
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/shared/pipes/array.pipe.ts26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean-text.pipe.spec.ts37
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean-text.pipe.ts14
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean.pipe.spec.ts57
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean.pipe.ts26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/cd-date.pipe.spec.ts24
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/cd-date.pipe.ts20
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-release-name.pipe.spec.ts28
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-release-name.pipe.ts24
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-short-version.pipe.spec.ts21
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-short-version.pipe.ts18
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless-binary-per-second.pipe.ts24
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless-binary.pipe.spec.ts56
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless-binary.pipe.ts24
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.spec.ts56
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.ts14
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/duration.pipe.spec.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/duration.pipe.ts37
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/empty.pipe.spec.ts18
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/empty.pipe.ts12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/encode-uri.pipe.spec.ts13
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/encode-uri.pipe.ts10
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/filter.pipe.spec.ts54
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/filter.pipe.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-color.pipe.spec.ts47
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-color.pipe.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iops.pipe.spec.ts8
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iops.pipe.ts10
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iscsi-backstore.pipe.spec.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iscsi-backstore.pipe.ts15
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/join.pipe.spec.ts13
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/join.pipe.ts10
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/log-priority.pipe.spec.ts32
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/log-priority.pipe.ts20
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/map.pipe.spec.ts25
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/map.pipe.ts15
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/milliseconds.pipe.spec.ts8
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/milliseconds.pipe.ts10
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/not-available.pipe.spec.ts30
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/not-available.pipe.ts15
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ordinal.pipe.spec.ts8
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ordinal.pipe.ts25
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/app/shared/pipes/pipes.module.ts125
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/rbd-configuration-source.pipe.spec.ts22
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/rbd-configuration-source.pipe.ts15
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/relative-date.pipe.spec.ts44
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/relative-date.pipe.ts57
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/round.pipe.spec.ts13
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/round.pipe.ts12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/sanitize-html.pipe.spec.ts26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/sanitize-html.pipe.ts13
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/search-highlight.pipe.spec.ts41
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/search-highlight.pipe.ts26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/truncate.pipe.spec.ts21
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/truncate.pipe.ts16
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/upper-first.pipe.spec.ts17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/upper-first.pipe.ts12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/rxjs/operators/page-visibilty.operator.ts20
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/api-interceptor.service.spec.ts227
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/api-interceptor.service.ts133
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-guard.service.spec.ts54
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-guard.service.ts29
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-storage.service.spec.ts47
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-storage.service.ts59
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/cd-table-server-side.service.spec.ts16
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/cd-table-server-side.service.ts14
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/change-password-guard.service.spec.ts68
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/change-password-guard.service.ts42
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/device.service.spec.ts92
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/device.service.ts57
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.spec.ts75
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.ts65
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/favicon.service.spec.ts23
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/favicon.service.ts79
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles-guard.service.spec.ts72
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles-guard.service.ts30
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles.service.spec.ts54
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles.service.ts37
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.spec.ts90
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.ts77
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/js-error-handler.service.ts33
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/language.service.spec.ts34
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/language.service.ts23
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/modal.service.spec.ts59
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/modal.service.ts28
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/module-status-guard.service.spec.ts102
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/module-status-guard.service.ts101
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/motd-notification.service.spec.ts117
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/motd-notification.service.ts84
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/ngzone-scheduler.service.ts48
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/no-sso-guard.service.spec.ts49
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/no-sso-guard.service.ts28
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/notification.service.spec.ts285
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/notification.service.ts237
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/password-policy.service.spec.ts208
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/password-policy.service.ts65
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert-formatter.spec.ts95
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert-formatter.ts74
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert.service.spec.ts214
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert.service.ts100
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-notification.service.spec.ts227
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-notification.service.ts51
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-silence-matcher.service.spec.ts133
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-silence-matcher.service.ts78
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/rbd-configuration.service.spec.ts45
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/rbd-configuration.service.ts144
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/refresh-interval.service.spec.ts52
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/refresh-interval.service.ts46
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/summary.service.spec.ts179
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/summary.service.ts89
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.spec.ts133
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.ts111
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-manager.service.spec.ts72
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-manager.service.ts59
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.spec.ts312
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.ts424
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-wrapper.service.spec.ts98
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-wrapper.service.ts68
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/telemetry-notification.service.spec.ts33
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/telemetry-notification.service.ts16
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/text-to-download.service.spec.ts20
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/text-to-download.service.ts12
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/time-diff.service.spec.ts71
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/time-diff.service.ts55
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/timer.service.spec.ts68
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/timer.service.ts29
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/url-builder.service.spec.ts37
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/url-builder.service.ts50
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/wizard-steps.service.spec.ts16
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/wizard-steps.service.ts58
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/shared.module.ts19
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/assets/.gitkeep0
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/assets/Ceph_Ceph_Logo_with_text_red_white.svg69
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/assets/Ceph_Ceph_Logo_with_text_white.svg69
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/assets/Ceph_Logo.svg71
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/assets/ceph_background.gifbin0 -> 98115 bytes
-rwxr-xr-xsrc/pybind/mgr/dashboard/frontend/src/assets/loading.gifbin0 -> 35386 bytes
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/assets/logo-mini.pngbin0 -> 1811 bytes
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/assets/prometheus_logo.svg50
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/environments/environment.tpl.ts10
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/favicon.icobin0 -> 1150 bytes
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/index.html24
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/jestGlobalMocks.ts7
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/locale/messages.cs.xlf14162
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/locale/messages.de-DE.xlf14885
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/locale/messages.es-ES.xlf14886
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/locale/messages.fr-FR.xlf14885
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/locale/messages.id-ID.xlf14069
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/locale/messages.it-IT.xlf14885
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/locale/messages.ja-JP.xlf14882
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/locale/messages.ko-KR.xlf14562
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/locale/messages.pl-PL.xlf14066
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/locale/messages.pt-BR.xlf14885
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/locale/messages.zh-CN.xlf14881
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/locale/messages.zh-TW.xlf14884
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/main.ts23
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/polyfills.ts54
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/setupJest.ts11
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles.scss138
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/_chart-tooltip.scss59
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/bootstrap-extends.scss129
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_basics.scss131
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_buttons.scss80
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_dropdown.scss35
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_forms.scss86
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_grid.scss6
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_icons.scss16
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_index.scss5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_navs.scss5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_toast.scss30
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/defaults/_bootstrap-defaults.scss111
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/defaults/_functions.scss5
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/defaults/_index.scss4
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/defaults/_mixins.scss34
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/vendor/_index.scss22
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/vendor/_style-overrides.scss4
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/styles/vendor/_variables.scss17
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/testing/activated-route-stub.ts26
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/testing/unit-test-helper.ts692
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/typings.d.ts5
-rw-r--r--src/pybind/mgr/dashboard/frontend/tsconfig.app.json14
-rw-r--r--src/pybind/mgr/dashboard/frontend/tsconfig.json42
-rw-r--r--src/pybind/mgr/dashboard/frontend/tsconfig.spec.json21
-rw-r--r--src/pybind/mgr/dashboard/frontend/tslint.json118
1221 files changed, 307382 insertions, 0 deletions
diff --git a/src/pybind/mgr/dashboard/frontend/.browserslistrc b/src/pybind/mgr/dashboard/frontend/.browserslistrc
new file mode 100644
index 000000000..5f47eea2c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/.browserslistrc
@@ -0,0 +1,11 @@
+# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
+# For additional information regarding the format and rule options, please see:
+# https://github.com/browserslist/browserslist#queries
+
+# You can see what browsers were selected by your queries by running:
+# npx browserslist
+
+last 2 Chrome versions
+last 2 Firefox versions
+Firefox ESR
+not dead
diff --git a/src/pybind/mgr/dashboard/frontend/.editorconfig b/src/pybind/mgr/dashboard/frontend/.editorconfig
new file mode 100644
index 000000000..6e87a003d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/.editorconfig
@@ -0,0 +1,13 @@
+# Editor configuration, see http://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+max_line_length = off
+trim_trailing_whitespace = false
diff --git a/src/pybind/mgr/dashboard/frontend/.gherkin-lintrc b/src/pybind/mgr/dashboard/frontend/.gherkin-lintrc
new file mode 100644
index 000000000..706b93bea
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/.gherkin-lintrc
@@ -0,0 +1,33 @@
+{
+ "no-files-without-scenarios" : "on",
+ "no-unnamed-features": "on",
+ "no-unnamed-scenarios": "on",
+ "no-dupe-scenario-names": ["on", "in-feature"],
+ "no-dupe-feature-names": "on",
+ "no-partially-commented-tag-lines": "on",
+ "indentation": ["on", {
+ "Feature": 0,
+ "Background": 4,
+ "Scenario": 4,
+ "Step": 8,
+ "Examples": 8,
+ "example": 12
+ }],
+ "no-trailing-spaces": "on",
+ "new-line-at-eof": ["on", "yes"],
+ "no-multiple-empty-lines": "on",
+ "no-empty-file": "on",
+ "no-scenario-outlines-without-examples": "on",
+ "name-length": "off",
+ "no-restricted-tags": ["on", {"tags": ["@watch", "@wip"]}],
+ "use-and": "off",
+ "no-duplicate-tags": "on",
+ "no-superfluous-tags": "on",
+ "no-homogenous-tags": "on",
+ "one-space-between-tags": "on",
+ "no-unused-variables": "on",
+ "no-background-only-scenario": "off",
+ "no-empty-background": "on",
+ "no-examples-in-scenarios": "on",
+ "scenario-size": ["on", { "steps-length": {"Background": 3, "Scenario": 15}}]
+}
diff --git a/src/pybind/mgr/dashboard/frontend/.gitignore b/src/pybind/mgr/dashboard/frontend/.gitignore
new file mode 100644
index 000000000..4aaf66910
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/.gitignore
@@ -0,0 +1,49 @@
+# See http://help.github.com/ignore-files/ for more about ignoring files.
+
+# compiled output
+/dist
+/tmp
+/out-tsc
+
+# dependencies
+/node_modules
+
+# IDEs and editors
+.project
+.classpath
+.c9/
+*.launch
+.settings/
+*.sublime-workspace
+
+# IDE - VSCode
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+
+# misc
+/.sass-cache
+/connect.lock
+/coverage
+/libpeerconnection.log
+npm-debug.log
+testem.log
+/typings
+
+# e2e
+/cypress/screenshots
+/cypress/videos
+/cypress/reports
+
+# System Files
+.DS_Store
+Thumbs.db
+
+# Package lock files
+yarn.lock
+
+# Ceph
+!core
+!*.core
diff --git a/src/pybind/mgr/dashboard/frontend/.htmllintrc b/src/pybind/mgr/dashboard/frontend/.htmllintrc
new file mode 100644
index 000000000..b06d7e7b6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/.htmllintrc
@@ -0,0 +1,70 @@
+{
+ "plugins": [], // npm modules to load
+
+ "maxerr": false,
+ "raw-ignore-regex": false,
+ "attr-bans": [
+ "align",
+ "background",
+ "bgcolor",
+ "border",
+ "longdesc",
+ "marginwidth",
+ "marginheight",
+ "style",
+ "width"
+ ],
+ "indent-delta": false,
+ "indent-style": "spaces",
+ "indent-width": 2,
+ "indent-width-cont": true,
+ "spec-char-escape": false,
+ "text-ignore-regex": false,
+ "tag-bans": [
+ "style"
+ ],
+ "tag-close": true,
+ "tag-name-lowercase": true,
+ "tag-name-match": true,
+ "tag-self-close": false,
+ "doctype-first": false,
+ "doctype-html5": false,
+ "attr-name-style": false,
+ "attr-name-ignore-regex": false,
+ "attr-no-dup": true,
+ "attr-no-unsafe-char": true,
+ "attr-order": false,
+ "attr-quote-style": "double",
+ "attr-req-value": false,
+ "attr-new-line": 1,
+ "attr-validate": true,
+ "id-no-dup": false,
+ "id-class-no-ad": true,
+ "id-class-style": false,
+ "class-no-dup": true,
+ "class-style": "none",
+ "id-class-ignore-regex": "{{.*?}}",
+ "img-req-alt": false,
+ "img-req-src": true,
+ "html-valid-content-model": true,
+ "head-valid-content-model": true,
+ "href-style": false,
+ "link-req-noopener": false,
+ "label-req-for": false,
+ "line-end-style": "lf",
+ "line-no-trailing-whitespace": true,
+ "line-max-len": false,
+ "line-max-len-ignore-regex": false,
+ "head-req-title": true,
+ "title-no-dup": true,
+ "title-max-len": 60,
+ "html-req-lang": false,
+ "lang-style": "case",
+ "fig-req-figcaption": false,
+ "focusable-tabindex-style": false,
+ "input-radio-req-name": false,
+ "input-req-label": false,
+ "table-req-caption": false,
+ "table-req-header": false,
+ "tag-req-attr": false
+}
diff --git a/src/pybind/mgr/dashboard/frontend/.npmrc b/src/pybind/mgr/dashboard/frontend/.npmrc
new file mode 100644
index 000000000..ce9882e34
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/.npmrc
@@ -0,0 +1,2 @@
+audit=false
+save-exact=true
diff --git a/src/pybind/mgr/dashboard/frontend/.prettierignore b/src/pybind/mgr/dashboard/frontend/.prettierignore
new file mode 100644
index 000000000..2d19fc766
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/.prettierignore
@@ -0,0 +1 @@
+*.html
diff --git a/src/pybind/mgr/dashboard/frontend/.prettierrc b/src/pybind/mgr/dashboard/frontend/.prettierrc
new file mode 100644
index 000000000..e2c84e58f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/.prettierrc
@@ -0,0 +1,6 @@
+{
+ "arrowParens": "always",
+ "printWidth": 100,
+ "singleQuote": true,
+ "trailingComma": "none"
+}
diff --git a/src/pybind/mgr/dashboard/frontend/.stylelintrc b/src/pybind/mgr/dashboard/frontend/.stylelintrc
new file mode 100644
index 000000000..c48d66dca
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/.stylelintrc
@@ -0,0 +1,43 @@
+{
+ "extends": "stylelint-config-sass-guidelines",
+ "plugins": [
+ "stylelint-declaration-use-variable"
+ ],
+ "rules": {
+ "function-parentheses-space-inside": null,
+ "indentation": null,
+ "selector-no-qualifying-type": null,
+ "selector-class-pattern": null,
+ "selector-pseudo-element-no-unknown": null,
+ "selector-max-id": null,
+ "selector-max-compound-selectors": null,
+ "scss/at-extend-no-missing-placeholder": null,
+ "max-nesting-depth": null,
+ "scss/at-import-partial-extension-blacklist": null,
+ "value-no-vendor-prefix": null,
+ "scss/dollar-variable-pattern": [
+ "^([a-z][a-z0-9]*)(-[a-z0-9]+)*$",
+ "message": "Variable name should be written in lower kebab-case (scss/dollar-variable-pattern)"
+ ],
+ "sh-waqar/declaration-use-variable": [
+ [
+ "/color/",
+ {
+ "ignoreValues": [
+ "inherit",
+ "initial",
+ "transparent",
+ "/darken/",
+ "/\\w+\\.\\$.+/"
+ ]
+ }
+ ]
+ ],
+ "property-no-unknown": [
+ true,
+ {
+ "ignoreSelectors": [":export"]
+ }
+ ]
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/angular.json b/src/pybind/mgr/dashboard/frontend/angular.json
new file mode 100644
index 000000000..b49c00b8c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/angular.json
@@ -0,0 +1,227 @@
+{
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
+ "version": 1,
+ "newProjectRoot": "projects",
+ "projects": {
+ "ceph-dashboard": {
+ "i18n": {
+ "sourceLocale": { "code": "en-US", "baseHref": "" },
+ "locales": {
+ "cs": { "translation": "src/locale/messages.cs.xlf", "baseHref": "" },
+ "de": { "translation": "src/locale/messages.de-DE.xlf", "baseHref": "" },
+ "es": { "translation": "src/locale/messages.es-ES.xlf", "baseHref": "" },
+ "fr": { "translation": "src/locale/messages.fr-FR.xlf", "baseHref": "" },
+ "id": { "translation": "src/locale/messages.id-ID.xlf", "baseHref": "" },
+ "it": { "translation": "src/locale/messages.it-IT.xlf", "baseHref": "" },
+ "ja": { "translation": "src/locale/messages.ja-JP.xlf", "baseHref": "" },
+ "ko": { "translation": "src/locale/messages.ko-KR.xlf", "baseHref": "" },
+ "pl": { "translation": "src/locale/messages.pl-PL.xlf", "baseHref": "" },
+ "pt": { "translation": "src/locale/messages.pt-BR.xlf", "baseHref": "" },
+ "zh-Hans": { "translation": "src/locale/messages.zh-CN.xlf", "baseHref": "" },
+ "zh-Hant": { "translation": "src/locale/messages.zh-TW.xlf", "baseHref": "" }
+ }
+ },
+ "root": "",
+ "sourceRoot": "src",
+ "projectType": "application",
+ "architect": {
+ "build": {
+ "builder": "@angular-devkit/build-angular:browser",
+ "options": {
+ "allowedCommonJsDependencies": [
+ "brace-expansion",
+ "chart.js",
+ "core-js",
+ "file-saver",
+ "lodash"
+ ],
+ "i18nMissingTranslation": "ignore",
+ "outputPath": "dist",
+ "index": "src/index.html",
+ "main": "src/main.ts",
+ "tsConfig": "tsconfig.app.json",
+ "polyfills": "src/polyfills.ts",
+ "assets": [
+ "src/assets",
+ "src/favicon.ico",
+ {
+ "glob": "**/swagger-ui.css",
+ "input": "node_modules/swagger-ui-dist",
+ "output": "."
+ },
+ {
+ "glob": "**/swagger-ui-bundle.js",
+ "input": "node_modules/swagger-ui-dist",
+ "output": "."
+ }
+ ],
+ "styles": [
+ "node_modules/swagger-ui/dist/swagger-ui.css",
+ "node_modules/ngx-toastr/toastr.css",
+ "src/styles.scss"
+ ],
+ "scripts": ["node_modules/chart.js/dist/Chart.bundle.js"],
+ "stylePreprocessorOptions": {
+ "includePaths": [
+ "src"
+ ]
+ },
+ "vendorChunk": true,
+ "extractLicenses": false,
+ "buildOptimizer": false,
+ "sourceMap": true,
+ "optimization": false,
+ "namedChunks": true
+ },
+ "configurations": {
+ "production": {
+ "budgets": [
+ {
+ "type": "anyComponentStyle",
+ "maximumWarning": "6kb"
+ }
+ ],
+ "optimization": true,
+ "outputHashing": "all",
+ "sourceMap": false,
+ "namedChunks": false,
+ "extractLicenses": true,
+ "vendorChunk": false,
+ "buildOptimizer": true,
+ "fileReplacements": [
+ {
+ "replace": "src/environments/environment.ts",
+ "with": "src/environments/environment.prod.ts"
+ }
+ ]
+ },
+ "cs": {
+ "localize": ["cs"]
+ },
+ "de": {
+ "localize": ["de"]
+ },
+ "en-US": {
+ "localize": ["en-US"]
+ },
+ "es": {
+ "localize": ["es"]
+ },
+ "fr": {
+ "localize": ["fr"]
+ },
+ "id": {
+ "localize": ["id"]
+ },
+ "it": {
+ "localize": ["it"]
+ },
+ "ja": {
+ "localize": ["ja"]
+ },
+ "ko": {
+ "localize": ["ko"]
+ },
+ "pl": {
+ "localize": ["pl"]
+ },
+ "pt": {
+ "localize": ["pt"]
+ },
+ "zh-Hans": {
+ "localize": ["zh-Hans"]
+ },
+ "zh-Hant": {
+ "localize": ["zh-Hant"]
+ }
+ },
+ "defaultConfiguration": ""
+ },
+ "serve": {
+ "builder": "@angular-devkit/build-angular:dev-server",
+ "options": {
+ "browserTarget": "ceph-dashboard:build",
+ "proxyConfig": "proxy.conf.json"
+ },
+ "configurations": {
+ "production": {
+ "browserTarget": "ceph-dashboard:build:production"
+ },
+ "cs": {
+ "browserTarget": "ceph-dashboard:build:cs"
+ },
+ "de": {
+ "browserTarget": "ceph-dashboard:build:de"
+ },
+ "en-US": {
+ "browserTarget": "ceph-dashboard:build:en-US"
+ },
+ "es": {
+ "browserTarget": "ceph-dashboard:build:es"
+ },
+ "fr": {
+ "browserTarget": "ceph-dashboard:build:fr"
+ },
+ "id": {
+ "browserTarget": "ceph-dashboard:build:id"
+ },
+ "it": {
+ "browserTarget": "ceph-dashboard:build:it"
+ },
+ "ja": {
+ "browserTarget": "ceph-dashboard:build:ja"
+ },
+ "ko": {
+ "browserTarget": "ceph-dashboard:build:ko"
+ },
+ "pl": {
+ "browserTarget": "ceph-dashboard:build:pl"
+ },
+ "pt": {
+ "browserTarget": "ceph-dashboard:build:pt"
+ },
+ "zh-Hans": {
+ "browserTarget": "ceph-dashboard:build:zh-Hans"
+ },
+ "zh-Hant": {
+ "browserTarget": "ceph-dashboard:build:zh-Hant"
+ }
+ }
+ },
+ "extract-i18n": {
+ "builder": "@angular-devkit/build-angular:extract-i18n",
+ "options": {
+ "browserTarget": "ceph-dashboard:build"
+ }
+ },
+ "lint": {
+ "builder": "@angular-devkit/build-angular:tslint",
+ "options": {
+ "tsConfig": [
+ "tsconfig.app.json",
+ "tsconfig.spec.json",
+ "cypress/tsconfig.json"
+ ],
+ "exclude": [
+ "**/node_modules/**"
+ ]
+ }
+ }
+ },
+ "cli": {}
+ }
+ },
+ "defaultProject": "ceph-dashboard",
+ "schematics": {
+ "@schematics/angular:component": {
+ "prefix": "cd",
+ "style": "scss"
+ },
+ "@schematics/angular:directive": {
+ "prefix": "cd"
+ }
+ },
+ "cli": {
+ "analytics": false
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/applitools.config.js b/src/pybind/mgr/dashboard/frontend/applitools.config.js
new file mode 100644
index 000000000..2bf52651e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/applitools.config.js
@@ -0,0 +1,21 @@
+const fs = require('fs');
+
+// Read the contents of the ceph_release file to retrieve
+// the branch
+const cephRelease = fs.readFileSync('../../../../ceph_release', 'utf8').split('\n');
+const branch = cephRelease[2] === 'dev' ? 'master' : cephRelease[1];
+module.exports = {
+ appName: 'Ceph Dashboard',
+ apiKey: process.env.APPLITOOLS_API_KEY,
+ browser: [
+ { width: 1920, height: 1080, name: 'chrome' },
+ { width: 1920, height: 1080, name: 'firefox' },
+ { width: 800, height: 600, name: 'chrome' },
+ { width: 800, height: 600, name: 'firefox' }
+ ],
+ showLogs: false,
+ saveDebugData: true,
+ failCypressOnDiff: true,
+ concurrency: 4,
+ baselineBranchName: branch
+};
diff --git a/src/pybind/mgr/dashboard/frontend/babel.config.js b/src/pybind/mgr/dashboard/frontend/babel.config.js
new file mode 100644
index 000000000..4512a854a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/babel.config.js
@@ -0,0 +1,11 @@
+module.exports = function(api) {
+ api.cache(true);
+
+ const presets = ['@babel/preset-env'];
+ const plugins = [];
+
+ return {
+ presets,
+ plugins
+ };
+};
diff --git a/src/pybind/mgr/dashboard/frontend/cd.js b/src/pybind/mgr/dashboard/frontend/cd.js
new file mode 100755
index 000000000..34d0ce29f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cd.js
@@ -0,0 +1,166 @@
+/**
+ * Ceph Dashboard node script
+ * This file should be used to aggregate all external scripts we need.
+ * Multiple flags can be used in the same call.
+ *
+ * Available flags:
+ * --env: Generates angular environment files.
+ *
+ * --pre: Modifies 'angular.json' to enable the build of custom locales using
+ * angular --localize.
+ * Languages can be defined using the environment variable DASHBOARD_FRONTEND_LANGS,
+ * if no value is provided all languages will be build.
+ * Default language is always build, even if not provided.
+ * p.e.: 'DASHBOARD_FRONTEND_LANGS="pt" node cd --pre', will build EN and PT.
+ * For backward compatibility we accept both long and short version of
+ * languages, p.e.: 'pt' and 'pt-BR'
+ *
+ * --res: Restores 'angular.json' to its original and removes the backup file.
+ */
+
+const fs = require('fs');
+
+const filename = './angular.json';
+const backup = './angular.backup.json';
+
+if (process.argv.includes('--env')) {
+ envBuild();
+}
+
+if (process.argv.includes('--pre')) {
+ prepareLocales();
+}
+
+if (process.argv.includes('--res')) {
+ restoreLocales();
+}
+
+function prepareLocales() {
+ try {
+ fs.accessSync(backup, fs.constants.F_OK);
+ logger(`'${backup}' already exists, restoring it into '${filename}'}`);
+ fs.copyFileSync(backup, filename);
+ } catch (err) {
+ fs.copyFileSync(filename, backup);
+ logger(`'${filename}' was copied to '${backup}'`);
+ }
+
+ let langs = process.env.DASHBOARD_FRONTEND_LANGS || '';
+ if (langs == 'ALL') {
+ logger(`Preparing build of all languages.`);
+ return;
+ } else if (langs.length == 0) {
+ langs = [];
+ logger(`Preparing build of EN.`);
+ } else {
+ langs = langs.split(/[ ,]/);
+ logger(`Preparing build of EN and ${langs}.`);
+ }
+
+ let angular = require(filename);
+
+ let allLocales = angular['projects']['ceph-dashboard']['i18n']['locales'];
+ let locales = {};
+
+ langs.forEach((lang) => {
+ const short = lang.substring(0, 2);
+ locale = allLocales[short];
+ if (locale) {
+ locales[short] = locale;
+ } else {
+ switch (lang) {
+ case 'zh-Hans':
+ case 'zh-CN':
+ locales['zh-Hans'] = allLocales['zh-Hans'];
+ break;
+
+ case 'zh-TW':
+ case 'zh-Hant':
+ locales['zh-Hant'] = allLocales['zh-Hant'];
+ break;
+ }
+ }
+ });
+
+ angular['projects']['ceph-dashboard']['i18n']['locales'] = locales;
+ const newAngular = JSON.stringify(angular, null, 2);
+
+ fs.writeFile(filename, newAngular, (err) => {
+ if (err) throw err;
+ logger(`Writing to ${filename}`);
+ });
+}
+
+function restoreLocales() {
+ fs.access(backup, fs.constants.F_OK, (err) => {
+ logger(`'${backup}' ${err ? 'does not exist' : 'exists'}`);
+
+ if (!err) {
+ fs.copyFile(backup, filename, (err) => {
+ if (err) throw err;
+ logger(`'${backup}' was copied to '${filename}'`);
+
+ fs.unlink(backup, (err) => {
+ if (err) throw err;
+ logger(`successfully deleted '${backup}'`);
+ });
+ });
+ }
+ });
+}
+
+function envBuild() {
+ origFile = 'src/environments/environment.tpl.ts';
+ devFile = 'src/environments/environment.ts';
+ prodFile = 'src/environments/environment.prod.ts';
+
+ const replacements = [
+ { from: '{DEFAULT_LANG}', to: process.env.npm_package_config_locale },
+ { from: '{COPYRIGHT_YEAR}', to: new Date().getFullYear() }
+ ];
+ let dev = replacements.concat([{ from: `'{PRODUCTION}'`, to: false }]);
+ let prod = replacements.concat([{ from: `'{PRODUCTION}'`, to: true }]);
+
+ fs.copyFile(origFile, devFile, (err) => {
+ if (err) throw err;
+ logger(`'${origFile}' was copied to '${devFile}'`);
+
+ replace(devFile, dev);
+ });
+
+ fs.copyFile(origFile, prodFile, (err) => {
+ if (err) throw err;
+ logger(`'${origFile}' was copied to '${prodFile}'`);
+
+ replace(prodFile, prod);
+ });
+}
+
+/**
+ * Replace strings in a file.
+ *
+ * @param {*} filename Relative path to the file
+ * @param {*} replacements List of replacements, each should have from' and 'to'
+ * proprieties.
+ */
+function replace(filename, replacements) {
+ fs.readFile(filename, 'utf8', (err, data) => {
+ if (err) throw err;
+
+ replacements.forEach((rep) => {
+ data = data.replace(rep.from, rep.to);
+ });
+
+ fs.writeFile(filename, data, 'utf8', (err) => {
+ if (err) throw err;
+ logger(`Placeholders were replace in '${filename}'`);
+ });
+ });
+}
+
+/**
+ * Writes logs to the console using the [cd.js] prefix
+ */
+function logger(message) {
+ console.log(`[cd.js] ${message}`);
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress.json b/src/pybind/mgr/dashboard/frontend/cypress.json
new file mode 100644
index 000000000..fae585389
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress.json
@@ -0,0 +1,22 @@
+{
+ "baseUrl": "http://localhost:4200/",
+ "ignoreTestFiles": [
+ "*.po.ts",
+ "**/orchestrator/**"
+ ],
+ "supportFile": "cypress/support/index.ts",
+ "video": false,
+ "defaultCommandTimeout": 120000,
+ "responseTimeout": 45000,
+ "viewportHeight": 1080,
+ "viewportWidth": 1920,
+ "projectId": "k7ab29",
+ "reporter": "cypress-multi-reporters",
+ "reporterOptions": {
+ "reporterEnabled": "spec, mocha-junit-reporter",
+ "mochaJunitReporterReporterOptions": {
+ "mochaFile": "cypress/reports/results-[hash].xml"
+ }
+ },
+ "retries": 1
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/fixtures/block-rbd-status.json b/src/pybind/mgr/dashboard/frontend/cypress/fixtures/block-rbd-status.json
new file mode 100644
index 000000000..1d6f30b9a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/fixtures/block-rbd-status.json
@@ -0,0 +1 @@
+{ "available": false, "message": "No RBD pools in the cluster. Please create a pool with the \"rbd\" application label." } \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/fixtures/nfs-ganesha-status.json b/src/pybind/mgr/dashboard/frontend/cypress/fixtures/nfs-ganesha-status.json
new file mode 100644
index 000000000..4dbbaaccc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/fixtures/nfs-ganesha-status.json
@@ -0,0 +1,4 @@
+{
+ "available": false,
+ "message": "Ganesha config location is not configured. Please set the GANESHA_RADOS_POOL_NAMESPACE setting."
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/fixtures/orchestrator/inventory.json b/src/pybind/mgr/dashboard/frontend/cypress/fixtures/orchestrator/inventory.json
new file mode 100644
index 000000000..21386f2d5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/fixtures/orchestrator/inventory.json
@@ -0,0 +1,390 @@
+[
+ {
+ "addr": "node1",
+ "devices": [
+ {
+ "available": false,
+ "device_id": "",
+ "human_readable_type": "hdd",
+ "lvs": [],
+ "path": "/dev/vda",
+ "rejected_reasons": ["locked"],
+ "sys_api": {
+ "human_readable_size": "42.00 GB",
+ "locked": 1,
+ "model": "",
+ "nr_requests": "256",
+ "partitions": {
+ "vda1": {
+ "holders": [],
+ "human_readable_size": "2.00 MB",
+ "sectors": "4096",
+ "sectorsize": 512,
+ "size": 2097152.0,
+ "start": "2048"
+ },
+ "vda2": {
+ "holders": [],
+ "human_readable_size": "20.00 MB",
+ "sectors": "40960",
+ "sectorsize": 512,
+ "size": 20971520.0,
+ "start": "6144"
+ },
+ "vda3": {
+ "holders": [],
+ "human_readable_size": "41.98 GB",
+ "sectors": "88033247",
+ "sectorsize": 512,
+ "size": 45073022464.0,
+ "start": "47104"
+ }
+ },
+ "path": "/dev/vda",
+ "removable": "0",
+ "rev": "",
+ "ro": "0",
+ "rotational": "1",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "scheduler_mode": "mq-deadline",
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 45097156608.0,
+ "support_discard": "512",
+ "vendor": "0x1af4"
+ }
+ },
+ {
+ "available": false,
+ "device_id": "641526",
+ "human_readable_type": "hdd",
+ "lvs": [
+ {
+ "block_uuid": "355c2I-e5kg-WWeT-bOsI-0Ez5-sfb7-7TZyE4",
+ "cluster_fsid": "68a32428-e2ab-11ea-9d25-525400ef4c6e",
+ "cluster_name": "ceph",
+ "name": "osd-data-3de18e23-8849-494c-83b0-458d97d32d72",
+ "osd_fsid": "a438ac13-f1bd-412c-9626-e2f063dbbf94",
+ "osd_id": "0",
+ "osdspec_affinity": "dashboard-admin-1597903910143",
+ "type": "block"
+ }
+ ],
+ "path": "/dev/vdb",
+ "rejected_reasons": ["locked", "LVM detected", "Insufficient space (<5GB) on vgs"],
+ "sys_api": {
+ "human_readable_size": "8.00 GB",
+ "locked": 1,
+ "model": "",
+ "nr_requests": "256",
+ "partitions": {},
+ "path": "/dev/vdb",
+ "removable": "0",
+ "rev": "",
+ "ro": "0",
+ "rotational": "1",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "scheduler_mode": "mq-deadline",
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 8589934592.0,
+ "support_discard": "512",
+ "vendor": "0x1af4"
+ }
+ },
+ {
+ "available": false,
+ "device_id": "467047",
+ "human_readable_type": "hdd",
+ "lvs": [
+ {
+ "block_uuid": "iGC2VU-MSTt-ZP05-kKCP-5EtO-F1Y3-DYAAeb",
+ "cluster_fsid": "68a32428-e2ab-11ea-9d25-525400ef4c6e",
+ "cluster_name": "ceph",
+ "name": "osd-data-2031893c-c83b-4ff0-bfa1-de548044f707",
+ "osd_fsid": "6f544fc4-a3ea-40f9-9c48-69b5ee866709",
+ "osd_id": "1",
+ "osdspec_affinity": "dashboard-admin-1597903910143",
+ "type": "block"
+ }
+ ],
+ "path": "/dev/vdc",
+ "rejected_reasons": ["locked", "LVM detected", "Insufficient space (<5GB) on vgs"],
+ "sys_api": {
+ "human_readable_size": "8.00 GB",
+ "locked": 1,
+ "model": "",
+ "nr_requests": "256",
+ "partitions": {},
+ "path": "/dev/vdc",
+ "removable": "0",
+ "rev": "",
+ "ro": "0",
+ "rotational": "1",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "scheduler_mode": "mq-deadline",
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 8589934592.0,
+ "support_discard": "512",
+ "vendor": "0x1af4"
+ }
+ },
+ {
+ "available": false,
+ "device_id": "900807",
+ "human_readable_type": "hdd",
+ "lvs": [
+ {
+ "block_uuid": "nO2VSn-IbXr-pxnx-ieXx-kIxk-B4hB-BM6ADc",
+ "cluster_fsid": "68a32428-e2ab-11ea-9d25-525400ef4c6e",
+ "cluster_name": "ceph",
+ "name": "osd-data-537f7b60-5887-440e-80c7-759c028db12d",
+ "osd_fsid": "adeddd37-5cc9-406a-88e5-2add3f81d089",
+ "osd_id": "2",
+ "osdspec_affinity": "dashboard-admin-1597903910143",
+ "type": "block"
+ }
+ ],
+ "path": "/dev/vdd",
+ "rejected_reasons": ["locked", "LVM detected", "Insufficient space (<5GB) on vgs"],
+ "sys_api": {
+ "human_readable_size": "8.00 GB",
+ "locked": 1,
+ "model": "",
+ "nr_requests": "256",
+ "partitions": {},
+ "path": "/dev/vdd",
+ "removable": "0",
+ "rev": "",
+ "ro": "0",
+ "rotational": "1",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "scheduler_mode": "mq-deadline",
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 8589934592.0,
+ "support_discard": "512",
+ "vendor": "0x1af4"
+ }
+ },
+ {
+ "available": false,
+ "device_id": "757404",
+ "human_readable_type": "hdd",
+ "lvs": [
+ {
+ "block_uuid": "3YSAlw-VMeK-XfUK-rbOB-IKD1-Z9ZI-hUzlDe",
+ "cluster_fsid": "68a32428-e2ab-11ea-9d25-525400ef4c6e",
+ "cluster_name": "ceph",
+ "name": "osd-data-15b39d59-f259-4e93-adc6-bdac7d490d88",
+ "osd_fsid": "840a7138-88e2-4ecb-b88d-6fa2d04d88e7",
+ "osd_id": "3",
+ "osdspec_affinity": "dashboard-admin-1597903910143",
+ "type": "block"
+ }
+ ],
+ "path": "/dev/vde",
+ "rejected_reasons": ["locked", "LVM detected", "Insufficient space (<5GB) on vgs"],
+ "sys_api": {
+ "human_readable_size": "8.00 GB",
+ "locked": 1,
+ "model": "",
+ "nr_requests": "256",
+ "partitions": {},
+ "path": "/dev/vde",
+ "removable": "0",
+ "rev": "",
+ "ro": "0",
+ "rotational": "1",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "scheduler_mode": "mq-deadline",
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 8589934592.0,
+ "support_discard": "512",
+ "vendor": "0x1af4"
+ }
+ }
+ ],
+ "labels": [],
+ "name": "node1"
+ },
+ {
+ "addr": "node2",
+ "devices": [
+ {
+ "available": true,
+ "device_id": "115432",
+ "human_readable_type": "hdd",
+ "lvs": [],
+ "path": "/dev/vdb",
+ "rejected_reasons": [],
+ "sys_api": {
+ "human_readable_size": "8.00 GB",
+ "locked": 0,
+ "model": "",
+ "nr_requests": "256",
+ "partitions": {},
+ "path": "/dev/vdb",
+ "removable": "0",
+ "rev": "",
+ "ro": "0",
+ "rotational": "1",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "scheduler_mode": "mq-deadline",
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 8589934592.0,
+ "support_discard": "512",
+ "vendor": "0x1af4"
+ }
+ },
+ {
+ "available": true,
+ "device_id": "937699",
+ "human_readable_type": "hdd",
+ "lvs": [],
+ "path": "/dev/vdc",
+ "rejected_reasons": [],
+ "sys_api": {
+ "human_readable_size": "8.00 GB",
+ "locked": 0,
+ "model": "",
+ "nr_requests": "256",
+ "partitions": {},
+ "path": "/dev/vdc",
+ "removable": "0",
+ "rev": "",
+ "ro": "0",
+ "rotational": "1",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "scheduler_mode": "mq-deadline",
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 8589934592.0,
+ "support_discard": "512",
+ "vendor": "0x1af4"
+ }
+ },
+ {
+ "available": true,
+ "device_id": "854127",
+ "human_readable_type": "hdd",
+ "lvs": [],
+ "path": "/dev/vdd",
+ "rejected_reasons": [],
+ "sys_api": {
+ "human_readable_size": "8.00 GB",
+ "locked": 0,
+ "model": "",
+ "nr_requests": "256",
+ "partitions": {},
+ "path": "/dev/vdd",
+ "removable": "0",
+ "rev": "",
+ "ro": "0",
+ "rotational": "1",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "scheduler_mode": "mq-deadline",
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 8589934592.0,
+ "support_discard": "512",
+ "vendor": "0x1af4"
+ }
+ },
+ {
+ "available": true,
+ "device_id": "122615",
+ "human_readable_type": "hdd",
+ "lvs": [],
+ "path": "/dev/vde",
+ "rejected_reasons": [],
+ "sys_api": {
+ "human_readable_size": "8.00 GB",
+ "locked": 0,
+ "model": "",
+ "nr_requests": "256",
+ "partitions": {},
+ "path": "/dev/vde",
+ "removable": "0",
+ "rev": "",
+ "ro": "0",
+ "rotational": "1",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "scheduler_mode": "mq-deadline",
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 8589934592.0,
+ "support_discard": "512",
+ "vendor": "0x1af4"
+ }
+ },
+ {
+ "available": false,
+ "device_id": "",
+ "human_readable_type": "hdd",
+ "lvs": [],
+ "path": "/dev/vda",
+ "rejected_reasons": ["locked"],
+ "sys_api": {
+ "human_readable_size": "42.00 GB",
+ "locked": 1,
+ "model": "",
+ "nr_requests": "256",
+ "partitions": {
+ "vda1": {
+ "holders": [],
+ "human_readable_size": "2.00 MB",
+ "sectors": "4096",
+ "sectorsize": 512,
+ "size": 2097152.0,
+ "start": "2048"
+ },
+ "vda2": {
+ "holders": [],
+ "human_readable_size": "20.00 MB",
+ "sectors": "40960",
+ "sectorsize": 512,
+ "size": 20971520.0,
+ "start": "6144"
+ },
+ "vda3": {
+ "holders": [],
+ "human_readable_size": "41.98 GB",
+ "sectors": "88033247",
+ "sectorsize": 512,
+ "size": 45073022464.0,
+ "start": "47104"
+ }
+ },
+ "path": "/dev/vda",
+ "removable": "0",
+ "rev": "",
+ "ro": "0",
+ "rotational": "1",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "scheduler_mode": "mq-deadline",
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 45097156608.0,
+ "support_discard": "512",
+ "vendor": "0x1af4"
+ }
+ }
+ ],
+ "labels": [],
+ "name": "node2"
+ }
+]
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/fixtures/orchestrator/services.json b/src/pybind/mgr/dashboard/frontend/cypress/fixtures/orchestrator/services.json
new file mode 100644
index 000000000..433da1fb3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/fixtures/orchestrator/services.json
@@ -0,0 +1,523 @@
+[
+ {
+ "container_id": "9fa324d32bc8",
+ "container_image_digests": [
+ "docker.io/prom/alertmanager@sha256:7e4e9f7a0954b45736d149c40e9620a6664036bb05f0dce447bef5042b139f5d",
+ "docker.io/prom/alertmanager@sha256:b9323917a2eda265bec69e59a457f001c529facbbc8166df277f4850cdac61a0"
+ ],
+ "container_image_id": "0881eb8f169f5556a292b4e2c01d683172b12830a62a9225a98a8e206bb734f0",
+ "container_image_name": "docker.io/prom/alertmanager:v0.20.0",
+ "created": "2021-04-04T14:20:55.872521Z",
+ "daemon_id": "ceph-node-00",
+ "daemon_type": "alertmanager",
+ "events": [
+ "2021-04-04T14:20:55.970128Z daemon:alertmanager.ceph-node-00 [INFO] \"Deployed alertmanager.ceph-node-00 on host 'ceph-node-00.cephlab.com'\"",
+ "2021-04-04T14:25:37.637716Z daemon:alertmanager.ceph-node-00 [INFO] \"Reconfigured alertmanager.ceph-node-00 on host 'ceph-node-00.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-00.cephlab.com",
+ "is_active": true,
+ "last_refresh": "2021-04-04T14:27:38.610198Z",
+ "memory_usage": 10471079,
+ "ports": [
+ 9093,
+ 9094
+ ],
+ "started": "2021-04-04T14:25:36.837872Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "0.20.0"
+ },
+ {
+ "container_id": "44add59a53bc",
+ "container_image_digests": [
+ "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4"
+ ],
+ "container_image_id": "f72dfde44435bedf5e4c8be05c8194cc57f5f654b9bb146b73e81f1c5358b4c5",
+ "container_image_name": "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4",
+ "created": "2021-04-04T14:21:00.330646Z",
+ "daemon_id": "ceph-node-00",
+ "daemon_type": "crash",
+ "events": [
+ "2021-04-04T14:21:00.456022Z daemon:crash.ceph-node-00 [INFO] \"Deployed crash.ceph-node-00 on host 'ceph-node-00.cephlab.com'\"",
+ "2021-04-04T14:25:41.234986Z daemon:crash.ceph-node-00 [INFO] \"Reconfigured crash.ceph-node-00 on host 'ceph-node-00.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-00.cephlab.com",
+ "is_active": false,
+ "last_refresh": "2021-04-04T14:27:38.610356Z",
+ "memory_usage": 7190085,
+ "ports": [],
+ "started": "2021-04-04T14:20:59.550334Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "17.0.0-2786-g7fb0569e"
+ },
+ {
+ "container_id": "4a2180e2e4ae",
+ "container_image_digests": [
+ "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4"
+ ],
+ "container_image_id": "f72dfde44435bedf5e4c8be05c8194cc57f5f654b9bb146b73e81f1c5358b4c5",
+ "container_image_name": "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4",
+ "created": "2021-04-04T14:24:23.552501Z",
+ "daemon_id": "ceph-node-01",
+ "daemon_type": "crash",
+ "events": [
+ "2021-04-04T14:24:23.591035Z daemon:crash.ceph-node-01 [INFO] \"Deployed crash.ceph-node-01 on host 'ceph-node-01.cephlab.com'\"",
+ "2021-04-04T14:25:42.677262Z daemon:crash.ceph-node-01 [INFO] \"Reconfigured crash.ceph-node-01 on host 'ceph-node-01.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-01.cephlab.com",
+ "is_active": false,
+ "last_refresh": "2021-04-04T14:26:25.839645Z",
+ "memory_usage": 7147094,
+ "ports": [],
+ "started": "2021-04-04T14:24:23.188059Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "17.0.0-2786-g7fb0569e"
+ },
+ {
+ "container_id": "2eb2f0a13f46",
+ "container_image_digests": [
+ "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4"
+ ],
+ "container_image_id": "f72dfde44435bedf5e4c8be05c8194cc57f5f654b9bb146b73e81f1c5358b4c5",
+ "container_image_name": "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4",
+ "created": "2021-04-04T14:24:21.012014Z",
+ "daemon_id": "ceph-node-02",
+ "daemon_type": "crash",
+ "events": [
+ "2021-04-04T14:24:21.047797Z daemon:crash.ceph-node-02 [INFO] \"Deployed crash.ceph-node-02 on host 'ceph-node-02.cephlab.com'\"",
+ "2021-04-04T14:25:43.974052Z daemon:crash.ceph-node-02 [INFO] \"Reconfigured crash.ceph-node-02 on host 'ceph-node-02.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-02.cephlab.com",
+ "is_active": false,
+ "last_refresh": "2021-04-04T14:27:37.470841Z",
+ "memory_usage": 8018460,
+ "ports": [],
+ "started": "2021-04-04T14:24:20.664558Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "17.0.0-2786-g7fb0569e"
+ },
+ {
+ "container_id": "10359b995638",
+ "container_image_digests": [
+ "docker.io/ceph/ceph-grafana@sha256:44f6f2bfa52724d4db9a2ce343b299ff70a18dc21f1420548d5643df4ee18a6b"
+ ],
+ "container_image_id": "80728b29ad3f603cb306daeb6b0fb6c4c388e29e7eaac82cd3d3582ffd96b931",
+ "container_image_name": "docker.io/ceph/ceph-grafana:6.7.4",
+ "created": "2021-04-04T14:21:41.602878Z",
+ "daemon_id": "ceph-node-00",
+ "daemon_type": "grafana",
+ "events": [
+ "2021-04-04T14:21:41.651390Z daemon:grafana.ceph-node-00 [INFO] \"Deployed grafana.ceph-node-00 on host 'ceph-node-00.cephlab.com'\"",
+ "2021-04-04T14:25:26.705257Z daemon:grafana.ceph-node-00 [INFO] \"Reconfigured grafana.ceph-node-00 on host 'ceph-node-00.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-00.cephlab.com",
+ "is_active": true,
+ "last_refresh": "2021-04-04T14:27:38.609816Z",
+ "memory_usage": 27797749,
+ "ports": [
+ 3000
+ ],
+ "started": "2021-04-04T14:25:26.020123Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "6.7.4"
+ },
+ {
+ "container_id": "04e86dfde3ae",
+ "container_image_digests": [
+ "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4"
+ ],
+ "container_image_id": "f72dfde44435bedf5e4c8be05c8194cc57f5f654b9bb146b73e81f1c5358b4c5",
+ "container_image_name": "quay.ceph.io/ceph-ci/ceph:master",
+ "created": "2021-04-04T14:17:17.458301Z",
+ "daemon_id": "ceph-node-00.cephlab.com.qqwcpr",
+ "daemon_type": "mgr",
+ "events": [
+ "2021-04-04T14:25:24.076974Z daemon:mgr.ceph-node-00.cephlab.com.qqwcpr [ERROR] \"\"",
+ "2021-04-04T14:25:39.425312Z daemon:mgr.ceph-node-00.cephlab.com.qqwcpr [INFO] \"Reconfigured mgr.ceph-node-00.cephlab.com.qqwcpr on host 'ceph-node-00.cephlab.com'\""
+ ],
+ "hostname": "",
+ "is_active": true,
+ "last_refresh": "2021-04-04T14:20:21.353502Z",
+ "memory_usage": 411670937,
+ "ports": [
+ 9283
+ ],
+ "started": "2021-04-04T14:17:16.779682Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "17.0.0-2786-g7fb0569e"
+ },
+ {
+ "container_id": "04e86dfde3ae",
+ "container_image_digests": [
+ "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4"
+ ],
+ "container_image_id": "f72dfde44435bedf5e4c8be05c8194cc57f5f654b9bb146b73e81f1c5358b4c5",
+ "container_image_name": "quay.ceph.io/ceph-ci/ceph:master",
+ "created": "2021-04-04T14:17:17.458301Z",
+ "daemon_id": "ceph-node-00.cephlab.com.qqwcpr",
+ "daemon_type": "mgr",
+ "events": [
+ "2021-04-04T14:25:24.076974Z daemon:mgr.ceph-node-00.cephlab.com.qqwcpr [ERROR] \"\"",
+ "2021-04-04T14:25:39.425312Z daemon:mgr.ceph-node-00.cephlab.com.qqwcpr [INFO] \"Reconfigured mgr.ceph-node-00.cephlab.com.qqwcpr on host 'ceph-node-00.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-00.cephlab.com",
+ "is_active": true,
+ "last_refresh": "2021-04-04T14:27:38.610265Z",
+ "memory_usage": 468608614,
+ "ports": [
+ 9283
+ ],
+ "started": "2021-04-04T14:17:16.779682Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "17.0.0-2786-g7fb0569e"
+ },
+ {
+ "container_id": "7bfba45507ab",
+ "container_image_digests": [
+ "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4"
+ ],
+ "container_image_id": "f72dfde44435bedf5e4c8be05c8194cc57f5f654b9bb146b73e81f1c5358b4c5",
+ "container_image_name": "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4",
+ "created": "2021-04-04T14:24:25.445135Z",
+ "daemon_id": "ceph-node-02.mywsmi",
+ "daemon_type": "mgr",
+ "events": [
+ "2021-04-04T14:24:25.484361Z daemon:mgr.ceph-node-02.mywsmi [INFO] \"Deployed mgr.ceph-node-02.mywsmi on host 'ceph-node-02.cephlab.com'\"",
+ "2021-04-04T14:25:46.457476Z daemon:mgr.ceph-node-02.mywsmi [INFO] \"Reconfigured mgr.ceph-node-02.mywsmi on host 'ceph-node-02.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-02.cephlab.com",
+ "is_active": false,
+ "last_refresh": "2021-04-04T14:27:37.471837Z",
+ "memory_usage": 384617676,
+ "ports": [
+ 8443,
+ 9283
+ ],
+ "started": "2021-04-04T14:24:25.142998Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "17.0.0-2786-g7fb0569e"
+ },
+ {
+ "container_id": "6045be766e88",
+ "container_image_digests": [
+ "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4"
+ ],
+ "container_image_id": "f72dfde44435bedf5e4c8be05c8194cc57f5f654b9bb146b73e81f1c5358b4c5",
+ "container_image_name": "quay.ceph.io/ceph-ci/ceph:master",
+ "created": "2021-04-04T14:17:07.904023Z",
+ "daemon_id": "ceph-node-00.cephlab.com",
+ "daemon_type": "mon",
+ "events": [
+ "2021-04-04T14:25:24.076865Z daemon:mon.ceph-node-00.cephlab.com [ERROR] \"\"",
+ "2021-04-04T14:25:28.250425Z daemon:mon.ceph-node-00.cephlab.com [INFO] \"Reconfigured mon.ceph-node-00.cephlab.com on host 'ceph-node-00.cephlab.com'\""
+ ],
+ "hostname": "",
+ "is_active": false,
+ "last_refresh": "2021-04-04T14:20:21.353077Z",
+ "memory_usage": 35871784,
+ "ports": [],
+ "started": "2021-04-04T14:17:13.608122Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "17.0.0-2786-g7fb0569e"
+ },
+ {
+ "container_id": "6045be766e88",
+ "container_image_digests": [
+ "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4"
+ ],
+ "container_image_id": "f72dfde44435bedf5e4c8be05c8194cc57f5f654b9bb146b73e81f1c5358b4c5",
+ "container_image_name": "quay.ceph.io/ceph-ci/ceph:master",
+ "created": "2021-04-04T14:17:07.904023Z",
+ "daemon_id": "ceph-node-00.cephlab.com",
+ "daemon_type": "mon",
+ "events": [
+ "2021-04-04T14:25:24.076865Z daemon:mon.ceph-node-00.cephlab.com [ERROR] \"\"",
+ "2021-04-04T14:25:28.250425Z daemon:mon.ceph-node-00.cephlab.com [INFO] \"Reconfigured mon.ceph-node-00.cephlab.com on host 'ceph-node-00.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-00.cephlab.com",
+ "is_active": false,
+ "last_refresh": "2021-04-04T14:27:38.609967Z",
+ "memory_usage": 74826383,
+ "ports": [],
+ "started": "2021-04-04T14:17:13.608122Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "17.0.0-2786-g7fb0569e"
+ },
+ {
+ "container_id": "d2d261f4eb17",
+ "container_image_digests": [
+ "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4"
+ ],
+ "container_image_id": "f72dfde44435bedf5e4c8be05c8194cc57f5f654b9bb146b73e81f1c5358b4c5",
+ "container_image_name": "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4",
+ "created": "2021-04-04T14:24:28.269212Z",
+ "daemon_id": "ceph-node-02",
+ "daemon_type": "mon",
+ "events": [
+ "2021-04-04T14:24:28.314782Z daemon:mon.ceph-node-02 [INFO] \"Deployed mon.ceph-node-02 on host 'ceph-node-02.cephlab.com'\"",
+ "2021-04-04T14:25:45.448194Z daemon:mon.ceph-node-02 [INFO] \"Reconfigured mon.ceph-node-02 on host 'ceph-node-02.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-02.cephlab.com",
+ "is_active": false,
+ "last_refresh": "2021-04-04T14:27:37.471665Z",
+ "memory_usage": 65515028,
+ "ports": [],
+ "started": "2021-04-04T14:24:28.147109Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "17.0.0-2786-g7fb0569e"
+ },
+ {
+ "container_id": "51c04231de4c",
+ "container_image_digests": [
+ "docker.io/prom/node-exporter@sha256:a2f29256e53cc3e0b64d7a472512600b2e9410347d53cdc85b49f659c17e02ee",
+ "docker.io/prom/node-exporter@sha256:b630fb29d99b3483c73a2a7db5fc01a967392a3d7ad754c8eccf9f4a67e7ee31"
+ ],
+ "container_image_id": "e5a616e4b9cf68dfcad7782b78e118be4310022e874d52da85c55923fb615f87",
+ "container_image_name": "docker.io/prom/node-exporter:v0.18.1",
+ "created": "2021-04-04T14:21:52.336199Z",
+ "daemon_id": "ceph-node-00",
+ "daemon_type": "node-exporter",
+ "events": [
+ "2021-04-04T14:21:52.372374Z daemon:node-exporter.ceph-node-00 [INFO] \"Deployed node-exporter.ceph-node-00 on host 'ceph-node-00.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-00.cephlab.com",
+ "is_active": false,
+ "last_refresh": "2021-04-04T14:27:38.610044Z",
+ "memory_usage": 8001683,
+ "ports": [
+ 9100
+ ],
+ "started": "2021-04-04T14:21:52.044759Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "0.18.1"
+ },
+ {
+ "container_id": "ac9e1d055972",
+ "container_image_digests": [
+ "docker.io/prom/node-exporter@sha256:a2f29256e53cc3e0b64d7a472512600b2e9410347d53cdc85b49f659c17e02ee",
+ "docker.io/prom/node-exporter@sha256:b630fb29d99b3483c73a2a7db5fc01a967392a3d7ad754c8eccf9f4a67e7ee31"
+ ],
+ "container_image_id": "e5a616e4b9cf68dfcad7782b78e118be4310022e874d52da85c55923fb615f87",
+ "container_image_name": "docker.io/prom/node-exporter:v0.18.1",
+ "created": "2021-04-04T14:24:39.469923Z",
+ "daemon_id": "ceph-node-01",
+ "daemon_type": "node-exporter",
+ "events": [
+ "2021-04-04T14:24:39.508244Z daemon:node-exporter.ceph-node-01 [INFO] \"Deployed node-exporter.ceph-node-01 on host 'ceph-node-01.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-01.cephlab.com",
+ "is_active": false,
+ "last_refresh": "2021-04-04T14:26:25.839072Z",
+ "memory_usage": 7052722,
+ "ports": [
+ 9100
+ ],
+ "started": "2021-04-04T14:24:39.156587Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "0.18.1"
+ },
+ {
+ "container_id": "b133dbf9cff8",
+ "container_image_digests": [
+ "docker.io/prom/node-exporter@sha256:a2f29256e53cc3e0b64d7a472512600b2e9410347d53cdc85b49f659c17e02ee",
+ "docker.io/prom/node-exporter@sha256:b630fb29d99b3483c73a2a7db5fc01a967392a3d7ad754c8eccf9f4a67e7ee31"
+ ],
+ "container_image_id": "e5a616e4b9cf68dfcad7782b78e118be4310022e874d52da85c55923fb615f87",
+ "container_image_name": "docker.io/prom/node-exporter:v0.18.1",
+ "created": "2021-04-04T14:24:49.840797Z",
+ "daemon_id": "ceph-node-02",
+ "daemon_type": "node-exporter",
+ "events": [
+ "2021-04-04T14:24:49.901437Z daemon:node-exporter.ceph-node-02 [INFO] \"Deployed node-exporter.ceph-node-02 on host 'ceph-node-02.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-02.cephlab.com",
+ "is_active": false,
+ "last_refresh": "2021-04-04T14:27:37.471349Z",
+ "memory_usage": 7696547,
+ "ports": [
+ 9100
+ ],
+ "started": "2021-04-04T14:24:49.524299Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "0.18.1"
+ },
+ {
+ "container_id": "51d864a583df",
+ "container_image_digests": [
+ "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4"
+ ],
+ "container_image_id": "f72dfde44435bedf5e4c8be05c8194cc57f5f654b9bb146b73e81f1c5358b4c5",
+ "container_image_name": "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4",
+ "created": "2021-04-04T14:25:03.086634Z",
+ "daemon_id": "0",
+ "daemon_type": "osd",
+ "events": [
+ "2021-04-04T14:25:03.152770Z daemon:osd.0 [INFO] \"Deployed osd.0 on host 'ceph-node-00.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-00.cephlab.com",
+ "is_active": false,
+ "last_refresh": "2021-04-04T14:27:38.610426Z",
+ "memory_usage": 63826821,
+ "osdspec_affinity": "all-available-devices",
+ "ports": [],
+ "started": "2021-04-04T14:25:02.948826Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "17.0.0-2786-g7fb0569e"
+ },
+ {
+ "container_id": "7a141557611e",
+ "container_image_digests": [
+ "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4"
+ ],
+ "container_image_id": "f72dfde44435bedf5e4c8be05c8194cc57f5f654b9bb146b73e81f1c5358b4c5",
+ "container_image_name": "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4",
+ "created": "2021-04-04T14:25:02.803534Z",
+ "daemon_id": "1",
+ "daemon_type": "osd",
+ "events": [
+ "2021-04-04T14:25:02.905863Z daemon:osd.1 [INFO] \"Deployed osd.1 on host 'ceph-node-01.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-01.cephlab.com",
+ "is_active": false,
+ "last_refresh": "2021-04-04T14:26:25.839343Z",
+ "memory_usage": 44155535,
+ "osdspec_affinity": "all-available-devices",
+ "ports": [],
+ "started": "2021-04-04T14:25:02.650699Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "17.0.0-2786-g7fb0569e"
+ },
+ {
+ "container_id": "bbf4cc5b870a",
+ "container_image_digests": [
+ "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4"
+ ],
+ "container_image_id": "f72dfde44435bedf5e4c8be05c8194cc57f5f654b9bb146b73e81f1c5358b4c5",
+ "container_image_name": "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4",
+ "created": "2021-04-04T14:25:03.771174Z",
+ "daemon_id": "2",
+ "daemon_type": "osd",
+ "events": [
+ "2021-04-04T14:25:03.827365Z daemon:osd.2 [INFO] \"Deployed osd.2 on host 'ceph-node-02.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-02.cephlab.com",
+ "is_active": false,
+ "last_refresh": "2021-04-04T14:27:37.471996Z",
+ "memory_usage": 62495129,
+ "osdspec_affinity": "all-available-devices",
+ "ports": [],
+ "started": "2021-04-04T14:25:08.134780Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "17.0.0-2786-g7fb0569e"
+ },
+ {
+ "container_id": "e36d84e5608b",
+ "container_image_digests": [
+ "docker.io/prom/prometheus@sha256:5880ec936055fad18ccee798d2a63f64ed85bd28e8e0af17c6923a090b686c3d",
+ "docker.io/prom/prometheus@sha256:b4e6cd0275a26750505e539f8528e891053434ebd3972be02645bed5f02f0795"
+ ],
+ "container_image_id": "de242295e2257c37c8cadfd962369228f8f10b2d48a44259b65fef44ad4f6490",
+ "container_image_name": "docker.io/prom/prometheus:v2.18.1",
+ "created": "2021-04-04T14:22:11.310763Z",
+ "daemon_id": "ceph-node-00",
+ "daemon_type": "prometheus",
+ "events": [
+ "2021-04-04T14:22:11.356043Z daemon:prometheus.ceph-node-00 [INFO] \"Deployed prometheus.ceph-node-00 on host 'ceph-node-00.cephlab.com'\"",
+ "2021-04-04T14:25:33.086106Z daemon:prometheus.ceph-node-00 [INFO] \"Reconfigured prometheus.ceph-node-00 on host 'ceph-node-00.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-00.cephlab.com",
+ "is_active": true,
+ "last_refresh": "2021-04-04T14:27:38.610128Z",
+ "memory_usage": 27724349,
+ "ports": [
+ 9095
+ ],
+ "started": "2021-04-04T14:25:32.344156Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "2.18.1"
+ },
+ {
+ "container_id": "5cdeb705c7f6",
+ "container_image_digests": [
+ "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4"
+ ],
+ "container_image_id": "f72dfde44435bedf5e4c8be05c8194cc57f5f654b9bb146b73e81f1c5358b4c5",
+ "container_image_name": "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4",
+ "created": "2021-04-04T14:27:26.775628Z",
+ "daemon_id": "foo.ceph-node-00.qknfoh",
+ "daemon_type": "rgw",
+ "events": [
+ "2021-04-04T14:27:26.824821Z daemon:rgw.foo.ceph-node-00.qknfoh [INFO] \"Deployed rgw.foo.ceph-node-00.qknfoh on host 'ceph-node-00.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-00.cephlab.com",
+ "is_active": false,
+ "last_refresh": "2021-04-04T14:27:38.610617Z",
+ "memory_usage": 53309603,
+ "ports": [
+ 80
+ ],
+ "started": "2021-04-04T14:27:26.350981Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "17.0.0-2786-g7fb0569e"
+ },
+ {
+ "container_id": "18a2179a35c0",
+ "container_image_digests": [
+ "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4"
+ ],
+ "container_image_id": "f72dfde44435bedf5e4c8be05c8194cc57f5f654b9bb146b73e81f1c5358b4c5",
+ "container_image_name": "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4",
+ "created": "2021-04-04T14:27:24.200977Z",
+ "daemon_id": "foo.ceph-node-02.fgzmmm",
+ "daemon_type": "rgw",
+ "events": [
+ "2021-04-04T14:27:24.300473Z daemon:rgw.foo.ceph-node-02.fgzmmm [INFO] \"Deployed rgw.foo.ceph-node-02.fgzmmm on host 'ceph-node-02.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-02.cephlab.com",
+ "is_active": false,
+ "last_refresh": "2021-04-04T14:27:37.471149Z",
+ "memory_usage": 53487861,
+ "ports": [
+ 80
+ ],
+ "started": "2021-04-04T14:27:23.793957Z",
+ "status": 1,
+ "status_desc": "running",
+ "version": "17.0.0-2786-g7fb0569e"
+ },
+ {
+ "container_image_name": "quay.ceph.io/ceph-ci/ceph@sha256:cfd9dc4a437e11894a9a0d930ed1221ccc4e939b943981f6dfbdc611816904d4",
+ "created": "2021-04-04T14:27:30.048136Z",
+ "daemon_id": "foo.ceph-node-02.hqjyla",
+ "daemon_type": "rgw",
+ "events": [
+ "2021-04-04T14:27:30.115692Z daemon:rgw.foo.ceph-node-02.hqjyla [INFO] \"Deployed rgw.foo.ceph-node-02.hqjyla on host 'ceph-node-02.cephlab.com'\""
+ ],
+ "hostname": "ceph-node-02.cephlab.com",
+ "is_active": false,
+ "last_refresh": "2021-04-04T14:27:37.471564Z",
+ "ports": [
+ 80
+ ],
+ "status": -1,
+ "status_desc": "unknown"
+ }
+] \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/fixtures/rgw-status.json b/src/pybind/mgr/dashboard/frontend/cypress/fixtures/rgw-status.json
new file mode 100644
index 000000000..faa8c0418
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/fixtures/rgw-status.json
@@ -0,0 +1 @@
+{ "available": true, "message": null }
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/block/images.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/block/images.e2e-spec.ts
new file mode 100644
index 000000000..5c89359db
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/block/images.e2e-spec.ts
@@ -0,0 +1,95 @@
+import { PoolPageHelper } from '../pools/pools.po';
+import { ImagesPageHelper } from './images.po';
+
+describe('Images page', () => {
+ const pools = new PoolPageHelper();
+ const images = new ImagesPageHelper();
+
+ const poolName = 'e2e_images_pool';
+
+ before(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ // Need pool for image testing
+ pools.navigateTo('create');
+ pools.create(poolName, 8, 'rbd');
+ pools.existTableCell(poolName);
+ });
+
+ after(() => {
+ // Deletes images test pool
+ pools.navigateTo();
+ pools.delete(poolName);
+ pools.navigateTo();
+ pools.existTableCell(poolName, false);
+ });
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ images.navigateTo();
+ });
+
+ it('should open and show breadcrumb', () => {
+ images.expectBreadcrumbText('Images');
+ });
+
+ it('should show four tabs', () => {
+ images.getTabsCount().should('eq', 4);
+ });
+
+ it('should show text for all tabs', () => {
+ images.getTabText(0).should('eq', 'Images');
+ images.getTabText(1).should('eq', 'Namespaces');
+ images.getTabText(2).should('eq', 'Trash');
+ images.getTabText(3).should('eq', 'Overall Performance');
+ });
+
+ describe('create, edit & delete image test', () => {
+ const imageName = 'e2e_images#image';
+ const newImageName = 'e2e_images#image_new';
+
+ it('should create image', () => {
+ images.createImage(imageName, poolName, '1');
+ images.getFirstTableCell(imageName).should('exist');
+ });
+
+ it('should edit image', () => {
+ images.editImage(imageName, poolName, newImageName, '2');
+ images.getFirstTableCell(newImageName).should('exist');
+ });
+
+ it('should delete image', () => {
+ images.delete(newImageName);
+ });
+ });
+
+ describe('move to trash, restore and purge image tests', () => {
+ const imageName = 'e2e_trash#image';
+ const newImageName = 'e2e_newtrash#image';
+
+ before(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ // Need image for trash testing
+ images.createImage(imageName, poolName, '1');
+ images.getFirstTableCell(imageName).should('exist');
+ });
+
+ it('should move the image to the trash', () => {
+ images.moveToTrash(imageName);
+ images.getFirstTableCell(imageName).should('exist');
+ });
+
+ it('should restore image to images table', () => {
+ images.restoreImage(imageName, newImageName);
+ images.getFirstTableCell(newImageName).should('exist');
+ });
+
+ it('should purge trash in images trash tab', () => {
+ images.getFirstTableCell(newImageName).should('exist');
+ images.moveToTrash(newImageName);
+ images.purgeTrash(newImageName, poolName);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/block/images.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/block/images.po.ts
new file mode 100644
index 000000000..bf6cbc052
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/block/images.po.ts
@@ -0,0 +1,110 @@
+import { PageHelper } from '../page-helper.po';
+
+export class ImagesPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/block/rbd', id: 'cd-rbd-list' },
+ create: { url: '#/block/rbd/create', id: 'cd-rbd-form' }
+ };
+
+ // Creates a block image and fills in the name, pool, and size fields.
+ // Then checks if the image is present in the Images table.
+ createImage(name: string, pool: string, size: string) {
+ this.navigateTo('create');
+
+ cy.get('#name').type(name); // Enter in image name
+
+ // Select image pool
+ cy.contains('Loading...').should('not.exist');
+ this.selectOption('pool', pool);
+ cy.get('#pool').should('have.class', 'ng-valid'); // check if selected
+
+ // Enter in the size of the image
+ cy.get('#size').type(size);
+
+ // Click the create button and wait for image to be made
+ cy.get('[data-cy=submitBtn]').click();
+ this.getFirstTableCell(name).should('exist');
+ }
+
+ editImage(name: string, pool: string, newName: string, newSize: string) {
+ this.navigateEdit(name);
+
+ // Wait until data is loaded
+ cy.get('#pool').should('contain.value', pool);
+
+ cy.get('#name').clear().type(newName);
+ cy.get('#size').clear().type(newSize); // click the size box and send new size
+
+ cy.get('[data-cy=submitBtn]').click();
+
+ this.getExpandCollapseElement(newName).click();
+ cy.get('.table.table-striped.table-bordered').contains('td', newSize);
+ }
+
+ // Selects RBD image and moves it to the trash,
+ // checks that it is present in the trash table
+ moveToTrash(name: string) {
+ // wait for image to be created
+ cy.get('.datatable-body').first().should('not.contain.text', '(Creating...)');
+
+ this.getFirstTableCell(name).click();
+
+ // click on the drop down and selects the move to trash option
+ cy.get('.table-actions button.dropdown-toggle').first().click();
+ cy.get('button.move-to-trash').click();
+
+ cy.get('[data-cy=submitBtn]').should('be.visible').click();
+
+ // Clicks trash tab
+ cy.contains('.nav-link', 'Trash').click();
+ this.getFirstTableCell(name).should('exist');
+ }
+
+ // Checks trash tab table for image and then restores it to the RBD Images table
+ // (could change name if new name is given)
+ restoreImage(name: string, newName?: string) {
+ // clicks on trash tab
+ cy.contains('.nav-link', 'Trash').click();
+
+ // wait for table to load
+ this.getFirstTableCell(name).click();
+ cy.contains('button', 'Restore').click();
+
+ // wait for pop-up to be visible (checks for title of pop-up)
+ cy.get('cd-modal #name').should('be.visible');
+
+ // If a new name for the image is passed, it changes the name of the image
+ if (newName !== undefined) {
+ // click name box and send new name
+ cy.get('cd-modal #name').clear().type(newName);
+ }
+
+ cy.get('[data-cy=submitBtn]').click();
+
+ // clicks images tab
+ cy.contains('.nav-link', 'Images').click();
+
+ this.getFirstTableCell(newName).should('exist');
+ }
+
+ // Enters trash tab and purges trash, thus emptying the trash table.
+ // Checks if Image is still in the table.
+ purgeTrash(name: string, pool?: string) {
+ // clicks trash tab
+ cy.contains('.nav-link', 'Trash').click();
+ cy.contains('button', 'Purge Trash').click();
+
+ // Check for visibility of modal container
+ cy.get('.modal-header').should('be.visible');
+
+ // If purgeing a specific pool, selects that pool if given
+ if (pool !== undefined) {
+ this.selectOption('poolName', pool);
+ cy.get('#poolName').should('have.class', 'ng-valid'); // check if pool is selected
+ }
+ cy.get('[data-cy=submitBtn]').click();
+ // Wait for image to delete and check it is not present
+
+ this.getFirstTableCell(name).should('not.exist');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/block/iscsi.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/block/iscsi.e2e-spec.ts
new file mode 100644
index 000000000..cef4874be
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/block/iscsi.e2e-spec.ts
@@ -0,0 +1,25 @@
+import { IscsiPageHelper } from './iscsi.po';
+
+describe('Iscsi Page', () => {
+ const iscsi = new IscsiPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ iscsi.navigateTo();
+ });
+
+ it('should open and show breadcrumb', () => {
+ iscsi.expectBreadcrumbText('Overview');
+ });
+
+ it('should check that tables are displayed and legends are correct', () => {
+ // Check tables are displayed
+ iscsi.getDataTables().its(0).should('be.visible');
+ iscsi.getDataTables().its(1).should('be.visible');
+
+ // Check that legends are correct
+ iscsi.getLegends().its(0).should('contain.text', 'Gateways');
+ iscsi.getLegends().its(1).should('contain.text', 'Images');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/block/iscsi.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/block/iscsi.po.ts
new file mode 100644
index 000000000..08efa6408
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/block/iscsi.po.ts
@@ -0,0 +1,7 @@
+import { PageHelper } from '../page-helper.po';
+
+export class IscsiPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/block/iscsi/overview', id: 'cd-iscsi' }
+ };
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/block/mirroring.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/block/mirroring.e2e-spec.ts
new file mode 100644
index 000000000..dfba73b27
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/block/mirroring.e2e-spec.ts
@@ -0,0 +1,54 @@
+import { PoolPageHelper } from '../pools/pools.po';
+import { MirroringPageHelper } from './mirroring.po';
+
+describe('Mirroring page', () => {
+ const pools = new PoolPageHelper();
+ const mirroring = new MirroringPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ mirroring.navigateTo();
+ });
+
+ it('should open and show breadcrumb', () => {
+ mirroring.expectBreadcrumbText('Mirroring');
+ });
+
+ it('should show three tabs', () => {
+ mirroring.getTabsCount().should('eq', 3);
+ });
+
+ it('should show text for all tabs', () => {
+ mirroring.getTabText(0).should('eq', 'Issues (0)');
+ mirroring.getTabText(1).should('eq', 'Syncing (0)');
+ mirroring.getTabText(2).should('eq', 'Ready (0)');
+ });
+
+ describe('checks that edit mode functionality shows in the pools table', () => {
+ const poolName = 'mirroring_test';
+
+ beforeEach(() => {
+ pools.navigateTo('create'); // Need pool for mirroring testing
+ pools.create(poolName, 8, 'rbd');
+ pools.navigateTo();
+ pools.existTableCell(poolName, true);
+ });
+
+ it('tests editing mode for pools', () => {
+ mirroring.navigateTo();
+
+ mirroring.editMirror(poolName, 'Pool');
+ mirroring.getFirstTableCell('pool').should('be.visible');
+ mirroring.editMirror(poolName, 'Image');
+ mirroring.getFirstTableCell('image').should('be.visible');
+ mirroring.editMirror(poolName, 'Disabled');
+ mirroring.getFirstTableCell('disabled').should('be.visible');
+ });
+
+ afterEach(() => {
+ pools.navigateTo();
+ pools.delete(poolName);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/block/mirroring.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/block/mirroring.po.ts
new file mode 100644
index 000000000..e24a3ebc0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/block/mirroring.po.ts
@@ -0,0 +1,35 @@
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/block/mirroring', id: 'cd-mirroring' }
+};
+
+export class MirroringPageHelper extends PageHelper {
+ pages = pages;
+
+ /**
+ * Goes to the mirroring page and edits a pool in the Pool table. Clicks on the
+ * pool and chooses an option (either pool, image, or disabled)
+ */
+ @PageHelper.restrictTo(pages.index.url)
+ editMirror(name: string, option: string) {
+ // Select the pool in the table
+ this.getFirstTableCell(name).click();
+
+ // Clicks the Edit Mode button
+ cy.contains('button', 'Edit Mode').click();
+
+ // Clicks the drop down in the edit pop-up, then clicks the Update button
+ cy.get('.modal-content').should('be.visible');
+ this.selectOption('mirrorMode', option);
+
+ // Clicks update button and checks if the mode has been changed
+ cy.contains('button', 'Update').click();
+ cy.contains('.modal-dialog', 'Edit pool mirror mode').should('not.exist');
+ const val = option.toLowerCase(); // used since entries in table are lower case
+ this.getFirstTableCell(val).should('be.visible');
+
+ // unselect the pool in the table
+ this.getFirstTableCell(name).click();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/configuration.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/configuration.e2e-spec.ts
new file mode 100644
index 000000000..d022d59cf
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/configuration.e2e-spec.ts
@@ -0,0 +1,78 @@
+import { ConfigurationPageHelper } from './configuration.po';
+
+describe('Configuration page', () => {
+ const configuration = new ConfigurationPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ configuration.navigateTo();
+ });
+
+ describe('breadcrumb test', () => {
+ it('should open and show breadcrumb', () => {
+ configuration.expectBreadcrumbText('Configuration');
+ });
+ });
+
+ describe('fields check', () => {
+ beforeEach(() => {
+ configuration.getExpandCollapseElement().click();
+ });
+
+ it('should check that details table opens (w/o tab header)', () => {
+ configuration.getStatusTables().should('be.visible');
+ configuration.getTabs().should('not.exist');
+ });
+ });
+
+ describe('edit configuration test', () => {
+ const configName = 'client_cache_size';
+
+ beforeEach(() => {
+ configuration.clearTableSearchInput();
+ configuration.getTableCount('found').as('configFound');
+ });
+
+ after(() => {
+ configuration.configClear(configName);
+ });
+
+ it('should click and edit a configuration and results should appear in the table', () => {
+ configuration.edit(
+ configName,
+ ['global', '1'],
+ ['mon', '2'],
+ ['mgr', '3'],
+ ['osd', '4'],
+ ['mds', '5'],
+ ['client', '6']
+ );
+ });
+
+ it('should verify modified filter is applied properly', () => {
+ configuration.filterTable('Modified', 'no');
+ configuration.getTableCount('found').as('unmodifiedConfigs');
+
+ // Modified filter value to yes
+ configuration.filterTable('Modified', 'yes');
+ configuration.getTableCount('found').as('modifiedConfigs');
+
+ cy.get('@configFound').then((configFound) => {
+ cy.get('@unmodifiedConfigs').then((unmodifiedConfigs) => {
+ const modifiedConfigs = Number(configFound) - Number(unmodifiedConfigs);
+ configuration.getTableCount('found').should('eq', modifiedConfigs);
+ });
+ });
+
+ // Modified filter value to no
+ configuration.filterTable('Modified', 'no');
+ cy.get('@configFound').then((configFound) => {
+ cy.get('@modifiedConfigs').then((modifiedConfigs) => {
+ const unmodifiedConfigs = Number(configFound) - Number(modifiedConfigs);
+ configuration.getTableCount('found').should('eq', unmodifiedConfigs);
+ });
+ });
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/configuration.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/configuration.po.ts
new file mode 100644
index 000000000..0133dc31f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/configuration.po.ts
@@ -0,0 +1,75 @@
+import { PageHelper } from '../page-helper.po';
+
+export class ConfigurationPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/configuration', id: 'cd-configuration' }
+ };
+
+ /**
+ * Clears out all the values in a config to reset before and after testing
+ * Does not work for configs with checkbox only, possible future PR
+ */
+ configClear(name: string) {
+ const valList = ['global', 'mon', 'mgr', 'osd', 'mds', 'client']; // Editable values
+
+ this.navigateEdit(name);
+ // Waits for the data to load
+ cy.contains('.card-header', `Edit ${name}`);
+
+ for (const i of valList) {
+ cy.get(`#${i}`).clear();
+ }
+ // Clicks save button and checks that values are not present for the selected config
+ cy.get('[data-cy=submitBtn]').click();
+
+ // Enter config setting name into filter box
+ this.searchTable(name);
+
+ // Expand row
+ this.getExpandCollapseElement(name).click();
+
+ // Checks for visibility of details tab
+ this.getStatusTables().should('be.visible');
+
+ for (const i of valList) {
+ // Waits until values are not present in the details table
+ this.getStatusTables().should('not.contain.text', i + ':');
+ }
+ }
+
+ /**
+ * Clicks the designated config, then inputs the values passed into the edit function.
+ * Then checks if the edit is reflected in the config table.
+ * Takes in name of config and a list of tuples of values the user wants edited,
+ * each tuple having the desired value along with the number tehey want for that value.
+ * Ex: [global, '2'] is the global value with an input of 2
+ */
+ edit(name: string, ...values: [string, string][]) {
+ this.navigateEdit(name);
+
+ // Waits for data to load
+ cy.contains('.card-header', `Edit ${name}`);
+
+ values.forEach((valtuple) => {
+ // Finds desired value based off given list
+ cy.get(`#${valtuple[0]}`).type(valtuple[1]); // of values and inserts the given number for the value
+ });
+
+ // Clicks save button then waits until the desired config is visible, clicks it,
+ // then checks that each desired value appears with the desired number
+ cy.get('[data-cy=submitBtn]').click();
+
+ // Enter config setting name into filter box
+ this.searchTable(name);
+
+ // Checks for visibility of config in table
+ this.getExpandCollapseElement(name).should('be.visible').click();
+
+ // Clicks config
+ values.forEach((value) => {
+ // iterates through list of values and
+ // checks if the value appears in details with the correct number attatched
+ cy.contains('.table.table-striped.table-bordered', `${value[0]}\: ${value[1]}`);
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/create-cluster.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/create-cluster.po.ts
new file mode 100644
index 000000000..300eddbcc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/create-cluster.po.ts
@@ -0,0 +1,56 @@
+import { PageHelper } from '../page-helper.po';
+import { NotificationSidebarPageHelper } from '../ui/notification.po';
+import { HostsPageHelper } from './hosts.po';
+import { ServicesPageHelper } from './services.po';
+
+const pages = {
+ index: { url: '#/expand-cluster', id: 'cd-create-cluster' }
+};
+export class CreateClusterWizardHelper extends PageHelper {
+ pages = pages;
+
+ createCluster() {
+ cy.get('cd-create-cluster').should('contain.text', 'Please expand your cluster first');
+ cy.get('[name=expand-cluster]').click();
+ cy.get('cd-wizard').should('exist');
+ }
+
+ doSkip() {
+ cy.get('[name=skip-cluster-creation]').click();
+ cy.contains('cd-modal button', 'Continue').click();
+
+ cy.get('cd-dashboard').should('exist');
+ const notification = new NotificationSidebarPageHelper();
+ notification.open();
+ notification.getNotifications().should('contain', 'Cluster expansion skipped by user');
+ }
+}
+
+export class CreateClusterHostPageHelper extends HostsPageHelper {
+ pages = {
+ index: { url: '#/expand-cluster', id: 'cd-wizard' },
+ add: { url: '', id: 'cd-host-form' }
+ };
+
+ columnIndex = {
+ hostname: 1,
+ labels: 2,
+ status: 3,
+ services: 0
+ };
+}
+
+export class CreateClusterServicePageHelper extends ServicesPageHelper {
+ pages = {
+ index: { url: '#/expand-cluster', id: 'cd-wizard' },
+ create: { url: '', id: 'cd-service-form' }
+ };
+
+ columnIndex = {
+ service_name: 1,
+ placement: 2,
+ running: 0,
+ size: 0,
+ last_refresh: 0
+ };
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/crush-map.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/crush-map.e2e-spec.ts
new file mode 100644
index 000000000..0a454739f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/crush-map.e2e-spec.ts
@@ -0,0 +1,37 @@
+import { CrushMapPageHelper } from './crush-map.po';
+
+describe('CRUSH map page', () => {
+ const crushmap = new CrushMapPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ crushmap.navigateTo();
+ });
+
+ describe('breadcrumb test', () => {
+ it('should open and show breadcrumb', () => {
+ crushmap.expectBreadcrumbText('CRUSH map');
+ });
+ });
+
+ describe('fields check', () => {
+ it('should check that title & table appears', () => {
+ // Check that title (CRUSH map viewer) appears
+ crushmap.getPageTitle().should('equal', 'CRUSH map viewer');
+
+ // Check that title appears once OSD is clicked
+ crushmap.getCrushNode(0).click();
+
+ crushmap
+ .getLegends()
+ .invoke('text')
+ .then((legend) => {
+ crushmap.getCrushNode(0).should('have.text', legend);
+ });
+
+ // Check that table appears once OSD is clicked
+ crushmap.getDataTables().should('be.visible');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/crush-map.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/crush-map.po.ts
new file mode 100644
index 000000000..a5d2d591c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/crush-map.po.ts
@@ -0,0 +1,13 @@
+import { PageHelper } from '../page-helper.po';
+
+export class CrushMapPageHelper extends PageHelper {
+ pages = { index: { url: '#/crush-map', id: 'cd-crushmap' } };
+
+ getPageTitle() {
+ return cy.get('cd-crushmap .card-header').text();
+ }
+
+ getCrushNode(idx: number) {
+ return cy.get('.node-name.type-osd').eq(idx);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/hosts.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/hosts.e2e-spec.ts
new file mode 100644
index 000000000..e4f9936c3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/hosts.e2e-spec.ts
@@ -0,0 +1,35 @@
+import { HostsPageHelper } from './hosts.po';
+
+describe('Hosts page', () => {
+ const hosts = new HostsPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ hosts.navigateTo();
+ });
+
+ describe('breadcrumb and tab tests', () => {
+ it('should open and show breadcrumb', () => {
+ hosts.expectBreadcrumbText('Hosts');
+ });
+
+ it('should show two tabs', () => {
+ hosts.getTabsCount().should('eq', 2);
+ });
+
+ it('should show hosts list tab at first', () => {
+ hosts.getTabText(0).should('eq', 'Hosts List');
+ });
+
+ it('should show overall performance as a second tab', () => {
+ hosts.getTabText(1).should('eq', 'Overall Performance');
+ });
+ });
+
+ describe('services link test', () => {
+ it('should check at least one host is present', () => {
+ hosts.check_for_host();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/hosts.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/hosts.po.ts
new file mode 100644
index 000000000..33fe756ff
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/hosts.po.ts
@@ -0,0 +1,184 @@
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/hosts', id: 'cd-hosts' },
+ add: { url: '#/hosts/(modal:add)', id: 'cd-host-form' }
+};
+
+export class HostsPageHelper extends PageHelper {
+ pages = pages;
+
+ columnIndex = {
+ hostname: 2,
+ services: 3,
+ labels: 4,
+ status: 5
+ };
+
+ check_for_host() {
+ this.getTableCount('total').should('not.be.eq', 0);
+ }
+
+ add(hostname: string, exist?: boolean, maintenance?: boolean, labels: string[] = []) {
+ cy.get(`${this.pages.add.id}`).within(() => {
+ cy.get('#hostname').type(hostname);
+ if (maintenance) {
+ cy.get('label[for=maintenance]').click();
+ }
+ if (exist) {
+ cy.get('#hostname').should('have.class', 'ng-invalid');
+ }
+ });
+
+ if (labels.length) {
+ this.selectPredefinedLabels(labels);
+ }
+
+ cy.get('cd-submit-button').click();
+ // back to host list
+ cy.get(`${this.pages.index.id}`);
+ }
+
+ selectPredefinedLabels(labels: string[]) {
+ cy.get('a[data-testid=select-menu-edit]').click();
+ for (const label of labels) {
+ cy.get('.popover-body div.select-menu-item-content').contains(label).click();
+ }
+ }
+
+ checkExist(hostname: string, exist: boolean) {
+ this.getTableCell(this.columnIndex.hostname, hostname).should(($elements) => {
+ const hosts = $elements.map((_, el) => el.textContent).get();
+ if (exist) {
+ expect(hosts).to.include(hostname);
+ } else {
+ expect(hosts).to.not.include(hostname);
+ }
+ });
+ }
+
+ remove(hostname: string) {
+ super.delete(hostname, this.columnIndex.hostname, 'hosts');
+ }
+
+ // Add or remove labels on a host, then verify labels in the table
+ editLabels(hostname: string, labels: string[], add: boolean) {
+ this.getTableCell(this.columnIndex.hostname, hostname).click();
+ this.clickActionButton('edit');
+
+ // add or remove label badges
+ if (add) {
+ cy.get('cd-modal').find('.select-menu-edit').click();
+ for (const label of labels) {
+ cy.contains('cd-modal .badge', new RegExp(`^${label}$`)).should('not.exist');
+ cy.get('.popover-body input').type(`${label}{enter}`);
+ }
+ } else {
+ for (const label of labels) {
+ cy.contains('cd-modal .badge', new RegExp(`^${label}$`))
+ .find('.badge-remove')
+ .click();
+ }
+ }
+ cy.get('cd-modal cd-submit-button').click();
+ this.checkLabelExists(hostname, labels, add);
+ }
+
+ checkLabelExists(hostname: string, labels: string[], add: boolean) {
+ // Verify labels are added or removed from Labels column
+ // First find row with hostname, then find labels in the row
+ this.getTableCell(this.columnIndex.hostname, hostname)
+ .click()
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.labels}) .badge`)
+ .should(($ele) => {
+ const newLabels = $ele.toArray().map((v) => v.innerText);
+ for (const label of labels) {
+ if (add) {
+ expect(newLabels).to.include(label);
+ } else {
+ expect(newLabels).to.not.include(label);
+ }
+ }
+ });
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ maintenance(hostname: string, exit = false, force = false) {
+ this.clearTableSearchInput();
+ this.getTableCell(this.columnIndex.hostname, hostname).click();
+ if (force) {
+ this.clickActionButton('enter-maintenance');
+
+ cy.get('cd-modal').within(() => {
+ cy.contains('button', 'Continue').click();
+ });
+
+ this.getTableCell(this.columnIndex.hostname, hostname)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.status}) .badge`)
+ .should(($ele) => {
+ const status = $ele.toArray().map((v) => v.innerText);
+ expect(status).to.include('maintenance');
+ });
+ }
+ if (exit) {
+ this.getTableCell(this.columnIndex.hostname, hostname)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.status})`)
+ .then(($ele) => {
+ const status = $ele.toArray().map((v) => v.innerText);
+ if (status[0].includes('maintenance')) {
+ this.clickActionButton('exit-maintenance');
+ }
+ });
+
+ this.getTableCell(this.columnIndex.hostname, hostname)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.status})`)
+ .should(($ele) => {
+ const status = $ele.toArray().map((v) => v.innerText);
+ expect(status).to.not.include('maintenance');
+ });
+ } else {
+ this.clickActionButton('enter-maintenance');
+
+ this.getTableCell(this.columnIndex.hostname, hostname)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.status}) .badge`)
+ .should(($ele) => {
+ const status = $ele.toArray().map((v) => v.innerText);
+ expect(status).to.include('maintenance');
+ });
+ }
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ drain(hostname: string) {
+ this.getTableCell(this.columnIndex.hostname, hostname).click();
+ this.clickActionButton('start-drain');
+ this.checkLabelExists(hostname, ['_no_schedule'], true);
+
+ // unselect it to avoid colliding with any other selection
+ // in different steps
+ this.getTableCell(this.columnIndex.hostname, hostname).click();
+
+ this.clickTab('cd-host-details', hostname, 'Daemons');
+ cy.get('cd-host-details').within(() => {
+ cy.wait(20000);
+ this.expectTableCount('total', 0);
+ });
+ }
+
+ checkServiceInstancesExist(hostname: string, instances: string[]) {
+ this.getTableCell(this.columnIndex.hostname, hostname)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.services}) .badge`)
+ .should(($ele) => {
+ const serviceInstances = $ele.toArray().map((v) => v.innerText);
+ for (const instance of instances) {
+ expect(serviceInstances).to.include(instance);
+ }
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/inventory.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/inventory.po.ts
new file mode 100644
index 000000000..5a9abdc03
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/inventory.po.ts
@@ -0,0 +1,22 @@
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/inventory', id: 'cd-inventory' }
+};
+
+export class InventoryPageHelper extends PageHelper {
+ pages = pages;
+
+ identify() {
+ // Nothing we can do, just verify the form is there
+ this.getFirstTableCell().click();
+ cy.contains('cd-table-actions button', 'Identify').click();
+ cy.get('cd-modal').within(() => {
+ cy.get('#duration').select('15 minutes');
+ cy.get('#duration').select('10 minutes');
+ cy.get('cd-back-button').click();
+ });
+ cy.get('cd-modal').should('not.exist');
+ cy.get(`${this.pages.index.id}`);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/logs.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/logs.e2e-spec.ts
new file mode 100644
index 000000000..9868b89ae
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/logs.e2e-spec.ts
@@ -0,0 +1,58 @@
+import { PoolPageHelper } from '../pools/pools.po';
+import { LogsPageHelper } from './logs.po';
+
+describe('Logs page', () => {
+ const logs = new LogsPageHelper();
+ const pools = new PoolPageHelper();
+
+ const poolname = 'e2e_logs_test_pool';
+ const today = new Date();
+ let hour = today.getHours();
+ if (hour > 12) {
+ hour = hour - 12;
+ }
+ const minute = today.getMinutes();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ });
+
+ describe('breadcrumb and tab tests', () => {
+ beforeEach(() => {
+ logs.navigateTo();
+ });
+
+ it('should open and show breadcrumb', () => {
+ logs.expectBreadcrumbText('Logs');
+ });
+
+ it('should show two tabs', () => {
+ logs.getTabsCount().should('eq', 2);
+ });
+
+ it('should show cluster logs tab at first', () => {
+ logs.getTabText(0).should('eq', 'Cluster Logs');
+ });
+
+ it('should show audit logs as a second tab', () => {
+ logs.getTabText(1).should('eq', 'Audit Logs');
+ });
+ });
+
+ describe('audit logs respond to pool creation and deletion test', () => {
+ it('should create pool and check audit logs reacted', () => {
+ pools.navigateTo('create');
+ pools.create(poolname, 8);
+ pools.navigateTo();
+ pools.existTableCell(poolname, true);
+ logs.checkAuditForPoolFunction(poolname, 'create', hour, minute);
+ });
+
+ it('should delete pool and check audit logs reacted', () => {
+ pools.navigateTo();
+ pools.delete(poolname);
+ logs.checkAuditForPoolFunction(poolname, 'delete', hour, minute);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/logs.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/logs.po.ts
new file mode 100644
index 000000000..7efd8a652
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/logs.po.ts
@@ -0,0 +1,70 @@
+import { PageHelper } from '../page-helper.po';
+
+export class LogsPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/logs', id: 'cd-logs' }
+ };
+
+ checkAuditForPoolFunction(poolname: string, poolfunction: string, hour: number, minute: number) {
+ this.navigateTo();
+
+ // sometimes the modal from deleting pool is still present at this point.
+ // This wait makes sure it isn't
+ cy.contains('.modal-dialog', 'Delete Pool').should('not.exist');
+
+ // go to audit logs tab
+ cy.contains('.nav-link', 'Audit Logs').click();
+
+ // Enter an earliest time so that no old messages with the same pool name show up
+ cy.get('.ngb-tp-input').its(0).clear();
+
+ if (hour < 10) {
+ cy.get('.ngb-tp-input').its(0).type('0');
+ }
+ cy.get('.ngb-tp-input').its(0).type(`${hour}`);
+
+ cy.get('.ngb-tp-input').its(1).clear();
+ if (minute < 10) {
+ cy.get('.ngb-tp-input').its(1).type('0');
+ }
+ cy.get('.ngb-tp-input').its(1).type(`${minute}`);
+
+ // Enter the pool name into the filter box
+ cy.get('input.form-control.ng-valid').first().clear().type(poolname);
+
+ cy.get('.tab-pane.active')
+ .get('.card-body')
+ .get('.message')
+ .should('contain.text', poolname)
+ .and('contain.text', `pool ${poolfunction}`);
+ }
+
+ checkAuditForConfigChange(configname: string, setting: string, hour: number, minute: number) {
+ this.navigateTo();
+
+ // go to audit logs tab
+ cy.contains('.nav-link', 'Audit Logs').click();
+
+ // Enter an earliest time so that no old messages with the same config name show up
+ cy.get('.ngb-tp-input').its(0).clear();
+ if (hour < 10) {
+ cy.get('.ngb-tp-input').its(0).type('0');
+ }
+ cy.get('.ngb-tp-input').its(0).type(`${hour}`);
+
+ cy.get('.ngb-tp-input').its(1).clear();
+ if (minute < 10) {
+ cy.get('.ngb-tp-input').its(1).type('0');
+ }
+ cy.get('.ngb-tp-input').its(1).type(`${minute}`);
+
+ // Enter the config name into the filter box
+ cy.get('input.form-control.ng-valid').first().clear().type(configname);
+
+ cy.get('.tab-pane.active')
+ .get('.card-body')
+ .get('.message')
+ .should('contain.text', configname)
+ .and('contain.text', setting);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/mgr-modules.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/mgr-modules.e2e-spec.ts
new file mode 100644
index 000000000..50656fece
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/mgr-modules.e2e-spec.ts
@@ -0,0 +1,78 @@
+import { Input, ManagerModulesPageHelper } from './mgr-modules.po';
+
+describe('Manager modules page', () => {
+ const mgrmodules = new ManagerModulesPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ mgrmodules.navigateTo();
+ });
+
+ describe('breadcrumb test', () => {
+ it('should open and show breadcrumb', () => {
+ mgrmodules.expectBreadcrumbText('Manager Modules');
+ });
+ });
+
+ describe('verifies editing functionality for manager modules', () => {
+ it('should test editing on balancer module', () => {
+ const balancerArr: Input[] = [
+ {
+ id: 'crush_compat_max_iterations',
+ newValue: '123',
+ oldValue: '25'
+ }
+ ];
+ mgrmodules.editMgrModule('balancer', balancerArr);
+ });
+
+ it('should test editing on dashboard module', () => {
+ const dashboardArr: Input[] = [
+ {
+ id: 'GRAFANA_API_PASSWORD',
+ newValue: 'rafa',
+ oldValue: ''
+ }
+ ];
+ mgrmodules.editMgrModule('dashboard', dashboardArr);
+ });
+
+ it('should test editing on devicehealth module', () => {
+ const devHealthArray: Input[] = [
+ {
+ id: 'mark_out_threshold',
+ newValue: '1987',
+ oldValue: '2419200'
+ },
+ {
+ id: 'pool_name',
+ newValue: 'sox',
+ oldValue: 'device_health_metrics'
+ },
+ {
+ id: 'retention_period',
+ newValue: '1999',
+ oldValue: '15552000'
+ },
+ {
+ id: 'scrape_frequency',
+ newValue: '2020',
+ oldValue: '86400'
+ },
+ {
+ id: 'sleep_interval',
+ newValue: '456',
+ oldValue: '600'
+ },
+ {
+ id: 'warn_threshold',
+ newValue: '567',
+ oldValue: '7257600'
+ }
+ ];
+
+ mgrmodules.editMgrModule('devicehealth', devHealthArray);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/mgr-modules.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/mgr-modules.po.ts
new file mode 100644
index 000000000..04d2eee46
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/mgr-modules.po.ts
@@ -0,0 +1,57 @@
+import { PageHelper } from '../page-helper.po';
+
+export class Input {
+ id: string;
+ oldValue: string;
+ newValue: string;
+}
+
+export class ManagerModulesPageHelper extends PageHelper {
+ pages = { index: { url: '#/mgr-modules', id: 'cd-mgr-module-list' } };
+
+ /**
+ * Selects the Manager Module and then fills in the desired fields.
+ */
+ editMgrModule(name: string, inputs: Input[]) {
+ this.navigateEdit(name);
+
+ for (const input of inputs) {
+ // Clears fields and adds edits
+ cy.get(`#${input.id}`).clear().type(input.newValue);
+ }
+
+ cy.contains('button', 'Update').click();
+ // Checks if edits appear
+ this.getExpandCollapseElement(name).should('be.visible').click();
+
+ for (const input of inputs) {
+ cy.get('.datatable-body').last().contains(input.newValue);
+ }
+
+ // Clear mgr module of all edits made to it
+ this.navigateEdit(name);
+
+ // Clears the editable fields
+ for (const input of inputs) {
+ if (input.oldValue) {
+ const id = `#${input.id}`;
+ cy.get(id).clear();
+ if (input.oldValue) {
+ cy.get(id).type(input.oldValue);
+ }
+ }
+ }
+
+ // Checks that clearing represents in details tab of module
+ cy.contains('button', 'Update').click();
+ this.getExpandCollapseElement(name).should('be.visible').click();
+ for (const input of inputs) {
+ if (input.oldValue) {
+ cy.get('.datatable-body')
+ .eq(1)
+ .should('contain', input.id)
+ .and('not.contain', input.newValue);
+ }
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/monitors.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/monitors.e2e-spec.ts
new file mode 100644
index 000000000..a23d071e6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/monitors.e2e-spec.ts
@@ -0,0 +1,62 @@
+import { MonitorsPageHelper } from './monitors.po';
+
+describe('Monitors page', () => {
+ const monitors = new MonitorsPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ monitors.navigateTo();
+ });
+
+ describe('breadcrumb test', () => {
+ it('should open and show breadcrumb', () => {
+ monitors.expectBreadcrumbText('Monitors');
+ });
+ });
+
+ describe('fields check', () => {
+ it('should check status table is present', () => {
+ // check for table header 'Status'
+ monitors.getLegends().its(0).should('have.text', 'Status');
+
+ // check for fields in table
+ monitors
+ .getStatusTables()
+ .should('contain.text', 'Cluster ID')
+ .and('contain.text', 'monmap modified')
+ .and('contain.text', 'monmap epoch')
+ .and('contain.text', 'quorum con')
+ .and('contain.text', 'quorum mon')
+ .and('contain.text', 'required con')
+ .and('contain.text', 'required mon');
+ });
+
+ it('should check In Quorum and Not In Quorum tables are present', () => {
+ // check for there to be two tables
+ monitors.getDataTables().should('have.length', 2);
+
+ // check for table header 'In Quorum'
+ monitors.getLegends().its(1).should('have.text', 'In Quorum');
+
+ // check for table header 'Not In Quorum'
+ monitors.getLegends().its(2).should('have.text', 'Not In Quorum');
+
+ // verify correct columns on In Quorum table
+ monitors.getDataTableHeaders(0).contains('Name');
+
+ monitors.getDataTableHeaders(0).contains('Rank');
+
+ monitors.getDataTableHeaders(0).contains('Public Address');
+
+ monitors.getDataTableHeaders(0).contains('Open Sessions');
+
+ // verify correct columns on Not In Quorum table
+ monitors.getDataTableHeaders(1).contains('Name');
+
+ monitors.getDataTableHeaders(1).contains('Rank');
+
+ monitors.getDataTableHeaders(1).contains('Public Address');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/monitors.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/monitors.po.ts
new file mode 100644
index 000000000..4113b9928
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/monitors.po.ts
@@ -0,0 +1,7 @@
+import { PageHelper } from '../page-helper.po';
+
+export class MonitorsPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/monitor', id: 'cd-monitor' }
+ };
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/osds.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/osds.e2e-spec.ts
new file mode 100644
index 000000000..e68d03bd5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/osds.e2e-spec.ts
@@ -0,0 +1,57 @@
+import { OSDsPageHelper } from './osds.po';
+
+describe('OSDs page', () => {
+ const osds = new OSDsPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ osds.navigateTo();
+ });
+
+ describe('breadcrumb and tab tests', () => {
+ it('should open and show breadcrumb', () => {
+ osds.expectBreadcrumbText('OSDs');
+ });
+
+ it('should show two tabs', () => {
+ osds.getTabsCount().should('eq', 2);
+ osds.getTabText(0).should('eq', 'OSDs List');
+ osds.getTabText(1).should('eq', 'Overall Performance');
+ });
+ });
+
+ describe('check existence of fields on OSD page', () => {
+ it('should check that number of rows and count in footer match', () => {
+ osds.getTableCount('total').then((text) => {
+ osds.getTableRows().its('length').should('equal', text);
+ });
+ });
+
+ it('should verify that buttons exist', () => {
+ cy.contains('button', 'Create');
+ cy.contains('button', 'Cluster-wide configuration');
+ });
+
+ describe('by selecting one row in OSDs List', () => {
+ beforeEach(() => {
+ osds.getExpandCollapseElement().click();
+ });
+
+ it('should show the correct text for the tab labels', () => {
+ cy.get('#tabset-osd-details > li > a').then(($tabs) => {
+ const tabHeadings = $tabs.map((_i, e) => e.textContent).get();
+
+ expect(tabHeadings).to.eql([
+ 'Devices',
+ 'Attributes (OSD map)',
+ 'Metadata',
+ 'Device health',
+ 'Performance counter',
+ 'Performance Details'
+ ]);
+ });
+ });
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/osds.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/osds.po.ts
new file mode 100644
index 000000000..cd812f474
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/osds.po.ts
@@ -0,0 +1,84 @@
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/osd', id: 'cd-osd-list' },
+ create: { url: '#/osd/create', id: 'cd-osd-form' }
+};
+
+export class OSDsPageHelper extends PageHelper {
+ pages = pages;
+
+ columnIndex = {
+ id: 3,
+ status: 5
+ };
+
+ create(deviceType: 'hdd' | 'ssd', hostname?: string, expandCluster = false) {
+ cy.get('[aria-label="toggle advanced mode"]').click();
+ // Click Primary devices Add button
+ cy.get('cd-osd-devices-selection-groups[name="Primary"]').as('primaryGroups');
+ cy.get('@primaryGroups').find('button').click();
+
+ // Select all devices with `deviceType`
+ cy.get('cd-osd-devices-selection-modal').within(() => {
+ cy.get('.modal-footer .tc_submitButton').as('addButton').should('be.disabled');
+ this.filterTable('Type', deviceType);
+ if (hostname) {
+ this.filterTable('Hostname', hostname);
+ }
+
+ if (expandCluster) {
+ this.getTableCount('total').should('be.gte', 1);
+ }
+ cy.get('@addButton').click();
+ });
+
+ if (!expandCluster) {
+ cy.get('@primaryGroups').within(() => {
+ this.getTableCount('total').as('newOSDCount');
+ });
+
+ cy.get(`${pages.create.id} .card-footer .tc_submitButton`).click();
+ cy.get(`cd-osd-creation-preview-modal .modal-footer .tc_submitButton`).click();
+ }
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ checkStatus(id: number, status: string[]) {
+ this.searchTable(`id:${id}`);
+ this.expectTableCount('found', 1);
+ cy.get(`datatable-body-cell:nth-child(${this.columnIndex.status}) .badge`).should(($ele) => {
+ const allStatus = $ele.toArray().map((v) => v.innerText);
+ for (const s of status) {
+ expect(allStatus).to.include(s);
+ }
+ });
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ ensureNoOsd(id: number) {
+ this.searchTable(`id:${id}`);
+ this.expectTableCount('found', 0);
+ this.clearTableSearchInput();
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ deleteByIDs(osdIds: number[], replace?: boolean) {
+ this.getTableRows().each(($el) => {
+ const rowOSD = Number(
+ $el.find('datatable-body-cell .datatable-body-cell-label').get(this.columnIndex.id - 1)
+ .textContent
+ );
+ if (osdIds.includes(rowOSD)) {
+ cy.wrap($el).click();
+ }
+ });
+ this.clickActionButton('delete');
+ if (replace) {
+ cy.get('cd-modal label[for="preserve"]').click();
+ }
+ cy.get('cd-modal label[for="confirmation"]').click();
+ cy.contains('cd-modal button', 'Delete').click();
+ cy.get('cd-modal').should('not.exist');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/services.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/services.po.ts
new file mode 100644
index 000000000..481d6bc9b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/services.po.ts
@@ -0,0 +1,204 @@
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/services', id: 'cd-services' },
+ create: { url: '#/services/(modal:create)', id: 'cd-service-form' }
+};
+
+export class ServicesPageHelper extends PageHelper {
+ pages = pages;
+
+ columnIndex = {
+ service_name: 2,
+ placement: 3,
+ running: 4,
+ size: 5,
+ last_refresh: 6
+ };
+
+ serviceDetailColumnIndex = {
+ daemonName: 2,
+ status: 4
+ };
+
+ check_for_service() {
+ this.getTableCount('total').should('not.be.eq', 0);
+ }
+
+ private selectServiceType(serviceType: string) {
+ return this.selectOption('service_type', serviceType);
+ }
+
+ clickServiceTab(serviceName: string, tabName: string) {
+ this.getExpandCollapseElement(serviceName).click();
+ cy.get('cd-service-details').within(() => {
+ this.getTab(tabName).click();
+ });
+ }
+
+ addService(
+ serviceType: string,
+ exist?: boolean,
+ count = '1',
+ snmpVersion?: string,
+ snmpPrivProtocol?: boolean,
+ unmanaged = false
+ ) {
+ cy.get(`${this.pages.create.id}`).within(() => {
+ this.selectServiceType(serviceType);
+ switch (serviceType) {
+ case 'rgw':
+ cy.get('#service_id').type('foo');
+ unmanaged ? cy.get('label[for=unmanaged]').click() : cy.get('#count').type(count);
+ break;
+
+ case 'ingress':
+ if (unmanaged) {
+ cy.get('label[for=unmanaged]').click();
+ }
+ this.selectOption('backend_service', 'rgw.foo');
+ cy.get('#service_id').should('have.value', 'rgw.foo');
+ cy.get('#virtual_ip').type('192.168.100.1/24');
+ cy.get('#frontend_port').type('8081');
+ cy.get('#monitor_port').type('8082');
+ break;
+
+ case 'nfs':
+ cy.get('#service_id').type('testnfs');
+ unmanaged ? cy.get('label[for=unmanaged]').click() : cy.get('#count').type(count);
+ break;
+
+ case 'snmp-gateway':
+ this.selectOption('snmp_version', snmpVersion);
+ cy.get('#snmp_destination').type('192.168.0.1:8443');
+ if (snmpVersion === 'V2c') {
+ cy.get('#snmp_community').type('public');
+ } else {
+ cy.get('#engine_id').type('800C53F00000');
+ this.selectOption('auth_protocol', 'SHA');
+ if (snmpPrivProtocol) {
+ this.selectOption('privacy_protocol', 'DES');
+ cy.get('#snmp_v3_priv_password').type('testencrypt');
+ }
+
+ // Credentials
+ cy.get('#snmp_v3_auth_username').type('test');
+ cy.get('#snmp_v3_auth_password').type('testpass');
+ }
+ break;
+
+ default:
+ cy.get('#service_id').type('test');
+ unmanaged ? cy.get('label[for=unmanaged]').click() : cy.get('#count').type(count);
+ break;
+ }
+ if (serviceType === 'snmp-gateway') {
+ cy.get('cd-submit-button').dblclick();
+ } else {
+ cy.get('cd-submit-button').click();
+ }
+ });
+ if (exist) {
+ cy.get('#service_id').should('have.class', 'ng-invalid');
+ } else {
+ // back to service list
+ cy.get(`${this.pages.index.id}`);
+ }
+ }
+
+ editService(name: string, daemonCount: string) {
+ this.navigateEdit(name, true, false);
+ cy.get(`${this.pages.create.id}`).within(() => {
+ cy.get('#service_type').should('be.disabled');
+ cy.get('#service_id').should('be.disabled');
+ cy.get('#count').clear().type(daemonCount);
+ cy.get('cd-submit-button').click();
+ });
+ }
+
+ checkServiceStatus(daemon: string, expectedStatus = 'running') {
+ let daemonNameIndex = this.serviceDetailColumnIndex.daemonName;
+ let statusIndex = this.serviceDetailColumnIndex.status;
+
+ // since hostname row is hidden from the hosts details table,
+ // we'll need to manually override the indexes when this check is being
+ // done for the daemons in host details page. So we'll get the url and
+ // verify if the current page is not the services index page
+ cy.url().then((url) => {
+ if (!url.includes(pages.index.url)) {
+ daemonNameIndex = 1;
+ statusIndex = 3;
+ }
+
+ cy.get('cd-service-daemon-list').within(() => {
+ this.getTableCell(daemonNameIndex, daemon, true)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${statusIndex}) .badge`)
+ .should(($ele) => {
+ const status = $ele.toArray().map((v) => v.innerText);
+ expect(status).to.include(expectedStatus);
+ });
+ });
+ });
+ }
+
+ expectPlacementCount(serviceName: string, expectedCount: string) {
+ this.getTableCell(this.columnIndex.service_name, serviceName)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.placement})`)
+ .should(($ele) => {
+ const running = $ele.text().split(';');
+ expect(running).to.include(`count:${expectedCount}`);
+ });
+ }
+
+ checkExist(serviceName: string, exist: boolean) {
+ this.getTableCell(this.columnIndex.service_name, serviceName).should(($elements) => {
+ const services = $elements.map((_, el) => el.textContent).get();
+ if (exist) {
+ expect(services).to.include(serviceName);
+ } else {
+ expect(services).to.not.include(serviceName);
+ }
+ });
+ }
+
+ isUnmanaged(serviceName: string, unmanaged: boolean) {
+ this.getTableCell(this.columnIndex.service_name, serviceName)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.placement})`)
+ .should(($ele) => {
+ const placement = $ele.text().split(';');
+ unmanaged
+ ? expect(placement).to.include('unmanaged')
+ : expect(placement).to.not.include('unmanaged');
+ });
+ }
+
+ deleteService(serviceName: string) {
+ const getRow = this.getTableCell.bind(this, this.columnIndex.service_name);
+ getRow(serviceName).click();
+
+ // Clicks on table Delete button
+ this.clickActionButton('delete');
+
+ // Confirms deletion
+ cy.get('cd-modal .custom-control-label').click();
+ cy.contains('cd-modal button', 'Delete').click();
+
+ // Wait for modal to close
+ cy.get('cd-modal').should('not.exist');
+ this.checkExist(serviceName, false);
+ }
+
+ daemonAction(daemon: string, action: string) {
+ cy.get('cd-service-daemon-list').within(() => {
+ this.getTableRow(daemon).click();
+ this.clickActionButton(action);
+
+ // unselect it to avoid colliding with any other selection
+ // in different steps
+ this.getTableRow(daemon).click();
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/common/01-global.feature.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/common/01-global.feature.po.ts
new file mode 100644
index 000000000..575d4013b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/common/01-global.feature.po.ts
@@ -0,0 +1,188 @@
+import { And, Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
+
+import { UrlsCollection } from './urls.po';
+
+const urlsCollection = new UrlsCollection();
+
+Given('I am logged in', () => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+});
+
+Given('I am on the {string} page', (page: string) => {
+ cy.visit(urlsCollection.pages[page].url);
+ cy.get(urlsCollection.pages[page].id).should('exist');
+});
+
+Then('I should be on the {string} page', (page: string) => {
+ cy.get(urlsCollection.pages[page].id).should('exist');
+});
+
+And('I should see a button to {string}', (button: string) => {
+ cy.get(`[aria-label="${button}"]`).should('be.visible');
+});
+
+When('I click on {string} button', (button: string) => {
+ cy.get(`[aria-label="${button}"]`).first().click();
+});
+
+// When you are clicking on an action in the table actions dropdown button
+When('I click on {string} button from the table actions', (button: string) => {
+ cy.get('.table-actions button.dropdown-toggle').first().click();
+ cy.get(`[aria-label="${button}"]`).first().click();
+});
+
+And('select options {string}', (labels: string) => {
+ if (labels) {
+ cy.get('a[data-testid=select-menu-edit]').click();
+ for (const label of labels.split(', ')) {
+ cy.get('.popover-body div.select-menu-item-content').contains(label).click();
+ }
+ }
+});
+
+And('{string} option {string}', (action: string, labels: string) => {
+ if (labels) {
+ if (action === 'add') {
+ cy.get('cd-modal').find('.select-menu-edit').click();
+ for (const label of labels.split(', ')) {
+ cy.get('.popover-body input').type(`${label}{enter}`);
+ }
+ } else {
+ for (const label of labels.split(', ')) {
+ cy.contains('cd-modal .badge', new RegExp(`^${label}$`))
+ .find('.badge-remove')
+ .click();
+ }
+ }
+ }
+});
+
+/**
+ * Fills in the given field using the value provided
+ * @param field ID of the field that needs to be filled out.
+ * @param value Value that should be filled in the field.
+ */
+And('enter {string} {string}', (field: string, value: string) => {
+ cy.get('cd-modal').within(() => {
+ cy.get(`input[id=${field}]`).type(value);
+ });
+});
+
+And('I click on submit button', () => {
+ cy.get('[data-cy=submitBtn]').click();
+});
+
+/**
+ * Selects any row on the datatable if it matches the given name
+ */
+When('I select a row {string}', (row: string) => {
+ cy.get('cd-table .search input').first().clear().type(row);
+ cy.contains(`datatable-body-row datatable-body-cell .datatable-body-cell-label`, row).click();
+});
+
+Then('I should see the modal', () => {
+ cy.get('cd-modal').should('exist');
+});
+
+Then('I should not see the modal', () => {
+ cy.get('cd-modal').should('not.exist');
+});
+
+/**
+ * Some modals have an additional confirmation to be provided
+ * by ticking the 'Are you sure?' box.
+ */
+Then('I check the tick box in modal', () => {
+ cy.get('cd-modal .custom-control-label').click();
+});
+
+And('I confirm to {string}', (action: string) => {
+ cy.contains('cd-modal button', action).click();
+ cy.get('cd-modal').should('not.exist');
+});
+
+Then('I should see an error in {string} field', (field: string) => {
+ cy.get('cd-modal').within(() => {
+ cy.get(`input[id=${field}]`).should('have.class', 'ng-invalid');
+ });
+});
+
+Then('I should see a row with {string}', (row: string) => {
+ cy.get('cd-table .search input').first().clear().type(row);
+ cy.contains(`datatable-body-row datatable-body-cell .datatable-body-cell-label`, row).should(
+ 'exist'
+ );
+});
+
+Then('I should not see a row with {string}', (row: string) => {
+ cy.get('cd-table .search input').first().clear().type(row);
+ cy.contains(`datatable-body-row datatable-body-cell .datatable-body-cell-label`, row).should(
+ 'not.exist'
+ );
+});
+
+Then('I should see rows with following entries', (entries) => {
+ entries.hashes().forEach((entry: any) => {
+ cy.get('cd-table .search input').first().clear().type(entry.hostname);
+ cy.contains(
+ `datatable-body-row datatable-body-cell .datatable-body-cell-label`,
+ entry.hostname
+ ).should('exist');
+ });
+});
+
+And('I should see row {string} have {string}', (row: string, options: string) => {
+ if (options) {
+ cy.get('cd-table .search input').first().clear().type(row);
+ for (const option of options.split(',')) {
+ cy.contains(
+ `datatable-body-row datatable-body-cell .datatable-body-cell-label .badge`,
+ option
+ ).should('exist');
+ }
+ }
+});
+
+And('I should see row {string} does not have {string}', (row: string, options: string) => {
+ if (options) {
+ cy.get('cd-table .search input').first().clear().type(row);
+ for (const option of options.split(',')) {
+ cy.contains(
+ `datatable-body-row datatable-body-cell .datatable-body-cell-label .badge`,
+ option
+ ).should('not.exist');
+ }
+ }
+});
+
+And('I go to the {string} tab', (names: string) => {
+ for (const name of names.split(', ')) {
+ cy.contains('.nav.nav-tabs li', name).click();
+ }
+});
+
+And('select {string} {string}', (selectionName: string, option: string) => {
+ cy.get(`select[name=${selectionName}]`).select(option);
+ cy.get(`select[name=${selectionName}] option:checked`).contains(option);
+});
+
+When('I expand the row {string}', (row: string) => {
+ cy.contains('.datatable-body-row', row).first().find('.tc_expand-collapse').click();
+});
+
+And('I should see row {string} have {string} on this tab', (row: string, options: string) => {
+ if (options) {
+ cy.get('cd-table').should('exist');
+ cy.get('datatable-scroller, .empty-row');
+ cy.get('.datatable-row-detail').within(() => {
+ cy.get('cd-table .search input').first().clear().type(row);
+ for (const option of options.split(',')) {
+ cy.contains(
+ `datatable-body-row datatable-body-cell .datatable-body-cell-label span`,
+ option
+ ).should('exist');
+ }
+ });
+ }
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/common/create-cluster/create-cluster.feature.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/common/create-cluster/create-cluster.feature.po.ts
new file mode 100644
index 000000000..d18c34855
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/common/create-cluster/create-cluster.feature.po.ts
@@ -0,0 +1,12 @@
+import { Given, Then } from 'cypress-cucumber-preprocessor/steps';
+
+Given('I am on the {string} section', (page: string) => {
+ cy.get('cd-wizard').within(() => {
+ cy.get('.nav-link').should('contain.text', page).first().click();
+ cy.get('.nav-link.active').should('contain.text', page);
+ });
+});
+
+Then('I should see a message {string}', () => {
+ cy.get('cd-create-cluster').should('contain.text', 'Please expand your cluster first');
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/common/grafana.feature.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/common/grafana.feature.po.ts
new file mode 100644
index 000000000..7366f8bab
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/common/grafana.feature.po.ts
@@ -0,0 +1,86 @@
+import { e2e } from '@grafana/e2e';
+import { Then, When } from 'cypress-cucumber-preprocessor/steps';
+import 'cypress-iframe';
+
+function getIframe() {
+ cy.frameLoaded('#iframe');
+ return cy.iframe();
+}
+
+Then('I should see the grafana panel {string}', (panels: string) => {
+ getIframe().within(() => {
+ for (const panel of panels.split(', ')) {
+ cy.get('.grafana-app')
+ .wait(100)
+ .within(() => {
+ e2e.components.Panels.Panel.title(panel).should('be.visible');
+ });
+ }
+ });
+});
+
+When('I view the grafana panel {string}', (panels: string) => {
+ getIframe().within(() => {
+ for (const panel of panels.split(', ')) {
+ cy.get('.grafana-app')
+ .wait(100)
+ .within(() => {
+ e2e.components.Panels.Panel.title(panel).should('be.visible').click();
+ e2e.components.Panels.Panel.headerItems('View').should('be.visible').click();
+ });
+ }
+ });
+});
+
+Then('I should not see {string} in the panel {string}', (value: string, panels: string) => {
+ getIframe().within(() => {
+ for (const panel of panels.split(', ')) {
+ cy.get('.grafana-app')
+ .wait(100)
+ .within(() => {
+ cy.get(`[aria-label="${panel} panel"]`)
+ .should('be.visible')
+ .within(() => {
+ cy.get('span').first().should('not.have.text', value);
+ });
+ });
+ }
+ });
+});
+
+Then(
+ 'I should see the legends {string} in the graph {string}',
+ (legends: string, panels: string) => {
+ getIframe().within(() => {
+ for (const panel of panels.split(', ')) {
+ cy.get('.grafana-app')
+ .wait(100)
+ .within(() => {
+ cy.get(`[aria-label="${panel} panel"]`)
+ .should('be.visible')
+ .within(() => {
+ for (const legend of legends.split(', ')) {
+ cy.get('a').contains(legend);
+ }
+ });
+ });
+ }
+ });
+ }
+);
+
+Then('I should not see No Data in the graph {string}', (panels: string) => {
+ getIframe().within(() => {
+ for (const panel of panels.split(', ')) {
+ cy.get('.grafana-app')
+ .wait(100)
+ .within(() => {
+ cy.get(`[aria-label="${panel} panel"]`)
+ .should('be.visible')
+ .within(() => {
+ cy.get('div.datapoints-warning').should('not.exist');
+ });
+ });
+ }
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/common/urls.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/common/urls.po.ts
new file mode 100644
index 000000000..286355085
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/common/urls.po.ts
@@ -0,0 +1,44 @@
+import { PageHelper } from '../page-helper.po';
+
+export class UrlsCollection extends PageHelper {
+ pages = {
+ // Cluster expansion
+ welcome: { url: '#/expand-cluster', id: 'cd-create-cluster' },
+
+ // Landing page
+ dashboard: { url: '#/dashboard', id: 'cd-dashboard' },
+
+ // Hosts
+ hosts: { url: '#/hosts', id: 'cd-hosts' },
+ 'add hosts': { url: '#/hosts/(modal:add)', id: 'cd-host-form' },
+
+ // Services
+ services: { url: '#/services', id: 'cd-services' },
+ 'create services': { url: '#/services/(modal:create)', id: 'cd-service-form' },
+
+ // Physical Disks
+ 'physical disks': { url: '#/inventory', id: 'cd-inventory' },
+
+ // Monitors
+ monitors: { url: '#/monitor', id: 'cd-monitor' },
+
+ // OSDs
+ osds: { url: '#/osd', id: 'cd-osd-list' },
+ 'create osds': { url: '#/osd/create', id: 'cd-osd-form' },
+
+ // Configuration
+ configuration: { url: '#/configuration', id: 'cd-configuration' },
+
+ // Crush Map
+ 'crush map': { url: '#/crush-map', id: 'cd-crushmap' },
+
+ // Mgr modules
+ 'mgr-modules': { url: '#/mgr-modules', id: 'cd-mgr-module-list' },
+
+ // Logs
+ logs: { url: '#/logs', id: 'cd-logs' },
+
+ // RGW Daemons
+ 'rgw daemons': { url: '#/rgw/daemon', id: 'cd-rgw-daemon-list' }
+ };
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/filesystems/filesystems.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/filesystems/filesystems.e2e-spec.ts
new file mode 100644
index 000000000..e623475fd
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/filesystems/filesystems.e2e-spec.ts
@@ -0,0 +1,17 @@
+import { FilesystemsPageHelper } from './filesystems.po';
+
+describe('File Systems page', () => {
+ const filesystems = new FilesystemsPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ filesystems.navigateTo();
+ });
+
+ describe('breadcrumb test', () => {
+ it('should open and show breadcrumb', () => {
+ filesystems.expectBreadcrumbText('File Systems');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/filesystems/filesystems.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/filesystems/filesystems.po.ts
new file mode 100644
index 000000000..bd6e5b8b7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/filesystems/filesystems.po.ts
@@ -0,0 +1,5 @@
+import { PageHelper } from '../page-helper.po';
+
+export class FilesystemsPageHelper extends PageHelper {
+ pages = { index: { url: '#/cephfs', id: 'cd-cephfs-list' } };
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/01-hosts.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/01-hosts.e2e-spec.ts
new file mode 100644
index 000000000..aca36ade1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/01-hosts.e2e-spec.ts
@@ -0,0 +1,86 @@
+import { HostsPageHelper } from '../cluster/hosts.po';
+
+describe('Hosts page', () => {
+ const hosts = new HostsPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ hosts.navigateTo();
+ });
+
+ describe('when Orchestrator is available', () => {
+ beforeEach(function () {
+ cy.fixture('orchestrator/inventory.json').as('hosts');
+ cy.fixture('orchestrator/services.json').as('services');
+ });
+
+ it('should not add an exsiting host', function () {
+ const hostname = Cypress._.sample(this.hosts).name;
+ hosts.navigateTo('add');
+ hosts.add(hostname, true);
+ });
+
+ it('should drain and remove a host and then add it back', function () {
+ const hostname = Cypress._.last(this.hosts)['name'];
+
+ // should drain the host first before deleting
+ hosts.drain(hostname);
+ hosts.remove(hostname);
+
+ // add it back
+ hosts.navigateTo('add');
+ hosts.add(hostname);
+ hosts.checkExist(hostname, true);
+ });
+
+ it('should display inventory', function () {
+ for (const host of this.hosts) {
+ hosts.clickTab('cd-host-details', host.name, 'Physical Disks');
+ cy.get('cd-host-details').within(() => {
+ hosts.expectTableCount('total', host.devices.length);
+ });
+ }
+ });
+
+ it('should display daemons', function () {
+ for (const host of this.hosts) {
+ hosts.clickTab('cd-host-details', host.name, 'Daemons');
+ cy.get('cd-host-details').within(() => {
+ hosts.getTableCount('total').should('be.gte', 0);
+ });
+ }
+ });
+
+ it('should edit host labels', function () {
+ const hostname = Cypress._.sample(this.hosts).name;
+ const labels = ['foo', 'bar'];
+ hosts.editLabels(hostname, labels, true);
+ hosts.editLabels(hostname, labels, false);
+ });
+
+ it('should enter host into maintenance', function () {
+ const hostname = Cypress._.sample(this.hosts).name;
+ const serviceList = new Array();
+ this.services.forEach((service: any) => {
+ if (hostname === service.hostname) {
+ serviceList.push(service.daemon_type);
+ }
+ });
+ let enterMaintenance = true;
+ serviceList.forEach((service: string) => {
+ if (service === 'mgr' || service === 'alertmanager') {
+ enterMaintenance = false;
+ }
+ });
+ if (enterMaintenance) {
+ hosts.maintenance(hostname);
+ }
+ });
+
+ it('should exit host from maintenance', function () {
+ const hostname = Cypress._.sample(this.hosts).name;
+ hosts.maintenance(hostname, true);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/03-inventory.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/03-inventory.e2e-spec.ts
new file mode 100644
index 000000000..a64e3bc8c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/03-inventory.e2e-spec.ts
@@ -0,0 +1,26 @@
+import { InventoryPageHelper } from '../cluster/inventory.po';
+
+describe('Physical Disks page', () => {
+ const inventory = new InventoryPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ inventory.navigateTo();
+ });
+
+ it('should have correct devices', () => {
+ cy.fixture('orchestrator/inventory.json').then((hosts) => {
+ const totalDiskCount = Cypress._.sumBy(hosts, 'devices.length');
+ inventory.expectTableCount('total', totalDiskCount);
+ for (const host of hosts) {
+ inventory.filterTable('Hostname', host['name']);
+ inventory.getTableCount('found').should('be.eq', host.devices.length);
+ }
+ });
+ });
+
+ it('should identify device', () => {
+ inventory.identify();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/04-osds.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/04-osds.e2e-spec.ts
new file mode 100644
index 000000000..41f0933b7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/04-osds.e2e-spec.ts
@@ -0,0 +1,50 @@
+import { OSDsPageHelper } from '../cluster/osds.po';
+import { DashboardPageHelper } from '../ui/dashboard.po';
+
+describe('OSDs page', () => {
+ const osds = new OSDsPageHelper();
+ const dashboard = new DashboardPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ osds.navigateTo();
+ });
+
+ describe('when Orchestrator is available', () => {
+ it('should create and delete OSDs', () => {
+ osds.getTableCount('total').as('initOSDCount');
+ osds.navigateTo('create');
+ osds.create('hdd');
+
+ cy.get('@newOSDCount').then((newCount) => {
+ cy.get('@initOSDCount').then((oldCount) => {
+ const expectedCount = Number(oldCount) + Number(newCount);
+
+ // check total rows
+ osds.expectTableCount('total', expectedCount);
+
+ // landing page is easier to check OSD status
+ dashboard.navigateTo();
+ dashboard.infoCardBody('OSDs').should('contain.text', `${expectedCount} total`);
+ dashboard.infoCardBody('OSDs').should('contain.text', `${expectedCount} up`);
+ dashboard.infoCardBody('OSDs').should('contain.text', `${expectedCount} in`);
+
+ cy.wait(30000);
+ expect(Number(newCount)).to.be.gte(2);
+ // Delete the first OSD we created
+ osds.navigateTo();
+ const deleteOsdId = Number(oldCount);
+ osds.deleteByIDs([deleteOsdId], false);
+ osds.ensureNoOsd(deleteOsdId);
+
+ cy.wait(30000);
+ // Replace the second OSD we created
+ const replaceID = Number(oldCount) + 1;
+ osds.deleteByIDs([replaceID], true);
+ osds.checkStatus(replaceID, ['destroyed']);
+ });
+ });
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/05-services.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/05-services.e2e-spec.ts
new file mode 100644
index 000000000..fb5e6ac89
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/05-services.e2e-spec.ts
@@ -0,0 +1,36 @@
+import { ServicesPageHelper } from '../cluster/services.po';
+
+describe('Services page', () => {
+ const services = new ServicesPageHelper();
+ const serviceName = 'rgw.foo';
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ services.navigateTo();
+ });
+
+ describe('when Orchestrator is available', () => {
+ it('should create an rgw service', () => {
+ services.navigateTo('create');
+ services.addService('rgw');
+
+ services.checkExist(serviceName, true);
+ });
+
+ it('should edit a service', () => {
+ const count = '2';
+ services.editService(serviceName, count);
+ services.expectPlacementCount(serviceName, count);
+ });
+
+ it('should create and delete an ingress service', () => {
+ services.navigateTo('create');
+ services.addService('ingress');
+
+ services.checkExist('ingress.rgw.foo', true);
+
+ services.deleteService('ingress.rgw.foo');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/grafana/grafana.feature b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/grafana/grafana.feature
new file mode 100644
index 000000000..62476ad25
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/grafana/grafana.feature
@@ -0,0 +1,63 @@
+Feature: Grafana panels
+
+ Go to some of the grafana performance section and check if
+ panels are populated without any issues
+
+ Background: Log in
+ Given I am logged in
+
+ Scenario Outline: Hosts Overall Performance
+ Given I am on the "hosts" page
+ When I go to the "Overall Performance" tab
+ Then I should see the grafana panel "<panel>"
+ When I view the grafana panel "<panel>"
+ Then I should not see "No Data" in the panel "<panel>"
+
+ Examples:
+ | panel |
+ | OSD Hosts |
+ | AVG CPU Busy |
+ | AVG RAM Utilization |
+ | Physical IOPS |
+ | AVG Disk Utilization |
+ | Network Load |
+ | CPU Busy - Top 10 Hosts |
+ | Network Load - Top 10 Hosts |
+
+ Scenario Outline: RGW Daemon Overall Performance
+ Given I am on the "rgw daemons" page
+ When I go to the "Overall Performance" tab
+ Then I should see the grafana panel "<panel>"
+ When I view the grafana panel "<panel>"
+ Then I should not see No Data in the graph "<panel>"
+ And I should see the legends "<legends>" in the graph "<panel>"
+
+ Examples:
+ | panel | legends |
+ | Total Requests/sec by RGW Instance | foo.ceph-node-00, foo.ceph-node-01, foo.ceph-node-02 |
+ | GET Latencies by RGW Instance | foo.ceph-node-00, foo.ceph-node-01, foo.ceph-node-02 |
+ | Bandwidth by RGW Instance | foo.ceph-node-00, foo.ceph-node-01, foo.ceph-node-02 |
+ | PUT Latencies by RGW Instance | foo.ceph-node-00, foo.ceph-node-01, foo.ceph-node-02 |
+ | Average GET/PUT Latencies | GET AVG, PUT AVG |
+ | Bandwidth Consumed by Type | GETs, PUTs |
+
+ Scenario Outline: RGW per Daemon Performance
+ Given I am on the "rgw daemons" page
+ When I expand the row "<name>"
+ And I go to the "Performance Details" tab
+ Then I should see the grafana panel "<panel>"
+ When I view the grafana panel "<panel>"
+ Then I should not see No Data in the graph "<panel>"
+ And I should see the legends "<name>" in the graph "<panel>"
+
+ Examples:
+ | name | panel |
+ | foo.ceph-node-00 | Bandwidth by HTTP Operation |
+ | foo.ceph-node-00 | HTTP Request Breakdown |
+ | foo.ceph-node-00 | Workload Breakdown |
+ | foo.ceph-node-01 | Bandwidth by HTTP Operation |
+ | foo.ceph-node-01 | HTTP Request Breakdown |
+ | foo.ceph-node-01 | Workload Breakdown |
+ | foo.ceph-node-02 | Bandwidth by HTTP Operation |
+ | foo.ceph-node-02 | HTTP Request Breakdown |
+ | foo.ceph-node-02 | Workload Breakdown |
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/01-create-cluster-welcome.feature b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/01-create-cluster-welcome.feature
new file mode 100644
index 000000000..6ba2fc4fc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/01-create-cluster-welcome.feature
@@ -0,0 +1,26 @@
+Feature: Cluster expansion welcome screen
+
+ Go to the welcome screen and decide whether
+ to proceed to wizard or skips to landing page
+
+ Background: Login
+ Given I am logged in
+
+ Scenario: Cluster expansion welcome screen
+ Given I am on the "welcome" page
+ And I should see a button to "Expand Cluster"
+ And I should see a button to "Skip"
+ And I should see a message "Please expand your cluster first"
+
+ Scenario: Go to the Cluster expansion wizard
+ Given I am on the "welcome" page
+ And I should see a button to "Expand Cluster"
+ When I click on "Expand Cluster" button
+ Then I am on the "Add Hosts" section
+
+ Scenario: Skips the process and go to the landing page
+ Given I am on the "welcome" page
+ And I should see a button to "Skip"
+ When I click on "Skip" button
+ And I confirm to "Continue"
+ Then I should be on the "dashboard" page
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/02-create-cluster-add-host.feature b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/02-create-cluster-add-host.feature
new file mode 100644
index 000000000..93c10833d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/02-create-cluster-add-host.feature
@@ -0,0 +1,74 @@
+Feature: Cluster expansion host addition
+
+ Add some hosts and perform some host related actions like editing the labels
+ and removing the hosts from the cluster and verify all of the actions are performed
+ as expected
+
+ Background: Cluster expansion wizard
+ Given I am logged in
+ And I am on the "welcome" page
+ And I click on "Expand Cluster" button
+
+ Scenario Outline: Add hosts
+ Given I am on the "Add Hosts" section
+ When I click on "Add" button
+ And enter "hostname" "<hostname>"
+ And select options "<labels>"
+ And I click on submit button
+ Then I should see a row with "<hostname>"
+ And I should see row "<hostname>" have "<labels>"
+
+ Examples:
+ | hostname | labels |
+ | ceph-node-01 | mon, mgr |
+ | ceph-node-02 ||
+
+ Scenario Outline: Remove hosts
+ Given I am on the "Add Hosts" section
+ And I should see a row with "<hostname>"
+ When I select a row "<hostname>"
+ And I click on "Remove" button from the table actions
+ Then I should see the modal
+ And I check the tick box in modal
+ And I click on "Remove Host" button
+ Then I should not see the modal
+ And I should not see a row with "<hostname>"
+
+ Examples:
+ | hostname |
+ | ceph-node-01 |
+ | ceph-node-02 |
+
+ Scenario: Add hosts using pattern 'ceph-node-[01-02]'
+ Given I am on the "Add Hosts" section
+ When I click on "Add" button
+ And enter "hostname" "ceph-node-[01-02]"
+ And I click on submit button
+ Then I should see rows with following entries
+ | hostname |
+ | ceph-node-01 |
+ | ceph-node-02 |
+
+ Scenario: Add exisiting host and verify it failed
+ Given I am on the "Add Hosts" section
+ And I should see a row with "ceph-node-00"
+ When I click on "Add" button
+ And enter "hostname" "ceph-node-00"
+ Then I should see an error in "hostname" field
+
+ Scenario Outline: Add and remove labels on host
+ Given I am on the "Add Hosts" section
+ When I select a row "<hostname>"
+ And I click on "Edit" button from the table actions
+ And "add" option "<labels>"
+ And I click on submit button
+ Then I should see row "<hostname>" have "<labels>"
+ When I select a row "<hostname>"
+ And I click on "Edit" button from the table actions
+ And "remove" option "<labels>"
+ And I click on submit button
+ Then I should see row "<hostname>" does not have "<labels>"
+
+ Examples:
+ | hostname | labels |
+ | ceph-node-01 | foo |
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/03-create-cluster-create-services.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/03-create-cluster-create-services.e2e-spec.ts
new file mode 100644
index 000000000..7668cafcf
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/03-create-cluster-create-services.e2e-spec.ts
@@ -0,0 +1,47 @@
+/* tslint:disable*/
+import {
+ CreateClusterServicePageHelper,
+ CreateClusterWizardHelper
+} from '../../cluster/create-cluster.po';
+/* tslint:enable*/
+
+describe('Create cluster create services page', () => {
+ const createCluster = new CreateClusterWizardHelper();
+ const createClusterServicePage = new CreateClusterServicePageHelper();
+
+ const createService = (serviceType: string, serviceName: string, count = '1') => {
+ cy.get('[aria-label=Create]').first().click();
+ createClusterServicePage.addService(serviceType, false, count);
+ createClusterServicePage.checkExist(serviceName, true);
+ };
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ createCluster.navigateTo();
+ createCluster.createCluster();
+ cy.get('.nav-link').contains('Create Services').click();
+ });
+
+ it('should check if title contains Create Services', () => {
+ cy.get('.title').should('contain.text', 'Create Services');
+ });
+
+ describe('when Orchestrator is available', () => {
+ const serviceName = 'mds.test';
+
+ it('should create an mds service', () => {
+ createService('mds', serviceName, '1');
+ });
+
+ it('should edit a service', () => {
+ const daemonCount = '2';
+ createClusterServicePage.editService(serviceName, daemonCount);
+ createClusterServicePage.expectPlacementCount(serviceName, daemonCount);
+ });
+
+ it('should delete mds service', () => {
+ createClusterServicePage.deleteService('mds.test');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/04-create-cluster-create-osds.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/04-create-cluster-create-osds.e2e-spec.ts
new file mode 100644
index 000000000..a82be9855
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/04-create-cluster-create-osds.e2e-spec.ts
@@ -0,0 +1,41 @@
+/* tslint:disable*/
+import { CreateClusterWizardHelper } from '../../cluster/create-cluster.po';
+import { OSDsPageHelper } from '../../cluster/osds.po';
+/* tslint:enable*/
+
+const osds = new OSDsPageHelper();
+
+describe('Create cluster create osds page', () => {
+ const createCluster = new CreateClusterWizardHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ createCluster.navigateTo();
+ createCluster.createCluster();
+ cy.get('.nav-link').contains('Create OSDs').click();
+ });
+
+ it('should check if title contains Create OSDs', () => {
+ cy.get('.title').should('contain.text', 'Create OSDs');
+ });
+
+ describe('when Orchestrator is available', () => {
+ it('should create OSDs', () => {
+ const hostnames = ['ceph-node-00', 'ceph-node-01', 'ceph-node-02'];
+ for (const hostname of hostnames) {
+ osds.create('hdd', hostname, true);
+
+ // Go to the Review section and Expand the cluster
+ // because the drive group spec is only stored
+ // in frontend and will be lost when refreshed
+ cy.get('.nav-link').contains('Review').click();
+ cy.get('button[aria-label="Next"]').click();
+ cy.get('cd-dashboard').should('exist');
+ createCluster.navigateTo();
+ createCluster.createCluster();
+ cy.get('.nav-link').contains('Create OSDs').click();
+ }
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/05-create-cluster-review.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/05-create-cluster-review.e2e-spec.ts
new file mode 100644
index 000000000..f93ad7a97
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/05-create-cluster-review.e2e-spec.ts
@@ -0,0 +1,67 @@
+/* tslint:disable*/
+import {
+ CreateClusterHostPageHelper,
+ CreateClusterWizardHelper
+} from '../../cluster/create-cluster.po';
+/* tslint:enable*/
+
+describe('Create Cluster Review page', () => {
+ const createCluster = new CreateClusterWizardHelper();
+ const createClusterHostPage = new CreateClusterHostPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ createCluster.navigateTo();
+ createCluster.createCluster();
+
+ cy.get('.nav-link').contains('Review').click();
+ });
+
+ describe('navigation link test', () => {
+ it('should check if active nav-link is of Review section', () => {
+ cy.get('.nav-link.active').should('contain.text', 'Review');
+ });
+ });
+
+ describe('fields check', () => {
+ it('should check cluster resources table is present', () => {
+ // check for table header 'Cluster Resources'
+ createCluster.getLegends().its(0).should('have.text', 'Cluster Resources');
+
+ // check for fields in table
+ createCluster.getStatusTables().should('contain.text', 'Hosts');
+ createCluster.getStatusTables().should('contain.text', 'Storage Capacity');
+ createCluster.getStatusTables().should('contain.text', 'CPUs');
+ createCluster.getStatusTables().should('contain.text', 'Memory');
+ });
+
+ it('should check Host Details table is present', () => {
+ // check for there to be two tables
+ createCluster.getDataTables().should('have.length', 1);
+
+ // verify correct columns on Host Details table
+ createCluster.getDataTableHeaders(0).contains('Hostname');
+
+ createCluster.getDataTableHeaders(0).contains('Labels');
+
+ createCluster.getDataTableHeaders(0).contains('CPUs');
+
+ createCluster.getDataTableHeaders(0).contains('Cores');
+
+ createCluster.getDataTableHeaders(0).contains('Total Memory');
+
+ createCluster.getDataTableHeaders(0).contains('Raw Capacity');
+
+ createCluster.getDataTableHeaders(0).contains('HDDs');
+
+ createCluster.getDataTableHeaders(0).contains('Flash');
+
+ createCluster.getDataTableHeaders(0).contains('NICs');
+ });
+
+ it('should check default host name is present', () => {
+ createClusterHostPage.check_for_host();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/06-cluster-check.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/06-cluster-check.e2e-spec.ts
new file mode 100644
index 000000000..589cbaa90
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/06-cluster-check.e2e-spec.ts
@@ -0,0 +1,99 @@
+/* tslint:disable*/
+import { Input, ManagerModulesPageHelper } from '../../cluster/mgr-modules.po';
+import { CreateClusterWizardHelper } from '../../cluster/create-cluster.po';
+import { HostsPageHelper } from '../../cluster/hosts.po';
+import { ServicesPageHelper } from '../../cluster/services.po';
+/* tslint:enable*/
+
+describe('when cluster creation is completed', () => {
+ const createCluster = new CreateClusterWizardHelper();
+ const services = new ServicesPageHelper();
+ const hosts = new HostsPageHelper();
+ const mgrmodules = new ManagerModulesPageHelper();
+
+ const hostnames = ['ceph-node-00', 'ceph-node-01', 'ceph-node-02', 'ceph-node-03'];
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ });
+
+ it('should redirect to dashboard landing page after cluster creation', () => {
+ createCluster.navigateTo();
+ createCluster.createCluster();
+
+ cy.get('.nav-link').contains('Review').click();
+ cy.get('button[aria-label="Next"]').click();
+ cy.get('cd-dashboard').should('exist');
+ });
+
+ describe('Hosts page', () => {
+ beforeEach(() => {
+ hosts.navigateTo();
+ });
+
+ it('should check if monitoring stacks are running on the root host', () => {
+ const monitoringStack = ['alertmanager', 'grafana', 'node-exporter', 'prometheus'];
+ hosts.clickTab('cd-host-details', 'ceph-node-00', 'Daemons');
+ for (const daemon of monitoringStack) {
+ cy.get('cd-host-details').within(() => {
+ services.checkServiceStatus(daemon);
+ });
+ }
+ });
+
+ // avoid creating node-exporter on the newly added host
+ // to favour the host draining process
+ it('should reduce the count for node-exporter', () => {
+ services.editService('node-exporter', '3');
+ });
+
+ // grafana ip address is set to the fqdn by default.
+ // kcli is not working with that, so setting the IP manually.
+ it('should change ip address of grafana', { retries: 2 }, () => {
+ const dashboardArr: Input[] = [
+ {
+ id: 'GRAFANA_API_URL',
+ newValue: 'https://192.168.100.100:3000',
+ oldValue: ''
+ }
+ ];
+ mgrmodules.editMgrModule('dashboard', dashboardArr);
+ });
+
+ it('should add one more host', () => {
+ hosts.navigateTo('add');
+ hosts.add(hostnames[3]);
+ hosts.checkExist(hostnames[3], true);
+ });
+
+ it('should have removed "_no_schedule" label', () => {
+ for (const hostname of hostnames) {
+ hosts.checkLabelExists(hostname, ['_no_schedule'], false);
+ }
+ });
+
+ it('should display inventory', () => {
+ hosts.clickTab('cd-host-details', hostnames[1], 'Physical Disks');
+ cy.get('cd-host-details').within(() => {
+ hosts.getTableCount('total').should('be.gte', 0);
+ });
+ });
+
+ it('should display daemons', () => {
+ hosts.clickTab('cd-host-details', hostnames[1], 'Daemons');
+ cy.get('cd-host-details').within(() => {
+ hosts.getTableCount('total').should('be.gte', 0);
+ });
+ });
+
+ it('should check if mon daemon is running on all hosts', () => {
+ for (const hostname of hostnames) {
+ hosts.clickTab('cd-host-details', hostname, 'Daemons');
+ cy.get('cd-host-details').within(() => {
+ services.checkServiceStatus('mon');
+ });
+ }
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/07-osds.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/07-osds.e2e-spec.ts
new file mode 100644
index 000000000..a0a1dd032
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/07-osds.e2e-spec.ts
@@ -0,0 +1,24 @@
+/* tslint:disable*/
+import { OSDsPageHelper } from '../../cluster/osds.po';
+/* tslint:enable*/
+
+describe('OSDs page', () => {
+ const osds = new OSDsPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ osds.navigateTo();
+ });
+
+ it('should check if atleast 3 osds are created', { retries: 3 }, () => {
+ // we have created a total of more than 3 osds throughout
+ // the whole tests so ensuring that atleast
+ // 3 osds are listed in the table. Since the OSD
+ // creation can take more time going with
+ // retry of 3
+ for (let id = 0; id < 3; id++) {
+ osds.checkStatus(id, ['in', 'up']);
+ }
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/08-hosts.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/08-hosts.e2e-spec.ts
new file mode 100644
index 000000000..374ecdb0c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/08-hosts.e2e-spec.ts
@@ -0,0 +1,49 @@
+/* tslint:disable*/
+import { HostsPageHelper } from '../../cluster/hosts.po';
+import { ServicesPageHelper } from '../../cluster/services.po';
+/* tslint:enable*/
+
+describe('Host Page', () => {
+ const hosts = new HostsPageHelper();
+ const services = new ServicesPageHelper();
+
+ const hostnames = ['ceph-node-00', 'ceph-node-01', 'ceph-node-02', 'ceph-node-03'];
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ hosts.navigateTo();
+ });
+
+ // rgw is needed for testing the force maintenance
+ it('should create rgw services', () => {
+ services.navigateTo('create');
+ services.addService('rgw', false, '4');
+ services.checkExist('rgw.foo', true);
+ });
+
+ it('should check if rgw daemon is running on all hosts', () => {
+ for (const hostname of hostnames) {
+ hosts.clickTab('cd-host-details', hostname, 'Daemons');
+ cy.get('cd-host-details').within(() => {
+ services.checkServiceStatus('rgw');
+ });
+ }
+ });
+
+ it('should force maintenance and exit', () => {
+ hosts.maintenance(hostnames[3], true, true);
+ });
+
+ it('should drain, remove and add the host back', () => {
+ hosts.drain(hostnames[3]);
+ hosts.remove(hostnames[3]);
+ hosts.navigateTo('add');
+ hosts.add(hostnames[3]);
+ hosts.checkExist(hostnames[3], true);
+ });
+
+ it('should show the exact count of daemons', () => {
+ hosts.checkServiceInstancesExist(hostnames[0], ['mgr: 1', 'prometheus: 1']);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/09-services.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/09-services.e2e-spec.ts
new file mode 100644
index 000000000..ed9ffb989
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/09-services.e2e-spec.ts
@@ -0,0 +1,114 @@
+/* tslint:disable*/
+import { ServicesPageHelper } from '../../cluster/services.po';
+/* tslint:enable*/
+
+describe('Services page', () => {
+ const services = new ServicesPageHelper();
+ const mdsDaemonName = 'mds.test';
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ services.navigateTo();
+ });
+
+ it('should check if rgw service is created', () => {
+ services.checkExist('rgw.foo', true);
+ });
+
+ it('should create an mds service', () => {
+ services.navigateTo('create');
+ services.addService('mds', false);
+ services.checkExist(mdsDaemonName, true);
+
+ services.clickServiceTab(mdsDaemonName, 'Details');
+ cy.get('cd-service-details').within(() => {
+ services.checkServiceStatus(mdsDaemonName);
+ });
+ });
+
+ it('should stop a daemon', () => {
+ services.clickServiceTab(mdsDaemonName, 'Details');
+ services.checkServiceStatus(mdsDaemonName);
+
+ services.daemonAction('mds', 'stop');
+ services.checkServiceStatus(mdsDaemonName, 'stopped');
+ });
+
+ it('should restart a daemon', () => {
+ services.checkExist(mdsDaemonName, true);
+ services.clickServiceTab(mdsDaemonName, 'Details');
+ services.daemonAction('mds', 'restart');
+ services.checkServiceStatus(mdsDaemonName, 'running');
+ });
+
+ it('should redeploy a daemon', () => {
+ services.checkExist(mdsDaemonName, true);
+ services.clickServiceTab(mdsDaemonName, 'Details');
+
+ services.daemonAction('mds', 'stop');
+ services.checkServiceStatus(mdsDaemonName, 'stopped');
+ services.daemonAction('mds', 'redeploy');
+ services.checkServiceStatus(mdsDaemonName, 'running');
+ });
+
+ it('should start a daemon', () => {
+ services.checkExist(mdsDaemonName, true);
+ services.clickServiceTab(mdsDaemonName, 'Details');
+
+ services.daemonAction('mds', 'stop');
+ services.checkServiceStatus(mdsDaemonName, 'stopped');
+ services.daemonAction('mds', 'start');
+ services.checkServiceStatus(mdsDaemonName, 'running');
+ });
+
+ it('should delete an mds service', () => {
+ services.deleteService(mdsDaemonName);
+ });
+
+ it('should create and delete snmp-gateway service with version V2c', () => {
+ services.navigateTo('create');
+ services.addService('snmp-gateway', false, '1', 'V2c');
+ services.checkExist('snmp-gateway', true);
+
+ services.clickServiceTab('snmp-gateway', 'Details');
+ cy.get('cd-service-details').within(() => {
+ services.checkServiceStatus('snmp-gateway');
+ });
+
+ services.deleteService('snmp-gateway');
+ });
+
+ it('should create and delete snmp-gateway service with version V3', () => {
+ services.navigateTo('create');
+ services.addService('snmp-gateway', false, '1', 'V3', true);
+ services.checkExist('snmp-gateway', true);
+
+ services.clickServiceTab('snmp-gateway', 'Details');
+ cy.get('cd-service-details').within(() => {
+ services.checkServiceStatus('snmp-gateway');
+ });
+
+ services.deleteService('snmp-gateway');
+ });
+
+ it('should create and delete snmp-gateway service with version V3 and w/o privacy protocol', () => {
+ services.navigateTo('create');
+ services.addService('snmp-gateway', false, '1', 'V3', false);
+ services.checkExist('snmp-gateway', true);
+
+ services.clickServiceTab('snmp-gateway', 'Details');
+ cy.get('cd-service-details').within(() => {
+ services.checkServiceStatus('snmp-gateway');
+ });
+
+ services.deleteService('snmp-gateway');
+ });
+
+ it('should create ingress as unmanaged', () => {
+ services.navigateTo('create');
+ services.addService('ingress', false, undefined, undefined, undefined, true);
+ services.checkExist('ingress.rgw.foo', true);
+ services.isUnmanaged('ingress.rgw.foo', true);
+ services.deleteService('ingress.rgw.foo');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/10-nfs-exports.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/10-nfs-exports.e2e-spec.ts
new file mode 100644
index 000000000..f4b5499f0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/10-nfs-exports.e2e-spec.ts
@@ -0,0 +1,83 @@
+/* tslint:disable*/
+import { ServicesPageHelper } from '../../cluster/services.po';
+import { NFSPageHelper } from '../../orchestrator/workflow/nfs/nfs-export.po';
+import { BucketsPageHelper } from '../../rgw/buckets.po';
+/* tslint:enable*/
+
+describe('nfsExport page', () => {
+ const nfsExport = new NFSPageHelper();
+ const services = new ServicesPageHelper();
+ const buckets = new BucketsPageHelper();
+ const bucketName = 'e2e.nfs.bucket';
+ // @TODO: uncomment this when a CephFS volume can be created through Dashboard.
+ // const fsPseudo = '/fsPseudo';
+ const rgwPseudo = '/rgwPseudo';
+ const editPseudo = '/editPseudo';
+ const backends = ['CephFS', 'Object Gateway'];
+ const squash = 'no_root_squash';
+ const client: object = { addresses: '192.168.0.10' };
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ nfsExport.navigateTo();
+ });
+
+ describe('breadcrumb test', () => {
+ it('should open and show breadcrumb', () => {
+ nfsExport.expectBreadcrumbText('NFS');
+ });
+ });
+
+ describe('Create, edit and delete', () => {
+ it('should create an NFS cluster', () => {
+ services.navigateTo('create');
+
+ services.addService('nfs');
+
+ services.checkExist('nfs.testnfs', true);
+ services.getExpandCollapseElement().click();
+ services.checkServiceStatus('nfs');
+ });
+
+ it('should create a nfs-export with RGW backend', () => {
+ buckets.navigateTo('create');
+ buckets.create(bucketName, 'dashboard', 'default-placement');
+
+ nfsExport.navigateTo();
+ nfsExport.existTableCell(rgwPseudo, false);
+ nfsExport.navigateTo('create');
+ nfsExport.create(backends[1], squash, client, rgwPseudo, bucketName);
+ nfsExport.existTableCell(rgwPseudo);
+ });
+
+ // @TODO: uncomment this when a CephFS volume can be created through Dashboard.
+ // it('should create a nfs-export with CephFS backend', () => {
+ // nfsExport.navigateTo();
+ // nfsExport.existTableCell(fsPseudo, false);
+ // nfsExport.navigateTo('create');
+ // nfsExport.create(backends[0], squash, client, fsPseudo);
+ // nfsExport.existTableCell(fsPseudo);
+ // });
+
+ it('should show Clients', () => {
+ nfsExport.clickTab('cd-nfs-details', rgwPseudo, 'Clients (1)');
+ cy.get('cd-nfs-details').within(() => {
+ nfsExport.getTableCount('total').should('be.gte', 0);
+ });
+ });
+
+ it('should edit an export', () => {
+ nfsExport.editExport(rgwPseudo, editPseudo);
+
+ nfsExport.existTableCell(editPseudo);
+ });
+
+ it('should delete exports and bucket', () => {
+ nfsExport.delete(editPseudo);
+
+ buckets.navigateTo();
+ buckets.delete(bucketName);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/nfs/nfs-export.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/nfs/nfs-export.po.ts
new file mode 100644
index 000000000..c700ef058
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/orchestrator/workflow/nfs/nfs-export.po.ts
@@ -0,0 +1,52 @@
+/* tslint:disable*/
+import { PageHelper } from '../../../page-helper.po';
+/* tslint:enable*/
+
+const pages = {
+ index: { url: '#/nfs', id: 'cd-nfs-list' },
+ create: { url: '#/nfs/create', id: 'cd-nfs-form' }
+};
+
+export class NFSPageHelper extends PageHelper {
+ pages = pages;
+
+ @PageHelper.restrictTo(pages.create.url)
+ create(backend: string, squash: string, client: object, pseudo: string, rgwPath?: string) {
+ this.selectOption('cluster_id', 'testnfs');
+ // select a storage backend
+ this.selectOption('name', backend);
+ if (backend === 'CephFS') {
+ this.selectOption('fs_name', 'myfs');
+
+ cy.get('#security_label').click({ force: true });
+ } else {
+ cy.get('input[data-testid=rgw_path]').type(rgwPath);
+ }
+
+ cy.get('input[name=pseudo]').type(pseudo);
+ this.selectOption('squash', squash);
+
+ // Add clients
+ cy.get('button[name=add_client]').click({ force: true });
+ cy.get('input[name=addresses]').type(client['addresses']);
+
+ // Check if we can remove clients and add it again
+ cy.get('span[name=remove_client]').click({ force: true });
+ cy.get('button[name=add_client]').click({ force: true });
+ cy.get('input[name=addresses]').type(client['addresses']);
+
+ cy.get('cd-submit-button').click();
+ }
+
+ editExport(pseudo: string, editPseudo: string) {
+ this.navigateEdit(pseudo);
+
+ cy.get('input[name=pseudo]').clear().type(editPseudo);
+
+ cy.get('cd-submit-button').click();
+
+ // Click the export and check its details table for updated content
+ this.getExpandCollapseElement(editPseudo).click();
+ cy.get('.active.tab-pane').should('contain.text', editPseudo);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/page-helper.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/page-helper.po.ts
new file mode 100644
index 000000000..4531a70bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/page-helper.po.ts
@@ -0,0 +1,309 @@
+interface Page {
+ url: string;
+ id: string;
+}
+
+export abstract class PageHelper {
+ pages: Record<string, Page>;
+
+ /**
+ * Decorator to be used on Helper methods to restrict access to one particular URL. This shall
+ * help developers to prevent and highlight mistakes. It also reduces boilerplate code and by
+ * thus, increases readability.
+ */
+ static restrictTo(page: string): Function {
+ return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
+ const fn: Function = descriptor.value;
+ descriptor.value = function (...args: any) {
+ cy.location('hash').should((url) => {
+ expect(url).to.eq(
+ page,
+ `Method ${target.constructor.name}::${propertyKey} is supposed to be ` +
+ `run on path "${page}", but was run on URL "${url}"`
+ );
+ });
+ fn.apply(this, args);
+ };
+ };
+ }
+
+ /**
+ * Navigates to the given page or to index.
+ * Waits until the page component is loaded
+ */
+ navigateTo(name: string = null) {
+ name = name || 'index';
+ const page = this.pages[name];
+
+ cy.visit(page.url);
+ cy.get(page.id);
+ }
+
+ /**
+ * Navigates back and waits for the hash to change
+ */
+ navigateBack() {
+ cy.location('hash').then((hash) => {
+ cy.go('back');
+ cy.location('hash').should('not.be', hash);
+ });
+ }
+
+ /**
+ * Navigates to the edit page
+ */
+ navigateEdit(name: string, select = true, breadcrumb = true) {
+ if (select) {
+ this.navigateTo();
+ this.getFirstTableCell(name).click();
+ }
+ cy.contains('Creating...').should('not.exist');
+ cy.contains('button', 'Edit').click();
+ if (breadcrumb) {
+ this.expectBreadcrumbText('Edit');
+ }
+ }
+
+ /**
+ * Checks the active breadcrumb value.
+ */
+ expectBreadcrumbText(text: string) {
+ cy.get('.breadcrumb-item.active').should('have.text', text);
+ }
+
+ getTabs() {
+ return cy.get('.nav.nav-tabs li');
+ }
+
+ getTab(tabName: string) {
+ return cy.contains('.nav.nav-tabs li', tabName);
+ }
+
+ getTabText(index: number) {
+ return this.getTabs().its(index).text();
+ }
+
+ getTabsCount(): any {
+ return this.getTabs().its('length');
+ }
+
+ /**
+ * Helper method to navigate/click a tab inside the expanded table row.
+ * @param selector The selector of the expanded table row.
+ * @param name The name of the row which should expand.
+ * @param tabName Name of the tab to be navigated/clicked.
+ */
+ clickTab(selector: string, name: string, tabName: string) {
+ this.getExpandCollapseElement(name).click();
+ cy.get(selector).within(() => {
+ this.getTab(tabName).click();
+ });
+ }
+
+ /**
+ * Helper method to select an option inside a select element.
+ * This method will also expect that the option was set.
+ * @param option The option text (not value) to be selected.
+ */
+ selectOption(selectionName: string, option: string) {
+ cy.get(`select[name=${selectionName}]`).select(option);
+ return this.expectSelectOption(selectionName, option);
+ }
+
+ /**
+ * Helper method to expect a set option inside a select element.
+ * @param option The selected option text (not value) that is to
+ * be expected.
+ */
+ expectSelectOption(selectionName: string, option: string) {
+ return cy.get(`select[name=${selectionName}] option:checked`).contains(option);
+ }
+
+ getLegends() {
+ return cy.get('legend');
+ }
+
+ getToast() {
+ return cy.get('.ngx-toastr');
+ }
+
+ /**
+ * Waits for the table to load its data
+ * Should be used in all methods that access the datatable
+ */
+ private waitDataTableToLoad() {
+ cy.get('cd-table').should('exist');
+ cy.get('datatable-scroller, .empty-row');
+ }
+
+ getDataTables() {
+ this.waitDataTableToLoad();
+
+ return cy.get('cd-table .dataTables_wrapper');
+ }
+
+ private getTableCountSpan(spanType: 'selected' | 'found' | 'total') {
+ return cy.contains('.datatable-footer-inner .page-count span', spanType);
+ }
+
+ // Get 'selected', 'found', or 'total' row count of a table.
+ getTableCount(spanType: 'selected' | 'found' | 'total') {
+ this.waitDataTableToLoad();
+ return this.getTableCountSpan(spanType).then(($elem) => {
+ const text = $elem
+ .filter((_i, e) => e.innerText.includes(spanType))
+ .first()
+ .text();
+
+ return Number(text.match(/(\d+)\s+\w*/)[1]);
+ });
+ }
+
+ // Wait until selected', 'found', or 'total' row count of a table equal to a number.
+ expectTableCount(spanType: 'selected' | 'found' | 'total', count: number) {
+ this.waitDataTableToLoad();
+ this.getTableCountSpan(spanType).should(($elem) => {
+ const text = $elem.first().text();
+ expect(Number(text.match(/(\d+)\s+\w*/)[1])).to.equal(count);
+ });
+ }
+
+ getTableRow(content: string) {
+ this.waitDataTableToLoad();
+
+ this.searchTable(content);
+ return cy.contains('.datatable-body-row', content);
+ }
+
+ getTableRows() {
+ this.waitDataTableToLoad();
+
+ return cy.get('datatable-row-wrapper');
+ }
+
+ /**
+ * Returns the first table cell.
+ * Optionally, you can specify the content of the cell.
+ */
+ getFirstTableCell(content?: string) {
+ this.waitDataTableToLoad();
+
+ if (content) {
+ this.searchTable(content);
+ return cy.contains('.datatable-body-cell-label', content);
+ } else {
+ return cy.get('.datatable-body-cell-label').first();
+ }
+ }
+
+ getTableCell(columnIndex: number, exactContent: string, partialMatch = false) {
+ this.waitDataTableToLoad();
+ this.clearTableSearchInput();
+ this.searchTable(exactContent);
+ if (partialMatch) {
+ return cy.contains(
+ `datatable-body-row datatable-body-cell:nth-child(${columnIndex})`,
+ exactContent
+ );
+ }
+ return cy.contains(
+ `datatable-body-row datatable-body-cell:nth-child(${columnIndex})`,
+ new RegExp(`^${exactContent}$`)
+ );
+ }
+
+ existTableCell(name: string, oughtToBePresent = true) {
+ const waitRule = oughtToBePresent ? 'be.visible' : 'not.exist';
+ this.getFirstTableCell(name).should(waitRule);
+ }
+
+ getExpandCollapseElement(content?: string) {
+ this.waitDataTableToLoad();
+
+ if (content) {
+ return cy.contains('.datatable-body-row', content).find('.tc_expand-collapse');
+ } else {
+ return cy.get('.tc_expand-collapse').first();
+ }
+ }
+
+ /**
+ * Gets column headers of table
+ */
+ getDataTableHeaders(index = 0) {
+ this.waitDataTableToLoad();
+
+ return cy.get('.datatable-header').its(index).find('.datatable-header-cell');
+ }
+
+ /**
+ * Grabs striped tables
+ */
+ getStatusTables() {
+ return cy.get('.table.table-striped');
+ }
+
+ filterTable(name: string, option: string) {
+ this.waitDataTableToLoad();
+
+ cy.get('.tc_filter_name > button').click();
+ cy.contains(`.tc_filter_name .dropdown-item`, name).click();
+
+ cy.get('.tc_filter_option > button').click();
+ cy.contains(`.tc_filter_option .dropdown-item`, option).click();
+ }
+
+ setPageSize(size: string) {
+ cy.get('cd-table .dataTables_paginate input').first().clear({ force: true }).type(size);
+ }
+
+ searchTable(text: string) {
+ this.waitDataTableToLoad();
+
+ this.setPageSize('10');
+ cy.get('cd-table .search input').first().clear().type(text);
+ }
+
+ clearTableSearchInput() {
+ this.waitDataTableToLoad();
+
+ return cy.get('cd-table .search button').first().click();
+ }
+
+ // Click the action button
+ clickActionButton(action: string) {
+ cy.get('.table-actions button.dropdown-toggle').first().click(); // open submenu
+ cy.get(`button.${action}`).click(); // click on "action" menu item
+ }
+
+ /**
+ * This is a generic method to delete table rows.
+ * It will select the first row that contains the provided name and delete it.
+ * After that it will wait until the row is no longer displayed.
+ * @param name The string to search in table cells.
+ * @param columnIndex If provided, search string in columnIndex column.
+ */
+ delete(name: string, columnIndex?: number, section?: string) {
+ // Selects row
+ const getRow = columnIndex
+ ? this.getTableCell.bind(this, columnIndex)
+ : this.getFirstTableCell.bind(this);
+ getRow(name).click();
+ let action: string;
+ section === 'hosts' ? (action = 'remove') : (action = 'delete');
+
+ // Clicks on table Delete/Remove button
+ this.clickActionButton(action);
+
+ // Convert action to SentenceCase and Confirms deletion
+ const actionUpperCase = action.charAt(0).toUpperCase() + action.slice(1);
+ cy.get('cd-modal .custom-control-label').click();
+ cy.contains('cd-modal button', actionUpperCase).click();
+
+ // Wait for modal to close
+ cy.get('cd-modal').should('not.exist');
+
+ // Waits for item to be removed from table
+ getRow(name).should('not.exist');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/pools/pools.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/pools/pools.e2e-spec.ts
new file mode 100644
index 000000000..b4c3c75ac
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/pools/pools.e2e-spec.ts
@@ -0,0 +1,54 @@
+import { PoolPageHelper } from './pools.po';
+
+describe('Pools page', () => {
+ const pools = new PoolPageHelper();
+ const poolName = 'pool_e2e_pool-test';
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ pools.navigateTo();
+ });
+
+ describe('breadcrumb and tab tests', () => {
+ it('should open and show breadcrumb', () => {
+ pools.expectBreadcrumbText('Pools');
+ });
+
+ it('should show two tabs', () => {
+ pools.getTabsCount().should('equal', 2);
+ });
+
+ it('should show pools list tab at first', () => {
+ pools.getTabText(0).should('eq', 'Pools List');
+ });
+
+ it('should show overall performance as a second tab', () => {
+ pools.getTabText(1).should('eq', 'Overall Performance');
+ });
+ });
+
+ describe('Create, update and destroy', () => {
+ it('should create a pool', () => {
+ pools.existTableCell(poolName, false);
+ pools.navigateTo('create');
+ pools.create(poolName, 8, 'rbd');
+ pools.existTableCell(poolName);
+ });
+
+ it('should edit a pools placement group', () => {
+ pools.existTableCell(poolName);
+ pools.edit_pool_pg(poolName, 32);
+ });
+
+ it('should show updated configuration field values', () => {
+ pools.existTableCell(poolName);
+ const bpsLimit = '4 B/s';
+ pools.edit_pool_configuration(poolName, bpsLimit);
+ });
+
+ it('should delete a pool', () => {
+ pools.delete(poolName);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/pools/pools.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/pools/pools.po.ts
new file mode 100644
index 000000000..98cee470e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/pools/pools.po.ts
@@ -0,0 +1,70 @@
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/pool', id: 'cd-pool-list' },
+ create: { url: '#/pool/create', id: 'cd-pool-form' }
+};
+
+export class PoolPageHelper extends PageHelper {
+ pages = pages;
+
+ private isPowerOf2(n: number) {
+ // tslint:disable-next-line: no-bitwise
+ return expect((n & (n - 1)) === 0, `Placement groups ${n} are not a power of 2`).to.be.true;
+ }
+
+ @PageHelper.restrictTo(pages.create.url)
+ create(name: string, placement_groups: number, ...apps: string[]) {
+ cy.get('input[name=name]').clear().type(name);
+
+ this.isPowerOf2(placement_groups);
+
+ this.selectOption('poolType', 'replicated');
+
+ this.expectSelectOption('pgAutoscaleMode', 'on');
+ this.selectOption('pgAutoscaleMode', 'off'); // To show pgNum field
+ cy.get('input[name=pgNum]').clear().type(`${placement_groups}`);
+ this.setApplications(apps);
+ cy.get('cd-submit-button').click();
+ }
+
+ edit_pool_pg(name: string, new_pg: number, wait = true) {
+ this.isPowerOf2(new_pg);
+ this.navigateEdit(name);
+
+ cy.get('input[name=pgNum]').clear().type(`${new_pg}`);
+ cy.get('cd-submit-button').click();
+ const str = `${new_pg} active+clean`;
+ this.getTableRow(name);
+ if (wait) {
+ this.getTableRow(name).contains(str);
+ }
+ }
+
+ edit_pool_configuration(name: string, bpsLimit: string) {
+ this.navigateEdit(name);
+
+ cy.get('.collapsible').click();
+ cy.get('cd-rbd-configuration-form')
+ .get('input[name=rbd_qos_bps_limit]')
+ .clear()
+ .type(`${bpsLimit}`);
+ cy.get('cd-submit-button').click();
+
+ this.navigateEdit(name);
+
+ cy.get('.collapsible').click();
+ cy.get('cd-rbd-configuration-form')
+ .get('input[name=rbd_qos_bps_limit]')
+ .should('have.value', bpsLimit);
+ }
+
+ private setApplications(apps: string[]) {
+ if (!apps || apps.length === 0) {
+ return;
+ }
+ cy.get('.float-left.mr-2.select-menu-edit').click();
+ cy.get('.popover-body').should('be.visible');
+ apps.forEach((app) => cy.get('.select-menu-item-content').contains(app).click());
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/buckets.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/buckets.e2e-spec.ts
new file mode 100644
index 000000000..e5ffdeee9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/buckets.e2e-spec.ts
@@ -0,0 +1,62 @@
+import { BucketsPageHelper } from './buckets.po';
+
+describe('RGW buckets page', () => {
+ const buckets = new BucketsPageHelper();
+ const bucket_name = 'e2ebucket';
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ buckets.navigateTo();
+ });
+
+ describe('breadcrumb tests', () => {
+ it('should open and show breadcrumb', () => {
+ buckets.expectBreadcrumbText('Buckets');
+ });
+ });
+
+ describe('create, edit & delete bucket tests', () => {
+ it('should create bucket', () => {
+ buckets.navigateTo('create');
+ buckets.create(bucket_name, BucketsPageHelper.USERS[0], 'default-placement');
+ buckets.getFirstTableCell(bucket_name).should('exist');
+ });
+
+ it('should edit bucket', () => {
+ buckets.edit(bucket_name, BucketsPageHelper.USERS[1]);
+ buckets.getDataTables().should('contain.text', BucketsPageHelper.USERS[1]);
+ });
+
+ it('should delete bucket', () => {
+ buckets.delete(bucket_name);
+ });
+
+ it('should create bucket with object locking enabled', () => {
+ buckets.navigateTo('create');
+ buckets.create(bucket_name, BucketsPageHelper.USERS[0], 'default-placement', true);
+ buckets.getFirstTableCell(bucket_name).should('exist');
+ });
+
+ it('should not allow to edit versioning if object locking is enabled', () => {
+ buckets.edit(bucket_name, BucketsPageHelper.USERS[1], true);
+ buckets.getDataTables().should('contain.text', BucketsPageHelper.USERS[1]);
+
+ buckets.delete(bucket_name);
+ });
+ });
+
+ describe('Invalid Input in Create and Edit tests', () => {
+ it('should test invalid inputs in create fields', () => {
+ buckets.testInvalidCreate();
+ });
+
+ it('should test invalid input in edit owner field', () => {
+ buckets.navigateTo('create');
+ buckets.create(bucket_name, BucketsPageHelper.USERS[0], 'default-placement');
+ buckets.testInvalidEdit(bucket_name);
+ buckets.navigateTo();
+ buckets.delete(bucket_name);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/buckets.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/buckets.po.ts
new file mode 100644
index 000000000..4804753d1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/buckets.po.ts
@@ -0,0 +1,193 @@
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/rgw/bucket', id: 'cd-rgw-bucket-list' },
+ create: { url: '#/rgw/bucket/create', id: 'cd-rgw-bucket-form' }
+};
+
+export class BucketsPageHelper extends PageHelper {
+ static readonly USERS = ['dashboard', 'testid'];
+
+ pages = pages;
+
+ versioningStateEnabled = 'Enabled';
+ versioningStateSuspended = 'Suspended';
+
+ private selectOwner(owner: string) {
+ return this.selectOption('owner', owner);
+ }
+
+ private selectPlacementTarget(placementTarget: string) {
+ return this.selectOption('placement-target', placementTarget);
+ }
+
+ private selectLockMode(lockMode: string) {
+ return this.selectOption('lock_mode', lockMode);
+ }
+
+ @PageHelper.restrictTo(pages.create.url)
+ create(name: string, owner: string, placementTarget: string, isLocking = false) {
+ // Enter in bucket name
+ cy.get('#bid').type(name);
+
+ // Select bucket owner
+ this.selectOwner(owner);
+ cy.get('#owner').should('have.class', 'ng-valid');
+
+ // Select bucket placement target:
+ this.selectPlacementTarget(placementTarget);
+ cy.get('#placement-target').should('have.class', 'ng-valid');
+
+ if (isLocking) {
+ cy.get('#lock_enabled').click({ force: true });
+ // Select lock mode:
+ this.selectLockMode('Compliance');
+ cy.get('#lock_mode').should('have.class', 'ng-valid');
+ cy.get('#lock_retention_period_days').type('3');
+ }
+
+ // Click the create button and wait for bucket to be made
+ cy.contains('button', 'Create Bucket').click();
+
+ this.getFirstTableCell(name).should('exist');
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ edit(name: string, new_owner: string, isLocking = false) {
+ this.navigateEdit(name);
+
+ cy.get('input[name=placement-target]').should('have.value', 'default-placement');
+ this.selectOwner(new_owner);
+
+ // If object locking is enabled versioning shouldn't be visible
+ if (isLocking) {
+ cy.get('input[id=versioning]').should('be.disabled');
+ cy.contains('button', 'Edit Bucket').click();
+
+ // wait to be back on buckets page with table visible and click
+ this.getExpandCollapseElement(name).click();
+
+ // check its details table for edited owner field
+ cy.get('.table.table-striped.table-bordered')
+ .first()
+ .should('contains.text', new_owner)
+ .as('bucketDataTable');
+
+ // Check versioning enabled:
+ cy.get('@bucketDataTable').find('tr').its(2).find('td').last().should('have.text', new_owner);
+ cy.get('@bucketDataTable').find('tr').its(11).find('td').last().as('versioningValueCell');
+
+ return cy.get('@versioningValueCell').should('have.text', this.versioningStateEnabled);
+ }
+ // Enable versioning
+ cy.get('input[id=versioning]').should('not.be.checked');
+ cy.get('label[for=versioning]').click();
+ cy.get('input[id=versioning]').should('be.checked');
+
+ cy.contains('button', 'Edit Bucket').click();
+
+ // wait to be back on buckets page with table visible and click
+ this.getExpandCollapseElement(name).click();
+
+ // check its details table for edited owner field
+ cy.get('.table.table-striped.table-bordered')
+ .first()
+ .should('contains.text', new_owner)
+ .as('bucketDataTable');
+
+ // Check versioning enabled:
+ cy.get('@bucketDataTable').find('tr').its(2).find('td').last().should('have.text', new_owner);
+ cy.get('@bucketDataTable').find('tr').its(11).find('td').last().as('versioningValueCell');
+
+ cy.get('@versioningValueCell').should('have.text', this.versioningStateEnabled);
+
+ // Disable versioning:
+ this.navigateEdit(name);
+
+ cy.get('label[for=versioning]').click();
+ cy.get('input[id=versioning]').should('not.be.checked');
+ cy.contains('button', 'Edit Bucket').click();
+
+ // Check versioning suspended:
+ this.getExpandCollapseElement(name).click();
+
+ return cy.get('@versioningValueCell').should('have.text', this.versioningStateSuspended);
+ }
+
+ testInvalidCreate() {
+ this.navigateTo('create');
+ cy.get('#bid').as('nameInputField'); // Grabs name box field
+
+ // Gives an invalid name (too short), then waits for dashboard to determine validity
+ cy.get('@nameInputField').type('rq');
+
+ cy.contains('button', 'Create Bucket').click(); // To trigger a validation
+
+ // Waiting for website to decide if name is valid or not
+ // Check that name input field was marked invalid in the css
+ cy.get('@nameInputField')
+ .should('not.have.class', 'ng-pending')
+ .and('have.class', 'ng-invalid');
+
+ // Check that error message was printed under name input field
+ cy.get('#bid + .invalid-feedback').should(
+ 'have.text',
+ 'Bucket names must be 3 to 63 characters long.'
+ );
+
+ // Test invalid owner input
+ // select some valid option. The owner drop down error message will not appear unless a valid user was selected at
+ // one point before the invalid placeholder user is selected.
+ this.selectOwner(BucketsPageHelper.USERS[1]);
+
+ // select the first option, which is invalid because it is a placeholder
+ this.selectOwner('-- Select a user --');
+
+ cy.get('@nameInputField').click();
+
+ // Check that owner drop down field was marked invalid in the css
+ cy.get('#owner').should('have.class', 'ng-invalid');
+
+ // Check that error message was printed under owner drop down field
+ cy.get('#owner + .invalid-feedback').should('have.text', 'This field is required.');
+
+ // Check invalid placement target input
+ this.selectOwner(BucketsPageHelper.USERS[1]);
+ // The drop down error message will not appear unless a valid option is previsously selected.
+ this.selectPlacementTarget('default-placement');
+ this.selectPlacementTarget('-- Select a placement target --');
+ cy.get('@nameInputField').click(); // Trigger validation
+ cy.get('#placement-target').should('have.class', 'ng-invalid');
+ cy.get('#placement-target + .invalid-feedback').should('have.text', 'This field is required.');
+
+ // Clicks the Create Bucket button but the page doesn't move.
+ // Done by testing for the breadcrumb
+ cy.contains('button', 'Create Bucket').click(); // Clicks Create Bucket button
+ this.expectBreadcrumbText('Create');
+ // content in fields seems to subsist through tests if not cleared, so it is cleared
+ cy.get('@nameInputField').clear();
+ return cy.contains('button', 'Cancel').click();
+ }
+
+ testInvalidEdit(name: string) {
+ this.navigateEdit(name);
+
+ cy.get('input[id=versioning]').should('exist').and('not.be.checked');
+
+ // Chooses 'Select a user' rather than a valid owner on Edit Bucket page
+ // and checks if it's an invalid input
+
+ // select the first option, which is invalid because it is a placeholder
+ this.selectOwner('-- Select a user --');
+
+ cy.contains('button', 'Edit Bucket').click();
+
+ // Check that owner drop down field was marked invalid in the css
+ cy.get('#owner').should('have.class', 'ng-invalid');
+
+ // Check that error message was printed under owner drop down field
+ cy.get('#owner + .invalid-feedback').should('have.text', 'This field is required.');
+
+ this.expectBreadcrumbText('Edit');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/daemons.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/daemons.e2e-spec.ts
new file mode 100644
index 000000000..4cad786c6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/daemons.e2e-spec.ts
@@ -0,0 +1,35 @@
+import { DaemonsPageHelper } from './daemons.po';
+
+describe('RGW daemons page', () => {
+ const daemons = new DaemonsPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ daemons.navigateTo();
+ });
+
+ describe('breadcrumb and tab tests', () => {
+ it('should open and show breadcrumb', () => {
+ daemons.expectBreadcrumbText('Daemons');
+ });
+
+ it('should show two tabs', () => {
+ daemons.getTabsCount().should('eq', 2);
+ });
+
+ it('should show daemons list tab at first', () => {
+ daemons.getTabText(0).should('eq', 'Daemons List');
+ });
+
+ it('should show overall performance as a second tab', () => {
+ daemons.getTabText(1).should('eq', 'Overall Performance');
+ });
+ });
+
+ describe('details and performance counters table tests', () => {
+ it('should check that details/performance tables are visible when daemon is selected', () => {
+ daemons.checkTables();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/daemons.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/daemons.po.ts
new file mode 100644
index 000000000..82a179463
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/daemons.po.ts
@@ -0,0 +1,34 @@
+import { PageHelper } from '../page-helper.po';
+
+export class DaemonsPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/rgw/daemon', id: 'cd-rgw-daemon-list' }
+ };
+
+ getTableCell() {
+ return cy
+ .get('.tab-content')
+ .its(1)
+ .find('cd-table')
+ .should('have.length', 1) // Only 1 table should be renderer
+ .find('datatable-body-cell');
+ }
+
+ checkTables() {
+ // click on a daemon so details table appears
+ cy.get('.datatable-body-cell-label').first().click();
+
+ // check details table is visible
+ // check at least one field is present
+ this.getTableCell().should('be.visible').should('contain.text', 'ceph_version');
+
+ // click on performance counters tab and check table is loaded
+ cy.contains('.nav-link', 'Performance Counters').click();
+
+ // check at least one field is present
+ this.getTableCell().should('be.visible').should('contain.text', 'objecter.op_r');
+
+ // click on performance details tab
+ cy.contains('.nav-link', 'Performance Details').click();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/users.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/users.e2e-spec.ts
new file mode 100644
index 000000000..b5f366a09
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/users.e2e-spec.ts
@@ -0,0 +1,46 @@
+import { UsersPageHelper } from './users.po';
+
+describe('RGW users page', () => {
+ const users = new UsersPageHelper();
+ const tenant = 'e2e_000tenant';
+ const user_id = 'e2e_000user_create_edit_delete';
+ const user_name = tenant + '$' + user_id;
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ users.navigateTo();
+ });
+
+ describe('breadcrumb tests', () => {
+ it('should open and show breadcrumb', () => {
+ users.expectBreadcrumbText('Users');
+ });
+ });
+
+ describe('create, edit & delete user tests', () => {
+ it('should create user', () => {
+ users.navigateTo('create');
+ users.create(tenant, user_id, 'Some Name', 'original@website.com', '1200');
+ users.getFirstTableCell(user_id).should('exist');
+ });
+
+ it('should edit users full name, email and max buckets', () => {
+ users.edit(user_name, 'Another Identity', 'changed@othersite.com', '1969');
+ });
+
+ it('should delete user', () => {
+ users.delete(user_name);
+ });
+ });
+
+ describe('Invalid input tests', () => {
+ it('should put invalid input into user creation form and check fields are marked invalid', () => {
+ users.invalidCreate();
+ });
+
+ it('should put invalid input into user edit form and check fields are marked invalid', () => {
+ users.invalidEdit();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/users.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/users.po.ts
new file mode 100644
index 000000000..a4266f989
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/rgw/users.po.ts
@@ -0,0 +1,139 @@
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/rgw/user', id: 'cd-rgw-user-list' },
+ create: { url: '#/rgw/user/create', id: 'cd-rgw-user-form' }
+};
+
+export class UsersPageHelper extends PageHelper {
+ pages = pages;
+
+ @PageHelper.restrictTo(pages.create.url)
+ create(tenant: string, user_id: string, fullname: string, email: string, maxbuckets: string) {
+ // Enter in user_id
+ cy.get('#user_id').type(user_id);
+ // Show Tenanat
+ cy.get('#show_tenant').click({ force: true });
+ // Enter in tenant
+ cy.get('#tenant').type(tenant);
+ // Enter in full name
+ cy.get('#display_name').click().type(fullname);
+
+ // Enter in email
+ cy.get('#email').click().type(email);
+
+ // Enter max buckets
+ this.selectOption('max_buckets_mode', 'Custom');
+ cy.get('#max_buckets').should('exist').should('have.value', '1000');
+ cy.get('#max_buckets').click().clear().type(maxbuckets);
+
+ // Click the create button and wait for user to be made
+ cy.contains('button', 'Create User').click();
+ this.getFirstTableCell(tenant + '$' + user_id).should('exist');
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ edit(name: string, new_fullname: string, new_email: string, new_maxbuckets: string) {
+ this.navigateEdit(name);
+
+ // Change the full name field
+ cy.get('#display_name').click().clear().type(new_fullname);
+
+ // Change the email field
+ cy.get('#email').click().clear().type(new_email);
+
+ // Change the max buckets field
+ this.selectOption('max_buckets_mode', 'Custom');
+ cy.get('#max_buckets').click().clear().type(new_maxbuckets);
+
+ cy.contains('button', 'Edit User').click();
+
+ // Click the user and check its details table for updated content
+ this.getExpandCollapseElement(name).click();
+ cy.get('.active.tab-pane')
+ .should('contain.text', new_fullname)
+ .and('contain.text', new_email)
+ .and('contain.text', new_maxbuckets);
+ }
+
+ invalidCreate() {
+ const tenant = '000invalid_tenant';
+ const uname = '000invalid_create_user';
+ // creating this user in order to check that you can't give two users the same name
+ this.navigateTo('create');
+ this.create(tenant, uname, 'xxx', 'xxx@xxx', '1');
+
+ this.navigateTo('create');
+
+ // Username
+ cy.get('#user_id')
+ // No username had been entered. Field should be invalid
+ .should('have.class', 'ng-invalid')
+ // Try to give user already taken name. Should make field invalid.
+ .type(uname);
+ cy.get('#show_tenant').click({ force: true });
+ cy.get('#tenant').type(tenant).should('have.class', 'ng-invalid');
+ cy.contains('#tenant + .invalid-feedback', 'The chosen user ID exists in this tenant.');
+
+ // check that username field is marked invalid if username has been cleared off
+ cy.get('#user_id').clear().blur().should('have.class', 'ng-invalid');
+ cy.contains('#user_id + .invalid-feedback', 'This field is required.');
+
+ // Full name
+ cy.get('#display_name')
+ // No display name has been given so field should be invalid
+ .should('have.class', 'ng-invalid')
+ // display name field should also be marked invalid if given input then emptied
+ .type('a')
+ .clear()
+ .blur()
+ .should('have.class', 'ng-invalid');
+ cy.contains('#display_name + .invalid-feedback', 'This field is required.');
+
+ // put invalid email to make field invalid
+ cy.get('#email').type('a').blur().should('have.class', 'ng-invalid');
+ cy.contains('#email + .invalid-feedback', 'This is not a valid email address.');
+
+ // put negative max buckets to make field invalid
+ this.expectSelectOption('max_buckets_mode', 'Custom');
+ cy.get('#max_buckets').clear().type('-5').blur().should('have.class', 'ng-invalid');
+ cy.contains('#max_buckets + .invalid-feedback', 'The entered value must be >= 1.');
+
+ this.navigateTo();
+ this.delete(tenant + '$' + uname);
+ }
+
+ invalidEdit() {
+ const tenant = '000invalid_tenant';
+ const uname = '000invalid_edit_user';
+ // creating this user to edit for the test
+ this.navigateTo('create');
+ this.create(tenant, uname, 'xxx', 'xxx@xxx', '50');
+ const name = tenant + '$' + uname;
+ this.navigateEdit(name);
+
+ // put invalid email to make field invalid
+ cy.get('#email')
+ .clear()
+ .type('a')
+ .blur()
+ .should('not.have.class', 'ng-pending')
+ .should('have.class', 'ng-invalid');
+ cy.contains('#email + .invalid-feedback', 'This is not a valid email address.');
+
+ // empty the display name field making it invalid
+ cy.get('#display_name').clear().blur().should('have.class', 'ng-invalid');
+ cy.contains('#display_name + .invalid-feedback', 'This field is required.');
+
+ // put negative max buckets to make field invalid
+ this.selectOption('max_buckets_mode', 'Disabled');
+ cy.get('#max_buckets').should('not.exist');
+ this.selectOption('max_buckets_mode', 'Custom');
+ cy.get('#max_buckets').should('exist').should('have.value', '50');
+ cy.get('#max_buckets').clear().type('-5').blur().should('have.class', 'ng-invalid');
+ cy.contains('#max_buckets + .invalid-feedback', 'The entered value must be >= 1.');
+
+ this.navigateTo();
+ this.delete(tenant + '$' + uname);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/api-docs.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/api-docs.e2e-spec.ts
new file mode 100644
index 000000000..52994859e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/api-docs.e2e-spec.ts
@@ -0,0 +1,15 @@
+import { ApiDocsPageHelper } from '../ui/api-docs.po';
+
+describe('Api Docs Page', () => {
+ const apiDocs = new ApiDocsPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ apiDocs.navigateTo();
+ });
+
+ it('should show the API Docs description', () => {
+ cy.get('.renderedMarkdown').first().contains('This is the official Ceph REST API');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/api-docs.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/api-docs.po.ts
new file mode 100644
index 000000000..c7a8d222d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/api-docs.po.ts
@@ -0,0 +1,5 @@
+import { PageHelper } from '../page-helper.po';
+
+export class ApiDocsPageHelper extends PageHelper {
+ pages = { index: { url: '#/api-docs', id: 'cd-api-docs' } };
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/dashboard.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/dashboard.e2e-spec.ts
new file mode 100644
index 000000000..9cb84480b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/dashboard.e2e-spec.ts
@@ -0,0 +1,124 @@
+import { IscsiPageHelper } from '../block/iscsi.po';
+import { HostsPageHelper } from '../cluster/hosts.po';
+import { MonitorsPageHelper } from '../cluster/monitors.po';
+import { OSDsPageHelper } from '../cluster/osds.po';
+import { PageHelper } from '../page-helper.po';
+import { PoolPageHelper } from '../pools/pools.po';
+import { DaemonsPageHelper } from '../rgw/daemons.po';
+import { DashboardPageHelper } from './dashboard.po';
+
+describe('Dashboard Main Page', () => {
+ const dashboard = new DashboardPageHelper();
+ const daemons = new DaemonsPageHelper();
+ const hosts = new HostsPageHelper();
+ const osds = new OSDsPageHelper();
+ const pools = new PoolPageHelper();
+ const monitors = new MonitorsPageHelper();
+ const iscsi = new IscsiPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ dashboard.navigateTo();
+ });
+
+ describe('Check that all hyperlinks on info cards lead to the correct page and fields exist', () => {
+ it('should ensure that all linked info cards lead to correct page', () => {
+ const expectationMap = {
+ Monitors: 'Monitors',
+ OSDs: 'OSDs',
+ Hosts: 'Hosts',
+ 'Object Gateways': 'Daemons',
+ 'iSCSI Gateways': 'Overview',
+ Pools: 'Pools'
+ };
+
+ for (const [linkText, breadcrumbText] of Object.entries(expectationMap)) {
+ cy.location('hash').should('eq', '#/dashboard');
+ dashboard.clickInfoCardLink(linkText);
+ dashboard.expectBreadcrumbText(breadcrumbText);
+ dashboard.navigateBack();
+ }
+ });
+
+ it('should verify that info cards exist on dashboard in proper order', () => {
+ // Ensures that info cards are all displayed on the dashboard tab while being in the proper
+ // order, checks for card title and position via indexing into a list of all info cards.
+ const order = [
+ 'Cluster Status',
+ 'Hosts',
+ 'Monitors',
+ 'OSDs',
+ 'Managers',
+ 'Object Gateways',
+ 'Metadata Servers',
+ 'iSCSI Gateways',
+ 'Raw Capacity',
+ 'Objects',
+ 'PG Status',
+ 'Pools',
+ 'PGs per OSD',
+ 'Client Read/Write',
+ 'Client Throughput',
+ 'Recovery Throughput',
+ 'Scrubbing'
+ ];
+
+ for (let i = 0; i < order.length; i++) {
+ dashboard.infoCard(i).should('contain.text', order[i]);
+ }
+ });
+
+ it('should verify that info card group titles are present and in the right order', () => {
+ cy.location('hash').should('eq', '#/dashboard');
+ dashboard.infoGroupTitle(0).should('eq', 'Status');
+ dashboard.infoGroupTitle(1).should('eq', 'Capacity');
+ dashboard.infoGroupTitle(2).should('eq', 'Performance');
+ });
+ });
+
+ it('Should check that dashboard cards have correct information', () => {
+ interface TestSpec {
+ cardName: string;
+ regexMatcher?: RegExp;
+ pageObject: PageHelper;
+ }
+ const testSpecs: TestSpec[] = [
+ { cardName: 'Object Gateways', regexMatcher: /(\d+)\s+total/, pageObject: daemons },
+ { cardName: 'Monitors', regexMatcher: /(\d+)\s+\(quorum/, pageObject: monitors },
+ { cardName: 'Hosts', regexMatcher: /(\d+)\s+total/, pageObject: hosts },
+ { cardName: 'OSDs', regexMatcher: /(\d+)\s+total/, pageObject: osds },
+ { cardName: 'Pools', pageObject: pools },
+ { cardName: 'iSCSI Gateways', regexMatcher: /(\d+)\s+total/, pageObject: iscsi }
+ ];
+ for (let i = 0; i < testSpecs.length; i++) {
+ const spec = testSpecs[i];
+ dashboard.navigateTo();
+
+ dashboard.infoCardBodyText(spec.cardName).then((infoCardBodyText: string) => {
+ let dashCount = 0;
+
+ if (spec.regexMatcher) {
+ const match = infoCardBodyText.match(new RegExp(spec.regexMatcher));
+ expect(match).to.length.gt(
+ 1,
+ `Regex ${spec.regexMatcher} did not find a match for card with name ` +
+ `${spec.cardName}`
+ );
+ dashCount = Number(match[1]);
+ } else {
+ dashCount = Number(infoCardBodyText);
+ }
+
+ spec.pageObject.navigateTo();
+ spec.pageObject.getTableCount('total').then((tableCount) => {
+ expect(tableCount).to.eq(
+ dashCount,
+ `Text of card "${spec.cardName}" and regex "${spec.regexMatcher}" resulted in ${dashCount} ` +
+ `but did not match table count ${tableCount}`
+ );
+ });
+ });
+ }
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/dashboard.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/dashboard.po.ts
new file mode 100644
index 000000000..42d63ef44
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/dashboard.po.ts
@@ -0,0 +1,31 @@
+import { PageHelper } from '../page-helper.po';
+
+export class DashboardPageHelper extends PageHelper {
+ pages = { index: { url: '#/dashboard', id: 'cd-dashboard' } };
+
+ infoGroupTitle(index: number) {
+ return cy.get('.info-group-title').its(index).text();
+ }
+
+ clickInfoCardLink(cardName: string) {
+ cy.get(`cd-info-card[cardtitle="${cardName}"]`).contains('a', cardName).click();
+ }
+
+ infoCard(indexOrTitle: number | string) {
+ cy.get('cd-info-card').as('infoCards');
+
+ if (typeof indexOrTitle === 'number') {
+ return cy.get('@infoCards').its(indexOrTitle);
+ } else {
+ return cy.contains('cd-info-card a', indexOrTitle).parent().parent().parent().parent();
+ }
+ }
+
+ infoCardBodyText(infoCard: string) {
+ return this.infoCard(infoCard).find('.card-text').text();
+ }
+
+ infoCardBody(infoCard: string) {
+ return this.infoCard(infoCard).find('.card-text');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/language.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/language.e2e-spec.ts
new file mode 100644
index 000000000..ccf16c2b5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/language.e2e-spec.ts
@@ -0,0 +1,20 @@
+import { LanguagePageHelper } from './language.po';
+
+describe('Shared pages', () => {
+ const language = new LanguagePageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ language.navigateTo();
+ });
+
+ it('should check default language', () => {
+ language.getLanguageBtn().should('contain.text', 'English');
+ });
+
+ it('should check all available languages', () => {
+ language.getLanguageBtn().click();
+ language.getAllLanguages().should('have.length', 1).should('contain.text', 'English');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/language.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/language.po.ts
new file mode 100644
index 000000000..80e21ba1e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/language.po.ts
@@ -0,0 +1,15 @@
+import { PageHelper } from '../page-helper.po';
+
+export class LanguagePageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/dashboard', id: 'cd-dashboard' }
+ };
+
+ getLanguageBtn() {
+ return cy.get('cd-language-selector a').first();
+ }
+
+ getAllLanguages() {
+ return cy.get('cd-language-selector button');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/login.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/login.e2e-spec.ts
new file mode 100644
index 000000000..29c9e9e10
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/login.e2e-spec.ts
@@ -0,0 +1,17 @@
+import { LoginPageHelper } from './login.po';
+
+describe('Login page', () => {
+ const login = new LoginPageHelper();
+
+ it('should login and navigate to dashboard page', () => {
+ login.navigateTo();
+ login.doLogin();
+ });
+
+ it('should logout when clicking the button', () => {
+ login.navigateTo();
+ login.doLogin();
+
+ login.doLogout();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/login.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/login.po.ts
new file mode 100644
index 000000000..d4d2c6921
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/login.po.ts
@@ -0,0 +1,22 @@
+import { PageHelper } from '../page-helper.po';
+
+export class LoginPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/login', id: 'cd-login' },
+ dashboard: { url: '#/dashboard', id: 'cd-dashboard' }
+ };
+
+ doLogin() {
+ cy.get('[name=username]').type('admin');
+ cy.get('#password').type('admin');
+ cy.get('[type=submit]').click();
+ cy.get('cd-dashboard').should('exist');
+ }
+
+ doLogout() {
+ cy.get('cd-identity a').click();
+ cy.contains('cd-identity span', 'Sign out').click();
+ cy.get('cd-login').should('exist');
+ cy.location('hash').should('eq', '#/login');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/navigation.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/navigation.e2e-spec.ts
new file mode 100644
index 000000000..fee2d2db9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/navigation.e2e-spec.ts
@@ -0,0 +1,24 @@
+import { NavigationPageHelper } from './navigation.po';
+
+describe('Shared pages', () => {
+ const shared = new NavigationPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ shared.navigateTo();
+ });
+
+ it('should display the vertical menu by default', () => {
+ shared.getVerticalMenu().should('not.have.class', 'active');
+ });
+
+ it('should hide the vertical menu', () => {
+ shared.getMenuToggler().click();
+ shared.getVerticalMenu().should('have.class', 'active');
+ });
+
+ it('should navigate to the correct page', () => {
+ shared.checkNavigations(shared.navigations);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/navigation.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/navigation.po.ts
new file mode 100644
index 000000000..a7ecf3af0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/navigation.po.ts
@@ -0,0 +1,69 @@
+import { PageHelper } from '../page-helper.po';
+
+export class NavigationPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/dashboard', id: 'cd-dashboard' }
+ };
+
+ navigations = [
+ { menu: 'NFS', component: 'cd-error' },
+ {
+ menu: 'Object Gateway',
+ submenus: [
+ { menu: 'Daemons', component: 'cd-rgw-daemon-list' },
+ { menu: 'Users', component: 'cd-rgw-user-list' },
+ { menu: 'Buckets', component: 'cd-rgw-bucket-list' }
+ ]
+ },
+ { menu: 'Dashboard', component: 'cd-dashboard' },
+ {
+ menu: 'Cluster',
+ submenus: [
+ { menu: 'Hosts', component: 'cd-hosts' },
+ { menu: 'Physical Disks', component: 'cd-error' },
+ { menu: 'Monitors', component: 'cd-monitor' },
+ { menu: 'Services', component: 'cd-error' },
+ { menu: 'OSDs', component: 'cd-osd-list' },
+ { menu: 'Configuration', component: 'cd-configuration' },
+ { menu: 'CRUSH map', component: 'cd-crushmap' },
+ { menu: 'Manager Modules', component: 'cd-mgr-module-list' },
+ { menu: 'Logs', component: 'cd-logs' },
+ { menu: 'Monitoring', component: 'cd-prometheus-tabs' }
+ ]
+ },
+ { menu: 'Pools', component: 'cd-pool-list' },
+ {
+ menu: 'Block',
+ submenus: [
+ { menu: 'Images', component: 'cd-error' },
+ { menu: 'Mirroring', component: 'cd-mirroring' },
+ { menu: 'iSCSI', component: 'cd-iscsi' }
+ ]
+ },
+ { menu: 'File Systems', component: 'cd-cephfs-list' }
+ ];
+
+ getVerticalMenu() {
+ return cy.get('nav[id=sidebar]');
+ }
+
+ getMenuToggler() {
+ return cy.get('[aria-label="toggle sidebar visibility"]');
+ }
+
+ checkNavigations(navs: any) {
+ // The nfs-ganesha, RGW, and block/rbd status requests are mocked to ensure that this method runs in time
+ cy.intercept('/ui-api/nfs-ganesha/status', { fixture: 'nfs-ganesha-status.json' });
+ cy.intercept('/ui-api/rgw/status', { fixture: 'rgw-status.json' });
+ cy.intercept('/ui-api/block/rbd/status', { fixture: 'block-rbd-status.json' });
+
+ navs.forEach((nav: any) => {
+ cy.contains('.simplebar-content li.nav-item a', nav.menu).click();
+ if (nav.submenus) {
+ this.checkNavigations(nav.submenus);
+ } else {
+ cy.get(nav.component).should('exist');
+ }
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/notification.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/notification.e2e-spec.ts
new file mode 100644
index 000000000..2ee73a706
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/notification.e2e-spec.ts
@@ -0,0 +1,59 @@
+import { PoolPageHelper } from '../pools/pools.po';
+import { NotificationSidebarPageHelper } from './notification.po';
+
+describe('Notification page', () => {
+ const notification = new NotificationSidebarPageHelper();
+ const pools = new PoolPageHelper();
+ const poolName = 'e2e_notification_pool';
+
+ before(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ pools.navigateTo('create');
+ pools.create(poolName, 8);
+ pools.edit_pool_pg(poolName, 4, false);
+ });
+
+ after(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ pools.navigateTo();
+ pools.delete(poolName);
+ });
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ pools.navigateTo();
+ });
+
+ it('should open notification sidebar', () => {
+ notification.getSidebar().should('not.be.visible');
+ notification.open();
+ notification.getSidebar().should('be.visible');
+ });
+
+ it('should display a running task', () => {
+ notification.getToast().should('not.exist');
+
+ // Check that running task is shown.
+ notification.open();
+ notification.getTasks().contains(poolName).should('exist');
+
+ // Delete pool after task is complete (otherwise we get an error).
+ notification.getTasks().contains(poolName, { timeout: 300000 }).should('not.exist');
+ });
+
+ it('should have notifications', () => {
+ notification.open();
+ notification.getNotifications().should('have.length.gt', 0);
+ });
+
+ it('should clear notifications', () => {
+ notification.getToast().should('not.exist');
+ notification.open();
+ notification.getNotifications().should('have.length.gt', 0);
+ notification.getClearNotficationsBtn().should('be.visible');
+ notification.clearNotifications();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/notification.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/notification.po.ts
new file mode 100644
index 000000000..12c424e35
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/notification.po.ts
@@ -0,0 +1,45 @@
+import { PageHelper } from '../page-helper.po';
+
+export class NotificationSidebarPageHelper extends PageHelper {
+ getNotificatinoIcon() {
+ return cy.get('cd-notifications a');
+ }
+
+ getSidebar() {
+ return cy.get('cd-notifications-sidebar');
+ }
+
+ getTasks() {
+ return this.getSidebar().find('.card.tc_task');
+ }
+
+ getNotifications() {
+ return this.getSidebar().find('.card.tc_notification');
+ }
+
+ getClearNotficationsBtn() {
+ return this.getSidebar().find('button.btn-block');
+ }
+
+ getCloseBtn() {
+ return this.getSidebar().find('button.close');
+ }
+
+ open() {
+ this.getNotificatinoIcon().click();
+ this.getSidebar().should('be.visible');
+ }
+
+ clearNotifications() {
+ // It can happen that although notifications are cleared, by the time we check the notifications
+ // amount, another notification can appear, so we check it more than once (if needed).
+ this.getClearNotficationsBtn().click();
+ this.getNotifications()
+ .should('have.length.gte', 0)
+ .then(($elems) => {
+ if ($elems.length > 0) {
+ this.clearNotifications();
+ }
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/role-mgmt.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/role-mgmt.e2e-spec.ts
new file mode 100644
index 000000000..c3f325dbb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/role-mgmt.e2e-spec.ts
@@ -0,0 +1,37 @@
+import { RoleMgmtPageHelper } from './role-mgmt.po';
+
+describe('Role Management page', () => {
+ const roleMgmt = new RoleMgmtPageHelper();
+ const role_name = 'e2e_role_mgmt_role';
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ roleMgmt.navigateTo();
+ });
+
+ describe('breadcrumb tests', () => {
+ it('should check breadcrumb on roles tab on user management page', () => {
+ roleMgmt.expectBreadcrumbText('Roles');
+ });
+
+ it('should check breadcrumb on role creation page', () => {
+ roleMgmt.navigateTo('create');
+ roleMgmt.expectBreadcrumbText('Create');
+ });
+ });
+
+ describe('role create, edit & delete test', () => {
+ it('should create a role', () => {
+ roleMgmt.create(role_name, 'An interesting description');
+ });
+
+ it('should edit a role', () => {
+ roleMgmt.edit(role_name, 'A far more interesting description');
+ });
+
+ it('should delete a role', () => {
+ roleMgmt.delete(role_name);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/role-mgmt.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/role-mgmt.po.ts
new file mode 100644
index 000000000..1cc3630a4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/role-mgmt.po.ts
@@ -0,0 +1,40 @@
+import { PageHelper } from '../page-helper.po';
+
+export class RoleMgmtPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/user-management/roles', id: 'cd-role-list' },
+ create: { url: '#/user-management/roles/create', id: 'cd-role-form' }
+ };
+
+ create(name: string, description: string) {
+ this.navigateTo('create');
+ // Waits for data to load
+ cy.contains('grafana');
+
+ // fill in fields
+ cy.get('#name').type(name);
+ cy.get('#description').type(description);
+
+ // Click the create button and wait for role to be made
+ cy.get('[data-cy=submitBtn]').click();
+ cy.get('.breadcrumb-item.active').should('not.have.text', 'Create');
+
+ this.getFirstTableCell(name).should('exist');
+ }
+
+ edit(name: string, description: string) {
+ this.navigateEdit(name);
+ // Waits for data to load
+ cy.contains('grafana');
+
+ // fill in fields with new values
+ cy.get('#description').clear().type(description);
+
+ // Click the edit button and check new values are present in table
+ cy.get('[data-cy=submitBtn]').click();
+ cy.get('.breadcrumb-item.active').should('not.have.text', 'Edit');
+
+ this.getFirstTableCell(name).should('exist');
+ this.getFirstTableCell(description).should('exist');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/user-mgmt.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/user-mgmt.e2e-spec.ts
new file mode 100644
index 000000000..92dc77212
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/user-mgmt.e2e-spec.ts
@@ -0,0 +1,37 @@
+import { UserMgmtPageHelper } from './user-mgmt.po';
+
+describe('User Management page', () => {
+ const userMgmt = new UserMgmtPageHelper();
+ const user_name = 'e2e_user_mgmt_user';
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ userMgmt.navigateTo();
+ });
+
+ describe('breadcrumb tests', () => {
+ it('should check breadcrumb on users tab of user management page', () => {
+ userMgmt.expectBreadcrumbText('Users');
+ });
+
+ it('should check breadcrumb on user creation page', () => {
+ userMgmt.navigateTo('create');
+ userMgmt.expectBreadcrumbText('Create');
+ });
+ });
+
+ describe('user create, edit & delete test', () => {
+ it('should create a user', () => {
+ userMgmt.create(user_name, 'cool_password', 'Jeff', 'realemail@realwebsite.com');
+ });
+
+ it('should edit a user', () => {
+ userMgmt.edit(user_name, 'cool_password_number_2', 'Geoff', 'w@m');
+ });
+
+ it('should delete a user', () => {
+ userMgmt.delete(user_name);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/user-mgmt.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/user-mgmt.po.ts
new file mode 100644
index 000000000..fb2b79129
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/ui/user-mgmt.po.ts
@@ -0,0 +1,39 @@
+import { PageHelper } from '../page-helper.po';
+
+export class UserMgmtPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/user-management/users', id: 'cd-user-list' },
+ create: { url: '#/user-management/users/create', id: 'cd-user-form' }
+ };
+
+ create(username: string, password: string, name: string, email: string) {
+ this.navigateTo('create');
+
+ // fill in fields
+ cy.get('#username').type(username);
+ cy.get('#password').type(password);
+ cy.get('#confirmpassword').type(password);
+ cy.get('#name').type(name);
+ cy.get('#email').type(email);
+
+ // Click the create button and wait for user to be made
+ cy.get('[data-cy=submitBtn]').click();
+ this.getFirstTableCell(username).should('exist');
+ }
+
+ edit(username: string, password: string, name: string, email: string) {
+ this.navigateEdit(username);
+
+ // fill in fields with new values
+ cy.get('#password').clear().type(password);
+ cy.get('#confirmpassword').clear().type(password);
+ cy.get('#name').clear().type(name);
+ cy.get('#email').clear().type(email);
+
+ // Click the edit button and check new values are present in table
+ const editButton = cy.get('[data-cy=submitBtn]');
+ editButton.click();
+ this.getFirstTableCell(email).should('exist');
+ this.getFirstTableCell(name).should('exist');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/visualTests/dashboard.vrt-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/visualTests/dashboard.vrt-spec.ts
new file mode 100644
index 000000000..b83d16d3d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/visualTests/dashboard.vrt-spec.ts
@@ -0,0 +1,22 @@
+import { LoginPageHelper } from '../ui/login.po';
+
+describe('Dashboard Landing Page', () => {
+ const login = new LoginPageHelper();
+
+ beforeEach(() => {
+ cy.eyesOpen({
+ testName: 'Dashboard Component'
+ });
+ });
+
+ afterEach(() => {
+ cy.eyesClose();
+ });
+
+ it('should take screenshot of dashboard landing page', () => {
+ login.navigateTo();
+ login.doLogin();
+ cy.get('.card-text').should('be.visible');
+ cy.eyesCheckWindow({ tag: 'Dashboard landing page', ignore: { selector: '.card-text' } });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/visualTests/login.vrt-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/visualTests/login.vrt-spec.ts
new file mode 100644
index 000000000..ea74f1d0f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/visualTests/login.vrt-spec.ts
@@ -0,0 +1,19 @@
+describe('Login Page', () => {
+ beforeEach(() => {
+ cy.visit('#/login');
+ cy.eyesOpen({
+ appName: 'Ceph',
+ testName: 'Login Component Check'
+ });
+ });
+
+ afterEach(() => {
+ cy.eyesClose();
+ });
+
+ it('types login credentials and takes screenshot', () => {
+ cy.get('[name=username]').type('admin');
+ cy.get('#password').type('admin');
+ cy.eyesCheckWindow({ tag: 'Login Screen with credentials typed' });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/plugins/index.js b/src/pybind/mgr/dashboard/frontend/cypress/plugins/index.js
new file mode 100644
index 000000000..d9294002b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/plugins/index.js
@@ -0,0 +1,26 @@
+
+const browserify = require('@cypress/browserify-preprocessor');
+const cucumber = require('cypress-cucumber-preprocessor').default;
+module.exports = (on, _config) => {
+ const options = {
+ ...browserify.defaultOptions,
+ typescript: require.resolve("typescript"),
+ };
+
+ on('file:preprocessor', cucumber(options));
+ on('before:browser:launch', (browser, launchOptions) => {
+ if (browser.name === 'chrome' && browser.isHeadless) {
+ launchOptions.args.push('--disable-gpu');
+ return launchOptions;
+ }
+ });
+
+ on('task', {
+ log({ message, optional }) {
+ optional ? console.log(message, optional) : console.log(message);
+ return null;
+ },
+ });
+};
+
+require('@applitools/eyes-cypress')(module);
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/support/commands.ts b/src/pybind/mgr/dashboard/frontend/cypress/support/commands.ts
new file mode 100644
index 000000000..6ff17f9d6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/support/commands.ts
@@ -0,0 +1,59 @@
+declare global {
+ namespace Cypress {
+ interface Chainable<Subject> {
+ login(): void;
+ logToConsole(message: string, optional?: any): void;
+ text(): Chainable<string>;
+ }
+ }
+}
+// Disabling tslint rule since cypress-cucumber has
+// issues with absolute import paths.
+// This can be removed when
+// https://github.com/cypress-io/cypress-browserify-preprocessor/issues/53
+// is fixed.
+/* tslint:disable*/
+import { CdHelperClass } from '../../src/app/shared/classes/cd-helper.class';
+import { Permissions } from '../../src/app/shared/models/permissions';
+/* tslint:enable*/
+let auth: any;
+
+const fillAuth = () => {
+ window.localStorage.setItem('dashboard_username', auth.username);
+ window.localStorage.setItem('dashboard_permissions', auth.permissions);
+ window.localStorage.setItem('user_pwd_expiration_date', auth.pwdExpirationDate);
+ window.localStorage.setItem('user_pwd_update_required', auth.pwdUpdateRequired);
+ window.localStorage.setItem('sso', auth.sso);
+};
+
+Cypress.Commands.add('login', () => {
+ const username = Cypress.env('LOGIN_USER') || 'admin';
+ const password = Cypress.env('LOGIN_PWD') || 'admin';
+
+ if (auth === undefined) {
+ cy.request({
+ method: 'POST',
+ url: 'api/auth',
+ headers: { Accept: CdHelperClass.cdVersionHeader('1', '0') },
+ body: { username: username, password: password }
+ }).then((resp) => {
+ auth = resp.body;
+ auth.permissions = JSON.stringify(new Permissions(auth.permissions));
+ auth.pwdExpirationDate = String(auth.pwdExpirationDate);
+ auth.pwdUpdateRequired = String(auth.pwdUpdateRequired);
+ auth.sso = String(auth.sso);
+ fillAuth();
+ });
+ } else {
+ fillAuth();
+ }
+});
+
+// @ts-ignore
+Cypress.Commands.add('text', { prevSubject: true }, (subject: any) => {
+ return subject.text();
+});
+
+Cypress.Commands.add('logToConsole', (message: string, optional?: any) => {
+ cy.task('log', { message: `(${new Date().toISOString()}) ${message}`, optional });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/support/eyes-index.d.ts b/src/pybind/mgr/dashboard/frontend/cypress/support/eyes-index.d.ts
new file mode 100644
index 000000000..59fc1eca4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/support/eyes-index.d.ts
@@ -0,0 +1 @@
+import '@applitools/eyes-cypress';
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/support/index.ts b/src/pybind/mgr/dashboard/frontend/cypress/support/index.ts
new file mode 100644
index 000000000..f2307131a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/support/index.ts
@@ -0,0 +1,11 @@
+import '@applitools/eyes-cypress/commands';
+
+import './commands';
+
+afterEach(() => {
+ cy.visit('#/403');
+});
+
+Cypress.on('uncaught:exception', (err: Error) => {
+ return !err.message.includes('ResizeObserver loop limit exceeded');
+});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/tsconfig.json b/src/pybind/mgr/dashboard/frontend/cypress/tsconfig.json
new file mode 100644
index 000000000..90f899b57
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/cypress/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "extends": "../tsconfig.json",
+ "exclude": [],
+ "include": [
+ "**/*.ts",
+ "plugins/index.js"
+ ],
+ "compilerOptions": {
+ "sourceMap": false,
+ "types": [
+ "cypress",
+ "@applitools/eyes-cypress"
+ ],
+ "target": "es6"
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/117.9781bbf8cc6a4aaa7e8e.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/117.9781bbf8cc6a4aaa7e8e.js
new file mode 100644
index 000000000..b02db3d52
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/117.9781bbf8cc6a4aaa7e8e.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkceph_dashboard=self.webpackChunkceph_dashboard||[]).push([[117],{73117:(Si,Ae,r)=>{r.r(Ae),r.d(Ae,{PoolModule:()=>ze,RoutedPoolModule:()=>hi});var C=r(12057),a=r(24751),Oe=r(6283),E=r(38549),M=r(79512),O_=r(44466),d_=r(70483),u_=r(370),f_=r(23815),g=r.n(f_),P_=r(80226),E_=r(26504),ue=r(80842);class S{constructor(){this.nodes=[],this.idTree={},this.allDevices=[],this.buckets=[],this.failureDomains={},this.failureDomainKeys=[],this.devices=[],this.deviceCount=0}static searchFailureDomains(i,_){return this.getFailureDomains(this.search(i,_))}static search(i,_){const[o,n]=_.split("~"),s=i.find(c=>["name","id","type"].some(d=>c[d]===o));return s?(i=this.getSubNodes(s,this.createIdTreeFromNodes(i)),n&&(i=this.filterNodesByDeviceType(i,n)),i):[]}static createIdTreeFromNodes(i){const _={};return i.forEach(o=>{_[o.id]=o}),_}static getSubNodes(i,_){let o=[i];return i.children&&i.children.forEach(n=>{o=o.concat(this.getSubNodes(_[n],_))}),o}static filterNodesByDeviceType(i,_){let n,o=i.filter(c=>c.device_class&&c.device_class!==_).map(c=>c.id),s=o;do{n=!1,i=i.filter(d=>!o.includes(d.id));const c=[];i.forEach(d=>{d.children&&d.children.every(f=>o.includes(f))&&(c.push(d.id),n=!0)}),n&&(o=c,s=s.concat(c))}while(n);return(i=g().cloneDeep(i)).map(c=>(c.children&&(c.children=c.children.filter(d=>!s.includes(d))),c))}static getFailureDomains(i){const _={};return i.forEach(o=>{const n=o.type;_[n]||(_[n]=[]),_[n].push(o)}),_}initCrushNodeSelection(i,_,o,n){this.nodes=i,this.idTree=S.createIdTreeFromNodes(i),i.forEach(s=>{this.idTree[s.id]=s}),this.buckets=g().sortBy(i.filter(s=>s.children),"name"),this.controls={root:_,failure:o,device:n},this.preSelectRoot(),this.controls.root.valueChanges.subscribe(()=>this.onRootChange()),this.controls.failure.valueChanges.subscribe(()=>this.onFailureDomainChange()),this.controls.device.valueChanges.subscribe(()=>this.onDeviceChange())}preSelectRoot(){const i=this.nodes.find(_=>"root"===_.type);this.silentSet(this.controls.root,i),this.onRootChange()}silentSet(i,_){i.setValue(_,{emitEvent:!1})}onRootChange(){const i=S.getSubNodes(this.controls.root.value,this.idTree),_=S.getFailureDomains(i);Object.keys(_).forEach(o=>{_[o].length<=1&&delete _[o]}),this.failureDomains=_,this.failureDomainKeys=Object.keys(_).sort(),this.updateFailureDomain()}updateFailureDomain(){let i=this.getIncludedCustomValue(this.controls.failure,Object.keys(this.failureDomains));""===i&&(i=this.setMostCommonDomain(this.controls.failure)),this.updateDevices(i)}getIncludedCustomValue(i,_){return i.dirty&&_.includes(i.value)?i.value:""}setMostCommonDomain(i){let _={n:0,type:""};return Object.keys(this.failureDomains).forEach(o=>{const n=this.failureDomains[o].length;_.n<n&&(_={n,type:o})}),this.silentSet(i,_.type),_.type}onFailureDomainChange(){this.updateDevices()}updateDevices(i=this.controls.failure.value){const _=g().flatten(this.failureDomains[i].map(n=>S.getSubNodes(n,this.idTree)));this.allDevices=_.filter(n=>n.device_class).map(n=>n.device_class),this.devices=g().uniq(this.allDevices).sort();const o=1===this.devices.length?this.devices[0]:this.getIncludedCustomValue(this.controls.device,this.devices);this.silentSet(this.controls.device,o),this.onDeviceChange(o)}onDeviceChange(i=this.controls.device.value){this.deviceCount=""===i?this.allDevices.length:this.allDevices.filter(_=>_===i).length}}var Fe=r(30982),g_=r(14745),v=r(65862),p_=r(93614),Ne=r(95463),P=r(77205),m_=r(30633),I=r(76111),R_=r(47557),C_=r(28211),de=r(32337),e=r(74788),be=r(62862),ve=r(83608),Ie=r(60312),fe=r(41582),Pe=r(56310),Ee=r(87925),ge=r(94276),pe=r(82945),me=r(18372),Re=r(30839),Ce=r(10545);function M_(t,i){1&t&&(e.TgZ(0,"span",30),e.SDv(1,31),e.qZA())}function T_(t,i){1&t&&(e.TgZ(0,"span",30),e.SDv(1,32),e.qZA())}function h_(t,i){1&t&&(e.TgZ(0,"span",30),e.SDv(1,33),e.qZA())}function S_(t,i){1&t&&(e.TgZ(0,"option",26),e.SDv(1,34),e.qZA())}function L_(t,i){if(1&t&&(e.TgZ(0,"option",35),e._uU(1),e.qZA()),2&t){const _=i.$implicit;e.Q6J("ngValue",_),e.xp6(1),e.hij(" ",_.name," ")}}function A_(t,i){1&t&&(e.TgZ(0,"span",30),e.SDv(1,36),e.qZA())}function F_(t,i){1&t&&(e.TgZ(0,"option",26),e.SDv(1,37),e.qZA())}function N_(t,i){if(1&t&&(e.TgZ(0,"option",35),e._uU(1),e.qZA()),2&t){const _=i.$implicit,o=e.oxw();e.Q6J("ngValue",_),e.xp6(1),e.AsE(" ",_," ( ",o.failureDomains[_].length," ) ")}}function b_(t,i){1&t&&(e.TgZ(0,"span",30),e.SDv(1,38),e.qZA())}function v_(t,i){if(1&t&&(e.TgZ(0,"option",35),e._uU(1),e.qZA()),2&t){const _=i.$implicit;e.Q6J("ngValue",_),e.xp6(1),e.hij(" ",_," ")}}let I_=(()=>{class t extends S{constructor(_,o,n,s,c){super(),this.formBuilder=_,this.activeModal=o,this.taskWrapper=n,this.crushRuleService=s,this.actionLabels=c,this.submitAction=new e.vpe,this.tooltips=this.crushRuleService.formTooltips,this.action=this.actionLabels.CREATE,this.resource="Crush Rule",this.createForm()}createForm(){this.form=this.formBuilder.group({name:["",[a.kI.required,a.kI.pattern("[A-Za-z0-9_-]+"),P.h.custom("uniqueName",_=>this.names&&-1!==this.names.indexOf(_))]],root:null,failure_domain:"",device_class:""})}ngOnInit(){this.crushRuleService.getInfo().subscribe(({names:_,nodes:o})=>{this.initCrushNodeSelection(o,this.form.get("root"),this.form.get("failure_domain"),this.form.get("device_class")),this.names=_})}onSubmit(){if(this.form.invalid)return void this.form.setErrors({cdSubmitButton:!0});const _=g().cloneDeep(this.form.value);_.root=_.root.name,""===_.device_class&&delete _.device_class,this.taskWrapper.wrapTaskAroundCall({task:new I.R("crushRule/create",_),call:this.crushRuleService.create(_)}).subscribe({error:()=>{this.form.setErrors({cdSubmitButton:!0})},complete:()=>{this.activeModal.close(),this.submitAction.emit(_)}})}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(be.O),e.Y36(E.Kz),e.Y36(de.P),e.Y36(ve.H),e.Y36(M.p4))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-crush-rule-form-modal"]],outputs:{submitAction:"submitAction"},features:[e.qOj],decls:55,vars:27,consts:function(){let i,_,o,n,s,c,d,f,p,m,T,h,R;return i="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",_="Name",o="Root",n="Failure domain type",s="Device class",c="Let Ceph decide",d="This field is required!",f="The name can only consist of alphanumeric characters, dashes and underscores.",p="The chosen erasure code profile name is already in use.",m="Loading...",T="This field is required!",h="Loading...",R="This field is required!",[[3,"modalRef"],[1,"modal-title"],i,[1,"modal-content"],["novalidate","",3,"formGroup"],["frm","ngForm"],[1,"modal-body"],[1,"form-group","row"],["for","name",1,"cd-col-form-label"],_,[1,"required"],[1,"cd-col-form-input"],["type","text","id","name","name","name","placeholder","Name...","formControlName","name","autofocus","",1,"form-control"],["class","invalid-feedback",4,"ngIf"],["for","root",1,"cd-col-form-label"],o,[3,"html"],["id","root","name","root","formControlName","root",1,"form-control"],["ngValue","",4,"ngIf"],[3,"ngValue",4,"ngFor","ngForOf"],["for","failure_domain",1,"cd-col-form-label"],n,["id","failure_domain","name","failure_domain","formControlName","failure_domain",1,"form-control"],["for","device_class",1,"cd-col-form-label"],s,["id","device_class","name","device_class","formControlName","device_class",1,"form-control"],["ngValue",""],c,[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],[1,"invalid-feedback"],d,f,p,m,[3,"ngValue"],T,h,R]},template:function(_,o){if(1&_&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.ALo(3,"titlecase"),e.ALo(4,"upperFirst"),e.BQk(),e.ynx(5,3),e.TgZ(6,"form",4,5),e.TgZ(8,"div",6),e.TgZ(9,"div",7),e.TgZ(10,"label",8),e.ynx(11),e.SDv(12,9),e.BQk(),e._UZ(13,"span",10),e.qZA(),e.TgZ(14,"div",11),e._UZ(15,"input",12),e.YNc(16,M_,2,0,"span",13),e.YNc(17,T_,2,0,"span",13),e.YNc(18,h_,2,0,"span",13),e.qZA(),e.qZA(),e.TgZ(19,"div",7),e.TgZ(20,"label",14),e.ynx(21),e.SDv(22,15),e.BQk(),e._UZ(23,"cd-helper",16),e._UZ(24,"span",10),e.qZA(),e.TgZ(25,"div",11),e.TgZ(26,"select",17),e.YNc(27,S_,2,0,"option",18),e.YNc(28,L_,2,2,"option",19),e.qZA(),e.YNc(29,A_,2,0,"span",13),e.qZA(),e.qZA(),e.TgZ(30,"div",7),e.TgZ(31,"label",20),e.ynx(32),e.SDv(33,21),e.BQk(),e._UZ(34,"cd-helper",16),e._UZ(35,"span",10),e.qZA(),e.TgZ(36,"div",11),e.TgZ(37,"select",22),e.YNc(38,F_,2,0,"option",18),e.YNc(39,N_,2,3,"option",19),e.qZA(),e.YNc(40,b_,2,0,"span",13),e.qZA(),e.qZA(),e.TgZ(41,"div",7),e.TgZ(42,"label",23),e.ynx(43),e.SDv(44,24),e.BQk(),e._UZ(45,"cd-helper",16),e.qZA(),e.TgZ(46,"div",11),e.TgZ(47,"select",25),e.TgZ(48,"option",26),e.SDv(49,27),e.qZA(),e.YNc(50,v_,2,2,"option",19),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(51,"div",28),e.TgZ(52,"cd-form-button-panel",29),e.NdJ("submitActionEvent",function(){return o.onSubmit()}),e.ALo(53,"titlecase"),e.ALo(54,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&_){const n=e.MAs(7);e.Q6J("modalRef",o.activeModal),e.xp6(4),e.pQV(e.lcZ(3,19,o.action))(e.lcZ(4,21,o.resource)),e.QtT(2),e.xp6(2),e.Q6J("formGroup",o.form),e.xp6(10),e.Q6J("ngIf",o.form.showError("name",n,"required")),e.xp6(1),e.Q6J("ngIf",o.form.showError("name",n,"pattern")),e.xp6(1),e.Q6J("ngIf",o.form.showError("name",n,"uniqueName")),e.xp6(5),e.Q6J("html",o.tooltips.root),e.xp6(4),e.Q6J("ngIf",!o.buckets),e.xp6(1),e.Q6J("ngForOf",o.buckets),e.xp6(1),e.Q6J("ngIf",o.form.showError("root",n,"required")),e.xp6(5),e.Q6J("html",o.tooltips.failure_domain),e.xp6(4),e.Q6J("ngIf",!o.failureDomains),e.xp6(1),e.Q6J("ngForOf",o.failureDomainKeys),e.xp6(1),e.Q6J("ngIf",o.form.showError("failure_domain",n,"required")),e.xp6(5),e.Q6J("html",o.tooltips.device_class),e.xp6(5),e.Q6J("ngForOf",o.devices),e.xp6(2),e.Q6J("form",o.form)("submitText",e.lcZ(53,23,o.action)+" "+e.lcZ(54,25,o.resource))}},directives:[Ie.z,a._Y,a.JL,fe.V,a.sg,Pe.P,Ee.o,a.Fj,ge.b,a.JJ,a.u,pe.U,C.O5,me.S,a.EJ,C.sg,a.YN,a.Kr,Re.p],pipes:[C.rS,Ce.m],styles:[""]}),t})();class $_{}var D_=r(58497);let Me=(()=>{class t{constructor(_){this.http=_,this.apiPath="api/erasure_code_profile",this.formTooltips={k:"Each object is split in data-chunks parts, each stored on a different OSD.",m:"Compute coding chunks for each object and store them on different OSDs.\n The number of coding chunks is also the number of OSDs that can be down without losing data.",plugins:{jerasure:{description:"The jerasure plugin is the most generic and flexible plugin,\n it is also the default for Ceph erasure coded pools.",technique:"The more flexible technique is reed_sol_van : it is enough to set k\n and m. The cauchy_good technique can be faster but you need to chose the packetsize\n carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents\n in the sense that they can only be configured with m=2.",packetSize:"The encoding will be done on packets of bytes size at a time.\n Choosing the right packet size is difficult.\n The jerasure documentation contains extensive information on this topic."},lrc:{description:"With the jerasure plugin, when an erasure coded object is stored on\n multiple OSDs, recovering from the loss of one OSD requires reading from all the others.\n For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading\n from the eleven others to repair.\n\n The lrc erasure code plugin creates local parity chunks to be able to recover using\n less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create\n an additional parity chunk for every four OSDs. When a single OSD is lost, it can be\n recovered with only four OSDs instead of eleven.",l:"Group the coding and data chunks into sets of size locality. For instance,\n for k=4 and m=2, when locality=3 two groups of three are created. Each set can\n be recovered without reading chunks from another set.",crushLocality:"The type of the crush bucket in which each set of chunks defined\n by l will be stored. For instance, if it is set to rack, each group of l chunks will be\n placed in a different rack. It is used to create a CRUSH rule step such as step choose\n rack. If it is not set, no such grouping is done."},isa:{description:"The isa plugin encapsulates the ISA library. It only runs on Intel processors.",technique:"The ISA plugin comes in two Reed Solomon forms.\n If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy."},shec:{description:"The shec plugin encapsulates the multiple SHEC library.\n It allows ceph to recover data more efficiently than Reed Solomon codes.",c:"The number of parity chunks each of which includes each data chunk in its\n calculation range. The number is used as a durability estimator. For instance, if c=2,\n 2 OSDs can be down without losing data."},clay:{description:"CLAY (short for coupled-layer) codes are erasure codes designed to\n bring about significant savings in terms of network bandwidth and disk IO when a failed\n node/OSD/rack is being repaired.",d:"Number of OSDs requested to send data during recovery of a single chunk.\n d needs to be chosen such that k+1 <= d <= k+m-1. The larger the d, the better\n the savings.",scalar_mds:"scalar_mds specifies the plugin that is used as a building block\n in the layered construction. It can be one of jerasure, isa, shec.",technique:"technique specifies the technique that will be picked\n within the 'scalar_mds' plugin specified. Supported techniques\n are 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',\n 'cauchy_good', 'liber8tion' for jerasure, 'reed_sol_van',\n 'cauchy' for isa and 'single', 'multiple' for shec."}},crushRoot:"The name of the crush bucket used for the first step of the CRUSH rule.\n For instance step take default.",crushFailureDomain:"Ensure that no two chunks are in a bucket with the same failure\n domain. For instance, if the failure domain is host no two chunks will be stored on the same\n host. It is used to create a CRUSH rule step such as step chooseleaf host.",crushDeviceClass:"Restrict placement to devices of a specific class\n (e.g., ssd or hdd), using the crush device class names in the CRUSH map.",directory:"Set the directory name from which the erasure code plugin is loaded."}}list(){return this.http.get(this.apiPath)}create(_){return this.http.post(this.apiPath,_,{observe:"response"})}delete(_){return this.http.delete(`${this.apiPath}/${_}`,{observe:"response"})}getInfo(){return this.http.get(`ui-${this.apiPath}/info`)}}return t.\u0275fac=function(_){return new(_||t)(e.LFG(D_.eN))},t.\u0275prov=e.Yz7({token:t,factory:t.\u0275fac,providedIn:"root"}),t})();function Z_(t,i){1&t&&(e.TgZ(0,"span",46),e.SDv(1,47),e.qZA())}function x_(t,i){1&t&&(e.TgZ(0,"span",46),e.SDv(1,48),e.qZA())}function y_(t,i){1&t&&(e.TgZ(0,"span",46),e.SDv(1,49),e.qZA())}function U_(t,i){1&t&&(e.TgZ(0,"option",37),e.SDv(1,50),e.qZA())}function q_(t,i){if(1&t&&(e.TgZ(0,"option",51),e._uU(1),e.qZA()),2&t){const _=i.$implicit;e.Q6J("ngValue",_),e.xp6(1),e.hij(" ",_," ")}}function H_(t,i){1&t&&(e.TgZ(0,"span",46),e.SDv(1,52),e.qZA())}function G_(t,i){1&t&&(e.TgZ(0,"span",46),e.SDv(1,53),e.qZA())}function z_(t,i){1&t&&(e.TgZ(0,"span",46),e.SDv(1,54),e.qZA())}function X_(t,i){if(1&t&&(e.TgZ(0,"span",46),e.SDv(1,55),e.qZA()),2&t){const _=e.oxw();e.xp6(1),e.pQV(_.deviceCount),e.QtT(1)}}function w_(t,i){1&t&&(e.TgZ(0,"span",46),e.SDv(1,56),e.qZA())}function Q_(t,i){1&t&&(e.TgZ(0,"span",46),e.SDv(1,57),e.qZA())}function J_(t,i){if(1&t&&(e.TgZ(0,"span",39),e.SDv(1,58),e.qZA()),2&t){const _=e.oxw();e.xp6(1),e.pQV(_.lrcMultiK),e.QtT(1)}}function k_(t,i){1&t&&(e.TgZ(0,"span",46),e.SDv(1,59),e.qZA())}function V_(t,i){1&t&&(e.TgZ(0,"span",46),e.SDv(1,60),e.qZA())}function Y_(t,i){if(1&t&&(e.TgZ(0,"span",46),e.SDv(1,61),e.qZA()),2&t){const _=e.oxw();e.xp6(1),e.pQV(_.deviceCount),e.QtT(1)}}function B_(t,i){1&t&&(e.TgZ(0,"span",46),e.SDv(1,65),e.qZA())}function j_(t,i){1&t&&(e.TgZ(0,"span",46),e.SDv(1,66),e.qZA())}function K_(t,i){if(1&t&&(e.TgZ(0,"div",7),e.TgZ(1,"label",62),e.TgZ(2,"span",14),e.SDv(3,63),e.qZA(),e._UZ(4,"cd-helper",16),e.qZA(),e.TgZ(5,"div",10),e._UZ(6,"input",64),e.YNc(7,B_,2,0,"span",12),e.YNc(8,j_,2,0,"span",12),e.qZA(),e.qZA()),2&t){const _=e.oxw(),o=e.MAs(7);e.xp6(4),e.Q6J("html",_.tooltips.plugins.shec.c),e.xp6(3),e.Q6J("ngIf",_.form.showError("c",o,"min")),e.xp6(1),e.Q6J("ngIf",_.form.showError("c",o,"cGreaterM"))}}function W_(t,i){1&t&&(e.TgZ(0,"span",39),e.SDv(1,75),e.qZA())}function eo(t,i){if(1&t&&(e.TgZ(0,"span",39),e.SDv(1,76),e.qZA()),2&t){const _=e.oxw(3);e.xp6(1),e.pQV(_.getDMin())(_.getDMax()),e.QtT(1)}}function _o(t,i){if(1&t&&(e.TgZ(0,"span",39),e.SDv(1,77),e.qZA()),2&t){const _=e.oxw(3);e.xp6(1),e.pQV(_.getDMax()),e.QtT(1)}}function oo(t,i){if(1&t&&(e.ynx(0),e.YNc(1,eo,2,2,"span",23),e.YNc(2,_o,2,1,"span",23),e.BQk()),2&t){const _=e.oxw(2);e.xp6(1),e.Q6J("ngIf",_.getDMin()<_.getDMax()),e.xp6(1),e.Q6J("ngIf",_.getDMin()===_.getDMax())}}function to(t,i){if(1&t&&(e.TgZ(0,"span",46),e.SDv(1,78),e.qZA()),2&t){const _=e.oxw(2);e.xp6(1),e.pQV(_.getDMin()),e.QtT(1)}}function io(t,i){if(1&t&&(e.TgZ(0,"span",46),e.SDv(1,79),e.qZA()),2&t){const _=e.oxw(2);e.xp6(1),e.pQV(_.getDMax()),e.QtT(1)}}function no(t,i){if(1&t){const _=e.EpF();e.TgZ(0,"div",7),e.TgZ(1,"label",67),e.TgZ(2,"span",14),e.SDv(3,68),e.qZA(),e._UZ(4,"cd-helper",16),e.qZA(),e.TgZ(5,"div",10),e.TgZ(6,"div",69),e._UZ(7,"input",70),e.TgZ(8,"span",71),e.TgZ(9,"button",72),e.NdJ("click",function(){return e.CHM(_),e.oxw().toggleDCalc()}),e._UZ(10,"i",73),e.qZA(),e.qZA(),e.qZA(),e.YNc(11,W_,2,0,"span",23),e.YNc(12,oo,3,2,"ng-container",74),e.YNc(13,to,2,1,"span",12),e.YNc(14,io,2,1,"span",12),e.qZA(),e.qZA()}if(2&t){const _=e.oxw(),o=e.MAs(7);e.xp6(4),e.Q6J("html",_.tooltips.plugins.clay.d),e.xp6(6),e.Q6J("ngClass",_.dCalc?_.icons.unlock:_.icons.lock),e.xp6(1),e.Q6J("ngIf",_.dCalc),e.xp6(1),e.Q6J("ngIf",!_.dCalc),e.xp6(1),e.Q6J("ngIf",_.form.showError("d",o,"dMin")),e.xp6(1),e.Q6J("ngIf",_.form.showError("d",o,"dMax"))}}function so(t,i){1&t&&(e.TgZ(0,"span",46),e.SDv(1,84),e.qZA())}function ao(t,i){1&t&&(e.TgZ(0,"span",46),e.SDv(1,85),e.qZA())}function lo(t,i){1&t&&(e.TgZ(0,"span",46),e.SDv(1,86),e.qZA())}function ro(t,i){if(1&t&&(e.TgZ(0,"div",7),e.TgZ(1,"label",80),e.TgZ(2,"span",14),e.SDv(3,81),e.qZA(),e._UZ(4,"cd-helper",16),e.qZA(),e.TgZ(5,"div",10),e._UZ(6,"input",82),e.YNc(7,so,2,0,"span",12),e.YNc(8,ao,2,0,"span",12),e.YNc(9,lo,2,0,"span",12),e.TgZ(10,"span",39),e.SDv(11,83),e.qZA(),e.qZA(),e.qZA()),2&t){const _=e.oxw(),o=e.MAs(7);e.xp6(4),e.Q6J("html",_.tooltips.plugins.lrc.l),e.xp6(3),e.Q6J("ngIf",_.form.showError("l",o,"required")),e.xp6(1),e.Q6J("ngIf",_.form.showError("l",o,"min")),e.xp6(1),e.Q6J("ngIf",_.form.showError("l",o,"unequal")),e.xp6(2),e.pQV(_.lrcGroups),e.QtT(11)}}function co(t,i){1&t&&(e.TgZ(0,"option",37),e.SDv(1,87),e.qZA())}function Oo(t,i){if(1&t&&(e.TgZ(0,"option",51),e._uU(1),e.qZA()),2&t){const _=i.$implicit,o=e.oxw();e.Q6J("ngValue",_),e.xp6(1),e.AsE(" ",_," ( ",o.failureDomains[_].length," ) ")}}function uo(t,i){1&t&&(e.TgZ(0,"option",37),e.SDv(1,91),e.qZA())}function fo(t,i){1&t&&(e.TgZ(0,"option",37),e.SDv(1,92),e.qZA())}function Po(t,i){if(1&t&&(e.TgZ(0,"option",51),e._uU(1),e.qZA()),2&t){const _=i.$implicit,o=e.oxw(2);e.Q6J("ngValue",_),e.xp6(1),e.AsE(" ",_," ( ",o.failureDomains[_].length," ) ")}}function Eo(t,i){if(1&t&&(e.TgZ(0,"div",7),e.TgZ(1,"label",88),e.ynx(2),e.SDv(3,89),e.BQk(),e._UZ(4,"cd-helper",16),e.qZA(),e.TgZ(5,"div",10),e.TgZ(6,"select",90),e.YNc(7,uo,2,0,"option",18),e.YNc(8,fo,2,0,"option",18),e.YNc(9,Po,2,3,"option",19),e.qZA(),e.qZA(),e.qZA()),2&t){const _=e.oxw();e.xp6(4),e.Q6J("html",_.tooltips.plugins.lrc.crushLocality),e.xp6(3),e.Q6J("ngIf",!_.failureDomains),e.xp6(1),e.Q6J("ngIf",_.failureDomainKeys.length>0),e.xp6(1),e.Q6J("ngForOf",_.failureDomainKeys)}}function go(t,i){if(1&t&&(e.TgZ(0,"option",51),e._uU(1),e.qZA()),2&t){const _=i.$implicit;e.Q6J("ngValue",_),e.xp6(1),e.hij(" ",_," ")}}const $e=function(t,i,_){return[t,i,_]};function po(t,i){if(1&t&&(e.TgZ(0,"div",7),e.TgZ(1,"label",93),e.ynx(2),e.SDv(3,94),e.BQk(),e._UZ(4,"cd-helper",16),e.qZA(),e.TgZ(5,"div",10),e.TgZ(6,"select",95),e.YNc(7,go,2,2,"option",19),e.qZA(),e.qZA(),e.qZA()),2&t){const _=e.oxw();e.xp6(4),e.Q6J("html",_.tooltips.plugins.clay.scalar_mds),e.xp6(3),e.Q6J("ngForOf",e.kEZ(2,$e,_.PLUGIN.JERASURE,_.PLUGIN.ISA,_.PLUGIN.SHEC))}}function mo(t,i){if(1&t&&(e.TgZ(0,"option",51),e._uU(1),e.qZA()),2&t){const _=i.$implicit;e.Q6J("ngValue",_),e.xp6(1),e.hij(" ",_," ")}}function Ro(t,i){if(1&t&&(e.TgZ(0,"div",7),e.TgZ(1,"label",96),e.ynx(2),e.SDv(3,97),e.BQk(),e._UZ(4,"cd-helper",16),e.qZA(),e.TgZ(5,"div",10),e.TgZ(6,"select",98),e.YNc(7,mo,2,2,"option",19),e.qZA(),e.qZA(),e.qZA()),2&t){const _=e.oxw();e.xp6(4),e.Q6J("html",_.tooltips.plugins[_.plugin].technique),e.xp6(3),e.Q6J("ngForOf",_.techniques)}}function Co(t,i){1&t&&(e.TgZ(0,"span",46),e.SDv(1,102),e.qZA())}function Mo(t,i){if(1&t&&(e.TgZ(0,"div",7),e.TgZ(1,"label",99),e.ynx(2),e.SDv(3,100),e.BQk(),e._UZ(4,"cd-helper",16),e.qZA(),e.TgZ(5,"div",10),e._UZ(6,"input",101),e.YNc(7,Co,2,0,"span",12),e.qZA(),e.qZA()),2&t){const _=e.oxw(),o=e.MAs(7);e.xp6(4),e.Q6J("html",_.tooltips.plugins.jerasure.packetSize),e.xp6(3),e.Q6J("ngIf",_.form.showError("packetSize",o,"min"))}}function To(t,i){1&t&&(e.TgZ(0,"option",37),e.SDv(1,103),e.qZA())}function ho(t,i){if(1&t&&(e.TgZ(0,"option",51),e._uU(1),e.qZA()),2&t){const _=i.$implicit;e.Q6J("ngValue",_),e.xp6(1),e.hij(" ",_.name," ")}}function So(t,i){if(1&t&&(e.TgZ(0,"option",51),e._uU(1),e.qZA()),2&t){const _=i.$implicit;e.Q6J("ngValue",_),e.xp6(1),e.hij(" ",_," ")}}let Lo=(()=>{class t extends S{constructor(_,o,n,s,c){super(),this.formBuilder=_,this.activeModal=o,this.taskWrapper=n,this.ecpService=s,this.actionLabels=c,this.submitAction=new e.vpe,this.tooltips=this.ecpService.formTooltips,this.PLUGIN={LRC:"lrc",SHEC:"shec",CLAY:"clay",JERASURE:"jerasure",ISA:"isa"},this.plugin=this.PLUGIN.JERASURE,this.icons=v.P,this.action=this.actionLabels.CREATE,this.resource="EC Profile",this.createForm(),this.setJerasureDefaults()}createForm(){this.form=this.formBuilder.group({name:[null,[a.kI.required,a.kI.pattern("[A-Za-z0-9_-]+"),P.h.custom("uniqueName",_=>this.names&&-1!==this.names.indexOf(_))]],plugin:[this.PLUGIN.JERASURE,[a.kI.required]],k:[4,[a.kI.required,P.h.custom("max",()=>this.baseValueValidation(!0)),P.h.custom("unequal",_=>this.lrcDataValidation(_)),P.h.custom("kLowerM",_=>this.shecDataValidation(_))]],m:[2,[a.kI.required,P.h.custom("max",()=>this.baseValueValidation())]],crushFailureDomain:"",crushRoot:null,crushDeviceClass:"",directory:"",technique:"reed_sol_van",packetSize:[2048],l:[3,[a.kI.required,P.h.custom("unequal",_=>this.lrcLocalityValidation(_))]],crushLocality:"",c:[2,[a.kI.required,P.h.custom("cGreaterM",_=>this.shecDurabilityValidation(_))]],d:[5,[a.kI.required,P.h.custom("dMin",_=>this.dMinValidation(_)),P.h.custom("dMax",_=>this.dMaxValidation(_))]],scalar_mds:[this.PLUGIN.JERASURE,[a.kI.required]]}),this.toggleDCalc(),this.form.get("k").valueChanges.subscribe(()=>this.updateValidityOnChange(["m","l","d"])),this.form.get("m").valueChanges.subscribe(()=>this.updateValidityOnChange(["k","l","c","d"])),this.form.get("l").valueChanges.subscribe(()=>this.updateValidityOnChange(["k","m"])),this.form.get("plugin").valueChanges.subscribe(_=>this.onPluginChange(_)),this.form.get("scalar_mds").valueChanges.subscribe(()=>this.setClayDefaultsForScalar())}baseValueValidation(_=!1){return this.validValidation(()=>this.getKMSum()>this.deviceCount&&this.form.getValue("k")>this.form.getValue("m")===_)}validValidation(_,o){return!((!this.form||o)&&this.plugin!==o)&&_()}getKMSum(){return this.form.getValue("k")+this.form.getValue("m")}lrcDataValidation(_){return this.validValidation(()=>{const o=this.form.getValue("m"),n=this.form.getValue("l"),s=_+o;return this.lrcMultiK=_/(s/n),_%(s/n)!=0},"lrc")}shecDataValidation(_){return this.validValidation(()=>this.form.getValue("m")>_,"shec")}lrcLocalityValidation(_){return this.validValidation(()=>{const o=this.getKMSum();return this.lrcGroups=_>0?o/_:0,_>0&&o%_!=0},"lrc")}shecDurabilityValidation(_){return this.validValidation(()=>{const o=this.form.getValue("m");return _>o},"shec")}dMinValidation(_){return this.validValidation(()=>this.getDMin()>_,"clay")}getDMin(){return this.form.getValue("k")+1}dMaxValidation(_){return this.validValidation(()=>_>this.getDMax(),"clay")}getDMax(){const _=this.form.getValue("m");return this.form.getValue("k")+_-1}toggleDCalc(){this.dCalc=!this.dCalc,this.form.get("d")[this.dCalc?"disable":"enable"](),this.calculateD()}calculateD(){this.plugin!==this.PLUGIN.CLAY||!this.dCalc||this.form.silentSet("d",this.getDMax())}updateValidityOnChange(_){_.forEach(o=>{"d"===o&&this.calculateD(),this.form.get(o).updateValueAndValidity({emitEvent:!1})})}onPluginChange(_){this.plugin=_,_===this.PLUGIN.JERASURE?this.setJerasureDefaults():_===this.PLUGIN.LRC?this.setLrcDefaults():_===this.PLUGIN.ISA?this.setIsaDefaults():_===this.PLUGIN.SHEC?this.setShecDefaults():_===this.PLUGIN.CLAY&&this.setClayDefaults(),this.updateValidityOnChange(["m"])}setJerasureDefaults(){this.techniques=["reed_sol_van","reed_sol_r6_op","cauchy_orig","cauchy_good","liberation","blaum_roth","liber8tion"],this.setDefaults({k:4,m:2,technique:"reed_sol_van"})}setLrcDefaults(){this.setDefaults({k:4,m:2,l:3})}setIsaDefaults(){this.techniques=["reed_sol_van","cauchy"],this.setDefaults({k:7,m:3,technique:"reed_sol_van"})}setShecDefaults(){this.setDefaults({k:4,m:3,c:2})}setClayDefaults(){this.setDefaults({k:4,m:2,scalar_mds:this.PLUGIN.JERASURE}),this.setClayDefaultsForScalar()}setClayDefaultsForScalar(){const _=this.form.getValue("scalar_mds");let o="reed_sol_van";_===this.PLUGIN.JERASURE?this.techniques=["reed_sol_van","reed_sol_r6_op","cauchy_orig","cauchy_good","liber8tion"]:_===this.PLUGIN.ISA?this.techniques=["reed_sol_van","cauchy"]:(o="single",this.techniques=["single","multiple"]),this.setDefaults({technique:o})}setDefaults(_){Object.keys(_).forEach(o=>{const n=this.form.get(o),s=n.value;n.pristine||"technique"===o&&!this.techniques.includes(s)||"k"===o&&[4,7].includes(s)||"m"===o&&[2,3].includes(s)?n.setValue(_[o]):n.updateValueAndValidity()})}ngOnInit(){this.ecpService.getInfo().subscribe(({plugins:_,names:o,directory:n,nodes:s})=>{this.initCrushNodeSelection(s,this.form.get("crushRoot"),this.form.get("crushFailureDomain"),this.form.get("crushDeviceClass")),this.plugins=_,this.names=o,this.form.silentSet("directory",n),this.preValidateNumericInputFields()})}preValidateNumericInputFields(){const _=["k","m","l","c","d"].map(o=>this.form.get(o));_.forEach(o=>{o.markAsTouched(),o.markAsDirty()}),_[1].updateValueAndValidity()}onSubmit(){if(this.form.invalid)return void this.form.setErrors({cdSubmitButton:!0});const _=this.createJson();this.taskWrapper.wrapTaskAroundCall({task:new I.R("ecp/create",{name:_.name}),call:this.ecpService.create(_)}).subscribe({error:()=>{this.form.setErrors({cdSubmitButton:!0})},complete:()=>{this.activeModal.close(),this.submitAction.emit(_)}})}createJson(){const _={technique:[this.PLUGIN.ISA,this.PLUGIN.JERASURE,this.PLUGIN.CLAY],packetSize:[this.PLUGIN.JERASURE],l:[this.PLUGIN.LRC],crushLocality:[this.PLUGIN.LRC],c:[this.PLUGIN.SHEC],d:[this.PLUGIN.CLAY],scalar_mds:[this.PLUGIN.CLAY]},o=new $_,n=this.form.getValue("plugin");return Object.keys(this.form.controls).filter(s=>{const c=_[s],d=this.form.getValue(s);return(c&&c.includes(n)||!c)&&d&&""!==d}).forEach(s=>{this.extendJson(s,o)}),o}extendJson(_,o){const s=this.form.getValue(_);o[{crushFailureDomain:"crush-failure-domain",crushRoot:"crush-root",crushDeviceClass:"crush-device-class",packetSize:"packetsize",crushLocality:"crush-locality"}[_]||_]="crushRoot"===_?s.name:s}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(be.O),e.Y36(E.Kz),e.Y36(de.P),e.Y36(Me),e.Y36(M.p4))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-erasure-code-profile-form-modal"]],outputs:{submitAction:"submitAction"},features:[e.qOj],decls:98,vars:53,consts:function(){let i,_,o,n,s,c,d,f,p,m,T,h,R,u,A,$,D,Z,x,y,U,q,H,G,z,X,w,Q,J,k,V,Y,B,j,K,N,W,ee,_e,oe,te,ie,ne,se,ae,le,re,ce,b;return i="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",_="Name",o="Plugin",n="Data chunks (k)",s="Coding chunks (m)",c="Crush failure domain",d="Crush root",f="Crush device class",p="Let Ceph decide",m="Available OSDs: " + "\ufffd0\ufffd" + "",T="Directory",h="This field is required!",R="The name can only consist of alphanumeric characters, dashes and underscores.",u="The chosen erasure code profile name is already in use.",A="Loading...",$="This field is required!",D="This field is required!",Z="Must be equal to or greater than 2.",x="Chunks (k+m) have exceeded the available OSDs of " + "\ufffd0\ufffd" + ".",y="For an equal distribution k has to be a multiple of (k+m)/l.",U="K has to be equal to or greater than m in order to recover data correctly through c.",q="Distribution factor: " + "\ufffd0\ufffd" + "",H="This field is required!",G="Must be equal to or greater than 1.",z="Chunks (k+m) have exceeded the available OSDs of " + "\ufffd0\ufffd" + ".",X="Durability estimator (c)",w="Must be equal to or greater than 1.",Q="C has to be equal to or lower than m as m defines the amount of chunks that can be used.",J="Helper chunks (d)",k="Set d manually or use the plugin's default calculation that maximizes d.",V="D is automatically updated on k and m changes",Y="D can be set from " + "\ufffd0\ufffd" + " to " + "\ufffd1\ufffd" + "",B="D can only be set to " + "\ufffd0\ufffd" + "",j="D has to be greater than k (" + "\ufffd0\ufffd" + ").",K="D has to be lower than k + m (" + "\ufffd0\ufffd" + ").",N="Locality (l)",W="Locality groups: " + "\ufffd0\ufffd" + "",ee="This field is required!",_e="Must be equal to or greater than 1.",oe="Can't split up chunks (k+m) correctly with the current locality.",te="Loading...",ie="Crush Locality",ne="Loading...",se="None",ae="Scalar mds",le="Technique",re="Packetsize",ce="Must be equal to or greater than 1.",b="Loading...",[[3,"modalRef"],[1,"modal-title"],i,[1,"modal-content"],["novalidate","",3,"formGroup"],["frm","ngForm"],[1,"modal-body"],[1,"form-group","row"],["for","name",1,"cd-col-form-label"],_,[1,"cd-col-form-input"],["type","text","id","name","name","name","placeholder","Name...","formControlName","name","autofocus","",1,"form-control"],["class","invalid-feedback",4,"ngIf"],["for","plugin",1,"cd-col-form-label"],[1,"required"],o,[3,"html"],["id","plugin","name","plugin","formControlName","plugin",1,"form-control"],["ngValue","",4,"ngIf"],[3,"ngValue",4,"ngFor","ngForOf"],["for","k",1,"cd-col-form-label"],n,["type","number","id","k","name","k","ng-model","$ctrl.erasureCodeProfile.k","placeholder","Data chunks...","formControlName","k","min","2",1,"form-control"],["class","form-text text-muted",4,"ngIf"],["for","m",1,"cd-col-form-label"],s,["type","number","id","m","name","m","placeholder","Coding chunks...","formControlName","m","min","1",1,"form-control"],["class","form-group row",4,"ngIf"],["for","crushFailureDomain",1,"cd-col-form-label"],c,["id","crushFailureDomain","name","crushFailureDomain","formControlName","crushFailureDomain",1,"form-control"],["for","crushRoot",1,"cd-col-form-label"],d,["id","crushRoot","name","crushRoot","formControlName","crushRoot",1,"form-control"],["for","crushDeviceClass",1,"cd-col-form-label"],f,["id","crushDeviceClass","name","crushDeviceClass","formControlName","crushDeviceClass",1,"form-control"],["ngValue",""],p,[1,"form-text","text-muted"],m,["for","directory",1,"cd-col-form-label"],T,["type","text","id","directory","name","directory","placeholder","Path...","formControlName","directory",1,"form-control"],[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],[1,"invalid-feedback"],h,R,u,A,[3,"ngValue"],$,D,Z,x,y,U,q,H,G,z,["for","c",1,"cd-col-form-label"],X,["type","number","id","c","name","c","placeholder","Coding chunks...","formControlName","c","min","1",1,"form-control"],w,Q,["for","d",1,"cd-col-form-label"],J,[1,"input-group"],["type","number","id","d","name","d","placeholder","Helper chunks...","formControlName","d",1,"form-control"],[1,"input-group-append"],["id","d-calc-btn","ngbTooltip",k,"type","button",1,"btn","btn-light",3,"click"],["aria-hidden","true",3,"ngClass"],[4,"ngIf"],V,Y,B,j,K,["for","l",1,"cd-col-form-label"],N,["type","number","id","l","name","l","placeholder","Coding chunks...","formControlName","l","min","1",1,"form-control"],W,ee,_e,oe,te,["for","crushLocality",1,"cd-col-form-label"],ie,["id","crushLocality","name","crushLocality","formControlName","crushLocality",1,"form-control"],ne,se,["for","scalar_mds",1,"cd-col-form-label"],ae,["id","scalar_mds","name","scalar_mds","formControlName","scalar_mds",1,"form-control"],["for","technique",1,"cd-col-form-label"],le,["id","technique","name","technique","formControlName","technique",1,"form-control"],["for","packetSize",1,"cd-col-form-label"],re,["type","number","id","packetSize","name","packetSize","placeholder","Packetsize...","formControlName","packetSize","min","1",1,"form-control"],ce,b]},template:function(_,o){if(1&_&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.ALo(3,"titlecase"),e.ALo(4,"upperFirst"),e.BQk(),e.ynx(5,3),e.TgZ(6,"form",4,5),e.TgZ(8,"div",6),e.TgZ(9,"div",7),e.TgZ(10,"label",8),e.SDv(11,9),e.qZA(),e.TgZ(12,"div",10),e._UZ(13,"input",11),e.YNc(14,Z_,2,0,"span",12),e.YNc(15,x_,2,0,"span",12),e.YNc(16,y_,2,0,"span",12),e.qZA(),e.qZA(),e.TgZ(17,"div",7),e.TgZ(18,"label",13),e.TgZ(19,"span",14),e.SDv(20,15),e.qZA(),e._UZ(21,"cd-helper",16),e.qZA(),e.TgZ(22,"div",10),e.TgZ(23,"select",17),e.YNc(24,U_,2,0,"option",18),e.YNc(25,q_,2,2,"option",19),e.qZA(),e.YNc(26,H_,2,0,"span",12),e.qZA(),e.qZA(),e.TgZ(27,"div",7),e.TgZ(28,"label",20),e.TgZ(29,"span",14),e.SDv(30,21),e.qZA(),e._UZ(31,"cd-helper",16),e.qZA(),e.TgZ(32,"div",10),e._UZ(33,"input",22),e.YNc(34,G_,2,0,"span",12),e.YNc(35,z_,2,0,"span",12),e.YNc(36,X_,2,1,"span",12),e.YNc(37,w_,2,0,"span",12),e.YNc(38,Q_,2,0,"span",12),e.YNc(39,J_,2,1,"span",23),e.qZA(),e.qZA(),e.TgZ(40,"div",7),e.TgZ(41,"label",24),e.TgZ(42,"span",14),e.SDv(43,25),e.qZA(),e._UZ(44,"cd-helper",16),e.qZA(),e.TgZ(45,"div",10),e._UZ(46,"input",26),e.YNc(47,k_,2,0,"span",12),e.YNc(48,V_,2,0,"span",12),e.YNc(49,Y_,2,1,"span",12),e.qZA(),e.qZA(),e.YNc(50,K_,9,3,"div",27),e.YNc(51,no,15,6,"div",27),e.YNc(52,ro,12,5,"div",27),e.TgZ(53,"div",7),e.TgZ(54,"label",28),e.ynx(55),e.SDv(56,29),e.BQk(),e._UZ(57,"cd-helper",16),e.qZA(),e.TgZ(58,"div",10),e.TgZ(59,"select",30),e.YNc(60,co,2,0,"option",18),e.YNc(61,Oo,2,3,"option",19),e.qZA(),e.qZA(),e.qZA(),e.YNc(62,Eo,10,4,"div",27),e.YNc(63,po,8,6,"div",27),e.YNc(64,Ro,8,2,"div",27),e.YNc(65,Mo,8,2,"div",27),e.TgZ(66,"div",7),e.TgZ(67,"label",31),e.ynx(68),e.SDv(69,32),e.BQk(),e._UZ(70,"cd-helper",16),e.qZA(),e.TgZ(71,"div",10),e.TgZ(72,"select",33),e.YNc(73,To,2,0,"option",18),e.YNc(74,ho,2,2,"option",19),e.qZA(),e.qZA(),e.qZA(),e.TgZ(75,"div",7),e.TgZ(76,"label",34),e.ynx(77),e.SDv(78,35),e.BQk(),e._UZ(79,"cd-helper",16),e.qZA(),e.TgZ(80,"div",10),e.TgZ(81,"select",36),e.TgZ(82,"option",37),e.SDv(83,38),e.qZA(),e.YNc(84,So,2,2,"option",19),e.qZA(),e.TgZ(85,"span",39),e.SDv(86,40),e.qZA(),e.qZA(),e.qZA(),e.TgZ(87,"div",7),e.TgZ(88,"label",41),e.ynx(89),e.SDv(90,42),e.BQk(),e._UZ(91,"cd-helper",16),e.qZA(),e.TgZ(92,"div",10),e._UZ(93,"input",43),e.qZA(),e.qZA(),e.qZA(),e.TgZ(94,"div",44),e.TgZ(95,"cd-form-button-panel",45),e.NdJ("submitActionEvent",function(){return o.onSubmit()}),e.ALo(96,"titlecase"),e.ALo(97,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&_){const n=e.MAs(7);e.Q6J("modalRef",o.activeModal),e.xp6(4),e.pQV(e.lcZ(3,41,o.action))(e.lcZ(4,43,o.resource)),e.QtT(2),e.xp6(2),e.Q6J("formGroup",o.form),e.xp6(8),e.Q6J("ngIf",o.form.showError("name",n,"required")),e.xp6(1),e.Q6J("ngIf",o.form.showError("name",n,"pattern")),e.xp6(1),e.Q6J("ngIf",o.form.showError("name",n,"uniqueName")),e.xp6(5),e.Q6J("html",o.tooltips.plugins[o.plugin].description),e.xp6(3),e.Q6J("ngIf",!o.plugins),e.xp6(1),e.Q6J("ngForOf",o.plugins),e.xp6(1),e.Q6J("ngIf",o.form.showError("name",n,"required")),e.xp6(5),e.Q6J("html",o.tooltips.k),e.xp6(3),e.Q6J("ngIf",o.form.showError("k",n,"required")),e.xp6(1),e.Q6J("ngIf",o.form.showError("k",n,"min")),e.xp6(1),e.Q6J("ngIf",o.form.showError("k",n,"max")),e.xp6(1),e.Q6J("ngIf",o.form.showError("k",n,"unequal")),e.xp6(1),e.Q6J("ngIf",o.form.showError("k",n,"kLowerM")),e.xp6(1),e.Q6J("ngIf","lrc"===o.plugin),e.xp6(5),e.Q6J("html",o.tooltips.m),e.xp6(3),e.Q6J("ngIf",o.form.showError("m",n,"required")),e.xp6(1),e.Q6J("ngIf",o.form.showError("m",n,"min")),e.xp6(1),e.Q6J("ngIf",o.form.showError("m",n,"max")),e.xp6(1),e.Q6J("ngIf","shec"===o.plugin),e.xp6(1),e.Q6J("ngIf","clay"===o.plugin),e.xp6(1),e.Q6J("ngIf",o.plugin===o.PLUGIN.LRC),e.xp6(5),e.Q6J("html",o.tooltips.crushFailureDomain),e.xp6(3),e.Q6J("ngIf",!o.failureDomains),e.xp6(1),e.Q6J("ngForOf",o.failureDomainKeys),e.xp6(1),e.Q6J("ngIf",o.plugin===o.PLUGIN.LRC),e.xp6(1),e.Q6J("ngIf",o.PLUGIN.CLAY===o.plugin),e.xp6(1),e.Q6J("ngIf",e.kEZ(49,$e,o.PLUGIN.JERASURE,o.PLUGIN.ISA,o.PLUGIN.CLAY).includes(o.plugin)),e.xp6(1),e.Q6J("ngIf",o.plugin===o.PLUGIN.JERASURE),e.xp6(5),e.Q6J("html",o.tooltips.crushRoot),e.xp6(3),e.Q6J("ngIf",!o.buckets),e.xp6(1),e.Q6J("ngForOf",o.buckets),e.xp6(5),e.Q6J("html",o.tooltips.crushDeviceClass),e.xp6(5),e.Q6J("ngForOf",o.devices),e.xp6(2),e.pQV(o.deviceCount),e.QtT(86),e.xp6(5),e.Q6J("html",o.tooltips.directory),e.xp6(4),e.Q6J("form",o.form)("submitText",e.lcZ(96,45,o.action)+" "+e.lcZ(97,47,o.resource))}},directives:[Ie.z,a._Y,a.JL,fe.V,a.sg,Pe.P,Ee.o,a.Fj,ge.b,a.JJ,a.u,pe.U,C.O5,me.S,a.EJ,C.sg,a.wV,a.qQ,a.YN,a.Kr,Re.p,E._L,C.mk],pipes:[C.rS,Ce.m],styles:[""]}),t})();var Ao=r(7022);class Fo{constructor(){this.erasureInfo=!1,this.crushInfo=!1,this.pgs=1,this.poolTypes=["erasure","replicated"],this.applications={selected:[],default:["cephfs","rbd","rgw"],available:[],validators:[a.kI.pattern("[A-Za-z0-9_]+"),a.kI.maxLength(128)],messages:new Ao.a({empty:"No applications added",selectionLimit:{text:"Applications limit reached",tooltip:"A pool can only have up to four applications definitions."},customValidations:{pattern:"Allowed characters '_a-zA-Z0-9'",maxlength:"Maximum length is 128 characters"},filter:"Filter or add applications'",add:"Add application"})}}}var De=r(63285),Ze=r(74937),No=r(63622),bo=r(60192),vo=r(17932),Io=r(54555),$o=r(30490),xe=r(61350);const Do=["crushInfoTabs"],Zo=["crushDeletionBtn"],xo=["ecpInfoTabs"],yo=["ecpDeletionBtn"];function Uo(t,i){1&t&&(e.TgZ(0,"span",40),e.SDv(1,41),e.qZA())}function qo(t,i){1&t&&(e.TgZ(0,"span",40),e.SDv(1,42),e.qZA())}function Ho(t,i){1&t&&(e.TgZ(0,"span",40),e.SDv(1,43),e.qZA())}function Go(t,i){1&t&&(e.TgZ(0,"span",40),e.SDv(1,44),e.qZA())}function zo(t,i){if(1&t&&(e.TgZ(0,"option",45),e._uU(1),e.qZA()),2&t){const _=i.$implicit;e.Q6J("value",_),e.xp6(1),e.hij(" ",_," ")}}function Xo(t,i){1&t&&(e.TgZ(0,"span",40),e.SDv(1,46),e.qZA())}function wo(t,i){if(1&t&&(e.TgZ(0,"option",45),e._uU(1),e.qZA()),2&t){const _=i.$implicit;e.Q6J("value",_),e.xp6(1),e.hij(" ",_," ")}}function Qo(t,i){1&t&&(e.TgZ(0,"span",40),e.SDv(1,57),e.qZA())}function Jo(t,i){1&t&&(e.TgZ(0,"span",40),e.SDv(1,58),e.qZA())}function ko(t,i){1&t&&(e.TgZ(0,"span",40),e.SDv(1,59),e.qZA())}function Vo(t,i){1&t&&(e.TgZ(0,"span",54),e.SDv(1,60),e.qZA())}function Yo(t,i){if(1&t){const _=e.EpF();e.TgZ(0,"div",8),e.TgZ(1,"label",51),e.SDv(2,52),e.qZA(),e.TgZ(3,"div",11),e.TgZ(4,"input",53),e.NdJ("focus",function(){return e.CHM(_),e.oxw(3).externalPgChange=!1})("blur",function(){return e.CHM(_),e.oxw(3).alignPgs()}),e.qZA(),e.YNc(5,Qo,2,0,"span",13),e.YNc(6,Jo,2,0,"span",13),e.YNc(7,ko,2,0,"span",13),e.TgZ(8,"span",54),e._UZ(9,"cd-doc",55),e.qZA(),e.YNc(10,Vo,2,0,"span",56),e.qZA(),e.qZA()}if(2&t){e.oxw(2);const _=e.MAs(2),o=e.oxw();e.xp6(5),e.Q6J("ngIf",o.form.showError("pgNum",_,"required")),e.xp6(1),e.Q6J("ngIf",o.form.showError("pgNum",_,"min")),e.xp6(1),e.Q6J("ngIf",o.form.showError("pgNum",_,"34")),e.xp6(3),e.Q6J("ngIf",o.externalPgChange)}}function Bo(t,i){if(1&t&&(e.TgZ(0,"span",40),e.TgZ(1,"ul",65),e.TgZ(2,"li"),e.SDv(3,66),e.qZA(),e.TgZ(4,"li"),e.SDv(5,67),e.qZA(),e.qZA(),e.qZA()),2&t){const _=e.oxw(4);e.xp6(3),e.pQV(_.getMinSize()),e.QtT(3),e.xp6(2),e.pQV(_.getMaxSize()),e.QtT(5)}}function jo(t,i){if(1&t&&(e.TgZ(0,"span",40),e.SDv(1,68),e.qZA()),2&t){const _=e.oxw(4);e.xp6(1),e.pQV(_.getMinSize())(_.getMaxSize()),e.QtT(1)}}function Ko(t,i){1&t&&(e.TgZ(0,"span",69),e.SDv(1,70),e.qZA())}function Wo(t,i){if(1&t&&(e.TgZ(0,"div",8),e.TgZ(1,"label",61),e.SDv(2,62),e.qZA(),e.TgZ(3,"div",11),e._UZ(4,"input",63),e.YNc(5,Bo,6,2,"span",13),e.YNc(6,jo,2,2,"span",13),e.YNc(7,Ko,2,0,"span",64),e.qZA(),e.qZA()),2&t){e.oxw(2);const _=e.MAs(2),o=e.oxw();e.xp6(4),e.Q6J("max",o.getMaxSize())("min",o.getMinSize()),e.xp6(1),e.Q6J("ngIf",o.form.showError("size",_)),e.xp6(1),e.Q6J("ngIf",o.form.showError("size",_)),e.xp6(1),e.Q6J("ngIf",1===o.form.getValue("size"))}}function et(t,i){1&t&&(e.TgZ(0,"div",8),e.TgZ(1,"label",71),e.SDv(2,72),e.qZA(),e.TgZ(3,"div",11),e.TgZ(4,"div",73),e._UZ(5,"input",74),e.TgZ(6,"label",75),e.SDv(7,76),e.qZA(),e.qZA(),e.qZA(),e.qZA())}function _t(t,i){if(1&t&&(e.TgZ(0,"div"),e.TgZ(1,"div",8),e.TgZ(2,"label",47),e.SDv(3,48),e.qZA(),e.TgZ(4,"div",11),e.TgZ(5,"select",49),e.YNc(6,wo,2,2,"option",19),e.qZA(),e.qZA(),e.qZA(),e.YNc(7,Yo,11,4,"div",50),e.YNc(8,Wo,8,5,"div",50),e.YNc(9,et,8,0,"div",50),e.qZA()),2&t){const _=e.oxw(2);e.xp6(6),e.Q6J("ngForOf",_.pgAutoscaleModes),e.xp6(1),e.Q6J("ngIf","on"!==_.form.getValue("pgAutoscaleMode")),e.xp6(1),e.Q6J("ngIf",_.isReplicated),e.xp6(1),e.Q6J("ngIf",_.info.is_all_bluestore&&_.isErasure)}}function ot(t,i){1&t&&(e.TgZ(0,"option",17),e.SDv(1,91),e.qZA())}function tt(t,i){1&t&&(e.TgZ(0,"option",92),e.SDv(1,93),e.qZA()),2&t&&e.Q6J("ngValue",null)}function it(t,i){1&t&&(e.TgZ(0,"option",92),e.SDv(1,94),e.qZA()),2&t&&e.Q6J("ngValue",null)}function nt(t,i){if(1&t&&(e.TgZ(0,"option",92),e._uU(1),e.qZA()),2&t){const _=i.$implicit;e.Q6J("ngValue",_),e.xp6(1),e.hij(" ",_.name," ")}}const F=function(t){return[t]};function st(t,i){if(1&t){const _=e.EpF();e.TgZ(0,"button",95),e.NdJ("click",function(){return e.CHM(_),e.oxw(4).addErasureCodeProfile()}),e._UZ(1,"i",87),e.qZA()}if(2&t){const _=e.oxw(4);e.xp6(1),e.Q6J("ngClass",e.VKq(1,F,_.icons.add))}}function at(t,i){if(1&t){const _=e.EpF();e.TgZ(0,"button",96,97),e.NdJ("click",function(){return e.CHM(_),e.oxw(4).deleteErasureCodeProfile()}),e._UZ(2,"i",87),e.qZA()}if(2&t){const _=e.oxw(4);e.xp6(2),e.Q6J("ngClass",e.VKq(1,F,_.icons.trash))}}const lt=function(){return["name"]};function rt(t,i){if(1&t&&e._UZ(0,"cd-table-key-value",108),2&t){const _=e.oxw(5);e.Q6J("renderObjects",!0)("hideKeys",e.DdM(4,lt))("data",_.form.getValue("erasureProfile"))("autoReload",!1)}}function ct(t,i){1&t&&(e.TgZ(0,"span"),e.SDv(1,111),e.qZA())}function Ot(t,i){if(1&t&&(e.TgZ(0,"li"),e._uU(1),e.qZA()),2&t){const _=i.$implicit;e.xp6(1),e.hij(" ",_," ")}}function dt(t,i){if(1&t&&(e.TgZ(0,"ul"),e.YNc(1,Ot,2,1,"li",112),e.qZA()),2&t){const _=e.oxw(6);e.xp6(1),e.Q6J("ngForOf",_.ecpUsage)}}function ut(t,i){if(1&t&&(e.YNc(0,ct,2,0,"ng-template",null,109,e.W1O),e.YNc(2,dt,2,1,"ul",110)),2&t){const _=e.MAs(1),o=e.oxw(5);e.xp6(2),e.Q6J("ngIf",o.ecpUsage)("ngIfElse",_)}}function ft(t,i){if(1&t&&(e.TgZ(0,"span",98),e.TgZ(1,"ul",99,100),e.TgZ(3,"li",101),e.TgZ(4,"a",102),e.SDv(5,103),e.qZA(),e.YNc(6,rt,1,5,"ng-template",104),e.qZA(),e.TgZ(7,"li",105),e.TgZ(8,"a",102),e.SDv(9,106),e.qZA(),e.YNc(10,ut,3,2,"ng-template",104),e.qZA(),e.qZA(),e._UZ(11,"div",107),e.qZA()),2&t){const _=e.MAs(2);e.xp6(11),e.Q6J("ngbNavOutlet",_)}}const ye=function(t){return{active:t}};function Pt(t,i){if(1&t){const _=e.EpF();e.TgZ(0,"div",8),e.TgZ(1,"label",78),e.SDv(2,79),e.qZA(),e.TgZ(3,"div",11),e.TgZ(4,"div",80),e.TgZ(5,"select",81),e.YNc(6,ot,2,0,"option",82),e.YNc(7,tt,2,1,"option",83),e.YNc(8,it,2,1,"option",83),e.YNc(9,nt,2,2,"option",84),e.qZA(),e.TgZ(10,"span",85),e.TgZ(11,"button",86),e.NdJ("click",function(){e.CHM(_);const n=e.oxw(3);return n.data.erasureInfo=!n.data.erasureInfo}),e._UZ(12,"i",87),e.qZA(),e.YNc(13,st,2,3,"button",88),e.YNc(14,at,3,3,"button",89),e.qZA(),e.qZA(),e.YNc(15,ft,12,1,"span",90),e.qZA(),e.qZA()}if(2&t){const _=e.oxw(3);e.xp6(6),e.Q6J("ngIf",!_.ecProfiles),e.xp6(1),e.Q6J("ngIf",_.ecProfiles&&0===_.ecProfiles.length),e.xp6(1),e.Q6J("ngIf",_.ecProfiles&&_.ecProfiles.length>0),e.xp6(1),e.Q6J("ngForOf",_.ecProfiles),e.xp6(2),e.Q6J("ngClass",e.VKq(9,ye,_.data.erasureInfo)),e.xp6(1),e.Q6J("ngClass",e.VKq(11,F,_.icons.questionCircle)),e.xp6(1),e.Q6J("ngIf",!_.editing),e.xp6(1),e.Q6J("ngIf",!_.editing),e.xp6(1),e.Q6J("ngIf",_.data.erasureInfo&&_.form.getValue("erasureProfile"))}}function Et(t,i){1&t&&(e.TgZ(0,"div",8),e.TgZ(1,"label",113),e.SDv(2,114),e.qZA(),e.TgZ(3,"div",11),e.TgZ(4,"span",54),e.SDv(5,115),e.qZA(),e.qZA(),e.qZA())}function gt(t,i){1&t&&(e.TgZ(0,"span",54),e.TgZ(1,"span"),e.SDv(2,118),e.qZA(),e._uU(3,"\xa0 "),e.qZA())}function pt(t,i){if(1&t&&(e.TgZ(0,"option",92),e._uU(1),e.qZA()),2&t){const _=i.$implicit;e.Q6J("ngValue",_),e.xp6(1),e.hij(" ",_.rule_name," ")}}function mt(t,i){if(1&t){const _=e.EpF();e.TgZ(0,"button",95),e.NdJ("click",function(){return e.CHM(_),e.oxw(5).addCrushRule()}),e._UZ(1,"i",87),e.qZA()}if(2&t){const _=e.oxw(5);e.xp6(1),e.Q6J("ngClass",e.VKq(1,F,_.icons.add))}}function Rt(t,i){if(1&t){const _=e.EpF();e.TgZ(0,"button",124,125),e.NdJ("click",function(){return e.CHM(_),e.oxw(5).deleteCrushRule()}),e._UZ(2,"i",87),e.qZA()}if(2&t){const _=e.oxw(5);e.xp6(2),e.Q6J("ngClass",e.VKq(1,F,_.icons.trash))}}const Ct=function(){return["steps","ruleset","type","rule_name"]};function Mt(t,i){if(1&t&&e._UZ(0,"cd-table-key-value",108),2&t){const _=e.oxw(6);e.Q6J("renderObjects",!1)("hideKeys",e.DdM(4,Ct))("data",_.form.getValue("crushRule"))("autoReload",!1)}}function Tt(t,i){if(1&t&&(e.TgZ(0,"li"),e._uU(1),e.qZA()),2&t){const _=i.$implicit,o=e.oxw(7);e.xp6(1),e.hij(" ",o.describeCrushStep(_)," ")}}function ht(t,i){if(1&t&&(e.TgZ(0,"ol"),e.YNc(1,Tt,2,1,"li",112),e.qZA()),2&t){const _=e.oxw(6);e.xp6(1),e.Q6J("ngForOf",_.form.get("crushRule").value.steps)}}function St(t,i){1&t&&(e.TgZ(0,"span"),e.SDv(1,134),e.qZA())}function Lt(t,i){if(1&t&&(e.TgZ(0,"li"),e._uU(1),e.qZA()),2&t){const _=i.$implicit;e.xp6(1),e.hij(" ",_," ")}}function At(t,i){if(1&t&&(e.TgZ(0,"ul"),e.YNc(1,Lt,2,1,"li",112),e.qZA()),2&t){const _=e.oxw(7);e.xp6(1),e.Q6J("ngForOf",_.crushUsage)}}function Ft(t,i){if(1&t&&(e.YNc(0,St,2,0,"ng-template",null,133,e.W1O),e.YNc(2,At,2,1,"ul",110)),2&t){const _=e.MAs(1),o=e.oxw(6);e.xp6(2),e.Q6J("ngIf",o.crushUsage)("ngIfElse",_)}}function Nt(t,i){if(1&t&&(e.TgZ(0,"div",126),e.TgZ(1,"ul",99,127),e.TgZ(3,"li",128),e.TgZ(4,"a",102),e.SDv(5,129),e.qZA(),e.YNc(6,Mt,1,5,"ng-template",104),e.qZA(),e.TgZ(7,"li",130),e.TgZ(8,"a",102),e.SDv(9,131),e.qZA(),e.YNc(10,ht,2,1,"ng-template",104),e.qZA(),e.TgZ(11,"li",105),e.TgZ(12,"a",102),e.SDv(13,132),e.qZA(),e.YNc(14,Ft,3,2,"ng-template",104),e.qZA(),e.qZA(),e._UZ(15,"div",107),e.qZA()),2&t){const _=e.MAs(2);e.xp6(15),e.Q6J("ngbNavOutlet",_)}}function bt(t,i){1&t&&(e.TgZ(0,"span",40),e.SDv(1,135),e.qZA())}function vt(t,i){1&t&&(e.TgZ(0,"span",40),e.SDv(1,136),e.qZA())}function It(t,i){if(1&t){const _=e.EpF();e.TgZ(0,"div"),e.TgZ(1,"div",80),e.TgZ(2,"select",119),e.TgZ(3,"option",92),e.SDv(4,120),e.qZA(),e.YNc(5,pt,2,2,"option",84),e.qZA(),e.TgZ(6,"span",85),e.TgZ(7,"button",121),e.NdJ("click",function(){e.CHM(_);const n=e.oxw(4);return n.data.crushInfo=!n.data.crushInfo}),e._UZ(8,"i",87),e.qZA(),e.YNc(9,mt,2,3,"button",88),e.YNc(10,Rt,3,3,"button",122),e.qZA(),e.qZA(),e.YNc(11,Nt,16,1,"div",123),e.YNc(12,bt,2,0,"span",13),e.YNc(13,vt,2,0,"span",13),e.qZA()}if(2&t){e.oxw(3);const _=e.MAs(2),o=e.oxw();e.xp6(3),e.Q6J("ngValue",null),e.xp6(2),e.Q6J("ngForOf",o.current.rules),e.xp6(2),e.Q6J("ngClass",e.VKq(9,ye,o.data.crushInfo)),e.xp6(1),e.Q6J("ngClass",e.VKq(11,F,o.icons.questionCircle)),e.xp6(1),e.Q6J("ngIf",o.isReplicated&&!o.editing),e.xp6(1),e.Q6J("ngIf",o.isReplicated&&!o.editing),e.xp6(1),e.Q6J("ngIf",o.data.crushInfo&&o.form.getValue("crushRule")),e.xp6(1),e.Q6J("ngIf",o.form.showError("crushRule",_,"required")),e.xp6(1),e.Q6J("ngIf",o.form.showError("crushRule",_,"tooFewOsds"))}}function $t(t,i){if(1&t&&(e.TgZ(0,"div",8),e.TgZ(1,"label",113),e.SDv(2,116),e.qZA(),e.TgZ(3,"div",11),e.YNc(4,gt,4,0,"ng-template",null,117,e.W1O),e.YNc(6,It,14,13,"div",110),e.qZA(),e.qZA()),2&t){const _=e.MAs(5),o=e.oxw(3);e.xp6(6),e.Q6J("ngIf",o.current.rules.length>0)("ngIfElse",_)}}function Dt(t,i){if(1&t&&(e.TgZ(0,"div"),e.TgZ(1,"legend"),e.SDv(2,77),e.qZA(),e.YNc(3,Pt,16,13,"div",50),e.YNc(4,Et,6,0,"div",50),e.YNc(5,$t,7,2,"div",50),e.qZA()),2&t){const _=e.oxw(2);e.xp6(3),e.Q6J("ngIf",_.isErasure),e.xp6(1),e.Q6J("ngIf",_.isErasure&&!_.editing),e.xp6(1),e.Q6J("ngIf",_.isReplicated||_.editing)}}function Zt(t,i){if(1&t&&(e.TgZ(0,"option",45),e._uU(1),e.qZA()),2&t){const _=i.$implicit;e.Q6J("value",_),e.xp6(1),e.hij(" ",_," ")}}function xt(t,i){1&t&&(e.TgZ(0,"option",17),e.SDv(1,154),e.qZA())}function yt(t,i){1&t&&(e.TgZ(0,"option",17),e.SDv(1,155),e.qZA())}function Ut(t,i){if(1&t&&(e.TgZ(0,"option",45),e._uU(1),e.qZA()),2&t){const _=i.$implicit;e.Q6J("value",_),e.xp6(1),e.hij(" ",_," ")}}function qt(t,i){1&t&&(e.TgZ(0,"span",40),e.SDv(1,156),e.qZA())}function Ht(t,i){1&t&&(e.TgZ(0,"span",40),e.SDv(1,157),e.qZA())}function Gt(t,i){1&t&&(e.TgZ(0,"span",40),e.SDv(1,158),e.qZA())}function zt(t,i){1&t&&(e.TgZ(0,"span",40),e.SDv(1,159),e.qZA())}function Xt(t,i){1&t&&(e.TgZ(0,"span",40),e.SDv(1,160),e.qZA())}function wt(t,i){if(1&t&&(e.TgZ(0,"div"),e.TgZ(1,"div",8),e.TgZ(2,"label",142),e.SDv(3,143),e.qZA(),e.TgZ(4,"div",11),e.TgZ(5,"select",144),e.YNc(6,xt,2,0,"option",82),e.YNc(7,yt,2,0,"option",82),e.YNc(8,Ut,2,2,"option",19),e.qZA(),e.qZA(),e.qZA(),e.TgZ(9,"div",8),e.TgZ(10,"label",145),e.SDv(11,146),e.qZA(),e.TgZ(12,"div",11),e._UZ(13,"input",147),e.YNc(14,qt,2,0,"span",13),e.YNc(15,Ht,2,0,"span",13),e.qZA(),e.qZA(),e.TgZ(16,"div",8),e.TgZ(17,"label",148),e.SDv(18,149),e.qZA(),e.TgZ(19,"div",11),e._UZ(20,"input",150),e.YNc(21,Gt,2,0,"span",13),e.YNc(22,zt,2,0,"span",13),e.qZA(),e.qZA(),e.TgZ(23,"div",8),e.TgZ(24,"label",151),e.SDv(25,152),e.qZA(),e.TgZ(26,"div",11),e._UZ(27,"input",153),e.YNc(28,Xt,2,0,"span",13),e.qZA(),e.qZA(),e.qZA()),2&t){e.oxw(2);const _=e.MAs(2),o=e.oxw();e.xp6(6),e.Q6J("ngIf",!o.info.compression_algorithms),e.xp6(1),e.Q6J("ngIf",o.info.compression_algorithms&&0===o.info.compression_algorithms.length),e.xp6(1),e.Q6J("ngForOf",o.info.compression_algorithms),e.xp6(6),e.Q6J("ngIf",o.form.showError("minBlobSize",_,"min")),e.xp6(1),e.Q6J("ngIf",o.form.showError("minBlobSize",_,"maximum")),e.xp6(6),e.Q6J("ngIf",o.form.showError("maxBlobSize",_,"min")),e.xp6(1),e.Q6J("ngIf",o.form.showError("maxBlobSize",_,"minimum")),e.xp6(6),e.Q6J("ngIf",o.form.showError("ratio",_,"min")||o.form.showError("ratio",_,"max"))}}function Qt(t,i){if(1&t&&(e.TgZ(0,"div",137),e.TgZ(1,"legend"),e.SDv(2,138),e.qZA(),e.TgZ(3,"div",8),e.TgZ(4,"label",139),e.SDv(5,140),e.qZA(),e.TgZ(6,"div",11),e.TgZ(7,"select",141),e.YNc(8,Zt,2,2,"option",19),e.qZA(),e.qZA(),e.qZA(),e.YNc(9,wt,29,8,"div",20),e.qZA()),2&t){const _=e.oxw(2);e.xp6(8),e.Q6J("ngForOf",_.info.compression_modes),e.xp6(1),e.Q6J("ngIf",_.hasCompressionEnabled())}}function Jt(t,i){1&t&&(e.TgZ(0,"span",40),e.SDv(1,161),e.qZA())}function kt(t,i){if(1&t){const _=e.EpF();e.TgZ(0,"div",1),e.TgZ(1,"form",2,3),e.TgZ(3,"div",4),e.TgZ(4,"div",5),e.SDv(5,6),e.ALo(6,"titlecase"),e.ALo(7,"upperFirst"),e.qZA(),e.TgZ(8,"div",7),e.TgZ(9,"div",8),e.TgZ(10,"label",9),e.SDv(11,10),e.qZA(),e.TgZ(12,"div",11),e._UZ(13,"input",12),e.YNc(14,Uo,2,0,"span",13),e.YNc(15,qo,2,0,"span",13),e.YNc(16,Ho,2,0,"span",13),e.YNc(17,Go,2,0,"span",13),e.qZA(),e.qZA(),e.TgZ(18,"div",8),e.TgZ(19,"label",14),e.SDv(20,15),e.qZA(),e.TgZ(21,"div",11),e.TgZ(22,"select",16),e.TgZ(23,"option",17),e.SDv(24,18),e.qZA(),e.YNc(25,zo,2,2,"option",19),e.qZA(),e.YNc(26,Xo,2,0,"span",13),e.qZA(),e.qZA(),e.YNc(27,_t,10,4,"div",20),e.TgZ(28,"div",8),e.TgZ(29,"label",21),e.SDv(30,22),e.qZA(),e.TgZ(31,"div",11),e.TgZ(32,"cd-select-badges",23),e.NdJ("selection",function(){return e.CHM(_),e.oxw().appSelection()}),e.qZA(),e.qZA(),e.qZA(),e.YNc(33,Dt,6,3,"div",20),e.YNc(34,Qt,10,2,"div",24),e.TgZ(35,"div"),e.TgZ(36,"legend"),e.SDv(37,25),e.qZA(),e.TgZ(38,"div",8),e.TgZ(39,"label",26),e.ynx(40),e.SDv(41,27),e.BQk(),e.TgZ(42,"cd-helper"),e.TgZ(43,"span"),e.SDv(44,28),e.qZA(),e._UZ(45,"br"),e.TgZ(46,"span"),e.SDv(47,29),e.qZA(),e.qZA(),e.qZA(),e.TgZ(48,"div",11),e._UZ(49,"input",30),e.qZA(),e.qZA(),e.TgZ(50,"div",8),e.TgZ(51,"label",31),e.ynx(52),e.SDv(53,32),e.BQk(),e.TgZ(54,"cd-helper"),e.TgZ(55,"span"),e.SDv(56,33),e.qZA(),e._UZ(57,"br"),e.TgZ(58,"span"),e.SDv(59,34),e.qZA(),e.qZA(),e.qZA(),e.TgZ(60,"div",11),e._UZ(61,"input",35),e.YNc(62,Jt,2,0,"span",13),e.qZA(),e.qZA(),e.qZA(),e.TgZ(63,"div",36),e.TgZ(64,"cd-rbd-configuration-form",37),e.NdJ("changes",function(n){return e.CHM(_),e.oxw().currentConfigurationValues=n()}),e.qZA(),e.qZA(),e.qZA(),e.TgZ(65,"div",38),e.TgZ(66,"cd-form-button-panel",39),e.NdJ("submitActionEvent",function(){return e.CHM(_),e.oxw().submit()}),e.ALo(67,"titlecase"),e.ALo(68,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&t){const _=e.MAs(2),o=e.oxw();e.xp6(1),e.Q6J("formGroup",o.form),e.xp6(6),e.pQV(e.lcZ(6,24,o.action))(e.lcZ(7,26,o.resource)),e.QtT(5),e.xp6(7),e.Q6J("ngIf",o.form.showError("name",_,"required")),e.xp6(1),e.Q6J("ngIf",o.form.showError("name",_,"uniqueName")),e.xp6(1),e.Q6J("ngIf",o.form.showError("name",_,"rbdPool")),e.xp6(1),e.Q6J("ngIf",o.form.showError("name",_,"pattern")),e.xp6(8),e.Q6J("ngForOf",o.data.poolTypes),e.xp6(1),e.Q6J("ngIf",o.form.showError("poolType",_,"required")),e.xp6(1),e.Q6J("ngIf",o.isReplicated||o.isErasure),e.xp6(5),e.Q6J("customBadges",!0)("customBadgeValidators",o.data.applications.validators)("messages",o.data.applications.messages)("data",o.data.applications.selected)("options",o.data.applications.available)("selectionLimit",4),e.xp6(1),e.Q6J("ngIf",o.isErasure||o.isReplicated),e.xp6(1),e.Q6J("ngIf",o.info.is_all_bluestore),e.xp6(28),e.Q6J("ngIf",o.form.showError("max_objects",_,"min")),e.xp6(1),e.Q6J("hidden",o.isErasure||-1===o.data.applications.selected.indexOf("rbd")),e.xp6(1),e.Q6J("form",o.form)("initializeData",o.initializeConfigData),e.xp6(2),e.Q6J("form",o.form)("submitText",e.lcZ(67,28,o.action)+" "+e.lcZ(68,30,o.resource))}}let Ue=(()=>{class t extends p_.E{constructor(_,o,n,s,c,d,f,p,m,T,h){super(),this.dimlessBinaryPipe=_,this.route=o,this.router=n,this.modalService=s,this.poolService=c,this.authStorageService=d,this.formatter=f,this.taskWrapper=p,this.ecpService=m,this.crushRuleService=T,this.actionLabels=h,this.editing=!1,this.isReplicated=!1,this.isErasure=!1,this.data=new Fo,this.externalPgChange=!1,this.current={rules:[]},this.initializeConfigData=new P_.t(1),this.currentConfigurationValues={},this.icons=v.P,this.crushUsage=void 0,this.ecpUsage=void 0,this.editing=this.router.url.startsWith(`/pool/${M.MQ.EDIT}`),this.action=this.editing?this.actionLabels.EDIT:this.actionLabels.CREATE,this.resource="pool",this.authenticate(),this.createForm()}authenticate(){if(this.permission=this.authStorageService.getPermissions().pool,!this.permission.read||!this.permission.update&&this.editing||!this.permission.create&&!this.editing)throw new E_._2}createForm(){const _=new Ne.d({mode:new a.NI("none"),algorithm:new a.NI(""),minBlobSize:new a.NI("",{updateOn:"blur"}),maxBlobSize:new a.NI("",{updateOn:"blur"}),ratio:new a.NI("",{updateOn:"blur"})});this.form=new Ne.d({name:new a.NI("",{validators:[a.kI.pattern(/^[.A-Za-z0-9_/-]+$/),a.kI.required,P.h.custom("rbdPool",()=>this.form&&this.form.getValue("name").includes("/")&&this.data&&-1!==this.data.applications.selected.indexOf("rbd"))]}),poolType:new a.NI("",{validators:[a.kI.required]}),crushRule:new a.NI(null,{validators:[P.h.custom("tooFewOsds",o=>this.info&&o&&this.info.osd_count<o.min_size),P.h.custom("required",o=>this.isReplicated&&this.info.crush_rules_replicated.length>0&&!o)]}),size:new a.NI("",{updateOn:"blur"}),erasureProfile:new a.NI(null),pgNum:new a.NI("",{validators:[a.kI.required]}),pgAutoscaleMode:new a.NI(null),ecOverwrites:new a.NI(!1),compression:_,max_bytes:new a.NI(""),max_objects:new a.NI(0)},[P.h.custom("form",()=>null)])}ngOnInit(){this.poolService.getInfo().subscribe(_=>{this.initInfo(_),this.editing?this.initEditMode():(this.setAvailableApps(),this.loadingReady()),this.listenToChanges(),this.setComplexValidators()})}initInfo(_){this.pgAutoscaleModes=_.pg_autoscale_modes,this.form.silentSet("pgAutoscaleMode",_.pg_autoscale_default_mode),this.form.silentSet("algorithm",_.bluestore_compression_algorithm),this.info=_,this.initEcp(_.erasure_code_profiles)}initEcp(_){this.setListControlStatus("erasureProfile",_),this.ecProfiles=_}setListControlStatus(_,o){const n=this.form.get(_),s=n.value;1!==o.length||s&&g().isEqual(s,o[0])?0===o.length&&s&&n.setValue(null):n.setValue(o[0]),o.length<=1?n.enabled&&n.disable():n.disabled&&n.enable()}initEditMode(){this.disableForEdit(),this.routeParamsSubscribe=this.route.params.subscribe(_=>this.poolService.get(_.name).subscribe(o=>{this.data.pool=o,this.initEditFormData(o),this.loadingReady()}))}disableForEdit(){["poolType","crushRule","size","erasureProfile","ecOverwrites"].forEach(_=>this.form.get(_).disable())}initEditFormData(_){this.initializeConfigData.next({initialData:_.configuration,sourceType:m_.h.pool}),this.poolTypeChange(_.type);const o=this.info.crush_rules_replicated.concat(this.info.crush_rules_erasure),n={name:_.pool_name,poolType:_.type,crushRule:o.find(s=>s.rule_name===_.crush_rule),size:_.size,erasureProfile:this.ecProfiles.find(s=>s.name===_.erasure_code_profile),pgAutoscaleMode:_.pg_autoscale_mode,pgNum:_.pg_num,ecOverwrites:_.flags_names.includes("ec_overwrites"),mode:_.options.compression_mode,algorithm:_.options.compression_algorithm,minBlobSize:this.dimlessBinaryPipe.transform(_.options.compression_min_blob_size),maxBlobSize:this.dimlessBinaryPipe.transform(_.options.compression_max_blob_size),ratio:_.options.compression_required_ratio,max_bytes:this.dimlessBinaryPipe.transform(_.quota_max_bytes),max_objects:_.quota_max_objects};Object.keys(n).forEach(s=>{const c=n[s];!g().isUndefined(c)&&""!==c&&this.form.silentSet(s,c)}),this.data.pgs=this.form.getValue("pgNum"),this.setAvailableApps(this.data.applications.default.concat(_.application_metadata)),this.data.applications.selected=_.application_metadata}setAvailableApps(_=this.data.applications.default){this.data.applications.available=g().uniq(_.sort()).map(o=>new g_.$(!1,o,""))}listenToChanges(){this.listenToChangesDuringAddEdit(),this.editing||this.listenToChangesDuringAdd()}listenToChangesDuringAddEdit(){this.form.get("pgNum").valueChanges.subscribe(_=>{const o=_-this.data.pgs;1===Math.abs(o)&&2!==_?this.doPgPowerJump(o):this.data.pgs=_})}doPgPowerJump(_){const o=this.calculatePgPower()+_;this.setPgs(-1===_?Math.round(o):Math.floor(o))}calculatePgPower(_=this.form.getValue("pgNum")){return Math.log(_)/Math.log(2)}setPgs(_){const o=Math.pow(2,_<0?0:_);this.data.pgs=o,this.form.silentSet("pgNum",o)}listenToChangesDuringAdd(){this.form.get("poolType").valueChanges.subscribe(_=>{this.poolTypeChange(_)}),this.form.get("crushRule").valueChanges.subscribe(_=>{this.crushDeletionBtn&&this.crushDeletionBtn.isOpen()&&this.crushDeletionBtn.close(),_&&(this.setCorrectMaxSize(_),this.crushRuleIsUsedBy(_.rule_name),this.replicatedRuleChange(),this.pgCalc())}),this.form.get("size").valueChanges.subscribe(()=>{this.pgCalc()}),this.form.get("erasureProfile").valueChanges.subscribe(_=>{this.ecpDeletionBtn&&this.ecpDeletionBtn.isOpen()&&this.ecpDeletionBtn.close(),_&&(this.ecpIsUsedBy(_.name),this.pgCalc())}),this.form.get("mode").valueChanges.subscribe(()=>{["minBlobSize","maxBlobSize","ratio"].forEach(_=>{this.form.get(_).updateValueAndValidity({emitEvent:!1})})}),this.form.get("minBlobSize").valueChanges.subscribe(()=>{this.form.get("maxBlobSize").updateValueAndValidity({emitEvent:!1})}),this.form.get("maxBlobSize").valueChanges.subscribe(()=>{this.form.get("minBlobSize").updateValueAndValidity({emitEvent:!1})})}poolTypeChange(_){if("replicated"===_?this.setTypeBooleans(!0,!1):this.setTypeBooleans(!1,"erasure"===_),!_||!this.info)return void(this.current.rules=[]);const o=this.info["crush_rules_"+_]||[];this.current.rules=o,!this.editing&&(this.isReplicated&&this.setListControlStatus("crushRule",o),this.replicatedRuleChange(),this.pgCalc())}setTypeBooleans(_,o){this.isReplicated=_,this.isErasure=o}replicatedRuleChange(){if(!this.isReplicated)return;const _=this.form.get("size");let o=this.form.getValue("size")||3;const n=this.getMinSize(),s=this.getMaxSize();o<n?o=n:o>s&&(o=s),o!==_.value&&this.form.silentSet("size",o)}getMinSize(){if(!this.info||this.info.osd_count<1)return 0;const _=this.form.getValue("crushRule");return _?_.min_size:1}getMaxSize(){const _=this.form.getValue("crushRule");return this.info?_?_.usable_size:Math.min(this.info.osd_count,3):0}pgCalc(){const _=this.form.getValue("poolType");if(!this.info||this.form.get("pgNum").dirty||!_)return;const o=100*this.info.osd_count,n=this.isReplicated?this.replicatedPgCalc(o):this.erasurePgCalc(o);if(!n)return;const s=this.data.pgs;this.alignPgs(n),this.externalPgChange||(this.externalPgChange=s!==this.data.pgs)}setCorrectMaxSize(_=this.form.getValue("crushRule")){if(!_)return;const n=S.searchFailureDomains(this.info.nodes,_.steps[0].item_name)[_.steps[1].type];_.usable_size=Math.min(n?n.length:_.max_size,_.max_size)}replicatedPgCalc(_){const o=this.form.get("size"),n=o.value;return o.valid&&n>0?_/n:0}erasurePgCalc(_){const o=this.form.get("erasureProfile"),n=o.value;return(o.valid||o.disabled)&&n?_/(n.k+n.m):0}alignPgs(_=this.form.getValue("pgNum")){this.setPgs(Math.round(this.calculatePgPower(_<1?1:_)))}setComplexValidators(){this.editing?this.form.get("name").setValidators([this.form.get("name").validator,P.h.custom("uniqueName",_=>this.data.pool&&this.info&&-1!==this.info.pool_names.indexOf(_)&&this.info.pool_names.indexOf(_)!==this.info.pool_names.indexOf(this.data.pool.pool_name))]):(P.h.validateIf(this.form.get("size"),()=>this.isReplicated,[P.h.custom("min",_=>this.form.getValue("size")&&_<this.getMinSize()),P.h.custom("max",_=>this.form.getValue("size")&&this.getMaxSize()<_)]),this.form.get("name").setValidators([this.form.get("name").validator,P.h.custom("uniqueName",_=>this.info&&-1!==this.info.pool_names.indexOf(_))])),this.setCompressionValidators()}setCompressionValidators(){P.h.validateIf(this.form.get("minBlobSize"),()=>this.hasCompressionEnabled(),[a.kI.min(0),P.h.custom("maximum",_=>this.oddBlobSize(_,this.form.getValue("maxBlobSize")))]),P.h.validateIf(this.form.get("maxBlobSize"),()=>this.hasCompressionEnabled(),[a.kI.min(0),P.h.custom("minimum",_=>this.oddBlobSize(this.form.getValue("minBlobSize"),_))]),P.h.validateIf(this.form.get("ratio"),()=>this.hasCompressionEnabled(),[a.kI.min(0),a.kI.max(1)])}oddBlobSize(_,o){const n=this.formatter.toBytes(_),s=this.formatter.toBytes(o);return Boolean(n&&s&&n>=s)}hasCompressionEnabled(){return this.form.getValue("mode")&&"none"!==this.form.get("mode").value.toLowerCase()}describeCrushStep(_){return[_.op.replace("_"," "),_.item_name||"",_.type?_.num+" type "+_.type:""].join(" ")}addErasureCodeProfile(){this.addModal(Lo,_=>this.reloadECPs(_))}addModal(_,o){this.hideOpenTooltips(),this.modalService.show(_).componentInstance.submitAction.subscribe(s=>{o(s.name)})}hideOpenTooltips(){const _=o=>o&&o.isOpen()&&o.close();_(this.ecpDeletionBtn),_(this.crushDeletionBtn)}reloadECPs(_){this.reloadList({newItemName:_,getInfo:()=>this.ecpService.list(),initInfo:o=>this.initEcp(o),findNewItem:()=>this.ecProfiles.find(o=>o.name===_),controlName:"erasureProfile"})}reloadList({newItemName:_,getInfo:o,initInfo:n,findNewItem:s,controlName:c}){this.modalSubscription&&this.modalSubscription.unsubscribe(),o().subscribe(d=>{if(n(d),!_)return;const f=s();f&&this.form.get(c).setValue(f)})}deleteErasureCodeProfile(){this.deletionModal({value:this.form.getValue("erasureProfile"),usage:this.ecpUsage,deletionBtn:this.ecpDeletionBtn,dataName:"erasureInfo",getTabs:()=>this.ecpInfoTabs,tabPosition:"used-by-pools",nameAttribute:"name",itemDescription:"erasure code profile",reloadFn:()=>this.reloadECPs(),deleteFn:_=>this.ecpService.delete(_),taskName:"ecp/delete"})}deletionModal({value:_,usage:o,deletionBtn:n,dataName:s,getTabs:c,tabPosition:d,nameAttribute:f,itemDescription:p,reloadFn:m,deleteFn:T,taskName:h}){if(!_)return;if(o)return n.animation=!1,n.toggle(),this.data[s]=!0,void setTimeout(()=>{const u=c();u&&u.select(d)},50);const R=_[f];this.modalService.show(Fe.M,{itemDescription:p,itemNames:[R],submitActionObservable:()=>{const u=T(R);return u.subscribe(()=>m()),this.taskWrapper.wrapTaskAroundCall({task:new I.R(h,{name:R}),call:u})}})}addCrushRule(){this.addModal(I_,_=>this.reloadCrushRules(_))}reloadCrushRules(_){this.reloadList({newItemName:_,getInfo:()=>this.poolService.getInfo(),initInfo:o=>{this.initInfo(o),this.poolTypeChange("replicated")},findNewItem:()=>this.info.crush_rules_replicated.find(o=>o.rule_name===_),controlName:"crushRule"})}deleteCrushRule(){this.deletionModal({value:this.form.getValue("crushRule"),usage:this.crushUsage,deletionBtn:this.crushDeletionBtn,dataName:"crushInfo",getTabs:()=>this.crushInfoTabs,tabPosition:"used-by-pools",nameAttribute:"rule_name",itemDescription:"crush rule",reloadFn:()=>this.reloadCrushRules(),deleteFn:_=>this.crushRuleService.delete(_),taskName:"crushRule/delete"})}crushRuleIsUsedBy(_){this.crushUsage=_?this.info.used_rules[_]:void 0}ecpIsUsedBy(_){this.ecpUsage=_?this.info.used_profiles[_]:void 0}submit(){if(this.form.invalid)return void this.form.setErrors({cdSubmitButton:!0});const _={pool:this.form.getValue("name")};this.assignFormFields(_,[{externalFieldName:"pool_type",formControlName:"poolType"},{externalFieldName:"pg_autoscale_mode",formControlName:"pgAutoscaleMode",editable:!0},{externalFieldName:"pg_num",formControlName:"pgNum",replaceFn:n=>"on"===this.form.getValue("pgAutoscaleMode")?1:n,editable:!0},this.isReplicated?{externalFieldName:"size",formControlName:"size"}:{externalFieldName:"erasure_code_profile",formControlName:"erasureProfile",attr:"name"},{externalFieldName:"rule_name",formControlName:"crushRule",replaceFn:n=>this.isReplicated?n&&n.rule_name:void 0},{externalFieldName:"quota_max_bytes",formControlName:"max_bytes",replaceFn:this.formatter.toBytes,editable:!0,resetValue:this.editing?0:void 0},{externalFieldName:"quota_max_objects",formControlName:"max_objects",editable:!0,resetValue:this.editing?0:void 0}]),this.info.is_all_bluestore&&(this.assignFormField(_,{externalFieldName:"flags",formControlName:"ecOverwrites",replaceFn:()=>this.isErasure?["ec_overwrites"]:void 0}),"none"!==this.form.getValue("mode")?this.assignFormFields(_,[{externalFieldName:"compression_mode",formControlName:"mode",editable:!0,replaceFn:n=>this.hasCompressionEnabled()&&n},{externalFieldName:"compression_algorithm",formControlName:"algorithm",editable:!0},{externalFieldName:"compression_min_blob_size",formControlName:"minBlobSize",replaceFn:this.formatter.toBytes,editable:!0,resetValue:0},{externalFieldName:"compression_max_blob_size",formControlName:"maxBlobSize",replaceFn:this.formatter.toBytes,editable:!0,resetValue:0},{externalFieldName:"compression_required_ratio",formControlName:"ratio",editable:!0,resetValue:0}]):this.editing&&this.assignFormFields(_,[{externalFieldName:"compression_mode",formControlName:"mode",editable:!0,replaceFn:()=>"unset"},{externalFieldName:"srcpool",formControlName:"name",editable:!0,replaceFn:()=>this.data.pool.pool_name}]));const o=this.data.applications.selected;(o.length>0||this.editing)&&(_.application_metadata=o),this.isReplicated&&!g().isEmpty(this.currentConfigurationValues)&&(_.configuration=this.currentConfigurationValues),this.triggerApiTask(_)}assignFormFields(_,o){o.forEach(n=>this.assignFormField(_,n))}assignFormField(_,{externalFieldName:o,formControlName:n,attr:s,replaceFn:c,editable:d,resetValue:f}){if(this.editing&&(!d||this.form.get(n).pristine))return;const p=this.form.getValue(n);let m=c?c(p):s?g().get(p,s):p;if(!p||!m){if(!d||g().isUndefined(f))return;m=f}_[o]=m}triggerApiTask(_){this.taskWrapper.wrapTaskAroundCall({task:new I.R("pool/"+(this.editing?M.MQ.EDIT:M.MQ.CREATE),{pool_name:_.hasOwnProperty("srcpool")?_.srcpool:_.pool}),call:this.poolService[this.editing?M.MQ.UPDATE:M.MQ.CREATE](_)}).subscribe({error:o=>{g().isObject(o.error)&&"34"===o.error.code&&this.form.get("pgNum").setErrors({34:!0}),this.form.setErrors({cdSubmitButton:!0})},complete:()=>this.router.navigate(["/pool"])})}appSelection(){this.form.get("name").updateValueAndValidity({emitEvent:!1,onlySelf:!0})}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(R_.$),e.Y36(Oe.gz),e.Y36(Oe.F0),e.Y36(De.Z),e.Y36(ue.q),e.Y36(Ze.j),e.Y36(C_.H),e.Y36(de.P),e.Y36(Me),e.Y36(ve.H),e.Y36(M.p4))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-pool-form"]],viewQuery:function(_,o){if(1&_&&(e.Gf(Do,5),e.Gf(Zo,5),e.Gf(xo,5),e.Gf(yo,5)),2&_){let n;e.iGM(n=e.CRH())&&(o.crushInfoTabs=n.first),e.iGM(n=e.CRH())&&(o.crushDeletionBtn=n.first),e.iGM(n=e.CRH())&&(o.ecpInfoTabs=n.first),e.iGM(n=e.CRH())&&(o.ecpDeletionBtn=n.first)}},features:[e.qOj],decls:1,vars:1,consts:function(){let i,_,o,n,s,c,d,f,p,m,T,h,R,u,A,$,D,Z,x,y,U,q,H,G,z,X,w,Q,J,k,V,Y,B,j,K,N,W,ee,_e,oe,te,ie,ne,se,ae,le,re,ce,b,O,Xe,we,Qe,Je,ke,Ve,Ye,Be,je,Ke,We,e_,__,o_,t_,i_,n_,s_,a_,l_,r_,c_;return i="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",_="Name",o="Name...",n="Pool type",s="-- Select a pool type --",c="Applications",d="Quotas",f="Max bytes",p="Leave it blank or specify 0 to disable this quota.",m="A valid quota should be greater than 0.",T="e.g., 10GiB",h="Max objects",R="Leave it blank or specify 0 to disable this quota.",u="A valid quota should be greater than 0.",A="This field is required!",$="The chosen Ceph pool name is already in use.",D="It's not possible to create an RBD pool with '/' in the name. Please change the name or remove 'rbd' from the applications list.",Z="Pool name can only contain letters, numbers, '.', '-', '_' or '/'.",x="This field is required!",y="PG Autoscale",U="Placement groups",q="Calculation help",H="This field is required!",G="At least one placement group is needed!",z="Your cluster can't handle this many PGs. Please recalculate the PG amount needed.",X="The current PGs settings were calculated for you, you should make sure the values suit your needs before submit.",w="Replicated size",Q="Minimum: " + "\ufffd0\ufffd" + "",J="Maximum: " + "\ufffd0\ufffd" + "",k="The size specified is out of range. A value from " + "\ufffd0\ufffd" + " to " + "\ufffd1\ufffd" + " is usable.",V="A size of 1 will not create a replication of the object. The 'Replicated size' includes the object itself.",Y="Flags",B="EC Overwrites",j="CRUSH",K="Erasure code profile",N="This profile can't be deleted as it is in use.",W="Loading...",ee="-- No erasure code profile available --",_e="-- Select an erasure code profile --",oe="Profile",te="Used by pools",ie="Profile is not in use.",ne="Crush ruleset",se="A new crush ruleset will be implicitly created.",ae="Crush ruleset",le="There are no rules.",re="-- Select a crush rule --",ce="Placement and\n replication strategies or distribution policies that allow to\n specify how CRUSH places data replicas.",b="This rule can't be deleted as it is in use.",O="Crush rule",Xe="Crush steps",we="Used by pools",Qe="Rule is not in use.",Je="This field is required!",ke="The rule can't be used in the current cluster as it has too few OSDs to meet the minimum required OSD by this rule.",Ve="Compression",Ye="Mode",Be="Algorithm",je="Minimum blob size",Ke="e.g., 128KiB",We="Maximum blob size",e_="e.g., 512KiB",__="Ratio",o_="Compression ratio",t_="Loading...",i_="-- No erasure compression algorithm available --",n_="Value should be greater than 0",s_="Value should be less than the maximum blob size",a_="Value should be greater than 0",l_="Value should be greater than the minimum blob size",r_="Value should be between 0.0 and 1.0",c_="The value should be greater or equal to 0",[["class","cd-col-form",4,"cdFormLoading"],[1,"cd-col-form"],["name","form","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"card"],[1,"card-header"],i,[1,"card-body"],[1,"form-group","row"],["for","name",1,"cd-col-form-label","required"],_,[1,"cd-col-form-input"],["id","name","name","name","type","text","placeholder",o,"formControlName","name","autofocus","",1,"form-control"],["class","invalid-feedback",4,"ngIf"],["for","poolType",1,"cd-col-form-label","required"],n,["id","poolType","formControlName","poolType","name","poolType",1,"form-control"],["ngValue",""],s,[3,"value",4,"ngFor","ngForOf"],[4,"ngIf"],["for","applications",1,"cd-col-form-label"],c,["id","applications",3,"customBadges","customBadgeValidators","messages","data","options","selectionLimit","selection"],["formGroupName","compression",4,"ngIf"],d,["for","max_bytes",1,"cd-col-form-label"],f,p,m,["id","max_bytes","name","max_bytes","type","text","formControlName","max_bytes","placeholder",T,"defaultUnit","GiB","cdDimlessBinary","",1,"form-control"],["for","max_objects",1,"cd-col-form-label"],h,R,u,["id","max_objects","min","0","name","max_objects","type","number","formControlName","max_objects",1,"form-control"],[3,"hidden"],[3,"form","initializeData","changes"],[1,"card-footer"],["wrappingClass","text-right",3,"form","submitText","submitActionEvent"],[1,"invalid-feedback"],A,$,D,Z,[3,"value"],x,["for","pgAutoscaleMode",1,"cd-col-form-label"],y,["id","pgAutoscaleMode","name","pgAutoscaleMode","formControlName","pgAutoscaleMode",1,"form-control"],["class","form-group row",4,"ngIf"],["for","pgNum",1,"cd-col-form-label","required"],U,["id","pgNum","name","pgNum","formControlName","pgNum","min","1","type","number","required","",1,"form-control",3,"focus","blur"],[1,"form-text","text-muted"],["section","pgs","docText",q],["class","form-text text-muted",4,"ngIf"],H,G,z,X,["for","size",1,"cd-col-form-label","required"],w,["id","size","name","size","type","number","formControlName","size",1,"form-control",3,"max","min"],["class","text-warning-dark",4,"ngIf"],[1,"list-inline"],Q,J,k,[1,"text-warning-dark"],V,[1,"cd-col-form-label"],Y,[1,"custom-control","custom-checkbox"],["type","checkbox","id","ec-overwrites","formControlName","ecOverwrites",1,"custom-control-input"],["for","ec-overwrites",1,"custom-control-label"],B,j,["for","erasureProfile",1,"cd-col-form-label"],K,[1,"input-group"],["id","erasureProfile","name","erasureProfile","formControlName","erasureProfile",1,"form-control"],["ngValue","",4,"ngIf"],[3,"ngValue",4,"ngIf"],[3,"ngValue",4,"ngFor","ngForOf"],[1,"input-group-append"],["id","ecp-info-button","type","button",1,"btn","btn-light",3,"ngClass","click"],["aria-hidden","true",3,"ngClass"],["class","btn btn-light","type","button",3,"click",4,"ngIf"],["class","btn btn-light","type","button","ngbTooltip",N,"triggers","manual",3,"click",4,"ngIf"],["class","form-text text-muted","id","ecp-info-block",4,"ngIf"],W,[3,"ngValue"],ee,_e,["type","button",1,"btn","btn-light",3,"click"],["type","button","ngbTooltip",N,"triggers","manual",1,"btn","btn-light",3,"click"],["ecpDeletionBtn","ngbTooltip"],["id","ecp-info-block",1,"form-text","text-muted"],["ngbNav","",1,"nav-tabs"],["ecpInfoTabs","ngbNav"],["ngbNavItem","ecp-info"],["ngbNavLink",""],oe,["ngbNavContent",""],["ngbNavItem","used-by-pools"],te,[3,"ngbNavOutlet"],[3,"renderObjects","hideKeys","data","autoReload"],["ecpIsNotUsed",""],[4,"ngIf","ngIfElse"],ie,[4,"ngFor","ngForOf"],["for","crushRule",1,"cd-col-form-label"],ne,se,ae,["noRules",""],le,["id","crushRule","formControlName","crushRule","name","crushSet",1,"form-control"],re,["id","crush-info-button","type","button","ngbTooltip",ce,1,"btn","btn-light",3,"ngClass","click"],["class","btn btn-light","type","button","ngbTooltip",b,"triggers","manual",3,"click",4,"ngIf"],["class","form-text text-muted","id","crush-info-block",4,"ngIf"],["type","button","ngbTooltip",b,"triggers","manual",1,"btn","btn-light",3,"click"],["crushDeletionBtn","ngbTooltip"],["id","crush-info-block",1,"form-text","text-muted"],["crushInfoTabs","ngbNav"],["ngbNavItem","crush-rule-info"],O,["ngbNavItem","crush-rule-steps"],Xe,we,["ruleIsNotUsed",""],Qe,Je,ke,["formGroupName","compression"],Ve,["for","mode",1,"cd-col-form-label"],Ye,["id","mode","name","mode","formControlName","mode",1,"form-control"],["for","algorithm",1,"cd-col-form-label"],Be,["id","algorithm","name","algorithm","formControlName","algorithm",1,"form-control"],["for","minBlobSize",1,"cd-col-form-label"],je,["id","minBlobSize","name","minBlobSize","formControlName","minBlobSize","type","text","min","0","placeholder",Ke,"defaultUnit","KiB","cdDimlessBinary","",1,"form-control"],["for","maxBlobSize",1,"cd-col-form-label"],We,["id","maxBlobSize","type","text","min","0","formControlName","maxBlobSize","placeholder",e_,"defaultUnit","KiB","cdDimlessBinary","",1,"form-control"],["for","ratio",1,"cd-col-form-label"],__,["id","ratio","name","ratio","formControlName","ratio","type","number","min","0","max","1","step","0.1","placeholder",o_,1,"form-control"],t_,i_,n_,s_,a_,l_,r_,c_]},template:function(_,o){1&_&&e.YNc(0,kt,69,32,"div",0),2&_&&e.Q6J("cdFormLoading",o.loading)},directives:[No.y,a._Y,a.JL,fe.V,a.sg,Pe.P,Ee.o,a.Fj,ge.b,a.JJ,a.u,pe.U,C.O5,a.EJ,a.YN,a.Kr,C.sg,bo.m,me.S,vo.Q,a.qQ,a.wV,Io.d,Re.p,a.Q7,$o.K,a.Fd,a.Wl,C.mk,E._L,E.Pz,E.nv,E.Vx,E.uN,E.tO,xe.b,a.x0],pipes:[C.rS,Ce.m],styles:[""]}),t})();var Vt=r(19773),Yt=r(49671),Bt=r(68136),Te=r(69158),he=r(35905),L=r(99466),jt=r(91801),Kt=r(68774),Wt=r(66369),qe=r(38047),Se=r(51847);class ei{constructor(i){this.pool_name=i}}var _i=r(64724),oi=r(94928),He=r(51295),ti=r(59376),Ge=r(76317),ii=r(71752);function ni(t,i){if(1&t&&e._UZ(0,"cd-table-key-value",12),2&t){const _=e.oxw(2);e.Q6J("renderObjects",!0)("data",_.poolDetails)("autoReload",!1)}}function si(t,i){if(1&t&&e._UZ(0,"cd-grafana",15),2&t){const _=e.oxw(3);e.MGl("grafanaPath","ceph-pool-detail?var-pool_name=",_.selection.pool_name,"")}}function ai(t,i){1&t&&(e.TgZ(0,"li",13),e.TgZ(1,"a",5),e.SDv(2,14),e.qZA(),e.YNc(3,si,1,1,"ng-template",7),e.qZA())}function li(t,i){if(1&t&&e._UZ(0,"cd-rbd-configuration-table",18),2&t){const _=e.oxw(3);e.Q6J("data",_.selectedPoolConfiguration)}}function ri(t,i){1&t&&(e.TgZ(0,"li",16),e.TgZ(1,"a",5),e.SDv(2,17),e.qZA(),e.YNc(3,li,1,1,"ng-template",7),e.qZA())}function ci(t,i){if(1&t&&e._UZ(0,"cd-table",21),2&t){const _=e.oxw(3);e.Q6J("data",_.cacheTiers)("columns",_.cacheTierColumns)("autoSave",!1)}}function Oi(t,i){1&t&&(e.TgZ(0,"li",19),e.TgZ(1,"a",5),e.SDv(2,20),e.qZA(),e.YNc(3,ci,1,3,"ng-template",7),e.qZA())}function di(t,i){if(1&t&&(e.ynx(0,1),e.TgZ(1,"ul",2,3),e.TgZ(3,"li",4),e.TgZ(4,"a",5),e.SDv(5,6),e.qZA(),e.YNc(6,ni,1,3,"ng-template",7),e.qZA(),e.YNc(7,ai,4,0,"li",8),e.YNc(8,ri,4,0,"li",9),e.YNc(9,Oi,4,0,"li",10),e.qZA(),e._UZ(10,"div",11),e.BQk()),2&t){const _=e.MAs(2),o=e.oxw();e.xp6(7),e.Q6J("ngIf",o.permissions.grafana.read),e.xp6(1),e.Q6J("ngIf","replicated"===o.selection.type),e.xp6(1),e.Q6J("ngIf",(null==o.selection.tiers?null:o.selection.tiers.length)>0),e.xp6(1),e.Q6J("ngbNavOutlet",_)}}let ui=(()=>{class t{constructor(_){this.poolService=_,this.cacheTierColumns=[],this.omittedPoolAttributes=["cdExecuting","cdIsBinary","stats"],this.cacheTierColumns=[{prop:"pool_name",name:"Name",flexGrow:3},{prop:"cache_mode",name:"Cache Mode",flexGrow:2},{prop:"cache_min_evict_age",name:"Min Evict Age",flexGrow:2},{prop:"cache_min_flush_age",name:"Min Flush Age",flexGrow:2},{prop:"target_max_bytes",name:"Target Max Bytes",flexGrow:2},{prop:"target_max_objects",name:"Target Max Objects",flexGrow:2}]}ngOnChanges(){this.selection&&(this.poolService.getConfiguration(this.selection.pool_name).subscribe(_=>{He.T.updateChanged(this,{selectedPoolConfiguration:_})}),He.T.updateChanged(this,{poolDetails:g().omit(this.selection,this.omittedPoolAttributes)}))}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(ue.q))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-pool-details"]],inputs:{cacheTiers:"cacheTiers",permissions:"permissions",selection:"selection"},features:[e.TTD],decls:1,vars:1,consts:function(){let i,_,o,n;return i="Details",_="Performance Details",o="Configuration",n="Cache Tiers Details",[["cdTableDetail","",4,"ngIf"],["cdTableDetail",""],["ngbNav","","cdStatefulTab","pool-details",1,"nav-tabs"],["nav","ngbNav"],["ngbNavItem","details"],["ngbNavLink",""],i,["ngbNavContent",""],["ngbNavItem","performance-details",4,"ngIf"],["ngbNavItem","configuration",4,"ngIf"],["ngbNavItem","cache-tiers-details",4,"ngIf"],[3,"ngbNavOutlet"],[3,"renderObjects","data","autoReload"],["ngbNavItem","performance-details"],_,["uid","-xyV8KCiz","grafanaStyle","three",3,"grafanaPath"],["ngbNavItem","configuration"],o,[3,"data"],["ngbNavItem","cache-tiers-details"],n,["columnMode","flex",3,"data","columns","autoSave"]]},template:function(_,o){1&_&&e.YNc(0,di,11,4,"ng-container",0),2&_&&e.Q6J("ngIf",o.selection)},directives:[C.O5,E.Pz,ti.m,E.nv,E.Vx,E.uN,E.tO,xe.b,Ge.F,ii.P,he.a],styles:[""],changeDetection:0}),t})();var fi=r(60251);const Pi=["poolUsageTpl"],Ei=["poolConfigurationSourceTpl"];function gi(t,i){if(1&t){const _=e.EpF();e.TgZ(0,"cd-table",9,10),e.NdJ("fetchData",function(){return e.CHM(_),e.oxw().taskListService.fetch()})("setExpandedRow",function(n){return e.CHM(_),e.oxw().setExpandedRow(n)})("updateSelection",function(n){return e.CHM(_),e.oxw().updateSelection(n)}),e._UZ(2,"cd-table-actions",11),e._UZ(3,"cd-pool-details",12),e.qZA()}if(2&t){const _=e.oxw();e.Q6J("data",_.pools)("columns",_.columns)("hasDetails",!0)("status",_.tableStatus)("autoReload",-1),e.xp6(2),e.Q6J("permission",_.permissions.pool)("selection",_.selection)("tableActions",_.tableActions),e.xp6(1),e.Q6J("selection",_.expandedRow)("permissions",_.permissions)("cacheTiers",_.cacheTiers)}}function pi(t,i){1&t&&e._UZ(0,"cd-grafana",14),2&t&&e.Q6J("grafanaPath","ceph-pools-overview?")}function mi(t,i){1&t&&(e.TgZ(0,"li",2),e.TgZ(1,"a",3),e.SDv(2,13),e.qZA(),e.YNc(3,pi,1,1,"ng-template",5),e.qZA())}function Ri(t,i){if(1&t&&e._UZ(0,"cd-usage-bar",16),2&t){const _=e.oxw().row;e.Q6J("total",_.stats.bytes_used.latest+_.stats.avail_raw.latest)("used",_.stats.bytes_used.latest)}}function Ci(t,i){if(1&t&&e.YNc(0,Ri,1,2,"cd-usage-bar",15),2&t){const _=i.row;e.Q6J("ngIf",null==_.stats||null==_.stats.avail_raw?null:_.stats.avail_raw.latest)}}let Mi=(()=>{class t extends Bt.o{constructor(_,o,n,s,c,d,f,p,m,T,h){super(),this.poolService=_,this.taskWrapper=o,this.ecpService=n,this.authStorageService=s,this.taskListService=c,this.modalService=d,this.pgCategoryService=f,this.dimlessPipe=p,this.urlBuilder=m,this.configurationService=T,this.actionLabels=h,this.selection=new Kt.r,this.executingTasks=[],this.tableStatus=new Te.E,this.cacheTiers=[],this.monAllowPoolDelete=!1,this.permissions=this.authStorageService.getPermissions(),this.tableActions=[{permission:"create",icon:v.P.add,routerLink:()=>this.urlBuilder.getCreate(),name:this.actionLabels.CREATE},{permission:"update",icon:v.P.edit,routerLink:()=>this.urlBuilder.getEdit(encodeURIComponent(this.selection.first().pool_name)),name:this.actionLabels.EDIT},{permission:"delete",icon:v.P.destroy,click:()=>this.deletePoolModal(),name:this.actionLabels.DELETE,disable:this.getDisableDesc.bind(this)}],this.permissions.configOpt.read&&this.configurationService.get("mon_allow_pool_delete").subscribe(R=>{if(g().has(R,"value")){const u=g().find(R.value,A=>"mon"===A.section)||{value:!1};this.monAllowPoolDelete="true"===u.value}})}ngOnInit(){const _=(o,n,s)=>g().get(n,o)>g().get(s,o)?1:-1;this.columns=[{prop:"pool_name",name:"Name",flexGrow:4,cellTransformation:L.e.executing},{prop:"data_protection",name:"Data Protection",cellTransformation:L.e.badge,customTemplateConfig:{class:"badge-background-gray"},flexGrow:1.3},{prop:"application_metadata",name:"Applications",cellTransformation:L.e.badge,customTemplateConfig:{class:"badge-background-primary"},flexGrow:1.5},{prop:"pg_status",name:"PG Status",flexGrow:1.2,cellClass:({row:o,column:n,value:s})=>this.getPgStatusCellClass(o,n,s)},{prop:"crush_rule",name:"Crush Ruleset",isHidden:!0,flexGrow:2},{name:"Usage",prop:"usage",cellTemplate:this.poolUsageTpl,flexGrow:1.2},{prop:"stats.rd_bytes.rates",name:"Read bytes",comparator:(o,n,s,c)=>_("stats.rd_bytes.latest",s,c),cellTransformation:L.e.sparkline,flexGrow:1.5},{prop:"stats.wr_bytes.rates",name:"Write bytes",comparator:(o,n,s,c)=>_("stats.wr_bytes.latest",s,c),cellTransformation:L.e.sparkline,flexGrow:1.5},{prop:"stats.rd.rate",name:"Read ops",flexGrow:1,pipe:this.dimlessPipe,cellTransformation:L.e.perSecond},{prop:"stats.wr.rate",name:"Write ops",flexGrow:1,pipe:this.dimlessPipe,cellTransformation:L.e.perSecond}],this.taskListService.init(()=>this.ecpService.list().pipe((0,Vt.zg)(o=>(this.ecProfileList=o,this.poolService.getList()))),void 0,o=>{this.pools=this.transformPoolsData(o),this.tableStatus=new Te.E},()=>{this.table.reset(),this.tableStatus=new Te.E(jt.T.ValueException)},o=>o.name.startsWith("pool/"),(o,n)=>n.metadata.pool_name===o.pool_name,{default:o=>new ei(o.pool_name)})}updateSelection(_){this.selection=_}deletePoolModal(){const _=this.selection.first().pool_name;this.modalService.show(Fe.M,{itemDescription:"Pool",itemNames:[_],submitActionObservable:()=>this.taskWrapper.wrapTaskAroundCall({task:new I.R(`pool/${M.MQ.DELETE}`,{pool_name:_}),call:this.poolService.delete(_)})})}getPgStatusCellClass(_,o,n){return{"text-right":!0,[`pg-${this.pgCategoryService.getTypeByStates(n)}`]:!0}}getErasureCodeProfile(_){let o="";return g().forEach(this.ecProfileList,n=>{n.name===_&&(o=`EC: ${n.k}+${n.m}`)}),o}transformPoolsData(_){const o=["bytes_used","max_avail","avail_raw","percent_used","rd_bytes","wr_bytes","rd","wr"],n={latest:0,rate:0,rates:[]};return g().forEach(_,s=>{s.pg_status=this.transformPgStatus(s.pg_status);const c={};g().forEach(o,d=>{c[d]=s.stats&&s.stats[d]?s.stats[d]:n}),s.stats=c,s.usage=c.percent_used.latest,!s.cdExecuting&&s.pg_num+s.pg_placement_num!==s.pg_num_target+s.pg_placement_num_target&&(s.cdExecuting="Updating"),["rd_bytes","wr_bytes"].forEach(d=>{s.stats[d].rates=s.stats[d].rates.map(f=>f[1])}),s.cdIsBinary=!0,"erasure"===s.type&&(s.data_protection=this.getErasureCodeProfile(s.erasure_code_profile)),"replicated"===s.type&&(s.data_protection=`replica: \xd7${s.size}`)}),_}transformPgStatus(_){const o=[];return g().forEach(_,(n,s)=>{o.push(`${n} ${s}`)}),o.join(", ")}getSelectionTiers(){if(void 0!==this.expandedRow){const _=this.expandedRow.tiers;this.cacheTiers=this.pools.filter(o=>_.includes(o.pool))}}getDisableDesc(){var _;return!(null===(_=this.selection)||void 0===_?void 0:_.hasSelection)||!this.monAllowPoolDelete&&"Pool deletion is disabled by the mon_allow_pool_delete configuration setting."}setExpandedRow(_){super.setExpandedRow(_),this.getSelectionTiers()}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(ue.q),e.Y36(de.P),e.Y36(Me),e.Y36(Ze.j),e.Y36(qe.j),e.Y36(De.Z),e.Y36(Yt.j),e.Y36(Wt.n),e.Y36(Se.F),e.Y36(_i.e),e.Y36(M.p4))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-pool-list"]],viewQuery:function(_,o){if(1&_&&(e.Gf(he.a,5),e.Gf(Pi,7),e.Gf(Ei,5)),2&_){let n;e.iGM(n=e.CRH())&&(o.table=n.first),e.iGM(n=e.CRH())&&(o.poolUsageTpl=n.first),e.iGM(n=e.CRH())&&(o.poolConfigurationSourceTpl=n.first)}},features:[e._Bn([qe.j,{provide:Se.F,useValue:new Se.F("pool")}]),e.qOj],decls:10,vars:2,consts:function(){let i,_;return i="Pools List",_="Overall Performance",[["ngbNav","",1,"nav-tabs"],["nav","ngbNav"],["ngbNavItem",""],["ngbNavLink",""],i,["ngbNavContent",""],["ngbNavItem","",4,"ngIf"],[3,"ngbNavOutlet"],["poolUsageTpl",""],["id","pool-list","selectionType","single",3,"data","columns","hasDetails","status","autoReload","fetchData","setExpandedRow","updateSelection"],["table",""],["id","pool-list-actions",1,"table-actions",3,"permission","selection","tableActions"],["cdTableDetail","","id","pool-list-details",3,"selection","permissions","cacheTiers"],_,["uid","z99hzWtmk","grafanaStyle","two",3,"grafanaPath"],["decimals","2",3,"total","used",4,"ngIf"],["decimals","2",3,"total","used"]]},template:function(_,o){if(1&_&&(e.TgZ(0,"ul",0,1),e.TgZ(2,"li",2),e.TgZ(3,"a",3),e.SDv(4,4),e.qZA(),e.YNc(5,gi,4,11,"ng-template",5),e.qZA(),e.YNc(6,mi,4,0,"li",6),e.qZA(),e._UZ(7,"div",7),e.YNc(8,Ci,1,1,"ng-template",null,8,e.W1O)),2&_){const n=e.MAs(1);e.xp6(6),e.Q6J("ngIf",o.permissions.grafana.read),e.xp6(1),e.Q6J("ngbNavOutlet",n)}},directives:[E.Pz,E.nv,E.Vx,E.uN,C.O5,E.tO,he.a,oi.K,ui,Ge.F,fi.O],styles:["cd-pool-list .pg-clean{color:#0b0} cd-pool-list .pg-working{color:#2b99a8} cd-pool-list .pg-warning{color:#ffc200} cd-pool-list .pg-unknown{color:#ef5c55}"]}),t})(),ze=(()=>{class t{}return t.\u0275fac=function(_){return new(_||t)},t.\u0275mod=e.oAB({type:t}),t.\u0275inj=e.cJS({imports:[[u_.t,C.ez,E.Oz,O_.m,Oe.Bz,a.UX,E.HK,d_.BlockModule]]}),t})();const Ti=[{path:"",component:Mi},{path:M.MQ.CREATE,component:Ue,data:{breadcrumbs:M.Qn.CREATE}},{path:`${M.MQ.EDIT}/:name`,component:Ue,data:{breadcrumbs:M.Qn.EDIT}}];let hi=(()=>{class t{}return t.\u0275fac=function(_){return new(_||t)},t.\u0275mod=e.oAB({type:t}),t.\u0275inj=e.cJS({imports:[[ze,Oe.Bz.forChild(Ti)]]}),t})()}}]); \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/281.0d0cd268ddc6a6760dd4.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/281.0d0cd268ddc6a6760dd4.js
new file mode 100644
index 000000000..84a069270
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/281.0d0cd268ddc6a6760dd4.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkceph_dashboard=self.webpackChunkceph_dashboard||[]).push([[281],{59281:(si,Oe,r)=>{r.r(Oe),r.d(Oe,{RgwModule:()=>e_,RoutedRgwModule:()=>ii});var f=r(12057),a=r(24751),w=r(6283),M=r(38549),Ue=r(37496),A=r(79512),N_=r(44466),O_=r(66265),U_=r(23815),u=r.n(U_),Y=r(35758),Me=r(95152),We=r(33394),Ze=r(64762),$e=r(58497),me=r(25917),he=r(19773),W_=r(96736),Z_=r(5304),ge=r(20523),$_=r(93523),e=r(74788);let O=class{constructor(o,_){this.http=o,this.rgwDaemonService=_,this.url="api/rgw/user"}list(){return this.enumerate().pipe((0,he.zg)(o=>o.length>0?(0,Y.D)(o.map(_=>this.get(_))):(0,me.of)([])))}enumerate(){return this.rgwDaemonService.request(o=>this.http.get(this.url,{params:o}))}enumerateEmail(){return this.rgwDaemonService.request(o=>this.http.get(`${this.url}/get_emails`,{params:o}))}get(o){return this.rgwDaemonService.request(_=>this.http.get(`${this.url}/${o}`,{params:_}))}getQuota(o){return this.rgwDaemonService.request(_=>this.http.get(`${this.url}/${o}/quota`,{params:_}))}create(o){return this.rgwDaemonService.request(_=>(u().keys(o).forEach(n=>{_=_.append(n,o[n])}),this.http.post(this.url,null,{params:_})))}update(o,_){return this.rgwDaemonService.request(n=>(u().keys(_).forEach(i=>{n=n.append(i,_[i])}),this.http.put(`${this.url}/${o}`,null,{params:n})))}updateQuota(o,_){return this.rgwDaemonService.request(n=>(u().keys(_).forEach(i=>{n=n.append(i,_[i])}),this.http.put(`${this.url}/${o}/quota`,null,{params:n})))}delete(o){return this.rgwDaemonService.request(_=>this.http.delete(`${this.url}/${o}`,{params:_}))}createSubuser(o,_){return this.rgwDaemonService.request(n=>(u().keys(_).forEach(i=>{n=n.append(i,_[i])}),this.http.post(`${this.url}/${o}/subuser`,null,{params:n})))}deleteSubuser(o,_){return this.rgwDaemonService.request(n=>this.http.delete(`${this.url}/${o}/subuser/${_}`,{params:n}))}addCapability(o,_,n){return this.rgwDaemonService.request(i=>(i=(i=i.append("type",_)).append("perm",n),this.http.post(`${this.url}/${o}/capability`,null,{params:i})))}deleteCapability(o,_,n){return this.rgwDaemonService.request(i=>(i=(i=i.append("type",_)).append("perm",n),this.http.delete(`${this.url}/${o}/capability`,{params:i})))}addS3Key(o,_){return this.rgwDaemonService.request(n=>(n=n.append("key_type","s3"),u().keys(_).forEach(i=>{n=n.append(i,_[i])}),this.http.post(`${this.url}/${o}/key`,null,{params:n})))}deleteS3Key(o,_){return this.rgwDaemonService.request(n=>(n=(n=n.append("key_type","s3")).append("access_key",_),this.http.delete(`${this.url}/${o}/key`,{params:n})))}exists(o){return this.get(o).pipe((0,W_.h)(!0),(0,Z_.K)(_=>(u().isFunction(_.preventDefault)&&_.preventDefault(),(0,me.of)(!1))))}emailExists(o){return o=decodeURIComponent(o),this.enumerateEmail().pipe((0,he.zg)(_=>{const n=u().indexOf(_,o);return(0,me.of)(-1!==n)}))}};O.\u0275fac=function(o){return new(o||O)(e.LFG($e.eN),e.LFG(ge.b))},O.\u0275prov=e.Yz7({token:O,factory:O.\u0275fac,providedIn:"root"}),O=(0,Ze.gn)([$_.o,(0,Ze.w6)("design:paramtypes",[$e.eN,ge.b])],O);var D=r(65862),Ae=r(18001),Ie=r(93614),m=r(77205),ve=r(97161),k=(()=>{return(t=k||(k={})).ENABLED="Enabled",t.DISABLED="Disabled",k;var t})(),B=(()=>{return(t=B||(B={})).ENABLED="Enabled",t.SUSPENDED="Suspended",B;var t})(),J=r(62862),Fe=r(63622),V=r(41582),H=r(56310),q=r(87925),X=r(94276),j=r(82945),h_=r(18372),ee=r(30839),K=r(10545);function I_(t,o){1&t&&(e.TgZ(0,"div",9),e.TgZ(1,"label",35),e.SDv(2,36),e.qZA(),e.TgZ(3,"div",12),e._UZ(4,"input",37),e.qZA(),e.qZA())}function v_(t,o){1&t&&(e.TgZ(0,"span",38),e.SDv(1,39),e.qZA())}function F_(t,o){1&t&&(e.TgZ(0,"span",38),e.SDv(1,40),e.qZA())}function L_(t,o){1&t&&(e.TgZ(0,"span",38),e.SDv(1,41),e.qZA())}function D_(t,o){1&t&&(e.TgZ(0,"span",38),e.SDv(1,42),e.qZA())}function x_(t,o){1&t&&(e.TgZ(0,"span",38),e.SDv(1,43),e.qZA())}function y_(t,o){1&t&&(e.TgZ(0,"span",38),e.SDv(1,44),e.qZA())}function q_(t,o){1&t&&(e.TgZ(0,"span",38),e.SDv(1,45),e.qZA())}function w_(t,o){1&t&&(e.TgZ(0,"span",38),e.SDv(1,46),e.qZA())}function k_(t,o){1&t&&(e.TgZ(0,"option",47),e.SDv(1,48),e.qZA()),2&t&&e.Q6J("ngValue",null)}function B_(t,o){1&t&&(e.TgZ(0,"option",47),e.SDv(1,49),e.qZA()),2&t&&e.Q6J("ngValue",null)}function H_(t,o){if(1&t&&(e.TgZ(0,"option",50),e._uU(1),e.qZA()),2&t){const _=o.$implicit;e.Q6J("value",_),e.xp6(1),e.Oqu(_)}}function X_(t,o){1&t&&(e.TgZ(0,"span",38),e.SDv(1,51),e.qZA())}function K_(t,o){1&t&&(e.TgZ(0,"option",47),e.SDv(1,53),e.qZA()),2&t&&e.Q6J("ngValue",null)}function z_(t,o){1&t&&(e.TgZ(0,"option",47),e.SDv(1,54),e.qZA()),2&t&&e.Q6J("ngValue",null)}function Q_(t,o){if(1&t&&(e.TgZ(0,"option",50),e._uU(1),e.qZA()),2&t){const _=o.$implicit;e.Q6J("value",_.name),e.xp6(1),e.Oqu(_.description)}}function Y_(t,o){1&t&&(e.TgZ(0,"span",38),e.SDv(1,55),e.qZA())}function J_(t,o){if(1&t&&(e.TgZ(0,"select",52),e.YNc(1,K_,2,1,"option",18),e.YNc(2,z_,2,1,"option",18),e.YNc(3,Q_,2,2,"option",19),e.qZA(),e.YNc(4,Y_,2,0,"span",14)),2&t){e.oxw();const _=e.MAs(2),n=e.oxw();e.xp6(1),e.Q6J("ngIf",null===n.placementTargets),e.xp6(1),e.Q6J("ngIf",null!==n.placementTargets),e.xp6(1),e.Q6J("ngForOf",n.placementTargets),e.xp6(1),e.Q6J("ngIf",n.bucketForm.showError("placement-target",_,"required"))}}function V_(t,o){1&t&&(e.ynx(0),e._UZ(1,"input",56),e.BQk())}function j_(t,o){if(1&t){const _=e.EpF();e.TgZ(0,"fieldset"),e.TgZ(1,"legend",25),e.SDv(2,57),e.qZA(),e.TgZ(3,"div",9),e.TgZ(4,"div",27),e.TgZ(5,"div",28),e.TgZ(6,"input",58),e.NdJ("change",function(){return e.CHM(_),e.oxw(2).setMfaDeleteValidators()}),e.qZA(),e.TgZ(7,"label",59),e.SDv(8,60),e.qZA(),e.TgZ(9,"cd-helper"),e.TgZ(10,"span"),e.SDv(11,61),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()}}function et(t,o){1&t&&(e.TgZ(0,"span",38),e.SDv(1,70),e.qZA())}function _t(t,o){if(1&t&&(e.TgZ(0,"div",9),e.TgZ(1,"label",67),e.SDv(2,68),e.qZA(),e.TgZ(3,"div",12),e._UZ(4,"input",69),e.YNc(5,et,2,0,"span",14),e.qZA(),e.qZA()),2&t){e.oxw(2);const _=e.MAs(2),n=e.oxw();e.xp6(5),e.Q6J("ngIf",n.bucketForm.showError("mfa-token-serial",_,"required"))}}function tt(t,o){1&t&&(e.TgZ(0,"span",38),e.SDv(1,74),e.qZA())}function nt(t,o){if(1&t&&(e.TgZ(0,"div",9),e.TgZ(1,"label",71),e.SDv(2,72),e.qZA(),e.TgZ(3,"div",12),e._UZ(4,"input",73),e.YNc(5,tt,2,0,"span",14),e.qZA(),e.qZA()),2&t){e.oxw(2);const _=e.MAs(2),n=e.oxw();e.xp6(5),e.Q6J("ngIf",n.bucketForm.showError("mfa-token-pin",_,"required"))}}function ot(t,o){if(1&t){const _=e.EpF();e.TgZ(0,"fieldset"),e.TgZ(1,"legend",25),e.SDv(2,62),e.qZA(),e.TgZ(3,"div",9),e.TgZ(4,"div",27),e.TgZ(5,"div",28),e.TgZ(6,"input",63),e.NdJ("change",function(){return e.CHM(_),e.oxw(2).setMfaDeleteValidators()}),e.qZA(),e.TgZ(7,"label",64),e.SDv(8,65),e.qZA(),e.TgZ(9,"cd-helper"),e.TgZ(10,"span"),e.SDv(11,66),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(12,_t,6,1,"div",8),e.YNc(13,nt,6,1,"div",8),e.qZA()}if(2&t){const _=e.oxw(2);e.xp6(12),e.Q6J("ngIf",_.areMfaCredentialsRequired()),e.xp6(1),e.Q6J("ngIf",_.areMfaCredentialsRequired())}}function it(t,o){1&t&&(e.TgZ(0,"div",9),e.TgZ(1,"label",75),e.SDv(2,76),e.qZA(),e.TgZ(3,"div",12),e.TgZ(4,"select",77),e.TgZ(5,"option",78),e.SDv(6,79),e.qZA(),e.TgZ(7,"option",80),e.SDv(8,81),e.qZA(),e.qZA(),e.qZA(),e.qZA())}function st(t,o){1&t&&(e.TgZ(0,"span",38),e.SDv(1,86),e.qZA())}function at(t,o){1&t&&(e.TgZ(0,"span",38),e.SDv(1,87),e.qZA())}function rt(t,o){if(1&t&&(e.TgZ(0,"div",9),e.TgZ(1,"label",82),e.ynx(2),e.SDv(3,83),e.BQk(),e.TgZ(4,"cd-helper"),e.SDv(5,84),e.qZA(),e.qZA(),e.TgZ(6,"div",12),e._UZ(7,"input",85),e.YNc(8,st,2,0,"span",14),e.YNc(9,at,2,0,"span",14),e.qZA(),e.qZA()),2&t){e.oxw();const _=e.MAs(2),n=e.oxw();e.xp6(8),e.Q6J("ngIf",n.bucketForm.showError("lock_retention_period_days",_,"pattern")),e.xp6(1),e.Q6J("ngIf",n.bucketForm.showError("lock_retention_period_days",_,"lockDays"))}}const Le=function(t){return{required:t}};function lt(t,o){if(1&t){const _=e.EpF();e.TgZ(0,"div",1),e.TgZ(1,"form",2,3),e.TgZ(3,"div",4),e.TgZ(4,"div",5),e.SDv(5,6),e.ALo(6,"titlecase"),e.ALo(7,"upperFirst"),e.qZA(),e.TgZ(8,"div",7),e.YNc(9,I_,5,0,"div",8),e.TgZ(10,"div",9),e.TgZ(11,"label",10),e.SDv(12,11),e.qZA(),e.TgZ(13,"div",12),e._UZ(14,"input",13),e.YNc(15,v_,2,0,"span",14),e.YNc(16,F_,2,0,"span",14),e.YNc(17,L_,2,0,"span",14),e.YNc(18,D_,2,0,"span",14),e.YNc(19,x_,2,0,"span",14),e.YNc(20,y_,2,0,"span",14),e.YNc(21,q_,2,0,"span",14),e.YNc(22,w_,2,0,"span",14),e.qZA(),e.qZA(),e.TgZ(23,"div",9),e.TgZ(24,"label",15),e.SDv(25,16),e.qZA(),e.TgZ(26,"div",12),e.TgZ(27,"select",17),e.YNc(28,k_,2,1,"option",18),e.YNc(29,B_,2,1,"option",18),e.YNc(30,H_,2,2,"option",19),e.qZA(),e.YNc(31,X_,2,0,"span",14),e.qZA(),e.qZA(),e.TgZ(32,"div",9),e.TgZ(33,"label",20),e.SDv(34,21),e.qZA(),e.TgZ(35,"div",12),e.YNc(36,J_,5,4,"ng-template",null,22,e.W1O),e.YNc(38,V_,2,0,"ng-container",23),e.qZA(),e.qZA(),e.YNc(39,j_,12,0,"fieldset",24),e.YNc(40,ot,14,2,"fieldset",24),e.TgZ(41,"fieldset"),e.TgZ(42,"legend",25),e.SDv(43,26),e.qZA(),e.TgZ(44,"div",9),e.TgZ(45,"div",27),e.TgZ(46,"div",28),e._UZ(47,"input",29),e.TgZ(48,"label",30),e.SDv(49,31),e.qZA(),e.TgZ(50,"cd-helper"),e.TgZ(51,"span"),e.SDv(52,32),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(53,it,9,0,"div",8),e.YNc(54,rt,10,2,"div",8),e.qZA(),e.qZA(),e.TgZ(55,"div",33),e.TgZ(56,"cd-form-button-panel",34),e.NdJ("submitActionEvent",function(){return e.CHM(_),e.oxw().submit()}),e.ALo(57,"titlecase"),e.ALo(58,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&t){const _=e.MAs(2),n=e.MAs(37),i=e.oxw();e.xp6(1),e.Q6J("formGroup",i.bucketForm),e.xp6(6),e.pQV(e.lcZ(6,29,i.action))(e.lcZ(7,31,i.resource)),e.QtT(5),e.xp6(2),e.Q6J("ngIf",i.editing),e.xp6(2),e.Q6J("ngClass",e.VKq(37,Le,!i.editing)),e.xp6(3),e.Q6J("readonly",i.editing)("autofocus",!i.editing),e.xp6(1),e.Q6J("ngIf",i.bucketForm.showError("bid",_,"required")),e.xp6(1),e.Q6J("ngIf",i.bucketForm.showError("bid",_,"bucketNameInvalid")),e.xp6(1),e.Q6J("ngIf",i.bucketForm.showError("bid",_,"bucketNameNotAllowed")),e.xp6(1),e.Q6J("ngIf",i.bucketForm.showError("bid",_,"containsUpperCase")),e.xp6(1),e.Q6J("ngIf",i.bucketForm.showError("bid",_,"lowerCaseOrNumber")),e.xp6(1),e.Q6J("ngIf",i.bucketForm.showError("bid",_,"ipAddress")),e.xp6(1),e.Q6J("ngIf",i.bucketForm.showError("bid",_,"onlyLowerCaseAndNumbers")),e.xp6(1),e.Q6J("ngIf",i.bucketForm.showError("bid",_,"shouldBeInRange")),e.xp6(5),e.Q6J("autofocus",i.editing),e.xp6(1),e.Q6J("ngIf",null===i.owners),e.xp6(1),e.Q6J("ngIf",null!==i.owners),e.xp6(1),e.Q6J("ngForOf",i.owners),e.xp6(1),e.Q6J("ngIf",i.bucketForm.showError("owner",_,"required")),e.xp6(2),e.Q6J("ngClass",e.VKq(39,Le,!i.editing)),e.xp6(5),e.Q6J("ngIf",i.editing)("ngIfElse",n),e.xp6(1),e.Q6J("ngIf",i.editing),e.xp6(1),e.Q6J("ngIf",i.editing),e.xp6(13),e.Q6J("ngIf",i.bucketForm.getValue("lock_enabled")),e.xp6(1),e.Q6J("ngIf",i.bucketForm.getValue("lock_enabled")),e.xp6(2),e.Q6J("form",i.bucketForm)("submitText",e.lcZ(57,33,i.action)+" "+e.lcZ(58,35,i.resource))}}let De=(()=>{class t extends Ie.E{constructor(_,n,i,s,c,d,E,g){super(),this.route=_,this.router=n,this.formBuilder=i,this.rgwBucketService=s,this.rgwSiteService=c,this.rgwUserService=d,this.notificationService=E,this.actionLabels=g,this.editing=!1,this.owners=null,this.placementTargets=[],this.isVersioningAlreadyEnabled=!1,this.isMfaDeleteAlreadyEnabled=!1,this.icons=D.P,this.editing=this.router.url.startsWith(`/rgw/bucket/${A.MQ.EDIT}`),this.action=this.editing?this.actionLabels.EDIT:this.actionLabels.CREATE,this.resource="bucket",this.createForm()}get isVersioningEnabled(){return this.bucketForm.getValue("versioning")}get isMfaDeleteEnabled(){return this.bucketForm.getValue("mfa-delete")}createForm(){const _=this,n=m.h.custom("lockDays",()=>{if(!_.bucketForm||!u().get(_.bucketForm.getRawValue(),"lock_enabled"))return!1;const i=Number(_.bucketForm.getValue("lock_retention_period_days"));return!Number.isInteger(i)||0===i});this.bucketForm=this.formBuilder.group({id:[null],bid:[null,[a.kI.required],this.editing?[]:[m.h.bucketName(),m.h.bucketExistence(!1,this.rgwBucketService)]],owner:[null,[a.kI.required]],"placement-target":[null,this.editing?[]:[a.kI.required]],versioning:[null],"mfa-delete":[null],"mfa-token-serial":[""],"mfa-token-pin":[""],lock_enabled:[{value:!1,disabled:this.editing}],lock_mode:["COMPLIANCE"],lock_retention_period_days:[0,[m.h.number(!1),n]]})}ngOnInit(){const _={owners:this.rgwUserService.enumerate()};this.editing||(_.getPlacementTargets=this.rgwSiteService.get("placement-targets")),this.route.params.subscribe(n=>{if(n.hasOwnProperty("bid")){const i=decodeURIComponent(n.bid);_.getBid=this.rgwBucketService.get(i)}(0,Y.D)(_).subscribe(i=>{if(this.owners=i.owners.sort(),i.getPlacementTargets){const s=i.getPlacementTargets;this.zonegroup=s.zonegroup,u().forEach(s.placement_targets,c=>{c.description=`${c.name} (${"pool"}: ${c.data_pool})`,this.placementTargets.push(c)}),1===this.placementTargets.length&&this.bucketForm.get("placement-target").setValue(this.placementTargets[0].name)}if(i.getBid){const s=i.getBid,c=u().clone(this.bucketForm.getRawValue());let d=u().pick(s,u().keys(c));d.lock_retention_period_days=this.rgwBucketService.getLockDays(s),d["placement-target"]=s.placement_rule,d.versioning=s.versioning===B.ENABLED,d["mfa-delete"]=s.mfa_delete===k.ENABLED,d=u().merge(c,d),this.bucketForm.setValue(d),this.editing&&(this.isVersioningAlreadyEnabled=this.isVersioningEnabled,this.isMfaDeleteAlreadyEnabled=this.isMfaDeleteEnabled,this.setMfaDeleteValidators(),d.lock_enabled&&this.bucketForm.controls.versioning.disable())}this.loadingReady()})})}goToListView(){this.router.navigate(["/rgw/bucket"])}submit(){if(this.bucketForm.pristine)return void this.goToListView();const _=this.bucketForm.value;if(this.editing){const n=this.getVersioningStatus(),i=this.getMfaDeleteStatus();this.rgwBucketService.update(_.bid,_.id,_.owner,n,i,_["mfa-token-serial"],_["mfa-token-pin"],_.lock_mode,_.lock_retention_period_days).subscribe(()=>{this.notificationService.show(Ae.k.success,"Updated Object Gateway bucket '" + _.bid + "'."),this.goToListView()},()=>{this.bucketForm.setErrors({cdSubmitButton:!0})})}else this.rgwBucketService.create(_.bid,_.owner,this.zonegroup,_["placement-target"],_.lock_enabled,_.lock_mode,_.lock_retention_period_days).subscribe(()=>{this.notificationService.show(Ae.k.success,"Created Object Gateway bucket '" + _.bid + "'"),this.goToListView()},()=>{this.bucketForm.setErrors({cdSubmitButton:!0})})}areMfaCredentialsRequired(){return this.isMfaDeleteEnabled!==this.isMfaDeleteAlreadyEnabled||this.isMfaDeleteAlreadyEnabled&&this.isVersioningEnabled!==this.isVersioningAlreadyEnabled}setMfaDeleteValidators(){const _=this.bucketForm.get("mfa-token-serial"),n=this.bucketForm.get("mfa-token-pin");this.areMfaCredentialsRequired()?(_.setValidators(a.kI.required),n.setValidators(a.kI.required)):(_.setValidators(null),n.setValidators(null)),_.updateValueAndValidity(),n.updateValueAndValidity()}getVersioningStatus(){return this.isVersioningEnabled?B.ENABLED:B.SUSPENDED}getMfaDeleteStatus(){return this.isMfaDeleteEnabled?k.ENABLED:k.DISABLED}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(w.gz),e.Y36(w.F0),e.Y36(J.O),e.Y36(Me.o),e.Y36(We.I),e.Y36(O),e.Y36(ve.g),e.Y36(A.p4))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-rgw-bucket-form"]],features:[e.qOj],decls:1,vars:1,consts:function(){let o,_,n,i,s,c,d,E,g,C,b,P,G,N,p,U,W,Z,$,h,I,v,F,T,x,y,S,_e,te,ne,oe,ie,se,ae,re,le,ce,de,ue,Re;return o="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",_="Name",n="Name...",i="Owner",s="Placement target",c="Locking",d="Enabled",E="Enables locking for the objects in the bucket. Locking can only be enabled while creating a bucket.",g="Id",C="This field is required.",b="Bucket names can only contain lowercase letters, numbers, periods and hyphens.",P="The chosen name is already in use.",G="Bucket names must not contain uppercase characters or underscores.",N="Each label must start and end with a lowercase letter or a number.",p="Bucket names cannot be formatted as IP address.",U="Bucket labels cannot be empty and can only contain lowercase letters, numbers and hyphens.",W="Bucket names must be 3 to 63 characters long.",Z="Loading...",$="-- Select a user --",h="This field is required.",I="Loading...",v="-- Select a placement target --",F="This field is required.",T="Versioning",x="Enabled",y="Enables versioning for the objects in the bucket.",S="Multi-Factor Authentication",_e="Delete enabled",te="Enables MFA (multi-factor authentication) Delete, which requires additional authentication for changing the bucket versioning state.",ne="Token Serial Number",oe="This field is required.",ie="Token PIN",se="This field is required.",ae="Mode",re="Compliance",le="Governance",ce="Days",de="The number of days that you want to specify for the default retention period that will be applied to new objects placed in this bucket.",ue="The entered value must be a positive integer.",Re="Retention Days must be a positive integer.",[["class","cd-col-form",4,"cdFormLoading"],[1,"cd-col-form"],["name","bucketForm","novalidate","",3,"formGroup"],["frm","ngForm"],[1,"card"],[1,"card-header"],o,[1,"card-body"],["class","form-group row",4,"ngIf"],[1,"form-group","row"],["for","bid",1,"cd-col-form-label",3,"ngClass"],_,[1,"cd-col-form-input"],["id","bid","name","bid","type","text","placeholder",n,"formControlName","bid",1,"form-control",3,"readonly","autofocus"],["class","invalid-feedback",4,"ngIf"],["for","owner",1,"cd-col-form-label","required"],i,["id","owner","name","owner","formControlName","owner",1,"form-control",3,"autofocus"],[3,"ngValue",4,"ngIf"],[3,"value",4,"ngFor","ngForOf"],["for","placement-target",1,"cd-col-form-label",3,"ngClass"],s,["placementTargetSelect",""],[4,"ngIf","ngIfElse"],[4,"ngIf"],[1,"cd-header"],c,[1,"cd-col-form-offset"],[1,"custom-control","custom-checkbox"],["id","lock_enabled","formControlName","lock_enabled","type","checkbox",1,"custom-control-input"],["for","lock_enabled",1,"custom-control-label"],d,E,[1,"card-footer"],["wrappingClass","text-right",3,"form","submitText","submitActionEvent"],["for","id",1,"cd-col-form-label"],g,["id","id","name","id","type","text","formControlName","id","readonly","",1,"form-control"],[1,"invalid-feedback"],C,b,P,G,N,p,U,W,[3,"ngValue"],Z,$,[3,"value"],h,["id","placement-target","name","placement-target","formControlName","placement-target",1,"form-control"],I,v,F,["id","placement-target","name","placement-target","formControlName","placement-target","type","text","readonly","",1,"form-control"],T,["type","checkbox","id","versioning","name","versioning","formControlName","versioning",1,"custom-control-input",3,"change"],["for","versioning",1,"custom-control-label"],x,y,S,["type","checkbox","id","mfa-delete","name","mfa-delete","formControlName","mfa-delete",1,"custom-control-input",3,"change"],["for","mfa-delete",1,"custom-control-label"],_e,te,["for","mfa-token-serial",1,"cd-col-form-label"],ne,["type","text","id","mfa-token-serial","name","mfa-token-serial","formControlName","mfa-token-serial",1,"form-control"],oe,["for","mfa-token-pin",1,"cd-col-form-label"],ie,["type","text","id","mfa-token-pin","name","mfa-token-pin","formControlName","mfa-token-pin",1,"form-control"],se,["for","lock_mode",1,"cd-col-form-label"],ae,["formControlName","lock_mode","name","lock_mode","id","lock_mode",1,"form-control"],["value","COMPLIANCE"],re,["value","GOVERNANCE"],le,["for","lock_retention_period_days",1,"cd-col-form-label"],ce,de,["type","number","id","lock_retention_period_days","formControlName","lock_retention_period_days","min","0",1,"form-control"],ue,Re]},template:function(_,n){1&_&&e.YNc(0,lt,59,41,"div",0),2&_&&e.Q6J("cdFormLoading",n.loading)},directives:[Fe.y,a._Y,a.JL,V.V,a.sg,f.O5,H.P,f.mk,q.o,a.Fj,X.b,a.JJ,a.u,j.U,a.EJ,f.sg,a.Wl,h_.S,ee.p,a.YN,a.Kr,a.wV,a.qQ],pipes:[f.rS,K.m],styles:[""]}),t})();var xe=r(18891),be=r(68136),ye=r(30982),z=r(35905),Pe=r(68774),qe=r(47557),we=r(66369),Q=r(51847),Ee=r(74937),Te=r(63285),ke=r(94928),ct=r(96102),Be=r(68962);function dt(t,o){1&t&&(e.TgZ(0,"td"),e.SDv(1,24),e.qZA())}function ut(t,o){if(1&t&&(e.TgZ(0,"td"),e._uU(1),e.ALo(2,"dimless"),e.qZA()),2&t){const _=e.oxw(3);e.xp6(1),e.hij(" ",e.lcZ(2,1,_.selection.bucket_quota.max_size)," ")}}function Rt(t,o){1&t&&(e.TgZ(0,"td"),e.SDv(1,25),e.qZA())}function gt(t,o){if(1&t&&(e.TgZ(0,"td"),e._uU(1),e.qZA()),2&t){const _=e.oxw(3);e.xp6(1),e.hij(" ",_.selection.bucket_quota.max_objects," ")}}function Et(t,o){if(1&t&&(e.TgZ(0,"div"),e.TgZ(1,"legend"),e.SDv(2,20),e.qZA(),e.TgZ(3,"table",1),e.TgZ(4,"tbody"),e.TgZ(5,"tr"),e.TgZ(6,"td",2),e.SDv(7,21),e.qZA(),e.TgZ(8,"td",4),e._uU(9),e.ALo(10,"booleanText"),e.qZA(),e.qZA(),e.TgZ(11,"tr"),e.TgZ(12,"td",5),e.SDv(13,22),e.qZA(),e.YNc(14,dt,2,0,"td",0),e.YNc(15,ut,3,3,"td",0),e.qZA(),e.TgZ(16,"tr"),e.TgZ(17,"td",5),e.SDv(18,23),e.qZA(),e.YNc(19,Rt,2,0,"td",0),e.YNc(20,gt,2,1,"td",0),e.qZA(),e.qZA(),e.qZA(),e.qZA()),2&t){const _=e.oxw(2);e.xp6(9),e.Oqu(e.lcZ(10,5,_.selection.bucket_quota.enabled)),e.xp6(5),e.Q6J("ngIf",_.selection.bucket_quota.max_size<=-1),e.xp6(1),e.Q6J("ngIf",_.selection.bucket_quota.max_size>-1),e.xp6(4),e.Q6J("ngIf",_.selection.bucket_quota.max_objects<=-1),e.xp6(1),e.Q6J("ngIf",_.selection.bucket_quota.max_objects>-1)}}function Tt(t,o){if(1&t&&(e.ynx(0),e.TgZ(1,"tr"),e.TgZ(2,"td",5),e.SDv(3,26),e.qZA(),e.TgZ(4,"td"),e._uU(5),e.qZA(),e.qZA(),e.TgZ(6,"tr"),e.TgZ(7,"td",5),e.SDv(8,27),e.qZA(),e.TgZ(9,"td"),e._uU(10),e.qZA(),e.qZA(),e.BQk()),2&t){const _=e.oxw(2);e.xp6(5),e.Oqu(_.selection.lock_mode),e.xp6(5),e.Oqu(_.selection.lock_retention_period_days)}}function St(t,o){if(1&t&&(e.ynx(0),e.TgZ(1,"table",1),e.TgZ(2,"tbody"),e.TgZ(3,"tr"),e.TgZ(4,"td",2),e.SDv(5,3),e.qZA(),e.TgZ(6,"td",4),e._uU(7),e.qZA(),e.qZA(),e.TgZ(8,"tr"),e.TgZ(9,"td",5),e.SDv(10,6),e.qZA(),e.TgZ(11,"td"),e._uU(12),e.qZA(),e.qZA(),e.TgZ(13,"tr"),e.TgZ(14,"td",5),e.SDv(15,7),e.qZA(),e.TgZ(16,"td"),e._uU(17),e.qZA(),e.qZA(),e.TgZ(18,"tr"),e.TgZ(19,"td",5),e.SDv(20,8),e.qZA(),e.TgZ(21,"td"),e._uU(22),e.qZA(),e.qZA(),e.TgZ(23,"tr"),e.TgZ(24,"td",5),e.SDv(25,9),e.qZA(),e.TgZ(26,"td"),e._uU(27),e.qZA(),e.qZA(),e.TgZ(28,"tr"),e.TgZ(29,"td",5),e.SDv(30,10),e.qZA(),e.TgZ(31,"td"),e._uU(32),e.qZA(),e.qZA(),e.TgZ(33,"tr"),e.TgZ(34,"td",5),e.SDv(35,11),e.qZA(),e.TgZ(36,"td"),e._uU(37),e.qZA(),e.qZA(),e.TgZ(38,"tr"),e.TgZ(39,"td",5),e.SDv(40,12),e.qZA(),e.TgZ(41,"td"),e._uU(42),e.qZA(),e.qZA(),e.TgZ(43,"tr"),e.TgZ(44,"td",5),e.SDv(45,13),e.qZA(),e.TgZ(46,"td"),e._uU(47),e.qZA(),e.qZA(),e.TgZ(48,"tr"),e.TgZ(49,"td",5),e.SDv(50,14),e.qZA(),e.TgZ(51,"td"),e._uU(52),e.ALo(53,"cdDate"),e.qZA(),e.qZA(),e.TgZ(54,"tr"),e.TgZ(55,"td",5),e.SDv(56,15),e.qZA(),e.TgZ(57,"td"),e._uU(58),e.qZA(),e.qZA(),e.TgZ(59,"tr"),e.TgZ(60,"td",5),e.SDv(61,16),e.qZA(),e.TgZ(62,"td"),e._uU(63),e.qZA(),e.qZA(),e.TgZ(64,"tr"),e.TgZ(65,"td",5),e.SDv(66,17),e.qZA(),e.TgZ(67,"td"),e._uU(68),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(69,Et,21,7,"div",0),e.TgZ(70,"legend"),e.SDv(71,18),e.qZA(),e.TgZ(72,"table",1),e.TgZ(73,"tbody"),e.TgZ(74,"tr"),e.TgZ(75,"td",2),e.SDv(76,19),e.qZA(),e.TgZ(77,"td",4),e._uU(78),e.ALo(79,"booleanText"),e.qZA(),e.qZA(),e.YNc(80,Tt,11,2,"ng-container",0),e.qZA(),e.qZA(),e.BQk()),2&t){const _=e.oxw();e.xp6(7),e.Oqu(_.selection.bid),e.xp6(5),e.Oqu(_.selection.id),e.xp6(5),e.Oqu(_.selection.owner),e.xp6(5),e.Oqu(_.selection.index_type),e.xp6(5),e.Oqu(_.selection.placement_rule),e.xp6(5),e.Oqu(_.selection.marker),e.xp6(5),e.Oqu(_.selection.max_marker),e.xp6(5),e.Oqu(_.selection.ver),e.xp6(5),e.Oqu(_.selection.master_ver),e.xp6(5),e.Oqu(e.lcZ(53,16,_.selection.mtime)),e.xp6(6),e.Oqu(_.selection.zonegroup),e.xp6(5),e.Oqu(_.selection.versioning),e.xp6(5),e.Oqu(_.selection.mfa_delete),e.xp6(1),e.Q6J("ngIf",_.selection.bucket_quota),e.xp6(9),e.Oqu(e.lcZ(79,18,_.selection.lock_enabled)),e.xp6(2),e.Q6J("ngIf",_.selection.lock_enabled)}}let ft=(()=>{class t{constructor(_){this.rgwBucketService=_}ngOnChanges(){this.selection&&this.rgwBucketService.get(this.selection.bid).subscribe(_=>{_.lock_retention_period_days=this.rgwBucketService.getLockDays(_),this.selection=_})}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(Me.o))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-rgw-bucket-details"]],inputs:{selection:"selection"},features:[e.TTD],decls:1,vars:1,consts:function(){let o,_,n,i,s,c,d,E,g,C,b,P,G,N,p,U,W,Z,$,h,I,v,F;return o="Name",_="ID",n="Owner",i="Index type",s="Placement rule",c="Marker",d="Maximum marker",E="Version",g="Master version",C="Modification time",b="Zonegroup",P="Versioning",G="MFA Delete",N="Locking",p="Enabled",U="Bucket quota",W="Enabled",Z="Maximum size",$="Maximum objects",h="Unlimited",I="Unlimited",v="Mode",F="Days",[[4,"ngIf"],[1,"table","table-striped","table-bordered"],[1,"bold","w-25"],o,[1,"w-75"],[1,"bold"],_,n,i,s,c,d,E,g,C,b,P,G,N,p,U,W,Z,$,h,I,v,F]},template:function(_,n){1&_&&e.YNc(0,St,81,20,"ng-container",0),2&_&&e.Q6J("ngIf",n.selection)},directives:[f.O5],pipes:[ct.N,Be.T,we.n],styles:["table[_ngcontent-%COMP%]{table-layout:fixed}table[_ngcontent-%COMP%] td[_ngcontent-%COMP%]{word-wrap:break-word}"]}),t})();var He=r(60251);const Ct=["bucketSizeTpl"],pt=["bucketObjectTpl"];function Mt(t,o){if(1&t&&e._UZ(0,"cd-usage-bar",8),2&t){const _=e.oxw().row;e.Q6J("total",_.bucket_quota.max_size)("used",_.bucket_size)}}function mt(t,o){1&t&&e.SDv(0,9)}function At(t,o){if(1&t&&(e.YNc(0,Mt,1,2,"cd-usage-bar",6),e.YNc(1,mt,1,0,"ng-template",null,7,e.W1O)),2&t){const _=o.row,n=e.MAs(2);e.Q6J("ngIf",_.bucket_quota.max_size>0&&_.bucket_quota.enabled)("ngIfElse",n)}}function bt(t,o){if(1&t&&e._UZ(0,"cd-usage-bar",12),2&t){const _=e.oxw().row;e.Q6J("total",_.bucket_quota.max_objects)("used",_.num_objects)("isBinary",!1)}}function Pt(t,o){1&t&&e.SDv(0,13)}function Gt(t,o){if(1&t&&(e.YNc(0,bt,1,3,"cd-usage-bar",10),e.YNc(1,Pt,1,0,"ng-template",null,11,e.W1O)),2&t){const _=o.row,n=e.MAs(2);e.Q6J("ngIf",_.bucket_quota.max_objects>0&&_.bucket_quota.enabled)("ngIfElse",n)}}let Ot=(()=>{class t extends be.o{constructor(_,n,i,s,c,d,E,g){super(g),this.authStorageService=_,this.dimlessBinaryPipe=n,this.dimlessPipe=i,this.rgwBucketService=s,this.modalService=c,this.urlBuilder=d,this.actionLabels=E,this.ngZone=g,this.columns=[],this.buckets=[],this.selection=new Pe.r}ngOnInit(){this.permission=this.authStorageService.getPermissions().rgw,this.columns=[{name:"Name",prop:"bid",flexGrow:2},{name:"Owner",prop:"owner",flexGrow:2.5},{name:"Used Capacity",prop:"bucket_size",flexGrow:.6,pipe:this.dimlessBinaryPipe},{name:"Capacity Limit %",prop:"size_usage",cellTemplate:this.bucketSizeTpl,flexGrow:.8},{name:"Objects",prop:"num_objects",flexGrow:.6,pipe:this.dimlessPipe},{name:"Object Limit %",prop:"object_usage",cellTemplate:this.bucketObjectTpl,flexGrow:.8}];const _=()=>this.selection.first()&&`${encodeURIComponent(this.selection.first().bid)}`;this.tableActions=[{permission:"create",icon:D.P.add,routerLink:()=>this.urlBuilder.getCreate(),name:this.actionLabels.CREATE,canBePrimary:c=>!c.hasSelection},{permission:"update",icon:D.P.edit,routerLink:()=>this.urlBuilder.getEdit(_()),name:this.actionLabels.EDIT},{permission:"delete",icon:D.P.destroy,click:()=>this.deleteAction(),disable:()=>!this.selection.hasSelection,name:this.actionLabels.DELETE,canBePrimary:c=>c.hasMultiSelection}],this.setTableRefreshTimeout()}transformBucketData(){u().forEach(this.buckets,_=>{const n=_.bucket_quota.max_size,i=_.bucket_quota.max_objects;_.bucket_size=0,_.num_objects=0,u().isEmpty(_.usage)||(_.bucket_size=_.usage["rgw.main"].size_actual,_.num_objects=_.usage["rgw.main"].num_objects),_.size_usage=n>0?_.bucket_size/n:void 0,_.object_usage=i>0?_.num_objects/i:void 0})}getBucketList(_){this.setTableRefreshTimeout(),this.rgwBucketService.list(!0).subscribe(n=>{this.buckets=n,this.transformBucketData()},()=>{_.error()})}updateSelection(_){this.selection=_}deleteAction(){this.modalService.show(ye.M,{itemDescription:this.selection.hasSingleSelection?"bucket":"buckets",itemNames:this.selection.selected.map(_=>_.bid),submitActionObservable:()=>new xe.y(_=>{(0,Y.D)(this.selection.selected.map(n=>this.rgwBucketService.delete(n.bid))).subscribe({error:n=>{_.error(n),this.table.refreshBtn()},complete:()=>{_.complete(),this.table.refreshBtn()}})})})}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(Ee.j),e.Y36(qe.$),e.Y36(we.n),e.Y36(Me.o),e.Y36(Te.Z),e.Y36(Q.F),e.Y36(A.p4),e.Y36(e.R0b))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-rgw-bucket-list"]],viewQuery:function(_,n){if(1&_&&(e.Gf(z.a,7),e.Gf(Ct,7),e.Gf(pt,7)),2&_){let i;e.iGM(i=e.CRH())&&(n.table=i.first),e.iGM(i=e.CRH())&&(n.bucketSizeTpl=i.first),e.iGM(i=e.CRH())&&(n.bucketObjectTpl=i.first)}},features:[e._Bn([{provide:Q.F,useValue:new Q.F("rgw/bucket")}]),e.qOj],decls:8,vars:9,consts:function(){let o,_;return o="No Limit",_="No Limit",[["columnMode","flex","selectionType","multiClick","identifier","bid",3,"autoReload","data","columns","hasDetails","status","setExpandedRow","updateSelection","fetchData"],["table",""],[1,"table-actions",3,"permission","selection","tableActions"],["cdTableDetail","",3,"selection"],["bucketSizeTpl",""],["bucketObjectTpl",""],[3,"total","used",4,"ngIf","ngIfElse"],["noSizeQuota",""],[3,"total","used"],o,[3,"total","used","isBinary",4,"ngIf","ngIfElse"],["noObjectQuota",""],[3,"total","used","isBinary"],_]},template:function(_,n){1&_&&(e.TgZ(0,"cd-table",0,1),e.NdJ("setExpandedRow",function(s){return n.setExpandedRow(s)})("updateSelection",function(s){return n.updateSelection(s)})("fetchData",function(s){return n.getBucketList(s)}),e._UZ(2,"cd-table-actions",2),e._UZ(3,"cd-rgw-bucket-details",3),e.qZA(),e.YNc(4,At,3,2,"ng-template",null,4,e.W1O),e.YNc(6,Gt,3,2,"ng-template",null,5,e.W1O)),2&_&&(e.Q6J("autoReload",!1)("data",n.buckets)("columns",n.columns)("hasDetails",!0)("status",n.tableStatus),e.xp6(2),e.Q6J("permission",n.permission)("selection",n.selection)("tableActions",n.tableActions),e.xp6(1),e.Q6J("selection",n.expandedRow))},directives:[z.a,ke.K,ft,f.O5,He.O],styles:[""]}),t})();var Ut=r(58111),Xe=r(59376),Wt=r(61350),Zt=r(98056),Ke=r(76317);function $t(t,o){if(1&t){const _=e.EpF();e.TgZ(0,"cd-table-key-value",11),e.NdJ("fetchData",function(){return e.CHM(_),e.oxw(2).getMetaData()}),e.qZA()}if(2&t){const _=e.oxw(2);e.Q6J("data",_.metadata)}}function ht(t,o){if(1&t&&e._UZ(0,"cd-table-performance-counter",12),2&t){const _=e.oxw(2);e.Q6J("serviceId",_.serviceMapId)}}function It(t,o){if(1&t&&e._UZ(0,"cd-grafana",15),2&t){const _=e.oxw(3);e.Q6J("grafanaPath","rgw-instance-detail?var-rgw_servers=rgw."+_.serviceId)}}function vt(t,o){1&t&&(e.TgZ(0,"li",13),e.TgZ(1,"a",4),e.SDv(2,14),e.qZA(),e.YNc(3,It,1,1,"ng-template",6),e.qZA())}function Ft(t,o){if(1&t&&(e.ynx(0),e.TgZ(1,"ul",1,2),e.TgZ(3,"li",3),e.TgZ(4,"a",4),e.SDv(5,5),e.qZA(),e.YNc(6,$t,1,1,"ng-template",6),e.qZA(),e.TgZ(7,"li",7),e.TgZ(8,"a",4),e.SDv(9,8),e.qZA(),e.YNc(10,ht,1,1,"ng-template",6),e.qZA(),e.YNc(11,vt,4,0,"li",9),e.qZA(),e._UZ(12,"div",10),e.BQk()),2&t){const _=e.MAs(2),n=e.oxw();e.xp6(11),e.Q6J("ngIf",n.grafanaPermission.read),e.xp6(1),e.Q6J("ngbNavOutlet",_)}}let Lt=(()=>{class t{constructor(_,n){this.rgwDaemonService=_,this.authStorageService=n,this.serviceId="",this.serviceMapId="",this.grafanaPermission=this.authStorageService.getPermissions().grafana}ngOnChanges(){this.selection&&(this.serviceId=this.selection.id,this.serviceMapId=this.selection.service_map_id)}getMetaData(){u().isEmpty(this.serviceId)||this.rgwDaemonService.get(this.serviceId).subscribe(_=>{this.metadata=_.rgw_metadata})}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(ge.b),e.Y36(Ee.j))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-rgw-daemon-details"]],inputs:{selection:"selection"},features:[e.TTD],decls:1,vars:1,consts:function(){let o,_,n;return o="Details",_="Performance Counters",n="Performance Details",[[4,"ngIf"],["ngbNav","","cdStatefulTab","rgw-daemon-details",1,"nav-tabs"],["nav","ngbNav"],["ngbNavItem","details"],["ngbNavLink",""],o,["ngbNavContent",""],["ngbNavItem","performance-counters"],_,["ngbNavItem","performance-details",4,"ngIf"],[3,"ngbNavOutlet"],[3,"data","fetchData"],["serviceType","rgw",3,"serviceId"],["ngbNavItem","performance-details"],n,["uid","x5ARzZtmk","grafanaStyle","one",3,"grafanaPath"]]},template:function(_,n){1&_&&e.YNc(0,Ft,13,2,"ng-container",0),2&_&&e.Q6J("ngIf",n.selection)},directives:[f.O5,M.Pz,Xe.m,M.nv,M.Vx,M.uN,M.tO,Wt.b,Zt.p,Ke.F],styles:[""]}),t})();function Dt(t,o){if(1&t){const _=e.EpF();e.TgZ(0,"cd-table",8),e.NdJ("setExpandedRow",function(i){return e.CHM(_),e.oxw().setExpandedRow(i)})("fetchData",function(i){return e.CHM(_),e.oxw().getDaemonList(i)}),e._UZ(1,"cd-rgw-daemon-details",9),e.qZA()}if(2&t){const _=e.oxw();e.Q6J("data",_.daemons)("columns",_.columns)("hasDetails",!0),e.xp6(1),e.Q6J("selection",_.expandedRow)}}function xt(t,o){1&t&&e._UZ(0,"cd-grafana",11),2&t&&e.Q6J("grafanaPath","rgw-overview?")}function yt(t,o){1&t&&(e.TgZ(0,"li",2),e.TgZ(1,"a",3),e.SDv(2,10),e.qZA(),e.YNc(3,xt,1,1,"ng-template",5),e.qZA())}function qt(t,o){1&t&&e._UZ(0,"cd-grafana",13),2&t&&e.Q6J("grafanaPath","radosgw-sync-overview?")}function wt(t,o){1&t&&(e.TgZ(0,"li",2),e.TgZ(1,"a",3),e.SDv(2,12),e.qZA(),e.YNc(3,qt,1,1,"ng-template",5),e.qZA())}let kt=(()=>{class t extends be.o{constructor(_,n,i,s){super(),this.rgwDaemonService=_,this.authStorageService=n,this.cephShortVersionPipe=i,this.rgwSiteService=s,this.columns=[],this.daemons=[],this.updateDaemons=c=>{this.daemons=c}}ngOnInit(){this.grafanaPermission=this.authStorageService.getPermissions().grafana,this.columns=[{name:"ID",prop:"id",flexGrow:2},{name:"Hostname",prop:"server_hostname",flexGrow:2},{name:"Zone",prop:"zone_name",flexGrow:2},{name:"Zone Group",prop:"zonegroup_name",flexGrow:2},{name:"Realm",prop:"realm_name",flexGrow:2},{name:"Version",prop:"version",flexGrow:1,pipe:this.cephShortVersionPipe}],this.rgwSiteService.get("realms").subscribe(_=>this.isMultiSite=_.length>0)}getDaemonList(_){this.rgwDaemonService.list().subscribe(this.updateDaemons,()=>{_.error()})}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(ge.b),e.Y36(Ee.j),e.Y36(Ut.F),e.Y36(We.I))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-rgw-daemon-list"]],features:[e.qOj],decls:9,vars:3,consts:function(){let o,_,n;return o="Daemons List",_="Overall Performance",n="Sync Performance",[["ngbNav","",1,"nav-tabs"],["nav","ngbNav"],["ngbNavItem",""],["ngbNavLink",""],o,["ngbNavContent",""],["ngbNavItem","",4,"ngIf"],[3,"ngbNavOutlet"],["columnMode","flex",3,"data","columns","hasDetails","setExpandedRow","fetchData"],["cdTableDetail","",3,"selection"],_,["uid","WAkugZpiz","grafanaStyle","two",3,"grafanaPath"],n,["uid","rgw-sync-overview","grafanaStyle","two",3,"grafanaPath"]]},template:function(_,n){if(1&_&&(e.TgZ(0,"ul",0,1),e.TgZ(2,"li",2),e.TgZ(3,"a",3),e.SDv(4,4),e.qZA(),e.YNc(5,Dt,2,4,"ng-template",5),e.qZA(),e.YNc(6,yt,4,0,"li",6),e.YNc(7,wt,4,0,"li",6),e.qZA(),e._UZ(8,"div",7)),2&_){const i=e.MAs(1);e.xp6(6),e.Q6J("ngIf",n.grafanaPermission.read),e.xp6(1),e.Q6J("ngIf",n.grafanaPermission.read&&n.isMultiSite),e.xp6(1),e.Q6J("ngbNavOutlet",i)}},directives:[M.Pz,M.nv,M.Vx,M.uN,f.O5,M.tO,z.a,Lt,Ke.F],styles:[""]}),t})();var Bt=r(58071),Ge=r(28211),Se=(()=>{return(t=Se||(Se={})).USERS="users",t.BUCKETS="buckets",t.METADATA="metadata",t.USAGE="usage",t.ZONE="zone",Se;var t})();let ze=(()=>{class t{static getAll(){return Object.values(t.capabilities)}}return t.capabilities=Se,t})();var fe=r(60312);function Ht(t,o){1&t&&e._UZ(0,"input",22),2&t&&e.Q6J("readonly",!0)}function Xt(t,o){1&t&&(e.TgZ(0,"option",17),e.SDv(1,25),e.qZA()),2&t&&e.Q6J("ngValue",null)}function Kt(t,o){if(1&t&&(e.TgZ(0,"option",26),e._uU(1),e.qZA()),2&t){const _=o.$implicit;e.Q6J("value",_),e.xp6(1),e.Oqu(_)}}function zt(t,o){if(1&t&&(e.TgZ(0,"select",23),e.YNc(1,Xt,2,1,"option",24),e.YNc(2,Kt,2,2,"option",19),e.qZA()),2&t){const _=e.oxw();e.xp6(1),e.Q6J("ngIf",null!==_.types),e.xp6(1),e.Q6J("ngForOf",_.types)}}function Qt(t,o){1&t&&(e.TgZ(0,"span",27),e.SDv(1,28),e.qZA())}function Yt(t,o){if(1&t&&(e.TgZ(0,"option",26),e._uU(1),e.qZA()),2&t){const _=o.$implicit;e.Q6J("value",_),e.xp6(1),e.hij(" ",_," ")}}function Jt(t,o){1&t&&(e.TgZ(0,"span",27),e.SDv(1,29),e.qZA())}const Vt=function(t){return{required:t}},jt=function(){return["read","write","*"]};let en=(()=>{class t{constructor(_,n,i){this.formBuilder=_,this.activeModal=n,this.actionLabels=i,this.submitAction=new e.vpe,this.editing=!0,this.types=[],this.resource="capability",this.createForm()}createForm(){this.formGroup=this.formBuilder.group({type:[null,[a.kI.required]],perm:[null,[a.kI.required]]})}setEditing(_=!0){this.editing=_,this.action=this.editing?this.actionLabels.EDIT:this.actionLabels.ADD}setValues(_,n){this.formGroup.setValue({type:_,perm:n})}setCapabilities(_){const n=[];_.forEach(i=>{n.push(i.type)}),this.types=[],ze.getAll().forEach(i=>{-1===u().indexOf(n,i)&&this.types.push(i)})}onSubmit(){this.submitAction.emit(this.formGroup.value),this.activeModal.close()}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(J.O),e.Y36(M.Kz),e.Y36(A.p4))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-rgw-user-capability-modal"]],outputs:{submitAction:"submitAction"},decls:29,vars:24,consts:function(){let o,_,n,i,s,c,d;return o="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",_="Type",n="Permission",i="-- Select a permission --",s="-- Select a type --",c="This field is required.",d="This field is required.",[[3,"modalRef"],[1,"modal-title"],o,[1,"modal-content"],["novalidate","",3,"formGroup"],["frm","ngForm"],[1,"modal-body"],[1,"form-group","row"],["for","type",1,"cd-col-form-label",3,"ngClass"],_,[1,"cd-col-form-input"],["id","type","class","form-control","type","text","formControlName","type",3,"readonly",4,"ngIf"],["id","type","class","form-control","formControlName","type","autofocus","",4,"ngIf"],["class","invalid-feedback",4,"ngIf"],["for","perm",1,"cd-col-form-label","required"],n,["id","perm","formControlName","perm",1,"form-control"],[3,"ngValue"],i,[3,"value",4,"ngFor","ngForOf"],[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],["id","type","type","text","formControlName","type",1,"form-control",3,"readonly"],["id","type","formControlName","type","autofocus","",1,"form-control"],[3,"ngValue",4,"ngIf"],s,[3,"value"],[1,"invalid-feedback"],c,d]},template:function(_,n){if(1&_&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.ALo(3,"titlecase"),e.ALo(4,"upperFirst"),e.BQk(),e.ynx(5,3),e.TgZ(6,"form",4,5),e.TgZ(8,"div",6),e.TgZ(9,"div",7),e.TgZ(10,"label",8),e.SDv(11,9),e.qZA(),e.TgZ(12,"div",10),e.YNc(13,Ht,1,1,"input",11),e.YNc(14,zt,3,2,"select",12),e.YNc(15,Qt,2,0,"span",13),e.qZA(),e.qZA(),e.TgZ(16,"div",7),e.TgZ(17,"label",14),e.SDv(18,15),e.qZA(),e.TgZ(19,"div",10),e.TgZ(20,"select",16),e.TgZ(21,"option",17),e.SDv(22,18),e.qZA(),e.YNc(23,Yt,2,2,"option",19),e.qZA(),e.YNc(24,Jt,2,0,"span",13),e.qZA(),e.qZA(),e.qZA(),e.TgZ(25,"div",20),e.TgZ(26,"cd-form-button-panel",21),e.NdJ("submitActionEvent",function(){return n.onSubmit()}),e.ALo(27,"titlecase"),e.ALo(28,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&_){const i=e.MAs(7);e.Q6J("modalRef",n.activeModal),e.xp6(4),e.pQV(e.lcZ(3,13,n.action))(e.lcZ(4,15,n.resource)),e.QtT(2),e.xp6(2),e.Q6J("formGroup",n.formGroup),e.xp6(4),e.Q6J("ngClass",e.VKq(21,Vt,!n.editing)),e.xp6(3),e.Q6J("ngIf",n.editing),e.xp6(1),e.Q6J("ngIf",!n.editing),e.xp6(1),e.Q6J("ngIf",n.formGroup.showError("type",i,"required")),e.xp6(6),e.Q6J("ngValue",null),e.xp6(2),e.Q6J("ngForOf",e.DdM(23,jt)),e.xp6(1),e.Q6J("ngIf",n.formGroup.showError("perm",i,"required")),e.xp6(2),e.Q6J("form",n.formGroup)("submitText",e.lcZ(27,17,n.action)+" "+e.lcZ(28,19,n.resource))}},directives:[fe.z,a._Y,a.JL,V.V,a.sg,H.P,f.mk,f.O5,q.o,a.EJ,X.b,a.JJ,a.u,a.YN,a.Kr,f.sg,ee.p,a.Fj,j.U],pipes:[f.rS,K.m],styles:[""]}),t})();var Ce=r(4416),pe=r(58039);function _n(t,o){1&t&&e._UZ(0,"input",17),2&t&&e.Q6J("readonly",!0)}function tn(t,o){1&t&&(e.TgZ(0,"option",21),e.SDv(1,22),e.qZA()),2&t&&e.Q6J("ngValue",null)}function nn(t,o){if(1&t&&(e.TgZ(0,"option",23),e._uU(1),e.qZA()),2&t){const _=o.$implicit;e.Q6J("value",_),e.xp6(1),e.Oqu(_)}}function on(t,o){if(1&t&&(e.TgZ(0,"select",18),e.YNc(1,tn,2,1,"option",19),e.YNc(2,nn,2,2,"option",20),e.qZA()),2&t){const _=e.oxw();e.xp6(1),e.Q6J("ngIf",null!==_.userCandidates),e.xp6(1),e.Q6J("ngForOf",_.userCandidates)}}function sn(t,o){1&t&&(e.TgZ(0,"span",24),e.SDv(1,25),e.qZA())}function an(t,o){1&t&&(e.TgZ(0,"div",7),e.TgZ(1,"div",26),e.TgZ(2,"div",27),e._UZ(3,"input",28),e.TgZ(4,"label",29),e.SDv(5,30),e.qZA(),e.qZA(),e.qZA(),e.qZA())}function rn(t,o){1&t&&(e.TgZ(0,"span",24),e.SDv(1,38),e.qZA())}const Ne=function(t){return{required:t}};function ln(t,o){if(1&t&&(e.TgZ(0,"div",7),e.TgZ(1,"label",31),e.SDv(2,32),e.qZA(),e.TgZ(3,"div",10),e.TgZ(4,"div",33),e._UZ(5,"input",34),e.TgZ(6,"span",35),e._UZ(7,"button",36),e._UZ(8,"cd-copy-2-clipboard-button",37),e.qZA(),e.qZA(),e.YNc(9,rn,2,0,"span",13),e.qZA(),e.qZA()),2&t){const _=e.oxw(),n=e.MAs(7);e.xp6(1),e.Q6J("ngClass",e.VKq(3,Ne,!_.viewing)),e.xp6(4),e.Q6J("readonly",_.viewing),e.xp6(4),e.Q6J("ngIf",_.formGroup.showError("access_key",n,"required"))}}function cn(t,o){1&t&&(e.TgZ(0,"span",24),e.SDv(1,44),e.qZA())}function dn(t,o){if(1&t&&(e.TgZ(0,"div",7),e.TgZ(1,"label",39),e.SDv(2,40),e.qZA(),e.TgZ(3,"div",10),e.TgZ(4,"div",33),e._UZ(5,"input",41),e.TgZ(6,"span",35),e._UZ(7,"button",42),e._UZ(8,"cd-copy-2-clipboard-button",43),e.qZA(),e.qZA(),e.YNc(9,cn,2,0,"span",13),e.qZA(),e.qZA()),2&t){const _=e.oxw(),n=e.MAs(7);e.xp6(1),e.Q6J("ngClass",e.VKq(3,Ne,!_.viewing)),e.xp6(4),e.Q6J("readonly",_.viewing),e.xp6(4),e.Q6J("ngIf",_.formGroup.showError("secret_key",n,"required"))}}let Qe=(()=>{class t{constructor(_,n,i){this.formBuilder=_,this.activeModal=n,this.actionLabels=i,this.submitAction=new e.vpe,this.viewing=!0,this.userCandidates=[],this.resource="S3 Key",this.createForm()}createForm(){this.formGroup=this.formBuilder.group({user:[null,[a.kI.required]],generate_key:[!0],access_key:[null,[m.h.requiredIf({generate_key:!1})]],secret_key:[null,[m.h.requiredIf({generate_key:!1})]]})}setViewing(_=!0){this.viewing=_,this.action=this.viewing?this.actionLabels.SHOW:this.actionLabels.CREATE}setValues(_,n,i){this.formGroup.setValue({user:_,generate_key:u().isEmpty(n),access_key:n,secret_key:i})}setUserCandidates(_){this.userCandidates=_}onSubmit(){this.submitAction.emit(this.formGroup.value),this.activeModal.close()}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(J.O),e.Y36(M.Kz),e.Y36(A.p4))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-rgw-user-s3-key-modal"]],outputs:{submitAction:"submitAction"},decls:23,vars:24,consts:function(){let o,_,n,i,s,c,d,E,g;return o="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",_="Username",n="-- Select a username --",i="This field is required.",s="Auto-generate key",c="Access key",d="This field is required.",E="Secret key",g="This field is required.",[[3,"modalRef"],[1,"modal-title"],o,[1,"modal-content"],["novalidate","",3,"formGroup"],["frm","ngForm"],[1,"modal-body"],[1,"form-group","row"],["for","user",1,"cd-col-form-label",3,"ngClass"],_,[1,"cd-col-form-input"],["id","user","class","form-control","type","text","formControlName","user",3,"readonly",4,"ngIf"],["id","user","class","form-control","formControlName","user","autofocus","",4,"ngIf"],["class","invalid-feedback",4,"ngIf"],["class","form-group row",4,"ngIf"],[1,"modal-footer"],[3,"form","submitText","showSubmit","submitActionEvent"],["id","user","type","text","formControlName","user",1,"form-control",3,"readonly"],["id","user","formControlName","user","autofocus","",1,"form-control"],[3,"ngValue",4,"ngIf"],[3,"value",4,"ngFor","ngForOf"],[3,"ngValue"],n,[3,"value"],[1,"invalid-feedback"],i,[1,"cd-col-form-offset"],[1,"custom-control","custom-checkbox"],["id","generate_key","type","checkbox","formControlName","generate_key",1,"custom-control-input"],["for","generate_key",1,"custom-control-label"],s,["for","access_key",1,"cd-col-form-label",3,"ngClass"],c,[1,"input-group"],["id","access_key","type","password","formControlName","access_key",1,"form-control",3,"readonly"],[1,"input-group-append"],["type","button","cdPasswordButton","access_key",1,"btn","btn-light"],["source","access_key"],d,["for","secret_key",1,"cd-col-form-label",3,"ngClass"],E,["id","secret_key","type","password","formControlName","secret_key",1,"form-control",3,"readonly"],["type","button","cdPasswordButton","secret_key",1,"btn","btn-light"],["source","secret_key"],g]},template:function(_,n){if(1&_&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.ALo(3,"titlecase"),e.ALo(4,"upperFirst"),e.BQk(),e.ynx(5,3),e.TgZ(6,"form",4,5),e.TgZ(8,"div",6),e.TgZ(9,"div",7),e.TgZ(10,"label",8),e.SDv(11,9),e.qZA(),e.TgZ(12,"div",10),e.YNc(13,_n,1,1,"input",11),e.YNc(14,on,3,2,"select",12),e.YNc(15,sn,2,0,"span",13),e.qZA(),e.qZA(),e.YNc(16,an,6,0,"div",14),e.YNc(17,ln,10,5,"div",14),e.YNc(18,dn,10,5,"div",14),e.qZA(),e.TgZ(19,"div",15),e.TgZ(20,"cd-form-button-panel",16),e.NdJ("submitActionEvent",function(){return n.onSubmit()}),e.ALo(21,"titlecase"),e.ALo(22,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&_){const i=e.MAs(7);e.Q6J("modalRef",n.activeModal),e.xp6(4),e.pQV(e.lcZ(3,14,n.action))(e.lcZ(4,16,n.resource)),e.QtT(2),e.xp6(2),e.Q6J("formGroup",n.formGroup),e.xp6(4),e.Q6J("ngClass",e.VKq(22,Ne,!n.viewing)),e.xp6(3),e.Q6J("ngIf",n.viewing),e.xp6(1),e.Q6J("ngIf",!n.viewing),e.xp6(1),e.Q6J("ngIf",n.formGroup.showError("user",i,"required")),e.xp6(1),e.Q6J("ngIf",!n.viewing),e.xp6(1),e.Q6J("ngIf",!n.formGroup.getValue("generate_key")),e.xp6(1),e.Q6J("ngIf",!n.formGroup.getValue("generate_key")),e.xp6(2),e.Q6J("form",n.formGroup)("submitText",e.lcZ(21,18,n.action)+" "+e.lcZ(22,20,n.resource))("showSubmit",!n.viewing)}},directives:[fe.z,a._Y,a.JL,V.V,a.sg,H.P,f.mk,f.O5,ee.p,q.o,a.Fj,X.b,a.JJ,a.u,a.EJ,j.U,f.sg,a.YN,a.Kr,a.Wl,Ce.C,pe.s],pipes:[f.rS,K.m],styles:[""]}),t})();class un{}function Rn(t,o){1&t&&(e.TgZ(0,"span",29),e.SDv(1,30),e.qZA())}function gn(t,o){1&t&&(e.TgZ(0,"span",29),e.SDv(1,31),e.qZA())}function En(t,o){if(1&t&&(e.TgZ(0,"option",32),e._uU(1),e.qZA()),2&t){const _=o.$implicit;e.Q6J("value",_),e.xp6(1),e.hij(" ",_," ")}}function Tn(t,o){1&t&&(e.TgZ(0,"span",29),e.SDv(1,33),e.qZA())}function Sn(t,o){1&t&&(e.TgZ(0,"span",29),e.SDv(1,48),e.qZA())}function fn(t,o){if(1&t&&(e.TgZ(0,"div",7),e.TgZ(1,"label",41),e.SDv(2,42),e.qZA(),e.TgZ(3,"div",10),e.TgZ(4,"div",43),e._UZ(5,"input",44),e.TgZ(6,"span",45),e._UZ(7,"button",46),e._UZ(8,"cd-copy-2-clipboard-button",47),e.qZA(),e.qZA(),e.YNc(9,Sn,2,0,"span",15),e.qZA(),e.qZA()),2&t){const _=e.oxw(2),n=e.MAs(7);e.xp6(9),e.Q6J("ngIf",_.formGroup.showError("secret_key",n,"required"))}}function Cn(t,o){if(1&t&&(e.TgZ(0,"fieldset"),e.TgZ(1,"legend"),e.SDv(2,34),e.qZA(),e.TgZ(3,"div",7),e.TgZ(4,"div",35),e.TgZ(5,"div",36),e._UZ(6,"input",37),e.TgZ(7,"label",38),e.SDv(8,39),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(9,fn,10,1,"div",40),e.qZA()),2&t){const _=e.oxw();e.xp6(9),e.Q6J("ngIf",!_.editing&&!_.formGroup.getValue("generate_secret"))}}const pn=function(t){return{required:t}},Mn=function(){return["read","write"]};let mn=(()=>{class t{constructor(_,n,i){this.formBuilder=_,this.bsModalRef=n,this.actionLabels=i,this.submitAction=new e.vpe,this.editing=!0,this.subusers=[],this.resource="Subuser",this.createForm()}createForm(){this.formGroup=this.formBuilder.group({uid:[null],subuid:[null,[a.kI.required,this.subuserValidator()]],perm:[null,[a.kI.required]],generate_secret:[!0],secret_key:[null,[m.h.requiredIf({generate_secret:!1})]]})}subuserValidator(){const _=this;return n=>_.editing||(0,m.P)(n.value)?null:_.subusers.some(s=>u().isEqual(_.getSubuserName(s.id),n.value))?{subuserIdExists:!0}:null}getSubuserName(_){if(u().isEmpty(_))return _;const n=_.match(/([^:]+)(:(.+))?/);return u().isUndefined(n[3])?n[1]:n[3]}setEditing(_=!0){this.editing=_,this.action=this.editing?this.actionLabels.EDIT:this.actionLabels.CREATE}setValues(_,n="",i=""){this.formGroup.setValue({uid:_,subuid:this.getSubuserName(n),perm:i,generate_secret:!0,secret_key:null})}setSubusers(_){this.subusers=_}onSubmit(){const _=this.formGroup.value,n=new un;n.id=`${_.uid}:${_.subuid}`,n.permissions=_.perm,n.generate_secret=_.generate_secret,n.secret_key=_.secret_key,this.submitAction.emit(n),this.bsModalRef.close()}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(J.O),e.Y36(M.Kz),e.Y36(A.p4))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-rgw-user-subuser-modal"]],outputs:{submitAction:"submitAction"},decls:39,vars:26,consts:function(){let o,_,n,i,s,c,d,E,g,C,b,P,G,N;return o="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",_="Username",n="Subuser",i="Permission",s="-- Select a permission --",c="read, write",d="full",E="This field is required.",g="The chosen subuser ID is already in use.",C="This field is required.",b="Swift key",P="Auto-generate secret",G="Secret key",N="This field is required.",[[3,"modalRef"],[1,"modal-title"],o,[1,"modal-content"],["novalidate","",3,"formGroup"],["frm","ngForm"],[1,"modal-body"],[1,"form-group","row"],["for","uid",1,"cd-col-form-label"],_,[1,"cd-col-form-input"],["id","uid","type","text","formControlName","uid",1,"form-control",3,"readonly"],["for","subuid",1,"cd-col-form-label",3,"ngClass"],n,["id","subuid","type","text","formControlName","subuid","autofocus","",1,"form-control",3,"readonly"],["class","invalid-feedback",4,"ngIf"],["for","perm",1,"cd-col-form-label","required"],i,["id","perm","formControlName","perm",1,"form-control"],[3,"ngValue"],s,[3,"value",4,"ngFor","ngForOf"],["value","read-write"],c,["value","full-control"],d,[4,"ngIf"],[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],[1,"invalid-feedback"],E,g,[3,"value"],C,b,[1,"cd-col-form-offset"],[1,"custom-control","custom-checkbox"],["id","generate_secret","type","checkbox","formControlName","generate_secret",1,"custom-control-input"],["for","generate_secret",1,"custom-control-label"],P,["class","form-group row",4,"ngIf"],["for","secret_key",1,"cd-col-form-label","required"],G,[1,"input-group"],["id","secret_key","type","password","formControlName","secret_key",1,"form-control"],[1,"input-group-append"],["type","button","cdPasswordButton","secret_key",1,"btn","btn-light"],["source","secret_key"],N]},template:function(_,n){if(1&_&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.ALo(3,"titlecase"),e.ALo(4,"upperFirst"),e.BQk(),e.ynx(5,3),e.TgZ(6,"form",4,5),e.TgZ(8,"div",6),e.TgZ(9,"div",7),e.TgZ(10,"label",8),e.SDv(11,9),e.qZA(),e.TgZ(12,"div",10),e._UZ(13,"input",11),e.qZA(),e.qZA(),e.TgZ(14,"div",7),e.TgZ(15,"label",12),e.SDv(16,13),e.qZA(),e.TgZ(17,"div",10),e._UZ(18,"input",14),e.YNc(19,Rn,2,0,"span",15),e.YNc(20,gn,2,0,"span",15),e.qZA(),e.qZA(),e.TgZ(21,"div",7),e.TgZ(22,"label",16),e.SDv(23,17),e.qZA(),e.TgZ(24,"div",10),e.TgZ(25,"select",18),e.TgZ(26,"option",19),e.SDv(27,20),e.qZA(),e.YNc(28,En,2,2,"option",21),e.TgZ(29,"option",22),e.SDv(30,23),e.qZA(),e.TgZ(31,"option",24),e.SDv(32,25),e.qZA(),e.qZA(),e.YNc(33,Tn,2,0,"span",15),e.qZA(),e.qZA(),e.YNc(34,Cn,10,1,"fieldset",26),e.qZA(),e.TgZ(35,"div",27),e.TgZ(36,"cd-form-button-panel",28),e.NdJ("submitActionEvent",function(){return n.onSubmit()}),e.ALo(37,"titlecase"),e.ALo(38,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&_){const i=e.MAs(7);e.Q6J("modalRef",n.bsModalRef),e.xp6(4),e.pQV(e.lcZ(3,15,n.action))(e.lcZ(4,17,n.resource)),e.QtT(2),e.xp6(2),e.Q6J("formGroup",n.formGroup),e.xp6(7),e.Q6J("readonly",!0),e.xp6(2),e.Q6J("ngClass",e.VKq(23,pn,!n.editing)),e.xp6(3),e.Q6J("readonly",n.editing),e.xp6(1),e.Q6J("ngIf",n.formGroup.showError("subuid",i,"required")),e.xp6(1),e.Q6J("ngIf",n.formGroup.showError("subuid",i,"subuserIdExists")),e.xp6(6),e.Q6J("ngValue",null),e.xp6(2),e.Q6J("ngForOf",e.DdM(25,Mn)),e.xp6(5),e.Q6J("ngIf",n.formGroup.showError("perm",i,"required")),e.xp6(1),e.Q6J("ngIf",!n.editing),e.xp6(2),e.Q6J("form",n.formGroup)("submitText",e.lcZ(37,19,n.action)+" "+e.lcZ(38,21,n.resource))}},directives:[fe.z,a._Y,a.JL,V.V,a.sg,H.P,q.o,a.Fj,X.b,a.JJ,a.u,f.mk,j.U,f.O5,a.EJ,a.YN,a.Kr,f.sg,ee.p,a.Wl,Ce.C,pe.s],pipes:[f.rS,K.m],styles:[""]}),t})();var An=r(13472);let Ye=(()=>{class t{constructor(_,n){this.activeModal=_,this.actionLabels=n,this.resource="Swift Key",this.action=this.actionLabels.SHOW}setValues(_,n){this.user=_,this.secret_key=n}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(M.Kz),e.Y36(A.p4))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-rgw-user-swift-key-modal"]],decls:24,vars:11,consts:function(){let o,_,n;return o="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",_="Username",n="Secret key",[[3,"modalRef"],[1,"modal-title"],o,[1,"modal-content"],[1,"modal-body"],["novalidate",""],[1,"form-group","row"],["for","user",1,"cd-col-form-label"],_,[1,"cd-col-form-input"],["id","user","name","user","type","text",1,"form-control",3,"readonly","ngModel","ngModelChange"],["for","secret_key",1,"cd-col-form-label"],n,[1,"input-group"],["id","secret_key","name","secret_key","type","password",1,"form-control",3,"ngModel","readonly","ngModelChange"],[1,"input-group-append"],["type","button","cdPasswordButton","secret_key",1,"btn","btn-light"],["source","secret_key"],[1,"modal-footer"],[3,"backAction"]]},template:function(_,n){1&_&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.ALo(3,"titlecase"),e.ALo(4,"upperFirst"),e.BQk(),e.ynx(5,3),e.TgZ(6,"div",4),e.TgZ(7,"form",5),e.TgZ(8,"div",6),e.TgZ(9,"label",7),e.SDv(10,8),e.qZA(),e.TgZ(11,"div",9),e.TgZ(12,"input",10),e.NdJ("ngModelChange",function(s){return n.user=s}),e.qZA(),e.qZA(),e.qZA(),e.TgZ(13,"div",6),e.TgZ(14,"label",11),e.SDv(15,12),e.qZA(),e.TgZ(16,"div",9),e.TgZ(17,"div",13),e.TgZ(18,"input",14),e.NdJ("ngModelChange",function(s){return n.secret_key=s}),e.qZA(),e.TgZ(19,"span",15),e._UZ(20,"button",16),e._UZ(21,"cd-copy-2-clipboard-button",17),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(22,"div",18),e.TgZ(23,"cd-back-button",19),e.NdJ("backAction",function(){return n.activeModal.close()}),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&_&&(e.Q6J("modalRef",n.activeModal),e.xp6(4),e.pQV(e.lcZ(3,7,n.action))(e.lcZ(4,9,n.resource)),e.QtT(2),e.xp6(8),e.Q6J("readonly",!0)("ngModel",n.user),e.xp6(6),e.Q6J("ngModel",n.secret_key)("readonly",!0))},directives:[fe.z,a._Y,a.JL,a.F,H.P,q.o,a.Fj,X.b,a.JJ,a.On,Ce.C,pe.s,An.W],pipes:[f.rS,K.m],styles:[""]}),t})();var bn=r(17932);function Pn(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,50),e.qZA())}function Gn(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,51),e.qZA())}function Nn(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,52),e.qZA())}function On(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,56),e.qZA())}function Un(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,57),e.qZA())}function Wn(t,o){if(1&t&&(e.TgZ(0,"div",8),e.TgZ(1,"label",53),e.SDv(2,54),e.qZA(),e.TgZ(3,"div",11),e._UZ(4,"input",55),e.YNc(5,On,2,0,"span",13),e.YNc(6,Un,2,0,"span",13),e.qZA(),e.qZA()),2&t){e.oxw();const _=e.MAs(2),n=e.oxw();e.xp6(4),e.Q6J("readonly",n.editing),e.xp6(1),e.Q6J("ngIf",n.userForm.showError("tenant",_,"pattern")),e.xp6(1),e.Q6J("ngIf",n.userForm.showError("tenant",_,"notUnique"))}}function Zn(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,58),e.qZA())}function $n(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,59),e.qZA())}function hn(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,60),e.qZA())}function In(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,63),e.qZA())}function vn(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,64),e.qZA())}function Fn(t,o){if(1&t&&(e.TgZ(0,"div",8),e._UZ(1,"label",61),e.TgZ(2,"div",11),e._UZ(3,"input",62),e.YNc(4,In,2,0,"span",13),e.YNc(5,vn,2,0,"span",13),e.qZA(),e.qZA()),2&t){e.oxw();const _=e.MAs(2),n=e.oxw();e.xp6(4),e.Q6J("ngIf",n.userForm.showError("max_buckets",_,"required")),e.xp6(1),e.Q6J("ngIf",n.userForm.showError("max_buckets",_,"min"))}}function Ln(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,76),e.qZA())}function Dn(t,o){if(1&t&&(e.TgZ(0,"div",8),e.TgZ(1,"label",69),e.SDv(2,70),e.qZA(),e.TgZ(3,"div",11),e.TgZ(4,"div",71),e._UZ(5,"input",72),e.TgZ(6,"span",73),e._UZ(7,"button",74),e._UZ(8,"cd-copy-2-clipboard-button",75),e.qZA(),e.qZA(),e.YNc(9,Ln,2,0,"span",13),e.qZA(),e.qZA()),2&t){e.oxw(2);const _=e.MAs(2),n=e.oxw();e.xp6(9),e.Q6J("ngIf",n.userForm.showError("access_key",_,"required"))}}function xn(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,82),e.qZA())}function yn(t,o){if(1&t&&(e.TgZ(0,"div",8),e.TgZ(1,"label",77),e.SDv(2,78),e.qZA(),e.TgZ(3,"div",11),e.TgZ(4,"div",71),e._UZ(5,"input",79),e.TgZ(6,"span",73),e._UZ(7,"button",80),e._UZ(8,"cd-copy-2-clipboard-button",81),e.qZA(),e.qZA(),e.YNc(9,xn,2,0,"span",13),e.qZA(),e.qZA()),2&t){e.oxw(2);const _=e.MAs(2),n=e.oxw();e.xp6(9),e.Q6J("ngIf",n.userForm.showError("secret_key",_,"required"))}}function qn(t,o){if(1&t&&(e.TgZ(0,"fieldset"),e.TgZ(1,"legend"),e.SDv(2,65),e.qZA(),e.TgZ(3,"div",8),e.TgZ(4,"div",14),e.TgZ(5,"div",15),e._UZ(6,"input",66),e.TgZ(7,"label",67),e.SDv(8,68),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(9,Dn,10,1,"div",19),e.YNc(10,yn,10,1,"div",19),e.qZA()),2&t){const _=e.oxw(2);e.xp6(9),e.Q6J("ngIf",!_.editing&&!_.userForm.getValue("generate_key")),e.xp6(1),e.Q6J("ngIf",!_.editing&&!_.userForm.getValue("generate_key"))}}function wn(t,o){1&t&&(e.TgZ(0,"span",92),e.TgZ(1,"span",93),e.SDv(2,94),e.qZA(),e.qZA())}const L=function(t){return[t]};function kn(t,o){if(1&t){const _=e.EpF();e.TgZ(0,"span"),e.TgZ(1,"div",71),e.TgZ(2,"div",95),e.TgZ(3,"span",96),e._UZ(4,"i"),e.qZA(),e.qZA(),e._UZ(5,"input",97),e.TgZ(6,"div",98),e.TgZ(7,"span",96),e._UZ(8,"i"),e.qZA(),e.qZA(),e._UZ(9,"input",97),e.TgZ(10,"span",73),e.TgZ(11,"button",99),e.NdJ("click",function(){const s=e.CHM(_).index;return e.oxw(3).showSubuserModal(s)}),e._UZ(12,"i",89),e.qZA(),e.TgZ(13,"button",100),e.NdJ("click",function(){const s=e.CHM(_).index;return e.oxw(3).deleteSubuser(s)}),e._UZ(14,"i",89),e.qZA(),e.qZA(),e.qZA(),e._UZ(15,"span",93),e.qZA()}if(2&t){const _=o.$implicit,n=e.oxw(3);e.xp6(4),e.Tol(n.icons.user),e.xp6(1),e.s9C("value",_.id),e.xp6(3),e.Tol(n.icons.share),e.xp6(1),e.s9C("value","full-control"===_.permissions?"full":_.permissions),e.xp6(3),e.Q6J("ngClass",e.VKq(10,L,n.icons.edit)),e.xp6(2),e.Q6J("ngClass",e.VKq(12,L,n.icons.destroy))}}function Bn(t,o){if(1&t){const _=e.EpF();e.TgZ(0,"fieldset"),e.TgZ(1,"legend"),e.SDv(2,83),e.qZA(),e.TgZ(3,"div",84),e.TgZ(4,"div",14),e.YNc(5,wn,3,0,"span",85),e.YNc(6,kn,16,14,"span",86),e.TgZ(7,"div",84),e.TgZ(8,"div",87),e.TgZ(9,"button",88),e.NdJ("click",function(){return e.CHM(_),e.oxw(2).showSubuserModal()}),e._UZ(10,"i",89),e.ynx(11),e.SDv(12,90),e.ALo(13,"titlecase"),e.ALo(14,"upperFirst"),e.BQk(),e.qZA(),e.qZA(),e.qZA(),e._UZ(15,"span",91),e.qZA(),e.qZA(),e.qZA()}if(2&t){const _=e.oxw(2);e.xp6(5),e.Q6J("ngIf",0===_.subusers.length),e.xp6(1),e.Q6J("ngForOf",_.subusers),e.xp6(4),e.Q6J("ngClass",e.VKq(9,L,_.icons.add)),e.xp6(4),e.pQV(e.lcZ(13,5,_.actionLabels.CREATE))(e.lcZ(14,7,_.subuserLabel)),e.QtT(12)}}function Hn(t,o){1&t&&(e.TgZ(0,"span",92),e.TgZ(1,"span",93),e.SDv(2,106),e.qZA(),e.qZA())}function Xn(t,o){if(1&t){const _=e.EpF();e.TgZ(0,"span"),e.TgZ(1,"div",71),e.TgZ(2,"div",95),e.TgZ(3,"div",96),e._UZ(4,"i"),e.qZA(),e.qZA(),e._UZ(5,"input",97),e.TgZ(6,"span",73),e.TgZ(7,"button",107),e.NdJ("click",function(){const s=e.CHM(_).index;return e.oxw(3).showS3KeyModal(s)}),e._UZ(8,"i",89),e.qZA(),e.TgZ(9,"button",108),e.NdJ("click",function(){const s=e.CHM(_).index;return e.oxw(3).deleteS3Key(s)}),e._UZ(10,"i",89),e.qZA(),e.qZA(),e.qZA(),e._UZ(11,"span",93),e.qZA()}if(2&t){const _=o.$implicit,n=e.oxw(3);e.xp6(4),e.Tol(n.icons.key),e.xp6(1),e.s9C("value",_.user),e.xp6(3),e.Q6J("ngClass",e.VKq(6,L,n.icons.show)),e.xp6(2),e.Q6J("ngClass",e.VKq(8,L,n.icons.destroy))}}function Kn(t,o){1&t&&(e.TgZ(0,"span",92),e.TgZ(1,"span",93),e.SDv(2,109),e.qZA(),e.qZA())}function zn(t,o){if(1&t){const _=e.EpF();e.TgZ(0,"span"),e.TgZ(1,"div",71),e.TgZ(2,"div",95),e.TgZ(3,"span",96),e._UZ(4,"i"),e.qZA(),e.qZA(),e._UZ(5,"input",97),e.TgZ(6,"span",73),e.TgZ(7,"button",110),e.NdJ("click",function(){const s=e.CHM(_).index;return e.oxw(3).showSwiftKeyModal(s)}),e._UZ(8,"i",89),e.qZA(),e.qZA(),e.qZA(),e._UZ(9,"span",93),e.qZA()}if(2&t){const _=o.$implicit,n=e.oxw(3);e.xp6(4),e.Tol(n.icons.key),e.xp6(1),e.s9C("value",_.user),e.xp6(3),e.Q6J("ngClass",e.VKq(5,L,n.icons.show))}}function Qn(t,o){if(1&t){const _=e.EpF();e.TgZ(0,"fieldset"),e.TgZ(1,"legend"),e.SDv(2,101),e.qZA(),e.TgZ(3,"div",8),e.TgZ(4,"label",61),e.SDv(5,102),e.qZA(),e.TgZ(6,"div",11),e.YNc(7,Hn,3,0,"span",85),e.YNc(8,Xn,12,10,"span",86),e.TgZ(9,"div",84),e.TgZ(10,"div",87),e.TgZ(11,"button",103),e.NdJ("click",function(){return e.CHM(_),e.oxw(2).showS3KeyModal()}),e._UZ(12,"i",89),e.ynx(13),e.SDv(14,104),e.ALo(15,"titlecase"),e.ALo(16,"upperFirst"),e.BQk(),e.qZA(),e.qZA(),e.qZA(),e._UZ(17,"span",91),e.qZA(),e._UZ(18,"hr"),e.qZA(),e.TgZ(19,"div",8),e.TgZ(20,"label",61),e.SDv(21,105),e.qZA(),e.TgZ(22,"div",11),e.YNc(23,Kn,3,0,"span",85),e.YNc(24,zn,10,7,"span",86),e.qZA(),e.qZA(),e.qZA()}if(2&t){const _=e.oxw(2);e.xp6(7),e.Q6J("ngIf",0===_.s3Keys.length),e.xp6(1),e.Q6J("ngForOf",_.s3Keys),e.xp6(4),e.Q6J("ngClass",e.VKq(11,L,_.icons.add)),e.xp6(4),e.pQV(e.lcZ(15,7,_.actionLabels.CREATE))(e.lcZ(16,9,_.s3keyLabel)),e.QtT(14),e.xp6(7),e.Q6J("ngIf",0===_.swiftKeys.length),e.xp6(1),e.Q6J("ngForOf",_.swiftKeys)}}function Yn(t,o){1&t&&(e.TgZ(0,"span",92),e.TgZ(1,"span",93),e.SDv(2,114),e.qZA(),e.qZA())}function Jn(t,o){if(1&t){const _=e.EpF();e.TgZ(0,"span"),e.TgZ(1,"div",71),e.TgZ(2,"span",95),e.TgZ(3,"div",96),e._UZ(4,"i"),e.qZA(),e.qZA(),e._UZ(5,"input",97),e.TgZ(6,"span",73),e.TgZ(7,"button",115),e.NdJ("click",function(){const s=e.CHM(_).index;return e.oxw(3).showCapabilityModal(s)}),e._UZ(8,"i",89),e.qZA(),e.TgZ(9,"button",116),e.NdJ("click",function(){const s=e.CHM(_).index;return e.oxw(3).deleteCapability(s)}),e._UZ(10,"i",89),e.qZA(),e.qZA(),e.qZA(),e._UZ(11,"span",93),e.qZA()}if(2&t){const _=o.$implicit,n=e.oxw(3);e.xp6(4),e.Tol(n.icons.share),e.xp6(1),e.hYB("value","",_.type,":",_.perm,""),e.xp6(3),e.Q6J("ngClass",e.VKq(7,L,n.icons.edit)),e.xp6(2),e.Q6J("ngClass",e.VKq(9,L,n.icons.destroy))}}function Vn(t,o){if(1&t){const _=e.EpF();e.TgZ(0,"fieldset"),e.TgZ(1,"legend"),e.SDv(2,111),e.qZA(),e.TgZ(3,"div",8),e.TgZ(4,"div",14),e.YNc(5,Yn,3,0,"span",85),e.YNc(6,Jn,12,11,"span",86),e.TgZ(7,"div",84),e.TgZ(8,"div",87),e.TgZ(9,"button",112),e.NdJ("click",function(){return e.CHM(_),e.oxw(2).showCapabilityModal()}),e.ALo(10,"pipeFunction"),e.ALo(11,"pipeFunction"),e._UZ(12,"i",89),e.ynx(13),e.SDv(14,113),e.ALo(15,"titlecase"),e.ALo(16,"upperFirst"),e.BQk(),e.qZA(),e.qZA(),e.qZA(),e._UZ(17,"span",91),e.qZA(),e.qZA(),e.qZA()}if(2&t){const _=e.oxw(2);e.xp6(5),e.Q6J("ngIf",0===_.capabilities.length),e.xp6(1),e.Q6J("ngForOf",_.capabilities),e.xp6(3),e.Q6J("disabled",e.xi3(10,7,_.capabilities,_.hasAllCapabilities))("disableTooltip",!e.xi3(11,10,_.capabilities,_.hasAllCapabilities)),e.xp6(3),e.Q6J("ngClass",e.VKq(17,L,_.icons.add)),e.xp6(4),e.pQV(e.lcZ(15,13,_.actionLabels.ADD))(e.lcZ(16,15,_.capabilityLabel)),e.QtT(14)}}function jn(t,o){1&t&&(e.TgZ(0,"div",8),e.TgZ(1,"div",14),e.TgZ(2,"div",15),e._UZ(3,"input",117),e.TgZ(4,"label",118),e.SDv(5,119),e.qZA(),e.qZA(),e.qZA(),e.qZA())}function eo(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,123),e.qZA())}function _o(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,124),e.qZA())}function to(t,o){if(1&t&&(e.TgZ(0,"div",8),e.TgZ(1,"label",120),e.SDv(2,121),e.qZA(),e.TgZ(3,"div",11),e._UZ(4,"input",122),e.YNc(5,eo,2,0,"span",13),e.YNc(6,_o,2,0,"span",13),e.qZA(),e.qZA()),2&t){e.oxw();const _=e.MAs(2),n=e.oxw();e.xp6(5),e.Q6J("ngIf",n.userForm.showError("user_quota_max_size",_,"required")),e.xp6(1),e.Q6J("ngIf",n.userForm.showError("user_quota_max_size",_,"quotaMaxSize"))}}function no(t,o){1&t&&(e.TgZ(0,"div",8),e.TgZ(1,"div",14),e.TgZ(2,"div",15),e._UZ(3,"input",125),e.TgZ(4,"label",126),e.SDv(5,127),e.qZA(),e.qZA(),e.qZA(),e.qZA())}function oo(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,131),e.qZA())}function io(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,132),e.qZA())}function so(t,o){if(1&t&&(e.TgZ(0,"div",8),e.TgZ(1,"label",128),e.SDv(2,129),e.qZA(),e.TgZ(3,"div",11),e._UZ(4,"input",130),e.YNc(5,oo,2,0,"span",13),e.YNc(6,io,2,0,"span",13),e.qZA(),e.qZA()),2&t){e.oxw();const _=e.MAs(2),n=e.oxw();e.xp6(5),e.Q6J("ngIf",n.userForm.showError("user_quota_max_objects",_,"required")),e.xp6(1),e.Q6J("ngIf",n.userForm.showError("user_quota_max_objects",_,"min"))}}function ao(t,o){1&t&&(e.TgZ(0,"div",8),e.TgZ(1,"div",14),e.TgZ(2,"div",15),e._UZ(3,"input",133),e.TgZ(4,"label",134),e.SDv(5,135),e.qZA(),e.qZA(),e.qZA(),e.qZA())}function ro(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,139),e.qZA())}function lo(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,140),e.qZA())}function co(t,o){if(1&t&&(e.TgZ(0,"div",8),e.TgZ(1,"label",136),e.SDv(2,137),e.qZA(),e.TgZ(3,"div",11),e._UZ(4,"input",138),e.YNc(5,ro,2,0,"span",13),e.YNc(6,lo,2,0,"span",13),e.qZA(),e.qZA()),2&t){e.oxw();const _=e.MAs(2),n=e.oxw();e.xp6(5),e.Q6J("ngIf",n.userForm.showError("bucket_quota_max_size",_,"required")),e.xp6(1),e.Q6J("ngIf",n.userForm.showError("bucket_quota_max_size",_,"quotaMaxSize"))}}function uo(t,o){1&t&&(e.TgZ(0,"div",8),e.TgZ(1,"div",14),e.TgZ(2,"div",15),e._UZ(3,"input",141),e.TgZ(4,"label",142),e.SDv(5,143),e.qZA(),e.qZA(),e.qZA(),e.qZA())}function Ro(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,147),e.qZA())}function go(t,o){1&t&&(e.TgZ(0,"span",49),e.SDv(1,148),e.qZA())}function Eo(t,o){if(1&t&&(e.TgZ(0,"div",8),e.TgZ(1,"label",144),e.SDv(2,145),e.qZA(),e.TgZ(3,"div",11),e._UZ(4,"input",146),e.YNc(5,Ro,2,0,"span",13),e.YNc(6,go,2,0,"span",13),e.qZA(),e.qZA()),2&t){e.oxw();const _=e.MAs(2),n=e.oxw();e.xp6(5),e.Q6J("ngIf",n.userForm.showError("bucket_quota_max_objects",_,"required")),e.xp6(1),e.Q6J("ngIf",n.userForm.showError("bucket_quota_max_objects",_,"min"))}}const Je=function(t){return{required:t}};function To(t,o){if(1&t){const _=e.EpF();e.TgZ(0,"div",1),e.TgZ(1,"form",2,3),e.TgZ(3,"div",4),e.TgZ(4,"div",5),e.SDv(5,6),e.ALo(6,"titlecase"),e.ALo(7,"upperFirst"),e.qZA(),e.TgZ(8,"div",7),e.TgZ(9,"div",8),e.TgZ(10,"label",9),e.SDv(11,10),e.qZA(),e.TgZ(12,"div",11),e._UZ(13,"input",12),e.YNc(14,Pn,2,0,"span",13),e.YNc(15,Gn,2,0,"span",13),e.YNc(16,Nn,2,0,"span",13),e.qZA(),e.qZA(),e.TgZ(17,"div",8),e.TgZ(18,"div",14),e.TgZ(19,"div",15),e.TgZ(20,"input",16),e.NdJ("click",function(){return e.CHM(_),e.oxw().updateFieldsWhenTenanted()}),e.qZA(),e.TgZ(21,"label",17),e.SDv(22,18),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(23,Wn,7,3,"div",19),e.TgZ(24,"div",8),e.TgZ(25,"label",20),e.SDv(26,21),e.qZA(),e.TgZ(27,"div",11),e._UZ(28,"input",22),e.YNc(29,Zn,2,0,"span",13),e.qZA(),e.qZA(),e.TgZ(30,"div",8),e.TgZ(31,"label",23),e.SDv(32,24),e.qZA(),e.TgZ(33,"div",11),e._UZ(34,"input",25),e.YNc(35,$n,2,0,"span",13),e.YNc(36,hn,2,0,"span",13),e.qZA(),e.qZA(),e.TgZ(37,"div",8),e.TgZ(38,"label",26),e.SDv(39,27),e.qZA(),e.TgZ(40,"div",11),e.TgZ(41,"select",28),e.NdJ("change",function(i){return e.CHM(_),e.oxw().onMaxBucketsModeChange(i.target.value)}),e.TgZ(42,"option",29),e.SDv(43,30),e.qZA(),e.TgZ(44,"option",31),e.SDv(45,32),e.qZA(),e.TgZ(46,"option",33),e.SDv(47,34),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(48,Fn,6,2,"div",19),e.TgZ(49,"div",8),e.TgZ(50,"div",14),e.TgZ(51,"div",15),e._UZ(52,"input",35),e.TgZ(53,"label",36),e.SDv(54,37),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(55,qn,11,2,"fieldset",38),e.YNc(56,Bn,16,11,"fieldset",38),e.YNc(57,Qn,25,13,"fieldset",38),e.YNc(58,Vn,18,19,"fieldset",38),e.TgZ(59,"fieldset"),e.TgZ(60,"legend"),e.SDv(61,39),e.qZA(),e.TgZ(62,"div",8),e.TgZ(63,"div",14),e.TgZ(64,"div",15),e._UZ(65,"input",40),e.TgZ(66,"label",41),e.SDv(67,42),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(68,jn,6,0,"div",19),e.YNc(69,to,7,2,"div",19),e.YNc(70,no,6,0,"div",19),e.YNc(71,so,7,2,"div",19),e.qZA(),e.TgZ(72,"fieldset"),e.TgZ(73,"legend"),e.SDv(74,43),e.qZA(),e.TgZ(75,"div",8),e.TgZ(76,"div",14),e.TgZ(77,"div",15),e._UZ(78,"input",44),e.TgZ(79,"label",45),e.SDv(80,46),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(81,ao,6,0,"div",19),e.YNc(82,co,7,2,"div",19),e.YNc(83,uo,6,0,"div",19),e.YNc(84,Eo,7,2,"div",19),e.qZA(),e.qZA(),e.TgZ(85,"div",47),e.TgZ(86,"cd-form-button-panel",48),e.NdJ("submitActionEvent",function(){return e.CHM(_),e.oxw().onSubmit()}),e.ALo(87,"titlecase"),e.ALo(88,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&t){const _=e.MAs(2),n=e.oxw();e.xp6(1),e.Q6J("formGroup",n.userForm),e.xp6(6),e.pQV(e.lcZ(6,29,n.action))(e.lcZ(7,31,n.resource)),e.QtT(5),e.xp6(3),e.Q6J("ngClass",e.VKq(37,Je,!n.editing)),e.xp6(3),e.Q6J("readonly",n.editing),e.xp6(1),e.Q6J("ngIf",n.userForm.showError("user_id",_,"required")),e.xp6(1),e.Q6J("ngIf",n.userForm.showError("user_id",_,"pattern")),e.xp6(1),e.Q6J("ngIf",!n.userForm.getValue("show_tenant")&&n.userForm.showError("user_id",_,"notUnique")),e.xp6(4),e.Q6J("readonly",!0),e.xp6(3),e.Q6J("ngIf",n.userForm.getValue("show_tenant")),e.xp6(2),e.Q6J("ngClass",e.VKq(39,Je,!n.editing)),e.xp6(4),e.Q6J("ngIf",n.userForm.showError("display_name",_,"required")),e.xp6(6),e.Q6J("ngIf",n.userForm.showError("email",_,"email")),e.xp6(1),e.Q6J("ngIf",n.userForm.showError("email",_,"notUnique")),e.xp6(12),e.Q6J("ngIf",1==n.userForm.get("max_buckets_mode").value),e.xp6(7),e.Q6J("ngIf",!n.editing),e.xp6(1),e.Q6J("ngIf",n.editing),e.xp6(1),e.Q6J("ngIf",n.editing),e.xp6(1),e.Q6J("ngIf",n.editing),e.xp6(10),e.Q6J("ngIf",n.userForm.controls.user_quota_enabled.value),e.xp6(1),e.Q6J("ngIf",n.userForm.controls.user_quota_enabled.value&&!n.userForm.getValue("user_quota_max_size_unlimited")),e.xp6(1),e.Q6J("ngIf",n.userForm.controls.user_quota_enabled.value),e.xp6(1),e.Q6J("ngIf",n.userForm.controls.user_quota_enabled.value&&!n.userForm.getValue("user_quota_max_objects_unlimited")),e.xp6(10),e.Q6J("ngIf",n.userForm.controls.bucket_quota_enabled.value),e.xp6(1),e.Q6J("ngIf",n.userForm.controls.bucket_quota_enabled.value&&!n.userForm.getValue("bucket_quota_max_size_unlimited")),e.xp6(1),e.Q6J("ngIf",n.userForm.controls.bucket_quota_enabled.value),e.xp6(1),e.Q6J("ngIf",n.userForm.controls.bucket_quota_enabled.value&&!n.userForm.getValue("bucket_quota_max_objects_unlimited")),e.xp6(2),e.Q6J("form",n.userForm)("submitText",e.lcZ(87,33,n.action)+" "+e.lcZ(88,35,n.resource))}}let Ve=(()=>{class t extends Ie.E{constructor(_,n,i,s,c,d,E){super(),this.formBuilder=_,this.route=n,this.router=i,this.rgwUserService=s,this.modalService=c,this.notificationService=d,this.actionLabels=E,this.editing=!1,this.submitObservables=[],this.icons=D.P,this.subusers=[],this.s3Keys=[],this.swiftKeys=[],this.capabilities=[],this.showTenant=!1,this.previousTenant=null,this.resource="user",this.subuserLabel="subuser",this.s3keyLabel="S3 Key",this.capabilityLabel="capability",this.editing=this.router.url.startsWith(`/rgw/user/${A.MQ.EDIT}`),this.action=this.editing?this.actionLabels.EDIT:this.actionLabels.CREATE,this.createForm()}createForm(){this.userForm=this.formBuilder.group({user_id:[null,[a.kI.required,a.kI.pattern(/^[a-zA-Z0-9!@#%^&*()_-]+$/)],this.editing?[]:[m.h.unique(this.rgwUserService.exists,this.rgwUserService,()=>this.userForm.getValue("tenant"))]],show_tenant:[this.editing],tenant:[null,[a.kI.pattern(/^[a-zA-Z0-9!@#%^&*()_-]+$/)],this.editing?[]:[m.h.unique(this.rgwUserService.exists,this.rgwUserService,()=>this.userForm.getValue("user_id"),!0)]],display_name:[null,[a.kI.required]],email:[null,[m.h.email],[m.h.unique(this.rgwUserService.emailExists,this.rgwUserService)]],max_buckets_mode:[1],max_buckets:[1e3,[m.h.requiredIf({max_buckets_mode:"1"}),m.h.number(!1)]],suspended:[!1],generate_key:[!0],access_key:[null,[m.h.requiredIf({generate_key:!1})]],secret_key:[null,[m.h.requiredIf({generate_key:!1})]],user_quota_enabled:[!1],user_quota_max_size_unlimited:[!0],user_quota_max_size:[null,[m.h.composeIf({user_quota_enabled:!0,user_quota_max_size_unlimited:!1},[a.kI.required,this.quotaMaxSizeValidator])]],user_quota_max_objects_unlimited:[!0],user_quota_max_objects:[null,[m.h.requiredIf({user_quota_enabled:!0,user_quota_max_objects_unlimited:!1})]],bucket_quota_enabled:[!1],bucket_quota_max_size_unlimited:[!0],bucket_quota_max_size:[null,[m.h.composeIf({bucket_quota_enabled:!0,bucket_quota_max_size_unlimited:!1},[a.kI.required,this.quotaMaxSizeValidator])]],bucket_quota_max_objects_unlimited:[!0],bucket_quota_max_objects:[null,[m.h.requiredIf({bucket_quota_enabled:!0,bucket_quota_max_objects_unlimited:!1})]]})}ngOnInit(){this.route.params.subscribe(_=>{if(!_.hasOwnProperty("uid"))return void this.loadingReady();const n=decodeURIComponent(_.uid),i=[];i.push(this.rgwUserService.get(n)),i.push(this.rgwUserService.getQuota(n)),(0,Y.D)(i).subscribe(s=>{const c=u().clone(this.userForm.value);let d=u().pick(s[0],u().keys(this.userForm.value));switch(d.max_buckets){case-1:d.max_buckets_mode=-1,d.max_buckets="";break;case 0:d.max_buckets_mode=0,d.max_buckets="";break;default:d.max_buckets_mode=1}["user","bucket"].forEach(g=>{const C=s[1][g+"_quota"];d[g+"_quota_enabled"]=C.enabled,C.max_size<0?(d[g+"_quota_max_size_unlimited"]=!0,d[g+"_quota_max_size"]=null):(d[g+"_quota_max_size_unlimited"]=!1,d[g+"_quota_max_size"]=`${C.max_size} B`),C.max_objects<0?(d[g+"_quota_max_objects_unlimited"]=!0,d[g+"_quota_max_objects"]=null):(d[g+"_quota_max_objects_unlimited"]=!1,d[g+"_quota_max_objects"]=C.max_objects)}),d=u().merge(c,d),this.userForm.setValue(d),this.subusers=s[0].subusers,this.s3Keys=s[0].keys,this.swiftKeys=s[0].swift_keys;const E={"read, write":"*"};s[0].caps.forEach(g=>{g.perm in E&&(g.perm=E[g.perm])}),this.capabilities=s[0].caps,this.loadingReady()},()=>{this.loadingError()})})}goToListView(){this.router.navigate(["/rgw/user"])}onSubmit(){let _;if(this.userForm.pristine)return void this.goToListView();const n=this.getUID();if(this.editing){if(this._isGeneralDirty()){const i=this._getUpdateArgs();this.submitObservables.push(this.rgwUserService.update(n,i))}_="Updated Object Gateway user '" + n + "'"}else{const i=this._getCreateArgs();this.submitObservables.push(this.rgwUserService.create(i)),_="Created Object Gateway user '" + n + "'"}if(this._isUserQuotaDirty()){const i=this._getUserQuotaArgs();this.submitObservables.push(this.rgwUserService.updateQuota(n,i))}if(this._isBucketQuotaDirty()){const i=this._getBucketQuotaArgs();this.submitObservables.push(this.rgwUserService.updateQuota(n,i))}(0,Bt.z)(...this.submitObservables).subscribe({error:()=>{this.userForm.setErrors({cdSubmitButton:!0})},complete:()=>{this.notificationService.show(Ae.k.success,_),this.goToListView()}})}updateFieldsWhenTenanted(){this.showTenant=this.userForm.getValue("show_tenant"),this.showTenant?(this.userForm.get("user_id").markAsTouched(),this.previousTenant=this.userForm.get("tenant").value,this.userForm.get("tenant").patchValue(null)):(this.userForm.get("user_id").markAsUntouched(),this.userForm.get("tenant").patchValue(this.previousTenant))}getUID(){var _;let n=this.userForm.getValue("user_id");const i=null===(_=this.userForm)||void 0===_?void 0:_.getValue("tenant");return i&&i.length>0&&(n=`${this.userForm.getValue("tenant")}$${n}`),n}quotaMaxSizeValidator(_){return(0,m.P)(_.value)?null:null===RegExp("^(\\d+(\\.\\d+)?)\\s*(B|K(B|iB)?|M(B|iB)?|G(B|iB)?|T(B|iB)?)?$","i").exec(_.value)||(new Ge.H).toBytes(_.value)<1024?{quotaMaxSize:!0}:null}setSubuser(_,n){const i={"full-control":"full","read-write":"readwrite"},s=this.getUID();this.submitObservables.push(this.rgwUserService.createSubuser(s,{subuser:_.id,access:_.permissions in i?i[_.permissions]:_.permissions,key_type:"swift",secret_key:_.secret_key,generate_secret:_.generate_secret?"true":"false"})),u().isNumber(n)?this.subusers[n]=_:(this.subusers.push(_),this.swiftKeys.push({user:_.id,secret_key:_.generate_secret?"Apply your changes first...":_.secret_key})),this.userForm.markAsDirty()}deleteSubuser(_){const n=this.subusers[_];this.submitObservables.push(this.rgwUserService.deleteSubuser(this.getUID(),n.id)),this.s3Keys=this.s3Keys.filter(i=>i.user!==n.id),this.swiftKeys=this.swiftKeys.filter(i=>i.user!==n.id),this.subusers.splice(_,1),this.userForm.markAsDirty()}setCapability(_,n){const i=this.getUID();if(u().isNumber(n)){const s=this.capabilities[n];this.submitObservables.push(this.rgwUserService.deleteCapability(i,s.type,s.perm)),this.submitObservables.push(this.rgwUserService.addCapability(i,_.type,_.perm)),this.capabilities[n]=_}else this.submitObservables.push(this.rgwUserService.addCapability(i,_.type,_.perm)),this.capabilities=[...this.capabilities,_];this.userForm.markAsDirty()}deleteCapability(_){const n=this.capabilities[_];this.submitObservables.push(this.rgwUserService.deleteCapability(this.getUID(),n.type,n.perm)),this.capabilities.splice(_,1),this.capabilities=[...this.capabilities],this.userForm.markAsDirty()}hasAllCapabilities(_){return!u().difference(ze.getAll(),u().map(_,"type")).length}setS3Key(_,n){if(!u().isNumber(n)){const i=_.user.match(/([^:]+)(:(.+))?/),s=i[1],c={subuser:i[2]?i[3]:"",generate_key:_.generate_key?"true":"false"};"false"===c.generate_key&&(u().isNil(_.access_key)||(c.access_key=_.access_key),u().isNil(_.secret_key)||(c.secret_key=_.secret_key)),this.submitObservables.push(this.rgwUserService.addS3Key(s,c)),this.s3Keys.push({user:_.user,access_key:_.generate_key?"Apply your changes first...":_.access_key,secret_key:_.generate_key?"Apply your changes first...":_.secret_key})}this.userForm.markAsDirty()}deleteS3Key(_){const n=this.s3Keys[_];this.submitObservables.push(this.rgwUserService.deleteS3Key(this.getUID(),n.access_key)),this.s3Keys.splice(_,1),this.userForm.markAsDirty()}showSubuserModal(_){const n=this.getUID(),i=this.modalService.show(mn);if(u().isNumber(_)){const s=this.subusers[_];i.componentInstance.setEditing(),i.componentInstance.setValues(n,s.id,s.permissions)}else i.componentInstance.setEditing(!1),i.componentInstance.setValues(n),i.componentInstance.setSubusers(this.subusers);i.componentInstance.submitAction.subscribe(s=>{this.setSubuser(s,_)})}showS3KeyModal(_){const n=this.modalService.show(Qe);if(u().isNumber(_)){const i=this.s3Keys[_];n.componentInstance.setViewing(),n.componentInstance.setValues(i.user,i.access_key,i.secret_key)}else{const i=this._getS3KeyUserCandidates();n.componentInstance.setViewing(!1),n.componentInstance.setUserCandidates(i),n.componentInstance.submitAction.subscribe(s=>{this.setS3Key(s)})}}showSwiftKeyModal(_){const n=this.modalService.show(Ye),i=this.swiftKeys[_];n.componentInstance.setValues(i.user,i.secret_key)}showCapabilityModal(_){const n=this.modalService.show(en);if(u().isNumber(_)){const i=this.capabilities[_];n.componentInstance.setEditing(),n.componentInstance.setValues(i.type,i.perm)}else n.componentInstance.setEditing(!1),n.componentInstance.setCapabilities(this.capabilities);n.componentInstance.submitAction.subscribe(i=>{this.setCapability(i,_)})}_isGeneralDirty(){return["display_name","email","max_buckets_mode","max_buckets","suspended"].some(_=>this.userForm.get(_).dirty)}_isUserQuotaDirty(){return["user_quota_enabled","user_quota_max_size_unlimited","user_quota_max_size","user_quota_max_objects_unlimited","user_quota_max_objects"].some(_=>this.userForm.get(_).dirty)}_isBucketQuotaDirty(){return["bucket_quota_enabled","bucket_quota_max_size_unlimited","bucket_quota_max_size","bucket_quota_max_objects_unlimited","bucket_quota_max_objects"].some(_=>this.userForm.get(_).dirty)}_getCreateArgs(){const _={uid:this.getUID(),display_name:this.userForm.getValue("display_name"),suspended:this.userForm.getValue("suspended"),email:"",max_buckets:this.userForm.getValue("max_buckets"),generate_key:this.userForm.getValue("generate_key"),access_key:"",secret_key:""},n=this.userForm.getValue("email");u().isString(n)&&n.length>0&&u().merge(_,{email:n}),this.userForm.getValue("generate_key")||u().merge(_,{generate_key:!1,access_key:this.userForm.getValue("access_key"),secret_key:this.userForm.getValue("secret_key")});const s=parseInt(this.userForm.getValue("max_buckets_mode"),10);return u().includes([-1,0],s)&&u().merge(_,{max_buckets:s}),_}_getUpdateArgs(){const _={},n=["display_name","email","max_buckets","suspended"];for(const s of n)_[s]=this.userForm.getValue(s);const i=parseInt(this.userForm.getValue("max_buckets_mode"),10);return u().includes([-1,0],i)&&(_.max_buckets=i),_}_getUserQuotaArgs(){const _={quota_type:"user",enabled:this.userForm.getValue("user_quota_enabled"),max_size_kb:-1,max_objects:-1};if(!this.userForm.getValue("user_quota_max_size_unlimited")){const n=(new Ge.H).toBytes(this.userForm.getValue("user_quota_max_size"));_.max_size_kb=(n/1024).toFixed(0)}return this.userForm.getValue("user_quota_max_objects_unlimited")||(_.max_objects=this.userForm.getValue("user_quota_max_objects")),_}_getBucketQuotaArgs(){const _={quota_type:"bucket",enabled:this.userForm.getValue("bucket_quota_enabled"),max_size_kb:-1,max_objects:-1};if(!this.userForm.getValue("bucket_quota_max_size_unlimited")){const n=(new Ge.H).toBytes(this.userForm.getValue("bucket_quota_max_size"));_.max_size_kb=(n/1024).toFixed(0)}return this.userForm.getValue("bucket_quota_max_objects_unlimited")||(_.max_objects=this.userForm.getValue("bucket_quota_max_objects")),_}_getS3KeyUserCandidates(){let _=[];const n=this.getUID();return u().isString(n)&&!u().isEmpty(n)&&_.push(n),this.subusers.forEach(i=>{_.push(i.id)}),this.s3Keys.forEach(i=>{_.push(i.user)}),_=u().uniq(_),_}onMaxBucketsModeChange(_){"1"===_&&(this.userForm.get("max_buckets").valid||this.userForm.patchValue({max_buckets:1e3}))}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(J.O),e.Y36(w.gz),e.Y36(w.F0),e.Y36(O),e.Y36(Te.Z),e.Y36(ve.g),e.Y36(A.p4))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-rgw-user-form"]],features:[e.qOj],decls:1,vars:1,consts:function(){let o,_,n,i,s,c,d,E,g,C,b,P,G,N,p,U,W,Z,$,h,I,v,F,T,x,y,S,_e,te,ne,oe,ie,se,ae,re,le,ce,de,ue,Re,R,__,t_,n_,o_,i_,s_,a_,r_,l_,c_,d_,u_,R_,g_,E_,T_,S_,f_,C_,p_,M_,m_,A_,b_,P_,G_;return o="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",_="User ID",n="Show Tenant",i="Full name",s="Email address",c="Max. buckets",d="Disabled",E="Unlimited",g="Custom",C="Suspended",b="User quota",P="Enabled",G="Bucket quota",N="Enabled",p="This field is required.",U="The value is not valid.",W="The chosen user ID is already in use.",Z="Tenant",$="The value is not valid.",h="The chosen user ID exists in this tenant.",I="This field is required.",v="This is not a valid email address.",F="The chosen email address is already in use.",T="This field is required.",x="The entered value must be >= 1.",y="S3 key",S="Auto-generate key",_e="Access key",te="This field is required.",ne="Secret key",oe="This field is required.",ie="Subusers",se="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",ae="There are no subusers.",re="Edit",le="Delete",ce="Keys",de="S3",ue="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",Re="Swift",R="There are no keys.",__="Show",t_="Delete",n_="There are no keys.",o_="Show",i_="Capabilities",s_="All capabilities are already added.",a_="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",r_="There are no capabilities.",l_="Edit",c_="Delete",d_="Unlimited size",u_="Max. size",R_="This field is required.",g_="The value is not valid.",E_="Unlimited objects",T_="Max. objects",S_="This field is required.",f_="The entered value must be >= 0.",C_="Unlimited size",p_="Max. size",M_="This field is required.",m_="The value is not valid.",A_="Unlimited objects",b_="Max. objects",P_="This field is required.",G_="The entered value must be >= 0.",[["class","cd-col-form",4,"cdFormLoading"],[1,"cd-col-form"],["novalidate","",3,"formGroup"],["frm","ngForm"],[1,"card"],[1,"card-header"],o,[1,"card-body"],[1,"form-group","row"],["for","user_id",1,"cd-col-form-label",3,"ngClass"],_,[1,"cd-col-form-input"],["id","user_id","type","text","formControlName","user_id",1,"form-control",3,"readonly"],["class","invalid-feedback",4,"ngIf"],[1,"cd-col-form-offset"],[1,"custom-control","custom-checkbox"],["id","show_tenant","type","checkbox","formControlName","show_tenant",1,"custom-control-input",3,"readonly","click"],["for","show_tenant",1,"custom-control-label"],n,["class","form-group row",4,"ngIf"],["for","display_name",1,"cd-col-form-label",3,"ngClass"],i,["id","display_name","type","text","formControlName","display_name",1,"form-control"],["for","email",1,"cd-col-form-label"],s,["id","email","type","text","formControlName","email",1,"form-control"],["for","max_buckets_mode",1,"cd-col-form-label"],c,["formControlName","max_buckets_mode","name","max_buckets_mode","id","max_buckets_mode",1,"form-control",3,"change"],["value","-1"],d,["value","0"],E,["value","1"],g,["id","suspended","type","checkbox","formControlName","suspended",1,"custom-control-input"],["for","suspended",1,"custom-control-label"],C,[4,"ngIf"],b,["id","user_quota_enabled","type","checkbox","formControlName","user_quota_enabled",1,"custom-control-input"],["for","user_quota_enabled",1,"custom-control-label"],P,G,["id","bucket_quota_enabled","type","checkbox","formControlName","bucket_quota_enabled",1,"custom-control-input"],["for","bucket_quota_enabled",1,"custom-control-label"],N,[1,"card-footer"],["wrappingClass","text-right",3,"form","submitText","submitActionEvent"],[1,"invalid-feedback"],p,U,W,["for","tenant",1,"cd-col-form-label"],Z,["id","tenant","type","text","formControlName","tenant","autofocus","",1,"form-control",3,"readonly"],$,h,I,v,F,[1,"cd-col-form-label"],["id","max_buckets","type","number","formControlName","max_buckets","min","1",1,"form-control"],T,x,y,["id","generate_key","type","checkbox","formControlName","generate_key",1,"custom-control-input"],["for","generate_key",1,"custom-control-label"],S,["for","access_key",1,"cd-col-form-label","required"],_e,[1,"input-group"],["id","access_key","type","password","formControlName","access_key",1,"form-control"],[1,"input-group-append"],["type","button","cdPasswordButton","access_key",1,"btn","btn-light"],["source","access_key"],te,["for","secret_key",1,"cd-col-form-label","required"],ne,["id","secret_key","type","password","formControlName","secret_key",1,"form-control"],["type","button","cdPasswordButton","secret_key",1,"btn","btn-light"],["source","secret_key"],oe,ie,[1,"row"],["class","no-border",4,"ngIf"],[4,"ngFor","ngForOf"],[1,"col-12"],["type","button",1,"btn","btn-light","float-right","tc_addSubuserButton",3,"click"],[3,"ngClass"],se,[1,"help-block"],[1,"no-border"],[1,"form-text","text-muted"],ae,[1,"input-group-prepend"],[1,"input-group-text"],["type","text","readonly","",1,"cd-form-control",3,"value"],[1,"input-group-prepend","border-left-0","border-right-0"],["type","button","ngbTooltip",re,1,"btn","btn-light","tc_showSubuserButton",3,"click"],["type","button","ngbTooltip",le,1,"btn","btn-light","tc_deleteSubuserButton",3,"click"],ce,de,["type","button",1,"btn","btn-light","float-right","tc_addS3KeyButton",3,"click"],ue,Re,R,["type","button","ngbTooltip",__,1,"btn","btn-light","tc_showS3KeyButton",3,"click"],["type","button","ngbTooltip",t_,1,"btn","btn-light","tc_deleteS3KeyButton",3,"click"],n_,["type","button","ngbTooltip",o_,1,"btn","btn-light","tc_showSwiftKeyButton",3,"click"],i_,["type","button","ngbTooltip",s_,"triggers","pointerenter:pointerleave",1,"btn","btn-light","float-right","tc_addCapButton",3,"disabled","disableTooltip","click"],a_,r_,["type","button","ngbTooltip",l_,1,"btn","btn-light","tc_editCapButton",3,"click"],["type","button","ngbTooltip",c_,1,"btn","btn-light","tc_deleteCapButton",3,"click"],["id","user_quota_max_size_unlimited","type","checkbox","formControlName","user_quota_max_size_unlimited",1,"custom-control-input"],["for","user_quota_max_size_unlimited",1,"custom-control-label"],d_,["for","user_quota_max_size",1,"cd-col-form-label","required"],u_,["id","user_quota_max_size","type","text","formControlName","user_quota_max_size","cdDimlessBinary","",1,"form-control"],R_,g_,["id","user_quota_max_objects_unlimited","type","checkbox","formControlName","user_quota_max_objects_unlimited",1,"custom-control-input"],["for","user_quota_max_objects_unlimited",1,"custom-control-label"],E_,["for","user_quota_max_objects",1,"cd-col-form-label","required"],T_,["id","user_quota_max_objects","type","number","formControlName","user_quota_max_objects","min","0",1,"form-control"],S_,f_,["id","bucket_quota_max_size_unlimited","type","checkbox","formControlName","bucket_quota_max_size_unlimited",1,"custom-control-input"],["for","bucket_quota_max_size_unlimited",1,"custom-control-label"],C_,["for","bucket_quota_max_size",1,"cd-col-form-label","required"],p_,["id","bucket_quota_max_size","type","text","formControlName","bucket_quota_max_size","cdDimlessBinary","",1,"form-control"],M_,m_,["id","bucket_quota_max_objects_unlimited","type","checkbox","formControlName","bucket_quota_max_objects_unlimited",1,"custom-control-input"],["for","bucket_quota_max_objects_unlimited",1,"custom-control-label"],A_,["for","bucket_quota_max_objects",1,"cd-col-form-label","required"],b_,["id","bucket_quota_max_objects","type","number","formControlName","bucket_quota_max_objects","min","0",1,"form-control"],P_,G_]},template:function(_,n){1&_&&e.YNc(0,To,89,41,"div",0),2&_&&e.Q6J("cdFormLoading",n.loading)},directives:[Fe.y,a._Y,a.JL,V.V,a.sg,H.P,f.mk,q.o,a.Fj,X.b,a.JJ,a.u,f.O5,a.Wl,a.EJ,a.YN,a.Kr,ee.p,j.U,a.wV,a.qQ,Ce.C,pe.s,f.sg,M._L,bn.Q],pipes:[f.rS,K.m,Ue.i],styles:[""]}),t})();var je=r(99466),So=r(78877),fo=r(86969);const Co=["accessKeyTpl"],po=["secretKeyTpl"];function Mo(t,o){if(1&t&&(e.TgZ(0,"tr"),e.TgZ(1,"td",15),e.SDv(2,20),e.qZA(),e.TgZ(3,"td"),e._uU(4),e.qZA(),e.qZA()),2&t){const _=e.oxw(4);e.xp6(4),e.Oqu(_.user.email)}}function mo(t,o){if(1&t&&(e.TgZ(0,"div"),e._uU(1),e.qZA()),2&t){const _=o.$implicit;e.xp6(1),e.AsE(" ",_.id," (",_.permissions,") ")}}function Ao(t,o){if(1&t&&(e.TgZ(0,"tr"),e.TgZ(1,"td",15),e.SDv(2,21),e.qZA(),e.TgZ(3,"td"),e.YNc(4,mo,2,2,"div",22),e.qZA(),e.qZA()),2&t){const _=e.oxw(4);e.xp6(4),e.Q6J("ngForOf",_.user.subusers)}}function bo(t,o){if(1&t&&(e.TgZ(0,"div"),e._uU(1),e.qZA()),2&t){const _=o.$implicit;e.xp6(1),e.AsE(" ",_.type," (",_.perm,") ")}}function Po(t,o){if(1&t&&(e.TgZ(0,"tr"),e.TgZ(1,"td",15),e.SDv(2,23),e.qZA(),e.TgZ(3,"td"),e.YNc(4,bo,2,2,"div",22),e.qZA(),e.qZA()),2&t){const _=e.oxw(4);e.xp6(4),e.Q6J("ngForOf",_.user.caps)}}function Go(t,o){if(1&t&&(e.TgZ(0,"tr"),e.TgZ(1,"td",15),e.SDv(2,24),e.qZA(),e.TgZ(3,"td"),e._uU(4),e.ALo(5,"join"),e.qZA(),e.qZA()),2&t){const _=e.oxw(4);e.xp6(4),e.Oqu(e.lcZ(5,1,_.user.mfa_ids))}}function No(t,o){1&t&&(e.TgZ(0,"td"),e._uU(1,"-"),e.qZA())}function Oo(t,o){1&t&&(e.TgZ(0,"td"),e.SDv(1,29),e.qZA())}function Uo(t,o){if(1&t&&(e.TgZ(0,"td"),e._uU(1),e.ALo(2,"dimlessBinary"),e.qZA()),2&t){const _=e.oxw(5);e.xp6(1),e.hij(" ",e.lcZ(2,1,_.user.user_quota.max_size)," ")}}function Wo(t,o){1&t&&(e.TgZ(0,"td"),e._uU(1,"-"),e.qZA())}function Zo(t,o){1&t&&(e.TgZ(0,"td"),e.SDv(1,30),e.qZA())}function $o(t,o){if(1&t&&(e.TgZ(0,"td"),e._uU(1),e.qZA()),2&t){const _=e.oxw(5);e.xp6(1),e.hij(" ",_.user.user_quota.max_objects," ")}}function ho(t,o){if(1&t&&(e.TgZ(0,"div"),e.TgZ(1,"legend"),e.SDv(2,25),e.qZA(),e.TgZ(3,"table",9),e.TgZ(4,"tbody"),e.TgZ(5,"tr"),e.TgZ(6,"td",10),e.SDv(7,26),e.qZA(),e.TgZ(8,"td",12),e._uU(9),e.ALo(10,"booleanText"),e.qZA(),e.qZA(),e.TgZ(11,"tr"),e.TgZ(12,"td",15),e.SDv(13,27),e.qZA(),e.YNc(14,No,2,0,"td",0),e.YNc(15,Oo,2,0,"td",0),e.YNc(16,Uo,3,3,"td",0),e.qZA(),e.TgZ(17,"tr"),e.TgZ(18,"td",15),e.SDv(19,28),e.qZA(),e.YNc(20,Wo,2,0,"td",0),e.YNc(21,Zo,2,0,"td",0),e.YNc(22,$o,2,1,"td",0),e.qZA(),e.qZA(),e.qZA(),e.qZA()),2&t){const _=e.oxw(4);e.xp6(9),e.Oqu(e.lcZ(10,7,_.user.user_quota.enabled)),e.xp6(5),e.Q6J("ngIf",!_.user.user_quota.enabled),e.xp6(1),e.Q6J("ngIf",_.user.user_quota.enabled&&_.user.user_quota.max_size<=-1),e.xp6(1),e.Q6J("ngIf",_.user.user_quota.enabled&&_.user.user_quota.max_size>-1),e.xp6(4),e.Q6J("ngIf",!_.user.user_quota.enabled),e.xp6(1),e.Q6J("ngIf",_.user.user_quota.enabled&&_.user.user_quota.max_objects<=-1),e.xp6(1),e.Q6J("ngIf",_.user.user_quota.enabled&&_.user.user_quota.max_objects>-1)}}function Io(t,o){1&t&&(e.TgZ(0,"td"),e._uU(1,"-"),e.qZA())}function vo(t,o){1&t&&(e.TgZ(0,"td"),e.SDv(1,35),e.qZA())}function Fo(t,o){if(1&t&&(e.TgZ(0,"td"),e._uU(1),e.ALo(2,"dimlessBinary"),e.qZA()),2&t){const _=e.oxw(5);e.xp6(1),e.hij(" ",e.lcZ(2,1,_.user.bucket_quota.max_size)," ")}}function Lo(t,o){1&t&&(e.TgZ(0,"td"),e._uU(1,"-"),e.qZA())}function Do(t,o){1&t&&(e.TgZ(0,"td"),e.SDv(1,36),e.qZA())}function xo(t,o){if(1&t&&(e.TgZ(0,"td"),e._uU(1),e.qZA()),2&t){const _=e.oxw(5);e.xp6(1),e.hij(" ",_.user.bucket_quota.max_objects," ")}}function yo(t,o){if(1&t&&(e.TgZ(0,"div"),e.TgZ(1,"legend"),e.SDv(2,31),e.qZA(),e.TgZ(3,"table",9),e.TgZ(4,"tbody"),e.TgZ(5,"tr"),e.TgZ(6,"td",10),e.SDv(7,32),e.qZA(),e.TgZ(8,"td",12),e._uU(9),e.ALo(10,"booleanText"),e.qZA(),e.qZA(),e.TgZ(11,"tr"),e.TgZ(12,"td",15),e.SDv(13,33),e.qZA(),e.YNc(14,Io,2,0,"td",0),e.YNc(15,vo,2,0,"td",0),e.YNc(16,Fo,3,3,"td",0),e.qZA(),e.TgZ(17,"tr"),e.TgZ(18,"td",15),e.SDv(19,34),e.qZA(),e.YNc(20,Lo,2,0,"td",0),e.YNc(21,Do,2,0,"td",0),e.YNc(22,xo,2,1,"td",0),e.qZA(),e.qZA(),e.qZA(),e.qZA()),2&t){const _=e.oxw(4);e.xp6(9),e.Oqu(e.lcZ(10,7,_.user.bucket_quota.enabled)),e.xp6(5),e.Q6J("ngIf",!_.user.bucket_quota.enabled),e.xp6(1),e.Q6J("ngIf",_.user.bucket_quota.enabled&&_.user.bucket_quota.max_size<=-1),e.xp6(1),e.Q6J("ngIf",_.user.bucket_quota.enabled&&_.user.bucket_quota.max_size>-1),e.xp6(4),e.Q6J("ngIf",!_.user.bucket_quota.enabled),e.xp6(1),e.Q6J("ngIf",_.user.bucket_quota.enabled&&_.user.bucket_quota.max_objects<=-1),e.xp6(1),e.Q6J("ngIf",_.user.bucket_quota.enabled&&_.user.bucket_quota.max_objects>-1)}}function qo(t,o){if(1&t&&(e.TgZ(0,"div"),e.TgZ(1,"table",9),e.TgZ(2,"tbody"),e.TgZ(3,"tr"),e.TgZ(4,"td",10),e.SDv(5,11),e.qZA(),e.TgZ(6,"td",12),e._uU(7),e.qZA(),e.qZA(),e.TgZ(8,"tr"),e.TgZ(9,"td",10),e.SDv(10,13),e.qZA(),e.TgZ(11,"td",12),e._uU(12),e.qZA(),e.qZA(),e.TgZ(13,"tr"),e.TgZ(14,"td",10),e.SDv(15,14),e.qZA(),e.TgZ(16,"td",12),e._uU(17),e.qZA(),e.qZA(),e.TgZ(18,"tr"),e.TgZ(19,"td",15),e.SDv(20,16),e.qZA(),e.TgZ(21,"td"),e._uU(22),e.qZA(),e.qZA(),e.YNc(23,Mo,5,1,"tr",0),e.TgZ(24,"tr"),e.TgZ(25,"td",15),e.SDv(26,17),e.qZA(),e.TgZ(27,"td"),e._uU(28),e.ALo(29,"booleanText"),e.qZA(),e.qZA(),e.TgZ(30,"tr"),e.TgZ(31,"td",15),e.SDv(32,18),e.qZA(),e.TgZ(33,"td"),e._uU(34),e.ALo(35,"booleanText"),e.qZA(),e.qZA(),e.TgZ(36,"tr"),e.TgZ(37,"td",15),e.SDv(38,19),e.qZA(),e.TgZ(39,"td"),e._uU(40),e.ALo(41,"map"),e.qZA(),e.qZA(),e.YNc(42,Ao,5,1,"tr",0),e.YNc(43,Po,5,1,"tr",0),e.YNc(44,Go,6,3,"tr",0),e.qZA(),e.qZA(),e.YNc(45,ho,23,9,"div",0),e.YNc(46,yo,23,9,"div",0),e.qZA()),2&t){const _=e.oxw(3);e.xp6(7),e.Oqu(_.user.tenant),e.xp6(5),e.Oqu(_.user.user_id),e.xp6(5),e.Oqu(_.user.uid),e.xp6(5),e.Oqu(_.user.display_name),e.xp6(1),e.Q6J("ngIf",null==_.user.email?null:_.user.email.length),e.xp6(5),e.Oqu(e.lcZ(29,13,_.user.suspended)),e.xp6(6),e.Oqu(e.lcZ(35,15,"true"===_.user.system)),e.xp6(6),e.Oqu(e.xi3(41,17,_.user.max_buckets,_.maxBucketsMap)),e.xp6(2),e.Q6J("ngIf",_.user.subusers&&_.user.subusers.length),e.xp6(1),e.Q6J("ngIf",_.user.caps&&_.user.caps.length),e.xp6(1),e.Q6J("ngIf",null==_.user.mfa_ids?null:_.user.mfa_ids.length),e.xp6(1),e.Q6J("ngIf",_.user.user_quota),e.xp6(1),e.Q6J("ngIf",_.user.bucket_quota)}}function wo(t,o){if(1&t&&e.YNc(0,qo,47,20,"div",0),2&t){const _=e.oxw(2);e.Q6J("ngIf",_.user)}}const ko=function(t){return[t]};function Bo(t,o){if(1&t){const _=e.EpF();e.TgZ(0,"cd-table",39),e.NdJ("updateSelection",function(i){return e.CHM(_),e.oxw(3).updateKeysSelection(i)}),e.TgZ(1,"div",40),e.TgZ(2,"div",41),e.TgZ(3,"button",42),e.NdJ("click",function(){return e.CHM(_),e.oxw(3).showKeyModal()}),e._UZ(4,"i",43),e.ynx(5),e.SDv(6,44),e.BQk(),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&t){const _=e.oxw(3);e.Q6J("data",_.keys)("columns",_.keysColumns),e.xp6(3),e.Q6J("disabled",!_.keysSelection.hasSingleSelection),e.xp6(1),e.Q6J("ngClass",e.VKq(4,ko,_.icons.show))}}function Ho(t,o){1&t&&(e.TgZ(0,"li",37),e.TgZ(1,"a",4),e.SDv(2,38),e.qZA(),e.YNc(3,Bo,7,6,"ng-template",6),e.qZA())}function Xo(t,o){if(1&t&&(e.ynx(0),e.TgZ(1,"ul",1,2),e.TgZ(3,"li",3),e.TgZ(4,"a",4),e.SDv(5,5),e.qZA(),e.YNc(6,wo,1,1,"ng-template",6),e.qZA(),e.YNc(7,Ho,4,0,"li",7),e.qZA(),e._UZ(8,"div",8),e.BQk()),2&t){const _=e.MAs(2),n=e.oxw();e.xp6(7),e.Q6J("ngIf",n.keys.length),e.xp6(1),e.Q6J("ngbNavOutlet",_)}}let Ko=(()=>{class t{constructor(_,n){this.rgwUserService=_,this.modalService=n,this.keys=[],this.keysColumns=[],this.keysSelection=new Pe.r,this.icons=D.P}ngOnInit(){this.keysColumns=[{name:"Username",prop:"username",flexGrow:1},{name:"Type",prop:"type",flexGrow:1}],this.maxBucketsMap={"-1":"Disabled",0:"Unlimited"}}ngOnChanges(){this.selection&&(this.user=this.selection,this.user.subusers=u().sortBy(this.user.subusers,"id"),this.user.caps=u().sortBy(this.user.caps,"type"),this.rgwUserService.getQuota(this.user.uid).subscribe(_=>{u().extend(this.user,_)}),this.keys=[],this.user.keys&&this.user.keys.forEach(_=>{this.keys.push({id:this.keys.length+1,type:"S3",username:_.user,ref:_})}),this.user.swift_keys&&this.user.swift_keys.forEach(_=>{this.keys.push({id:this.keys.length+1,type:"Swift",username:_.user,ref:_})}),this.keys=u().sortBy(this.keys,"user"))}updateKeysSelection(_){this.keysSelection=_}showKeyModal(){const _=this.keysSelection.first(),n=this.modalService.show("S3"===_.type?Qe:Ye);switch(_.type){case"S3":n.componentInstance.setViewing(),n.componentInstance.setValues(_.ref.user,_.ref.access_key,_.ref.secret_key);break;case"Swift":n.componentInstance.setValues(_.ref.user,_.ref.secret_key)}}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(O),e.Y36(Te.Z))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-rgw-user-details"]],viewQuery:function(_,n){if(1&_&&(e.Gf(Co,5),e.Gf(po,5)),2&_){let i;e.iGM(i=e.CRH())&&(n.accessKeyTpl=i.first),e.iGM(i=e.CRH())&&(n.secretKeyTpl=i.first)}},inputs:{selection:"selection"},features:[e.TTD],decls:1,vars:1,consts:function(){let o,_,n,i,s,c,d,E,g,C,b,P,G,N,p,U,W,Z,$,h,I,v,F,T,x,y;return o="Details",_="Tenant",n="User ID",i="Username",s="Full name",c="Suspended",d="System",E="Maximum buckets",g="Email address",C="Subusers",b="Capabilities",P="MFAs(Id)",G="User quota",N="Enabled",p="Maximum size",U="Maximum objects",W="Unlimited",Z="Unlimited",$="Bucket quota",h="Enabled",I="Maximum size",v="Maximum objects",F="Unlimited",T="Unlimited",x="Keys",y="Show",[[4,"ngIf"],["ngbNav","","cdStatefulTab","rgw-user-details",1,"nav-tabs"],["nav","ngbNav"],["ngbNavItem","details"],["ngbNavLink",""],o,["ngbNavContent",""],["ngbNavItem","keys",4,"ngIf"],[3,"ngbNavOutlet"],[1,"table","table-striped","table-bordered"],[1,"bold","w-25"],_,[1,"w-75"],n,i,[1,"bold"],s,c,d,E,g,C,[4,"ngFor","ngForOf"],b,P,G,N,p,U,W,Z,$,h,I,v,F,T,["ngbNavItem","keys"],x,["columnMode","flex","selectionType","multi","forceIdentifier","true",3,"data","columns","updateSelection"],[1,"table-actions"],["dropdown","",1,"btn-group"],["type","button",1,"btn","btn-accent",3,"disabled","click"],[3,"ngClass"],y]},template:function(_,n){1&_&&e.YNc(0,Xo,9,2,"ng-container",0),2&_&&e.Q6J("ngIf",n.selection)},directives:[f.O5,M.Pz,Xe.m,M.nv,M.Vx,M.uN,M.tO,f.sg,z.a,q.o,f.mk],pipes:[Be.T,So.b,fo.A,qe.$],styles:[""]}),t})();const zo=["userSizeTpl"],Qo=["userObjectTpl"];function Yo(t,o){if(1&t&&e._UZ(0,"cd-usage-bar",8),2&t){const _=e.oxw().row;e.Q6J("total",_.user_quota.max_size)("used",_.stats.size_actual)}}function Jo(t,o){1&t&&e.SDv(0,9)}function Vo(t,o){if(1&t&&(e.YNc(0,Yo,1,2,"cd-usage-bar",6),e.YNc(1,Jo,1,0,"ng-template",null,7,e.W1O)),2&t){const _=o.row,n=e.MAs(2);e.Q6J("ngIf",_.user_quota.max_size>0&&_.user_quota.enabled)("ngIfElse",n)}}function jo(t,o){if(1&t&&e._UZ(0,"cd-usage-bar",12),2&t){const _=e.oxw().row;e.Q6J("total",_.user_quota.max_objects)("used",_.stats.num_objects)("isBinary",!1)}}function ei(t,o){1&t&&e.SDv(0,13)}function _i(t,o){if(1&t&&(e.YNc(0,jo,1,3,"cd-usage-bar",10),e.YNc(1,ei,1,0,"ng-template",null,11,e.W1O)),2&t){const _=o.row,n=e.MAs(2);e.Q6J("ngIf",_.user_quota.max_objects>0&&_.user_quota.enabled)("ngIfElse",n)}}let ni=(()=>{class t extends be.o{constructor(_,n,i,s,c,d){super(d),this.authStorageService=_,this.rgwUserService=n,this.modalService=i,this.urlBuilder=s,this.actionLabels=c,this.ngZone=d,this.columns=[],this.users=[],this.selection=new Pe.r}ngOnInit(){this.permission=this.authStorageService.getPermissions().rgw,this.columns=[{name:"Username",prop:"uid",flexGrow:1},{name:"Tenant",prop:"tenant",flexGrow:1},{name:"Full name",prop:"display_name",flexGrow:1},{name:"Email address",prop:"email",flexGrow:1},{name:"Suspended",prop:"suspended",flexGrow:1,cellClass:"text-center",cellTransformation:je.e.checkIcon},{name:"Max. buckets",prop:"max_buckets",flexGrow:1,cellTransformation:je.e.map,customTemplateConfig:{"-1":"Disabled",0:"Unlimited"}},{name:"Capacity Limit %",prop:"size_usage",cellTemplate:this.userSizeTpl,flexGrow:.8},{name:"Object Limit %",prop:"object_usage",cellTemplate:this.userObjectTpl,flexGrow:.8}];const _=()=>this.selection.first()&&`${encodeURIComponent(this.selection.first().uid)}`;this.tableActions=[{permission:"create",icon:D.P.add,routerLink:()=>this.urlBuilder.getCreate(),name:this.actionLabels.CREATE,canBePrimary:c=>!c.hasSelection},{permission:"update",icon:D.P.edit,routerLink:()=>this.urlBuilder.getEdit(_()),name:this.actionLabels.EDIT},{permission:"delete",icon:D.P.destroy,click:()=>this.deleteAction(),disable:()=>!this.selection.hasSelection,name:this.actionLabels.DELETE,canBePrimary:c=>c.hasMultiSelection}],this.setTableRefreshTimeout()}getUserList(_){this.setTableRefreshTimeout(),this.rgwUserService.list().subscribe(n=>{this.users=n},()=>{_.error()})}updateSelection(_){this.selection=_}deleteAction(){this.modalService.show(ye.M,{itemDescription:this.selection.hasSingleSelection?"user":"users",itemNames:this.selection.selected.map(_=>_.uid),submitActionObservable:()=>new xe.y(_=>{(0,Y.D)(this.selection.selected.map(n=>this.rgwUserService.delete(n.uid))).subscribe({error:n=>{_.error(n),this.table.refreshBtn()},complete:()=>{_.complete(),this.table.refreshBtn()}})})})}}return t.\u0275fac=function(_){return new(_||t)(e.Y36(Ee.j),e.Y36(O),e.Y36(Te.Z),e.Y36(Q.F),e.Y36(A.p4),e.Y36(e.R0b))},t.\u0275cmp=e.Xpm({type:t,selectors:[["cd-rgw-user-list"]],viewQuery:function(_,n){if(1&_&&(e.Gf(z.a,7),e.Gf(zo,7),e.Gf(Qo,7)),2&_){let i;e.iGM(i=e.CRH())&&(n.table=i.first),e.iGM(i=e.CRH())&&(n.userSizeTpl=i.first),e.iGM(i=e.CRH())&&(n.userObjectTpl=i.first)}},features:[e._Bn([{provide:Q.F,useValue:new Q.F("rgw/user")}]),e.qOj],decls:8,vars:9,consts:function(){let o,_;return o="No Limit",_="No Limit",[["columnMode","flex","selectionType","multiClick","identifier","uid",3,"autoReload","data","columns","hasDetails","status","setExpandedRow","updateSelection","fetchData"],["table",""],[1,"table-actions",3,"permission","selection","tableActions"],["cdTableDetail","",3,"selection"],["userSizeTpl",""],["userObjectTpl",""],[3,"total","used",4,"ngIf","ngIfElse"],["noSizeQuota",""],[3,"total","used"],o,[3,"total","used","isBinary",4,"ngIf","ngIfElse"],["noObjectQuota",""],[3,"total","used","isBinary"],_]},template:function(_,n){1&_&&(e.TgZ(0,"cd-table",0,1),e.NdJ("setExpandedRow",function(s){return n.setExpandedRow(s)})("updateSelection",function(s){return n.updateSelection(s)})("fetchData",function(s){return n.getUserList(s)}),e._UZ(2,"cd-table-actions",2),e._UZ(3,"cd-rgw-user-details",3),e.qZA(),e.YNc(4,Vo,3,2,"ng-template",null,4,e.W1O),e.YNc(6,_i,3,2,"ng-template",null,5,e.W1O)),2&_&&(e.Q6J("autoReload",!1)("data",n.users)("columns",n.columns)("hasDetails",!0)("status",n.tableStatus),e.xp6(2),e.Q6J("permission",n.permission)("selection",n.selection)("tableActions",n.tableActions),e.xp6(1),e.Q6J("selection",n.expandedRow))},directives:[z.a,ke.K,Ko,f.O5,He.O],styles:[""]}),t})(),e_=(()=>{class t{}return t.\u0275fac=function(_){return new(_||t)},t.\u0275mod=e.oAB({type:t}),t.\u0275inj=e.cJS({imports:[[f.ez,N_.m,a.u5,a.UX,O_.B,M.Oz,w.Bz,M.HK,Ue.b]]}),t})();const oi=[{path:""},{path:"daemon",component:kt,data:{breadcrumbs:"Daemons"}},{path:"user",data:{breadcrumbs:"Users"},children:[{path:"",component:ni},{path:A.MQ.CREATE,component:Ve,data:{breadcrumbs:A.Qn.CREATE}},{path:`${A.MQ.EDIT}/:uid`,component:Ve,data:{breadcrumbs:A.Qn.EDIT}}]},{path:"bucket",data:{breadcrumbs:"Buckets"},children:[{path:"",component:Ot},{path:A.MQ.CREATE,component:De,data:{breadcrumbs:A.Qn.CREATE}},{path:`${A.MQ.EDIT}/:bid`,component:De,data:{breadcrumbs:A.Qn.EDIT}}]}];let ii=(()=>{class t{}return t.\u0275fac=function(_){return new(_||t)},t.\u0275mod=e.oAB({type:t}),t.\u0275inj=e.cJS({imports:[[e_,w.Bz.forChild(oi)]]}),t})()}}]); \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/3rdpartylicenses.txt b/src/pybind/mgr/dashboard/frontend/dist/en-US/3rdpartylicenses.txt
new file mode 100644
index 000000000..0f40b833c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/3rdpartylicenses.txt
@@ -0,0 +1,3508 @@
+@angular/animations
+MIT
+
+@angular/common
+MIT
+
+@angular/core
+MIT
+
+@angular/forms
+MIT
+
+@angular/platform-browser
+MIT
+
+@angular/router
+MIT
+
+@babel/runtime
+MIT
+MIT License
+
+Copyright (c) 2014-present Sebastian McKenzie and other contributors
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+@babel/runtime-corejs3
+MIT
+MIT License
+
+Copyright (c) 2014-present Sebastian McKenzie and other contributors
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+@braintree/sanitize-url
+MIT
+MIT License
+
+Copyright (c) 2017 Braintree
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+@circlon/angular-tree-component
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2020 Circlon Group
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+@juggle/resize-observer
+Apache-2.0
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2019 JUGGLE LTD
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+@ng-bootstrap/ng-bootstrap
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2015-2018 Angular ng-bootstrap team
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+@swimlane/ngx-datatable
+MIT
+(The MIT License)
+
+Copyright (c) 2019 Swimlane <info@swimlane.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+async-mutex
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2016 Christian Speckner <cnspeckn@googlemail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+autolinker
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2014 Gregory Jacobs (http://greg-jacobs.com)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+balanced-match
+MIT
+(MIT)
+
+Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+base64-js
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2014 Jameson Little
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+brace-expansion
+MIT
+MIT License
+
+Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+call-bind
+MIT
+MIT License
+
+Copyright (c) 2020 Jordan Harband
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+can-use-dom
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2015 Kiran Abburi
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+
+chart.js
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2018 Chart.js Contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+classnames
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2018 Jed Watson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+concat-map
+MIT
+This software is released under the MIT license:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+cookie
+MIT
+(The MIT License)
+
+Copyright (c) 2012-2014 Roman Shtylman <shtylman@gmail.com>
+Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+
+copy-to-clipboard
+MIT
+MIT License
+
+Copyright (c) 2017 sudodoki <smd.deluzion@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+core-js
+MIT
+Copyright (c) 2014-2022 Denis Pushkarev
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+core-js-pure
+MIT
+Copyright (c) 2014-2022 Denis Pushkarev
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+cross-fetch
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2017 Leonardo Quixadá
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+css.escape
+MIT
+Copyright Mathias Bynens <https://mathiasbynens.be/>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+deepmerge
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2012 James Halliday, Josh Duff, and other contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+detect-browser
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2019 Damon Oehlman <damon.oehlman@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+dompurify
+(MPL-2.0 OR Apache-2.0)
+DOMPurify
+Copyright 2015 Mario Heiderich
+
+DOMPurify is free software; you can redistribute it and/or modify it under the
+terms of either:
+
+a) the Apache License Version 2.0, or
+b) the Mozilla Public License Version 2.0
+
+-----------------------------------------------------------------------------
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-----------------------------------------------------------------------------
+Mozilla Public License, version 2.0
+
+1. Definitions
+
+1.1. “Contributor”
+
+ means each individual or legal entity that creates, contributes to the
+ creation of, or owns Covered Software.
+
+1.2. “Contributor Version”
+
+ means the combination of the Contributions of others (if any) used by a
+ Contributor and that particular Contributor’s Contribution.
+
+1.3. “Contribution”
+
+ means Covered Software of a particular Contributor.
+
+1.4. “Covered Software”
+
+ means Source Code Form to which the initial Contributor has attached the
+ notice in Exhibit A, the Executable Form of such Source Code Form, and
+ Modifications of such Source Code Form, in each case including portions
+ thereof.
+
+1.5. “Incompatible With Secondary Licenses”
+ means
+
+ a. that the initial Contributor has attached the notice described in
+ Exhibit B to the Covered Software; or
+
+ b. that the Covered Software was made available under the terms of version
+ 1.1 or earlier of the License, but not also under the terms of a
+ Secondary License.
+
+1.6. “Executable Form”
+
+ means any form of the work other than Source Code Form.
+
+1.7. “Larger Work”
+
+ means a work that combines Covered Software with other material, in a separate
+ file or files, that is not Covered Software.
+
+1.8. “License”
+
+ means this document.
+
+1.9. “Licensable”
+
+ means having the right to grant, to the maximum extent possible, whether at the
+ time of the initial grant or subsequently, any and all of the rights conveyed by
+ this License.
+
+1.10. “Modifications”
+
+ means any of the following:
+
+ a. any file in Source Code Form that results from an addition to, deletion
+ from, or modification of the contents of Covered Software; or
+
+ b. any new file in Source Code Form that contains any Covered Software.
+
+1.11. “Patent Claims” of a Contributor
+
+ means any patent claim(s), including without limitation, method, process,
+ and apparatus claims, in any patent Licensable by such Contributor that
+ would be infringed, but for the grant of the License, by the making,
+ using, selling, offering for sale, having made, import, or transfer of
+ either its Contributions or its Contributor Version.
+
+1.12. “Secondary License”
+
+ means either the GNU General Public License, Version 2.0, the GNU Lesser
+ General Public License, Version 2.1, the GNU Affero General Public
+ License, Version 3.0, or any later versions of those licenses.
+
+1.13. “Source Code Form”
+
+ means the form of the work preferred for making modifications.
+
+1.14. “You” (or “Your”)
+
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, “You” includes any entity that controls, is
+ controlled by, or is under common control with You. For purposes of this
+ definition, “control” means (a) the power, direct or indirect, to cause
+ the direction or management of such entity, whether by contract or
+ otherwise, or (b) ownership of more than fifty percent (50%) of the
+ outstanding shares or beneficial ownership of such entity.
+
+
+2. License Grants and Conditions
+
+2.1. Grants
+
+ Each Contributor hereby grants You a world-wide, royalty-free,
+ non-exclusive license:
+
+ a. under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or as
+ part of a Larger Work; and
+
+ b. under Patent Claims of such Contributor to make, use, sell, offer for
+ sale, have made, import, and otherwise transfer either its Contributions
+ or its Contributor Version.
+
+2.2. Effective Date
+
+ The licenses granted in Section 2.1 with respect to any Contribution become
+ effective for each Contribution on the date the Contributor first distributes
+ such Contribution.
+
+2.3. Limitations on Grant Scope
+
+ The licenses granted in this Section 2 are the only rights granted under this
+ License. No additional rights or licenses will be implied from the distribution
+ or licensing of Covered Software under this License. Notwithstanding Section
+ 2.1(b) above, no patent license is granted by a Contributor:
+
+ a. for any code that a Contributor has removed from Covered Software; or
+
+ b. for infringements caused by: (i) Your and any other third party’s
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+ c. under Patent Claims infringed by Covered Software in the absence of its
+ Contributions.
+
+ This License does not grant any rights in the trademarks, service marks, or
+ logos of any Contributor (except as may be necessary to comply with the
+ notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+ No Contributor makes additional grants as a result of Your choice to
+ distribute the Covered Software under a subsequent version of this License
+ (see Section 10.2) or under the terms of a Secondary License (if permitted
+ under the terms of Section 3.3).
+
+2.5. Representation
+
+ Each Contributor represents that the Contributor believes its Contributions
+ are its original creation(s) or it has sufficient rights to grant the
+ rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+ This License is not intended to limit any rights You have under applicable
+ copyright doctrines of fair use, fair dealing, or other equivalents.
+
+2.7. Conditions
+
+ Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
+ Section 2.1.
+
+
+3. Responsibilities
+
+3.1. Distribution of Source Form
+
+ All distribution of Covered Software in Source Code Form, including any
+ Modifications that You create or to which You contribute, must be under the
+ terms of this License. You must inform recipients that the Source Code Form
+ of the Covered Software is governed by the terms of this License, and how
+ they can obtain a copy of this License. You may not attempt to alter or
+ restrict the recipients’ rights in the Source Code Form.
+
+3.2. Distribution of Executable Form
+
+ If You distribute Covered Software in Executable Form then:
+
+ a. such Covered Software must also be made available in Source Code Form,
+ as described in Section 3.1, and You must inform recipients of the
+ Executable Form how they can obtain a copy of such Source Code Form by
+ reasonable means in a timely manner, at a charge no more than the cost
+ of distribution to the recipient; and
+
+ b. You may distribute such Executable Form under the terms of this License,
+ or sublicense it under different terms, provided that the license for
+ the Executable Form does not attempt to limit or alter the recipients’
+ rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+ You may create and distribute a Larger Work under terms of Your choice,
+ provided that You also comply with the requirements of this License for the
+ Covered Software. If the Larger Work is a combination of Covered Software
+ with a work governed by one or more Secondary Licenses, and the Covered
+ Software is not Incompatible With Secondary Licenses, this License permits
+ You to additionally distribute such Covered Software under the terms of
+ such Secondary License(s), so that the recipient of the Larger Work may, at
+ their option, further distribute the Covered Software under the terms of
+ either this License or such Secondary License(s).
+
+3.4. Notices
+
+ You may not remove or alter the substance of any license notices (including
+ copyright notices, patent notices, disclaimers of warranty, or limitations
+ of liability) contained within the Source Code Form of the Covered
+ Software, except that You may alter any license notices to the extent
+ required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+ You may choose to offer, and to charge a fee for, warranty, support,
+ indemnity or liability obligations to one or more recipients of Covered
+ Software. However, You may do so only on Your own behalf, and not on behalf
+ of any Contributor. You must make it absolutely clear that any such
+ warranty, support, indemnity, or liability obligation is offered by You
+ alone, and You hereby agree to indemnify every Contributor for any
+ liability incurred by such Contributor as a result of warranty, support,
+ indemnity or liability terms You offer. You may include additional
+ disclaimers of warranty and limitations of liability specific to any
+ jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+
+ If it is impossible for You to comply with any of the terms of this License
+ with respect to some or all of the Covered Software due to statute, judicial
+ order, or regulation then You must: (a) comply with the terms of this License
+ to the maximum extent possible; and (b) describe the limitations and the code
+ they affect. Such description must be placed in a text file included with all
+ distributions of the Covered Software under this License. Except to the
+ extent prohibited by statute or regulation, such description must be
+ sufficiently detailed for a recipient of ordinary skill to be able to
+ understand it.
+
+5. Termination
+
+5.1. The rights granted under this License will terminate automatically if You
+ fail to comply with any of its terms. However, if You become compliant,
+ then the rights granted under this License from a particular Contributor
+ are reinstated (a) provisionally, unless and until such Contributor
+ explicitly and finally terminates Your grants, and (b) on an ongoing basis,
+ if such Contributor fails to notify You of the non-compliance by some
+ reasonable means prior to 60 days after You have come back into compliance.
+ Moreover, Your grants from a particular Contributor are reinstated on an
+ ongoing basis if such Contributor notifies You of the non-compliance by
+ some reasonable means, this is the first time You have received notice of
+ non-compliance with this License from such Contributor, and You become
+ compliant prior to 30 days after Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+ infringement claim (excluding declaratory judgment actions, counter-claims,
+ and cross-claims) alleging that a Contributor Version directly or
+ indirectly infringes any patent, then the rights granted to You by any and
+ all Contributors for the Covered Software under Section 2.1 of this License
+ shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
+ license agreements (excluding distributors and resellers) which have been
+ validly granted by You or Your distributors under this License prior to
+ termination shall survive termination.
+
+6. Disclaimer of Warranty
+
+ Covered Software is provided under this License on an “as is” basis, without
+ warranty of any kind, either expressed, implied, or statutory, including,
+ without limitation, warranties that the Covered Software is free of defects,
+ merchantable, fit for a particular purpose or non-infringing. The entire
+ risk as to the quality and performance of the Covered Software is with You.
+ Should any Covered Software prove defective in any respect, You (not any
+ Contributor) assume the cost of any necessary servicing, repair, or
+ correction. This disclaimer of warranty constitutes an essential part of this
+ License. No use of any Covered Software is authorized under this License
+ except under this disclaimer.
+
+7. Limitation of Liability
+
+ Under no circumstances and under no legal theory, whether tort (including
+ negligence), contract, or otherwise, shall any Contributor, or anyone who
+ distributes Covered Software as permitted above, be liable to You for any
+ direct, indirect, special, incidental, or consequential damages of any
+ character including, without limitation, damages for lost profits, loss of
+ goodwill, work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses, even if such party shall have been
+ informed of the possibility of such damages. This limitation of liability
+ shall not apply to liability for death or personal injury resulting from such
+ party’s negligence to the extent applicable law prohibits such limitation.
+ Some jurisdictions do not allow the exclusion or limitation of incidental or
+ consequential damages, so this exclusion and limitation may not apply to You.
+
+8. Litigation
+
+ Any litigation relating to this License may be brought only in the courts of
+ a jurisdiction where the defendant maintains its principal place of business
+ and such litigation shall be governed by laws of that jurisdiction, without
+ reference to its conflict-of-law provisions. Nothing in this Section shall
+ prevent a party’s ability to bring cross-claims or counter-claims.
+
+9. Miscellaneous
+
+ This License represents the complete agreement concerning the subject matter
+ hereof. If any provision of this License is held to be unenforceable, such
+ provision shall be reformed only to the extent necessary to make it
+ enforceable. Any law or regulation which provides that the language of a
+ contract shall be construed against the drafter shall not be used to construe
+ this License against a Contributor.
+
+
+10. Versions of the License
+
+10.1. New Versions
+
+ Mozilla Foundation is the license steward. Except as provided in Section
+ 10.3, no one other than the license steward has the right to modify or
+ publish new versions of this License. Each version will be given a
+ distinguishing version number.
+
+10.2. Effect of New Versions
+
+ You may distribute the Covered Software under the terms of the version of
+ the License under which You originally received the Covered Software, or
+ under the terms of any subsequent version published by the license
+ steward.
+
+10.3. Modified Versions
+
+ If you create software not governed by this License, and you want to
+ create a new license for such software, you may create and use a modified
+ version of this License if you rename the license and remove any
+ references to the name of the license steward (except to note that such
+ modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
+ If You choose to distribute Source Code Form that is Incompatible With
+ Secondary Licenses under the terms of this version of the License, the
+ notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+
+ This Source Code Form is subject to the
+ terms of the Mozilla Public License, v.
+ 2.0. If a copy of the MPL was not
+ distributed with this file, You can
+ obtain one at
+ http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular file, then
+You may include the notice in a location (such as a LICENSE file in a relevant
+directory) where a recipient would be likely to look for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - “Incompatible With Secondary Licenses” Notice
+
+ This Source Code Form is “Incompatible
+ With Secondary Licenses”, as defined by
+ the Mozilla Public License, v. 2.0.
+
+
+
+drange
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2014 David Tudury
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+fast-json-patch
+MIT
+(The MIT License)
+
+Copyright (c) 2013, 2014, 2020 Joachim Wester
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+fault
+MIT
+(The MIT License)
+
+Copyright (c) 2015 Titus Wormer <tituswormer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+file-saver
+MIT
+The MIT License
+
+Copyright © 2016 [Eli Grey][1].
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ [1]: http://eligrey.com
+
+
+format
+MIT
+
+formdata-node
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2017-present Nick K.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+function-bind
+MIT
+Copyright (c) 2013 Raynos.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+
+get-intrinsic
+MIT
+MIT License
+
+Copyright (c) 2020 Jordan Harband
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+has
+MIT
+Copyright (c) 2013 Thiago de Arruda
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+
+has-symbols
+MIT
+MIT License
+
+Copyright (c) 2016 Jordan Harband
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+highlight.js
+BSD-3-Clause
+BSD 3-Clause License
+
+Copyright (c) 2006, Ivan Sagalaev.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+* Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+hoist-non-react-statics
+BSD-3-Clause
+Software License Agreement (BSD License)
+========================================
+
+Copyright (c) 2015, Yahoo! Inc. All rights reserved.
+----------------------------------------------------
+
+Redistribution and use of this software in source and binary forms, with or
+without modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of Yahoo! Inc. nor the names of YUI's contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission of Yahoo! Inc.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+ieee754
+BSD-3-Clause
+Copyright 2008 Fair Oaks Labs, Inc.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+immutable
+MIT
+MIT License
+
+Copyright (c) 2014-present, Facebook, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+is-plain-object
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2014-2017, Jon Schlinkert.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+js-file-download
+MIT
+Copyright 2017 Kenneth Jiang
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
+
+
+js-yaml
+MIT
+(The MIT License)
+
+Copyright (C) 2011-2015 by Vitaly Puzrin
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+lodash
+MIT
+Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
+
+Based on Underscore.js, copyright Jeremy Ashkenas,
+DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
+
+This software consists of voluntary contributions made by many
+individuals. For exact contribution history, see the revision history
+available at https://github.com/lodash/lodash
+
+The following license applies to all parts of this software except as
+documented below:
+
+====
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====
+
+Copyright and related rights for sample code are waived via CC0. Sample
+code is defined as all source code displayed within the prose of the
+documentation.
+
+CC0: http://creativecommons.org/publicdomain/zero/1.0/
+
+====
+
+Files located in the node_modules and vendor directories are externally
+maintained libraries used by this software which have their own
+licenses; we recommend you read them, as their terms may differ from the
+terms above.
+
+
+lodash-es
+MIT
+Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
+
+Based on Underscore.js, copyright Jeremy Ashkenas,
+DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
+
+This software consists of voluntary contributions made by many
+individuals. For exact contribution history, see the revision history
+available at https://github.com/lodash/lodash
+
+The following license applies to all parts of this software except as
+documented below:
+
+====
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====
+
+Copyright and related rights for sample code are waived via CC0. Sample
+code is defined as all source code displayed within the prose of the
+documentation.
+
+CC0: http://creativecommons.org/publicdomain/zero/1.0/
+
+====
+
+Files located in the node_modules and vendor directories are externally
+maintained libraries used by this software which have their own
+licenses; we recommend you read them, as their terms may differ from the
+terms above.
+
+
+lodash.debounce
+MIT
+Copyright jQuery Foundation and other contributors <https://jquery.org/>
+
+Based on Underscore.js, copyright Jeremy Ashkenas,
+DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
+
+This software consists of voluntary contributions made by many
+individuals. For exact contribution history, see the revision history
+available at https://github.com/lodash/lodash
+
+The following license applies to all parts of this software except as
+documented below:
+
+====
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====
+
+Copyright and related rights for sample code are waived via CC0. Sample
+code is defined as all source code displayed within the prose of the
+documentation.
+
+CC0: http://creativecommons.org/publicdomain/zero/1.0/
+
+====
+
+Files located in the node_modules and vendor directories are externally
+maintained libraries used by this software which have their own
+licenses; we recommend you read them, as their terms may differ from the
+terms above.
+
+
+lodash.memoize
+MIT
+Copyright jQuery Foundation and other contributors <https://jquery.org/>
+
+Based on Underscore.js, copyright Jeremy Ashkenas,
+DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
+
+This software consists of voluntary contributions made by many
+individuals. For exact contribution history, see the revision history
+available at https://github.com/lodash/lodash
+
+The following license applies to all parts of this software except as
+documented below:
+
+====
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====
+
+Copyright and related rights for sample code are waived via CC0. Sample
+code is defined as all source code displayed within the prose of the
+documentation.
+
+CC0: http://creativecommons.org/publicdomain/zero/1.0/
+
+====
+
+Files located in the node_modules and vendor directories are externally
+maintained libraries used by this software which have their own
+licenses; we recommend you read them, as their terms may differ from the
+terms above.
+
+
+lodash.throttle
+MIT
+Copyright jQuery Foundation and other contributors <https://jquery.org/>
+
+Based on Underscore.js, copyright Jeremy Ashkenas,
+DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
+
+This software consists of voluntary contributions made by many
+individuals. For exact contribution history, see the revision history
+available at https://github.com/lodash/lodash
+
+The following license applies to all parts of this software except as
+documented below:
+
+====
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====
+
+Copyright and related rights for sample code are waived via CC0. Sample
+code is defined as all source code displayed within the prose of the
+documentation.
+
+CC0: http://creativecommons.org/publicdomain/zero/1.0/
+
+====
+
+Files located in the node_modules and vendor directories are externally
+maintained libraries used by this software which have their own
+licenses; we recommend you read them, as their terms may differ from the
+terms above.
+
+
+lowlight
+MIT
+(The MIT License)
+
+Copyright (c) 2016 Titus Wormer <tituswormer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+mobx
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2015 Michel Weststrate
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+moment
+MIT
+Copyright (c) JS Foundation and other contributors
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+
+ng-block-ui
+MIT
+MIT License
+
+Copyright (c) 2017
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+ng-click-outside
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2016 Eugene Cheung
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+ng2-charts
+ISC
+
+ngx-pipe-function
+MIT License
+
+Copyright (c) 2019 Artem Lanovyy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+ngx-toastr
+MIT
+The MIT License (MIT)
+
+Copyright (c) Scott Cooper <scttcper@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+object-assign
+MIT
+The MIT License (MIT)
+
+Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+object-inspect
+MIT
+MIT License
+
+Copyright (c) 2013 James Halliday
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+prop-types
+MIT
+MIT License
+
+Copyright (c) 2013-present, Facebook, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+punycode
+MIT
+Copyright Mathias Bynens <https://mathiasbynens.be/>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+qs
+BSD-3-Clause
+BSD 3-Clause License
+
+Copyright (c) 2014, Nathan LaFreniere and other [contributors](https://github.com/ljharb/qs/graphs/contributors)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+querystring
+MIT
+
+Copyright 2012 Irakli Gozalishvili. All rights reserved.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+
+querystringify
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2015 Unshift.io, Arnout Kazemier, the Contributors.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+
+randexp
+MIT
+MIT License
+
+Copyright (C) 2011 by fent
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+react
+MIT
+MIT License
+
+Copyright (c) Facebook, Inc. and its affiliates.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+react-copy-to-clipboard
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2016 Nik Butenko
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+
+react-debounce-input
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2016 Nik Butenko
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+
+react-dom
+MIT
+MIT License
+
+Copyright (c) Facebook, Inc. and its affiliates.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+react-immutable-proptypes
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2015 James Burnett
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+
+react-immutable-pure-component
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2017 Piotr Tomasz Monarski
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+react-is
+MIT
+MIT License
+
+Copyright (c) Facebook, Inc. and its affiliates.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+react-redux
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2015-present Dan Abramov
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+react-syntax-highlighter
+MIT
+MIT License
+
+Copyright (c) 2019 Conor Hastings
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+redux
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2015-present Dan Abramov
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+redux-immutable
+BSD-3-Clause
+Copyright (c) 2016, Gajus Kuizinas (http://gajus.com/)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the Gajus Kuizinas (http://gajus.com/) nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ANUARY BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+remarkable
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2014-2016, Jon Schlinkert
+Copyright (c) 2014 Jon Schlinkert, Vitaly Puzrin.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+repeat-string
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2014-2016, Jon Schlinkert.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+requires-port
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2015 Unshift.io, Arnout Kazemier, the Contributors.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+
+reselect
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2015-2018 Reselect Contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+ret
+MIT
+MIT License
+
+Copyright (C) 2011 by fent
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+rxjs
+Apache-2.0
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright (c) 2015-2018 Google, Inc., Netflix, Inc., Microsoft Corp. and contributors
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
+scheduler
+MIT
+MIT License
+
+Copyright (c) Facebook, Inc. and its affiliates.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+serialize-error
+MIT
+MIT License
+
+Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+side-channel
+MIT
+MIT License
+
+Copyright (c) 2019 Jordan Harband
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+simplebar
+MIT
+
+simplebar-angular
+The MIT License (MIT)
+
+Copyright (c) 2015 Jonathan Nicol
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+swagger-client
+Apache-2.0
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+swagger-ui
+Apache-2.0
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+toggle-selection
+MIT
+
+traverse
+MIT
+Copyright 2010 James Halliday (mail@substack.net)
+
+This project is free software released under the MIT/X11 license:
+http://www.opensource.org/licenses/mit-license.php
+
+Copyright 2010 James Halliday (mail@substack.net)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+tslib
+0BSD
+Copyright (c) Microsoft Corporation.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+url
+MIT
+The MIT License (MIT)
+
+Copyright Joyent, Inc. and other Node contributors.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+url-parse
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2015 Unshift.io, Arnout Kazemier, the Contributors.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+
+xml-but-prettier
+MIT
+The MIT License (MIT)
+
+Copyright (c) 2015 Jonathan Persson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+zenscroll
+Unlicense
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org>
+
+
+
+zone.js
+MIT
+The MIT License
+
+Copyright (c) 2010-2020 Google LLC. http://angular.io/license
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/483.f42c1d67e206231ecdac.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/483.f42c1d67e206231ecdac.js
new file mode 100644
index 000000000..b1f3294a4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/483.f42c1d67e206231ecdac.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkceph_dashboard=self.webpackChunkceph_dashboard||[]).push([[483],{70483:(ct,Oe,p)=>{p.r(Oe),p.d(Oe,{BlockModule:()=>$t,RoutedBlockModule:()=>sr});var l=p(12057),a=p(24751),m=p(6283),ne=p(19723),N=p(38549),Ie=p(37496),v=p(79512),U=p(4222),re=p(54462),Ae=p(44466),be=p(23815),S=p.n(be),le=p(35758),D=p(64762),ie=p(58497),V=p(93523),e=p(74788);let X=class{constructor(s){this.http=s}listTargets(){return this.http.get("api/iscsi/target")}getTarget(s){return this.http.get(`api/iscsi/target/${s}`)}updateTarget(s,t){return this.http.put(`api/iscsi/target/${s}`,t,{observe:"response"})}status(){return this.http.get("ui-api/iscsi/status")}settings(){return this.http.get("ui-api/iscsi/settings")}version(){return this.http.get("ui-api/iscsi/version")}portals(){return this.http.get("ui-api/iscsi/portals")}createTarget(s){return this.http.post("api/iscsi/target",s,{observe:"response"})}deleteTarget(s){return this.http.delete(`api/iscsi/target/${s}`,{observe:"response"})}getDiscovery(){return this.http.get("api/iscsi/discoveryauth")}updateDiscovery(s){return this.http.put("api/iscsi/discoveryauth",s)}overview(){return this.http.get("ui-api/iscsi/overview")}};X.\u0275fac=function(s){return new(s||X)(e.LFG(ie.eN))},X.\u0275prov=e.Yz7({token:X,factory:X.\u0275fac,providedIn:"root"}),X=(0,D.gn)([V.o,(0,D.w6)("design:paramtypes",[ie.eN])],X);var Ne=p(88002),Fe=p(76189),L=p(19358),he=p(34089);let q=class extends Fe.S{constructor(s,t){super(),this.http=s,this.rbdConfigurationService=t}isRBDPool(s){return-1!==S().indexOf(s.application_metadata,"rbd")&&!s.pool_name.includes("/")}create(s){return this.http.post("api/block/image",s,{observe:"response"})}delete(s){return this.http.delete(`api/block/image/${s.toStringEncoded()}`,{observe:"response"})}update(s,t){return this.http.put(`api/block/image/${s.toStringEncoded()}`,t,{observe:"response"})}get(s){return this.http.get(`api/block/image/${s.toStringEncoded()}`)}list(s){return this.http.get("api/block/image",{params:s,headers:{Accept:this.getVersionHeaderValue(2,0)},observe:"response"}).pipe((0,Ne.U)(t=>t.body.map(o=>(o.value.map(i=>(i.configuration&&i.configuration.map(_=>Object.assign(_,this.rbdConfigurationService.getOptionByName(_.name))),i)),o.headers=t.headers,o))))}copy(s,t){return this.http.post(`api/block/image/${s.toStringEncoded()}/copy`,t,{observe:"response"})}flatten(s){return this.http.post(`api/block/image/${s.toStringEncoded()}/flatten`,null,{observe:"response"})}defaultFeatures(){return this.http.get("api/block/image/default_features")}cloneFormatVersion(){return this.http.get("api/block/image/clone_format_version")}createSnapshot(s,t){const o={snapshot_name:t};return this.http.post(`api/block/image/${s.toStringEncoded()}/snap`,o,{observe:"response"})}renameSnapshot(s,t,o){const i={new_snap_name:o};return this.http.put(`api/block/image/${s.toStringEncoded()}/snap/${t}`,i,{observe:"response"})}protectSnapshot(s,t,o){const i={is_protected:o};return this.http.put(`api/block/image/${s.toStringEncoded()}/snap/${t}`,i,{observe:"response"})}rollbackSnapshot(s,t){return this.http.post(`api/block/image/${s.toStringEncoded()}/snap/${t}/rollback`,null,{observe:"response"})}cloneSnapshot(s,t,o){return this.http.post(`api/block/image/${s.toStringEncoded()}/snap/${t}/clone`,o,{observe:"response"})}deleteSnapshot(s,t){return this.http.delete(`api/block/image/${s.toStringEncoded()}/snap/${t}`,{observe:"response"})}listTrash(){return this.http.get("api/block/image/trash/")}createNamespace(s,t){return this.http.post(`api/block/pool/${s}/namespace`,{namespace:t},{observe:"response"})}listNamespaces(s){return this.http.get(`api/block/pool/${s}/namespace/`)}deleteNamespace(s,t){return this.http.delete(`api/block/pool/${s}/namespace/${t}`,{observe:"response"})}moveTrash(s,t){return this.http.post(`api/block/image/${s.toStringEncoded()}/move_trash`,{delay:t},{observe:"response"})}purgeTrash(s){return this.http.post(`api/block/image/trash/purge/?pool_name=${s}`,null,{observe:"response"})}restoreTrash(s,t){return this.http.post(`api/block/image/trash/${s.toStringEncoded()}/restore`,{new_image_name:t},{observe:"response"})}removeTrash(s,t=!1){return this.http.delete(`api/block/image/trash/${s.toStringEncoded()}/?force=${t}`,{observe:"response"})}};q.\u0275fac=function(s){return new(s||q)(e.LFG(ie.eN),e.LFG(he.n))},q.\u0275prov=e.Yz7({token:q,factory:q.\u0275fac,providedIn:"root"}),(0,D.gn)([(0,D.fM)(1,V.G),(0,D.w6)("design:type",Function),(0,D.w6)("design:paramtypes",[L.N,String]),(0,D.w6)("design:returntype",void 0)],q.prototype,"createSnapshot",null),(0,D.gn)([(0,D.fM)(2,V.G),(0,D.w6)("design:type",Function),(0,D.w6)("design:paramtypes",[L.N,String,String]),(0,D.w6)("design:returntype",void 0)],q.prototype,"renameSnapshot",null),(0,D.gn)([(0,D.fM)(2,V.G),(0,D.w6)("design:type",Function),(0,D.w6)("design:paramtypes",[L.N,String,Boolean]),(0,D.w6)("design:returntype",void 0)],q.prototype,"protectSnapshot",null),(0,D.gn)([(0,D.fM)(1,V.G),(0,D.w6)("design:type",Function),(0,D.w6)("design:paramtypes",[L.N,String]),(0,D.w6)("design:returntype",void 0)],q.prototype,"restoreTrash",null),q=(0,D.gn)([V.o,(0,D.w6)("design:paramtypes",[ie.eN,he.n])],q);var F=p(7022),x=p(14745),T=p(65862),H=p(93614),y=p(95463),z=p(77205),A=p(86919),R=p(76111),u=p(32337),C=p(60312),h=p(41582),O=p(56310),$=p(87925),k=p(94276),j=p(30839);function to(n,s){if(1&n&&(e.TgZ(0,"option",6),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("ngValue",t),e.xp6(1),e.Oqu(t)}}function oo(n,s){if(1&n&&(e.TgZ(0,"select",5),e._UZ(1,"option",6),e.YNc(2,to,2,2,"option",7),e.qZA()),2&n){const t=e.oxw();e.s9C("id",t.setting),e.s9C("name",t.setting),e.Q6J("formControlName",t.setting),e.xp6(1),e.Q6J("ngValue",null),e.xp6(1),e.Q6J("ngForOf",t.limits.values)}}function no(n,s){if(1&n&&e._UZ(0,"input",10),2&n){const t=e.oxw(2);e.Q6J("formControlName",t.setting)}}function io(n,s){if(1&n&&e._UZ(0,"input",11),2&n){const t=e.oxw(2);e.Q6J("formControlName",t.setting)}}function so(n,s){if(1&n&&(e.ynx(0),e._UZ(1,"br"),e.TgZ(2,"div",12),e._UZ(3,"input",13),e.TgZ(4,"label",14),e._uU(5,"Yes"),e.qZA(),e.qZA(),e.TgZ(6,"div",12),e._UZ(7,"input",13),e.TgZ(8,"label",14),e._uU(9,"No"),e.qZA(),e.qZA(),e.BQk()),2&n){const t=e.oxw(2);e.xp6(3),e.Q6J("id",t.setting+"True")("value",!0)("formControlName",t.setting),e.xp6(1),e.Q6J("for",t.setting+"True"),e.xp6(3),e.Q6J("id",t.setting+"False")("value",!1)("formControlName",t.setting),e.xp6(1),e.Q6J("for",t.setting+"False")}}function _o(n,s){if(1&n&&(e.TgZ(0,"span"),e.YNc(1,no,1,1,"input",8),e.YNc(2,io,1,1,"input",9),e.YNc(3,so,10,8,"ng-container",3),e.qZA()),2&n){const t=e.oxw();e.xp6(1),e.Q6J("ngIf","int"===t.limits.type),e.xp6(1),e.Q6J("ngIf","str"===t.limits.type),e.xp6(1),e.Q6J("ngIf","bool"===t.limits.type)}}function ao(n,s){if(1&n&&(e.TgZ(0,"span",15),e.ynx(1),e.SDv(2,16),e.BQk(),e.qZA()),2&n){const t=e.oxw();e.xp6(2),e.pQV(t.limits.min),e.QtT(2)}}function ro(n,s){if(1&n&&(e.TgZ(0,"span",15),e.ynx(1),e.SDv(2,17),e.BQk(),e.qZA()),2&n){const t=e.oxw();e.xp6(2),e.pQV(t.limits.max),e.QtT(2)}}let dt=(()=>{class n{ngOnInit(){const t=[];"min"in this.limits&&t.push(a.kI.min(this.limits.min)),"max"in this.limits&&t.push(a.kI.max(this.limits.max)),this.settingsForm.get(this.setting).setValidators(t)}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-iscsi-setting"]],inputs:{settingsForm:"settingsForm",formDir:"formDir",setting:"setting",limits:"limits"},decls:7,vars:7,consts:function(){let s,t;return s="Must be greater than or equal to " + "\ufffd0\ufffd" + ".",t="Must be less than or equal to " + "\ufffd0\ufffd" + ".",[[1,"form-group",3,"formGroup"],[1,"col-form-label",3,"for"],["class","form-control",3,"id","name","formControlName",4,"ngIf"],[4,"ngIf"],["class","invalid-feedback",4,"ngIf"],[1,"form-control",3,"id","name","formControlName"],[3,"ngValue"],[3,"ngValue",4,"ngFor","ngForOf"],["type","number","class","form-control",3,"formControlName",4,"ngIf"],["type","text","class","form-control",3,"formControlName",4,"ngIf"],["type","number",1,"form-control",3,"formControlName"],["type","text",1,"form-control",3,"formControlName"],[1,"custom-control","custom-radio","custom-control-inline"],["type","radio",1,"custom-control-input",3,"id","value","formControlName"],[1,"custom-control-label",3,"for"],[1,"invalid-feedback"],s,t]},template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"label",1),e._uU(2),e.qZA(),e.YNc(3,oo,3,5,"select",2),e.YNc(4,_o,4,3,"span",3),e.YNc(5,ao,3,1,"span",4),e.YNc(6,ro,3,1,"span",4),e.qZA()),2&t&&(e.Q6J("formGroup",o.settingsForm),e.xp6(1),e.s9C("for",o.setting),e.xp6(1),e.Oqu(o.setting),e.xp6(1),e.Q6J("ngIf","enum"===o.limits.type),e.xp6(1),e.Q6J("ngIf","enum"!==o.limits.type),e.xp6(1),e.Q6J("ngIf",o.settingsForm.showError(o.setting,o.formDir,"min")),e.xp6(1),e.Q6J("ngIf",o.settingsForm.showError(o.setting,o.formDir,"max")))},directives:[O.P,a.JL,a.sg,h.V,l.O5,$.o,a.EJ,k.b,a.JJ,a.u,a.YN,a.Kr,l.sg,a.wV,a.Fj,a._],styles:[""]}),n})();var Je=p(88820);function lo(n,s){1&n&&(e.TgZ(0,"span",29),e.SDv(1,30),e.qZA())}function co(n,s){if(1&n&&(e.TgZ(0,"span"),e.TgZ(1,"legend",10),e.SDv(2,21),e.qZA(),e.TgZ(3,"div",12),e.TgZ(4,"div",13),e.TgZ(5,"label",22),e.SDv(6,23),e.qZA(),e._UZ(7,"input",24),e.YNc(8,lo,2,0,"span",25),e.qZA(),e.qZA(),e.TgZ(9,"div",12),e.TgZ(10,"div",13),e.TgZ(11,"label",26),e.SDv(12,27),e.qZA(),e._UZ(13,"input",28),e.qZA(),e.qZA(),e.qZA()),2&n){const t=e.oxw(),o=e.MAs(9);e.xp6(8),e.Q6J("ngIf",t.settingsForm.showError("lun",o,"required"))}}function po(n,s){if(1&n&&(e.TgZ(0,"option",31),e._uU(1),e.ALo(2,"iscsiBackstore"),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t),e.xp6(1),e.Oqu(e.lcZ(2,2,t))}}function go(n,s){if(1&n&&(e.TgZ(0,"div",12),e.TgZ(1,"div",13),e._UZ(2,"cd-iscsi-setting",33),e.qZA(),e.qZA()),2&n){const t=s.$implicit,o=e.oxw(2).$implicit,i=e.oxw(),_=e.MAs(9);e.xp6(2),e.Q6J("settingsForm",i.settingsForm)("formDir",_)("setting",t.key)("limits",i.getDiskControlLimits(o,t.key))}}function uo(n,s){if(1&n&&(e.ynx(0),e.YNc(1,go,3,4,"div",32),e.ALo(2,"keyvalue"),e.BQk()),2&n){const t=e.oxw().$implicit,o=e.oxw();e.xp6(1),e.Q6J("ngForOf",e.lcZ(2,1,o.disk_default_controls[t]))}}function mo(n,s){if(1&n&&(e.ynx(0),e.YNc(1,uo,3,3,"ng-container",9),e.BQk()),2&n){const t=s.$implicit,o=e.oxw();e.xp6(1),e.Q6J("ngIf",o.settingsForm.value.backstore===t)}}let To=(()=>{class n{constructor(t,o,i){this.activeModal=t,this.iscsiService=o,this.actionLabels=i}ngOnInit(){const t={backstore:new a.NI(this.imagesSettings[this.image].backstore),lun:new a.NI(this.imagesSettings[this.image].lun),wwn:new a.NI(this.imagesSettings[this.image].wwn)};S().forEach(this.backstores,o=>{const i=this.imagesSettings[this.image][o]||{};S().forIn(this.disk_default_controls[o],(_,r)=>{t[r]=new a.NI(i[r])})}),this.settingsForm=new y.d(t)}getDiskControlLimits(t,o){return this.disk_controls_limits?this.disk_controls_limits[t][o]:{type:"int"}}save(){const t=this.settingsForm.controls.backstore.value,o=this.settingsForm.controls.lun.value,i=this.settingsForm.controls.wwn.value,_={};S().forIn(this.settingsForm.controls,(r,c)=>{""!==r.value&&null!==r.value&&c in this.disk_default_controls[this.settingsForm.value.backstore]&&(_[c]=r.value,S().forEach(this.backstores,d=>{d!==t&&c in(this.imagesSettings[this.image][d]||{})&&(this.imagesSettings[this.image][d][c]=r.value)}))}),this.imagesSettings[this.image].backstore=t,this.imagesSettings[this.image].lun=o,this.imagesSettings[this.image].wwn=i,this.imagesSettings[this.image][t]=_,this.imagesSettings=Object.assign({},this.imagesSettings),this.control.updateValueAndValidity({emitEvent:!1}),this.activeModal.close()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(N.Kz),e.Y36(X),e.Y36(v.p4))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-iscsi-target-image-settings-modal"]],decls:25,vars:8,consts:function(){let s,t,o,i,_,r,c,d;return s="Configure",t="Changing these parameters from their default values is usually not necessary.",o="Settings",i="Backstore",_="Identifier",r="lun",c="wwn",d="This field is required.",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["name","settingsForm","novalidate","",1,"form",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],[1,"alert-warning"],t,[4,"ngIf"],[1,"cd-header"],o,[1,"form-group","row"],[1,"col-sm-12"],[1,"col-form-label"],i,["id","backstore","name","backstore","formControlName","backstore",1,"form-control"],[3,"value",4,"ngFor","ngForOf"],[4,"ngFor","ngForOf"],[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],_,["for","lun",1,"col-form-label","required"],r,["type","number","id","lun","name","lun","formControlName","lun",1,"form-control"],["class","invalid-feedback",4,"ngIf"],["for","wwn",1,"col-form-label"],c,["type","text","id","wwn","name","wwn","formControlName","wwn",1,"form-control"],[1,"invalid-feedback"],d,[3,"value"],["class","form-group row",4,"ngFor","ngForOf"],[3,"settingsForm","formDir","setting","limits"]]},template:function(t,o){1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.ynx(2),e.SDv(3,2),e.BQk(),e._uU(4,"\xa0 "),e.TgZ(5,"small"),e._uU(6),e.qZA(),e.BQk(),e.ynx(7,3),e.TgZ(8,"form",4,5),e.TgZ(10,"div",6),e.TgZ(11,"p",7),e.SDv(12,8),e.qZA(),e.YNc(13,co,14,1,"span",9),e.TgZ(14,"legend",10),e.SDv(15,11),e.qZA(),e.TgZ(16,"div",12),e.TgZ(17,"div",13),e.TgZ(18,"label",14),e.SDv(19,15),e.qZA(),e.TgZ(20,"select",16),e.YNc(21,po,3,4,"option",17),e.qZA(),e.qZA(),e.qZA(),e.YNc(22,mo,2,1,"ng-container",18),e.qZA(),e.TgZ(23,"div",19),e.TgZ(24,"cd-form-button-panel",20),e.NdJ("submitActionEvent",function(){return o.save()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t&&(e.Q6J("modalRef",o.activeModal),e.xp6(6),e.Oqu(o.image),e.xp6(2),e.Q6J("formGroup",o.settingsForm),e.xp6(5),e.Q6J("ngIf",o.api_version>=1),e.xp6(8),e.Q6J("ngForOf",o.backstores),e.xp6(1),e.Q6J("ngForOf",o.backstores),e.xp6(2),e.Q6J("form",o.settingsForm)("submitText",o.actionLabels.UPDATE))},directives:[C.z,a._Y,a.JL,a.sg,h.V,l.O5,O.P,$.o,a.EJ,k.b,a.JJ,a.u,l.sg,j.p,a.wV,a.Fj,a.YN,a.Kr,dt],pipes:[Je.V,l.Nd],styles:[""]}),n})();function fo(n,s){if(1&n&&(e.TgZ(0,"div",12),e.TgZ(1,"div",13),e._UZ(2,"cd-iscsi-setting",14),e.qZA(),e.qZA()),2&n){const t=s.$implicit,o=e.oxw(),i=e.MAs(5);e.xp6(2),e.Q6J("settingsForm",o.settingsForm)("formDir",i)("setting",t.key)("limits",o.getTargetControlLimits(t.key))}}let Co=(()=>{class n{constructor(t,o,i){this.activeModal=t,this.iscsiService=o,this.actionLabels=i}ngOnInit(){const t={};S().forIn(this.target_default_controls,(o,i)=>{t[i]=new a.NI(this.target_controls.value[i])}),this.settingsForm=new y.d(t)}save(){const t={};S().forIn(this.settingsForm.controls,(o,i)=>{""===o.value||null===o.value||(t[i]=o.value)}),this.target_controls.setValue(t),this.activeModal.close()}getTargetControlLimits(t){return this.target_controls_limits?this.target_controls_limits[t]:["Yes","No"].includes(this.target_default_controls[t])?{type:"bool"}:{type:"int"}}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(N.Kz),e.Y36(X),e.Y36(v.p4))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-iscsi-target-iqn-settings-modal"]],decls:13,vars:7,consts:function(){let s,t;return s="Advanced Settings",t="Changing these parameters from their default values is usually not necessary.",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["name","settingsForm","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],[1,"alert-warning"],t,["class","form-group row",4,"ngFor","ngForOf"],[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],[1,"form-group","row"],[1,"col-sm-12"],[3,"settingsForm","formDir","setting","limits"]]},template:function(t,o){1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.BQk(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.TgZ(7,"p",7),e.SDv(8,8),e.qZA(),e.YNc(9,fo,3,4,"div",9),e.ALo(10,"keyvalue"),e.qZA(),e.TgZ(11,"div",10),e.TgZ(12,"cd-form-button-panel",11),e.NdJ("submitActionEvent",function(){return o.save()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t&&(e.Q6J("modalRef",o.activeModal),e.xp6(4),e.Q6J("formGroup",o.settingsForm),e.xp6(5),e.Q6J("ngForOf",e.lcZ(10,5,o.settingsForm.controls)),e.xp6(3),e.Q6J("form",o.settingsForm)("submitText",o.actionLabels.UPDATE))},directives:[C.z,a._Y,a.JL,a.sg,h.V,l.sg,j.p,O.P,dt],pipes:[l.Nd],styles:[""]}),n})();var de=p(63285),pt=p(63622);let So=(()=>{class n{constructor(t){this.ngControl=t}onInput(t){this.setValue(t)}setValue(t){t=S().isString(t)?t.trim():t,this.ngControl.control.setValue(t)}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(a.a5))},n.\u0275dir=e.lG2({type:n,selectors:[["","cdTrim",""]],hostBindings:function(t,o){1&t&&e.NdJ("input",function(_){return o.onInput(_.target.value)})}}),n})();var Eo=p(39092),gt=p(4416),Ye=p(58039),et=p(10545);function Ro(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,42),e.qZA())}function Mo(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,43),e.qZA())}function Oo(n,s){1&n&&(e.TgZ(0,"span",41),e.ynx(1),e.SDv(2,44),e.BQk(),e._UZ(3,"br"),e.ynx(4),e.SDv(5,45),e.BQk(),e._UZ(6,"br"),e.TgZ(7,"a",46),e.SDv(8,47),e.qZA(),e.qZA())}function Ao(n,s){1&n&&(e.TgZ(0,"span",48),e.SDv(1,49),e.qZA())}const J=function(n){return[n]};function ho(n,s){if(1&n){const t=e.EpF();e.ynx(0),e.TgZ(1,"div",50),e._UZ(2,"input",51),e.TgZ(3,"span",14),e.TgZ(4,"button",52),e.NdJ("click",function(){const i=e.CHM(t),_=i.index,r=i.$implicit;return e.oxw(2).removePortal(_,r)}),e._UZ(5,"i",16),e.qZA(),e.qZA(),e.qZA(),e.BQk()}if(2&n){const t=s.$implicit,o=e.oxw(2);e.xp6(2),e.Q6J("value",t),e.xp6(3),e.Q6J("ngClass",e.VKq(2,J,o.icons.destroy))}}function Po(n,s){if(1&n&&(e.TgZ(0,"span",41),e.SDv(1,53),e.qZA()),2&n){const t=e.oxw(2);e.xp6(1),e.pQV(t.minimum_gateways),e.QtT(1)}}function Io(n,s){if(1&n&&(e.TgZ(0,"div",56),e._uU(1),e.qZA()),2&n){const t=e.oxw().$implicit,o=e.oxw(2);e.xp6(1),e.hij("lun: ",o.imagesSettings[t].lun,"")}}function bo(n,s){if(1&n&&(e.ynx(0),e.SDv(1,57),e.ALo(2,"iscsiBackstore"),e.BQk()),2&n){const t=e.oxw().$implicit,o=e.oxw(2);e.xp6(2),e.pQV(e.lcZ(2,1,o.imagesSettings[t].backstore)),e.QtT(1)}}function No(n,s){1&n&&(e.ynx(0),e.SDv(1,58),e.BQk())}function Fo(n,s){if(1&n){const t=e.EpF();e.ynx(0),e.TgZ(1,"div",50),e._UZ(2,"input",51),e.TgZ(3,"span",14),e.YNc(4,Io,2,1,"div",54),e.TgZ(5,"button",52),e.NdJ("click",function(){const _=e.CHM(t).$implicit;return e.oxw(2).imageSettingsModal(_)}),e._UZ(6,"i",16),e.qZA(),e.TgZ(7,"button",52),e.NdJ("click",function(){const i=e.CHM(t),_=i.index,r=i.$implicit;return e.oxw(2).removeImage(_,r)}),e._UZ(8,"i",16),e.qZA(),e.qZA(),e.qZA(),e.TgZ(9,"span",48),e.YNc(10,bo,3,3,"ng-container",55),e.YNc(11,No,2,0,"ng-container",55),e.qZA(),e.BQk()}if(2&n){const t=s.$implicit,o=e.oxw(2);e.xp6(2),e.Q6J("value",t),e.xp6(2),e.Q6J("ngIf",o.api_version>=1),e.xp6(2),e.Q6J("ngClass",e.VKq(6,J,o.icons.deepCheck)),e.xp6(2),e.Q6J("ngClass",e.VKq(8,J,o.icons.destroy)),e.xp6(2),e.Q6J("ngIf",o.backstores.length>1),e.xp6(1),e.Q6J("ngIf",o.hasAdvancedSettings(o.imagesSettings[t][o.imagesSettings[t].backstore]))}}function Do(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,59),e.qZA())}function vo(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,60),e.qZA())}function Lo(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,78),e.qZA())}function $o(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,79),e.qZA())}function Zo(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,80),e.qZA())}function Bo(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,81),e.qZA())}function Go(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,82),e.qZA())}function xo(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,83),e.qZA())}function yo(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,84),e.qZA())}function wo(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,85),e.qZA())}function qo(n,s){if(1&n&&(e.TgZ(0,"div",61),e.TgZ(1,"div",8),e.TgZ(2,"label",62),e.ynx(3),e.SDv(4,63),e.BQk(),e.qZA(),e.TgZ(5,"div",11),e._UZ(6,"input",64),e.YNc(7,Lo,2,0,"span",17),e.YNc(8,$o,2,0,"span",17),e.qZA(),e.qZA(),e.TgZ(9,"div",8),e.TgZ(10,"label",65),e.ynx(11),e.SDv(12,66),e.BQk(),e.qZA(),e.TgZ(13,"div",11),e.TgZ(14,"div",12),e._UZ(15,"input",67),e.TgZ(16,"span",14),e._UZ(17,"button",68),e._UZ(18,"cd-copy-2-clipboard-button",69),e.qZA(),e.qZA(),e.YNc(19,Zo,2,0,"span",17),e.YNc(20,Bo,2,0,"span",17),e.qZA(),e.qZA(),e.TgZ(21,"div",8),e.TgZ(22,"label",70),e.ynx(23),e.SDv(24,71),e.BQk(),e.qZA(),e.TgZ(25,"div",11),e._UZ(26,"input",72),e.YNc(27,Go,2,0,"span",17),e.YNc(28,xo,2,0,"span",17),e.qZA(),e.qZA(),e.TgZ(29,"div",8),e.TgZ(30,"label",73),e.ynx(31),e.SDv(32,74),e.BQk(),e.qZA(),e.TgZ(33,"div",11),e.TgZ(34,"div",12),e._UZ(35,"input",75),e.TgZ(36,"span",14),e._UZ(37,"button",76),e._UZ(38,"cd-copy-2-clipboard-button",77),e.qZA(),e.qZA(),e.YNc(39,yo,2,0,"span",17),e.YNc(40,wo,2,0,"span",17),e.qZA(),e.qZA(),e.qZA()),2&n){e.oxw();const t=e.MAs(2),o=e.oxw();e.xp6(7),e.Q6J("ngIf",o.targetForm.showError("user",t,"required")),e.xp6(1),e.Q6J("ngIf",o.targetForm.showError("user",t,"pattern")),e.xp6(11),e.Q6J("ngIf",o.targetForm.showError("password",t,"required")),e.xp6(1),e.Q6J("ngIf",o.targetForm.showError("password",t,"pattern")),e.xp6(7),e.Q6J("ngIf",o.targetForm.showError("mutual_user",t,"required")),e.xp6(1),e.Q6J("ngIf",o.targetForm.showError("mutual_user",t,"pattern")),e.xp6(11),e.Q6J("ngIf",o.targetForm.showError("mutual_password",t,"required")),e.xp6(1),e.Q6J("ngIf",o.targetForm.showError("mutual_password",t,"pattern"))}}function Ho(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,115),e.qZA())}function ko(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,116),e.qZA())}function Ko(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,117),e.qZA())}function Xo(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,118),e.qZA())}function Qo(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,119),e.qZA())}function zo(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,120),e.qZA())}function Jo(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,121),e.qZA())}function Yo(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,122),e.qZA())}function Vo(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,123),e.qZA())}function Uo(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,124),e.qZA())}function jo(n,s){1&n&&(e.TgZ(0,"span",41),e.SDv(1,125),e.qZA())}function Wo(n,s){if(1&n){const t=e.EpF();e.ynx(0),e.TgZ(1,"div",50),e._UZ(2,"input",51),e.TgZ(3,"span",14),e.TgZ(4,"button",52),e.NdJ("click",function(){const i=e.CHM(t),_=i.index,r=i.$implicit,c=e.oxw(),d=c.$implicit,g=c.index;return e.oxw(3).removeInitiatorImage(d,_,g,r)}),e._UZ(5,"i",16),e.qZA(),e.qZA(),e.qZA(),e.BQk()}if(2&n){const t=s.$implicit,o=e.oxw(4);e.xp6(2),e.Q6J("value",t),e.xp6(3),e.Q6J("ngClass",e.VKq(2,J,o.icons.destroy))}}function en(n,s){1&n&&(e.TgZ(0,"span"),e.SDv(1,126),e.qZA())}function tn(n,s){if(1&n&&(e.TgZ(0,"div",22),e.TgZ(1,"div",23),e.TgZ(2,"cd-select",127),e._UZ(3,"i",25),e.ynx(4),e.SDv(5,128),e.BQk(),e.qZA(),e.qZA(),e.qZA()),2&n){const t=e.oxw(),o=t.$implicit,i=t.index,_=e.oxw(3);e.xp6(2),e.Q6J("data",o.getValue("luns"))("options",_.imagesInitiatorSelections[i])("messages",_.messages.initiatorImage),e.xp6(1),e.Q6J("ngClass",e.VKq(4,J,_.icons.add))}}function on(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",92),e.TgZ(1,"div",5),e.ynx(2),e.SDv(3,93),e.BQk(),e._uU(4),e.TgZ(5,"button",94),e.NdJ("click",function(){const _=e.CHM(t).index;return e.oxw(3).removeInitiator(_)}),e._UZ(6,"i",25),e.qZA(),e.qZA(),e.TgZ(7,"div",7),e.TgZ(8,"div",8),e.TgZ(9,"label",95),e.SDv(10,96),e.qZA(),e.TgZ(11,"div",11),e.TgZ(12,"input",97),e.NdJ("blur",function(){return e.CHM(t),e.oxw(3).updatedInitiatorSelector()}),e.qZA(),e.YNc(13,Ho,2,0,"span",17),e.YNc(14,ko,2,0,"span",17),e.YNc(15,Ko,2,0,"span",17),e.qZA(),e.qZA(),e.ynx(16,61),e.TgZ(17,"div",8),e.TgZ(18,"label",98),e.SDv(19,99),e.qZA(),e.TgZ(20,"div",11),e._UZ(21,"input",100),e.YNc(22,Xo,2,0,"span",17),e.YNc(23,Qo,2,0,"span",17),e.qZA(),e.qZA(),e.TgZ(24,"div",8),e.TgZ(25,"label",101),e.SDv(26,102),e.qZA(),e.TgZ(27,"div",11),e.TgZ(28,"div",12),e._UZ(29,"input",103),e.TgZ(30,"span",14),e._UZ(31,"button",104),e._UZ(32,"cd-copy-2-clipboard-button",105),e.qZA(),e.qZA(),e.YNc(33,zo,2,0,"span",17),e.YNc(34,Jo,2,0,"span",17),e.qZA(),e.qZA(),e.TgZ(35,"div",8),e.TgZ(36,"label",106),e.ynx(37),e.SDv(38,107),e.BQk(),e.qZA(),e.TgZ(39,"div",11),e._UZ(40,"input",108),e.YNc(41,Yo,2,0,"span",17),e.YNc(42,Vo,2,0,"span",17),e.qZA(),e.qZA(),e.TgZ(43,"div",8),e.TgZ(44,"label",109),e.SDv(45,110),e.qZA(),e.TgZ(46,"div",11),e.TgZ(47,"div",12),e._UZ(48,"input",111),e.TgZ(49,"span",14),e._UZ(50,"button",104),e._UZ(51,"cd-copy-2-clipboard-button",105),e.qZA(),e.qZA(),e.YNc(52,Uo,2,0,"span",17),e.YNc(53,jo,2,0,"span",17),e.qZA(),e.qZA(),e.BQk(),e.TgZ(54,"div",8),e.TgZ(55,"label",112),e.SDv(56,113),e.qZA(),e.TgZ(57,"div",11),e.YNc(58,Wo,6,4,"ng-container",21),e.YNc(59,en,2,0,"span",55),e.YNc(60,tn,6,6,"div",114),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=s.$implicit,o=s.index;e.oxw(2);const i=e.MAs(2),_=e.oxw();e.Q6J("formGroup",t),e.xp6(4),e.hij(": ",t.getValue("client_iqn")," "),e.xp6(2),e.Q6J("ngClass",e.VKq(25,J,_.icons.destroy)),e.xp6(7),e.Q6J("ngIf",t.showError("client_iqn",i,"notUnique")),e.xp6(1),e.Q6J("ngIf",t.showError("client_iqn",i,"required")),e.xp6(1),e.Q6J("ngIf",t.showError("client_iqn",i,"pattern")),e.xp6(6),e.Q6J("id","user"+o),e.xp6(1),e.Q6J("ngIf",t.showError("user",i,"required")),e.xp6(1),e.Q6J("ngIf",t.showError("user",i,"pattern")),e.xp6(6),e.Q6J("id","password"+o),e.xp6(2),e.Q6J("cdPasswordButton","password"+o),e.xp6(1),e.Q6J("source","password"+o),e.xp6(1),e.Q6J("ngIf",t.showError("password",i,"required")),e.xp6(1),e.Q6J("ngIf",t.showError("password",i,"pattern")),e.xp6(6),e.Q6J("id","mutual_user"+o),e.xp6(1),e.Q6J("ngIf",t.showError("mutual_user",i,"required")),e.xp6(1),e.Q6J("ngIf",t.showError("mutual_user",i,"pattern")),e.xp6(6),e.Q6J("id","mutual_password"+o),e.xp6(2),e.Q6J("cdPasswordButton","mutual_password"+o),e.xp6(1),e.Q6J("source","mutual_password"+o),e.xp6(1),e.Q6J("ngIf",t.showError("mutual_password",i,"required")),e.xp6(1),e.Q6J("ngIf",t.showError("mutual_password",i,"pattern")),e.xp6(5),e.Q6J("ngForOf",t.getValue("luns")),e.xp6(1),e.Q6J("ngIf",t.getValue("cdIsInGroup")),e.xp6(1),e.Q6J("ngIf",!t.getValue("cdIsInGroup"))}}function nn(n,s){1&n&&(e.TgZ(0,"span",48),e.SDv(1,129),e.qZA())}function sn(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",8),e.TgZ(1,"label",86),e.SDv(2,87),e.qZA(),e.TgZ(3,"div",88),e.YNc(4,on,61,27,"div",89),e.TgZ(5,"div",22),e.TgZ(6,"div",23),e.YNc(7,nn,2,0,"span",18),e.TgZ(8,"button",90),e.NdJ("click",function(){return e.CHM(t),e.oxw(2).addInitiator(),!1}),e._UZ(9,"i",25),e.ynx(10),e.SDv(11,91),e.BQk(),e.qZA(),e.qZA(),e.qZA(),e._UZ(12,"hr"),e.qZA(),e.qZA()}if(2&n){const t=e.oxw(2);e.xp6(4),e.Q6J("ngForOf",t.initiators.controls),e.xp6(3),e.Q6J("ngIf",0===t.initiators.controls.length),e.xp6(2),e.Q6J("ngClass",e.VKq(3,J,t.icons.add))}}function _n(n,s){if(1&n){const t=e.EpF();e.ynx(0),e.TgZ(1,"div",50),e._UZ(2,"input",51),e.TgZ(3,"span",14),e.TgZ(4,"button",52),e.NdJ("click",function(){const _=e.CHM(t).index,r=e.oxw(),c=r.$implicit,d=r.index;return e.oxw(3).removeGroupInitiator(c,_,d)}),e._UZ(5,"i",16),e.qZA(),e.qZA(),e.qZA(),e.BQk()}if(2&n){const t=s.$implicit,o=e.oxw(4);e.xp6(2),e.Q6J("value",t),e.xp6(3),e.Q6J("ngClass",e.VKq(2,J,o.icons.destroy))}}function an(n,s){if(1&n){const t=e.EpF();e.ynx(0),e.TgZ(1,"div",50),e._UZ(2,"input",51),e.TgZ(3,"span",14),e.TgZ(4,"button",52),e.NdJ("click",function(){const _=e.CHM(t).index,r=e.oxw(),c=r.$implicit,d=r.index;return e.oxw(3).removeGroupDisk(c,_,d)}),e._UZ(5,"i",16),e.qZA(),e.qZA(),e.qZA(),e.BQk()}if(2&n){const t=s.$implicit,o=e.oxw(4);e.xp6(2),e.Q6J("value",t),e.xp6(3),e.Q6J("ngClass",e.VKq(2,J,o.icons.destroy))}}function rn(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",92),e.TgZ(1,"div",5),e.ynx(2),e.SDv(3,133),e.BQk(),e._uU(4),e.TgZ(5,"button",94),e.NdJ("click",function(){const _=e.CHM(t).index;return e.oxw(3).removeGroup(_)}),e._UZ(6,"i",25),e.qZA(),e.qZA(),e.TgZ(7,"div",7),e.TgZ(8,"div",8),e.TgZ(9,"label",134),e.SDv(10,135),e.qZA(),e.TgZ(11,"div",11),e._UZ(12,"input",136),e.qZA(),e.qZA(),e.TgZ(13,"div",8),e.TgZ(14,"label",137),e.ynx(15),e.SDv(16,138),e.BQk(),e.qZA(),e.TgZ(17,"div",11),e.YNc(18,_n,6,4,"ng-container",21),e.TgZ(19,"div",22),e.TgZ(20,"div",23),e.TgZ(21,"cd-select",24),e.NdJ("selection",function(i){const r=e.CHM(t).index;return e.oxw(3).onGroupMemberSelection(i,r)}),e._UZ(22,"i",25),e.ynx(23),e.SDv(24,139),e.BQk(),e.qZA(),e.qZA(),e.qZA(),e._UZ(25,"hr"),e.qZA(),e.qZA(),e.TgZ(26,"div",8),e.TgZ(27,"label",28),e.ynx(28),e.SDv(29,140),e.BQk(),e.qZA(),e.TgZ(30,"div",11),e.YNc(31,an,6,4,"ng-container",21),e.TgZ(32,"div",22),e.TgZ(33,"div",23),e.TgZ(34,"cd-select",127),e._UZ(35,"i",25),e.ynx(36),e.SDv(37,141),e.BQk(),e.qZA(),e.qZA(),e.qZA(),e._UZ(38,"hr"),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=s.$implicit,o=s.index,i=e.oxw(3);e.Q6J("formGroup",t),e.xp6(4),e.hij(": ",t.getValue("group_id")," "),e.xp6(2),e.Q6J("ngClass",e.VKq(13,J,i.icons.destroy)),e.xp6(12),e.Q6J("ngForOf",t.getValue("members")),e.xp6(3),e.Q6J("data",t.getValue("members"))("options",i.groupMembersSelections[o])("messages",i.messages.groupInitiator),e.xp6(1),e.Q6J("ngClass",e.VKq(15,J,i.icons.add)),e.xp6(9),e.Q6J("ngForOf",t.getValue("disks")),e.xp6(3),e.Q6J("data",t.getValue("disks"))("options",i.groupDiskSelections[o])("messages",i.messages.initiatorImage),e.xp6(1),e.Q6J("ngClass",e.VKq(17,J,i.icons.add))}}function ln(n,s){1&n&&(e.TgZ(0,"span",48),e.SDv(1,142),e.qZA())}function cn(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",8),e.TgZ(1,"label",86),e.SDv(2,130),e.qZA(),e.TgZ(3,"div",131),e.YNc(4,rn,39,19,"div",89),e.TgZ(5,"div",22),e.TgZ(6,"div",23),e.YNc(7,ln,2,0,"span",18),e.TgZ(8,"button",90),e.NdJ("click",function(){return e.CHM(t),e.oxw(2).addGroup(),!1}),e._UZ(9,"i",25),e.ynx(10),e.SDv(11,132),e.BQk(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=e.oxw(2);e.xp6(4),e.Q6J("ngForOf",t.groups.controls),e.xp6(3),e.Q6J("ngIf",0===t.groups.controls.length),e.xp6(2),e.Q6J("ngClass",e.VKq(3,J,t.icons.add))}}function dn(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",1),e.TgZ(1,"form",2,3),e.TgZ(3,"div",4),e.TgZ(4,"div",5),e.SDv(5,6),e.ALo(6,"titlecase"),e.ALo(7,"upperFirst"),e.qZA(),e.TgZ(8,"div",7),e.TgZ(9,"div",8),e.TgZ(10,"label",9),e.SDv(11,10),e.qZA(),e.TgZ(12,"div",11),e.TgZ(13,"div",12),e._UZ(14,"input",13),e.TgZ(15,"span",14),e.TgZ(16,"button",15),e.NdJ("click",function(){return e.CHM(t),e.oxw().targetSettingsModal()}),e._UZ(17,"i",16),e.qZA(),e.qZA(),e.qZA(),e.YNc(18,Ro,2,0,"span",17),e.YNc(19,Mo,2,0,"span",17),e.YNc(20,Oo,9,0,"span",17),e.YNc(21,Ao,2,0,"span",18),e._UZ(22,"hr"),e.qZA(),e.qZA(),e.TgZ(23,"div",8),e.TgZ(24,"label",19),e.SDv(25,20),e.qZA(),e.TgZ(26,"div",11),e.YNc(27,ho,6,4,"ng-container",21),e.TgZ(28,"div",22),e.TgZ(29,"div",23),e.TgZ(30,"cd-select",24),e.NdJ("selection",function(i){return e.CHM(t),e.oxw().onPortalSelection(i)}),e._UZ(31,"i",25),e.ynx(32),e.SDv(33,26),e.BQk(),e.qZA(),e.qZA(),e.qZA(),e._UZ(34,"input",27),e.YNc(35,Po,2,1,"span",17),e._UZ(36,"hr"),e.qZA(),e.qZA(),e.TgZ(37,"div",8),e.TgZ(38,"label",28),e.SDv(39,29),e.qZA(),e.TgZ(40,"div",11),e.YNc(41,Fo,12,10,"ng-container",21),e._UZ(42,"input",30),e.YNc(43,Do,2,0,"span",17),e.YNc(44,vo,2,0,"span",17),e.TgZ(45,"div",22),e.TgZ(46,"div",23),e.TgZ(47,"cd-select",24),e.NdJ("selection",function(i){return e.CHM(t),e.oxw().onImageSelection(i)}),e._UZ(48,"i",25),e.ynx(49),e.SDv(50,31),e.BQk(),e.qZA(),e.qZA(),e.qZA(),e._UZ(51,"hr"),e.qZA(),e.qZA(),e.TgZ(52,"div",8),e.TgZ(53,"div",32),e.TgZ(54,"div",33),e._UZ(55,"input",34),e.TgZ(56,"label",35),e.SDv(57,36),e.qZA(),e.qZA(),e._UZ(58,"hr"),e.qZA(),e.qZA(),e.YNc(59,qo,41,8,"div",37),e.YNc(60,sn,13,5,"div",38),e.YNc(61,cn,12,5,"div",38),e.qZA(),e.TgZ(62,"div",39),e.TgZ(63,"cd-form-button-panel",40),e.NdJ("submitActionEvent",function(){return e.CHM(t),e.oxw().submit()}),e.ALo(64,"titlecase"),e.ALo(65,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=e.MAs(2),o=e.oxw();e.xp6(1),e.Q6J("formGroup",o.targetForm),e.xp6(6),e.pQV(e.lcZ(6,26,o.action))(e.lcZ(7,28,o.resource)),e.QtT(5),e.xp6(10),e.Q6J("ngClass",e.VKq(34,J,o.icons.deepCheck)),e.xp6(1),e.Q6J("ngIf",o.targetForm.showError("target_iqn",t,"required")),e.xp6(1),e.Q6J("ngIf",o.targetForm.showError("target_iqn",t,"pattern")),e.xp6(1),e.Q6J("ngIf",o.targetForm.showError("target_iqn",t,"iqn")),e.xp6(1),e.Q6J("ngIf",o.hasAdvancedSettings(o.targetForm.getValue("target_controls"))),e.xp6(6),e.Q6J("ngForOf",o.portals.value),e.xp6(3),e.Q6J("data",o.portals.value)("options",o.portalsSelections)("messages",o.messages.portals),e.xp6(1),e.Q6J("ngClass",e.VKq(36,J,o.icons.add)),e.xp6(4),e.Q6J("ngIf",o.targetForm.showError("portals",t,"minGateways")),e.xp6(6),e.Q6J("ngForOf",o.targetForm.getValue("disks")),e.xp6(2),e.Q6J("ngIf",o.targetForm.showError("disks",t,"dupLunId")),e.xp6(1),e.Q6J("ngIf",o.targetForm.showError("disks",t,"dupWwn")),e.xp6(3),e.Q6J("data",o.disks.value)("options",o.imagesSelections)("messages",o.messages.images),e.xp6(1),e.Q6J("ngClass",e.VKq(38,J,o.icons.add)),e.xp6(11),e.Q6J("ngIf",o.cephIscsiConfigVersion>10&&!o.targetForm.getValue("acl_enabled")),e.xp6(1),e.Q6J("ngIf",o.targetForm.getValue("acl_enabled")),e.xp6(1),e.Q6J("ngIf",o.targetForm.getValue("acl_enabled")),e.xp6(2),e.Q6J("form",o.targetForm)("submitText",e.lcZ(64,30,o.action)+" "+e.lcZ(65,32,o.resource))}}let ut=(()=>{class n extends H.E{constructor(t,o,i,_,r,c,d){super(),this.iscsiService=t,this.modalService=o,this.rbdService=i,this.router=_,this.route=r,this.taskWrapper=c,this.actionLabels=d,this.api_version=0,this.minimum_gateways=1,this.icons=T.P,this.isEdit=!1,this.portalsSelections=[],this.imagesInitiatorSelections=[],this.groupDiskSelections=[],this.groupMembersSelections=[],this.imagesSettings={},this.messages={portals:new F.a({noOptions:"There are no portals available."}),images:new F.a({noOptions:"There are no images available."}),initiatorImage:new F.a({noOptions:"There are no images available. Please make sure you add an image to the target."}),groupInitiator:new F.a({noOptions:"There are no initiators available. Please make sure you add an initiator to the target."})},this.IQN_REGEX=/^iqn\.(19|20)\d\d-(0[1-9]|1[0-2])\.\D{2,3}(\.[A-Za-z0-9-]+)+(:[A-Za-z0-9-\.]+)*$/,this.USER_REGEX=/^[\w\.:@_-]{8,64}$/,this.PASSWORD_REGEX=/^[\w@\-_\/]{12,16}$/,this.resource="target"}ngOnInit(){const t=new A.E(()=>{});t.pageInfo.limit=-1;const o=[this.iscsiService.listTargets(),this.rbdService.list(t.toParams()),this.iscsiService.portals(),this.iscsiService.settings(),this.iscsiService.version()];this.router.url.startsWith("/block/iscsi/targets/edit")&&(this.isEdit=!0,this.route.params.subscribe(i=>{this.target_iqn=decodeURIComponent(i.target_iqn),o.push(this.iscsiService.getTarget(this.target_iqn))})),this.action=this.isEdit?this.actionLabels.EDIT:this.actionLabels.CREATE,(0,le.D)(o).subscribe(i=>{const _=S()(i[0]).filter(c=>c.target_iqn!==this.target_iqn).flatMap(c=>c.disks).map(c=>`${c.pool}/${c.image}`).value();"api_version"in i[3]&&(this.api_version=i[3].api_version),this.minimum_gateways=i[3].config.minimum_gateways,this.target_default_controls=i[3].target_default_controls,this.target_controls_limits=i[3].target_controls_limits,this.disk_default_controls=i[3].disk_default_controls,this.disk_controls_limits=i[3].disk_controls_limits,this.backstores=i[3].backstores,this.default_backstore=i[3].default_backstore,this.unsupported_rbd_features=i[3].unsupported_rbd_features,this.required_rbd_features=i[3].required_rbd_features,this.imagesAll=S()(i[1]).flatMap(c=>c.value).filter(c=>!c.namespace&&!(-1!==_.indexOf(`${c.pool_name}/${c.name}`)||0===this.getValidBackstores(c).length)).value(),this.imagesSelections=this.imagesAll.map(c=>new x.$(!1,`${c.pool_name}/${c.name}`,""));const r=[];i[2].forEach(c=>{c.ip_addresses.forEach(d=>{r.push(new x.$(!1,c.name+":"+d,""))})}),this.portalsSelections=[...r],this.cephIscsiConfigVersion=i[4].ceph_iscsi_config_version,this.createForm(),i[5]&&this.resolveModel(i[5]),this.loadingReady()})}createForm(){if(this.targetForm=new y.d({target_iqn:new a.NI("iqn.2001-07.com.ceph:"+Date.now(),{validators:[a.kI.required,a.kI.pattern(this.IQN_REGEX)]}),target_controls:new a.NI({}),portals:new a.NI([],{validators:[z.h.custom("minGateways",t=>S().uniq(t.map(i=>i.split(":")[0])).length<Math.max(1,this.minimum_gateways))]}),disks:new a.NI([],{validators:[z.h.custom("dupLunId",t=>{const o=this.getLunIds(t);return o.length!==S().uniq(o).length}),z.h.custom("dupWwn",t=>{const o=this.getWwns(t);return o.length!==S().uniq(o).length})]}),initiators:new a.Oe([]),groups:new a.Oe([]),acl_enabled:new a.NI(!1)}),this.cephIscsiConfigVersion>10){const t=new y.d({user:new a.NI(""),password:new a.NI(""),mutual_user:new a.NI(""),mutual_password:new a.NI("")});this.setAuthValidator(t),this.targetForm.addControl("auth",t)}}resolveModel(t){this.targetForm.patchValue({target_iqn:t.target_iqn,target_controls:t.target_controls,acl_enabled:t.acl_enabled}),this.cephIscsiConfigVersion>10&&this.targetForm.patchValue({auth:t.auth});const o=[];S().forEach(t.portals,_=>{o.push(`${_.host}:${_.ip}`)}),this.targetForm.patchValue({portals:o});const i=[];S().forEach(t.disks,_=>{const r=`${_.pool}/${_.image}`;i.push(r),this.imagesSettings[r]={backstore:_.backstore},this.imagesSettings[r][_.backstore]=_.controls,"lun"in _&&(this.imagesSettings[r].lun=_.lun),"wwn"in _&&(this.imagesSettings[r].wwn=_.wwn),this.onImageSelection({option:{name:r,selected:!0}})}),this.targetForm.patchValue({disks:i}),S().forEach(t.clients,_=>{const r=this.addInitiator();_.luns=S().map(_.luns,c=>`${c.pool}/${c.image}`),r.patchValue(_)}),t.groups.forEach((_,r)=>{const c=this.addGroup();_.disks=S().map(_.disks,d=>`${d.pool}/${d.image}`),c.patchValue(_),S().forEach(_.members,d=>{this.onGroupMemberSelection({option:new x.$(!0,d,"")},r)})})}hasAdvancedSettings(t){return Object.values(t).length>0}get portals(){return this.targetForm.get("portals")}onPortalSelection(){this.portals.setValue(this.portals.value)}removePortal(t,o){return this.portalsSelections.forEach(i=>{i.name===o&&(i.selected=!1)}),this.portals.value.splice(t,1),this.portals.setValue(this.portals.value),!1}get disks(){return this.targetForm.get("disks")}removeImage(t,o){return this.imagesSelections.forEach(i=>{i.name===o&&(i.selected=!1)}),this.disks.value.splice(t,1),this.removeImageRefs(o),this.targetForm.get("disks").updateValueAndValidity({emitEvent:!1}),!1}removeImageRefs(t){this.initiators.controls.forEach(o=>{const i=o.value.luns.filter(_=>_!==t);o.get("luns").setValue(i)}),this.groups.controls.forEach(o=>{const i=o.value.disks.filter(_=>_!==t);o.get("disks").setValue(i)}),S().forEach(this.imagesInitiatorSelections,(o,i)=>{this.imagesInitiatorSelections[i]=o.filter(_=>_.name!==t)}),S().forEach(this.groupDiskSelections,(o,i)=>{this.groupDiskSelections[i]=o.filter(_=>_.name!==t)})}getDefaultBackstore(t){let o=this.default_backstore;const i=this.getImageById(t);return this.validFeatures(i,this.default_backstore)||this.backstores.forEach(_=>{_!==this.default_backstore&&this.validFeatures(i,_)&&(o=_)}),o}isLunIdInUse(t,o){const i=this.disks.value.filter(_=>_!==o);return this.getLunIds(i).includes(t)}getLunIds(t){return S().map(t,o=>this.imagesSettings[o].lun)}nextLunId(t){const o=this.disks.value.filter(r=>r!==t),i=this.getLunIds(o);let _=0;for(;i.includes(_);)_++;return _}getWwns(t){return S().map(t,i=>this.imagesSettings[i].wwn).filter(i=>S().isString(i)&&""!==i)}onImageSelection(t){const o=t.option;if(o.selected){if(this.imagesSettings[o.name])this.isLunIdInUse(this.imagesSettings[o.name].lun,o.name)&&(this.imagesSettings[o.name].lun=this.nextLunId(o.name));else{const i=this.getDefaultBackstore(o.name);this.imagesSettings[o.name]={backstore:i,lun:this.nextLunId(o.name)},this.imagesSettings[o.name][i]={}}S().forEach(this.imagesInitiatorSelections,(i,_)=>{i.push(new x.$(!1,o.name,"")),this.imagesInitiatorSelections[_]=[...i]}),S().forEach(this.groupDiskSelections,(i,_)=>{i.push(new x.$(!1,o.name,"")),this.groupDiskSelections[_]=[...i]})}else this.removeImageRefs(o.name);this.targetForm.get("disks").updateValueAndValidity({emitEvent:!1})}get initiators(){return this.targetForm.get("initiators")}addInitiator(){const t=new y.d({client_iqn:new a.NI("",{validators:[a.kI.required,z.h.custom("notUnique",i=>{const _=this.initiators.controls.reduce(function(r,c){return r.concat(c.value.client_iqn)},[]);return _.indexOf(i)!==_.lastIndexOf(i)}),a.kI.pattern(this.IQN_REGEX)]}),auth:new y.d({user:new a.NI(""),password:new a.NI(""),mutual_user:new a.NI(""),mutual_password:new a.NI("")}),luns:new a.NI([]),cdIsInGroup:new a.NI(!1)});this.setAuthValidator(t),this.initiators.push(t),S().forEach(this.groupMembersSelections,(i,_)=>{i.push(new x.$(!1,"","")),this.groupMembersSelections[_]=[...i]});const o=S().map(this.targetForm.getValue("disks"),i=>new x.$(!1,i,""));return this.imagesInitiatorSelections.push(o),t}setAuthValidator(t){z.h.validateIf(t.get("user"),()=>t.getValue("password")||t.getValue("mutual_user")||t.getValue("mutual_password"),[a.kI.required],[a.kI.pattern(this.USER_REGEX)],[t.get("password"),t.get("mutual_user"),t.get("mutual_password")]),z.h.validateIf(t.get("password"),()=>t.getValue("user")||t.getValue("mutual_user")||t.getValue("mutual_password"),[a.kI.required],[a.kI.pattern(this.PASSWORD_REGEX)],[t.get("user"),t.get("mutual_user"),t.get("mutual_password")]),z.h.validateIf(t.get("mutual_user"),()=>t.getValue("mutual_password"),[a.kI.required],[a.kI.pattern(this.USER_REGEX)],[t.get("user"),t.get("password"),t.get("mutual_password")]),z.h.validateIf(t.get("mutual_password"),()=>t.getValue("mutual_user"),[a.kI.required],[a.kI.pattern(this.PASSWORD_REGEX)],[t.get("user"),t.get("password"),t.get("mutual_user")])}removeInitiator(t){const o=this.initiators.value[t];this.initiators.removeAt(t),S().forEach(this.groupMembersSelections,(i,_)=>{i.splice(t,1),this.groupMembersSelections[_]=[...i]}),this.groups.controls.forEach(i=>{const _=i.value.members.filter(r=>r!==o.client_iqn);i.get("members").setValue(_)}),this.imagesInitiatorSelections.splice(t,1)}updatedInitiatorSelector(){this.initiators.controls.forEach(t=>{t.get("client_iqn").updateValueAndValidity({emitEvent:!1})}),S().forEach(this.groupMembersSelections,(t,o)=>{S().forEach(t,(i,_)=>{const r=i.name;i.name=this.initiators.controls[_].value.client_iqn,this.groups.controls.forEach(c=>{const d=c.value.members,g=d.indexOf(r);-1!==g&&(d[g]=i.name),c.get("members").setValue(d)})}),this.groupMembersSelections[o]=[...this.groupMembersSelections[o]]})}removeInitiatorImage(t,o,i,_){const r=t.getValue("luns");return r.splice(o,1),t.patchValue({luns:r}),this.imagesInitiatorSelections[i].forEach(c=>{c.name===_&&(c.selected=!1)}),!1}get groups(){return this.targetForm.get("groups")}addGroup(){const t=new y.d({group_id:new a.NI("",{validators:[a.kI.required]}),members:new a.NI([]),disks:new a.NI([])});this.groups.push(t);const o=S().map(this.targetForm.getValue("disks"),_=>new x.$(!1,_,""));this.groupDiskSelections.push(o);const i=S().map(this.initiators.value,_=>new x.$(!1,_.client_iqn,"",!_.cdIsInGroup));return this.groupMembersSelections.push(i),t}removeGroup(t){this.groups.removeAt(t),this.groupMembersSelections[t].filter(i=>i.selected).forEach(i=>{i.selected=!1,this.onGroupMemberSelection({option:i},t)}),this.groupMembersSelections.splice(t,1),this.groupDiskSelections.splice(t,1)}onGroupMemberSelection(t,o){const i=t.option;let _=[];i.selected||(_=this.groupDiskSelections[o].filter(c=>c.selected).map(c=>c.name)),this.initiators.controls.forEach((r,c)=>{r.value.client_iqn===i.name&&(r.patchValue({luns:_}),r.get("cdIsInGroup").setValue(i.selected),S().forEach(this.groupMembersSelections,d=>{d[c].enabled=!i.selected}),this.imagesInitiatorSelections[c].forEach(d=>{d.selected=_.includes(d.name)}))})}removeGroupInitiator(t,o,i){const _=t.getValue("members")[o];t.getValue("members").splice(o,1),this.onGroupMemberSelection({option:new x.$(!1,_,"")},i)}removeGroupDisk(t,o,i){const _=t.getValue("disks")[o];t.getValue("disks").splice(o,1),this.groupDiskSelections[i].forEach(r=>{r.name===_&&(r.selected=!1)}),this.groupDiskSelections[i]=[...this.groupDiskSelections[i]]}submit(){const t=S().cloneDeep(this.targetForm.value),o={target_iqn:this.targetForm.getValue("target_iqn"),target_controls:this.targetForm.getValue("target_controls"),acl_enabled:this.targetForm.getValue("acl_enabled"),portals:[],disks:[],clients:[],groups:[]};if(this.cephIscsiConfigVersion>10){const _=this.targetForm.get("auth");_.getValue("user")||_.get("user").setValue(""),_.getValue("password")||_.get("password").setValue(""),_.getValue("mutual_user")||_.get("mutual_user").setValue(""),_.getValue("mutual_password")||_.get("mutual_password").setValue("");const r=this.targetForm.getValue("acl_enabled");o.auth={user:r?"":_.getValue("user"),password:r?"":_.getValue("password"),mutual_user:r?"":_.getValue("mutual_user"),mutual_password:r?"":_.getValue("mutual_password")}}let i;t.disks.forEach(_=>{const r=_.split("/"),c=this.imagesSettings[_].backstore;o.disks.push({pool:r[0],image:r[1],backstore:c,controls:this.imagesSettings[_][c],lun:this.imagesSettings[_].lun,wwn:this.imagesSettings[_].wwn})}),t.portals.forEach(_=>{const r=_.indexOf(":");o.portals.push({host:_.substring(0,r),ip:_.substring(r+1)})}),o.acl_enabled&&(t.initiators.forEach(_=>{_.auth.user||(_.auth.user=""),_.auth.password||(_.auth.password=""),_.auth.mutual_user||(_.auth.mutual_user=""),_.auth.mutual_password||(_.auth.mutual_password=""),delete _.cdIsInGroup;const r=[];_.luns.forEach(c=>{const d=c.split("/");r.push({pool:d[0],image:d[1]})}),_.luns=r}),o.clients=t.initiators),o.acl_enabled&&(t.groups.forEach(_=>{const r=[];_.disks.forEach(c=>{const d=c.split("/");r.push({pool:d[0],image:d[1]})}),_.disks=r}),o.groups=t.groups),this.isEdit?(o.new_target_iqn=o.target_iqn,o.target_iqn=this.target_iqn,i=this.taskWrapper.wrapTaskAroundCall({task:new R.R("iscsi/target/edit",{target_iqn:o.target_iqn}),call:this.iscsiService.updateTarget(this.target_iqn,o)})):i=this.taskWrapper.wrapTaskAroundCall({task:new R.R("iscsi/target/create",{target_iqn:o.target_iqn}),call:this.iscsiService.createTarget(o)}),i.subscribe({error:()=>{this.targetForm.setErrors({cdSubmitButton:!0})},complete:()=>this.router.navigate(["/block/iscsi/targets"])})}targetSettingsModal(){const t={target_controls:this.targetForm.get("target_controls"),target_default_controls:this.target_default_controls,target_controls_limits:this.target_controls_limits};this.modalRef=this.modalService.show(Co,t)}imageSettingsModal(t){const o={imagesSettings:this.imagesSettings,image:t,api_version:this.api_version,disk_default_controls:this.disk_default_controls,disk_controls_limits:this.disk_controls_limits,backstores:this.getValidBackstores(this.getImageById(t)),control:this.targetForm.get("disks")};this.modalRef=this.modalService.show(To,o)}validFeatures(t,o){const i=t.features,_=this.required_rbd_features[o];return(i&_)===_&&0==(i&this.unsupported_rbd_features[o])}getImageById(t){return this.imagesAll.find(o=>t===`${o.pool_name}/${o.name}`)}getValidBackstores(t){return this.backstores.filter(o=>this.validFeatures(t,o))}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(X),e.Y36(de.Z),e.Y36(q),e.Y36(m.F0),e.Y36(m.gz),e.Y36(u.P),e.Y36(v.p4))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-iscsi-target-form"]],features:[e.qOj],decls:1,vars:1,consts:function(){let s,t,o,i,_,r,c,d,g,f,I,P,Z,B,Q,Y,ee,te,w,_e,ae,M,ge,ue,me,Te,fe,Ce,G,Be,Ge,xe,ye,we,qe,He,ke,Ke,Xe,Qe,ze,b,Zt,Bt,Gt,xt,yt,wt,qt,Ht,kt,Kt,Xt,Qt,zt,Jt,Yt,Vt,Ut,jt,Wt,eo;return s="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",t="Target IQN",o="Portals",i="Add portal",_="Images",r="Add image",c="ACL authentication",d="This field is required.",g="IQN has wrong pattern.",f="An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'",I="For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309",P="More information",Z="This target has modified advanced settings.",B="At least " + "\ufffd0\ufffd" + " gateways are required.",Q="Backstore: " + "\ufffd0\ufffd" + ".\xA0",Y="This image has modified settings.",ee="Duplicated LUN numbers.",te="Duplicated WWN.",w="User",_e="Password",ae="Mutual User",M="Mutual Password",ge="This field is required.",ue="User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.",me="This field is required.",Te="Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.",fe="This field is required.",Ce="User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.",G="This field is required.",Be="Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.",Ge="Initiators",xe="Add initiator",ye="Initiator",we="Client IQN",qe="User",He="Password",ke="Mutual User",Ke="Mutual Password",Xe="Images",Qe="Initiator IQN needs to be unique.",ze="This field is required.",b="IQN has wrong pattern.",Zt="This field is required.",Bt="User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.",Gt="This field is required.",xt="Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.",yt="This field is required.",wt="User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.",qt="This field is required.",Ht="Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.",kt="Initiator belongs to a group. Images will be configure in the group.",Kt="Add image",Xt="No items added.",Qt="Groups",zt="Add group",Jt="Group",Yt="Name",Vt="Initiators",Ut="Add initiator",jt="Images",Wt="Add image",eo="No items added.",[["class","cd-col-form",4,"cdFormLoading"],[1,"cd-col-form"],["name","targetForm","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"card"],[1,"card-header"],s,[1,"card-body"],[1,"form-group","row"],["for","target_iqn",1,"cd-col-form-label","required"],t,[1,"cd-col-form-input"],[1,"input-group"],["type","text","id","target_iqn","name","target_iqn","formControlName","target_iqn","cdTrim","",1,"form-control"],[1,"input-group-append"],["id","ecp-info-button","type","button",1,"btn","btn-light",3,"click"],["aria-hidden","true",3,"ngClass"],["class","invalid-feedback",4,"ngIf"],["class","form-text text-muted",4,"ngIf"],["for","portals",1,"cd-col-form-label","required"],o,[4,"ngFor","ngForOf"],[1,"row"],[1,"col-md-12"],["elemClass","btn btn-light float-right",3,"data","options","messages","selection"],[3,"ngClass"],i,["type","hidden","id","portals","name","portals","formControlName","portals",1,"form-control"],["for","disks",1,"cd-col-form-label"],_,["type","hidden","id","disks","name","disks","formControlName","disks",1,"form-control"],r,[1,"cd-col-form-offset"],[1,"custom-control","custom-checkbox"],["type","checkbox","formControlName","acl_enabled","name","acl_enabled","id","acl_enabled",1,"custom-control-input"],["for","acl_enabled",1,"custom-control-label"],c,["formGroupName","auth",4,"ngIf"],["class","form-group row",4,"ngIf"],[1,"card-footer"],["wrappingClass","text-right",3,"form","submitText","submitActionEvent"],[1,"invalid-feedback"],d,g,f,I,["target","_blank","href","https://en.wikipedia.org/wiki/ISCSI#Addressing"],P,[1,"form-text","text-muted"],Z,[1,"input-group","cd-mb"],["type","text","disabled","",1,"cd-form-control",3,"value"],["type","button",1,"btn","btn-light",3,"click"],B,["class","input-group-text",4,"ngIf"],[4,"ngIf"],[1,"input-group-text"],Q,Y,ee,te,["formGroupName","auth"],["for","target_user",1,"cd-col-form-label"],w,["type","text","autocomplete","off","id","target_user","name","target_user","formControlName","user",1,"form-control"],["for","target_password",1,"cd-col-form-label"],_e,["type","password","autocomplete","new-password","id","target_password","name","target_password","formControlName","password",1,"form-control"],["type","button","cdPasswordButton","target_password",1,"btn","btn-light"],["source","target_password"],["for","target_mutual_user",1,"cd-col-form-label"],ae,["type","text","autocomplete","off","id","target_mutual_user","name","target_mutual_user","formControlName","mutual_user",1,"form-control"],["for","target_mutual_password",1,"cd-col-form-label"],M,["type","password","autocomplete","new-password","id","target_mutual_password","name","target_mutual_password","formControlName","mutual_password",1,"form-control"],["type","button","cdPasswordButton","target_mutual_password",1,"btn","btn-light"],["source","target_mutual_password"],ge,ue,me,Te,fe,Ce,G,Be,["for","initiators",1,"cd-col-form-label"],Ge,["formArrayName","initiators",1,"cd-col-form-input"],["class","card mb-2",3,"formGroup",4,"ngFor","ngForOf"],[1,"btn","btn-light","float-right",3,"click"],xe,[1,"card","mb-2",3,"formGroup"],ye,["type","button",1,"close",3,"click"],["for","client_iqn",1,"cd-col-form-label","required"],we,["type","text","formControlName","client_iqn","cdTrim","",1,"form-control",3,"blur"],["for","user",1,"cd-col-form-label"],qe,["formControlName","user","autocomplete","off","type","text",1,"form-control",3,"id"],["for","password",1,"cd-col-form-label"],He,["formControlName","password","autocomplete","new-password","type","password",1,"form-control",3,"id"],["type","button",1,"btn","btn-light",3,"cdPasswordButton"],[3,"source"],["for","mutual_user",1,"cd-col-form-label"],ke,["formControlName","mutual_user","autocomplete","off","type","text",1,"form-control",3,"id"],["for","mutual_password",1,"cd-col-form-label"],Ke,["formControlName","mutual_password","autocomplete","new-password","type","password",1,"form-control",3,"id"],["for","luns",1,"cd-col-form-label"],Xe,["class","row",4,"ngIf"],Qe,ze,b,Zt,Bt,Gt,xt,yt,wt,qt,Ht,kt,["elemClass","btn btn-light float-right",3,"data","options","messages"],Kt,Xt,Qt,["formArrayName","groups",1,"cd-col-form-input"],zt,Jt,["for","group_id",1,"cd-col-form-label","required"],Yt,["type","text","formControlName","group_id",1,"form-control"],["for","members",1,"cd-col-form-label"],Vt,Ut,jt,Wt,eo]},template:function(t,o){1&t&&e.YNc(0,dn,66,40,"div",0),2&t&&e.Q6J("cdFormLoading",o.loading)},directives:[pt.y,a._Y,a.JL,a.sg,h.V,O.P,$.o,a.Fj,k.b,a.JJ,a.u,So,l.mk,l.O5,l.sg,Eo.H,a.Wl,j.p,a.x0,gt.C,Ye.s,a.CE],pipes:[l.rS,et.m,Je.V],styles:[".cd-mb[_ngcontent-%COMP%]{margin-bottom:10px}"]}),n})();var mt=p(68136),pe=p(30982),W=p(35905),De=p(99466),Se=p(68774),Tt=p(55657),ce=p(38047),tt=p(18001),ve=p(97161),oe=p(74937);function pn(n,s){1&n&&(e.TgZ(0,"span",30),e.SDv(1,31),e.qZA())}function gn(n,s){1&n&&(e.TgZ(0,"span",30),e.SDv(1,32),e.qZA())}function un(n,s){1&n&&(e.TgZ(0,"span",30),e.SDv(1,33),e.qZA())}function mn(n,s){1&n&&(e.TgZ(0,"span",30),e.SDv(1,34),e.qZA())}function Tn(n,s){1&n&&(e.TgZ(0,"span",30),e.SDv(1,35),e.qZA())}function fn(n,s){1&n&&(e.TgZ(0,"span",30),e.SDv(1,36),e.qZA())}function Cn(n,s){1&n&&(e.TgZ(0,"span",30),e.SDv(1,37),e.qZA())}function Sn(n,s){1&n&&(e.TgZ(0,"span",30),e.SDv(1,38),e.qZA())}let En=(()=>{class n{constructor(t,o,i,_,r){this.authStorageService=t,this.activeModal=o,this.actionLabels=i,this.iscsiService=_,this.notificationService=r,this.USER_REGEX=/^[\w\.:@_-]{8,64}$/,this.PASSWORD_REGEX=/^[\w@\-_\/]{12,16}$/,this.permission=this.authStorageService.getPermissions().iscsi}ngOnInit(){this.hasPermission=this.permission.update,this.createForm(),this.iscsiService.getDiscovery().subscribe(t=>{this.discoveryForm.patchValue(t)})}createForm(){this.discoveryForm=new y.d({user:new a.NI({value:"",disabled:!this.hasPermission}),password:new a.NI({value:"",disabled:!this.hasPermission}),mutual_user:new a.NI({value:"",disabled:!this.hasPermission}),mutual_password:new a.NI({value:"",disabled:!this.hasPermission})}),z.h.validateIf(this.discoveryForm.get("user"),()=>this.discoveryForm.getValue("password")||this.discoveryForm.getValue("mutual_user")||this.discoveryForm.getValue("mutual_password"),[a.kI.required],[a.kI.pattern(this.USER_REGEX)],[this.discoveryForm.get("password"),this.discoveryForm.get("mutual_user"),this.discoveryForm.get("mutual_password")]),z.h.validateIf(this.discoveryForm.get("password"),()=>this.discoveryForm.getValue("user")||this.discoveryForm.getValue("mutual_user")||this.discoveryForm.getValue("mutual_password"),[a.kI.required],[a.kI.pattern(this.PASSWORD_REGEX)],[this.discoveryForm.get("user"),this.discoveryForm.get("mutual_user"),this.discoveryForm.get("mutual_password")]),z.h.validateIf(this.discoveryForm.get("mutual_user"),()=>this.discoveryForm.getValue("mutual_password"),[a.kI.required],[a.kI.pattern(this.USER_REGEX)],[this.discoveryForm.get("user"),this.discoveryForm.get("password"),this.discoveryForm.get("mutual_password")]),z.h.validateIf(this.discoveryForm.get("mutual_password"),()=>this.discoveryForm.getValue("mutual_user"),[a.kI.required],[a.kI.pattern(this.PASSWORD_REGEX)],[this.discoveryForm.get("user"),this.discoveryForm.get("password"),this.discoveryForm.get("mutual_user")])}submitAction(){this.iscsiService.updateDiscovery(this.discoveryForm.value).subscribe(()=>{this.notificationService.show(tt.k.success,"Updated discovery authentication"),this.activeModal.close()},()=>{this.discoveryForm.setErrors({cdSubmitButton:!0})})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(oe.j),e.Y36(N.Kz),e.Y36(v.p4),e.Y36(X),e.Y36(ve.g))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-iscsi-target-discovery-modal"]],decls:46,vars:13,consts:function(){let s,t,o,i,_,r,c,d,g,f,I,P,Z;return s="Discovery Authentication",t="User",o="Password",i="Mutual User",_="Mutual Password",r="This field is required.",c="User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.",d="This field is required.",g="Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.",f="This field is required.",I="User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.",P="This field is required.",Z="Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["name","discoveryForm","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],[1,"form-group","row"],["for","user",1,"cd-col-form-label"],t,[1,"cd-col-form-input"],["id","user","formControlName","user","type","text","autocomplete","off",1,"form-control"],["class","invalid-feedback",4,"ngIf"],["for","password",1,"cd-col-form-label"],o,[1,"input-group"],["id","password","formControlName","password","type","password","autocomplete","new-password",1,"form-control"],[1,"input-group-append"],["type","button","cdPasswordButton","password",1,"btn","btn-light"],["source","password"],["for","mutual_user",1,"cd-col-form-label"],i,["id","mutual_user","formControlName","mutual_user","type","text","autocomplete","off",1,"form-control"],["for","mutual_password",1,"cd-col-form-label"],_,["id","mutual_password","formControlName","mutual_password","type","password","autocomplete","new-password",1,"form-control"],["type","button","cdPasswordButton","mutual_password",1,"btn","btn-light"],["source","mutual_password"],[1,"modal-footer"],[3,"form","showSubmit","submitText","submitActionEvent"],[1,"invalid-feedback"],r,c,d,g,f,I,P,Z]},template:function(t,o){if(1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.BQk(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.TgZ(7,"div",7),e.TgZ(8,"label",8),e.SDv(9,9),e.qZA(),e.TgZ(10,"div",10),e._UZ(11,"input",11),e.YNc(12,pn,2,0,"span",12),e.YNc(13,gn,2,0,"span",12),e.qZA(),e.qZA(),e.TgZ(14,"div",7),e.TgZ(15,"label",13),e.SDv(16,14),e.qZA(),e.TgZ(17,"div",10),e.TgZ(18,"div",15),e._UZ(19,"input",16),e.TgZ(20,"span",17),e._UZ(21,"button",18),e._UZ(22,"cd-copy-2-clipboard-button",19),e.qZA(),e.qZA(),e.YNc(23,un,2,0,"span",12),e.YNc(24,mn,2,0,"span",12),e.qZA(),e.qZA(),e.TgZ(25,"div",7),e.TgZ(26,"label",20),e.ynx(27),e.SDv(28,21),e.BQk(),e.qZA(),e.TgZ(29,"div",10),e._UZ(30,"input",22),e.YNc(31,Tn,2,0,"span",12),e.YNc(32,fn,2,0,"span",12),e.qZA(),e.qZA(),e.TgZ(33,"div",7),e.TgZ(34,"label",23),e.SDv(35,24),e.qZA(),e.TgZ(36,"div",10),e.TgZ(37,"div",15),e._UZ(38,"input",25),e.TgZ(39,"span",17),e._UZ(40,"button",26),e._UZ(41,"cd-copy-2-clipboard-button",27),e.qZA(),e.qZA(),e.YNc(42,Cn,2,0,"span",12),e.YNc(43,Sn,2,0,"span",12),e.qZA(),e.qZA(),e.qZA(),e.TgZ(44,"div",28),e.TgZ(45,"cd-form-button-panel",29),e.NdJ("submitActionEvent",function(){return o.submitAction()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t){const i=e.MAs(5);e.Q6J("modalRef",o.activeModal),e.xp6(4),e.Q6J("formGroup",o.discoveryForm),e.xp6(8),e.Q6J("ngIf",o.discoveryForm.showError("user",i,"required")),e.xp6(1),e.Q6J("ngIf",o.discoveryForm.showError("user",i,"pattern")),e.xp6(10),e.Q6J("ngIf",o.discoveryForm.showError("password",i,"required")),e.xp6(1),e.Q6J("ngIf",o.discoveryForm.showError("password",i,"pattern")),e.xp6(7),e.Q6J("ngIf",o.discoveryForm.showError("mutual_user",i,"required")),e.xp6(1),e.Q6J("ngIf",o.discoveryForm.showError("mutual_user",i,"pattern")),e.xp6(10),e.Q6J("ngIf",o.discoveryForm.showError("mutual_password",i,"required")),e.xp6(1),e.Q6J("ngIf",o.discoveryForm.showError("mutual_password",i,"pattern")),e.xp6(2),e.Q6J("form",o.discoveryForm)("showSubmit",o.hasPermission)("submitText",o.actionLabels.SUBMIT)}},directives:[C.z,a._Y,a.JL,a.sg,h.V,O.P,$.o,a.Fj,k.b,a.JJ,a.u,l.O5,gt.C,Ye.s,j.p],styles:[""]}),n})();var Rn=p(86969);let ft=(()=>{class n{constructor(t){this.router=t}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(m.F0))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-iscsi-tabs"]],decls:8,vars:1,consts:function(){let s,t;return s="Overview",t="Targets",[["ngbNav","",1,"nav-tabs",3,"activeId","navChange"],["nav","ngbNav"],["ngbNavItem","/block/iscsi/overview"],["ngbNavLink",""],s,["ngbNavItem","/block/iscsi/targets"],t]},template:function(t,o){1&t&&(e.TgZ(0,"ul",0,1),e.NdJ("navChange",function(_){return o.router.navigate([_.nextId])}),e.TgZ(2,"li",2),e.TgZ(3,"a",3),e.SDv(4,4),e.qZA(),e.qZA(),e.TgZ(5,"li",5),e.TgZ(6,"a",3),e.SDv(7,6),e.qZA(),e.qZA(),e.qZA()),2&t&&e.Q6J("activeId",o.router.url)},directives:[N.Pz,N.nv,N.Vx],styles:[""]}),n})();var Ct=p(34501),Mn=p(30490),Ee=p(94928),On=p(68962);const An=["highlightTpl"],hn=["detailTable"],Pn=["tree"],In=function(){return["logged_in"]},bn=function(){return["logged_out"]},Nn=function(n,s){return{"badge-success":n,"badge-danger":s}};function Fn(n,s){if(1&n&&(e._UZ(0,"i"),e.TgZ(1,"span"),e._uU(2),e.qZA(),e._uU(3," \xa0 "),e.TgZ(4,"span",8),e._uU(5),e.qZA()),2&n){const t=s.$implicit;e.Tol(t.data.cdIcon),e.xp6(2),e.Oqu(t.data.name),e.xp6(2),e.Q6J("ngClass",e.WLB(7,Nn,e.DdM(5,In).includes(t.data.status),e.DdM(6,bn).includes(t.data.status))),e.xp6(1),e.hij(" ",t.data.status," ")}}function Dn(n,s){if(1&n&&(e.TgZ(0,"div",9),e.TgZ(1,"legend"),e._uU(2),e.qZA(),e._UZ(3,"cd-table",10,11),e.qZA()),2&n){const t=e.oxw();e.xp6(2),e.Oqu(t.title),e.xp6(1),e.Q6J("data",t.data)("columns",t.columns)("limit",0)}}function vn(n,s){if(1&n&&(e.TgZ(0,"span"),e._uU(1),e.qZA()),2&n){const t=e.oxw().value;e.xp6(1),e.Oqu(t)}}function Ln(n,s){if(1&n&&(e.TgZ(0,"strong"),e._uU(1),e.qZA()),2&n){const t=e.oxw().value;e.xp6(1),e.Oqu(t)}}function $n(n,s){if(1&n&&(e.YNc(0,vn,2,1,"span",12),e.YNc(1,Ln,2,1,"strong",12)),2&n){const t=s.row;e.Q6J("ngIf",void 0===t.default||t.default===t.current),e.xp6(1),e.Q6J("ngIf",void 0!==t.default&&t.default!==t.current)}}let Zn=(()=>{class n{constructor(t,o){this.iscsiBackstorePipe=t,this.booleanTextPipe=o,this.icons=T.P,this.metadata={},this.nodes=[],this.treeOptions={useVirtualScroll:!0,actionMapping:{mouse:{click:this.onNodeSelected.bind(this)}}}}set content(t){this.detailTable=t,t&&t.updateColumns()}ngOnInit(){this.columns=[{prop:"displayName",name:"Name",flexGrow:1,cellTemplate:this.highlightTpl},{prop:"current",name:"Current",flexGrow:1,cellTemplate:this.highlightTpl},{prop:"default",name:"Default",flexGrow:1,cellTemplate:this.highlightTpl}]}ngOnChanges(){this.selection&&(this.selectedItem=this.selection,this.generateTree()),this.data=void 0}generateTree(){const t=S().cloneDeep(this.selectedItem.target_controls);this.cephIscsiConfigVersion>10&&S().extend(t,S().cloneDeep(this.selectedItem.auth)),this.metadata={root:t};const o={target:{expanded:S().join(this.selectedItem.cdExecuting?[T.P.large,T.P.spinner,T.P.spin]:[T.P.large,T.P.bullseye]," ")},initiators:{expanded:S().join([T.P.large,T.P.user]," "),leaf:S().join([T.P.user]," ")},groups:{expanded:S().join([T.P.large,T.P.users]," "),leaf:S().join([T.P.users]," ")},disks:{expanded:S().join([T.P.large,T.P.disk]," "),leaf:S().join([T.P.disk]," ")},portals:{expanded:S().join([T.P.large,T.P.server]," "),leaf:S().join([T.P.server]," ")}},i=[];S().forEach(this.selectedItem.disks,d=>{const g="disk_"+d.pool+"_"+d.image;this.metadata[g]={controls:d.controls,backstore:d.backstore},["wwn","lun"].forEach(f=>{f in d&&(this.metadata[g][f]=d[f])}),i.push({name:`${d.pool}/${d.image}`,cdId:g,cdIcon:o.disks.leaf})});const _=[];S().forEach(this.selectedItem.portals,d=>{_.push({name:`${d.host}:${d.ip}`,cdIcon:o.portals.leaf})});const r=[];S().forEach(this.selectedItem.clients,d=>{const g=S().cloneDeep(d.auth);d.info&&(S().extend(g,d.info),delete g.state,S().forEach(Object.keys(d.info.state),P=>{g[P.toLowerCase()]=d.info.state[P]})),this.metadata["client_"+d.client_iqn]=g;const f=[];d.luns.forEach(P=>{f.push({name:`${P.pool}/${P.image}`,cdId:"disk_"+P.pool+"_"+P.image,cdIcon:o.disks.leaf})});let I="";d.info&&(I=Object.keys(d.info.state).includes("LOGGED_IN")?"logged_in":"logged_out"),r.push({name:d.client_iqn,status:I,cdId:"client_"+d.client_iqn,children:f,cdIcon:o.initiators.leaf})});const c=[];S().forEach(this.selectedItem.groups,d=>{const g=[];d.disks.forEach(I=>{g.push({name:`${I.pool}/${I.image}`,cdId:"disk_"+I.pool+"_"+I.image,cdIcon:o.disks.leaf})});const f=[];d.members.forEach(I=>{f.push({name:I,cdId:"client_"+I})}),c.push({name:d.group_id,cdIcon:o.groups.leaf,children:[{name:"Disks",children:g,cdIcon:o.disks.expanded},{name:"Initiators",children:f,cdIcon:o.initiators.expanded}]})}),this.nodes=[{name:this.selectedItem.target_iqn,cdId:"root",isExpanded:!0,cdIcon:o.target.expanded,children:[{name:"Disks",isExpanded:!0,children:i,cdIcon:o.disks.expanded},{name:"Portals",isExpanded:!0,children:_,cdIcon:o.portals.expanded},{name:"Initiators",isExpanded:!0,children:r,cdIcon:o.initiators.expanded},{name:"Groups",isExpanded:!0,children:c,cdIcon:o.groups.expanded}]}]}format(t){return"boolean"==typeof t?this.booleanTextPipe.transform(t):t}onNodeSelected(t,o){var i,_,r,c;if(ne.iM.ACTIVATE(t,o,!0),o.data.cdId){this.title=o.data.name;const d=this.metadata[o.data.cdId]||{};"root"===o.data.cdId?(null===(i=this.detailTable)||void 0===i||i.toggleColumn({prop:"default",isHidden:!0}),this.data=S().map(this.settings.target_default_controls,(g,f)=>({displayName:f,default:g=this.format(g),current:S().isUndefined(d[f])?g:this.format(d[f])})),this.cephIscsiConfigVersion>10&&["user","password","mutual_user","mutual_password"].forEach(g=>{this.data.push({displayName:g,default:null,current:d[g]})})):o.data.cdId.toString().startsWith("disk_")?(null===(_=this.detailTable)||void 0===_||_.toggleColumn({prop:"default",isHidden:!0}),this.data=S().map(this.settings.disk_default_controls[d.backstore],(g,f)=>({displayName:f,default:g=this.format(g),current:S().isUndefined(d.controls[f])?g:this.format(d.controls[f])})),this.data.push({displayName:"backstore",default:this.iscsiBackstorePipe.transform(this.settings.default_backstore),current:this.iscsiBackstorePipe.transform(d.backstore)}),["wwn","lun"].forEach(g=>{g in d&&this.data.push({displayName:g,default:void 0,current:d[g]})})):(null===(r=this.detailTable)||void 0===r||r.toggleColumn({prop:"default",isHidden:!1}),this.data=S().map(d,(g,f)=>({displayName:f,default:void 0,current:this.format(g)})))}else this.data=void 0;null===(c=this.detailTable)||void 0===c||c.updateColumns()}onUpdateData(){this.tree.treeModel.expandAll()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Je.V),e.Y36(On.T))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-iscsi-target-details"]],viewQuery:function(t,o){if(1&t&&(e.Gf(An,7),e.Gf(hn,5),e.Gf(Pn,5)),2&t){let i;e.iGM(i=e.CRH())&&(o.highlightTpl=i.first),e.iGM(i=e.CRH())&&(o.content=i.first),e.iGM(i=e.CRH())&&(o.tree=i.first)}},inputs:{selection:"selection",settings:"settings",cephIscsiConfigVersion:"cephIscsiConfigVersion"},features:[e.TTD],decls:11,vars:3,consts:function(){let s;return s="iSCSI Topology",[[1,"row"],[1,"col-6"],s,[3,"nodes","options","updateData"],["tree",""],["treeNodeTemplate",""],["class","col-6 metadata",4,"ngIf"],["highlightTpl",""],[1,"badge",3,"ngClass"],[1,"col-6","metadata"],["columnMode","flex",3,"data","columns","limit"],["detailTable",""],[4,"ngIf"]]},template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"div",1),e.TgZ(2,"legend"),e.SDv(3,2),e.qZA(),e.TgZ(4,"tree-root",3,4),e.NdJ("updateData",function(){return o.onUpdateData()}),e.YNc(6,Fn,6,10,"ng-template",null,5,e.W1O),e.qZA(),e.qZA(),e.YNc(8,Dn,5,4,"div",6),e.qZA(),e.YNc(9,$n,2,2,"ng-template",null,7,e.W1O)),2&t&&(e.xp6(4),e.Q6J("nodes",o.nodes)("options",o.treeOptions),e.xp6(4),e.Q6J("ngIf",o.data))},directives:[ne.qr,l.O5,l.mk,W.a],styles:[""]}),n})();function Bn(n,s){if(1&n&&(e.ynx(0),e._UZ(1,"br"),e.TgZ(2,"span"),e.SDv(3,6),e.qZA(),e.TgZ(4,"pre"),e._uU(5),e.qZA(),e.BQk()),2&n){const t=e.oxw(2);e.xp6(5),e.Oqu(t.status)}}function Gn(n,s){if(1&n&&(e.TgZ(0,"cd-alert-panel",2),e.ynx(1),e.tHW(2,3),e._UZ(3,"cd-doc",4),e.N_p(),e.BQk(),e.YNc(4,Bn,6,1,"ng-container",5),e.qZA()),2&n){const t=e.oxw();e.xp6(4),e.Q6J("ngIf",t.status)}}function xn(n,s){if(1&n&&e._UZ(0,"cd-iscsi-target-details",15),2&n){const t=e.oxw(2);e.Q6J("cephIscsiConfigVersion",t.cephIscsiConfigVersion)("selection",t.expandedRow)("settings",t.settings)}}const yn=function(n){return[n]};function wn(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-table",7,8),e.NdJ("fetchData",function(){return e.CHM(t),e.oxw().getTargets()})("setExpandedRow",function(i){return e.CHM(t),e.oxw().setExpandedRow(i)})("updateSelection",function(i){return e.CHM(t),e.oxw().updateSelection(i)}),e.TgZ(2,"div",9),e._UZ(3,"cd-table-actions",10),e.TgZ(4,"button",11),e.NdJ("click",function(){return e.CHM(t),e.oxw().configureDiscoveryAuth()}),e._UZ(5,"i",12),e.ynx(6),e.SDv(7,13),e.BQk(),e.qZA(),e.qZA(),e.YNc(8,xn,1,3,"cd-iscsi-target-details",14),e.qZA()}if(2&n){const t=e.oxw();e.Q6J("data",t.targets)("columns",t.columns)("hasDetails",!0)("autoReload",!1)("status",t.tableStatus),e.xp6(3),e.Q6J("permission",t.permission)("selection",t.selection)("tableActions",t.tableActions),e.xp6(2),e.Q6J("ngClass",e.VKq(10,yn,t.icons.key)),e.xp6(3),e.Q6J("ngIf",t.expandedRow)}}let qn=(()=>{class n extends mt.o{constructor(t,o,i,_,r,c,d,g,f){super(f),this.authStorageService=t,this.iscsiService=o,this.joinPipe=i,this.taskListService=_,this.notAvailablePipe=r,this.modalService=c,this.taskWrapper=d,this.actionLabels=g,this.ngZone=f,this.available=void 0,this.selection=new Se.r,this.targets=[],this.icons=T.P,this.builders={"iscsi/target/create":I=>({target_iqn:I.target_iqn})},this.permission=this.authStorageService.getPermissions().iscsi,this.tableActions=[{permission:"create",icon:T.P.add,routerLink:()=>"/block/iscsi/targets/create",name:this.actionLabels.CREATE},{permission:"update",icon:T.P.edit,routerLink:()=>`/block/iscsi/targets/edit/${this.selection.first().target_iqn}`,name:this.actionLabels.EDIT,disable:()=>this.getEditDisableDesc()},{permission:"delete",icon:T.P.destroy,click:()=>this.deleteIscsiTargetModal(),name:this.actionLabels.DELETE,disable:()=>this.getDeleteDisableDesc()}]}ngOnInit(){this.columns=[{name:"Target",prop:"target_iqn",flexGrow:2,cellTransformation:De.e.executing},{name:"Portals",prop:"cdPortals",pipe:this.joinPipe,flexGrow:2},{name:"Images",prop:"cdImages",pipe:this.joinPipe,flexGrow:2},{name:"# Sessions",prop:"info.num_sessions",pipe:this.notAvailablePipe,flexGrow:1}],this.iscsiService.status().subscribe(t=>{this.available=t.available,t.available||(this.status=t.message)})}getTargets(){this.available&&(this.setTableRefreshTimeout(),this.iscsiService.version().subscribe(t=>{this.cephIscsiConfigVersion=t.ceph_iscsi_config_version}),this.taskListService.init(()=>this.iscsiService.listTargets(),t=>this.prepareResponse(t),t=>this.targets=t,()=>this.onFetchError(),this.taskFilter,this.itemFilter,this.builders),this.iscsiService.settings().subscribe(t=>{this.settings=t}))}ngOnDestroy(){this.summaryDataSubscription&&this.summaryDataSubscription.unsubscribe()}getEditDisableDesc(){const t=this.selection.first();return t&&(null==t?void 0:t.cdExecuting)?t.cdExecuting:t&&S().isUndefined(null==t?void 0:t.info)?"Unavailable gateway(s)":!t}getDeleteDisableDesc(){var t;const o=this.selection.first();return(null==o?void 0:o.cdExecuting)?o.cdExecuting:o&&S().isUndefined(null==o?void 0:o.info)?"Unavailable gateway(s)":o&&(null===(t=null==o?void 0:o.info)||void 0===t?void 0:t.num_sessions)?"Target has active sessions":!o}prepareResponse(t){return t.forEach(o=>{o.cdPortals=o.portals.map(i=>`${i.host}:${i.ip}`),o.cdImages=o.disks.map(i=>`${i.pool}/${i.image}`)}),t}onFetchError(){this.table.reset()}itemFilter(t,o){return t.target_iqn===o.metadata.target_iqn}taskFilter(t){return["iscsi/target/create","iscsi/target/edit","iscsi/target/delete"].includes(t.name)}updateSelection(t){this.selection=t}deleteIscsiTargetModal(){const t=this.selection.first().target_iqn;this.modalRef=this.modalService.show(pe.M,{itemDescription:"iSCSI target",itemNames:[t],submitActionObservable:()=>this.taskWrapper.wrapTaskAroundCall({task:new R.R("iscsi/target/delete",{target_iqn:t}),call:this.iscsiService.deleteTarget(t)})})}configureDiscoveryAuth(){this.modalService.show(En)}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(oe.j),e.Y36(X),e.Y36(Rn.A),e.Y36(ce.j),e.Y36(Tt.g),e.Y36(de.Z),e.Y36(u.P),e.Y36(v.p4),e.Y36(e.R0b))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-iscsi-target-list"]],viewQuery:function(t,o){if(1&t&&e.Gf(W.a,5),2&t){let i;e.iGM(i=e.CRH())&&(o.table=i.first)}},features:[e._Bn([ce.j]),e.qOj],decls:3,vars:2,consts:function(){let s,t,o,i;return s="iSCSI Targets not available",t="Please consult the " + "\ufffd#3\ufffd" + "" + "\ufffd/#3\ufffd" + " on how to configure and enable the iSCSI Targets management functionality.",o="Available information:",i="Discovery authentication",[["type","info","title",s,4,"ngIf"],["columnMode","flex","identifier","target_iqn","forceIdentifier","true","selectionType","single",3,"data","columns","hasDetails","autoReload","status","fetchData","setExpandedRow","updateSelection",4,"ngIf"],["type","info","title",s],t,["section","iscsi"],[4,"ngIf"],o,["columnMode","flex","identifier","target_iqn","forceIdentifier","true","selectionType","single",3,"data","columns","hasDetails","autoReload","status","fetchData","setExpandedRow","updateSelection"],["table",""],[1,"table-actions","btn-toolbar"],[1,"btn-group",3,"permission","selection","tableActions"],["type","button",1,"btn","btn-light",3,"click"],["aria-hidden","true",3,"ngClass"],i,["cdTableDetail","",3,"cephIscsiConfigVersion","selection","settings",4,"ngIf"],["cdTableDetail","",3,"cephIscsiConfigVersion","selection","settings"]]},template:function(t,o){1&t&&(e._UZ(0,"cd-iscsi-tabs"),e.YNc(1,Gn,5,1,"cd-alert-panel",0),e.YNc(2,wn,9,12,"cd-table",1)),2&t&&(e.xp6(1),e.Q6J("ngIf",!1===o.available),e.xp6(1),e.Q6J("ngIf",!0===o.available))},directives:[ft,l.O5,Ct.G,Mn.K,W.a,Ee.K,$.o,l.mk,Zn],styles:[""]}),n})();var ot=p(66369),Hn=p(76446),kn=p(90068);const Kn=["iscsiSparklineTpl"],Xn=["iscsiPerSecondTpl"],Qn=["iscsiRelativeDateTpl"];function zn(n,s){if(1&n&&(e.TgZ(0,"span"),e._UZ(1,"cd-sparkline",9),e.qZA()),2&n){const t=e.oxw(),o=t.value,i=t.row;e.xp6(1),e.Q6J("data",o)("isBinary",i.cdIsBinary)}}function Jn(n,s){1&n&&(e.TgZ(0,"span",10),e._uU(1," n/a "),e.qZA())}function Yn(n,s){if(1&n&&(e.YNc(0,zn,2,2,"span",7),e.YNc(1,Jn,2,0,"span",8)),2&n){const t=s.row;e.Q6J("ngIf","user:rbd"===t.backstore),e.xp6(1),e.Q6J("ngIf","user:rbd"!==t.backstore)}}function Vn(n,s){if(1&n&&(e.TgZ(0,"span"),e._uU(1),e.qZA()),2&n){const t=e.oxw().value;e.xp6(1),e.hij(" ",t," /s ")}}function Un(n,s){1&n&&(e.TgZ(0,"span",10),e._uU(1," n/a "),e.qZA())}function jn(n,s){if(1&n&&(e.YNc(0,Vn,2,1,"span",7),e.YNc(1,Un,2,0,"span",8)),2&n){const t=s.row;e.Q6J("ngIf","user:rbd"===t.backstore),e.xp6(1),e.Q6J("ngIf","user:rbd"!==t.backstore)}}function Wn(n,s){if(1&n&&(e.TgZ(0,"span"),e._uU(1),e.ALo(2,"notAvailable"),e.ALo(3,"relativeDate"),e.qZA()),2&n){const t=e.oxw().value;e.xp6(1),e.hij(" ",e.lcZ(2,1,e.lcZ(3,3,t))," ")}}function ei(n,s){1&n&&(e.TgZ(0,"span",10),e._uU(1," n/a "),e.qZA())}function ti(n,s){if(1&n&&(e.YNc(0,Wn,4,5,"span",7),e.YNc(1,ei,2,0,"span",8)),2&n){const t=s.row;e.Q6J("ngIf","user:rbd"===t.backstore),e.xp6(1),e.Q6J("ngIf","user:rbd"!==t.backstore)}}let oi=(()=>{class n{constructor(t,o,i){this.iscsiService=t,this.dimlessPipe=o,this.iscsiBackstorePipe=i,this.gateways=[],this.images=[]}ngOnInit(){this.gatewaysColumns=[{name:"Name",prop:"name"},{name:"State",prop:"state",flexGrow:1,cellTransformation:De.e.badge,customTemplateConfig:{map:{up:{class:"badge-success"},down:{class:"badge-danger"}}}},{name:"# Targets",prop:"num_targets"},{name:"# Sessions",prop:"num_sessions"}],this.imagesColumns=[{name:"Pool",prop:"pool"},{name:"Image",prop:"image"},{name:"Backstore",prop:"backstore",pipe:this.iscsiBackstorePipe},{name:"Read Bytes",prop:"stats_history.rd_bytes",cellTemplate:this.iscsiSparklineTpl},{name:"Write Bytes",prop:"stats_history.wr_bytes",cellTemplate:this.iscsiSparklineTpl},{name:"Read Ops",prop:"stats.rd",pipe:this.dimlessPipe,cellTemplate:this.iscsiPerSecondTpl},{name:"Write Ops",prop:"stats.wr",pipe:this.dimlessPipe,cellTemplate:this.iscsiPerSecondTpl},{name:"A/O Since",prop:"optimized_since",cellTemplate:this.iscsiRelativeDateTpl}]}refresh(){this.iscsiService.overview().subscribe(t=>{this.gateways=t.gateways,this.images=t.images,this.images.map(o=>(o.stats_history&&(o.stats_history.rd_bytes=o.stats_history.rd_bytes.map(i=>i[1]),o.stats_history.wr_bytes=o.stats_history.wr_bytes.map(i=>i[1])),o.cdIsBinary=!0,o))})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(X),e.Y36(ot.n),e.Y36(Je.V))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-iscsi"]],viewQuery:function(t,o){if(1&t&&(e.Gf(Kn,7),e.Gf(Xn,7),e.Gf(Qn,7)),2&t){let i;e.iGM(i=e.CRH())&&(o.iscsiSparklineTpl=i.first),e.iGM(i=e.CRH())&&(o.iscsiPerSecondTpl=i.first),e.iGM(i=e.CRH())&&(o.iscsiRelativeDateTpl=i.first)}},decls:13,vars:4,consts:function(){let s,t;return s="Gateways",t="Images",[s,[3,"data","columns","fetchData"],t,[3,"data","columns"],["iscsiSparklineTpl",""],["iscsiPerSecondTpl",""],["iscsiRelativeDateTpl",""],[4,"ngIf"],["class","text-muted",4,"ngIf"],[3,"data","isBinary"],[1,"text-muted"]]},template:function(t,o){1&t&&(e._UZ(0,"cd-iscsi-tabs"),e.TgZ(1,"legend"),e.SDv(2,0),e.qZA(),e.TgZ(3,"cd-table",1),e.NdJ("fetchData",function(){return o.refresh()}),e.qZA(),e.TgZ(4,"legend"),e.SDv(5,2),e.qZA(),e._UZ(6,"cd-table",3),e.YNc(7,Yn,2,2,"ng-template",null,4,e.W1O),e.YNc(9,jn,2,2,"ng-template",null,5,e.W1O),e.YNc(11,ti,2,2,"ng-template",null,6,e.W1O)),2&t&&(e.xp6(3),e.Q6J("data",o.gateways)("columns",o.gatewaysColumns),e.xp6(3),e.Q6J("data",o.images)("columns",o.imagesColumns))},directives:[ft,W.a,l.O5,Hn.l],pipes:[Tt.g,kn.h],styles:[""]}),n})(),ni=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275mod=e.oAB({type:n}),n.\u0275inj=e.cJS({imports:[[l.ez,Ae.m,N.Oz,m.Bz,a.u5,a.UX,N.ZQ]]}),n})();var ii=p(75319),si=p(26215),_i=p(45435),St=p(46947);let K=class{constructor(s,t){this.http=s,this.timerService=t,this.REFRESH_INTERVAL=3e4,this.summaryDataSource=new si.X(null),this.summaryData$=this.summaryDataSource.asObservable()}startPolling(){return this.timerService.get(()=>this.retrieveSummaryObservable(),this.REFRESH_INTERVAL).subscribe(this.retrieveSummaryObserver())}refresh(){return this.retrieveSummaryObservable().subscribe(this.retrieveSummaryObserver())}retrieveSummaryObservable(){return this.http.get("api/block/mirroring/summary")}retrieveSummaryObserver(){return s=>{this.summaryDataSource.next(s)}}subscribeSummary(s,t){return this.summaryData$.pipe((0,_i.h)(o=>!!o)).subscribe(s,t)}getPool(s){return this.http.get(`api/block/mirroring/pool/${s}`)}updatePool(s,t){return this.http.put(`api/block/mirroring/pool/${s}`,t,{observe:"response"})}getSiteName(){return this.http.get("api/block/mirroring/site_name")}setSiteName(s){return this.http.put("api/block/mirroring/site_name",{site_name:s},{observe:"response"})}createBootstrapToken(s){return this.http.post(`api/block/mirroring/pool/${s}/bootstrap/token`,{})}importBootstrapToken(s,t,o){return this.http.post(`api/block/mirroring/pool/${s}/bootstrap/peer`,{direction:t,token:o},{observe:"response"})}getPeer(s,t){return this.http.get(`api/block/mirroring/pool/${s}/peer/${t}`)}addPeer(s,t){return this.http.post(`api/block/mirroring/pool/${s}/peer`,t,{observe:"response"})}updatePeer(s,t,o){return this.http.put(`api/block/mirroring/pool/${s}/peer/${t}`,o,{observe:"response"})}deletePeer(s,t){return this.http.delete(`api/block/mirroring/pool/${s}/peer/${t}`,{observe:"response"})}};K.\u0275fac=function(s){return new(s||K)(e.LFG(ie.eN),e.LFG(St.f))},K.\u0275prov=e.Yz7({token:K,factory:K.\u0275fac,providedIn:"root"}),(0,D.gn)([(0,D.fM)(0,V.G),(0,D.w6)("design:type",Function),(0,D.w6)("design:paramtypes",[String]),(0,D.w6)("design:returntype",void 0)],K.prototype,"setSiteName",null),(0,D.gn)([(0,D.fM)(1,V.G),(0,D.fM)(2,V.G),(0,D.w6)("design:type",Function),(0,D.w6)("design:paramtypes",[String,String,String]),(0,D.w6)("design:returntype",void 0)],K.prototype,"importBootstrapToken",null),K=(0,D.gn)([V.o,(0,D.w6)("design:paramtypes",[ie.eN,St.f])],K);var nt=p(58071),ai=p(68307),Et=p(12627),Re=p(82945),ri=p(39749),li=p(13472);function ci(n,s){1&n&&(e.TgZ(0,"span",25),e.SDv(1,26),e.qZA())}function di(n,s){if(1&n&&(e.TgZ(0,"div",27),e._UZ(1,"input",28),e.TgZ(2,"label",29),e._uU(3),e.qZA(),e.qZA()),2&n){const t=s.$implicit;e.xp6(1),e.s9C("id",t.name),e.s9C("name",t.name),e.s9C("formControlName",t.name),e.xp6(1),e.s9C("for",t.name),e.xp6(1),e.Oqu(t.name)}}function pi(n,s){1&n&&(e.TgZ(0,"span",25),e.SDv(1,30),e.qZA())}let gi=(()=>{class n{constructor(t,o,i){this.activeModal=t,this.rbdMirroringService=o,this.taskWrapper=i,this.pools=[],this.createForm()}createForm(){this.createBootstrapForm=new y.d({siteName:new a.NI("",{validators:[a.kI.required]}),pools:new a.cw({},{validators:[this.validatePools()]}),token:new a.NI("",{})})}ngOnInit(){this.createBootstrapForm.get("siteName").setValue(this.siteName),this.rbdMirroringService.getSiteName().subscribe(t=>{this.createBootstrapForm.get("siteName").setValue(t.site_name)}),this.subs=this.rbdMirroringService.subscribeSummary(t=>{this.pools=t.content_data.pools.reduce((_,r)=>(_.push({name:r.name,mirror_mode:r.mirror_mode}),_),[]);const i=this.createBootstrapForm.get("pools");S().each(this.pools,_=>{const r=_.name,c="disabled"===_.mirror_mode,d=i.controls[r];d?c&&d.disabled?d.enable():!c&&d.enabled&&(d.disable(),d.setValue(!0)):i.addControl(r,new a.NI({value:!c,disabled:!c}))})})}ngOnDestroy(){this.subs&&this.subs.unsubscribe()}validatePools(){return t=>{let o=0;return S().each(t.controls,i=>{!0===i.value&&++o}),o>0?null:{requirePool:!0}}}generate(){this.createBootstrapForm.get("token").setValue("");let t="";const o=[],i=this.createBootstrapForm.get("pools");S().each(i.controls,(g,f)=>{!0===g.value&&(t=f,g.disabled||o.push(f))});const _={mirror_mode:"image"},r=(0,nt.z)(this.rbdMirroringService.setSiteName(this.createBootstrapForm.getValue("siteName")),(0,le.D)(o.map(g=>this.rbdMirroringService.updatePool(g,_))),this.rbdMirroringService.createBootstrapToken(t).pipe((0,ai.b)(g=>this.createBootstrapForm.get("token").setValue(g.token)))).pipe((0,Et.Z)()),c=()=>{this.rbdMirroringService.refresh(),this.createBootstrapForm.setErrors({cdSubmitButton:!0})};this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/mirroring/bootstrap/create",{}),call:r}).subscribe({error:c,complete:c})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(N.Kz),e.Y36(K),e.Y36(u.P))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-bootstrap-create-modal"]],decls:32,vars:6,consts:function(){let s,t,o,i,_,r,c,d,g,f,I;return s="Create Bootstrap Token",t="To create a bootstrap token which can be imported by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, and click\xA0 " + "\ufffd#10\ufffd" + "Generate" + "\ufffd/#10\ufffd" + ".",o="Site Name",i="Name...",_="Pools",r="Generate",c="Token",d="Generated token...",g="Close",f="This field is required.",I="At least one pool is required.",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["name","createBootstrapForm","novalidate","",1,"form",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],t,[1,"form-group"],["for","siteName",1,"col-form-label","required"],o,["type","text","placeholder",i,"id","siteName","name","siteName","formControlName","siteName","autofocus","",1,"form-control"],["class","invalid-feedback",4,"ngIf"],["formGroupName","pools",1,"form-group"],["for","pools",1,"col-form-label","required"],_,["class","custom-control custom-checkbox",4,"ngFor","ngForOf"],[1,"mb-4","float-right",3,"form","submitAction"],r,["for","token",1,"col-form-label"],c,["placeholder",d,"id","token","formControlName","token","readonly","",1,"form-control","resize-vertical"],["source","token",1,"float-right"],[1,"modal-footer"],["name",g,3,"backAction"],[1,"invalid-feedback"],f,[1,"custom-control","custom-checkbox"],["type","checkbox",1,"custom-control-input",3,"id","name","formControlName"],[1,"custom-control-label",3,"for"],I]},template:function(t,o){if(1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.BQk(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.TgZ(7,"p"),e.ynx(8),e.tHW(9,7),e._UZ(10,"kbd"),e.N_p(),e.BQk(),e.qZA(),e.TgZ(11,"div",8),e.TgZ(12,"label",9),e.SDv(13,10),e.qZA(),e._UZ(14,"input",11),e.YNc(15,ci,2,0,"span",12),e.qZA(),e.TgZ(16,"div",13),e.TgZ(17,"label",14),e.SDv(18,15),e.qZA(),e.YNc(19,di,4,5,"div",16),e.YNc(20,pi,2,0,"span",12),e.qZA(),e.TgZ(21,"cd-submit-button",17),e.NdJ("submitAction",function(){return o.generate()}),e.SDv(22,18),e.qZA(),e.TgZ(23,"div",8),e.TgZ(24,"label",19),e.TgZ(25,"span"),e.SDv(26,20),e.qZA(),e.qZA(),e.TgZ(27,"textarea",21),e._uU(28," "),e.qZA(),e.qZA(),e._UZ(29,"cd-copy-2-clipboard-button",22),e.qZA(),e.TgZ(30,"div",23),e.TgZ(31,"cd-back-button",24),e.NdJ("backAction",function(){return o.activeModal.close()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t){const i=e.MAs(5);e.Q6J("modalRef",o.activeModal),e.xp6(4),e.Q6J("formGroup",o.createBootstrapForm),e.xp6(11),e.Q6J("ngIf",o.createBootstrapForm.showError("siteName",i,"required")),e.xp6(4),e.Q6J("ngForOf",o.pools),e.xp6(1),e.Q6J("ngIf",o.createBootstrapForm.showError("pools",i,"requirePool")),e.xp6(1),e.Q6J("form",o.createBootstrapForm)}},directives:[C.z,a._Y,a.JL,h.V,a.sg,O.P,$.o,a.Fj,k.b,a.JJ,a.u,Re.U,l.O5,a.x0,l.sg,ri.w,Ye.s,li.W,a.Wl],styles:[".form-group.ng-invalid[_ngcontent-%COMP%] .invalid-feedback[_ngcontent-%COMP%]{display:block}"]}),n})();function ui(n,s){1&n&&(e.TgZ(0,"span",26),e.SDv(1,27),e.qZA())}function mi(n,s){if(1&n&&(e.TgZ(0,"option",28),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t.key),e.xp6(1),e.Oqu(t.desc)}}function Ti(n,s){if(1&n&&(e.TgZ(0,"div",29),e._UZ(1,"input",30),e.TgZ(2,"label",31),e._uU(3),e.qZA(),e.qZA()),2&n){const t=s.$implicit;e.xp6(1),e.s9C("id",t.name),e.s9C("name",t.name),e.s9C("formControlName",t.name),e.xp6(1),e.s9C("for",t.name),e.xp6(1),e.Oqu(t.name)}}function fi(n,s){1&n&&(e.TgZ(0,"span",26),e.SDv(1,32),e.qZA())}function Ci(n,s){1&n&&(e.TgZ(0,"span",26),e.SDv(1,33),e.qZA())}function Si(n,s){1&n&&(e.TgZ(0,"span",26),e.SDv(1,34),e.qZA())}let Ei=(()=>{class n{constructor(t,o,i,_){this.activeModal=t,this.actionLabels=o,this.rbdMirroringService=i,this.taskWrapper=_,this.pools=[],this.directions=[{key:"rx-tx",desc:"Bidirectional"},{key:"rx",desc:"Unidirectional (receive-only)"}],this.createForm()}createForm(){this.importBootstrapForm=new y.d({siteName:new a.NI("",{validators:[a.kI.required]}),direction:new a.NI("rx-tx",{}),pools:new a.cw({},{validators:[this.validatePools()]}),token:new a.NI("",{validators:[a.kI.required,this.validateToken()]})})}ngOnInit(){this.rbdMirroringService.getSiteName().subscribe(t=>{this.importBootstrapForm.get("siteName").setValue(t.site_name)}),this.subs=this.rbdMirroringService.subscribeSummary(t=>{this.pools=t.content_data.pools.reduce((_,r)=>(_.push({name:r.name,mirror_mode:r.mirror_mode}),_),[]);const i=this.importBootstrapForm.get("pools");S().each(this.pools,_=>{const r=_.name,c="disabled"===_.mirror_mode,d=i.controls[r];d?c&&d.disabled?d.enable():!c&&d.enabled&&(d.disable(),d.setValue(!0)):i.addControl(r,new a.NI({value:!c,disabled:!c}))})})}ngOnDestroy(){this.subs&&this.subs.unsubscribe()}validatePools(){return t=>{let o=0;return S().each(t.controls,i=>{!0===i.value&&++o}),o>0?null:{requirePool:!0}}}validateToken(){return t=>{try{if(JSON.parse(atob(t.value)))return null}catch(o){}return{invalidToken:!0}}}import(){const t=[],o=[],i=this.importBootstrapForm.get("pools");S().each(i.controls,(g,f)=>{!0===g.value&&(t.push(f),g.disabled||o.push(f))});const _={mirror_mode:"image"};let r=(0,nt.z)(this.rbdMirroringService.setSiteName(this.importBootstrapForm.getValue("siteName")),(0,le.D)(o.map(g=>this.rbdMirroringService.updatePool(g,_))));r=t.reduce((g,f)=>(0,nt.z)(g,this.rbdMirroringService.importBootstrapToken(f,this.importBootstrapForm.getValue("direction"),this.importBootstrapForm.getValue("token"))),r).pipe((0,Et.Z)());const c=()=>{this.rbdMirroringService.refresh(),this.importBootstrapForm.setErrors({cdSubmitButton:!0})};this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/mirroring/bootstrap/import",{}),call:r}).subscribe({error:c,complete:()=>{c(),this.activeModal.close()}})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(N.Kz),e.Y36(v.p4),e.Y36(K),e.Y36(u.P))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-bootstrap-import-modal"]],decls:36,vars:10,consts:function(){let s,t,o,i,_,r,c,d,g,f,I,P;return s="Import Bootstrap Token",t="To import a bootstrap token which was created by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, provide the generated token, and click\xA0" + "\ufffd#10\ufffd" + "Import" + "\ufffd/#10\ufffd" + ".",o="Site Name",i="Name...",_="Direction",r="Pools",c="Token",d="Generated token...",g="This field is required.",f="At least one pool is required.",I="This field is required.",P="The token is invalid.",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["name","importBootstrapForm","novalidate","",1,"form",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],t,[1,"form-group"],["for","siteName",1,"col-form-label","required"],o,["type","text","placeholder",i,"id","siteName","name","siteName","formControlName","siteName","autofocus","",1,"form-control"],["class","invalid-feedback",4,"ngIf"],["for","direction",1,"col-form-label"],_,["id","direction","name","direction","formControlName","direction",1,"form-control"],[3,"value",4,"ngFor","ngForOf"],["formGroupName","pools",1,"form-group"],["for","pools",1,"col-form-label","required"],r,["class","custom-control custom-checkbox",4,"ngFor","ngForOf"],["for","token",1,"col-form-label","required"],c,["placeholder",d,"id","token","formControlName","token",1,"form-control","resize-vertical"],[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],[1,"invalid-feedback"],g,[3,"value"],[1,"custom-control","custom-checkbox"],["type","checkbox",1,"custom-control-input",3,"id","name","formControlName"],[1,"custom-control-label",3,"for"],f,I,P]},template:function(t,o){if(1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.BQk(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.TgZ(7,"p"),e.ynx(8),e.tHW(9,7),e._UZ(10,"kbd"),e.N_p(),e.BQk(),e.qZA(),e.TgZ(11,"div",8),e.TgZ(12,"label",9),e.SDv(13,10),e.qZA(),e._UZ(14,"input",11),e.YNc(15,ui,2,0,"span",12),e.qZA(),e.TgZ(16,"div",8),e.TgZ(17,"label",13),e.TgZ(18,"span"),e.SDv(19,14),e.qZA(),e.qZA(),e.TgZ(20,"select",15),e.YNc(21,mi,2,2,"option",16),e.qZA(),e.qZA(),e.TgZ(22,"div",17),e.TgZ(23,"label",18),e.SDv(24,19),e.qZA(),e.YNc(25,Ti,4,5,"div",20),e.YNc(26,fi,2,0,"span",12),e.qZA(),e.TgZ(27,"div",8),e.TgZ(28,"label",21),e.SDv(29,22),e.qZA(),e.TgZ(30,"textarea",23),e._uU(31," "),e.qZA(),e.YNc(32,Ci,2,0,"span",12),e.YNc(33,Si,2,0,"span",12),e.qZA(),e.qZA(),e.TgZ(34,"div",24),e.TgZ(35,"cd-form-button-panel",25),e.NdJ("submitActionEvent",function(){return o.import()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t){const i=e.MAs(5);e.Q6J("modalRef",o.activeModal),e.xp6(4),e.Q6J("formGroup",o.importBootstrapForm),e.xp6(11),e.Q6J("ngIf",o.importBootstrapForm.showError("siteName",i,"required")),e.xp6(6),e.Q6J("ngForOf",o.directions),e.xp6(4),e.Q6J("ngForOf",o.pools),e.xp6(1),e.Q6J("ngIf",o.importBootstrapForm.showError("pools",i,"requirePool")),e.xp6(6),e.Q6J("ngIf",o.importBootstrapForm.showError("token",i,"required")),e.xp6(1),e.Q6J("ngIf",o.importBootstrapForm.showError("token",i,"invalidToken")),e.xp6(2),e.Q6J("form",o.importBootstrapForm)("submitText",o.actionLabels.SUBMIT)}},directives:[C.z,a._Y,a.JL,h.V,a.sg,O.P,$.o,a.Fj,k.b,a.JJ,a.u,Re.U,l.O5,a.EJ,l.sg,a.x0,j.p,a.YN,a.Kr,a.Wl],styles:[""]}),n})();var se=p(69158),Ri=p(58111);let it=(()=>{class n{transform(t){return"warning"===t?"badge badge-warning":"error"===t?"badge badge-danger":"success"===t?"badge badge-success":"badge badge-info"}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275pipe=e.Yjl({name:"mirrorHealthColor",type:n,pure:!0}),n})();const Mi=["healthTmpl"];function Oi(n,s){if(1&n&&(e.TgZ(0,"span",2),e.ALo(1,"mirrorHealthColor"),e._uU(2),e.qZA()),2&n){const o=s.value;e.Q6J("ngClass",e.lcZ(1,2,s.row.health_color)),e.xp6(2),e.Oqu(o)}}let Ai=(()=>{class n{constructor(t,o){this.rbdMirroringService=t,this.cephShortVersionPipe=o,this.tableStatus=new se.E}ngOnInit(){this.columns=[{prop:"instance_id",name:"Instance",flexGrow:2},{prop:"id",name:"ID",flexGrow:2},{prop:"server_hostname",name:"Hostname",flexGrow:2},{prop:"version",name:"Version",pipe:this.cephShortVersionPipe,flexGrow:2},{prop:"health",name:"Health",cellTemplate:this.healthTmpl,flexGrow:1}],this.subs=this.rbdMirroringService.subscribeSummary(t=>{this.data=t.content_data.daemons,this.tableStatus=new se.E(t.status)})}ngOnDestroy(){this.subs.unsubscribe()}refresh(){this.rbdMirroringService.refresh()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(K),e.Y36(Ri.F))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-mirroring-daemons"]],viewQuery:function(t,o){if(1&t&&e.Gf(Mi,7),2&t){let i;e.iGM(i=e.CRH())&&(o.healthTmpl=i.first)}},decls:3,vars:4,consts:[["columnMode","flex",3,"data","columns","autoReload","status","fetchData"],["healthTmpl",""],[3,"ngClass"]],template:function(t,o){1&t&&(e.TgZ(0,"cd-table",0),e.NdJ("fetchData",function(){return o.refresh()}),e.qZA(),e.YNc(1,Oi,3,4,"ng-template",null,1,e.W1O)),2&t&&e.Q6J("data",o.data)("columns",o.columns)("autoReload",-1)("status",o.tableStatus)},directives:[W.a,l.mk],pipes:[it],styles:[""]}),n})();var Rt=p(18891);class hi{}function Pi(n,s){1&n&&(e.TgZ(0,"span",24),e.SDv(1,25),e.qZA())}function Ii(n,s){1&n&&(e.TgZ(0,"span",24),e.SDv(1,26),e.qZA())}function bi(n,s){1&n&&(e.TgZ(0,"span",24),e.SDv(1,27),e.qZA())}function Ni(n,s){1&n&&(e.TgZ(0,"span",24),e.SDv(1,28),e.qZA())}function Fi(n,s){1&n&&(e.TgZ(0,"span",24),e.SDv(1,29),e.qZA())}function Di(n,s){1&n&&(e.TgZ(0,"span",24),e.SDv(1,30),e.qZA())}let vi=(()=>{class n{constructor(t,o,i,_){this.activeModal=t,this.actionLabels=o,this.rbdMirroringService=i,this.taskWrapper=_,this.bsConfig={containerClass:"theme-default"},this.createForm()}createForm(){this.editPeerForm=new y.d({clusterName:new a.NI("",{validators:[a.kI.required,this.validateClusterName]}),clientID:new a.NI("",{validators:[a.kI.required,this.validateClientID]}),monAddr:new a.NI("",{validators:[this.validateMonAddr]}),key:new a.NI("",{validators:[this.validateKey]})})}ngOnInit(){this.pattern=`${this.poolName}/${this.peerUUID}`,"edit"===this.mode&&this.rbdMirroringService.getPeer(this.poolName,this.peerUUID).subscribe(t=>{this.setResponse(t)})}validateClusterName(t){if(!t.value.match(/^[\w\-_]*$/))return{invalidClusterName:{value:t.value}}}validateClientID(t){if(!t.value.match(/^(?!client\.)[\w\-_.]*$/))return{invalidClientID:{value:t.value}}}validateMonAddr(t){if(!t.value.match(/^[,; ]*([\w.\-_\[\]]+(:[\d]+)?[,; ]*)*$/))return{invalidMonAddr:{value:t.value}}}validateKey(t){try{if(""===t.value||atob(t.value))return null}catch(o){}return{invalidKey:{value:t.value}}}setResponse(t){this.response=t,this.editPeerForm.get("clusterName").setValue(t.cluster_name),this.editPeerForm.get("clientID").setValue(t.client_id),this.editPeerForm.get("monAddr").setValue(t.mon_host),this.editPeerForm.get("key").setValue(t.key)}update(){const t=new hi;let o;t.cluster_name=this.editPeerForm.getValue("clusterName"),t.client_id=this.editPeerForm.getValue("clientID"),t.mon_host=this.editPeerForm.getValue("monAddr"),t.key=this.editPeerForm.getValue("key"),o=this.taskWrapper.wrapTaskAroundCall("edit"===this.mode?{task:new R.R("rbd/mirroring/peer/edit",{pool_name:this.poolName}),call:this.rbdMirroringService.updatePeer(this.poolName,this.peerUUID,t)}:{task:new R.R("rbd/mirroring/peer/add",{pool_name:this.poolName}),call:this.rbdMirroringService.addPeer(this.poolName,t)}),o.subscribe({error:()=>this.editPeerForm.setErrors({cdSubmitButton:!0}),complete:()=>{this.rbdMirroringService.refresh(),this.activeModal.close()}})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(N.Kz),e.Y36(v.p4),e.Y36(K),e.Y36(u.P))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-pool-edit-peer-modal"]],decls:38,vars:13,consts:function(){let s,t,o,i,_,r,c,d,g,f,I,P,Z,B,Q,Y,ee,te;return s="{VAR_SELECT, select, edit {Edit} other {Add}}",s=e.Zx4(s,{VAR_SELECT:"\ufffd0\ufffd"}),t="" + s + " pool mirror peer",o="{VAR_SELECT, select, edit {Edit} other {Add}}",o=e.Zx4(o,{VAR_SELECT:"\ufffd0\ufffd"}),i="" + o + " the pool mirror peer attributes for pool " + "[\ufffd#10\ufffd|\ufffd#11\ufffd]" + "" + "\ufffd1\ufffd" + "" + "[\ufffd/#10\ufffd|\ufffd/#11\ufffd]" + " and click " + "[\ufffd#10\ufffd|\ufffd#11\ufffd]" + "Submit" + "[\ufffd/#10\ufffd|\ufffd/#11\ufffd]" + ".",i=e.Zx4(i),_="Cluster Name",r="Name...",c="CephX ID",d="CephX ID...",g="Monitor Addresses",f="Comma-delimited addresses...",I="CephX Key",P="Base64-encoded key...",Z="This field is required.",B="The cluster name is not valid.",Q="This field is required.",Y="The CephX ID is not valid.",ee="The monitory address is not valid.",te="CephX key must be base64 encoded.",[[3,"modalRef"],[1,"modal-title"],t,[1,"modal-content"],["name","editPeerForm","novalidate","",1,"form",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],i,[1,"form-group"],["for","clusterName",1,"col-form-label","required"],_,["type","text","placeholder",r,"id","clusterName","name","clusterName","formControlName","clusterName","autofocus","",1,"form-control"],["class","invalid-feedback",4,"ngIf"],["for","clientID",1,"col-form-label","required"],c,["type","text","placeholder",d,"id","clientID","name","clientID","formControlName","clientID",1,"form-control"],["for","monAddr",1,"col-form-label"],g,["type","text","placeholder",f,"id","monAddr","name","monAddr","formControlName","monAddr",1,"form-control"],["for","key",1,"col-form-label"],I,["type","text","placeholder",P,"id","key","name","key","formControlName","key",1,"form-control"],[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],[1,"invalid-feedback"],Z,B,Q,Y,ee,te]},template:function(t,o){if(1&t&&(e.TgZ(0,"cd-modal",0),e.TgZ(1,"span",1),e.SDv(2,2),e.qZA(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.TgZ(7,"p"),e.TgZ(8,"span"),e.tHW(9,7),e._UZ(10,"kbd"),e._UZ(11,"kbd"),e.N_p(),e.qZA(),e.qZA(),e.TgZ(12,"div",8),e.TgZ(13,"label",9),e.SDv(14,10),e.qZA(),e._UZ(15,"input",11),e.YNc(16,Pi,2,0,"span",12),e.YNc(17,Ii,2,0,"span",12),e.qZA(),e.TgZ(18,"div",8),e.TgZ(19,"label",13),e.SDv(20,14),e.qZA(),e._UZ(21,"input",15),e.YNc(22,bi,2,0,"span",12),e.YNc(23,Ni,2,0,"span",12),e.qZA(),e.TgZ(24,"div",8),e.TgZ(25,"label",16),e.TgZ(26,"span"),e.SDv(27,17),e.qZA(),e.qZA(),e._UZ(28,"input",18),e.YNc(29,Fi,2,0,"span",12),e.qZA(),e.TgZ(30,"div",8),e.TgZ(31,"label",19),e.TgZ(32,"span"),e.SDv(33,20),e.qZA(),e.qZA(),e._UZ(34,"input",21),e.YNc(35,Di,2,0,"span",12),e.qZA(),e.qZA(),e.TgZ(36,"div",22),e.TgZ(37,"cd-form-button-panel",23),e.NdJ("submitActionEvent",function(){return o.update()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t){const i=e.MAs(5);e.Q6J("modalRef",o.activeModal),e.xp6(2),e.pQV(o.mode),e.QtT(2),e.xp6(2),e.Q6J("formGroup",o.editPeerForm),e.xp6(7),e.pQV(o.mode)(o.poolName),e.QtT(9),e.xp6(5),e.Q6J("ngIf",o.editPeerForm.showError("clusterName",i,"required")),e.xp6(1),e.Q6J("ngIf",o.editPeerForm.showError("clusterName",i,"invalidClusterName")),e.xp6(5),e.Q6J("ngIf",o.editPeerForm.showError("clientID",i,"required")),e.xp6(1),e.Q6J("ngIf",o.editPeerForm.showError("clientID",i,"invalidClientID")),e.xp6(6),e.Q6J("ngIf",o.editPeerForm.showError("monAddr",i,"invalidMonAddr")),e.xp6(6),e.Q6J("ngIf",o.editPeerForm.showError("key",i,"invalidKey")),e.xp6(2),e.Q6J("form",o.editPeerForm)("submitText",o.actionLabels.SUBMIT)}},directives:[C.z,a._Y,a.JL,h.V,a.sg,O.P,$.o,a.Fj,k.b,a.JJ,a.u,Re.U,l.O5,j.p],styles:[""]}),n})();const Li=["healthTmpl"];function $i(n,s){if(1&n&&(e.TgZ(0,"span",4),e.ALo(1,"mirrorHealthColor"),e._uU(2),e.qZA()),2&n){const o=s.value;e.Q6J("ngClass",e.lcZ(1,2,s.row.health_color)),e.xp6(2),e.Oqu(o)}}let Bi=(()=>{class n{constructor(t,o,i,_,r){this.authStorageService=t,this.rbdMirroringService=o,this.modalService=i,this.taskWrapper=_,this.router=r,this.selection=new Se.r,this.tableStatus=new se.E,this.data=[],this.permission=this.authStorageService.getPermissions().rbdMirroring;const c={permission:"update",icon:T.P.edit,click:()=>this.editModeModal(),name:"Edit Mode",canBePrimary:()=>!0},d={permission:"create",icon:T.P.add,name:"Add Peer",click:()=>this.editPeersModal("add"),disable:()=>!this.selection.first()||"disabled"===this.selection.first().mirror_mode,visible:()=>!this.getPeerUUID(),canBePrimary:()=>!1},g={permission:"update",icon:T.P.exchange,name:"Edit Peer",click:()=>this.editPeersModal("edit"),visible:()=>!!this.getPeerUUID()},f={permission:"delete",icon:T.P.destroy,name:"Delete Peer",click:()=>this.deletePeersModal(),visible:()=>!!this.getPeerUUID()};this.tableActions=[c,d,g,f]}ngOnInit(){this.columns=[{prop:"name",name:"Name",flexGrow:2},{prop:"mirror_mode",name:"Mode",flexGrow:2},{prop:"leader_id",name:"Leader",flexGrow:2},{prop:"image_local_count",name:"# Local",flexGrow:2},{prop:"image_remote_count",name:"# Remote",flexGrow:2},{prop:"health",name:"Health",cellTemplate:this.healthTmpl,flexGrow:1}],this.subs=this.rbdMirroringService.subscribeSummary(t=>{this.data=t.content_data.pools,this.tableStatus=new se.E(t.status)})}ngOnDestroy(){this.subs.unsubscribe()}refresh(){this.rbdMirroringService.refresh()}editModeModal(){this.router.navigate(["/block/mirroring",{outlets:{modal:[v.MQ.EDIT,this.selection.first().name]}}])}editPeersModal(t){const o={poolName:this.selection.first().name,mode:t};"edit"===t&&(o.peerUUID=this.getPeerUUID()),this.modalRef=this.modalService.show(vi,o)}deletePeersModal(){const t=this.selection.first().name,o=this.getPeerUUID();this.modalRef=this.modalService.show(pe.M,{itemDescription:"mirror peer",itemNames:[`${t} (${o})`],submitActionObservable:()=>new Rt.y(i=>{this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/mirroring/peer/delete",{pool_name:t}),call:this.rbdMirroringService.deletePeer(t,o)}).subscribe({error:_=>i.error(_),complete:()=>{this.rbdMirroringService.refresh(),i.complete()}})})})}getPeerUUID(){const t=this.selection.first(),o=this.data.find(i=>t&&t.name===i.name);if(o&&o.peer_uuids)return o.peer_uuids[0]}updateSelection(t){this.selection=t}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(oe.j),e.Y36(K),e.Y36(de.Z),e.Y36(u.P),e.Y36(m.F0))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-mirroring-pools"]],viewQuery:function(t,o){if(1&t&&e.Gf(Li,7),2&t){let i;e.iGM(i=e.CRH())&&(o.healthTmpl=i.first)}},decls:5,vars:7,consts:[["columnMode","flex","identifier","name","forceIdentifier","true","selectionType","single",3,"data","columns","autoReload","status","fetchData","updateSelection"],[1,"table-actions",3,"permission","selection","tableActions"],["healthTmpl",""],["name","modal"],[3,"ngClass"]],template:function(t,o){1&t&&(e.TgZ(0,"cd-table",0),e.NdJ("fetchData",function(){return o.refresh()})("updateSelection",function(_){return o.updateSelection(_)}),e._UZ(1,"cd-table-actions",1),e.qZA(),e.YNc(2,$i,3,4,"ng-template",null,2,e.W1O),e._UZ(4,"router-outlet",3)),2&t&&(e.Q6J("data",o.data)("columns",o.columns)("autoReload",-1)("status",o.tableStatus),e.xp6(1),e.Q6J("permission",o.permission)("selection",o.selection)("tableActions",o.tableActions))},directives:[W.a,Ee.K,m.lC,l.mk],pipes:[it],styles:[""]}),n})();var Mt=p(59376);const Gi=["stateTmpl"],xi=["syncTmpl"],yi=["progressTmpl"];function wi(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-table",13),e.NdJ("fetchData",function(){return e.CHM(t),e.oxw().refresh()}),e.qZA()}if(2&n){const t=e.oxw();e.Q6J("data",t.image_error.data)("columns",t.image_error.columns)("autoReload",-1)("status",t.tableStatus)}}function qi(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-table",13),e.NdJ("fetchData",function(){return e.CHM(t),e.oxw().refresh()}),e.qZA()}if(2&n){const t=e.oxw();e.Q6J("data",t.image_syncing.data)("columns",t.image_syncing.columns)("autoReload",-1)("status",t.tableStatus)}}function Hi(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-table",13),e.NdJ("fetchData",function(){return e.CHM(t),e.oxw().refresh()}),e.qZA()}if(2&n){const t=e.oxw();e.Q6J("data",t.image_ready.data)("columns",t.image_ready.columns)("autoReload",-1)("status",t.tableStatus)}}function ki(n,s){if(1&n&&(e.TgZ(0,"span",14),e.ALo(1,"mirrorHealthColor"),e._uU(2),e.qZA()),2&n){const o=s.value;e.Q6J("ngClass",e.lcZ(1,2,s.row.state_color)),e.xp6(2),e.Oqu(o)}}function Ki(n,s){1&n&&e._UZ(0,"div")}function Xi(n,s){if(1&n&&e._UZ(0,"ngb-progressbar",17),2&n){const t=e.oxw().value;e.Q6J("value",t)("showValue",!0)}}function Qi(n,s){if(1&n&&(e.YNc(0,Ki,1,0,"div",15),e.YNc(1,Xi,1,2,"ngb-progressbar",16)),2&n){const t=s.row;e.Q6J("ngIf","Replaying"===t.state),e.xp6(1),e.Q6J("ngIf","Syncing"===t.state)}}let zi=(()=>{class n{constructor(t){this.rbdMirroringService=t,this.image_error={data:[],columns:{}},this.image_syncing={data:[],columns:{}},this.image_ready={data:[],columns:{}},this.tableStatus=new se.E}ngOnInit(){this.image_error.columns=[{prop:"pool_name",name:"Pool",flexGrow:2},{prop:"name",name:"Image",flexGrow:2},{prop:"state",name:"State",cellTemplate:this.stateTmpl,flexGrow:1},{prop:"description",name:"Issue",flexGrow:4}],this.image_syncing.columns=[{prop:"pool_name",name:"Pool",flexGrow:2},{prop:"name",name:"Image",flexGrow:2},{prop:"state",name:"State",cellTemplate:this.stateTmpl,flexGrow:1},{prop:"progress",name:"Progress",cellTemplate:this.progressTmpl,flexGrow:2},{prop:"bytes_per_second",name:"Bytes per second",flexGrow:2},{prop:"entries_behind_primary",name:"Entries behind primary",flexGrow:2}],this.image_ready.columns=[{prop:"pool_name",name:"Pool",flexGrow:2},{prop:"name",name:"Image",flexGrow:2},{prop:"state",name:"State",cellTemplate:this.stateTmpl,flexGrow:1},{prop:"description",name:"Description",flexGrow:4}],this.subs=this.rbdMirroringService.subscribeSummary(t=>{this.image_error.data=t.content_data.image_error,this.image_syncing.data=t.content_data.image_syncing,this.image_ready.data=t.content_data.image_ready,this.tableStatus=new se.E(t.status)})}ngOnDestroy(){this.subs.unsubscribe()}refresh(){this.rbdMirroringService.refresh()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(K))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-mirroring-images"]],viewQuery:function(t,o){if(1&t&&(e.Gf(Gi,7),e.Gf(xi,7),e.Gf(yi,7)),2&t){let i;e.iGM(i=e.CRH())&&(o.stateTmpl=i.first),e.iGM(i=e.CRH())&&(o.syncTmpl=i.first),e.iGM(i=e.CRH())&&(o.progressTmpl=i.first)}},decls:19,vars:4,consts:function(){let s,t,o;return s="Issues (" + "\ufffd0\ufffd" + ")",t="Syncing (" + "\ufffd0\ufffd" + ")",o="Ready (" + "\ufffd0\ufffd" + ")",[["ngbNav","","cdStatefulTab","image-list",1,"nav-tabs"],["nav","ngbNav"],["ngbNavItem","issues"],["ngbNavLink",""],s,["ngbNavContent",""],["ngbNavItem","syncing"],t,["ngbNavItem","ready"],o,[3,"ngbNavOutlet"],["stateTmpl",""],["progressTmpl",""],["columnMode","flex",3,"data","columns","autoReload","status","fetchData"],[3,"ngClass"],[4,"ngIf"],["type","info",3,"value","showValue",4,"ngIf"],["type","info",3,"value","showValue"]]},template:function(t,o){if(1&t&&(e.TgZ(0,"ul",0,1),e.TgZ(2,"li",2),e.TgZ(3,"a",3),e.SDv(4,4),e.qZA(),e.YNc(5,wi,1,4,"ng-template",5),e.qZA(),e.TgZ(6,"li",6),e.TgZ(7,"a",3),e.SDv(8,7),e.qZA(),e.YNc(9,qi,1,4,"ng-template",5),e.qZA(),e.TgZ(10,"li",8),e.TgZ(11,"a",3),e.SDv(12,9),e.qZA(),e.YNc(13,Hi,1,4,"ng-template",5),e.qZA(),e.qZA(),e._UZ(14,"div",10),e.YNc(15,ki,3,4,"ng-template",null,11,e.W1O),e.YNc(17,Qi,2,2,"ng-template",null,12,e.W1O)),2&t){const i=e.MAs(1);e.xp6(4),e.pQV(o.image_error.data.length),e.QtT(4),e.xp6(4),e.pQV(o.image_syncing.data.length),e.QtT(8),e.xp6(4),e.pQV(o.image_ready.data.length),e.QtT(12),e.xp6(2),e.Q6J("ngbNavOutlet",i)}},directives:[N.Pz,Mt.m,N.nv,N.Vx,N.uN,N.tO,W.a,l.mk,l.O5,N.Ly],pipes:[it],styles:[""]}),n})();function Ji(n,s){if(1&n&&e._UZ(0,"i",18),2&n){const t=e.oxw();e.Q6J("ngClass",t.icons.edit)}}function Yi(n,s){if(1&n&&e._UZ(0,"i",18),2&n){const t=e.oxw();e.Q6J("ngClass",t.icons.check)}}let Vi=(()=>{class n{constructor(t,o,i,_){this.authStorageService=t,this.rbdMirroringService=o,this.modalService=i,this.taskWrapper=_,this.selection=new Se.r,this.peersExist=!0,this.subs=new ii.w,this.editing=!1,this.icons=T.P,this.permission=this.authStorageService.getPermissions().rbdMirroring;const r={permission:"update",icon:T.P.upload,click:()=>this.createBootstrapModal(),name:"Create Bootstrap Token",canBePrimary:()=>!0,disable:()=>!1},c={permission:"update",icon:T.P.download,click:()=>this.importBootstrapModal(),name:"Import Bootstrap Token",disable:()=>this.peersExist};this.tableActions=[r,c]}ngOnInit(){this.createForm(),this.subs.add(this.rbdMirroringService.startPolling()),this.subs.add(this.rbdMirroringService.subscribeSummary(t=>{this.status=t.content_data.status,this.peersExist=!!t.content_data.pools.find(o=>o.peer_uuids.length>0)})),this.rbdMirroringService.getSiteName().subscribe(t=>{this.siteName=t.site_name,this.rbdmirroringForm.get("siteName").setValue(this.siteName)})}createForm(){this.rbdmirroringForm=new y.d({siteName:new a.NI({value:"",disabled:!0})})}ngOnDestroy(){this.subs.unsubscribe()}updateSiteName(){this.editing&&this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/mirroring/site_name/edit",{}),call:this.rbdMirroringService.setSiteName(this.rbdmirroringForm.getValue("siteName"))}).subscribe({complete:()=>{this.rbdMirroringService.refresh()}}),this.editing=!this.editing}createBootstrapModal(){this.modalRef=this.modalService.show(gi,{siteName:this.siteName})}importBootstrapModal(){this.modalRef=this.modalService.show(Ei,{siteName:this.siteName})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(oe.j),e.Y36(K),e.Y36(de.Z),e.Y36(u.P))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-mirroring"]],decls:29,vars:9,consts:function(){let s,t,o,i;return s="Site Name",t="Daemons",o="Pools",i="Images",[[1,"row"],[1,"col-md-12"],["name","rbdmirroringForm","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"d-flex","flex-row"],["for","siteName",1,"col-form-label"],s,[1,"col-md-4","input-group","mb-3","mr-auto"],["type","text","id","siteName","name","siteName","formControlName","siteName",1,"form-control"],[1,"input-group-append"],["id","editSiteName",1,"btn","btn-light",3,"click"],[3,"ngClass",4,"ngIf"],[3,"source","byId"],[1,"table-actions",3,"permission","selection","tableActions"],[1,"col-sm-6"],t,o,i,[3,"ngClass"]]},template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"div",1),e.TgZ(2,"form",2,3),e.TgZ(4,"div",4),e.TgZ(5,"label",5),e.SDv(6,6),e.qZA(),e.TgZ(7,"div",7),e._UZ(8,"input",8),e.TgZ(9,"div",9),e.TgZ(10,"button",10),e.NdJ("click",function(){return o.updateSiteName()}),e.YNc(11,Ji,1,1,"i",11),e.YNc(12,Yi,1,1,"i",11),e.qZA(),e._UZ(13,"cd-copy-2-clipboard-button",12),e.qZA(),e.qZA(),e._UZ(14,"cd-table-actions",13),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(15,"div",0),e.TgZ(16,"div",14),e.TgZ(17,"legend"),e.SDv(18,15),e.qZA(),e._UZ(19,"cd-mirroring-daemons"),e.qZA(),e.TgZ(20,"div",14),e.TgZ(21,"legend"),e.SDv(22,16),e.qZA(),e._UZ(23,"cd-mirroring-pools"),e.qZA(),e.qZA(),e.TgZ(24,"div",0),e.TgZ(25,"div",1),e.TgZ(26,"legend"),e.SDv(27,17),e.qZA(),e._UZ(28,"cd-mirroring-images"),e.qZA(),e.qZA()),2&t&&(e.xp6(2),e.Q6J("formGroup",o.rbdmirroringForm),e.xp6(6),e.uIk("disabled",!o.editing||null),e.xp6(3),e.Q6J("ngIf",!o.editing),e.xp6(1),e.Q6J("ngIf",o.editing),e.xp6(1),e.Q6J("source",o.siteName)("byId",!1),e.xp6(1),e.Q6J("permission",o.permission)("selection",o.selection)("tableActions",o.tableActions))},directives:[a._Y,a.JL,h.V,a.sg,$.o,a.Fj,k.b,a.JJ,a.u,l.O5,Ye.s,Ee.K,Ai,Bi,zi,l.mk],styles:[""]}),n})();class Ui{}function ji(n,s){if(1&n&&(e.TgZ(0,"option",16),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t.id),e.xp6(1),e.Oqu(t.name)}}function Wi(n,s){1&n&&(e.TgZ(0,"span",17),e.SDv(1,18),e.qZA())}let es=(()=>{class n{constructor(t,o,i,_,r,c){this.activeModal=t,this.actionLabels=o,this.rbdMirroringService=i,this.taskWrapper=_,this.route=r,this.location=c,this.bsConfig={containerClass:"theme-default"},this.peerExists=!1,this.mirrorModes=[{id:"disabled",name:"Disabled"},{id:"pool",name:"Pool"},{id:"image",name:"Image"}],this.createForm()}createForm(){this.editModeForm=new y.d({mirrorMode:new a.NI("",{validators:[a.kI.required,this.validateMode.bind(this)]})})}ngOnInit(){this.route.params.subscribe(t=>{this.poolName=t.pool_name}),this.pattern=`${this.poolName}`,this.rbdMirroringService.getPool(this.poolName).subscribe(t=>{this.setResponse(t)}),this.subs=this.rbdMirroringService.subscribeSummary(t=>{this.peerExists=!1;const i=t.content_data.pools.find(_=>this.poolName===_.name);this.peerExists=i&&i.peer_uuids.length})}ngOnDestroy(){this.subs.unsubscribe()}validateMode(t){return"disabled"===t.value&&this.peerExists?{cannotDisable:{value:t.value}}:null}setResponse(t){this.editModeForm.get("mirrorMode").setValue(t.mirror_mode)}update(){const t=new Ui;t.mirror_mode=this.editModeForm.getValue("mirrorMode"),this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/mirroring/pool/edit",{pool_name:this.poolName}),call:this.rbdMirroringService.updatePool(this.poolName,t)}).subscribe({error:()=>this.editModeForm.setErrors({cdSubmitButton:!0}),complete:()=>{this.rbdMirroringService.refresh(),this.location.back()}})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(N.Kz),e.Y36(v.p4),e.Y36(K),e.Y36(u.P),e.Y36(m.gz),e.Y36(l.Ye))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-pool-edit-mode-modal"]],decls:21,vars:7,consts:function(){let s,t,o,i;return s="Edit pool mirror mode",t="To edit the mirror mode for pool\xA0 " + "[\ufffd#10\ufffd|\ufffd#11\ufffd]" + "" + "\ufffd0\ufffd" + "" + "[\ufffd/#10\ufffd|\ufffd/#11\ufffd]" + ", select a new mode from the list and click\xA0 " + "[\ufffd#10\ufffd|\ufffd#11\ufffd]" + "Update" + "[\ufffd/#10\ufffd|\ufffd/#11\ufffd]" + ".",t=e.Zx4(t),o="Mode",i="Peer clusters must be removed prior to disabling mirror.",[["pageURL","mirroring",3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["name","editModeForm","novalidate","",1,"form",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],t,[1,"form-group"],["for","mirrorMode",1,"col-form-label"],o,["id","mirrorMode","name","mirrorMode","formControlName","mirrorMode",1,"form-control"],[3,"value",4,"ngFor","ngForOf"],["class","invalid-feedback",4,"ngIf"],[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],[3,"value"],[1,"invalid-feedback"],i]},template:function(t,o){if(1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.BQk(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.TgZ(7,"p"),e.ynx(8),e.tHW(9,7),e._UZ(10,"kbd"),e._UZ(11,"kbd"),e.N_p(),e.BQk(),e.qZA(),e.TgZ(12,"div",8),e.TgZ(13,"label",9),e.TgZ(14,"span"),e.SDv(15,10),e.qZA(),e.qZA(),e.TgZ(16,"select",11),e.YNc(17,ji,2,2,"option",12),e.qZA(),e.YNc(18,Wi,2,0,"span",13),e.qZA(),e.qZA(),e.TgZ(19,"div",14),e.TgZ(20,"cd-form-button-panel",15),e.NdJ("submitActionEvent",function(){return o.update()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t){const i=e.MAs(5);e.Q6J("modalRef",o.activeModal),e.xp6(4),e.Q6J("formGroup",o.editModeForm),e.xp6(7),e.pQV(o.poolName),e.QtT(9),e.xp6(6),e.Q6J("ngForOf",o.mirrorModes),e.xp6(1),e.Q6J("ngIf",o.editModeForm.showError("mirrorMode",i,"cannotDisable")),e.xp6(2),e.Q6J("form",o.editModeForm)("submitText",o.actionLabels.UPDATE)}},directives:[C.z,a._Y,a.JL,h.V,a.sg,O.P,$.o,a.EJ,k.b,a.JJ,a.u,l.sg,l.O5,j.p,a.YN,a.Kr],styles:[""]}),n})();var Ot=p(80226),ts=p(28049),os=p(43190),Ve=p(80842),st=p(30633),Le=p(47557),ns=p(28211);class is{}var Pe=(()=>{return(n=Pe||(Pe={}))[n.V1=1]="V1",n[n.V2=2]="V2",Pe;var n})();class ss{constructor(){this.features=[]}}class _s{constructor(){this.features=[]}}class rs extends class{}{constructor(){super(...arguments),this.features=[]}}class _t{constructor(){this.features=[],this.remove_scheduling=!1}}var Ue=(()=>{return(n=Ue||(Ue={})).editing="editing",n.cloning="cloning",n.copying="copying",Ue;var n})(),ls=p(17932),cs=p(18372),ds=p(54555);function ps(n,s){if(1&n&&(e.TgZ(0,"div",9),e.TgZ(1,"label",58),e.SDv(2,59),e.ALo(3,"titlecase"),e.qZA(),e.TgZ(4,"div",12),e._UZ(5,"input",60),e._UZ(6,"hr"),e.qZA(),e.qZA()),2&n){const t=e.oxw(2);e.xp6(3),e.pQV(e.lcZ(3,1,t.action)),e.QtT(2)}}function gs(n,s){1&n&&(e.TgZ(0,"span",61),e.ynx(1),e.SDv(2,62),e.BQk(),e.qZA())}function us(n,s){1&n&&(e.TgZ(0,"span",61),e.ynx(1),e.SDv(2,63),e.BQk(),e.qZA())}function ms(n,s){1&n&&e._UZ(0,"input",64)}function Ts(n,s){1&n&&(e.TgZ(0,"option",50),e.SDv(1,67),e.qZA()),2&n&&e.Q6J("ngValue",null)}function fs(n,s){1&n&&(e.TgZ(0,"option",50),e.SDv(1,68),e.qZA()),2&n&&e.Q6J("ngValue",null)}function Cs(n,s){1&n&&(e.TgZ(0,"option",50),e.SDv(1,69),e.qZA()),2&n&&e.Q6J("ngValue",null)}function Ss(n,s){if(1&n&&(e.TgZ(0,"option",70),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t.pool_name),e.xp6(1),e.Oqu(t.pool_name)}}function Es(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"select",65),e.NdJ("change",function(){return e.CHM(t),e.oxw(2).setPoolMirrorMode()}),e.YNc(1,Ts,2,1,"option",66),e.YNc(2,fs,2,1,"option",66),e.YNc(3,Cs,2,1,"option",66),e.YNc(4,Ss,2,2,"option",46),e.qZA()}if(2&n){const t=e.oxw(2);e.xp6(1),e.Q6J("ngIf",null===t.pools),e.xp6(1),e.Q6J("ngIf",null!==t.pools&&0===t.pools.length),e.xp6(1),e.Q6J("ngIf",null!==t.pools&&t.pools.length>0),e.xp6(1),e.Q6J("ngForOf",t.pools)}}function Rs(n,s){1&n&&(e.TgZ(0,"span",61),e.SDv(1,71),e.qZA())}const Ms=function(n,s){return[n,s]};function Os(n,s){if(1&n&&(e.TgZ(0,"div",9),e.TgZ(1,"div",20),e._UZ(2,"i",72),e.qZA(),e.qZA()),2&n){const t=e.oxw(2);e.xp6(2),e.Q6J("ngClass",e.WLB(1,Ms,t.icons.spinner,t.icons.spin))}}function As(n,s){1&n&&e._UZ(0,"input",76)}function hs(n,s){1&n&&(e.TgZ(0,"option",50),e.SDv(1,78),e.qZA()),2&n&&e.Q6J("ngValue",null)}function Ps(n,s){1&n&&(e.TgZ(0,"option",50),e.SDv(1,79),e.qZA()),2&n&&e.Q6J("ngValue",null)}function Is(n,s){1&n&&(e.TgZ(0,"option",50),e.SDv(1,80),e.qZA()),2&n&&e.Q6J("ngValue",null)}function bs(n,s){if(1&n&&(e.TgZ(0,"option",70),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t),e.xp6(1),e.Oqu(t)}}function Ns(n,s){if(1&n&&(e.TgZ(0,"select",77),e.YNc(1,hs,2,1,"option",66),e.YNc(2,Ps,2,1,"option",66),e.YNc(3,Is,2,1,"option",66),e.YNc(4,bs,2,2,"option",46),e.qZA()),2&n){const t=e.oxw(3);e.xp6(1),e.Q6J("ngIf",null===t.pools),e.xp6(1),e.Q6J("ngIf",null!==t.pools&&0===t.pools.length),e.xp6(1),e.Q6J("ngIf",null!==t.pools&&t.pools.length>0),e.xp6(1),e.Q6J("ngForOf",t.namespaces)}}function Fs(n,s){if(1&n&&(e.TgZ(0,"div",9),e.TgZ(1,"label",73),e._uU(2," Namespace "),e.qZA(),e.TgZ(3,"div",12),e.YNc(4,As,1,0,"input",74),e.YNc(5,Ns,5,4,"select",75),e.qZA(),e.qZA()),2&n){const t=e.oxw(2);e.xp6(4),e.Q6J("ngIf","editing"===t.mode||!t.poolPermission.read),e.xp6(1),e.Q6J("ngIf","editing"!==t.mode&&t.poolPermission.read)}}function Ds(n,s){1&n&&(e.TgZ(0,"cd-helper"),e.TgZ(1,"span"),e.SDv(2,81),e.qZA(),e.qZA())}function vs(n,s){1&n&&e._UZ(0,"input",87)}function Ls(n,s){1&n&&(e.TgZ(0,"option",50),e.SDv(1,89),e.qZA()),2&n&&e.Q6J("ngValue",null)}function $s(n,s){1&n&&(e.TgZ(0,"option",50),e.SDv(1,90),e.qZA()),2&n&&e.Q6J("ngValue",null)}function Zs(n,s){1&n&&(e.TgZ(0,"option",50),e._uU(1,"-- Select a data pool -- "),e.qZA()),2&n&&e.Q6J("ngValue",null)}function Bs(n,s){if(1&n&&(e.TgZ(0,"option",70),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t.pool_name),e.xp6(1),e.Oqu(t.pool_name)}}function Gs(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"select",88),e.NdJ("change",function(i){return e.CHM(t),e.oxw(3).onDataPoolChange(i.target.value)}),e.YNc(1,Ls,2,1,"option",66),e.YNc(2,$s,2,1,"option",66),e.YNc(3,Zs,2,1,"option",66),e.YNc(4,Bs,2,2,"option",46),e.qZA()}if(2&n){const t=e.oxw(3);e.xp6(1),e.Q6J("ngIf",null===t.dataPools),e.xp6(1),e.Q6J("ngIf",null!==t.dataPools&&0===t.dataPools.length),e.xp6(1),e.Q6J("ngIf",null!==t.dataPools&&t.dataPools.length>0),e.xp6(1),e.Q6J("ngForOf",t.dataPools)}}function xs(n,s){1&n&&(e.TgZ(0,"span",61),e.SDv(1,91),e.qZA())}const je=function(n){return{required:n}};function ys(n,s){if(1&n&&(e.TgZ(0,"div",9),e.TgZ(1,"label",82),e.TgZ(2,"span",72),e.SDv(3,83),e.qZA(),e._UZ(4,"cd-helper",84),e.qZA(),e.TgZ(5,"div",12),e.YNc(6,vs,1,0,"input",85),e.YNc(7,Gs,5,4,"select",86),e.YNc(8,xs,2,0,"span",14),e.qZA(),e.qZA()),2&n){e.oxw();const t=e.MAs(2),o=e.oxw();e.xp6(2),e.Q6J("ngClass",e.VKq(4,je,"editing"!==o.mode)),e.xp6(4),e.Q6J("ngIf","editing"===o.mode||!o.poolPermission.read),e.xp6(1),e.Q6J("ngIf","editing"!==o.mode&&o.poolPermission.read),e.xp6(1),e.Q6J("ngIf",o.rbdForm.showError("dataPool",t,"required"))}}function ws(n,s){1&n&&(e.TgZ(0,"span",61),e.SDv(1,92),e.qZA())}function qs(n,s){1&n&&(e.TgZ(0,"span",61),e.SDv(1,93),e.qZA())}function Hs(n,s){if(1&n&&e._UZ(0,"cd-helper",97),2&n){const t=e.oxw().$implicit;e.s9C("html",t.helperHtml)}}function ks(n,s){if(1&n&&(e.TgZ(0,"div",21),e._UZ(1,"input",94),e.TgZ(2,"label",95),e._uU(3),e.qZA(),e.YNc(4,Hs,1,1,"cd-helper",96),e.qZA()),2&n){const t=s.$implicit;e.xp6(1),e.s9C("id",t.key),e.s9C("name",t.key),e.s9C("formControlName",t.key),e.xp6(1),e.s9C("for",t.key),e.xp6(1),e.Oqu(t.desc),e.xp6(1),e.Q6J("ngIf",t.helperHtml)}}const At=function(n){return["edit",n]},ht=function(n){return{modal:n}},Pt=function(n){return{outlets:n}},It=function(n){return["/block/mirroring",n]};function Ks(n,s){if(1&n&&(e.TgZ(0,"cd-helper"),e.TgZ(1,"span"),e.tHW(2,98),e._UZ(3,"b"),e._UZ(4,"a",99),e.N_p(),e.qZA(),e.qZA()),2&n){const t=e.oxw(2);e.xp6(4),e.Q6J("routerLink",e.VKq(7,It,e.VKq(5,Pt,e.VKq(3,ht,e.VKq(1,At,t.currentPoolName)))))}}function Xs(n,s){if(1&n&&(e.TgZ(0,"cd-helper"),e.TgZ(1,"span"),e.tHW(2,103),e._UZ(3,"b"),e._UZ(4,"a",99),e.N_p(),e.qZA(),e.qZA()),2&n){const t=e.oxw(4);e.xp6(4),e.Q6J("routerLink",e.VKq(7,It,e.VKq(5,Pt,e.VKq(3,ht,e.VKq(1,At,t.currentPoolName)))))}}function Qs(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",101),e.TgZ(1,"input",102),e.NdJ("change",function(){return e.CHM(t),e.oxw(3).setExclusiveLock()}),e.qZA(),e.TgZ(2,"label",95),e._uU(3),e.ALo(4,"titlecase"),e.qZA(),e.YNc(5,Xs,5,9,"cd-helper",25),e.qZA()}if(2&n){const t=s.$implicit,o=e.oxw(3);e.xp6(1),e.Q6J("id",t)("value",t),e.uIk("disabled","pool"===o.poolMirrorMode&&"snapshot"===t||null),e.xp6(1),e.Q6J("for",t),e.xp6(1),e.Oqu(e.lcZ(4,6,t)),e.xp6(2),e.Q6J("ngIf","pool"===o.poolMirrorMode&&"snapshot"===t)}}function zs(n,s){if(1&n&&(e.TgZ(0,"div"),e.YNc(1,Qs,6,8,"div",100),e.qZA()),2&n){const t=e.oxw(2);e.xp6(1),e.Q6J("ngForOf",t.mirroringOptions)}}function Js(n,s){if(1&n&&(e.TgZ(0,"div",9),e.TgZ(1,"label",104),e.tHW(2,105),e._UZ(3,"cd-helper",106),e.N_p(),e.qZA(),e.TgZ(4,"div",12),e._UZ(5,"input",107),e.qZA(),e.qZA()),2&n){const t=e.oxw(2);e.xp6(5),e.uIk("disabled",t.mode===t.rbdFormMode.editing||null)}}function Ys(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"a",108),e.NdJ("click",function(){return e.CHM(t),e.oxw(2).advancedEnabled=!0,!1}),e.SDv(1,109),e.qZA()}}function Vs(n,s){if(1&n&&(e.TgZ(0,"option",70),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t),e.xp6(1),e.Oqu(t)}}function Us(n,s){if(1&n&&(e.TgZ(0,"option",70),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t),e.xp6(1),e.Oqu(t)}}function js(n,s){1&n&&(e.TgZ(0,"span",61),e.SDv(1,110),e.qZA())}function Ws(n,s){1&n&&(e.TgZ(0,"span",61),e.SDv(1,111),e.qZA())}function e_(n,s){1&n&&(e.TgZ(0,"span",61),e.SDv(1,112),e.qZA())}function t_(n,s){1&n&&(e.TgZ(0,"span",61),e.SDv(1,113),e.qZA())}function o_(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",1),e.TgZ(1,"form",2,3),e.TgZ(3,"div",4),e.TgZ(4,"div",5),e.SDv(5,6),e.ALo(6,"titlecase"),e.ALo(7,"upperFirst"),e.qZA(),e.TgZ(8,"div",7),e.YNc(9,ps,7,3,"div",8),e.TgZ(10,"div",9),e.TgZ(11,"label",10),e.SDv(12,11),e.qZA(),e.TgZ(13,"div",12),e._UZ(14,"input",13),e.YNc(15,gs,3,0,"span",14),e.YNc(16,us,3,0,"span",14),e.qZA(),e.qZA(),e.TgZ(17,"div",15),e.NdJ("change",function(i){return e.CHM(t),e.oxw().onPoolChange(i.target.value)}),e.TgZ(18,"label",16),e.SDv(19,17),e.qZA(),e.TgZ(20,"div",12),e.YNc(21,ms,1,0,"input",18),e.YNc(22,Es,5,4,"select",19),e.YNc(23,Rs,2,0,"span",14),e.qZA(),e.qZA(),e.YNc(24,Os,3,4,"div",8),e.YNc(25,Fs,6,2,"div",8),e.TgZ(26,"div",9),e.TgZ(27,"div",20),e.TgZ(28,"div",21),e.TgZ(29,"input",22),e.NdJ("change",function(){return e.CHM(t),e.oxw().onUseDataPoolChange()}),e.qZA(),e.TgZ(30,"label",23),e.SDv(31,24),e.qZA(),e.YNc(32,Ds,3,0,"cd-helper",25),e.qZA(),e.qZA(),e.qZA(),e.YNc(33,ys,9,6,"div",8),e.TgZ(34,"div",9),e.TgZ(35,"label",26),e.SDv(36,27),e.qZA(),e.TgZ(37,"div",12),e._UZ(38,"input",28),e.YNc(39,ws,2,0,"span",14),e.YNc(40,qs,2,0,"span",14),e.qZA(),e.qZA(),e.TgZ(41,"div",29),e.TgZ(42,"label",30),e.SDv(43,31),e.qZA(),e.TgZ(44,"div",12),e.YNc(45,ks,5,6,"div",32),e.qZA(),e.qZA(),e.TgZ(46,"div",9),e.TgZ(47,"div",20),e.TgZ(48,"div",21),e.TgZ(49,"input",33),e.NdJ("change",function(){return e.CHM(t),e.oxw().setMirrorMode()}),e.qZA(),e.TgZ(50,"label",34),e._uU(51,"Mirroring"),e.qZA(),e.YNc(52,Ks,5,9,"cd-helper",25),e.qZA(),e.YNc(53,zs,2,1,"div",25),e.qZA(),e.qZA(),e.YNc(54,Js,6,1,"div",8),e.TgZ(55,"div",35),e.TgZ(56,"div",36),e.YNc(57,Ys,2,0,"a",37),e.qZA(),e.qZA(),e.TgZ(58,"div",38),e.TgZ(59,"legend",39),e.SDv(60,40),e.qZA(),e.TgZ(61,"div",41),e.TgZ(62,"h4",39),e.SDv(63,42),e.qZA(),e.TgZ(64,"div",9),e.TgZ(65,"label",43),e.tHW(66,44),e._UZ(67,"cd-helper"),e.N_p(),e.qZA(),e.TgZ(68,"div",12),e.TgZ(69,"select",45),e.YNc(70,Vs,2,2,"option",46),e.qZA(),e.qZA(),e.qZA(),e.TgZ(71,"div",9),e.TgZ(72,"label",47),e.tHW(73,48),e._UZ(74,"cd-helper"),e.N_p(),e.qZA(),e.TgZ(75,"div",12),e.TgZ(76,"select",49),e.TgZ(77,"option",50),e.SDv(78,51),e.qZA(),e.YNc(79,Us,2,2,"option",46),e.qZA(),e.YNc(80,js,2,0,"span",14),e.YNc(81,Ws,2,0,"span",14),e.qZA(),e.qZA(),e.TgZ(82,"div",9),e.TgZ(83,"label",52),e.tHW(84,53),e._UZ(85,"cd-helper"),e.N_p(),e.qZA(),e.TgZ(86,"div",12),e._UZ(87,"input",54),e.YNc(88,e_,2,0,"span",14),e.YNc(89,t_,2,0,"span",14),e.qZA(),e.qZA(),e.qZA(),e.TgZ(90,"cd-rbd-configuration-form",55),e.NdJ("changes",function(i){return e.CHM(t),e.oxw().getDirtyConfigurationValues=i}),e.qZA(),e.qZA(),e.qZA(),e.TgZ(91,"div",56),e.TgZ(92,"cd-form-button-panel",57),e.NdJ("submitActionEvent",function(){return e.CHM(t),e.oxw().submit()}),e.ALo(93,"titlecase"),e.ALo(94,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=e.MAs(2),o=e.oxw();e.xp6(1),e.Q6J("formGroup",o.rbdForm),e.xp6(6),e.pQV(e.lcZ(6,35,o.action))(e.lcZ(7,37,o.resource)),e.QtT(5),e.xp6(2),e.Q6J("ngIf",o.rbdForm.getValue("parent")),e.xp6(6),e.Q6J("ngIf",o.rbdForm.showError("name",t,"required")),e.xp6(1),e.Q6J("ngIf",o.rbdForm.showError("name",t,"pattern")),e.xp6(2),e.Q6J("ngClass",e.VKq(43,je,"editing"!==o.mode)),e.xp6(3),e.Q6J("ngIf","editing"===o.mode||!o.poolPermission.read),e.xp6(1),e.Q6J("ngIf","editing"!==o.mode&&o.poolPermission.read),e.xp6(1),e.Q6J("ngIf",o.rbdForm.showError("pool",t,"required")),e.xp6(1),e.Q6J("ngIf","editing"!==o.mode&&o.rbdForm.getValue("pool")&&null===o.namespaces),e.xp6(1),e.Q6J("ngIf","editing"===o.mode&&o.rbdForm.getValue("namespace")||"editing"!==o.mode&&(o.namespaces&&o.namespaces.length>0||!o.poolPermission.read)),e.xp6(7),e.Q6J("ngIf",o.allDataPools.length<=1),e.xp6(1),e.Q6J("ngIf",o.rbdForm.getValue("useDataPool")),e.xp6(6),e.Q6J("ngIf",o.rbdForm.showError("size",t,"required")),e.xp6(1),e.Q6J("ngIf",o.rbdForm.showError("size",t,"invalidSizeObject")),e.xp6(5),e.Q6J("ngForOf",o.featuresList),e.xp6(7),e.Q6J("ngIf",!1===o.mirroring&&o.currentPoolName),e.xp6(1),e.Q6J("ngIf",o.mirroring),e.xp6(1),e.Q6J("ngIf","snapshot"===o.rbdForm.getValue("mirroringMode")&&o.mirroring),e.xp6(3),e.Q6J("ngIf",!o.advancedEnabled),e.xp6(1),e.Q6J("hidden",!o.advancedEnabled),e.xp6(12),e.Q6J("ngForOf",o.objectSizes),e.xp6(2),e.Q6J("ngClass",e.VKq(45,je,o.rbdForm.getValue("stripingCount"))),e.xp6(5),e.Q6J("ngValue",null),e.xp6(2),e.Q6J("ngForOf",o.objectSizes),e.xp6(1),e.Q6J("ngIf",o.rbdForm.showError("stripingUnit",t,"required")),e.xp6(1),e.Q6J("ngIf",o.rbdForm.showError("stripingUnit",t,"invalidStripingUnit")),e.xp6(2),e.Q6J("ngClass",e.VKq(47,je,o.rbdForm.getValue("stripingUnit"))),e.xp6(5),e.Q6J("ngIf",o.rbdForm.showError("stripingCount",t,"required")),e.xp6(1),e.Q6J("ngIf",o.rbdForm.showError("stripingCount",t,"min")),e.xp6(1),e.Q6J("form",o.rbdForm)("initializeData",o.initializeConfigData),e.xp6(2),e.Q6J("form",t)("submitText",e.lcZ(93,39,o.action)+" "+e.lcZ(94,41,o.resource))}}let $e=(()=>{class n extends H.E{constructor(t,o,i,_,r,c,d,g,f,I){super(),this.authStorageService=t,this.route=o,this.poolService=i,this.rbdService=_,this.formatter=r,this.taskWrapper=c,this.dimlessBinaryPipe=d,this.actionLabels=g,this.router=f,this.rbdMirroringService=I,this.namespaces=[],this.namespacesByPoolCache={},this.pools=null,this.allPools=null,this.dataPools=null,this.allDataPools=[],this.featuresList=[],this.initializeConfigData=new Ot.t(1),this.advancedEnabled=!1,this.rbdFormMode=Ue,this.defaultObjectSize="4 MiB",this.mirroringOptions=["journal","snapshot"],this.mirroring=!1,this.currentPoolName="",this.objectSizes=["4 KiB","8 KiB","16 KiB","32 KiB","64 KiB","128 KiB","256 KiB","512 KiB","1 MiB","2 MiB","4 MiB","8 MiB","16 MiB","32 MiB"],this.defaultStripingUnit="4 MiB",this.defaultStripingCount=1,this.rbdImage=new Ot.t(1),this.icons=T.P,this.routerUrl=this.router.url,this.poolPermission=this.authStorageService.getPermissions().pool,this.resource="RBD",this.features={"deep-flatten":{desc:"Deep flatten",requires:null,allowEnable:!1,allowDisable:!0},layering:{desc:"Layering",requires:null,allowEnable:!1,allowDisable:!1},"exclusive-lock":{desc:"Exclusive lock",requires:null,allowEnable:!0,allowDisable:!0},"object-map":{desc:"Object map (requires exclusive-lock)",requires:"exclusive-lock",allowEnable:!0,allowDisable:!0,initDisabled:!0},"fast-diff":{desc:"Fast diff (interlocked with object-map)",requires:"object-map",allowEnable:!0,allowDisable:!0,interlockedWith:"object-map",initDisabled:!0}},this.featuresList=this.objToArray(this.features),this.createForm()}objToArray(t){return S().map(t,(o,i)=>Object.assign(o,{key:i}))}createForm(){this.rbdForm=new y.d({parent:new a.NI(""),name:new a.NI("",{validators:[a.kI.required,a.kI.pattern(/^[^@/]+?$/)]}),pool:new a.NI(null,{validators:[a.kI.required]}),namespace:new a.NI(null),useDataPool:new a.NI(!1),dataPool:new a.NI(null),size:new a.NI(null,{updateOn:"blur"}),obj_size:new a.NI(this.defaultObjectSize),features:new y.d(this.featuresList.reduce((t,o)=>(t[o.key]=new a.NI({value:!1,disabled:!!o.initDisabled}),t),{})),mirroring:new a.NI(!1),schedule:new a.NI("",{validators:[a.kI.pattern(/^([0-9]+)d|([0-9]+)h|([0-9]+)m$/)]}),mirroringMode:new a.NI(this.mirroringOptions[0]),stripingUnit:new a.NI(this.defaultStripingUnit),stripingCount:new a.NI(this.defaultStripingCount,{updateOn:"blur"})},this.validateRbdForm(this.formatter))}disableForEdit(){this.rbdForm.get("parent").disable(),this.rbdForm.get("pool").disable(),this.rbdForm.get("namespace").disable(),this.rbdForm.get("useDataPool").disable(),this.rbdForm.get("dataPool").disable(),this.rbdForm.get("obj_size").disable(),this.rbdForm.get("stripingUnit").disable(),this.rbdForm.get("stripingCount").disable(),this.rbdImage.subscribe(t=>{t.image_format===Pe.V1&&(this.rbdForm.get("deep-flatten").disable(),this.rbdForm.get("layering").disable(),this.rbdForm.get("exclusive-lock").disable())})}disableForClone(){this.rbdForm.get("parent").disable(),this.rbdForm.get("size").disable()}disableForCopy(){this.rbdForm.get("parent").disable(),this.rbdForm.get("size").disable()}ngOnInit(){this.prepareFormForAction(),this.gatherNeededData().subscribe(this.handleExternalData.bind(this))}setExclusiveLock(){this.mirroring&&"journal"===this.rbdForm.get("mirroringMode").value?(this.rbdForm.get("exclusive-lock").setValue(!0),this.rbdForm.get("exclusive-lock").disable()):(this.rbdForm.get("exclusive-lock").enable(),"pool"===this.poolMirrorMode&&this.rbdForm.get("mirroringMode").setValue(this.mirroringOptions[0]))}setMirrorMode(){this.mirroring=!this.mirroring,this.setExclusiveLock()}setPoolMirrorMode(){var t;this.currentPoolName=this.mode===this.rbdFormMode.editing?null===(t=this.response)||void 0===t?void 0:t.pool_name:this.rbdForm.getValue("pool"),this.currentPoolName&&(this.rbdMirroringService.refresh(),this.rbdMirroringService.subscribeSummary(o=>{const i=o.content_data.pools.find(_=>_.name===this.currentPoolName);this.poolMirrorMode=i.mirror_mode,"disabled"===i.mirror_mode?(this.mirroring=!1,this.rbdForm.get("mirroring").setValue(this.mirroring),this.rbdForm.get("mirroring").disable()):this.mode!==this.rbdFormMode.editing&&(this.rbdForm.get("mirroring").enable(),this.mirroring=!0,this.rbdForm.get("mirroring").setValue(this.mirroring))})),this.setExclusiveLock()}prepareFormForAction(){const t=this.routerUrl;t.startsWith("/block/rbd/edit")?(this.mode=this.rbdFormMode.editing,this.action=this.actionLabels.EDIT,this.disableForEdit()):t.startsWith("/block/rbd/clone")?(this.mode=this.rbdFormMode.cloning,this.disableForClone(),this.action=this.actionLabels.CLONE):t.startsWith("/block/rbd/copy")?(this.mode=this.rbdFormMode.copying,this.action=this.actionLabels.COPY,this.disableForCopy()):this.action=this.actionLabels.CREATE,S().each(this.features,o=>{this.rbdForm.get("features").get(o.key).valueChanges.subscribe(i=>this.featureFormUpdate(o.key,i))})}gatherNeededData(){const t={};return this.mode?this.route.params.subscribe(o=>{const i=L.N.fromString(decodeURIComponent(o.image_spec));o.snap&&(this.snapName=decodeURIComponent(o.snap)),t.rbd=this.rbdService.get(i)}):t.defaultFeatures=this.rbdService.defaultFeatures(),this.mode!==this.rbdFormMode.editing&&this.poolPermission.read&&(t.pools=this.poolService.list(["pool_name","type","flags_names","application_metadata"])),(0,le.D)(t)}handleExternalData(t){if(this.handlePoolData(t.pools),this.setPoolMirrorMode(),t.defaultFeatures&&this.setFeatures(t.defaultFeatures),t.rbd){const o=t.rbd;this.setResponse(o,this.snapName),this.rbdImage.next(o)}this.loadingReady()}handlePoolData(t){if(!t)return;const o=[],i=[];for(const _ of t)this.rbdService.isRBDPool(_)&&("replicated"===_.type?(o.push(_),i.push(_)):"erasure"===_.type&&-1!==_.flags_names.indexOf("ec_overwrites")&&i.push(_));if(this.pools=o,this.allPools=o,this.dataPools=i,this.allDataPools=i,1===this.pools.length){const _=this.pools[0].pool_name;this.rbdForm.get("pool").setValue(_),this.onPoolChange(_)}this.allDataPools.length<=1&&this.rbdForm.get("useDataPool").disable()}onPoolChange(t){const o=this.rbdForm.get("dataPool");o.value===t&&o.setValue(null),this.dataPools=this.allDataPools?this.allDataPools.filter(i=>i.pool_name!==t):[],this.namespaces=null,t in this.namespacesByPoolCache?this.namespaces=this.namespacesByPoolCache[t]:this.rbdService.listNamespaces(t).subscribe(i=>{i=i.map(_=>_.namespace),this.namespacesByPoolCache[t]=i,this.namespaces=i}),this.rbdForm.get("namespace").setValue(null)}onUseDataPoolChange(){this.rbdForm.getValue("useDataPool")||(this.rbdForm.get("dataPool").setValue(null),this.onDataPoolChange(null))}onDataPoolChange(t){const o=this.allPools.filter(i=>i.pool_name!==t);this.rbdForm.getValue("pool")===t&&this.rbdForm.get("pool").setValue(null),this.pools=o}validateRbdForm(t){return o=>{const i=o.get("useDataPool"),_=o.get("dataPool");let r=null;i.value&&null==_.value&&(r={required:!0}),_.setErrors(r);const c=o.get("size"),d=o.get("obj_size"),g=t.toBytes(null!=d.value?d.value:this.defaultObjectSize),f=o.get("stripingCount"),I=null!=f.value?f.value:this.defaultStripingCount;let P=null;null===c.value?P={required:!0}:I*g>t.toBytes(c.value)&&(P={invalidSizeObject:!0}),c.setErrors(P);const Z=o.get("stripingUnit");let B=null;null===Z.value&&null!==f.value?B={required:!0}:null!==Z.value&&t.toBytes(Z.value)>g&&(B={invalidStripingUnit:!0}),Z.setErrors(B);let Q=null;return null===f.value&&null!==Z.value?Q={required:!0}:I<1&&(Q={min:!0}),f.setErrors(Q),null}}deepBoxCheck(t,o){this.getDependentChildFeatures(t).forEach(_=>{const r=this.rbdForm.get(_.key);o?r.enable({emitEvent:!1}):(r.disable({emitEvent:!1}),r.setValue(!1,{emitEvent:!1}),this.deepBoxCheck(_.key,o));const c=this.rbdForm.get("features");this.mode===this.rbdFormMode.editing&&c.get(_.key).enabled&&(-1!==this.response.features_name.indexOf(_.key)&&!_.allowDisable||-1===this.response.features_name.indexOf(_.key)&&!_.allowEnable)&&c.get(_.key).disable()})}getDependentChildFeatures(t){return S().filter(this.features,o=>o.requires===t)||[]}interlockCheck(t,o){const i=this.featuresList.find(_=>_.key===t);if(this.response){const _=null!=i.interlockedWith,r=this.featuresList.find(d=>d.interlockedWith===i.key),c=!!this.response.features_name.find(d=>d===i.key);if(_){if(c!==!!this.response.features_name.find(g=>g===i.interlockedWith))return}else if(r&&!!this.response.features_name.find(g=>g===r.key)!==c)return}o?S().filter(this.features,_=>_.interlockedWith===t).forEach(_=>this.rbdForm.get(_.key).setValue(!0,{emitEvent:!1})):i.interlockedWith&&this.rbdForm.get("features").get(i.interlockedWith).setValue(!1)}featureFormUpdate(t,o){if(o){const i=this.features[t].requires;if(i&&!this.rbdForm.getValue(i))return void this.rbdForm.get(`features.${t}`).setValue(!1)}this.deepBoxCheck(t,o),this.interlockCheck(t,o)}setFeatures(t){const o=this.rbdForm.get("features");S().forIn(this.features,i=>{-1!==t.indexOf(i.key)&&o.get(i.key).setValue(!0),this.featureFormUpdate(i.key,o.get(i.key).value)})}setResponse(t,o){this.response=t;const i=new L.N(t.pool_name,t.namespace,t.name).toString();if(this.mode===this.rbdFormMode.cloning)this.rbdForm.get("parent").setValue(`${i}@${o}`);else if(this.mode===this.rbdFormMode.copying)o?this.rbdForm.get("parent").setValue(`${i}@${o}`):this.rbdForm.get("parent").setValue(`${i}`);else if(t.parent){const _=t.parent;this.rbdForm.get("parent").setValue(`${_.pool_name}/${_.image_name}@${_.snap_name}`)}this.mode===this.rbdFormMode.editing&&(this.rbdForm.get("name").setValue(t.name),"snapshot"===(null==t?void 0:t.mirror_mode)||t.features_name.includes("journaling")?(this.mirroring=!0,this.rbdForm.get("mirroring").setValue(this.mirroring),this.rbdForm.get("mirroringMode").setValue(null==t?void 0:t.mirror_mode),this.rbdForm.get("schedule").setValue(null==t?void 0:t.schedule_interval)):(this.mirroring=!1,this.rbdForm.get("mirroring").setValue(this.mirroring)),this.setPoolMirrorMode()),this.rbdForm.get("pool").setValue(t.pool_name),this.onPoolChange(t.pool_name),this.rbdForm.get("namespace").setValue(t.namespace),t.data_pool&&(this.rbdForm.get("useDataPool").setValue(!0),this.rbdForm.get("dataPool").setValue(t.data_pool)),this.rbdForm.get("size").setValue(this.dimlessBinaryPipe.transform(t.size)),this.rbdForm.get("obj_size").setValue(this.dimlessBinaryPipe.transform(t.obj_size)),this.setFeatures(t.features_name),this.rbdForm.get("stripingUnit").setValue(this.dimlessBinaryPipe.transform(t.stripe_unit)),this.rbdForm.get("stripingCount").setValue(t.stripe_count),this.initializeConfigData.next({initialData:this.response.configuration,sourceType:st.h.image})}createRequest(){const t=new rs;return t.pool_name=this.rbdForm.getValue("pool"),t.namespace=this.rbdForm.getValue("namespace"),t.name=this.rbdForm.getValue("name"),t.schedule_interval=this.rbdForm.getValue("schedule"),t.size=this.formatter.toBytes(this.rbdForm.getValue("size")),"image"===this.poolMirrorMode&&(t.mirror_mode=this.rbdForm.getValue("mirroringMode")),this.addObjectSizeAndStripingToRequest(t),t.configuration=this.getDirtyConfigurationValues(),t}addObjectSizeAndStripingToRequest(t){t.obj_size=this.formatter.toBytes(this.rbdForm.getValue("obj_size")),S().forIn(this.features,o=>{this.rbdForm.getValue(o.key)&&t.features.push(o.key)}),this.mirroring&&"journal"===this.rbdForm.getValue("mirroringMode")&&t.features.push("journaling"),t.stripe_unit=this.formatter.toBytes(this.rbdForm.getValue("stripingUnit")),t.stripe_count=this.rbdForm.getValue("stripingCount"),t.data_pool=this.rbdForm.getValue("dataPool")}createAction(){const t=this.createRequest();return this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/create",{pool_name:t.pool_name,namespace:t.namespace,image_name:t.name,schedule_interval:t.schedule_interval,start_time:t.start_time}),call:this.rbdService.create(t)})}editRequest(){const t=new _t;if(t.name=this.rbdForm.getValue("name"),t.schedule_interval=this.rbdForm.getValue("schedule"),t.name=this.rbdForm.getValue("name"),t.size=this.formatter.toBytes(this.rbdForm.getValue("size")),S().forIn(this.features,o=>{this.rbdForm.getValue(o.key)&&t.features.push(o.key)}),t.enable_mirror=this.rbdForm.getValue("mirroring"),t.enable_mirror)"journal"===this.rbdForm.getValue("mirroringMode")&&t.features.push("journaling"),"image"===this.poolMirrorMode&&(t.mirror_mode=this.rbdForm.getValue("mirroringMode"));else{const o=t.features.indexOf("journaling",0);o>-1&&t.features.splice(o,1)}return t.configuration=this.getDirtyConfigurationValues(),t}cloneRequest(){const t=new ss;return t.child_pool_name=this.rbdForm.getValue("pool"),t.child_namespace=this.rbdForm.getValue("namespace"),t.child_image_name=this.rbdForm.getValue("name"),this.addObjectSizeAndStripingToRequest(t),t.configuration=this.getDirtyConfigurationValues(!0,st.h.image),t}editAction(){const t=new L.N(this.response.pool_name,this.response.namespace,this.response.name);return this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/edit",{image_spec:t.toString()}),call:this.rbdService.update(t,this.editRequest())})}cloneAction(){const t=this.cloneRequest(),o=new L.N(this.response.pool_name,this.response.namespace,this.response.name);return this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/clone",{parent_image_spec:o.toString(),parent_snap_name:this.snapName,child_pool_name:t.child_pool_name,child_namespace:t.child_namespace,child_image_name:t.child_image_name}),call:this.rbdService.cloneSnapshot(o,this.snapName,t)})}copyRequest(){const t=new _s;return this.snapName&&(t.snapshot_name=this.snapName),t.dest_pool_name=this.rbdForm.getValue("pool"),t.dest_namespace=this.rbdForm.getValue("namespace"),t.dest_image_name=this.rbdForm.getValue("name"),this.addObjectSizeAndStripingToRequest(t),t.configuration=this.getDirtyConfigurationValues(!0,st.h.image),t}copyAction(){const t=this.copyRequest(),o=new L.N(this.response.pool_name,this.response.namespace,this.response.name);return this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/copy",{src_image_spec:o.toString(),dest_pool_name:t.dest_pool_name,dest_namespace:t.dest_namespace,dest_image_name:t.dest_image_name}),call:this.rbdService.copy(o,t)})}submit(){this.mode||this.rbdImage.next("create"),this.rbdImage.pipe((0,ts.P)(),(0,os.w)(()=>this.mode===this.rbdFormMode.editing?this.editAction():this.mode===this.rbdFormMode.cloning?this.cloneAction():this.mode===this.rbdFormMode.copying?this.copyAction():this.createAction())).subscribe(()=>{},()=>this.rbdForm.setErrors({cdSubmitButton:!0}),()=>this.router.navigate(["/block/rbd"]))}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(oe.j),e.Y36(m.gz),e.Y36(Ve.q),e.Y36(q),e.Y36(ns.H),e.Y36(u.P),e.Y36(Le.$),e.Y36(v.p4),e.Y36(m.F0),e.Y36(K))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-rbd-form"]],features:[e.qOj],decls:1,vars:1,consts:function(){let s,t,o,i,_,r,c,d,g,f,I,P,Z,B,Q,Y,ee,te,w,_e,ae,M,ge,ue,me,Te,fe,Ce,G,Be,Ge,xe,ye,we,qe,He,ke,Ke,Xe,Qe,ze;return s="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",t="Name",o="Pool",i="Use a dedicated data pool",_="Size",r="e.g., 10GiB",c="Features",d="Advanced",g="Striping",f="Object size" + "\ufffd#67\ufffd" + "Objects in the Ceph Storage Cluster have a maximum configurable size (e.g., 2MB, 4MB, etc.). The object size should be large enough to accommodate many stripe units, and should be a multiple of the stripe unit." + "\ufffd/#67\ufffd" + "",I="Stripe unit" + "\ufffd#74\ufffd" + "Stripes have a configurable unit size (e.g., 64kb). The Ceph Client divides the data it will write to objects into equally sized stripe units, except for the last stripe unit. A stripe width, should be a fraction of the Object Size so that an object may contain many stripe units." + "\ufffd/#74\ufffd" + "",P="-- Select stripe unit --",Z="Stripe count" + "\ufffd#85\ufffd" + "The Ceph Client writes a sequence of stripe units over a series of objects determined by the stripe count. The series of objects is called an object set. After the Ceph Client writes to the last object in the object set, it returns to the first object in the object set." + "\ufffd/#85\ufffd" + "",B="" + "\ufffd0\ufffd" + " from",Q="This field is required.",Y="'/' and '@' are not allowed.",ee="Loading...",te="-- No rbd pools available --",w="-- Select a pool --",_e="This field is required.",ae="Loading...",M="-- No namespaces available --",ge="-- Select a namespace --",ue="You need more than one pool with the rbd application label use to use a dedicated data pool.",me="Data pool",Te="Dedicated pool that stores the object-data of the RBD.",fe="Loading...",Ce="-- No data pools available --",G="This field is required.",Be="This field is required.",Ge="You have to increase the size.",xe="You need to enable a " + "\ufffd#3\ufffd" + "mirror mode" + "\ufffd/#3\ufffd" + " in the selected pool. Please " + "\ufffd#4\ufffd" + "click here to select a mode and enable it in this pool." + "\ufffd/#4\ufffd" + "",ye="You need to enable " + "\ufffd#3\ufffd" + "image mirror mode" + "\ufffd/#3\ufffd" + " in the selected pool. Please " + "\ufffd#4\ufffd" + "click here to select a mode and enable it in this pool." + "\ufffd/#4\ufffd" + "",we="Create Mirror-Snapshots automatically on a periodic basis. The interval can be specified in days, hours, or minutes using d, h, m suffix respectively.",qe="Schedule Interval " + "\ufffd#3\ufffd" + "" + "\ufffd/#3\ufffd" + "",He="e.g., 12h or 1d or 10m",ke="Advanced...",Ke="This field is required because stripe count is defined!",Xe="Stripe unit is greater than object size.",Qe="This field is required because stripe unit is defined!",ze="Stripe count must be greater than 0.",[["class","cd-col-form",4,"cdFormLoading"],[1,"cd-col-form"],["name","rbdForm","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"card"],[1,"card-header"],s,[1,"card-body"],["class","form-group row",4,"ngIf"],[1,"form-group","row"],["for","name",1,"cd-col-form-label","required"],t,[1,"cd-col-form-input"],["type","text","placeholder","Name...","id","name","name","name","formControlName","name","autofocus","",1,"form-control"],["class","invalid-feedback",4,"ngIf"],[1,"form-group","row",3,"change"],["for","pool",1,"cd-col-form-label",3,"ngClass"],o,["class","form-control","type","text","placeholder","Pool name...","id","pool","name","pool","formControlName","pool",4,"ngIf"],["id","pool","name","pool","class","form-control","formControlName","pool",3,"change",4,"ngIf"],[1,"cd-col-form-offset"],[1,"custom-control","custom-checkbox"],["type","checkbox","id","useDataPool","name","useDataPool","formControlName","useDataPool",1,"custom-control-input",3,"change"],["for","useDataPool",1,"custom-control-label"],i,[4,"ngIf"],["for","size",1,"cd-col-form-label","required"],_,["id","size","name","size","type","text","formControlName","size","placeholder",r,"defaultUnit","GiB","cdDimlessBinary","",1,"form-control"],["formGroupName","features",1,"form-group","row"],["for","features",1,"cd-col-form-label"],c,["class","custom-control custom-checkbox",4,"ngFor","ngForOf"],["type","checkbox","id","mirroring","name","mirroring","formControlName","mirroring",1,"custom-control-input",3,"change"],["for","mirroring",1,"custom-control-label"],[1,"row"],[1,"col-sm-12"],["class","float-right margin-right-md","href","",3,"click",4,"ngIf"],[3,"hidden"],[1,"cd-header"],d,[1,"col-md-12"],g,["for","size",1,"cd-col-form-label"],f,["id","obj_size","name","obj_size","formControlName","obj_size",1,"form-control"],[3,"value",4,"ngFor","ngForOf"],["for","stripingUnit",1,"cd-col-form-label",3,"ngClass"],I,["id","stripingUnit","name","stripingUnit","formControlName","stripingUnit",1,"form-control"],[3,"ngValue"],P,["for","stripingCount",1,"cd-col-form-label",3,"ngClass"],Z,["id","stripingCount","name","stripingCount","formControlName","stripingCount","type","number",1,"form-control"],[3,"form","initializeData","changes"],[1,"card-footer"],["wrappingClass","text-right",3,"form","submitText","submitActionEvent"],["for","name",1,"cd-col-form-label"],B,["type","text","id","parent","name","parent","formControlName","parent",1,"form-control"],[1,"invalid-feedback"],Q,Y,["type","text","placeholder","Pool name...","id","pool","name","pool","formControlName","pool",1,"form-control"],["id","pool","name","pool","formControlName","pool",1,"form-control",3,"change"],[3,"ngValue",4,"ngIf"],ee,te,w,[3,"value"],_e,[3,"ngClass"],["for","pool",1,"cd-col-form-label"],["class","form-control","type","text","placeholder","Namespace...","id","namespace","name","namespace","formControlName","namespace",4,"ngIf"],["id","namespace","name","namespace","class","form-control","formControlName","namespace",4,"ngIf"],["type","text","placeholder","Namespace...","id","namespace","name","namespace","formControlName","namespace",1,"form-control"],["id","namespace","name","namespace","formControlName","namespace",1,"form-control"],ae,M,ge,ue,["for","dataPool",1,"cd-col-form-label"],me,["html",Te],["class","form-control","type","text","placeholder","Data pool name...","id","dataPool","name","dataPool","formControlName","dataPool",4,"ngIf"],["id","dataPool","name","dataPool","class","form-control","formControlName","dataPool",3,"change",4,"ngIf"],["type","text","placeholder","Data pool name...","id","dataPool","name","dataPool","formControlName","dataPool",1,"form-control"],["id","dataPool","name","dataPool","formControlName","dataPool",1,"form-control",3,"change"],fe,Ce,G,Be,Ge,["type","checkbox",1,"custom-control-input",3,"id","name","formControlName"],[1,"custom-control-label",3,"for"],[3,"html",4,"ngIf"],[3,"html"],xe,[3,"routerLink"],["class","custom-control custom-radio ml-2",4,"ngFor","ngForOf"],[1,"custom-control","custom-radio","ml-2"],["type","radio","name","mirroringMode","formControlName","mirroringMode",1,"custom-control-input",3,"id","value","change"],ye,[1,"cd-col-form-label"],qe,["html",we],["id","schedule","name","schedule","type","text","formControlName","schedule","placeholder",He,1,"form-control"],["href","",1,"float-right","margin-right-md",3,"click"],ke,Ke,Xe,Qe,ze]},template:function(t,o){1&t&&e.YNc(0,o_,95,49,"div",0),2&t&&e.Q6J("cdFormLoading",o.loading)},directives:[pt.y,a._Y,a.JL,a.sg,h.V,l.O5,O.P,$.o,a.Fj,k.b,a.JJ,a.u,Re.U,l.mk,a.Wl,ls.Q,a.x0,l.sg,cs.S,a.EJ,a.YN,a.Kr,a.wV,ds.d,j.p,m.yS,a._],pipes:[l.rS,et.m],styles:[""]}),n})();var bt=p(71225),Nt=p(36169);let n_=(()=>{class n{constructor(){}static getCount(t){var o;return Number(null===(o=t.headers)||void 0===o?void 0:o.get("X-Total-Count"))}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();var at=p(51847),i_=p(16738),Me=p.n(i_),rt=p(62862),s_=p(52266);function __(n,s){1&n&&(e.TgZ(0,"div",18),e.TgZ(1,"span"),e.SDv(2,19),e.qZA(),e.qZA())}function a_(n,s){1&n&&(e.TgZ(0,"span",20),e.SDv(1,21),e.qZA())}function r_(n,s){1&n&&(e.TgZ(0,"span",20),e.SDv(1,22),e.qZA())}function l_(n,s){if(1&n&&e._UZ(0,"cd-date-time-picker",23),2&n){const t=e.oxw();e.Q6J("control",t.moveForm.get("expiresAt"))}}let c_=(()=>{class n{constructor(t,o,i,_,r){this.rbdService=t,this.activeModal=o,this.actionLabels=i,this.fb=_,this.taskWrapper=r,this.createForm()}createForm(){this.moveForm=this.fb.group({expiresAt:["",[z.h.custom("format",t=>!(""===t||Me()(t,"YYYY-MM-DD HH:mm:ss").isValid())),z.h.custom("expired",t=>Me()().isAfter(t))]]})}ngOnInit(){this.imageSpec=new L.N(this.poolName,this.namespace,this.imageName),this.imageSpecStr=this.imageSpec.toString(),this.pattern=`${this.poolName}/${this.imageName}`}moveImage(){let t=0;const o=this.moveForm.getValue("expiresAt");o&&(t=Me()(o,"YYYY-MM-DD HH:mm:ss").diff(Me()(),"seconds",!0)),t<0&&(t=0),this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/trash/move",{image_spec:this.imageSpecStr}),call:this.rbdService.moveTrash(this.imageSpec,t)}).subscribe({complete:()=>{this.activeModal.close()}})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(q),e.Y36(N.Kz),e.Y36(v.p4),e.Y36(rt.O),e.Y36(u.P))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-rbd-trash-move-modal"]],decls:23,vars:9,consts:function(){let s,t,o,i,_,r,c;return s="Move an image to trash",t="To move " + "[\ufffd#10\ufffd|\ufffd#11\ufffd]" + "" + "\ufffd0\ufffd" + "" + "[\ufffd/#10\ufffd|\ufffd/#11\ufffd]" + " to trash, click " + "[\ufffd#10\ufffd|\ufffd#11\ufffd]" + "Move" + "[\ufffd/#10\ufffd|\ufffd/#11\ufffd]" + ". Optionally, you can pick an expiration date.",t=e.Zx4(t),o="Protection expires at",i="NOT PROTECTED",_="This image contains snapshot(s), which will prevent it from being removed after moved to trash.",r="Wrong date format. Please use \"YYYY-MM-DD HH:mm:ss\".",c="Protection has already expired. Please pick a future date or leave it empty.",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["name","moveForm","novalidate","",1,"form",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],["class","alert alert-warning","role","alert",4,"ngIf"],t,[1,"form-group"],["for","expiresAt",1,"col-form-label"],o,["type","text","placeholder",i,"formControlName","expiresAt","triggers","manual",1,"form-control",3,"ngbPopover","click","keypress"],["p","ngbPopover"],["class","invalid-feedback",4,"ngIf"],[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],["popContent",""],["role","alert",1,"alert","alert-warning"],_,[1,"invalid-feedback"],r,c,[3,"control"]]},template:function(t,o){if(1&t){const i=e.EpF();e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.BQk(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.YNc(7,__,3,0,"div",7),e.TgZ(8,"p"),e.tHW(9,8),e._UZ(10,"kbd"),e._UZ(11,"kbd"),e.N_p(),e.qZA(),e.TgZ(12,"div",9),e.TgZ(13,"label",10),e.SDv(14,11),e.qZA(),e.TgZ(15,"input",12,13),e.NdJ("click",function(){return e.CHM(i),e.MAs(16).open()})("keypress",function(){return e.CHM(i),e.MAs(16).close()}),e.qZA(),e.YNc(17,a_,2,0,"span",14),e.YNc(18,r_,2,0,"span",14),e.qZA(),e.qZA(),e.TgZ(19,"div",15),e.TgZ(20,"cd-form-button-panel",16),e.NdJ("submitActionEvent",function(){return o.moveImage()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA(),e.YNc(21,l_,1,1,"ng-template",null,17,e.W1O)}if(2&t){const i=e.MAs(5),_=e.MAs(22);e.Q6J("modalRef",o.activeModal),e.xp6(4),e.Q6J("formGroup",o.moveForm),e.xp6(3),e.Q6J("ngIf",o.hasSnapshots),e.xp6(4),e.pQV(o.imageSpecStr),e.QtT(9),e.xp6(4),e.Q6J("ngbPopover",_),e.xp6(2),e.Q6J("ngIf",o.moveForm.showError("expiresAt",i,"format")),e.xp6(1),e.Q6J("ngIf",o.moveForm.showError("expiresAt",i,"expired")),e.xp6(2),e.Q6J("form",o.moveForm)("submitText",o.actionLabels.MOVE)}},directives:[C.z,a._Y,a.JL,a.sg,h.V,l.O5,O.P,$.o,a.Fj,k.b,a.JJ,a.u,N.o8,j.p,s_.J],styles:[""]}),n})();function d_(n,s){1&n&&(e.TgZ(0,"li",10),e.TgZ(1,"a",3),e.SDv(2,11),e.qZA(),e.qZA())}let We=(()=>{class n{constructor(t,o){this.authStorageService=t,this.router=o,this.grafanaPermission=this.authStorageService.getPermissions().grafana}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(oe.j),e.Y36(m.F0))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-rbd-tabs"]],decls:12,vars:2,consts:function(){let s,t,o,i;return s="Images",t="Namespaces",o="Trash",i="Overall Performance",[["ngbNav","",1,"nav-tabs",3,"activeId","navChange"],["nav","ngbNav"],["ngbNavItem","/block/rbd"],["ngbNavLink",""],s,["ngbNavItem","/block/rbd/namespaces"],t,["ngbNavItem","/block/rbd/trash"],o,["ngbNavItem","/block/rbd/performance",4,"ngIf"],["ngbNavItem","/block/rbd/performance"],i]},template:function(t,o){1&t&&(e.TgZ(0,"ul",0,1),e.NdJ("navChange",function(_){return o.router.navigate([_.nextId])}),e.TgZ(2,"li",2),e.TgZ(3,"a",3),e.SDv(4,4),e.qZA(),e.qZA(),e.TgZ(5,"li",5),e.TgZ(6,"a",3),e.SDv(7,6),e.qZA(),e.qZA(),e.TgZ(8,"li",7),e.TgZ(9,"a",3),e.SDv(10,8),e.qZA(),e.qZA(),e.YNc(11,d_,3,0,"li",9),e.qZA()),2&t&&(e.Q6J("activeId",o.router.url),e.xp6(11),e.Q6J("ngIf",o.grafanaPermission.read))},directives:[N.Pz,N.nv,N.Vx,l.O5],styles:[""]}),n})();var p_=p(25917),Ft=p(51295),lt=p(60737),g_=p(74255),Dt=p(71099),vt=p(79765);function u_(n,s){1&n&&(e.TgZ(0,"span",16),e.SDv(1,17),e.qZA())}function m_(n,s){if(1&n&&(e.TgZ(0,"span"),e.tHW(1,18),e._UZ(2,"b"),e.N_p(),e.qZA()),2&n){const t=e.oxw();e.xp6(2),e.pQV(t.imageName),e.QtT(1)}}let T_=(()=>{class n{constructor(t,o,i,_,r){this.activeModal=t,this.rbdService=o,this.taskManagerService=i,this.notificationService=_,this.actionLabels=r,this.editing=!1,this.onSubmit=new vt.xQ,this.action=this.actionLabels.CREATE,this.resource="RBD Snapshot",this.createForm()}createForm(){this.snapshotForm=new y.d({snapshotName:new a.NI("",{validators:[a.kI.required]})})}setSnapName(t){this.snapName=t,"snapshot"!==this.mirroring?this.snapshotForm.get("snapshotName").setValue(t):this.snapshotForm.get("snapshotName").clearValidators()}setEditing(t=!0){this.editing=t,this.action=this.editing?this.actionLabels.RENAME:this.actionLabels.CREATE}editAction(){const t=this.snapshotForm.getValue("snapshotName"),o=new L.N(this.poolName,this.namespace,this.imageName),i=new R.R;i.name="rbd/snap/edit",i.metadata={image_spec:o.toString(),snapshot_name:t},this.rbdService.renameSnapshot(o,this.snapName,t).toPromise().then(()=>{this.taskManagerService.subscribe(i.name,i.metadata,_=>{this.notificationService.notifyTask(_)}),this.activeModal.close(),this.onSubmit.next(this.snapName)}).catch(()=>{this.snapshotForm.setErrors({cdSubmitButton:!0})})}createAction(){const t=this.snapshotForm.getValue("snapshotName"),o=new L.N(this.poolName,this.namespace,this.imageName),i=new R.R;i.name="rbd/snap/create",i.metadata={image_spec:o.toString(),snapshot_name:t},this.rbdService.createSnapshot(o,t).toPromise().then(()=>{this.taskManagerService.subscribe(i.name,i.metadata,_=>{this.notificationService.notifyTask(_)}),this.activeModal.close(),this.onSubmit.next(t)}).catch(()=>{this.snapshotForm.setErrors({cdSubmitButton:!0})})}submit(){this.editing?this.editAction():this.createAction()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(N.Kz),e.Y36(q),e.Y36(Dt.k),e.Y36(ve.g),e.Y36(v.p4))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-rbd-snapshot-form-modal"]],decls:22,vars:17,consts:function(){let s,t,o,i;return s="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",t="Name",o="This field is required.",i="Snapshot mode is enabled on image " + "\ufffd#2\ufffd" + "" + "\ufffd0\ufffd" + "" + "\ufffd/#2\ufffd" + ": snapshot names are auto generated",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["name","snapshotForm","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],[1,"form-group","row"],["for","snapshotName",1,"cd-col-form-label","required"],t,[1,"cd-col-form-input"],["type","text","placeholder","Snapshot name...","id","snapshotName","name","snapshotName","formControlName","snapshotName","autofocus","",1,"form-control"],["class","invalid-feedback",4,"ngIf"],[4,"ngIf"],[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],[1,"invalid-feedback"],o,i]},template:function(t,o){if(1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.ALo(3,"titlecase"),e.ALo(4,"upperFirst"),e.BQk(),e.ynx(5,3),e.TgZ(6,"form",4,5),e.TgZ(8,"div",6),e.TgZ(9,"div",7),e.TgZ(10,"label",8),e.SDv(11,9),e.qZA(),e.TgZ(12,"div",10),e._UZ(13,"input",11),e.YNc(14,u_,2,0,"span",12),e._UZ(15,"br"),e._UZ(16,"br"),e.YNc(17,m_,3,1,"span",13),e.qZA(),e.qZA(),e.qZA(),e.TgZ(18,"div",14),e.TgZ(19,"cd-form-button-panel",15),e.NdJ("submitActionEvent",function(){return o.submit()}),e.ALo(20,"titlecase"),e.ALo(21,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t){const i=e.MAs(7);e.Q6J("modalRef",o.activeModal),e.xp6(4),e.pQV(e.lcZ(3,9,o.action))(e.lcZ(4,11,o.resource)),e.QtT(2),e.xp6(2),e.Q6J("formGroup",o.snapshotForm),e.xp6(7),e.uIk("disabled","snapshot"===o.mirroring||null),e.xp6(1),e.Q6J("ngIf",o.snapshotForm.showError("snapshotName",i,"required")),e.xp6(3),e.Q6J("ngIf","snapshot"===o.mirroring),e.xp6(2),e.Q6J("form",o.snapshotForm)("submitText",e.lcZ(20,13,o.action)+" "+e.lcZ(21,15,o.resource))}},directives:[C.z,a._Y,a.JL,a.sg,h.V,O.P,$.o,a.Fj,k.b,a.JJ,a.u,Re.U,l.O5,j.p],pipes:[l.rS,et.m],styles:[""]}),n})();class f_{constructor(s,t,o){this.featuresName=t,this.cloneFormatVersion=1,o.cloneFormatVersion().subscribe(i=>{this.cloneFormatVersion=i}),this.create={permission:"create",icon:T.P.add,name:s.CREATE},this.rename={permission:"update",icon:T.P.edit,name:s.RENAME,disable:i=>this.disableForMirrorSnapshot(i)},this.protect={permission:"update",icon:T.P.lock,visible:i=>i.hasSingleSelection&&!i.first().is_protected,name:s.PROTECT,disable:i=>this.disableForMirrorSnapshot(i)},this.unprotect={permission:"update",icon:T.P.unlock,visible:i=>i.hasSingleSelection&&i.first().is_protected,name:s.UNPROTECT,disable:i=>this.disableForMirrorSnapshot(i)},this.clone={permission:"create",canBePrimary:i=>i.hasSingleSelection,disable:i=>this.getCloneDisableDesc(i,this.featuresName)||this.disableForMirrorSnapshot(i),icon:T.P.clone,name:s.CLONE},this.copy={permission:"create",canBePrimary:i=>i.hasSingleSelection,disable:i=>!i.hasSingleSelection||i.first().cdExecuting||this.disableForMirrorSnapshot(i),icon:T.P.copy,name:s.COPY},this.rollback={permission:"update",icon:T.P.undo,name:s.ROLLBACK,disable:i=>this.disableForMirrorSnapshot(i)},this.deleteSnap={permission:"delete",icon:T.P.destroy,disable:i=>{const _=i.first();return!i.hasSingleSelection||_.cdExecuting||_.is_protected||this.disableForMirrorSnapshot(i)},name:s.DELETE},this.ordering=[this.create,this.rename,this.protect,this.unprotect,this.clone,this.copy,this.rollback,this.deleteSnap]}getCloneDisableDesc(s,t){return!(s.hasSingleSelection&&!s.first().cdExecuting)||((null==t?void 0:t.includes("layering"))?1===this.cloneFormatVersion&&!s.first().is_protected&&"Snapshot must be protected in order to clone.":"Parent image must support Layering")}disableForMirrorSnapshot(s){return s.hasSingleSelection&&"snapshot"===s.first().mirror_mode&&s.first().name.includes(".mirror.")}}class C_{}var Ze=p(96102);const S_=["nameTpl"],E_=["rollbackTpl"];function R_(n,s){if(1&n&&(e.ynx(0),e.SDv(1,3),e.BQk(),e.TgZ(2,"strong"),e._uU(3),e.qZA(),e._uU(4,".\n")),2&n){const t=s.$implicit;e.xp6(3),e.hij(" ",t.snapName,"")}}let M_=(()=>{class n{constructor(t,o,i,_,r,c,d,g,f,I,P){this.authStorageService=t,this.modalService=o,this.dimlessBinaryPipe=i,this.cdDatePipe=_,this.rbdService=r,this.taskManagerService=c,this.notificationService=d,this.summaryService=g,this.taskListService=f,this.actionLabels=I,this.cdr=P,this.snapshots=[],this.selection=new Se.r,this.builders={"rbd/snap/create":Z=>{const B=new C_;return B.name=Z.snapshot_name,B}},this.permission=this.authStorageService.getPermissions().rbdImage}ngOnInit(){this.columns=[{name:"Name",prop:"name",cellTransformation:De.e.executing,flexGrow:2},{name:"Size",prop:"size",flexGrow:1,cellClass:"text-right",pipe:this.dimlessBinaryPipe},{name:"Provisioned",prop:"disk_usage",flexGrow:1,cellClass:"text-right",pipe:this.dimlessBinaryPipe},{name:"State",prop:"is_protected",flexGrow:1,cellTransformation:De.e.badge,customTemplateConfig:{map:{true:{value:"PROTECTED",class:"badge-success"},false:{value:"UNPROTECTED",class:"badge-info"}}}},{name:"Created",prop:"timestamp",flexGrow:1,pipe:this.cdDatePipe}],this.imageSpec=new L.N(this.poolName,this.namespace,this.rbdName),this.rbdTableActions=new f_(this.actionLabels,this.featuresName,this.rbdService),this.rbdTableActions.create.click=()=>this.openCreateSnapshotModal(),this.rbdTableActions.rename.click=()=>this.openEditSnapshotModal(),this.rbdTableActions.protect.click=()=>this.toggleProtection(),this.rbdTableActions.unprotect.click=()=>this.toggleProtection();const t=()=>this.selection.first()&&`${this.imageSpec.toStringEncoded()}/${encodeURIComponent(this.selection.first().name)}`;this.rbdTableActions.clone.routerLink=()=>`/block/rbd/clone/${t()}`,this.rbdTableActions.copy.routerLink=()=>`/block/rbd/copy/${t()}`,this.rbdTableActions.rollback.click=()=>this.rollbackModal(),this.rbdTableActions.deleteSnap.click=()=>this.deleteSnapshotModal(),this.tableActions=this.rbdTableActions.ordering,this.taskListService.init(()=>(0,p_.of)(this.snapshots),null,_=>{Ft.T.updateChanged(this,{data:_})&&(this.cdr.detectChanges(),this.data=[...this.data])},()=>{Ft.T.updateChanged(this,{data:this.snapshots})&&(this.cdr.detectChanges(),this.data=[...this.data])},_=>["rbd/snap/create","rbd/snap/delete","rbd/snap/edit","rbd/snap/rollback"].includes(_.name)&&this.imageSpec.toString()===_.metadata.image_spec,(_,r)=>_.name===r.metadata.snapshot_name,this.builders)}ngOnChanges(){this.columns&&(this.imageSpec=new L.N(this.poolName,this.namespace,this.rbdName),this.rbdTableActions&&(this.rbdTableActions.featuresName=this.featuresName),this.taskListService.fetch())}openSnapshotModal(t,o=null){this.modalRef=this.modalService.show(T_,{mirroring:this.mirroring}),this.modalRef.componentInstance.poolName=this.poolName,this.modalRef.componentInstance.imageName=this.rbdName,this.modalRef.componentInstance.namespace=this.namespace,o?this.modalRef.componentInstance.setEditing():o=`${this.rbdName}_${Me()().toISOString(!0)}`,this.modalRef.componentInstance.setSnapName(o),this.modalRef.componentInstance.onSubmit.subscribe(_=>{const r=new lt.o;r.name=t,r.metadata={image_spec:this.imageSpec.toString(),snapshot_name:_},this.summaryService.addRunningTask(r)})}openCreateSnapshotModal(){this.openSnapshotModal("rbd/snap/create")}openEditSnapshotModal(){this.openSnapshotModal("rbd/snap/edit",this.selection.first().name)}toggleProtection(){const t=this.selection.first().name,o=this.selection.first().is_protected,i=new R.R;i.name="rbd/snap/edit";const _=new L.N(this.poolName,this.namespace,this.rbdName);i.metadata={image_spec:_.toString(),snapshot_name:t},this.rbdService.protectSnapshot(_,t,!o).toPromise().then(()=>{const r=new lt.o;r.name=i.name,r.metadata=i.metadata,this.summaryService.addRunningTask(r),this.taskManagerService.subscribe(i.name,i.metadata,c=>{this.notificationService.notifyTask(c)})})}_asyncTask(t,o,i){const _=new R.R;_.name=o,_.metadata={image_spec:new L.N(this.poolName,this.namespace,this.rbdName).toString(),snapshot_name:i};const r=new L.N(this.poolName,this.namespace,this.rbdName);this.rbdService[t](r,i).toPromise().then(()=>{const c=new lt.o;c.name=_.name,c.metadata=_.metadata,this.summaryService.addRunningTask(c),this.modalRef.close(),this.taskManagerService.subscribe(c.name,c.metadata,d=>{this.notificationService.notifyTask(d)})}).catch(()=>{this.modalRef.componentInstance.stopLoadingSpinner()})}rollbackModal(){const t=this.selection.selected[0].name,o=new L.N(this.poolName,this.namespace,this.rbdName).toString(),i={titleText:"RBD snapshot rollback",buttonText:"Rollback",bodyTpl:this.rollbackTpl,bodyData:{snapName:`${o}@${t}`},onSubmit:()=>{this._asyncTask("rollbackSnapshot","rbd/snap/rollback",t)}};this.modalRef=this.modalService.show(Nt.Y,i)}deleteSnapshotModal(){const t=this.selection.selected[0].name;this.modalRef=this.modalService.show(pe.M,{itemDescription:"RBD snapshot",itemNames:[t],submitAction:()=>this._asyncTask("deleteSnapshot","rbd/snap/delete",t)})}updateSelection(t){this.selection=t}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(oe.j),e.Y36(de.Z),e.Y36(Le.$),e.Y36(Ze.N),e.Y36(q),e.Y36(Dt.k),e.Y36(ve.g),e.Y36(g_.J),e.Y36(ce.j),e.Y36(v.p4),e.Y36(e.sBO))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-rbd-snapshot-list"]],viewQuery:function(t,o){if(1&t&&(e.Gf(S_,5),e.Gf(E_,7)),2&t){let i;e.iGM(i=e.CRH())&&(o.nameTpl=i.first),e.iGM(i=e.CRH())&&(o.rollbackTpl=i.first)}},inputs:{snapshots:"snapshots",featuresName:"featuresName",poolName:"poolName",namespace:"namespace",mirroring:"mirroring",rbdName:"rbdName"},features:[e._Bn([ce.j]),e.TTD],decls:4,vars:5,consts:function(){let s;return s="You are about to rollback",[["columnMode","flex","selectionType","single",3,"data","columns","updateSelection"],[1,"table-actions",3,"permission","selection","tableActions"],["rollbackTpl",""],s]},template:function(t,o){1&t&&(e.TgZ(0,"cd-table",0),e.NdJ("updateSelection",function(_){return o.updateSelection(_)}),e._UZ(1,"cd-table-actions",1),e.qZA(),e.YNc(2,R_,5,1,"ng-template",null,2,e.W1O)),2&t&&(e.Q6J("data",o.data)("columns",o.columns),e.xp6(1),e.Q6J("permission",o.permission)("selection",o.selection)("tableActions",o.tableActions))},directives:[W.a,Ee.K],styles:[""],changeDetection:0}),n})();var O_=p(71752),Lt=p(76317),A_=p(41039);const h_=["poolConfigurationSourceTpl"];function P_(n,s){1&n&&(e.ynx(0),e.tHW(1,3),e._UZ(2,"strong"),e.N_p(),e.BQk())}function I_(n,s){if(1&n&&(e.TgZ(0,"span"),e.TgZ(1,"span",38),e._uU(2),e.qZA(),e.qZA()),2&n){const t=s.$implicit;e.xp6(2),e.Oqu(t)}}function b_(n,s){if(1&n&&(e.TgZ(0,"span"),e.TgZ(1,"span",39),e.SDv(2,40),e.qZA(),e.qZA()),2&n){e.oxw(3);const t=e.MAs(1);e.xp6(1),e.Q6J("ngbTooltip",t)}}function N_(n,s){if(1&n&&(e.TgZ(0,"span"),e._uU(1),e.ALo(2,"dimlessBinary"),e.qZA()),2&n){const t=e.oxw(3);e.xp6(1),e.hij(" ",e.lcZ(2,1,t.selection.disk_usage)," ")}}function F_(n,s){if(1&n&&(e.TgZ(0,"span"),e.TgZ(1,"span",39),e.SDv(2,41),e.qZA(),e.qZA()),2&n){e.oxw(3);const t=e.MAs(1);e.xp6(1),e.Q6J("ngbTooltip",t)}}function D_(n,s){if(1&n&&(e.TgZ(0,"span"),e._uU(1),e.ALo(2,"dimlessBinary"),e.qZA()),2&n){const t=e.oxw(3);e.xp6(1),e.hij(" ",e.lcZ(2,1,t.selection.total_disk_usage)," ")}}function v_(n,s){if(1&n&&(e.TgZ(0,"span"),e._uU(1),e.qZA()),2&n){const t=e.oxw(4);e.xp6(1),e.hij("/",t.selection.parent.pool_namespace,"")}}function L_(n,s){if(1&n&&(e.TgZ(0,"span"),e._uU(1),e.YNc(2,v_,2,1,"span",1),e._uU(3),e.qZA()),2&n){const t=e.oxw(3);e.xp6(1),e.Oqu(t.selection.parent.pool_name),e.xp6(1),e.Q6J("ngIf",t.selection.parent.pool_namespace),e.xp6(1),e.AsE("/",t.selection.parent.image_name,"@",t.selection.parent.snap_name,"")}}function $_(n,s){1&n&&(e.TgZ(0,"span"),e._uU(1,"-"),e.qZA())}function Z_(n,s){if(1&n&&(e.TgZ(0,"table",17),e.TgZ(1,"tbody"),e.TgZ(2,"tr"),e.TgZ(3,"td",18),e.SDv(4,19),e.qZA(),e.TgZ(5,"td",20),e._uU(6),e.qZA(),e.qZA(),e.TgZ(7,"tr"),e.TgZ(8,"td",21),e.SDv(9,22),e.qZA(),e.TgZ(10,"td"),e._uU(11),e.qZA(),e.qZA(),e.TgZ(12,"tr"),e.TgZ(13,"td",21),e.SDv(14,23),e.qZA(),e.TgZ(15,"td"),e._uU(16),e.ALo(17,"empty"),e.qZA(),e.qZA(),e.TgZ(18,"tr"),e.TgZ(19,"td",21),e.SDv(20,24),e.qZA(),e.TgZ(21,"td"),e._uU(22),e.ALo(23,"cdDate"),e.qZA(),e.qZA(),e.TgZ(24,"tr"),e.TgZ(25,"td",21),e.SDv(26,25),e.qZA(),e.TgZ(27,"td"),e._uU(28),e.ALo(29,"dimlessBinary"),e.qZA(),e.qZA(),e.TgZ(30,"tr"),e.TgZ(31,"td",21),e.SDv(32,26),e.qZA(),e.TgZ(33,"td"),e._uU(34),e.ALo(35,"dimless"),e.qZA(),e.qZA(),e.TgZ(36,"tr"),e.TgZ(37,"td",21),e.SDv(38,27),e.qZA(),e.TgZ(39,"td"),e._uU(40),e.ALo(41,"dimlessBinary"),e.qZA(),e.qZA(),e.TgZ(42,"tr"),e.TgZ(43,"td",21),e.SDv(44,28),e.qZA(),e.TgZ(45,"td"),e.YNc(46,I_,3,1,"span",29),e.qZA(),e.qZA(),e.TgZ(47,"tr"),e.TgZ(48,"td",21),e.SDv(49,30),e.qZA(),e.TgZ(50,"td"),e.YNc(51,b_,3,1,"span",1),e.YNc(52,N_,3,3,"span",1),e.qZA(),e.qZA(),e.TgZ(53,"tr"),e.TgZ(54,"td",21),e.SDv(55,31),e.qZA(),e.TgZ(56,"td"),e.YNc(57,F_,3,1,"span",1),e.YNc(58,D_,3,3,"span",1),e.qZA(),e.qZA(),e.TgZ(59,"tr"),e.TgZ(60,"td",21),e.SDv(61,32),e.qZA(),e.TgZ(62,"td"),e._uU(63),e.ALo(64,"dimlessBinary"),e.qZA(),e.qZA(),e.TgZ(65,"tr"),e.TgZ(66,"td",21),e.SDv(67,33),e.qZA(),e.TgZ(68,"td"),e._uU(69),e.qZA(),e.qZA(),e.TgZ(70,"tr"),e.TgZ(71,"td",21),e.SDv(72,34),e.qZA(),e.TgZ(73,"td"),e.YNc(74,L_,4,4,"span",1),e.YNc(75,$_,2,0,"span",1),e.qZA(),e.qZA(),e.TgZ(76,"tr"),e.TgZ(77,"td",21),e.SDv(78,35),e.qZA(),e.TgZ(79,"td"),e._uU(80),e.qZA(),e.qZA(),e.TgZ(81,"tr"),e.TgZ(82,"td",21),e.SDv(83,36),e.qZA(),e.TgZ(84,"td"),e._uU(85),e.qZA(),e.qZA(),e.TgZ(86,"tr"),e.TgZ(87,"td",21),e.SDv(88,37),e.qZA(),e.TgZ(89,"td"),e._uU(90),e.qZA(),e.qZA(),e.qZA(),e.qZA()),2&n){const t=e.oxw(2);e.xp6(6),e.Oqu(t.selection.name),e.xp6(5),e.Oqu(t.selection.pool_name),e.xp6(5),e.Oqu(e.lcZ(17,19,t.selection.data_pool)),e.xp6(6),e.Oqu(e.lcZ(23,21,t.selection.timestamp)),e.xp6(6),e.Oqu(e.lcZ(29,23,t.selection.size)),e.xp6(6),e.Oqu(e.lcZ(35,25,t.selection.num_objs)),e.xp6(6),e.Oqu(e.lcZ(41,27,t.selection.obj_size)),e.xp6(6),e.Q6J("ngForOf",t.selection.features_name),e.xp6(5),e.Q6J("ngIf",-1===(null==t.selection.features_name?null:t.selection.features_name.indexOf("fast-diff"))),e.xp6(1),e.Q6J("ngIf",-1!==(null==t.selection.features_name?null:t.selection.features_name.indexOf("fast-diff"))),e.xp6(5),e.Q6J("ngIf",-1===(null==t.selection.features_name?null:t.selection.features_name.indexOf("fast-diff"))),e.xp6(1),e.Q6J("ngIf",-1!==(null==t.selection.features_name?null:t.selection.features_name.indexOf("fast-diff"))),e.xp6(5),e.Oqu(e.lcZ(64,29,t.selection.stripe_unit)),e.xp6(6),e.Oqu(t.selection.stripe_count),e.xp6(5),e.Q6J("ngIf",t.selection.parent),e.xp6(1),e.Q6J("ngIf",!t.selection.parent),e.xp6(5),e.Oqu(t.selection.block_name_prefix),e.xp6(5),e.Oqu(t.selection.order),e.xp6(5),e.Oqu(t.selection.image_format)}}function B_(n,s){if(1&n&&e._UZ(0,"cd-rbd-snapshot-list",42),2&n){const t=e.oxw(2);e.Q6J("snapshots",t.selection.snapshots)("featuresName",t.selection.features_name)("poolName",t.selection.pool_name)("namespace",t.selection.namespace)("mirroring",t.selection.mirror_mode)("rbdName",t.selection.name)}}function G_(n,s){if(1&n&&e._UZ(0,"cd-rbd-configuration-table",43),2&n){const t=e.oxw(2);e.Q6J("data",t.selection.configuration)}}function x_(n,s){if(1&n&&e._UZ(0,"cd-grafana",44),2&n){const t=e.oxw(2);e.Q6J("grafanaPath",t.rbdDashboardUrl)}}function y_(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"ul",4,5),e.TgZ(3,"li",6),e.TgZ(4,"a",7),e.SDv(5,8),e.qZA(),e.YNc(6,Z_,91,31,"ng-template",9),e.qZA(),e.TgZ(7,"li",10),e.TgZ(8,"a",7),e.SDv(9,11),e.qZA(),e.YNc(10,B_,1,6,"ng-template",9),e.qZA(),e.TgZ(11,"li",12),e.TgZ(12,"a",7),e.SDv(13,13),e.qZA(),e.YNc(14,G_,1,1,"ng-template",9),e.qZA(),e.TgZ(15,"li",14),e.TgZ(16,"a",7),e.SDv(17,15),e.qZA(),e.YNc(18,x_,1,1,"ng-template",9),e.qZA(),e.qZA(),e._UZ(19,"div",16),e.BQk()),2&n){const t=e.MAs(2);e.xp6(19),e.Q6J("ngbNavOutlet",t)}}function w_(n,s){1&n&&(e.ynx(0),e.TgZ(1,"cd-alert-panel",45),e.SDv(2,46),e.qZA(),e.BQk())}function q_(n,s){1&n&&(e.ynx(0),e.TgZ(1,"strong",49),e.SDv(2,50),e.qZA(),e.BQk())}function H_(n,s){1&n&&(e.TgZ(0,"span",51),e.SDv(1,52),e.qZA())}function k_(n,s){if(1&n&&(e.YNc(0,q_,3,0,"ng-container",47),e.YNc(1,H_,2,0,"ng-template",null,48,e.W1O)),2&n){const t=s.value,o=e.MAs(2);e.Q6J("ngIf",+t)("ngIfElse",o)}}let K_=(()=>{class n{ngOnChanges(){this.selection&&(this.rbdDashboardUrl=`rbd-details?var-Pool=${this.selection.pool_name}&var-Image=${this.selection.name}`)}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-rbd-details"]],viewQuery:function(t,o){if(1&t&&(e.Gf(h_,7),e.Gf(N.Pz,7)),2&t){let i;e.iGM(i=e.CRH())&&(o.poolConfigurationSourceTpl=i.first),e.iGM(i=e.CRH())&&(o.nav=i.first)}},inputs:{selection:"selection",images:"images"},features:[e.TTD],decls:6,vars:2,consts:function(){let s,t,o,i,_,r,c,d,g,f,I,P,Z,B,Q,Y,ee,te,w,_e,ae,M,ge,ue,me,Te,fe,Ce;return s="Only available for RBD images with " + "\ufffd#2\ufffd" + "fast-diff" + "\ufffd/#2\ufffd" + " enabled",t="Details",o="Snapshots",i="Configuration",_="Performance",r="Name",c="Pool",d="Data Pool",g="Created",f="Size",I="Objects",P="Object size",Z="Features",B="Provisioned",Q="Total provisioned",Y="Striping unit",ee="Striping count",te="Parent",w="Block name prefix",_e="Order",ae="Format Version",M="N/A",ge="N/A",ue="Information can not be displayed for RBD in status 'Removing'.",me="This setting overrides the global value",Te="Image",fe="This is the global value. No value for this option has been set for this image.",Ce="Global",[["usageNotAvailableTooltipTpl",""],[4,"ngIf"],["poolConfigurationSourceTpl",""],s,["ngbNav","","cdStatefulTab","rbd-details",1,"nav-tabs"],["nav","ngbNav"],["ngbNavItem","details"],["ngbNavLink",""],t,["ngbNavContent",""],["ngbNavItem","snapshots"],o,["ngbNavItem","configuration"],i,["ngbNavItem","performance"],_,[3,"ngbNavOutlet"],[1,"table","table-striped","table-bordered"],[1,"bold","w-25"],r,[1,"w-75"],[1,"bold"],c,d,g,f,I,P,Z,[4,"ngFor","ngForOf"],B,Q,Y,ee,te,w,_e,ae,[1,"badge","badge-dark","mr-2"],["placement","top",1,"form-text","text-muted",3,"ngbTooltip"],M,ge,[3,"snapshots","featuresName","poolName","namespace","mirroring","rbdName"],[3,"data"],["uid","YhCYGcuZz","grafanaStyle","one",3,"grafanaPath"],["type","warning"],ue,[4,"ngIf","ngIfElse"],["global",""],["ngbTooltip",me],Te,["ngbTooltip",fe],Ce]},template:function(t,o){1&t&&(e.YNc(0,P_,3,0,"ng-template",null,0,e.W1O),e.YNc(2,y_,20,1,"ng-container",1),e.YNc(3,w_,3,0,"ng-container",1),e.YNc(4,k_,3,2,"ng-template",null,2,e.W1O)),2&t&&(e.xp6(2),e.Q6J("ngIf",o.selection&&"REMOVING"!==o.selection.source),e.xp6(1),e.Q6J("ngIf",o.selection&&"REMOVING"===o.selection.source))},directives:[l.O5,N.Pz,Mt.m,N.nv,N.Vx,N.uN,N.tO,l.sg,N._L,M_,O_.P,Lt.F,Ct.G],pipes:[A_.W,Ze.N,Le.$,ot.n],styles:[""]}),n})();const X_=["usageTpl"],Q_=["parentTpl"],z_=["nameTpl"],J_=["mirroringTpl"],Y_=["flattenTpl"],V_=["deleteTpl"],U_=["removingStatTpl"],j_=["provisionedNotAvailableTooltipTpl"],W_=["totalProvisionedNotAvailableTooltipTpl"];function ea(n,s){1&n&&e._UZ(0,"div",12),2&n&&e.Q6J("innerHtml","Only available for RBD images with <strong>fast-diff</strong> enabled",e.oJD)}function ta(n,s){if(1&n&&(e.TgZ(0,"span",15),e.SDv(1,16),e.qZA()),2&n){const t=e.oxw(2);e.Q6J("ngbTooltip",t.usageNotAvailableTooltipTpl)}}function oa(n,s){if(1&n&&(e.SDv(0,17),e.ALo(1,"dimlessBinary")),2&n){const t=e.oxw().row;e.xp6(1),e.pQV(e.lcZ(1,1,t.disk_usage)),e.QtT(0)}}function na(n,s){if(1&n&&(e.YNc(0,ta,2,1,"span",13),e.YNc(1,oa,2,3,"ng-template",null,14,e.W1O)),2&n){const t=s.row,o=e.MAs(2);e.Q6J("ngIf",null===t.disk_usage&&!t.features_name.includes("fast-diff"))("ngIfElse",o)}}function ia(n,s){if(1&n&&(e.TgZ(0,"span",15),e.SDv(1,19),e.qZA()),2&n){const t=e.oxw(2);e.Q6J("ngbTooltip",t.usageNotAvailableTooltipTpl)}}function sa(n,s){if(1&n&&(e.SDv(0,20),e.ALo(1,"dimlessBinary")),2&n){const t=e.oxw().row;e.xp6(1),e.pQV(e.lcZ(1,1,t.total_disk_usage)),e.QtT(0)}}function _a(n,s){if(1&n&&(e.YNc(0,ia,2,1,"span",13),e.YNc(1,sa,2,3,"ng-template",null,18,e.W1O)),2&n){const t=s.row,o=e.MAs(2);e.Q6J("ngIf",null===t.total_disk_usage&&!t.features_name.includes("fast-diff"))("ngIfElse",o)}}function aa(n,s){if(1&n&&(e.TgZ(0,"span"),e._uU(1),e.qZA()),2&n){const t=e.oxw(2).value;e.xp6(1),e.hij("/",t.pool_namespace,"")}}function ra(n,s){if(1&n&&(e.TgZ(0,"span"),e._uU(1),e.YNc(2,aa,2,1,"span",21),e._uU(3),e.qZA()),2&n){const t=e.oxw().value;e.xp6(1),e.Oqu(t.pool_name),e.xp6(1),e.Q6J("ngIf",t.pool_namespace),e.xp6(1),e.AsE("/",t.image_name,"@",t.snap_name,"")}}function la(n,s){1&n&&(e.TgZ(0,"span"),e._uU(1,"-"),e.qZA())}function ca(n,s){if(1&n&&(e.YNc(0,ra,4,4,"span",21),e.YNc(1,la,2,0,"span",21)),2&n){const t=s.value;e.Q6J("ngIf",t),e.xp6(1),e.Q6J("ngIf",!t)}}function da(n,s){if(1&n&&(e.TgZ(0,"span",26),e._uU(1),e.qZA()),2&n){const t=e.oxw().value;e.xp6(1),e.Oqu(t[0])}}function pa(n,s){if(1&n&&(e.TgZ(0,"span",27),e.ALo(1,"cdDate"),e._uU(2),e.qZA()),2&n){const t=e.oxw().value;e.Q6J("ngbTooltip","Next scheduled snapshot on "+e.lcZ(1,2,t[2])),e.xp6(2),e.Oqu(t[1])}}function ga(n,s){1&n&&(e.TgZ(0,"span",26),e.SDv(1,28),e.qZA())}function ua(n,s){1&n&&(e.TgZ(0,"span",26),e.SDv(1,29),e.qZA())}function ma(n,s){if(1&n&&(e.TgZ(0,"span",26),e._uU(1),e.qZA()),2&n){const t=e.oxw().value;e.xp6(1),e.Oqu(t)}}function Ta(n,s){if(1&n&&(e.YNc(0,da,2,1,"span",22),e._uU(1,"\xa0 "),e.YNc(2,pa,3,4,"span",23),e.YNc(3,ga,2,0,"span",24),e.YNc(4,ua,2,0,"span",24),e.YNc(5,ma,2,1,"ng-template",null,25,e.W1O)),2&n){const t=s.value,o=s.row,i=e.MAs(6);e.Q6J("ngIf",3===t.length)("ngIfElse",i),e.xp6(2),e.Q6J("ngIf",3===t.length),e.xp6(1),e.Q6J("ngIf",!0===o.primary),e.xp6(1),e.Q6J("ngIf",!1===o.primary)}}function fa(n,s){if(1&n&&(e._uU(0," You are about to flatten "),e.TgZ(1,"strong"),e._uU(2),e.qZA(),e._uU(3,". "),e._UZ(4,"br"),e._UZ(5,"br"),e._uU(6," All blocks will be copied from parent "),e.TgZ(7,"strong"),e._uU(8),e.qZA(),e._uU(9," to child "),e.TgZ(10,"strong"),e._uU(11),e.qZA(),e._uU(12,".\n")),2&n){const t=s.$implicit;e.xp6(2),e.Oqu(t.child),e.xp6(6),e.Oqu(t.parent),e.xp6(3),e.Oqu(t.child)}}function Ca(n,s){if(1&n&&(e.TgZ(0,"li"),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.xp6(1),e.Oqu(t)}}function Sa(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"span"),e.SDv(2,33),e.qZA(),e.TgZ(3,"ul"),e.YNc(4,Ca,2,1,"li",34),e.qZA(),e.BQk()),2&n){const t=e.oxw(2).snapshots;e.xp6(4),e.Q6J("ngForOf",t)}}function Ea(n,s){if(1&n&&(e.TgZ(0,"div",31),e.TgZ(1,"span"),e.SDv(2,32),e.qZA(),e._UZ(3,"br"),e.YNc(4,Sa,5,1,"ng-container",21),e.qZA()),2&n){const t=e.oxw().snapshots;e.xp6(4),e.Q6J("ngIf",t.length>0)}}function Ra(n,s){1&n&&e.YNc(0,Ea,5,1,"div",30),2&n&&e.Q6J("ngIf",s.hasSnapshots)}const Ma=function(n,s){return[n,s]};function Oa(n,s){if(1&n&&e._UZ(0,"i",36),2&n){const t=e.oxw(2);e.Q6J("ngClass",e.WLB(1,Ma,t.icons.spinner,t.icons.spin))}}function Aa(n,s){if(1&n&&(e.TgZ(0,"span",36),e._uU(1),e.qZA()),2&n){const t=e.oxw(),o=t.column,i=t.row;e.Q6J("ngClass",null!=o&&null!=o.customTemplateConfig&&o.customTemplateConfig.executingClass?o.customTemplateConfig.executingClass:"text-muted italic"),e.xp6(1),e.hij(" (",i.cdExecuting,") ")}}function ha(n,s){if(1&n&&e._UZ(0,"i",38),2&n){const t=e.oxw(2);e.Gre("",t.icons.warning," warn")}}function Pa(n,s){if(1&n&&(e.YNc(0,Oa,1,4,"i",35),e.TgZ(1,"span",36),e._uU(2),e.qZA(),e.YNc(3,Aa,2,2,"span",35),e.YNc(4,ha,1,3,"i",37)),2&n){const t=s.column,o=s.value,i=s.row;e.Q6J("ngIf",i.cdExecuting),e.xp6(1),e.Q6J("ngClass",null==t||null==t.customTemplateConfig?null:t.customTemplateConfig.valueClass),e.xp6(1),e.hij(" ",o," "),e.xp6(1),e.Q6J("ngIf",i.cdExecuting),e.xp6(1),e.Q6J("ngIf",i.source&&"REMOVING"===i.source)}}let ba=(()=>{class n extends mt.o{constructor(t,o,i,_,r,c,d,g,f){super(),this.authStorageService=t,this.rbdService=o,this.dimlessBinaryPipe=i,this.dimlessPipe=_,this.modalService=r,this.taskWrapper=c,this.taskListService=d,this.urlBuilder=g,this.actionLabels=f,this.tableStatus=new bt.c("light"),this.selection=new Se.r,this.icons=T.P,this.count=0,this.tableContext=null,this.builders={"rbd/create":M=>this.createRbdFromTask(M.pool_name,M.namespace,M.image_name),"rbd/delete":M=>this.createRbdFromTaskImageSpec(M.image_spec),"rbd/clone":M=>this.createRbdFromTask(M.child_pool_name,M.child_namespace,M.child_image_name),"rbd/copy":M=>this.createRbdFromTask(M.dest_pool_name,M.dest_namespace,M.dest_image_name)},this.permission=this.authStorageService.getPermissions().rbdImage;const I=()=>this.selection.first()&&new L.N(this.selection.first().pool_name,this.selection.first().namespace,this.selection.first().name).toStringEncoded();this.tableActions=[{permission:"create",icon:T.P.add,routerLink:()=>this.urlBuilder.getCreate(),canBePrimary:M=>!M.hasSingleSelection,name:this.actionLabels.CREATE},{permission:"update",icon:T.P.edit,routerLink:()=>this.urlBuilder.getEdit(I()),name:this.actionLabels.EDIT,disable:M=>this.getRemovingStatusDesc(M)||this.getInvalidNameDisable(M)},{permission:"create",canBePrimary:M=>M.hasSingleSelection,disable:M=>this.getRemovingStatusDesc(M)||this.getInvalidNameDisable(M)||!!M.first().cdExecuting,icon:T.P.copy,routerLink:()=>`/block/rbd/copy/${I()}`,name:this.actionLabels.COPY},{permission:"update",disable:M=>this.getRemovingStatusDesc(M)||this.getInvalidNameDisable(M)||M.first().cdExecuting||!M.first().parent,icon:T.P.flatten,click:()=>this.flattenRbdModal(),name:this.actionLabels.FLATTEN},{permission:"update",icon:T.P.refresh,click:()=>this.resyncRbdModal(),name:this.actionLabels.RESYNC,disable:M=>this.getResyncDisableDesc(M)},{permission:"delete",icon:T.P.destroy,click:()=>this.deleteRbdModal(),name:this.actionLabels.DELETE,disable:M=>this.getDeleteDisableDesc(M)},{permission:"delete",icon:T.P.trash,click:()=>this.trashRbdModal(),name:this.actionLabels.TRASH,disable:M=>this.getRemovingStatusDesc(M)||this.getInvalidNameDisable(M)||M.first().image_format===Pe.V1},{permission:"update",icon:T.P.edit,click:()=>this.removeSchedulingModal(),name:this.actionLabels.REMOVE_SCHEDULING,disable:M=>this.getRemovingStatusDesc(M)||this.getInvalidNameDisable(M)||void 0===M.first().schedule_info},{permission:"update",icon:T.P.edit,click:()=>this.actionPrimary(!0),name:this.actionLabels.PROMOTE,visible:()=>null!=this.selection.first()&&!this.selection.first().primary},{permission:"update",icon:T.P.edit,click:()=>this.actionPrimary(!1),name:this.actionLabels.DEMOTE,visible:()=>null!=this.selection.first()&&this.selection.first().primary}]}createRbdFromTaskImageSpec(t){const o=L.N.fromString(t);return this.createRbdFromTask(o.poolName,o.namespace,o.imageName)}createRbdFromTask(t,o,i){const _=new is;return _.id="-1",_.unique_id="-1",_.name=i,_.namespace=o,_.pool_name=t,_.image_format=Pe.V2,_}ngOnInit(){this.columns=[{name:"Name",prop:"name",flexGrow:2,cellTemplate:this.removingStatTpl},{name:"Pool",prop:"pool_name",flexGrow:2},{name:"Namespace",prop:"namespace",flexGrow:2},{name:"Size",prop:"size",flexGrow:1,cellClass:"text-right",sortable:!1,pipe:this.dimlessBinaryPipe},{name:"Objects",prop:"num_objs",flexGrow:1,cellClass:"text-right",sortable:!1,pipe:this.dimlessPipe},{name:"Object size",prop:"obj_size",flexGrow:1,cellClass:"text-right",sortable:!1,pipe:this.dimlessBinaryPipe},{name:"Provisioned",prop:"disk_usage",cellClass:"text-center",flexGrow:1,pipe:this.dimlessBinaryPipe,sortable:!1,cellTemplate:this.provisionedNotAvailableTooltipTpl},{name:"Total provisioned",prop:"total_disk_usage",cellClass:"text-center",flexGrow:1,pipe:this.dimlessBinaryPipe,sortable:!1,cellTemplate:this.totalProvisionedNotAvailableTooltipTpl},{name:"Parent",prop:"parent",flexGrow:2,sortable:!1,cellTemplate:this.parentTpl},{name:"Mirroring",prop:"mirror_mode",flexGrow:3,sortable:!1,cellTemplate:this.mirroringTpl}],this.taskListService.init(i=>this.getRbdImages(i),i=>this.prepareResponse(i),i=>this.images=i,()=>this.onFetchError(),i=>["rbd/clone","rbd/copy","rbd/create","rbd/delete","rbd/edit","rbd/flatten","rbd/trash/move"].includes(i.name),(i,_)=>{let r;switch(_.name){case"rbd/copy":r=new L.N(_.metadata.dest_pool_name,_.metadata.dest_namespace,_.metadata.dest_image_name).toString();break;case"rbd/clone":r=new L.N(_.metadata.child_pool_name,_.metadata.child_namespace,_.metadata.child_image_name).toString();break;case"rbd/create":r=new L.N(_.metadata.pool_name,_.metadata.namespace,_.metadata.image_name).toString();break;default:r=_.metadata.image_spec}return r===new L.N(i.pool_name,i.namespace,i.name).toString()},this.builders)}onFetchError(){this.table.reset(),this.tableStatus=new bt.c("danger")}getRbdImages(t){var o;return null!==t&&(this.tableContext=t),null==this.tableContext&&(this.tableContext=new A.E(()=>{})),this.rbdService.list(null===(o=this.tableContext)||void 0===o?void 0:o.toParams())}prepareResponse(t){let o=[];return t.forEach(i=>{o=o.concat(i.value)}),o.forEach(i=>{if(void 0!==i.schedule_info){let _=[];const r="scheduled";let c=+new Date(i.schedule_info.schedule_time);const d=(new Date).getTimezoneOffset();c+=6e4*Math.abs(d),_.push(i.mirror_mode,r,c),i.mirror_mode=_,_=[]}}),this.count=o.length>0?n_.getCount(t[0]):0,o}updateSelection(t){this.selection=t}deleteRbdModal(){const t=this.selection.first().pool_name,o=this.selection.first().namespace,i=this.selection.first().name,_=new L.N(t,o,i);this.modalRef=this.modalService.show(pe.M,{itemDescription:"RBD",itemNames:[_],bodyTemplate:this.deleteTpl,bodyContext:{hasSnapshots:this.hasSnapshots(),snapshots:this.listProtectedSnapshots()},submitActionObservable:()=>this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/delete",{image_spec:_.toString()}),call:this.rbdService.delete(_)})})}resyncRbdModal(){const t=this.selection.first().pool_name,o=this.selection.first().namespace,i=this.selection.first().name,_=new L.N(t,o,i);this.modalRef=this.modalService.show(pe.M,{itemDescription:"RBD",itemNames:[_],actionDescription:"resync",submitActionObservable:()=>this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/edit",{image_spec:_.toString()}),call:this.rbdService.update(_,{resync:!0})})})}trashRbdModal(){const t={poolName:this.selection.first().pool_name,namespace:this.selection.first().namespace,imageName:this.selection.first().name,hasSnapshots:this.hasSnapshots()};this.modalRef=this.modalService.show(c_,t)}flattenRbd(t){this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/flatten",{image_spec:t.toString()}),call:this.rbdService.flatten(t)}).subscribe({complete:()=>{this.modalRef.close()}})}flattenRbdModal(){const t=this.selection.first().pool_name,o=this.selection.first().namespace,i=this.selection.first().name,_=this.selection.first().parent,r=new L.N(_.pool_name,_.pool_namespace,_.image_name),c=new L.N(t,o,i),d={titleText:"RBD flatten",buttonText:"Flatten",bodyTpl:this.flattenTpl,bodyData:{parent:`${r}@${_.snap_name}`,child:c.toString()},onSubmit:()=>{this.flattenRbd(c)}};this.modalRef=this.modalService.show(Nt.Y,d)}editRequest(){const t=new _t;return t.remove_scheduling=!t.remove_scheduling,t}removeSchedulingModal(){const t=this.selection.first().name,o=new L.N(this.selection.first().pool_name,this.selection.first().namespace,this.selection.first().name);this.modalRef=this.modalService.show(pe.M,{actionDescription:"remove scheduling on",itemDescription:"image",itemNames:[`${t}`],submitActionObservable:()=>new Rt.y(i=>{this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/edit",{image_spec:o.toString()}),call:this.rbdService.update(o,this.editRequest())}).subscribe({error:_=>i.error(_),complete:()=>{this.modalRef.close()}})})})}actionPrimary(t){const o=new _t;o.primary=t,o.features=null;const i=new L.N(this.selection.first().pool_name,this.selection.first().namespace,this.selection.first().name);this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/edit",{image_spec:i.toString()}),call:this.rbdService.update(i,o)}).subscribe()}hasSnapshots(){return(this.selection.first().snapshots||[]).length>0}hasClonedSnapshots(t){return(t.snapshots||[]).some(i=>i.children&&i.children.length>0)}listProtectedSnapshots(){return this.selection.first().snapshots.reduce((i,_)=>(_.is_protected&&i.push(_.name),i),[])}getDeleteDisableDesc(t){const o=t.first();return o&&this.hasClonedSnapshots(o)?"This RBD has cloned snapshots. Please delete related RBDs before deleting this RBD.":this.getInvalidNameDisable(t)||this.hasClonedSnapshots(t.first())}getResyncDisableDesc(t){const o=t.first();return o&&this.imageIsPrimary(o)?"Primary RBD images cannot be resynced":this.getInvalidNameDisable(t)}imageIsPrimary(t){return t.primary}getInvalidNameDisable(t){var o;const i=t.first();return(null===(o=null==i?void 0:i.name)||void 0===o?void 0:o.match(/[@/]/))?"This RBD image has an invalid name and can't be managed by ceph.":!t.first()||!t.hasSingleSelection}getRemovingStatusDesc(t){const o=t.first();return"REMOVING"===(null==o?void 0:o.source)&&"Action not possible for an RBD in status 'Removing'"}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(oe.j),e.Y36(q),e.Y36(Le.$),e.Y36(ot.n),e.Y36(de.Z),e.Y36(u.P),e.Y36(ce.j),e.Y36(at.F),e.Y36(v.p4))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-rbd-list"]],viewQuery:function(t,o){if(1&t&&(e.Gf(W.a,7),e.Gf(X_,5),e.Gf(Q_,7),e.Gf(z_,5),e.Gf(J_,7),e.Gf(Y_,7),e.Gf(V_,7),e.Gf(U_,7),e.Gf(j_,7),e.Gf(W_,7)),2&t){let i;e.iGM(i=e.CRH())&&(o.table=i.first),e.iGM(i=e.CRH())&&(o.usageTpl=i.first),e.iGM(i=e.CRH())&&(o.parentTpl=i.first),e.iGM(i=e.CRH())&&(o.nameTpl=i.first),e.iGM(i=e.CRH())&&(o.mirroringTpl=i.first),e.iGM(i=e.CRH())&&(o.flattenTpl=i.first),e.iGM(i=e.CRH())&&(o.deleteTpl=i.first),e.iGM(i=e.CRH())&&(o.removingStatTpl=i.first),e.iGM(i=e.CRH())&&(o.provisionedNotAvailableTooltipTpl=i.first),e.iGM(i=e.CRH())&&(o.totalProvisionedNotAvailableTooltipTpl=i.first)}},features:[e._Bn([ce.j,{provide:at.F,useValue:new at.F("block/rbd")}]),e.qOj],decls:21,vars:13,consts:function(){let s,t,o,i,_,r,c,d,g;return s="N/A",t="" + "\ufffd0\ufffd" + "",o="N/A",i="" + "\ufffd0\ufffd" + "",_="primary",r="secondary",c="Deleting this image will also delete all its snapshots.",d="The following snapshots are currently protected and will be removed:",g="RBD in status 'Removing'",[["columnMode","flex","identifier","unique_id","forceIdentifier","true","selectionType","single",3,"data","columns","searchableObjects","serverSide","count","hasDetails","status","maxLimit","autoReload","fetchData","setExpandedRow","updateSelection"],["table",""],[1,"table-actions",3,"permission","selection","tableActions"],["cdTableDetail","",3,"selection"],["scheduleStatus",""],["provisionedNotAvailableTooltipTpl",""],["totalProvisionedNotAvailableTooltipTpl",""],["parentTpl",""],["mirroringTpl",""],["flattenTpl",""],["deleteTpl",""],["removingStatTpl",""],[3,"innerHtml"],["placement","top",3,"ngbTooltip",4,"ngIf","ngIfElse"],["provisioned",""],["placement","top",3,"ngbTooltip"],s,t,["totalProvisioned",""],o,i,[4,"ngIf"],["class","badge badge-info",4,"ngIf","ngIfElse"],["class","badge badge-info",3,"ngbTooltip",4,"ngIf"],["class","badge badge-info",4,"ngIf"],["probb",""],[1,"badge","badge-info"],[1,"badge","badge-info",3,"ngbTooltip"],_,r,["class","alert alert-warning","role","alert",4,"ngIf"],["role","alert",1,"alert","alert-warning"],c,d,[4,"ngFor","ngForOf"],[3,"ngClass",4,"ngIf"],[3,"ngClass"],["title",g,3,"class",4,"ngIf"],["title",g]]},template:function(t,o){1&t&&(e._UZ(0,"cd-rbd-tabs"),e.TgZ(1,"cd-table",0,1),e.NdJ("fetchData",function(_){return o.taskListService.fetch(_)})("setExpandedRow",function(_){return o.setExpandedRow(_)})("updateSelection",function(_){return o.updateSelection(_)}),e._UZ(3,"cd-table-actions",2),e._UZ(4,"cd-rbd-details",3),e.qZA(),e.YNc(5,ea,1,1,"ng-template",null,4,e.W1O),e.YNc(7,na,3,2,"ng-template",null,5,e.W1O),e.YNc(9,_a,3,2,"ng-template",null,6,e.W1O),e.YNc(11,ca,2,2,"ng-template",null,7,e.W1O),e.YNc(13,Ta,7,5,"ng-template",null,8,e.W1O),e.YNc(15,fa,13,3,"ng-template",null,9,e.W1O),e.YNc(17,Ra,1,1,"ng-template",null,10,e.W1O),e.YNc(19,Pa,5,5,"ng-template",null,11,e.W1O)),2&t&&(e.xp6(1),e.Q6J("data",o.images)("columns",o.columns)("searchableObjects",!0)("serverSide",!0)("count",o.count)("hasDetails",!0)("status",o.tableStatus)("maxLimit",25)("autoReload",-1),e.xp6(2),e.Q6J("permission",o.permission)("selection",o.selection)("tableActions",o.tableActions),e.xp6(1),e.Q6J("selection",o.expandedRow))},directives:[We,W.a,Ee.K,K_,l.O5,N._L,l.sg,l.mk],pipes:[Le.$,Ze.N],styles:[".warn[_ngcontent-%COMP%]{color:#ffc200}"]}),n})();function Na(n,s){1&n&&e._UZ(0,"input",19)}function Fa(n,s){1&n&&(e.TgZ(0,"option",23),e.SDv(1,24),e.qZA()),2&n&&e.Q6J("ngValue",null)}function Da(n,s){1&n&&(e.TgZ(0,"option",23),e.SDv(1,25),e.qZA()),2&n&&e.Q6J("ngValue",null)}function va(n,s){1&n&&(e.TgZ(0,"option",23),e.SDv(1,26),e.qZA()),2&n&&e.Q6J("ngValue",null)}function La(n,s){if(1&n&&(e.TgZ(0,"option",27),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t.pool_name),e.xp6(1),e.Oqu(t.pool_name)}}function $a(n,s){if(1&n&&(e.TgZ(0,"select",20),e.YNc(1,Fa,2,1,"option",21),e.YNc(2,Da,2,1,"option",21),e.YNc(3,va,2,1,"option",21),e.YNc(4,La,2,2,"option",22),e.qZA()),2&n){const t=e.oxw();e.xp6(1),e.Q6J("ngIf",null===t.pools),e.xp6(1),e.Q6J("ngIf",null!==t.pools&&0===t.pools.length),e.xp6(1),e.Q6J("ngIf",null!==t.pools&&t.pools.length>0),e.xp6(1),e.Q6J("ngForOf",t.pools)}}function Za(n,s){1&n&&(e.TgZ(0,"span",28),e.SDv(1,29),e.qZA())}function Ba(n,s){1&n&&(e.TgZ(0,"span",28),e.SDv(1,30),e.qZA())}function Ga(n,s){1&n&&(e.TgZ(0,"span",28),e.SDv(1,31),e.qZA())}let xa=(()=>{class n{constructor(t,o,i,_,r,c){this.activeModal=t,this.actionLabels=o,this.authStorageService=i,this.notificationService=_,this.poolService=r,this.rbdService=c,this.pools=null,this.editing=!1,this.poolPermission=this.authStorageService.getPermissions().pool,this.createForm()}createForm(){this.namespaceForm=new y.d({pool:new a.NI(""),namespace:new a.NI("")},this.validator(),this.asyncValidator())}validator(){return t=>{const o=t.get("pool"),i=t.get("namespace");let _=null;o.value||(_={required:!0}),o.setErrors(_);let r=null;return i.value||(r={required:!0}),i.setErrors(r),null}}asyncValidator(){return t=>new Promise(o=>{const i=t.get("pool"),_=t.get("namespace");this.rbdService.listNamespaces(i.value).subscribe(r=>{if(r.some(c=>c.namespace===_.value)){const c={namespaceExists:!0};_.setErrors(c),o(c)}else o(null)})})}ngOnInit(){this.onSubmit=new vt.xQ,this.poolPermission.read&&this.poolService.list(["pool_name","type","application_metadata"]).then(t=>{const o=[];for(const i of t)this.rbdService.isRBDPool(i)&&"replicated"===i.type&&o.push(i);if(this.pools=o,1===this.pools.length){const i=this.pools[0].pool_name;this.namespaceForm.get("pool").setValue(i)}})}submit(){const t=this.namespaceForm.getValue("pool"),o=this.namespaceForm.getValue("namespace"),i=new R.R;i.name="rbd/namespace/create",i.metadata={pool:t,namespace:o},this.rbdService.createNamespace(t,o).toPromise().then(()=>{this.notificationService.show(tt.k.success,"Created namespace '" + t + "/" + o + "'"),this.activeModal.close(),this.onSubmit.next()}).catch(()=>{this.namespaceForm.setErrors({cdSubmitButton:!0})})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(N.Kz),e.Y36(v.p4),e.Y36(oe.j),e.Y36(ve.g),e.Y36(Ve.q),e.Y36(q))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-rbd-namespace-form-modal"]],decls:23,vars:9,consts:function(){let s,t,o,i,_,r,c,d,g;return s="Create Namespace",t="Pool",o="Name",i="Loading...",_="-- No rbd pools available --",r="-- Select a pool --",c="This field is required.",d="This field is required.",g="Namespace already exists.",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["name","namespaceForm","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],[1,"form-group","row"],["for","pool",1,"cd-col-form-label","required"],t,[1,"cd-col-form-input"],["class","form-control","type","text","placeholder","Pool name...","id","pool","name","pool","formControlName","pool",4,"ngIf"],["id","pool","name","pool","class","form-control","formControlName","pool",4,"ngIf"],["class","invalid-feedback",4,"ngIf"],["for","namespace",1,"cd-col-form-label","required"],o,["type","text","placeholder","Namespace name...","id","namespace","name","namespace","formControlName","namespace","autofocus","",1,"form-control"],[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],["type","text","placeholder","Pool name...","id","pool","name","pool","formControlName","pool",1,"form-control"],["id","pool","name","pool","formControlName","pool",1,"form-control"],[3,"ngValue",4,"ngIf"],[3,"value",4,"ngFor","ngForOf"],[3,"ngValue"],i,_,r,[3,"value"],[1,"invalid-feedback"],c,d,g]},template:function(t,o){if(1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.BQk(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.TgZ(7,"div",7),e.TgZ(8,"label",8),e.SDv(9,9),e.qZA(),e.TgZ(10,"div",10),e.YNc(11,Na,1,0,"input",11),e.YNc(12,$a,5,4,"select",12),e.YNc(13,Za,2,0,"span",13),e.qZA(),e.qZA(),e.TgZ(14,"div",7),e.TgZ(15,"label",14),e.SDv(16,15),e.qZA(),e.TgZ(17,"div",10),e._UZ(18,"input",16),e.YNc(19,Ba,2,0,"span",13),e.YNc(20,Ga,2,0,"span",13),e.qZA(),e.qZA(),e.qZA(),e.TgZ(21,"div",17),e.TgZ(22,"cd-form-button-panel",18),e.NdJ("submitActionEvent",function(){return o.submit()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t){const i=e.MAs(5);e.Q6J("modalRef",o.activeModal),e.xp6(4),e.Q6J("formGroup",o.namespaceForm),e.xp6(7),e.Q6J("ngIf",!o.poolPermission.read),e.xp6(1),e.Q6J("ngIf",o.poolPermission.read),e.xp6(1),e.Q6J("ngIf",o.namespaceForm.showError("pool",i,"required")),e.xp6(6),e.Q6J("ngIf",o.namespaceForm.showError("namespace",i,"required")),e.xp6(1),e.Q6J("ngIf",o.namespaceForm.showError("namespace",i,"namespaceExists")),e.xp6(2),e.Q6J("form",o.namespaceForm)("submitText",o.actionLabels.CREATE)}},directives:[C.z,a._Y,a.JL,a.sg,h.V,O.P,l.O5,$.o,a.Fj,k.b,a.JJ,a.u,Re.U,j.p,a.EJ,l.sg,a.YN,a.Kr],styles:[""]}),n})(),ya=(()=>{class n{constructor(t,o,i,_,r,c){this.authStorageService=t,this.rbdService=o,this.poolService=i,this.modalService=_,this.notificationService=r,this.actionLabels=c,this.selection=new Se.r,this.permission=this.authStorageService.getPermissions().rbdImage,this.tableActions=[{permission:"create",icon:T.P.add,click:()=>this.createModal(),name:this.actionLabels.CREATE},{permission:"delete",icon:T.P.destroy,click:()=>this.deleteModal(),name:this.actionLabels.DELETE,disable:()=>this.getDeleteDisableDesc()}]}ngOnInit(){this.columns=[{name:"Namespace",prop:"namespace",flexGrow:1},{name:"Pool",prop:"pool",flexGrow:1},{name:"Total images",prop:"num_images",flexGrow:1}],this.refresh()}refresh(){this.poolService.list(["pool_name","type","application_metadata"]).then(t=>{t=t.filter(i=>this.rbdService.isRBDPool(i)&&"replicated"===i.type);const o=[];t.forEach(i=>{o.push(this.rbdService.listNamespaces(i.pool_name))}),o.length>0?(0,le.D)(o).subscribe(i=>{const _=[];for(let r=0;r<i.length;r++){const d=t[r].pool_name;i[r].forEach(g=>{_.push({id:`${d}/${g.namespace}`,pool:d,namespace:g.namespace,num_images:g.num_images})})}this.namespaces=_}):this.namespaces=[]})}updateSelection(t){this.selection=t}createModal(){this.modalRef=this.modalService.show(xa),this.modalRef.componentInstance.onSubmit.subscribe(()=>{this.refresh()})}deleteModal(){const t=this.selection.first().pool,o=this.selection.first().namespace;this.modalRef=this.modalService.show(pe.M,{itemDescription:"Namespace",itemNames:[`${t}/${o}`],submitAction:()=>this.rbdService.deleteNamespace(t,o).subscribe(()=>{this.notificationService.show(tt.k.success,"Deleted namespace '" + t + "/" + o + "'"),this.modalRef.close(),this.refresh()},()=>{this.modalRef.componentInstance.stopLoadingSpinner()})})}getDeleteDisableDesc(){var t;const o=this.selection.first();return(null==o?void 0:o.num_images)>0?"Namespace contains images":!(null===(t=this.selection)||void 0===t?void 0:t.first())}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(oe.j),e.Y36(q),e.Y36(Ve.q),e.Y36(de.Z),e.Y36(ve.g),e.Y36(v.p4))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-rbd-namespace-list"]],features:[e._Bn([ce.j])],decls:4,vars:5,consts:[["columnMode","flex","identifier","id","forceIdentifier","true","selectionType","single",3,"data","columns","fetchData","updateSelection"],[1,"table-actions","btn-toolbar"],[1,"btn-group",3,"permission","selection","tableActions"]],template:function(t,o){1&t&&(e._UZ(0,"cd-rbd-tabs"),e.TgZ(1,"cd-table",0),e.NdJ("fetchData",function(){return o.refresh()})("updateSelection",function(_){return o.updateSelection(_)}),e.TgZ(2,"div",1),e._UZ(3,"cd-table-actions",2),e.qZA(),e.qZA()),2&t&&(e.xp6(1),e.Q6J("data",o.namespaces)("columns",o.columns),e.xp6(2),e.Q6J("permission",o.permission)("selection",o.selection)("tableActions",o.tableActions))},directives:[We,W.a,Ee.K],styles:[""]}),n})(),wa=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-rbd-performance"]],decls:2,vars:1,consts:[["uid","41FrpeUiz","grafanaStyle","two",3,"grafanaPath"]],template:function(t,o){1&t&&(e._UZ(0,"cd-rbd-tabs"),e._UZ(1,"cd-grafana",0)),2&t&&(e.xp6(1),e.Q6J("grafanaPath","rbd-overview?"))},directives:[We,Lt.F],styles:[""]}),n})();var qa=p(91801);function Ha(n,s){1&n&&e._UZ(0,"input",15)}function ka(n,s){if(1&n&&(e.TgZ(0,"option",20),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t),e.xp6(1),e.Oqu(t)}}function Ka(n,s){if(1&n&&(e.TgZ(0,"select",16),e.TgZ(1,"option",17),e.SDv(2,18),e.qZA(),e.YNc(3,ka,2,2,"option",19),e.qZA()),2&n){const t=e.oxw();e.xp6(3),e.Q6J("ngForOf",t.pools)}}let Xa=(()=>{class n{constructor(t,o,i,_,r,c,d){this.authStorageService=t,this.rbdService=o,this.activeModal=i,this.actionLabels=_,this.fb=r,this.poolService=c,this.taskWrapper=d,this.poolPermission=this.authStorageService.getPermissions().pool}createForm(){this.purgeForm=this.fb.group({poolName:""})}ngOnInit(){this.poolPermission.read&&this.poolService.list(["pool_name","application_metadata"]).then(t=>{this.pools=t.filter(o=>o.application_metadata.includes("rbd")).map(o=>o.pool_name)}),this.createForm()}purge(){const t=this.purgeForm.getValue("poolName")||"";this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/trash/purge",{pool_name:t}),call:this.rbdService.purgeTrash(t)}).subscribe({error:()=>{this.purgeForm.setErrors({cdSubmitButton:!0})},complete:()=>{this.activeModal.close()}})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(oe.j),e.Y36(q),e.Y36(N.Kz),e.Y36(v.p4),e.Y36(rt.O),e.Y36(Ve.q),e.Y36(u.P))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-rbd-trash-purge-modal"]],decls:18,vars:6,consts:function(){let s,t,o,i,_;return s="Purge Trash",t="To purge, select\xA0 " + "[\ufffd#9\ufffd|\ufffd#10\ufffd]" + "All" + "[\ufffd/#9\ufffd|\ufffd/#10\ufffd]" + "\xA0 or one pool and click\xA0 " + "[\ufffd#9\ufffd|\ufffd#10\ufffd]" + "Purge" + "[\ufffd/#9\ufffd|\ufffd/#10\ufffd]" + ".\xA0",t=e.Zx4(t),o="Pool:",i="Pool name...",_="All",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["name","purgeForm","novalidate","",1,"form",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],t,[1,"form-group"],[1,"col-form-label","mx-auto"],o,["class","form-control","type","text","placeholder",i,"formControlName","poolName",4,"ngIf"],["id","poolName","name","poolName","class","form-control","formControlName","poolName",4,"ngIf"],[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],["type","text","placeholder",i,"formControlName","poolName",1,"form-control"],["id","poolName","name","poolName","formControlName","poolName",1,"form-control"],["value",""],_,[3,"value",4,"ngFor","ngForOf"],[3,"value"]]},template:function(t,o){1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.BQk(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.TgZ(7,"p"),e.tHW(8,7),e._UZ(9,"kbd"),e._UZ(10,"kbd"),e.N_p(),e.qZA(),e.TgZ(11,"div",8),e.TgZ(12,"label",9),e.SDv(13,10),e.qZA(),e.YNc(14,Ha,1,0,"input",11),e.YNc(15,Ka,4,1,"select",12),e.qZA(),e.qZA(),e.TgZ(16,"div",13),e.TgZ(17,"cd-form-button-panel",14),e.NdJ("submitActionEvent",function(){return o.purge()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t&&(e.Q6J("modalRef",o.activeModal),e.xp6(4),e.Q6J("formGroup",o.purgeForm),e.xp6(10),e.Q6J("ngIf",!o.poolPermission.read),e.xp6(1),e.Q6J("ngIf",o.poolPermission.read),e.xp6(2),e.Q6J("form",o.purgeForm)("submitText",o.actionLabels.PURGE))},directives:[C.z,a._Y,a.JL,a.sg,h.V,O.P,l.O5,j.p,$.o,a.Fj,k.b,a.JJ,a.u,a.EJ,a.YN,a.Kr,l.sg],styles:[""]}),n})();function Qa(n,s){1&n&&(e.TgZ(0,"span",15),e.SDv(1,16),e.qZA())}let za=(()=>{class n{constructor(t,o,i,_,r){this.rbdService=t,this.activeModal=o,this.actionLabels=i,this.fb=_,this.taskWrapper=r}ngOnInit(){this.imageSpec=new L.N(this.poolName,this.namespace,this.imageName).toString(),this.restoreForm=this.fb.group({name:this.imageName})}restore(){const t=this.restoreForm.getValue("name"),o=new L.N(this.poolName,this.namespace,this.imageId);this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/trash/restore",{image_id_spec:o.toString(),new_image_name:t}),call:this.rbdService.restoreTrash(o,t)}).subscribe({error:()=>{this.restoreForm.setErrors({cdSubmitButton:!0})},complete:()=>{this.activeModal.close()}})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(q),e.Y36(N.Kz),e.Y36(v.p4),e.Y36(rt.O),e.Y36(u.P))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-rbd-trash-restore-modal"]],decls:18,vars:7,consts:function(){let s,t,o,i;return s="Restore Image",t="To restore\xA0 " + "[\ufffd#9\ufffd|\ufffd#10\ufffd]" + "" + "\ufffd0\ufffd" + "@" + "\ufffd1\ufffd" + "" + "[\ufffd/#9\ufffd|\ufffd/#10\ufffd]" + ",\xA0 type the image's new name and click\xA0 " + "[\ufffd#9\ufffd|\ufffd#10\ufffd]" + "Restore" + "[\ufffd/#9\ufffd|\ufffd/#10\ufffd]" + ".",t=e.Zx4(t),o="New Name",i="This field is required.",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["name","restoreForm","novalidate","",1,"form",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],t,[1,"form-group"],["for","name",1,"col-form-label"],o,["type","text","name","name","id","name","autocomplete","off","formControlName","name","autofocus","",1,"form-control"],["class","invalid-feedback",4,"ngIf"],[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],[1,"invalid-feedback"],i]},template:function(t,o){if(1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.BQk(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.TgZ(7,"p"),e.tHW(8,7),e._UZ(9,"kbd"),e._UZ(10,"kbd"),e.N_p(),e.qZA(),e.TgZ(11,"div",8),e.TgZ(12,"label",9),e.SDv(13,10),e.qZA(),e._UZ(14,"input",11),e.YNc(15,Qa,2,0,"span",12),e.qZA(),e.qZA(),e.TgZ(16,"div",13),e.TgZ(17,"cd-form-button-panel",14),e.NdJ("submitActionEvent",function(){return o.restore()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t){const i=e.MAs(5);e.Q6J("modalRef",o.activeModal),e.xp6(4),e.Q6J("formGroup",o.restoreForm),e.xp6(6),e.pQV(o.imageSpec)(o.imageId),e.QtT(8),e.xp6(5),e.Q6J("ngIf",o.restoreForm.showError("name",i,"required")),e.xp6(2),e.Q6J("form",o.restoreForm)("submitText",o.actionLabels.RESTORE)}},directives:[C.z,a._Y,a.JL,a.sg,h.V,O.P,$.o,a.Fj,k.b,a.JJ,a.u,Re.U,l.O5,j.p],styles:[""]}),n})();const Ja=["expiresTpl"],Ya=["deleteTpl"],Va=function(n){return[n]};function Ua(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"button",6),e.NdJ("click",function(){return e.CHM(t),e.oxw().purgeModal()}),e._UZ(1,"i",7),e.ynx(2),e.SDv(3,8),e.BQk(),e.qZA()}if(2&n){const t=e.oxw();e.Q6J("disabled",t.disablePurgeBtn),e.xp6(1),e.Q6J("ngClass",e.VKq(2,Va,t.icons.destroy))}}function ja(n,s){1&n&&(e.ynx(0),e.SDv(1,10),e.BQk())}function Wa(n,s){1&n&&(e.ynx(0),e.SDv(1,11),e.BQk())}function er(n,s){if(1&n&&(e.YNc(0,ja,2,0,"ng-container",9),e.YNc(1,Wa,2,0,"ng-container",9),e._uU(2),e.ALo(3,"cdDate")),2&n){const t=s.row,o=s.value;e.Q6J("ngIf",t.cdIsExpired),e.xp6(1),e.Q6J("ngIf",!t.cdIsExpired),e.xp6(1),e.hij(" ",e.lcZ(3,3,o),"\n")}}function tr(n,s){if(1&n&&(e.TgZ(0,"p",13),e.TgZ(1,"strong"),e.ynx(2),e.SDv(3,14),e.ALo(4,"cdDate"),e.BQk(),e.qZA(),e.qZA()),2&n){const t=e.oxw().expiresAt;e.xp6(4),e.pQV(e.lcZ(4,1,t)),e.QtT(3)}}function or(n,s){1&n&&e.YNc(0,tr,5,3,"p",12),2&n&&e.Q6J("ngIf",!s.isExpired)}let nr=(()=>{class n{constructor(t,o,i,_,r,c,d){this.authStorageService=t,this.rbdService=o,this.modalService=i,this.cdDatePipe=_,this.taskListService=r,this.taskWrapper=c,this.actionLabels=d,this.icons=T.P,this.executingTasks=[],this.selection=new Se.r,this.tableStatus=new se.E,this.disablePurgeBtn=!0,this.permission=this.authStorageService.getPermissions().rbdImage,this.tableActions=[{permission:"update",icon:T.P.undo,click:()=>this.restoreModal(),name:this.actionLabels.RESTORE},{permission:"delete",icon:T.P.destroy,click:()=>this.deleteModal(),name:this.actionLabels.DELETE}]}ngOnInit(){this.columns=[{name:"ID",prop:"id",flexGrow:1,cellTransformation:De.e.executing},{name:"Name",prop:"name",flexGrow:1},{name:"Pool",prop:"pool_name",flexGrow:1},{name:"Namespace",prop:"namespace",flexGrow:1},{name:"Status",prop:"deferment_end_time",flexGrow:1,cellTemplate:this.expiresTpl},{name:"Deleted At",prop:"deletion_time",flexGrow:1,pipe:this.cdDatePipe}],this.taskListService.init(()=>this.rbdService.listTrash(),i=>this.prepareResponse(i),i=>this.images=i,()=>this.onFetchError(),i=>["rbd/trash/remove","rbd/trash/restore"].includes(i.name),(i,_)=>new L.N(i.pool_name,i.namespace,i.id).toString()===_.metadata.image_id_spec,void 0)}prepareResponse(t){let o=[];const i={};let _;if(t.forEach(r=>{S().isUndefined(i[r.status])&&(i[r.status]=[]),i[r.status].push(r.pool_name),o=o.concat(r.value),this.disablePurgeBtn=!o.length}),i[3]?_=3:i[1]?_=1:i[2]&&(_=2),_){const r=(i[_].length>1?"pools ":"pool ")+i[_].join();this.tableStatus=new se.E(_,r)}else this.tableStatus=new se.E;return o.forEach(r=>{r.cdIsExpired=Me()().isAfter(r.deferment_end_time)}),o}onFetchError(){this.table.reset(),this.tableStatus=new se.E(qa.T.ValueException)}updateSelection(t){this.selection=t}restoreModal(){const t={poolName:this.selection.first().pool_name,namespace:this.selection.first().namespace,imageName:this.selection.first().name,imageId:this.selection.first().id};this.modalRef=this.modalService.show(za,t)}deleteModal(){const t=this.selection.first().pool_name,o=this.selection.first().namespace,i=this.selection.first().id,_=this.selection.first().deferment_end_time,r=Me()().isAfter(_),c=new L.N(t,o,i);this.modalRef=this.modalService.show(pe.M,{itemDescription:"RBD",itemNames:[c],bodyTemplate:this.deleteTpl,bodyContext:{expiresAt:_,isExpired:r},submitActionObservable:()=>this.taskWrapper.wrapTaskAroundCall({task:new R.R("rbd/trash/remove",{image_id_spec:c.toString()}),call:this.rbdService.removeTrash(c,!0)})})}purgeModal(){this.modalService.show(Xa)}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(oe.j),e.Y36(q),e.Y36(de.Z),e.Y36(Ze.N),e.Y36(ce.j),e.Y36(u.P),e.Y36(v.p4))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-rbd-trash-list"]],viewQuery:function(t,o){if(1&t&&(e.Gf(W.a,7),e.Gf(Ja,7),e.Gf(Ya,7)),2&t){let i;e.iGM(i=e.CRH())&&(o.table=i.first),e.iGM(i=e.CRH())&&(o.expiresTpl=i.first),e.iGM(i=e.CRH())&&(o.deleteTpl=i.first)}},features:[e._Bn([ce.j])],decls:9,vars:8,consts:function(){let s,t,o,i;return s="Purge Trash",t="Expired at",o="Protected until",i="This image is protected until " + "\ufffd0\ufffd" + ".",[["columnMode","flex","identifier","id","forceIdentifier","true","selectionType","single",3,"data","columns","status","autoReload","fetchData","updateSelection"],[1,"table-actions","btn-toolbar"],[1,"btn-group",3,"permission","selection","tableActions"],["class","btn btn-light","type","button",3,"disabled","click",4,"ngIf"],["expiresTpl",""],["deleteTpl",""],["type","button",1,"btn","btn-light",3,"disabled","click"],["aria-hidden","true",3,"ngClass"],s,[4,"ngIf"],t,o,["class","text-danger",4,"ngIf"],[1,"text-danger"],i]},template:function(t,o){1&t&&(e._UZ(0,"cd-rbd-tabs"),e.TgZ(1,"cd-table",0),e.NdJ("fetchData",function(){return o.taskListService.fetch()})("updateSelection",function(_){return o.updateSelection(_)}),e.TgZ(2,"div",1),e._UZ(3,"cd-table-actions",2),e.YNc(4,Ua,4,4,"button",3),e.qZA(),e.qZA(),e.YNc(5,er,4,5,"ng-template",null,4,e.W1O),e.YNc(7,or,1,1,"ng-template",null,5,e.W1O)),2&t&&(e.xp6(1),e.Q6J("data",o.images)("columns",o.columns)("status",o.tableStatus)("autoReload",-1),e.xp6(2),e.Q6J("permission",o.permission)("selection",o.selection)("tableActions",o.tableActions),e.xp6(1),e.Q6J("ngIf",o.permission.delete))},directives:[We,W.a,Ee.K,l.O5,$.o,l.mk],pipes:[Ze.N],styles:[""]}),n})(),$t=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275mod=e.oAB({type:n}),n.\u0275inj=e.cJS({imports:[[l.ez,ni,a.u5,a.UX,N.Oz,N.dT,N.HK,Ie.b,Ae.m,m.Bz,ne.xc]]}),n})();const ir=[{path:"",redirectTo:"rbd",pathMatch:"full"},{path:"rbd",canActivate:[U.T,re.P],data:{moduleStatusGuardConfig:{uiApiPath:"block/rbd",redirectTo:"error",header:"No RBD pools available",button_name:"Create RBD pool",button_route:"/pool/create"},breadcrumbs:"Images"},children:[{path:"",component:ba},{path:"namespaces",component:ya,data:{breadcrumbs:"Namespaces"}},{path:"trash",component:nr,data:{breadcrumbs:"Trash"}},{path:"performance",component:wa,data:{breadcrumbs:"Overall Performance"}},{path:v.MQ.CREATE,component:$e,data:{breadcrumbs:v.Qn.CREATE}},{path:`${v.MQ.EDIT}/:image_spec`,component:$e,data:{breadcrumbs:v.Qn.EDIT}},{path:`${v.MQ.CLONE}/:image_spec/:snap`,component:$e,data:{breadcrumbs:v.Qn.CLONE}},{path:`${v.MQ.COPY}/:image_spec`,component:$e,data:{breadcrumbs:v.Qn.COPY}},{path:`${v.MQ.COPY}/:image_spec/:snap`,component:$e,data:{breadcrumbs:v.Qn.COPY}}]},{path:"mirroring",component:Vi,canActivate:[U.T,re.P],data:{moduleStatusGuardConfig:{uiApiPath:"block/mirroring",redirectTo:"error",header:"RBD mirroring is not configured",button_name:"Configure RBD Mirroring",button_title:"This will create rbd-mirror service and a replicated RBD pool",component:"RBD Mirroring",uiConfig:!0},breadcrumbs:"Mirroring"},children:[{path:`${v.MQ.EDIT}/:pool_name`,component:es,outlet:"modal"}]},{path:"iscsi",canActivate:[U.T],data:{breadcrumbs:"iSCSI"},children:[{path:"",redirectTo:"overview",pathMatch:"full"},{path:"overview",component:oi,data:{breadcrumbs:"Overview"}},{path:"targets",data:{breadcrumbs:"Targets"},children:[{path:"",component:qn},{path:v.MQ.CREATE,component:ut,data:{breadcrumbs:v.Qn.CREATE}},{path:`${v.MQ.EDIT}/:target_iqn`,component:ut,data:{breadcrumbs:v.Qn.EDIT}}]}]}];let sr=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275mod=e.oAB({type:n}),n.\u0275inj=e.cJS({imports:[[$t,m.Bz.forChild(ir)]]}),n})()},54555:(ct,Oe,p)=>{p.d(Oe,{d:()=>z});var l=p(74788),a=p(24751),m=p(23815),ne=p.n(m),N=p(80226),Ie=p(65862),v=p(95463),U=p(30633),re=p(28211),Ae=p(34089),be=p(41582),S=p(12057),le=p(56310),D=p(18372),ie=p(87925),V=p(94276);let e=(()=>{class A{constructor(u,C){this.control=u,this.formatter=C}setValue(u){const C=this.formatter.toMilliseconds(u);this.control.control.setValue(`${C} ms`)}ngOnInit(){this.setValue(this.control.value),this.ngDataReady&&this.ngDataReady.subscribe(()=>this.setValue(this.control.value))}onUpdate(u){this.setValue(u)}}return A.\u0275fac=function(u){return new(u||A)(l.Y36(a.a5),l.Y36(re.H))},A.\u0275dir=l.lG2({type:A,selectors:[["","cdMilliseconds",""]],hostBindings:function(u,C){1&u&&l.NdJ("blur",function(O){return C.onUpdate(O.target.value)})},inputs:{ngDataReady:"ngDataReady"}}),A})();var X=p(20044);let Ne=(()=>{class A{constructor(u,C,h,O){this.elementRef=u,this.control=C,this.dimlessBinaryPerSecondPipe=h,this.formatter=O,this.ngModelChange=new l.vpe,this.el=this.elementRef.nativeElement}ngOnInit(){this.setValue(this.el.value),this.ngDataReady&&this.ngDataReady.subscribe(()=>this.setValue(this.el.value))}setValue(u){/^[\d.]+$/.test(u)&&(u+=this.defaultUnit||"m");const C=this.formatter.toBytes(u,0),h=this.round(C);this.el.value=this.dimlessBinaryPerSecondPipe.transform(h),null!==C?(this.ngModelChange.emit(this.el.value),this.control.control.setValue(this.el.value)):(this.ngModelChange.emit(null),this.control.control.setValue(null))}round(u){if(null!==u&&0!==u){if(!ne().isUndefined(this.minBytes)&&u<this.minBytes)return this.minBytes;if(!ne().isUndefined(this.maxBytes)&&u>this.maxBytes)return this.maxBytes;if(!ne().isUndefined(this.roundPower)){const C=Math.round(Math.log(u)/Math.log(this.roundPower));return Math.pow(this.roundPower,C)}}return u}onBlur(u){this.setValue(u)}}return A.\u0275fac=function(u){return new(u||A)(l.Y36(l.SBq),l.Y36(a.a5),l.Y36(X.O),l.Y36(re.H))},A.\u0275dir=l.lG2({type:A,selectors:[["","cdDimlessBinaryPerSecond",""]],hostBindings:function(u,C){1&u&&l.NdJ("blur",function(O){return C.onBlur(O.target.value)})},inputs:{ngDataReady:"ngDataReady",minBytes:"minBytes",maxBytes:"maxBytes",roundPower:"roundPower",defaultUnit:"defaultUnit"},outputs:{ngModelChange:"ngModelChange"}}),A})(),Fe=(()=>{class A{constructor(u,C){this.formatter=u,this.ngControl=C}setValue(u){const C=this.formatter.toIops(u);this.ngControl.control.setValue(`${C} IOPS`)}ngOnInit(){this.setValue(this.ngControl.value),this.ngDataReady&&this.ngDataReady.subscribe(()=>this.setValue(this.ngControl.value))}onUpdate(u){this.setValue(u)}}return A.\u0275fac=function(u){return new(u||A)(l.Y36(re.H),l.Y36(a.a5))},A.\u0275dir=l.lG2({type:A,selectors:[["","cdIops",""]],hostBindings:function(u,C){1&u&&l.NdJ("blur",function(O){return C.onUpdate(O.target.value)})},inputs:{ngDataReady:"ngDataReady"}}),A})();function L(A,R){if(1&A&&(l.ynx(0),l._UZ(1,"input",18),l.BQk()),2&A){const u=l.oxw().$implicit,C=l.oxw(2);l.xp6(1),l.Q6J("id",u.name)("name",u.name)("formControlName",u.name)("ngDataReady",C.ngDataReady)}}function he(A,R){if(1&A&&(l.ynx(0),l._UZ(1,"input",19),l.BQk()),2&A){const u=l.oxw().$implicit,C=l.oxw(2);l.xp6(1),l.Q6J("id",u.name)("name",u.name)("formControlName",u.name)("ngDataReady",C.ngDataReady)}}function q(A,R){if(1&A&&(l.ynx(0),l._UZ(1,"input",20),l.BQk()),2&A){const u=l.oxw().$implicit,C=l.oxw(2);l.xp6(1),l.Q6J("id",u.name)("name",u.name)("formControlName",u.name)("ngDataReady",C.ngDataReady)}}function F(A,R){1&A&&(l.TgZ(0,"span",21),l.SDv(1,22),l.qZA())}const x=function(A){return{active:A}},T=function(A){return[A]};function H(A,R){if(1&A){const u=l.EpF();l.TgZ(0,"div",10),l.TgZ(1,"label",11),l._uU(2),l.TgZ(3,"cd-helper"),l._uU(4),l.qZA(),l.qZA(),l.TgZ(5,"div"),l.TgZ(6,"div",12),l.ynx(7,13),l.YNc(8,L,2,4,"ng-container",14),l.YNc(9,he,2,4,"ng-container",14),l.YNc(10,q,2,4,"ng-container",14),l.BQk(),l.TgZ(11,"span",15),l.TgZ(12,"button",16),l.NdJ("click",function(){const O=l.CHM(u).$implicit;return l.oxw(2).reset(O.name)}),l._UZ(13,"i",7),l.qZA(),l.qZA(),l.qZA(),l.YNc(14,F,2,0,"span",17),l.qZA(),l.qZA()}if(2&A){const u=R.$implicit,C=l.oxw().$implicit,h=l.oxw(),O=l.MAs(1);l.xp6(1),l.Q6J("for",u.name),l.xp6(1),l.Oqu(u.displayName),l.xp6(2),l.Oqu(u.description),l.xp6(1),l.Gre("cd-col-form-input ",C.heading,""),l.xp6(2),l.Q6J("ngSwitch",u.type),l.xp6(1),l.Q6J("ngSwitchCase",h.configurationType.milliseconds),l.xp6(1),l.Q6J("ngSwitchCase",h.configurationType.bps),l.xp6(1),l.Q6J("ngSwitchCase",h.configurationType.iops),l.xp6(2),l.Q6J("ngClass",l.VKq(13,x,h.isDisabled(u.name))),l.xp6(1),l.Q6J("ngClass",l.VKq(15,T,h.icons.erase)),l.xp6(1),l.Q6J("ngIf",h.form.showError("configuration."+u.name,O,"min"))}}function y(A,R){if(1&A){const u=l.EpF();l.TgZ(0,"div",4),l.TgZ(1,"h4",5),l.TgZ(2,"span",6),l.NdJ("click",function(){const O=l.CHM(u).$implicit;return l.oxw().toggleSectionVisibility(O.class)}),l._uU(3),l._UZ(4,"i",7),l.qZA(),l.qZA(),l.TgZ(5,"div",8),l.YNc(6,H,15,17,"div",9),l.qZA(),l.qZA()}if(2&A){const u=R.$implicit,C=l.oxw();l.xp6(3),l.hij(" ",u.heading," "),l.xp6(1),l.Q6J("ngClass",C.sectionVisibility[u.class]?C.icons.minusCircle:C.icons.addCircle),l.xp6(1),l.Tol(u.class),l.Q6J("hidden",!C.sectionVisibility[u.class]),l.xp6(1),l.Q6J("ngForOf",u.options)}}let z=(()=>{class A{constructor(u,C){this.formatterService=u,this.rbdConfigurationService=C,this.initializeData=new N.t(1),this.changes=new l.vpe,this.icons=Ie.P,this.ngDataReady=new l.vpe,this.configurationType=U.r,this.sectionVisibility={}}ngOnInit(){const u=this.createConfigurationFormGroup();this.form.addControl("configuration",u),u.valueChanges.subscribe(()=>{this.changes.emit(this.getDirtyValues.bind(this))}),this.initializeData&&this.initializeData.subscribe(C=>{this.initialData=C.initialData;const h=C.sourceType;this.rbdConfigurationService.getWritableOptionFields().forEach(O=>{const $=C.initialData.filter(k=>k.name===O.name).pop();$&&$.source===h&&this.form.get(`configuration.${O.name}`).setValue($.value)}),this.ngDataReady.emit()}),this.rbdConfigurationService.getWritableSections().forEach(C=>this.sectionVisibility[C.class]=!1)}getDirtyValues(u=!1,C){if(u&&!C)throw new Error("ProgrammingError: If local values shall be included, a proper localFieldType argument has to be provided, too");const h={};return this.rbdConfigurationService.getWritableOptionFields().forEach(O=>{const $=this.form.get("configuration").get(O.name);this.initialData&&this.initialData[O.name]===$.value||($.dirty||u&&$.source===C)&&(h[O.name]=null===$.value?$.value:O.type===U.r.bps?this.formatterService.toBytes($.value):O.type===U.r.milliseconds?this.formatterService.toMilliseconds($.value):O.type===U.r.iops?this.formatterService.toIops($.value):$.value)}),h}createConfigurationFormGroup(){const u=new v.d({});return this.rbdConfigurationService.getWritableOptionFields().forEach(C=>{let h;if(C.type!==U.r.milliseconds&&C.type!==U.r.iops&&C.type!==U.r.bps)throw new Error(`Type ${C.type} is unknown, you may need to add it to RbdConfiguration class`);{let O=0;ne().forEach(this.initialData,$=>{$.name===C.name&&(O=$.value)}),h=new a.NI(O,a.kI.min(0))}u.addControl(C.name,h)}),u}reset(u){const C=this.form.get("configuration").get(u);C.disabled?(C.setValue(C.previousValue||0),C.enable(),C.previousValue||C.markAsPristine()):(C.previousValue=C.value,C.setValue(null),C.markAsDirty(),C.disable())}isDisabled(u){return this.form.get("configuration").get(u).disabled}toggleSectionVisibility(u){this.sectionVisibility[u]=!this.sectionVisibility[u]}}return A.\u0275fac=function(u){return new(u||A)(l.Y36(re.H),l.Y36(Ae.n))},A.\u0275cmp=l.Xpm({type:A,selectors:[["cd-rbd-configuration-form"]],inputs:{form:"form",initializeData:"initializeData"},outputs:{changes:"changes"},decls:5,vars:2,consts:function(){let R,u,C;return R="RBD Configuration",u="Remove the local configuration value. The parent configuration value will be inherited and used instead.",C="The minimum value is 0",[[3,"formGroup"],["cfgFormGroup",""],R,["class","col-12",4,"ngFor","ngForOf"],[1,"col-12"],[1,"cd-header"],[1,"collapsible",3,"click"],["aria-hidden","true",3,"ngClass"],[3,"hidden"],["class","form-group row",4,"ngFor","ngForOf"],[1,"form-group","row"],[1,"cd-col-form-label",3,"for"],[1,"input-group"],[3,"ngSwitch"],[4,"ngSwitchCase"],[1,"input-group-append"],["type","button","data-toggle","button","title",u,1,"btn","btn-light",3,"ngClass","click"],["class","invalid-feedback",4,"ngIf"],["type","text","cdMilliseconds","",1,"form-control",3,"id","name","formControlName","ngDataReady"],["type","text","defaultUnit","b","cdDimlessBinaryPerSecond","",1,"form-control",3,"id","name","formControlName","ngDataReady"],["type","text","cdIops","",1,"form-control",3,"id","name","formControlName","ngDataReady"],[1,"invalid-feedback"],C]},template:function(u,C){1&u&&(l.TgZ(0,"fieldset",0,1),l.TgZ(2,"legend"),l.SDv(3,2),l.qZA(),l.YNc(4,y,7,7,"div",3),l.qZA()),2&u&&(l.Q6J("formGroup",C.form.get("configuration")),l.xp6(4),l.Q6J("ngForOf",C.rbdConfigurationService.sections))},directives:[a.JL,a.sg,be.V,S.sg,S.mk,le.P,D.S,S.RF,S.n9,ie.o,S.O5,a.Fj,V.b,e,a.JJ,a.u,Ne,Fe],styles:[".collapsible[_ngcontent-%COMP%]{cursor:pointer;user-select:none}"]}),A})()},71752:(ct,Oe,p)=>{p.d(Oe,{P:()=>q});var l=p(35905),a=p(30633),m=p(74788);let ne=(()=>{class F{transform(T){return{0:"global",1:"pool",2:"image"}[T]}}return F.\u0275fac=function(T){return new(T||F)},F.\u0275pipe=m.Yjl({name:"rbdConfigurationSource",type:F,pure:!0}),F})();var N=p(28211),Ie=p(34089),v=p(12057),U=p(20044),re=p(48537),Ae=p(21766);const be=["configurationSourceTpl"],S=["configurationValueTpl"],le=["poolConfTable"];function D(F,x){1&F&&(m.TgZ(0,"span"),m.SDv(1,6),m.qZA())}function ie(F,x){1&F&&(m.TgZ(0,"strong"),m.SDv(1,7),m.qZA())}function V(F,x){1&F&&(m.TgZ(0,"strong"),m.SDv(1,8),m.qZA())}function e(F,x){1&F&&(m.TgZ(0,"div",4),m.YNc(1,D,2,0,"span",5),m.YNc(2,ie,2,0,"strong",5),m.YNc(3,V,2,0,"strong",5),m.qZA()),2&F&&(m.Q6J("ngSwitch",x.value),m.xp6(1),m.Q6J("ngSwitchCase","global"),m.xp6(1),m.Q6J("ngSwitchCase","image"),m.xp6(1),m.Q6J("ngSwitchCase","pool"))}function X(F,x){if(1&F&&(m.TgZ(0,"span"),m._uU(1),m.ALo(2,"dimlessBinaryPerSecond"),m.qZA()),2&F){const T=m.oxw().value;m.xp6(1),m.Oqu(m.lcZ(2,1,T))}}function Ne(F,x){if(1&F&&(m.TgZ(0,"span"),m._uU(1),m.ALo(2,"milliseconds"),m.qZA()),2&F){const T=m.oxw().value;m.xp6(1),m.Oqu(m.lcZ(2,1,T))}}function Fe(F,x){if(1&F&&(m.TgZ(0,"span"),m._uU(1),m.ALo(2,"iops"),m.qZA()),2&F){const T=m.oxw().value;m.xp6(1),m.Oqu(m.lcZ(2,1,T))}}function L(F,x){if(1&F&&(m.TgZ(0,"span"),m._uU(1),m.qZA()),2&F){const T=m.oxw().value;m.xp6(1),m.Oqu(T)}}function he(F,x){if(1&F&&(m.TgZ(0,"div",4),m.YNc(1,X,3,3,"span",5),m.YNc(2,Ne,3,3,"span",5),m.YNc(3,Fe,3,3,"span",5),m.YNc(4,L,2,1,"span",9),m.qZA()),2&F){const T=x.row,H=m.oxw();m.Q6J("ngSwitch",T.type),m.xp6(1),m.Q6J("ngSwitchCase",H.typeField.bps),m.xp6(1),m.Q6J("ngSwitchCase",H.typeField.milliseconds),m.xp6(1),m.Q6J("ngSwitchCase",H.typeField.iops)}}let q=(()=>{class F{constructor(T,H){this.formatterService=T,this.rbdConfigurationService=H,this.sourceField=a.h,this.typeField=a.r}ngOnInit(){this.poolConfigurationColumns=[{prop:"displayName",name:"Name"},{prop:"description",name:"Description"},{prop:"name",name:"Key"},{prop:"source",name:"Source",cellTemplate:this.configurationSourceTpl,pipe:new ne},{prop:"value",name:"Value",cellTemplate:this.configurationValueTpl}]}ngOnChanges(){!this.data||(this.data=this.data.filter(T=>this.rbdConfigurationService.getOptionFields().map(H=>H.name).includes(T.name)))}}return F.\u0275fac=function(T){return new(T||F)(m.Y36(N.H),m.Y36(Ie.n))},F.\u0275cmp=m.Xpm({type:F,selectors:[["cd-rbd-configuration-table"]],viewQuery:function(T,H){if(1&T&&(m.Gf(be,7),m.Gf(S,7),m.Gf(le,7)),2&T){let y;m.iGM(y=m.CRH())&&(H.configurationSourceTpl=y.first),m.iGM(y=m.CRH())&&(H.configurationValueTpl=y.first),m.iGM(y=m.CRH())&&(H.poolConfTable=y.first)}},inputs:{data:"data"},features:[m.TTD],decls:6,vars:2,consts:function(){let x,T,H;return x="Global",T="Image",H="Pool",[["identifier","name",3,"data","columns"],["poolConfTable",""],["configurationSourceTpl",""],["configurationValueTpl",""],[3,"ngSwitch"],[4,"ngSwitchCase"],x,T,H,[4,"ngSwitchDefault"]]},template:function(T,H){1&T&&(m._UZ(0,"cd-table",0,1),m.YNc(2,e,4,4,"ng-template",null,2,m.W1O),m.YNc(4,he,5,4,"ng-template",null,3,m.W1O)),2&T&&m.Q6J("data",H.data)("columns",H.poolConfigurationColumns)},directives:[l.a,v.RF,v.n9,v.ED],pipes:[U.O,re.J,Ae.A],styles:[""]}),F})()}}]); \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/Ceph_Logo.487a0001b327fa7f5232.svg b/src/pybind/mgr/dashboard/frontend/dist/en-US/Ceph_Logo.487a0001b327fa7f5232.svg
new file mode 100644
index 000000000..9426c300d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/Ceph_Logo.487a0001b327fa7f5232.svg
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="Ceph_Logo.svg"
+ inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
+ id="svg27"
+ version="1.1"
+ viewBox="0 0 22.93428 22.4424"
+ height="22.4424mm"
+ width="22.93428mm">
+ <defs
+ id="defs21">
+ <color-profile
+ xlink:href="file:///usr/share/color/icc/krita/sRGB-elle-V2-g10.icc"
+ name="sRGB-elle-V2-g10.icc"
+ id="color-profile35" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-maximized="1"
+ inkscape:window-y="1080"
+ inkscape:window-x="3840"
+ inkscape:window-height="1051"
+ inkscape:window-width="1920"
+ fit-margin-bottom="0"
+ fit-margin-right="0"
+ fit-margin-left="0"
+ fit-margin-top="0"
+ showgrid="false"
+ inkscape:document-rotation="0"
+ inkscape:current-layer="layer1"
+ inkscape:document-units="mm"
+ inkscape:cy="39.499381"
+ inkscape:cx="29.58201"
+ inkscape:zoom="5.6"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base" />
+ <metadata
+ id="metadata24">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ transform="translate(-111.75311,-212.54075)"
+ id="layer1"
+ inkscape:groupmode="layer"
+ inkscape:label="Ebene 1">
+ <path
+ style="fill:#f0424d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.264583"
+ d="m 123.18096,212.54075 c -1.54244,0 -3.03889,0.30198 -4.44866,0.89818 -1.36085,0.57588 -2.58333,1.3995 -3.63198,2.44903 -1.04982,1.04891 -1.87352,2.27125 -2.44969,3.63166 -0.59614,1.41006 -0.89752,2.90769 -0.89752,4.44931 0,0.88089 0.0998,1.75881 0.29917,2.60975 0.19372,0.82789 0.48107,1.63557 0.85432,2.40026 0.68819,1.40905 1.80379,2.81384 3.06538,3.86536 0.82281,-0.4498 1.28965,-0.94572 1.38884,-1.47622 0.0956,-0.50956 -0.12815,-1.05842 -0.7044,-1.72565 -1.36741,-1.56892 -2.12041,-3.58324 -2.12041,-5.6735 0,-4.76667 3.87763,-8.6456 8.64495,-8.6456 0.008,0 0.0393,6.6e-4 0.0393,6.6e-4 0,0 0.0305,-6.6e-4 0.0383,-6.6e-4 4.76715,0 8.64527,3.87893 8.64527,8.6456 0,2.09026 -0.75283,4.1046 -2.11975,5.67284 -0.57201,0.66284 -0.80153,1.23499 -0.70211,1.74922 0.10311,0.53107 0.56896,1.02002 1.38458,1.45397 1.26331,-1.05177 2.3782,-2.4564 3.06637,-3.86602 0.37372,-0.76469 0.66107,-1.57237 0.85464,-2.40026 0.1988,-0.85094 0.29983,-1.72886 0.29983,-2.60975 0,-1.54162 -0.30231,-3.03925 -0.89851,-4.44931 -0.57588,-1.36041 -1.40013,-2.58275 -2.44904,-3.63166 -1.04913,-1.04953 -2.27155,-1.87315 -3.63198,-2.44903 -1.40995,-0.5962 -2.90688,-0.89818 -4.44931,-0.89818 h -0.0393 z m -0.004,4.62214 c -0.32192,0 -0.64417,0.0219 -0.95873,0.0671 -0.92883,0.1324 -1.8401,0.46397 -2.63525,0.96004 -0.75897,0.47323 -1.43426,1.1087 -1.95215,1.83792 -0.53535,0.75374 -0.91954,1.62985 -1.10963,2.53316 -0.20655,0.97977 -0.19361,2.01224 0.0376,2.98552 0.21276,0.89514 0.61602,1.75703 1.16626,2.49191 0.14746,0.19797 0.31251,0.37855 0.48673,0.56987 0.058,0.063 0.11717,0.12782 0.17675,0.19411 0.002,0.002 0.003,0.003 0.005,0.005 0.007,0.007 0.0162,0.0158 0.0252,0.0265 0.60646,0.70473 0.91421,1.46388 0.91421,2.25525 0,1.19597 -0.66414,2.29315 -1.70895,2.85525 0.60776,0.33731 1.24734,0.61904 1.90404,0.83925 0.21816,0.0731 0.44001,0.13985 0.6625,0.19934 0.13296,-0.0835 0.58624,-0.42093 1.02943,-1.03369 0.42381,-0.58551 0.92331,-1.55674 0.89687,-2.85753 -0.0155,-0.78287 -0.17316,-1.54536 -0.46709,-2.26507 -0.29199,-0.71355 -0.71021,-1.36743 -1.24449,-1.94268 l -0.002,-0.004 c -0.04,-0.0456 -0.0786,-0.0911 -0.11816,-0.13613 -0.20138,-0.23358 -0.40932,-0.47459 -0.57609,-0.75677 -0.20417,-0.34691 -0.35302,-0.71154 -0.44123,-1.08442 -0.13724,-0.57588 -0.1445,-1.18703 -0.0229,-1.76689 0.1135,-0.53315 0.3392,-1.04985 0.65563,-1.49522 0.30638,-0.43154 0.70637,-0.80806 1.15578,-1.08835 0.46898,-0.29265 1.00724,-0.48855 1.55511,-0.56627 0.18502,-0.0266 0.37651,-0.0403 0.56824,-0.0403 h 0.0409 0.0412 c 0.19212,0 0.38328,0.0137 0.56889,0.0403 0.54819,0.0777 1.08631,0.27362 1.55479,0.56627 0.44949,0.28029 0.84882,0.65681 1.15545,1.08835 0.31651,0.44537 0.54311,0.96207 0.65563,1.49522 0.12194,0.57986 0.11399,1.19101 -0.0222,1.76689 -0.0886,0.37288 -0.23731,0.73751 -0.44189,1.08442 -0.16594,0.28218 -0.37412,0.52319 -0.57544,0.75677 -0.0397,0.045 -0.0786,0.0905 -0.11783,0.13617 l -0.003,0.004 c -0.53338,0.57525 -0.9522,1.22913 -1.24416,1.94267 -0.29412,0.71971 -0.45106,1.4822 -0.46742,2.26507 -0.0261,1.30079 0.47323,2.27202 0.89753,2.85754 0.44229,0.61275 0.89596,0.95014 1.02877,1.03369 0.22233,-0.0595 0.44541,-0.12627 0.66349,-0.19934 0.6567,-0.22022 1.29635,-0.50194 1.90436,-0.83926 -1.04596,-0.5621 -1.70993,-1.65928 -1.70993,-2.85524 0,-0.78066 0.29884,-1.5183 0.91356,-2.25395 0.008,-0.0117 0.0182,-0.0208 0.0252,-0.0278 0.002,-0.002 0.004,-0.003 0.006,-0.005 0.0597,-0.0663 0.1185,-0.1311 0.17577,-0.19411 0.17488,-0.19132 0.33935,-0.3719 0.48706,-0.56987 0.55097,-0.73488 0.95359,-1.59677 1.16691,-2.49191 0.2306,-0.97328 0.24377,-2.00575 0.038,-2.98552 -0.19086,-0.90335 -0.57496,-1.77946 -1.10998,-2.5332 -0.51797,-0.72922 -1.19318,-1.36469 -1.95215,-1.83792 -0.79523,-0.49606 -1.70641,-0.82764 -2.63561,-0.96004 -0.31415,-0.0452 -0.63706,-0.0671 -0.95906,-0.0671 h -0.0409 -0.0452 z m 0.0429,4.65814 c -1.24383,0 -2.25624,1.01222 -2.25624,2.25657 0,1.24414 1.01241,2.25624 2.25624,2.25624 1.24382,0 2.25591,-1.0121 2.25591,-2.25624 0,-1.24435 -1.01209,-2.25657 -2.25591,-2.25657 z"
+ id="path3043-5"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Ceph_Logo_with_text_red_white.svg b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Ceph_Logo_with_text_red_white.svg
new file mode 100644
index 000000000..a5b0602eb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Ceph_Logo_with_text_red_white.svg
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="Ceph_Ceph_Logo_red_white.svg"
+ inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
+ xml:space="preserve"
+ id="svg3023"
+ height="84.821152"
+ width="309.90601"
+ version="1.1"><sodipodi:namedview
+ inkscape:window-maximized="1"
+ inkscape:window-y="1080"
+ inkscape:window-x="3840"
+ inkscape:snap-grids="true"
+ inkscape:document-rotation="0"
+ inkscape:current-layer="svg3023"
+ inkscape:cy="40.664131"
+ inkscape:cx="174.44199"
+ inkscape:zoom="4"
+ fit-margin-bottom="0"
+ fit-margin-right="0"
+ fit-margin-left="0"
+ fit-margin-top="0"
+ showgrid="true"
+ id="namedview18"
+ inkscape:window-height="1051"
+ inkscape:window-width="1920"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0"
+ guidetolerance="10"
+ gridtolerance="10"
+ objecttolerance="10"
+ borderopacity="1"
+ bordercolor="#666666"
+ pagecolor="#000000"><inkscape:grid
+ id="grid12"
+ type="xygrid" /></sodipodi:namedview><metadata
+ id="metadata3029"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3027" /><g
+ transform="matrix(1.2645281,0,0,1.2645281,-331.87054,-100.71194)"
+ id="g7238"><path
+ inkscape:connector-curvature="0"
+ d="m 381.9911,121.40232 c 0,8.86025 -0.7935,11.31 -2.92775,13.4477 -1.26475,1.26514 -3.24375,2.13379 -6.963,2.13379 l -13.05023,0 c -4.19238,0 -6.72071,-0.7124 -8.46338,-2.45019 -2.76562,-2.77005 -3.55664,-6.0923 -3.55664,-18.9038 0,-12.8135 0.79102,-16.137245 3.55664,-18.90387 1.74267,-1.73975 4.271,-2.449625 8.46338,-2.449625 l 12.97361,0 c 3.87262,0 5.61237,0.787625 6.95799,2.13475 2.05525,2.055125 2.84863,4.902875 2.84863,12.888625 l -7.98725,0 c -0.16013,-5.53612 -0.47562,-6.48338 -0.95162,-6.9585 -0.47563,-0.47363 -1.10701,-0.71138 -2.92588,-0.71138 l -9.88712,0 c -2.45073,0 -3.08353,0.23775 -3.63627,0.7915 -0.79101,0.78863 -1.1875,2.2925 -1.1875,13.2085 0,10.91263 0.39649,12.4165 1.1875,13.2075 0.55274,0.55375 1.18554,0.7915 3.63627,0.7915 l 9.96437,0 c 1.74162,0 2.53563,-0.15775 3.08537,-0.71137 0.55475,-0.55525 0.87213,-2.13775 0.87213,-7.51513 l 7.99075,0"
+ id="path3049-5"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
+ inkscape:connector-curvature="0"
+ d="m 395.91147,111.75232 19.45601,0 c 0,-7.19625 -0.476,-8.77875 -1.18363,-9.49112 -0.478,-0.47363 -1.1875,-0.78863 -3.63763,-0.78863 l -9.81099,0 c -2.45076,0 -3.08351,0.23738 -3.71738,0.86863 -0.71238,0.71387 -1.02537,2.13387 -1.10638,9.41112 z m 0,6.5665 c 0.081,8.38225 0.55225,10.04338 1.1875,10.67625 0.63376,0.63375 1.1855,0.7925 3.63626,0.7925 l 11.07324,0 c 1.82076,0 2.37538,-0.3165 2.851,-0.7925 0.54988,-0.55375 0.70801,-1.5025 0.87013,-5.29887 l 7.98537,0 c -0.15724,6.64262 -0.791,9.01612 -2.92775,11.15382 -1.34325,1.34473 -3.16212,2.13379 -6.95799,2.13379 l -13.84088,0 c -4.19287,0 -6.72363,-0.7124 -8.46388,-2.45019 -2.77049,-2.77005 -3.55662,-6.0923 -3.55662,-18.9038 0,-12.8135 0.78613,-16.137245 3.55662,-18.90387 1.74025,-1.73975 4.27101,-2.449625 8.46388,-2.449625 l 11.70462,0 c 4.19438,0 6.88138,0.787625 8.46588,2.370125 2.76512,2.7685 3.55612,6.09225 3.55612,18.58838 l 0,2.13525 c 0,0.62987 -0.23637,0.94875 -0.95075,0.94875 l -26.65275,0"
+ id="path3051-2"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
+ inkscape:connector-curvature="0"
+ d="m 455.71123,128.68007 c -0.71038,0.711 -1.74313,1.02738 -4.34813,1.02738 l -6.17338,0 c -2.53174,0 -4.73137,-0.71388 -7.75137,-2.25 -0.18412,-0.0937 -0.35987,-0.18113 -0.55275,-0.27875 l 0,-23.25637 c 3.165,-1.58113 5.37838,-2.37113 7.99075,-2.37113 l 6.48675,0 c 2.605,0 3.63775,0.31637 4.34813,1.02738 1.18512,1.185 1.50249,3.47749 1.50249,13.05124 0,9.57275 -0.31737,11.86275 -1.50249,13.05025 z m -2.37688,-34.487745 -5.76913,0 c -3.562,0 -5.30124,0.793875 -10.67962,5.222625 l 0,-5.138625 -8.22463,0 0,52.149875 c 2.96238,0 8.22463,0 8.22463,0 l 0,-14.5025 c 5.37838,4.34771 7.11762,5.13872 10.67962,5.13872 l 5.76913,0 c 4.59225,0 6.88475,-0.79101 8.7035,-2.60741 2.29162,-2.29494 3.401,-5.53756 3.401,-18.82518 0,-13.28863 -1.10938,-16.533755 -3.401,-18.824755 -1.81875,-1.818875 -4.11125,-2.61275 -8.7035,-2.61275"
+ id="path3053-7"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
+ inkscape:connector-curvature="0"
+ d="m 504.98885,96.64645 c -1.5825,-1.5825 -3.6375,-2.454125 -7.35625,-2.454125 l -6.72125,0 c -3.56,0 -5.29875,0.793875 -10.68,5.222625 l 0,-16.27875 c -2.5525,-1.401375 -5.2175,-2.42875 -8.16625,-3.061125 -0.0212,0.001 -0.037,0.01375 -0.0589,0.021 l 0,56.887735 8.22512,0 0,-33.06148 c 0.6025,-0.30126 1.165,-0.56351 1.7075,-0.80713 2.30875,-1.03662 4.16875,-1.564 6.28125,-1.564 l 5.5375,0 c 2.7675,0 3.55875,0.31638 4.42875,1.1875 0.79125,0.79 1.10625,2.05375 1.10625,4.11138 l 0,30.13373 8.23,0 0,-30.68749 c 0,-5.93262 -0.8725,-7.988745 -2.53375,-9.64987"
+ id="path3055-0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><path
+ inkscape:connector-curvature="0"
+ id="path3043-5"
+ d="M 43.19186,0 C 37.36219,0 31.70629,1.141324 26.37804,3.39468 21.23468,5.571233 16.61428,8.684145 12.65087,12.650872 8.68303,16.615226 5.56986,21.235109 3.3922,26.376813 1.13908,31.706162 0,37.366518 0,43.193098 c 0,3.32935 0.37705,6.64748 1.13073,9.86362 0.73215,3.12905 1.81822,6.1817 3.22891,9.07187 2.60102,5.32555 6.81748,10.63499 11.58571,14.60924 3.1098,-1.70006 4.87424,-3.57439 5.24913,-5.57944 0.3612,-1.9259 -0.48432,-4.0003 -2.6623,-6.52213 -5.16814,-5.92976 -8.01412,-13.54295 -8.01412,-21.44316 0,-18.015755 14.65559,-32.676271 32.6738,-32.676271 0.0308,0 0.14845,0.0025 0.14845,0.0025 0,0 0.11535,-0.0025 0.14475,-0.0025 18.01758,0 32.67503,14.660516 32.67503,32.676271 0,7.90021 -2.84531,15.51346 -8.01164,21.44067 -2.16191,2.50521 -3.02941,4.66768 -2.65365,6.61121 0.38972,2.0072 2.15042,3.8552 5.23306,5.49533 4.77471,-3.9752 8.98849,-9.28404 11.58942,-14.61172 1.41251,-2.89017 2.49856,-5.94282 3.23014,-9.07187 0.75139,-3.21614 1.13321,-6.53427 1.13321,-9.86362 0,-5.82658 -1.14257,-11.486936 -3.39592,-16.816285 C 81.10817,21.235109 77.99288,16.615226 74.02852,12.650872 70.06329,8.684145 65.44312,5.571233 60.30133,3.39468 54.9724,1.141324 49.31472,0 43.48506,0 L 43.3366,0 43.19186,0 Z m -0.0161,17.469488 c -1.2167,0 -2.43464,0.0826 -3.62355,0.253612 -3.51067,0.500394 -6.95483,1.753604 -9.96012,3.628497 -2.86856,1.78859 -5.42084,4.190352 -7.37823,6.946476 -2.02335,2.84876 -3.47542,6.160065 -4.19387,9.574135 -0.78068,3.70308 -0.73174,7.60532 0.14227,11.28385 0.80411,3.3832 2.32825,6.64075 4.40789,9.41825 0.55734,0.74822 1.18117,1.43073 1.83961,2.15385 0.21932,0.23815 0.44287,0.48311 0.66805,0.73362 0.006,0.008 0.0128,0.0119 0.0172,0.0185 0.0263,0.0266 0.0614,0.0596 0.0953,0.10018 2.29215,2.66356 3.4553,5.53278 3.4553,8.52381 0,4.52017 -2.51013,8.66702 -6.45904,10.79148 2.29705,1.27489 4.71435,2.33969 7.19637,3.17199 0.82454,0.27617 1.66303,0.52855 2.50394,0.75341 0.50254,-0.31575 2.21572,-1.59095 3.89078,-3.90686 1.60181,-2.21297 3.48965,-5.88375 3.38973,-10.80013 -0.0587,-2.95889 -0.65446,-5.84073 -1.76538,-8.56091 -1.10357,-2.69684 -2.68426,-5.16818 -4.70357,-7.34236 l -0.009,-0.0161 c -0.15122,-0.17261 -0.29697,-0.34443 -0.4466,-0.51466 -0.76111,-0.88281 -1.54703,-1.79373 -2.17735,-2.86024 -0.77165,-1.31115 -1.33423,-2.68927 -1.66765,-4.0986 -0.51868,-2.17655 -0.54614,-4.48642 -0.0865,-6.67801 0.42898,-2.01504 1.28202,-3.96792 2.47797,-5.65121 1.15796,-1.631028 2.66974,-3.054071 4.3683,-4.113449 1.77252,-1.106091 3.8069,-1.84649 5.8776,-2.140233 0.69928,-0.100552 1.42303,-0.152167 2.14766,-0.152167 l 0.15463,0 0.15588,0 c 0.72613,0 1.44862,0.05161 2.15013,0.152167 2.07189,0.293743 4.10574,1.034142 5.87636,2.140233 1.69888,1.059378 3.20816,2.482421 4.36706,4.113449 1.19628,1.68329 2.05272,3.63617 2.47797,5.65121 0.46088,2.19159 0.43084,4.50146 -0.0841,6.67801 -0.33469,1.40933 -0.8969,2.78745 -1.67012,4.0986 -0.62716,1.06651 -1.41399,1.97743 -2.17488,2.86024 -0.14996,0.17023 -0.29692,0.34205 -0.44537,0.51466 l -0.0124,0.0161 c -2.01591,2.17418 -3.59885,4.64552 -4.70232,7.34236 -1.11164,2.72018 -1.7048,5.60202 -1.76662,8.56091 -0.0986,4.91638 1.78857,8.58716 3.39221,10.80013 1.67165,2.31591 3.38632,3.59111 3.88828,3.90686 0.84031,-0.22486 1.68344,-0.47724 2.50767,-0.75341 2.48201,-0.8323 4.89961,-1.8971 7.19761,-3.17199 -3.95326,-2.12446 -6.46275,-6.27131 -6.46275,-10.79148 0,-2.9505 1.12948,-5.73844 3.45282,-8.51886 0.0319,-0.0442 0.0689,-0.0786 0.0953,-0.10512 0.008,-0.007 0.0133,-0.0127 0.021,-0.0185 0.22574,-0.25051 0.44787,-0.49547 0.66435,-0.73362 0.66096,-0.72312 1.28257,-1.40563 1.84085,-2.15385 2.08241,-2.7775 3.6041,-6.03505 4.41035,-9.41825 0.87158,-3.67853 0.92134,-7.58077 0.1435,-11.28384 -0.72129,-3.41408 -2.17301,-6.725384 -4.1951,-9.574144 C 62.50747,25.54196 59.95551,23.140198 57.08696,21.351608 54.08135,19.476714 50.63753,18.223505 47.12559,17.723112 45.93826,17.552091 44.71783,17.4695 43.50081,17.4695 l -0.15464,0 -0.17074,0 z m 0.16206,17.60557 c -4.70109,0 -8.52752,3.8257 -8.52752,8.52877 0,4.70227 3.82643,8.52752 8.52752,8.52752 4.70108,0 8.52629,-3.82525 8.52629,-8.52752 0,-4.70307 -3.82521,-8.52877 -8.52629,-8.52877 z"
+ style="fill:#f0424d;fill-opacity:1;fill-rule:nonzero;stroke:none" /></svg>
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Ceph_Logo_with_text_white.svg b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Ceph_Logo_with_text_white.svg
new file mode 100644
index 000000000..35bcc8c0a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Ceph_Logo_with_text_white.svg
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="Ceph_Ceph_Logo_white.svg"
+ inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
+ xml:space="preserve"
+ id="svg3023"
+ height="84.821152"
+ width="309.90601"
+ version="1.1"><sodipodi:namedview
+ inkscape:window-maximized="1"
+ inkscape:window-y="1080"
+ inkscape:window-x="3840"
+ inkscape:snap-grids="true"
+ inkscape:document-rotation="0"
+ inkscape:current-layer="svg3023"
+ inkscape:cy="40.664131"
+ inkscape:cx="174.44199"
+ inkscape:zoom="4"
+ fit-margin-bottom="0"
+ fit-margin-right="0"
+ fit-margin-left="0"
+ fit-margin-top="0"
+ showgrid="true"
+ id="namedview18"
+ inkscape:window-height="1051"
+ inkscape:window-width="1920"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0"
+ guidetolerance="10"
+ gridtolerance="10"
+ objecttolerance="10"
+ borderopacity="1"
+ bordercolor="#666666"
+ pagecolor="#000000"><inkscape:grid
+ id="grid12"
+ type="xygrid" /></sodipodi:namedview><metadata
+ id="metadata3029"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3027" /><g
+ transform="matrix(1.2645281,0,0,1.2645281,-331.87054,-100.71194)"
+ id="g7238"><path
+ inkscape:connector-curvature="0"
+ d="m 381.9911,121.40232 c 0,8.86025 -0.7935,11.31 -2.92775,13.4477 -1.26475,1.26514 -3.24375,2.13379 -6.963,2.13379 l -13.05023,0 c -4.19238,0 -6.72071,-0.7124 -8.46338,-2.45019 -2.76562,-2.77005 -3.55664,-6.0923 -3.55664,-18.9038 0,-12.8135 0.79102,-16.137245 3.55664,-18.90387 1.74267,-1.73975 4.271,-2.449625 8.46338,-2.449625 l 12.97361,0 c 3.87262,0 5.61237,0.787625 6.95799,2.13475 2.05525,2.055125 2.84863,4.902875 2.84863,12.888625 l -7.98725,0 c -0.16013,-5.53612 -0.47562,-6.48338 -0.95162,-6.9585 -0.47563,-0.47363 -1.10701,-0.71138 -2.92588,-0.71138 l -9.88712,0 c -2.45073,0 -3.08353,0.23775 -3.63627,0.7915 -0.79101,0.78863 -1.1875,2.2925 -1.1875,13.2085 0,10.91263 0.39649,12.4165 1.1875,13.2075 0.55274,0.55375 1.18554,0.7915 3.63627,0.7915 l 9.96437,0 c 1.74162,0 2.53563,-0.15775 3.08537,-0.71137 0.55475,-0.55525 0.87213,-2.13775 0.87213,-7.51513 l 7.99075,0"
+ id="path3049-5"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
+ inkscape:connector-curvature="0"
+ d="m 395.91147,111.75232 19.45601,0 c 0,-7.19625 -0.476,-8.77875 -1.18363,-9.49112 -0.478,-0.47363 -1.1875,-0.78863 -3.63763,-0.78863 l -9.81099,0 c -2.45076,0 -3.08351,0.23738 -3.71738,0.86863 -0.71238,0.71387 -1.02537,2.13387 -1.10638,9.41112 z m 0,6.5665 c 0.081,8.38225 0.55225,10.04338 1.1875,10.67625 0.63376,0.63375 1.1855,0.7925 3.63626,0.7925 l 11.07324,0 c 1.82076,0 2.37538,-0.3165 2.851,-0.7925 0.54988,-0.55375 0.70801,-1.5025 0.87013,-5.29887 l 7.98537,0 c -0.15724,6.64262 -0.791,9.01612 -2.92775,11.15382 -1.34325,1.34473 -3.16212,2.13379 -6.95799,2.13379 l -13.84088,0 c -4.19287,0 -6.72363,-0.7124 -8.46388,-2.45019 -2.77049,-2.77005 -3.55662,-6.0923 -3.55662,-18.9038 0,-12.8135 0.78613,-16.137245 3.55662,-18.90387 1.74025,-1.73975 4.27101,-2.449625 8.46388,-2.449625 l 11.70462,0 c 4.19438,0 6.88138,0.787625 8.46588,2.370125 2.76512,2.7685 3.55612,6.09225 3.55612,18.58838 l 0,2.13525 c 0,0.62987 -0.23637,0.94875 -0.95075,0.94875 l -26.65275,0"
+ id="path3051-2"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
+ inkscape:connector-curvature="0"
+ d="m 455.71123,128.68007 c -0.71038,0.711 -1.74313,1.02738 -4.34813,1.02738 l -6.17338,0 c -2.53174,0 -4.73137,-0.71388 -7.75137,-2.25 -0.18412,-0.0937 -0.35987,-0.18113 -0.55275,-0.27875 l 0,-23.25637 c 3.165,-1.58113 5.37838,-2.37113 7.99075,-2.37113 l 6.48675,0 c 2.605,0 3.63775,0.31637 4.34813,1.02738 1.18512,1.185 1.50249,3.47749 1.50249,13.05124 0,9.57275 -0.31737,11.86275 -1.50249,13.05025 z m -2.37688,-34.487745 -5.76913,0 c -3.562,0 -5.30124,0.793875 -10.67962,5.222625 l 0,-5.138625 -8.22463,0 0,52.149875 c 2.96238,0 8.22463,0 8.22463,0 l 0,-14.5025 c 5.37838,4.34771 7.11762,5.13872 10.67962,5.13872 l 5.76913,0 c 4.59225,0 6.88475,-0.79101 8.7035,-2.60741 2.29162,-2.29494 3.401,-5.53756 3.401,-18.82518 0,-13.28863 -1.10938,-16.533755 -3.401,-18.824755 -1.81875,-1.818875 -4.11125,-2.61275 -8.7035,-2.61275"
+ id="path3053-7"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
+ inkscape:connector-curvature="0"
+ d="m 504.98885,96.64645 c -1.5825,-1.5825 -3.6375,-2.454125 -7.35625,-2.454125 l -6.72125,0 c -3.56,0 -5.29875,0.793875 -10.68,5.222625 l 0,-16.27875 c -2.5525,-1.401375 -5.2175,-2.42875 -8.16625,-3.061125 -0.0212,0.001 -0.037,0.01375 -0.0589,0.021 l 0,56.887735 8.22512,0 0,-33.06148 c 0.6025,-0.30126 1.165,-0.56351 1.7075,-0.80713 2.30875,-1.03662 4.16875,-1.564 6.28125,-1.564 l 5.5375,0 c 2.7675,0 3.55875,0.31638 4.42875,1.1875 0.79125,0.79 1.10625,2.05375 1.10625,4.11138 l 0,30.13373 8.23,0 0,-30.68749 c 0,-5.93262 -0.8725,-7.988745 -2.53375,-9.64987"
+ id="path3055-0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><path
+ inkscape:connector-curvature="0"
+ id="path3043-5"
+ d="M 43.19186,0 C 37.36219,0 31.70629,1.141324 26.37804,3.39468 21.23468,5.571233 16.61428,8.684145 12.65087,12.650872 8.68303,16.615226 5.56986,21.235109 3.3922,26.376813 1.13908,31.706162 0,37.366518 0,43.193098 c 0,3.32935 0.37705,6.64748 1.13073,9.86362 0.73215,3.12905 1.81822,6.1817 3.22891,9.07187 2.60102,5.32555 6.81748,10.63499 11.58571,14.60924 3.1098,-1.70006 4.87424,-3.57439 5.24913,-5.57944 0.3612,-1.9259 -0.48432,-4.0003 -2.6623,-6.52213 -5.16814,-5.92976 -8.01412,-13.54295 -8.01412,-21.44316 0,-18.015755 14.65559,-32.676271 32.6738,-32.676271 0.0308,0 0.14845,0.0025 0.14845,0.0025 0,0 0.11535,-0.0025 0.14475,-0.0025 18.01758,0 32.67503,14.660516 32.67503,32.676271 0,7.90021 -2.84531,15.51346 -8.01164,21.44067 -2.16191,2.50521 -3.02941,4.66768 -2.65365,6.61121 0.38972,2.0072 2.15042,3.8552 5.23306,5.49533 4.77471,-3.9752 8.98849,-9.28404 11.58942,-14.61172 1.41251,-2.89017 2.49856,-5.94282 3.23014,-9.07187 0.75139,-3.21614 1.13321,-6.53427 1.13321,-9.86362 0,-5.82658 -1.14257,-11.486936 -3.39592,-16.816285 C 81.10817,21.235109 77.99288,16.615226 74.02852,12.650872 70.06329,8.684145 65.44312,5.571233 60.30133,3.39468 54.9724,1.141324 49.31472,0 43.48506,0 L 43.3366,0 43.19186,0 Z m -0.0161,17.469488 c -1.2167,0 -2.43464,0.0826 -3.62355,0.253612 -3.51067,0.500394 -6.95483,1.753604 -9.96012,3.628497 -2.86856,1.78859 -5.42084,4.190352 -7.37823,6.946476 -2.02335,2.84876 -3.47542,6.160065 -4.19387,9.574135 -0.78068,3.70308 -0.73174,7.60532 0.14227,11.28385 0.80411,3.3832 2.32825,6.64075 4.40789,9.41825 0.55734,0.74822 1.18117,1.43073 1.83961,2.15385 0.21932,0.23815 0.44287,0.48311 0.66805,0.73362 0.006,0.008 0.0128,0.0119 0.0172,0.0185 0.0263,0.0266 0.0614,0.0596 0.0953,0.10018 2.29215,2.66356 3.4553,5.53278 3.4553,8.52381 0,4.52017 -2.51013,8.66702 -6.45904,10.79148 2.29705,1.27489 4.71435,2.33969 7.19637,3.17199 0.82454,0.27617 1.66303,0.52855 2.50394,0.75341 0.50254,-0.31575 2.21572,-1.59095 3.89078,-3.90686 1.60181,-2.21297 3.48965,-5.88375 3.38973,-10.80013 -0.0587,-2.95889 -0.65446,-5.84073 -1.76538,-8.56091 -1.10357,-2.69684 -2.68426,-5.16818 -4.70357,-7.34236 l -0.009,-0.0161 c -0.15122,-0.17261 -0.29697,-0.34443 -0.4466,-0.51466 -0.76111,-0.88281 -1.54703,-1.79373 -2.17735,-2.86024 -0.77165,-1.31115 -1.33423,-2.68927 -1.66765,-4.0986 -0.51868,-2.17655 -0.54614,-4.48642 -0.0865,-6.67801 0.42898,-2.01504 1.28202,-3.96792 2.47797,-5.65121 1.15796,-1.631028 2.66974,-3.054071 4.3683,-4.113449 1.77252,-1.106091 3.8069,-1.84649 5.8776,-2.140233 0.69928,-0.100552 1.42303,-0.152167 2.14766,-0.152167 l 0.15463,0 0.15588,0 c 0.72613,0 1.44862,0.05161 2.15013,0.152167 2.07189,0.293743 4.10574,1.034142 5.87636,2.140233 1.69888,1.059378 3.20816,2.482421 4.36706,4.113449 1.19628,1.68329 2.05272,3.63617 2.47797,5.65121 0.46088,2.19159 0.43084,4.50146 -0.0841,6.67801 -0.33469,1.40933 -0.8969,2.78745 -1.67012,4.0986 -0.62716,1.06651 -1.41399,1.97743 -2.17488,2.86024 -0.14996,0.17023 -0.29692,0.34205 -0.44537,0.51466 l -0.0124,0.0161 c -2.01591,2.17418 -3.59885,4.64552 -4.70232,7.34236 -1.11164,2.72018 -1.7048,5.60202 -1.76662,8.56091 -0.0986,4.91638 1.78857,8.58716 3.39221,10.80013 1.67165,2.31591 3.38632,3.59111 3.88828,3.90686 0.84031,-0.22486 1.68344,-0.47724 2.50767,-0.75341 2.48201,-0.8323 4.89961,-1.8971 7.19761,-3.17199 -3.95326,-2.12446 -6.46275,-6.27131 -6.46275,-10.79148 0,-2.9505 1.12948,-5.73844 3.45282,-8.51886 0.0319,-0.0442 0.0689,-0.0786 0.0953,-0.10512 0.008,-0.007 0.0133,-0.0127 0.021,-0.0185 0.22574,-0.25051 0.44787,-0.49547 0.66435,-0.73362 0.66096,-0.72312 1.28257,-1.40563 1.84085,-2.15385 2.08241,-2.7775 3.6041,-6.03505 4.41035,-9.41825 0.87158,-3.67853 0.92134,-7.58077 0.1435,-11.28384 -0.72129,-3.41408 -2.17301,-6.725384 -4.1951,-9.574144 C 62.50747,25.54196 59.95551,23.140198 57.08696,21.351608 54.08135,19.476714 50.63753,18.223505 47.12559,17.723112 45.93826,17.552091 44.71783,17.4695 43.50081,17.4695 l -0.15464,0 -0.17074,0 z m 0.16206,17.60557 c -4.70109,0 -8.52752,3.8257 -8.52752,8.52877 0,4.70227 3.82643,8.52752 8.52752,8.52752 4.70108,0 8.52629,-3.82525 8.52629,-8.52752 0,-4.70307 -3.82521,-8.52877 -8.52629,-8.52877 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /></svg>
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo.svg b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo.svg
new file mode 100644
index 000000000..9426c300d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo.svg
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="Ceph_Logo.svg"
+ inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
+ id="svg27"
+ version="1.1"
+ viewBox="0 0 22.93428 22.4424"
+ height="22.4424mm"
+ width="22.93428mm">
+ <defs
+ id="defs21">
+ <color-profile
+ xlink:href="file:///usr/share/color/icc/krita/sRGB-elle-V2-g10.icc"
+ name="sRGB-elle-V2-g10.icc"
+ id="color-profile35" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-maximized="1"
+ inkscape:window-y="1080"
+ inkscape:window-x="3840"
+ inkscape:window-height="1051"
+ inkscape:window-width="1920"
+ fit-margin-bottom="0"
+ fit-margin-right="0"
+ fit-margin-left="0"
+ fit-margin-top="0"
+ showgrid="false"
+ inkscape:document-rotation="0"
+ inkscape:current-layer="layer1"
+ inkscape:document-units="mm"
+ inkscape:cy="39.499381"
+ inkscape:cx="29.58201"
+ inkscape:zoom="5.6"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base" />
+ <metadata
+ id="metadata24">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ transform="translate(-111.75311,-212.54075)"
+ id="layer1"
+ inkscape:groupmode="layer"
+ inkscape:label="Ebene 1">
+ <path
+ style="fill:#f0424d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.264583"
+ d="m 123.18096,212.54075 c -1.54244,0 -3.03889,0.30198 -4.44866,0.89818 -1.36085,0.57588 -2.58333,1.3995 -3.63198,2.44903 -1.04982,1.04891 -1.87352,2.27125 -2.44969,3.63166 -0.59614,1.41006 -0.89752,2.90769 -0.89752,4.44931 0,0.88089 0.0998,1.75881 0.29917,2.60975 0.19372,0.82789 0.48107,1.63557 0.85432,2.40026 0.68819,1.40905 1.80379,2.81384 3.06538,3.86536 0.82281,-0.4498 1.28965,-0.94572 1.38884,-1.47622 0.0956,-0.50956 -0.12815,-1.05842 -0.7044,-1.72565 -1.36741,-1.56892 -2.12041,-3.58324 -2.12041,-5.6735 0,-4.76667 3.87763,-8.6456 8.64495,-8.6456 0.008,0 0.0393,6.6e-4 0.0393,6.6e-4 0,0 0.0305,-6.6e-4 0.0383,-6.6e-4 4.76715,0 8.64527,3.87893 8.64527,8.6456 0,2.09026 -0.75283,4.1046 -2.11975,5.67284 -0.57201,0.66284 -0.80153,1.23499 -0.70211,1.74922 0.10311,0.53107 0.56896,1.02002 1.38458,1.45397 1.26331,-1.05177 2.3782,-2.4564 3.06637,-3.86602 0.37372,-0.76469 0.66107,-1.57237 0.85464,-2.40026 0.1988,-0.85094 0.29983,-1.72886 0.29983,-2.60975 0,-1.54162 -0.30231,-3.03925 -0.89851,-4.44931 -0.57588,-1.36041 -1.40013,-2.58275 -2.44904,-3.63166 -1.04913,-1.04953 -2.27155,-1.87315 -3.63198,-2.44903 -1.40995,-0.5962 -2.90688,-0.89818 -4.44931,-0.89818 h -0.0393 z m -0.004,4.62214 c -0.32192,0 -0.64417,0.0219 -0.95873,0.0671 -0.92883,0.1324 -1.8401,0.46397 -2.63525,0.96004 -0.75897,0.47323 -1.43426,1.1087 -1.95215,1.83792 -0.53535,0.75374 -0.91954,1.62985 -1.10963,2.53316 -0.20655,0.97977 -0.19361,2.01224 0.0376,2.98552 0.21276,0.89514 0.61602,1.75703 1.16626,2.49191 0.14746,0.19797 0.31251,0.37855 0.48673,0.56987 0.058,0.063 0.11717,0.12782 0.17675,0.19411 0.002,0.002 0.003,0.003 0.005,0.005 0.007,0.007 0.0162,0.0158 0.0252,0.0265 0.60646,0.70473 0.91421,1.46388 0.91421,2.25525 0,1.19597 -0.66414,2.29315 -1.70895,2.85525 0.60776,0.33731 1.24734,0.61904 1.90404,0.83925 0.21816,0.0731 0.44001,0.13985 0.6625,0.19934 0.13296,-0.0835 0.58624,-0.42093 1.02943,-1.03369 0.42381,-0.58551 0.92331,-1.55674 0.89687,-2.85753 -0.0155,-0.78287 -0.17316,-1.54536 -0.46709,-2.26507 -0.29199,-0.71355 -0.71021,-1.36743 -1.24449,-1.94268 l -0.002,-0.004 c -0.04,-0.0456 -0.0786,-0.0911 -0.11816,-0.13613 -0.20138,-0.23358 -0.40932,-0.47459 -0.57609,-0.75677 -0.20417,-0.34691 -0.35302,-0.71154 -0.44123,-1.08442 -0.13724,-0.57588 -0.1445,-1.18703 -0.0229,-1.76689 0.1135,-0.53315 0.3392,-1.04985 0.65563,-1.49522 0.30638,-0.43154 0.70637,-0.80806 1.15578,-1.08835 0.46898,-0.29265 1.00724,-0.48855 1.55511,-0.56627 0.18502,-0.0266 0.37651,-0.0403 0.56824,-0.0403 h 0.0409 0.0412 c 0.19212,0 0.38328,0.0137 0.56889,0.0403 0.54819,0.0777 1.08631,0.27362 1.55479,0.56627 0.44949,0.28029 0.84882,0.65681 1.15545,1.08835 0.31651,0.44537 0.54311,0.96207 0.65563,1.49522 0.12194,0.57986 0.11399,1.19101 -0.0222,1.76689 -0.0886,0.37288 -0.23731,0.73751 -0.44189,1.08442 -0.16594,0.28218 -0.37412,0.52319 -0.57544,0.75677 -0.0397,0.045 -0.0786,0.0905 -0.11783,0.13617 l -0.003,0.004 c -0.53338,0.57525 -0.9522,1.22913 -1.24416,1.94267 -0.29412,0.71971 -0.45106,1.4822 -0.46742,2.26507 -0.0261,1.30079 0.47323,2.27202 0.89753,2.85754 0.44229,0.61275 0.89596,0.95014 1.02877,1.03369 0.22233,-0.0595 0.44541,-0.12627 0.66349,-0.19934 0.6567,-0.22022 1.29635,-0.50194 1.90436,-0.83926 -1.04596,-0.5621 -1.70993,-1.65928 -1.70993,-2.85524 0,-0.78066 0.29884,-1.5183 0.91356,-2.25395 0.008,-0.0117 0.0182,-0.0208 0.0252,-0.0278 0.002,-0.002 0.004,-0.003 0.006,-0.005 0.0597,-0.0663 0.1185,-0.1311 0.17577,-0.19411 0.17488,-0.19132 0.33935,-0.3719 0.48706,-0.56987 0.55097,-0.73488 0.95359,-1.59677 1.16691,-2.49191 0.2306,-0.97328 0.24377,-2.00575 0.038,-2.98552 -0.19086,-0.90335 -0.57496,-1.77946 -1.10998,-2.5332 -0.51797,-0.72922 -1.19318,-1.36469 -1.95215,-1.83792 -0.79523,-0.49606 -1.70641,-0.82764 -2.63561,-0.96004 -0.31415,-0.0452 -0.63706,-0.0671 -0.95906,-0.0671 h -0.0409 -0.0452 z m 0.0429,4.65814 c -1.24383,0 -2.25624,1.01222 -2.25624,2.25657 0,1.24414 1.01241,2.25624 2.25624,2.25624 1.24382,0 2.25591,-1.0121 2.25591,-2.25624 0,-1.24435 -1.01209,-2.25657 -2.25591,-2.25657 z"
+ id="path3043-5"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/ceph_background.gif b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/ceph_background.gif
new file mode 100644
index 000000000..0f7426ee0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/ceph_background.gif
Binary files differ
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/loading.gif b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/loading.gif
new file mode 100755
index 000000000..8fb88dea3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/loading.gif
Binary files differ
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/logo-mini.png b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/logo-mini.png
new file mode 100644
index 000000000..b3446a894
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/logo-mini.png
Binary files differ
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/prometheus_logo.svg b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/prometheus_logo.svg
new file mode 100644
index 000000000..5c51f66d9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/prometheus_logo.svg
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ width="115.333px"
+ height="114px"
+ viewBox="0 0 115.333 114"
+ enable-background="new 0 0 115.333 114"
+ xml:space="preserve"
+ sodipodi:docname="prometheus_logo_orange.svg"
+ inkscape:version="0.92.1 r15371"><metadata
+ id="metadata4495"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs4493" /><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1484"
+ inkscape:window-height="886"
+ id="namedview4491"
+ showgrid="false"
+ inkscape:zoom="5.2784901"
+ inkscape:cx="60.603667"
+ inkscape:cy="60.329656"
+ inkscape:window-x="54"
+ inkscape:window-y="7"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="Layer_1" /><g
+ id="Layer_2" /><path
+ style="fill:#e6522c;fill-opacity:1"
+ inkscape:connector-curvature="0"
+ id="path4486"
+ d="M 56.667,0.667 C 25.372,0.667 0,26.036 0,57.332 c 0,31.295 25.372,56.666 56.667,56.666 31.295,0 56.666,-25.371 56.666,-56.666 0,-31.296 -25.372,-56.665 -56.666,-56.665 z m 0,106.055 c -8.904,0 -16.123,-5.948 -16.123,-13.283 H 72.79 c 0,7.334 -7.219,13.283 -16.123,13.283 z M 83.297,89.04 H 30.034 V 79.382 H 83.298 V 89.04 Z M 83.106,74.411 H 30.186 C 30.01,74.208 29.83,74.008 29.66,73.802 24.208,67.182 22.924,63.726 21.677,60.204 c -0.021,-0.116 6.611,1.355 11.314,2.413 0,0 2.42,0.56 5.958,1.205 -3.397,-3.982 -5.414,-9.044 -5.414,-14.218 0,-11.359 8.712,-21.285 5.569,-29.308 3.059,0.249 6.331,6.456 6.552,16.161 3.252,-4.494 4.613,-12.701 4.613,-17.733 0,-5.21 3.433,-11.262 6.867,-11.469 -3.061,5.045 0.793,9.37 4.219,20.099 1.285,4.03 1.121,10.812 2.113,15.113 C 63.797,33.534 65.333,20.5 71,16 c -2.5,5.667 0.37,12.758 2.333,16.167 3.167,5.5 5.087,9.667 5.087,17.548 0,5.284 -1.951,10.259 -5.242,14.148 3.742,-0.702 6.326,-1.335 6.326,-1.335 l 12.152,-2.371 c 10e-4,-10e-4 -1.765,7.261 -8.55,14.254 z" /></svg> \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/ceph_background.e82dd79127290ddbe8cb.gif b/src/pybind/mgr/dashboard/frontend/dist/en-US/ceph_background.e82dd79127290ddbe8cb.gif
new file mode 100644
index 000000000..0f7426ee0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/ceph_background.e82dd79127290ddbe8cb.gif
Binary files differ
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/favicon.ico b/src/pybind/mgr/dashboard/frontend/dist/en-US/favicon.ico
new file mode 100644
index 000000000..90e538ba7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/favicon.ico
Binary files differ
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.2dfb5f36fc148e26e398.woff b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.2dfb5f36fc148e26e398.woff
new file mode 100644
index 000000000..477da445a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.2dfb5f36fc148e26e398.woff
Binary files differ
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.7c20758e3e7c7dff7c8d.woff2 b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.7c20758e3e7c7dff7c8d.woff2
new file mode 100644
index 000000000..f3520b533
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.7c20758e3e7c7dff7c8d.woff2
Binary files differ
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.86541105409e56d17291.svg b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.86541105409e56d17291.svg
new file mode 100644
index 000000000..e99720454
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.86541105409e56d17291.svg
@@ -0,0 +1,2849 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<!--
+2019-2-18: Created with FontForge (http://fontforge.org)
+-->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
+<metadata>
+Created by FontForge 20180321 at Mon Feb 18 18:29:30 2019
+ By Julien Deswaef
+The Fork Awesome font is licensed under the SIL OFL 1.1 (http://scripts.sil.org/OFL). Fork Awesome is a fork based of off Font Awesome 4.7.0 by Dave Gandy. More info on licenses at https://forkawesome.github.io
+</metadata>
+<defs>
+<font id="forkawesome" horiz-adv-x="1536" >
+ <font-face
+ font-family="forkawesome"
+ font-weight="400"
+ font-stretch="normal"
+ units-per-em="1792"
+ panose-1="2 0 5 3 0 0 0 0 0 0"
+ ascent="1536"
+ descent="-256"
+ bbox="-0.653061 -264 2304.01 1538"
+ underline-thickness="89.6"
+ underline-position="-179.2"
+ unicode-range="U+0020-F32B"
+ />
+ <missing-glyph />
+ <glyph glyph-name="space" unicode=" " horiz-adv-x="200"
+ />
+ <glyph glyph-name="code" unicode="&#xf121;" horiz-adv-x="1830"
+d="M572 137l-50 -50c-13 -13 -33 -13 -46 0l-466 466c-13 13 -13 33 0 46l466 466c13 13 33 13 46 0l50 -50c13 -13 13 -33 0 -46l-393 -393l393 -393c13 -13 13 -33 0 -46zM1163 1204l-373 -1291c-5 -17 -23 -27 -39 -22l-62 17c-17 5 -27 23 -22 40l373 1291
+c5 17 23 27 39 22l62 -17c17 -5 27 -23 22 -40zM1820 553l-466 -466c-13 -13 -33 -13 -46 0l-50 50c-13 13 -13 33 0 46l393 393l-393 393c-13 13 -13 33 0 46l50 50c13 13 33 13 46 0l466 -466c13 -13 13 -33 0 -46z" />
+ <glyph glyph-name="chevron-circle-right" unicode="&#xf138;"
+d="M717 141l454 454c25 25 25 65 0 90l-454 454c-25 25 -65 25 -90 0l-102 -102c-25 -25 -25 -65 0 -90l307 -307l-307 -307c-25 -25 -25 -65 0 -90l102 -102c25 -25 65 -25 90 0zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768
+s768 -344 768 -768z" />
+ <glyph glyph-name="crosshairs" unicode="&#xf05b;"
+d="M1197 512h-109c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h109c-43 144 -157 258 -301 301v-109c0 -35 -29 -64 -64 -64h-128c-35 0 -64 29 -64 64v109c-144 -43 -258 -157 -301 -301h109c35 0 64 -29 64 -64v-128c0 -35 -29 -64 -64 -64h-109c43 -144 157 -258 301 -301
+v109c0 35 29 64 64 64h128c35 0 64 -29 64 -64v-109c144 43 258 157 301 301zM1536 704v-128c0 -35 -29 -64 -64 -64h-143c-49 -215 -218 -384 -433 -433v-143c0 -35 -29 -64 -64 -64h-128c-35 0 -64 29 -64 64v143c-215 49 -384 218 -433 433h-143c-35 0 -64 29 -64 64v128
+c0 35 29 64 64 64h143c49 215 218 384 433 433v143c0 35 29 64 64 64h128c35 0 64 -29 64 -64v-143c215 -49 384 -218 433 -433h143c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="gg" unicode="&#xf260;" horiz-adv-x="1920"
+d="M672 736l384 -384l-384 -384l-672 672l672 672l168 -168l-96 -96l-72 72l-480 -480l480 -480l193 193l-289 287zM1248 1312l672 -672l-672 -672l-168 168l96 96l72 -72l480 480l-480 480l-193 -193l289 -287l-96 -96l-384 384z" />
+ <glyph glyph-name="wpforms" unicode="&#xf298;"
+d="M515 625v-128h-252v128h252zM515 880v-127h-252v127h252zM1273 369v-128h-341v128h341zM1273 625v-128h-672v128h672zM1273 880v-127h-672v127h672zM1408 20v1240c0 11 -9 20 -20 20h-32l-378 -256l-210 171l-210 -171l-378 256h-32c-11 0 -20 -9 -20 -20v-1240
+c0 -11 9 -20 20 -20h1240c11 0 20 9 20 20zM553 1130l185 150h-406zM983 1130l221 150h-406zM1536 1260v-1240c0 -82 -66 -148 -148 -148h-1240c-82 0 -148 66 -148 148v1240c0 82 66 148 148 148h1240c82 0 148 -66 148 -148z" />
+ <glyph glyph-name="angle-double-left" unicode="&#xf100;" horiz-adv-x="966"
+d="M582 160c0 -8 -4 -17 -10 -23l-50 -50c-6 -6 -15 -10 -23 -10s-17 4 -23 10l-466 466c-6 6 -10 15 -10 23s4 17 10 23l466 466c6 6 15 10 23 10s17 -4 23 -10l50 -50c6 -6 10 -15 10 -23s-4 -17 -10 -23l-393 -393l393 -393c6 -6 10 -15 10 -23zM966 160
+c0 -8 -4 -17 -10 -23l-50 -50c-6 -6 -15 -10 -23 -10s-17 4 -23 10l-466 466c-6 6 -10 15 -10 23s4 17 10 23l466 466c6 6 15 10 23 10s17 -4 23 -10l50 -50c6 -6 10 -15 10 -23s-4 -17 -10 -23l-393 -393l393 -393c6 -6 10 -15 10 -23z" />
+ <glyph glyph-name="list" unicode="&#xf03a;" horiz-adv-x="1792"
+d="M256 224v-192c0 -17 -15 -32 -32 -32h-192c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h192c17 0 32 -15 32 -32zM256 608v-192c0 -17 -15 -32 -32 -32h-192c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h192c17 0 32 -15 32 -32zM256 992v-192c0 -17 -15 -32 -32 -32h-192
+c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h192c17 0 32 -15 32 -32zM1792 224v-192c0 -17 -15 -32 -32 -32h-1344c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h1344c17 0 32 -15 32 -32zM256 1376v-192c0 -17 -15 -32 -32 -32h-192c-17 0 -32 15 -32 32v192
+c0 17 15 32 32 32h192c17 0 32 -15 32 -32zM1792 608v-192c0 -17 -15 -32 -32 -32h-1344c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h1344c17 0 32 -15 32 -32zM1792 992v-192c0 -17 -15 -32 -32 -32h-1344c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h1344
+c17 0 32 -15 32 -32zM1792 1376v-192c0 -17 -15 -32 -32 -32h-1344c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h1344c17 0 32 -15 32 -32z" />
+ <glyph glyph-name="archlinux" unicode="&#xf323;" horiz-adv-x="1794"
+d="M897 1538c164 -386 203 -504 682 -1397c-61 36 -138 70 -247 98c158 -81 236 -156 310 -214c47 -87 97 -179 152 -281c-281 162 -499 263 -702 303c7 31 11 64 12 98c5 182 -83 337 -195 347s-207 -131 -212 -313v-9c0 -43 4 -84 13 -122c-205 -39 -426 -140 -710 -304
+c362 650 540 989 654 1226c60 -50 139 -99 256 -147c-109 76 -175 143 -230 201c89 190 137 318 217 514z" />
+ <glyph glyph-name="th" unicode="&#xf00a;" horiz-adv-x="1792"
+d="M512 288v-192c0 -53 -43 -96 -96 -96h-320c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h320c53 0 96 -43 96 -96zM512 800v-192c0 -53 -43 -96 -96 -96h-320c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h320c53 0 96 -43 96 -96zM1152 288v-192c0 -53 -43 -96 -96 -96h-320
+c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h320c53 0 96 -43 96 -96zM512 1312v-192c0 -53 -43 -96 -96 -96h-320c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h320c53 0 96 -43 96 -96zM1152 800v-192c0 -53 -43 -96 -96 -96h-320c-53 0 -96 43 -96 96v192c0 53 43 96 96 96
+h320c53 0 96 -43 96 -96zM1792 288v-192c0 -53 -43 -96 -96 -96h-320c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h320c53 0 96 -43 96 -96zM1152 1312v-192c0 -53 -43 -96 -96 -96h-320c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h320c53 0 96 -43 96 -96zM1792 800v-192
+c0 -53 -43 -96 -96 -96h-320c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h320c53 0 96 -43 96 -96zM1792 1312v-192c0 -53 -43 -96 -96 -96h-320c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h320c53 0 96 -43 96 -96z" />
+ <glyph glyph-name="angle-left" unicode="&#xf104;" horiz-adv-x="582"
+d="M582 992c0 -8 -4 -17 -10 -23l-393 -393l393 -393c6 -6 10 -15 10 -23s-4 -17 -10 -23l-50 -50c-6 -6 -15 -10 -23 -10s-17 4 -23 10l-466 466c-6 6 -10 15 -10 23s4 17 10 23l466 466c6 6 15 10 23 10s17 -4 23 -10l50 -50c6 -6 10 -14 10 -23z" />
+ <glyph glyph-name="recycle" unicode="&#xf1b8;" horiz-adv-x="1760"
+d="M820 367l-15 -368l-2 -22l-420 29c-52 4 -95 53 -114 97c-40 93 12 203 42 292c0 0 77 -12 509 -28zM433 953l180 -379l-147 92c-225 -257 -246 -448 -246 -448l-190 357c-39 58 -4 121 -4 121s35 63 114 188l-140 86zM1664 436l-188 -359c-26 -65 -98 -71 -98 -71
+s-71 -7 -219 -12l8 -164l-230 367l211 362l7 -173c339 -41 509 50 509 50zM879 1360c0 0 -47 -62 -265 -435l-317 187l-19 12l225 356c28 44 91 60 140 55c100 -9 172 -106 236 -175zM1534 1053l212 -363c27 -45 11 -108 -15 -150c-54 -84 -174 -104 -264 -129
+c0 0 -34 71 -265 436l313 195zM1391 1279l142 83l-220 -373l-419 20l151 86c-120 319 -279 429 -279 429l405 -1c70 6 108 -54 108 -54s39 -61 112 -190z" />
+ <glyph glyph-name="file-code-o" unicode="&#xf1c9;"
+d="M1468 1156c37 -37 68 -111 68 -164v-1152c0 -53 -43 -96 -96 -96h-1344c-53 0 -96 43 -96 96v1600c0 53 43 96 96 96h896c53 0 127 -31 164 -68zM1024 1400v-376h376c-6 17 -15 34 -22 41l-313 313c-7 7 -24 16 -41 22zM1408 -128v1024h-416c-53 0 -96 43 -96 96v416
+h-768v-1536h1280zM480 768c11 14 31 17 45 6l51 -38c14 -11 17 -31 6 -45l-182 -243l182 -243c11 -14 8 -34 -6 -45l-51 -38c-14 -11 -34 -8 -45 6l-226 301c-8 11 -8 27 0 38zM1282 467c8 -11 8 -27 0 -38l-226 -301c-11 -14 -31 -17 -45 -6l-51 38c-14 11 -17 31 -6 45
+l182 243l-182 243c-11 14 -8 34 6 45l51 38c14 11 34 8 45 -6zM662 6c-18 3 -29 20 -26 37l138 831c3 18 20 29 37 26l63 -10c18 -3 29 -20 26 -37l-138 -831c-3 -18 -20 -29 -37 -26z" />
+ <glyph glyph-name="thumb-tack" unicode="&#xf08d;" horiz-adv-x="1152"
+d="M480 672v448c0 18 -14 32 -32 32s-32 -14 -32 -32v-448c0 -18 14 -32 32 -32s32 14 32 32zM1152 320c0 -35 -29 -64 -64 -64h-429l-51 -483c-2 -16 -15 -29 -31 -29h-1c-16 0 -29 11 -32 27l-76 485h-404c-35 0 -64 29 -64 64c0 164 124 320 256 320v512
+c-70 0 -128 58 -128 128s58 128 128 128h640c70 0 128 -58 128 -128s-58 -128 -128 -128v-512c132 0 256 -156 256 -320z" />
+ <glyph glyph-name="fax" unicode="&#xf1ac;" horiz-adv-x="1792"
+d="M288 1152c88 0 160 -72 160 -160v-1088c0 -88 -72 -160 -160 -160h-128c-88 0 -160 72 -160 160v1088c0 88 72 160 160 160h128zM1664 989c76 -44 128 -127 128 -221v-768c0 -141 -115 -256 -256 -256h-864c-88 0 -160 72 -160 160v1536c0 53 43 96 96 96h672
+c53 0 127 -31 164 -68l152 -152c37 -37 68 -111 68 -164v-163zM928 0v128c0 18 -14 32 -32 32h-128c-18 0 -32 -14 -32 -32v-128c0 -18 14 -32 32 -32h128c18 0 32 14 32 32zM928 256v128c0 18 -14 32 -32 32h-128c-18 0 -32 -14 -32 -32v-128c0 -18 14 -32 32 -32h128
+c18 0 32 14 32 32zM928 512v128c0 18 -14 32 -32 32h-128c-18 0 -32 -14 -32 -32v-128c0 -18 14 -32 32 -32h128c18 0 32 14 32 32zM1184 0v128c0 18 -14 32 -32 32h-128c-18 0 -32 -14 -32 -32v-128c0 -18 14 -32 32 -32h128c18 0 32 14 32 32zM1184 256v128
+c0 18 -14 32 -32 32h-128c-18 0 -32 -14 -32 -32v-128c0 -18 14 -32 32 -32h128c18 0 32 14 32 32zM1184 512v128c0 18 -14 32 -32 32h-128c-18 0 -32 -14 -32 -32v-128c0 -18 14 -32 32 -32h128c18 0 32 14 32 32zM1440 0v128c0 18 -14 32 -32 32h-128
+c-18 0 -32 -14 -32 -32v-128c0 -18 14 -32 32 -32h128c18 0 32 14 32 32zM1440 256v128c0 18 -14 32 -32 32h-128c-18 0 -32 -14 -32 -32v-128c0 -18 14 -32 32 -32h128c18 0 32 14 32 32zM1440 512v128c0 18 -14 32 -32 32h-128c-18 0 -32 -14 -32 -32v-128
+c0 -18 14 -32 32 -32h128c18 0 32 14 32 32zM1536 896v256h-160c-53 0 -96 43 -96 96v160h-640v-512h896z" />
+ <glyph glyph-name="xing-square" unicode="&#xf169;"
+d="M685 771c0 0 0 1 -126 222c-10 16 -24 34 -52 34h-184c-12 0 -21 -4 -26 -11c-5 -8 -4 -19 1 -29l125 -216v-1l-196 -346c-6 -10 -5 -20 0 -28s13 -13 24 -13h185c27 0 41 19 50 36c192 339 199 352 199 352zM1309 1268c-5 8 -13 12 -24 12h-187c-27 0 -39 -17 -49 -35
+c-398 -706 -411 -729 -411 -729s0 -1 262 -481c9 -16 23 -35 52 -35h184c11 0 20 4 25 12s5 18 -1 28l-260 476v1l409 723c5 10 5 20 0 28zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960
+c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="google-plus-official" unicode="&#xf2b3;"
+d="M917 631c0 22 -2 43 -6 64h-362v-132h217c-16 -106 -116 -165 -217 -165c-133 0 -239 110 -239 242s106 242 239 242c56 0 112 -19 153 -59l104 101c-71 66 -160 100 -257 100c-213 0 -384 -172 -384 -384s171 -384 384 -384c221 0 368 156 368 375zM1262 585h109v110
+h-109v110h-110v-110h-110v-110h110v-110h110v110zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="quora" unicode="&#xf2c4;" horiz-adv-x="1734"
+d="M1226 749c0 417 -130 631 -435 631c-300 0 -430 -214 -430 -631c0 -415 130 -627 430 -627c48 0 91 5 131 17c-62 122 -135 245 -277 245c-27 0 -54 -4 -79 -16l-49 97c59 51 154 91 276 91c191 0 288 -92 366 -209c45 100 67 235 67 402zM1616 117h117
+c7 -72 -29 -373 -356 -373c-198 0 -302 115 -381 249c-65 -18 -135 -27 -205 -27c-400 0 -791 319 -791 783c0 468 392 787 791 787c407 0 794 -317 794 -787c0 -262 -122 -475 -299 -612c57 -86 116 -143 198 -143c90 0 126 69 132 123z" />
+ <glyph glyph-name="archive-org" unicode="&#xf2fc;" horiz-adv-x="1506"
+d="M1459 1344l-27 -53h-1385l-24 53l717 189zM1430 1237v-140h-1380v140h1380zM1257 442c-3 65 -4 124 -3 178c0 25 1 61 3 108s3 77 3 91c1 22 3 57 5 104s4 82 5 107c0 1 1 3 1 7v10c47 10 93 10 138 0c21 -325 21 -630 0 -916c-41 -11 -82 -12 -123 -1c-6 1 -10 2 -11 2
+s-3 2 -3 3s-1 4 -1 9c-3 34 -6 90 -10 165zM80 369v0c-1 9 -1 22 -1 38c0 5 -1 11 -1 21s-1 17 -1 22c0 26 0 45 -1 57v219c2 38 3 68 3 88c2 32 3 56 3 71c1 7 1 15 1 26c0 3 1 9 1 17s1 14 1 18c0 7 0 10 1 12c0 12 0 22 1 28c0 11 1 20 2 27c0 11 0 19 1 24c0 4 2 6 7 7
+c29 10 61 13 96 8c11 -2 22 -5 32 -9c2 0 3 -2 3 -6c2 -42 4 -74 6 -97c1 -20 2 -50 3 -90s2 -69 2 -88s1 -47 1 -85s1 -66 2 -84c-3 -131 -4 -199 -4 -206c-1 -47 -3 -112 -7 -194c-2 -27 -3 -47 -3 -60c0 -3 -2 -5 -6 -6c-28 -9 -59 -11 -94 -8c-4 1 -10 3 -18 5
+s-12 4 -14 5c-4 0 -6 1 -6 4c0 12 0 21 -1 26c0 4 -1 8 -1 14s-1 10 -1 13c0 9 0 15 -1 20c0 6 -1 13 -1 24v25c-1 6 -2 14 -2 25s0 19 -1 25c0 17 -1 30 -2 40v24zM464 255v0v25s-1 19 -1 25c-1 10 -1 23 -1 40c-1 5 -2 13 -2 24c0 16 0 29 -1 38v43c-1 13 -2 32 -2 57v29
+s-1 21 -1 27v102c0 27 0 47 1 61c0 18 1 48 3 88c0 17 1 40 3 71c0 11 0 20 1 26c0 15 1 27 2 35v12c0 4 1 9 1 15v13s1 7 2 13s1 10 1 14l2 24c0 4 1 6 5 7c30 10 62 13 96 8c11 -2 22 -5 32 -9c4 0 6 -2 6 -6l4 -97l4 -178c2 -78 3 -135 3 -169c0 -24 -1 -59 -1 -104
+s-1 -79 -2 -102c-1 -47 -3 -112 -7 -194c0 -13 -1 -33 -3 -60c0 -3 -2 -5 -7 -6c-26 -10 -57 -12 -92 -8c-4 0 -7 1 -11 2s-8 3 -13 4s-8 3 -10 4c-2 0 -3 1 -3 4c-1 7 -1 15 -1 26c-1 7 -2 16 -2 27c-2 4 -3 10 -3 20zM1046 961v0c1 -26 3 -63 4 -114s2 -89 2 -114
+c2 -67 3 -113 3 -140c0 -22 -1 -53 -1 -95s-1 -73 -2 -94c-1 -45 -3 -111 -7 -199c-1 -8 -2 -20 -2 -36s0 -28 -1 -36c0 -3 -2 -5 -7 -6c-27 -9 -58 -11 -93 -8c-5 1 -12 2 -20 5s-12 5 -13 5c-3 0 -5 1 -5 5c0 12 0 31 -2 56s-4 45 -5 58c0 15 -1 40 -2 73s-2 59 -3 77
+c0 13 -1 33 -2 60s-1 47 -1 60v68c-1 46 -1 69 0 70c1 55 3 136 7 242c2 48 4 94 8 139c0 4 2 6 6 7c29 10 61 13 95 8c12 -2 23 -5 33 -9c3 0 4 -2 4 -6zM60 -18v98h1390v-98h-1390zM0 -128v73h1506v-73h-1506z" />
+ <glyph glyph-name="volume-up" unicode="&#xf028;" horiz-adv-x="1664"
+d="M768 1184v-1088c0 -35 -29 -64 -64 -64c-17 0 -33 7 -45 19l-333 333h-262c-35 0 -64 29 -64 64v384c0 35 29 64 64 64h262l333 333c12 12 28 19 45 19c35 0 64 -29 64 -64zM1152 640c0 -100 -61 -197 -155 -235c-8 -4 -17 -5 -25 -5c-35 0 -64 28 -64 64
+c0 76 116 55 116 176s-116 100 -116 176c0 36 29 64 64 64c8 0 17 -1 25 -5c94 -37 155 -135 155 -235zM1408 640c0 -203 -122 -392 -310 -471c-8 -3 -17 -5 -25 -5c-36 0 -65 29 -65 64c0 28 16 47 39 59c27 14 52 26 76 44c99 72 157 187 157 309s-58 237 -157 309
+c-24 18 -49 30 -76 44c-23 12 -39 31 -39 59c0 35 29 64 64 64c9 0 18 -2 26 -5c188 -79 310 -268 310 -471zM1664 640c0 -307 -183 -585 -465 -706c-8 -3 -17 -5 -26 -5c-35 0 -64 29 -64 64c0 29 15 45 39 59c14 8 30 13 45 21c28 15 56 32 82 51c164 121 261 312 261 516
+s-97 395 -261 516c-26 19 -54 36 -82 51c-15 8 -31 13 -45 21c-24 14 -39 30 -39 59c0 35 29 64 64 64c9 0 18 -2 26 -5c282 -121 465 -399 465 -706z" />
+ <glyph glyph-name="spoon" unicode="&#xf1b1;" horiz-adv-x="640"
+d="M640 1008c0 -200 -87 -331 -209 -379l45 -821c2 -35 -25 -64 -60 -64h-192c-35 0 -62 29 -60 64l45 821c-122 48 -209 179 -209 379c0 256 143 528 320 528s320 -272 320 -528z" />
+ <glyph glyph-name="facebook" unicode="&#xf09a;" horiz-adv-x="864"
+d="M864 1524v-264h-157c-123 0 -146 -59 -146 -144v-189h293l-39 -296h-254v-759h-306v759h-255v296h255v218c0 253 155 391 381 391c108 0 201 -8 228 -12z" />
+ <glyph glyph-name="universal-access" unicode="&#xf29a;" horiz-adv-x="1792"
+d="M1374 879c-8 34 -42 55 -77 47c-143 -34 -273 -62 -401 -62s-258 28 -401 62c-35 8 -69 -13 -77 -47c-8 -35 13 -69 47 -77c106 -25 205 -47 303 -58c-4 -338 -41 -432 -83 -540l-9 -21c-13 -33 4 -70 37 -83c7 -3 15 -4 23 -4c26 0 50 15 60 41l8 20
+c28 72 54 139 71 259h42c17 -120 43 -187 71 -259l8 -20c10 -26 34 -41 60 -41c8 0 16 1 23 4c33 13 50 50 37 83l-9 21c-42 108 -79 202 -83 540c98 11 197 33 303 58c34 8 55 42 47 77zM1024 1024c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128
+s128 57 128 128zM1600 640c0 -389 -315 -704 -704 -704s-704 315 -704 704s315 704 704 704s704 -315 704 -704zM896 1408c-423 0 -768 -345 -768 -768s345 -768 768 -768s768 345 768 768s-345 768 -768 768zM1792 640c0 -495 -401 -896 -896 -896s-896 401 -896 896
+s401 896 896 896s896 -401 896 -896z" />
+ <glyph glyph-name="cloud-download" unicode="&#xf0ed;" horiz-adv-x="1920"
+d="M1280 608c0 18 -14 32 -32 32h-224v352c0 17 -15 32 -32 32h-192c-17 0 -32 -15 -32 -32v-352h-224c-18 0 -32 -15 -32 -32c0 -8 3 -17 9 -23l352 -352c6 -6 14 -9 23 -9c8 0 17 3 23 9l351 351c6 7 10 15 10 24zM1920 384c0 -212 -172 -384 -384 -384h-1088
+c-247 0 -448 201 -448 448c0 174 101 332 258 405c-1 15 -2 29 -2 43c0 283 229 512 512 512c208 0 395 -126 474 -318c46 40 105 62 166 62c141 0 256 -115 256 -256c0 -49 -14 -97 -41 -138c174 -41 297 -196 297 -374z" />
+ <glyph glyph-name="trophy" unicode="&#xf091;" horiz-adv-x="1664"
+d="M458 653c-42 92 -74 214 -74 371h-256v-96c0 -98 133 -234 330 -275zM1536 928v96h-256c0 -157 -32 -279 -74 -371c197 41 330 177 330 275zM1664 1056v-128c0 -190 -230 -400 -542 -415c-40 -51 -77 -81 -95 -95c-53 -48 -67 -98 -67 -162s32 -128 128 -128
+s192 -64 192 -160v-64c0 -18 -14 -32 -32 -32h-832c-18 0 -32 14 -32 32v64c0 96 96 160 192 160s128 64 128 128s-14 114 -67 162c-18 14 -55 44 -95 95c-312 15 -542 225 -542 415v128c0 53 43 96 96 96h288v96c0 88 72 160 160 160h576c88 0 160 -72 160 -160v-96h288
+c53 0 96 -43 96 -96z" />
+ <glyph glyph-name="caret-up" unicode="&#xf0d8;" horiz-adv-x="1024"
+d="M1024 320c0 -35 -29 -64 -64 -64h-896c-35 0 -64 29 -64 64c0 17 7 33 19 45l448 448c12 12 28 19 45 19s33 -7 45 -19l448 -448c12 -12 19 -28 19 -45z" />
+ <glyph glyph-name="magic" unicode="&#xf0d0;" horiz-adv-x="1637"
+d="M1163 955l293 293l-107 107l-293 -293zM1610 1248c0 -17 -6 -33 -18 -45l-1286 -1286c-12 -12 -28 -18 -45 -18s-33 6 -45 18l-198 198c-12 12 -18 28 -18 45s6 33 18 45l1286 1286c12 12 28 18 45 18s33 -6 45 -18l198 -198c12 -12 18 -28 18 -45zM259 1438l98 -30
+l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM609 1276l196 -60l-196 -60l-60 -196l-60 196l-196 60l196 60l60 196zM1539 798l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM899 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98z" />
+ <glyph glyph-name="hourglass-o" unicode="&#xf250;"
+d="M1408 1408c0 -370 -177 -638 -373 -768c196 -130 373 -398 373 -768h96c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-1472c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h96c0 370 177 638 373 768c-196 130 -373 398 -373 768h-96c-18 0 -32 14 -32 32v64
+c0 18 14 32 32 32h1472c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-96zM874 700c202 76 406 343 406 708h-1024c0 -365 204 -632 406 -708c25 -9 42 -33 42 -60s-17 -51 -42 -60c-202 -76 -406 -343 -406 -708h1024c0 365 -204 632 -406 708c-25 9 -42 33 -42 60
+s17 51 42 60z" />
+ <glyph glyph-name="balance-scale" unicode="&#xf24e;" horiz-adv-x="2176"
+d="M1728 1088l-384 -704h768zM448 1088l-384 -704h768zM1269 1280c-19 -54 -63 -98 -117 -117v-1291h608c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-1344c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h608v1291c-54 19 -98 63 -117 117h-491c-18 0 -32 14 -32 32v64
+c0 18 14 32 32 32h491c27 75 97 128 181 128s154 -53 181 -128h491c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-491zM1088 1264c44 0 80 36 80 80s-36 80 -80 80s-80 -36 -80 -80s36 -80 80 -80zM2176 384c0 -206 -285 -288 -448 -288s-448 82 -448 288
+c0 39 349 657 392 735c11 20 33 33 56 33s45 -13 56 -33c43 -78 392 -696 392 -735zM896 384c0 -206 -285 -288 -448 -288s-448 82 -448 288c0 39 349 657 392 735c11 20 33 33 56 33s45 -13 56 -33c43 -78 392 -696 392 -735z" />
+ <glyph glyph-name="upload" unicode="&#xf093;" horiz-adv-x="1664"
+d="M1280 64c0 35 -29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64s64 29 64 64zM1536 64c0 35 -29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64s64 29 64 64zM1664 288v-320c0 -53 -43 -96 -96 -96h-1472c-53 0 -96 43 -96 96v320c0 53 43 96 96 96h427c27 -74 98 -128 181 -128
+h256c83 0 154 54 181 128h427c53 0 96 -43 96 -96zM1339 936c-10 -24 -33 -40 -59 -40h-256v-448c0 -35 -29 -64 -64 -64h-256c-35 0 -64 29 -64 64v448h-256c-26 0 -49 16 -59 40c-10 23 -5 51 14 69l448 448c12 13 29 19 45 19s33 -6 45 -19l448 -448
+c19 -18 24 -46 14 -69z" />
+ <glyph glyph-name="magnet" unicode="&#xf076;"
+d="M1536 704v-128c0 -408 -323 -704 -768 -704s-768 296 -768 704v128c0 35 29 64 64 64h384c35 0 64 -29 64 -64v-128c0 -183 213 -192 256 -192s256 9 256 192v128c0 35 29 64 64 64h384c35 0 64 -29 64 -64zM512 1344v-384c0 -35 -29 -64 -64 -64h-384
+c-35 0 -64 29 -64 64v384c0 35 29 64 64 64h384c35 0 64 -29 64 -64zM1536 1344v-384c0 -35 -29 -64 -64 -64h-384c-35 0 -64 29 -64 64v384c0 35 29 64 64 64h384c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="adjust" unicode="&#xf042;"
+d="M768 96v1088c-300 0 -544 -244 -544 -544s244 -544 544 -544zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="subway" unicode="&#xf239;"
+d="M1088 1536c247 0 448 -143 448 -320v-896c0 -173 -191 -313 -431 -319l213 -202c21 -20 7 -55 -22 -55h-1056c-29 0 -43 35 -22 55l213 202c-240 6 -431 146 -431 319v896c0 177 201 320 448 320h640zM288 224c88 0 160 72 160 160s-72 160 -160 160s-160 -72 -160 -160
+s72 -160 160 -160zM704 768v512h-544v-512h544zM1248 224c88 0 160 72 160 160s-72 160 -160 160s-160 -72 -160 -160s72 -160 160 -160zM1408 768v512h-576v-512h576z" />
+ <glyph glyph-name="unslpash" unicode="&#xf325;"
+d="M1052 728h484v-856h-1536v856h484v-428h568v428zM484 1408h568v-428h-568v428z" />
+ <glyph glyph-name="chevron-down" unicode="&#xf078;" horiz-adv-x="1612"
+d="M1593 728l-742 -741c-25 -25 -65 -25 -90 0l-742 741c-25 25 -25 66 0 91l166 165c25 25 65 25 90 0l531 -531l531 531c25 25 65 25 90 0l166 -165c25 -25 25 -66 0 -91z" />
+ <glyph glyph-name="location-arrow" unicode="&#xf124;" horiz-adv-x="1408"
+d="M1401 1187l-640 -1280c-11 -22 -33 -35 -57 -35c-5 0 -10 1 -15 2c-29 7 -49 32 -49 62v576h-576c-30 0 -55 20 -62 49s7 59 33 72l1280 640c9 5 19 7 29 7c17 0 33 -6 45 -19c20 -19 25 -49 12 -74z" />
+ <glyph glyph-name="check-circle" unicode="&#xf058;"
+d="M1284 802c0 17 -6 34 -18 46l-91 90c-12 12 -28 19 -45 19s-33 -7 -45 -19l-408 -407l-226 226c-12 12 -28 19 -45 19s-33 -7 -45 -19l-91 -90c-12 -12 -18 -29 -18 -46s6 -33 18 -45l362 -362c12 -12 29 -19 45 -19c17 0 34 7 46 19l543 543c12 12 18 28 18 45z
+M1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="arrow-down" unicode="&#xf063;" horiz-adv-x="1558"
+d="M1558 704c0 -34 -14 -67 -37 -90l-651 -652c-24 -23 -57 -37 -91 -37s-67 14 -90 37l-651 652c-24 23 -38 56 -38 90s14 67 38 91l74 75c24 23 57 37 91 37s67 -14 90 -37l294 -294v704c0 70 58 128 128 128h128c70 0 128 -58 128 -128v-704l294 294c23 23 56 37 90 37
+s67 -14 91 -37l75 -75c23 -24 37 -57 37 -91z" />
+ <glyph glyph-name="bicycle" unicode="&#xf206;" horiz-adv-x="2304"
+d="M762 384h-314c-53 0 -83 60 -51 102l188 251c-42 20 -88 31 -137 31c-176 0 -320 -144 -320 -320s144 -320 320 -320c155 0 284 110 314 256zM576 512h186c-12 56 -38 107 -75 148zM1056 512l288 384h-480l-99 -132c67 -66 112 -154 126 -252h165zM2176 448
+c0 176 -144 320 -320 320c-43 0 -83 -9 -121 -24l174 -260c20 -30 12 -70 -17 -89c-11 -8 -24 -11 -36 -11c-21 0 -41 10 -53 29l-174 260c-57 -58 -93 -137 -93 -225c0 -176 144 -320 320 -320s320 144 320 320zM2304 448c0 -247 -201 -448 -448 -448s-448 201 -448 448
+c0 132 58 251 149 333l-65 98l-353 -469c-12 -17 -31 -26 -51 -26h-197c-31 -217 -217 -384 -443 -384c-247 0 -448 201 -448 448s201 448 448 448c78 0 151 -20 215 -55l137 183h-224c-35 0 -64 29 -64 64s29 64 64 64h384v-128h435l-85 128h-222c-35 0 -64 29 -64 64
+s29 64 64 64h256c21 0 41 -11 53 -28l267 -400c58 28 123 44 192 44c247 0 448 -201 448 -448z" />
+ <glyph glyph-name="instagram" unicode="&#xf16d;"
+d="M1024 640c0 141 -115 256 -256 256s-256 -115 -256 -256s115 -256 256 -256s256 115 256 256zM1162 640c0 -218 -176 -394 -394 -394s-394 176 -394 394s176 394 394 394s394 -176 394 -394zM1270 1050c0 -51 -41 -92 -92 -92s-92 41 -92 92s41 92 92 92s92 -41 92 -92z
+M768 1270c-112 0 -352 9 -453 -31c-35 -14 -61 -31 -88 -58s-44 -53 -58 -88c-40 -101 -31 -341 -31 -453s-9 -352 31 -453c14 -35 31 -61 58 -88s53 -44 88 -58c101 -40 341 -31 453 -31s352 -9 453 31c35 14 61 31 88 58s44 53 58 88c40 101 31 341 31 453s9 352 -31 453
+c-14 35 -31 61 -58 88s-53 44 -88 58c-101 40 -341 31 -453 31zM1536 640c0 -106 1 -211 -5 -317c-6 -123 -34 -232 -124 -322s-199 -118 -322 -124c-106 -6 -211 -5 -317 -5s-211 -1 -317 5c-123 6 -232 34 -322 124s-118 199 -124 322c-6 106 -5 211 -5 317s-1 211 5 317
+c6 123 34 232 124 322s199 118 322 124c106 6 211 5 317 5s211 1 317 -5c123 -6 232 -34 322 -124s118 -199 124 -322c6 -106 5 -211 5 -317z" />
+ <glyph glyph-name="caret-square-o-up" unicode="&#xf151;"
+d="M1145 419c-11 -22 -33 -35 -57 -35h-640c-24 0 -46 13 -57 35c-11 21 -9 47 5 66l320 448c12 17 31 27 52 27s40 -10 52 -27l320 -448c14 -19 16 -45 5 -66zM1280 160v960c0 17 -15 32 -32 32h-960c-17 0 -32 -15 -32 -32v-960c0 -17 15 -32 32 -32h960c17 0 32 15 32 32
+zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="crop" unicode="&#xf125;" horiz-adv-x="1664"
+d="M557 256h595v595zM512 301l595 595h-595v-595zM1664 224v-192c0 -18 -14 -32 -32 -32h-224v-224c0 -18 -14 -32 -32 -32h-192c-18 0 -32 14 -32 32v224h-864c-18 0 -32 14 -32 32v864h-224c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h224v224c0 18 14 32 32 32h192
+c18 0 32 -14 32 -32v-224h851l246 247c13 12 33 12 46 0c12 -13 12 -33 0 -46l-247 -246v-851h224c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="external-link" unicode="&#xf08e;" horiz-adv-x="1792"
+d="M1408 608v-320c0 -159 -129 -288 -288 -288h-832c-159 0 -288 129 -288 288v832c0 159 129 288 288 288h704c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-704c-88 0 -160 -72 -160 -160v-832c0 -88 72 -160 160 -160h832c88 0 160 72 160 160v320c0 18 14 32 32 32
+h64c18 0 32 -14 32 -32zM1792 1472v-512c0 -35 -29 -64 -64 -64c-17 0 -33 7 -45 19l-176 176l-652 -652c-6 -6 -15 -10 -23 -10s-17 4 -23 10l-114 114c-6 6 -10 15 -10 23s4 17 10 23l652 652l-176 176c-12 12 -19 28 -19 45c0 35 29 64 64 64h512c35 0 64 -29 64 -64z
+" />
+ <glyph glyph-name="arrow-circle-down" unicode="&#xf0ab;"
+d="M1284 639c0 17 -6 33 -18 45l-91 91c-12 12 -28 18 -45 18s-33 -6 -45 -18l-189 -189v502c0 35 -29 64 -64 64h-128c-35 0 -64 -29 -64 -64v-502l-189 189c-12 12 -28 19 -45 19s-33 -7 -45 -19l-91 -91c-12 -12 -18 -28 -18 -45s6 -33 18 -45l362 -362l91 -91
+c12 -12 28 -18 45 -18s33 6 45 18l91 91l362 362c12 12 18 28 18 45zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="font-awesome" unicode="&#xf2b4;" horiz-adv-x="1499"
+d="M1499 1024v-839c0 -31 -20 -54 -49 -62c-107 -32 -227 -52 -338 -52c-150 0 -277 59 -443 59c-123 0 -250 -20 -370 -48v-338h-160v1368c-84 33 -139 115 -139 205c0 121 98 219 219 219s219 -98 219 -219c0 -90 -55 -172 -139 -205v-68c112 26 228 44 343 44
+c66 0 132 -5 198 -15c86 -13 173 -43 261 -43c55 0 111 7 165 18c41 8 135 40 169 40c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="paper-plane" unicode="&#xf1d8;" horiz-adv-x="1792"
+d="M1764 1525c21 -15 31 -39 27 -64l-256 -1536c-3 -19 -15 -35 -32 -45c-9 -5 -20 -8 -31 -8c-8 0 -16 2 -24 5l-453 185l-242 -295c-12 -15 -30 -23 -49 -23c-7 0 -15 1 -22 4c-25 9 -42 33 -42 60v349l864 1059l-1069 -925l-395 162c-23 9 -38 30 -40 55
+c-1 24 11 47 32 59l1664 960c10 6 21 9 32 9c13 0 26 -4 36 -11z" />
+ <glyph glyph-name="meanpath" unicode="&#xf20c;"
+d="M1311 694v-114c0 -32 -19 -52 -51 -52h-202c-32 0 -52 20 -52 52v114c0 32 20 52 52 52h202c32 0 51 -20 51 -52zM821 464v250c0 71 -47 118 -118 118h-133c-45 0 -78 -19 -96 -52c-18 33 -51 52 -96 52h-130c-70 0 -118 -47 -118 -118v-250c0 -15 7 -22 21 -22h55
+c15 0 22 7 22 22v230c0 32 19 52 52 52h94c32 0 52 -20 52 -52v-230c0 -15 6 -22 21 -22h54c15 0 22 7 22 22v230c0 32 20 52 52 52h97c32 0 51 -20 51 -52v-230c0 -15 7 -22 22 -22h55c14 0 21 7 21 22zM1410 560v154c0 71 -48 118 -119 118h-264c-71 0 -119 -47 -119 -118
+v-410c0 -15 8 -21 22 -21h55c15 0 21 6 21 21v180c19 -26 49 -42 94 -42h191c71 0 119 48 119 118zM1536 1176v-1072c0 -128 -104 -232 -232 -232h-1072c-128 0 -232 104 -232 232v1072c0 128 104 232 232 232h1072c128 0 232 -104 232 -232z" />
+ <glyph glyph-name="long-arrow-left" unicode="&#xf177;" horiz-adv-x="1728"
+d="M1728 736v-192c0 -18 -14 -32 -32 -32h-1248v-224c0 -13 -7 -24 -19 -29s-25 -3 -35 5l-384 350c-6 6 -10 14 -10 23s4 18 10 24l384 354c10 9 23 11 35 6c11 -5 19 -16 19 -29v-224h1248c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="download" unicode="&#xf019;" horiz-adv-x="1664"
+d="M1280 192c0 35 -29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64s64 29 64 64zM1536 192c0 35 -29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64s64 29 64 64zM1664 416v-320c0 -53 -43 -96 -96 -96h-1472c-53 0 -96 43 -96 96v320c0 53 43 96 96 96h465l135 -136
+c37 -36 85 -56 136 -56s99 20 136 56l136 136h464c53 0 96 -43 96 -96zM1339 985c10 -24 5 -52 -14 -70l-448 -448c-12 -13 -29 -19 -45 -19s-33 6 -45 19l-448 448c-19 18 -24 46 -14 70c10 23 33 39 59 39h256v448c0 35 29 64 64 64h256c35 0 64 -29 64 -64v-448h256
+c26 0 49 -16 59 -39z" />
+ <glyph glyph-name="bold" unicode="&#xf032;" horiz-adv-x="1408"
+d="M555 15c44 -19 92 -32 140 -32c228 0 376 91 376 335c0 62 -8 127 -41 180c-93 150 -227 158 -388 158c-30 0 -73 0 -101 -10c0 -106 -1 -212 -1 -317c0 -69 -9 -256 15 -314zM541 761c36 -6 73 -7 109 -7c206 0 353 58 353 289c0 195 -173 262 -340 262
+c-44 0 -87 -6 -130 -13c0 -101 8 -202 8 -303c0 -53 -1 -106 -1 -159c0 -23 0 -46 1 -69zM0 -128l2 94c64 16 129 17 191 43c35 59 30 163 30 230c0 22 2 978 -22 1025c-15 29 -162 36 -195 40l-4 83c238 4 476 21 713 21c45 0 91 -1 136 -1c226 0 475 -108 475 -368
+c0 -179 -136 -246 -277 -310c190 -43 359 -172 359 -382c0 -344 -313 -458 -606 -458c-88 0 -176 6 -264 6c-179 0 -360 -16 -538 -23z" />
+ <glyph glyph-name="caret-down" unicode="&#xf0d7;" horiz-adv-x="1024"
+d="M1024 832c0 -17 -7 -33 -19 -45l-448 -448c-12 -12 -28 -19 -45 -19s-33 7 -45 19l-448 448c-12 12 -19 28 -19 45c0 35 29 64 64 64h896c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="chevron-left" unicode="&#xf053;" horiz-adv-x="1036"
+d="M1017 1235l-531 -531l531 -531c25 -25 25 -65 0 -90l-166 -166c-25 -25 -65 -25 -90 0l-742 742c-25 25 -25 65 0 90l742 742c25 25 65 25 90 0l166 -166c25 -25 25 -65 0 -90z" />
+ <glyph glyph-name="venus" unicode="&#xf221;" horiz-adv-x="1152"
+d="M1152 960c0 -296 -224 -540 -512 -572v-260h224c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-224v-224c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v224h-224c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h224v260c-303 33 -535 302 -510 619
+c22 272 238 495 508 525c348 39 642 -232 642 -572zM128 960c0 -247 201 -448 448 -448s448 201 448 448s-201 448 -448 448s-448 -201 -448 -448z" />
+ <glyph glyph-name="font" unicode="&#xf031;" horiz-adv-x="1664"
+d="M725 977l-170 -450c99 -1 198 -4 297 -4c19 0 38 1 57 2c-52 152 -113 307 -184 452zM0 -128l2 79c94 29 196 9 238 117l237 616l280 724h128c4 -7 8 -14 11 -21l205 -480c75 -177 144 -356 220 -532c45 -104 80 -211 130 -313c7 -16 21 -46 35 -57
+c33 -26 125 -32 172 -50c3 -19 6 -38 6 -57c0 -9 -1 -17 -1 -26c-127 0 -254 16 -381 16c-131 0 -262 -11 -393 -15c0 26 1 52 4 78l131 28c27 6 80 13 80 50c0 36 -129 333 -145 374l-450 2c-26 -58 -127 -320 -127 -358c0 -77 147 -80 204 -88c1 -19 1 -38 1 -58
+c0 -9 -1 -18 -2 -27c-116 0 -233 20 -349 20c-14 0 -34 -6 -48 -8c-63 -11 -125 -14 -188 -14z" />
+ <glyph glyph-name="pinterest" unicode="&#xf0d2;"
+d="M1536 640c0 -424 -344 -768 -768 -768c-76 0 -148 11 -218 32c29 46 62 105 78 164c0 0 9 34 54 211c26 -51 104 -96 187 -96c247 0 415 225 415 527c0 227 -193 440 -487 440c-364 0 -548 -262 -548 -480c0 -132 50 -250 157 -294c17 -7 33 0 38 20c4 13 12 47 16 61
+c5 20 3 26 -11 43c-31 37 -51 84 -51 151c0 194 145 368 378 368c206 0 320 -126 320 -295c0 -221 -98 -408 -244 -408c-80 0 -140 66 -121 148c23 97 68 202 68 272c0 63 -34 116 -104 116c-82 0 -148 -85 -148 -199c0 0 0 -73 25 -122c-84 -356 -99 -418 -99 -418
+c-14 -58 -15 -123 -13 -177c-271 119 -460 389 -460 704c0 424 344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="sun" unicode="&#xf329;" horiz-adv-x="1707"
+d="M1706 363c-3 -10 -11 -17 -20 -20l-292 -96v-306c0 -10 -5 -20 -13 -26c-9 -6 -19 -8 -29 -4l-292 94l-180 -248c-6 -8 -16 -13 -26 -13s-20 5 -26 13l-180 248l-292 -94c-10 -4 -20 -2 -29 4c-8 6 -13 16 -13 26v306l-292 96c-9 3 -17 10 -20 20s-2 21 4 29l180 248
+l-180 248c-6 9 -7 19 -4 29s11 17 20 20l292 96v306c0 10 5 20 13 26c9 6 19 8 29 4l292 -94l180 248c12 16 40 16 52 0l180 -248l292 94c10 4 20 2 29 -4c8 -6 13 -16 13 -26v-306l292 -96c9 -3 17 -10 20 -20s2 -20 -4 -29l-180 -248l180 -248c6 -8 7 -19 4 -29z" />
+ <glyph glyph-name="cart-plus" unicode="&#xf217;" horiz-adv-x="1664"
+d="M1216 832c0 35 -29 64 -64 64h-128v128c0 35 -29 64 -64 64s-64 -29 -64 -64v-128h-128c-35 0 -64 -29 -64 -64s29 -64 64 -64h128v-128c0 -35 29 -64 64 -64s64 29 64 64v128h128c35 0 64 29 64 64zM640 0c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128
+s128 -57 128 -128zM1536 0c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128s128 -57 128 -128zM1664 1088v-512c0 -32 -24 -60 -57 -64l-1044 -122c4 -22 13 -47 13 -70s-14 -44 -24 -64h920c35 0 64 -29 64 -64s-29 -64 -64 -64h-1024c-35 0 -64 29 -64 64
+c0 31 47 108 61 137l-177 823h-204c-35 0 -64 29 -64 64s29 64 64 64h256c68 0 69 -80 79 -128h1201c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="folder-open-o" unicode="&#xf115;" horiz-adv-x="1909"
+d="M1781 605c0 28 -31 35 -53 35h-1088c-53 0 -123 -33 -157 -74l-294 -363c-9 -12 -18 -25 -18 -40c0 -28 31 -35 53 -35h1088c53 0 123 33 157 75l294 363c9 11 18 24 18 39zM640 768h768v160c0 53 -43 96 -96 96h-576c-53 0 -96 43 -96 96v64c0 53 -43 96 -96 96h-320
+c-53 0 -96 -43 -96 -96v-853l256 315c58 71 165 122 256 122zM1909 605c0 -44 -19 -86 -46 -120l-295 -363c-57 -70 -166 -122 -256 -122h-1088c-123 0 -224 101 -224 224v960c0 123 101 224 224 224h320c123 0 224 -101 224 -224v-32h544c123 0 224 -101 224 -224v-160h192
+c68 0 136 -31 166 -95c10 -21 15 -44 15 -68z" />
+ <glyph glyph-name="tachometer" unicode="&#xf0e4;" horiz-adv-x="1792"
+d="M384 384c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM576 832c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM1004 351l101 382c8 34 -12 69 -46 78s-69 -12 -78 -46l-101 -382
+c-79 -6 -148 -61 -170 -142c-27 -103 35 -208 137 -235c103 -27 208 35 235 137c21 81 -13 163 -78 208zM1664 384c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM1024 1024c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128
+s128 57 128 128zM1472 832c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM1792 384c0 -172 -49 -338 -141 -483c-12 -18 -32 -29 -54 -29h-1402c-22 0 -42 11 -54 29c-92 144 -141 311 -141 483c0 494 402 896 896 896s896 -402 896 -896z
+" />
+ <glyph glyph-name="creative-commons" unicode="&#xf25e;" horiz-adv-x="1792"
+d="M605 303c-200 0 -344 142 -344 337c0 192 147 337 344 337c159 0 240 -92 243 -96c9 -11 10 -27 2 -39l-53 -78c-5 -8 -14 -13 -24 -14s-19 3 -26 10c0 0 -55 56 -138 56c-99 0 -170 -73 -170 -175c0 -103 73 -177 174 -177c92 0 155 67 156 67c7 8 17 12 27 11
+c10 -2 20 -8 24 -17l45 -82c7 -11 5 -26 -3 -36c-4 -4 -93 -104 -257 -104zM1235 303c-200 0 -344 142 -344 337c0 192 148 337 344 337c159 0 240 -92 243 -96c9 -11 10 -27 2 -39l-53 -78c-5 -8 -14 -13 -24 -14s-19 3 -26 10c0 0 -54 56 -138 56
+c-99 0 -170 -73 -170 -175c0 -103 73 -177 174 -177c92 0 155 67 156 67c7 8 17 12 27 11c11 -2 20 -8 25 -17l45 -82c6 -11 4 -26 -4 -36c-4 -4 -92 -104 -257 -104zM896 1376c-406 0 -736 -330 -736 -736s330 -736 736 -736s736 330 736 736s-330 736 -736 736zM896 1536
+c495 0 896 -401 896 -896s-401 -896 -896 -896s-896 401 -896 896s401 896 896 896z" />
+ <glyph glyph-name="clipboard" unicode="&#xf0ea;" horiz-adv-x="1792"
+d="M768 -128h896v640h-416c-53 0 -96 43 -96 96v416h-384v-1152zM1024 1312v64c0 17 -15 32 -32 32h-704c-17 0 -32 -15 -32 -32v-64c0 -17 15 -32 32 -32h704c17 0 32 15 32 32zM1280 640h299l-299 299v-299zM1792 512v-672c0 -53 -43 -96 -96 -96h-960
+c-53 0 -96 43 -96 96v160h-544c-53 0 -96 43 -96 96v1344c0 53 43 96 96 96h1088c53 0 96 -43 96 -96v-328c13 -8 25 -17 36 -28l408 -408c38 -38 68 -111 68 -164z" />
+ <glyph glyph-name="eercast" unicode="&#xf2da;" horiz-adv-x="1719"
+d="M1304 752c35 54 -6 191 -128 272c-121 81 -276 75 -312 21c-35 -53 40 -19 177 -70c226 -84 228 -277 263 -223zM1667 178c-283 -696 -1558 -520 -1531 383c3 115 35 192 68 302c-211 -864 966 -1367 1449 -685c18 25 23 23 14 0zM1428 627c0 -283 -228 -513 -509 -513
+s-509 230 -509 513s228 513 509 513s509 -230 509 -513zM1715 915c-356 808 -1826 510 -1663 -589c-338 1101 1055 1606 1570 822c42 -64 90 -176 93 -233zM1653 573c17 338 -217 569 -533 656c-5 0 -27 9 14 13c772 -26 800 -1260 -41 -1274c274 76 543 266 560 605z" />
+ <glyph glyph-name="bar-chart" unicode="&#xf080;" horiz-adv-x="2048"
+d="M640 640v-512h-256v512h256zM1024 1152v-1024h-256v1024h256zM2048 0v-128h-2048v1536h128v-1408h1920zM1408 896v-768h-256v768h256zM1792 1280v-1152h-256v1152h256z" />
+ <glyph glyph-name="reply" unicode="&#xf112;" horiz-adv-x="1792"
+d="M1792 416c0 -140 -70 -323 -127 -451c-11 -23 -22 -55 -37 -76c-7 -10 -14 -17 -28 -17c-20 0 -32 16 -32 35c0 16 4 34 5 50c3 41 5 82 5 123c0 477 -283 560 -714 560h-224v-256c0 -35 -29 -64 -64 -64c-17 0 -33 7 -45 19l-512 512c-12 12 -19 28 -19 45s7 33 19 45
+l512 512c12 12 28 19 45 19c35 0 64 -29 64 -64v-256h224c328 0 736 -58 875 -403c42 -106 53 -221 53 -333z" />
+ <glyph glyph-name="hourglass-half" unicode="&#xf252;"
+d="M1408 1408c0 -370 -177 -638 -373 -768c196 -130 373 -398 373 -768h96c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-1472c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h96c0 370 177 638 373 768c-196 130 -373 398 -373 768h-96c-18 0 -32 14 -32 32v64
+c0 18 14 32 32 32h1472c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-96zM1280 1408h-1024c0 -146 33 -275 85 -384h854c52 109 85 238 85 384zM1223 192c-74 193 -207 330 -340 384h-230c-133 -54 -266 -191 -340 -384h910z" />
+ <glyph glyph-name="microchip" unicode="&#xf2db;"
+d="M192 256v-128h-112c-9 0 -16 7 -16 16v16h-48c-9 0 -16 7 -16 16v32c0 9 7 16 16 16h48v16c0 9 7 16 16 16h112zM192 512v-128h-112c-9 0 -16 7 -16 16v16h-48c-9 0 -16 7 -16 16v32c0 9 7 16 16 16h48v16c0 9 7 16 16 16h112zM192 768v-128h-112c-9 0 -16 7 -16 16v16
+h-48c-9 0 -16 7 -16 16v32c0 9 7 16 16 16h48v16c0 9 7 16 16 16h112zM192 1024v-128h-112c-9 0 -16 7 -16 16v16h-48c-9 0 -16 7 -16 16v32c0 9 7 16 16 16h48v16c0 9 7 16 16 16h112zM192 1280v-128h-112c-9 0 -16 7 -16 16v16h-48c-9 0 -16 7 -16 16v32c0 9 7 16 16 16
+h48v16c0 9 7 16 16 16h112zM1280 1440v-1472c0 -53 -43 -96 -96 -96h-832c-53 0 -96 43 -96 96v1472c0 53 43 96 96 96h832c53 0 96 -43 96 -96zM1536 208v-32c0 -9 -7 -16 -16 -16h-48v-16c0 -9 -7 -16 -16 -16h-112v128h112c9 0 16 -7 16 -16v-16h48c9 0 16 -7 16 -16z
+M1536 464v-32c0 -9 -7 -16 -16 -16h-48v-16c0 -9 -7 -16 -16 -16h-112v128h112c9 0 16 -7 16 -16v-16h48c9 0 16 -7 16 -16zM1536 720v-32c0 -9 -7 -16 -16 -16h-48v-16c0 -9 -7 -16 -16 -16h-112v128h112c9 0 16 -7 16 -16v-16h48c9 0 16 -7 16 -16zM1536 976v-32
+c0 -9 -7 -16 -16 -16h-48v-16c0 -9 -7 -16 -16 -16h-112v128h112c9 0 16 -7 16 -16v-16h48c9 0 16 -7 16 -16zM1536 1232v-32c0 -9 -7 -16 -16 -16h-48v-16c0 -9 -7 -16 -16 -16h-112v128h112c9 0 16 -7 16 -16v-16h48c9 0 16 -7 16 -16z" />
+ <glyph glyph-name="graduation-cap" unicode="&#xf19d;" horiz-adv-x="2304"
+d="M1774 700l18 -316c8 -141 -287 -256 -640 -256s-648 115 -640 256l18 316l574 -181c16 -5 32 -7 48 -7s32 2 48 7zM2304 1024c0 -14 -9 -26 -22 -31l-1120 -352c-4 -1 -7 -1 -10 -1s-6 0 -10 1l-652 206c-57 -45 -97 -155 -105 -290c38 -22 63 -62 63 -109
+c0 -45 -23 -84 -58 -107l58 -433c1 -9 -2 -18 -8 -25s-15 -11 -24 -11h-192c-9 0 -18 4 -24 11s-9 16 -8 25l58 433c-35 23 -58 62 -58 107c0 48 27 89 65 111c6 117 36 243 98 330l-333 104c-13 5 -22 17 -22 31s9 26 22 31l1120 352c4 1 7 1 10 1s6 0 10 -1l1120 -352
+c13 -5 22 -17 22 -31z" />
+ <glyph glyph-name="info-circle" unicode="&#xf05a;"
+d="M1024 160v160c0 18 -14 32 -32 32h-96v512c0 18 -14 32 -32 32h-320c-18 0 -32 -14 -32 -32v-160c0 -18 14 -32 32 -32h96v-320h-96c-18 0 -32 -14 -32 -32v-160c0 -18 14 -32 32 -32h448c18 0 32 14 32 32zM896 1056v160c0 18 -14 32 -32 32h-192c-18 0 -32 -14 -32 -32
+v-160c0 -18 14 -32 32 -32h192c18 0 32 14 32 32zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="barcode" unicode="&#xf02a;" horiz-adv-x="2176"
+d="M0 1404h128v-1532h-128v1532zM2048 1408h128v-1536h-128v1536zM256 1408h128v-1280h-128v1280zM512 1408h256v-1280h-256v1280zM1280 1408h256v-1280h-256v1280zM1792 1408h128v-1280h-128v1280zM1024 1408h128v-1280h-128v1280zM256 0h128v-128h-128v128zM512 0h128
+v-128h-128v128zM768 0h128v-128h-128v128zM1024 0h128v-128h-128v128zM1280 0h128v-128h-128v128zM1536 0h128v-128h-128v128zM1792 0h128v-128h-128v128z" />
+ <glyph glyph-name="exchange" unicode="&#xf0ec;" horiz-adv-x="1792"
+d="M1792 352v-192c0 -17 -15 -32 -32 -32h-1376v-192c0 -17 -14 -32 -32 -32c-9 0 -17 4 -24 10l-319 320c-6 6 -9 14 -9 22c0 9 3 17 9 23l320 320c6 6 15 9 23 9c17 0 32 -14 32 -32v-192h1376c17 0 32 -14 32 -32zM1792 896c0 -8 -3 -17 -9 -23l-320 -320
+c-6 -6 -15 -9 -23 -9c-17 0 -32 15 -32 32v192h-1376c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h1376v192c0 18 14 32 32 32c9 0 17 -4 24 -10l319 -319c6 -6 9 -15 9 -23z" />
+ <glyph glyph-name="hand-o-up" unicode="&#xf0a6;"
+d="M1280 -64c0 35 -29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64s64 29 64 64zM1408 700c0 113 -46 189 -167 189c-19 0 -38 -2 -56 -5c-23 42 -80 65 -126 65c-24 0 -48 -6 -69 -18c-32 34 -72 53 -119 53c-32 0 -79 -14 -103 -35v331c0 69 -59 128 -128 128
+c-68 0 -128 -61 -128 -128v-576c-63 0 -128 96 -256 96c-96 0 -128 -75 -128 -160c0 -28 116 -79 139 -90c22 -12 44 -24 65 -37c53 -33 99 -71 145 -112c73 -64 163 -135 163 -241v-32h640v32c0 175 128 346 128 540zM1536 705c0 -112 -31 -218 -69 -322
+c-22 -61 -59 -160 -59 -223v-288c0 -71 -57 -128 -128 -128h-640c-71 0 -128 57 -128 128v288c0 48 -86 116 -119 145c-41 36 -82 70 -129 100c-93 58 -264 101 -264 235c0 159 87 288 256 288c44 0 87 -7 128 -22v374c0 138 117 256 255 256c140 0 257 -116 257 -256v-169
+c42 -3 82 -16 119 -37c14 2 29 3 43 3c64 0 128 -21 178 -60c189 2 300 -127 300 -312z" />
+ <glyph glyph-name="pause" unicode="&#xf04c;"
+d="M1536 1344v-1408c0 -35 -29 -64 -64 -64h-512c-35 0 -64 29 -64 64v1408c0 35 29 64 64 64h512c35 0 64 -29 64 -64zM640 1344v-1408c0 -35 -29 -64 -64 -64h-512c-35 0 -64 29 -64 64v1408c0 35 29 64 64 64h512c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="github-square" unicode="&#xf092;"
+d="M519 336c2 3 1 9 -3 13c-5 4 -11 5 -14 2c-2 -3 -1 -9 3 -13c5 -4 11 -5 14 -2zM491 377c-3 4 -8 6 -12 4c-3 -2 -3 -8 0 -12c4 -5 9 -7 12 -5s3 8 0 13zM450 417c1 2 -1 6 -5 8c-3 1 -7 1 -8 -2c-2 -3 0 -6 4 -8c4 -1 8 -1 9 2zM471 394c2 2 2 7 -2 10c-3 4 -8 5 -10 3
+c-3 -3 -2 -7 1 -11c3 -3 8 -5 11 -2zM557 319c1 4 -3 9 -9 11s-11 0 -13 -4c-1 -4 3 -9 9 -11s11 0 13 4zM599 316c0 4 -5 8 -12 8c-6 0 -10 -4 -10 -8s5 -8 11 -8s11 4 11 8zM638 323c-1 4 -7 6 -13 5s-10 -5 -9 -9s6 -7 12 -6s10 6 10 10zM1280 640
+c0 283 -229 512 -512 512s-512 -229 -512 -512c0 -226 147 -418 350 -486c26 -5 35 11 35 25c0 12 0 52 -1 95c0 0 -142 -31 -172 61c0 0 -23 59 -57 74c0 0 -46 32 4 32c0 0 50 -4 78 -53c45 -79 120 -56 149 -43c5 33 18 56 33 69c-114 13 -234 57 -234 253
+c0 56 20 101 53 137c-5 13 -23 65 5 136c43 13 141 -53 141 -53c41 12 84 17 128 17s87 -5 128 -17c0 0 98 66 141 53c28 -71 10 -123 5 -136c33 -36 53 -81 53 -137c0 -197 -120 -240 -234 -253c18 -16 35 -47 35 -95c0 -68 -1 -123 -1 -140c0 -14 9 -30 35 -25
+c203 68 350 260 350 486zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="search" unicode="&#xf002;" horiz-adv-x="1664"
+d="M1152 704c0 247 -201 448 -448 448s-448 -201 -448 -448s201 -448 448 -448s448 201 448 448zM1664 -128c0 -70 -58 -128 -128 -128c-34 0 -67 14 -90 38l-343 342c-117 -81 -257 -124 -399 -124c-389 0 -704 315 -704 704s315 704 704 704s704 -315 704 -704
+c0 -142 -43 -282 -124 -399l343 -343c23 -23 37 -56 37 -90z" />
+ <glyph glyph-name="mixcloud" unicode="&#xf289;" horiz-adv-x="2304"
+d="M1645 438c0 80 -51 148 -121 175c-5 -31 -13 -62 -23 -92c-10 -32 -40 -52 -72 -52c-8 0 -16 1 -24 3c-41 14 -62 57 -49 97c15 46 23 94 23 143c0 250 -204 454 -455 454c-180 0 -342 -107 -414 -267c70 -18 135 -54 188 -106c30 -30 30 -79 0 -109s-79 -30 -109 0
+c-48 48 -112 75 -180 75c-141 0 -256 -114 -256 -255s115 -255 256 -255h1046c105 0 190 85 190 189zM1798 438c0 -189 -154 -342 -343 -342h-1046c-226 0 -409 183 -409 408c0 205 152 374 349 403c83 244 314 412 575 412c315 0 575 -241 605 -548
+c153 -33 269 -170 269 -333zM2048 438c0 -114 -33 -224 -97 -319c-15 -22 -39 -33 -64 -33c-15 0 -30 4 -43 13c-35 23 -44 71 -20 106c47 69 71 149 71 233c0 83 -24 164 -71 233c-24 35 -15 82 20 106s83 14 107 -21c64 -94 97 -204 97 -318zM2304 438
+c0 -159 -46 -312 -134 -443c-15 -22 -39 -34 -64 -34c-14 0 -29 4 -42 13c-35 24 -45 71 -21 106c70 106 108 230 108 358s-38 252 -108 357c-24 35 -14 83 21 106c35 24 82 15 106 -21c88 -130 134 -283 134 -442z" />
+ <glyph glyph-name="snowflake-o" unicode="&#xf2dc;" horiz-adv-x="1570"
+d="M1519 419l-167 -33l186 -107c30 -17 41 -57 23 -87s-57 -41 -87 -23l-186 106l55 -160c28 -80 -94 -121 -121 -42l-102 300l-271 156v-313l208 -238c56 -63 -41 -148 -96 -84l-112 128v-214c0 -35 -29 -64 -64 -64s-64 29 -64 64v214l-112 -128c-55 -64 -152 21 -96 84
+l208 238v313l-271 -156l-102 -300c-27 -79 -149 -38 -121 42l55 160l-186 -106c-30 -18 -69 -7 -87 23s-7 70 23 87l186 107l-167 33c-83 17 -58 142 25 126l310 -62l271 157l-271 157l-310 -62c-4 -1 -9 -1 -13 -1c-76 0 -87 112 -12 127l167 33l-186 107
+c-30 17 -41 57 -23 87c18 31 57 41 87 23l186 -106l-55 160c-28 80 94 121 121 42l102 -300l271 -156v313l-208 238c-56 63 41 148 96 84l112 -128v214c0 35 29 64 64 64s64 -29 64 -64v-214l112 128c55 64 152 -21 96 -84l-208 -238v-313l271 156l102 300
+c27 79 149 38 121 -42l-55 -160l186 106c30 18 69 7 87 -23s7 -70 -23 -87l-186 -107l167 -33c75 -15 64 -127 -12 -127c-4 0 -9 0 -13 1l-310 62l-271 -157l271 -157l310 62c83 16 108 -109 25 -126z" />
+ <glyph glyph-name="flask" unicode="&#xf0c3;" horiz-adv-x="1458"
+d="M1424 88c75 -119 22 -216 -119 -216h-1152c-141 0 -194 97 -119 216l503 793v399h-64c-35 0 -64 29 -64 64s29 64 64 64h512c35 0 64 -29 64 -64s-29 -64 -64 -64h-64v-399zM645 813l-272 -429h712l-272 429l-20 31v436h-128v-436z" />
+ <glyph glyph-name="pinterest-square" unicode="&#xf0d3;"
+d="M1248 1408c159 0 288 -129 288 -288v-960c0 -159 -129 -288 -288 -288h-725c33 47 87 128 108 210c0 0 9 34 53 209c27 -51 104 -95 186 -95c244 0 410 223 410 521c0 225 -191 435 -481 435c-361 0 -543 -259 -543 -475c0 -130 50 -246 156 -290c17 -7 33 0 38 19
+c3 13 11 47 15 61c5 19 3 26 -11 42c-30 37 -50 83 -50 150c0 192 144 363 374 363c204 0 316 -124 316 -291c0 -219 -97 -404 -241 -404c-79 0 -139 66 -120 147c23 96 67 200 67 269c0 62 -33 114 -102 114c-81 0 -146 -84 -146 -196c0 0 0 -72 24 -121
+c-83 -352 -98 -414 -98 -414c-22 -92 -13 -199 -7 -254h-183c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960z" />
+ <glyph glyph-name="fast-backward" unicode="&#xf049;" horiz-adv-x="1792"
+d="M1747 1395c25 25 45 16 45 -19v-1472c0 -35 -20 -44 -45 -19l-710 710c-6 6 -10 12 -13 19v-710c0 -35 -20 -44 -45 -19l-710 710c-6 6 -10 12 -13 19v-678c0 -35 -29 -64 -64 -64h-128c-35 0 -64 29 -64 64v1408c0 35 29 64 64 64h128c35 0 64 -29 64 -64v-678
+c3 7 7 13 13 19l710 710c25 25 45 16 45 -19v-710c3 7 7 13 13 19z" />
+ <glyph glyph-name="volume-control-phone" unicode="&#xf2a0;" horiz-adv-x="1408"
+d="M617 -153c0 -34 -90 -84 -119 -95c-15 -6 -30 -8 -45 -8c-33 0 -66 9 -98 18c-164 49 -203 149 -268 290c-70 151 -87 295 -87 460s17 309 87 460c65 141 104 241 268 290c32 9 65 18 98 18c15 0 30 -2 45 -8c29 -11 119 -61 119 -95c0 -24 -53 -194 -64 -234
+c-6 -25 -8 -66 -27 -84c-13 -12 -34 -14 -51 -14c-47 0 -94 11 -141 11c-14 0 -35 -1 -47 -11c-16 -13 -24 -58 -30 -78c-24 -83 -37 -168 -37 -255s13 -172 37 -255c6 -20 14 -65 30 -78c12 -10 33 -11 47 -11c47 0 94 11 141 11c17 0 38 -2 51 -14c19 -18 21 -59 27 -84
+c11 -40 64 -210 64 -234zM776 760c-17 0 -33 7 -45 19c-25 25 -26 66 0 91c24 24 37 56 37 90s-13 66 -37 91c-26 25 -25 65 0 90s65 25 90 0c48 -48 75 -113 75 -181s-27 -133 -75 -181c-13 -12 -29 -19 -45 -19zM957 579c-17 0 -33 6 -45 19c-25 25 -25 65 0 90
+c72 73 112 169 112 272s-40 199 -112 272c-25 25 -25 65 0 90s65 25 90 0c97 -97 150 -225 150 -362s-53 -265 -150 -362c-12 -13 -29 -19 -45 -19zM1138 398c-17 0 -33 6 -45 19c-25 25 -25 65 0 90c120 121 187 282 187 453s-67 332 -187 453c-25 25 -25 65 0 90
+s65 25 90 0c145 -145 225 -338 225 -543s-80 -398 -225 -543c-12 -13 -29 -19 -45 -19z" />
+ <glyph glyph-name="biometric" unicode="&#xf32b;" horiz-adv-x="2304"
+d="M1419 640c0 -147 -120 -267 -267 -267s-267 120 -267 267s120 267 267 267s267 -120 267 -267zM0 1222h2304v-521h-769c-29 185 -190 327 -383 327s-354 -142 -383 -327h-769v521zM0 579h769c29 -185 190 -327 383 -327s354 142 383 327h769v-521h-2304v521z" />
+ <glyph glyph-name="tasks" unicode="&#xf0ae;" horiz-adv-x="1792"
+d="M1024 128h640v128h-640v-128zM640 640h1024v128h-1024v-128zM1280 1152h384v128h-384v-128zM1792 320v-256c0 -35 -29 -64 -64 -64h-1664c-35 0 -64 29 -64 64v256c0 35 29 64 64 64h1664c35 0 64 -29 64 -64zM1792 832v-256c0 -35 -29 -64 -64 -64h-1664
+c-35 0 -64 29 -64 64v256c0 35 29 64 64 64h1664c35 0 64 -29 64 -64zM1792 1344v-256c0 -35 -29 -64 -64 -64h-1664c-35 0 -64 29 -64 64v256c0 35 29 64 64 64h1664c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="firefox" unicode="&#xf269;" horiz-adv-x="1792"
+d="M903 -256c-386 0 -693 226 -834 549c-158 359 -32 934 249 1188l-11 -281c14 18 121 23 138 0c58 111 245 194 395 197c-57 -48 -189 -223 -178 -312c73 -23 185 -24 244 -28c18 -10 15 -71 -21 -121c0 0 -47 -65 -174 -88l15 -189l-139 67c-45 -114 63 -215 175 -196
+c124 21 168 102 255 97c86 -5 120 -53 109 -98c0 0 -14 -54 -107 -45c-79 -125 -184 -180 -354 -165c258 -214 606 -20 694 155c88 174 11 433 -77 506c104 -45 176 -91 214 -192c20 224 -83 478 -267 627c346 -101 557 -369 563 -797s-379 -874 -889 -874z" />
+ <glyph glyph-name="apple" unicode="&#xf179;" horiz-adv-x="1393"
+d="M1393 321c-25 -79 -65 -163 -123 -250c-86 -131 -172 -196 -257 -196c-34 0 -80 11 -140 32c-59 22 -110 32 -151 32c-40 0 -88 -11 -142 -33c-55 -23 -99 -34 -132 -34c-103 0 -202 87 -301 259c-97 172 -147 339 -147 503c0 153 38 277 113 374c75 96 169 144 284 144
+c49 0 107 -10 177 -30c69 -20 115 -30 138 -30c29 0 77 11 143 34c66 22 124 34 173 34c80 0 151 -22 213 -65c35 -24 70 -58 104 -100c-52 -44 -90 -83 -114 -118c-43 -62 -65 -131 -65 -207c0 -82 23 -157 69 -223s99 -108 158 -126zM1017 1494c0 -41 -10 -87 -29 -136
+c-20 -50 -51 -96 -93 -138c-36 -36 -72 -60 -108 -72c-23 -7 -57 -13 -104 -17c2 99 28 185 78 257s134 121 250 148c2 -9 4 -16 5 -22c0 -7 1 -13 1 -20z" />
+ <glyph glyph-name="gamepad" unicode="&#xf11b;" horiz-adv-x="1920"
+d="M832 448v128c0 18 -14 32 -32 32h-192v192c0 18 -14 32 -32 32h-128c-18 0 -32 -14 -32 -32v-192h-192c-18 0 -32 -14 -32 -32v-128c0 -18 14 -32 32 -32h192v-192c0 -18 14 -32 32 -32h128c18 0 32 14 32 32v192h192c18 0 32 14 32 32zM1408 384c0 71 -57 128 -128 128
+s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM1664 640c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM1920 512c0 -283 -229 -512 -512 -512c-130 0 -248 49 -338 128h-220c-90 -79 -208 -128 -338 -128c-283 0 -512 229 -512 512
+s229 512 512 512h896c283 0 512 -229 512 -512z" />
+ <glyph glyph-name="cc-stripe" unicode="&#xf1f5;" horiz-adv-x="2304"
+d="M1597 633c0 -46 -7 -81 -21 -106c-12 -22 -31 -35 -52 -35c-15 0 -29 3 -41 9v224c26 27 49 30 57 30c38 0 57 -42 57 -122zM2035 669h-110c4 67 22 98 56 98s52 -32 54 -98zM476 534c0 84 -51 119 -134 149c-44 16 -68 29 -68 49c0 17 14 26 38 26c46 0 92 -17 124 -33
+l18 112c-25 12 -77 32 -149 32c-51 0 -93 -13 -123 -38c-32 -26 -48 -64 -48 -109c0 -82 50 -118 132 -147c52 -19 70 -32 70 -53c0 -20 -17 -31 -48 -31c-38 0 -101 19 -142 43l-18 -113c35 -20 100 -41 168 -41c54 0 98 13 129 37c34 27 51 66 51 117zM771 749l19 111h-96
+v135l-129 -21l-18 -114l-46 -8l-17 -103h62v-219c0 -57 15 -96 44 -120c25 -20 61 -30 111 -30c39 0 62 7 79 11v118c-9 -2 -30 -7 -44 -7c-29 0 -42 16 -42 50v197h77zM1087 724v139c-10 2 -19 3 -28 3c-42 0 -76 -22 -89 -62l-10 56h-131v-471h150v306c19 23 46 31 82 31
+c8 0 16 0 26 -2zM1124 389h150v471h-150v-471zM1746 638c0 80 -15 141 -45 179c-27 35 -64 52 -111 52c-43 0 -81 -18 -117 -56l-8 47h-132v-645l150 25v151c23 -7 47 -11 68 -11c37 0 92 10 134 56c41 44 61 112 61 202zM1278 986c0 44 -35 79 -79 79s-79 -35 -79 -79
+s35 -80 79 -80s79 36 79 80zM2176 629c0 75 -16 134 -48 176c-33 42 -82 64 -144 64c-128 0 -207 -94 -207 -246c0 -84 21 -148 63 -188c37 -37 91 -55 161 -55c64 0 123 15 160 40l-16 103c-37 -20 -80 -31 -128 -31c-29 0 -49 6 -63 19c-16 13 -25 35 -28 66h248
+c1 7 2 41 2 52zM2304 1280v-1280c0 -70 -58 -128 -128 -128h-2048c-70 0 -128 58 -128 128v1280c0 70 58 128 128 128h2048c70 0 128 -58 128 -128z" />
+ <glyph glyph-name="quote-left" unicode="&#xf10d;" horiz-adv-x="1664"
+d="M768 576v-384c0 -106 -86 -192 -192 -192h-384c-106 0 -192 86 -192 192v704c0 282 230 512 512 512h64c35 0 64 -29 64 -64v-128c0 -35 -29 -64 -64 -64h-64c-141 0 -256 -115 -256 -256v-32c0 -53 43 -96 96 -96h224c106 0 192 -86 192 -192zM1664 576v-384
+c0 -106 -86 -192 -192 -192h-384c-106 0 -192 86 -192 192v704c0 282 230 512 512 512h64c35 0 64 -29 64 -64v-128c0 -35 -29 -64 -64 -64h-64c-141 0 -256 -115 -256 -256v-32c0 -53 43 -96 96 -96h224c106 0 192 -86 192 -192z" />
+ <glyph glyph-name="user-times" unicode="&#xf235;" horiz-adv-x="2039"
+d="M704 640c-212 0 -384 172 -384 384s172 384 384 384s384 -172 384 -384s-172 -384 -384 -384zM1781 320l249 -249c6 -6 9 -14 9 -23c0 -8 -3 -16 -9 -22l-136 -136c-6 -6 -14 -9 -22 -9c-9 0 -17 3 -23 9l-249 249l-249 -249c-6 -6 -14 -9 -23 -9c-8 0 -16 3 -22 9
+l-136 136c-6 6 -9 14 -9 22c0 9 3 17 9 23l249 249l-249 249c-6 6 -9 14 -9 23c0 8 3 16 9 22l136 136c6 6 14 9 22 9c9 0 17 -3 23 -9l249 -249l249 249c6 6 14 9 23 9c8 0 16 -3 22 -9l136 -136c6 -6 9 -14 9 -22c0 -9 -3 -17 -9 -23zM1283 320l-181 -181
+c-24 -24 -37 -57 -37 -91c0 -33 13 -66 37 -90l83 -83c-14 -2 -29 -3 -44 -3h-874c-160 0 -267 96 -267 259c0 226 53 573 346 573c16 0 27 -7 39 -17c96 -76 194 -122 319 -122s223 46 319 122c12 10 23 17 39 17c19 0 38 -2 57 -6c-33 -32 -54 -58 -54 -106
+c0 -34 13 -67 37 -91z" />
+ <glyph glyph-name="plus-square-o" unicode="&#xf196;" horiz-adv-x="1408"
+d="M1152 736v-64c0 -18 -14 -32 -32 -32h-352v-352c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v352h-352c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h352v352c0 18 14 32 32 32h64c18 0 32 -14 32 -32v-352h352c18 0 32 -14 32 -32zM1280 288v832c0 88 -72 160 -160 160
+h-832c-88 0 -160 -72 -160 -160v-832c0 -88 72 -160 160 -160h832c88 0 160 72 160 160zM1408 1120v-832c0 -159 -129 -288 -288 -288h-832c-159 0 -288 129 -288 288v832c0 159 129 288 288 288h832c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="eye-slash" unicode="&#xf070;" horiz-adv-x="1792"
+d="M555 201l78 141c-116 84 -185 219 -185 362c0 79 21 157 61 225c-156 -80 -286 -206 -381 -353c104 -161 251 -296 427 -375zM944 960c0 26 -22 48 -48 48c-167 0 -304 -137 -304 -304c0 -26 22 -48 48 -48s48 22 48 48c0 115 94 208 208 208c26 0 48 22 48 48z
+M1307 1151c0 -2 0 -7 -1 -9c-211 -377 -420 -756 -631 -1133l-49 -89c-6 -10 -17 -16 -28 -16c-18 0 -113 58 -134 70c-10 6 -16 16 -16 28c0 16 34 70 44 87c-194 88 -357 238 -472 418c-13 20 -20 44 -20 69c0 24 7 49 20 69c198 304 507 507 876 507c60 0 121 -6 180 -17
+l54 97c6 10 16 16 28 16c18 0 112 -58 133 -70c10 -6 16 -16 16 -27zM1344 704c0 -186 -115 -352 -288 -418l280 502c5 -28 8 -56 8 -84zM1792 576c0 -26 -7 -47 -20 -69c-31 -51 -70 -100 -109 -145c-196 -225 -466 -362 -767 -362l74 132c291 25 538 202 694 444
+c-74 115 -169 216 -282 294l63 112c124 -83 249 -208 327 -337c13 -22 20 -43 20 -69z" />
+ <glyph glyph-name="trello" unicode="&#xf181;"
+d="M704 192v1024c0 18 -14 32 -32 32h-480c-18 0 -32 -14 -32 -32v-1024c0 -18 14 -32 32 -32h480c18 0 32 14 32 32zM1376 576v640c0 18 -14 32 -32 32h-480c-18 0 -32 -14 -32 -32v-640c0 -18 14 -32 32 -32h480c18 0 32 14 32 32zM1536 1344v-1408c0 -35 -29 -64 -64 -64
+h-1408c-35 0 -64 29 -64 64v1408c0 35 29 64 64 64h1408c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="dribbble" unicode="&#xf17d;"
+d="M1024 36c-10 58 -48 258 -140 498c-1 0 -3 -1 -4 -1c0 0 -389 -136 -515 -410c-6 5 -15 11 -15 11c114 -93 259 -150 418 -150c91 0 177 19 256 52zM839 643c-16 37 -34 74 -53 111c-338 -101 -662 -93 -673 -93c-1 -7 -1 -14 -1 -21c0 -168 64 -322 168 -438
+c179 319 533 433 533 433c9 3 18 5 26 8zM732 855c-114 202 -235 366 -244 378c-183 -86 -319 -255 -362 -458c17 0 291 -3 606 80zM1416 536c-14 4 -197 62 -409 29c86 -237 121 -430 128 -469c147 99 251 257 281 440zM611 1277c-1 0 -1 0 -2 -1c0 0 1 1 2 1zM1201 1132
+c-115 102 -267 164 -433 164c-53 0 -105 -7 -155 -19c10 -13 134 -176 246 -382c247 92 340 234 342 237zM1424 647c-2 155 -57 298 -149 410c-2 -2 -107 -154 -366 -260c15 -31 30 -63 44 -95c5 -11 9 -23 14 -34c226 29 449 -20 457 -21zM1536 640
+c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="user-secret" unicode="&#xf21b;" horiz-adv-x="1408"
+d="M576 0l96 448l-96 128l-128 64zM832 0l128 640l-128 -64l-96 -128zM992 1010c-1 2 -2 4 -4 6c-9 7 -81 8 -96 8c-57 0 -111 -8 -167 -19c-7 -2 -14 -2 -21 -2s-14 0 -21 2c-56 11 -110 19 -167 19c-15 0 -87 -1 -96 -8c-2 -2 -3 -4 -4 -6c1 -9 2 -18 4 -27
+c6 -8 11 -5 15 -17c26 -71 38 -126 128 -126c129 0 93 119 135 119h12c42 0 6 -119 135 -119c90 0 102 55 128 126c4 12 9 9 15 17c2 9 3 18 4 27zM1408 131c0 -163 -107 -259 -267 -259h-874c-160 0 -267 96 -267 259c0 181 32 455 218 545l-90 220h214
+c-14 41 -22 84 -22 128c0 11 1 22 2 32c-39 8 -194 40 -194 96c0 59 170 91 210 99c21 75 71 189 122 248c20 23 45 37 76 37c60 0 108 -62 168 -62s108 62 168 62c31 0 56 -14 76 -37c51 -59 101 -173 122 -248c40 -8 210 -40 210 -99c0 -56 -155 -88 -194 -96
+c5 -54 -2 -108 -20 -160h214l-82 -225c179 -93 210 -362 210 -540z" />
+ <glyph glyph-name="cloud" unicode="&#xf0c2;" horiz-adv-x="1920"
+d="M1920 384c0 -212 -172 -384 -384 -384h-1088c-247 0 -448 201 -448 448c0 179 106 334 258 405c-1 14 -2 29 -2 43c0 283 229 512 512 512c214 0 397 -131 474 -318c44 39 102 62 166 62c141 0 256 -115 256 -256c0 -51 -15 -98 -41 -138c170 -40 297 -192 297 -374z" />
+ <glyph glyph-name="usd" unicode="&#xf155;" horiz-adv-x="932"
+d="M932 351c0 -204 -146 -365 -358 -400v-175c0 -18 -14 -32 -32 -32h-135c-17 0 -32 14 -32 32v175c-234 33 -362 173 -367 179c-10 12 -11 29 -2 41l103 135c5 7 14 11 23 12s18 -2 24 -9c2 -1 142 -135 319 -135c98 0 204 52 204 165c0 96 -118 143 -253 197
+c-180 71 -404 161 -404 412c0 184 144 336 353 376v180c0 18 15 32 32 32h135c18 0 32 -14 32 -32v-176c203 -23 311 -133 315 -137c10 -11 12 -26 5 -38l-81 -146c-5 -9 -13 -15 -23 -16c-10 -2 -19 1 -27 7c-1 1 -122 108 -272 108c-127 0 -215 -63 -215 -154
+c0 -106 122 -153 264 -208c184 -71 392 -152 392 -393z" />
+ <glyph glyph-name="eye" unicode="&#xf06e;" horiz-adv-x="1792"
+d="M1664 576c-95 147 -225 273 -381 353c40 -68 61 -146 61 -225c0 -247 -201 -448 -448 -448s-448 201 -448 448c0 79 21 157 61 225c-156 -80 -286 -206 -381 -353c171 -264 447 -448 768 -448s597 184 768 448zM944 960c0 26 -22 48 -48 48c-167 0 -304 -137 -304 -304
+c0 -26 22 -48 48 -48s48 22 48 48c0 114 94 208 208 208c26 0 48 22 48 48zM1792 576c0 -25 -8 -48 -20 -69c-184 -303 -521 -507 -876 -507s-692 205 -876 507c-12 21 -20 44 -20 69s8 48 20 69c184 302 521 507 876 507s692 -205 876 -507c12 -21 20 -44 20 -69z" />
+ <glyph glyph-name="usb" unicode="&#xf287;" horiz-adv-x="2304"
+d="M2288 731c10 -5 16 -16 16 -27s-6 -22 -16 -27l-320 -192c-5 -3 -10 -5 -16 -5c-5 0 -11 1 -16 4c-10 6 -16 16 -16 28v128h-858c32 -50 59 -109 83 -165c48 -108 97 -219 167 -219h96v96c0 18 14 32 32 32h320c18 0 32 -14 32 -32v-320c0 -18 -14 -32 -32 -32h-320
+c-18 0 -32 14 -32 32v96h-96c-153 0 -222 157 -284 295c-47 107 -96 217 -164 217h-360c-29 -110 -129 -192 -248 -192c-141 0 -256 115 -256 256s115 256 256 256c119 0 219 -82 248 -192h104c68 0 117 110 164 217c62 138 131 295 284 295h107c27 75 97 128 181 128
+c106 0 192 -86 192 -192s-86 -192 -192 -192c-84 0 -154 53 -181 128h-107c-70 0 -119 -111 -167 -219c-24 -56 -51 -115 -83 -165h1114v128c0 12 6 22 16 28s23 5 32 -1z" />
+ <glyph glyph-name="certificate" unicode="&#xf0a3;"
+d="M1376 640l138 -135c19 -18 26 -45 20 -70c-7 -25 -27 -45 -52 -51l-188 -48l53 -186c7 -25 0 -52 -19 -70c-18 -19 -45 -26 -70 -19l-186 53l-48 -188c-6 -25 -26 -45 -51 -52c-6 -1 -13 -2 -19 -2c-19 0 -38 8 -51 22l-135 138l-135 -138c-18 -19 -45 -26 -70 -20
+c-26 7 -45 27 -51 52l-48 188l-186 -53c-25 -7 -52 0 -70 19c-19 18 -26 45 -19 70l53 186l-188 48c-25 6 -45 26 -52 51c-6 25 1 52 20 70l138 135l-138 135c-19 18 -26 45 -20 70c7 25 27 45 52 51l188 48l-53 186c-7 25 0 52 19 70c18 19 45 26 70 19l186 -53l48 188
+c6 25 26 45 51 51c25 7 52 0 70 -19l135 -139l135 139c18 19 44 26 70 19c25 -6 45 -26 51 -51l48 -188l186 53c25 7 52 0 70 -19c19 -18 26 -45 19 -70l-53 -186l188 -48c25 -6 45 -26 52 -51c6 -25 -1 -52 -20 -70z" />
+ <glyph glyph-name="500px" unicode="&#xf26e;" horiz-adv-x="1394"
+d="M1387 -11l-6 -6c-75 -75 -162 -134 -259 -175c-101 -42 -207 -64 -317 -64s-217 22 -317 64c-97 41 -185 100 -259 175c-75 74 -134 161 -175 258c-25 61 -45 124 -54 189c-4 28 35 34 48 36c31 5 52 3 56 -20c1 -1 1 -2 1 -4c4 -20 14 -80 46 -159
+c33 -82 84 -158 152 -226c65 -65 141 -116 226 -152c87 -37 180 -56 276 -56c95 0 188 19 276 56c84 36 160 87 225 152l6 6c7 7 15 9 25 6c9 -2 20 -10 33 -22c32 -33 25 -49 17 -58zM915 604l-66 -66l63 -63c7 -7 20 -22 -7 -49c-11 -11 -22 -17 -32 -17
+c-7 0 -13 3 -19 10l-62 61l-66 -66c-2 -2 -7 -5 -15 -5c-9 0 -20 5 -31 16l-2 2c-7 6 -18 17 -18 29c0 6 3 11 8 17l66 65l-66 66c-11 11 -6 25 14 45c12 12 22 18 31 18c5 0 9 -2 13 -5l65 -66l65 65c11 11 29 6 48 -13c12 -12 25 -29 11 -44zM1386 547
+c0 -79 -16 -156 -46 -228c-30 -70 -72 -132 -126 -186s-117 -96 -187 -126c-72 -31 -149 -46 -228 -46s-156 15 -228 46c-70 30 -133 72 -187 126s-96 116 -125 186c-6 13 -15 38 -15 40h-1c-9 28 31 40 43 44c29 9 51 13 60 -12c24 -64 61 -126 97 -167h1v341
+c2 84 37 169 102 232c67 66 157 103 253 103c196 0 355 -158 355 -352c0 -196 -160 -355 -355 -355c-39 0 -68 3 -112 16c-5 2 -28 12 -13 61c4 13 16 51 44 43c2 0 51 -12 77 -12c139 0 248 108 248 246c0 65 -26 126 -72 171c-46 46 -108 71 -175 71
+c-69 0 -132 -28 -178 -80c-40 -45 -64 -105 -64 -160v-413c72 -44 155 -67 242 -67c128 0 252 51 341 140c90 90 140 211 140 338c0 128 -50 248 -141 339c-90 90 -210 140 -339 140s-250 -50 -340 -140c-1 -1 -58 -60 -77 -87l-2 -2c-12 -17 -23 -33 -73 -22
+c-25 6 -52 21 -52 43v680c0 18 14 38 38 38h877c30 0 30 -42 30 -55c0 -14 0 -55 -30 -55h-811v-483h1c56 59 153 121 210 145c71 30 151 46 231 46c79 0 156 -15 228 -46c70 -30 133 -72 187 -126s96 -116 126 -186c30 -73 46 -149 46 -229zM1355 1128
+c19 -17 6 -35 -13 -57c-12 -12 -25 -26 -39 -26c-6 0 -11 2 -16 7c-72 62 -137 104 -207 133c-87 38 -180 56 -276 56c-85 0 -178 -17 -262 -49c-26 -10 -40 24 -45 37c-6 16 -9 29 -8 38c2 10 7 17 16 20c82 36 194 57 299 57c109 0 216 -22 316 -64
+c92 -39 167 -87 235 -152z" />
+ <glyph glyph-name="liberapay-square" unicode="&#xf2e8;" horiz-adv-x="1533"
+d="M148 1404h1236c82 0 149 -66 149 -148v-1236c0 -82 -67 -148 -149 -148h-1236c-82 0 -148 66 -148 148v1236c0 82 66 148 148 148zM736 1150v0l-161 -25l-133 -553c-8 -33 -12 -64 -12 -93s6 -54 18 -76s32 -40 60 -53s68 -19 117 -19l31 128c-18 1 -32 4 -42 9
+s-18 12 -22 20s-5 17 -5 27s1 23 4 35zM985 902v0c-42 0 -80 -3 -116 -10s-67 -14 -95 -22l-174 -722h155l47 189c24 -4 47 -6 71 -6c49 0 94 8 135 25s76 41 106 72s52 67 69 109s25 88 25 139c0 31 -4 61 -13 88s-22 51 -40 72c-18 20 -41 36 -69 48s-62 18 -101 18z
+M965 772v0c33 0 56 -11 69 -32s20 -46 20 -76c0 -31 -4 -59 -13 -84s-21 -47 -37 -65s-34 -32 -56 -42s-47 -15 -74 -15c-17 0 -32 1 -44 4l73 303c19 4 40 7 62 7z" />
+ <glyph glyph-name="foursquare" unicode="&#xf180;" horiz-adv-x="1192"
+d="M956 1102l37 194c7 32 -17 57 -44 57h-712c-32 0 -54 -29 -54 -54v-1101c0 -3 3 -4 6 -1c262 315 291 352 291 352c30 35 42 41 86 41h239c33 0 52 28 55 44s31 162 37 191s-21 59 -48 59h-294c-39 0 -67 28 -67 67v42c0 39 28 66 67 66h346c24 0 51 22 55 43zM1183 1324
+c-37 -180 -148 -749 -158 -790c-12 -47 -30 -129 -144 -129h-271c-11 0 -12 1 -22 -10c0 0 -7 -8 -426 -494c-33 -38 -87 -31 -107 -23s-55 32 -55 98v1410c0 58 36 150 158 150h888c130 0 165 -74 137 -212zM1183 1324l-158 -790c10 41 121 610 158 790z" />
+ <glyph glyph-name="music" unicode="&#xf001;"
+d="M1536 1312v-1120c0 -141 -211 -192 -320 -192s-320 51 -320 192s211 192 320 192c66 0 132 -12 192 -39v537l-768 -237v-709c0 -141 -211 -192 -320 -192s-320 51 -320 192s211 192 320 192c66 0 132 -12 192 -39v967c0 42 28 79 68 92l832 256c9 3 18 4 28 4
+c53 0 96 -43 96 -96z" />
+ <glyph glyph-name="wpexplorer" unicode="&#xf2de;" horiz-adv-x="1792"
+d="M948 508l163 -329h-51l-175 350l-171 -350h-49l179 374l-78 33l21 49l240 -102l-21 -50zM563 1100l304 -130l-130 -304l-304 130zM907 915l240 -103l-103 -239l-239 102zM1188 765l191 -81l-82 -190l-190 81zM1680 640c0 432 -352 784 -784 784s-784 -352 -784 -784
+s352 -784 784 -784s784 352 784 784zM1792 640c0 -494 -402 -896 -896 -896s-896 402 -896 896s402 896 896 896s896 -402 896 -896z" />
+ <glyph glyph-name="gg-circle" unicode="&#xf261;" horiz-adv-x="1792"
+d="M717 182l271 271l-279 279l-88 -88l192 -191l-96 -96l-279 279l279 279l40 -40l87 87l-127 128l-454 -454zM1075 190l454 454l-454 454l-271 -271l279 -279l88 88l-192 191l96 96l279 -279l-279 -279l-40 40l-87 -88zM1792 640c0 -495 -401 -896 -896 -896
+s-896 401 -896 896s401 896 896 896s896 -401 896 -896z" />
+ <glyph glyph-name="sort" unicode="&#xf0dc;" horiz-adv-x="1024"
+d="M1024 448c0 -17 -7 -33 -19 -45l-448 -448c-12 -12 -28 -19 -45 -19s-33 7 -45 19l-448 448c-12 12 -19 28 -19 45c0 35 29 64 64 64h896c35 0 64 -29 64 -64zM1024 832c0 -35 -29 -64 -64 -64h-896c-35 0 -64 29 -64 64c0 17 7 33 19 45l448 448c12 12 28 19 45 19
+s33 -7 45 -19l448 -448c12 -12 19 -28 19 -45z" />
+ <glyph glyph-name="pencil" unicode="&#xf040;" horiz-adv-x="1515"
+d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928c0 13 -9 22 -22 22c-6 0 -12 -2 -17 -7l-542 -542c-5 -5 -7 -11 -7 -17c0 -13 9 -22 22 -22c6 0 12 2 17 7l542 542c5 5 7 11 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024c0 -34 -14 -67 -37 -90
+l-166 -166l-416 416l166 165c23 24 56 38 90 38s67 -14 91 -38l235 -234c23 -24 37 -57 37 -91z" />
+ <glyph glyph-name="bookmark-o" unicode="&#xf097;" horiz-adv-x="1280"
+d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408c15 0 30 -3 44 -9c44 -17 72 -58 72 -103v-1289c0 -45 -28 -86 -72 -103c-14 -6 -29 -8 -44 -8c-31 0 -60 11 -83 32l-441 424l-441 -424c-23 -21 -52 -33 -83 -33c-15 0 -30 3 -44 9
+c-44 17 -72 58 -72 103v1289c0 45 28 86 72 103c14 6 29 9 44 9h1048z" />
+ <glyph glyph-name="diamond" unicode="&#xf219;" horiz-adv-x="2048"
+d="M212 768l623 -665l-300 665h-323zM1024 -4l349 772h-698zM538 896l204 384h-262l-288 -384h346zM1213 103l623 665h-323zM683 896h682l-204 384h-274zM1510 896h346l-288 384h-262zM1651 1382l384 -512c19 -24 17 -59 -4 -82l-960 -1024c-12 -13 -29 -20 -47 -20
+s-35 7 -47 20l-960 1024c-21 23 -23 58 -4 82l384 512c12 17 31 26 51 26h1152c20 0 39 -9 51 -26z" />
+ <glyph glyph-name="share" unicode="&#xf064;" horiz-adv-x="1792"
+d="M1792 896c0 -17 -7 -33 -19 -45l-512 -512c-12 -12 -28 -19 -45 -19c-35 0 -64 29 -64 64v256h-224c-431 0 -714 -83 -714 -560c0 -41 2 -82 5 -123c1 -16 5 -34 5 -50c0 -19 -12 -35 -32 -35c-14 0 -21 7 -28 17c-15 21 -26 53 -37 76c-57 128 -127 311 -127 451
+c0 112 11 227 53 333c139 345 547 403 875 403h224v256c0 35 29 64 64 64c17 0 33 -7 45 -19l512 -512c12 -12 19 -28 19 -45z" />
+ <glyph glyph-name="envelope" unicode="&#xf0e0;" horiz-adv-x="1792"
+d="M1792 826v-794c0 -88 -72 -160 -160 -160h-1472c-88 0 -160 72 -160 160v794c30 -33 64 -62 101 -87c166 -113 334 -226 497 -345c84 -62 188 -138 297 -138h2c109 0 213 76 297 138c163 118 331 232 498 345c36 25 70 54 100 87zM1792 1120c0 -112 -83 -213 -171 -274
+c-156 -108 -313 -216 -468 -325c-65 -45 -175 -137 -256 -137h-2c-81 0 -191 92 -256 137c-155 109 -312 217 -467 325c-71 48 -172 161 -172 252c0 98 53 182 160 182h1472c87 0 160 -72 160 -160z" />
+ <glyph glyph-name="yahoo" unicode="&#xf19e;" horiz-adv-x="1318"
+d="M750 579l13 -707c-34 6 -69 11 -105 11c-35 0 -70 -5 -105 -11l13 707c-186 321 -361 648 -566 957c35 -9 71 -15 108 -15s75 7 111 15c140 -248 292 -489 439 -733c148 242 305 483 439 733c35 -9 71 -14 107 -14c38 0 77 5 114 14c-80 -110 -146 -230 -215 -347
+c-119 -203 -236 -406 -353 -610z" />
+ <glyph glyph-name="window-restore" unicode="&#xf2d2;" horiz-adv-x="2048"
+d="M256 0h768v512h-768v-512zM1280 512h512v768h-768v-256h96c88 0 160 -72 160 -160v-352zM2048 1376v-960c0 -88 -72 -160 -160 -160h-608v-352c0 -88 -72 -160 -160 -160h-960c-88 0 -160 72 -160 160v960c0 88 72 160 160 160h608v352c0 88 72 160 160 160h960
+c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="glass" unicode="&#xf000;" horiz-adv-x="1606"
+d="M1606 1350c0 -29 -23 -58 -43 -78l-632 -632v-768h320c35 0 64 -29 64 -64s-29 -64 -64 -64h-896c-35 0 -64 29 -64 64s29 64 64 64h320v768l-632 632c-20 20 -43 49 -43 78c0 49 62 58 99 58h1408c37 0 99 -9 99 -58z" />
+ <glyph glyph-name="flag" unicode="&#xf024;" horiz-adv-x="1728"
+d="M256 1280c0 -46 -25 -87 -64 -110v-1266c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v1266c-39 23 -64 64 -64 110c0 71 57 128 128 128s128 -57 128 -128zM1728 1216v-763c0 -37 -23 -51 -52 -66c-113 -61 -238 -116 -369 -116c-184 0 -272 140 -490 140
+c-159 0 -326 -72 -464 -146c-11 -6 -21 -9 -33 -9c-35 0 -64 29 -64 64v742c0 24 12 41 31 55c24 16 53 30 79 43c126 64 279 120 421 120c157 0 280 -52 419 -117c28 -14 57 -19 88 -19c157 0 326 136 370 136c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="train" unicode="&#xf238;"
+d="M1088 1536c247 0 448 -143 448 -320v-896c0 -173 -191 -313 -431 -319l213 -202c21 -20 7 -55 -22 -55h-1056c-29 0 -43 35 -22 55l213 202c-240 6 -431 146 -431 319v896c0 177 201 320 448 320h640zM768 192c106 0 192 86 192 192s-86 192 -192 192s-192 -86 -192 -192
+s86 -192 192 -192zM1344 768v512h-1152v-512h1152z" />
+ <glyph glyph-name="bullhorn" unicode="&#xf0a1;" horiz-adv-x="1792"
+d="M1664 896c71 0 128 -57 128 -128s-57 -128 -128 -128v-384c0 -70 -58 -128 -128 -128c-178 148 -465 351 -812 380c-119 -40 -160 -179 -82 -259c-70 -115 20 -196 126 -279c-62 -122 -320 -124 -412 -39c-58 178 -144 356 -74 581h-122c-88 0 -160 72 -160 160v192
+c0 88 72 160 160 160h480c384 0 704 224 896 384c70 0 128 -58 128 -128v-384zM1536 292v954c-261 -200 -514 -315 -768 -343v-270c254 -28 507 -141 768 -341z" />
+ <glyph glyph-name="pause-circle-o" unicode="&#xf28c;"
+d="M768 1408c424 0 768 -344 768 -768s-344 -768 -768 -768s-768 344 -768 768s344 768 768 768zM768 96c300 0 544 244 544 544s-244 544 -544 544s-544 -244 -544 -544s244 -544 544 -544zM864 320c-18 0 -32 14 -32 32v576c0 18 14 32 32 32h192c18 0 32 -14 32 -32v-576
+c0 -18 -14 -32 -32 -32h-192zM480 320c-18 0 -32 14 -32 32v576c0 18 14 32 32 32h192c18 0 32 -14 32 -32v-576c0 -18 -14 -32 -32 -32h-192z" />
+ <glyph glyph-name="snapchat-ghost" unicode="&#xf2ac;" horiz-adv-x="1634"
+d="M833 1408c180 2 329 -99 404 -261c23 -49 27 -125 27 -179c0 -64 -5 -127 -9 -191c8 -4 19 -7 28 -7c36 0 66 27 102 27c34 0 83 -24 83 -64c0 -96 -201 -78 -201 -162c0 -15 6 -29 12 -43c48 -105 139 -206 247 -251c26 -11 52 -17 80 -23c18 -4 28 -17 28 -35
+c0 -68 -173 -96 -219 -103c-20 -31 -5 -104 -58 -104c-41 0 -82 13 -126 13c-21 0 -42 -1 -62 -5c-119 -20 -159 -148 -354 -148c-188 0 -233 128 -349 148c-21 4 -42 5 -63 5c-45 0 -88 -15 -124 -15c-56 0 -39 74 -60 106c-46 7 -219 35 -219 103c0 18 10 31 28 35
+c28 6 54 12 80 23c107 44 200 146 247 251c6 14 12 28 12 43c0 84 -202 68 -202 161c0 39 46 64 81 64c31 0 62 -26 101 -26c11 0 22 2 32 7c-4 63 -9 126 -9 190c0 54 4 131 27 180c88 190 237 259 436 261z" />
+ <glyph glyph-name="folder" unicode="&#xf07b;" horiz-adv-x="1664"
+d="M1664 928v-704c0 -123 -101 -224 -224 -224h-1216c-123 0 -224 101 -224 224v960c0 123 101 224 224 224h320c123 0 224 -101 224 -224v-32h672c123 0 224 -101 224 -224z" />
+ <glyph glyph-name="outdent" unicode="&#xf03b;" horiz-adv-x="1792"
+d="M384 992v-576c0 -17 -15 -32 -32 -32c-8 0 -17 3 -23 9l-288 288c-6 6 -9 15 -9 23s3 17 9 23l288 288c6 6 15 9 23 9c17 0 32 -15 32 -32zM1792 224v-192c0 -17 -15 -32 -32 -32h-1728c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h1728c17 0 32 -15 32 -32zM1792 608
+v-192c0 -17 -15 -32 -32 -32h-1088c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h1088c17 0 32 -15 32 -32zM1792 992v-192c0 -17 -15 -32 -32 -32h-1088c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h1088c17 0 32 -15 32 -32zM1792 1376v-192c0 -17 -15 -32 -32 -32h-1728
+c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h1728c17 0 32 -15 32 -32z" />
+ <glyph glyph-name="stumbleupon" unicode="&#xf1a4;" horiz-adv-x="1920"
+d="M1062 824v118c0 56 -46 102 -102 102s-102 -46 -102 -102v-612c0 -234 -194 -423 -429 -423c-237 0 -429 192 -429 429v266h328v-262c0 -57 46 -102 102 -102s102 45 102 102v620c0 229 196 413 428 413c233 0 428 -185 428 -416v-136l-195 -58zM1592 602h328v-266
+c0 -237 -192 -429 -429 -429c-236 0 -429 190 -429 425v268l131 -61l195 58v-270c0 -56 46 -101 102 -101s102 45 102 101v275z" />
+ <glyph glyph-name="address-card" unicode="&#xf2bb;" horiz-adv-x="2048"
+d="M1024 405c0 155 -38 327 -196 327c-49 -28 -115 -76 -188 -76s-139 48 -188 76c-158 0 -196 -172 -196 -327c0 -87 57 -149 128 -149h512c71 0 128 62 128 149zM867 925c0 125 -102 227 -227 227s-227 -102 -227 -227c0 -126 102 -227 227 -227s227 101 227 227z
+M1792 416v64c0 18 -14 32 -32 32h-576c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h576c18 0 32 14 32 32zM1792 676v56c0 20 -16 36 -36 36h-568c-20 0 -36 -16 -36 -36v-56c0 -20 16 -36 36 -36h568c20 0 36 16 36 36zM1792 928v64c0 18 -14 32 -32 32h-576
+c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h576c18 0 32 14 32 32zM2048 1248v-1216c0 -88 -72 -160 -160 -160h-352v96c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-96h-768v96c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-96h-352c-88 0 -160 72 -160 160
+v1216c0 88 72 160 160 160h1728c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="i-cursor" unicode="&#xf246;" horiz-adv-x="896"
+d="M832 1408c-212 0 -320 -75 -320 -224v-416h128v-128h-128v-544c0 -149 108 -224 320 -224h64v-128h-64c-180 0 -312 52 -384 146c-72 -94 -204 -146 -384 -146h-64v128h64c212 0 320 75 320 224v544h-128v128h128v416c0 149 -108 224 -320 224h-64v128h64
+c180 0 312 -52 384 -146c72 94 204 146 384 146h64v-128h-64z" />
+ <glyph glyph-name="car" unicode="&#xf1b9;" horiz-adv-x="2048"
+d="M480 448c0 88 -72 160 -160 160s-160 -72 -160 -160s72 -160 160 -160s160 72 160 160zM516 768h1016l-89 357c-3 11 -23 27 -35 27h-768c-12 0 -32 -16 -35 -27zM1888 448c0 88 -72 160 -160 160s-160 -72 -160 -160s72 -160 160 -160s160 72 160 160zM2048 544v-384
+c0 -18 -14 -32 -32 -32h-96v-128c0 -106 -86 -192 -192 -192s-192 86 -192 192v128h-1024v-128c0 -106 -86 -192 -192 -192s-192 86 -192 192v128h-96c-18 0 -32 14 -32 32v384c0 124 100 224 224 224h28l105 419c31 126 153 221 283 221h768c130 0 252 -95 283 -221
+l105 -419h28c124 0 224 -100 224 -224z" />
+ <glyph glyph-name="file-excel-o" unicode="&#xf1c3;"
+d="M1468 1156c37 -37 68 -111 68 -164v-1152c0 -53 -43 -96 -96 -96h-1344c-53 0 -96 43 -96 96v1600c0 53 43 96 96 96h896c53 0 127 -31 164 -68zM1024 1400v-376h376c-6 17 -15 34 -22 41l-313 313c-7 7 -24 16 -41 22zM1408 -128v1024h-416c-53 0 -96 43 -96 96v416
+h-768v-1536h1280zM429 106h68l194 283l-189 272h-68v107h290v-107h-76l106 -159c8 -9 13 -16 17 -23c2 -3 4 -6 5 -10h2c0 -1 9 14 21 33l103 159h-74v107h279v-107h-67l-195 -282l192 -273h68v-106h-291v106h76l-107 161c-7 10 -13 16 -17 24c-2 3 -4 6 -5 10h-2
+c-3 0 -9 -15 -21 -34l-103 -161h75v-106h-281v106z" />
+ <glyph glyph-name="arrow-circle-o-left" unicode="&#xf190;"
+d="M1152 736v-192c0 -17 -15 -32 -32 -32h-352v-192c0 -18 -14 -32 -32 -32c-9 0 -17 4 -24 10l-319 319c-6 6 -9 15 -9 23s3 17 9 23l320 320c6 6 15 9 23 9c17 0 32 -15 32 -32v-192h352c17 0 32 -15 32 -32zM1312 640c0 300 -244 544 -544 544s-544 -244 -544 -544
+s244 -544 544 -544s544 244 544 544zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="paragraph" unicode="&#xf1dd;" horiz-adv-x="1254"
+d="M1254 1347v-73c0 -34 -27 -93 -61 -93c-17 0 -37 3 -54 -1c-16 -4 -28 -15 -32 -31c-5 -19 -3 -43 -3 -64v-1152c0 -34 -27 -61 -61 -61h-108c-34 0 -61 27 -61 61v1218h-143v-1218c0 -34 -27 -61 -61 -61h-108c-34 0 -61 27 -61 61v496c-97 8 -180 28 -245 59
+c-84 39 -148 99 -192 179c-42 77 -64 164 -64 259c0 111 30 207 88 286c59 79 129 132 209 159c75 25 233 37 417 37h479c34 0 61 -27 61 -61z" />
+ <glyph glyph-name="y-combinator" unicode="&#xf23b;"
+d="M809 532l266 499h-112l-157 -312s-24 -48 -44 -92c-19 46 -42 92 -42 92l-155 312h-120l263 -493v-324h101v318zM1536 1408v-1536h-1536v1536h1536z" />
+ <glyph glyph-name="male" unicode="&#xf183;" horiz-adv-x="1024"
+d="M1024 832v-416c0 -53 -43 -96 -96 -96s-96 43 -96 96v352h-64v-912c0 -62 -50 -112 -112 -112s-112 50 -112 112v464h-64v-464c0 -62 -50 -112 -112 -112s-112 50 -112 112v912h-64v-352c0 -53 -43 -96 -96 -96s-96 43 -96 96v416c0 106 86 192 192 192h640
+c106 0 192 -86 192 -192zM736 1280c0 -124 -100 -224 -224 -224s-224 100 -224 224s100 224 224 224s224 -100 224 -224z" />
+ <glyph glyph-name="history" unicode="&#xf1da;"
+d="M1536 640c0 -423 -345 -768 -768 -768c-229 0 -445 101 -591 277c-10 13 -9 32 2 43l137 138c7 6 16 9 25 9c9 -1 18 -5 23 -12c98 -127 245 -199 404 -199c282 0 512 230 512 512s-230 512 -512 512c-131 0 -255 -50 -348 -137l137 -138c19 -18 24 -46 14 -69
+c-10 -24 -33 -40 -59 -40h-448c-35 0 -64 29 -64 64v448c0 26 16 49 40 59c23 10 51 5 69 -14l130 -129c141 133 332 212 529 212c423 0 768 -345 768 -768zM896 928v-448c0 -18 -14 -32 -32 -32h-320c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h224v352c0 18 14 32 32 32h64
+c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="h-square" unicode="&#xf0fd;"
+d="M1280 192v896c0 35 -29 64 -64 64h-128c-35 0 -64 -29 -64 -64v-320h-512v320c0 35 -29 64 -64 64h-128c-35 0 -64 -29 -64 -64v-896c0 -35 29 -64 64 -64h128c35 0 64 29 64 64v320h512v-320c0 -35 29 -64 64 -64h128c35 0 64 29 64 64zM1536 1120v-960
+c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="heart" unicode="&#xf004;" horiz-adv-x="1792"
+d="M896 -128c-16 0 -32 6 -44 18l-624 602c-8 7 -228 208 -228 448c0 293 179 468 478 468c175 0 339 -138 418 -216c79 78 243 216 418 216c299 0 478 -175 478 -468c0 -240 -220 -441 -229 -450l-623 -600c-12 -12 -28 -18 -44 -18z" />
+ <glyph glyph-name="sort-amount-desc" unicode="&#xf161;" horiz-adv-x="1760"
+d="M1184 -32v-192c0 -18 -14 -32 -32 -32h-256c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h256c18 0 32 -14 32 -32zM704 96c0 -9 -4 -17 -10 -24l-319 -319c-7 -6 -15 -9 -23 -9s-16 3 -23 9l-320 320c-9 10 -12 23 -7 35s17 20 30 20h192v1376c0 18 14 32 32 32h192
+c18 0 32 -14 32 -32v-1376h192c18 0 32 -14 32 -32zM1376 480v-192c0 -18 -14 -32 -32 -32h-448c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h448c18 0 32 -14 32 -32zM1568 992v-192c0 -18 -14 -32 -32 -32h-640c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h640
+c18 0 32 -14 32 -32zM1760 1504v-192c0 -18 -14 -32 -32 -32h-832c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h832c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="search-plus" unicode="&#xf00e;" horiz-adv-x="1664"
+d="M1024 736v-64c0 -17 -15 -32 -32 -32h-224v-224c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v224h-224c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h224v224c0 17 15 32 32 32h64c17 0 32 -15 32 -32v-224h224c17 0 32 -15 32 -32zM1152 704c0 247 -201 448 -448 448
+s-448 -201 -448 -448s201 -448 448 -448s448 201 448 448zM1664 -128c0 -71 -57 -128 -128 -128c-34 0 -67 14 -90 38l-343 342c-117 -81 -257 -124 -399 -124c-389 0 -704 315 -704 704s315 704 704 704s704 -315 704 -704c0 -142 -43 -282 -124 -399l343 -343
+c23 -23 37 -56 37 -90z" />
+ <glyph glyph-name="life-ring" unicode="&#xf1cd;" horiz-adv-x="1792"
+d="M896 1536c495 0 896 -401 896 -896s-401 -896 -896 -896s-896 401 -896 896s401 896 896 896zM896 1408c-130 0 -253 -33 -361 -90l194 -194c53 18 109 28 167 28c59 0 114 -10 167 -28l194 194c-108 57 -231 90 -361 90zM218 279l194 194c-18 53 -28 109 -28 167
+c0 59 10 114 28 167l-194 194c-57 -108 -90 -231 -90 -361s33 -253 90 -361zM896 -128c130 0 253 33 361 90l-194 194c-53 -18 -108 -28 -167 -28c-58 0 -114 10 -167 28l-194 -194c108 -57 231 -90 361 -90zM896 256c212 0 384 172 384 384s-172 384 -384 384
+s-384 -172 -384 -384s172 -384 384 -384zM1380 473l194 -194c57 108 90 231 90 361s-33 253 -90 361l-194 -194c18 -53 28 -109 28 -167s-10 -114 -28 -167z" />
+ <glyph glyph-name="lock" unicode="&#xf023;" horiz-adv-x="1152"
+d="M320 768h512v192c0 141 -115 256 -256 256s-256 -115 -256 -256v-192zM1152 672v-576c0 -53 -43 -96 -96 -96h-960c-53 0 -96 43 -96 96v576c0 53 43 96 96 96h32v192c0 246 202 448 448 448s448 -202 448 -448v-192h32c53 0 96 -43 96 -96z" />
+ <glyph glyph-name="git-square" unicode="&#xf1d2;"
+d="M582 228c0 -54 -49 -66 -93 -66c-43 0 -107 7 -107 63c0 55 54 64 98 64c42 0 102 -7 102 -61zM546 694c0 -50 -20 -85 -74 -85c-55 0 -77 32 -77 84s20 90 77 90c51 0 74 -42 74 -89zM712 769v125c-43 -16 -89 -29 -135 -29c-33 19 -71 29 -110 29
+c-114 0 -204 -84 -204 -200c0 -62 41 -148 103 -169v-3c-32 -14 -38 -53 -38 -85c0 -33 12 -60 41 -77v-3c-68 -22 -113 -65 -113 -139c0 -127 121 -163 227 -163c128 0 224 47 224 188c0 100 -91 130 -174 145c-28 5 -76 25 -76 60c0 33 18 47 49 52c102 20 167 99 167 204
+c0 18 -4 35 -10 52c16 4 33 8 49 13zM771 350h137c-2 27 -2 55 -2 82v387c0 23 0 46 2 69h-137c3 -23 3 -48 3 -71v-392c0 -25 0 -50 -3 -75zM1280 366v121c-20 -14 -44 -21 -68 -21c-45 0 -53 45 -53 82v225h52c18 0 35 -2 53 -2v117h-105c0 34 -2 68 3 102h-140
+c3 -18 4 -36 4 -55v-47h-60v-117c12 1 24 3 37 3c7 0 15 -1 23 -1v-2h-2v-217c0 -108 16 -212 148 -212c37 0 75 6 108 24zM924 1072c0 47 -35 91 -84 91s-85 -43 -85 -91c0 -47 37 -89 85 -89s84 43 84 89zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960
+c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="mouse-pointer" unicode="&#xf245;" horiz-adv-x="1152"
+d="M1133 493c19 -18 24 -46 14 -69c-10 -24 -33 -40 -59 -40h-382l201 -476c14 -33 -2 -70 -34 -84l-177 -75c-33 -14 -70 2 -84 34l-191 452l-312 -312c-12 -12 -28 -19 -45 -19c-8 0 -17 2 -24 5c-24 10 -40 33 -40 59v1504c0 26 16 49 40 59c7 3 16 5 24 5
+c17 0 33 -6 45 -19z" />
+ <glyph glyph-name="sign-in" unicode="&#xf090;"
+d="M1184 640c0 -17 -7 -33 -19 -45l-544 -544c-12 -12 -28 -19 -45 -19c-35 0 -64 29 -64 64v288h-448c-35 0 -64 29 -64 64v384c0 35 29 64 64 64h448v288c0 35 29 64 64 64c17 0 33 -7 45 -19l544 -544c12 -12 19 -28 19 -45zM1536 992v-704c0 -159 -129 -288 -288 -288
+h-320c-17 0 -32 15 -32 32c0 28 -13 96 32 96h320c88 0 160 72 160 160v704c0 88 -72 160 -160 160h-288c-25 0 -64 -5 -64 32c0 28 -13 96 32 96h320c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="odnoklassniki-square" unicode="&#xf264;"
+d="M927 956c0 -88 -71 -159 -159 -159s-159 71 -159 159s71 159 159 159s159 -71 159 -159zM1141 593c-18 36 -69 67 -136 14c0 0 -91 -72 -237 -72s-237 72 -237 72c-67 53 -118 22 -136 -14c-32 -64 4 -95 85 -148c69 -44 165 -61 226 -67l-51 -52
+c-72 -72 -142 -142 -191 -190c-29 -29 -29 -76 0 -105l9 -9c29 -29 76 -29 105 0l191 191c72 -73 142 -143 191 -191c29 -29 76 -29 105 0l9 9c29 29 29 76 0 105l-191 190l-52 52c62 6 156 23 225 67c81 53 117 84 85 148zM1092 956c0 179 -145 324 -324 324
+s-324 -145 -324 -324s145 -324 324 -324s324 145 324 324zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="tag" unicode="&#xf02b;" horiz-adv-x="1515"
+d="M448 1088c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM1515 512c0 -34 -14 -67 -37 -90l-491 -492c-24 -23 -57 -37 -91 -37s-67 14 -90 37l-715 716c-51 50 -91 147 -91 218v416c0 70 58 128 128 128h416c71 0 168 -40 219 -91
+l715 -714c23 -24 37 -57 37 -91z" />
+ <glyph glyph-name="align-justify" unicode="&#xf039;" horiz-adv-x="1792"
+d="M1792 192v-128c0 -35 -29 -64 -64 -64h-1664c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1664c35 0 64 -29 64 -64zM1792 576v-128c0 -35 -29 -64 -64 -64h-1664c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1664c35 0 64 -29 64 -64zM1792 960v-128
+c0 -35 -29 -64 -64 -64h-1664c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1664c35 0 64 -29 64 -64zM1792 1344v-128c0 -35 -29 -64 -64 -64h-1664c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1664c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="hospital-o" unicode="&#xf0f8;" horiz-adv-x="1408"
+d="M384 224v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM384 480v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM640 480v-64c0 -17 -15 -32 -32 -32h-64
+c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM384 736v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM1152 224v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64
+c17 0 32 -15 32 -32zM896 480v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM640 736v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM1152 480v-64
+c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM896 736v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM1152 736v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64
+c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM896 -128h384v1152h-256v-32c0 -53 -43 -96 -96 -96h-448c-53 0 -96 43 -96 96v32h-256v-1152h384v224c0 17 15 32 32 32h320c17 0 32 -15 32 -32v-224zM896 1056v320c0 17 -15 32 -32 32h-64c-17 0 -32 -15 -32 -32v-96h-128v96
+c0 17 -15 32 -32 32h-64c-17 0 -32 -15 -32 -32v-320c0 -17 15 -32 32 -32h64c17 0 32 15 32 32v96h128v-96c0 -17 15 -32 32 -32h64c17 0 32 15 32 32zM1408 1088v-1280c0 -35 -29 -64 -64 -64h-1280c-35 0 -64 29 -64 64v1280c0 35 29 64 64 64h320v288c0 53 43 96 96 96
+h448c53 0 96 -43 96 -96v-288h320c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="chevron-circle-down" unicode="&#xf13a;"
+d="M813 237l454 454c25 25 25 65 0 90l-102 102c-25 25 -65 25 -90 0l-307 -307l-307 307c-25 25 -65 25 -90 0l-102 -102c-25 -25 -25 -65 0 -90l454 -454c25 -25 65 -25 90 0zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z
+" />
+ <glyph glyph-name="filter" unicode="&#xf0b0;" horiz-adv-x="1408"
+d="M1403 1241c10 -24 5 -52 -14 -70l-493 -493v-742c0 -26 -16 -49 -39 -59c-8 -3 -17 -5 -25 -5c-17 0 -33 6 -45 19l-256 256c-12 12 -19 28 -19 45v486l-493 493c-19 18 -24 46 -14 70c10 23 33 39 59 39h1280c26 0 49 -16 59 -39z" />
+ <glyph glyph-name="google-plus" unicode="&#xf0d5;" horiz-adv-x="2304"
+d="M1437 623c0 -419 -281 -716 -704 -716c-405 0 -733 328 -733 733s328 733 733 733c198 0 363 -72 491 -192l-199 -191c-54 52 -149 113 -292 113c-250 0 -454 -207 -454 -463s204 -463 454 -463c290 0 399 209 416 316h-416v252h692c7 -37 12 -74 12 -122zM2304 745v-210
+h-209v-209h-210v209h-209v210h209v209h210v-209h209z" />
+ <glyph glyph-name="sticky-note-o" unicode="&#xf24a;"
+d="M1400 256h-248v-248c17 6 34 15 41 22l185 185c7 7 16 24 22 41zM1120 384h288v896h-1280v-1280h896v288c0 53 43 96 96 96zM1536 1312v-1024c0 -53 -31 -127 -68 -164l-184 -184c-37 -37 -111 -68 -164 -68h-1024c-53 0 -96 43 -96 96v1344c0 53 43 96 96 96h1344
+c53 0 96 -43 96 -96z" />
+ <glyph glyph-name="fonticons" unicode="&#xf280;"
+d="M0 1408h1536v-1536h-1536v1536zM908 1088l-12 -33l75 -83l-31 -114l25 -25l107 57l107 -57l25 25l-31 114l75 83l-12 33h-95l-53 96h-32l-53 -96h-95zM641 925c41 0 57 -15 56 -79l174 21c0 153 -105 181 -222 181c-174 0 -265 -70 -265 -240v-72h-96v-128h76
+c10 0 20 0 20 -8v-382c0 -19 -5 -25 -23 -27l-73 -7v-88h448v86l-149 14c-18 2 -11 5 -11 25v387h191l38 128h-231c-10 0 2 7 2 15v80c0 60 2 94 65 94zM1248 96v86l-54 9c-19 3 -10 5 -10 25v520h-275l-23 -101l83 -22c13 -4 23 -13 23 -27v-370c0 -19 -8 -23 -26 -25
+l-70 -9v-86h352z" />
+ <glyph glyph-name="comments-o" unicode="&#xf0e6;" horiz-adv-x="1792"
+d="M704 1152c-312 0 -576 -176 -576 -384c0 -110 74 -216 202 -290l97 -56l-35 -84c21 12 42 25 62 39l44 31l53 -10c50 -9 101 -14 153 -14c312 0 576 176 576 384s-264 384 -576 384zM704 1280c389 0 704 -229 704 -512s-315 -512 -704 -512c-61 0 -120 6 -176 16
+c-83 -59 -177 -102 -278 -128c-27 -7 -56 -12 -86 -16h-3c-15 0 -29 12 -32 29c-4 19 9 31 20 44c39 44 83 83 117 166c-162 94 -266 239 -266 401c0 283 315 512 704 512zM1526 111c34 -83 78 -122 117 -166c11 -13 24 -25 20 -44c-4 -18 -19 -31 -35 -29
+c-30 4 -59 9 -86 16c-101 26 -195 69 -278 128c-56 -10 -115 -16 -176 -16c-181 0 -347 50 -472 132c29 -2 59 -4 88 -4c215 0 418 62 573 174c167 122 259 287 259 466c0 52 -8 103 -23 152c169 -93 279 -241 279 -408c0 -163 -104 -307 -266 -401z" />
+ <glyph glyph-name="lastfm" unicode="&#xf202;" horiz-adv-x="1792"
+d="M1292 832c0 -6 8 -34 10 -41c27 -82 90 -99 165 -120c167 -47 325 -136 325 -332c0 -199 -166 -339 -360 -339c-322 0 -422 394 -515 634c-77 198 -158 314 -381 314c-198 0 -372 -190 -372 -385c0 -207 155 -399 370 -399c95 0 194 20 258 95c31 35 61 73 83 116
+l84 -152c-11 -25 -27 -49 -44 -70l1 -1c-101 -117 -239 -152 -388 -152c-302 0 -528 267 -528 561c0 285 248 550 536 550c478 0 502 -414 664 -747c44 -92 119 -200 233 -200c104 0 196 67 196 177c0 238 -437 76 -499 467c-2 11 -3 22 -3 33c0 148 139 275 286 270
+c88 -3 141 -6 211 -68h-1c27 -25 47 -59 68 -88l-129 -99c-15 28 -29 51 -54 70v1c-24 22 -67 21 -97 21c-65 0 -119 -49 -119 -116z" />
+ <glyph glyph-name="peertube" unicode="&#xf2e4;" horiz-adv-x="1350"
+d="M0 1536l675 -450l-675 -450v900zM675 1086l675 -450l-675 -450v900zM0 636l675 -450l-675 -450v900z" />
+ <glyph glyph-name="pagelines" unicode="&#xf18c;" horiz-adv-x="1402"
+d="M1402 433c-201 -499 -683 -197 -683 -197c-148 -299 -392 -491 -674 -492c-25 0 -45 20 -45 45s20 44 45 44c235 1 440 156 574 402c-150 -58 -433 -102 -590 300c398 164 581 -41 651 -166c36 89 62 186 79 291c0 0 -510 -80 -546 358c435 175 557 -280 557 -280
+c6 61 12 192 12 195c0 0 -388 269 -139 603c455 -157 224 -593 224 -593c2 -6 2 -87 0 -122c0 0 165 325 498 210c-15 -489 -518 -388 -518 -388c-16 -100 -41 -195 -73 -283c0 0 303 335 628 73z" />
+ <glyph glyph-name="credit-card-alt" unicode="&#xf283;" horiz-adv-x="2304"
+d="M0 32v608h2304v-608c0 -88 -72 -160 -160 -160h-1984c-88 0 -160 72 -160 160zM640 256v-128h384v128h-384zM256 256v-128h256v128h-256zM2144 1408c88 0 160 -72 160 -160v-224h-2304v224c0 88 72 160 160 160h1984z" />
+ <glyph glyph-name="file-word-o" unicode="&#xf1c2;"
+d="M1468 1156c37 -37 68 -111 68 -164v-1152c0 -53 -43 -96 -96 -96h-1344c-53 0 -96 43 -96 96v1600c0 53 43 96 96 96h896c53 0 127 -31 164 -68zM1024 1400v-376h376c-6 17 -15 34 -22 41l-313 313c-7 7 -24 16 -41 22zM1408 -128v1024h-416c-53 0 -96 43 -96 96v416
+h-768v-1536h1280zM233 768h300v-107h-90l99 -438c4 -16 6 -33 7 -46l2 -21h4l4 21c3 13 4 30 8 46l144 545h114l144 -545c4 -16 6 -33 9 -46c1 -7 3 -15 3 -21h4l2 21c1 13 3 30 7 46l99 438h-90v107h300v-107h-70l-164 -661h-159l-128 485c-5 16 -6 32 -9 46l-3 24h-4
+c0 -8 -1 -16 -2 -24c-2 -16 -5 -31 -10 -46l-128 -485h-159l-164 661h-70v107z" />
+ <glyph glyph-name="map" unicode="&#xf279;" horiz-adv-x="1792"
+d="M512 1536c17 0 32 -15 32 -32v-1472c0 -12 -7 -23 -17 -28l-480 -256c-5 -3 -10 -4 -15 -4c-17 0 -32 15 -32 32v1472c0 12 7 23 17 28l480 256c5 3 10 4 15 4zM1760 1536c17 0 32 -15 32 -32v-1472c0 -12 -7 -23 -17 -28l-480 -256c-5 -3 -10 -4 -15 -4
+c-17 0 -32 15 -32 32v1472c0 12 7 23 17 28l480 256c5 3 10 4 15 4zM640 1536c5 0 10 -1 14 -3l512 -256c11 -6 18 -17 18 -29v-1472c0 -17 -15 -32 -32 -32c-5 0 -10 1 -14 3l-512 256c-11 6 -18 17 -18 29v1472c0 17 15 32 32 32z" />
+ <glyph glyph-name="object-ungroup" unicode="&#xf248;" horiz-adv-x="2304"
+d="M2304 768h-128v-640h128v-384h-384v128h-896v-128h-384v384h128v128h-384v-128h-384v384h128v640h-128v384h384v-128h896v128h384v-384h-128v-128h384v128h384v-384zM2048 1024v-128h128v128h-128zM1408 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 256
+v128h-128v-128h128zM1536 384h-128v-128h128v128zM384 384h896v128h128v640h-128v128h-896v-128h-128v-640h128v-128zM896 -128v128h-128v-128h128zM2176 -128v128h-128v-128h128zM2048 128v640h-128v128h-384v-384h128v-384h-384v128h-384v-128h128v-128h896v128h128z" />
+ <glyph glyph-name="briefcase" unicode="&#xf0b1;" horiz-adv-x="1792"
+d="M640 1280h512v128h-512v-128zM1792 640v-480c0 -88 -72 -160 -160 -160h-1472c-88 0 -160 72 -160 160v480h672v-160c0 -35 29 -64 64 -64h320c35 0 64 29 64 64v160h672zM1024 640v-128h-256v128h256zM1792 1120v-384h-1792v384c0 88 72 160 160 160h352v160
+c0 53 43 96 96 96h576c53 0 96 -43 96 -96v-160h352c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="weixin" unicode="&#xf1d7;" horiz-adv-x="2048"
+d="M580 1075c0 55 -36 91 -91 91c-54 0 -109 -36 -109 -91c0 -54 55 -90 109 -90c55 0 91 36 91 90zM1323 568c0 36 -36 72 -91 72c-36 0 -72 -36 -72 -72c0 -37 36 -73 72 -73c55 0 91 36 91 73zM1087 1075c0 55 -36 91 -90 91c-55 0 -109 -36 -109 -91
+c0 -54 54 -90 109 -90c54 0 90 36 90 90zM1722 568c0 36 -37 72 -91 72c-36 0 -72 -36 -72 -72c0 -37 36 -73 72 -73c54 0 91 36 91 73zM1456 965c-23 3 -46 4 -70 4c-344 0 -616 -257 -616 -573c0 -53 8 -104 23 -152c-23 -2 -45 -3 -68 -3c-91 0 -163 18 -254 36
+l-253 -127l72 218c-181 127 -290 291 -290 490c0 345 326 616 725 616c356 0 669 -217 731 -509zM2048 404c0 -163 -108 -308 -254 -417l55 -181l-199 109c-73 -18 -146 -37 -218 -37c-345 0 -616 236 -616 526s271 526 616 526c326 0 616 -236 616 -526z" />
+ <glyph glyph-name="stop" unicode="&#xf04d;"
+d="M1536 1344v-1408c0 -35 -29 -64 -64 -64h-1408c-35 0 -64 29 -64 64v1408c0 35 29 64 64 64h1408c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="clone" unicode="&#xf24d;" horiz-adv-x="1792"
+d="M1664 -96v1088c0 17 -15 32 -32 32h-1088c-17 0 -32 -15 -32 -32v-1088c0 -17 15 -32 32 -32h1088c17 0 32 15 32 32zM1792 992v-1088c0 -88 -72 -160 -160 -160h-1088c-88 0 -160 72 -160 160v1088c0 88 72 160 160 160h1088c88 0 160 -72 160 -160zM1408 1376v-160
+h-128v160c0 17 -15 32 -32 32h-1088c-17 0 -32 -15 -32 -32v-1088c0 -17 15 -32 32 -32h160v-128h-160c-88 0 -160 72 -160 160v1088c0 88 72 160 160 160h1088c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="thermometer-full" unicode="&#xf2c7;" horiz-adv-x="1024"
+d="M640 192c0 -106 -86 -192 -192 -192s-192 86 -192 192c0 80 50 153 128 181v907h128v-907c78 -28 128 -101 128 -181zM768 192c0 105 -50 197 -128 256v768c0 106 -86 192 -192 192s-192 -86 -192 -192v-768c-78 -59 -128 -151 -128 -256c0 -177 143 -320 320 -320
+s320 143 320 320zM896 192c0 -247 -201 -448 -448 -448s-448 201 -448 448c0 122 49 232 128 313v711c0 177 143 320 320 320s320 -143 320 -320v-711c79 -81 128 -191 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192v128h192z
+" />
+ <glyph glyph-name="plane" unicode="&#xf072;" horiz-adv-x="1402"
+d="M1376 1376c64 -64 0 -224 -96 -320l-161 -161l160 -696c3 -12 -2 -25 -12 -33l-128 -96c-5 -4 -12 -6 -19 -6c-2 0 -4 0 -7 1c-9 2 -17 7 -21 16l-279 508l-259 -259l53 -194c3 -11 0 -22 -8 -31l-96 -96c-6 -6 -15 -9 -23 -9h-2c-10 1 -18 5 -24 13l-189 252l-252 189
+c-8 5 -12 14 -13 23s3 18 9 25l96 97c6 6 15 9 23 9c3 0 6 0 8 -1l194 -53l259 259l-508 279c-9 5 -15 14 -17 24c-1 9 2 20 9 27l128 128c8 7 20 11 30 8l665 -159l160 160c96 96 256 160 320 96z" />
+ <glyph glyph-name="check-square" unicode="&#xf14a;"
+d="M685 237l614 614c25 25 25 65 0 90l-102 102c-25 25 -65 25 -90 0l-467 -467l-211 211c-25 25 -65 25 -90 0l-102 -102c-25 -25 -25 -65 0 -90l358 -358c25 -25 65 -25 90 0zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960
+c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="window-maximize" unicode="&#xf2d0;" horiz-adv-x="1792"
+d="M256 128h1280v768h-1280v-768zM1792 1248v-1216c0 -88 -72 -160 -160 -160h-1472c-88 0 -160 72 -160 160v1216c0 88 72 160 160 160h1472c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="github" unicode="&#xf09b;"
+d="M768 1408c424 0 768 -344 768 -768c0 -339 -220 -627 -525 -729c-39 -7 -53 17 -53 37c0 25 1 108 1 211c0 72 -24 118 -52 142c171 19 351 84 351 379c0 84 -30 152 -79 206c8 20 34 98 -8 204c-64 20 -211 -79 -211 -79c-61 17 -127 26 -192 26s-131 -9 -192 -26
+c0 0 -147 99 -211 79c-42 -106 -16 -184 -8 -204c-49 -54 -79 -122 -79 -206c0 -294 179 -360 350 -379c-22 -20 -42 -54 -49 -103c-44 -20 -156 -54 -223 64c-42 73 -118 79 -118 79c-75 1 -5 -47 -5 -47c50 -23 85 -112 85 -112c45 -137 259 -91 259 -91
+c0 -64 1 -124 1 -143c0 -20 -14 -44 -53 -37c-305 102 -525 390 -525 729c0 424 344 768 768 768zM291 305c-2 -4 -8 -5 -13 -2c-6 3 -9 8 -7 12c2 3 7 4 13 2c6 -3 9 -8 7 -12zM322 271c-4 -4 -11 -2 -16 3c-5 6 -6 13 -2 16c4 4 11 2 16 -3c5 -6 6 -13 2 -16zM352 226
+c-4 -3 -12 0 -17 7s-5 15 0 18c5 4 13 1 17 -6c5 -7 5 -15 0 -19zM394 184c-4 -5 -13 -4 -20 3c-7 6 -9 15 -4 19c4 5 13 4 20 -3c6 -6 8 -15 4 -19zM451 159c-2 -6 -11 -9 -19 -6c-9 2 -15 9 -13 15s11 9 19 7c9 -3 15 -10 13 -16zM514 154c0 -6 -7 -11 -16 -11
+c-10 -1 -17 4 -17 11c0 6 7 11 16 11c9 1 17 -4 17 -11zM572 164c1 -6 -5 -12 -14 -14s-17 2 -18 8c-1 7 5 13 14 15c9 1 17 -3 18 -9z" />
+ <glyph glyph-name="mastodon" unicode="&#xf2e1;"
+d="M1503 425c-23 -116 -202 -243 -408 -268c-108 -13 -214 -25 -327 -20c-185 8 -330 44 -330 44c0 -18 1 -35 3 -51c24 -182 181 -193 329 -198c150 -5 284 37 284 37l6 -136s-105 -56 -292 -66c-103 -6 -230 3 -379 42c-323 85 -379 430 -388 779c-3 104 -1 201 -1 283
+c0 357 235 462 235 462c118 54 320 77 531 79h5c211 -2 413 -25 531 -79c0 0 234 -105 234 -462c0 0 3 -263 -33 -446zM1260 843c0 88 -22 160 -68 211c-47 52 -107 79 -183 79c-88 0 -154 -34 -198 -101l-43 -72l-43 72c-44 67 -110 101 -198 101c-76 0 -136 -27 -183 -79
+c-45 -52 -68 -123 -68 -211v-432h171v420c0 88 38 133 112 133c82 0 124 -54 124 -159v-229h170v229c0 105 42 159 124 159c74 0 112 -45 112 -133v-420h171v432v0z" />
+ <glyph glyph-name="envelope-open" unicode="&#xf2b6;" horiz-adv-x="1792"
+d="M1792 882v-978c0 -88 -72 -160 -160 -160h-1472c-88 0 -160 72 -160 160v978c0 9 4 18 11 24c105 92 106 103 628 484c63 46 174 146 257 146s195 -101 257 -146c522 -381 523 -392 628 -484c7 -6 11 -15 11 -24zM1228 297c156 113 265 192 345 252c14 10 17 30 6 44
+l-38 52c-11 14 -31 17 -45 6c-79 -58 -187 -138 -343 -250c-62 -45 -174 -145 -257 -145s-195 100 -257 145c-156 113 -264 192 -343 250c-14 11 -34 8 -45 -6l-38 -52c-11 -14 -8 -34 6 -44c80 -60 189 -139 345 -252c78 -56 201 -169 332 -169c132 0 258 115 332 169z" />
+ <glyph glyph-name="step-backward" unicode="&#xf048;" horiz-adv-x="1024"
+d="M979 1395c25 25 45 16 45 -19v-1472c0 -35 -20 -44 -45 -19l-710 710c-6 6 -10 12 -13 19v-678c0 -35 -29 -64 -64 -64h-128c-35 0 -64 29 -64 64v1408c0 35 29 64 64 64h128c35 0 64 -29 64 -64v-678c3 7 7 13 13 19z" />
+ <glyph glyph-name="wheelchair" unicode="&#xf193;" horiz-adv-x="1629"
+d="M1023 349l102 -204c-77 -238 -299 -401 -549 -401c-317 0 -576 259 -576 576c0 242 152 458 379 541l17 -131c-163 -72 -268 -232 -268 -410c0 -247 201 -448 448 -448c257 0 465 220 447 477zM1571 249l58 -114l-256 -128c-9 -5 -19 -7 -29 -7c-24 0 -47 14 -57 35
+l-239 477h-472c-32 0 -60 25 -64 57l-96 779c-1 10 3 32 6 42c19 69 83 114 154 114c88 0 160 -72 160 -160c0 -91 -80 -169 -172 -159l37 -289h423v-128h-407l16 -128h455c24 0 47 -14 57 -35l228 -455z" />
+ <glyph glyph-name="bootstrap" unicode="&#xf315;"
+d="M256 1408h1024c141 0 256 -115 256 -256v-1024c0 -141 -115 -256 -256 -256h-1024c-141 0 -256 115 -256 256v1024c0 141 115 256 256 256zM494 1020v-795h310c169 0 270 83 270 223c0 106 -69 182 -177 196v4c77 14 137 91 137 174c0 119 -93 198 -229 198h-311z
+M593 933h190c97 0 150 -44 150 -123c0 -86 -64 -133 -181 -133h-159v256zM593 592v0h187c127 0 192 -47 192 -139s-63 -141 -183 -141h-196v280z" />
+ <glyph glyph-name="cutlery" unicode="&#xf0f5;" horiz-adv-x="1408"
+d="M640 1472v-640c0 -81 -52 -154 -128 -181v-779c0 -70 -58 -128 -128 -128h-128c-70 0 -128 58 -128 128v779c-76 27 -128 100 -128 181v640c0 35 29 64 64 64s64 -29 64 -64v-416c0 -35 29 -64 64 -64s64 29 64 64v416c0 35 29 64 64 64s64 -29 64 -64v-416
+c0 -35 29 -64 64 -64s64 29 64 64v416c0 35 29 64 64 64s64 -29 64 -64zM1408 1472v-1600c0 -70 -58 -128 -128 -128h-128c-70 0 -128 58 -128 128v512h-224c-17 0 -32 15 -32 32v800c0 176 144 320 320 320h256c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="microphone-slash" unicode="&#xf131;" horiz-adv-x="1382"
+d="M258 591l-101 -101c-27 66 -42 138 -42 214v128c0 35 29 64 64 64s64 -29 64 -64v-128c0 -39 6 -77 15 -113zM1372 1193l-361 -361v-128c0 -176 -144 -320 -320 -320c-38 0 -75 7 -109 19l-96 -96c61 -32 131 -51 205 -51c247 0 448 201 448 448v128c0 35 29 64 64 64
+s64 -29 64 -64v-128c0 -296 -224 -540 -512 -572v-132h256c35 0 64 -29 64 -64s-29 -64 -64 -64h-640c-35 0 -64 29 -64 64s29 64 64 64h256v132c-85 9 -165 38 -235 81l-254 -254c-13 -13 -33 -13 -46 0l-82 82c-13 13 -13 33 0 46l1234 1234c13 13 33 13 46 0l82 -82
+c13 -13 13 -33 0 -46zM992 1325l-621 -621v512c0 176 144 320 320 320c138 0 256 -89 301 -211z" />
+ <glyph glyph-name="user-plus" unicode="&#xf234;" horiz-adv-x="2048"
+d="M704 640c-212 0 -384 172 -384 384s172 384 384 384s384 -172 384 -384s-172 -384 -384 -384zM1664 512h352c17 0 32 -15 32 -32v-192c0 -17 -15 -32 -32 -32h-352v-352c0 -17 -15 -32 -32 -32h-192c-17 0 -32 15 -32 32v352h-352c-17 0 -32 15 -32 32v192
+c0 17 15 32 32 32h352v352c0 17 15 32 32 32h192c17 0 32 -15 32 -32v-352zM928 288c0 -70 58 -128 128 -128h256v-238c-49 -36 -111 -50 -171 -50h-874c-160 0 -267 96 -267 259c0 226 53 573 346 573c16 0 27 -7 39 -17c98 -75 193 -122 319 -122s221 47 319 122
+c12 10 23 17 39 17c85 0 160 -32 217 -96h-223c-70 0 -128 -58 -128 -128v-192z" />
+ <glyph glyph-name="truck" unicode="&#xf0d1;" horiz-adv-x="1728"
+d="M576 128c0 70 -58 128 -128 128s-128 -58 -128 -128s58 -128 128 -128s128 58 128 128zM192 640h384v256h-158c-4 0 -19 -6 -22 -9l-195 -195c-3 -3 -9 -18 -9 -22v-30zM1472 128c0 70 -58 128 -128 128s-128 -58 -128 -128s58 -128 128 -128s128 58 128 128zM1728 1216
+v-1024c0 -74 -78 -64 -128 -64c0 -141 -115 -256 -256 -256s-256 115 -256 256h-384c0 -141 -115 -256 -256 -256s-256 115 -256 256h-64c-50 0 -128 -10 -128 64c0 35 29 64 64 64v320c0 71 -10 150 45 205l198 198c25 25 73 45 109 45h160v192c0 35 29 64 64 64h1024
+c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="wrench" unicode="&#xf0ad;" horiz-adv-x="1641"
+d="M363 64c0 35 -29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64s64 29 64 64zM1007 484l-682 -682c-23 -23 -56 -37 -90 -37s-67 14 -91 37l-106 108c-24 23 -38 56 -38 90s14 67 38 91l681 681c52 -131 157 -236 288 -288zM1641 919c0 -33 -12 -74 -23 -106
+c-63 -178 -234 -301 -423 -301c-247 0 -448 201 -448 448s201 448 448 448c73 0 168 -22 229 -63c10 -7 16 -16 16 -28c0 -11 -7 -22 -16 -28l-293 -169v-224l193 -107c33 19 265 165 285 165s32 -15 32 -35z" />
+ <glyph glyph-name="ambulance" unicode="&#xf0f9;" horiz-adv-x="1856"
+d="M576 128c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM192 640h384v256h-158c-6 -1 -17 -5 -22 -9l-195 -195c-3 -5 -8 -16 -9 -22v-30zM1472 128c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM1600 800
+v192c0 18 -14 32 -32 32h-224v224c0 18 -14 32 -32 32h-192c-18 0 -32 -14 -32 -32v-224h-224c-18 0 -32 -14 -32 -32v-192c0 -18 14 -32 32 -32h224v-224c0 -18 14 -32 32 -32h192c18 0 32 14 32 32v224h224c18 0 32 14 32 32zM1856 1344v-1152c0 -35 -29 -64 -64 -64h-192
+c0 -141 -114 -256 -256 -256c-141 0 -256 115 -256 256h-384c0 -141 -114 -256 -256 -256s-256 115 -256 256h-128c-35 0 -64 29 -64 64s29 64 64 64v416c0 35 20 84 45 109l198 198c25 25 74 45 109 45h160v320c0 35 29 64 64 64h1152c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="cc-visa" unicode="&#xf1f0;" horiz-adv-x="2304"
+d="M1975 546h-138s14 37 66 179c-1 -1 14 37 22 61l12 -55c31 -153 38 -185 38 -185zM531 611l-58 295c-8 41 -39 54 -75 54h-268l-2 -13c184 -47 335 -147 403 -336zM710 960l-162 -438l-17 89c-35 93 -120 179 -216 218l135 -510h175l261 641h-176zM849 318h166l104 642
+h-166zM1617 944c-33 13 -85 27 -149 27c-164 0 -279 -87 -280 -212c-1 -92 82 -143 145 -174c65 -31 86 -52 86 -80c0 -43 -52 -62 -99 -62c-67 0 -103 8 -156 33l-22 11l-23 -144c39 -18 110 -34 185 -34c174 -1 287 86 289 219c0 73 -45 128 -140 174
+c-58 29 -93 50 -93 80c0 27 30 55 95 55c54 1 94 -10 124 -24l15 -8zM2042 960h-128c-40 0 -70 -12 -87 -54l-246 -588h174c28 79 35 96 35 96h212s5 -22 20 -96h154zM2304 1280v-1280c0 -70 -58 -128 -128 -128h-2048c-70 0 -128 58 -128 128v1280c0 70 58 128 128 128
+h2048c70 0 128 -58 128 -128z" />
+ <glyph glyph-name="superscript" unicode="&#xf12b;" horiz-adv-x="1529"
+d="M892 167v-167h-248l-159 252l-24 42c-6 7 -9 14 -11 21h-3c-2 -7 -6 -14 -9 -21c-6 -12 -15 -28 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228c9 -14 16 -29 23 -42c6 -7 9 -14 11 -21h3c2 7 6 14 11 21l25 42l140 228h257v-168h-125
+l-184 -267l204 -296h109zM1529 846v-206h-514l-3 27c-2 14 -4 33 -4 46c0 273 350 296 350 441c0 52 -47 87 -100 87c-38 0 -72 -18 -97 -39c-13 -11 -25 -25 -36 -38l-105 92c18 25 38 46 63 66c42 33 103 65 188 65c145 0 246 -85 246 -218c0 -240 -332 -260 -346 -403
+h232v80h126z" />
+ <glyph glyph-name="pixelfed" unicode="&#xf314;"
+d="M768 -128c-424 0 -768 344 -768 768s344 768 768 768s768 -344 768 -768s-344 -768 -768 -768zM707 472h141c133 0 240 105 240 234s-107 234 -240 234h-203c-77 0 -139 -60 -139 -135v-525z" />
+ <glyph glyph-name="tty" unicode="&#xf1e4;" horiz-adv-x="1792"
+d="M448 224v-192c0 -18 -14 -32 -32 -32h-192c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h192c18 0 32 -14 32 -32zM256 608v-192c0 -18 -14 -32 -32 -32h-192c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h192c18 0 32 -14 32 -32zM832 224v-192c0 -18 -14 -32 -32 -32h-192
+c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h192c18 0 32 -14 32 -32zM640 608v-192c0 -18 -14 -32 -32 -32h-192c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h192c18 0 32 -14 32 -32zM66 768c-37 0 -66 29 -66 65v129h514v-129c0 -36 -29 -65 -65 -65h-383zM1216 224v-192
+c0 -18 -14 -32 -32 -32h-192c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h192c18 0 32 -14 32 -32zM1024 608v-192c0 -18 -14 -32 -32 -32h-192c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h192c18 0 32 -14 32 -32zM1600 224v-192c0 -18 -14 -32 -32 -32h-192
+c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h192c18 0 32 -14 32 -32zM1408 608v-192c0 -18 -14 -32 -32 -32h-192c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h192c18 0 32 -14 32 -32zM1792 1016v-13h-514v10c0 37 -32 104 -382 102c-350 -1 -382 -65 -382 -102v-10h-514v13
+c0 67 120 392 896 392c775 0 896 -325 896 -392zM1792 608v-192c0 -18 -14 -32 -32 -32h-192c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h192c18 0 32 -14 32 -32zM1792 962v-129c0 -36 -29 -65 -65 -65h-384c-36 0 -65 29 -65 65v129h514z" />
+ <glyph glyph-name="linode" unicode="&#xf2b8;" horiz-adv-x="1494"
+d="M309 1l202 -214l-34 236l-216 213zM535 -225l274 218l-11 245l-300 -215zM224 413l227 -213l-48 327l-245 204zM474 189l317 214l-14 324l-352 -200zM822 178l95 -80l-2 239l-103 79c0 -8 4 -22 -4 -28l-78 -52l85 -70c10 -8 7 -76 7 -88zM117 930l256 -200l-68 465
+l-279 173zM1152 267l15 234l-230 -164l2 -240zM396 722l373 194l-19 441l-423 -163zM1249 357l20 233l-226 142l-2 -105l144 -95c3 -2 5 -6 4 -9l-7 -119zM1440 496l30 222l-179 -128l-20 -228zM1252 329l-71 49l-8 -117c0 -3 -1 -6 -4 -8l-234 -187c-4 -3 -10 -3 -14 0
+l-98 83l7 -161c0 -3 -1 -6 -4 -8l-293 -234c-2 -1 -4 -2 -6 -2c-3 1 -6 1 -8 3l-228 242c-5 5 -54 252 -59 277c-1 4 2 9 5 11l61 37c-12 11 -93 82 -95 92l-72 351c-1 4 1 9 6 12l94 45c-16 12 -132 96 -135 108l-96 466c-1 6 2 11 7 13l433 135c2 0 5 0 8 -1l317 -153
+c3 -2 6 -6 6 -9l20 -463c0 -4 -2 -8 -6 -10l-118 -61l126 -85c3 -1 5 -5 5 -8l5 -123l121 74c3 2 8 2 11 0l84 -56l3 110c0 3 2 7 5 9l206 126c4 2 8 2 11 0l245 -135c2 -2 4 -4 5 -7c2 -7 -31 -232 -34 -255c0 -3 -2 -6 -4 -7l-191 -153c-4 -3 -9 -3 -13 0z" />
+ <glyph glyph-name="shield" unicode="&#xf132;" horiz-adv-x="1280"
+d="M1088 576v640h-448v-1137c51 27 133 74 213 137c107 84 235 215 235 360zM1280 1344v-768c0 -421 -589 -687 -614 -698c-8 -4 -17 -6 -26 -6s-18 2 -26 6c-25 11 -614 277 -614 698v768c0 35 29 64 64 64h1152c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="user-md" unicode="&#xf0f0;" horiz-adv-x="1408"
+d="M384 192c0 -35 -29 -64 -64 -64s-64 29 -64 64s29 64 64 64s64 -29 64 -64zM1408 131c0 -163 -107 -259 -267 -259h-874c-160 0 -267 96 -267 259c0 199 40 513 278 565c-16 -38 -22 -79 -22 -120v-203c-77 -27 -128 -100 -128 -181c0 -106 86 -192 192 -192
+s192 86 192 192c0 81 -52 154 -128 181v203c0 33 3 66 25 93c84 -66 188 -104 295 -104s211 38 295 104c22 -27 25 -60 25 -93v-64c-141 0 -256 -115 -256 -256v-89c-20 -18 -32 -44 -32 -71c0 -53 43 -96 96 -96s96 43 96 96c0 27 -12 53 -32 71v89c0 70 58 128 128 128
+s128 -58 128 -128v-89c-20 -18 -32 -44 -32 -71c0 -53 43 -96 96 -96s96 43 96 96c0 27 -12 53 -32 71v89c0 91 -49 176 -128 221c0 73 7 151 -22 219c238 -52 278 -366 278 -565zM1088 1024c0 -212 -172 -384 -384 -384s-384 172 -384 384s172 384 384 384
+s384 -172 384 -384z" />
+ <glyph glyph-name="xmpp" unicode="&#xf2f9;" horiz-adv-x="1542"
+d="M1536 1314c47 -398 -206 -904 -657 -1199c122 -101 261 -177 414 -216v-27c-165 14 -320 59 -461 128l-30 15l-1 1l-6 3c-11 6 -30 16 -41 22c-94 -51 -193 -90 -297 -116c-68 -19 -139 -33 -211 -42v28c145 37 279 107 396 201c-426 296 -682 805 -637 1192l93 -33v0
+l273 -81c-1 -16 -1 -32 -1 -49c0 -296 147 -656 394 -917c254 262 406 628 406 929c0 17 0 33 -1 49l274 81z" />
+ <glyph glyph-name="moon-o" unicode="&#xf186;" horiz-adv-x="1471"
+d="M1262 233c-36 -6 -73 -9 -110 -9c-371 0 -672 301 -672 672c0 127 37 251 104 357c-266 -79 -456 -323 -456 -613c0 -353 287 -640 640 -640c193 0 374 88 494 233zM1465 318c-125 -271 -399 -446 -697 -446c-423 0 -768 345 -768 768c0 415 325 752 739 767
+c28 1 51 -15 61 -39c11 -25 4 -54 -15 -72c-114 -104 -177 -246 -177 -400c0 -300 244 -544 544 -544c79 0 155 17 228 51c25 11 53 6 72 -13s24 -48 13 -72z" />
+ <glyph glyph-name="pie-chart" unicode="&#xf200;" horiz-adv-x="1728"
+d="M768 646l546 -546c-139 -141 -333 -228 -546 -228c-424 0 -768 344 -768 768s344 768 768 768v-762zM955 640h773c0 -213 -87 -407 -228 -546zM1664 768h-768v768c424 0 768 -344 768 -768z" />
+ <glyph glyph-name="align-left" unicode="&#xf036;" horiz-adv-x="1792"
+d="M1792 192v-128c0 -35 -29 -64 -64 -64h-1664c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1664c35 0 64 -29 64 -64zM1408 576v-128c0 -35 -29 -64 -64 -64h-1280c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1280c35 0 64 -29 64 -64zM1664 960v-128
+c0 -35 -29 -64 -64 -64h-1536c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1536c35 0 64 -29 64 -64zM1280 1344v-128c0 -35 -29 -64 -64 -64h-1152c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1152c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="motorcycle" unicode="&#xf21c;" horiz-adv-x="2304"
+d="M2301 500c32 -281 -197 -517 -476 -499c-214 14 -392 185 -414 399c-16 152 44 289 146 381l-71 107c-126 -105 -206 -262 -206 -438c0 -36 -28 -66 -64 -66h-325c-31 -217 -217 -384 -443 -384c-247 0 -448 201 -448 448s201 448 448 448c53 0 104 -10 152 -27l24 45
+c-77 69 -178 110 -304 110h-64c-35 0 -64 29 -64 64s29 64 64 64h128c224 0 338 -92 384 -128h627l-85 128h-222c-39 0 -70 35 -63 75c5 31 35 53 66 53h253c21 0 41 -11 53 -28l70 -105l114 114c12 12 29 19 46 19h101c35 0 64 -29 64 -64v-128c0 -35 -29 -64 -64 -64h-179
+l115 -172c81 39 175 55 275 36c191 -35 340 -195 362 -388zM448 128c155 0 284 110 314 256h-314c-22 0 -43 12 -55 31c-11 19 -12 43 -1 63l147 277c-29 8 -59 13 -91 13c-176 0 -320 -144 -320 -320s144 -320 320 -320zM1856 128c176 0 320 144 320 320s-144 320 -320 320
+c-43 0 -83 -9 -121 -24l174 -260c20 -30 12 -70 -17 -89c-11 -8 -24 -11 -36 -11c-21 0 -41 10 -53 29l-174 260c-57 -58 -93 -137 -93 -225c0 -176 144 -320 320 -320z" />
+ <glyph glyph-name="nextcloud-square" unicode="&#xf307;"
+d="M257 1408h1022c142 0 257 -115 257 -257v-1022c0 -142 -115 -257 -257 -257h-1022c-142 0 -257 115 -257 257v1022c0 142 115 257 257 257zM772 969v0c-145 0 -268 -98 -307 -230c-34 69 -105 118 -187 118c-114 0 -208 -94 -208 -208s94 -207 208 -207
+c82 0 153 48 187 117c39 -132 162 -230 307 -230s267 98 306 230c34 -69 105 -117 187 -117c114 0 208 93 208 207s-94 208 -208 208c-82 0 -153 -49 -187 -118c-39 132 -161 230 -306 230zM772 846v0c106 0 196 -88 196 -197s-87 -196 -196 -196s-197 87 -197 196
+s88 197 197 197zM278 733c47 0 84 -37 84 -84s-37 -84 -84 -84s-84 37 -84 84s37 84 84 84zM1265 733c47 0 84 -37 84 -84s-37 -84 -84 -84s-84 37 -84 84s37 84 84 84z" />
+ <glyph glyph-name="ticket" unicode="&#xf145;" horiz-adv-x="1685"
+d="M970 1084l316 -316l-572 -572l-316 316zM760 105l618 618c25 25 25 65 0 90l-362 362c-24 24 -66 24 -90 0l-618 -618c-25 -25 -25 -65 0 -90l362 -362c12 -12 27 -18 44 -18s34 6 46 18zM1648 742l-906 -908c-50 -49 -133 -49 -182 0l-126 126c75 75 75 197 0 272
+s-197 75 -272 0l-124 126c-50 49 -50 131 0 181l906 906c49 50 132 50 182 0l124 -125c-75 -75 -75 -197 0 -272s197 -75 272 0l126 -125c49 -50 49 -132 0 -181z" />
+ <glyph glyph-name="battery-half" unicode="&#xf242;" horiz-adv-x="2304"
+d="M256 256v768h896v-768h-896zM2176 960c71 0 128 -57 128 -128v-384c0 -71 -57 -128 -128 -128v-160c0 -88 -72 -160 -160 -160h-1856c-88 0 -160 72 -160 160v960c0 88 72 160 160 160h1856c88 0 160 -72 160 -160v-160zM2176 448v384h-128v288c0 18 -14 32 -32 32h-1856
+c-18 0 -32 -14 -32 -32v-960c0 -18 14 -32 32 -32h1856c18 0 32 14 32 32v288h128z" />
+ <glyph glyph-name="spotify" unicode="&#xf1bc;"
+d="M1127 326c0 28 -11 39 -30 51c-129 77 -279 115 -447 115c-98 0 -192 -13 -287 -34c-23 -5 -42 -20 -42 -52c0 -25 19 -49 49 -49c9 0 25 5 37 8c78 16 160 27 243 27c147 0 286 -36 397 -103c12 -7 20 -11 33 -11c25 0 47 20 47 48zM1223 541c0 27 -10 46 -35 61
+c-153 91 -347 141 -548 141c-129 0 -217 -18 -303 -42c-32 -9 -48 -31 -48 -64s27 -60 60 -60c14 0 22 4 37 8c70 19 154 33 251 33c190 0 363 -50 488 -124c11 -6 22 -13 38 -13c34 0 60 27 60 60zM1331 789c0 37 -16 56 -40 70c-173 101 -410 148 -636 148
+c-133 0 -255 -15 -364 -47c-28 -8 -54 -32 -54 -74c0 -41 31 -73 72 -73c15 0 29 5 40 8c97 27 202 37 307 37c208 0 424 -46 563 -129c14 -8 24 -12 40 -12c38 0 72 30 72 72zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z
+" />
+ <glyph glyph-name="dot-circle-o" unicode="&#xf192;"
+d="M1024 640c0 -141 -115 -256 -256 -256s-256 115 -256 256s115 256 256 256s256 -115 256 -256zM768 1184c-300 0 -544 -244 -544 -544s244 -544 544 -544s544 244 544 544s-244 544 -544 544zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768
+s768 -344 768 -768z" />
+ <glyph glyph-name="facebook-square" unicode="&#xf082;"
+d="M1248 1408c159 0 288 -129 288 -288v-960c0 -159 -129 -288 -288 -288h-188v595h199l30 232h-229v148c0 67 18 112 115 112l122 1v207c-21 3 -94 9 -178 9c-177 0 -299 -108 -299 -306v-171h-200v-232h200v-595h-532c-159 0 -288 129 -288 288v960c0 159 129 288 288 288
+h960z" />
+ <glyph glyph-name="facebook-messenger" unicode="&#xf2fe;" horiz-adv-x="1520"
+d="M760 1408c420 0 760 -318 760 -711c0 -476 -490 -817 -978 -681l-260 -144v272c-556 420 -235 1264 478 1264zM841 455l415 440l-379 -209l-197 204l-415 -441l379 210z" />
+ <glyph glyph-name="angle-up" unicode="&#xf106;" horiz-adv-x="998"
+d="M998 352c0 -8 -4 -17 -10 -23l-50 -50c-6 -6 -14 -10 -23 -10c-8 0 -17 4 -23 10l-393 393l-393 -393c-6 -6 -15 -10 -23 -10s-17 4 -23 10l-50 50c-6 6 -10 15 -10 23s4 17 10 23l466 466c6 6 15 10 23 10s17 -4 23 -10l466 -466c6 -6 10 -15 10 -23z" />
+ <glyph glyph-name="glide" unicode="&#xf2a5;"
+d="M866 1021c0 -32 -7 -63 -13 -94c-21 -100 -41 -200 -62 -300c-3 -14 -3 -14 -18 -15c-10 -1 -21 -2 -31 -2c-86 0 -110 93 -110 163c0 104 41 243 138 298c16 8 33 14 51 14c41 0 45 -30 45 -64zM1352 597c0 18 -74 135 -91 142c-8 3 -25 8 -34 8
+c-82 0 -156 -37 -226 -77l-2 2c16 107 52 202 52 313c0 159 -85 233 -242 233c-23 0 -46 -3 -68 -6c-197 -35 -317 -260 -317 -445c0 -196 113 -304 308 -304c4 0 25 2 25 -3c0 -2 0 -3 -1 -5c-4 -38 -16 -80 -26 -117c-15 -55 -67 -150 -134 -150c-29 0 -42 20 -42 47
+c0 87 100 139 102 144c0 4 -5 8 -7 10c-31 28 -82 51 -124 51c-76 0 -117 -122 -117 -184c0 -116 73 -196 190 -196c173 0 299 182 338 332c11 44 19 89 30 133c2 9 5 13 14 18c71 36 146 60 227 60c44 0 83 -8 127 -18c1 -1 3 -1 4 -1c6 0 14 7 14 13zM1536 1120v-960
+c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="gitea" unicode="&#xf31f;" horiz-adv-x="2066"
+d="M366 1280v0c62 0 120 -8 160 -8v0v0c329 -18 502 -29 699 -29l1 -363l53 -27v390c171 2 371 11 709 29v0h1c15 0 28 -7 38 -17s18 -25 24 -43c12 -36 16 -85 15 -143c-3 -117 -30 -272 -75 -427s-107 -311 -182 -431s-163 -204 -259 -211h-615c-75 8 -156 85 -224 169
+c-34 42 -64 87 -87 126c-21 36 -35 66 -41 88c-82 2 -219 15 -341 80c-125 67 -233 191 -242 414c-6 143 45 245 118 310s167 93 248 93zM388 1107v0c-90 -1 -147 -29 -180 -71c-36 -44 -46 -104 -38 -164c14 -113 61 -183 126 -229c62 -44 143 -65 231 -78
+c-70 193 -106 325 -128 542h-11zM1118 893c-34 0 -66 -19 -82 -51l-172 -353c-22 -45 -3 -99 42 -121l354 -172c45 -22 99 -3 121 42l171 354c22 45 3 99 -42 121l-249 121l-45 -93c5 -5 10 -14 12 -20c2 -5 3 -13 3 -19v-4c30 -14 54 -25 74 -36c30 -17 52 -34 59 -62
+s-1 -57 -17 -95c-12 -29 -29 -65 -51 -111c4 -5 9 -13 11 -19c2 -5 4 -13 4 -19c0 -22 -17 -46 -38 -54c-5 -2 -14 -4 -20 -4c-22 0 -46 17 -54 38c-2 5 -3 14 -3 20c0 22 17 46 38 54c5 2 14 3 19 3h2c22 46 41 82 52 109c15 36 18 55 15 66s-13 20 -39 35
+c-18 10 -41 22 -71 36c-4 -4 -13 -9 -19 -11c-5 -2 -14 -3 -19 -3h-6l-77 -158c5 -5 12 -14 14 -21c2 -5 3 -13 3 -19c0 -22 -17 -46 -38 -54c-5 -2 -13 -4 -19 -4c-22 0 -46 17 -54 38c-2 5 -3 14 -3 20c0 22 16 46 37 54c5 2 15 3 20 3l79 162c-3 4 -8 11 -10 16
+s-3 14 -3 20c0 22 17 46 38 54c5 2 14 3 19 3h1l46 94l-64 31c-13 6 -26 9 -39 9z" />
+ <glyph glyph-name="f-droid" unicode="&#xf32a;" horiz-adv-x="1676"
+d="M47 1526v0c12 0 29 -8 36 -18l127 -164c10 3 27 6 37 6v0h1182v0c10 0 27 -3 37 -6l127 164c7 9 22 17 34 18h2h3c24 -1 44 -22 44 -46c0 -9 -4 -22 -10 -29l-133 -172c4 -11 7 -29 7 -40v0v-258c0 -61 -50 -111 -111 -111h-1182c-61 0 -111 50 -111 111v258v0
+c0 11 3 29 7 40l-133 172c-6 7 -10 20 -10 29c0 26 20 46 46 46h1zM482 1212v0c-69 0 -125 -56 -125 -125v0c0 -69 56 -125 125 -125v0c69 0 125 56 125 125v0c0 69 -56 125 -125 125v0zM1203 1212c-69 0 -125 -56 -125 -125v0c0 -69 56 -125 125 -125s125 56 125 125v0
+c0 69 -56 125 -125 125zM247 833h1182c61 0 111 -50 111 -111v-739c0 -61 -50 -111 -111 -111h-1182c-61 0 -111 50 -111 111v739c0 61 50 111 111 111zM838 740v0c-214 0 -388 -174 -388 -388s174 -388 388 -388s388 174 388 388s-174 388 -388 388zM838 670v0
+c176 0 318 -142 318 -318s-142 -317 -318 -317s-318 141 -318 317s142 318 318 318zM838 583v0c-106 0 -197 -72 -223 -171h119c20 36 59 61 104 61c67 0 120 -54 120 -121s-53 -120 -120 -120c-48 0 -89 28 -108 69h-117c24 -102 116 -180 225 -180c127 0 231 104 231 231
+s-104 231 -231 231z" />
+ <glyph glyph-name="shopping-basket" unicode="&#xf291;" horiz-adv-x="2048"
+d="M1920 768c71 0 128 -57 128 -128s-57 -128 -128 -128h-15l-115 -662c-11 -61 -64 -106 -126 -106h-1280c-62 0 -115 45 -126 106l-115 662h-15c-71 0 -128 57 -128 128s57 128 128 128h1792zM485 -32c35 3 62 34 59 69l-32 416c-3 35 -34 62 -69 59s-62 -34 -59 -69
+l32 -416c3 -33 31 -59 64 -59h5zM896 32v416c0 35 -29 64 -64 64s-64 -29 -64 -64v-416c0 -35 29 -64 64 -64s64 29 64 64zM1280 32v416c0 35 -29 64 -64 64s-64 -29 -64 -64v-416c0 -35 29 -64 64 -64s64 29 64 64zM1632 27l32 416c3 35 -24 66 -59 69s-66 -24 -69 -59
+l-32 -416c-3 -35 24 -66 59 -69h5c33 0 61 26 64 59zM476 1244l-93 -412h-132l101 441c26 117 129 199 249 199h167c0 35 29 64 64 64h384c35 0 64 -29 64 -64h167c120 0 223 -82 249 -199l101 -441h-132l-93 412c-14 59 -65 100 -125 100h-167c0 -35 -29 -64 -64 -64h-384
+c-35 0 -64 29 -64 64h-167c-60 0 -111 -41 -125 -100z" />
+ <glyph glyph-name="user-o" unicode="&#xf2c0;"
+d="M1201 752c141 -41 335 -180 335 -635c0 -206 -153 -373 -341 -373h-854c-188 0 -341 167 -341 373c0 455 194 594 335 635c-50 79 -79 172 -79 272c0 282 230 512 512 512s512 -230 512 -512c0 -100 -29 -193 -79 -272zM768 1408c-212 0 -384 -172 -384 -384
+s172 -384 384 -384s384 172 384 384s-172 384 -384 384zM1195 -128c117 0 213 109 213 245c0 315 -106 512 -304 522c-90 -79 -207 -127 -336 -127s-246 48 -336 127c-198 -10 -304 -207 -304 -522c0 -136 96 -245 213 -245h854z" />
+ <glyph glyph-name="paperclip" unicode="&#xf0c6;" horiz-adv-x="1400"
+d="M1400 151c0 -156 -119 -275 -275 -275c-88 0 -173 38 -235 100l-777 776c-71 72 -113 170 -113 271c0 212 167 381 379 381c102 0 200 -41 273 -113l605 -606c6 -6 10 -14 10 -22c0 -21 -56 -77 -77 -77c-9 0 -17 4 -23 10l-606 607c-48 47 -113 77 -181 77
+c-142 0 -252 -115 -252 -256c0 -68 28 -133 76 -181l776 -777c38 -38 91 -63 145 -63c85 0 148 63 148 148c0 55 -25 107 -63 145l-581 581c-16 15 -38 24 -60 24c-38 0 -67 -28 -67 -67c0 -22 10 -43 25 -59l410 -410c6 -6 10 -14 10 -22c0 -21 -57 -78 -78 -78
+c-8 0 -16 4 -22 10l-410 410c-40 39 -63 94 -63 149c0 110 86 196 196 196c56 0 110 -23 149 -63l581 -581c63 -62 100 -147 100 -235z" />
+ <glyph glyph-name="deviantart" unicode="&#xf1bd;" horiz-adv-x="1024"
+d="M1024 1233l-303 -582l24 -31h279v-415h-507l-44 -30l-142 -273c-1 0 -28 -28 -30 -30h-301v303l303 583l-24 30h-279v415h507l44 30l142 273c1 0 28 28 30 30h301v-303z" />
+ <glyph glyph-name="file-audio-o" unicode="&#xf1c7;"
+d="M1468 1156c37 -37 68 -111 68 -164v-1152c0 -53 -43 -96 -96 -96h-1344c-53 0 -96 43 -96 96v1600c0 53 43 96 96 96h896c53 0 127 -31 164 -68zM1024 1400v-376h376c-6 17 -15 34 -22 41l-313 313c-7 7 -24 16 -41 22zM1408 -128v1024h-416c-53 0 -96 43 -96 96v416
+h-768v-1536h1280zM620 686c12 -5 20 -17 20 -30v-544c0 -13 -8 -25 -20 -30c-4 -1 -8 -2 -12 -2c-8 0 -16 3 -23 9l-166 167h-131c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h131l166 167c10 9 23 12 35 7zM1037 -3c-14 0 -28 5 -40 15c-28 22 -32 62 -9 90
+c65 80 100 178 100 282s-35 202 -100 282c-23 28 -19 68 9 91c27 22 68 18 90 -10c83 -102 129 -231 129 -363s-46 -261 -129 -363c-13 -16 -31 -24 -50 -24zM826 145c-15 0 -31 6 -44 17c-25 24 -27 65 -2 91c33 36 52 82 52 131s-19 95 -52 131c-25 26 -23 67 2 91
+c26 24 67 23 91 -3c56 -60 87 -137 87 -219s-31 -159 -87 -219c-13 -13 -30 -20 -47 -20z" />
+ <glyph glyph-name="eur" unicode="&#xf153;" horiz-adv-x="1012"
+d="M976 229l35 -159c4 -16 -5 -32 -20 -37c-4 -1 -97 -33 -217 -33c-312 0 -563 188 -647 482h-95c-18 0 -32 15 -32 32v113c0 17 14 32 32 32h66c-1 32 -1 70 1 105h-67c-18 0 -32 14 -32 32v114c0 18 14 32 32 32h98c89 280 345 466 644 466c104 0 190 -22 194 -23
+c8 -2 15 -8 20 -15c4 -7 5 -16 3 -24l-43 -159c-4 -17 -21 -27 -38 -22c-1 0 -69 17 -140 17c-168 0 -309 -91 -376 -240h468c10 0 19 -4 25 -12c6 -7 9 -17 7 -26l-24 -114c-3 -15 -16 -26 -32 -26h-488c-3 -32 -2 -66 0 -105h459c10 0 19 -5 25 -12c6 -8 8 -18 6 -27
+l-24 -112c-3 -15 -16 -26 -31 -26h-387c64 -156 208 -254 378 -254c87 0 158 24 159 24c8 3 18 2 26 -2c8 -5 13 -13 15 -21z" />
+ <glyph glyph-name="coffee" unicode="&#xf0f4;" horiz-adv-x="1856"
+d="M1664 896c0 106 -86 192 -192 192h-64v-384h64c106 0 192 86 192 192zM0 128h1792c0 -141 -115 -256 -256 -256h-1280c-141 0 -256 115 -256 256zM1856 896c0 -212 -172 -384 -384 -384h-64v-32c0 -123 -101 -224 -224 -224h-704c-123 0 -224 101 -224 224v736
+c0 35 29 64 64 64h1152c212 0 384 -172 384 -384z" />
+ <glyph glyph-name="university" unicode="&#xf19c;" horiz-adv-x="1920"
+d="M960 1536l960 -384v-128h-128c0 -35 -31 -64 -69 -64h-1526c-38 0 -69 29 -69 64h-128v128zM256 896h256v-768h128v768h256v-768h128v768h256v-768h128v768h256v-768h59c38 0 69 -29 69 -64v-64h-1664v64c0 35 31 64 69 64h59v768zM1851 -64c38 0 69 -29 69 -64v-128
+h-1920v128c0 35 31 64 69 64h1782z" />
+ <glyph glyph-name="times-circle-o" unicode="&#xf05c;"
+d="M1097 457l-146 -146c-13 -13 -33 -13 -46 0l-137 137l-137 -137c-13 -13 -33 -13 -46 0l-146 146c-13 13 -13 33 0 46l137 137l-137 137c-13 13 -13 33 0 46l146 146c13 13 33 13 46 0l137 -137l137 137c13 13 33 13 46 0l146 -146c13 -13 13 -33 0 -46l-137 -137
+l137 -137c13 -13 13 -33 0 -46zM1312 640c0 300 -244 544 -544 544s-544 -244 -544 -544s244 -544 544 -544s544 244 544 544zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="python" unicode="&#xf322;"
+d="M759 1416v0c63 0 129 -4 193 -15c101 -17 185 -92 185 -192v-353c0 -103 -82 -188 -185 -188h-370c-126 0 -232 -108 -232 -230v-170h-127c-108 0 -171 78 -197 188c-36 147 -34 236 0 377c29 123 124 188 232 188h509v47h-370v141c0 107 28 164 185 192
+c53 9 114 15 177 15zM558 1303c-38 0 -69 -32 -69 -71s31 -70 69 -70s70 31 70 70s-32 71 -70 71zM1183 1021h139c108 0 159 -81 186 -188c37 -149 39 -261 0 -377c-37 -113 -78 -188 -186 -188h-555v-47h370v-141c0 -107 -92 -161 -185 -188c-140 -41 -253 -34 -370 0
+c-98 29 -185 88 -185 188v353c0 102 84 188 185 188h370c123 0 231 107 231 235v165zM975 127v0c-38 0 -69 -31 -69 -70s31 -71 69 -71s70 32 70 71s-32 70 -70 70zM1389 366c0 -17 -70 -30 -156 -30s-156 13 -156 30s70 30 156 30s156 -13 156 -30z" />
+ <glyph glyph-name="internet-explorer" unicode="&#xf26b;" horiz-adv-x="1792"
+d="M1792 599c0 -35 -2 -70 -7 -104h-1151c0 -199 175 -343 367 -343c130 0 255 64 322 177h423c-114 -321 -419 -536 -759 -536c-123 0 -246 29 -356 83c-112 -57 -269 -116 -394 -116c-168 0 -237 103 -237 263c0 93 20 186 45 275c16 58 80 176 109 229
+c123 223 285 437 475 606c-153 -66 -319 -232 -427 -354c84 366 410 625 785 625c15 0 30 0 45 -1c124 57 297 117 433 117c162 0 301 -62 301 -245c0 -96 -37 -200 -75 -286c66 -119 101 -254 101 -390zM1722 1239c0 112 -80 181 -190 181c-84 0 -179 -34 -254 -70
+c162 -63 301 -179 393 -327c25 66 51 146 51 216zM128 2c0 -116 69 -179 183 -179c89 0 188 40 266 83c-163 96 -289 249 -351 428c-46 -96 -98 -224 -98 -332zM632 715h728c-7 193 -177 332 -364 332c-188 0 -357 -139 -364 -332z" />
+ <glyph glyph-name="file-video-o" unicode="&#xf1c8;"
+d="M1468 1156c37 -37 68 -111 68 -164v-1152c0 -53 -43 -96 -96 -96h-1344c-53 0 -96 43 -96 96v1600c0 53 43 96 96 96h896c53 0 127 -31 164 -68zM1024 1400v-376h376c-6 17 -15 34 -22 41l-313 313c-7 7 -24 16 -41 22zM1408 -128v1024h-416c-53 0 -96 43 -96 96v416
+h-768v-1536h1280zM768 768c70 0 128 -58 128 -128v-384c0 -70 -58 -128 -128 -128h-384c-70 0 -128 58 -128 128v384c0 70 58 128 128 128h384zM1260 766c12 -5 20 -17 20 -30v-576c0 -13 -8 -25 -20 -30c-4 -1 -8 -2 -12 -2c-8 0 -17 3 -23 9l-265 266v90l265 266
+c6 6 15 9 23 9c4 0 8 -1 12 -2z" />
+ <glyph glyph-name="angle-double-right" unicode="&#xf101;" horiz-adv-x="966"
+d="M582 576c0 -8 -4 -17 -10 -23l-466 -466c-6 -6 -15 -10 -23 -10s-17 4 -23 10l-50 50c-6 6 -10 15 -10 23s4 17 10 23l393 393l-393 393c-6 6 -10 15 -10 23s4 17 10 23l50 50c6 6 15 10 23 10s17 -4 23 -10l466 -466c6 -6 10 -15 10 -23zM966 576c0 -8 -4 -17 -10 -23
+l-466 -466c-6 -6 -15 -10 -23 -10s-17 4 -23 10l-50 50c-6 6 -10 15 -10 23s4 17 10 23l393 393l-393 393c-6 6 -10 15 -10 23s4 17 10 23l50 50c6 6 15 10 23 10s17 -4 23 -10l466 -466c6 -6 10 -15 10 -23z" />
+ <glyph glyph-name="safari" unicode="&#xf267;" horiz-adv-x="1792"
+d="M949 643c0 -33 -23 -64 -58 -64c-33 0 -64 24 -64 58c0 33 24 64 59 64c32 0 63 -23 63 -58zM964 585l350 581c-47 -44 -485 -447 -497 -468l-349 -580c46 43 485 448 496 467zM1611 640c0 -131 -36 -260 -104 -371c-10 5 -52 35 -60 35c-7 0 -13 -6 -13 -13
+c0 -13 47 -37 59 -44c-99 -150 -252 -258 -426 -301l-16 67c-1 9 -7 10 -15 10c-7 0 -11 -10 -10 -15l16 -68c-48 -10 -97 -15 -146 -15c-131 0 -260 37 -372 105c6 10 44 65 44 73c0 7 -6 13 -13 13c-14 0 -44 -60 -53 -72c-151 100 -260 255 -302 432l69 15
+c8 2 10 8 10 15s-10 11 -16 10l-68 -15c-9 46 -14 92 -14 139c0 134 38 266 109 379c10 -6 58 -39 66 -39c7 0 13 5 13 12c0 14 -53 41 -65 49c102 149 257 256 433 296l15 -67c2 -8 8 -10 15 -10s11 10 10 16l-15 66c44 8 89 13 134 13c134 0 265 -38 379 -109
+c-7 -10 -39 -57 -39 -65c0 -7 5 -13 12 -13c14 0 41 52 48 64c148 -100 254 -253 295 -427l-56 -12c-9 -2 -10 -8 -10 -16c0 -7 10 -11 15 -10l57 13c9 -46 14 -93 14 -140zM1696 640c0 442 -358 800 -800 800s-800 -358 -800 -800s358 -800 800 -800s800 358 800 800z
+M1792 640c0 -495 -401 -896 -896 -896s-896 401 -896 896s401 896 896 896s896 -401 896 -896z" />
+ <glyph glyph-name="commenting-o" unicode="&#xf27b;" horiz-adv-x="1792"
+d="M640 640c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128s128 -57 128 -128zM1024 640c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128s128 -57 128 -128zM1408 640c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128s128 -57 128 -128z
+M896 1152c-416 0 -768 -234 -768 -512c0 -149 100 -291 273 -389l87 -50l-27 -96c-19 -71 -44 -126 -70 -172c101 42 193 99 275 171l43 38l57 -6c43 -5 87 -8 130 -8c416 0 768 234 768 512s-352 512 -768 512zM1792 640c0 -354 -401 -640 -896 -640c-49 0 -98 3 -145 8
+c-131 -116 -287 -198 -460 -242c-36 -10 -75 -17 -114 -22h-5c-20 0 -38 16 -43 38v1c-5 25 12 40 27 58c63 71 135 131 182 298c-206 117 -338 298 -338 501c0 353 401 640 896 640s896 -287 896 -640z" />
+ <glyph glyph-name="snowdrift" unicode="&#xf2f1;" horiz-adv-x="1448"
+d="M1007 384c104 116 30 287 -165 383c7 -6 44 24 83 67s65 84 58 90c-195 96 -438 80 -542 -36s-30 -287 165 -383c-7 6 -44 -24 -83 -67s-65 -84 -58 -90c195 -96 438 -80 542 36zM103 1188v0c228 253 760 288 1188 78c15 -14 -42 -101 -127 -196s-167 -161 -182 -147
+c428 -210 591 -585 363 -839c-228 -253 -760 -288 -1188 -78c-15 14 42 101 127 196s167 161 182 147c-428 210 -591 585 -363 839z" />
+ <glyph glyph-name="black-tie" unicode="&#xf27e;"
+d="M0 1408h1536v-1536h-1536v1536zM1085 293l-221 631l221 297h-634l221 -297l-221 -631l317 -304z" />
+ <glyph glyph-name="youtube-play" unicode="&#xf16a;" horiz-adv-x="1792"
+d="M711 408l484 250l-484 253v-503zM896 1270c377 0 627 -18 627 -18c35 -4 112 -4 180 -76c0 0 55 -54 71 -178c19 -145 18 -290 18 -290v-136s1 -145 -18 -290c-16 -123 -71 -178 -71 -178c-68 -71 -145 -71 -180 -75c0 0 -250 -19 -627 -19c-466 4 -609 18 -609 18
+c-40 7 -130 5 -198 76c0 0 -55 55 -71 178c-19 145 -18 290 -18 290v136s-1 145 18 290c16 124 71 178 71 178c68 72 145 72 180 76c0 0 250 18 627 18z" />
+ <glyph glyph-name="modx" unicode="&#xf285;" horiz-adv-x="1728"
+d="M1395 827l-614 386l92 151h855zM373 562l-184 116v858l1183 -743zM1392 697l147 -95v-858l-532 335zM1355 718l-500 -802h-855l356 571z" />
+ <glyph glyph-name="caret-square-o-right" unicode="&#xf152;"
+d="M1088 640c0 -21 -10 -40 -27 -52l-448 -320c-19 -14 -45 -16 -66 -5c-22 11 -35 33 -35 57v640c0 24 13 46 35 57c21 11 47 9 66 -5l448 -320c17 -12 27 -31 27 -52zM1280 160v960c0 18 -14 32 -32 32h-960c-18 0 -32 -14 -32 -32v-960c0 -18 14 -32 32 -32h960
+c18 0 32 14 32 32zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="gitlab" unicode="&#xf296;" horiz-adv-x="1793"
+d="M104 830l792 -1015l-868 630c-24 18 -34 49 -25 77zM566 830h660l-330 -1015zM368 1442l198 -612h-462l198 612c11 31 55 31 66 0zM1688 830l101 -308c9 -28 -1 -59 -25 -77l-868 -630zM1688 830h-462l198 612c11 31 55 31 66 0z" />
+ <glyph glyph-name="arrows" unicode="&#xf047;" horiz-adv-x="1792"
+d="M1792 640c0 -17 -7 -33 -19 -45l-256 -256c-12 -12 -28 -19 -45 -19c-35 0 -64 29 -64 64v128h-384v-384h128c35 0 64 -29 64 -64c0 -17 -7 -33 -19 -45l-256 -256c-12 -12 -28 -19 -45 -19s-33 7 -45 19l-256 256c-12 12 -19 28 -19 45c0 35 29 64 64 64h128v384h-384
+v-128c0 -35 -29 -64 -64 -64c-17 0 -33 7 -45 19l-256 256c-12 12 -19 28 -19 45s7 33 19 45l256 256c12 12 28 19 45 19c35 0 64 -29 64 -64v-128h384v384h-128c-35 0 -64 29 -64 64c0 17 7 33 19 45l256 256c12 12 28 19 45 19s33 -7 45 -19l256 -256
+c12 -12 19 -28 19 -45c0 -35 -29 -64 -64 -64h-128v-384h384v128c0 35 29 64 64 64c17 0 33 -7 45 -19l256 -256c12 -12 19 -28 19 -45z" />
+ <glyph glyph-name="refresh" unicode="&#xf021;"
+d="M1511 480c0 -2 0 -5 -1 -7c-85 -354 -377 -601 -746 -601c-195 0 -384 77 -526 212l-129 -129c-12 -12 -28 -19 -45 -19c-35 0 -64 29 -64 64v448c0 35 29 64 64 64h448c35 0 64 -29 64 -64c0 -17 -7 -33 -19 -45l-137 -137c94 -88 219 -138 348 -138
+c178 0 343 92 436 244c24 39 36 77 53 117c5 14 15 23 30 23h192c18 0 32 -15 32 -32zM1536 1280v-448c0 -35 -29 -64 -64 -64h-448c-35 0 -64 29 -64 64c0 17 7 33 19 45l138 138c-95 88 -220 137 -349 137c-178 0 -343 -92 -436 -244c-24 -39 -36 -77 -53 -117
+c-5 -14 -15 -23 -30 -23h-199c-18 0 -32 15 -32 32v7c86 355 381 601 750 601c196 0 387 -78 529 -212l130 129c12 12 28 19 45 19c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="file-o" unicode="&#xf016;"
+d="M1468 1156c37 -37 68 -111 68 -164v-1152c0 -53 -43 -96 -96 -96h-1344c-53 0 -96 43 -96 96v1600c0 53 43 96 96 96h896c53 0 127 -31 164 -68zM1024 1400v-376h376c-6 17 -15 34 -22 41l-313 313c-7 7 -24 16 -41 22zM1408 -128v1024h-416c-53 0 -96 43 -96 96v416
+h-768v-1536h1280z" />
+ <glyph glyph-name="battery-three-quarters" unicode="&#xf241;" horiz-adv-x="2304"
+d="M256 256v768h1280v-768h-1280zM2176 960c71 0 128 -57 128 -128v-384c0 -71 -57 -128 -128 -128v-160c0 -88 -72 -160 -160 -160h-1856c-88 0 -160 72 -160 160v960c0 88 72 160 160 160h1856c88 0 160 -72 160 -160v-160zM2176 448v384h-128v288c0 18 -14 32 -32 32
+h-1856c-18 0 -32 -14 -32 -32v-960c0 -18 14 -32 32 -32h1856c18 0 32 14 32 32v288h128z" />
+ <glyph glyph-name="reddit-alien" unicode="&#xf281;" horiz-adv-x="1792"
+d="M1792 690c0 -78 -44 -145 -109 -178c8 -31 12 -63 12 -96c0 -316 -357 -572 -797 -572c-439 0 -796 256 -796 572c0 32 4 64 11 94c-67 33 -113 101 -113 180c0 110 89 199 199 199c57 0 108 -24 145 -63c135 94 315 155 515 162l116 521c4 18 23 30 41 26l369 -81
+c24 48 75 82 133 82c83 0 150 -67 150 -149c0 -83 -67 -150 -150 -150c-82 0 -149 67 -149 149l-334 74l-104 -472c201 -6 383 -66 519 -160c36 38 87 61 143 61c110 0 199 -89 199 -199zM418 491c0 -83 67 -150 149 -150c83 0 150 67 150 150c0 82 -67 149 -150 149
+c-82 0 -149 -67 -149 -149zM1228 136c15 15 15 37 0 52c-14 14 -37 14 -51 0c-60 -61 -189 -82 -281 -82s-221 21 -281 82c-14 14 -37 14 -51 0c-15 -14 -15 -37 0 -52c95 -95 278 -102 332 -102s237 7 332 102zM1225 341c82 0 149 67 149 150c0 82 -67 149 -149 149
+c-83 0 -150 -67 -150 -149c0 -83 67 -150 150 -150z" />
+ <glyph glyph-name="square" unicode="&#xf0c8;"
+d="M1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="ellipsis-v" unicode="&#xf142;" horiz-adv-x="384"
+d="M384 288v-192c0 -53 -43 -96 -96 -96h-192c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h192c53 0 96 -43 96 -96zM384 800v-192c0 -53 -43 -96 -96 -96h-192c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h192c53 0 96 -43 96 -96zM384 1312v-192c0 -53 -43 -96 -96 -96h-192
+c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h192c53 0 96 -43 96 -96z" />
+ <glyph glyph-name="glide-g" unicode="&#xf2a6;" horiz-adv-x="1461"
+d="M707 1231c0 53 -5 99 -69 99c-27 0 -54 -9 -78 -23c-151 -83 -213 -298 -213 -460c0 -108 37 -252 169 -252c30 0 68 -8 76 27c32 154 64 309 96 463c10 48 19 97 19 146zM1461 575c0 -10 -13 -20 -23 -20l-6 1c-68 10 -128 28 -197 28c-125 0 -240 -37 -351 -93
+c-14 -7 -17 -13 -21 -27c-18 -68 -30 -138 -47 -206c-60 -233 -255 -514 -522 -514c-182 0 -294 124 -294 303c0 97 63 286 180 286c41 0 202 -53 203 -95c-2 -8 -157 -88 -157 -223c0 -41 20 -73 65 -73c159 0 232 290 248 412v9c0 8 -32 4 -38 4c-301 0 -477 168 -477 471
+c0 286 186 635 491 688c35 6 70 9 106 9c242 0 374 -113 374 -360c0 -167 -57 -321 -81 -484l3 -3c108 61 222 119 350 119c13 0 41 -8 53 -13c26 -10 141 -191 141 -219z" />
+ <glyph glyph-name="globe" unicode="&#xf0ac;"
+d="M768 1404c424 0 768 -344 768 -768s-344 -768 -768 -768s-768 344 -768 768s344 768 768 768zM737 1186v0c-18 0 -40 -7 -58 -7c-27 0 -61 12 -81 0s-18 -37 -27 -55s-28 -34 -28 -54s19 -36 28 -54s2 -47 27 -54s54 36 81 54s69 32 81 54s0 36 0 54s16 39 0 55
+c-5 5 -14 7 -23 7zM491 1178h-6s-44 -8 -76 -13c-136 -92 -261 -300 -278 -464c23 -12 46 -22 60 -36c27 -27 83 -27 88 -56s-24 -62 -33 -80s-31 -31 -27 -54s36 -36 54 -54s37 -22 54 -54s20 -98 27 -135c9 -47 23 -85 44 -118c27 -19 72 -44 102 -58c10 28 10 93 16 122
+c7 37 13 109 27 135s19 19 28 28s18 15 28 28s17 34 26 52s30 31 26 53s-36 37 -54 55s-29 39 -55 54s-73 18 -101 25s-127 12 -129 13c-2 0 -1 -6 -7 2s-2 39 -2 57s11 34 24 66c13 18 5 10 25 24c10 9 43 -44 57 -44s-3 91 6 100c36 36 128 98 128 136s-37 36 -55 54
+s-46 -30 -111 -30s76 103 85 112s23 17 27 27s0 18 0 27s12 22 8 25c-2 1 -4 1 -6 1zM1212 1096c-62 -8 -139 -10 -182 -26c-45 -17 -54 -36 -81 -54s-67 -28 -81 -54s0 -54 0 -81s-26 -68 0 -82s55 37 82 55s63 64 81 54s6 -7 0 -27s-51 -41 -52 -81s102 -73 68 -126
+s-188 46 -232 17s-19 -54 -28 -81s-37 -52 -27 -81s52 -34 81 -54s81 -56 82 -58s20 -99 27 -135c14 -73 -27 -199 76 -231c31 14 78 41 106 60c13 34 24 72 35 94c22 44 71 123 80 161s0 37 0 55s7 30 0 54s-36 54 -54 81s-34 64 -54 81s-46 18 -54 27s-4 8 -4 13
+s-4 7 5 14s34 8 54 0s36 -36 54 -54s25 -51 54 -54s54 36 81 54c25 17 52 56 76 55c-12 131 -98 312 -193 404z" />
+ <glyph glyph-name="hashnode" unicode="&#xf317;"
+d="M246 1408h1044c136 0 246 -110 246 -246v-1044c0 -136 -110 -246 -246 -246h-1044c-136 0 -246 110 -246 246v1044c0 136 110 246 246 246zM1153 23v0c87 1 158 71 162 158s-62 162 -149 171l-315 556c-46 83 -135 78 -167 -39c-28 -111 -20 -216 -28 -342
+c0 -1 -1 -2 -2 -2s-2 1 -2 1l-281 560c20 16 37 50 37 75c0 52 -41 93 -93 93s-94 -41 -94 -93s42 -93 94 -93c4 0 7 1 11 1c118 -304 250 -659 297 -741c32 -78 141 -53 144 31l12 444c0 3 3 3 4 1l226 -537c-11 -20 -21 -55 -21 -78v-1c0 -91 74 -165 165 -165z" />
+ <glyph glyph-name="comment-o" unicode="&#xf0e5;" horiz-adv-x="1792"
+d="M896 1152c-416 0 -768 -234 -768 -512c0 -149 100 -291 273 -389l87 -50l-27 -96c-19 -71 -44 -126 -70 -172c101 42 193 99 275 171l43 38l57 -6c43 -5 87 -8 130 -8c416 0 768 234 768 512s-352 512 -768 512zM1792 640c0 -354 -401 -640 -896 -640c-49 0 -98 3 -145 8
+c-131 -116 -287 -198 -460 -242c-36 -10 -75 -17 -114 -22h-5c-20 0 -38 16 -43 38v1c-5 25 12 40 27 58c63 71 135 131 182 298c-206 117 -338 298 -338 501c0 354 401 640 896 640s896 -286 896 -640z" />
+ <glyph glyph-name="bluetooth" unicode="&#xf293;" horiz-adv-x="1322"
+d="M734 483l148 -148l-149 -149zM733 1094l149 -149l-148 -148zM603 -130l464 464l-306 306l306 306l-464 464v-611l-255 255l-93 -93l320 -321l-320 -321l93 -93l255 255v-611zM1322 640c0 -710 -270 -896 -661 -896s-661 186 -661 896s270 896 661 896s661 -186 661 -896z
+" />
+ <glyph glyph-name="hand-pointer-o" unicode="&#xf25a;" horiz-adv-x="1664"
+d="M640 1408c-71 0 -128 -57 -128 -128v-896l-151 202c-25 33 -65 54 -107 54c-70 0 -126 -59 -126 -128c0 -28 9 -55 26 -77l384 -512c24 -32 62 -51 102 -51h718c29 0 55 20 62 48l92 368c16 64 24 129 24 194v217c0 53 -41 101 -96 101c-53 0 -96 -43 -96 -96h-32v61
+c0 63 -48 115 -112 115c-62 0 -112 -50 -112 -112v-64h-32v90c0 72 -55 134 -128 134c-71 0 -128 -57 -128 -128v-96h-32v570c0 72 -55 134 -128 134zM640 1536c143 0 256 -120 256 -262v-220c11 1 21 2 32 2c65 0 126 -25 173 -69c31 14 65 21 99 21c72 0 139 -32 184 -87
+c19 5 37 7 56 7c126 0 224 -105 224 -229v-217c0 -75 -9 -151 -28 -225l-92 -368c-21 -85 -98 -145 -186 -145h-718c-80 0 -157 39 -205 102l-384 512c-33 44 -51 99 -51 154c0 140 114 256 254 256c46 0 91 -12 130 -35v547c0 141 115 256 256 256zM768 128h-32v384h32
+v-384zM1024 128h-32v384h32v-384zM1280 128h-32v384h32v-384z" />
+ <glyph glyph-name="unlock" unicode="&#xf09c;" horiz-adv-x="1664"
+d="M1664 960v-256c0 -35 -29 -64 -64 -64h-64c-35 0 -64 29 -64 64v256c0 141 -115 256 -256 256s-256 -115 -256 -256v-192h96c53 0 96 -43 96 -96v-576c0 -53 -43 -96 -96 -96h-960c-53 0 -96 43 -96 96v576c0 53 43 96 96 96h672v192c0 247 201 448 448 448
+s448 -201 448 -448z" />
+ <glyph glyph-name="quote-right" unicode="&#xf10e;" horiz-adv-x="1664"
+d="M768 1216v-704c0 -282 -230 -512 -512 -512h-64c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h64c141 0 256 115 256 256v32c0 53 -43 96 -96 96h-224c-106 0 -192 86 -192 192v384c0 106 86 192 192 192h384c106 0 192 -86 192 -192zM1664 1216v-704
+c0 -282 -230 -512 -512 -512h-64c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h64c141 0 256 115 256 256v32c0 53 -43 96 -96 96h-224c-106 0 -192 86 -192 192v384c0 106 86 192 192 192h384c106 0 192 -86 192 -192z" />
+ <glyph glyph-name="arrow-left" unicode="&#xf060;" horiz-adv-x="1472"
+d="M1472 640v-128c0 -68 -45 -128 -117 -128h-704l293 -294c24 -23 38 -56 38 -90s-14 -67 -38 -90l-75 -76c-23 -23 -56 -37 -90 -37s-67 14 -91 37l-651 652c-23 23 -37 56 -37 90s14 67 37 91l651 650c24 24 57 38 91 38s66 -14 90 -38l75 -74c24 -24 38 -57 38 -91
+s-14 -67 -38 -91l-293 -293h704c72 0 117 -60 117 -128z" />
+ <glyph glyph-name="scissors" unicode="&#xf0c4;" horiz-adv-x="1792"
+d="M960 640c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM1260 576l507 -398c18 -13 27 -35 25 -56c-3 -22 -16 -41 -35 -51l-128 -64c-9 -5 -19 -7 -29 -7c-11 0 -22 3 -31 8l-690 387l-110 -66c-4 -2 -8 -4 -12 -5c9 -31 13 -64 10 -97
+c-9 -103 -78 -201 -188 -271c-85 -54 -183 -84 -277 -84c-90 0 -166 27 -222 78c-57 53 -86 129 -79 207c9 102 78 201 187 271c85 54 184 84 278 84c56 0 107 -11 151 -31c6 9 13 16 22 22l122 73l-122 73c-9 6 -16 13 -22 22c-44 -20 -95 -31 -151 -31
+c-94 0 -193 30 -278 84c-109 70 -178 169 -187 271c-7 78 22 154 79 206c56 52 132 79 222 79c94 0 192 -30 277 -84c110 -69 179 -168 188 -271c3 -33 -1 -66 -10 -97c4 -1 8 -3 12 -5l110 -66l690 387c9 5 20 8 31 8c10 0 20 -2 29 -7l128 -64c19 -10 32 -29 35 -51
+c2 -21 -7 -43 -25 -56zM579 836c61 56 23 157 -85 225c-61 39 -132 59 -192 59c-46 0 -87 -12 -113 -36c-61 -56 -23 -157 85 -225c61 -39 131 -59 192 -59c46 0 87 12 113 36zM494 91c108 68 146 169 85 225c-26 24 -67 36 -113 36c-61 0 -131 -20 -192 -59
+c-108 -68 -146 -169 -85 -225c26 -24 67 -36 113 -36c60 0 131 20 192 59zM672 704l96 -58v11c0 23 13 44 33 56l14 8l-79 47l-26 -26c-8 -8 -14 -16 -22 -23c-3 -3 -5 -4 -7 -6zM896 480l96 -32l736 576l-128 64l-768 -431v-113l-160 -96l9 -8c2 -3 4 -4 7 -6
+c8 -8 14 -16 22 -24l26 -26zM1600 64l128 64l-520 408l-177 -138c-3 -4 -8 -5 -13 -7z" />
+ <glyph glyph-name="ellipsis-h" unicode="&#xf141;" horiz-adv-x="1408"
+d="M384 800v-192c0 -53 -43 -96 -96 -96h-192c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h192c53 0 96 -43 96 -96zM896 800v-192c0 -53 -43 -96 -96 -96h-192c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h192c53 0 96 -43 96 -96zM1408 800v-192c0 -53 -43 -96 -96 -96h-192
+c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h192c53 0 96 -43 96 -96z" />
+ <glyph glyph-name="scribd" unicode="&#xf28a;" horiz-adv-x="1464"
+d="M1464 -13c0 -119 -96 -216 -216 -216s-217 97 -217 216c0 120 97 217 217 217s216 -97 216 -217zM1231 268c-152 -20 -270 -150 -270 -308c0 -49 12 -97 33 -138c-90 -48 -212 -78 -379 -78c-532 0 -615 376 -615 426c0 51 30 218 218 218s214 -161 214 -194
+c0 0 0 -34 -23 -81c64 -60 215 -60 215 -60c151 0 265 74 265 184c0 111 -128 165 -420 302c-292 138 -402 239 -402 490c0 252 168 507 587 507s577 -235 577 -396s-137 -201 -188 -201c-50 0 -235 -17 -235 261c-33 37 -177 37 -177 37c-145 0 -209 -110 -209 -177
+c0 -68 27 -152 329 -252c463 -154 480 -355 480 -540z" />
+ <glyph glyph-name="exclamation" unicode="&#xf12a;" horiz-adv-x="444"
+d="M414 288v-224c0 -35 -29 -64 -64 -64h-256c-35 0 -64 29 -64 64v224c0 35 29 64 64 64h256c35 0 64 -29 64 -64zM444 1344l-28 -768c-1 -35 -31 -64 -66 -64h-256c-35 0 -65 29 -66 64l-28 768c-1 35 27 64 62 64h320c35 0 63 -29 62 -64z" />
+ <glyph glyph-name="try" unicode="&#xf195;" horiz-adv-x="1152"
+d="M1152 704c0 -388 -316 -704 -704 -704h-160c-18 0 -32 14 -32 32v611l-215 -66c-3 -1 -6 -1 -9 -1c-7 0 -13 2 -19 6c-8 6 -13 16 -13 26v128c0 14 9 26 23 31l233 71v93l-215 -66c-3 -1 -6 -1 -9 -1c-7 0 -13 2 -19 6c-8 6 -13 16 -13 26v128c0 14 9 26 23 31l233 71
+v250c0 18 14 32 32 32h160c18 0 32 -14 32 -32v-181l375 116c9 3 20 1 28 -5s13 -16 13 -26v-128c0 -14 -9 -26 -23 -31l-393 -121v-93l375 116c9 3 20 1 28 -5s13 -16 13 -26v-128c0 -14 -9 -26 -23 -31l-393 -121v-487c250 17 448 225 448 479c0 18 14 32 32 32h160
+c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="assistive-listening-systems" unicode="&#xf2a2;" horiz-adv-x="1792"
+d="M128 -192c0 -35 -29 -64 -64 -64s-64 29 -64 64s29 64 64 64s64 -29 64 -64zM320 0c0 -35 -29 -64 -64 -64s-64 29 -64 64s29 64 64 64s64 -29 64 -64zM365 365l256 -256l-90 -90l-256 256zM704 384c0 -35 -29 -64 -64 -64s-64 29 -64 64s29 64 64 64s64 -29 64 -64z
+M1411 704c0 -166 -78 -255 -146 -334c-63 -72 -113 -129 -113 -242c0 -212 -172 -384 -384 -384c-35 0 -64 29 -64 64s29 64 64 64c141 0 256 115 256 256c0 161 77 249 144 326c62 71 115 132 115 250c0 247 -201 448 -448 448s-448 -201 -448 -448c0 -35 -29 -64 -64 -64
+s-64 29 -64 64c0 318 258 576 576 576s576 -258 576 -576zM896 576c0 -35 -29 -64 -64 -64s-64 29 -64 64s29 64 64 64s64 -29 64 -64zM1184 704c0 -35 -29 -64 -64 -64s-64 29 -64 64c0 124 -100 224 -224 224c-123 0 -224 -100 -224 -224c0 -35 -29 -64 -64 -64
+s-64 29 -64 64c0 194 158 352 352 352s352 -158 352 -352zM1578 993c13 -33 -4 -70 -37 -83c-7 -3 -15 -4 -23 -4c-25 0 -50 15 -59 41c-45 117 -123 219 -224 295c-28 21 -34 61 -13 89c22 28 62 34 90 13c120 -90 212 -212 266 -351zM1788 1074c12 -33 -4 -70 -37 -83
+c-8 -3 -15 -4 -23 -4c-26 0 -50 15 -60 41c-60 156 -163 292 -297 393c-29 21 -34 61 -13 89c21 29 61 34 89 13c154 -115 272 -271 341 -449z" />
+ <glyph glyph-name="flag-o" unicode="&#xf11d;" horiz-adv-x="1728"
+d="M1600 491v616c-80 -43 -192 -91 -306 -91c-53 0 -102 10 -145 32c-107 53 -223 104 -362 104c-129 0 -287 -63 -403 -127v-599c132 61 300 113 433 113c154 0 254 -51 361 -104l28 -14c28 -14 62 -22 101 -22c111 0 231 59 293 92zM256 1280c0 -47 -26 -88 -64 -110
+v-1266c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v1266c-38 22 -64 63 -64 110c0 71 57 128 128 128s128 -57 128 -128zM1728 1216v-763c0 -24 -14 -46 -35 -57c-4 -2 -10 -5 -17 -9c-64 -34 -215 -116 -369 -116c-59 0 -112 12 -158 35l-28 14
+c-101 51 -181 91 -304 91c-144 0 -347 -75 -464 -146c-10 -6 -22 -9 -33 -9s-22 3 -32 8c-20 12 -32 33 -32 56v742c0 22 12 43 31 55c64 38 290 163 500 163c167 0 303 -61 418 -117c26 -13 56 -19 89 -19c118 0 248 75 310 112c13 7 24 13 31 17c20 10 43 9 62 -2
+c19 -12 31 -33 31 -55z" />
+ <glyph glyph-name="wikipedia-w" unicode="&#xf266;" horiz-adv-x="2304"
+d="M1494 -103l-295 695c-117 -229 -246 -468 -357 -695c-1 -1 -54 0 -54 1c-169 395 -346 787 -515 1183c-41 96 -178 252 -272 251c0 11 -1 36 -1 51h583v-50c-69 -4 -190 -48 -156 -123c79 -179 373 -865 452 -1039c54 107 208 393 271 514c-50 102 -211 482 -262 576
+c-35 64 -130 70 -201 71v50l513 -1v-47c-70 -2 -137 -28 -106 -94c68 -144 110 -245 173 -377c20 39 125 250 173 363c32 74 -14 103 -139 106c1 13 0 37 1 49c160 1 400 1 443 2v-49c-81 -3 -165 -46 -209 -114l-213 -442c23 -58 228 -514 249 -564l441 1017
+c-31 83 -131 101 -170 102v50l460 -4l1 -2l-1 -44c-101 -3 -162 -57 -201 -145c-90 -208 -372 -864 -559 -1291h-49z" />
+ <glyph glyph-name="battery-quarter" unicode="&#xf243;" horiz-adv-x="2304"
+d="M256 256v768h512v-768h-512zM2176 960c71 0 128 -57 128 -128v-384c0 -71 -57 -128 -128 -128v-160c0 -88 -72 -160 -160 -160h-1856c-88 0 -160 72 -160 160v960c0 88 72 160 160 160h1856c88 0 160 -72 160 -160v-160zM2176 448v384h-128v288c0 18 -14 32 -32 32h-1856
+c-18 0 -32 -14 -32 -32v-960c0 -18 14 -32 32 -32h1856c18 0 32 14 32 32v288h128z" />
+ <glyph glyph-name="print" unicode="&#xf02f;" horiz-adv-x="1664"
+d="M384 0h896v256h-896v-256zM384 640h896v384h-160c-53 0 -96 43 -96 96v160h-640v-640zM1536 576c0 35 -29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64s64 29 64 64zM1664 576v-416c0 -17 -15 -32 -32 -32h-224v-160c0 -53 -43 -96 -96 -96h-960c-53 0 -96 43 -96 96v160
+h-224c-17 0 -32 15 -32 32v416c0 105 87 192 192 192h64v544c0 53 43 96 96 96h672c53 0 126 -30 164 -68l152 -152c38 -38 68 -111 68 -164v-256h64c105 0 192 -87 192 -192z" />
+ <glyph glyph-name="tipeee" unicode="&#xf301;" horiz-adv-x="2304"
+d="M116 1259h2072c64 0 116 -52 116 -116v-1006c0 -64 -52 -116 -116 -116h-2072c-64 0 -116 52 -116 116v1006c0 64 52 116 116 116zM756 1006v0c-59 0 -90 -47 -90 -85c0 -40 37 -84 90 -84c59 0 92 38 92 84c0 38 -34 85 -92 85zM1672 966v-159l45 -211h110l45 211v159
+h-200zM534 925l-154 -49v-77h-45v-109h45v-148c3 -107 7 -176 132 -176c19 0 77 6 102 16v107c-16 -7 -42 -14 -53 -14c-33 0 -27 39 -27 67v148h80v109h-80v126zM1212 806v0c-50 0 -85 -24 -101 -36l-14 29h-192v-111h35v-368h-35v-109h250v109h-45v85c6 -5 40 -33 109 -33
+c108 0 190 82 190 215c0 119 -67 219 -197 219zM643 799v-109h35v-199h-35v-110h234v110h-40v308h-194zM1169 688v0c37 0 61 -53 61 -103c0 -64 -25 -104 -60 -104c-32 0 -60 43 -60 100c-3 66 26 107 59 107zM1764 555c-60 0 -95 -47 -95 -89c0 -43 41 -86 95 -86
+c61 0 99 39 99 86c0 48 -40 89 -99 89z" />
+ <glyph glyph-name="check-circle-o" unicode="&#xf05d;"
+d="M1171 723l-422 -422c-25 -25 -65 -25 -90 0l-294 294c-25 25 -25 65 0 90l102 102c25 25 65 25 90 0l147 -147l275 275c25 25 65 25 90 0l102 -102c25 -25 25 -65 0 -90zM1312 640c0 300 -244 544 -544 544s-544 -244 -544 -544s244 -544 544 -544s544 244 544 544z
+M1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="level-up" unicode="&#xf148;" horiz-adv-x="1024"
+d="M1018 933c-11 -23 -33 -37 -58 -37h-192v-864c0 -18 -14 -32 -32 -32h-704c-12 0 -24 7 -29 18c-5 12 -4 25 4 35l160 192c6 7 16 11 25 11h320v640h-192c-25 0 -47 14 -58 37c-10 22 -7 49 9 68l320 384c24 29 74 29 98 0l320 -384c16 -19 20 -46 9 -68z" />
+ <glyph glyph-name="houzz" unicode="&#xf27c;" horiz-adv-x="1024"
+d="M512 345l512 295v-591l-512 -296v592zM0 640l512 -295l-512 -296v591zM512 1527v-591l-512 -296v591zM512 936l512 295v-591z" />
+ <glyph glyph-name="lemon-o" unicode="&#xf094;" horiz-adv-x="1535"
+d="M1407 710c0 47 -9 170 -25 210c-19 48 -30 75 -30 129c0 46 10 91 10 136c0 19 -1 39 -10 55c-4 1 -9 1 -13 1c-39 0 -78 -9 -117 -9c-119 0 -232 48 -351 48c-93 0 -183 -35 -269 -69c-68 -27 -143 -59 -202 -103c-202 -153 -272 -433 -272 -674c0 -81 25 -160 25 -241
+c0 -46 -22 -88 -22 -132c0 -28 16 -51 46 -51c49 0 96 22 146 22c114 0 225 -31 339 -31c89 0 201 7 284 36c263 93 461 397 461 673zM1535 712c0 -333 -231 -684 -547 -796c-99 -35 -222 -44 -326 -44c-114 0 -226 29 -339 29c-48 0 -96 -29 -146 -29
+c-99 0 -174 89 -174 184c0 47 22 89 22 135c0 81 -25 160 -25 242c0 284 87 598 323 777c68 52 153 89 232 120c102 41 205 78 316 78c119 0 232 -48 349 -48c38 0 76 10 115 10c114 0 155 -81 155 -185c0 -45 -10 -91 -10 -136c0 -36 9 -50 21 -82c23 -58 34 -191 34 -255z
+" />
+ <glyph glyph-name="umbrella" unicode="&#xf0e9;" horiz-adv-x="1664"
+d="M896 708v-580c0 -139 -117 -256 -256 -256s-256 117 -256 256c0 35 29 64 64 64s64 -29 64 -64c0 -67 61 -128 128 -128s128 61 128 128v580c21 7 42 11 64 11s43 -4 64 -11zM1664 681c0 -17 -15 -32 -32 -32c-9 0 -16 4 -23 10c-58 54 -112 92 -195 92
+c-95 0 -177 -59 -231 -134c-12 -17 -21 -35 -32 -52c-7 -11 -15 -17 -28 -17c-14 0 -22 6 -29 17c-11 17 -20 35 -32 52c-54 75 -135 134 -230 134s-176 -59 -230 -134c-12 -17 -21 -35 -32 -52c-7 -11 -15 -17 -29 -17c-13 0 -21 6 -28 17c-11 17 -20 35 -32 52
+c-54 75 -136 134 -231 134c-83 0 -137 -38 -195 -92c-7 -6 -14 -10 -23 -10c-17 0 -32 15 -32 32c0 3 0 5 1 7c92 378 457 592 831 592c372 0 741 -214 831 -592c1 -2 1 -4 1 -7zM896 1408v-98c-21 1 -43 2 -64 2s-43 -1 -64 -2v98c0 35 29 64 64 64s64 -29 64 -64z" />
+ <glyph glyph-name="bell-o" unicode="&#xf0a2;" horiz-adv-x="1664"
+d="M848 -160c0 9 -7 16 -16 16c-79 0 -144 65 -144 144c0 9 -7 16 -16 16s-16 -7 -16 -16c0 -97 79 -176 176 -176c9 0 16 7 16 16zM1664 128c0 -70 -58 -128 -128 -128h-448c0 -141 -115 -256 -256 -256s-256 115 -256 256h-448c-70 0 -128 58 -128 128
+c148 125 320 349 320 832c0 192 159 402 424 441c-5 12 -8 25 -8 39c0 53 43 96 96 96s96 -43 96 -96c0 -14 -3 -27 -8 -39c265 -39 424 -249 424 -441c0 -483 172 -707 320 -832z" />
+ <glyph glyph-name="shaarli" unicode="&#xf2f5;" horiz-adv-x="1651"
+d="M878 1408c161 0 254 -160 278 -479h66c287 -44 429 -135 426 -273c24 -163 -80 -238 -312 -226c178 -156 241 -302 191 -437c-39 -108 -133 -143 -282 -107c-164 82 -281 176 -349 282h-43c-64 -188 -188 -282 -372 -282h-64c-153 47 -209 140 -166 278l80 221h-23
+c-225 32 -326 131 -305 298c6 153 160 231 462 233c84 9 119 36 105 80c0 275 103 412 308 412zM830 1182c-56 4 -83 -72 -82 -227l-5 -128c-5 -64 -25 -96 -61 -96l-360 -20c-56 -2 -85 -25 -85 -69c0 -43 31 -65 92 -68c211 11 310 -4 296 -43l-64 -137
+c-108 -163 -135 -258 -80 -287c73 -44 176 70 310 342c32 29 59 29 80 0c94 -100 171 -182 232 -246c62 -64 113 -83 151 -57c46 49 33 101 -37 157c-68 58 -146 137 -234 237c-9 33 -8 50 6 50c298 -20 441 -1 429 57c9 64 -121 96 -388 96c-41 -8 -74 2 -100 29v224
+c0 125 -30 186 -89 184c-3 1 -8 2 -11 2v0z" />
+ <glyph glyph-name="cc-diners-club" unicode="&#xf24c;" horiz-adv-x="2304"
+d="M858 295v693c-139 -54 -238 -189 -238 -347s99 -293 238 -346zM1362 641c0 158 -99 293 -238 347v-694c139 54 238 189 238 347zM1577 641c0 -323 -262 -586 -586 -586c-323 0 -586 263 -586 586c0 324 263 586 586 586c324 0 586 -262 586 -586zM1960 634
+c0 382 -319 646 -669 646h-301c-354 0 -646 -264 -646 -646c0 -349 292 -634 646 -634h301c350 0 669 285 669 634zM2304 1280v-1280c0 -70 -58 -128 -128 -128h-2048c-70 0 -128 58 -128 128v1280c0 70 58 128 128 128h2048c70 0 128 -58 128 -128z" />
+ <glyph glyph-name="undo" unicode="&#xf0e2;"
+d="M1536 640c0 -423 -345 -768 -768 -768c-229 0 -445 101 -591 277c-10 13 -9 32 2 43l137 138c7 6 16 9 25 9c9 -1 18 -5 23 -12c98 -127 245 -199 404 -199c282 0 512 230 512 512s-230 512 -512 512c-131 0 -255 -50 -348 -137l137 -138c19 -18 24 -46 14 -69
+c-10 -24 -33 -40 -59 -40h-448c-35 0 -64 29 -64 64v448c0 26 16 49 40 59c23 10 51 5 69 -14l130 -129c141 133 332 212 529 212c423 0 768 -345 768 -768z" />
+ <glyph glyph-name="rebel" unicode="&#xf1d0;" horiz-adv-x="1756"
+d="M0 662c10 286 156 550 421 724c1 0 7 2 4 -3c-21 -20 -402 -469 -51 -818c180 -179 325 -9 325 -9c139 181 -2 455 -2 455c-36 90 -165 145 -165 145l104 115c88 -38 156 -140 156 -140c3 107 -79 222 -79 222l161 183l160 -181c-74 -104 -79 -226 -79 -226
+c50 83 157 142 157 142l103 -115c-99 -32 -164 -144 -164 -144c-57 -103 -98 -323 2 -460c117 -161 317 10 317 10c371 332 -38 813 -38 813c-22 20 3 10 3 10c181 -132 414 -305 420 -740c7 -526 -361 -901 -876 -901c-503 0 -894 420 -879 918z" />
+ <glyph glyph-name="codiepie" unicode="&#xf284;" horiz-adv-x="1723"
+d="M1584 246l-218 111c-98 -160 -272 -258 -460 -258c-298 0 -539 241 -539 538c0 298 241 539 539 539c175 0 339 -85 440 -229l215 125c-147 226 -396 361 -665 361c-438 0 -793 -355 -793 -793s355 -793 793 -793c284 0 547 152 688 399zM1030 643l693 -352
+c-152 -332 -457 -547 -827 -547c-495 0 -896 401 -896 896s401 896 896 896c352 0 642 -194 806 -500zM1543 640h-39v-160h-96v352h136c111 0 121 -192 -1 -192z" />
+ <glyph glyph-name="soundcloud" unicode="&#xf1be;" horiz-adv-x="2304"
+d="M784 164c-1 -13 -11 -23 -24 -23c-12 0 -22 10 -23 23l-14 241l14 523c0 13 11 24 23 24c13 0 23 -11 24 -24l16 -523zM1080 193l-1 -24c0 -8 -3 -15 -9 -20c-5 -5 -12 -9 -20 -9c-9 0 -17 4 -23 11c-4 5 -6 11 -6 17v1c-11 235 -11 236 -11 236l10 579l1 6
+c0 10 5 19 13 24c5 3 10 5 16 5s11 -2 16 -5c8 -5 13 -14 13 -24l12 -586zM35 533l20 -128l-20 -126c-1 -5 -4 -9 -9 -9s-8 4 -9 9l-17 126l17 128c1 5 4 9 9 9s8 -4 9 -9zM121 612l26 -207l-26 -203c-1 -5 -5 -9 -10 -9s-9 4 -9 10l-23 202l23 207c0 5 4 9 9 9s9 -4 10 -9z
+M401 159zM213 650l25 -245l-25 -237c0 -6 -5 -11 -11 -11s-11 5 -12 11l-21 237l21 245c1 7 6 12 12 12s11 -5 11 -12zM307 657l23 -252l-23 -244c-1 -8 -7 -13 -14 -13s-13 5 -13 13l-21 244l21 252c0 8 6 13 13 13s13 -5 14 -13zM401 639l21 -234l-21 -246
+c-1 -9 -8 -16 -16 -16s-15 7 -15 16l-20 246l20 234c0 8 7 15 15 15s15 -7 16 -15zM784 164zM495 785l21 -380l-21 -246c0 -10 -8 -18 -17 -18c-10 0 -17 8 -18 18l-18 246l18 380c1 10 8 18 18 18c9 0 17 -8 17 -18zM589 871l19 -468l-19 -244c0 -11 -9 -19 -19 -19
+c-11 0 -19 8 -20 19l-16 244l16 468c1 11 9 19 20 19c10 0 19 -8 19 -19zM687 911l18 -506l-18 -242c-1 -12 -10 -21 -22 -21c-11 0 -20 9 -21 21l-16 242l16 506c0 12 10 22 21 22c12 0 21 -10 22 -22zM1079 169zM881 915l15 -510l-15 -239c0 -14 -11 -25 -25 -25
+s-24 11 -25 25l-14 239l14 510c0 14 11 25 25 25s25 -11 25 -25zM980 896l14 -492l-14 -236c0 -15 -12 -27 -27 -27s-27 12 -28 27l-12 236l12 492c1 16 13 28 28 28s26 -12 27 -28zM1192 404l-14 -231c0 -17 -14 -31 -31 -31s-31 14 -32 31l-6 114l-6 117l12 636v3
+c1 9 5 18 12 24c5 4 12 7 20 7c5 0 11 -2 15 -5c9 -5 15 -15 16 -26zM2304 423c0 -156 -127 -282 -283 -282h-786c-17 2 -31 15 -31 33v899c0 17 6 25 28 33c55 22 117 34 181 34c261 0 475 -200 498 -455c34 14 71 22 110 22c156 0 283 -127 283 -284z" />
+ <glyph glyph-name="microphone" unicode="&#xf130;" horiz-adv-x="1152"
+d="M1152 832v-128c0 -296 -224 -540 -512 -572v-132h256c35 0 64 -29 64 -64s-29 -64 -64 -64h-640c-35 0 -64 29 -64 64s29 64 64 64h256v132c-288 32 -512 276 -512 572v128c0 35 29 64 64 64s64 -29 64 -64v-128c0 -247 201 -448 448 -448s448 201 448 448v128
+c0 35 29 64 64 64s64 -29 64 -64zM896 1216v-512c0 -176 -144 -320 -320 -320s-320 144 -320 320v512c0 176 144 320 320 320s320 -144 320 -320z" />
+ <glyph glyph-name="laravel" unicode="&#xf30b;" horiz-adv-x="1870"
+d="M1863 682v0c13 -14 10 -25 -13 -31c-20 -6 -203 -54 -255 -68c76 -101 219 -294 231 -312c17 -25 2 -32 -23 -42s-571 -207 -608 -218c-48 -14 -69 -21 -100 22c-23 33 -149 259 -211 371c-117 -30 -330 -86 -392 -101c-60 -14 -86 22 -96 44s-365 786 -387 839
+c-23 53 2 62 24 64s335 28 376 30s44 -8 62 -34l450 -753l566 136c-31 44 -173 246 -187 265c-15 22 0 32 25 36s242 41 261 44s33 9 63 -27s201 -251 214 -265zM834 472c7 1 10 5 3 18s-422 729 -422 729c-4 7 -3 9 -13 9s-305 -27 -310 -27s-5 -8 0 -18s380 -783 382 -789
+s2 -8 19 -4s334 81 341 82zM1728 304c-5 8 -178 244 -187 258s-13 10 -27 6l-552 -143s169 -293 182 -312s21 -17 31 -13s531 179 547 185s11 11 6 19zM1763 696c13 3 22 7 16 14s-149 189 -159 203s-18 12 -27 10c-8 -2 -196 -36 -208 -38s-8 -8 -3 -15l166 -227
+s202 50 215 53z" />
+ <glyph glyph-name="indent" unicode="&#xf03c;" horiz-adv-x="1792"
+d="M352 704c0 -8 -3 -17 -9 -23l-288 -288c-6 -6 -15 -9 -23 -9c-17 0 -32 15 -32 32v576c0 17 15 32 32 32c8 0 17 -3 23 -9l288 -288c6 -6 9 -15 9 -23zM1792 224v-192c0 -17 -15 -32 -32 -32h-1728c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h1728c17 0 32 -15 32 -32z
+M1792 608v-192c0 -17 -15 -32 -32 -32h-1088c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h1088c17 0 32 -15 32 -32zM1792 992v-192c0 -17 -15 -32 -32 -32h-1088c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h1088c17 0 32 -15 32 -32zM1792 1376v-192c0 -17 -15 -32 -32 -32
+h-1728c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h1728c17 0 32 -15 32 -32z" />
+ <glyph glyph-name="address-card-o" unicode="&#xf2bc;" horiz-adv-x="2048"
+d="M1024 405c0 -87 -57 -149 -128 -149h-512c-71 0 -128 62 -128 149c0 155 38 327 196 327c49 -28 115 -76 188 -76s139 48 188 76c158 0 196 -172 196 -327zM867 925c0 -126 -102 -227 -227 -227s-227 101 -227 227c0 125 102 227 227 227s227 -102 227 -227zM1792 480
+v-64c0 -18 -14 -32 -32 -32h-576c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h576c18 0 32 -14 32 -32zM1792 732v-56c0 -20 -16 -36 -36 -36h-568c-20 0 -36 16 -36 36v56c0 20 16 36 36 36h568c20 0 36 -16 36 -36zM1792 992v-64c0 -18 -14 -32 -32 -32h-576
+c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h576c18 0 32 -14 32 -32zM1920 32v1216c0 17 -15 32 -32 32h-1728c-17 0 -32 -15 -32 -32v-1216c0 -17 15 -32 32 -32h352v96c0 18 14 32 32 32h64c18 0 32 -14 32 -32v-96h768v96c0 18 14 32 32 32h64c18 0 32 -14 32 -32v-96h352
+c17 0 32 15 32 32zM2048 1248v-1216c0 -88 -72 -160 -160 -160h-1728c-88 0 -160 72 -160 160v1216c0 88 72 160 160 160h1728c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="language" unicode="&#xf1ab;"
+d="M654 458c-2 -7 -51 16 -64 21c-13 6 -72 39 -87 49s-72 57 -79 60c-36 -55 -82 -120 -134 -181c-18 -21 -72 -89 -105 -110c-5 -3 -34 -6 -38 -4c16 12 62 69 82 92c25 29 144 195 164 233c21 38 84 164 87 176c-10 1 -89 -26 -110 -33c-20 -6 -75 -19 -79 -22
+c-4 -4 -1 -16 -3 -20s-20 -13 -31 -15c-10 -3 -33 -4 -47 0c-13 3 -25 16 -28 21c0 0 -4 6 -5 23c12 4 32 5 54 11s76 22 105 32s85 31 102 35c18 3 63 33 87 41s41 18 42 13s0 -27 -1 -33c-1 -5 -49 -99 -56 -114c-4 -8 -32 -61 -77 -131c16 -7 50 -21 64 -28
+c17 -8 136 -58 142 -60s17 -48 15 -56zM449 944c3 -17 -2 -24 -4 -28c-10 -19 -35 -32 -50 -38s-40 -12 -60 -12c-9 1 -27 4 -49 26c-12 13 -21 48 -17 44s33 -8 46 -5s44 12 58 16c15 5 45 13 55 14c10 0 18 -4 21 -17zM1147 815l63 -227l-139 42zM39 15l694 232v1032
+l-694 -233v-1031zM1280 332l102 -31l-181 657l-100 31l-216 -536l102 -31l45 110l211 -65zM777 1294l573 -184v380zM1088 -29l158 -13l-54 -160l-40 66c-81 -52 -181 -92 -276 -108c-29 -6 -62 -12 -91 -12h-84c-106 0 -299 63 -383 124c-6 5 -8 9 -8 16c0 11 8 19 18 19
+c9 0 56 -29 69 -35c90 -45 216 -86 317 -86c125 0 210 16 324 65c33 15 62 34 93 51zM1536 1050v-1079c-773 246 -774 246 -774 246c-16 -7 -733 -249 -743 -249c-8 0 -15 5 -18 13c0 1 -1 2 -1 3v1078c1 3 2 8 4 10c6 7 14 9 20 11c3 1 64 21 149 50v384l558 -198
+c7 2 629 217 638 217c11 0 20 -8 20 -21v-418z" />
+ <glyph glyph-name="circle-thin" unicode="&#xf1db;"
+d="M768 1280c-353 0 -640 -287 -640 -640s287 -640 640 -640s640 287 640 640s-287 640 -640 640zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="drupal" unicode="&#xf1a9;"
+d="M1167 -50c-2 7 -8 17 -24 5c-34 -25 -110 -56 -218 -56s-159 23 -193 49c-5 4 -3 4 -13 4c-11 0 -17 -5 -26 -12c-8 -7 -12 -24 0 -36c74 -68 198 -62 289 -54c92 9 170 63 178 71c12 12 9 22 7 29zM1128 65c-7 17 -19 47 -39 61c-20 13 -49 15 -76 15s-42 2 -71 -10
+s-59 -39 -78 -56s-22 -30 -12 -44c10 -13 21 -5 49 19c29 23 48 44 107 44s69 -22 81 -44s13 -25 25 -19c14 7 21 17 14 34zM1483 346c0 52 -23 140 -108 140c-80 0 -242 -166 -327 -167c-99 -2 -236 196 -434 194c-156 -1 -279 -125 -281 -257c-1 -74 23 -129 74 -164
+c34 -23 65 -37 166 -37c168 0 381 208 479 205c78 -3 199 -194 260 -198c48 -4 73 18 114 77c40 60 57 154 57 207zM1536 506c0 -448 -354 -744 -761 -744c-408 0 -775 321 -775 758c0 436 340 638 403 671c75 40 129 61 214 129c42 33 77 81 88 198
+c61 -73 134 -158 186 -193c85 -56 170 -78 259 -134c54 -33 386 -236 386 -685z" />
+ <glyph glyph-name="headphones" unicode="&#xf025;" horiz-adv-x="1664"
+d="M1664 650c0 -109 -20 -215 -60 -314l-20 -49l-185 -33c-29 -109 -128 -190 -247 -190v-32c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v576c0 18 14 32 32 32h64c18 0 32 -14 32 -32v-32c96 0 179 -53 223 -131l68 12c19 62 29 126 29 193c0 302 -299 566 -640 566
+s-640 -264 -640 -566c0 -67 10 -131 29 -193l68 -12c44 78 127 131 223 131v32c0 18 14 32 32 32h64c18 0 32 -14 32 -32v-576c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v32c-119 0 -218 81 -247 190l-185 33l-20 49c-40 99 -60 205 -60 314c0 411 381 758 832 758
+s832 -347 832 -758z" />
+ <glyph glyph-name="cc-mastercard" unicode="&#xf1f1;" horiz-adv-x="2304"
+d="M1119 1195c-83 55 -181 85 -281 85c-281 0 -509 -228 -509 -508c0 -281 228 -509 509 -509c100 0 198 30 281 85c-268 218 -266 629 0 847zM1152 1171c-258 -203 -259 -597 0 -799c259 202 258 596 0 799zM1185 1195c265 -218 269 -630 0 -847c83 -55 182 -85 281 -85
+c281 0 509 228 509 509c0 280 -228 508 -509 508c-100 0 -198 -30 -281 -85zM1926 473h7v3h-17v-3h7v-17h3v17zM1955 456h4v20h-5l-6 -13l-6 13h-5v-20h3v15l6 -13h4l5 13v-15zM1947 16v-2h-5v3h5v-1zM1947 7h3l-4 5c2 0 2 1 3 1c1 1 1 2 1 3s0 2 -1 3c-1 0 -2 1 -4 1h-6
+v-13h3v5h1zM685 75c0 24 15 43 41 43c24 0 40 -19 40 -43c0 -25 -16 -43 -40 -43c-26 0 -41 19 -41 43zM1158 119c19 0 32 -11 35 -32h-70c3 19 15 32 35 32zM1514 75c0 24 15 43 40 43s41 -19 41 -43c0 -25 -16 -43 -41 -43s-40 19 -40 43zM1786 75c0 24 16 43 41 43
+c24 0 41 -19 41 -43c0 -25 -17 -43 -41 -43c-25 0 -41 19 -41 43zM1944 3c-1 0 -2 0 -4 1c-1 0 -2 1 -3 2s-2 2 -2 3c-1 2 -1 3 -1 4c0 2 0 3 1 4c0 2 1 3 2 4s2 1 3 2c2 1 3 1 4 1c2 0 3 0 4 -1c2 -1 3 -1 4 -2s1 -2 2 -4c0 -1 1 -2 1 -4c0 -1 -1 -2 -1 -4
+c-1 -1 -1 -2 -2 -3s-2 -2 -4 -2c-1 -1 -2 -1 -4 -1zM599 7h30v85c0 32 -21 53 -54 54c-17 0 -35 -5 -47 -24c-9 15 -24 24 -45 24c-14 0 -28 -5 -39 -20v16h-30v-135h30v75c0 24 13 36 33 36s30 -13 30 -36v-75h29v75c0 24 14 36 33 36c20 0 30 -13 30 -36v-75zM765 7h29
+v135h-29v-16c-10 12 -24 20 -43 20c-38 0 -67 -30 -67 -71s29 -71 67 -71c19 0 33 7 43 20v-17zM943 48c0 24 -18 36 -47 40l-14 2c-13 2 -23 5 -23 14s9 15 25 15c18 0 34 -6 43 -11l12 24c-14 9 -33 14 -55 14c-34 0 -56 -17 -56 -44c0 -22 16 -35 47 -39l13 -2
+c17 -3 24 -7 24 -14c0 -11 -11 -17 -31 -17s-35 7 -45 14l-13 -23c16 -11 36 -17 58 -17c39 0 62 18 62 44zM1073 14l-8 25c-9 -5 -18 -7 -26 -7c-15 0 -19 9 -19 22v61h48v27h-48v41h-30v-41h-28v-27h28v-61c0 -31 12 -50 47 -50c12 0 27 4 36 10zM1159 146
+c-39 0 -67 -29 -67 -71c0 -43 29 -71 69 -71c20 0 39 5 55 19l-14 22c-11 -9 -26 -15 -39 -15c-19 0 -36 9 -41 33h101v12c0 42 -26 71 -64 71zM1318 146c-17 0 -28 -8 -35 -20v16h-30v-135h30v76c0 22 9 35 29 35c6 0 12 -1 18 -4l9 28c-7 3 -15 4 -21 4zM1348 75
+c0 -41 28 -71 72 -71c20 0 34 4 48 16l-14 24c-11 -8 -22 -13 -35 -12c-24 0 -41 17 -41 43s17 43 41 43c13 0 24 -4 35 -12l14 24c-14 11 -28 16 -48 16c-44 0 -72 -30 -72 -71zM1593 7h30v135h-30v-16c-9 12 -23 20 -42 20c-38 0 -68 -30 -68 -71s30 -71 68 -71
+c19 0 33 7 42 20v-17zM1726 146c-17 0 -28 -8 -35 -20v16h-29v-135h29v76c0 22 10 35 29 35c6 0 12 -1 18 -4l9 28c-6 3 -15 4 -21 4zM1866 7h29v190h-29v-71c-9 12 -23 20 -43 20c-37 0 -67 -30 -67 -71s30 -71 67 -71c20 0 34 7 43 20v-17zM1944 27c-1 0 -3 -1 -5 -1
+c-2 -1 -3 -2 -4 -3c-2 -1 -3 -3 -3 -4c-1 -2 -1 -4 -1 -6c0 -1 0 -3 1 -5c0 -1 1 -3 3 -4c1 -1 2 -2 4 -3s4 -1 5 -1c2 0 4 0 6 1c1 1 3 2 4 3s2 3 3 4c1 2 1 4 1 5c0 2 0 4 -1 6c-1 1 -2 3 -3 4s-3 2 -4 3c-2 0 -4 1 -6 1zM2304 1280v-1280c0 -70 -58 -128 -128 -128h-2048
+c-70 0 -128 58 -128 128v1280c0 70 58 128 128 128h2048c70 0 128 -58 128 -128z" />
+ <glyph glyph-name="times" unicode="&#xf00d;" horiz-adv-x="1188"
+d="M1188 214c0 -25 -10 -50 -28 -68l-136 -136c-18 -18 -43 -28 -68 -28s-50 10 -68 28l-294 294l-294 -294c-18 -18 -43 -28 -68 -28s-50 10 -68 28l-136 136c-18 18 -28 43 -28 68s10 50 28 68l294 294l-294 294c-18 18 -28 43 -28 68s10 50 28 68l136 136
+c18 18 43 28 68 28s50 -10 68 -28l294 -294l294 294c18 18 43 28 68 28s50 -10 68 -28l136 -136c18 -18 28 -43 28 -68s-10 -50 -28 -68l-294 -294l294 -294c18 -18 28 -43 28 -68z" />
+ <glyph glyph-name="buysellads" unicode="&#xf20d;"
+d="M915 450h-294l147 551zM1001 128h311l-324 1024h-440l-324 -1024h311l383 314zM1536 1120v-960c0 -158 -130 -288 -288 -288h-960c-158 0 -288 130 -288 288v960c0 158 130 288 288 288h960c158 0 288 -130 288 -288z" />
+ <glyph glyph-name="diaspora" unicode="&#xf2e5;" horiz-adv-x="1581"
+d="M1005 -16c-42 59 -111 155 -153 214c-41 57 -75 102 -77 102s-66 -87 -152 -205c-82 -113 -150 -205 -151 -205c-2 0 -296 207 -297 209c0 1 65 99 147 217s149 217 149 219c0 4 -27 14 -234 83c-129 43 -235 78 -237 79s10 41 52 174c30 95 56 174 57 175
+s112 -35 248 -80s249 -81 250 -81s2 2 3 5s2 118 3 257s2 254 3 255c1 2 40 2 180 2c98 0 179 0 180 -1c2 -1 4 -78 8 -249c7 -281 9 -285 13 -285c2 0 109 36 239 80s236 79 237 78c3 -3 109 -350 108 -351s-109 -37 -241 -82c-181 -61 -240 -82 -240 -85
+c0 -2 62 -95 141 -211c78 -114 141 -208 141 -209c-1 -2 -293 -217 -295 -217c-1 0 -38 50 -82 112z" />
+ <glyph glyph-name="att" unicode="&#xf31e;"
+d="M768 1407v0c144 0 278 -39 393 -108c31 -19 46 -30 46 -48c0 -73 -206 -150 -472 -150c-268 0 -419 70 -419 135c0 22 19 39 54 60c116 71 253 111 398 111zM273 1226v0c1 0 0 -1 -1 -2c-22 -27 -31 -53 -31 -79c0 -72 57 -185 362 -185c416 0 677 151 677 236
+c0 7 -2 13 -5 18c-1 1 0 2 1 1c25 -23 48 -46 73 -74c38 -43 53 -66 53 -104c0 -107 -166 -228 -539 -228c-350 0 -725 108 -725 257c0 10 10 28 25 47c32 41 68 78 108 112c1 0 2 1 2 1zM1456 979v0s1 0 1 -1c18 -36 40 -89 51 -133c10 -40 10 -69 2 -97
+c-43 -152 -307 -235 -646 -235c-556 0 -794 160 -841 260c-6 12 -7 20 -4 37c7 39 32 114 55 159c1 1 1 1 1 0c-4 -15 -6 -30 -6 -45c0 -153 253 -274 557 -274c281 0 837 129 830 328v1zM1534 683v0s1 -1 1 -2c1 -13 1 -25 1 -41c0 -67 -9 -146 -28 -190
+c-26 -61 -154 -248 -714 -248c-411 0 -649 139 -744 238c-21 22 -36 49 -39 67c-7 36 -11 91 -11 133c0 2 2 2 2 0c34 -125 219 -308 612 -308c413 0 891 200 919 350c0 1 1 1 1 1zM1482 360v0c1 0 1 -1 1 -2c-13 -33 -30 -67 -47 -96c-29 -50 -61 -86 -95 -114
+c-124 -102 -332 -154 -521 -154c-359 0 -649 111 -745 315c-1 2 0 2 1 1c103 -149 366 -227 610 -227c345 0 679 106 795 276c0 1 1 1 1 1zM1274 64v0c1 0 1 -1 0 -2c-135 -118 -312 -190 -506 -190c-177 0 -341 60 -471 161c-1 1 -1 3 1 2c84 -47 234 -100 470 -100
+c272 0 444 89 505 129h1z" />
+ <glyph glyph-name="sort-asc" unicode="&#xf0de;" horiz-adv-x="1024"
+d="M1024 832c0 -35 -29 -64 -64 -64h-896c-35 0 -64 29 -64 64c0 17 7 33 19 45l448 448c12 12 28 19 45 19s33 -7 45 -19l448 -448c12 -12 19 -28 19 -45z" />
+ <glyph glyph-name="folder-open" unicode="&#xf07c;" horiz-adv-x="1879"
+d="M1879 584c0 -24 -15 -48 -31 -66l-336 -396c-58 -68 -176 -122 -264 -122h-1088c-36 0 -87 11 -87 56c0 24 15 48 31 66l336 396c58 68 176 122 264 122h1088c36 0 87 -11 87 -56zM1536 928v-160h-832c-125 0 -280 -71 -361 -167l-337 -396l-5 -6c0 8 -1 17 -1 25v960
+c0 123 101 224 224 224h320c123 0 224 -101 224 -224v-32h544c123 0 224 -101 224 -224z" />
+ <glyph glyph-name="heartbeat" unicode="&#xf21e;" horiz-adv-x="1792"
+d="M1280 512h305c-12 -13 -20 -20 -22 -22l-623 -600c-12 -12 -28 -18 -44 -18s-32 6 -44 18l-624 602c-2 1 -10 8 -21 20h369c29 0 55 20 62 48l70 281l190 -667c8 -27 33 -46 62 -46c28 0 53 19 61 46l146 485l56 -112c11 -21 33 -35 57 -35zM1792 940
+c0 -115 -50 -220 -103 -300h-369l-111 221c-11 23 -37 37 -62 35c-27 -3 -49 -20 -56 -46l-129 -430l-196 686c-8 27 -33 46 -63 46c-29 0 -54 -20 -61 -48l-116 -464h-423c-53 80 -103 185 -103 300c0 293 179 468 478 468c175 0 339 -138 418 -216c79 78 243 216 418 216
+c299 0 478 -175 478 -468z" />
+ <glyph glyph-name="blind" unicode="&#xf29d;" horiz-adv-x="1330"
+d="M327 1225c-86 0 -156 70 -156 156c0 85 70 155 156 155s155 -70 155 -155c0 -86 -69 -156 -155 -156zM878 583c0 -108 -115 -84 -141 -40l-367 438c-16 26 -28 14 -28 14s-7 -8 4 -21l122 -139l1 -354c-86 -250 -161 -457 -161 -457c-47 -134 -86 -250 -120 -266
+c-41 -21 -71 -16 -103 -1c-42 19 -54 70 -51 100c0 0 2 16 197 618l5 416l-85 -164l35 -222c13 -84 -58 -95 -58 -95c-68 -11 -82 68 -82 70l-46 299c210 379 211 381 211 381c16 24 52 34 113 34c54 0 88 -16 107 -40l424 -521c6 -4 10 -10 14 -17l3 -3l-1 -1
+c5 -9 7 -19 7 -29zM475 433c96 -255 182 -448 182 -448c29 -74 79 -180 6 -222c-72 -42 -130 7 -146 41h-1c-3 8 -6 16 -8 25l-124 351zM1299 -159c21 -33 39 -57 28 -64c-19 -12 -25 23 -46 57c0 0 -113 171 -423 661c6 -2 17 7 17 7s11 9 11 17
+c308 -503 413 -678 413 -678z" />
+ <glyph glyph-name="arrows-v" unicode="&#xf07d;" horiz-adv-x="640"
+d="M640 1216c0 -35 -29 -64 -64 -64h-128v-1024h128c35 0 64 -29 64 -64c0 -17 -7 -33 -19 -45l-256 -256c-12 -12 -28 -19 -45 -19s-33 7 -45 19l-256 256c-12 12 -19 28 -19 45c0 35 29 64 64 64h128v1024h-128c-35 0 -64 29 -64 64c0 17 7 33 19 45l256 256
+c12 12 28 19 45 19s33 -7 45 -19l256 -256c12 -12 19 -28 19 -45z" />
+ <glyph glyph-name="phone-square" unicode="&#xf098;"
+d="M1280 343c0 5 0 11 -2 16c-6 18 -152 92 -180 108c-19 11 -42 33 -65 33c-44 0 -109 -131 -148 -131c-20 0 -45 18 -63 28c-132 74 -223 165 -297 297c-10 18 -28 43 -28 63c0 39 131 104 131 148c0 23 -22 46 -33 65c-16 28 -90 174 -108 180c-5 2 -11 2 -16 2
+c-26 0 -77 -12 -101 -22c-66 -30 -114 -156 -114 -225c0 -67 27 -128 50 -190c80 -219 318 -457 537 -537c62 -23 123 -50 190 -50c69 0 195 48 225 114c10 24 22 75 22 101zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960
+c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="text-height" unicode="&#xf034;" horiz-adv-x="1789"
+d="M1744 128c44 0 58 -28 31 -63l-126 -162c-27 -35 -71 -35 -98 0l-126 162c-27 35 -13 63 31 63h80v1024h-80c-44 0 -58 28 -31 63l126 162c27 35 71 35 98 0l126 -162c27 -35 13 -63 -31 -63h-80v-1024h80zM81 1407l54 -27c7 -3 190 -5 211 -5c88 0 176 4 264 4
+c72 0 143 -1 215 -1h293c40 0 63 -9 90 29l42 1c9 0 19 -1 28 -1c2 -112 2 -224 2 -336c0 -35 1 -74 -5 -109c-22 -8 -45 -15 -68 -18c-23 40 -39 84 -54 128c-7 20 -31 155 -33 157c-21 26 -44 21 -75 21c-91 0 -186 4 -276 -7c-5 -44 -9 -91 -8 -136c1 -281 4 -562 4 -843
+c0 -77 -12 -158 10 -232c76 -39 166 -45 244 -80c2 -16 5 -33 5 -50c0 -9 -1 -19 -3 -29l-34 -1c-142 -4 -282 18 -425 18c-101 0 -202 -18 -303 -18c-1 17 -3 35 -3 52v9c38 61 175 62 238 99c22 49 19 320 19 383c0 202 -6 404 -6 606v117c0 18 4 90 -8 104
+c-14 15 -145 12 -162 12c-37 0 -144 -17 -173 -38c-48 -33 -48 -233 -108 -237c-18 11 -43 27 -56 44v383z" />
+ <glyph glyph-name="linkedin-square" unicode="&#xf08c;"
+d="M237 122h231v694h-231v-694zM483 1030c-1 68 -50 120 -129 120s-131 -52 -131 -120c0 -66 50 -120 128 -120h1c81 0 131 54 131 120zM1068 122h231v398c0 213 -114 312 -266 312c-124 0 -179 -69 -209 -117h2v101h-231s3 -65 0 -694h231v388c0 20 1 41 7 56
+c17 41 55 84 119 84c83 0 116 -63 116 -157v-371zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="delicious" unicode="&#xf1a5;"
+d="M1472 160v480h-704v704h-480c-124 0 -224 -100 -224 -224v-480h704v-704h480c124 0 224 100 224 224zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="qrcode" unicode="&#xf029;"
+d="M0 1408h768v-704h-128v576h-512v-512h640v-128h-768v768zM0 -128v640h640v-640h-576v128h448v384h-384v-512h-128zM896 768v640h640v-640h-576v128h448v384h-384v-512h-128zM256 1152h256v-256h-256v256zM1152 1152h128v-128h-128v128zM256 256h128v-128h-128v128z
+M768 512h128v-128h-128v128zM1152 384h128v-128h-128v128zM1152 128h128v-128h-128v128zM1024 640h384v-256h-128v128h-256v128zM1536 256v-384h-256v128h128v256h128zM1024 384v-256h-256v128h128v128h128zM768 0h384v-128h-384v128z" />
+ <glyph glyph-name="arrows-h" unicode="&#xf07e;" horiz-adv-x="1792"
+d="M1792 640c0 -17 -7 -33 -19 -45l-256 -256c-12 -12 -28 -19 -45 -19c-35 0 -64 29 -64 64v128h-1024v-128c0 -35 -29 -64 -64 -64c-17 0 -33 7 -45 19l-256 256c-12 12 -19 28 -19 45s7 33 19 45l256 256c12 12 28 19 45 19c35 0 64 -29 64 -64v-128h1024v128
+c0 35 29 64 64 64c17 0 33 -7 45 -19l256 -256c12 -12 19 -28 19 -45z" />
+ <glyph glyph-name="mercury" unicode="&#xf223;" horiz-adv-x="1152"
+d="M830 1220c190 -94 322 -290 322 -516c0 -296 -224 -540 -512 -572v-132h96c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-96v-96c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v96h-96c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h96v132c-288 32 -512 276 -512 572
+c0 226 132 422 322 516c-105 61 -187 157 -228 273c-8 21 8 43 30 43h69c13 0 24 -8 29 -20c58 -139 195 -236 354 -236s296 97 354 236c5 12 16 20 37 20h61c22 0 38 -22 30 -43c-41 -116 -123 -212 -228 -273zM576 256c247 0 448 201 448 448s-201 448 -448 448
+s-448 -201 -448 -448s201 -448 448 -448z" />
+ <glyph glyph-name="text-width" unicode="&#xf035;"
+d="M81 1407l54 -27c7 -3 190 -5 211 -5c88 0 176 4 264 4c265 0 533 6 798 -3c22 -1 43 13 56 31l42 1c9 0 19 -1 28 -1c2 -112 2 -224 2 -336c0 -36 1 -74 -5 -109c-22 -8 -45 -15 -68 -18c-23 40 -39 84 -54 128c-7 20 -32 155 -33 157c-7 9 -16 15 -27 19
+c-8 3 -56 2 -66 2c-123 0 -265 7 -386 -7c-5 -44 -9 -91 -8 -136l1 -152v52c1 -163 3 -325 3 -487c0 -77 -12 -158 10 -232c76 -39 166 -45 244 -80c2 -16 5 -33 5 -50c0 -9 -1 -19 -3 -29l-34 -1c-142 -4 -282 18 -425 18c-101 0 -202 -18 -303 -18c-1 17 -3 35 -3 52v9
+c38 61 175 62 238 99c25 56 18 529 18 617c0 14 -5 29 -5 44c0 41 7 276 -8 293c-14 15 -145 12 -162 12c-42 0 -277 -22 -301 -38c-47 -31 -48 -232 -108 -237c-18 11 -43 27 -56 44v383zM1310 125c35 0 168 -119 195 -140c15 -12 26 -29 26 -49s-11 -37 -26 -49
+c-27 -21 -160 -140 -195 -140c-46 0 -30 107 -30 125h-1024c0 -18 16 -125 -30 -125c-35 0 -168 119 -195 140c-15 12 -26 29 -26 49s11 37 26 49c27 21 160 140 195 140c46 0 30 -107 30 -125h1024c0 18 -16 125 30 125z" />
+ <glyph glyph-name="envelope-o" unicode="&#xf003;" horiz-adv-x="1792"
+d="M1664 32v768c-21 -24 -44 -46 -69 -66c-143 -110 -287 -222 -426 -338c-75 -63 -168 -140 -272 -140h-2c-104 0 -197 77 -272 140c-139 116 -283 228 -426 338c-25 20 -48 42 -69 66v-768c0 -17 15 -32 32 -32h1472c17 0 32 15 32 32zM1664 1083c0 25 6 69 -32 69h-1472
+c-17 0 -32 -15 -32 -32c0 -114 57 -213 147 -284c134 -105 268 -211 401 -317c53 -43 149 -135 219 -135h2c70 0 166 92 219 135c133 106 267 212 401 317c65 51 147 162 147 247zM1792 1120v-1088c0 -88 -72 -160 -160 -160h-1472c-88 0 -160 72 -160 160v1088
+c0 88 72 160 160 160h1472c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="rss-square" unicode="&#xf143;"
+d="M512 256c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM863 162c-17 310 -263 556 -573 573c-9 1 -18 -3 -24 -9s-10 -14 -10 -23v-128c0 -17 13 -31 30 -32c205 -15 370 -180 385 -385c1 -17 15 -30 32 -30h128c9 0 17 4 23 10
+s10 15 9 24zM1247 161c-17 520 -438 941 -958 958c-10 1 -17 -2 -23 -9c-6 -6 -10 -14 -10 -23v-128c0 -17 14 -31 31 -32c415 -15 753 -353 768 -768c1 -17 15 -31 32 -31h128c9 0 17 4 23 10c7 6 10 14 9 23zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960
+c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="bookmark" unicode="&#xf02e;" horiz-adv-x="1280"
+d="M1164 1408c15 0 30 -3 44 -9c44 -17 72 -58 72 -103v-1289c0 -45 -28 -86 -72 -103c-14 -6 -29 -8 -44 -8c-31 0 -60 11 -83 32l-441 424l-441 -424c-23 -21 -52 -33 -83 -33c-15 0 -30 3 -44 9c-44 17 -72 58 -72 103v1289c0 45 28 86 72 103c14 6 29 9 44 9h1048z" />
+ <glyph glyph-name="behance" unicode="&#xf1b4;" horiz-adv-x="2048"
+d="M1848 1197v-124h-511v124h511zM1596 771c-120 0 -200 -75 -208 -195h408c-11 121 -74 195 -200 195zM1612 186c76 0 174 41 198 119h221c-68 -209 -209 -307 -427 -307c-288 0 -467 195 -467 479c0 274 189 483 467 483c286 0 444 -225 444 -495c0 -16 -1 -32 -2 -47
+h-658c0 -146 77 -232 224 -232zM277 236h296c113 0 205 40 205 167c0 129 -77 180 -199 180h-302v-347zM277 773h281c99 0 169 43 169 150c0 116 -90 144 -190 144h-260v-294zM0 1282h594c216 0 403 -61 403 -312c0 -127 -59 -209 -172 -263c155 -44 230 -161 230 -319
+c0 -256 -215 -366 -444 -366h-611v1260z" />
+ <glyph glyph-name="wpbeginner" unicode="&#xf297;" horiz-adv-x="1792"
+d="M384 704h160v224h-160v-224zM1221 372v92c-86 -30 -157 -37 -243 -38c-193 -1 -364 79 -480 169l1 -96c109 -99 276 -177 484 -176c87 0 169 18 238 49zM640 704h640v224h-640v-224zM1792 736c0 -127 -36 -247 -99 -352c56 -64 89 -143 89 -229
+c0 -209 -198 -379 -443 -379c-166 0 -310 78 -386 193c-19 -1 -38 -1 -57 -1s-38 0 -57 1c-76 -115 -220 -193 -386 -193c-245 0 -443 170 -443 379c0 86 33 165 89 229c-63 105 -99 225 -99 352c0 424 401 768 896 768s896 -344 896 -768z" />
+ <glyph glyph-name="star-half-o" unicode="&#xf123;" horiz-adv-x="1664"
+d="M1186 579l257 250l-356 52l-66 10l-30 60l-159 322v-963l59 -31l318 -168l-60 355l-12 66zM1638 841l-363 -354l86 -500c7 -44 -9 -70 -40 -70c-11 0 -25 4 -40 12l-449 236l-449 -236c-15 -8 -29 -12 -40 -12c-31 0 -47 26 -40 70l86 500l-364 354c-43 43 -29 85 31 94
+l502 73l225 455c13 27 31 41 49 41s35 -14 49 -41l225 -455l502 -73c60 -9 74 -51 30 -94z" />
+ <glyph glyph-name="keyboard-o" unicode="&#xf11c;" horiz-adv-x="1920"
+d="M384 368v-96c0 -9 -7 -16 -16 -16h-96c-9 0 -16 7 -16 16v96c0 9 7 16 16 16h96c9 0 16 -7 16 -16zM512 624v-96c0 -9 -7 -16 -16 -16h-224c-9 0 -16 7 -16 16v96c0 9 7 16 16 16h224c9 0 16 -7 16 -16zM384 880v-96c0 -9 -7 -16 -16 -16h-96c-9 0 -16 7 -16 16v96
+c0 9 7 16 16 16h96c9 0 16 -7 16 -16zM1408 368v-96c0 -9 -7 -16 -16 -16h-864c-9 0 -16 7 -16 16v96c0 9 7 16 16 16h864c9 0 16 -7 16 -16zM768 624v-96c0 -9 -7 -16 -16 -16h-96c-9 0 -16 7 -16 16v96c0 9 7 16 16 16h96c9 0 16 -7 16 -16zM640 880v-96
+c0 -9 -7 -16 -16 -16h-96c-9 0 -16 7 -16 16v96c0 9 7 16 16 16h96c9 0 16 -7 16 -16zM1024 624v-96c0 -9 -7 -16 -16 -16h-96c-9 0 -16 7 -16 16v96c0 9 7 16 16 16h96c9 0 16 -7 16 -16zM896 880v-96c0 -9 -7 -16 -16 -16h-96c-9 0 -16 7 -16 16v96c0 9 7 16 16 16h96
+c9 0 16 -7 16 -16zM1280 624v-96c0 -9 -7 -16 -16 -16h-96c-9 0 -16 7 -16 16v96c0 9 7 16 16 16h96c9 0 16 -7 16 -16zM1664 368v-96c0 -9 -7 -16 -16 -16h-96c-9 0 -16 7 -16 16v96c0 9 7 16 16 16h96c9 0 16 -7 16 -16zM1152 880v-96c0 -9 -7 -16 -16 -16h-96
+c-9 0 -16 7 -16 16v96c0 9 7 16 16 16h96c9 0 16 -7 16 -16zM1408 880v-96c0 -9 -7 -16 -16 -16h-96c-9 0 -16 7 -16 16v96c0 9 7 16 16 16h96c9 0 16 -7 16 -16zM1664 880v-352c0 -9 -7 -16 -16 -16h-224c-9 0 -16 7 -16 16v96c0 9 7 16 16 16h112v240c0 9 7 16 16 16h96
+c9 0 16 -7 16 -16zM1792 128v896h-1664v-896h1664zM1920 1024v-896c0 -71 -57 -128 -128 -128h-1664c-71 0 -128 57 -128 128v896c0 71 57 128 128 128h1664c71 0 128 -57 128 -128z" />
+ <glyph glyph-name="minus-circle" unicode="&#xf056;"
+d="M1216 576v128c0 35 -29 64 -64 64h-768c-35 0 -64 -29 -64 -64v-128c0 -35 29 -64 64 -64h768c35 0 64 29 64 64zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="hand-o-down" unicode="&#xf0a7;"
+d="M1408 576c0 199 -128 369 -128 544v32h-640v-32c0 -106 -90 -177 -163 -241c-46 -41 -92 -79 -145 -112c-22 -14 -45 -26 -68 -38s-136 -62 -136 -89c0 -85 32 -160 128 -160c128 0 193 96 256 96v-576c0 -67 60 -128 128 -128c69 0 128 59 128 128v331
+c26 -20 70 -35 103 -35c47 0 87 19 119 53c21 -12 45 -18 69 -18c46 0 103 23 126 65c18 -3 37 -4 56 -4c118 0 167 73 167 184zM1280 1344c0 35 -29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64s64 29 64 64zM1536 580c0 -184 -104 -318 -295 -317l-5 1
+c-50 -40 -114 -61 -178 -61c-14 0 -29 1 -43 3c-34 -19 -80 -33 -119 -37v-169c0 -140 -117 -256 -257 -256c-138 0 -255 118 -255 256v374c-39 -16 -86 -22 -128 -22c-168 0 -256 129 -256 288c0 134 171 177 264 235c47 30 88 64 129 100c33 29 119 97 119 145v288
+c0 71 57 128 128 128h640c71 0 128 -57 128 -128v-288c0 -63 37 -162 59 -223c37 -102 69 -207 69 -317z" />
+ <glyph glyph-name="sort-numeric-asc" unicode="&#xf162;" horiz-adv-x="1454"
+d="M1314 223c0 82 -67 169 -147 169c-70 0 -114 -57 -114 -131c0 -72 46 -133 141 -133c65 0 120 39 120 95zM704 96c0 -9 -4 -17 -10 -24l-319 -319c-7 -6 -15 -9 -23 -9s-16 3 -23 9l-320 320c-9 10 -12 23 -7 35s17 20 30 20h192v1376c0 18 14 32 32 32h192
+c18 0 32 -14 32 -32v-1376h192c18 0 32 -14 32 -32zM1454 165c0 -202 -110 -421 -348 -421c-45 0 -82 7 -108 16c-16 5 -30 10 -42 15l39 113c9 -4 20 -8 31 -11c20 -7 46 -13 75 -13c120 0 182 100 201 204h-2c-28 -30 -87 -51 -146 -51c-145 0 -240 114 -240 244
+c0 138 106 251 253 251c159 0 287 -130 287 -347zM1424 882v-114h-469v114h167v432c0 13 1 26 1 36v16h-2l-7 -12c-5 -8 -13 -18 -26 -31l-62 -58l-82 86l192 185h123v-654h165z" />
+ <glyph glyph-name="share-alt" unicode="&#xf1e0;"
+d="M1216 512c177 0 320 -143 320 -320s-143 -320 -320 -320s-320 143 -320 320c0 11 1 23 2 34l-360 180c-57 -53 -134 -86 -218 -86c-177 0 -320 143 -320 320s143 320 320 320c84 0 161 -33 218 -86l360 180c-1 11 -2 23 -2 34c0 177 143 320 320 320s320 -143 320 -320
+s-143 -320 -320 -320c-84 0 -161 33 -218 86l-360 -180c1 -11 2 -23 2 -34s-1 -23 -2 -34l360 -180c57 53 134 86 218 86z" />
+ <glyph glyph-name="shirtsinbulk" unicode="&#xf214;"
+d="M0 1536h1536v-1392l-776 -338l-760 338v1392zM1436 209v926h-1336v-926l661 -294zM1436 1235v201h-1336v-201h1336zM181 937v-115h-37v115h37zM181 789v-115h-37v115h37zM181 641v-115h-37v115h37zM181 493v-115h-37v115h37zM181 345v-115h-37v115h37zM207 202l15 34
+l105 -47l-15 -33zM343 142l15 34l105 -46l-15 -34zM478 82l15 34l105 -46l-15 -34zM614 23l15 33l104 -46l-15 -34zM797 10l105 46l15 -33l-105 -47zM932 70l105 46l15 -34l-105 -46zM1068 130l105 46l15 -34l-105 -46zM1203 189l105 47l15 -34l-105 -46zM259 1389v-36h-114
+v36h114zM421 1389v-36h-115v36h115zM583 1389v-36h-115v36h115zM744 1389v-36h-114v36h114zM906 1389v-36h-114v36h114zM1068 1389v-36h-115v36h115zM1230 1389v-36h-115v36h115zM1391 1389v-36h-114v36h114zM181 1049v-79h-37v115h115v-36h-78zM421 1085v-36h-115v36h115z
+M583 1085v-36h-115v36h115zM744 1085v-36h-114v36h114zM906 1085v-36h-114v36h114zM1068 1085v-36h-115v36h115zM1230 1085v-36h-115v36h115zM1355 970v79h-78v36h115v-115h-37zM1355 822v115h37v-115h-37zM1355 674v115h37v-115h-37zM1355 526v115h37v-115h-37zM1355 378
+v115h37v-115h-37zM1355 230v115h37v-115h-37zM760 265c-172 0 -313 140 -313 313c0 172 141 313 313 313c173 0 313 -141 313 -313c0 -173 -140 -313 -313 -313zM595 646c0 -152 266 -41 266 -130c0 -45 -82 -49 -112 -49c-42 0 -102 9 -123 51h-3l-31 -63
+c51 -32 100 -42 162 -42c67 0 175 20 175 107c0 165 -269 56 -269 130c0 45 71 51 102 51c37 0 100 -11 122 -45h3l30 58c-52 21 -94 41 -152 41c-69 0 -170 -22 -170 -109z" />
+ <glyph glyph-name="viacoin" unicode="&#xf237;"
+d="M1536 1536l-192 -448h192v-192h-274l-55 -128h329v-192h-411l-357 -832l-357 832h-411v192h329l-55 128h-274v192h192l-192 448h256l323 -768h378l323 768h256zM768 320l108 256h-216z" />
+ <glyph glyph-name="dogmazic" unicode="&#xf303;"
+d="M768 1404c423 0 768 -343 768 -766s-345 -766 -768 -766s-768 343 -768 766s345 766 768 766zM768 1302c-368 0 -666 -297 -666 -664s298 -664 666 -664s666 297 666 664s-298 664 -666 664zM768 1223c668 3 845 -918 212 -1148c-52 -19 -148 -29 -165 -17
+c-9 6 6 111 30 214c20 88 28 84 -78 37c-49 -22 -92 -40 -96 -41c-5 -1 -23 23 -60 78c-32 48 -54 78 -55 74s-21 -73 -44 -154c-50 -177 -38 -165 -111 -110c-452 340 -218 1052 351 1067h16zM803 1137c-251 0 -505 -261 -415 -458c14 -31 19 -30 9 1
+c-66 214 206 464 458 420c281 -49 436 -423 255 -613c-49 -51 -21 -53 31 -2c184 181 17 586 -267 645c-23 5 -47 7 -71 7zM435 998c-2 0 -6 0 -10 -1c-132 -18 -189 -193 -96 -296c27 -30 30 -29 22 5c-18 75 7 167 69 258c19 28 24 34 15 34zM805 958
+c-12 0 -35 -27 -35 -44c0 -20 -7 -22 -25 -6c-42 37 -123 53 -167 34c-14 -6 -14 -5 6 -8c61 -8 101 -75 69 -117c-27 -36 -40 -72 -44 -123c-4 -61 -30 -81 -51 -39c-27 54 10 135 62 135c11 0 0 8 -15 11c-89 17 -142 -140 -56 -167c14 -4 6 -11 -14 -11
+c-24 0 -48 11 -69 31c-23 22 -10 -6 24 -53c12 -16 57 -84 101 -150c94 -139 89 -132 95 -129c3 1 61 28 131 60s144 64 166 72c40 15 83 37 79 41c-1 1 -6 0 -11 -3c-24 -13 -80 -2 -98 18c-9 10 -9 9 15 9c97 0 121 145 28 173c-16 5 -18 7 -20 26c-1 11 -4 26 -5 33
+c-5 33 78 59 121 37c19 -10 15 0 -9 21c-37 33 -64 43 -119 43c-70 0 -77 6 -56 49c9 19 10 23 4 24c-10 2 -23 -11 -30 -29c-5 -15 -13 -20 -19 -11c-2 3 1 12 6 20c11 17 12 30 3 30c-8 0 -17 -11 -27 -30c-4 -8 -10 -15 -12 -15c-6 0 -4 18 3 31c4 6 6 16 6 20
+c0 16 -22 -2 -32 -25c-5 -12 -13 -22 -16 -22c-9 0 -7 12 6 37c6 13 10 24 9 25s-2 2 -4 2zM1242 756c-5 0 -5 -16 -5 -59c0 -100 -23 -174 -72 -226c-26 -27 -19 -29 32 -6c106 48 136 192 58 280c-6 7 -10 11 -13 11zM982 689c3 0 6 -3 10 -8c39 -45 25 -117 -28 -144
+c-24 -12 -28 -11 -37 8c-8 16 -8 16 3 28c16 17 34 55 40 86c4 21 8 30 12 30zM680 537c10 0 20 -8 21 -22c2 -25 -16 -39 -36 -27v0c-11 6 -11 32 1 43c4 4 9 6 14 6zM778 509c10 0 19 -11 19 -28c0 -22 -23 -33 -38 -18c-10 10 -9 27 2 38c6 6 12 8 17 8z" />
+ <glyph glyph-name="digg" unicode="&#xf1a6;" horiz-adv-x="2048"
+d="M328 1254h204v-983h-532v697h328v286zM328 435v369h-123v-369h123zM614 968h205v-697h-205v697zM614 1254h205v-204h-205v204zM901 968h533v-942h-533v163h328v82h-328v697zM1229 435v369h-123v-369h123zM1516 968h532v-942h-532v163h327v82h-327v697zM1843 435v369h-123
+v-369h123z" />
+ <glyph glyph-name="rss" unicode="&#xf09e;" horiz-adv-x="1408"
+d="M384 192c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192zM896 69c1 -18 -5 -35 -17 -48c-12 -14 -29 -21 -47 -21h-135c-33 0 -60 25 -63 58c-29 305 -271 547 -576 576c-33 3 -58 30 -58 63v135c0 18 7 35 21 47c11 11 27 17 43 17h5
+c213 -17 414 -110 565 -262c152 -151 245 -352 262 -565zM1408 67c1 -17 -5 -34 -18 -47c-12 -13 -28 -20 -46 -20h-143c-34 0 -62 26 -64 60c-33 581 -496 1044 -1077 1078c-34 2 -60 30 -60 63v143c0 18 7 34 20 46c12 12 28 18 44 18h3c350 -18 679 -165 927 -414
+c249 -248 396 -577 414 -927z" />
+ <glyph glyph-name="television" unicode="&#xf26c;" horiz-adv-x="1920"
+d="M1792 288v960c0 17 -15 32 -32 32h-1600c-17 0 -32 -15 -32 -32v-960c0 -17 15 -32 32 -32h1600c17 0 32 15 32 32zM1920 1248v-960c0 -88 -72 -160 -160 -160h-736v-128h352c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-832c-18 0 -32 14 -32 32v64
+c0 18 14 32 32 32h352v128h-736c-88 0 -160 72 -160 160v960c0 88 72 160 160 160h1600c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="ffmpeg" unicode="&#xf30f;"
+d="M1158 323v179l-530 -527l-628 53l1010 1100l-167 -10l-730 -810v688l69 83l-169 -10v185l591 50l-325 -379v-161l483 553l774 66l-1134 -1194l149 -8l824 849v-806l-92 -87l234 -14v-223l-731 62z" />
+ <glyph glyph-name="folder-o" unicode="&#xf114;" horiz-adv-x="1664"
+d="M1536 224v704c0 53 -43 96 -96 96h-704c-53 0 -96 43 -96 96v64c0 53 -43 96 -96 96h-320c-53 0 -96 -43 -96 -96v-960c0 -53 43 -96 96 -96h1216c53 0 96 43 96 96zM1664 928v-704c0 -123 -101 -224 -224 -224h-1216c-123 0 -224 101 -224 224v960
+c0 123 101 224 224 224h320c123 0 224 -101 224 -224v-32h672c123 0 224 -101 224 -224z" />
+ <glyph glyph-name="bed" unicode="&#xf236;" horiz-adv-x="2048"
+d="M256 512h1728c35 0 64 -29 64 -64v-448h-256v256h-1536v-256h-256v1216c0 35 29 64 64 64h128c35 0 64 -29 64 -64v-704zM832 832c0 -141 -115 -256 -256 -256s-256 115 -256 256s115 256 256 256s256 -115 256 -256zM2048 576h-1152v384c0 35 29 64 64 64h704
+c212 0 384 -172 384 -384v-64z" />
+ <glyph glyph-name="caret-square-o-down" unicode="&#xf150;"
+d="M1145 861c11 -21 9 -47 -5 -66l-320 -448c-12 -17 -31 -27 -52 -27s-40 10 -52 27l-320 448c-14 19 -16 45 -5 66c11 22 33 35 57 35h640c24 0 46 -13 57 -35zM1280 160v960c0 17 -15 32 -32 32h-960c-17 0 -32 -15 -32 -32v-960c0 -17 15 -32 32 -32h960
+c17 0 32 15 32 32zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="shower" unicode="&#xf2cc;" horiz-adv-x="1920"
+d="M1433 1287c13 -13 13 -33 0 -46l-626 -626c-13 -13 -33 -13 -46 0l-82 82c-13 13 -13 33 0 46l44 44c-97 122 -109 289 -35 422c-46 44 -108 71 -176 71c-141 0 -256 -115 -256 -256v-1280h-256v1280c0 282 230 512 512 512c144 0 274 -60 367 -156
+c126 51 272 32 382 -55l44 44c13 13 33 13 46 0zM1344 1024c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM1600 896c-35 0 -64 29 -64 64s29 64 64 64s64 -29 64 -64s-29 -64 -64 -64zM1856 1024c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64
+s29 64 64 64zM1216 896c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM1408 832c0 35 29 64 64 64s64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64zM1728 896c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM1088 768c35 0 64 -29 64 -64
+s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM1344 640c-35 0 -64 29 -64 64s29 64 64 64s64 -29 64 -64s-29 -64 -64 -64zM1600 768c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM1216 512c-35 0 -64 29 -64 64s29 64 64 64s64 -29 64 -64
+s-29 -64 -64 -64zM1472 640c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM1088 512c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM1344 512c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM1216 384
+c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM1088 256c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64z" />
+ <glyph glyph-name="paper-plane-o" unicode="&#xf1d9;" horiz-adv-x="1792"
+d="M1764 1525c21 -15 31 -39 27 -64l-256 -1536c-3 -19 -15 -35 -32 -45c-9 -5 -20 -8 -31 -8c-8 0 -16 2 -24 5l-527 215l-298 -327c-12 -14 -29 -21 -47 -21c-8 0 -16 1 -23 4c-25 10 -41 34 -41 60v452l-472 193c-23 9 -38 30 -40 55c-2 24 11 47 32 59l1664 960
+c21 13 48 12 68 -2zM1422 26l221 1323l-1434 -827l336 -137l863 639l-478 -797z" />
+ <glyph glyph-name="circle-o-notch" unicode="&#xf1ce;" horiz-adv-x="1728"
+d="M1728 640c0 -477 -387 -864 -864 -864s-864 387 -864 864c0 434 320 793 736 855v-228c-292 -59 -512 -318 -512 -627c0 -353 287 -640 640 -640s640 287 640 640c0 309 -220 568 -512 627v228c416 -62 736 -421 736 -855z" />
+ <glyph glyph-name="gnupg" unicode="&#xf30d;" horiz-adv-x="1156"
+d="M0 667h81v244c0 274 223 497 497 497s497 -223 497 -497v-242c-1 -1 -3 -1 -4 -2v0l-1 -1v0v0v0h-1v-1v0v0v0h-1v0v0v-1v0h-1v0v0v0l-1 -1v0v0h-1v0l-1 -1v0v0v0v0l-1 -1v0v0v0h-1v0v0v0l-1 -1v0v0v0v0v0h-1v0v-1v0v0v0v0h-1v0v0v0l-2 -1v0v0l-1 -1v0h-1v0v-1v0v0v0h-1v0
+v0v0v0h-1v-1h-1l-1 -1h-1v-1l-2 -1h-1l-1 -1v0l-3 -1l-1 -1l-1 -1h-1l-1 -1l-1 -1h-1l-4 -2v0l-1 -1h-1v-1h-2l-3 -2l-1 -1c-1 -1 -3 -1 -4 -2h-1v0l-2 -2h-1h-1l-1 -1v0l-2 -1v0l-2 -1h-1l-1 -1c-1 -1 -3 -1 -4 -2l-1 -1c-2 -1 -3 -1 -5 -2v0l-4 -2l-2 -1
+c-2 -1 -3 -2 -5 -3v0c-99 -47 -257 -97 -557 -119c-215 -15 -346 -110 -431 -224v390v0zM310 667h536v244c0 148 -120 268 -268 268s-268 -120 -268 -268v-244zM1004 628c-1 -1 -4 -1 -5 -2zM803 1288c-64 38 -138 60 -218 60c-218 0 -398 -164 -422 -376
+c64 200 251 345 472 345c59 0 116 -10 168 -29v0zM1156 573v-701h-989c109 61 190 54 325 50c183 -6 385 71 485 173s-9 24 -122 -5s-330 -31 -476 7c459 -6 637 142 739 275s-44 24 -138 -22s-258 -79 -439 -55c273 1 482 137 615 278v0z" />
+ <glyph glyph-name="medkit" unicode="&#xf0fa;" horiz-adv-x="1792"
+d="M1280 416v192c0 18 -14 32 -32 32h-224v224c0 18 -14 32 -32 32h-192c-18 0 -32 -14 -32 -32v-224h-224c-18 0 -32 -14 -32 -32v-192c0 -18 14 -32 32 -32h224v-224c0 -18 14 -32 32 -32h192c18 0 32 14 32 32v224h224c18 0 32 14 32 32zM640 1152h512v128h-512v-128z
+M256 1152v-1280h-32c-123 0 -224 101 -224 224v832c0 123 101 224 224 224h32zM1440 1152v-1280h-1088v1280h160v160c0 53 43 96 96 96h576c53 0 96 -43 96 -96v-160h160zM1792 928v-832c0 -123 -101 -224 -224 -224h-32v1280h32c123 0 224 -101 224 -224z" />
+ <glyph glyph-name="toggle-off" unicode="&#xf204;" horiz-adv-x="2048"
+d="M1152 640c0 282 -230 512 -512 512s-512 -230 -512 -512s230 -512 512 -512s512 230 512 512zM1920 640c0 282 -230 512 -512 512h-386c156 -117 258 -303 258 -512s-102 -395 -258 -512h386c282 0 512 230 512 512zM2048 640c0 -353 -287 -640 -640 -640h-768
+c-353 0 -640 287 -640 640s287 640 640 640h768c353 0 640 -287 640 -640z" />
+ <glyph glyph-name="calendar-minus-o" unicode="&#xf272;" horiz-adv-x="1664"
+d="M1152 416v-64c0 -18 -14 -32 -32 -32h-576c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h576c18 0 32 -14 32 -32zM128 -128h1408v1024h-1408v-1024zM512 1088v288c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-288c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM1280 1088
+v288c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-288c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM1664 1152v-1280c0 -70 -58 -128 -128 -128h-1408c-70 0 -128 58 -128 128v1280c0 70 58 128 128 128h128v96c0 88 72 160 160 160h64c88 0 160 -72 160 -160v-96h384v96
+c0 88 72 160 160 160h64c88 0 160 -72 160 -160v-96h128c70 0 128 -58 128 -128z" />
+ <glyph glyph-name="id-badge" unicode="&#xf2c1;" horiz-adv-x="1280"
+d="M1024 278c0 -86 -57 -150 -128 -150h-512c-71 0 -128 64 -128 150c0 156 39 329 196 329c49 -46 115 -75 188 -75s139 29 188 75c157 0 196 -173 196 -329zM870 797c0 -126 -103 -227 -230 -227s-230 101 -230 227c0 125 103 227 230 227s230 -102 230 -227zM1152 -96
+v1376h-1024v-1376c0 -17 15 -32 32 -32h960c17 0 32 15 32 32zM1280 1376v-1472c0 -88 -72 -160 -160 -160h-960c-88 0 -160 72 -160 160v1472c0 88 72 160 160 160h352v-96c0 -18 14 -32 32 -32h192c18 0 32 14 32 32v96h352c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="tencent-weibo" unicode="&#xf1d5;" horiz-adv-x="1166"
+d="M785 964c0 -106 -87 -193 -193 -193c-41 0 -79 13 -111 35c-36 -39 -76 -88 -115 -146c-163 -245 -232 -534 -202 -859c2 -29 -19 -54 -47 -57h-5c-26 0 -49 20 -52 47c-39 438 100 748 223 931c45 67 90 121 132 165c-11 24 -16 50 -16 77c0 107 86 193 193 193
+c106 0 193 -86 193 -193zM1166 953c0 -321 -261 -582 -583 -582c-44 0 -88 5 -131 14c-28 7 -45 35 -39 63c7 27 34 45 62 39c35 -9 72 -13 108 -13c264 0 479 215 479 479s-215 479 -479 479s-479 -215 -479 -479c0 -77 18 -150 52 -218c13 -26 3 -57 -22 -70
+c-26 -13 -57 -3 -70 23c-42 81 -64 173 -64 265c0 322 262 583 583 583c322 0 583 -261 583 -583z" />
+ <glyph glyph-name="file-archive-o" unicode="&#xf1c6;"
+d="M640 1152h-128v128h128v-128zM768 1024h-128v128h128v-128zM640 896h-128v128h128v-128zM768 768h-128v128h128v-128zM1468 1156c37 -37 68 -111 68 -164v-1152c0 -53 -43 -96 -96 -96h-1344c-53 0 -96 43 -96 96v1600c0 53 43 96 96 96h896c53 0 127 -31 164 -68z
+M1024 1400v-376h376c-6 17 -15 34 -22 41l-313 313c-7 7 -24 16 -41 22zM1408 -128v1024h-416c-53 0 -96 43 -96 96v416h-128v-128h-128v128h-512v-1536h1280zM781 593c85 -287 107 -349 107 -349c5 -17 8 -34 8 -52c0 -111 -108 -192 -256 -192s-256 81 -256 192
+c0 18 3 35 8 52c0 0 21 62 120 396v128h128v-128h79c29 0 54 -19 62 -47zM640 128c71 0 128 29 128 64s-57 64 -128 64s-128 -29 -128 -64s57 -64 128 -64z" />
+ <glyph glyph-name="yoast" unicode="&#xf2b1;" horiz-adv-x="1664"
+d="M339 1318h691l-26 -72h-665c-147 0 -267 -121 -267 -268v-771c0 -126 90 -237 214 -263c32 -7 65 -5 98 -5v-72h-45c-187 0 -339 153 -339 340v771c0 187 152 340 339 340zM1190 1536h247l-482 -1294c-90 -240 -199 -490 -495 -498v195c111 18 182 79 220 182
+c13 34 20 69 20 105s-7 72 -20 106l-285 733h228l187 -585zM1664 978v-1111h-795c16 24 33 47 45 73h678v1038c0 114 -72 216 -179 254l25 67c136 -46 226 -178 226 -321z" />
+ <glyph glyph-name="share-alt-square" unicode="&#xf1e1;"
+d="M1280 341c0 118 -96 214 -213 214c-56 0 -107 -22 -145 -58l-241 120c1 8 2 15 2 23s-1 15 -2 23l241 120c38 -36 89 -58 145 -58c117 0 213 96 213 214c0 117 -96 213 -213 213c-118 0 -214 -96 -214 -213c0 -8 1 -15 2 -23l-241 -120c-38 35 -89 57 -145 57
+c-117 0 -213 -95 -213 -213s96 -213 213 -213c56 0 107 22 145 57l241 -120c-1 -8 -2 -15 -2 -23c0 -117 96 -213 214 -213c117 0 213 96 213 213zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960
+c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="imdb" unicode="&#xf2d8;"
+d="M922 739v-182c0 -36 7 -69 -38 -68v309c44 0 38 -23 38 -59zM1238 643v-121c0 -20 6 -53 -23 -53c-6 0 -11 3 -14 9c-8 19 -4 163 -4 165c0 14 -4 47 18 47c27 0 23 -27 23 -47zM180 407h122v472h-122v-472zM614 407h106v472h-159l-28 -221c-10 74 -20 148 -32 221h-158
+v-472h107v312l45 -312h76l43 319v-319zM1039 712c0 30 1 62 -5 90c-16 83 -116 77 -181 77h-91v-472c318 0 277 -22 277 305zM1356 515v133c0 64 -3 111 -82 111c-33 0 -55 -10 -77 -34v154h-117v-472h110l7 30c21 -25 44 -36 77 -36c73 0 82 56 82 114zM1536 1248v-1216
+c0 -88 -72 -160 -160 -160h-1216c-88 0 -160 72 -160 160v1216c0 88 72 160 160 160h1216c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="snapchat-square" unicode="&#xf2ad;"
+d="M1280 388c0 14 -8 24 -22 27c-91 19 -160 83 -198 167c-4 8 -7 16 -7 25c0 45 124 36 124 100c0 27 -33 44 -57 44c-22 0 -40 -16 -63 -16c-4 0 -8 1 -12 2c3 38 5 77 5 115c0 34 -2 82 -17 114c-48 104 -140 165 -255 165c-125 0 -220 -47 -275 -165
+c-15 -32 -18 -80 -18 -115c0 -38 3 -76 6 -114c-5 -1 -10 -2 -15 -2c-22 0 -41 16 -62 16c-25 0 -55 -17 -55 -45c0 -62 124 -54 124 -99c0 -9 -3 -17 -7 -25c-39 -84 -106 -147 -198 -167c-14 -3 -22 -13 -22 -27c0 -47 106 -64 138 -69c9 -24 5 -66 40 -66
+c26 0 51 10 77 10c106 0 134 -95 256 -95c127 0 151 95 258 95c26 0 52 -9 78 -9c34 0 31 42 39 65c32 5 138 22 138 69zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="spell-check" unicode="&#xf327;" horiz-adv-x="2049"
+d="M2049 700c0 -25 -10 -50 -28 -68l-724 -724l-136 -136c-18 -18 -43 -28 -68 -28s-50 10 -68 28l-136 136l-362 362c-18 18 -28 43 -28 68s10 50 28 68l136 136c18 18 43 28 68 28s50 -10 68 -28l294 -295l656 657c18 18 43 28 68 28s50 -10 68 -28l136 -136
+c18 -18 28 -43 28 -68zM0 880v73h48l158 454h111l158 -454h49v-73h-199v73h52l-32 98h-167l-32 -98h52v-73h-198zM200 1127h122l-49 149c-2 8 -5 16 -6 23c-1 8 -3 15 -3 18l-1 5h-2c-1 -13 -5 -29 -10 -46zM569 880v73h63v381h-63v73h242c40 0 72 -5 95 -14
+c24 -9 44 -25 58 -47c15 -21 22 -46 22 -75c0 -25 -6 -47 -17 -67s-28 -35 -48 -46v-1c28 -8 50 -24 64 -47s22 -49 22 -78c0 -35 -10 -65 -30 -91s-45 -43 -75 -52c-21 -6 -47 -9 -79 -9h-254zM730 1192h92c20 0 37 6 48 18c11 13 17 30 17 51c0 29 -10 49 -30 60
+c-11 5 -27 8 -46 8h-81v-137zM730 958h98c15 0 27 2 37 6c13 5 25 15 32 28c7 14 11 29 11 46c0 23 -7 41 -21 55c-13 14 -32 22 -56 22h-101v-157zM1131 950c-52 53 -78 118 -78 196s26 142 78 193s116 77 193 77c18 0 39 -2 60 -5c22 -3 44 -9 67 -16s41 -18 56 -33
+s23 -32 23 -51v-72h-88v41c0 12 -7 23 -20 31s-29 14 -45 17s-32 5 -48 5c-51 0 -94 -17 -127 -51c-33 -33 -49 -77 -49 -132c0 -59 17 -106 51 -142s78 -54 130 -54c14 0 29 2 45 4s31 8 46 16s23 19 23 32v41h89v-72c0 -18 -7 -35 -22 -49c-14 -14 -33 -26 -56 -33
+c-22 -7 -45 -13 -67 -16c-22 -4 -44 -6 -64 -6c-79 0 -145 27 -197 79v0z" />
+ <glyph glyph-name="building-o" unicode="&#xf0f7;" horiz-adv-x="1408"
+d="M384 224v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM384 480v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM640 480v-64c0 -17 -15 -32 -32 -32h-64
+c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM384 736v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM1152 224v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64
+c17 0 32 -15 32 -32zM896 480v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM640 736v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM384 992v-64
+c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM1152 480v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM896 736v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64
+c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM640 992v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM384 1248v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM1152 736
+v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM896 992v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM640 1248v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32
+v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM1152 992v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM896 1248v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32z
+M1152 1248v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM896 -128h384v1536h-1152v-1536h384v224c0 17 15 32 32 32h320c17 0 32 -15 32 -32v-224zM1408 1472v-1664c0 -35 -29 -64 -64 -64h-1280c-35 0 -64 29 -64 64
+v1664c0 35 29 64 64 64h1280c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="sort-alpha-desc" unicode="&#xf15e;" horiz-adv-x="1629"
+d="M1159 104h177l-72 218l-12 47c-1 8 -2 14 -2 20h-4l-3 -20c-3 -12 -4 -27 -11 -47zM704 96c0 -9 -4 -17 -10 -24l-319 -319c-7 -6 -15 -9 -23 -9s-16 3 -23 9l-320 320c-9 10 -12 23 -7 35s17 20 30 20h192v1376c0 18 14 32 32 32h192c18 0 32 -14 32 -32v-1376h192
+c18 0 32 -14 32 -32zM1629 -150v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162l230 -662h70zM1540 1001v-233h-584v90l369 529c8 12 16 22 21 27l11 9v3c-4 0 -8 -1 -14 -1c-8 -2 -18 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530
+c-6 -9 -14 -18 -21 -26l-11 -10v-3l14 3c9 1 18 1 30 1h248v119h121z" />
+ <glyph glyph-name="map-signs" unicode="&#xf277;" horiz-adv-x="1718"
+d="M1708 1239c13 -13 13 -33 0 -46l-141 -141c-18 -18 -43 -28 -68 -28h-1344c-35 0 -64 29 -64 64v256c0 35 29 64 64 64h576v64c0 35 29 64 64 64h128c35 0 64 -29 64 -64v-64h512c25 0 50 -10 68 -28zM731 320h256v-512c0 -35 -29 -64 -64 -64h-128c-35 0 -64 29 -64 64
+v512zM1563 768c35 0 64 -29 64 -64v-256c0 -35 -29 -64 -64 -64h-1344c-25 0 -50 10 -68 28l-141 141c-13 13 -13 33 0 46l141 141c18 18 43 28 68 28h512v192h256v-192h576z" />
+ <glyph glyph-name="long-arrow-right" unicode="&#xf178;" horiz-adv-x="1728"
+d="M1728 643c0 -9 -4 -18 -10 -24l-384 -354c-10 -9 -23 -11 -35 -6c-11 5 -19 16 -19 29v224h-1248c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h1248v224c0 13 7 24 19 29s25 3 35 -5l384 -350c6 -6 10 -14 10 -23z" />
+ <glyph glyph-name="first-order" unicode="&#xf2b0;"
+d="M1322 640c0 -26 -1 -51 -5 -76l-236 14l224 -78c-13 -51 -33 -98 -58 -141l-214 103l177 -158c-30 -41 -66 -77 -107 -108l-157 178l103 -215c-43 -26 -90 -45 -140 -59l-79 228l14 -240c-25 -4 -50 -6 -76 -6c-25 0 -51 2 -76 6l14 238l-78 -226c-50 13 -97 33 -140 59
+l103 215l-157 -178c-41 30 -77 67 -108 108l178 158l-214 -104c-25 44 -45 91 -58 141l224 79l-237 -14c-3 25 -5 50 -5 76s2 52 5 77l238 -14l-225 79c13 50 33 97 58 140l214 -104l-177 159c31 41 67 77 107 108l158 -178l-103 215c43 25 90 45 140 58l77 -224l-13 236
+c24 4 50 6 75 6c26 0 51 -2 76 -6l-14 -237l78 225c50 -13 97 -33 140 -59l-103 -214l158 178c40 -31 76 -67 107 -108l-177 -159l213 104c26 -43 45 -91 58 -141l-224 -78l237 14c4 -25 5 -51 5 -77zM1352 640c0 325 -262 588 -584 588c-323 0 -584 -263 -584 -588
+c0 -324 261 -587 584 -587c322 0 584 263 584 587zM1425 1023v-766l-657 -383l-657 383v766l657 383zM768 -183l708 412v823l-708 411l-708 -411v-823zM1536 1088v-896l-768 -448l-768 448v896l768 448z" />
+ <glyph glyph-name="calendar-check-o" unicode="&#xf274;" horiz-adv-x="1664"
+d="M1303 572l-512 -512c-13 -12 -33 -12 -46 0l-288 288c-12 13 -12 33 0 45l46 46c12 12 32 12 45 0l220 -220l444 444c13 12 33 12 45 0l46 -46c12 -12 12 -32 0 -45zM128 -128h1408v1024h-1408v-1024zM512 1088v288c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-288
+c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM1280 1088v288c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-288c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM1664 1152v-1280c0 -70 -58 -128 -128 -128h-1408c-70 0 -128 58 -128 128v1280c0 70 58 128 128 128h128v96
+c0 88 72 160 160 160h64c88 0 160 -72 160 -160v-96h384v96c0 88 72 160 160 160h64c88 0 160 -72 160 -160v-96h128c70 0 128 -58 128 -128z" />
+ <glyph glyph-name="id-card" unicode="&#xf2c2;" horiz-adv-x="2048"
+d="M896 324c0 132 -32 284 -164 284c-40 -40 -95 -64 -156 -64s-116 24 -156 64c-132 0 -164 -152 -164 -284c0 -73 48 -132 107 -132h426c59 0 107 59 107 132zM768 768c0 106 -86 192 -192 192s-192 -86 -192 -192s86 -192 192 -192s192 86 192 192zM1792 288v64
+c0 18 -14 32 -32 32h-704c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h704c18 0 32 14 32 32zM1408 544v64c0 18 -14 32 -32 32h-320c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h320c18 0 32 14 32 32zM1792 544v64c0 18 -14 32 -32 32h-192c-18 0 -32 -14 -32 -32
+v-64c0 -18 14 -32 32 -32h192c18 0 32 14 32 32zM1792 800v64c0 18 -14 32 -32 32h-704c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h704c18 0 32 14 32 32zM128 1152h1792v96c0 18 -14 32 -32 32h-1728c-18 0 -32 -14 -32 -32v-96zM2048 1248v-1216
+c0 -88 -72 -160 -160 -160h-1728c-88 0 -160 72 -160 160v1216c0 88 72 160 160 160h1728c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="globe-w" unicode="&#xf305;"
+d="M768 1404c424 0 768 -344 768 -768s-344 -768 -768 -768s-768 344 -768 768s344 768 768 768zM924 1238v0c-3 0 -6 -1 -7 -1c-2 0 -153 -25 -208 -34s-156 -30 -201 -34s-46 0 -69 0c-7 0 -14 1 -21 2c-65 -43 -152 -132 -193 -198c0 -4 2 -7 6 -11c12 -12 46 0 69 0
+s59 8 69 0s1 -7 2 -9s-16 -108 -7 -144s10 -88 33 -129s110 -63 145 -98s106 -34 112 -71s-30 -79 -42 -102s-40 -40 -35 -69s46 -47 69 -70s47 -29 69 -69s25 -125 35 -173c2 -9 5 -22 7 -31c3 0 8 -1 11 -1c57 0 146 15 200 33c6 41 13 83 24 103c18 33 24 24 36 36
+s23 18 35 35s23 46 34 68s38 38 33 67s-47 47 -70 70s-35 50 -69 69s-94 24 -130 33s-163 15 -165 16s0 -8 -8 2s-3 50 -3 73s13 44 30 85c17 23 7 12 33 31c13 12 55 -57 73 -57s-4 117 7 128c46 46 163 125 163 174s-46 46 -69 69s-60 -39 -143 -39s97 131 109 143
+s30 22 35 35s0 23 0 34s14 28 9 32c-2 2 -5 2 -8 2zM1041 1214v0c-6 -14 -7 -31 -14 -45c-12 -23 -35 -43 -35 -69s23 -46 35 -69s1 -60 34 -69s69 46 104 69c21 14 50 26 72 40c-46 50 -134 114 -196 143z" />
+ <glyph glyph-name="github-alt" unicode="&#xf113;" horiz-adv-x="1664"
+d="M640 320c0 -73 -38 -192 -128 -192s-128 119 -128 192s38 192 128 192s128 -119 128 -192zM1280 320c0 -73 -38 -192 -128 -192s-128 119 -128 192s38 192 128 192s128 -119 128 -192zM1440 320c0 153 -93 288 -256 288c-66 0 -129 -12 -195 -21
+c-52 -8 -104 -11 -157 -11s-105 3 -157 11c-65 9 -129 21 -195 21c-163 0 -256 -135 -256 -288c0 -306 280 -353 524 -353h168c244 0 524 47 524 353zM1664 496c0 -111 -11 -229 -61 -331c-132 -267 -495 -293 -755 -293c-264 0 -649 23 -786 293c-51 101 -62 220 -62 331
+c0 146 40 284 136 396c-18 55 -27 113 -27 170c0 75 17 150 51 218c158 0 259 -69 379 -163c101 24 205 35 309 35c94 0 189 -10 280 -32c119 93 220 160 376 160c34 -68 51 -143 51 -218c0 -57 -9 -114 -27 -168c96 -113 136 -252 136 -398z" />
+ <glyph glyph-name="sign-language" unicode="&#xf2a7;" horiz-adv-x="1664"
+d="M831 863c21 0 41 -6 59 -18l222 -148c41 -27 78 -60 110 -97l146 -170c25 -29 36 -68 29 -106l-72 -413c-8 -42 -42 -74 -85 -79l-527 -56l-352 -32h-9c-52 0 -96 42 -96 96c0 50 42 90 92 96l260 32h-448c-55 0 -99 46 -96 101c3 52 49 91 101 91l442 1l-521 64
+c-54 6 -93 55 -85 110c8 48 52 80 100 80h10l481 -60l-351 94c-50 13 -88 59 -80 110c8 48 49 81 95 81c7 0 13 -1 20 -2l448 -96l217 -37c2 0 4 -1 6 -1c30 0 45 41 18 59l-186 125c-46 31 -57 93 -24 137c18 25 47 38 76 38zM761 661l186 -125l-218 37l-5 2l-36 38
+l-238 262c-2 2 -3 5 -5 7c-31 41 -24 101 19 134c40 31 97 21 132 -16l142 -147c-3 -3 -6 -5 -9 -8c-21 -29 -29 -64 -23 -99c6 -34 26 -65 55 -85zM1648 1115l15 -266c3 -49 -1 -99 -11 -147l-48 -219c-8 -38 -32 -69 -67 -87l-106 -54c1 40 -12 78 -39 109l-146 170
+c-34 39 -73 74 -117 103l-222 148c-22 15 -48 23 -76 23c-34 0 -65 -14 -88 -37l-235 312c-33 44 -23 106 23 137c43 30 102 16 134 -26l266 -352l-262 455c-28 47 -12 108 37 134c46 24 104 5 130 -40l241 -420l-136 337c-19 48 -6 106 40 130c49 26 109 5 132 -45
+l193 -415l101 -196c16 -31 63 -18 61 16l-12 224c-3 55 40 101 95 102c52 0 94 -44 97 -96z" />
+ <glyph glyph-name="play" unicode="&#xf04b;" horiz-adv-x="1407"
+d="M1384 609l-1328 -738c-31 -17 -56 -2 -56 33v1472c0 35 25 50 56 33l1328 -738c31 -17 31 -45 0 -62z" />
+ <glyph glyph-name="heart-o" unicode="&#xf08a;" horiz-adv-x="1792"
+d="M1664 940c0 281 -190 340 -350 340c-149 0 -317 -161 -369 -223c-24 -29 -74 -29 -98 0c-52 62 -220 223 -369 223c-160 0 -350 -59 -350 -340c0 -183 185 -353 187 -355l581 -560l580 559c3 3 188 173 188 356zM1792 940c0 -240 -220 -441 -229 -450l-623 -600
+c-12 -12 -28 -18 -44 -18s-32 6 -44 18l-624 602c-8 7 -228 208 -228 448c0 293 179 468 478 468c175 0 339 -138 418 -216c79 78 243 216 418 216c299 0 478 -175 478 -468z" />
+ <glyph glyph-name="weibo" unicode="&#xf18a;" horiz-adv-x="1792"
+d="M675 252c28 46 13 99 -34 119c-45 19 -105 -1 -133 -45c-29 -45 -15 -98 30 -119c46 -21 108 -1 137 45zM769 373c10 18 4 38 -14 45c-18 6 -40 -2 -50 -19c-10 -18 -5 -37 13 -45c18 -7 41 1 51 19zM943 266c-60 -136 -234 -210 -382 -162c-143 46 -203 187 -141 314
+c62 124 221 194 362 158c147 -38 221 -176 161 -310zM1255 426c-19 195 -275 329 -572 300c-297 -30 -521 -211 -502 -406s275 -329 572 -300c297 30 521 211 502 406zM1563 422c0 -225 -324 -508 -811 -508c-372 0 -752 180 -752 477c0 155 98 334 267 503
+c226 226 489 328 588 229c44 -43 48 -119 20 -209c-14 -46 43 -20 43 -21c182 77 341 81 399 -2c31 -44 28 -106 0 -178c-13 -33 4 -38 29 -46c103 -32 217 -109 217 -245zM1489 1046c57 -63 73 -150 48 -226c-10 -31 -43 -48 -74 -38s-48 43 -38 74c12 38 4 80 -24 111
+s-69 43 -107 35c-32 -7 -64 13 -70 45c-7 32 13 63 45 70c78 17 163 -7 220 -71zM1670 1209c118 -130 149 -308 99 -464c-12 -36 -50 -56 -86 -44s-56 50 -45 86c36 111 14 238 -70 330c-84 93 -207 128 -321 104c-37 -8 -74 16 -82 53s16 73 53 81c161 34 334 -15 452 -146
+z" />
+ <glyph glyph-name="angle-down" unicode="&#xf107;" horiz-adv-x="998"
+d="M998 800c0 -8 -4 -17 -10 -23l-466 -466c-6 -6 -15 -10 -23 -10s-17 4 -23 10l-466 466c-6 6 -10 15 -10 23s4 17 10 23l50 50c6 6 14 10 23 10c8 0 17 -4 23 -10l393 -393l393 393c6 6 15 10 23 10s17 -4 23 -10l50 -50c6 -6 10 -15 10 -23z" />
+ <glyph glyph-name="cc-jcb" unicode="&#xf24b;" horiz-adv-x="2304"
+d="M1951 538c0 -36 -24 -62 -54 -68c-4 -1 -13 -2 -18 -2h-153v140h153c5 0 14 -1 18 -2c30 -6 54 -33 54 -68zM1933 751c0 -35 -24 -58 -53 -63c-3 -1 -10 -1 -15 -1h-139v129h139c5 0 12 -1 15 -1c29 -5 53 -29 53 -64zM728 587v308h-228v-308c0 -75 -51 -131 -143 -131
+c-78 0 -155 23 -229 59v-112c120 -33 272 -33 272 -33c254 0 328 97 328 217zM1442 403v113c-52 -27 -118 -53 -200 -59c-144 -11 -230 59 -230 183s86 194 230 183c82 -6 147 -31 200 -58v112c-107 27 -208 31 -208 31c-352 16 -452 -123 -452 -268s100 -284 452 -268
+c0 0 101 4 208 31zM2176 518c0 74 -66 122 -152 128v3c78 11 121 62 121 121c0 76 -63 120 -148 124c-6 0 -17 1 -26 1h-455v-510h491c97 0 169 52 169 133zM2304 1280v-1280c0 -70 -58 -128 -128 -128h-2048c-70 0 -128 58 -128 128v1280c0 70 58 128 128 128h2048
+c70 0 128 -58 128 -128z" />
+ <glyph glyph-name="compress" unicode="&#xf066;" horiz-adv-x="1510"
+d="M755 576v-448c0 -35 -29 -64 -64 -64c-17 0 -33 7 -45 19l-144 144l-332 -332c-6 -6 -15 -10 -23 -10s-17 4 -23 10l-114 114c-6 6 -10 15 -10 23s4 17 10 23l332 332l-144 144c-12 12 -19 28 -19 45c0 35 29 64 64 64h448c35 0 64 -29 64 -64zM1510 1248
+c0 -8 -4 -17 -10 -23l-332 -332l144 -144c12 -12 19 -28 19 -45c0 -35 -29 -64 -64 -64h-448c-35 0 -64 29 -64 64v448c0 35 29 64 64 64c17 0 33 -7 45 -19l144 -144l332 332c6 6 15 10 23 10s17 -4 23 -10l114 -114c6 -6 10 -15 10 -23z" />
+ <glyph glyph-name="pencil-square-o" unicode="&#xf044;" horiz-adv-x="1784"
+d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072c-9 9 -24 8 -33 -1l-350 -350c-9 -9 -10 -24 -1 -33s24 -8 33 1l350 350c9 9 10 24 1 33zM1408 478v-190c0 -159 -129 -288 -288 -288h-832c-159 0 -288 129 -288 288v832c0 159 129 288 288 288h832
+c40 0 80 -8 117 -25c9 -4 16 -13 18 -23c2 -11 -1 -21 -9 -29l-49 -49c-9 -9 -21 -12 -32 -8c-15 4 -30 6 -45 6h-832c-88 0 -160 -72 -160 -160v-832c0 -88 72 -160 160 -160h832c88 0 160 72 160 160v126c0 8 3 16 9 22l64 64c10 10 23 12 35 7s20 -16 20 -29zM1312 1216
+l288 -288l-672 -672h-288v288zM1756 1084l-92 -92l-288 288l92 92c37 37 99 37 136 0l152 -152c37 -37 37 -99 0 -136z" />
+ <glyph glyph-name="google-plus-square" unicode="&#xf0d4;"
+d="M917 631c0 25 -3 45 -6 64h-362v-132h217c-8 -56 -65 -165 -217 -165c-132 0 -239 108 -239 242s107 242 239 242c74 0 124 -31 153 -59l104 101c-67 62 -154 100 -257 100c-213 0 -384 -172 -384 -384s171 -384 384 -384c221 0 368 156 368 375zM1262 585h109v110h-109
+v110h-110v-110h-110v-110h110v-110h110v110zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="keybase" unicode="&#xf2f4;" horiz-adv-x="1547"
+d="M146 -80c-13 28 -30 67 -39 87l-13 38l-44 -49l-44 -48l-4 92c-7 131 4 267 26 363c50 214 208 408 411 511l45 21l-10 33c-7 17 -14 55 -16 79l-4 46l-46 4c-70 7 -107 26 -131 76c-13 26 -13 31 -9 101c4 92 12 111 40 142c35 39 59 45 146 41c63 -4 77 -6 105 -19
+c17 -9 33 -18 35 -18s22 24 46 57l41 59l26 -15c15 -9 33 -20 42 -24l15 -9l-13 -33c-7 -17 -16 -48 -18 -63l-4 -31l37 -4c133 -13 234 -94 271 -216c11 -39 11 -116 0 -153c-11 -35 -11 -37 -2 -37c15 0 118 -51 159 -77c81 -52 175 -143 227 -222
+c98 -146 140 -306 123 -481c-9 -105 -29 -187 -64 -268l-13 -31h-109l26 52c28 57 50 136 61 206c7 48 10 179 3 203l-5 15l-28 -31c-70 -76 -172 -98 -310 -61c-118 31 -167 37 -278 37c-85 0 -113 -2 -159 -13c-127 -28 -217 -69 -341 -159c-46 -33 -83 -59 -85 -59
+s4 22 13 50s24 74 33 105l17 55l-19 -20c-11 -11 -42 -42 -68 -70l-46 -50l11 -42c13 -55 44 -122 77 -172c13 -22 24 -40 24 -42s-26 -2 -57 -2h-57zM338 449c105 111 190 200 192 200c2 -2 -8 -35 -19 -72c-72 -227 -87 -271 -85 -273c0 0 26 9 54 20
+c186 81 402 92 631 31c103 -26 142 -26 192 0c28 15 40 23 53 45c24 37 26 90 11 138c-37 105 -182 240 -317 299c-70 31 -74 30 -89 15l-14 -13l57 -69c31 -37 64 -79 68 -90c13 -26 15 -68 2 -94c-17 -37 -70 -64 -111 -55c-17 4 -25 3 -42 -10c-48 -35 -100 -26 -144 26
+c-35 39 -44 59 -46 98c0 20 -7 43 -11 52c-7 13 -8 28 -8 48l2 31l-29 7c-39 11 -85 32 -111 52c-13 9 -24 17 -28 17s-33 -13 -64 -28c-212 -109 -349 -312 -371 -541c-2 -22 -4 -51 -6 -62l-3 -19l24 24c11 11 107 112 212 223zM904 610c20 15 37 28 41 28
+c2 0 9 -6 16 -15c11 -17 30 -17 39 -2c7 11 7 13 -122 170c-76 94 -92 110 -103 110c-26 -2 -19 -23 22 -73l39 -48l-22 -17c-24 -22 -26 -26 -11 -39c11 -11 13 -9 35 6l24 15l16 -13c9 -7 13 -17 13 -19c0 -4 -17 -20 -37 -37c-20 -15 -35 -34 -35 -38c0 -7 10 -24 30 -48
+c7 -13 18 -8 55 20zM679 920c13 39 56 70 100 70c24 0 59 -20 83 -46l22 -26l20 24c55 61 61 147 17 221c-33 55 -94 87 -179 96c-46 4 -57 8 -81 32l-17 18l-9 -13c-17 -26 -54 -111 -65 -144c-15 -50 -9 -129 11 -168c20 -37 72 -88 87 -81c2 -2 7 6 11 17zM484 1217
+c4 11 16 39 27 61s19 44 19 51c0 20 -21 28 -80 32c-52 4 -57 3 -68 -8c-9 -9 -13 -20 -13 -35c0 -13 -3 -37 -5 -57c-4 -46 2 -54 48 -61c68 -4 65 -5 72 17zM417 1270c0 37 4 41 35 41h28v-61h-61v20h-2zM554 -4c-13 13 -17 22 -17 44c0 41 24 66 63 66
+c37 0 64 -27 64 -64c0 -39 -25 -61 -66 -63c-22 0 -31 4 -44 17zM976 -10c-50 39 -24 116 39 116c39 0 61 -25 63 -66c0 -24 -2 -31 -17 -44s-22 -17 -44 -17c-20 0 -32 4 -41 11z" />
+ <glyph glyph-name="angle-right" unicode="&#xf105;" horiz-adv-x="582"
+d="M582 576c0 -8 -4 -17 -10 -23l-466 -466c-6 -6 -15 -10 -23 -10s-17 4 -23 10l-50 50c-6 6 -10 14 -10 23c0 8 4 17 10 23l393 393l-393 393c-6 6 -10 15 -10 23s4 17 10 23l50 50c6 6 15 10 23 10s17 -4 23 -10l466 -466c6 -6 10 -15 10 -23z" />
+ <glyph glyph-name="forumbee" unicode="&#xf211;"
+d="M934 1386c-423 -161 -756 -499 -914 -923c-13 58 -20 117 -20 176c0 423 342 766 765 766c57 0 114 -7 169 -19zM1203 1267c62 -43 117 -95 164 -155c-518 -151 -923 -558 -1071 -1077c-59 46 -112 100 -155 162c149 514 549 918 1062 1070zM470 -67
+c154 475 526 849 999 1006c27 -62 45 -128 54 -195c-390 -160 -700 -472 -859 -863c-67 9 -132 26 -194 52zM1536 -125c-124 32 -247 70 -367 115c-88 -55 -187 -92 -290 -107c146 273 371 499 643 646c-14 -100 -49 -198 -101 -284c45 -121 83 -245 115 -370z" />
+ <glyph glyph-name="eject" unicode="&#xf052;" horiz-adv-x="1538"
+d="M14 557l710 710c25 25 65 25 90 0l710 -710c25 -25 16 -45 -19 -45h-1472c-35 0 -44 20 -19 45zM1473 0h-1408c-35 0 -64 29 -64 64v256c0 35 29 64 64 64h1408c35 0 64 -29 64 -64v-256c0 -35 -29 -64 -64 -64z" />
+ <glyph glyph-name="mobile" unicode="&#xf10b;" horiz-adv-x="768"
+d="M464 128c0 44 -36 80 -80 80s-80 -36 -80 -80s36 -80 80 -80s80 36 80 80zM672 288v704c0 17 -15 32 -32 32h-512c-17 0 -32 -15 -32 -32v-704c0 -17 15 -32 32 -32h512c17 0 32 15 32 32zM480 1136c0 9 -7 16 -16 16h-160c-9 0 -16 -7 -16 -16s7 -16 16 -16h160
+c9 0 16 7 16 16zM768 1152v-1024c0 -70 -58 -128 -128 -128h-512c-70 0 -128 58 -128 128v1024c0 70 58 128 128 128h512c70 0 128 -58 128 -128z" />
+ <glyph glyph-name="hourglass-end" unicode="&#xf253;"
+d="M1408 1408c0 -370 -177 -638 -373 -768c196 -130 373 -398 373 -768h96c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-1472c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h96c0 370 177 638 373 768c-196 130 -373 398 -373 768h-96c-18 0 -32 14 -32 32v64
+c0 18 14 32 32 32h1472c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-96zM874 700c202 76 406 343 406 708h-1024c0 -365 204 -632 406 -708c25 -9 42 -33 42 -60s-17 -51 -42 -60c-86 -32 -173 -100 -244 -196h700c-71 96 -158 164 -244 196c-25 9 -42 33 -42 60
+s17 51 42 60z" />
+ <glyph glyph-name="trash-o" unicode="&#xf014;" horiz-adv-x="1408"
+d="M512 800v-576c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v576c0 18 14 32 32 32h64c18 0 32 -14 32 -32zM768 800v-576c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v576c0 18 14 32 32 32h64c18 0 32 -14 32 -32zM1024 800v-576c0 -18 -14 -32 -32 -32h-64
+c-18 0 -32 14 -32 32v576c0 18 14 32 32 32h64c18 0 32 -14 32 -32zM1152 76v948h-896v-948c0 -48 27 -76 32 -76h832c5 0 32 28 32 76zM480 1152h448l-48 117c-3 4 -12 10 -17 11h-317c-6 -1 -14 -7 -17 -11zM1408 1120v-64c0 -18 -14 -32 -32 -32h-96v-948
+c0 -110 -72 -204 -160 -204h-832c-88 0 -160 90 -160 200v952h-96c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h309l70 167c20 49 80 89 133 89h320c53 0 113 -40 133 -89l70 -167h309c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="star-o" unicode="&#xf006;" horiz-adv-x="1664"
+d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889c0 -18 -13 -35 -26 -48l-363 -354l86 -500c1 -7 1 -13 1 -20c0 -27 -12 -50 -41 -50c-14 0 -28 5 -40 12l-449 236l-449 -236c-13 -7 -26 -12 -40 -12
+c-29 0 -42 24 -42 50c0 7 1 13 2 20l86 500l-364 354c-12 13 -25 30 -25 48c0 30 31 42 56 46l502 73l225 455c9 19 26 41 49 41s40 -22 49 -41l225 -455l502 -73c24 -4 56 -16 56 -46z" />
+ <glyph glyph-name="floppy-o" unicode="&#xf0c7;"
+d="M384 0h768v384h-768v-384zM1280 0h128v896c0 19 -17 60 -30 73l-281 281c-14 14 -53 30 -73 30v-416c0 -53 -43 -96 -96 -96h-576c-53 0 -96 43 -96 96v416h-128v-1280h128v416c0 53 43 96 96 96h832c53 0 96 -43 96 -96v-416zM896 928v320c0 17 -15 32 -32 32h-192
+c-17 0 -32 -15 -32 -32v-320c0 -17 15 -32 32 -32h192c17 0 32 15 32 32zM1536 896v-928c0 -53 -43 -96 -96 -96h-1344c-53 0 -96 43 -96 96v1344c0 53 43 96 96 96h928c53 0 126 -30 164 -68l280 -280c38 -38 68 -111 68 -164z" />
+ <glyph glyph-name="file-powerpoint-o" unicode="&#xf1c4;"
+d="M1468 1156c37 -37 68 -111 68 -164v-1152c0 -53 -43 -96 -96 -96h-1344c-53 0 -96 43 -96 96v1600c0 53 43 96 96 96h896c53 0 127 -31 164 -68zM1024 1400v-376h376c-6 17 -15 34 -22 41l-313 313c-7 7 -24 16 -41 22zM1408 -128v1024h-416c-53 0 -96 43 -96 96v416
+h-768v-1536h1280zM416 106h92v555h-92v107h368c46 0 92 -4 130 -19c83 -35 137 -119 137 -228s-56 -202 -146 -233c-36 -13 -75 -15 -118 -15h-137v-167h93v-106h-327v106zM769 386c31 0 57 5 78 15c42 21 62 64 62 120c0 53 -20 94 -56 115c-21 12 -48 18 -83 18h-120v-268
+h119z" />
+ <glyph glyph-name="cc-discover" unicode="&#xf1f2;" horiz-adv-x="2304"
+d="M313 759c0 -32 -13 -63 -36 -84c-20 -18 -47 -26 -89 -26h-17v220h17c42 0 68 -7 89 -27c23 -20 36 -51 36 -83zM2089 824c0 -34 -22 -52 -64 -52h-19v101h20c41 0 63 -17 63 -49zM380 759c0 98 -73 167 -179 167h-95v-333h95c50 0 87 11 119 38c38 32 60 79 60 128z
+M410 593h65v333h-65v-333zM730 694c0 53 -22 77 -96 104c-39 14 -50 24 -50 42c0 21 20 37 48 37c20 0 36 -8 53 -27l34 44c-28 25 -62 37 -98 37c-59 0 -104 -41 -104 -95c0 -46 21 -70 82 -92c25 -9 38 -14 45 -19c13 -8 19 -20 19 -34c0 -27 -21 -47 -50 -47
+c-31 0 -56 15 -71 44l-42 -40c30 -44 66 -64 115 -64c68 0 115 45 115 110zM1008 604v77c-26 -26 -49 -37 -78 -37c-66 0 -112 48 -112 115c0 64 48 115 109 115c31 0 54 -11 81 -38v77c-28 14 -52 20 -80 20c-98 0 -177 -77 -177 -174c0 -98 77 -174 176 -174
+c28 0 52 5 81 19zM2240 0v527c-160 -100 -723 -420 -1633 -591h1569c35 0 64 29 64 64zM1389 757c0 100 -81 181 -181 181s-181 -81 -181 -181s81 -181 181 -181s181 81 181 181zM1541 584l144 342h-71l-90 -224l-89 224h-71l142 -342h35zM1714 593h184v56h-119v90h115v56
+h-115v74h119v57h-184v-333zM2105 593h80l-105 140c49 10 76 43 76 94c0 63 -43 99 -118 99h-97v-333h65v133h9zM2304 1274v-1268c0 -74 -59 -134 -132 -134h-2040c-73 0 -132 60 -132 134v1268c0 74 59 134 132 134h2040c73 0 132 -60 132 -134z" />
+ <glyph glyph-name="bomb" unicode="&#xf1e2;" horiz-adv-x="1792"
+d="M571 947c-13 33 -50 48 -83 35c-144 -58 -260 -174 -318 -318c-13 -33 2 -70 35 -83c8 -3 16 -5 24 -5c26 0 49 15 60 40c45 112 135 202 247 247c33 14 49 51 35 84zM1513 1303l46 -46l-244 -243l68 -68c25 -25 25 -66 0 -91l-64 -64c56 -101 89 -218 89 -343
+c0 -389 -315 -704 -704 -704s-704 315 -704 704s315 704 704 704c125 0 242 -33 343 -89l64 64c25 25 66 25 91 0l68 -68zM1521 1359c-6 -6 -14 -10 -22 -10c-9 0 -17 4 -23 10l-91 90c-12 13 -12 33 0 46c13 12 33 12 46 0l90 -91c13 -12 13 -33 0 -45zM1751 1129
+c-7 -6 -15 -9 -23 -9s-16 3 -23 9l-90 91c-13 12 -13 33 0 45c12 13 33 13 45 0l91 -90c12 -13 12 -33 0 -46zM1792 1312c0 -18 -14 -32 -32 -32h-96c-18 0 -32 14 -32 32s14 32 32 32h96c18 0 32 -14 32 -32zM1600 1504v-96c0 -18 -14 -32 -32 -32s-32 14 -32 32v96
+c0 18 14 32 32 32s32 -14 32 -32zM1751 1449l-91 -90c-6 -6 -14 -10 -22 -10c-9 0 -17 4 -23 10c-13 12 -13 33 0 45l90 91c13 12 33 12 46 0c12 -13 12 -33 0 -46z" />
+ <glyph glyph-name="random" unicode="&#xf074;" horiz-adv-x="1792"
+d="M666 1055c-56 -86 -97 -179 -137 -273c-58 121 -122 242 -273 242h-224c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h224c178 0 309 -83 410 -225zM1792 256c0 -8 -3 -17 -9 -23l-320 -320c-6 -6 -15 -9 -23 -9c-17 0 -32 15 -32 32v192c-297 0 -480 -35 -665 225
+c55 86 96 179 136 273c58 -121 122 -242 273 -242h256v192c0 18 14 32 32 32c9 0 17 -4 24 -10l319 -319c6 -6 9 -15 9 -23zM1792 1152c0 -8 -3 -17 -9 -23l-320 -320c-6 -6 -15 -9 -23 -9c-17 0 -32 14 -32 32v192h-256c-133 0 -196 -91 -252 -199
+c-29 -56 -54 -114 -78 -171c-111 -258 -241 -526 -566 -526h-224c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h224c133 0 196 91 252 199c29 56 54 114 78 171c111 258 241 526 566 526h256v192c0 18 14 32 32 32c9 0 17 -4 24 -10l319 -319c6 -6 9 -15 9 -23z" />
+ <glyph glyph-name="fire-extinguisher" unicode="&#xf134;" horiz-adv-x="1408"
+d="M512 1344c0 35 -29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64s64 29 64 64zM1408 1376v-320c0 -10 -4 -19 -12 -25c-6 -5 -13 -7 -20 -7c-2 0 -4 0 -7 1l-448 96c-14 3 -25 16 -25 31h-256v-102c146 -30 256 -159 256 -314v-800c0 -35 -29 -64 -64 -64h-512
+c-35 0 -64 29 -64 64v800c0 143 94 265 224 305v111h-32c-212 0 -326 -219 -327 -221c-11 -22 -34 -35 -57 -35c-10 0 -20 2 -29 7c-31 16 -44 54 -28 86c5 10 105 204 306 269c-15 25 -25 54 -25 86c0 88 72 160 160 160s160 -72 160 -160c0 -23 -5 -44 -14 -64h302
+c0 15 11 28 25 31l448 96c3 1 5 1 7 1c7 0 14 -2 20 -7c8 -6 12 -15 12 -25z" />
+ <glyph glyph-name="gnu-social" unicode="&#xf2e7;" horiz-adv-x="1513"
+d="M218 1404v0h1077c121 0 218 -97 218 -218v-873c0 -121 -97 -218 -218 -218h-118c-80 -349 -645 -351 -645 -351s334 104 335 351h-649c-121 0 -218 97 -218 218v873c0 121 97 218 218 218zM532 1229c-35 -5 -114 -89 -114 -150c0 -49 -3 -127 70 -167
+c-69 -67 -82 -163 -81 -247c2 -154 67 -382 357 -397s352 214 352 360h-305l50 -134l89 5s17 -107 -174 -100c-122 5 -200 68 -200 249s22 211 193 218s203 -139 203 -139l142 -3s-11 107 -93 188c73 40 72 118 69 167c-2 47 -102 169 -125 148s39 -41 34 -143
+c-2 -45 11 -79 -75 -79c-57 0 -33 51 -105 51c-43 0 -59 -28 -65 -50c-6 22 -21 50 -64 50c-72 0 -49 -51 -106 -51c-86 0 -72 34 -74 79c-5 102 56 122 33 143c-1 1 -3 2 -5 2h-6z" />
+ <glyph glyph-name="pencil-square" unicode="&#xf14b;"
+d="M404 428l152 -152l-52 -52h-56v96h-96v56zM818 818c8 -7 6 -21 -3 -30l-291 -291c-9 -9 -23 -11 -30 -3c-8 7 -6 21 3 30l291 291c9 9 23 11 30 3zM544 128l544 544l-288 288l-544 -544v-288h288zM1152 736l92 92c37 37 37 99 0 136l-152 152c-37 37 -99 37 -136 0
+l-92 -92zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="reddit-square" unicode="&#xf1a2;"
+d="M939 407c7 -7 7 -19 0 -26c-49 -49 -143 -53 -171 -53s-122 4 -171 53c-7 7 -7 19 0 26c7 8 19 8 26 0c31 -31 98 -42 145 -42s114 11 145 42c7 8 19 8 26 0zM676 563c0 -42 -35 -77 -77 -77s-77 35 -77 77c0 43 35 77 77 77s77 -34 77 -77zM1014 563
+c0 -42 -35 -77 -77 -77s-77 35 -77 77c0 43 35 77 77 77s77 -34 77 -77zM1229 666c0 56 -46 102 -103 102c-28 0 -54 -12 -73 -31c-70 48 -164 79 -267 82l54 243l171 -39c1 -42 35 -76 77 -76s77 35 77 77s-35 77 -77 77c-30 0 -56 -17 -69 -43l-189 42
+c-10 3 -19 -4 -21 -13l-60 -268c-103 -4 -196 -35 -265 -83c-19 20 -45 32 -74 32c-57 0 -103 -46 -103 -102c0 -41 24 -76 58 -93c-3 -15 -5 -32 -5 -48c0 -163 183 -295 409 -295s410 132 410 295c0 17 -2 33 -6 49c33 17 56 52 56 92zM1536 1120v-960
+c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="arrow-circle-o-down" unicode="&#xf01a;"
+d="M1120 608c0 -9 -4 -17 -10 -24l-319 -319c-7 -6 -15 -9 -23 -9s-16 3 -23 9l-320 320c-9 10 -12 23 -7 35s17 20 30 20h192v352c0 18 14 32 32 32h192c18 0 32 -14 32 -32v-352h192c18 0 32 -14 32 -32zM768 1184c-300 0 -544 -244 -544 -544s244 -544 544 -544
+s544 244 544 544s-244 544 -544 544zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="caret-left" unicode="&#xf0d9;" horiz-adv-x="576"
+d="M576 1088v-896c0 -35 -29 -64 -64 -64c-17 0 -33 7 -45 19l-448 448c-12 12 -19 28 -19 45s7 33 19 45l448 448c12 12 28 19 45 19c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="camera-retro" unicode="&#xf083;" horiz-adv-x="1792"
+d="M928 704c0 18 -14 32 -32 32c-88 0 -160 -72 -160 -160c0 -18 14 -32 32 -32s32 14 32 32c0 53 43 96 96 96c18 0 32 14 32 32zM1152 574c0 -141 -115 -256 -256 -256s-256 115 -256 256s115 256 256 256s256 -115 256 -256zM128 0h1536v128h-1536v-128zM1280 574
+c0 212 -172 384 -384 384s-384 -172 -384 -384s172 -384 384 -384s384 172 384 384zM256 1216h384v128h-384v-128zM128 1024h1536v256h-828l-64 -128h-644v-128zM1792 1280v-1280c0 -71 -57 -128 -128 -128h-1536c-71 0 -128 57 -128 128v1280c0 71 57 128 128 128h1536
+c71 0 128 -57 128 -128z" />
+ <glyph glyph-name="thumbs-o-up" unicode="&#xf087;"
+d="M256 192c0 35 -29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64s64 29 64 64zM1408 768c0 68 -61 128 -128 128h-352c0 117 96 202 96 320c0 117 -23 192 -160 192c-64 -65 -31 -218 -128 -320c-28 -29 -52 -60 -77 -91c-45 -58 -164 -229 -243 -229h-32v-640h32
+c56 0 148 -36 202 -55c110 -38 224 -73 342 -73h121c113 0 192 45 192 167c0 19 -2 38 -5 56c42 23 65 80 65 126c0 24 -6 48 -18 69c34 32 53 72 53 119c0 32 -14 79 -35 103c47 1 75 91 75 128zM1536 769c0 -58 -17 -115 -49 -163c6 -22 9 -46 9 -69
+c0 -50 -13 -100 -38 -144c2 -14 3 -29 3 -43c0 -64 -21 -128 -60 -178c2 -189 -127 -300 -312 -300h-129c-142 0 -274 42 -406 88c-29 10 -110 40 -138 40h-288c-71 0 -128 57 -128 128v640c0 71 57 128 128 128h274c39 26 107 116 137 155c34 44 69 87 107 128
+c60 64 28 222 128 320c24 23 56 37 90 37c104 0 204 -37 253 -134c31 -61 35 -119 35 -186c0 -70 -18 -130 -48 -192h176c138 0 256 -117 256 -255z" />
+ <glyph glyph-name="product-hunt" unicode="&#xf288;" horiz-adv-x="1792"
+d="M1150 774c0 -74 -60 -134 -135 -134h-253v269h253c75 0 135 -60 135 -135zM1329 774c0 174 -140 314 -314 314h-433v-896h180v269h253c174 0 314 140 314 313zM1792 640c0 -495 -401 -896 -896 -896s-896 401 -896 896s401 896 896 896s896 -401 896 -896z" />
+ <glyph glyph-name="etsy" unicode="&#xf2d7;"
+d="M518 1353v-655c232 -2 354 10 354 10c94 3 108 27 130 119l33 142h103l-14 -322l7 -319h-103l-29 127c-21 95 -62 118 -129 119c0 0 -86 8 -352 8v-556c0 -104 57 -153 177 -153h357c120 0 228 12 302 183l93 216h89c-7 -43 -55 -440 -62 -528c-329 12 -470 12 -470 12
+h-628l-376 -12v102l127 25c89 17 116 43 117 116c6 242 8 643 8 643s3 402 -8 645c-3 83 -28 103 -117 120l-127 24v102l376 -12h702s139 0 374 27c-14 -153 -31 -506 -31 -506h-93l-32 124c-39 155 -91 238 -187 238h-548c-41 0 -43 -14 -43 -39z" />
+ <glyph glyph-name="copyright" unicode="&#xf1f9;"
+d="M1150 462v-109c0 -141 -225 -193 -366 -193c-274 0 -480 209 -480 485c0 271 204 475 475 475c99 0 358 -35 358 -194v-109c0 -9 -7 -16 -16 -16h-118c-9 0 -16 7 -16 16v70c0 63 -121 92 -203 92c-187 0 -317 -135 -317 -329c0 -201 136 -348 325 -348
+c72 0 208 27 208 90v70c0 9 7 16 15 16h119c8 0 16 -7 16 -16zM768 1280c-353 0 -640 -287 -640 -640s287 -640 640 -640s640 287 640 640s-287 640 -640 640zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="pleroma" unicode="&#xf324;" horiz-adv-x="961"
+d="M120 1408h262v-1536h-382v1416c0 66 54 120 120 120zM575 1408h386v-648c0 -66 -53 -120 -119 -120v0h-267v768zM575 254h386v-262c0 -66 -53 -120 -119 -120v0h-267v382z" />
+ <glyph glyph-name="terminal" unicode="&#xf120;" horiz-adv-x="1651"
+d="M572 553l-466 -466c-13 -13 -33 -13 -46 0l-50 50c-13 13 -13 33 0 46l393 393l-393 393c-13 13 -13 33 0 46l50 50c13 13 33 13 46 0l466 -466c13 -13 13 -33 0 -46zM1651 96v-64c0 -18 -14 -32 -32 -32h-960c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h960
+c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="twitter-square" unicode="&#xf081;"
+d="M1280 926c-38 -17 -78 -28 -121 -34c44 26 77 68 93 117c-41 -24 -86 -42 -134 -51c-38 41 -93 66 -153 66c-116 0 -210 -94 -210 -210c0 -16 1 -33 5 -48c-175 9 -330 92 -434 220c-18 -31 -29 -68 -29 -106c0 -73 34 -137 91 -175c-35 1 -68 11 -100 26v-2
+c0 -102 77 -187 173 -206c-18 -5 -32 -8 -51 -8c-13 0 -26 2 -39 4c27 -83 104 -144 196 -146c-72 -56 -162 -90 -261 -90c-17 0 -34 1 -50 3c93 -59 203 -94 322 -94c386 0 598 320 598 598c0 9 0 18 -1 27c41 29 77 66 105 109zM1536 1120v-960
+c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="shopping-bag" unicode="&#xf290;" horiz-adv-x="1793"
+d="M1757 128l35 -313c2 -18 -4 -36 -16 -50c-12 -13 -30 -21 -48 -21h-1664c-18 0 -36 8 -48 21c-12 14 -18 32 -16 50l35 313h1722zM1664 967l86 -775h-1708l86 775c4 32 31 57 64 57h256v-128c0 -71 57 -128 128 -128s128 57 128 128v128h384v-128c0 -71 57 -128 128 -128
+s128 57 128 128v128h256c33 0 60 -25 64 -57zM1280 1152v-256c0 -35 -29 -64 -64 -64s-64 29 -64 64v256c0 141 -115 256 -256 256s-256 -115 -256 -256v-256c0 -35 -29 -64 -64 -64s-64 29 -64 64v256c0 212 172 384 384 384s384 -172 384 -384z" />
+ <glyph glyph-name="stop-circle" unicode="&#xf28d;"
+d="M1088 352v576c0 18 -14 32 -32 32h-576c-18 0 -32 -14 -32 -32v-576c0 -18 14 -32 32 -32h576c18 0 32 14 32 32zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="telegram" unicode="&#xf2c6;" horiz-adv-x="1792"
+d="M1189 229l147 693c13 61 -22 85 -62 70l-864 -333c-59 -23 -58 -56 -10 -71l221 -69l513 323c24 16 46 7 28 -9l-415 -375l-16 -228c23 0 33 10 45 22l108 104l224 -165c41 -23 70 -11 81 38zM1792 640c0 -495 -401 -896 -896 -896s-896 401 -896 896s401 896 896 896
+s896 -401 896 -896z" />
+ <glyph glyph-name="circle" unicode="&#xf111;"
+d="M1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="columns" unicode="&#xf0db;" horiz-adv-x="1664"
+d="M160 0h608v1152h-640v-1120c0 -17 15 -32 32 -32zM1536 32v1120h-640v-1152h608c17 0 32 15 32 32zM1664 1248v-1216c0 -88 -72 -160 -160 -160h-1344c-88 0 -160 72 -160 160v1216c0 88 72 160 160 160h1344c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="zotero" unicode="&#xf309;" horiz-adv-x="1330"
+d="M662 -127l-662 310v924l662 301l668 -301v-924zM314 152h723v221l-63 78h-275l338 379v218l-63 78h-601l-59 -82v-214h377l-352 -379l-25 -97v-202z" />
+ <glyph glyph-name="sign-out" unicode="&#xf08b;" horiz-adv-x="1568"
+d="M640 96c0 -28 13 -96 -32 -96h-320c-159 0 -288 129 -288 288v704c0 159 129 288 288 288h320c17 0 32 -15 32 -32c0 -28 13 -96 -32 -96h-320c-88 0 -160 -72 -160 -160v-704c0 -88 72 -160 160 -160h288c25 0 64 5 64 -32zM1568 640c0 -17 -7 -33 -19 -45l-544 -544
+c-12 -12 -28 -19 -45 -19c-35 0 -64 29 -64 64v288h-448c-35 0 -64 29 -64 64v384c0 35 29 64 64 64h448v288c0 35 29 64 64 64c17 0 33 -7 45 -19l544 -544c12 -12 19 -28 19 -45z" />
+ <glyph glyph-name="cube" unicode="&#xf1b2;" horiz-adv-x="1664"
+d="M896 -93l640 349v636l-640 -233v-752zM832 772l698 254l-698 254l-698 -254zM1664 1024v-768c0 -47 -26 -90 -67 -112l-704 -384c-19 -11 -40 -16 -61 -16s-42 5 -61 16l-704 384c-41 22 -67 65 -67 112v768c0 54 34 102 84 120l704 256c14 5 29 8 44 8s30 -3 44 -8
+l704 -256c50 -18 84 -66 84 -120z" />
+ <glyph glyph-name="mars-stroke-v" unicode="&#xf22a;" horiz-adv-x="1152"
+d="M640 892c288 -32 512 -276 512 -572c0 -340 -294 -611 -642 -572c-270 30 -486 253 -508 525c-25 317 207 586 510 619v132h-160c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h160v165l-92 -92c-13 -12 -33 -12 -45 0l-46 46c-12 12 -12 32 0 45l202 201c25 25 65 25 90 0
+l202 -201c12 -13 12 -33 0 -45l-46 -46c-12 -12 -32 -12 -45 0l-92 92v-165h160c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-160v-132zM576 -128c247 0 448 201 448 448s-201 448 -448 448s-448 -201 -448 -448s201 -448 448 -448z" />
+ <glyph glyph-name="file-text" unicode="&#xf15c;"
+d="M1468 1060c10 -10 19 -22 28 -36h-472v472c14 -9 26 -18 36 -28zM992 896h544v-1056c0 -53 -43 -96 -96 -96h-1344c-53 0 -96 43 -96 96v1600c0 53 43 96 96 96h800v-544c0 -53 43 -96 96 -96zM1152 160v64c0 18 -14 32 -32 32h-704c-18 0 -32 -14 -32 -32v-64
+c0 -18 14 -32 32 -32h704c18 0 32 14 32 32zM1152 416v64c0 18 -14 32 -32 32h-704c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h704c18 0 32 14 32 32zM1152 672v64c0 18 -14 32 -32 32h-704c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h704c18 0 32 14 32 32z" />
+ <glyph glyph-name="amazon" unicode="&#xf270;" horiz-adv-x="1736"
+d="M1523 60c30 15 53 -8 22 -48s-280 -268 -698 -268s-738 286 -836 404c-27 31 4 45 22 33c293 -178 751 -471 1490 -121zM1730 175c15 -20 0 -108 -26 -172c-26 -63 -64 -107 -85 -124c-22 -18 -38 -11 -26 15s77 186 51 220c-26 33 -148 17 -192 13c-43 -4 -52 -8 -56 1
+c-9 23 87 62 150 70c63 7 164 3 184 -23zM1336 618c0 -110 129 -211 129 -211l-227 -224c-89 84 -156 154 -156 154c-10 10 -18 22 -25 33c-181 -283 -734 -265 -734 173c0 408 483 463 678 470v127c0 27 10 150 -142 150c0 0 -152 0 -217 -198l-294 27
+c0 197 187 417 539 417c351 0 449 -228 449 -329v-589zM664 597c0 -203 337 -251 337 69v162c-135 -4 -337 -42 -337 -231z" />
+ <glyph glyph-name="smile-o" unicode="&#xf118;"
+d="M1134 461c-50 -161 -197 -269 -366 -269s-316 108 -366 269c-11 34 8 69 42 80c33 11 69 -8 80 -42c33 -107 132 -179 244 -179s211 72 244 179c11 34 47 53 81 42c33 -11 52 -46 41 -80zM640 896c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128
+s128 -57 128 -128zM1152 896c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128s128 -57 128 -128zM1408 640c0 353 -287 640 -640 640s-640 -287 -640 -640s287 -640 640 -640s640 287 640 640zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768
+s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="compass" unicode="&#xf14e;"
+d="M640 448l256 128l-256 128v-256zM1024 1039v-542l-512 -256v542zM1312 640c0 300 -244 544 -544 544s-544 -244 -544 -544s244 -544 544 -544s544 244 544 544zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="address-book" unicode="&#xf2b9;" horiz-adv-x="1664"
+d="M1201 298c0 177 -43 374 -221 374c-55 -32 -130 -87 -212 -87s-157 55 -212 87c-178 0 -221 -197 -221 -374c0 -99 65 -170 145 -170h576c80 0 145 71 145 170zM1028 892c0 144 -117 260 -260 260s-260 -116 -260 -260c0 -143 117 -259 260 -259s260 116 260 259z
+M1664 352v-192c0 -18 -14 -32 -32 -32h-96v-224c0 -88 -72 -160 -160 -160h-1216c-88 0 -160 72 -160 160v1472c0 88 72 160 160 160h1216c88 0 160 -72 160 -160v-224h96c18 0 32 -14 32 -32v-192c0 -18 -14 -32 -32 -32h-96v-128h96c18 0 32 -14 32 -32v-192
+c0 -18 -14 -32 -32 -32h-96v-128h96c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="list-ol" unicode="&#xf0cb;" horiz-adv-x="1777"
+d="M366 -84c0 -110 -86 -172 -190 -172c-63 0 -127 21 -172 66l57 88c27 -25 68 -45 106 -45c35 0 72 17 72 57c0 56 -64 59 -105 56l-26 56c36 46 69 97 112 136v1c-32 0 -65 -2 -97 -2v-53h-106v152h333v-88l-95 -115c67 -16 111 -68 111 -137zM368 543v-159h-362
+c-3 18 -6 36 -6 54c0 185 226 213 226 297c0 34 -21 52 -54 52c-35 0 -64 -30 -81 -58l-85 59c33 69 101 108 177 108c93 0 173 -55 173 -154c0 -148 -217 -181 -220 -259h127v60h105zM1777 224v-192c0 -17 -15 -32 -32 -32h-1216c-18 0 -32 15 -32 32v192c0 18 14 32 32 32
+h1216c17 0 32 -14 32 -32zM369 1123v-99h-335v99h107c0 81 1 162 1 243v12h-2c-11 -22 -31 -37 -50 -54l-71 76l136 127h106v-404h108zM1777 736v-192c0 -17 -15 -32 -32 -32h-1216c-18 0 -32 15 -32 32v192c0 18 14 32 32 32h1216c17 0 32 -14 32 -32zM1777 1248v-192
+c0 -17 -15 -32 -32 -32h-1216c-18 0 -32 15 -32 32v192c0 17 14 32 32 32h1216c17 0 32 -15 32 -32z" />
+ <glyph glyph-name="stumbleupon-circle" unicode="&#xf1a3;"
+d="M866 697l90 27v62c0 106 -90 191 -196 191s-196 -84 -196 -190v-283c0 -26 -21 -47 -47 -47s-46 21 -46 47v120h-151v-122c0 -109 88 -196 197 -196c107 0 196 86 196 193v280c0 26 21 47 47 47c25 0 46 -21 46 -47v-54zM1199 502v122h-150v-126c0 -26 -21 -47 -47 -47
+c-25 0 -46 21 -46 47v123l-90 -26l-60 28v-123c0 -107 89 -194 197 -194s196 87 196 196zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="slack" unicode="&#xf198;"
+d="M837 508l-205 69l66 197l205 -68zM979 1344c528 -158 651 -387 493 -915s-387 -651 -915 -493s-651 387 -493 915s387 651 915 493zM1256 671v0c13 41 -9 87 -51 101l-99 34l34 103c13 42 -8 88 -50 101c-47 13 -88 -14 -101 -51l-34 -103l-206 69l35 103
+c13 42 -9 88 -51 101c-47 13 -87 -13 -100 -50l-35 -104c-100 33 -111 39 -126 37c-32 -1 -63 -22 -74 -54c-13 -42 8 -88 50 -101l100 -33l-66 -198c-100 33 -112 39 -127 37c-32 -1 -63 -23 -74 -55c-13 -42 9 -87 51 -100l99 -34l-34 -103c-13 -42 8 -88 50 -101
+s88 9 101 51l34 103l206 -69l-35 -103c-13 -42 9 -88 51 -101s87 8 100 50l35 104l99 -34c42 -13 88 9 101 51s-8 88 -50 101l-100 33l66 198l100 -34c42 -13 88 9 101 51z" />
+ <glyph glyph-name="qq" unicode="&#xf1d6;" horiz-adv-x="1756"
+d="M252 730c-7 17 -8 34 -8 52c0 28 18 73 35 94c-1 26 10 79 30 96c0 185 143 418 310 498c103 49 211 66 324 66c88 0 184 -21 266 -55c235 -99 288 -283 338 -518l1 -5c29 -44 55 -96 55 -150c0 -27 -18 -54 -18 -78c0 -2 6 -10 7 -12c86 -127 164 -265 164 -423
+c0 -35 -19 -157 -75 -157c-39 0 -82 95 -96 121c-1 1 -2 1 -3 1l-5 -4c-32 -83 -67 -161 -132 -223c57 -55 149 -50 166 -145c-5 -11 -3 -23 -11 -34c-57 -86 -210 -97 -302 -97c-122 0 -221 32 -336 66c-24 7 -60 3 -86 6c-61 -67 -210 -85 -296 -85c-76 0 -370 5 -370 135
+c0 56 12 72 51 108c31 6 54 23 90 25c5 0 9 1 14 2c1 1 2 1 2 4l-2 3c-69 16 -166 190 -181 262l-5 3c-7 0 -10 -15 -12 -20c-22 -51 -74 -106 -132 -112h-1c-8 0 -5 8 -11 10c-14 33 -23 63 -23 100c0 200 96 348 252 466z" />
+ <glyph glyph-name="audio-description" unicode="&#xf29e;" horiz-adv-x="2304"
+d="M504 542h171l-1 265zM1530 641c0 111 -64 193 -197 193h-54v-388h52c125 0 199 91 199 195zM956 1018l1 -756c0 -19 -15 -34 -33 -34h-216c-18 0 -33 15 -33 34v62h-291l-55 -81c-6 -9 -17 -15 -28 -15h-267c-28 0 -44 31 -27 53l556 757c6 9 16 14 27 14h332
+c19 0 34 -15 34 -34zM1783 641c0 -263 -192 -413 -450 -413h-270c-19 0 -34 15 -34 34v756c0 19 15 34 34 34h268c260 0 452 -148 452 -411zM1939 640c0 0 4 -260 -148 -413h-51c136 162 139 414 139 414s2 198 -135 410h43c148 -169 152 -411 152 -411zM2123 640
+c0 0 4 -260 -149 -413h-51c136 162 139 414 139 414s2 198 -134 410h43c148 -169 152 -411 152 -411zM2304 640c0 0 4 -260 -148 -413h-51c135 162 138 414 138 414s2 198 -134 410h43c148 -169 152 -411 152 -411z" />
+ <glyph glyph-name="stop-circle-o" unicode="&#xf28e;"
+d="M768 1408c424 0 768 -344 768 -768s-344 -768 -768 -768s-768 344 -768 768s344 768 768 768zM768 96c300 0 544 244 544 544s-244 544 -544 544s-544 -244 -544 -544s244 -544 544 -544zM480 320c-18 0 -32 14 -32 32v576c0 18 14 32 32 32h576c18 0 32 -14 32 -32v-576
+c0 -18 -14 -32 -32 -32h-576z" />
+ <glyph glyph-name="grav" unicode="&#xf2d6;" horiz-adv-x="1794"
+d="M1291 1060c-32 36 -84 -25 -56 -58c27 -33 116 -9 56 58zM895 814c-11 -11 -28 -11 -38 0c-11 10 -11 27 0 37c10 11 27 11 38 0c10 -10 10 -27 0 -37zM1060 740l-35 -35c-16 -17 -43 -17 -60 0l-38 38c-16 17 -16 43 0 60l35 35c16 16 43 16 60 0l38 -39
+c16 -16 16 -43 0 -59zM951 870c-10 -10 -27 -10 -38 0c-10 11 -10 28 0 38c11 11 28 11 38 0c11 -10 11 -27 0 -38zM1354 968c-45 -85 -163 -120 -235 -69c-72 52 -122 156 -43 246c78 90 147 62 216 -3c43 -41 106 -90 62 -174zM1555 486c9 58 -74 60 -92 93
+c-49 87 -100 133 -197 110c42 29 85 22 85 22c1 23 0 47 -34 90c14 45 1 81 1 81c56 31 97 88 105 156c13 112 -68 214 -180 227c-80 9 -158 -28 -196 -93c-84 -145 5 -256 81 -294c-52 5 -124 43 -145 124c-24 93 10 180 32 222c0 0 -16 21 -29 32c0 0 -50 0 -89 -19
+c43 55 91 52 91 52c0 23 -2 54 -13 78c-20 41 -90 47 -117 -15c1 3 2 5 4 7c-18 -43 -4 -202 61 -315c-9 -5 -33 -22 -47 -36c-78 -35 -203 -218 -203 -218c-102 -39 -280 -184 -256 -288c1 -11 5 -20 11 -27c-10 -8 -20 -18 -30 -30c-43 -50 -19 -127 64 -88
+c57 26 108 73 132 110c0 0 -21 18 -60 16c100 24 125 34 168 33c29 -14 29 124 29 124c0 53 -8 112 -40 150c45 -44 105 -118 101 -219c-3 -66 -55 -83 -55 -83c-33 -60 -156 -238 -110 -383c0 0 -35 54 -37 80c-63 -70 -169 -189 -90 -233c96 -53 394 320 457 514
+c125 75 200 171 231 235c80 -159 346 -343 367 -215zM1794 640c0 -495 -402 -896 -897 -896s-897 401 -897 896s402 896 897 896s897 -401 897 -896z" />
+ <glyph glyph-name="mars-stroke-h" unicode="&#xf22b;" horiz-adv-x="1919"
+d="M1901 621c25 -25 25 -65 0 -90l-294 -294c-12 -13 -33 -13 -45 0l-45 45c-13 12 -13 33 0 45l185 185h-294v-224c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v224h-132c-32 -288 -276 -512 -572 -512c-340 0 -611 294 -572 642c30 270 253 486 525 508
+c317 25 586 -207 619 -510h132v224c0 18 14 32 32 32h64c18 0 32 -14 32 -32v-224h294l-185 185c-13 12 -13 33 0 45l45 45c12 13 33 13 45 0zM576 128c247 0 448 201 448 448s-201 448 -448 448s-448 -201 -448 -448s201 -448 448 -448z" />
+ <glyph glyph-name="gbp" unicode="&#xf154;" horiz-adv-x="1020"
+d="M1020 399v-367c0 -18 -14 -32 -32 -32h-956c-18 0 -32 14 -32 32v150c0 17 14 32 32 32h97v383h-95c-18 0 -32 14 -32 32v131c0 18 14 32 32 32h95v223c0 228 184 393 438 393c200 0 329 -120 335 -125c12 -11 13 -30 3 -43l-103 -127c-6 -7 -13 -11 -22 -12
+c-8 -1 -17 2 -23 7c-1 1 -87 69 -188 69c-113 0 -189 -68 -189 -170v-215h305c18 0 32 -14 32 -32v-131c0 -18 -14 -32 -32 -32h-305v-379h414v181c0 18 14 32 32 32h162c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="shaarli-o" unicode="&#xf2f6;" horiz-adv-x="1630"
+d="M859 1408v0c107 0 210 -67 264 -160c40 -69 61 -156 75 -252c115 -20 212 -47 288 -96c78 -50 134 -137 140 -229l3 -20c7 -91 -25 -191 -100 -245c-18 -13 -36 -22 -55 -30c11 -19 25 -36 34 -56c37 -84 43 -181 12 -267v-1h-1c-26 -70 -82 -133 -154 -160
+s-147 -24 -224 -5c-9 3 -17 5 -25 10c-94 47 -174 101 -239 162c-25 -34 -53 -66 -86 -91c-75 -57 -168 -84 -266 -84c-31 0 -62 -4 -90 5c-82 25 -155 68 -199 141s-44 164 -20 243l1 3l1 3l21 58c-57 19 -109 45 -151 86c-67 66 -95 165 -86 259h-1c0 1 1 2 1 3v7h1
+c8 100 75 193 165 238c87 43 192 57 317 60c6 109 27 206 84 283c66 89 177 135 290 135zM859 1288c-173 0 -260 -116 -260 -348c12 -37 -17 -59 -88 -67c-255 -1 -386 -66 -391 -196c-18 -141 68 -226 258 -253h19l-67 -186c-36 -117 11 -195 141 -235h53
+c155 0 260 80 314 239h37c58 -90 155 -170 294 -239c126 -31 206 -1 239 90c42 114 -12 238 -162 370c196 -10 285 53 264 190c3 117 -118 194 -360 231h-56c-21 269 -99 404 -235 404zM819 1097v0c3 0 6 0 9 -1c50 1 76 -51 76 -156v-188c22 -23 49 -31 84 -25
+c226 0 335 -27 327 -81c10 -49 -110 -65 -361 -48c-12 0 -14 -15 -6 -43c74 -85 140 -151 198 -200c59 -47 69 -92 31 -133c-32 -22 -74 -5 -127 49c-51 54 -117 122 -197 207c-18 24 -40 24 -67 0c-113 -230 -200 -325 -262 -288c-46 24 -23 105 68 242l54 116
+c12 33 -72 45 -250 36c-51 3 -77 22 -77 58c0 37 24 57 71 58l304 17c31 0 48 27 52 81l4 107c-1 131 22 195 69 192z" />
+ <glyph glyph-name="ban" unicode="&#xf05e;"
+d="M1312 643c0 109 -32 210 -87 295l-754 -753c86 -56 188 -89 297 -89c300 0 544 245 544 547zM313 344l755 754c-86 58 -189 91 -300 91c-300 0 -544 -245 -544 -546c0 -111 33 -213 89 -299zM1536 643c0 -426 -344 -771 -768 -771s-768 345 -768 771
+c0 425 344 770 768 770s768 -345 768 -770z" />
+ <glyph glyph-name="fighter-jet" unicode="&#xf0fb;" horiz-adv-x="1920"
+d="M1920 576c0 0 0 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69c35 0 64 -7 64 -16s-29 -16 -64 -16h-320v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8l-192 24v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h320c35 0 64 -7 64 -16
+s-29 -16 -64 -16h-69l293 -352h64l224 -64l352 -32c288 -64 288 -96 288 -96z" />
+ <glyph glyph-name="space-shuttle" unicode="&#xf197;" horiz-adv-x="2176"
+d="M620 416c-69 -40 -163 -64 -268 -64h-128v64h-64c-18 0 -32 36 -32 80c0 18 3 35 7 49c-77 2 -135 15 -135 31s58 29 135 31c-4 14 -7 31 -7 49c0 44 14 80 32 80h64v64h128c105 0 199 -24 268 -64h1113c74 -13 141 -24 187 -32c192 -32 256 -96 256 -128
+s-64 -96 -256 -128c-46 -8 -113 -19 -187 -32h-1113zM1739 668c32 -22 53 -55 53 -92s-21 -70 -53 -92l81 -30c41 29 68 73 68 122s-27 93 -68 122zM625 400h1015s-217 -38 -456 -80c-128 0 -224 -96 -224 -96l-288 -288s-97 -64 -160 -64h-96l-93 464h29
+c102 0 199 23 273 64zM352 816h-29l93 464h96c65 0 128 -32 160 -64l288 -288s96 -96 224 -96c239 -42 456 -80 456 -80h-1015c-74 41 -171 64 -273 64z" />
+ <glyph glyph-name="matrix-org" unicode="&#xf313;"
+d="M40 1373v-1466h106v-35h-146v1536h146v-35h-106zM491 908v-74h2c20 28 44 51 72 66c28 16 60 23 96 23c35 0 66 -7 95 -20s50 -37 65 -71c16 24 38 46 66 64s61 27 99 27c29 0 56 -4 81 -11s45 -18 63 -34s31 -35 41 -60s15 -56 15 -91v-367h-150v311c0 18 -1 36 -2 52
+s-6 30 -12 42s-16 22 -28 29s-29 10 -50 10s-38 -4 -51 -12s-24 -19 -31 -32s-13 -27 -15 -44s-4 -34 -4 -51v-305h-150v307c0 16 0 33 -1 49s-4 30 -9 44c-5 13 -15 24 -27 32s-31 12 -55 12c-7 0 -16 -2 -28 -5s-23 -9 -34 -18s-20 -21 -28 -38s-11 -38 -11 -65v-318h-151
+v548h142zM1496 -93v1466h-106v35h146v-1536h-146v35h106z" />
+ <glyph glyph-name="steam" unicode="&#xf1b6;" horiz-adv-x="1792"
+d="M1582 954c0 -135 -110 -244 -244 -244c-135 0 -244 109 -244 244s109 244 244 244c134 0 244 -109 244 -244zM812 212c0 139 -111 250 -250 250c-18 0 -36 -2 -54 -6l104 -42c102 -41 152 -156 111 -258s-157 -152 -259 -110c-41 16 -82 33 -123 49
+c42 -79 125 -133 221 -133c139 0 250 111 250 250zM1642 953c0 168 -137 305 -305 305c-169 0 -306 -137 -306 -305c0 -169 137 -305 306 -305c168 0 305 136 305 305zM1792 953c0 -252 -204 -455 -455 -455l-437 -319c-16 -172 -162 -307 -338 -307
+c-162 0 -299 115 -332 268l-230 92v429l389 -157c51 31 110 48 173 48c12 0 24 -1 35 -2l284 407c2 249 206 451 456 451c251 0 455 -204 455 -455z" />
+ <glyph glyph-name="bars" unicode="&#xf0c9;"
+d="M1536 192v-128c0 -35 -29 -64 -64 -64h-1408c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1408c35 0 64 -29 64 -64zM1536 704v-128c0 -35 -29 -64 -64 -64h-1408c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1408c35 0 64 -29 64 -64zM1536 1216v-128
+c0 -35 -29 -64 -64 -64h-1408c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1408c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="lightbulb-o" unicode="&#xf0eb;" horiz-adv-x="1024"
+d="M736 960c0 -17 -15 -32 -32 -32s-32 15 -32 32c0 69 -107 96 -160 96c-17 0 -32 15 -32 32s15 32 32 32c93 0 224 -49 224 -160zM896 960c0 200 -203 320 -384 320s-384 -120 -384 -320c0 -64 26 -131 68 -180c19 -22 41 -43 61 -66c71 -85 131 -185 141 -298h228
+c10 113 70 213 141 298c20 23 42 44 61 66c42 49 68 116 68 180zM1024 960c0 -103 -34 -192 -103 -268s-160 -183 -168 -290c29 -17 47 -49 47 -82c0 -24 -9 -47 -25 -64c16 -17 25 -40 25 -64c0 -33 -17 -63 -45 -81c8 -14 13 -31 13 -47c0 -65 -51 -96 -109 -96
+c-26 -58 -84 -96 -147 -96s-121 38 -147 96c-58 0 -109 31 -109 96c0 16 5 33 13 47c-28 18 -45 48 -45 81c0 24 9 47 25 64c-16 17 -25 40 -25 64c0 33 18 65 47 82c-8 107 -99 214 -168 290s-103 165 -103 268c0 272 259 448 512 448s512 -176 512 -448z" />
+ <glyph glyph-name="map-pin" unicode="&#xf276;" horiz-adv-x="1024"
+d="M512 448c44 0 87 5 128 15v-655c0 -35 -29 -64 -64 -64h-128c-35 0 -64 29 -64 64v655c41 -10 84 -15 128 -15zM512 1536c283 0 512 -229 512 -512s-229 -512 -512 -512s-512 229 -512 512s229 512 512 512zM512 1312c18 0 32 14 32 32s-14 32 -32 32
+c-194 0 -352 -158 -352 -352c0 -18 14 -32 32 -32s32 14 32 32c0 159 129 288 288 288z" />
+ <glyph glyph-name="circle-o" unicode="&#xf10c;"
+d="M768 1184c-300 0 -544 -244 -544 -544s244 -544 544 -544s544 244 544 544s-244 544 -544 544zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="contao" unicode="&#xf26d;" horiz-adv-x="1748"
+d="M116 1408h197c-47 -43 -89 -93 -126 -149c-155 -239 -92 -501 -32 -783c49 -229 90 -447 233 -604h-272c-64 0 -116 52 -116 116v1304c0 64 52 116 116 116zM1324 1408h308c64 0 116 -52 116 -116v-1304c0 -64 -52 -116 -116 -116h-178c132 131 207 321 196 565
+l-469 -101c-6 -111 -44 -218 -196 -250c-85 -18 -155 2 -199 40c-54 46 -97 106 -169 448c-73 343 -58 415 -28 479c25 52 81 100 165 118c153 32 231 -51 282 -150l468 100c-46 118 -107 214 -180 287z" />
+ <glyph glyph-name="vine" unicode="&#xf1ca;" horiz-adv-x="1458"
+d="M1458 709v-198c-70 -16 -140 -23 -198 -23c-140 -294 -391 -546 -475 -593c-53 -30 -103 -32 -162 3c-103 62 -493 382 -623 1388h283c71 -604 245 -914 436 -1146c106 106 208 247 287 406c-189 96 -304 307 -304 553c0 249 143 437 388 437c238 0 368 -148 368 -403
+c0 -95 -20 -203 -58 -286c0 0 -176 -35 -241 78c13 43 31 117 31 184c0 119 -43 177 -108 177c-69 0 -117 -65 -117 -190c0 -255 162 -401 372 -401c37 0 79 4 121 14z" />
+ <glyph glyph-name="align-center" unicode="&#xf037;" horiz-adv-x="1792"
+d="M1792 192v-128c0 -35 -29 -64 -64 -64h-1664c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1664c35 0 64 -29 64 -64zM1408 576v-128c0 -35 -29 -64 -64 -64h-896c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h896c35 0 64 -29 64 -64zM1664 960v-128c0 -35 -29 -64 -64 -64
+h-1408c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1408c35 0 64 -29 64 -64zM1280 1344v-128c0 -35 -29 -64 -64 -64h-640c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h640c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="btc" unicode="&#xf15a;" horiz-adv-x="1202"
+d="M1111 896c13 -133 -43 -213 -131 -258c146 -35 238 -122 220 -317c-23 -243 -203 -308 -461 -322v-255h-154v251c-39 0 -80 0 -122 1v-252h-154v255c-36 0 -72 1 -109 1h-200l31 183c113 -2 111 0 111 0c43 0 55 31 58 51v402h16c-6 1 -12 1 -16 1v287
+c-6 32 -26 68 -89 68c0 0 2 2 -111 0v164l212 -1c31 0 64 0 97 1v252h154v-247c41 1 82 2 122 2v245h154v-252c198 -17 355 -78 372 -260zM896 351c0 198 -326 169 -430 169v-338c104 0 430 -22 430 169zM825 827c0 181 -272 154 -359 154v-307c87 0 359 -20 359 153z" />
+ <glyph glyph-name="calendar" unicode="&#xf073;" horiz-adv-x="1664"
+d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z
+M512 1088v288c0 17 -15 32 -32 32h-64c-17 0 -32 -15 -32 -32v-288c0 -17 15 -32 32 -32h64c17 0 32 15 32 32zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288c0 17 -15 32 -32 32h-64c-17 0 -32 -15 -32 -32v-288
+c0 -17 15 -32 32 -32h64c17 0 32 15 32 32zM1664 1152v-1280c0 -70 -58 -128 -128 -128h-1408c-70 0 -128 58 -128 128v1280c0 70 58 128 128 128h128v96c0 88 72 160 160 160h64c88 0 160 -72 160 -160v-96h384v96c0 88 72 160 160 160h64c88 0 160 -72 160 -160v-96h128
+c70 0 128 -58 128 -128z" />
+ <glyph glyph-name="retweet" unicode="&#xf079;" horiz-adv-x="1920"
+d="M1280 32c0 -17 -15 -32 -32 -32h-960c-37 0 -32 39 -32 64v576h-192c-35 0 -64 29 -64 64c0 15 5 30 15 41l320 384c12 14 30 22 49 22s37 -8 49 -22l320 -384c10 -11 15 -26 15 -41c0 -35 -29 -64 -64 -64h-192v-384h576c9 0 19 -4 25 -11l160 -192c4 -6 7 -14 7 -21z
+M1920 448c0 -15 -5 -30 -15 -41l-320 -384c-12 -14 -30 -23 -49 -23s-37 9 -49 23l-320 384c-10 11 -15 26 -15 41c0 35 29 64 64 64h192v384h-576c-9 0 -19 4 -25 12l-160 192c-4 5 -7 13 -7 20c0 17 15 32 32 32h960c37 0 32 -39 32 -64v-576h192c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="hourglass" unicode="&#xf254;"
+d="M1504 -64c18 0 32 -14 32 -32v-128c0 -18 -14 -32 -32 -32h-1472c-18 0 -32 14 -32 32v128c0 18 14 32 32 32h1472zM130 0c19 337 294 518 478 640c-184 122 -459 303 -478 640h1276c-19 -337 -294 -518 -478 -640c184 -122 459 -303 478 -640h-1276zM1504 1536
+c18 0 32 -14 32 -32v-128c0 -18 -14 -32 -32 -32h-1472c-18 0 -32 14 -32 32v128c0 18 14 32 32 32h1472z" />
+ <glyph glyph-name="paint-brush" unicode="&#xf1fc;" horiz-adv-x="1790"
+d="M1615 1536c91 0 175 -68 175 -163c0 -53 -21 -104 -45 -151c-78 -148 -340 -637 -465 -752c-61 -57 -133 -91 -218 -91c-169 0 -307 144 -307 312c0 80 33 158 92 212l638 579c35 32 81 54 130 54zM706 502c52 -101 147 -177 257 -206l1 -71c6 -285 -192 -481 -478 -481
+c-339 0 -486 270 -486 577c37 -25 166 -128 208 -128c25 0 46 14 55 37c85 222 218 262 443 272z" />
+ <glyph glyph-name="viadeo-square" unicode="&#xf2aa;"
+d="M1050 495c0 50 -9 100 -28 147c-26 -16 -55 -28 -85 -34c16 -36 22 -75 22 -114c0 -154 -114 -280 -270 -280c-157 0 -271 126 -271 280c0 151 115 284 271 284c34 0 67 -6 98 -19c3 30 13 60 27 87c-40 14 -82 21 -125 21c-207 0 -361 -167 -361 -372s155 -367 361 -367
+s361 163 361 367zM872 850c25 -72 38 -148 38 -225c0 -173 -71 -317 -219 -411h-10c-14 0 -28 1 -42 3c199 76 235 377 235 562c0 23 0 47 -2 71zM872 850c-5 97 -60 247 -142 302c56 -95 106 -197 142 -302zM1207 955c0 61 -15 123 -51 174c-24 -51 -69 -94 -124 -109
+c-79 -22 -149 -59 -149 -153c0 -27 9 -54 24 -77c95 22 196 92 236 182c-6 -80 -155 -177 -213 -209c29 -29 67 -52 110 -52c73 0 125 65 150 127c12 30 17 86 17 117zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288
+h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="tags" unicode="&#xf02c;" horiz-adv-x="1899"
+d="M448 1088c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM1515 512c0 -34 -14 -67 -37 -90l-491 -492c-24 -23 -57 -37 -91 -37s-67 14 -90 37l-715 716c-51 50 -91 147 -91 218v416c0 70 58 128 128 128h416c71 0 168 -40 219 -91
+l715 -714c23 -24 37 -57 37 -91zM1899 512c0 -34 -14 -67 -37 -90l-491 -492c-24 -23 -57 -37 -91 -37c-52 0 -78 24 -112 59l470 470c23 23 37 56 37 90s-14 67 -37 91l-715 714c-51 51 -148 91 -219 91h224c71 0 168 -40 219 -91l715 -714c23 -24 37 -57 37 -91z" />
+ <glyph glyph-name="minus-square-o" unicode="&#xf147;" horiz-adv-x="1408"
+d="M1152 736v-64c0 -18 -14 -32 -32 -32h-832c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h832c18 0 32 -14 32 -32zM1280 288v832c0 88 -72 160 -160 160h-832c-88 0 -160 -72 -160 -160v-832c0 -88 72 -160 160 -160h832c88 0 160 72 160 160zM1408 1120v-832
+c0 -159 -129 -288 -288 -288h-832c-159 0 -288 129 -288 288v832c0 159 129 288 288 288h832c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="user-circle" unicode="&#xf2bd;" horiz-adv-x="1792"
+d="M1523 197c-26 187 -102 353 -272 376c-88 -96 -215 -157 -355 -157s-267 61 -355 157c-170 -23 -246 -189 -272 -376c139 -196 368 -325 627 -325s488 129 627 325zM1280 896c0 212 -172 384 -384 384s-384 -172 -384 -384s172 -384 384 -384s384 172 384 384zM1792 640
+c0 -493 -400 -896 -896 -896c-495 0 -896 402 -896 896c0 495 401 896 896 896s896 -401 896 -896z" />
+ <glyph glyph-name="thumbs-o-down" unicode="&#xf088;"
+d="M256 1088c0 35 -29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64s64 29 64 64zM1408 512c0 37 -28 127 -75 128c21 24 35 71 35 103c0 47 -19 87 -53 119c12 21 18 45 18 69c0 46 -23 103 -65 126c3 18 5 37 5 56c0 117 -74 167 -185 167h-128c-118 0 -232 -35 -342 -73
+c-54 -19 -146 -55 -202 -55h-32v-640h32c79 0 198 -171 243 -229c25 -31 49 -62 77 -91c97 -102 64 -255 128 -320c137 0 160 75 160 192c0 118 -96 203 -96 320h352c67 0 128 60 128 128zM1536 511c0 -138 -118 -255 -256 -255h-176c30 -62 48 -122 48 -192
+c0 -66 -4 -126 -35 -186c-49 -97 -149 -134 -253 -134c-34 0 -66 14 -90 37c-100 98 -69 256 -128 321c-38 40 -73 83 -107 127c-30 39 -98 129 -137 155h-274c-71 0 -128 57 -128 128v640c0 71 57 128 128 128h288c28 0 109 30 138 40c144 50 269 88 423 88h112
+c182 0 313 -108 312 -295v-5c39 -50 60 -114 60 -178c0 -14 -1 -29 -3 -43c25 -44 38 -94 38 -144c0 -23 -3 -47 -9 -69c32 -48 49 -105 49 -163z" />
+ <glyph glyph-name="subscript" unicode="&#xf12c;" horiz-adv-x="1531"
+d="M892 167v-167h-248l-159 252l-24 42c-6 7 -9 14 -11 21h-3c-2 -7 -6 -14 -9 -21c-6 -12 -15 -28 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228c9 -14 16 -29 23 -42c6 -7 9 -14 11 -21h3c2 7 6 14 11 21l25 42l140 228h257v-168h-125
+l-184 -267l204 -296h109zM1531 -50v-206h-514l-4 27c-1 15 -3 33 -3 46c0 273 350 296 350 441c0 52 -47 87 -100 87c-39 0 -72 -18 -97 -39c-13 -11 -25 -25 -36 -38l-105 92c18 25 38 46 63 66c42 34 103 65 188 65c145 0 246 -85 246 -218c0 -239 -332 -259 -346 -403
+h232v80h126z" />
+ <glyph glyph-name="flickr" unicode="&#xf16e;"
+d="M1248 1408c159 0 288 -129 288 -288v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960zM698 640c0 117 -95 212 -212 212s-212 -95 -212 -212s95 -212 212 -212s212 95 212 212zM1262 640c0 117 -95 212 -212 212
+s-212 -95 -212 -212s95 -212 212 -212s212 95 212 212z" />
+ <glyph glyph-name="cc-amex" unicode="&#xf1f3;" horiz-adv-x="2304"
+d="M119 854h89l-45 108zM740 328l74 79l-70 79h-163v-49h142v-55h-142v-54h159zM898 406l99 -110v217zM1186 453c0 24 -18 33 -40 33h-84v-69h83c23 0 41 11 41 36zM1475 457c0 25 -22 29 -42 29h-82v-61h81c22 0 43 5 43 32zM1197 923c0 25 -22 29 -42 29h-82v-60h81
+c22 0 43 5 43 31zM1656 854h89l-44 108zM699 1009v-271h-66v212l-94 -212h-57l-94 212v-212h-132l-25 60h-135l-25 -60h-70l116 271h96l110 -257v257h106l85 -184l77 184h108zM1255 453c0 -109 -119 -91 -193 -91v-91h-126l-80 90l-83 -90h-256v271h260l80 -89l82 89h207
+c61 0 109 -21 109 -89zM964 794v-56h-217v271h217v-57h-152v-49h148v-55h-148v-54h152zM2304 235v-229c0 -73 -59 -134 -132 -134h-2040c-73 0 -132 61 -132 134v678h111l25 61h55l25 -61h218v46l19 -46h113l20 47v-47h541v99l10 1c9 0 10 -7 10 -14v-86h279v23
+c65 -34 154 -23 222 -23l25 61h56l25 -61h227v58l34 -58h182v378h-180v-44l-25 44h-185v-44l-23 44h-249c-37 0 -76 -4 -109 -22v22h-172v-22c-20 18 -47 22 -73 22h-628l-43 -97l-43 97h-198v-44l-22 44h-169l-78 -179v391c0 73 59 134 132 134h2040c73 0 132 -61 132 -134
+v-678h-120c-28 0 -58 -5 -81 -22v22h-177c-25 0 -59 -4 -78 -22v22h-316v-22c-24 17 -59 22 -87 22h-209v-22c-21 20 -64 22 -91 22h-234l-54 -58l-50 58h-349v-378h343l55 59l52 -59h211v89h21c30 0 61 1 90 13v-102h174v99h8c10 0 12 -1 12 -12v-87h529c29 0 65 6 88 24
+v-24h168c32 0 66 3 95 17zM1546 469c0 -30 -16 -60 -46 -72c36 -13 43 -37 43 -72v-54h-65v45c0 46 -15 54 -58 54h-69v-99h-65v271h154c51 0 106 -9 106 -73zM1269 936c0 -31 -17 -61 -46 -73c37 -13 43 -36 43 -72v-53h-65c-1 58 14 98 -58 98h-70v-98h-64v271l153 -1
+c52 0 107 -8 107 -72zM1798 327v-56h-216v271h216v-56h-151v-49h148v-55h-148v-54zM1372 1009v-271h-66v271h66zM2065 357c0 -64 -44 -86 -102 -86h-126v58h126c16 0 34 4 34 25c0 58 -167 -22 -167 107c0 55 42 81 92 81h130v-57h-119c-17 0 -36 -3 -36 -25
+c0 -59 168 27 168 -103zM2304 407v-101c-19 -28 -56 -35 -88 -35h-125v58h125c16 0 33 5 33 25c0 57 -167 -22 -167 107c0 55 43 81 93 81h129v-57h-118c-18 0 -36 -3 -36 -25c0 -48 113 1 154 -53zM2139 1008v-270h-92l-122 203v-203h-132l-26 60h-134l-25 -60h-75
+c-89 0 -129 46 -129 133c0 91 41 138 133 138h63v-59c-68 1 -130 16 -130 -77c0 -46 11 -78 63 -78h29l92 213h97l109 -256v256h99l114 -188v188h66z" />
+ <glyph glyph-name="reddit" unicode="&#xf1a1;" horiz-adv-x="1792"
+d="M1095 369c9 -9 9 -23 0 -31c-57 -57 -167 -62 -199 -62s-142 5 -199 62c-9 8 -9 22 0 31c8 8 22 8 30 0c36 -37 114 -49 169 -49s132 12 169 49c8 8 22 8 30 0zM788 550c0 -49 -40 -89 -89 -89c-50 0 -90 40 -90 89c0 50 40 90 90 90c49 0 89 -40 89 -90zM1183 550
+c0 -49 -40 -89 -90 -89c-49 0 -89 40 -89 89c0 50 40 90 89 90c50 0 90 -40 90 -90zM1434 670c0 66 -54 119 -120 119c-34 0 -64 -14 -86 -36c-81 56 -190 92 -311 96l63 283l200 -45c0 -49 40 -89 89 -89c50 0 90 41 90 90s-40 90 -90 90c-35 0 -65 -21 -80 -50l-221 49
+c-11 3 -22 -5 -25 -16l-69 -312c-120 -5 -228 -41 -309 -97c-22 23 -53 37 -87 37c-66 0 -120 -53 -120 -119c0 -48 28 -88 68 -108c-4 -18 -6 -37 -6 -56c0 -190 214 -344 477 -344c264 0 478 154 478 344c0 19 -2 39 -7 57c39 20 66 60 66 107zM1792 640
+c0 -495 -401 -896 -896 -896s-896 401 -896 896s401 896 896 896s896 -401 896 -896z" />
+ <glyph glyph-name="times-circle" unicode="&#xf057;"
+d="M1149 414c0 17 -7 33 -19 45l-181 181l181 181c12 12 19 28 19 45s-7 34 -19 46l-90 90c-12 12 -29 19 -46 19s-33 -7 -45 -19l-181 -181l-181 181c-12 12 -28 19 -45 19s-34 -7 -46 -19l-90 -90c-12 -12 -19 -29 -19 -46s7 -33 19 -45l181 -181l-181 -181
+c-12 -12 -19 -28 -19 -45s7 -34 19 -46l90 -90c12 -12 29 -19 46 -19s33 7 45 19l181 181l181 -181c12 -12 28 -19 45 -19s34 7 46 19l90 90c12 12 19 29 19 46zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="tripadvisor" unicode="&#xf262;" horiz-adv-x="2304"
+d="M651 539c0 -52 -42 -94 -93 -94c-52 0 -94 42 -94 94c0 51 42 93 94 93c51 0 93 -42 93 -93zM1805 540c0 -52 -42 -94 -94 -94s-94 42 -94 94s42 93 94 93s94 -41 94 -93zM765 539c0 106 -87 193 -193 193c-107 0 -193 -87 -193 -193c0 -107 86 -193 193 -193
+c106 0 193 86 193 193zM1918 540c0 106 -86 193 -193 193c-106 0 -193 -87 -193 -193c0 -107 87 -193 193 -193c107 0 193 86 193 193zM850 539c0 -154 -124 -279 -278 -279s-279 125 -279 279c0 153 125 278 279 278s278 -125 278 -278zM2004 540
+c0 -154 -125 -278 -279 -278c-153 0 -278 124 -278 278s125 278 278 278c154 0 279 -124 279 -278zM1040 537c0 255 -207 462 -462 462c-254 0 -461 -207 -461 -462s207 -462 461 -462c255 0 462 207 462 462zM1708 1110c-165 72 -351 111 -556 111s-409 -39 -573 -110
+c317 -1 573 -257 573 -574c0 311 247 564 556 573zM2187 537c0 255 -206 462 -461 462s-462 -207 -462 -462s207 -462 462 -462s461 207 461 462zM1921 1103h383c-60 -70 -104 -164 -115 -229c69 -95 110 -211 110 -337c0 -317 -257 -573 -573 -573c-180 0 -340 82 -445 211
+c0 0 -47 -56 -129 -179c-14 29 -85 130 -128 180c-105 -130 -266 -212 -446 -212c-316 0 -573 256 -573 573c0 126 41 242 110 337c-11 65 -55 159 -115 229h365c196 131 481 213 787 213s573 -82 769 -213z" />
+ <glyph glyph-name="sort-amount-asc" unicode="&#xf160;" horiz-adv-x="1760"
+d="M704 96c0 -9 -4 -17 -10 -24l-319 -319c-7 -6 -15 -9 -23 -9s-16 3 -23 9l-320 320c-9 10 -12 23 -7 35s17 20 30 20h192v1376c0 18 14 32 32 32h192c18 0 32 -14 32 -32v-1376h192c18 0 32 -14 32 -32zM1760 -32v-192c0 -18 -14 -32 -32 -32h-832c-18 0 -32 14 -32 32
+v192c0 18 14 32 32 32h832c18 0 32 -14 32 -32zM1568 480v-192c0 -18 -14 -32 -32 -32h-640c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h640c18 0 32 -14 32 -32zM1376 992v-192c0 -18 -14 -32 -32 -32h-448c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h448
+c18 0 32 -14 32 -32zM1184 1504v-192c0 -18 -14 -32 -32 -32h-256c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h256c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="renren" unicode="&#xf18b;"
+d="M1133 -34c-109 -60 -234 -94 -368 -94c-133 0 -258 34 -367 94c177 112 320 281 367 479c48 -198 191 -367 368 -479zM638 1394v-485c0 -342 -189 -636 -457 -766c-113 134 -181 306 -181 495c0 380 276 695 638 756zM1536 638c0 -189 -68 -361 -181 -495
+c-268 130 -457 424 -457 766v485c362 -61 638 -376 638 -756z" />
+ <glyph glyph-name="key-modern" unicode="&#xf2f7;" horiz-adv-x="1792"
+d="M546 1536v0c139 1 278 -52 383 -158c142 -141 187 -343 137 -525l726 -726v-319c0 -35 -29 -64 -64 -64h-300l-45 45l135 226l-46 45l-225 -135l-45 46l134 225l-45 45l-225 -134l-46 45l135 225l-45 46l-243 -139l-186 186c-182 -50 -382 -5 -524 136
+c-211 212 -209 556 4 770c107 106 246 159 385 160zM405 1290v0c-41 0 -82 -16 -113 -47c-63 -63 -63 -163 0 -226s164 -63 227 0s63 163 0 226c-31 31 -73 47 -114 47z" />
+ <glyph glyph-name="arrow-circle-o-right" unicode="&#xf18e;"
+d="M1152 640c0 -8 -3 -17 -9 -23l-320 -320c-6 -6 -15 -9 -23 -9c-17 0 -32 15 -32 32v192h-352c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h352v192c0 18 14 32 32 32c9 0 17 -4 24 -10l319 -319c6 -6 9 -15 9 -23zM1312 640c0 300 -244 544 -544 544s-544 -244 -544 -544
+s244 -544 544 -544s544 244 544 544zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="pinterest-p" unicode="&#xf231;" horiz-adv-x="1280"
+d="M0 939c0 369 338 597 680 597c314 0 600 -216 600 -547c0 -311 -159 -656 -513 -656c-84 0 -190 42 -231 120c-76 -301 -70 -346 -238 -576l-14 -5l-9 10c-6 63 -15 125 -15 188c0 204 94 499 140 697c-25 51 -32 113 -32 169c0 101 70 229 184 229
+c84 0 129 -64 129 -143c0 -130 -88 -252 -88 -378c0 -86 71 -146 154 -146c230 0 301 332 301 509c0 237 -168 366 -395 366c-264 0 -468 -190 -468 -458c0 -129 79 -195 79 -226c0 -26 -19 -118 -52 -118c-5 0 -12 2 -17 3c-143 43 -195 234 -195 365z" />
+ <glyph glyph-name="html5" unicode="&#xf13b;" horiz-adv-x="1408"
+d="M1130 939l16 175h-884l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674zM0 1408h1408l-128 -1438l-578 -162l-574 162z" />
+ <glyph glyph-name="key" unicode="&#xf084;" horiz-adv-x="1683"
+d="M832 1024c0 106 -86 192 -192 192s-192 -86 -192 -192c0 -29 7 -57 19 -83c-26 12 -54 19 -83 19c-106 0 -192 -86 -192 -192s86 -192 192 -192s192 86 192 192c0 29 -7 57 -19 83c26 -12 54 -19 83 -19c106 0 192 86 192 192zM1683 320c0 -23 -92 -115 -115 -115
+c-26 0 -107 94 -128 115l-96 -96l220 -220c18 -18 28 -43 28 -68c0 -56 -64 -120 -120 -120c-25 0 -50 10 -68 28l-671 671c-105 -78 -233 -131 -365 -131c-218 0 -368 151 -368 368c0 328 328 656 656 656c217 0 368 -150 368 -368c0 -132 -53 -260 -131 -365l355 -355
+l96 96c-21 21 -115 102 -115 128c0 23 92 115 115 115c8 0 17 -4 23 -10c37 -37 316 -300 316 -329z" />
+ <glyph glyph-name="syncthing" unicode="&#xf311;"
+d="M768 1408c424 0 768 -344 768 -768s-344 -768 -768 -768s-768 344 -768 768s344 768 768 768zM774 1254c-337 0 -611 -274 -611 -611c0 -10 0 -28 1 -38c-17 -10 -32 -23 -42 -41c-33 -56 -14 -128 41 -161c18 -10 37 -15 56 -16c97 -210 309 -355 555 -355
+c108 0 210 28 298 78c16 -11 35 -19 56 -21c65 -5 122 42 129 107v10c0 14 -5 36 -11 49c87 105 139 241 139 388c0 57 -8 112 -23 164c14 13 25 30 32 49c21 61 -12 128 -73 149c-12 4 -26 6 -38 6v0c-6 0 -15 0 -21 -1c-112 148 -289 244 -488 244zM774 1175v0
+c171 0 323 -79 420 -204c-10 -11 -17 -24 -22 -39c-9 -27 -8 -55 1 -80l-224 -186c-18 11 -39 16 -60 16c-22 0 -44 -5 -63 -18c-26 -16 -43 -42 -50 -70l-447 -41c-10 21 -25 39 -46 52c-13 8 -27 12 -41 14c0 8 -1 16 -1 24c0 295 238 532 533 532zM1224 792
+c6 -3 15 -7 21 -9c15 -5 29 -8 44 -7c11 -43 17 -87 17 -133c0 -125 -42 -240 -114 -331c-13 7 -28 11 -43 13c-15 1 -28 0 -42 -4l-122 175c23 32 29 73 15 110zM783 516c2 -4 5 -11 8 -15c29 -44 81 -63 129 -50l122 -175c-12 -16 -19 -37 -21 -59v-9c0 -10 2 -26 5 -35
+c-75 -40 -161 -63 -252 -63c-211 0 -394 123 -480 301c10 8 24 22 30 33c5 8 11 22 13 31z" />
+ <glyph glyph-name="picture-o" unicode="&#xf03e;" horiz-adv-x="1920"
+d="M640 960c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600c-17 0 -32 -15 -32 -32v-1216c0 -17 15 -32 32 -32h1600c17 0 32 15 32 32v1216c0 17 -15 32 -32 32z
+M1920 1248v-1216c0 -88 -72 -160 -160 -160h-1600c-88 0 -160 72 -160 160v1216c0 88 72 160 160 160h1600c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="list-alt" unicode="&#xf022;" horiz-adv-x="1792"
+d="M384 352v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM384 608v-64c0 -17 -15 -32 -32 -32h-64c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM384 864v-64c0 -17 -15 -32 -32 -32h-64
+c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h64c17 0 32 -15 32 -32zM1536 352v-64c0 -17 -15 -32 -32 -32h-960c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h960c17 0 32 -15 32 -32zM1536 608v-64c0 -17 -15 -32 -32 -32h-960c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h960
+c17 0 32 -15 32 -32zM1536 864v-64c0 -17 -15 -32 -32 -32h-960c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h960c17 0 32 -15 32 -32zM1664 160v832c0 17 -15 32 -32 32h-1472c-17 0 -32 -15 -32 -32v-832c0 -17 15 -32 32 -32h1472c17 0 32 15 32 32zM1792 1248v-1088
+c0 -88 -72 -160 -160 -160h-1472c-88 0 -160 72 -160 160v1088c0 88 72 160 160 160h1472c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="fort-awesome" unicode="&#xf286;" horiz-adv-x="1664"
+d="M640 528v224c0 9 -7 16 -16 16h-96c-9 0 -16 -7 -16 -16v-224c0 -9 7 -16 16 -16h96c9 0 16 7 16 16zM1152 528v224c0 9 -7 16 -16 16h-96c-9 0 -16 -7 -16 -16v-224c0 -9 7 -16 16 -16h96c9 0 16 7 16 16zM1664 496v-752h-640v320c0 106 -86 192 -192 192
+s-192 -86 -192 -192v-320h-640v752c0 9 7 16 16 16h96c9 0 16 -7 16 -16v-112h128v624c0 9 7 16 16 16h96c9 0 16 -7 16 -16v-112h128v112c0 9 7 16 16 16h96c9 0 16 -7 16 -16v-112h128v112c0 21 28 16 41 16v391c-19 9 -32 29 -32 50c0 30 25 55 55 55s55 -25 55 -55
+c0 -21 -13 -41 -32 -50v-17c27 6 55 10 83 10c41 0 80 -15 114 -15c31 0 66 15 84 15c9 0 16 -7 16 -16v-210c0 -24 -81 -28 -97 -28c-37 0 -72 15 -110 15c-30 0 -61 -5 -90 -12v-133c13 0 41 5 41 -16v-112h128v112c0 9 7 16 16 16h96c9 0 16 -7 16 -16v-112h128v112
+c0 9 7 16 16 16h96c9 0 16 -7 16 -16v-624h128v112c0 9 7 16 16 16h96c9 0 16 -7 16 -16z" />
+ <glyph glyph-name="c" unicode="&#xf31c;" horiz-adv-x="1404"
+d="M996 819c0 0 -23 211 -232 217s-317 -157 -317 -392s119 -423 323 -423s226 235 226 235l391 -24s22 -211 -141 -373s-364 -188 -504 -187s-334 -2 -522 190s-220 379 -220 563s36 427 259 611c152 125 306 172 460 172c643 0 685 -593 685 -593l-408 4v0z" />
+ <glyph glyph-name="commenting" unicode="&#xf27a;" horiz-adv-x="1792"
+d="M640 640c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM1024 640c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM1408 640c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128z
+M1792 640c0 -354 -401 -640 -896 -640c-73 0 -144 6 -211 18c-114 -114 -263 -192 -435 -229c-27 -5 -56 -10 -86 -13c-16 -2 -31 9 -35 24c-4 16 8 26 20 37c63 59 138 106 164 317c-191 117 -313 291 -313 486c0 354 401 640 896 640s896 -286 896 -640z" />
+ <glyph glyph-name="tablet" unicode="&#xf10a;" horiz-adv-x="1152"
+d="M640 128c0 35 -29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64s64 29 64 64zM1024 288v960c0 17 -15 32 -32 32h-832c-17 0 -32 -15 -32 -32v-960c0 -17 15 -32 32 -32h832c17 0 32 15 32 32zM1152 1248v-1088c0 -88 -72 -160 -160 -160h-832c-88 0 -160 72 -160 160v1088
+c0 88 72 160 160 160h832c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="credit-card" unicode="&#xf09d;" horiz-adv-x="1920"
+d="M1760 1408c88 0 160 -72 160 -160v-1216c0 -88 -72 -160 -160 -160h-1600c-88 0 -160 72 -160 160v1216c0 88 72 160 160 160h1600zM160 1280c-17 0 -32 -15 -32 -32v-224h1664v224c0 17 -15 32 -32 32h-1600zM1760 0c17 0 32 15 32 32v608h-1664v-608
+c0 -17 15 -32 32 -32h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" />
+ <glyph glyph-name="minus" unicode="&#xf068;" horiz-adv-x="1408"
+d="M1408 800v-192c0 -53 -43 -96 -96 -96h-1216c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h1216c53 0 96 -43 96 -96z" />
+ <glyph glyph-name="unlock-alt" unicode="&#xf13e;" horiz-adv-x="1152"
+d="M1056 768c53 0 96 -43 96 -96v-576c0 -53 -43 -96 -96 -96h-960c-53 0 -96 43 -96 96v576c0 53 43 96 96 96h32v320c0 247 201 448 448 448s448 -201 448 -448c0 -35 -29 -64 -64 -64h-64c-35 0 -64 29 -64 64c0 141 -115 256 -256 256s-256 -115 -256 -256v-320h736z
+" />
+ <glyph glyph-name="ils" unicode="&#xf20b;" horiz-adv-x="1376"
+d="M992 912v-496c0 -18 -14 -32 -32 -32h-160c-18 0 -32 14 -32 32v496c0 150 -122 272 -272 272h-272v-1152c0 -18 -14 -32 -32 -32h-160c-18 0 -32 14 -32 32v1344c0 18 14 32 32 32h464c274 0 496 -222 496 -496zM1376 1376v-880c0 -274 -222 -496 -496 -496h-464
+c-18 0 -32 14 -32 32v960c0 18 14 32 32 32h160c18 0 32 -14 32 -32v-768h272c150 0 272 122 272 272v880c0 18 14 32 32 32h160c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="cog" unicode="&#xf013;"
+d="M1024 640c0 141 -115 256 -256 256s-256 -115 -256 -256s115 -256 256 -256s256 115 256 256zM1536 749v-222c0 -15 -12 -33 -28 -36l-185 -28c-11 -32 -23 -62 -39 -91c34 -49 70 -93 107 -138c6 -7 10 -16 10 -25s-3 -16 -9 -23c-24 -32 -159 -179 -193 -179
+c-9 0 -18 4 -26 9l-138 108c-29 -15 -60 -28 -91 -38c-7 -61 -13 -126 -29 -186c-4 -16 -18 -28 -36 -28h-222c-18 0 -34 13 -36 30l-28 184c-31 10 -61 22 -90 37l-141 -107c-7 -6 -16 -9 -25 -9s-18 4 -25 11c-53 48 -123 110 -165 168c-5 7 -7 15 -7 23c0 9 3 16 8 23
+c34 46 71 90 105 137c-17 32 -31 65 -41 99l-183 27c-17 3 -29 19 -29 36v222c0 15 12 33 27 36l186 28c10 32 23 62 39 92c-34 48 -70 93 -107 138c-6 7 -10 15 -10 24s4 16 9 23c24 33 159 179 193 179c9 0 18 -4 26 -10l138 -107c29 15 60 28 91 38c7 61 13 126 29 186
+c4 16 18 28 36 28h222c18 0 34 -13 36 -30l28 -184c31 -10 61 -22 90 -37l142 107c6 6 15 9 24 9s18 -4 25 -10c53 -49 123 -111 165 -170c5 -6 7 -14 7 -22c0 -9 -3 -16 -8 -23c-34 -46 -71 -90 -105 -137c17 -32 31 -65 41 -98l183 -28c17 -3 29 -19 29 -36z" />
+ <glyph glyph-name="arrow-right" unicode="&#xf061;" horiz-adv-x="1472"
+d="M1472 576c0 -34 -13 -67 -37 -91l-651 -651c-24 -23 -57 -37 -91 -37s-66 14 -90 37l-75 75c-24 24 -38 57 -38 91s14 67 38 91l293 293h-704c-72 0 -117 60 -117 128v128c0 68 45 128 117 128h704l-293 294c-24 23 -38 56 -38 90s14 67 38 90l75 75c24 24 56 38 90 38
+s67 -14 91 -38l651 -651c24 -23 37 -56 37 -90z" />
+ <glyph glyph-name="cc-paypal" unicode="&#xf1f4;" horiz-adv-x="2304"
+d="M745 630c0 -49 -39 -86 -88 -86c-37 0 -64 21 -64 60c0 49 38 88 87 88c37 0 65 -23 65 -62zM1530 779c0 -60 -36 -72 -88 -72l-32 -1l17 107c1 7 6 11 13 11h18c34 0 72 -2 72 -45zM1881 630c0 -49 -39 -86 -87 -86c-37 0 -65 21 -65 60c0 49 38 88 87 88
+c37 0 65 -23 65 -62zM513 801c0 84 -65 112 -139 112h-160c-10 0 -20 -8 -21 -19l-65 -408c-1 -8 5 -16 13 -16h76c11 0 21 8 22 19l18 110c4 29 53 19 72 19c114 0 184 68 184 183zM822 489l41 261c1 8 -5 16 -13 16h-76c-15 0 -16 -22 -17 -33c-23 34 -57 40 -95 40
+c-98 0 -173 -86 -173 -181c0 -78 49 -129 127 -129c36 0 81 16 106 44c-2 -6 -4 -15 -4 -21c0 -9 4 -16 13 -16h69c11 0 20 8 22 19zM1269 752c0 7 -6 14 -13 14h-77c-7 0 -14 -4 -18 -10l-106 -156l-44 150c-3 9 -12 16 -22 16h-75c-7 0 -13 -7 -13 -14
+c0 -5 78 -231 85 -252c-11 -15 -82 -108 -82 -120c0 -7 6 -13 13 -13h77c7 0 14 4 18 10l255 368c2 2 2 4 2 7zM1649 801c0 84 -65 112 -139 112h-159c-11 0 -21 -8 -22 -19l-65 -408c-1 -8 5 -16 13 -16h82c8 0 14 6 16 13l18 116c4 29 53 19 72 19c114 0 184 68 184 183z
+M1958 489l41 261c1 8 -5 16 -13 16h-76c-15 0 -16 -22 -17 -33c-22 34 -56 40 -95 40c-98 0 -173 -86 -173 -181c0 -78 49 -129 127 -129c37 0 82 16 106 44c-1 -6 -4 -15 -4 -21c0 -9 4 -16 13 -16h69c11 0 20 8 22 19zM2176 898v1c0 8 -6 14 -13 14h-74
+c-6 0 -12 -5 -13 -11l-65 -416l-1 -2c0 -7 6 -14 14 -14h66c10 0 20 8 21 19zM392 764c-8 -51 -42 -57 -86 -57l-33 -1l17 107c1 7 7 11 13 11h19c45 0 79 -6 70 -60zM2304 1280v-1280c0 -70 -58 -128 -128 -128h-2048c-70 0 -128 58 -128 128v1280c0 70 58 128 128 128
+h2048c70 0 128 -58 128 -128z" />
+ <glyph glyph-name="birthday-cake" unicode="&#xf1fd;" horiz-adv-x="1792"
+d="M1792 128v-384h-1792v384c98 0 150 44 191 79c34 30 57 49 108 49s73 -19 108 -49c41 -35 92 -79 191 -79c98 0 149 44 191 79c34 30 56 49 107 49s74 -19 108 -49c41 -35 93 -79 191 -79s150 44 191 79c34 30 57 49 108 49c50 0 73 -19 107 -49c41 -35 93 -79 191 -79z
+M1792 448v-192c-51 0 -73 19 -108 49c-41 35 -92 79 -190 79c-99 0 -150 -44 -191 -79c-35 -30 -57 -49 -108 -49s-74 19 -108 49c-41 35 -92 79 -191 79c-98 0 -149 -44 -191 -79c-34 -30 -56 -49 -107 -49s-74 19 -108 49c-41 35 -93 79 -191 79c-99 0 -150 -44 -191 -79
+c-34 -30 -57 -49 -108 -49v192c0 106 86 192 192 192h64v448h256v-448h256v448h256v-448h256v448h256v-448h64c106 0 192 -86 192 -192zM512 1312c0 -106 -57 -160 -128 -160s-128 57 -128 128c0 124 128 92 128 256c48 0 128 -118 128 -224zM1024 1312
+c0 -106 -57 -160 -128 -160s-128 57 -128 128c0 124 128 92 128 256c48 0 128 -118 128 -224zM1536 1312c0 -106 -57 -160 -128 -160s-128 57 -128 128c0 124 128 92 128 256c48 0 128 -118 128 -224z" />
+ <glyph glyph-name="comment" unicode="&#xf075;" horiz-adv-x="1792"
+d="M1792 640c0 -354 -401 -640 -896 -640c-49 0 -98 3 -145 8c-131 -116 -287 -198 -460 -242c-36 -10 -75 -17 -114 -22c-22 -2 -43 14 -48 38v1c-5 25 12 40 27 58c63 71 135 131 182 298c-206 117 -338 298 -338 501c0 353 401 640 896 640s896 -286 896 -640z" />
+ <glyph glyph-name="bell" unicode="&#xf0f3;" horiz-adv-x="1664"
+d="M848 -160c0 9 -7 16 -16 16c-79 0 -144 65 -144 144c0 9 -7 16 -16 16s-16 -7 -16 -16c0 -97 79 -176 176 -176c9 0 16 7 16 16zM182 128h1300c-179 202 -266 476 -266 832c0 129 -122 320 -384 320s-384 -191 -384 -320c0 -356 -87 -630 -266 -832zM1664 128
+c0 -70 -58 -128 -128 -128h-448c0 -141 -115 -256 -256 -256s-256 115 -256 256h-448c-70 0 -128 58 -128 128c148 125 320 349 320 832c0 192 159 402 424 441c-5 12 -8 25 -8 39c0 53 43 96 96 96s96 -43 96 -96c0 -14 -3 -27 -8 -39c265 -39 424 -249 424 -441
+c0 -483 172 -707 320 -832z" />
+ <glyph glyph-name="cc" unicode="&#xf20a;" horiz-adv-x="2048"
+d="M785 528h207c-19 -211 -140 -339 -313 -339c-216 0 -347 166 -347 432c0 264 144 429 326 429c200 0 312 -124 329 -334h-203c-7 85 -49 134 -117 134c-75 0 -120 -80 -120 -238c0 -115 20 -223 129 -223c69 0 101 60 109 139zM1497 528h206
+c-19 -211 -139 -339 -312 -339c-216 0 -347 166 -347 432c0 264 144 429 326 429c200 0 312 -124 329 -334h-204c-6 85 -49 134 -116 134c-75 0 -120 -80 -120 -238c0 -115 19 -223 128 -223c69 0 102 60 110 139zM1856 647c0 268 -14 384 -76 468c-13 17 -34 28 -51 40
+c-63 46 -356 63 -697 63s-648 -17 -710 -63c-18 -13 -40 -23 -53 -40c-62 -83 -75 -200 -75 -468c0 -269 14 -385 75 -468c14 -19 35 -27 53 -41c62 -46 369 -65 710 -65s634 18 697 65c17 13 39 21 51 41c63 82 76 199 76 468zM2048 1408v-1536h-2048v1536h2048z" />
+ <glyph glyph-name="get-pocket" unicode="&#xf265;" horiz-adv-x="1720"
+d="M1565 1408c87 0 155 -70 155 -156v-519c0 -479 -383 -861 -859 -861c-478 0 -861 382 -861 861v519c0 85 71 156 156 156h1409zM861 344c30 0 60 12 82 33l404 388c23 22 37 53 37 85c0 65 -53 118 -118 118c-31 0 -60 -12 -82 -33l-323 -310l-323 310
+c-22 21 -51 33 -81 33c-65 0 -118 -53 -118 -118c0 -32 13 -63 36 -85l405 -388c21 -21 51 -33 81 -33z" />
+ <glyph glyph-name="bell-slash-o" unicode="&#xf1f7;" horiz-adv-x="2019"
+d="M1026 -160c0 9 -7 16 -16 16c-79 0 -144 65 -144 144c0 9 -7 16 -16 16s-16 -7 -16 -16c0 -97 79 -176 176 -176c9 0 16 7 16 16zM489 315l877 760c-50 105 -166 205 -356 205c-262 0 -384 -191 -384 -320c0 -256 -45 -470 -137 -645zM1842 128c0 -70 -58 -128 -128 -128
+h-448c0 -141 -115 -256 -256 -256s-255 114 -256 255l149 129h757c-111 125 -186 277 -227 459l111 97c51 -298 182 -458 298 -556zM1928 1520l84 -96c11 -14 10 -34 -3 -46l-1872 -1622c-13 -11 -34 -10 -45 4l-84 96c-11 14 -10 34 3 45l186 161c-12 20 -19 42 -19 66
+c148 125 320 349 320 832c0 192 159 402 424 441c-5 12 -8 25 -8 39c0 53 43 96 96 96s96 -43 96 -96c0 -14 -3 -27 -8 -39c172 -25 299 -122 367 -240l418 363c13 11 34 10 45 -4z" />
+ <glyph glyph-name="header" unicode="&#xf1dc;" horiz-adv-x="1668"
+d="M1620 -128c-88 0 -177 7 -266 7c-88 0 -176 -7 -264 -7c-34 0 -50 37 -50 66c0 89 100 51 152 85c33 21 33 105 33 140l-1 391c0 11 0 21 -1 31c-16 5 -34 4 -50 4h-675c-17 0 -35 1 -51 -4c-1 -10 -1 -20 -1 -31l-1 -371c0 -38 0 -142 37 -164c52 -32 170 13 170 -77
+c0 -30 -14 -70 -49 -70c-93 0 -186 7 -278 7c-85 0 -170 -7 -255 -7c-33 0 -48 38 -48 66c0 87 92 51 141 85c32 22 33 108 33 143l-1 57v813c0 48 7 202 -38 229c-50 31 -157 -17 -157 73c0 29 13 70 48 70c92 0 185 -7 277 -7c84 0 169 7 253 7c36 0 50 -40 50 -70
+c0 -86 -99 -44 -148 -75c-35 -21 -35 -124 -35 -160l1 -320c0 -11 0 -21 1 -32c13 -3 26 -3 39 -3h699c12 0 25 0 38 3c1 11 1 21 1 32l1 320c0 37 0 139 -35 160c-50 30 -150 -10 -150 75c0 30 14 70 50 70c88 0 176 -7 264 -7c86 0 172 7 258 7c36 0 50 -40 50 -70
+c0 -87 -103 -43 -153 -74c-34 -22 -35 -125 -35 -161l1 -943c0 -33 2 -120 34 -140c51 -32 159 9 159 -78c0 -29 -13 -70 -48 -70z" />
+ <glyph glyph-name="bluetooth-b" unicode="&#xf294;" horiz-adv-x="944"
+d="M556 113l173 172l-173 172v-344zM556 823l173 172l-173 172v-344zM588 640l356 -356l-539 -540v711l-297 -296l-108 108l372 373l-372 373l108 108l297 -296v711l539 -540z" />
+ <glyph glyph-name="linux" unicode="&#xf17c;" horiz-adv-x="1523"
+d="M657 1125c-20 -2 -13 -20 -24 -20c-10 -1 -8 22 24 20zM744 1111c-10 -3 -11 16 -29 11c29 13 39 -7 29 -11zM393 684c-9 3 -7 -15 -16 -29c-7 -13 -25 -23 -11 -25c5 -1 19 11 25 25c5 17 10 26 2 29zM1248 325c0 18 -39 35 -55 42c27 90 15 126 -3 211
+c-14 64 -73 151 -119 178c12 -10 34 -39 57 -83c40 -75 80 -186 54 -278c-10 -36 -34 -41 -50 -42c-70 -8 -29 84 -58 209c-33 140 -67 150 -75 161c-41 182 -86 164 -99 232c-11 61 53 111 -34 128c-27 5 -65 32 -80 34s-23 101 33 104c55 4 65 -62 55 -88
+c-16 -26 1 -36 28 -27c22 7 8 65 13 73c-14 84 -49 96 -85 103c-138 -11 -76 -163 -90 -149c-20 21 -78 2 -78 15c1 78 -25 123 -61 124c-40 1 -56 -55 -58 -87c-3 -30 17 -93 32 -88c10 3 27 23 9 22c-9 0 -23 22 -25 48c-1 26 9 52 43 51c39 -1 39 -79 35 -82
+c-13 -9 -29 -26 -31 -29c-13 -21 -38 -27 -48 -36c-17 -18 -21 -38 -8 -45c46 -26 31 -56 95 -58c42 -2 73 6 102 15c22 7 93 22 108 48c7 11 15 11 20 8c10 -5 12 -24 -13 -30c-35 -10 -70 -29 -102 -41c-31 -13 -41 -18 -70 -23c-66 -12 -115 24 -71 -19
+c15 -14 29 -23 67 -22c84 3 177 104 186 59c2 -10 -26 -22 -48 -33c-78 -38 -133 -114 -183 -88c-45 24 -90 135 -89 85c1 -77 -101 -145 -54 -233c-31 -8 -100 -155 -110 -231c-6 -44 4 -98 -7 -128c-15 -44 -83 42 -61 147c4 18 0 22 -5 13c-27 -49 -12 -118 10 -166
+c9 -21 32 -30 49 -48c35 -40 173 -142 197 -167c31 -29 22 -97 -42 -104c33 -62 65 -68 64 -169c38 20 23 64 7 92c-11 20 -25 29 -22 34c2 3 22 20 33 7c34 -38 98 -45 166 -36c69 8 143 32 177 87c16 26 27 35 34 30c8 -4 11 -22 10 -52c-1 -32 -14 -65 -23 -92
+c-9 -31 -12 -52 18 -53c8 56 24 111 28 167c5 64 -41 182 9 241c13 16 29 18 51 18c3 80 126 74 167 41zM620 1152c4 25 -8 43 -14 45c-12 3 -10 -15 -4 -13c4 0 9 -6 7 -15c-2 -12 -1 -20 8 -20c1 0 3 0 3 3zM1039 955c-4 19 -18 12 -34 22c-19 12 -23 32 -30 25
+c-21 -23 26 -71 46 -75c12 -2 21 14 18 28zM861 1168c1 24 -20 36 -25 35c-13 -1 -9 -7 -3 -9c8 -2 16 -16 18 -31c0 -2 10 2 10 5zM915 1401c1 5 -12 11 -21 18c-8 8 -16 15 -24 15c-20 -2 -10 -23 -13 -33c-4 -11 -19 -20 -9 -28c9 -7 15 11 34 18c5 2 28 -1 33 10z
+M1480 60c123 -76 -46 -139 -119 -176c-57 -29 -133 -93 -161 -120c-21 -20 -108 -30 -157 -5c-57 29 -27 75 -115 78c-44 1 -87 1 -130 1c-38 -1 -76 -3 -115 -4c-132 -3 -145 -88 -230 -85c-58 2 -131 48 -257 74c-88 18 -173 23 -191 62s22 83 25 121c3 51 -38 120 -8 146
+c26 23 81 6 117 26c38 22 54 39 54 86c14 -48 -1 -87 -32 -106c-19 -12 -54 -18 -83 -15c-23 2 -37 -1 -43 -10c-9 -11 -6 -31 5 -57s24 -43 22 -75c-1 -32 -37 -70 -31 -97c2 -10 12 -19 37 -26c40 -11 113 -22 184 -39c79 -20 161 -56 212 -49c152 21 65 184 41 223
+c-129 202 -214 334 -282 282c-17 -14 -18 34 -17 53c3 66 36 90 56 141c38 97 67 208 125 265c43 56 111 147 124 195c-11 104 -14 214 -16 310c-2 103 14 193 130 256c28 15 65 21 104 21c69 1 146 -19 195 -55c78 -58 127 -181 121 -269c-4 -69 8 -140 30 -214
+c26 -87 67 -148 133 -218c79 -84 141 -249 159 -354c16 -98 -6 -159 -27 -162c-32 -5 -52 -106 -152 -102c-64 3 -70 41 -88 74c-29 51 -58 35 -69 -19c-6 -27 -2 -67 7 -97c18 -63 12 -122 1 -195c-21 -138 97 -164 176 -98c78 65 95 75 193 109c149 51 99 96 19 123
+c-72 24 -75 145 -49 168c6 -130 74 -149 102 -167z" />
+ <glyph glyph-name="table" unicode="&#xf0ce;" horiz-adv-x="1664"
+d="M512 160v192c0 18 -14 32 -32 32h-320c-18 0 -32 -14 -32 -32v-192c0 -18 14 -32 32 -32h320c18 0 32 14 32 32zM512 544v192c0 18 -14 32 -32 32h-320c-18 0 -32 -14 -32 -32v-192c0 -18 14 -32 32 -32h320c18 0 32 14 32 32zM1024 160v192c0 18 -14 32 -32 32h-320
+c-18 0 -32 -14 -32 -32v-192c0 -18 14 -32 32 -32h320c18 0 32 14 32 32zM512 928v192c0 18 -14 32 -32 32h-320c-18 0 -32 -14 -32 -32v-192c0 -18 14 -32 32 -32h320c18 0 32 14 32 32zM1024 544v192c0 18 -14 32 -32 32h-320c-18 0 -32 -14 -32 -32v-192
+c0 -18 14 -32 32 -32h320c18 0 32 14 32 32zM1536 160v192c0 18 -14 32 -32 32h-320c-18 0 -32 -14 -32 -32v-192c0 -18 14 -32 32 -32h320c18 0 32 14 32 32zM1024 928v192c0 18 -14 32 -32 32h-320c-18 0 -32 -14 -32 -32v-192c0 -18 14 -32 32 -32h320c18 0 32 14 32 32z
+M1536 544v192c0 18 -14 32 -32 32h-320c-18 0 -32 -14 -32 -32v-192c0 -18 14 -32 32 -32h320c18 0 32 14 32 32zM1536 928v192c0 18 -14 32 -32 32h-320c-18 0 -32 -14 -32 -32v-192c0 -18 14 -32 32 -32h320c18 0 32 14 32 32zM1664 1248v-1088c0 -88 -72 -160 -160 -160
+h-1344c-88 0 -160 72 -160 160v1088c0 88 72 160 160 160h1344c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="handshake-o" unicode="&#xf2b5;" horiz-adv-x="2304"
+d="M192 384c84 0 84 128 0 128s-84 -128 0 -128zM1665 442c-79 103 -156 208 -246 302l-125 -140c-110 -125 -307 -122 -414 6c-76 92 -76 224 2 315l177 206c-62 32 -137 21 -204 21c-59 0 -116 -24 -158 -66l-158 -158h-155v-544c44 0 84 6 119 -28l297 -292
+c61 -59 140 -111 227 -111c45 0 93 15 125 47c75 -26 162 16 185 93c48 -4 92 11 127 44c23 21 53 63 50 96c9 -9 31 -10 43 -10c119 0 181 125 108 219zM1824 384h96v512h-93l-157 180c-42 48 -105 76 -169 76h-167c-56 0 -110 -25 -146 -67l-209 -243
+c-37 -44 -37 -106 -1 -150c57 -68 162 -69 221 -3l193 218c46 51 130 3 109 -62c38 -44 79 -87 116 -131c50 -62 98 -127 147 -190c31 -40 54 -88 60 -140zM2112 384c84 0 84 128 0 128s-84 -128 0 -128zM2304 960v-640c0 -35 -29 -64 -64 -64h-434
+c-36 -87 -115 -145 -207 -158c-43 -63 -109 -111 -183 -127c-55 -70 -144 -112 -233 -106c-165 -93 -351 -12 -474 109l-287 282h-358c-35 0 -64 29 -64 64v672c0 35 29 64 64 64h421c116 116 196 224 370 224h117c65 0 128 -20 181 -56c53 36 116 56 181 56h167
+c190 0 269 -124 384 -256h355c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="spinner" unicode="&#xf110;" horiz-adv-x="1664"
+d="M462 142c0 -70 -57 -128 -128 -128c-70 0 -128 58 -128 128c0 71 58 128 128 128c71 0 128 -57 128 -128zM960 -64c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128s128 -57 128 -128zM256 640c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128
+s128 -57 128 -128zM1458 142c0 -70 -58 -128 -128 -128c-71 0 -128 58 -128 128c0 71 57 128 128 128c70 0 128 -57 128 -128zM494 1138c0 -88 -72 -160 -160 -160s-160 72 -160 160s72 160 160 160s160 -72 160 -160zM1664 640c0 -71 -57 -128 -128 -128s-128 57 -128 128
+s57 128 128 128s128 -57 128 -128zM1024 1344c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192zM1554 1138c0 -124 -101 -224 -224 -224c-124 0 -224 100 -224 224c0 123 100 224 224 224c123 0 224 -101 224 -224z" />
+ <glyph glyph-name="snapchat" unicode="&#xf2ab;"
+d="M1279 388c0 14 -8 24 -22 27c-91 20 -160 83 -198 167c-3 8 -7 16 -7 25c0 45 125 36 125 100c0 27 -33 44 -57 44c-23 0 -41 -16 -63 -16c-4 0 -8 1 -12 2c2 38 5 76 5 114c0 35 -2 83 -17 114c-48 104 -141 165 -255 165c-125 0 -220 -46 -275 -165
+c-15 -31 -17 -79 -17 -114c0 -38 3 -76 5 -114c-4 -2 -9 -2 -14 -2c-23 0 -41 15 -62 15c-25 0 -56 -16 -56 -44c0 -62 125 -54 125 -99c0 -9 -4 -17 -7 -25c-39 -84 -106 -147 -198 -167c-14 -3 -22 -13 -22 -27c0 -46 106 -63 137 -68c9 -24 5 -66 41 -66c25 0 50 9 77 9
+c105 0 133 -95 255 -95c127 0 151 95 257 95c27 0 52 -8 78 -8c35 0 31 42 40 65c31 5 137 22 137 68zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="tint" unicode="&#xf043;" horiz-adv-x="1024"
+d="M512 384c0 25 -8 49 -20 69c-13 20 -66 88 -87 155c-3 11 -13 16 -21 16s-18 -5 -21 -16c-21 -67 -74 -135 -87 -155c-12 -20 -20 -44 -20 -69c0 -71 57 -128 128 -128s128 57 128 128zM1024 512c0 -283 -229 -512 -512 -512s-512 229 -512 512c0 101 31 195 81 275
+c51 80 265 351 346 621c13 43 53 64 85 64s73 -21 85 -64c81 -270 295 -541 346 -621s81 -174 81 -275z" />
+ <glyph glyph-name="connectdevelop" unicode="&#xf20e;" horiz-adv-x="2048"
+d="M2048 641c0 -28 -20 -51 -46 -56l-205 -356c2 -6 3 -12 3 -18c0 -27 -19 -50 -45 -55l-193 -337c2 -5 3 -10 3 -16c0 -31 -25 -57 -57 -57c-16 0 -31 7 -41 18h-400c-10 -12 -26 -20 -43 -20s-33 8 -43 20h-399c-10 -12 -25 -20 -43 -20c-31 0 -57 25 -57 57
+c0 7 2 14 4 20l-193 335c-26 5 -45 28 -45 55c0 7 1 12 3 18l-206 356c-26 6 -45 29 -45 56c0 28 20 51 47 56l199 344c0 2 -1 4 -1 6c0 23 14 42 34 51l209 363c-2 5 -4 12 -4 18c0 32 26 57 57 57c18 0 33 -8 44 -21h396c10 13 25 21 43 21s33 -8 43 -21h398
+c11 13 26 21 44 21c31 0 57 -25 57 -57c0 -6 -2 -12 -4 -18l207 -358c30 -1 55 -26 55 -56c0 -10 -3 -19 -7 -27l187 -324c25 -5 44 -28 44 -55zM1063 -158h389l-342 354h-143l-342 -354h360c10 9 24 16 39 16s29 -7 39 -16zM112 654c1 -4 1 -8 1 -13s0 -10 -2 -15l208 -360
+c5 -1 10 -4 15 -6l188 199v347l-187 194c-9 -6 -19 -9 -29 -10zM986 1438h-388l190 -200l554 200h-280c-10 -10 -23 -16 -38 -16s-28 6 -38 16zM1689 226c1 4 3 8 5 11l-64 68l-17 -79h76zM1583 226l22 105l-252 266l-296 -307l63 -64h463zM1495 -142l16 28l65 310h-427
+l333 -343c4 2 8 4 13 5zM578 -158h5l342 354h-373v-335l4 -6c9 -3 16 -7 22 -13zM552 226h402l64 66l-309 321l-157 -166v-221zM359 226h163v189l-168 -177c2 -4 4 -8 5 -12zM358 1051c0 -1 1 -3 1 -4c0 -11 -3 -21 -8 -29l171 -177v269zM552 1121v-311l153 -157l297 314
+l-223 236zM556 1425l-4 -8v-264l205 74l-191 201c-3 -1 -6 -2 -10 -3zM1447 1438h-16l-621 -224l213 -225zM1023 946l-297 -315l311 -319l296 307zM688 634l-136 141v-284zM1038 270l-42 -44h85zM1374 618l238 -251l132 624l-3 5l-1 1zM1718 1018c-5 8 -8 18 -8 29v2
+l-216 376c-5 1 -9 3 -13 5l-437 -463l310 -327zM522 1142v223l-163 -282zM522 196h-163l163 -283v283zM1607 196l-48 -227l130 227h-82zM1729 266l207 361c-1 5 -2 9 -2 14c0 6 2 11 3 16l-171 296l-129 -612l77 -82c5 3 10 5 15 7z" />
+ <glyph glyph-name="chrome" unicode="&#xf268;" horiz-adv-x="1792"
+d="M893 1536c153 1 309 -38 451 -120c157 -91 276 -222 352 -372l-742 39c-210 12 -410 -106 -479 -304l-276 424c172 214 430 332 694 333zM146 1131l337 -663c95 -187 296 -301 504 -262l-230 -451c-429 66 -757 437 -757 885c0 181 54 350 146 491zM1732 962
+c157 -404 0 -874 -388 -1098c-157 -91 -330 -128 -498 -119l405 623c115 177 113 408 -24 568zM896 942c167 0 302 -135 302 -302s-135 -302 -302 -302s-302 135 -302 302s135 302 302 302z" />
+ <glyph glyph-name="trademark" unicode="&#xf25c;" horiz-adv-x="1972"
+d="M857 992v-117c0 -17 -15 -31 -32 -31h-298v-812c0 -18 -14 -32 -31 -32h-135c-18 0 -32 14 -32 32v812h-297c-18 0 -32 14 -32 31v117c0 18 14 32 32 32h793c17 0 32 -14 32 -32zM1895 995l77 -961c1 -9 -2 -17 -8 -24c-6 -6 -14 -10 -23 -10h-134c-16 0 -30 13 -31 29
+l-46 588l-189 -425c-5 -12 -16 -19 -29 -19h-120c-12 0 -23 7 -29 19l-188 427l-45 -590c-1 -16 -15 -29 -31 -29h-135c-9 0 -17 4 -23 10c-6 7 -9 15 -9 24l78 961c1 16 15 29 31 29h142c13 0 24 -8 29 -19l220 -520c7 -16 14 -34 20 -51c7 17 13 35 20 51l221 520
+c5 11 16 19 29 19h141c17 0 31 -13 32 -29z" />
+ <glyph glyph-name="align-right" unicode="&#xf038;" horiz-adv-x="1792"
+d="M1792 192v-128c0 -35 -29 -64 -64 -64h-1664c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1664c35 0 64 -29 64 -64zM1792 576v-128c0 -35 -29 -64 -64 -64h-1280c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1280c35 0 64 -29 64 -64zM1792 960v-128
+c0 -35 -29 -64 -64 -64h-1536c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1536c35 0 64 -29 64 -64zM1792 1344v-128c0 -35 -29 -64 -64 -64h-1152c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h1152c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="bandcamp" unicode="&#xf2d5;" horiz-adv-x="1792"
+d="M1070 358l306 564h-654l-306 -564h654zM1792 640c0 -495 -401 -896 -896 -896s-896 401 -896 896s401 896 896 896s896 -401 896 -896z" />
+ <glyph glyph-name="long-arrow-down" unicode="&#xf175;" horiz-adv-x="767"
+d="M765 237c5 -12 3 -25 -5 -35l-350 -384c-6 -6 -14 -10 -23 -10s-18 4 -24 10l-355 384c-8 10 -10 23 -5 35c5 11 16 19 29 19h224v1248c0 18 14 32 32 32h192c18 0 32 -14 32 -32v-1248h224c13 0 24 -7 29 -19z" />
+ <glyph glyph-name="beer" unicode="&#xf0fc;" horiz-adv-x="1600"
+d="M576 640v384h-256v-256c0 -71 57 -128 128 -128h128zM1600 192v-192h-1152v192l128 192h-128c-212 0 -384 172 -384 384v320l-64 64l32 128h480l32 128h960l32 -192l-64 -32v-800z" />
+ <glyph glyph-name="th-list" unicode="&#xf00b;" horiz-adv-x="1792"
+d="M512 288v-192c0 -53 -43 -96 -96 -96h-320c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h320c53 0 96 -43 96 -96zM512 800v-192c0 -53 -43 -96 -96 -96h-320c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h320c53 0 96 -43 96 -96zM1792 288v-192c0 -53 -43 -96 -96 -96h-960
+c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h960c53 0 96 -43 96 -96zM512 1312v-192c0 -53 -43 -96 -96 -96h-320c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h320c53 0 96 -43 96 -96zM1792 800v-192c0 -53 -43 -96 -96 -96h-960c-53 0 -96 43 -96 96v192c0 53 43 96 96 96
+h960c53 0 96 -43 96 -96zM1792 1312v-192c0 -53 -43 -96 -96 -96h-960c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h960c53 0 96 -43 96 -96z" />
+ <glyph glyph-name="eraser" unicode="&#xf12d;" horiz-adv-x="1920"
+d="M896 128l336 384h-768l-336 -384h768zM1909 1205c20 -46 12 -99 -21 -137l-896 -1024c-24 -28 -59 -44 -96 -44h-768c-50 0 -96 29 -117 75c-20 46 -12 99 21 137l896 1024c24 28 59 44 96 44h768c50 0 96 -29 117 -75z" />
+ <glyph glyph-name="codepen" unicode="&#xf1cb;" horiz-adv-x="1792"
+d="M216 367l603 -402v359l-334 223zM154 511l193 129l-193 129v-258zM973 -35l603 402l-269 180l-334 -223v-359zM896 458l272 182l-272 182l-272 -182zM485 733l334 223v359l-603 -402zM1445 640l193 -129v258zM1307 733l269 180l-603 402v-359zM1792 913v-546
+c0 -25 -13 -50 -34 -64l-819 -546c-13 -8 -28 -13 -43 -13s-30 5 -43 13l-819 546c-21 14 -34 39 -34 64v546c0 25 13 50 34 64l819 546c13 8 28 13 43 13s30 -5 43 -13l819 -546c21 -14 34 -39 34 -64z" />
+ <glyph glyph-name="slideshare" unicode="&#xf1e7;" horiz-adv-x="1758"
+d="M856 796c0 -111 -97 -202 -216 -202s-216 91 -216 202c0 112 97 202 216 202s216 -90 216 -202zM1358 796c0 -111 -96 -202 -216 -202c-119 0 -216 91 -216 202c0 112 97 202 216 202c120 0 216 -90 216 -202zM1583 616v667c0 115 -37 160 -143 160h-1112
+c-111 0 -142 -38 -142 -160v-673c237 -124 440 -102 551 -98c47 1 77 -8 95 -27c3 -3 6 -6 10 -9c21 -20 41 -36 61 -51c4 55 35 90 118 87c113 -5 321 -27 562 104zM1746 621c-64 -79 -186 -176 -372 -252c197 -671 -481 -778 -470 -434c0 -6 -1 185 -1 327
+c-15 3 -30 7 -48 11c0 -143 -1 -344 -1 -338c11 -344 -667 -237 -470 434c-186 76 -308 173 -372 252c-32 48 3 99 56 62c7 -5 15 -10 22 -15v694c0 96 72 174 161 174h1257c89 0 161 -78 161 -174v-694l21 15c53 37 88 -14 56 -62z" />
+ <glyph glyph-name="square-o" unicode="&#xf096;" horiz-adv-x="1408"
+d="M1120 1280h-832c-88 0 -160 -72 -160 -160v-832c0 -88 72 -160 160 -160h832c88 0 160 72 160 160v832c0 88 -72 160 -160 160zM1408 1120v-832c0 -159 -129 -288 -288 -288h-832c-159 0 -288 129 -288 288v832c0 159 129 288 288 288h832c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="hourglass-start" unicode="&#xf251;"
+d="M1408 1408c0 -370 -177 -638 -373 -768c196 -130 373 -398 373 -768h96c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-1472c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h96c0 370 177 638 373 768c-196 130 -373 398 -373 768h-96c-18 0 -32 14 -32 32v64
+c0 18 14 32 32 32h1472c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-96zM1280 1408h-1024c0 -44 3 -87 9 -128h1006c6 41 9 84 9 128zM1280 -128c0 359 -198 624 -397 704h-230c-199 -80 -397 -345 -397 -704h1024z" />
+ <glyph glyph-name="superpowers" unicode="&#xf2dd;" horiz-adv-x="1792"
+d="M1473 607c18 320 -227 585 -544 604c-315 19 -594 -221 -612 -538c-18 -320 227 -585 545 -604c315 -19 594 220 611 538zM1792 1536l-349 -348c159 -155 245 -371 231 -593c-22 -372 -308 -669 -675 -719l-999 -132l347 347c-159 155 -244 371 -231 593
+c23 373 308 670 676 720c333 44 667 88 1000 132z" />
+ <glyph glyph-name="fire" unicode="&#xf06d;" horiz-adv-x="1408"
+d="M1408 -160v-64c0 -17 -15 -32 -32 -32h-1344c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h1344c17 0 32 -15 32 -32zM1152 896c0 -383 -448 -417 -448 -672c0 -70 35 -163 67 -224l-4 1l1 -1c-276 127 -512 302 -512 640c0 383 448 417 448 672c0 70 -35 163 -66 224l3 -1
+l-1 1c276 -127 512 -302 512 -640z" />
+ <glyph glyph-name="sellsy" unicode="&#xf213;" horiz-adv-x="2048"
+d="M1500 165v733c0 28 -23 51 -50 51h-93c-27 0 -50 -23 -50 -51v-733c0 -27 23 -50 50 -50h93c27 0 50 23 50 50zM1216 165v531c0 27 -23 50 -50 50h-101c-27 0 -50 -23 -50 -50v-531c0 -27 23 -50 50 -50h101c27 0 50 23 50 50zM924 165v429c0 27 -23 50 -50 50h-101
+c-27 0 -50 -23 -50 -50v-429c0 -27 23 -50 50 -50h101c27 0 50 23 50 50zM632 165v362c0 27 -23 50 -50 50h-101c-27 0 -50 -23 -50 -50v-362c0 -27 23 -50 50 -50h101c27 0 50 23 50 50zM2048 311c0 -222 -181 -402 -402 -402h-1244c-221 0 -402 180 -402 402
+c0 155 91 297 231 363c-7 24 -10 49 -10 73c0 151 123 274 274 274c66 0 130 -24 180 -67c60 244 280 417 532 417c302 0 548 -246 548 -548c0 -41 -4 -82 -14 -122c180 -44 307 -206 307 -390z" />
+ <glyph glyph-name="fast-forward" unicode="&#xf050;" horiz-adv-x="1792"
+d="M45 -115c-25 -25 -45 -16 -45 19v1472c0 35 20 44 45 19l710 -710c6 -6 10 -12 13 -19v710c0 35 20 44 45 19l710 -710c6 -6 10 -12 13 -19v678c0 35 29 64 64 64h128c35 0 64 -29 64 -64v-1408c0 -35 -29 -64 -64 -64h-128c-35 0 -64 29 -64 64v678
+c-3 -7 -7 -13 -13 -19l-710 -710c-25 -25 -45 -16 -45 19v710c-3 -7 -7 -13 -13 -19z" />
+ <glyph glyph-name="bell-slash" unicode="&#xf1f6;" horiz-adv-x="2019"
+d="M1544 684c51 -298 182 -458 298 -556c0 -70 -58 -128 -128 -128h-448c0 -141 -115 -256 -256 -256s-255 114 -256 255zM1010 -176c9 0 16 7 16 16s-7 16 -16 16c-79 0 -144 65 -144 144c0 9 -7 16 -16 16s-16 -7 -16 -16c0 -97 79 -176 176 -176zM2012 1424
+c11 -14 10 -34 -3 -46l-1872 -1622c-13 -11 -34 -10 -45 4l-84 96c-11 14 -10 34 3 45l186 161c-12 20 -19 42 -19 66c148 125 320 349 320 832c0 192 159 402 424 441c-5 12 -8 25 -8 39c0 53 43 96 96 96s96 -43 96 -96c0 -14 -3 -27 -8 -39c172 -25 299 -122 367 -240
+l418 363c13 11 34 10 45 -4z" />
+ <glyph glyph-name="cubes" unicode="&#xf1b3;" horiz-adv-x="2176"
+d="M640 -96l384 192v314l-384 -164v-342zM576 358l404 173l-404 173l-404 -173zM1664 -96l384 192v314l-384 -164v-342zM1600 358l404 173l-404 173l-404 -173zM1152 651l384 165v266l-384 -164v-267zM1088 1030l441 189l-441 189l-441 -189zM2176 512v-416
+c0 -48 -27 -93 -71 -114l-448 -224c-18 -10 -37 -14 -57 -14s-39 4 -57 14l-448 224c-3 1 -5 2 -7 4c-2 -2 -4 -3 -7 -4l-448 -224c-18 -10 -37 -14 -57 -14s-39 4 -57 14l-448 224c-44 21 -71 66 -71 114v416c0 51 31 97 78 118l434 186v400c0 51 31 97 78 118l448 192
+c16 7 33 10 50 10s34 -3 50 -10l448 -192c47 -21 78 -67 78 -118v-400l434 -186c48 -21 78 -67 78 -118z" />
+ <glyph glyph-name="inr" unicode="&#xf156;" horiz-adv-x="898"
+d="M898 1066v-102c0 -18 -14 -32 -32 -32h-168c-31 -192 -178 -317 -405 -344c149 -159 308 -351 459 -536c8 -9 10 -23 4 -34c-5 -11 -16 -18 -29 -18h-195c-10 0 -19 4 -25 12c-161 193 -309 370 -498 571c-6 6 -9 14 -9 22v127c0 17 14 32 32 32h112
+c176 0 286 59 315 168h-427c-18 0 -32 14 -32 32v102c0 18 14 32 32 32h413c-38 75 -128 113 -268 113h-145c-18 0 -32 15 -32 32v133c0 18 14 32 32 32h832c18 0 32 -14 32 -32v-102c0 -18 -14 -32 -32 -32h-233c32 -41 53 -89 64 -144h171c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="hashtag" unicode="&#xf292;" horiz-adv-x="1728"
+d="M959 512l64 256h-254l-64 -256h254zM1727 1016l-56 -224c-4 -14 -16 -24 -31 -24h-327l-64 -256h311c10 0 19 -5 25 -12c6 -8 9 -18 6 -28l-56 -224c-3 -14 -16 -24 -31 -24h-327l-81 -328c-4 -14 -17 -24 -31 -24h-224c-10 0 -20 5 -26 12c-6 8 -8 18 -6 28l78 312h-254
+l-81 -328c-4 -14 -17 -24 -31 -24h-225c-9 0 -19 5 -25 12c-6 8 -8 18 -6 28l78 312h-311c-10 0 -19 5 -25 12c-6 8 -8 18 -6 28l56 224c4 14 16 24 31 24h327l64 256h-311c-10 0 -19 5 -25 12c-6 8 -9 18 -6 28l56 224c3 14 16 24 31 24h327l81 328c4 14 17 24 32 24h224
+c9 0 19 -5 25 -12c6 -8 8 -18 6 -28l-78 -312h254l81 328c4 14 17 24 32 24h224c9 0 19 -5 25 -12c6 -8 8 -18 6 -28l-78 -312h311c10 0 19 -5 25 -12c6 -8 8 -18 6 -28z" />
+ <glyph glyph-name="file-text-o" unicode="&#xf0f6;"
+d="M1468 1156c37 -37 68 -111 68 -164v-1152c0 -53 -43 -96 -96 -96h-1344c-53 0 -96 43 -96 96v1600c0 53 43 96 96 96h896c53 0 127 -31 164 -68zM1024 1400v-376h376c-6 17 -15 34 -22 41l-313 313c-7 7 -24 16 -41 22zM1408 -128v1024h-416c-53 0 -96 43 -96 96v416
+h-768v-1536h1280zM384 736c0 18 14 32 32 32h704c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-704c-18 0 -32 14 -32 32v64zM1120 512c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-704c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h704zM1120 256c18 0 32 -14 32 -32
+v-64c0 -18 -14 -32 -32 -32h-704c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h704z" />
+ <glyph glyph-name="nextcloud" unicode="&#xf306;" horiz-adv-x="1792"
+d="M896 1049c225 0 409 -184 409 -409s-184 -409 -409 -409s-409 184 -409 409s184 409 409 409zM896 891c-139 0 -251 -112 -251 -251s112 -251 251 -251s251 112 251 251s-112 251 -251 251zM265 905c146 0 265 -119 265 -265s-119 -265 -265 -265s-265 119 -265 265
+s119 265 265 265zM265 748c-60 0 -107 -48 -107 -108s47 -108 107 -108s108 48 108 108s-48 108 -108 108zM1527 905c146 0 265 -119 265 -265s-119 -265 -265 -265s-265 119 -265 265s119 265 265 265zM1527 748c-60 0 -108 -48 -108 -108s48 -108 108 -108s107 48 107 108
+s-47 108 -107 108z" />
+ <glyph glyph-name="hand-o-left" unicode="&#xf0a5;" horiz-adv-x="1792"
+d="M1376 128h32v640h-32c-106 0 -177 90 -241 163c-41 46 -79 92 -112 145c-14 22 -26 45 -38 68s-62 136 -89 136c-85 0 -160 -32 -160 -128c0 -128 96 -193 96 -256h-576c-67 0 -128 -60 -128 -128c0 -69 59 -128 128 -128h331c-21 -24 -35 -71 -35 -103
+c0 -47 19 -87 53 -119c-12 -21 -18 -45 -18 -69c0 -46 23 -103 65 -126c-3 -18 -4 -37 -4 -56c0 -118 73 -167 184 -167c199 0 369 128 544 128zM1664 192c0 35 -29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64s64 29 64 64zM1792 768v-640c0 -71 -57 -128 -128 -128h-288
+c-63 0 -162 -37 -223 -59c-102 -37 -207 -69 -317 -69c-184 0 -318 104 -317 295l1 5c-40 50 -61 114 -61 178c0 14 1 29 3 43c-21 37 -34 77 -37 119h-169c-140 0 -256 117 -256 257c0 138 118 255 256 255h374c-15 41 -22 84 -22 128c0 169 129 256 288 256
+c134 0 177 -171 235 -264c30 -47 64 -88 100 -129c29 -33 97 -119 145 -119h288c71 0 128 -57 128 -128z" />
+ <glyph glyph-name="vimeo" unicode="&#xf27d;" horiz-adv-x="1628"
+d="M1627 1018c-7 -158 -118 -375 -332 -651c-222 -287 -408 -431 -562 -431c-95 0 -175 88 -240 263c-44 160 -88 321 -132 482c-48 175 -101 262 -157 262c-12 0 -54 -25 -127 -76l-77 98c80 71 159 143 238 212c106 94 187 141 241 146c127 12 204 -74 234 -259
+c31 -200 54 -325 66 -373c37 -166 76 -249 120 -249c34 0 85 53 154 161c68 108 104 190 109 246c9 93 -27 139 -109 139c-39 0 -79 -9 -121 -26c80 262 233 389 459 382c167 -5 246 -114 236 -326z" />
+ <glyph glyph-name="mastodon-alt" unicode="&#xf2e2;"
+d="M766 1408h5c211 -2 413 -25 531 -79c0 0 234 -105 234 -462c0 0 3 -263 -33 -446c-23 -116 -202 -243 -408 -268c-108 -13 -214 -25 -327 -20c-185 8 -330 45 -330 45c0 -18 1 -36 3 -52c24 -182 181 -193 329 -198c150 -5 284 37 284 37l6 -135s-105 -57 -292 -67
+c-103 -6 -230 3 -379 42c-323 85 -380 430 -388 779c-3 104 -1 201 -1 283c0 357 235 462 235 462c118 54 320 77 531 79v0zM350 839c-64 0 -115 -52 -115 -116s51 -115 115 -115s116 51 116 115s-52 116 -116 116v0zM768 839c-64 0 -116 -52 -116 -116s52 -115 116 -115
+s116 51 116 115s-52 116 -116 116v0zM1186 839c-64 0 -116 -52 -116 -116s52 -115 116 -115s115 51 115 115s-51 116 -115 116v0z" />
+ <glyph glyph-name="strikethrough" unicode="&#xf0cc;" horiz-adv-x="1792"
+d="M1760 640c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-1728c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h1728zM483 704c-19 24 -36 51 -51 80c-32 65 -48 128 -48 188c0 122 45 224 134 309s220 127 393 127c38 0 93 -7 167 -19c44 -8 103 -24 177 -48
+c7 -26 14 -66 21 -118c9 -79 14 -140 14 -183c0 -14 -2 -29 -5 -45l-12 -3l-84 6l-14 2c-34 101 -69 169 -103 205c-59 61 -130 91 -210 91c-76 0 -137 -20 -182 -59s-67 -88 -67 -146c0 -49 22 -95 66 -140s137 -88 279 -129c48 -14 105 -36 173 -66c36 -17 68 -34 95 -52
+h-743zM990 448h411c5 -28 7 -59 7 -92c0 -72 -13 -143 -41 -212c-15 -37 -38 -71 -71 -104c-24 -23 -60 -50 -109 -81c-50 -30 -100 -53 -153 -66c-53 -14 -120 -21 -203 -21c-55 0 -121 2 -195 23l-140 40c-39 11 -62 20 -72 28c-4 4 -8 11 -8 22v13c0 8 2 60 -2 156
+c-2 50 2 85 2 105v44l102 2c37 -85 54 -136 65 -154c24 -39 51 -70 80 -94s64 -43 105 -57c40 -15 85 -22 132 -22c42 0 89 9 139 27c51 17 92 46 122 86c31 40 47 83 47 129c0 56 -27 108 -81 157c-22 19 -68 43 -137 71z" />
+ <glyph glyph-name="ravelry" unicode="&#xf2d9;" horiz-adv-x="2080"
+d="M1095 -197c-4 1 -7 2 -11 4c0 0 -329 193 -440 505c-37 6 -115 24 -175 37c87 -283 329 -499 626 -546zM454 409l168 -28c-57 171 -64 366 -64 366c-67 -65 -103 -154 -121 -224c3 -39 8 -77 17 -114zM564 1018c-31 -46 -56 -96 -77 -148c33 35 60 58 74 68
+c-2 30 3 80 3 80zM2001 584c0 436 -352 790 -784 790c-200 0 -382 -76 -521 -201c-21 -41 -35 -93 -45 -160c213 181 593 136 593 136c95 -4 84 -88 83 -114c-346 29 -516 -70 -684 -213c0 0 33 -320 109 -450c438 -20 771 218 771 218c42 30 79 33 87 -19
+c6 -42 9 -99 -39 -121c-146 -68 -307 -111 -467 -134c-104 -15 -162 -19 -317 -16c148 -344 518 -438 518 -438c116 -19 204 -4 263 15c256 130 433 398 433 707zM2075 621c-7 -68 -18 -147 -40 -212c-90 -267 -215 -441 -500 -600c-26 -18 -54 -35 -82 -44
+c-51 -18 -106 -22 -163 -16c-24 -2 -48 -3 -73 -3c-381 0 -703 260 -800 615c-3 0 -6 1 -9 1c-23 -180 110 -423 110 -423s8 -12 54 -82c-255 135 -262 533 -262 533c-61 23 -273 95 -310 154c0 0 166 -91 309 -109c-1 1 2 32 2 32c9 122 51 217 94 290
+c28 137 90 261 176 365c15 62 39 136 81 214c18 34 35 56 81 77c304 142 604 178 912 18c295 -154 455 -476 420 -810z" />
+ <glyph glyph-name="code-fork" unicode="&#xf126;" horiz-adv-x="1024"
+d="M288 64c0 53 -43 96 -96 96s-96 -43 -96 -96s43 -96 96 -96s96 43 96 96zM288 1216c0 53 -43 96 -96 96s-96 -43 -96 -96s43 -96 96 -96s96 43 96 96zM928 1088c0 53 -43 96 -96 96s-96 -43 -96 -96s43 -96 96 -96s96 43 96 96zM1024 1088c0 -71 -39 -133 -96 -166
+c-3 -361 -259 -441 -429 -495c-159 -50 -211 -74 -211 -171v-26c57 -33 96 -95 96 -166c0 -106 -86 -192 -192 -192s-192 86 -192 192c0 71 39 133 96 166v820c-57 33 -96 95 -96 166c0 106 86 192 192 192s192 -86 192 -192c0 -71 -39 -133 -96 -166v-497
+c51 25 105 42 154 57c186 59 292 103 294 312c-57 33 -96 95 -96 166c0 106 86 192 192 192s192 -86 192 -192z" />
+ <glyph glyph-name="hand-o-right" unicode="&#xf0a4;" horiz-adv-x="1792"
+d="M256 192c0 35 -29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64s64 29 64 64zM1664 768c0 68 -61 128 -128 128h-576c0 63 96 128 96 256c0 96 -75 128 -160 128c-28 0 -79 -116 -90 -139c-12 -22 -24 -44 -37 -65c-33 -53 -71 -99 -112 -145c-64 -73 -135 -163 -241 -163
+h-32v-640h32c175 0 346 -128 540 -128c112 0 189 47 189 167c0 19 -2 38 -5 56c42 23 65 80 65 126c0 24 -6 48 -18 69c34 32 53 72 53 119c0 32 -14 79 -35 103h331c69 0 128 59 128 128zM1792 769c0 -140 -116 -257 -256 -257h-169c-3 -42 -16 -82 -37 -119
+c2 -14 3 -29 3 -43c0 -64 -21 -128 -60 -178c2 -189 -127 -300 -312 -300c-112 0 -218 31 -322 69c-61 22 -160 59 -223 59h-288c-71 0 -128 57 -128 128v640c0 71 57 128 128 128h288c48 0 116 86 145 119c36 41 70 82 100 129c58 93 101 264 235 264
+c159 0 288 -87 288 -256c0 -44 -7 -87 -22 -128h374c138 0 256 -117 256 -255z" />
+ <glyph glyph-name="object-group" unicode="&#xf247;" horiz-adv-x="2048"
+d="M2048 1152h-128v-1024h128v-384h-384v128h-1280v-128h-384v384h128v1024h-128v384h384v-128h1280v128h384v-384zM1792 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 -128v128h-128v-128h128zM1664 0v128h128v1024h-128v128h-1280v-128h-128v-1024h128v-128
+h1280zM1920 -128v128h-128v-128h128zM1280 896h384v-768h-896v256h-384v768h896v-256zM512 512h640v512h-640v-512zM1536 256v512h-256v-384h-384v-128h640z" />
+ <glyph glyph-name="wikidata" unicode="&#xf31a;" horiz-adv-x="2048"
+d="M0 1264h76v-1264h-76v1264zM152 1264h227v-1264h-227v1264zM455 1264h228v-1264h-228v1264zM759 1264h75v-1264h-75v1264zM910 1264h76v-1264h-76v1264zM1820 1264h76v-1264h-76v1264zM1972 1264h76v-1264h-76v1264zM1062 1264h227v-1264h-227v1264zM1365 1264h76v-1264
+h-76v1264zM1517 1264h228v-1264h-228v1264z" />
+ <glyph glyph-name="anchor" unicode="&#xf13d;" horiz-adv-x="1792"
+d="M960 1280c0 35 -29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64s64 29 64 64zM1792 352v-352c0 -13 -8 -25 -20 -30c-4 -1 -8 -2 -12 -2c-8 0 -16 3 -23 9l-93 93c-157 -189 -439 -310 -748 -310s-591 121 -748 310l-93 -93c-6 -6 -15 -9 -23 -9c-4 0 -8 1 -12 2
+c-12 5 -20 17 -20 30v352c0 18 14 32 32 32h352c13 0 25 -8 30 -20s2 -25 -7 -35l-100 -100c90 -121 263 -209 461 -236v647h-192c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h192v163c-76 44 -128 126 -128 221c0 141 115 256 256 256s256 -115 256 -256
+c0 -95 -52 -177 -128 -221v-163h192c35 0 64 -29 64 -64v-128c0 -35 -29 -64 -64 -64h-192v-647c198 27 371 115 461 236l-100 100c-9 10 -12 23 -7 35s17 20 30 20h352c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="meh-o" unicode="&#xf11a;"
+d="M1152 448c0 -35 -29 -64 -64 -64h-640c-35 0 -64 29 -64 64s29 64 64 64h640c35 0 64 -29 64 -64zM640 896c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128s128 -57 128 -128zM1152 896c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128
+s128 -57 128 -128zM1408 640c0 353 -287 640 -640 640s-640 -287 -640 -640s287 -640 640 -640s640 287 640 640zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="file-image-o" unicode="&#xf1c5;"
+d="M1468 1156c37 -37 68 -111 68 -164v-1152c0 -53 -43 -96 -96 -96h-1344c-53 0 -96 43 -96 96v1600c0 53 43 96 96 96h896c53 0 127 -31 164 -68zM1024 1400v-376h376c-6 17 -15 34 -22 41l-313 313c-7 7 -24 16 -41 22zM1408 -128v1024h-416c-53 0 -96 43 -96 96v416
+h-768v-1536h1280zM1280 320v-320h-1024v192l192 192l128 -128l384 384zM448 512c-106 0 -192 86 -192 192s86 192 192 192s192 -86 192 -192s-86 -192 -192 -192z" />
+ <glyph glyph-name="liberapay" unicode="&#xf2e9;" horiz-adv-x="1191"
+d="M468 1404v0l-222 -918c-4 -19 -6 -37 -7 -53s3 -30 9 -42s18 -23 33 -30s36 -12 64 -14l-48 -196c-75 0 -134 9 -177 29s-74 47 -93 81s-28 73 -27 117s6 91 18 141l203 847zM849 1025v0c60 0 111 -9 154 -27s78 -44 106 -75s49 -68 62 -110s20 -86 20 -134h-1
+c0 -78 -12 -149 -38 -213s-61 -120 -106 -167s-99 -83 -162 -109s-133 -39 -207 -39c-36 0 -72 3 -108 9l-72 -288h-236l265 1103c42 13 91 24 146 34s113 16 177 16zM819 825v0c-34 0 -66 -3 -96 -9l-111 -464c18 -4 40 -7 67 -7c41 0 79 8 113 23s63 37 87 65
+s43 61 56 100s20 81 20 128c0 46 -11 84 -31 116s-55 48 -105 48z" />
+ <glyph glyph-name="nodejs" unicode="&#xf308;"
+d="M768 -225c-24 0 -46 6 -67 17l-211 126c-32 17 -17 24 -7 27c43 14 51 18 96 43c5 3 11 1 16 -2l162 -97c6 -3 14 -3 19 0l634 367c6 3 10 10 10 18v733c0 8 -4 14 -10 17l-634 366c-6 3 -14 3 -19 0l-635 -366c-6 -3 -9 -11 -9 -17v-733c0 -6 3 -15 9 -18l174 -100
+c94 -48 152 8 152 64v723c0 10 8 19 19 19h82c10 0 19 -8 19 -19v-723c0 -126 -69 -199 -188 -199c-37 0 -65 0 -146 40l-167 95c-41 24 -67 68 -67 116v733c0 48 26 92 67 116l634 368c40 22 94 22 134 0l634 -368c41 -24 67 -68 67 -116v-733c0 -48 -26 -92 -67 -116
+l-634 -367c-21 -10 -45 -14 -67 -14zM964 279c-278 0 -336 127 -336 235c0 10 8 19 19 19h83c10 0 17 -6 17 -16c13 -84 49 -125 218 -125c134 0 191 29 191 101c0 41 -16 72 -224 93c-173 17 -282 56 -282 194c0 129 109 205 290 205c204 0 303 -70 316 -223
+c0 -5 -2 -9 -5 -14c-3 -3 -7 -7 -12 -7h-83c-8 0 -16 7 -18 15c-19 87 -68 116 -198 116c-146 0 -164 -51 -164 -89c0 -46 21 -61 218 -86c196 -25 288 -62 288 -199c-2 -140 -116 -219 -318 -219z" />
+ <glyph glyph-name="calculator" unicode="&#xf1ec;" horiz-adv-x="1664"
+d="M384 0c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM768 0c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM384 384c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM1152 0
+c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM768 384c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM384 768c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM1152 384
+c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM768 768c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM1536 0v384c0 70 -58 128 -128 128s-128 -58 -128 -128v-384c0 -70 58 -128 128 -128s128 58 128 128z
+M1152 768c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM1536 1088v256c0 35 -29 64 -64 64h-1280c-35 0 -64 -29 -64 -64v-256c0 -35 29 -64 64 -64h1280c35 0 64 29 64 64zM1536 768c0 71 -57 128 -128 128s-128 -57 -128 -128
+s57 -128 128 -128s128 57 128 128zM1664 1408v-1536c0 -70 -58 -128 -128 -128h-1408c-70 0 -128 58 -128 128v1536c0 70 58 128 128 128h1408c70 0 128 -58 128 -128z" />
+ <glyph glyph-name="vk" unicode="&#xf189;" horiz-adv-x="1921"
+d="M1918 1016c15 -41 -32 -137 -150 -294c-194 -258 -215 -234 -55 -383c154 -143 186 -212 191 -221c0 0 64 -112 -71 -113l-256 -4c-55 -11 -128 39 -128 39c-96 66 -186 237 -256 215c0 0 -72 -23 -70 -177c1 -33 -15 -51 -15 -51s-18 -19 -53 -22h-115
+c-253 -16 -476 217 -476 217s-244 252 -458 755c-14 33 1 49 1 49s15 19 57 19l274 2c26 -4 44 -18 44 -18s16 -11 24 -32c45 -112 103 -214 103 -214c100 -206 168 -241 207 -220c0 0 51 31 40 280c-4 90 -29 131 -29 131c-23 31 -66 40 -85 43c-15 2 10 38 43 54
+c49 24 136 25 239 24c81 -1 104 -6 135 -13c95 -23 63 -111 63 -323c0 -68 -13 -163 36 -194c21 -14 73 -2 201 216c0 0 60 104 107 225c8 22 25 31 25 31s16 9 38 6l288 2c87 11 101 -29 101 -29z" />
+ <glyph glyph-name="odnoklassniki" unicode="&#xf263;" horiz-adv-x="1078"
+d="M539 629c-250 0 -454 203 -454 453c0 251 204 454 454 454s454 -203 454 -454c0 -250 -204 -453 -454 -453zM539 1306c-123 0 -223 -100 -223 -224c0 -123 100 -223 223 -223s223 100 223 223c0 124 -100 224 -223 224zM1062 574c44 -90 -6 -133 -120 -207
+c-96 -61 -228 -85 -315 -94l73 -72l267 -267c40 -41 40 -107 0 -147l-12 -13c-41 -40 -107 -40 -148 0c-67 68 -165 166 -267 268l-267 -268c-41 -40 -107 -40 -147 0l-12 13c-41 40 -41 106 0 147c68 68 165 166 267 267l72 72c-86 9 -220 32 -317 94
+c-114 74 -164 117 -120 207c26 51 97 94 191 20c0 0 127 -101 332 -101s332 101 332 101c94 74 165 31 191 -20z" />
+ <glyph glyph-name="linkedin" unicode="&#xf0e1;"
+d="M349 911v-991h-330v991h330zM370 1217c1 -95 -71 -171 -186 -171h-2c-111 0 -182 76 -182 171c0 97 74 171 186 171c113 0 183 -74 184 -171zM1536 488v-568h-329v530c0 133 -48 224 -167 224c-91 0 -145 -61 -169 -120c-8 -22 -11 -51 -11 -81v-553h-329
+c4 898 0 991 0 991h329v-144h-2c43 68 121 167 299 167c217 0 379 -142 379 -446z" />
+ <glyph glyph-name="jpy" unicode="&#xf157;" horiz-adv-x="1026"
+d="M603 0h-172c-18 0 -32 14 -32 32v330h-288c-18 0 -32 14 -32 32v103c0 18 14 32 32 32h288v85h-288c-18 0 -32 14 -32 32v104c0 17 14 32 32 32h214l-321 578c-5 10 -5 22 0 32c6 10 17 16 28 16h194c12 0 23 -7 29 -18l215 -425c24 -47 40 -87 56 -125
+c17 43 39 85 58 129l191 420c5 12 17 19 29 19h191c11 0 21 -6 27 -16c6 -9 6 -21 1 -31l-313 -579h215c18 0 32 -15 32 -32v-104c0 -18 -14 -32 -32 -32h-290v-85h290c18 0 32 -14 32 -32v-103c0 -18 -14 -32 -32 -32h-290v-330c0 -18 -15 -32 -32 -32z" />
+ <glyph glyph-name="skype" unicode="&#xf17e;"
+d="M1173 473c0 174 -169 234 -311 266l-104 24c-76 18 -133 31 -133 89c0 53 56 77 144 77c157 0 160 -115 257 -115c65 0 104 51 104 109c0 115 -191 190 -380 190c-173 0 -374 -75 -374 -278c0 -168 112 -228 258 -263l146 -36c89 -22 144 -32 144 -96
+c0 -51 -57 -90 -145 -90c-185 0 -195 154 -302 154c-70 0 -101 -50 -101 -105c0 -123 188 -223 413 -223c188 0 384 94 384 297zM1536 256c0 -212 -172 -384 -384 -384c-88 0 -169 30 -234 80c-48 -10 -99 -16 -150 -16c-389 0 -704 315 -704 704c0 51 6 102 16 150
+c-50 65 -80 146 -80 234c0 212 172 384 384 384c88 0 169 -30 234 -80c48 10 99 16 150 16c389 0 704 -315 704 -704c0 -51 -6 -102 -16 -150c50 -65 80 -146 80 -234z" />
+ <glyph glyph-name="envelope-square" unicode="&#xf199;"
+d="M1248 1408c159 0 288 -129 288 -288v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960zM1280 352v436c-19 -21 -40 -40 -64 -55c-94 -62 -191 -120 -284 -184c-47 -33 -105 -69 -164 -69s-117 36 -164 69
+c-93 64 -191 121 -284 185c-23 15 -41 37 -64 54v-436c0 -53 43 -96 96 -96h832c53 0 96 43 96 96zM1280 925c0 54 -40 99 -96 99h-832c-53 0 -96 -43 -96 -96c0 -54 56 -113 98 -141c88 -59 179 -114 267 -172c38 -25 101 -71 147 -71s109 46 147 71c89 58 178 115 267 174
+c39 26 98 86 98 136z" />
+ <glyph glyph-name="question-circle-o" unicode="&#xf29c;"
+d="M880 336v-160c0 -18 -14 -32 -32 -32h-160c-18 0 -32 14 -32 32v160c0 18 14 32 32 32h160c18 0 32 -14 32 -32zM1136 832c0 -142 -99 -198 -172 -239c-52 -30 -84 -49 -84 -81v-32c0 -18 -14 -32 -32 -32h-160c-18 0 -32 14 -32 32v68c0 123 88 162 159 194
+c60 28 97 47 97 92c0 58 -73 101 -139 101c-35 0 -72 -11 -95 -27c-22 -15 -43 -37 -80 -83c-6 -8 -15 -12 -25 -12c-7 0 -14 2 -19 6l-108 82c-13 10 -16 29 -7 43c82 129 197 192 349 192c164 0 348 -130 348 -304zM768 1280c-353 0 -640 -287 -640 -640
+s287 -640 640 -640s640 287 640 640s-287 640 -640 640zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="ship" unicode="&#xf21a;" horiz-adv-x="2010"
+d="M1792 -19c25 25 65 25 90 0l128 -128l-90 -90l-83 83l-83 -83c-12 -13 -29 -19 -45 -19s-33 6 -45 19l-83 83l-83 -83c-25 -25 -65 -25 -90 0l-83 83l-83 -83c-25 -25 -65 -25 -90 0l-83 83l-83 -83c-25 -25 -65 -25 -90 0l-83 83l-83 -83c-25 -25 -65 -25 -90 0l-83 83
+l-83 -83c-25 -25 -65 -25 -90 0l-83 83l-83 -83c-25 -25 -65 -25 -90 0l-128 128l90 90l83 -83l83 83c25 25 65 25 90 0l83 -83l83 83c25 25 65 25 90 0l83 -83l83 83c25 25 65 25 90 0l83 -83l83 83c25 25 65 25 90 0l83 -83l83 83c25 25 65 25 90 0l83 -83l83 83
+c25 25 65 25 90 0l83 -83zM218 19c-25 -25 -65 -25 -90 0l-128 128l90 90l83 -82l83 82c25 25 65 25 90 0l83 -82l64 64v293l-210 314c-23 35 -7 83 33 97l177 58v299h128v128h256v128h256v-128h256v-128h128v-299l177 -58c40 -14 56 -62 33 -97l-210 -314v-293l19 18
+c25 25 65 25 90 0l83 -82l83 82c25 25 65 25 90 0l128 -128l-90 -90l-83 83l-83 -83c-12 -13 -29 -19 -45 -19s-33 6 -45 19l-83 83l-83 -83c-25 -25 -65 -25 -90 0l-83 83l-83 -83c-25 -25 -65 -25 -90 0l-83 83l-83 -83c-25 -25 -65 -25 -90 0l-83 83l-83 -83
+c-25 -25 -65 -25 -90 0l-83 83l-83 -83c-25 -25 -65 -25 -90 0l-83 83zM621 1152v-128l384 128l384 -128v128h-128v128h-512v-128h-128z" />
+ <glyph glyph-name="gimp" unicode="&#xf31b;" horiz-adv-x="1792"
+d="M1760 1453c243 -1827 -975 -1550 -1432 -1186c28 4 55 13 78 30c50 38 74 102 73 173s-25 150 -73 220c-6 9 -13 17 -20 25l26 588s159 -366 481 -358c674 18 794 417 867 508zM612 937c-97 0 -177 -85 -177 -193s80 -194 177 -194c16 0 31 4 46 8
+c-67 3 -122 62 -122 133v0c0 73 57 133 127 133v0c56 0 112 -47 124 -104c1 8 2 16 2 24c0 108 -80 193 -177 193zM1031 928v0c-119 0 -216 -102 -216 -228s97 -227 216 -227c45 0 87 14 122 39c-17 -8 -47 -15 -66 -15c-90 0 -162 77 -162 171v0c0 94 72 170 162 170
+c75 0 147 -63 160 -141v3c0 126 -97 228 -216 228zM158 822v0c79 -2 166 -58 227 -146c46 -67 70 -141 70 -206s-21 -121 -64 -153s-100 -37 -158 -16s-118 67 -164 134s-69 141 -69 206s21 121 64 153c26 20 58 29 94 28zM1042 804c-42 0 -76 -36 -76 -80v0
+c0 -44 34 -80 76 -80s76 36 76 80v0c0 44 -34 80 -76 80zM615 787c-28 0 -50 -23 -50 -52v0v0c0 -29 22 -53 50 -53s50 24 50 53v0v0c0 29 -22 52 -50 52zM130 770c-47 0 -85 -47 -85 -106v0c0 -59 38 -107 85 -107s84 48 84 107v0c0 59 -37 106 -84 106zM1202 468
+c0 0 44 -38 69 -72c-96 -78 -261 -141 -583 -73c163 -60 300 -88 406 -81c-64 -22 -146 -39 -250 -44c233 -23 407 22 468 117c16 -18 32 -49 47 -89c10 69 36 101 -4 155s-153 87 -153 87z" />
+ <glyph glyph-name="dashcube" unicode="&#xf210;" horiz-adv-x="1408"
+d="M0 856c0 173 138 322 314 322h742l352 358v-1470c0 -174 -138 -322 -314 -322h-780c-176 0 -314 148 -314 322v790zM1232 102l-176 180v425c0 61 -49 112 -110 112h-484c-61 0 -110 -51 -110 -112v-492c0 -61 49 -113 110 -113h770z" />
+ <glyph glyph-name="optin-monster" unicode="&#xf23c;" horiz-adv-x="2132"
+d="M396 -139c-10 -21 -39 -50 -64 -60c-35 -12 -78 11 -80 35c-2 31 75 87 108 93c32 6 47 -42 36 -68zM1737 -139c-11 26 4 74 35 68c33 -6 111 -62 108 -93c-1 -24 -45 -47 -79 -35c-26 10 -55 39 -64 60zM1785 -30c-21 43 15 121 70 114c58 -6 183 -94 183 -160
+c0 -43 -58 -72 -119 -55c-45 12 -116 65 -134 101zM346 -30c-18 -36 -88 -89 -133 -101c-61 -17 -119 12 -119 55c0 66 125 154 183 160c55 7 91 -71 69 -114zM1076 1094c106 0 192 -80 192 -179s-86 -179 -192 -179s-191 80 -191 179c0 15 2 28 5 42c16 -25 46 -43 80 -43
+c51 0 92 38 92 85c0 37 -26 69 -61 80c23 10 49 15 76 15h-1zM1380 1312c-132 145 -301 177 -466 87c93 208 452 180 466 -87zM2130 73c5 -7 -1 -25 -11 -42c4 -13 7 -26 7 -40c3 -117 -164 -237 -272 -241c-64 -3 -128 31 -158 87c-420 -15 -840 -18 -1259 0
+c-31 -56 -95 -89 -159 -87c-107 4 -274 124 -272 241c1 14 3 27 7 40c-10 17 -16 35 -11 42c4 6 17 6 31 1c12 19 26 35 41 51c-4 17 -4 32 2 38c7 6 23 4 39 -4c17 12 37 24 59 34c0 18 5 32 13 37c12 6 33 2 51 -16c21 3 42 3 61 -2c13 -3 26 -10 38 -19v73
+c-6 0 -11 0 -18 2c-65 12 -136 57 -152 132c-6 25 -6 52 0 81c12 50 55 79 93 95c3 22 30 52 55 59c28 7 46 -17 52 -38h13c18 -2 47 -6 60 -23c2 -2 4 -5 5 -7c20 2 41 5 61 7c-9 7 -19 13 -30 17c-19 33 -51 41 -91 43c0 3 0 6 1 10c-73 2 -163 21 -203 66
+c-46 51 -54 138 -45 204c8 65 35 140 90 179c31 21 80 3 84 -36c2 -17 5 -75 21 -84c18 -9 47 -13 76 -12c30 29 62 54 98 74c-55 5 -107 -6 -162 -14l47 46c46 44 107 82 163 111c87 44 185 77 282 86c-69 29 -148 44 -221 61c283 60 646 82 904 -139
+c67 -57 120 -134 158 -222c41 -5 93 -6 121 9h1c16 9 19 66 21 84c4 38 53 57 84 35c55 -39 82 -114 91 -178c8 -66 1 -153 -46 -204c-40 -45 -127 -65 -199 -67v-10c-41 -1 -75 -9 -95 -43c-11 -4 -21 -10 -31 -17c21 -2 42 -5 62 -7c1 3 3 6 5 8c14 16 43 21 60 23h13
+c6 20 25 44 52 38s52 -37 55 -59c40 -16 82 -45 93 -95c7 -30 6 -56 1 -81c-17 -75 -88 -121 -153 -132c-5 -1 -12 -2 -17 -2c0 -25 0 -49 -1 -73c12 9 24 16 38 19c19 5 40 5 61 2c18 18 40 22 51 16c8 -5 14 -19 14 -37c21 -10 42 -22 59 -34c16 8 31 10 38 4
+c6 -6 7 -21 2 -38c15 -16 30 -33 41 -51c14 5 26 5 31 -1zM1855 1025c0 -23 -5 -43 -9 -54c64 -25 97 -82 112 -132c4 39 -10 146 -51 189c-27 27 -52 19 -52 -3zM1777 925c48 -58 63 -154 47 -233c40 8 76 23 97 45c7 8 14 18 18 28c-4 79 -38 158 -110 181
+c-12 -12 -34 -18 -52 -21zM1740 921c-14 0 -30 0 -44 1c28 -76 46 -158 53 -239c13 0 28 1 43 3c22 90 -1 191 -52 235zM176 839c15 50 48 107 112 132c-4 11 -9 31 -9 54c0 22 -26 30 -52 3c-42 -43 -55 -150 -51 -189zM212 737c21 -23 57 -37 97 -45c-16 79 -1 175 47 233
+c-18 3 -40 9 -52 21c-72 -23 -105 -102 -110 -181c5 -10 11 -20 18 -28zM389 683c9 82 34 162 73 235c-19 -4 -37 -11 -55 -18l-45 -19v1c-27 -52 -37 -127 -20 -196c17 -2 32 -3 47 -3zM1352 644c13 -66 18 -132 28 -198c4 -23 11 -28 33 -17c59 30 84 145 85 211
+c-48 3 -97 3 -146 4zM1070 1285c-155 0 -282 -126 -282 -281c0 -156 127 -282 282 -282s282 126 282 282c0 155 -127 281 -282 281zM1298 646c-70 1 -141 1 -211 0v1c-1 -19 1 -141 16 -152c41 -20 146 -17 189 -4c20 6 9 137 6 155zM1030 447c17 9 9 168 5 199v1
+c-72 -1 -143 -1 -214 -3c-7 -34 -17 -181 7 -191c48 -21 154 -19 202 -6zM636 636c-20 -73 1 -167 82 -203c20 -9 32 -9 36 16c7 32 9 136 18 193c-45 -1 -91 -3 -136 -6zM509 510c2 -18 -14 -29 -34 -36c162 -174 343 -317 577 -394c250 71 428 222 604 396
+c-18 7 -32 19 -30 34c1 4 2 6 3 9v1v-1c-33 3 -66 7 -98 10c-35 -122 -133 -196 -173 -117c-10 19 -13 43 -17 62c-14 -31 -49 -30 -91 -33c-49 -4 -117 -5 -163 11c-11 -48 -41 -48 -99 -53c-52 -5 -180 -15 -203 40c-4 -106 -130 -37 -167 26c-12 21 -20 42 -26 65
+c-29 -3 -58 -6 -87 -10c2 -3 3 -7 4 -10zM425 -118c2 9 3 19 3 30c-21 86 -69 184 -124 200c-83 25 -255 -87 -245 -202c47 -72 148 -132 219 -135c66 -3 133 41 147 107zM428 53c12 -33 24 -77 27 -119c124 72 256 132 392 174c-143 76 -252 177 -360 285
+c-8 -5 -19 -9 -29 -13c-1 -3 -1 -6 -2 -9c17 -10 29 -22 22 -37c-8 -15 -32 -28 -56 -34c-8 -10 -19 -18 -29 -24h-1c-1 -50 -1 -100 1 -150c14 -25 26 -51 35 -73zM497 -113c382 -15 764 -13 1145 0c-136 79 -274 153 -428 196c-51 -23 -103 -42 -156 -57
+c-8 -3 -8 -3 -16 0c-44 14 -86 30 -129 49c-149 -43 -286 -108 -416 -188h-1v-1c1 0 1 0 1 1zM1681 -67c3 42 16 87 28 120c8 22 19 47 33 71l-1 -1c2 51 3 102 3 153c-11 6 -21 15 -30 25c-24 5 -48 19 -56 33c-7 15 5 28 22 38c-1 2 -2 6 -2 9c-11 3 -20 7 -28 12
+c-117 -109 -242 -210 -383 -284c144 -43 281 -104 414 -176zM2073 -90c11 115 -161 227 -245 202c-54 -16 -103 -114 -124 -200c0 -11 1 -21 3 -30c14 -66 81 -110 147 -107c71 3 172 63 219 135z" />
+ <glyph glyph-name="paw" unicode="&#xf1b0;" horiz-adv-x="1664"
+d="M780 1064c0 -112 -58 -245 -187 -245c-162 0 -260 204 -260 344c0 112 58 245 187 245c163 0 260 -204 260 -344zM438 581c0 -97 -51 -198 -161 -198c-160 0 -277 196 -277 341c0 97 52 199 161 199c160 0 277 -197 277 -342zM832 608c245 0 576 -353 576 -589
+c0 -127 -104 -147 -206 -147c-134 0 -242 90 -370 90c-134 0 -248 -89 -393 -89c-97 0 -183 33 -183 146c0 237 331 589 576 589zM1071 819c-129 0 -187 133 -187 245c0 140 97 344 260 344c129 0 187 -133 187 -245c0 -140 -98 -344 -260 -344zM1503 923
+c109 0 161 -102 161 -199c0 -145 -117 -341 -277 -341c-110 0 -161 101 -161 198c0 145 117 342 277 342z" />
+ <glyph glyph-name="venus-double" unicode="&#xf226;" horiz-adv-x="1792"
+d="M1790 1007c25 -317 -207 -586 -510 -619v-260h224c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-224v-224c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v224h-512v-224c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v224h-224c-18 0 -32 14 -32 32v64
+c0 18 14 32 32 32h224v260c-303 33 -535 302 -510 619c22 275 243 500 517 526c140 14 271 -23 377 -94c106 71 237 108 377 94c274 -26 495 -251 517 -526zM896 647c79 81 128 191 128 313s-49 232 -128 313c-79 -81 -128 -191 -128 -313s49 -232 128 -313zM576 512
+c79 0 153 21 218 57c-96 103 -154 240 -154 391s59 288 154 391c-65 36 -139 57 -218 57c-247 0 -448 -201 -448 -448s201 -448 448 -448zM1152 128v260c-94 10 -181 44 -256 94c-75 -50 -162 -84 -256 -94v-260h512zM1216 512c247 0 448 201 448 448s-201 448 -448 448
+c-79 0 -153 -21 -218 -57c95 -103 154 -240 154 -391s-58 -288 -154 -391c65 -36 139 -57 218 -57z" />
+ <glyph glyph-name="calendar-times-o" unicode="&#xf273;" horiz-adv-x="1664"
+d="M1111 151l-46 -46c-12 -12 -32 -12 -45 0l-188 189l-188 -189c-13 -12 -33 -12 -45 0l-46 46c-12 12 -12 32 0 45l189 188l-189 188c-12 13 -12 33 0 45l46 46c12 12 32 12 45 0l188 -188l188 188c13 12 33 12 45 0l46 -46c12 -12 12 -32 0 -45l-188 -188l188 -188
+c12 -13 12 -33 0 -45zM128 -128h1408v1024h-1408v-1024zM512 1088v288c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-288c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM1280 1088v288c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-288c0 -18 14 -32 32 -32h64
+c18 0 32 14 32 32zM1664 1152v-1280c0 -70 -58 -128 -128 -128h-1408c-70 0 -128 58 -128 128v1280c0 70 58 128 128 128h128v96c0 88 72 160 160 160h64c88 0 160 -72 160 -160v-96h384v96c0 88 72 160 160 160h64c88 0 160 -72 160 -160v-96h128c70 0 128 -58 128 -128z
+" />
+ <glyph glyph-name="address-book-o" unicode="&#xf2ba;" horiz-adv-x="1664"
+d="M1028 892c0 -143 -117 -259 -260 -259s-260 116 -260 259c0 144 117 260 260 260s260 -116 260 -260zM980 672c191 0 221 -227 221 -374c0 -84 -53 -170 -145 -170h-576c-92 0 -145 86 -145 170c0 141 30 374 216 374h5c66 -39 133 -87 212 -87s146 48 212 87zM1664 928
+c0 -17 -15 -32 -32 -32h-96v-128h96c17 0 32 -15 32 -32v-192c0 -17 -15 -32 -32 -32h-96v-128h96c17 0 32 -15 32 -32v-192c0 -17 -15 -32 -32 -32h-96v-224c0 -88 -72 -160 -160 -160h-1216c-88 0 -160 72 -160 160v1472c0 88 72 160 160 160h1216c88 0 160 -72 160 -160
+v-224h96c17 0 32 -15 32 -32v-192zM1408 -96v1472c0 17 -15 32 -32 32h-1216c-17 0 -32 -15 -32 -32v-1472c0 -17 15 -32 32 -32h1216c17 0 32 15 32 32z" />
+ <glyph glyph-name="check" unicode="&#xf00c;" horiz-adv-x="1550"
+d="M1550 970c0 -25 -10 -50 -28 -68l-724 -724l-136 -136c-18 -18 -43 -28 -68 -28s-50 10 -68 28l-136 136l-362 362c-18 18 -28 43 -28 68s10 50 28 68l136 136c18 18 43 28 68 28s50 -10 68 -28l294 -295l656 657c18 18 43 28 68 28s50 -10 68 -28l136 -136
+c18 -18 28 -43 28 -68z" />
+ <glyph glyph-name="meetup" unicode="&#xf2e0;" horiz-adv-x="1847"
+d="M1297 302c-11 72 -143 16 -151 95c-11 112 153 354 140 448c-12 84 -68 102 -117 103c-47 1 -59 -7 -75 -16c-10 -6 -23 -17 -41 1c-22 21 -39 41 -68 45c-43 7 -62 -7 -93 -34c-12 -10 -42 -45 -70 -32c-12 6 -54 27 -84 40c-57 25 -140 -16 -170 -70
+c-45 -80 -133 -396 -146 -438c-30 -93 38 -170 129 -165c39 2 64 16 89 61c14 26 146 377 156 394c7 12 31 28 51 18c20 -11 24 -33 21 -53c-4 -34 -98 -248 -101 -272c-12 -80 94 -93 135 -14c13 25 160 324 173 344c15 22 26 29 41 28c11 0 29 -3 25 -38
+c-5 -33 -123 -253 -136 -307c-16 -72 23 -145 87 -177c40 -20 219 -55 205 39zM346 86c4 -20 -8 -39 -28 -43c-19 -4 -38 8 -42 28c-4 19 8 39 27 43s39 -8 43 -28zM916 -177c16 -23 10 -54 -12 -70c-23 -16 -54 -10 -70 13c-15 23 -9 54 13 70c23 16 54 10 69 -13zM140 635
+c-24 -36 -72 -45 -107 -20c-35 24 -44 73 -20 108c24 36 72 45 107 21c35 -25 44 -73 20 -109zM1430 -42c25 -37 16 -88 -21 -114c-37 -25 -87 -16 -112 21s-16 88 20 114c37 26 87 16 113 -21zM1542 562c92 -151 53 -350 -92 -452c-61 -43 -130 -62 -199 -60
+c-42 -165 -243 -226 -368 -114c-4 -3 -9 -6 -13 -10c-137 -95 -323 -61 -418 78c-34 50 -51 107 -53 164c-229 38 -315 329 -144 489c-99 164 2 376 187 402c88 232 377 342 573 190c236 78 477 -103 458 -354c144 -44 185 -234 69 -333zM418 1222c18 -27 12 -64 -15 -83
+c-26 -18 -63 -12 -81 15s-12 64 15 83c26 18 63 12 81 -15zM577 1503c5 -22 -9 -44 -31 -49s-44 9 -49 32c-4 22 10 44 32 49s44 -9 48 -32zM1763 555c6 -27 -11 -53 -37 -58c-26 -6 -52 11 -57 37c-6 27 11 53 37 59c26 5 52 -12 57 -38zM1099 1448c21 -36 10 -84 -27 -106
+c-36 -22 -83 -10 -104 26c-22 37 -10 85 26 107s83 10 105 -27zM1845 792c5 -20 -8 -39 -27 -44c-20 -4 -39 9 -43 28c-4 20 8 40 28 44c19 4 38 -8 42 -28zM1654 1033c20 -30 13 -71 -16 -92c-30 -20 -71 -13 -91 17s-13 71 17 92c29 21 70 13 90 -17z" />
+ <glyph glyph-name="sliders" unicode="&#xf1de;"
+d="M352 128v-128h-352v128h352zM704 256c35 0 64 -29 64 -64v-256c0 -35 -29 -64 -64 -64h-256c-35 0 -64 29 -64 64v256c0 35 29 64 64 64h256zM864 640v-128h-864v128h864zM224 1152v-128h-224v128h224zM1536 128v-128h-736v128h736zM576 1280c35 0 64 -29 64 -64v-256
+c0 -35 -29 -64 -64 -64h-256c-35 0 -64 29 -64 64v256c0 35 29 64 64 64h256zM1216 768c35 0 64 -29 64 -64v-256c0 -35 -29 -64 -64 -64h-256c-35 0 -64 29 -64 64v256c0 35 29 64 64 64h256zM1536 640v-128h-224v128h224zM1536 1152v-128h-864v128h864z" />
+ <glyph glyph-name="file-pdf-o" unicode="&#xf1c1;"
+d="M1468 1156c37 -37 68 -111 68 -164v-1152c0 -53 -43 -96 -96 -96h-1344c-53 0 -96 43 -96 96v1600c0 53 43 96 96 96h896c53 0 127 -31 164 -68zM1024 1400v-376h376c-6 17 -15 34 -22 41l-313 313c-7 7 -24 16 -41 22zM1408 -128v1024h-416c-53 0 -96 43 -96 96v416
+h-768v-1536h1280zM894 465c25 -20 53 -38 84 -56c42 5 81 7 117 7c67 0 152 -8 177 -49c7 -10 13 -28 2 -52c-1 -1 -2 -3 -3 -4v-1c-3 -18 -18 -38 -71 -38c-64 0 -161 29 -245 73c-139 -15 -285 -46 -392 -83c-103 -176 -182 -262 -242 -262c-10 0 -19 2 -28 7l-24 12
+c-3 1 -4 3 -6 5c-5 5 -9 16 -6 36c10 46 64 123 188 188c8 5 18 2 23 -6c1 -1 2 -3 2 -4c31 51 67 116 107 197c45 90 80 178 104 262c-32 109 -42 221 -24 287c7 25 22 40 42 40h22c15 0 27 -5 35 -15c12 -14 15 -36 9 -68c-1 -3 -2 -6 -4 -8c1 -3 1 -5 1 -8v-30
+c-1 -63 -2 -123 -14 -192c35 -105 87 -190 146 -238zM318 54c30 14 73 57 137 158c-75 -58 -122 -124 -137 -158zM716 974c-10 -28 -10 -76 -2 -132c3 16 5 31 7 44c2 17 5 31 7 43c1 3 2 5 4 8c-1 1 -1 3 -2 5c-1 18 -7 29 -13 36c0 -2 -1 -3 -1 -4zM592 313
+c88 35 186 63 284 81c-10 8 -20 15 -29 23c-49 43 -93 103 -127 176c-19 -61 -47 -126 -83 -197c-15 -28 -30 -56 -45 -83zM1238 329c-5 5 -31 24 -140 24c49 -18 94 -28 124 -28c9 0 14 0 18 1c0 1 -1 2 -2 3z" />
+ <glyph glyph-name="android" unicode="&#xf17b;" horiz-adv-x="1408"
+d="M493 1053c22 0 39 18 39 39s-17 39 -39 39c-21 0 -38 -18 -38 -39s17 -39 38 -39zM915 1053c21 0 38 18 38 39s-17 39 -38 39c-22 0 -39 -18 -39 -39s17 -39 39 -39zM103 869c56 0 102 -46 102 -102v-430c0 -57 -45 -103 -102 -103s-103 46 -103 103v430
+c0 56 46 102 103 102zM1163 850v-666c0 -61 -49 -110 -109 -110h-75v-227c0 -57 -46 -103 -103 -103s-103 46 -103 103v227h-138v-227c0 -57 -46 -103 -103 -103c-56 0 -102 46 -102 103l-1 227h-74c-61 0 -110 49 -110 110v666h918zM931 1255c140 -72 235 -210 235 -369
+h-925c0 159 95 297 236 369l-71 131c-4 7 -2 16 5 20c7 3 16 1 20 -6l72 -132c61 27 129 42 201 42s140 -15 201 -42l72 132c4 7 13 9 20 6c7 -4 9 -13 5 -20zM1408 767v-430c0 -57 -46 -103 -103 -103c-56 0 -102 46 -102 103v430c0 57 46 102 102 102
+c57 0 103 -45 103 -102z" />
+ <glyph glyph-name="hubzilla" unicode="&#xf2eb;" horiz-adv-x="1587"
+d="M1349 1363c86 -43 165 -125 207 -213c16 -40 34 -78 30 -170c-3 -83 -8 -115 -34 -170c-68 -146 -203 -243 -356 -253l-83 -6l-29 -115c-24 -96 -27 -129 -27 -129c28 -29 91 -47 117 -115c36 -69 32 -168 -14 -225c-75 -93 -187 -121 -286 -70c-90 47 -136 164 -108 266
+c7 26 -2 34 -109 104l-116 77l-43 -35c-203 -162 -499 -19 -498 242c0 168 133 299 304 298c86 0 138 -20 202 -78l47 -42l104 53l105 51l-11 37c-16 55 -12 176 7 238c21 74 87 166 150 212c128 94 302 111 441 43v0zM580 413l233 -160s71 60 167 68l60 254
+s-185 59 -237 189l-217 -102s52 -128 -6 -248v-1z" />
+ <glyph glyph-name="stack-exchange" unicode="&#xf18d;" horiz-adv-x="1238"
+d="M1238 283v-66c0 -113 -88 -204 -196 -204h-57l-260 -269v269h-529c-108 0 -196 91 -196 204v66h1238zM1238 609v-255h-1238v255h1238zM1238 937v-255h-1238v255h1238zM1238 1077v-67h-1238v67c0 112 88 203 196 203h846c108 0 196 -91 196 -203z" />
+ <glyph glyph-name="twitch" unicode="&#xf1e8;" horiz-adv-x="1592"
+d="M796 1102v-434h-145v434h145zM1194 1102v-434h-145v434h145zM1194 342l253 254v795h-1194v-1049h326v-217l217 217h398zM1592 1536v-1013l-434 -434h-326l-217 -217h-217v217h-398v1158l109 289h1483z" />
+ <glyph glyph-name="caret-right" unicode="&#xf0da;" horiz-adv-x="576"
+d="M576 640c0 -17 -7 -33 -19 -45l-448 -448c-12 -12 -28 -19 -45 -19c-35 0 -64 29 -64 64v896c0 35 29 64 64 64c17 0 33 -7 45 -19l448 -448c12 -12 19 -28 19 -45z" />
+ <glyph glyph-name="tree" unicode="&#xf1bb;" horiz-adv-x="1472"
+d="M1472 64c0 -35 -29 -64 -64 -64h-462c3 -64 11 -131 11 -196c0 -33 -27 -60 -61 -60h-320c-34 0 -61 27 -61 60c0 65 8 132 11 196h-462c-35 0 -64 29 -64 64c0 17 7 33 19 45l402 403h-229c-35 0 -64 29 -64 64c0 17 7 33 19 45l402 403h-197c-35 0 -64 29 -64 64
+c0 17 7 33 19 45l384 384c12 12 28 19 45 19s33 -7 45 -19l384 -384c12 -12 19 -28 19 -45c0 -35 -29 -64 -64 -64h-197l402 -403c12 -12 19 -28 19 -45c0 -35 -29 -64 -64 -64h-229l402 -403c12 -12 19 -28 19 -45z" />
+ <glyph glyph-name="friendica" unicode="&#xf2e6;" horiz-adv-x="1520"
+d="M0 1128c0 152 123 276 274 276h973c151 0 273 -124 273 -276v-980c0 -152 -122 -276 -273 -276h-973c-151 0 -274 124 -274 276v980zM1247 1343h-244v-368h-486v-310l485 3l1 -367h-486v-368h730c118 0 212 95 212 215v980c0 120 -94 215 -212 215z" />
+ <glyph glyph-name="gratipay" unicode="&#xf184;"
+d="M773 234l350 473c27 37 59 156 -43 223c-86 56 -168 13 -211 -37c-16 -18 -44 -40 -96 -40s-79 22 -95 40c-43 50 -125 93 -212 37c-101 -67 -69 -186 -42 -223zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="map-marker" unicode="&#xf041;" horiz-adv-x="1024"
+d="M768 896c0 141 -115 256 -256 256s-256 -115 -256 -256s115 -256 256 -256s256 115 256 256zM1024 896c0 -61 -7 -124 -33 -179l-364 -774c-21 -44 -67 -71 -115 -71s-94 27 -114 71l-365 774c-26 55 -33 118 -33 179c0 283 229 512 512 512s512 -229 512 -512z" />
+ <glyph glyph-name="globe-e" unicode="&#xf304;"
+d="M768 1404c204 0 399 -81 543 -225s225 -339 225 -543s-81 -399 -225 -543s-339 -225 -543 -225s-399 81 -543 225s-225 339 -225 543s81 399 225 543s339 225 543 225zM863 1165h-1h-6c-78 -1 -136 -19 -204 -29s-157 -10 -205 -29s-58 -39 -87 -58s-72 -30 -87 -58
+s0 -58 0 -87s-28 -73 0 -88s58 39 87 58s68 70 88 59s6 -8 0 -29s-54 -44 -56 -87s110 -78 73 -135c-37 -56 -202 50 -250 18s-19 -58 -29 -87s-40 -57 -29 -88s55 -37 87 -58s87 -59 88 -62s21 -106 29 -145c6 -34 3 -78 4 -120c44 -36 123 -82 176 -102
+c21 41 37 107 53 139c24 48 77 133 87 174s0 39 0 58s8 32 0 58s-40 58 -59 87s-37 69 -58 88s-49 19 -58 29s-4 9 -4 14s-5 8 5 15s36 9 58 0s39 -39 58 -58s27 -55 58 -58s58 39 87 58c29 20 74 35 107 -22c8 -16 43 -35 68 -35s22 42 30 58s24 37 48 41s28 -14 44 -30
+s30 -69 53 -69s22 43 30 59c15 34 6 65 57 116c19 19 50 29 57 57s-21 62 -29 86s-28 63 -28 88c0 21 27 25 63 44c-24 30 -67 73 -97 97c-22 1 -41 2 -55 4c-69 8 -176 29 -253 29zM1251 411c-32 1 -70 -43 -105 -60c-39 -19 -100 -32 -116 -59s0 -39 0 -58s-14 -44 0 -58
+s38 0 58 0s37 9 59 0c12 -5 23 -17 33 -29c40 34 96 98 125 142c-5 11 -10 21 -14 32c-10 29 5 74 -29 88c-4 2 -7 2 -11 2z" />
+ <glyph glyph-name="american-sign-language-interpreting" unicode="&#xf2a3;" horiz-adv-x="2303"
+d="M1032 576c-35 1 -68 21 -84 55c-22 45 -66 73 -116 73c-71 0 -128 -57 -128 -128c0 -34 12 -67 36 -89l10 -8c22 -20 51 -31 82 -31c50 0 94 28 116 73c16 34 49 54 84 55zM1600 704c0 34 -12 67 -36 89l-10 8c-22 20 -51 31 -82 31c-50 0 -94 -28 -116 -73
+c-16 -34 -49 -54 -84 -55c35 -1 68 -21 84 -55c22 -45 66 -73 116 -73c71 0 128 57 128 128zM1174 925c-23 -47 -81 -67 -128 -44c-42 21 -87 31 -134 31c-35 0 -68 -6 -99 -17c6 0 13 1 19 1c123 0 236 -72 289 -183c23 -48 2 -105 -46 -128c-12 -6 -25 -9 -39 -9
+c14 0 27 -3 39 -9c48 -23 69 -80 46 -128c-53 -111 -166 -183 -289 -183h-6c-15 2 -29 3 -44 4l-290 27l-239 -120c-10 -5 -19 -7 -29 -7c-23 0 -46 13 -57 35l-160 320c-15 31 -4 68 25 85l209 119l148 267c23 206 125 395 287 528c41 34 102 28 135 -13
+c34 -41 28 -101 -13 -135c-45 -38 -85 -81 -117 -128c78 53 168 89 267 101c53 7 101 -30 107 -83c7 -53 -30 -101 -83 -107c-58 -7 -112 -27 -159 -55c32 7 65 10 99 10c76 0 150 -17 218 -50c48 -24 68 -81 44 -129zM2137 1085l160 -320c15 -31 4 -68 -25 -85l-209 -119
+l-148 -267c-23 -206 -125 -395 -287 -528c-18 -15 -40 -22 -61 -22c-28 0 -55 12 -74 35c-34 41 -28 101 13 135c45 38 85 81 117 128c-78 -53 -168 -89 -267 -101c-4 -1 -8 -1 -12 -1c-48 0 -89 36 -95 84c-7 53 30 101 83 107c58 7 112 27 159 55c-32 -7 -65 -10 -99 -10
+c-76 0 -150 17 -218 50c-48 24 -68 81 -44 129c23 47 81 67 128 44c42 -21 87 -31 134 -31c35 0 68 6 99 17c-6 0 -13 -1 -19 -1c-123 0 -236 72 -289 183c-23 48 -2 105 46 128c12 6 25 9 39 9c-14 0 -27 3 -39 9c-48 23 -69 80 -46 128c53 111 166 183 289 183h7
+c14 -2 28 -3 42 -4l291 -27l239 120c10 5 19 7 29 7c23 0 46 -13 57 -35z" />
+ <glyph glyph-name="binoculars" unicode="&#xf1e5;" horiz-adv-x="1792"
+d="M704 1216v-768c0 -35 -29 -64 -64 -64v-576c0 -35 -29 -64 -64 -64h-512c-35 0 -64 29 -64 64v512l249 873c4 14 17 23 31 23h424zM1024 1216v-704h-256v704h256zM1792 320v-512c0 -35 -29 -64 -64 -64h-512c-35 0 -64 29 -64 64v576c-35 0 -64 29 -64 64v768h424
+c14 0 27 -9 31 -23zM736 1504v-224h-352v224c0 18 14 32 32 32h288c18 0 32 -14 32 -32zM1408 1504v-224h-352v224c0 18 14 32 32 32h288c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="sticky-note" unicode="&#xf249;"
+d="M1024 288v-416h-928c-53 0 -96 43 -96 96v1344c0 53 43 96 96 96h1344c53 0 96 -43 96 -96v-928h-416c-53 0 -96 -43 -96 -96zM1152 256h381c-9 -48 -35 -102 -65 -132l-184 -184c-30 -30 -84 -56 -132 -65v381z" />
+ <glyph glyph-name="user" unicode="&#xf007;" horiz-adv-x="1280"
+d="M1280 137c0 -146 -96 -265 -213 -265h-854c-117 0 -213 119 -213 265c0 263 65 567 327 567c81 -79 191 -128 313 -128s232 49 313 128c262 0 327 -304 327 -567zM1024 1024c0 -212 -172 -384 -384 -384s-384 172 -384 384s172 384 384 384s384 -172 384 -384z" />
+ <glyph glyph-name="php" unicode="&#xf30e;" horiz-adv-x="2299"
+d="M1149 1245c635 0 1150 -271 1150 -605s-515 -605 -1150 -605s-1149 271 -1149 605s514 605 1149 605zM1049 1081l-130 -627h125l74 359l100 -1c32 0 52 -6 62 -18s12 -33 6 -62l-58 -278h126l61 291c13 65 4 109 -27 132c-30 23 -77 36 -138 37h-111l35 167h-125z
+M478 914v0l-129 -625h126l34 165h108c37 0 73 5 107 13s66 27 96 57c25 24 44 50 58 80s24 60 28 91c11 67 1 121 -31 160s-84 58 -155 59h-242zM1549 914l-130 -625h126l34 165h109c37 0 72 5 106 13s67 27 97 57c25 24 43 50 57 80s24 60 28 91c11 67 1 121 -31 160
+s-84 58 -155 59h-241zM623 815v0c48 1 88 -4 120 -13s43 -45 32 -106c-13 -73 -38 -115 -77 -127s-87 -18 -145 -17h-12c-3 0 -8 1 -11 1l54 261h18c7 0 14 0 21 1zM1693 815v0c48 1 88 -4 120 -13s44 -45 33 -106c-13 -73 -39 -115 -78 -127s-87 -18 -145 -17h-12
+c-3 0 -8 1 -11 1l54 261h18c7 0 14 0 21 1z" />
+ <glyph glyph-name="ioxhost" unicode="&#xf208;" horiz-adv-x="2048"
+d="M1463 704c0 -47 -38 -86 -86 -86h-702c-48 0 -86 39 -86 86s38 86 86 86h702c48 0 86 -39 86 -86zM1677 704c0 59 -8 115 -23 170h-982c-48 0 -86 38 -86 85c0 48 38 86 86 86h908c-115 187 -321 311 -555 311c-360 0 -653 -292 -653 -652c0 -59 8 -115 23 -170h982
+c48 0 86 -38 86 -85c0 -48 -38 -86 -86 -86h-908c115 -187 321 -311 556 -311c359 0 652 292 652 652zM2048 959c0 -47 -38 -85 -86 -85h-131c11 -55 17 -112 17 -170c0 -454 -369 -824 -823 -824c-333 0 -620 198 -750 483h-189c-48 0 -86 38 -86 86c0 47 38 85 86 85h132
+c-11 55 -17 112 -17 170c0 454 369 824 824 824c332 0 619 -198 749 -483h188c48 0 86 -38 86 -86z" />
+ <glyph glyph-name="expand" unicode="&#xf065;"
+d="M755 480c0 -8 -4 -17 -10 -23l-332 -332l144 -144c12 -12 19 -28 19 -45c0 -35 -29 -64 -64 -64h-448c-35 0 -64 29 -64 64v448c0 35 29 64 64 64c17 0 33 -7 45 -19l144 -144l332 332c6 6 15 10 23 10s17 -4 23 -10l114 -114c6 -6 10 -15 10 -23zM1536 1344v-448
+c0 -35 -29 -64 -64 -64c-17 0 -33 7 -45 19l-144 144l-332 -332c-6 -6 -15 -10 -23 -10s-17 4 -23 10l-114 114c-6 6 -10 15 -10 23s4 17 10 23l332 332l-144 144c-12 12 -19 28 -19 45c0 35 29 64 64 64h448c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="discord-alt" unicode="&#xf2ef;"
+d="M559 1212v0l13 -16c-237 -68 -346 -172 -346 -172s29 16 78 38c141 62 252 79 298 83c8 1 15 3 23 3c80 11 170 13 265 2c125 -14 259 -51 396 -126c0 0 -103 99 -327 167l18 21s181 4 370 -138c0 0 189 -343 189 -766c0 0 -111 -191 -402 -200c0 0 -48 56 -87 106
+c172 49 238 157 238 157c-54 -35 -105 -61 -151 -78c-66 -28 -129 -45 -191 -56c-126 -24 -242 -17 -341 1c-75 14 -139 36 -193 57c-30 12 -63 26 -96 44c-4 3 -8 4 -12 7c-3 1 -4 3 -5 4c-24 13 -37 22 -37 22s63 -105 230 -155c-39 -50 -88 -109 -88 -109
+c-291 9 -401 200 -401 200c0 423 189 766 189 766c189 142 370 138 370 138zM522 722v0c-75 0 -134 -66 -134 -146s60 -146 134 -146c75 0 134 66 134 146c1 80 -59 146 -134 146zM1002 722v0c-75 0 -134 -66 -134 -146s60 -146 134 -146c75 0 134 66 134 146
+s-59 146 -134 146z" />
+ <glyph glyph-name="bitbucket-square" unicode="&#xf172;"
+d="M848 666c0 57 -70 96 -118 67c-57 -27 -57 -119 1 -143c52 -31 125 16 117 76zM928 682c11 -88 -58 -174 -146 -182s-171 64 -175 153c-3 66 38 130 98 157c94 42 210 -26 223 -128zM1100 1073c-44 -45 -111 -51 -170 -58c-107 -14 -216 -13 -324 0
+c-59 8 -124 15 -170 58c28 40 78 48 123 55c135 24 273 23 408 1c48 -7 102 -15 133 -56zM1142 327c0 24 25 65 -9 75c-215 -142 -515 -142 -731 0l-12 -6l-5 -12c12 -70 23 -141 41 -210c41 -71 129 -95 204 -108c142 -26 299 -18 428 53c75 42 63 137 84 208zM1272 1020
+c4 24 9 53 -8 75c-38 48 -98 71 -155 88c-158 46 -325 52 -487 36c-77 -7 -154 -20 -226 -46c-54 -21 -127 -49 -136 -113c18 -150 47 -297 72 -446c8 -42 8 -92 46 -122c81 -62 184 -89 284 -100c148 -16 305 -5 440 63c38 20 82 46 90 92c28 157 55 314 80 473zM1536 1120
+v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="hand-paper-o" unicode="&#xf256;" horiz-adv-x="1632"
+d="M880 1408c-62 0 -112 -50 -112 -112v-656h-32v528c0 62 -50 112 -112 112s-112 -50 -112 -112v-784l-154 205c-24 32 -62 51 -102 51c-71 0 -128 -58 -128 -128c0 -28 9 -55 26 -77l384 -512c24 -32 62 -51 102 -51h688c46 0 86 33 95 78l76 405c3 19 5 39 5 59v498
+c0 62 -50 112 -112 112s-112 -50 -112 -112v-272h-32v528c0 62 -50 112 -112 112s-112 -50 -112 -112v-528h-32v656c0 62 -50 112 -112 112zM880 1536c90 0 173 -51 214 -132c14 3 28 4 42 4c132 0 240 -108 240 -240v-17c139 8 256 -99 256 -239v-498c0 -28 -3 -56 -8 -83
+l-76 -404c-19 -106 -112 -183 -220 -183h-688c-80 0 -157 39 -205 102l-384 512c-33 44 -51 99 -51 154c0 141 114 256 256 256c42 0 93 -10 128 -34v434c0 132 108 240 240 240c14 0 28 -1 42 -4c41 81 124 132 214 132z" />
+ <glyph glyph-name="database" unicode="&#xf1c0;"
+d="M768 768c301 0 603 54 768 170v-170c0 -141 -344 -256 -768 -256s-768 115 -768 256v170c165 -116 467 -170 768 -170zM768 0c301 0 603 54 768 170v-170c0 -141 -344 -256 -768 -256s-768 115 -768 256v170c165 -116 467 -170 768 -170zM768 384c301 0 603 54 768 170
+v-170c0 -141 -344 -256 -768 -256s-768 115 -768 256v170c165 -116 467 -170 768 -170zM768 1536c424 0 768 -115 768 -256v-128c0 -141 -344 -256 -768 -256s-768 115 -768 256v128c0 141 344 256 768 256z" />
+ <glyph glyph-name="jirafeau" unicode="&#xf318;"
+d="M1459 1408c43 0 77 -34 77 -77v-1382c0 -43 -34 -77 -77 -77h-923c18 109 27 134 50 210c31 103 92 108 92 108c49 11 74 31 224 -36s270 -72 270 -72v0c15 -19 71 -80 137 -85c90 -7 128 19 128 19s31 91 -38 176s-336 376 -343 403c0 0 -40 47 -69 58s-119 63 -135 130
+s-42 168 -33 215s22 152 -32 130s-31 -74 -40 -137s-52 -190 -112 -190c0 0 -87 150 -145 132s-108 -181 -63 -275c0 0 -210 -295 -393 -772c-20 14 -34 37 -34 63v1382c0 43 34 77 77 77h1382z" />
+ <glyph glyph-name="user-circle-o" unicode="&#xf2be;" horiz-adv-x="1792"
+d="M896 1536c495 0 896 -401 896 -896c0 -492 -399 -896 -896 -896c-496 0 -896 403 -896 896c0 495 401 896 896 896zM1515 185c93 128 149 285 149 455c0 423 -345 768 -768 768s-768 -345 -768 -768c0 -170 56 -327 149 -455c36 179 123 327 306 327
+c81 -79 191 -128 313 -128s232 49 313 128c183 0 270 -148 306 -327zM1280 832c0 -212 -172 -384 -384 -384s-384 172 -384 384s172 384 384 384s384 -172 384 -384z" />
+ <glyph glyph-name="hacker-news" unicode="&#xf1d4;"
+d="M809 532l266 499h-112l-157 -312s-24 -48 -44 -92c-19 46 -42 92 -42 92l-155 312h-120l263 -493v-324h101v318zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="edge" unicode="&#xf282;" horiz-adv-x="1654"
+d="M0 741h1c52 414 335 796 841 795c307 0 560 -144 708 -409c76 -137 104 -283 104 -442v-188h-1125c5 -464 682 -448 974 -244v-377c-171 -103 -557 -192 -858 -77c-255 98 -433 363 -436 621c-4 333 165 554 436 680c-57 -72 -101 -150 -124 -285h635
+c37 379 -359 379 -359 379c-374 -13 -644 -231 -797 -453z" />
+ <glyph glyph-name="calendar-plus-o" unicode="&#xf271;" horiz-adv-x="1664"
+d="M1536 1280c70 0 128 -58 128 -128v-1280c0 -70 -58 -128 -128 -128h-1408c-70 0 -128 58 -128 128v1280c0 70 58 128 128 128h128v96c0 88 72 160 160 160h64c88 0 160 -72 160 -160v-96h384v96c0 88 72 160 160 160h64c88 0 160 -72 160 -160v-96h128zM1152 1376v-288
+c0 -18 14 -32 32 -32h64c18 0 32 14 32 32v288c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32zM384 1376v-288c0 -18 14 -32 32 -32h64c18 0 32 14 32 32v288c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32zM1536 -128v1024h-1408v-1024h1408zM896 448h224
+c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-224v-224c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v224h-224c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h224v224c0 18 14 32 32 32h64c18 0 32 -14 32 -32v-224z" />
+ <glyph glyph-name="hand-lizard-o" unicode="&#xf258;" horiz-adv-x="2048"
+d="M1151 1536c81 0 159 -39 207 -105l572 -781c77 -104 118 -229 118 -359v-355c0 -106 -86 -192 -192 -192h-384c-106 0 -192 86 -192 192v177l-286 143h-546c-106 0 -192 86 -192 192v32c0 159 129 288 288 288h420l42 128h-686c-133 0 -244 102 -255 234
+c-42 51 -65 116 -65 182v32c0 106 86 192 192 192h959zM1920 -64v355c0 101 -33 202 -93 284l-573 781c-24 32 -62 52 -103 52h-959c-35 0 -64 -29 -64 -64c0 -53 1 -90 36 -133c13 41 50 69 92 69h832v-32h-832c-35 0 -64 -29 -64 -64c0 -19 -1 -39 3 -58
+c11 -59 65 -102 125 -102h731c53 0 96 -43 96 -96c0 -10 -2 -21 -5 -30l-64 -192c-13 -39 -50 -66 -91 -66h-443c-88 0 -160 -72 -160 -160v-32c0 -35 29 -64 64 -64h561c10 0 20 -2 29 -7l317 -158c32 -17 53 -50 53 -86v-197c0 -35 29 -64 64 -64h384c35 0 64 29 64 64z
+" />
+ <glyph glyph-name="digitalocean" unicode="&#xf31d;" horiz-adv-x="1535"
+d="M245 169h-191v190h191v-190zM473 -59h-228v228h228v-228zM769 465v-296h-296v296h296zM768 -128v298c315 0 559 312 438 644c-44 123 -142 221 -265 265c-332 120 -644 -123 -644 -438h-297c0 502 485 894 1012 729c230 -72 414 -255 485 -485
+c165 -527 -226 -1013 -729 -1013z" />
+ <glyph glyph-name="xing" unicode="&#xf168;" horiz-adv-x="1408"
+d="M597 869c0 0 -10 -17 -257 -456c-13 -22 -30 -46 -65 -46h-239c-14 0 -25 7 -31 17s-7 23 0 36l253 448c1 0 1 0 0 1l-161 279c-7 13 -8 27 -1 37c6 10 18 15 32 15h239c36 0 54 -24 66 -45c163 -285 164 -286 164 -286zM1403 1511c7 -10 7 -24 0 -37l-528 -934
+c-1 0 -1 -1 0 -1l336 -615c7 -13 7 -27 1 -37c-7 -10 -18 -15 -32 -15h-239c-36 0 -55 24 -66 45c-339 621 -339 622 -339 622s17 30 531 942c13 23 28 45 64 45h241c14 0 25 -5 31 -15z" />
+ <glyph glyph-name="youtube-square" unicode="&#xf166;"
+d="M919 233v157c0 33 -10 50 -29 50c-11 0 -22 -5 -33 -16v-224c11 -11 22 -16 33 -16c19 0 29 16 29 49zM1103 355h66v34c0 34 -11 51 -33 51s-33 -17 -33 -51v-34zM532 621v-70h-80v-423h-74v423h-78v70h232zM733 495v-367h-67v40c-26 -30 -51 -45 -76 -45
+c-21 0 -36 9 -42 28c-4 11 -6 28 -6 54v290h66v-270c0 -15 0 -24 1 -26c1 -10 6 -15 15 -15c14 0 27 10 42 31v280h67zM985 384v-146c0 -33 -2 -58 -7 -73c-8 -28 -26 -42 -53 -42c-23 0 -46 14 -68 41v-36h-67v493h67v-161c21 26 44 40 68 40c27 0 45 -14 53 -42
+c5 -15 7 -39 7 -74zM1236 255v-9c0 -22 -1 -36 -2 -43c-2 -15 -7 -28 -15 -40c-18 -27 -46 -40 -80 -40c-35 0 -62 13 -81 38c-14 18 -21 47 -21 86v129c0 39 6 67 20 86c19 25 46 38 80 38c33 0 60 -13 78 -38c14 -19 21 -47 21 -86v-76h-133v-65c0 -34 11 -51 34 -51
+c16 0 26 9 30 26c0 4 1 19 1 45h68zM785 1079v-156c0 -34 -11 -51 -32 -51c-22 0 -32 17 -32 51v156c0 34 10 52 32 52c21 0 32 -18 32 -52zM1318 366c0 86 0 177 -19 260c-14 59 -62 102 -119 108c-136 15 -274 15 -412 15c-137 0 -275 0 -411 -15
+c-58 -6 -106 -49 -119 -108c-19 -83 -20 -174 -20 -260c0 -85 0 -176 20 -260c13 -58 61 -101 118 -108c137 -15 275 -15 412 -15s275 0 412 15c57 7 105 50 118 108c20 84 20 175 20 260zM563 1017l90 296h-75l-51 -195l-53 195h-78c15 -46 32 -92 47 -138
+c24 -70 39 -122 46 -158v-201h74v201zM852 936v130c0 39 -7 68 -21 87c-19 25 -45 38 -78 38c-34 0 -60 -13 -78 -38c-14 -19 -21 -48 -21 -87v-130c0 -39 7 -68 21 -87c18 -25 44 -38 78 -38c33 0 59 13 78 38c14 18 21 48 21 87zM1033 816h67v370h-67v-283
+c-15 -21 -29 -31 -42 -31c-9 0 -15 5 -16 16c-1 2 -1 10 -1 26v272h-67v-293c0 -26 2 -43 6 -55c7 -18 22 -27 43 -27c25 0 50 15 77 45v-40zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960
+c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="taxi" unicode="&#xf1ba;" horiz-adv-x="2048"
+d="M1824 640c124 0 224 -100 224 -224v-384c0 -18 -14 -32 -32 -32h-96v-64c0 -106 -86 -192 -192 -192s-192 86 -192 192v64h-1024v-64c0 -106 -86 -192 -192 -192s-192 86 -192 192v64h-96c-18 0 -32 14 -32 32v384c0 124 100 224 224 224h28l105 419
+c31 126 153 221 283 221h128v224c0 18 14 32 32 32h448c18 0 32 -14 32 -32v-224h128c130 0 252 -95 283 -221l105 -419h28zM320 160c88 0 160 72 160 160s-72 160 -160 160s-160 -72 -160 -160s72 -160 160 -160zM516 640h1016l-89 357c-3 11 -23 27 -35 27h-768
+c-12 0 -32 -16 -35 -27zM1728 160c88 0 160 72 160 160s-72 160 -160 160s-160 -72 -160 -160s72 -160 160 -160z" />
+ <glyph glyph-name="sort-desc" unicode="&#xf0dd;" horiz-adv-x="1024"
+d="M1024 448c0 -17 -7 -33 -19 -45l-448 -448c-12 -12 -28 -19 -45 -19s-33 7 -45 19l-448 448c-12 12 -19 28 -19 45c0 35 29 64 64 64h896c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="rocket" unicode="&#xf135;" horiz-adv-x="1632"
+d="M1408 1088c0 53 -43 96 -96 96s-96 -43 -96 -96s43 -96 96 -96s96 43 96 96zM1632 1376c0 -332 -92 -553 -329 -791c-58 -57 -124 -116 -195 -176l-20 -379c-1 -10 -7 -20 -16 -26l-384 -224c-5 -3 -10 -4 -16 -4c-8 0 -16 3 -23 9l-64 64c-8 9 -11 21 -8 32l85 276
+l-281 281l-276 -85c-3 -1 -6 -1 -9 -1c-8 0 -17 3 -23 9l-64 64c-10 11 -12 27 -5 39l224 384c6 9 16 15 26 16l379 20c60 71 119 137 176 195c250 249 441 329 789 329c18 0 34 -14 34 -32z" />
+ <glyph glyph-name="discord" unicode="&#xf2ee;"
+d="M180 1516v0h1176c99 0 180 -81 180 -181v-1575l-189 167l-106 98l-112 105l46 -163h-995c-99 0 -180 81 -180 181v1187c0 100 81 181 180 181zM634 1107c0 0 -121 3 -247 -92c0 0 -126 -229 -126 -512c0 0 73 -128 267 -134c0 0 33 40 59 73c-111 33 -153 104 -153 104
+s8 -6 24 -15c1 -1 2 -2 4 -3c3 -2 5 -2 8 -4c22 -12 44 -22 64 -30c36 -14 79 -28 129 -38c66 -12 143 -17 227 -1c41 7 83 20 127 38c31 11 65 28 101 52c0 0 -44 -73 -159 -105c26 -33 58 -71 58 -71c194 6 269 134 269 134c0 283 -127 512 -127 512
+c-126 95 -246 92 -246 92l-12 -14c149 -46 218 -112 218 -112c-91 50 -181 75 -264 85c-63 7 -123 5 -177 -2c-5 0 -10 -1 -15 -2c-31 -3 -106 -14 -200 -55c-32 -15 -51 -26 -51 -26s72 69 230 115zM609 779c50 0 91 -43 90 -97c0 -54 -40 -98 -90 -98c-49 0 -89 44 -89 98
+s39 97 89 97zM930 779c50 0 89 -43 89 -97s-39 -98 -89 -98c-49 0 -90 44 -90 98s40 97 90 97z" />
+ <glyph glyph-name="money" unicode="&#xf0d6;" horiz-adv-x="1920"
+d="M768 384h384v96h-128v448h-114l-148 -137l77 -80c24 21 39 32 55 57h2v-288h-128v-96zM1280 640c0 -182 -110 -416 -320 -416s-320 234 -320 416s110 416 320 416s320 -234 320 -416zM1792 384v512c-141 0 -256 115 -256 256h-1152c0 -141 -115 -256 -256 -256v-512
+c141 0 256 -115 256 -256h1152c0 141 115 256 256 256zM1920 1216v-1152c0 -35 -29 -64 -64 -64h-1792c-35 0 -64 29 -64 64v1152c0 35 29 64 64 64h1792c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="laptop" unicode="&#xf109;" horiz-adv-x="1920"
+d="M416 256c-88 0 -160 72 -160 160v704c0 88 72 160 160 160h1088c88 0 160 -72 160 -160v-704c0 -88 -72 -160 -160 -160h-1088zM384 1120v-704c0 -17 15 -32 32 -32h1088c17 0 32 15 32 32v704c0 17 -15 32 -32 32h-1088c-17 0 -32 -15 -32 -32zM1760 192h160v-96
+c0 -53 -72 -96 -160 -96h-1600c-88 0 -160 43 -160 96v96h1760zM1040 96c9 0 16 7 16 16s-7 16 -16 16h-160c-9 0 -16 -7 -16 -16s7 -16 16 -16h160z" />
+ <glyph glyph-name="arrows-alt" unicode="&#xf0b2;"
+d="M1283 995l-355 -355l355 -355l144 144c18 19 46 24 70 14c23 -10 39 -33 39 -59v-448c0 -35 -29 -64 -64 -64h-448c-26 0 -49 16 -59 40c-10 23 -5 51 14 69l144 144l-355 355l-355 -355l144 -144c19 -18 24 -46 14 -69c-10 -24 -33 -40 -59 -40h-448
+c-35 0 -64 29 -64 64v448c0 26 16 49 40 59c23 10 51 5 69 -14l144 -144l355 355l-355 355l-144 -144c-12 -12 -28 -19 -45 -19c-8 0 -17 2 -24 5c-24 10 -40 33 -40 59v448c0 35 29 64 64 64h448c26 0 49 -16 59 -40c10 -23 5 -51 -14 -69l-144 -144l355 -355l355 355
+l-144 144c-19 18 -24 46 -14 69c10 24 33 40 59 40h448c35 0 64 -29 64 -64v-448c0 -26 -16 -49 -39 -59c-8 -3 -17 -5 -25 -5c-17 0 -33 7 -45 19z" />
+ <glyph glyph-name="thermometer-empty" unicode="&#xf2cb;" horiz-adv-x="1024"
+d="M640 192c0 -106 -86 -192 -192 -192s-192 86 -192 192c0 105 85 192 192 192s192 -88 192 -192zM768 192c0 105 -50 197 -128 256v768c0 106 -86 192 -192 192s-192 -86 -192 -192v-768c-78 -59 -128 -151 -128 -256c0 -177 143 -320 320 -320s320 143 320 320zM896 192
+c0 -247 -201 -448 -448 -448s-448 201 -448 448c0 122 49 232 128 313v711c0 177 143 320 320 320s320 -143 320 -320v-711c79 -81 128 -191 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192v128h192z" />
+ <glyph glyph-name="underline" unicode="&#xf0cd;"
+d="M48 1313c-18 1 -33 1 -45 4l-3 88c13 1 26 1 40 1c35 0 73 -1 112 -4c94 -5 150 -7 166 -7c57 0 113 1 168 3c54 2 103 4 146 5c42 0 71 1 86 2l-1 -14l2 -64v-9c-40 -6 -81 -9 -124 -9c-40 0 -66 -8 -79 -25c-9 -10 -13 -54 -13 -132c0 -24 1 -43 1 -58l1 -229l14 -280
+c4 -81 20 -148 51 -202c23 -39 55 -70 96 -92c60 -32 119 -47 177 -47c68 0 132 9 191 28c35 11 68 27 99 51c31 23 53 44 65 64c26 40 43 79 53 114c14 49 21 125 21 229c0 179 -13 184 -28 410l-4 59c-3 43 -10 73 -24 88c-22 23 -48 35 -77 34l-100 -2l-14 3l2 86h84
+l205 -10c68 -3 133 3 196 10l18 -2c4 -25 6 -42 6 -51s-2 -19 -4 -31c-27 -7 -55 -12 -84 -13c-47 -7 -74 -12 -79 -17c-9 -9 -15 -22 -15 -41c0 -13 2 -33 3 -58c0 0 8 -18 22 -396c5 -151 -5 -253 -15 -304s-24 -92 -41 -122c-26 -44 -64 -85 -112 -123
+c-49 -37 -109 -67 -182 -89s-158 -33 -255 -33c-110 0 -205 15 -284 46s-139 72 -179 122s-68 115 -83 195c-11 55 -16 134 -16 237v333c0 126 -6 197 -17 213c-16 23 -65 37 -147 39zM1536 -96c0 -18 -14 -32 -32 -32h-1472c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h1472
+c18 0 32 -14 32 -32v-64z" />
+ <glyph glyph-name="sun-o" unicode="&#xf185;" horiz-adv-x="1707"
+d="M1430 640c0 318 -258 576 -576 576s-576 -258 -576 -576s258 -576 576 -576s576 258 576 576zM1706 363c-3 -10 -11 -17 -20 -20l-292 -96v-306c0 -10 -5 -20 -13 -26c-9 -6 -19 -8 -29 -4l-292 94l-180 -248c-6 -8 -16 -13 -26 -13s-20 5 -26 13l-180 248l-292 -94
+c-10 -4 -20 -2 -29 4c-8 6 -13 16 -13 26v306l-292 96c-9 3 -17 10 -20 20s-2 21 4 29l180 248l-180 248c-6 9 -7 19 -4 29s11 17 20 20l292 96v306c0 10 5 20 13 26c9 6 19 8 29 4l292 -94l180 248c12 16 40 16 52 0l180 -248l292 94c10 4 20 2 29 -4c8 -6 13 -16 13 -26
+v-306l292 -96c9 -3 17 -10 20 -20s2 -20 -4 -29l-180 -248l180 -248c6 -8 7 -19 4 -29z" />
+ <glyph glyph-name="activitypub" unicode="&#xf2f2;" horiz-adv-x="2032"
+d="M924 1280v-1280l-185 107v853l-739 -427v214zM1109 1280l923 -533v-214l-923 -533v213l739 427l-739 427v213zM1109 853l369 -213l-369 -213v426zM554 640v-427l-369 214z" />
+ <glyph glyph-name="play-circle" unicode="&#xf144;"
+d="M768 1408c424 0 768 -344 768 -768s-344 -768 -768 -768s-768 344 -768 768s344 768 768 768zM1152 585c20 11 32 32 32 55s-12 44 -32 55l-544 320c-19 12 -44 12 -64 1c-20 -12 -32 -33 -32 -56v-640c0 -23 12 -44 32 -56c10 -5 21 -8 32 -8s22 3 32 9z" />
+ <glyph glyph-name="share-square-o" unicode="&#xf045;" horiz-adv-x="1664"
+d="M1408 547v-259c0 -159 -129 -288 -288 -288h-832c-159 0 -288 129 -288 288v832c0 159 129 288 288 288h255c17 0 32 -14 32 -32c0 -16 -11 -29 -26 -32c-50 -17 -95 -37 -133 -60c-5 -2 -10 -4 -16 -4h-112c-88 0 -160 -72 -160 -160v-832c0 -88 72 -160 160 -160h832
+c88 0 160 72 160 160v214c0 12 7 23 18 29c20 9 38 22 54 37c9 9 23 13 35 8s21 -16 21 -29zM1645 1043l-384 -384c-12 -13 -28 -19 -45 -19c-8 0 -17 2 -25 5c-23 10 -39 33 -39 59v192h-160c-220 0 -360 -42 -438 -131c-81 -93 -105 -243 -74 -473c2 -14 -7 -28 -20 -34
+c-4 -1 -8 -2 -12 -2c-10 0 -20 5 -26 13c-7 10 -166 235 -166 435c0 268 84 576 736 576h160v192c0 26 16 49 39 59c8 3 17 5 25 5c17 0 33 -7 45 -19l384 -384c25 -25 25 -65 0 -90z" />
+ <glyph glyph-name="street-view" unicode="&#xf21d;" horiz-adv-x="1408"
+d="M1408 0c0 -176 -365 -256 -704 -256s-704 80 -704 256c0 136 203 200 373 229c35 6 68 -17 74 -52s-17 -68 -52 -74c-206 -36 -264 -92 -267 -104c10 -34 202 -127 576 -127s566 93 576 129c-3 10 -61 66 -267 102c-35 6 -58 39 -52 74s39 58 74 52
+c170 -29 373 -93 373 -229zM1024 896v-384c0 -35 -29 -64 -64 -64h-64v-384c0 -35 -29 -64 -64 -64h-256c-35 0 -64 29 -64 64v384h-64c-35 0 -64 29 -64 64v384c0 71 57 128 128 128h384c71 0 128 -57 128 -128zM928 1280c0 -124 -100 -224 -224 -224s-224 100 -224 224
+s100 224 224 224s224 -100 224 -224z" />
+ <glyph glyph-name="arrow-circle-up" unicode="&#xf0aa;"
+d="M1284 641c0 17 -6 33 -18 45l-362 362l-91 91c-12 12 -28 18 -45 18s-33 -6 -45 -18l-91 -91l-362 -362c-12 -12 -18 -28 -18 -45s6 -33 18 -45l91 -91c12 -12 28 -18 45 -18s33 6 45 18l189 189v-502c0 -35 29 -64 64 -64h128c35 0 64 29 64 64v502l189 -189
+c12 -12 28 -19 45 -19s33 7 45 19l91 91c12 12 18 28 18 45zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="podcast" unicode="&#xf2ce;"
+d="M994 344c0 -66 -7 -132 -17 -197c-15 -104 -30 -211 -55 -313c-18 -73 -86 -90 -152 -90s-134 17 -152 90c-25 102 -40 209 -55 313c-10 65 -17 131 -17 197c0 135 109 168 224 168s224 -33 224 -168zM1536 768c0 -324 -200 -601 -484 -714c-11 -4 -23 6 -21 18
+c3 21 6 43 10 66c2 16 4 32 6 47c1 6 4 10 9 12c208 106 352 322 352 571c0 365 -306 659 -675 639c-338 -18 -607 -306 -605 -644c2 -249 147 -464 356 -568c5 -2 8 -7 9 -12c2 -14 4 -29 6 -45c4 -24 7 -46 11 -68c2 -12 -11 -22 -22 -17c-297 116 -504 412 -487 753
+c19 387 331 704 718 728c446 28 817 -326 817 -766zM994 800c0 -124 -100 -224 -224 -224s-224 100 -224 224s100 224 224 224s224 -100 224 -224zM1282 768c0 -165 -79 -313 -200 -406c-10 -8 -24 -1 -26 12c-3 28 -11 61 -29 92c-4 6 -3 14 3 20c76 70 124 170 124 282
+c0 226 -197 407 -428 382c-177 -20 -321 -166 -338 -344c-13 -126 37 -242 122 -320c6 -6 7 -14 3 -20c-18 -31 -26 -64 -29 -93c-2 -12 -16 -19 -26 -11c-124 96 -203 247 -200 417c6 266 222 488 487 500c294 14 537 -220 537 -511z" />
+ <glyph glyph-name="hackster" unicode="&#xf326;"
+d="M768 -128c-424 0 -768 344 -768 768s344 768 768 768s768 -344 768 -768s-344 -768 -768 -768zM517 887c-10 -3 -17 -13 -17 -23s8 -18 18 -18h113c17 0 31 14 31 31v9c0 3 0 5 -1 8c-4 16 -22 26 -38 22zM661 739v59v5c-2 9 -12 13 -21 11l-325 -88c-5 -1 -9 -7 -9 -12
+s4 -9 9 -9h151c17 0 31 -14 31 -31v-86c0 -9 8 -17 17 -17h324c17 0 31 -13 31 -30v-59v-5c2 -9 12 -13 21 -11l325 88c5 1 9 7 9 12s-4 9 -9 9h-152c-17 0 -30 14 -30 31v85c0 9 -8 17 -17 17h-324c-17 0 -31 14 -31 31v0zM891 989c-13 -4 -23 -16 -23 -30v-176
+c0 -17 14 -31 31 -31h101c17 0 30 14 30 31v203v0c0 2 0 6 -1 8c-4 16 -21 26 -37 22zM1013 386c10 3 17 13 17 23s-8 19 -18 19h-113c-17 0 -31 -14 -31 -31v-9c0 -3 0 -5 1 -8c4 -16 22 -26 38 -22zM639 285c13 4 23 16 23 30v176c0 17 -14 30 -31 30h-101
+c-17 0 -30 -13 -30 -30v-204c0 -3 0 -5 1 -8c4 -16 21 -25 37 -21z" />
+ <glyph glyph-name="plus-square" unicode="&#xf0fe;"
+d="M1280 576v128c0 35 -29 64 -64 64h-320v320c0 35 -29 64 -64 64h-128c-35 0 -64 -29 -64 -64v-320h-320c-35 0 -64 -29 -64 -64v-128c0 -35 29 -64 64 -64h320v-320c0 -35 29 -64 64 -64h128c35 0 64 29 64 64v320h320c35 0 64 29 64 64zM1536 1120v-960
+c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="desktop" unicode="&#xf108;" horiz-adv-x="1920"
+d="M1792 544v832c0 17 -15 32 -32 32h-1600c-17 0 -32 -15 -32 -32v-832c0 -17 15 -32 32 -32h1600c17 0 32 15 32 32zM1920 1376v-1088c0 -88 -72 -160 -160 -160h-544c0 -85 64 -157 64 -192s-29 -64 -64 -64h-512c-35 0 -64 29 -64 64c0 37 64 105 64 192h-544
+c-88 0 -160 72 -160 160v1088c0 88 72 160 160 160h1600c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="expeditedssl" unicode="&#xf23e;" horiz-adv-x="1792"
+d="M896 1472c-459 0 -832 -373 -832 -832s373 -832 832 -832s832 373 832 832s-373 832 -832 832zM896 1536c495 0 896 -401 896 -896s-401 -896 -896 -896s-896 401 -896 896s401 896 896 896zM496 704c9 0 16 -7 16 -16v-480c0 -9 -7 -16 -16 -16h-32c-9 0 -16 7 -16 16
+v480c0 9 7 16 16 16h32zM896 640c71 0 128 -57 128 -128c0 -47 -26 -88 -64 -110v-114c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v114c-38 22 -64 63 -64 110c0 71 57 128 128 128zM896 1408c424 0 768 -344 768 -768s-344 -768 -768 -768s-768 344 -768 768
+s344 768 768 768zM544 928v-96c0 -18 14 -32 32 -32h64c18 0 32 14 32 32v96c0 124 100 224 224 224s224 -100 224 -224v-96c0 -18 14 -32 32 -32h64c18 0 32 14 32 32v96c0 194 -158 352 -352 352s-352 -158 -352 -352zM1408 192v512c0 35 -29 64 -64 64h-896
+c-35 0 -64 -29 -64 -64v-512c0 -35 29 -64 64 -64h896c35 0 64 29 64 64z" />
+ <glyph glyph-name="toggle-on" unicode="&#xf205;" horiz-adv-x="2048"
+d="M0 640c0 353 287 640 640 640h768c353 0 640 -287 640 -640s-287 -640 -640 -640h-768c-353 0 -640 287 -640 640zM1408 128c282 0 512 230 512 512s-230 512 -512 512s-512 -230 -512 -512s230 -512 512 -512z" />
+ <glyph glyph-name="minus-square" unicode="&#xf146;"
+d="M1280 576v128c0 35 -29 64 -64 64h-896c-35 0 -64 -29 -64 -64v-128c0 -35 29 -64 64 -64h896c35 0 64 29 64 64zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="adn" unicode="&#xf170;"
+d="M768 914l201 -306h-402zM1133 384h94l-459 691l-459 -691h94l104 160h522zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="whatsapp" unicode="&#xf232;"
+d="M985 562c17 0 180 -85 187 -97c2 -5 2 -11 2 -15c0 -25 -8 -53 -17 -76c-23 -56 -116 -92 -173 -92c-48 0 -147 42 -190 62c-143 65 -232 176 -318 303c-38 56 -72 125 -71 194v8c2 66 26 113 74 158c15 14 31 22 52 22c12 0 24 -3 37 -3c27 0 32 -8 42 -34
+c7 -17 58 -153 58 -163c0 -38 -69 -81 -69 -104c0 -5 2 -10 5 -15c22 -47 64 -101 102 -137c46 -44 95 -73 151 -101c7 -4 14 -7 22 -7c30 0 80 97 106 97zM782 32c346 0 628 282 628 628s-282 628 -628 628s-628 -282 -628 -628c0 -132 42 -261 120 -368l-79 -233l242 77
+c102 -67 223 -104 345 -104zM782 1414c416 0 754 -338 754 -754s-338 -754 -754 -754c-127 0 -253 32 -365 94l-417 -134l136 405c-71 117 -108 252 -108 389c0 416 338 754 754 754z" />
+ <glyph glyph-name="puzzle-piece" unicode="&#xf12e;" horiz-adv-x="1664"
+d="M1664 438c0 -103 -59 -189 -168 -189c-122 0 -154 111 -264 111c-80 0 -110 -50 -110 -124c0 -78 32 -153 31 -230v-5c-11 0 -22 0 -33 -1c-103 -10 -207 -30 -311 -30c-71 0 -145 28 -145 110c0 110 111 142 111 264c0 109 -86 168 -189 168c-105 0 -202 -58 -202 -173
+c0 -127 97 -182 97 -251c0 -35 -22 -66 -46 -89c-31 -29 -75 -35 -117 -35c-82 0 -164 11 -245 24c-18 3 -37 5 -55 8l-13 2c-2 1 -5 1 -5 2v1024c4 -3 63 -10 73 -12c81 -13 163 -24 245 -24c42 0 86 6 117 35c24 23 46 54 46 89c0 69 -97 124 -97 251
+c0 115 97 173 203 173c102 0 188 -59 188 -168c0 -122 -111 -154 -111 -264c0 -82 74 -110 145 -110c115 0 229 26 343 32v-2c-3 -4 -10 -63 -12 -73c-13 -81 -24 -163 -24 -245c0 -42 6 -86 35 -117c23 -24 54 -46 89 -46c69 0 124 97 251 97c115 0 173 -97 173 -202z" />
+ <glyph glyph-name="css3" unicode="&#xf13c;" horiz-adv-x="1768"
+d="M263 1408h1505l-266 -1333l-804 -267l-698 267l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208z" />
+ <glyph glyph-name="skyatlas" unicode="&#xf216;" horiz-adv-x="2048"
+d="M1430 953c0 0 -1 1 0 0zM1690 749c194 0 358 -145 358 -343c0 -211 -168 -366 -376 -366c-531 0 -629 799 -1151 799c-202 0 -349 -129 -349 -336c0 -214 160 -343 367 -343c136 0 291 57 401 136c18 13 54 52 73 52s35 -16 35 -35c0 -25 -42 -61 -60 -77
+c-131 -114 -321 -196 -495 -196c-267 0 -493 189 -493 464s216 477 489 477c593 0 712 -787 1158 -787c134 0 235 87 235 224c0 127 -98 223 -224 223c-56 0 -112 -37 -150 -37c-27 0 -51 23 -51 50c0 37 17 76 17 116c0 213 -163 367 -374 367c-170 0 -256 -118 -284 -118
+c-20 0 -36 16 -36 36c0 18 13 33 25 46c81 92 207 140 329 140c254 0 445 -187 445 -441c0 -22 -1 -44 -4 -66c38 10 77 15 115 15z" />
+ <glyph glyph-name="level-down" unicode="&#xf149;" horiz-adv-x="1024"
+d="M32 1280h704c18 0 32 -15 32 -33v-863h192c25 0 47 -15 58 -37c11 -23 7 -50 -9 -69l-320 -384c-24 -29 -74 -29 -98 0l-320 384c-16 19 -19 46 -9 69c11 22 33 37 58 37h192v640h-320c-9 0 -18 4 -25 11l-160 192c-8 9 -9 23 -4 34s17 19 29 19z" />
+ <glyph glyph-name="stack-overflow" unicode="&#xf16c;" horiz-adv-x="1514"
+d="M1278 -96v480h160v-640h-1438v640h160v-480h1118zM336 428l33 157l783 -165l-33 -156zM439 802l67 146l725 -339l-67 -145zM640 1158l102 123l614 -513l-102 -123zM1037 1536l477 -641l-128 -96l-477 641zM319 65v159h800v-159h-800z" />
+ <glyph glyph-name="check-square-o" unicode="&#xf046;" horiz-adv-x="1663"
+d="M1408 606v-318c0 -159 -129 -288 -288 -288h-832c-159 0 -288 129 -288 288v832c0 159 129 288 288 288h832c40 0 80 -8 117 -25c9 -4 16 -13 18 -23c2 -11 -1 -21 -9 -29l-49 -49c-6 -6 -15 -10 -23 -10c-3 0 -6 1 -9 2c-15 4 -30 6 -45 6h-832
+c-88 0 -160 -72 -160 -160v-832c0 -88 72 -160 160 -160h832c88 0 160 72 160 160v254c0 8 3 16 9 22l64 64c7 7 15 10 23 10c4 0 8 -1 12 -3c12 -5 20 -16 20 -29zM1639 1095l-814 -814c-32 -32 -82 -32 -114 0l-430 430c-32 32 -32 82 0 114l110 110c32 32 82 32 114 0
+l263 -263l647 647c32 32 82 32 114 0l110 -110c32 -32 32 -82 0 -114z" />
+ <glyph glyph-name="emby" unicode="&#xf319;" horiz-adv-x="1534"
+d="M474 224l-62 -62l-412 415l356 356l-60 61l414 414l355 -355l58 57l411 -414l-352 -352l58 -58l-414 -414zM1091 633l-496 291v-578z" />
+ <glyph glyph-name="hand-spock-o" unicode="&#xf259;" horiz-adv-x="1920"
+d="M459 -256c-103 0 -192 70 -217 170l-101 401c-8 35 -13 72 -13 108c0 23 0 45 -5 67l-116 477c-5 19 -7 38 -7 57c0 124 94 226 217 239c22 113 119 193 235 193c111 0 207 -76 233 -184l83 -348l103 428c26 108 122 184 233 184c119 0 217 -86 236 -202
+c123 -14 212 -118 212 -241c0 -19 -3 -39 -7 -59l-123 -512c80 60 138 118 243 118c139 0 255 -113 255 -253c0 -84 -41 -162 -107 -212l-507 -380c-44 -33 -98 -51 -153 -51h-694zM1104 1408c-51 0 -96 -36 -108 -86l-164 -682h-127l-145 602c-12 50 -57 86 -108 86
+c-64 0 -112 -51 -112 -113c0 -10 1 -19 3 -28l132 -547h-26l-99 408c-12 49 -57 88 -109 88c-62 0 -113 -50 -113 -112c0 -9 1 -18 3 -26l116 -478c14 -58 4 -116 19 -174l100 -401c11 -43 49 -73 93 -73h694c27 0 54 9 76 26l507 379c34 26 56 67 56 110
+c0 70 -58 125 -127 125c-28 0 -55 -9 -77 -26l-307 -230v227c0 8 129 538 139 581c2 9 4 19 4 29c0 62 -47 115 -111 115c-52 0 -97 -36 -109 -86l-116 -482h-26l150 624c2 9 3 19 3 28c0 63 -46 116 -111 116z" />
+ <glyph glyph-name="scuttlebutt" unicode="&#xf2ea;" horiz-adv-x="1709"
+d="M760 -126c-31 4 -114 28 -131 38c-5 3 -12 10 -16 16l-8 10l-7 -5c-14 -9 -14 -9 -151 60c-70 36 -134 68 -141 71c-21 10 -30 25 -45 74c-5 17 -6 19 -12 21c-18 7 -84 50 -121 78c-27 21 -66 60 -70 70c-10 25 -31 91 -37 112c-18 60 -21 88 -21 178c0 60 0 68 4 76
+c5 11 24 29 46 43c29 19 128 68 192 96l8 4l-4 8c-3 5 -16 24 -29 42l-24 33h-10c-21 1 -28 3 -48 16s-21 13 -39 41c-56 87 -91 163 -95 205c-4 46 23 129 52 160c9 9 17 16 28 22c16 8 17 8 40 8c19 0 25 -1 35 -5c27 -11 44 -29 49 -50c2 -11 2 -17 -1 -43
+c-9 -68 -1 -127 21 -163c4 -6 16 -19 28 -29c19 -17 38 -37 38 -43c0 -7 4 -1 11 15c9 23 70 138 78 148l5 8l-2 25c-8 86 -8 113 0 139c5 18 16 33 31 39c26 12 96 16 121 8c15 -5 28 -14 35 -26c5 -7 6 -12 7 -27l1 -18l52 8c71 11 95 16 116 24c26 10 38 13 57 13
+c29 0 45 -6 104 -37c137 -72 176 -97 219 -139c24 -23 28 -31 49 -73c17 -34 19 -37 38 -57l20 -21l23 6c28 8 37 8 49 2c10 -5 22 -21 22 -29c0 -2 4 -9 9 -16c7 -10 24 -34 39 -58c0 0 6 1 12 3c13 5 27 6 38 1c4 -2 17 -10 28 -19c11 -8 20 -15 21 -15s12 -7 25 -15
+c13 -9 27 -17 32 -18s14 -6 20 -9c13 -8 27 -10 64 -13c15 -1 31 -4 35 -5c18 -5 46 -31 55 -51c8 -18 5 -43 -9 -65c-4 -6 -18 -21 -30 -33s-23 -23 -24 -26s1 -24 4 -47c8 -67 4 -101 -13 -127c-8 -12 -29 -26 -59 -40c-13 -6 -24 -13 -27 -15s-8 -14 -12 -26
+c-9 -26 -17 -44 -26 -54c-8 -10 -10 -18 -13 -57c-4 -53 -10 -71 -37 -99c-20 -21 -37 -29 -70 -39c-11 -3 -49 -16 -85 -28c-35 -12 -66 -22 -68 -22s-6 -5 -9 -11c-14 -25 -33 -48 -63 -75c-48 -43 -116 -83 -163 -97c-9 -3 -16 -7 -24 -14c-43 -38 -88 -56 -154 -62
+c-28 -2 -42 -3 -63 0zM820 -67c13 1 31 5 41 7c18 4 49 17 49 20c0 1 -9 6 -20 12s-37 22 -56 36c-70 48 -117 94 -124 121c-9 35 -9 157 1 321c2 29 3 52 2 53c-3 3 -131 99 -131 99c-2 -2 -20 -148 -25 -210c-5 -54 -7 -145 -4 -170c3 -21 10 -46 32 -105
+c24 -66 44 -109 63 -139l9 -14l26 -8c44 -15 83 -25 104 -25c5 0 20 1 33 2zM559 26c-15 35 -29 69 -47 122c-14 40 -15 45 -17 70c-6 75 4 212 26 365c4 29 7 55 7 57c0 3 -11 12 -33 28c-30 22 -50 32 -58 32c-5 0 -83 -100 -120 -153c-34 -49 -63 -103 -68 -122
+c-2 -10 42 -188 64 -258c16 -52 -1 -38 137 -108l120 -60s-5 12 -11 27zM988 8c27 8 80 38 113 63c21 16 45 38 44 39c-1 0 -24 -2 -51 -6c-28 -4 -58 -7 -68 -7c-45 0 -82 18 -99 48c-8 14 -22 51 -31 82c-7 24 -8 30 -9 64c-1 30 -3 43 -7 59c-6 22 -18 48 -26 55
+c-9 8 -48 36 -57 40c-5 2 -13 7 -18 10l-9 6l-1 -10c-4 -31 -7 -124 -7 -206c0 -107 -2 -99 22 -123c49 -49 155 -116 185 -117c4 0 13 1 19 3zM1086 191c27 4 59 9 71 11c31 6 92 24 138 41c22 8 49 17 61 20c39 11 51 21 55 44c1 8 2 8 -3 7c-48 -15 -87 -22 -143 -24
+c-94 -4 -148 8 -226 46c-23 12 -57 33 -74 47c-5 4 -9 7 -9 7s3 -13 6 -27c5 -20 7 -33 8 -62c2 -39 6 -57 22 -97c6 -14 7 -16 13 -18c12 -4 31 -2 81 5zM232 241c-1 2 -10 37 -20 78s-19 77 -20 79c-4 8 -3 30 3 48c18 54 75 143 164 253c11 13 19 25 19 26
+c0 3 -40 24 -53 27c-7 2 -20 6 -27 9c-13 5 -14 5 -22 1c-4 -2 -28 -13 -53 -24c-76 -34 -138 -68 -159 -84l-7 -5l1 -71c1 -78 3 -88 17 -138c6 -20 26 -79 36 -106c3 -8 33 -36 58 -55c20 -15 62 -42 64 -42c0 0 0 2 -1 4v0zM1306 380c32 4 65 11 87 20c16 7 40 20 47 27
+c5 5 12 18 11 20l-24 -2c-44 -4 -92 -5 -118 -2c-32 3 -55 10 -86 26c-59 29 -105 72 -127 117c-11 23 -13 31 -13 52c0 63 43 117 183 229c22 17 40 32 41 33c0 1 -7 14 -17 29l-18 28l-11 2c-11 2 -13 2 -44 -8c-41 -14 -52 -16 -104 -22c-23 -2 -48 -7 -55 -9
+c-17 -5 -40 -21 -57 -39c-19 -20 -75 -92 -90 -116c-19 -29 -19 -33 -11 -52c4 -9 13 -27 20 -41s16 -33 20 -43c6 -16 9 -25 23 -88c7 -34 14 -49 32 -69c31 -33 75 -60 131 -80c49 -17 105 -20 180 -12zM889 488c0 0 -1 6 -3 12s-6 26 -10 44c-8 41 -14 58 -29 86
+c-16 31 -34 71 -37 83c-3 14 1 37 9 58c10 24 35 62 74 111c54 68 87 98 126 115c19 8 40 13 80 17c18 2 35 4 38 5c5 1 5 1 -2 9c-11 13 -23 33 -36 62c-10 22 -16 31 -26 42c-29 31 -63 54 -150 100c-35 18 -68 36 -73 39c-14 9 -36 17 -46 17c-5 0 -19 -4 -31 -9
+c-25 -10 -61 -17 -144 -30c-29 -5 -53 -9 -54 -9c-3 -3 -2 -38 1 -62c7 -50 24 -108 42 -142c9 -18 10 -29 4 -39c-5 -8 -27 -28 -34 -31c-9 -4 -12 -25 -11 -72c0 -33 0 -38 6 -57c9 -29 14 -67 13 -106l-1 -32l86 -65c112 -84 134 -100 153 -111c9 -5 24 -15 34 -22
+c16 -12 21 -15 21 -13zM1392 530c61 4 104 12 148 30l26 11v13c1 12 -2 47 -4 49c0 1 -6 -1 -10 -3c-22 -12 -53 -16 -74 -9c-34 12 -72 52 -86 90c-5 13 -5 18 -4 34s1 21 7 34c8 18 25 39 39 51c6 5 11 9 11 10s-3 3 -7 4c-4 2 -14 8 -22 14l-14 11l-19 -16
+c-10 -9 -37 -32 -61 -51c-70 -55 -85 -67 -114 -98c-24 -24 -29 -32 -36 -46c-7 -13 -6 -18 -4 -28c10 -26 42 -57 80 -77c44 -24 66 -28 144 -23zM1533 717c27 16 74 54 62 49c-2 -1 -9 -2 -16 -3c-15 -1 -28 5 -38 17c-6 8 -8 8 -15 6c-18 -5 -43 -23 -51 -36
+c-4 -7 -5 -9 -2 -15c1 -4 8 -12 14 -19c11 -11 12 -12 20 -11c5 1 17 6 26 12zM525 805c-4 36 -5 39 -38 113c-9 21 -11 22 -17 22c-8 0 -16 4 -23 11c-3 3 -13 28 -23 55c-13 36 -18 48 -19 46c-4 -5 -29 -57 -35 -72c-10 -27 -13 -43 -19 -90c-4 -25 -7 -48 -7 -50
+c0 -3 5 -4 15 -7c8 -2 18 -7 23 -10s14 -7 20 -11s16 -10 21 -13s24 -10 41 -16c23 -8 35 -14 47 -22l16 -11v11c0 6 0 26 -2 44zM210 969c12 6 27 21 27 26c0 1 -11 11 -24 23c-40 34 -56 64 -67 125c-5 27 -5 80 0 114c4 24 4 25 0 27c-14 9 -30 11 -43 4
+c-9 -4 -10 -7 -21 -30c-22 -47 -28 -86 -19 -114c10 -32 40 -90 75 -146c26 -41 40 -47 72 -29zM519 1007c20 5 27 8 36 14c2 2 2 6 -4 22c-12 30 -23 69 -29 103c-7 36 -7 79 -3 124c3 27 2 70 -1 73c-5 5 -72 -1 -79 -7c-4 -4 -6 -29 -3 -62c-2 -41 16 -99 14 -134
+c-2 -25 0 -32 22 -93c14 -39 16 -45 20 -45c2 0 15 2 27 5z" />
+ <glyph glyph-name="social-home" unicode="&#xf2ec;" horiz-adv-x="1486"
+d="M491 894h482v-621h-482v621v0zM1050 538h341v-666h-341v666zM91 273v0v620h318v-620h-318zM975 -128h-882v326h882v-326v0zM1053 894h340v-279h-340v279zM1452 1109v0c20 -5 34 -22 34 -44c0 -26 -93 -93 -93 -93h-1300s-87 62 -92 83s5 42 25 51l624 292
+c16 9 99 9 112 0z" />
+ <glyph glyph-name="leanpub" unicode="&#xf212;" horiz-adv-x="2048"
+d="M1893 1144l155 -1272c-93 0 -173 19 -257 57c-125 57 -255 91 -393 91c-142 0 -273 -47 -374 -148c-101 101 -232 148 -374 148c-138 0 -268 -34 -393 -91c-81 -36 -163 -57 -252 -57h-5l155 1272c143 81 317 127 482 127c135 0 274 -28 387 -106c113 78 252 106 387 106
+c165 0 339 -46 482 -127zM1398 157c190 0 320 -51 492 -122l-124 1021c-112 51 -245 78 -368 78c-140 0 -271 -44 -374 -141c-103 97 -234 141 -374 141c-123 0 -256 -27 -368 -78l-124 -1021c172 71 302 122 492 122c137 0 258 -35 374 -108c116 73 237 108 374 108z
+M1438 191l-40 1c-132 3 -261 -32 -374 -102c-113 70 -242 102 -374 102c-166 0 -299 -39 -450 -101l114 941c104 43 224 66 336 66c150 0 269 -48 374 -155c101 103 215 152 359 155z" />
+ <glyph glyph-name="arrow-circle-left" unicode="&#xf0a8;"
+d="M1280 576v128c0 35 -29 64 -64 64h-502l189 189c12 12 19 28 19 45s-7 33 -19 45l-91 91c-12 12 -28 18 -45 18s-33 -6 -45 -18l-362 -362l-91 -91c-12 -12 -18 -28 -18 -45s6 -33 18 -45l91 -91l362 -362c12 -12 28 -18 45 -18s33 6 45 18l91 91c12 12 18 28 18 45
+s-6 33 -18 45l-189 189h502c35 0 64 29 64 64zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="exclamation-triangle" unicode="&#xf071;" horiz-adv-x="1792"
+d="M1024 161v190c0 18 -14 33 -32 33h-192c-18 0 -32 -15 -32 -33v-190c0 -18 14 -33 32 -33h192c18 0 32 15 32 33zM1022 535l18 459c0 6 -3 14 -10 19c-6 5 -15 11 -24 11h-220c-9 0 -18 -6 -24 -11c-7 -5 -10 -15 -10 -21l17 -457c0 -13 15 -23 34 -23h185
+c18 0 33 10 34 23zM1008 1469l768 -1408c22 -39 21 -87 -2 -126s-65 -63 -110 -63h-1536c-45 0 -87 24 -110 63s-24 87 -2 126l768 1408c22 41 65 67 112 67s90 -26 112 -67z" />
+ <glyph glyph-name="gift" unicode="&#xf06b;"
+d="M928 180v716h-320v-716c0 -35 29 -52 64 -52h192c35 0 64 17 64 52zM472 1024h195l-126 161c-11 13 -35 31 -69 31c-53 0 -96 -43 -96 -96s43 -96 96 -96zM1160 1120c0 53 -43 96 -96 96c-34 0 -58 -18 -69 -31l-125 -161h194c53 0 96 43 96 96zM1536 864v-320
+c0 -18 -14 -32 -32 -32h-96v-416c0 -53 -43 -96 -96 -96h-1088c-53 0 -96 43 -96 96v416h-96c-18 0 -32 14 -32 32v320c0 18 14 32 32 32h440c-124 0 -224 100 -224 224s100 224 224 224c67 0 129 -28 168 -77l128 -165l128 165c39 49 101 77 168 77
+c124 0 224 -100 224 -224s-100 -224 -224 -224h440c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="cogs" unicode="&#xf085;" horiz-adv-x="1920"
+d="M896 640c0 141 -115 256 -256 256s-256 -115 -256 -256s115 -256 256 -256s256 115 256 256zM1664 128c0 70 -58 128 -128 128s-128 -58 -128 -128c0 -71 58 -128 128 -128c71 0 128 58 128 128zM1664 1152c0 70 -58 128 -128 128s-128 -58 -128 -128
+c0 -71 58 -128 128 -128c71 0 128 58 128 128zM1280 731v-185c0 -13 -10 -28 -23 -30l-155 -24c-8 -26 -19 -51 -32 -76c28 -40 58 -77 90 -115c4 -6 7 -12 7 -20c0 -7 -2 -14 -7 -19c-20 -27 -132 -149 -161 -149c-8 0 -15 3 -21 7l-115 90c-25 -13 -50 -23 -77 -31
+c-5 -51 -10 -106 -23 -155c-4 -14 -16 -24 -30 -24h-186c-14 0 -28 11 -30 25l-23 153c-26 8 -51 19 -75 31l-118 -89c-5 -5 -13 -7 -20 -7c-8 0 -15 3 -21 8c-26 24 -144 131 -144 160c0 7 3 13 7 19c29 38 59 75 88 114c-14 27 -26 54 -35 82l-152 24c-14 2 -24 15 -24 29
+v185c0 13 10 28 23 30l155 24c8 26 19 51 32 76c-28 40 -58 77 -90 115c-4 6 -7 13 -7 20s2 14 7 20c20 27 132 148 161 148c8 0 15 -3 21 -7l115 -90c25 13 50 23 77 32c5 50 10 105 23 154c4 14 16 24 30 24h186c14 0 28 -11 30 -25l23 -153c26 -8 51 -19 75 -31l118 89
+c6 5 13 7 20 7c8 0 15 -3 21 -8c26 -24 144 -132 144 -160c0 -7 -3 -13 -7 -19c-29 -39 -59 -75 -87 -114c13 -27 25 -54 34 -82l152 -23c14 -3 24 -16 24 -30zM1920 198v-140c0 -15 -129 -29 -149 -31c-8 -19 -18 -36 -30 -52c9 -20 51 -120 51 -138c0 -3 -1 -5 -4 -7
+c-12 -7 -119 -71 -124 -71c-13 0 -88 100 -98 115c-10 -1 -20 -2 -30 -2s-20 1 -30 2c-10 -15 -85 -115 -98 -115c-5 0 -112 64 -124 71c-3 2 -4 5 -4 7c0 17 42 118 51 138c-12 16 -22 33 -30 52c-20 2 -149 16 -149 31v140c0 15 129 29 149 31c8 18 18 36 30 52
+c-9 20 -51 121 -51 138c0 2 1 5 4 7c12 6 119 70 124 70c13 0 88 -99 98 -114c10 1 20 2 30 2s20 -1 30 -2c28 39 58 78 92 112l6 2c5 0 112 -63 124 -70c3 -2 4 -5 4 -7c0 -18 -42 -118 -51 -138c12 -16 22 -34 30 -52c20 -2 149 -16 149 -31zM1920 1222v-140
+c0 -15 -129 -29 -149 -31c-8 -19 -18 -36 -30 -52c9 -20 51 -120 51 -138c0 -3 -1 -5 -4 -7c-12 -7 -119 -71 -124 -71c-13 0 -88 100 -98 115c-10 -1 -20 -2 -30 -2s-20 1 -30 2c-10 -15 -85 -115 -98 -115c-5 0 -112 64 -124 71c-3 2 -4 5 -4 7c0 17 42 118 51 138
+c-12 16 -22 33 -30 52c-20 2 -149 16 -149 31v140c0 15 129 29 149 31c8 18 18 36 30 52c-9 20 -51 121 -51 138c0 2 1 5 4 7c12 6 119 70 124 70c13 0 88 -99 98 -114c10 1 20 2 30 2s20 -1 30 -2c28 39 58 78 92 112l6 2c5 0 112 -63 124 -70c3 -2 4 -5 4 -7
+c0 -18 -42 -118 -51 -138c12 -16 22 -34 30 -52c20 -2 149 -16 149 -31z" />
+ <glyph glyph-name="hackaday" unicode="&#xf30a;" horiz-adv-x="1686"
+d="M215 1408c118 0 214 -95 215 -213v-2c0 -11 -1 -21 -3 -31l168 -149c-60 -45 -109 -106 -142 -178l-173 154c-21 -7 -42 -11 -65 -11c-119 0 -215 96 -215 215c0 14 1 28 4 42l138 -122l150 167l-134 120c18 5 37 8 57 8zM1247 436l162 -143c17 5 45 9 62 9v0
+c118 0 214 -95 215 -213v-2c0 -13 -2 -26 -4 -39l-139 123l-150 -166l140 -124c-20 -6 -41 -9 -62 -9c-119 0 -215 96 -215 215c0 12 1 24 3 35l-140 124c56 50 100 115 128 190zM1471 1408c20 0 39 -3 57 -8l-134 -120l150 -167l138 122c3 -14 4 -28 4 -42
+c0 -119 -96 -215 -215 -215c-23 0 -44 4 -65 11l-174 -154c-33 72 -81 133 -141 178l167 149c-2 10 -2 20 -2 31v2c1 118 97 213 215 213zM439 436v0c28 -75 71 -140 127 -190l-139 -124c2 -11 3 -23 3 -35c0 -119 -96 -215 -215 -215c-21 0 -42 3 -62 9l140 124l-150 166
+l-139 -123c-2 13 -4 26 -4 39v2c1 118 97 213 215 213v0c17 0 45 -4 62 -9zM843 1062c222 0 401 -199 401 -445c0 -153 -69 -288 -175 -368c8 -12 12 -26 12 -41c0 -42 -33 -76 -75 -76s-76 34 -76 76c0 4 0 8 1 12h-13c1 -3 0 -9 0 -12v0c0 -42 -33 -76 -75 -76
+s-76 34 -76 76c0 4 0 8 1 12h-10v-9c0 -43 -35 -79 -77 -79s-77 36 -77 79c0 15 4 28 11 40c-105 80 -173 214 -173 366c0 246 179 445 401 445zM670 730c-8 0 -15 -1 -22 -3c-28 -4 -52 -23 -69 -45c-15 -18 -26 -40 -26 -64c-2 -20 1 -39 5 -58c5 -23 21 -41 39 -54
+c8 -7 20 -16 31 -8c7 9 1 23 7 33c2 10 9 18 18 23c18 9 37 18 57 25c16 5 29 15 43 24c18 14 30 40 21 62c-10 18 -22 34 -39 46c-19 12 -42 19 -65 19zM1015 730c-23 0 -45 -7 -64 -19c-17 -12 -29 -28 -39 -46c-9 -22 3 -48 21 -62c14 -9 27 -19 43 -24
+c20 -7 38 -16 56 -25c9 -5 17 -13 19 -23c6 -10 0 -24 7 -33c11 -8 23 1 31 8c18 13 34 31 39 54c4 19 7 38 5 58c0 24 -11 46 -26 64c-17 22 -41 41 -69 45c-7 2 -15 3 -23 3zM844 502c-20 1 -44 -88 -40 -126c12 -51 16 36 40 36c23 -1 19 -88 37 -35
+c5 35 -16 124 -37 125z" />
+ <glyph glyph-name="frown-o" unicode="&#xf119;"
+d="M1134 307c11 -34 -8 -69 -41 -80c-34 -11 -70 8 -81 42c-33 107 -132 179 -244 179s-211 -72 -244 -179c-11 -34 -47 -53 -80 -42c-34 11 -53 46 -42 80c50 161 197 269 366 269s316 -108 366 -269zM640 896c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128
+s128 -57 128 -128zM1152 896c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128s128 -57 128 -128zM1408 640c0 353 -287 640 -640 640s-640 -287 -640 -640s287 -640 640 -640s640 287 640 640zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768
+s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="opera" unicode="&#xf26a;" horiz-adv-x="1792"
+d="M1493 1308c-105 70 -228 110 -359 110c-213 0 -401 -109 -533 -273c-96 -120 -163 -290 -168 -484v-42c5 -194 72 -364 168 -484c132 -164 320 -273 533 -273c131 0 254 40 359 110c-158 -142 -368 -228 -597 -228c-14 0 -29 0 -43 1c-475 22 -853 414 -853 895
+c0 495 401 896 896 896h3c228 -1 436 -87 594 -228zM1792 640c0 -261 -112 -495 -290 -659c-68 -41 -143 -63 -222 -63c-92 0 -179 30 -255 84c203 74 353 331 353 638c0 306 -149 563 -352 638c76 53 162 83 254 83c81 0 157 -23 226 -65c176 -164 286 -397 286 -656z" />
+ <glyph glyph-name="viadeo" unicode="&#xf2a9;" horiz-adv-x="1278"
+d="M1050 430c0 -143 -50 -269 -147 -374c-101 -110 -229 -161 -378 -161c-148 0 -277 50 -378 161c-97 105 -147 231 -147 374c0 297 224 540 525 540c62 0 124 -10 182 -31c-20 -39 -34 -82 -39 -126c-45 19 -94 28 -143 28c-227 0 -394 -194 -394 -414
+c0 -224 166 -407 394 -407s393 183 393 407c0 57 -10 113 -32 166c44 9 86 26 123 49c28 -67 41 -140 41 -212zM846 619c0 111 -19 221 -55 326c3 -34 3 -69 3 -103c0 -268 -53 -707 -342 -817c20 -3 41 -5 62 -5l14 1c216 136 318 346 318 598zM791 947v-2
+c-52 153 -124 301 -206 440c126 -85 195 -291 206 -438zM1035 744c-62 0 -117 33 -160 75c102 56 231 143 290 247c7 14 19 40 21 56c-58 -130 -206 -232 -344 -264c-22 34 -35 72 -35 113c0 48 24 112 60 147c41 39 102 59 157 74c80 22 145 84 180 159
+c52 -74 74 -164 74 -253c0 -45 -7 -127 -24 -170c-37 -90 -112 -184 -219 -184z" />
+ <glyph glyph-name="battery-empty" unicode="&#xf244;" horiz-adv-x="2304"
+d="M2176 960c71 0 128 -57 128 -128v-384c0 -71 -57 -128 -128 -128v-160c0 -88 -72 -160 -160 -160h-1856c-88 0 -160 72 -160 160v960c0 88 72 160 160 160h1856c88 0 160 -72 160 -160v-160zM2176 448v384h-128v288c0 18 -14 32 -32 32h-1856c-18 0 -32 -14 -32 -32v-960
+c0 -18 14 -32 32 -32h1856c18 0 32 14 32 32v288h128z" />
+ <glyph glyph-name="freedombox" unicode="&#xf2fd;" horiz-adv-x="1816"
+d="M152 1274v0h10c90 -2 180 -36 272 -79c4 -2 11 -5 15 -7c7 -3 13 -7 20 -10c116 -58 199 -126 267 -210l3 -3c2 -2 4 -7 6 -9l-255 -148l9 -492l37 465l50 -29l10 -491l37 464l49 -29l10 -490l37 463l50 -29l9 -488l37 461l50 -29l10 -487l37 466l422 245l-267 155
+c2 3 5 5 7 8s5 6 7 9c70 83 157 151 278 208c101 48 200 86 296 86h9c45 -1 84 -15 110 -44c80 -92 -8 -177 -39 -293c-41 -155 6 -321 -118 -429c-43 -37 -93 -47 -143 -52c65 -77 103 -183 82 -292c-4 -21 -10 -42 -18 -61c-6 -17 -13 -32 -22 -47l-9 -15
+c-2 -2 -3 -5 -5 -7c-63 -94 -168 -154 -281 -161c-6 0 -11 -1 -17 -1h-9c-15 0 -39 3 -53 5c-19 3 -49 12 -67 19c-3 1 -7 2 -9 3c-69 29 -124 80 -159 143c-2 3 -4 5 -5 8c-2 3 -5 3 -7 0c-1 -3 -3 -5 -5 -8s-2 -5 -4 -8c-48 -81 -131 -140 -231 -157c-12 -2 -23 -3 -35 -4
+c-6 0 -12 -1 -18 -1c-169 -3 -327 118 -361 292c-21 109 18 215 83 292c-50 5 -101 15 -144 52c-124 108 -78 274 -119 429c-31 116 -118 201 -38 293c26 29 65 43 110 44h9z" />
+ <glyph glyph-name="file-epub" unicode="&#xf321;"
+d="M723 132l458 458l70 -71c24 -24 24 -64 0 -88l-483 -483c-24 -24 -65 -24 -89 0l-483 483c-24 24 -24 64 0 88l483 484c24 24 65 24 89 0l298 -299l-343 -343l-114 114l229 229l-115 114l-343 -343zM1468 1156c37 -37 68 -111 68 -164v-1152c0 -53 -43 -96 -96 -96h-1344
+c-53 0 -96 43 -96 96v1600c0 53 43 96 96 96h896c53 0 127 -31 164 -68zM1024 1400v-376h376c-6 17 -15 34 -22 41l-313 313c-7 7 -24 16 -41 22zM1408 -128v1024h-416c-53 0 -96 43 -96 96v416h-768v-1536h1280z" />
+ <glyph glyph-name="chevron-circle-left" unicode="&#xf137;"
+d="M909 141l102 102c25 25 25 65 0 90l-307 307l307 307c25 25 25 65 0 90l-102 102c-25 25 -65 25 -90 0l-454 -454c-25 -25 -25 -65 0 -90l454 -454c25 -25 65 -25 90 0zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="signal" unicode="&#xf012;" horiz-adv-x="1792"
+d="M256 96v-192c0 -18 -14 -32 -32 -32h-192c-18 0 -32 14 -32 32v192c0 18 14 32 32 32h192c18 0 32 -14 32 -32zM640 224v-320c0 -18 -14 -32 -32 -32h-192c-18 0 -32 14 -32 32v320c0 18 14 32 32 32h192c18 0 32 -14 32 -32zM1024 480v-576c0 -18 -14 -32 -32 -32h-192
+c-18 0 -32 14 -32 32v576c0 18 14 32 32 32h192c18 0 32 -14 32 -32zM1408 864v-960c0 -18 -14 -32 -32 -32h-192c-18 0 -32 14 -32 32v960c0 18 14 32 32 32h192c18 0 32 -14 32 -32zM1792 1376v-1472c0 -18 -14 -32 -32 -32h-192c-18 0 -32 14 -32 32v1472
+c0 18 14 32 32 32h192c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="sitemap" unicode="&#xf0e8;" horiz-adv-x="1792"
+d="M1792 288v-320c0 -53 -43 -96 -96 -96h-320c-53 0 -96 43 -96 96v320c0 53 43 96 96 96h96v192h-512v-192h96c53 0 96 -43 96 -96v-320c0 -53 -43 -96 -96 -96h-320c-53 0 -96 43 -96 96v320c0 53 43 96 96 96h96v192h-512v-192h96c53 0 96 -43 96 -96v-320
+c0 -53 -43 -96 -96 -96h-320c-53 0 -96 43 -96 96v320c0 53 43 96 96 96h96v192c0 70 58 128 128 128h512v192h-96c-53 0 -96 43 -96 96v320c0 53 43 96 96 96h320c53 0 96 -43 96 -96v-320c0 -53 -43 -96 -96 -96h-96v-192h512c70 0 128 -58 128 -128v-192h96
+c53 0 96 -43 96 -96z" />
+ <glyph glyph-name="wheelchair-alt" unicode="&#xf29b;" horiz-adv-x="1399"
+d="M1370 723c21 -22 32 -52 29 -82l-44 -551c-5 -56 -51 -98 -106 -98c-3 0 -6 0 -9 1c-59 4 -102 56 -98 114l35 429l-143 -8c35 -72 55 -154 55 -240c0 -144 -56 -275 -148 -372l-137 137c56 62 91 145 91 235c0 194 -157 351 -350 351c-91 0 -173 -35 -236 -92l-137 138
+c77 73 175 123 284 141l264 300l-149 87l-181 -161c-44 -40 -111 -36 -150 8s-35 111 8 150l239 213c34 31 84 36 124 12c487 -283 488 -283 488 -283c26 -15 41 -41 48 -68c10 -39 3 -83 -26 -117l-205 -232l371 20c31 2 61 -9 83 -32zM1172 1180c-98 0 -178 79 -178 178
+c0 98 80 178 178 178c99 0 179 -80 179 -178c0 -99 -80 -178 -179 -178zM545 -62c72 0 140 23 196 61l139 -139c-92 -73 -209 -116 -335 -116c-301 0 -545 244 -545 544c0 127 43 243 116 336l139 -139c-38 -56 -60 -124 -60 -197c0 -193 157 -350 350 -350z" />
+ <glyph glyph-name="external-link-square" unicode="&#xf14c;"
+d="M1280 608v480c0 35 -29 64 -64 64h-480c-26 0 -49 -16 -59 -39c-10 -24 -5 -52 14 -70l144 -144l-534 -534c-25 -25 -25 -65 0 -90l102 -102c25 -25 65 -25 90 0l534 534l144 -144c12 -13 28 -19 45 -19c8 0 17 2 25 5c23 10 39 33 39 59zM1536 1120v-960
+c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="google" unicode="&#xf1a0;" horiz-adv-x="1505"
+d="M768 750h725c7 -39 12 -77 12 -128c0 -438 -294 -750 -737 -750c-425 0 -768 343 -768 768s343 768 768 768c207 0 381 -76 515 -201l-209 -201c-57 55 -157 119 -306 119c-262 0 -476 -217 -476 -485s214 -485 476 -485c304 0 418 218 436 331h-436v264z" />
+ <glyph glyph-name="volume-off" unicode="&#xf026;" horiz-adv-x="768"
+d="M768 1184v-1088c0 -35 -29 -64 -64 -64c-17 0 -33 7 -45 19l-333 333h-262c-35 0 -64 29 -64 64v384c0 35 29 64 64 64h262l333 333c12 12 28 19 45 19c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="twitter" unicode="&#xf099;" horiz-adv-x="1576"
+d="M1576 1128c-44 -64 -99 -121 -162 -167c1 -14 1 -28 1 -42c0 -427 -325 -919 -919 -919c-183 0 -353 53 -496 145c26 -3 51 -4 78 -4c151 0 290 51 401 138c-142 3 -261 96 -302 224c20 -3 40 -5 61 -5c29 0 58 4 85 11c-148 30 -259 160 -259 317v4
+c43 -24 93 -39 146 -41c-87 58 -144 157 -144 269c0 60 16 115 44 163c159 -196 398 -324 666 -338c-5 24 -8 49 -8 74c0 178 144 323 323 323c93 0 177 -39 236 -102c73 14 143 41 205 78c-24 -75 -75 -138 -142 -178c65 7 128 25 186 50z" />
+ <glyph glyph-name="battery-full" unicode="&#xf240;" horiz-adv-x="2304"
+d="M1920 1024v-768h-1664v768h1664zM2048 448h128v384h-128v288c0 18 -14 32 -32 32h-1856c-18 0 -32 -14 -32 -32v-960c0 -18 14 -32 32 -32h1856c18 0 32 14 32 32v288zM2304 832v-384c0 -71 -57 -128 -128 -128v-160c0 -88 -72 -160 -160 -160h-1856
+c-88 0 -160 72 -160 160v960c0 88 72 160 160 160h1856c88 0 160 -72 160 -160v-160c71 0 128 -57 128 -128z" />
+ <glyph glyph-name="deaf" unicode="&#xf2a4;" horiz-adv-x="1792"
+d="M1056 704c0 124 -101 224 -224 224s-224 -100 -224 -224c0 -35 -29 -64 -64 -64s-64 29 -64 64c0 194 158 352 352 352s352 -158 352 -352c0 -35 -29 -64 -64 -64s-64 29 -64 64zM835 1280c318 0 576 -258 576 -576c0 -166 -78 -255 -146 -334
+c-63 -72 -113 -129 -113 -242c0 -212 -172 -384 -384 -384c-35 0 -64 29 -64 64s29 64 64 64c141 0 256 115 256 256c0 161 77 249 144 326c62 71 115 132 115 250c0 247 -201 448 -448 448s-448 -201 -448 -448c0 -35 -29 -64 -64 -64s-64 29 -64 64c0 318 258 576 576 576
+zM591 561l226 -226l-579 -579c-16 -16 -42 -16 -58 0l-168 168c-16 16 -16 42 0 58zM1612 1524l168 -168c16 -16 16 -42 0 -59l-233 -233l-26 -25l-71 -71c-43 100 -109 188 -195 258l91 91l207 207c17 16 43 16 59 0z" />
+ <glyph glyph-name="window-close-o" unicode="&#xf2d4;" horiz-adv-x="1792"
+d="M1257 425l-146 -146c-13 -13 -33 -13 -46 0l-169 169l-169 -169c-13 -13 -33 -13 -46 0l-146 146c-13 13 -13 33 0 46l169 169l-169 169c-13 13 -13 33 0 46l146 146c13 13 33 13 46 0l169 -169l169 169c13 13 33 13 46 0l146 -146c13 -13 13 -33 0 -46l-169 -169
+l169 -169c13 -13 13 -33 0 -46zM256 128h1280v1024h-1280v-1024zM1792 1248v-1216c0 -88 -72 -160 -160 -160h-1472c-88 0 -160 72 -160 160v1216c0 88 72 160 160 160h1472c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="phone" unicode="&#xf095;" horiz-adv-x="1408"
+d="M1408 296c0 -36 -16 -106 -31 -139c-21 -49 -77 -81 -122 -106c-59 -32 -119 -51 -186 -51c-93 0 -177 38 -262 69c-61 22 -120 49 -175 83c-170 105 -375 310 -480 480c-34 55 -61 114 -83 175c-31 85 -69 169 -69 262c0 67 19 127 51 186c25 45 57 101 106 122
+c33 15 103 31 139 31c7 0 14 0 21 -3c21 -7 43 -56 53 -76c32 -57 63 -115 96 -171c16 -26 46 -58 46 -89c0 -61 -181 -150 -181 -204c0 -27 25 -62 39 -86c101 -182 227 -308 409 -409c24 -14 59 -39 86 -39c54 0 143 181 204 181c31 0 63 -30 89 -46
+c56 -33 114 -64 171 -96c20 -10 69 -32 76 -53c3 -7 3 -14 3 -21z" />
+ <glyph glyph-name="mars-double" unicode="&#xf227;" horiz-adv-x="1920"
+d="M1536 1120c0 18 14 32 32 32h288c35 0 64 -29 64 -64v-288c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v134l-254 -255c98 -123 147 -286 117 -461c-42 -243 -240 -434 -484 -468c-286 -40 -539 131 -626 380c-316 16 -565 288 -544 613c18 274 235 502 508 533
+c161 19 311 -31 426 -122l255 254h-134c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h288c35 0 64 -29 64 -64v-288c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v134l-254 -255c40 -50 71 -107 93 -169c124 -6 237 -52 328 -124l255 254h-134c-18 0 -32 14 -32 32v64z
+M1024 704c0 20 -2 39 -4 58c-215 -33 -380 -218 -380 -442c0 -20 2 -39 4 -58c215 33 380 218 380 442zM128 704c0 -226 169 -413 387 -443c-2 19 -3 39 -3 59c0 282 204 517 473 566c-70 157 -227 266 -409 266c-247 0 -448 -201 -448 -448zM1088 -128
+c247 0 448 201 448 448c0 226 -169 413 -387 443c2 -19 3 -39 3 -59c0 -282 -204 -517 -473 -566c70 -157 227 -266 409 -266z" />
+ <glyph glyph-name="maxcdn" unicode="&#xf136;" horiz-adv-x="1755"
+d="M1745 763l-164 -763h-334l178 832c8 35 3 67 -15 88c-17 21 -47 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334l204 953l-153 327h1276c135 0 258 -56 337 -154c80 -98 109 -231 81 -363z" />
+ <glyph glyph-name="hand-peace-o" unicode="&#xf25b;"
+d="M1288 889c37 0 74 -7 107 -23c96 -43 141 -122 141 -226v-177c0 -63 -8 -126 -23 -186l-85 -339c-28 -114 -130 -194 -248 -194h-668c-141 0 -256 115 -256 256v401l-239 628c-11 29 -17 60 -17 91c0 141 115 256 256 256c106 0 202 -66 239 -165l17 -44v113
+c0 141 115 256 256 256s256 -115 256 -256v-261c16 3 32 5 48 5c92 0 176 -53 216 -135zM1072 896c-44 0 -84 -26 -102 -66l-74 -163l-71 -155h55c67 0 126 -47 140 -112l154 338c7 14 10 30 10 46c0 62 -50 112 -112 112zM1293 761c-76 0 -100 -61 -127 -121l-132 -290
+c-7 -14 -10 -30 -10 -46c0 -62 50 -112 112 -112c44 0 84 26 102 66l160 352c5 10 9 26 9 38c0 67 -48 113 -114 113zM128 1120c0 -16 3 -31 8 -46l248 -650v-69l102 111c27 29 66 46 106 46h198l106 233v535c0 71 -57 128 -128 128s-128 -57 -128 -128v-640h-64l-200 526
+c-19 49 -67 82 -120 82c-71 0 -128 -58 -128 -128zM1180 -128c59 0 110 40 124 97l85 339c13 50 19 103 19 155v91l-141 -310c-23 -51 -75 -84 -131 -84c-70 0 -131 51 -142 121c-27 -35 -69 -57 -114 -57h-208v32h208c61 0 116 50 116 112c0 61 -46 112 -108 112h-296
+c-31 0 -61 -13 -82 -36l-126 -136v-308c0 -71 57 -128 128 -128h668z" />
+ <glyph glyph-name="envira" unicode="&#xf299;" horiz-adv-x="1792"
+d="M896 720c-127 240 -244 474 -577 632c-199 94 -21 -37 -21 -37c181 -125 264 -294 361 -479c126 -241 316 -559 577 -671c260 -112 137 -50 24 34c-113 85 -273 348 -364 521zM549 177c-361 286 -341 628 -549 1359c1911 0 1467 -1269 1469 -1465l323 -327h-104l-281 285
+c-156 -17 -498 -138 -858 148z" />
+ <glyph glyph-name="lastfm-square" unicode="&#xf203;"
+d="M1432 484c0 141 -114 205 -234 239c-55 15 -100 28 -120 88c-1 5 -6 24 -6 28c0 48 38 83 85 83c22 0 53 1 71 -15h-1c19 -14 28 -30 39 -51l93 71c-15 21 -30 46 -49 64c-47 42 -91 49 -153 49c-105 0 -204 -86 -204 -195c0 -8 1 -15 2 -23c22 -136 91 -178 213 -213
+c60 -17 145 -44 146 -118v-5c1 -80 -66 -128 -141 -128c-82 0 -135 78 -167 144c-116 239 -134 538 -478 538c-207 0 -393 -191 -386 -396v-1c7 -214 154 -403 380 -403c107 0 207 25 279 110c12 16 23 33 31 51l-60 109c-56 -106 -125 -152 -245 -152
+c-158 0 -267 140 -267 291c0 139 128 273 268 273c160 0 218 -83 274 -226c67 -172 139 -456 371 -456c139 0 259 101 259 244zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="home" unicode="&#xf015;" horiz-adv-x="1612"
+d="M1382 544v-480c0 -35 -29 -64 -64 -64h-384v384h-256v-384h-384c-35 0 -64 29 -64 64v480c0 2 1 4 1 6l575 474l575 -474c1 -2 1 -4 1 -6zM1605 613l-62 -74c-5 -6 -13 -10 -21 -11h-3c-8 0 -15 2 -21 7l-692 577l-692 -577c-7 -5 -15 -8 -24 -7c-8 1 -16 5 -21 11
+l-62 74c-11 13 -9 34 4 45l719 599c42 35 110 35 152 0l244 -204v195c0 18 14 32 32 32h192c18 0 32 -14 32 -32v-408l219 -182c13 -11 15 -32 4 -45z" />
+ <glyph glyph-name="empire" unicode="&#xf1d1;" horiz-adv-x="1792"
+d="M874 -102v-66c-282 8 -529 160 -668 385l58 34c21 -35 46 -68 73 -99l65 57c94 -107 222 -183 368 -212l-17 -86c39 -7 80 -12 121 -13zM276 428l-83 -28c14 -39 30 -76 49 -112l-57 -33c-62 114 -98 246 -98 385s36 271 98 385l57 -33c-19 -35 -36 -73 -49 -112l82 -28
+c-23 -66 -35 -138 -35 -212s13 -146 36 -212zM1528 251l58 -34c-139 -225 -386 -377 -668 -385v66c41 1 82 6 121 13l-17 86c146 29 274 105 368 212l65 -57c27 31 52 64 73 99zM1377 805l-233 -80c9 -27 14 -55 14 -85s-5 -58 -14 -85l232 -80c-21 -63 -55 -120 -98 -169
+l-185 162c-37 -43 -88 -73 -147 -85l48 -241c-31 -6 -64 -10 -98 -10s-67 4 -98 10l48 241c-59 12 -110 42 -147 85l-185 -162c-43 49 -77 106 -98 169l232 80c-9 27 -14 55 -14 85s5 58 14 85l-233 80c22 63 56 120 99 169l185 -162c37 43 88 74 147 86l-48 240
+c31 7 64 10 98 10s67 -3 98 -10l-48 -240c59 -12 110 -43 147 -86l185 162c43 -49 77 -106 99 -169zM874 1448v-66c-41 -1 -82 -5 -121 -13l17 -86c-146 -28 -274 -104 -368 -211l-65 56c-27 -30 -51 -63 -73 -98l-57 33c139 226 385 377 667 385zM1705 640
+c0 -139 -36 -271 -98 -385l-57 33c19 36 35 73 49 112l-83 28c23 66 36 138 36 212s-12 146 -35 212l82 28c-13 39 -30 77 -49 112l57 33c62 -114 98 -246 98 -385zM1585 1063l-57 -33c-22 35 -46 68 -73 98l-65 -56c-94 107 -222 183 -368 211l17 86c-39 8 -80 12 -121 13
+v66c282 -8 528 -159 667 -385zM1748 640c0 470 -382 852 -852 852s-852 -382 -852 -852s382 -852 852 -852s852 382 852 852zM1792 640c0 -495 -401 -896 -896 -896s-896 401 -896 896s401 896 896 896s896 -401 896 -896z" />
+ <glyph glyph-name="server" unicode="&#xf233;" horiz-adv-x="1792"
+d="M128 128h1024v128h-1024v-128zM128 640h1024v128h-1024v-128zM1696 192c0 53 -43 96 -96 96s-96 -43 -96 -96s43 -96 96 -96s96 43 96 96zM128 1152h1024v128h-1024v-128zM1696 704c0 53 -43 96 -96 96s-96 -43 -96 -96s43 -96 96 -96s96 43 96 96zM1696 1216
+c0 53 -43 96 -96 96s-96 -43 -96 -96s43 -96 96 -96s96 43 96 96zM1792 384v-384h-1792v384h1792zM1792 896v-384h-1792v384h1792zM1792 1408v-384h-1792v384h1792z" />
+ <glyph glyph-name="inkscape" unicode="&#xf312;"
+d="M755 1398v0c47 0 95 -17 131 -52l588 -601c234 -234 -259 -288 -401 -371c-50 -51 153 -85 132 -147c-42 -126 -157 -45 -280 -171c-50 -51 95 -46 45 -97c-93 -68 -285 -115 -300 -32c-21 117 -135 68 -185 119s101 104 51 155s-299 97 -349 148s191 88 141 139
+c-138 68 -461 41 -269 278l567 580c34 35 82 52 129 52zM760 1343v0c-34 0 -68 -13 -93 -38c-49 -50 -140 -138 -219 -223c-45 -45 -40 -109 10 -109h123l80 139l49 -199l149 95l93 -49l22 131l111 -89c12 12 12 54 -9 76l-224 228c-24 25 -58 38 -92 38zM491 456
+c-74 0 219 -119 279 -103c27 14 40 34 21 38c-56 9 -285 56 -300 65zM1390 297c43 -1 86 -22 100 -63c0 -54 -212 -36 -212 -7c13 47 63 71 112 70zM409 172c26 0 50 -8 64 -26c-23 -61 -101 -115 -151 -72c-57 50 21 99 87 98zM1251 168c71 -14 85 -65 71 -79
+c-64 -38 -136 21 -71 79z" />
+ <glyph glyph-name="search-minus" unicode="&#xf010;" horiz-adv-x="1664"
+d="M1024 736v-64c0 -17 -15 -32 -32 -32h-576c-17 0 -32 15 -32 32v64c0 17 15 32 32 32h576c17 0 32 -15 32 -32zM1152 704c0 247 -201 448 -448 448s-448 -201 -448 -448s201 -448 448 -448s448 201 448 448zM1664 -128c0 -71 -57 -128 -128 -128c-34 0 -67 14 -90 38
+l-343 342c-117 -81 -257 -124 -399 -124c-389 0 -704 315 -704 704s315 704 704 704s704 -315 704 -704c0 -142 -43 -282 -124 -399l343 -343c23 -23 37 -56 37 -90z" />
+ <glyph glyph-name="leaf" unicode="&#xf06c;" horiz-adv-x="1792"
+d="M1280 832c0 35 -29 64 -64 64c-354 0 -582 -148 -813 -403c-12 -13 -19 -27 -19 -45c0 -35 29 -64 64 -64c18 0 32 7 45 19c49 44 93 92 141 137c181 163 336 228 582 228c35 0 64 29 64 64zM1792 1030c0 -64 -7 -129 -20 -193c-64 -311 -264 -513 -542 -651
+c-135 -68 -286 -108 -438 -108c-96 0 -195 16 -286 47c-48 16 -144 79 -184 79c-50 0 -110 -204 -197 -204c-63 0 -82 31 -109 77c-9 17 -16 23 -16 44c0 104 198 185 198 243c0 9 -26 62 -30 82c-6 34 -9 69 -9 104c0 318 253 545 537 639c205 68 641 -11 780 121
+c55 51 82 98 166 98c113 0 150 -293 150 -378z" />
+ <glyph glyph-name="envelope-open-o" unicode="&#xf2b7;" horiz-adv-x="1792"
+d="M1474 623l39 -51c11 -14 8 -33 -5 -44c-100 -78 -330 -255 -340 -263c-71 -58 -167 -138 -271 -137h-2c-104 0 -200 79 -271 137c-11 9 -233 180 -331 256c-14 11 -17 30 -6 44l37 52c11 15 32 18 46 6c68 -53 164 -127 306 -236c50 -38 149 -131 219 -131h2
+c70 0 169 93 219 131c147 113 245 188 313 242c14 11 34 8 45 -6zM1664 -96v928c-100 93 -85 85 -548 443c-50 39 -149 133 -219 133h-2c-70 0 -169 -94 -219 -133c-463 -358 -448 -350 -548 -443v-928c0 -17 15 -32 32 -32h1472c17 0 32 15 32 32zM1792 832v-928
+c0 -88 -72 -160 -160 -160h-1472c-88 0 -160 72 -160 160v928c0 36 15 70 41 94c205 190 441 355 583 472c70 58 167 138 271 138h2c104 0 201 -80 271 -138c132 -109 383 -286 583 -472c26 -24 41 -58 41 -94z" />
+ <glyph glyph-name="exclamation-circle" unicode="&#xf06a;"
+d="M768 1408c424 0 768 -344 768 -768s-344 -768 -768 -768s-768 344 -768 768s344 768 768 768zM896 161v190c0 18 -14 33 -31 33h-192c-18 0 -33 -15 -33 -33v-190c0 -18 15 -33 33 -33h192c17 0 31 15 31 33zM894 505l18 621c0 7 -3 14 -10 18c-6 5 -15 8 -24 8h-220
+c-9 0 -18 -3 -24 -8c-7 -4 -10 -11 -10 -18l17 -621c0 -14 15 -25 34 -25h185c18 0 33 11 34 25z" />
+ <glyph glyph-name="comments" unicode="&#xf086;" horiz-adv-x="1792"
+d="M1408 768c0 -283 -315 -512 -704 -512c-61 0 -120 6 -176 16c-83 -59 -177 -102 -278 -128c-27 -7 -56 -12 -86 -16h-3c-15 0 -29 12 -32 29c-4 19 9 31 20 44c39 44 83 83 117 166c-162 94 -266 239 -266 401c0 283 315 512 704 512s704 -229 704 -512zM1792 512
+c0 -163 -104 -307 -266 -401c34 -83 78 -122 117 -166c11 -13 24 -25 20 -44c-4 -18 -19 -31 -35 -29c-30 4 -59 9 -86 16c-101 26 -195 69 -278 128c-56 -10 -115 -16 -176 -16c-181 0 -347 50 -472 132c29 -2 59 -4 88 -4c215 0 418 62 573 174c167 122 259 287 259 466
+c0 52 -8 103 -23 152c169 -93 279 -241 279 -408z" />
+ <glyph glyph-name="moon" unicode="&#xf328;" horiz-adv-x="1471"
+d="M1465 318c-125 -271 -399 -446 -697 -446c-423 0 -768 345 -768 768c0 415 325 752 739 767c28 1 51 -15 61 -39c11 -25 4 -54 -15 -72c-114 -104 -177 -246 -177 -400c0 -300 244 -544 544 -544c79 0 155 17 228 51c25 11 53 6 72 -13s24 -48 13 -72z" />
+ <glyph glyph-name="facebook-official" unicode="&#xf230;"
+d="M1451 1408c47 0 85 -38 85 -85v-1366c0 -47 -38 -85 -85 -85h-391v595h199l30 232h-229v148c0 67 18 112 115 112l122 1v207c-21 3 -94 9 -178 9c-177 0 -299 -108 -299 -306v-171h-200v-232h200v-595h-735c-47 0 -85 38 -85 85v1366c0 47 38 85 85 85h1366z" />
+ <glyph glyph-name="clock-o" unicode="&#xf017;"
+d="M896 992v-448c0 -18 -14 -32 -32 -32h-320c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h224v352c0 18 14 32 32 32h64c18 0 32 -14 32 -32zM1312 640c0 300 -244 544 -544 544s-544 -244 -544 -544s244 -544 544 -544s544 244 544 544zM1536 640
+c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="caret-square-o-left" unicode="&#xf191;"
+d="M1024 960v-640c0 -35 -29 -64 -64 -64c-13 0 -26 4 -37 12l-448 320c-17 12 -27 31 -27 52c0 20 10 40 27 52l448 320c11 8 24 12 37 12c35 0 64 -29 64 -64zM1280 160v960c0 17 -15 32 -32 32h-960c-17 0 -32 -15 -32 -32v-960c0 -17 15 -32 32 -32h960
+c17 0 32 15 32 32zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="hand-scissors-o" unicode="&#xf257;" horiz-adv-x="1792"
+d="M1073 -128h-177c-104 0 -183 45 -226 141c-15 32 -23 67 -23 102v5c-82 40 -135 124 -135 216c0 11 0 38 5 48h-261c-141 0 -256 115 -256 256s115 256 256 256h113l-44 17c-99 37 -165 133 -165 239c0 141 115 256 256 256c31 0 62 -6 91 -17l628 -239h401
+c141 0 256 -115 256 -256v-668c0 -118 -80 -220 -194 -248l-339 -85c-60 -15 -123 -23 -186 -23zM1024 583l-155 -71l-163 -74c-40 -18 -66 -58 -66 -102c0 -62 50 -112 112 -112c16 0 32 3 46 10l338 154c-65 14 -112 73 -112 140v55zM1344 272c0 62 -50 112 -112 112
+c-16 0 -32 -3 -46 -10l-290 -132c-60 -27 -121 -51 -121 -127c0 -66 46 -114 113 -114c12 0 28 4 38 9l352 160c40 18 66 58 66 102zM1112 1024l-650 248c-15 5 -30 8 -46 8c-70 0 -128 -57 -128 -128c0 -53 33 -101 82 -120l526 -200v-64h-640c-71 0 -128 -57 -128 -128
+s57 -128 128 -128h535l233 106v198c0 40 17 79 46 106l111 102h-69zM1073 0c52 0 105 6 155 19l339 85c57 14 97 65 97 124v668c0 71 -57 128 -128 128h-308l-136 -126c-23 -21 -36 -51 -36 -82v-296c0 -62 51 -108 112 -108c62 0 112 55 112 116v208h32v-208
+c0 -45 -22 -87 -57 -114c70 -11 121 -72 121 -142c0 -56 -33 -108 -84 -131l-310 -141h91z" />
+ <glyph glyph-name="tumblr-square" unicode="&#xf174;"
+d="M1136 75l-62 183c-24 -12 -69 -22 -103 -22c-102 -3 -123 71 -123 126v398h257v194h-256v326h-188c-3 0 -8 -3 -9 -10c-11 -99 -58 -275 -252 -345v-165h130v-418c0 -143 105 -347 384 -342c94 2 199 41 222 75zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960
+c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="rub" unicode="&#xf158;" horiz-adv-x="1280"
+d="M1043 971c0 134 -95 224 -236 224h-320v-448h320c141 0 236 90 236 224zM1280 971c0 -257 -186 -437 -453 -437h-340v-118h505c18 0 32 -14 32 -32v-128c0 -18 -14 -32 -32 -32h-505v-192c0 -18 -14 -32 -32 -32h-167c-18 0 -32 14 -32 32v192h-224c-18 0 -32 14 -32 32
+v128c0 18 14 32 32 32h224v118h-224c-18 0 -32 14 -32 32v149c0 18 14 32 32 32h224v629c0 18 14 32 32 32h539c267 0 453 -180 453 -437z" />
+ <glyph glyph-name="chevron-circle-up" unicode="&#xf139;"
+d="M1165 397l102 102c25 25 25 65 0 90l-454 454c-25 25 -65 25 -90 0l-454 -454c-25 -25 -25 -65 0 -90l102 -102c25 -25 65 -25 90 0l307 307l307 -307c25 -25 65 -25 90 0zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z
+" />
+ <glyph glyph-name="opencart" unicode="&#xf23d;" horiz-adv-x="2304"
+d="M1524 -25c0 -91 -73 -164 -164 -164s-165 73 -165 164s74 165 165 165s164 -74 164 -165zM775 -25c0 -91 -74 -164 -165 -164s-164 73 -164 164s73 165 164 165s165 -74 165 -165zM0 1469c295 -311 572 -357 1660 -357s610 -242 -62 -842c213 370 945 698 -255 680
+c-1151 -17 -1219 333 -1343 519z" />
+ <glyph glyph-name="artstation" unicode="&#xf2ed;" horiz-adv-x="1533"
+d="M601 1277v0h267c51 0 112 -37 136 -83l504 -878c16 -24 25 -53 25 -84c0 -35 -7 -53 -31 -94l-123 -213zM474 1058l348 -604h-695zM0 233v0h949l178 -309h-859c-53 0 -114 38 -138 85h-1z" />
+ <glyph glyph-name="thumbs-up" unicode="&#xf164;" horiz-adv-x="1600"
+d="M256 192c0 35 -29 64 -64 64c-36 0 -64 -29 -64 -64c0 -36 28 -64 64 -64c35 0 64 28 64 64zM416 704v-640c0 -35 -29 -64 -64 -64h-288c-35 0 -64 29 -64 64v640c0 35 29 64 64 64h288c35 0 64 -29 64 -64zM1600 704c0 -53 -21 -110 -55 -149c11 -32 15 -62 15 -76
+c2 -50 -13 -97 -43 -137c11 -37 11 -77 0 -117c-10 -37 -29 -70 -54 -94c6 -75 -11 -136 -49 -181c-43 -51 -109 -77 -197 -78h-129c-143 0 -278 47 -386 84c-63 22 -123 43 -158 44c-34 1 -64 29 -64 64v641c0 33 28 61 61 64c37 3 133 122 177 180c36 46 70 89 101 120
+c39 39 50 99 62 157c11 59 23 121 66 163c12 12 28 19 45 19c224 0 224 -179 224 -256c0 -82 -29 -140 -56 -192c-11 -22 -21 -32 -29 -64h277c104 0 192 -88 192 -192z" />
+ <glyph glyph-name="vimeo-square" unicode="&#xf194;"
+d="M1292 898c7 145 -47 218 -161 222c-154 5 -258 -82 -312 -261c28 12 55 19 82 19c56 0 81 -32 74 -96c-3 -38 -28 -94 -74 -167c-47 -74 -82 -110 -105 -110c-30 0 -56 56 -82 169c-8 34 -23 118 -45 255c-20 126 -73 185 -160 177c-36 -4 -92 -36 -164 -100
+c-54 -47 -107 -96 -162 -144l52 -67c50 34 79 52 87 52c38 0 74 -60 107 -179c30 -110 60 -219 90 -329c45 -119 99 -179 164 -179c104 0 232 98 383 294c146 188 222 336 226 444zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960
+c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="arrow-circle-right" unicode="&#xf0a9;"
+d="M1285 640c0 17 -6 33 -18 45l-91 91l-362 362c-12 12 -28 18 -45 18s-33 -6 -45 -18l-91 -91c-12 -12 -18 -28 -18 -45s6 -33 18 -45l189 -189h-502c-35 0 -64 -29 -64 -64v-128c0 -35 29 -64 64 -64h502l-189 -189c-12 -12 -19 -28 -19 -45s7 -33 19 -45l91 -91
+c12 -12 28 -18 45 -18s33 6 45 18l362 362l91 91c12 12 18 28 18 45zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="bolt" unicode="&#xf0e7;" horiz-adv-x="896"
+d="M885 970c11 -12 14 -29 7 -44l-540 -1157c-8 -15 -24 -25 -42 -25c-4 0 -9 1 -14 2c-22 7 -35 28 -30 49l197 808l-406 -101c-4 -1 -8 -1 -12 -1c-11 0 -23 4 -31 11c-12 10 -16 25 -13 39l201 825c5 19 23 32 44 32h328c25 0 45 -19 45 -42c0 -6 -2 -12 -5 -18
+l-171 -463l396 98c4 1 8 2 12 2c13 0 25 -6 34 -15z" />
+ <glyph glyph-name="thermometer-quarter" unicode="&#xf2ca;" horiz-adv-x="1024"
+d="M640 192c0 -106 -86 -192 -192 -192s-192 86 -192 192c0 80 50 153 128 181v139h128v-139c78 -28 128 -101 128 -181zM768 192c0 105 -50 197 -128 256v768c0 106 -86 192 -192 192s-192 -86 -192 -192v-768c-78 -59 -128 -151 -128 -256c0 -177 143 -320 320 -320
+s320 143 320 320zM896 192c0 -247 -201 -448 -448 -448s-448 201 -448 448c0 122 49 232 128 313v711c0 177 143 320 320 320s320 -143 320 -320v-711c79 -81 128 -191 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192v128h192z
+" />
+ <glyph glyph-name="hdd-o" unicode="&#xf0a0;"
+d="M1040 320c0 -44 -36 -80 -80 -80s-80 36 -80 80s36 80 80 80s80 -36 80 -80zM1296 320c0 -44 -36 -80 -80 -80s-80 36 -80 80s36 80 80 80s80 -36 80 -80zM1408 160v320c0 17 -15 32 -32 32h-1216c-17 0 -32 -15 -32 -32v-320c0 -17 15 -32 32 -32h1216c17 0 32 15 32 32
+zM178 640h1180l-157 482c-5 17 -24 30 -42 30h-782c-18 0 -37 -13 -42 -30zM1536 480v-320c0 -88 -72 -160 -160 -160h-1216c-88 0 -160 72 -160 160v320c0 27 8 50 16 75l197 606c23 70 90 119 164 119h782c74 0 141 -49 164 -119l197 -606c8 -25 16 -48 16 -75z" />
+ <glyph glyph-name="id-card-o" unicode="&#xf2c3;" horiz-adv-x="2048"
+d="M896 324c0 -73 -48 -132 -107 -132h-426c-59 0 -107 59 -107 132c0 132 32 284 164 284c40 -40 95 -64 156 -64s116 24 156 64c132 0 164 -152 164 -284zM768 768c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192zM1792 352v-64
+c0 -18 -14 -32 -32 -32h-704c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h704c18 0 32 -14 32 -32zM1408 608v-64c0 -18 -14 -32 -32 -32h-320c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h320c18 0 32 -14 32 -32zM1792 608v-64c0 -18 -14 -32 -32 -32h-192
+c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h192c18 0 32 -14 32 -32zM1792 864v-64c0 -18 -14 -32 -32 -32h-704c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h704c18 0 32 -14 32 -32zM1920 32v1120h-1792v-1120c0 -17 15 -32 32 -32h1728c17 0 32 15 32 32zM2048 1248v-1216
+c0 -88 -72 -160 -160 -160h-1728c-88 0 -160 72 -160 160v1216c0 88 72 160 160 160h1728c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="plug" unicode="&#xf1e6;" horiz-adv-x="1792"
+d="M1755 1083c49 -50 49 -131 0 -181l-401 -400l150 -150l-160 -160c-219 -219 -553 -250 -801 -86l-362 -362h-181v181l362 362c-164 248 -133 582 86 801l160 160l150 -150l400 401c50 49 131 49 181 0c50 -50 50 -132 0 -181l-400 -401l234 -234l401 400
+c50 50 131 50 181 0z" />
+ <glyph glyph-name="react" unicode="&#xf302;" horiz-adv-x="1755"
+d="M1434 910v0c187 -64 321 -165 321 -269c0 -109 -143 -215 -341 -280c-11 -3 -21 -7 -32 -10c3 -13 7 -33 10 -46c39 -197 10 -360 -83 -413c-89 -52 -235 -1 -382 125c-16 14 -31 28 -46 43c-12 -12 -24 -22 -36 -33c-152 -133 -307 -187 -400 -134
+c-90 52 -118 203 -82 393c4 21 9 40 14 61c-16 4 -32 10 -47 15c-190 65 -330 172 -330 279c0 104 131 205 314 268c20 7 42 14 64 20c-5 19 -9 38 -13 57c-38 193 -11 348 79 400c94 55 250 -3 406 -142c8 -7 21 -20 29 -27c14 13 28 27 43 40c149 130 296 184 386 132
+c94 -54 121 -219 79 -423c-3 -13 -6 -25 -9 -38c15 -5 41 -13 56 -18zM970 1201v0c-14 -12 -27 -23 -40 -36c53 -57 101 -118 146 -182c77 -7 155 -20 231 -37c3 11 5 23 7 35c36 177 15 311 -43 344c-54 31 -173 -13 -301 -124zM524 553c-22 -52 -41 -104 -56 -153
+c52 -11 106 -19 159 -25c-19 29 -37 59 -54 89c-17 29 -33 59 -49 89zM524 726c15 30 32 61 49 90s35 59 53 87c-55 -7 -108 -16 -157 -27c15 -48 33 -99 55 -150zM563 640v0c23 -47 48 -93 74 -139c22 -38 59 -98 84 -134c50 -3 103 -5 157 -5s107 2 158 6
+c29 44 57 87 83 133c22 38 55 101 74 140c-23 47 -49 94 -75 139c-22 37 -59 96 -83 132c-51 4 -104 6 -157 6s-107 -2 -158 -6c-29 -44 -57 -87 -83 -133s-51 -92 -74 -139zM1182 464c-17 -29 -34 -59 -53 -88c54 6 108 16 161 28c-17 52 -35 102 -57 152
+c-16 -31 -34 -62 -51 -92zM1232 726c21 49 39 98 55 149c-49 11 -102 21 -157 28c15 -24 38 -63 52 -87c17 -29 34 -60 50 -90zM878 1112v0c-34 -37 -68 -79 -102 -123c28 1 74 3 102 3s74 -2 102 -3c-32 43 -66 84 -102 123zM481 1322c-54 -31 -76 -156 -44 -322
+c4 -18 8 -36 12 -53c76 17 154 29 231 36c45 64 94 125 147 182c-9 8 -17 16 -26 24c-135 119 -262 167 -320 133zM397 419c24 75 52 149 85 221c-33 71 -61 144 -84 218c-20 -6 -40 -12 -60 -19c-156 -55 -264 -135 -264 -198c7 -41 29 -78 64 -102
+c60 -48 143 -84 216 -107c14 -5 29 -9 43 -13zM796 83c11 10 22 19 33 30c-53 58 -103 119 -148 183c-79 6 -156 18 -233 34c-5 -19 -8 -38 -12 -57c-31 -163 -9 -284 46 -316c39 -15 83 -13 121 5c71 28 136 69 193 121zM880 166c36 40 70 81 102 125
+c-34 -2 -69 -3 -104 -3c-34 0 -68 1 -101 2c34 -45 68 -86 103 -124zM1328 63c11 76 9 153 -8 227c-2 12 -6 31 -9 42c-64 -14 -169 -31 -234 -36c-44 -64 -93 -126 -145 -184c15 -14 30 -27 44 -39c125 -108 241 -149 296 -117c33 26 53 65 56 107zM1391 432
+c171 57 291 143 291 210c0 62 -112 144 -272 199c-16 5 -34 11 -52 16c-23 -74 -51 -146 -84 -216c34 -71 64 -143 88 -218c10 3 19 6 29 9zM878 797c87 0 157 -70 157 -157s-70 -157 -157 -157s-157 70 -157 157s70 157 157 157z" />
+ <glyph glyph-name="themeisle" unicode="&#xf2b2;" horiz-adv-x="1792"
+d="M852 1227c0 -36 -23 -76 -62 -76c-40 0 -62 40 -62 76c0 35 22 76 62 76c39 0 62 -41 62 -76zM688 -149v114c0 39 -31 73 -71 73s-70 -34 -70 -73v-114c0 -39 30 -74 70 -74s71 34 71 74zM860 -149v114c0 39 -30 73 -70 73s-71 -34 -71 -73v-114c0 -39 31 -74 71 -74
+s70 35 70 74zM1034 -149v114c0 39 -31 73 -71 73s-71 -34 -71 -73v-114c0 -39 31 -74 71 -74s71 34 71 74zM1208 -149v114c0 39 -31 73 -71 73s-71 -34 -71 -73v-114c0 -39 31 -74 71 -74s71 35 71 74zM1476 535c-108 -207 -316 -359 -555 -359c-338 0 -562 296 -562 618
+c0 59 7 117 21 174c-70 -118 -104 -254 -104 -390c0 -211 87 -426 250 -563c18 34 52 57 91 57c35 0 68 -20 86 -50c19 30 51 50 87 50c35 0 68 -20 86 -50c19 30 52 50 87 50s68 -20 87 -50c18 30 51 50 86 50c38 0 73 -23 90 -56c152 127 240 322 250 519zM1326 564
+c0 50 -22 75 -72 75c-16 0 -32 -3 -47 -6c-50 -10 -99 -19 -149 -19c-158 0 -226 92 -226 243c0 69 13 137 30 204c-53 -81 -83 -178 -83 -275c0 -189 120 -371 324 -371c75 0 149 27 210 70c7 26 13 52 13 79zM884 1223c0 63 -44 129 -113 129s-113 -66 -113 -129
+c0 -64 44 -130 113 -130s113 66 113 130zM1513 884c0 188 -121 370 -324 370c-106 0 -205 -53 -276 -129c-25 -83 -48 -180 -48 -268c0 -133 53 -210 193 -210c48 0 95 9 142 19c18 3 35 6 53 6c69 0 104 -40 104 -108c0 -15 -1 -31 -4 -46c101 91 160 230 160 366z
+M1792 667c0 -126 -40 -358 -127 -454c-80 -87 -306 -214 -423 -247l-4 -1v-114c0 -57 -44 -107 -102 -107c-35 0 -68 20 -86 50c-19 -30 -52 -50 -87 -50s-68 20 -87 50c-18 -30 -51 -50 -86 -50c-36 0 -68 20 -87 50c-18 -30 -51 -50 -86 -50c-66 0 -103 55 -103 115
+c-57 -43 -125 -68 -198 -68c-77 0 -152 29 -211 80c36 1 72 8 106 20c-73 20 -138 66 -182 127c23 -5 47 -7 71 -7c58 0 115 16 164 46c-77 77 -198 206 -240 306c-20 47 -24 110 -24 160c0 174 71 560 302 560c37 0 66 -17 81 -52c13 19 27 37 42 54c7 9 20 19 25 29
+c28 44 41 74 76 119c113 144 286 243 472 243c21 0 42 -1 62 -4c38 41 91 64 146 64c51 0 104 -21 140 -57c3 -3 5 -8 5 -12c0 -13 -36 -47 -45 -57c15 -5 55 -24 55 -42c0 -10 -10 -18 -16 -25c110 -97 173 -235 197 -378c15 18 36 30 60 30c37 0 73 -25 100 -49
+c73 -65 90 -186 90 -279z" />
+ <glyph glyph-name="braille" unicode="&#xf2a1;" horiz-adv-x="2176"
+d="M192 352c-88 0 -160 -72 -160 -160s72 -160 160 -160s160 72 160 160s-72 160 -160 160zM704 352c-88 0 -160 -72 -160 -160s72 -160 160 -160s160 72 160 160s-72 160 -160 160zM704 864c-88 0 -160 -72 -160 -160s72 -160 160 -160s160 72 160 160s-72 160 -160 160z
+M1472 352c-88 0 -160 -72 -160 -160s72 -160 160 -160s160 72 160 160s-72 160 -160 160zM1984 352c-88 0 -160 -72 -160 -160s72 -160 160 -160s160 72 160 160s-72 160 -160 160zM1472 864c-88 0 -160 -72 -160 -160s72 -160 160 -160s160 72 160 160s-72 160 -160 160z
+M1984 864c-88 0 -160 -72 -160 -160s72 -160 160 -160s160 72 160 160s-72 160 -160 160zM1984 1376c-88 0 -160 -72 -160 -160s72 -160 160 -160s160 72 160 160s-72 160 -160 160zM384 192c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192z
+M896 192c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192zM384 704c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192zM896 704c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192z
+M384 1216c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192zM1664 192c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192zM896 1216c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192
+zM2176 192c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192zM1664 704c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192zM2176 704c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192
+s192 -86 192 -192zM1664 1216c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192zM2176 1216c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192z" />
+ <glyph glyph-name="industry" unicode="&#xf275;" horiz-adv-x="1792"
+d="M448 1536c35 0 64 -29 64 -64v-891l536 429c11 9 26 14 40 14c35 0 64 -29 64 -64v-379l536 429c11 9 26 14 40 14c35 0 64 -29 64 -64v-1152c0 -35 -29 -64 -64 -64h-1664c-35 0 -64 29 -64 64v1664c0 35 29 64 64 64h384z" />
+ <glyph glyph-name="map-o" unicode="&#xf278;" horiz-adv-x="2048"
+d="M2020 1525c17 -12 28 -32 28 -53v-1408c0 -26 -16 -50 -40 -59l-640 -256c-16 -7 -32 -7 -48 0l-616 246l-616 -246c-8 -4 -16 -5 -24 -5c-13 0 -25 4 -36 11c-17 12 -28 32 -28 53v1408c0 26 16 50 40 59l640 256c16 7 32 7 48 0l616 -246l616 246c20 8 42 6 60 -6z
+M736 1390v-1270l576 -230v1270zM128 1173v-1270l544 217v1270zM1920 107v1270l-544 -217v-1270z" />
+ <glyph glyph-name="krw" unicode="&#xf159;" horiz-adv-x="1792"
+d="M514 341l81 299h-159l75 -300c1 -2 1 -4 2 -6c0 2 1 5 1 7zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299c1 -3 1 -5 2 -7c0 2 1 4 1 6zM1382 768l33 128h-297l34 -128h230zM1792 736v-64c0 -18 -14 -32 -32 -32h-213
+l-164 -616c-4 -14 -17 -24 -31 -24h-159c-14 0 -27 10 -31 24l-166 616h-209l-167 -616c-4 -14 -16 -24 -31 -24h-159c-14 0 -27 10 -30 24l-160 616h-208c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h175l-33 128h-142c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h109l-89 344
+c-3 10 -1 20 5 28c6 7 16 12 26 12h137c15 0 28 -10 31 -24l90 -360h359l97 360c4 14 17 24 31 24h126c15 0 27 -10 31 -24l98 -360h365l93 360c3 14 16 24 31 24h137c10 0 20 -5 26 -12c6 -8 8 -19 5 -28l-91 -344h111c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-145
+l-34 -128h179c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="joomla" unicode="&#xf1aa;"
+d="M1070 463l-160 -160l-151 -152l-30 -30c-88 -87 -211 -117 -323 -89c-21 -92 -103 -160 -201 -160c-113 0 -205 92 -205 206c0 97 67 179 158 200c-29 113 1 237 89 325l12 12l151 -152l-11 -11c-50 -49 -49 -129 0 -179c49 -49 129 -49 178 0l30 30l151 152l161 160z
+M729 1145l12 -12l-152 -152l-12 12c-49 49 -129 49 -178 0s-49 -130 0 -179l29 -29l152 -152l160 -160l-151 -152l-161 160l-151 152l-30 30c-92 91 -120 222 -85 339c-92 20 -160 102 -160 200c0 114 92 206 205 206c103 0 187 -75 203 -172c111 26 232 -5 319 -91z
+M1536 78c0 -114 -92 -206 -205 -206c-100 0 -183 71 -202 165c-116 -36 -249 -8 -341 84l-11 12l151 152l12 -12c49 -49 129 -49 178 0s49 129 0 178l-30 30l-152 152l-160 160l152 152l160 -160l152 -152l29 -30c87 -87 118 -210 90 -322c100 -14 177 -99 177 -203z
+M1534 1202c0 -104 -78 -190 -178 -204c33 -115 4 -244 -87 -335l-12 -12l-151 152l12 12c49 49 49 129 0 178s-129 49 -178 0l-30 -30l-152 -152l-160 -160l-152 152l161 160l152 152l29 30c91 91 221 120 337 86c14 100 100 177 204 177c113 0 205 -92 205 -206z" />
+ <glyph glyph-name="ethereum" unicode="&#xf2f3;" horiz-adv-x="1064"
+d="M1064 623l-532 -325l-532 325l532 913zM532 194l532 325l-532 -775l-532 775z" />
+ <glyph glyph-name="plus" unicode="&#xf067;" horiz-adv-x="1408"
+d="M1408 800v-192c0 -53 -43 -96 -96 -96h-416v-416c0 -53 -43 -96 -96 -96h-192c-53 0 -96 43 -96 96v416h-416c-53 0 -96 43 -96 96v192c0 53 43 96 96 96h416v416c0 53 43 96 96 96h192c53 0 96 -43 96 -96v-416h416c53 0 96 -43 96 -96z" />
+ <glyph glyph-name="list-ul" unicode="&#xf0ca;" horiz-adv-x="1792"
+d="M384 128c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192zM384 640c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192zM1792 224v-192c0 -17 -15 -32 -32 -32h-1216c-17 0 -32 15 -32 32v192c0 17 15 32 32 32
+h1216c17 0 32 -15 32 -32zM384 1152c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192s192 -86 192 -192zM1792 736v-192c0 -17 -15 -32 -32 -32h-1216c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h1216c17 0 32 -15 32 -32zM1792 1248v-192
+c0 -17 -15 -32 -32 -32h-1216c-17 0 -32 15 -32 32v192c0 17 15 32 32 32h1216c17 0 32 -15 32 -32z" />
+ <glyph glyph-name="play-circle-o" unicode="&#xf01d;"
+d="M1184 640c0 -23 -12 -44 -32 -55l-544 -320c-10 -6 -21 -9 -32 -9s-22 3 -32 8c-20 12 -32 33 -32 56v640c0 23 12 44 32 56c20 11 45 11 64 -1l544 -320c20 -11 32 -32 32 -55zM1312 640c0 300 -244 544 -544 544s-544 -244 -544 -544s244 -544 544 -544
+s544 244 544 544zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="joplin" unicode="&#xf310;"
+d="M288 1408h960c159 0 288 -129 288 -288v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288zM737 1171v-148l43 -1c59 -2 70 -6 81 -30c4 -10 5 -13 5 -296c0 -323 0 -323 -16 -362c-16 -38 -48 -69 -87 -83
+c-13 -5 -21 -5 -43 -6c-33 -1 -53 2 -80 15c-30 14 -50 37 -62 69c-9 24 -10 34 -12 88c-2 51 -1 56 -7 70c-9 23 -25 45 -40 56c-24 18 -49 24 -87 22c-40 -2 -68 -13 -95 -41c-23 -23 -35 -44 -44 -75c-4 -15 -5 -23 -5 -54c0 -38 1 -46 11 -79c26 -82 92 -156 178 -199
+c46 -23 85 -35 155 -44v0c20 -3 119 -3 142 0c87 10 150 32 208 71c73 49 127 125 142 199c8 40 9 47 10 343l1 291l6 13c6 15 15 24 29 28c5 2 28 3 52 4l43 1v74l-1 73l-263 1h-264z" />
+ <glyph glyph-name="mars-stroke" unicode="&#xf229;"
+d="M1472 1408c35 0 64 -29 64 -64v-416c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v262l-213 -214l140 -140c12 -13 12 -33 0 -45l-46 -46c-12 -12 -32 -12 -45 0l-140 141l-78 -79c79 -98 126 -223 126 -359c0 -318 -258 -576 -576 -576s-576 258 -576 576
+s258 576 576 576c136 0 261 -47 359 -126l78 78l-172 172c-12 13 -12 33 0 45l46 46c12 12 32 12 45 0l172 -172l213 213h-261c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h416zM576 0c247 0 448 201 448 448s-201 448 -448 448s-448 -201 -448 -448s201 -448 448 -448z" />
+ <glyph glyph-name="road" unicode="&#xf018;" horiz-adv-x="1820"
+d="M1061 540v4l-24 320c-1 18 -17 32 -34 32h-186c-17 0 -33 -14 -34 -32l-24 -320v-4c-1 -16 14 -28 29 -28h244c15 0 30 12 29 28zM1820 73c0 -29 -8 -73 -46 -73h-704c17 0 31 14 30 32l-20 256c-1 18 -17 32 -34 32h-272c-17 0 -33 -14 -34 -32l-20 -256
+c-1 -18 13 -32 30 -32h-704c-38 0 -46 44 -46 73c0 40 11 80 26 116l417 1044c10 25 37 47 64 47h339c-17 0 -33 -14 -34 -32l-15 -192c-1 -18 12 -32 30 -32h166c18 0 31 14 30 32l-15 192c-1 18 -17 32 -34 32h339c27 0 54 -22 64 -47l417 -1044c15 -36 26 -76 26 -116z
+" />
+ <glyph glyph-name="volume-down" unicode="&#xf027;" horiz-adv-x="1152"
+d="M768 1184v-1088c0 -35 -29 -64 -64 -64c-17 0 -33 7 -45 19l-333 333h-262c-35 0 -64 29 -64 64v384c0 35 29 64 64 64h262l333 333c12 12 28 19 45 19c35 0 64 -29 64 -64zM1152 640c0 -100 -61 -197 -155 -235c-8 -4 -17 -5 -25 -5c-35 0 -64 28 -64 64
+c0 76 116 55 116 176s-116 100 -116 176c0 36 29 64 64 64c8 0 17 -1 25 -5c94 -37 155 -135 155 -235z" />
+ <glyph glyph-name="question-circle" unicode="&#xf059;"
+d="M896 160v192c0 18 -14 32 -32 32h-192c-18 0 -32 -14 -32 -32v-192c0 -18 14 -32 32 -32h192c18 0 32 14 32 32zM1152 832c0 183 -192 320 -364 320c-163 0 -285 -70 -371 -213c-9 -14 -5 -32 8 -42l132 -100c5 -4 12 -6 19 -6c9 0 19 4 25 12c47 60 67 78 86 92
+c17 12 50 24 86 24c64 0 123 -41 123 -85c0 -52 -27 -78 -88 -106c-71 -32 -168 -115 -168 -212v-36c0 -18 14 -32 32 -32h192c18 0 32 14 32 32c0 23 29 72 76 99c76 43 180 101 180 253zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768
+s768 -344 768 -768z" />
+ <glyph glyph-name="paypal" unicode="&#xf1ed;" horiz-adv-x="1519"
+d="M1510 890c13 -60 10 -129 -4 -204c-65 -330 -284 -444 -565 -444h-44c-34 0 -62 -25 -68 -59l-4 -19l-55 -346l-2 -15c-7 -34 -35 -59 -69 -59h-251c-28 0 -46 23 -42 51c18 112 35 224 53 336s36 223 54 335c3 24 19 37 43 37c40 0 80 1 131 0c72 -1 155 3 236 21
+c108 24 206 68 287 144c73 68 122 152 155 246c15 44 27 88 35 133c2 12 5 10 12 5c55 -41 86 -96 98 -162zM1338 1172c0 -82 -19 -160 -46 -236c-52 -151 -150 -259 -302 -315c-81 -29 -166 -41 -252 -42c-60 -1 -120 0 -180 0c-65 0 -106 -32 -118 -96
+c-14 -76 -69 -430 -85 -530c-1 -7 -4 -10 -12 -10h-295c-30 0 -52 26 -48 55l232 1471c6 38 40 67 79 67h598c43 0 142 -19 209 -45c142 -55 220 -167 220 -319z" />
+ <glyph glyph-name="child" unicode="&#xf1ae;" horiz-adv-x="1152"
+d="M1124 988l-292 -292v-824c0 -62 -50 -112 -112 -112s-112 50 -112 112v384h-64v-384c0 -62 -50 -112 -112 -112s-112 50 -112 112v824l-292 292c-37 38 -37 98 0 136c38 37 98 37 136 0l228 -228h368l228 228c38 37 98 37 136 0c37 -38 37 -98 0 -136zM800 1152
+c0 -124 -100 -224 -224 -224s-224 100 -224 224s100 224 224 224s224 -100 224 -224z" />
+ <glyph glyph-name="fork-awesome" unicode="&#xf2e3;" horiz-adv-x="1533"
+d="M766 1404v0c423 0 767 -343 767 -766v-1v-2c0 -8 -1 -17 -1 -25v-2c-14 -388 -318 -703 -701 -735v1c-18 -2 -47 -2 -65 -2s-47 1 -65 3v-2c-383 32 -685 347 -700 735v2c0 8 -1 17 -1 25v2v1c0 423 343 766 766 766zM594 1085h-66c-35 -251 -54 -525 -29 -712
+s145 -157 181 -351c5 -29 10 -59 14 -89c20 -2 52 -4 72 -4s52 2 72 4c4 30 9 60 14 89c36 194 156 164 181 351s6 456 -28 712h-65c3 -190 12 -430 -8 -640c-8 -89 -103 -87 -108 0c-13 208 -15 428 -26 639h-64c-11 -211 -18 -431 -26 -643c-3 -82 -100 -81 -108 0
+c-19 208 -10 453 -6 644z" />
+ <glyph glyph-name="angle-double-up" unicode="&#xf102;" horiz-adv-x="998"
+d="M998 224c0 -8 -4 -17 -10 -23l-50 -50c-6 -6 -14 -10 -23 -10c-8 0 -17 4 -23 10l-393 393l-393 -393c-6 -6 -15 -10 -23 -10s-17 4 -23 10l-50 50c-6 6 -10 15 -10 23s4 17 10 23l466 466c6 6 15 10 23 10s17 -4 23 -10l466 -466c6 -6 10 -15 10 -23zM998 608
+c0 -8 -4 -17 -10 -23l-50 -50c-6 -6 -14 -10 -23 -10c-8 0 -17 4 -23 10l-393 393l-393 -393c-6 -6 -15 -10 -23 -10s-17 4 -23 10l-50 50c-6 6 -10 15 -10 23s4 17 10 23l466 466c6 6 15 10 23 10s17 -4 23 -10l466 -466c6 -6 10 -15 10 -23z" />
+ <glyph glyph-name="bath" unicode="&#xf2cd;" horiz-adv-x="1792"
+d="M1664 448v-192c0 -114 -50 -215 -128 -286v-194c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v118c-40 -14 -83 -22 -128 -22h-768c-45 0 -88 8 -128 22v-110c0 -22 -14 -40 -32 -40h-64c-18 0 -32 18 -32 40v186c-78 71 -128 172 -128 286v192h1536zM704 864
+c0 -18 -14 -32 -32 -32s-32 14 -32 32s14 32 32 32s32 -14 32 -32zM768 928c0 -18 -14 -32 -32 -32s-32 14 -32 32s14 32 32 32s32 -14 32 -32zM704 992c0 -18 -14 -32 -32 -32s-32 14 -32 32s14 32 32 32s32 -14 32 -32zM832 992c0 -18 -14 -32 -32 -32s-32 14 -32 32
+s14 32 32 32s32 -14 32 -32zM768 1056c0 -18 -14 -32 -32 -32s-32 14 -32 32s14 32 32 32s32 -14 32 -32zM704 1120c0 -18 -14 -32 -32 -32s-32 14 -32 32s14 32 32 32s32 -14 32 -32zM1792 608v-64c0 -18 -14 -32 -32 -32h-1728c-18 0 -32 14 -32 32v64c0 18 14 32 32 32
+h96v640c0 141 115 256 256 256c72 0 137 -30 184 -78c62 25 136 16 191 -27l22 22c6 6 16 6 22 0l42 -42c6 -6 6 -16 0 -22l-314 -314c-6 -6 -16 -6 -22 0l-42 42c-6 6 -6 16 0 22l22 22c-48 61 -54 145 -17 212c-23 22 -54 35 -88 35c-71 0 -128 -57 -128 -128v-640h1504
+c18 0 32 -14 32 -32zM896 1056c0 -18 -14 -32 -32 -32s-32 14 -32 32s14 32 32 32s32 -14 32 -32zM832 1120c0 -18 -14 -32 -32 -32s-32 14 -32 32s14 32 32 32s32 -14 32 -32zM768 1184c0 -18 -14 -32 -32 -32s-32 14 -32 32s14 32 32 32s32 -14 32 -32zM960 1120
+c0 -18 -14 -32 -32 -32s-32 14 -32 32s14 32 32 32s32 -14 32 -32zM896 1184c0 -18 -14 -32 -32 -32s-32 14 -32 32s14 32 32 32s32 -14 32 -32zM832 1248c0 -18 -14 -32 -32 -32s-32 14 -32 32s14 32 32 32s32 -14 32 -32zM1024 1184c0 -18 -14 -32 -32 -32s-32 14 -32 32
+s14 32 32 32s32 -14 32 -32zM960 1248c0 -18 -14 -32 -32 -32s-32 14 -32 32s14 32 32 32s32 -14 32 -32zM1088 1248c0 -18 -14 -32 -32 -32s-32 14 -32 32s14 32 32 32s32 -14 32 -32z" />
+ <glyph glyph-name="reply-all" unicode="&#xf122;" horiz-adv-x="1792"
+d="M640 454v-70c0 -26 -16 -49 -39 -59c-8 -3 -17 -5 -25 -5c-17 0 -33 6 -45 19l-512 512c-25 25 -25 65 0 90l512 512c18 19 46 24 70 14c23 -10 39 -33 39 -59v-69l-397 -398c-25 -25 -25 -65 0 -90zM1792 416c0 -208 -157 -514 -164 -527c-5 -11 -16 -17 -28 -17
+c-3 0 -6 0 -9 1c-15 5 -24 19 -23 34c29 273 -5 453 -106 565c-85 95 -223 146 -438 163v-251c0 -26 -16 -49 -39 -59c-8 -3 -17 -5 -25 -5c-17 0 -33 6 -45 19l-512 512c-25 25 -25 65 0 90l512 512c18 19 46 24 70 14c23 -10 39 -33 39 -59v-262c276 -19 473 -92 599 -221
+c151 -155 169 -365 169 -509z" />
+ <glyph glyph-name="patreon" unicode="&#xf2f0;"
+d="M985 1341c-305 0 -553 -248 -553 -553c0 -304 248 -551 553 -551c304 0 551 247 551 551c0 305 -247 553 -551 553zM270 -132h-270v1473h270v-1473z" />
+ <glyph glyph-name="inbox" unicode="&#xf01c;"
+d="M1023 576h316c-2 5 -3 11 -5 16l-212 496h-708l-212 -496c-2 -5 -3 -11 -5 -16h316l95 -192h320zM1536 546v-482c0 -35 -29 -64 -64 -64h-1408c-35 0 -64 29 -64 64v482c0 36 11 89 25 123l238 552c14 33 54 59 89 59h832c35 0 75 -26 89 -59l238 -552
+c14 -34 25 -87 25 -123z" />
+ <glyph glyph-name="female" unicode="&#xf182;" horiz-adv-x="1280"
+d="M1280 480c0 -53 -43 -96 -96 -96c-32 0 -62 16 -80 43l-227 341h-45v-132l247 -411c6 -10 9 -21 9 -33c0 -35 -29 -64 -64 -64h-192v-272c0 -62 -50 -112 -112 -112h-160c-61 0 -112 50 -112 112v272h-192c-35 0 -64 29 -64 64c0 12 3 23 9 33l247 411v132h-45l-227 -341
+c-18 -27 -48 -43 -80 -43c-53 0 -96 43 -96 96c0 19 6 38 16 53l256 384c40 59 102 107 176 107h384c74 0 136 -48 176 -107l256 -384c10 -15 16 -34 16 -53zM864 1280c0 -124 -100 -224 -224 -224s-224 100 -224 224s100 224 224 224s224 -100 224 -224z" />
+ <glyph glyph-name="gavel" unicode="&#xf0e3;" horiz-adv-x="1731"
+d="M1731 0c0 -34 -14 -67 -37 -90l-107 -108c-24 -23 -57 -37 -91 -37s-67 14 -90 37l-363 364c-24 23 -38 56 -38 90c0 38 16 69 43 96l-256 256l-126 -126c-9 -9 -21 -14 -34 -14s-25 5 -34 14c30 -30 58 -52 58 -98c0 -26 -10 -49 -28 -68c-34 -36 -70 -84 -124 -84
+c-25 0 -50 10 -68 28l-408 408c-18 18 -28 43 -28 68c0 54 48 90 84 124c19 18 42 28 68 28c46 0 68 -28 98 -58c-9 9 -14 21 -14 34s5 25 14 34l348 348c9 9 21 14 34 14s25 -5 34 -14c-30 30 -58 52 -58 98c0 26 10 49 28 68c34 36 70 84 124 84c25 0 50 -10 68 -28
+l408 -408c18 -18 28 -43 28 -68c0 -54 -48 -90 -84 -124c-19 -18 -42 -28 -68 -28c-46 0 -68 28 -98 58c9 -9 14 -21 14 -34s-5 -25 -14 -34l-126 -126l256 -256c27 27 58 43 96 43c34 0 67 -14 91 -37l363 -363c23 -24 37 -57 37 -91z" />
+ <glyph glyph-name="jsfiddle" unicode="&#xf1cc;" horiz-adv-x="2048"
+d="M1800 764c145 -60 248 -202 248 -367c0 -219 -181 -397 -403 -397c-8 0 -15 1 -22 1h-1217c-224 13 -406 184 -406 406c0 149 81 279 202 350c-8 26 -12 53 -12 82c0 153 125 277 281 277c64 0 124 -22 172 -58c98 202 306 342 549 342c337 0 609 -269 609 -600
+c0 -12 -1 -24 -1 -36zM468 498c0 -169 133 -264 292 -264c98 0 169 31 240 99c-29 36 -61 71 -91 107c-41 -40 -86 -65 -144 -65c-71 0 -132 47 -132 121c0 73 61 121 130 121c220 0 267 -384 587 -384c156 0 288 98 288 262c0 166 -133 263 -291 263
+c-98 0 -171 -28 -241 -97c32 -35 62 -72 93 -108c40 39 85 64 142 64c66 0 132 -47 132 -117c0 -77 -56 -126 -131 -126c-213 0 -270 384 -582 384c-155 0 -292 -95 -292 -260z" />
+ <glyph glyph-name="git" unicode="&#xf1d3;" horiz-adv-x="1656"
+d="M527 22c0 88 -97 100 -165 100c-71 0 -158 -15 -158 -104c0 -90 103 -101 172 -101c73 0 151 18 151 105zM468 777c0 75 -36 143 -119 143c-92 0 -124 -61 -124 -145c0 -83 36 -135 124 -135c87 0 119 56 119 137zM737 1101v-202c-26 -9 -52 -16 -79 -22
+c10 -27 16 -55 16 -84c0 -169 -104 -298 -270 -329c-50 -10 -79 -31 -79 -85c0 -153 404 -49 404 -331c0 -229 -155 -304 -363 -304c-171 0 -366 57 -366 263c0 120 73 189 182 225v4c-46 28 -67 72 -67 126c0 51 11 114 63 137v4c-101 34 -167 173 -167 274
+c0 187 145 324 330 324c62 0 124 -16 178 -47c75 0 149 20 218 47zM1055 220h-222c4 45 4 89 4 134v609c0 43 1 86 -4 128h222c-5 -41 -4 -83 -4 -124v-613c0 -45 0 -89 4 -134zM1656 442v-196c-53 -29 -114 -39 -174 -39c-214 0 -239 169 -239 343v351h2v4
+c-13 0 -25 2 -37 2c-20 0 -40 -3 -59 -6v190h96v76c0 30 -1 60 -6 89h227c-8 -55 -6 -110 -6 -165h171v-190c-29 0 -58 4 -86 4h-85v-365c0 -59 13 -131 87 -131c39 0 77 11 109 33zM1080 1389c0 -75 -58 -145 -135 -145c-79 0 -138 69 -138 145c0 77 58 147 138 147
+c79 0 135 -72 135 -147z" />
+ <glyph glyph-name="signalapp" unicode="&#xf30c;" horiz-adv-x="1652"
+d="M710 1400c32 4 84 8 116 8v0c27 0 53 -2 80 -4l-3 -42c-21 2 -56 3 -77 3c-31 0 -81 -3 -111 -7zM977 1351l8 43c54 -10 138 -36 188 -58l-17 -39c-48 21 -128 45 -179 54zM446 1321c49 24 133 54 186 66l10 -42c-51 -11 -130 -39 -177 -62zM1223 1264l21 37
+c48 -27 120 -78 160 -115l-29 -32c-38 35 -106 85 -152 110zM222 1161c39 39 108 93 155 122l22 -36c-44 -27 -110 -79 -147 -116l-30 30v0zM1427 1101l32 28c37 -41 87 -114 112 -163l-38 -20c-24 46 -71 116 -106 155v0zM65 934c23 50 69 125 104 168l33 -27
+c-33 -40 -77 -112 -98 -159zM1564 878l39 15c20 -52 41 -138 46 -193l-43 -4c-5 52 -23 133 -42 182zM0 664c3 55 19 143 36 196l41 -14c-16 -49 -32 -132 -34 -184zM1582 436c14 50 26 133 27 185h43c-1 -55 -14 -144 -29 -197zM-0 585l43 2c2 -70 10 -131 23 -187l-42 -11
+c-14 59 -22 123 -24 196zM1464 203c32 41 73 114 93 162l40 -16c-21 -51 -66 -128 -99 -172zM47 313l40 15c22 -60 52 -113 92 -160l-33 -28c-43 51 -75 108 -99 173v0zM1273 26c44 28 107 82 143 120l31 -29c-37 -40 -105 -97 -151 -127zM202 82l28 32
+c12 -11 34 -28 47 -38c4 -3 6 -7 7 -11l40 -125l-41 -13l-37 118c-13 10 -32 26 -44 37v0zM1033 -80c50 13 129 44 175 68l20 -39c-48 -25 -131 -56 -184 -70zM644 -86c2 1 7 2 9 2s3 -1 5 -1c17 -5 31 -8 42 -11l-9 -42c-10 2 -27 7 -37 10l-128 -57l-18 40l136 59v0z
+M826 -106c45 0 90 4 134 11l7 -42c-39 -6 -102 -12 -141 -12c-22 0 -40 0 -55 1l2 43c15 -1 31 -1 53 -1v0zM357 -256v0v0c-9 0 -17 7 -20 15l-30 93l41 13l23 -70l67 29l17 -39l-89 -39c-2 -1 -7 -2 -9 -2zM442 -65c-11 0 -21 8 -22 19l-16 213c-70 53 -124 122 -161 204
+c-37 81 -56 171 -56 268c0 332 292 602 651 602s651 -270 651 -602s-292 -602 -651 -602c-60 0 -119 8 -176 23l-209 -123c-3 -2 -7 -2 -11 -2v0z" />
+ <glyph glyph-name="share-square" unicode="&#xf14d;"
+d="M1005 435l352 352c25 25 25 65 0 90l-352 352c-18 19 -46 24 -69 14c-24 -10 -40 -33 -40 -59v-160c-574 0 -640 -329 -640 -576c0 -201 161 -396 167 -404c7 -8 16 -12 25 -12c4 0 9 1 13 3c13 5 21 19 19 33c-30 241 -11 391 62 473c61 69 167 99 354 99v-160
+c0 -26 16 -49 40 -59c7 -3 16 -5 24 -5c17 0 33 7 45 19zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960c159 0 288 -129 288 -288z" />
+ <glyph glyph-name="thermometer-half" unicode="&#xf2c9;" horiz-adv-x="1024"
+d="M640 192c0 -106 -86 -192 -192 -192s-192 86 -192 192c0 80 50 153 128 181v395h128v-395c78 -28 128 -101 128 -181zM768 192c0 105 -50 197 -128 256v768c0 106 -86 192 -192 192s-192 -86 -192 -192v-768c-78 -59 -128 -151 -128 -256c0 -177 143 -320 320 -320
+s320 143 320 320zM896 192c0 -247 -201 -448 -448 -448s-448 201 -448 448c0 122 49 232 128 313v711c0 177 143 320 320 320s320 -143 320 -320v-711c79 -81 128 -191 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192v128h192z
+" />
+ <glyph glyph-name="question" unicode="&#xf128;" horiz-adv-x="924"
+d="M608 280v-240c0 -22 -18 -40 -40 -40h-240c-22 0 -40 18 -40 40v240c0 22 18 40 40 40h240c22 0 40 -18 40 -40zM924 880c0 -190 -129 -263 -224 -316c-59 -34 -96 -103 -96 -132c0 -22 -17 -48 -40 -48h-240c-22 0 -36 34 -36 56v45c0 121 120 225 208 265
+c77 35 109 68 109 132c0 56 -73 106 -154 106c-45 0 -86 -14 -108 -29c-24 -17 -48 -41 -107 -115c-8 -10 -20 -16 -31 -16c-9 0 -17 3 -25 8l-164 125c-17 13 -21 35 -10 53c108 179 260 266 464 266c214 0 454 -171 454 -400z" />
+ <glyph glyph-name="low-vision" unicode="&#xf2a8;" horiz-adv-x="1792"
+d="M335 180c-2 0 -4 1 -6 2c-117 78 -234 206 -308 325c-14 20 -21 44 -21 69c0 52 36 94 65 133c116 158 271 288 452 365c-15 27 -110 193 -110 211c0 12 7 23 17 29c20 11 110 64 128 64c11 0 22 -6 28 -16l124 -229c63 13 128 19 192 19c362 0 684 -205 876 -507
+c13 -20 20 -44 20 -69s-7 -49 -20 -69c-119 -187 -293 -342 -497 -429c15 -27 110 -193 110 -211c0 -12 -6 -23 -17 -29c-20 -11 -110 -64 -127 -64c-12 0 -23 6 -29 16l-124 229l-64 119l-444 820l7 7c-34 -14 -67 -29 -99 -47c12 -23 489 -899 489 -906c0 -5 -4 -8 -9 -9
+c-22 -5 -50 -3 -72 -3c-11 0 -56 -2 -60 7l-456 841c-29 -21 -56 -44 -82 -68c22 -39 404 -742 404 -748c0 -8 -5 -10 -11 -10c-17 0 -150 41 -155 50l-106 197l-224 413c-28 -34 -54 -69 -78 -106c13 -19 30 -39 41 -59c14 -26 176 -321 176 -327c0 -5 -5 -10 -10 -10z
+M1165 282l49 -91c187 76 341 216 450 385c-111 171 -269 313 -459 389c89 -85 139 -202 139 -325c0 -141 -66 -274 -179 -358zM848 896c0 -26 22 -48 48 -48c55 0 108 -22 147 -61s61 -92 61 -147c0 -26 22 -48 48 -48s48 22 48 48c0 168 -136 304 -304 304
+c-26 0 -48 -22 -48 -48zM1214 961l-9 4l7 -7z" />
+ <glyph glyph-name="camera" unicode="&#xf030;" horiz-adv-x="1920"
+d="M960 864c159 0 288 -129 288 -288s-129 -288 -288 -288s-288 129 -288 288s129 288 288 288zM1664 1280c141 0 256 -115 256 -256v-896c0 -141 -115 -256 -256 -256h-1408c-141 0 -256 115 -256 256v896c0 141 115 256 256 256h224l51 136c25 66 103 120 173 120h512
+c70 0 148 -54 173 -120l51 -136h224zM960 128c247 0 448 201 448 448s-201 448 -448 448s-448 -201 -448 -448s201 -448 448 -448z" />
+ <glyph glyph-name="wordpress" unicode="&#xf19a;" horiz-adv-x="1792"
+d="M127 640c0 111 24 217 67 313l367 -1005c-257 125 -434 388 -434 692zM1415 679c0 -66 -27 -142 -59 -249l-76 -256l-278 826s46 3 88 8c41 5 36 66 -5 63c-125 -9 -205 -10 -205 -10s-75 1 -202 10c-42 3 -47 -60 -5 -63c39 -4 80 -8 80 -8l120 -328l-168 -504l-280 832
+s46 3 88 8c41 5 36 66 -5 63c-124 -9 -205 -10 -205 -10c-14 0 -31 1 -49 1c137 209 373 347 642 347c200 0 382 -77 519 -202h-10c-75 0 -129 -65 -129 -136c0 -63 37 -116 76 -180c30 -51 63 -117 63 -212zM909 573l237 -647c1 -4 3 -8 5 -11c-80 -28 -165 -44 -255 -44
+c-75 0 -148 11 -217 32zM1570 1009c60 -110 95 -235 95 -369c0 -284 -154 -531 -383 -664l235 678c39 112 59 198 59 276c0 28 -2 54 -6 79zM896 1536c494 0 896 -402 896 -896s-402 -896 -896 -896s-896 402 -896 896s402 896 896 896zM896 -215c471 0 855 384 855 855
+s-384 855 -855 855s-855 -384 -855 -855s384 -855 855 -855z" />
+ <glyph glyph-name="italic" unicode="&#xf033;" horiz-adv-x="1024"
+d="M0 -126l17 85c64 20 133 28 193 59c23 29 34 66 41 101c13 68 231 1049 228 1129v25c-55 30 -122 22 -182 32l19 103c129 -6 260 -16 390 -16c106 0 212 10 318 16c-4 -30 -11 -60 -19 -89c-69 -24 -142 -35 -210 -62c-22 -54 -27 -113 -37 -170
+c-48 -259 -112 -518 -165 -775c-10 -48 -59 -247 -55 -289l1 -18c61 -14 123 -21 185 -31c-2 -33 -8 -66 -16 -99c-22 0 -43 -3 -65 -3c-57 0 -116 19 -173 20c-69 1 -138 2 -206 2c-89 0 -176 -15 -264 -20z" />
+ <glyph glyph-name="forward" unicode="&#xf04e;" horiz-adv-x="1542"
+d="M45 -115c-25 -25 -45 -16 -45 19v1472c0 35 20 44 45 19l710 -710c6 -6 10 -12 13 -19v710c0 35 20 44 45 19l710 -710c25 -25 25 -65 0 -90l-710 -710c-25 -25 -45 -16 -45 19v710c-3 -7 -7 -13 -13 -19z" />
+ <glyph glyph-name="steam-square" unicode="&#xf1b7;"
+d="M1242 889c0 106 -87 193 -194 193c-106 0 -193 -87 -193 -193c0 -107 87 -193 193 -193c107 0 194 86 194 193zM632 301c0 -110 -88 -198 -198 -198c-76 0 -142 43 -175 106c33 -13 65 -26 98 -40c80 -32 172 7 205 88c32 80 -7 172 -88 204l-82 33c13 3 28 5 42 5
+c110 0 198 -88 198 -198zM1536 1120v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v153l172 -69c26 -121 134 -212 262 -212c140 0 255 107 268 243l345 252c200 0 361 162 361 360c0 200 -161 361 -361 361c-197 0 -358 -160 -360 -357l-225 -322
+c-9 1 -18 1 -28 1c-50 0 -97 -13 -137 -37l-297 119v468c0 159 129 288 288 288h960c159 0 288 -129 288 -288zM1289 887c0 -133 -108 -241 -242 -241c-133 0 -241 108 -241 241c0 134 108 242 241 242c134 0 242 -108 242 -242z" />
+ <glyph glyph-name="medium-square" unicode="&#xf2f8;"
+d="M0 1404h1536v-1536h-1536v1536zM257 1057v-17l97 -116c7 -7 13 -20 13 -30v-4v-456v-9c0 -12 -6 -28 -14 -36l-109 -132v-17h308v17l-109 132c-9 9 -15 26 -15 38v7v395l270 -589h31l232 589v-469c0 -13 0 -16 -8 -24l-84 -80v-18h405v18l-80 79c-5 4 -10 12 -10 19
+c0 1 1 3 1 4v580c0 1 -1 3 -1 4c0 7 5 15 10 19l82 79v17h-285l-203 -507l-232 507h-299z" />
+ <glyph glyph-name="sort-numeric-desc" unicode="&#xf163;" horiz-adv-x="1454"
+d="M1314 1247c0 82 -67 169 -147 169c-70 0 -114 -57 -114 -131c0 -72 46 -133 141 -133c65 0 120 39 120 95zM704 96c0 -9 -4 -17 -10 -24l-319 -319c-7 -6 -15 -9 -23 -9s-16 3 -23 9l-320 320c-9 10 -12 23 -7 35s17 20 30 20h192v1376c0 18 14 32 32 32h192
+c18 0 32 -14 32 -32v-1376h192c18 0 32 -14 32 -32zM1424 -142v-114h-469v114h167v432c0 13 1 26 1 36v16h-2l-7 -12c-5 -8 -13 -18 -26 -31l-62 -58l-82 86l192 185h123v-654h165zM1454 1189c0 -202 -110 -421 -348 -421c-45 0 -82 7 -108 16c-16 5 -30 10 -42 15l39 113
+c9 -4 20 -8 31 -11c20 -7 46 -13 75 -13c120 0 182 100 201 204h-2c-28 -30 -87 -51 -146 -51c-145 0 -240 114 -240 244c0 138 106 251 253 251c159 0 287 -130 287 -347z" />
+ <glyph glyph-name="video-camera" unicode="&#xf03d;" horiz-adv-x="1792"
+d="M1792 1184v-1088c0 -26 -16 -49 -39 -59c-8 -3 -17 -5 -25 -5c-17 0 -33 6 -45 19l-403 403v-166c0 -159 -129 -288 -288 -288h-704c-159 0 -288 129 -288 288v704c0 159 129 288 288 288h704c159 0 288 -129 288 -288v-165l403 402c12 13 28 19 45 19c8 0 17 -2 25 -5
+c23 -10 39 -33 39 -59z" />
+ <glyph glyph-name="thumbs-down" unicode="&#xf165;" horiz-adv-x="1600"
+d="M256 960c0 36 -29 64 -64 64c-36 0 -64 -28 -64 -64c0 -35 28 -64 64 -64c35 0 64 29 64 64zM416 448c0 -35 -29 -64 -64 -64h-288c-35 0 -64 29 -64 64v640c0 35 29 64 64 64h288c35 0 64 -29 64 -64v-640zM1545 597c34 -38 55 -96 55 -149c-1 -104 -88 -192 -192 -192
+h-277c8 -32 18 -42 29 -64c26 -52 56 -110 56 -192c0 -77 0 -256 -224 -256c-17 0 -33 7 -45 19c-43 42 -55 104 -66 163c-12 58 -23 118 -62 157c-31 31 -65 74 -101 120c-44 58 -140 177 -177 180c-33 3 -61 31 -61 64v641c0 35 30 63 64 64c35 1 95 22 158 44
+c108 37 243 84 386 84h129c88 -1 154 -27 197 -78c38 -45 55 -106 49 -181c25 -24 44 -57 54 -94c11 -40 11 -80 0 -117c30 -40 45 -87 43 -137c0 -14 -4 -44 -15 -76z" />
+ <glyph glyph-name="medium" unicode="&#xf23a;"
+d="M182 999v6c0 15 -8 34 -19 44l-144 173v26h446l344 -755l302 755h425v-26l-123 -117c-8 -6 -14 -19 -14 -29c0 -2 1 -4 1 -6v-864c0 -2 -1 -4 -1 -6c0 -10 6 -23 14 -29l120 -117v-26h-602v26l124 120c12 12 12 16 12 35v698l-345 -876h-47l-401 876v-587
+c0 -3 -1 -8 -1 -11c0 -18 10 -44 23 -57l162 -195v-26h-458v26l161 195c12 13 22 38 22 55c0 4 0 9 -1 13v679z" />
+ <glyph glyph-name="chevron-right" unicode="&#xf054;" horiz-adv-x="1036"
+d="M1017 659l-742 -742c-25 -25 -65 -25 -90 0l-166 166c-25 25 -25 65 0 90l531 531l-531 531c-25 25 -25 65 0 90l166 166c25 25 65 25 90 0l742 -742c25 -25 25 -65 0 -90z" />
+ <glyph glyph-name="bus" unicode="&#xf207;"
+d="M384 320c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM1408 320c0 71 -57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128s128 57 128 128zM1362 716l-72 384c-6 30 -32 52 -63 52h-918c-31 0 -57 -22 -63 -52l-72 -384
+c-7 -40 23 -76 63 -76h1062c40 0 70 36 63 76zM1136 1328c0 27 -21 48 -48 48h-640c-26 0 -48 -21 -48 -48s22 -48 48 -48h640c27 0 48 21 48 48zM1536 603v-603h-128v-128c0 -71 -57 -128 -128 -128s-128 57 -128 128v128h-768v-128c0 -71 -57 -128 -128 -128
+s-128 57 -128 128v128h-128v603c0 82 7 143 25 223l103 454c19 160 299 256 640 256s621 -96 640 -256l105 -454c18 -80 23 -141 23 -223z" />
+ <glyph glyph-name="registered" unicode="&#xf25d;" horiz-adv-x="1792"
+d="M1042 833c0 58 -20 99 -60 121c-20 11 -48 18 -117 18h-123v-281h162c88 0 138 52 138 142zM1094 548l205 -373c5 -10 5 -22 -1 -31c-5 -10 -16 -16 -27 -16h-152c-12 0 -23 6 -28 17l-194 365h-155v-350c0 -18 -14 -32 -32 -32h-134c-18 0 -32 14 -32 32v960
+c0 18 14 32 32 32h294c105 0 151 -9 190 -24c113 -42 183 -153 183 -289c0 -123 -61 -227 -158 -275c3 -5 6 -10 9 -16zM896 1376c-406 0 -736 -330 -736 -736s330 -736 736 -736s736 330 736 736s-330 736 -736 736zM1792 640c0 -495 -401 -896 -896 -896
+s-896 401 -896 896s401 896 896 896s896 -401 896 -896z" />
+ <glyph glyph-name="mars" unicode="&#xf222;"
+d="M1472 1408c35 0 64 -29 64 -64v-416c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v262l-382 -383c79 -98 126 -223 126 -359c0 -318 -258 -576 -576 -576s-576 258 -576 576s258 576 576 576c136 0 261 -47 359 -126l382 382h-261c-18 0 -32 14 -32 32v64
+c0 18 14 32 32 32h416zM576 0c247 0 448 201 448 448s-201 448 -448 448s-448 -201 -448 -448s201 -448 448 -448z" />
+ <glyph glyph-name="hand-rock-o" unicode="&#xf255;"
+d="M768 1152c-71 0 -128 -57 -128 -128v-128h-32v93c0 63 -48 115 -112 115c-62 0 -112 -50 -112 -112v-429l-32 30v172c0 63 -48 115 -112 115c-62 0 -112 -50 -112 -112v-224c0 -31 13 -60 35 -82l310 -296c29 -29 39 -62 39 -102c0 -35 29 -64 64 -64h640
+c35 0 64 29 64 64v25c0 26 3 52 10 77l108 436c7 25 10 51 10 77v246c0 63 -48 115 -112 115c-62 0 -112 -50 -112 -112v-32h-32v125c0 53 -36 102 -89 113c-7 1 -15 2 -23 2c-62 0 -112 -50 -112 -112v-128h-32v122c0 67 -48 126 -115 133c-5 1 -9 1 -13 1zM768 1280
+c54 0 106 -17 149 -50c37 22 80 34 123 34c79 0 152 -38 197 -103c19 5 39 7 59 7c134 0 240 -110 240 -243v-246c0 -36 -5 -73 -13 -108l-109 -436c-6 -24 -6 -47 -6 -71c0 -106 -86 -192 -192 -192h-640c-114 0 -192 91 -192 201l-308 296c-47 45 -76 109 -76 175v224
+c0 132 108 240 240 240c6 0 11 0 16 -1c8 127 114 225 240 225c34 0 67 -7 98 -21c47 45 109 69 174 69z" />
+ <glyph glyph-name="window-close" unicode="&#xf2d3;" horiz-adv-x="1792"
+d="M1175 215l146 146c13 13 13 33 0 46l-233 233l233 233c13 13 13 33 0 46l-146 146c-13 13 -33 13 -46 0l-233 -233l-233 233c-13 13 -33 13 -46 0l-146 -146c-13 -13 -13 -33 0 -46l233 -233l-233 -233c-13 -13 -13 -33 0 -46l146 -146c13 -13 33 -13 46 0l233 233
+l233 -233c13 -13 33 -13 46 0zM1792 1248v-1216c0 -88 -72 -160 -160 -160h-1472c-88 0 -160 72 -160 160v1216c0 88 72 160 160 160h1472c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="link" unicode="&#xf0c1;" horiz-adv-x="1632"
+d="M1440 320c0 26 -10 50 -28 68l-208 208c-18 18 -43 28 -68 28c-29 0 -52 -11 -72 -32c33 -33 72 -61 72 -112c0 -53 -43 -96 -96 -96c-51 0 -79 39 -112 72c-21 -20 -33 -43 -33 -73c0 -25 10 -50 28 -68l206 -207c18 -18 43 -27 68 -27s50 9 68 26l147 146
+c18 18 28 42 28 67zM737 1025c0 25 -10 50 -28 68l-206 207c-18 18 -43 28 -68 28s-50 -10 -68 -27l-147 -146c-18 -18 -28 -42 -28 -67c0 -26 10 -50 28 -68l208 -208c18 -18 43 -27 68 -27c29 0 52 10 72 31c-33 33 -72 61 -72 112c0 53 43 96 96 96c51 0 79 -39 112 -72
+c21 20 33 43 33 73zM1632 320c0 -76 -31 -150 -85 -203l-147 -146c-54 -54 -127 -83 -203 -83c-77 0 -150 30 -204 85l-206 207c-54 54 -83 127 -83 203c0 79 32 154 88 209l-88 88c-55 -56 -129 -88 -208 -88c-76 0 -150 30 -204 84l-208 208c-55 55 -84 127 -84 204
+c0 76 31 150 85 203l147 146c54 54 127 83 203 83c77 0 150 -30 204 -85l206 -207c54 -54 83 -127 83 -203c0 -79 -32 -154 -88 -209l88 -88c55 56 129 88 208 88c76 0 150 -30 204 -84l208 -208c55 -55 84 -127 84 -204z" />
+ <glyph glyph-name="window-minimize" unicode="&#xf2d1;" horiz-adv-x="1792"
+d="M1792 224v-192c0 -88 -72 -160 -160 -160h-1472c-88 0 -160 72 -160 160v192c0 88 72 160 160 160h1472c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="eyedropper" unicode="&#xf1fb;" horiz-adv-x="1792"
+d="M1698 1442c125 -125 126 -328 0 -452l-225 -223l104 -104c13 -13 13 -33 0 -46l-210 -210c-13 -13 -33 -13 -46 0l-105 105l-603 -603c-24 -24 -56 -37 -90 -37h-203l-256 -128l-64 64l128 256v203c0 34 13 66 37 90l603 603l-105 105c-13 13 -13 33 0 46l210 210
+c13 13 33 13 46 0l104 -104l223 225c124 126 327 125 452 0zM512 64l576 576l-192 192l-576 -576v-192h192z" />
+ <glyph glyph-name="bug" unicode="&#xf188;" horiz-adv-x="1600"
+d="M1600 576c0 -35 -29 -64 -64 -64h-224c0 -125 -27 -219 -67 -290l208 -209c25 -25 25 -65 0 -90c-12 -13 -29 -19 -45 -19s-33 6 -45 19l-198 197s-131 -120 -301 -120v896h-128v-896c-181 0 -313 132 -313 132l-183 -207c-13 -14 -30 -21 -48 -21c-15 0 -30 5 -43 16
+c-26 24 -28 64 -5 91l202 227c-35 69 -58 158 -58 274h-224c-35 0 -64 29 -64 64s29 64 64 64h224v294l-173 173c-25 25 -25 65 0 90s65 25 90 0l173 -173h844l173 173c25 25 65 25 90 0s25 -65 0 -90l-173 -173v-294h224c35 0 64 -29 64 -64zM1120 1152h-640
+c0 177 143 320 320 320s320 -143 320 -320z" />
+ <glyph glyph-name="angellist" unicode="&#xf209;" horiz-adv-x="1258"
+d="M942 1158l-114 -328l117 -21c30 82 165 451 165 518c0 25 -8 56 -38 56c-56 0 -116 -182 -130 -225zM643 471c11 -29 23 -58 33 -88c22 25 45 48 71 67c-35 7 -70 10 -104 21zM351 1367c0 -102 121 -420 159 -521c14 8 32 10 49 10c24 0 51 -3 75 -5l-121 351
+c-13 38 -71 220 -123 220c-27 0 -39 -32 -39 -55zM272 608c0 -73 196 -342 269 -342c20 0 37 22 37 40c0 23 -23 80 -32 102c-26 67 -121 274 -203 274c-27 0 -71 -47 -71 -74zM114 273c0 -36 12 -71 25 -104c79 -195 257 -309 465 -309c152 0 280 58 382 170
+c108 120 152 268 152 427c0 56 1 145 -43 185c-84 74 -369 102 -482 102c-14 0 -38 -1 -49 -11c-12 -5 -12 -24 -12 -35c0 -153 323 -139 420 -139c19 0 28 -5 40 -19c13 -16 17 -35 19 -55c-26 -26 -62 -41 -96 -54c-33 -12 -65 -25 -93 -46c-77 -56 -153 -152 -153 -251
+c0 -62 37 -115 37 -176c0 -1 -7 -23 -7 -26c-114 8 -142 121 -146 216c-12 -3 -28 -2 -41 -2c2 -7 2 -14 2 -21c0 -73 -65 -126 -135 -126c-108 0 -251 127 -251 237c0 30 13 47 33 67c20 -25 41 -50 60 -76c29 -39 79 -104 133 -104c14 0 41 12 41 29
+c0 45 -164 256 -204 256c-63 0 -97 -83 -97 -135zM0 264c0 130 50 216 179 251c-11 29 -28 73 -28 104c0 82 101 184 183 184c24 0 48 -7 70 -15c-42 119 -163 454 -163 567c0 101 51 181 160 181c140 0 299 -504 333 -604c44 110 182 571 338 571c98 0 153 -78 153 -171
+c0 -106 -118 -436 -159 -550c168 -41 192 -177 192 -328c0 -400 -255 -710 -668 -710c-76 0 -151 15 -223 42c-190 72 -367 267 -367 478z" />
+ <glyph glyph-name="chain-broken" unicode="&#xf127;" horiz-adv-x="1664"
+d="M439 265l-256 -256c-7 -6 -15 -9 -23 -9s-16 3 -23 9c-12 13 -12 33 0 46l256 256c13 12 33 12 46 0c12 -13 12 -33 0 -46zM608 224v-320c0 -18 -14 -32 -32 -32s-32 14 -32 32v320c0 18 14 32 32 32s32 -14 32 -32zM384 448c0 -18 -14 -32 -32 -32h-320
+c-18 0 -32 14 -32 32s14 32 32 32h320c18 0 32 -14 32 -32zM1648 320c0 -77 -30 -149 -85 -203l-147 -146c-54 -54 -126 -83 -203 -83s-150 30 -204 85l-334 335c-17 17 -30 36 -42 56l239 18l273 -274c36 -36 100 -37 136 -1l147 146c18 18 28 42 28 67c0 26 -10 50 -28 68
+l-274 275l18 239c20 -12 39 -25 56 -42l336 -336c54 -55 84 -127 84 -204zM1031 1044l-239 -18l-273 274c-18 18 -42 28 -68 28s-50 -10 -68 -27l-147 -146c-18 -18 -28 -42 -28 -67c0 -26 10 -50 28 -68l274 -274l-18 -240c-20 12 -39 25 -56 42l-336 336
+c-54 55 -84 127 -84 204s30 149 85 203l147 146c54 54 126 83 203 83s150 -30 204 -85l334 -335c17 -17 30 -36 42 -56zM1664 960c0 -18 -14 -32 -32 -32h-320c-18 0 -32 14 -32 32s14 32 32 32h320c18 0 32 -14 32 -32zM1120 1504v-320c0 -18 -14 -32 -32 -32
+s-32 14 -32 32v320c0 18 14 32 32 32s32 -14 32 -32zM1527 1353l-256 -256c-7 -6 -15 -9 -23 -9s-16 3 -23 9c-12 13 -12 33 0 46l256 256c13 12 33 12 46 0c12 -13 12 -33 0 -46z" />
+ <glyph glyph-name="info" unicode="&#xf129;" horiz-adv-x="640"
+d="M640 192v-128c0 -35 -29 -64 -64 -64h-512c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h64v384h-64c-35 0 -64 29 -64 64v128c0 35 29 64 64 64h384c35 0 64 -29 64 -64v-576h64c35 0 64 -29 64 -64zM512 1344v-192c0 -35 -29 -64 -64 -64h-256c-35 0 -64 29 -64 64v192
+c0 35 29 64 64 64h256c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="tumblr" unicode="&#xf173;" horiz-adv-x="956"
+d="M876 207l80 -237c-30 -45 -166 -96 -288 -98c-363 -6 -500 258 -500 444v544h-168v215c252 91 313 319 327 449c1 8 8 12 12 12h244v-424h333v-252h-334v-518c0 -70 26 -167 160 -164c44 1 103 14 134 29z" />
+ <glyph glyph-name="line-chart" unicode="&#xf201;" horiz-adv-x="2048"
+d="M2048 0v-128h-2048v1536h128v-1408h1920zM1920 1248v-435c0 -28 -34 -43 -55 -22l-121 121l-633 -633c-13 -13 -33 -13 -46 0l-233 233l-416 -416l-192 192l585 585c13 13 33 13 46 0l233 -233l464 464l-121 121c-21 21 -6 55 22 55h435c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="long-arrow-up" unicode="&#xf176;" horiz-adv-x="767"
+d="M765 1043c-5 -11 -16 -19 -29 -19h-224v-1248c0 -18 -14 -32 -32 -32h-192c-18 0 -32 14 -32 32v1248h-224c-13 0 -24 7 -29 19s-3 25 5 35l350 384c6 6 14 10 23 10s18 -4 24 -10l355 -384c8 -10 10 -23 5 -35z" />
+ <glyph glyph-name="simplybuilt" unicode="&#xf215;" horiz-adv-x="2048"
+d="M863 504c0 150 -121 271 -271 271c-149 0 -270 -121 -270 -271c0 -149 121 -270 270 -270c150 0 271 121 271 270zM1726 505c0 149 -121 270 -270 270c-150 0 -271 -121 -271 -270c0 -150 121 -271 271 -271c149 0 270 121 270 271zM2048 1314v-1348
+c0 -59 -48 -107 -108 -107h-1832c-60 0 -108 48 -108 107v1348c0 59 48 107 108 107h431c59 0 108 -48 108 -107v-161h754v161c0 59 49 107 108 107h431c60 0 108 -48 108 -107z" />
+ <glyph glyph-name="trash" unicode="&#xf1f8;" horiz-adv-x="1408"
+d="M512 160v704c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-704c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM768 160v704c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-704c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM1024 160v704c0 18 -14 32 -32 32h-64
+c-18 0 -32 -14 -32 -32v-704c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM480 1152h448l-48 117c-3 4 -12 10 -17 11h-317c-6 -1 -14 -7 -17 -11zM1408 1120v-64c0 -18 -14 -32 -32 -32h-96v-948c0 -110 -72 -204 -160 -204h-832c-88 0 -160 90 -160 200v952h-96
+c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h309l70 167c20 49 80 89 133 89h320c53 0 113 -40 133 -89l70 -167h309c18 0 32 -14 32 -32z" />
+ <glyph glyph-name="free-code-camp" unicode="&#xf2c5;" horiz-adv-x="2304"
+d="M453 -101c0 -28 -25 -54 -53 -54c-4 0 -9 2 -13 3c-56 13 -128 97 -162 140c-156 197 -225 427 -225 676c0 232 70 431 213 614c33 43 131 156 189 156c25 0 51 -20 51 -46c0 -30 -44 -71 -63 -90c-55 -57 -106 -115 -147 -184c-85 -142 -119 -284 -119 -449
+c0 -177 33 -337 123 -491c38 -65 83 -119 136 -173c21 -23 70 -68 70 -102zM1796 33c0 -37 -25 -68 -64 -68h-1081c-35 0 -64 29 -64 64c0 37 25 68 64 68h1081c35 0 64 -29 64 -64zM1581 644c0 -84 -19 -162 -67 -233c-33 -49 -100 -112 -153 -139c-8 -5 -18 -10 -27 -10
+c-8 0 -23 9 -23 18c0 29 122 98 122 232c0 44 -11 93 -35 130c-7 10 -32 42 -46 42c-3 0 -3 -2 -3 -5c0 -24 15 -47 15 -72c0 -32 -39 -48 -66 -48c-47 0 -66 33 -66 76c0 29 3 59 3 88c0 21 -1 27 -10 46c-14 27 -60 82 -93 82c-9 0 -12 0 -12 -9c0 -14 32 -29 32 -80
+c0 -133 -183 -157 -183 -290c0 -60 8 -110 42 -160c21 -31 44 -49 79 -63c9 -3 18 -4 18 -15s-9 -16 -18 -16c-5 0 -28 9 -33 11c-154 56 -271 190 -271 358c0 199 239 373 239 564c0 37 -6 63 -25 94c-11 18 -38 53 -56 64c-8 4 -19 11 -19 21c0 17 29 20 41 20
+c36 0 77 -13 110 -29c139 -66 168 -167 192 -307c6 -33 18 -138 66 -138c31 0 51 21 51 51c0 45 -40 94 -40 119c0 7 4 10 10 10c25 0 77 -53 93 -70c97 -103 133 -203 133 -342zM2304 615c0 -176 -47 -352 -138 -503c-42 -70 -180 -266 -271 -266c-21 0 -46 26 -46 47
+c0 34 117 143 146 180c124 156 183 332 183 531c0 164 -20 297 -93 446c-45 92 -92 154 -163 228c-23 24 -73 69 -73 105c0 25 26 52 51 52c66 0 161 -122 196 -169c134 -180 191 -365 206 -587c1 -21 2 -43 2 -64z" />
+ <glyph glyph-name="windows" unicode="&#xf17a;" horiz-adv-x="1664"
+d="M682 530v-651l-682 94v557h682zM682 1273v-659h-682v565zM1664 530v-786l-907 125v661h907zM1664 1408v-794h-907v669z" />
+ <glyph glyph-name="calendar-o" unicode="&#xf133;" horiz-adv-x="1664"
+d="M128 -128h1408v1024h-1408v-1024zM512 1088v288c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-288c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM1280 1088v288c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-288c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM1664 1152
+v-1280c0 -70 -58 -128 -128 -128h-1408c-70 0 -128 58 -128 128v1280c0 70 58 128 128 128h128v96c0 88 72 160 160 160h64c88 0 160 -72 160 -160v-96h384v96c0 88 72 160 160 160h64c88 0 160 -72 160 -160v-96h128c70 0 128 -58 128 -128z" />
+ <glyph glyph-name="suitcase" unicode="&#xf0f2;" horiz-adv-x="1792"
+d="M640 1152h512v128h-512v-128zM288 1152v-1280h-64c-123 0 -224 101 -224 224v832c0 123 101 224 224 224h64zM1408 1152v-1280h-1024v1280h128v160c0 53 43 96 96 96h576c53 0 96 -43 96 -96v-160h128zM1792 928v-832c0 -123 -101 -224 -224 -224h-64v1280h64
+c123 0 224 -101 224 -224z" />
+ <glyph glyph-name="arrow-circle-o-up" unicode="&#xf01b;"
+d="M1118 660c-5 -12 -17 -20 -30 -20h-192v-352c0 -18 -14 -32 -32 -32h-192c-18 0 -32 14 -32 32v352h-192c-18 0 -32 14 -32 32c0 9 4 17 10 24l319 319c7 6 15 9 23 9s16 -3 23 -9l320 -320c9 -10 12 -23 7 -35zM768 1184c-300 0 -544 -244 -544 -544s244 -544 544 -544
+s544 244 544 544s-244 544 -544 544zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="arrow-up" unicode="&#xf062;" horiz-adv-x="1558"
+d="M1558 565c0 -34 -14 -66 -37 -90l-75 -75c-24 -24 -57 -38 -91 -38s-67 14 -90 38l-294 293v-704c0 -72 -60 -117 -128 -117h-128c-68 0 -128 45 -128 117v704l-294 -293c-23 -24 -56 -38 -90 -38s-67 14 -90 38l-75 75c-24 24 -38 56 -38 90s14 67 38 91l651 651
+c23 24 56 37 90 37s67 -13 91 -37l651 -651c23 -24 37 -57 37 -91z" />
+ <glyph glyph-name="venus-mars" unicode="&#xf228;" horiz-adv-x="2048"
+d="M1664 1504c0 18 14 32 32 32h288c35 0 64 -29 64 -64v-288c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v134l-254 -255c98 -123 147 -286 117 -461c-42 -240 -237 -431 -478 -467c-152 -23 -295 14 -409 90c-75 -50 -162 -83 -256 -93v-132h96c18 0 32 -14 32 -32
+v-64c0 -18 -14 -32 -32 -32h-96v-96c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v96h-96c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h96v132c-314 35 -553 323 -506 654c34 249 232 449 480 487c153 23 296 -14 410 -90c92 61 202 97 320 97c136 0 261 -48 359 -126
+l255 254h-134c-18 0 -32 14 -32 32v64zM896 391c79 81 128 191 128 313s-49 232 -128 313c-79 -81 -128 -191 -128 -313s49 -232 128 -313zM128 704c0 -247 201 -448 448 -448c79 0 154 21 218 57c-95 103 -154 240 -154 391s59 288 154 391c-64 36 -139 57 -218 57
+c-247 0 -448 -201 -448 -448zM1216 256c247 0 448 201 448 448s-201 448 -448 448c-79 0 -154 -21 -218 -57c95 -103 154 -240 154 -391s-59 -288 -154 -391c64 -36 139 -57 218 -57z" />
+ <glyph glyph-name="pause-circle" unicode="&#xf28b;"
+d="M704 352v576c0 18 -14 32 -32 32h-256c-18 0 -32 -14 -32 -32v-576c0 -18 14 -32 32 -32h256c18 0 32 14 32 32zM1152 352v576c0 18 -14 32 -32 32h-256c-18 0 -32 -14 -32 -32v-576c0 -18 14 -32 32 -32h256c18 0 32 14 32 32zM1536 640c0 -424 -344 -768 -768 -768
+s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="shopping-cart" unicode="&#xf07a;" horiz-adv-x="1664"
+d="M640 0c0 -70 -58 -128 -128 -128s-128 58 -128 128s58 128 128 128s128 -58 128 -128zM1536 0c0 -70 -58 -128 -128 -128s-128 58 -128 128s58 128 128 128s128 -58 128 -128zM1664 1088v-512c0 -32 -25 -60 -57 -64l-1044 -122c5 -23 13 -46 13 -70
+c0 -23 -14 -44 -24 -64h920c35 0 64 -29 64 -64s-29 -64 -64 -64h-1024c-35 0 -64 29 -64 64c0 31 45 106 61 137l-177 823h-204c-35 0 -64 29 -64 64s29 64 64 64h256c67 0 69 -80 79 -128h1201c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="files-o" unicode="&#xf0c5;" horiz-adv-x="1792"
+d="M1696 1152c53 0 96 -43 96 -96v-1216c0 -53 -43 -96 -96 -96h-960c-53 0 -96 43 -96 96v288h-544c-53 0 -96 43 -96 96v672c0 53 31 127 68 164l408 408c37 37 111 68 164 68h416c53 0 96 -43 96 -96v-328c39 23 89 40 128 40h416zM1152 939l-299 -299h299v299zM512 1323
+l-299 -299h299v299zM708 676l316 316v416h-384v-416c0 -53 -43 -96 -96 -96h-416v-640h512v256c0 53 31 127 68 164zM1664 -128v1152h-384v-416c0 -53 -43 -96 -96 -96h-416v-640h896z" />
+ <glyph glyph-name="mastodon-square" unicode="&#xf300;"
+d="M288 1408h960c159 0 288 -129 288 -288v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288zM766 1189v0c-140 -1 -275 -17 -354 -53c0 0 -156 -70 -156 -308c0 -55 -1 -119 1 -188c6 -233 43 -463 258 -520
+c99 -26 184 -32 253 -28c124 7 195 45 195 45l-5 90s-88 -28 -188 -25c-99 3 -204 11 -220 133c-1 11 -2 22 -2 34c0 0 97 -24 220 -30c75 -3 146 4 218 13c138 16 257 102 272 179c24 122 22 297 22 297c0 238 -156 308 -156 308c-79 36 -214 52 -354 53h-4zM608 1003v0
+c58 0 103 -23 132 -68l28 -47l28 47c29 45 74 68 132 68c51 0 92 -18 123 -53c31 -34 45 -81 45 -140v-288h-114v280c0 59 -25 88 -75 88c-55 0 -82 -35 -82 -105v-153h-114v153c0 70 -27 105 -82 105c-50 0 -75 -29 -75 -88v-280h-114v288c0 59 15 105 45 140
+c31 35 72 53 123 53z" />
+ <glyph glyph-name="th-large" unicode="&#xf009;" horiz-adv-x="1664"
+d="M768 512v-384c0 -70 -58 -128 -128 -128h-512c-70 0 -128 58 -128 128v384c0 70 58 128 128 128h512c70 0 128 -58 128 -128zM768 1280v-384c0 -70 -58 -128 -128 -128h-512c-70 0 -128 58 -128 128v384c0 70 58 128 128 128h512c70 0 128 -58 128 -128zM1664 512v-384
+c0 -70 -58 -128 -128 -128h-512c-70 0 -128 58 -128 128v384c0 70 58 128 128 128h512c70 0 128 -58 128 -128zM1664 1280v-384c0 -70 -58 -128 -128 -128h-512c-70 0 -128 58 -128 128v384c0 70 58 128 128 128h512c70 0 128 -58 128 -128z" />
+ <glyph glyph-name="at" unicode="&#xf1fa;"
+d="M972 761c0 144 -75 230 -201 230c-166 0 -344 -165 -344 -432c0 -149 74 -234 204 -234c201 0 341 230 341 436zM1536 640c0 -311 -222 -428 -412 -434c-13 0 -18 -1 -32 -1c-62 0 -111 18 -142 53c-19 22 -30 50 -33 83c-62 -78 -170 -154 -305 -154
+c-215 0 -338 133 -338 365c0 319 221 578 491 578c117 0 211 -50 261 -135l2 19l11 56c1 8 8 18 15 18h118c5 0 10 -7 13 -11c3 -3 4 -11 3 -16l-120 -614c-4 -19 -5 -34 -5 -48c0 -54 16 -65 57 -65c68 2 288 30 288 306c0 389 -251 640 -640 640
+c-353 0 -640 -287 -640 -640s287 -640 640 -640c147 0 291 51 405 144c14 12 34 10 45 -4l41 -49c5 -7 8 -15 7 -24c-1 -8 -5 -16 -12 -22c-136 -111 -309 -173 -486 -173c-423 0 -768 345 -768 768s345 768 768 768c459 0 768 -309 768 -768z" />
+ <glyph glyph-name="file" unicode="&#xf15b;"
+d="M1024 1024v472c14 -9 26 -18 36 -28l408 -408c10 -10 19 -22 28 -36h-472zM896 992c0 -53 43 -96 96 -96h544v-1056c0 -53 -43 -96 -96 -96h-1344c-53 0 -96 43 -96 96v1600c0 53 43 96 96 96h800v-544z" />
+ <glyph glyph-name="star-half" unicode="&#xf089;" horiz-adv-x="832"
+d="M832 1504v-1339l-449 -236c-13 -7 -26 -12 -40 -12c-29 0 -42 24 -42 50c0 7 1 13 2 20l86 500l-364 354c-12 13 -25 30 -25 48c0 30 31 42 56 46l502 73l225 455c9 19 26 41 49 41z" />
+ <glyph glyph-name="futbol-o" unicode="&#xf1e3;" horiz-adv-x="1792"
+d="M609 720l287 208l287 -208l-109 -336h-355zM896 1536c495 0 896 -401 896 -896s-401 -896 -896 -896s-896 401 -896 896s401 896 896 896zM1515 186c94 128 149 284 149 454v3l-102 -89l-240 224l63 323l134 -12c-95 131 -231 232 -389 282l53 -124l-287 -159l-287 159
+l53 124c-158 -50 -294 -151 -389 -282l135 12l62 -323l-240 -224l-102 89v-3c0 -170 55 -326 149 -454l30 132l326 -40l139 -298l-116 -69c75 -25 156 -39 240 -39s165 14 240 39l-116 69l139 298l326 40z" />
+ <glyph glyph-name="flag-checkered" unicode="&#xf11e;" horiz-adv-x="1728"
+d="M768 536v192c-122 -11 -269 -60 -384 -117v-185c116 54 260 100 384 110zM768 954v197c-126 -6 -274 -65 -384 -126v-189c118 61 260 113 384 118zM1600 491v184c-91 -45 -250 -112 -384 -71v224c-13 4 -26 9 -39 15c-115 58 -209 112 -360 112c-16 0 -32 -1 -49 -3v-222
+h19c151 0 275 -54 390 -111c13 -6 26 -11 39 -15v-188c27 -11 57 -17 91 -17c111 0 231 59 293 92zM1600 918v189c-80 -43 -192 -91 -306 -91c-27 0 -53 2 -78 8v-196c134 -38 293 39 384 90zM256 1280c0 -47 -26 -88 -64 -110v-1266c0 -18 -14 -32 -32 -32h-64
+c-18 0 -32 14 -32 32v1266c-38 22 -64 63 -64 110c0 71 57 128 128 128s128 -57 128 -128zM1728 1216v-763c0 -24 -14 -46 -35 -57c-4 -2 -10 -5 -17 -9c-64 -34 -215 -116 -369 -116c-59 0 -112 12 -158 35l-28 14c-101 51 -181 91 -304 91c-144 0 -347 -75 -464 -146
+c-10 -6 -22 -9 -33 -9s-22 3 -32 8c-20 12 -32 33 -32 56v742c0 22 12 43 31 55c64 38 290 163 500 163c167 0 303 -61 418 -117c26 -13 56 -19 89 -19c118 0 248 75 310 112c13 7 24 13 31 17c20 10 43 9 62 -2c19 -12 31 -33 31 -55z" />
+ <glyph glyph-name="genderless" unicode="&#xf22d;" horiz-adv-x="1152"
+d="M1024 576c0 247 -201 448 -448 448s-448 -201 -448 -448s201 -448 448 -448s448 201 448 448zM1152 576c0 -318 -258 -576 -576 -576s-576 258 -576 576s258 576 576 576s576 -258 576 -576z" />
+ <glyph glyph-name="archive" unicode="&#xf187;" horiz-adv-x="1664"
+d="M1024 704c0 35 -29 64 -64 64h-256c-35 0 -64 -29 -64 -64s29 -64 64 -64h256c35 0 64 29 64 64zM1600 896v-960c0 -35 -29 -64 -64 -64h-1408c-35 0 -64 29 -64 64v960c0 35 29 64 64 64h1408c35 0 64 -29 64 -64zM1664 1344v-256c0 -35 -29 -64 -64 -64h-1536
+c-35 0 -64 29 -64 64v256c0 35 29 64 64 64h1536c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="film" unicode="&#xf008;" horiz-adv-x="1920"
+d="M384 -64v128c0 35 -29 64 -64 64h-128c-35 0 -64 -29 -64 -64v-128c0 -35 29 -64 64 -64h128c35 0 64 29 64 64zM384 320v128c0 35 -29 64 -64 64h-128c-35 0 -64 -29 -64 -64v-128c0 -35 29 -64 64 -64h128c35 0 64 29 64 64zM384 704v128c0 35 -29 64 -64 64h-128
+c-35 0 -64 -29 -64 -64v-128c0 -35 29 -64 64 -64h128c35 0 64 29 64 64zM1408 -64v512c0 35 -29 64 -64 64h-768c-35 0 -64 -29 -64 -64v-512c0 -35 29 -64 64 -64h768c35 0 64 29 64 64zM384 1088v128c0 35 -29 64 -64 64h-128c-35 0 -64 -29 -64 -64v-128
+c0 -35 29 -64 64 -64h128c35 0 64 29 64 64zM1792 -64v128c0 35 -29 64 -64 64h-128c-35 0 -64 -29 -64 -64v-128c0 -35 29 -64 64 -64h128c35 0 64 29 64 64zM1408 704v512c0 35 -29 64 -64 64h-768c-35 0 -64 -29 -64 -64v-512c0 -35 29 -64 64 -64h768c35 0 64 29 64 64z
+M1792 320v128c0 35 -29 64 -64 64h-128c-35 0 -64 -29 -64 -64v-128c0 -35 29 -64 64 -64h128c35 0 64 29 64 64zM1792 704v128c0 35 -29 64 -64 64h-128c-35 0 -64 -29 -64 -64v-128c0 -35 29 -64 64 -64h128c35 0 64 29 64 64zM1792 1088v128c0 35 -29 64 -64 64h-128
+c-35 0 -64 -29 -64 -64v-128c0 -35 29 -64 64 -64h128c35 0 64 29 64 64zM1920 1248v-1344c0 -88 -72 -160 -160 -160h-1600c-88 0 -160 72 -160 160v1344c0 88 72 160 160 160h1600c88 0 160 -72 160 -160z" />
+ <glyph glyph-name="power-off" unicode="&#xf011;"
+d="M1536 640c0 -423 -345 -768 -768 -768s-768 345 -768 768c0 243 112 467 307 613c57 43 137 32 179 -25c43 -56 31 -137 -25 -179c-130 -98 -205 -247 -205 -409c0 -282 230 -512 512 -512s512 230 512 512c0 162 -75 311 -205 409c-56 42 -68 123 -25 179
+c42 57 123 68 179 25c195 -146 307 -370 307 -613zM896 1408v-640c0 -70 -58 -128 -128 -128s-128 58 -128 128v640c0 70 58 128 128 128s128 -58 128 -128z" />
+ <glyph glyph-name="percent" unicode="&#xf295;"
+d="M1280 256c0 70 -58 128 -128 128s-128 -58 -128 -128s58 -128 128 -128s128 58 128 128zM512 1024c0 70 -58 128 -128 128s-128 -58 -128 -128s58 -128 128 -128s128 58 128 128zM1536 256c0 -212 -172 -384 -384 -384s-384 172 -384 384s172 384 384 384
+s384 -172 384 -384zM1440 1344c0 -14 -5 -27 -13 -38l-1056 -1408c-12 -16 -31 -26 -51 -26h-160c-35 0 -64 29 -64 64c0 14 5 27 13 38l1056 1408c12 16 31 26 51 26h160c35 0 64 -29 64 -64zM768 1024c0 -212 -172 -384 -384 -384s-384 172 -384 384s172 384 384 384
+s384 -172 384 -384z" />
+ <glyph glyph-name="google-wallet" unicode="&#xf1ee;" horiz-adv-x="1756"
+d="M405 864c20 0 40 -10 52 -26c175 -239 297 -495 362 -774h-446c-80 278 -198 532 -367 749c-16 21 0 51 26 51h373zM964 507c-33 -135 -75 -266 -125 -393c-53 209 -138 405 -256 594c26 145 41 294 44 449c141 -227 253 -443 337 -650zM1063 1216
+c299 -412 521 -920 569 -1472h-451c-33 534 -279 1040 -553 1472h435zM1756 640c0 -278 -38 -570 -101 -812c-44 370 -166 738 -359 1083c-17 202 -53 398 -106 584c-5 21 10 41 31 41h359c28 0 54 -19 61 -46c76 -270 115 -556 115 -850z" />
+ <glyph glyph-name="book" unicode="&#xf02d;" horiz-adv-x="1664"
+d="M1639 1058c25 -36 32 -83 18 -129l-275 -906c-25 -85 -113 -151 -199 -151h-923c-102 0 -211 81 -248 185c-16 45 -16 89 -2 127c2 20 6 40 7 64c1 16 -8 29 -6 41c4 24 25 41 41 68c30 50 64 131 75 183c5 19 -5 41 0 58c5 19 24 33 34 51c27 46 62 135 67 182
+c2 21 -8 44 -2 60c7 23 29 33 44 53c24 33 64 128 70 181c2 17 -8 34 -5 52c4 19 28 39 44 62c42 62 50 199 177 163l-1 -3c17 4 34 9 51 9h761c47 0 89 -21 114 -56c26 -36 32 -83 18 -130l-274 -906c-47 -154 -73 -188 -200 -188h-869c-13 0 -29 -3 -38 -15
+c-8 -12 -9 -21 -1 -43c20 -58 89 -70 144 -70h923c37 0 80 21 91 57l300 987c6 19 6 39 5 57c23 -9 44 -23 59 -43zM575 1056c-6 -18 4 -32 22 -32h608c17 0 36 14 42 32l21 64c6 18 -4 32 -22 32h-608c-17 0 -36 -14 -42 -32zM492 800c-6 -18 4 -32 22 -32h608
+c17 0 36 14 42 32l21 64c6 18 -4 32 -22 32h-608c-17 0 -36 -14 -42 -32z" />
+ <glyph glyph-name="thermometer-three-quarters" unicode="&#xf2c8;" horiz-adv-x="1024"
+d="M640 192c0 -106 -86 -192 -192 -192s-192 86 -192 192c0 80 50 153 128 181v651h128v-651c78 -28 128 -101 128 -181zM768 192c0 105 -50 197 -128 256v768c0 106 -86 192 -192 192s-192 -86 -192 -192v-768c-78 -59 -128 -151 -128 -256c0 -177 143 -320 320 -320
+s320 143 320 320zM896 192c0 -247 -201 -448 -448 -448s-448 201 -448 448c0 122 49 232 128 313v711c0 177 143 320 320 320s320 -143 320 -320v-711c79 -81 128 -191 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192v128h192z
+" />
+ <glyph glyph-name="transgender" unicode="&#xf224;" horiz-adv-x="1408"
+d="M1024 1504c0 18 14 32 32 32h288c35 0 64 -29 64 -64v-288c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v134l-254 -255c78 -98 126 -223 126 -359c0 -296 -224 -540 -512 -572v-132h96c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-96v-96c0 -18 -14 -32 -32 -32
+h-64c-18 0 -32 14 -32 32v96h-96c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h96v132c-302 33 -535 302 -510 618c21 272 237 495 507 526c162 19 312 -31 426 -122l255 254h-134c-18 0 -32 14 -32 32v64zM576 256c247 0 448 201 448 448s-201 448 -448 448
+s-448 -201 -448 -448s201 -448 448 -448z" />
+ <glyph glyph-name="cloud-upload" unicode="&#xf0ee;" horiz-adv-x="1920"
+d="M1280 672c0 8 -3 17 -9 23l-352 352c-6 6 -14 9 -23 9c-8 0 -17 -3 -23 -9l-351 -351c-6 -7 -10 -15 -10 -24c0 -18 14 -32 32 -32h224v-352c0 -17 15 -32 32 -32h192c17 0 32 15 32 32v352h224c18 0 32 15 32 32zM1920 384c0 -212 -172 -384 -384 -384h-1088
+c-247 0 -448 201 -448 448c0 174 101 332 258 405c-1 15 -2 29 -2 43c0 283 229 512 512 512c208 0 395 -126 474 -318c46 40 105 62 166 62c141 0 256 -115 256 -256c0 -49 -14 -97 -41 -138c174 -41 297 -196 297 -374z" />
+ <glyph glyph-name="bullseye" unicode="&#xf140;"
+d="M1024 640c0 -141 -115 -256 -256 -256s-256 115 -256 256s115 256 256 256s256 -115 256 -256zM1152 640c0 212 -172 384 -384 384s-384 -172 -384 -384s172 -384 384 -384s384 172 384 384zM1280 640c0 -283 -229 -512 -512 -512s-512 229 -512 512s229 512 512 512
+s512 -229 512 -512zM1408 640c0 353 -287 640 -640 640s-640 -287 -640 -640s287 -640 640 -640s640 287 640 640zM1536 640c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="openid" unicode="&#xf19b;" horiz-adv-x="1792"
+d="M1086 1536v-1536l-272 -128c-460 41 -814 286 -814 583c0 286 330 524 767 577v-172c-286 -50 -496 -212 -496 -405c0 -204 234 -373 543 -412v1360zM1755 954l37 -390l-525 114l147 83c-78 46 -174 80 -280 99v172c185 -22 351 -78 481 -157z" />
+ <glyph glyph-name="repeat" unicode="&#xf01e;"
+d="M1536 1280v-448c0 -35 -29 -64 -64 -64h-448c-26 0 -49 16 -59 40c-10 23 -5 51 14 69l138 138c-94 87 -218 137 -349 137c-282 0 -512 -230 -512 -512s230 -512 512 -512c159 0 306 72 404 199c5 7 14 11 23 12c9 0 18 -3 25 -9l137 -138c12 -11 12 -30 2 -43
+c-146 -176 -362 -277 -591 -277c-423 0 -768 345 -768 768s345 768 768 768c197 0 388 -79 529 -212l130 129c18 19 46 24 70 14c23 -10 39 -33 39 -59z" />
+ <glyph glyph-name="star" unicode="&#xf005;" horiz-adv-x="1664"
+d="M1664 889c0 -18 -13 -35 -26 -48l-363 -354l86 -500c1 -7 1 -13 1 -20c0 -26 -12 -50 -41 -50c-14 0 -28 5 -40 12l-449 236l-449 -236c-13 -7 -26 -12 -40 -12c-29 0 -42 24 -42 50c0 7 1 13 2 20l86 500l-364 354c-12 13 -25 30 -25 48c0 30 31 42 56 46l502 73
+l225 455c9 19 26 41 49 41s40 -22 49 -41l225 -455l502 -73c24 -4 56 -16 56 -46z" />
+ <glyph glyph-name="users" unicode="&#xf0c0;" horiz-adv-x="1920"
+d="M593 640c-104 -3 -198 -48 -265 -128h-134c-100 0 -194 48 -194 159c0 81 -3 353 124 353c21 0 125 -85 260 -85c46 0 90 8 133 23c-3 -22 -5 -44 -5 -66c0 -91 29 -181 81 -256zM1664 3c0 -162 -107 -259 -267 -259h-874c-160 0 -267 97 -267 259c0 226 53 573 346 573
+c34 0 158 -139 358 -139s324 139 358 139c293 0 346 -347 346 -573zM640 1280c0 -141 -115 -256 -256 -256s-256 115 -256 256s115 256 256 256s256 -115 256 -256zM1344 896c0 -212 -172 -384 -384 -384s-384 172 -384 384s172 384 384 384s384 -172 384 -384zM1920 671
+c0 -111 -94 -159 -194 -159h-134c-67 80 -161 125 -265 128c52 75 81 165 81 256c0 22 -2 44 -5 66c43 -15 87 -23 133 -23c135 0 239 85 260 85c127 0 124 -272 124 -353zM1792 1280c0 -141 -115 -256 -256 -256s-256 115 -256 256s115 256 256 256s256 -115 256 -256z" />
+ <glyph glyph-name="transgender-alt" unicode="&#xf225;" horiz-adv-x="1664"
+d="M1280 1504c0 18 14 32 32 32h288c35 0 64 -29 64 -64v-288c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v134l-254 -255c78 -98 126 -223 126 -359c0 -296 -224 -540 -512 -572v-132h96c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-96v-96c0 -18 -14 -32 -32 -32
+h-64c-18 0 -32 14 -32 32v96h-96c-18 0 -32 14 -32 32v64c0 18 14 32 32 32h96v132c-288 32 -512 276 -512 572c0 136 48 261 126 359l-52 53l-101 -111c-12 -13 -32 -14 -45 -3l-48 44c-13 11 -14 32 -2 45l105 115l-111 112v-134c0 -18 -14 -32 -32 -32h-64
+c-18 0 -32 14 -32 32v288c0 35 29 64 64 64h288c18 0 32 -14 32 -32v-64c0 -18 -14 -32 -32 -32h-133l106 -107l86 94c12 13 32 14 45 3l48 -44c13 -11 14 -32 2 -45l-90 -99l57 -56c98 78 223 126 359 126s261 -48 359 -126l255 254h-134c-18 0 -32 14 -32 32v64zM832 256
+c247 0 448 201 448 448s-201 448 -448 448s-448 -201 -448 -448s201 -448 448 -448z" />
+ <glyph glyph-name="chevron-up" unicode="&#xf077;" horiz-adv-x="1612"
+d="M1593 205l-166 -165c-25 -25 -65 -25 -90 0l-531 531l-531 -531c-25 -25 -65 -25 -90 0l-166 165c-25 25 -25 66 0 91l742 741c25 25 65 25 90 0l742 -741c25 -25 25 -66 0 -91z" />
+ <glyph glyph-name="asterisk" unicode="&#xf069;" horiz-adv-x="1428"
+d="M1364 486c61 -35 82 -114 47 -175l-64 -110c-35 -61 -114 -82 -175 -47l-266 153v-307c0 -70 -58 -128 -128 -128h-128c-70 0 -128 58 -128 128v307l-266 -153c-61 -35 -140 -14 -175 47l-64 110c-35 61 -14 140 47 175l266 154l-266 154c-61 35 -82 114 -47 175l64 110
+c35 61 114 82 175 47l266 -153v307c0 70 58 128 128 128h128c70 0 128 -58 128 -128v-307l266 153c61 35 140 14 175 -47l64 -110c35 -61 14 -140 -47 -175l-266 -154z" />
+ <glyph glyph-name="plus-circle" unicode="&#xf055;"
+d="M1216 576v128c0 35 -29 64 -64 64h-256v256c0 35 -29 64 -64 64h-128c-35 0 -64 -29 -64 -64v-256h-256c-35 0 -64 -29 -64 -64v-128c0 -35 29 -64 64 -64h256v-256c0 -35 29 -64 64 -64h128c35 0 64 29 64 64v256h256c35 0 64 29 64 64zM1536 640
+c0 -424 -344 -768 -768 -768s-768 344 -768 768s344 768 768 768s768 -344 768 -768z" />
+ <glyph glyph-name="cart-arrow-down" unicode="&#xf218;" horiz-adv-x="1664"
+d="M1280 832c0 35 -29 64 -64 64c-17 0 -33 -7 -45 -19l-147 -146v293c0 35 -29 64 -64 64s-64 -29 -64 -64v-293l-147 146c-12 12 -28 19 -45 19c-35 0 -64 -29 -64 -64c0 -17 7 -33 19 -45l256 -256c12 -12 28 -19 45 -19s33 7 45 19l256 256c12 12 19 28 19 45zM640 0
+c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128s128 -57 128 -128zM1536 0c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128s128 -57 128 -128zM1664 1088v-512c0 -32 -24 -60 -57 -64l-1044 -122c4 -22 13 -47 13 -70s-14 -44 -24 -64h920
+c35 0 64 -29 64 -64s-29 -64 -64 -64h-1024c-35 0 -64 29 -64 64c0 31 47 108 61 137l-177 823h-204c-35 0 -64 29 -64 64s29 64 64 64h256c68 0 69 -80 79 -128h1201c35 0 64 -29 64 -64z" />
+ <glyph glyph-name="dropbox" unicode="&#xf16b;" horiz-adv-x="1664"
+d="M338 829l494 -305l-342 -285l-490 319zM1324 274v-108l-490 -293v-1l-1 1l-1 -1v1l-489 293v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284zM490 1418l342 -285l-494 -304l-338 270zM1326 829l338 -271l-489 -319l-343 285zM1175 1418l489 -319l-338 -270l-494 304z" />
+ <glyph glyph-name="debian" unicode="&#xf2ff;" horiz-adv-x="1440"
+d="M1 954c3 22 -11 29 15 62c-4 -17 -6 -33 -15 -62zM61 1152c0 -18 30 18 8 -31c-40 -28 -3 -12 -8 31zM754 1527c20 7 49 4 70 9c-28 -2 -55 -3 -82 -7l12 -2zM1399 728c-8 -61 -27 -121 -56 -176c26 52 43 108 51 165zM582 550l10 -27c-12 21 -26 42 -33 66
+c7 -14 13 -28 23 -39zM536 548c25 -47 38 -61 56 -96c-25 21 -40 49 -60 76zM1274 762c2 -48 -15 -72 -29 -113l-25 -13c-21 -41 2 -26 -13 -58c-33 -29 -100 -91 -121 -97c-16 0 11 19 14 26c-44 -30 -36 -46 -103 -64l-2 4c-166 -78 -395 76 -392 287
+c-2 -13 -5 -10 -9 -15c-9 108 50 218 149 262c97 48 210 28 279 -37c-38 50 -113 103 -203 98c-88 -1 -171 -57 -198 -118c-45 -28 -49 -109 -69 -124c-26 -194 49 -277 178 -376c20 -14 5 -16 8 -26c-43 20 -82 50 -114 87c17 -25 35 -49 59 -68c-40 14 -93 98 -109 101
+c69 -124 282 -218 393 -172c-51 -2 -117 -1 -175 20c-24 12 -57 39 -51 44c152 -57 308 -43 439 62c33 26 70 70 81 71c-16 -24 2 -12 -10 -33c33 54 -14 22 35 93l18 -25c-7 45 55 99 49 169c14 22 16 -23 1 -73c21 55 5 65 10 110c6 -15 14 -32 18 -48
+c-14 53 14 89 21 120c-7 3 -22 -23 -25 40c0 27 8 14 11 21c-5 3 -19 24 -28 64c6 9 17 -25 25 -26c-5 32 -15 57 -15 81c-25 51 -9 -7 -29 22c-26 82 22 19 25 56c40 -58 63 -147 73 -184c-8 45 -21 89 -37 131c12 -5 -19 93 16 28c-38 138 -161 266 -274 327
+c14 -13 31 -29 25 -31c-56 34 -46 37 -54 51c-46 19 -49 -1 -79 0c-86 46 -103 40 -183 69l4 -17c-57 19 -67 -7 -129 0c-4 3 20 11 39 14c-55 -7 -53 11 -107 -2c13 9 28 15 42 23c-45 -3 -107 -26 -88 -5c-74 -33 -205 -78 -278 -147l-2 15c-34 -40 -147 -121 -156 -173
+l-9 -2c-17 -30 -29 -64 -43 -94c-23 -39 -33 -15 -30 -21c-45 -91 -68 -168 -87 -231c14 -21 1 -123 6 -206c-23 -408 286 -804 624 -896c50 -18 123 -17 186 -19c-74 21 -84 11 -156 36c-52 24 -63 53 -100 85l15 -26c-72 26 -42 31 -101 50l16 20c-23 2 -62 40 -73 61
+l-25 -1c-31 38 -47 65 -46 86l-8 -15c-9 16 -114 142 -60 113c-10 9 -23 15 -37 41l11 13c-26 33 -48 76 -46 90c14 -19 23 -22 32 -25c-65 162 -68 9 -118 165l10 1c-8 12 -13 25 -19 38l5 45c-47 54 -14 232 -7 329c5 39 40 81 66 147l-16 3c31 53 174 214 241 206
+c32 41 -6 1 -12 11c71 74 93 52 141 65c52 31 -45 -13 -20 11c89 23 63 52 180 64c12 -7 -28 -11 -38 -20c75 36 235 28 340 -20c122 -57 259 -225 264 -383l6 -2c-3 -63 10 -135 -12 -202l15 32zM779 1504l-11 -2l11 1v1zM748 1513c53 -2 48 -5 31 -9c3 4 -15 6 -31 9z
+M1079 782c-5 -22 -10 13 -16 16c5 20 20 37 16 -16zM1020 629c18 24 30 51 35 79c-4 -20 -15 -37 -25 -55c-56 -35 -5 21 0 42c-60 -75 -8 -45 -10 -66zM860 589c-30 0 6 -15 45 -21c8 7 21 18 29 25c-24 -6 -49 -6 -74 -4z" />
+ <glyph glyph-name="newspaper-o" unicode="&#xf1ea;" horiz-adv-x="2048"
+d="M1024 1024h-384v-384h384v384zM1152 384v-128h-640v128h640zM1152 1152v-640h-640v640h640zM1792 384v-128h-512v128h512zM1792 640v-128h-512v128h512zM1792 896v-128h-512v128h512zM1792 1152v-128h-512v128h512zM256 192v960h-128v-960c0 -35 29 -64 64 -64
+s64 29 64 64zM1920 192v1088h-1536v-1088c0 -22 -4 -44 -11 -64h1483c35 0 64 29 64 64zM2048 1408v-1216c0 -106 -86 -192 -192 -192h-1664c-106 0 -192 86 -192 192v1088h256v128h1792z" />
+ <glyph glyph-name="building" unicode="&#xf1ad;" horiz-adv-x="1408"
+d="M1344 1536c35 0 64 -29 64 -64v-1664c0 -35 -29 -64 -64 -64h-1280c-35 0 -64 29 -64 64v1664c0 35 29 64 64 64h1280zM512 1248v-64c0 -18 14 -32 32 -32h64c18 0 32 14 32 32v64c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32zM512 992v-64c0 -18 14 -32 32 -32h64
+c18 0 32 14 32 32v64c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32zM512 736v-64c0 -18 14 -32 32 -32h64c18 0 32 14 32 32v64c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32zM512 480v-64c0 -18 14 -32 32 -32h64c18 0 32 14 32 32v64c0 18 -14 32 -32 32h-64
+c-18 0 -32 -14 -32 -32zM384 160v64c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM384 416v64c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM384 672v64
+c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM384 928v64c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM384 1184v64c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-64
+c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM896 -96v192c0 18 -14 32 -32 32h-320c-18 0 -32 -14 -32 -32v-192c0 -18 14 -32 32 -32h320c18 0 32 14 32 32zM896 416v64c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h64c18 0 32 14 32 32z
+M896 672v64c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM896 928v64c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM896 1184v64c0 18 -14 32 -32 32h-64
+c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM1152 160v64c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM1152 416v64c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h64
+c18 0 32 14 32 32zM1152 672v64c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM1152 928v64c0 18 -14 32 -32 32h-64c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h64c18 0 32 14 32 32zM1152 1184v64c0 18 -14 32 -32 32
+h-64c-18 0 -32 -14 -32 -32v-64c0 -18 14 -32 32 -32h64c18 0 32 14 32 32z" />
+ <glyph glyph-name="bitbucket" unicode="&#xf171;" horiz-adv-x="1408"
+d="M815 677c11 -84 -91 -150 -162 -107c-80 35 -80 162 -2 198c67 41 164 -13 164 -91zM926 698c-18 142 -179 236 -310 177c-83 -37 -139 -125 -135 -218c5 -122 121 -222 243 -211s217 130 202 252zM1165 1240c-44 58 -119 68 -185 79c-187 30 -379 31 -566 -2
+c-62 -10 -132 -21 -171 -77c64 -60 155 -69 237 -79c148 -19 300 -20 448 -1c83 10 175 18 237 80zM1222 205c-28 -98 -12 -230 -116 -287c-179 -99 -396 -110 -593 -75c-104 19 -226 52 -283 150c-25 96 -41 194 -57 292l6 16l18 9c298 -197 715 -197 1014 0
+c47 -14 12 -71 11 -105zM1403 1166c-34 -219 -73 -437 -111 -655c-11 -64 -73 -100 -125 -127c-187 -94 -405 -110 -610 -88c-139 15 -281 52 -394 139c-53 41 -53 111 -63 170c-35 205 -75 410 -100 617c12 90 113 129 188 157c100 37 207 54 313 64c226 22 457 14 676 -50
+c78 -23 162 -55 215 -122c24 -31 16 -70 11 -105z" />
+ <glyph glyph-name="yelp" unicode="&#xf1e9;" horiz-adv-x="1366"
+d="M688 217v-127c-1 -282 -1 -292 -6 -305c-8 -21 -26 -35 -51 -40c-72 -12 -297 71 -344 127c-10 11 -15 24 -17 36c-1 9 1 18 4 26c5 14 14 25 215 263c0 0 1 0 60 70c20 25 56 33 89 21c33 -13 51 -41 50 -71zM539 468c-2 -35 -22 -61 -52 -70l-120 -39
+c-269 -86 -278 -88 -292 -88c-22 1 -42 14 -54 36c-8 16 -14 43 -17 75c-11 98 2 245 31 291c14 22 34 33 56 32c15 0 27 -6 317 -124c0 0 -1 -1 84 -34c30 -12 49 -43 47 -79zM1365 171c-10 -72 -159 -261 -227 -288c-23 -9 -46 -7 -63 7c-12 9 -24 27 -184 287l-47 77
+c-18 28 -15 64 8 92c22 27 54 36 83 26c0 0 1 -1 119 -40c269 -88 278 -91 289 -100c18 -14 26 -35 22 -61zM693 803c5 -104 -39 -117 -54 -122c-14 -4 -58 -17 -114 71c-368 581 -378 598 -378 598c-5 21 1 44 19 62c55 57 354 141 432 121c25 -6 43 -22 49 -45
+c4 -25 40 -564 46 -685zM1355 695c2 -25 -7 -46 -26 -59c-12 -8 -24 -12 -329 -86c-49 -11 -76 -18 -91 -23l1 2c-30 -8 -64 6 -83 36s-18 63 0 87c0 0 1 1 75 102c164 224 172 235 184 243c19 13 42 13 65 2c65 -31 196 -226 204 -301v-3z" />
+ <glyph glyph-name="neuter" unicode="&#xf22c;" horiz-adv-x="1152"
+d="M1152 960c0 -296 -224 -540 -512 -572v-612c0 -18 -14 -32 -32 -32h-64c-18 0 -32 14 -32 32v612c-288 32 -512 276 -512 572c0 318 258 576 576 576s576 -258 576 -576zM576 512c247 0 448 201 448 448s-201 448 -448 448s-448 -201 -448 -448s201 -448 448 -448z" />
+ <glyph glyph-name="behance-square" unicode="&#xf1b5;"
+d="M1248 1408c159 0 288 -129 288 -288v-960c0 -159 -129 -288 -288 -288h-960c-159 0 -288 129 -288 288v960c0 159 129 288 288 288h960zM499 1041h-371v-787h382c143 0 277 68 277 228c0 99 -47 172 -143 200c70 34 107 85 107 164c0 157 -117 195 -252 195zM477 723
+h-176v184h163c62 0 119 -17 119 -90c0 -67 -44 -94 -106 -94zM486 388h-185v217h189c76 0 124 -33 124 -113s-57 -104 -128 -104zM1136 356c-92 0 -140 54 -140 145h411c1 10 1 20 1 30c0 168 -99 309 -278 309c-173 0 -292 -131 -292 -302c0 -178 112 -299 292 -299
+c137 0 225 61 267 191h-138c-15 -48 -76 -74 -123 -74zM1126 722c78 0 117 -47 124 -122h-254c5 75 55 122 130 122zM964 988v-77h319v77h-319z" />
+ <glyph glyph-name="wifi" unicode="&#xf1eb;" horiz-adv-x="1964"
+d="M982 13c-26 0 -166 140 -166 167c0 49 128 76 166 76s166 -27 166 -76c0 -27 -140 -167 -166 -167zM1252 284c-14 0 -123 100 -270 100c-148 0 -255 -100 -270 -100c-24 0 -169 144 -169 168c0 9 4 17 10 23c107 106 281 165 429 165s322 -59 429 -165
+c6 -6 10 -14 10 -23c0 -24 -145 -168 -169 -168zM1525 556c-8 0 -17 4 -23 8c-165 128 -304 204 -520 204c-302 0 -532 -212 -543 -212c-23 0 -167 144 -167 168c0 8 4 16 10 22c179 179 449 278 700 278s521 -99 700 -278c6 -6 10 -14 10 -22c0 -24 -144 -168 -167 -168z
+M1796 827c-8 0 -16 4 -22 9c-231 203 -480 316 -792 316s-561 -113 -792 -316c-6 -5 -14 -9 -22 -9c-23 0 -168 144 -168 168c0 9 4 17 10 23c253 251 618 390 972 390s719 -139 972 -390c6 -6 10 -14 10 -23c0 -24 -145 -168 -168 -168z" />
+ <glyph glyph-name="youtube" unicode="&#xf167;" horiz-adv-x="1482"
+d="M944 292v-211c0 -45 -13 -67 -39 -67c-15 0 -30 7 -45 22v301c15 15 30 22 45 22c26 0 39 -23 39 -67zM1282 291v-46h-90v46c0 45 15 68 45 68s45 -23 45 -68zM316 509h107v94h-312v-94h105v-569h100v569zM604 -60h89v494h-89v-378c-20 -28 -39 -42 -57 -42
+c-12 0 -19 7 -21 21c-1 3 -1 14 -1 35v364h-89v-391c0 -35 3 -58 8 -73c8 -25 29 -37 58 -37c32 0 66 20 102 61v-54zM1033 88v197c0 46 -2 79 -9 99c-11 37 -36 56 -71 56c-33 0 -64 -18 -93 -54v217h-89v-663h89v48c30 -37 61 -55 93 -55c35 0 60 19 71 55
+c7 21 9 54 9 100zM1371 98v13h-91c0 -36 -1 -56 -2 -61c-5 -24 -18 -36 -40 -36c-31 0 -46 23 -46 69v87h179v103c0 53 -9 91 -27 116c-26 34 -61 51 -106 51c-46 0 -81 -17 -107 -51c-19 -25 -28 -63 -28 -116v-173c0 -53 10 -92 29 -116c26 -34 61 -51 108 -51
+s84 18 108 53c11 16 19 34 21 54c2 9 2 29 2 58zM763 1011v210c0 46 -13 69 -43 69c-29 0 -43 -23 -43 -69v-210c0 -46 14 -70 43 -70c30 0 43 24 43 70zM1482 260c0 -115 -1 -238 -26 -350c-19 -79 -83 -137 -160 -145c-184 -21 -370 -21 -555 -21s-371 0 -555 21
+c-77 8 -142 66 -160 145c-26 112 -26 235 -26 350c0 116 1 238 26 350c19 79 83 137 161 146c183 20 369 20 554 20s371 0 555 -20c77 -9 142 -67 160 -146c26 -112 26 -234 26 -350zM484 1536h102l-121 -399v-271h-100v271c-9 49 -29 119 -61 212c-22 62 -44 125 -65 187
+h106l71 -263zM854 1203v-175c0 -53 -9 -93 -28 -118c-25 -34 -60 -51 -106 -51c-45 0 -80 17 -105 51c-19 26 -28 65 -28 118v175c0 53 9 92 28 117c25 34 60 51 105 51c46 0 81 -17 106 -51c19 -25 28 -64 28 -117zM1189 1365v-499h-91v55c-36 -42 -70 -62 -103 -62
+c-29 0 -50 12 -59 37c-5 15 -8 39 -8 75v394h91v-367c0 -21 0 -33 1 -35c2 -14 9 -22 21 -22c18 0 37 14 57 43v381h91z" />
+ <glyph glyph-name="angle-double-down" unicode="&#xf103;" horiz-adv-x="998"
+d="M998 672c0 -8 -4 -17 -10 -23l-466 -466c-6 -6 -15 -10 -23 -10s-17 4 -23 10l-466 466c-6 6 -10 15 -10 23s4 17 10 23l50 50c6 6 14 10 23 10c8 0 17 -4 23 -10l393 -393l393 393c6 6 15 10 23 10s17 -4 23 -10l50 -50c6 -6 10 -15 10 -23zM998 1056
+c0 -8 -4 -17 -10 -23l-466 -466c-6 -6 -15 -10 -23 -10s-17 4 -23 10l-466 466c-6 6 -10 15 -10 23s4 17 10 23l50 50c6 6 14 10 23 10c8 0 17 -4 23 -10l393 -393l393 393c6 6 15 10 23 10s17 -4 23 -10l50 -50c6 -6 10 -15 10 -23z" />
+ <glyph glyph-name="sort-alpha-asc" unicode="&#xf15d;" horiz-adv-x="1629"
+d="M1159 1128h177l-72 218l-12 47c-1 8 -2 14 -2 20h-4l-3 -20c-3 -12 -4 -27 -11 -47zM704 96c0 -9 -4 -17 -10 -24l-319 -319c-7 -6 -15 -9 -23 -9s-16 3 -23 9l-320 320c-9 10 -12 23 -7 35s17 20 30 20h192v1376c0 18 14 32 32 32h192c18 0 32 -14 32 -32v-1376h192
+c18 0 32 -14 32 -32zM1540 -23v-233h-584v90l369 529c8 12 16 22 21 27l11 9v3c-4 0 -8 -1 -14 -1c-8 -2 -18 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530c-6 -9 -14 -18 -21 -26l-11 -11v-2l14 2c9 2 18 2 30 2h248v119h121zM1629 874v-106h-288v106h75l-47 144h-243
+l-47 -144h75v-106h-287v106h70l230 662h162l230 -662h70z" />
+ <glyph glyph-name="area-chart" unicode="&#xf1fe;" horiz-adv-x="2048"
+d="M2048 0v-128h-2048v1536h128v-1408h1920zM1664 1024l256 -896h-1664v576l448 576l576 -576z" />
+ <glyph glyph-name="dev-to" unicode="&#xf316;"
+d="M39 1403v0c13 5 121 6 735 5c717 -1 721 -1 734 -9c7 -5 15 -14 20 -21c8 -13 8 -16 8 -739s0 -726 -8 -739c-5 -7 -13 -15 -20 -20c-13 -8 -16 -8 -739 -8s-726 0 -739 8c-7 5 -16 13 -21 20c-8 13 -8 16 -9 731c0 490 0 723 3 733c5 19 18 33 36 39zM404 935
+c-18 4 -53 6 -119 6h-93v-603h84c46 0 96 1 111 3c72 9 131 63 144 132c5 26 5 306 0 332c-6 31 -20 59 -43 83c-25 26 -50 40 -84 47zM897 886v55h-118c-92 0 -121 -2 -133 -6c-20 -7 -42 -30 -47 -50c-3 -11 -4 -89 -3 -254c1 -265 -1 -250 27 -274c20 -17 39 -19 163 -19
+h111v109l-95 1l-96 1l-1 69v69h116v109h-116v136h192v54zM1081 933c-3 8 -4 8 -62 8h-59l3 -10c26 -106 136 -514 143 -528c11 -23 33 -49 49 -57c18 -9 47 -7 67 4c16 9 45 45 50 62c8 25 138 522 138 525s-16 4 -60 3l-58 -1l-52 -198c-28 -109 -52 -199 -53 -202
+s-24 83 -52 190s-52 199 -54 204zM301 639v193l41 -1c37 -2 42 -2 56 -11c28 -18 27 -18 27 -178c0 -164 0 -166 -29 -183c-15 -9 -22 -10 -56 -11l-39 -2v193z" />
+ <glyph glyph-name="stethoscope" unicode="&#xf0f1;" horiz-adv-x="1408"
+d="M1280 832c0 35 -29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64s64 29 64 64zM1408 832c0 -84 -53 -154 -128 -181v-395c0 -212 -201 -384 -448 -384s-448 172 -448 384v132c-217 27 -384 187 -384 380v512c0 35 29 64 64 64c6 0 11 -1 16 -2c22 39 64 66 112 66
+c71 0 128 -57 128 -128s-57 -128 -128 -128c-23 0 -45 7 -64 18v-402c0 -141 144 -256 320 -256s320 115 320 256v402c-19 -11 -41 -18 -64 -18c-71 0 -128 57 -128 128s57 128 128 128c48 0 90 -27 112 -66c5 1 10 2 16 2c35 0 64 -29 64 -64v-512
+c0 -193 -167 -353 -384 -380v-132c0 -141 144 -256 320 -256s320 115 320 256v395c-75 27 -128 97 -128 181c0 106 86 192 192 192s192 -86 192 -192z" />
+ <glyph glyph-name="step-forward" unicode="&#xf051;" horiz-adv-x="1024"
+d="M45 -115c-25 -25 -45 -16 -45 19v1472c0 35 20 44 45 19l710 -710c6 -6 10 -12 13 -19v678c0 35 29 64 64 64h128c35 0 64 -29 64 -64v-1408c0 -35 -29 -64 -64 -64h-128c-35 0 -64 29 -64 64v678c-3 -7 -7 -13 -13 -19z" />
+ <glyph glyph-name="backward" unicode="&#xf04a;" horiz-adv-x="1542"
+d="M1497 1395c25 25 45 16 45 -19v-1472c0 -35 -20 -44 -45 -19l-710 710c-6 6 -10 12 -13 19v-710c0 -35 -20 -44 -45 -19l-710 710c-25 25 -25 65 0 90l710 710c25 25 45 16 45 -19v-710c3 7 7 13 13 19z" />
+ </font>
+</defs></svg>
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.e182ad6df04f9177b326.eot b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.e182ad6df04f9177b326.eot
new file mode 100644
index 000000000..b96d208fa
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.e182ad6df04f9177b326.eot
Binary files differ
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.ee4d8bfd0af89fc714a2.ttf b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.ee4d8bfd0af89fc714a2.ttf
new file mode 100644
index 000000000..6cf62efb8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.ee4d8bfd0af89fc714a2.ttf
Binary files differ
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/index.html b/src/pybind/mgr/dashboard/frontend/dist/en-US/index.html
new file mode 100644
index 000000000..75c21411f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/index.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html><html lang="en-US"><head>
+ <meta charset="utf-8">
+ <title>Ceph</title>
+
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+ <link rel="icon" type="image/x-icon" id="cdFavicon" href="favicon.ico">
+<style>@charset "UTF-8";:root{--gray-100:#f8f9fa;--gray-200:#e9ecef;--gray-300:#dee2e6;--gray-400:#ced4da;--gray-500:#adb5bd;--gray-600:#6c757d;--gray-700:#495057;--gray-800:#343a40;--gray-900:#212529;--black:#000;--barley-white:#fcecba;--fg-color-over-dark-bg:#fff;--fg-hover-color-over-dark-bg:#adb5bd;--body-color-bright:#f8f9fa;--body-bg:#fff;--body-color:#212529;--body-bg-alt:#e9ecef;--health-color-error:red;--health-color-healthy:#0b0;--health-color-warning:orange;--chart-color-red:#c9190b;--chart-color-blue:#06c;--chart-color-orange:#ef9234;--chart-color-yellow:#f6d173;--chart-color-green:#7cc674;--chart-color-gray:#ededed;--chart-color-cyan:#73c5c5;--chart-color-purple:#3c3d99;--chart-color-center-text:#151515;--chart-color-center-text-description:#72767b;--chart-color-tooltip-background:#000;--chart-danger:#c9190b;--card-cap-bg:#f8f9fa;--grid-gutter-width:30px;--datatable-divider-color:#00000017;--nav-tabs-margin-bottom:1rem;--tooltip-color:#fff;--tooltip-bg:#212529;--screen-sm-min:576px;--screen-md-min:768px;--screen-lg-min:992px;--screen-xl-min:1200px;--screen-xs-max:calc(576px - 1px);--screen-sm-max:calc(768px - 1px);--screen-md-max:calc(992px - 1px);--screen-lg-max:calc(1200px - 1px);--navbar-height:43px;--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#a94442;--red:#ef5c55;--orange:#fd7e14;--yellow:#ffc200;--green:#0b0;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#2b99a8;--secondary:#374249;--success:#0b0;--info:#2b99a8;--warning:#ffc200;--danger:#ef5c55;--light:#f8f9fa;--dark:#777;--accent:#ef5c55;--warning-dark:#fd7e14;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--breakpoint-2xl:1450px;--font-family-sans-serif:"Helvetica Neue",Helvetica,Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,:after,:before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{margin:0;font-family:Helvetica Neue,Helvetica,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}@media print{*,:after,:before{text-shadow:none!important;box-shadow:none!important}@page{size:a3}body{min-width:992px!important}}html{background-color:#fff}body,html{font-size:12px;height:100%;width:100%}</style><link rel="stylesheet" href="styles.f05c06a6a64f4730faae.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.f05c06a6a64f4730faae.css"></noscript></head>
+<body>
+ <noscript>
+ <div class="noscript container"
+ ng-if="false">
+ <div class="jumbotron alert alert-danger">
+ <h2 i18n>JavaScript required!</h2>
+ <p i18n>A browser with JavaScript enabled is required in order to use this service.</p>
+ <p i18n>When using Internet Explorer, please check your security settings and add this address to your trusted sites.</p>
+ </div>
+ </div>
+ </noscript>
+
+ <cd-root></cd-root>
+<script src="runtime.dfeb6a20b4d203b567dc.js" defer></script><script src="polyfills.2068f3f22a496426465b.js" defer></script><script src="scripts.6bda3fa7e09a87cd4228.js" defer></script><script src="main.c3b711a3156fe72f66f4.js" defer></script>
+
+</body></html> \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/main.c3b711a3156fe72f66f4.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/main.c3b711a3156fe72f66f4.js
new file mode 100644
index 000000000..0933ce611
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/main.c3b711a3156fe72f66f4.js
@@ -0,0 +1,3 @@
+var $localize=Object.assign(void 0===$localize?{}:$localize,{locale:"en-US"});
+"use strict";(function(global){global.ng=global.ng||{};global.ng.common=global.ng.common||{};global.ng.common.locales=global.ng.common.locales||{};const u=undefined;function plural(n){const i=Math.floor(Math.abs(n)),v=n.toString().replace(/^[^.]*\.?/,"").length;if(i===1&&v===0)return 1;return 5}global.ng.common.locales["en-us-posix"]=["en-US-POSIX",[["a","p"],["AM","PM"],u],[["AM","PM"],u,u],[["S","M","T","W","T","F","S"],["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],["Su","Mo","Tu","We","Th","Fr","Sa"]],u,[["J","F","M","A","M","J","J","A","S","O","N","D"],["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],["January","February","March","April","May","June","July","August","September","October","November","December"]],u,[["B","A"],["BC","AD"],["Before Christ","Anno Domini"]],0,[6,0],["M/d/yy","MMM d, y","MMMM d, y","EEEE, MMMM d, y"],["h:mm a","h:mm:ss a","h:mm:ss a z","h:mm:ss a zzzz"],["{1}, {0}",u,"{1} 'at' {0}",u],[".",",",";","%","+","-","E","\xD7","0/00","INF","NaN",":"],["0.######","0%","\xA4\xA00.00","0.000000E+000"],"USD","$","US Dollar",{},"ltr",plural,[[["mi","n","in the morning","in the afternoon","in the evening","at night"],["midnight","noon","in the morning","in the afternoon","in the evening","at night"],u],[["midnight","noon","morning","afternoon","evening","night"],u,u],["00:00","12:00",["06:00","12:00"],["12:00","18:00"],["18:00","21:00"],["21:00","06:00"]]]]})(typeof globalThis!=="undefined"&&globalThis||typeof global!=="undefined"&&global||typeof window!=="undefined"&&window);;
+var vm=Math.pow;(self.webpackChunkceph_dashboard=self.webpackChunkceph_dashboard||[]).push([[179],{98255:v=>{function T(i){return Promise.resolve().then(()=>{var r=new Error("Cannot find module '"+i+"'");throw r.code="MODULE_NOT_FOUND",r})}T.keys=()=>[],T.resolve=T,T.id=98255,v.exports=T},56083:(v,T,i)=>{"use strict";i.d(T,{l3:()=>p,_j:()=>r,LC:()=>u,ZN:()=>H,jt:()=>e,vP:()=>y,SB:()=>A,oB:()=>S,eR:()=>L,X$:()=>d,ZE:()=>se,k1:()=>Ee});class r{}class u{}const p="*";function d(ie,he){return{type:7,name:ie,definitions:he,options:{}}}function e(ie,he=null){return{type:4,styles:he,timings:ie}}function y(ie,he=null){return{type:2,steps:ie,options:he}}function S(ie){return{type:6,styles:ie,offset:null}}function A(ie,he,ge){return{type:0,name:ie,styles:he,options:ge}}function L(ie,he,ge=null){return{type:1,expr:ie,animation:he,options:ge}}function ae(ie){Promise.resolve(null).then(ie)}class H{constructor(he=0,ge=0){this._onDoneFns=[],this._onStartFns=[],this._onDestroyFns=[],this._started=!1,this._destroyed=!1,this._finished=!1,this._position=0,this.parentPlayer=null,this.totalTime=he+ge}_onFinish(){this._finished||(this._finished=!0,this._onDoneFns.forEach(he=>he()),this._onDoneFns=[])}onStart(he){this._onStartFns.push(he)}onDone(he){this._onDoneFns.push(he)}onDestroy(he){this._onDestroyFns.push(he)}hasStarted(){return this._started}init(){}play(){this.hasStarted()||(this._onStart(),this.triggerMicrotask()),this._started=!0}triggerMicrotask(){ae(()=>this._onFinish())}_onStart(){this._onStartFns.forEach(he=>he()),this._onStartFns=[]}pause(){}restart(){}finish(){this._onFinish()}destroy(){this._destroyed||(this._destroyed=!0,this.hasStarted()||this._onStart(),this.finish(),this._onDestroyFns.forEach(he=>he()),this._onDestroyFns=[])}reset(){this._started=!1}setPosition(he){this._position=this.totalTime?he*this.totalTime:1}getPosition(){return this.totalTime?this._position/this.totalTime:1}triggerCallback(he){const ge="start"==he?this._onStartFns:this._onDoneFns;ge.forEach(De=>De()),ge.length=0}}class se{constructor(he){this._onDoneFns=[],this._onStartFns=[],this._finished=!1,this._started=!1,this._destroyed=!1,this._onDestroyFns=[],this.parentPlayer=null,this.totalTime=0,this.players=he;let ge=0,De=0,ce=0;const lt=this.players.length;0==lt?ae(()=>this._onFinish()):this.players.forEach(Ve=>{Ve.onDone(()=>{++ge==lt&&this._onFinish()}),Ve.onDestroy(()=>{++De==lt&&this._onDestroy()}),Ve.onStart(()=>{++ce==lt&&this._onStart()})}),this.totalTime=this.players.reduce((Ve,ze)=>Math.max(Ve,ze.totalTime),0)}_onFinish(){this._finished||(this._finished=!0,this._onDoneFns.forEach(he=>he()),this._onDoneFns=[])}init(){this.players.forEach(he=>he.init())}onStart(he){this._onStartFns.push(he)}_onStart(){this.hasStarted()||(this._started=!0,this._onStartFns.forEach(he=>he()),this._onStartFns=[])}onDone(he){this._onDoneFns.push(he)}onDestroy(he){this._onDestroyFns.push(he)}hasStarted(){return this._started}play(){this.parentPlayer||this.init(),this._onStart(),this.players.forEach(he=>he.play())}pause(){this.players.forEach(he=>he.pause())}restart(){this.players.forEach(he=>he.restart())}finish(){this._onFinish(),this.players.forEach(he=>he.finish())}destroy(){this._onDestroy()}_onDestroy(){this._destroyed||(this._destroyed=!0,this._onFinish(),this.players.forEach(he=>he.destroy()),this._onDestroyFns.forEach(he=>he()),this._onDestroyFns=[])}reset(){this.players.forEach(he=>he.reset()),this._destroyed=!1,this._finished=!1,this._started=!1}setPosition(he){const ge=he*this.totalTime;this.players.forEach(De=>{const ce=De.totalTime?Math.min(1,ge/De.totalTime):1;De.setPosition(ce)})}getPosition(){const he=this.players.reduce((ge,De)=>null===ge||De.totalTime>ge.totalTime?De:ge,null);return null!=he?he.getPosition():0}beforeDestroy(){this.players.forEach(he=>{he.beforeDestroy&&he.beforeDestroy()})}triggerCallback(he){const ge="start"==he?this._onStartFns:this._onDoneFns;ge.forEach(De=>De()),ge.length=0}}const Ee="!"},12057:(v,T,i)=>{"use strict";i.d(T,{mr:()=>se,Ov:()=>Ws,ez:()=>Eo,K0:()=>y,uU:()=>So,JJ:()=>an,x:()=>Be,Do:()=>ie,Gx:()=>to,Ts:()=>sn,Nd:()=>$e,V_:()=>N,Ye:()=>he,S$:()=>ae,i8:()=>Po,mk:()=>si,sg:()=>co,O5:()=>ls,PC:()=>Il,RF:()=>us,n9:()=>ya,ED:()=>el,tP:()=>fo,b0:()=>Ee,Zx:()=>ti,lw:()=>S,rS:()=>Ls,Tn:()=>Pe,gd:()=>ps,EM:()=>Fs,JF:()=>Zl,p6:()=>_i,Mn:()=>It,ol:()=>tn,UT:()=>Zt,NF:()=>bc,w_:()=>_,bD:()=>ba,q:()=>p,Mx:()=>on,HT:()=>e});var r=i(74788);let u=null;function p(){return u}function e(rt){u||(u=rt)}class _{}const y=new r.OlP("DocumentToken");let S=(()=>{class rt{historyGo(dt){throw new Error("Not implemented")}}return rt.\u0275fac=function(dt){return new(dt||rt)},rt.\u0275prov=(0,r.Yz7)({factory:A,token:rt,providedIn:"platform"}),rt})();function A(){return(0,r.LFG)(L)}const N=new r.OlP("Location Initialized");let L=(()=>{class rt extends S{constructor(dt){super(),this._doc=dt,this._init()}_init(){this.location=window.location,this._history=window.history}getBaseHrefFromDOM(){return p().getBaseHref(this._doc)}onPopState(dt){const Te=p().getGlobalEventTarget(this._doc,"window");return Te.addEventListener("popstate",dt,!1),()=>Te.removeEventListener("popstate",dt)}onHashChange(dt){const Te=p().getGlobalEventTarget(this._doc,"window");return Te.addEventListener("hashchange",dt,!1),()=>Te.removeEventListener("hashchange",dt)}get href(){return this.location.href}get protocol(){return this.location.protocol}get hostname(){return this.location.hostname}get port(){return this.location.port}get pathname(){return this.location.pathname}get search(){return this.location.search}get hash(){return this.location.hash}set pathname(dt){this.location.pathname=dt}pushState(dt,Te,Me){Z()?this._history.pushState(dt,Te,Me):this.location.hash=Me}replaceState(dt,Te,Me){Z()?this._history.replaceState(dt,Te,Me):this.location.hash=Me}forward(){this._history.forward()}back(){this._history.back()}historyGo(dt=0){this._history.go(dt)}getState(){return this._history.state}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.LFG(y))},rt.\u0275prov=(0,r.Yz7)({factory:J,token:rt,providedIn:"platform"}),rt})();function Z(){return!!window.history.pushState}function J(){return new L((0,r.LFG)(y))}function K(rt,Pt){if(0==rt.length)return Pt;if(0==Pt.length)return rt;let dt=0;return rt.endsWith("/")&&dt++,Pt.startsWith("/")&&dt++,2==dt?rt+Pt.substring(1):1==dt?rt+Pt:rt+"/"+Pt}function ee(rt){const Pt=rt.match(/#|\?|$/),dt=Pt&&Pt.index||rt.length;return rt.slice(0,dt-("/"===rt[dt-1]?1:0))+rt.slice(dt)}function ue(rt){return rt&&"?"!==rt[0]?"?"+rt:rt}let ae=(()=>{class rt{historyGo(dt){throw new Error("Not implemented")}}return rt.\u0275fac=function(dt){return new(dt||rt)},rt.\u0275prov=(0,r.Yz7)({factory:H,token:rt,providedIn:"root"}),rt})();function H(rt){const Pt=(0,r.LFG)(y).location;return new Ee((0,r.LFG)(S),Pt&&Pt.origin||"")}const se=new r.OlP("appBaseHref");let Ee=(()=>{class rt extends ae{constructor(dt,Te){if(super(),this._platformLocation=dt,this._removeListenerFns=[],null==Te&&(Te=this._platformLocation.getBaseHrefFromDOM()),null==Te)throw new Error("No base href set. Please provide a value for the APP_BASE_HREF token or add a base element to the document.");this._baseHref=Te}ngOnDestroy(){for(;this._removeListenerFns.length;)this._removeListenerFns.pop()()}onPopState(dt){this._removeListenerFns.push(this._platformLocation.onPopState(dt),this._platformLocation.onHashChange(dt))}getBaseHref(){return this._baseHref}prepareExternalUrl(dt){return K(this._baseHref,dt)}path(dt=!1){const Te=this._platformLocation.pathname+ue(this._platformLocation.search),Me=this._platformLocation.hash;return Me&&dt?`${Te}${Me}`:Te}pushState(dt,Te,Me,xe){const Ct=this.prepareExternalUrl(Me+ue(xe));this._platformLocation.pushState(dt,Te,Ct)}replaceState(dt,Te,Me,xe){const Ct=this.prepareExternalUrl(Me+ue(xe));this._platformLocation.replaceState(dt,Te,Ct)}forward(){this._platformLocation.forward()}back(){this._platformLocation.back()}historyGo(dt=0){var Te,Me;null===(Me=(Te=this._platformLocation).historyGo)||void 0===Me||Me.call(Te,dt)}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.LFG(S),r.LFG(se,8))},rt.\u0275prov=r.Yz7({token:rt,factory:rt.\u0275fac}),rt})(),ie=(()=>{class rt extends ae{constructor(dt,Te){super(),this._platformLocation=dt,this._baseHref="",this._removeListenerFns=[],null!=Te&&(this._baseHref=Te)}ngOnDestroy(){for(;this._removeListenerFns.length;)this._removeListenerFns.pop()()}onPopState(dt){this._removeListenerFns.push(this._platformLocation.onPopState(dt),this._platformLocation.onHashChange(dt))}getBaseHref(){return this._baseHref}path(dt=!1){let Te=this._platformLocation.hash;return null==Te&&(Te="#"),Te.length>0?Te.substring(1):Te}prepareExternalUrl(dt){const Te=K(this._baseHref,dt);return Te.length>0?"#"+Te:Te}pushState(dt,Te,Me,xe){let Ct=this.prepareExternalUrl(Me+ue(xe));0==Ct.length&&(Ct=this._platformLocation.pathname),this._platformLocation.pushState(dt,Te,Ct)}replaceState(dt,Te,Me,xe){let Ct=this.prepareExternalUrl(Me+ue(xe));0==Ct.length&&(Ct=this._platformLocation.pathname),this._platformLocation.replaceState(dt,Te,Ct)}forward(){this._platformLocation.forward()}back(){this._platformLocation.back()}historyGo(dt=0){var Te,Me;null===(Me=(Te=this._platformLocation).historyGo)||void 0===Me||Me.call(Te,dt)}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.LFG(S),r.LFG(se,8))},rt.\u0275prov=r.Yz7({token:rt,factory:rt.\u0275fac}),rt})(),he=(()=>{class rt{constructor(dt,Te){this._subject=new r.vpe,this._urlChangeListeners=[],this._platformStrategy=dt;const Me=this._platformStrategy.getBaseHref();this._platformLocation=Te,this._baseHref=ee(ce(Me)),this._platformStrategy.onPopState(xe=>{this._subject.emit({url:this.path(!0),pop:!0,state:xe.state,type:xe.type})})}path(dt=!1){return this.normalize(this._platformStrategy.path(dt))}getState(){return this._platformLocation.getState()}isCurrentPathEqualTo(dt,Te=""){return this.path()==this.normalize(dt+ue(Te))}normalize(dt){return rt.stripTrailingSlash(function(rt,Pt){return rt&&Pt.startsWith(rt)?Pt.substring(rt.length):Pt}(this._baseHref,ce(dt)))}prepareExternalUrl(dt){return dt&&"/"!==dt[0]&&(dt="/"+dt),this._platformStrategy.prepareExternalUrl(dt)}go(dt,Te="",Me=null){this._platformStrategy.pushState(Me,"",dt,Te),this._notifyUrlChangeListeners(this.prepareExternalUrl(dt+ue(Te)),Me)}replaceState(dt,Te="",Me=null){this._platformStrategy.replaceState(Me,"",dt,Te),this._notifyUrlChangeListeners(this.prepareExternalUrl(dt+ue(Te)),Me)}forward(){this._platformStrategy.forward()}back(){this._platformStrategy.back()}historyGo(dt=0){var Te,Me;null===(Me=(Te=this._platformStrategy).historyGo)||void 0===Me||Me.call(Te,dt)}onUrlChange(dt){this._urlChangeListeners.push(dt),this._urlChangeSubscription||(this._urlChangeSubscription=this.subscribe(Te=>{this._notifyUrlChangeListeners(Te.url,Te.state)}))}_notifyUrlChangeListeners(dt="",Te){this._urlChangeListeners.forEach(Me=>Me(dt,Te))}subscribe(dt,Te,Me){return this._subject.subscribe({next:dt,error:Te,complete:Me})}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.LFG(ae),r.LFG(S))},rt.normalizeQueryParams=ue,rt.joinWithSlash=K,rt.stripTrailingSlash=ee,rt.\u0275prov=(0,r.Yz7)({factory:ge,token:rt,providedIn:"root"}),rt})();function ge(){return new he((0,r.LFG)(ae),(0,r.LFG)(S))}function ce(rt){return rt.replace(/\/index.html$/,"")}var Ve=(()=>((Ve=Ve||{})[Ve.Decimal=0]="Decimal",Ve[Ve.Percent=1]="Percent",Ve[Ve.Currency=2]="Currency",Ve[Ve.Scientific=3]="Scientific",Ve))(),ze=(()=>((ze=ze||{})[ze.Zero=0]="Zero",ze[ze.One=1]="One",ze[ze.Two=2]="Two",ze[ze.Few=3]="Few",ze[ze.Many=4]="Many",ze[ze.Other=5]="Other",ze))(),Be=(()=>((Be=Be||{})[Be.Format=0]="Format",Be[Be.Standalone=1]="Standalone",Be))(),Pe=(()=>((Pe=Pe||{})[Pe.Narrow=0]="Narrow",Pe[Pe.Abbreviated=1]="Abbreviated",Pe[Pe.Wide=2]="Wide",Pe[Pe.Short=3]="Short",Pe))(),je=(()=>((je=je||{})[je.Short=0]="Short",je[je.Medium=1]="Medium",je[je.Long=2]="Long",je[je.Full=3]="Full",je))(),He=(()=>((He=He||{})[He.Decimal=0]="Decimal",He[He.Group=1]="Group",He[He.List=2]="List",He[He.PercentSign=3]="PercentSign",He[He.PlusSign=4]="PlusSign",He[He.MinusSign=5]="MinusSign",He[He.Exponential=6]="Exponential",He[He.SuperscriptingExponent=7]="SuperscriptingExponent",He[He.PerMille=8]="PerMille",He[He.Infinity=9]="Infinity",He[He.NaN=10]="NaN",He[He.TimeSeparator=11]="TimeSeparator",He[He.CurrencyDecimal=12]="CurrencyDecimal",He[He.CurrencyGroup=13]="CurrencyGroup",He))();function tn(rt,Pt,dt){const Te=(0,r.cg1)(rt),xe=fi([Te[r.wAp.DayPeriodsFormat],Te[r.wAp.DayPeriodsStandalone]],Pt);return fi(xe,dt)}function It(rt,Pt,dt){const Te=(0,r.cg1)(rt),xe=fi([Te[r.wAp.DaysFormat],Te[r.wAp.DaysStandalone]],Pt);return fi(xe,dt)}function Zt(rt,Pt,dt){const Te=(0,r.cg1)(rt),xe=fi([Te[r.wAp.MonthsFormat],Te[r.wAp.MonthsStandalone]],Pt);return fi(xe,dt)}function Gt(rt,Pt){return fi((0,r.cg1)(rt)[r.wAp.DateFormat],Pt)}function xt(rt,Pt){return fi((0,r.cg1)(rt)[r.wAp.TimeFormat],Pt)}function Xt(rt,Pt){return fi((0,r.cg1)(rt)[r.wAp.DateTimeFormat],Pt)}function Zn(rt,Pt){const dt=(0,r.cg1)(rt),Te=dt[r.wAp.NumberSymbols][Pt];if(void 0===Te){if(Pt===He.CurrencyDecimal)return dt[r.wAp.NumberSymbols][He.Decimal];if(Pt===He.CurrencyGroup)return dt[r.wAp.NumberSymbols][He.Group]}return Te}function Ur(rt,Pt){return(0,r.cg1)(rt)[r.wAp.NumberFormats][Pt]}const ei=r.kL8;function Nn(rt){if(!rt[r.wAp.ExtraData])throw new Error(`Missing extra locale data for the locale "${rt[r.wAp.LocaleId]}". Use "registerLocaleData" to load new data. See the "I18n guide" on angular.io to know more.`)}function fi(rt,Pt){for(let dt=Pt;dt>-1;dt--)if(void 0!==rt[dt])return rt[dt];throw new Error("Locale data API: locale data undefined")}function ki(rt){const[Pt,dt]=rt.split(":");return{hours:+Pt,minutes:+dt}}const Wt=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/,zn={},rr=/((?:[^BEGHLMOSWYZabcdhmswyz']+)|(?:'(?:[^']|'')*')|(?:G{1,5}|y{1,4}|Y{1,4}|M{1,5}|L{1,5}|w{1,2}|W{1}|d{1,2}|E{1,6}|c{1,6}|a{1,5}|b{1,5}|B{1,5}|h{1,2}|H{1,2}|m{1,2}|s{1,2}|S{1,3}|z{1,4}|Z{1,5}|O{1,4}))([\s\S]*)/;var Fr=(()=>((Fr=Fr||{})[Fr.Short=0]="Short",Fr[Fr.ShortGMT=1]="ShortGMT",Fr[Fr.Long=2]="Long",Fr[Fr.Extended=3]="Extended",Fr))(),Gn=(()=>((Gn=Gn||{})[Gn.FullYear=0]="FullYear",Gn[Gn.Month=1]="Month",Gn[Gn.Date=2]="Date",Gn[Gn.Hours=3]="Hours",Gn[Gn.Minutes=4]="Minutes",Gn[Gn.Seconds=5]="Seconds",Gn[Gn.FractionalSeconds=6]="FractionalSeconds",Gn[Gn.Day=7]="Day",Gn))(),Jr=(()=>((Jr=Jr||{})[Jr.DayPeriods=0]="DayPeriods",Jr[Jr.Days=1]="Days",Jr[Jr.Months=2]="Months",Jr[Jr.Eras=3]="Eras",Jr))();function _i(rt,Pt,dt,Te){let Me=function(rt){if(lo(rt))return rt;if("number"==typeof rt&&!isNaN(rt))return new Date(rt);if("string"==typeof rt){if(rt=rt.trim(),/^(\d{4}(-\d{1,2}(-\d{1,2})?)?)$/.test(rt)){const[Me,xe=1,Ct=1]=rt.split("-").map(ur=>+ur);return wi(Me,xe-1,Ct)}const dt=parseFloat(rt);if(!isNaN(rt-dt))return new Date(dt);let Te;if(Te=rt.match(Wt))return function(rt){const Pt=new Date(0);let dt=0,Te=0;const Me=rt[8]?Pt.setUTCFullYear:Pt.setFullYear,xe=rt[8]?Pt.setUTCHours:Pt.setHours;rt[9]&&(dt=Number(rt[9]+rt[10]),Te=Number(rt[9]+rt[11])),Me.call(Pt,Number(rt[1]),Number(rt[2])-1,Number(rt[3]));const Ct=Number(rt[4]||0)-dt,ur=Number(rt[5]||0)-Te,Qi=Number(rt[6]||0),Go=Math.floor(1e3*parseFloat("0."+(rt[7]||0)));return xe.call(Pt,Ct,ur,Qi,Go),Pt}(Te)}const Pt=new Date(rt);if(!lo(Pt))throw new Error(`Unable to convert "${rt}" into a date`);return Pt}(rt);Pt=br(dt,Pt)||Pt;let ur,Ct=[];for(;Pt;){if(ur=rr.exec(Pt),!ur){Ct.push(Pt);break}{Ct=Ct.concat(ur.slice(1));const ms=Ct.pop();if(!ms)break;Pt=ms}}let Qi=Me.getTimezoneOffset();Te&&(Qi=Wr(Te,Qi),Me=function(rt,Pt,dt){const Me=rt.getTimezoneOffset();return function(rt,Pt){return(rt=new Date(rt.getTime())).setMinutes(rt.getMinutes()+Pt),rt}(rt,-1*(Wr(Pt,Me)-Me))}(Me,Te));let Go="";return Ct.forEach(ms=>{const hs=function(rt){if(An[rt])return An[rt];let Pt;switch(rt){case"G":case"GG":case"GGG":Pt=Vn(Jr.Eras,Pe.Abbreviated);break;case"GGGG":Pt=Vn(Jr.Eras,Pe.Wide);break;case"GGGGG":Pt=Vn(Jr.Eras,Pe.Narrow);break;case"y":Pt=gr(Gn.FullYear,1,0,!1,!0);break;case"yy":Pt=gr(Gn.FullYear,2,0,!0,!0);break;case"yyy":Pt=gr(Gn.FullYear,3,0,!1,!0);break;case"yyyy":Pt=gr(Gn.FullYear,4,0,!1,!0);break;case"Y":Pt=mi(1);break;case"YY":Pt=mi(2,!0);break;case"YYY":Pt=mi(3);break;case"YYYY":Pt=mi(4);break;case"M":case"L":Pt=gr(Gn.Month,1,1);break;case"MM":case"LL":Pt=gr(Gn.Month,2,1);break;case"MMM":Pt=Vn(Jr.Months,Pe.Abbreviated);break;case"MMMM":Pt=Vn(Jr.Months,Pe.Wide);break;case"MMMMM":Pt=Vn(Jr.Months,Pe.Narrow);break;case"LLL":Pt=Vn(Jr.Months,Pe.Abbreviated,Be.Standalone);break;case"LLLL":Pt=Vn(Jr.Months,Pe.Wide,Be.Standalone);break;case"LLLLL":Pt=Vn(Jr.Months,Pe.Narrow,Be.Standalone);break;case"w":Pt=kr(1);break;case"ww":Pt=kr(2);break;case"W":Pt=kr(1,!0);break;case"d":Pt=gr(Gn.Date,1);break;case"dd":Pt=gr(Gn.Date,2);break;case"c":case"cc":Pt=gr(Gn.Day,1);break;case"ccc":Pt=Vn(Jr.Days,Pe.Abbreviated,Be.Standalone);break;case"cccc":Pt=Vn(Jr.Days,Pe.Wide,Be.Standalone);break;case"ccccc":Pt=Vn(Jr.Days,Pe.Narrow,Be.Standalone);break;case"cccccc":Pt=Vn(Jr.Days,Pe.Short,Be.Standalone);break;case"E":case"EE":case"EEE":Pt=Vn(Jr.Days,Pe.Abbreviated);break;case"EEEE":Pt=Vn(Jr.Days,Pe.Wide);break;case"EEEEE":Pt=Vn(Jr.Days,Pe.Narrow);break;case"EEEEEE":Pt=Vn(Jr.Days,Pe.Short);break;case"a":case"aa":case"aaa":Pt=Vn(Jr.DayPeriods,Pe.Abbreviated);break;case"aaaa":Pt=Vn(Jr.DayPeriods,Pe.Wide);break;case"aaaaa":Pt=Vn(Jr.DayPeriods,Pe.Narrow);break;case"b":case"bb":case"bbb":Pt=Vn(Jr.DayPeriods,Pe.Abbreviated,Be.Standalone,!0);break;case"bbbb":Pt=Vn(Jr.DayPeriods,Pe.Wide,Be.Standalone,!0);break;case"bbbbb":Pt=Vn(Jr.DayPeriods,Pe.Narrow,Be.Standalone,!0);break;case"B":case"BB":case"BBB":Pt=Vn(Jr.DayPeriods,Pe.Abbreviated,Be.Format,!0);break;case"BBBB":Pt=Vn(Jr.DayPeriods,Pe.Wide,Be.Format,!0);break;case"BBBBB":Pt=Vn(Jr.DayPeriods,Pe.Narrow,Be.Format,!0);break;case"h":Pt=gr(Gn.Hours,1,-12);break;case"hh":Pt=gr(Gn.Hours,2,-12);break;case"H":Pt=gr(Gn.Hours,1);break;case"HH":Pt=gr(Gn.Hours,2);break;case"m":Pt=gr(Gn.Minutes,1);break;case"mm":Pt=gr(Gn.Minutes,2);break;case"s":Pt=gr(Gn.Seconds,1);break;case"ss":Pt=gr(Gn.Seconds,2);break;case"S":Pt=gr(Gn.FractionalSeconds,1);break;case"SS":Pt=gr(Gn.FractionalSeconds,2);break;case"SSS":Pt=gr(Gn.FractionalSeconds,3);break;case"Z":case"ZZ":case"ZZZ":Pt=Dn(Fr.Short);break;case"ZZZZZ":Pt=Dn(Fr.Extended);break;case"O":case"OO":case"OOO":case"z":case"zz":case"zzz":Pt=Dn(Fr.ShortGMT);break;case"OOOO":case"ZZZZ":case"zzzz":Pt=Dn(Fr.Long);break;default:return null}return An[rt]=Pt,Pt}(ms);Go+=hs?hs(Me,dt,Qi):"''"===ms?"'":ms.replace(/(^'|'$)/g,"").replace(/''/g,"'")}),Go}function wi(rt,Pt,dt){const Te=new Date(0);return Te.setFullYear(rt,Pt,dt),Te.setHours(0,0,0),Te}function br(rt,Pt){const dt=function(rt){return(0,r.cg1)(rt)[r.wAp.LocaleId]}(rt);if(zn[dt]=zn[dt]||{},zn[dt][Pt])return zn[dt][Pt];let Te="";switch(Pt){case"shortDate":Te=Gt(rt,je.Short);break;case"mediumDate":Te=Gt(rt,je.Medium);break;case"longDate":Te=Gt(rt,je.Long);break;case"fullDate":Te=Gt(rt,je.Full);break;case"shortTime":Te=xt(rt,je.Short);break;case"mediumTime":Te=xt(rt,je.Medium);break;case"longTime":Te=xt(rt,je.Long);break;case"fullTime":Te=xt(rt,je.Full);break;case"short":const Me=br(rt,"shortTime"),xe=br(rt,"shortDate");Te=Dr(Xt(rt,je.Short),[Me,xe]);break;case"medium":const Ct=br(rt,"mediumTime"),ur=br(rt,"mediumDate");Te=Dr(Xt(rt,je.Medium),[Ct,ur]);break;case"long":const Qi=br(rt,"longTime"),Go=br(rt,"longDate");Te=Dr(Xt(rt,je.Long),[Qi,Go]);break;case"full":const ms=br(rt,"fullTime"),hs=br(rt,"fullDate");Te=Dr(Xt(rt,je.Full),[ms,hs])}return Te&&(zn[dt][Pt]=Te),Te}function Dr(rt,Pt){return Pt&&(rt=rt.replace(/\{([^}]+)}/g,function(dt,Te){return null!=Pt&&Te in Pt?Pt[Te]:dt})),rt}function gn(rt,Pt,dt="-",Te,Me){let xe="";(rt<0||Me&&rt<=0)&&(Me?rt=1-rt:(rt=-rt,xe=dt));let Ct=String(rt);for(;Ct.length<Pt;)Ct="0"+Ct;return Te&&(Ct=Ct.substr(Ct.length-Pt)),xe+Ct}function gr(rt,Pt,dt=0,Te=!1,Me=!1){return function(xe,Ct){let ur=function(rt,Pt){switch(rt){case Gn.FullYear:return Pt.getFullYear();case Gn.Month:return Pt.getMonth();case Gn.Date:return Pt.getDate();case Gn.Hours:return Pt.getHours();case Gn.Minutes:return Pt.getMinutes();case Gn.Seconds:return Pt.getSeconds();case Gn.FractionalSeconds:return Pt.getMilliseconds();case Gn.Day:return Pt.getDay();default:throw new Error(`Unknown DateType value "${rt}".`)}}(rt,xe);if((dt>0||ur>-dt)&&(ur+=dt),rt===Gn.Hours)0===ur&&-12===dt&&(ur=12);else if(rt===Gn.FractionalSeconds)return function(rt,Pt){return gn(rt,3).substr(0,Pt)}(ur,Pt);const Qi=Zn(Ct,He.MinusSign);return gn(ur,Pt,Qi,Te,Me)}}function Vn(rt,Pt,dt=Be.Format,Te=!1){return function(Me,xe){return function(rt,Pt,dt,Te,Me,xe){switch(dt){case Jr.Months:return Zt(Pt,Me,Te)[rt.getMonth()];case Jr.Days:return It(Pt,Me,Te)[rt.getDay()];case Jr.DayPeriods:const Ct=rt.getHours(),ur=rt.getMinutes();if(xe){const Go=function(rt){const Pt=(0,r.cg1)(rt);return Nn(Pt),(Pt[r.wAp.ExtraData][2]||[]).map(Te=>"string"==typeof Te?ki(Te):[ki(Te[0]),ki(Te[1])])}(Pt),ms=function(rt,Pt,dt){const Te=(0,r.cg1)(rt);Nn(Te);const xe=fi([Te[r.wAp.ExtraData][0],Te[r.wAp.ExtraData][1]],Pt)||[];return fi(xe,dt)||[]}(Pt,Me,Te),hs=Go.findIndex(Ts=>{if(Array.isArray(Ts)){const[Ma,au]=Ts,Wa=Ct>=Ma.hours&&ur>=Ma.minutes,Rl=Ct<au.hours||Ct===au.hours&&ur<au.minutes;if(Ma.hours<au.hours){if(Wa&&Rl)return!0}else if(Wa||Rl)return!0}else if(Ts.hours===Ct&&Ts.minutes===ur)return!0;return!1});if(-1!==hs)return ms[hs]}return tn(Pt,Me,Te)[Ct<12?0:1];case Jr.Eras:return function(rt,Pt){return fi((0,r.cg1)(rt)[r.wAp.Eras],Pt)}(Pt,Te)[rt.getFullYear()<=0?0:1];default:throw new Error(`unexpected translation type ${dt}`)}}(Me,xe,rt,Pt,dt,Te)}}function Dn(rt){return function(Pt,dt,Te){const Me=-1*Te,xe=Zn(dt,He.MinusSign),Ct=Me>0?Math.floor(Me/60):Math.ceil(Me/60);switch(rt){case Fr.Short:return(Me>=0?"+":"")+gn(Ct,2,xe)+gn(Math.abs(Me%60),2,xe);case Fr.ShortGMT:return"GMT"+(Me>=0?"+":"")+gn(Ct,1,xe);case Fr.Long:return"GMT"+(Me>=0?"+":"")+gn(Ct,2,xe)+":"+gn(Math.abs(Me%60),2,xe);case Fr.Extended:return 0===Te?"Z":(Me>=0?"+":"")+gn(Ct,2,xe)+":"+gn(Math.abs(Me%60),2,xe);default:throw new Error(`Unknown zone width "${rt}"`)}}}function Ge(rt){return wi(rt.getFullYear(),rt.getMonth(),rt.getDate()+(4-rt.getDay()))}function kr(rt,Pt=!1){return function(dt,Te){let Me;if(Pt){const xe=new Date(dt.getFullYear(),dt.getMonth(),1).getDay()-1,Ct=dt.getDate();Me=1+Math.floor((Ct+xe)/7)}else{const xe=Ge(dt),Ct=function(rt){const Pt=wi(rt,0,1).getDay();return wi(rt,0,1+(Pt<=4?4:11)-Pt)}(xe.getFullYear()),ur=xe.getTime()-Ct.getTime();Me=1+Math.round(ur/6048e5)}return gn(Me,rt,Zn(Te,He.MinusSign))}}function mi(rt,Pt=!1){return function(dt,Te){return gn(Ge(dt).getFullYear(),rt,Zn(Te,He.MinusSign),Pt)}}const An={};function Wr(rt,Pt){rt=rt.replace(/:/g,"");const dt=Date.parse("Jan 01, 1970 00:00:00 "+rt)/6e4;return isNaN(dt)?Pt:dt}function lo(rt){return rt instanceof Date&&!isNaN(rt.valueOf())}const vo=/^(\d+)?\.((\d+)(-(\d+))?)?$/;function lr(rt,Pt,dt,Te,Me,xe,Ct=!1){let ur="",Qi=!1;if(isFinite(rt)){let Go=function(rt){let Te,Me,xe,Ct,ur,Pt=Math.abs(rt)+"",dt=0;for((Me=Pt.indexOf("."))>-1&&(Pt=Pt.replace(".","")),(xe=Pt.search(/e/i))>0?(Me<0&&(Me=xe),Me+=+Pt.slice(xe+1),Pt=Pt.substring(0,xe)):Me<0&&(Me=Pt.length),xe=0;"0"===Pt.charAt(xe);xe++);if(xe===(ur=Pt.length))Te=[0],Me=1;else{for(ur--;"0"===Pt.charAt(ur);)ur--;for(Me-=xe,Te=[],Ct=0;xe<=ur;xe++,Ct++)Te[Ct]=Number(Pt.charAt(xe))}return Me>22&&(Te=Te.splice(0,21),dt=Me-1,Me=1),{digits:Te,exponent:dt,integerLen:Me}}(rt);Ct&&(Go=function(rt){if(0===rt.digits[0])return rt;const Pt=rt.digits.length-rt.integerLen;return rt.exponent?rt.exponent+=2:(0===Pt?rt.digits.push(0,0):1===Pt&&rt.digits.push(0),rt.integerLen+=2),rt}(Go));let ms=Pt.minInt,hs=Pt.minFrac,Ts=Pt.maxFrac;if(xe){const Al=xe.match(vo);if(null===Al)throw new Error(`${xe} is not a valid digit info`);const vs=Al[1],Lc=Al[3],Tc=Al[5];null!=vs&&(ms=Ar(vs)),null!=Lc&&(hs=Ar(Lc)),null!=Tc?Ts=Ar(Tc):null!=Lc&&hs>Ts&&(Ts=hs)}!function(rt,Pt,dt){if(Pt>dt)throw new Error(`The minimum number of digits after fraction (${Pt}) is higher than the maximum (${dt}).`);let Te=rt.digits,Me=Te.length-rt.integerLen;const xe=Math.min(Math.max(Pt,Me),dt);let Ct=xe+rt.integerLen,ur=Te[Ct];if(Ct>0){Te.splice(Math.max(rt.integerLen,Ct));for(let hs=Ct;hs<Te.length;hs++)Te[hs]=0}else{Me=Math.max(0,Me),rt.integerLen=1,Te.length=Math.max(1,Ct=xe+1),Te[0]=0;for(let hs=1;hs<Ct;hs++)Te[hs]=0}if(ur>=5)if(Ct-1<0){for(let hs=0;hs>Ct;hs--)Te.unshift(0),rt.integerLen++;Te.unshift(1),rt.integerLen++}else Te[Ct-1]++;for(;Me<Math.max(0,xe);Me++)Te.push(0);let Qi=0!==xe;const Go=Pt+rt.integerLen,ms=Te.reduceRight(function(hs,Ts,Ma,au){return au[Ma]=(Ts+=hs)<10?Ts:Ts-10,Qi&&(0===au[Ma]&&Ma>=Go?au.pop():Qi=!1),Ts>=10?1:0},0);ms&&(Te.unshift(ms),rt.integerLen++)}(Go,hs,Ts);let Ma=Go.digits,au=Go.integerLen;const Wa=Go.exponent;let Rl=[];for(Qi=Ma.every(Al=>!Al);au<ms;au++)Ma.unshift(0);for(;au<0;au++)Ma.unshift(0);au>0?Rl=Ma.splice(au,Ma.length):(Rl=Ma,Ma=[0]);const nc=[];for(Ma.length>=Pt.lgSize&&nc.unshift(Ma.splice(-Pt.lgSize,Ma.length).join(""));Ma.length>Pt.gSize;)nc.unshift(Ma.splice(-Pt.gSize,Ma.length).join(""));Ma.length&&nc.unshift(Ma.join("")),ur=nc.join(Zn(dt,Te)),Rl.length&&(ur+=Zn(dt,Me)+Rl.join("")),Wa&&(ur+=Zn(dt,He.Exponential)+"+"+Wa)}else ur=Zn(dt,He.Infinity);return ur=rt<0&&!Qi?Pt.negPre+ur+Pt.negSuf:Pt.posPre+ur+Pt.posSuf,ur}function uo(rt,Pt="-"){const dt={minInt:1,minFrac:0,maxFrac:0,posPre:"",posSuf:"",negPre:"",negSuf:"",gSize:0,lgSize:0},Te=rt.split(";"),Me=Te[0],xe=Te[1],Ct=-1!==Me.indexOf(".")?Me.split("."):[Me.substring(0,Me.lastIndexOf("0")+1),Me.substring(Me.lastIndexOf("0")+1)],ur=Ct[0],Qi=Ct[1]||"";dt.posPre=ur.substr(0,ur.indexOf("#"));for(let ms=0;ms<Qi.length;ms++){const hs=Qi.charAt(ms);"0"===hs?dt.minFrac=dt.maxFrac=ms+1:"#"===hs?dt.maxFrac=ms+1:dt.posSuf+=hs}const Go=ur.split(",");if(dt.gSize=Go[1]?Go[1].length:0,dt.lgSize=Go[2]||Go[1]?(Go[2]||Go[1]).length:0,xe){const ms=Me.length-dt.posPre.length-dt.posSuf.length,hs=xe.indexOf("#");dt.negPre=xe.substr(0,hs).replace(/'/g,""),dt.negSuf=xe.substr(hs+ms).replace(/'/g,"")}else dt.negPre=Pt+dt.posPre,dt.negSuf=dt.posSuf;return dt}function Ar(rt){const Pt=parseInt(rt);if(isNaN(Pt))throw new Error("Invalid integer literal when parsing "+rt);return Pt}class Rt{}let mt=(()=>{class rt extends Rt{constructor(dt){super(),this.locale=dt}getPluralCategory(dt,Te){switch(ei(Te||this.locale)(dt)){case ze.Zero:return"zero";case ze.One:return"one";case ze.Two:return"two";case ze.Few:return"few";case ze.Many:return"many";default:return"other"}}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.LFG(r.soG))},rt.\u0275prov=r.Yz7({token:rt,factory:rt.\u0275fac}),rt})();function on(rt,Pt){Pt=encodeURIComponent(Pt);for(const dt of rt.split(";")){const Te=dt.indexOf("="),[Me,xe]=-1==Te?[dt,""]:[dt.slice(0,Te),dt.slice(Te+1)];if(Me.trim()===Pt)return decodeURIComponent(xe)}return null}let si=(()=>{class rt{constructor(dt,Te,Me,xe){this._iterableDiffers=dt,this._keyValueDiffers=Te,this._ngEl=Me,this._renderer=xe,this._iterableDiffer=null,this._keyValueDiffer=null,this._initialClasses=[],this._rawClass=null}set klass(dt){this._removeClasses(this._initialClasses),this._initialClasses="string"==typeof dt?dt.split(/\s+/):[],this._applyClasses(this._initialClasses),this._applyClasses(this._rawClass)}set ngClass(dt){this._removeClasses(this._rawClass),this._applyClasses(this._initialClasses),this._iterableDiffer=null,this._keyValueDiffer=null,this._rawClass="string"==typeof dt?dt.split(/\s+/):dt,this._rawClass&&((0,r.sIi)(this._rawClass)?this._iterableDiffer=this._iterableDiffers.find(this._rawClass).create():this._keyValueDiffer=this._keyValueDiffers.find(this._rawClass).create())}ngDoCheck(){if(this._iterableDiffer){const dt=this._iterableDiffer.diff(this._rawClass);dt&&this._applyIterableChanges(dt)}else if(this._keyValueDiffer){const dt=this._keyValueDiffer.diff(this._rawClass);dt&&this._applyKeyValueChanges(dt)}}_applyKeyValueChanges(dt){dt.forEachAddedItem(Te=>this._toggleClass(Te.key,Te.currentValue)),dt.forEachChangedItem(Te=>this._toggleClass(Te.key,Te.currentValue)),dt.forEachRemovedItem(Te=>{Te.previousValue&&this._toggleClass(Te.key,!1)})}_applyIterableChanges(dt){dt.forEachAddedItem(Te=>{if("string"!=typeof Te.item)throw new Error(`NgClass can only toggle CSS classes expressed as strings, got ${(0,r.AaK)(Te.item)}`);this._toggleClass(Te.item,!0)}),dt.forEachRemovedItem(Te=>this._toggleClass(Te.item,!1))}_applyClasses(dt){dt&&(Array.isArray(dt)||dt instanceof Set?dt.forEach(Te=>this._toggleClass(Te,!0)):Object.keys(dt).forEach(Te=>this._toggleClass(Te,!!dt[Te])))}_removeClasses(dt){dt&&(Array.isArray(dt)||dt instanceof Set?dt.forEach(Te=>this._toggleClass(Te,!1)):Object.keys(dt).forEach(Te=>this._toggleClass(Te,!1)))}_toggleClass(dt,Te){(dt=dt.trim())&&dt.split(/\s+/g).forEach(Me=>{Te?this._renderer.addClass(this._ngEl.nativeElement,Me):this._renderer.removeClass(this._ngEl.nativeElement,Me)})}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.Y36(r.ZZ4),r.Y36(r.aQg),r.Y36(r.SBq),r.Y36(r.Qsj))},rt.\u0275dir=r.lG2({type:rt,selectors:[["","ngClass",""]],inputs:{klass:["class","klass"],ngClass:"ngClass"}}),rt})();class _o{constructor(Pt,dt,Te,Me){this.$implicit=Pt,this.ngForOf=dt,this.index=Te,this.count=Me}get first(){return 0===this.index}get last(){return this.index===this.count-1}get even(){return this.index%2==0}get odd(){return!this.even}}let co=(()=>{class rt{constructor(dt,Te,Me){this._viewContainer=dt,this._template=Te,this._differs=Me,this._ngForOf=null,this._ngForOfDirty=!0,this._differ=null}set ngForOf(dt){this._ngForOf=dt,this._ngForOfDirty=!0}set ngForTrackBy(dt){this._trackByFn=dt}get ngForTrackBy(){return this._trackByFn}set ngForTemplate(dt){dt&&(this._template=dt)}ngDoCheck(){if(this._ngForOfDirty){this._ngForOfDirty=!1;const dt=this._ngForOf;if(!this._differ&&dt)try{this._differ=this._differs.find(dt).create(this.ngForTrackBy)}catch(Te){throw new Error(`Cannot find a differ supporting object '${dt}' of type '${function(rt){return rt.name||typeof rt}(dt)}'. NgFor only supports binding to Iterables such as Arrays.`)}}if(this._differ){const dt=this._differ.diff(this._ngForOf);dt&&this._applyChanges(dt)}}_applyChanges(dt){const Te=[];dt.forEachOperation((Me,xe,Ct)=>{if(null==Me.previousIndex){const ur=this._viewContainer.createEmbeddedView(this._template,new _o(null,this._ngForOf,-1,-1),null===Ct?void 0:Ct),Qi=new Es(Me,ur);Te.push(Qi)}else if(null==Ct)this._viewContainer.remove(null===xe?void 0:xe);else if(null!==xe){const ur=this._viewContainer.get(xe);this._viewContainer.move(ur,Ct);const Qi=new Es(Me,ur);Te.push(Qi)}});for(let Me=0;Me<Te.length;Me++)this._perViewChange(Te[Me].view,Te[Me].record);for(let Me=0,xe=this._viewContainer.length;Me<xe;Me++){const Ct=this._viewContainer.get(Me);Ct.context.index=Me,Ct.context.count=xe,Ct.context.ngForOf=this._ngForOf}dt.forEachIdentityChange(Me=>{this._viewContainer.get(Me.currentIndex).context.$implicit=Me.item})}_perViewChange(dt,Te){dt.context.$implicit=Te.item}static ngTemplateContextGuard(dt,Te){return!0}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.Y36(r.s_b),r.Y36(r.Rgc),r.Y36(r.ZZ4))},rt.\u0275dir=r.lG2({type:rt,selectors:[["","ngFor","","ngForOf",""]],inputs:{ngForOf:"ngForOf",ngForTrackBy:"ngForTrackBy",ngForTemplate:"ngForTemplate"}}),rt})();class Es{constructor(Pt,dt){this.record=Pt,this.view=dt}}let ls=(()=>{class rt{constructor(dt,Te){this._viewContainer=dt,this._context=new La,this._thenTemplateRef=null,this._elseTemplateRef=null,this._thenViewRef=null,this._elseViewRef=null,this._thenTemplateRef=Te}set ngIf(dt){this._context.$implicit=this._context.ngIf=dt,this._updateView()}set ngIfThen(dt){ta("ngIfThen",dt),this._thenTemplateRef=dt,this._thenViewRef=null,this._updateView()}set ngIfElse(dt){ta("ngIfElse",dt),this._elseTemplateRef=dt,this._elseViewRef=null,this._updateView()}_updateView(){this._context.$implicit?this._thenViewRef||(this._viewContainer.clear(),this._elseViewRef=null,this._thenTemplateRef&&(this._thenViewRef=this._viewContainer.createEmbeddedView(this._thenTemplateRef,this._context))):this._elseViewRef||(this._viewContainer.clear(),this._thenViewRef=null,this._elseTemplateRef&&(this._elseViewRef=this._viewContainer.createEmbeddedView(this._elseTemplateRef,this._context)))}static ngTemplateContextGuard(dt,Te){return!0}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.Y36(r.s_b),r.Y36(r.Rgc))},rt.\u0275dir=r.lG2({type:rt,selectors:[["","ngIf",""]],inputs:{ngIf:"ngIf",ngIfThen:"ngIfThen",ngIfElse:"ngIfElse"}}),rt})();class La{constructor(){this.$implicit=null,this.ngIf=null}}function ta(rt,Pt){if(Pt&&!Pt.createEmbeddedView)throw new Error(`${rt} must be a TemplateRef, but received '${(0,r.AaK)(Pt)}'.`)}class Is{constructor(Pt,dt){this._viewContainerRef=Pt,this._templateRef=dt,this._created=!1}create(){this._created=!0,this._viewContainerRef.createEmbeddedView(this._templateRef)}destroy(){this._created=!1,this._viewContainerRef.clear()}enforceState(Pt){Pt&&!this._created?this.create():!Pt&&this._created&&this.destroy()}}let us=(()=>{class rt{constructor(){this._defaultUsed=!1,this._caseCount=0,this._lastCaseCheckIndex=0,this._lastCasesMatched=!1}set ngSwitch(dt){this._ngSwitch=dt,0===this._caseCount&&this._updateDefaultCases(!0)}_addCase(){return this._caseCount++}_addDefault(dt){this._defaultViews||(this._defaultViews=[]),this._defaultViews.push(dt)}_matchCase(dt){const Te=dt==this._ngSwitch;return this._lastCasesMatched=this._lastCasesMatched||Te,this._lastCaseCheckIndex++,this._lastCaseCheckIndex===this._caseCount&&(this._updateDefaultCases(!this._lastCasesMatched),this._lastCaseCheckIndex=0,this._lastCasesMatched=!1),Te}_updateDefaultCases(dt){if(this._defaultViews&&dt!==this._defaultUsed){this._defaultUsed=dt;for(let Te=0;Te<this._defaultViews.length;Te++)this._defaultViews[Te].enforceState(dt)}}}return rt.\u0275fac=function(dt){return new(dt||rt)},rt.\u0275dir=r.lG2({type:rt,selectors:[["","ngSwitch",""]],inputs:{ngSwitch:"ngSwitch"}}),rt})(),ya=(()=>{class rt{constructor(dt,Te,Me){this.ngSwitch=Me,Me._addCase(),this._view=new Is(dt,Te)}ngDoCheck(){this._view.enforceState(this.ngSwitch._matchCase(this.ngSwitchCase))}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.Y36(r.s_b),r.Y36(r.Rgc),r.Y36(us,9))},rt.\u0275dir=r.lG2({type:rt,selectors:[["","ngSwitchCase",""]],inputs:{ngSwitchCase:"ngSwitchCase"}}),rt})(),el=(()=>{class rt{constructor(dt,Te,Me){Me._addDefault(new Is(dt,Te))}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.Y36(r.s_b),r.Y36(r.Rgc),r.Y36(us,9))},rt.\u0275dir=r.lG2({type:rt,selectors:[["","ngSwitchDefault",""]]}),rt})(),Il=(()=>{class rt{constructor(dt,Te,Me){this._ngEl=dt,this._differs=Te,this._renderer=Me,this._ngStyle=null,this._differ=null}set ngStyle(dt){this._ngStyle=dt,!this._differ&&dt&&(this._differ=this._differs.find(dt).create())}ngDoCheck(){if(this._differ){const dt=this._differ.diff(this._ngStyle);dt&&this._applyChanges(dt)}}_setStyle(dt,Te){const[Me,xe]=dt.split(".");null!=(Te=null!=Te&&xe?`${Te}${xe}`:Te)?this._renderer.setStyle(this._ngEl.nativeElement,Me,Te):this._renderer.removeStyle(this._ngEl.nativeElement,Me)}_applyChanges(dt){dt.forEachRemovedItem(Te=>this._setStyle(Te.key,null)),dt.forEachAddedItem(Te=>this._setStyle(Te.key,Te.currentValue)),dt.forEachChangedItem(Te=>this._setStyle(Te.key,Te.currentValue))}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.Y36(r.SBq),r.Y36(r.aQg),r.Y36(r.Qsj))},rt.\u0275dir=r.lG2({type:rt,selectors:[["","ngStyle",""]],inputs:{ngStyle:"ngStyle"}}),rt})(),fo=(()=>{class rt{constructor(dt){this._viewContainerRef=dt,this._viewRef=null,this.ngTemplateOutletContext=null,this.ngTemplateOutlet=null}ngOnChanges(dt){if(dt.ngTemplateOutlet){const Te=this._viewContainerRef;this._viewRef&&Te.remove(Te.indexOf(this._viewRef)),this._viewRef=this.ngTemplateOutlet?Te.createEmbeddedView(this.ngTemplateOutlet,this.ngTemplateOutletContext):null}else this._viewRef&&dt.ngTemplateOutletContext&&this.ngTemplateOutletContext&&(this._viewRef.context=this.ngTemplateOutletContext)}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.Y36(r.s_b))},rt.\u0275dir=r.lG2({type:rt,selectors:[["","ngTemplateOutlet",""]],inputs:{ngTemplateOutletContext:"ngTemplateOutletContext",ngTemplateOutlet:"ngTemplateOutlet"},features:[r.TTD]}),rt})();function Ao(rt,Pt){return Error(`InvalidPipeArgument: '${Pt}' for pipe '${(0,r.AaK)(rt)}'`)}class fs{createSubscription(Pt,dt){return Pt.subscribe({next:dt,error:Te=>{throw Te}})}dispose(Pt){Pt.unsubscribe()}onDestroy(Pt){Pt.unsubscribe()}}class Ca{createSubscription(Pt,dt){return Pt.then(dt,Te=>{throw Te})}dispose(Pt){}onDestroy(Pt){}}const Ra=new Ca,pl=new fs;let Ws=(()=>{class rt{constructor(dt){this._ref=dt,this._latestValue=null,this._subscription=null,this._obj=null,this._strategy=null}ngOnDestroy(){this._subscription&&this._dispose()}transform(dt){return this._obj?dt!==this._obj?(this._dispose(),this.transform(dt)):this._latestValue:(dt&&this._subscribe(dt),this._latestValue)}_subscribe(dt){this._obj=dt,this._strategy=this._selectStrategy(dt),this._subscription=this._strategy.createSubscription(dt,Te=>this._updateLatestValue(dt,Te))}_selectStrategy(dt){if((0,r.QGY)(dt))return Ra;if((0,r.F4k)(dt))return pl;throw Ao(rt,dt)}_dispose(){this._strategy.dispose(this._subscription),this._latestValue=null,this._subscription=null,this._obj=null}_updateLatestValue(dt,Te){dt===this._obj&&(this._latestValue=Te,this._ref.markForCheck())}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.Y36(r.sBO,16))},rt.\u0275pipe=r.Yjl({name:"async",type:rt,pure:!1}),rt})(),Po=(()=>{class rt{transform(dt){if(null==dt)return null;if("string"!=typeof dt)throw Ao(rt,dt);return dt.toLowerCase()}}return rt.\u0275fac=function(dt){return new(dt||rt)},rt.\u0275pipe=r.Yjl({name:"lowercase",type:rt,pure:!0}),rt})();const bo=/(?:[0-9A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5D\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD23\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF1C\uDF27\uDF30-\uDF45\uDF70-\uDF81\uDFB0-\uDFC4\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDEB8\uDF00-\uDF1A\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCDF\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDEE0-\uDEF2\uDFB0]|\uD808[\uDC00-\uDF99]|\uD809[\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE70-\uDEBE\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD837[\uDF00-\uDF1E]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB]|\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43\uDD4B]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])\S*/g;let Ls=(()=>{class rt{transform(dt){if(null==dt)return null;if("string"!=typeof dt)throw Ao(rt,dt);return dt.replace(bo,Te=>Te[0].toUpperCase()+Te.substr(1).toLowerCase())}}return rt.\u0275fac=function(dt){return new(dt||rt)},rt.\u0275pipe=r.Yjl({name:"titlecase",type:rt,pure:!0}),rt})(),ps=(()=>{class rt{transform(dt){if(null==dt)return null;if("string"!=typeof dt)throw Ao(rt,dt);return dt.toUpperCase()}}return rt.\u0275fac=function(dt){return new(dt||rt)},rt.\u0275pipe=r.Yjl({name:"uppercase",type:rt,pure:!0}),rt})(),So=(()=>{class rt{constructor(dt){this.locale=dt}transform(dt,Te="mediumDate",Me,xe){if(null==dt||""===dt||dt!=dt)return null;try{return _i(dt,Te,xe||this.locale,Me)}catch(Ct){throw Ao(rt,Ct.message)}}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.Y36(r.soG,16))},rt.\u0275pipe=r.Yjl({name:"date",type:rt,pure:!0}),rt})();const $r=/#/g;let to=(()=>{class rt{constructor(dt){this._localization=dt}transform(dt,Te,Me){if(null==dt)return"";if("object"!=typeof Te||null===Te)throw Ao(rt,Te);return Te[function(rt,Pt,dt,Te){let Me=`=${rt}`;if(Pt.indexOf(Me)>-1||(Me=dt.getPluralCategory(rt,Te),Pt.indexOf(Me)>-1))return Me;if(Pt.indexOf("other")>-1)return"other";throw new Error(`No plural message found for value "${rt}"`)}(dt,Object.keys(Te),this._localization,Me)].replace($r,dt.toString())}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.Y36(Rt,16))},rt.\u0275pipe=r.Yjl({name:"i18nPlural",type:rt,pure:!0}),rt})(),sn=(()=>{class rt{transform(dt){return JSON.stringify(dt,null,2)}}return rt.\u0275fac=function(dt){return new(dt||rt)},rt.\u0275pipe=r.Yjl({name:"json",type:rt,pure:!1}),rt})(),$e=(()=>{class rt{constructor(dt){this.differs=dt,this.keyValues=[],this.compareFn=Lt}transform(dt,Te=Lt){if(!dt||!(dt instanceof Map)&&"object"!=typeof dt)return null;this.differ||(this.differ=this.differs.find(dt).create());const Me=this.differ.diff(dt),xe=Te!==this.compareFn;return Me&&(this.keyValues=[],Me.forEachItem(Ct=>{this.keyValues.push(function(rt,Pt){return{key:rt,value:Pt}}(Ct.key,Ct.currentValue))})),(Me||xe)&&(this.keyValues.sort(Te),this.compareFn=Te),this.keyValues}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.Y36(r.aQg,16))},rt.\u0275pipe=r.Yjl({name:"keyvalue",type:rt,pure:!1}),rt})();function Lt(rt,Pt){const dt=rt.key,Te=Pt.key;if(dt===Te)return 0;if(void 0===dt)return 1;if(void 0===Te)return-1;if(null===dt)return 1;if(null===Te)return-1;if("string"==typeof dt&&"string"==typeof Te)return dt<Te?-1:1;if("number"==typeof dt&&"number"==typeof Te)return dt-Te;if("boolean"==typeof dt&&"boolean"==typeof Te)return dt<Te?-1:1;const Me=String(dt),xe=String(Te);return Me==xe?0:Me<xe?-1:1}let an=(()=>{class rt{constructor(dt){this._locale=dt}transform(dt,Te,Me){if(!xi(dt))return null;Me=Me||this._locale;try{return function(rt,Pt,dt){return lr(rt,uo(Ur(Pt,Ve.Decimal),Zn(Pt,He.MinusSign)),Pt,He.Group,He.Decimal,dt)}(ts(dt),Me,Te)}catch(xe){throw Ao(rt,xe.message)}}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.Y36(r.soG,16))},rt.\u0275pipe=r.Yjl({name:"number",type:rt,pure:!0}),rt})(),ti=(()=>{class rt{constructor(dt){this._locale=dt}transform(dt,Te,Me){if(!xi(dt))return null;Me=Me||this._locale;try{return function(rt,Pt,dt){return lr(rt,uo(Ur(Pt,Ve.Percent),Zn(Pt,He.MinusSign)),Pt,He.Group,He.Decimal,dt,!0).replace(new RegExp("%","g"),Zn(Pt,He.PercentSign))}(ts(dt),Me,Te)}catch(xe){throw Ao(rt,xe.message)}}}return rt.\u0275fac=function(dt){return new(dt||rt)(r.Y36(r.soG,16))},rt.\u0275pipe=r.Yjl({name:"percent",type:rt,pure:!0}),rt})();function xi(rt){return!(null==rt||""===rt||rt!=rt)}function ts(rt){if("string"==typeof rt&&!isNaN(Number(rt)-parseFloat(rt)))return Number(rt);if("number"!=typeof rt)throw new Error(`${rt} is not a number`);return rt}let Eo=(()=>{class rt{}return rt.\u0275fac=function(dt){return new(dt||rt)},rt.\u0275mod=r.oAB({type:rt}),rt.\u0275inj=r.cJS({providers:[{provide:Rt,useClass:mt}]}),rt})();const ba="browser";function bc(rt){return rt===ba}let Fs=(()=>{class rt{}return rt.\u0275prov=(0,r.Yz7)({token:rt,providedIn:"root",factory:()=>new dc((0,r.LFG)(y),window)}),rt})();class dc{constructor(Pt,dt){this.document=Pt,this.window=dt,this.offset=()=>[0,0]}setOffset(Pt){this.offset=Array.isArray(Pt)?()=>Pt:Pt}getScrollPosition(){return this.supportsScrolling()?[this.window.pageXOffset,this.window.pageYOffset]:[0,0]}scrollToPosition(Pt){this.supportsScrolling()&&this.window.scrollTo(Pt[0],Pt[1])}scrollToAnchor(Pt){if(!this.supportsScrolling())return;const dt=function(rt,Pt){const dt=rt.getElementById(Pt)||rt.getElementsByName(Pt)[0];if(dt)return dt;if("function"==typeof rt.createTreeWalker&&rt.body&&(rt.body.createShadowRoot||rt.body.attachShadow)){const Te=rt.createTreeWalker(rt.body,NodeFilter.SHOW_ELEMENT);let Me=Te.currentNode;for(;Me;){const xe=Me.shadowRoot;if(xe){const Ct=xe.getElementById(Pt)||xe.querySelector(`[name="${Pt}"]`);if(Ct)return Ct}Me=Te.nextNode()}}return null}(this.document,Pt);dt&&(this.scrollToElement(dt),this.attemptFocus(dt))}setHistoryScrollRestoration(Pt){if(this.supportScrollRestoration()){const dt=this.window.history;dt&&dt.scrollRestoration&&(dt.scrollRestoration=Pt)}}scrollToElement(Pt){const dt=Pt.getBoundingClientRect(),Te=dt.left+this.window.pageXOffset,Me=dt.top+this.window.pageYOffset,xe=this.offset();this.window.scrollTo(Te-xe[0],Me-xe[1])}attemptFocus(Pt){return Pt.focus(),this.document.activeElement===Pt}supportScrollRestoration(){try{if(!this.supportsScrolling())return!1;const Pt=iu(this.window.history)||iu(Object.getPrototypeOf(this.window.history));return!(!Pt||!Pt.writable&&!Pt.set)}catch(Pt){return!1}}supportsScrolling(){try{return!!this.window&&!!this.window.scrollTo&&"pageXOffset"in this.window}catch(Pt){return!1}}}function iu(rt){return Object.getOwnPropertyDescriptor(rt,"scrollRestoration")}class Zl{}},58497:(v,T,i)=>{"use strict";i.d(T,{TP:()=>it,eN:()=>He,JF:()=>fi,UA:()=>Pe,LE:()=>ae});var r=i(12057),u=i(74788),p=i(25917),d=i(18891),e=i(94612),_=i(45435),y=i(88002);class S{}class A{}class N{constructor(Cn){this.normalizedNames=new Map,this.lazyUpdate=null,Cn?this.lazyInit="string"==typeof Cn?()=>{this.headers=new Map,Cn.split("\n").forEach(Wt=>{const zn=Wt.indexOf(":");if(zn>0){const rr=Wt.slice(0,zn),Fr=rr.toLowerCase(),Gn=Wt.slice(zn+1).trim();this.maybeSetNormalizedName(rr,Fr),this.headers.has(Fr)?this.headers.get(Fr).push(Gn):this.headers.set(Fr,[Gn])}})}:()=>{this.headers=new Map,Object.keys(Cn).forEach(Wt=>{let zn=Cn[Wt];const rr=Wt.toLowerCase();"string"==typeof zn&&(zn=[zn]),zn.length>0&&(this.headers.set(rr,zn),this.maybeSetNormalizedName(Wt,rr))})}:this.headers=new Map}has(Cn){return this.init(),this.headers.has(Cn.toLowerCase())}get(Cn){this.init();const Wt=this.headers.get(Cn.toLowerCase());return Wt&&Wt.length>0?Wt[0]:null}keys(){return this.init(),Array.from(this.normalizedNames.values())}getAll(Cn){return this.init(),this.headers.get(Cn.toLowerCase())||null}append(Cn,Wt){return this.clone({name:Cn,value:Wt,op:"a"})}set(Cn,Wt){return this.clone({name:Cn,value:Wt,op:"s"})}delete(Cn,Wt){return this.clone({name:Cn,value:Wt,op:"d"})}maybeSetNormalizedName(Cn,Wt){this.normalizedNames.has(Wt)||this.normalizedNames.set(Wt,Cn)}init(){this.lazyInit&&(this.lazyInit instanceof N?this.copyFrom(this.lazyInit):this.lazyInit(),this.lazyInit=null,this.lazyUpdate&&(this.lazyUpdate.forEach(Cn=>this.applyUpdate(Cn)),this.lazyUpdate=null))}copyFrom(Cn){Cn.init(),Array.from(Cn.headers.keys()).forEach(Wt=>{this.headers.set(Wt,Cn.headers.get(Wt)),this.normalizedNames.set(Wt,Cn.normalizedNames.get(Wt))})}clone(Cn){const Wt=new N;return Wt.lazyInit=this.lazyInit&&this.lazyInit instanceof N?this.lazyInit:this,Wt.lazyUpdate=(this.lazyUpdate||[]).concat([Cn]),Wt}applyUpdate(Cn){const Wt=Cn.name.toLowerCase();switch(Cn.op){case"a":case"s":let zn=Cn.value;if("string"==typeof zn&&(zn=[zn]),0===zn.length)return;this.maybeSetNormalizedName(Cn.name,Wt);const rr=("a"===Cn.op?this.headers.get(Wt):void 0)||[];rr.push(...zn),this.headers.set(Wt,rr);break;case"d":const Fr=Cn.value;if(Fr){let Gn=this.headers.get(Wt);if(!Gn)return;Gn=Gn.filter(Jr=>-1===Fr.indexOf(Jr)),0===Gn.length?(this.headers.delete(Wt),this.normalizedNames.delete(Wt)):this.headers.set(Wt,Gn)}else this.headers.delete(Wt),this.normalizedNames.delete(Wt)}}forEach(Cn){this.init(),Array.from(this.normalizedNames.keys()).forEach(Wt=>Cn(this.normalizedNames.get(Wt),this.headers.get(Wt)))}}class L{encodeKey(Cn){return ee(Cn)}encodeValue(Cn){return ee(Cn)}decodeKey(Cn){return decodeURIComponent(Cn)}decodeValue(Cn){return decodeURIComponent(Cn)}}const J=/%(\d[a-f0-9])/gi,K={40:"@","3A":":",24:"$","2C":",","3B":";","2B":"+","3D":"=","3F":"?","2F":"/"};function ee(Zr){return encodeURIComponent(Zr).replace(J,(Cn,Wt)=>{var zn;return null!==(zn=K[Wt])&&void 0!==zn?zn:Cn})}function ue(Zr){return`${Zr}`}class ae{constructor(Cn={}){if(this.updates=null,this.cloneFrom=null,this.encoder=Cn.encoder||new L,Cn.fromString){if(Cn.fromObject)throw new Error("Cannot specify both fromString and fromObject.");this.map=function(Zr,Cn){const Wt=new Map;return Zr.length>0&&Zr.replace(/^\?/,"").split("&").forEach(rr=>{const Fr=rr.indexOf("="),[Gn,Jr]=-1==Fr?[Cn.decodeKey(rr),""]:[Cn.decodeKey(rr.slice(0,Fr)),Cn.decodeValue(rr.slice(Fr+1))],_i=Wt.get(Gn)||[];_i.push(Jr),Wt.set(Gn,_i)}),Wt}(Cn.fromString,this.encoder)}else Cn.fromObject?(this.map=new Map,Object.keys(Cn.fromObject).forEach(Wt=>{const zn=Cn.fromObject[Wt];this.map.set(Wt,Array.isArray(zn)?zn:[zn])})):this.map=null}has(Cn){return this.init(),this.map.has(Cn)}get(Cn){this.init();const Wt=this.map.get(Cn);return Wt?Wt[0]:null}getAll(Cn){return this.init(),this.map.get(Cn)||null}keys(){return this.init(),Array.from(this.map.keys())}append(Cn,Wt){return this.clone({param:Cn,value:Wt,op:"a"})}appendAll(Cn){const Wt=[];return Object.keys(Cn).forEach(zn=>{const rr=Cn[zn];Array.isArray(rr)?rr.forEach(Fr=>{Wt.push({param:zn,value:Fr,op:"a"})}):Wt.push({param:zn,value:rr,op:"a"})}),this.clone(Wt)}set(Cn,Wt){return this.clone({param:Cn,value:Wt,op:"s"})}delete(Cn,Wt){return this.clone({param:Cn,value:Wt,op:"d"})}toString(){return this.init(),this.keys().map(Cn=>{const Wt=this.encoder.encodeKey(Cn);return this.map.get(Cn).map(zn=>Wt+"="+this.encoder.encodeValue(zn)).join("&")}).filter(Cn=>""!==Cn).join("&")}clone(Cn){const Wt=new ae({encoder:this.encoder});return Wt.cloneFrom=this.cloneFrom||this,Wt.updates=(this.updates||[]).concat(Cn),Wt}init(){null===this.map&&(this.map=new Map),null!==this.cloneFrom&&(this.cloneFrom.init(),this.cloneFrom.keys().forEach(Cn=>this.map.set(Cn,this.cloneFrom.map.get(Cn))),this.updates.forEach(Cn=>{switch(Cn.op){case"a":case"s":const Wt=("a"===Cn.op?this.map.get(Cn.param):void 0)||[];Wt.push(ue(Cn.value)),this.map.set(Cn.param,Wt);break;case"d":if(void 0===Cn.value){this.map.delete(Cn.param);break}{let zn=this.map.get(Cn.param)||[];const rr=zn.indexOf(ue(Cn.value));-1!==rr&&zn.splice(rr,1),zn.length>0?this.map.set(Cn.param,zn):this.map.delete(Cn.param)}}}),this.cloneFrom=this.updates=null)}}class se{constructor(){this.map=new Map}set(Cn,Wt){return this.map.set(Cn,Wt),this}get(Cn){return this.map.has(Cn)||this.map.set(Cn,Cn.defaultValue()),this.map.get(Cn)}delete(Cn){return this.map.delete(Cn),this}keys(){return this.map.keys()}}function ie(Zr){return"undefined"!=typeof ArrayBuffer&&Zr instanceof ArrayBuffer}function he(Zr){return"undefined"!=typeof Blob&&Zr instanceof Blob}function ge(Zr){return"undefined"!=typeof FormData&&Zr instanceof FormData}class ce{constructor(Cn,Wt,zn,rr){let Fr;if(this.url=Wt,this.body=null,this.reportProgress=!1,this.withCredentials=!1,this.responseType="json",this.method=Cn.toUpperCase(),function(Zr){switch(Zr){case"DELETE":case"GET":case"HEAD":case"OPTIONS":case"JSONP":return!1;default:return!0}}(this.method)||rr?(this.body=void 0!==zn?zn:null,Fr=rr):Fr=zn,Fr&&(this.reportProgress=!!Fr.reportProgress,this.withCredentials=!!Fr.withCredentials,Fr.responseType&&(this.responseType=Fr.responseType),Fr.headers&&(this.headers=Fr.headers),Fr.context&&(this.context=Fr.context),Fr.params&&(this.params=Fr.params)),this.headers||(this.headers=new N),this.context||(this.context=new se),this.params){const Gn=this.params.toString();if(0===Gn.length)this.urlWithParams=Wt;else{const Jr=Wt.indexOf("?");this.urlWithParams=Wt+(-1===Jr?"?":Jr<Wt.length-1?"&":"")+Gn}}else this.params=new ae,this.urlWithParams=Wt}serializeBody(){return null===this.body?null:ie(this.body)||he(this.body)||ge(this.body)||"undefined"!=typeof URLSearchParams&&this.body instanceof URLSearchParams||"string"==typeof this.body?this.body:this.body instanceof ae?this.body.toString():"object"==typeof this.body||"boolean"==typeof this.body||Array.isArray(this.body)?JSON.stringify(this.body):this.body.toString()}detectContentTypeHeader(){return null===this.body||ge(this.body)?null:he(this.body)?this.body.type||null:ie(this.body)?null:"string"==typeof this.body?"text/plain":this.body instanceof ae?"application/x-www-form-urlencoded;charset=UTF-8":"object"==typeof this.body||"number"==typeof this.body||"boolean"==typeof this.body?"application/json":null}clone(Cn={}){var Wt;const zn=Cn.method||this.method,rr=Cn.url||this.url,Fr=Cn.responseType||this.responseType,Gn=void 0!==Cn.body?Cn.body:this.body,Jr=void 0!==Cn.withCredentials?Cn.withCredentials:this.withCredentials,_i=void 0!==Cn.reportProgress?Cn.reportProgress:this.reportProgress;let wi=Cn.headers||this.headers,br=Cn.params||this.params;const Dr=null!==(Wt=Cn.context)&&void 0!==Wt?Wt:this.context;return void 0!==Cn.setHeaders&&(wi=Object.keys(Cn.setHeaders).reduce((gn,yn)=>gn.set(yn,Cn.setHeaders[yn]),wi)),Cn.setParams&&(br=Object.keys(Cn.setParams).reduce((gn,yn)=>gn.set(yn,Cn.setParams[yn]),br)),new ce(zn,rr,Gn,{params:br,headers:wi,context:Dr,reportProgress:_i,responseType:Fr,withCredentials:Jr})}}var lt=(()=>((lt=lt||{})[lt.Sent=0]="Sent",lt[lt.UploadProgress=1]="UploadProgress",lt[lt.ResponseHeader=2]="ResponseHeader",lt[lt.DownloadProgress=3]="DownloadProgress",lt[lt.Response=4]="Response",lt[lt.User=5]="User",lt))();class Ve{constructor(Cn,Wt=200,zn="OK"){this.headers=Cn.headers||new N,this.status=void 0!==Cn.status?Cn.status:Wt,this.statusText=Cn.statusText||zn,this.url=Cn.url||null,this.ok=this.status>=200&&this.status<300}}class ze extends Ve{constructor(Cn={}){super(Cn),this.type=lt.ResponseHeader}clone(Cn={}){return new ze({headers:Cn.headers||this.headers,status:void 0!==Cn.status?Cn.status:this.status,statusText:Cn.statusText||this.statusText,url:Cn.url||this.url||void 0})}}class Be extends Ve{constructor(Cn={}){super(Cn),this.type=lt.Response,this.body=void 0!==Cn.body?Cn.body:null}clone(Cn={}){return new Be({body:void 0!==Cn.body?Cn.body:this.body,headers:Cn.headers||this.headers,status:void 0!==Cn.status?Cn.status:this.status,statusText:Cn.statusText||this.statusText,url:Cn.url||this.url||void 0})}}class Pe extends Ve{constructor(Cn){super(Cn,0,"Unknown Error"),this.name="HttpErrorResponse",this.ok=!1,this.message=this.status>=200&&this.status<300?`Http failure during parsing for ${Cn.url||"(unknown url)"}`:`Http failure response for ${Cn.url||"(unknown url)"}: ${Cn.status} ${Cn.statusText}`,this.error=Cn.error||null}}function je(Zr,Cn){return{body:Cn,headers:Zr.headers,context:Zr.context,observe:Zr.observe,params:Zr.params,reportProgress:Zr.reportProgress,responseType:Zr.responseType,withCredentials:Zr.withCredentials}}let He=(()=>{class Zr{constructor(Wt){this.handler=Wt}request(Wt,zn,rr={}){let Fr;if(Wt instanceof ce)Fr=Wt;else{let _i,wi;_i=rr.headers instanceof N?rr.headers:new N(rr.headers),rr.params&&(wi=rr.params instanceof ae?rr.params:new ae({fromObject:rr.params})),Fr=new ce(Wt,zn,void 0!==rr.body?rr.body:null,{headers:_i,context:rr.context,params:wi,reportProgress:rr.reportProgress,responseType:rr.responseType||"json",withCredentials:rr.withCredentials})}const Gn=(0,p.of)(Fr).pipe((0,e.b)(_i=>this.handler.handle(_i)));if(Wt instanceof ce||"events"===rr.observe)return Gn;const Jr=Gn.pipe((0,_.h)(_i=>_i instanceof Be));switch(rr.observe||"body"){case"body":switch(Fr.responseType){case"arraybuffer":return Jr.pipe((0,y.U)(_i=>{if(null!==_i.body&&!(_i.body instanceof ArrayBuffer))throw new Error("Response is not an ArrayBuffer.");return _i.body}));case"blob":return Jr.pipe((0,y.U)(_i=>{if(null!==_i.body&&!(_i.body instanceof Blob))throw new Error("Response is not a Blob.");return _i.body}));case"text":return Jr.pipe((0,y.U)(_i=>{if(null!==_i.body&&"string"!=typeof _i.body)throw new Error("Response is not a string.");return _i.body}));case"json":default:return Jr.pipe((0,y.U)(_i=>_i.body))}case"response":return Jr;default:throw new Error(`Unreachable: unhandled observe type ${rr.observe}}`)}}delete(Wt,zn={}){return this.request("DELETE",Wt,zn)}get(Wt,zn={}){return this.request("GET",Wt,zn)}head(Wt,zn={}){return this.request("HEAD",Wt,zn)}jsonp(Wt,zn){return this.request("JSONP",Wt,{params:(new ae).append(zn,"JSONP_CALLBACK"),observe:"body",responseType:"json"})}options(Wt,zn={}){return this.request("OPTIONS",Wt,zn)}patch(Wt,zn,rr={}){return this.request("PATCH",Wt,je(rr,zn))}post(Wt,zn,rr={}){return this.request("POST",Wt,je(rr,zn))}put(Wt,zn,rr={}){return this.request("PUT",Wt,je(rr,zn))}}return Zr.\u0275fac=function(Wt){return new(Wt||Zr)(u.LFG(S))},Zr.\u0275prov=u.Yz7({token:Zr,factory:Zr.\u0275fac}),Zr})();class Vt{constructor(Cn,Wt){this.next=Cn,this.interceptor=Wt}handle(Cn){return this.interceptor.intercept(Cn,this.next)}}const it=new u.OlP("HTTP_INTERCEPTORS");let tn=(()=>{class Zr{intercept(Wt,zn){return zn.handle(Wt)}}return Zr.\u0275fac=function(Wt){return new(Wt||Zr)},Zr.\u0275prov=u.Yz7({token:Zr,factory:Zr.\u0275fac}),Zr})();const Xt=/^\)\]\}',?\n/;let Ur=(()=>{class Zr{constructor(Wt){this.xhrFactory=Wt}handle(Wt){if("JSONP"===Wt.method)throw new Error("Attempted to construct Jsonp request without HttpClientJsonpModule installed.");return new d.y(zn=>{const rr=this.xhrFactory.build();if(rr.open(Wt.method,Wt.urlWithParams),Wt.withCredentials&&(rr.withCredentials=!0),Wt.headers.forEach((yn,gr)=>rr.setRequestHeader(yn,gr.join(","))),Wt.headers.has("Accept")||rr.setRequestHeader("Accept","application/json, text/plain, */*"),!Wt.headers.has("Content-Type")){const yn=Wt.detectContentTypeHeader();null!==yn&&rr.setRequestHeader("Content-Type",yn)}if(Wt.responseType){const yn=Wt.responseType.toLowerCase();rr.responseType="json"!==yn?yn:"text"}const Fr=Wt.serializeBody();let Gn=null;const Jr=()=>{if(null!==Gn)return Gn;const yn=1223===rr.status?204:rr.status,gr=rr.statusText||"OK",Jt=new N(rr.getAllResponseHeaders()),Vn=function(Zr){return"responseURL"in Zr&&Zr.responseURL?Zr.responseURL:/^X-Request-URL:/m.test(Zr.getAllResponseHeaders())?Zr.getResponseHeader("X-Request-URL"):null}(rr)||Wt.url;return Gn=new ze({headers:Jt,status:yn,statusText:gr,url:Vn}),Gn},_i=()=>{let{headers:yn,status:gr,statusText:Jt,url:Vn}=Jr(),mr=null;204!==gr&&(mr=void 0===rr.response?rr.responseText:rr.response),0===gr&&(gr=mr?200:0);let Dn=gr>=200&&gr<300;if("json"===Wt.responseType&&"string"==typeof mr){const Pr=mr;mr=mr.replace(Xt,"");try{mr=""!==mr?JSON.parse(mr):null}catch(Yt){mr=Pr,Dn&&(Dn=!1,mr={error:Yt,text:mr})}}Dn?(zn.next(new Be({body:mr,headers:yn,status:gr,statusText:Jt,url:Vn||void 0})),zn.complete()):zn.error(new Pe({error:mr,headers:yn,status:gr,statusText:Jt,url:Vn||void 0}))},wi=yn=>{const{url:gr}=Jr(),Jt=new Pe({error:yn,status:rr.status||0,statusText:rr.statusText||"Unknown Error",url:gr||void 0});zn.error(Jt)};let br=!1;const Dr=yn=>{br||(zn.next(Jr()),br=!0);let gr={type:lt.DownloadProgress,loaded:yn.loaded};yn.lengthComputable&&(gr.total=yn.total),"text"===Wt.responseType&&!!rr.responseText&&(gr.partialText=rr.responseText),zn.next(gr)},gn=yn=>{let gr={type:lt.UploadProgress,loaded:yn.loaded};yn.lengthComputable&&(gr.total=yn.total),zn.next(gr)};return rr.addEventListener("load",_i),rr.addEventListener("error",wi),rr.addEventListener("timeout",wi),rr.addEventListener("abort",wi),Wt.reportProgress&&(rr.addEventListener("progress",Dr),null!==Fr&&rr.upload&&rr.upload.addEventListener("progress",gn)),rr.send(Fr),zn.next({type:lt.Sent}),()=>{rr.removeEventListener("error",wi),rr.removeEventListener("abort",wi),rr.removeEventListener("load",_i),rr.removeEventListener("timeout",wi),Wt.reportProgress&&(rr.removeEventListener("progress",Dr),null!==Fr&&rr.upload&&rr.upload.removeEventListener("progress",gn)),rr.readyState!==rr.DONE&&rr.abort()}})}}return Zr.\u0275fac=function(Wt){return new(Wt||Zr)(u.LFG(r.JF))},Zr.\u0275prov=u.Yz7({token:Zr,factory:Zr.\u0275fac}),Zr})();const di=new u.OlP("XSRF_COOKIE_NAME"),Lr=new u.OlP("XSRF_HEADER_NAME");class Mr{}let Kr=(()=>{class Zr{constructor(Wt,zn,rr){this.doc=Wt,this.platform=zn,this.cookieName=rr,this.lastCookieString="",this.lastToken=null,this.parseCount=0}getToken(){if("server"===this.platform)return null;const Wt=this.doc.cookie||"";return Wt!==this.lastCookieString&&(this.parseCount++,this.lastToken=(0,r.Mx)(Wt,this.cookieName),this.lastCookieString=Wt),this.lastToken}}return Zr.\u0275fac=function(Wt){return new(Wt||Zr)(u.LFG(r.K0),u.LFG(u.Lbi),u.LFG(di))},Zr.\u0275prov=u.Yz7({token:Zr,factory:Zr.\u0275fac}),Zr})(),ei=(()=>{class Zr{constructor(Wt,zn){this.tokenService=Wt,this.headerName=zn}intercept(Wt,zn){const rr=Wt.url.toLowerCase();if("GET"===Wt.method||"HEAD"===Wt.method||rr.startsWith("http://")||rr.startsWith("https://"))return zn.handle(Wt);const Fr=this.tokenService.getToken();return null!==Fr&&!Wt.headers.has(this.headerName)&&(Wt=Wt.clone({headers:Wt.headers.set(this.headerName,Fr)})),zn.handle(Wt)}}return Zr.\u0275fac=function(Wt){return new(Wt||Zr)(u.LFG(Mr),u.LFG(Lr))},Zr.\u0275prov=u.Yz7({token:Zr,factory:Zr.\u0275fac}),Zr})(),Nn=(()=>{class Zr{constructor(Wt,zn){this.backend=Wt,this.injector=zn,this.chain=null}handle(Wt){if(null===this.chain){const zn=this.injector.get(it,[]);this.chain=zn.reduceRight((rr,Fr)=>new Vt(rr,Fr),this.backend)}return this.chain.handle(Wt)}}return Zr.\u0275fac=function(Wt){return new(Wt||Zr)(u.LFG(A),u.LFG(u.zs3))},Zr.\u0275prov=u.Yz7({token:Zr,factory:Zr.\u0275fac}),Zr})(),Yr=(()=>{class Zr{static disable(){return{ngModule:Zr,providers:[{provide:ei,useClass:tn}]}}static withOptions(Wt={}){return{ngModule:Zr,providers:[Wt.cookieName?{provide:di,useValue:Wt.cookieName}:[],Wt.headerName?{provide:Lr,useValue:Wt.headerName}:[]]}}}return Zr.\u0275fac=function(Wt){return new(Wt||Zr)},Zr.\u0275mod=u.oAB({type:Zr}),Zr.\u0275inj=u.cJS({providers:[ei,{provide:it,useExisting:ei,multi:!0},{provide:Mr,useClass:Kr},{provide:di,useValue:"XSRF-TOKEN"},{provide:Lr,useValue:"X-XSRF-TOKEN"}]}),Zr})(),fi=(()=>{class Zr{}return Zr.\u0275fac=function(Wt){return new(Wt||Zr)},Zr.\u0275mod=u.oAB({type:Zr}),Zr.\u0275inj=u.cJS({providers:[He,{provide:S,useClass:Nn},Ur,{provide:A,useExisting:Ur}],imports:[[Yr.withOptions({cookieName:"XSRF-TOKEN",headerName:"X-XSRF-TOKEN"})]]}),Zr})()},74788:(v,T,i)=>{"use strict";i.d(T,{deG:()=>vd,tb:()=>Pp,AFp:()=>N2,ip1:()=>yT,CZH:()=>Zv,hGG:()=>$T,z2F:()=>r0,sBO:()=>Kw,Sil:()=>n0,_Vd:()=>Pv,UuU:()=>nM,EJc:()=>F2,SBq:()=>og,qLn:()=>Gf,vpe:()=>Wp,gxx:()=>Jg,tBr:()=>ha,XFs:()=>Yr,OlP:()=>Jl,zs3:()=>Ac,IIB:()=>w2,ZZ4:()=>Ay,aQg:()=>Oy,soG:()=>Gy,YKP:()=>DE,v3s:()=>UD,h0i:()=>zm,PXZ:()=>FD,R0b:()=>Eh,FiY:()=>ia,r_U:()=>gD,Lbi:()=>cm,g9A:()=>D_,Qsj:()=>kw,FYo:()=>Cy,JOm:()=>Bd,Tiy:()=>xE,q3G:()=>Vs,tp0:()=>il,EAV:()=>ZD,Rgc:()=>F1,dDg:()=>AT,DyG:()=>Hf,GfV:()=>aM,i9L:()=>fp,s_b:()=>Dy,ifc:()=>Gn,eFA:()=>DT,G48:()=>RD,Gpc:()=>L,X6Q:()=>xT,_c5:()=>JD,VLi:()=>DD,c2e:()=>L2,zSh:()=>Im,wAp:()=>Ua,vHH:()=>ee,EiD:()=>Xo,mCW:()=>vf,qzn:()=>Yf,JVY:()=>bd,pB0:()=>Nh,eBb:()=>th,L6k:()=>Rh,LAX:()=>nh,cg1:()=>fE,Tjo:()=>WD,kL8:()=>wC,yhl:()=>eh,dqk:()=>Dr,sIi:()=>Hm,CqO:()=>qb,QGY:()=>Zm,F4k:()=>kS,RDi:()=>tl,AaK:()=>S,z3N:()=>kd,qOj:()=>T1,TTD:()=>Eo,_Bn:()=>Pw,xp6:()=>Fa,uIk:()=>A1,Tol:()=>rC,Gre:()=>gC,MT6:()=>mC,DjV:()=>vC,ekj:()=>oE,Suo:()=>a2,Xpm:()=>mi,lG2:()=>lo,Yz7:()=>xt,cJS:()=>Zn,oAB:()=>Fn,Yjl:()=>vo,Y36:()=>D1,_UZ:()=>LS,GkF:()=>FS,BQk:()=>Kb,ynx:()=>Xb,qZA:()=>Qb,TgZ:()=>Jb,EpF:()=>fy,n5z:()=>$f,Ikx:()=>cE,SDv:()=>QC,QtT:()=>KC,DtL:()=>XC,N_p:()=>EE,pQV:()=>TE,Zx4:()=>qC,tHW:()=>Ty,LFG:()=>xn,$8M:()=>Sl,NdJ:()=>eE,CRH:()=>l2,oxw:()=>BS,ALo:()=>e2,lcZ:()=>t2,xi3:()=>bh,Dn7:()=>n2,Hsn:()=>ZS,F$t:()=>YS,Q6J:()=>zb,s9C:()=>nE,MGl:()=>py,hYB:()=>xg,DdM:()=>WE,VKq:()=>JE,WLB:()=>z1,kEZ:()=>WM,l5B:()=>e_,qbA:()=>JM,iGM:()=>o2,MAs:()=>Ke,pYS:()=>Vf,Jf7:()=>Uh,CHM:()=>Aa,oJD:()=>_c,uOi:()=>Hd,LSH:()=>wu,kYT:()=>ar,Udp:()=>iE,d8E:()=>dE,YNc:()=>$,W1O:()=>of,_uU:()=>uC,Oqu:()=>aE,hij:()=>gy,AsE:()=>lE,lnq:()=>uE,Gf:()=>s2});var r=i(79765),u=i(75319),p=i(18891),d=i(66682),e=i(18819);function _(a){for(let l in a)if(a[l]===_)return l;throw Error("Could not find renamed property on target object.")}function y(a,l){for(const f in l)l.hasOwnProperty(f)&&!a.hasOwnProperty(f)&&(a[f]=l[f])}function S(a){if("string"==typeof a)return a;if(Array.isArray(a))return"["+a.map(S).join(", ")+"]";if(null==a)return""+a;if(a.overriddenName)return`${a.overriddenName}`;if(a.name)return`${a.name}`;const l=a.toString();if(null==l)return""+l;const f=l.indexOf("\n");return-1===f?l:l.substring(0,f)}function A(a,l){return null==a||""===a?null===l?"":l:null==l||""===l?a:a+" "+l}const N=_({__forward_ref__:_});function L(a){return a.__forward_ref__=L,a.toString=function(){return S(this())},a}function Z(a){return J(a)?a():a}function J(a){return"function"==typeof a&&a.hasOwnProperty(N)&&a.__forward_ref__===L}class ee extends Error{constructor(l,f){super(function(a,l){return`${a?`NG0${a}: `:""}${l}`}(l,f)),this.code=l}}function H(a){return"string"==typeof a?a:null==a?"":String(a)}function se(a){return"function"==typeof a?a.name||a.toString():"object"==typeof a&&null!=a&&"function"==typeof a.type?a.type.name||a.type.toString():H(a)}function ge(a,l){const f=l?` in ${l}`:"";throw new ee("201",`No provider for ${se(a)} found${f}`)}function Ut(a,l,f,m){throw new Error(`ASSERTION ERROR: ${a}`+(null==m?"":` [Expected=> ${f} ${m} ${l} <=Actual]`))}function xt(a){return{token:a.token,providedIn:a.providedIn||null,factory:a.factory,value:void 0}}function Zn(a){return{providers:a.providers||[],imports:a.imports||[]}}function Ur(a){return di(a,ei)||di(a,$n)}function di(a,l){return a.hasOwnProperty(l)?a[l]:null}function Kr(a){return a&&(a.hasOwnProperty(Nn)||a.hasOwnProperty(Br))?a[Nn]:null}const ei=_({\u0275prov:_}),Nn=_({\u0275inj:_}),$n=_({ngInjectableDef:_}),Br=_({ngInjectorDef:_});var Yr=(()=>((Yr=Yr||{})[Yr.Default=0]="Default",Yr[Yr.Host=1]="Host",Yr[Yr.Self=2]="Self",Yr[Yr.SkipSelf=4]="SkipSelf",Yr[Yr.Optional=8]="Optional",Yr))();let fi;function Hi(a){const l=fi;return fi=a,l}function Zr(a,l,f){const m=Ur(a);return m&&"root"==m.providedIn?void 0===m.value?m.value=m.factory():m.value:f&Yr.Optional?null:void 0!==l?l:void ge(S(a),"Injector")}function Wt(a){return{toString:a}.toString()}var zn=(()=>((zn=zn||{})[zn.OnPush=0]="OnPush",zn[zn.Default=1]="Default",zn))(),Gn=(()=>((Gn=Gn||{})[Gn.Emulated=0]="Emulated",Gn[Gn.None=2]="None",Gn[Gn.ShadowDom=3]="ShadowDom",Gn))();const Jr="undefined"!=typeof globalThis&&globalThis,_i="undefined"!=typeof window&&window,wi="undefined"!=typeof self&&"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&self,Dr=Jr||"undefined"!=typeof global&&global||_i||wi,gr={},Jt=[],Vn=_({\u0275cmp:_}),mr=_({\u0275dir:_}),Dn=_({\u0275pipe:_}),Pr=_({\u0275mod:_}),Yt=_({\u0275loc:_}),_n=_({\u0275fac:_}),Ge=_({__NG_ELEMENT_ID__:_});let kr=0;function mi(a){return Wt(()=>{const f={},m={type:a.type,providersResolver:null,decls:a.decls,vars:a.vars,factory:null,template:a.template||null,consts:a.consts||null,ngContentSelectors:a.ngContentSelectors,hostBindings:a.hostBindings||null,hostVars:a.hostVars||0,hostAttrs:a.hostAttrs||null,contentQueries:a.contentQueries||null,declaredInputs:f,inputs:null,outputs:null,exportAs:a.exportAs||null,onPush:a.changeDetection===zn.OnPush,directiveDefs:null,pipeDefs:null,selectors:a.selectors||Jt,viewQuery:a.viewQuery||null,features:a.features||null,data:a.data||{},encapsulation:a.encapsulation||Gn.Emulated,id:"c",styles:a.styles||Jt,_:null,setInput:null,schemas:a.schemas||null,tView:null},M=a.directives,k=a.features,te=a.pipes;return m.id+=kr++,m.inputs=Wi(a.inputs,f),m.outputs=Wi(a.outputs),k&&k.forEach(le=>le(m)),m.directiveDefs=M?()=>("function"==typeof M?M():M).map(Er):null,m.pipeDefs=te?()=>("function"==typeof te?te():te).map(Wr):null,m})}function Er(a){return Co(a)||function(a){return a[mr]||null}(a)}function Wr(a){return function(a){return a[Dn]||null}(a)}const dr={};function Fn(a){return Wt(()=>{const l={type:a.type,bootstrap:a.bootstrap||Jt,declarations:a.declarations||Jt,imports:a.imports||Jt,exports:a.exports||Jt,transitiveCompileScopes:null,schemas:a.schemas||null,id:a.id||null};return null!=a.id&&(dr[a.id]=a.type),l})}function ar(a,l){return Wt(()=>{const f=jo(a,!0);f.declarations=l.declarations||Jt,f.imports=l.imports||Jt,f.exports=l.exports||Jt})}function Wi(a,l){if(null==a)return gr;const f={};for(const m in a)if(a.hasOwnProperty(m)){let M=a[m],k=M;Array.isArray(M)&&(k=M[1],M=M[0]),f[M]=m,l&&(l[M]=k)}return f}const lo=mi;function vo(a){return{type:a.type,name:a.name,factory:null,pure:!1!==a.pure,onDestroy:a.type.prototype.ngOnDestroy||null}}function Co(a){return a[Vn]||null}function jo(a,l){const f=a[Pr]||null;if(!f&&!0===l)throw new Error(`Type ${S(a)} does not have '\u0275mod' property.`);return f}function ca(a){return Array.isArray(a)&&"object"==typeof a[1]}function $s(a){return Array.isArray(a)&&!0===a[1]}function da(a){return 0!=(8&a.flags)}function Il(a){return 2==(2&a.flags)}function fo(a){return 1==(1&a.flags)}function Ya(a){return null!==a.template}function Ao(a){return 0!=(512&a[2])}function wo(a,l){return a.hasOwnProperty(_n)?a[_n]:null}class ko{constructor(l,f,m){this.previousValue=l,this.currentValue=f,this.firstChange=m}isFirstChange(){return this.firstChange}}function Eo(){return ba}function ba(a){return a.type.prototype.ngOnChanges&&(a.setInput=tc),sl}function sl(){const a=bc(this),l=null==a?void 0:a.current;if(l){const f=a.previous;if(f===gr)a.previous=l;else for(let m in l)f[m]=l[m];a.current=null,this.ngOnChanges(l)}}function tc(a,l,f,m){const M=bc(a)||function(a,l){return a[Nu]=l}(a,{previous:gr,current:null}),k=M.current||(M.current={}),te=M.previous,le=this.declaredInputs[f],Ne=te[le];k[le]=new ko(Ne&&Ne.currentValue,l,te===gr),a[m]=l}Eo.ngInherit=!0;const Nu="__ngSimpleChanges__";function bc(a){return a[Nu]||null}let iu;function tl(a){iu=a}function Su(){return void 0!==iu?iu:"undefined"!=typeof document?document:void 0}function rt(a){return!!a.listen}const dt={createRenderer:(a,l)=>Su()};function Me(a){for(;Array.isArray(a);)a=a[0];return a}function ur(a,l){return Me(l[a])}function Qi(a,l){return Me(l[a.index])}function ms(a,l){return a.data[l]}function hs(a,l){return a[l]}function Ts(a,l){const f=l[a];return ca(f)?f:f[0]}function Ma(a){return 4==(4&a[2])}function au(a){return 128==(128&a[2])}function Rl(a,l){return null==l?null:a[l]}function nc(a){a[18]=0}function Al(a,l){a[5]+=l;let f=a,m=a[3];for(;null!==m&&(1===l&&1===f[5]||-1===l&&0===f[5]);)m[5]+=l,f=m,m=m[3]}const vs={lFrame:Or(null),bindingsEnabled:!0,isInCheckNoChangesMode:!1};function kc(){return vs.bindingsEnabled}function Li(){return vs.lFrame.lView}function sa(){return vs.lFrame.tView}function Aa(a){return vs.lFrame.contextLView=a,a[8]}function Ss(){let a=$u();for(;null!==a&&64===a.type;)a=a.parent;return a}function $u(){return vs.lFrame.currentTNode}function yl(){const a=vs.lFrame,l=a.currentTNode;return a.isParent?l:l.parent}function Mu(a,l){const f=vs.lFrame;f.currentTNode=a,f.isParent=l}function yu(){return vs.lFrame.isParent}function lu(){vs.lFrame.isParent=!1}function Uu(){return vs.isInCheckNoChangesMode}function Bo(a){vs.isInCheckNoChangesMode=a}function uu(){const a=vs.lFrame;let l=a.bindingRootIndex;return-1===l&&(l=a.bindingRootIndex=a.tView.bindingStartIndex),l}function wr(){return vs.lFrame.bindingIndex}function pu(){return vs.lFrame.bindingIndex++}function aa(a){const l=vs.lFrame,f=l.bindingIndex;return l.bindingIndex=l.bindingIndex+a,f}function bl(a){vs.lFrame.inI18n=a}function El(a,l){const f=vs.lFrame;f.bindingIndex=f.bindingRootIndex=a,ks(l)}function ks(a){vs.lFrame.currentDirectiveIndex=a}function V(a){const l=vs.lFrame.currentDirectiveIndex;return-1===l?null:a[l]}function Ae(){return vs.lFrame.currentQueryIndex}function st(a){vs.lFrame.currentQueryIndex=a}function vt(a){const l=a[1];return 2===l.type?l.declTNode:1===l.type?a[6]:null}function ut(a,l,f){if(f&Yr.SkipSelf){let M=l,k=a;for(;!(M=M.parent,null!==M||f&Yr.Host||(M=vt(k),null===M||(k=k[15],10&M.type))););if(null===M)return!1;l=M,a=k}const m=vs.lFrame=mn();return m.currentTNode=l,m.lView=a,!0}function un(a){const l=mn(),f=a[1];vs.lFrame=l,l.currentTNode=f.firstChild,l.lView=a,l.tView=f,l.contextLView=a,l.bindingIndex=f.bindingStartIndex,l.inI18n=!1}function mn(){const a=vs.lFrame,l=null===a?null:a.child;return null===l?Or(a):l}function Or(a){const l={currentTNode:null,isParent:!0,lView:null,tView:null,selectedIndex:-1,contextLView:null,elementDepthCount:0,currentNamespace:null,currentDirectiveIndex:-1,bindingRootIndex:-1,bindingIndex:-1,currentQueryIndex:0,parent:a,child:null,inI18n:!1};return null!==a&&(a.child=l),l}function zr(){const a=vs.lFrame;return vs.lFrame=a.parent,a.currentTNode=null,a.lView=null,a}const gi=zr;function ai(){const a=zr();a.isParent=!0,a.tView=null,a.selectedIndex=-1,a.contextLView=null,a.elementDepthCount=0,a.currentDirectiveIndex=-1,a.currentNamespace=null,a.bindingRootIndex=-1,a.bindingIndex=-1,a.currentQueryIndex=0}function In(){return vs.lFrame.selectedIndex}function Cr(a){vs.lFrame.selectedIndex=a}function hr(){const a=vs.lFrame;return ms(a.tView,a.selectedIndex)}function $c(a,l){for(let f=l.directiveStart,m=l.directiveEnd;f<m;f++){const k=a.data[f].type.prototype,{ngAfterContentInit:te,ngAfterContentChecked:le,ngAfterViewInit:Ne,ngAfterViewChecked:qe,ngOnDestroy:wt}=k;te&&(a.contentHooks||(a.contentHooks=[])).push(-f,te),le&&((a.contentHooks||(a.contentHooks=[])).push(f,le),(a.contentCheckHooks||(a.contentCheckHooks=[])).push(f,le)),Ne&&(a.viewHooks||(a.viewHooks=[])).push(-f,Ne),qe&&((a.viewHooks||(a.viewHooks=[])).push(f,qe),(a.viewCheckHooks||(a.viewCheckHooks=[])).push(f,qe)),null!=wt&&(a.destroyHooks||(a.destroyHooks=[])).push(f,wt)}}function Gl(a,l,f){pa(a,l,3,f)}function $i(a,l,f,m){(3&a[2])===f&&pa(a,l,f,m)}function xo(a,l){let f=a[2];(3&f)===l&&(f&=2047,f+=1,a[2]=f)}function pa(a,l,f,m){const k=null!=m?m:-1,te=l.length-1;let le=0;for(let Ne=void 0!==m?65535&a[18]:0;Ne<te;Ne++)if("number"==typeof l[Ne+1]){if(le=l[Ne],null!=m&&le>=m)break}else l[Ne]<0&&(a[18]+=65536),(le<k||-1==k)&&(hl(a,f,l,Ne),a[18]=(4294901760&a[18])+Ne+2),Ne++}function hl(a,l,f,m){const M=f[m]<0,k=f[m+1],le=a[M?-f[m]:f[m]];if(M){if(a[2]>>11<a[18]>>16&&(3&a[2])===l){a[2]+=2048;try{k.call(le)}finally{}}}else try{k.call(le)}finally{}}class Js{constructor(l,f,m){this.factory=l,this.resolving=!1,this.canSeeViewProviders=f,this.injectImpl=m}}function ic(a,l,f){const m=rt(a);let M=0;for(;M<f.length;){const k=f[M];if("number"==typeof k){if(0!==k)break;M++;const te=f[M++],le=f[M++],Ne=f[M++];m?a.setAttribute(l,le,Ne,te):l.setAttributeNS(te,le,Ne)}else{const te=k,le=f[++M];al(te)?m&&a.setProperty(l,te,le):m?a.setAttribute(l,te,le):l.setAttribute(te,le),M++}}return M}function df(a){return 3===a||4===a||6===a}function al(a){return 64===a.charCodeAt(0)}function Wd(a,l){if(null!==l&&0!==l.length)if(null===a||0===a.length)a=l.slice();else{let f=-1;for(let m=0;m<l.length;m++){const M=l[m];"number"==typeof M?f=M:0===f||Jd(a,f,M,null,-1===f||2===f?l[++m]:null)}}return a}function Jd(a,l,f,m,M){let k=0,te=a.length;if(-1===l)te=-1;else for(;k<a.length;){const le=a[k++];if("number"==typeof le){if(le===l){te=-1;break}if(le>l){te=k-1;break}}}for(;k<a.length;){const le=a[k];if("number"==typeof le)break;if(le===f){if(null===m)return void(null!==M&&(a[k+1]=M));if(m===a[k+1])return void(a[k+2]=M)}k++,null!==m&&k++,null!==M&&k++}-1!==te&&(a.splice(te,0,l),k=te+1),a.splice(k++,0,f),null!==m&&a.splice(k++,0,m),null!==M&&a.splice(k++,0,M)}function Ye(a){return-1!==a}function Ie(a){return 32767&a}function ot(a,l){let f=function(a){return a>>16}(a),m=l;for(;f>0;)m=m[15],f--;return m}let Et=!0;function qt(a){const l=Et;return Et=a,l}let Yo=0;function ns(a,l){const f=Hs(a,l);if(-1!==f)return f;const m=l[1];m.firstCreatePass&&(a.injectorIndex=l.length,Oa(m.data,a),Oa(l,null),Oa(m.blueprint,null));const M=fc(a,l),k=a.injectorIndex;if(Ye(M)){const te=Ie(M),le=ot(M,l),Ne=le[1].data;for(let qe=0;qe<8;qe++)l[k+qe]=le[te+qe]|Ne[te+qe]}return l[k+8]=M,k}function Oa(a,l){a.push(0,0,0,0,0,0,0,0,l)}function Hs(a,l){return-1===a.injectorIndex||a.parent&&a.parent.injectorIndex===a.injectorIndex||null===l[a.injectorIndex+8]?-1:a.injectorIndex}function fc(a,l){if(a.parent&&-1!==a.parent.injectorIndex)return a.parent.injectorIndex;let f=0,m=null,M=l;for(;null!==M;){const k=M[1],te=k.type;if(m=2===te?k.declTNode:1===te?M[6]:null,null===m)return-1;if(f++,M=M[15],-1!==m.injectorIndex)return m.injectorIndex|f<<16}return-1}function ga(a,l,f){!function(a,l,f){let m;"string"==typeof f?m=f.charCodeAt(0)||0:f.hasOwnProperty(Ge)&&(m=f[Ge]),null==m&&(m=f[Ge]=Yo++);const M=255&m;l.data[a+(M>>5)]|=1<<M}(a,l,f)}function ll(a,l,f){if(f&Yr.Optional)return a;ge(l,"NodeInjector")}function Za(a,l,f,m){if(f&Yr.Optional&&void 0===m&&(m=null),0==(f&(Yr.Self|Yr.Host))){const M=a[9],k=Hi(void 0);try{return M?M.get(l,m,f&Yr.Optional):Zr(l,m,f&Yr.Optional)}finally{Hi(k)}}return ll(m,l,f)}function ja(a,l,f,m=Yr.Default,M){if(null!==a){const k=function(a){if("string"==typeof a)return a.charCodeAt(0)||0;const l=a.hasOwnProperty(Ge)?a[Ge]:void 0;return"number"==typeof l?l>=0?255&l:Of:l}(f);if("function"==typeof k){if(!ut(l,a,m))return m&Yr.Host?ll(M,f,m):Za(l,f,m,M);try{const te=k(m);if(null!=te||m&Yr.Optional)return te;ge(f)}finally{gi()}}else if("number"==typeof k){let te=null,le=Hs(a,l),Ne=-1,qe=m&Yr.Host?l[16][6]:null;for((-1===le||m&Yr.SkipSelf)&&(Ne=-1===le?fc(a,l):l[le+8],-1!==Ne&&Xd(m,!1)?(te=l[1],le=Ie(Ne),l=ot(Ne,l)):le=-1);-1!==le;){const wt=l[1];if(Cc(k,le,wt.data)){const ln=Rd(le,l,f,te,m,qe);if(ln!==ul)return ln}Ne=l[le+8],-1!==Ne&&Xd(m,l[1].data[le+8]===qe)&&Cc(k,le,l)?(te=wt,le=Ie(Ne),l=ot(Ne,l)):le=-1}}}return Za(l,f,m,M)}const ul={};function Of(){return new jc(Ss(),Li())}function Rd(a,l,f,m,M,k){const te=l[1],le=te.data[a+8],wt=Qd(le,te,f,null==m?Il(le)&&Et:m!=te&&0!=(3&le.type),M&Yr.Host&&k===le);return null!==wt?Sc(l,te,wt,le):ul}function Qd(a,l,f,m,M){const k=a.providerIndexes,te=l.data,le=1048575&k,Ne=a.directiveStart,wt=k>>20,dn=M?le+wt:a.directiveEnd;for(let nr=m?le:le+wt;nr<dn;nr++){const Rr=te[nr];if(nr<Ne&&f===Rr||nr>=Ne&&Rr.type===f)return nr}if(M){const nr=te[Ne];if(nr&&Ya(nr)&&nr.type===f)return Ne}return null}function Sc(a,l,f,m){let M=a[f];const k=l.data;if(function(a){return a instanceof Js}(M)){const te=M;te.resolving&&function(a,l){throw new ee("200",`Circular dependency in DI detected for ${a}`)}(se(k[f]));const le=qt(te.canSeeViewProviders);te.resolving=!0;const Ne=te.injectImpl?Hi(te.injectImpl):null;ut(a,m,Yr.Default);try{M=a[f]=te.factory(void 0,k,a,m),l.firstCreatePass&&f>=m.directiveStart&&function(a,l,f){const{ngOnChanges:m,ngOnInit:M,ngDoCheck:k}=l.type.prototype;if(m){const te=ba(l);(f.preOrderHooks||(f.preOrderHooks=[])).push(a,te),(f.preOrderCheckHooks||(f.preOrderCheckHooks=[])).push(a,te)}M&&(f.preOrderHooks||(f.preOrderHooks=[])).push(0-a,M),k&&((f.preOrderHooks||(f.preOrderHooks=[])).push(a,k),(f.preOrderCheckHooks||(f.preOrderCheckHooks=[])).push(a,k))}(f,k[f],l)}finally{null!==Ne&&Hi(Ne),qt(le),te.resolving=!1,gi()}}return M}function Cc(a,l,f){return!!(f[l+(a>>5)]&1<<a)}function Xd(a,l){return!(a&Yr.Self||a&Yr.Host&&l)}class jc{constructor(l,f){this._tNode=l,this._lView=f}get(l,f,m){return ja(this._tNode,this._lView,l,m,f)}}function $f(a){return Wt(()=>{const l=a.prototype.constructor,f=l[_n]||Ju(l),m=Object.prototype;let M=Object.getPrototypeOf(a.prototype).constructor;for(;M&&M!==m;){const k=M[_n]||Ju(M);if(k&&k!==f)return k;M=Object.getPrototypeOf(M)}return k=>new k})}function Ju(a){return J(a)?()=>{const l=Ju(Z(a));return l&&l()}:wo(a)}function Sl(a){return function(a,l){if("class"===l)return a.classes;if("style"===l)return a.styles;const f=a.attrs;if(f){const m=f.length;let M=0;for(;M<m;){const k=f[M];if(df(k))break;if(0===k)M+=2;else if("number"==typeof k)for(M++;M<m&&"string"==typeof f[M];)M++;else{if(k===l)return f[M+1];M+=2}}}return null}(Ss(),a)}const kl="__parameters__",Pu="__prop__metadata__";function Qu(a){return function(...f){if(a){const m=a(...f);for(const M in m)this[M]=m[M]}}}function en(a,l,f){return Wt(()=>{const m=Qu(l);function M(...k){if(this instanceof M)return m.apply(this,k),this;const te=new M(...k);return le.annotation=te,le;function le(Ne,qe,wt){const ln=Ne.hasOwnProperty(kl)?Ne[kl]:Object.defineProperty(Ne,kl,{value:[]})[kl];for(;ln.length<=wt;)ln.push(null);return(ln[wt]=ln[wt]||[]).push(te),Ne}}return f&&(M.prototype=Object.create(f.prototype)),M.prototype.ngMetadataName=a,M.annotationCls=M,M})}function Oc(a,l,f,m){return Wt(()=>{const M=Qu(l);function k(...te){if(this instanceof k)return M.apply(this,te),this;const le=new k(...te);return function(qe,wt){const ln=qe.constructor,dn=ln.hasOwnProperty(Pu)?ln[Pu]:Object.defineProperty(ln,Pu,{value:{}})[Pu];dn[wt]=dn.hasOwnProperty(wt)&&dn[wt]||[],dn[wt].unshift(le),m&&m(qe,wt,...te)}}return f&&(k.prototype=Object.create(f.prototype)),k.prototype.ngMetadataName=a,k.annotationCls=k,k})}class Jl{constructor(l,f){this._desc=l,this.ngMetadataName="InjectionToken",this.\u0275prov=void 0,"number"==typeof f?this.__NG_ELEMENT_ID__=f:void 0!==f&&(this.\u0275prov=xt({token:this,providedIn:f.providedIn||"root",factory:f.factory}))}toString(){return`InjectionToken ${this._desc}`}}const vd=new Jl("AnalyzeForEntryComponents");class Gc{}const fp=Oc("ViewChild",(a,l)=>Object.assign({selector:a,first:!0,isViewQuery:!0,descendants:!0},l),Gc),Hf=Function;function Dc(a,l){void 0===l&&(l=a);for(let f=0;f<a.length;f++){let m=a[f];Array.isArray(m)?(l===a&&(l=a.slice(0,f)),Dc(m,l)):l!==a&&l.push(m)}return l}function Xl(a,l){a.forEach(f=>Array.isArray(f)?Xl(f,l):l(f))}function Ji(a,l,f){l>=a.length?a.push(f):a.splice(l,0,f)}function cl(a,l){return l>=a.length-1?a.pop():a.splice(l,1)[0]}function Ll(a,l){const f=[];for(let m=0;m<a;m++)f.push(l);return f}function Vl(a,l,f){let m=oc(a,l);return m>=0?a[1|m]=f:(m=~m,function(a,l,f,m){let M=a.length;if(M==l)a.push(f,m);else if(1===M)a.push(m,a[0]),a[0]=f;else{for(M--,a.push(a[M-1],a[M]);M>l;)a[M]=a[M-2],M--;a[l]=f,a[l+1]=m}}(a,m,l,f)),m}function Id(a,l){const f=oc(a,l);if(f>=0)return a[1|f]}function oc(a,l){return function(a,l,f){let m=0,M=a.length>>f;for(;M!==m;){const k=m+(M-m>>1),te=a[k<<f];if(l===te)return k<<f;te>l?M=k:m=k+1}return~(M<<f)}(a,l,1)}const R={},F="__NG_DI_FLAG__",q="ngTempTokenPath",ye=/\n/gm,Oe="__source",gt=_({provide:String,useValue:_});let yt;function nn(a){const l=yt;return yt=a,l}function Pn(a,l=Yr.Default){if(void 0===yt)throw new Error("inject() must be called from an injection context");return null===yt?Zr(a,void 0,l):yt.get(a,l&Yr.Optional?null:void 0,l)}function xn(a,l=Yr.Default){return(fi||Pn)(Z(a),l)}function Pi(a){const l=[];for(let f=0;f<a.length;f++){const m=Z(a[f]);if(Array.isArray(m)){if(0===m.length)throw new Error("Arguments array must have arguments.");let M,k=Yr.Default;for(let te=0;te<m.length;te++){const le=m[te],Ne=Lo(le);"number"==typeof Ne?-1===Ne?M=le.token:k|=Ne:M=le}l.push(xn(M,k))}else l.push(xn(m))}return l}function Zo(a,l){return a[F]=l,a.prototype[F]=l,a}function Lo(a){return a[F]}function Gs(a,l,f,m){const M=a[q];throw l[Oe]&&M.unshift(l[Oe]),a.message=function(a,l,f,m=null){a=a&&"\n"===a.charAt(0)&&"\u0275"==a.charAt(1)?a.substr(2):a;let M=S(l);if(Array.isArray(l))M=l.map(S).join(" -> ");else if("object"==typeof l){let k=[];for(let te in l)if(l.hasOwnProperty(te)){let le=l[te];k.push(te+":"+("string"==typeof le?JSON.stringify(le):S(le)))}M=`{${k.join(", ")}}`}return`${f}${m?"("+m+")":""}[${M}]: ${a.replace(ye,"\n ")}`}("\n"+a.message,M,f,m),a.ngTokenPath=M,a[q]=null,a}const ha=Zo(en("Inject",a=>({token:a})),-1),ia=Zo(en("Optional"),8),il=Zo(en("SkipSelf"),4);let na,Hp;function zl(a){var l;return(null===(l=function(){if(void 0===na&&(na=null,Dr.trustedTypes))try{na=Dr.trustedTypes.createPolicy("angular",{createHTML:a=>a,createScript:a=>a,createScriptURL:a=>a})}catch(a){}return na}())||void 0===l?void 0:l.createHTML(a))||a}function Up(){if(void 0===Hp&&(Hp=null,Dr.trustedTypes))try{Hp=Dr.trustedTypes.createPolicy("angular#unsafe-bypass",{createHTML:a=>a,createScript:a=>a,createScriptURL:a=>a})}catch(a){}return Hp}function mf(a){var l;return(null===(l=Up())||void 0===l?void 0:l.createHTML(a))||a}function dd(a){var l;return(null===(l=Up())||void 0===l?void 0:l.createScriptURL(a))||a}class Fd{constructor(l){this.changingThisBreaksApplicationSecurity=l}toString(){return`SafeValue must use [property]=binding: ${this.changingThisBreaksApplicationSecurity} (see https://g.co/ng/security#xss)`}}class pp extends Fd{getTypeName(){return"HTML"}}class fl extends Fd{getTypeName(){return"Style"}}class i_ extends Fd{getTypeName(){return"Script"}}class F_ extends Fd{getTypeName(){return"URL"}}class Bf extends Fd{getTypeName(){return"ResourceURL"}}function kd(a){return a instanceof Fd?a.changingThisBreaksApplicationSecurity:a}function Yf(a,l){const f=eh(a);if(null!=f&&f!==l){if("ResourceURL"===f&&"URL"===l)return!0;throw new Error(`Required a safe ${l}, got a ${f} (see https://g.co/ng/security#xss)`)}return f===l}function eh(a){return a instanceof Fd&&a.getTypeName()||null}function bd(a){return new pp(a)}function Rh(a){return new fl(a)}function th(a){return new i_(a)}function nh(a){return new F_(a)}function Nh(a){return new Bf(a)}function rh(a){const l=new xf(a);return function(){try{return!!(new window.DOMParser).parseFromString(zl(""),"text/html")}catch(a){return!1}}()?new Ed(l):l}class Ed{constructor(l){this.inertDocumentHelper=l}getInertBodyElement(l){l="<body><remove></remove>"+l;try{const f=(new window.DOMParser).parseFromString(zl(l),"text/html").body;return null===f?this.inertDocumentHelper.getInertBodyElement(l):(f.removeChild(f.firstChild),f)}catch(f){return null}}}class xf{constructor(l){if(this.defaultDoc=l,this.inertDocument=this.defaultDoc.implementation.createHTMLDocument("sanitization-inert"),null==this.inertDocument.body){const f=this.inertDocument.createElement("html");this.inertDocument.appendChild(f);const m=this.inertDocument.createElement("body");f.appendChild(m)}}getInertBodyElement(l){const f=this.inertDocument.createElement("template");if("content"in f)return f.innerHTML=zl(l),f;const m=this.inertDocument.createElement("body");return m.innerHTML=zl(l),this.defaultDoc.documentMode&&this.stripCustomNsAttrs(m),m}stripCustomNsAttrs(l){const f=l.attributes;for(let M=f.length-1;0<M;M--){const te=f.item(M).name;("xmlns:ns1"===te||0===te.indexOf("ns1:"))&&l.removeAttribute(te)}let m=l.firstChild;for(;m;)m.nodeType===Node.ELEMENT_NODE&&this.stripCustomNsAttrs(m),m=m.nextSibling}}const Bp=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^&:/?#]*(?:[/?#]|$))/gi,Ih=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+\/]+=*$/i;function vf(a){return(a=String(a)).match(Bp)||a.match(Ih)?a:"unsafe:"+a}function Lh(a){return(a=String(a)).split(",").map(l=>vf(l.trim())).join(", ")}function $d(a){const l={};for(const f of a.split(","))l[f]=!0;return l}function hp(...a){const l={};for(const f of a)for(const m in f)f.hasOwnProperty(m)&&(l[m]=!0);return l}const Zf=$d("area,br,col,hr,img,wbr"),qd=$d("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),ac=$d("rp,rt"),Y=hp(Zf,hp(qd,$d("address,article,aside,blockquote,caption,center,del,details,dialog,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,main,map,menu,nav,ol,pre,section,summary,table,ul")),hp(ac,$d("a,abbr,acronym,audio,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,picture,q,ruby,rp,rt,s,samp,small,source,span,strike,strong,sub,sup,time,track,tt,u,var,video")),hp(ac,qd)),fe=$d("background,cite,href,itemtype,longdesc,poster,src,xlink:href"),w=$d("srcset"),ct=hp(fe,w,$d("abbr,accesskey,align,alt,autoplay,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,controls,coords,datetime,default,dir,download,face,headers,height,hidden,hreflang,hspace,ismap,itemscope,itemprop,kind,label,lang,language,loop,media,muted,nohref,nowrap,open,preload,rel,rev,role,rows,rowspan,rules,scope,scrolling,shape,size,sizes,span,srclang,start,summary,tabindex,target,title,translate,type,usemap,valign,value,vspace,width"),$d("aria-activedescendant,aria-atomic,aria-autocomplete,aria-busy,aria-checked,aria-colcount,aria-colindex,aria-colspan,aria-controls,aria-current,aria-describedby,aria-details,aria-disabled,aria-dropeffect,aria-errormessage,aria-expanded,aria-flowto,aria-grabbed,aria-haspopup,aria-hidden,aria-invalid,aria-keyshortcuts,aria-label,aria-labelledby,aria-level,aria-live,aria-modal,aria-multiline,aria-multiselectable,aria-orientation,aria-owns,aria-placeholder,aria-posinset,aria-pressed,aria-readonly,aria-relevant,aria-required,aria-roledescription,aria-rowcount,aria-rowindex,aria-rowspan,aria-selected,aria-setsize,aria-sort,aria-valuemax,aria-valuemin,aria-valuenow,aria-valuetext")),Jn=$d("script,style,template");class Ir{constructor(){this.sanitizedSomething=!1,this.buf=[]}sanitizeChildren(l){let f=l.firstChild,m=!0;for(;f;)if(f.nodeType===Node.ELEMENT_NODE?m=this.startElement(f):f.nodeType===Node.TEXT_NODE?this.chars(f.nodeValue):this.sanitizedSomething=!0,m&&f.firstChild)f=f.firstChild;else for(;f;){f.nodeType===Node.ELEMENT_NODE&&this.endElement(f);let M=this.checkClobberedElement(f,f.nextSibling);if(M){f=M;break}f=this.checkClobberedElement(f,f.parentNode)}return this.buf.join("")}startElement(l){const f=l.nodeName.toLowerCase();if(!Y.hasOwnProperty(f))return this.sanitizedSomething=!0,!Jn.hasOwnProperty(f);this.buf.push("<"),this.buf.push(f);const m=l.attributes;for(let M=0;M<m.length;M++){const k=m.item(M),te=k.name,le=te.toLowerCase();if(!ct.hasOwnProperty(le)){this.sanitizedSomething=!0;continue}let Ne=k.value;fe[le]&&(Ne=vf(Ne)),w[le]&&(Ne=Lh(Ne)),this.buf.push(" ",te,'="',Do(Ne),'"')}return this.buf.push(">"),!0}endElement(l){const f=l.nodeName.toLowerCase();Y.hasOwnProperty(f)&&!Zf.hasOwnProperty(f)&&(this.buf.push("</"),this.buf.push(f),this.buf.push(">"))}chars(l){this.buf.push(Do(l))}checkClobberedElement(l,f){if(f&&(l.compareDocumentPosition(f)&Node.DOCUMENT_POSITION_CONTAINED_BY)===Node.DOCUMENT_POSITION_CONTAINED_BY)throw new Error(`Failed to sanitize html because the element is clobbered: ${l.outerHTML}`);return f}}const vi=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,zi=/([^\#-~ |!])/g;function Do(a){return a.replace(/&/g,"&amp;").replace(vi,function(l){return"&#"+(1024*(l.charCodeAt(0)-55296)+(l.charCodeAt(1)-56320)+65536)+";"}).replace(zi,function(l){return"&#"+l.charCodeAt(0)+";"}).replace(/</g,"&lt;").replace(/>/g,"&gt;")}let xs;function Xo(a,l){let f=null;try{xs=xs||rh(a);let m=l?String(l):"";f=xs.getInertBodyElement(m);let M=5,k=m;do{if(0===M)throw new Error("Failed to sanitize html because the input is unstable");M--,m=k,k=f.innerHTML,f=xs.getInertBodyElement(m)}while(m!==k);return zl((new Ir).sanitizeChildren(Rs(f)||f))}finally{if(f){const m=Rs(f)||f;for(;m.firstChild;)m.removeChild(m.firstChild)}}}function Rs(a){return"content"in a&&function(a){return a.nodeType===Node.ELEMENT_NODE&&"TEMPLATE"===a.nodeName}(a)?a.content:null}var Vs=(()=>((Vs=Vs||{})[Vs.NONE=0]="NONE",Vs[Vs.HTML=1]="HTML",Vs[Vs.STYLE=2]="STYLE",Vs[Vs.SCRIPT=3]="SCRIPT",Vs[Vs.URL=4]="URL",Vs[Vs.RESOURCE_URL=5]="RESOURCE_URL",Vs))();function _c(a){const l=gp();return l?mf(l.sanitize(Vs.HTML,a)||""):Yf(a,"HTML")?mf(kd(a)):Xo(Su(),H(a))}function wu(a){const l=gp();return l?l.sanitize(Vs.URL,a)||"":Yf(a,"URL")?kd(a):vf(H(a))}function Hd(a){const l=gp();if(l)return dd(l.sanitize(Vs.RESOURCE_URL,a)||"");if(Yf(a,"ResourceURL"))return dd(kd(a));throw new Error("unsafe value used in a resource URL context (see https://g.co/ng/security#xss)")}function gp(){const a=Li();return a&&a[12]}const B_="__ngContext__";function Wc(a,l){a[B_]=l}function a_(a){const l=function(a){return a[B_]||null}(a);return l?Array.isArray(l)?l:l.lView:null}function Zu(a){return a.ngOriginalError}function Yp(a,...l){a.error(...l)}class Gf{constructor(){this._console=console}handleError(l){const f=this._findOriginalError(l),m=this._findContext(l),M=(a=l)&&a.ngErrorLogger||Yp;var a;M(this._console,"ERROR",l),f&&M(this._console,"ORIGINAL ERROR",f),m&&M(this._console,"ERROR CONTEXT",m)}_findContext(l){return l?l.ngDebugContext||this._findContext(Zu(l)):null}_findOriginalError(l){let f=l&&Zu(l);for(;f&&Zu(f);)f=Zu(f);return f||null}}const Z_=/^>|^->|<!--|-->|--!>|<!-$/g,j_=/(<|>)/;const Hh=(()=>("undefined"!=typeof requestAnimationFrame&&requestAnimationFrame||setTimeout).bind(Dr))();function Uh(a){return a.ownerDocument.defaultView}function Vf(a){return a.ownerDocument.body}function yf(a){return a instanceof Function?a():a}var Bd=(()=>((Bd=Bd||{})[Bd.Important=1]="Important",Bd[Bd.DashCase=2]="DashCase",Bd))();let fd;function bf(a,l){return fd(a,l)}function od(a){const l=a[3];return $s(l)?l[3]:l}function np(a){return fh(a[13])}function V_(a){return fh(a[4])}function fh(a){for(;null!==a&&!$s(a);)a=a[4];return a}function Bc(a,l,f,m,M){if(null!=m){let k,te=!1;$s(m)?k=m:ca(m)&&(te=!0,m=m[0]);const le=Me(m);0===a&&null!==f?null==M?Bg(l,f,le):_h(l,f,le,M||null,!0):1===a&&null!==f?_h(l,f,le,M||null,!0):2===a?y_(l,le,te):3===a&&l.destroyNode(le),null!=k&&function(a,l,f,m,M){const k=f[7];k!==Me(f)&&Bc(l,a,m,k,M);for(let le=10;le<f.length;le++){const Ne=f[le];jh(Ne[1],Ne,a,l,m,k)}}(l,a,k,f,M)}}function Rf(a,l){return rt(a)?a.createText(l):a.createTextNode(l)}function ph(a,l,f){rt(a)?a.setValue(l,f):l.textContent=f}function _g(a,l){return a.createComment(function(a){return a.replace(Z_,l=>l.replace(j_,"\u200b$1\u200b"))}(l))}function Bh(a,l,f){return rt(a)?a.createElement(l,f):null===f?a.createElement(l):a.createElementNS(f,l)}function Hg(a,l){const f=a[9],m=f.indexOf(l),M=l[3];1024&l[2]&&(l[2]&=-1025,Al(M,-1)),f.splice(m,1)}function gg(a,l){if(a.length<=10)return;const f=10+l,m=a[f];if(m){const M=m[17];null!==M&&M!==a&&Hg(M,m),l>0&&(a[f-1][4]=m[4]);const k=cl(a,10+l);!function(a,l){jh(a,l,l[11],2,null,null),l[0]=null,l[6]=null}(m[1],m);const te=k[19];null!==te&&te.detachView(k[1]),m[3]=null,m[4]=null,m[2]&=-129}return m}function Ep(a,l){if(!(256&l[2])){const f=l[11];rt(f)&&f.destroyNode&&jh(a,l,f,3,null,null),function(a){let l=a[13];if(!l)return mg(a[1],a);for(;l;){let f=null;if(ca(l))f=l[13];else{const m=l[10];m&&(f=m)}if(!f){for(;l&&!l[4]&&l!==a;)ca(l)&&mg(l[1],l),l=l[3];null===l&&(l=a),ca(l)&&mg(l[1],l),f=l&&l[4]}l=f}}(l)}}function mg(a,l){if(!(256&l[2])){l[2]&=-129,l[2]|=256,function(a,l){let f;if(null!=a&&null!=(f=a.destroyHooks))for(let m=0;m<f.length;m+=2){const M=l[f[m]];if(!(M instanceof Js)){const k=f[m+1];if(Array.isArray(k))for(let te=0;te<k.length;te+=2){const le=M[k[te]],Ne=k[te+1];try{Ne.call(le)}finally{}}else try{k.call(M)}finally{}}}}(a,l),function(a,l){const f=a.cleanup,m=l[7];let M=-1;if(null!==f)for(let k=0;k<f.length-1;k+=2)if("string"==typeof f[k]){const te=f[k+1],le="function"==typeof te?te(l):Me(l[te]),Ne=m[M=f[k+2]],qe=f[k+3];"boolean"==typeof qe?le.removeEventListener(f[k],Ne,qe):qe>=0?m[M=qe]():m[M=-qe].unsubscribe(),k+=2}else{const te=m[M=f[k+1]];f[k].call(te)}if(null!==m){for(let k=M+1;k<m.length;k++)m[k]();l[7]=null}}(a,l),1===l[1].type&&rt(l[11])&&l[11].destroy();const f=l[17];if(null!==f&&$s(l[3])){f!==l[3]&&Hg(f,l);const m=l[19];null!==m&&m.detachView(a)}}}function z_(a,l,f){return Tp(a,l.parent,f)}function Tp(a,l,f){let m=l;for(;null!==m&&40&m.type;)m=(l=m).parent;if(null===m)return f[0];if(2&m.flags){const M=a.data[m.directiveStart].encapsulation;if(M===Gn.None||M===Gn.Emulated)return null}return Qi(m,f)}function _h(a,l,f,m,M){rt(a)?a.insertBefore(l,f,m,M):l.insertBefore(f,m,M)}function Bg(a,l,f){rt(a)?a.appendChild(l,f):l.appendChild(f)}function W_(a,l,f,m,M){null!==m?_h(a,l,f,m,M):Bg(a,l,f)}function Yd(a,l){return rt(a)?a.parentNode(l):l.parentNode}function Yg(a,l,f){return v_(a,l,f)}function Sp(a,l,f){return 40&a.type?Qi(a,f):null}let Jc,v_=Sp;function J_(a,l){v_=a,Jc=l}function Yh(a,l,f,m){const M=z_(a,m,l),k=l[11],le=Yg(m.parent||l[6],m,l);if(null!=M)if(Array.isArray(f))for(let Ne=0;Ne<f.length;Ne++)W_(k,M,f[Ne],le,!1);else W_(k,M,f,le,!1);void 0!==Jc&&Jc(k,m,l,f,M)}function Zh(a,l){if(null!==l){const f=l.type;if(3&f)return Qi(l,a);if(4&f)return Eg(-1,a[l.index]);if(8&f){const m=l.child;if(null!==m)return Zh(a,m);{const M=a[l.index];return $s(M)?Eg(-1,M):Me(M)}}if(32&f)return bf(l,a)()||Me(a[l.index]);{const m=bg(a,l);return null!==m?Array.isArray(m)?m[0]:Zh(od(a[16]),m):Zh(a,l.next)}}return null}function bg(a,l){return null!==l?a[16][6].projection[l.projection]:null}function Eg(a,l){const f=10+a+1;if(f<l.length){const m=l[f],M=m[1].firstChild;if(null!==M)return Zh(m,M)}return l[7]}function y_(a,l,f){const m=Yd(a,l);m&&function(a,l,f,m){rt(a)?a.removeChild(l,f,m):l.removeChild(f)}(a,m,l,f)}function b_(a,l,f,m,M,k,te){for(;null!=f;){const le=m[f.index],Ne=f.type;if(te&&0===l&&(le&&Wc(Me(le),m),f.flags|=4),64!=(64&f.flags))if(8&Ne)b_(a,l,f.child,m,M,k,!1),Bc(l,a,M,le,k);else if(32&Ne){const qe=bf(f,m);let wt;for(;wt=qe();)Bc(l,a,M,wt,k);Bc(l,a,M,le,k)}else 16&Ne?jp(a,l,m,f,M,k):Bc(l,a,M,le,k);f=te?f.projectionNext:f.next}}function jh(a,l,f,m,M,k){b_(f,m,a.firstChild,l,M,k,!1)}function jp(a,l,f,m,M,k){const te=f[16],Ne=te[6].projection[m.projection];if(Array.isArray(Ne))for(let qe=0;qe<Ne.length;qe++)Bc(l,a,M,Ne[qe],k);else b_(a,l,Ne,te[3],M,k,!0)}function Zg(a,l,f){rt(a)?a.setAttribute(l,"style",f):l.style.cssText=f}function Gh(a,l,f){rt(a)?""===f?a.removeAttribute(l,"class"):a.setAttribute(l,"class",f):l.className=f}function Sg(a,l,f){let m=a.length;for(;;){const M=a.indexOf(l,f);if(-1===M)return M;if(0===M||a.charCodeAt(M-1)<=32){const k=l.length;if(M+k===m||a.charCodeAt(M+k)<=32)return M}f=M+1}}const Vh="ng-template";function Tm(a,l,f){let m=0;for(;m<a.length;){let M=a[m++];if(f&&"class"===M){if(M=a[m],-1!==Sg(M.toLowerCase(),l,0))return!0}else if(1===M){for(;m<a.length&&"string"==typeof(M=a[m++]);)if(M.toLowerCase()===l)return!0;return!1}}return!1}function S_(a){return 4===a.type&&a.value!==Vh}function b(a,l,f){return l===(4!==a.type||f?a.value:Vh)}function x(a,l,f){let m=4;const M=a.attrs||[],k=function(a){for(let l=0;l<a.length;l++)if(df(a[l]))return l;return a.length}(M);let te=!1;for(let le=0;le<l.length;le++){const Ne=l[le];if("number"!=typeof Ne){if(!te)if(4&m){if(m=2|1&m,""!==Ne&&!b(a,Ne,f)||""===Ne&&1===l.length){if(G(m))return!1;te=!0}}else{const qe=8&m?Ne:l[++le];if(8&m&&null!==a.attrs){if(!Tm(a.attrs,qe,f)){if(G(m))return!1;te=!0}continue}const ln=Se(8&m?"class":Ne,M,S_(a),f);if(-1===ln){if(G(m))return!1;te=!0;continue}if(""!==qe){let dn;dn=ln>k?"":M[ln+1].toLowerCase();const nr=8&m?dn:null;if(nr&&-1!==Sg(nr,qe,0)||2&m&&qe!==dn){if(G(m))return!1;te=!0}}}}else{if(!te&&!G(m)&&!G(Ne))return!1;if(te&&G(Ne))continue;te=!1,m=Ne|1&m}}return G(m)||te}function G(a){return 0==(1&a)}function Se(a,l,f,m){if(null===l)return-1;let M=0;if(m||!f){let k=!1;for(;M<l.length;){const te=l[M];if(te===a)return M;if(3===te||6===te)k=!0;else{if(1===te||2===te){let le=l[++M];for(;"string"==typeof le;)le=l[++M];continue}if(4===te)break;if(0===te){M+=4;continue}}M+=k?1:2}return-1}return function(a,l){let f=a.indexOf(4);if(f>-1)for(f++;f<a.length;){const m=a[f];if("number"==typeof m)return-1;if(m===l)return f;f++}return-1}(l,a)}function We(a,l,f=!1){for(let m=0;m<l.length;m++)if(x(a,l[m],f))return!0;return!1}function yr(a,l){e:for(let f=0;f<l.length;f++){const m=l[f];if(a.length===m.length){for(let M=0;M<a.length;M++)if(a[M]!==m[M])continue e;return!0}}return!1}function Si(a,l){return a?":not("+l.trim()+")":l}function as(a){let l=a[0],f=1,m=2,M="",k=!1;for(;f<a.length;){let te=a[f];if("string"==typeof te)if(2&m){const le=a[++f];M+="["+te+(le.length>0?'="'+le+'"':"")+"]"}else 8&m?M+="."+te:4&m&&(M+=" "+te);else""!==M&&!G(te)&&(l+=Si(k,M),M=""),m=te,k=k||!G(m);f++}return""!==M&&(l+=Si(k,M)),l}const po={};function Fa(a){Ta(sa(),Li(),In()+a,Uu())}function Ta(a,l,f,m){if(!m)if(3==(3&l[2])){const k=a.preOrderCheckHooks;null!==k&&Gl(l,k,f)}else{const k=a.preOrderHooks;null!==k&&$i(l,k,0,f)}Cr(f)}function ni(a,l){return a<<17|l<<2}function Tr(a){return a>>17&32767}function io(a){return 2|a}function va(a){return(131068&a)>>2}function Cs(a,l){return-131069&a|l<<2}function xl(a){return 1|a}function hv(a,l){const f=a.contentQueries;if(null!==f)for(let m=0;m<f.length;m+=2){const M=f[m],k=f[m+1];if(-1!==k){const te=a.data[k];st(M),te.contentQueries(2,l[k],k)}}}function Ap(a,l,f,m,M,k,te,le,Ne,qe){const wt=l.blueprint.slice();return wt[0]=M,wt[2]=140|m,nc(wt),wt[3]=wt[15]=a,wt[8]=f,wt[10]=te||a&&a[10],wt[11]=le||a&&a[11],wt[12]=Ne||a&&a[12]||null,wt[9]=qe||a&&a[9]||null,wt[6]=k,wt[16]=2==l.type?a[16]:wt,wt}function ip(a,l,f,m,M){let k=a.data[l];if(null===k)k=Jh(a,l,f,m,M),vs.lFrame.inI18n&&(k.flags|=64);else if(64&k.type){k.type=f,k.value=m,k.attrs=M;const te=yl();k.injectorIndex=null===te?-1:te.injectorIndex}return Mu(k,!0),k}function Jh(a,l,f,m,M){const k=$u(),te=yu(),Ne=a.data[l]=function(a,l,f,m,M,k){return{type:f,index:m,insertBeforeIndex:null,injectorIndex:l?l.injectorIndex:-1,directiveStart:-1,directiveEnd:-1,directiveStylingLast:-1,propertyBindings:null,flags:0,providerIndexes:0,value:M,attrs:k,mergedAttrs:null,localNames:null,initialInputs:void 0,inputs:null,outputs:null,tViews:null,next:null,projectionNext:null,child:null,parent:l,projection:null,styles:null,stylesWithoutHost:null,residualStyles:void 0,classes:null,classesWithoutHost:null,residualClasses:void 0,classBindings:0,styleBindings:0}}(0,te?k:k&&k.parent,f,l,m,M);return null===a.firstChild&&(a.firstChild=Ne),null!==k&&(te?null==k.child&&null!==Ne.parent&&(k.child=Ne):null===k.next&&(k.next=Ne)),Ne}function Vp(a,l,f,m){if(0===f)return-1;const M=l.length;for(let k=0;k<f;k++)l.push(m),a.blueprint.push(m),a.data.push(null);return M}function X_(a,l,f){un(l);try{const m=a.viewQuery;null!==m&&Ef(1,m,f);const M=a.template;null!==M&&Dm(a,l,M,1,f),a.firstCreatePass&&(a.firstCreatePass=!1),a.staticContentQueries&&hv(a,l),a.staticViewQueries&&Ef(2,a.viewQuery,f);const k=a.components;null!==k&&function(a,l){for(let f=0;f<l.length;f++)Nm(a,l[f])}(l,k)}catch(m){throw a.firstCreatePass&&(a.incompleteFirstPass=!0,a.firstCreatePass=!1),m}finally{l[2]&=-5,ai()}}function C_(a,l,f,m){const M=l[2];if(256==(256&M))return;un(l);const k=Uu();try{nc(l),function(a){vs.lFrame.bindingIndex=a}(a.bindingStartIndex),null!==f&&Dm(a,l,f,2,m);const te=3==(3&M);if(!k)if(te){const qe=a.preOrderCheckHooks;null!==qe&&Gl(l,qe,null)}else{const qe=a.preOrderHooks;null!==qe&&$i(l,qe,0,null),xo(l,0)}if(function(a){for(let l=np(a);null!==l;l=V_(l)){if(!l[2])continue;const f=l[9];for(let m=0;m<f.length;m++){const M=f[m],k=M[3];0==(1024&M[2])&&Al(k,1),M[2]|=1024}}}(l),function(a){for(let l=np(a);null!==l;l=V_(l))for(let f=10;f<l.length;f++){const m=l[f],M=m[1];au(m)&&C_(M,m,M.template,m[8])}}(l),null!==a.contentQueries&&hv(a,l),!k)if(te){const qe=a.contentCheckHooks;null!==qe&&Gl(l,qe)}else{const qe=a.contentHooks;null!==qe&&$i(l,qe,1),xo(l,1)}!function(a,l){const f=a.hostBindingOpCodes;if(null!==f)try{for(let m=0;m<f.length;m++){const M=f[m];if(M<0)Cr(~M);else{const k=M,te=f[++m],le=f[++m];El(te,k),le(2,l[k])}}}finally{Cr(-1)}}(a,l);const le=a.components;null!==le&&function(a,l){for(let f=0;f<l.length;f++)p1(a,l[f])}(l,le);const Ne=a.viewQuery;if(null!==Ne&&Ef(2,Ne,m),!k)if(te){const qe=a.viewCheckHooks;null!==qe&&Gl(l,qe)}else{const qe=a.viewHooks;null!==qe&&$i(l,qe,2),xo(l,2)}!0===a.firstUpdatePass&&(a.firstUpdatePass=!1),k||(l[2]&=-73),1024&l[2]&&(l[2]&=-1025,Al(l[3],-1))}finally{ai()}}function xm(a,l,f,m){const M=l[10],k=!Uu(),te=Ma(l);try{k&&!te&&M.begin&&M.begin(),te&&X_(a,l,m),C_(a,l,f,m)}finally{k&&!te&&M.end&&M.end()}}function Dm(a,l,f,m,M){const k=In(),te=2&m;try{Cr(-1),te&&l.length>20&&Ta(a,l,20,Uu()),f(m,M)}finally{Cr(k)}}function c1(a,l,f){if(da(l)){const M=l.directiveEnd;for(let k=l.directiveStart;k<M;k++){const te=a.data[k];te.contentQueries&&te.contentQueries(1,f[k],k)}}}function Rm(a,l,f){!kc()||(function(a,l,f,m){const M=f.directiveStart,k=f.directiveEnd;a.firstCreatePass||ns(f,l),Wc(m,l);const te=f.initialInputs;for(let le=M;le<k;le++){const Ne=a.data[le],qe=Ya(Ne);qe&&gb(l,f,Ne);const wt=Sc(l,a,le,f);Wc(wt,l),null!==te&&mb(0,le-M,wt,Ne,0,te),qe&&(Ts(f.index,l)[8]=wt)}}(a,l,f,Qi(f,l)),128==(128&f.flags)&&function(a,l,f){const m=f.directiveStart,M=f.directiveEnd,te=f.index,le=vs.lFrame.currentDirectiveIndex;try{Cr(te);for(let Ne=m;Ne<M;Ne++){const qe=a.data[Ne],wt=l[Ne];ks(Ne),(null!==qe.hostBindings||0!==qe.hostVars||null!==qe.hostAttrs)&&Qc(qe,wt)}}finally{Cr(-1),ks(le)}}(a,l,f))}function Vg(a,l,f=Qi){const m=l.localNames;if(null!==m){let M=l.index+1;for(let k=0;k<m.length;k+=2){const te=m[k+1],le=-1===te?f(l,a):a[te];a[M++]=le}}}function _v(a){const l=a.tView;return null===l||l.incompleteFirstPass?a.tView=zg(1,null,a.template,a.decls,a.vars,a.directiveDefs,a.pipeDefs,a.viewQuery,a.schemas,a.consts):l}function zg(a,l,f,m,M,k,te,le,Ne,qe){const wt=20+m,ln=wt+M,dn=function(a,l){const f=[];for(let m=0;m<l;m++)f.push(m<a?null:po);return f}(wt,ln),nr="function"==typeof qe?qe():qe;return dn[1]={type:a,blueprint:dn,template:f,queries:null,viewQuery:le,declTNode:l,data:dn.slice().fill(null,wt),bindingStartIndex:wt,expandoStartIndex:ln,hostBindingOpCodes:null,firstCreatePass:!0,firstUpdatePass:!0,staticViewQueries:!1,staticContentQueries:!1,preOrderHooks:null,preOrderCheckHooks:null,contentHooks:null,contentCheckHooks:null,viewHooks:null,viewCheckHooks:null,destroyHooks:null,cleanup:null,contentQueries:null,components:null,directiveRegistry:"function"==typeof k?k():k,pipeRegistry:"function"==typeof te?te():te,firstChild:null,schemas:Ne,consts:nr,incompleteFirstPass:!1}}function at(a,l,f,m){const M=Vu(l);null===f?M.push(m):(M.push(f),a.firstCreatePass&&yb(a).push(m,M.length-1))}function jn(a,l,f){for(let m in a)if(a.hasOwnProperty(m)){const M=a[m];(f=null===f?{}:f).hasOwnProperty(m)?f[m].push(l,M):f[m]=[l,M]}return f}function Ro(a,l,f,m,M,k,te,le){const Ne=Qi(l,f);let wt,qe=l.inputs;!le&&null!=qe&&(wt=qe[m])?(bb(a,f,wt,m,M),Il(l)&&function(a,l){const f=Ts(l,a);16&f[2]||(f[2]|=64)}(f,l.index)):3&l.type&&(m=function(a){return"class"===a?"className":"for"===a?"htmlFor":"formaction"===a?"formAction":"innerHtml"===a?"innerHTML":"readonly"===a?"readOnly":"tabindex"===a?"tabIndex":a}(m),M=null!=te?te(M,l.value||"",m):M,rt(k)?k.setProperty(Ne,m,M):al(m)||(Ne.setProperty?Ne.setProperty(m,M):Ne[m]=M))}function Cd(a,l,f,m){let M=!1;if(kc()){const k=function(a,l,f){const m=a.directiveRegistry;let M=null;if(m)for(let k=0;k<m.length;k++){const te=m[k];We(f,te.selectors,!1)&&(M||(M=[]),ga(ns(f,l),a,te.type),Ya(te)?(ju(a,f),M.unshift(te)):M.push(te))}return M}(a,l,f),te=null===m?null:{"":-1};if(null!==k){M=!0,R0(f,a.data.length,k.length);for(let wt=0;wt<k.length;wt++){const ln=k[wt];ln.providersResolver&&ln.providersResolver(ln)}let le=!1,Ne=!1,qe=Vp(a,l,k.length,null);for(let wt=0;wt<k.length;wt++){const ln=k[wt];f.mergedAttrs=Wd(f.mergedAttrs,ln.hostAttrs),N0(a,f,l,qe,ln),D0(qe,ln,te),null!==ln.contentQueries&&(f.flags|=8),(null!==ln.hostBindings||null!==ln.hostAttrs||0!==ln.hostVars)&&(f.flags|=128);const dn=ln.type.prototype;!le&&(dn.ngOnChanges||dn.ngOnInit||dn.ngDoCheck)&&((a.preOrderHooks||(a.preOrderHooks=[])).push(f.index),le=!0),!Ne&&(dn.ngOnChanges||dn.ngDoCheck)&&((a.preOrderCheckHooks||(a.preOrderCheckHooks=[])).push(f.index),Ne=!0),qe++}!function(a,l){const m=l.directiveEnd,M=a.data,k=l.attrs,te=[];let le=null,Ne=null;for(let qe=l.directiveStart;qe<m;qe++){const wt=M[qe],ln=wt.inputs,dn=null===k||S_(l)?null:P0(ln,k);te.push(dn),le=jn(ln,qe,le),Ne=jn(wt.outputs,qe,Ne)}null!==le&&(le.hasOwnProperty("class")&&(l.flags|=16),le.hasOwnProperty("style")&&(l.flags|=32)),l.initialInputs=te,l.inputs=le,l.outputs=Ne}(a,f)}te&&function(a,l,f){if(l){const m=a.localNames=[];for(let M=0;M<l.length;M+=2){const k=f[l[M+1]];if(null==k)throw new ee("301",`Export of name '${l[M+1]}' not found!`);m.push(l[M],k)}}}(f,m,te)}return f.mergedAttrs=Wd(f.mergedAttrs,f.attrs),M}function Op(a,l,f,m,M,k){const te=k.hostBindings;if(te){let le=a.hostBindingOpCodes;null===le&&(le=a.hostBindingOpCodes=[]);const Ne=~l.index;(function(a){let l=a.length;for(;l>0;){const f=a[--l];if("number"==typeof f&&f<0)return f}return 0})(le)!=Ne&&le.push(Ne),le.push(m,M,te)}}function Qc(a,l){null!==a.hostBindings&&a.hostBindings(1,l)}function ju(a,l){l.flags|=2,(a.components||(a.components=[])).push(l.index)}function D0(a,l,f){if(f){if(l.exportAs)for(let m=0;m<l.exportAs.length;m++)f[l.exportAs[m]]=a;Ya(l)&&(f[""]=a)}}function R0(a,l,f){a.flags|=1,a.directiveStart=l,a.directiveEnd=l+f,a.providerIndexes=l}function N0(a,l,f,m,M){a.data[m]=M;const k=M.factory||(M.factory=wo(M.type)),te=new Js(k,Ya(M),null);a.blueprint[m]=te,f[m]=te,Op(a,l,0,m,Vp(a,f,M.hostVars,po),M)}function gb(a,l,f){const m=Qi(l,a),M=_v(f),k=a[10],te=h1(a,Ap(a,M,null,f.onPush?64:16,m,l,k,k.createRenderer(m,f),null,null));a[l.index]=te}function d1(a,l,f,m,M,k,te){if(null==k)rt(a)?a.removeAttribute(l,M,f):l.removeAttribute(M);else{const le=null==te?H(k):te(k,m||"",M);rt(a)?a.setAttribute(l,M,le,f):f?l.setAttributeNS(f,M,le):l.setAttribute(M,le)}}function mb(a,l,f,m,M,k){const te=k[l];if(null!==te){const le=m.setInput;for(let Ne=0;Ne<te.length;){const qe=te[Ne++],wt=te[Ne++],ln=te[Ne++];null!==le?m.setInput(f,ln,qe,wt):f[wt]=ln}}}function P0(a,l){let f=null,m=0;for(;m<l.length;){const M=l[m];if(0!==M)if(5!==M){if("number"==typeof M)break;a.hasOwnProperty(M)&&(null===f&&(f=[]),f.push(M,a[M],l[m+1])),m+=2}else m+=2;else m+=4}return f}function Wg(a,l,f,m){return new Array(a,!0,!1,l,null,0,m,f,null,null)}function p1(a,l){const f=Ts(l,a);if(au(f)){const m=f[1];80&f[2]?C_(m,f,m.template,f[8]):f[5]>0&&Gu(f)}}function Gu(a){for(let m=np(a);null!==m;m=V_(m))for(let M=10;M<m.length;M++){const k=m[M];if(1024&k[2]){const te=k[1];C_(te,k,te.template,k[8])}else k[5]>0&&Gu(k)}const f=a[1].components;if(null!==f)for(let m=0;m<f.length;m++){const M=Ts(f[m],a);au(M)&&M[5]>0&&Gu(M)}}function Nm(a,l){const f=Ts(l,a),m=f[1];(function(a,l){for(let f=l.length;f<a.blueprint.length;f++)l.push(a.blueprint[f])})(m,f),X_(m,f,f[8])}function h1(a,l){return a[13]?a[14][4]=l:a[13]=l,a[14]=l,l}function I0(a){for(;a;){a[2]|=64;const l=od(a);if(Ao(a)&&!l)return a;a=l}return null}function Pm(a,l,f){const m=l[10];m.begin&&m.begin();try{C_(a,l,a.template,f)}catch(M){throw mv(l,M),M}finally{m.end&&m.end()}}function Xh(a){!function(a){for(let l=0;l<a.components.length;l++){const f=a.components[l],m=a_(f),M=m[1];xm(M,m,M.template,f)}}(a[8])}function Ef(a,l,f){st(0),l(a,f)}const vS=(()=>Promise.resolve(null))();function Vu(a){return a[7]||(a[7]=[])}function yb(a){return a.cleanup||(a.cleanup=[])}function mv(a,l){const f=a[9],m=f?f.get(Gf,null):null;m&&m.handleError(l)}function bb(a,l,f,m,M){for(let k=0;k<f.length;){const te=f[k++],le=f[k++],Ne=l[te],qe=a.data[te];null!==qe.setInput?qe.setInput(Ne,M,m,le):Ne[le]=M}}function eg(a,l,f){const m=ur(l,a);ph(a[11],m,f)}function vv(a,l,f){let m=f?a.styles:null,M=f?a.classes:null,k=0;if(null!==l)for(let te=0;te<l.length;te++){const le=l[te];"number"==typeof le?k=le:1==k?M=A(M,le):2==k&&(m=A(m,le+": "+l[++te]+";"))}f?a.styles=m:a.stylesWithoutHost=m,f?a.classes=M:a.classesWithoutHost=M}const Jg=new Jl("INJECTOR",-1);class k0{get(l,f=R){if(f===R){const m=new Error(`NullInjectorError: No provider for ${S(l)}!`);throw m.name="NullInjectorError",m}return f}}const Im=new Jl("Set Injector scope."),Lm={},pd={};let Mg;function Ag(){return void 0===Mg&&(Mg=new k0),Mg}function Sb(a,l=null,f=null,m){return new $0(a,f,l||Ag(),m)}class $0{constructor(l,f,m,M=null){this.parent=m,this.records=new Map,this.injectorDefTypes=new Set,this.onDestroy=new Set,this._destroyed=!1;const k=[];f&&Xl(f,le=>this.processProvider(le,l,f)),Xl([l],le=>this.processInjectorType(le,[],k)),this.records.set(Jg,sd(void 0,this));const te=this.records.get(Im);this.scope=null!=te?te.value:null,this.source=M||("object"==typeof l?null:S(l))}get destroyed(){return this._destroyed}destroy(){this.assertNotDestroyed(),this._destroyed=!0;try{this.onDestroy.forEach(l=>l.ngOnDestroy())}finally{this.records.clear(),this.onDestroy.clear(),this.injectorDefTypes.clear()}}get(l,f=R,m=Yr.Default){this.assertNotDestroyed();const M=nn(this),k=Hi(void 0);try{if(!(m&Yr.SkipSelf)){let le=this.records.get(l);if(void 0===le){const Ne=("function"==typeof(a=l)||"object"==typeof a&&a instanceof Jl)&&Ur(l);le=Ne&&this.injectableDefInScope(Ne)?sd(yv(l),Lm):null,this.records.set(l,le)}if(null!=le)return this.hydrate(l,le)}return(m&Yr.Self?Ag():this.parent).get(l,f=m&Yr.Optional&&f===R?null:f)}catch(te){if("NullInjectorError"===te.name){if((te[q]=te[q]||[]).unshift(S(l)),M)throw te;return Gs(te,l,"R3InjectorError",this.source)}throw te}finally{Hi(k),nn(M)}var a}_resolveInjectorDefTypes(){this.injectorDefTypes.forEach(l=>this.get(l))}toString(){const l=[];return this.records.forEach((m,M)=>l.push(S(M))),`R3Injector[${l.join(", ")}]`}assertNotDestroyed(){if(this._destroyed)throw new Error("Injector has already been destroyed.")}processInjectorType(l,f,m){if(!(l=Z(l)))return!1;let M=Kr(l);const k=null==M&&l.ngModule||void 0,te=void 0===k?l:k,le=-1!==m.indexOf(te);if(void 0!==k&&(M=Kr(k)),null==M)return!1;if(null!=M.imports&&!le){let wt;m.push(te);try{Xl(M.imports,ln=>{this.processInjectorType(ln,f,m)&&(void 0===wt&&(wt=[]),wt.push(ln))})}finally{}if(void 0!==wt)for(let ln=0;ln<wt.length;ln++){const{ngModule:dn,providers:nr}=wt[ln];Xl(nr,Rr=>this.processProvider(Rr,dn,nr||Jt))}}this.injectorDefTypes.add(te);const Ne=wo(te)||(()=>new te);this.records.set(te,sd(Ne,Lm));const qe=M.providers;if(null!=qe&&!le){const wt=l;Xl(qe,ln=>this.processProvider(ln,wt,qe))}return void 0!==k&&void 0!==l.providers}processProvider(l,f,m){let M=Og(l=Z(l))?l:Z(l&&l.provide);const k=g1(a=l)?sd(void 0,a.useValue):sd(Md(a),Lm);var a;if(Og(l)||!0!==l.multi)this.records.get(M);else{let te=this.records.get(M);te||(te=sd(void 0,Lm,!0),te.factory=()=>Pi(te.multi),this.records.set(M,te)),M=l,te.multi.push(l)}this.records.set(M,k)}hydrate(l,f){return f.value===Lm&&(f.value=pd,f.value=f.factory()),"object"==typeof f.value&&f.value&&null!==(a=f.value)&&"object"==typeof a&&"function"==typeof a.ngOnDestroy&&this.onDestroy.add(f.value),f.value;var a}injectableDefInScope(l){if(!l.providedIn)return!1;const f=Z(l.providedIn);return"string"==typeof f?"any"===f||f===this.scope:this.injectorDefTypes.has(f)}}function yv(a){const l=Ur(a),f=null!==l?l.factory:wo(a);if(null!==f)return f;if(a instanceof Jl)throw new Error(`Token ${S(a)} is missing a \u0275prov definition.`);if(a instanceof Function)return function(a){const l=a.length;if(l>0){const m=Ll(l,"?");throw new Error(`Can't resolve all parameters for ${S(a)}: (${m.join(", ")}).`)}const f=function(a){const l=a&&(a[ei]||a[$n]);if(l){const f=function(a){if(a.hasOwnProperty("name"))return a.name;const l=(""+a).match(/^function\s*([^\s(]+)/);return null===l?"":l[1]}(a);return console.warn(`DEPRECATED: DI is instantiating a token "${f}" that inherits its @Injectable decorator but does not provide one itself.\nThis will become an error in a future version of Angular. Please add @Injectable() to the "${f}" class.`),l}return null}(a);return null!==f?()=>f.factory(a):()=>new a}(a);throw new Error("unreachable")}function Md(a,l,f){let m;if(Og(a)){const M=Z(a);return wo(M)||yv(M)}if(g1(a))m=()=>Z(a.useValue);else if(function(a){return!(!a||!a.useFactory)}(a))m=()=>a.useFactory(...Pi(a.deps||[]));else if(function(a){return!(!a||!a.useExisting)}(a))m=()=>xn(Z(a.useExisting));else{const M=Z(a&&(a.useClass||a.provide));if(!function(a){return!!a.deps}(a))return wo(M)||yv(M);m=()=>new M(...Pi(a.deps))}return m}function sd(a,l,f=!1){return{factory:a,value:l,multi:f?[]:void 0}}function g1(a){return null!==a&&"object"==typeof a&&gt in a}function Og(a){return"function"==typeof a}const U0=function(a,l,f){return function(a,l=null,f=null,m){const M=Sb(a,l,f,m);return M._resolveInjectorDefTypes(),M}({name:f},l,a,f)};let Ac=(()=>{class a{static create(f,m){return Array.isArray(f)?U0(f,m,""):U0(f.providers,f.parent,f.name||"")}}return a.THROW_IF_NOT_FOUND=R,a.NULL=new k0,a.\u0275prov=xt({token:a,providedIn:"any",factory:()=>xn(Jg)}),a.__NG_ELEMENT_ID__=-1,a})();function ny(a,l){$c(a_(a)[1],Ss())}function T1(a){let l=function(a){return Object.getPrototypeOf(a.prototype).constructor}(a.type),f=!0;const m=[a];for(;l;){let M;if(Ya(a))M=l.\u0275cmp||l.\u0275dir;else{if(l.\u0275cmp)throw new Error("Directives cannot inherit Components");M=l.\u0275dir}if(M){if(f){m.push(M);const te=a;te.inputs=Nf(a.inputs),te.declaredInputs=Nf(a.declaredInputs),te.outputs=Nf(a.outputs);const le=M.hostBindings;le&&Bb(a,le);const Ne=M.viewQuery,qe=M.contentQueries;if(Ne&&S1(a,Ne),qe&&Ub(a,qe),y(a.inputs,M.inputs),y(a.declaredInputs,M.declaredInputs),y(a.outputs,M.outputs),Ya(M)&&M.data.animation){const wt=a.data;wt.animation=(wt.animation||[]).concat(M.data.animation)}}const k=M.features;if(k)for(let te=0;te<k.length;te++){const le=k[te];le&&le.ngInherit&&le(a),le===T1&&(f=!1)}}l=Object.getPrototypeOf(l)}!function(a){let l=0,f=null;for(let m=a.length-1;m>=0;m--){const M=a[m];M.hostVars=l+=M.hostVars,M.hostAttrs=Wd(M.hostAttrs,f=Wd(f,M.hostAttrs))}}(m)}function Nf(a){return a===gr?{}:a===Jt?[]:a}function S1(a,l){const f=a.viewQuery;a.viewQuery=f?(m,M)=>{l(m,M),f(m,M)}:l}function Ub(a,l){const f=a.contentQueries;a.contentQueries=f?(m,M,k)=>{l(m,M,k),f(m,M,k)}:l}function Bb(a,l){const f=a.hostBindings;a.hostBindings=f?(m,M)=>{l(m,M),f(m,M)}:l}let Tv=null;function tg(){if(!Tv){const a=Dr.Symbol;if(a&&a.iterator)Tv=a.iterator;else{const l=Object.getOwnPropertyNames(Map.prototype);for(let f=0;f<l.length;++f){const m=l[f];"entries"!==m&&"size"!==m&&Map.prototype[m]===Map.prototype.entries&&(Tv=m)}}}return Tv}class mh{constructor(l){this.wrapped=l}static wrap(l){return new mh(l)}static unwrap(l){return mh.isWrapped(l)?l.wrapped:l}static isWrapped(l){return l instanceof mh}}function Hm(a){return!!M1(a)&&(Array.isArray(a)||!(a instanceof Map)&&tg()in a)}function M1(a){return null!==a&&("function"==typeof a||"object"==typeof a)}function Kh(a,l,f){return a[l]=f}function Um(a,l){return a[l]}function nf(a,l,f){return!Object.is(a[l],f)&&(a[l]=f,!0)}function A_(a,l,f,m){const M=nf(a,l,f);return nf(a,l+1,m)||M}function Sv(a,l,f,m,M){const k=A_(a,l,f,m);return nf(a,l+2,M)||k}function zp(a,l,f,m,M,k){const te=A_(a,l,f,m);return A_(a,l+2,M,k)||te}function A1(a,l,f,m){const M=Li();return nf(M,pu(),l)&&(sa(),function(a,l,f,m,M,k){const te=Qi(a,l);d1(l[11],te,k,a.value,f,m,M)}(hr(),M,a,l,f,m)),A1}function Kg(a,l,f,m){return nf(a,pu(),f)?l+H(f)+m:po}function qg(a,l,f,m,M,k){const le=A_(a,wr(),f,M);return aa(2),le?l+H(f)+m+H(M)+k:po}function $(a,l,f,m,M,k,te,le){const Ne=Li(),qe=sa(),wt=a+20,ln=qe.firstCreatePass?function(a,l,f,m,M,k,te,le,Ne){const qe=l.consts,wt=ip(l,a,4,te||null,Rl(qe,le));Cd(l,f,wt,Rl(qe,Ne)),$c(l,wt);const ln=wt.tViews=zg(2,wt,m,M,k,l.directiveRegistry,l.pipeRegistry,null,l.schemas,qe);return null!==l.queries&&(l.queries.template(l,wt),ln.queries=l.queries.embeddedTView(wt)),wt}(wt,qe,Ne,l,f,m,M,k,te):qe.data[wt];Mu(ln,!1);const dn=Ne[11].createComment("");Yh(qe,Ne,dn,ln),Wc(dn,Ne),h1(Ne,Ne[wt]=Wg(dn,Ne,dn,ln)),fo(ln)&&Rm(qe,Ne,ln),null!=te&&Vg(Ne,ln,le)}function Ke(a){return hs(vs.lFrame.contextLView,20+a)}function D1(a,l=Yr.Default){const f=Li();return null===f?xn(a,l):ja(Ss(),f,Z(a),l)}function zb(a,l,f){const m=Li();return nf(m,pu(),l)&&Ro(sa(),hr(),m,a,l,m[11],f,!1),zb}function Wb(a,l,f,m,M){const te=M?"class":"style";bb(a,f,l.inputs[te],te,m)}function Jb(a,l,f,m){const M=Li(),k=sa(),te=20+a,le=M[11],Ne=M[te]=Bh(le,l,vs.lFrame.currentNamespace),qe=k.firstCreatePass?function(a,l,f,m,M,k,te){const le=l.consts,qe=ip(l,a,2,M,Rl(le,k));return Cd(l,f,qe,Rl(le,te)),null!==qe.attrs&&vv(qe,qe.attrs,!1),null!==qe.mergedAttrs&&vv(qe,qe.mergedAttrs,!0),null!==l.queries&&l.queries.elementStart(l,qe),qe}(te,k,M,0,l,f,m):k.data[te];Mu(qe,!0);const wt=qe.mergedAttrs;null!==wt&&ic(le,Ne,wt);const ln=qe.classes;null!==ln&&Gh(le,Ne,ln);const dn=qe.styles;null!==dn&&Zg(le,Ne,dn),64!=(64&qe.flags)&&Yh(k,M,Ne,qe),0===vs.lFrame.elementDepthCount&&Wc(Ne,M),vs.lFrame.elementDepthCount++,fo(qe)&&(Rm(k,M,qe),c1(k,qe,M)),null!==m&&Vg(M,qe)}function Qb(){let a=Ss();yu()?lu():(a=a.parent,Mu(a,!1));const l=a;vs.lFrame.elementDepthCount--;const f=sa();f.firstCreatePass&&($c(f,a),da(a)&&f.queries.elementEnd(a)),null!=l.classesWithoutHost&&function(a){return 0!=(16&a.flags)}(l)&&Wb(f,l,Li(),l.classesWithoutHost,!0),null!=l.stylesWithoutHost&&function(a){return 0!=(32&a.flags)}(l)&&Wb(f,l,Li(),l.stylesWithoutHost,!1)}function LS(a,l,f,m){Jb(a,l,f,m),Qb()}function Xb(a,l,f){const m=Li(),M=sa(),k=a+20,te=M.firstCreatePass?function(a,l,f,m,M){const k=l.consts,te=Rl(k,m),le=ip(l,a,8,"ng-container",te);return null!==te&&vv(le,te,!0),Cd(l,f,le,Rl(k,M)),null!==l.queries&&l.queries.elementStart(l,le),le}(k,M,m,l,f):M.data[k];Mu(te,!0);const le=m[k]=m[11].createComment("");Yh(M,m,le,te),Wc(le,m),fo(te)&&(Rm(M,m,te),c1(M,te,m)),null!=f&&Vg(m,te)}function Kb(){let a=Ss();const l=sa();yu()?lu():(a=a.parent,Mu(a,!1)),l.firstCreatePass&&($c(l,a),da(a)&&l.queries.elementEnd(a))}function FS(a,l,f){Xb(a,l,f),Kb()}function fy(){return Li()}function Zm(a){return!!a&&"function"==typeof a.then}function kS(a){return!!a&&"function"==typeof a.subscribe}const qb=kS;function eE(a,l,f,m){const M=Li(),k=sa(),te=Ss();return function(a,l,f,m,M,k,te,le){const Ne=fo(m),wt=a.firstCreatePass&&yb(a),ln=l[8],dn=Vu(l);let nr=!0;if(3&m.type||le){const ii=Qi(m,l),Oo=le?le(ii):ii,Xi=dn.length,ua=le?Xa=>le(Me(Xa[m.index])):m.index;if(rt(f)){let Xa=null;if(!le&&Ne&&(Xa=function(a,l,f,m){const M=a.cleanup;if(null!=M)for(let k=0;k<M.length-1;k+=2){const te=M[k];if(te===f&&M[k+1]===m){const le=l[7],Ne=M[k+2];return le.length>Ne?le[Ne]:null}"string"==typeof te&&(k+=2)}return null}(a,l,M,m.index)),null!==Xa)(Xa.__ngLastListenerFn__||Xa).__ngNextListenerFn__=k,Xa.__ngLastListenerFn__=k,nr=!1;else{k=tE(m,l,ln,k,!1);const du=f.listen(Oo,M,k);dn.push(k,du),wt&&wt.push(M,ua,Xi,Xi+1)}}else k=tE(m,l,ln,k,!0),Oo.addEventListener(M,k,te),dn.push(k),wt&&wt.push(M,ua,Xi,te)}else k=tE(m,l,ln,k,!1);const Rr=m.outputs;let Ti;if(nr&&null!==Rr&&(Ti=Rr[M])){const ii=Ti.length;if(ii)for(let Oo=0;Oo<ii;Oo+=2){const jd=l[Ti[Oo]][Ti[Oo+1]].subscribe(k),Ch=dn.length;dn.push(k,jd),wt&&wt.push(M,m.index,Ch,-(Ch+1))}}}(k,M,M[11],te,a,l,!!f,m),eE}function US(a,l,f,m){try{return!1!==f(m)}catch(M){return mv(a,M),!1}}function tE(a,l,f,m,M){return function k(te){if(te===Function)return m;const le=2&a.flags?Ts(a.index,l):l;0==(32&l[2])&&I0(le);let Ne=US(l,0,m,te),qe=k.__ngNextListenerFn__;for(;qe;)Ne=US(l,0,qe,te)&&Ne,qe=qe.__ngNextListenerFn__;return M&&!1===Ne&&(te.preventDefault(),te.returnValue=!1),Ne}}function BS(a=1){return function(a){return(vs.lFrame.contextLView=function(a,l){for(;a>0;)l=l[15],a--;return l}(a,vs.lFrame.contextLView))[8]}(a)}function fO(a,l){let f=null;const m=function(a){const l=a.attrs;if(null!=l){const f=l.indexOf(5);if(0==(1&f))return l[f+1]}return null}(a);for(let M=0;M<l.length;M++){const k=l[M];if("*"!==k){if(null===m?We(a,k,!0):yr(m,k))return M}else f=M}return f}function YS(a){const l=Li()[16][6];if(!l.projection){const m=l.projection=Ll(a?a.length:1,null),M=m.slice();let k=l.child;for(;null!==k;){const te=a?fO(k,a):0;null!==te&&(M[te]?M[te].projectionNext=k:m[te]=k,M[te]=k),k=k.next}}}function ZS(a,l=0,f){const m=Li(),M=sa(),k=ip(M,20+a,16,null,f||null);null===k.projection&&(k.projection=l),lu(),64!=(64&k.flags)&&function(a,l,f){jp(l[11],0,l,f,z_(a,f,l),Yg(f.parent||l[6],f,l))}(M,m,k)}function nE(a,l,f){return py(a,"",l,"",f),nE}function py(a,l,f,m,M){const k=Li(),te=Kg(k,l,f,m);return te!==po&&Ro(sa(),hr(),k,a,te,k[11],M,!1),py}function xg(a,l,f,m,M,k,te){const le=Li(),Ne=qg(le,l,f,m,M,k);return Ne!==po&&Ro(sa(),hr(),le,a,Ne,le[11],te,!1),xg}function QS(a,l,f,m,M){const k=a[f+1],te=null===l;let le=m?Tr(k):va(k),Ne=!1;for(;0!==le&&(!1===Ne||te);){const wt=a[le+1];_O(a[le],l)&&(Ne=!0,a[le+1]=m?xl(wt):io(wt)),le=m?Tr(wt):va(wt)}Ne&&(a[f+1]=m?io(k):xl(k))}function _O(a,l){return null===a||null==l||(Array.isArray(a)?a[1]:a)===l||!(!Array.isArray(a)||"string"!=typeof l)&&oc(a,l)>=0}const Tf={textEnd:0,key:0,keyEnd:0,value:0,valueEnd:0};function XS(a){return a.substring(Tf.key,Tf.keyEnd)}function KS(a,l){const f=Tf.textEnd;return f===l?-1:(l=Tf.keyEnd=function(a,l,f){for(;l<f&&a.charCodeAt(l)>32;)l++;return l}(a,Tf.key=l,f),Ov(a,l,f))}function Ov(a,l,f){for(;l<f&&a.charCodeAt(l)<=32;)l++;return l}function iE(a,l,f){return O_(a,l,f,!1),iE}function oE(a,l){return O_(a,l,null,!0),oE}function rC(a){w_(Vl,ig,a,!0)}function ig(a,l){for(let f=function(a){return function(a){Tf.key=0,Tf.keyEnd=0,Tf.value=0,Tf.valueEnd=0,Tf.textEnd=a.length}(a),KS(a,Ov(a,0,Tf.textEnd))}(l);f>=0;f=KS(l,f))Vl(a,XS(l),!0)}function O_(a,l,f,m){const M=Li(),k=sa(),te=aa(2);k.firstUpdatePass&&oC(k,a,te,m),l!==po&&nf(M,te,l)&&wv(k,k.data[In()],M,M[11],a,M[te+1]=function(a,l){return null==a||("string"==typeof l?a+=l:"object"==typeof a&&(a=S(kd(a)))),a}(l,f),m,te)}function w_(a,l,f,m){const M=sa(),k=aa(2);M.firstUpdatePass&&oC(M,null,k,m);const te=Li();if(f!==po&&nf(te,k,f)){const le=M.data[In()];if(_y(le,m)&&!iC(M,k)){let Ne=m?le.classesWithoutHost:le.stylesWithoutHost;null!==Ne&&(f=A(Ne,f||"")),Wb(M,le,te,f,m)}else!function(a,l,f,m,M,k,te,le){M===po&&(M=Jt);let Ne=0,qe=0,wt=0<M.length?M[0]:null,ln=0<k.length?k[0]:null;for(;null!==wt||null!==ln;){const dn=Ne<M.length?M[Ne+1]:void 0,nr=qe<k.length?k[qe+1]:void 0;let Ti,Rr=null;wt===ln?(Ne+=2,qe+=2,dn!==nr&&(Rr=ln,Ti=nr)):null===ln||null!==wt&&wt<ln?(Ne+=2,Rr=wt):(qe+=2,Rr=ln,Ti=nr),null!==Rr&&wv(a,l,f,m,Rr,Ti,te,le),wt=Ne<M.length?M[Ne]:null,ln=qe<k.length?k[qe]:null}}(M,le,te,te[11],te[k+1],te[k+1]=function(a,l,f){if(null==f||""===f)return Jt;const m=[],M=kd(f);if(Array.isArray(M))for(let k=0;k<M.length;k++)a(m,M[k],!0);else if("object"==typeof M)for(const k in M)M.hasOwnProperty(k)&&a(m,k,M[k]);else"string"==typeof M&&l(m,M);return m}(a,l,f),m,k)}}function iC(a,l){return l>=a.expandoStartIndex}function oC(a,l,f,m){const M=a.data;if(null===M[f+1]){const k=M[In()],te=iC(a,f);_y(k,m)&&null===l&&!te&&(l=!1),l=function(a,l,f,m){const M=V(a);let k=m?l.residualClasses:l.residualStyles;if(null===M)0===(m?l.classBindings:l.styleBindings)&&(f=R1(f=sE(null,a,l,f,m),l.attrs,m),k=null);else{const te=l.directiveStylingLast;if(-1===te||a[te]!==M)if(f=sE(M,a,l,f,m),null===k){let Ne=function(a,l,f){const m=f?l.classBindings:l.styleBindings;if(0!==va(m))return a[Tr(m)]}(a,l,m);void 0!==Ne&&Array.isArray(Ne)&&(Ne=sE(null,a,l,Ne[1],m),Ne=R1(Ne,l.attrs,m),function(a,l,f,m){a[Tr(f?l.classBindings:l.styleBindings)]=m}(a,l,m,Ne))}else k=function(a,l,f){let m;const M=l.directiveEnd;for(let k=1+l.directiveStylingLast;k<M;k++)m=R1(m,a[k].hostAttrs,f);return R1(m,l.attrs,f)}(a,l,m)}return void 0!==k&&(m?l.residualClasses=k:l.residualStyles=k),f}(M,k,l,m),function(a,l,f,m,M,k){let te=k?l.classBindings:l.styleBindings,le=Tr(te),Ne=va(te);a[m]=f;let wt,qe=!1;if(Array.isArray(f)){const ln=f;wt=ln[1],(null===wt||oc(ln,wt)>0)&&(qe=!0)}else wt=f;if(M)if(0!==Ne){const dn=Tr(a[le+1]);a[m+1]=ni(dn,le),0!==dn&&(a[dn+1]=Cs(a[dn+1],m)),a[le+1]=function(a,l){return 131071&a|l<<17}(a[le+1],m)}else a[m+1]=ni(le,0),0!==le&&(a[le+1]=Cs(a[le+1],m)),le=m;else a[m+1]=ni(Ne,0),0===le?le=m:a[Ne+1]=Cs(a[Ne+1],m),Ne=m;qe&&(a[m+1]=io(a[m+1])),QS(a,wt,m,!0),QS(a,wt,m,!1),function(a,l,f,m,M){const k=M?a.residualClasses:a.residualStyles;null!=k&&"string"==typeof l&&oc(k,l)>=0&&(f[m+1]=xl(f[m+1]))}(l,wt,a,m,k),te=ni(le,Ne),k?l.classBindings=te:l.styleBindings=te}(M,k,l,f,te,m)}}function sE(a,l,f,m,M){let k=null;const te=f.directiveEnd;let le=f.directiveStylingLast;for(-1===le?le=f.directiveStart:le++;le<te&&(k=l[le],m=R1(m,k.hostAttrs,M),k!==a);)le++;return null!==a&&(f.directiveStylingLast=le),m}function R1(a,l,f){const m=f?1:2;let M=-1;if(null!==l)for(let k=0;k<l.length;k++){const te=l[k];"number"==typeof te?M=te:M===m&&(Array.isArray(a)||(a=void 0===a?[]:["",a]),Vl(a,te,!!f||l[++k]))}return void 0===a?null:a}function wv(a,l,f,m,M,k,te,le){if(!(3&l.type))return;const Ne=a.data,qe=Ne[le+1];hy(function(a){return 1==(1&a)}(qe)?aC(Ne,l,f,M,va(qe),te):void 0)||(hy(k)||function(a){return 2==(2&a)}(qe)&&(k=aC(Ne,null,f,M,le,te)),function(a,l,f,m,M){const k=rt(a);if(l)M?k?a.addClass(f,m):f.classList.add(m):k?a.removeClass(f,m):f.classList.remove(m);else{let te=-1===m.indexOf("-")?void 0:Bd.DashCase;if(null==M)k?a.removeStyle(f,m,te):f.style.removeProperty(m);else{const le="string"==typeof M&&M.endsWith("!important");le&&(M=M.slice(0,-10),te|=Bd.Important),k?a.setStyle(f,m,M,te):f.style.setProperty(m,M,le?"important":"")}}}(m,te,ur(In(),f),M,k))}function aC(a,l,f,m,M,k){const te=null===l;let le;for(;M>0;){const Ne=a[M],qe=Array.isArray(Ne),wt=qe?Ne[1]:Ne,ln=null===wt;let dn=f[M+1];dn===po&&(dn=ln?Jt:void 0);let nr=ln?Id(dn,m):wt===m?dn:void 0;if(qe&&!hy(nr)&&(nr=Id(Ne,m)),hy(nr)&&(le=nr,te))return le;const Rr=a[M+1];M=te?Tr(Rr):va(Rr)}if(null!==l){let Ne=k?l.residualClasses:l.residualStyles;null!=Ne&&(le=Id(Ne,m))}return le}function hy(a){return void 0!==a}function _y(a,l){return 0!=(a.flags&(l?16:32))}function uC(a,l=""){const f=Li(),m=sa(),M=a+20,k=m.firstCreatePass?ip(m,M,1,l,null):m.data[M],te=f[M]=Rf(f[11],l);Yh(m,f,te,k),Mu(k,!1)}function aE(a){return gy("",a,""),aE}function gy(a,l,f){const m=Li(),M=Kg(m,a,l,f);return M!==po&&eg(m,In(),M),gy}function lE(a,l,f,m,M){const k=Li(),te=qg(k,a,l,f,m,M);return te!==po&&eg(k,In(),te),lE}function uE(a,l,f,m,M,k,te){const le=Li(),Ne=function(a,l,f,m,M,k,te,le){const qe=Sv(a,wr(),f,M,te);return aa(3),qe?l+H(f)+m+H(M)+k+H(te)+le:po}(le,a,l,f,m,M,k,te);return Ne!==po&&eg(le,In(),Ne),uE}function gC(a,l,f){w_(Vl,ig,Kg(Li(),a,l,f),!0)}function mC(a,l,f,m,M){w_(Vl,ig,qg(Li(),a,l,f,m,M),!0)}function vC(a,l,f,m,M,k,te,le,Ne){w_(Vl,ig,function(a,l,f,m,M,k,te,le,Ne,qe){const ln=zp(a,wr(),f,M,te,Ne);return aa(4),ln?l+H(f)+m+H(M)+k+H(te)+le+H(Ne)+qe:po}(Li(),a,l,f,m,M,k,te,le,Ne),!0)}function cE(a,l,f){const m=Li();return nf(m,pu(),l)&&Ro(sa(),hr(),m,a,l,m[11],f,!0),cE}function dE(a,l,f){const m=Li();if(nf(m,pu(),l)){const k=sa(),te=hr();Ro(k,te,m,a,l,function(a,l,f){return(null===a||Ya(a))&&(f=function(a){for(;Array.isArray(a);){if("object"==typeof a[1])return a;a=a[0]}return null}(f[l.index])),f[11]}(V(k.data),te,m),f,!0)}return dE}const jm=void 0;var GO=["en",[["a","p"],["AM","PM"],jm],[["AM","PM"],jm,jm],[["S","M","T","W","T","F","S"],["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],["Su","Mo","Tu","We","Th","Fr","Sa"]],jm,[["J","F","M","A","M","J","J","A","S","O","N","D"],["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],["January","February","March","April","May","June","July","August","September","October","November","December"]],jm,[["B","A"],["BC","AD"],["Before Christ","Anno Domini"]],0,[6,0],["M/d/yy","MMM d, y","MMMM d, y","EEEE, MMMM d, y"],["h:mm a","h:mm:ss a","h:mm:ss a z","h:mm:ss a zzzz"],["{1}, {0}",jm,"{1} 'at' {0}",jm],[".",",",";","%","+","-","E","\xd7","\u2030","\u221e","NaN",":"],["#,##0.###","#,##0%","\xa4#,##0.00","#E0"],"USD","$","US Dollar",{},"ltr",function(a){const l=Math.floor(Math.abs(a)),f=a.toString().replace(/^[^.]*\.?/,"").length;return 1===l&&0===f?1:5}];let xv={};function fE(a){const l=function(a){return a.toLowerCase().replace(/_/g,"-")}(a);let f=xC(l);if(f)return f;const m=l.split("-")[0];if(f=xC(m),f)return f;if("en"===m)return GO;throw new Error(`Missing locale data for the locale "${a}".`)}function wC(a){return fE(a)[Ua.PluralCase]}function xC(a){return a in xv||(xv[a]=Dr.ng&&Dr.ng.common&&Dr.ng.common.locales&&Dr.ng.common.locales[a]),xv[a]}var Ua=(()=>((Ua=Ua||{})[Ua.LocaleId=0]="LocaleId",Ua[Ua.DayPeriodsFormat=1]="DayPeriodsFormat",Ua[Ua.DayPeriodsStandalone=2]="DayPeriodsStandalone",Ua[Ua.DaysFormat=3]="DaysFormat",Ua[Ua.DaysStandalone=4]="DaysStandalone",Ua[Ua.MonthsFormat=5]="MonthsFormat",Ua[Ua.MonthsStandalone=6]="MonthsStandalone",Ua[Ua.Eras=7]="Eras",Ua[Ua.FirstDayOfWeek=8]="FirstDayOfWeek",Ua[Ua.WeekendRange=9]="WeekendRange",Ua[Ua.DateFormat=10]="DateFormat",Ua[Ua.TimeFormat=11]="TimeFormat",Ua[Ua.DateTimeFormat=12]="DateTimeFormat",Ua[Ua.NumberSymbols=13]="NumberSymbols",Ua[Ua.NumberFormats=14]="NumberFormats",Ua[Ua.CurrencyCode=15]="CurrencyCode",Ua[Ua.CurrencySymbol=16]="CurrencySymbol",Ua[Ua.CurrencyName=17]="CurrencyName",Ua[Ua.Currencies=18]="Currencies",Ua[Ua.Directionality=19]="Directionality",Ua[Ua.PluralCase=20]="PluralCase",Ua[Ua.ExtraData=21]="ExtraData",Ua))();const zO=["zero","one","two","few","many"],my="en-US",vy={marker:"element"},yy={marker:"ICU"};var Ad=(()=>((Ad=Ad||{})[Ad.SHIFT=2]="SHIFT",Ad[Ad.APPEND_EAGERLY=1]="APPEND_EAGERLY",Ad[Ad.COMMENT=2]="COMMENT",Ad))();let DC=my;function pE(a){(function(a,l){null==a&&Ut(l,a,null,"!=")})(a,"Expected localeId to be defined"),"string"==typeof a&&(DC=a.toLowerCase().replace(/_/g,"-"))}function RC(a,l,f){const m=l.insertBeforeIndex,M=Array.isArray(m)?m[0]:m;return null===M?Sp(a,0,f):Me(f[M])}function hE(a,l,f,m,M){const k=l.insertBeforeIndex;if(Array.isArray(k)){let te=m,le=null;if(3&l.type||(le=te,te=M),null!==te&&0==(2&l.flags))for(let Ne=1;Ne<k.length;Ne++)_h(a,te,f[k[Ne]],le,!1)}}function _E(a,l){if(a.push(l),a.length>1)for(let f=a.length-2;f>=0;f--){const m=a[f];NC(m)||XO(m,l)&&null===KO(m)&&qO(m,l.index)}}function NC(a){return!(64&a.type)}function XO(a,l){return NC(l)||a.index>l.index}function KO(a){const l=a.insertBeforeIndex;return Array.isArray(l)?l[0]:l}function qO(a,l){const f=a.insertBeforeIndex;Array.isArray(f)?f[0]=l:(J_(RC,hE),a.insertBeforeIndex=l)}function N1(a,l){const f=a.data[l];return null===f||"string"==typeof f?null:f.hasOwnProperty("currentCaseLViewIndex")?f:f.value}function nw(a,l,f){const m=Jh(a,f,64,null,null);return _E(l,m),m}function by(a,l){const f=l[a.currentCaseLViewIndex];return null===f?f:f<0?~f:f}function PC(a){return a>>>17}function IC(a){return(131070&a)>>>1}let Dv=0,Gm=0;function FC(a,l,f,m){const M=f[11];let te,k=null;for(let le=0;le<l.length;le++){const Ne=l[le];if("string"==typeof Ne){const qe=l[++le];null===f[qe]&&(f[qe]=Rf(M,Ne))}else if("number"==typeof Ne)switch(1&Ne){case 0:const qe=PC(Ne);let wt,ln;if(null===k&&(k=qe,te=Yd(M,m)),qe===k?(wt=m,ln=te):(wt=null,ln=Me(f[qe])),null!==ln){const Ti=IC(Ne);_h(M,ln,f[Ti],wt,!1);const Oo=N1(a,Ti);if(null!==Oo&&"object"==typeof Oo){const Xi=by(Oo,f);null!==Xi&&FC(a,Oo.create[Xi],f,f[Oo.anchorIdx])}}break;case 1:const nr=l[++le],Rr=l[++le];d1(M,ur(Ne>>>1,f),null,null,nr,Rr,null);break;default:throw new Error(`Unable to determine the type of mutate operation for "${Ne}"`)}else switch(Ne){case yy:const qe=l[++le],wt=l[++le];null===f[wt]&&Wc(f[wt]=_g(M,qe),f);break;case vy:const ln=l[++le],dn=l[++le];null===f[dn]&&Wc(f[dn]=Bh(M,ln,null),f)}}}function kC(a,l,f,m,M){for(let k=0;k<f.length;k++){const te=f[k],le=f[++k];if(te&M){let Ne="";for(let qe=k+1;qe<=k+le;qe++){const wt=f[qe];if("string"==typeof wt)Ne+=wt;else if("number"==typeof wt)if(wt<0)Ne+=H(l[m-wt]);else{const ln=wt>>>2;switch(3&wt){case 1:const dn=f[++qe],nr=f[++qe],Rr=a.data[ln];"string"==typeof Rr?d1(l[11],l[ln],null,Rr,dn,Ne,nr):Ro(a,Rr,l,dn,Ne,l[11],nr,!1);break;case 0:const Ti=l[ln];null!==Ti&&ph(l[11],Ti,Ne);break;case 2:sw(a,N1(a,ln),l,Ne);break;case 3:$C(a,N1(a,ln),m,l)}}}}else{const Ne=f[k+1];if(Ne>0&&3==(3&Ne)){const wt=N1(a,Ne>>>2);l[wt.currentCaseLViewIndex]<0&&$C(a,wt,m,l)}}k+=le}}function $C(a,l,f,m){let M=m[l.currentCaseLViewIndex];if(null!==M){let k=Dv;M<0&&(M=m[l.currentCaseLViewIndex]=~M,k=-1),kC(a,m,l.update[M],f,k)}}function sw(a,l,f,m){const M=function(a,l){let f=a.cases.indexOf(l);if(-1===f)switch(a.type){case 1:{const m=function(a,l){const f=wC(l)(parseInt(a,10)),m=zO[f];return void 0!==m?m:"other"}(l,DC);f=a.cases.indexOf(m),-1===f&&"other"!==m&&(f=a.cases.indexOf("other"));break}case 0:f=a.cases.indexOf("other")}return-1===f?null:f}(l,m);if(by(l,f)!==M&&(HC(a,l,f),f[l.currentCaseLViewIndex]=null===M?null:~M,null!==M)){const te=f[l.anchorIdx];te&&FC(a,l.create[M],f,te)}}function HC(a,l,f){let m=by(l,f);if(null!==m){const M=l.remove[m];for(let k=0;k<M.length;k++){const te=M[k];if(te>0){const le=ur(te,f);null!==le&&y_(f[11],le)}else HC(a,N1(a,~te),f)}}}function aw(){const a=[];let f,m,l=-1;function k(le,Ne){l=0;const qe=by(le,Ne);m=null!==qe?le.remove[qe]:Jt}function te(){if(l<m.length){const le=m[l++];return le>0?f[le]:(a.push(l,m),k(f[1].data[~le],f),te())}return 0===a.length?null:(m=a.pop(),l=a.pop(),te())}return function(le,Ne){for(f=Ne;a.length;)a.pop();return k(le.value,Ne),te}}const Ey=/\ufffd(\d+):?\d*\ufffd/gi,lw=/({\s*\ufffd\d+:?\d*\ufffd\s*,\s*\S{6}\s*,[\s\S]*})/gi,uw=/\ufffd(\d+)\ufffd/,YC=/^\s*(\ufffd\d+:?\d*\ufffd)\s*,\s*(select|plural)\s*,/,cw=/\ufffd\/?\*(\d+:\d+)\ufffd/gi,dw=/\ufffd(\/?[#*]\d+):?\d*\ufffd/gi,ZC=/\uE500/g;function jC(a,l,f,m,M,k,te){const le=Vp(a,m,1,null);let Ne=le<<Ad.SHIFT,qe=yl();l===qe&&(qe=null),null===qe&&(Ne|=Ad.APPEND_EAGERLY),te&&(Ne|=Ad.COMMENT,function(a){void 0===fd&&(fd=a())}(aw)),M.push(Ne,null===k?"":k);const wt=Jh(a,le,te?32:1,null===k?"":k,null);_E(f,wt);const ln=wt.index;return Mu(wt,!1),null!==qe&&l!==qe&&function(a,l){let f=a.insertBeforeIndex;null===f?(J_(RC,hE),f=a.insertBeforeIndex=[null,l]):(function(a,l,f){a!=l&&Ut(f,a,l,"==")}(Array.isArray(f),!0,"Expecting array here"),f.push(l))}(qe,ln),wt}function hw(a,l,f,m,M,k,te){const le=te.match(Ey),Ne=jC(a,l,f,k,m,le?null:te,!1);le&&Rv(M,te,Ne.index,null,0,null)}function Rv(a,l,f,m,M,k){const te=a.length,le=te+1;a.push(null,null);const Ne=te+2,qe=l.split(Ey);let wt=0;for(let ln=0;ln<qe.length;ln++){const dn=qe[ln];if(1&ln){const nr=M+parseInt(dn,10);a.push(-1-nr),wt|=GC(nr)}else""!==dn&&a.push(dn)}return a.push(f<<2|(m?1:0)),m&&a.push(m,k),a[te]=wt,a[le]=a.length-Ne,wt}function gw(a){let l=0;for(let f=0;f<a.length;f++){const m=a[f];"number"==typeof m&&m<0&&l++}return l}function GC(a){return 1<<Math.min(a,31)}function VC(a){let l,k,f="",m=0,M=!1;for(;null!==(l=cw.exec(a));)M?l[0]===`\ufffd/*${k}\ufffd`&&(m=l.index,M=!1):(f+=a.substring(m,l.index+l[0].length),k=l[1],M=!0);return f+=a.substr(m),f}function mE(a,l,f,m,M,k){let te=0;const le={type:M.type,currentCaseLViewIndex:Vp(a,l,1,null),anchorIdx:k,cases:[],create:[],remove:[],update:[]};(function(a,l,f){a.push(GC(l.mainBinding),2,-1-l.mainBinding,f<<2|2)})(f,M,k),function(a,l,f){const m=a.data[l];null===m?a.data[l]=f:m.value=f}(a,k,le);const Ne=M.values;for(let qe=0;qe<Ne.length;qe++){const wt=Ne[qe],ln=[];for(let dn=0;dn<wt.length;dn++){const nr=wt[dn];if("string"!=typeof nr){const Rr=ln.push(nr)-1;wt[dn]=`\x3c!--\ufffd${Rr}\ufffd--\x3e`}}te=bw(a,le,l,f,m,M.cases[qe],wt.join(""),ln)|te}te&&function(a,l,f){a.push(l,1,f<<2|3)}(f,te,k)}function yw(a){const l=[],f=[];let m=1,M=0;const k=Vm(a=a.replace(YC,function(te,le,Ne){return m="select"===Ne?0:1,M=parseInt(le.substr(1),10),""}));for(let te=0;te<k.length;){let le=k[te++].trim();1===m&&(le=le.replace(/\s*(?:=)?(\w+)\s*/,"$1")),le.length&&l.push(le);const Ne=Vm(k[te++]);l.length>f.length&&f.push(Ne)}return{type:m,mainBinding:M,cases:l,values:f}}function Vm(a){if(!a)return[];let l=0;const f=[],m=[],M=/[{}]/g;let k;for(M.lastIndex=0;k=M.exec(a);){const le=k.index;if("}"==k[0]){if(f.pop(),0==f.length){const Ne=a.substring(l,le);YC.test(Ne)?m.push(yw(Ne)):m.push(Ne),l=le+1}}else{if(0==f.length){const Ne=a.substring(l,le);m.push(Ne),l=le+1}f.push("{")}}const te=a.substring(l);return m.push(te),m}function bw(a,l,f,m,M,k,te,le){const Ne=[],qe=[],wt=[];l.cases.push(k),l.create.push(Ne),l.remove.push(qe),l.update.push(wt);const dn=rh(Su()).getInertBodyElement(te),nr=Rs(dn)||dn;return nr?vE(a,l,f,m,Ne,qe,wt,nr,M,le,0):0}function vE(a,l,f,m,M,k,te,le,Ne,qe,wt){let ln=0,dn=le.firstChild;for(;dn;){const nr=Vp(a,f,1,null);switch(dn.nodeType){case Node.ELEMENT_NODE:const Rr=dn,Ti=Rr.tagName.toLowerCase();if(Y.hasOwnProperty(Ti)){yE(M,vy,Ti,Ne,nr),a.data[nr]=Ti;const ua=Rr.attributes;for(let Xa=0;Xa<ua.length;Xa++){const du=ua.item(Xa),jd=du.name.toLowerCase();du.value.match(Ey)?ct.hasOwnProperty(jd)&&Rv(te,du.value,nr,du.name,0,fe[jd]?vf:w[jd]?Lh:null):Nv(M,nr,du)}ln=vE(a,l,f,m,M,k,te,dn,nr,qe,wt+1)|ln,zC(k,nr,wt)}break;case Node.TEXT_NODE:const ii=dn.textContent||"",Oo=ii.match(Ey);yE(M,null,Oo?"":ii,Ne,nr),zC(k,nr,wt),Oo&&(ln=Rv(te,ii,nr,null,0,null)|ln);break;case Node.COMMENT_NODE:const Xi=uw.exec(dn.textContent||"");if(Xi){const Xa=qe[parseInt(Xi[1],10)];yE(M,yy,"",Ne,nr),mE(a,f,m,Ne,Xa,nr),Ew(k,nr,wt)}}dn=dn.nextSibling}return ln}function zC(a,l,f){0===f&&a.push(l)}function Ew(a,l,f){0===f&&(a.push(~l),a.push(l))}function yE(a,l,f,m,M){null!==l&&a.push(l),a.push(f,M,function(a,l,f){return 0|l<<17|f<<1}(0,m,M))}function Nv(a,l,f){a.push(l<<1|1,f.name,f.value)}const Cw=/\[(\ufffd.+?\ufffd?)\]/,WC=/\[(\ufffd.+?\ufffd?)\]|(\ufffd\/?\*\d+:\d+\ufffd)/g,Mw=/({\s*)(VAR_(PLURAL|SELECT)(_\d+)?)(\s*,)/g,Aw=/{([A-Z0-9_]+)}/g,JC=/\ufffdI18N_EXP_(ICU(_\d+)?)\ufffd/g,Ow=/\/\*/,ww=/\d+\:(\d+)/;function Ty(a,l,f=-1){const m=sa(),M=Li(),k=20+a,te=Rl(m.consts,l),le=yl();m.firstCreatePass&&function(a,l,f,m,M,k){const te=yl(),le=[],Ne=[],qe=[[]],wt=function(a){return a.replace(ZC," ")}(M=function(a,l){if(function(a){return-1===a}(l))return VC(a);{const f=a.indexOf(`:${l}\ufffd`)+2+l.toString().length,m=a.search(new RegExp(`\ufffd\\/\\*\\d+:${l}\ufffd`));return VC(a.substring(f,m))}}(M,k)).split(dw);for(let ln=0;ln<wt.length;ln++){let dn=wt[ln];if(0==(1&ln)){const nr=Vm(dn);for(let Rr=0;Rr<nr.length;Rr++){let Ti=nr[Rr];if(0==(1&Rr)){const ii=Ti;""!==ii&&hw(a,te,qe[0],le,Ne,f,ii)}else{const ii=Ti;if("object"!=typeof ii)throw new Error(`Unable to parse ICU expression in "${M}" message.`);mE(a,f,Ne,l,ii,jC(a,te,qe[0],f,le,"",!0).index)}}}else{const nr=47===dn.charCodeAt(0),Ti=(dn.charCodeAt(nr?1:0),20+Number.parseInt(dn.substring(nr?2:1)));if(nr)qe.shift(),Mu(yl(),!1);else{const ii=nw(a,qe[0],Ti);qe.unshift([]),Mu(ii,!0)}}}a.data[m]={create:le,update:Ne}}(m,null===le?0:le.index,M,k,te,f);const Ne=m.data[k],wt=Tp(m,le===M[6]?null:le,M);(function(a,l,f,m){const M=a[11];for(let k=0;k<l.length;k++){const te=l[k++],le=l[k],Ne=(te&Ad.COMMENT)===Ad.COMMENT,qe=(te&Ad.APPEND_EAGERLY)===Ad.APPEND_EAGERLY,wt=te>>>Ad.SHIFT;let ln=a[wt];null===ln&&(ln=a[wt]=Ne?M.createComment(le):Rf(M,le)),qe&&null!==f&&_h(M,f,ln,m,!1)}})(M,Ne.create,wt,le&&8&le.type?M[le.index]:null),bl(!0)}function EE(){bl(!1)}function QC(a,l,f){Ty(a,l,f),EE()}function XC(a,l){const f=sa();!function(a,l,f){const M=Ss().index,k=[];if(a.firstCreatePass&&null===a.data[l]){for(let te=0;te<f.length;te+=2){const le=f[te],Ne=f[te+1];if(""!==Ne){if(lw.test(Ne))throw new Error(`ICU expressions are not supported in attributes. Message: "${Ne}".`);Rv(k,Ne,M,le,gw(k),null)}}a.data[l]=k}}(f,a+20,Rl(f.consts,l))}function TE(a){return function(a){a&&(Dv|=1<<Math.min(Gm,31)),Gm++}(nf(Li(),pu(),a)),TE}function KC(a){!function(a,l,f){if(Gm>0){const m=a.data[f];kC(a,l,Array.isArray(m)?m:m.update,wr()-Gm-1,Dv)}Dv=0,Gm=0}(sa(),Li(),a+20)}function qC(a,l={}){return function(a,l={}){let f=a;if(Cw.test(a)){const m={},M=[0];f=f.replace(WC,(k,te,le)=>{const Ne=te||le,qe=m[Ne]||[];if(qe.length||(Ne.split("|").forEach(Ti=>{const ii=Ti.match(ww),Oo=ii?parseInt(ii[1],10):0,Xi=Ow.test(Ti);qe.push([Oo,Xi,Ti])}),m[Ne]=qe),!qe.length)throw new Error(`i18n postprocess: unmatched placeholder - ${Ne}`);const wt=M[M.length-1];let ln=0;for(let Ti=0;Ti<qe.length;Ti++)if(qe[Ti][0]===wt){ln=Ti;break}const[dn,nr,Rr]=qe[ln];return nr?M.pop():wt!==dn&&M.push(dn),qe.splice(ln,1),Rr})}return Object.keys(l).length&&(f=f.replace(Mw,(m,M,k,te,le,Ne)=>l.hasOwnProperty(k)?`${M}${l[k]}${Ne}`:m),f=f.replace(Aw,(m,M)=>l.hasOwnProperty(M)?l[M]:m),f=f.replace(JC,(m,M)=>{if(l.hasOwnProperty(M)){const k=l[M];if(!k.length)throw new Error(`i18n postprocess: unmatched ICU - ${m} with key: ${M}`);return k.shift()}return m})),f}(a,l)}function SE(a,l,f,m,M){if(a=Z(a),Array.isArray(a))for(let k=0;k<a.length;k++)SE(a[k],l,f,m,M);else{const k=sa(),te=Li();let le=Og(a)?a:Z(a.provide),Ne=Md(a);const qe=Ss(),wt=1048575&qe.providerIndexes,ln=qe.directiveStart,dn=qe.providerIndexes>>20;if(Og(a)||!a.multi){const nr=new Js(Ne,M,D1),Rr=ME(le,l,M?wt:wt+dn,ln);-1===Rr?(ga(ns(qe,te),k,le),CE(k,a,l.length),l.push(le),qe.directiveStart++,qe.directiveEnd++,M&&(qe.providerIndexes+=1048576),f.push(nr),te.push(nr)):(f[Rr]=nr,te[Rr]=nr)}else{const nr=ME(le,l,wt+dn,ln),Rr=ME(le,l,wt,wt+dn),Ti=nr>=0&&f[nr],ii=Rr>=0&&f[Rr];if(M&&!ii||!M&&!Ti){ga(ns(qe,te),k,le);const Oo=function(a,l,f,m,M){const k=new Js(a,f,D1);return k.multi=[],k.index=l,k.componentProviders=0,eM(k,M,m&&!f),k}(M?Nw:Rw,f.length,M,m,Ne);!M&&ii&&(f[Rr].providerFactory=Oo),CE(k,a,l.length,0),l.push(le),qe.directiveStart++,qe.directiveEnd++,M&&(qe.providerIndexes+=1048576),f.push(Oo),te.push(Oo)}else CE(k,a,nr>-1?nr:Rr,eM(f[M?Rr:nr],Ne,!M&&m));!M&&m&&ii&&f[Rr].componentProviders++}}}function CE(a,l,f,m){const M=Og(l);if(M||function(a){return!!a.useClass}(l)){const te=(l.useClass||l).prototype.ngOnDestroy;if(te){const le=a.destroyHooks||(a.destroyHooks=[]);if(!M&&l.multi){const Ne=le.indexOf(f);-1===Ne?le.push(f,[m,te]):le[Ne+1].push(m,te)}else le.push(f,te)}}}function eM(a,l,f){return f&&a.componentProviders++,a.multi.push(l)-1}function ME(a,l,f,m){for(let M=f;M<m;M++)if(l[M]===a)return M;return-1}function Rw(a,l,f,m){return AE(this.multi,[])}function Nw(a,l,f,m){const M=this.multi;let k;if(this.providerFactory){const te=this.providerFactory.componentProviders,le=Sc(f,f[1],this.providerFactory.index,m);k=le.slice(0,te),AE(M,k);for(let Ne=te;Ne<le.length;Ne++)k.push(le[Ne])}else k=[],AE(M,k);return k}function AE(a,l){for(let f=0;f<a.length;f++)l.push((0,a[f])());return l}function Pw(a,l=[]){return f=>{f.providersResolver=(m,M)=>function(a,l,f){const m=sa();if(m.firstCreatePass){const M=Ya(a);SE(f,m.data,m.blueprint,M,!0),SE(l,m.data,m.blueprint,M,!1)}}(m,M?M(a):a,l)}}class nM{}class rM{}const Sy="ngComponent";class Iw{resolveComponentFactory(l){throw function(a){const l=Error(`No component factory found for ${S(a)}. Did you add it to @NgModule.entryComponents?`);return l[Sy]=a,l}(l)}}let Pv=(()=>{class a{}return a.NULL=new Iw,a})();function I1(...a){}function Iv(a,l){return new og(Qi(a,l))}const Fw=function(){return Iv(Ss(),Li())};let og=(()=>{class a{constructor(f){this.nativeElement=f}}return a.__NG_ELEMENT_ID__=Fw,a})();function sM(a){return a instanceof og?a.nativeElement:a}class Cy{}let kw=(()=>{class a{}return a.__NG_ELEMENT_ID__=()=>Hw(),a})();const Hw=function(){const a=Li(),f=Ts(Ss().index,a);return function(a){return a[11]}(ca(f)?f:a)};let xE=(()=>{class a{}return a.\u0275prov=xt({token:a,providedIn:"root",factory:()=>null}),a})();class aM{constructor(l){this.full=l,this.major=l.split(".")[0],this.minor=l.split(".")[1],this.patch=l.split(".").slice(2).join(".")}}const lM=new aM("12.2.13");class uM{constructor(){}supports(l){return Hm(l)}create(l){return new Zw(l)}}const Yw=(a,l)=>l;class Zw{constructor(l){this.length=0,this._linkedRecords=null,this._unlinkedRecords=null,this._previousItHead=null,this._itHead=null,this._itTail=null,this._additionsHead=null,this._additionsTail=null,this._movesHead=null,this._movesTail=null,this._removalsHead=null,this._removalsTail=null,this._identityChangesHead=null,this._identityChangesTail=null,this._trackByFn=l||Yw}forEachItem(l){let f;for(f=this._itHead;null!==f;f=f._next)l(f)}forEachOperation(l){let f=this._itHead,m=this._removalsHead,M=0,k=null;for(;f||m;){const te=!m||f&&f.currentIndex<cM(m,M,k)?f:m,le=cM(te,M,k),Ne=te.currentIndex;if(te===m)M--,m=m._nextRemoved;else if(f=f._next,null==te.previousIndex)M++;else{k||(k=[]);const qe=le-M,wt=Ne-M;if(qe!=wt){for(let dn=0;dn<qe;dn++){const nr=dn<k.length?k[dn]:k[dn]=0,Rr=nr+dn;wt<=Rr&&Rr<qe&&(k[dn]=nr+1)}k[te.previousIndex]=wt-qe}}le!==Ne&&l(te,le,Ne)}}forEachPreviousItem(l){let f;for(f=this._previousItHead;null!==f;f=f._nextPrevious)l(f)}forEachAddedItem(l){let f;for(f=this._additionsHead;null!==f;f=f._nextAdded)l(f)}forEachMovedItem(l){let f;for(f=this._movesHead;null!==f;f=f._nextMoved)l(f)}forEachRemovedItem(l){let f;for(f=this._removalsHead;null!==f;f=f._nextRemoved)l(f)}forEachIdentityChange(l){let f;for(f=this._identityChangesHead;null!==f;f=f._nextIdentityChange)l(f)}diff(l){if(null==l&&(l=[]),!Hm(l))throw new Error(`Error trying to diff '${S(l)}'. Only arrays and iterables are allowed`);return this.check(l)?this:null}onDestroy(){}check(l){this._reset();let M,k,te,f=this._itHead,m=!1;if(Array.isArray(l)){this.length=l.length;for(let le=0;le<this.length;le++)k=l[le],te=this._trackByFn(le,k),null!==f&&Object.is(f.trackById,te)?(m&&(f=this._verifyReinsertion(f,k,te,le)),Object.is(f.item,k)||this._addIdentityChange(f,k)):(f=this._mismatch(f,k,te,le),m=!0),f=f._next}else M=0,function(a,l){if(Array.isArray(a))for(let f=0;f<a.length;f++)l(a[f]);else{const f=a[tg()]();let m;for(;!(m=f.next()).done;)l(m.value)}}(l,le=>{te=this._trackByFn(M,le),null!==f&&Object.is(f.trackById,te)?(m&&(f=this._verifyReinsertion(f,le,te,M)),Object.is(f.item,le)||this._addIdentityChange(f,le)):(f=this._mismatch(f,le,te,M),m=!0),f=f._next,M++}),this.length=M;return this._truncate(f),this.collection=l,this.isDirty}get isDirty(){return null!==this._additionsHead||null!==this._movesHead||null!==this._removalsHead||null!==this._identityChangesHead}_reset(){if(this.isDirty){let l;for(l=this._previousItHead=this._itHead;null!==l;l=l._next)l._nextPrevious=l._next;for(l=this._additionsHead;null!==l;l=l._nextAdded)l.previousIndex=l.currentIndex;for(this._additionsHead=this._additionsTail=null,l=this._movesHead;null!==l;l=l._nextMoved)l.previousIndex=l.currentIndex;this._movesHead=this._movesTail=null,this._removalsHead=this._removalsTail=null,this._identityChangesHead=this._identityChangesTail=null}}_mismatch(l,f,m,M){let k;return null===l?k=this._itTail:(k=l._prev,this._remove(l)),null!==(l=null===this._unlinkedRecords?null:this._unlinkedRecords.get(m,null))?(Object.is(l.item,f)||this._addIdentityChange(l,f),this._reinsertAfter(l,k,M)):null!==(l=null===this._linkedRecords?null:this._linkedRecords.get(m,M))?(Object.is(l.item,f)||this._addIdentityChange(l,f),this._moveAfter(l,k,M)):l=this._addAfter(new jw(f,m),k,M),l}_verifyReinsertion(l,f,m,M){let k=null===this._unlinkedRecords?null:this._unlinkedRecords.get(m,null);return null!==k?l=this._reinsertAfter(k,l._prev,M):l.currentIndex!=M&&(l.currentIndex=M,this._addToMoves(l,M)),l}_truncate(l){for(;null!==l;){const f=l._next;this._addToRemovals(this._unlink(l)),l=f}null!==this._unlinkedRecords&&this._unlinkedRecords.clear(),null!==this._additionsTail&&(this._additionsTail._nextAdded=null),null!==this._movesTail&&(this._movesTail._nextMoved=null),null!==this._itTail&&(this._itTail._next=null),null!==this._removalsTail&&(this._removalsTail._nextRemoved=null),null!==this._identityChangesTail&&(this._identityChangesTail._nextIdentityChange=null)}_reinsertAfter(l,f,m){null!==this._unlinkedRecords&&this._unlinkedRecords.remove(l);const M=l._prevRemoved,k=l._nextRemoved;return null===M?this._removalsHead=k:M._nextRemoved=k,null===k?this._removalsTail=M:k._prevRemoved=M,this._insertAfter(l,f,m),this._addToMoves(l,m),l}_moveAfter(l,f,m){return this._unlink(l),this._insertAfter(l,f,m),this._addToMoves(l,m),l}_addAfter(l,f,m){return this._insertAfter(l,f,m),this._additionsTail=null===this._additionsTail?this._additionsHead=l:this._additionsTail._nextAdded=l,l}_insertAfter(l,f,m){const M=null===f?this._itHead:f._next;return l._next=M,l._prev=f,null===M?this._itTail=l:M._prev=l,null===f?this._itHead=l:f._next=l,null===this._linkedRecords&&(this._linkedRecords=new My),this._linkedRecords.put(l),l.currentIndex=m,l}_remove(l){return this._addToRemovals(this._unlink(l))}_unlink(l){null!==this._linkedRecords&&this._linkedRecords.remove(l);const f=l._prev,m=l._next;return null===f?this._itHead=m:f._next=m,null===m?this._itTail=f:m._prev=f,l}_addToMoves(l,f){return l.previousIndex===f||(this._movesTail=null===this._movesTail?this._movesHead=l:this._movesTail._nextMoved=l),l}_addToRemovals(l){return null===this._unlinkedRecords&&(this._unlinkedRecords=new My),this._unlinkedRecords.put(l),l.currentIndex=null,l._nextRemoved=null,null===this._removalsTail?(this._removalsTail=this._removalsHead=l,l._prevRemoved=null):(l._prevRemoved=this._removalsTail,this._removalsTail=this._removalsTail._nextRemoved=l),l}_addIdentityChange(l,f){return l.item=f,this._identityChangesTail=null===this._identityChangesTail?this._identityChangesHead=l:this._identityChangesTail._nextIdentityChange=l,l}}class jw{constructor(l,f){this.item=l,this.trackById=f,this.currentIndex=null,this.previousIndex=null,this._nextPrevious=null,this._prev=null,this._next=null,this._prevDup=null,this._nextDup=null,this._prevRemoved=null,this._nextRemoved=null,this._nextAdded=null,this._nextMoved=null,this._nextIdentityChange=null}}class Gw{constructor(){this._head=null,this._tail=null}add(l){null===this._head?(this._head=this._tail=l,l._nextDup=null,l._prevDup=null):(this._tail._nextDup=l,l._prevDup=this._tail,l._nextDup=null,this._tail=l)}get(l,f){let m;for(m=this._head;null!==m;m=m._nextDup)if((null===f||f<=m.currentIndex)&&Object.is(m.trackById,l))return m;return null}remove(l){const f=l._prevDup,m=l._nextDup;return null===f?this._head=m:f._nextDup=m,null===m?this._tail=f:m._prevDup=f,null===this._head}}class My{constructor(){this.map=new Map}put(l){const f=l.trackById;let m=this.map.get(f);m||(m=new Gw,this.map.set(f,m)),m.add(l)}get(l,f){const M=this.map.get(l);return M?M.get(l,f):null}remove(l){const f=l.trackById;return this.map.get(f).remove(l)&&this.map.delete(f),l}get isEmpty(){return 0===this.map.size}clear(){this.map.clear()}}function cM(a,l,f){const m=a.previousIndex;if(null===m)return m;let M=0;return f&&m<f.length&&(M=f[m]),m+l+M}class dM{constructor(){}supports(l){return l instanceof Map||M1(l)}create(){return new Vw}}class Vw{constructor(){this._records=new Map,this._mapHead=null,this._appendAfter=null,this._previousMapHead=null,this._changesHead=null,this._changesTail=null,this._additionsHead=null,this._additionsTail=null,this._removalsHead=null,this._removalsTail=null}get isDirty(){return null!==this._additionsHead||null!==this._changesHead||null!==this._removalsHead}forEachItem(l){let f;for(f=this._mapHead;null!==f;f=f._next)l(f)}forEachPreviousItem(l){let f;for(f=this._previousMapHead;null!==f;f=f._nextPrevious)l(f)}forEachChangedItem(l){let f;for(f=this._changesHead;null!==f;f=f._nextChanged)l(f)}forEachAddedItem(l){let f;for(f=this._additionsHead;null!==f;f=f._nextAdded)l(f)}forEachRemovedItem(l){let f;for(f=this._removalsHead;null!==f;f=f._nextRemoved)l(f)}diff(l){if(l){if(!(l instanceof Map||M1(l)))throw new Error(`Error trying to diff '${S(l)}'. Only maps and objects are allowed`)}else l=new Map;return this.check(l)?this:null}onDestroy(){}check(l){this._reset();let f=this._mapHead;if(this._appendAfter=null,this._forEach(l,(m,M)=>{if(f&&f.key===M)this._maybeAddToChanges(f,m),this._appendAfter=f,f=f._next;else{const k=this._getOrCreateRecordForKey(M,m);f=this._insertBeforeOrAppend(f,k)}}),f){f._prev&&(f._prev._next=null),this._removalsHead=f;for(let m=f;null!==m;m=m._nextRemoved)m===this._mapHead&&(this._mapHead=null),this._records.delete(m.key),m._nextRemoved=m._next,m.previousValue=m.currentValue,m.currentValue=null,m._prev=null,m._next=null}return this._changesTail&&(this._changesTail._nextChanged=null),this._additionsTail&&(this._additionsTail._nextAdded=null),this.isDirty}_insertBeforeOrAppend(l,f){if(l){const m=l._prev;return f._next=l,f._prev=m,l._prev=f,m&&(m._next=f),l===this._mapHead&&(this._mapHead=f),this._appendAfter=l,l}return this._appendAfter?(this._appendAfter._next=f,f._prev=this._appendAfter):this._mapHead=f,this._appendAfter=f,null}_getOrCreateRecordForKey(l,f){if(this._records.has(l)){const M=this._records.get(l);this._maybeAddToChanges(M,f);const k=M._prev,te=M._next;return k&&(k._next=te),te&&(te._prev=k),M._next=null,M._prev=null,M}const m=new zw(l);return this._records.set(l,m),m.currentValue=f,this._addToAdditions(m),m}_reset(){if(this.isDirty){let l;for(this._previousMapHead=this._mapHead,l=this._previousMapHead;null!==l;l=l._next)l._nextPrevious=l._next;for(l=this._changesHead;null!==l;l=l._nextChanged)l.previousValue=l.currentValue;for(l=this._additionsHead;null!=l;l=l._nextAdded)l.previousValue=l.currentValue;this._changesHead=this._changesTail=null,this._additionsHead=this._additionsTail=null,this._removalsHead=null}}_maybeAddToChanges(l,f){Object.is(f,l.currentValue)||(l.previousValue=l.currentValue,l.currentValue=f,this._addToChanges(l))}_addToAdditions(l){null===this._additionsHead?this._additionsHead=this._additionsTail=l:(this._additionsTail._nextAdded=l,this._additionsTail=l)}_addToChanges(l){null===this._changesHead?this._changesHead=this._changesTail=l:(this._changesTail._nextChanged=l,this._changesTail=l)}_forEach(l,f){l instanceof Map?l.forEach(f):Object.keys(l).forEach(m=>f(l[m],m))}}class zw{constructor(l){this.key=l,this.previousValue=null,this.currentValue=null,this._nextPrevious=null,this._next=null,this._prev=null,this._nextAdded=null,this._nextRemoved=null,this._nextChanged=null}}function fM(){return new Ay([new uM])}let Ay=(()=>{class a{constructor(f){this.factories=f}static create(f,m){if(null!=m){const M=m.factories.slice();f=f.concat(M)}return new a(f)}static extend(f){return{provide:a,useFactory:m=>a.create(f,m||fM()),deps:[[a,new il,new ia]]}}find(f){const m=this.factories.find(M=>M.supports(f));if(null!=m)return m;throw new Error(`Cannot find a differ supporting object '${f}' of type '${function(a){return a.name||typeof a}(f)}'`)}}return a.\u0275prov=xt({token:a,providedIn:"root",factory:fM}),a})();function pM(){return new Oy([new dM])}let Oy=(()=>{class a{constructor(f){this.factories=f}static create(f,m){if(m){const M=m.factories.slice();f=f.concat(M)}return new a(f)}static extend(f){return{provide:a,useFactory:m=>a.create(f,m||pM()),deps:[[a,new il,new ia]]}}find(f){const m=this.factories.find(M=>M.supports(f));if(m)return m;throw new Error(`Cannot find a differ supporting object '${f}'`)}}return a.\u0275prov=xt({token:a,providedIn:"root",factory:pM}),a})();function wy(a,l,f,m,M=!1){for(;null!==f;){const k=l[f.index];if(null!==k&&m.push(Me(k)),$s(k))for(let le=10;le<k.length;le++){const Ne=k[le],qe=Ne[1].firstChild;null!==qe&&wy(Ne[1],Ne,qe,m)}const te=f.type;if(8&te)wy(a,l,f.child,m);else if(32&te){const le=bf(f,l);let Ne;for(;Ne=le();)m.push(Ne)}else if(16&te){const le=bg(l,f);if(Array.isArray(le))m.push(...le);else{const Ne=od(l[16]);wy(Ne[1],Ne,le,m,!0)}}f=M?f.projectionNext:f.next}return m}class L1{constructor(l,f){this._lView=l,this._cdRefInjectingView=f,this._appRef=null,this._attachedToViewContainer=!1}get rootNodes(){const l=this._lView,f=l[1];return wy(f,l,f.firstChild,[])}get context(){return this._lView[8]}set context(l){this._lView[8]=l}get destroyed(){return 256==(256&this._lView[2])}destroy(){if(this._appRef)this._appRef.detachView(this);else if(this._attachedToViewContainer){const l=this._lView[3];if($s(l)){const f=l[8],m=f?f.indexOf(this):-1;m>-1&&(gg(l,m),cl(f,m))}this._attachedToViewContainer=!1}Ep(this._lView[1],this._lView)}onDestroy(l){at(this._lView[1],this._lView,null,l)}markForCheck(){I0(this._cdRefInjectingView||this._lView)}detach(){this._lView[2]&=-129}reattach(){this._lView[2]|=128}detectChanges(){Pm(this._lView[1],this._lView,this.context)}checkNoChanges(){!function(a,l,f){Bo(!0);try{Pm(a,l,f)}finally{Bo(!1)}}(this._lView[1],this._lView,this.context)}attachToViewContainerRef(){if(this._appRef)throw new Error("This view is already attached directly to the ApplicationRef!");this._attachedToViewContainer=!0}detachFromAppRef(){var l;this._appRef=null,jh(this._lView[1],l=this._lView,l[11],2,null,null)}attachToAppRef(l){if(this._attachedToViewContainer)throw new Error("This view is already attached to a ViewContainer!");this._appRef=l}}class Jw extends L1{constructor(l){super(l),this._view=l}detectChanges(){Xh(this._view)}checkNoChanges(){!function(a){Bo(!0);try{Xh(a)}finally{Bo(!1)}}(this._view)}get context(){return null}}const Xw=function(a){return function(a,l,f){if(Il(a)&&!f){const m=Ts(a.index,l);return new L1(m,m)}return 47&a.type?new L1(l[16],l):null}(Ss(),Li(),16==(16&a))};let Kw=(()=>{class a{}return a.__NG_ELEMENT_ID__=Xw,a})();const tx=[new dM],rx=new Ay([new uM]),ix=new Oy(tx),sx=function(){return xy(Ss(),Li())};let F1=(()=>{class a{}return a.__NG_ELEMENT_ID__=sx,a})();const ax=F1,lx=class extends ax{constructor(l,f,m){super(),this._declarationLView=l,this._declarationTContainer=f,this.elementRef=m}createEmbeddedView(l){const f=this._declarationTContainer.tViews,m=Ap(this._declarationLView,f,l,16,null,f.declTNode,null,null,null,null);m[17]=this._declarationLView[this._declarationTContainer.index];const k=this._declarationLView[19];return null!==k&&(m[19]=k.createEmbeddedView(f)),X_(f,m,l),new L1(m)}};function xy(a,l){return 4&a.type?new lx(l,a,Iv(a,l)):null}class zm{}class DE{}const dx=function(){return gM(Ss(),Li())};let Dy=(()=>{class a{}return a.__NG_ELEMENT_ID__=dx,a})();const px=Dy,hM=class extends px{constructor(l,f,m){super(),this._lContainer=l,this._hostTNode=f,this._hostLView=m}get element(){return Iv(this._hostTNode,this._hostLView)}get injector(){return new jc(this._hostTNode,this._hostLView)}get parentInjector(){const l=fc(this._hostTNode,this._hostLView);if(Ye(l)){const f=ot(l,this._hostLView),m=Ie(l);return new jc(f[1].data[m+8],f)}return new jc(null,this._hostLView)}clear(){for(;this.length>0;)this.remove(this.length-1)}get(l){const f=_M(this._lContainer);return null!==f&&f[l]||null}get length(){return this._lContainer.length-10}createEmbeddedView(l,f,m){const M=l.createEmbeddedView(f||{});return this.insert(M,m),M}createComponent(l,f,m,M,k){const te=m||this.parentInjector;if(!k&&null==l.ngModule&&te){const Ne=te.get(zm,null);Ne&&(k=Ne)}const le=l.create(te,M,void 0,k);return this.insert(le.hostView,f),le}insert(l,f){const m=l._lView,M=m[1];if($s(m[3])){const wt=this.indexOf(l);if(-1!==wt)this.detach(wt);else{const ln=m[3],dn=new hM(ln,ln[6],ln[3]);dn.detach(dn.indexOf(l))}}const k=this._adjustIndex(f),te=this._lContainer;!function(a,l,f,m){const M=10+m,k=f.length;m>0&&(f[M-1][4]=l),m<k-10?(l[4]=f[M],Ji(f,10+m,l)):(f.push(l),l[4]=null),l[3]=f;const te=l[17];null!==te&&f!==te&&function(a,l){const f=a[9];l[16]!==l[3][3][16]&&(a[2]=!0),null===f?a[9]=[l]:f.push(l)}(te,l);const le=l[19];null!==le&&le.insertView(a),l[2]|=128}(M,m,te,k);const le=Eg(k,te),Ne=m[11],qe=Yd(Ne,te[7]);return null!==qe&&function(a,l,f,m,M,k){m[0]=M,m[6]=l,jh(a,m,f,1,M,k)}(M,te[6],Ne,m,qe,le),l.attachToViewContainerRef(),Ji(RE(te),k,l),l}move(l,f){return this.insert(l,f)}indexOf(l){const f=_M(this._lContainer);return null!==f?f.indexOf(l):-1}remove(l){const f=this._adjustIndex(l,-1),m=gg(this._lContainer,f);m&&(cl(RE(this._lContainer),f),Ep(m[1],m))}detach(l){const f=this._adjustIndex(l,-1),m=gg(this._lContainer,f);return m&&null!=cl(RE(this._lContainer),f)?new L1(m):null}_adjustIndex(l,f=0){return null==l?this.length+f:l}};function _M(a){return a[8]}function RE(a){return a[8]||(a[8]=[])}function gM(a,l){let f;const m=l[a.index];if($s(m))f=m;else{let M;if(8&a.type)M=Me(m);else{const k=l[11];M=k.createComment("");const te=Qi(a,l);_h(k,Yd(k,te),M,function(a,l){return rt(a)?a.nextSibling(l):l.nextSibling}(k,te),!1)}l[a.index]=f=Wg(m,l,M,a),h1(l,f)}return new hM(f,a,l)}const Uv={};class Uy extends Pv{constructor(l){super(),this.ngModule=l}resolveComponentFactory(l){const f=Co(l);return new V1(f,this.ngModule)}}function GE(a){const l=[];for(let f in a)a.hasOwnProperty(f)&&l.push({propName:a[f],templateName:f});return l}const Zx=new Jl("SCHEDULER_TOKEN",{providedIn:"root",factory:()=>Hh});class V1 extends rM{constructor(l,f){super(),this.componentDef=l,this.ngModule=f,this.componentType=l.type,this.selector=l.selectors.map(as).join(","),this.ngContentSelectors=l.ngContentSelectors?l.ngContentSelectors:[],this.isBoundToModule=!!f}get inputs(){return GE(this.componentDef.inputs)}get outputs(){return GE(this.componentDef.outputs)}create(l,f,m,M){const k=(M=M||this.ngModule)?function(a,l){return{get:(f,m,M)=>{const k=a.get(f,Uv,M);return k!==Uv||m===Uv?k:l.get(f,m,M)}}}(l,M.injector):l,te=k.get(Cy,dt),le=k.get(xE,null),Ne=te.createRenderer(null,this.componentDef),qe=this.componentDef.selectors[0][0]||"div",wt=m?function(a,l,f){if(rt(a))return a.selectRootElement(l,f===Gn.ShadowDom);let m="string"==typeof l?a.querySelector(l):l;return m.textContent="",m}(Ne,m,this.componentDef.encapsulation):Bh(te.createRenderer(null,this.componentDef),qe,function(a){const l=a.toLowerCase();return"svg"===l?"http://www.w3.org/2000/svg":"math"===l?"http://www.w3.org/1998/MathML/":null}(qe)),ln=this.componentDef.onPush?576:528,dn=function(a,l){return{components:[],scheduler:a||Hh,clean:vS,playerHandler:l||null,flags:0}}(),nr=zg(0,null,null,1,0,null,null,null,null,null),Rr=Ap(null,nr,dn,ln,null,null,te,Ne,le,k);let Ti,ii;un(Rr);try{const Oo=function(a,l,f,m,M,k){const te=f[1];f[20]=a;const Ne=ip(te,20,2,"#host",null),qe=Ne.mergedAttrs=l.hostAttrs;null!==qe&&(vv(Ne,qe,!0),null!==a&&(ic(M,a,qe),null!==Ne.classes&&Gh(M,a,Ne.classes),null!==Ne.styles&&Zg(M,a,Ne.styles)));const wt=m.createRenderer(a,l),ln=Ap(f,_v(l),null,l.onPush?64:16,f[20],Ne,m,wt,k||null,null);return te.firstCreatePass&&(ga(ns(Ne,f),te,l.type),ju(te,Ne),R0(Ne,f.length,1)),h1(f,ln),f[20]=ln}(wt,this.componentDef,Rr,te,Ne);if(wt)if(m)ic(Ne,wt,["ng-version",lM.full]);else{const{attrs:Xi,classes:ua}=function(a){const l=[],f=[];let m=1,M=2;for(;m<a.length;){let k=a[m];if("string"==typeof k)2===M?""!==k&&l.push(k,a[++m]):8===M&&f.push(k);else{if(!G(M))break;M=k}m++}return{attrs:l,classes:f}}(this.componentDef.selectors[0]);Xi&&ic(Ne,wt,Xi),ua&&ua.length>0&&Gh(Ne,wt,ua.join(" "))}if(ii=ms(nr,20),void 0!==f){const Xi=ii.projection=[];for(let ua=0;ua<this.ngContentSelectors.length;ua++){const Xa=f[ua];Xi.push(null!=Xa?Array.from(Xa):null)}}Ti=function(a,l,f,m,M){const k=f[1],te=function(a,l,f){const m=Ss();a.firstCreatePass&&(f.providersResolver&&f.providersResolver(f),N0(a,m,l,Vp(a,l,1,null),f));const M=Sc(l,a,m.directiveStart,m);Wc(M,l);const k=Qi(m,l);return k&&Wc(k,l),M}(k,f,l);if(m.components.push(te),a[8]=te,M&&M.forEach(Ne=>Ne(te,l)),l.contentQueries){const Ne=Ss();l.contentQueries(1,te,Ne.directiveStart)}const le=Ss();return!k.firstCreatePass||null===l.hostBindings&&null===l.hostAttrs||(Cr(le.index),Op(f[1],le,0,le.directiveStart,le.directiveEnd,l),Qc(l,te)),te}(Oo,this.componentDef,Rr,dn,[ny]),X_(nr,Rr,null)}finally{ai()}return new jx(this.componentType,Ti,Iv(ii,Rr),Rr,ii)}}class jx extends nM{constructor(l,f,m,M,k){super(),this.location=m,this._rootLView=M,this._tNode=k,this.instance=f,this.hostView=this.changeDetectorRef=new Jw(M),this.componentType=l}get injector(){return new jc(this._tNode,this._rootLView)}destroy(){this.hostView.destroy()}onDestroy(l){this.hostView.onDestroy(l)}}const Bv=new Map;class zx extends zm{constructor(l,f){super(),this._parent=f,this._bootstrapComponents=[],this.injector=this,this.destroyCbs=[],this.componentFactoryResolver=new Uy(this);const m=jo(l),M=l[Yt]||null;M&&pE(M),this._bootstrapComponents=yf(m.bootstrap),this._r3Injector=Sb(l,f,[{provide:zm,useValue:this},{provide:Pv,useValue:this.componentFactoryResolver}],S(l)),this._r3Injector._resolveInjectorDefTypes(),this.instance=this.get(l)}get(l,f=Ac.THROW_IF_NOT_FOUND,m=Yr.Default){return l===Ac||l===zm||l===Jg?this:this._r3Injector.get(l,f,m)}destroy(){const l=this._r3Injector;!l.destroyed&&l.destroy(),this.destroyCbs.forEach(f=>f()),this.destroyCbs=null}onDestroy(l){this.destroyCbs.push(l)}}class zE extends DE{constructor(l){super(),this.moduleType=l,null!==jo(l)&&function(a){const l=new Set;!function f(m){const M=jo(m,!0),k=M.id;null!==k&&(function(a,l,f){if(l&&l!==f)throw new Error(`Duplicate module registered for ${a} - ${S(l)} vs ${S(l.name)}`)}(k,Bv.get(k),m),Bv.set(k,m));const te=yf(M.imports);for(const le of te)l.has(le)||(l.add(le),f(le))}(a)}(l)}create(l){return new zx(this.moduleType,l)}}function WE(a,l,f){const m=uu()+a,M=Li();return M[m]===po?Kh(M,m,f?l.call(f):l()):Um(M,m)}function JE(a,l,f,m){return QM(Li(),uu(),a,l,f,m)}function z1(a,l,f,m,M){return XM(Li(),uu(),a,l,f,m,M)}function WM(a,l,f,m,M,k){return KM(Li(),uu(),a,l,f,m,M,k)}function e_(a,l,f,m,M,k,te){return function(a,l,f,m,M,k,te,le,Ne){const qe=l+f;return zp(a,qe,M,k,te,le)?Kh(a,qe+4,Ne?m.call(Ne,M,k,te,le):m(M,k,te,le)):W1(a,qe+4)}(Li(),uu(),a,l,f,m,M,k,te)}function JM(a,l,f,m,M,k,te,le){const Ne=uu()+a,qe=Li(),wt=zp(qe,Ne,f,m,M,k);return nf(qe,Ne+4,te)||wt?Kh(qe,Ne+5,le?l.call(le,f,m,M,k,te):l(f,m,M,k,te)):Um(qe,Ne+5)}function W1(a,l){const f=a[l];return f===po?void 0:f}function QM(a,l,f,m,M,k){const te=l+f;return nf(a,te,M)?Kh(a,te+1,k?m.call(k,M):m(M)):W1(a,te+1)}function XM(a,l,f,m,M,k,te){const le=l+f;return A_(a,le,M,k)?Kh(a,le+2,te?m.call(te,M,k):m(M,k)):W1(a,le+2)}function KM(a,l,f,m,M,k,te,le){const Ne=l+f;return Sv(a,Ne,M,k,te)?Kh(a,Ne+3,le?m.call(le,M,k,te):m(M,k,te)):W1(a,Ne+3)}function e2(a,l){const f=sa();let m;const M=a+20;f.firstCreatePass?(m=function(a,l){if(l)for(let f=l.length-1;f>=0;f--){const m=l[f];if(a===m.name)return m}throw new ee("302",`The pipe '${a}' could not be found!`)}(l,f.pipeRegistry),f.data[M]=m,m.onDestroy&&(f.destroyHooks||(f.destroyHooks=[])).push(M,m.onDestroy)):m=f.data[M];const k=m.factory||(m.factory=wo(m.type)),te=Hi(D1);try{const le=qt(!1),Ne=k();return qt(le),function(a,l,f,m){f>=a.data.length&&(a.data[f]=null,a.blueprint[f]=null),l[f]=m}(f,Li(),M,Ne),Ne}finally{Hi(te)}}function t2(a,l,f){const m=a+20,M=Li(),k=hs(M,m);return J1(M,Qm(M,m)?QM(M,uu(),l,k.transform,f,k):k.transform(f))}function bh(a,l,f,m){const M=a+20,k=Li(),te=hs(k,M);return J1(k,Qm(k,M)?XM(k,uu(),l,te.transform,f,m,te):te.transform(f,m))}function n2(a,l,f,m,M){const k=a+20,te=Li(),le=hs(te,k);return J1(te,Qm(te,k)?KM(te,uu(),l,le.transform,f,m,M,le):le.transform(f,m,M))}function Qm(a,l){return a[1].data[l].pure}function J1(a,l){return mh.isWrapped(l)&&(l=mh.unwrap(l),a[wr()]=po),l}function XE(a){return l=>{setTimeout(a,void 0,l)}}const Wp=class extends r.xQ{constructor(l=!1){super(),this.__isAsync=l}emit(l){super.next(l)}subscribe(l,f,m){var M,k,te;let le=l,Ne=f||(()=>null),qe=m;if(l&&"object"==typeof l){const ln=l;le=null===(M=ln.next)||void 0===M?void 0:M.bind(ln),Ne=null===(k=ln.error)||void 0===k?void 0:k.bind(ln),qe=null===(te=ln.complete)||void 0===te?void 0:te.bind(ln)}this.__isAsync&&(Ne=XE(Ne),le&&(le=XE(le)),qe&&(qe=XE(qe)));const wt=super.subscribe({next:le,error:Ne,complete:qe});return l instanceof u.w&&l.add(wt),wt}};function Kx(){return this._results[tg()]()}class Tu{constructor(l=!1){this._emitDistinctChangesOnly=l,this.dirty=!0,this._results=[],this._changesDetected=!1,this._changes=null,this.length=0,this.first=void 0,this.last=void 0;const f=tg(),m=Tu.prototype;m[f]||(m[f]=Kx)}get changes(){return this._changes||(this._changes=new Wp)}get(l){return this._results[l]}map(l){return this._results.map(l)}filter(l){return this._results.filter(l)}find(l){return this._results.find(l)}reduce(l,f){return this._results.reduce(l,f)}forEach(l){this._results.forEach(l)}some(l){return this._results.some(l)}toArray(){return this._results.slice()}toString(){return this._results.toString()}reset(l,f){const m=this;m.dirty=!1;const M=Dc(l);(this._changesDetected=!function(a,l,f){if(a.length!==l.length)return!1;for(let m=0;m<a.length;m++){let M=a[m],k=l[m];if(f&&(M=f(M),k=f(k)),k!==M)return!1}return!0}(m._results,M,f))&&(m._results=M,m.length=M.length,m.last=M[this.length-1],m.first=M[0])}notifyOnChanges(){this._changes&&(this._changesDetected||!this._emitDistinctChangesOnly)&&this._changes.emit(this)}setDirty(){this.dirty=!0}destroy(){this.changes.complete(),this.changes.unsubscribe()}}Symbol;class ra{constructor(l){this.queryList=l,this.matches=null}clone(){return new ra(this.queryList)}setDirty(){this.queryList.setDirty()}}class KE{constructor(l=[]){this.queries=l}createEmbeddedView(l){const f=l.queries;if(null!==f){const m=null!==l.contentQueries?l.contentQueries[0]:f.length,M=[];for(let k=0;k<m;k++){const te=f.getByIndex(k);M.push(this.queries[te.indexInDeclarationView].clone())}return new KE(M)}return null}insertView(l){this.dirtyQueriesWithMatches(l)}detachView(l){this.dirtyQueriesWithMatches(l)}dirtyQueriesWithMatches(l){for(let f=0;f<this.queries.length;f++)null!==d2(l,f).matches&&this.queries[f].setDirty()}}class qE{constructor(l,f,m=null){this.predicate=l,this.flags=f,this.read=m}}class eT{constructor(l=[]){this.queries=l}elementStart(l,f){for(let m=0;m<this.queries.length;m++)this.queries[m].elementStart(l,f)}elementEnd(l){for(let f=0;f<this.queries.length;f++)this.queries[f].elementEnd(l)}embeddedTView(l){let f=null;for(let m=0;m<this.length;m++){const M=null!==f?f.length:0,k=this.getByIndex(m).embeddedTView(l,M);k&&(k.indexInDeclarationView=m,null!==f?f.push(k):f=[k])}return null!==f?new eT(f):null}template(l,f){for(let m=0;m<this.queries.length;m++)this.queries[m].template(l,f)}getByIndex(l){return this.queries[l]}get length(){return this.queries.length}track(l){this.queries.push(l)}}class Np{constructor(l,f=-1){this.metadata=l,this.matches=null,this.indexInDeclarationView=-1,this.crossesNgTemplate=!1,this._appliesToNextNode=!0,this._declarationNodeIndex=f}elementStart(l,f){this.isApplyingToNode(f)&&this.matchTNode(l,f)}elementEnd(l){this._declarationNodeIndex===l.index&&(this._appliesToNextNode=!1)}template(l,f){this.elementStart(l,f)}embeddedTView(l,f){return this.isApplyingToNode(l)?(this.crossesNgTemplate=!0,this.addMatch(-l.index,f),new Np(this.metadata)):null}isApplyingToNode(l){if(this._appliesToNextNode&&1!=(1&this.metadata.flags)){const f=this._declarationNodeIndex;let m=l.parent;for(;null!==m&&8&m.type&&m.index!==f;)m=m.parent;return f===(null!==m?m.index:-1)}return this._appliesToNextNode}matchTNode(l,f){const m=this.metadata.predicate;if(Array.isArray(m))for(let M=0;M<m.length;M++){const k=m[M];this.matchTNodeWithReadOption(l,f,JR(f,k)),this.matchTNodeWithReadOption(l,f,Qd(f,l,k,!1,!1))}else m===F1?4&f.type&&this.matchTNodeWithReadOption(l,f,-1):this.matchTNodeWithReadOption(l,f,Qd(f,l,m,!1,!1))}matchTNodeWithReadOption(l,f,m){if(null!==m){const M=this.metadata.read;if(null!==M)if(M===og||M===Dy||M===F1&&4&f.type)this.addMatch(f.index,-2);else{const k=Qd(f,l,M,!1,!1);null!==k&&this.addMatch(f.index,k)}else this.addMatch(f.index,m)}}addMatch(l,f){null===this.matches?this.matches=[l,f]:this.matches.push(l,f)}}function JR(a,l){const f=a.localNames;if(null!==f)for(let m=0;m<f.length;m+=2)if(f[m]===l)return f[m+1];return null}function tT(a,l,f,m){return-1===f?function(a,l){return 11&a.type?Iv(a,l):4&a.type?xy(a,l):null}(l,a):-2===f?function(a,l,f){return f===og?Iv(l,a):f===F1?xy(l,a):f===Dy?gM(l,a):void 0}(a,l,m):Sc(a,a[1],f,l)}function i2(a,l,f,m){const M=l[19].queries[m];if(null===M.matches){const k=a.data,te=f.matches,le=[];for(let Ne=0;Ne<te.length;Ne+=2){const qe=te[Ne];le.push(qe<0?null:tT(l,k[qe],te[Ne+1],f.metadata.read))}M.matches=le}return M.matches}function nT(a,l,f,m){const M=a.queries.getByIndex(f),k=M.matches;if(null!==k){const te=i2(a,l,M,f);for(let le=0;le<k.length;le+=2){const Ne=k[le];if(Ne>0)m.push(te[le/2]);else{const qe=k[le+1],wt=l[-Ne];for(let ln=10;ln<wt.length;ln++){const dn=wt[ln];dn[17]===dn[3]&&nT(dn[1],dn,qe,m)}if(null!==wt[9]){const ln=wt[9];for(let dn=0;dn<ln.length;dn++){const nr=ln[dn];nT(nr[1],nr,qe,m)}}}}}return m}function o2(a){const l=Li(),f=sa(),m=Ae();st(m+1);const M=d2(f,m);if(a.dirty&&Ma(l)===(2==(2&M.metadata.flags))){if(null===M.matches)a.reset([]);else{const k=M.crossesNgTemplate?nT(f,l,m,[]):i2(f,l,M,m);a.reset(k,sM),a.notifyOnChanges()}return!0}return!1}function s2(a,l,f){const m=sa();m.firstCreatePass&&(c2(m,new qE(a,l,f),-1),2==(2&l)&&(m.staticViewQueries=!0)),u2(m,Li(),l)}function a2(a,l,f,m){const M=sa();if(M.firstCreatePass){const k=Ss();c2(M,new qE(l,f,m),k.index),function(a,l){const f=a.contentQueries||(a.contentQueries=[]);l!==(f.length?f[f.length-1]:-1)&&f.push(a.queries.length-1,l)}(M,a),2==(2&f)&&(M.staticContentQueries=!0)}u2(M,Li(),f)}function l2(){return a=Li(),l=Ae(),a[19].queries[l].queryList;var a,l}function u2(a,l,f){const m=new Tu(4==(4&f));at(a,l,m,m.destroy),null===l[19]&&(l[19]=new KE),l[19].queries.push(new ra(m))}function c2(a,l,f){null===a.queries&&(a.queries=new eT),a.queries.track(new Np(l,f))}function d2(a,l){return a.queries.getByIndex(l)}function of(a,l){return xy(a,l)}const w2=Oc("Input",a=>({bindingPropertyName:a})),gD=Oc("Output",a=>({bindingPropertyName:a})),yT=new Jl("Application Initializer");let Zv=(()=>{class a{constructor(f){this.appInits=f,this.resolve=I1,this.reject=I1,this.initialized=!1,this.done=!1,this.donePromise=new Promise((m,M)=>{this.resolve=m,this.reject=M})}runInitializers(){if(this.initialized)return;const f=[],m=()=>{this.done=!0,this.resolve()};if(this.appInits)for(let M=0;M<this.appInits.length;M++){const k=this.appInits[M]();if(Zm(k))f.push(k);else if(qb(k)){const te=new Promise((le,Ne)=>{k.subscribe({complete:le,error:Ne})});f.push(te)}}Promise.all(f).then(()=>{m()}).catch(M=>{this.reject(M)}),0===f.length&&m(),this.initialized=!0}}return a.\u0275fac=function(f){return new(f||a)(xn(yT,8))},a.\u0275prov=xt({token:a,factory:a.\u0275fac}),a})();const N2=new Jl("AppId"),I2={provide:N2,useFactory:function(){return`${jy()}${jy()}${jy()}`},deps:[]};function jy(){return String.fromCharCode(97+Math.floor(25*Math.random()))}const D_=new Jl("Platform Initializer"),cm=new Jl("Platform ID"),Pp=new Jl("appBootstrapListener");let L2=(()=>{class a{log(f){console.log(f)}warn(f){console.warn(f)}}return a.\u0275fac=function(f){return new(f||a)},a.\u0275prov=xt({token:a,factory:a.\u0275fac}),a})();const Gy=new Jl("LocaleId"),F2=new Jl("DefaultCurrencyCode");class $2{constructor(l,f){this.ngModuleFactory=l,this.componentFactories=f}}const zy=function(a){return new zE(a)},dm=zy,ET=function(a){return Promise.resolve(zy(a))},t0=function(a){const l=zy(a),m=yf(jo(a).declarations).reduce((M,k)=>{const te=Co(k);return te&&M.push(new V1(te)),M},[]);return new $2(l,m)},TT=t0,MD=function(a){return Promise.resolve(t0(a))};let n0=(()=>{class a{constructor(){this.compileModuleSync=dm,this.compileModuleAsync=ET,this.compileModuleAndAllComponentsSync=TT,this.compileModuleAndAllComponentsAsync=MD}clearCache(){}clearCacheFor(f){}getModuleId(f){}}return a.\u0275fac=function(f){return new(f||a)},a.\u0275prov=xt({token:a,factory:a.\u0275fac}),a})();const OD=(()=>Promise.resolve(0))();function ST(a){"undefined"==typeof Zone?OD.then(()=>{a&&a.apply(null,null)}):Zone.current.scheduleMicroTask("scheduleMicrotask",a)}class Eh{constructor({enableLongStackTrace:l=!1,shouldCoalesceEventChangeDetection:f=!1,shouldCoalesceRunChangeDetection:m=!1}){if(this.hasPendingMacrotasks=!1,this.hasPendingMicrotasks=!1,this.isStable=!0,this.onUnstable=new Wp(!1),this.onMicrotaskEmpty=new Wp(!1),this.onStable=new Wp(!1),this.onError=new Wp(!1),"undefined"==typeof Zone)throw new Error("In this configuration Angular requires Zone.js");Zone.assertZonePatched();const M=this;M._nesting=0,M._outer=M._inner=Zone.current,Zone.TaskTrackingZoneSpec&&(M._inner=M._inner.fork(new Zone.TaskTrackingZoneSpec)),l&&Zone.longStackTraceZoneSpec&&(M._inner=M._inner.fork(Zone.longStackTraceZoneSpec)),M.shouldCoalesceEventChangeDetection=!m&&f,M.shouldCoalesceRunChangeDetection=m,M.lastRequestAnimationFrameId=-1,M.nativeRequestAnimationFrame=function(){let a=Dr.requestAnimationFrame,l=Dr.cancelAnimationFrame;if("undefined"!=typeof Zone&&a&&l){const f=a[Zone.__symbol__("OriginalDelegate")];f&&(a=f);const m=l[Zone.__symbol__("OriginalDelegate")];m&&(l=m)}return{nativeRequestAnimationFrame:a,nativeCancelAnimationFrame:l}}().nativeRequestAnimationFrame,function(a){const l=()=>{!function(a){a.isCheckStableRunning||-1!==a.lastRequestAnimationFrameId||(a.lastRequestAnimationFrameId=a.nativeRequestAnimationFrame.call(Dr,()=>{a.fakeTopEventTask||(a.fakeTopEventTask=Zone.root.scheduleEventTask("fakeTopEventTask",()=>{a.lastRequestAnimationFrameId=-1,MT(a),a.isCheckStableRunning=!0,CT(a),a.isCheckStableRunning=!1},void 0,()=>{},()=>{})),a.fakeTopEventTask.invoke()}),MT(a))}(a)};a._inner=a._inner.fork({name:"angular",properties:{isAngularZone:!0},onInvokeTask:(f,m,M,k,te,le)=>{try{return B2(a),f.invokeTask(M,k,te,le)}finally{(a.shouldCoalesceEventChangeDetection&&"eventTask"===k.type||a.shouldCoalesceRunChangeDetection)&&l(),Y2(a)}},onInvoke:(f,m,M,k,te,le,Ne)=>{try{return B2(a),f.invoke(M,k,te,le,Ne)}finally{a.shouldCoalesceRunChangeDetection&&l(),Y2(a)}},onHasTask:(f,m,M,k)=>{f.hasTask(M,k),m===M&&("microTask"==k.change?(a._hasPendingMicrotasks=k.microTask,MT(a),CT(a)):"macroTask"==k.change&&(a.hasPendingMacrotasks=k.macroTask))},onHandleError:(f,m,M,k)=>(f.handleError(M,k),a.runOutsideAngular(()=>a.onError.emit(k)),!1)})}(M)}static isInAngularZone(){return!0===Zone.current.get("isAngularZone")}static assertInAngularZone(){if(!Eh.isInAngularZone())throw new Error("Expected to be in Angular Zone, but it is not!")}static assertNotInAngularZone(){if(Eh.isInAngularZone())throw new Error("Expected to not be in Angular Zone, but it is!")}run(l,f,m){return this._inner.run(l,f,m)}runTask(l,f,m,M){const k=this._inner,te=k.scheduleEventTask("NgZoneEvent: "+M,l,jv,I1,I1);try{return k.runTask(te,f,m)}finally{k.cancelTask(te)}}runGuarded(l,f,m){return this._inner.runGuarded(l,f,m)}runOutsideAngular(l){return this._outer.run(l)}}const jv={};function CT(a){if(0==a._nesting&&!a.hasPendingMicrotasks&&!a.isStable)try{a._nesting++,a.onMicrotaskEmpty.emit(null)}finally{if(a._nesting--,!a.hasPendingMicrotasks)try{a.runOutsideAngular(()=>a.onStable.emit(null))}finally{a.isStable=!0}}}function MT(a){a.hasPendingMicrotasks=!!(a._hasPendingMicrotasks||(a.shouldCoalesceEventChangeDetection||a.shouldCoalesceRunChangeDetection)&&-1!==a.lastRequestAnimationFrameId)}function B2(a){a._nesting++,a.isStable&&(a.isStable=!1,a.onUnstable.emit(null))}function Y2(a){a._nesting--,CT(a)}class Z2{constructor(){this.hasPendingMicrotasks=!1,this.hasPendingMacrotasks=!1,this.isStable=!0,this.onUnstable=new Wp,this.onMicrotaskEmpty=new Wp,this.onStable=new Wp,this.onError=new Wp}run(l,f,m){return l.apply(f,m)}runGuarded(l,f,m){return l.apply(f,m)}runOutsideAngular(l){return l()}runTask(l,f,m,M){return l.apply(f,m)}}let AT=(()=>{class a{constructor(f){this._ngZone=f,this._pendingCount=0,this._isZoneStable=!0,this._didWork=!1,this._callbacks=[],this.taskTrackingZone=null,this._watchAngularEvents(),f.run(()=>{this.taskTrackingZone="undefined"==typeof Zone?null:Zone.current.get("TaskTrackingZone")})}_watchAngularEvents(){this._ngZone.onUnstable.subscribe({next:()=>{this._didWork=!0,this._isZoneStable=!1}}),this._ngZone.runOutsideAngular(()=>{this._ngZone.onStable.subscribe({next:()=>{Eh.assertNotInAngularZone(),ST(()=>{this._isZoneStable=!0,this._runCallbacksIfReady()})}})})}increasePendingRequestCount(){return this._pendingCount+=1,this._didWork=!0,this._pendingCount}decreasePendingRequestCount(){if(this._pendingCount-=1,this._pendingCount<0)throw new Error("pending async requests below zero");return this._runCallbacksIfReady(),this._pendingCount}isStable(){return this._isZoneStable&&0===this._pendingCount&&!this._ngZone.hasPendingMacrotasks}_runCallbacksIfReady(){if(this.isStable())ST(()=>{for(;0!==this._callbacks.length;){let f=this._callbacks.pop();clearTimeout(f.timeoutId),f.doneCb(this._didWork)}this._didWork=!1});else{let f=this.getPendingTasks();this._callbacks=this._callbacks.filter(m=>!m.updateCb||!m.updateCb(f)||(clearTimeout(m.timeoutId),!1)),this._didWork=!0}}getPendingTasks(){return this.taskTrackingZone?this.taskTrackingZone.macroTasks.map(f=>({source:f.source,creationLocation:f.creationLocation,data:f.data})):[]}addCallback(f,m,M){let k=-1;m&&m>0&&(k=setTimeout(()=>{this._callbacks=this._callbacks.filter(te=>te.timeoutId!==k),f(this._didWork,this.getPendingTasks())},m)),this._callbacks.push({doneCb:f,timeoutId:k,updateCb:M})}whenStable(f,m,M){if(M&&!this.taskTrackingZone)throw new Error('Task tracking zone is required when passing an update callback to whenStable(). Is "zone.js/plugins/task-tracking" loaded?');this.addCallback(f,m,M),this._runCallbacksIfReady()}getPendingRequestCount(){return this._pendingCount}findProviders(f,m,M){return[]}}return a.\u0275fac=function(f){return new(f||a)(xn(Eh))},a.\u0275prov=xt({token:a,factory:a.\u0275fac}),a})(),OT=(()=>{class a{constructor(){this._applications=new Map,Xm.addToWindow(this)}registerApplication(f,m){this._applications.set(f,m)}unregisterApplication(f){this._applications.delete(f)}unregisterAllApplications(){this._applications.clear()}getTestability(f){return this._applications.get(f)||null}getAllTestabilities(){return Array.from(this._applications.values())}getAllRootElements(){return Array.from(this._applications.keys())}findTestabilityInTree(f,m=!0){return Xm.findTestabilityInTree(this,f,m)}}return a.\u0275fac=function(f){return new(f||a)},a.\u0275prov=xt({token:a,factory:a.\u0275fac}),a})();class wT{addToWindow(l){}findTestabilityInTree(l,f,m){return null}}function DD(a){Xm=a}let Xm=new wT,j2=!0,G2=!1;function xT(){return G2=!0,j2}function RD(){if(G2)throw new Error("Cannot enable prod mode after platform setup.");j2=!1}let Th;const z2=new Jl("AllowMultipleToken");class FD{constructor(l,f){this.name=l,this.token=f}}function DT(a,l,f=[]){const m=`Platform: ${l}`,M=new Jl(m);return(k=[])=>{let te=J2();if(!te||te.injector.get(z2,!1))if(a)a(f.concat(k).concat({provide:M,useValue:!0}));else{const le=f.concat(k).concat({provide:M,useValue:!0},{provide:Im,useValue:"platform"});!function(a){if(Th&&!Th.destroyed&&!Th.injector.get(z2,!1))throw new Error("There can be only one platform. Destroy the previous one to create a new one.");Th=a.get(RT);const l=a.get(D_,null);l&&l.forEach(f=>f())}(Ac.create({providers:le,name:m}))}return function(a){const l=J2();if(!l)throw new Error("No platform exists!");if(!l.injector.get(a,null))throw new Error("A platform with a different configuration has been created. Please destroy it first.");return l}(M)}}function J2(){return Th&&!Th.destroyed?Th:null}let RT=(()=>{class a{constructor(f){this._injector=f,this._modules=[],this._destroyListeners=[],this._destroyed=!1}bootstrapModuleFactory(f,m){const le=function(a,l){let f;return f="noop"===a?new Z2:("zone.js"===a?void 0:a)||new Eh({enableLongStackTrace:xT(),shouldCoalesceEventChangeDetection:!!(null==l?void 0:l.ngZoneEventCoalescing),shouldCoalesceRunChangeDetection:!!(null==l?void 0:l.ngZoneRunCoalescing)}),f}(m?m.ngZone:void 0,{ngZoneEventCoalescing:m&&m.ngZoneEventCoalescing||!1,ngZoneRunCoalescing:m&&m.ngZoneRunCoalescing||!1}),Ne=[{provide:Eh,useValue:le}];return le.run(()=>{const qe=Ac.create({providers:Ne,parent:this.injector,name:f.moduleType.name}),wt=f.create(qe),ln=wt.injector.get(Gf,null);if(!ln)throw new Error("No ErrorHandler. Is platform module (BrowserModule) included?");return le.runOutsideAngular(()=>{const dn=le.onError.subscribe({next:nr=>{ln.handleError(nr)}});wt.onDestroy(()=>{NT(this._modules,wt),dn.unsubscribe()})}),function(a,l,f){try{const m=f();return Zm(m)?m.catch(M=>{throw l.runOutsideAngular(()=>a.handleError(M)),M}):m}catch(m){throw l.runOutsideAngular(()=>a.handleError(m)),m}}(ln,le,()=>{const dn=wt.injector.get(Zv);return dn.runInitializers(),dn.donePromise.then(()=>(pE(wt.injector.get(Gy,my)||my),this._moduleDoBootstrap(wt),wt))})})}bootstrapModule(f,m=[]){const M=Q2({},m);return function(a,l,f){const m=new zE(f);return Promise.resolve(m)}(0,0,f).then(k=>this.bootstrapModuleFactory(k,M))}_moduleDoBootstrap(f){const m=f.injector.get(r0);if(f._bootstrapComponents.length>0)f._bootstrapComponents.forEach(M=>m.bootstrap(M));else{if(!f.instance.ngDoBootstrap)throw new Error(`The module ${S(f.instance.constructor)} was bootstrapped, but it does not declare "@NgModule.bootstrap" components nor a "ngDoBootstrap" method. Please define one of these.`);f.instance.ngDoBootstrap(m)}this._modules.push(f)}onDestroy(f){this._destroyListeners.push(f)}get injector(){return this._injector}destroy(){if(this._destroyed)throw new Error("The platform has already been destroyed!");this._modules.slice().forEach(f=>f.destroy()),this._destroyListeners.forEach(f=>f()),this._destroyed=!0}get destroyed(){return this._destroyed}}return a.\u0275fac=function(f){return new(f||a)(xn(Ac))},a.\u0275prov=xt({token:a,factory:a.\u0275fac}),a})();function Q2(a,l){return Array.isArray(l)?l.reduce(Q2,a):Object.assign(Object.assign({},a),l)}let r0=(()=>{class a{constructor(f,m,M,k,te){this._zone=f,this._injector=m,this._exceptionHandler=M,this._componentFactoryResolver=k,this._initStatus=te,this._bootstrapListeners=[],this._views=[],this._runningTick=!1,this._stable=!0,this.componentTypes=[],this.components=[],this._onMicrotaskEmptySubscription=this._zone.onMicrotaskEmpty.subscribe({next:()=>{this._zone.run(()=>{this.tick()})}});const le=new p.y(qe=>{this._stable=this._zone.isStable&&!this._zone.hasPendingMacrotasks&&!this._zone.hasPendingMicrotasks,this._zone.runOutsideAngular(()=>{qe.next(this._stable),qe.complete()})}),Ne=new p.y(qe=>{let wt;this._zone.runOutsideAngular(()=>{wt=this._zone.onStable.subscribe(()=>{Eh.assertNotInAngularZone(),ST(()=>{!this._stable&&!this._zone.hasPendingMacrotasks&&!this._zone.hasPendingMicrotasks&&(this._stable=!0,qe.next(!0))})})});const ln=this._zone.onUnstable.subscribe(()=>{Eh.assertInAngularZone(),this._stable&&(this._stable=!1,this._zone.runOutsideAngular(()=>{qe.next(!1)}))});return()=>{wt.unsubscribe(),ln.unsubscribe()}});this.isStable=(0,d.T)(le,Ne.pipe((0,e.B)()))}bootstrap(f,m){if(!this._initStatus.done)throw new Error("Cannot bootstrap as there are still asynchronous initializers running. Bootstrap components in the `ngDoBootstrap` method of the root module.");let M;M=f instanceof rM?f:this._componentFactoryResolver.resolveComponentFactory(f),this.componentTypes.push(M.componentType);const k=function(a){return a.isBoundToModule}(M)?void 0:this._injector.get(zm),le=M.create(Ac.NULL,[],m||M.selector,k),Ne=le.location.nativeElement,qe=le.injector.get(AT,null),wt=qe&&le.injector.get(OT);return qe&&wt&&wt.registerApplication(Ne,qe),le.onDestroy(()=>{this.detachView(le.hostView),NT(this.components,le),wt&&wt.unregisterApplication(Ne)}),this._loadComponent(le),le}tick(){if(this._runningTick)throw new Error("ApplicationRef.tick is called recursively");try{this._runningTick=!0;for(let f of this._views)f.detectChanges()}catch(f){this._zone.runOutsideAngular(()=>this._exceptionHandler.handleError(f))}finally{this._runningTick=!1}}attachView(f){const m=f;this._views.push(m),m.attachToAppRef(this)}detachView(f){const m=f;NT(this._views,m),m.detachFromAppRef()}_loadComponent(f){this.attachView(f.hostView),this.tick(),this.components.push(f),this._injector.get(Pp,[]).concat(this._bootstrapListeners).forEach(M=>M(f))}ngOnDestroy(){this._views.slice().forEach(f=>f.destroy()),this._onMicrotaskEmptySubscription.unsubscribe()}get viewCount(){return this._views.length}}return a.\u0275fac=function(f){return new(f||a)(xn(Eh),xn(Ac),xn(Gf),xn(Pv),xn(Zv))},a.\u0275prov=xt({token:a,factory:a.\u0275fac}),a})();function NT(a,l){const f=a.indexOf(l);f>-1&&a.splice(f,1)}class UD{}class eA{}const YD={factoryPathPrefix:"",factoryPathSuffix:".ngfactory"};let ZD=(()=>{class a{constructor(f,m){this._compiler=f,this._config=m||YD}load(f){return this.loadAndCompile(f)}loadAndCompile(f){let[m,M]=f.split("#");return void 0===M&&(M="default"),i(98255)(m).then(k=>k[M]).then(k=>Vv(k,m,M)).then(k=>this._compiler.compileModuleAsync(k))}loadFactory(f){let[m,M]=f.split("#"),k="NgFactory";return void 0===M&&(M="default",k=""),i(98255)(this._config.factoryPathPrefix+m+this._config.factoryPathSuffix).then(te=>te[M+k]).then(te=>Vv(te,m,M))}}return a.\u0275fac=function(f){return new(f||a)(xn(n0),xn(eA,8))},a.\u0275prov=xt({token:a,factory:a.\u0275fac}),a})();function Vv(a,l,f){if(!a)throw new Error(`Cannot find '${f}' in '${l}'`);return a}const WD=function(a){return null},JD=DT(null,"core",[{provide:cm,useValue:"unknown"},{provide:RT,deps:[Ac]},{provide:OT,deps:[]},{provide:L2,deps:[]}]),e3=[{provide:r0,useClass:r0,deps:[Eh,Ac,Gf,Pv,Zv]},{provide:Zx,deps:[Eh],useFactory:function(a){let l=[];return a.onStable.subscribe(()=>{for(;l.length;)l.pop()()}),function(f){l.push(f)}}},{provide:Zv,useClass:Zv,deps:[[new ia,yT]]},{provide:n0,useClass:n0,deps:[]},I2,{provide:Ay,useFactory:function(){return rx},deps:[]},{provide:Oy,useFactory:function(){return ix},deps:[]},{provide:Gy,useFactory:function(a){return pE(a=a||"undefined"!=typeof $localize&&$localize.locale||my),a},deps:[[new ha(Gy),new ia,new il]]},{provide:F2,useValue:"USD"}];let $T=(()=>{class a{constructor(f){}}return a.\u0275fac=function(f){return new(f||a)(xn(r0))},a.\u0275mod=Fn({type:a}),a.\u0275inj=Zn({providers:e3}),a})()},24751:(v,T,i)=>{"use strict";i.d(T,{TO:()=>li,Wl:()=>N,gN:()=>Mr,Fj:()=>K,Oe:()=>vr,CE:()=>Ca,qu:()=>Pt,NI:()=>Bn,u:()=>Ws,cw:()=>lr,sg:()=>fo,x0:()=>Ao,u5:()=>Su,Fd:()=>pi,qQ:()=>ts,Cf:()=>ae,JU:()=>S,a5:()=>Kr,JJ:()=>Br,JL:()=>Yr,F:()=>Ci,On:()=>_o,YN:()=>So,wV:()=>Zs,_:()=>us,UX:()=>Zl,Q7:()=>Eo,EJ:()=>ps,kI:()=>Ee,_Y:()=>co,Kr:()=>$e});var r=i(74788),u=i(12057),p=i(94402),d=i(35758),e=i(88002);let _=(()=>{class Te{constructor(xe,Ct){this._renderer=xe,this._elementRef=Ct,this.onChange=ur=>{},this.onTouched=()=>{}}setProperty(xe,Ct){this._renderer.setProperty(this._elementRef.nativeElement,xe,Ct)}registerOnTouched(xe){this.onTouched=xe}registerOnChange(xe){this.onChange=xe}setDisabledState(xe){this.setProperty("disabled",xe)}}return Te.\u0275fac=function(xe){return new(xe||Te)(r.Y36(r.Qsj),r.Y36(r.SBq))},Te.\u0275dir=r.lG2({type:Te}),Te})(),y=(()=>{class Te extends _{}return Te.\u0275fac=function(){let Me;return function(Ct){return(Me||(Me=r.n5z(Te)))(Ct||Te)}}(),Te.\u0275dir=r.lG2({type:Te,features:[r.qOj]}),Te})();const S=new r.OlP("NgValueAccessor"),A={provide:S,useExisting:(0,r.Gpc)(()=>N),multi:!0};let N=(()=>{class Te extends y{writeValue(xe){this.setProperty("checked",xe)}}return Te.\u0275fac=function(){let Me;return function(Ct){return(Me||(Me=r.n5z(Te)))(Ct||Te)}}(),Te.\u0275dir=r.lG2({type:Te,selectors:[["input","type","checkbox","formControlName",""],["input","type","checkbox","formControl",""],["input","type","checkbox","ngModel",""]],hostBindings:function(xe,Ct){1&xe&&r.NdJ("change",function(Qi){return Ct.onChange(Qi.target.checked)})("blur",function(){return Ct.onTouched()})},features:[r._Bn([A]),r.qOj]}),Te})();const L={provide:S,useExisting:(0,r.Gpc)(()=>K),multi:!0},J=new r.OlP("CompositionEventMode");let K=(()=>{class Te extends _{constructor(xe,Ct,ur){super(xe,Ct),this._compositionMode=ur,this._composing=!1,null==this._compositionMode&&(this._compositionMode=!function(){const Te=(0,u.q)()?(0,u.q)().getUserAgent():"";return/android (\d+)/.test(Te.toLowerCase())}())}writeValue(xe){this.setProperty("value",null==xe?"":xe)}_handleInput(xe){(!this._compositionMode||this._compositionMode&&!this._composing)&&this.onChange(xe)}_compositionStart(){this._composing=!0}_compositionEnd(xe){this._composing=!1,this._compositionMode&&this.onChange(xe)}}return Te.\u0275fac=function(xe){return new(xe||Te)(r.Y36(r.Qsj),r.Y36(r.SBq),r.Y36(J,8))},Te.\u0275dir=r.lG2({type:Te,selectors:[["input","formControlName","",3,"type","checkbox"],["textarea","formControlName",""],["input","formControl","",3,"type","checkbox"],["textarea","formControl",""],["input","ngModel","",3,"type","checkbox"],["textarea","ngModel",""],["","ngDefaultControl",""]],hostBindings:function(xe,Ct){1&xe&&r.NdJ("input",function(Qi){return Ct._handleInput(Qi.target.value)})("blur",function(){return Ct.onTouched()})("compositionstart",function(){return Ct._compositionStart()})("compositionend",function(Qi){return Ct._compositionEnd(Qi.target.value)})},features:[r._Bn([L]),r.qOj]}),Te})();function ee(Te){return null==Te||0===Te.length}function ue(Te){return null!=Te&&"number"==typeof Te.length}const ae=new r.OlP("NgValidators"),H=new r.OlP("NgAsyncValidators"),se=/^(?=.{1,254}$)(?=.{1,64}@)[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;class Ee{static min(Me){return ie(Me)}static max(Me){return he(Me)}static required(Me){return ge(Me)}static requiredTrue(Me){return!0===Me.value?null:{required:!0}}static email(Me){return ee((Te=Me).value)||se.test(Te.value)?null:{email:!0};var Te}static minLength(Me){return Te=Me,Me=>ee(Me.value)||!ue(Me.value)?null:Me.value.length<Te?{minlength:{requiredLength:Te,actualLength:Me.value.length}}:null;var Te}static maxLength(Me){return Te=Me,Me=>ue(Me.value)&&Me.value.length>Te?{maxlength:{requiredLength:Te,actualLength:Me.value.length}}:null;var Te}static pattern(Me){return function(Te){if(!Te)return Be;let Me,xe;return"string"==typeof Te?(xe="","^"!==Te.charAt(0)&&(xe+="^"),xe+=Te,"$"!==Te.charAt(Te.length-1)&&(xe+="$"),Me=new RegExp(xe)):(xe=Te.toString(),Me=Te),Ct=>{if(ee(Ct.value))return null;const ur=Ct.value;return Me.test(ur)?null:{pattern:{requiredPattern:xe,actualValue:ur}}}}(Me)}static nullValidator(Me){return null}static compose(Me){return It(Me)}static composeAsync(Me){return Ut(Me)}}function ie(Te){return Me=>{if(ee(Me.value)||ee(Te))return null;const xe=parseFloat(Me.value);return!isNaN(xe)&&xe<Te?{min:{min:Te,actual:Me.value}}:null}}function he(Te){return Me=>{if(ee(Me.value)||ee(Te))return null;const xe=parseFloat(Me.value);return!isNaN(xe)&&xe>Te?{max:{max:Te,actual:Me.value}}:null}}function ge(Te){return ee(Te.value)?{required:!0}:null}function Be(Te){return null}function Pe(Te){return null!=Te}function je(Te){const Me=(0,r.QGY)(Te)?(0,p.D)(Te):Te;return(0,r.CqO)(Me),Me}function He(Te){let Me={};return Te.forEach(xe=>{Me=null!=xe?Object.assign(Object.assign({},Me),xe):Me}),0===Object.keys(Me).length?null:Me}function Vt(Te,Me){return Me.map(xe=>xe(Te))}function tn(Te){return Te.map(Me=>function(Te){return!Te.validate}(Me)?Me:xe=>Me.validate(xe))}function It(Te){if(!Te)return null;const Me=Te.filter(Pe);return 0==Me.length?null:function(xe){return He(Vt(xe,Me))}}function Zt(Te){return null!=Te?It(tn(Te)):null}function Ut(Te){if(!Te)return null;const Me=Te.filter(Pe);return 0==Me.length?null:function(xe){const Ct=Vt(xe,Me).map(je);return(0,d.D)(Ct).pipe((0,e.U)(He))}}function Bt(Te){return null!=Te?Ut(tn(Te)):null}function bt(Te,Me){return null===Te?[Me]:Array.isArray(Te)?[...Te,Me]:[Te,Me]}function Gt(Te){return Te._rawValidators}function xt(Te){return Te._rawAsyncValidators}function Xt(Te){return Te?Array.isArray(Te)?Te:[Te]:[]}function Zn(Te,Me){return Array.isArray(Te)?Te.includes(Me):Te===Me}function Ur(Te,Me){const xe=Xt(Me);return Xt(Te).forEach(ur=>{Zn(xe,ur)||xe.push(ur)}),xe}function di(Te,Me){return Xt(Me).filter(xe=>!Zn(Te,xe))}let Lr=(()=>{class Te{constructor(){this._rawValidators=[],this._rawAsyncValidators=[],this._onDestroyCallbacks=[]}get value(){return this.control?this.control.value:null}get valid(){return this.control?this.control.valid:null}get invalid(){return this.control?this.control.invalid:null}get pending(){return this.control?this.control.pending:null}get disabled(){return this.control?this.control.disabled:null}get enabled(){return this.control?this.control.enabled:null}get errors(){return this.control?this.control.errors:null}get pristine(){return this.control?this.control.pristine:null}get dirty(){return this.control?this.control.dirty:null}get touched(){return this.control?this.control.touched:null}get status(){return this.control?this.control.status:null}get untouched(){return this.control?this.control.untouched:null}get statusChanges(){return this.control?this.control.statusChanges:null}get valueChanges(){return this.control?this.control.valueChanges:null}get path(){return null}_setValidators(xe){this._rawValidators=xe||[],this._composedValidatorFn=Zt(this._rawValidators)}_setAsyncValidators(xe){this._rawAsyncValidators=xe||[],this._composedAsyncValidatorFn=Bt(this._rawAsyncValidators)}get validator(){return this._composedValidatorFn||null}get asyncValidator(){return this._composedAsyncValidatorFn||null}_registerOnDestroy(xe){this._onDestroyCallbacks.push(xe)}_invokeOnDestroyCallbacks(){this._onDestroyCallbacks.forEach(xe=>xe()),this._onDestroyCallbacks=[]}reset(xe){this.control&&this.control.reset(xe)}hasError(xe,Ct){return!!this.control&&this.control.hasError(xe,Ct)}getError(xe,Ct){return this.control?this.control.getError(xe,Ct):null}}return Te.\u0275fac=function(xe){return new(xe||Te)},Te.\u0275dir=r.lG2({type:Te}),Te})(),Mr=(()=>{class Te extends Lr{get formDirective(){return null}get path(){return null}}return Te.\u0275fac=function(){let Me;return function(Ct){return(Me||(Me=r.n5z(Te)))(Ct||Te)}}(),Te.\u0275dir=r.lG2({type:Te,features:[r.qOj]}),Te})();class Kr extends Lr{constructor(){super(...arguments),this._parent=null,this.name=null,this.valueAccessor=null}}class ei{constructor(Me){this._cd=Me}is(Me){var xe,Ct,ur;return"submitted"===Me?!!(null===(xe=this._cd)||void 0===xe?void 0:xe.submitted):!!(null===(ur=null===(Ct=this._cd)||void 0===Ct?void 0:Ct.control)||void 0===ur?void 0:ur[Me])}}let Br=(()=>{class Te extends ei{constructor(xe){super(xe)}}return Te.\u0275fac=function(xe){return new(xe||Te)(r.Y36(Kr,2))},Te.\u0275dir=r.lG2({type:Te,selectors:[["","formControlName",""],["","ngModel",""],["","formControl",""]],hostVars:14,hostBindings:function(xe,Ct){2&xe&&r.ekj("ng-untouched",Ct.is("untouched"))("ng-touched",Ct.is("touched"))("ng-pristine",Ct.is("pristine"))("ng-dirty",Ct.is("dirty"))("ng-valid",Ct.is("valid"))("ng-invalid",Ct.is("invalid"))("ng-pending",Ct.is("pending"))},features:[r.qOj]}),Te})(),Yr=(()=>{class Te extends ei{constructor(xe){super(xe)}}return Te.\u0275fac=function(xe){return new(xe||Te)(r.Y36(Mr,10))},Te.\u0275dir=r.lG2({type:Te,selectors:[["","formGroupName",""],["","formArrayName",""],["","ngModelGroup",""],["","formGroup",""],["form",3,"ngNoForm",""],["","ngForm",""]],hostVars:16,hostBindings:function(xe,Ct){2&xe&&r.ekj("ng-untouched",Ct.is("untouched"))("ng-touched",Ct.is("touched"))("ng-pristine",Ct.is("pristine"))("ng-dirty",Ct.is("dirty"))("ng-valid",Ct.is("valid"))("ng-invalid",Ct.is("invalid"))("ng-pending",Ct.is("pending"))("ng-submitted",Ct.is("submitted"))},features:[r.qOj]}),Te})();function wi(Te,Me){return[...Me.path,Te]}function br(Te,Me){gr(Te,Me),Me.valueAccessor.writeValue(Te.value),function(Te,Me){Me.valueAccessor.registerOnChange(xe=>{Te._pendingValue=xe,Te._pendingChange=!0,Te._pendingDirty=!0,"change"===Te.updateOn&&Dn(Te,Me)})}(Te,Me),function(Te,Me){const xe=(Ct,ur)=>{Me.valueAccessor.writeValue(Ct),ur&&Me.viewToModelUpdate(Ct)};Te.registerOnChange(xe),Me._registerOnDestroy(()=>{Te._unregisterOnChange(xe)})}(Te,Me),function(Te,Me){Me.valueAccessor.registerOnTouched(()=>{Te._pendingTouched=!0,"blur"===Te.updateOn&&Te._pendingChange&&Dn(Te,Me),"submit"!==Te.updateOn&&Te.markAsTouched()})}(Te,Me),function(Te,Me){if(Me.valueAccessor.setDisabledState){const xe=Ct=>{Me.valueAccessor.setDisabledState(Ct)};Te.registerOnDisabledChange(xe),Me._registerOnDestroy(()=>{Te._unregisterOnDisabledChange(xe)})}}(Te,Me)}function Dr(Te,Me,xe=!0){const Ct=()=>{};Me.valueAccessor&&(Me.valueAccessor.registerOnChange(Ct),Me.valueAccessor.registerOnTouched(Ct)),Jt(Te,Me),Te&&(Me._invokeOnDestroyCallbacks(),Te._registerOnCollectionChange(()=>{}))}function gn(Te,Me){Te.forEach(xe=>{xe.registerOnValidatorChange&&xe.registerOnValidatorChange(Me)})}function gr(Te,Me){const xe=Gt(Te);null!==Me.validator?Te.setValidators(bt(xe,Me.validator)):"function"==typeof xe&&Te.setValidators([xe]);const Ct=xt(Te);null!==Me.asyncValidator?Te.setAsyncValidators(bt(Ct,Me.asyncValidator)):"function"==typeof Ct&&Te.setAsyncValidators([Ct]);const ur=()=>Te.updateValueAndValidity();gn(Me._rawValidators,ur),gn(Me._rawAsyncValidators,ur)}function Jt(Te,Me){let xe=!1;if(null!==Te){if(null!==Me.validator){const ur=Gt(Te);if(Array.isArray(ur)&&ur.length>0){const Qi=ur.filter(Go=>Go!==Me.validator);Qi.length!==ur.length&&(xe=!0,Te.setValidators(Qi))}}if(null!==Me.asyncValidator){const ur=xt(Te);if(Array.isArray(ur)&&ur.length>0){const Qi=ur.filter(Go=>Go!==Me.asyncValidator);Qi.length!==ur.length&&(xe=!0,Te.setAsyncValidators(Qi))}}}const Ct=()=>{};return gn(Me._rawValidators,Ct),gn(Me._rawAsyncValidators,Ct),xe}function Dn(Te,Me){Te._pendingDirty&&Te.markAsDirty(),Te.setValue(Te._pendingValue,{emitModelToViewChange:!1}),Me.viewToModelUpdate(Te._pendingValue),Te._pendingChange=!1}function Yt(Te,Me){gr(Te,Me)}function mi(Te,Me){if(!Te.hasOwnProperty("model"))return!1;const xe=Te.model;return!!xe.isFirstChange()||!Object.is(Me,xe.currentValue)}function Er(Te,Me){Te._syncPendingControls(),Me.forEach(xe=>{const Ct=xe.control;"submit"===Ct.updateOn&&Ct._pendingChange&&(xe.viewToModelUpdate(Ct._pendingValue),Ct._pendingChange=!1)})}function Wr(Te,Me){if(!Me)return null;let xe,Ct,ur;return Array.isArray(Me),Me.forEach(Qi=>{Qi.constructor===K?xe=Qi:function(Te){return Object.getPrototypeOf(Te.constructor)===y}(Qi)?Ct=Qi:ur=Qi}),ur||Ct||xe||null}function dr(Te,Me){const xe=Te.indexOf(Me);xe>-1&&Te.splice(xe,1)}const ar="VALID",Wi="INVALID",lo="PENDING",vo="DISABLED";function Gi(Te){return(Mi(Te)?Te.validators:Te)||null}function os(Te){return Array.isArray(Te)?Zt(Te):Te||null}function jo(Te,Me){return(Mi(Me)?Me.asyncValidators:Te)||null}function To(Te){return Array.isArray(Te)?Bt(Te):Te||null}function Mi(Te){return null!=Te&&!Array.isArray(Te)&&"object"==typeof Te}class li{constructor(Me,xe){this._hasOwnPendingAsyncValidator=!1,this._onCollectionChange=()=>{},this._parent=null,this.pristine=!0,this.touched=!1,this._onDisabledChange=[],this._rawValidators=Me,this._rawAsyncValidators=xe,this._composedValidatorFn=os(this._rawValidators),this._composedAsyncValidatorFn=To(this._rawAsyncValidators)}get validator(){return this._composedValidatorFn}set validator(Me){this._rawValidators=this._composedValidatorFn=Me}get asyncValidator(){return this._composedAsyncValidatorFn}set asyncValidator(Me){this._rawAsyncValidators=this._composedAsyncValidatorFn=Me}get parent(){return this._parent}get valid(){return this.status===ar}get invalid(){return this.status===Wi}get pending(){return this.status==lo}get disabled(){return this.status===vo}get enabled(){return this.status!==vo}get dirty(){return!this.pristine}get untouched(){return!this.touched}get updateOn(){return this._updateOn?this._updateOn:this.parent?this.parent.updateOn:"change"}setValidators(Me){this._rawValidators=Me,this._composedValidatorFn=os(Me)}setAsyncValidators(Me){this._rawAsyncValidators=Me,this._composedAsyncValidatorFn=To(Me)}addValidators(Me){this.setValidators(Ur(Me,this._rawValidators))}addAsyncValidators(Me){this.setAsyncValidators(Ur(Me,this._rawAsyncValidators))}removeValidators(Me){this.setValidators(di(Me,this._rawValidators))}removeAsyncValidators(Me){this.setAsyncValidators(di(Me,this._rawAsyncValidators))}hasValidator(Me){return Zn(this._rawValidators,Me)}hasAsyncValidator(Me){return Zn(this._rawAsyncValidators,Me)}clearValidators(){this.validator=null}clearAsyncValidators(){this.asyncValidator=null}markAsTouched(Me={}){this.touched=!0,this._parent&&!Me.onlySelf&&this._parent.markAsTouched(Me)}markAllAsTouched(){this.markAsTouched({onlySelf:!0}),this._forEachChild(Me=>Me.markAllAsTouched())}markAsUntouched(Me={}){this.touched=!1,this._pendingTouched=!1,this._forEachChild(xe=>{xe.markAsUntouched({onlySelf:!0})}),this._parent&&!Me.onlySelf&&this._parent._updateTouched(Me)}markAsDirty(Me={}){this.pristine=!1,this._parent&&!Me.onlySelf&&this._parent.markAsDirty(Me)}markAsPristine(Me={}){this.pristine=!0,this._pendingDirty=!1,this._forEachChild(xe=>{xe.markAsPristine({onlySelf:!0})}),this._parent&&!Me.onlySelf&&this._parent._updatePristine(Me)}markAsPending(Me={}){this.status=lo,!1!==Me.emitEvent&&this.statusChanges.emit(this.status),this._parent&&!Me.onlySelf&&this._parent.markAsPending(Me)}disable(Me={}){const xe=this._parentMarkedDirty(Me.onlySelf);this.status=vo,this.errors=null,this._forEachChild(Ct=>{Ct.disable(Object.assign(Object.assign({},Me),{onlySelf:!0}))}),this._updateValue(),!1!==Me.emitEvent&&(this.valueChanges.emit(this.value),this.statusChanges.emit(this.status)),this._updateAncestors(Object.assign(Object.assign({},Me),{skipPristineCheck:xe})),this._onDisabledChange.forEach(Ct=>Ct(!0))}enable(Me={}){const xe=this._parentMarkedDirty(Me.onlySelf);this.status=ar,this._forEachChild(Ct=>{Ct.enable(Object.assign(Object.assign({},Me),{onlySelf:!0}))}),this.updateValueAndValidity({onlySelf:!0,emitEvent:Me.emitEvent}),this._updateAncestors(Object.assign(Object.assign({},Me),{skipPristineCheck:xe})),this._onDisabledChange.forEach(Ct=>Ct(!1))}_updateAncestors(Me){this._parent&&!Me.onlySelf&&(this._parent.updateValueAndValidity(Me),Me.skipPristineCheck||this._parent._updatePristine(),this._parent._updateTouched())}setParent(Me){this._parent=Me}updateValueAndValidity(Me={}){this._setInitialStatus(),this._updateValue(),this.enabled&&(this._cancelExistingSubscription(),this.errors=this._runValidator(),this.status=this._calculateStatus(),(this.status===ar||this.status===lo)&&this._runAsyncValidator(Me.emitEvent)),!1!==Me.emitEvent&&(this.valueChanges.emit(this.value),this.statusChanges.emit(this.status)),this._parent&&!Me.onlySelf&&this._parent.updateValueAndValidity(Me)}_updateTreeValidity(Me={emitEvent:!0}){this._forEachChild(xe=>xe._updateTreeValidity(Me)),this.updateValueAndValidity({onlySelf:!0,emitEvent:Me.emitEvent})}_setInitialStatus(){this.status=this._allControlsDisabled()?vo:ar}_runValidator(){return this.validator?this.validator(this):null}_runAsyncValidator(Me){if(this.asyncValidator){this.status=lo,this._hasOwnPendingAsyncValidator=!0;const xe=je(this.asyncValidator(this));this._asyncValidationSubscription=xe.subscribe(Ct=>{this._hasOwnPendingAsyncValidator=!1,this.setErrors(Ct,{emitEvent:Me})})}}_cancelExistingSubscription(){this._asyncValidationSubscription&&(this._asyncValidationSubscription.unsubscribe(),this._hasOwnPendingAsyncValidator=!1)}setErrors(Me,xe={}){this.errors=Me,this._updateControlsErrors(!1!==xe.emitEvent)}get(Me){return function(Te,Me,xe){if(null==Me||(Array.isArray(Me)||(Me=Me.split(".")),Array.isArray(Me)&&0===Me.length))return null;let Ct=Te;return Me.forEach(ur=>{Ct=Ct instanceof lr?Ct.controls.hasOwnProperty(ur)?Ct.controls[ur]:null:Ct instanceof vr&&Ct.at(ur)||null}),Ct}(this,Me)}getError(Me,xe){const Ct=xe?this.get(xe):this;return Ct&&Ct.errors?Ct.errors[Me]:null}hasError(Me,xe){return!!this.getError(Me,xe)}get root(){let Me=this;for(;Me._parent;)Me=Me._parent;return Me}_updateControlsErrors(Me){this.status=this._calculateStatus(),Me&&this.statusChanges.emit(this.status),this._parent&&this._parent._updateControlsErrors(Me)}_initObservables(){this.valueChanges=new r.vpe,this.statusChanges=new r.vpe}_calculateStatus(){return this._allControlsDisabled()?vo:this.errors?Wi:this._hasOwnPendingAsyncValidator||this._anyControlsHaveStatus(lo)?lo:this._anyControlsHaveStatus(Wi)?Wi:ar}_anyControlsHaveStatus(Me){return this._anyControls(xe=>xe.status===Me)}_anyControlsDirty(){return this._anyControls(Me=>Me.dirty)}_anyControlsTouched(){return this._anyControls(Me=>Me.touched)}_updatePristine(Me={}){this.pristine=!this._anyControlsDirty(),this._parent&&!Me.onlySelf&&this._parent._updatePristine(Me)}_updateTouched(Me={}){this.touched=this._anyControlsTouched(),this._parent&&!Me.onlySelf&&this._parent._updateTouched(Me)}_isBoxedValue(Me){return"object"==typeof Me&&null!==Me&&2===Object.keys(Me).length&&"value"in Me&&"disabled"in Me}_registerOnCollectionChange(Me){this._onCollectionChange=Me}_setUpdateStrategy(Me){Mi(Me)&&null!=Me.updateOn&&(this._updateOn=Me.updateOn)}_parentMarkedDirty(Me){return!Me&&!(!this._parent||!this._parent.dirty)&&!this._parent._anyControlsDirty()}}class Bn extends li{constructor(Me=null,xe,Ct){super(Gi(xe),jo(Ct,xe)),this._onChange=[],this._applyFormState(Me),this._setUpdateStrategy(xe),this._initObservables(),this.updateValueAndValidity({onlySelf:!0,emitEvent:!!this.asyncValidator})}setValue(Me,xe={}){this.value=this._pendingValue=Me,this._onChange.length&&!1!==xe.emitModelToViewChange&&this._onChange.forEach(Ct=>Ct(this.value,!1!==xe.emitViewToModelChange)),this.updateValueAndValidity(xe)}patchValue(Me,xe={}){this.setValue(Me,xe)}reset(Me=null,xe={}){this._applyFormState(Me),this.markAsPristine(xe),this.markAsUntouched(xe),this.setValue(this.value,xe),this._pendingChange=!1}_updateValue(){}_anyControls(Me){return!1}_allControlsDisabled(){return this.disabled}registerOnChange(Me){this._onChange.push(Me)}_unregisterOnChange(Me){dr(this._onChange,Me)}registerOnDisabledChange(Me){this._onDisabledChange.push(Me)}_unregisterOnDisabledChange(Me){dr(this._onDisabledChange,Me)}_forEachChild(Me){}_syncPendingControls(){return!("submit"!==this.updateOn||(this._pendingDirty&&this.markAsDirty(),this._pendingTouched&&this.markAsTouched(),!this._pendingChange)||(this.setValue(this._pendingValue,{onlySelf:!0,emitModelToViewChange:!1}),0))}_applyFormState(Me){this._isBoxedValue(Me)?(this.value=this._pendingValue=Me.value,Me.disabled?this.disable({onlySelf:!0,emitEvent:!1}):this.enable({onlySelf:!0,emitEvent:!1})):this.value=this._pendingValue=Me}}class lr extends li{constructor(Me,xe,Ct){super(Gi(xe),jo(Ct,xe)),this.controls=Me,this._initObservables(),this._setUpdateStrategy(xe),this._setUpControls(),this.updateValueAndValidity({onlySelf:!0,emitEvent:!!this.asyncValidator})}registerControl(Me,xe){return this.controls[Me]?this.controls[Me]:(this.controls[Me]=xe,xe.setParent(this),xe._registerOnCollectionChange(this._onCollectionChange),xe)}addControl(Me,xe,Ct={}){this.registerControl(Me,xe),this.updateValueAndValidity({emitEvent:Ct.emitEvent}),this._onCollectionChange()}removeControl(Me,xe={}){this.controls[Me]&&this.controls[Me]._registerOnCollectionChange(()=>{}),delete this.controls[Me],this.updateValueAndValidity({emitEvent:xe.emitEvent}),this._onCollectionChange()}setControl(Me,xe,Ct={}){this.controls[Me]&&this.controls[Me]._registerOnCollectionChange(()=>{}),delete this.controls[Me],xe&&this.registerControl(Me,xe),this.updateValueAndValidity({emitEvent:Ct.emitEvent}),this._onCollectionChange()}contains(Me){return this.controls.hasOwnProperty(Me)&&this.controls[Me].enabled}setValue(Me,xe={}){this._checkAllValuesPresent(Me),Object.keys(Me).forEach(Ct=>{this._throwIfControlMissing(Ct),this.controls[Ct].setValue(Me[Ct],{onlySelf:!0,emitEvent:xe.emitEvent})}),this.updateValueAndValidity(xe)}patchValue(Me,xe={}){null!=Me&&(Object.keys(Me).forEach(Ct=>{this.controls[Ct]&&this.controls[Ct].patchValue(Me[Ct],{onlySelf:!0,emitEvent:xe.emitEvent})}),this.updateValueAndValidity(xe))}reset(Me={},xe={}){this._forEachChild((Ct,ur)=>{Ct.reset(Me[ur],{onlySelf:!0,emitEvent:xe.emitEvent})}),this._updatePristine(xe),this._updateTouched(xe),this.updateValueAndValidity(xe)}getRawValue(){return this._reduceChildren({},(Me,xe,Ct)=>(Me[Ct]=xe instanceof Bn?xe.value:xe.getRawValue(),Me))}_syncPendingControls(){let Me=this._reduceChildren(!1,(xe,Ct)=>!!Ct._syncPendingControls()||xe);return Me&&this.updateValueAndValidity({onlySelf:!0}),Me}_throwIfControlMissing(Me){if(!Object.keys(this.controls).length)throw new Error("\n There are no form controls registered with this group yet. If you're using ngModel,\n you may want to check next tick (e.g. use setTimeout).\n ");if(!this.controls[Me])throw new Error(`Cannot find form control with name: ${Me}.`)}_forEachChild(Me){Object.keys(this.controls).forEach(xe=>{const Ct=this.controls[xe];Ct&&Me(Ct,xe)})}_setUpControls(){this._forEachChild(Me=>{Me.setParent(this),Me._registerOnCollectionChange(this._onCollectionChange)})}_updateValue(){this.value=this._reduceValue()}_anyControls(Me){for(const xe of Object.keys(this.controls)){const Ct=this.controls[xe];if(this.contains(xe)&&Me(Ct))return!0}return!1}_reduceValue(){return this._reduceChildren({},(Me,xe,Ct)=>((xe.enabled||this.disabled)&&(Me[Ct]=xe.value),Me))}_reduceChildren(Me,xe){let Ct=Me;return this._forEachChild((ur,Qi)=>{Ct=xe(Ct,ur,Qi)}),Ct}_allControlsDisabled(){for(const Me of Object.keys(this.controls))if(this.controls[Me].enabled)return!1;return Object.keys(this.controls).length>0||this.disabled}_checkAllValuesPresent(Me){this._forEachChild((xe,Ct)=>{if(void 0===Me[Ct])throw new Error(`Must supply a value for form control with name: '${Ct}'.`)})}}class vr extends li{constructor(Me,xe,Ct){super(Gi(xe),jo(Ct,xe)),this.controls=Me,this._initObservables(),this._setUpdateStrategy(xe),this._setUpControls(),this.updateValueAndValidity({onlySelf:!0,emitEvent:!!this.asyncValidator})}at(Me){return this.controls[Me]}push(Me,xe={}){this.controls.push(Me),this._registerControl(Me),this.updateValueAndValidity({emitEvent:xe.emitEvent}),this._onCollectionChange()}insert(Me,xe,Ct={}){this.controls.splice(Me,0,xe),this._registerControl(xe),this.updateValueAndValidity({emitEvent:Ct.emitEvent})}removeAt(Me,xe={}){this.controls[Me]&&this.controls[Me]._registerOnCollectionChange(()=>{}),this.controls.splice(Me,1),this.updateValueAndValidity({emitEvent:xe.emitEvent})}setControl(Me,xe,Ct={}){this.controls[Me]&&this.controls[Me]._registerOnCollectionChange(()=>{}),this.controls.splice(Me,1),xe&&(this.controls.splice(Me,0,xe),this._registerControl(xe)),this.updateValueAndValidity({emitEvent:Ct.emitEvent}),this._onCollectionChange()}get length(){return this.controls.length}setValue(Me,xe={}){this._checkAllValuesPresent(Me),Me.forEach((Ct,ur)=>{this._throwIfControlMissing(ur),this.at(ur).setValue(Ct,{onlySelf:!0,emitEvent:xe.emitEvent})}),this.updateValueAndValidity(xe)}patchValue(Me,xe={}){null!=Me&&(Me.forEach((Ct,ur)=>{this.at(ur)&&this.at(ur).patchValue(Ct,{onlySelf:!0,emitEvent:xe.emitEvent})}),this.updateValueAndValidity(xe))}reset(Me=[],xe={}){this._forEachChild((Ct,ur)=>{Ct.reset(Me[ur],{onlySelf:!0,emitEvent:xe.emitEvent})}),this._updatePristine(xe),this._updateTouched(xe),this.updateValueAndValidity(xe)}getRawValue(){return this.controls.map(Me=>Me instanceof Bn?Me.value:Me.getRawValue())}clear(Me={}){this.controls.length<1||(this._forEachChild(xe=>xe._registerOnCollectionChange(()=>{})),this.controls.splice(0),this.updateValueAndValidity({emitEvent:Me.emitEvent}))}_syncPendingControls(){let Me=this.controls.reduce((xe,Ct)=>!!Ct._syncPendingControls()||xe,!1);return Me&&this.updateValueAndValidity({onlySelf:!0}),Me}_throwIfControlMissing(Me){if(!this.controls.length)throw new Error("\n There are no form controls registered with this array yet. If you're using ngModel,\n you may want to check next tick (e.g. use setTimeout).\n ");if(!this.at(Me))throw new Error(`Cannot find form control at index ${Me}`)}_forEachChild(Me){this.controls.forEach((xe,Ct)=>{Me(xe,Ct)})}_updateValue(){this.value=this.controls.filter(Me=>Me.enabled||this.disabled).map(Me=>Me.value)}_anyControls(Me){return this.controls.some(xe=>xe.enabled&&Me(xe))}_setUpControls(){this._forEachChild(Me=>this._registerControl(Me))}_checkAllValuesPresent(Me){this._forEachChild((xe,Ct)=>{if(void 0===Me[Ct])throw new Error(`Must supply a value for form control at index: ${Ct}.`)})}_allControlsDisabled(){for(const Me of this.controls)if(Me.enabled)return!1;return this.controls.length>0||this.disabled}_registerControl(Me){Me.setParent(this),Me._registerOnCollectionChange(this._onCollectionChange)}}const er={provide:Mr,useExisting:(0,r.Gpc)(()=>Ci)},uo=(()=>Promise.resolve(null))();let Ci=(()=>{class Te extends Mr{constructor(xe,Ct){super(),this.submitted=!1,this._directives=[],this.ngSubmit=new r.vpe,this.form=new lr({},Zt(xe),Bt(Ct))}ngAfterViewInit(){this._setUpdateStrategy()}get formDirective(){return this}get control(){return this.form}get path(){return[]}get controls(){return this.form.controls}addControl(xe){uo.then(()=>{const Ct=this._findContainer(xe.path);xe.control=Ct.registerControl(xe.name,xe.control),br(xe.control,xe),xe.control.updateValueAndValidity({emitEvent:!1}),this._directives.push(xe)})}getControl(xe){return this.form.get(xe.path)}removeControl(xe){uo.then(()=>{const Ct=this._findContainer(xe.path);Ct&&Ct.removeControl(xe.name),dr(this._directives,xe)})}addFormGroup(xe){uo.then(()=>{const Ct=this._findContainer(xe.path),ur=new lr({});Yt(ur,xe),Ct.registerControl(xe.name,ur),ur.updateValueAndValidity({emitEvent:!1})})}removeFormGroup(xe){uo.then(()=>{const Ct=this._findContainer(xe.path);Ct&&Ct.removeControl(xe.name)})}getFormGroup(xe){return this.form.get(xe.path)}updateModel(xe,Ct){uo.then(()=>{this.form.get(xe.path).setValue(Ct)})}setValue(xe){this.control.setValue(xe)}onSubmit(xe){return this.submitted=!0,Er(this.form,this._directives),this.ngSubmit.emit(xe),!1}onReset(){this.resetForm()}resetForm(xe){this.form.reset(xe),this.submitted=!1}_setUpdateStrategy(){this.options&&null!=this.options.updateOn&&(this.form._updateOn=this.options.updateOn)}_findContainer(xe){return xe.pop(),xe.length?this.form.get(xe):this.form}}return Te.\u0275fac=function(xe){return new(xe||Te)(r.Y36(ae,10),r.Y36(H,10))},Te.\u0275dir=r.lG2({type:Te,selectors:[["form",3,"ngNoForm","",3,"formGroup",""],["ng-form"],["","ngForm",""]],hostBindings:function(xe,Ct){1&xe&&r.NdJ("submit",function(Qi){return Ct.onSubmit(Qi)})("reset",function(){return Ct.onReset()})},inputs:{options:["ngFormOptions","options"]},outputs:{ngSubmit:"ngSubmit"},exportAs:["ngForm"],features:[r._Bn([er]),r.qOj]}),Te})(),$o=(()=>{class Te extends Mr{ngOnInit(){this._checkParentType(),this.formDirective.addFormGroup(this)}ngOnDestroy(){this.formDirective&&this.formDirective.removeFormGroup(this)}get control(){return this.formDirective.getFormGroup(this)}get path(){return wi(null==this.name?this.name:this.name.toString(),this._parent)}get formDirective(){return this._parent?this._parent.formDirective:null}_checkParentType(){}}return Te.\u0275fac=function(){let Me;return function(Ct){return(Me||(Me=r.n5z(Te)))(Ct||Te)}}(),Te.\u0275dir=r.lG2({type:Te,features:[r.qOj]}),Te})();const on={provide:Kr,useExisting:(0,r.Gpc)(()=>_o)},Vi=(()=>Promise.resolve(null))();let _o=(()=>{class Te extends Kr{constructor(xe,Ct,ur,Qi){super(),this.control=new Bn,this._registered=!1,this.update=new r.vpe,this._parent=xe,this._setValidators(Ct),this._setAsyncValidators(ur),this.valueAccessor=Wr(0,Qi)}ngOnChanges(xe){this._checkForErrors(),this._registered||this._setUpControl(),"isDisabled"in xe&&this._updateDisabled(xe),mi(xe,this.viewModel)&&(this._updateValue(this.model),this.viewModel=this.model)}ngOnDestroy(){this.formDirective&&this.formDirective.removeControl(this)}get path(){return this._parent?wi(this.name,this._parent):[this.name]}get formDirective(){return this._parent?this._parent.formDirective:null}viewToModelUpdate(xe){this.viewModel=xe,this.update.emit(xe)}_setUpControl(){this._setUpdateStrategy(),this._isStandalone()?this._setUpStandalone():this.formDirective.addControl(this),this._registered=!0}_setUpdateStrategy(){this.options&&null!=this.options.updateOn&&(this.control._updateOn=this.options.updateOn)}_isStandalone(){return!this._parent||!(!this.options||!this.options.standalone)}_setUpStandalone(){br(this.control,this),this.control.updateValueAndValidity({emitEvent:!1})}_checkForErrors(){this._isStandalone()||this._checkParentType(),this._checkName()}_checkParentType(){}_checkName(){this.options&&this.options.name&&(this.name=this.options.name),this._isStandalone()}_updateValue(xe){Vi.then(()=>{this.control.setValue(xe,{emitViewToModelChange:!1})})}_updateDisabled(xe){const Ct=xe.isDisabled.currentValue,ur=""===Ct||Ct&&"false"!==Ct;Vi.then(()=>{ur&&!this.control.disabled?this.control.disable():!ur&&this.control.disabled&&this.control.enable()})}}return Te.\u0275fac=function(xe){return new(xe||Te)(r.Y36(Mr,9),r.Y36(ae,10),r.Y36(H,10),r.Y36(S,10))},Te.\u0275dir=r.lG2({type:Te,selectors:[["","ngModel","",3,"formControlName","",3,"formControl",""]],inputs:{name:"name",isDisabled:["disabled","isDisabled"],model:["ngModel","model"],options:["ngModelOptions","options"]},outputs:{update:"ngModelChange"},exportAs:["ngModel"],features:[r._Bn([on]),r.qOj,r.TTD]}),Te})(),co=(()=>{class Te{}return Te.\u0275fac=function(xe){return new(xe||Te)},Te.\u0275dir=r.lG2({type:Te,selectors:[["form",3,"ngNoForm","",3,"ngNativeValidate",""]],hostAttrs:["novalidate",""]}),Te})();const Es={provide:S,useExisting:(0,r.Gpc)(()=>Zs),multi:!0};let Zs=(()=>{class Te extends y{writeValue(xe){this.setProperty("value",null==xe?"":xe)}registerOnChange(xe){this.onChange=Ct=>{xe(""==Ct?null:parseFloat(Ct))}}}return Te.\u0275fac=function(){let Me;return function(Ct){return(Me||(Me=r.n5z(Te)))(Ct||Te)}}(),Te.\u0275dir=r.lG2({type:Te,selectors:[["input","type","number","formControlName",""],["input","type","number","formControl",""],["input","type","number","ngModel",""]],hostBindings:function(xe,Ct){1&xe&&r.NdJ("input",function(Qi){return Ct.onChange(Qi.target.value)})("blur",function(){return Ct.onTouched()})},features:[r._Bn([Es]),r.qOj]}),Te})();const ls={provide:S,useExisting:(0,r.Gpc)(()=>us),multi:!0};let ta=(()=>{class Te{}return Te.\u0275fac=function(xe){return new(xe||Te)},Te.\u0275mod=r.oAB({type:Te}),Te.\u0275inj=r.cJS({}),Te})(),Is=(()=>{class Te{constructor(){this._accessors=[]}add(xe,Ct){this._accessors.push([xe,Ct])}remove(xe){for(let Ct=this._accessors.length-1;Ct>=0;--Ct)if(this._accessors[Ct][1]===xe)return void this._accessors.splice(Ct,1)}select(xe){this._accessors.forEach(Ct=>{this._isSameGroup(Ct,xe)&&Ct[1]!==xe&&Ct[1].fireUncheck(xe.value)})}_isSameGroup(xe,Ct){return!!xe[0].control&&xe[0]._parent===Ct._control._parent&&xe[1].name===Ct.name}}return Te.\u0275fac=function(xe){return new(xe||Te)},Te.\u0275prov=(0,r.Yz7)({factory:function(){return new Te},token:Te,providedIn:ta}),Te})(),us=(()=>{class Te extends y{constructor(xe,Ct,ur,Qi){super(xe,Ct),this._registry=ur,this._injector=Qi,this.onChange=()=>{}}ngOnInit(){this._control=this._injector.get(Kr),this._checkName(),this._registry.add(this._control,this)}ngOnDestroy(){this._registry.remove(this)}writeValue(xe){this._state=xe===this.value,this.setProperty("checked",this._state)}registerOnChange(xe){this._fn=xe,this.onChange=()=>{xe(this.value),this._registry.select(this)}}fireUncheck(xe){this.writeValue(xe)}_checkName(){!this.name&&this.formControlName&&(this.name=this.formControlName)}}return Te.\u0275fac=function(xe){return new(xe||Te)(r.Y36(r.Qsj),r.Y36(r.SBq),r.Y36(Is),r.Y36(r.zs3))},Te.\u0275dir=r.lG2({type:Te,selectors:[["input","type","radio","formControlName",""],["input","type","radio","formControl",""],["input","type","radio","ngModel",""]],hostBindings:function(xe,Ct){1&xe&&r.NdJ("change",function(){return Ct.onChange()})("blur",function(){return Ct.onTouched()})},inputs:{name:"name",formControlName:"formControlName",value:"value"},features:[r._Bn([ls]),r.qOj]}),Te})();const ca=new r.OlP("NgModelWithFormControlWarning"),Il={provide:Mr,useExisting:(0,r.Gpc)(()=>fo)};let fo=(()=>{class Te extends Mr{constructor(xe,Ct){super(),this.validators=xe,this.asyncValidators=Ct,this.submitted=!1,this._onCollectionChange=()=>this._updateDomValue(),this.directives=[],this.form=null,this.ngSubmit=new r.vpe,this._setValidators(xe),this._setAsyncValidators(Ct)}ngOnChanges(xe){this._checkFormPresent(),xe.hasOwnProperty("form")&&(this._updateValidators(),this._updateDomValue(),this._updateRegistrations(),this._oldForm=this.form)}ngOnDestroy(){this.form&&(Jt(this.form,this),this.form._onCollectionChange===this._onCollectionChange&&this.form._registerOnCollectionChange(()=>{}))}get formDirective(){return this}get control(){return this.form}get path(){return[]}addControl(xe){const Ct=this.form.get(xe.path);return br(Ct,xe),Ct.updateValueAndValidity({emitEvent:!1}),this.directives.push(xe),Ct}getControl(xe){return this.form.get(xe.path)}removeControl(xe){Dr(xe.control||null,xe,!1),dr(this.directives,xe)}addFormGroup(xe){this._setUpFormContainer(xe)}removeFormGroup(xe){this._cleanUpFormContainer(xe)}getFormGroup(xe){return this.form.get(xe.path)}addFormArray(xe){this._setUpFormContainer(xe)}removeFormArray(xe){this._cleanUpFormContainer(xe)}getFormArray(xe){return this.form.get(xe.path)}updateModel(xe,Ct){this.form.get(xe.path).setValue(Ct)}onSubmit(xe){return this.submitted=!0,Er(this.form,this.directives),this.ngSubmit.emit(xe),!1}onReset(){this.resetForm()}resetForm(xe){this.form.reset(xe),this.submitted=!1}_updateDomValue(){this.directives.forEach(xe=>{const Ct=xe.control,ur=this.form.get(xe.path);Ct!==ur&&(Dr(Ct||null,xe),ur instanceof Bn&&(br(ur,xe),xe.control=ur))}),this.form._updateTreeValidity({emitEvent:!1})}_setUpFormContainer(xe){const Ct=this.form.get(xe.path);Yt(Ct,xe),Ct.updateValueAndValidity({emitEvent:!1})}_cleanUpFormContainer(xe){if(this.form){const Ct=this.form.get(xe.path);Ct&&function(Te,Me){return Jt(Te,Me)}(Ct,xe)&&Ct.updateValueAndValidity({emitEvent:!1})}}_updateRegistrations(){this.form._registerOnCollectionChange(this._onCollectionChange),this._oldForm&&this._oldForm._registerOnCollectionChange(()=>{})}_updateValidators(){gr(this.form,this),this._oldForm&&Jt(this._oldForm,this)}_checkFormPresent(){}}return Te.\u0275fac=function(xe){return new(xe||Te)(r.Y36(ae,10),r.Y36(H,10))},Te.\u0275dir=r.lG2({type:Te,selectors:[["","formGroup",""]],hostBindings:function(xe,Ct){1&xe&&r.NdJ("submit",function(Qi){return Ct.onSubmit(Qi)})("reset",function(){return Ct.onReset()})},inputs:{form:["formGroup","form"]},outputs:{ngSubmit:"ngSubmit"},exportAs:["ngForm"],features:[r._Bn([Il]),r.qOj,r.TTD]}),Te})();const Ya={provide:Mr,useExisting:(0,r.Gpc)(()=>Ao)};let Ao=(()=>{class Te extends $o{constructor(xe,Ct,ur){super(),this._parent=xe,this._setValidators(Ct),this._setAsyncValidators(ur)}_checkParentType(){Ra(this._parent)}}return Te.\u0275fac=function(xe){return new(xe||Te)(r.Y36(Mr,13),r.Y36(ae,10),r.Y36(H,10))},Te.\u0275dir=r.lG2({type:Te,selectors:[["","formGroupName",""]],inputs:{name:["formGroupName","name"]},features:[r._Bn([Ya]),r.qOj]}),Te})();const fs={provide:Mr,useExisting:(0,r.Gpc)(()=>Ca)};let Ca=(()=>{class Te extends Mr{constructor(xe,Ct,ur){super(),this._parent=xe,this._setValidators(Ct),this._setAsyncValidators(ur)}ngOnInit(){this._checkParentType(),this.formDirective.addFormArray(this)}ngOnDestroy(){this.formDirective&&this.formDirective.removeFormArray(this)}get control(){return this.formDirective.getFormArray(this)}get formDirective(){return this._parent?this._parent.formDirective:null}get path(){return wi(null==this.name?this.name:this.name.toString(),this._parent)}_checkParentType(){Ra(this._parent)}}return Te.\u0275fac=function(xe){return new(xe||Te)(r.Y36(Mr,13),r.Y36(ae,10),r.Y36(H,10))},Te.\u0275dir=r.lG2({type:Te,selectors:[["","formArrayName",""]],inputs:{name:["formArrayName","name"]},features:[r._Bn([fs]),r.qOj]}),Te})();function Ra(Te){return!(Te instanceof Ao||Te instanceof fo||Te instanceof Ca)}const pl={provide:Kr,useExisting:(0,r.Gpc)(()=>Ws)};let Ws=(()=>{class Te extends Kr{constructor(xe,Ct,ur,Qi,Go){super(),this._ngModelWarningConfig=Go,this._added=!1,this.update=new r.vpe,this._ngModelWarningSent=!1,this._parent=xe,this._setValidators(Ct),this._setAsyncValidators(ur),this.valueAccessor=Wr(0,Qi)}set isDisabled(xe){}ngOnChanges(xe){this._added||this._setUpControl(),mi(xe,this.viewModel)&&(this.viewModel=this.model,this.formDirective.updateModel(this,this.model))}ngOnDestroy(){this.formDirective&&this.formDirective.removeControl(this)}viewToModelUpdate(xe){this.viewModel=xe,this.update.emit(xe)}get path(){return wi(null==this.name?this.name:this.name.toString(),this._parent)}get formDirective(){return this._parent?this._parent.formDirective:null}_checkParentType(){}_setUpControl(){this._checkParentType(),this.control=this.formDirective.addControl(this),this.control.disabled&&this.valueAccessor.setDisabledState&&this.valueAccessor.setDisabledState(!0),this._added=!0}}return Te.\u0275fac=function(xe){return new(xe||Te)(r.Y36(Mr,13),r.Y36(ae,10),r.Y36(H,10),r.Y36(S,10),r.Y36(ca,8))},Te.\u0275dir=r.lG2({type:Te,selectors:[["","formControlName",""]],inputs:{isDisabled:["disabled","isDisabled"],name:["formControlName","name"],model:["ngModel","model"]},outputs:{update:"ngModelChange"},features:[r._Bn([pl]),r.qOj,r.TTD]}),Te._ngModelWarningSentOnce=!1,Te})();const Po={provide:S,useExisting:(0,r.Gpc)(()=>ps),multi:!0};function bo(Te,Me){return null==Te?`${Me}`:(Me&&"object"==typeof Me&&(Me="Object"),`${Te}: ${Me}`.slice(0,50))}let ps=(()=>{class Te extends y{constructor(){super(...arguments),this._optionMap=new Map,this._idCounter=0,this._compareWith=Object.is}set compareWith(xe){this._compareWith=xe}writeValue(xe){this.value=xe;const Ct=this._getOptionId(xe);null==Ct&&this.setProperty("selectedIndex",-1);const ur=bo(Ct,xe);this.setProperty("value",ur)}registerOnChange(xe){this.onChange=Ct=>{this.value=this._getOptionValue(Ct),xe(this.value)}}_registerOption(){return(this._idCounter++).toString()}_getOptionId(xe){for(const Ct of Array.from(this._optionMap.keys()))if(this._compareWith(this._optionMap.get(Ct),xe))return Ct;return null}_getOptionValue(xe){const Ct=function(Te){return Te.split(":")[0]}(xe);return this._optionMap.has(Ct)?this._optionMap.get(Ct):xe}}return Te.\u0275fac=function(){let Me;return function(Ct){return(Me||(Me=r.n5z(Te)))(Ct||Te)}}(),Te.\u0275dir=r.lG2({type:Te,selectors:[["select","formControlName","",3,"multiple",""],["select","formControl","",3,"multiple",""],["select","ngModel","",3,"multiple",""]],hostBindings:function(xe,Ct){1&xe&&r.NdJ("change",function(Qi){return Ct.onChange(Qi.target.value)})("blur",function(){return Ct.onTouched()})},inputs:{compareWith:"compareWith"},features:[r._Bn([Po]),r.qOj]}),Te})(),So=(()=>{class Te{constructor(xe,Ct,ur){this._element=xe,this._renderer=Ct,this._select=ur,this._select&&(this.id=this._select._registerOption())}set ngValue(xe){null!=this._select&&(this._select._optionMap.set(this.id,xe),this._setElementValue(bo(this.id,xe)),this._select.writeValue(this._select.value))}set value(xe){this._setElementValue(xe),this._select&&this._select.writeValue(this._select.value)}_setElementValue(xe){this._renderer.setProperty(this._element.nativeElement,"value",xe)}ngOnDestroy(){this._select&&(this._select._optionMap.delete(this.id),this._select.writeValue(this._select.value))}}return Te.\u0275fac=function(xe){return new(xe||Te)(r.Y36(r.SBq),r.Y36(r.Qsj),r.Y36(ps,9))},Te.\u0275dir=r.lG2({type:Te,selectors:[["option"]],inputs:{ngValue:"ngValue",value:"value"}}),Te})();const $r={provide:S,useExisting:(0,r.Gpc)(()=>ne),multi:!0};function to(Te,Me){return null==Te?`${Me}`:("string"==typeof Me&&(Me=`'${Me}'`),Me&&"object"==typeof Me&&(Me="Object"),`${Te}: ${Me}`.slice(0,50))}let ne=(()=>{class Te extends y{constructor(){super(...arguments),this._optionMap=new Map,this._idCounter=0,this._compareWith=Object.is}set compareWith(xe){this._compareWith=xe}writeValue(xe){let Ct;if(this.value=xe,Array.isArray(xe)){const ur=xe.map(Qi=>this._getOptionId(Qi));Ct=(Qi,Go)=>{Qi._setSelected(ur.indexOf(Go.toString())>-1)}}else Ct=(ur,Qi)=>{ur._setSelected(!1)};this._optionMap.forEach(Ct)}registerOnChange(xe){this.onChange=Ct=>{const ur=[];if(void 0!==Ct.selectedOptions){const Qi=Ct.selectedOptions;for(let Go=0;Go<Qi.length;Go++){const ms=Qi.item(Go),hs=this._getOptionValue(ms.value);ur.push(hs)}}else{const Qi=Ct.options;for(let Go=0;Go<Qi.length;Go++){const ms=Qi.item(Go);if(ms.selected){const hs=this._getOptionValue(ms.value);ur.push(hs)}}}this.value=ur,xe(ur)}}_registerOption(xe){const Ct=(this._idCounter++).toString();return this._optionMap.set(Ct,xe),Ct}_getOptionId(xe){for(const Ct of Array.from(this._optionMap.keys()))if(this._compareWith(this._optionMap.get(Ct)._value,xe))return Ct;return null}_getOptionValue(xe){const Ct=function(Te){return Te.split(":")[0]}(xe);return this._optionMap.has(Ct)?this._optionMap.get(Ct)._value:xe}}return Te.\u0275fac=function(){let Me;return function(Ct){return(Me||(Me=r.n5z(Te)))(Ct||Te)}}(),Te.\u0275dir=r.lG2({type:Te,selectors:[["select","multiple","","formControlName",""],["select","multiple","","formControl",""],["select","multiple","","ngModel",""]],hostBindings:function(xe,Ct){1&xe&&r.NdJ("change",function(Qi){return Ct.onChange(Qi.target)})("blur",function(){return Ct.onTouched()})},inputs:{compareWith:"compareWith"},features:[r._Bn([$r]),r.qOj]}),Te})(),$e=(()=>{class Te{constructor(xe,Ct,ur){this._element=xe,this._renderer=Ct,this._select=ur,this._select&&(this.id=this._select._registerOption(this))}set ngValue(xe){null!=this._select&&(this._value=xe,this._setElementValue(to(this.id,xe)),this._select.writeValue(this._select.value))}set value(xe){this._select?(this._value=xe,this._setElementValue(to(this.id,xe)),this._select.writeValue(this._select.value)):this._setElementValue(xe)}_setElementValue(xe){this._renderer.setProperty(this._element.nativeElement,"value",xe)}_setSelected(xe){this._renderer.setProperty(this._element.nativeElement,"selected",xe)}ngOnDestroy(){this._select&&(this._select._optionMap.delete(this.id),this._select.writeValue(this._select.value))}}return Te.\u0275fac=function(xe){return new(xe||Te)(r.Y36(r.SBq),r.Y36(r.Qsj),r.Y36(ne,9))},Te.\u0275dir=r.lG2({type:Te,selectors:[["option"]],inputs:{ngValue:"ngValue",value:"value"}}),Te})(),an=(()=>{class Te{constructor(){this._validator=Be}handleChanges(xe){if(this.inputName in xe){const Ct=this.normalizeInput(xe[this.inputName].currentValue);this._validator=this.createValidator(Ct),this._onChange&&this._onChange()}}validate(xe){return this._validator(xe)}registerOnValidatorChange(xe){this._onChange=xe}}return Te.\u0275fac=function(xe){return new(xe||Te)},Te.\u0275dir=r.lG2({type:Te}),Te})();const ti={provide:ae,useExisting:(0,r.Gpc)(()=>pi),multi:!0};let pi=(()=>{class Te extends an{constructor(){super(...arguments),this.inputName="max",this.normalizeInput=xe=>parseFloat(xe),this.createValidator=xe=>he(xe)}ngOnChanges(xe){this.handleChanges(xe)}}return Te.\u0275fac=function(){let Me;return function(Ct){return(Me||(Me=r.n5z(Te)))(Ct||Te)}}(),Te.\u0275dir=r.lG2({type:Te,selectors:[["input","type","number","max","","formControlName",""],["input","type","number","max","","formControl",""],["input","type","number","max","","ngModel",""]],hostVars:1,hostBindings:function(xe,Ct){if(2&xe){let ur;r.uIk("max",null!==(ur=Ct.max)&&void 0!==ur?ur:null)}},inputs:{max:"max"},features:[r._Bn([ti]),r.qOj,r.TTD]}),Te})();const xi={provide:ae,useExisting:(0,r.Gpc)(()=>ts),multi:!0};let ts=(()=>{class Te extends an{constructor(){super(...arguments),this.inputName="min",this.normalizeInput=xe=>parseFloat(xe),this.createValidator=xe=>ie(xe)}ngOnChanges(xe){this.handleChanges(xe)}}return Te.\u0275fac=function(){let Me;return function(Ct){return(Me||(Me=r.n5z(Te)))(Ct||Te)}}(),Te.\u0275dir=r.lG2({type:Te,selectors:[["input","type","number","min","","formControlName",""],["input","type","number","min","","formControl",""],["input","type","number","min","","ngModel",""]],hostVars:1,hostBindings:function(xe,Ct){if(2&xe){let ur;r.uIk("min",null!==(ur=Ct.min)&&void 0!==ur?ur:null)}},inputs:{min:"min"},features:[r._Bn([xi]),r.qOj,r.TTD]}),Te})();const wo={provide:ae,useExisting:(0,r.Gpc)(()=>Eo),multi:!0};let Eo=(()=>{class Te{constructor(){this._required=!1}get required(){return this._required}set required(xe){this._required=null!=xe&&!1!==xe&&"false"!=`${xe}`,this._onChange&&this._onChange()}validate(xe){return this.required?ge(xe):null}registerOnValidatorChange(xe){this._onChange=xe}}return Te.\u0275fac=function(xe){return new(xe||Te)},Te.\u0275dir=r.lG2({type:Te,selectors:[["","required","","formControlName","",3,"type","checkbox"],["","required","","formControl","",3,"type","checkbox"],["","required","","ngModel","",3,"type","checkbox"]],hostVars:1,hostBindings:function(xe,Ct){2&xe&&r.uIk("required",Ct.required?"":null)},inputs:{required:"required"},features:[r._Bn([wo])]}),Te})(),tl=(()=>{class Te{}return Te.\u0275fac=function(xe){return new(xe||Te)},Te.\u0275mod=r.oAB({type:Te}),Te.\u0275inj=r.cJS({imports:[[ta]]}),Te})(),Su=(()=>{class Te{}return Te.\u0275fac=function(xe){return new(xe||Te)},Te.\u0275mod=r.oAB({type:Te}),Te.\u0275inj=r.cJS({imports:[tl]}),Te})(),Zl=(()=>{class Te{static withConfig(xe){return{ngModule:Te,providers:[{provide:ca,useValue:xe.warnOnNgModelWithFormControl}]}}}return Te.\u0275fac=function(xe){return new(xe||Te)},Te.\u0275mod=r.oAB({type:Te}),Te.\u0275inj=r.cJS({imports:[tl]}),Te})(),Pt=(()=>{class Te{group(xe,Ct=null){const ur=this._reduceControls(xe);let ms,Qi=null,Go=null;return null!=Ct&&(function(Te){return void 0!==Te.asyncValidators||void 0!==Te.validators||void 0!==Te.updateOn}(Ct)?(Qi=null!=Ct.validators?Ct.validators:null,Go=null!=Ct.asyncValidators?Ct.asyncValidators:null,ms=null!=Ct.updateOn?Ct.updateOn:void 0):(Qi=null!=Ct.validator?Ct.validator:null,Go=null!=Ct.asyncValidator?Ct.asyncValidator:null)),new lr(ur,{asyncValidators:Go,updateOn:ms,validators:Qi})}control(xe,Ct,ur){return new Bn(xe,Ct,ur)}array(xe,Ct,ur){const Qi=xe.map(Go=>this._createControl(Go));return new vr(Qi,Ct,ur)}_reduceControls(xe){const Ct={};return Object.keys(xe).forEach(ur=>{Ct[ur]=this._createControl(xe[ur])}),Ct}_createControl(xe){return xe instanceof Bn||xe instanceof lr||xe instanceof vr?xe:Array.isArray(xe)?this.control(xe[0],xe.length>1?xe[1]:null,xe.length>2?xe[2]:null):this.control(xe)}}return Te.\u0275fac=function(xe){return new(xe||Te)},Te.\u0275prov=(0,r.Yz7)({factory:function(){return new Te},token:Te,providedIn:Zl}),Te})()},91211:(v,T,i)=>{"use strict";i.d(T,{b2:()=>Fn,H7:()=>Vn,HJ:()=>li,q6:()=>Wr,se:()=>di});var r=i(12057),u=i(74788);class p extends r.w_{constructor(){super(...arguments),this.supportsDOMEvents=!0}}class d extends p{static makeCurrent(){(0,r.HT)(new d)}onAndCancel(_t,mt,jt){return _t.addEventListener(mt,jt,!1),()=>{_t.removeEventListener(mt,jt,!1)}}dispatchEvent(_t,mt){_t.dispatchEvent(mt)}remove(_t){_t.parentNode&&_t.parentNode.removeChild(_t)}createElement(_t,mt){return(mt=mt||this.getDefaultDocument()).createElement(_t)}createHtmlDocument(){return document.implementation.createHTMLDocument("fakeTitle")}getDefaultDocument(){return document}isElementNode(_t){return _t.nodeType===Node.ELEMENT_NODE}isShadowRoot(_t){return _t instanceof DocumentFragment}getGlobalEventTarget(_t,mt){return"window"===mt?window:"document"===mt?_t:"body"===mt?_t.body:null}getBaseHref(_t){const mt=(e=e||document.querySelector("base"),e?e.getAttribute("href"):null);return null==mt?null:function(Rt){y=y||document.createElement("a"),y.setAttribute("href",Rt);const _t=y.pathname;return"/"===_t.charAt(0)?_t:`/${_t}`}(mt)}resetBaseElement(){e=null}getUserAgent(){return window.navigator.userAgent}getCookie(_t){return(0,r.Mx)(document.cookie,_t)}}let y,e=null;const A=new u.OlP("TRANSITION_ID"),L=[{provide:u.ip1,useFactory:function(Rt,_t,mt){return()=>{mt.get(u.CZH).donePromise.then(()=>{const jt=(0,r.q)(),on=_t.querySelectorAll(`style[ng-transition="${Rt}"]`);for(let si=0;si<on.length;si++)jt.remove(on[si])})}},deps:[A,r.K0,u.zs3],multi:!0}];class Z{static init(){(0,u.VLi)(new Z)}addToWindow(_t){u.dqk.getAngularTestability=(jt,on=!0)=>{const si=_t.findTestabilityInTree(jt,on);if(null==si)throw new Error("Could not find testability for element.");return si},u.dqk.getAllAngularTestabilities=()=>_t.getAllTestabilities(),u.dqk.getAllAngularRootElements=()=>_t.getAllRootElements(),u.dqk.frameworkStabilizers||(u.dqk.frameworkStabilizers=[]),u.dqk.frameworkStabilizers.push(jt=>{const on=u.dqk.getAllAngularTestabilities();let si=on.length,Vi=!1;const _o=function(co){Vi=Vi||co,si--,0==si&&jt(Vi)};on.forEach(function(co){co.whenStable(_o)})})}findTestabilityInTree(_t,mt,jt){if(null==mt)return null;const on=_t.getTestability(mt);return null!=on?on:jt?(0,r.q)().isShadowRoot(mt)?this.findTestabilityInTree(_t,mt.host,!0):this.findTestabilityInTree(_t,mt.parentElement,!0):null}}let J=(()=>{class Rt{build(){return new XMLHttpRequest}}return Rt.\u0275fac=function(mt){return new(mt||Rt)},Rt.\u0275prov=u.Yz7({token:Rt,factory:Rt.\u0275fac}),Rt})();const Be=new u.OlP("EventManagerPlugins");let Pe=(()=>{class Rt{constructor(mt,jt){this._zone=jt,this._eventNameToPlugin=new Map,mt.forEach(on=>on.manager=this),this._plugins=mt.slice().reverse()}addEventListener(mt,jt,on){return this._findPluginFor(jt).addEventListener(mt,jt,on)}addGlobalEventListener(mt,jt,on){return this._findPluginFor(jt).addGlobalEventListener(mt,jt,on)}getZone(){return this._zone}_findPluginFor(mt){const jt=this._eventNameToPlugin.get(mt);if(jt)return jt;const on=this._plugins;for(let si=0;si<on.length;si++){const Vi=on[si];if(Vi.supports(mt))return this._eventNameToPlugin.set(mt,Vi),Vi}throw new Error(`No event manager plugin found for event ${mt}`)}}return Rt.\u0275fac=function(mt){return new(mt||Rt)(u.LFG(Be),u.LFG(u.R0b))},Rt.\u0275prov=u.Yz7({token:Rt,factory:Rt.\u0275fac}),Rt})();class je{constructor(_t){this._doc=_t}addGlobalEventListener(_t,mt,jt){const on=(0,r.q)().getGlobalEventTarget(this._doc,_t);if(!on)throw new Error(`Unsupported event target ${on} for event ${mt}`);return this.addEventListener(on,mt,jt)}}let He=(()=>{class Rt{constructor(){this._stylesSet=new Set}addStyles(mt){const jt=new Set;mt.forEach(on=>{this._stylesSet.has(on)||(this._stylesSet.add(on),jt.add(on))}),this.onStylesAdded(jt)}onStylesAdded(mt){}getAllStyles(){return Array.from(this._stylesSet)}}return Rt.\u0275fac=function(mt){return new(mt||Rt)},Rt.\u0275prov=u.Yz7({token:Rt,factory:Rt.\u0275fac}),Rt})(),Vt=(()=>{class Rt extends He{constructor(mt){super(),this._doc=mt,this._hostNodes=new Map,this._hostNodes.set(mt.head,[])}_addStylesToHost(mt,jt,on){mt.forEach(si=>{const Vi=this._doc.createElement("style");Vi.textContent=si,on.push(jt.appendChild(Vi))})}addHost(mt){const jt=[];this._addStylesToHost(this._stylesSet,mt,jt),this._hostNodes.set(mt,jt)}removeHost(mt){const jt=this._hostNodes.get(mt);jt&&jt.forEach(it),this._hostNodes.delete(mt)}onStylesAdded(mt){this._hostNodes.forEach((jt,on)=>{this._addStylesToHost(mt,on,jt)})}ngOnDestroy(){this._hostNodes.forEach(mt=>mt.forEach(it))}}return Rt.\u0275fac=function(mt){return new(mt||Rt)(u.LFG(r.K0))},Rt.\u0275prov=u.Yz7({token:Rt,factory:Rt.\u0275fac}),Rt})();function it(Rt){(0,r.q)().remove(Rt)}const tn={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},It=/%COMP%/g;function Xt(Rt,_t,mt){for(let jt=0;jt<_t.length;jt++){let on=_t[jt];Array.isArray(on)?Xt(Rt,on,mt):(on=on.replace(It,Rt),mt.push(on))}return mt}function Zn(Rt){return _t=>{if("__ngUnwrap__"===_t)return Rt;!1===Rt(_t)&&(_t.preventDefault(),_t.returnValue=!1)}}let di=(()=>{class Rt{constructor(mt,jt,on){this.eventManager=mt,this.sharedStylesHost=jt,this.appId=on,this.rendererByCompId=new Map,this.defaultRenderer=new Lr(mt)}createRenderer(mt,jt){if(!mt||!jt)return this.defaultRenderer;switch(jt.encapsulation){case u.ifc.Emulated:{let on=this.rendererByCompId.get(jt.id);return on||(on=new Nn(this.eventManager,this.sharedStylesHost,jt,this.appId),this.rendererByCompId.set(jt.id,on)),on.applyToHost(mt),on}case 1:case u.ifc.ShadowDom:return new $n(this.eventManager,this.sharedStylesHost,mt,jt);default:if(!this.rendererByCompId.has(jt.id)){const on=Xt(jt.id,jt.styles,[]);this.sharedStylesHost.addStyles(on),this.rendererByCompId.set(jt.id,this.defaultRenderer)}return this.defaultRenderer}}begin(){}end(){}}return Rt.\u0275fac=function(mt){return new(mt||Rt)(u.LFG(Pe),u.LFG(Vt),u.LFG(u.AFp))},Rt.\u0275prov=u.Yz7({token:Rt,factory:Rt.\u0275fac}),Rt})();class Lr{constructor(_t){this.eventManager=_t,this.data=Object.create(null)}destroy(){}createElement(_t,mt){return mt?document.createElementNS(tn[mt]||mt,_t):document.createElement(_t)}createComment(_t){return document.createComment(_t)}createText(_t){return document.createTextNode(_t)}appendChild(_t,mt){_t.appendChild(mt)}insertBefore(_t,mt,jt){_t&&_t.insertBefore(mt,jt)}removeChild(_t,mt){_t&&_t.removeChild(mt)}selectRootElement(_t,mt){let jt="string"==typeof _t?document.querySelector(_t):_t;if(!jt)throw new Error(`The selector "${_t}" did not match any elements`);return mt||(jt.textContent=""),jt}parentNode(_t){return _t.parentNode}nextSibling(_t){return _t.nextSibling}setAttribute(_t,mt,jt,on){if(on){mt=on+":"+mt;const si=tn[on];si?_t.setAttributeNS(si,mt,jt):_t.setAttribute(mt,jt)}else _t.setAttribute(mt,jt)}removeAttribute(_t,mt,jt){if(jt){const on=tn[jt];on?_t.removeAttributeNS(on,mt):_t.removeAttribute(`${jt}:${mt}`)}else _t.removeAttribute(mt)}addClass(_t,mt){_t.classList.add(mt)}removeClass(_t,mt){_t.classList.remove(mt)}setStyle(_t,mt,jt,on){on&(u.JOm.DashCase|u.JOm.Important)?_t.style.setProperty(mt,jt,on&u.JOm.Important?"important":""):_t.style[mt]=jt}removeStyle(_t,mt,jt){jt&u.JOm.DashCase?_t.style.removeProperty(mt):_t.style[mt]=""}setProperty(_t,mt,jt){_t[mt]=jt}setValue(_t,mt){_t.nodeValue=mt}listen(_t,mt,jt){return"string"==typeof _t?this.eventManager.addGlobalEventListener(_t,mt,Zn(jt)):this.eventManager.addEventListener(_t,mt,Zn(jt))}}class Nn extends Lr{constructor(_t,mt,jt,on){super(_t),this.component=jt;const si=Xt(on+"-"+jt.id,jt.styles,[]);mt.addStyles(si),this.contentAttr="_ngcontent-%COMP%".replace(It,on+"-"+jt.id),this.hostAttr="_nghost-%COMP%".replace(It,on+"-"+jt.id)}applyToHost(_t){super.setAttribute(_t,this.hostAttr,"")}createElement(_t,mt){const jt=super.createElement(_t,mt);return super.setAttribute(jt,this.contentAttr,""),jt}}class $n extends Lr{constructor(_t,mt,jt,on){super(_t),this.sharedStylesHost=mt,this.hostEl=jt,this.shadowRoot=jt.attachShadow({mode:"open"}),this.sharedStylesHost.addHost(this.shadowRoot);const si=Xt(on.id,on.styles,[]);for(let Vi=0;Vi<si.length;Vi++){const _o=document.createElement("style");_o.textContent=si[Vi],this.shadowRoot.appendChild(_o)}}nodeOrShadowRoot(_t){return _t===this.hostEl?this.shadowRoot:_t}destroy(){this.sharedStylesHost.removeHost(this.shadowRoot)}appendChild(_t,mt){return super.appendChild(this.nodeOrShadowRoot(_t),mt)}insertBefore(_t,mt,jt){return super.insertBefore(this.nodeOrShadowRoot(_t),mt,jt)}removeChild(_t,mt){return super.removeChild(this.nodeOrShadowRoot(_t),mt)}parentNode(_t){return this.nodeOrShadowRoot(super.parentNode(this.nodeOrShadowRoot(_t)))}}let Br=(()=>{class Rt extends je{constructor(mt){super(mt)}supports(mt){return!0}addEventListener(mt,jt,on){return mt.addEventListener(jt,on,!1),()=>this.removeEventListener(mt,jt,on)}removeEventListener(mt,jt,on){return mt.removeEventListener(jt,on)}}return Rt.\u0275fac=function(mt){return new(mt||Rt)(u.LFG(r.K0))},Rt.\u0275prov=u.Yz7({token:Rt,factory:Rt.\u0275fac}),Rt})();const Fr=["alt","control","meta","shift"],Jr={"\b":"Backspace","\t":"Tab","\x7f":"Delete","\x1b":"Escape",Del:"Delete",Esc:"Escape",Left:"ArrowLeft",Right:"ArrowRight",Up:"ArrowUp",Down:"ArrowDown",Menu:"ContextMenu",Scroll:"ScrollLock",Win:"OS"},_i={A:"1",B:"2",C:"3",D:"4",E:"5",F:"6",G:"7",H:"8",I:"9",J:"*",K:"+",M:"-",N:".",O:"/","`":"0","\x90":"NumLock"},yn={alt:Rt=>Rt.altKey,control:Rt=>Rt.ctrlKey,meta:Rt=>Rt.metaKey,shift:Rt=>Rt.shiftKey};let gr=(()=>{class Rt extends je{constructor(mt){super(mt)}supports(mt){return null!=Rt.parseEventName(mt)}addEventListener(mt,jt,on){const si=Rt.parseEventName(jt),Vi=Rt.eventCallback(si.fullKey,on,this.manager.getZone());return this.manager.getZone().runOutsideAngular(()=>(0,r.q)().onAndCancel(mt,si.domEventName,Vi))}static parseEventName(mt){const jt=mt.toLowerCase().split("."),on=jt.shift();if(0===jt.length||"keydown"!==on&&"keyup"!==on)return null;const si=Rt._normalizeKey(jt.pop());let Vi="";if(Fr.forEach(co=>{const Es=jt.indexOf(co);Es>-1&&(jt.splice(Es,1),Vi+=co+".")}),Vi+=si,0!=jt.length||0===si.length)return null;const _o={};return _o.domEventName=on,_o.fullKey=Vi,_o}static getEventFullKey(mt){let jt="",on=function(Rt){let _t=Rt.key;if(null==_t){if(_t=Rt.keyIdentifier,null==_t)return"Unidentified";_t.startsWith("U+")&&(_t=String.fromCharCode(parseInt(_t.substring(2),16)),3===Rt.location&&_i.hasOwnProperty(_t)&&(_t=_i[_t]))}return Jr[_t]||_t}(mt);return on=on.toLowerCase()," "===on?on="space":"."===on&&(on="dot"),Fr.forEach(si=>{si!=on&&yn[si](mt)&&(jt+=si+".")}),jt+=on,jt}static eventCallback(mt,jt,on){return si=>{Rt.getEventFullKey(si)===mt&&on.runGuarded(()=>jt(si))}}static _normalizeKey(mt){switch(mt){case"esc":return"escape";default:return mt}}}return Rt.\u0275fac=function(mt){return new(mt||Rt)(u.LFG(r.K0))},Rt.\u0275prov=u.Yz7({token:Rt,factory:Rt.\u0275fac}),Rt})(),Vn=(()=>{class Rt{}return Rt.\u0275fac=function(mt){return new(mt||Rt)},Rt.\u0275prov=(0,u.Yz7)({factory:function(){return(0,u.LFG)(Dn)},token:Rt,providedIn:"root"}),Rt})(),Dn=(()=>{class Rt extends Vn{constructor(mt){super(),this._doc=mt}sanitize(mt,jt){if(null==jt)return null;switch(mt){case u.q3G.NONE:return jt;case u.q3G.HTML:return(0,u.qzn)(jt,"HTML")?(0,u.z3N)(jt):(0,u.EiD)(this._doc,String(jt)).toString();case u.q3G.STYLE:return(0,u.qzn)(jt,"Style")?(0,u.z3N)(jt):jt;case u.q3G.SCRIPT:if((0,u.qzn)(jt,"Script"))return(0,u.z3N)(jt);throw new Error("unsafe value used in a script context");case u.q3G.URL:return(0,u.yhl)(jt),(0,u.qzn)(jt,"URL")?(0,u.z3N)(jt):(0,u.mCW)(String(jt));case u.q3G.RESOURCE_URL:if((0,u.qzn)(jt,"ResourceURL"))return(0,u.z3N)(jt);throw new Error("unsafe value used in a resource URL context (see https://g.co/ng/security#xss)");default:throw new Error(`Unexpected SecurityContext ${mt} (see https://g.co/ng/security#xss)`)}}bypassSecurityTrustHtml(mt){return(0,u.JVY)(mt)}bypassSecurityTrustStyle(mt){return(0,u.L6k)(mt)}bypassSecurityTrustScript(mt){return(0,u.eBb)(mt)}bypassSecurityTrustUrl(mt){return(0,u.LAX)(mt)}bypassSecurityTrustResourceUrl(mt){return(0,u.pB0)(mt)}}return Rt.\u0275fac=function(mt){return new(mt||Rt)(u.LFG(r.K0))},Rt.\u0275prov=(0,u.Yz7)({factory:function(){return function(Rt){return new Dn(Rt.get(r.K0))}((0,u.LFG)(u.gxx))},token:Rt,providedIn:"root"}),Rt})();const Wr=(0,u.eFA)(u._c5,"browser",[{provide:u.Lbi,useValue:r.bD},{provide:u.g9A,useValue:function(){d.makeCurrent(),Z.init()},multi:!0},{provide:r.K0,useFactory:function(){return(0,u.RDi)(document),document},deps:[]}]),dr=[[],{provide:u.zSh,useValue:"root"},{provide:u.qLn,useFactory:function(){return new u.qLn},deps:[]},{provide:Be,useClass:Br,multi:!0,deps:[r.K0,u.R0b,u.Lbi]},{provide:Be,useClass:gr,multi:!0,deps:[r.K0]},[],{provide:di,useClass:di,deps:[Pe,Vt,u.AFp]},{provide:u.FYo,useExisting:di},{provide:He,useExisting:Vt},{provide:Vt,useClass:Vt,deps:[r.K0]},{provide:u.dDg,useClass:u.dDg,deps:[u.R0b]},{provide:Pe,useClass:Pe,deps:[Be,u.R0b]},{provide:r.JF,useClass:J,deps:[]},[]];let Fn=(()=>{class Rt{constructor(mt){if(mt)throw new Error("BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.")}static withServerTransition(mt){return{ngModule:Rt,providers:[{provide:u.AFp,useValue:mt.appId},{provide:A,useExisting:u.AFp},L]}}}return Rt.\u0275fac=function(mt){return new(mt||Rt)(u.LFG(Rt,12))},Rt.\u0275mod=u.oAB({type:Rt}),Rt.\u0275inj=u.cJS({providers:dr,imports:[r.ez,u.hGG]}),Rt})();const Gi="undefined"!=typeof window&&window||{};class os{constructor(_t,mt){this.msPerTick=_t,this.numTicks=mt}}class jo{constructor(_t){this.appRef=_t.injector.get(u.z2F)}timeChangeDetection(_t){const mt=_t&&_t.record,jt="Change Detection",on=null!=Gi.console.profile;mt&&on&&Gi.console.profile(jt);const si=To();let Vi=0;for(;Vi<5||To()-si<500;)this.appRef.tick(),Vi++;const _o=To();mt&&on&&Gi.console.profileEnd(jt);const co=(_o-si)/Vi;return Gi.console.log(`ran ${Vi} change detection cycles`),Gi.console.log(`${co.toFixed(2)} ms per check`),new os(co,Vi)}}function To(){return Gi.performance&&Gi.performance.now?Gi.performance.now():(new Date).getTime()}function li(Rt){return function(Rt,_t){"undefined"!=typeof COMPILED&&COMPILED||((u.dqk.ng=u.dqk.ng||{})[Rt]=_t)}("profiler",new jo(Rt)),Rt}},6283:(v,T,i)=>{"use strict";i.d(T,{gz:()=>tr,m2:()=>He,OD:()=>je,wm:()=>Tl,F0:()=>zr,rH:()=>Io,Od:()=>Cr,yS:()=>Fo,Bz:()=>Js,lC:()=>ao});var r=i(12057),u=i(74788),p=i(18891),d=i(94402),e=i(59193);function _(Ye){return new p.y(Ie=>{let Ce;try{Ce=Ye()}catch(Et){return void Ie.error(Et)}return(Ce?(0,d.D)(Ce):(0,e.c)()).subscribe(Ie)})}var y=i(25917),S=i(26215),A=i(9112),N=i(13410),L=i(58071),Z=i(52441),J=i(79765),K=i(88002),ee=i(43190),ue=i(15257),ae=i(39761),H=i(42145),se=i(45435),Ee=i(5304),ie=i(94612),he=i(12627),ge=i(28049),De=i(19773),ce=i(68307),lt=i(548),Ve=i(51307),ze=i(68939),Be=i(63282);class Pe{constructor(Ie,Ce){this.id=Ie,this.url=Ce}}class je extends Pe{constructor(Ie,Ce,ot="imperative",Et=null){super(Ie,Ce),this.navigationTrigger=ot,this.restoredState=Et}toString(){return`NavigationStart(id: ${this.id}, url: '${this.url}')`}}class He extends Pe{constructor(Ie,Ce,ot){super(Ie,Ce),this.urlAfterRedirects=ot}toString(){return`NavigationEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}')`}}class Vt extends Pe{constructor(Ie,Ce,ot){super(Ie,Ce),this.reason=ot}toString(){return`NavigationCancel(id: ${this.id}, url: '${this.url}')`}}class it extends Pe{constructor(Ie,Ce,ot){super(Ie,Ce),this.error=ot}toString(){return`NavigationError(id: ${this.id}, url: '${this.url}', error: ${this.error})`}}class tn extends Pe{constructor(Ie,Ce,ot,Et){super(Ie,Ce),this.urlAfterRedirects=ot,this.state=Et}toString(){return`RoutesRecognized(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`}}class It extends Pe{constructor(Ie,Ce,ot,Et){super(Ie,Ce),this.urlAfterRedirects=ot,this.state=Et}toString(){return`GuardsCheckStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`}}class Zt extends Pe{constructor(Ie,Ce,ot,Et,qt){super(Ie,Ce),this.urlAfterRedirects=ot,this.state=Et,this.shouldActivate=qt}toString(){return`GuardsCheckEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state}, shouldActivate: ${this.shouldActivate})`}}class Ut extends Pe{constructor(Ie,Ce,ot,Et){super(Ie,Ce),this.urlAfterRedirects=ot,this.state=Et}toString(){return`ResolveStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`}}class Bt extends Pe{constructor(Ie,Ce,ot,Et){super(Ie,Ce),this.urlAfterRedirects=ot,this.state=Et}toString(){return`ResolveEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`}}class bt{constructor(Ie){this.route=Ie}toString(){return`RouteConfigLoadStart(path: ${this.route.path})`}}class Gt{constructor(Ie){this.route=Ie}toString(){return`RouteConfigLoadEnd(path: ${this.route.path})`}}class xt{constructor(Ie){this.snapshot=Ie}toString(){return`ChildActivationStart(path: '${this.snapshot.routeConfig&&this.snapshot.routeConfig.path||""}')`}}class Xt{constructor(Ie){this.snapshot=Ie}toString(){return`ChildActivationEnd(path: '${this.snapshot.routeConfig&&this.snapshot.routeConfig.path||""}')`}}class Zn{constructor(Ie){this.snapshot=Ie}toString(){return`ActivationStart(path: '${this.snapshot.routeConfig&&this.snapshot.routeConfig.path||""}')`}}class Ur{constructor(Ie){this.snapshot=Ie}toString(){return`ActivationEnd(path: '${this.snapshot.routeConfig&&this.snapshot.routeConfig.path||""}')`}}class di{constructor(Ie,Ce,ot){this.routerEvent=Ie,this.position=Ce,this.anchor=ot}toString(){return`Scroll(anchor: '${this.anchor}', position: '${this.position?`${this.position[0]}, ${this.position[1]}`:null}')`}}const Lr="primary";class Mr{constructor(Ie){this.params=Ie||{}}has(Ie){return Object.prototype.hasOwnProperty.call(this.params,Ie)}get(Ie){if(this.has(Ie)){const Ce=this.params[Ie];return Array.isArray(Ce)?Ce[0]:Ce}return null}getAll(Ie){if(this.has(Ie)){const Ce=this.params[Ie];return Array.isArray(Ce)?Ce:[Ce]}return[]}get keys(){return Object.keys(this.params)}}function Kr(Ye){return new Mr(Ye)}const ei="ngNavigationCancelingError";function Nn(Ye){const Ie=Error("NavigationCancelingError: "+Ye);return Ie[ei]=!0,Ie}function Br(Ye,Ie,Ce){const ot=Ce.path.split("/");if(ot.length>Ye.length||"full"===Ce.pathMatch&&(Ie.hasChildren()||ot.length<Ye.length))return null;const Et={};for(let qt=0;qt<ot.length;qt++){const Hn=ot[qt],Xn=Ye[qt];if(Hn.startsWith(":"))Et[Hn.substring(1)]=Xn;else if(Hn!==Xn.path)return null}return{consumed:Ye.slice(0,ot.length),posParams:Et}}function fi(Ye,Ie){const Ce=Ye?Object.keys(Ye):void 0,ot=Ie?Object.keys(Ie):void 0;if(!Ce||!ot||Ce.length!=ot.length)return!1;let Et;for(let qt=0;qt<Ce.length;qt++)if(Et=Ce[qt],!ki(Ye[Et],Ie[Et]))return!1;return!0}function ki(Ye,Ie){if(Array.isArray(Ye)&&Array.isArray(Ie)){if(Ye.length!==Ie.length)return!1;const Ce=[...Ye].sort(),ot=[...Ie].sort();return Ce.every((Et,qt)=>ot[qt]===Et)}return Ye===Ie}function Hi(Ye){return Array.prototype.concat.apply([],Ye)}function Zr(Ye){return Ye.length>0?Ye[Ye.length-1]:null}function Wt(Ye,Ie){for(const Ce in Ye)Ye.hasOwnProperty(Ce)&&Ie(Ye[Ce],Ce)}function zn(Ye){return(0,u.CqO)(Ye)?Ye:(0,u.QGY)(Ye)?(0,d.D)(Promise.resolve(Ye)):(0,y.of)(Ye)}const Fr={exact:function wi(Ye,Ie,Ce){if(!Dn(Ye.segments,Ie.segments)||!yn(Ye.segments,Ie.segments,Ce)||Ye.numberOfChildren!==Ie.numberOfChildren)return!1;for(const ot in Ie.children)if(!Ye.children[ot]||!wi(Ye.children[ot],Ie.children[ot],Ce))return!1;return!0},subset:Dr},Gn={exact:function(Ye,Ie){return fi(Ye,Ie)},subset:function(Ye,Ie){return Object.keys(Ie).length<=Object.keys(Ye).length&&Object.keys(Ie).every(Ce=>ki(Ye[Ce],Ie[Ce]))},ignored:()=>!0};function Jr(Ye,Ie,Ce){return Fr[Ce.paths](Ye.root,Ie.root,Ce.matrixParams)&&Gn[Ce.queryParams](Ye.queryParams,Ie.queryParams)&&!("exact"===Ce.fragment&&Ye.fragment!==Ie.fragment)}function Dr(Ye,Ie,Ce){return gn(Ye,Ie,Ie.segments,Ce)}function gn(Ye,Ie,Ce,ot){if(Ye.segments.length>Ce.length){const Et=Ye.segments.slice(0,Ce.length);return!(!Dn(Et,Ce)||Ie.hasChildren()||!yn(Et,Ce,ot))}if(Ye.segments.length===Ce.length){if(!Dn(Ye.segments,Ce)||!yn(Ye.segments,Ce,ot))return!1;for(const Et in Ie.children)if(!Ye.children[Et]||!Dr(Ye.children[Et],Ie.children[Et],ot))return!1;return!0}{const Et=Ce.slice(0,Ye.segments.length),qt=Ce.slice(Ye.segments.length);return!!(Dn(Ye.segments,Et)&&yn(Ye.segments,Et,ot)&&Ye.children[Lr])&&gn(Ye.children[Lr],Ie,qt,ot)}}function yn(Ye,Ie,Ce){return Ie.every((ot,Et)=>Gn[Ce](Ye[Et].parameters,ot.parameters))}class gr{constructor(Ie,Ce,ot){this.root=Ie,this.queryParams=Ce,this.fragment=ot}get queryParamMap(){return this._queryParamMap||(this._queryParamMap=Kr(this.queryParams)),this._queryParamMap}toString(){return Ge.serialize(this)}}class Jt{constructor(Ie,Ce){this.segments=Ie,this.children=Ce,this.parent=null,Wt(Ce,(ot,Et)=>ot.parent=this)}hasChildren(){return this.numberOfChildren>0}get numberOfChildren(){return Object.keys(this.children).length}toString(){return kr(this)}}class Vn{constructor(Ie,Ce){this.path=Ie,this.parameters=Ce}get parameterMap(){return this._parameterMap||(this._parameterMap=Kr(this.parameters)),this._parameterMap}toString(){return Wi(this)}}function Dn(Ye,Ie){return Ye.length===Ie.length&&Ye.every((Ce,ot)=>Ce.path===Ie[ot].path)}class Yt{}class _n{parse(Ie){const Ce=new li(Ie);return new gr(Ce.parseRootSegment(),Ce.parseQueryParams(),Ce.parseFragment())}serialize(Ie){var Ye;return`${`/${mi(Ie.root,!0)}`}${function(Ye){const Ie=Object.keys(Ye).map(Ce=>{const ot=Ye[Ce];return Array.isArray(ot)?ot.map(Et=>`${Er(Ce)}=${Er(Et)}`).join("&"):`${Er(Ce)}=${Er(ot)}`}).filter(Ce=>!!Ce);return Ie.length?`?${Ie.join("&")}`:""}(Ie.queryParams)}${"string"==typeof Ie.fragment?`#${Ye=Ie.fragment,encodeURI(Ye)}`:""}`}}const Ge=new _n;function kr(Ye){return Ye.segments.map(Ie=>Wi(Ie)).join("/")}function mi(Ye,Ie){if(!Ye.hasChildren())return kr(Ye);if(Ie){const Ce=Ye.children[Lr]?mi(Ye.children[Lr],!1):"",ot=[];return Wt(Ye.children,(Et,qt)=>{qt!==Lr&&ot.push(`${qt}:${mi(Et,!1)}`)}),ot.length>0?`${Ce}(${ot.join("//")})`:Ce}{const Ce=function(Ye,Ie){let Ce=[];return Wt(Ye.children,(ot,Et)=>{Et===Lr&&(Ce=Ce.concat(Ie(ot,Et)))}),Wt(Ye.children,(ot,Et)=>{Et!==Lr&&(Ce=Ce.concat(Ie(ot,Et)))}),Ce}(Ye,(ot,Et)=>Et===Lr?[mi(Ye.children[Lr],!1)]:[`${Et}:${mi(ot,!1)}`]);return 1===Object.keys(Ye.children).length&&null!=Ye.children[Lr]?`${kr(Ye)}/${Ce[0]}`:`${kr(Ye)}/(${Ce.join("//")})`}}function An(Ye){return encodeURIComponent(Ye).replace(/%40/g,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",")}function Er(Ye){return An(Ye).replace(/%3B/gi,";")}function dr(Ye){return An(Ye).replace(/\(/g,"%28").replace(/\)/g,"%29").replace(/%26/gi,"&")}function Fn(Ye){return decodeURIComponent(Ye)}function ar(Ye){return Fn(Ye.replace(/\+/g,"%20"))}function Wi(Ye){return`${dr(Ye.path)}${function(Ye){return Object.keys(Ye).map(Ie=>`;${dr(Ie)}=${dr(Ye[Ie])}`).join("")}(Ye.parameters)}`}const Co=/^[^\/()?;=#]+/;function Gi(Ye){const Ie=Ye.match(Co);return Ie?Ie[0]:""}const os=/^[^=?&#]+/,To=/^[^?&#]+/;class li{constructor(Ie){this.url=Ie,this.remaining=Ie}parseRootSegment(){return this.consumeOptional("/"),""===this.remaining||this.peekStartsWith("?")||this.peekStartsWith("#")?new Jt([],{}):new Jt([],this.parseChildren())}parseQueryParams(){const Ie={};if(this.consumeOptional("?"))do{this.parseQueryParam(Ie)}while(this.consumeOptional("&"));return Ie}parseFragment(){return this.consumeOptional("#")?decodeURIComponent(this.remaining):null}parseChildren(){if(""===this.remaining)return{};this.consumeOptional("/");const Ie=[];for(this.peekStartsWith("(")||Ie.push(this.parseSegment());this.peekStartsWith("/")&&!this.peekStartsWith("//")&&!this.peekStartsWith("/(");)this.capture("/"),Ie.push(this.parseSegment());let Ce={};this.peekStartsWith("/(")&&(this.capture("/"),Ce=this.parseParens(!0));let ot={};return this.peekStartsWith("(")&&(ot=this.parseParens(!1)),(Ie.length>0||Object.keys(Ce).length>0)&&(ot[Lr]=new Jt(Ie,Ce)),ot}parseSegment(){const Ie=Gi(this.remaining);if(""===Ie&&this.peekStartsWith(";"))throw new Error(`Empty path url segment cannot have parameters: '${this.remaining}'.`);return this.capture(Ie),new Vn(Fn(Ie),this.parseMatrixParams())}parseMatrixParams(){const Ie={};for(;this.consumeOptional(";");)this.parseParam(Ie);return Ie}parseParam(Ie){const Ce=Gi(this.remaining);if(!Ce)return;this.capture(Ce);let ot="";if(this.consumeOptional("=")){const Et=Gi(this.remaining);Et&&(ot=Et,this.capture(ot))}Ie[Fn(Ce)]=Fn(ot)}parseQueryParam(Ie){const Ce=function(Ye){const Ie=Ye.match(os);return Ie?Ie[0]:""}(this.remaining);if(!Ce)return;this.capture(Ce);let ot="";if(this.consumeOptional("=")){const Hn=function(Ye){const Ie=Ye.match(To);return Ie?Ie[0]:""}(this.remaining);Hn&&(ot=Hn,this.capture(ot))}const Et=ar(Ce),qt=ar(ot);if(Ie.hasOwnProperty(Et)){let Hn=Ie[Et];Array.isArray(Hn)||(Hn=[Hn],Ie[Et]=Hn),Hn.push(qt)}else Ie[Et]=qt}parseParens(Ie){const Ce={};for(this.capture("(");!this.consumeOptional(")")&&this.remaining.length>0;){const ot=Gi(this.remaining),Et=this.remaining[ot.length];if("/"!==Et&&")"!==Et&&";"!==Et)throw new Error(`Cannot parse url '${this.url}'`);let qt;ot.indexOf(":")>-1?(qt=ot.substr(0,ot.indexOf(":")),this.capture(qt),this.capture(":")):Ie&&(qt=Lr);const Hn=this.parseChildren();Ce[qt]=1===Object.keys(Hn).length?Hn[Lr]:new Jt([],Hn),this.consumeOptional("//")}return Ce}peekStartsWith(Ie){return this.remaining.startsWith(Ie)}consumeOptional(Ie){return!!this.peekStartsWith(Ie)&&(this.remaining=this.remaining.substring(Ie.length),!0)}capture(Ie){if(!this.consumeOptional(Ie))throw new Error(`Expected "${Ie}".`)}}class Bn{constructor(Ie){this._root=Ie}get root(){return this._root.value}parent(Ie){const Ce=this.pathFromRoot(Ie);return Ce.length>1?Ce[Ce.length-2]:null}children(Ie){const Ce=lr(Ie,this._root);return Ce?Ce.children.map(ot=>ot.value):[]}firstChild(Ie){const Ce=lr(Ie,this._root);return Ce&&Ce.children.length>0?Ce.children[0].value:null}siblings(Ie){const Ce=vr(Ie,this._root);return Ce.length<2?[]:Ce[Ce.length-2].children.map(Et=>Et.value).filter(Et=>Et!==Ie)}pathFromRoot(Ie){return vr(Ie,this._root).map(Ce=>Ce.value)}}function lr(Ye,Ie){if(Ye===Ie.value)return Ie;for(const Ce of Ie.children){const ot=lr(Ye,Ce);if(ot)return ot}return null}function vr(Ye,Ie){if(Ye===Ie.value)return[Ie];for(const Ce of Ie.children){const ot=vr(Ye,Ce);if(ot.length)return ot.unshift(Ie),ot}return[]}class er{constructor(Ie,Ce){this.value=Ie,this.children=Ce}toString(){return`TreeNode(${this.value})`}}function ri(Ye){const Ie={};return Ye&&Ye.children.forEach(Ce=>Ie[Ce.value.outlet]=Ce),Ie}class uo extends Bn{constructor(Ie,Ce){super(Ie),this.snapshot=Ce,jt(this,Ie)}toString(){return this.snapshot.toString()}}function Ci(Ye,Ie){const Ce=function(Ye,Ie){const Hn=new _t([],{},{},"",{},Lr,Ie,null,Ye.root,-1,{});return new mt("",new er(Hn,[]))}(Ye,Ie),ot=new S.X([new Vn("",{})]),Et=new S.X({}),qt=new S.X({}),Hn=new S.X({}),Xn=new S.X(""),Ei=new tr(ot,Et,Hn,Xn,qt,Lr,Ie,Ce.root);return Ei.snapshot=Ce.root,new uo(new er(Ei,[]),Ce)}class tr{constructor(Ie,Ce,ot,Et,qt,Hn,Xn,Ei){this.url=Ie,this.params=Ce,this.queryParams=ot,this.fragment=Et,this.data=qt,this.outlet=Hn,this.component=Xn,this._futureSnapshot=Ei}get routeConfig(){return this._futureSnapshot.routeConfig}get root(){return this._routerState.root}get parent(){return this._routerState.parent(this)}get firstChild(){return this._routerState.firstChild(this)}get children(){return this._routerState.children(this)}get pathFromRoot(){return this._routerState.pathFromRoot(this)}get paramMap(){return this._paramMap||(this._paramMap=this.params.pipe((0,K.U)(Ie=>Kr(Ie)))),this._paramMap}get queryParamMap(){return this._queryParamMap||(this._queryParamMap=this.queryParams.pipe((0,K.U)(Ie=>Kr(Ie)))),this._queryParamMap}toString(){return this.snapshot?this.snapshot.toString():`Future(${this._futureSnapshot})`}}function Ar(Ye,Ie="emptyOnly"){const Ce=Ye.pathFromRoot;let ot=0;if("always"!==Ie)for(ot=Ce.length-1;ot>=1;){const Et=Ce[ot],qt=Ce[ot-1];if(Et.routeConfig&&""===Et.routeConfig.path)ot--;else{if(qt.component)break;ot--}}return function(Ye){return Ye.reduce((Ie,Ce)=>({params:Object.assign(Object.assign({},Ie.params),Ce.params),data:Object.assign(Object.assign({},Ie.data),Ce.data),resolve:Object.assign(Object.assign({},Ie.resolve),Ce._resolvedData)}),{params:{},data:{},resolve:{}})}(Ce.slice(ot))}class _t{constructor(Ie,Ce,ot,Et,qt,Hn,Xn,Ei,Yo,$a,ns){this.url=Ie,this.params=Ce,this.queryParams=ot,this.fragment=Et,this.data=qt,this.outlet=Hn,this.component=Xn,this.routeConfig=Ei,this._urlSegment=Yo,this._lastPathIndex=$a,this._resolve=ns}get root(){return this._routerState.root}get parent(){return this._routerState.parent(this)}get firstChild(){return this._routerState.firstChild(this)}get children(){return this._routerState.children(this)}get pathFromRoot(){return this._routerState.pathFromRoot(this)}get paramMap(){return this._paramMap||(this._paramMap=Kr(this.params)),this._paramMap}get queryParamMap(){return this._queryParamMap||(this._queryParamMap=Kr(this.queryParams)),this._queryParamMap}toString(){return`Route(url:'${this.url.map(ot=>ot.toString()).join("/")}', path:'${this.routeConfig?this.routeConfig.path:""}')`}}class mt extends Bn{constructor(Ie,Ce){super(Ce),this.url=Ie,jt(this,Ce)}toString(){return on(this._root)}}function jt(Ye,Ie){Ie.value._routerState=Ye,Ie.children.forEach(Ce=>jt(Ye,Ce))}function on(Ye){const Ie=Ye.children.length>0?` { ${Ye.children.map(on).join(", ")} } `:"";return`${Ye.value}${Ie}`}function si(Ye){if(Ye.snapshot){const Ie=Ye.snapshot,Ce=Ye._futureSnapshot;Ye.snapshot=Ce,fi(Ie.queryParams,Ce.queryParams)||Ye.queryParams.next(Ce.queryParams),Ie.fragment!==Ce.fragment&&Ye.fragment.next(Ce.fragment),fi(Ie.params,Ce.params)||Ye.params.next(Ce.params),function(Ye,Ie){if(Ye.length!==Ie.length)return!1;for(let Ce=0;Ce<Ye.length;++Ce)if(!fi(Ye[Ce],Ie[Ce]))return!1;return!0}(Ie.url,Ce.url)||Ye.url.next(Ce.url),fi(Ie.data,Ce.data)||Ye.data.next(Ce.data)}else Ye.snapshot=Ye._futureSnapshot,Ye.data.next(Ye._futureSnapshot.data)}function Vi(Ye,Ie){return fi(Ye.params,Ie.params)&&function(Ye,Ie){return Dn(Ye,Ie)&&Ye.every((Ce,ot)=>fi(Ce.parameters,Ie[ot].parameters))}(Ye.url,Ie.url)&&!(!Ye.parent!=!Ie.parent)&&(!Ye.parent||Vi(Ye.parent,Ie.parent))}function co(Ye,Ie,Ce){if(Ce&&Ye.shouldReuseRoute(Ie.value,Ce.value.snapshot)){const ot=Ce.value;ot._futureSnapshot=Ie.value;const Et=function(Ye,Ie,Ce){return Ie.children.map(ot=>{for(const Et of Ce.children)if(Ye.shouldReuseRoute(ot.value,Et.value.snapshot))return co(Ye,ot,Et);return co(Ye,ot)})}(Ye,Ie,Ce);return new er(ot,Et)}{if(Ye.shouldAttach(Ie.value)){const qt=Ye.retrieve(Ie.value);if(null!==qt){const Hn=qt.route;return Es(Ie,Hn),Hn}}const ot=function(Ye){return new tr(new S.X(Ye.url),new S.X(Ye.params),new S.X(Ye.queryParams),new S.X(Ye.fragment),new S.X(Ye.data),Ye.outlet,Ye.component,Ye)}(Ie.value),Et=Ie.children.map(qt=>co(Ye,qt));return new er(ot,Et)}}function Es(Ye,Ie){if(Ye.value.routeConfig!==Ie.value.routeConfig)throw new Error("Cannot reattach ActivatedRouteSnapshot created from a different route");if(Ye.children.length!==Ie.children.length)throw new Error("Cannot reattach ActivatedRouteSnapshot with a different number of children");Ie.value._futureSnapshot=Ye.value;for(let Ce=0;Ce<Ye.children.length;++Ce)Es(Ye.children[Ce],Ie.children[Ce])}function ta(Ye){return"object"==typeof Ye&&null!=Ye&&!Ye.outlets&&!Ye.segmentPath}function Is(Ye){return"object"==typeof Ye&&null!=Ye&&Ye.outlets}function us(Ye,Ie,Ce,ot,Et){let qt={};return ot&&Wt(ot,(Hn,Xn)=>{qt[Xn]=Array.isArray(Hn)?Hn.map(Ei=>`${Ei}`):`${Hn}`}),new gr(Ce.root===Ye?Ie:ya(Ce.root,Ye,Ie),qt,Et)}function ya(Ye,Ie,Ce){const ot={};return Wt(Ye.children,(Et,qt)=>{ot[qt]=Et===Ie?Ce:ya(Et,Ie,Ce)}),new Jt(Ye.segments,ot)}class el{constructor(Ie,Ce,ot){if(this.isAbsolute=Ie,this.numberOfDoubleDots=Ce,this.commands=ot,Ie&&ot.length>0&&ta(ot[0]))throw new Error("Root segment cannot have matrix parameters");const Et=ot.find(Is);if(Et&&Et!==Zr(ot))throw new Error("{outlets:{}} has to be the last command")}toRoot(){return this.isAbsolute&&1===this.commands.length&&"/"==this.commands[0]}}class $s{constructor(Ie,Ce,ot){this.segmentGroup=Ie,this.processChildren=Ce,this.index=ot}}function Ya(Ye,Ie,Ce){if(Ye||(Ye=new Jt([],{})),0===Ye.segments.length&&Ye.hasChildren())return Ao(Ye,Ie,Ce);const ot=function(Ye,Ie,Ce){let ot=0,Et=Ie;const qt={match:!1,pathIndex:0,commandIndex:0};for(;Et<Ye.segments.length;){if(ot>=Ce.length)return qt;const Hn=Ye.segments[Et],Xn=Ce[ot];if(Is(Xn))break;const Ei=`${Xn}`,Yo=ot<Ce.length-1?Ce[ot+1]:null;if(Et>0&&void 0===Ei)break;if(Ei&&Yo&&"object"==typeof Yo&&void 0===Yo.outlets){if(!Ws(Ei,Yo,Hn))return qt;ot+=2}else{if(!Ws(Ei,{},Hn))return qt;ot++}Et++}return{match:!0,pathIndex:Et,commandIndex:ot}}(Ye,Ie,Ce),Et=Ce.slice(ot.commandIndex);if(ot.match&&ot.pathIndex<Ye.segments.length){const qt=new Jt(Ye.segments.slice(0,ot.pathIndex),{});return qt.children[Lr]=new Jt(Ye.segments.slice(ot.pathIndex),Ye.children),Ao(qt,0,Et)}return ot.match&&0===Et.length?new Jt(Ye.segments,{}):ot.match&&!Ye.hasChildren()?Ca(Ye,Ie,Ce):ot.match?Ao(Ye,0,Et):Ca(Ye,Ie,Ce)}function Ao(Ye,Ie,Ce){if(0===Ce.length)return new Jt(Ye.segments,{});{const ot=function(Ye){return Is(Ye[0])?Ye[0].outlets:{[Lr]:Ye}}(Ce),Et={};return Wt(ot,(qt,Hn)=>{"string"==typeof qt&&(qt=[qt]),null!==qt&&(Et[Hn]=Ya(Ye.children[Hn],Ie,qt))}),Wt(Ye.children,(qt,Hn)=>{void 0===ot[Hn]&&(Et[Hn]=qt)}),new Jt(Ye.segments,Et)}}function Ca(Ye,Ie,Ce){const ot=Ye.segments.slice(0,Ie);let Et=0;for(;Et<Ce.length;){const qt=Ce[Et];if(Is(qt)){const Ei=Ra(qt.outlets);return new Jt(ot,Ei)}if(0===Et&&ta(Ce[0])){ot.push(new Vn(Ye.segments[Ie].path,pl(Ce[0]))),Et++;continue}const Hn=Is(qt)?qt.outlets[Lr]:`${qt}`,Xn=Et<Ce.length-1?Ce[Et+1]:null;Hn&&Xn&&ta(Xn)?(ot.push(new Vn(Hn,pl(Xn))),Et+=2):(ot.push(new Vn(Hn,{})),Et++)}return new Jt(ot,{})}function Ra(Ye){const Ie={};return Wt(Ye,(Ce,ot)=>{"string"==typeof Ce&&(Ce=[Ce]),null!==Ce&&(Ie[ot]=Ca(new Jt([],{}),0,Ce))}),Ie}function pl(Ye){const Ie={};return Wt(Ye,(Ce,ot)=>Ie[ot]=`${Ce}`),Ie}function Ws(Ye,Ie,Ce){return Ye==Ce.path&&fi(Ie,Ce.parameters)}class bo{constructor(Ie,Ce,ot,Et){this.routeReuseStrategy=Ie,this.futureState=Ce,this.currState=ot,this.forwardEvent=Et}activate(Ie){const Ce=this.futureState._root,ot=this.currState?this.currState._root:null;this.deactivateChildRoutes(Ce,ot,Ie),si(this.futureState.root),this.activateChildRoutes(Ce,ot,Ie)}deactivateChildRoutes(Ie,Ce,ot){const Et=ri(Ce);Ie.children.forEach(qt=>{const Hn=qt.value.outlet;this.deactivateRoutes(qt,Et[Hn],ot),delete Et[Hn]}),Wt(Et,(qt,Hn)=>{this.deactivateRouteAndItsChildren(qt,ot)})}deactivateRoutes(Ie,Ce,ot){const Et=Ie.value,qt=Ce?Ce.value:null;if(Et===qt)if(Et.component){const Hn=ot.getContext(Et.outlet);Hn&&this.deactivateChildRoutes(Ie,Ce,Hn.children)}else this.deactivateChildRoutes(Ie,Ce,ot);else qt&&this.deactivateRouteAndItsChildren(Ce,ot)}deactivateRouteAndItsChildren(Ie,Ce){this.routeReuseStrategy.shouldDetach(Ie.value.snapshot)?this.detachAndStoreRouteSubtree(Ie,Ce):this.deactivateRouteAndOutlet(Ie,Ce)}detachAndStoreRouteSubtree(Ie,Ce){const ot=Ce.getContext(Ie.value.outlet);if(ot&&ot.outlet){const Et=ot.outlet.detach(),qt=ot.children.onOutletDeactivated();this.routeReuseStrategy.store(Ie.value.snapshot,{componentRef:Et,route:Ie,contexts:qt})}}deactivateRouteAndOutlet(Ie,Ce){const ot=Ce.getContext(Ie.value.outlet),Et=ot&&Ie.value.component?ot.children:Ce,qt=ri(Ie);for(const Hn of Object.keys(qt))this.deactivateRouteAndItsChildren(qt[Hn],Et);ot&&ot.outlet&&(ot.outlet.deactivate(),ot.children.onOutletDeactivated(),ot.attachRef=null,ot.resolver=null,ot.route=null)}activateChildRoutes(Ie,Ce,ot){const Et=ri(Ce);Ie.children.forEach(qt=>{this.activateRoutes(qt,Et[qt.value.outlet],ot),this.forwardEvent(new Ur(qt.value.snapshot))}),Ie.children.length&&this.forwardEvent(new Xt(Ie.value.snapshot))}activateRoutes(Ie,Ce,ot){const Et=Ie.value,qt=Ce?Ce.value:null;if(si(Et),Et===qt)if(Et.component){const Hn=ot.getOrCreateContext(Et.outlet);this.activateChildRoutes(Ie,Ce,Hn.children)}else this.activateChildRoutes(Ie,Ce,ot);else if(Et.component){const Hn=ot.getOrCreateContext(Et.outlet);if(this.routeReuseStrategy.shouldAttach(Et.snapshot)){const Xn=this.routeReuseStrategy.retrieve(Et.snapshot);this.routeReuseStrategy.store(Et.snapshot,null),Hn.children.onOutletReAttached(Xn.contexts),Hn.attachRef=Xn.componentRef,Hn.route=Xn.route.value,Hn.outlet&&Hn.outlet.attach(Xn.componentRef,Xn.route.value),Ls(Xn.route)}else{const Xn=function(Ye){for(let Ie=Ye.parent;Ie;Ie=Ie.parent){const Ce=Ie.routeConfig;if(Ce&&Ce._loadedConfig)return Ce._loadedConfig;if(Ce&&Ce.component)return null}return null}(Et.snapshot),Ei=Xn?Xn.module.componentFactoryResolver:null;Hn.attachRef=null,Hn.route=Et,Hn.resolver=Ei,Hn.outlet&&Hn.outlet.activateWith(Et,Ei),this.activateChildRoutes(Ie,null,Hn.children)}}else this.activateChildRoutes(Ie,null,ot)}}function Ls(Ye){si(Ye.value),Ye.children.forEach(Ls)}class So{constructor(Ie,Ce){this.routes=Ie,this.module=Ce}}function $r(Ye){return"function"==typeof Ye}function tt(Ye){return Ye instanceof gr}const an=Symbol("INITIAL_VALUE");function ti(){return(0,ee.w)(Ye=>(0,A.aj)(Ye.map(Ie=>Ie.pipe((0,ue.q)(1),(0,ae.O)(an)))).pipe((0,H.R)((Ie,Ce)=>{let ot=!1;return Ce.reduce((Et,qt,Hn)=>Et!==an?Et:(qt===an&&(ot=!0),ot||!1!==qt&&Hn!==Ce.length-1&&!tt(qt)?Et:qt),Ie)},an),(0,se.h)(Ie=>Ie!==an),(0,K.U)(Ie=>tt(Ie)?Ie:!0===Ie),(0,ue.q)(1)))}let pi=(()=>{class Ye{}return Ye.\u0275fac=function(Ce){return new(Ce||Ye)},Ye.\u0275cmp=u.Xpm({type:Ye,selectors:[["ng-component"]],decls:1,vars:0,template:function(Ce,ot){1&Ce&&u._UZ(0,"router-outlet")},directives:function(){return[ao]},encapsulation:2}),Ye})();function xi(Ye,Ie=""){for(let Ce=0;Ce<Ye.length;Ce++){const ot=Ye[Ce];ts(ot,wo(Ie,ot))}}function ts(Ye,Ie){Ye.children&&xi(Ye.children,Ie)}function wo(Ye,Ie){return Ie?Ye||Ie.path?Ye&&!Ie.path?`${Ye}/`:!Ye&&Ie.path?Ie.path:`${Ye}/${Ie.path}`:"":Ye}function ko(Ye){const Ie=Ye.children&&Ye.children.map(ko),Ce=Ie?Object.assign(Object.assign({},Ye),{children:Ie}):Object.assign({},Ye);return!Ce.component&&(Ie||Ce.loadChildren)&&Ce.outlet&&Ce.outlet!==Lr&&(Ce.component=pi),Ce}function Eo(Ye){return Ye.outlet||Lr}function ba(Ye,Ie){const Ce=Ye.filter(ot=>Eo(ot)===Ie);return Ce.push(...Ye.filter(ot=>Eo(ot)!==Ie)),Ce}const sl={matched:!1,consumedSegments:[],lastChild:0,parameters:{},positionalParamSegments:{}};function tc(Ye,Ie,Ce){var ot;if(""===Ie.path)return"full"===Ie.pathMatch&&(Ye.hasChildren()||Ce.length>0)?Object.assign({},sl):{matched:!0,consumedSegments:[],lastChild:0,parameters:{},positionalParamSegments:{}};const qt=(Ie.matcher||Br)(Ce,Ye,Ie);if(!qt)return Object.assign({},sl);const Hn={};Wt(qt.posParams,(Ei,Yo)=>{Hn[Yo]=Ei.path});const Xn=qt.consumed.length>0?Object.assign(Object.assign({},Hn),qt.consumed[qt.consumed.length-1].parameters):Hn;return{matched:!0,consumedSegments:qt.consumed,lastChild:qt.consumed.length,parameters:Xn,positionalParamSegments:null!==(ot=qt.posParams)&&void 0!==ot?ot:{}}}function Nu(Ye,Ie,Ce,ot,Et="corrected"){if(Ce.length>0&&function(Ye,Ie,Ce){return Ce.some(ot=>Yl(Ye,Ie,ot)&&Eo(ot)!==Lr)}(Ye,Ce,ot)){const Hn=new Jt(Ie,function(Ye,Ie,Ce,ot){const Et={};Et[Lr]=ot,ot._sourceSegment=Ye,ot._segmentIndexShift=Ie.length;for(const qt of Ce)if(""===qt.path&&Eo(qt)!==Lr){const Hn=new Jt([],{});Hn._sourceSegment=Ye,Hn._segmentIndexShift=Ie.length,Et[Eo(qt)]=Hn}return Et}(Ye,Ie,ot,new Jt(Ce,Ye.children)));return Hn._sourceSegment=Ye,Hn._segmentIndexShift=Ie.length,{segmentGroup:Hn,slicedSegments:[]}}if(0===Ce.length&&function(Ye,Ie,Ce){return Ce.some(ot=>Yl(Ye,Ie,ot))}(Ye,Ce,ot)){const Hn=new Jt(Ye.segments,function(Ye,Ie,Ce,ot,Et,qt){const Hn={};for(const Xn of ot)if(Yl(Ye,Ce,Xn)&&!Et[Eo(Xn)]){const Ei=new Jt([],{});Ei._sourceSegment=Ye,Ei._segmentIndexShift="legacy"===qt?Ye.segments.length:Ie.length,Hn[Eo(Xn)]=Ei}return Object.assign(Object.assign({},Et),Hn)}(Ye,Ie,Ce,ot,Ye.children,Et));return Hn._sourceSegment=Ye,Hn._segmentIndexShift=Ie.length,{segmentGroup:Hn,slicedSegments:Ce}}const qt=new Jt(Ye.segments,Ye.children);return qt._sourceSegment=Ye,qt._segmentIndexShift=Ie.length,{segmentGroup:qt,slicedSegments:Ce}}function Yl(Ye,Ie,Ce){return(!(Ye.hasChildren()||Ie.length>0)||"full"!==Ce.pathMatch)&&""===Ce.path}function Fs(Ye,Ie,Ce,ot){return!!(Eo(Ye)===ot||ot!==Lr&&Yl(Ie,Ce,Ye))&&("**"===Ye.path||tc(Ie,Ye,Ce).matched)}function dc(Ye,Ie,Ce){return 0===Ie.length&&!Ye.children[Ce]}class iu{constructor(Ie){this.segmentGroup=Ie||null}}class tl{constructor(Ie){this.urlTree=Ie}}function Su(Ye){return new p.y(Ie=>Ie.error(new iu(Ye)))}function Zl(Ye){return new p.y(Ie=>Ie.error(new tl(Ye)))}function rt(Ye){return new p.y(Ie=>Ie.error(new Error(`Only absolute redirects can have named outlets. redirectTo: '${Ye}'`)))}class Te{constructor(Ie,Ce,ot,Et,qt){this.configLoader=Ce,this.urlSerializer=ot,this.urlTree=Et,this.config=qt,this.allowRedirects=!0,this.ngModule=Ie.get(u.h0i)}apply(){const Ie=Nu(this.urlTree.root,[],[],this.config).segmentGroup,Ce=new Jt(Ie.segments,Ie.children);return this.expandSegmentGroup(this.ngModule,this.config,Ce,Lr).pipe((0,K.U)(qt=>this.createUrlTree(xe(qt),this.urlTree.queryParams,this.urlTree.fragment))).pipe((0,Ee.K)(qt=>{if(qt instanceof tl)return this.allowRedirects=!1,this.match(qt.urlTree);throw qt instanceof iu?this.noMatchError(qt):qt}))}match(Ie){return this.expandSegmentGroup(this.ngModule,this.config,Ie.root,Lr).pipe((0,K.U)(Et=>this.createUrlTree(xe(Et),Ie.queryParams,Ie.fragment))).pipe((0,Ee.K)(Et=>{throw Et instanceof iu?this.noMatchError(Et):Et}))}noMatchError(Ie){return new Error(`Cannot match any routes. URL Segment: '${Ie.segmentGroup}'`)}createUrlTree(Ie,Ce,ot){const Et=Ie.segments.length>0?new Jt([],{[Lr]:Ie}):Ie;return new gr(Et,Ce,ot)}expandSegmentGroup(Ie,Ce,ot,Et){return 0===ot.segments.length&&ot.hasChildren()?this.expandChildren(Ie,Ce,ot).pipe((0,K.U)(qt=>new Jt([],qt))):this.expandSegment(Ie,ot,Ce,ot.segments,Et,!0)}expandChildren(Ie,Ce,ot){const Et=[];for(const qt of Object.keys(ot.children))"primary"===qt?Et.unshift(qt):Et.push(qt);return(0,d.D)(Et).pipe((0,ie.b)(qt=>{const Hn=ot.children[qt],Xn=ba(Ce,qt);return this.expandSegmentGroup(Ie,Xn,Hn,qt).pipe((0,K.U)(Ei=>({segment:Ei,outlet:qt})))}),(0,H.R)((qt,Hn)=>(qt[Hn.outlet]=Hn.segment,qt),{}),(0,he.Z)())}expandSegment(Ie,Ce,ot,Et,qt,Hn){return(0,d.D)(ot).pipe((0,ie.b)(Xn=>this.expandSegmentAgainstRoute(Ie,Ce,ot,Xn,Et,qt,Hn).pipe((0,Ee.K)(Yo=>{if(Yo instanceof iu)return(0,y.of)(null);throw Yo}))),(0,ge.P)(Xn=>!!Xn),(0,Ee.K)((Xn,Ei)=>{if(Xn instanceof N.K||"EmptyError"===Xn.name){if(dc(Ce,Et,qt))return(0,y.of)(new Jt([],{}));throw new iu(Ce)}throw Xn}))}expandSegmentAgainstRoute(Ie,Ce,ot,Et,qt,Hn,Xn){return Fs(Et,Ce,qt,Hn)?void 0===Et.redirectTo?this.matchSegmentAgainstRoute(Ie,Ce,Et,qt,Hn):Xn&&this.allowRedirects?this.expandSegmentAgainstRouteUsingRedirect(Ie,Ce,ot,Et,qt,Hn):Su(Ce):Su(Ce)}expandSegmentAgainstRouteUsingRedirect(Ie,Ce,ot,Et,qt,Hn){return"**"===Et.path?this.expandWildCardWithParamsAgainstRouteUsingRedirect(Ie,ot,Et,Hn):this.expandRegularSegmentAgainstRouteUsingRedirect(Ie,Ce,ot,Et,qt,Hn)}expandWildCardWithParamsAgainstRouteUsingRedirect(Ie,Ce,ot,Et){const qt=this.applyRedirectCommands([],ot.redirectTo,{});return ot.redirectTo.startsWith("/")?Zl(qt):this.lineralizeSegments(ot,qt).pipe((0,De.zg)(Hn=>{const Xn=new Jt(Hn,{});return this.expandSegment(Ie,Xn,Ce,Hn,Et,!1)}))}expandRegularSegmentAgainstRouteUsingRedirect(Ie,Ce,ot,Et,qt,Hn){const{matched:Xn,consumedSegments:Ei,lastChild:Yo,positionalParamSegments:$a}=tc(Ce,Et,qt);if(!Xn)return Su(Ce);const ns=this.applyRedirectCommands(Ei,Et.redirectTo,$a);return Et.redirectTo.startsWith("/")?Zl(ns):this.lineralizeSegments(Et,ns).pipe((0,De.zg)(Oa=>this.expandSegment(Ie,Ce,ot,Oa.concat(qt.slice(Yo)),Hn,!1)))}matchSegmentAgainstRoute(Ie,Ce,ot,Et,qt){if("**"===ot.path)return ot.loadChildren?(ot._loadedConfig?(0,y.of)(ot._loadedConfig):this.configLoader.load(Ie.injector,ot)).pipe((0,K.U)(Oa=>(ot._loadedConfig=Oa,new Jt(Et,{})))):(0,y.of)(new Jt(Et,{}));const{matched:Hn,consumedSegments:Xn,lastChild:Ei}=tc(Ce,ot,Et);if(!Hn)return Su(Ce);const Yo=Et.slice(Ei);return this.getChildConfig(Ie,ot,Et).pipe((0,De.zg)(ns=>{const Oa=ns.module,Hs=ns.routes,{segmentGroup:fc,slicedSegments:ga}=Nu(Ce,Xn,Yo,Hs),Ol=new Jt(fc.segments,fc.children);if(0===ga.length&&Ol.hasChildren())return this.expandChildren(Oa,Hs,Ol).pipe((0,K.U)(ul=>new Jt(Xn,ul)));if(0===Hs.length&&0===ga.length)return(0,y.of)(new Jt(Xn,{}));const ll=Eo(ot)===qt;return this.expandSegment(Oa,Ol,Hs,ga,ll?Lr:qt,!0).pipe((0,K.U)(ja=>new Jt(Xn.concat(ja.segments),ja.children)))}))}getChildConfig(Ie,Ce,ot){return Ce.children?(0,y.of)(new So(Ce.children,Ie)):Ce.loadChildren?void 0!==Ce._loadedConfig?(0,y.of)(Ce._loadedConfig):this.runCanLoadGuards(Ie.injector,Ce,ot).pipe((0,De.zg)(Et=>{return Et?this.configLoader.load(Ie.injector,Ce).pipe((0,K.U)(qt=>(Ce._loadedConfig=qt,qt))):(Ye=Ce,new p.y(Ie=>Ie.error(Nn(`Cannot load children because the guard of the route "path: '${Ye.path}'" returned false`))));var Ye})):(0,y.of)(new So([],Ie))}runCanLoadGuards(Ie,Ce,ot){const Et=Ce.canLoad;if(!Et||0===Et.length)return(0,y.of)(!0);const qt=Et.map(Hn=>{const Xn=Ie.get(Hn);let Ei;if((Ye=Xn)&&$r(Ye.canLoad))Ei=Xn.canLoad(Ce,ot);else{if(!$r(Xn))throw new Error("Invalid CanLoad guard");Ei=Xn(Ce,ot)}var Ye;return zn(Ei)});return(0,y.of)(qt).pipe(ti(),(0,ce.b)(Hn=>{if(!tt(Hn))return;const Xn=Nn(`Redirecting to "${this.urlSerializer.serialize(Hn)}"`);throw Xn.url=Hn,Xn}),(0,K.U)(Hn=>!0===Hn))}lineralizeSegments(Ie,Ce){let ot=[],Et=Ce.root;for(;;){if(ot=ot.concat(Et.segments),0===Et.numberOfChildren)return(0,y.of)(ot);if(Et.numberOfChildren>1||!Et.children[Lr])return rt(Ie.redirectTo);Et=Et.children[Lr]}}applyRedirectCommands(Ie,Ce,ot){return this.applyRedirectCreatreUrlTree(Ce,this.urlSerializer.parse(Ce),Ie,ot)}applyRedirectCreatreUrlTree(Ie,Ce,ot,Et){const qt=this.createSegmentGroup(Ie,Ce.root,ot,Et);return new gr(qt,this.createQueryParams(Ce.queryParams,this.urlTree.queryParams),Ce.fragment)}createQueryParams(Ie,Ce){const ot={};return Wt(Ie,(Et,qt)=>{if("string"==typeof Et&&Et.startsWith(":")){const Xn=Et.substring(1);ot[qt]=Ce[Xn]}else ot[qt]=Et}),ot}createSegmentGroup(Ie,Ce,ot,Et){const qt=this.createSegments(Ie,Ce.segments,ot,Et);let Hn={};return Wt(Ce.children,(Xn,Ei)=>{Hn[Ei]=this.createSegmentGroup(Ie,Xn,ot,Et)}),new Jt(qt,Hn)}createSegments(Ie,Ce,ot,Et){return Ce.map(qt=>qt.path.startsWith(":")?this.findPosParam(Ie,qt,Et):this.findOrReturn(qt,ot))}findPosParam(Ie,Ce,ot){const Et=ot[Ce.path.substring(1)];if(!Et)throw new Error(`Cannot redirect to '${Ie}'. Cannot find '${Ce.path}'.`);return Et}findOrReturn(Ie,Ce){let ot=0;for(const Et of Ce){if(Et.path===Ie.path)return Ce.splice(ot),Et;ot++}return Ie}}function xe(Ye){const Ie={};for(const ot of Object.keys(Ye.children)){const qt=xe(Ye.children[ot]);(qt.segments.length>0||qt.hasChildren())&&(Ie[ot]=qt)}return function(Ye){if(1===Ye.numberOfChildren&&Ye.children[Lr]){const Ie=Ye.children[Lr];return new Jt(Ye.segments.concat(Ie.segments),Ie.children)}return Ye}(new Jt(Ye.segments,Ie))}class ur{constructor(Ie){this.path=Ie,this.route=this.path[this.path.length-1]}}class Qi{constructor(Ie,Ce){this.component=Ie,this.route=Ce}}function Go(Ye,Ie,Ce){const ot=Ye._root;return Ma(ot,Ie?Ie._root:null,Ce,[ot.value])}function hs(Ye,Ie,Ce){const ot=function(Ye){if(!Ye)return null;for(let Ie=Ye.parent;Ie;Ie=Ie.parent){const Ce=Ie.routeConfig;if(Ce&&Ce._loadedConfig)return Ce._loadedConfig}return null}(Ie);return(ot?ot.module.injector:Ce).get(Ye)}function Ma(Ye,Ie,Ce,ot,Et={canDeactivateChecks:[],canActivateChecks:[]}){const qt=ri(Ie);return Ye.children.forEach(Hn=>{(function(Ye,Ie,Ce,ot,Et={canDeactivateChecks:[],canActivateChecks:[]}){const qt=Ye.value,Hn=Ie?Ie.value:null,Xn=Ce?Ce.getContext(Ye.value.outlet):null;if(Hn&&qt.routeConfig===Hn.routeConfig){const Ei=function(Ye,Ie,Ce){if("function"==typeof Ce)return Ce(Ye,Ie);switch(Ce){case"pathParamsChange":return!Dn(Ye.url,Ie.url);case"pathParamsOrQueryParamsChange":return!Dn(Ye.url,Ie.url)||!fi(Ye.queryParams,Ie.queryParams);case"always":return!0;case"paramsOrQueryParamsChange":return!Vi(Ye,Ie)||!fi(Ye.queryParams,Ie.queryParams);case"paramsChange":default:return!Vi(Ye,Ie)}}(Hn,qt,qt.routeConfig.runGuardsAndResolvers);Ei?Et.canActivateChecks.push(new ur(ot)):(qt.data=Hn.data,qt._resolvedData=Hn._resolvedData),Ma(Ye,Ie,qt.component?Xn?Xn.children:null:Ce,ot,Et),Ei&&Xn&&Xn.outlet&&Xn.outlet.isActivated&&Et.canDeactivateChecks.push(new Qi(Xn.outlet.component,Hn))}else Hn&&Rl(Ie,Xn,Et),Et.canActivateChecks.push(new ur(ot)),Ma(Ye,null,qt.component?Xn?Xn.children:null:Ce,ot,Et)})(Hn,qt[Hn.value.outlet],Ce,ot.concat([Hn.value]),Et),delete qt[Hn.value.outlet]}),Wt(qt,(Hn,Xn)=>Rl(Hn,Ce.getContext(Xn),Et)),Et}function Rl(Ye,Ie,Ce){const ot=ri(Ye),Et=Ye.value;Wt(ot,(qt,Hn)=>{Rl(qt,Et.component?Ie?Ie.children.getContext(Hn):null:Ie,Ce)}),Ce.canDeactivateChecks.push(new Qi(Et.component&&Ie&&Ie.outlet&&Ie.outlet.isActivated?Ie.outlet.component:null,Et))}class gd{}function rc(Ye){return new p.y(Ie=>Ie.error(Ye))}class sa{constructor(Ie,Ce,ot,Et,qt,Hn){this.rootComponentType=Ie,this.config=Ce,this.urlTree=ot,this.url=Et,this.paramsInheritanceStrategy=qt,this.relativeLinkResolution=Hn}recognize(){const Ie=Nu(this.urlTree.root,[],[],this.config.filter(Hn=>void 0===Hn.redirectTo),this.relativeLinkResolution).segmentGroup,Ce=this.processSegmentGroup(this.config,Ie,Lr);if(null===Ce)return null;const ot=new _t([],Object.freeze({}),Object.freeze(Object.assign({},this.urlTree.queryParams)),this.urlTree.fragment,{},Lr,this.rootComponentType,null,this.urlTree.root,-1,{}),Et=new er(ot,Ce),qt=new mt(this.url,Et);return this.inheritParamsAndData(qt._root),qt}inheritParamsAndData(Ie){const Ce=Ie.value,ot=Ar(Ce,this.paramsInheritanceStrategy);Ce.params=Object.freeze(ot.params),Ce.data=Object.freeze(ot.data),Ie.children.forEach(Et=>this.inheritParamsAndData(Et))}processSegmentGroup(Ie,Ce,ot){return 0===Ce.segments.length&&Ce.hasChildren()?this.processChildren(Ie,Ce):this.processSegment(Ie,Ce,Ce.segments,ot)}processChildren(Ie,Ce){const ot=[];for(const qt of Object.keys(Ce.children)){const Hn=Ce.children[qt],Xn=ba(Ie,qt),Ei=this.processSegmentGroup(Xn,Hn,qt);if(null===Ei)return null;ot.push(...Ei)}const Et=yl(ot);return Et.sort((Ie,Ce)=>Ie.value.outlet===Lr?-1:Ce.value.outlet===Lr?1:Ie.value.outlet.localeCompare(Ce.value.outlet)),Et}processSegment(Ie,Ce,ot,Et){for(const qt of Ie){const Hn=this.processSegmentAgainstRoute(qt,Ce,ot,Et);if(null!==Hn)return Hn}return dc(Ce,ot,Et)?[]:null}processSegmentAgainstRoute(Ie,Ce,ot,Et){if(Ie.redirectTo||!Fs(Ie,Ce,ot,Et))return null;let qt,Hn=[],Xn=[];if("**"===Ie.path){const Hs=ot.length>0?Zr(ot).parameters:{};qt=new _t(ot,Hs,Object.freeze(Object.assign({},this.urlTree.queryParams)),this.urlTree.fragment,js(Ie),Eo(Ie),Ie.component,Ie,yu(Ce),lu(Ce)+ot.length,Hu(Ie))}else{const Hs=tc(Ce,Ie,ot);if(!Hs.matched)return null;Hn=Hs.consumedSegments,Xn=ot.slice(Hs.lastChild),qt=new _t(Hn,Hs.parameters,Object.freeze(Object.assign({},this.urlTree.queryParams)),this.urlTree.fragment,js(Ie),Eo(Ie),Ie.component,Ie,yu(Ce),lu(Ce)+Hn.length,Hu(Ie))}const Ei=(Ye=Ie).children?Ye.children:Ye.loadChildren?Ye._loadedConfig.routes:[],{segmentGroup:Yo,slicedSegments:$a}=Nu(Ce,Hn,Xn,Ei.filter(Hs=>void 0===Hs.redirectTo),this.relativeLinkResolution);var Ye;if(0===$a.length&&Yo.hasChildren()){const Hs=this.processChildren(Ei,Yo);return null===Hs?null:[new er(qt,Hs)]}if(0===Ei.length&&0===$a.length)return[new er(qt,[])];const ns=Eo(Ie)===Et,Oa=this.processSegment(Ei,Yo,$a,ns?Lr:Et);return null===Oa?null:[new er(qt,Oa)]}}function $u(Ye){const Ie=Ye.value.routeConfig;return Ie&&""===Ie.path&&void 0===Ie.redirectTo}function yl(Ye){const Ie=[],Ce=new Set;for(const ot of Ye){if(!$u(ot)){Ie.push(ot);continue}const Et=Ie.find(qt=>ot.value.routeConfig===qt.value.routeConfig);void 0!==Et?(Et.children.push(...ot.children),Ce.add(Et)):Ie.push(ot)}for(const ot of Ce){const Et=yl(ot.children);Ie.push(new er(ot.value,Et))}return Ie.filter(ot=>!Ce.has(ot))}function yu(Ye){let Ie=Ye;for(;Ie._sourceSegment;)Ie=Ie._sourceSegment;return Ie}function lu(Ye){let Ie=Ye,Ce=Ie._segmentIndexShift?Ie._segmentIndexShift:0;for(;Ie._sourceSegment;)Ie=Ie._sourceSegment,Ce+=Ie._segmentIndexShift?Ie._segmentIndexShift:0;return Ce-1}function js(Ye){return Ye.data||{}}function Hu(Ye){return Ye.resolve||{}}function pu(Ye){return(0,ee.w)(Ie=>{const Ce=Ye(Ie);return Ce?(0,d.D)(Ce).pipe((0,K.U)(()=>Ie)):(0,y.of)(Ie)})}class bl extends class{shouldDetach(Ie){return!1}store(Ie,Ce){}shouldAttach(Ie){return!1}retrieve(Ie){return null}shouldReuseRoute(Ie,Ce){return Ie.routeConfig===Ce.routeConfig}}{}const El=new u.OlP("ROUTES");class Ul{constructor(Ie,Ce,ot,Et){this.loader=Ie,this.compiler=Ce,this.onLoadStartListener=ot,this.onLoadEndListener=Et}load(Ie,Ce){if(Ce._loader$)return Ce._loader$;this.onLoadStartListener&&this.onLoadStartListener(Ce);const Et=this.loadModuleFactory(Ce.loadChildren).pipe((0,K.U)(qt=>{this.onLoadEndListener&&this.onLoadEndListener(Ce);const Hn=qt.create(Ie);return new So(Hi(Hn.injector.get(El,void 0,u.XFs.Self|u.XFs.Optional)).map(ko),Hn)}),(0,Ee.K)(qt=>{throw Ce._loader$=void 0,qt}));return Ce._loader$=new Z.c(Et,()=>new J.xQ).pipe((0,Ve.x)()),Ce._loader$}loadModuleFactory(Ie){return"string"==typeof Ie?(0,d.D)(this.loader.load(Ie)):zn(Ie()).pipe((0,De.zg)(Ce=>Ce instanceof u.YKP?(0,y.of)(Ce):(0,d.D)(this.compiler.compileModuleAsync(Ce))))}}class ks{constructor(){this.outlet=null,this.route=null,this.resolver=null,this.children=new V,this.attachRef=null}}class V{constructor(){this.contexts=new Map}onChildOutletCreated(Ie,Ce){const ot=this.getOrCreateContext(Ie);ot.outlet=Ce,this.contexts.set(Ie,ot)}onChildOutletDestroyed(Ie){const Ce=this.getContext(Ie);Ce&&(Ce.outlet=null,Ce.attachRef=null)}onOutletDeactivated(){const Ie=this.contexts;return this.contexts=new Map,Ie}onOutletReAttached(Ie){this.contexts=Ie}getOrCreateContext(Ie){let Ce=this.getContext(Ie);return Ce||(Ce=new ks,this.contexts.set(Ie,Ce)),Ce}getContext(Ie){return this.contexts.get(Ie)||null}}class st{shouldProcessUrl(Ie){return!0}extract(Ie){return Ie}merge(Ie,Ce){return Ie}}function vt(Ye){throw Ye}function ut(Ye,Ie,Ce){return Ie.parse("/")}function un(Ye,Ie){return(0,y.of)(null)}const mn={paths:"exact",fragment:"ignored",matrixParams:"ignored",queryParams:"exact"},Or={paths:"subset",fragment:"ignored",matrixParams:"ignored",queryParams:"subset"};let zr=(()=>{class Ye{constructor(Ce,ot,Et,qt,Hn,Xn,Ei,Yo){this.rootComponentType=Ce,this.urlSerializer=ot,this.rootContexts=Et,this.location=qt,this.config=Yo,this.lastSuccessfulNavigation=null,this.currentNavigation=null,this.disposed=!1,this.lastLocationChangeInfo=null,this.navigationId=0,this.currentPageId=0,this.isNgZoneEnabled=!1,this.events=new J.xQ,this.errorHandler=vt,this.malformedUriErrorHandler=ut,this.navigated=!1,this.lastSuccessfulId=-1,this.hooks={beforePreactivation:un,afterPreactivation:un},this.urlHandlingStrategy=new st,this.routeReuseStrategy=new bl,this.onSameUrlNavigation="ignore",this.paramsInheritanceStrategy="emptyOnly",this.urlUpdateStrategy="deferred",this.relativeLinkResolution="corrected",this.canceledNavigationResolution="replace",this.ngModule=Hn.get(u.h0i),this.console=Hn.get(u.c2e);const Oa=Hn.get(u.R0b);this.isNgZoneEnabled=Oa instanceof u.R0b&&u.R0b.isInAngularZone(),this.resetConfig(Yo),this.currentUrlTree=new gr(new Jt([],{}),{},null),this.rawUrlTree=this.currentUrlTree,this.browserUrlTree=this.currentUrlTree,this.configLoader=new Ul(Xn,Ei,Hs=>this.triggerEvent(new bt(Hs)),Hs=>this.triggerEvent(new Gt(Hs))),this.routerState=Ci(this.currentUrlTree,this.rootComponentType),this.transitions=new S.X({id:0,targetPageId:0,currentUrlTree:this.currentUrlTree,currentRawUrl:this.currentUrlTree,extractedUrl:this.urlHandlingStrategy.extract(this.currentUrlTree),urlAfterRedirects:this.urlHandlingStrategy.extract(this.currentUrlTree),rawUrl:this.currentUrlTree,extras:{},resolve:null,reject:null,promise:Promise.resolve(!0),source:"imperative",restoredState:null,currentSnapshot:this.routerState.snapshot,targetSnapshot:null,currentRouterState:this.routerState,targetRouterState:null,guards:{canActivateChecks:[],canDeactivateChecks:[]},guardsResult:null}),this.navigations=this.setupNavigations(this.transitions),this.processNavigations()}get browserPageId(){var Ce;return null===(Ce=this.location.getState())||void 0===Ce?void 0:Ce.\u0275routerPageId}setupNavigations(Ce){const ot=this.events;return Ce.pipe((0,se.h)(Et=>0!==Et.id),(0,K.U)(Et=>Object.assign(Object.assign({},Et),{extractedUrl:this.urlHandlingStrategy.extract(Et.rawUrl)})),(0,ee.w)(Et=>{let qt=!1,Hn=!1;return(0,y.of)(Et).pipe((0,ce.b)(Xn=>{this.currentNavigation={id:Xn.id,initialUrl:Xn.currentRawUrl,extractedUrl:Xn.extractedUrl,trigger:Xn.source,extras:Xn.extras,previousNavigation:this.lastSuccessfulNavigation?Object.assign(Object.assign({},this.lastSuccessfulNavigation),{previousNavigation:null}):null}}),(0,ee.w)(Xn=>{const Ei=this.browserUrlTree.toString(),Yo=!this.navigated||Xn.extractedUrl.toString()!==Ei||Ei!==this.currentUrlTree.toString();if(("reload"===this.onSameUrlNavigation||Yo)&&this.urlHandlingStrategy.shouldProcessUrl(Xn.rawUrl))return ai(Xn.source)&&(this.browserUrlTree=Xn.extractedUrl),(0,y.of)(Xn).pipe((0,ee.w)(ns=>{const Oa=this.transitions.getValue();return ot.next(new je(ns.id,this.serializeUrl(ns.extractedUrl),ns.source,ns.restoredState)),Oa!==this.transitions.getValue()?e.E:Promise.resolve(ns)}),function(Ye,Ie,Ce,ot){return(0,ee.w)(Et=>function(Ye,Ie,Ce,ot,Et){return new Te(Ye,Ie,Ce,ot,Et).apply()}(Ye,Ie,Ce,Et.extractedUrl,ot).pipe((0,K.U)(qt=>Object.assign(Object.assign({},Et),{urlAfterRedirects:qt}))))}(this.ngModule.injector,this.configLoader,this.urlSerializer,this.config),(0,ce.b)(ns=>{this.currentNavigation=Object.assign(Object.assign({},this.currentNavigation),{finalUrl:ns.urlAfterRedirects})}),function(Ye,Ie,Ce,ot,Et){return(0,De.zg)(qt=>function(Ye,Ie,Ce,ot,Et="emptyOnly",qt="legacy"){try{const Hn=new sa(Ye,Ie,Ce,ot,Et,qt).recognize();return null===Hn?rc(new gd):(0,y.of)(Hn)}catch(Hn){return rc(Hn)}}(Ye,Ie,qt.urlAfterRedirects,Ce(qt.urlAfterRedirects),ot,Et).pipe((0,K.U)(Hn=>Object.assign(Object.assign({},qt),{targetSnapshot:Hn}))))}(this.rootComponentType,this.config,ns=>this.serializeUrl(ns),this.paramsInheritanceStrategy,this.relativeLinkResolution),(0,ce.b)(ns=>{"eager"===this.urlUpdateStrategy&&(ns.extras.skipLocationChange||this.setBrowserUrl(ns.urlAfterRedirects,ns),this.browserUrlTree=ns.urlAfterRedirects);const Oa=new tn(ns.id,this.serializeUrl(ns.extractedUrl),this.serializeUrl(ns.urlAfterRedirects),ns.targetSnapshot);ot.next(Oa)}));if(Yo&&this.rawUrlTree&&this.urlHandlingStrategy.shouldProcessUrl(this.rawUrlTree)){const{id:Oa,extractedUrl:Hs,source:fc,restoredState:ga,extras:Ol}=Xn,ll=new je(Oa,this.serializeUrl(Hs),fc,ga);ot.next(ll);const Za=Ci(Hs,this.rootComponentType).snapshot;return(0,y.of)(Object.assign(Object.assign({},Xn),{targetSnapshot:Za,urlAfterRedirects:Hs,extras:Object.assign(Object.assign({},Ol),{skipLocationChange:!1,replaceUrl:!1})}))}return this.rawUrlTree=Xn.rawUrl,this.browserUrlTree=Xn.urlAfterRedirects,Xn.resolve(null),e.E}),pu(Xn=>{const{targetSnapshot:Ei,id:Yo,extractedUrl:$a,rawUrl:ns,extras:{skipLocationChange:Oa,replaceUrl:Hs}}=Xn;return this.hooks.beforePreactivation(Ei,{navigationId:Yo,appliedUrlTree:$a,rawUrlTree:ns,skipLocationChange:!!Oa,replaceUrl:!!Hs})}),(0,ce.b)(Xn=>{const Ei=new It(Xn.id,this.serializeUrl(Xn.extractedUrl),this.serializeUrl(Xn.urlAfterRedirects),Xn.targetSnapshot);this.triggerEvent(Ei)}),(0,K.U)(Xn=>Object.assign(Object.assign({},Xn),{guards:Go(Xn.targetSnapshot,Xn.currentSnapshot,this.rootContexts)})),function(Ye,Ie){return(0,De.zg)(Ce=>{const{targetSnapshot:ot,currentSnapshot:Et,guards:{canActivateChecks:qt,canDeactivateChecks:Hn}}=Ce;return 0===Hn.length&&0===qt.length?(0,y.of)(Object.assign(Object.assign({},Ce),{guardsResult:!0})):function(Ye,Ie,Ce,ot){return(0,d.D)(Ye).pipe((0,De.zg)(Et=>function(Ye,Ie,Ce,ot,Et){const qt=Ie&&Ie.routeConfig?Ie.routeConfig.canDeactivate:null;if(!qt||0===qt.length)return(0,y.of)(!0);const Hn=qt.map(Xn=>{const Ei=hs(Xn,Ie,Et);let Yo;if(function(Ye){return Ye&&$r(Ye.canDeactivate)}(Ei))Yo=zn(Ei.canDeactivate(Ye,Ie,Ce,ot));else{if(!$r(Ei))throw new Error("Invalid CanDeactivate guard");Yo=zn(Ei(Ye,Ie,Ce,ot))}return Yo.pipe((0,ge.P)())});return(0,y.of)(Hn).pipe(ti())}(Et.component,Et.route,Ce,Ie,ot)),(0,ge.P)(Et=>!0!==Et,!0))}(Hn,ot,Et,Ye).pipe((0,De.zg)(Xn=>Xn&&function(Ye){return"boolean"==typeof Ye}(Xn)?function(Ye,Ie,Ce,ot){return(0,d.D)(Ie).pipe((0,ie.b)(Et=>(0,L.z)(function(Ye,Ie){return null!==Ye&&Ie&&Ie(new xt(Ye)),(0,y.of)(!0)}(Et.route.parent,ot),function(Ye,Ie){return null!==Ye&&Ie&&Ie(new Zn(Ye)),(0,y.of)(!0)}(Et.route,ot),function(Ye,Ie,Ce){const ot=Ie[Ie.length-1],qt=Ie.slice(0,Ie.length-1).reverse().map(Hn=>function(Ye){const Ie=Ye.routeConfig?Ye.routeConfig.canActivateChild:null;return Ie&&0!==Ie.length?{node:Ye,guards:Ie}:null}(Hn)).filter(Hn=>null!==Hn).map(Hn=>_(()=>{const Xn=Hn.guards.map(Ei=>{const Yo=hs(Ei,Hn.node,Ce);let $a;if(function(Ye){return Ye&&$r(Ye.canActivateChild)}(Yo))$a=zn(Yo.canActivateChild(ot,Ye));else{if(!$r(Yo))throw new Error("Invalid CanActivateChild guard");$a=zn(Yo(ot,Ye))}return $a.pipe((0,ge.P)())});return(0,y.of)(Xn).pipe(ti())}));return(0,y.of)(qt).pipe(ti())}(Ye,Et.path,Ce),function(Ye,Ie,Ce){const ot=Ie.routeConfig?Ie.routeConfig.canActivate:null;if(!ot||0===ot.length)return(0,y.of)(!0);const Et=ot.map(qt=>_(()=>{const Hn=hs(qt,Ie,Ce);let Xn;if(function(Ye){return Ye&&$r(Ye.canActivate)}(Hn))Xn=zn(Hn.canActivate(Ie,Ye));else{if(!$r(Hn))throw new Error("Invalid CanActivate guard");Xn=zn(Hn(Ie,Ye))}return Xn.pipe((0,ge.P)())}));return(0,y.of)(Et).pipe(ti())}(Ye,Et.route,Ce))),(0,ge.P)(Et=>!0!==Et,!0))}(ot,qt,Ye,Ie):(0,y.of)(Xn)),(0,K.U)(Xn=>Object.assign(Object.assign({},Ce),{guardsResult:Xn})))})}(this.ngModule.injector,Xn=>this.triggerEvent(Xn)),(0,ce.b)(Xn=>{if(tt(Xn.guardsResult)){const Yo=Nn(`Redirecting to "${this.serializeUrl(Xn.guardsResult)}"`);throw Yo.url=Xn.guardsResult,Yo}const Ei=new Zt(Xn.id,this.serializeUrl(Xn.extractedUrl),this.serializeUrl(Xn.urlAfterRedirects),Xn.targetSnapshot,!!Xn.guardsResult);this.triggerEvent(Ei)}),(0,se.h)(Xn=>!!Xn.guardsResult||(this.restoreHistory(Xn),this.cancelNavigationTransition(Xn,""),!1)),pu(Xn=>{if(Xn.guards.canActivateChecks.length)return(0,y.of)(Xn).pipe((0,ce.b)(Ei=>{const Yo=new Ut(Ei.id,this.serializeUrl(Ei.extractedUrl),this.serializeUrl(Ei.urlAfterRedirects),Ei.targetSnapshot);this.triggerEvent(Yo)}),(0,ee.w)(Ei=>{let Yo=!1;return(0,y.of)(Ei).pipe(function(Ye,Ie){return(0,De.zg)(Ce=>{const{targetSnapshot:ot,guards:{canActivateChecks:Et}}=Ce;if(!Et.length)return(0,y.of)(Ce);let qt=0;return(0,d.D)(Et).pipe((0,ie.b)(Hn=>function(Ye,Ie,Ce,ot){return function(Ye,Ie,Ce,ot){const Et=Object.keys(Ye);if(0===Et.length)return(0,y.of)({});const qt={};return(0,d.D)(Et).pipe((0,De.zg)(Hn=>function(Ye,Ie,Ce,ot){const Et=hs(Ye,Ie,ot);return zn(Et.resolve?Et.resolve(Ie,Ce):Et(Ie,Ce))}(Ye[Hn],Ie,Ce,ot).pipe((0,ce.b)(Xn=>{qt[Hn]=Xn}))),(0,lt.h)(1),(0,De.zg)(()=>Object.keys(qt).length===Et.length?(0,y.of)(qt):e.E))}(Ye._resolve,Ye,Ie,ot).pipe((0,K.U)(qt=>(Ye._resolvedData=qt,Ye.data=Object.assign(Object.assign({},Ye.data),Ar(Ye,Ce).resolve),null)))}(Hn.route,ot,Ye,Ie)),(0,ce.b)(()=>qt++),(0,lt.h)(1),(0,De.zg)(Hn=>qt===Et.length?(0,y.of)(Ce):e.E))})}(this.paramsInheritanceStrategy,this.ngModule.injector),(0,ce.b)({next:()=>Yo=!0,complete:()=>{Yo||(this.restoreHistory(Ei),this.cancelNavigationTransition(Ei,"At least one route resolver didn't emit any value."))}}))}),(0,ce.b)(Ei=>{const Yo=new Bt(Ei.id,this.serializeUrl(Ei.extractedUrl),this.serializeUrl(Ei.urlAfterRedirects),Ei.targetSnapshot);this.triggerEvent(Yo)}))}),pu(Xn=>{const{targetSnapshot:Ei,id:Yo,extractedUrl:$a,rawUrl:ns,extras:{skipLocationChange:Oa,replaceUrl:Hs}}=Xn;return this.hooks.afterPreactivation(Ei,{navigationId:Yo,appliedUrlTree:$a,rawUrlTree:ns,skipLocationChange:!!Oa,replaceUrl:!!Hs})}),(0,K.U)(Xn=>{const Ei=function(Ye,Ie,Ce){const ot=co(Ye,Ie._root,Ce?Ce._root:void 0);return new uo(ot,Ie)}(this.routeReuseStrategy,Xn.targetSnapshot,Xn.currentRouterState);return Object.assign(Object.assign({},Xn),{targetRouterState:Ei})}),(0,ce.b)(Xn=>{this.currentUrlTree=Xn.urlAfterRedirects,this.rawUrlTree=this.urlHandlingStrategy.merge(Xn.urlAfterRedirects,Xn.rawUrl),this.routerState=Xn.targetRouterState,"deferred"===this.urlUpdateStrategy&&(Xn.extras.skipLocationChange||this.setBrowserUrl(this.rawUrlTree,Xn),this.browserUrlTree=Xn.urlAfterRedirects)}),((Ye,Ie,Ce)=>(0,K.U)(ot=>(new bo(Ie,ot.targetRouterState,ot.currentRouterState,Ce).activate(Ye),ot)))(this.rootContexts,this.routeReuseStrategy,Xn=>this.triggerEvent(Xn)),(0,ce.b)({next(){qt=!0},complete(){qt=!0}}),(0,ze.x)(()=>{var Xn;if(!qt&&!Hn){const Ei=`Navigation ID ${Et.id} is not equal to the current navigation id ${this.navigationId}`;"replace"===this.canceledNavigationResolution?(this.restoreHistory(Et),this.cancelNavigationTransition(Et,Ei)):this.cancelNavigationTransition(Et,Ei)}(null===(Xn=this.currentNavigation)||void 0===Xn?void 0:Xn.id)===Et.id&&(this.currentNavigation=null)}),(0,Ee.K)(Xn=>{if(Hn=!0,function(Ye){return Ye&&Ye[ei]}(Xn)){const Ei=tt(Xn.url);Ei||(this.navigated=!0,this.restoreHistory(Et,!0));const Yo=new Vt(Et.id,this.serializeUrl(Et.extractedUrl),Xn.message);ot.next(Yo),Ei?setTimeout(()=>{const $a=this.urlHandlingStrategy.merge(Xn.url,this.rawUrlTree),ns={skipLocationChange:Et.extras.skipLocationChange,replaceUrl:"eager"===this.urlUpdateStrategy||ai(Et.source)};this.scheduleNavigation($a,"imperative",null,ns,{resolve:Et.resolve,reject:Et.reject,promise:Et.promise})},0):Et.resolve(!1)}else{this.restoreHistory(Et,!0);const Ei=new it(Et.id,this.serializeUrl(Et.extractedUrl),Xn);ot.next(Ei);try{Et.resolve(this.errorHandler(Xn))}catch(Yo){Et.reject(Yo)}}return e.E}))}))}resetRootComponentType(Ce){this.rootComponentType=Ce,this.routerState.root.component=this.rootComponentType}getTransition(){const Ce=this.transitions.value;return Ce.urlAfterRedirects=this.browserUrlTree,Ce}setTransition(Ce){this.transitions.next(Object.assign(Object.assign({},this.getTransition()),Ce))}initialNavigation(){this.setUpLocationChangeListener(),0===this.navigationId&&this.navigateByUrl(this.location.path(!0),{replaceUrl:!0})}setUpLocationChangeListener(){this.locationSubscription||(this.locationSubscription=this.location.subscribe(Ce=>{const ot=this.extractLocationChangeInfoFromEvent(Ce);this.shouldScheduleNavigation(this.lastLocationChangeInfo,ot)&&setTimeout(()=>{const{source:Et,state:qt,urlTree:Hn}=ot,Xn={replaceUrl:!0};if(qt){const Ei=Object.assign({},qt);delete Ei.navigationId,delete Ei.\u0275routerPageId,0!==Object.keys(Ei).length&&(Xn.state=Ei)}this.scheduleNavigation(Hn,Et,qt,Xn)},0),this.lastLocationChangeInfo=ot}))}extractLocationChangeInfoFromEvent(Ce){var ot;return{source:"popstate"===Ce.type?"popstate":"hashchange",urlTree:this.parseUrl(Ce.url),state:(null===(ot=Ce.state)||void 0===ot?void 0:ot.navigationId)?Ce.state:null,transitionId:this.getTransition().id}}shouldScheduleNavigation(Ce,ot){if(!Ce)return!0;const Et=ot.urlTree.toString()===Ce.urlTree.toString();return ot.transitionId!==Ce.transitionId||!Et||!("hashchange"===ot.source&&"popstate"===Ce.source||"popstate"===ot.source&&"hashchange"===Ce.source)}get url(){return this.serializeUrl(this.currentUrlTree)}getCurrentNavigation(){return this.currentNavigation}triggerEvent(Ce){this.events.next(Ce)}resetConfig(Ce){xi(Ce),this.config=Ce.map(ko),this.navigated=!1,this.lastSuccessfulId=-1}ngOnDestroy(){this.dispose()}dispose(){this.transitions.complete(),this.locationSubscription&&(this.locationSubscription.unsubscribe(),this.locationSubscription=void 0),this.disposed=!0}createUrlTree(Ce,ot={}){const{relativeTo:Et,queryParams:qt,fragment:Hn,queryParamsHandling:Xn,preserveFragment:Ei}=ot,Yo=Et||this.routerState.root,$a=Ei?this.currentUrlTree.fragment:Hn;let ns=null;switch(Xn){case"merge":ns=Object.assign(Object.assign({},this.currentUrlTree.queryParams),qt);break;case"preserve":ns=this.currentUrlTree.queryParams;break;default:ns=qt||null}return null!==ns&&(ns=this.removeEmptyProps(ns)),function(Ye,Ie,Ce,ot,Et){if(0===Ce.length)return us(Ie.root,Ie.root,Ie,ot,Et);const qt=function(Ye){if("string"==typeof Ye[0]&&1===Ye.length&&"/"===Ye[0])return new el(!0,0,Ye);let Ie=0,Ce=!1;const ot=Ye.reduce((Et,qt,Hn)=>{if("object"==typeof qt&&null!=qt){if(qt.outlets){const Xn={};return Wt(qt.outlets,(Ei,Yo)=>{Xn[Yo]="string"==typeof Ei?Ei.split("/"):Ei}),[...Et,{outlets:Xn}]}if(qt.segmentPath)return[...Et,qt.segmentPath]}return"string"!=typeof qt?[...Et,qt]:0===Hn?(qt.split("/").forEach((Xn,Ei)=>{0==Ei&&"."===Xn||(0==Ei&&""===Xn?Ce=!0:".."===Xn?Ie++:""!=Xn&&Et.push(Xn))}),Et):[...Et,qt]},[]);return new el(Ce,Ie,ot)}(Ce);if(qt.toRoot())return us(Ie.root,new Jt([],{}),Ie,ot,Et);const Hn=function(Ye,Ie,Ce){if(Ye.isAbsolute)return new $s(Ie.root,!0,0);if(-1===Ce.snapshot._lastPathIndex){const qt=Ce.snapshot._urlSegment;return new $s(qt,qt===Ie.root,0)}const ot=ta(Ye.commands[0])?0:1;return function(Ye,Ie,Ce){let ot=Ye,Et=Ie,qt=Ce;for(;qt>Et;){if(qt-=Et,ot=ot.parent,!ot)throw new Error("Invalid number of '../'");Et=ot.segments.length}return new $s(ot,!1,Et-qt)}(Ce.snapshot._urlSegment,Ce.snapshot._lastPathIndex+ot,Ye.numberOfDoubleDots)}(qt,Ie,Ye),Xn=Hn.processChildren?Ao(Hn.segmentGroup,Hn.index,qt.commands):Ya(Hn.segmentGroup,Hn.index,qt.commands);return us(Hn.segmentGroup,Xn,Ie,ot,Et)}(Yo,this.currentUrlTree,Ce,ns,null!=$a?$a:null)}navigateByUrl(Ce,ot={skipLocationChange:!1}){const Et=tt(Ce)?Ce:this.parseUrl(Ce),qt=this.urlHandlingStrategy.merge(Et,this.rawUrlTree);return this.scheduleNavigation(qt,"imperative",null,ot)}navigate(Ce,ot={skipLocationChange:!1}){return function(Ye){for(let Ie=0;Ie<Ye.length;Ie++){const Ce=Ye[Ie];if(null==Ce)throw new Error(`The requested path contains ${Ce} segment at index ${Ie}`)}}(Ce),this.navigateByUrl(this.createUrlTree(Ce,ot),ot)}serializeUrl(Ce){return this.urlSerializer.serialize(Ce)}parseUrl(Ce){let ot;try{ot=this.urlSerializer.parse(Ce)}catch(Et){ot=this.malformedUriErrorHandler(Et,this.urlSerializer,Ce)}return ot}isActive(Ce,ot){let Et;if(Et=!0===ot?Object.assign({},mn):!1===ot?Object.assign({},Or):ot,tt(Ce))return Jr(this.currentUrlTree,Ce,Et);const qt=this.parseUrl(Ce);return Jr(this.currentUrlTree,qt,Et)}removeEmptyProps(Ce){return Object.keys(Ce).reduce((ot,Et)=>{const qt=Ce[Et];return null!=qt&&(ot[Et]=qt),ot},{})}processNavigations(){this.navigations.subscribe(Ce=>{this.navigated=!0,this.lastSuccessfulId=Ce.id,this.currentPageId=Ce.targetPageId,this.events.next(new He(Ce.id,this.serializeUrl(Ce.extractedUrl),this.serializeUrl(this.currentUrlTree))),this.lastSuccessfulNavigation=this.currentNavigation,Ce.resolve(!0)},Ce=>{this.console.warn(`Unhandled Navigation Error: ${Ce}`)})}scheduleNavigation(Ce,ot,Et,qt,Hn){var Xn,Ei;if(this.disposed)return Promise.resolve(!1);const Yo=this.getTransition(),$a=ai(ot)&&Yo&&!ai(Yo.source),Hs=(this.lastSuccessfulId===Yo.id||this.currentNavigation?Yo.rawUrl:Yo.urlAfterRedirects).toString()===Ce.toString();if($a&&Hs)return Promise.resolve(!0);let fc,ga,Ol;Hn?(fc=Hn.resolve,ga=Hn.reject,Ol=Hn.promise):Ol=new Promise((ja,ul)=>{fc=ja,ga=ul});const ll=++this.navigationId;let Za;return"computed"===this.canceledNavigationResolution?(0===this.currentPageId&&(Et=this.location.getState()),Za=Et&&Et.\u0275routerPageId?Et.\u0275routerPageId:qt.replaceUrl||qt.skipLocationChange?null!==(Xn=this.browserPageId)&&void 0!==Xn?Xn:0:(null!==(Ei=this.browserPageId)&&void 0!==Ei?Ei:0)+1):Za=0,this.setTransition({id:ll,targetPageId:Za,source:ot,restoredState:Et,currentUrlTree:this.currentUrlTree,currentRawUrl:this.rawUrlTree,rawUrl:Ce,extras:qt,resolve:fc,reject:ga,promise:Ol,currentSnapshot:this.routerState.snapshot,currentRouterState:this.routerState}),Ol.catch(ja=>Promise.reject(ja))}setBrowserUrl(Ce,ot){const Et=this.urlSerializer.serialize(Ce),qt=Object.assign(Object.assign({},ot.extras.state),this.generateNgRouterState(ot.id,ot.targetPageId));this.location.isCurrentPathEqualTo(Et)||ot.extras.replaceUrl?this.location.replaceState(Et,"",qt):this.location.go(Et,"",qt)}restoreHistory(Ce,ot=!1){var Et,qt;if("computed"===this.canceledNavigationResolution){const Hn=this.currentPageId-Ce.targetPageId;"popstate"!==Ce.source&&"eager"!==this.urlUpdateStrategy&&this.currentUrlTree!==(null===(Et=this.currentNavigation)||void 0===Et?void 0:Et.finalUrl)||0===Hn?this.currentUrlTree===(null===(qt=this.currentNavigation)||void 0===qt?void 0:qt.finalUrl)&&0===Hn&&(this.resetState(Ce),this.browserUrlTree=Ce.currentUrlTree,this.resetUrlToCurrentUrlTree()):this.location.historyGo(Hn)}else"replace"===this.canceledNavigationResolution&&(ot&&this.resetState(Ce),this.resetUrlToCurrentUrlTree())}resetState(Ce){this.routerState=Ce.currentRouterState,this.currentUrlTree=Ce.currentUrlTree,this.rawUrlTree=this.urlHandlingStrategy.merge(this.currentUrlTree,Ce.rawUrl)}resetUrlToCurrentUrlTree(){this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree),"",this.generateNgRouterState(this.lastSuccessfulId,this.currentPageId))}cancelNavigationTransition(Ce,ot){const Et=new Vt(Ce.id,this.serializeUrl(Ce.extractedUrl),ot);this.triggerEvent(Et),Ce.resolve(!1)}generateNgRouterState(Ce,ot){return"computed"===this.canceledNavigationResolution?{navigationId:Ce,\u0275routerPageId:ot}:{navigationId:Ce}}}return Ye.\u0275fac=function(Ce){return new(Ce||Ye)(u.LFG(u.DyG),u.LFG(Yt),u.LFG(V),u.LFG(r.Ye),u.LFG(u.zs3),u.LFG(u.v3s),u.LFG(u.Sil),u.LFG(void 0))},Ye.\u0275prov=u.Yz7({token:Ye,factory:Ye.\u0275fac}),Ye})();function ai(Ye){return"imperative"!==Ye}let Io=(()=>{class Ye{constructor(Ce,ot,Et,qt,Hn){this.router=Ce,this.route=ot,this.commands=[],this.onChanges=new J.xQ,null==Et&&qt.setAttribute(Hn.nativeElement,"tabindex","0")}ngOnChanges(Ce){this.onChanges.next(this)}set routerLink(Ce){this.commands=null!=Ce?Array.isArray(Ce)?Ce:[Ce]:[]}onClick(){const Ce={skipLocationChange:In(this.skipLocationChange),replaceUrl:In(this.replaceUrl),state:this.state};return this.router.navigateByUrl(this.urlTree,Ce),!0}get urlTree(){return this.router.createUrlTree(this.commands,{relativeTo:void 0!==this.relativeTo?this.relativeTo:this.route,queryParams:this.queryParams,fragment:this.fragment,queryParamsHandling:this.queryParamsHandling,preserveFragment:In(this.preserveFragment)})}}return Ye.\u0275fac=function(Ce){return new(Ce||Ye)(u.Y36(zr),u.Y36(tr),u.$8M("tabindex"),u.Y36(u.Qsj),u.Y36(u.SBq))},Ye.\u0275dir=u.lG2({type:Ye,selectors:[["","routerLink","",5,"a",5,"area"]],hostBindings:function(Ce,ot){1&Ce&&u.NdJ("click",function(){return ot.onClick()})},inputs:{routerLink:"routerLink",queryParams:"queryParams",fragment:"fragment",queryParamsHandling:"queryParamsHandling",preserveFragment:"preserveFragment",skipLocationChange:"skipLocationChange",replaceUrl:"replaceUrl",state:"state",relativeTo:"relativeTo"},features:[u.TTD]}),Ye})(),Fo=(()=>{class Ye{constructor(Ce,ot,Et){this.router=Ce,this.route=ot,this.locationStrategy=Et,this.commands=[],this.onChanges=new J.xQ,this.subscription=Ce.events.subscribe(qt=>{qt instanceof He&&this.updateTargetUrlAndHref()})}set routerLink(Ce){this.commands=null!=Ce?Array.isArray(Ce)?Ce:[Ce]:[]}ngOnChanges(Ce){this.updateTargetUrlAndHref(),this.onChanges.next(this)}ngOnDestroy(){this.subscription.unsubscribe()}onClick(Ce,ot,Et,qt,Hn){if(0!==Ce||ot||Et||qt||Hn||"string"==typeof this.target&&"_self"!=this.target)return!0;const Xn={skipLocationChange:In(this.skipLocationChange),replaceUrl:In(this.replaceUrl),state:this.state};return this.router.navigateByUrl(this.urlTree,Xn),!1}updateTargetUrlAndHref(){this.href=this.locationStrategy.prepareExternalUrl(this.router.serializeUrl(this.urlTree))}get urlTree(){return this.router.createUrlTree(this.commands,{relativeTo:void 0!==this.relativeTo?this.relativeTo:this.route,queryParams:this.queryParams,fragment:this.fragment,queryParamsHandling:this.queryParamsHandling,preserveFragment:In(this.preserveFragment)})}}return Ye.\u0275fac=function(Ce){return new(Ce||Ye)(u.Y36(zr),u.Y36(tr),u.Y36(r.S$))},Ye.\u0275dir=u.lG2({type:Ye,selectors:[["a","routerLink",""],["area","routerLink",""]],hostVars:2,hostBindings:function(Ce,ot){1&Ce&&u.NdJ("click",function(qt){return ot.onClick(qt.button,qt.ctrlKey,qt.shiftKey,qt.altKey,qt.metaKey)}),2&Ce&&(u.Ikx("href",ot.href,u.LSH),u.uIk("target",ot.target))},inputs:{routerLink:"routerLink",target:"target",queryParams:"queryParams",fragment:"fragment",queryParamsHandling:"queryParamsHandling",preserveFragment:"preserveFragment",skipLocationChange:"skipLocationChange",replaceUrl:"replaceUrl",state:"state",relativeTo:"relativeTo"},features:[u.TTD]}),Ye})();function In(Ye){return""===Ye||!!Ye}let Cr=(()=>{class Ye{constructor(Ce,ot,Et,qt,Hn,Xn){this.router=Ce,this.element=ot,this.renderer=Et,this.cdr=qt,this.link=Hn,this.linkWithHref=Xn,this.classes=[],this.isActive=!1,this.routerLinkActiveOptions={exact:!1},this.routerEventsSubscription=Ce.events.subscribe(Ei=>{Ei instanceof He&&this.update()})}ngAfterContentInit(){(0,y.of)(this.links.changes,this.linksWithHrefs.changes,(0,y.of)(null)).pipe((0,Be.J)()).subscribe(Ce=>{this.update(),this.subscribeToEachLinkOnChanges()})}subscribeToEachLinkOnChanges(){var Ce;null===(Ce=this.linkInputChangesSubscription)||void 0===Ce||Ce.unsubscribe();const ot=[...this.links.toArray(),...this.linksWithHrefs.toArray(),this.link,this.linkWithHref].filter(Et=>!!Et).map(Et=>Et.onChanges);this.linkInputChangesSubscription=(0,d.D)(ot).pipe((0,Be.J)()).subscribe(Et=>{this.isActive!==this.isLinkActive(this.router)(Et)&&this.update()})}set routerLinkActive(Ce){const ot=Array.isArray(Ce)?Ce:Ce.split(" ");this.classes=ot.filter(Et=>!!Et)}ngOnChanges(Ce){this.update()}ngOnDestroy(){var Ce;this.routerEventsSubscription.unsubscribe(),null===(Ce=this.linkInputChangesSubscription)||void 0===Ce||Ce.unsubscribe()}update(){!this.links||!this.linksWithHrefs||!this.router.navigated||Promise.resolve().then(()=>{const Ce=this.hasActiveLinks();this.isActive!==Ce&&(this.isActive=Ce,this.cdr.markForCheck(),this.classes.forEach(ot=>{Ce?this.renderer.addClass(this.element.nativeElement,ot):this.renderer.removeClass(this.element.nativeElement,ot)}))})}isLinkActive(Ce){const ot=function(Ye){return!!Ye.paths}(this.routerLinkActiveOptions)?this.routerLinkActiveOptions:this.routerLinkActiveOptions.exact||!1;return Et=>Ce.isActive(Et.urlTree,ot)}hasActiveLinks(){const Ce=this.isLinkActive(this.router);return this.link&&Ce(this.link)||this.linkWithHref&&Ce(this.linkWithHref)||this.links.some(Ce)||this.linksWithHrefs.some(Ce)}}return Ye.\u0275fac=function(Ce){return new(Ce||Ye)(u.Y36(zr),u.Y36(u.SBq),u.Y36(u.Qsj),u.Y36(u.sBO),u.Y36(Io,8),u.Y36(Fo,8))},Ye.\u0275dir=u.lG2({type:Ye,selectors:[["","routerLinkActive",""]],contentQueries:function(Ce,ot,Et){if(1&Ce&&(u.Suo(Et,Io,5),u.Suo(Et,Fo,5)),2&Ce){let qt;u.iGM(qt=u.CRH())&&(ot.links=qt),u.iGM(qt=u.CRH())&&(ot.linksWithHrefs=qt)}},inputs:{routerLinkActiveOptions:"routerLinkActiveOptions",routerLinkActive:"routerLinkActive"},exportAs:["routerLinkActive"],features:[u.TTD]}),Ye})(),ao=(()=>{class Ye{constructor(Ce,ot,Et,qt,Hn){this.parentContexts=Ce,this.location=ot,this.resolver=Et,this.changeDetector=Hn,this.activated=null,this._activatedRoute=null,this.activateEvents=new u.vpe,this.deactivateEvents=new u.vpe,this.name=qt||Lr,Ce.onChildOutletCreated(this.name,this)}ngOnDestroy(){this.parentContexts.onChildOutletDestroyed(this.name)}ngOnInit(){if(!this.activated){const Ce=this.parentContexts.getContext(this.name);Ce&&Ce.route&&(Ce.attachRef?this.attach(Ce.attachRef,Ce.route):this.activateWith(Ce.route,Ce.resolver||null))}}get isActivated(){return!!this.activated}get component(){if(!this.activated)throw new Error("Outlet is not activated");return this.activated.instance}get activatedRoute(){if(!this.activated)throw new Error("Outlet is not activated");return this._activatedRoute}get activatedRouteData(){return this._activatedRoute?this._activatedRoute.snapshot.data:{}}detach(){if(!this.activated)throw new Error("Outlet is not activated");this.location.detach();const Ce=this.activated;return this.activated=null,this._activatedRoute=null,Ce}attach(Ce,ot){this.activated=Ce,this._activatedRoute=ot,this.location.insert(Ce.hostView)}deactivate(){if(this.activated){const Ce=this.component;this.activated.destroy(),this.activated=null,this._activatedRoute=null,this.deactivateEvents.emit(Ce)}}activateWith(Ce,ot){if(this.isActivated)throw new Error("Cannot activate an already activated outlet");this._activatedRoute=Ce;const Hn=(ot=ot||this.resolver).resolveComponentFactory(Ce._futureSnapshot.routeConfig.component),Xn=this.parentContexts.getOrCreateContext(this.name).children,Ei=new ys(Ce,Xn,this.location.injector);this.activated=this.location.createComponent(Hn,this.location.length,Ei),this.changeDetector.markForCheck(),this.activateEvents.emit(this.activated.instance)}}return Ye.\u0275fac=function(Ce){return new(Ce||Ye)(u.Y36(V),u.Y36(u.s_b),u.Y36(u._Vd),u.$8M("name"),u.Y36(u.sBO))},Ye.\u0275dir=u.lG2({type:Ye,selectors:[["router-outlet"]],outputs:{activateEvents:"activate",deactivateEvents:"deactivate"},exportAs:["outlet"]}),Ye})();class ys{constructor(Ie,Ce,ot){this.route=Ie,this.childContexts=Ce,this.parent=ot}get(Ie,Ce){return Ie===tr?this.route:Ie===V?this.childContexts:this.parent.get(Ie,Ce)}}class Na{}class Tl{preload(Ie,Ce){return Ce().pipe((0,Ee.K)(()=>(0,y.of)(null)))}}class Qs{preload(Ie,Ce){return(0,y.of)(null)}}let ed=(()=>{class Ye{constructor(Ce,ot,Et,qt,Hn){this.router=Ce,this.injector=qt,this.preloadingStrategy=Hn,this.loader=new Ul(ot,Et,Yo=>Ce.triggerEvent(new bt(Yo)),Yo=>Ce.triggerEvent(new Gt(Yo)))}setUpPreloading(){this.subscription=this.router.events.pipe((0,se.h)(Ce=>Ce instanceof He),(0,ie.b)(()=>this.preload())).subscribe(()=>{})}preload(){const Ce=this.injector.get(u.h0i);return this.processRoutes(Ce,this.router.config)}ngOnDestroy(){this.subscription&&this.subscription.unsubscribe()}processRoutes(Ce,ot){const Et=[];for(const qt of ot)if(qt.loadChildren&&!qt.canLoad&&qt._loadedConfig){const Hn=qt._loadedConfig;Et.push(this.processRoutes(Hn.module,Hn.routes))}else qt.loadChildren&&!qt.canLoad?Et.push(this.preloadConfig(Ce,qt)):qt.children&&Et.push(this.processRoutes(Ce,qt.children));return(0,d.D)(Et).pipe((0,Be.J)(),(0,K.U)(qt=>{}))}preloadConfig(Ce,ot){return this.preloadingStrategy.preload(ot,()=>(ot._loadedConfig?(0,y.of)(ot._loadedConfig):this.loader.load(Ce.injector,ot)).pipe((0,De.zg)(qt=>(ot._loadedConfig=qt,this.processRoutes(qt.module,qt.routes)))))}}return Ye.\u0275fac=function(Ce){return new(Ce||Ye)(u.LFG(zr),u.LFG(u.v3s),u.LFG(u.Sil),u.LFG(u.zs3),u.LFG(Na))},Ye.\u0275prov=u.Yz7({token:Ye,factory:Ye.\u0275fac}),Ye})(),$c=(()=>{class Ye{constructor(Ce,ot,Et={}){this.router=Ce,this.viewportScroller=ot,this.options=Et,this.lastId=0,this.lastSource="imperative",this.restoredId=0,this.store={},Et.scrollPositionRestoration=Et.scrollPositionRestoration||"disabled",Et.anchorScrolling=Et.anchorScrolling||"disabled"}init(){"disabled"!==this.options.scrollPositionRestoration&&this.viewportScroller.setHistoryScrollRestoration("manual"),this.routerEventsSubscription=this.createScrollEvents(),this.scrollEventsSubscription=this.consumeScrollEvents()}createScrollEvents(){return this.router.events.subscribe(Ce=>{Ce instanceof je?(this.store[this.lastId]=this.viewportScroller.getScrollPosition(),this.lastSource=Ce.navigationTrigger,this.restoredId=Ce.restoredState?Ce.restoredState.navigationId:0):Ce instanceof He&&(this.lastId=Ce.id,this.scheduleScrollEvent(Ce,this.router.parseUrl(Ce.urlAfterRedirects).fragment))})}consumeScrollEvents(){return this.router.events.subscribe(Ce=>{Ce instanceof di&&(Ce.position?"top"===this.options.scrollPositionRestoration?this.viewportScroller.scrollToPosition([0,0]):"enabled"===this.options.scrollPositionRestoration&&this.viewportScroller.scrollToPosition(Ce.position):Ce.anchor&&"enabled"===this.options.anchorScrolling?this.viewportScroller.scrollToAnchor(Ce.anchor):"disabled"!==this.options.scrollPositionRestoration&&this.viewportScroller.scrollToPosition([0,0]))})}scheduleScrollEvent(Ce,ot){this.router.triggerEvent(new di(Ce,"popstate"===this.lastSource?this.store[this.restoredId]:null,ot))}ngOnDestroy(){this.routerEventsSubscription&&this.routerEventsSubscription.unsubscribe(),this.scrollEventsSubscription&&this.scrollEventsSubscription.unsubscribe()}}return Ye.\u0275fac=function(Ce){return new(Ce||Ye)(u.LFG(zr),u.LFG(r.EM),u.LFG(void 0))},Ye.\u0275prov=u.Yz7({token:Ye,factory:Ye.\u0275fac}),Ye})();const $i=new u.OlP("ROUTER_CONFIGURATION"),xo=new u.OlP("ROUTER_FORROOT_GUARD"),hl=[r.Ye,{provide:Yt,useClass:_n},{provide:zr,useFactory:function(Ye,Ie,Ce,ot,Et,qt,Hn,Xn={},Ei,Yo){const $a=new zr(null,Ye,Ie,Ce,ot,Et,qt,Hi(Hn));return Ei&&($a.urlHandlingStrategy=Ei),Yo&&($a.routeReuseStrategy=Yo),function(Ye,Ie){Ye.errorHandler&&(Ie.errorHandler=Ye.errorHandler),Ye.malformedUriErrorHandler&&(Ie.malformedUriErrorHandler=Ye.malformedUriErrorHandler),Ye.onSameUrlNavigation&&(Ie.onSameUrlNavigation=Ye.onSameUrlNavigation),Ye.paramsInheritanceStrategy&&(Ie.paramsInheritanceStrategy=Ye.paramsInheritanceStrategy),Ye.relativeLinkResolution&&(Ie.relativeLinkResolution=Ye.relativeLinkResolution),Ye.urlUpdateStrategy&&(Ie.urlUpdateStrategy=Ye.urlUpdateStrategy)}(Xn,$a),Xn.enableTracing&&$a.events.subscribe(ns=>{var Oa,Hs;null===(Oa=console.group)||void 0===Oa||Oa.call(console,`Router Event: ${ns.constructor.name}`),console.log(ns.toString()),console.log(ns),null===(Hs=console.groupEnd)||void 0===Hs||Hs.call(console)}),$a},deps:[Yt,V,r.Ye,u.zs3,u.v3s,u.Sil,El,$i,[class{},new u.FiY],[class{},new u.FiY]]},V,{provide:tr,useFactory:function(Ye){return Ye.routerState.root},deps:[zr]},{provide:u.v3s,useClass:u.EAV},ed,Qs,Tl,{provide:$i,useValue:{enableTracing:!1}}];function Bl(){return new u.PXZ("Router",zr)}let Js=(()=>{class Ye{constructor(Ce,ot){}static forRoot(Ce,ot){return{ngModule:Ye,providers:[hl,td(Ce),{provide:xo,useFactory:Nl,deps:[[zr,new u.FiY,new u.tp0]]},{provide:$i,useValue:ot||{}},{provide:r.S$,useFactory:Mn,deps:[r.lw,[new u.tBr(r.mr),new u.FiY],$i]},{provide:$c,useFactory:md,deps:[zr,r.EM,$i]},{provide:Na,useExisting:ot&&ot.preloadingStrategy?ot.preloadingStrategy:Qs},{provide:u.PXZ,multi:!0,useFactory:Bl},[Zc,{provide:u.ip1,multi:!0,useFactory:ic,deps:[Zc]},{provide:al,useFactory:df,deps:[Zc]},{provide:u.tb,multi:!0,useExisting:al}]]}}static forChild(Ce){return{ngModule:Ye,providers:[td(Ce)]}}}return Ye.\u0275fac=function(Ce){return new(Ce||Ye)(u.LFG(xo,8),u.LFG(zr,8))},Ye.\u0275mod=u.oAB({type:Ye}),Ye.\u0275inj=u.cJS({}),Ye})();function md(Ye,Ie,Ce){return Ce.scrollOffset&&Ie.setOffset(Ce.scrollOffset),new $c(Ye,Ie,Ce)}function Mn(Ye,Ie,Ce={}){return Ce.useHash?new r.Do(Ye,Ie):new r.b0(Ye,Ie)}function Nl(Ye){return"guarded"}function td(Ye){return[{provide:u.deG,multi:!0,useValue:Ye},{provide:El,multi:!0,useValue:Ye}]}let Zc=(()=>{class Ye{constructor(Ce){this.injector=Ce,this.initNavigation=!1,this.destroyed=!1,this.resultOfPreactivationDone=new J.xQ}appInitializer(){return this.injector.get(r.V_,Promise.resolve(null)).then(()=>{if(this.destroyed)return Promise.resolve(!0);let ot=null;const Et=new Promise(Xn=>ot=Xn),qt=this.injector.get(zr),Hn=this.injector.get($i);return"disabled"===Hn.initialNavigation?(qt.setUpLocationChangeListener(),ot(!0)):"enabled"===Hn.initialNavigation||"enabledBlocking"===Hn.initialNavigation?(qt.hooks.afterPreactivation=()=>this.initNavigation?(0,y.of)(null):(this.initNavigation=!0,ot(!0),this.resultOfPreactivationDone),qt.initialNavigation()):ot(!0),Et})}bootstrapListener(Ce){const ot=this.injector.get($i),Et=this.injector.get(ed),qt=this.injector.get($c),Hn=this.injector.get(zr),Xn=this.injector.get(u.z2F);Ce===Xn.components[0]&&(("enabledNonBlocking"===ot.initialNavigation||void 0===ot.initialNavigation)&&Hn.initialNavigation(),Et.setUpPreloading(),qt.init(),Hn.resetRootComponentType(Xn.componentTypes[0]),this.resultOfPreactivationDone.next(null),this.resultOfPreactivationDone.complete())}ngOnDestroy(){this.destroyed=!0}}return Ye.\u0275fac=function(Ce){return new(Ce||Ye)(u.LFG(u.zs3))},Ye.\u0275prov=u.Yz7({token:Ye,factory:Ye.\u0275fac}),Ye})();function ic(Ye){return Ye.appInitializer.bind(Ye)}function df(Ye){return Ye.bootstrapListener.bind(Ye)}const al=new u.OlP("Router Initializer")},43155:(v,T)=>{"use strict";T.N=void 0;var r=/^([^\w]*)(javascript|data|vbscript)/im,u=/&#(\w+)(^\w|;)?/g,p=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,d=/^([^:]+):/gm,e=[".","/"];T.N=function(A){var N=function(A){return A.replace(u,function(N,L){return String.fromCharCode(L)})}(A||"").replace(p,"").trim();if(!N)return"about:blank";if(function(A){return e.indexOf(A[0])>-1}(N))return N;var L=N.match(d);return L&&r.test(L[0])?"about:blank":N}},19723:(v,T,i)=>{"use strict";i.d(T,{iM:()=>rp,qr:()=>Om,xc:()=>zg});var r=i(74788),u=i(12057),p=function(I,z){return(p=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(B,be){B.__proto__=be}||function(B,be){for(var at in be)be.hasOwnProperty(at)&&(B[at]=be[at])})(I,z)};function d(I,z){function B(){this.constructor=I}p(I,z),I.prototype=null===z?Object.create(z):(B.prototype=z.prototype,new B)}var e=function(){return(e=Object.assign||function(z){for(var B,be=1,at=arguments.length;be<at;be++)for(var $t in B=arguments[be])Object.prototype.hasOwnProperty.call(B,$t)&&(z[$t]=B[$t]);return z}).apply(this,arguments)};function _(I,z){var B="function"==typeof Symbol&&I[Symbol.iterator];if(!B)return I;var at,jn,be=B.call(I),$t=[];try{for(;(void 0===z||z-- >0)&&!(at=be.next()).done;)$t.push(at.value)}catch(fr){jn={error:fr}}finally{try{at&&!at.done&&(B=be.return)&&B.call(be)}finally{if(jn)throw jn.error}}return $t}function y(){for(var I=[],z=0;z<arguments.length;z++)I=I.concat(_(arguments[z]));return I}var A=[];Object.freeze(A);var N={};Object.freeze(N);var L={};function Z(){return"undefined"!=typeof window?window:"undefined"!=typeof global?global:L}function J(){return++on.mobxGuid}function K(I){throw ee(!1,I),"X"}function ee(I,z){if(!I)throw new Error("[mobx] "+(z||"An invariant failed, however the error is obfuscated because this is an production build."))}function H(I){var z=!1;return function(){if(!z)return z=!0,I.apply(this,arguments)}}var se=function(){};function ie(I){return null!==I&&"object"==typeof I}function he(I){if(null===I||"object"!=typeof I)return!1;var z=Object.getPrototypeOf(I);return z===Object.prototype||null===z}function ce(I,z,B){Object.defineProperty(I,z,{enumerable:!1,writable:!0,configurable:!0,value:B})}function lt(I,z,B){Object.defineProperty(I,z,{enumerable:!1,writable:!1,configurable:!0,value:B})}function Be(I,z){var B="isMobX"+I;return z.prototype[B]=!0,function(be){return ie(be)&&!0===be[B]}}function He(I){return void 0!==Z().Map&&I instanceof Z().Map}function Vt(I){return I instanceof Set}function it(I){for(var z=[];;){var B=I.next();if(B.done)break;z.push(B.value)}return z}function tn(){return"function"==typeof Symbol&&Symbol.toPrimitive||"@@toPrimitive"}function It(I){return null===I?null:"object"==typeof I?""+I:I}function Zt(){return"function"==typeof Symbol&&Symbol.iterator||"@@iterator"}function Ut(I,z){lt(I,Zt(),z)}function Bt(I){return I[Zt()]=Gt,I}function bt(){return"function"==typeof Symbol&&Symbol.toStringTag||"@@toStringTag"}function Gt(){return this}var xt=function(){function I(z){void 0===z&&(z="Atom@"+J()),this.name=z,this.isPendingUnobservation=!1,this.isBeingObserved=!1,this.observers=[],this.observersIndexes={},this.diffValue=0,this.lastAccessedBy=0,this.lowestObserverState=Pr.NOT_TRACKING}return I.prototype.onBecomeUnobserved=function(){},I.prototype.onBecomeObserved=function(){},I.prototype.reportObserved=function(){return us(this)},I.prototype.reportChanged=function(){ta(),function(I){if(I.lowestObserverState!==Pr.STALE){I.lowestObserverState=Pr.STALE;for(var z=I.observers,B=z.length;B--;){var be=z[B];be.dependenciesState===Pr.UP_TO_DATE&&(be.isTracing!==Yt.NONE&&$s(be,I),be.onBecomeStale()),be.dependenciesState=Pr.STALE}}}(this),Is()},I.prototype.toString=function(){return this.name},I}(),Xt=Be("Atom",xt);function Ur(I,z){return I===z}var Kr={identity:Ur,structural:function(I,z){return Tl(I,z)},default:function(I,z){return function(I,z){return"number"==typeof I&&"number"==typeof z&&isNaN(I)&&isNaN(z)}(I,z)||Ur(I,z)},shallow:function(I,z){return Tl(I,z,1)}},ei={},Nn={};function $n(I,z){var B=z?ei:Nn;return B[I]||(B[I]={configurable:!0,enumerable:z,get:function(){return Br(this),this[I]},set:function(be){Br(this),this[I]=be}})}function Br(I){if(!0!==I.__mobxDidRunLazyInitializers){var z=I.__mobxDecorators;if(z)for(var B in ce(I,"__mobxDidRunLazyInitializers",!0),z){var be=z[B];be.propertyCreator(I,be.prop,be.descriptor,be.decoratorTarget,be.decoratorArguments)}}}function Yr(I,z){return function(){var be,at=function(jn,fr,ui,Ro){return!0===Ro?(z(jn,fr,ui,jn,be),null):(Object.prototype.hasOwnProperty.call(jn,"__mobxDecorators")||ce(jn,"__mobxDecorators",e({},jn.__mobxDecorators)),jn.__mobxDecorators[fr]={prop:fr,propertyCreator:z,descriptor:ui,decoratorTarget:jn,decoratorArguments:be},$n(fr,I))};return fi(arguments)?(be=A,at.apply(null,arguments)):(be=Array.prototype.slice.call(arguments),at)}}function fi(I){return(2===I.length||3===I.length)&&"string"==typeof I[1]||4===I.length&&!0===I[3]}function ki(I,z,B){return xe(I)?I:Array.isArray(I)?gr.array(I,{name:B}):he(I)?gr.object(I,void 0,{name:B}):He(I)?gr.map(I,{name:B}):Vt(I)?gr.set(I,{name:B}):I}function Zr(I){return I}function Wt(I){var z=Yr(!0,function(be,at,$t,jn,fr){!function(I,z,B,be){var at=ut(I);if(Li(at)){var $t=Aa(at,{object:I,name:z,type:"add",newValue:B});if(!$t)return;B=$t.newValue}B=(at.values[z]=new Ci(B,be,at.name+"."+z,!1)).value,Object.defineProperty(I,z,function(I){return Or[I]||(Or[I]={configurable:!0,enumerable:!0,get:function(){return this.$mobx.read(this,I)},set:function(z){this.$mobx.write(this,I,z)}})}(z)),at.keys&&at.keys.push(z),function(I,z,B,be){var at=Ss(I),$t=Ws(),jn=at||$t?{type:"add",object:z,name:B,newValue:be}:null;$t&&bo(e({},jn,{name:I.name,key:B})),at&&yl(I,jn),$t&&ps()}(at,I,z,B)}(be,at,$t?$t.initializer?$t.initializer.call(be):$t.value:void 0,I)}),B=("undefined"!=typeof process&&process,z);return B.enhancer=I,B}var zn={deep:!0,name:void 0,defaultDecorator:void 0};function Gn(I){return null==I?zn:"string"==typeof I?{name:I,deep:!0}:I}function Jr(I){return I.defaultDecorator?I.defaultDecorator.enhancer:!1===I.deep?Zr:ki}Object.freeze(zn),Object.freeze({deep:!1,name:void 0,defaultDecorator:void 0});var _i=Wt(ki),wi=Wt(function(I,z,B){return null==I||Cr(I)||jl(I)||ks(I)||st(I)?I:Array.isArray(I)?gr.array(I,{name:B,deep:!1}):he(I)?gr.object(I,void 0,{name:B,deep:!1}):He(I)?gr.map(I,{name:B,deep:!1}):Vt(I)?gr.set(I,{name:B,deep:!1}):K(!1)}),br=Wt(Zr),Dr=Wt(function(I,z,B){return Tl(I,z)?z:I}),yn={box:function(I,z){arguments.length>2&&Jt("box");var B=Gn(z);return new Ci(I,Jr(B),B.name,!0,B.equals)},shallowBox:function(I,z){return arguments.length>2&&Jt("shallowBox"),gr.box(I,{name:z,deep:!1})},array:function(I,z){arguments.length>2&&Jt("array");var B=Gn(z);return new Bo(I,Jr(B),B.name)},shallowArray:function(I,z){return arguments.length>2&&Jt("shallowArray"),gr.array(I,{name:z,deep:!1})},map:function(I,z){arguments.length>2&&Jt("map");var B=Gn(z);return new El(I,Jr(B),B.name)},shallowMap:function(I,z){return arguments.length>2&&Jt("shallowMap"),gr.map(I,{name:z,deep:!1})},set:function(I,z){arguments.length>2&&Jt("set");var B=Gn(z);return new Ae(I,Jr(B),B.name)},object:function(I,z,B){"string"==typeof arguments[1]&&Jt("object");var be=Gn(B);return bc({},I,z,be)},shallowObject:function(I,z){return"string"==typeof arguments[1]&&Jt("shallowObject"),gr.object(I,{},{name:z,deep:!1})},ref:br,shallow:wi,deep:_i,struct:Dr},gr=function(I,z,B){if("string"==typeof arguments[1])return _i.apply(null,arguments);if(xe(I))return I;var be=he(I)?gr.object(I,z,B):Array.isArray(I)?gr.array(I,z):He(I)?gr.map(I,z):Vt(I)?gr.set(I,z):I;if(be!==I)return be;K(!1)};function Jt(I){K("Expected one or two arguments to observable."+I+". Did you accidentally try to use observable."+I+" as decorator?")}Object.keys(yn).forEach(function(I){return gr[I]=yn[I]});var Vn=Yr(!1,function(I,z,B,be,at){!function(I,z,B){var be=ut(I);B.name=be.name+"."+z,B.context=I,be.values[z]=new tr(B),Object.defineProperty(I,z,function(I){return zr[I]||(zr[I]={configurable:on.computedConfigurable,enumerable:!1,get:function(){return ai(this).read(this,I)},set:function(z){ai(this).write(this,I,z)}})}(z))}(I,z,e({get:B.get,set:B.set},at[0]||{}))}),mr=Vn({equals:Kr.structural}),Dn=function(z,B,be){if("string"==typeof B||null!==z&&"object"==typeof z&&1===arguments.length)return Vn.apply(null,arguments);var at="object"==typeof B?B:{};return at.get=z,at.set="function"==typeof B?B:at.set,at.name=at.name||z.name||"",new tr(at)};Dn.struct=mr;var Pr=(()=>{return(I=Pr||(Pr={}))[I.NOT_TRACKING=-1]="NOT_TRACKING",I[I.UP_TO_DATE=0]="UP_TO_DATE",I[I.POSSIBLY_STALE=1]="POSSIBLY_STALE",I[I.STALE=2]="STALE",Pr;var I})(),Yt=(()=>{return(I=Yt||(Yt={}))[I.NONE=0]="NONE",I[I.LOG=1]="LOG",I[I.BREAK=2]="BREAK",Yt;var I})(),_n=function(z){this.cause=z};function Ge(I){return I instanceof _n}function kr(I){switch(I.dependenciesState){case Pr.UP_TO_DATE:return!1;case Pr.NOT_TRACKING:case Pr.STALE:return!0;case Pr.POSSIBLY_STALE:for(var z=lo(),B=I.observing,be=B.length,at=0;at<be;at++){var $t=B[at];if(Ar($t)){if(on.disableErrorBoundaries)$t.get();else try{$t.get()}catch(jn){return vo(z),!0}if(I.dependenciesState===Pr.STALE)return vo(z),!0}}return os(I),vo(z),!1}}function An(I){var z=I.observers.length>0;on.computationDepth>0&&z&&K(!1),!on.allowStateChanges&&(z||"strict"===on.enforceActions)&&K(!1)}function Wr(I,z,B){var be=Co(!0);os(I),I.newObserving=new Array(I.observing.length+100),I.unboundDepsCount=0,I.runId=++on.runId;var $t,at=on.trackingDerivation;if(on.trackingDerivation=I,!0===on.disableErrorBoundaries)$t=z.call(B);else try{$t=z.call(B)}catch(jn){$t=new _n(jn)}return on.trackingDerivation=at,function(I){for(var z=I.observing,B=I.observing=I.newObserving,be=Pr.UP_TO_DATE,at=0,$t=I.unboundDepsCount,jn=0;jn<$t;jn++)0===(fr=B[jn]).diffValue&&(fr.diffValue=1,at!==jn&&(B[at]=fr),at++),fr.dependenciesState>be&&(be=fr.dependenciesState);for(B.length=at,I.newObserving=null,$t=z.length;$t--;)0===(fr=z[$t]).diffValue&&ls(fr,I),fr.diffValue=0;for(;at--;){var fr;1===(fr=B[at]).diffValue&&(fr.diffValue=0,Zs(fr,I))}be!==Pr.UP_TO_DATE&&(I.dependenciesState=be,I.onBecomeStale())}(I),Gi(be),$t}function ar(I){var z=I.observing;I.observing=[];for(var B=z.length;B--;)ls(z[B],I);I.dependenciesState=Pr.NOT_TRACKING}function Wi(I){var z=lo(),B=I();return vo(z),B}function lo(){var I=on.trackingDerivation;return on.trackingDerivation=null,I}function vo(I){on.trackingDerivation=I}function Co(I){var z=on.allowStateReads;return on.allowStateReads=I,z}function Gi(I){on.allowStateReads=I}function os(I){if(I.dependenciesState!==Pr.UP_TO_DATE){I.dependenciesState=Pr.UP_TO_DATE;for(var z=I.observing,B=z.length;B--;)z[B].lowestObserverState=Pr.UP_TO_DATE}}var jo=0,To=1;function Mi(I,z){var B=function(){return li(I,z,this,arguments)};return B.isMobxAction=!0,B}function li(I,z,B,be){var at=function(I,z,B){var be=Ws()&&!!I,at=0;if(be){at=Date.now();var $t=B&&B.length||0,jn=new Array($t);if($t>0)for(var fr=0;fr<$t;fr++)jn[fr]=B[fr];bo({type:"action",name:I,object:z,arguments:jn})}var ui=lo();ta();var Ms={prevDerivation:ui,prevAllowStateChanges:er(!0),prevAllowStateReads:Co(!0),notifySpy:be,startTime:at,actionId:To++,parentActionId:jo};return jo=Ms.actionId,Ms}(I,B,be);try{return z.apply(B,be)}catch($t){throw at.error=$t,$t}finally{!function(I){jo!==I.actionId&&K("invalid action stack. did you forget to finish an action?"),jo=I.parentActionId,void 0!==I.error&&(on.suppressReactionErrors=!0),ri(I.prevAllowStateChanges),Gi(I.prevAllowStateReads),Is(),vo(I.prevDerivation),I.notifySpy&&ps({time:Date.now()-I.startTime}),on.suppressReactionErrors=!1}(at)}}function er(I){var z=on.allowStateChanges;return on.allowStateChanges=I,z}function ri(I){on.allowStateChanges=I}var Ci=function(I){function z(B,be,at,$t,jn){void 0===at&&(at="ObservableValue@"+J()),void 0===$t&&($t=!0),void 0===jn&&(jn=Kr.default);var fr=I.call(this,at)||this;return fr.enhancer=be,fr.name=at,fr.equals=jn,fr.hasUnreportedChange=!1,fr.value=be(B,void 0,at),$t&&Ws()&&Po({type:"create",name:fr.name,newValue:""+fr.value}),fr}return d(z,I),z.prototype.dehanceValue=function(B){return void 0!==this.dehancer?this.dehancer(B):B},z.prototype.set=function(B){var be=this.value;if((B=this.prepareNewValue(B))!==on.UNCHANGED){var at=Ws();at&&bo({type:"update",name:this.name,newValue:B,oldValue:be}),this.setNewValue(B),at&&ps()}},z.prototype.prepareNewValue=function(B){if(An(this),Li(this)){var be=Aa(this,{object:this,type:"update",newValue:B});if(!be)return on.UNCHANGED;B=be.newValue}return B=this.enhancer(B,this.value,this.name),this.equals(this.value,B)?on.UNCHANGED:B},z.prototype.setNewValue=function(B){var be=this.value;this.value=B,this.reportChanged(),Ss(this)&&yl(this,{type:"update",object:this,newValue:B,oldValue:be})},z.prototype.get=function(){return this.reportObserved(),this.dehanceValue(this.value)},z.prototype.intercept=function(B){return sa(this,B)},z.prototype.observe=function(B,be){return be&&B({object:this,type:"update",newValue:this.value,oldValue:void 0}),$u(this,B)},z.prototype.toJSON=function(){return this.get()},z.prototype.toString=function(){return this.name+"["+this.value+"]"},z.prototype.valueOf=function(){return It(this.get())},z}(xt);Ci.prototype[tn()]=Ci.prototype.valueOf,Be("ObservableValue",Ci);var tr=function(){function I(z){this.dependenciesState=Pr.NOT_TRACKING,this.observing=[],this.newObserving=null,this.isBeingObserved=!1,this.isPendingUnobservation=!1,this.observers=[],this.observersIndexes={},this.diffValue=0,this.runId=0,this.lastAccessedBy=0,this.lowestObserverState=Pr.UP_TO_DATE,this.unboundDepsCount=0,this.__mapid="#"+J(),this.value=new _n(null),this.isComputing=!1,this.isRunningSetter=!1,this.isTracing=Yt.NONE,this.derivation=z.get,this.name=z.name||"ComputedValue@"+J(),z.set&&(this.setter=Mi(this.name+"-setter",z.set)),this.equals=z.equals||(z.compareStructural||z.struct?Kr.structural:Kr.default),this.scope=z.context,this.requiresReaction=!!z.requiresReaction,this.keepAlive=!!z.keepAlive}return I.prototype.onBecomeStale=function(){!function(I){if(I.lowestObserverState===Pr.UP_TO_DATE){I.lowestObserverState=Pr.POSSIBLY_STALE;for(var z=I.observers,B=z.length;B--;){var be=z[B];be.dependenciesState===Pr.UP_TO_DATE&&(be.dependenciesState=Pr.POSSIBLY_STALE,be.isTracing!==Yt.NONE&&$s(be,I),be.onBecomeStale())}}}(this)},I.prototype.onBecomeUnobserved=function(){},I.prototype.onBecomeObserved=function(){},I.prototype.get=function(){this.isComputing&&K("Cycle detected in computation "+this.name+": "+this.derivation),0!==on.inBatch||0!==this.observers.length||this.keepAlive?(us(this),kr(this)&&this.trackAndCompute()&&function(I){if(I.lowestObserverState!==Pr.STALE){I.lowestObserverState=Pr.STALE;for(var z=I.observers,B=z.length;B--;){var be=z[B];be.dependenciesState===Pr.POSSIBLY_STALE?be.dependenciesState=Pr.STALE:be.dependenciesState===Pr.UP_TO_DATE&&(I.lowestObserverState=Pr.UP_TO_DATE)}}}(this)):kr(this)&&(this.warnAboutUntrackedRead(),ta(),this.value=this.computeValue(!1),Is());var z=this.value;if(Ge(z))throw z.cause;return z},I.prototype.peek=function(){var z=this.computeValue(!1);if(Ge(z))throw z.cause;return z},I.prototype.set=function(z){if(this.setter){ee(!this.isRunningSetter,"The setter of computed value '"+this.name+"' is trying to update itself. Did you intend to update an _observable_ value, instead of the computed property?"),this.isRunningSetter=!0;try{this.setter.call(this.scope,z)}finally{this.isRunningSetter=!1}}else ee(!1,!1)},I.prototype.trackAndCompute=function(){Ws()&&Po({object:this.scope,type:"compute",name:this.name});var z=this.value,B=this.dependenciesState===Pr.NOT_TRACKING,be=this.computeValue(!0),at=B||Ge(z)||Ge(be)||!this.equals(z,be);return at&&(this.value=be),at},I.prototype.computeValue=function(z){var B;if(this.isComputing=!0,on.computationDepth++,z)B=Wr(this,this.derivation,this.scope);else if(!0===on.disableErrorBoundaries)B=this.derivation.call(this.scope);else try{B=this.derivation.call(this.scope)}catch(be){B=new _n(be)}return on.computationDepth--,this.isComputing=!1,B},I.prototype.suspend=function(){this.keepAlive||(ar(this),this.value=void 0)},I.prototype.observe=function(z,B){var be=this,at=!0,$t=void 0;return ti(function(){var jn=be.get();if(!at||B){var fr=lo();z({type:"update",object:be,newValue:jn,oldValue:$t}),vo(fr)}at=!1,$t=jn})},I.prototype.warnAboutUntrackedRead=function(){},I.prototype.toJSON=function(){return this.get()},I.prototype.toString=function(){return this.name+"["+this.derivation.toString()+"]"},I.prototype.valueOf=function(){return It(this.get())},I}();tr.prototype[tn()]=tr.prototype.valueOf;var I,Ar=Be("ComputedValue",tr),_t=function(){this.version=5,this.UNCHANGED={},this.trackingDerivation=null,this.computationDepth=0,this.runId=0,this.mobxGuid=0,this.inBatch=0,this.pendingUnobservations=[],this.pendingReactions=[],this.isRunningReactions=!1,this.allowStateChanges=!0,this.allowStateReads=!0,this.enforceActions=!1,this.spyListeners=[],this.globalReactionErrorHandlers=[],this.computedRequiresReaction=!1,this.reactionRequiresObservable=!1,this.observableRequiresReaction=!1,this.computedConfigurable=!1,this.disableErrorBoundaries=!1,this.suppressReactionErrors=!1},mt=!0,on=((I=Z()).__mobxInstanceCount>0&&!I.__mobxGlobals&&(mt=!1),I.__mobxGlobals&&I.__mobxGlobals.version!==(new _t).version&&(mt=!1),mt?I.__mobxGlobals?(I.__mobxInstanceCount+=1,I.__mobxGlobals.UNCHANGED||(I.__mobxGlobals.UNCHANGED={}),I.__mobxGlobals):(I.__mobxInstanceCount=1,I.__mobxGlobals=new _t):(setTimeout(function(){K("There are multiple, different versions of MobX active. Make sure MobX is loaded only once or use `configure({ isolateGlobalState: true })`")},1),new _t));function Zs(I,z){var B=I.observers.length;B&&(I.observersIndexes[z.__mapid]=B),I.observers[B]=z,I.lowestObserverState>z.dependenciesState&&(I.lowestObserverState=z.dependenciesState)}function ls(I,z){if(1===I.observers.length)I.observers.length=0,La(I);else{var B=I.observers,be=I.observersIndexes,at=B.pop();if(at!==z){var $t=be[z.__mapid]||0;$t?be[at.__mapid]=$t:delete be[at.__mapid],B[$t]=at}delete be[z.__mapid]}}function La(I){!1===I.isPendingUnobservation&&(I.isPendingUnobservation=!0,on.pendingUnobservations.push(I))}function ta(){on.inBatch++}function Is(){if(0==--on.inBatch){fs();for(var I=on.pendingUnobservations,z=0;z<I.length;z++){var B=I[z];B.isPendingUnobservation=!1,0===B.observers.length&&(B.isBeingObserved&&(B.isBeingObserved=!1,B.onBecomeUnobserved()),B instanceof tr&&B.suspend())}on.pendingUnobservations=[]}}function us(I){var z=on.trackingDerivation;return null!==z?(z.runId!==I.lastAccessedBy&&(I.lastAccessedBy=z.runId,z.newObserving[z.unboundDepsCount++]=I,I.isBeingObserved||(I.isBeingObserved=!0,I.onBecomeObserved())),!0):(0===I.observers.length&&on.inBatch>0&&La(I),!1)}function $s(I,z){if(console.log("[mobx.trace] '"+I.name+"' is invalidated due to a change in: '"+z.name+"'"),I.isTracing===Yt.BREAK){var B=[];da(function(I,z){return qc(hr(I,void 0))}(I),B,1),new Function("debugger;\n/*\nTracing '"+I.name+"'\n\nYou are entering this break point because derivation '"+I.name+"' is being traced and '"+z.name+"' is now forcing it to update.\nJust follow the stacktrace you should now see in the devtools to see precisely what piece of your code is causing this update\nThe stackframe you are looking for is at least ~6-8 stack-frames up.\n\n"+(I instanceof tr?I.derivation.toString().replace(/[*]\//g,"/"):"")+"\n\nThe dependencies for this derivation are:\n\n"+B.join("\n")+"\n*/\n ")()}}function da(I,z,B){z.length>=1e3?z.push("(and many more)"):(z.push(""+new Array(B).join("\t")+I.name),I.dependencies&&I.dependencies.forEach(function(be){return da(be,z,B+1)}))}var Il=function(){function I(z,B,be,at){void 0===z&&(z="Reaction@"+J()),void 0===at&&(at=!1),this.name=z,this.onInvalidate=B,this.errorHandler=be,this.requiresObservable=at,this.observing=[],this.newObserving=[],this.dependenciesState=Pr.NOT_TRACKING,this.diffValue=0,this.runId=0,this.unboundDepsCount=0,this.__mapid="#"+J(),this.isDisposed=!1,this._isScheduled=!1,this._isTrackPending=!1,this._isRunning=!1,this.isTracing=Yt.NONE}return I.prototype.onBecomeStale=function(){this.schedule()},I.prototype.schedule=function(){this._isScheduled||(this._isScheduled=!0,on.pendingReactions.push(this),fs())},I.prototype.isScheduled=function(){return this._isScheduled},I.prototype.runReaction=function(){if(!this.isDisposed){if(ta(),this._isScheduled=!1,kr(this)){this._isTrackPending=!0;try{this.onInvalidate(),this._isTrackPending&&Ws()&&Po({name:this.name,type:"scheduled-reaction"})}catch(z){this.reportExceptionInDerivation(z)}}Is()}},I.prototype.track=function(z){ta();var be,B=Ws();B&&(be=Date.now(),bo({name:this.name,type:"reaction"})),this._isRunning=!0;var at=Wr(this,z,void 0);this._isRunning=!1,this._isTrackPending=!1,this.isDisposed&&ar(this),Ge(at)&&this.reportExceptionInDerivation(at.cause),B&&ps({time:Date.now()-be}),Is()},I.prototype.reportExceptionInDerivation=function(z){var B=this;if(this.errorHandler)this.errorHandler(z,this);else{if(on.disableErrorBoundaries)throw z;var be="[mobx] Encountered an uncaught exception that was thrown by a reaction or observer component, in: '"+this+"'";on.suppressReactionErrors?console.warn("[mobx] (error in reaction '"+this.name+"' suppressed, fix error of causing action below)"):console.error(be,z),Ws()&&Po({type:"error",name:this.name,message:be,error:""+z}),on.globalReactionErrorHandlers.forEach(function(at){return at(z,B)})}},I.prototype.dispose=function(){this.isDisposed||(this.isDisposed=!0,this._isRunning||(ta(),ar(this),Is()))},I.prototype.getDisposer=function(){var z=this.dispose.bind(this);return z.$mobx=this,z},I.prototype.toString=function(){return"Reaction["+this.name+"]"},I.prototype.trace=function(z){void 0===z&&(z=!1),function(){for(var I=[],z=0;z<arguments.length;z++)I[z]=arguments[z];var B=!1;"boolean"==typeof I[I.length-1]&&(B=I.pop());var be=Fc(I);if(!be)return K(!1);be.isTracing===Yt.NONE&&console.log("[mobx.trace] '"+be.name+"' tracing enabled"),be.isTracing=B?Yt.BREAK:Yt.LOG}(this,z)},I}();function fs(){on.inBatch>0||on.isRunningReactions||function(I){I()}(Ca)}function Ca(){on.isRunningReactions=!0;for(var I=on.pendingReactions,z=0;I.length>0;){100==++z&&(console.error("Reaction doesn't converge to a stable state after 100 iterations. Probably there is a cycle in the reactive function: "+I[0]),I.splice(0));for(var B=I.splice(0),be=0,at=B.length;be<at;be++)B[be].runReaction()}on.isRunningReactions=!1}var Ra=Be("Reaction",Il);function Ws(){return!!on.spyListeners.length}function Po(I){if(on.spyListeners.length)for(var z=on.spyListeners,B=0,be=z.length;B<be;B++)z[B](I)}function bo(I){Po(e({},I,{spyReportStart:!0}))}var Ls={spyReportEnd:!0};function ps(I){Po(I?e({},I,{spyReportEnd:!0}):Ls)}function $r(){K(!1)}function to(I){return function(z,B,be){if(be){if(be.value)return{value:Mi(I,be.value),enumerable:!1,configurable:!0,writable:!0};var at=be.initializer;return{enumerable:!1,configurable:!0,writable:!0,initializer:function(){return Mi(I,at.call(this))}}}return tt(I).apply(this,arguments)}}function tt(I){return function(z,B,be){Object.defineProperty(z,B,{configurable:!0,enumerable:!1,get:function(){},set:function(at){ce(this,B,ne(I,at))}})}}var ne=function(z,B,be,at){return 1===arguments.length&&"function"==typeof z?Mi(z.name||"<unnamed action>",z):2===arguments.length&&"function"==typeof B?Mi(z,B):1===arguments.length&&"string"==typeof z?to(z):!0!==at?to(B).apply(null,arguments):void(z[B]=Mi(z.name||B,be.value))};function an(I,z,B){ce(I,z,Mi(z,B.bind(I)))}function ti(I,z){void 0===z&&(z=N);var at,B=z&&z.name||I.name||"Autorun@"+J();if(z.scheduler||z.delay){var $t=xi(z),jn=!1;at=new Il(B,function(){jn||(jn=!0,$t(function(){jn=!1,at.isDisposed||at.track(fr)}))},z.onError,z.requiresObservable)}else at=new Il(B,function(){this.track(fr)},z.onError,z.requiresObservable);function fr(){I(at)}return at.schedule(),at.getDisposer()}ne.bound=function(I,z,B,be){return!0===be?(an(I,z,B.value),null):B?{configurable:!0,enumerable:!1,get:function(){return an(this,z,B.value||B.initializer.call(this)),this[z]},set:$r}:{enumerable:!1,configurable:!0,set:function(at){an(this,z,at)},get:function(){}}};var pi=function(I){return I()};function xi(I){return I.scheduler?I.scheduler:I.delay?function(z){return setTimeout(z,I.delay)}:pi}function ts(I,z,B){void 0===B&&(B=N),"boolean"==typeof B&&(B={fireImmediately:B});var Ro,be=B.name||"Reaction@"+J(),at=ne(be,B.onError?function(I,z){return function(){try{return z.apply(this,arguments)}catch(B){I.call(this,B)}}}(B.onError,z):z),$t=!B.scheduler&&!B.delay,jn=xi(B),fr=!0,ui=!1,Vo=B.compareStructural?Kr.structural:B.equals||Kr.default,Ms=new Il(be,function(){fr||$t?Dl():ui||(ui=!0,jn(Dl))},B.onError,B.requiresObservable);function Dl(){if(ui=!1,!Ms.isDisposed){var ql=!1;Ms.track(function(){var eu=I(Ms);ql=fr||!Vo(Ro,eu),Ro=eu}),fr&&B.fireImmediately&&at(Ro,Ms),!fr&&!0===ql&&at(Ro,Ms),fr&&(fr=!1)}}return Ms.schedule(),Ms.getDisposer()}function Eo(I,z,B){return ba("onBecomeUnobserved",I,z,B)}function ba(I,z,B,be){var at="function"==typeof be?hr(z,B):hr(z),$t="function"==typeof be?be:B,jn=at[I];return"function"!=typeof jn?K(!1):(at[I]=function(){jn.call(this),$t.call(this)},function(){at[I]=jn})}function bc(I,z,B,be){var $t=(be=Gn(be)).defaultDecorator||(!1===be.deep?br:_i);Br(I),ut(I,be.name,$t.enhancer),ta();try{for(var at in z){var jn=Object.getOwnPropertyDescriptor(z,at),ui=(B&&at in B?B[at]:jn.get?Vn:$t)(I,at,jn,!0);ui&&Object.defineProperty(I,at,ui)}}finally{Is()}return I}function qc(I){var z={name:I.name};return I.observing&&I.observing.length>0&&(z.dependencies=function(I){var z=[];return I.forEach(function(B){-1===z.indexOf(B)&&z.push(B)}),z}(I.observing).map(qc)),z}function Me(I,z){if(null==I)return!1;if(void 0!==z){if(Cr(I)){var B=I.$mobx;return B.values&&!!B.values[z]}return!1}return Cr(I)||!!I.$mobx||Xt(I)||Ra(I)||Ar(I)}function xe(I){return 1!==arguments.length&&K(!1),Me(I)}function Fc(I){switch(I.length){case 0:return on.trackingDerivation;case 1:return hr(I[0]);case 2:return hr(I[0],I[1])}}function Cu(I,z){void 0===z&&(z=void 0),ta();try{return I.apply(z)}finally{Is()}}function Li(I){return void 0!==I.interceptors&&I.interceptors.length>0}function sa(I,z){var B=I.interceptors||(I.interceptors=[]);return B.push(z),H(function(){var be=B.indexOf(z);-1!==be&&B.splice(be,1)})}function Aa(I,z){var B=lo();try{var be=I.interceptors;if(be)for(var at=0,$t=be.length;at<$t&&(ee(!(z=be[at](z))||z.type,"Intercept handlers should return nothing or a change object"),z);at++);return z}finally{vo(B)}}function Ss(I){return void 0!==I.changeListeners&&I.changeListeners.length>0}function $u(I,z){var B=I.changeListeners||(I.changeListeners=[]);return B.push(z),H(function(){var be=B.indexOf(z);-1!==be&&B.splice(be,1)})}function yl(I,z){var B=lo(),be=I.changeListeners;if(be){for(var at=0,$t=(be=be.slice()).length;at<$t;at++)be[at](z);vo(B)}}var yu=function(){var I=!1,z={};return Object.defineProperty(z,"0",{set:function(){I=!0}}),Object.create(z)[0]=1,!1===I}(),lu=0,js=function(){};(function(I,z){void 0!==Object.setPrototypeOf?Object.setPrototypeOf(I.prototype,z):void 0!==I.prototype.__proto__?I.prototype.__proto__=z:I.prototype=z})(js,Array.prototype),Object.isFrozen(Array)&&["constructor","push","shift","concat","pop","unshift","replace","find","findIndex","splice","reverse","sort"].forEach(function(I){Object.defineProperty(js.prototype,I,{configurable:!0,writable:!0,value:Array.prototype[I]})});var Uu=function(){function I(z,B,be,at){this.array=be,this.owned=at,this.values=[],this.lastKnownLength=0,this.atom=new xt(z||"ObservableArray@"+J()),this.enhancer=function($t,jn){return B($t,jn,z+"[..]")}}return I.prototype.dehanceValue=function(z){return void 0!==this.dehancer?this.dehancer(z):z},I.prototype.dehanceValues=function(z){return void 0!==this.dehancer&&z.length>0?z.map(this.dehancer):z},I.prototype.intercept=function(z){return sa(this,z)},I.prototype.observe=function(z,B){return void 0===B&&(B=!1),B&&z({object:this.array,type:"splice",index:0,added:this.values.slice(),addedCount:this.values.length,removed:[],removedCount:0}),$u(this,z)},I.prototype.getArrayLength=function(){return this.atom.reportObserved(),this.values.length},I.prototype.setArrayLength=function(z){if("number"!=typeof z||z<0)throw new Error("[mobx.array] Out of range: "+z);var B=this.values.length;if(z!==B)if(z>B){for(var be=new Array(z-B),at=0;at<z-B;at++)be[at]=void 0;this.spliceWithArray(B,0,be)}else this.spliceWithArray(z,B-z)},I.prototype.updateArrayLength=function(z,B){if(z!==this.lastKnownLength)throw new Error("[mobx] Modification exception: the internal structure of an observable array was changed. Did you use peek() to change it?");this.lastKnownLength+=B,B>0&&z+B+1>lu&&pu(z+B+1)},I.prototype.spliceWithArray=function(z,B,be){var at=this;An(this.atom);var $t=this.values.length;if(void 0===z?z=0:z>$t?z=$t:z<0&&(z=Math.max(0,$t+z)),B=1===arguments.length?$t-z:null==B?0:Math.max(0,Math.min(B,$t-z)),void 0===be&&(be=A),Li(this)){var jn=Aa(this,{object:this.array,type:"splice",index:z,removedCount:B,added:be});if(!jn)return A;B=jn.removedCount,be=jn.added}var fr=(be=0===be.length?be:be.map(function(Ro){return at.enhancer(Ro,void 0)})).length-B;this.updateArrayLength($t,fr);var ui=this.spliceItemsIntoValues(z,B,be);return(0!==B||0!==be.length)&&this.notifyArraySplice(z,be,ui),this.dehanceValues(ui)},I.prototype.spliceItemsIntoValues=function(z,B,be){var at;if(be.length<1e4)return(at=this.values).splice.apply(at,y([z,B],be));var $t=this.values.slice(z,z+B);return this.values=this.values.slice(0,z).concat(be,this.values.slice(z+B)),$t},I.prototype.notifyArrayChildUpdate=function(z,B,be){var at=!this.owned&&Ws(),$t=Ss(this),jn=$t||at?{object:this.array,type:"update",index:z,newValue:B,oldValue:be}:null;at&&bo(e({},jn,{name:this.atom.name})),this.atom.reportChanged(),$t&&yl(this,jn),at&&ps()},I.prototype.notifyArraySplice=function(z,B,be){var at=!this.owned&&Ws(),$t=Ss(this),jn=$t||at?{object:this.array,type:"splice",index:z,removed:be,added:B,removedCount:be.length,addedCount:B.length}:null;at&&bo(e({},jn,{name:this.atom.name})),this.atom.reportChanged(),$t&&yl(this,jn),at&&ps()},I}(),Bo=function(I){function z(B,be,at,$t){void 0===at&&(at="ObservableArray@"+J()),void 0===$t&&($t=!1);var jn=I.call(this)||this,fr=new Uu(at,be,jn,$t);if(lt(jn,"$mobx",fr),B&&B.length){var ui=er(!0);jn.spliceWithArray(0,0,B),ri(ui)}return yu&&Object.defineProperty(fr.array,"0",uu),jn}return d(z,I),z.prototype.intercept=function(B){return this.$mobx.intercept(B)},z.prototype.observe=function(B,be){return void 0===be&&(be=!1),this.$mobx.observe(B,be)},z.prototype.clear=function(){return this.splice(0)},z.prototype.concat=function(){for(var B=[],be=0;be<arguments.length;be++)B[be]=arguments[be];return this.$mobx.atom.reportObserved(),Array.prototype.concat.apply(this.peek(),B.map(function(at){return jl(at)?at.peek():at}))},z.prototype.replace=function(B){return this.$mobx.spliceWithArray(0,this.$mobx.values.length,B)},z.prototype.toJS=function(){return this.slice()},z.prototype.toJSON=function(){return this.toJS()},z.prototype.peek=function(){return this.$mobx.atom.reportObserved(),this.$mobx.dehanceValues(this.$mobx.values)},z.prototype.find=function(B,be,at){void 0===at&&(at=0);var $t=this.findIndex.apply(this,arguments);return-1===$t?void 0:this.get($t)},z.prototype.findIndex=function(B,be,at){void 0===at&&(at=0);for(var $t=this.peek(),jn=$t.length,fr=at;fr<jn;fr++)if(B.call(be,$t[fr],fr,this))return fr;return-1},z.prototype.splice=function(B,be){for(var at=[],$t=2;$t<arguments.length;$t++)at[$t-2]=arguments[$t];switch(arguments.length){case 0:return[];case 1:return this.$mobx.spliceWithArray(B);case 2:return this.$mobx.spliceWithArray(B,be)}return this.$mobx.spliceWithArray(B,be,at)},z.prototype.spliceWithArray=function(B,be,at){return this.$mobx.spliceWithArray(B,be,at)},z.prototype.push=function(){for(var B=[],be=0;be<arguments.length;be++)B[be]=arguments[be];var at=this.$mobx;return at.spliceWithArray(at.values.length,0,B),at.values.length},z.prototype.pop=function(){return this.splice(Math.max(this.$mobx.values.length-1,0),1)[0]},z.prototype.shift=function(){return this.splice(0,1)[0]},z.prototype.unshift=function(){for(var B=[],be=0;be<arguments.length;be++)B[be]=arguments[be];var at=this.$mobx;return at.spliceWithArray(0,0,B),at.values.length},z.prototype.reverse=function(){var B=this.slice();return B.reverse.apply(B,arguments)},z.prototype.sort=function(B){var be=this.slice();return be.sort.apply(be,arguments)},z.prototype.remove=function(B){var be=this.$mobx.dehanceValues(this.$mobx.values).indexOf(B);return be>-1&&(this.splice(be,1),!0)},z.prototype.move=function(B,be){function at(fr){if(fr<0)throw new Error("[mobx.array] Index out of bounds: "+fr+" is negative");var ui=this.$mobx.values.length;if(fr>=ui)throw new Error("[mobx.array] Index out of bounds: "+fr+" is not smaller than "+ui)}if(at.call(this,B),at.call(this,be),B!==be){var jn,$t=this.$mobx.values;jn=B<be?y($t.slice(0,B),$t.slice(B+1,be+1),[$t[B]],$t.slice(be+1)):y($t.slice(0,be),[$t[B]],$t.slice(be,B),$t.slice(B+1)),this.replace(jn)}},z.prototype.get=function(B){var be=this.$mobx;if(be){if(B<be.values.length)return be.atom.reportObserved(),be.dehanceValue(be.values[B]);console.warn("[mobx.array] Attempt to read an array index ("+B+") that is out of bounds ("+be.values.length+"). Please check length first. Out of bound indices will not be tracked by MobX")}},z.prototype.set=function(B,be){var at=this.$mobx,$t=at.values;if(B<$t.length){An(at.atom);var jn=$t[B];if(Li(at)){var fr=Aa(at,{type:"update",object:this,index:B,newValue:be});if(!fr)return;be=fr.newValue}(be=at.enhancer(be,jn))!==jn&&($t[B]=be,at.notifyArrayChildUpdate(B,be,jn))}else{if(B!==$t.length)throw new Error("[mobx.array] Index out of bounds, "+B+" is larger than "+$t.length);at.spliceWithArray(B,0,[be])}},z}(js);Ut(Bo.prototype,function(){this.$mobx.atom.reportObserved();var I=this,z=0;return Bt({next:function(){return z<I.length?{value:I[z++],done:!1}:{done:!0,value:void 0}}})}),Object.defineProperty(Bo.prototype,"length",{enumerable:!1,configurable:!0,get:function(){return this.$mobx.getArrayLength()},set:function(I){this.$mobx.setArrayLength(I)}}),ce(Bo.prototype,bt(),"Array"),["every","filter","forEach","indexOf","join","lastIndexOf","map","reduce","reduceRight","slice","some","toString","toLocaleString"].forEach(function(I){var z=Array.prototype[I];ee("function"==typeof z,"Base function not defined on Array prototype: '"+I+"'"),ce(Bo.prototype,I,function(){return z.apply(this.peek(),arguments)})}),function(I,z){for(var B=0;B<z.length;B++)ce(I,z[B],I[z[B]])}(Bo.prototype,["constructor","intercept","observe","clear","concat","get","replace","toJS","toJSON","peek","find","findIndex","splice","spliceWithArray","push","pop","set","shift","unshift","reverse","sort","remove","move","toString","toLocaleString"]);var uu=wr(0);function wr(I){return{enumerable:!1,configurable:!1,get:function(){return this.get(I)},set:function(z){this.set(I,z)}}}function fa(I){Object.defineProperty(Bo.prototype,""+I,wr(I))}function pu(I){for(var z=lu;z<I;z++)fa(z);lu=I}pu(1e3);var aa=Be("ObservableArrayAdministration",Uu);function jl(I){return ie(I)&&aa(I.$mobx)}var bl={},El=function(){function I(z,B,be){if(void 0===B&&(B=ki),void 0===be&&(be="ObservableMap@"+J()),this.enhancer=B,this.name=be,this.$mobx=bl,this._keys=new Bo(void 0,Zr,this.name+".keys()",!0),"function"!=typeof Map)throw new Error("mobx.map requires Map polyfill for the current browser. Check babel-polyfill or core-js/es6/map.js");this._data=new Map,this._hasMap=new Map,this.merge(z)}return I.prototype._has=function(z){return this._data.has(z)},I.prototype.has=function(z){var B=this;if(!on.trackingDerivation)return this._has(z);var be=this._hasMap.get(z);if(!be){var at=be=new Ci(this._has(z),Zr,this.name+"."+Ul(z)+"?",!1);this._hasMap.set(z,at),Eo(at,function(){return B._hasMap.delete(z)})}return be.get()},I.prototype.set=function(z,B){var be=this._has(z);if(Li(this)){var at=Aa(this,{type:be?"update":"add",object:this,newValue:B,name:z});if(!at)return this;B=at.newValue}return be?this._updateValue(z,B):this._addValue(z,B),this},I.prototype.delete=function(z){var B=this;if(Li(this)&&!(be=Aa(this,{type:"delete",object:this,name:z})))return!1;if(this._has(z)){var at=Ws(),$t=Ss(this),be=$t||at?{type:"delete",object:this,oldValue:this._data.get(z).value,name:z}:null;return at&&bo(e({},be,{name:this.name,key:z})),Cu(function(){B._keys.remove(z),B._updateHasMapEntry(z,!1),B._data.get(z).setNewValue(void 0),B._data.delete(z)}),$t&&yl(this,be),at&&ps(),!0}return!1},I.prototype._updateHasMapEntry=function(z,B){var be=this._hasMap.get(z);be&&be.setNewValue(B)},I.prototype._updateValue=function(z,B){var be=this._data.get(z);if((B=be.prepareNewValue(B))!==on.UNCHANGED){var at=Ws(),$t=Ss(this),jn=$t||at?{type:"update",object:this,oldValue:be.value,name:z,newValue:B}:null;at&&bo(e({},jn,{name:this.name,key:z})),be.setNewValue(B),$t&&yl(this,jn),at&&ps()}},I.prototype._addValue=function(z,B){var be=this;Cu(function(){var fr=new Ci(B,be.enhancer,be.name+"."+Ul(z),!1);be._data.set(z,fr),B=fr.value,be._updateHasMapEntry(z,!0),be._keys.push(z)});var at=Ws(),$t=Ss(this),jn=$t||at?{type:"add",object:this,name:z,newValue:B}:null;at&&bo(e({},jn,{name:this.name,key:z})),$t&&yl(this,jn),at&&ps()},I.prototype.get=function(z){return this.has(z)?this.dehanceValue(this._data.get(z).get()):this.dehanceValue(void 0)},I.prototype.dehanceValue=function(z){return void 0!==this.dehancer?this.dehancer(z):z},I.prototype.keys=function(){return this._keys[Zt()]()},I.prototype.values=function(){var z=this,B=0;return Bt({next:function(){return B<z._keys.length?{value:z.get(z._keys[B++]),done:!1}:{value:void 0,done:!0}}})},I.prototype.entries=function(){var z=this,B=0;return Bt({next:function(){if(B<z._keys.length){var be=z._keys[B++];return{value:[be,z.get(be)],done:!1}}return{done:!0}}})},I.prototype.forEach=function(z,B){var be=this;this._keys.forEach(function(at){return z.call(B,be.get(at),at,be)})},I.prototype.merge=function(z){var B=this;return ks(z)&&(z=z.toJS()),Cu(function(){he(z)?Object.keys(z).forEach(function(be){return B.set(be,z[be])}):Array.isArray(z)?z.forEach(function(be){var at=_(be,2);return B.set(at[0],at[1])}):He(z)?z.constructor!==Map?K("Cannot initialize from classes that inherit from Map: "+z.constructor.name):z.forEach(function(be,at){return B.set(at,be)}):null!=z&&K("Cannot initialize map from "+z)}),this},I.prototype.clear=function(){var z=this;Cu(function(){Wi(function(){z._keys.slice().forEach(function(B){return z.delete(B)})})})},I.prototype.replace=function(z){var B=this;return Cu(function(){for(var be=function(I){return He(I)||ks(I)?I:Array.isArray(I)?new Map(I):he(I)?new Map(Object.entries(I)):K("Cannot convert to map from '"+I+"'")}(z),at=B._keys,$t=Array.from(be.keys()),jn=!1,fr=0;fr<at.length;fr++){var ui=at[fr];at.length===$t.length&&ui!==$t[fr]&&(jn=!0),be.has(ui)||(jn=!0,B.delete(ui))}be.forEach(function(Ro,Vo){B._data.has(Vo)||(jn=!0),B.set(Vo,Ro)}),jn&&B._keys.replace($t)}),this},Object.defineProperty(I.prototype,"size",{get:function(){return this._keys.length},enumerable:!0,configurable:!0}),I.prototype.toPOJO=function(){var z=this,B={};return this._keys.forEach(function(be){return B["symbol"==typeof be?be:Ul(be)]=z.get(be)}),B},I.prototype.toJS=function(){var z=this,B=new Map;return this._keys.forEach(function(be){return B.set(be,z.get(be))}),B},I.prototype.toJSON=function(){return this.toPOJO()},I.prototype.toString=function(){var z=this;return this.name+"[{ "+this._keys.map(function(B){return Ul(B)+": "+z.get(B)}).join(", ")+" }]"},I.prototype.observe=function(z,B){return $u(this,z)},I.prototype.intercept=function(z){return sa(this,z)},I}();function Ul(I){return I&&I.toString?I.toString():new String(I).toString()}Ut(El.prototype,function(){return this.entries()}),lt(El.prototype,bt(),"Map");var ks=Be("ObservableMap",El),V={},Ae=function(){function I(z,B,be){if(void 0===B&&(B=ki),void 0===be&&(be="ObservableSet@"+J()),this.name=be,this.$mobx=V,this._data=new Set,this._atom=function(I,z,B){void 0===z&&(z=se),void 0===B&&(B=se);var be=new xt(I);return function(I,z,B){ba("onBecomeObserved",I,z,void 0)}(be,z),Eo(be,B),be}(this.name),"function"!=typeof Set)throw new Error("mobx.set requires Set polyfill for the current browser. Check babel-polyfill or core-js/es6/set.js");this.enhancer=function(at,$t){return B(at,$t,be)},z&&this.replace(z)}return I.prototype.dehanceValue=function(z){return void 0!==this.dehancer?this.dehancer(z):z},I.prototype.clear=function(){var z=this;Cu(function(){Wi(function(){z._data.forEach(function(B){z.delete(B)})})})},I.prototype.forEach=function(z,B){var be=this;this._data.forEach(function(at){z.call(B,at,at,be)})},Object.defineProperty(I.prototype,"size",{get:function(){return this._atom.reportObserved(),this._data.size},enumerable:!0,configurable:!0}),I.prototype.add=function(z){var B=this;if(An(this._atom),Li(this)&&!(be=Aa(this,{type:"add",object:this,newValue:z})))return this;if(!this.has(z)){Cu(function(){B._data.add(B.enhancer(z,void 0)),B._atom.reportChanged()});var at=Ws(),$t=Ss(this),be=$t||at?{type:"add",object:this,newValue:z}:null;$t&&yl(this,be)}return this},I.prototype.delete=function(z){var B=this;if(Li(this)&&!(be=Aa(this,{type:"delete",object:this,oldValue:z})))return!1;if(this.has(z)){var at=Ws(),$t=Ss(this),be=$t||at?{type:"delete",object:this,oldValue:z}:null;return Cu(function(){B._atom.reportChanged(),B._data.delete(z)}),$t&&yl(this,be),!0}return!1},I.prototype.has=function(z){return this._atom.reportObserved(),this._data.has(this.dehanceValue(z))},I.prototype.entries=function(){var z=0,B=it(this.keys()),be=it(this.values());return Bt({next:function(){var at=z;return z+=1,at<be.length?{value:[B[at],be[at]],done:!1}:{done:!0}}})},I.prototype.keys=function(){return this.values()},I.prototype.values=function(){this._atom.reportObserved();var be,z=this,B=0;return void 0!==this._data.values?be=it(this._data.values()):(be=[],this._data.forEach(function(at){return be.push(at)})),Bt({next:function(){return B<be.length?{value:z.dehanceValue(be[B++]),done:!1}:{done:!0}}})},I.prototype.replace=function(z){var B=this;return st(z)&&(z=z.toJS()),Cu(function(){Array.isArray(z)||Vt(z)?(B.clear(),z.forEach(function(be){return B.add(be)})):null!=z&&K("Cannot initialize set from "+z)}),this},I.prototype.observe=function(z,B){return $u(this,z)},I.prototype.intercept=function(z){return sa(this,z)},I.prototype.toJS=function(){return new Set(this)},I.prototype.toString=function(){return this.name+"[ "+it(this.keys()).join(", ")+" ]"},I}();Ut(Ae.prototype,function(){return this.values()}),lt(Ae.prototype,bt(),"Set");var st=Be("ObservableSet",Ae),vt=function(){function I(z,B,be){this.target=z,this.name=B,this.defaultEnhancer=be,this.values={}}return I.prototype.read=function(z,B){if(this.target===z||(this.illegalAccess(z,B),this.values[B]))return this.values[B].get()},I.prototype.write=function(z,B,be){var at=this.target;at!==z&&this.illegalAccess(z,B);var $t=this.values[B];if($t instanceof tr)$t.set(be);else{if(Li(this)){if(!(jn=Aa(this,{type:"update",object:at,name:B,newValue:be})))return;be=jn.newValue}if((be=$t.prepareNewValue(be))!==on.UNCHANGED){var fr=Ss(this),ui=Ws(),jn=fr||ui?{type:"update",object:at,oldValue:$t.value,name:B,newValue:be}:null;ui&&bo(e({},jn,{name:this.name,key:B})),$t.setNewValue(be),fr&&yl(this,jn),ui&&ps()}}},I.prototype.remove=function(z){if(this.values[z]){var B=this.target;if(Li(this)&&!(be=Aa(this,{object:B,name:z,type:"remove"})))return;try{ta();var at=Ss(this),$t=Ws(),jn=this.values[z].get();this.keys&&this.keys.remove(z),delete this.values[z],delete this.target[z];var be=at||$t?{type:"remove",object:B,oldValue:jn,name:z}:null;$t&&bo(e({},be,{name:this.name,key:z})),at&&yl(this,be),$t&&ps()}finally{Is()}}},I.prototype.illegalAccess=function(z,B){console.warn("Property '"+B+"' of '"+z+"' was accessed through the prototype chain. Use 'decorate' instead to declare the prop or access it statically through it's owner")},I.prototype.observe=function(z,B){return $u(this,z)},I.prototype.intercept=function(z){return sa(this,z)},I.prototype.getKeys=function(){var z=this;return void 0===this.keys&&(this.keys=new Bo(Object.keys(this.values).filter(function(B){return z.values[B]instanceof Ci}),Zr,"keys("+this.name+")",!0)),this.keys.slice()},I}();function ut(I,z,B){void 0===z&&(z=""),void 0===B&&(B=ki);var be=I.$mobx;return be||(he(I)||(z=(I.constructor.name||"ObservableObject")+"@"+J()),z||(z="ObservableObject@"+J()),lt(I,"$mobx",be=new vt(I,z,B)),be)}var Or=Object.create(null),zr=Object.create(null);function ai(I){return I.$mobx||(Br(I),I.$mobx)}var In=Be("ObservableObjectAdministration",vt);function Cr(I){return!!ie(I)&&(Br(I),In(I.$mobx))}function hr(I,z){if("object"==typeof I&&null!==I){if(jl(I))return void 0!==z&&K(!1),I.$mobx.atom;if(st(I))return I.$mobx;if(ks(I)){var B=I;return void 0===z?hr(B._keys):((be=B._data.get(z)||B._hasMap.get(z))||K(!1),be)}var be;if(Br(I),Cr(I))return z?((be=I.$mobx.values[z])||K(!1),be):K(!1);if(Xt(I)||Ar(I)||Ra(I))return I}else if("function"==typeof I&&Ra(I.$mobx))return I.$mobx;return K(!1)}function ao(I,z){return I||K("Expecting some object"),void 0!==z?ao(hr(I,z)):Xt(I)||Ar(I)||Ra(I)||ks(I)||st(I)?I:(Br(I),I.$mobx?I.$mobx:void K(!1))}var Na=Object.prototype.toString;function Tl(I,z,B){return void 0===B&&(B=-1),Qs(I,z,B)}function Qs(I,z,B,be,at){if(I===z)return 0!==I||1/I==1/z;if(null==I||null==z)return!1;if(I!=I)return z!=z;var $t=typeof I;if("function"!==$t&&"object"!==$t&&"object"!=typeof z)return!1;I=ed(I),z=ed(z);var jn=Na.call(I);if(jn!==Na.call(z))return!1;switch(jn){case"[object RegExp]":case"[object String]":return""+I==""+z;case"[object Number]":return+I!=+I?+z!=+z:0==+I?1/+I==1/z:+I==+z;case"[object Date]":case"[object Boolean]":return+I==+z;case"[object Symbol]":return"undefined"!=typeof Symbol&&Symbol.valueOf.call(I)===Symbol.valueOf.call(z)}var fr="[object Array]"===jn;if(!fr){if("object"!=typeof I||"object"!=typeof z)return!1;var ui=I.constructor,Ro=z.constructor;if(ui!==Ro&&!("function"==typeof ui&&ui instanceof ui&&"function"==typeof Ro&&Ro instanceof Ro)&&"constructor"in I&&"constructor"in z)return!1}if(0===B)return!1;B<0&&(B=-1),at=at||[];for(var Vo=(be=be||[]).length;Vo--;)if(be[Vo]===I)return at[Vo]===z;if(be.push(I),at.push(z),fr){if((Vo=I.length)!==z.length)return!1;for(;Vo--;)if(!Qs(I[Vo],z[Vo],B-1,be,at))return!1}else{var Ms=Object.keys(I),Dl=void 0;if(Vo=Ms.length,Object.keys(z).length!==Vo)return!1;for(;Vo--;)if(!$c(z,Dl=Ms[Vo])||!Qs(I[Dl],z[Dl],B-1,be,at))return!1}return be.pop(),at.pop(),!0}function ed(I){return jl(I)?I.peek():He(I)||ks(I)||Vt(I)||st(I)?it(I.entries()):I}function $c(I,z){return Object.prototype.hasOwnProperty.call(I,z)}"object"==typeof __MOBX_DEVTOOLS_GLOBAL_HOOK__&&__MOBX_DEVTOOLS_GLOBAL_HOOK__.injectMobx({spy:function(I){return on.spyListeners.push(I),H(function(){on.spyListeners=on.spyListeners.filter(function(z){return z!==I})})},extras:{getDebugName:function(I,z){return(void 0!==z?hr(I,z):Cr(I)||ks(I)||st(I)?ao(I):hr(I)).name}},$mobx:"$mobx"});const hl=function(I,z,B){switch(B.length){case 0:return I.call(z);case 1:return I.call(z,B[0]);case 2:return I.call(z,B[0],B[1]);case 3:return I.call(z,B[0],B[1],B[2])}return I.apply(z,B)},Js=function(I){return I};var md=Math.max;const Nl=function(I,z,B){return z=md(void 0===z?I.length-1:z,0),function(){for(var be=arguments,at=-1,$t=md(be.length-z,0),jn=Array($t);++at<$t;)jn[at]=be[z+at];at=-1;for(var fr=Array(z+1);++at<z;)fr[at]=be[at];return fr[z]=B(jn),hl(I,this,fr)}},zd=function(I){return function(){return I}};var ss=i(99567),al=Date.now;const Ie=function(I){var z=0,B=0;return function(){var be=al(),at=16-(be-B);if(B=be,at>0){if(++z>=800)return arguments[0]}else z=0;return I.apply(void 0,arguments)}}(ss.Z?function(I,z){return(0,ss.Z)(I,"toString",{configurable:!0,enumerable:!1,value:zd(z),writable:!0})}:Js),ot=function(I,z){return Ie(Nl(I,z,Js),I+"")};var Et=i(7475),qt=i(2951),Hn=i(66224);const Ei=function(I,z,B){(void 0!==B&&!(0,Hn.Z)(I[z],B)||void 0===B&&!(z in I))&&(0,qt.Z)(I,z,B)},Oa=function(z,B,be){for(var at=-1,$t=Object(z),jn=be(z),fr=jn.length;fr--;){var ui=jn[++at];if(!1===B($t[ui],ui,$t))break}return z};var Hs=i(27672),fc=i(1044),ga=i(36889),Ol=i(22595),ll=i(2172),Za=i(34654),ja=i(18402),ul=i(6539);var Qd=i(12434),Sc=i(58209),Wu=i(4214),Cc=i(46382),Xd=i(11595),Sl=Function.prototype.toString,wl=Object.prototype.hasOwnProperty,kl=Sl.call(Object);const Ja=function(I){if(!(0,ul.Z)(I)||"[object Object]"!=(0,Cc.Z)(I))return!1;var z=(0,Xd.Z)(I);if(null===z)return!0;var B=wl.call(z,"constructor")&&z.constructor;return"function"==typeof B&&B instanceof B&&Sl.call(B)==kl};var Qu=i(99436);const Oc=function(I,z){if(("constructor"!==z||"function"!=typeof I[z])&&"__proto__"!=z)return I[z]};var Au=i(57640),Iu=i(76212);const vd=function(I,z,B,be,at,$t,jn){var fr=Oc(I,B),ui=Oc(z,B),Ro=jn.get(ui);if(Ro)Ei(I,B,Ro);else{var Vo=$t?$t(fr,ui,B+"",I,z,jn):void 0,Ms=void 0===Vo;if(Ms){var Dl=(0,Za.Z)(ui),ql=!Dl&&(0,Qd.Z)(ui),eu=!Dl&&!ql&&(0,Qu.Z)(ui);Vo=ui,Dl||ql||eu?(0,Za.Z)(fr)?Vo=fr:function(I){return(0,ul.Z)(I)&&(0,ja.Z)(I)}(fr)?Vo=(0,ga.Z)(fr):ql?(Ms=!1,Vo=(0,Hs.Z)(ui,!0)):eu?(Ms=!1,Vo=(0,fc.Z)(ui,!0)):Vo=[]:Ja(ui)||(0,ll.Z)(ui)?(Vo=fr,(0,ll.Z)(fr)?Vo=function(I){return(0,Au.Z)(I,(0,Iu.Z)(I))}(fr):(!(0,Wu.Z)(fr)||(0,Sc.Z)(fr))&&(Vo=(0,Ol.Z)(ui))):Ms=!1}Ms&&(jn.set(ui,Vo),at(Vo,ui,be,$t,jn),jn.delete(ui)),Ei(I,B,Vo)}},Gc=function wc(I,z,B,be,at){I!==z&&Oa(z,function($t,jn){if(at||(at=new Et.Z),(0,Wu.Z)($t))vd(I,z,jn,B,wc,be,at);else{var fr=be?be(Oc(I,jn),$t,jn+"",I,z,at):void 0;void 0===fr&&(fr=$t),Ei(I,jn,fr)}},Iu.Z)},xc=function pf(I,z,B,be,at,$t){return(0,Wu.Z)(I)&&(0,Wu.Z)(z)&&($t.set(z,I),Gc(I,z,void 0,pf,$t),$t.delete(z)),I};var hf=i(28078);const hu=function(I,z,B){if(!(0,Wu.Z)(B))return!1;var be=typeof z;return!!("number"==be?(0,ja.Z)(B)&&(0,hf.Z)(z,B.length):"string"==be&&z in B)&&(0,Hn.Z)(B[z],I)},_f=function(I){return ot(function(z,B){var be=-1,at=B.length,$t=at>1?B[at-1]:void 0,jn=at>2?B[2]:void 0;for($t=I.length>3&&"function"==typeof $t?(at--,$t):void 0,jn&&hu(B[0],B[1],jn)&&($t=at<3?void 0:$t,at=1),z=Object(z);++be<at;){var fr=B[be];fr&&I(z,fr,be,$t)}return z})}(function(I,z,B,be){Gc(I,z,B,be)}),Ql=ot(function(I){return I.push(void 0,xc),hl(_f,void 0,I)}),Kf=function(I){return"symbol"==typeof I||(0,ul.Z)(I)&&"[object Symbol]"==(0,Cc.Z)(I)};var Nd=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Dc=/^\w*$/;const Ji=function(I,z){if((0,Za.Z)(I))return!1;var B=typeof I;return!("number"!=B&&"symbol"!=B&&"boolean"!=B&&null!=I&&!Kf(I))||Dc.test(I)||!Nd.test(I)||null!=z&&I in Object(z)};var cl=i(79489);function Pd(I,z){if("function"!=typeof I||null!=z&&"function"!=typeof z)throw new TypeError("Expected a function");var B=function(){var be=arguments,at=z?z.apply(this,be):be[0],$t=B.cache;if($t.has(at))return $t.get(at);var jn=I.apply(this,be);return B.cache=$t.set(at,jn)||$t,jn};return B.cache=new(Pd.Cache||cl.Z),B}Pd.Cache=cl.Z;var wf=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,Vl=/\\(\\)?/g;const oc=(z=Pd(function(I){var z=[];return 46===I.charCodeAt(0)&&z.push(""),I.replace(wf,function(B,be,at,$t){z.push(at?$t.replace(Vl,"$1"):be||B)}),z},function(be){return 500===B.size&&B.clear(),be}),B=z.cache,z);var z,B,hc=i(35770);const Mc=function(I,z){for(var B=-1,be=null==I?0:I.length,at=Array(be);++B<be;)at[B]=z(I[B],B,I);return at};var cu=hc.Z?hc.Z.prototype:void 0,Lu=cu?cu.toString:void 0;const Rc=function Ou(I){if("string"==typeof I)return I;if((0,Za.Z)(I))return Mc(I,Ou)+"";if(Kf(I))return Lu?Lu.call(I):"";var z=I+"";return"0"==z&&1/I==-1/0?"-0":z},h=function(I){return null==I?"":Rc(I)},R=function(I,z){return(0,Za.Z)(I)?I:Ji(I,z)?[I]:oc(h(I))},de=function(I){if("string"==typeof I||Kf(I))return I;var z=I+"";return"0"==z&&1/I==-1/0?"-0":z},Ue=function(I,z){for(var B=0,be=(z=R(z,I)).length;null!=I&&B<be;)I=I[de(z[B++])];return B&&B==be?I:void 0},Xe=function(I,z,B){var be=null==I?void 0:Ue(I,z);return void 0===be?B:be};var gt=i(57765);const nn=function(I){var z=null==I?0:I.length;return z?I[z-1]:void 0},Gr=function(I,z){return z.length<2?I:Ue(I,function(I,z,B){var be=-1,at=I.length;z<0&&(z=-z>at?0:at+z),(B=B>at?at:B)<0&&(B+=at),at=z>B?0:B-z>>>0,z>>>=0;for(var $t=Array(at);++be<at;)$t[be]=I[be+z];return $t}(z,0,-1))},Zo=function(I,z){return z=R(z,I),null==(I=Gr(I,z))||delete I[de(nn(z))]},Gs=function(I){return Ja(I)?void 0:I};var Xs=i(57052),dl=hc.Z?hc.Z.isConcatSpreadable:void 0;const ia=function(I){return(0,Za.Z)(I)||(0,ll.Z)(I)||!!(dl&&I&&I[dl])},il=function Pa(I,z,B,be,at){var $t=-1,jn=I.length;for(B||(B=ia),at||(at=[]);++$t<jn;){var fr=I[$t];z>0&&B(fr)?z>1?Pa(fr,z-1,B,be,at):(0,Xs.Z)(at,fr):be||(at[at.length]=fr)}return at},wa=function(I){return null!=I&&I.length?il(I,1):[]},gu=function(I){return Ie(Nl(I,void 0,wa),I+"")};var Nc=i(23359);const ve=gu(function(I,z){var B={};if(null==I)return B;var be=!1;z=Mc(z,function($t){return $t=R($t,I),be||(be=$t.length>1),$t}),(0,Au.Z)(I,(0,Nc.Z)(I),B),be&&(B=(0,gt.Z)(B,7,Gs));for(var at=z.length;at--;)Zo(B,z[at]);return B}),bi=function(I,z){for(var B=-1,be=null==I?0:I.length;++B<be;)if(z(I[B],B,I))return!0;return!1};function zc(I){var z=-1,B=null==I?0:I.length;for(this.__data__=new cl.Z;++z<B;)this.add(I[z])}zc.prototype.add=zc.prototype.push=function(I){return this.__data__.set(I,"__lodash_hash_undefined__"),this},zc.prototype.has=function(I){return this.__data__.has(I)};const qf=zc,Hp=function(I,z){return I.has(z)},dd=function(I,z,B,be,at,$t){var jn=1&B,fr=I.length,ui=z.length;if(fr!=ui&&!(jn&&ui>fr))return!1;var Ro=$t.get(I),Vo=$t.get(z);if(Ro&&Vo)return Ro==z&&Vo==I;var Ms=-1,Dl=!0,ql=2&B?new qf:void 0;for($t.set(I,z),$t.set(z,I);++Ms<fr;){var eu=I[Ms],Ku=z[Ms];if(be)var Zd=jn?be(Ku,eu,Ms,z,I,$t):be(eu,Ku,Ms,I,z,$t);if(void 0!==Zd){if(Zd)continue;Dl=!1;break}if(ql){if(!bi(z,function(Cd,Op){if(!Hp(ql,Op)&&(eu===Cd||at(eu,Cd,B,be,$t)))return ql.push(Op)})){Dl=!1;break}}else if(eu!==Ku&&!at(eu,Ku,B,be,$t)){Dl=!1;break}}return $t.delete(I),$t.delete(z),Dl};var Fd=i(83345);const fl=function(I){var z=-1,B=Array(I.size);return I.forEach(function(be,at){B[++z]=[at,be]}),B},F_=function(I){var z=-1,B=Array(I.size);return I.forEach(function(be){B[++z]=be}),B};var Bp=hc.Z?hc.Z.prototype:void 0,ih=Bp?Bp.valueOf:void 0;var Lh=i(22018),Zf=Object.prototype.hasOwnProperty;var oh=i(81901),o_="[object Arguments]",Y="[object Array]",fe="[object Object]",X=Object.prototype.hasOwnProperty;const ct=function(I,z,B,be,at,$t){var jn=(0,Za.Z)(I),fr=(0,Za.Z)(z),ui=jn?Y:(0,oh.Z)(I),Ro=fr?Y:(0,oh.Z)(z),Vo=(ui=ui==o_?fe:ui)==fe,Ms=(Ro=Ro==o_?fe:Ro)==fe,Dl=ui==Ro;if(Dl&&(0,Qd.Z)(I)){if(!(0,Qd.Z)(z))return!1;jn=!0,Vo=!1}if(Dl&&!Vo)return $t||($t=new Et.Z),jn||(0,Qu.Z)(I)?dd(I,z,B,be,at,$t):function(I,z,B,be,at,$t,jn){switch(B){case"[object DataView]":if(I.byteLength!=z.byteLength||I.byteOffset!=z.byteOffset)return!1;I=I.buffer,z=z.buffer;case"[object ArrayBuffer]":return!(I.byteLength!=z.byteLength||!$t(new Fd.Z(I),new Fd.Z(z)));case"[object Boolean]":case"[object Date]":case"[object Number]":return(0,Hn.Z)(+I,+z);case"[object Error]":return I.name==z.name&&I.message==z.message;case"[object RegExp]":case"[object String]":return I==z+"";case"[object Map]":var fr=fl;case"[object Set]":if(fr||(fr=F_),I.size!=z.size&&!(1&be))return!1;var Ro=jn.get(I);if(Ro)return Ro==z;be|=2,jn.set(I,z);var Vo=dd(fr(I),fr(z),be,at,$t,jn);return jn.delete(I),Vo;case"[object Symbol]":if(ih)return ih.call(I)==ih.call(z)}return!1}(I,z,ui,B,be,at,$t);if(!(1&B)){var ql=Vo&&X.call(I,"__wrapped__"),eu=Ms&&X.call(z,"__wrapped__");if(ql||eu){var Ku=ql?I.value():I,Zd=eu?z.value():z;return $t||($t=new Et.Z),at(Ku,Zd,B,be,$t)}}return!!Dl&&($t||($t=new Et.Z),function(I,z,B,be,at,$t){var jn=1&B,fr=(0,Lh.Z)(I),ui=fr.length;if(ui!=(0,Lh.Z)(z).length&&!jn)return!1;for(var Ms=ui;Ms--;){var Dl=fr[Ms];if(!(jn?Dl in z:Zf.call(z,Dl)))return!1}var ql=$t.get(I),eu=$t.get(z);if(ql&&eu)return ql==z&&eu==I;var Ku=!0;$t.set(I,z),$t.set(z,I);for(var Zd=jn;++Ms<ui;){var Cd=I[Dl=fr[Ms]],Op=z[Dl];if(be)var K_=jn?be(Op,Cd,Dl,z,I,$t):be(Cd,Op,Dl,I,z,$t);if(!(void 0===K_?Cd===Op||at(Cd,Op,B,be,$t):K_)){Ku=!1;break}Zd||(Zd="constructor"==Dl)}if(Ku&&!Zd){var q_=I.constructor,tf=z.constructor;q_!=tf&&"constructor"in I&&"constructor"in z&&!("function"==typeof q_&&q_ instanceof q_&&"function"==typeof tf&&tf instanceof tf)&&(Ku=!1)}return $t.delete(I),$t.delete(z),Ku}(I,z,B,be,at,$t))},Ir=function Jn(I,z,B,be,at){return I===z||(null==I||null==z||!(0,ul.Z)(I)&&!(0,ul.Z)(z)?I!=I&&z!=z:ct(I,z,B,be,Jn,at))},Rs=function(I){return I==I&&!(0,Wu.Z)(I)};var ma=i(6251);const wu=function(I,z){return function(B){return null!=B&&B[I]===z&&(void 0!==z||I in Object(B))}},$_=function(I){var z=function(I){for(var z=(0,ma.Z)(I),B=z.length;B--;){var be=z[B],at=I[be];z[B]=[be,at,Rs(at)]}return z}(I);return 1==z.length&&z[0][2]?wu(z[0][0],z[0][1]):function(B){return B===I||function(I,z,B,be){var at=B.length,$t=at,jn=!be;if(null==I)return!$t;for(I=Object(I);at--;){var fr=B[at];if(jn&&fr[2]?fr[1]!==I[fr[0]]:!(fr[0]in I))return!1}for(;++at<$t;){var ui=(fr=B[at])[0],Ro=I[ui],Vo=fr[1];if(jn&&fr[2]){if(void 0===Ro&&!(ui in I))return!1}else{var Ms=new Et.Z;if(be)var Dl=be(Ro,Vo,ui,I,z,Ms);if(!(void 0===Dl?Ir(Vo,Ro,3,be,Ms):Dl))return!1}}return!0}(B,I,z)}},ah=function(I,z){return null!=I&&z in Object(I)};var _p=i(19238);const gp=function(I,z){return null!=I&&function(I,z,B){for(var be=-1,at=(z=R(z,I)).length,$t=!1;++be<at;){var jn=de(z[be]);if(!($t=null!=I&&B(I,jn)))break;I=I[jn]}return $t||++be!=at?$t:!!(at=null==I?0:I.length)&&(0,_p.Z)(at)&&(0,hf.Z)(jn,at)&&((0,Za.Z)(I)||(0,ll.Z)(I))}(I,z,ah)},lh=function(I){return Ji(I)?function(I){return function(z){return null==z?void 0:z[I]}}(de(I)):function(I){return function(z){return Ue(z,I)}}(I)},rd=function(I){return"function"==typeof I?I:null==I?Js:"object"==typeof I?(0,Za.Z)(I)?function(I,z){return Ji(I)&&Rs(z)?wu(de(I),z):function(B){var be=Xe(B,I);return void 0===be&&be===z?gp(B,I):Ir(z,be,3)}}(I[0],I[1]):$_(I):lh(I)},Ea=function(B,be){if(null==B)return B;if(!(0,ja.Z)(B))return function(I,z){return I&&Oa(I,z,ma.Z)}(B,be);for(var at=B.length,$t=-1,jn=Object(B);++$t<at&&!1!==be(jn[$t],$t,jn););return B},Xu=function(I,z){var B;return Ea(I,function(be,at,$t){return!(B=z(be,at,$t))}),!!B},Zu=function(I,z){for(var B=-1,be=null==I?0:I.length;++B<be;)if(!z(I[B],B,I))return!1;return!0},Yp=function(I,z){var B=!0;return Ea(I,function(be,at,$t){return B=!!z(be,at,$t)}),B},Z_=function(I){return I&&I.length?I[0]:void 0},kh=function(I){for(var z=-1,B=null==I?0:I.length,be=0,at=[];++z<B;){var $t=I[z];$t&&(at[be++]=$t)}return at},G_=function(I,z,B,be){for(var at=I.length,$t=B+(be?1:-1);be?$t--:++$t<at;)if(z(I[$t],$t,I))return $t;return-1};var id=/\s/;var Hh=/^\s+/;const hg=function(I){return I&&I.slice(0,function(I){for(var z=I.length;z--&&id.test(I.charAt(z)););return z}(I)+1).replace(Hh,"")};var Ud=/^[-+]0x[0-9a-f]+$/i,yf=/^0b[01]+$/i,p_=/^0o[0-7]+$/i,yp=parseInt;const bp=function(I){if("number"==typeof I)return I;if(Kf(I))return NaN;if((0,Wu.Z)(I)){var z="function"==typeof I.valueOf?I.valueOf():I;I=(0,Wu.Z)(z)?z+"":z}if("string"!=typeof I)return 0===I?I:+I;I=hg(I);var B=yf.test(I);return B||p_.test(I)?yp(I.slice(2),B?2:8):Ud.test(I)?NaN:+I},od=function(I){var z=function(I){return I?1/0===(I=bp(I))||-1/0===I?17976931348623157e292*(I<0?-1:1):I==I?I:0:0===I?I:0}(I),B=z%1;return z==z?B?z-B:z:0};var dh=Math.max;const fh=function(z,B,be){var at=Object(z);if(!(0,ja.Z)(z)){var $t=rd(B);z=(0,ma.Z)(z),B=function(fr){return $t(at[fr],fr,at)}}var jn=function(I,z,B){var be=null==I?0:I.length;if(!be)return-1;var at=null==B?0:od(B);return at<0&&(at=dh(be+at,0)),G_(I,rd(z),at)}(z,B,be);return jn>-1?at[$t?z[jn]:jn]:void 0},Rf=function(I){return"string"==typeof I||!(0,Za.Z)(I)&&(0,ul.Z)(I)&&"[object String]"==(0,Cc.Z)(I)};var ph=i(40309);const Bh=function(){return ph.Z.Date.now()};var ym=Math.max,bm=Math.min;const gg=function(I,z,B){var be=!0,at=!0;if("function"!=typeof I)throw new TypeError("Expected a function");return(0,Wu.Z)(B)&&(be="leading"in B?!!B.leading:be,at="trailing"in B?!!B.trailing:at),function(I,z,B){var be,at,$t,jn,fr,ui,Ro=0,Vo=!1,Ms=!1,Dl=!0;if("function"!=typeof I)throw new TypeError("Expected a function");function ql(Qc){var wp=be,ju=at;return be=at=void 0,Ro=Qc,jn=I.apply(ju,wp)}function eu(Qc){return Ro=Qc,fr=setTimeout(Cd,z),Vo?ql(Qc):jn}function Zd(Qc){var wp=Qc-ui;return void 0===ui||wp>=z||wp<0||Ms&&Qc-Ro>=$t}function Cd(){var Qc=Bh();if(Zd(Qc))return Op(Qc);fr=setTimeout(Cd,function(Qc){var Ic=z-(Qc-ui);return Ms?bm(Ic,$t-(Qc-Ro)):Ic}(Qc))}function Op(Qc){return fr=void 0,Dl&&be?ql(Qc):(be=at=void 0,jn)}function tf(){var Qc=Bh(),wp=Zd(Qc);if(be=arguments,at=this,ui=Qc,wp){if(void 0===fr)return eu(ui);if(Ms)return clearTimeout(fr),fr=setTimeout(Cd,z),ql(ui)}return void 0===fr&&(fr=setTimeout(Cd,z)),jn}return z=bp(z)||0,(0,Wu.Z)(B)&&(Vo=!!B.leading,$t=(Ms="maxWait"in B)?ym(bp(B.maxWait)||0,z):$t,Dl="trailing"in B?!!B.trailing:Dl),tf.cancel=function(){void 0!==fr&&clearTimeout(fr),Ro=0,be=ui=at=fr=void 0},tf.flush=function(){return void 0===fr?jn:Op(Bh())},tf}(I,z,{leading:be,maxWait:z,trailing:at})},mg=function(I){return I!=I},Em=function(I){return null==I?[]:function(I,z){return Mc(z,function(B){return I[B]})}(I,(0,ma.Z)(I))};var Yd=Math.max;const Yg=function(I,z,B,be){I=(0,ja.Z)(I)?I:Em(I),B=B&&!be?od(B):0;var at=I.length;return B<0&&(B=Yd(at+B,0)),Rf(I)?B<=at&&I.indexOf(z,B)>-1:!!at&&function(I,z,B){return z==z?function(I,z,B){for(var be=B-1,at=I.length;++be<at;)if(I[be]===z)return be;return-1}(I,z,B):G_(I,mg,B)}(I,z,B)>-1};var Sp=i(15427);const Jc=function(I,z,B,be){if(!(0,Wu.Z)(I))return I;for(var at=-1,$t=(z=R(z,I)).length,jn=$t-1,fr=I;null!=fr&&++at<$t;){var ui=de(z[at]),Ro=B;if("__proto__"===ui||"constructor"===ui||"prototype"===ui)return I;if(at!=jn){var Vo=fr[ui];void 0===(Ro=be?be(Vo,ui,fr):void 0)&&(Ro=(0,Wu.Z)(Vo)?Vo:(0,hf.Z)(z[at+1])?[]:{})}(0,Sp.Z)(fr,ui,Ro),fr=fr[ui]}return I},bg=function(I,z){return function(I,z,B){for(var be=-1,at=z.length,$t={};++be<at;){var jn=z[be],fr=Ue(I,jn);B(fr,jn)&&Jc($t,R(jn,I),fr)}return $t}(I,z,function(B,be){return gp(I,be)})},y_=gu(function(I,z){return null==I?{}:bg(I,z)});function b_(I,z){1&I&&(r.TgZ(0,"span"),r._uU(1,"loading..."),r.qZA())}const jh=function(I){return{$implicit:I}};function E_(I,z){if(1&I&&(r.ynx(0),r.TgZ(1,"div"),r.Hsn(2),r.qZA(),r.BQk()),2&I){const B=r.oxw();r.xp6(1),r.Udp("height",B.getTotalHeight())}}const jp=function(){return{dontDetach:!0}},Tg=["*"],T_=["loadingTemplate"],Zg=["treeNodeTemplate"],Gh=["treeNodeWrapperTemplate"],Sg=["treeNodeFullTemplate"],rv=["viewport"],Vh=function(I,z,B,be){return{loadingTemplate:I,treeNodeTemplate:z,treeNodeWrapperTemplate:B,treeNodeFullTemplate:be}};function Tm(I,z){if(1&I&&r._UZ(0,"tree-node-collection",4),2&I){const B=r.oxw();r.Q6J("nodes",B.treeModel.roots)("treeModel",B.treeModel)("templates",r.l5B(3,Vh,B.loadingTemplate,B.treeNodeTemplate,B.treeNodeWrapperTemplate,B.treeNodeFullTemplate))}}function S_(I,z){if(1&I&&r._UZ(0,"tree-node-drop-slot",5),2&I){const B=r.oxw();r.Q6J("dropIndex",0)("node",B.treeModel.virtualRoot)}}function b(I,z){if(1&I&&r._UZ(0,"tree-node-drop-slot",6),2&I){const B=r.oxw(3);r.Q6J("dropIndex",B.node.index)("node",B.node.parent)}}function x(I,z){if(1&I&&(r.TgZ(0,"div"),r.YNc(1,b,1,2,"tree-node-drop-slot",3),r._UZ(2,"tree-node-wrapper",4),r._UZ(3,"tree-node-children",5),r._UZ(4,"tree-node-drop-slot",6),r.qZA()),2&I){const B=r.oxw(2);r.Tol(B.node.getClass()),r.ekj("tree-node",!0)("tree-node-expanded",B.node.isExpanded&&B.node.hasChildren)("tree-node-collapsed",B.node.isCollapsed&&B.node.hasChildren)("tree-node-leaf",B.node.isLeaf)("tree-node-active",B.node.isActive)("tree-node-focused",B.node.isFocused),r.xp6(1),r.Q6J("ngIf",0===B.index),r.xp6(1),r.Q6J("node",B.node)("index",B.index)("templates",B.templates),r.xp6(1),r.Q6J("node",B.node)("templates",B.templates),r.xp6(1),r.Q6J("dropIndex",B.node.index+1)("node",B.node.parent)}}const G=function(I,z,B,be){return{$implicit:I,node:z,index:B,templates:be}};function Se(I,z){if(1&I&&(r.ynx(0),r.YNc(1,x,5,22,"div",1),r.GkF(2,2),r.BQk()),2&I){const B=r.oxw();r.xp6(1),r.Q6J("ngIf",!B.templates.treeNodeFullTemplate),r.xp6(1),r.Q6J("ngTemplateOutlet",B.templates.treeNodeFullTemplate)("ngTemplateOutletContext",r.l5B(3,G,B.node,B.node,B.index,B.templates))}}function We(I,z){if(1&I&&(r.TgZ(0,"span"),r._uU(1),r.qZA()),2&I){const B=r.oxw();r.xp6(1),r.Oqu(B.node.displayField)}}const Nt=function(I,z,B){return{$implicit:I,node:z,index:B}};function rn(I,z){if(1&I){const B=r.EpF();r.TgZ(0,"span",3),r.NdJ("click",function(at){return r.CHM(B),r.oxw(2).node.mouseAction("expanderClick",at)}),r._UZ(1,"span",4),r.qZA()}if(2&I){const B=r.oxw(2);r.ekj("toggle-children-wrapper-expanded",B.node.isExpanded)("toggle-children-wrapper-collapsed",B.node.isCollapsed)}}function On(I,z){1&I&&r._UZ(0,"span",5)}function yr(I,z){if(1&I&&(r.ynx(0),r.YNc(1,rn,2,4,"span",1),r.YNc(2,On,1,0,"span",2),r.BQk()),2&I){const B=r.oxw();r.xp6(1),r.Q6J("ngIf",B.node.hasChildren),r.xp6(1),r.Q6J("ngIf",!B.node.hasChildren)}}function Si(I,z){if(1&I&&r._UZ(0,"tree-node-collection",4),2&I){const B=r.oxw(3);r.Q6J("nodes",B.node.children)("templates",B.templates)("treeModel",B.node.treeModel)}}function as(I,z){if(1&I&&r._UZ(0,"tree-loading-component",5),2&I){const B=r.oxw(3);r.Udp("padding-left",B.node.getNodePadding()),r.Q6J("template",B.templates.loadingTemplate)("node",B.node)}}function Ha(I,z){if(1&I&&(r.TgZ(0,"div"),r.YNc(1,Si,1,3,"tree-node-collection",2),r.YNc(2,as,1,4,"tree-loading-component",3),r.qZA()),2&I){const B=r.oxw(2);r.ekj("tree-children",!0)("tree-children-no-padding",B.node.options.levelPadding),r.xp6(1),r.Q6J("ngIf",B.node.children),r.xp6(1),r.Q6J("ngIf",!B.node.children)}}function go(I,z){if(1&I&&(r.ynx(0),r.YNc(1,Ha,3,6,"div",1),r.BQk()),2&I){const B=r.oxw();r.xp6(1),r.Q6J("treeAnimateOpen",B.node.isExpanded)("treeAnimateOpenSpeed",B.node.options.animateSpeed)("treeAnimateOpenAcceleration",B.node.options.animateAcceleration)("treeAnimateOpenEnabled",B.node.options.animateExpand)}}function po(I,z){if(1&I&&r._UZ(0,"tree-node",2),2&I){const B=z.$implicit,be=z.index,at=r.oxw(2);r.Q6J("node",B)("index",be)("templates",at.templates)}}function Fa(I,z){if(1&I&&(r.ynx(0),r.TgZ(1,"div"),r.YNc(2,po,1,3,"tree-node",1),r.qZA(),r.BQk()),2&I){const B=r.oxw();r.xp6(1),r.Udp("margin-top",B.marginTop),r.xp6(1),r.Q6J("ngForOf",B.viewportNodes)("ngForTrackBy",B.trackNode)}}function Ta(I,z){if(1&I&&r._UZ(0,"tree-node-checkbox",4),2&I){const B=r.oxw(2);r.Q6J("node",B.node)}}function ni(I,z){if(1&I){const B=r.EpF();r.TgZ(0,"div",2),r.YNc(1,Ta,1,1,"tree-node-checkbox",3),r._UZ(2,"tree-node-expander",4),r.TgZ(3,"div",5),r.NdJ("click",function(at){return r.CHM(B),r.oxw().node.mouseAction("click",at)})("dblclick",function(at){return r.CHM(B),r.oxw().node.mouseAction("dblClick",at)})("mouseover",function(at){return r.CHM(B),r.oxw().node.mouseAction("mouseOver",at)})("mouseout",function(at){return r.CHM(B),r.oxw().node.mouseAction("mouseOut",at)})("contextmenu",function(at){return r.CHM(B),r.oxw().node.mouseAction("contextMenu",at)})("treeDrop",function(at){return r.CHM(B),r.oxw().node.onDrop(at)})("treeDropDragOver",function(at){return r.CHM(B),r.oxw().node.mouseAction("dragOver",at)})("treeDropDragLeave",function(at){return r.CHM(B),r.oxw().node.mouseAction("dragLeave",at)})("treeDropDragEnter",function(at){return r.CHM(B),r.oxw().node.mouseAction("dragEnter",at)}),r._UZ(4,"tree-node-content",6),r.qZA(),r.qZA()}if(2&I){const B=r.oxw();r.Udp("padding-left",B.node.getNodePadding()),r.xp6(1),r.Q6J("ngIf",B.node.options.useCheckbox),r.xp6(1),r.Q6J("node",B.node),r.xp6(1),r.ekj("node-content-wrapper-active",B.node.isActive)("node-content-wrapper-focused",B.node.isFocused),r.Q6J("treeAllowDrop",B.node.allowDrop)("allowDragoverStyling",B.node.allowDragoverStyling())("treeDrag",B.node)("treeDragEnabled",B.node.allowDrag()),r.xp6(1),r.Q6J("node",B.node)("index",B.index)("template",B.templates.treeNodeTemplate)}}function Tr(I,z){if(1&I){const B=r.EpF();r.ynx(0),r.TgZ(1,"input",1),r.NdJ("click",function(at){return r.CHM(B),r.oxw().node.mouseAction("checkboxClick",at)}),r.qZA(),r.BQk()}if(2&I){const B=r.oxw();r.xp6(1),r.Q6J("checked",B.node.isSelected)("indeterminate",B.node.isPartiallySelected)}}let Qr=(()=>{class I{constructor(B,be){this.templateRef=B,this.viewContainer=be,this.templateBindings={}}ngOnInit(){this.view=this.viewContainer.createEmbeddedView(this.templateRef),this.dispose&&this.dispose(),this.shouldDetach()&&this.view.detach(),this.autoDetect(this.view)}shouldDetach(){return this.treeMobxAutorun&&this.treeMobxAutorun.detach}autoDetect(B){this.dispose=ti(()=>B.detectChanges())}ngOnDestroy(){this.dispose&&this.dispose()}}return I.\u0275fac=function(B){return new(B||I)(r.Y36(r.Rgc),r.Y36(r.s_b))},I.\u0275dir=r.lG2({type:I,selectors:[["","treeMobxAutorun",""]],inputs:{treeMobxAutorun:"treeMobxAutorun"}}),I})();const rp={TOGGLE_ACTIVE:(I,z,B)=>z&&z.toggleActivated(),TOGGLE_ACTIVE_MULTI:(I,z,B)=>z&&z.toggleActivated(!0),TOGGLE_SELECTED:(I,z,B)=>z&&z.toggleSelected(),ACTIVATE:(I,z,B)=>z.setIsActive(!0),DEACTIVATE:(I,z,B)=>z.setIsActive(!1),SELECT:(I,z,B)=>z.setIsSelected(!0),DESELECT:(I,z,B)=>z.setIsSelected(!1),FOCUS:(I,z,B)=>z.focus(),TOGGLE_EXPANDED:(I,z,B)=>z.hasChildren&&z.toggleExpanded(),EXPAND:(I,z,B)=>z.expand(),COLLAPSE:(I,z,B)=>z.collapse(),DRILL_DOWN:(I,z,B)=>I.focusDrillDown(),DRILL_UP:(I,z,B)=>I.focusDrillUp(),NEXT_NODE:(I,z,B)=>I.focusNextNode(),PREVIOUS_NODE:(I,z,B)=>I.focusPreviousNode(),MOVE_NODE:(I,z,B,{from:be,to:at})=>{B.ctrlKey?I.copyNode(be,at):I.moveNode(be,at)}},sv={mouse:{click:rp.TOGGLE_ACTIVE,dblClick:null,contextMenu:null,expanderClick:rp.TOGGLE_EXPANDED,checkboxClick:rp.TOGGLE_SELECTED,drop:rp.MOVE_NODE},keys:{39:rp.DRILL_DOWN,37:rp.DRILL_UP,40:rp.NEXT_NODE,38:rp.PREVIOUS_NODE,32:rp.TOGGLE_ACTIVE,13:rp.TOGGLE_ACTIVE}};class Mm{constructor(z={}){this.options=z,this.actionMapping=Ql({},this.options.actionMapping,sv),z.rtl&&(this.actionMapping.keys[39]=Xe(z,["actionMapping","keys",39])||rp.DRILL_UP,this.actionMapping.keys[37]=Xe(z,["actionMapping","keys",37])||rp.DRILL_DOWN)}get hasChildrenField(){return this.options.hasChildrenField||"hasChildren"}get childrenField(){return this.options.childrenField||"children"}get displayField(){return this.options.displayField||"name"}get idField(){return this.options.idField||"id"}get isExpandedField(){return this.options.isExpandedField||"isExpanded"}get getChildren(){return this.options.getChildren}get levelPadding(){return this.options.levelPadding||0}get useVirtualScroll(){return this.options.useVirtualScroll}get animateExpand(){return this.options.animateExpand}get animateSpeed(){return this.options.animateSpeed||1}get animateAcceleration(){return this.options.animateAcceleration||1.2}get scrollOnActivate(){return void 0===this.options.scrollOnActivate||this.options.scrollOnActivate}get rtl(){return!!this.options.rtl}get rootId(){return this.options.rootId}get useCheckbox(){return this.options.useCheckbox}get useTriState(){return void 0===this.options.useTriState||this.options.useTriState}get scrollContainer(){return this.options.scrollContainer}get allowDragoverStyling(){return void 0===this.options.allowDragoverStyling||this.options.allowDragoverStyling}getNodeClone(z){return this.options.getNodeClone?this.options.getNodeClone(z):ve(Object.assign({},z.data),["id"])}allowDrop(z,B,be){return this.options.allowDrop instanceof Function?this.options.allowDrop(z,B,be):void 0===this.options.allowDrop||this.options.allowDrop}allowDrag(z){return this.options.allowDrag instanceof Function?this.options.allowDrag(z):this.options.allowDrag}nodeClass(z){return this.options.nodeClass?this.options.nodeClass(z):""}nodeHeight(z){if(z.data.virtual)return 0;let B=this.options.nodeHeight||22;return"function"==typeof B&&(B=B(z)),B+(0===z.index?2:1)*this.dropSlotHeight}get dropSlotHeight(){return function(I){return"number"==typeof I||(0,ul.Z)(I)&&"[object Number]"==(0,Cc.Z)(I)}(this.options.dropSlotHeight)?this.options.dropSlotHeight:2}}const mc={toggleExpanded:"toggleExpanded",activate:"activate",deactivate:"deactivate",nodeActivate:"nodeActivate",nodeDeactivate:"nodeDeactivate",select:"select",deselect:"deselect",focus:"focus",blur:"blur",initialized:"initialized",updateData:"updateData",moveNode:"moveNode",copyNode:"copyNode",event:"event",loadNodeChildren:"loadNodeChildren",changeFilter:"changeFilter",stateChange:"stateChange"};var ef=function(I,z,B,be){var jn,at=arguments.length,$t=at<3?z:null===be?be=Object.getOwnPropertyDescriptor(z,B):be;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)$t=Reflect.decorate(I,z,B,be);else for(var fr=I.length-1;fr>=0;fr--)(jn=I[fr])&&($t=(at<3?jn($t):at>3?jn(z,B,$t):jn(z,B))||$t);return at>3&&$t&&Object.defineProperty(z,B,$t),$t},Fu=function(I,z){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(I,z)};let s1=(()=>{class I{constructor(B,be,at,$t){this.data=B,this.parent=be,this.treeModel=at,this.position=0,this.allowDrop=(jn,fr)=>this.options.allowDrop(jn,{parent:this,index:0},fr),this.allowDragoverStyling=()=>this.options.allowDragoverStyling,null==this.id&&(this.id=Math.floor(1e13*Math.random())),this.index=$t,this.getField("children")&&this._initChildren(),this.autoLoadChildren()}get isHidden(){return this.treeModel.isHidden(this)}get isExpanded(){return this.treeModel.isExpanded(this)}get isActive(){return this.treeModel.isActive(this)}get isFocused(){return this.treeModel.isNodeFocused(this)}get isSelected(){return this.isSelectable()?this.treeModel.isSelected(this):function(I,z,B){var be=(0,Za.Z)(I)?bi:Xu;return B&&hu(I,z,B)&&(z=void 0),be(I,rd(z))}(this.children,B=>B.isSelected)}get isAllSelected(){return this.isSelectable()?this.treeModel.isSelected(this):function(I,z,B){var be=(0,Za.Z)(I)?Zu:Yp;return B&&hu(I,z,B)&&(z=void 0),be(I,rd(z))}(this.children,B=>B.isAllSelected)}get isPartiallySelected(){return this.isSelected&&!this.isAllSelected}get level(){return this.parent?this.parent.level+1:0}get path(){return this.parent?[...this.parent.path,this.id]:[]}get elementRef(){throw"Element Ref is no longer supported since introducing virtual scroll\n\n You may use a template to obtain a reference to the element"}get originalNode(){return this._originalNode}get hasChildren(){return!!(this.getField("hasChildren")||this.children&&this.children.length>0)}get isCollapsed(){return!this.isExpanded}get isLeaf(){return!this.hasChildren}get isRoot(){return this.parent.data.virtual}get realParent(){return this.isRoot?null:this.parent}get options(){return this.treeModel.options}fireEvent(B){this.treeModel.fireEvent(B)}get displayField(){return this.getField("display")}get id(){return this.getField("id")}set id(B){this.setField("id",B)}getField(B){return this.data[this.options[`${B}Field`]]}setField(B,be){this.data[this.options[`${B}Field`]]=be}_findAdjacentSibling(B,be=!1){const at=this._getParentsChildren(be),$t=at.indexOf(this);return at.length>$t+B?at[$t+B]:null}findNextSibling(B=!1){return this._findAdjacentSibling(1,B)}findPreviousSibling(B=!1){return this._findAdjacentSibling(-1,B)}getVisibleChildren(){return this.visibleChildren}get visibleChildren(){return(this.children||[]).filter(B=>!B.isHidden)}getFirstChild(B=!1){return Z_((B?this.visibleChildren:this.children)||[])}getLastChild(B=!1){return nn((B?this.visibleChildren:this.children)||[])}findNextNode(B=!0,be=!1){return B&&this.isExpanded&&this.getFirstChild(be)||this.findNextSibling(be)||this.parent&&this.parent.findNextNode(!1,be)}findPreviousNode(B=!1){let be=this.findPreviousSibling(B);return be?be._getLastOpenDescendant(B):this.realParent}_getLastOpenDescendant(B=!1){const be=this.getLastChild(B);return this.isCollapsed||!be?this:be._getLastOpenDescendant(B)}_getParentsChildren(B=!1){return this.parent&&(B?this.parent.getVisibleChildren():this.parent.children)||[]}getIndexInParent(B=!1){return this._getParentsChildren(B).indexOf(this)}isDescendantOf(B){return this===B||this.parent&&this.parent.isDescendantOf(B)}getNodePadding(){return this.options.levelPadding*(this.level-1)+"px"}getClass(){return[this.options.nodeClass(this),`tree-node-level-${this.level}`].join(" ")}onDrop(B){this.mouseAction("drop",B.event,{from:B.element,to:{parent:this,index:0,dropOnNode:!0}})}allowDrag(){return this.options.allowDrag(this)}loadNodeChildren(){return this.options.getChildren?Promise.resolve(this.options.getChildren(this)).then(B=>{B&&(this.setField("children",B),this._initChildren(),this.options.useTriState&&this.treeModel.isSelected(this)&&this.setIsSelected(!0),this.children.forEach(be=>{be.getField("isExpanded")&&be.hasChildren&&be.expand()}))}).then(()=>{this.fireEvent({eventName:mc.loadNodeChildren,node:this})}):Promise.resolve()}expand(){return this.isExpanded||this.toggleExpanded(),this}collapse(){return this.isExpanded&&this.toggleExpanded(),this}doForAll(B){Promise.resolve(B(this)).then(()=>{this.children&&this.children.forEach(be=>be.doForAll(B))})}expandAll(){this.doForAll(B=>B.expand())}collapseAll(){this.doForAll(B=>B.collapse())}ensureVisible(){return this.realParent&&(this.realParent.expand(),this.realParent.ensureVisible()),this}toggleExpanded(){return this.setIsExpanded(!this.isExpanded),this}setIsExpanded(B){return this.hasChildren&&this.treeModel.setExpandedNode(this,B),this}autoLoadChildren(){this.handler=ts(()=>this.isExpanded,B=>{!this.children&&this.hasChildren&&B&&this.loadNodeChildren()},{fireImmediately:!0})}dispose(){this.children&&this.children.forEach(B=>B.dispose()),this.handler&&this.handler(),this.parent=null,this.children=null}setIsActive(B,be=!1){return this.treeModel.setActiveNode(this,B,be),B&&this.focus(this.options.scrollOnActivate),this}isSelectable(){return this.isLeaf||!this.children||!this.options.useTriState}setIsSelected(B){return this.isSelectable()?this.treeModel.setSelectedNode(this,B):this.visibleChildren.forEach(be=>be.setIsSelected(B)),this}toggleSelected(){return this.setIsSelected(!this.isSelected),this}toggleActivated(B=!1){return this.setIsActive(!this.isActive,B),this}setActiveAndVisible(B=!1){return this.setIsActive(!0,B).ensureVisible(),setTimeout(this.scrollIntoView.bind(this)),this}scrollIntoView(B=!1){this.treeModel.virtualScroll.scrollIntoView(this,B)}focus(B=!0){let be=this.treeModel.getFocusedNode();return this.treeModel.setFocusedNode(this),B&&this.scrollIntoView(),be&&this.fireEvent({eventName:mc.blur,node:be}),this.fireEvent({eventName:mc.focus,node:this}),this}blur(){let B=this.treeModel.getFocusedNode();return this.treeModel.setFocusedNode(null),B&&this.fireEvent({eventName:mc.blur,node:this}),this}setIsHidden(B){this.treeModel.setIsHidden(this,B)}hide(){this.setIsHidden(!0)}show(){this.setIsHidden(!1)}mouseAction(B,be,at=null){this.treeModel.setFocus(!0);const jn=this.options.actionMapping.mouse[B];jn&&jn(this.treeModel,this,be,at)}getSelfHeight(){return this.options.nodeHeight(this)}_initChildren(){this.children=this.getField("children").map((B,be)=>new I(B,this,this.treeModel,be))}}return ef([Dn,Fu("design:type",Object),Fu("design:paramtypes",[])],I.prototype,"isHidden",null),ef([Dn,Fu("design:type",Object),Fu("design:paramtypes",[])],I.prototype,"isExpanded",null),ef([Dn,Fu("design:type",Object),Fu("design:paramtypes",[])],I.prototype,"isActive",null),ef([Dn,Fu("design:type",Object),Fu("design:paramtypes",[])],I.prototype,"isFocused",null),ef([Dn,Fu("design:type",Object),Fu("design:paramtypes",[])],I.prototype,"isSelected",null),ef([Dn,Fu("design:type",Object),Fu("design:paramtypes",[])],I.prototype,"isAllSelected",null),ef([Dn,Fu("design:type",Object),Fu("design:paramtypes",[])],I.prototype,"isPartiallySelected",null),ef([gr,Fu("design:type",Array)],I.prototype,"children",void 0),ef([gr,Fu("design:type",Number)],I.prototype,"index",void 0),ef([gr,Fu("design:type",Object)],I.prototype,"position",void 0),ef([gr,Fu("design:type",Number)],I.prototype,"height",void 0),ef([Dn,Fu("design:type",Number),Fu("design:paramtypes",[])],I.prototype,"level",null),ef([Dn,Fu("design:type",Array),Fu("design:paramtypes",[])],I.prototype,"path",null),ef([Dn,Fu("design:type",Object),Fu("design:paramtypes",[])],I.prototype,"visibleChildren",null),ef([ne,Fu("design:type",Function),Fu("design:paramtypes",[Object]),Fu("design:returntype",void 0)],I.prototype,"setIsSelected",null),ef([ne,Fu("design:type",Function),Fu("design:paramtypes",[]),Fu("design:returntype",void 0)],I.prototype,"_initChildren",null),I})();var mu=function(I,z,B,be){var jn,at=arguments.length,$t=at<3?z:null===be?be=Object.getOwnPropertyDescriptor(z,B):be;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)$t=Reflect.decorate(I,z,B,be);else for(var fr=I.length-1;fr>=0;fr--)(jn=I[fr])&&($t=(at<3?jn($t):at>3?jn(z,B,$t):jn(z,B))||$t);return at>3&&$t&&Object.defineProperty(z,B,$t),$t},Qo=function(I,z){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(I,z)};let Kl=(()=>{class I{constructor(){this.options=new Mm,this.eventNames=Object.keys(mc),this.expandedNodeIds={},this.selectedLeafNodeIds={},this.activeNodeIds={},this.hiddenNodeIds={},this.focusedNodeId=null,this.firstUpdate=!0,this.subscriptions=[]}fireEvent(B){B.treeModel=this,this.events[B.eventName].emit(B),this.events.event.emit(B)}subscribe(B,be){const at=this.events[B].subscribe(be);this.subscriptions.push(at)}getFocusedNode(){return this.focusedNode}getActiveNode(){return this.activeNodes[0]}getActiveNodes(){return this.activeNodes}getVisibleRoots(){return this.virtualRoot.visibleChildren}getFirstRoot(B=!1){return Z_(B?this.getVisibleRoots():this.roots)}getLastRoot(B=!1){return nn(B?this.getVisibleRoots():this.roots)}get isFocused(){return I.focusedTree===this}isNodeFocused(B){return this.focusedNode===B}isEmptyTree(){return this.roots&&0===this.roots.length}get focusedNode(){return this.focusedNodeId?this.getNodeById(this.focusedNodeId):null}get expandedNodes(){const B=Object.keys(this.expandedNodeIds).filter(be=>this.expandedNodeIds[be]).map(be=>this.getNodeById(be));return kh(B)}get activeNodes(){const B=Object.keys(this.activeNodeIds).filter(be=>this.activeNodeIds[be]).map(be=>this.getNodeById(be));return kh(B)}get hiddenNodes(){const B=Object.keys(this.hiddenNodeIds).filter(be=>this.hiddenNodeIds[be]).map(be=>this.getNodeById(be));return kh(B)}get selectedLeafNodes(){const B=Object.keys(this.selectedLeafNodeIds).filter(be=>this.selectedLeafNodeIds[be]).map(be=>this.getNodeById(be));return kh(B)}getNodeByPath(B,be=null){if(!B)return null;if(be=be||this.virtualRoot,0===B.length)return be;if(!be.children)return null;const at=B.shift(),$t=fh(be.children,{id:at});return $t?this.getNodeByPath(B,$t):null}getNodeById(B){const be=B.toString();return this.getNodeBy(at=>at.id.toString()===be)}getNodeBy(B,be=null){if(!(be=be||this.virtualRoot).children)return null;const at=fh(be.children,B);if(at)return at;for(let $t of be.children){const jn=this.getNodeBy(B,$t);if(jn)return jn}}isExpanded(B){return this.expandedNodeIds[B.id]}isHidden(B){return this.hiddenNodeIds[B.id]}isActive(B){return this.activeNodeIds[B.id]}isSelected(B){return this.selectedLeafNodeIds[B.id]}ngOnDestroy(){this.dispose(),this.unsubscribeAll()}dispose(){this.virtualRoot&&this.virtualRoot.dispose()}unsubscribeAll(){this.subscriptions.forEach(B=>B.unsubscribe()),this.subscriptions=[]}setData({nodes:B,options:be=null,events:at=null}){be&&(this.options=new Mm(be)),at&&(this.events=at),B&&(this.nodes=B),this.update()}update(){let B={id:this.options.rootId,virtual:!0,[this.options.childrenField]:this.nodes};this.dispose(),this.virtualRoot=new s1(B,null,this,0),this.roots=this.virtualRoot.children,this.firstUpdate?this.roots&&(this.firstUpdate=!1,this._calculateExpandedNodes()):this.fireEvent({eventName:mc.updateData})}setFocusedNode(B){this.focusedNodeId=B?B.id:null}setFocus(B){I.focusedTree=B?this:null}doForAll(B){this.roots.forEach(be=>be.doForAll(B))}focusNextNode(){let B=this.getFocusedNode(),be=B?B.findNextNode(!0,!0):this.getFirstRoot(!0);be&&be.focus()}focusPreviousNode(){let B=this.getFocusedNode(),be=B?B.findPreviousNode(!0):this.getLastRoot(!0);be&&be.focus()}focusDrillDown(){let B=this.getFocusedNode();if(B&&B.isCollapsed&&B.hasChildren)B.toggleExpanded();else{let be=B?B.getFirstChild(!0):this.getFirstRoot(!0);be&&be.focus()}}focusDrillUp(){let B=this.getFocusedNode();if(B)if(B.isExpanded)B.toggleExpanded();else{let be=B.realParent;be&&be.focus()}}setActiveNode(B,be,at=!1){at?this._setActiveNodeMulti(B,be):this._setActiveNodeSingle(B,be),be?(B.focus(this.options.scrollOnActivate),this.fireEvent({eventName:mc.activate,node:B}),this.fireEvent({eventName:mc.nodeActivate,node:B})):(this.fireEvent({eventName:mc.deactivate,node:B}),this.fireEvent({eventName:mc.nodeDeactivate,node:B}))}setSelectedNode(B,be){this.selectedLeafNodeIds=Object.assign({},this.selectedLeafNodeIds,{[B.id]:be}),be?(B.focus(),this.fireEvent({eventName:mc.select,node:B})):this.fireEvent({eventName:mc.deselect,node:B})}setExpandedNode(B,be){this.expandedNodeIds=Object.assign({},this.expandedNodeIds,{[B.id]:be}),this.fireEvent({eventName:mc.toggleExpanded,node:B,isExpanded:be})}expandAll(){this.roots.forEach(B=>B.expandAll())}collapseAll(){this.roots.forEach(B=>B.collapseAll())}setIsHidden(B,be){this.hiddenNodeIds=Object.assign({},this.hiddenNodeIds,{[B.id]:be})}setHiddenNodeIds(B){this.hiddenNodeIds=B.reduce((be,at)=>Object.assign(be,{[at]:!0}),{})}performKeyAction(B,be){const at=this.options.actionMapping.keys[be.keyCode];return!!at&&(be.preventDefault(),at(this,B,be),!0)}filterNodes(B,be=!0){let at;if(!B)return this.clearFilter();if(Rf(B))at=jn=>-1!==jn.displayField.toLowerCase().indexOf(B.toLowerCase());else{if(!(0,Sc.Z)(B))return console.error("Don't know what to do with filter",B),void console.error("Should be either a string or function");at=B}const $t={};this.roots.forEach(jn=>this._filterNode($t,jn,at,be)),this.hiddenNodeIds=$t,this.fireEvent({eventName:mc.changeFilter})}clearFilter(){this.hiddenNodeIds={},this.fireEvent({eventName:mc.changeFilter})}moveNode(B,be){const at=B.getIndexInParent(),$t=B.parent;if(!this.canMoveNode(B,be,at))return;const jn=$t.getField("children");be.parent.getField("children")||be.parent.setField("children",[]);const fr=be.parent.getField("children"),ui=jn.splice(at,1)[0];let Ro=$t===be.parent&&be.index>at?be.index-1:be.index;fr.splice(Ro,0,ui),$t.treeModel.update(),be.parent.treeModel!==$t.treeModel&&be.parent.treeModel.update(),this.fireEvent({eventName:mc.moveNode,node:ui,to:{parent:be.parent.data,index:Ro},from:{parent:$t.data,index:at}})}copyNode(B,be){const at=B.getIndexInParent();if(!this.canMoveNode(B,be,at))return;be.parent.getField("children")||be.parent.setField("children",[]);const $t=be.parent.getField("children"),jn=this.options.getNodeClone(B);$t.splice(be.index,0,jn),B.treeModel.update(),be.parent.treeModel!==B.treeModel&&be.parent.treeModel.update(),this.fireEvent({eventName:mc.copyNode,node:jn,to:{parent:be.parent.data,index:be.index}})}getState(){return{expandedNodeIds:this.expandedNodeIds,selectedLeafNodeIds:this.selectedLeafNodeIds,activeNodeIds:this.activeNodeIds,hiddenNodeIds:this.hiddenNodeIds,focusedNodeId:this.focusedNodeId}}setState(B){!B||Object.assign(this,{expandedNodeIds:B.expandedNodeIds||{},selectedLeafNodeIds:B.selectedLeafNodeIds||{},activeNodeIds:B.activeNodeIds||{},hiddenNodeIds:B.hiddenNodeIds||{},focusedNodeId:B.focusedNodeId})}subscribeToState(B){ti(()=>B(this.getState()))}canMoveNode(B,be,at){return at||B.getIndexInParent(),(B.parent!==be.parent||at!==be.index)&&!be.parent.isDescendantOf(B)}calculateExpandedNodes(){this._calculateExpandedNodes()}_filterNode(B,be,at,$t){let jn=at(be);return be.children&&be.children.forEach(fr=>{this._filterNode(B,fr,at,$t)&&(jn=!0)}),jn||(B[be.id]=!0),$t&&jn&&be.ensureVisible(),jn}_calculateExpandedNodes(B=null){(B=B||this.virtualRoot).data[this.options.isExpandedField]&&(this.expandedNodeIds=Object.assign({},this.expandedNodeIds,{[B.id]:!0})),B.children&&B.children.forEach(be=>this._calculateExpandedNodes(be))}_setActiveNodeSingle(B,be){this.activeNodes.filter(at=>at!==B).forEach(at=>{this.fireEvent({eventName:mc.deactivate,node:at}),this.fireEvent({eventName:mc.nodeDeactivate,node:at})}),this.activeNodeIds=be?{[B.id]:!0}:{}}_setActiveNodeMulti(B,be){this.activeNodeIds=Object.assign({},this.activeNodeIds,{[B.id]:be})}}return I.\u0275fac=function(B){return new(B||I)},I.\u0275prov=r.Yz7({token:I,factory:I.\u0275fac}),I.focusedTree=null,I})();mu([gr,Qo("design:type",Array)],Kl.prototype,"roots",void 0),mu([gr,Qo("design:type",Object)],Kl.prototype,"expandedNodeIds",void 0),mu([gr,Qo("design:type",Object)],Kl.prototype,"selectedLeafNodeIds",void 0),mu([gr,Qo("design:type",Object)],Kl.prototype,"activeNodeIds",void 0),mu([gr,Qo("design:type",Object)],Kl.prototype,"hiddenNodeIds",void 0),mu([gr,Qo("design:type",Object)],Kl.prototype,"focusedNodeId",void 0),mu([gr,Qo("design:type",s1)],Kl.prototype,"virtualRoot",void 0),mu([Dn,Qo("design:type",Object),Qo("design:paramtypes",[])],Kl.prototype,"focusedNode",null),mu([Dn,Qo("design:type",Object),Qo("design:paramtypes",[])],Kl.prototype,"expandedNodes",null),mu([Dn,Qo("design:type",Object),Qo("design:paramtypes",[])],Kl.prototype,"activeNodes",null),mu([Dn,Qo("design:type",Object),Qo("design:paramtypes",[])],Kl.prototype,"hiddenNodes",null),mu([Dn,Qo("design:type",Object),Qo("design:paramtypes",[])],Kl.prototype,"selectedLeafNodes",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[Object]),Qo("design:returntype",void 0)],Kl.prototype,"setData",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[]),Qo("design:returntype",void 0)],Kl.prototype,"update",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[Object]),Qo("design:returntype",void 0)],Kl.prototype,"setFocusedNode",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[Object]),Qo("design:returntype",void 0)],Kl.prototype,"setFocus",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[Object]),Qo("design:returntype",void 0)],Kl.prototype,"doForAll",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[]),Qo("design:returntype",void 0)],Kl.prototype,"focusNextNode",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[]),Qo("design:returntype",void 0)],Kl.prototype,"focusPreviousNode",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[]),Qo("design:returntype",void 0)],Kl.prototype,"focusDrillDown",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[]),Qo("design:returntype",void 0)],Kl.prototype,"focusDrillUp",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[Object,Object,Object]),Qo("design:returntype",void 0)],Kl.prototype,"setActiveNode",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[Object,Object]),Qo("design:returntype",void 0)],Kl.prototype,"setSelectedNode",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[Object,Object]),Qo("design:returntype",void 0)],Kl.prototype,"setExpandedNode",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[]),Qo("design:returntype",void 0)],Kl.prototype,"expandAll",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[]),Qo("design:returntype",void 0)],Kl.prototype,"collapseAll",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[Object,Object]),Qo("design:returntype",void 0)],Kl.prototype,"setIsHidden",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[Object]),Qo("design:returntype",void 0)],Kl.prototype,"setHiddenNodeIds",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[Object,Object]),Qo("design:returntype",void 0)],Kl.prototype,"filterNodes",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[]),Qo("design:returntype",void 0)],Kl.prototype,"clearFilter",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[Object,Object]),Qo("design:returntype",void 0)],Kl.prototype,"moveNode",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[Object,Object]),Qo("design:returntype",void 0)],Kl.prototype,"copyNode",null),mu([ne,Qo("design:type",Function),Qo("design:paramtypes",[Object]),Qo("design:returntype",void 0)],Kl.prototype,"setState",null);let lv=(()=>{class I{constructor(){this._draggedElement=null}set(B){this._draggedElement=B}get(){return this._draggedElement}isDragging(){return!!this.get()}}return I.\u0275fac=function(B){return new(B||I)},I.\u0275prov=(0,r.Yz7)({factory:function(){return new I},token:I,providedIn:"root"}),I})();var Wh=function(I,z,B,be){var jn,at=arguments.length,$t=at<3?z:null===be?be=Object.getOwnPropertyDescriptor(z,B):be;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)$t=Reflect.decorate(I,z,B,be);else for(var fr=I.length-1;fr>=0;fr--)(jn=I[fr])&&($t=(at<3?jn($t):at>3?jn(z,B,$t):jn(z,B))||$t);return at>3&&$t&&Object.defineProperty(z,B,$t),$t},Sd=function(I,z){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(I,z)};let Wf=(()=>{class I{constructor(B){this.treeModel=B,this.yBlocks=0,this.x=0,this.viewportHeight=null,this.viewport=null,B.virtualScroll=this,this._dispose=[ti(()=>this.fixScroll())]}get y(){return 150*this.yBlocks}get totalHeight(){return this.treeModel.virtualRoot?this.treeModel.virtualRoot.height:0}fireEvent(B){this.treeModel.fireEvent(B)}init(){const B=this.recalcPositions.bind(this);B(),this._dispose=[...this._dispose,ts(()=>this.treeModel.roots,B),ts(()=>this.treeModel.expandedNodeIds,B),ts(()=>this.treeModel.hiddenNodeIds,B)],this.treeModel.subscribe(mc.loadNodeChildren,B)}isEnabled(){return this.treeModel.options.useVirtualScroll}_setYBlocks(B){this.yBlocks=B}recalcPositions(){this.treeModel.virtualRoot.height=this._getPositionAfter(this.treeModel.getVisibleRoots(),0)}_getPositionAfter(B,be){let at=be;return B.forEach($t=>{$t.position=at,at=this._getPositionAfterNode($t,at)}),at}_getPositionAfterNode(B,be){let at=B.getSelfHeight()+be;return B.children&&B.isExpanded&&(at=this._getPositionAfter(B.visibleChildren,at)),B.height=at-be,at}clear(){this._dispose.forEach(B=>B())}setViewport(B){Object.assign(this,{viewport:B,x:B.scrollLeft,yBlocks:Math.round(B.scrollTop/150),viewportHeight:B.getBoundingClientRect?B.getBoundingClientRect().height:0})}scrollIntoView(B,be,at=!0){if(B.options.scrollContainer){const $t=B.options.scrollContainer,jn=$t.getBoundingClientRect().height,fr=$t.getBoundingClientRect().top,ui=this.viewport.getBoundingClientRect().top+B.position-fr;(be||ui<$t.scrollTop||ui+B.getSelfHeight()>$t.scrollTop+jn)&&($t.scrollTop=at?ui-jn/2:ui)}else(be||B.position<this.y||B.position+B.getSelfHeight()>this.y+this.viewportHeight)&&this.viewport&&(this.viewport.scrollTop=at?B.position-this.viewportHeight/2:B.position,this._setYBlocks(Math.floor(this.viewport.scrollTop/150)))}getViewportNodes(B){if(!B)return[];const be=B.filter(Ro=>!Ro.isHidden);if(!this.isEnabled())return be;if(!this.viewportHeight||!be.length)return[];const at=cv(be,Ro=>Ro.position+500>this.y||Ro.position+Ro.height>this.y),$t=cv(be,Ro=>Ro.position-500>this.y+this.viewportHeight,at),jn=[];if($t-at>(1e3+this.viewportHeight)/be[0].treeModel.options.options.nodeHeight)return[];for(let Ro=at;Ro<=$t;Ro++)jn.push(be[Ro]);return jn}fixScroll(){const B=Math.max(0,this.totalHeight-this.viewportHeight);this.y<0&&this._setYBlocks(0),this.y>B&&this._setYBlocks(B/150)}}return I.\u0275fac=function(B){return new(B||I)(r.LFG(Kl))},I.\u0275prov=r.Yz7({token:I,factory:I.\u0275fac}),I})();function cv(I,z,B=0){let be=B,at=I.length-1;for(;be!==at;){let $t=Math.floor((be+at)/2);z(I[$t])?at=$t:be=be===$t?at:$t}return be}Wh([gr,Sd("design:type",Object)],Wf.prototype,"yBlocks",void 0),Wh([gr,Sd("design:type",Object)],Wf.prototype,"x",void 0),Wh([gr,Sd("design:type",Object)],Wf.prototype,"viewportHeight",void 0),Wh([Dn,Sd("design:type",Object),Sd("design:paramtypes",[])],Wf.prototype,"y",null),Wh([Dn,Sd("design:type",Object),Sd("design:paramtypes",[])],Wf.prototype,"totalHeight",null),Wh([ne,Sd("design:type",Function),Sd("design:paramtypes",[Object]),Sd("design:returntype",void 0)],Wf.prototype,"_setYBlocks",null),Wh([ne,Sd("design:type",Function),Sd("design:paramtypes",[]),Sd("design:returntype",void 0)],Wf.prototype,"recalcPositions",null),Wh([ne,Sd("design:type",Function),Sd("design:paramtypes",[Object]),Sd("design:returntype",void 0)],Wf.prototype,"setViewport",null),Wh([ne,Sd("design:type",Function),Sd("design:paramtypes",[Object,Object,Object]),Sd("design:returntype",void 0)],Wf.prototype,"scrollIntoView",null);let dv=(()=>{class I{}return I.\u0275fac=function(B){return new(B||I)},I.\u0275cmp=r.Xpm({type:I,selectors:[["tree-loading-component"]],inputs:{template:"template",node:"node"},decls:2,vars:5,consts:[[4,"ngIf"],[3,"ngTemplateOutlet","ngTemplateOutletContext"]],template:function(B,be){1&B&&(r.YNc(0,b_,2,0,"span",0),r.GkF(1,1)),2&B&&(r.Q6J("ngIf",!be.template),r.xp6(1),r.Q6J("ngTemplateOutlet",be.template)("ngTemplateOutletContext",r.VKq(3,jh,be.node)))},directives:[u.O5,u.tP],encapsulation:2}),I})(),Q_=(()=>{class I{constructor(B,be,at){this.elementRef=B,this.ngZone=be,this.virtualScroll=at,this.setViewport=gg(()=>{this.virtualScroll.setViewport(this.elementRef.nativeElement)},17),this.scrollEventHandler=this.setViewport.bind(this)}ngOnInit(){this.virtualScroll.init()}ngAfterViewInit(){setTimeout(()=>{this.setViewport(),this.virtualScroll.fireEvent({eventName:mc.initialized})});let B=this.elementRef.nativeElement;this.ngZone.runOutsideAngular(()=>{B.addEventListener("scroll",this.scrollEventHandler)})}ngOnDestroy(){this.virtualScroll.clear(),this.elementRef.nativeElement.removeEventListener("scroll",this.scrollEventHandler)}getTotalHeight(){return this.virtualScroll.isEnabled()&&this.virtualScroll.totalHeight+"px"||"auto"}}return I.\u0275fac=function(B){return new(B||I)(r.Y36(r.SBq),r.Y36(r.R0b),r.Y36(Wf))},I.\u0275cmp=r.Xpm({type:I,selectors:[["tree-viewport"]],features:[r._Bn([Wf])],ngContentSelectors:Tg,decls:1,vars:2,consts:[[4,"treeMobxAutorun"]],template:function(B,be){1&B&&(r.F$t(),r.YNc(0,E_,3,2,"ng-container",0)),2&B&&r.Q6J("treeMobxAutorun",r.DdM(1,jp))},directives:[Qr],encapsulation:2}),I})(),Om=(()=>{class I{constructor(B,be){this.treeModel=B,this.treeDraggedElement=be,B.eventNames.forEach(at=>this[at]=new r.vpe),B.subscribeToState(at=>this.stateChange.emit(at))}set nodes(B){}set options(B){}set focused(B){this.treeModel.setFocus(B)}set state(B){this.treeModel.setState(B)}onKeydown(B){if(!this.treeModel.isFocused||Yg(["input","textarea"],document.activeElement.tagName.toLowerCase()))return;const be=this.treeModel.getFocusedNode();this.treeModel.performKeyAction(be,B)}onMousedown(B){(function be(at,$t){return!at||at.localName!==$t&&be(at.parentElement,$t)})(B.target,"tree-root")&&this.treeModel.setFocus(!1)}ngOnChanges(B){(B.options||B.nodes)&&this.treeModel.setData({options:B.options&&B.options.currentValue,nodes:B.nodes&&B.nodes.currentValue,events:y_(this,this.treeModel.eventNames)})}sizeChanged(){this.viewportComponent.setViewport()}}return I.\u0275fac=function(B){return new(B||I)(r.Y36(Kl),r.Y36(lv))},I.\u0275cmp=r.Xpm({type:I,selectors:[["Tree"],["tree-root"]],contentQueries:function(B,be,at){if(1&B&&(r.Suo(at,T_,5),r.Suo(at,Zg,5),r.Suo(at,Gh,5),r.Suo(at,Sg,5)),2&B){let $t;r.iGM($t=r.CRH())&&(be.loadingTemplate=$t.first),r.iGM($t=r.CRH())&&(be.treeNodeTemplate=$t.first),r.iGM($t=r.CRH())&&(be.treeNodeWrapperTemplate=$t.first),r.iGM($t=r.CRH())&&(be.treeNodeFullTemplate=$t.first)}},viewQuery:function(B,be){if(1&B&&r.Gf(rv,5),2&B){let at;r.iGM(at=r.CRH())&&(be.viewportComponent=at.first)}},hostBindings:function(B,be){1&B&&r.NdJ("keydown",function($t){return be.onKeydown($t)},!1,r.pYS)("mousedown",function($t){return be.onMousedown($t)},!1,r.pYS)},inputs:{nodes:"nodes",options:"options",focused:"focused",state:"state"},outputs:{toggleExpanded:"toggleExpanded",activate:"activate",deactivate:"deactivate",nodeActivate:"nodeActivate",nodeDeactivate:"nodeDeactivate",select:"select",deselect:"deselect",focus:"focus",blur:"blur",updateData:"updateData",initialized:"initialized",moveNode:"moveNode",copyNode:"copyNode",loadNodeChildren:"loadNodeChildren",changeFilter:"changeFilter",event:"event",stateChange:"stateChange"},features:[r._Bn([Kl]),r.TTD],decls:5,vars:6,consts:[["viewport",""],[1,"angular-tree-component"],[3,"nodes","treeModel","templates",4,"ngIf"],["class","empty-tree-drop-slot",3,"dropIndex","node",4,"ngIf"],[3,"nodes","treeModel","templates"],[1,"empty-tree-drop-slot",3,"dropIndex","node"]],template:function(B,be){1&B&&(r.TgZ(0,"tree-viewport",null,0),r.TgZ(2,"div",1),r.YNc(3,Tm,1,8,"tree-node-collection",2),r.YNc(4,S_,1,2,"tree-node-drop-slot",3),r.qZA(),r.qZA()),2&B&&(r.xp6(2),r.ekj("node-dragging",be.treeDraggedElement.isDragging())("angular-tree-component-rtl",be.treeModel.options.rtl),r.xp6(1),r.Q6J("ngIf",be.treeModel.roots),r.xp6(1),r.Q6J("ngIf",be.treeModel.isEmptyTree()))},directives:function(){return[Q_,u.O5,Jh,Mp]},encapsulation:2}),I})(),jg=(()=>{class I{}return I.\u0275fac=function(B){return new(B||I)},I.\u0275cmp=r.Xpm({type:I,selectors:[["TreeNode"],["tree-node"]],inputs:{node:"node",index:"index",templates:"templates"},decls:1,vars:2,consts:[[4,"treeMobxAutorun"],[3,"class","tree-node","tree-node-expanded","tree-node-collapsed","tree-node-leaf","tree-node-active","tree-node-focused",4,"ngIf"],[3,"ngTemplateOutlet","ngTemplateOutletContext"],[3,"dropIndex","node",4,"ngIf"],[3,"node","index","templates"],[3,"node","templates"],[3,"dropIndex","node"]],template:function(B,be){1&B&&r.YNc(0,Se,3,8,"ng-container",0),2&B&&r.Q6J("treeMobxAutorun",r.DdM(1,jp))},directives:function(){return[Qr,u.O5,u.tP,Vp,pv,Mp]},encapsulation:2}),I})(),fv=(()=>{class I{}return I.\u0275fac=function(B){return new(B||I)},I.\u0275cmp=r.Xpm({type:I,selectors:[["tree-node-content"]],inputs:{node:"node",index:"index",template:"template"},decls:2,vars:7,consts:[[4,"ngIf"],[3,"ngTemplateOutlet","ngTemplateOutletContext"]],template:function(B,be){1&B&&(r.YNc(0,We,2,1,"span",0),r.GkF(1,1)),2&B&&(r.Q6J("ngIf",!be.template),r.xp6(1),r.Q6J("ngTemplateOutlet",be.template)("ngTemplateOutletContext",r.kEZ(3,Nt,be.node,be.node,be.index)))},directives:[u.O5,u.tP],encapsulation:2}),I})(),Mp=(()=>{class I{onDrop(B){this.node.mouseAction("drop",B.event,{from:B.element,to:{parent:this.node,index:this.dropIndex}})}allowDrop(B,be){return this.node.options.allowDrop(B,{parent:this.node,index:this.dropIndex},be)}}return I.\u0275fac=function(B){return new(B||I)},I.\u0275cmp=r.Xpm({type:I,selectors:[["TreeNodeDropSlot"],["tree-node-drop-slot"]],inputs:{node:"node",dropIndex:"dropIndex"},decls:1,vars:2,consts:[[1,"node-drop-slot",3,"treeAllowDrop","allowDragoverStyling","treeDrop"]],template:function(B,be){1&B&&(r.TgZ(0,"div",0),r.NdJ("treeDrop",function($t){return be.onDrop($t)}),r.qZA()),2&B&&r.Q6J("treeAllowDrop",be.allowDrop.bind(be))("allowDragoverStyling",!0)},directives:function(){return[Dm]},encapsulation:2}),I})(),wm=(()=>{class I{}return I.\u0275fac=function(B){return new(B||I)},I.\u0275cmp=r.Xpm({type:I,selectors:[["tree-node-expander"]],inputs:{node:"node"},decls:1,vars:2,consts:[[4,"treeMobxAutorun"],["class","toggle-children-wrapper",3,"toggle-children-wrapper-expanded","toggle-children-wrapper-collapsed","click",4,"ngIf"],["class","toggle-children-placeholder",4,"ngIf"],[1,"toggle-children-wrapper",3,"click"],[1,"toggle-children"],[1,"toggle-children-placeholder"]],template:function(B,be){1&B&&r.YNc(0,yr,3,2,"ng-container",0),2&B&&r.Q6J("treeMobxAutorun",r.DdM(1,jp))},directives:[Qr,u.O5],encapsulation:2}),I})(),pv=(()=>{class I{}return I.\u0275fac=function(B){return new(B||I)},I.\u0275cmp=r.Xpm({type:I,selectors:[["tree-node-children"]],inputs:{node:"node",templates:"templates"},decls:1,vars:2,consts:[[4,"treeMobxAutorun"],[3,"tree-children","tree-children-no-padding",4,"treeAnimateOpen","treeAnimateOpenSpeed","treeAnimateOpenAcceleration","treeAnimateOpenEnabled"],[3,"nodes","templates","treeModel",4,"ngIf"],["class","tree-node-loading",3,"padding-left","template","node",4,"ngIf"],[3,"nodes","templates","treeModel"],[1,"tree-node-loading",3,"template","node"]],template:function(B,be){1&B&&r.YNc(0,go,2,4,"ng-container",0),2&B&&r.Q6J("treeMobxAutorun",r.DdM(1,jp))},directives:function(){return[Qr,_v,u.O5,Jh,dv]},encapsulation:2}),I})();const Gg=Object.assign(function(...I){return ne(...I)},ne),hv=Object.assign(function(...I){return Dn(...I)},Dn),Cg=Object.assign(function(...I){return gr(...I)},gr);var Ap=function(I,z,B,be){var jn,at=arguments.length,$t=at<3?z:null===be?be=Object.getOwnPropertyDescriptor(z,B):be;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)$t=Reflect.decorate(I,z,B,be);else for(var fr=I.length-1;fr>=0;fr--)(jn=I[fr])&&($t=(at<3?jn($t):at>3?jn(z,B,$t):jn(z,B))||$t);return at>3&&$t&&Object.defineProperty(z,B,$t),$t},ip=function(I,z){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(I,z)};let Jh=(()=>{class I{constructor(){this._dispose=[]}get nodes(){return this._nodes}set nodes(B){this.setNodes(B)}get marginTop(){const B=this.viewportNodes&&this.viewportNodes.length&&this.viewportNodes[0];return(B&&B.parent?B.position-B.parent.position-B.parent.getSelfHeight():0)+"px"}setNodes(B){this._nodes=B}ngOnInit(){this.virtualScroll=this.treeModel.virtualScroll,this._dispose=[ts(()=>this.virtualScroll.getViewportNodes(this.nodes).map(B=>B.index),B=>{this.viewportNodes=B.map(be=>this.nodes[be])},{compareStructural:!0,fireImmediately:!0}),ts(()=>this.nodes,B=>{this.viewportNodes=this.virtualScroll.getViewportNodes(B)})]}ngOnDestroy(){this._dispose.forEach(B=>B())}trackNode(B,be){return be.id}}return I.\u0275fac=function(B){return new(B||I)},I.\u0275cmp=r.Xpm({type:I,selectors:[["tree-node-collection"]],inputs:{nodes:"nodes",treeModel:"treeModel",templates:"templates"},decls:1,vars:2,consts:[[4,"treeMobxAutorun"],[3,"node","index","templates",4,"ngFor","ngForOf","ngForTrackBy"],[3,"node","index","templates"]],template:function(B,be){1&B&&r.YNc(0,Fa,3,4,"ng-container",0),2&B&&r.Q6J("treeMobxAutorun",r.DdM(1,jp))},directives:[Qr,u.sg,jg],encapsulation:2}),I})();Ap([Cg,ip("design:type",Object)],Jh.prototype,"_nodes",void 0),Ap([Cg,ip("design:type",Array)],Jh.prototype,"viewportNodes",void 0),Ap([hv,ip("design:type",String),ip("design:paramtypes",[])],Jh.prototype,"marginTop",null),Ap([Gg,ip("design:type",Function),ip("design:paramtypes",[Object]),ip("design:returntype",void 0)],Jh.prototype,"setNodes",null);let Vp=(()=>{class I{constructor(){}}return I.\u0275fac=function(B){return new(B||I)},I.\u0275cmp=r.Xpm({type:I,selectors:[["tree-node-wrapper"]],inputs:{node:"node",index:"index",templates:"templates"},decls:2,vars:8,consts:[["class","node-wrapper",3,"padding-left",4,"ngIf"],[3,"ngTemplateOutlet","ngTemplateOutletContext"],[1,"node-wrapper"],[3,"node",4,"ngIf"],[3,"node"],[1,"node-content-wrapper",3,"treeAllowDrop","allowDragoverStyling","treeDrag","treeDragEnabled","click","dblclick","mouseover","mouseout","contextmenu","treeDrop","treeDropDragOver","treeDropDragLeave","treeDropDragEnter"],[3,"node","index","template"]],template:function(B,be){1&B&&(r.YNc(0,ni,5,15,"div",0),r.GkF(1,1)),2&B&&(r.Q6J("ngIf",!be.templates.treeNodeWrapperTemplate),r.xp6(1),r.Q6J("ngTemplateOutlet",be.templates.treeNodeWrapperTemplate)("ngTemplateOutletContext",r.l5B(3,G,be.node,be.node,be.index,be.templates)))},directives:function(){return[u.O5,u.tP,wm,Rm,Dm,fv,X_]},encapsulation:2}),I})(),X_=(()=>{class I{}return I.\u0275fac=function(B){return new(B||I)},I.\u0275cmp=r.Xpm({type:I,selectors:[["tree-node-checkbox"]],inputs:{node:"node"},decls:1,vars:2,consts:[[4,"treeMobxAutorun"],["type","checkbox",1,"tree-node-checkbox",3,"checked","indeterminate","click"]],template:function(B,be){1&B&&r.YNc(0,Tr,2,2,"ng-container",0),2&B&&r.Q6J("treeMobxAutorun",r.DdM(1,jp))},directives:[Qr],encapsulation:2}),I})();const C_="is-dragging-over",xm="is-dragging-over-disabled";let Dm=(()=>{class I{constructor(B,be,at,$t){this.el=B,this.renderer=be,this.treeDraggedElement=at,this.ngZone=$t,this.allowDragoverStyling=!0,this.onDropCallback=new r.vpe,this.onDragOverCallback=new r.vpe,this.onDragLeaveCallback=new r.vpe,this.onDragEnterCallback=new r.vpe,this._allowDrop=(jn,fr)=>!0,this.dragOverEventHandler=this.onDragOver.bind(this),this.dragEnterEventHandler=this.onDragEnter.bind(this),this.dragLeaveEventHandler=this.onDragLeave.bind(this)}set treeAllowDrop(B){this._allowDrop=B instanceof Function?B:(be,at)=>B}allowDrop(B){return this._allowDrop(this.treeDraggedElement.get(),B)}ngAfterViewInit(){let B=this.el.nativeElement;this.ngZone.runOutsideAngular(()=>{B.addEventListener("dragover",this.dragOverEventHandler),B.addEventListener("dragenter",this.dragEnterEventHandler),B.addEventListener("dragleave",this.dragLeaveEventHandler)})}ngOnDestroy(){let B=this.el.nativeElement;B.removeEventListener("dragover",this.dragOverEventHandler),B.removeEventListener("dragenter",this.dragEnterEventHandler),B.removeEventListener("dragleave",this.dragLeaveEventHandler)}onDragOver(B){if(!this.allowDrop(B))return this.allowDragoverStyling?this.addDisabledClass():void 0;this.onDragOverCallback.emit({event:B,element:this.treeDraggedElement.get()}),B.preventDefault(),this.allowDragoverStyling&&this.addClass()}onDragEnter(B){!this.allowDrop(B)||(B.preventDefault(),this.onDragEnterCallback.emit({event:B,element:this.treeDraggedElement.get()}))}onDragLeave(B){if(!this.allowDrop(B))return this.allowDragoverStyling?this.removeDisabledClass():void 0;this.onDragLeaveCallback.emit({event:B,element:this.treeDraggedElement.get()}),this.allowDragoverStyling&&this.removeClass()}onDrop(B){!this.allowDrop(B)||(B.preventDefault(),this.onDropCallback.emit({event:B,element:this.treeDraggedElement.get()}),this.allowDragoverStyling&&this.removeClass(),this.treeDraggedElement.set(null))}addClass(){this.renderer.addClass(this.el.nativeElement,C_)}removeClass(){this.renderer.removeClass(this.el.nativeElement,C_)}addDisabledClass(){this.renderer.addClass(this.el.nativeElement,xm)}removeDisabledClass(){this.renderer.removeClass(this.el.nativeElement,xm)}}return I.\u0275fac=function(B){return new(B||I)(r.Y36(r.SBq),r.Y36(r.Qsj),r.Y36(lv),r.Y36(r.R0b))},I.\u0275dir=r.lG2({type:I,selectors:[["","treeDrop",""]],hostBindings:function(B,be){1&B&&r.NdJ("drop",function($t){return be.onDrop($t)})},inputs:{allowDragoverStyling:"allowDragoverStyling",treeAllowDrop:"treeAllowDrop"},outputs:{onDropCallback:"treeDrop",onDragOverCallback:"treeDropDragOver",onDragLeaveCallback:"treeDropDragLeave",onDragEnterCallback:"treeDropDragEnter"}}),I})(),Rm=(()=>{class I{constructor(B,be,at,$t){this.el=B,this.renderer=be,this.treeDraggedElement=at,this.ngZone=$t,this.dragEventHandler=this.onDrag.bind(this)}ngAfterViewInit(){let B=this.el.nativeElement;this.ngZone.runOutsideAngular(()=>{B.addEventListener("drag",this.dragEventHandler)})}ngDoCheck(){this.renderer.setAttribute(this.el.nativeElement,"draggable",this.treeDragEnabled?"true":"false")}ngOnDestroy(){this.el.nativeElement.removeEventListener("drag",this.dragEventHandler)}onDragStart(B){B.dataTransfer.setData("text",B.target.id),this.treeDraggedElement.set(this.draggedElement),this.draggedElement.mouseAction&&this.draggedElement.mouseAction("dragStart",B)}onDrag(B){this.draggedElement.mouseAction&&this.draggedElement.mouseAction("drag",B)}onDragEnd(){this.draggedElement.mouseAction&&this.draggedElement.mouseAction("dragEnd"),this.treeDraggedElement.set(null)}}return I.\u0275fac=function(B){return new(B||I)(r.Y36(r.SBq),r.Y36(r.Qsj),r.Y36(lv),r.Y36(r.R0b))},I.\u0275dir=r.lG2({type:I,selectors:[["","treeDrag",""]],hostBindings:function(B,be){1&B&&r.NdJ("dragstart",function($t){return be.onDragStart($t)})("dragend",function(){return be.onDragEnd()})},inputs:{draggedElement:["treeDrag","draggedElement"],treeDragEnabled:"treeDragEnabled"}}),I})(),_v=(()=>{class I{constructor(B,be,at){this.renderer=B,this.templateRef=be,this.viewContainerRef=at}set isOpen(B){B?(this._show(),this.isEnabled&&!1===this._isOpen&&this._animateOpen()):this.isEnabled?this._animateClose():this._hide(),this._isOpen=!!B}_show(){this.innerElement||(this.innerElement=this.viewContainerRef.createEmbeddedView(this.templateRef).rootNodes[0])}_hide(){this.viewContainerRef.clear(),this.innerElement=null}_animateOpen(){let B=this.animateSpeed,be=this.animateAcceleration,at=0;this.renderer.setStyle(this.innerElement,"max-height","0"),setTimeout(()=>{const $t=setInterval(()=>{if(!this._isOpen||!this.innerElement)return clearInterval($t);at+=B;const jn=Math.round(at);this.renderer.setStyle(this.innerElement,"max-height",`${jn}px`);const fr=this.innerElement.getBoundingClientRect?this.innerElement.getBoundingClientRect().height:0;B*=be,be*=1.005,fr<jn&&(this.renderer.setStyle(this.innerElement,"max-height",null),clearInterval($t))},17)})}_animateClose(){if(!this.innerElement)return;let B=this.animateSpeed,be=this.animateAcceleration,at=this.innerElement.getBoundingClientRect().height;const $t=setInterval(()=>{if(this._isOpen||!this.innerElement)return clearInterval($t);at-=B,this.renderer.setStyle(this.innerElement,"max-height",`${at}px`),B*=be,be*=1.005,at<=0&&(this.viewContainerRef.clear(),this.innerElement=null,clearInterval($t))},17)}}return I.\u0275fac=function(B){return new(B||I)(r.Y36(r.Qsj),r.Y36(r.Rgc),r.Y36(r.s_b))},I.\u0275dir=r.lG2({type:I,selectors:[["","treeAnimateOpen",""]],inputs:{isOpen:["treeAnimateOpen","isOpen"],animateSpeed:["treeAnimateOpenSpeed","animateSpeed"],animateAcceleration:["treeAnimateOpenAcceleration","animateAcceleration"],isEnabled:["treeAnimateOpenEnabled","isEnabled"]}}),I})(),zg=(()=>{class I{}return I.\u0275fac=function(B){return new(B||I)},I.\u0275mod=r.oAB({type:I}),I.\u0275inj=r.cJS({providers:[],imports:[[u.ez]]}),I})()},38549:(v,T,i)=>{"use strict";i.d(T,{Kz:()=>E,xm:()=>Rl,_A:()=>nc,vL:()=>Ul,_D:()=>fa,lQ:()=>pu,VL:()=>Gl,M:()=>Yu,jt:()=>hc,TH:()=>wf,Vi:()=>Vl,XC:()=>Mc,iD:()=>oc,J4:()=>qt,FF:()=>ye,Pz:()=>xn,uN:()=>nn,nv:()=>Pn,Vx:()=>ir,Oz:()=>Xs,tO:()=>Lo,M2:()=>Kd,o8:()=>na,AX:()=>bi,dT:()=>_l,Ly:()=>zc,ZQ:()=>qf,Pm:()=>kd,UL:()=>Yf,_L:()=>Ph,xI:()=>rh,HK:()=>Bp,dR:()=>ac,ZS:()=>oh});var r=i(74788),u=i(12057),p=i(59796),d=i(56693),e=i(55197),_=i(20509);function y(...Y){if(1===Y.length){if(!(0,p.k)(Y[0]))return Y[0];Y=Y[0]}return(0,d.n)(Y,void 0).lift(new S)}class S{call(fe,w){return w.subscribe(new A(fe))}}class A extends e.L{constructor(fe){super(fe),this.hasFirst=!1,this.observables=[],this.subscriptions=[]}_next(fe){this.observables.push(fe)}_complete(){const fe=this.observables,w=fe.length;if(0===w)this.destination.complete();else{for(let X=0;X<w&&!this.hasFirst;X++){const ct=(0,_.D)(this,fe[X],void 0,X);this.subscriptions&&this.subscriptions.push(ct),this.add(ct)}this.observables=null}}notifyNext(fe,w,X){if(!this.hasFirst){this.hasFirst=!0;for(let ke=0;ke<this.subscriptions.length;ke++)if(ke!==X){let ct=this.subscriptions[ke];ct.unsubscribe(),this.remove(ct)}this.subscriptions=null}this.destination.next(w)}}var N=i(77393),L=i(20377),Z=i(85345);function J(...Y){const fe=Y[Y.length-1];return"function"==typeof fe&&Y.pop(),(0,d.n)(Y,void 0).lift(new K(fe))}class K{constructor(fe){this.resultSelector=fe}call(fe,w){return w.subscribe(new ee(fe,this.resultSelector))}}class ee extends N.L{constructor(fe,w,X=Object.create(null)){super(fe),this.resultSelector=w,this.iterators=[],this.active=0,this.resultSelector="function"==typeof w?w:void 0}_next(fe){const w=this.iterators;(0,p.k)(fe)?w.push(new ae(fe)):w.push("function"==typeof fe[L.hZ]?new ue(fe[L.hZ]()):new H(this.destination,this,fe))}_complete(){const fe=this.iterators,w=fe.length;if(this.unsubscribe(),0!==w){this.active=w;for(let X=0;X<w;X++){let ke=fe[X];ke.stillUnsubscribed?this.destination.add(ke.subscribe()):this.active--}}else this.destination.complete()}notifyInactive(){this.active--,0===this.active&&this.destination.complete()}checkIterators(){const fe=this.iterators,w=fe.length,X=this.destination;for(let Jn=0;Jn<w;Jn++){let Ir=fe[Jn];if("function"==typeof Ir.hasValue&&!Ir.hasValue())return}let ke=!1;const ct=[];for(let Jn=0;Jn<w;Jn++){let Ir=fe[Jn],vi=Ir.next();if(Ir.hasCompleted()&&(ke=!0),vi.done)return void X.complete();ct.push(vi.value)}this.resultSelector?this._tryresultSelector(ct):X.next(ct),ke&&X.complete()}_tryresultSelector(fe){let w;try{w=this.resultSelector.apply(this,fe)}catch(X){return void this.destination.error(X)}this.destination.next(w)}}class ue{constructor(fe){this.iterator=fe,this.nextResult=fe.next()}hasValue(){return!0}next(){const fe=this.nextResult;return this.nextResult=this.iterator.next(),fe}hasCompleted(){const fe=this.nextResult;return Boolean(fe&&fe.done)}}class ae{constructor(fe){this.array=fe,this.index=0,this.length=0,this.length=fe.length}[L.hZ](){return this}next(fe){const w=this.index++;return w<this.length?{value:this.array[w],done:!1}:{value:null,done:!0}}hasValue(){return this.array.length>this.index}hasCompleted(){return this.array.length===this.index}}class H extends Z.Ds{constructor(fe,w,X){super(fe),this.parent=w,this.observable=X,this.stillUnsubscribed=!0,this.buffer=[],this.isComplete=!1}[L.hZ](){return this}next(){const fe=this.buffer;return 0===fe.length&&this.isComplete?{value:null,done:!0}:{value:fe.shift(),done:!1}}hasValue(){return this.buffer.length>0}hasCompleted(){return 0===this.buffer.length&&this.isComplete}notifyComplete(){this.buffer.length>0?(this.isComplete=!0,this.parent.notifyInactive()):this.destination.complete()}notifyNext(fe){this.buffer.push(fe),this.parent.checkIterators()}subscribe(){return(0,Z.ft)(this.observable,new Z.IY(this))}}var se=i(18891),Ee=i(59193),ie=i(25917),he=i(79765),ge=i(22759),De=i(46797),ce=i(26215),ze=(i(9112),i(17757),i(66682)),Be=i(58071);function je(...Y){return fe=>{let w;return"function"==typeof Y[Y.length-1]&&(w=Y.pop()),fe.lift(new He(Y,w))}}class He{constructor(fe,w){this.observables=fe,this.project=w}call(fe,w){return w.subscribe(new Vt(fe,this.observables,this.project))}}class Vt extends e.L{constructor(fe,w,X){super(fe),this.observables=w,this.project=X,this.toRespond=[];const ke=w.length;this.values=new Array(ke);for(let ct=0;ct<ke;ct++)this.toRespond.push(ct);for(let ct=0;ct<ke;ct++)this.add((0,_.D)(this,w[ct],void 0,ct))}notifyNext(fe,w,X){this.values[X]=w;const ke=this.toRespond;if(ke.length>0){const ct=ke.indexOf(X);-1!==ct&&ke.splice(ct,1)}}notifyComplete(){}_next(fe){if(0===this.toRespond.length){const w=[fe,...this.values];this.project?this._tryProject(w):this.destination.next(w)}}_tryProject(fe){let w;try{w=this.project.apply(this,fe)}catch(X){return void this.destination.error(X)}this.destination.next(w)}}class tn{constructor(fe){this.total=fe}call(fe,w){return w.subscribe(new It(fe,this.total))}}class It extends N.L{constructor(fe,w){super(fe),this.total=w,this.count=0}_next(fe){++this.count>this.total&&this.destination.next(fe)}}var Zt=i(46782),Ut=i(45435),Bt=i(15257),bt=i(88002),Gt=i(39761),xt=i(87519),Xt=i(43190),Zn=i(68307),Ur=i(71289),di=i(19773),Lr=i(18819),Mr=i(24751);function ki(Y,fe){if(1&Y){const w=r.EpF();r.TgZ(0,"button",1),r.NdJ("click",function(){return r.CHM(w),r.oxw().close()}),r.TgZ(1,"span",2),r._uU(2,"\xd7"),r.qZA(),r.qZA()}}const Hi=["*"],Fr=["defaultDayTemplate"],Gn=["content"];function Jr(Y,fe){if(1&Y&&r._UZ(0,"div",7),2&Y){const X=fe.currentMonth,ke=fe.selected,ct=fe.disabled,Jn=fe.focused;r.Q6J("date",fe.date)("currentMonth",X)("selected",ke)("disabled",ct)("focused",Jn)}}function _i(Y,fe){if(1&Y&&(r.TgZ(0,"div",12),r._uU(1),r.qZA()),2&Y){const w=r.oxw().$implicit,X=r.oxw(2);r.xp6(1),r.hij(" ",X.i18n.getMonthLabel(w.firstDate)," ")}}function wi(Y,fe){if(1&Y&&(r.TgZ(0,"div",9),r.YNc(1,_i,2,1,"div",10),r._UZ(2,"ngb-datepicker-month",11),r.qZA()),2&Y){const w=fe.$implicit,X=r.oxw(2);r.xp6(1),r.Q6J("ngIf","none"===X.navigation||X.displayMonths>1&&"select"===X.navigation),r.xp6(1),r.Q6J("month",w.firstDate)}}function br(Y,fe){if(1&Y&&r.YNc(0,wi,3,2,"div",8),2&Y){const w=r.oxw();r.Q6J("ngForOf",w.model.months)}}function Dr(Y,fe){if(1&Y){const w=r.EpF();r.TgZ(0,"ngb-datepicker-navigation",13),r.NdJ("navigate",function(ke){return r.CHM(w),r.oxw().onNavigateEvent(ke)})("select",function(ke){return r.CHM(w),r.oxw().onNavigateDateSelect(ke)}),r.qZA()}if(2&Y){const w=r.oxw();r.Q6J("date",w.model.firstDate)("months",w.model.months)("disabled",w.model.disabled)("showSelect","select"===w.model.navigation)("prevDisabled",w.model.prevDisabled)("nextDisabled",w.model.nextDisabled)("selectBoxes",w.model.selectBoxes)}}function gn(Y,fe){}function yn(Y,fe){}function gr(Y,fe){if(1&Y&&(r.TgZ(0,"div",5),r._uU(1),r.qZA()),2&Y){const w=r.oxw(2);r.xp6(1),r.Oqu(w.i18n.getWeekLabel())}}function Jt(Y,fe){if(1&Y&&(r.TgZ(0,"div",6),r._uU(1),r.qZA()),2&Y){const w=fe.$implicit;r.xp6(1),r.Oqu(w)}}function Vn(Y,fe){if(1&Y&&(r.TgZ(0,"div",2),r.YNc(1,gr,2,1,"div",3),r.YNc(2,Jt,2,1,"div",4),r.qZA()),2&Y){const w=r.oxw();r.xp6(1),r.Q6J("ngIf",w.datepicker.showWeekNumbers),r.xp6(1),r.Q6J("ngForOf",w.viewModel.weekdays)}}function mr(Y,fe){if(1&Y&&(r.TgZ(0,"div",11),r._uU(1),r.qZA()),2&Y){const w=r.oxw(2).$implicit,X=r.oxw();r.xp6(1),r.Oqu(X.i18n.getWeekNumerals(w.number))}}function Dn(Y,fe){}function Pr(Y,fe){if(1&Y&&r.YNc(0,Dn,0,0,"ng-template",14),2&Y){const w=r.oxw().$implicit,X=r.oxw(3);r.Q6J("ngTemplateOutlet",X.datepicker.dayTemplate)("ngTemplateOutletContext",w.context)}}function Yt(Y,fe){if(1&Y){const w=r.EpF();r.TgZ(0,"div",12),r.NdJ("click",function(ke){const Jn=r.CHM(w).$implicit;return r.oxw(3).doSelect(Jn),ke.preventDefault()}),r.YNc(1,Pr,1,2,"ng-template",13),r.qZA()}if(2&Y){const w=fe.$implicit;r.ekj("disabled",w.context.disabled)("hidden",w.hidden)("ngb-dp-today",w.context.today),r.Q6J("tabindex",w.tabindex),r.uIk("aria-label",w.ariaLabel),r.xp6(1),r.Q6J("ngIf",!w.hidden)}}function _n(Y,fe){if(1&Y&&(r.TgZ(0,"div",8),r.YNc(1,mr,2,1,"div",9),r.YNc(2,Yt,2,9,"div",10),r.qZA()),2&Y){const w=r.oxw().$implicit,X=r.oxw();r.xp6(1),r.Q6J("ngIf",X.datepicker.showWeekNumbers),r.xp6(1),r.Q6J("ngForOf",w.days)}}function Ge(Y,fe){1&Y&&r.YNc(0,_n,3,2,"div",7),2&Y&&r.Q6J("ngIf",!fe.$implicit.collapsed)}function kr(Y,fe){if(1&Y){const w=r.EpF();r.TgZ(0,"ngb-datepicker-navigation-select",7),r.NdJ("select",function(ke){return r.CHM(w),r.oxw().select.emit(ke)}),r.qZA()}if(2&Y){const w=r.oxw();r.Q6J("date",w.date)("disabled",w.disabled)("months",w.selectBoxes.months)("years",w.selectBoxes.years)}}function mi(Y,fe){1&Y&&r._UZ(0,"div",0)}function An(Y,fe){1&Y&&r._UZ(0,"div",0)}function Er(Y,fe){if(1&Y&&(r.YNc(0,mi,1,0,"div",9),r.TgZ(1,"div",10),r._uU(2),r.qZA(),r.YNc(3,An,1,0,"div",9)),2&Y){const w=fe.$implicit,X=fe.index,ke=r.oxw(2);r.Q6J("ngIf",X>0),r.xp6(2),r.hij(" ",ke.i18n.getMonthLabel(w.firstDate)," "),r.xp6(1),r.Q6J("ngIf",X!==ke.months.length-1)}}function Wr(Y,fe){if(1&Y&&r.YNc(0,Er,4,3,"ng-template",8),2&Y){const w=r.oxw();r.Q6J("ngForOf",w.months)}}const dr=["ngbDatepickerDayView",""],Fn=["month"],ar=["year"];function Wi(Y,fe){if(1&Y&&(r.TgZ(0,"option",5),r._uU(1),r.qZA()),2&Y){const w=fe.$implicit,X=r.oxw();r.Q6J("value",w),r.uIk("aria-label",X.i18n.getMonthFullName(w,null==X.date?null:X.date.year)),r.xp6(1),r.Oqu(X.i18n.getMonthShortName(w,null==X.date?null:X.date.year))}}function lo(Y,fe){if(1&Y&&(r.TgZ(0,"option",5),r._uU(1),r.qZA()),2&Y){const w=fe.$implicit,X=r.oxw();r.Q6J("value",w),r.xp6(1),r.Oqu(X.i18n.getYearNumerals(w))}}const vo=["dialog"],Co=["ngbNavOutlet",""];function Gi(Y,fe){}const os=function(Y){return{$implicit:Y}};function jo(Y,fe){if(1&Y&&(r.TgZ(0,"div",2),r.YNc(1,Gi,0,0,"ng-template",3),r.qZA()),2&Y){const w=r.oxw().$implicit,X=r.oxw();r.Q6J("item",w)("nav",X.nav)("role",X.paneRole),r.xp6(1),r.Q6J("ngTemplateOutlet",(null==w.contentTpl?null:w.contentTpl.templateRef)||null)("ngTemplateOutletContext",r.VKq(5,os,w.active||X.isPanelTransitioning(w)))}}function To(Y,fe){if(1&Y&&r.YNc(0,jo,2,7,"div",1),2&Y){const w=fe.$implicit,X=r.oxw();r.Q6J("ngIf",w.isPanelInDom()||X.isPanelTransitioning(w))}}function us(Y,fe){if(1&Y&&r._uU(0),2&Y){const w=r.oxw(2);r.Oqu(w.title)}}function ya(Y,fe){}function el(Y,fe){if(1&Y&&(r.TgZ(0,"h3",3),r.YNc(1,us,1,1,"ng-template",null,4,r.W1O),r.YNc(3,ya,0,0,"ng-template",5),r.qZA()),2&Y){const w=r.MAs(2),X=r.oxw();r.xp6(3),r.Q6J("ngTemplateOutlet",X.isTitleTemplate()?X.title:w)("ngTemplateOutletContext",X.context)}}function ca(Y,fe){if(1&Y&&(r.TgZ(0,"span"),r.SDv(1,2),r.ALo(2,"percent"),r.qZA()),2&Y){const w=r.oxw();r.xp6(2),r.pQV(r.lcZ(2,1,w.getValue()/w.max)),r.QtT(1)}}function fo(Y,fe){if(1&Y){const w=r.EpF();r.TgZ(0,"button",11),r.NdJ("click",function(){r.CHM(w);const ke=r.oxw();return ke.changeHour(ke.hourStep)}),r._UZ(1,"span",12),r.TgZ(2,"span",13),r.SDv(3,14),r.qZA(),r.qZA()}if(2&Y){const w=r.oxw();r.ekj("btn-sm",w.isSmallSize)("btn-lg",w.isLargeSize)("disabled",w.disabled),r.Q6J("disabled",w.disabled)}}function Ya(Y,fe){if(1&Y){const w=r.EpF();r.TgZ(0,"button",11),r.NdJ("click",function(){r.CHM(w);const ke=r.oxw();return ke.changeHour(-ke.hourStep)}),r._UZ(1,"span",15),r.TgZ(2,"span",13),r.SDv(3,16),r.qZA(),r.qZA()}if(2&Y){const w=r.oxw();r.ekj("btn-sm",w.isSmallSize)("btn-lg",w.isLargeSize)("disabled",w.disabled),r.Q6J("disabled",w.disabled)}}function Ao(Y,fe){if(1&Y){const w=r.EpF();r.TgZ(0,"button",11),r.NdJ("click",function(){r.CHM(w);const ke=r.oxw();return ke.changeMinute(ke.minuteStep)}),r._UZ(1,"span",12),r.TgZ(2,"span",13),r.SDv(3,17),r.qZA(),r.qZA()}if(2&Y){const w=r.oxw();r.ekj("btn-sm",w.isSmallSize)("btn-lg",w.isLargeSize)("disabled",w.disabled),r.Q6J("disabled",w.disabled)}}function fs(Y,fe){if(1&Y){const w=r.EpF();r.TgZ(0,"button",11),r.NdJ("click",function(){r.CHM(w);const ke=r.oxw();return ke.changeMinute(-ke.minuteStep)}),r._UZ(1,"span",15),r.TgZ(2,"span",13),r.SDv(3,18),r.qZA(),r.qZA()}if(2&Y){const w=r.oxw();r.ekj("btn-sm",w.isSmallSize)("btn-lg",w.isLargeSize)("disabled",w.disabled),r.Q6J("disabled",w.disabled)}}function Ca(Y,fe){1&Y&&(r.TgZ(0,"div",5),r._uU(1,":"),r.qZA())}function Ra(Y,fe){if(1&Y){const w=r.EpF();r.TgZ(0,"button",11),r.NdJ("click",function(){r.CHM(w);const ke=r.oxw(2);return ke.changeSecond(ke.secondStep)}),r._UZ(1,"span",12),r.TgZ(2,"span",13),r.SDv(3,21),r.qZA(),r.qZA()}if(2&Y){const w=r.oxw(2);r.ekj("btn-sm",w.isSmallSize)("btn-lg",w.isLargeSize)("disabled",w.disabled),r.Q6J("disabled",w.disabled)}}function pl(Y,fe){if(1&Y){const w=r.EpF();r.TgZ(0,"button",11),r.NdJ("click",function(){r.CHM(w);const ke=r.oxw(2);return ke.changeSecond(-ke.secondStep)}),r._UZ(1,"span",15),r.TgZ(2,"span",13),r.SDv(3,22),r.qZA(),r.qZA()}if(2&Y){const w=r.oxw(2);r.ekj("btn-sm",w.isSmallSize)("btn-lg",w.isLargeSize)("disabled",w.disabled),r.Q6J("disabled",w.disabled)}}function Ws(Y,fe){if(1&Y){const w=r.EpF();r.TgZ(0,"div",19),r.YNc(1,Ra,4,7,"button",3),r.TgZ(2,"input",20),r.NdJ("change",function(ke){return r.CHM(w),r.oxw().updateSecond(ke.target.value)})("blur",function(){return r.CHM(w),r.oxw().handleBlur()})("input",function(ke){return r.CHM(w),r.oxw().formatInput(ke.target)})("keydown.ArrowUp",function(ke){r.CHM(w);const ct=r.oxw();return ct.changeSecond(ct.secondStep),ke.preventDefault()})("keydown.ArrowDown",function(ke){r.CHM(w);const ct=r.oxw();return ct.changeSecond(-ct.secondStep),ke.preventDefault()}),r.qZA(),r.YNc(3,pl,4,7,"button",3),r.qZA()}if(2&Y){const w=r.oxw();r.xp6(1),r.Q6J("ngIf",w.spinners),r.xp6(1),r.ekj("form-control-sm",w.isSmallSize)("form-control-lg",w.isLargeSize),r.Q6J("value",w.formatMinSec(null==w.model?null:w.model.second))("readOnly",w.readonlyInputs)("disabled",w.disabled),r.xp6(1),r.Q6J("ngIf",w.spinners)}}function Po(Y,fe){1&Y&&r._UZ(0,"div",5)}function bo(Y,fe){if(1&Y&&(r.ynx(0),r.SDv(1,27),r.BQk()),2&Y){const w=r.oxw(2);r.xp6(1),r.pQV(w.i18n.getAfternoonPeriod()),r.QtT(1)}}function Ls(Y,fe){if(1&Y&&r.SDv(0,28),2&Y){const w=r.oxw(2);r.pQV(w.i18n.getMorningPeriod()),r.QtT(0)}}function ps(Y,fe){if(1&Y){const w=r.EpF();r.TgZ(0,"div",23),r.TgZ(1,"button",24),r.NdJ("click",function(){return r.CHM(w),r.oxw().toggleMeridian()}),r.YNc(2,bo,2,1,"ng-container",25),r.YNc(3,Ls,1,1,"ng-template",null,26,r.W1O),r.qZA(),r.qZA()}if(2&Y){const w=r.MAs(4),X=r.oxw();r.xp6(1),r.ekj("btn-sm",X.isSmallSize)("btn-lg",X.isLargeSize)("disabled",X.disabled),r.Q6J("disabled",X.disabled),r.xp6(1),r.Q6J("ngIf",X.model&&X.model.hour>=12)("ngIfElse",w)}}function tt(Y,fe){if(1&Y&&(r.TgZ(0,"span"),r._uU(1),r.qZA()),2&Y){const w=r.oxw().$implicit,X=r.oxw();r.Tol(X.highlightClass),r.xp6(1),r.Oqu(w)}}function sn(Y,fe){if(1&Y&&r._uU(0),2&Y){const w=r.oxw().$implicit;r.Oqu(w)}}function ne(Y,fe){if(1&Y&&(r.YNc(0,tt,2,3,"span",1),r.YNc(1,sn,1,1,"ng-template",null,2,r.W1O)),2&Y){const w=fe.odd,X=r.MAs(2);r.Q6J("ngIf",w)("ngIfElse",X)}}function $e(Y,fe){if(1&Y&&r._UZ(0,"ngb-highlight",2),2&Y){const X=fe.term;r.Q6J("result",(0,fe.formatter)(fe.result))("term",X)}}function Lt(Y,fe){}const an=function(Y,fe,w){return{result:Y,term:fe,formatter:w}};function ti(Y,fe){if(1&Y){const w=r.EpF();r.TgZ(0,"button",3),r.NdJ("mouseenter",function(){const ct=r.CHM(w).index;return r.oxw().markActive(ct)})("click",function(){const ct=r.CHM(w).$implicit;return r.oxw().select(ct)}),r.YNc(1,Lt,0,0,"ng-template",4),r.qZA()}if(2&Y){const w=fe.$implicit,X=fe.index,ke=r.oxw(),ct=r.MAs(1);r.ekj("active",X===ke.activeIdx),r.Q6J("id",ke.id+"-"+X),r.xp6(1),r.Q6J("ngTemplateOutlet",ke.resultTemplate||ct)("ngTemplateOutletContext",r.kEZ(5,an,w,ke.term,ke.formatter))}}function pi(Y){return parseInt(`${Y}`,10)}function xi(Y){return null!=Y?`${Y}`:""}function wo(Y){return"string"==typeof Y}function ko(Y){return!isNaN(pi(Y))}function Eo(Y){return"number"==typeof Y&&isFinite(Y)&&Math.floor(Y)===Y}function ba(Y){return null!=Y}function sl(Y){return ko(Y)?`0${Y}`.slice(-2):""}function Nu(Y,fe){return Y&&Y.className&&Y.className.split&&Y.className.split(/\s+/).indexOf(fe)>=0}function Ec(Y){return(Y||document.body).getBoundingClientRect()}function Hl(Y){return Y.normalize("NFD").replace(/[\u0300-\u036f]/g,"")}"undefined"!=typeof Element&&!Element.prototype.closest&&(Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector),Element.prototype.closest=function(Y){let fe=this;if(!document.documentElement.contains(fe))return null;do{if(fe.matches(Y))return fe;fe=fe.parentElement||fe.parentNode}while(null!==fe&&1===fe.nodeType);return null});const Yl={animation:!0,transitionTimerDelayMs:5};let Fs=(()=>{class Y{constructor(){this.animation=Yl.animation}}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275prov=r.Yz7({factory:function(){return new Y},token:Y,providedIn:"root"}),Y})();const tl=()=>{},{transitionTimerDelayMs:Zl}=Yl,rt=new Map,Pt=(Y,fe,w,X)=>{let ke=X.context||{};const ct=rt.get(fe);if(ct)switch(X.runningTransition){case"continue":return Ee.E;case"stop":Y.run(()=>ct.transition$.complete()),ke=Object.assign(ct.context,ke),rt.delete(fe)}const Jn=w(fe,X.animation,ke)||tl;if(!X.animation||"none"===window.getComputedStyle(fe).transitionProperty)return Y.run(()=>Jn()),(0,ie.of)(void 0).pipe(function(Y){return fe=>new se.y(w=>fe.subscribe(Jn=>Y.run(()=>w.next(Jn)),Jn=>Y.run(()=>w.error(Jn)),()=>Y.run(()=>w.complete())))}(Y));const Ir=new he.xQ,vi=new he.xQ,zi=Ir.pipe(function(...Y){return fe=>(0,Be.z)(fe,(0,ie.of)(...Y))}(!0));rt.set(fe,{transition$:Ir,complete:()=>{vi.next(),vi.complete()},context:ke});const Do=function(Y){const{transitionDelay:fe,transitionDuration:w}=window.getComputedStyle(Y);return 1e3*(parseFloat(fe)+parseFloat(w))}(fe);return Y.runOutsideAngular(()=>{const xs=(0,ge.R)(fe,"transitionend").pipe((0,Zt.R)(zi),(0,Ut.h)(({target:Rs})=>Rs===fe));y((0,De.H)(Do+Zl).pipe((0,Zt.R)(zi)),xs,vi).pipe((0,Zt.R)(zi)).subscribe(()=>{rt.delete(fe),Y.run(()=>{Jn(),Ir.next(),Ir.complete()})})}),Ir.asObservable()},Me=(Y,fe,w)=>{let{direction:X,maxHeight:ke}=w;const{classList:ct}=Y;function Jn(){ct.add("collapse"),"show"===X?ct.add("show"):ct.remove("show")}if(fe)return ke||(ke=function(Y){if("undefined"==typeof navigator)return"0px";const{classList:fe}=Y,w=fe.contains("show");w||fe.add("show"),Y.style.height="";const X=Y.getBoundingClientRect().height+"px";return w||fe.remove("show"),X}(Y),w.maxHeight=ke,Y.style.height="show"!==X?ke:"0px",ct.remove("collapse"),ct.remove("collapsing"),ct.remove("show"),Ec(Y),ct.add("collapsing")),Y.style.height="show"===X?ke:"0px",()=>{Jn(),ct.remove("collapsing"),Y.style.height=""};Jn()};let au=(()=>{class Y{constructor(w){this._ngbConfig=w,this.dismissible=!0,this.type="warning"}get animation(){return void 0===this._animation?this._ngbConfig.animation:this._animation}set animation(w){this._animation=w}}return Y.\u0275fac=function(w){return new(w||Y)(r.LFG(Fs))},Y.\u0275prov=r.Yz7({factory:function(){return new Y(r.LFG(Fs))},token:Y,providedIn:"root"}),Y})();const Wa=({classList:Y})=>{Y.remove("show")};let Rl=(()=>{class Y{constructor(w,X,ke,ct){this._renderer=X,this._element=ke,this._zone=ct,this.closed=new r.vpe,this.dismissible=w.dismissible,this.type=w.type,this.animation=w.animation}close(){const w=Pt(this._zone,this._element.nativeElement,Wa,{animation:this.animation,runningTransition:"continue"});return w.subscribe(()=>this.closed.emit()),w}ngOnChanges(w){const X=w.type;X&&!X.firstChange&&(this._renderer.removeClass(this._element.nativeElement,`alert-${X.previousValue}`),this._renderer.addClass(this._element.nativeElement,`alert-${X.currentValue}`))}ngOnInit(){this._renderer.addClass(this._element.nativeElement,`alert-${this.type}`)}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(au),r.Y36(r.Qsj),r.Y36(r.SBq),r.Y36(r.R0b))},Y.\u0275cmp=r.Xpm({type:Y,selectors:[["ngb-alert"]],hostAttrs:["role","alert",1,"alert","show"],hostVars:4,hostBindings:function(w,X){2&w&&r.ekj("fade",X.animation)("alert-dismissible",X.dismissible)},inputs:{dismissible:"dismissible",type:"type",animation:"animation"},outputs:{closed:"closed"},exportAs:["ngbAlert"],features:[r.TTD],ngContentSelectors:Hi,decls:2,vars:1,consts:function(){let fe;return fe="Close",[["type","button","class","close","aria-label",fe,3,"click",4,"ngIf"],["type","button","aria-label",fe,1,"close",3,"click"],["aria-hidden","true"]]},template:function(w,X){1&w&&(r.F$t(),r.Hsn(0),r.YNc(1,ki,3,0,"button",0)),2&w&&(r.xp6(1),r.Q6J("ngIf",X.dismissible))},directives:[u.O5],styles:["ngb-alert{display:block}"],encapsulation:2,changeDetection:0}),Y})(),nc=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275mod=r.oAB({type:Y}),Y.\u0275inj=r.cJS({imports:[[u.ez]]}),Y})(),wr=(()=>{class Y{constructor(w){this._ngbConfig=w}get animation(){return void 0===this._animation?this._ngbConfig.animation:this._animation}set animation(w){this._animation=w}}return Y.\u0275fac=function(w){return new(w||Y)(r.LFG(Fs))},Y.\u0275prov=r.Yz7({factory:function(){return new Y(r.LFG(Fs))},token:Y,providedIn:"root"}),Y})(),fa=(()=>{class Y{constructor(w,X,ke){this._element=w,this._zone=ke,this.collapsed=!1,this.ngbCollapseChange=new r.vpe,this.shown=new r.vpe,this.hidden=new r.vpe,this.animation=X.animation}ngOnInit(){this._runTransition(this.collapsed,!1)}ngOnChanges({collapsed:w}){w.firstChange||this._runTransitionWithEvents(this.collapsed,this.animation)}toggle(w=this.collapsed){this.collapsed=!w,this.ngbCollapseChange.next(this.collapsed),this._runTransitionWithEvents(this.collapsed,this.animation)}_runTransition(w,X){return Pt(this._zone,this._element.nativeElement,Me,{animation:X,runningTransition:"stop",context:{direction:w?"hide":"show"}})}_runTransitionWithEvents(w,X){this._runTransition(w,X).subscribe(()=>{w?this.hidden.emit():this.shown.emit()})}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(r.SBq),r.Y36(wr),r.Y36(r.R0b))},Y.\u0275dir=r.lG2({type:Y,selectors:[["","ngbCollapse",""]],inputs:{collapsed:["ngbCollapse","collapsed"],animation:"animation"},outputs:{ngbCollapseChange:"ngbCollapseChange",shown:"shown",hidden:"hidden"},exportAs:["ngbCollapse"],features:[r.TTD]}),Y})(),pu=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275mod=r.oAB({type:Y}),Y.\u0275inj=r.cJS({}),Y})();class aa{constructor(fe,w,X){this.year=Eo(fe)?fe:null,this.month=Eo(w)?w:null,this.day=Eo(X)?X:null}static from(fe){return fe instanceof aa?fe:fe?new aa(fe.year,fe.month,fe.day):null}equals(fe){return null!=fe&&this.year===fe.year&&this.month===fe.month&&this.day===fe.day}before(fe){return!!fe&&(this.year===fe.year?this.month===fe.month?this.day!==fe.day&&this.day<fe.day:this.month<fe.month:this.year<fe.year)}after(fe){return!!fe&&(this.year===fe.year?this.month===fe.month?this.day!==fe.day&&this.day>fe.day:this.month>fe.month:this.year>fe.year)}}function jl(Y){return new aa(Y.getFullYear(),Y.getMonth()+1,Y.getDate())}function bl(Y){const fe=new Date(Y.year,Y.month-1,Y.day,12);return isNaN(fe.getTime())||fe.setFullYear(Y.year),fe}function El(){return new ks}let Ul=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275prov=r.Yz7({factory:El,token:Y,providedIn:"root"}),Y})(),ks=(()=>{class Y extends Ul{getDaysPerWeek(){return 7}getMonths(){return[1,2,3,4,5,6,7,8,9,10,11,12]}getWeeksPerMonth(){return 6}getNext(w,X="d",ke=1){let ct=bl(w),Jn=!0,Ir=ct.getMonth();switch(X){case"y":ct.setFullYear(ct.getFullYear()+ke);break;case"m":Ir+=ke,ct.setMonth(Ir),Ir%=12,Ir<0&&(Ir+=12);break;case"d":ct.setDate(ct.getDate()+ke),Jn=!1;break;default:return w}return Jn&&ct.getMonth()!==Ir&&ct.setDate(0),jl(ct)}getPrev(w,X="d",ke=1){return this.getNext(w,X,-ke)}getWeekday(w){let ke=bl(w).getDay();return 0===ke?7:ke}getWeekNumber(w,X){7===X&&(X=0);const Jn=bl(w[(11-X)%7]);Jn.setDate(Jn.getDate()+4-(Jn.getDay()||7));const Ir=Jn.getTime();return Jn.setMonth(0),Jn.setDate(1),Math.floor(Math.round((Ir-Jn.getTime())/864e5)/7)+1}getToday(){return jl(new Date)}isValid(w){if(!(w&&Eo(w.year)&&Eo(w.month)&&Eo(w.day)&&0!==w.year))return!1;const X=bl(w);return!isNaN(X.getTime())&&X.getFullYear()===w.year&&X.getMonth()+1===w.month&&X.getDate()===w.day}}return Y.\u0275fac=function(){let fe;return function(X){return(fe||(fe=r.n5z(Y)))(X||Y)}}(),Y.\u0275prov=r.Yz7({token:Y,factory:Y.\u0275fac}),Y})();function V(Y,fe){return!function(Y,fe){return!Y&&!fe||!!Y&&!!fe&&Y.equals(fe)}(Y,fe)}function Ae(Y,fe){return!(!Y&&!fe||Y&&fe&&Y.year===fe.year&&Y.month===fe.month)}function ut(Y,fe,w){return Y&&fe&&Y.before(fe)?fe:Y&&w&&Y.after(w)?w:Y||null}function un(Y,fe){const{minDate:w,maxDate:X,disabled:ke,markDisabled:ct}=fe;return!(null==Y||ke||ct&&ct(Y,{year:Y.year,month:Y.month})||w&&Y.before(w)||X&&Y.after(X))}let Cr=(()=>{class Y{getMonthLabel(w){return`${this.getMonthFullName(w.month,w.year)} ${this.getYearNumerals(w.year)}`}getDayNumerals(w){return`${w.day}`}getWeekNumerals(w){return`${w}`}getYearNumerals(w){return`${w}`}getWeekLabel(){return""}}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275prov=r.Yz7({factory:function(){return function(Y){return new hr(Y)}(r.LFG(r.soG))},token:Y,providedIn:"root"}),Y})(),hr=(()=>{class Y extends Cr{constructor(w){super(),this._locale=w,this._monthsShort=(0,u.UT)(w,u.x.Standalone,u.Tn.Abbreviated),this._monthsFull=(0,u.UT)(w,u.x.Standalone,u.Tn.Wide)}getWeekdayLabel(w,X){const ke=(0,u.Mn)(this._locale,u.x.Standalone,void 0===X?u.Tn.Short:X);return ke.map((Jn,Ir)=>ke[(Ir+1)%7])[w-1]||""}getMonthShortName(w){return this._monthsShort[w-1]||""}getMonthFullName(w){return this._monthsFull[w-1]||""}getDayAriaLabel(w){const X=new Date(w.year,w.month-1,w.day);return(0,u.p6)(X,"fullDate",this._locale)}}return Y.\u0275fac=function(w){return new(w||Y)(r.LFG(r.soG))},Y.\u0275prov=r.Yz7({token:Y,factory:Y.\u0275fac}),Y})(),ao=(()=>{class Y{constructor(w,X){this._calendar=w,this._i18n=X,this._VALIDATORS={dayTemplateData:ke=>{if(this._state.dayTemplateData!==ke)return{dayTemplateData:ke}},displayMonths:ke=>{if(Eo(ke=pi(ke))&&ke>0&&this._state.displayMonths!==ke)return{displayMonths:ke}},disabled:ke=>{if(this._state.disabled!==ke)return{disabled:ke}},firstDayOfWeek:ke=>{if(Eo(ke=pi(ke))&&ke>=0&&this._state.firstDayOfWeek!==ke)return{firstDayOfWeek:ke}},focusVisible:ke=>{if(this._state.focusVisible!==ke&&!this._state.disabled)return{focusVisible:ke}},markDisabled:ke=>{if(this._state.markDisabled!==ke)return{markDisabled:ke}},maxDate:ke=>{const ct=this.toValidDate(ke,null);if(V(this._state.maxDate,ct))return{maxDate:ct}},minDate:ke=>{const ct=this.toValidDate(ke,null);if(V(this._state.minDate,ct))return{minDate:ct}},navigation:ke=>{if(this._state.navigation!==ke)return{navigation:ke}},outsideDays:ke=>{if(this._state.outsideDays!==ke)return{outsideDays:ke}},weekdays:ke=>{const ct=!0===ke||!1===ke?u.Tn.Short:ke,Jn=!0!==ke&&!1!==ke||ke;if(this._state.weekdayWidth!==ct||this._state.weekdaysVisible!==Jn)return{weekdayWidth:ct,weekdaysVisible:Jn}}},this._model$=new he.xQ,this._dateSelect$=new he.xQ,this._state={dayTemplateData:null,markDisabled:null,maxDate:null,minDate:null,disabled:!1,displayMonths:1,firstDate:null,firstDayOfWeek:1,lastDate:null,focusDate:null,focusVisible:!1,months:[],navigation:"select",outsideDays:"visible",prevDisabled:!1,nextDisabled:!1,selectedDate:null,selectBoxes:{years:[],months:[]},weekdayWidth:u.Tn.Short,weekdaysVisible:!0}}get model$(){return this._model$.pipe((0,Ut.h)(w=>w.months.length>0))}get dateSelect$(){return this._dateSelect$.pipe((0,Ut.h)(w=>null!==w))}set(w){let X=Object.keys(w).map(ke=>this._VALIDATORS[ke](w[ke])).reduce((ke,ct)=>Object.assign(Object.assign({},ke),ct),{});Object.keys(X).length>0&&this._nextState(X)}focus(w){const X=this.toValidDate(w,null);null!=X&&!this._state.disabled&&V(this._state.focusDate,X)&&this._nextState({focusDate:w})}focusSelect(){un(this._state.focusDate,this._state)&&this.select(this._state.focusDate,{emitEvent:!0})}open(w){const X=this.toValidDate(w,this._calendar.getToday());null!=X&&!this._state.disabled&&(!this._state.firstDate||Ae(this._state.firstDate,X))&&this._nextState({firstDate:X})}select(w,X={}){const ke=this.toValidDate(w,null);null!=ke&&!this._state.disabled&&(V(this._state.selectedDate,ke)&&this._nextState({selectedDate:ke}),X.emitEvent&&un(ke,this._state)&&this._dateSelect$.next(ke))}toValidDate(w,X){const ke=aa.from(w);return void 0===X&&(X=this._calendar.getToday()),this._calendar.isValid(ke)?ke:X}getMonth(w){for(let X of this._state.months)if(w.month===X.number&&w.year===X.year)return X;throw new Error(`month ${w.month} of year ${w.year} not found`)}_nextState(w){const X=this._updateState(w);this._patchContexts(X),this._state=X,this._model$.next(this._state)}_patchContexts(w){const{months:X,displayMonths:ke,selectedDate:ct,focusDate:Jn,focusVisible:Ir,disabled:vi,outsideDays:zi}=w;w.months.forEach(Do=>{Do.weeks.forEach(xs=>{xs.days.forEach(Xo=>{Jn&&(Xo.context.focused=Jn.equals(Xo.date)&&Ir),Xo.tabindex=!vi&&Jn&&Xo.date.equals(Jn)&&Jn.month===Do.number?0:-1,!0===vi&&(Xo.context.disabled=!0),void 0!==ct&&(Xo.context.selected=null!==ct&&ct.equals(Xo.date)),Do.number!==Xo.date.month&&(Xo.hidden="hidden"===zi||"collapsed"===zi||ke>1&&Xo.date.after(X[0].firstDate)&&Xo.date.before(X[ke-1].lastDate))})})})}_updateState(w){const X=Object.assign({},this._state,w);let ke=X.firstDate;if(("minDate"in w||"maxDate"in w)&&(function(Y,fe){if(fe&&Y&&fe.before(Y))throw new Error(`'maxDate' ${fe} should be greater than 'minDate' ${Y}`)}(X.minDate,X.maxDate),X.focusDate=ut(X.focusDate,X.minDate,X.maxDate),X.firstDate=ut(X.firstDate,X.minDate,X.maxDate),ke=X.focusDate),"disabled"in w&&(X.focusVisible=!1),"selectedDate"in w&&0===this._state.months.length&&(ke=X.selectedDate),"focusVisible"in w||"focusDate"in w&&(X.focusDate=ut(X.focusDate,X.minDate,X.maxDate),ke=X.focusDate,0!==X.months.length&&X.focusDate&&!X.focusDate.before(X.firstDate)&&!X.focusDate.after(X.lastDate)))return X;if("firstDate"in w&&(X.firstDate=ut(X.firstDate,X.minDate,X.maxDate),ke=X.firstDate),ke){const Jn=function(Y,fe,w,X,ke){const{displayMonths:ct,months:Jn}=w,Ir=Jn.splice(0,Jn.length);return Array.from({length:ct},(zi,Do)=>{const xs=Object.assign(Y.getNext(fe,"m",Do),{day:1});if(Jn[Do]=null,!ke){const Xo=Ir.findIndex(Rs=>Rs.firstDate.equals(xs));-1!==Xo&&(Jn[Do]=Ir.splice(Xo,1)[0])}return xs}).forEach((zi,Do)=>{null===Jn[Do]&&(Jn[Do]=function(Y,fe,w,X,ke={}){const{dayTemplateData:ct,minDate:Jn,maxDate:Ir,firstDayOfWeek:vi,markDisabled:zi,outsideDays:Do,weekdayWidth:xs,weekdaysVisible:Xo}=w,Rs=Y.getToday();ke.firstDate=null,ke.lastDate=null,ke.number=fe.month,ke.year=fe.year,ke.weeks=ke.weeks||[],ke.weekdays=ke.weekdays||[],fe=function(Y,fe,w){const X=Y.getDaysPerWeek(),ke=new aa(fe.year,fe.month,1),ct=Y.getWeekday(ke)%X;return Y.getPrev(ke,"d",(X+ct-w)%X)}(Y,fe,vi),Xo||(ke.weekdays.length=0);for(let ma=0;ma<Y.getWeeksPerMonth();ma++){let Vs=ke.weeks[ma];Vs||(Vs=ke.weeks[ma]={number:0,days:[],collapsed:!0});const _c=Vs.days;for(let nd=0;nd<Y.getDaysPerWeek();nd++){0===ma&&Xo&&(ke.weekdays[nd]=X.getWeekdayLabel(Y.getWeekday(fe),xs));const wu=new aa(fe.year,fe.month,fe.day),Hd=Y.getNext(wu),$_=X.getDayAriaLabel(wu);let sh=!!(Jn&&wu.before(Jn)||Ir&&wu.after(Ir));!sh&&zi&&(sh=zi(wu,{month:ke.number,year:ke.year}));let ah=wu.equals(Rs),_p=ct?ct(wu,{month:ke.number,year:ke.year}):void 0;null===ke.firstDate&&wu.month===ke.number&&(ke.firstDate=wu),wu.month===ke.number&&Hd.month!==ke.number&&(ke.lastDate=wu);let jf=_c[nd];jf||(jf=_c[nd]={}),jf.date=wu,jf.context=Object.assign(jf.context||{},{$implicit:wu,date:wu,data:_p,currentMonth:ke.number,currentYear:ke.year,disabled:sh,focused:!1,selected:!1,today:ah}),jf.tabindex=-1,jf.ariaLabel=$_,jf.hidden=!1,fe=Hd}Vs.number=Y.getWeekNumber(_c.map(nd=>nd.date),vi),Vs.collapsed="collapsed"===Do&&_c[0].date.month!==ke.number&&_c[_c.length-1].date.month!==ke.number}return ke}(Y,zi,w,X,Ir.shift()||{}))}),Jn}(this._calendar,ke,X,this._i18n,"dayTemplateData"in w||"firstDayOfWeek"in w||"markDisabled"in w||"minDate"in w||"maxDate"in w||"disabled"in w||"outsideDays"in w||"weekdaysVisible"in w);X.months=Jn,X.firstDate=Jn[0].firstDate,X.lastDate=Jn[Jn.length-1].lastDate,"selectedDate"in w&&!un(X.selectedDate,X)&&(X.selectedDate=null),"firstDate"in w&&(!X.focusDate||X.focusDate.before(X.firstDate)||X.focusDate.after(X.lastDate))&&(X.focusDate=ke);const Ir=!this._state.firstDate||this._state.firstDate.year!==X.firstDate.year,vi=!this._state.firstDate||this._state.firstDate.month!==X.firstDate.month;"select"===X.navigation?(("minDate"in w||"maxDate"in w||0===X.selectBoxes.years.length||Ir)&&(X.selectBoxes.years=function(Y,fe,w){if(!Y)return[];const X=fe?Math.max(fe.year,Y.year-500):Y.year-10,ct=(w?Math.min(w.year,Y.year+500):Y.year+10)-X+1,Jn=Array(ct);for(let Ir=0;Ir<ct;Ir++)Jn[Ir]=X+Ir;return Jn}(X.firstDate,X.minDate,X.maxDate)),("minDate"in w||"maxDate"in w||0===X.selectBoxes.months.length||Ir)&&(X.selectBoxes.months=function(Y,fe,w,X){if(!fe)return[];let ke=Y.getMonths(fe.year);if(w&&fe.year===w.year){const ct=ke.findIndex(Jn=>Jn===w.month);ke=ke.slice(ct)}if(X&&fe.year===X.year){const ct=ke.findIndex(Jn=>Jn===X.month);ke=ke.slice(0,ct+1)}return ke}(this._calendar,X.firstDate,X.minDate,X.maxDate))):X.selectBoxes={years:[],months:[]},("arrows"===X.navigation||"select"===X.navigation)&&(vi||Ir||"minDate"in w||"maxDate"in w||"disabled"in w)&&(X.prevDisabled=X.disabled||function(Y,fe,w){const X=Object.assign(Y.getPrev(fe,"m"),{day:1});return null!=w&&(X.year===w.year&&X.month<w.month||X.year<w.year&&1===w.month)}(this._calendar,X.firstDate,X.minDate),X.nextDisabled=X.disabled||function(Y,fe,w){const X=Object.assign(Y.getNext(fe,"m"),{day:1});return null!=w&&X.after(w)}(this._calendar,X.lastDate,X.maxDate))}return X}}return Y.\u0275fac=function(w){return new(w||Y)(r.LFG(Ul),r.LFG(Cr))},Y.\u0275prov=r.Yz7({token:Y,factory:Y.\u0275fac}),Y})();var ys=(()=>{return(Y=ys||(ys={}))[Y.PREV=0]="PREV",Y[Y.NEXT=1]="NEXT",ys;var Y})();let Na=(()=>{class Y{constructor(){this.displayMonths=1,this.firstDayOfWeek=1,this.navigation="select",this.outsideDays="visible",this.showWeekNumbers=!1,this.weekdays=u.Tn.Short}}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275prov=r.Yz7({factory:function(){return new Y},token:Y,providedIn:"root"}),Y})();function Tl(){return new ed}let Qs=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275prov=r.Yz7({factory:Tl,token:Y,providedIn:"root"}),Y})(),ed=(()=>{class Y extends Qs{fromModel(w){return w&&Eo(w.year)&&Eo(w.month)&&Eo(w.day)?{year:w.year,month:w.month,day:w.day}:null}toModel(w){return w&&Eo(w.year)&&Eo(w.month)&&Eo(w.day)?{year:w.year,month:w.month,day:w.day}:null}}return Y.\u0275fac=function(){let fe;return function(X){return(fe||(fe=r.n5z(Y)))(X||Y)}}(),Y.\u0275prov=r.Yz7({token:Y,factory:Y.\u0275fac}),Y})(),$c=(()=>{class Y{constructor(w){this.templateRef=w}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(r.Rgc))},Y.\u0275dir=r.lG2({type:Y,selectors:[["ng-template","ngbDatepickerContent",""]]}),Y})(),Gl=(()=>{class Y{constructor(w,X,ke,ct,Jn,Ir,vi,zi){this._service=w,this._calendar=X,this.i18n=ke,this._elementRef=Ir,this._ngbDateAdapter=vi,this._ngZone=zi,this._controlValue=null,this._destroyed$=new he.xQ,this._publicState={},this.navigate=new r.vpe,this.dateSelect=new r.vpe,this.onChange=Do=>{},this.onTouched=()=>{},["dayTemplate","dayTemplateData","displayMonths","firstDayOfWeek","footerTemplate","markDisabled","minDate","maxDate","navigation","outsideDays","showWeekNumbers","startDate","weekdays"].forEach(Do=>this[Do]=ct[Do]),w.dateSelect$.pipe((0,Zt.R)(this._destroyed$)).subscribe(Do=>{this.dateSelect.emit(Do)}),w.model$.pipe((0,Zt.R)(this._destroyed$)).subscribe(Do=>{const xs=Do.firstDate,Xo=this.model?this.model.firstDate:null;this._publicState={maxDate:Do.maxDate,minDate:Do.minDate,firstDate:Do.firstDate,lastDate:Do.lastDate,focusedDate:Do.focusDate,months:Do.months.map(nd=>nd.firstDate)};let Rs=!1;if(!xs.equals(Xo)&&(this.navigate.emit({current:Xo?{year:Xo.year,month:Xo.month}:null,next:{year:xs.year,month:xs.month},preventDefault:()=>Rs=!0}),Rs&&null!==Xo))return void this._service.open(Xo);const ma=Do.selectedDate,Vs=Do.focusDate,_c=this.model?this.model.focusDate:null;this.model=Do,V(ma,this._controlValue)&&(this._controlValue=ma,this.onTouched(),this.onChange(this._ngbDateAdapter.toModel(ma))),V(Vs,_c)&&_c&&Do.focusVisible&&this.focus(),Jn.markForCheck()})}get state(){return this._publicState}get calendar(){return this._calendar}focusDate(w){this._service.focus(aa.from(w))}focusSelect(){this._service.focusSelect()}focus(){this._ngZone.onStable.asObservable().pipe((0,Bt.q)(1)).subscribe(()=>{const w=this._elementRef.nativeElement.querySelector('div.ngb-dp-day[tabindex="0"]');w&&w.focus()})}navigateTo(w){this._service.open(aa.from(w?w.day?w:Object.assign(Object.assign({},w),{day:1}):null))}ngAfterViewInit(){this._ngZone.runOutsideAngular(()=>{const w=(0,ge.R)(this._contentEl.nativeElement,"focusin"),X=(0,ge.R)(this._contentEl.nativeElement,"focusout"),{nativeElement:ke}=this._elementRef;(0,ze.T)(w,X).pipe((0,Ut.h)(({target:ct,relatedTarget:Jn})=>!(Nu(ct,"ngb-dp-day")&&Nu(Jn,"ngb-dp-day")&&ke.contains(ct)&&ke.contains(Jn))),(0,Zt.R)(this._destroyed$)).subscribe(({type:ct})=>this._ngZone.run(()=>this._service.set({focusVisible:"focusin"===ct})))})}ngOnDestroy(){this._destroyed$.next()}ngOnInit(){if(void 0===this.model){const w={};["dayTemplateData","displayMonths","markDisabled","firstDayOfWeek","navigation","minDate","maxDate","outsideDays","weekdays"].forEach(X=>w[X]=this[X]),this._service.set(w),this.navigateTo(this.startDate)}this.dayTemplate||(this.dayTemplate=this._defaultDayTemplate)}ngOnChanges(w){const X={};if(["dayTemplateData","displayMonths","markDisabled","firstDayOfWeek","navigation","minDate","maxDate","outsideDays","weekdays"].filter(ke=>ke in w).forEach(ke=>X[ke]=this[ke]),this._service.set(X),"startDate"in w){const{currentValue:ke,previousValue:ct}=w.startDate;Ae(ct,ke)&&this.navigateTo(this.startDate)}}onDateSelect(w){this._service.focus(w),this._service.select(w,{emitEvent:!0})}onNavigateDateSelect(w){this._service.open(w)}onNavigateEvent(w){switch(w){case ys.PREV:this._service.open(this._calendar.getPrev(this.model.firstDate,"m",1));break;case ys.NEXT:this._service.open(this._calendar.getNext(this.model.firstDate,"m",1))}}registerOnChange(w){this.onChange=w}registerOnTouched(w){this.onTouched=w}setDisabledState(w){this._service.set({disabled:w})}writeValue(w){this._controlValue=aa.from(this._ngbDateAdapter.fromModel(w)),this._service.select(this._controlValue)}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(ao),r.Y36(Ul),r.Y36(Cr),r.Y36(Na),r.Y36(r.sBO),r.Y36(r.SBq),r.Y36(Qs),r.Y36(r.R0b))},Y.\u0275cmp=r.Xpm({type:Y,selectors:[["ngb-datepicker"]],contentQueries:function(w,X,ke){if(1&w&&r.Suo(ke,$c,7),2&w){let ct;r.iGM(ct=r.CRH())&&(X.contentTemplate=ct.first)}},viewQuery:function(w,X){if(1&w&&(r.Gf(Fr,7),r.Gf(Gn,7)),2&w){let ke;r.iGM(ke=r.CRH())&&(X._defaultDayTemplate=ke.first),r.iGM(ke=r.CRH())&&(X._contentEl=ke.first)}},inputs:{dayTemplate:"dayTemplate",dayTemplateData:"dayTemplateData",displayMonths:"displayMonths",firstDayOfWeek:"firstDayOfWeek",footerTemplate:"footerTemplate",markDisabled:"markDisabled",maxDate:"maxDate",minDate:"minDate",navigation:"navigation",outsideDays:"outsideDays",showWeekNumbers:"showWeekNumbers",startDate:"startDate",weekdays:"weekdays"},outputs:{navigate:"navigate",dateSelect:"dateSelect"},exportAs:["ngbDatepicker"],features:[r._Bn([{provide:Mr.JU,useExisting:(0,r.Gpc)(()=>Y),multi:!0},ao]),r.TTD],decls:10,vars:5,consts:[["defaultDayTemplate",""],["defaultContentTemplate",""],[1,"ngb-dp-header"],[3,"date","months","disabled","showSelect","prevDisabled","nextDisabled","selectBoxes","navigate","select",4,"ngIf"],[1,"ngb-dp-content"],["content",""],[3,"ngTemplateOutlet"],["ngbDatepickerDayView","",3,"date","currentMonth","selected","disabled","focused"],["class","ngb-dp-month",4,"ngFor","ngForOf"],[1,"ngb-dp-month"],["class","ngb-dp-month-name",4,"ngIf"],[3,"month"],[1,"ngb-dp-month-name"],[3,"date","months","disabled","showSelect","prevDisabled","nextDisabled","selectBoxes","navigate","select"]],template:function(w,X){if(1&w&&(r.YNc(0,Jr,1,5,"ng-template",null,0,r.W1O),r.YNc(2,br,1,1,"ng-template",null,1,r.W1O),r.TgZ(4,"div",2),r.YNc(5,Dr,1,7,"ngb-datepicker-navigation",3),r.qZA(),r.TgZ(6,"div",4,5),r.YNc(8,gn,0,0,"ng-template",6),r.qZA(),r.YNc(9,yn,0,0,"ng-template",6)),2&w){const ke=r.MAs(3);r.xp6(5),r.Q6J("ngIf","none"!==X.navigation),r.xp6(1),r.ekj("ngb-dp-months",!X.contentTemplate),r.xp6(2),r.Q6J("ngTemplateOutlet",(null==X.contentTemplate?null:X.contentTemplate.templateRef)||ke),r.xp6(1),r.Q6J("ngTemplateOutlet",X.footerTemplate)}},directives:function(){return[u.O5,u.tP,Hn,u.sg,pa,hl]},styles:["ngb-datepicker{border:1px solid #dfdfdf;border-radius:.25rem;display:inline-block}ngb-datepicker-month{pointer-events:auto}ngb-datepicker.dropdown-menu{padding:0}.ngb-dp-body{z-index:1050}.ngb-dp-header{border-bottom:0;border-radius:.25rem .25rem 0 0;padding-top:.25rem;background-color:#f8f9fa;background-color:var(--light)}.ngb-dp-months{display:flex}.ngb-dp-month{pointer-events:none}.ngb-dp-month-name{font-size:larger;height:2rem;line-height:2rem;text-align:center;background-color:#f8f9fa;background-color:var(--light)}.ngb-dp-month+.ngb-dp-month .ngb-dp-month-name,.ngb-dp-month+.ngb-dp-month .ngb-dp-week{padding-left:1rem}.ngb-dp-month:last-child .ngb-dp-week{padding-right:.25rem}.ngb-dp-month:first-child .ngb-dp-week{padding-left:.25rem}.ngb-dp-month .ngb-dp-week:last-child{padding-bottom:.25rem}"],encapsulation:2,changeDetection:0}),Y})();var $i=(()=>{return(Y=$i||($i={}))[Y.Tab=9]="Tab",Y[Y.Enter=13]="Enter",Y[Y.Escape=27]="Escape",Y[Y.Space=32]="Space",Y[Y.PageUp=33]="PageUp",Y[Y.PageDown=34]="PageDown",Y[Y.End=35]="End",Y[Y.Home=36]="Home",Y[Y.ArrowLeft=37]="ArrowLeft",Y[Y.ArrowUp=38]="ArrowUp",Y[Y.ArrowRight=39]="ArrowRight",Y[Y.ArrowDown=40]="ArrowDown",$i;var Y})();let xo=(()=>{class Y{processKey(w,X){const{state:ke,calendar:ct}=X;switch(w.which){case $i.PageUp:X.focusDate(ct.getPrev(ke.focusedDate,w.shiftKey?"y":"m",1));break;case $i.PageDown:X.focusDate(ct.getNext(ke.focusedDate,w.shiftKey?"y":"m",1));break;case $i.End:X.focusDate(w.shiftKey?ke.maxDate:ke.lastDate);break;case $i.Home:X.focusDate(w.shiftKey?ke.minDate:ke.firstDate);break;case $i.ArrowLeft:X.focusDate(ct.getPrev(ke.focusedDate,"d",1));break;case $i.ArrowUp:X.focusDate(ct.getPrev(ke.focusedDate,"d",ct.getDaysPerWeek()));break;case $i.ArrowRight:X.focusDate(ct.getNext(ke.focusedDate,"d",1));break;case $i.ArrowDown:X.focusDate(ct.getNext(ke.focusedDate,"d",ct.getDaysPerWeek()));break;case $i.Enter:case $i.Space:X.focusSelect();break;default:return}w.preventDefault(),w.stopPropagation()}}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275prov=r.Yz7({factory:function(){return new Y},token:Y,providedIn:"root"}),Y})(),pa=(()=>{class Y{constructor(w,X,ke,ct){this.i18n=w,this.datepicker=X,this._keyboardService=ke,this._service=ct}set month(w){this.viewModel=this._service.getMonth(w)}onKeyDown(w){this._keyboardService.processKey(w,this.datepicker)}doSelect(w){!w.context.disabled&&!w.hidden&&this.datepicker.onDateSelect(w.date)}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(Cr),r.Y36(Gl),r.Y36(xo),r.Y36(ao))},Y.\u0275cmp=r.Xpm({type:Y,selectors:[["ngb-datepicker-month"]],hostAttrs:["role","grid"],hostBindings:function(w,X){1&w&&r.NdJ("keydown",function(ct){return X.onKeyDown(ct)})},inputs:{month:"month"},decls:2,vars:2,consts:[["class","ngb-dp-week ngb-dp-weekdays","role","row",4,"ngIf"],["ngFor","",3,"ngForOf"],["role","row",1,"ngb-dp-week","ngb-dp-weekdays"],["class","ngb-dp-weekday ngb-dp-showweek small",4,"ngIf"],["class","ngb-dp-weekday small","role","columnheader",4,"ngFor","ngForOf"],[1,"ngb-dp-weekday","ngb-dp-showweek","small"],["role","columnheader",1,"ngb-dp-weekday","small"],["class","ngb-dp-week","role","row",4,"ngIf"],["role","row",1,"ngb-dp-week"],["class","ngb-dp-week-number small text-muted",4,"ngIf"],["class","ngb-dp-day","role","gridcell",3,"disabled","tabindex","hidden","ngb-dp-today","click",4,"ngFor","ngForOf"],[1,"ngb-dp-week-number","small","text-muted"],["role","gridcell",1,"ngb-dp-day",3,"tabindex","click"],[3,"ngIf"],[3,"ngTemplateOutlet","ngTemplateOutletContext"]],template:function(w,X){1&w&&(r.YNc(0,Vn,3,2,"div",0),r.YNc(1,Ge,1,1,"ng-template",1)),2&w&&(r.Q6J("ngIf",X.viewModel.weekdays.length>0),r.xp6(1),r.Q6J("ngForOf",X.viewModel.weeks))},directives:[u.O5,u.sg,u.tP],styles:['ngb-datepicker-month{display:block}.ngb-dp-week-number,.ngb-dp-weekday{line-height:2rem;text-align:center;font-style:italic}.ngb-dp-weekday{color:#5bc0de;color:var(--info)}.ngb-dp-week{border-radius:.25rem;display:flex}.ngb-dp-weekdays{border-bottom:1px solid rgba(0,0,0,.125);border-radius:0;background-color:#f8f9fa;background-color:var(--light)}.ngb-dp-day,.ngb-dp-week-number,.ngb-dp-weekday{width:2rem;height:2rem}.ngb-dp-day{cursor:pointer}.ngb-dp-day.disabled,.ngb-dp-day.hidden{cursor:default;pointer-events:none}.ngb-dp-day[tabindex="0"]{z-index:1}'],encapsulation:2}),Y})(),hl=(()=>{class Y{constructor(w){this.i18n=w,this.navigation=ys,this.months=[],this.navigate=new r.vpe,this.select=new r.vpe}onClickPrev(w){w.currentTarget.focus(),this.navigate.emit(this.navigation.PREV)}onClickNext(w){w.currentTarget.focus(),this.navigate.emit(this.navigation.NEXT)}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(Cr))},Y.\u0275cmp=r.Xpm({type:Y,selectors:[["ngb-datepicker-navigation"]],inputs:{months:"months",date:"date",disabled:"disabled",showSelect:"showSelect",prevDisabled:"prevDisabled",nextDisabled:"nextDisabled",selectBoxes:"selectBoxes"},outputs:{navigate:"navigate",select:"select"},decls:8,vars:4,consts:function(){let fe,w,X,ke;return fe="Previous month",w="Previous month",X="Next month",ke="Next month",[[1,"ngb-dp-arrow"],["type","button","aria-label",fe,"title",w,1,"btn","btn-link","ngb-dp-arrow-btn",3,"disabled","click"],[1,"ngb-dp-navigation-chevron"],["class","ngb-dp-navigation-select",3,"date","disabled","months","years","select",4,"ngIf"],[4,"ngIf"],[1,"ngb-dp-arrow","right"],["type","button","aria-label",X,"title",ke,1,"btn","btn-link","ngb-dp-arrow-btn",3,"disabled","click"],[1,"ngb-dp-navigation-select",3,"date","disabled","months","years","select"],["ngFor","",3,"ngForOf"],["class","ngb-dp-arrow",4,"ngIf"],[1,"ngb-dp-month-name"]]},template:function(w,X){1&w&&(r.TgZ(0,"div",0),r.TgZ(1,"button",1),r.NdJ("click",function(ct){return X.onClickPrev(ct)}),r._UZ(2,"span",2),r.qZA(),r.qZA(),r.YNc(3,kr,1,4,"ngb-datepicker-navigation-select",3),r.YNc(4,Wr,1,1,void 0,4),r.TgZ(5,"div",5),r.TgZ(6,"button",6),r.NdJ("click",function(ct){return X.onClickNext(ct)}),r._UZ(7,"span",2),r.qZA(),r.qZA()),2&w&&(r.xp6(1),r.Q6J("disabled",X.prevDisabled),r.xp6(2),r.Q6J("ngIf",X.showSelect),r.xp6(1),r.Q6J("ngIf",!X.showSelect),r.xp6(2),r.Q6J("disabled",X.nextDisabled))},directives:function(){return[u.O5,Xn,u.sg]},styles:["ngb-datepicker-navigation{display:flex;align-items:center}.ngb-dp-navigation-chevron{border-style:solid;border-width:.2em .2em 0 0;display:inline-block;width:.75em;height:.75em;margin-left:.25em;margin-right:.15em;transform:rotate(-135deg)}.ngb-dp-arrow{display:flex;flex:1 1 auto;padding-right:0;padding-left:0;margin:0;width:2rem;height:2rem}.ngb-dp-arrow.right{justify-content:flex-end}.ngb-dp-arrow.right .ngb-dp-navigation-chevron{transform:rotate(45deg);margin-left:.15em;margin-right:.25em}.ngb-dp-arrow-btn{padding:0 .25rem;margin:0 .5rem;border:none;background-color:transparent;z-index:1}.ngb-dp-arrow-btn:focus{outline-width:1px;outline-style:auto}@media (-ms-high-contrast:active),(-ms-high-contrast:none){.ngb-dp-arrow-btn:focus{outline-style:solid}}.ngb-dp-month-name{font-size:larger;height:2rem;line-height:2rem;text-align:center}.ngb-dp-navigation-select{display:flex;flex:1 1 9rem}"],encapsulation:2,changeDetection:0}),Y})();const Bl=(Y,fe)=>!!fe&&fe.some(w=>w.contains(Y)),md=(Y,fe)=>!fe||null!=function(Y,fe){return fe&&void 0!==Y.closest?Y.closest(fe):null}(Y,fe),td="undefined"!=typeof navigator&&!!navigator.userAgent&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||/Macintosh/.test(navigator.userAgent)&&navigator.maxTouchPoints&&navigator.maxTouchPoints>2||/Android/.test(navigator.userAgent));function la(Y,fe,w,X,ke,ct,Jn,Ir){w&&Y.runOutsideAngular((Y=>td?()=>setTimeout(()=>Y(),100):Y)(()=>{const zi=(0,ge.R)(fe,"keydown").pipe((0,Zt.R)(ke),(0,Ut.h)(Xo=>Xo.which===$i.Escape),(0,Zn.b)(Xo=>Xo.preventDefault())),Do=(0,ge.R)(fe,"mousedown").pipe((0,bt.U)(Xo=>{const Rs=Xo.target;return 2!==Xo.button&&!Bl(Rs,Jn)&&("inside"===w?Bl(Rs,ct)&&md(Rs,Ir):"outside"===w?!Bl(Rs,ct):md(Rs,Ir)||!Bl(Rs,ct))}),(0,Zt.R)(ke)),xs=(0,ge.R)(fe,"mouseup").pipe(je(Do),(0,Ut.h)(([Xo,Rs])=>Rs),(0,Ur.g)(0),(0,Zt.R)(ke));y([zi.pipe((0,bt.U)(Xo=>0)),xs.pipe((0,bt.U)(Xo=>1))]).subscribe(Xo=>Y.run(()=>X(Xo)))}))}const Zc=["a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])","[contenteditable]",'[tabindex]:not([tabindex="-1"])'].join(", ");function ic(Y){const fe=Array.from(Y.querySelectorAll(Zc)).filter(w=>-1!==w.tabIndex);return[fe[0],fe[fe.length-1]]}const df=(Y,fe,w,X=!1)=>{Y.runOutsideAngular(()=>{const ke=(0,ge.R)(fe,"focusin").pipe((0,Zt.R)(w),(0,bt.U)(ct=>ct.target));(0,ge.R)(fe,"keydown").pipe((0,Zt.R)(w),(0,Ut.h)(ct=>ct.which===$i.Tab),je(ke)).subscribe(([ct,Jn])=>{const[Ir,vi]=ic(fe);(Jn===Ir||Jn===fe)&&ct.shiftKey&&(vi.focus(),ct.preventDefault()),Jn===vi&&!ct.shiftKey&&(Ir.focus(),ct.preventDefault())}),X&&(0,ge.R)(fe,"click").pipe((0,Zt.R)(w),je(ke),(0,bt.U)(ct=>ct[1])).subscribe(ct=>ct.focus())})},Wd=/\s+/,Jd=new class{getAllStyles(fe){return window.getComputedStyle(fe)}getStyle(fe,w){return this.getAllStyles(fe)[w]}isStaticPositioned(fe){return"static"===(this.getStyle(fe,"position")||"static")}offsetParent(fe){let w=fe.offsetParent||document.documentElement;for(;w&&w!==document.documentElement&&this.isStaticPositioned(w);)w=w.offsetParent;return w||document.documentElement}position(fe,w=!0){let X,ke={width:0,height:0,top:0,bottom:0,left:0,right:0};if("fixed"===this.getStyle(fe,"position"))X=fe.getBoundingClientRect(),X={top:X.top,bottom:X.bottom,left:X.left,right:X.right,height:X.height,width:X.width};else{const ct=this.offsetParent(fe);X=this.offset(fe,!1),ct!==document.documentElement&&(ke=this.offset(ct,!1)),ke.top+=ct.clientTop,ke.left+=ct.clientLeft}return X.top-=ke.top,X.bottom-=ke.top,X.left-=ke.left,X.right-=ke.left,w&&(X.top=Math.round(X.top),X.bottom=Math.round(X.bottom),X.left=Math.round(X.left),X.right=Math.round(X.right)),X}offset(fe,w=!0){const X=fe.getBoundingClientRect(),ke_top=window.pageYOffset-document.documentElement.clientTop,ke_left=window.pageXOffset-document.documentElement.clientLeft;let ct={height:X.height||fe.offsetHeight,width:X.width||fe.offsetWidth,top:X.top+ke_top,bottom:X.bottom+ke_top,left:X.left+ke_left,right:X.right+ke_left};return w&&(ct.height=Math.round(ct.height),ct.width=Math.round(ct.width),ct.top=Math.round(ct.top),ct.bottom=Math.round(ct.bottom),ct.left=Math.round(ct.left),ct.right=Math.round(ct.right)),ct}positionElements(fe,w,X,ke){const[ct="top",Jn="center"]=X.split("-"),Ir=ke?this.offset(fe,!1):this.position(fe,!1),vi=this.getAllStyles(w),zi=parseFloat(vi.marginTop),Do=parseFloat(vi.marginBottom),xs=parseFloat(vi.marginLeft),Xo=parseFloat(vi.marginRight);let Rs=0,ma=0;switch(ct){case"top":Rs=Ir.top-(w.offsetHeight+zi+Do);break;case"bottom":Rs=Ir.top+Ir.height;break;case"left":ma=Ir.left-(w.offsetWidth+xs+Xo);break;case"right":ma=Ir.left+Ir.width}switch(Jn){case"top":Rs=Ir.top;break;case"bottom":Rs=Ir.top+Ir.height-w.offsetHeight;break;case"left":ma=Ir.left;break;case"right":ma=Ir.left+Ir.width-w.offsetWidth;break;case"center":"top"===ct||"bottom"===ct?ma=Ir.left+Ir.width/2-w.offsetWidth/2:Rs=Ir.top+Ir.height/2-w.offsetHeight/2}w.style.transform=`translate(${Math.round(ma)}px, ${Math.round(Rs)}px)`;const Vs=w.getBoundingClientRect(),_c=document.documentElement,nd=window.innerHeight||_c.clientHeight,wu=window.innerWidth||_c.clientWidth;return Vs.left>=0&&Vs.top>=0&&Vs.right<=wu&&Vs.bottom<=nd}};function Ye(Y,fe,w,X,ke){let ct=Array.isArray(w)?w:w.split(Wd);const Jn=["top","bottom","left","right","top-left","top-right","bottom-left","bottom-right","left-top","left-bottom","right-top","right-bottom"],Ir=fe.classList,vi=Rs=>{const[ma,Vs]=Rs.split("-"),_c=[];return ke&&(_c.push(`${ke}-${ma}`),Vs&&_c.push(`${ke}-${ma}-${Vs}`),_c.forEach(nd=>{Ir.add(nd)})),_c};ke&&Jn.forEach(Rs=>{Ir.remove(`${ke}-${Rs}`)});let zi=ct.findIndex(Rs=>"auto"===Rs);zi>=0&&Jn.forEach(function(Rs){null==ct.find(ma=>-1!==ma.search("^"+Rs))&&ct.splice(zi++,1,Rs)});const Do=fe.style;Do.position="absolute",Do.top="0",Do.left="0",Do["will-change"]="transform";let xs=null,Xo=!1;for(xs of ct){let Rs=vi(xs);if(Jd.positionElements(Y,fe,xs,X)){Xo=!0;break}ke&&Rs.forEach(ma=>{Ir.remove(ma)})}return Xo||(xs=ct[0],vi(xs),Jd.positionElements(Y,fe,xs,X)),xs}function Ie(){return new ot}let Ce=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275prov=r.Yz7({factory:Ie,token:Y,providedIn:"root"}),Y})(),ot=(()=>{class Y extends Ce{parse(w){if(null!=w){const X=w.trim().split("-");if(1===X.length&&ko(X[0]))return{year:pi(X[0]),month:null,day:null};if(2===X.length&&ko(X[0])&&ko(X[1]))return{year:pi(X[0]),month:pi(X[1]),day:null};if(3===X.length&&ko(X[0])&&ko(X[1])&&ko(X[2]))return{year:pi(X[0]),month:pi(X[1]),day:pi(X[2])}}return null}format(w){return w?`${w.year}-${ko(w.month)?sl(w.month):""}-${ko(w.day)?sl(w.day):""}`:""}}return Y.\u0275fac=function(){let fe;return function(X){return(fe||(fe=r.n5z(Y)))(X||Y)}}(),Y.\u0275prov=r.Yz7({token:Y,factory:Y.\u0275fac}),Y})(),Et=(()=>{class Y extends Na{constructor(){super(...arguments),this.autoClose=!0,this.placement=["bottom-left","bottom-right","top-left","top-right"],this.restoreFocus=!0}}return Y.\u0275fac=function(){let fe;return function(X){return(fe||(fe=r.n5z(Y)))(X||Y)}}(),Y.\u0275prov=r.Yz7({factory:function(){return new Y},token:Y,providedIn:"root"}),Y})(),qt=(()=>{class Y{constructor(w,X,ke,ct,Jn,Ir,vi,zi,Do,xs,Xo){this._parserFormatter=w,this._elRef=X,this._vcRef=ke,this._renderer=ct,this._cfr=Jn,this._ngZone=Ir,this._calendar=vi,this._dateAdapter=zi,this._document=Do,this._changeDetector=xs,this._cRef=null,this._disabled=!1,this._elWithFocus=null,this._model=null,this.dateSelect=new r.vpe,this.navigate=new r.vpe,this.closed=new r.vpe,this._onChange=Rs=>{},this._onTouched=()=>{},this._validatorChange=()=>{},["autoClose","container","positionTarget","placement"].forEach(Rs=>this[Rs]=Xo[Rs]),this._zoneSubscription=Ir.onStable.subscribe(()=>this._updatePopupPosition())}get disabled(){return this._disabled}set disabled(w){this._disabled=""===w||w&&"false"!==w,this.isOpen()&&this._cRef.instance.setDisabledState(this._disabled)}registerOnChange(w){this._onChange=w}registerOnTouched(w){this._onTouched=w}registerOnValidatorChange(w){this._validatorChange=w}setDisabledState(w){this.disabled=w}validate(w){const{value:X}=w;if(null!=X){const ke=this._fromDateStruct(this._dateAdapter.fromModel(X));if(!ke)return{ngbDate:{invalid:X}};if(this.minDate&&ke.before(aa.from(this.minDate)))return{ngbDate:{minDate:{minDate:this.minDate,actual:X}}};if(this.maxDate&&ke.after(aa.from(this.maxDate)))return{ngbDate:{maxDate:{maxDate:this.maxDate,actual:X}}}}return null}writeValue(w){this._model=this._fromDateStruct(this._dateAdapter.fromModel(w)),this._writeModelValue(this._model)}manualDateChange(w,X=!1){const ke=w!==this._inputValue;ke&&(this._inputValue=w,this._model=this._fromDateStruct(this._parserFormatter.parse(w))),(ke||!X)&&this._onChange(this._model?this._dateAdapter.toModel(this._model):""===w?null:w),X&&this._model&&this._writeModelValue(this._model)}isOpen(){return!!this._cRef}open(){if(!this.isOpen()){const w=this._cfr.resolveComponentFactory(Gl);this._cRef=this._vcRef.createComponent(w),this._applyPopupStyling(this._cRef.location.nativeElement),this._applyDatepickerInputs(this._cRef.instance),this._subscribeForDatepickerOutputs(this._cRef.instance),this._cRef.instance.ngOnInit(),this._cRef.instance.writeValue(this._dateAdapter.toModel(this._model)),this._cRef.instance.registerOnChange(X=>{this.writeValue(X),this._onChange(X),this._onTouched()}),this._cRef.changeDetectorRef.detectChanges(),this._cRef.instance.setDisabledState(this.disabled),"body"===this.container&&this._document.querySelector(this.container).appendChild(this._cRef.location.nativeElement),this._elWithFocus=this._document.activeElement,df(this._ngZone,this._cRef.location.nativeElement,this.closed,!0),this._cRef.instance.focus(),la(this._ngZone,this._document,this.autoClose,()=>this.close(),this.closed,[],[this._elRef.nativeElement,this._cRef.location.nativeElement])}}close(){if(this.isOpen()){this._vcRef.remove(this._vcRef.indexOf(this._cRef.hostView)),this._cRef=null,this.closed.emit(),this._changeDetector.markForCheck();let w=this._elWithFocus;wo(this.restoreFocus)?w=this._document.querySelector(this.restoreFocus):void 0!==this.restoreFocus&&(w=this.restoreFocus),w&&w.focus?w.focus():this._document.body.focus()}}toggle(){this.isOpen()?this.close():this.open()}navigateTo(w){this.isOpen()&&this._cRef.instance.navigateTo(w)}onBlur(){this._onTouched()}onFocus(){this._elWithFocus=this._elRef.nativeElement}ngOnChanges(w){if((w.minDate||w.maxDate)&&(this._validatorChange(),this.isOpen()&&(w.minDate&&(this._cRef.instance.minDate=this.minDate),w.maxDate&&(this._cRef.instance.maxDate=this.maxDate),this._cRef.instance.ngOnChanges(w))),w.datepickerClass){const{currentValue:X,previousValue:ke}=w.datepickerClass;this._applyPopupClass(X,ke)}}ngOnDestroy(){this.close(),this._zoneSubscription.unsubscribe()}_applyDatepickerInputs(w){["dayTemplate","dayTemplateData","displayMonths","firstDayOfWeek","footerTemplate","markDisabled","minDate","maxDate","navigation","outsideDays","showNavigation","showWeekNumbers","weekdays"].forEach(X=>{void 0!==this[X]&&(w[X]=this[X])}),w.startDate=this.startDate||this._model}_applyPopupClass(w,X){var ke;const ct=null===(ke=this._cRef)||void 0===ke?void 0:ke.location.nativeElement;ct&&(w&&this._renderer.addClass(ct,w),X&&this._renderer.removeClass(ct,X))}_applyPopupStyling(w){this._renderer.addClass(w,"dropdown-menu"),this._renderer.addClass(w,"show"),"body"===this.container&&this._renderer.addClass(w,"ngb-dp-body"),this._applyPopupClass(this.datepickerClass)}_subscribeForDatepickerOutputs(w){w.navigate.subscribe(X=>this.navigate.emit(X)),w.dateSelect.subscribe(X=>{this.dateSelect.emit(X),(!0===this.autoClose||"inside"===this.autoClose)&&this.close()})}_writeModelValue(w){const X=this._parserFormatter.format(w);this._inputValue=X,this._renderer.setProperty(this._elRef.nativeElement,"value",X),this.isOpen()&&(this._cRef.instance.writeValue(this._dateAdapter.toModel(w)),this._onTouched())}_fromDateStruct(w){const X=w?new aa(w.year,w.month,w.day):null;return this._calendar.isValid(X)?X:null}_updatePopupPosition(){if(!this._cRef)return;let w;if(w=wo(this.positionTarget)?this._document.querySelector(this.positionTarget):this.positionTarget instanceof HTMLElement?this.positionTarget:this._elRef.nativeElement,this.positionTarget&&!w)throw new Error("ngbDatepicker could not find element declared in [positionTarget] to position against.");Ye(w,this._cRef.location.nativeElement,this.placement,"body"===this.container)}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(Ce),r.Y36(r.SBq),r.Y36(r.s_b),r.Y36(r.Qsj),r.Y36(r._Vd),r.Y36(r.R0b),r.Y36(Ul),r.Y36(Qs),r.Y36(u.K0),r.Y36(r.sBO),r.Y36(Et))},Y.\u0275dir=r.lG2({type:Y,selectors:[["input","ngbDatepicker",""]],hostVars:1,hostBindings:function(w,X){1&w&&r.NdJ("input",function(ct){return X.manualDateChange(ct.target.value)})("change",function(ct){return X.manualDateChange(ct.target.value,!0)})("focus",function(){return X.onFocus()})("blur",function(){return X.onBlur()}),2&w&&r.Ikx("disabled",X.disabled)},inputs:{disabled:"disabled",autoClose:"autoClose",datepickerClass:"datepickerClass",dayTemplate:"dayTemplate",dayTemplateData:"dayTemplateData",displayMonths:"displayMonths",firstDayOfWeek:"firstDayOfWeek",footerTemplate:"footerTemplate",markDisabled:"markDisabled",minDate:"minDate",maxDate:"maxDate",navigation:"navigation",outsideDays:"outsideDays",placement:"placement",restoreFocus:"restoreFocus",showWeekNumbers:"showWeekNumbers",startDate:"startDate",container:"container",positionTarget:"positionTarget",weekdays:"weekdays"},outputs:{dateSelect:"dateSelect",navigate:"navigate",closed:"closed"},exportAs:["ngbDatepicker"],features:[r._Bn([{provide:Mr.JU,useExisting:(0,r.Gpc)(()=>Y),multi:!0},{provide:Mr.Cf,useExisting:(0,r.Gpc)(()=>Y),multi:!0},{provide:Na,useExisting:Et}]),r.TTD]}),Y})(),Hn=(()=>{class Y{constructor(w){this.i18n=w}isMuted(){return!this.selected&&(this.date.month!==this.currentMonth||this.disabled)}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(Cr))},Y.\u0275cmp=r.Xpm({type:Y,selectors:[["","ngbDatepickerDayView",""]],hostAttrs:[1,"btn-light"],hostVars:10,hostBindings:function(w,X){2&w&&r.ekj("bg-primary",X.selected)("text-white",X.selected)("text-muted",X.isMuted())("outside",X.isMuted())("active",X.focused)},inputs:{currentMonth:"currentMonth",date:"date",disabled:"disabled",focused:"focused",selected:"selected"},attrs:dr,decls:1,vars:1,template:function(w,X){1&w&&r._uU(0),2&w&&r.Oqu(X.i18n.getDayNumerals(X.date))},styles:["[ngbDatepickerDayView]{text-align:center;width:2rem;height:2rem;line-height:2rem;border-radius:.25rem;background:transparent}[ngbDatepickerDayView].outside{opacity:.5}"],encapsulation:2,changeDetection:0}),Y})(),Xn=(()=>{class Y{constructor(w,X){this.i18n=w,this._renderer=X,this.select=new r.vpe,this._month=-1,this._year=-1}changeMonth(w){this.select.emit(new aa(this.date.year,pi(w),1))}changeYear(w){this.select.emit(new aa(pi(w),this.date.month,1))}ngAfterViewChecked(){this.date&&(this.date.month!==this._month&&(this._month=this.date.month,this._renderer.setProperty(this.monthSelect.nativeElement,"value",this._month)),this.date.year!==this._year&&(this._year=this.date.year,this._renderer.setProperty(this.yearSelect.nativeElement,"value",this._year)))}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(Cr),r.Y36(r.Qsj))},Y.\u0275cmp=r.Xpm({type:Y,selectors:[["ngb-datepicker-navigation-select"]],viewQuery:function(w,X){if(1&w&&(r.Gf(Fn,7,r.SBq),r.Gf(ar,7,r.SBq)),2&w){let ke;r.iGM(ke=r.CRH())&&(X.monthSelect=ke.first),r.iGM(ke=r.CRH())&&(X.yearSelect=ke.first)}},inputs:{date:"date",disabled:"disabled",months:"months",years:"years"},outputs:{select:"select"},decls:6,vars:4,consts:function(){let fe,w,X,ke;return fe="Select month",w="Select month",X="Select year",ke="Select year",[["aria-label",fe,"title",w,1,"custom-select",3,"disabled","change"],["month",""],[3,"value",4,"ngFor","ngForOf"],["aria-label",X,"title",ke,1,"custom-select",3,"disabled","change"],["year",""],[3,"value"]]},template:function(w,X){1&w&&(r.TgZ(0,"select",0,1),r.NdJ("change",function(ct){return X.changeMonth(ct.target.value)}),r.YNc(2,Wi,2,3,"option",2),r.qZA(),r.TgZ(3,"select",3,4),r.NdJ("change",function(ct){return X.changeYear(ct.target.value)}),r.YNc(5,lo,2,2,"option",2),r.qZA()),2&w&&(r.Q6J("disabled",X.disabled),r.xp6(2),r.Q6J("ngForOf",X.months),r.xp6(1),r.Q6J("disabled",X.disabled),r.xp6(2),r.Q6J("ngForOf",X.years))},directives:[u.sg,Mr.YN,Mr.Kr],styles:["ngb-datepicker-navigation-select>.custom-select{flex:1 1 auto;padding:0 .5rem;font-size:.875rem;height:1.85rem}ngb-datepicker-navigation-select>.custom-select:focus{z-index:1}ngb-datepicker-navigation-select>.custom-select::-ms-value{background-color:transparent!important}"],encapsulation:2,changeDetection:0}),Y})();new Date(1882,10,12),new Date(2174,10,25);let Yu=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275mod=r.oAB({type:Y}),Y.\u0275inj=r.cJS({imports:[[u.ez,Mr.u5]]}),Y})(),pc=(()=>{class Y{constructor(){this.autoClose=!0,this.placement=["bottom-left","bottom-right","top-left","top-right"]}}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275prov=r.Yz7({factory:function(){return new Y},token:Y,providedIn:"root"}),Y})(),Kd=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275dir=r.lG2({type:Y,selectors:[["",8,"navbar"]]}),Y})(),wf=(()=>{class Y{constructor(w){this.elementRef=w,this._disabled=!1}set disabled(w){this._disabled=""===w||!0===w}get disabled(){return this._disabled}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(r.SBq))},Y.\u0275dir=r.lG2({type:Y,selectors:[["","ngbDropdownItem",""]],hostAttrs:[1,"dropdown-item"],hostVars:2,hostBindings:function(w,X){2&w&&r.ekj("disabled",X.disabled)},inputs:{disabled:"disabled"}}),Y})(),Vl=(()=>{class Y{constructor(w,X){this.dropdown=w,this.placement="bottom",this.isOpen=!1,this.nativeElement=X.nativeElement}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36((0,r.Gpc)(()=>hc)),r.Y36(r.SBq))},Y.\u0275dir=r.lG2({type:Y,selectors:[["","ngbDropdownMenu",""]],contentQueries:function(w,X,ke){if(1&w&&r.Suo(ke,wf,4),2&w){let ct;r.iGM(ct=r.CRH())&&(X.menuItems=ct)}},hostVars:5,hostBindings:function(w,X){1&w&&r.NdJ("keydown.ArrowUp",function(ct){return X.dropdown.onKeyDown(ct)})("keydown.ArrowDown",function(ct){return X.dropdown.onKeyDown(ct)})("keydown.Home",function(ct){return X.dropdown.onKeyDown(ct)})("keydown.End",function(ct){return X.dropdown.onKeyDown(ct)})("keydown.Enter",function(ct){return X.dropdown.onKeyDown(ct)})("keydown.Space",function(ct){return X.dropdown.onKeyDown(ct)})("keydown.Tab",function(ct){return X.dropdown.onKeyDown(ct)})("keydown.Shift.Tab",function(ct){return X.dropdown.onKeyDown(ct)}),2&w&&(r.uIk("x-placement",X.placement),r.ekj("dropdown-menu",!0)("show",X.dropdown.isOpen()))}}),Y})(),Id=(()=>{class Y{constructor(w,X){this.dropdown=w,this.nativeElement=X.nativeElement}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36((0,r.Gpc)(()=>hc)),r.Y36(r.SBq))},Y.\u0275dir=r.lG2({type:Y,selectors:[["","ngbDropdownAnchor",""]],hostAttrs:[1,"dropdown-toggle"],hostVars:1,hostBindings:function(w,X){2&w&&r.uIk("aria-expanded",X.dropdown.isOpen())}}),Y})(),oc=(()=>{class Y extends Id{constructor(w,X){super(w,X)}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36((0,r.Gpc)(()=>hc)),r.Y36(r.SBq))},Y.\u0275dir=r.lG2({type:Y,selectors:[["","ngbDropdownToggle",""]],hostAttrs:[1,"dropdown-toggle"],hostVars:1,hostBindings:function(w,X){1&w&&r.NdJ("click",function(){return X.dropdown.toggle()})("keydown.ArrowUp",function(ct){return X.dropdown.onKeyDown(ct)})("keydown.ArrowDown",function(ct){return X.dropdown.onKeyDown(ct)})("keydown.Home",function(ct){return X.dropdown.onKeyDown(ct)})("keydown.End",function(ct){return X.dropdown.onKeyDown(ct)})("keydown.Tab",function(ct){return X.dropdown.onKeyDown(ct)})("keydown.Shift.Tab",function(ct){return X.dropdown.onKeyDown(ct)}),2&w&&r.uIk("aria-expanded",X.dropdown.isOpen())},features:[r._Bn([{provide:Id,useExisting:(0,r.Gpc)(()=>Y)}]),r.qOj]}),Y})(),hc=(()=>{class Y{constructor(w,X,ke,ct,Jn,Ir,vi){this._changeDetector=w,this._document=ke,this._ngZone=ct,this._elementRef=Jn,this._renderer=Ir,this._closed$=new he.xQ,this._bodyContainer=null,this._open=!1,this.openChange=new r.vpe,this.placement=X.placement,this.container=X.container,this.autoClose=X.autoClose,this.display=vi?"static":"dynamic",this._zoneSubscription=ct.onStable.subscribe(()=>{this._positionMenu()})}ngAfterContentInit(){this._ngZone.onStable.pipe((0,Bt.q)(1)).subscribe(()=>{this._applyPlacementClasses(),this._open&&this._setCloseHandlers()})}ngOnChanges(w){if(w.container&&this._open&&this._applyContainer(this.container),w.placement&&!w.placement.isFirstChange&&this._applyPlacementClasses(),w.dropdownClass){const{currentValue:X,previousValue:ke}=w.dropdownClass;this._applyCustomDropdownClass(X,ke)}}isOpen(){return this._open}open(){this._open||(this._open=!0,this._applyContainer(this.container),this.openChange.emit(!0),this._setCloseHandlers(),this._anchor&&this._anchor.nativeElement.focus())}_setCloseHandlers(){la(this._ngZone,this._document,this.autoClose,w=>{this.close(),0===w&&this._anchor.nativeElement.focus()},this._closed$,this._menu?[this._menu.nativeElement]:[],this._anchor?[this._anchor.nativeElement]:[],".dropdown-item,.dropdown-divider")}close(){this._open&&(this._open=!1,this._resetContainer(),this._closed$.next(),this.openChange.emit(!1),this._changeDetector.markForCheck())}toggle(){this.isOpen()?this.close():this.open()}ngOnDestroy(){this._resetContainer(),this._closed$.next(),this._zoneSubscription.unsubscribe()}onKeyDown(w){const X=w.which,ke=this._getMenuElements();let ct=-1,Jn=null;const Ir=this._isEventFromToggle(w);if(!Ir&&ke.length&&ke.forEach((vi,zi)=>{vi.contains(w.target)&&(Jn=vi),vi===this._document.activeElement&&(ct=zi)}),X!==$i.Space&&X!==$i.Enter){if(X!==$i.Tab){if(Ir||Jn){if(this.open(),ke.length){switch(X){case $i.ArrowDown:ct=Math.min(ct+1,ke.length-1);break;case $i.ArrowUp:if(this._isDropup()&&-1===ct){ct=ke.length-1;break}ct=Math.max(ct-1,0);break;case $i.Home:ct=0;break;case $i.End:ct=ke.length-1}ke[ct].focus()}w.preventDefault()}}else if(w.target&&this.isOpen()&&this.autoClose){if(this._anchor.nativeElement===w.target)return void("body"!==this.container||w.shiftKey?w.shiftKey&&this.close():(this._renderer.setAttribute(this._menu.nativeElement,"tabindex","0"),this._menu.nativeElement.focus(),this._renderer.removeAttribute(this._menu.nativeElement,"tabindex")));if("body"===this.container){const vi=this._menu.nativeElement.querySelectorAll(Zc);w.shiftKey&&w.target===vi[0]?(this._anchor.nativeElement.focus(),w.preventDefault()):!w.shiftKey&&w.target===vi[vi.length-1]&&(this._anchor.nativeElement.focus(),this.close())}else(0,ge.R)(w.target,"focusout").pipe((0,Bt.q)(1)).subscribe(({relatedTarget:vi})=>{this._elementRef.nativeElement.contains(vi)||this.close()})}}else Jn&&(!0===this.autoClose||"inside"===this.autoClose)&&(0,ge.R)(Jn,"click").pipe((0,Bt.q)(1)).subscribe(()=>this.close())}_isDropup(){return this._elementRef.nativeElement.classList.contains("dropup")}_isEventFromToggle(w){return this._anchor.nativeElement.contains(w.target)}_getMenuElements(){const w=this._menu;return null==w?[]:w.menuItems.filter(X=>!X.disabled).map(X=>X.elementRef.nativeElement)}_positionMenu(){const w=this._menu;this.isOpen()&&w&&this._applyPlacementClasses("dynamic"===this.display?Ye(this._anchor.nativeElement,this._bodyContainer||this._menu.nativeElement,this.placement,"body"===this.container):this._getFirstPlacement(this.placement))}_getFirstPlacement(w){return Array.isArray(w)?w[0]:w.split(" ")[0]}_resetContainer(){const w=this._renderer;if(this._menu){const ke=this._menu.nativeElement;w.appendChild(this._elementRef.nativeElement,ke),w.removeStyle(ke,"position"),w.removeStyle(ke,"transform")}this._bodyContainer&&(w.removeChild(this._document.body,this._bodyContainer),this._bodyContainer=null)}_applyContainer(w=null){if(this._resetContainer(),"body"===w){const X=this._renderer,ke=this._menu.nativeElement,ct=this._bodyContainer=this._bodyContainer||X.createElement("div");X.setStyle(ct,"position","absolute"),X.setStyle(ke,"position","static"),X.setStyle(ct,"z-index","1050"),X.appendChild(ct,ke),X.appendChild(this._document.body,ct)}this._applyCustomDropdownClass(this.dropdownClass)}_applyCustomDropdownClass(w,X){const ke="body"===this.container?this._bodyContainer:this._elementRef.nativeElement;ke&&(X&&this._renderer.removeClass(ke,X),w&&this._renderer.addClass(ke,w))}_applyPlacementClasses(w){const X=this._menu;if(X){w||(w=this._getFirstPlacement(this.placement));const ke=this._renderer,ct=this._elementRef.nativeElement;ke.removeClass(ct,"dropup"),ke.removeClass(ct,"dropdown"),X.placement="static"===this.display?null:w;const Jn=-1!==w.search("^top")?"dropup":"dropdown";ke.addClass(ct,Jn);const Ir=this._bodyContainer;Ir&&(ke.removeClass(Ir,"dropup"),ke.removeClass(Ir,"dropdown"),ke.addClass(Ir,Jn))}}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(r.sBO),r.Y36(pc),r.Y36(u.K0),r.Y36(r.R0b),r.Y36(r.SBq),r.Y36(r.Qsj),r.Y36(Kd,8))},Y.\u0275dir=r.lG2({type:Y,selectors:[["","ngbDropdown",""]],contentQueries:function(w,X,ke){if(1&w&&(r.Suo(ke,Vl,5),r.Suo(ke,Id,5)),2&w){let ct;r.iGM(ct=r.CRH())&&(X._menu=ct.first),r.iGM(ct=r.CRH())&&(X._anchor=ct.first)}},hostVars:2,hostBindings:function(w,X){2&w&&r.ekj("show",X.isOpen())},inputs:{_open:["open","_open"],placement:"placement",container:"container",autoClose:"autoClose",display:"display",dropdownClass:"dropdownClass"},outputs:{openChange:"openChange"},exportAs:["ngbDropdown"],features:[r.TTD]}),Y})(),Mc=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275mod=r.oAB({type:Y}),Y.\u0275inj=r.cJS({}),Y})(),Hc=(()=>{class Y{constructor(w){this._ngbConfig=w,this.backdrop=!0,this.keyboard=!0}get animation(){return void 0===this._animation?this._ngbConfig.animation:this._animation}set animation(w){this._animation=w}}return Y.\u0275fac=function(w){return new(w||Y)(r.LFG(Fs))},Y.\u0275prov=r.Yz7({factory:function(){return new Y(r.LFG(Fs))},token:Y,providedIn:"root"}),Y})();class cu{constructor(fe,w,X){this.nodes=fe,this.viewRef=w,this.componentRef=X}}class Lu{constructor(fe,w,X,ke,ct,Jn,Ir){this._type=fe,this._injector=w,this._viewContainerRef=X,this._renderer=ke,this._ngZone=ct,this._componentFactoryResolver=Jn,this._applicationRef=Ir,this._windowRef=null,this._contentRef=null}open(fe,w,X=!1){this._windowRef||(this._contentRef=this._getContentRef(fe,w),this._windowRef=this._viewContainerRef.createComponent(this._componentFactoryResolver.resolveComponentFactory(this._type),this._viewContainerRef.length,this._injector,this._contentRef.nodes));const{nativeElement:ke}=this._windowRef.location,ct=this._ngZone.onStable.pipe((0,Bt.q)(1),(0,di.zg)(()=>Pt(this._ngZone,ke,({classList:Jn})=>Jn.add("show"),{animation:X,runningTransition:"continue"})));return{windowRef:this._windowRef,transition$:ct}}close(fe=!1){return this._windowRef?Pt(this._ngZone,this._windowRef.location.nativeElement,({classList:w})=>w.remove("show"),{animation:fe,runningTransition:"stop"}).pipe((0,Zn.b)(()=>{var w;this._windowRef&&(this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._windowRef.hostView)),this._windowRef=null),(null===(w=this._contentRef)||void 0===w?void 0:w.viewRef)&&(this._applicationRef.detachView(this._contentRef.viewRef),this._contentRef.viewRef.destroy(),this._contentRef=null)})):(0,ie.of)(void 0)}_getContentRef(fe,w){if(fe){if(fe instanceof r.Rgc){const X=fe.createEmbeddedView(w);return this._applicationRef.attachView(X),new cu([X.rootNodes],X)}return new cu([[this._renderer.createText(`${fe}`)]])}return new cu([])}}const Ou=()=>{};let bu=(()=>{class Y{constructor(w){this._document=w}compensate(){const w=this._getWidth();return this._isPresent(w)?this._adjustBody(w):Ou}_adjustBody(w){const X=this._document.body,ke=X.style.paddingRight,ct=parseFloat(window.getComputedStyle(X)["padding-right"]);return X.style["padding-right"]=`${ct+w}px`,()=>X.style["padding-right"]=ke}_isPresent(w){const X=this._document.body.getBoundingClientRect();return window.innerWidth-(X.left+X.right)>=w-.1*w}_getWidth(){const w=this._document.createElement("div");w.className="modal-scrollbar-measure";const X=this._document.body;X.appendChild(w);const ke=w.getBoundingClientRect().width-w.clientWidth;return X.removeChild(w),ke}}return Y.\u0275fac=function(w){return new(w||Y)(r.LFG(u.K0))},Y.\u0275prov=r.Yz7({factory:function(){return new Y(r.LFG(u.K0))},token:Y,providedIn:"root"}),Y})(),h=(()=>{class Y{constructor(w,X){this._el=w,this._zone=X}ngOnInit(){this._zone.onStable.asObservable().pipe((0,Bt.q)(1)).subscribe(()=>{Pt(this._zone,this._el.nativeElement,(w,X)=>{X&&Ec(w),w.classList.add("show")},{animation:this.animation,runningTransition:"continue"})})}hide(){return Pt(this._zone,this._el.nativeElement,({classList:w})=>w.remove("show"),{animation:this.animation,runningTransition:"stop"})}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(r.SBq),r.Y36(r.R0b))},Y.\u0275cmp=r.Xpm({type:Y,selectors:[["ngb-modal-backdrop"]],hostAttrs:[2,"z-index","1050"],hostVars:6,hostBindings:function(w,X){2&w&&(r.Tol("modal-backdrop"+(X.backdropClass?" "+X.backdropClass:"")),r.ekj("show",!X.animation)("fade",X.animation))},inputs:{animation:"animation",backdropClass:"backdropClass"},decls:0,vars:0,template:function(w,X){},encapsulation:2}),Y})();class E{close(fe){}dismiss(fe){}}class R{constructor(fe,w,X,ke){this._windowCmptRef=fe,this._contentRef=w,this._backdropCmptRef=X,this._beforeDismiss=ke,this._closed=new he.xQ,this._dismissed=new he.xQ,this._hidden=new he.xQ,fe.instance.dismissEvent.subscribe(ct=>{this.dismiss(ct)}),this.result=new Promise((ct,Jn)=>{this._resolve=ct,this._reject=Jn}),this.result.then(null,()=>{})}get componentInstance(){if(this._contentRef&&this._contentRef.componentRef)return this._contentRef.componentRef.instance}get closed(){return this._closed.asObservable().pipe((0,Zt.R)(this._hidden))}get dismissed(){return this._dismissed.asObservable().pipe((0,Zt.R)(this._hidden))}get hidden(){return this._hidden.asObservable()}get shown(){return this._windowCmptRef.instance.shown.asObservable()}close(fe){this._windowCmptRef&&(this._closed.next(fe),this._resolve(fe),this._removeModalElements())}_dismiss(fe){this._dismissed.next(fe),this._reject(fe),this._removeModalElements()}dismiss(fe){if(this._windowCmptRef)if(this._beforeDismiss){const w=this._beforeDismiss();w&&w.then?w.then(X=>{!1!==X&&this._dismiss(fe)},()=>{}):!1!==w&&this._dismiss(fe)}else this._dismiss(fe)}_removeModalElements(){const fe=this._windowCmptRef.instance.hide(),w=this._backdropCmptRef?this._backdropCmptRef.instance.hide():(0,ie.of)(void 0);fe.subscribe(()=>{const{nativeElement:X}=this._windowCmptRef.location;X.parentNode.removeChild(X),this._windowCmptRef.destroy(),this._contentRef&&this._contentRef.viewRef&&this._contentRef.viewRef.destroy(),this._windowCmptRef=null,this._contentRef=null}),w.subscribe(()=>{if(this._backdropCmptRef){const{nativeElement:X}=this._backdropCmptRef.location;X.parentNode.removeChild(X),this._backdropCmptRef.destroy(),this._backdropCmptRef=null}}),J(fe,w).subscribe(()=>{this._hidden.next(),this._hidden.complete()})}}var F=(()=>{return(Y=F||(F={}))[Y.BACKDROP_CLICK=0]="BACKDROP_CLICK",Y[Y.ESC=1]="ESC",F;var Y})();let q=(()=>{class Y{constructor(w,X,ke){this._document=w,this._elRef=X,this._zone=ke,this._closed$=new he.xQ,this._elWithFocus=null,this.backdrop=!0,this.keyboard=!0,this.dismissEvent=new r.vpe,this.shown=new he.xQ,this.hidden=new he.xQ}dismiss(w){this.dismissEvent.emit(w)}ngOnInit(){this._elWithFocus=this._document.activeElement,this._zone.onStable.asObservable().pipe((0,Bt.q)(1)).subscribe(()=>{this._show()})}ngOnDestroy(){this._disableEventHandling()}hide(){const{nativeElement:w}=this._elRef,X={animation:this.animation,runningTransition:"stop"},Jn=J(Pt(this._zone,w,()=>w.classList.remove("show"),X),Pt(this._zone,this._dialogEl.nativeElement,()=>{},X));return Jn.subscribe(()=>{this.hidden.next(),this.hidden.complete()}),this._disableEventHandling(),this._restoreFocus(),Jn}_show(){const w={animation:this.animation,runningTransition:"continue"};J(Pt(this._zone,this._elRef.nativeElement,(ct,Jn)=>{Jn&&Ec(ct),ct.classList.add("show")},w),Pt(this._zone,this._dialogEl.nativeElement,()=>{},w)).subscribe(()=>{this.shown.next(),this.shown.complete()}),this._enableEventHandling(),this._setFocus()}_enableEventHandling(){const{nativeElement:w}=this._elRef;this._zone.runOutsideAngular(()=>{(0,ge.R)(w,"keydown").pipe((0,Zt.R)(this._closed$),(0,Ut.h)(ke=>ke.which===$i.Escape)).subscribe(ke=>{this.keyboard?requestAnimationFrame(()=>{ke.defaultPrevented||this._zone.run(()=>this.dismiss(F.ESC))}):"static"===this.backdrop&&this._bumpBackdrop()});let X=!1;(0,ge.R)(this._dialogEl.nativeElement,"mousedown").pipe((0,Zt.R)(this._closed$),(0,Zn.b)(()=>X=!1),(0,Xt.w)(()=>(0,ge.R)(w,"mouseup").pipe((0,Zt.R)(this._closed$),(0,Bt.q)(1))),(0,Ut.h)(({target:ke})=>w===ke)).subscribe(()=>{X=!0}),(0,ge.R)(w,"click").pipe((0,Zt.R)(this._closed$)).subscribe(({target:ke})=>{w===ke&&("static"===this.backdrop?this._bumpBackdrop():!0===this.backdrop&&!X&&this._zone.run(()=>this.dismiss(F.BACKDROP_CLICK))),X=!1})})}_disableEventHandling(){this._closed$.next()}_setFocus(){const{nativeElement:w}=this._elRef;if(!w.contains(document.activeElement)){const X=w.querySelector("[ngbAutofocus]"),ke=ic(w)[0];(X||ke||w).focus()}}_restoreFocus(){const w=this._document.body,X=this._elWithFocus;let ke;ke=X&&X.focus&&w.contains(X)?X:w,this._zone.runOutsideAngular(()=>{setTimeout(()=>ke.focus()),this._elWithFocus=null})}_bumpBackdrop(){"static"===this.backdrop&&Pt(this._zone,this._elRef.nativeElement,({classList:w})=>(w.add("modal-static"),()=>w.remove("modal-static")),{animation:this.animation,runningTransition:"continue"})}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(u.K0),r.Y36(r.SBq),r.Y36(r.R0b))},Y.\u0275cmp=r.Xpm({type:Y,selectors:[["ngb-modal-window"]],viewQuery:function(w,X){if(1&w&&r.Gf(vo,7),2&w){let ke;r.iGM(ke=r.CRH())&&(X._dialogEl=ke.first)}},hostAttrs:["role","dialog","tabindex","-1"],hostVars:7,hostBindings:function(w,X){2&w&&(r.uIk("aria-modal",!0)("aria-labelledby",X.ariaLabelledBy)("aria-describedby",X.ariaDescribedBy),r.Tol("modal d-block"+(X.windowClass?" "+X.windowClass:"")),r.ekj("fade",X.animation))},inputs:{backdrop:"backdrop",keyboard:"keyboard",animation:"animation",ariaLabelledBy:"ariaLabelledBy",ariaDescribedBy:"ariaDescribedBy",centered:"centered",scrollable:"scrollable",size:"size",windowClass:"windowClass",modalDialogClass:"modalDialogClass"},outputs:{dismissEvent:"dismiss"},ngContentSelectors:Hi,decls:4,vars:2,consts:[["role","document"],["dialog",""],[1,"modal-content"]],template:function(w,X){1&w&&(r.F$t(),r.TgZ(0,"div",0,1),r.TgZ(2,"div",2),r.Hsn(3),r.qZA(),r.qZA()),2&w&&r.Tol("modal-dialog"+(X.size?" modal-"+X.size:"")+(X.centered?" modal-dialog-centered":"")+(X.scrollable?" modal-dialog-scrollable":"")+(X.modalDialogClass?" "+X.modalDialogClass:""))},styles:["ngb-modal-window .component-host-scrollable{display:flex;flex-direction:column;overflow:hidden}"],encapsulation:2}),Y})(),de=(()=>{class Y{constructor(w,X,ke,ct,Jn,Ir){this._applicationRef=w,this._injector=X,this._document=ke,this._scrollBar=ct,this._rendererFactory=Jn,this._ngZone=Ir,this._activeWindowCmptHasChanged=new he.xQ,this._ariaHiddenValues=new Map,this._backdropAttributes=["animation","backdropClass"],this._modalRefs=[],this._windowAttributes=["animation","ariaLabelledBy","ariaDescribedBy","backdrop","centered","keyboard","scrollable","size","windowClass","modalDialogClass"],this._windowCmpts=[],this._activeInstances=new r.vpe,this._activeWindowCmptHasChanged.subscribe(()=>{if(this._windowCmpts.length){const vi=this._windowCmpts[this._windowCmpts.length-1];df(this._ngZone,vi.location.nativeElement,this._activeWindowCmptHasChanged),this._revertAriaHidden(),this._setAriaHidden(vi.location.nativeElement)}})}open(w,X,ke,ct){const Jn=ct.container instanceof HTMLElement?ct.container:ba(ct.container)?this._document.querySelector(ct.container):this._document.body,Ir=this._rendererFactory.createRenderer(null,null),vi=this._scrollBar.compensate(),zi=()=>{this._modalRefs.length||(Ir.removeClass(this._document.body,"modal-open"),this._revertAriaHidden())};if(!Jn)throw new Error(`The specified modal container "${ct.container||"body"}" was not found in the DOM.`);const Do=new E,xs=this._getContentRef(w,ct.injector||X,ke,Do,ct);let Xo=!1!==ct.backdrop?this._attachBackdrop(w,Jn):void 0,Rs=this._attachWindowComponent(w,Jn,xs),ma=new R(Rs,xs,Xo,ct.beforeDismiss);return this._registerModalRef(ma),this._registerWindowCmpt(Rs),ma.result.then(vi,vi),ma.result.then(zi,zi),Do.close=Vs=>{ma.close(Vs)},Do.dismiss=Vs=>{ma.dismiss(Vs)},this._applyWindowOptions(Rs.instance,ct),1===this._modalRefs.length&&Ir.addClass(this._document.body,"modal-open"),Xo&&Xo.instance&&(this._applyBackdropOptions(Xo.instance,ct),Xo.changeDetectorRef.detectChanges()),Rs.changeDetectorRef.detectChanges(),ma}get activeInstances(){return this._activeInstances}dismissAll(w){this._modalRefs.forEach(X=>X.dismiss(w))}hasOpenModals(){return this._modalRefs.length>0}_attachBackdrop(w,X){let ct=w.resolveComponentFactory(h).create(this._injector);return this._applicationRef.attachView(ct.hostView),X.appendChild(ct.location.nativeElement),ct}_attachWindowComponent(w,X,ke){let Jn=w.resolveComponentFactory(q).create(this._injector,ke.nodes);return this._applicationRef.attachView(Jn.hostView),X.appendChild(Jn.location.nativeElement),Jn}_applyWindowOptions(w,X){this._windowAttributes.forEach(ke=>{ba(X[ke])&&(w[ke]=X[ke])})}_applyBackdropOptions(w,X){this._backdropAttributes.forEach(ke=>{ba(X[ke])&&(w[ke]=X[ke])})}_getContentRef(w,X,ke,ct,Jn){return ke?ke instanceof r.Rgc?this._createFromTemplateRef(ke,ct):wo(ke)?this._createFromString(ke):this._createFromComponent(w,X,ke,ct,Jn):new cu([])}_createFromTemplateRef(w,X){const ct=w.createEmbeddedView({$implicit:X,close(Jn){X.close(Jn)},dismiss(Jn){X.dismiss(Jn)}});return this._applicationRef.attachView(ct),new cu([ct.rootNodes],ct)}_createFromString(w){const X=this._document.createTextNode(`${w}`);return new cu([[X]])}_createFromComponent(w,X,ke,ct,Jn){const Ir=w.resolveComponentFactory(ke),vi=r.zs3.create({providers:[{provide:E,useValue:ct}],parent:X}),zi=Ir.create(vi),Do=zi.location.nativeElement;return Jn.scrollable&&Do.classList.add("component-host-scrollable"),this._applicationRef.attachView(zi.hostView),new cu([[Do]],zi.hostView,zi)}_setAriaHidden(w){const X=w.parentElement;X&&w!==this._document.body&&(Array.from(X.children).forEach(ke=>{ke!==w&&"SCRIPT"!==ke.nodeName&&(this._ariaHiddenValues.set(ke,ke.getAttribute("aria-hidden")),ke.setAttribute("aria-hidden","true"))}),this._setAriaHidden(X))}_revertAriaHidden(){this._ariaHiddenValues.forEach((w,X)=>{w?X.setAttribute("aria-hidden",w):X.removeAttribute("aria-hidden")}),this._ariaHiddenValues.clear()}_registerModalRef(w){const X=()=>{const ke=this._modalRefs.indexOf(w);ke>-1&&(this._modalRefs.splice(ke,1),this._activeInstances.emit(this._modalRefs))};this._modalRefs.push(w),this._activeInstances.emit(this._modalRefs),w.result.then(X,X)}_registerWindowCmpt(w){this._windowCmpts.push(w),this._activeWindowCmptHasChanged.next(),w.onDestroy(()=>{const X=this._windowCmpts.indexOf(w);X>-1&&(this._windowCmpts.splice(X,1),this._activeWindowCmptHasChanged.next())})}}return Y.\u0275fac=function(w){return new(w||Y)(r.LFG(r.z2F),r.LFG(r.zs3),r.LFG(u.K0),r.LFG(bu),r.LFG(r.FYo),r.LFG(r.R0b))},Y.\u0275prov=r.Yz7({factory:function(){return new Y(r.LFG(r.z2F),r.LFG(r.gxx),r.LFG(u.K0),r.LFG(bu),r.LFG(r.FYo),r.LFG(r.R0b))},token:Y,providedIn:"root"}),Y})(),ye=(()=>{class Y{constructor(w,X,ke,ct){this._moduleCFR=w,this._injector=X,this._modalStack=ke,this._config=ct}open(w,X={}){const ke=Object.assign(Object.assign(Object.assign({},this._config),{animation:this._config.animation}),X);return this._modalStack.open(this._moduleCFR,this._injector,w,ke)}get activeInstances(){return this._modalStack.activeInstances}dismissAll(w){this._modalStack.dismissAll(w)}hasOpenModals(){return this._modalStack.hasOpenModals()}}return Y.\u0275fac=function(w){return new(w||Y)(r.LFG(r._Vd),r.LFG(r.zs3),r.LFG(de),r.LFG(Hc))},Y.\u0275prov=r.Yz7({factory:function(){return new Y(r.LFG(r._Vd),r.LFG(r.gxx),r.LFG(de),r.LFG(Hc))},token:Y,providedIn:"root"}),Y})(),Oe=(()=>{class Y{constructor(w){this._ngbConfig=w,this.destroyOnHide=!0,this.orientation="horizontal",this.roles="tablist",this.keyboard=!1}get animation(){return void 0===this._animation?this._ngbConfig.animation:this._animation}set animation(w){this._animation=w}}return Y.\u0275fac=function(w){return new(w||Y)(r.LFG(Fs))},Y.\u0275prov=r.Yz7({factory:function(){return new Y(r.LFG(Fs))},token:Y,providedIn:"root"}),Y})();const Xe=Y=>ba(Y)&&""!==Y;let yt=0,nn=(()=>{class Y{constructor(w){this.templateRef=w}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(r.Rgc))},Y.\u0275dir=r.lG2({type:Y,selectors:[["ng-template","ngbNavContent",""]]}),Y})(),Pn=(()=>{class Y{constructor(w,X){this.elementRef=X,this.disabled=!1,this.shown=new r.vpe,this.hidden=new r.vpe,this._nav=w}ngAfterContentChecked(){this.contentTpl=this.contentTpls.first}ngOnInit(){ba(this.domId)||(this.domId="ngb-nav-"+yt++)}get active(){return this._nav.activeId===this.id}get id(){return Xe(this._id)?this._id:this.domId}get panelDomId(){return`${this.domId}-panel`}isPanelInDom(){return(ba(this.destroyOnHide)?!this.destroyOnHide:!this._nav.destroyOnHide)||this.active}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36((0,r.Gpc)(()=>xn)),r.Y36(r.SBq))},Y.\u0275dir=r.lG2({type:Y,selectors:[["","ngbNavItem",""]],contentQueries:function(w,X,ke){if(1&w&&r.Suo(ke,nn,4),2&w){let ct;r.iGM(ct=r.CRH())&&(X.contentTpls=ct)}},hostVars:2,hostBindings:function(w,X){2&w&&r.ekj("nav-item",!0)},inputs:{disabled:"disabled",domId:"domId",destroyOnHide:"destroyOnHide",_id:["ngbNavItem","_id"]},outputs:{shown:"shown",hidden:"hidden"},exportAs:["ngbNavItem"]}),Y})(),xn=(()=>{class Y{constructor(w,X,ke,ct){this.role=w,this._cd=ke,this._document=ct,this.activeIdChange=new r.vpe,this.shown=new r.vpe,this.hidden=new r.vpe,this.destroy$=new he.xQ,this.navItemChange$=new he.xQ,this.navChange=new r.vpe,this.animation=X.animation,this.destroyOnHide=X.destroyOnHide,this.orientation=X.orientation,this.roles=X.roles,this.keyboard=X.keyboard}click(w){w.disabled||this._updateActiveId(w.id)}onKeyDown(w){if("tablist"!==this.roles||!this.keyboard)return;const X=w.which,ke=this.links.filter(Ir=>!Ir.navItem.disabled),{length:ct}=ke;let Jn=-1;if(ke.forEach((Ir,vi)=>{Ir.elRef.nativeElement===this._document.activeElement&&(Jn=vi)}),ct){switch(X){case $i.ArrowLeft:if("vertical"===this.orientation)return;Jn=(Jn-1+ct)%ct;break;case $i.ArrowRight:if("vertical"===this.orientation)return;Jn=(Jn+1)%ct;break;case $i.ArrowDown:if("horizontal"===this.orientation)return;Jn=(Jn+1)%ct;break;case $i.ArrowUp:if("horizontal"===this.orientation)return;Jn=(Jn-1+ct)%ct;break;case $i.Home:Jn=0;break;case $i.End:Jn=ct-1}"changeWithArrows"===this.keyboard&&this.select(ke[Jn].navItem.id),ke[Jn].elRef.nativeElement.focus(),w.preventDefault()}}select(w){this._updateActiveId(w,!1)}ngAfterContentInit(){if(!ba(this.activeId)){const w=this.items.first?this.items.first.id:null;Xe(w)&&(this._updateActiveId(w,!1),this._cd.detectChanges())}this.items.changes.pipe((0,Zt.R)(this.destroy$)).subscribe(()=>this._notifyItemChanged(this.activeId))}ngOnChanges({activeId:w}){w&&!w.firstChange&&this._notifyItemChanged(w.currentValue)}ngOnDestroy(){this.destroy$.next()}_updateActiveId(w,X=!0){if(this.activeId!==w){let ke=!1;X&&this.navChange.emit({activeId:this.activeId,nextId:w,preventDefault:()=>{ke=!0}}),ke||(this.activeId=w,this.activeIdChange.emit(w),this._notifyItemChanged(w))}}_notifyItemChanged(w){this.navItemChange$.next(this._getItemById(w))}_getItemById(w){return this.items&&this.items.find(X=>X.id===w)||null}}return Y.\u0275fac=function(w){return new(w||Y)(r.$8M("role"),r.Y36(Oe),r.Y36(r.sBO),r.Y36(u.K0))},Y.\u0275dir=r.lG2({type:Y,selectors:[["","ngbNav",""]],contentQueries:function(w,X,ke){if(1&w&&(r.Suo(ke,Pn,4),r.Suo(ke,ir,5)),2&w){let ct;r.iGM(ct=r.CRH())&&(X.items=ct),r.iGM(ct=r.CRH())&&(X.links=ct)}},hostVars:6,hostBindings:function(w,X){1&w&&r.NdJ("keydown.arrowLeft",function(ct){return X.onKeyDown(ct)})("keydown.arrowRight",function(ct){return X.onKeyDown(ct)})("keydown.arrowDown",function(ct){return X.onKeyDown(ct)})("keydown.arrowUp",function(ct){return X.onKeyDown(ct)})("keydown.Home",function(ct){return X.onKeyDown(ct)})("keydown.End",function(ct){return X.onKeyDown(ct)}),2&w&&(r.uIk("aria-orientation","vertical"===X.orientation&&"tablist"===X.roles?"vertical":void 0)("role",X.role?X.role:X.roles?"tablist":void 0),r.ekj("nav",!0)("flex-column","vertical"===X.orientation))},inputs:{animation:"animation",destroyOnHide:"destroyOnHide",orientation:"orientation",roles:"roles",keyboard:"keyboard",activeId:"activeId"},outputs:{activeIdChange:"activeIdChange",shown:"shown",hidden:"hidden",navChange:"navChange"},exportAs:["ngbNav"],features:[r.TTD]}),Y})(),ir=(()=>{class Y{constructor(w,X,ke,ct){this.role=w,this.navItem=X,this.nav=ke,this.elRef=ct}hasNavItemClass(){return this.navItem.elementRef.nativeElement.nodeType===Node.COMMENT_NODE}}return Y.\u0275fac=function(w){return new(w||Y)(r.$8M("role"),r.Y36(Pn),r.Y36(xn),r.Y36(r.SBq))},Y.\u0275dir=r.lG2({type:Y,selectors:[["a","ngbNavLink",""]],hostAttrs:["href",""],hostVars:14,hostBindings:function(w,X){1&w&&r.NdJ("click",function(ct){return X.nav.click(X.navItem),ct.preventDefault()}),2&w&&(r.Ikx("id",X.navItem.domId),r.uIk("role",X.role?X.role:X.nav.roles?"tab":void 0)("tabindex",X.navItem.disabled?-1:void 0)("aria-controls",X.navItem.isPanelInDom()?X.navItem.panelDomId:null)("aria-selected",X.navItem.active)("aria-disabled",X.navItem.disabled),r.ekj("nav-link",!0)("nav-item",X.hasNavItemClass())("active",X.navItem.active)("disabled",X.navItem.disabled))}}),Y})();const Gr=({classList:Y})=>(Y.remove("show"),()=>Y.remove("active")),Pi=(Y,fe)=>{fe&&Ec(Y),Y.classList.add("show")};let Zo=(()=>{class Y{constructor(w){this.elRef=w}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(r.SBq))},Y.\u0275dir=r.lG2({type:Y,selectors:[["","ngbNavPane",""]],hostAttrs:[1,"tab-pane"],hostVars:5,hostBindings:function(w,X){2&w&&(r.Ikx("id",X.item.panelDomId),r.uIk("role",X.role?X.role:X.nav.roles?"tabpanel":void 0)("aria-labelledby",X.item.domId),r.ekj("fade",X.nav.animation))},inputs:{item:"item",nav:"nav",role:"role"}}),Y})(),Lo=(()=>{class Y{constructor(w,X){this._cd=w,this._ngZone=X,this._activePane=null}isPanelTransitioning(w){var X;return(null===(X=this._activePane)||void 0===X?void 0:X.item)===w}ngAfterViewInit(){var w;this._updateActivePane(),this.nav.navItemChange$.pipe((0,Zt.R)(this.nav.destroy$),(0,Gt.O)((null===(w=this._activePane)||void 0===w?void 0:w.item)||null),(0,xt.x)(),fe=>fe.lift(new tn(1))).subscribe(X=>{const ke={animation:this.nav.animation,runningTransition:"stop"};this._cd.detectChanges(),this._activePane?Pt(this._ngZone,this._activePane.elRef.nativeElement,Gr,ke).subscribe(()=>{var ct;const Jn=null===(ct=this._activePane)||void 0===ct?void 0:ct.item;this._activePane=this._getPaneForItem(X),this._cd.markForCheck(),this._activePane&&(this._activePane.elRef.nativeElement.classList.add("active"),Pt(this._ngZone,this._activePane.elRef.nativeElement,Pi,ke).subscribe(()=>{X&&(X.shown.emit(),this.nav.shown.emit(X.id))})),Jn&&(Jn.hidden.emit(),this.nav.hidden.emit(Jn.id))}):this._updateActivePane()})}_updateActivePane(){var w,X;this._activePane=this._getActivePane(),null===(w=this._activePane)||void 0===w||w.elRef.nativeElement.classList.add("show"),null===(X=this._activePane)||void 0===X||X.elRef.nativeElement.classList.add("active")}_getPaneForItem(w){return this._panes&&this._panes.find(X=>X.item===w)||null}_getActivePane(){return this._panes&&this._panes.find(w=>w.item.active)||null}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(r.sBO),r.Y36(r.R0b))},Y.\u0275cmp=r.Xpm({type:Y,selectors:[["","ngbNavOutlet",""]],viewQuery:function(w,X){if(1&w&&r.Gf(Zo,5),2&w){let ke;r.iGM(ke=r.CRH())&&(X._panes=ke)}},hostVars:2,hostBindings:function(w,X){2&w&&r.ekj("tab-content",!0)},inputs:{paneRole:"paneRole",nav:["ngbNavOutlet","nav"]},attrs:Co,decls:1,vars:1,consts:[["ngFor","",3,"ngForOf"],["ngbNavPane","",3,"item","nav","role",4,"ngIf"],["ngbNavPane","",3,"item","nav","role"],[3,"ngTemplateOutlet","ngTemplateOutletContext"]],template:function(w,X){1&w&&r.YNc(0,To,1,1,"ng-template",0),2&w&&r.Q6J("ngForOf",X.nav.items)},directives:[u.sg,u.O5,Zo,u.tP],encapsulation:2,changeDetection:0}),Y})(),Xs=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275mod=r.oAB({type:Y}),Y.\u0275inj=r.cJS({imports:[[u.ez]]}),Y})();class gf{constructor(fe,w){this.open=fe,this.close=w,w||(this.close=fe)}isManual(){return"manual"===this.open||"manual"===this.close}}const Ga={hover:["mouseenter","mouseleave"],focus:["focusin","focusout"]},nt=Y=>Y>0?(0,Ur.g)(Y):fe=>fe;function cr(Y,fe,w,X,ke,ct,Jn=0,Ir=0){const vi=function(Y,fe=Ga){const w=(Y||"").trim();if(0===w.length)return[];const X=w.split(/\s+/).map(ct=>ct.split(":")).map(ct=>{let Jn=fe[ct[0]]||ct;return new gf(Jn[0],Jn[1])}),ke=X.filter(ct=>ct.isManual());if(ke.length>1)throw"Triggers parse error: only one manual trigger is allowed";if(1===ke.length&&X.length>1)throw"Triggers parse error: manual trigger can't be mixed with other triggers";return X}(w);if(1===vi.length&&vi[0].isManual())return()=>{};const zi=function(Y,fe,w,X){return new se.y(ke=>{const ct=[],Jn=()=>ke.next(!0),Ir=()=>ke.next(!1),vi=()=>ke.next(!X());return w.forEach(zi=>{zi.open===zi.close?ct.push(Y.listen(fe,zi.open,vi)):ct.push(Y.listen(fe,zi.open,Jn),Y.listen(fe,zi.close,Ir))}),()=>{ct.forEach(zi=>zi())}})}(Y,fe,vi,X).pipe(function(Y,fe,w){return X=>{let ke=null;const ct=X.pipe((0,bt.U)(vi=>({open:vi})),(0,Ut.h)(vi=>{const zi=w();return zi===vi.open||ke&&ke.open!==zi?(ke&&ke.open!==vi.open&&(ke=null),!1):(ke=vi,!0)}),(0,Lr.B)()),Jn=ct.pipe((0,Ut.h)(vi=>vi.open),nt(Y)),Ir=ct.pipe((0,Ut.h)(vi=>!vi.open),nt(fe));return(0,ze.T)(Jn,Ir).pipe((0,Ut.h)(vi=>vi===ke&&(ke=null,vi.open!==w())),(0,bt.U)(vi=>vi.open))}}(Jn,Ir,X)).subscribe(Do=>Do?ke():ct());return()=>zi.unsubscribe()}let bi=(()=>{class Y{constructor(w){this._ngbConfig=w,this.autoClose=!0,this.placement="auto",this.triggers="click",this.disablePopover=!1,this.openDelay=0,this.closeDelay=0}get animation(){return void 0===this._animation?this._ngbConfig.animation:this._animation}set animation(w){this._animation=w}}return Y.\u0275fac=function(w){return new(w||Y)(r.LFG(Fs))},Y.\u0275prov=r.Yz7({factory:function(){return new Y(r.LFG(Fs))},token:Y,providedIn:"root"}),Y})(),cs=0,xa=(()=>{class Y{isTitleTemplate(){return this.title instanceof r.Rgc}}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275cmp=r.Xpm({type:Y,selectors:[["ngb-popover-window"]],hostAttrs:["role","tooltip"],hostVars:5,hostBindings:function(w,X){2&w&&(r.Ikx("id",X.id),r.Tol("popover"+(X.popoverClass?" "+X.popoverClass:"")),r.ekj("fade",X.animation))},inputs:{animation:"animation",title:"title",id:"id",popoverClass:"popoverClass",context:"context"},ngContentSelectors:Hi,decls:4,vars:1,consts:[[1,"arrow"],["class","popover-header",4,"ngIf"],[1,"popover-body"],[1,"popover-header"],["simpleTitle",""],[3,"ngTemplateOutlet","ngTemplateOutletContext"]],template:function(w,X){1&w&&(r.F$t(),r._UZ(0,"div",0),r.YNc(1,el,4,2,"h3",1),r.TgZ(2,"div",2),r.Hsn(3),r.qZA()),2&w&&(r.xp6(1),r.Q6J("ngIf",X.title))},directives:[u.O5,u.tP],styles:["ngb-popover-window.bs-popover-bottom>.arrow,ngb-popover-window.bs-popover-top>.arrow{left:50%;margin-left:-.5rem}ngb-popover-window.bs-popover-bottom-left>.arrow,ngb-popover-window.bs-popover-top-left>.arrow{left:2em}ngb-popover-window.bs-popover-bottom-right>.arrow,ngb-popover-window.bs-popover-top-right>.arrow{left:auto;right:2em}ngb-popover-window.bs-popover-left>.arrow,ngb-popover-window.bs-popover-right>.arrow{top:50%;margin-top:-.5rem}ngb-popover-window.bs-popover-left-top>.arrow,ngb-popover-window.bs-popover-right-top>.arrow{top:.7em}ngb-popover-window.bs-popover-left-bottom>.arrow,ngb-popover-window.bs-popover-right-bottom>.arrow{top:auto;bottom:.7em}"],encapsulation:2,changeDetection:0}),Y})(),na=(()=>{class Y{constructor(w,X,ke,ct,Jn,Ir,vi,zi,Do,xs){this._elementRef=w,this._renderer=X,this._ngZone=vi,this._document=zi,this._changeDetector=Do,this.shown=new r.vpe,this.hidden=new r.vpe,this._ngbPopoverWindowId="ngb-popover-"+cs++,this._windowRef=null,this.animation=Ir.animation,this.autoClose=Ir.autoClose,this.placement=Ir.placement,this.triggers=Ir.triggers,this.container=Ir.container,this.disablePopover=Ir.disablePopover,this.popoverClass=Ir.popoverClass,this.openDelay=Ir.openDelay,this.closeDelay=Ir.closeDelay,this._popupService=new Lu(xa,ke,Jn,X,this._ngZone,ct,xs),this._zoneSubscription=vi.onStable.subscribe(()=>{this._windowRef&&Ye(this._elementRef.nativeElement,this._windowRef.location.nativeElement,this.placement,"body"===this.container,"bs-popover")})}_isDisabled(){return!(!this.disablePopover&&(this.ngbPopover||this.popoverTitle))}open(w){if(!this._windowRef&&!this._isDisabled()){const{windowRef:X,transition$:ke}=this._popupService.open(this.ngbPopover,w,this.animation);this._windowRef=X,this._windowRef.instance.animation=this.animation,this._windowRef.instance.title=this.popoverTitle,this._windowRef.instance.context=w,this._windowRef.instance.popoverClass=this.popoverClass,this._windowRef.instance.id=this._ngbPopoverWindowId,this._renderer.setAttribute(this._elementRef.nativeElement,"aria-describedby",this._ngbPopoverWindowId),"body"===this.container&&this._document.querySelector(this.container).appendChild(this._windowRef.location.nativeElement),this._windowRef.changeDetectorRef.detectChanges(),this._windowRef.changeDetectorRef.markForCheck(),la(this._ngZone,this._document,this.autoClose,()=>this.close(),this.hidden,[this._windowRef.location.nativeElement]),ke.subscribe(()=>this.shown.emit())}}close(){this._windowRef&&(this._renderer.removeAttribute(this._elementRef.nativeElement,"aria-describedby"),this._popupService.close(this.animation).subscribe(()=>{this._windowRef=null,this.hidden.emit(),this._changeDetector.markForCheck()}))}toggle(){this._windowRef?this.close():this.open()}isOpen(){return null!=this._windowRef}ngOnInit(){this._unregisterListenersFn=cr(this._renderer,this._elementRef.nativeElement,this.triggers,this.isOpen.bind(this),this.open.bind(this),this.close.bind(this),+this.openDelay,+this.closeDelay)}ngOnChanges({ngbPopover:w,popoverTitle:X,disablePopover:ke,popoverClass:ct}){ct&&this.isOpen()&&(this._windowRef.instance.popoverClass=ct.currentValue),(w||X||ke)&&this._isDisabled()&&this.close()}ngOnDestroy(){this.close(),this._unregisterListenersFn&&this._unregisterListenersFn(),this._zoneSubscription.unsubscribe()}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(r.SBq),r.Y36(r.Qsj),r.Y36(r.zs3),r.Y36(r._Vd),r.Y36(r.s_b),r.Y36(bi),r.Y36(r.R0b),r.Y36(u.K0),r.Y36(r.sBO),r.Y36(r.z2F))},Y.\u0275dir=r.lG2({type:Y,selectors:[["","ngbPopover",""]],inputs:{animation:"animation",autoClose:"autoClose",placement:"placement",triggers:"triggers",container:"container",disablePopover:"disablePopover",popoverClass:"popoverClass",openDelay:"openDelay",closeDelay:"closeDelay",ngbPopover:"ngbPopover",popoverTitle:"popoverTitle"},outputs:{shown:"shown",hidden:"hidden"},exportAs:["ngbPopover"],features:[r.TTD]}),Y})(),_l=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275mod=r.oAB({type:Y}),Y.\u0275inj=r.cJS({imports:[[u.ez]]}),Y})(),zl=(()=>{class Y{constructor(){this.max=100,this.animated=!1,this.striped=!1,this.showValue=!1}}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275prov=r.Yz7({factory:function(){return new Y},token:Y,providedIn:"root"}),Y})(),zc=(()=>{class Y{constructor(w){this.value=0,this.max=w.max,this.animated=w.animated,this.striped=w.striped,this.textType=w.textType,this.type=w.type,this.showValue=w.showValue,this.height=w.height}set max(w){this._max=!ko(w)||w<=0?100:w}get max(){return this._max}getValue(){return function(Y,fe,w=0){return Math.max(Math.min(Y,fe),w)}(this.value,this.max)}getPercentValue(){return 100*this.getValue()/this.max}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(zl))},Y.\u0275cmp=r.Xpm({type:Y,selectors:[["ngb-progressbar"]],hostAttrs:[1,"progress"],hostVars:2,hostBindings:function(w,X){2&w&&r.Udp("height",X.height)},inputs:{value:"value",max:"max",animated:"animated",striped:"striped",textType:"textType",type:"type",showValue:"showValue",height:"height"},ngContentSelectors:Hi,decls:3,vars:11,consts:function(){let fe;return fe="" + "\ufffd0\ufffd" + "",[["role","progressbar","aria-valuemin","0"],[4,"ngIf"],fe]},template:function(w,X){1&w&&(r.F$t(),r.TgZ(0,"div",0),r.YNc(1,ca,3,3,"span",1),r.Hsn(2),r.qZA()),2&w&&(r.DjV("progress-bar",X.type?" bg-"+X.type:"","",X.textType?" text-"+X.textType:"","\n ",X.animated?" progress-bar-animated":"","",X.striped?" progress-bar-striped":"",""),r.Udp("width",X.getPercentValue(),"%"),r.uIk("aria-valuenow",X.getValue())("aria-valuemax",X.max),r.xp6(1),r.Q6J("ngIf",X.showValue))},directives:[u.O5],pipes:[u.Zx],encapsulation:2,changeDetection:0}),Y})(),qf=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275mod=r.oAB({type:Y}),Y.\u0275inj=r.cJS({imports:[[u.ez]]}),Y})();class mf{constructor(fe,w,X){this.hour=pi(fe),this.minute=pi(w),this.second=pi(X)}changeHour(fe=1){this.updateHour((isNaN(this.hour)?0:this.hour)+fe)}updateHour(fe){this.hour=ko(fe)?(fe<0?24+fe:fe)%24:NaN}changeMinute(fe=1){this.updateMinute((isNaN(this.minute)?0:this.minute)+fe)}updateMinute(fe){ko(fe)?(this.minute=fe%60<0?60+fe%60:fe%60,this.changeHour(Math.floor(fe/60))):this.minute=NaN}changeSecond(fe=1){this.updateSecond((isNaN(this.second)?0:this.second)+fe)}updateSecond(fe){ko(fe)?(this.second=fe<0?60+fe%60:fe%60,this.changeMinute(Math.floor(fe/60))):this.second=NaN}isValid(fe=!0){return ko(this.hour)&&ko(this.minute)&&(!fe||ko(this.second))}toString(){return`${this.hour||0}:${this.minute||0}:${this.second||0}`}}let Uf=(()=>{class Y{constructor(){this.meridian=!1,this.spinners=!0,this.seconds=!1,this.hourStep=1,this.minuteStep=1,this.secondStep=1,this.disabled=!1,this.readonlyInputs=!1,this.size="medium"}}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275prov=r.Yz7({factory:function(){return new Y},token:Y,providedIn:"root"}),Y})();function dd(){return new pp}let Fd=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275prov=r.Yz7({factory:dd,token:Y,providedIn:"root"}),Y})(),pp=(()=>{class Y extends Fd{fromModel(w){return w&&Eo(w.hour)&&Eo(w.minute)?{hour:w.hour,minute:w.minute,second:Eo(w.second)?w.second:null}:null}toModel(w){return w&&Eo(w.hour)&&Eo(w.minute)?{hour:w.hour,minute:w.minute,second:Eo(w.second)?w.second:null}:null}}return Y.\u0275fac=function(){let fe;return function(X){return(fe||(fe=r.n5z(Y)))(X||Y)}}(),Y.\u0275prov=r.Yz7({token:Y,factory:Y.\u0275fac}),Y})(),i_=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275prov=r.Yz7({factory:function(){return function(Y){return new F_(Y)}(r.LFG(r.soG))},token:Y,providedIn:"root"}),Y})(),F_=(()=>{class Y extends i_{constructor(w){super(),this._periods=(0,u.ol)(w,u.x.Standalone,u.Tn.Narrow)}getMorningPeriod(){return this._periods[0]}getAfternoonPeriod(){return this._periods[1]}}return Y.\u0275fac=function(w){return new(w||Y)(r.LFG(r.soG))},Y.\u0275prov=r.Yz7({token:Y,factory:Y.\u0275fac}),Y})();const Bf=/[^0-9]/g;let kd=(()=>{class Y{constructor(w,X,ke,ct){this._config=w,this._ngbTimeAdapter=X,this._cd=ke,this.i18n=ct,this.onChange=Jn=>{},this.onTouched=()=>{},this.meridian=w.meridian,this.spinners=w.spinners,this.seconds=w.seconds,this.hourStep=w.hourStep,this.minuteStep=w.minuteStep,this.secondStep=w.secondStep,this.disabled=w.disabled,this.readonlyInputs=w.readonlyInputs,this.size=w.size}set hourStep(w){this._hourStep=Eo(w)?w:this._config.hourStep}get hourStep(){return this._hourStep}set minuteStep(w){this._minuteStep=Eo(w)?w:this._config.minuteStep}get minuteStep(){return this._minuteStep}set secondStep(w){this._secondStep=Eo(w)?w:this._config.secondStep}get secondStep(){return this._secondStep}writeValue(w){const X=this._ngbTimeAdapter.fromModel(w);this.model=X?new mf(X.hour,X.minute,X.second):new mf,!this.seconds&&(!X||!ko(X.second))&&(this.model.second=0),this._cd.markForCheck()}registerOnChange(w){this.onChange=w}registerOnTouched(w){this.onTouched=w}setDisabledState(w){this.disabled=w}changeHour(w){this.model.changeHour(w),this.propagateModelChange()}changeMinute(w){this.model.changeMinute(w),this.propagateModelChange()}changeSecond(w){this.model.changeSecond(w),this.propagateModelChange()}updateHour(w){const X=this.model.hour>=12,ke=pi(w);this.model.updateHour(this.meridian&&(X&&ke<12||!X&&12===ke)?ke+12:ke),this.propagateModelChange()}updateMinute(w){this.model.updateMinute(pi(w)),this.propagateModelChange()}updateSecond(w){this.model.updateSecond(pi(w)),this.propagateModelChange()}toggleMeridian(){this.meridian&&this.changeHour(12)}formatInput(w){w.value=w.value.replace(Bf,"")}formatHour(w){return ko(w)?sl(this.meridian?w%12==0?12:w%12:w%24):sl(NaN)}formatMinSec(w){return sl(ko(w)?w:NaN)}handleBlur(){this.onTouched()}get isSmallSize(){return"small"===this.size}get isLargeSize(){return"large"===this.size}ngOnChanges(w){w.seconds&&!this.seconds&&this.model&&!ko(this.model.second)&&(this.model.second=0,this.propagateModelChange(!1))}propagateModelChange(w=!0){w&&this.onTouched(),this.model.isValid(this.seconds)?this.onChange(this._ngbTimeAdapter.toModel({hour:this.model.hour,minute:this.model.minute,second:this.model.second})):this.onChange(this._ngbTimeAdapter.toModel(null))}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(Uf),r.Y36(Fd),r.Y36(r.sBO),r.Y36(i_))},Y.\u0275cmp=r.Xpm({type:Y,selectors:[["ngb-timepicker"]],inputs:{meridian:"meridian",spinners:"spinners",seconds:"seconds",hourStep:"hourStep",minuteStep:"minuteStep",secondStep:"secondStep",readonlyInputs:"readonlyInputs",size:"size"},features:[r._Bn([{provide:Mr.JU,useExisting:(0,r.Gpc)(()=>Y),multi:!0}]),r.TTD],decls:16,vars:25,consts:function(){let fe,w,X,ke,ct,Jn,Ir,vi,zi,Do,xs,Xo,Rs,ma;return fe="HH",w="Hours",X="MM",ke="Minutes",ct="Increment hours",Jn="Decrement hours",Ir="Increment minutes",vi="Decrement minutes",zi="SS",Do="Seconds",xs="Increment seconds",Xo="Decrement seconds",Rs="" + "\ufffd0\ufffd" + "",ma="" + "\ufffd0\ufffd" + "",[[3,"disabled"],[1,"ngb-tp"],[1,"ngb-tp-input-container","ngb-tp-hour"],["tabindex","-1","type","button","class","btn btn-link",3,"btn-sm","btn-lg","disabled","click",4,"ngIf"],["type","text","maxlength","2","inputmode","numeric","placeholder",fe,"aria-label",w,1,"ngb-tp-input","form-control",3,"value","readOnly","disabled","change","blur","input","keydown.ArrowUp","keydown.ArrowDown"],[1,"ngb-tp-spacer"],[1,"ngb-tp-input-container","ngb-tp-minute"],["type","text","maxlength","2","inputmode","numeric","placeholder",X,"aria-label",ke,1,"ngb-tp-input","form-control",3,"value","readOnly","disabled","change","blur","input","keydown.ArrowUp","keydown.ArrowDown"],["class","ngb-tp-spacer",4,"ngIf"],["class","ngb-tp-input-container ngb-tp-second",4,"ngIf"],["class","ngb-tp-meridian",4,"ngIf"],["tabindex","-1","type","button",1,"btn","btn-link",3,"disabled","click"],[1,"chevron","ngb-tp-chevron"],[1,"sr-only"],ct,[1,"chevron","ngb-tp-chevron","bottom"],Jn,Ir,vi,[1,"ngb-tp-input-container","ngb-tp-second"],["type","text","maxlength","2","inputmode","numeric","placeholder",zi,"aria-label",Do,1,"ngb-tp-input","form-control",3,"value","readOnly","disabled","change","blur","input","keydown.ArrowUp","keydown.ArrowDown"],xs,Xo,[1,"ngb-tp-meridian"],["type","button",1,"btn","btn-outline-primary",3,"disabled","click"],[4,"ngIf","ngIfElse"],["am",""],Rs,ma]},template:function(w,X){1&w&&(r.TgZ(0,"fieldset",0),r.TgZ(1,"div",1),r.TgZ(2,"div",2),r.YNc(3,fo,4,7,"button",3),r.TgZ(4,"input",4),r.NdJ("change",function(ct){return X.updateHour(ct.target.value)})("blur",function(){return X.handleBlur()})("input",function(ct){return X.formatInput(ct.target)})("keydown.ArrowUp",function(ct){return X.changeHour(X.hourStep),ct.preventDefault()})("keydown.ArrowDown",function(ct){return X.changeHour(-X.hourStep),ct.preventDefault()}),r.qZA(),r.YNc(5,Ya,4,7,"button",3),r.qZA(),r.TgZ(6,"div",5),r._uU(7,":"),r.qZA(),r.TgZ(8,"div",6),r.YNc(9,Ao,4,7,"button",3),r.TgZ(10,"input",7),r.NdJ("change",function(ct){return X.updateMinute(ct.target.value)})("blur",function(){return X.handleBlur()})("input",function(ct){return X.formatInput(ct.target)})("keydown.ArrowUp",function(ct){return X.changeMinute(X.minuteStep),ct.preventDefault()})("keydown.ArrowDown",function(ct){return X.changeMinute(-X.minuteStep),ct.preventDefault()}),r.qZA(),r.YNc(11,fs,4,7,"button",3),r.qZA(),r.YNc(12,Ca,2,0,"div",8),r.YNc(13,Ws,4,9,"div",9),r.YNc(14,Po,1,0,"div",8),r.YNc(15,ps,5,9,"div",10),r.qZA(),r.qZA()),2&w&&(r.ekj("disabled",X.disabled),r.Q6J("disabled",X.disabled),r.xp6(3),r.Q6J("ngIf",X.spinners),r.xp6(1),r.ekj("form-control-sm",X.isSmallSize)("form-control-lg",X.isLargeSize),r.Q6J("value",X.formatHour(null==X.model?null:X.model.hour))("readOnly",X.readonlyInputs)("disabled",X.disabled),r.xp6(1),r.Q6J("ngIf",X.spinners),r.xp6(4),r.Q6J("ngIf",X.spinners),r.xp6(1),r.ekj("form-control-sm",X.isSmallSize)("form-control-lg",X.isLargeSize),r.Q6J("value",X.formatMinSec(null==X.model?null:X.model.minute))("readOnly",X.readonlyInputs)("disabled",X.disabled),r.xp6(1),r.Q6J("ngIf",X.spinners),r.xp6(1),r.Q6J("ngIf",X.seconds),r.xp6(1),r.Q6J("ngIf",X.seconds),r.xp6(1),r.Q6J("ngIf",X.meridian),r.xp6(1),r.Q6J("ngIf",X.meridian))},directives:[u.O5],styles:['ngb-timepicker{font-size:1rem}.ngb-tp{display:flex;align-items:center}.ngb-tp-input-container{width:4em}.ngb-tp-chevron:before{border-style:solid;border-width:.29em .29em 0 0;content:"";display:inline-block;height:.69em;left:.05em;position:relative;top:.15em;transform:rotate(-45deg);vertical-align:middle;width:.69em}.ngb-tp-chevron.bottom:before{top:-.3em;transform:rotate(135deg)}.ngb-tp-input{text-align:center}.ngb-tp-hour,.ngb-tp-meridian,.ngb-tp-minute,.ngb-tp-second{display:flex;flex-direction:column;align-items:center;justify-content:space-around}.ngb-tp-spacer{width:1em;text-align:center}'],encapsulation:2}),Y})(),Yf=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275mod=r.oAB({type:Y}),Y.\u0275inj=r.cJS({imports:[[u.ez]]}),Y})(),rh=(()=>{class Y{constructor(w){this._ngbConfig=w,this.autoClose=!0,this.placement="auto",this.triggers="hover focus",this.disableTooltip=!1,this.openDelay=0,this.closeDelay=0}get animation(){return void 0===this._animation?this._ngbConfig.animation:this._animation}set animation(w){this._animation=w}}return Y.\u0275fac=function(w){return new(w||Y)(r.LFG(Fs))},Y.\u0275prov=r.Yz7({factory:function(){return new Y(r.LFG(Fs))},token:Y,providedIn:"root"}),Y})(),Ed=0,xf=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275cmp=r.Xpm({type:Y,selectors:[["ngb-tooltip-window"]],hostAttrs:["role","tooltip"],hostVars:5,hostBindings:function(w,X){2&w&&(r.Ikx("id",X.id),r.Tol("tooltip"+(X.tooltipClass?" "+X.tooltipClass:"")),r.ekj("fade",X.animation))},inputs:{animation:"animation",id:"id",tooltipClass:"tooltipClass"},ngContentSelectors:Hi,decls:3,vars:0,consts:[[1,"arrow"],[1,"tooltip-inner"]],template:function(w,X){1&w&&(r.F$t(),r._UZ(0,"div",0),r.TgZ(1,"div",1),r.Hsn(2),r.qZA())},styles:["ngb-tooltip-window{pointer-events:none}ngb-tooltip-window .tooltip-inner{pointer-events:auto}ngb-tooltip-window.bs-tooltip-bottom .arrow,ngb-tooltip-window.bs-tooltip-top .arrow{left:calc(50% - .4rem)}ngb-tooltip-window.bs-tooltip-bottom-left .arrow,ngb-tooltip-window.bs-tooltip-top-left .arrow{left:1em}ngb-tooltip-window.bs-tooltip-bottom-right .arrow,ngb-tooltip-window.bs-tooltip-top-right .arrow{left:auto;right:.8rem}ngb-tooltip-window.bs-tooltip-left .arrow,ngb-tooltip-window.bs-tooltip-right .arrow{top:calc(50% - .4rem)}ngb-tooltip-window.bs-tooltip-left-top .arrow,ngb-tooltip-window.bs-tooltip-right-top .arrow{top:.4rem}ngb-tooltip-window.bs-tooltip-left-bottom .arrow,ngb-tooltip-window.bs-tooltip-right-bottom .arrow{top:auto;bottom:.4rem}"],encapsulation:2,changeDetection:0}),Y})(),Ph=(()=>{class Y{constructor(w,X,ke,ct,Jn,Ir,vi,zi,Do,xs){this._elementRef=w,this._renderer=X,this._ngZone=vi,this._document=zi,this._changeDetector=Do,this.shown=new r.vpe,this.hidden=new r.vpe,this._ngbTooltipWindowId="ngb-tooltip-"+Ed++,this._windowRef=null,this.animation=Ir.animation,this.autoClose=Ir.autoClose,this.placement=Ir.placement,this.triggers=Ir.triggers,this.container=Ir.container,this.disableTooltip=Ir.disableTooltip,this.tooltipClass=Ir.tooltipClass,this.openDelay=Ir.openDelay,this.closeDelay=Ir.closeDelay,this._popupService=new Lu(xf,ke,Jn,X,this._ngZone,ct,xs),this._zoneSubscription=vi.onStable.subscribe(()=>{this._windowRef&&Ye(this._elementRef.nativeElement,this._windowRef.location.nativeElement,this.placement,"body"===this.container,"bs-tooltip")})}set ngbTooltip(w){this._ngbTooltip=w,!w&&this._windowRef&&this.close()}get ngbTooltip(){return this._ngbTooltip}open(w){if(!this._windowRef&&this._ngbTooltip&&!this.disableTooltip){const{windowRef:X,transition$:ke}=this._popupService.open(this._ngbTooltip,w,this.animation);this._windowRef=X,this._windowRef.instance.animation=this.animation,this._windowRef.instance.tooltipClass=this.tooltipClass,this._windowRef.instance.id=this._ngbTooltipWindowId,this._renderer.setAttribute(this._elementRef.nativeElement,"aria-describedby",this._ngbTooltipWindowId),"body"===this.container&&this._document.querySelector(this.container).appendChild(this._windowRef.location.nativeElement),this._windowRef.changeDetectorRef.detectChanges(),this._windowRef.changeDetectorRef.markForCheck(),la(this._ngZone,this._document,this.autoClose,()=>this.close(),this.hidden,[this._windowRef.location.nativeElement]),ke.subscribe(()=>this.shown.emit())}}close(){null!=this._windowRef&&(this._renderer.removeAttribute(this._elementRef.nativeElement,"aria-describedby"),this._popupService.close(this.animation).subscribe(()=>{this._windowRef=null,this.hidden.emit(),this._changeDetector.markForCheck()}))}toggle(){this._windowRef?this.close():this.open()}isOpen(){return null!=this._windowRef}ngOnInit(){this._unregisterListenersFn=cr(this._renderer,this._elementRef.nativeElement,this.triggers,this.isOpen.bind(this),this.open.bind(this),this.close.bind(this),+this.openDelay,+this.closeDelay)}ngOnChanges({tooltipClass:w}){w&&this.isOpen()&&(this._windowRef.instance.tooltipClass=w.currentValue)}ngOnDestroy(){this.close(),this._unregisterListenersFn&&this._unregisterListenersFn(),this._zoneSubscription.unsubscribe()}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(r.SBq),r.Y36(r.Qsj),r.Y36(r.zs3),r.Y36(r._Vd),r.Y36(r.s_b),r.Y36(rh),r.Y36(r.R0b),r.Y36(u.K0),r.Y36(r.sBO),r.Y36(r.z2F))},Y.\u0275dir=r.lG2({type:Y,selectors:[["","ngbTooltip",""]],inputs:{animation:"animation",autoClose:"autoClose",placement:"placement",triggers:"triggers",container:"container",disableTooltip:"disableTooltip",tooltipClass:"tooltipClass",openDelay:"openDelay",closeDelay:"closeDelay",ngbTooltip:"ngbTooltip"},outputs:{shown:"shown",hidden:"hidden"},exportAs:["ngbTooltip"],features:[r.TTD]}),Y})(),Bp=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275mod=r.oAB({type:Y}),Y.\u0275inj=r.cJS({}),Y})(),ih=(()=>{class Y{constructor(){this.highlightClass="ngb-highlight",this.accentSensitive=!0}ngOnChanges(w){!this.accentSensitive&&!String.prototype.normalize&&(console.warn("The `accentSensitive` input in `ngb-highlight` cannot be set to `false` in a browser that does not implement the `String.normalize` function. You will have to include a polyfill in your application to use this feature in the current browser."),this.accentSensitive=!0);const X=xi(this.result),ke=Array.isArray(this.term)?this.term:[this.term],ct=zi=>this.accentSensitive?zi:Hl(zi),Jn=ke.map(zi=>function(Y){return Y.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")}(ct(xi(zi)))).filter(zi=>zi),Ir=this.accentSensitive?X:Hl(X),vi=Jn.length?Ir.split(new RegExp(`(${Jn.join("|")})`,"gmi")):[X];if(this.accentSensitive)this.parts=vi;else{let zi=0;this.parts=vi.map(Do=>X.substring(zi,zi+=Do.length))}}}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275cmp=r.Xpm({type:Y,selectors:[["ngb-highlight"]],inputs:{highlightClass:"highlightClass",accentSensitive:"accentSensitive",result:"result",term:"term"},features:[r.TTD],decls:1,vars:1,consts:[["ngFor","",3,"ngForOf"],[3,"class",4,"ngIf","ngIfElse"],["even",""]],template:function(w,X){1&w&&r.YNc(0,ne,3,2,"ng-template",0),2&w&&r.Q6J("ngForOf",X.parts)},directives:[u.sg,u.O5],styles:[".ngb-highlight{font-weight:700}"],encapsulation:2,changeDetection:0}),Y})(),Ih=(()=>{class Y{constructor(){this.activeIdx=0,this.focusFirst=!0,this.formatter=xi,this.selectEvent=new r.vpe,this.activeChangeEvent=new r.vpe}hasActive(){return this.activeIdx>-1&&this.activeIdx<this.results.length}getActive(){return this.results[this.activeIdx]}markActive(w){this.activeIdx=w,this._activeChanged()}next(){this.activeIdx===this.results.length-1?this.activeIdx=this.focusFirst?(this.activeIdx+1)%this.results.length:-1:this.activeIdx++,this._activeChanged()}prev(){this.activeIdx<0?this.activeIdx=this.results.length-1:0===this.activeIdx?this.activeIdx=this.focusFirst?this.results.length-1:-1:this.activeIdx--,this._activeChanged()}resetActive(){this.activeIdx=this.focusFirst?0:-1,this._activeChanged()}select(w){this.selectEvent.emit(w)}ngOnInit(){this.resetActive()}_activeChanged(){this.activeChangeEvent.emit(this.activeIdx>=0?this.id+"-"+this.activeIdx:void 0)}}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275cmp=r.Xpm({type:Y,selectors:[["ngb-typeahead-window"]],hostAttrs:["role","listbox"],hostVars:3,hostBindings:function(w,X){1&w&&r.NdJ("mousedown",function(ct){return ct.preventDefault()}),2&w&&(r.Ikx("id",X.id),r.Tol("dropdown-menu show"+(X.popupClass?" "+X.popupClass:"")))},inputs:{focusFirst:"focusFirst",formatter:"formatter",id:"id",results:"results",term:"term",resultTemplate:"resultTemplate",popupClass:"popupClass"},outputs:{selectEvent:"select",activeChangeEvent:"activeChange"},exportAs:["ngbTypeaheadWindow"],decls:3,vars:1,consts:[["rt",""],["ngFor","",3,"ngForOf"],[3,"result","term"],["type","button","role","option",1,"dropdown-item",3,"id","mouseenter","click"],[3,"ngTemplateOutlet","ngTemplateOutletContext"]],template:function(w,X){1&w&&(r.YNc(0,$e,1,2,"ng-template",null,0,r.W1O),r.YNc(2,ti,2,9,"ng-template",1)),2&w&&(r.xp6(2),r.Q6J("ngForOf",X.results))},directives:[u.sg,ih,u.tP],encapsulation:2}),Y})();const vf=new r.OlP("live announcer delay",{providedIn:"root",factory:function(){return 100}});function $d(Y,fe=!1){let w=Y.body.querySelector("#ngb-live");return null==w&&fe&&(w=Y.createElement("div"),w.setAttribute("id","ngb-live"),w.setAttribute("aria-live","polite"),w.setAttribute("aria-atomic","true"),w.classList.add("sr-only"),Y.body.appendChild(w)),w}let hp=(()=>{class Y{constructor(w,X){this._document=w,this._delay=X}ngOnDestroy(){const w=$d(this._document);w&&w.parentElement.removeChild(w)}say(w){const X=$d(this._document,!0),ke=this._delay;if(null!=X){X.textContent="";const ct=()=>X.textContent=w;null===ke?ct():setTimeout(ct,ke)}}}return Y.\u0275fac=function(w){return new(w||Y)(r.LFG(u.K0),r.LFG(vf))},Y.\u0275prov=r.Yz7({factory:function(){return new Y(r.LFG(u.K0),r.LFG(vf))},token:Y,providedIn:"root"}),Y})(),Zf=(()=>{class Y{constructor(){this.editable=!0,this.focusFirst=!0,this.showHint=!1,this.placement=["bottom-left","bottom-right","top-left","top-right"]}}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275prov=r.Yz7({factory:function(){return new Y},token:Y,providedIn:"root"}),Y})(),qd=0,ac=(()=>{class Y{constructor(w,X,ke,ct,Jn,Ir,vi,zi,Do,xs,Xo,Rs){this._elementRef=w,this._renderer=ke,this._live=zi,this._document=Do,this._ngZone=xs,this._changeDetector=Xo,this._subscription=null,this._closed$=new he.xQ,this._inputValueBackup=null,this._windowRef=null,this.autocomplete="off",this.placement="bottom-left",this.selectItem=new r.vpe,this.activeDescendant=null,this.popupId="ngb-typeahead-"+qd++,this._onTouched=()=>{},this._onChange=ma=>{},this.container=Ir.container,this.editable=Ir.editable,this.focusFirst=Ir.focusFirst,this.showHint=Ir.showHint,this.placement=Ir.placement,this._valueChanges=(0,ge.R)(w.nativeElement,"input").pipe((0,bt.U)(ma=>ma.target.value)),this._resubscribeTypeahead=new ce.X(null),this._popupService=new Lu(Ih,ct,X,ke,this._ngZone,Jn,Rs),this._zoneSubscription=vi.onStable.subscribe(()=>{this.isPopupOpen()&&Ye(this._elementRef.nativeElement,this._windowRef.location.nativeElement,this.placement,"body"===this.container)})}ngOnInit(){this._subscribeToUserInput()}ngOnChanges({ngbTypeahead:w}){w&&!w.firstChange&&(this._unsubscribeFromUserInput(),this._subscribeToUserInput())}ngOnDestroy(){this._closePopup(),this._unsubscribeFromUserInput(),this._zoneSubscription.unsubscribe()}registerOnChange(w){this._onChange=w}registerOnTouched(w){this._onTouched=w}writeValue(w){this._writeInputValue(this._formatItemForInput(w)),this.showHint&&(this._inputValueBackup=w)}setDisabledState(w){this._renderer.setProperty(this._elementRef.nativeElement,"disabled",w)}dismissPopup(){this.isPopupOpen()&&(this._resubscribeTypeahead.next(null),this._closePopup(),this.showHint&&null!==this._inputValueBackup&&this._writeInputValue(this._inputValueBackup),this._changeDetector.markForCheck())}isPopupOpen(){return null!=this._windowRef}handleBlur(){this._resubscribeTypeahead.next(null),this._onTouched()}handleKeyDown(w){if(this.isPopupOpen())switch(w.which){case $i.ArrowDown:w.preventDefault(),this._windowRef.instance.next(),this._showHint();break;case $i.ArrowUp:w.preventDefault(),this._windowRef.instance.prev(),this._showHint();break;case $i.Enter:case $i.Tab:const X=this._windowRef.instance.getActive();ba(X)&&(w.preventDefault(),w.stopPropagation(),this._selectResult(X)),this._closePopup()}}_openPopup(){if(!this.isPopupOpen()){this._inputValueBackup=this._elementRef.nativeElement.value;const{windowRef:w}=this._popupService.open();this._windowRef=w,this._windowRef.instance.id=this.popupId,this._windowRef.instance.selectEvent.subscribe(X=>this._selectResultClosePopup(X)),this._windowRef.instance.activeChangeEvent.subscribe(X=>this.activeDescendant=X),this._windowRef.instance.popupClass=this.popupClass,"body"===this.container&&this._document.querySelector(this.container).appendChild(this._windowRef.location.nativeElement),this._changeDetector.markForCheck(),la(this._ngZone,this._document,"outside",()=>this.dismissPopup(),this._closed$,[this._elementRef.nativeElement,this._windowRef.location.nativeElement])}}_closePopup(){this._popupService.close().subscribe(()=>{this._closed$.next(),this._windowRef=null,this.activeDescendant=null})}_selectResult(w){let X=!1;this.selectItem.emit({item:w,preventDefault:()=>{X=!0}}),this._resubscribeTypeahead.next(null),X||(this.writeValue(w),this._onChange(w))}_selectResultClosePopup(w){this._selectResult(w),this._closePopup()}_showHint(){var w;if(this.showHint&&(null===(w=this._windowRef)||void 0===w?void 0:w.instance.hasActive())&&null!=this._inputValueBackup){const X=this._inputValueBackup.toLowerCase(),ke=this._formatItemForInput(this._windowRef.instance.getActive());X===ke.substr(0,this._inputValueBackup.length).toLowerCase()?(this._writeInputValue(this._inputValueBackup+ke.substr(this._inputValueBackup.length)),this._elementRef.nativeElement.setSelectionRange.apply(this._elementRef.nativeElement,[this._inputValueBackup.length,ke.length])):this._writeInputValue(ke)}}_formatItemForInput(w){return null!=w&&this.inputFormatter?this.inputFormatter(w):xi(w)}_writeInputValue(w){this._renderer.setProperty(this._elementRef.nativeElement,"value",xi(w))}_subscribeToUserInput(){const w=this._valueChanges.pipe((0,Zn.b)(X=>{this._inputValueBackup=this.showHint?X:null,this._onChange(this.editable?X:void 0)}),this.ngbTypeahead?this.ngbTypeahead:()=>(0,ie.of)([]));this._subscription=this._resubscribeTypeahead.pipe((0,Xt.w)(()=>w)).subscribe(X=>{X&&0!==X.length?(this._openPopup(),this._windowRef.instance.focusFirst=this.focusFirst,this._windowRef.instance.results=X,this._windowRef.instance.term=this._elementRef.nativeElement.value,this.resultFormatter&&(this._windowRef.instance.formatter=this.resultFormatter),this.resultTemplate&&(this._windowRef.instance.resultTemplate=this.resultTemplate),this._windowRef.instance.resetActive(),this._windowRef.changeDetectorRef.detectChanges(),this._showHint()):this._closePopup();const ke=X?X.length:0;this._live.say(0===ke?"No results available":`${ke} result${1===ke?"":"s"} available`)})}_unsubscribeFromUserInput(){this._subscription&&this._subscription.unsubscribe(),this._subscription=null}}return Y.\u0275fac=function(w){return new(w||Y)(r.Y36(r.SBq),r.Y36(r.s_b),r.Y36(r.Qsj),r.Y36(r.zs3),r.Y36(r._Vd),r.Y36(Zf),r.Y36(r.R0b),r.Y36(hp),r.Y36(u.K0),r.Y36(r.R0b),r.Y36(r.sBO),r.Y36(r.z2F))},Y.\u0275dir=r.lG2({type:Y,selectors:[["input","ngbTypeahead",""]],hostAttrs:["autocapitalize","off","autocorrect","off","role","combobox","aria-multiline","false"],hostVars:7,hostBindings:function(w,X){1&w&&r.NdJ("blur",function(){return X.handleBlur()})("keydown",function(ct){return X.handleKeyDown(ct)}),2&w&&(r.Ikx("autocomplete",X.autocomplete),r.uIk("aria-autocomplete",X.showHint?"both":"list")("aria-activedescendant",X.activeDescendant)("aria-owns",X.isPopupOpen()?X.popupId:null)("aria-expanded",X.isPopupOpen()),r.ekj("open",X.isPopupOpen()))},inputs:{autocomplete:"autocomplete",placement:"placement",container:"container",editable:"editable",focusFirst:"focusFirst",showHint:"showHint",inputFormatter:"inputFormatter",ngbTypeahead:"ngbTypeahead",resultFormatter:"resultFormatter",resultTemplate:"resultTemplate",popupClass:"popupClass"},outputs:{selectItem:"selectItem"},exportAs:["ngbTypeahead"],features:[r._Bn([{provide:Mr.JU,useExisting:(0,r.Gpc)(()=>Y),multi:!0}]),r.TTD]}),Y})(),oh=(()=>{class Y{}return Y.\u0275fac=function(w){return new(w||Y)},Y.\u0275mod=r.oAB({type:Y}),Y.\u0275inj=r.cJS({imports:[[u.ez]]}),Y})()},84051:(v,T,i)=>{"use strict";i.d(T,{vq:()=>lo,ii:()=>rr,Ke:()=>fo,nE:()=>$s,dX:()=>jo,$7:()=>os,AR:()=>Gi,xD:()=>So,Sr:()=>us,Hg:()=>gr});var r=i(74788),u=i(12057),p=i(79765),d=i(22759),e=i(26215),_=i(46782),y=i(64762);const S=["*"];function A(tt,sn){1&tt&&r._UZ(0,"datatable-progress")}function N(tt,sn){if(1&tt&&r._UZ(0,"datatable-summary-row",9),2&tt){const ne=r.oxw(2);r.Q6J("rowHeight",ne.summaryHeight)("offsetX",ne.offsetX)("innerWidth",ne.innerWidth)("rows",ne.rows)("columns",ne.columns)}}function L(tt,sn){if(1&tt){const ne=r.EpF();r.TgZ(0,"datatable-body-row",13),r.NdJ("treeAction",function(){r.CHM(ne);const Lt=r.oxw().$implicit;return r.oxw(2).onTreeAction(Lt)})("activate",function(Lt){r.CHM(ne);const an=r.oxw().index,ti=r.oxw(2);return r.MAs(2).onActivate(Lt,ti.indexes.first+an)}),r.qZA()}if(2&tt){const ne=r.oxw().$implicit,$e=r.oxw(2),Lt=r.MAs(2);r.Q6J("isSelected",Lt.getRowSelected(ne))("innerWidth",$e.innerWidth)("offsetX",$e.offsetX)("columns",$e.columns)("rowHeight",$e.getRowHeight(ne))("row",ne)("rowIndex",$e.getRowIndex(ne))("expanded",$e.getRowExpanded(ne))("rowClass",$e.rowClass)("displayCheck",$e.displayCheck)("treeStatus",ne&&ne.treeStatus)}}function Z(tt,sn){if(1&tt){const ne=r.EpF();r.TgZ(0,"datatable-body-row",15),r.NdJ("activate",function(Lt){const ti=r.CHM(ne).index;return r.oxw(4),r.MAs(2).onActivate(Lt,ti)}),r.qZA()}if(2&tt){const ne=sn.$implicit,$e=r.oxw(2).$implicit,Lt=r.oxw(2),an=r.MAs(2);r.Q6J("isSelected",an.getRowSelected(ne))("innerWidth",Lt.innerWidth)("offsetX",Lt.offsetX)("columns",Lt.columns)("rowHeight",Lt.getRowHeight(ne))("row",ne)("group",$e.value)("rowIndex",Lt.getRowIndex(ne))("expanded",Lt.getRowExpanded(ne))("rowClass",Lt.rowClass)}}function J(tt,sn){if(1&tt&&r.YNc(0,Z,1,10,"datatable-body-row",14),2&tt){const ne=r.oxw().$implicit,$e=r.oxw(2);r.Q6J("ngForOf",ne.value)("ngForTrackBy",$e.rowTrackingFn)}}function K(tt,sn){if(1&tt){const ne=r.EpF();r.TgZ(0,"datatable-row-wrapper",10),r.NdJ("rowContextmenu",function(Lt){return r.CHM(ne),r.oxw(2).rowContextmenu.emit(Lt)}),r.YNc(1,L,1,11,"datatable-body-row",11),r.YNc(2,J,1,2,"ng-template",null,12,r.W1O),r.qZA()}if(2&tt){const ne=sn.$implicit,$e=sn.index,Lt=r.MAs(3),an=r.oxw(2);r.Q6J("groupedRows",an.groupedRows)("innerWidth",an.innerWidth)("ngStyle",an.getRowsStyles(ne))("rowDetail",an.rowDetail)("groupHeader",an.groupHeader)("offsetX",an.offsetX)("detailRowHeight",an.getDetailRowHeight(ne&&ne[$e],$e))("row",ne)("expanded",an.getRowExpanded(ne))("rowIndex",an.getRowIndex(ne&&ne[$e])),r.xp6(1),r.Q6J("ngIf",!an.groupedRows)("ngIfElse",Lt)}}function ee(tt,sn){if(1&tt&&r._UZ(0,"datatable-summary-row",16),2&tt){const ne=r.oxw(2);r.Q6J("ngStyle",ne.getBottomSummaryRowStyles())("rowHeight",ne.summaryHeight)("offsetX",ne.offsetX)("innerWidth",ne.innerWidth)("rows",ne.rows)("columns",ne.columns)}}function ue(tt,sn){if(1&tt){const ne=r.EpF();r.TgZ(0,"datatable-scroller",5),r.NdJ("scroll",function(Lt){return r.CHM(ne),r.oxw().onBodyScroll(Lt)}),r.YNc(1,N,1,5,"datatable-summary-row",6),r.YNc(2,K,4,12,"datatable-row-wrapper",7),r.YNc(3,ee,1,6,"datatable-summary-row",8),r.qZA()}if(2&tt){const ne=r.oxw();r.Q6J("scrollbarV",ne.scrollbarV)("scrollbarH",ne.scrollbarH)("scrollHeight",ne.scrollHeight)("scrollWidth",null==ne.columnGroupWidths?null:ne.columnGroupWidths.total),r.xp6(1),r.Q6J("ngIf",ne.summaryRow&&"top"===ne.summaryPosition),r.xp6(1),r.Q6J("ngForOf",ne.temp)("ngForTrackBy",ne.rowTrackingFn),r.xp6(1),r.Q6J("ngIf",ne.summaryRow&&"bottom"===ne.summaryPosition)}}function ae(tt,sn){if(1&tt&&r._UZ(0,"div",17),2&tt){const ne=r.oxw();r.Q6J("innerHTML",ne.emptyMessage,r.oJD)}}function H(tt,sn){if(1&tt){const ne=r.EpF();r.TgZ(0,"datatable-header-cell",4),r.NdJ("resize",function(Lt){const ti=r.CHM(ne).$implicit;return r.oxw(2).onColumnResized(Lt,ti)})("longPressStart",function(Lt){return r.CHM(ne),r.oxw(2).onLongPressStart(Lt)})("longPressEnd",function(Lt){return r.CHM(ne),r.oxw(2).onLongPressEnd(Lt)})("sort",function(Lt){return r.CHM(ne),r.oxw(2).onSort(Lt)})("select",function(Lt){return r.CHM(ne),r.oxw(2).select.emit(Lt)})("columnContextmenu",function(Lt){return r.CHM(ne),r.oxw(2).columnContextmenu.emit(Lt)}),r.qZA()}if(2&tt){const ne=sn.$implicit,$e=r.oxw(2);r.Q6J("resizeEnabled",ne.resizeable)("pressModel",ne)("pressEnabled",$e.reorderable&&ne.draggable)("dragX",$e.reorderable&&ne.draggable&&ne.dragging)("dragY",!1)("dragModel",ne)("dragEventTarget",$e.dragEventTarget)("headerHeight",$e.headerHeight)("isTarget",ne.isTarget)("targetMarkerTemplate",$e.targetMarkerTemplate)("targetMarkerContext",ne.targetMarkerContext)("column",ne)("sortType",$e.sortType)("sorts",$e.sorts)("selectionType",$e.selectionType)("sortAscendingIcon",$e.sortAscendingIcon)("sortDescendingIcon",$e.sortDescendingIcon)("sortUnsetIcon",$e.sortUnsetIcon)("allRowsSelected",$e.allRowsSelected)}}function se(tt,sn){if(1&tt&&(r.TgZ(0,"div",2),r.YNc(1,H,1,19,"datatable-header-cell",3),r.qZA()),2&tt){const ne=sn.$implicit,$e=r.oxw();r.Tol("datatable-row-"+ne.type),r.Q6J("ngStyle",$e._styleByGroup[ne.type]),r.xp6(1),r.Q6J("ngForOf",ne.columns)("ngForTrackBy",$e.columnTrackingFn)}}function Ee(tt,sn){if(1&tt){const ne=r.EpF();r.TgZ(0,"datatable-header",4),r.NdJ("sort",function(Lt){return r.CHM(ne),r.oxw().onColumnSort(Lt)})("resize",function(Lt){return r.CHM(ne),r.oxw().onColumnResize(Lt)})("reorder",function(Lt){return r.CHM(ne),r.oxw().onColumnReorder(Lt)})("select",function(Lt){return r.CHM(ne),r.oxw().onHeaderSelect(Lt)})("columnContextmenu",function(Lt){return r.CHM(ne),r.oxw().onColumnContextmenu(Lt)}),r.ALo(1,"async"),r.qZA()}if(2&tt){const ne=r.oxw();r.Q6J("sorts",ne.sorts)("sortType",ne.sortType)("scrollbarH",ne.scrollbarH)("innerWidth",ne._innerWidth)("offsetX",r.lcZ(1,15,ne._offsetX))("dealsWithGroup",void 0!==ne.groupedRows)("columns",ne._internalColumns)("headerHeight",ne.headerHeight)("reorderable",ne.reorderable)("targetMarkerTemplate",ne.targetMarkerTemplate)("sortAscendingIcon",ne.cssClasses.sortAscending)("sortDescendingIcon",ne.cssClasses.sortDescending)("sortUnsetIcon",ne.cssClasses.sortUnset)("allRowsSelected",ne.allRowsSelected)("selectionType",ne.selectionType)}}function ie(tt,sn){if(1&tt){const ne=r.EpF();r.TgZ(0,"datatable-footer",5),r.NdJ("page",function(Lt){return r.CHM(ne),r.oxw().onFooterPage(Lt)}),r.qZA()}if(2&tt){const ne=r.oxw();r.Q6J("rowCount",ne.rowCount)("pageSize",ne.pageSize)("offset",ne.offset)("footerHeight",ne.footerHeight)("footerTemplate",ne.footer)("totalMessage",ne.messages.totalMessage)("pagerLeftArrowIcon",ne.cssClasses.pagerLeftArrow)("pagerRightArrowIcon",ne.cssClasses.pagerRightArrow)("pagerPreviousIcon",ne.cssClasses.pagerPrevious)("selectedCount",ne.selected.length)("selectedMessage",!!ne.selectionType&&ne.messages.selectedMessage)("pagerNextIcon",ne.cssClasses.pagerNext)}}function he(tt,sn){}function ge(tt,sn){if(1&tt&&r.YNc(0,he,0,0,"ng-template",5),2&tt){const ne=r.oxw();r.Q6J("ngTemplateOutlet",ne.targetMarkerTemplate)("ngTemplateOutletContext",ne.targetMarkerContext)}}function De(tt,sn){if(1&tt){const ne=r.EpF();r.TgZ(0,"label",6),r.TgZ(1,"input",7),r.NdJ("change",function(){r.CHM(ne);const Lt=r.oxw();return Lt.select.emit(!Lt.allRowsSelected)}),r.qZA(),r.qZA()}if(2&tt){const ne=r.oxw();r.xp6(1),r.Q6J("checked",ne.allRowsSelected)}}function ce(tt,sn){if(1&tt){const ne=r.EpF();r.TgZ(0,"span",8),r.TgZ(1,"span",9),r.NdJ("click",function(){return r.CHM(ne),r.oxw().onSort()}),r.qZA(),r.qZA()}if(2&tt){const ne=r.oxw();r.xp6(1),r.Q6J("innerHTML",ne.name,r.oJD)}}function lt(tt,sn){}function Ve(tt,sn){if(1&tt&&r.YNc(0,lt,0,0,"ng-template",5),2&tt){const ne=r.oxw();r.Q6J("ngTemplateOutlet",ne.column.headerTemplate)("ngTemplateOutletContext",ne.cellContext)}}function ze(tt,sn){}const Be=function(tt,sn,ne,$e,Lt){return{rowCount:tt,pageSize:sn,selectedCount:ne,curPage:$e,offset:Lt}};function Pe(tt,sn){if(1&tt&&r.YNc(0,ze,0,0,"ng-template",4),2&tt){const ne=r.oxw();r.Q6J("ngTemplateOutlet",ne.footerTemplate.template)("ngTemplateOutletContext",r.qbA(2,Be,ne.rowCount,ne.pageSize,ne.selectedCount,ne.curPage,ne.offset))}}function je(tt,sn){if(1&tt&&(r.TgZ(0,"span"),r._uU(1),r.qZA()),2&tt){const ne=r.oxw(2);r.xp6(1),r.AsE(" ",null==ne.selectedCount?null:ne.selectedCount.toLocaleString()," ",ne.selectedMessage," / ")}}function He(tt,sn){if(1&tt&&(r.TgZ(0,"div",5),r.YNc(1,je,2,2,"span",1),r._uU(2),r.qZA()),2&tt){const ne=r.oxw();r.xp6(1),r.Q6J("ngIf",ne.selectedMessage),r.xp6(1),r.AsE(" ",null==ne.rowCount?null:ne.rowCount.toLocaleString()," ",ne.totalMessage," ")}}function Vt(tt,sn){if(1&tt){const ne=r.EpF();r.TgZ(0,"datatable-pager",6),r.NdJ("change",function(Lt){return r.CHM(ne),r.oxw().page.emit(Lt)}),r.qZA()}if(2&tt){const ne=r.oxw();r.Q6J("pagerLeftArrowIcon",ne.pagerLeftArrowIcon)("pagerRightArrowIcon",ne.pagerRightArrowIcon)("pagerPreviousIcon",ne.pagerPreviousIcon)("pagerNextIcon",ne.pagerNextIcon)("page",ne.curPage)("size",ne.pageSize)("count",ne.rowCount)("hidden",!ne.isVisible)}}const it=function(tt){return{"selected-count":tt}};function tn(tt,sn){if(1&tt){const ne=r.EpF();r.TgZ(0,"li",6),r.TgZ(1,"a",7),r.NdJ("click",function(){const an=r.CHM(ne).$implicit;return r.oxw().selectPage(an.number)}),r._uU(2),r.qZA(),r.qZA()}if(2&tt){const ne=sn.$implicit,$e=r.oxw();r.ekj("active",ne.number===$e.page),r.uIk("aria-label","page "+ne.number),r.xp6(2),r.hij(" ",ne.text," ")}}function It(tt,sn){if(1&tt){const ne=r.EpF();r.TgZ(0,"datatable-body-cell",3),r.NdJ("activate",function(Lt){const ti=r.CHM(ne).index;return r.oxw(2).onActivate(Lt,ti)})("treeAction",function(){return r.CHM(ne),r.oxw(2).onTreeAction()}),r.qZA()}if(2&tt){const ne=sn.$implicit,$e=r.oxw(2);r.Q6J("row",$e.row)("group",$e.group)("expanded",$e.expanded)("isSelected",$e.isSelected)("rowIndex",$e.rowIndex)("column",ne)("rowHeight",$e.rowHeight)("displayCheck",$e.displayCheck)("treeStatus",$e.treeStatus)}}function Zt(tt,sn){if(1&tt&&(r.TgZ(0,"div",1),r.YNc(1,It,1,9,"datatable-body-cell",2),r.qZA()),2&tt){const ne=sn.$implicit,$e=r.oxw();r.Gre("datatable-row-",ne.type," datatable-row-group"),r.Q6J("ngStyle",$e._groupStyles[ne.type]),r.xp6(1),r.Q6J("ngForOf",ne.columns)("ngForTrackBy",$e.columnTrackingFn)}}function Ut(tt,sn){}function Bt(tt,sn){if(1&tt&&r.YNc(0,Ut,0,0,"ng-template",4),2&tt){const ne=r.oxw(2);r.Q6J("ngTemplateOutlet",ne.groupHeader.template)("ngTemplateOutletContext",ne.groupContext)}}function bt(tt,sn){if(1&tt&&(r.TgZ(0,"div",3),r.YNc(1,Bt,1,2,void 0,1),r.qZA()),2&tt){const ne=r.oxw();r.Q6J("ngStyle",ne.getGroupHeaderStyle()),r.xp6(1),r.Q6J("ngIf",ne.groupHeader&&ne.groupHeader.template)}}function Gt(tt,sn){1&tt&&r.Hsn(0,0,["*ngIf","(groupHeader && groupHeader.template && expanded) || !groupHeader || !groupHeader.template"])}function xt(tt,sn){}function Xt(tt,sn){if(1&tt&&r.YNc(0,xt,0,0,"ng-template",4),2&tt){const ne=r.oxw(2);r.Q6J("ngTemplateOutlet",ne.rowDetail.template)("ngTemplateOutletContext",ne.rowContext)}}function Zn(tt,sn){if(1&tt&&(r.TgZ(0,"div",5),r.YNc(1,Xt,1,2,void 0,1),r.qZA()),2&tt){const ne=r.oxw();r.Udp("height",ne.detailRowHeight,"px"),r.xp6(1),r.Q6J("ngIf",ne.rowDetail&&ne.rowDetail.template)}}const Ur=["cellTemplate"];function di(tt,sn){if(1&tt){const ne=r.EpF();r.TgZ(0,"label",4),r.TgZ(1,"input",5),r.NdJ("click",function(Lt){return r.CHM(ne),r.oxw().onCheckboxChange(Lt)}),r.qZA(),r.qZA()}if(2&tt){const ne=r.oxw();r.xp6(1),r.Q6J("checked",ne.isSelected)}}function Lr(tt,sn){1&tt&&r._UZ(0,"i",11)}function Mr(tt,sn){1&tt&&r._UZ(0,"i",12)}function Kr(tt,sn){1&tt&&r._UZ(0,"i",13)}function ei(tt,sn){if(1&tt){const ne=r.EpF();r.TgZ(0,"button",7),r.NdJ("click",function(){return r.CHM(ne),r.oxw(2).onTreeAction()}),r.TgZ(1,"span"),r.YNc(2,Lr,1,0,"i",8),r.YNc(3,Mr,1,0,"i",9),r.YNc(4,Kr,1,0,"i",10),r.qZA(),r.qZA()}if(2&tt){const ne=r.oxw(2);r.Q6J("disabled","disabled"===ne.treeStatus),r.xp6(2),r.Q6J("ngIf","loading"===ne.treeStatus),r.xp6(1),r.Q6J("ngIf","collapsed"===ne.treeStatus),r.xp6(1),r.Q6J("ngIf","expanded"===ne.treeStatus||"disabled"===ne.treeStatus)}}function Nn(tt,sn){}const $n=function(tt){return{cellContext:tt}};function Br(tt,sn){if(1&tt&&r.YNc(0,Nn,0,0,"ng-template",14),2&tt){const ne=r.oxw(2);r.Q6J("ngTemplateOutlet",ne.column.treeToggleTemplate)("ngTemplateOutletContext",r.VKq(2,$n,ne.cellContext))}}function Yr(tt,sn){if(1&tt&&(r.ynx(0),r.YNc(1,ei,5,4,"button",6),r.YNc(2,Br,1,4,void 0,2),r.BQk()),2&tt){const ne=r.oxw();r.xp6(1),r.Q6J("ngIf",!ne.column.treeToggleTemplate),r.xp6(1),r.Q6J("ngIf",ne.column.treeToggleTemplate)}}function fi(tt,sn){if(1&tt&&r._UZ(0,"span",15),2&tt){const ne=r.oxw();r.Q6J("title",ne.sanitizedValue)("innerHTML",ne.value,r.oJD)}}function ki(tt,sn){}function Hi(tt,sn){if(1&tt&&r.YNc(0,ki,0,0,"ng-template",14,16,r.W1O),2&tt){const ne=r.oxw();r.Q6J("ngTemplateOutlet",ne.column.cellTemplate)("ngTemplateOutletContext",ne.cellContext)}}function Zr(tt,sn){if(1&tt&&r._UZ(0,"datatable-body-row",1),2&tt){const ne=r.oxw();r.Q6J("innerWidth",ne.innerWidth)("offsetX",ne.offsetX)("columns",ne._internalColumns)("rowHeight",ne.rowHeight)("row",ne.summaryRow)("rowIndex",-1)}}let Cn=(()=>{class tt{constructor(ne){this.document=ne,this.width=this.getWidth()}getWidth(){const ne=this.document.createElement("div");ne.style.visibility="hidden",ne.style.width="100px",ne.style.msOverflowStyle="scrollbar",this.document.body.appendChild(ne);const $e=ne.offsetWidth;ne.style.overflow="scroll";const Lt=this.document.createElement("div");Lt.style.width="100%",ne.appendChild(Lt);const an=Lt.offsetWidth;return ne.parentNode.removeChild(ne),$e-an}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.LFG(u.K0))},tt.\u0275prov=r.Yz7({token:tt,factory:tt.\u0275fac}),tt})(),Wt=(()=>{class tt{getDimensions(ne){return ne.getBoundingClientRect()}}return tt.\u0275fac=function(ne){return new(ne||tt)},tt.\u0275prov=r.Yz7({token:tt,factory:tt.\u0275fac}),tt})(),zn=(()=>{class tt{constructor(){this.columnInputChanges=new p.xQ}get columnInputChanges$(){return this.columnInputChanges.asObservable()}onInputChange(){this.columnInputChanges.next()}}return tt.\u0275fac=function(ne){return new(ne||tt)},tt.\u0275prov=r.Yz7({token:tt,factory:tt.\u0275fac}),tt})(),rr=(()=>{class tt{constructor(ne){this.template=ne}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.Rgc))},tt.\u0275dir=r.lG2({type:tt,selectors:[["","ngx-datatable-footer-template",""]]}),tt})(),Fr=(()=>{class tt{constructor(ne,$e){this.element=ne,this.zone=$e,this.isVisible=!1,this.visible=new r.vpe}ngOnInit(){this.runCheck()}ngOnDestroy(){clearTimeout(this.timeout)}onVisibilityChange(){this.zone.run(()=>{this.isVisible=!0,this.visible.emit(!0)})}runCheck(){const ne=()=>{const{offsetHeight:$e,offsetWidth:Lt}=this.element.nativeElement;$e&&Lt?(clearTimeout(this.timeout),this.onVisibilityChange()):(clearTimeout(this.timeout),this.zone.runOutsideAngular(()=>{this.timeout=setTimeout(()=>ne(),50)}))};this.timeout=setTimeout(()=>ne())}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.SBq),r.Y36(r.R0b))},tt.\u0275dir=r.lG2({type:tt,selectors:[["","visibilityObserver",""]],hostVars:2,hostBindings:function(ne,$e){2&ne&&r.ekj("visible",$e.isVisible)},outputs:{visible:"visible"}}),tt})(),Gn=(()=>{class tt{constructor(ne){this.dragX=!0,this.dragY=!0,this.dragStart=new r.vpe,this.dragging=new r.vpe,this.dragEnd=new r.vpe,this.isDragging=!1,this.element=ne.nativeElement}ngOnChanges(ne){ne.dragEventTarget&&ne.dragEventTarget.currentValue&&this.dragModel.dragging&&this.onMousedown(ne.dragEventTarget.currentValue)}ngOnDestroy(){this._destroySubscription()}onMouseup(ne){!this.isDragging||(this.isDragging=!1,this.element.classList.remove("dragging"),this.subscription&&(this._destroySubscription(),this.dragEnd.emit({event:ne,element:this.element,model:this.dragModel})))}onMousedown(ne){if(ne.target.classList.contains("draggable")&&(this.dragX||this.dragY)){ne.preventDefault(),this.isDragging=!0;const Lt={x:ne.clientX,y:ne.clientY},an=(0,d.R)(document,"mouseup");this.subscription=an.subscribe(pi=>this.onMouseup(pi));const ti=(0,d.R)(document,"mousemove").pipe((0,_.R)(an)).subscribe(pi=>this.move(pi,Lt));this.subscription.add(ti),this.dragStart.emit({event:ne,element:this.element,model:this.dragModel})}}move(ne,$e){if(!this.isDragging)return;const an=ne.clientY-$e.y;this.dragX&&(this.element.style.left=ne.clientX-$e.x+"px"),this.dragY&&(this.element.style.top=`${an}px`),this.element.classList.add("dragging"),this.dragging.emit({event:ne,element:this.element,model:this.dragModel})}_destroySubscription(){this.subscription&&(this.subscription.unsubscribe(),this.subscription=void 0)}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.SBq))},tt.\u0275dir=r.lG2({type:tt,selectors:[["","draggable",""]],inputs:{dragX:"dragX",dragY:"dragY",dragEventTarget:"dragEventTarget",dragModel:"dragModel"},outputs:{dragStart:"dragStart",dragging:"dragging",dragEnd:"dragEnd"},features:[r.TTD]}),tt})(),Jr=(()=>{class tt{constructor(ne,$e){this.renderer=$e,this.resizeEnabled=!0,this.resize=new r.vpe,this.resizing=!1,this.element=ne.nativeElement}ngAfterViewInit(){const ne=this.renderer;this.resizeHandle=ne.createElement("span"),ne.addClass(this.resizeHandle,this.resizeEnabled?"resize-handle":"resize-handle--not-resizable"),ne.appendChild(this.element,this.resizeHandle)}ngOnDestroy(){this._destroySubscription(),this.renderer.destroyNode?this.renderer.destroyNode(this.resizeHandle):this.resizeHandle&&this.renderer.removeChild(this.renderer.parentNode(this.resizeHandle),this.resizeHandle)}onMouseup(){this.resizing=!1,this.subscription&&!this.subscription.closed&&(this._destroySubscription(),this.resize.emit(this.element.clientWidth))}onMousedown(ne){const $e=ne.target.classList.contains("resize-handle"),Lt=this.element.clientWidth,an=ne.screenX;if($e){ne.stopPropagation(),this.resizing=!0;const ti=(0,d.R)(document,"mouseup");this.subscription=ti.subscribe(xi=>this.onMouseup());const pi=(0,d.R)(document,"mousemove").pipe((0,_.R)(ti)).subscribe(xi=>this.move(xi,Lt,an));this.subscription.add(pi)}}move(ne,$e,Lt){const ti=$e+(ne.screenX-Lt);(!this.minWidth||ti>=this.minWidth)&&(!this.maxWidth||ti<=this.maxWidth)&&(this.element.style.width=`${ti}px`)}_destroySubscription(){this.subscription&&(this.subscription.unsubscribe(),this.subscription=void 0)}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.SBq),r.Y36(r.Qsj))},tt.\u0275dir=r.lG2({type:tt,selectors:[["","resizeable",""]],hostVars:2,hostBindings:function(ne,$e){1&ne&&r.NdJ("mousedown",function(an){return $e.onMousedown(an)}),2&ne&&r.ekj("resizeable",$e.resizeEnabled)},inputs:{resizeEnabled:"resizeEnabled",minWidth:"minWidth",maxWidth:"maxWidth"},outputs:{resize:"resize"}}),tt})(),_i=(()=>{class tt{constructor(ne,$e){this.document=$e,this.reorder=new r.vpe,this.targetChanged=new r.vpe,this.differ=ne.find({}).create()}ngAfterContentInit(){this.updateSubscriptions(),this.draggables.changes.subscribe(this.updateSubscriptions.bind(this))}ngOnDestroy(){this.draggables.forEach(ne=>{ne.dragStart.unsubscribe(),ne.dragging.unsubscribe(),ne.dragEnd.unsubscribe()})}updateSubscriptions(){const ne=this.differ.diff(this.createMapDiffs());if(ne){const $e=({currentValue:an,previousValue:ti})=>{Lt({previousValue:ti}),an&&(an.dragStart.subscribe(this.onDragStart.bind(this)),an.dragging.subscribe(this.onDragging.bind(this)),an.dragEnd.subscribe(this.onDragEnd.bind(this)))},Lt=({previousValue:an})=>{an&&(an.dragStart.unsubscribe(),an.dragging.unsubscribe(),an.dragEnd.unsubscribe())};ne.forEachAddedItem($e),ne.forEachRemovedItem(Lt)}}onDragStart(){this.positions={};let ne=0;for(const $e of this.draggables.toArray()){const Lt=$e.element,an=parseInt(Lt.offsetLeft.toString(),0);this.positions[$e.dragModel.prop]={left:an,right:an+parseInt(Lt.offsetWidth.toString(),0),index:ne++,element:Lt}}}onDragging({model:$e,event:Lt}){const an=this.positions[$e.prop],ti=this.isTarget($e,Lt);ti?this.lastDraggingIndex!==ti.i&&(this.targetChanged.emit({prevIndex:this.lastDraggingIndex,newIndex:ti.i,initialIndex:an.index}),this.lastDraggingIndex=ti.i):this.lastDraggingIndex!==an.index&&(this.targetChanged.emit({prevIndex:this.lastDraggingIndex,initialIndex:an.index}),this.lastDraggingIndex=an.index)}onDragEnd({element:ne,model:$e,event:Lt}){const an=this.positions[$e.prop],ti=this.isTarget($e,Lt);ti&&this.reorder.emit({prevIndex:an.index,newIndex:ti.i,model:$e}),this.lastDraggingIndex=void 0,ne.style.left="auto"}isTarget(ne,$e){let Lt=0;const pi=this.document.elementsFromPoint($e.x||$e.clientX,$e.y||$e.clientY);for(const xi in this.positions){const ts=this.positions[xi];if(ne.prop!==xi&&pi.find(wo=>wo===ts.element))return{pos:ts,i:Lt};Lt++}}createMapDiffs(){return this.draggables.toArray().reduce((ne,$e)=>(ne[$e.dragModel.$$id]=$e,ne),{})}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.aQg),r.Y36(u.K0))},tt.\u0275dir=r.lG2({type:tt,selectors:[["","orderable",""]],contentQueries:function(ne,$e,Lt){if(1&ne&&r.Suo(Lt,Gn,5),2&ne){let an;r.iGM(an=r.CRH())&&($e.draggables=an)}},outputs:{reorder:"reorder",targetChanged:"targetChanged"}}),tt})(),wi=(()=>{class tt{constructor(){this.pressEnabled=!0,this.duration=500,this.longPressStart=new r.vpe,this.longPressing=new r.vpe,this.longPressEnd=new r.vpe,this.mouseX=0,this.mouseY=0}get press(){return this.pressing}get isLongPress(){return this.isLongPressing}onMouseDown(ne){if(1!==ne.which||!this.pressEnabled||ne.target.classList.contains("resize-handle"))return;this.mouseX=ne.clientX,this.mouseY=ne.clientY,this.pressing=!0,this.isLongPressing=!1;const Lt=(0,d.R)(document,"mouseup");this.subscription=Lt.subscribe(an=>this.onMouseup()),this.timeout=setTimeout(()=>{this.isLongPressing=!0,this.longPressStart.emit({event:ne,model:this.pressModel}),this.subscription.add((0,d.R)(document,"mousemove").pipe((0,_.R)(Lt)).subscribe(an=>this.onMouseMove(an))),this.loop(ne)},this.duration),this.loop(ne)}onMouseMove(ne){if(this.pressing&&!this.isLongPressing){const $e=Math.abs(ne.clientX-this.mouseX)>10,Lt=Math.abs(ne.clientY-this.mouseY)>10;($e||Lt)&&this.endPress()}}loop(ne){this.isLongPressing&&(this.timeout=setTimeout(()=>{this.longPressing.emit({event:ne,model:this.pressModel}),this.loop(ne)},50))}endPress(){clearTimeout(this.timeout),this.isLongPressing=!1,this.pressing=!1,this._destroySubscription(),this.longPressEnd.emit({model:this.pressModel})}onMouseup(){this.endPress()}ngOnDestroy(){this._destroySubscription()}_destroySubscription(){this.subscription&&(this.subscription.unsubscribe(),this.subscription=void 0)}}return tt.\u0275fac=function(ne){return new(ne||tt)},tt.\u0275dir=r.lG2({type:tt,selectors:[["","long-press",""]],hostVars:4,hostBindings:function(ne,$e){1&ne&&r.NdJ("mousedown",function(an){return $e.onMouseDown(an)}),2&ne&&r.ekj("press",$e.press)("longpress",$e.isLongPress)},inputs:{pressEnabled:"pressEnabled",duration:"duration",pressModel:"pressModel"},outputs:{longPressStart:"longPressStart",longPressing:"longPressing",longPressEnd:"longPressEnd"}}),tt})(),br=(()=>{class tt{constructor(ne,$e,Lt){this.ngZone=ne,this.renderer=Lt,this.scrollbarV=!1,this.scrollbarH=!1,this.scroll=new r.vpe,this.scrollYPos=0,this.scrollXPos=0,this.prevScrollYPos=0,this.prevScrollXPos=0,this._scrollEventListener=null,this.element=$e.nativeElement}ngOnInit(){if(this.scrollbarV||this.scrollbarH){const ne=this.renderer;this.parentElement=ne.parentNode(ne.parentNode(this.element)),this._scrollEventListener=this.onScrolled.bind(this),this.parentElement.addEventListener("scroll",this._scrollEventListener)}}ngOnDestroy(){this._scrollEventListener&&(this.parentElement.removeEventListener("scroll",this._scrollEventListener),this._scrollEventListener=null)}setOffset(ne){this.parentElement&&(this.parentElement.scrollTop=ne)}onScrolled(ne){const $e=ne.currentTarget;requestAnimationFrame(()=>{this.scrollYPos=$e.scrollTop,this.scrollXPos=$e.scrollLeft,this.updateOffset()})}updateOffset(){let ne;this.scrollYPos<this.prevScrollYPos?ne="down":this.scrollYPos>this.prevScrollYPos&&(ne="up"),this.scroll.emit({direction:ne,scrollYPos:this.scrollYPos,scrollXPos:this.scrollXPos}),this.prevScrollYPos=this.scrollYPos,this.prevScrollXPos=this.scrollXPos}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.R0b),r.Y36(r.SBq),r.Y36(r.Qsj))},tt.\u0275cmp=r.Xpm({type:tt,selectors:[["datatable-scroller"]],hostAttrs:[1,"datatable-scroll"],hostVars:4,hostBindings:function(ne,$e){2&ne&&r.Udp("height",$e.scrollHeight,"px")("width",$e.scrollWidth,"px")},inputs:{scrollbarV:"scrollbarV",scrollbarH:"scrollbarH",scrollHeight:"scrollHeight",scrollWidth:"scrollWidth"},outputs:{scroll:"scroll"},ngContentSelectors:S,decls:1,vars:0,template:function(ne,$e){1&ne&&(r.F$t(),r.Hsn(0))},encapsulation:2,changeDetection:0}),tt})(),Dr=(()=>{class tt{constructor(ne){this.template=ne}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.Rgc))},tt.\u0275dir=r.lG2({type:tt,selectors:[["","ngx-datatable-group-header-template",""]]}),tt})(),gn=(()=>{class tt{constructor(){this.rowHeight=0,this.toggle=new r.vpe}get template(){return this._templateInput||this._templateQuery}toggleExpandGroup(ne){this.toggle.emit({type:"group",value:ne})}expandAllGroups(){this.toggle.emit({type:"all",value:!0})}collapseAllGroups(){this.toggle.emit({type:"all",value:!1})}}return tt.\u0275fac=function(ne){return new(ne||tt)},tt.\u0275dir=r.lG2({type:tt,selectors:[["ngx-datatable-group-header"]],contentQueries:function(ne,$e,Lt){if(1&ne&&r.Suo(Lt,Dr,7,r.Rgc),2&ne){let an;r.iGM(an=r.CRH())&&($e._templateQuery=an.first)}},inputs:{rowHeight:"rowHeight",_templateInput:["template","_templateInput"]},outputs:{toggle:"toggle"}}),tt})();function yn(){return""}function gr(tt){return null==tt?yn:"number"==typeof tt?Jt:-1!==tt.indexOf(".")?mr:Vn}function Jt(tt,sn){if(null==tt)return"";if(!tt||null==sn)return tt;const ne=tt[sn];return null==ne?"":ne}function Vn(tt,sn){if(null==tt)return"";if(!tt||!sn)return tt;const ne=tt[sn];return null==ne?"":ne}function mr(tt,sn){if(null==tt)return"";if(!tt||!sn)return tt;let ne=tt[sn];if(void 0!==ne)return ne;ne=tt;const $e=sn.split(".");if($e.length)for(let Lt=0;Lt<$e.length;Lt++)if(ne=ne[$e[Lt]],null==ne)return"";return ne}function Dn(tt){return tt&&(sn=>gr(tt)(sn,tt))}function Pr(tt,sn,ne){if(sn&&ne){const $e={},Lt=tt.length;let an=null;$e[0]=new Yt;const ti=tt.reduce((xi,ts)=>{const wo=ne(ts);return-1===xi.indexOf(wo)&&xi.push(wo),xi},[]);for(let xi=0;xi<Lt;xi++)$e[ne(tt[xi])]=new Yt(tt[xi]);for(let xi=0;xi<Lt;xi++){an=$e[ne(tt[xi])];let ts=0;const wo=sn(an.row);!!wo&&ti.indexOf(wo)>-1&&(ts=wo),an.parent=$e[ts],an.row.level=an.parent.row.level+1,an.parent.children.push(an)}let pi=[];return $e[0].flatten(function(){pi=[...pi,this.row]},!0),pi}return tt}class Yt{constructor(sn=null){sn||(sn={level:-1,treeStatus:"expanded"}),this.row=sn,this.parent=null,this.children=[]}flatten(sn,ne){if("expanded"===this.row.treeStatus)for(let $e=0,Lt=this.children.length;$e<Lt;$e++){const an=this.children[$e];sn.apply(an,Array.prototype.slice.call(arguments,2)),ne&&an.flatten.apply(an,arguments)}}}function _n(tt){return(tt=(tt=(tt=tt.replace(/[^a-zA-Z0-9 ]/g," ")).replace(/([a-z](?=[A-Z]))/g,"$1 ")).replace(/([^a-zA-Z0-9 ])|^[0-9]+/g,"").trim().toLowerCase()).replace(/([ 0-9]+)([a-zA-Z])/g,function(sn,ne,$e){return ne.trim()+$e.toUpperCase()})}function Ge(tt){return tt.replace(/([A-Z])/g,sn=>` ${sn}`).replace(/^./,sn=>sn.toUpperCase())}function mi(tt){if(!tt)return;let sn=!1;for(const ne of tt)ne.$$id||(ne.$$id=("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)),An(ne.prop)&&ne.name&&(ne.prop=_n(ne.name)),ne.$$valueGetter||(ne.$$valueGetter=gr(ne.prop)),!An(ne.prop)&&An(ne.name)&&(ne.name=Ge(String(ne.prop))),An(ne.prop)&&An(ne.name)&&(ne.name=""),ne.hasOwnProperty("resizeable")||(ne.resizeable=!0),ne.hasOwnProperty("sortable")||(ne.sortable=!0),ne.hasOwnProperty("draggable")||(ne.draggable=!0),ne.hasOwnProperty("canAutoResize")||(ne.canAutoResize=!0),ne.hasOwnProperty("width")||(ne.width=150),ne.hasOwnProperty("isTreeColumn")&&ne.isTreeColumn&&!sn?sn=!0:ne.isTreeColumn=!1}function An(tt){return null==tt}var Wr=(()=>{return(tt=Wr||(Wr={})).standard="standard",tt.flex="flex",tt.force="force",Wr;var tt})(),dr=(()=>{return(tt=dr||(dr={})).single="single",tt.multi="multi",tt.multiClick="multiClick",tt.cell="cell",tt.checkbox="checkbox",dr;var tt})(),Fn=(()=>{return(tt=Fn||(Fn={})).single="single",tt.multi="multi",Fn;var tt})(),ar=(()=>{return(tt=ar||(ar={})).header="header",tt.body="body",ar;var tt})();let Wi=(()=>{class tt{constructor(ne){this.template=ne}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.Rgc))},tt.\u0275dir=r.lG2({type:tt,selectors:[["","ngx-datatable-header-template",""]]}),tt})(),lo=(()=>{class tt{constructor(ne){this.template=ne}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.Rgc))},tt.\u0275dir=r.lG2({type:tt,selectors:[["","ngx-datatable-cell-template",""]]}),tt})(),vo=(()=>{class tt{constructor(ne){this.template=ne}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.Rgc))},tt.\u0275dir=r.lG2({type:tt,selectors:[["","ngx-datatable-tree-toggle",""]]}),tt})(),Co=(()=>{class tt{constructor(ne){this.columnChangesService=ne,this.isFirstChange=!0}get cellTemplate(){return this._cellTemplateInput||this._cellTemplateQuery}get headerTemplate(){return this._headerTemplateInput||this._headerTemplateQuery}get treeToggleTemplate(){return this._treeToggleTemplateInput||this._treeToggleTemplateQuery}ngOnChanges(){this.isFirstChange?this.isFirstChange=!1:this.columnChangesService.onInputChange()}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(zn))},tt.\u0275dir=r.lG2({type:tt,selectors:[["ngx-datatable-column"]],contentQueries:function(ne,$e,Lt){if(1&ne&&(r.Suo(Lt,lo,7,r.Rgc),r.Suo(Lt,Wi,7,r.Rgc),r.Suo(Lt,vo,7,r.Rgc)),2&ne){let an;r.iGM(an=r.CRH())&&($e._cellTemplateQuery=an.first),r.iGM(an=r.CRH())&&($e._headerTemplateQuery=an.first),r.iGM(an=r.CRH())&&($e._treeToggleTemplateQuery=an.first)}},inputs:{name:"name",prop:"prop",frozenLeft:"frozenLeft",frozenRight:"frozenRight",flexGrow:"flexGrow",resizeable:"resizeable",comparator:"comparator",pipe:"pipe",sortable:"sortable",draggable:"draggable",canAutoResize:"canAutoResize",minWidth:"minWidth",width:"width",maxWidth:"maxWidth",checkboxable:"checkboxable",headerCheckboxable:"headerCheckboxable",headerClass:"headerClass",cellClass:"cellClass",isTreeColumn:"isTreeColumn",treeLevelIndent:"treeLevelIndent",summaryFunc:"summaryFunc",summaryTemplate:"summaryTemplate",_cellTemplateInput:["cellTemplate","_cellTemplateInput"],_headerTemplateInput:["headerTemplate","_headerTemplateInput"],_treeToggleTemplateInput:["treeToggleTemplate","_treeToggleTemplateInput"]},features:[r.TTD]}),tt})(),Gi=(()=>{class tt{constructor(ne){this.template=ne}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.Rgc))},tt.\u0275dir=r.lG2({type:tt,selectors:[["","ngx-datatable-row-detail-template",""]]}),tt})(),os=(()=>{class tt{constructor(){this.rowHeight=0,this.toggle=new r.vpe}get template(){return this._templateInput||this._templateQuery}toggleExpandRow(ne){this.toggle.emit({type:"row",value:ne})}expandAllRows(){this.toggle.emit({type:"all",value:!0})}collapseAllRows(){this.toggle.emit({type:"all",value:!1})}}return tt.\u0275fac=function(ne){return new(ne||tt)},tt.\u0275dir=r.lG2({type:tt,selectors:[["ngx-datatable-row-detail"]],contentQueries:function(ne,$e,Lt){if(1&ne&&r.Suo(Lt,Gi,7,r.Rgc),2&ne){let an;r.iGM(an=r.CRH())&&($e._templateQuery=an.first)}},inputs:{rowHeight:"rowHeight",_templateInput:["template","_templateInput"]},outputs:{toggle:"toggle"}}),tt})(),jo=(()=>{class tt{get template(){return this._templateInput||this._templateQuery}}return tt.\u0275fac=function(ne){return new(ne||tt)},tt.\u0275dir=r.lG2({type:tt,selectors:[["ngx-datatable-footer"]],contentQueries:function(ne,$e,Lt){if(1&ne&&r.Suo(Lt,rr,5,r.Rgc),2&ne){let an;r.iGM(an=r.CRH())&&($e._templateQuery=an.first)}},inputs:{footerHeight:"footerHeight",totalMessage:"totalMessage",selectedMessage:"selectedMessage",pagerLeftArrowIcon:"pagerLeftArrowIcon",pagerRightArrowIcon:"pagerRightArrowIcon",pagerPreviousIcon:"pagerPreviousIcon",pagerNextIcon:"pagerNextIcon",_templateInput:["template","_templateInput"]}}),tt})();function To(tt){const sn={left:[],center:[],right:[]};if(tt)for(const ne of tt)ne.frozenLeft?sn.left.push(ne):ne.frozenRight?sn.right.push(ne):sn.center.push(ne);return sn}function Mi(tt,sn){return{left:li(tt.left),center:li(tt.center),right:li(tt.right),total:Math.floor(li(sn))}}function li(tt,sn){let ne=0;if(tt)for(const $e of tt)ne+=parseFloat(sn&&$e[sn]?$e[sn]:$e.width);return ne}function lr(tt){const sn=[],ne=To(tt);return sn.push({type:"left",columns:ne.left}),sn.push({type:"center",columns:ne.center}),sn.push({type:"right",columns:ne.right}),sn}class vr{constructor(){this.treeArray=[]}clearCache(){this.treeArray=[]}initCache(sn){const{rows:ne,rowHeight:$e,detailRowHeight:Lt,externalVirtual:an,rowCount:ti,rowIndexes:pi,rowExpansions:xi}=sn,ts="function"==typeof $e,wo="function"==typeof Lt;if(!ts&&isNaN($e))throw new Error(`Row Height cache initialization failed. Please ensure that 'rowHeight' is a\n valid number or function value: (${$e}) when 'scrollbarV' is enabled.`);if(!wo&&isNaN(Lt))throw new Error(`Row Height cache initialization failed. Please ensure that 'detailRowHeight' is a\n valid number or function value: (${Lt}) when 'scrollbarV' is enabled.`);const ko=an?ti:ne.length;this.treeArray=new Array(ko);for(let Eo=0;Eo<ko;++Eo)this.treeArray[Eo]=0;for(let Eo=0;Eo<ko;++Eo){const ba=ne[Eo];let sl=$e;ts&&(sl=$e(ba));const tc=xi.has(ba);ba&&tc&&(sl+=wo?Lt(ba,pi.get(ba)):Lt),this.update(Eo,sl)}}getRowIndex(sn){return 0===sn?0:this.calcRowIndex(sn)}update(sn,ne){if(!this.treeArray.length)throw new Error(`Update at index ${sn} with value ${ne} failed:\n Row Height cache not initialized.`);const $e=this.treeArray.length;for(sn|=0;sn<$e;)this.treeArray[sn]+=ne,sn|=sn+1}query(sn){if(!this.treeArray.length)throw new Error(`query at index ${sn} failed: Fenwick tree array not initialized.`);let ne=0;for(sn|=0;sn>=0;)ne+=this.treeArray[sn],sn=(sn&sn+1)-1;return ne}queryBetween(sn,ne){return this.query(ne)-this.query(sn-1)}calcRowIndex(sn){if(!this.treeArray.length)return 0;let ne=-1;const $e=this.treeArray.length;for(let an=Math.pow(2,$e.toString(2).length-1);0!==an;an>>=1){const ti=ne+an;ti<$e&&sn>=this.treeArray[ti]&&(sn-=this.treeArray[ti],ne=ti)}return ne+1}}const er={},ri="undefined"!=typeof document?document.createElement("div").style:void 0,Ci=function(){const tt="undefined"!=typeof window?window.getComputedStyle(document.documentElement,""):void 0,sn=void 0!==tt?Array.prototype.slice.call(tt).join("").match(/-(moz|webkit|ms)-/):null,ne=null!==sn?sn[1]:void 0,$e=void 0!==ne?"WebKit|Moz|MS|O".match(new RegExp("("+ne+")","i"))[1]:void 0;return $e?{dom:$e,lowercase:ne,css:`-${ne}-`,js:ne[0].toUpperCase()+ne.substr(1)}:void 0}();function $o(tt){const sn=_n(tt);return er[sn]||(void 0!==Ci&&void 0!==ri[Ci.css+tt]?er[sn]=Ci.css+tt:void 0!==ri[tt]&&(er[sn]=tt)),er[sn]}const tr="undefined"!=typeof window?$o("transform"):void 0,Ar="undefined"!=typeof window?$o("backfaceVisibility"):void 0,Rt="undefined"!=typeof window?!!$o("transform"):void 0,_t="undefined"!=typeof window?!!$o("perspective"):void 0,mt="undefined"!=typeof window?window.navigator.userAgent:"Chrome",jt=/Safari\//.test(mt)&&!/Chrome\//.test(mt);function on(tt,sn,ne){void 0!==tr&&Rt?!jt&&_t?(tt[tr]=`translate3d(${sn}px, ${ne}px, 0)`,tt[Ar]="hidden"):tt[_n(tr)]=`translate(${sn}px, ${ne}px)`:(tt.top=`${ne}px`,tt.left=`${sn}px`)}let si=(()=>{class tt{constructor(ne){this.cd=ne,this.selected=[],this.scroll=new r.vpe,this.page=new r.vpe,this.activate=new r.vpe,this.select=new r.vpe,this.detailToggle=new r.vpe,this.rowContextmenu=new r.vpe(!1),this.treeAction=new r.vpe,this.rowHeightsCache=new vr,this.temp=[],this.offsetY=0,this.indexes={},this.rowIndexes=new WeakMap,this.rowExpansions=[],this.getDetailRowHeight=($e,Lt)=>{if(!this.rowDetail)return 0;const an=this.rowDetail.rowHeight;return"function"==typeof an?an($e,Lt):an},this.rowTrackingFn=($e,Lt)=>{const an=this.getRowIndex(Lt);return this.trackByProp?Lt[this.trackByProp]:an}}set pageSize(ne){this._pageSize=ne,this.recalcLayout()}get pageSize(){return this._pageSize}set rows(ne){this._rows=ne,this.recalcLayout()}get rows(){return this._rows}set columns(ne){this._columns=ne;const $e=To(ne);this.columnGroupWidths=Mi($e,ne)}get columns(){return this._columns}set offset(ne){this._offset=ne,(!this.scrollbarV||this.scrollbarV&&!this.virtualization)&&this.recalcLayout()}get offset(){return this._offset}set rowCount(ne){this._rowCount=ne,this.recalcLayout()}get rowCount(){return this._rowCount}get bodyWidth(){return this.scrollbarH?this.innerWidth+"px":"100%"}set bodyHeight(ne){this._bodyHeight=this.scrollbarV?ne+"px":"auto",this.recalcLayout()}get bodyHeight(){return this._bodyHeight}get selectEnabled(){return!!this.selectionType}get scrollHeight(){if(this.scrollbarV&&this.virtualization&&this.rowCount)return this.rowHeightsCache.query(this.rowCount-1)}ngOnInit(){this.rowDetail&&(this.listener=this.rowDetail.toggle.subscribe(({type:ne,value:$e})=>{"row"===ne&&this.toggleRowExpansion($e),"all"===ne&&this.toggleAllRows($e),this.updateIndexes(),this.updateRows(),this.cd.markForCheck()})),this.groupHeader&&(this.listener=this.groupHeader.toggle.subscribe(({type:ne,value:$e})=>{"group"===ne&&this.toggleRowExpansion($e),"all"===ne&&this.toggleAllRows($e),this.updateIndexes(),this.updateRows(),this.cd.markForCheck()}))}ngOnDestroy(){(this.rowDetail||this.groupHeader)&&this.listener.unsubscribe()}updateOffsetY(ne){this.scroller&&(this.scrollbarV&&this.virtualization&&ne?ne=this.rowHeightsCache.query(this.pageSize*ne-1):this.scrollbarV&&!this.virtualization&&(ne=0),this.scroller.setOffset(ne||0))}onBodyScroll(ne){const $e=ne.scrollYPos,Lt=ne.scrollXPos;(this.offsetY!==$e||this.offsetX!==Lt)&&this.scroll.emit({offsetY:$e,offsetX:Lt}),this.offsetY=$e,this.offsetX=Lt,this.updateIndexes(),this.updatePage(ne.direction),this.updateRows()}updatePage(ne){let $e=this.indexes.first/this.pageSize;"up"===ne?$e=Math.ceil($e):"down"===ne&&($e=Math.floor($e)),void 0!==ne&&!isNaN($e)&&this.page.emit({offset:$e})}updateRows(){const{first:ne,last:$e}=this.indexes;let Lt=ne,an=0;const ti=[];if(this.groupedRows){let pi=3;for(1===this.groupedRows.length&&(pi=this.groupedRows[0].value.length);Lt<$e&&Lt<this.groupedRows.length;){const xi=this.groupedRows[Lt];this.rowIndexes.set(xi,Lt),xi.value&&xi.value.forEach((ts,wo)=>{this.rowIndexes.set(ts,`${Lt}-${wo}`)}),ti[an]=xi,an++,Lt++}}else for(;Lt<$e&&Lt<this.rowCount;){const pi=this.rows[Lt];pi&&(this.rowIndexes.set(pi,Lt),ti[an]=pi),an++,Lt++}this.temp=ti}getRowHeight(ne){return"function"==typeof this.rowHeight?this.rowHeight(ne):this.rowHeight}getGroupHeight(ne){let $e=0;if(ne.value)for(let Lt=0;Lt<ne.value.length;Lt++)$e+=this.getRowAndDetailHeight(ne.value[Lt]);return $e}getRowAndDetailHeight(ne){let $e=this.getRowHeight(ne);return this.getRowExpanded(ne)&&($e+=this.getDetailRowHeight(ne)),$e}getRowsStyles(ne){const $e={};if(this.groupedRows&&($e.width=this.columnGroupWidths.total),this.scrollbarV&&this.virtualization){let Lt=0;if(this.groupedRows){const ti=ne[ne.length-1];Lt=ti?this.getRowIndex(ti):0}else Lt=this.getRowIndex(ne);on($e,0,this.rowHeightsCache.query(Lt-1))}return $e}getBottomSummaryRowStyles(){if(!this.scrollbarV||!this.rows||!this.rows.length)return null;const ne={position:"absolute"};return on(ne,0,this.rowHeightsCache.query(this.rows.length-1)),ne}hideIndicator(){setTimeout(()=>this.loadingIndicator=!1,500)}updateIndexes(){let ne=0,$e=0;if(this.scrollbarV)if(this.virtualization){const Lt=parseInt(this.bodyHeight,0);ne=this.rowHeightsCache.getRowIndex(this.offsetY),$e=this.rowHeightsCache.getRowIndex(Lt+this.offsetY)+1}else ne=0,$e=this.rowCount;else this.externalPaging||(ne=Math.max(this.offset*this.pageSize,0)),$e=Math.min(ne+this.pageSize,this.rowCount);this.indexes={first:ne,last:$e}}refreshRowHeightCache(){if(this.scrollbarV&&(!this.scrollbarV||this.virtualization)&&(this.rowHeightsCache.clearCache(),this.rows&&this.rows.length)){const ne=new Set;for(const $e of this.rows)this.getRowExpanded($e)&&ne.add($e);this.rowHeightsCache.initCache({rows:this.rows,rowHeight:this.rowHeight,detailRowHeight:this.getDetailRowHeight,externalVirtual:this.scrollbarV&&this.externalPaging,rowCount:this.rowCount,rowIndexes:this.rowIndexes,rowExpansions:ne})}}getAdjustedViewPortIndex(){const ne=this.indexes.first;return this.scrollbarV&&this.virtualization&&this.rowHeightsCache.query(ne-1)<=this.offsetY?ne-1:ne}toggleRowExpansion(ne){const $e=this.getAdjustedViewPortIndex(),Lt=this.getRowExpandedIdx(ne,this.rowExpansions),an=Lt>-1;if(this.scrollbarV&&this.virtualization){const ti=this.getDetailRowHeight(ne)*(an?-1:1),pi=this.getRowIndex(ne);this.rowHeightsCache.update(pi,ti)}an?this.rowExpansions.splice(Lt,1):this.rowExpansions.push(ne),this.detailToggle.emit({rows:[ne],currentIndex:$e})}toggleAllRows(ne){this.rowExpansions=[];const $e=this.getAdjustedViewPortIndex();if(ne)for(const Lt of this.rows)this.rowExpansions.push(Lt);this.scrollbarV&&this.recalcLayout(),this.detailToggle.emit({rows:this.rows,currentIndex:$e})}recalcLayout(){this.refreshRowHeightCache(),this.updateIndexes(),this.updateRows()}columnTrackingFn(ne,$e){return $e.$$id}stylesByGroup(ne){const $e=this.columnGroupWidths,Lt=this.offsetX,an={width:`${$e[ne]}px`};if("left"===ne)on(an,Lt,0);else if("right"===ne){const ti=parseInt(this.innerWidth+"",0);on(an,-1*($e.total-ti-Lt),0)}return an}getRowExpanded(ne){if(0===this.rowExpansions.length&&this.groupExpansionDefault)for(const $e of this.groupedRows)this.rowExpansions.push($e);return this.getRowExpandedIdx(ne,this.rowExpansions)>-1}getRowExpandedIdx(ne,$e){if(!$e||!$e.length)return-1;const Lt=this.rowIdentity(ne);return $e.findIndex(an=>this.rowIdentity(an)===Lt)}getRowIndex(ne){return this.rowIndexes.get(ne)||0}onTreeAction(ne){this.treeAction.emit({row:ne})}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.sBO))},tt.\u0275cmp=r.Xpm({type:tt,selectors:[["datatable-body"]],viewQuery:function(ne,$e){if(1&ne&&r.Gf(br,5),2&ne){let Lt;r.iGM(Lt=r.CRH())&&($e.scroller=Lt.first)}},hostAttrs:[1,"datatable-body"],hostVars:4,hostBindings:function(ne,$e){2&ne&&r.Udp("width",$e.bodyWidth)("height",$e.bodyHeight)},inputs:{selected:"selected",pageSize:"pageSize",rows:"rows",columns:"columns",offset:"offset",rowCount:"rowCount",bodyHeight:"bodyHeight",offsetX:"offsetX",loadingIndicator:"loadingIndicator",scrollbarV:"scrollbarV",scrollbarH:"scrollbarH",externalPaging:"externalPaging",rowHeight:"rowHeight",emptyMessage:"emptyMessage",selectionType:"selectionType",rowIdentity:"rowIdentity",rowDetail:"rowDetail",groupHeader:"groupHeader",selectCheck:"selectCheck",displayCheck:"displayCheck",trackByProp:"trackByProp",rowClass:"rowClass",groupedRows:"groupedRows",groupExpansionDefault:"groupExpansionDefault",innerWidth:"innerWidth",groupRowsBy:"groupRowsBy",virtualization:"virtualization",summaryRow:"summaryRow",summaryPosition:"summaryPosition",summaryHeight:"summaryHeight"},outputs:{scroll:"scroll",page:"page",activate:"activate",select:"select",detailToggle:"detailToggle",rowContextmenu:"rowContextmenu",treeAction:"treeAction"},decls:5,vars:9,consts:[[4,"ngIf"],[3,"selected","rows","selectCheck","selectEnabled","selectionType","rowIdentity","select","activate"],["selector",""],[3,"scrollbarV","scrollbarH","scrollHeight","scrollWidth","scroll",4,"ngIf"],["class","empty-row",3,"innerHTML",4,"ngIf"],[3,"scrollbarV","scrollbarH","scrollHeight","scrollWidth","scroll"],[3,"rowHeight","offsetX","innerWidth","rows","columns",4,"ngIf"],[3,"groupedRows","innerWidth","ngStyle","rowDetail","groupHeader","offsetX","detailRowHeight","row","expanded","rowIndex","rowContextmenu",4,"ngFor","ngForOf","ngForTrackBy"],[3,"ngStyle","rowHeight","offsetX","innerWidth","rows","columns",4,"ngIf"],[3,"rowHeight","offsetX","innerWidth","rows","columns"],[3,"groupedRows","innerWidth","ngStyle","rowDetail","groupHeader","offsetX","detailRowHeight","row","expanded","rowIndex","rowContextmenu"],["tabindex","-1",3,"isSelected","innerWidth","offsetX","columns","rowHeight","row","rowIndex","expanded","rowClass","displayCheck","treeStatus","treeAction","activate",4,"ngIf","ngIfElse"],["groupedRowsTemplate",""],["tabindex","-1",3,"isSelected","innerWidth","offsetX","columns","rowHeight","row","rowIndex","expanded","rowClass","displayCheck","treeStatus","treeAction","activate"],["tabindex","-1",3,"isSelected","innerWidth","offsetX","columns","rowHeight","row","group","rowIndex","expanded","rowClass","activate",4,"ngFor","ngForOf","ngForTrackBy"],["tabindex","-1",3,"isSelected","innerWidth","offsetX","columns","rowHeight","row","group","rowIndex","expanded","rowClass","activate"],[3,"ngStyle","rowHeight","offsetX","innerWidth","rows","columns"],[1,"empty-row",3,"innerHTML"]],template:function(ne,$e){1&ne&&(r.YNc(0,A,1,0,"datatable-progress",0),r.TgZ(1,"datatable-selection",1,2),r.NdJ("select",function(an){return $e.select.emit(an)})("activate",function(an){return $e.activate.emit(an)}),r.YNc(3,ue,4,8,"datatable-scroller",3),r.YNc(4,ae,1,1,"div",4),r.qZA()),2&ne&&(r.Q6J("ngIf",$e.loadingIndicator),r.xp6(1),r.Q6J("selected",$e.selected)("rows",$e.rows)("selectCheck",$e.selectCheck)("selectEnabled",$e.selectEnabled)("selectionType",$e.selectionType)("rowIdentity",$e.rowIdentity),r.xp6(2),r.Q6J("ngIf",null==$e.rows?null:$e.rows.length),r.xp6(1),r.Q6J("ngIf",!(null!=$e.rows&&$e.rows.length||$e.loadingIndicator)))},directives:function(){return[u.O5,Po,Ya,br,u.sg,ps,Ca,u.PC,fs]},encapsulation:2,changeDetection:0}),tt})(),Vi=(()=>{class tt{constructor(ne){this.cd=ne,this.sort=new r.vpe,this.reorder=new r.vpe,this.resize=new r.vpe,this.select=new r.vpe,this.columnContextmenu=new r.vpe(!1),this._columnGroupWidths={total:100},this._styleByGroup={left:{},center:{},right:{}},this.destroyed=!1}set innerWidth(ne){this._innerWidth=ne,setTimeout(()=>{if(this._columns){const $e=To(this._columns);this._columnGroupWidths=Mi($e,this._columns),this.setStylesByGroup()}})}get innerWidth(){return this._innerWidth}set headerHeight(ne){this._headerHeight="auto"!==ne?`${ne}px`:ne}get headerHeight(){return this._headerHeight}set columns(ne){this._columns=ne;const $e=To(ne);this._columnsByPin=lr(ne),setTimeout(()=>{this._columnGroupWidths=Mi($e,ne),this.setStylesByGroup()})}get columns(){return this._columns}set offsetX(ne){this._offsetX=ne,this.setStylesByGroup()}get offsetX(){return this._offsetX}ngOnDestroy(){this.destroyed=!0}onLongPressStart({event:ne,model:$e}){$e.dragging=!0,this.dragEventTarget=ne}onLongPressEnd({event:ne,model:$e}){this.dragEventTarget=ne,setTimeout(()=>{const Lt=this._columns.find(an=>an.$$id===$e.$$id);Lt&&(Lt.dragging=!1)},5)}get headerWidth(){return this.scrollbarH?this.innerWidth+"px":"100%"}trackByGroups(ne,$e){return $e.type}columnTrackingFn(ne,$e){return $e.$$id}onColumnResized(ne,$e){ne<=$e.minWidth?ne=$e.minWidth:ne>=$e.maxWidth&&(ne=$e.maxWidth),this.resize.emit({column:$e,prevValue:$e.width,newValue:ne})}onColumnReordered({prevIndex:ne,newIndex:$e,model:Lt}){const an=this.getColumn($e);an.isTarget=!1,an.targetMarkerContext=void 0,this.reorder.emit({column:Lt,prevValue:ne,newValue:$e})}onTargetChanged({prevIndex:ne,newIndex:$e,initialIndex:Lt}){if(ne||0===ne){const an=this.getColumn(ne);an.isTarget=!1,an.targetMarkerContext=void 0}if($e||0===$e){const an=this.getColumn($e);an.isTarget=!0,Lt!==$e&&(an.targetMarkerContext={class:"targetMarker ".concat(Lt>$e?"dragFromRight":"dragFromLeft")})}}getColumn(ne){const $e=this._columnsByPin[0].columns.length;if(ne<$e)return this._columnsByPin[0].columns[ne];const Lt=this._columnsByPin[1].columns.length;return ne<$e+Lt?this._columnsByPin[1].columns[ne-$e]:this._columnsByPin[2].columns[ne-$e-Lt]}onSort({column:ne,prevValue:$e,newValue:Lt}){if(ne.dragging)return;const an=this.calcNewSorts(ne,$e,Lt);this.sort.emit({sorts:an,column:ne,prevValue:$e,newValue:Lt})}calcNewSorts(ne,$e,Lt){let an=0;this.sorts||(this.sorts=[]);const ti=this.sorts.map((pi,xi)=>((pi=Object.assign({},pi)).prop===ne.prop&&(an=xi),pi));return void 0===Lt?ti.splice(an,1):$e?ti[an].dir=Lt:(this.sortType===Fn.single&&ti.splice(0,this.sorts.length),ti.push({dir:Lt,prop:ne.prop})),ti}setStylesByGroup(){this._styleByGroup.left=this.calcStylesByGroup("left"),this._styleByGroup.center=this.calcStylesByGroup("center"),this._styleByGroup.right=this.calcStylesByGroup("right"),this.destroyed||this.cd.detectChanges()}calcStylesByGroup(ne){const $e=this._columnGroupWidths,an={width:`${$e[ne]}px`};return"center"===ne?on(an,-1*this.offsetX,0):"right"===ne&&on(an,-1*($e.total-this.innerWidth),0),an}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.sBO))},tt.\u0275cmp=r.Xpm({type:tt,selectors:[["datatable-header"]],hostAttrs:[1,"datatable-header"],hostVars:4,hostBindings:function(ne,$e){2&ne&&r.Udp("height",$e.headerHeight)("width",$e.headerWidth)},inputs:{innerWidth:"innerWidth",headerHeight:"headerHeight",columns:"columns",offsetX:"offsetX",sorts:"sorts",sortAscendingIcon:"sortAscendingIcon",sortDescendingIcon:"sortDescendingIcon",sortUnsetIcon:"sortUnsetIcon",scrollbarH:"scrollbarH",dealsWithGroup:"dealsWithGroup",targetMarkerTemplate:"targetMarkerTemplate",sortType:"sortType",allRowsSelected:"allRowsSelected",selectionType:"selectionType",reorderable:"reorderable"},outputs:{sort:"sort",reorder:"reorder",resize:"resize",select:"select",columnContextmenu:"columnContextmenu"},decls:2,vars:4,consts:[["orderable","",1,"datatable-header-inner",3,"reorder","targetChanged"],[3,"class","ngStyle",4,"ngFor","ngForOf","ngForTrackBy"],[3,"ngStyle"],["resizeable","","long-press","","draggable","",3,"resizeEnabled","pressModel","pressEnabled","dragX","dragY","dragModel","dragEventTarget","headerHeight","isTarget","targetMarkerTemplate","targetMarkerContext","column","sortType","sorts","selectionType","sortAscendingIcon","sortDescendingIcon","sortUnsetIcon","allRowsSelected","resize","longPressStart","longPressEnd","sort","select","columnContextmenu",4,"ngFor","ngForOf","ngForTrackBy"],["resizeable","","long-press","","draggable","",3,"resizeEnabled","pressModel","pressEnabled","dragX","dragY","dragModel","dragEventTarget","headerHeight","isTarget","targetMarkerTemplate","targetMarkerContext","column","sortType","sorts","selectionType","sortAscendingIcon","sortDescendingIcon","sortUnsetIcon","allRowsSelected","resize","longPressStart","longPressEnd","sort","select","columnContextmenu"]],template:function(ne,$e){1&ne&&(r.TgZ(0,"div",0),r.NdJ("reorder",function(an){return $e.onColumnReordered(an)})("targetChanged",function(an){return $e.onTargetChanged(an)}),r.YNc(1,se,2,5,"div",1),r.qZA()),2&ne&&(r.Udp("width",$e._columnGroupWidths.total,"px"),r.xp6(1),r.Q6J("ngForOf",$e._columnsByPin)("ngForTrackBy",$e.trackByGroups))},directives:function(){return[_i,u.sg,u.PC,da,Jr,wi,Gn]},encapsulation:2,changeDetection:0}),tt})();function _o(tt,sn,ne){ne=ne||{};let $e,Lt,an,ti=null,pi=0;function xi(){pi=!1===ne.leading?0:+new Date,ti=null,an=tt.apply($e,Lt)}return function(){const ts=+new Date;!pi&&!1===ne.leading&&(pi=ts);const wo=sn-(ts-pi);return $e=this,Lt=arguments,wo<=0?(clearTimeout(ti),ti=null,pi=ts,an=tt.apply($e,Lt)):!ti&&!1!==ne.trailing&&(ti=setTimeout(xi,wo)),an}}function co(tt,sn){return function($e,Lt,an){return{configurable:!0,enumerable:an.enumerable,get:function(){return Object.defineProperty(this,Lt,{configurable:!0,enumerable:an.enumerable,value:_o(an.value,tt,sn)}),this[Lt]}}}}function ta(tt,sn){for(const ne of sn){const $e=tt.indexOf(ne);tt.splice($e,1)}}function Is(tt,sn=300){let ne=0;for(const $e of tt)ne+=$e.width||sn;return ne}var us=(()=>{return(tt=us||(us={})).asc="asc",tt.desc="desc",us;var tt})();function el(tt,sn){if(null==tt&&(tt=0),null==sn&&(sn=0),tt instanceof Date&&sn instanceof Date){if(tt<sn)return-1;if(tt>sn)return 1}else if(isNaN(parseFloat(tt))||!isFinite(tt)||isNaN(parseFloat(sn))||!isFinite(sn)){if(tt=String(tt),sn=String(sn),tt.toLowerCase()<sn.toLowerCase())return-1;if(tt.toLowerCase()>sn.toLowerCase())return 1}else{if(parseFloat(tt)<parseFloat(sn))return-1;if(parseFloat(tt)>parseFloat(sn))return 1}return 0}let $s=(()=>{class tt{constructor(ne,$e,Lt,an,ti,pi,xi){this.scrollbarHelper=ne,this.dimensionsHelper=$e,this.cd=Lt,this.columnChangesService=pi,this.configuration=xi,this.selected=[],this.scrollbarV=!1,this.scrollbarH=!1,this.rowHeight=30,this.columnMode=Wr.standard,this.headerHeight=30,this.footerHeight=0,this.externalPaging=!1,this.externalSorting=!1,this.loadingIndicator=!1,this.reorderable=!0,this.swapColumns=!0,this.sortType=Fn.single,this.sorts=[],this.cssClasses={sortAscending:"datatable-icon-up",sortDescending:"datatable-icon-down",sortUnset:"datatable-icon-sort-unset",pagerLeftArrow:"datatable-icon-left",pagerRightArrow:"datatable-icon-right",pagerPrevious:"datatable-icon-prev",pagerNext:"datatable-icon-skip"},this.messages={emptyMessage:"No data to display",totalMessage:"total",selectedMessage:"selected"},this.groupExpansionDefault=!1,this.selectAllRowsOnPage=!1,this.virtualization=!0,this.summaryRow=!1,this.summaryHeight=30,this.summaryPosition="top",this.scroll=new r.vpe,this.activate=new r.vpe,this.select=new r.vpe,this.sort=new r.vpe,this.page=new r.vpe,this.reorder=new r.vpe,this.resize=new r.vpe,this.tableContextmenu=new r.vpe(!1),this.treeAction=new r.vpe,this.rowCount=0,this._offsetX=new e.X(0),this._count=0,this._offset=0,this._subscriptions=[],this.rowIdentity=ts=>this._groupRowsBy?ts.key:ts,this.element=an.nativeElement,this.rowDiffer=ti.find({}).create(),this.configuration&&this.configuration.messages&&(this.messages=Object.assign({},this.configuration.messages))}set rows(ne){this._rows=ne,ne&&(this._internalRows=[...ne]),this.externalSorting||this.sortInternalRows(),this._internalRows=Pr(this._internalRows,Dn(this.treeFromRelation),Dn(this.treeToRelation)),this.recalculate(),this._rows&&this._groupRowsBy&&(this.groupedRows=this.groupArrayBy(this._rows,this._groupRowsBy)),this.cd.markForCheck()}get rows(){return this._rows}set groupRowsBy(ne){ne&&(this._groupRowsBy=ne,this._rows&&this._groupRowsBy&&(this.groupedRows=this.groupArrayBy(this._rows,this._groupRowsBy)))}get groupRowsBy(){return this._groupRowsBy}set columns(ne){ne&&(this._internalColumns=[...ne],mi(this._internalColumns),this.recalculateColumns()),this._columns=ne}get columns(){return this._columns}set limit(ne){this._limit=ne,this.recalculate()}get limit(){return this._limit}set count(ne){this._count=ne,this.recalculate()}get count(){return this._count}set offset(ne){this._offset=ne}get offset(){return Math.max(Math.min(this._offset,Math.ceil(this.rowCount/this.pageSize)-1),0)}get isFixedHeader(){const ne=this.headerHeight;return"string"!=typeof ne||"auto"!==ne}get isFixedRow(){return"auto"!==this.rowHeight}get isVertScroll(){return this.scrollbarV}get isVirtualized(){return this.virtualization}get isHorScroll(){return this.scrollbarH}get isSelectable(){return void 0!==this.selectionType}get isCheckboxSelection(){return this.selectionType===dr.checkbox}get isCellSelection(){return this.selectionType===dr.cell}get isSingleSelection(){return this.selectionType===dr.single}get isMultiSelection(){return this.selectionType===dr.multi}get isMultiClickSelection(){return this.selectionType===dr.multiClick}set columnTemplates(ne){this._columnTemplates=ne,this.translateColumns(ne)}get columnTemplates(){return this._columnTemplates}get allRowsSelected(){let ne=this.rows&&this.selected&&this.selected.length===this.rows.length;if(this.bodyComponent&&this.selectAllRowsOnPage){const $e=this.bodyComponent.indexes;ne=this.selected.length===$e.last-$e.first}return this.selected&&this.rows&&0!==this.rows.length&&ne}ngOnInit(){this.recalculate()}ngAfterViewInit(){this.externalSorting||this.sortInternalRows(),"undefined"!=typeof requestAnimationFrame&&requestAnimationFrame(()=>{this.recalculate(),this.externalPaging&&this.scrollbarV&&this.page.emit({count:this.count,pageSize:this.pageSize,limit:this.limit,offset:0})})}ngAfterContentInit(){this.columnTemplates.changes.subscribe(ne=>this.translateColumns(ne)),this.listenForColumnInputChanges()}translateColumns(ne){if(ne){const $e=ne.toArray();$e.length&&(this._internalColumns=function(tt){const sn=[];for(const ne of tt){const $e={},Lt=Object.getOwnPropertyNames(ne);for(const an of Lt)$e[an]=ne[an];ne.headerTemplate&&($e.headerTemplate=ne.headerTemplate),ne.cellTemplate&&($e.cellTemplate=ne.cellTemplate),ne.summaryFunc&&($e.summaryFunc=ne.summaryFunc),ne.summaryTemplate&&($e.summaryTemplate=ne.summaryTemplate),sn.push($e)}return sn}($e),mi(this._internalColumns),this.recalculateColumns(),this.sortInternalRows(),this.cd.markForCheck())}}groupArrayBy(ne,$e){const Lt=new Map;return ne.forEach(pi=>{const xi=pi[$e];Lt.has(xi)?Lt.get(xi).push(pi):Lt.set(xi,[pi])}),Array.from(Lt,pi=>((pi,xi)=>({key:pi,value:xi}))(pi[0],pi[1]))}ngDoCheck(){this.rowDiffer.diff(this.rows)&&(this.externalSorting?this._internalRows=[...this.rows]:this.sortInternalRows(),this._internalRows=Pr(this._internalRows,Dn(this.treeFromRelation),Dn(this.treeToRelation)),this.recalculatePages(),this.cd.markForCheck())}recalculate(){this.recalculateDims(),this.recalculateColumns(),this.cd.markForCheck()}onWindowResize(){this.recalculate()}recalculateColumns(ne=this._internalColumns,$e=-1,Lt=this.scrollbarH){if(!ne)return;let an=this._innerWidth;return this.scrollbarV&&(an-=this.scrollbarHelper.width),this.columnMode===Wr.force?function(tt,sn,ne,$e,Lt=300){const an=tt.slice(ne+1,tt.length).filter(Eo=>!1!==Eo.canAutoResize);for(const Eo of an)Eo.$$oldWidth||(Eo.$$oldWidth=Eo.width);let ti=0,pi=!1,xi=Is(tt,Lt),ts=sn-xi;const wo=[];do{ti=ts/an.length,pi=xi>=sn;for(const Eo of an){if(pi&&$e)Eo.width=Eo.$$oldWidth||Eo.width||Lt;else{const ba=(Eo.width||Lt)+ti;Eo.minWidth&&ba<Eo.minWidth?(Eo.width=Eo.minWidth,wo.push(Eo)):Eo.maxWidth&&ba>Eo.maxWidth?(Eo.width=Eo.maxWidth,wo.push(Eo)):Eo.width=ba}Eo.width=Math.max(0,Eo.width)}xi=Is(tt),ts=sn-xi,ta(an,wo)}while(ts>1&&0!==an.length)}(ne,an,$e,Lt):this.columnMode===Wr.flex&&function(tt,sn){const ne=function(tt,sn){let ne=0;for(const $e of tt)ne+=$e.width;return ne}(tt),$e=function(tt){let sn=0;for(const ne of tt)sn+=ne.flexGrow||0;return sn}(tt),Lt=To(tt);ne!==sn&&function(tt,sn,ne){for(const an in tt)for(const ti of tt[an])ti.canAutoResize?ti.width=0:(sn-=ti.width,ne-=ti.flexGrow?ti.flexGrow:0);const $e={};let Lt=sn;do{const an=Lt/ne;Lt=0;for(const ti in tt)for(const pi of tt[ti])if(pi.canAutoResize&&!$e[pi.prop]){const xi=pi.width+pi.flexGrow*an;void 0!==pi.minWidth&&xi<pi.minWidth?(Lt+=xi-pi.minWidth,pi.width=pi.minWidth,$e[pi.prop]=!0):pi.width=xi}}while(0!==Lt)}(Lt,sn,$e)}(ne,an),ne}recalculateDims(){const ne=this.dimensionsHelper.getDimensions(this.element);if(this._innerWidth=Math.floor(ne.width),this.scrollbarV){let $e=ne.height;this.headerHeight&&($e-=this.headerHeight),this.footerHeight&&($e-=this.footerHeight),this.bodyHeight=$e}this.recalculatePages()}recalculatePages(){this.pageSize=this.calcPageSize(),this.rowCount=this.calcRowCount()}onBodyPage({offset:ne}){this.externalPaging&&!this.virtualization||(this.offset=ne,this.page.emit({count:this.count,pageSize:this.pageSize,limit:this.limit,offset:this.offset}))}onBodyScroll(ne){this._offsetX.next(ne.offsetX),this.scroll.emit(ne),this.cd.detectChanges()}onFooterPage(ne){this.offset=ne.page-1,this.bodyComponent.updateOffsetY(this.offset),this.page.emit({count:this.count,pageSize:this.pageSize,limit:this.limit,offset:this.offset}),this.selectAllRowsOnPage&&(this.selected=[],this.select.emit({selected:this.selected}))}calcPageSize(ne=this.rows){if(this.scrollbarV&&this.virtualization){const $e=Math.ceil(this.bodyHeight/this.rowHeight);return Math.max($e,0)}return void 0!==this.limit?this.limit:ne?ne.length:0}calcRowCount(ne=this.rows){return this.externalPaging?this.count:ne?this.groupedRows?this.groupedRows.length:null!=this.treeFromRelation&&null!=this.treeToRelation?this._internalRows.length:ne.length:0}onColumnContextmenu({event:ne,column:$e}){this.tableContextmenu.emit({event:ne,type:ar.header,content:$e})}onRowContextmenu({event:ne,row:$e}){this.tableContextmenu.emit({event:ne,type:ar.body,content:$e})}onColumnResize({column:ne,newValue:$e}){if(void 0===ne)return;let Lt;const an=this._internalColumns.map((ti,pi)=>((ti=Object.assign({},ti)).$$id===ne.$$id&&(Lt=pi,ti.width=$e,ti.$$oldWidth=$e),ti));this.recalculateColumns(an,Lt),this._internalColumns=an,this.resize.emit({column:ne,newValue:$e})}onColumnReorder({column:ne,newValue:$e,prevValue:Lt}){const an=this._internalColumns.map(ti=>Object.assign({},ti));if(this.swapColumns){const ti=an[$e];an[$e]=ne,an[Lt]=ti}else if($e>Lt){const ti=an[Lt];for(let pi=Lt;pi<$e;pi++)an[pi]=an[pi+1];an[$e]=ti}else{const ti=an[Lt];for(let pi=Lt;pi>$e;pi--)an[pi]=an[pi-1];an[$e]=ti}this._internalColumns=an,this.reorder.emit({column:ne,newValue:$e,prevValue:Lt})}onColumnSort(ne){this.selectAllRowsOnPage&&(this.selected=[],this.select.emit({selected:this.selected})),this.sorts=ne.sorts,!1===this.externalSorting&&this.sortInternalRows(),this._internalRows=Pr(this._internalRows,Dn(this.treeFromRelation),Dn(this.treeToRelation)),this.offset=0,this.bodyComponent.updateOffsetY(this.offset),this.sort.emit(ne)}onHeaderSelect(ne){if(this.bodyComponent&&this.selectAllRowsOnPage){const $e=this.bodyComponent.indexes.first,Lt=this.bodyComponent.indexes.last,an=this.selected.length===Lt-$e;this.selected=[],an||this.selected.push(...this._internalRows.slice($e,Lt))}else{const $e=this.selected.length===this.rows.length;this.selected=[],$e||this.selected.push(...this.rows)}this.select.emit({selected:this.selected})}onBodySelect(ne){this.select.emit(ne)}onTreeAction(ne){const $e=ne.row,Lt=this._rows.findIndex(an=>an[this.treeToRelation]===ne.row[this.treeToRelation]);this.treeAction.emit({row:$e,rowIndex:Lt})}ngOnDestroy(){this._subscriptions.forEach(ne=>ne.unsubscribe())}listenForColumnInputChanges(){this._subscriptions.push(this.columnChangesService.columnInputChanges$.subscribe(()=>{this.columnTemplates&&this.columnTemplates.notifyOnChanges()}))}sortInternalRows(){this._internalRows=function(tt,sn,ne){if(!tt)return[];if(!ne||!ne.length||!sn)return[...tt];const $e=new Map;tt.forEach((pi,xi)=>$e.set(pi,xi));const Lt=[...tt],an=sn.reduce((pi,xi)=>(xi.comparator&&"function"==typeof xi.comparator&&(pi[xi.prop]=xi.comparator),pi),{}),ti=ne.map(pi=>{const xi=pi.prop;return{prop:xi,dir:pi.dir,valueGetter:gr(xi),compareFn:an[xi]||el}});return Lt.sort(function(pi,xi){for(const ts of ti){const{prop:wo,valueGetter:ko}=ts,Eo=ko(pi,wo),ba=ko(xi,wo),sl=ts.dir!==us.desc?ts.compareFn(Eo,ba,pi,xi,ts.dir):-ts.compareFn(Eo,ba,pi,xi,ts.dir);if(0!==sl)return sl}return $e.has(pi)&&$e.has(xi)?$e.get(pi)<$e.get(xi)?-1:1:0})}(this._internalRows,this._internalColumns,this.sorts)}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(Cn,4),r.Y36(Wt,4),r.Y36(r.sBO),r.Y36(r.SBq),r.Y36(r.aQg),r.Y36(zn),r.Y36("configuration",8))},tt.\u0275cmp=r.Xpm({type:tt,selectors:[["ngx-datatable"]],contentQueries:function(ne,$e,Lt){if(1&ne&&(r.Suo(Lt,os,5),r.Suo(Lt,gn,5),r.Suo(Lt,jo,5),r.Suo(Lt,Co,4)),2&ne){let an;r.iGM(an=r.CRH())&&($e.rowDetail=an.first),r.iGM(an=r.CRH())&&($e.groupHeader=an.first),r.iGM(an=r.CRH())&&($e.footer=an.first),r.iGM(an=r.CRH())&&($e.columnTemplates=an)}},viewQuery:function(ne,$e){if(1&ne&&(r.Gf(si,5),r.Gf(Vi,5)),2&ne){let Lt;r.iGM(Lt=r.CRH())&&($e.bodyComponent=Lt.first),r.iGM(Lt=r.CRH())&&($e.headerComponent=Lt.first)}},hostAttrs:[1,"ngx-datatable"],hostVars:22,hostBindings:function(ne,$e){1&ne&&r.NdJ("resize",function(){return $e.onWindowResize()},!1,r.Jf7),2&ne&&r.ekj("fixed-header",$e.isFixedHeader)("fixed-row",$e.isFixedRow)("scroll-vertical",$e.isVertScroll)("virtualized",$e.isVirtualized)("scroll-horz",$e.isHorScroll)("selectable",$e.isSelectable)("checkbox-selection",$e.isCheckboxSelection)("cell-selection",$e.isCellSelection)("single-selection",$e.isSingleSelection)("multi-selection",$e.isMultiSelection)("multi-click-selection",$e.isMultiClickSelection)},inputs:{selected:"selected",scrollbarV:"scrollbarV",scrollbarH:"scrollbarH",rowHeight:"rowHeight",columnMode:"columnMode",headerHeight:"headerHeight",footerHeight:"footerHeight",externalPaging:"externalPaging",externalSorting:"externalSorting",loadingIndicator:"loadingIndicator",reorderable:"reorderable",swapColumns:"swapColumns",sortType:"sortType",sorts:"sorts",cssClasses:"cssClasses",messages:"messages",groupExpansionDefault:"groupExpansionDefault",selectAllRowsOnPage:"selectAllRowsOnPage",virtualization:"virtualization",summaryRow:"summaryRow",summaryHeight:"summaryHeight",summaryPosition:"summaryPosition",rowIdentity:"rowIdentity",rows:"rows",groupedRows:"groupedRows",groupRowsBy:"groupRowsBy",columns:"columns",limit:"limit",count:"count",offset:"offset",targetMarkerTemplate:"targetMarkerTemplate",selectionType:"selectionType",rowClass:"rowClass",selectCheck:"selectCheck",displayCheck:"displayCheck",trackByProp:"trackByProp",treeFromRelation:"treeFromRelation",treeToRelation:"treeToRelation"},outputs:{scroll:"scroll",activate:"activate",select:"select",sort:"sort",page:"page",reorder:"reorder",resize:"resize",tableContextmenu:"tableContextmenu",treeAction:"treeAction"},decls:5,vars:34,consts:[["visibilityObserver","",3,"visible"],[3,"sorts","sortType","scrollbarH","innerWidth","offsetX","dealsWithGroup","columns","headerHeight","reorderable","targetMarkerTemplate","sortAscendingIcon","sortDescendingIcon","sortUnsetIcon","allRowsSelected","selectionType","sort","resize","reorder","select","columnContextmenu",4,"ngIf"],[3,"groupRowsBy","groupedRows","rows","groupExpansionDefault","scrollbarV","scrollbarH","virtualization","loadingIndicator","externalPaging","rowHeight","rowCount","offset","trackByProp","columns","pageSize","offsetX","rowDetail","groupHeader","selected","innerWidth","bodyHeight","selectionType","emptyMessage","rowIdentity","rowClass","selectCheck","displayCheck","summaryRow","summaryHeight","summaryPosition","page","activate","rowContextmenu","select","scroll","treeAction"],[3,"rowCount","pageSize","offset","footerHeight","footerTemplate","totalMessage","pagerLeftArrowIcon","pagerRightArrowIcon","pagerPreviousIcon","selectedCount","selectedMessage","pagerNextIcon","page",4,"ngIf"],[3,"sorts","sortType","scrollbarH","innerWidth","offsetX","dealsWithGroup","columns","headerHeight","reorderable","targetMarkerTemplate","sortAscendingIcon","sortDescendingIcon","sortUnsetIcon","allRowsSelected","selectionType","sort","resize","reorder","select","columnContextmenu"],[3,"rowCount","pageSize","offset","footerHeight","footerTemplate","totalMessage","pagerLeftArrowIcon","pagerRightArrowIcon","pagerPreviousIcon","selectedCount","selectedMessage","pagerNextIcon","page"]],template:function(ne,$e){1&ne&&(r.TgZ(0,"div",0),r.NdJ("visible",function(){return $e.recalculate()}),r.YNc(1,Ee,2,17,"datatable-header",1),r.TgZ(2,"datatable-body",2),r.NdJ("page",function(an){return $e.onBodyPage(an)})("activate",function(an){return $e.activate.emit(an)})("rowContextmenu",function(an){return $e.onRowContextmenu(an)})("select",function(an){return $e.onBodySelect(an)})("scroll",function(an){return $e.onBodyScroll(an)})("treeAction",function(an){return $e.onTreeAction(an)}),r.ALo(3,"async"),r.qZA(),r.YNc(4,ie,1,12,"datatable-footer",3),r.qZA()),2&ne&&(r.xp6(1),r.Q6J("ngIf",$e.headerHeight),r.xp6(1),r.Q6J("groupRowsBy",$e.groupRowsBy)("groupedRows",$e.groupedRows)("rows",$e._internalRows)("groupExpansionDefault",$e.groupExpansionDefault)("scrollbarV",$e.scrollbarV)("scrollbarH",$e.scrollbarH)("virtualization",$e.virtualization)("loadingIndicator",$e.loadingIndicator)("externalPaging",$e.externalPaging)("rowHeight",$e.rowHeight)("rowCount",$e.rowCount)("offset",$e.offset)("trackByProp",$e.trackByProp)("columns",$e._internalColumns)("pageSize",$e.pageSize)("offsetX",r.lcZ(3,32,$e._offsetX))("rowDetail",$e.rowDetail)("groupHeader",$e.groupHeader)("selected",$e.selected)("innerWidth",$e._innerWidth)("bodyHeight",$e.bodyHeight)("selectionType",$e.selectionType)("emptyMessage",$e.messages.emptyMessage)("rowIdentity",$e.rowIdentity)("rowClass",$e.rowClass)("selectCheck",$e.selectCheck)("displayCheck",$e.displayCheck)("summaryRow",$e.summaryRow)("summaryHeight",$e.summaryHeight)("summaryPosition",$e.summaryPosition),r.xp6(2),r.Q6J("ngIf",$e.footerHeight))},directives:function(){return[Fr,u.O5,si,Vi,Il]},pipes:function(){return[u.Ov]},styles:[".ngx-datatable{display:block;justify-content:center;overflow:hidden;position:relative;transform:translateZ(0)}.ngx-datatable [hidden]{display:none!important}.ngx-datatable *,.ngx-datatable :after,.ngx-datatable :before{box-sizing:border-box}.ngx-datatable.scroll-vertical .datatable-body{overflow-y:auto}.ngx-datatable.scroll-vertical.virtualized .datatable-body .datatable-row-wrapper{position:absolute}.ngx-datatable.scroll-horz .datatable-body{-webkit-overflow-scrolling:touch;overflow-x:auto}.ngx-datatable.fixed-header .datatable-header .datatable-header-inner{white-space:nowrap}.ngx-datatable.fixed-header .datatable-header .datatable-header-inner .datatable-header-cell{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ngx-datatable.fixed-row .datatable-scroll,.ngx-datatable.fixed-row .datatable-scroll .datatable-body-row{white-space:nowrap}.ngx-datatable.fixed-row .datatable-scroll .datatable-body-row .datatable-body-cell,.ngx-datatable.fixed-row .datatable-scroll .datatable-body-row .datatable-body-group-cell{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ngx-datatable .datatable-body-row,.ngx-datatable .datatable-header-inner,.ngx-datatable .datatable-row-center{-o-flex-flow:row;display:flex;flex-direction:row;flex-flow:row}.ngx-datatable .datatable-body-cell,.ngx-datatable .datatable-header-cell{display:inline-block;line-height:1.625;overflow-x:hidden;vertical-align:top}.ngx-datatable .datatable-body-cell:focus,.ngx-datatable .datatable-header-cell:focus{outline:none}.ngx-datatable .datatable-row-left,.ngx-datatable .datatable-row-right{z-index:9}.ngx-datatable .datatable-row-center,.ngx-datatable .datatable-row-group,.ngx-datatable .datatable-row-left,.ngx-datatable .datatable-row-right{position:relative}.ngx-datatable .datatable-header{display:block;overflow:hidden}.ngx-datatable .datatable-header .datatable-header-inner{-webkit-align-items:stretch;align-items:stretch}.ngx-datatable .datatable-header .datatable-header-cell{display:inline-block;position:relative}.ngx-datatable .datatable-header .datatable-header-cell.sortable .datatable-header-cell-wrapper{cursor:pointer}.ngx-datatable .datatable-header .datatable-header-cell.longpress .datatable-header-cell-wrapper{cursor:move}.ngx-datatable .datatable-header .datatable-header-cell .sort-btn{cursor:pointer;display:inline-block;line-height:100%;vertical-align:middle}.ngx-datatable .datatable-header .datatable-header-cell .resize-handle,.ngx-datatable .datatable-header .datatable-header-cell .resize-handle--not-resizable{bottom:0;display:inline-block;padding:0 4px;position:absolute;right:0;top:0;visibility:hidden;width:5px}.ngx-datatable .datatable-header .datatable-header-cell .resize-handle{cursor:ew-resize}.ngx-datatable .datatable-header .datatable-header-cell.resizeable:hover .resize-handle,.ngx-datatable .datatable-header .datatable-header-cell:hover .resize-handle--not-resizable{visibility:visible}.ngx-datatable .datatable-header .datatable-header-cell .targetMarker{bottom:0;position:absolute;top:0}.ngx-datatable .datatable-header .datatable-header-cell .targetMarker.dragFromLeft{right:0}.ngx-datatable .datatable-header .datatable-header-cell .targetMarker.dragFromRight{left:0}.ngx-datatable .datatable-header .datatable-header-cell .datatable-header-cell-template-wrap{height:inherit}.ngx-datatable .datatable-body{display:block;position:relative;z-index:10}.ngx-datatable .datatable-body .datatable-scroll{display:inline-block}.ngx-datatable .datatable-body .datatable-row-detail{overflow-y:hidden}.ngx-datatable .datatable-body .datatable-row-wrapper{display:flex;flex-direction:column}.ngx-datatable .datatable-body .datatable-body-row{outline:none}.ngx-datatable .datatable-body .datatable-body-row>div{display:flex}.ngx-datatable .datatable-footer{display:block;overflow:auto;width:100%}.ngx-datatable .datatable-footer .datatable-footer-inner{align-items:center;display:flex;width:100%}.ngx-datatable .datatable-footer .selected-count .page-count{flex:1 1 40%}.ngx-datatable .datatable-footer .selected-count .datatable-pager{flex:1 1 60%}.ngx-datatable .datatable-footer .page-count{flex:1 1 20%}.ngx-datatable .datatable-footer .datatable-pager{flex:1 1 80%;text-align:right}.ngx-datatable .datatable-footer .datatable-pager .pager,.ngx-datatable .datatable-footer .datatable-pager .pager li{display:inline-block;list-style:none;margin:0;padding:0}.ngx-datatable .datatable-footer .datatable-pager .pager li,.ngx-datatable .datatable-footer .datatable-pager .pager li a{outline:none}.ngx-datatable .datatable-footer .datatable-pager .pager li a{cursor:pointer;display:inline-block}.ngx-datatable .datatable-footer .datatable-pager .pager li.disabled a{cursor:not-allowed}"],encapsulation:2,changeDetection:0}),(0,y.gn)([co(5)],tt.prototype,"onWindowResize",null),tt})(),da=(()=>{class tt{constructor(ne){this.cd=ne,this.sort=new r.vpe,this.select=new r.vpe,this.columnContextmenu=new r.vpe(!1),this.sortFn=this.onSort.bind(this),this.selectFn=this.select.emit.bind(this.select),this.cellContext={column:this.column,sortDir:this.sortDir,sortFn:this.sortFn,allRowsSelected:this.allRowsSelected,selectFn:this.selectFn}}set allRowsSelected(ne){this._allRowsSelected=ne,this.cellContext.allRowsSelected=ne}get allRowsSelected(){return this._allRowsSelected}set column(ne){this._column=ne,this.cellContext.column=ne,this.cd.markForCheck()}get column(){return this._column}set sorts(ne){this._sorts=ne,this.sortDir=this.calcSortDir(ne),this.cellContext.sortDir=this.sortDir,this.sortClass=this.calcSortClass(this.sortDir),this.cd.markForCheck()}get sorts(){return this._sorts}get columnCssClasses(){let ne="datatable-header-cell";if(this.column.sortable&&(ne+=" sortable"),this.column.resizeable&&(ne+=" resizeable"),this.column.headerClass)if("string"==typeof this.column.headerClass)ne+=" "+this.column.headerClass;else if("function"==typeof this.column.headerClass){const Lt=this.column.headerClass({column:this.column});if("string"==typeof Lt)ne+=Lt;else if("object"==typeof Lt){const an=Object.keys(Lt);for(const ti of an)!0===Lt[ti]&&(ne+=` ${ti}`)}}const $e=this.sortDir;return $e&&(ne+=` sort-active sort-${$e}`),ne}get name(){return void 0===this.column.headerTemplate?this.column.name:void 0}get minWidth(){return this.column.minWidth}get maxWidth(){return this.column.maxWidth}get width(){return this.column.width}get isCheckboxable(){return this.column.checkboxable&&this.column.headerCheckboxable&&this.selectionType===dr.checkbox}onContextmenu(ne){this.columnContextmenu.emit({event:ne,column:this.column})}ngOnInit(){this.sortClass=this.calcSortClass(this.sortDir)}calcSortDir(ne){if(ne&&this.column){const $e=ne.find(Lt=>Lt.prop===this.column.prop);if($e)return $e.dir}}onSort(){if(!this.column.sortable)return;const ne=function(tt,sn){return tt===Fn.single?sn===us.asc?us.desc:us.asc:sn?sn===us.asc?us.desc:void 0:us.asc}(this.sortType,this.sortDir);this.sort.emit({column:this.column,prevValue:this.sortDir,newValue:ne})}calcSortClass(ne){if(this.cellContext.column.sortable)return ne===us.asc?`sort-btn sort-asc ${this.sortAscendingIcon}`:ne===us.desc?`sort-btn sort-desc ${this.sortDescendingIcon}`:`sort-btn ${this.sortUnsetIcon}`}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.sBO))},tt.\u0275cmp=r.Xpm({type:tt,selectors:[["datatable-header-cell"]],hostAttrs:[1,"datatable-header-cell"],hostVars:11,hostBindings:function(ne,$e){1&ne&&r.NdJ("contextmenu",function(an){return $e.onContextmenu(an)}),2&ne&&(r.uIk("title",$e.name),r.Tol($e.columnCssClasses),r.Udp("min-width",$e.minWidth,"px")("max-width",$e.maxWidth,"px")("width",$e.width,"px")("height",$e.headerHeight,"px"))},inputs:{allRowsSelected:"allRowsSelected",column:"column",sorts:"sorts",sortType:"sortType",sortAscendingIcon:"sortAscendingIcon",sortDescendingIcon:"sortDescendingIcon",sortUnsetIcon:"sortUnsetIcon",isTarget:"isTarget",targetMarkerTemplate:"targetMarkerTemplate",targetMarkerContext:"targetMarkerContext",selectionType:"selectionType",headerHeight:"headerHeight"},outputs:{sort:"sort",select:"select",columnContextmenu:"columnContextmenu"},decls:6,vars:6,consts:[[1,"datatable-header-cell-template-wrap"],[4,"ngIf"],["class","datatable-checkbox",4,"ngIf"],["class","datatable-header-cell-wrapper",4,"ngIf"],[3,"click"],[3,"ngTemplateOutlet","ngTemplateOutletContext"],[1,"datatable-checkbox"],["type","checkbox",3,"checked","change"],[1,"datatable-header-cell-wrapper"],[1,"datatable-header-cell-label","draggable",3,"innerHTML","click"]],template:function(ne,$e){1&ne&&(r.TgZ(0,"div",0),r.YNc(1,ge,1,2,void 0,1),r.YNc(2,De,2,1,"label",2),r.YNc(3,ce,2,1,"span",3),r.YNc(4,Ve,1,2,void 0,1),r.TgZ(5,"span",4),r.NdJ("click",function(){return $e.onSort()}),r.qZA(),r.qZA()),2&ne&&(r.xp6(1),r.Q6J("ngIf",$e.isTarget),r.xp6(1),r.Q6J("ngIf",$e.isCheckboxable),r.xp6(1),r.Q6J("ngIf",!$e.column.headerTemplate),r.xp6(1),r.Q6J("ngIf",$e.column.headerTemplate),r.xp6(1),r.Tol($e.sortClass))},directives:[u.O5,u.tP],encapsulation:2,changeDetection:0}),tt})(),Il=(()=>{class tt{constructor(){this.selectedCount=0,this.page=new r.vpe}get isVisible(){return this.rowCount/this.pageSize>1}get curPage(){return this.offset+1}}return tt.\u0275fac=function(ne){return new(ne||tt)},tt.\u0275cmp=r.Xpm({type:tt,selectors:[["datatable-footer"]],hostAttrs:[1,"datatable-footer"],inputs:{selectedCount:"selectedCount",footerHeight:"footerHeight",rowCount:"rowCount",pageSize:"pageSize",offset:"offset",pagerLeftArrowIcon:"pagerLeftArrowIcon",pagerRightArrowIcon:"pagerRightArrowIcon",pagerPreviousIcon:"pagerPreviousIcon",pagerNextIcon:"pagerNextIcon",totalMessage:"totalMessage",footerTemplate:"footerTemplate",selectedMessage:"selectedMessage"},outputs:{page:"page"},decls:4,vars:8,consts:[[1,"datatable-footer-inner",3,"ngClass"],[4,"ngIf"],["class","page-count",4,"ngIf"],[3,"pagerLeftArrowIcon","pagerRightArrowIcon","pagerPreviousIcon","pagerNextIcon","page","size","count","hidden","change",4,"ngIf"],[3,"ngTemplateOutlet","ngTemplateOutletContext"],[1,"page-count"],[3,"pagerLeftArrowIcon","pagerRightArrowIcon","pagerPreviousIcon","pagerNextIcon","page","size","count","hidden","change"]],template:function(ne,$e){1&ne&&(r.TgZ(0,"div",0),r.YNc(1,Pe,1,8,void 0,1),r.YNc(2,He,3,3,"div",2),r.YNc(3,Vt,1,8,"datatable-pager",3),r.qZA()),2&ne&&(r.Udp("height",$e.footerHeight,"px"),r.Q6J("ngClass",r.VKq(6,it,$e.selectedMessage)),r.xp6(1),r.Q6J("ngIf",$e.footerTemplate),r.xp6(1),r.Q6J("ngIf",!$e.footerTemplate),r.xp6(1),r.Q6J("ngIf",!$e.footerTemplate))},directives:function(){return[u.mk,u.O5,u.tP,fo]},encapsulation:2,changeDetection:0}),tt})(),fo=(()=>{class tt{constructor(){this.change=new r.vpe,this._count=0,this._page=1,this._size=0}set size(ne){this._size=ne,this.pages=this.calcPages()}get size(){return this._size}set count(ne){this._count=ne,this.pages=this.calcPages()}get count(){return this._count}set page(ne){this._page=ne,this.pages=this.calcPages()}get page(){return this._page}get totalPages(){const ne=this.size<1?1:Math.ceil(this.count/this.size);return Math.max(ne||0,1)}canPrevious(){return this.page>1}canNext(){return this.page<this.totalPages}prevPage(){this.selectPage(this.page-1)}nextPage(){this.selectPage(this.page+1)}selectPage(ne){ne>0&&ne<=this.totalPages&&ne!==this.page&&(this.page=ne,this.change.emit({page:ne}))}calcPages(ne){const $e=[];let Lt=1,an=this.totalPages;ne=ne||this.page,5<this.totalPages&&(Lt=ne-Math.floor(2.5),an=ne+Math.floor(2.5),Lt<1?(Lt=1,an=Math.min(Lt+5-1,this.totalPages)):an>this.totalPages&&(Lt=Math.max(this.totalPages-5+1,1),an=this.totalPages));for(let xi=Lt;xi<=an;xi++)$e.push({number:xi,text:xi});return $e}}return tt.\u0275fac=function(ne){return new(ne||tt)},tt.\u0275cmp=r.Xpm({type:tt,selectors:[["datatable-pager"]],hostAttrs:[1,"datatable-pager"],inputs:{size:"size",count:"count",page:"page",pagerLeftArrowIcon:"pagerLeftArrowIcon",pagerRightArrowIcon:"pagerRightArrowIcon",pagerPreviousIcon:"pagerPreviousIcon",pagerNextIcon:"pagerNextIcon"},outputs:{change:"change"},decls:14,vars:21,consts:[[1,"pager"],["role","button","aria-label","go to first page","href","javascript:void(0)",3,"click"],["role","button","aria-label","go to previous page","href","javascript:void(0)",3,"click"],["role","button","class","pages",3,"active",4,"ngFor","ngForOf"],["role","button","aria-label","go to next page","href","javascript:void(0)",3,"click"],["role","button","aria-label","go to last page","href","javascript:void(0)",3,"click"],["role","button",1,"pages"],["href","javascript:void(0)",3,"click"]],template:function(ne,$e){1&ne&&(r.TgZ(0,"ul",0),r.TgZ(1,"li"),r.TgZ(2,"a",1),r.NdJ("click",function(){return $e.selectPage(1)}),r._UZ(3,"i"),r.qZA(),r.qZA(),r.TgZ(4,"li"),r.TgZ(5,"a",2),r.NdJ("click",function(){return $e.prevPage()}),r._UZ(6,"i"),r.qZA(),r.qZA(),r.YNc(7,tn,3,4,"li",3),r.TgZ(8,"li"),r.TgZ(9,"a",4),r.NdJ("click",function(){return $e.nextPage()}),r._UZ(10,"i"),r.qZA(),r.qZA(),r.TgZ(11,"li"),r.TgZ(12,"a",5),r.NdJ("click",function(){return $e.selectPage($e.totalPages)}),r._UZ(13,"i"),r.qZA(),r.qZA(),r.qZA()),2&ne&&(r.xp6(1),r.ekj("disabled",!$e.canPrevious()),r.xp6(2),r.Tol($e.pagerPreviousIcon),r.xp6(1),r.ekj("disabled",!$e.canPrevious()),r.xp6(2),r.Tol($e.pagerLeftArrowIcon),r.xp6(1),r.Q6J("ngForOf",$e.pages),r.xp6(1),r.ekj("disabled",!$e.canNext()),r.xp6(2),r.Tol($e.pagerRightArrowIcon),r.xp6(1),r.ekj("disabled",!$e.canNext()),r.xp6(2),r.Tol($e.pagerNextIcon))},directives:[u.sg],encapsulation:2,changeDetection:0}),tt})(),Ya=(()=>{class tt{}return tt.\u0275fac=function(ne){return new(ne||tt)},tt.\u0275cmp=r.Xpm({type:tt,selectors:[["datatable-progress"]],decls:3,vars:0,consts:[["role","progressbar",1,"progress-linear"],[1,"container"],[1,"bar"]],template:function(ne,$e){1&ne&&(r.TgZ(0,"div",0),r.TgZ(1,"div",1),r._UZ(2,"div",2),r.qZA(),r.qZA())},encapsulation:2,changeDetection:0}),tt})();var Ao=(()=>{return(tt=Ao||(Ao={}))[tt.up=38]="up",tt[tt.down=40]="down",tt[tt.return=13]="return",tt[tt.escape=27]="escape",tt[tt.left=37]="left",tt[tt.right=39]="right",Ao;var tt})();let fs=(()=>{class tt{constructor(ne,$e,Lt,an){this.differs=ne,this.scrollbarHelper=$e,this.cd=Lt,this.treeStatus="collapsed",this.activate=new r.vpe,this.treeAction=new r.vpe,this._groupStyles={left:{},center:{},right:{}},this._element=an.nativeElement,this._rowDiffer=ne.find({}).create()}set columns(ne){this._columns=ne,this.recalculateColumns(ne),this.buildStylesByGroup()}get columns(){return this._columns}set innerWidth(ne){if(this._columns){const $e=To(this._columns);this._columnGroupWidths=Mi($e,this._columns)}this._innerWidth=ne,this.recalculateColumns(),this.buildStylesByGroup()}get innerWidth(){return this._innerWidth}set offsetX(ne){this._offsetX=ne,this.buildStylesByGroup()}get offsetX(){return this._offsetX}get cssClass(){let ne="datatable-body-row";if(this.isSelected&&(ne+=" active"),this.rowIndex%2!=0&&(ne+=" datatable-row-odd"),this.rowIndex%2==0&&(ne+=" datatable-row-even"),this.rowClass){const $e=this.rowClass(this.row);if("string"==typeof $e)ne+=` ${$e}`;else if("object"==typeof $e){const Lt=Object.keys($e);for(const an of Lt)!0===$e[an]&&(ne+=` ${an}`)}}return ne}get columnsTotalWidths(){return this._columnGroupWidths.total}ngDoCheck(){this._rowDiffer.diff(this.row)&&this.cd.markForCheck()}trackByGroups(ne,$e){return $e.type}columnTrackingFn(ne,$e){return $e.$$id}buildStylesByGroup(){this._groupStyles.left=this.calcStylesByGroup("left"),this._groupStyles.center=this.calcStylesByGroup("center"),this._groupStyles.right=this.calcStylesByGroup("right"),this.cd.markForCheck()}calcStylesByGroup(ne){const $e=this._columnGroupWidths,Lt=this.offsetX,an={width:`${$e[ne]}px`};if("left"===ne)on(an,Lt,0);else if("right"===ne){const ti=parseInt(this.innerWidth+"",0);on(an,-1*($e.total-ti-Lt+this.scrollbarHelper.width),0)}return an}onActivate(ne,$e){ne.cellIndex=$e,ne.rowElement=this._element,this.activate.emit(ne)}onKeyDown(ne){const $e=ne.keyCode;($e===Ao.return||$e===Ao.down||$e===Ao.up||$e===Ao.left||$e===Ao.right)&&ne.target===this._element&&(ne.preventDefault(),ne.stopPropagation(),this.activate.emit({type:"keydown",event:ne,row:this.row,rowElement:this._element}))}onMouseenter(ne){this.activate.emit({type:"mouseenter",event:ne,row:this.row,rowElement:this._element})}recalculateColumns(ne=this.columns){this._columns=ne;const $e=To(this._columns);this._columnsByPin=lr(this._columns),this._columnGroupWidths=Mi($e,this._columns)}onTreeAction(){this.treeAction.emit()}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.aQg),r.Y36(Cn,4),r.Y36(r.sBO),r.Y36(r.SBq))},tt.\u0275cmp=r.Xpm({type:tt,selectors:[["datatable-body-row"]],hostVars:6,hostBindings:function(ne,$e){1&ne&&r.NdJ("keydown",function(an){return $e.onKeyDown(an)})("mouseenter",function(an){return $e.onMouseenter(an)}),2&ne&&(r.Tol($e.cssClass),r.Udp("width",$e.columnsTotalWidths,"px")("height",$e.rowHeight,"px"))},inputs:{treeStatus:"treeStatus",columns:"columns",innerWidth:"innerWidth",offsetX:"offsetX",expanded:"expanded",rowClass:"rowClass",row:"row",group:"group",isSelected:"isSelected",rowIndex:"rowIndex",displayCheck:"displayCheck",rowHeight:"rowHeight"},outputs:{activate:"activate",treeAction:"treeAction"},decls:1,vars:2,consts:[[3,"class","ngStyle",4,"ngFor","ngForOf","ngForTrackBy"],[3,"ngStyle"],["tabindex","-1",3,"row","group","expanded","isSelected","rowIndex","column","rowHeight","displayCheck","treeStatus","activate","treeAction",4,"ngFor","ngForOf","ngForTrackBy"],["tabindex","-1",3,"row","group","expanded","isSelected","rowIndex","column","rowHeight","displayCheck","treeStatus","activate","treeAction"]],template:function(ne,$e){1&ne&&r.YNc(0,Zt,2,6,"div",0),2&ne&&r.Q6J("ngForOf",$e._columnsByPin)("ngForTrackBy",$e.trackByGroups)},directives:function(){return[u.sg,u.PC,Ra]},encapsulation:2,changeDetection:0}),tt})(),Ca=(()=>{class tt{constructor(ne,$e){this.cd=ne,this.differs=$e,this.rowContextmenu=new r.vpe(!1),this.groupContext={group:this.row,expanded:this.expanded,rowIndex:this.rowIndex},this.rowContext={row:this.row,expanded:this.expanded,rowIndex:this.rowIndex},this._expanded=!1,this.rowDiffer=$e.find({}).create()}set rowIndex(ne){this._rowIndex=ne,this.rowContext.rowIndex=ne,this.groupContext.rowIndex=ne,this.cd.markForCheck()}get rowIndex(){return this._rowIndex}set expanded(ne){this._expanded=ne,this.groupContext.expanded=ne,this.rowContext.expanded=ne,this.cd.markForCheck()}get expanded(){return this._expanded}ngDoCheck(){this.rowDiffer.diff(this.row)&&(this.rowContext.row=this.row,this.groupContext.group=this.row,this.cd.markForCheck())}onContextmenu(ne){this.rowContextmenu.emit({event:ne,row:this.row})}getGroupHeaderStyle(){const ne={};return ne.transform="translate3d("+this.offsetX+"px, 0px, 0px)",ne["backface-visibility"]="hidden",ne.width=this.innerWidth,ne}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.sBO),r.Y36(r.aQg))},tt.\u0275cmp=r.Xpm({type:tt,selectors:[["datatable-row-wrapper"]],hostAttrs:[1,"datatable-row-wrapper"],hostBindings:function(ne,$e){1&ne&&r.NdJ("contextmenu",function(an){return $e.onContextmenu(an)})},inputs:{rowIndex:"rowIndex",expanded:"expanded",innerWidth:"innerWidth",rowDetail:"rowDetail",groupHeader:"groupHeader",offsetX:"offsetX",detailRowHeight:"detailRowHeight",row:"row",groupedRows:"groupedRows"},outputs:{rowContextmenu:"rowContextmenu"},ngContentSelectors:S,decls:3,vars:3,consts:[["class","datatable-group-header",3,"ngStyle",4,"ngIf"],[4,"ngIf"],["class","datatable-row-detail",3,"height",4,"ngIf"],[1,"datatable-group-header",3,"ngStyle"],[3,"ngTemplateOutlet","ngTemplateOutletContext"],[1,"datatable-row-detail"]],template:function(ne,$e){1&ne&&(r.F$t(),r.YNc(0,bt,2,2,"div",0),r.YNc(1,Gt,1,0,"ng-content",1),r.YNc(2,Zn,2,3,"div",2)),2&ne&&(r.Q6J("ngIf",$e.groupHeader&&$e.groupHeader.template),r.xp6(1),r.Q6J("ngIf",$e.groupHeader&&$e.groupHeader.template&&$e.expanded||!$e.groupHeader||!$e.groupHeader.template),r.xp6(1),r.Q6J("ngIf",$e.rowDetail&&$e.rowDetail.template&&$e.expanded))},directives:[u.O5,u.PC,u.tP],encapsulation:2,changeDetection:0}),tt})(),Ra=(()=>{class tt{constructor(ne,$e){this.cd=$e,this.activate=new r.vpe,this.treeAction=new r.vpe,this.isFocused=!1,this.onCheckboxChangeFn=this.onCheckboxChange.bind(this),this.activateFn=this.activate.emit.bind(this.activate),this.cellContext={onCheckboxChangeFn:this.onCheckboxChangeFn,activateFn:this.activateFn,row:this.row,group:this.group,value:this.value,column:this.column,rowHeight:this.rowHeight,isSelected:this.isSelected,rowIndex:this.rowIndex,treeStatus:this.treeStatus,onTreeAction:this.onTreeAction.bind(this)},this._element=ne.nativeElement}set group(ne){this._group=ne,this.cellContext.group=ne,this.checkValueUpdates(),this.cd.markForCheck()}get group(){return this._group}set rowHeight(ne){this._rowHeight=ne,this.cellContext.rowHeight=ne,this.checkValueUpdates(),this.cd.markForCheck()}get rowHeight(){return this._rowHeight}set isSelected(ne){this._isSelected=ne,this.cellContext.isSelected=ne,this.cd.markForCheck()}get isSelected(){return this._isSelected}set expanded(ne){this._expanded=ne,this.cellContext.expanded=ne,this.cd.markForCheck()}get expanded(){return this._expanded}set rowIndex(ne){this._rowIndex=ne,this.cellContext.rowIndex=ne,this.checkValueUpdates(),this.cd.markForCheck()}get rowIndex(){return this._rowIndex}set column(ne){this._column=ne,this.cellContext.column=ne,this.checkValueUpdates(),this.cd.markForCheck()}get column(){return this._column}set row(ne){this._row=ne,this.cellContext.row=ne,this.checkValueUpdates(),this.cd.markForCheck()}get row(){return this._row}set sorts(ne){this._sorts=ne,this.calcSortDir=this.calcSortDir(ne)}get sorts(){return this._sorts}set treeStatus(ne){this._treeStatus="collapsed"!==ne&&"expanded"!==ne&&"loading"!==ne&&"disabled"!==ne?"collapsed":ne,this.cellContext.treeStatus=this._treeStatus,this.checkValueUpdates(),this.cd.markForCheck()}get treeStatus(){return this._treeStatus}get columnCssClasses(){let ne="datatable-body-cell";if(this.column.cellClass)if("string"==typeof this.column.cellClass)ne+=" "+this.column.cellClass;else if("function"==typeof this.column.cellClass){const $e=this.column.cellClass({row:this.row,group:this.group,column:this.column,value:this.value,rowHeight:this.rowHeight});if("string"==typeof $e)ne+=" "+$e;else if("object"==typeof $e){const Lt=Object.keys($e);for(const an of Lt)!0===$e[an]&&(ne+=` ${an}`)}}return this.sortDir||(ne+=" sort-active"),this.isFocused&&(ne+=" active"),this.sortDir===us.asc&&(ne+=" sort-asc"),this.sortDir===us.desc&&(ne+=" sort-desc"),ne}get width(){return this.column.width}get minWidth(){return this.column.minWidth}get maxWidth(){return this.column.maxWidth}get height(){const ne=this.rowHeight;return isNaN(ne)?ne:ne+"px"}ngDoCheck(){this.checkValueUpdates()}ngOnDestroy(){this.cellTemplate&&this.cellTemplate.clear()}checkValueUpdates(){let ne="";if(this.row&&this.column){const $e=this.column.$$valueGetter(this.row,this.column.prop),Lt=this.column.pipe;Lt?ne=Lt.transform($e):void 0!==ne&&(ne=$e)}else ne="";this.value!==ne&&(this.value=ne,this.cellContext.value=ne,this.sanitizedValue=null!=ne?this.stripHtml(ne):ne,this.cd.markForCheck())}onFocus(){this.isFocused=!0}onBlur(){this.isFocused=!1}onClick(ne){this.activate.emit({type:"click",event:ne,row:this.row,group:this.group,rowHeight:this.rowHeight,column:this.column,value:this.value,cellElement:this._element})}onDblClick(ne){this.activate.emit({type:"dblclick",event:ne,row:this.row,group:this.group,rowHeight:this.rowHeight,column:this.column,value:this.value,cellElement:this._element})}onKeyDown(ne){const $e=ne.keyCode;($e===Ao.return||$e===Ao.down||$e===Ao.up||$e===Ao.left||$e===Ao.right)&&ne.target===this._element&&(ne.preventDefault(),ne.stopPropagation(),this.activate.emit({type:"keydown",event:ne,row:this.row,group:this.group,rowHeight:this.rowHeight,column:this.column,value:this.value,cellElement:this._element}))}onCheckboxChange(ne){this.activate.emit({type:"checkbox",event:ne,row:this.row,group:this.group,rowHeight:this.rowHeight,column:this.column,value:this.value,cellElement:this._element,treeStatus:"collapsed"})}calcSortDir(ne){if(!ne)return;const $e=ne.find(Lt=>Lt.prop===this.column.prop);return $e?$e.dir:void 0}stripHtml(ne){return ne.replace?ne.replace(/<\/?[^>]+(>|$)/g,""):ne}onTreeAction(){this.treeAction.emit(this.row)}calcLeftMargin(ne,$e){return ne.isTreeColumn?$e.level*(null!=ne.treeLevelIndent?ne.treeLevelIndent:50):0}}return tt.\u0275fac=function(ne){return new(ne||tt)(r.Y36(r.SBq),r.Y36(r.sBO))},tt.\u0275cmp=r.Xpm({type:tt,selectors:[["datatable-body-cell"]],viewQuery:function(ne,$e){if(1&ne&&r.Gf(Ur,7,r.s_b),2&ne){let Lt;r.iGM(Lt=r.CRH())&&($e.cellTemplate=Lt.first)}},hostVars:10,hostBindings:function(ne,$e){1&ne&&r.NdJ("focus",function(){return $e.onFocus()})("blur",function(){return $e.onBlur()})("click",function(an){return $e.onClick(an)})("dblclick",function(an){return $e.onDblClick(an)})("keydown",function(an){return $e.onKeyDown(an)}),2&ne&&(r.Tol($e.columnCssClasses),r.Udp("width",$e.width,"px")("min-width",$e.minWidth,"px")("max-width",$e.maxWidth,"px")("height",$e.height))},inputs:{group:"group",rowHeight:"rowHeight",isSelected:"isSelected",expanded:"expanded",rowIndex:"rowIndex",column:"column",row:"row",sorts:"sorts",treeStatus:"treeStatus",displayCheck:"displayCheck"},outputs:{activate:"activate",treeAction:"treeAction"},decls:5,vars:6,consts:[[1,"datatable-body-cell-label"],["class","datatable-checkbox",4,"ngIf"],[4,"ngIf"],[3,"title","innerHTML",4,"ngIf"],[1,"datatable-checkbox"],["type","checkbox",3,"checked","click"],["class","datatable-tree-button",3,"disabled","click",4,"ngIf"],[1,"datatable-tree-button",3,"disabled","click"],["class","icon datatable-icon-collapse",4,"ngIf"],["class","icon datatable-icon-up",4,"ngIf"],["class","icon datatable-icon-down",4,"ngIf"],[1,"icon","datatable-icon-collapse"],[1,"icon","datatable-icon-up"],[1,"icon","datatable-icon-down"],[3,"ngTemplateOutlet","ngTemplateOutletContext"],[3,"title","innerHTML"],["cellTemplate",""]],template:function(ne,$e){1&ne&&(r.TgZ(0,"div",0),r.YNc(1,di,2,1,"label",1),r.YNc(2,Yr,3,2,"ng-container",2),r.YNc(3,fi,1,2,"span",3),r.YNc(4,Hi,2,2,void 0,2),r.qZA()),2&ne&&(r.Udp("margin-left",$e.calcLeftMargin($e.column,$e.row),"px"),r.xp6(1),r.Q6J("ngIf",$e.column.checkboxable&&(!$e.displayCheck||$e.displayCheck($e.row,$e.column,$e.value))),r.xp6(1),r.Q6J("ngIf",$e.column.isTreeColumn),r.xp6(1),r.Q6J("ngIf",!$e.column.cellTemplate),r.xp6(1),r.Q6J("ngIf",$e.column.cellTemplate))},directives:[u.O5,u.tP],encapsulation:2,changeDetection:0}),tt})();function pl(tt,sn,ne){const $e=ne(sn,tt);return $e>-1?tt.splice($e,1):tt.push(sn),tt}let Po=(()=>{class tt{constructor(){this.activate=new r.vpe,this.select=new r.vpe}selectRow(ne,$e,Lt){if(!this.selectEnabled)return;const an=this.selectionType===dr.checkbox,pi=this.selectionType===dr.multiClick;let xi=[];xi=this.selectionType===dr.multi||an||pi?ne.shiftKey?function(tt,sn,ne,$e,Lt){const an=ne<$e;for(let ti=0;ti<sn.length;ti++){const pi=sn[ti],xi=ti>=$e&&ti<=ne,ts=ti<=$e&&ti>=ne;let wo={start:0,end:0};wo=an?{start:ne,end:$e}:{start:$e,end:ne+1},(an&&ts||!an&&xi)&&ti>=wo.start&&ti<=wo.end&&tt.push(pi)}return tt}([],this.rows,$e,this.prevIndex,this.getRowSelectedIdx.bind(this)):pl(ne.ctrlKey||ne.metaKey||pi||an?[...this.selected]:[],Lt,this.getRowSelectedIdx.bind(this)):pl([],Lt,this.getRowSelectedIdx.bind(this)),"function"==typeof this.selectCheck&&(xi=xi.filter(this.selectCheck.bind(this))),this.selected.splice(0,this.selected.length),this.selected.push(...xi),this.prevIndex=$e,this.select.emit({selected:xi})}onActivate(ne,$e){const{type:Lt,event:an,row:ti}=ne,pi=this.selectionType===dr.checkbox;!pi&&("click"===Lt||"dblclick"===Lt)||pi&&"checkbox"===Lt?this.selectRow(an,$e,ti):"keydown"===Lt&&(an.keyCode===Ao.return?this.selectRow(an,$e,ti):this.onKeyboardFocus(ne)),this.activate.emit(ne)}onKeyboardFocus(ne){const{keyCode:$e}=ne.event;if($e===Ao.up||$e===Ao.down||$e===Ao.right||$e===Ao.left){const an=this.selectionType===dr.cell;ne.cellElement&&an?an&&this.focusCell(ne.cellElement,ne.rowElement,$e,ne.cellIndex):this.focusRow(ne.rowElement,$e)}}focusRow(ne,$e){const Lt=this.getPrevNextRow(ne,$e);Lt&&Lt.focus()}getPrevNextRow(ne,$e){const Lt=ne.parentElement;if(Lt){let an;if($e===Ao.up?an=Lt.previousElementSibling:$e===Ao.down&&(an=Lt.nextElementSibling),an&&an.children.length)return an.children[0]}}focusCell(ne,$e,Lt,an){let ti;if(Lt===Ao.left)ti=ne.previousElementSibling;else if(Lt===Ao.right)ti=ne.nextElementSibling;else if(Lt===Ao.up||Lt===Ao.down){const pi=this.getPrevNextRow($e,Lt);if(pi){const xi=pi.getElementsByClassName("datatable-body-cell");xi.length&&(ti=xi[an])}}ti&&ti.focus()}getRowSelected(ne){return this.getRowSelectedIdx(ne,this.selected)>-1}getRowSelectedIdx(ne,$e){if(!$e||!$e.length)return-1;const Lt=this.rowIdentity(ne);return $e.findIndex(an=>this.rowIdentity(an)===Lt)}}return tt.\u0275fac=function(ne){return new(ne||tt)},tt.\u0275cmp=r.Xpm({type:tt,selectors:[["datatable-selection"]],inputs:{rows:"rows",selected:"selected",selectEnabled:"selectEnabled",selectionType:"selectionType",rowIdentity:"rowIdentity",selectCheck:"selectCheck"},outputs:{activate:"activate",select:"select"},ngContentSelectors:S,decls:1,vars:0,template:function(ne,$e){1&ne&&(r.F$t(),r.Hsn(0))},encapsulation:2,changeDetection:0}),tt})();function bo(tt){const sn=tt.filter(ne=>!!ne);return!sn.length||sn.some(ne=>"number"!=typeof ne)?null:sn.reduce((ne,$e)=>ne+$e)}function Ls(tt){return null}let ps=(()=>{class tt{constructor(){this.summaryRow={}}ngOnChanges(){!this.columns||!this.rows||(this.updateInternalColumns(),this.updateValues())}updateInternalColumns(){this._internalColumns=this.columns.map(ne=>Object.assign(Object.assign({},ne),{cellTemplate:ne.summaryTemplate}))}updateValues(){this.summaryRow={},this.columns.filter(ne=>!ne.summaryTemplate).forEach(ne=>{const $e=this.rows.map(an=>an[ne.prop]),Lt=this.getSummaryFunction(ne);this.summaryRow[ne.prop]=ne.pipe?ne.pipe.transform(Lt($e)):Lt($e)})}getSummaryFunction(ne){return void 0===ne.summaryFunc?bo:null===ne.summaryFunc?Ls:ne.summaryFunc}}return tt.\u0275fac=function(ne){return new(ne||tt)},tt.\u0275cmp=r.Xpm({type:tt,selectors:[["datatable-summary-row"]],hostAttrs:[1,"datatable-summary-row"],inputs:{rows:"rows",columns:"columns",rowHeight:"rowHeight",offsetX:"offsetX",innerWidth:"innerWidth"},features:[r.TTD],decls:1,vars:1,consts:[["tabindex","-1",3,"innerWidth","offsetX","columns","rowHeight","row","rowIndex",4,"ngIf"],["tabindex","-1",3,"innerWidth","offsetX","columns","rowHeight","row","rowIndex"]],template:function(ne,$e){1&ne&&r.YNc(0,Zr,1,6,"datatable-body-row",0),2&ne&&r.Q6J("ngIf",$e.summaryRow&&$e._internalColumns)},directives:[u.O5,fs],encapsulation:2}),tt})(),So=(()=>{class tt{static forRoot(ne){return{ngModule:tt,providers:[{provide:"configuration",useValue:ne}]}}}return tt.\u0275fac=function(ne){return new(ne||tt)},tt.\u0275mod=r.oAB({type:tt}),tt.\u0275inj=r.cJS({providers:[Cn,Wt,zn],imports:[[u.ez]]}),tt})();"undefined"!=typeof document&&!document.elementsFromPoint&&(document.elementsFromPoint=function(tt,sn){const ne=[],$e=[];let Lt,an,ti;for(;(Lt=document.elementFromPoint(tt,sn))&&-1===ne.indexOf(Lt)&&null!=Lt;)ne.push(Lt),$e.push({value:Lt.style.getPropertyValue("pointer-events"),priority:Lt.style.getPropertyPriority("pointer-events")}),Lt.style.setProperty("pointer-events","none","important");for(an=$e.length;ti=$e[--an];)ne[an].style.setProperty("pointer-events",ti.value?ti.value:"",ti.priority);return ne})},67506:v=>{"use strict";function T(u,p,d){u instanceof RegExp&&(u=i(u,d)),p instanceof RegExp&&(p=i(p,d));var e=r(u,p,d);return e&&{start:e[0],end:e[1],pre:d.slice(0,e[0]),body:d.slice(e[0]+u.length,e[1]),post:d.slice(e[1]+p.length)}}function i(u,p){var d=p.match(u);return d?d[0]:null}function r(u,p,d){var e,_,y,S,A,N=d.indexOf(u),L=d.indexOf(p,N+1),Z=N;if(N>=0&&L>0){if(u===p)return[N,L];for(e=[],y=d.length;Z>=0&&!A;)Z==N?(e.push(Z),N=d.indexOf(u,Z+1)):1==e.length?A=[e.pop(),L]:((_=e.pop())<y&&(y=_,S=L),L=d.indexOf(p,Z+1)),Z=N<L&&N>=0?N:L;e.length&&(A=[y,S])}return A}v.exports=T,T.range=r},96434:(v,T)=>{"use strict";T.byteLength=function(J){var K=_(J),ue=K[1];return 3*(K[0]+ue)/4-ue},T.toByteArray=function(J){var K,ie,ee=_(J),ue=ee[0],ae=ee[1],H=new u(function(J,K,ee){return 3*(K+ee)/4-ee}(0,ue,ae)),se=0,Ee=ae>0?ue-4:ue;for(ie=0;ie<Ee;ie+=4)K=r[J.charCodeAt(ie)]<<18|r[J.charCodeAt(ie+1)]<<12|r[J.charCodeAt(ie+2)]<<6|r[J.charCodeAt(ie+3)],H[se++]=K>>16&255,H[se++]=K>>8&255,H[se++]=255&K;return 2===ae&&(K=r[J.charCodeAt(ie)]<<2|r[J.charCodeAt(ie+1)]>>4,H[se++]=255&K),1===ae&&(K=r[J.charCodeAt(ie)]<<10|r[J.charCodeAt(ie+1)]<<4|r[J.charCodeAt(ie+2)]>>2,H[se++]=K>>8&255,H[se++]=255&K),H},T.fromByteArray=function(J){for(var K,ee=J.length,ue=ee%3,ae=[],H=16383,se=0,Ee=ee-ue;se<Ee;se+=H)ae.push(L(J,se,se+H>Ee?Ee:se+H));return 1===ue?ae.push(i[(K=J[ee-1])>>2]+i[K<<4&63]+"=="):2===ue&&ae.push(i[(K=(J[ee-2]<<8)+J[ee-1])>>10]+i[K>>4&63]+i[K<<2&63]+"="),ae.join("")};for(var i=[],r=[],u="undefined"!=typeof Uint8Array?Uint8Array:Array,p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",d=0,e=p.length;d<e;++d)i[d]=p[d],r[p.charCodeAt(d)]=d;function _(J){var K=J.length;if(K%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var ee=J.indexOf("=");return-1===ee&&(ee=K),[ee,ee===K?0:4-ee%4]}function N(J){return i[J>>18&63]+i[J>>12&63]+i[J>>6&63]+i[63&J]}function L(J,K,ee){for(var ae=[],H=K;H<ee;H+=3)ae.push(N((J[H]<<16&16711680)+(J[H+1]<<8&65280)+(255&J[H+2])));return ae.join("")}r["-".charCodeAt(0)]=62,r["_".charCodeAt(0)]=63},33512:(v,T,i)=>{var r=i(2665),u=i(67506);v.exports=function(se){return se?("{}"===se.substr(0,2)&&(se="\\{\\}"+se.substr(2)),H(function(se){return se.split("\\\\").join(p).split("\\{").join(d).split("\\}").join(e).split("\\,").join(_).split("\\.").join(y)}(se),!0).map(N)):[]};var p="\0SLASH"+Math.random()+"\0",d="\0OPEN"+Math.random()+"\0",e="\0CLOSE"+Math.random()+"\0",_="\0COMMA"+Math.random()+"\0",y="\0PERIOD"+Math.random()+"\0";function S(se){return parseInt(se,10)==se?parseInt(se,10):se.charCodeAt(0)}function N(se){return se.split(p).join("\\").split(d).join("{").split(e).join("}").split(_).join(",").split(y).join(".")}function L(se){if(!se)return[""];var Ee=[],ie=u("{","}",se);if(!ie)return se.split(",");var ge=ie.body,De=ie.post,ce=ie.pre.split(",");ce[ce.length-1]+="{"+ge+"}";var lt=L(De);return De.length&&(ce[ce.length-1]+=lt.shift(),ce.push.apply(ce,lt)),Ee.push.apply(Ee,ce),Ee}function K(se){return"{"+se+"}"}function ee(se){return/^-?0\d/.test(se)}function ue(se,Ee){return se<=Ee}function ae(se,Ee){return se>=Ee}function H(se,Ee){var ie=[],he=u("{","}",se);if(!he||/\$$/.test(he.pre))return[se];var Ve,ge=/^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(he.body),De=/^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(he.body),ce=ge||De,lt=he.body.indexOf(",")>=0;if(!ce&&!lt)return he.post.match(/,.*\}/)?H(se=he.pre+"{"+he.body+e+he.post):[se];if(ce)Ve=he.body.split(/\.\./);else if(1===(Ve=L(he.body)).length&&1===(Ve=H(Ve[0],!1).map(K)).length)return(Be=he.post.length?H(he.post,!1):[""]).map(function(di){return he.pre+Ve[0]+di});var Pe,ze=he.pre,Be=he.post.length?H(he.post,!1):[""];if(ce){var je=S(Ve[0]),He=S(Ve[1]),Vt=Math.max(Ve[0].length,Ve[1].length),it=3==Ve.length?Math.abs(S(Ve[2])):1,tn=ue;He<je&&(it*=-1,tn=ae);var Zt=Ve.some(ee);Pe=[];for(var Ut=je;tn(Ut,He);Ut+=it){var Bt;if(De)"\\"===(Bt=String.fromCharCode(Ut))&&(Bt="");else if(Bt=String(Ut),Zt){var bt=Vt-Bt.length;if(bt>0){var Gt=new Array(bt+1).join("0");Bt=Ut<0?"-"+Gt+Bt.slice(1):Gt+Bt}}Pe.push(Bt)}}else Pe=r(Ve,function(Ur){return H(Ur,!1)});for(var xt=0;xt<Pe.length;xt++)for(var Xt=0;Xt<Be.length;Xt++){var Zn=ze+Pe[xt]+Be[Xt];(!Ee||ce||Zn)&&ie.push(Zn)}return ie}},19568:(v,T,i)=>{"use strict";var r=i(18540),u=i(60044),p=u(r("String.prototype.indexOf"));v.exports=function(e,_){var y=r(e,!!_);return"function"==typeof y&&p(e,".prototype.")>-1?u(y):y}},60044:(v,T,i)=>{"use strict";var r=i(75396),u=i(18540),p=u("%Function.prototype.apply%"),d=u("%Function.prototype.call%"),e=u("%Reflect.apply%",!0)||r.call(d,p),_=u("%Object.getOwnPropertyDescriptor%",!0),y=u("%Object.defineProperty%",!0),S=u("%Math.max%");if(y)try{y({},"a",{value:1})}catch(N){y=null}v.exports=function(L){var Z=e(r,d,arguments);if(_&&y){var J=_(Z,"length");J.configurable&&y(Z,"length",{value:1+S(0,L.length-(arguments.length-1))})}return Z};var A=function(){return e(r,p,arguments)};y?y(v.exports,"apply",{value:A}):v.exports.apply=A},72318:v=>{var T=!("undefined"==typeof window||!window.document||!window.document.createElement);v.exports=T},6823:function(v,T,i){v.exports=function(r){"use strict";r=r&&r.hasOwnProperty("default")?r.default:r;var d={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},e=function(h,E){return h(E={exports:{}},E.exports),E.exports}(function(h){var E={};for(var R in d)d.hasOwnProperty(R)&&(E[d[R]]=R);var F=h.exports={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};for(var q in F)if(F.hasOwnProperty(q)){if(!("channels"in F[q]))throw new Error("missing channels property: "+q);if(!("labels"in F[q]))throw new Error("missing channel labels property: "+q);if(F[q].labels.length!==F[q].channels)throw new Error("channel and label counts mismatch: "+q);var de=F[q].channels,ye=F[q].labels;delete F[q].channels,delete F[q].labels,Object.defineProperty(F[q],"channels",{value:de}),Object.defineProperty(F[q],"labels",{value:ye})}function Ue(Oe,Xe){return Math.pow(Oe[0]-Xe[0],2)+Math.pow(Oe[1]-Xe[1],2)+Math.pow(Oe[2]-Xe[2],2)}F.rgb.hsl=function(Oe){var ir,Pi,Xe=Oe[0]/255,gt=Oe[1]/255,yt=Oe[2]/255,nn=Math.min(Xe,gt,yt),Pn=Math.max(Xe,gt,yt),xn=Pn-nn;return Pn===nn?ir=0:Xe===Pn?ir=(gt-yt)/xn:gt===Pn?ir=2+(yt-Xe)/xn:yt===Pn&&(ir=4+(Xe-gt)/xn),(ir=Math.min(60*ir,360))<0&&(ir+=360),Pi=(nn+Pn)/2,[ir,100*(Pn===nn?0:Pi<=.5?xn/(Pn+nn):xn/(2-Pn-nn)),100*Pi]},F.rgb.hsv=function(Oe){var Xe,gt,yt,nn,Pn,xn=Oe[0]/255,ir=Oe[1]/255,Gr=Oe[2]/255,Pi=Math.max(xn,ir,Gr),Zo=Pi-Math.min(xn,ir,Gr),Lo=function(Gs){return(Pi-Gs)/6/Zo+.5};return 0===Zo?nn=Pn=0:(Pn=Zo/Pi,Xe=Lo(xn),gt=Lo(ir),yt=Lo(Gr),xn===Pi?nn=yt-gt:ir===Pi?nn=1/3+Xe-yt:Gr===Pi&&(nn=2/3+gt-Xe),nn<0?nn+=1:nn>1&&(nn-=1)),[360*nn,100*Pn,100*Pi]},F.rgb.hwb=function(Oe){var Xe=Oe[0],gt=Oe[1],yt=Oe[2];return[F.rgb.hsl(Oe)[0],1/255*Math.min(Xe,Math.min(gt,yt))*100,100*(yt=1-1/255*Math.max(Xe,Math.max(gt,yt)))]},F.rgb.cmyk=function(Oe){var ir,Xe=Oe[0]/255,gt=Oe[1]/255,yt=Oe[2]/255;return[100*((1-Xe-(ir=Math.min(1-Xe,1-gt,1-yt)))/(1-ir)||0),100*((1-gt-ir)/(1-ir)||0),100*((1-yt-ir)/(1-ir)||0),100*ir]},F.rgb.keyword=function(Oe){var Xe=E[Oe];if(Xe)return Xe;var yt,gt=1/0;for(var nn in d)if(d.hasOwnProperty(nn)){var xn=Ue(Oe,d[nn]);xn<gt&&(gt=xn,yt=nn)}return yt},F.keyword.rgb=function(Oe){return d[Oe]},F.rgb.xyz=function(Oe){var Xe=Oe[0]/255,gt=Oe[1]/255,yt=Oe[2]/255;return[100*(.4124*(Xe=Xe>.04045?Math.pow((Xe+.055)/1.055,2.4):Xe/12.92)+.3576*(gt=gt>.04045?Math.pow((gt+.055)/1.055,2.4):gt/12.92)+.1805*(yt=yt>.04045?Math.pow((yt+.055)/1.055,2.4):yt/12.92)),100*(.2126*Xe+.7152*gt+.0722*yt),100*(.0193*Xe+.1192*gt+.9505*yt)]},F.rgb.lab=function(Oe){var Xe=F.rgb.xyz(Oe),gt=Xe[0],yt=Xe[1],nn=Xe[2];return yt/=100,nn/=108.883,gt=(gt/=95.047)>.008856?Math.pow(gt,1/3):7.787*gt+16/116,[116*(yt=yt>.008856?Math.pow(yt,1/3):7.787*yt+16/116)-16,500*(gt-yt),200*(yt-(nn=nn>.008856?Math.pow(nn,1/3):7.787*nn+16/116))]},F.hsl.rgb=function(Oe){var nn,Pn,xn,ir,Gr,Xe=Oe[0]/360,gt=Oe[1]/100,yt=Oe[2]/100;if(0===gt)return[Gr=255*yt,Gr,Gr];nn=2*yt-(Pn=yt<.5?yt*(1+gt):yt+gt-yt*gt),ir=[0,0,0];for(var Pi=0;Pi<3;Pi++)(xn=Xe+1/3*-(Pi-1))<0&&xn++,xn>1&&xn--,ir[Pi]=255*(Gr=6*xn<1?nn+6*(Pn-nn)*xn:2*xn<1?Pn:3*xn<2?nn+(Pn-nn)*(2/3-xn)*6:nn);return ir},F.hsl.hsv=function(Oe){var Xe=Oe[0],gt=Oe[1]/100,yt=Oe[2]/100,nn=gt,Pn=Math.max(yt,.01);return gt*=(yt*=2)<=1?yt:2-yt,nn*=Pn<=1?Pn:2-Pn,[Xe,100*(0===yt?2*nn/(Pn+nn):2*gt/(yt+gt)),(yt+gt)/2*100]},F.hsv.rgb=function(Oe){var Xe=Oe[0]/60,gt=Oe[1]/100,yt=Oe[2]/100,nn=Math.floor(Xe)%6,Pn=Xe-Math.floor(Xe),xn=255*yt*(1-gt),ir=255*yt*(1-gt*Pn),Gr=255*yt*(1-gt*(1-Pn));switch(yt*=255,nn){case 0:return[yt,Gr,xn];case 1:return[ir,yt,xn];case 2:return[xn,yt,Gr];case 3:return[xn,ir,yt];case 4:return[Gr,xn,yt];case 5:return[yt,xn,ir]}},F.hsv.hsl=function(Oe){var Pn,xn,ir,Xe=Oe[0],gt=Oe[1]/100,yt=Oe[2]/100,nn=Math.max(yt,.01);return ir=(2-gt)*yt,xn=gt*nn,[Xe,100*(xn=(xn/=(Pn=(2-gt)*nn)<=1?Pn:2-Pn)||0),100*(ir/=2)]},F.hwb.rgb=function(Oe){var Pn,xn,ir,Gr,Pi,Zo,Lo,Xe=Oe[0]/360,gt=Oe[1]/100,yt=Oe[2]/100,nn=gt+yt;switch(nn>1&&(gt/=nn,yt/=nn),ir=6*Xe-(Pn=Math.floor(6*Xe)),0!=(1&Pn)&&(ir=1-ir),Gr=gt+ir*((xn=1-yt)-gt),Pn){default:case 6:case 0:Pi=xn,Zo=Gr,Lo=gt;break;case 1:Pi=Gr,Zo=xn,Lo=gt;break;case 2:Pi=gt,Zo=xn,Lo=Gr;break;case 3:Pi=gt,Zo=Gr,Lo=xn;break;case 4:Pi=Gr,Zo=gt,Lo=xn;break;case 5:Pi=xn,Zo=gt,Lo=Gr}return[255*Pi,255*Zo,255*Lo]},F.cmyk.rgb=function(Oe){var gt=Oe[1]/100,yt=Oe[2]/100,nn=Oe[3]/100;return[255*(1-Math.min(1,Oe[0]/100*(1-nn)+nn)),255*(1-Math.min(1,gt*(1-nn)+nn)),255*(1-Math.min(1,yt*(1-nn)+nn))]},F.xyz.rgb=function(Oe){var nn,Pn,xn,Xe=Oe[0]/100,gt=Oe[1]/100,yt=Oe[2]/100;return Pn=-.9689*Xe+1.8758*gt+.0415*yt,xn=.0557*Xe+-.204*gt+1.057*yt,nn=(nn=3.2406*Xe+-1.5372*gt+-.4986*yt)>.0031308?1.055*Math.pow(nn,1/2.4)-.055:12.92*nn,Pn=Pn>.0031308?1.055*Math.pow(Pn,1/2.4)-.055:12.92*Pn,xn=xn>.0031308?1.055*Math.pow(xn,1/2.4)-.055:12.92*xn,[255*(nn=Math.min(Math.max(0,nn),1)),255*(Pn=Math.min(Math.max(0,Pn),1)),255*(xn=Math.min(Math.max(0,xn),1))]},F.xyz.lab=function(Oe){var Xe=Oe[0],gt=Oe[1],yt=Oe[2];return gt/=100,yt/=108.883,Xe=(Xe/=95.047)>.008856?Math.pow(Xe,1/3):7.787*Xe+16/116,[116*(gt=gt>.008856?Math.pow(gt,1/3):7.787*gt+16/116)-16,500*(Xe-gt),200*(gt-(yt=yt>.008856?Math.pow(yt,1/3):7.787*yt+16/116))]},F.lab.xyz=function(Oe){var nn,Pn,xn;nn=Oe[1]/500+(Pn=(Oe[0]+16)/116),xn=Pn-Oe[2]/200;var ir=Math.pow(Pn,3),Gr=Math.pow(nn,3),Pi=Math.pow(xn,3);return Pn=ir>.008856?ir:(Pn-16/116)/7.787,nn=Gr>.008856?Gr:(nn-16/116)/7.787,xn=Pi>.008856?Pi:(xn-16/116)/7.787,[nn*=95.047,Pn*=100,xn*=108.883]},F.lab.lch=function(Oe){var Pn,Xe=Oe[0],gt=Oe[1],yt=Oe[2];return(Pn=360*Math.atan2(yt,gt)/2/Math.PI)<0&&(Pn+=360),[Xe,Math.sqrt(gt*gt+yt*yt),Pn]},F.lch.lab=function(Oe){var xn,gt=Oe[1];return xn=Oe[2]/360*2*Math.PI,[Oe[0],gt*Math.cos(xn),gt*Math.sin(xn)]},F.rgb.ansi16=function(Oe){var Xe=Oe[0],gt=Oe[1],yt=Oe[2],nn=1 in arguments?arguments[1]:F.rgb.hsv(Oe)[2];if(0===(nn=Math.round(nn/50)))return 30;var Pn=30+(Math.round(yt/255)<<2|Math.round(gt/255)<<1|Math.round(Xe/255));return 2===nn&&(Pn+=60),Pn},F.hsv.ansi16=function(Oe){return F.rgb.ansi16(F.hsv.rgb(Oe),Oe[2])},F.rgb.ansi256=function(Oe){var Xe=Oe[0],gt=Oe[1],yt=Oe[2];return Xe===gt&&gt===yt?Xe<8?16:Xe>248?231:Math.round((Xe-8)/247*24)+232:16+36*Math.round(Xe/255*5)+6*Math.round(gt/255*5)+Math.round(yt/255*5)},F.ansi16.rgb=function(Oe){var Xe=Oe%10;if(0===Xe||7===Xe)return Oe>50&&(Xe+=3.5),[Xe=Xe/10.5*255,Xe,Xe];var gt=.5*(1+~~(Oe>50));return[(1&Xe)*gt*255,(Xe>>1&1)*gt*255,(Xe>>2&1)*gt*255]},F.ansi256.rgb=function(Oe){if(Oe>=232){var Xe=10*(Oe-232)+8;return[Xe,Xe,Xe]}var gt;return Oe-=16,[Math.floor(Oe/36)/5*255,Math.floor((gt=Oe%36)/6)/5*255,gt%6/5*255]},F.rgb.hex=function(Oe){var gt=(((255&Math.round(Oe[0]))<<16)+((255&Math.round(Oe[1]))<<8)+(255&Math.round(Oe[2]))).toString(16).toUpperCase();return"000000".substring(gt.length)+gt},F.hex.rgb=function(Oe){var Xe=Oe.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!Xe)return[0,0,0];var gt=Xe[0];3===Xe[0].length&&(gt=gt.split("").map(function(ir){return ir+ir}).join(""));var yt=parseInt(gt,16);return[yt>>16&255,yt>>8&255,255&yt]},F.rgb.hcg=function(Oe){var Gr,Xe=Oe[0]/255,gt=Oe[1]/255,yt=Oe[2]/255,nn=Math.max(Math.max(Xe,gt),yt),Pn=Math.min(Math.min(Xe,gt),yt),xn=nn-Pn;return Gr=xn<=0?0:nn===Xe?(gt-yt)/xn%6:nn===gt?2+(yt-Xe)/xn:4+(Xe-gt)/xn+4,Gr/=6,[360*(Gr%=1),100*xn,100*(xn<1?Pn/(1-xn):0)]},F.hsl.hcg=function(Oe){var yt,Xe=Oe[1]/100,gt=Oe[2]/100,nn=0;return(yt=gt<.5?2*Xe*gt:2*Xe*(1-gt))<1&&(nn=(gt-.5*yt)/(1-yt)),[Oe[0],100*yt,100*nn]},F.hsv.hcg=function(Oe){var gt=Oe[2]/100,yt=Oe[1]/100*gt,nn=0;return yt<1&&(nn=(gt-yt)/(1-yt)),[Oe[0],100*yt,100*nn]},F.hcg.rgb=function(Oe){var gt=Oe[1]/100,yt=Oe[2]/100;if(0===gt)return[255*yt,255*yt,255*yt];var Gr,nn=[0,0,0],Pn=Oe[0]/360%1*6,xn=Pn%1,ir=1-xn;switch(Math.floor(Pn)){case 0:nn[0]=1,nn[1]=xn,nn[2]=0;break;case 1:nn[0]=ir,nn[1]=1,nn[2]=0;break;case 2:nn[0]=0,nn[1]=1,nn[2]=xn;break;case 3:nn[0]=0,nn[1]=ir,nn[2]=1;break;case 4:nn[0]=xn,nn[1]=0,nn[2]=1;break;default:nn[0]=1,nn[1]=0,nn[2]=ir}return[255*(gt*nn[0]+(Gr=(1-gt)*yt)),255*(gt*nn[1]+Gr),255*(gt*nn[2]+Gr)]},F.hcg.hsv=function(Oe){var Xe=Oe[1]/100,yt=Xe+Oe[2]/100*(1-Xe),nn=0;return yt>0&&(nn=Xe/yt),[Oe[0],100*nn,100*yt]},F.hcg.hsl=function(Oe){var Xe=Oe[1]/100,yt=Oe[2]/100*(1-Xe)+.5*Xe,nn=0;return yt>0&&yt<.5?nn=Xe/(2*yt):yt>=.5&&yt<1&&(nn=Xe/(2*(1-yt))),[Oe[0],100*nn,100*yt]},F.hcg.hwb=function(Oe){var Xe=Oe[1]/100,yt=Xe+Oe[2]/100*(1-Xe);return[Oe[0],100*(yt-Xe),100*(1-yt)]},F.hwb.hcg=function(Oe){var yt=1-Oe[2]/100,nn=yt-Oe[1]/100,Pn=0;return nn<1&&(Pn=(yt-nn)/(1-nn)),[Oe[0],100*nn,100*Pn]},F.apple.rgb=function(Oe){return[Oe[0]/65535*255,Oe[1]/65535*255,Oe[2]/65535*255]},F.rgb.apple=function(Oe){return[Oe[0]/255*65535,Oe[1]/255*65535,Oe[2]/255*65535]},F.gray.rgb=function(Oe){return[Oe[0]/100*255,Oe[0]/100*255,Oe[0]/100*255]},F.gray.hsl=F.gray.hsv=function(Oe){return[0,0,Oe[0]]},F.gray.hwb=function(Oe){return[0,100,Oe[0]]},F.gray.cmyk=function(Oe){return[0,0,0,Oe[0]]},F.gray.lab=function(Oe){return[Oe[0],0,0]},F.gray.hex=function(Oe){var Xe=255&Math.round(Oe[0]/100*255),yt=((Xe<<16)+(Xe<<8)+Xe).toString(16).toUpperCase();return"000000".substring(yt.length)+yt},F.rgb.gray=function(Oe){return[(Oe[0]+Oe[1]+Oe[2])/3/255*100]}});function he(h){var E=function(){for(var h={},E=Object.keys(e),R=E.length,F=0;F<R;F++)h[E[F]]={distance:-1,parent:null};return h}(),R=[h];for(E[h].distance=0;R.length;)for(var F=R.pop(),q=Object.keys(e[F]),de=q.length,ye=0;ye<de;ye++){var Ue=q[ye],Oe=E[Ue];-1===Oe.distance&&(Oe.distance=E[F].distance+1,Oe.parent=F,R.unshift(Ue))}return E}function ge(h,E){return function(R){return E(h(R))}}function De(h,E){for(var R=[E[h].parent,h],F=e[E[h].parent][h],q=E[h].parent;E[q].parent;)R.unshift(E[q].parent),F=ge(e[E[q].parent][q],F),q=E[q].parent;return F.conversion=R,F}var lt={};Object.keys(e).forEach(function(h){lt[h]={},Object.defineProperty(lt[h],"channels",{value:e[h].channels}),Object.defineProperty(lt[h],"labels",{value:e[h].labels});var E=function(h){for(var E=he(h),R={},F=Object.keys(E),q=F.length,de=0;de<q;de++){var ye=F[de];null!==E[ye].parent&&(R[ye]=De(ye,E))}return R}(h);Object.keys(E).forEach(function(F){var q=E[F];lt[h][F]=function(h){var E=function(R){if(null==R)return R;arguments.length>1&&(R=Array.prototype.slice.call(arguments));var F=h(R);if("object"==typeof F)for(var q=F.length,de=0;de<q;de++)F[de]=Math.round(F[de]);return F};return"conversion"in h&&(E.conversion=h.conversion),E}(q),lt[h][F].raw=function(h){var E=function(R){return null==R?R:(arguments.length>1&&(R=Array.prototype.slice.call(arguments)),h(R))};return"conversion"in h&&(E.conversion=h.conversion),E}(q)})});var Pe=lt,je={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},He={getRgba:Vt,getHsla:it,getRgb:function(h){var E=Vt(h);return E&&E.slice(0,3)},getHsl:function(h){var E=it(h);return E&&E.slice(0,3)},getHwb:tn,getAlpha:function(h){var E=Vt(h);return E||(E=it(h))||(E=tn(h))?E[3]:void 0},hexString:function(h,E){return E=void 0!==E&&3===h.length?E:h[3],"#"+Kr(h[0])+Kr(h[1])+Kr(h[2])+(E>=0&&E<1?Kr(Math.round(255*E)):"")},rgbString:function(h,E){return E<1||h[3]&&h[3]<1?Gt(h,E):"rgb("+h[0]+", "+h[1]+", "+h[2]+")"},rgbaString:Gt,percentString:function(h,E){return E<1||h[3]&&h[3]<1?Xt(h,E):"rgb("+Math.round(h[0]/255*100)+"%, "+Math.round(h[1]/255*100)+"%, "+Math.round(h[2]/255*100)+"%)"},percentaString:Xt,hslString:function(h,E){return E<1||h[3]&&h[3]<1?Ur(h,E):"hsl("+h[0]+", "+h[1]+"%, "+h[2]+"%)"},hslaString:Ur,hwbString:function(h,E){return void 0===E&&(E=void 0!==h[3]?h[3]:1),"hwb("+h[0]+", "+h[1]+"%, "+h[2]+"%"+(void 0!==E&&1!==E?", "+E:"")+")"},keyword:function(h){return ei[h.slice(0,3)]}};function Vt(h){if(h){var ye=[0,0,0],Ue=1,Oe=h.match(/^#([a-fA-F0-9]{3,4})$/i),Xe="";if(Oe){Xe=(Oe=Oe[1])[3];for(var gt=0;gt<ye.length;gt++)ye[gt]=parseInt(Oe[gt]+Oe[gt],16);Xe&&(Ue=Math.round(parseInt(Xe+Xe,16)/255*100)/100)}else if(Oe=h.match(/^#([a-fA-F0-9]{6}([a-fA-F0-9]{2})?)$/i)){for(Xe=Oe[2],Oe=Oe[1],gt=0;gt<ye.length;gt++)ye[gt]=parseInt(Oe.slice(2*gt,2*gt+2),16);Xe&&(Ue=Math.round(parseInt(Xe,16)/255*100)/100)}else if(Oe=h.match(/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(gt=0;gt<ye.length;gt++)ye[gt]=parseInt(Oe[gt+1]);Ue=parseFloat(Oe[4])}else if(Oe=h.match(/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(gt=0;gt<ye.length;gt++)ye[gt]=Math.round(2.55*parseFloat(Oe[gt+1]));Ue=parseFloat(Oe[4])}else if(Oe=h.match(/(\w+)/)){if("transparent"==Oe[1])return[0,0,0,0];if(!(ye=je[Oe[1]]))return}for(gt=0;gt<ye.length;gt++)ye[gt]=Mr(ye[gt],0,255);return Ue=Ue||0==Ue?Mr(Ue,0,1):1,ye[3]=Ue,ye}}function it(h){if(h){var R=h.match(/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/);if(R){var F=parseFloat(R[4]);return[Mr(parseInt(R[1]),0,360),Mr(parseFloat(R[2]),0,100),Mr(parseFloat(R[3]),0,100),Mr(isNaN(F)?1:F,0,1)]}}}function tn(h){if(h){var R=h.match(/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/);if(R){var F=parseFloat(R[4]);return[Mr(parseInt(R[1]),0,360),Mr(parseFloat(R[2]),0,100),Mr(parseFloat(R[3]),0,100),Mr(isNaN(F)?1:F,0,1)]}}}function Gt(h,E){return void 0===E&&(E=void 0!==h[3]?h[3]:1),"rgba("+h[0]+", "+h[1]+", "+h[2]+", "+E+")"}function Xt(h,E){return"rgba("+Math.round(h[0]/255*100)+"%, "+Math.round(h[1]/255*100)+"%, "+Math.round(h[2]/255*100)+"%, "+(E||h[3]||1)+")"}function Ur(h,E){return void 0===E&&(E=void 0!==h[3]?h[3]:1),"hsla("+h[0]+", "+h[1]+"%, "+h[2]+"%, "+E+")"}function Mr(h,E,R){return Math.min(Math.max(E,h),R)}function Kr(h){var E=h.toString(16).toUpperCase();return E.length<2?"0"+E:E}var ei={};for(var Nn in je)ei[je[Nn]]=Nn;var $n=function(h){return h instanceof $n?h:this instanceof $n?(this.valid=!1,this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1},void("string"==typeof h?(E=He.getRgba(h))?this.setValues("rgb",E):(E=He.getHsla(h))?this.setValues("hsl",E):(E=He.getHwb(h))&&this.setValues("hwb",E):"object"==typeof h&&(void 0!==(E=h).r||void 0!==E.red?this.setValues("rgb",E):void 0!==E.l||void 0!==E.lightness?this.setValues("hsl",E):void 0!==E.v||void 0!==E.value?this.setValues("hsv",E):void 0!==E.w||void 0!==E.whiteness?this.setValues("hwb",E):(void 0!==E.c||void 0!==E.cyan)&&this.setValues("cmyk",E)))):new $n(h);var E};$n.prototype={isValid:function(){return this.valid},rgb:function(){return this.setSpace("rgb",arguments)},hsl:function(){return this.setSpace("hsl",arguments)},hsv:function(){return this.setSpace("hsv",arguments)},hwb:function(){return this.setSpace("hwb",arguments)},cmyk:function(){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){var h=this.values;return 1!==h.alpha?h.hwb.concat([h.alpha]):h.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var h=this.values;return h.rgb.concat([h.alpha])},hslaArray:function(){var h=this.values;return h.hsl.concat([h.alpha])},alpha:function(h){return void 0===h?this.values.alpha:(this.setValues("alpha",h),this)},red:function(h){return this.setChannel("rgb",0,h)},green:function(h){return this.setChannel("rgb",1,h)},blue:function(h){return this.setChannel("rgb",2,h)},hue:function(h){return h&&(h=(h%=360)<0?360+h:h),this.setChannel("hsl",0,h)},saturation:function(h){return this.setChannel("hsl",1,h)},lightness:function(h){return this.setChannel("hsl",2,h)},saturationv:function(h){return this.setChannel("hsv",1,h)},whiteness:function(h){return this.setChannel("hwb",1,h)},blackness:function(h){return this.setChannel("hwb",2,h)},value:function(h){return this.setChannel("hsv",2,h)},cyan:function(h){return this.setChannel("cmyk",0,h)},magenta:function(h){return this.setChannel("cmyk",1,h)},yellow:function(h){return this.setChannel("cmyk",2,h)},black:function(h){return this.setChannel("cmyk",3,h)},hexString:function(){return He.hexString(this.values.rgb)},rgbString:function(){return He.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return He.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return He.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return He.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return He.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return He.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return He.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){var h=this.values.rgb;return h[0]<<16|h[1]<<8|h[2]},luminosity:function(){for(var h=this.values.rgb,E=[],R=0;R<h.length;R++){var F=h[R]/255;E[R]=F<=.03928?F/12.92:Math.pow((F+.055)/1.055,2.4)}return.2126*E[0]+.7152*E[1]+.0722*E[2]},contrast:function(h){var E=this.luminosity(),R=h.luminosity();return E>R?(E+.05)/(R+.05):(R+.05)/(E+.05)},level:function(h){var E=this.contrast(h);return E>=7.1?"AAA":E>=4.5?"AA":""},dark:function(){var h=this.values.rgb;return(299*h[0]+587*h[1]+114*h[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var h=[],E=0;E<3;E++)h[E]=255-this.values.rgb[E];return this.setValues("rgb",h),this},lighten:function(h){var E=this.values.hsl;return E[2]+=E[2]*h,this.setValues("hsl",E),this},darken:function(h){var E=this.values.hsl;return E[2]-=E[2]*h,this.setValues("hsl",E),this},saturate:function(h){var E=this.values.hsl;return E[1]+=E[1]*h,this.setValues("hsl",E),this},desaturate:function(h){var E=this.values.hsl;return E[1]-=E[1]*h,this.setValues("hsl",E),this},whiten:function(h){var E=this.values.hwb;return E[1]+=E[1]*h,this.setValues("hwb",E),this},blacken:function(h){var E=this.values.hwb;return E[2]+=E[2]*h,this.setValues("hwb",E),this},greyscale:function(){var h=this.values.rgb,E=.3*h[0]+.59*h[1]+.11*h[2];return this.setValues("rgb",[E,E,E]),this},clearer:function(h){var E=this.values.alpha;return this.setValues("alpha",E-E*h),this},opaquer:function(h){var E=this.values.alpha;return this.setValues("alpha",E+E*h),this},rotate:function(h){var E=this.values.hsl,R=(E[0]+h)%360;return E[0]=R<0?360+R:R,this.setValues("hsl",E),this},mix:function(h,E){var R=this,F=h,q=void 0===E?.5:E,de=2*q-1,ye=R.alpha()-F.alpha(),Ue=((de*ye==-1?de:(de+ye)/(1+de*ye))+1)/2,Oe=1-Ue;return this.rgb(Ue*R.red()+Oe*F.red(),Ue*R.green()+Oe*F.green(),Ue*R.blue()+Oe*F.blue()).alpha(R.alpha()*q+F.alpha()*(1-q))},toJSON:function(){return this.rgb()},clone:function(){var F,q,h=new $n,E=this.values,R=h.values;for(var de in E)E.hasOwnProperty(de)&&("[object Array]"===(q={}.toString.call(F=E[de]))?R[de]=F.slice(0):"[object Number]"===q?R[de]=F:console.error("unexpected color value:",F));return h}},$n.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},$n.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},$n.prototype.getValues=function(h){for(var E=this.values,R={},F=0;F<h.length;F++)R[h.charAt(F)]=E[h][F];return 1!==E.alpha&&(R.a=E.alpha),R},$n.prototype.setValues=function(h,E){var ye,Oe,R=this.values,F=this.spaces,q=this.maxes,de=1;if(this.valid=!0,"alpha"===h)de=E;else if(E.length)R[h]=E.slice(0,h.length),de=E[h.length];else if(void 0!==E[h.charAt(0)]){for(ye=0;ye<h.length;ye++)R[h][ye]=E[h.charAt(ye)];de=E.a}else if(void 0!==E[F[h][0]]){var Ue=F[h];for(ye=0;ye<h.length;ye++)R[h][ye]=E[Ue[ye]];de=E.alpha}if(R.alpha=Math.max(0,Math.min(1,void 0===de?R.alpha:de)),"alpha"===h)return!1;for(ye=0;ye<h.length;ye++)Oe=Math.max(0,Math.min(q[h][ye],R[h][ye])),R[h][ye]=Math.round(Oe);for(var Xe in F)Xe!==h&&(R[Xe]=Pe[h][Xe](R[h]));return!0},$n.prototype.setSpace=function(h,E){var R=E[0];return void 0===R?this.getValues(h):("number"==typeof R&&(R=Array.prototype.slice.call(E)),this.setValues(h,R),this)},$n.prototype.setChannel=function(h,E,R){var F=this.values[h];return void 0===R?F[E]:(R===F[E]||(F[E]=R,this.setValues(h,F)),this)},"undefined"!=typeof window&&(window.Color=$n);var Br=$n;function Yr(h){return-1===["__proto__","prototype","constructor"].indexOf(h)}var h,fi={noop:function(){},uid:(h=0,function(){return h++}),isNullOrUndef:function(h){return null==h},isArray:function(h){if(Array.isArray&&Array.isArray(h))return!0;var E=Object.prototype.toString.call(h);return"[object"===E.substr(0,7)&&"Array]"===E.substr(-6)},isObject:function(h){return null!==h&&"[object Object]"===Object.prototype.toString.call(h)},isFinite:function(h){return("number"==typeof h||h instanceof Number)&&isFinite(h)},valueOrDefault:function(h,E){return void 0===h?E:h},valueAtIndexOrDefault:function(h,E,R){return fi.valueOrDefault(fi.isArray(h)?h[E]:h,R)},callback:function(h,E,R){if(h&&"function"==typeof h.call)return h.apply(R,E)},each:function(h,E,R,F){var q,de,ye;if(fi.isArray(h))if(de=h.length,F)for(q=de-1;q>=0;q--)E.call(R,h[q],q);else for(q=0;q<de;q++)E.call(R,h[q],q);else if(fi.isObject(h))for(de=(ye=Object.keys(h)).length,q=0;q<de;q++)E.call(R,h[ye[q]],ye[q])},arrayEquals:function(h,E){var R,F,q,de;if(!h||!E||h.length!==E.length)return!1;for(R=0,F=h.length;R<F;++R)if(de=E[R],(q=h[R])instanceof Array&&de instanceof Array){if(!fi.arrayEquals(q,de))return!1}else if(q!==de)return!1;return!0},clone:function(h){if(fi.isArray(h))return h.map(fi.clone);if(fi.isObject(h)){for(var E=Object.create(h),R=Object.keys(h),F=R.length,q=0;q<F;++q)E[R[q]]=fi.clone(h[R[q]]);return E}return h},_merger:function(h,E,R,F){if(Yr(h)){var q=E[h],de=R[h];fi.isObject(q)&&fi.isObject(de)?fi.merge(q,de,F):E[h]=fi.clone(de)}},_mergerIf:function(h,E,R){if(Yr(h)){var F=E[h],q=R[h];fi.isObject(F)&&fi.isObject(q)?fi.mergeIf(F,q):E.hasOwnProperty(h)||(E[h]=fi.clone(q))}},merge:function(h,E,R){var de,ye,Ue,Oe,Xe,F=fi.isArray(E)?E:[E],q=F.length;if(!fi.isObject(h))return h;for(de=(R=R||{}).merger||fi._merger,ye=0;ye<q;++ye)if(fi.isObject(E=F[ye]))for(Xe=0,Oe=(Ue=Object.keys(E)).length;Xe<Oe;++Xe)de(Ue[Xe],h,E,R);return h},mergeIf:function(h,E){return fi.merge(h,E,{merger:fi._mergerIf})},extend:Object.assign||function(h){return fi.merge(h,[].slice.call(arguments,1),{merger:function(E,R,F){R[E]=F[E]}})},inherits:function(h){var E=this,R=h&&h.hasOwnProperty("constructor")?h.constructor:function(){return E.apply(this,arguments)},F=function(){this.constructor=R};return F.prototype=E.prototype,R.prototype=new F,R.extend=fi.inherits,h&&fi.extend(R.prototype,h),R.__super__=E.prototype,R},_deprecated:function(h,E,R,F){void 0!==E&&console.warn(h+': "'+R+'" is deprecated. Please use "'+F+'" instead')}},ki=fi;fi.callCallback=fi.callback,fi.indexOf=function(h,E,R){return Array.prototype.indexOf.call(h,E,R)},fi.getValueOrDefault=fi.valueOrDefault,fi.getValueAtIndexOrDefault=fi.valueAtIndexOrDefault;var Hi={linear:function(h){return h},easeInQuad:function(h){return h*h},easeOutQuad:function(h){return-h*(h-2)},easeInOutQuad:function(h){return(h/=.5)<1?.5*h*h:-.5*(--h*(h-2)-1)},easeInCubic:function(h){return h*h*h},easeOutCubic:function(h){return(h-=1)*h*h+1},easeInOutCubic:function(h){return(h/=.5)<1?.5*h*h*h:.5*((h-=2)*h*h+2)},easeInQuart:function(h){return h*h*h*h},easeOutQuart:function(h){return-((h-=1)*h*h*h-1)},easeInOutQuart:function(h){return(h/=.5)<1?.5*h*h*h*h:-.5*((h-=2)*h*h*h-2)},easeInQuint:function(h){return h*h*h*h*h},easeOutQuint:function(h){return(h-=1)*h*h*h*h+1},easeInOutQuint:function(h){return(h/=.5)<1?.5*h*h*h*h*h:.5*((h-=2)*h*h*h*h+2)},easeInSine:function(h){return 1-Math.cos(h*(Math.PI/2))},easeOutSine:function(h){return Math.sin(h*(Math.PI/2))},easeInOutSine:function(h){return-.5*(Math.cos(Math.PI*h)-1)},easeInExpo:function(h){return 0===h?0:Math.pow(2,10*(h-1))},easeOutExpo:function(h){return 1===h?1:1-Math.pow(2,-10*h)},easeInOutExpo:function(h){return 0===h?0:1===h?1:(h/=.5)<1?.5*Math.pow(2,10*(h-1)):.5*(2-Math.pow(2,-10*--h))},easeInCirc:function(h){return h>=1?h:-(Math.sqrt(1-h*h)-1)},easeOutCirc:function(h){return Math.sqrt(1-(h-=1)*h)},easeInOutCirc:function(h){return(h/=.5)<1?-.5*(Math.sqrt(1-h*h)-1):.5*(Math.sqrt(1-(h-=2)*h)+1)},easeInElastic:function(h){var E=1.70158,R=0,F=1;return 0===h?0:1===h?1:(R||(R=.3),F<1?(F=1,E=R/4):E=R/(2*Math.PI)*Math.asin(1/F),-F*Math.pow(2,10*(h-=1))*Math.sin((h-E)*(2*Math.PI)/R))},easeOutElastic:function(h){var E=1.70158,R=0,F=1;return 0===h?0:1===h?1:(R||(R=.3),F<1?(F=1,E=R/4):E=R/(2*Math.PI)*Math.asin(1/F),F*Math.pow(2,-10*h)*Math.sin((h-E)*(2*Math.PI)/R)+1)},easeInOutElastic:function(h){var E=1.70158,R=0,F=1;return 0===h?0:2==(h/=.5)?1:(R||(R=.45),F<1?(F=1,E=R/4):E=R/(2*Math.PI)*Math.asin(1/F),h<1?F*Math.pow(2,10*(h-=1))*Math.sin((h-E)*(2*Math.PI)/R)*-.5:F*Math.pow(2,-10*(h-=1))*Math.sin((h-E)*(2*Math.PI)/R)*.5+1)},easeInBack:function(h){var E=1.70158;return h*h*((E+1)*h-E)},easeOutBack:function(h){var E=1.70158;return(h-=1)*h*((E+1)*h+E)+1},easeInOutBack:function(h){var E=1.70158;return(h/=.5)<1?h*h*((1+(E*=1.525))*h-E)*.5:.5*((h-=2)*h*((1+(E*=1.525))*h+E)+2)},easeInBounce:function(h){return 1-Hi.easeOutBounce(1-h)},easeOutBounce:function(h){return h<1/2.75?7.5625*h*h:h<2/2.75?7.5625*(h-=1.5/2.75)*h+.75:h<2.5/2.75?7.5625*(h-=2.25/2.75)*h+.9375:7.5625*(h-=2.625/2.75)*h+.984375},easeInOutBounce:function(h){return h<.5?.5*Hi.easeInBounce(2*h):.5*Hi.easeOutBounce(2*h-1)+.5}},Zr={effects:Hi};ki.easingEffects=Hi;var Cn=Math.PI,Wt=Cn/180,zn=2*Cn,rr=Cn/2,Fr=Cn/4,Gn=2*Cn/3,Jr={clear:function(h){h.ctx.clearRect(0,0,h.width,h.height)},roundedRect:function(h,E,R,F,q,de){if(de){var ye=Math.min(de,q/2,F/2),Ue=E+ye,Oe=R+ye,Xe=E+F-ye,gt=R+q-ye;h.moveTo(E,Oe),Ue<Xe&&Oe<gt?(h.arc(Ue,Oe,ye,-Cn,-rr),h.arc(Xe,Oe,ye,-rr,0),h.arc(Xe,gt,ye,0,rr),h.arc(Ue,gt,ye,rr,Cn)):Ue<Xe?(h.moveTo(Ue,R),h.arc(Xe,Oe,ye,-rr,rr),h.arc(Ue,Oe,ye,rr,Cn+rr)):Oe<gt?(h.arc(Ue,Oe,ye,-Cn,0),h.arc(Ue,gt,ye,0,Cn)):h.arc(Ue,Oe,ye,-Cn,Cn),h.closePath(),h.moveTo(E,R)}else h.rect(E,R,F,q)},drawPoint:function(h,E,R,F,q,de){var ye,Ue,Oe,Xe,gt,yt=(de||0)*Wt;if(E&&"object"==typeof E&&("[object HTMLImageElement]"===(ye=E.toString())||"[object HTMLCanvasElement]"===ye))return h.save(),h.translate(F,q),h.rotate(yt),h.drawImage(E,-E.width/2,-E.height/2,E.width,E.height),void h.restore();if(!(isNaN(R)||R<=0)){switch(h.beginPath(),E){default:h.arc(F,q,R,0,zn),h.closePath();break;case"triangle":h.moveTo(F+Math.sin(yt)*R,q-Math.cos(yt)*R),yt+=Gn,h.lineTo(F+Math.sin(yt)*R,q-Math.cos(yt)*R),yt+=Gn,h.lineTo(F+Math.sin(yt)*R,q-Math.cos(yt)*R),h.closePath();break;case"rectRounded":Xe=R-(gt=.516*R),Ue=Math.cos(yt+Fr)*Xe,Oe=Math.sin(yt+Fr)*Xe,h.arc(F-Ue,q-Oe,gt,yt-Cn,yt-rr),h.arc(F+Oe,q-Ue,gt,yt-rr,yt),h.arc(F+Ue,q+Oe,gt,yt,yt+rr),h.arc(F-Oe,q+Ue,gt,yt+rr,yt+Cn),h.closePath();break;case"rect":if(!de){Xe=Math.SQRT1_2*R,h.rect(F-Xe,q-Xe,2*Xe,2*Xe);break}yt+=Fr;case"rectRot":Ue=Math.cos(yt)*R,Oe=Math.sin(yt)*R,h.moveTo(F-Ue,q-Oe),h.lineTo(F+Oe,q-Ue),h.lineTo(F+Ue,q+Oe),h.lineTo(F-Oe,q+Ue),h.closePath();break;case"crossRot":yt+=Fr;case"cross":Ue=Math.cos(yt)*R,Oe=Math.sin(yt)*R,h.moveTo(F-Ue,q-Oe),h.lineTo(F+Ue,q+Oe),h.moveTo(F+Oe,q-Ue),h.lineTo(F-Oe,q+Ue);break;case"star":Ue=Math.cos(yt)*R,Oe=Math.sin(yt)*R,h.moveTo(F-Ue,q-Oe),h.lineTo(F+Ue,q+Oe),h.moveTo(F+Oe,q-Ue),h.lineTo(F-Oe,q+Ue),yt+=Fr,Ue=Math.cos(yt)*R,Oe=Math.sin(yt)*R,h.moveTo(F-Ue,q-Oe),h.lineTo(F+Ue,q+Oe),h.moveTo(F+Oe,q-Ue),h.lineTo(F-Oe,q+Ue);break;case"line":Ue=Math.cos(yt)*R,Oe=Math.sin(yt)*R,h.moveTo(F-Ue,q-Oe),h.lineTo(F+Ue,q+Oe);break;case"dash":h.moveTo(F,q),h.lineTo(F+Math.cos(yt)*R,q+Math.sin(yt)*R)}h.fill(),h.stroke()}},_isPointInArea:function(h,E){var R=1e-6;return h.x>E.left-R&&h.x<E.right+R&&h.y>E.top-R&&h.y<E.bottom+R},clipArea:function(h,E){h.save(),h.beginPath(),h.rect(E.left,E.top,E.right-E.left,E.bottom-E.top),h.clip()},unclipArea:function(h){h.restore()},lineTo:function(h,E,R,F){var q=R.steppedLine;if(q){if("middle"===q){var de=(E.x+R.x)/2;h.lineTo(de,F?R.y:E.y),h.lineTo(de,F?E.y:R.y)}else"after"===q&&!F||"after"!==q&&F?h.lineTo(E.x,R.y):h.lineTo(R.x,E.y);h.lineTo(R.x,R.y)}else R.tension?h.bezierCurveTo(F?E.controlPointPreviousX:E.controlPointNextX,F?E.controlPointPreviousY:E.controlPointNextY,F?R.controlPointNextX:R.controlPointPreviousX,F?R.controlPointNextY:R.controlPointPreviousY,R.x,R.y):h.lineTo(R.x,R.y)}},_i=Jr;ki.clear=Jr.clear,ki.drawRoundedRectangle=function(h){h.beginPath(),Jr.roundedRect.apply(Jr,arguments)};var wi={_set:function(h,E){return ki.merge(this[h]||(this[h]={}),E)}};wi._set("global",{defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",defaultLineHeight:1.2,showLines:!0});var br=wi,Dr=ki.valueOrDefault;var yn={toLineHeight:function(h,E){var R=(""+h).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);if(!R||"normal"===R[1])return 1.2*E;switch(h=+R[2],R[3]){case"px":return h;case"%":h/=100}return E*h},toPadding:function(h){var E,R,F,q;return ki.isObject(h)?(E=+h.top||0,R=+h.right||0,F=+h.bottom||0,q=+h.left||0):E=R=F=q=+h||0,{top:E,right:R,bottom:F,left:q,height:E+F,width:q+R}},_parseFont:function(h){var E=br.global,R=Dr(h.fontSize,E.defaultFontSize),F={family:Dr(h.fontFamily,E.defaultFontFamily),lineHeight:ki.options.toLineHeight(Dr(h.lineHeight,E.defaultLineHeight),R),size:R,style:Dr(h.fontStyle,E.defaultFontStyle),weight:null,string:""};return F.string=function(h){return!h||ki.isNullOrUndef(h.size)||ki.isNullOrUndef(h.family)?null:(h.style?h.style+" ":"")+(h.weight?h.weight+" ":"")+h.size+"px "+h.family}(F),F},resolve:function(h,E,R,F){var de,ye,Ue,q=!0;for(de=0,ye=h.length;de<ye;++de)if(void 0!==(Ue=h[de])&&(void 0!==E&&"function"==typeof Ue&&(Ue=Ue(E),q=!1),void 0!==R&&ki.isArray(Ue)&&(Ue=Ue[R],q=!1),void 0!==Ue))return F&&!q&&(F.cacheable=!1),Ue}},gr={_factorize:function(h){var F,E=[],R=Math.sqrt(h);for(F=1;F<R;F++)h%F==0&&(E.push(F),E.push(h/F));return R===(0|R)&&E.push(R),E.sort(function(q,de){return q-de}).pop(),E},log10:Math.log10||function(h){var E=Math.log(h)*Math.LOG10E,R=Math.round(E);return h===Math.pow(10,R)?R:E}},Jt=gr;ki.log10=gr.log10;var Ge=ki,mi=_i,An=yn,Er=Jt,Wr={getRtlAdapter:function(h,E,R){return h?function(h,E){return{x:function(R){return h+h+E-R},setWidth:function(R){E=R},textAlign:function(R){return"center"===R?R:"right"===R?"left":"right"},xPlus:function(R,F){return R-F},leftForLtr:function(R,F){return R-F}}}(E,R):{x:function(h){return h},setWidth:function(h){},textAlign:function(h){return h},xPlus:function(h,E){return h+E},leftForLtr:function(h,E){return h}}},overrideTextDirection:function(h,E){var R,F;("ltr"===E||"rtl"===E)&&(F=[(R=h.canvas.style).getPropertyValue("direction"),R.getPropertyPriority("direction")],R.setProperty("direction",E,"important"),h.prevTextDirection=F)},restoreTextDirection:function(h){var E=h.prevTextDirection;void 0!==E&&(delete h.prevTextDirection,h.canvas.style.setProperty("direction",E[0],E[1]))}};Ge.easing=Zr,Ge.canvas=mi,Ge.options=An,Ge.math=Er,Ge.rtl=Wr;var Fn=function(h){Ge.extend(this,h),this.initialize.apply(this,arguments)};Ge.extend(Fn.prototype,{_type:void 0,initialize:function(){this.hidden=!1},pivot:function(){var h=this;return h._view||(h._view=Ge.extend({},h._model)),h._start={},h},transition:function(h){var E=this,R=E._model,F=E._start,q=E._view;return R&&1!==h?(q||(q=E._view={}),F||(F=E._start={}),function(h,E,R,F){var de,ye,Ue,Oe,Xe,gt,yt,nn,Pn,q=Object.keys(R);for(de=0,ye=q.length;de<ye;++de)if(gt=R[Ue=q[de]],E.hasOwnProperty(Ue)||(E[Ue]=gt),(Oe=E[Ue])!==gt&&"_"!==Ue[0]){if(h.hasOwnProperty(Ue)||(h[Ue]=Oe),(yt=typeof gt)==typeof(Xe=h[Ue]))if("string"===yt){if((nn=Br(Xe)).valid&&(Pn=Br(gt)).valid){E[Ue]=Pn.mix(nn,F).rgbString();continue}}else if(Ge.isFinite(Xe)&&Ge.isFinite(gt)){E[Ue]=Xe+(gt-Xe)*F;continue}E[Ue]=gt}}(F,q,R,h),E):(E._view=Ge.extend({},R),E._start=null,E)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return Ge.isNumber(this._model.x)&&Ge.isNumber(this._model.y)}}),Fn.extend=Ge.inherits;var ar=Fn,Wi=ar.extend({chart:null,currentStep:0,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),lo=Wi;Object.defineProperty(Wi.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(Wi.prototype,"chartInstance",{get:function(){return this.chart},set:function(h){this.chart=h}}),br._set("global",{animation:{duration:1e3,easing:"easeOutQuart",onProgress:Ge.noop,onComplete:Ge.noop}});var vo={animations:[],request:null,addAnimation:function(h,E,R,F){var de,ye,q=this.animations;for(E.chart=h,E.startTime=Date.now(),E.duration=R,F||(h.animating=!0),de=0,ye=q.length;de<ye;++de)if(q[de].chart===h)return void(q[de]=E);q.push(E),1===q.length&&this.requestAnimationFrame()},cancelAnimation:function(h){var E=Ge.findIndex(this.animations,function(R){return R.chart===h});-1!==E&&(this.animations.splice(E,1),h.animating=!1)},requestAnimationFrame:function(){var h=this;null===h.request&&(h.request=Ge.requestAnimFrame.call(window,function(){h.request=null,h.startDigest()}))},startDigest:function(){var h=this;h.advance(),h.animations.length>0&&h.requestAnimationFrame()},advance:function(){for(var E,R,F,q,h=this.animations,de=0;de<h.length;)R=(E=h[de]).chart,F=E.numSteps,q=Math.floor((Date.now()-E.startTime)/E.duration*F)+1,E.currentStep=Math.min(q,F),Ge.callback(E.render,[R,E],R),Ge.callback(E.onAnimationProgress,[E],R),E.currentStep>=F?(Ge.callback(E.onAnimationComplete,[E],R),R.animating=!1,h.splice(de,1)):++de}},Co=Ge.options.resolve,Gi=["push","pop","shift","splice","unshift"];function jo(h,E){var R=h._chartjs;if(R){var F=R.listeners,q=F.indexOf(E);-1!==q&&F.splice(q,1),!(F.length>0)&&(Gi.forEach(function(de){delete h[de]}),delete h._chartjs)}}var To=function(h,E){this.initialize(h,E)};Ge.extend(To.prototype,{datasetElementType:null,dataElementType:null,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth"],_dataElementOptions:["backgroundColor","borderColor","borderWidth","pointStyle"],initialize:function(h,E){var R=this;R.chart=h,R.index=E,R.linkScales(),R.addElements(),R._type=R.getMeta().type},updateIndex:function(h){this.index=h},linkScales:function(){var h=this,E=h.getMeta(),R=h.chart,F=R.scales,q=h.getDataset(),de=R.options.scales;(null===E.xAxisID||!(E.xAxisID in F)||q.xAxisID)&&(E.xAxisID=q.xAxisID||de.xAxes[0].id),(null===E.yAxisID||!(E.yAxisID in F)||q.yAxisID)&&(E.yAxisID=q.yAxisID||de.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(h){return this.chart.scales[h]},_getValueScaleId:function(){return this.getMeta().yAxisID},_getIndexScaleId:function(){return this.getMeta().xAxisID},_getValueScale:function(){return this.getScaleForId(this._getValueScaleId())},_getIndexScale:function(){return this.getScaleForId(this._getIndexScaleId())},reset:function(){this._update(!0)},destroy:function(){this._data&&jo(this._data,this)},createMetaDataset:function(){var h=this,E=h.datasetElementType;return E&&new E({_chart:h.chart,_datasetIndex:h.index})},createMetaData:function(h){var E=this,R=E.dataElementType;return R&&new R({_chart:E.chart,_datasetIndex:E.index,_index:h})},addElements:function(){var q,de,h=this,E=h.getMeta(),R=h.getDataset().data||[],F=E.data;for(q=0,de=R.length;q<de;++q)F[q]=F[q]||h.createMetaData(q);E.dataset=E.dataset||h.createMetaDataset()},addElementAndReset:function(h){var E=this.createMetaData(h);this.getMeta().data.splice(h,0,E),this.updateElement(E,h,!0)},buildOrUpdateElements:function(){var h=this,E=h.getDataset(),R=E.data||(E.data=[]);h._data!==R&&(h._data&&jo(h._data,h),R&&Object.isExtensible(R)&&function(h,E){h._chartjs?h._chartjs.listeners.push(E):(Object.defineProperty(h,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[E]}}),Gi.forEach(function(R){var F="onData"+R.charAt(0).toUpperCase()+R.slice(1),q=h[R];Object.defineProperty(h,R,{configurable:!0,enumerable:!1,value:function(){var de=Array.prototype.slice.call(arguments),ye=q.apply(this,de);return Ge.each(h._chartjs.listeners,function(Ue){"function"==typeof Ue[F]&&Ue[F].apply(Ue,de)}),ye}})}))}(R,h),h._data=R),h.resyncElements()},_configure:function(){var h=this;h._config=Ge.merge(Object.create(null),[h.chart.options.datasets[h._type],h.getDataset()],{merger:function(E,R,F){"_meta"!==E&&"data"!==E&&Ge._merger(E,R,F)}})},_update:function(h){var E=this;E._configure(),E._cachedDataOpts=null,E.update(h)},update:Ge.noop,transition:function(h){for(var E=this.getMeta(),R=E.data||[],F=R.length,q=0;q<F;++q)R[q].transition(h);E.dataset&&E.dataset.transition(h)},draw:function(){var h=this.getMeta(),E=h.data||[],R=E.length,F=0;for(h.dataset&&h.dataset.draw();F<R;++F)E[F].draw()},getStyle:function(h){var q,E=this,R=E.getMeta(),F=R.dataset;return E._configure(),(!1===(q=F&&void 0===h?E._resolveDatasetElementOptions(F||{}):E._resolveDataElementOptions(R.data[h=h||0]||{},h)).fill||null===q.fill)&&(q.backgroundColor=q.borderColor),q},_resolveDatasetElementOptions:function(h,E){var Xe,gt,yt,nn,R=this,F=R.chart,q=R._config,de=h.custom||{},ye=F.options.elements[R.datasetElementType.prototype._type]||{},Ue=R._datasetElementOptions,Oe={},Pn={chart:F,dataset:R.getDataset(),datasetIndex:R.index,hover:E};for(Xe=0,gt=Ue.length;Xe<gt;++Xe)yt=Ue[Xe],nn=E?"hover"+yt.charAt(0).toUpperCase()+yt.slice(1):yt,Oe[yt]=Co([de[nn],q[nn],ye[nn]],Pn);return Oe},_resolveDataElementOptions:function(h,E){var R=this,F=h&&h.custom,q=R._cachedDataOpts;if(q&&!F)return q;var nn,Pn,xn,ir,de=R.chart,ye=R._config,Ue=de.options.elements[R.dataElementType.prototype._type]||{},Oe=R._dataElementOptions,Xe={},gt={chart:de,dataIndex:E,dataset:R.getDataset(),datasetIndex:R.index},yt={cacheable:!F};if(F=F||{},Ge.isArray(Oe))for(Pn=0,xn=Oe.length;Pn<xn;++Pn)Xe[ir=Oe[Pn]]=Co([F[ir],ye[ir],Ue[ir]],gt,E,yt);else for(Pn=0,xn=(nn=Object.keys(Oe)).length;Pn<xn;++Pn)Xe[ir=nn[Pn]]=Co([F[ir],ye[Oe[ir]],ye[ir],Ue[ir]],gt,E,yt);return yt.cacheable&&(R._cachedDataOpts=Object.freeze(Xe)),Xe},removeHoverStyle:function(h){Ge.merge(h._model,h.$previousStyle||{}),delete h.$previousStyle},setHoverStyle:function(h){var E=this.chart.data.datasets[h._datasetIndex],R=h._index,F=h.custom||{},q=h._model,de=Ge.getHoverColor;h.$previousStyle={backgroundColor:q.backgroundColor,borderColor:q.borderColor,borderWidth:q.borderWidth},q.backgroundColor=Co([F.hoverBackgroundColor,E.hoverBackgroundColor,de(q.backgroundColor)],void 0,R),q.borderColor=Co([F.hoverBorderColor,E.hoverBorderColor,de(q.borderColor)],void 0,R),q.borderWidth=Co([F.hoverBorderWidth,E.hoverBorderWidth,q.borderWidth],void 0,R)},_removeDatasetHoverStyle:function(){var h=this.getMeta().dataset;h&&this.removeHoverStyle(h)},_setDatasetHoverStyle:function(){var R,F,q,de,ye,Ue,h=this.getMeta().dataset,E={};if(h){for(Ue=h._model,ye=this._resolveDatasetElementOptions(h,!0),R=0,F=(de=Object.keys(ye)).length;R<F;++R)E[q=de[R]]=Ue[q],Ue[q]=ye[q];h.$previousStyle=E}},resyncElements:function(){var h=this,E=h.getMeta(),R=h.getDataset().data,F=E.data.length,q=R.length;q<F?E.data.splice(q,F-q):q>F&&h.insertElements(F,q-F)},insertElements:function(h,E){for(var R=0;R<E;++R)this.addElementAndReset(h+R)},onDataPush:function(){var h=arguments.length;this.insertElements(this.getDataset().data.length-h,h)},onDataPop:function(){this.getMeta().data.pop()},onDataShift:function(){this.getMeta().data.shift()},onDataSplice:function(h,E){this.getMeta().data.splice(h,E),this.insertElements(h,arguments.length-2)},onDataUnshift:function(){this.insertElements(0,arguments.length)}}),To.extend=Ge.inherits;var Mi=To,li=2*Math.PI;function Bn(h,E){var R=E.startAngle,F=E.endAngle,q=E.pixelMargin,de=q/E.outerRadius,ye=E.x,Ue=E.y;h.beginPath(),h.arc(ye,Ue,E.outerRadius,R-de,F+de),E.innerRadius>q?h.arc(ye,Ue,E.innerRadius-q,F+(de=q/E.innerRadius),R-de,!0):h.arc(ye,Ue,q,F+Math.PI/2,R-Math.PI/2),h.closePath(),h.clip()}function vr(h,E,R){var F="inner"===E.borderAlign;F?(h.lineWidth=2*E.borderWidth,h.lineJoin="round"):(h.lineWidth=E.borderWidth,h.lineJoin="bevel"),R.fullCircles&&function(h,E,R,F){var de,q=R.endAngle;for(F&&(R.endAngle=R.startAngle+li,Bn(h,R),R.endAngle=q,R.endAngle===R.startAngle&&R.fullCircles&&(R.endAngle+=li,R.fullCircles--)),h.beginPath(),h.arc(R.x,R.y,R.innerRadius,R.startAngle+li,R.startAngle,!0),de=0;de<R.fullCircles;++de)h.stroke();for(h.beginPath(),h.arc(R.x,R.y,E.outerRadius,R.startAngle,R.startAngle+li),de=0;de<R.fullCircles;++de)h.stroke()}(h,E,R,F),F&&Bn(h,R),h.beginPath(),h.arc(R.x,R.y,E.outerRadius,R.startAngle,R.endAngle),h.arc(R.x,R.y,R.innerRadius,R.endAngle,R.startAngle,!0),h.closePath(),h.stroke()}br._set("global",{elements:{arc:{backgroundColor:br.global.defaultColor,borderColor:"#fff",borderWidth:2,borderAlign:"center"}}});var er=ar.extend({_type:"arc",inLabelRange:function(h){var E=this._view;return!!E&&Math.pow(h-E.x,2)<Math.pow(E.radius+E.hoverRadius,2)},inRange:function(h,E){var R=this._view;if(R){for(var F=Ge.getAngleFromPoint(R,{x:h,y:E}),q=F.angle,de=F.distance,ye=R.startAngle,Ue=R.endAngle;Ue<ye;)Ue+=li;for(;q>Ue;)q-=li;for(;q<ye;)q+=li;return q>=ye&&q<=Ue&&de>=R.innerRadius&&de<=R.outerRadius}return!1},getCenterPoint:function(){var h=this._view,E=(h.startAngle+h.endAngle)/2,R=(h.innerRadius+h.outerRadius)/2;return{x:h.x+Math.cos(E)*R,y:h.y+Math.sin(E)*R}},getArea:function(){var h=this._view;return Math.PI*((h.endAngle-h.startAngle)/(2*Math.PI))*(Math.pow(h.outerRadius,2)-Math.pow(h.innerRadius,2))},tooltipPosition:function(){var h=this._view,E=h.startAngle+(h.endAngle-h.startAngle)/2,R=(h.outerRadius-h.innerRadius)/2+h.innerRadius;return{x:h.x+Math.cos(E)*R,y:h.y+Math.sin(E)*R}},draw:function(){var q,h=this._chart.ctx,E=this._view,R="inner"===E.borderAlign?.33:0,F={x:E.x,y:E.y,innerRadius:E.innerRadius,outerRadius:Math.max(E.outerRadius-R,0),pixelMargin:R,startAngle:E.startAngle,endAngle:E.endAngle,fullCircles:Math.floor(E.circumference/li)};if(h.save(),h.fillStyle=E.backgroundColor,h.strokeStyle=E.borderColor,F.fullCircles){for(F.endAngle=F.startAngle+li,h.beginPath(),h.arc(F.x,F.y,F.outerRadius,F.startAngle,F.endAngle),h.arc(F.x,F.y,F.innerRadius,F.endAngle,F.startAngle,!0),h.closePath(),q=0;q<F.fullCircles;++q)h.fill();F.endAngle=F.startAngle+E.circumference%li}h.beginPath(),h.arc(F.x,F.y,F.outerRadius,F.startAngle,F.endAngle),h.arc(F.x,F.y,F.innerRadius,F.endAngle,F.startAngle,!0),h.closePath(),h.fill(),E.borderWidth&&vr(h,E,F),h.restore()}}),ri=Ge.valueOrDefault,uo=br.global.defaultColor;br._set("global",{elements:{line:{tension:.4,backgroundColor:uo,borderWidth:3,borderColor:uo,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}});var Ci=ar.extend({_type:"line",draw:function(){var Xe,gt,yt,h=this,E=h._view,R=h._chart.ctx,F=E.spanGaps,q=h._children.slice(),de=br.global,ye=de.elements.line,Ue=-1,Oe=h._loop;if(q.length){if(h._loop){for(Xe=0;Xe<q.length;++Xe)if(gt=Ge.previousItem(q,Xe),!q[Xe]._view.skip&&gt._view.skip){q=q.slice(Xe).concat(q.slice(0,Xe)),Oe=F;break}Oe&&q.push(q[0])}for(R.save(),R.lineCap=E.borderCapStyle||ye.borderCapStyle,R.setLineDash&&R.setLineDash(E.borderDash||ye.borderDash),R.lineDashOffset=ri(E.borderDashOffset,ye.borderDashOffset),R.lineJoin=E.borderJoinStyle||ye.borderJoinStyle,R.lineWidth=ri(E.borderWidth,ye.borderWidth),R.strokeStyle=E.borderColor||de.defaultColor,R.beginPath(),(yt=q[0]._view).skip||(R.moveTo(yt.x,yt.y),Ue=0),Xe=1;Xe<q.length;++Xe)yt=q[Xe]._view,gt=-1===Ue?Ge.previousItem(q,Xe):q[Ue],yt.skip||(Ue!==Xe-1&&!F||-1===Ue?R.moveTo(yt.x,yt.y):Ge.canvas.lineTo(R,gt._view,yt),Ue=Xe);Oe&&R.closePath(),R.stroke(),R.restore()}}}),$o=Ge.valueOrDefault,tr=br.global.defaultColor;function Ar(h){var E=this._view;return!!E&&Math.abs(h-E.x)<E.radius+E.hitRadius}br._set("global",{elements:{point:{radius:3,pointStyle:"circle",backgroundColor:tr,borderColor:tr,borderWidth:1,hitRadius:1,hoverRadius:4,hoverBorderWidth:1}}});var _t=ar.extend({_type:"point",inRange:function(h,E){var R=this._view;return!!R&&Math.pow(h-R.x,2)+Math.pow(E-R.y,2)<Math.pow(R.hitRadius+R.radius,2)},inLabelRange:Ar,inXRange:Ar,inYRange:function(h){var E=this._view;return!!E&&Math.abs(h-E.y)<E.radius+E.hitRadius},getCenterPoint:function(){var h=this._view;return{x:h.x,y:h.y}},getArea:function(){return Math.PI*Math.pow(this._view.radius,2)},tooltipPosition:function(){var h=this._view;return{x:h.x,y:h.y,padding:h.radius+h.borderWidth}},draw:function(h){var E=this._view,R=this._chart.ctx,F=E.pointStyle,q=E.rotation,de=E.radius,ye=E.x,Ue=E.y,Oe=br.global,Xe=Oe.defaultColor;E.skip||(void 0===h||Ge.canvas._isPointInArea(E,h))&&(R.strokeStyle=E.borderColor||Xe,R.lineWidth=$o(E.borderWidth,Oe.elements.point.borderWidth),R.fillStyle=E.backgroundColor||Xe,Ge.canvas.drawPoint(R,F,de,ye,Ue,q))}}),mt=br.global.defaultColor;function jt(h){return h&&void 0!==h.width}function on(h){var E,R,F,q,de;return jt(h)?(E=h.x-(de=h.width/2),R=h.x+de,F=Math.min(h.y,h.base),q=Math.max(h.y,h.base)):(de=h.height/2,E=Math.min(h.x,h.base),R=Math.max(h.x,h.base),F=h.y-de,q=h.y+de),{left:E,top:F,right:R,bottom:q}}function si(h,E,R){return h===E?R:h===R?E:h}function _o(h,E,R){var de,ye,Ue,Oe,F=h.borderWidth,q=function(h){var E=h.borderSkipped,R={};return E&&(h.horizontal?h.base>h.x&&(E=si(E,"left","right")):h.base<h.y&&(E=si(E,"bottom","top")),R[E]=!0),R}(h);return Ge.isObject(F)?(de=+F.top||0,ye=+F.right||0,Ue=+F.bottom||0,Oe=+F.left||0):de=ye=Ue=Oe=+F||0,{t:q.top||de<0?0:de>R?R:de,r:q.right||ye<0?0:ye>E?E:ye,b:q.bottom||Ue<0?0:Ue>R?R:Ue,l:q.left||Oe<0?0:Oe>E?E:Oe}}function Es(h,E,R){var F=null===E,q=null===R,de=!(!h||F&&q)&&on(h);return de&&(F||E>=de.left&&E<=de.right)&&(q||R>=de.top&&R<=de.bottom)}br._set("global",{elements:{rectangle:{backgroundColor:mt,borderColor:mt,borderSkipped:"bottom",borderWidth:0}}});var Zs=ar.extend({_type:"rectangle",draw:function(){var h=this._chart.ctx,E=this._view,R=function(h){var E=on(h),R=E.right-E.left,F=E.bottom-E.top,q=_o(h,R/2,F/2);return{outer:{x:E.left,y:E.top,w:R,h:F},inner:{x:E.left+q.l,y:E.top+q.t,w:R-q.l-q.r,h:F-q.t-q.b}}}(E),F=R.outer,q=R.inner;h.fillStyle=E.backgroundColor,h.fillRect(F.x,F.y,F.w,F.h),(F.w!==q.w||F.h!==q.h)&&(h.save(),h.beginPath(),h.rect(F.x,F.y,F.w,F.h),h.clip(),h.fillStyle=E.borderColor,h.rect(q.x,q.y,q.w,q.h),h.fill("evenodd"),h.restore())},height:function(){var h=this._view;return h.base-h.y},inRange:function(h,E){return Es(this._view,h,E)},inLabelRange:function(h,E){var R=this._view;return jt(R)?Es(R,h,null):Es(R,null,E)},inXRange:function(h){return Es(this._view,h,null)},inYRange:function(h){return Es(this._view,null,h)},getCenterPoint:function(){var E,R,h=this._view;return jt(h)?(E=h.x,R=(h.y+h.base)/2):(E=(h.x+h.base)/2,R=h.y),{x:E,y:R}},getArea:function(){var h=this._view;return jt(h)?h.width*Math.abs(h.y-h.base):h.height*Math.abs(h.x-h.base)},tooltipPosition:function(){var h=this._view;return{x:h.x,y:h.y}}}),ls={},ta=Ci,Is=_t,us=Zs;ls.Arc=er,ls.Line=ta,ls.Point=Is,ls.Rectangle=us;var ya=Ge._deprecated,el=Ge.valueOrDefault;function $s(h,E,R){var Ue,Oe,F=R.barThickness,q=E.stackCount,de=E.pixels[h],ye=Ge.isNullOrUndef(F)?function(h,E){var F,q,de,ye,R=h._length;for(de=1,ye=E.length;de<ye;++de)R=Math.min(R,Math.abs(E[de]-E[de-1]));for(de=0,ye=h.getTicks().length;de<ye;++de)q=h.getPixelForTick(de),R=de>0?Math.min(R,Math.abs(q-F)):R,F=q;return R}(E.scale,E.pixels):-1;return Ge.isNullOrUndef(F)?(Ue=ye*R.categoryPercentage,Oe=R.barPercentage):(Ue=F*q,Oe=1),{chunk:Ue/q,ratio:Oe,start:de-Ue/2}}br._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),br._set("global",{datasets:{bar:{categoryPercentage:.8,barPercentage:.9}}});var Il=Mi.extend({dataElementType:ls.Rectangle,_dataElementOptions:["backgroundColor","borderColor","borderSkipped","borderWidth","barPercentage","barThickness","categoryPercentage","maxBarThickness","minBarLength"],initialize:function(){var E,R,h=this;Mi.prototype.initialize.apply(h,arguments),(E=h.getMeta()).stack=h.getDataset().stack,E.bar=!0,R=h._getIndexScale().options,ya("bar chart",R.barPercentage,"scales.[x/y]Axes.barPercentage","dataset.barPercentage"),ya("bar chart",R.barThickness,"scales.[x/y]Axes.barThickness","dataset.barThickness"),ya("bar chart",R.categoryPercentage,"scales.[x/y]Axes.categoryPercentage","dataset.categoryPercentage"),ya("bar chart",h._getValueScale().options.minBarLength,"scales.[x/y]Axes.minBarLength","dataset.minBarLength"),ya("bar chart",R.maxBarThickness,"scales.[x/y]Axes.maxBarThickness","dataset.maxBarThickness")},update:function(h){var F,q,E=this,R=E.getMeta().data;for(E._ruler=E.getRuler(),F=0,q=R.length;F<q;++F)E.updateElement(R[F],F,h)},updateElement:function(h,E,R){var F=this,q=F.getMeta(),de=F.getDataset(),ye=F._resolveDataElementOptions(h,E);h._xScale=F.getScaleForId(q.xAxisID),h._yScale=F.getScaleForId(q.yAxisID),h._datasetIndex=F.index,h._index=E,h._model={backgroundColor:ye.backgroundColor,borderColor:ye.borderColor,borderSkipped:ye.borderSkipped,borderWidth:ye.borderWidth,datasetLabel:de.label,label:F.chart.data.labels[E]},Ge.isArray(de.data[E])&&(h._model.borderSkipped=null),F._updateElementGeometry(h,E,R,ye),h.pivot()},_updateElementGeometry:function(h,E,R,F){var q=this,de=h._model,ye=q._getValueScale(),Ue=ye.getBasePixel(),Oe=ye.isHorizontal(),Xe=q._ruler||q.getRuler(),gt=q.calculateBarValuePixels(q.index,E,F),yt=q.calculateBarIndexPixels(q.index,E,Xe,F);de.horizontal=Oe,de.base=R?Ue:gt.base,de.x=Oe?R?Ue:gt.head:yt.center,de.y=Oe?yt.center:R?Ue:gt.head,de.height=Oe?yt.size:void 0,de.width=Oe?void 0:yt.size},_getStacks:function(h){var Ue,Oe,R=this._getIndexScale(),F=R._getMatchingVisibleMetas(this._type),q=R.options.stacked,de=F.length,ye=[];for(Ue=0;Ue<de&&(Oe=F[Ue],(!1===q||-1===ye.indexOf(Oe.stack)||void 0===q&&void 0===Oe.stack)&&ye.push(Oe.stack),Oe.index!==h);++Ue);return ye},getStackCount:function(){return this._getStacks().length},getStackIndex:function(h,E){var R=this._getStacks(h),F=void 0!==E?R.indexOf(E):-1;return-1===F?R.length-1:F},getRuler:function(){var F,q,h=this,E=h._getIndexScale(),R=[];for(F=0,q=h.getMeta().data.length;F<q;++F)R.push(E.getPixelForValue(null,F,h.index));return{pixels:R,start:E._startPixel,end:E._endPixel,stackCount:h.getStackCount(),scale:E}},calculateBarValuePixels:function(h,E,R){var Gr,Pi,Zo,Lo,Gs,Xs,dl,F=this,q=F.chart,de=F._getValueScale(),ye=de.isHorizontal(),Ue=q.data.datasets,Oe=de._getMatchingVisibleMetas(F._type),Xe=de._parseValue(Ue[h].data[E]),gt=R.minBarLength,yt=de.options.stacked,nn=F.getMeta().stack,Pn=void 0===Xe.start?0:Xe.max>=0&&Xe.min>=0?Xe.min:Xe.max,xn=void 0===Xe.start?Xe.end:Xe.max>=0&&Xe.min>=0?Xe.max-Xe.min:Xe.min-Xe.max,ir=Oe.length;if(yt||void 0===yt&&void 0!==nn)for(Gr=0;Gr<ir&&(Pi=Oe[Gr]).index!==h;++Gr)Pi.stack===nn&&(Zo=void 0===(dl=de._parseValue(Ue[Pi.index].data[E])).start?dl.end:dl.min>=0&&dl.max>=0?dl.max:dl.min,(Xe.min<0&&Zo<0||Xe.max>=0&&Zo>0)&&(Pn+=Zo));return Lo=de.getPixelForValue(Pn),Xs=(Gs=de.getPixelForValue(Pn+xn))-Lo,void 0!==gt&&Math.abs(Xs)<gt&&(Xs=gt,Gs=xn>=0&&!ye||xn<0&&ye?Lo-gt:Lo+gt),{size:Xs,base:Lo,head:Gs,center:Gs+Xs/2}},calculateBarIndexPixels:function(h,E,R,F){var de="flex"===F.barThickness?function(h,E,R){var Oe,F=E.pixels,q=F[h],de=h>0?F[h-1]:null,ye=h<F.length-1?F[h+1]:null,Ue=R.categoryPercentage;return null===de&&(de=q-(null===ye?E.end-E.start:ye-q)),null===ye&&(ye=q+q-de),Oe=q-(q-Math.min(de,ye))/2*Ue,{chunk:Math.abs(ye-de)/2*Ue/E.stackCount,ratio:R.barPercentage,start:Oe}}(E,R,F):$s(E,R,F),ye=this.getStackIndex(h,this.getMeta().stack),Ue=de.start+de.chunk*ye+de.chunk/2,Oe=Math.min(el(F.maxBarThickness,1/0),de.chunk*de.ratio);return{base:Ue-Oe/2,head:Ue+Oe/2,center:Ue,size:Oe}},draw:function(){var h=this,E=h.chart,R=h._getValueScale(),F=h.getMeta().data,q=h.getDataset(),de=F.length,ye=0;for(Ge.canvas.clipArea(E.ctx,E.chartArea);ye<de;++ye){var Ue=R._parseValue(q.data[ye]);!isNaN(Ue.min)&&!isNaN(Ue.max)&&F[ye].draw()}Ge.canvas.unclipArea(E.ctx)},_resolveDataElementOptions:function(){var h=this,E=Ge.extend({},Mi.prototype._resolveDataElementOptions.apply(h,arguments)),R=h._getIndexScale().options,F=h._getValueScale().options;return E.barPercentage=el(R.barPercentage,E.barPercentage),E.barThickness=el(R.barThickness,E.barThickness),E.categoryPercentage=el(R.categoryPercentage,E.categoryPercentage),E.maxBarThickness=el(R.maxBarThickness,E.maxBarThickness),E.minBarLength=el(F.minBarLength,E.minBarLength),E}}),fo=Ge.valueOrDefault,Ya=Ge.options.resolve;br._set("bubble",{hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(){return""},label:function(h,E){return(E.datasets[h.datasetIndex].label||"")+": ("+h.xLabel+", "+h.yLabel+", "+E.datasets[h.datasetIndex].data[h.index].r+")"}}}});var Ao=Mi.extend({dataElementType:ls.Point,_dataElementOptions:["backgroundColor","borderColor","borderWidth","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth","hoverRadius","hitRadius","pointStyle","rotation"],update:function(h){var E=this,R=E.getMeta();Ge.each(R.data,function(q,de){E.updateElement(q,de,h)})},updateElement:function(h,E,R){var F=this,q=F.getMeta(),de=h.custom||{},ye=F.getScaleForId(q.xAxisID),Ue=F.getScaleForId(q.yAxisID),Oe=F._resolveDataElementOptions(h,E),Xe=F.getDataset().data[E],gt=F.index,yt=R?ye.getPixelForDecimal(.5):ye.getPixelForValue("object"==typeof Xe?Xe:NaN,E,gt),nn=R?Ue.getBasePixel():Ue.getPixelForValue(Xe,E,gt);h._xScale=ye,h._yScale=Ue,h._options=Oe,h._datasetIndex=gt,h._index=E,h._model={backgroundColor:Oe.backgroundColor,borderColor:Oe.borderColor,borderWidth:Oe.borderWidth,hitRadius:Oe.hitRadius,pointStyle:Oe.pointStyle,rotation:Oe.rotation,radius:R?0:Oe.radius,skip:de.skip||isNaN(yt)||isNaN(nn),x:yt,y:nn},h.pivot()},setHoverStyle:function(h){var E=h._model,R=h._options,F=Ge.getHoverColor;h.$previousStyle={backgroundColor:E.backgroundColor,borderColor:E.borderColor,borderWidth:E.borderWidth,radius:E.radius},E.backgroundColor=fo(R.hoverBackgroundColor,F(R.backgroundColor)),E.borderColor=fo(R.hoverBorderColor,F(R.borderColor)),E.borderWidth=fo(R.hoverBorderWidth,R.borderWidth),E.radius=R.radius+R.hoverRadius},_resolveDataElementOptions:function(h,E){var R=this,F=R.chart,q=R.getDataset(),de=h.custom||{},ye=q.data[E]||{},Ue=Mi.prototype._resolveDataElementOptions.apply(R,arguments),Oe={chart:F,dataIndex:E,dataset:q,datasetIndex:R.index};return R._cachedDataOpts===Ue&&(Ue=Ge.extend({},Ue)),Ue.radius=Ya([de.radius,ye.r,R._config.radius,F.options.elements.point.radius],Oe,E),Ue}}),fs=Ge.valueOrDefault,Ca=Math.PI,Ra=2*Ca,pl=Ca/2;br._set("doughnut",{animation:{animateRotate:!0,animateScale:!1},hover:{mode:"single"},legendCallback:function(h){var de,ye,Ue,E=document.createElement("ul"),R=h.data,F=R.datasets,q=R.labels;if(E.setAttribute("class",h.id+"-legend"),F.length)for(de=0,ye=F[0].data.length;de<ye;++de)(Ue=E.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=F[0].backgroundColor[de],q[de]&&Ue.appendChild(document.createTextNode(q[de]));return E.outerHTML},legend:{labels:{generateLabels:function(h){var E=h.data;return E.labels.length&&E.datasets.length?E.labels.map(function(R,F){var q=h.getDatasetMeta(0),de=q.controller.getStyle(F);return{text:R,fillStyle:de.backgroundColor,strokeStyle:de.borderColor,lineWidth:de.borderWidth,hidden:isNaN(E.datasets[0].data[F])||q.data[F].hidden,index:F}}):[]}},onClick:function(h,E){var q,de,ye,R=E.index,F=this.chart;for(q=0,de=(F.data.datasets||[]).length;q<de;++q)(ye=F.getDatasetMeta(q)).data[R]&&(ye.data[R].hidden=!ye.data[R].hidden);F.update()}},cutoutPercentage:50,rotation:-pl,circumference:Ra,tooltips:{callbacks:{title:function(){return""},label:function(h,E){var R=E.labels[h.index],F=": "+E.datasets[h.datasetIndex].data[h.index];return Ge.isArray(R)?(R=R.slice())[0]+=F:R+=F,R}}}});var Ws=Mi.extend({dataElementType:ls.Arc,linkScales:Ge.noop,_dataElementOptions:["backgroundColor","borderColor","borderWidth","borderAlign","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth"],getRingIndex:function(h){for(var E=0,R=0;R<h;++R)this.chart.isDatasetVisible(R)&&++E;return E},update:function(h){var Gr,Pi,E=this,R=E.chart,F=R.chartArea,q=R.options,de=1,ye=1,Ue=0,Oe=0,Xe=E.getMeta(),gt=Xe.data,yt=q.cutoutPercentage/100||0,nn=q.circumference,Pn=E._getRingWeight(E.index);if(nn<Ra){var Zo=q.rotation%Ra,Lo=(Zo+=Zo>=Ca?-Ra:Zo<-Ca?Ra:0)+nn,Gs=Math.cos(Zo),Xs=Math.sin(Zo),dl=Math.cos(Lo),ha=Math.sin(Lo),ia=Zo<=0&&Lo>=0||Lo>=Ra,Pa=Zo<=pl&&Lo>=pl||Lo>=Ra+pl,Eu=Zo<=-pl&&Lo>=-pl||Lo>=Ca+pl,wa=Zo===-Ca||Lo>=Ca?-1:Math.min(Gs,Gs*yt,dl,dl*yt),ou=Eu?-1:Math.min(Xs,Xs*yt,ha,ha*yt),gu=ia?1:Math.max(Gs,Gs*yt,dl,dl*yt),Nc=Pa?1:Math.max(Xs,Xs*yt,ha,ha*yt);de=(gu-wa)/2,ye=(Nc-ou)/2,Ue=-(gu+wa)/2,Oe=-(Nc+ou)/2}for(Gr=0,Pi=gt.length;Gr<Pi;++Gr)gt[Gr]._options=E._resolveDataElementOptions(gt[Gr],Gr);for(R.borderWidth=E.getMaxBorderWidth(),R.outerRadius=Math.max(Math.min((F.right-F.left-R.borderWidth)/de,(F.bottom-F.top-R.borderWidth)/ye)/2,0),R.innerRadius=Math.max(R.outerRadius*yt,0),R.radiusLength=(R.outerRadius-R.innerRadius)/(E._getVisibleDatasetWeightTotal()||1),R.offsetX=Ue*R.outerRadius,R.offsetY=Oe*R.outerRadius,Xe.total=E.calculateTotal(),E.outerRadius=R.outerRadius-R.radiusLength*E._getRingWeightOffset(E.index),E.innerRadius=Math.max(E.outerRadius-R.radiusLength*Pn,0),Gr=0,Pi=gt.length;Gr<Pi;++Gr)E.updateElement(gt[Gr],Gr,h)},updateElement:function(h,E,R){var F=this,q=F.chart,de=q.chartArea,ye=q.options,Ue=ye.animation,Oe=(de.left+de.right)/2,Xe=(de.top+de.bottom)/2,gt=ye.rotation,yt=ye.rotation,nn=F.getDataset(),Pn=R&&Ue.animateRotate||h.hidden?0:F.calculateCircumference(nn.data[E])*(ye.circumference/Ra),Gr=h._options||{};Ge.extend(h,{_datasetIndex:F.index,_index:E,_model:{backgroundColor:Gr.backgroundColor,borderColor:Gr.borderColor,borderWidth:Gr.borderWidth,borderAlign:Gr.borderAlign,x:Oe+q.offsetX,y:Xe+q.offsetY,startAngle:gt,endAngle:yt,circumference:Pn,outerRadius:R&&Ue.animateScale?0:F.outerRadius,innerRadius:R&&Ue.animateScale?0:F.innerRadius,label:Ge.valueAtIndexOrDefault(nn.label,E,q.data.labels[E])}});var Pi=h._model;(!R||!Ue.animateRotate)&&(Pi.startAngle=0===E?ye.rotation:F.getMeta().data[E-1]._model.endAngle,Pi.endAngle=Pi.startAngle+Pi.circumference),h.pivot()},calculateTotal:function(){var F,h=this.getDataset(),E=this.getMeta(),R=0;return Ge.each(E.data,function(q,de){F=h.data[de],!isNaN(F)&&!q.hidden&&(R+=Math.abs(F))}),R},calculateCircumference:function(h){var E=this.getMeta().total;return E>0&&!isNaN(h)?Ra*(Math.abs(h)/E):0},getMaxBorderWidth:function(h){var q,de,ye,Ue,Oe,Xe,gt,yt,R=0,F=this.chart;if(!h)for(q=0,de=F.data.datasets.length;q<de;++q)if(F.isDatasetVisible(q)){h=(ye=F.getDatasetMeta(q)).data,q!==this.index&&(Oe=ye.controller);break}if(!h)return 0;for(q=0,de=h.length;q<de;++q)Ue=h[q],Oe?(Oe._configure(),Xe=Oe._resolveDataElementOptions(Ue,q)):Xe=Ue._options,"inner"!==Xe.borderAlign&&(R=(yt=Xe.hoverBorderWidth)>(R=(gt=Xe.borderWidth)>R?gt:R)?yt:R);return R},setHoverStyle:function(h){var E=h._model,R=h._options,F=Ge.getHoverColor;h.$previousStyle={backgroundColor:E.backgroundColor,borderColor:E.borderColor,borderWidth:E.borderWidth},E.backgroundColor=fs(R.hoverBackgroundColor,F(R.backgroundColor)),E.borderColor=fs(R.hoverBorderColor,F(R.borderColor)),E.borderWidth=fs(R.hoverBorderWidth,R.borderWidth)},_getRingWeightOffset:function(h){for(var E=0,R=0;R<h;++R)this.chart.isDatasetVisible(R)&&(E+=this._getRingWeight(R));return E},_getRingWeight:function(h){return Math.max(fs(this.chart.data.datasets[h].weight,1),0)},_getVisibleDatasetWeightTotal:function(){return this._getRingWeightOffset(this.chart.data.datasets.length)}});br._set("horizontalBar",{hover:{mode:"index",axis:"y"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{type:"category",position:"left",offset:!0,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{mode:"index",axis:"y"}}),br._set("global",{datasets:{horizontalBar:{categoryPercentage:.8,barPercentage:.9}}});var Po=Il.extend({_getValueScaleId:function(){return this.getMeta().xAxisID},_getIndexScaleId:function(){return this.getMeta().yAxisID}}),bo=Ge.valueOrDefault,Ls=Ge.options.resolve,ps=Ge.canvas._isPointInArea;function So(h,E){var R=h&&h.options.ticks||{},F=R.reverse,q=void 0===R.min?E:0,de=void 0===R.max?E:0;return{start:F?de:q,end:F?q:de}}function $r(h,E,R){var F=R/2,q=So(h,F),de=So(E,F);return{top:de.end,right:q.end,bottom:de.start,left:q.start}}function to(h){var E,R,F,q;return Ge.isObject(h)?(E=h.top,R=h.right,F=h.bottom,q=h.left):E=R=F=q=h,{top:E,right:R,bottom:F,left:q}}br._set("line",{showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}});var tt=Mi.extend({datasetElementType:ls.Line,dataElementType:ls.Point,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth","cubicInterpolationMode","fill"],_dataElementOptions:{backgroundColor:"pointBackgroundColor",borderColor:"pointBorderColor",borderWidth:"pointBorderWidth",hitRadius:"pointHitRadius",hoverBackgroundColor:"pointHoverBackgroundColor",hoverBorderColor:"pointHoverBorderColor",hoverBorderWidth:"pointHoverBorderWidth",hoverRadius:"pointHoverRadius",pointStyle:"pointStyle",radius:"pointRadius",rotation:"pointRotation"},update:function(h){var Oe,Xe,E=this,R=E.getMeta(),F=R.dataset,q=R.data||[],ye=E._config,Ue=E._showLine=bo(ye.showLine,E.chart.options.showLines);for(E._xScale=E.getScaleForId(R.xAxisID),E._yScale=E.getScaleForId(R.yAxisID),Ue&&(void 0!==ye.tension&&void 0===ye.lineTension&&(ye.lineTension=ye.tension),F._scale=E._yScale,F._datasetIndex=E.index,F._children=q,F._model=E._resolveDatasetElementOptions(F),F.pivot()),Oe=0,Xe=q.length;Oe<Xe;++Oe)E.updateElement(q[Oe],Oe,h);for(Ue&&0!==F._model.tension&&E.updateBezierControlPoints(),Oe=0,Xe=q.length;Oe<Xe;++Oe)q[Oe].pivot()},updateElement:function(h,E,R){var nn,Pn,F=this,q=F.getMeta(),de=h.custom||{},ye=F.getDataset(),Ue=F.index,Oe=ye.data[E],Xe=F._xScale,gt=F._yScale,yt=q.dataset._model,xn=F._resolveDataElementOptions(h,E);nn=Xe.getPixelForValue("object"==typeof Oe?Oe:NaN,E,Ue),Pn=R?gt.getBasePixel():F.calculatePointY(Oe,E,Ue),h._xScale=Xe,h._yScale=gt,h._options=xn,h._datasetIndex=Ue,h._index=E,h._model={x:nn,y:Pn,skip:de.skip||isNaN(nn)||isNaN(Pn),radius:xn.radius,pointStyle:xn.pointStyle,rotation:xn.rotation,backgroundColor:xn.backgroundColor,borderColor:xn.borderColor,borderWidth:xn.borderWidth,tension:bo(de.tension,yt?yt.tension:0),steppedLine:!!yt&&yt.steppedLine,hitRadius:xn.hitRadius}},_resolveDatasetElementOptions:function(h){var E=this,R=E._config,F=h.custom||{},q=E.chart.options,de=q.elements.line,ye=Mi.prototype._resolveDatasetElementOptions.apply(E,arguments);return ye.spanGaps=bo(R.spanGaps,q.spanGaps),ye.tension=bo(R.lineTension,de.tension),ye.steppedLine=Ls([F.steppedLine,R.steppedLine,de.stepped]),ye.clip=to(bo(R.clip,$r(E._xScale,E._yScale,ye.borderWidth))),ye},calculatePointY:function(h,E,R){var Oe,gt,yt,nn,Pn,xn,q=this.chart,de=this._yScale,ye=0,Ue=0;if(de.options.stacked){for(nn=+de.getRightValue(h),xn=(Pn=q._getSortedVisibleDatasetMetas()).length,Oe=0;Oe<xn&&(gt=Pn[Oe]).index!==R;++Oe)"line"===gt.type&&gt.yAxisID===de.id&&((yt=+de.getRightValue(q.data.datasets[gt.index].data[E]))<0?Ue+=yt||0:ye+=yt||0);return de.getPixelForValue(nn<0?Ue+nn:ye+nn)}return de.getPixelForValue(h)},updateBezierControlPoints:function(){var ye,Ue,Oe,Xe,E=this.chart,R=this.getMeta(),F=R.dataset._model,q=E.chartArea,de=R.data||[];function gt(yt,nn,Pn){return Math.max(Math.min(yt,Pn),nn)}if(F.spanGaps&&(de=de.filter(function(yt){return!yt._model.skip})),"monotone"===F.cubicInterpolationMode)Ge.splineCurveMonotone(de);else for(ye=0,Ue=de.length;ye<Ue;++ye)Oe=de[ye]._model,Xe=Ge.splineCurve(Ge.previousItem(de,ye)._model,Oe,Ge.nextItem(de,ye)._model,F.tension),Oe.controlPointPreviousX=Xe.previous.x,Oe.controlPointPreviousY=Xe.previous.y,Oe.controlPointNextX=Xe.next.x,Oe.controlPointNextY=Xe.next.y;if(E.options.elements.line.capBezierPoints)for(ye=0,Ue=de.length;ye<Ue;++ye)ps(Oe=de[ye]._model,q)&&(ye>0&&ps(de[ye-1]._model,q)&&(Oe.controlPointPreviousX=gt(Oe.controlPointPreviousX,q.left,q.right),Oe.controlPointPreviousY=gt(Oe.controlPointPreviousY,q.top,q.bottom)),ye<de.length-1&&ps(de[ye+1]._model,q)&&(Oe.controlPointNextX=gt(Oe.controlPointNextX,q.left,q.right),Oe.controlPointNextY=gt(Oe.controlPointNextY,q.top,q.bottom)))},draw:function(){var Oe,h=this,E=h.chart,R=h.getMeta(),F=R.data||[],q=E.chartArea,de=E.canvas,ye=0,Ue=F.length;for(h._showLine&&(Ge.canvas.clipArea(E.ctx,{left:!1===(Oe=R.dataset._model.clip).left?0:q.left-Oe.left,right:!1===Oe.right?de.width:q.right+Oe.right,top:!1===Oe.top?0:q.top-Oe.top,bottom:!1===Oe.bottom?de.height:q.bottom+Oe.bottom}),R.dataset.draw(),Ge.canvas.unclipArea(E.ctx));ye<Ue;++ye)F[ye].draw(q)},setHoverStyle:function(h){var E=h._model,R=h._options,F=Ge.getHoverColor;h.$previousStyle={backgroundColor:E.backgroundColor,borderColor:E.borderColor,borderWidth:E.borderWidth,radius:E.radius},E.backgroundColor=bo(R.hoverBackgroundColor,F(R.backgroundColor)),E.borderColor=bo(R.hoverBorderColor,F(R.borderColor)),E.borderWidth=bo(R.hoverBorderWidth,R.borderWidth),E.radius=bo(R.hoverRadius,R.radius)}}),sn=Ge.options.resolve;br._set("polarArea",{scale:{type:"radialLinear",angleLines:{display:!1},gridLines:{circular:!0},pointLabels:{display:!1},ticks:{beginAtZero:!0}},animation:{animateRotate:!0,animateScale:!0},startAngle:-.5*Math.PI,legendCallback:function(h){var de,ye,Ue,E=document.createElement("ul"),R=h.data,F=R.datasets,q=R.labels;if(E.setAttribute("class",h.id+"-legend"),F.length)for(de=0,ye=F[0].data.length;de<ye;++de)(Ue=E.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=F[0].backgroundColor[de],q[de]&&Ue.appendChild(document.createTextNode(q[de]));return E.outerHTML},legend:{labels:{generateLabels:function(h){var E=h.data;return E.labels.length&&E.datasets.length?E.labels.map(function(R,F){var q=h.getDatasetMeta(0),de=q.controller.getStyle(F);return{text:R,fillStyle:de.backgroundColor,strokeStyle:de.borderColor,lineWidth:de.borderWidth,hidden:isNaN(E.datasets[0].data[F])||q.data[F].hidden,index:F}}):[]}},onClick:function(h,E){var q,de,ye,R=E.index,F=this.chart;for(q=0,de=(F.data.datasets||[]).length;q<de;++q)(ye=F.getDatasetMeta(q)).data[R].hidden=!ye.data[R].hidden;F.update()}},tooltips:{callbacks:{title:function(){return""},label:function(h,E){return E.labels[h.index]+": "+h.yLabel}}}});var ne=Mi.extend({dataElementType:ls.Arc,linkScales:Ge.noop,_dataElementOptions:["backgroundColor","borderColor","borderWidth","borderAlign","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth"],_getIndexScaleId:function(){return this.chart.scale.id},_getValueScaleId:function(){return this.chart.scale.id},update:function(h){var Oe,Xe,gt,E=this,R=E.getDataset(),F=E.getMeta(),q=E.chart.options.startAngle||0,de=E._starts=[],ye=E._angles=[],Ue=F.data;for(E._updateRadius(),F.count=E.countVisibleElements(),Oe=0,Xe=R.data.length;Oe<Xe;Oe++)de[Oe]=q,gt=E._computeAngle(Oe),ye[Oe]=gt,q+=gt;for(Oe=0,Xe=Ue.length;Oe<Xe;++Oe)Ue[Oe]._options=E._resolveDataElementOptions(Ue[Oe],Oe),E.updateElement(Ue[Oe],Oe,h)},_updateRadius:function(){var h=this,E=h.chart,R=E.chartArea,F=E.options,q=Math.min(R.right-R.left,R.bottom-R.top);E.outerRadius=Math.max(q/2,0),E.innerRadius=Math.max(F.cutoutPercentage?E.outerRadius/100*F.cutoutPercentage:1,0),E.radiusLength=(E.outerRadius-E.innerRadius)/E.getVisibleDatasetCount(),h.outerRadius=E.outerRadius-E.radiusLength*h.index,h.innerRadius=h.outerRadius-E.radiusLength},updateElement:function(h,E,R){var F=this,q=F.chart,de=F.getDataset(),ye=q.options,Ue=ye.animation,Oe=q.scale,Xe=q.data.labels,gt=Oe.xCenter,yt=Oe.yCenter,nn=ye.startAngle,Pn=h.hidden?0:Oe.getDistanceFromCenterForValue(de.data[E]),xn=F._starts[E],ir=xn+(h.hidden?0:F._angles[E]),Gr=Ue.animateScale?0:Oe.getDistanceFromCenterForValue(de.data[E]),Pi=h._options||{};Ge.extend(h,{_datasetIndex:F.index,_index:E,_scale:Oe,_model:{backgroundColor:Pi.backgroundColor,borderColor:Pi.borderColor,borderWidth:Pi.borderWidth,borderAlign:Pi.borderAlign,x:gt,y:yt,innerRadius:0,outerRadius:R?Gr:Pn,startAngle:R&&Ue.animateRotate?nn:xn,endAngle:R&&Ue.animateRotate?nn:ir,label:Ge.valueAtIndexOrDefault(Xe,E,Xe[E])}}),h.pivot()},countVisibleElements:function(){var h=this.getDataset(),E=this.getMeta(),R=0;return Ge.each(E.data,function(F,q){!isNaN(h.data[q])&&!F.hidden&&R++}),R},setHoverStyle:function(h){var E=h._model,R=h._options,F=Ge.getHoverColor,q=Ge.valueOrDefault;h.$previousStyle={backgroundColor:E.backgroundColor,borderColor:E.borderColor,borderWidth:E.borderWidth},E.backgroundColor=q(R.hoverBackgroundColor,F(R.backgroundColor)),E.borderColor=q(R.hoverBorderColor,F(R.borderColor)),E.borderWidth=q(R.hoverBorderWidth,R.borderWidth)},_computeAngle:function(h){var E=this,R=this.getMeta().count,F=E.getDataset(),q=E.getMeta();return isNaN(F.data[h])||q.data[h].hidden?0:sn([E.chart.options.elements.arc.angle,2*Math.PI/R],{chart:E.chart,dataIndex:h,dataset:F,datasetIndex:E.index},h)}});br._set("pie",Ge.clone(br.doughnut)),br._set("pie",{cutoutPercentage:0});var $e=Ws,Lt=Ge.valueOrDefault;br._set("radar",{spanGaps:!1,scale:{type:"radialLinear"},elements:{line:{fill:"start",tension:0}}});var an=Mi.extend({datasetElementType:ls.Line,dataElementType:ls.Point,linkScales:Ge.noop,_datasetElementOptions:["backgroundColor","borderWidth","borderColor","borderCapStyle","borderDash","borderDashOffset","borderJoinStyle","fill"],_dataElementOptions:{backgroundColor:"pointBackgroundColor",borderColor:"pointBorderColor",borderWidth:"pointBorderWidth",hitRadius:"pointHitRadius",hoverBackgroundColor:"pointHoverBackgroundColor",hoverBorderColor:"pointHoverBorderColor",hoverBorderWidth:"pointHoverBorderWidth",hoverRadius:"pointHoverRadius",pointStyle:"pointStyle",radius:"pointRadius",rotation:"pointRotation"},_getIndexScaleId:function(){return this.chart.scale.id},_getValueScaleId:function(){return this.chart.scale.id},update:function(h){var Ue,Oe,E=this,R=E.getMeta(),F=R.dataset,q=R.data||[],de=E.chart.scale,ye=E._config;for(void 0!==ye.tension&&void 0===ye.lineTension&&(ye.lineTension=ye.tension),F._scale=de,F._datasetIndex=E.index,F._children=q,F._loop=!0,F._model=E._resolveDatasetElementOptions(F),F.pivot(),Ue=0,Oe=q.length;Ue<Oe;++Ue)E.updateElement(q[Ue],Ue,h);for(E.updateBezierControlPoints(),Ue=0,Oe=q.length;Ue<Oe;++Ue)q[Ue].pivot()},updateElement:function(h,E,R){var F=this,q=h.custom||{},de=F.getDataset(),ye=F.chart.scale,Ue=ye.getPointPositionForValue(E,de.data[E]),Oe=F._resolveDataElementOptions(h,E),Xe=F.getMeta().dataset._model,gt=R?ye.xCenter:Ue.x,yt=R?ye.yCenter:Ue.y;h._scale=ye,h._options=Oe,h._datasetIndex=F.index,h._index=E,h._model={x:gt,y:yt,skip:q.skip||isNaN(gt)||isNaN(yt),radius:Oe.radius,pointStyle:Oe.pointStyle,rotation:Oe.rotation,backgroundColor:Oe.backgroundColor,borderColor:Oe.borderColor,borderWidth:Oe.borderWidth,tension:Lt(q.tension,Xe?Xe.tension:0),hitRadius:Oe.hitRadius}},_resolveDatasetElementOptions:function(){var h=this,E=h._config,R=h.chart.options,F=Mi.prototype._resolveDatasetElementOptions.apply(h,arguments);return F.spanGaps=Lt(E.spanGaps,R.spanGaps),F.tension=Lt(E.lineTension,R.elements.line.tension),F},updateBezierControlPoints:function(){var q,de,ye,Ue,E=this.getMeta(),R=this.chart.chartArea,F=E.data||[];function Oe(Xe,gt,yt){return Math.max(Math.min(Xe,yt),gt)}for(E.dataset._model.spanGaps&&(F=F.filter(function(Xe){return!Xe._model.skip})),q=0,de=F.length;q<de;++q)ye=F[q]._model,Ue=Ge.splineCurve(Ge.previousItem(F,q,!0)._model,ye,Ge.nextItem(F,q,!0)._model,ye.tension),ye.controlPointPreviousX=Oe(Ue.previous.x,R.left,R.right),ye.controlPointPreviousY=Oe(Ue.previous.y,R.top,R.bottom),ye.controlPointNextX=Oe(Ue.next.x,R.left,R.right),ye.controlPointNextY=Oe(Ue.next.y,R.top,R.bottom)},setHoverStyle:function(h){var E=h._model,R=h._options,F=Ge.getHoverColor;h.$previousStyle={backgroundColor:E.backgroundColor,borderColor:E.borderColor,borderWidth:E.borderWidth,radius:E.radius},E.backgroundColor=Lt(R.hoverBackgroundColor,F(R.backgroundColor)),E.borderColor=Lt(R.hoverBorderColor,F(R.borderColor)),E.borderWidth=Lt(R.hoverBorderWidth,R.borderWidth),E.radius=Lt(R.hoverRadius,R.radius)}});br._set("scatter",{hover:{mode:"single"},scales:{xAxes:[{id:"x-axis-1",type:"linear",position:"bottom"}],yAxes:[{id:"y-axis-1",type:"linear",position:"left"}]},tooltips:{callbacks:{title:function(){return""},label:function(h){return"("+h.xLabel+", "+h.yLabel+")"}}}}),br._set("global",{datasets:{scatter:{showLine:!1}}});var pi={bar:Il,bubble:Ao,doughnut:Ws,horizontalBar:Po,line:tt,polarArea:ne,pie:$e,radar:an,scatter:tt};function xi(h,E){return h.native?{x:h.x,y:h.y}:Ge.getRelativePosition(h,E)}function ts(h,E){var F,q,de,ye,Ue,Oe,R=h._getSortedVisibleDatasetMetas();for(q=0,ye=R.length;q<ye;++q)for(de=0,Ue=(F=R[q].data).length;de<Ue;++de)(Oe=F[de])._view.skip||E(Oe)}function wo(h,E){var R=[];return ts(h,function(F){F.inRange(E.x,E.y)&&R.push(F)}),R}function ko(h,E,R,F){var q=Number.POSITIVE_INFINITY,de=[];return ts(h,function(ye){if(!R||ye.inRange(E.x,E.y)){var Ue=ye.getCenterPoint(),Oe=F(E,Ue);Oe<q?(de=[ye],q=Oe):Oe===q&&de.push(ye)}}),de}function Eo(h){var E=-1!==h.indexOf("x"),R=-1!==h.indexOf("y");return function(F,q){var de=E?Math.abs(F.x-q.x):0,ye=R?Math.abs(F.y-q.y):0;return Math.sqrt(Math.pow(de,2)+Math.pow(ye,2))}}function ba(h,E,R){var F=xi(E,h);R.axis=R.axis||"x";var q=Eo(R.axis),de=R.intersect?wo(h,F):ko(h,F,!1,q),ye=[];return de.length?(h._getSortedVisibleDatasetMetas().forEach(function(Ue){var Oe=Ue.data[de[0]._index];Oe&&!Oe._view.skip&&ye.push(Oe)}),ye):[]}var sl={modes:{single:function(h,E){var R=xi(E,h),F=[];return ts(h,function(q){if(q.inRange(R.x,R.y))return F.push(q),F}),F.slice(0,1)},label:ba,index:ba,dataset:function(h,E,R){var F=xi(E,h);R.axis=R.axis||"xy";var q=Eo(R.axis),de=R.intersect?wo(h,F):ko(h,F,!1,q);return de.length>0&&(de=h.getDatasetMeta(de[0]._datasetIndex).data),de},"x-axis":function(h,E){return ba(h,E,{intersect:!1})},point:function(h,E){return wo(h,xi(E,h))},nearest:function(h,E,R){var F=xi(E,h);R.axis=R.axis||"xy";var q=Eo(R.axis);return ko(h,F,R.intersect,q)},x:function(h,E,R){var F=xi(E,h),q=[],de=!1;return ts(h,function(ye){ye.inXRange(F.x)&&q.push(ye),ye.inRange(F.x,F.y)&&(de=!0)}),R.intersect&&!de&&(q=[]),q},y:function(h,E,R){var F=xi(E,h),q=[],de=!1;return ts(h,function(ye){ye.inYRange(F.y)&&q.push(ye),ye.inRange(F.x,F.y)&&(de=!0)}),R.intersect&&!de&&(q=[]),q}}},tc=Ge.extend;function Nu(h,E){return Ge.where(h,function(R){return R.pos===E})}function bc(h,E){return h.sort(function(R,F){var q=E?F:R,de=E?R:F;return q.weight===de.weight?q.index-de.index:q.weight-de.weight})}function Yl(h,E,R,F){return Math.max(h[R],E[R])+Math.max(h[F],E[F])}function Fs(h,E,R){var de,ye,F=R.box,q=h.maxPadding;if(R.size&&(h[R.pos]-=R.size),R.size=R.horizontal?F.height:F.width,h[R.pos]+=R.size,F.getPadding){var Ue=F.getPadding();q.top=Math.max(q.top,Ue.top),q.left=Math.max(q.left,Ue.left),q.bottom=Math.max(q.bottom,Ue.bottom),q.right=Math.max(q.right,Ue.right)}if(de=E.outerWidth-Yl(q,h,"left","right"),ye=E.outerHeight-Yl(q,h,"top","bottom"),de!==h.w||ye!==h.h){h.w=de,h.h=ye;var Oe=R.horizontal?[de,h.w]:[ye,h.h];return!(Oe[0]===Oe[1]||isNaN(Oe[0])&&isNaN(Oe[1]))}}function iu(h,E){var de,R=E.maxPadding;return de={left:0,top:0,right:0,bottom:0},(h?["left","right"]:["top","bottom"]).forEach(function(ye){de[ye]=Math.max(E[ye],R[ye])}),de}function tl(h,E,R){var q,de,ye,Ue,Oe,Xe,F=[];for(q=0,de=h.length;q<de;++q)(Ue=(ye=h[q]).box).update(ye.width||E.w,ye.height||E.h,iu(ye.horizontal,E)),Fs(E,R,ye)&&(Xe=!0,F.length&&(Oe=!0)),Ue.fullWidth||F.push(ye);return Oe&&tl(F,E,R)||Xe}function Su(h,E,R){var ye,Ue,Oe,Xe,F=R.padding,q=E.x,de=E.y;for(ye=0,Ue=h.length;ye<Ue;++ye)Xe=(Oe=h[ye]).box,Oe.horizontal?(Xe.left=Xe.fullWidth?F.left:E.left,Xe.right=Xe.fullWidth?R.outerWidth-F.right:E.left+E.w,Xe.top=de,Xe.bottom=de+Xe.height,Xe.width=Xe.right-Xe.left,de=Xe.bottom):(Xe.left=q,Xe.right=q+Xe.width,Xe.top=E.top,Xe.bottom=E.top+E.h,Xe.height=Xe.bottom-Xe.top,q=Xe.right);E.x=q,E.y=de}br._set("global",{layout:{padding:{top:0,right:0,bottom:0,left:0}}});var Zl={defaults:{},addBox:function(h,E){h.boxes||(h.boxes=[]),E.fullWidth=E.fullWidth||!1,E.position=E.position||"top",E.weight=E.weight||0,E._layers=E._layers||function(){return[{z:0,draw:function(){E.draw.apply(E,arguments)}}]},h.boxes.push(E)},removeBox:function(h,E){var R=h.boxes?h.boxes.indexOf(E):-1;-1!==R&&h.boxes.splice(R,1)},configure:function(h,E,R){for(var ye,F=["fullWidth","position","weight"],q=F.length,de=0;de<q;++de)R.hasOwnProperty(ye=F[de])&&(E[ye]=R[ye])},update:function(h,E,R){if(h){var q=Ge.options.toPadding((h.options.layout||{}).padding),de=E-q.width,ye=R-q.height,Ue=function(h){var E=function(h){var R,F,q,E=[];for(R=0,F=(h||[]).length;R<F;++R)E.push({index:R,box:q=h[R],pos:q.position,horizontal:q.isHorizontal(),weight:q.weight});return E}(h),R=bc(Nu(E,"left"),!0),F=bc(Nu(E,"right")),q=bc(Nu(E,"top"),!0),de=bc(Nu(E,"bottom"));return{leftAndTop:R.concat(q),rightAndBottom:F.concat(de),chartArea:Nu(E,"chartArea"),vertical:R.concat(F),horizontal:q.concat(de)}}(h.boxes),Oe=Ue.vertical,Xe=Ue.horizontal,gt=Object.freeze({outerWidth:E,outerHeight:R,padding:q,availableWidth:de,vBoxMaxWidth:de/2/Oe.length,hBoxMaxHeight:ye/2}),yt=tc({maxPadding:tc({},q),w:de,h:ye,x:q.left,y:q.top},q);(function(h,E){var R,F,q;for(R=0,F=h.length;R<F;++R)(q=h[R]).width=q.horizontal?q.box.fullWidth&&E.availableWidth:E.vBoxMaxWidth,q.height=q.horizontal&&E.hBoxMaxHeight})(Oe.concat(Xe),gt),tl(Oe,yt,gt),tl(Xe,yt,gt)&&tl(Oe,yt,gt),function(h){var E=h.maxPadding;function R(F){var q=Math.max(E[F]-h[F],0);return h[F]+=q,q}h.y+=R("top"),h.x+=R("left"),R("right"),R("bottom")}(yt),Su(Ue.leftAndTop,yt,gt),yt.x+=yt.w,yt.y+=yt.h,Su(Ue.rightAndBottom,yt,gt),h.chartArea={left:yt.left,top:yt.top,right:yt.left+yt.w,bottom:yt.top+yt.h},Ge.each(Ue.chartArea,function(nn){var Pn=nn.box;tc(Pn,h.chartArea),Pn.update(yt.w,yt.h)})}}},Te=function(h){return h&&h.default||h}(Object.freeze({__proto__:null,default:"/*\r\n * DOM element rendering detection\r\n * https://davidwalsh.name/detect-node-insertion\r\n */\r\n@keyframes chartjs-render-animation {\r\n\tfrom { opacity: 0.99; }\r\n\tto { opacity: 1; }\r\n}\r\n\r\n.chartjs-render-monitor {\r\n\tanimation: chartjs-render-animation 0.001s;\r\n}\r\n\r\n/*\r\n * DOM element resizing detection\r\n * https://github.com/marcj/css-element-queries\r\n */\r\n.chartjs-size-monitor,\r\n.chartjs-size-monitor-expand,\r\n.chartjs-size-monitor-shrink {\r\n\tposition: absolute;\r\n\tdirection: ltr;\r\n\tleft: 0;\r\n\ttop: 0;\r\n\tright: 0;\r\n\tbottom: 0;\r\n\toverflow: hidden;\r\n\tpointer-events: none;\r\n\tvisibility: hidden;\r\n\tz-index: -1;\r\n}\r\n\r\n.chartjs-size-monitor-expand > div {\r\n\tposition: absolute;\r\n\twidth: 1000000px;\r\n\theight: 1000000px;\r\n\tleft: 0;\r\n\ttop: 0;\r\n}\r\n\r\n.chartjs-size-monitor-shrink > div {\r\n\tposition: absolute;\r\n\twidth: 200%;\r\n\theight: 200%;\r\n\tleft: 0;\r\n\ttop: 0;\r\n}\r\n"})),Me="$chartjs",xe="chartjs-",Ct=xe+"size-monitor",ur=xe+"render-monitor",Go=["animationstart","webkitAnimationStart"],ms={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function hs(h,E){var R=Ge.getStyle(h,E),F=R&&R.match(/^(\d+)(\.\d+)?px$/);return F?Number(F[1]):void 0}var au=!!function(){var h=!1;try{var E=Object.defineProperty({},"passive",{get:function(){h=!0}});window.addEventListener("e",null,E)}catch(R){}return h}()&&{passive:!0};function Wa(h,E,R){h.addEventListener(E,R,au)}function Rl(h,E,R){h.removeEventListener(E,R,au)}function nc(h,E,R,F,q){return{type:h,chart:E,native:q||null,x:void 0!==R?R:null,y:void 0!==F?F:null}}function Lc(h){var E=document.createElement("div");return E.className=h||"",E}function kc(h,E,R){var F=h[Me]||(h[Me]={}),q=F.resizer=function(h){var E=1e6,R=Lc(Ct),F=Lc(Ct+"-expand"),q=Lc(Ct+"-shrink");F.appendChild(Lc()),q.appendChild(Lc()),R.appendChild(F),R.appendChild(q),R._reset=function(){F.scrollLeft=E,F.scrollTop=E,q.scrollLeft=E,q.scrollTop=E};var de=function(){R._reset(),h()};return Wa(F,"scroll",de.bind(F,"expand")),Wa(q,"scroll",de.bind(q,"shrink")),R}(function(h,E){var R=!1,F=[];return function(){F=Array.prototype.slice.call(arguments),E=E||this,R||(R=!0,Ge.requestAnimFrame.call(window,function(){R=!1,h.apply(E,F)}))}}(function(){if(F.resizer){var de=R.options.maintainAspectRatio&&h.parentNode,ye=de?de.clientWidth:0;E(nc("resize",R)),de&&de.clientWidth<ye&&R.canvas&&E(nc("resize",R))}}));!function(h,E){var R=h[Me]||(h[Me]={}),F=R.renderProxy=function(q){"chartjs-render-animation"===q.animationName&&E()};Ge.each(Go,function(q){Wa(h,q,F)}),R.reflow=!!h.offsetParent,h.classList.add(ur)}(h,function(){if(F.resizer){var de=h.parentNode;de&&de!==q.parentNode&&de.insertBefore(q,de.firstChild),q._reset()}})}function gd(h){var E=h[Me]||{},R=E.resizer;delete E.resizer,function(h){var E=h[Me]||{},R=E.renderProxy;R&&(Ge.each(Go,function(F){Rl(h,F,R)}),delete E.renderProxy),h.classList.remove(ur)}(h),R&&R.parentNode&&R.parentNode.removeChild(R)}var Li={disableCSSInjection:!1,_enabled:"undefined"!=typeof window&&"undefined"!=typeof document,_ensureLoaded:function(h){if(!this.disableCSSInjection){var E=h.getRootNode?h.getRootNode():document;!function(h,E){var R=h[Me]||(h[Me]={});if(!R.containsStyles){R.containsStyles=!0,E="/* Chart.js */\n"+E;var F=document.createElement("style");F.setAttribute("type","text/css"),F.appendChild(document.createTextNode(E)),h.appendChild(F)}}(E.host?E:document.head,Te)}},acquireContext:function(h,E){"string"==typeof h?h=document.getElementById(h):h.length&&(h=h[0]),h&&h.canvas&&(h=h.canvas);var R=h&&h.getContext&&h.getContext("2d");return R&&R.canvas===h?(this._ensureLoaded(h),function(h,E){var R=h.style,F=h.getAttribute("height"),q=h.getAttribute("width");if(h[Me]={initial:{height:F,width:q,style:{display:R.display,height:R.height,width:R.width}}},R.display=R.display||"block",null===q||""===q){var de=hs(h,"width");void 0!==de&&(h.width=de)}if(null===F||""===F)if(""===h.style.height)h.height=h.width/(E.options.aspectRatio||2);else{var ye=hs(h,"height");void 0!==de&&(h.height=ye)}}(h,E),R):null},releaseContext:function(h){var E=h.canvas;if(E[Me]){var R=E[Me].initial;["height","width"].forEach(function(F){var q=R[F];Ge.isNullOrUndef(q)?E.removeAttribute(F):E.setAttribute(F,q)}),Ge.each(R.style||{},function(F,q){E.style[q]=F}),E.width=E.width,delete E[Me]}},addEventListener:function(h,E,R){var F=h.canvas;if("resize"!==E){var q=R[Me]||(R[Me]={});Wa(F,E,(q.proxies||(q.proxies={}))[h.id+"_"+E]=function(Ue){R(function(h,E){var R=ms[h.type]||h.type,F=Ge.getRelativePosition(h,E);return nc(R,E,F.x,F.y,h)}(Ue,h))})}else kc(F,R,h)},removeEventListener:function(h,E,R){var F=h.canvas;if("resize"!==E){var ye=((R[Me]||{}).proxies||{})[h.id+"_"+E];!ye||Rl(F,E,ye)}else gd(F)}};Ge.addEvent=Wa,Ge.removeEvent=Rl;var Aa=Ge.extend({initialize:function(){},acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},Li._enabled?Li:{acquireContext:function(h){return h&&h.canvas&&(h=h.canvas),h&&h.getContext("2d")||null}});br._set("global",{plugins:{}});var Ss={_plugins:[],_cacheId:0,register:function(h){var E=this._plugins;[].concat(h).forEach(function(R){-1===E.indexOf(R)&&E.push(R)}),this._cacheId++},unregister:function(h){var E=this._plugins;[].concat(h).forEach(function(R){var F=E.indexOf(R);-1!==F&&E.splice(F,1)}),this._cacheId++},clear:function(){this._plugins=[],this._cacheId++},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(h,E,R){var de,ye,Ue,Oe,Xe,F=this.descriptors(h),q=F.length;for(de=0;de<q;++de)if("function"==typeof(Xe=(Ue=(ye=F[de]).plugin)[E])&&((Oe=[h].concat(R||[])).push(ye.options),!1===Xe.apply(Ue,Oe)))return!1;return!0},descriptors:function(h){var E=h.$plugins||(h.$plugins={});if(E.id===this._cacheId)return E.descriptors;var R=[],F=[],q=h&&h.config||{},de=q.options&&q.options.plugins||{};return this._plugins.concat(q.plugins||[]).forEach(function(ye){if(-1===R.indexOf(ye)){var Oe=ye.id,Xe=de[Oe];!1!==Xe&&(!0===Xe&&(Xe=Ge.clone(br.global.plugins[Oe])),R.push(ye),F.push({plugin:ye,options:Xe||{}}))}}),E.descriptors=F,E.id=this._cacheId,F},_invalidate:function(h){delete h.$plugins}},$u={constructors:{},defaults:{},registerScaleType:function(h,E,R){this.constructors[h]=E,this.defaults[h]=Ge.clone(R)},getScaleConstructor:function(h){return this.constructors.hasOwnProperty(h)?this.constructors[h]:void 0},getScaleDefaults:function(h){return this.defaults.hasOwnProperty(h)?Ge.merge(Object.create(null),[br.scale,this.defaults[h]]):{}},updateScaleDefaults:function(h,E){var R=this;R.defaults.hasOwnProperty(h)&&(R.defaults[h]=Ge.extend(R.defaults[h],E))},addScalesToLayout:function(h){Ge.each(h.scales,function(E){E.fullWidth=E.options.fullWidth,E.position=E.options.position,E.weight=E.options.weight,Zl.addBox(h,E)})}},yl=Ge.valueOrDefault,Mu=Ge.rtl.getRtlAdapter;br._set("global",{tooltips:{enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretPadding:2,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,borderColor:"rgba(0,0,0,0)",borderWidth:0,callbacks:{beforeTitle:Ge.noop,title:function(h,E){var R="",F=E.labels,q=F?F.length:0;if(h.length>0){var de=h[0];de.label?R=de.label:de.xLabel?R=de.xLabel:q>0&&de.index<q&&(R=F[de.index])}return R},afterTitle:Ge.noop,beforeBody:Ge.noop,beforeLabel:Ge.noop,label:function(h,E){var R=E.datasets[h.datasetIndex].label||"";return R&&(R+=": "),Ge.isNullOrUndef(h.value)?R+=h.yLabel:R+=h.value,R},labelColor:function(h,E){var q=E.getDatasetMeta(h.datasetIndex).data[h.index]._view;return{borderColor:q.borderColor,backgroundColor:q.backgroundColor}},labelTextColor:function(){return this._options.bodyFontColor},afterLabel:Ge.noop,afterBody:Ge.noop,beforeFooter:Ge.noop,footer:Ge.noop,afterFooter:Ge.noop}}});var yu={average:function(h){if(!h.length)return!1;var E,R,F=0,q=0,de=0;for(E=0,R=h.length;E<R;++E){var ye=h[E];if(ye&&ye.hasValue()){var Ue=ye.tooltipPosition();F+=Ue.x,q+=Ue.y,++de}}return{x:F/de,y:q/de}},nearest:function(h,E){var de,ye,Ue,R=E.x,F=E.y,q=Number.POSITIVE_INFINITY;for(de=0,ye=h.length;de<ye;++de){var Oe=h[de];if(Oe&&Oe.hasValue()){var Xe=Oe.getCenterPoint(),gt=Ge.distanceBetweenPoints(E,Xe);gt<q&&(q=gt,Ue=Oe)}}if(Ue){var yt=Ue.tooltipPosition();R=yt.x,F=yt.y}return{x:R,y:F}}};function lu(h,E){return E&&(Ge.isArray(E)?Array.prototype.push.apply(h,E):h.push(E)),h}function js(h){return("string"==typeof h||h instanceof String)&&h.indexOf("\n")>-1?h.split("\n"):h}function Hu(h){var E=h._xScale,R=h._yScale||h._scale,F=h._index,q=h._datasetIndex,de=h._chart.getDatasetMeta(q).controller,ye=de._getIndexScale(),Ue=de._getValueScale();return{xLabel:E?E.getLabelForIndex(F,q):"",yLabel:R?R.getLabelForIndex(F,q):"",label:ye?""+ye.getLabelForIndex(F,q):"",value:Ue?""+Ue.getLabelForIndex(F,q):"",index:F,datasetIndex:q,x:h._model.x,y:h._model.y}}function Uu(h){var E=br.global;return{xPadding:h.xPadding,yPadding:h.yPadding,xAlign:h.xAlign,yAlign:h.yAlign,rtl:h.rtl,textDirection:h.textDirection,bodyFontColor:h.bodyFontColor,_bodyFontFamily:yl(h.bodyFontFamily,E.defaultFontFamily),_bodyFontStyle:yl(h.bodyFontStyle,E.defaultFontStyle),_bodyAlign:h.bodyAlign,bodyFontSize:yl(h.bodyFontSize,E.defaultFontSize),bodySpacing:h.bodySpacing,titleFontColor:h.titleFontColor,_titleFontFamily:yl(h.titleFontFamily,E.defaultFontFamily),_titleFontStyle:yl(h.titleFontStyle,E.defaultFontStyle),titleFontSize:yl(h.titleFontSize,E.defaultFontSize),_titleAlign:h.titleAlign,titleSpacing:h.titleSpacing,titleMarginBottom:h.titleMarginBottom,footerFontColor:h.footerFontColor,_footerFontFamily:yl(h.footerFontFamily,E.defaultFontFamily),_footerFontStyle:yl(h.footerFontStyle,E.defaultFontStyle),footerFontSize:yl(h.footerFontSize,E.defaultFontSize),_footerAlign:h.footerAlign,footerSpacing:h.footerSpacing,footerMarginTop:h.footerMarginTop,caretSize:h.caretSize,cornerRadius:h.cornerRadius,backgroundColor:h.backgroundColor,opacity:0,legendColorBackground:h.multiKeyBackground,displayColors:h.displayColors,borderColor:h.borderColor,borderWidth:h.borderWidth}}function fa(h,E){return"center"===E?h.x+h.width/2:"right"===E?h.x+h.width-h.xPadding:h.x+h.xPadding}function pu(h){return lu([],js(h))}var bl=ar.extend({initialize:function(){this._model=Uu(this._options),this._lastActive=[]},getTitle:function(){var h=this,R=h._options.callbacks,F=R.beforeTitle.apply(h,arguments),q=R.title.apply(h,arguments),de=R.afterTitle.apply(h,arguments),ye=[];return ye=lu(ye,js(F)),ye=lu(ye,js(q)),lu(ye,js(de))},getBeforeBody:function(){return pu(this._options.callbacks.beforeBody.apply(this,arguments))},getBody:function(h,E){var R=this,F=R._options.callbacks,q=[];return Ge.each(h,function(de){var ye={before:[],lines:[],after:[]};lu(ye.before,js(F.beforeLabel.call(R,de,E))),lu(ye.lines,F.label.call(R,de,E)),lu(ye.after,js(F.afterLabel.call(R,de,E))),q.push(ye)}),q},getAfterBody:function(){return pu(this._options.callbacks.afterBody.apply(this,arguments))},getFooter:function(){var h=this,E=h._options.callbacks,R=E.beforeFooter.apply(h,arguments),F=E.footer.apply(h,arguments),q=E.afterFooter.apply(h,arguments),de=[];return de=lu(de,js(R)),de=lu(de,js(F)),lu(de,js(q))},update:function(h){var yt,nn,E=this,R=E._options,F=E._model,q=E._model=Uu(R),de=E._active,ye=E._data,Ue={xAlign:F.xAlign,yAlign:F.yAlign},Oe={x:F.x,y:F.y},Xe={width:F.width,height:F.height},gt={x:F.caretX,y:F.caretY};if(de.length){q.opacity=1;var Pn=[],xn=[];gt=yu[R.position].call(E,de,E._eventPosition);var ir=[];for(yt=0,nn=de.length;yt<nn;++yt)ir.push(Hu(de[yt]));R.filter&&(ir=ir.filter(function(Gr){return R.filter(Gr,ye)})),R.itemSort&&(ir=ir.sort(function(Gr,Pi){return R.itemSort(Gr,Pi,ye)})),Ge.each(ir,function(Gr){Pn.push(R.callbacks.labelColor.call(E,Gr,E._chart)),xn.push(R.callbacks.labelTextColor.call(E,Gr,E._chart))}),q.title=E.getTitle(ir,ye),q.beforeBody=E.getBeforeBody(ir,ye),q.body=E.getBody(ir,ye),q.afterBody=E.getAfterBody(ir,ye),q.footer=E.getFooter(ir,ye),q.x=gt.x,q.y=gt.y,q.caretPadding=R.caretPadding,q.labelColors=Pn,q.labelTextColors=xn,q.dataPoints=ir,Oe=function(h,E,R,F){var q=h.x,de=h.y,Ue=h.caretPadding,Xe=R.xAlign,gt=R.yAlign,yt=h.caretSize+Ue,nn=h.cornerRadius+Ue;return"right"===Xe?q-=E.width:"center"===Xe&&((q-=E.width/2)+E.width>F.width&&(q=F.width-E.width),q<0&&(q=0)),"top"===gt?de+=yt:de-="bottom"===gt?E.height+yt:E.height/2,"center"===gt?"left"===Xe?q+=yt:"right"===Xe&&(q-=yt):"left"===Xe?q-=nn:"right"===Xe&&(q+=nn),{x:q,y:de}}(q,Xe=function(h,E){var R=h._chart.ctx,F=2*E.yPadding,q=0,de=E.body,ye=de.reduce(function(xn,ir){return xn+ir.before.length+ir.lines.length+ir.after.length},0),Ue=E.title.length,Oe=E.footer.length,Xe=E.titleFontSize,gt=E.bodyFontSize,yt=E.footerFontSize;F+=Ue*Xe,F+=Ue?(Ue-1)*E.titleSpacing:0,F+=Ue?E.titleMarginBottom:0,F+=(ye+=E.beforeBody.length+E.afterBody.length)*gt,F+=ye?(ye-1)*E.bodySpacing:0,F+=Oe?E.footerMarginTop:0,F+=Oe*yt,F+=Oe?(Oe-1)*E.footerSpacing:0;var nn=0,Pn=function(xn){q=Math.max(q,R.measureText(xn).width+nn)};return R.font=Ge.fontString(Xe,E._titleFontStyle,E._titleFontFamily),Ge.each(E.title,Pn),R.font=Ge.fontString(gt,E._bodyFontStyle,E._bodyFontFamily),Ge.each(E.beforeBody.concat(E.afterBody),Pn),nn=E.displayColors?gt+2:0,Ge.each(de,function(xn){Ge.each(xn.before,Pn),Ge.each(xn.lines,Pn),Ge.each(xn.after,Pn)}),nn=0,R.font=Ge.fontString(yt,E._footerFontStyle,E._footerFontFamily),Ge.each(E.footer,Pn),{width:q+=2*E.xPadding,height:F}}(this,q),Ue=function(h,E){var R=h._model,F=h._chart,q=h._chart.chartArea,de="center",ye="center";R.y<E.height?ye="top":R.y>F.height-E.height&&(ye="bottom");var Ue,Oe,Xe,gt,yt,nn=(q.left+q.right)/2,Pn=(q.top+q.bottom)/2;"center"===ye?(Ue=function(ir){return ir<=nn},Oe=function(ir){return ir>nn}):(Ue=function(ir){return ir<=E.width/2},Oe=function(ir){return ir>=F.width-E.width/2}),Xe=function(ir){return ir+E.width+R.caretSize+R.caretPadding>F.width},gt=function(ir){return ir-E.width-R.caretSize-R.caretPadding<0},yt=function(ir){return ir<=Pn?"top":"bottom"},Ue(R.x)?(de="left",Xe(R.x)&&(de="center",ye=yt(R.y))):Oe(R.x)&&(de="right",gt(R.x)&&(de="center",ye=yt(R.y)));var xn=h._options;return{xAlign:xn.xAlign?xn.xAlign:de,yAlign:xn.yAlign?xn.yAlign:ye}}(this,Xe),E._chart)}else q.opacity=0;return q.xAlign=Ue.xAlign,q.yAlign=Ue.yAlign,q.x=Oe.x,q.y=Oe.y,q.width=Xe.width,q.height=Xe.height,q.caretX=gt.x,q.caretY=gt.y,E._model=q,h&&R.custom&&R.custom.call(E,q),E},drawCaret:function(h,E){var R=this._chart.ctx,q=this.getCaretPosition(h,E,this._view);R.lineTo(q.x1,q.y1),R.lineTo(q.x2,q.y2),R.lineTo(q.x3,q.y3)},getCaretPosition:function(h,E,R){var F,q,de,ye,Ue,Oe,Xe=R.caretSize,gt=R.cornerRadius,yt=R.xAlign,nn=R.yAlign,Pn=h.x,xn=h.y,ir=E.width,Gr=E.height;if("center"===nn)Ue=xn+Gr/2,"left"===yt?(q=(F=Pn)-Xe,de=F,ye=Ue+Xe,Oe=Ue-Xe):(q=(F=Pn+ir)+Xe,de=F,ye=Ue-Xe,Oe=Ue+Xe);else if("left"===yt?(F=(q=Pn+gt+Xe)-Xe,de=q+Xe):"right"===yt?(F=(q=Pn+ir-gt-Xe)-Xe,de=q+Xe):(F=(q=R.caretX)-Xe,de=q+Xe),"top"===nn)Ue=(ye=xn)-Xe,Oe=ye;else{Ue=(ye=xn+Gr)+Xe,Oe=ye;var Pi=de;de=F,F=Pi}return{x1:F,x2:q,x3:de,y1:ye,y2:Ue,y3:Oe}},drawTitle:function(h,E,R){var de,ye,Ue,F=E.title,q=F.length;if(q){var Oe=Mu(E.rtl,E.x,E.width);for(h.x=fa(E,E._titleAlign),R.textAlign=Oe.textAlign(E._titleAlign),R.textBaseline="middle",de=E.titleFontSize,ye=E.titleSpacing,R.fillStyle=E.titleFontColor,R.font=Ge.fontString(de,E._titleFontStyle,E._titleFontFamily),Ue=0;Ue<q;++Ue)R.fillText(F[Ue],Oe.x(h.x),h.y+de/2),h.y+=de+ye,Ue+1===q&&(h.y+=E.titleMarginBottom-ye)}},drawBody:function(h,E,R){var nn,Pn,xn,ir,Gr,Pi,Zo,Lo,F=E.bodyFontSize,q=E.bodySpacing,de=E._bodyAlign,ye=E.body,Ue=E.displayColors,Oe=0,Xe=Ue?fa(E,"left"):0,gt=Mu(E.rtl,E.x,E.width),yt=function(dl){R.fillText(dl,gt.x(h.x+Oe),h.y+F/2),h.y+=F+q},Gs=gt.textAlign(de);for(R.textAlign=de,R.textBaseline="middle",R.font=Ge.fontString(F,E._bodyFontStyle,E._bodyFontFamily),h.x=fa(E,Gs),R.fillStyle=E.bodyFontColor,Ge.each(E.beforeBody,yt),Oe=Ue&&"right"!==Gs?"center"===de?F/2+1:F+2:0,Gr=0,Zo=ye.length;Gr<Zo;++Gr){for(nn=ye[Gr],xn=E.labelColors[Gr],R.fillStyle=Pn=E.labelTextColors[Gr],Ge.each(nn.before,yt),Pi=0,Lo=(ir=nn.lines).length;Pi<Lo;++Pi){if(Ue){var Xs=gt.x(Xe);R.fillStyle=E.legendColorBackground,R.fillRect(gt.leftForLtr(Xs,F),h.y,F,F),R.lineWidth=1,R.strokeStyle=xn.borderColor,R.strokeRect(gt.leftForLtr(Xs,F),h.y,F,F),R.fillStyle=xn.backgroundColor,R.fillRect(gt.leftForLtr(gt.xPlus(Xs,1),F-2),h.y+1,F-2,F-2),R.fillStyle=Pn}yt(ir[Pi])}Ge.each(nn.after,yt)}Oe=0,Ge.each(E.afterBody,yt),h.y-=q},drawFooter:function(h,E,R){var de,ye,F=E.footer,q=F.length;if(q){var Ue=Mu(E.rtl,E.x,E.width);for(h.x=fa(E,E._footerAlign),h.y+=E.footerMarginTop,R.textAlign=Ue.textAlign(E._footerAlign),R.textBaseline="middle",de=E.footerFontSize,R.fillStyle=E.footerFontColor,R.font=Ge.fontString(de,E._footerFontStyle,E._footerFontFamily),ye=0;ye<q;++ye)R.fillText(F[ye],Ue.x(h.x),h.y+de/2),h.y+=de+E.footerSpacing}},drawBackground:function(h,E,R,F){R.fillStyle=E.backgroundColor,R.strokeStyle=E.borderColor,R.lineWidth=E.borderWidth;var q=E.xAlign,de=E.yAlign,ye=h.x,Ue=h.y,Oe=F.width,Xe=F.height,gt=E.cornerRadius;R.beginPath(),R.moveTo(ye+gt,Ue),"top"===de&&this.drawCaret(h,F),R.lineTo(ye+Oe-gt,Ue),R.quadraticCurveTo(ye+Oe,Ue,ye+Oe,Ue+gt),"center"===de&&"right"===q&&this.drawCaret(h,F),R.lineTo(ye+Oe,Ue+Xe-gt),R.quadraticCurveTo(ye+Oe,Ue+Xe,ye+Oe-gt,Ue+Xe),"bottom"===de&&this.drawCaret(h,F),R.lineTo(ye+gt,Ue+Xe),R.quadraticCurveTo(ye,Ue+Xe,ye,Ue+Xe-gt),"center"===de&&"left"===q&&this.drawCaret(h,F),R.lineTo(ye,Ue+gt),R.quadraticCurveTo(ye,Ue,ye+gt,Ue),R.closePath(),R.fill(),E.borderWidth>0&&R.stroke()},draw:function(){var h=this._chart.ctx,E=this._view;if(0!==E.opacity){var R={width:E.width,height:E.height},F={x:E.x,y:E.y},q=Math.abs(E.opacity<.001)?0:E.opacity;this._options.enabled&&(E.title.length||E.beforeBody.length||E.body.length||E.afterBody.length||E.footer.length)&&(h.save(),h.globalAlpha=q,this.drawBackground(F,E,h,R),F.y+=E.yPadding,Ge.rtl.overrideTextDirection(h,E.textDirection),this.drawTitle(F,E,h),this.drawBody(F,E,h),this.drawFooter(F,E,h),Ge.rtl.restoreTextDirection(h,E.textDirection),h.restore())}},handleEvent:function(h){var F,E=this,R=E._options;return E._lastActive=E._lastActive||[],"mouseout"===h.type?E._active=[]:(E._active=E._chart.getElementsAtEventForMode(h,R.mode,R),R.reverse&&E._active.reverse()),(F=!Ge.arrayEquals(E._active,E._lastActive))&&(E._lastActive=E._active,(R.enabled||R.custom)&&(E._eventPosition={x:h.x,y:h.y},E.update(!0),E.pivot())),F}});bl.positioners=yu;var El=Ge.valueOrDefault;function Ul(){return Ge.merge(Object.create(null),[].slice.call(arguments),{merger:function(h,E,R,F){if("xAxes"===h||"yAxes"===h){var de,ye,Ue,q=R[h].length;for(E[h]||(E[h]=[]),de=0;de<q;++de)ye=El((Ue=R[h][de]).type,"xAxes"===h?"category":"linear"),de>=E[h].length&&E[h].push({}),Ge.merge(E[h][de],!E[h][de].type||Ue.type&&Ue.type!==E[h][de].type?[$u.getScaleDefaults(ye),Ue]:Ue)}else Ge._merger(h,E,R,F)}})}function ks(){return Ge.merge(Object.create(null),[].slice.call(arguments),{merger:function(h,E,R,F){var q=E[h]||Object.create(null),de=R[h];"scales"===h?E[h]=Ul(q,de):"scale"===h?E[h]=Ge.merge(q,[$u.getScaleDefaults(de.type),de]):Ge._merger(h,E,R,F)}})}function Ae(h){var E=h.options;Ge.each(h.scales,function(R){Zl.removeBox(h,R)}),E=ks(br.global,br[h.config.type],E),h.options=h.config.options=E,h.ensureScalesHaveIDs(),h.buildOrUpdateScales(),h.tooltip._options=E.tooltips,h.tooltip.initialize()}function st(h,E,R){var F,q=function(de){return de.id===F};do{F=E+R++}while(Ge.findIndex(h,q)>=0);return F}function vt(h){return"top"===h||"bottom"===h}function ut(h,E){return function(R,F){return R[h]===F[h]?R[E]-F[E]:R[h]-F[h]}}br._set("global",{elements:{},events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,maintainAspectRatio:!0,responsive:!0,responsiveAnimationDuration:0});var un=function(h,E){return this.construct(h,E),this};Ge.extend(un.prototype,{construct:function(h,E){var R=this;E=function(h){var E=(h=h||Object.create(null)).data=h.data||{};return E.datasets=E.datasets||[],E.labels=E.labels||[],h.options=ks(br.global,br[h.type],h.options||{}),h}(E);var F=Aa.acquireContext(h,E),q=F&&F.canvas,de=q&&q.height,ye=q&&q.width;R.id=Ge.uid(),R.ctx=F,R.canvas=q,R.config=E,R.width=ye,R.height=de,R.aspectRatio=de?ye/de:null,R.options=E.options,R._bufferedRender=!1,R._layers=[],R.chart=R,R.controller=R,un.instances[R.id]=R,Object.defineProperty(R,"data",{get:function(){return R.config.data},set:function(Ue){R.config.data=Ue}}),F&&q?(R.initialize(),R.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var h=this;return Ss.notify(h,"beforeInit"),Ge.retinaScale(h,h.options.devicePixelRatio),h.bindEvents(),h.options.responsive&&h.resize(!0),h.initToolTip(),Ss.notify(h,"afterInit"),h},clear:function(){return Ge.canvas.clear(this),this},stop:function(){return vo.cancelAnimation(this),this},resize:function(h){var E=this,R=E.options,F=E.canvas,q=R.maintainAspectRatio&&E.aspectRatio||null,de=Math.max(0,Math.floor(Ge.getMaximumWidth(F))),ye=Math.max(0,Math.floor(q?de/q:Ge.getMaximumHeight(F)));if((E.width!==de||E.height!==ye)&&(F.width=E.width=de,F.height=E.height=ye,F.style.width=de+"px",F.style.height=ye+"px",Ge.retinaScale(E,R.devicePixelRatio),!h)){var Ue={width:de,height:ye};Ss.notify(E,"resize",[Ue]),R.onResize&&R.onResize(E,Ue),E.stop(),E.update({duration:R.responsiveAnimationDuration})}},ensureScalesHaveIDs:function(){var h=this.options,E=h.scales||{},R=h.scale;Ge.each(E.xAxes,function(F,q){F.id||(F.id=st(E.xAxes,"x-axis-",q))}),Ge.each(E.yAxes,function(F,q){F.id||(F.id=st(E.yAxes,"y-axis-",q))}),R&&(R.id=R.id||"scale")},buildOrUpdateScales:function(){var h=this,E=h.options,R=h.scales||{},F=[],q=Object.keys(R).reduce(function(de,ye){return de[ye]=!1,de},{});E.scales&&(F=F.concat((E.scales.xAxes||[]).map(function(de){return{options:de,dtype:"category",dposition:"bottom"}}),(E.scales.yAxes||[]).map(function(de){return{options:de,dtype:"linear",dposition:"left"}}))),E.scale&&F.push({options:E.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),Ge.each(F,function(de){var ye=de.options,Ue=ye.id,Oe=El(ye.type,de.dtype);vt(ye.position)!==vt(de.dposition)&&(ye.position=de.dposition),q[Ue]=!0;var Xe=null;if(Ue in R&&R[Ue].type===Oe)(Xe=R[Ue]).options=ye,Xe.ctx=h.ctx,Xe.chart=h;else{var gt=$u.getScaleConstructor(Oe);if(!gt)return;Xe=new gt({id:Ue,type:Oe,options:ye,ctx:h.ctx,chart:h}),R[Xe.id]=Xe}Xe.mergeTicksOptions(),de.isDefault&&(h.scale=Xe)}),Ge.each(q,function(de,ye){de||delete R[ye]}),h.scales=R,$u.addScalesToLayout(this)},buildOrUpdateControllers:function(){var F,q,h=this,E=[],R=h.data.datasets;for(F=0,q=R.length;F<q;F++){var de=R[F],ye=h.getDatasetMeta(F),Ue=de.type||h.config.type;if(ye.type&&ye.type!==Ue&&(h.destroyDatasetMeta(F),ye=h.getDatasetMeta(F)),ye.type=Ue,ye.order=de.order||0,ye.index=F,ye.controller)ye.controller.updateIndex(F),ye.controller.linkScales();else{var Oe=pi[ye.type];if(void 0===Oe)throw new Error('"'+ye.type+'" is not a chart type.');ye.controller=new Oe(h,F),E.push(ye.controller)}}return E},resetElements:function(){var h=this;Ge.each(h.data.datasets,function(E,R){h.getDatasetMeta(R).controller.reset()},h)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(h){var R,F,E=this;if((!h||"object"!=typeof h)&&(h={duration:h,lazy:arguments[1]}),Ae(E),Ss._invalidate(E),!1!==Ss.notify(E,"beforeUpdate")){E.tooltip._data=E.data;var q=E.buildOrUpdateControllers();for(R=0,F=E.data.datasets.length;R<F;R++)E.getDatasetMeta(R).controller.buildOrUpdateElements();E.updateLayout(),E.options.animation&&E.options.animation.duration&&Ge.each(q,function(de){de.reset()}),E.updateDatasets(),E.tooltip.initialize(),E.lastActive=[],Ss.notify(E,"afterUpdate"),E._layers.sort(ut("z","_idx")),E._bufferedRender?E._bufferedRequest={duration:h.duration,easing:h.easing,lazy:h.lazy}:E.render(h)}},updateLayout:function(){var h=this;!1!==Ss.notify(h,"beforeLayout")&&(Zl.update(this,this.width,this.height),h._layers=[],Ge.each(h.boxes,function(E){E._configure&&E._configure(),h._layers.push.apply(h._layers,E._layers())},h),h._layers.forEach(function(E,R){E._idx=R}),Ss.notify(h,"afterScaleUpdate"),Ss.notify(h,"afterLayout"))},updateDatasets:function(){var h=this;if(!1!==Ss.notify(h,"beforeDatasetsUpdate")){for(var E=0,R=h.data.datasets.length;E<R;++E)h.updateDataset(E);Ss.notify(h,"afterDatasetsUpdate")}},updateDataset:function(h){var E=this,R=E.getDatasetMeta(h),F={meta:R,index:h};!1!==Ss.notify(E,"beforeDatasetUpdate",[F])&&(R.controller._update(),Ss.notify(E,"afterDatasetUpdate",[F]))},render:function(h){var E=this;(!h||"object"!=typeof h)&&(h={duration:h,lazy:arguments[1]});var R=E.options.animation,F=El(h.duration,R&&R.duration),q=h.lazy;if(!1!==Ss.notify(E,"beforeRender")){var de=function(Ue){Ss.notify(E,"afterRender"),Ge.callback(R&&R.onComplete,[Ue],E)};if(R&&F){var ye=new lo({numSteps:F/16.66,easing:h.easing||R.easing,render:function(Ue,Oe){var gt=Oe.currentStep,yt=gt/Oe.numSteps;Ue.draw((0,Ge.easing.effects[Oe.easing])(yt),yt,gt)},onAnimationProgress:R.onProgress,onAnimationComplete:de});vo.addAnimation(E,ye,F,q)}else E.draw(),de(new lo({numSteps:0,chart:E}));return E}},draw:function(h){var R,F,E=this;if(E.clear(),Ge.isNullOrUndef(h)&&(h=1),E.transition(h),!(E.width<=0||E.height<=0)&&!1!==Ss.notify(E,"beforeDraw",[h])){for(F=E._layers,R=0;R<F.length&&F[R].z<=0;++R)F[R].draw(E.chartArea);for(E.drawDatasets(h);R<F.length;++R)F[R].draw(E.chartArea);E._drawTooltip(h),Ss.notify(E,"afterDraw",[h])}},transition:function(h){for(var E=this,R=0,F=(E.data.datasets||[]).length;R<F;++R)E.isDatasetVisible(R)&&E.getDatasetMeta(R).controller.transition(h);E.tooltip.transition(h)},_getSortedDatasetMetas:function(h){var q,de,E=this,F=[];for(q=0,de=(E.data.datasets||[]).length;q<de;++q)(!h||E.isDatasetVisible(q))&&F.push(E.getDatasetMeta(q));return F.sort(ut("order","index")),F},_getSortedVisibleDatasetMetas:function(){return this._getSortedDatasetMetas(!0)},drawDatasets:function(h){var R,F,E=this;if(!1!==Ss.notify(E,"beforeDatasetsDraw",[h])){for(F=(R=E._getSortedVisibleDatasetMetas()).length-1;F>=0;--F)E.drawDataset(R[F],h);Ss.notify(E,"afterDatasetsDraw",[h])}},drawDataset:function(h,E){var F={meta:h,index:h.index,easingValue:E};!1!==Ss.notify(this,"beforeDatasetDraw",[F])&&(h.controller.draw(E),Ss.notify(this,"afterDatasetDraw",[F]))},_drawTooltip:function(h){var E=this,R=E.tooltip,F={tooltip:R,easingValue:h};!1!==Ss.notify(E,"beforeTooltipDraw",[F])&&(R.draw(),Ss.notify(E,"afterTooltipDraw",[F]))},getElementAtEvent:function(h){return sl.modes.single(this,h)},getElementsAtEvent:function(h){return sl.modes.label(this,h,{intersect:!0})},getElementsAtXAxis:function(h){return sl.modes["x-axis"](this,h,{intersect:!0})},getElementsAtEventForMode:function(h,E,R){var F=sl.modes[E];return"function"==typeof F?F(this,h,R):[]},getDatasetAtEvent:function(h){return sl.modes.dataset(this,h,{intersect:!0})},getDatasetMeta:function(h){var E=this,R=E.data.datasets[h];R._meta||(R._meta={});var F=R._meta[E.id];return F||(F=R._meta[E.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:R.order||0,index:h}),F},getVisibleDatasetCount:function(){for(var h=0,E=0,R=this.data.datasets.length;E<R;++E)this.isDatasetVisible(E)&&h++;return h},isDatasetVisible:function(h){var E=this.getDatasetMeta(h);return"boolean"==typeof E.hidden?!E.hidden:!this.data.datasets[h].hidden},generateLegend:function(){return this.options.legendCallback(this)},destroyDatasetMeta:function(h){var E=this.id,R=this.data.datasets[h],F=R._meta&&R._meta[E];F&&(F.controller.destroy(),delete R._meta[E])},destroy:function(){var R,F,h=this,E=h.canvas;for(h.stop(),R=0,F=h.data.datasets.length;R<F;++R)h.destroyDatasetMeta(R);E&&(h.unbindEvents(),Ge.canvas.clear(h),Aa.releaseContext(h.ctx),h.canvas=null,h.ctx=null),Ss.notify(h,"destroy"),delete un.instances[h.id]},toBase64Image:function(){return this.canvas.toDataURL.apply(this.canvas,arguments)},initToolTip:function(){var h=this;h.tooltip=new bl({_chart:h,_chartInstance:h,_data:h.data,_options:h.options.tooltips},h)},bindEvents:function(){var h=this,E=h._listeners={},R=function(){h.eventHandler.apply(h,arguments)};Ge.each(h.options.events,function(F){Aa.addEventListener(h,F,R),E[F]=R}),h.options.responsive&&(R=function(){h.resize()},Aa.addEventListener(h,"resize",R),E.resize=R)},unbindEvents:function(){var h=this,E=h._listeners;!E||(delete h._listeners,Ge.each(E,function(R,F){Aa.removeEventListener(h,F,R)}))},updateHoverStyle:function(h,E,R){var q,de,ye,F=R?"set":"remove";for(de=0,ye=h.length;de<ye;++de)(q=h[de])&&this.getDatasetMeta(q._datasetIndex).controller[F+"HoverStyle"](q);"dataset"===E&&this.getDatasetMeta(h[0]._datasetIndex).controller["_"+F+"DatasetHoverStyle"]()},eventHandler:function(h){var E=this,R=E.tooltip;if(!1!==Ss.notify(E,"beforeEvent",[h])){E._bufferedRender=!0,E._bufferedRequest=null;var F=E.handleEvent(h);R&&(F=R._start?R.handleEvent(h):F|R.handleEvent(h)),Ss.notify(E,"afterEvent",[h]);var q=E._bufferedRequest;return q?E.render(q):F&&!E.animating&&(E.stop(),E.render({duration:E.options.hover.animationDuration,lazy:!0})),E._bufferedRender=!1,E._bufferedRequest=null,E}},handleEvent:function(h){var q,E=this,R=E.options||{},F=R.hover;return E.lastActive=E.lastActive||[],E.active="mouseout"===h.type?[]:E.getElementsAtEventForMode(h,F.mode,F),Ge.callback(R.onHover||R.hover.onHover,[h.native,E.active],E),("mouseup"===h.type||"click"===h.type)&&R.onClick&&R.onClick.call(E,h.native,E.active),E.lastActive.length&&E.updateHoverStyle(E.lastActive,F.mode,!1),E.active.length&&F.mode&&E.updateHoverStyle(E.active,F.mode,!0),q=!Ge.arrayEquals(E.active,E.lastActive),E.lastActive=E.active,q}}),un.instances={};var mn=un;un.Controller=un,un.types={},Ge.configMerge=ks,Ge.scaleMerge=Ul;function zr(){throw new Error("This method is not implemented: either no adapter can be found or an incomplete integration was provided.")}function gi(h){this.options=h||{}}Ge.extend(gi.prototype,{formats:zr,parse:zr,format:zr,add:zr,diff:zr,startOf:zr,endOf:zr,_create:function(h){return h}}),gi.override=function(h){Ge.extend(gi.prototype,h)};var Io={_date:gi},Fo={formatters:{values:function(h){return Ge.isArray(h)?h:""+h},linear:function(h,E,R){var F=R.length>3?R[2]-R[1]:R[1]-R[0];Math.abs(F)>1&&h!==Math.floor(h)&&(F=h-Math.floor(h));var q=Ge.log10(Math.abs(F)),de="";if(0!==h)if(Math.max(Math.abs(R[0]),Math.abs(R[R.length-1]))<1e-4){var Ue=Ge.log10(Math.abs(h)),Oe=Math.floor(Ue)-Math.floor(q);Oe=Math.max(Math.min(Oe,20),0),de=h.toExponential(Oe)}else{var Xe=-1*Math.floor(q);Xe=Math.max(Math.min(Xe,20),0),de=h.toFixed(Xe)}else de="0";return de},logarithmic:function(h,E,R){var F=h/Math.pow(10,Math.floor(Ge.log10(h)));return 0===h?"0":1===F||2===F||5===F||0===E||E===R.length-1?h.toExponential():""}}},In=Ge.isArray,Cr=Ge.isNullOrUndef,hr=Ge.valueOrDefault,ao=Ge.valueAtIndexOrDefault;function Na(h,E,R){var Xe,F=h.getTicks().length,q=Math.min(E,F-1),de=h.getPixelForTick(q),ye=h._startPixel,Ue=h._endPixel;if(!(R&&(Xe=1===F?Math.max(de-ye,Ue-de):0===E?(h.getPixelForTick(1)-de)/2:(de-h.getPixelForTick(q-1))/2,de+=q<E?Xe:-Xe,de<ye-1e-6||de>Ue+1e-6)))return de}function Qs(h,E,R,F){var gt,yt,nn,Pn,xn,ir,Gr,Pi,Zo,Lo,Gs,Xs,dl,q=R.length,de=[],ye=[],Ue=[],Oe=0,Xe=0;for(gt=0;gt<q;++gt){if(Pn=R[gt].label,h.font=ir=(xn=R[gt].major?E.major:E.minor).string,Gr=F[ir]=F[ir]||{data:{},gc:[]},Pi=xn.lineHeight,Zo=Lo=0,Cr(Pn)||In(Pn)){if(In(Pn))for(yt=0,nn=Pn.length;yt<nn;++yt)!Cr(Gs=Pn[yt])&&!In(Gs)&&(Zo=Ge.measureText(h,Gr.data,Gr.gc,Zo,Gs),Lo+=Pi)}else Zo=Ge.measureText(h,Gr.data,Gr.gc,Zo,Pn),Lo=Pi;de.push(Zo),ye.push(Lo),Ue.push(Pi/2),Oe=Math.max(Zo,Oe),Xe=Math.max(Lo,Xe)}function ha(ia){return{width:de[ia]||0,height:ye[ia]||0,offset:Ue[ia]||0}}return function(h,E){Ge.each(h,function(R){var de,F=R.gc,q=F.length/2;if(q>E){for(de=0;de<q;++de)delete R.data[F[de]];F.splice(0,q)}})}(F,q),Xs=de.indexOf(Oe),dl=ye.indexOf(Xe),{first:ha(0),last:ha(q-1),widest:ha(Xs),highest:ha(dl)}}function ed(h){return h.drawTicks?h.tickMarkLength:0}function $c(h){var E,R;return h.display?(E=Ge.options._parseFont(h),R=Ge.options.toPadding(h.padding),E.lineHeight+R.height):0}function Gl(h,E){return Ge.extend(Ge.options._parseFont({fontFamily:hr(E.fontFamily,h.fontFamily),fontSize:hr(E.fontSize,h.fontSize),fontStyle:hr(E.fontStyle,h.fontStyle),lineHeight:hr(E.lineHeight,h.lineHeight)}),{color:Ge.options.resolve([E.fontColor,h.fontColor,br.global.defaultFontColor])})}function $i(h){var E=Gl(h,h.minor);return{minor:E,major:h.major.enabled?Gl(h,h.major):E}}function xo(h){var R,F,q,E=[];for(F=0,q=h.length;F<q;++F)void 0!==(R=h[F])._index&&E.push(R);return E}function md(h,E,R,F){var Ue,Oe,Xe,gt,q=hr(R,0),de=Math.min(hr(F,h.length),h.length),ye=0;for(E=Math.ceil(E),F&&(E=(Ue=F-R)/Math.floor(Ue/E)),gt=q;gt<0;)ye++,gt=Math.round(q+ye*E);for(Oe=Math.max(q,0);Oe<de;Oe++)Xe=h[Oe],Oe===gt?(Xe._index=Oe,ye++,gt=Math.round(q+ye*E)):delete Xe.label}br._set("scale",{display:!0,position:"left",offset:!1,gridLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickMarkLength:10,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",zeroLineBorderDash:[],zeroLineBorderDashOffset:0,offsetGridLines:!1,borderDash:[],borderDashOffset:0},scaleLabel:{display:!1,labelString:"",padding:{top:4,bottom:4}},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:0,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:Fo.formatters.values,minor:{},major:{}}});var Mn=ar.extend({zeroLineIndex:0,getPadding:function(){var h=this;return{left:h.paddingLeft||0,top:h.paddingTop||0,right:h.paddingRight||0,bottom:h.paddingBottom||0}},getTicks:function(){return this._ticks},_getLabels:function(){var h=this.chart.data;return this.options.labels||(this.isHorizontal()?h.xLabels:h.yLabels)||h.labels||[]},mergeTicksOptions:function(){},beforeUpdate:function(){Ge.callback(this.options.beforeUpdate,[this])},update:function(h,E,R){var ye,Ue,Oe,Xe,gt,F=this,q=F.options.ticks,de=q.sampleSize;if(F.beforeUpdate(),F.maxWidth=h,F.maxHeight=E,F.margins=Ge.extend({left:0,right:0,top:0,bottom:0},R),F._ticks=null,F.ticks=null,F._labelSizes=null,F._maxLabelLines=0,F.longestLabelWidth=0,F.longestTextCache=F.longestTextCache||{},F._gridLineItems=null,F._labelItems=null,F.beforeSetDimensions(),F.setDimensions(),F.afterSetDimensions(),F.beforeDataLimits(),F.determineDataLimits(),F.afterDataLimits(),F.beforeBuildTicks(),Xe=F.buildTicks()||[],(!(Xe=F.afterBuildTicks(Xe)||Xe)||!Xe.length)&&F.ticks)for(Xe=[],ye=0,Ue=F.ticks.length;ye<Ue;++ye)Xe.push({value:F.ticks[ye],major:!1});return F._ticks=Xe,Oe=F._convertTicksToLabels((gt=de<Xe.length)?function(h,E){for(var R=[],F=h.length/E,q=0,de=h.length;q<de;q+=F)R.push(h[Math.floor(q)]);return R}(Xe,de):Xe),F._configure(),F.beforeCalculateTickRotation(),F.calculateTickRotation(),F.afterCalculateTickRotation(),F.beforeFit(),F.fit(),F.afterFit(),F._ticksToDraw=q.display&&(q.autoSkip||"auto"===q.source)?F._autoSkip(Xe):Xe,gt&&(Oe=F._convertTicksToLabels(F._ticksToDraw)),F.ticks=Oe,F.afterUpdate(),F.minSize},_configure:function(){var R,F,h=this,E=h.options.ticks.reverse;h.isHorizontal()?(R=h.left,F=h.right):(R=h.top,F=h.bottom,E=!E),h._startPixel=R,h._endPixel=F,h._reversePixels=E,h._length=F-R},afterUpdate:function(){Ge.callback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){Ge.callback(this.options.beforeSetDimensions,[this])},setDimensions:function(){var h=this;h.isHorizontal()?(h.width=h.maxWidth,h.left=0,h.right=h.width):(h.height=h.maxHeight,h.top=0,h.bottom=h.height),h.paddingLeft=0,h.paddingTop=0,h.paddingRight=0,h.paddingBottom=0},afterSetDimensions:function(){Ge.callback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){Ge.callback(this.options.beforeDataLimits,[this])},determineDataLimits:Ge.noop,afterDataLimits:function(){Ge.callback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){Ge.callback(this.options.beforeBuildTicks,[this])},buildTicks:Ge.noop,afterBuildTicks:function(h){var E=this;return In(h)&&h.length?Ge.callback(E.options.afterBuildTicks,[E,h]):(E.ticks=Ge.callback(E.options.afterBuildTicks,[E,E.ticks])||E.ticks,h)},beforeTickToLabelConversion:function(){Ge.callback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var h=this,E=h.options.ticks;h.ticks=h.ticks.map(E.userCallback||E.callback,this)},afterTickToLabelConversion:function(){Ge.callback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){Ge.callback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var Ue,Oe,Xe,gt,yt,nn,Pn,h=this,E=h.options,R=E.ticks,F=h.getTicks().length,q=R.minRotation||0,de=R.maxRotation,ye=q;!h._isVisible()||!R.display||q>=de||F<=1||!h.isHorizontal()?h.labelRotation=q:(Oe=(Ue=h._getLabelSizes()).widest.width,Xe=Ue.highest.height-Ue.highest.offset,gt=Math.min(h.maxWidth,h.chart.width-Oe),Oe+6>(yt=E.offset?h.maxWidth/F:gt/(F-1))&&(yt=gt/(F-(E.offset?.5:1)),nn=h.maxHeight-ed(E.gridLines)-R.padding-$c(E.scaleLabel),Pn=Math.sqrt(Oe*Oe+Xe*Xe),ye=Ge.toDegrees(Math.min(Math.asin(Math.min((Ue.highest.height+6)/yt,1)),Math.asin(Math.min(nn/Pn,1))-Math.asin(Xe/Pn))),ye=Math.max(q,Math.min(de,ye))),h.labelRotation=ye)},afterCalculateTickRotation:function(){Ge.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){Ge.callback(this.options.beforeFit,[this])},fit:function(){var h=this,E=h.minSize={width:0,height:0},R=h.chart,F=h.options,q=F.ticks,de=F.scaleLabel,ye=F.gridLines,Ue=h._isVisible(),Oe="bottom"===F.position,Xe=h.isHorizontal();if(Xe?E.width=h.maxWidth:Ue&&(E.width=ed(ye)+$c(de)),Xe?Ue&&(E.height=ed(ye)+$c(de)):E.height=h.maxHeight,q.display&&Ue){var gt=$i(q),yt=h._getLabelSizes(),nn=yt.first,Pn=yt.last,xn=yt.widest,ir=yt.highest,Gr=.4*gt.minor.lineHeight,Pi=q.padding;if(Xe){var Zo=0!==h.labelRotation,Lo=Ge.toRadians(h.labelRotation),Gs=Math.cos(Lo),Xs=Math.sin(Lo);E.height=Math.min(h.maxHeight,E.height+(Xs*xn.width+Gs*(ir.height-(Zo?ir.offset:0))+(Zo?0:Gr))+Pi);var Pa,il,ha=h.getPixelForTick(0)-h.left,ia=h.right-h.getPixelForTick(h.getTicks().length-1);Zo?(Pa=Oe?Gs*nn.width+Xs*nn.offset:Xs*(nn.height-nn.offset),il=Oe?Xs*(Pn.height-Pn.offset):Gs*Pn.width+Xs*Pn.offset):(Pa=nn.width/2,il=Pn.width/2),h.paddingLeft=Math.max((Pa-ha)*h.width/(h.width-ha),0)+3,h.paddingRight=Math.max((il-ia)*h.width/(h.width-ia),0)+3}else E.width=Math.min(h.maxWidth,E.width+(q.mirror?0:xn.width+Pi+Gr)),h.paddingTop=nn.height/2,h.paddingBottom=Pn.height/2}h.handleMargins(),Xe?(h.width=h._length=R.width-h.margins.left-h.margins.right,h.height=E.height):(h.width=E.width,h.height=h._length=R.height-h.margins.top-h.margins.bottom)},handleMargins:function(){var h=this;h.margins&&(h.margins.left=Math.max(h.paddingLeft,h.margins.left),h.margins.top=Math.max(h.paddingTop,h.margins.top),h.margins.right=Math.max(h.paddingRight,h.margins.right),h.margins.bottom=Math.max(h.paddingBottom,h.margins.bottom))},afterFit:function(){Ge.callback(this.options.afterFit,[this])},isHorizontal:function(){var h=this.options.position;return"top"===h||"bottom"===h},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(h){if(Cr(h))return NaN;if(("number"==typeof h||h instanceof Number)&&!isFinite(h))return NaN;if(h)if(this.isHorizontal()){if(void 0!==h.x)return this.getRightValue(h.x)}else if(void 0!==h.y)return this.getRightValue(h.y);return h},_convertTicksToLabels:function(h){var R,F,q,E=this;for(E.ticks=h.map(function(de){return de.value}),E.beforeTickToLabelConversion(),R=E.convertTicksToLabels(h)||E.ticks,E.afterTickToLabelConversion(),F=0,q=h.length;F<q;++F)h[F].label=R[F];return R},_getLabelSizes:function(){var h=this,E=h._labelSizes;return E||(h._labelSizes=E=Qs(h.ctx,$i(h.options.ticks),h.getTicks(),h.longestTextCache),h.longestLabelWidth=E.widest.width),E},_parseValue:function(h){var E,R,F,q;return In(h)?(E=+this.getRightValue(h[0]),R=+this.getRightValue(h[1]),F=Math.min(E,R),q=Math.max(E,R)):(E=void 0,R=h=+this.getRightValue(h),F=h,q=h),{min:F,max:q,start:E,end:R}},_getScaleLabel:function(h){var E=this._parseValue(h);return void 0!==E.start?"["+E.start+", "+E.end+"]":+this.getRightValue(h)},getLabelForIndex:Ge.noop,getPixelForValue:Ge.noop,getValueForPixel:Ge.noop,getPixelForTick:function(h){var E=this,R=E.options.offset,F=E._ticks.length,q=1/Math.max(F-(R?0:1),1);return h<0||h>F-1?null:E.getPixelForDecimal(h*q+(R?q/2:0))},getPixelForDecimal:function(h){var E=this;return E._reversePixels&&(h=1-h),E._startPixel+h*E._length},getDecimalForPixel:function(h){var E=(h-this._startPixel)/this._length;return this._reversePixels?1-E:E},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var h=this,E=h.min,R=h.max;return h.beginAtZero?0:E<0&&R<0?R:E>0&&R>0?E:0},_autoSkip:function(h){var Xe,gt,yt,nn,E=this,R=E.options.ticks,F=E._length,q=R.maxTicksLimit||F/E._tickSize()+1,de=R.major.enabled?function(h){var R,F,E=[];for(R=0,F=h.length;R<F;R++)h[R].major&&E.push(R);return E}(h):[],ye=de.length,Ue=de[0],Oe=de[ye-1];if(ye>q)return function(h,E,R){var de,ye,F=0,q=E[0];for(R=Math.ceil(R),de=0;de<h.length;de++)ye=h[de],de===q?(ye._index=de,q=E[++F*R]):delete ye.label}(h,de,ye/q),xo(h);if(yt=function(h,E,R,F){var ye,Ue,Oe,Xe,q=function(h){var R,F,E=h.length;if(E<2)return!1;for(F=h[0],R=1;R<E;++R)if(h[R]-h[R-1]!==F)return!1;return F}(h),de=(E.length-1)/F;if(!q)return Math.max(de,1);for(Oe=0,Xe=(ye=Ge.math._factorize(q)).length-1;Oe<Xe;Oe++)if((Ue=ye[Oe])>de)return Ue;return Math.max(de,1)}(de,h,0,q),ye>0){for(Xe=0,gt=ye-1;Xe<gt;Xe++)md(h,yt,de[Xe],de[Xe+1]);return md(h,yt,Ge.isNullOrUndef(nn=ye>1?(Oe-Ue)/(ye-1):null)?0:Ue-nn,Ue),md(h,yt,Oe,Ge.isNullOrUndef(nn)?h.length:Oe+nn),xo(h)}return md(h,yt),xo(h)},_tickSize:function(){var h=this,E=h.options.ticks,R=Ge.toRadians(h.labelRotation),F=Math.abs(Math.cos(R)),q=Math.abs(Math.sin(R)),de=h._getLabelSizes(),ye=E.autoSkipPadding||0,Ue=de?de.widest.width+ye:0,Oe=de?de.highest.height+ye:0;return h.isHorizontal()?Oe*F>Ue*q?Ue/F:Oe/q:Oe*q<Ue*F?Oe/F:Ue/q},_isVisible:function(){var F,q,de,h=this,E=h.chart,R=h.options.display;if("auto"!==R)return!!R;for(F=0,q=E.data.datasets.length;F<q;++F)if(E.isDatasetVisible(F)&&((de=E.getDatasetMeta(F)).xAxisID===h.id||de.yAxisID===h.id))return!0;return!1},_computeGridLineItems:function(h){var Gr,Pi,Zo,Lo,Gs,Xs,dl,ha,ia,Pa,il,Eu,wa,ou,gu,Nc,sc,E=this,R=E.chart,F=E.options,q=F.gridLines,de=F.position,ye=q.offsetGridLines,Ue=E.isHorizontal(),Oe=E._ticksToDraw,Xe=Oe.length+(ye?1:0),gt=ed(q),yt=[],nn=q.drawBorder?ao(q.lineWidth,0,0):0,Pn=nn/2,xn=Ge._alignPixel,ir=function(gf){return xn(R,gf,nn)};for("top"===de?(Gr=ir(E.bottom),dl=E.bottom-gt,ia=Gr-Pn,il=ir(h.top)+Pn,wa=h.bottom):"bottom"===de?(Gr=ir(E.top),il=h.top,wa=ir(h.bottom)-Pn,dl=Gr+Pn,ia=E.top+gt):"left"===de?(Gr=ir(E.right),Xs=E.right-gt,ha=Gr-Pn,Pa=ir(h.left)+Pn,Eu=h.right):(Gr=ir(E.left),Pa=h.left,Eu=ir(h.right)-Pn,Xs=Gr+Pn,ha=E.left+gt),Pi=0;Pi<Xe;++Pi)!(Cr((Zo=Oe[Pi]||{}).label)&&Pi<Oe.length)&&(Pi===E.zeroLineIndex&&F.offset===ye?(ou=q.zeroLineWidth,gu=q.zeroLineColor,Nc=q.zeroLineBorderDash||[],sc=q.zeroLineBorderDashOffset||0):(ou=ao(q.lineWidth,Pi,1),gu=ao(q.color,Pi,"rgba(0,0,0,0.1)"),Nc=q.borderDash||[],sc=q.borderDashOffset||0),void 0!==(Lo=Na(E,Zo._index||Pi,ye))&&(Gs=xn(R,Lo,ou),Ue?Xs=ha=Pa=Eu=Gs:dl=ia=il=wa=Gs,yt.push({tx1:Xs,ty1:dl,tx2:ha,ty2:ia,x1:Pa,y1:il,x2:Eu,y2:wa,width:ou,color:gu,borderDash:Nc,borderDashOffset:sc})));return yt.ticksLength=Xe,yt.borderValue=Gr,yt},_computeLabelItems:function(){var nn,Pn,xn,ir,Gr,Pi,Zo,Lo,Gs,Xs,dl,ha,h=this,E=h.options,R=E.ticks,F=E.position,q=R.mirror,de=h.isHorizontal(),ye=h._ticksToDraw,Ue=$i(R),Oe=R.padding,Xe=ed(E.gridLines),gt=-Ge.toRadians(h.labelRotation),yt=[];for("top"===F?(Pi=h.bottom-Xe-Oe,Zo=gt?"left":"center"):"bottom"===F?(Pi=h.top+Xe+Oe,Zo=gt?"right":"center"):"left"===F?(Gr=h.right-(q?0:Xe)-Oe,Zo=q?"left":"right"):(Gr=h.left+(q?0:Xe)+Oe,Zo=q?"right":"left"),nn=0,Pn=ye.length;nn<Pn;++nn)!Cr(ir=(xn=ye[nn]).label)&&(Lo=h.getPixelForTick(xn._index||nn)+R.labelOffset,Xs=(Gs=xn.major?Ue.major:Ue.minor).lineHeight,dl=In(ir)?ir.length:1,de?(Gr=Lo,ha="top"===F?((gt?1:.5)-dl)*Xs:(gt?0:.5)*Xs):(Pi=Lo,ha=(1-dl)*Xs/2),yt.push({x:Gr,y:Pi,rotation:gt,label:ir,font:Gs,textOffset:ha,textAlign:Zo}));return yt},_drawGrid:function(h){var E=this,R=E.options.gridLines;if(R.display){var Oe,Xe,gt,yt,nn,F=E.ctx,q=E.chart,de=Ge._alignPixel,ye=R.drawBorder?ao(R.lineWidth,0,0):0,Ue=E._gridLineItems||(E._gridLineItems=E._computeGridLineItems(h));for(gt=0,yt=Ue.length;gt<yt;++gt)Xe=(nn=Ue[gt]).color,(Oe=nn.width)&&Xe&&(F.save(),F.lineWidth=Oe,F.strokeStyle=Xe,F.setLineDash&&(F.setLineDash(nn.borderDash),F.lineDashOffset=nn.borderDashOffset),F.beginPath(),R.drawTicks&&(F.moveTo(nn.tx1,nn.ty1),F.lineTo(nn.tx2,nn.ty2)),R.drawOnChartArea&&(F.moveTo(nn.x1,nn.y1),F.lineTo(nn.x2,nn.y2)),F.stroke(),F.restore());if(ye){var Gr,Pi,Zo,Lo,Pn=ye,xn=ao(R.lineWidth,Ue.ticksLength-1,1),ir=Ue.borderValue;E.isHorizontal()?(Gr=de(q,E.left,Pn)-Pn/2,Pi=de(q,E.right,xn)+xn/2,Zo=Lo=ir):(Zo=de(q,E.top,Pn)-Pn/2,Lo=de(q,E.bottom,xn)+xn/2,Gr=Pi=ir),F.lineWidth=ye,F.strokeStyle=ao(R.color,0),F.beginPath(),F.moveTo(Gr,Zo),F.lineTo(Pi,Lo),F.stroke()}}},_drawLabels:function(){var h=this;if(h.options.ticks.display){var q,de,ye,Ue,Oe,Xe,gt,yt,R=h.ctx,F=h._labelItems||(h._labelItems=h._computeLabelItems());for(q=0,ye=F.length;q<ye;++q){if(Xe=(Oe=F[q]).font,R.save(),R.translate(Oe.x,Oe.y),R.rotate(Oe.rotation),R.font=Xe.string,R.fillStyle=Xe.color,R.textBaseline="middle",R.textAlign=Oe.textAlign,yt=Oe.textOffset,In(gt=Oe.label))for(de=0,Ue=gt.length;de<Ue;++de)R.fillText(""+gt[de],0,yt),yt+=Xe.lineHeight;else R.fillText(gt,0,yt);R.restore()}}},_drawTitle:function(){var h=this,E=h.ctx,R=h.options,F=R.scaleLabel;if(F.display){var gt,yt,q=hr(F.fontColor,br.global.defaultFontColor),de=Ge.options._parseFont(F),ye=Ge.options.toPadding(F.padding),Ue=de.lineHeight/2,Oe=R.position,Xe=0;if(h.isHorizontal())gt=h.left+h.width/2,yt="bottom"===Oe?h.bottom-Ue-ye.bottom:h.top+Ue+ye.top;else{var nn="left"===Oe;gt=nn?h.left+Ue+ye.top:h.right-Ue-ye.top,yt=h.top+h.height/2,Xe=nn?-.5*Math.PI:.5*Math.PI}E.save(),E.translate(gt,yt),E.rotate(Xe),E.textAlign="center",E.textBaseline="middle",E.fillStyle=q,E.font=de.string,E.fillText(F.labelString,0,0),E.restore()}},draw:function(h){var E=this;!E._isVisible()||(E._drawGrid(h),E._drawTitle(),E._drawLabels())},_layers:function(){var h=this,E=h.options,R=E.ticks&&E.ticks.z||0,F=E.gridLines&&E.gridLines.z||0;return h._isVisible()&&R!==F&&h.draw===h._draw?[{z:F,draw:function(){h._drawGrid.apply(h,arguments),h._drawTitle.apply(h,arguments)}},{z:R,draw:function(){h._drawLabels.apply(h,arguments)}}]:[{z:R,draw:function(){h.draw.apply(h,arguments)}}]},_getMatchingVisibleMetas:function(h){var E=this,R=E.isHorizontal();return E.chart._getSortedVisibleDatasetMetas().filter(function(F){return(!h||F.type===h)&&(R?F.xAxisID===E.id:F.yAxisID===E.id)})}});Mn.prototype._draw=Mn.prototype.draw;var Nl=Mn,td=Ge.isNullOrUndef,ss=Nl.extend({determineDataLimits:function(){var Ue,h=this,E=h._getLabels(),R=h.options.ticks,F=R.min,q=R.max,de=0,ye=E.length-1;void 0!==F&&(Ue=E.indexOf(F))>=0&&(de=Ue),void 0!==q&&(Ue=E.indexOf(q))>=0&&(ye=Ue),h.minIndex=de,h.maxIndex=ye,h.min=E[de],h.max=E[ye]},buildTicks:function(){var h=this,E=h._getLabels(),R=h.minIndex,F=h.maxIndex;h.ticks=0===R&&F===E.length-1?E:E.slice(R,F+1)},getLabelForIndex:function(h,E){var R=this,F=R.chart;return F.getDatasetMeta(E).controller._getValueScaleId()===R.id?R.getRightValue(F.data.datasets[E].data[h]):R._getLabels()[h]},_configure:function(){var h=this,E=h.options.offset,R=h.ticks;Nl.prototype._configure.call(h),h.isHorizontal()||(h._reversePixels=!h._reversePixels),R&&(h._startValue=h.minIndex-(E?.5:0),h._valueRange=Math.max(R.length-(E?0:1),1))},getPixelForValue:function(h,E,R){var q,de,ye,F=this;return!td(E)&&!td(R)&&(h=F.chart.data.datasets[R].data[E]),td(h)||(q=F.isHorizontal()?h.x:h.y),(void 0!==q||void 0!==h&&isNaN(E))&&(de=F._getLabels(),h=Ge.valueOrDefault(q,h),E=-1!==(ye=de.indexOf(h))?ye:E,isNaN(E)&&(E=h)),F.getPixelForDecimal((E-F._startValue)/F._valueRange)},getPixelForTick:function(h){var E=this.ticks;return h<0||h>E.length-1?null:this.getPixelForValue(E[h],h+this.minIndex)},getValueForPixel:function(h){var E=this,R=Math.round(E._startValue+E.getDecimalForPixel(h)*E._valueRange);return Math.min(Math.max(R,0),E.ticks.length-1)},getBasePixel:function(){return this.bottom}});ss._defaults={position:"bottom"};var ic=Ge.isNullOrUndef;var al=Nl.extend({getRightValue:function(h){return"string"==typeof h?+h:Nl.prototype.getRightValue.call(this,h)},handleTickRangeOptions:function(){var h=this,R=h.options.ticks;if(R.beginAtZero){var F=Ge.sign(h.min),q=Ge.sign(h.max);F<0&&q<0?h.max=0:F>0&&q>0&&(h.min=0)}var de=void 0!==R.min||void 0!==R.suggestedMin,ye=void 0!==R.max||void 0!==R.suggestedMax;void 0!==R.min?h.min=R.min:void 0!==R.suggestedMin&&(h.min=null===h.min?R.suggestedMin:Math.min(h.min,R.suggestedMin)),void 0!==R.max?h.max=R.max:void 0!==R.suggestedMax&&(h.max=null===h.max?R.suggestedMax:Math.max(h.max,R.suggestedMax)),de!==ye&&h.min>=h.max&&(de?h.max=h.min+1:h.min=h.max-1),h.min===h.max&&(h.max++,R.beginAtZero||h.min--)},getTickLimit:function(){var q,h=this,E=h.options.ticks,R=E.stepSize,F=E.maxTicksLimit;return R?q=Math.ceil(h.max/R)-Math.floor(h.min/R)+1:(q=h._computeTickLimit(),F=F||11),F&&(q=Math.min(F,q)),q},_computeTickLimit:function(){return Number.POSITIVE_INFINITY},handleDirectionalChanges:Ge.noop,buildTicks:function(){var h=this,R=h.options.ticks,F=h.getTickLimit(),q={maxTicks:F=Math.max(2,F),min:R.min,max:R.max,precision:R.precision,stepSize:Ge.valueOrDefault(R.fixedStepSize,R.stepSize)},de=h.ticks=function(h,E){var Pn,xn,ir,Gr,R=[],q=h.stepSize,de=q||1,ye=h.maxTicks-1,Ue=h.min,Oe=h.max,Xe=h.precision,gt=E.min,yt=E.max,nn=Ge.niceNum((yt-gt)/ye/de)*de;if(nn<1e-14&&ic(Ue)&&ic(Oe))return[gt,yt];(Gr=Math.ceil(yt/nn)-Math.floor(gt/nn))>ye&&(nn=Ge.niceNum(Gr*nn/ye/de)*de),q||ic(Xe)?Pn=Math.pow(10,Ge._decimalPlaces(nn)):(Pn=Math.pow(10,Xe),nn=Math.ceil(nn*Pn)/Pn),xn=Math.floor(gt/nn)*nn,ir=Math.ceil(yt/nn)*nn,q&&(!ic(Ue)&&Ge.almostWhole(Ue/nn,nn/1e3)&&(xn=Ue),!ic(Oe)&&Ge.almostWhole(Oe/nn,nn/1e3)&&(ir=Oe)),Gr=Ge.almostEquals(Gr=(ir-xn)/nn,Math.round(Gr),nn/1e3)?Math.round(Gr):Math.ceil(Gr),xn=Math.round(xn*Pn)/Pn,ir=Math.round(ir*Pn)/Pn,R.push(ic(Ue)?xn:Ue);for(var Pi=1;Pi<Gr;++Pi)R.push(Math.round((xn+Pi*nn)*Pn)/Pn);return R.push(ic(Oe)?ir:Oe),R}(q,h);h.handleDirectionalChanges(),h.max=Ge.max(de),h.min=Ge.min(de),R.reverse?(de.reverse(),h.start=h.max,h.end=h.min):(h.start=h.min,h.end=h.max)},convertTicksToLabels:function(){var h=this;h.ticksAsNumbers=h.ticks.slice(),h.zeroLineIndex=h.ticks.indexOf(0),Nl.prototype.convertTicksToLabels.call(h)},_configure:function(){var q,h=this,E=h.getTicks(),R=h.min,F=h.max;Nl.prototype._configure.call(h),h.options.offset&&E.length&&(R-=q=(F-R)/Math.max(E.length-1,1)/2,F+=q),h._startValue=R,h._endValue=F,h._valueRange=F-R}}),Wd={position:"left",ticks:{callback:Fo.formatters.linear}};function Ce(h,E,R,F){var gt,yt,q=h.options,ye=function(h,E,R){var F=[R.type,void 0===E&&void 0===R.stack?R.index:"",R.stack].join(".");return void 0===h[F]&&(h[F]={pos:[],neg:[]}),h[F]}(E,q.stacked,R),Ue=ye.pos,Oe=ye.neg,Xe=F.length;for(gt=0;gt<Xe;++gt)yt=h._parseValue(F[gt]),!(isNaN(yt.min)||isNaN(yt.max)||R.data[gt].hidden)&&(Ue[gt]=Ue[gt]||0,Oe[gt]=Oe[gt]||0,q.relativePoints?Ue[gt]=100:yt.min<0||yt.max<0?Oe[gt]+=yt.min:Ue[gt]+=yt.max)}function ot(h,E,R){var q,de,F=R.length;for(q=0;q<F;++q)de=h._parseValue(R[q]),!(isNaN(de.min)||isNaN(de.max)||E.data[q].hidden)&&(h.min=Math.min(h.min,de.min),h.max=Math.max(h.max,de.max))}var Et=al.extend({determineDataLimits:function(){var Oe,Xe,gt,yt,h=this,E=h.options,F=h.chart.data.datasets,q=h._getMatchingVisibleMetas(),de=E.stacked,ye={},Ue=q.length;if(h.min=Number.POSITIVE_INFINITY,h.max=Number.NEGATIVE_INFINITY,void 0===de)for(Oe=0;!de&&Oe<Ue;++Oe)de=void 0!==(Xe=q[Oe]).stack;for(Oe=0;Oe<Ue;++Oe)gt=F[(Xe=q[Oe]).index].data,de?Ce(h,ye,Xe,gt):ot(h,Xe,gt);Ge.each(ye,function(nn){yt=nn.pos.concat(nn.neg),h.min=Math.min(h.min,Ge.min(yt)),h.max=Math.max(h.max,Ge.max(yt))}),h.min=Ge.isFinite(h.min)&&!isNaN(h.min)?h.min:0,h.max=Ge.isFinite(h.max)&&!isNaN(h.max)?h.max:1,h.handleTickRangeOptions()},_computeTickLimit:function(){var E,h=this;return h.isHorizontal()?Math.ceil(h.width/40):(E=Ge.options._parseFont(h.options.ticks),Math.ceil(h.height/E.lineHeight))},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(h,E){return this._getScaleLabel(this.chart.data.datasets[E].data[h])},getPixelForValue:function(h){var E=this;return E.getPixelForDecimal((+E.getRightValue(h)-E._startValue)/E._valueRange)},getValueForPixel:function(h){return this._startValue+this.getDecimalForPixel(h)*this._valueRange},getPixelForTick:function(h){var E=this.ticksAsNumbers;return h<0||h>E.length-1?null:this.getPixelForValue(E[h])}});Et._defaults=Wd;var Hn=Ge.valueOrDefault,Xn=Ge.math.log10;var Yo={position:"left",ticks:{callback:Fo.formatters.logarithmic}};function $a(h,E){return Ge.isFinite(h)&&h>=0?h:E}var ns=Nl.extend({determineDataLimits:function(){var ye,Ue,Oe,Xe,gt,yt,h=this,E=h.options,R=h.chart,F=R.data.datasets,q=h.isHorizontal();function de(Gr){return q?Gr.xAxisID===h.id:Gr.yAxisID===h.id}h.min=Number.POSITIVE_INFINITY,h.max=Number.NEGATIVE_INFINITY,h.minNotZero=Number.POSITIVE_INFINITY;var nn=E.stacked;if(void 0===nn)for(ye=0;ye<F.length;ye++)if(Ue=R.getDatasetMeta(ye),R.isDatasetVisible(ye)&&de(Ue)&&void 0!==Ue.stack){nn=!0;break}if(E.stacked||nn){var Pn={};for(ye=0;ye<F.length;ye++){var xn=[(Ue=R.getDatasetMeta(ye)).type,void 0===E.stacked&&void 0===Ue.stack?ye:"",Ue.stack].join(".");if(R.isDatasetVisible(ye)&&de(Ue))for(void 0===Pn[xn]&&(Pn[xn]=[]),gt=0,yt=(Xe=F[ye].data).length;gt<yt;gt++){var ir=Pn[xn];Oe=h._parseValue(Xe[gt]),!(isNaN(Oe.min)||isNaN(Oe.max)||Ue.data[gt].hidden||Oe.min<0||Oe.max<0)&&(ir[gt]=ir[gt]||0,ir[gt]+=Oe.max)}}Ge.each(Pn,function(Gr){if(Gr.length>0){var Pi=Ge.min(Gr),Zo=Ge.max(Gr);h.min=Math.min(h.min,Pi),h.max=Math.max(h.max,Zo)}})}else for(ye=0;ye<F.length;ye++)if(Ue=R.getDatasetMeta(ye),R.isDatasetVisible(ye)&&de(Ue))for(gt=0,yt=(Xe=F[ye].data).length;gt<yt;gt++)Oe=h._parseValue(Xe[gt]),!(isNaN(Oe.min)||isNaN(Oe.max)||Ue.data[gt].hidden||Oe.min<0||Oe.max<0)&&(h.min=Math.min(Oe.min,h.min),h.max=Math.max(Oe.max,h.max),0!==Oe.min&&(h.minNotZero=Math.min(Oe.min,h.minNotZero)));h.min=Ge.isFinite(h.min)?h.min:null,h.max=Ge.isFinite(h.max)?h.max:null,h.minNotZero=Ge.isFinite(h.minNotZero)?h.minNotZero:null,this.handleTickRangeOptions()},handleTickRangeOptions:function(){var h=this,E=h.options.ticks;h.min=$a(E.min,h.min),h.max=$a(E.max,h.max),h.min===h.max&&(0!==h.min&&null!==h.min?(h.min=Math.pow(10,Math.floor(Xn(h.min))-1),h.max=Math.pow(10,Math.floor(Xn(h.max))+1)):(h.min=1,h.max=10)),null===h.min&&(h.min=Math.pow(10,Math.floor(Xn(h.max))-1)),null===h.max&&(h.max=0!==h.min?Math.pow(10,Math.floor(Xn(h.min))+1):10),null===h.minNotZero&&(h.minNotZero=h.min>0?h.min:h.max<1?Math.pow(10,Math.floor(Xn(h.max))):1)},buildTicks:function(){var h=this,E=h.options.ticks,R=!h.isHorizontal(),F={min:$a(E.min),max:$a(E.max)},q=h.ticks=function(h,E){var ye,Ue,R=[],F=Hn(h.min,Math.pow(10,Math.floor(Xn(E.min)))),q=Math.floor(Xn(E.max)),de=Math.ceil(E.max/Math.pow(10,q));0===F?(ye=Math.floor(Xn(E.minNotZero)),Ue=Math.floor(E.minNotZero/Math.pow(10,ye)),R.push(F),F=Ue*Math.pow(10,ye)):(ye=Math.floor(Xn(F)),Ue=Math.floor(F/Math.pow(10,ye)));var Oe=ye<0?Math.pow(10,Math.abs(ye)):1;do{R.push(F),10==++Ue&&(Ue=1,Oe=++ye>=0?1:Oe),F=Math.round(Ue*Math.pow(10,ye)*Oe)/Oe}while(ye<q||ye===q&&Ue<de);var Xe=Hn(h.max,F);return R.push(Xe),R}(F,h);h.max=Ge.max(q),h.min=Ge.min(q),E.reverse?(R=!R,h.start=h.max,h.end=h.min):(h.start=h.min,h.end=h.max),R&&q.reverse()},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),Nl.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(h,E){return this._getScaleLabel(this.chart.data.datasets[E].data[h])},getPixelForTick:function(h){var E=this.tickValues;return h<0||h>E.length-1?null:this.getPixelForValue(E[h])},_getFirstTickValue:function(h){var E=Math.floor(Xn(h));return Math.floor(h/Math.pow(10,E))*Math.pow(10,E)},_configure:function(){var h=this,E=h.min,R=0;Nl.prototype._configure.call(h),0===E&&(E=h._getFirstTickValue(h.minNotZero),R=Hn(h.options.ticks.fontSize,br.global.defaultFontSize)/h._length),h._startValue=Xn(E),h._valueOffset=R,h._valueRange=(Xn(h.max)-Xn(E))/(1-R)},getPixelForValue:function(h){var E=this,R=0;return(h=+E.getRightValue(h))>E.min&&h>0&&(R=(Xn(h)-E._startValue)/E._valueRange+E._valueOffset),E.getPixelForDecimal(R)},getValueForPixel:function(h){var E=this,R=E.getDecimalForPixel(h);return 0===R&&0===E.min?0:Math.pow(10,E._startValue+(R-E._valueOffset)*E._valueRange)}});ns._defaults=Yo;var Hs=Ge.valueOrDefault,fc=Ge.valueAtIndexOrDefault,ga=Ge.options.resolve,Ol={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,borderDash:[],borderDashOffset:0},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:Fo.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(h){return h}}};function ll(h){var E=h.ticks;return E.display&&h.display?Hs(E.fontSize,br.global.defaultFontSize)+2*E.backdropPaddingY:0}function Za(h,E,R){return Ge.isArray(R)?{w:Ge.longestText(h,h.font,R),h:R.length*E}:{w:h.measureText(R).width,h:E}}function ja(h,E,R,F,q){return h===F||h===q?{start:E-R/2,end:E+R/2}:h<F||h>q?{start:E-R,end:E}:{start:E,end:E+R}}function Of(h){return 0===h||180===h?"center":h<180?"left":"right"}function Rd(h,E,R,F){var de,ye,q=R.y+F/2;if(Ge.isArray(E))for(de=0,ye=E.length;de<ye;++de)h.fillText(E[de],R.x,q),q+=F;else h.fillText(E,R.x,q)}function Qd(h,E,R){90===h||270===h?R.y-=E.h/2:(h>270||h<90)&&(R.y-=E.h)}function Cc(h){return Ge.isNumber(h)?h:0}var Xd=al.extend({setDimensions:function(){var h=this;h.width=h.maxWidth,h.height=h.maxHeight,h.paddingTop=ll(h.options)/2,h.xCenter=Math.floor(h.width/2),h.yCenter=Math.floor((h.height-h.paddingTop)/2),h.drawingArea=Math.min(h.height-h.paddingTop,h.width)/2},determineDataLimits:function(){var h=this,E=h.chart,R=Number.POSITIVE_INFINITY,F=Number.NEGATIVE_INFINITY;Ge.each(E.data.datasets,function(q,de){if(E.isDatasetVisible(de)){var ye=E.getDatasetMeta(de);Ge.each(q.data,function(Ue,Oe){var Xe=+h.getRightValue(Ue);isNaN(Xe)||ye.data[Oe].hidden||(R=Math.min(Xe,R),F=Math.max(Xe,F))})}}),h.min=R===Number.POSITIVE_INFINITY?0:R,h.max=F===Number.NEGATIVE_INFINITY?0:F,h.handleTickRangeOptions()},_computeTickLimit:function(){return Math.ceil(this.drawingArea/ll(this.options))},convertTicksToLabels:function(){var h=this;al.prototype.convertTicksToLabels.call(h),h.pointLabels=h.chart.data.labels.map(function(){var E=Ge.callback(h.options.pointLabels.callback,arguments,h);return E||0===E?E:""})},getLabelForIndex:function(h,E){return+this.getRightValue(this.chart.data.datasets[E].data[h])},fit:function(){var h=this,E=h.options;E.display&&E.pointLabels.display?function(h){var q,de,ye,E=Ge.options._parseFont(h.options.pointLabels),R={l:0,r:h.width,t:0,b:h.height-h.paddingTop},F={};h.ctx.font=E.string,h._pointLabelSizes=[];var Ue=h.chart.data.labels.length;for(q=0;q<Ue;q++){ye=h.getPointPosition(q,h.drawingArea+5),de=Za(h.ctx,E.lineHeight,h.pointLabels[q]),h._pointLabelSizes[q]=de;var Oe=h.getIndexAngle(q),Xe=Ge.toDegrees(Oe)%360,gt=ja(Xe,ye.x,de.w,0,180),yt=ja(Xe,ye.y,de.h,90,270);gt.start<R.l&&(R.l=gt.start,F.l=Oe),gt.end>R.r&&(R.r=gt.end,F.r=Oe),yt.start<R.t&&(R.t=yt.start,F.t=Oe),yt.end>R.b&&(R.b=yt.end,F.b=Oe)}h.setReductions(h.drawingArea,R,F)}(h):h.setCenterPoint(0,0,0,0)},setReductions:function(h,E,R){var F=this,q=E.l/Math.sin(R.l),de=Math.max(E.r-F.width,0)/Math.sin(R.r),ye=-E.t/Math.cos(R.t),Ue=-Math.max(E.b-(F.height-F.paddingTop),0)/Math.cos(R.b);q=Cc(q),de=Cc(de),ye=Cc(ye),Ue=Cc(Ue),F.drawingArea=Math.min(Math.floor(h-(q+de)/2),Math.floor(h-(ye+Ue)/2)),F.setCenterPoint(q,de,ye,Ue)},setCenterPoint:function(h,E,R,F){var q=this,Ue=R+q.drawingArea,Oe=q.height-q.paddingTop-F-q.drawingArea;q.xCenter=Math.floor((h+q.drawingArea+(q.width-E-q.drawingArea))/2+q.left),q.yCenter=Math.floor((Ue+Oe)/2+q.top+q.paddingTop)},getIndexAngle:function(h){var E=this.chart,de=(h*(360/E.data.labels.length)+((E.options||{}).startAngle||0))%360;return(de<0?de+360:de)*Math.PI*2/360},getDistanceFromCenterForValue:function(h){var E=this;if(Ge.isNullOrUndef(h))return NaN;var R=E.drawingArea/(E.max-E.min);return E.options.ticks.reverse?(E.max-h)*R:(h-E.min)*R},getPointPosition:function(h,E){var R=this,F=R.getIndexAngle(h)-Math.PI/2;return{x:Math.cos(F)*E+R.xCenter,y:Math.sin(F)*E+R.yCenter}},getPointPositionForValue:function(h,E){return this.getPointPosition(h,this.getDistanceFromCenterForValue(E))},getBasePosition:function(h){var E=this,R=E.min,F=E.max;return E.getPointPositionForValue(h||0,E.beginAtZero?0:R<0&&F<0?F:R>0&&F>0?R:0)},_drawGrid:function(){var Ue,Oe,Xe,h=this,E=h.ctx,R=h.options,F=R.gridLines,q=R.angleLines,de=Hs(q.lineWidth,F.lineWidth),ye=Hs(q.color,F.color);if(R.pointLabels.display&&function(h){var E=h.ctx,R=h.options,F=R.pointLabels,q=ll(R),de=h.getDistanceFromCenterForValue(R.ticks.reverse?h.min:h.max),ye=Ge.options._parseFont(F);E.save(),E.font=ye.string,E.textBaseline="middle";for(var Ue=h.chart.data.labels.length-1;Ue>=0;Ue--){var Xe=h.getPointPosition(Ue,de+(0===Ue?q/2:0)+5),gt=fc(F.fontColor,Ue,br.global.defaultFontColor);E.fillStyle=gt;var yt=h.getIndexAngle(Ue),nn=Ge.toDegrees(yt);E.textAlign=Of(nn),Qd(nn,h._pointLabelSizes[Ue],Xe),Rd(E,h.pointLabels[Ue],Xe,ye.lineHeight)}E.restore()}(h),F.display&&Ge.each(h.ticks,function(gt,yt){0!==yt&&(Oe=h.getDistanceFromCenterForValue(h.ticksAsNumbers[yt]),function(h,E,R,F){var Xe,q=h.ctx,de=E.circular,ye=h.chart.data.labels.length,Ue=fc(E.color,F-1),Oe=fc(E.lineWidth,F-1);if((de||ye)&&Ue&&Oe){if(q.save(),q.strokeStyle=Ue,q.lineWidth=Oe,q.setLineDash&&(q.setLineDash(E.borderDash||[]),q.lineDashOffset=E.borderDashOffset||0),q.beginPath(),de)q.arc(h.xCenter,h.yCenter,R,0,2*Math.PI);else{Xe=h.getPointPosition(0,R),q.moveTo(Xe.x,Xe.y);for(var gt=1;gt<ye;gt++)Xe=h.getPointPosition(gt,R),q.lineTo(Xe.x,Xe.y)}q.closePath(),q.stroke(),q.restore()}}(h,F,Oe,yt))}),q.display&&de&&ye){for(E.save(),E.lineWidth=de,E.strokeStyle=ye,E.setLineDash&&(E.setLineDash(ga([q.borderDash,F.borderDash,[]])),E.lineDashOffset=ga([q.borderDashOffset,F.borderDashOffset,0])),Ue=h.chart.data.labels.length-1;Ue>=0;Ue--)Oe=h.getDistanceFromCenterForValue(R.ticks.reverse?h.min:h.max),Xe=h.getPointPosition(Ue,Oe),E.beginPath(),E.moveTo(h.xCenter,h.yCenter),E.lineTo(Xe.x,Xe.y),E.stroke();E.restore()}},_drawLabels:function(){var h=this,E=h.ctx,F=h.options.ticks;if(F.display){var Ue,Oe,q=h.getIndexAngle(0),de=Ge.options._parseFont(F),ye=Hs(F.fontColor,br.global.defaultFontColor);E.save(),E.font=de.string,E.translate(h.xCenter,h.yCenter),E.rotate(q),E.textAlign="center",E.textBaseline="middle",Ge.each(h.ticks,function(Xe,gt){0===gt&&!F.reverse||(Ue=h.getDistanceFromCenterForValue(h.ticksAsNumbers[gt]),F.showLabelBackdrop&&(Oe=E.measureText(Xe).width,E.fillStyle=F.backdropColor,E.fillRect(-Oe/2-F.backdropPaddingX,-Ue-de.size/2-F.backdropPaddingY,Oe+2*F.backdropPaddingX,de.size+2*F.backdropPaddingY)),E.fillStyle=ye,E.fillText(Xe,0,-Ue))}),E.restore()}},_drawTitle:Ge.noop});Xd._defaults=Ol;var $f=Ge._deprecated,Ju=Ge.options.resolve,Sl=Ge.valueOrDefault,wl=Number.MIN_SAFE_INTEGER||-9007199254740991,kl=Number.MAX_SAFE_INTEGER||9007199254740991,Pu={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},Ja=Object.keys(Pu);function Qu(h,E){return h-E}function Oc(h){return Ge.valueOrDefault(h.time.min,h.ticks.min)}function Au(h){return Ge.valueOrDefault(h.time.max,h.ticks.max)}function ff(h,E,R,F){var q=function(h,E,R){for(var de,ye,Ue,F=0,q=h.length-1;F>=0&&F<=q;){if(Ue=h[de=F+q>>1],!(ye=h[de-1]||null))return{lo:null,hi:Ue};if(Ue[E]<R)F=de+1;else{if(!(ye[E]>R))return{lo:ye,hi:Ue};q=de-1}}return{lo:Ue,hi:null}}(h,E,R),de=q.lo?q.hi?q.lo:h[h.length-2]:h[0],ye=q.lo?q.hi?q.hi:h[h.length-1]:h[1],Ue=ye[E]-de[E];return de[F]+(ye[F]-de[F])*(Ue?(R-de[E])/Ue:0)}function Jl(h,E){var R=h._adapter,F=h.options.time,q=F.parser,de=q||F.format,ye=E;return"function"==typeof q&&(ye=q(ye)),Ge.isFinite(ye)||(ye="string"==typeof de?R.parse(ye,de):R.parse(ye)),null!==ye?+ye:(!q&&"function"==typeof de&&(ye=de(E),Ge.isFinite(ye)||(ye=R.parse(ye))),ye)}function vd(h,E){if(Ge.isNullOrUndef(E))return null;var R=h.options.time,F=Jl(h,h.getRightValue(E));return null===F||R.round&&(F=+h._adapter.startOf(F,R.round)),F}function wc(h,E,R,F){var de,ye,q=Ja.length;for(de=Ja.indexOf(h);de<q-1;++de)if((ye=Pu[Ja[de]]).common&&Math.ceil((R-E)/((ye.steps?ye.steps:kl)*ye.size))<=F)return Ja[de];return Ja[q-1]}function hu(h,E,R){var ye,Ue,F=[],q={},de=E.length;for(ye=0;ye<de;++ye)q[Ue=E[ye]]=ye,F.push({value:Ue,major:!1});return 0!==de&&R?function(h,E,R,F){var Ue,Oe,q=h._adapter,de=+q.startOf(E[0].value,F),ye=E[E.length-1].value;for(Ue=de;Ue<=ye;Ue=+q.add(Ue,1,F))(Oe=R[Ue])>=0&&(E[Oe].major=!0);return E}(h,F,q,R):F}var $p=Nl.extend({initialize:function(){this.mergeTicksOptions(),Nl.prototype.initialize.call(this)},update:function(){var h=this,E=h.options,R=E.time||(E.time={}),F=h._adapter=new Io._date(E.adapters.date);return $f("time scale",R.format,"time.format","time.parser"),$f("time scale",R.min,"time.min","ticks.min"),$f("time scale",R.max,"time.max","ticks.max"),Ge.mergeIf(R.displayFormats,F.formats()),Nl.prototype.update.apply(h,arguments)},getRightValue:function(h){return h&&void 0!==h.t&&(h=h.t),Nl.prototype.getRightValue.call(this,h)},determineDataLimits:function(){var gt,yt,nn,Pn,xn,ir,Gr,h=this,E=h.chart,R=h._adapter,F=h.options,q=F.time.unit||"day",de=kl,ye=wl,Ue=[],Oe=[],Xe=[],Pi=h._getLabels();for(gt=0,nn=Pi.length;gt<nn;++gt)Xe.push(vd(h,Pi[gt]));for(gt=0,nn=(E.data.datasets||[]).length;gt<nn;++gt)if(E.isDatasetVisible(gt))if(Ge.isObject((xn=E.data.datasets[gt].data)[0]))for(Oe[gt]=[],yt=0,Pn=xn.length;yt<Pn;++yt)ir=vd(h,xn[yt]),Ue.push(ir),Oe[gt][yt]=ir;else Oe[gt]=Xe.slice(0),Gr||(Ue=Ue.concat(Xe),Gr=!0);else Oe[gt]=[];Xe.length&&(de=Math.min(de,Xe[0]),ye=Math.max(ye,Xe[Xe.length-1])),Ue.length&&(Ue=nn>1?function(h){var F,q,de,E={},R=[];for(F=0,q=h.length;F<q;++F)E[de=h[F]]||(E[de]=!0,R.push(de));return R}(Ue).sort(Qu):Ue.sort(Qu),de=Math.min(de,Ue[0]),ye=Math.max(ye,Ue[Ue.length-1])),de=vd(h,Oc(F))||de,ye=vd(h,Au(F))||ye,de=de===kl?+R.startOf(Date.now(),q):de,ye=ye===wl?+R.endOf(Date.now(),q)+1:ye,h.min=Math.min(de,ye),h.max=Math.max(de+1,ye),h._table=[],h._timestamps={data:Ue,datasets:Oe,labels:Xe}},buildTicks:function(){var yt,nn,Pn,h=this,E=h.min,R=h.max,F=h.options,q=F.ticks,de=F.time,ye=h._timestamps,Ue=[],Oe=h.getLabelCapacity(E),Xe=q.source,gt=F.distribution;for(ye="data"===Xe||"auto"===Xe&&"series"===gt?ye.data:"labels"===Xe?ye.labels:function(h,E,R,F){var nn,q=h._adapter,de=h.options,ye=de.time,Ue=ye.unit||wc(ye.minUnit,E,R,F),Oe=Ju([ye.stepSize,ye.unitStepSize,1]),Xe="week"===Ue&&ye.isoWeekday,gt=E,yt=[];if(Xe&&(gt=+q.startOf(gt,"isoWeek",Xe)),gt=+q.startOf(gt,Xe?"day":Ue),q.diff(R,E,Ue)>1e5*Oe)throw E+" and "+R+" are too far apart with stepSize of "+Oe+" "+Ue;for(nn=gt;nn<R;nn=+q.add(nn,Oe,Ue))yt.push(nn);return(nn===R||"ticks"===de.bounds)&&yt.push(nn),yt}(h,E,R,Oe),"ticks"===F.bounds&&ye.length&&(E=ye[0],R=ye[ye.length-1]),E=vd(h,Oc(F))||E,R=vd(h,Au(F))||R,yt=0,nn=ye.length;yt<nn;++yt)(Pn=ye[yt])>=E&&Pn<=R&&Ue.push(Pn);return h.min=E,h.max=R,h._unit=de.unit||(q.autoSkip?wc(de.minUnit,h.min,h.max,Oe):function(h,E,R,F,q){var de,ye;for(de=Ja.length-1;de>=Ja.indexOf(R);de--)if(Pu[ye=Ja[de]].common&&h._adapter.diff(q,F,ye)>=E-1)return ye;return Ja[R?Ja.indexOf(R):0]}(h,Ue.length,de.minUnit,h.min,h.max)),h._majorUnit=q.major.enabled&&"year"!==h._unit?function(h){for(var E=Ja.indexOf(h)+1,R=Ja.length;E<R;++E)if(Pu[Ja[E]].common)return Ja[E]}(h._unit):void 0,h._table=function(h,E,R,F){if("linear"===F||!h.length)return[{time:E,pos:0},{time:R,pos:1}];var ye,Ue,Oe,Xe,gt,q=[],de=[E];for(ye=0,Ue=h.length;ye<Ue;++ye)(Xe=h[ye])>E&&Xe<R&&de.push(Xe);for(de.push(R),ye=0,Ue=de.length;ye<Ue;++ye)gt=de[ye+1],Xe=de[ye],(void 0===(Oe=de[ye-1])||void 0===gt||Math.round((gt+Oe)/2)!==Xe)&&q.push({time:Xe,pos:ye/(Ue-1)});return q}(h._timestamps.data,E,R,gt),h._offsets=function(h,E,R,F,q){var Ue,Oe,de=0,ye=0;return q.offset&&E.length&&(Ue=ff(h,"time",E[0],"pos"),de=1===E.length?1-Ue:(ff(h,"time",E[1],"pos")-Ue)/2,Oe=ff(h,"time",E[E.length-1],"pos"),ye=1===E.length?Oe:(Oe-ff(h,"time",E[E.length-2],"pos"))/2),{start:de,end:ye,factor:1/(de+1+ye)}}(h._table,Ue,0,0,F),q.reverse&&Ue.reverse(),hu(h,Ue,h._majorUnit)},getLabelForIndex:function(h,E){var R=this,F=R._adapter,q=R.chart.data,de=R.options.time,ye=q.labels&&h<q.labels.length?q.labels[h]:"",Ue=q.datasets[E].data[h];return Ge.isObject(Ue)&&(ye=R.getRightValue(Ue)),de.tooltipFormat?F.format(Jl(R,ye),de.tooltipFormat):"string"==typeof ye?ye:F.format(Jl(R,ye),de.displayFormats.datetime)},tickFormatFunction:function(h,E,R,F){var q=this,ye=q.options,Ue=ye.time.displayFormats,Xe=q._majorUnit,gt=Ue[Xe],yt=R[E],nn=ye.ticks,Pn=Xe&&gt&&yt&&yt.major,xn=q._adapter.format(h,F||(Pn?gt:Ue[q._unit])),ir=Pn?nn.major:nn.minor,Gr=Ju([ir.callback,ir.userCallback,nn.callback,nn.userCallback]);return Gr?Gr(xn,E,R):xn},convertTicksToLabels:function(h){var R,F,E=[];for(R=0,F=h.length;R<F;++R)E.push(this.tickFormatFunction(h[R].value,R,h));return E},getPixelForOffset:function(h){var E=this,R=E._offsets,F=ff(E._table,"time",h,"pos");return E.getPixelForDecimal((R.start+F)*R.factor)},getPixelForValue:function(h,E,R){var F=this,q=null;if(void 0!==E&&void 0!==R&&(q=F._timestamps.datasets[R][E]),null===q&&(q=vd(F,h)),null!==q)return F.getPixelForOffset(q)},getPixelForTick:function(h){var E=this.getTicks();return h>=0&&h<E.length?this.getPixelForOffset(E[h].value):null},getValueForPixel:function(h){var E=this,R=E._offsets,F=E.getDecimalForPixel(h)/R.factor-R.end,q=ff(E._table,"pos",F,"time");return E._adapter._create(q)},_getLabelSize:function(h){var E=this,R=E.options.ticks,F=E.ctx.measureText(h).width,q=Ge.toRadians(E.isHorizontal()?R.maxRotation:R.minRotation),de=Math.cos(q),ye=Math.sin(q),Ue=Sl(R.fontSize,br.global.defaultFontSize);return{w:F*de+Ue*ye,h:F*ye+Ue*de}},getLabelWidth:function(h){return this._getLabelSize(h).w},getLabelCapacity:function(h){var E=this,R=E.options.time,F=R.displayFormats,q=F[R.unit]||F.millisecond,de=E.tickFormatFunction(h,0,hu(E,[h],E._majorUnit),q),ye=E._getLabelSize(de),Ue=Math.floor(E.isHorizontal()?E.width/ye.w:E.height/ye.h);return E.options.offset&&Ue--,Ue>0?Ue:1}});$p._defaults={position:"bottom",distribution:"linear",bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}};var _f={category:ss,linear:Et,logarithmic:ns,radialLinear:Xd,time:$p},Dh={datetime:"MMM D, YYYY, h:mm:ss a",millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"};Io._date.override("function"==typeof r?{_id:"moment",formats:function(){return Dh},parse:function(h,E){return"string"==typeof h&&"string"==typeof E?h=r(h,E):h instanceof r||(h=r(h)),h.isValid()?h.valueOf():null},format:function(h,E){return r(h).format(E)},add:function(h,E,R){return r(h).add(E,R).valueOf()},diff:function(h,E,R){return r(h).diff(r(E),R)},startOf:function(h,E,R){return h=r(h),"isoWeek"===E?h.isoWeekday(R).valueOf():h.startOf(E).valueOf()},endOf:function(h,E){return r(h).endOf(E).valueOf()},_create:function(h){return r(h)}}:{}),br._set("global",{plugins:{filler:{propagate:!0}}});var Ql={dataset:function(h){var E=h.fill,R=h.chart,F=R.getDatasetMeta(E),de=F&&R.isDatasetVisible(E)&&F.dataset._children||[],ye=de.length||0;return ye?function(Ue,Oe){return Oe<ye&&de[Oe]._view||null}:null},boundary:function(h){var E=h.boundary,R=E?E.x:null,F=E?E.y:null;return Ge.isArray(E)?function(q,de){return E[de]}:function(q){return{x:null===R?q.x:R,y:null===F?q.y:F}}}};function Hf(h,E,R){var de,F=h._model||{},q=F.fill;if(void 0===q&&(q=!!F.backgroundColor),!1===q||null===q)return!1;if(!0===q)return"origin";if(de=parseFloat(q,10),isFinite(de)&&Math.floor(de)===de)return("-"===q[0]||"+"===q[0])&&(de=E+de),!(de===E||de<0||de>=R)&&de;switch(q){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return q;default:return!1}}function Nd(h){return(h.el._scale||{}).getPointPositionForValue?function(h){var ye,Ue,Oe,Xe,gt,E=h.el._scale,R=E.options,F=E.chart.data.labels.length,q=h.fill,de=[];if(!F)return null;for(Ue=R.ticks.reverse?E.min:E.max,Oe=E.getPointPositionForValue(0,ye=R.ticks.reverse?E.max:E.min),Xe=0;Xe<F;++Xe)gt="start"===q||"end"===q?E.getPointPositionForValue(Xe,"start"===q?ye:Ue):E.getBasePosition(Xe),R.gridLines.circular&&(gt.cx=Oe.x,gt.cy=Oe.y,gt.angle=E.getIndexAngle(Xe)-Math.PI/2),de.push(gt);return de}(h):function(h){var de,E=h.el._model||{},R=h.el._scale||{},F=h.fill,q=null;if(isFinite(F))return null;if("start"===F?q=void 0===E.scaleBottom?R.bottom:E.scaleBottom:"end"===F?q=void 0===E.scaleTop?R.top:E.scaleTop:void 0!==E.scaleZero?q=E.scaleZero:R.getBasePixel&&(q=R.getBasePixel()),null!=q){if(void 0!==q.x&&void 0!==q.y)return q;if(Ge.isFinite(q))return{x:(de=R.isHorizontal())?q:null,y:de?null:q}}return null}(h)}function Dc(h,E,R){var ye,q=h[E].fill,de=[E];if(!R)return q;for(;!1!==q&&-1===de.indexOf(q);){if(!isFinite(q))return q;if(!(ye=h[q]))return!1;if(ye.visible)return q;de.push(q),q=ye.fill}return!1}function Xl(h){var E=h.fill,R="dataset";return!1===E?null:(isFinite(E)||(R="boundary"),Ql[R](h))}function Ji(h){return h&&!h.skip}function cl(h,E,R,F,q){var de,ye,Ue,Oe;if(F&&q){for(h.moveTo(E[0].x,E[0].y),de=1;de<F;++de)Ge.canvas.lineTo(h,E[de-1],E[de]);if(void 0!==R[0].angle){for(ye=R[0].cx,Ue=R[0].cy,Oe=Math.sqrt(Math.pow(R[0].x-ye,2)+Math.pow(R[0].y-Ue,2)),de=q-1;de>0;--de)h.arc(ye,Ue,Oe,R[de].angle,R[de-1].angle,!0);return}for(h.lineTo(R[q-1].x,R[q-1].y),de=q-1;de>0;--de)Ge.canvas.lineTo(h,R[de],R[de-1],!0)}}function Ll(h,E,R,F,q,de){var nn,Pn,xn,ir,Gr,Pi,Zo,Lo,ye=E.length,Ue=F.spanGaps,Oe=[],Xe=[],gt=0,yt=0;for(h.beginPath(),nn=0,Pn=ye;nn<Pn;++nn)Gr=R(ir=E[xn=nn%ye]._view,xn,F),Pi=Ji(ir),Zo=Ji(Gr),de&&void 0===Lo&&Pi&&(Pn=ye+(Lo=nn+1)),Pi&&Zo?(gt=Oe.push(ir),yt=Xe.push(Gr)):gt&&yt&&(Ue?(Pi&&Oe.push(ir),Zo&&Xe.push(Gr)):(cl(h,Oe,Xe,gt,yt),gt=yt=0,Oe=[],Xe=[]));cl(h,Oe,Xe,gt,yt),h.closePath(),h.fillStyle=q,h.fill()}var Pd={id:"filler",afterDatasetsUpdate:function(h,E){var de,ye,Ue,Oe,R=(h.data.datasets||[]).length,F=E.propagate,q=[];for(ye=0;ye<R;++ye)Oe=null,(Ue=(de=h.getDatasetMeta(ye)).dataset)&&Ue._model&&Ue instanceof ls.Line&&(Oe={visible:h.isDatasetVisible(ye),fill:Hf(Ue,ye,R),chart:h,el:Ue}),de.$filler=Oe,q.push(Oe);for(ye=0;ye<R;++ye)(Oe=q[ye])&&(Oe.fill=Dc(q,ye,F),Oe.boundary=Nd(Oe),Oe.mapper=Xl(Oe))},beforeDatasetsDraw:function(h){var F,q,de,ye,Ue,Oe,Xe,E=h._getSortedVisibleDatasetMetas(),R=h.ctx;for(q=E.length-1;q>=0;--q)(F=E[q].$filler)&&F.visible&&(Ue=(de=F.el)._children||[],Xe=(ye=de._view).backgroundColor||br.global.defaultColor,(Oe=F.mapper)&&Xe&&Ue.length&&(Ge.canvas.clipArea(R,h.chartArea),Ll(R,Ue,Oe,ye,Xe,de._loop),Ge.canvas.unclipArea(R)))}},rl=Ge.rtl.getRtlAdapter,Yu=Ge.noop,pc=Ge.valueOrDefault;function Kd(h,E){return h.usePointStyle&&h.boxWidth>E?E:h.boxWidth}br._set("global",{legend:{display:!0,position:"top",align:"center",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(h,E){var R=E.datasetIndex,F=this.chart,q=F.getDatasetMeta(R);q.hidden=null===q.hidden?!F.data.datasets[R].hidden:null,F.update()},onHover:null,onLeave:null,labels:{boxWidth:40,padding:10,generateLabels:function(h){var E=h.data.datasets,R=h.options.legend||{},F=R.labels&&R.labels.usePointStyle;return h._getSortedDatasetMetas().map(function(q){var de=q.controller.getStyle(F?0:void 0);return{text:E[q.index].label,fillStyle:de.backgroundColor,hidden:!h.isDatasetVisible(q.index),lineCap:de.borderCapStyle,lineDash:de.borderDash,lineDashOffset:de.borderDashOffset,lineJoin:de.borderJoinStyle,lineWidth:de.borderWidth,strokeStyle:de.borderColor,pointStyle:de.pointStyle,rotation:de.rotation,datasetIndex:q.index}},this)}}},legendCallback:function(h){var F,q,de,E=document.createElement("ul"),R=h.data.datasets;for(E.setAttribute("class",h.id+"-legend"),F=0,q=R.length;F<q;F++)(de=E.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=R[F].backgroundColor,R[F].label&&de.appendChild(document.createTextNode(R[F].label));return E.outerHTML}});var wf=ar.extend({initialize:function(h){var E=this;Ge.extend(E,h),E.legendHitBoxes=[],E._hoveredItem=null,E.doughnutMode=!1},beforeUpdate:Yu,update:function(h,E,R){var F=this;return F.beforeUpdate(),F.maxWidth=h,F.maxHeight=E,F.margins=R,F.beforeSetDimensions(),F.setDimensions(),F.afterSetDimensions(),F.beforeBuildLabels(),F.buildLabels(),F.afterBuildLabels(),F.beforeFit(),F.fit(),F.afterFit(),F.afterUpdate(),F.minSize},afterUpdate:Yu,beforeSetDimensions:Yu,setDimensions:function(){var h=this;h.isHorizontal()?(h.width=h.maxWidth,h.left=0,h.right=h.width):(h.height=h.maxHeight,h.top=0,h.bottom=h.height),h.paddingLeft=0,h.paddingTop=0,h.paddingRight=0,h.paddingBottom=0,h.minSize={width:0,height:0}},afterSetDimensions:Yu,beforeBuildLabels:Yu,buildLabels:function(){var h=this,E=h.options.labels||{},R=Ge.callback(E.generateLabels,[h.chart],h)||[];E.filter&&(R=R.filter(function(F){return E.filter(F,h.chart.data)})),h.options.reverse&&R.reverse(),h.legendItems=R},afterBuildLabels:Yu,beforeFit:Yu,fit:function(){var h=this,E=h.options,R=E.labels,F=E.display,q=h.ctx,de=Ge.options._parseFont(R),ye=de.size,Ue=h.legendHitBoxes=[],Oe=h.minSize,Xe=h.isHorizontal();if(Xe?(Oe.width=h.maxWidth,Oe.height=F?10:0):(Oe.width=F?10:0,Oe.height=h.maxHeight),F){if(q.font=de.string,Xe){var gt=h.lineWidths=[0],yt=0;q.textAlign="left",q.textBaseline="middle",Ge.each(h.legendItems,function(Zo,Lo){var Xs=Kd(R,ye)+ye/2+q.measureText(Zo.text).width;(0===Lo||gt[gt.length-1]+Xs+2*R.padding>Oe.width)&&(yt+=ye+R.padding,gt[gt.length-(Lo>0?0:1)]=0),Ue[Lo]={left:0,top:0,width:Xs,height:ye},gt[gt.length-1]+=Xs+R.padding}),Oe.height+=yt}else{var nn=R.padding,Pn=h.columnWidths=[],xn=h.columnHeights=[],ir=R.padding,Gr=0,Pi=0;Ge.each(h.legendItems,function(Zo,Lo){var Xs=Kd(R,ye)+ye/2+q.measureText(Zo.text).width;Lo>0&&Pi+ye+2*nn>Oe.height&&(ir+=Gr+R.padding,Pn.push(Gr),xn.push(Pi),Gr=0,Pi=0),Gr=Math.max(Gr,Xs),Pi+=ye+nn,Ue[Lo]={left:0,top:0,width:Xs,height:ye}}),ir+=Gr,Pn.push(Gr),xn.push(Pi),Oe.width+=ir}h.width=Oe.width,h.height=Oe.height}else h.width=Oe.width=h.height=Oe.height=0},afterFit:Yu,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var h=this,E=h.options,R=E.labels,F=br.global,q=F.defaultColor,de=F.elements.line,ye=h.height,Ue=h.columnHeights,Oe=h.width,Xe=h.lineWidths;if(E.display){var ir,gt=rl(E.rtl,h.left,h.minSize.width),yt=h.ctx,nn=pc(R.fontColor,F.defaultFontColor),Pn=Ge.options._parseFont(R),xn=Pn.size;yt.textAlign=gt.textAlign("left"),yt.textBaseline="middle",yt.lineWidth=.5,yt.strokeStyle=nn,yt.fillStyle=nn,yt.font=Pn.string;var Gr=Kd(R,xn),Pi=h.legendHitBoxes,Gs=function(ha,ia){switch(E.align){case"start":return R.padding;case"end":return ha-ia;default:return(ha-ia+R.padding)/2}},Xs=h.isHorizontal();ir=Xs?{x:h.left+Gs(Oe,Xe[0]),y:h.top+R.padding,line:0}:{x:h.left+R.padding,y:h.top+Gs(ye,Ue[0]),line:0},Ge.rtl.overrideTextDirection(h.ctx,E.textDirection);var dl=xn+R.padding;Ge.each(h.legendItems,function(ha,ia){var Pa=yt.measureText(ha.text).width,il=Gr+xn/2+Pa,Eu=ir.x,wa=ir.y;gt.setWidth(h.minSize.width),Xs?ia>0&&Eu+il+R.padding>h.left+h.minSize.width&&(wa=ir.y+=dl,ir.line++,Eu=ir.x=h.left+Gs(Oe,Xe[ir.line])):ia>0&&wa+dl>h.top+h.minSize.height&&(Eu=ir.x=Eu+h.columnWidths[ir.line]+R.padding,ir.line++,wa=ir.y=h.top+Gs(ye,Ue[ir.line]));var ou=gt.x(Eu);(function(ha,ia,Pa){if(!(isNaN(Gr)||Gr<=0)){yt.save();var il=pc(Pa.lineWidth,de.borderWidth);if(yt.fillStyle=pc(Pa.fillStyle,q),yt.lineCap=pc(Pa.lineCap,de.borderCapStyle),yt.lineDashOffset=pc(Pa.lineDashOffset,de.borderDashOffset),yt.lineJoin=pc(Pa.lineJoin,de.borderJoinStyle),yt.lineWidth=il,yt.strokeStyle=pc(Pa.strokeStyle,q),yt.setLineDash&&yt.setLineDash(pc(Pa.lineDash,de.borderDash)),R&&R.usePointStyle){var Eu=Gr*Math.SQRT2/2,wa=gt.xPlus(ha,Gr/2);Ge.canvas.drawPoint(yt,Pa.pointStyle,Eu,wa,ia+xn/2,Pa.rotation)}else yt.fillRect(gt.leftForLtr(ha,Gr),ia,Gr,xn),0!==il&&yt.strokeRect(gt.leftForLtr(ha,Gr),ia,Gr,xn);yt.restore()}})(ou,wa,ha),Pi[ia].left=gt.leftForLtr(ou,Pi[ia].width),Pi[ia].top=wa,function(ha,ia,Pa,il){var Eu=xn/2,wa=gt.xPlus(ha,Gr+Eu),ou=ia+Eu;yt.fillText(Pa.text,wa,ou),Pa.hidden&&(yt.beginPath(),yt.lineWidth=2,yt.moveTo(wa,ou),yt.lineTo(gt.xPlus(wa,il),ou),yt.stroke())}(ou,wa,ha,Pa),Xs?ir.x+=il+R.padding:ir.y+=dl}),Ge.rtl.restoreTextDirection(h.ctx,E.textDirection)}},_getLegendItemAt:function(h,E){var F,q,de,R=this;if(h>=R.left&&h<=R.right&&E>=R.top&&E<=R.bottom)for(de=R.legendHitBoxes,F=0;F<de.length;++F)if(h>=(q=de[F]).left&&h<=q.left+q.width&&E>=q.top&&E<=q.top+q.height)return R.legendItems[F];return null},handleEvent:function(h){var q,E=this,R=E.options,F="mouseup"===h.type?"click":h.type;if("mousemove"===F){if(!R.onHover&&!R.onLeave)return}else{if("click"!==F)return;if(!R.onClick)return}q=E._getLegendItemAt(h.x,h.y),"click"===F?q&&R.onClick&&R.onClick.call(E,h.native,q):(R.onLeave&&q!==E._hoveredItem&&(E._hoveredItem&&R.onLeave.call(E,h.native,E._hoveredItem),E._hoveredItem=q),R.onHover&&q&&R.onHover.call(E,h.native,q))}});function Vl(h,E){var R=new wf({ctx:h.ctx,options:E,chart:h});Zl.configure(h,R,E),Zl.addBox(h,R),h.legend=R}var Id={id:"legend",_element:wf,beforeInit:function(h){var E=h.options.legend;E&&Vl(h,E)},beforeUpdate:function(h){var E=h.options.legend,R=h.legend;E?(Ge.mergeIf(E,br.global.legend),R?(Zl.configure(h,R,E),R.options=E):Vl(h,E)):R&&(Zl.removeBox(h,R),delete h.legend)},afterEvent:function(h,E){var R=h.legend;R&&R.handleEvent(E)}},oc=Ge.noop;br._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,padding:10,position:"top",text:"",weight:2e3}});var hc=ar.extend({initialize:function(h){Ge.extend(this,h),this.legendHitBoxes=[]},beforeUpdate:oc,update:function(h,E,R){var F=this;return F.beforeUpdate(),F.maxWidth=h,F.maxHeight=E,F.margins=R,F.beforeSetDimensions(),F.setDimensions(),F.afterSetDimensions(),F.beforeBuildLabels(),F.buildLabels(),F.afterBuildLabels(),F.beforeFit(),F.fit(),F.afterFit(),F.afterUpdate(),F.minSize},afterUpdate:oc,beforeSetDimensions:oc,setDimensions:function(){var h=this;h.isHorizontal()?(h.width=h.maxWidth,h.left=0,h.right=h.width):(h.height=h.maxHeight,h.top=0,h.bottom=h.height),h.paddingLeft=0,h.paddingTop=0,h.paddingRight=0,h.paddingBottom=0,h.minSize={width:0,height:0}},afterSetDimensions:oc,beforeBuildLabels:oc,buildLabels:oc,afterBuildLabels:oc,beforeFit:oc,fit:function(){var de,h=this,E=h.options,R=h.minSize={},F=h.isHorizontal();E.display?(de=(Ge.isArray(E.text)?E.text.length:1)*Ge.options._parseFont(E).lineHeight+2*E.padding,h.width=R.width=F?h.maxWidth:de,h.height=R.height=F?de:h.maxHeight):h.width=R.width=h.height=R.height=0},afterFit:oc,isHorizontal:function(){var h=this.options.position;return"top"===h||"bottom"===h},draw:function(){var h=this,E=h.ctx,R=h.options;if(R.display){var yt,nn,Pn,F=Ge.options._parseFont(R),q=F.lineHeight,de=q/2+R.padding,ye=0,Ue=h.top,Oe=h.left,Xe=h.bottom,gt=h.right;E.fillStyle=Ge.valueOrDefault(R.fontColor,br.global.defaultFontColor),E.font=F.string,h.isHorizontal()?(nn=Oe+(gt-Oe)/2,Pn=Ue+de,yt=gt-Oe):(nn="left"===R.position?Oe+de:gt-de,Pn=Ue+(Xe-Ue)/2,yt=Xe-Ue,ye=Math.PI*("left"===R.position?-.5:.5)),E.save(),E.translate(nn,Pn),E.rotate(ye),E.textAlign="center",E.textBaseline="middle";var xn=R.text;if(Ge.isArray(xn))for(var ir=0,Gr=0;Gr<xn.length;++Gr)E.fillText(xn[Gr],0,ir,yt),ir+=q;else E.fillText(xn,0,0,yt);E.restore()}}});function _u(h,E){var R=new hc({ctx:h.ctx,options:E,chart:h});Zl.configure(h,R,E),Zl.addBox(h,R),h.titleBlock=R}var Hc={},cu=Pd,Lu=Id,Ou={id:"title",_element:hc,beforeInit:function(h){var E=h.options.title;E&&_u(h,E)},beforeUpdate:function(h){var E=h.options.title,R=h.titleBlock;E?(Ge.mergeIf(E,br.global.title),R?(Zl.configure(h,R,E),R.options=E):_u(h,E)):R&&(Zl.removeBox(h,R),delete h.titleBlock)}};for(var Rc in Hc.filler=cu,Hc.legend=Lu,Hc.title=Ou,mn.helpers=Ge,function(){function h(F,q,de){var ye;return"string"==typeof F?(ye=parseInt(F,10),-1!==F.indexOf("%")&&(ye=ye/100*q.parentNode[de])):ye=F,ye}function E(F){return null!=F&&"none"!==F}function R(F,q,de){var ye=document.defaultView,Ue=Ge._getParentNode(F),Oe=ye.getComputedStyle(F)[q],Xe=ye.getComputedStyle(Ue)[q],gt=E(Oe),yt=E(Xe),nn=Number.POSITIVE_INFINITY;return gt||yt?Math.min(gt?h(Oe,F,de):nn,yt?h(Xe,Ue,de):nn):"none"}Ge.where=function(F,q){if(Ge.isArray(F)&&Array.prototype.filter)return F.filter(q);var de=[];return Ge.each(F,function(ye){q(ye)&&de.push(ye)}),de},Ge.findIndex=Array.prototype.findIndex?function(F,q,de){return F.findIndex(q,de)}:function(F,q,de){de=void 0===de?F:de;for(var ye=0,Ue=F.length;ye<Ue;++ye)if(q.call(de,F[ye],ye,F))return ye;return-1},Ge.findNextWhere=function(F,q,de){Ge.isNullOrUndef(de)&&(de=-1);for(var ye=de+1;ye<F.length;ye++){var Ue=F[ye];if(q(Ue))return Ue}},Ge.findPreviousWhere=function(F,q,de){Ge.isNullOrUndef(de)&&(de=F.length);for(var ye=de-1;ye>=0;ye--){var Ue=F[ye];if(q(Ue))return Ue}},Ge.isNumber=function(F){return!isNaN(parseFloat(F))&&isFinite(F)},Ge.almostEquals=function(F,q,de){return Math.abs(F-q)<de},Ge.almostWhole=function(F,q){var de=Math.round(F);return de-q<=F&&de+q>=F},Ge.max=function(F){return F.reduce(function(q,de){return isNaN(de)?q:Math.max(q,de)},Number.NEGATIVE_INFINITY)},Ge.min=function(F){return F.reduce(function(q,de){return isNaN(de)?q:Math.min(q,de)},Number.POSITIVE_INFINITY)},Ge.sign=Math.sign?function(F){return Math.sign(F)}:function(F){return 0==(F=+F)||isNaN(F)?F:F>0?1:-1},Ge.toRadians=function(F){return F*(Math.PI/180)},Ge.toDegrees=function(F){return F*(180/Math.PI)},Ge._decimalPlaces=function(F){if(Ge.isFinite(F)){for(var q=1,de=0;Math.round(F*q)/q!==F;)q*=10,de++;return de}},Ge.getAngleFromPoint=function(F,q){var de=q.x-F.x,ye=q.y-F.y,Ue=Math.sqrt(de*de+ye*ye),Oe=Math.atan2(ye,de);return Oe<-.5*Math.PI&&(Oe+=2*Math.PI),{angle:Oe,distance:Ue}},Ge.distanceBetweenPoints=function(F,q){return Math.sqrt(Math.pow(q.x-F.x,2)+Math.pow(q.y-F.y,2))},Ge.aliasPixel=function(F){return F%2==0?0:.5},Ge._alignPixel=function(F,q,de){var ye=F.currentDevicePixelRatio,Ue=de/2;return Math.round((q-Ue)*ye)/ye+Ue},Ge.splineCurve=function(F,q,de,ye){var Ue=F.skip?q:F,Oe=q,Xe=de.skip?q:de,gt=Math.sqrt(Math.pow(Oe.x-Ue.x,2)+Math.pow(Oe.y-Ue.y,2)),yt=Math.sqrt(Math.pow(Xe.x-Oe.x,2)+Math.pow(Xe.y-Oe.y,2)),nn=gt/(gt+yt),Pn=yt/(gt+yt),xn=ye*(nn=isNaN(nn)?0:nn),ir=ye*(Pn=isNaN(Pn)?0:Pn);return{previous:{x:Oe.x-xn*(Xe.x-Ue.x),y:Oe.y-xn*(Xe.y-Ue.y)},next:{x:Oe.x+ir*(Xe.x-Ue.x),y:Oe.y+ir*(Xe.y-Ue.y)}}},Ge.EPSILON=Number.EPSILON||1e-14,Ge.splineCurveMonotone=function(F){var ye,Ue,Oe,Xe,yt,nn,Pn,xn,ir,q=(F||[]).map(function(Gr){return{model:Gr._model,deltaK:0,mK:0}}),de=q.length;for(ye=0;ye<de;++ye)if(!(Oe=q[ye]).model.skip){if(Ue=ye>0?q[ye-1]:null,(Xe=ye<de-1?q[ye+1]:null)&&!Xe.model.skip){var gt=Xe.model.x-Oe.model.x;Oe.deltaK=0!==gt?(Xe.model.y-Oe.model.y)/gt:0}Oe.mK=!Ue||Ue.model.skip?Oe.deltaK:!Xe||Xe.model.skip?Ue.deltaK:this.sign(Ue.deltaK)!==this.sign(Oe.deltaK)?0:(Ue.deltaK+Oe.deltaK)/2}for(ye=0;ye<de-1;++ye)if(Xe=q[ye+1],!(Oe=q[ye]).model.skip&&!Xe.model.skip){if(Ge.almostEquals(Oe.deltaK,0,this.EPSILON)){Oe.mK=Xe.mK=0;continue}yt=Oe.mK/Oe.deltaK,nn=Xe.mK/Oe.deltaK,!((xn=Math.pow(yt,2)+Math.pow(nn,2))<=9)&&(Pn=3/Math.sqrt(xn),Oe.mK=yt*Pn*Oe.deltaK,Xe.mK=nn*Pn*Oe.deltaK)}for(ye=0;ye<de;++ye)!(Oe=q[ye]).model.skip&&(Xe=ye<de-1?q[ye+1]:null,(Ue=ye>0?q[ye-1]:null)&&!Ue.model.skip&&(Oe.model.controlPointPreviousX=Oe.model.x-(ir=(Oe.model.x-Ue.model.x)/3),Oe.model.controlPointPreviousY=Oe.model.y-ir*Oe.mK),Xe&&!Xe.model.skip&&(Oe.model.controlPointNextX=Oe.model.x+(ir=(Xe.model.x-Oe.model.x)/3),Oe.model.controlPointNextY=Oe.model.y+ir*Oe.mK))},Ge.nextItem=function(F,q,de){return de?q>=F.length-1?F[0]:F[q+1]:q>=F.length-1?F[F.length-1]:F[q+1]},Ge.previousItem=function(F,q,de){return de?q<=0?F[F.length-1]:F[q-1]:q<=0?F[0]:F[q-1]},Ge.niceNum=function(F,q){var de=Math.floor(Ge.log10(F)),ye=F/Math.pow(10,de);return(q?ye<1.5?1:ye<3?2:ye<7?5:10:ye<=1?1:ye<=2?2:ye<=5?5:10)*Math.pow(10,de)},Ge.requestAnimFrame="undefined"==typeof window?function(F){F()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(F){return window.setTimeout(F,1e3/60)},Ge.getRelativePosition=function(F,q){var de,ye,Ue=F.originalEvent||F,Oe=F.target||F.srcElement,Xe=Oe.getBoundingClientRect(),gt=Ue.touches;gt&&gt.length>0?(de=gt[0].clientX,ye=gt[0].clientY):(de=Ue.clientX,ye=Ue.clientY);var yt=parseFloat(Ge.getStyle(Oe,"padding-left")),nn=parseFloat(Ge.getStyle(Oe,"padding-top")),Pn=parseFloat(Ge.getStyle(Oe,"padding-right")),xn=parseFloat(Ge.getStyle(Oe,"padding-bottom")),Gr=Xe.bottom-Xe.top-nn-xn;return{x:de=Math.round((de-Xe.left-yt)/(Xe.right-Xe.left-yt-Pn)*Oe.width/q.currentDevicePixelRatio),y:ye=Math.round((ye-Xe.top-nn)/Gr*Oe.height/q.currentDevicePixelRatio)}},Ge.getConstraintWidth=function(F){return R(F,"max-width","clientWidth")},Ge.getConstraintHeight=function(F){return R(F,"max-height","clientHeight")},Ge._calculatePadding=function(F,q,de){return(q=Ge.getStyle(F,q)).indexOf("%")>-1?de*parseInt(q,10)/100:parseInt(q,10)},Ge._getParentNode=function(F){var q=F.parentNode;return q&&"[object ShadowRoot]"===q.toString()&&(q=q.host),q},Ge.getMaximumWidth=function(F){var q=Ge._getParentNode(F);if(!q)return F.clientWidth;var de=q.clientWidth,Oe=de-Ge._calculatePadding(q,"padding-left",de)-Ge._calculatePadding(q,"padding-right",de),Xe=Ge.getConstraintWidth(F);return isNaN(Xe)?Oe:Math.min(Oe,Xe)},Ge.getMaximumHeight=function(F){var q=Ge._getParentNode(F);if(!q)return F.clientHeight;var de=q.clientHeight,Oe=de-Ge._calculatePadding(q,"padding-top",de)-Ge._calculatePadding(q,"padding-bottom",de),Xe=Ge.getConstraintHeight(F);return isNaN(Xe)?Oe:Math.min(Oe,Xe)},Ge.getStyle=function(F,q){return F.currentStyle?F.currentStyle[q]:document.defaultView.getComputedStyle(F,null).getPropertyValue(q)},Ge.retinaScale=function(F,q){var de=F.currentDevicePixelRatio=q||"undefined"!=typeof window&&window.devicePixelRatio||1;if(1!==de){var ye=F.canvas,Ue=F.height,Oe=F.width;ye.height=Ue*de,ye.width=Oe*de,F.ctx.scale(de,de),!ye.style.height&&!ye.style.width&&(ye.style.height=Ue+"px",ye.style.width=Oe+"px")}},Ge.fontString=function(F,q,de){return q+" "+F+"px "+de},Ge.longestText=function(F,q,de,ye){var Ue=(ye=ye||{}).data=ye.data||{},Oe=ye.garbageCollect=ye.garbageCollect||[];ye.font!==q&&(Ue=ye.data={},Oe=ye.garbageCollect=[],ye.font=q),F.font=q;var yt,nn,Pn,xn,ir,Xe=0,gt=de.length;for(yt=0;yt<gt;yt++)if(null!=(xn=de[yt])&&!0!==Ge.isArray(xn))Xe=Ge.measureText(F,Ue,Oe,Xe,xn);else if(Ge.isArray(xn))for(nn=0,Pn=xn.length;nn<Pn;nn++)null!=(ir=xn[nn])&&!Ge.isArray(ir)&&(Xe=Ge.measureText(F,Ue,Oe,Xe,ir));var Gr=Oe.length/2;if(Gr>de.length){for(yt=0;yt<Gr;yt++)delete Ue[Oe[yt]];Oe.splice(0,Gr)}return Xe},Ge.measureText=function(F,q,de,ye,Ue){var Oe=q[Ue];return Oe||(Oe=q[Ue]=F.measureText(Ue).width,de.push(Ue)),Oe>ye&&(ye=Oe),ye},Ge.numberOfLabelLines=function(F){var q=1;return Ge.each(F,function(de){Ge.isArray(de)&&de.length>q&&(q=de.length)}),q},Ge.color=Br?function(F){return F instanceof CanvasGradient&&(F=br.global.defaultColor),Br(F)}:function(F){return console.error("Color.js not found!"),F},Ge.getHoverColor=function(F){return F instanceof CanvasPattern||F instanceof CanvasGradient?F:Ge.color(F).saturate(.5).darken(.1).rgbString()}}(),mn._adapters=Io,mn.Animation=lo,mn.animationService=vo,mn.controllers=pi,mn.DatasetController=Mi,mn.defaults=br,mn.Element=ar,mn.elements=ls,mn.Interaction=sl,mn.layouts=Zl,mn.platform=Aa,mn.plugins=Ss,mn.Scale=Nl,mn.scaleService=$u,mn.Ticks=Fo,mn.Tooltip=bl,mn.helpers.each(_f,function(h,E){mn.scaleService.registerScaleType(E,h,h._defaults)}),Hc)Hc.hasOwnProperty(Rc)&&mn.plugins.register(Hc[Rc]);mn.platform.initialize();var bu=mn;return"undefined"!=typeof window&&(window.Chart=mn),mn.Chart=mn,mn.Legend=Hc.legend._element,mn.Title=Hc.title._element,mn.pluginService=mn.plugins,mn.PluginBase=mn.Element.extend({}),mn.canvasHelpers=mn.helpers.canvas,mn.layoutService=mn.layouts,mn.LinearScaleBase=al,mn.helpers.each(["Bar","Bubble","Doughnut","Line","PolarArea","Radar","Scatter"],function(h){mn[h]=function(E,R){return new mn(E,mn.helpers.merge(R||{},{type:h.charAt(0).toLowerCase()+h.slice(1)}))}}),bu}(function(){try{return i(16738)}catch(p){}}())},82885:(v,T)=>{var r;!function(){"use strict";var u={}.hasOwnProperty;function p(){for(var d=[],e=0;e<arguments.length;e++){var _=arguments[e];if(_){var y=typeof _;if("string"===y||"number"===y)d.push(_);else if(Array.isArray(_)){if(_.length){var S=p.apply(null,_);S&&d.push(S)}}else if("object"===y)if(_.toString===Object.prototype.toString)for(var A in _)u.call(_,A)&&_[A]&&d.push(A);else d.push(_.toString())}}return d.join(" ")}v.exports?(p.default=p,v.exports=p):void 0!==(r=function(){return p}.apply(T,[]))&&(v.exports=r)}()},2665:v=>{v.exports=function(i,r){for(var u=[],p=0;p<i.length;p++){var d=r(i[p],p);T(d)?u.push.apply(u,d):u.push(d)}return u};var T=Array.isArray||function(i){return"[object Array]"===Object.prototype.toString.call(i)}},7281:(v,T)=>{"use strict";T.parse=function(S,A){if("string"!=typeof S)throw new TypeError("argument str must be a string");for(var N={},Z=(A||{}).decode||d,J=0;J<S.length;){var K=S.indexOf("=",J);if(-1===K)break;var ee=S.indexOf(";",J);if(-1===ee)ee=S.length;else if(ee<K){J=S.lastIndexOf(";",K-1)+1;continue}var ue=S.slice(J,K).trim();if(void 0===N[ue]){var ae=S.slice(K+1,ee).trim();34===ae.charCodeAt(0)&&(ae=ae.slice(1,-1)),N[ue]=y(ae,Z)}J=ee+1}return N},T.serialize=function(S,A,N){var L=N||{},Z=L.encode||e;if("function"!=typeof Z)throw new TypeError("option encode is invalid");if(!r.test(S))throw new TypeError("argument name is invalid");var J=Z(A);if(J&&!r.test(J))throw new TypeError("argument val is invalid");var K=S+"="+J;if(null!=L.maxAge){var ee=L.maxAge-0;if(isNaN(ee)||!isFinite(ee))throw new TypeError("option maxAge is invalid");K+="; Max-Age="+Math.floor(ee)}if(L.domain){if(!r.test(L.domain))throw new TypeError("option domain is invalid");K+="; Domain="+L.domain}if(L.path){if(!r.test(L.path))throw new TypeError("option path is invalid");K+="; Path="+L.path}if(L.expires){var ue=L.expires;if(!function(S){return"[object Date]"===i.call(S)||S instanceof Date}(ue)||isNaN(ue.valueOf()))throw new TypeError("option expires is invalid");K+="; Expires="+ue.toUTCString()}if(L.httpOnly&&(K+="; HttpOnly"),L.secure&&(K+="; Secure"),L.priority)switch("string"==typeof L.priority?L.priority.toLowerCase():L.priority){case"low":K+="; Priority=Low";break;case"medium":K+="; Priority=Medium";break;case"high":K+="; Priority=High";break;default:throw new TypeError("option priority is invalid")}if(L.sameSite)switch("string"==typeof L.sameSite?L.sameSite.toLowerCase():L.sameSite){case!0:K+="; SameSite=Strict";break;case"lax":K+="; SameSite=Lax";break;case"strict":K+="; SameSite=Strict";break;case"none":K+="; SameSite=None";break;default:throw new TypeError("option sameSite is invalid")}return K};var i=Object.prototype.toString,r=/^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;function d(S){return-1!==S.indexOf("%")?decodeURIComponent(S):S}function e(S){return encodeURIComponent(S)}function y(S,A){try{return A(S)}catch(N){return S}}},96967:(v,T,i)=>{"use strict";var r=i(35311),u={"text/plain":"Text","text/html":"Url",default:"Text"};v.exports=function(_,y){var S,A,N,L,Z,J,K=!1;y||(y={}),S=y.debug||!1;try{if(N=r(),L=document.createRange(),Z=document.getSelection(),(J=document.createElement("span")).textContent=_,J.ariaHidden="true",J.style.all="unset",J.style.position="fixed",J.style.top=0,J.style.clip="rect(0, 0, 0, 0)",J.style.whiteSpace="pre",J.style.webkitUserSelect="text",J.style.MozUserSelect="text",J.style.msUserSelect="text",J.style.userSelect="text",J.addEventListener("copy",function(ue){ue.stopPropagation(),y.format&&(ue.preventDefault(),void 0===ue.clipboardData?(S&&console.warn("unable to use e.clipboardData"),S&&console.warn("trying IE specific stuff"),window.clipboardData.clearData(),window.clipboardData.setData(u[y.format]||u.default,_)):(ue.clipboardData.clearData(),ue.clipboardData.setData(y.format,_))),y.onCopy&&(ue.preventDefault(),y.onCopy(ue.clipboardData))}),document.body.appendChild(J),L.selectNodeContents(J),Z.addRange(L),!document.execCommand("copy"))throw new Error("copy command was unsuccessful");K=!0}catch(ue){S&&console.error("unable to copy using execCommand: ",ue),S&&console.warn("trying IE specific stuff");try{window.clipboardData.setData(y.format||"text",_),y.onCopy&&y.onCopy(window.clipboardData),K=!0}catch(ae){S&&console.error("unable to copy using clipboardData: ",ae),S&&console.error("falling back to prompt"),A=function(_){var y=(/mac os x/i.test(navigator.userAgent)?"\u2318":"Ctrl")+"+C";return _.replace(/#{\s*key\s*}/g,y)}("message"in y?y.message:"Copy to clipboard: #{key}, Enter"),window.prompt(A,_)}}finally{Z&&("function"==typeof Z.removeRange?Z.removeRange(L):Z.removeAllRanges()),J&&document.body.removeChild(J),N()}return K}},43987:(v,T,i)=>{var r=i(75242);v.exports=r},99556:(v,T,i)=>{var r=i(10323);v.exports=r},39287:(v,T,i)=>{var r=i(8748);v.exports=r},52964:(v,T,i)=>{var r=i(47506);v.exports=r},25272:(v,T,i)=>{var r=i(71873);v.exports=r},54450:(v,T,i)=>{var r=i(19095);v.exports=r},39557:(v,T,i)=>{var r=i(52049);v.exports=r},61611:(v,T,i)=>{var r=i(87054);v.exports=r},22549:(v,T,i)=>{var r=i(45284);v.exports=r},47646:(v,T,i)=>{var r=i(70157);v.exports=r},78663:(v,T,i)=>{var r=i(640);v.exports=r},48498:(v,T,i)=>{var r=i(50320);v.exports=r},4922:(v,T,i)=>{var r=i(93006);v.exports=r},95190:(v,T,i)=>{var r=i(36226);v.exports=r},78525:(v,T,i)=>{var r=i(21968);v.exports=r},21064:(v,T,i)=>{var r=i(87259);v.exports=r},65641:(v,T,i)=>{var r=i(62021);v.exports=r},21693:(v,T,i)=>{var r=i(57682);v.exports=r},88907:(v,T,i)=>{var r=i(94222);v.exports=r},41432:(v,T,i)=>{var r=i(1162);v.exports=r},7398:(v,T,i)=>{var r=i(82805);v.exports=r},67221:(v,T,i)=>{var r=i(26498);v.exports=r},67447:(v,T,i)=>{var r=i(44850);v.exports=r},58811:(v,T,i)=>{var r=i(9634);v.exports=r},19573:(v,T,i)=>{var r=i(96551);v.exports=r},10226:(v,T,i)=>{var r=i(98908);v.exports=r},74771:(v,T,i)=>{i(3934),i(261);var r=i(13544);v.exports=r.Array.from},8412:(v,T,i)=>{i(2862);var r=i(13544);v.exports=r.Array.isArray},77377:(v,T,i)=>{i(1625);var r=i(97911);v.exports=r("Array").concat},399:(v,T,i)=>{i(1285),i(17221);var r=i(97911);v.exports=r("Array").entries},66933:(v,T,i)=>{i(70466);var r=i(97911);v.exports=r("Array").every},9504:(v,T,i)=>{i(24990);var r=i(97911);v.exports=r("Array").fill},82168:(v,T,i)=>{i(56534);var r=i(97911);v.exports=r("Array").filter},65618:(v,T,i)=>{i(12773);var r=i(97911);v.exports=r("Array").findIndex},9186:(v,T,i)=>{i(60326);var r=i(97911);v.exports=r("Array").find},98812:(v,T,i)=>{i(98792);var r=i(97911);v.exports=r("Array").forEach},58479:(v,T,i)=>{i(77059);var r=i(97911);v.exports=r("Array").includes},43207:(v,T,i)=>{i(2795);var r=i(97911);v.exports=r("Array").indexOf},33195:(v,T,i)=>{i(1285),i(17221);var r=i(97911);v.exports=r("Array").keys},63033:(v,T,i)=>{i(74926);var r=i(97911);v.exports=r("Array").lastIndexOf},5736:(v,T,i)=>{i(88119);var r=i(97911);v.exports=r("Array").map},7198:(v,T,i)=>{i(46250);var r=i(97911);v.exports=r("Array").reduce},84302:(v,T,i)=>{i(32836);var r=i(97911);v.exports=r("Array").reverse},86693:(v,T,i)=>{i(72999);var r=i(97911);v.exports=r("Array").slice},24273:(v,T,i)=>{i(50733);var r=i(97911);v.exports=r("Array").some},45974:(v,T,i)=>{i(93639);var r=i(97911);v.exports=r("Array").sort},68012:(v,T,i)=>{i(63117);var r=i(97911);v.exports=r("Array").splice},46332:(v,T,i)=>{i(1285),i(17221);var r=i(97911);v.exports=r("Array").values},42618:(v,T,i)=>{i(34699);var r=i(13544);v.exports=r.Date.now},97724:(v,T,i)=>{i(33379);var r=i(97911);v.exports=r("Function").bind},63791:(v,T,i)=>{i(1285),i(3934);var r=i(34014);v.exports=r},27959:(v,T,i)=>{i(87404),v.exports=i(70009)},69029:(v,T,i)=>{var r=i(23336),u=i(97724),p=Function.prototype;v.exports=function(d){var e=d.bind;return d===p||r(p,d)&&e===p.bind?u:e}},28924:(v,T,i)=>{var r=i(23336),u=i(77377),p=Array.prototype;v.exports=function(d){var e=d.concat;return d===p||r(p,d)&&e===p.concat?u:e}},98709:(v,T,i)=>{var r=i(23336),u=i(66933),p=Array.prototype;v.exports=function(d){var e=d.every;return d===p||r(p,d)&&e===p.every?u:e}},65991:(v,T,i)=>{var r=i(23336),u=i(9504),p=Array.prototype;v.exports=function(d){var e=d.fill;return d===p||r(p,d)&&e===p.fill?u:e}},64158:(v,T,i)=>{var r=i(23336),u=i(82168),p=Array.prototype;v.exports=function(d){var e=d.filter;return d===p||r(p,d)&&e===p.filter?u:e}},91799:(v,T,i)=>{var r=i(23336),u=i(65618),p=Array.prototype;v.exports=function(d){var e=d.findIndex;return d===p||r(p,d)&&e===p.findIndex?u:e}},26155:(v,T,i)=>{var r=i(23336),u=i(9186),p=Array.prototype;v.exports=function(d){var e=d.find;return d===p||r(p,d)&&e===p.find?u:e}},33758:(v,T,i)=>{var r=i(23336),u=i(58479),p=i(85136),d=Array.prototype,e=String.prototype;v.exports=function(_){var y=_.includes;return _===d||r(d,_)&&y===d.includes?u:"string"==typeof _||_===e||r(e,_)&&y===e.includes?p:y}},7592:(v,T,i)=>{var r=i(23336),u=i(43207),p=Array.prototype;v.exports=function(d){var e=d.indexOf;return d===p||r(p,d)&&e===p.indexOf?u:e}},17480:(v,T,i)=>{var r=i(23336),u=i(63033),p=Array.prototype;v.exports=function(d){var e=d.lastIndexOf;return d===p||r(p,d)&&e===p.lastIndexOf?u:e}},20681:(v,T,i)=>{var r=i(23336),u=i(5736),p=Array.prototype;v.exports=function(d){var e=d.map;return d===p||r(p,d)&&e===p.map?u:e}},90949:(v,T,i)=>{var r=i(23336),u=i(7198),p=Array.prototype;v.exports=function(d){var e=d.reduce;return d===p||r(p,d)&&e===p.reduce?u:e}},99316:(v,T,i)=>{var r=i(23336),u=i(96302),p=String.prototype;v.exports=function(d){var e=d.repeat;return"string"==typeof d||d===p||r(p,d)&&e===p.repeat?u:e}},62212:(v,T,i)=>{var r=i(23336),u=i(84302),p=Array.prototype;v.exports=function(d){var e=d.reverse;return d===p||r(p,d)&&e===p.reverse?u:e}},49073:(v,T,i)=>{var r=i(23336),u=i(86693),p=Array.prototype;v.exports=function(d){var e=d.slice;return d===p||r(p,d)&&e===p.slice?u:e}},24146:(v,T,i)=>{var r=i(23336),u=i(24273),p=Array.prototype;v.exports=function(d){var e=d.some;return d===p||r(p,d)&&e===p.some?u:e}},40104:(v,T,i)=>{var r=i(23336),u=i(45974),p=Array.prototype;v.exports=function(d){var e=d.sort;return d===p||r(p,d)&&e===p.sort?u:e}},3555:(v,T,i)=>{var r=i(23336),u=i(68012),p=Array.prototype;v.exports=function(d){var e=d.splice;return d===p||r(p,d)&&e===p.splice?u:e}},68333:(v,T,i)=>{var r=i(23336),u=i(98720),p=String.prototype;v.exports=function(d){var e=d.startsWith;return"string"==typeof d||d===p||r(p,d)&&e===p.startsWith?u:e}},65786:(v,T,i)=>{var r=i(23336),u=i(75998),p=String.prototype;v.exports=function(d){var e=d.trim;return"string"==typeof d||d===p||r(p,d)&&e===p.trim?u:e}},66306:(v,T,i)=>{i(75071);var r=i(13544),u=i(2543);r.JSON||(r.JSON={stringify:JSON.stringify}),v.exports=function(d,e,_){return u(r.JSON.stringify,null,arguments)}},31845:(v,T,i)=>{i(1285),i(85140),i(17221),i(3934);var r=i(13544);v.exports=r.Map},44168:(v,T,i)=>{i(67234);var r=i(13544);v.exports=r.Object.assign},25852:(v,T,i)=>{i(86516);var u=i(13544).Object;v.exports=function(d,e){return u.create(d,e)}},24457:(v,T,i)=>{i(36255);var u=i(13544).Object,p=v.exports=function(e,_){return u.defineProperties(e,_)};u.defineProperties.sham&&(p.sham=!0)},99671:(v,T,i)=>{i(84468);var u=i(13544).Object,p=v.exports=function(e,_,y){return u.defineProperty(e,_,y)};u.defineProperty.sham&&(p.sham=!0)},35161:(v,T,i)=>{i(54989);var r=i(13544);v.exports=r.Object.entries},38007:(v,T,i)=>{i(86627);var u=i(13544).Object,p=v.exports=function(e,_){return u.getOwnPropertyDescriptor(e,_)};u.getOwnPropertyDescriptor.sham&&(p.sham=!0)},57432:(v,T,i)=>{i(78275);var r=i(13544);v.exports=r.Object.getOwnPropertyDescriptors},36541:(v,T,i)=>{i(56728);var r=i(13544);v.exports=r.Object.getOwnPropertySymbols},17303:(v,T,i)=>{i(31193);var r=i(13544);v.exports=r.Object.getPrototypeOf},62149:(v,T,i)=>{i(56557);var r=i(13544);v.exports=r.Object.keys},86537:(v,T,i)=>{i(17971);var r=i(13544);v.exports=r.Object.setPrototypeOf},79553:(v,T,i)=>{i(88923);var r=i(13544);v.exports=r.Object.values},80092:(v,T,i)=>{i(10901),i(1285),i(17221),i(66793),i(84798),i(98857),i(30185),i(3934);var r=i(13544);v.exports=r.Promise},472:(v,T,i)=>{i(19539);var r=i(13544);v.exports=r.Reflect.construct},4678:(v,T,i)=>{i(60851);var r=i(13544);v.exports=r.Reflect.get},85136:(v,T,i)=>{i(97764);var r=i(97911);v.exports=r("String").includes},96302:(v,T,i)=>{i(3588);var r=i(97911);v.exports=r("String").repeat},98720:(v,T,i)=>{i(24655);var r=i(97911);v.exports=r("String").startsWith},75998:(v,T,i)=>{i(90451);var r=i(97911);v.exports=r("String").trim},61697:(v,T,i)=>{i(1625),i(17221),i(56728),i(16426),i(1172),i(99579),i(41258),i(2383),i(44339),i(64776),i(88215),i(65389),i(12733),i(97977),i(59792),i(60242),i(26291),i(32300),i(63603),i(44864);var r=i(13544);v.exports=r.Symbol},42497:(v,T,i)=>{i(1285),i(17221),i(3934),i(2383);var r=i(89734);v.exports=r.f("iterator")},58255:(v,T,i)=>{i(1285),i(17221),i(90770);var r=i(13544);v.exports=r.WeakMap},56286:(v,T,i)=>{v.exports=i(73875)},54153:(v,T,i)=>{v.exports=i(91700)},90755:(v,T,i)=>{v.exports=i(70589)},60833:(v,T,i)=>{v.exports=i(6324)},98235:(v,T,i)=>{v.exports=i(71432)},78096:(v,T,i)=>{v.exports=i(73712)},31236:(v,T,i)=>{v.exports=i(58044)},15819:(v,T,i)=>{v.exports=i(55451)},44948:(v,T,i)=>{v.exports=i(61483)},96471:(v,T,i)=>{v.exports=i(46815)},5228:(v,T,i)=>{v.exports=i(28296)},50182:(v,T,i)=>{v.exports=i(96973)},41171:(v,T,i)=>{v.exports=i(47194)},54585:(v,T,i)=>{v.exports=i(56805)},62005:(v,T,i)=>{v.exports=i(32944)},39964:(v,T,i)=>{v.exports=i(70729)},70326:(v,T,i)=>{v.exports=i(48299)},98162:(v,T,i)=>{v.exports=i(33969)},42346:(v,T,i)=>{v.exports=i(26421)},4204:(v,T,i)=>{v.exports=i(37785)},24329:(v,T,i)=>{v.exports=i(15123)},2793:(v,T,i)=>{v.exports=i(49745)},42700:(v,T,i)=>{v.exports=i(29044)},70269:(v,T,i)=>{v.exports=i(20611)},88819:(v,T,i)=>{v.exports=i(65861)},55912:(v,T,i)=>{v.exports=i(63816)},73875:(v,T,i)=>{var r=i(43987);v.exports=r},91700:(v,T,i)=>{var r=i(99556);v.exports=r},70589:(v,T,i)=>{var r=i(39287);v.exports=r},6324:(v,T,i)=>{i(65237);var r=i(52964);v.exports=r},71432:(v,T,i)=>{var r=i(25272);v.exports=r},73712:(v,T,i)=>{var r=i(54450);v.exports=r},58044:(v,T,i)=>{var r=i(39557);v.exports=r},55451:(v,T,i)=>{var r=i(61611);v.exports=r},61483:(v,T,i)=>{var r=i(22549);v.exports=r},46815:(v,T,i)=>{var r=i(47646);v.exports=r},28296:(v,T,i)=>{var r=i(78663);i(78271),i(60854),i(10509),i(30887),i(54547),i(68996),i(1530),i(60176),i(41554),i(41688),i(92847),i(17316),i(58786),i(35517),i(12783),i(69773),i(22337),i(40199),i(69046),i(84131),v.exports=r},96973:(v,T,i)=>{var r=i(48498);v.exports=r},47194:(v,T,i)=>{var r=i(4922);v.exports=r},56805:(v,T,i)=>{var r=i(95190);v.exports=r},32944:(v,T,i)=>{var r=i(78525);v.exports=r},70729:(v,T,i)=>{var r=i(21064);v.exports=r},48299:(v,T,i)=>{var r=i(65641);v.exports=r},33969:(v,T,i)=>{var r=i(21693);v.exports=r},26421:(v,T,i)=>{var r=i(88907);v.exports=r},37785:(v,T,i)=>{var r=i(41432);v.exports=r},15123:(v,T,i)=>{var r=i(7398);v.exports=r},49745:(v,T,i)=>{var r=i(67221);i(67670),i(61127),i(93114),i(45975),v.exports=r},29044:(v,T,i)=>{var r=i(67447);v.exports=r},20611:(v,T,i)=>{var r=i(58811);v.exports=r},65861:(v,T,i)=>{var r=i(19573);i(55461),i(5737),i(87097),i(29559),i(90212),i(71985),i(93770),i(47743),v.exports=r},63816:(v,T,i)=>{var r=i(10226);v.exports=r},61812:(v,T,i)=>{var r=i(52208),u=i(7378),p=TypeError;v.exports=function(d){if(r(d))return d;throw p(u(d)+" is not a function")}},54356:(v,T,i)=>{var r=i(81177),u=i(7378),p=TypeError;v.exports=function(d){if(r(d))return d;throw p(u(d)+" is not a constructor")}},93221:(v,T,i)=>{var r=i(52208),u=String,p=TypeError;v.exports=function(d){if("object"==typeof d||r(d))return d;throw p("Can't set "+u(d)+" as a prototype")}},82196:v=>{v.exports=function(){}},54849:(v,T,i)=>{var r=i(23336),u=TypeError;v.exports=function(p,d){if(r(d,p))return p;throw u("Incorrect invocation")}},64562:(v,T,i)=>{var r=i(77293),u=String,p=TypeError;v.exports=function(d){if(r(d))return d;throw p(u(d)+" is not an object")}},76318:(v,T,i)=>{var r=i(55756);v.exports=r(function(){if("function"==typeof ArrayBuffer){var u=new ArrayBuffer(8);Object.isExtensible(u)&&Object.defineProperty(u,"a",{value:8})}})},35277:(v,T,i)=>{"use strict";var r=i(70267),u=i(19401),p=i(6381);v.exports=function(e){for(var _=r(this),y=p(_),S=arguments.length,A=u(S>1?arguments[1]:void 0,y),N=S>2?arguments[2]:void 0,L=void 0===N?y:u(N,y);L>A;)_[A++]=e;return _}},8366:(v,T,i)=>{"use strict";var r=i(68607).forEach,p=i(33620)("forEach");v.exports=p?[].forEach:function(e){return r(this,e,arguments.length>1?arguments[1]:void 0)}},51923:(v,T,i)=>{"use strict";var r=i(76781),u=i(25401),p=i(70267),d=i(93463),e=i(39918),_=i(81177),y=i(6381),S=i(46751),A=i(88055),N=i(34014),L=Array;v.exports=function(J){var K=p(J),ee=_(this),ue=arguments.length,ae=ue>1?arguments[1]:void 0,H=void 0!==ae;H&&(ae=r(ae,ue>2?arguments[2]:void 0));var ie,he,ge,De,ce,lt,se=N(K),Ee=0;if(!se||this===L&&e(se))for(ie=y(K),he=ee?new this(ie):L(ie);ie>Ee;Ee++)lt=H?ae(K[Ee],Ee):K[Ee],S(he,Ee,lt);else for(ce=(De=A(K,se)).next,he=ee?new this:[];!(ge=u(ce,De)).done;Ee++)lt=H?d(De,ae,[ge.value,Ee],!0):ge.value,S(he,Ee,lt);return he.length=Ee,he}},95171:(v,T,i)=>{var r=i(81010),u=i(19401),p=i(6381),d=function(e){return function(_,y,S){var Z,A=r(_),N=p(A),L=u(S,N);if(e&&y!=y){for(;N>L;)if((Z=A[L++])!=Z)return!0}else for(;N>L;L++)if((e||L in A)&&A[L]===y)return e||L||0;return!e&&-1}};v.exports={includes:d(!0),indexOf:d(!1)}},68607:(v,T,i)=>{var r=i(76781),u=i(23634),p=i(20973),d=i(70267),e=i(6381),_=i(2103),y=u([].push),S=function(A){var N=1==A,L=2==A,Z=3==A,J=4==A,K=6==A,ee=7==A,ue=5==A||K;return function(ae,H,se,Ee){for(var ze,Be,ie=d(ae),he=p(ie),ge=r(H,se),De=e(he),ce=0,lt=Ee||_,Ve=N?lt(ae,De):L||ee?lt(ae,0):void 0;De>ce;ce++)if((ue||ce in he)&&(Be=ge(ze=he[ce],ce,ie),A))if(N)Ve[ce]=Be;else if(Be)switch(A){case 3:return!0;case 5:return ze;case 6:return ce;case 2:y(Ve,ze)}else switch(A){case 4:return!1;case 7:y(Ve,ze)}return K?-1:Z||J?J:Ve}};v.exports={forEach:S(0),map:S(1),filter:S(2),some:S(3),every:S(4),find:S(5),findIndex:S(6),filterReject:S(7)}},78375:(v,T,i)=>{"use strict";var r=i(2543),u=i(81010),p=i(33912),d=i(6381),e=i(33620),_=Math.min,y=[].lastIndexOf,S=!!y&&1/[1].lastIndexOf(1,-0)<0,A=e("lastIndexOf");v.exports=S||!A?function(Z){if(S)return r(y,this,arguments)||0;var J=u(this),K=d(J),ee=K-1;for(arguments.length>1&&(ee=_(ee,p(arguments[1]))),ee<0&&(ee=K+ee);ee>=0;ee--)if(ee in J&&J[ee]===Z)return ee||0;return-1}:y},95913:(v,T,i)=>{var r=i(55756),u=i(91840),p=i(63556),d=u("species");v.exports=function(e){return p>=51||!r(function(){var _=[];return(_.constructor={})[d]=function(){return{foo:1}},1!==_[e](Boolean).foo})}},33620:(v,T,i)=>{"use strict";var r=i(55756);v.exports=function(u,p){var d=[][u];return!!d&&r(function(){d.call(null,p||function(){return 1},1)})}},88908:(v,T,i)=>{var r=i(61812),u=i(70267),p=i(20973),d=i(6381),e=TypeError,_=function(y){return function(S,A,N,L){r(A);var Z=u(S),J=p(Z),K=d(Z),ee=y?K-1:0,ue=y?-1:1;if(N<2)for(;;){if(ee in J){L=J[ee],ee+=ue;break}if(ee+=ue,y?ee<0:K<=ee)throw e("Reduce of empty array with no initial value")}for(;y?ee>=0:K>ee;ee+=ue)ee in J&&(L=A(L,J[ee],ee,Z));return L}};v.exports={left:_(!1),right:_(!0)}},54716:(v,T,i)=>{"use strict";var r=i(49642),u=i(89735),p=TypeError,d=Object.getOwnPropertyDescriptor,e=r&&!function(){if(void 0!==this)return!0;try{Object.defineProperty([],"length",{writable:!1}).length=1}catch(_){return _ instanceof TypeError}}();v.exports=e?function(_,y){if(u(_)&&!d(_,"length").writable)throw p("Cannot set read only .length");return _.length=y}:function(_,y){return _.length=y}},8681:(v,T,i)=>{var r=i(19401),u=i(6381),p=i(46751),d=Array,e=Math.max;v.exports=function(_,y,S){for(var A=u(_),N=r(y,A),L=r(void 0===S?A:S,A),Z=d(e(L-N,0)),J=0;N<L;N++,J++)p(Z,J,_[N]);return Z.length=J,Z}},37591:(v,T,i)=>{var r=i(23634);v.exports=r([].slice)},84865:(v,T,i)=>{var r=i(8681),u=Math.floor,p=function(_,y){var S=_.length,A=u(S/2);return S<8?d(_,y):e(_,p(r(_,0,A),y),p(r(_,A),y),y)},d=function(_,y){for(var N,L,S=_.length,A=1;A<S;){for(L=A,N=_[A];L&&y(_[L-1],N)>0;)_[L]=_[--L];L!==A++&&(_[L]=N)}return _},e=function(_,y,S,A){for(var N=y.length,L=S.length,Z=0,J=0;Z<N||J<L;)_[Z+J]=Z<N&&J<L?A(y[Z],S[J])<=0?y[Z++]:S[J++]:Z<N?y[Z++]:S[J++];return _};v.exports=p},48045:(v,T,i)=>{var r=i(89735),u=i(81177),p=i(77293),e=i(91840)("species"),_=Array;v.exports=function(y){var S;return r(y)&&(u(S=y.constructor)&&(S===_||r(S.prototype))||p(S)&&null===(S=S[e]))&&(S=void 0),void 0===S?_:S}},2103:(v,T,i)=>{var r=i(48045);v.exports=function(u,p){return new(r(u))(0===p?0:p)}},93463:(v,T,i)=>{var r=i(64562),u=i(40798);v.exports=function(p,d,e,_){try{return _?d(r(e)[0],e[1]):d(e)}catch(y){u(p,"throw",y)}}},5253:(v,T,i)=>{var u=i(91840)("iterator"),p=!1;try{var d=0,e={next:function(){return{done:!!d++}},return:function(){p=!0}};e[u]=function(){return this},Array.from(e,function(){throw 2})}catch(_){}v.exports=function(_,y){if(!y&&!p)return!1;var S=!1;try{var A={};A[u]=function(){return{next:function(){return{done:S=!0}}}},_(A)}catch(N){}return S}},49806:(v,T,i)=>{var r=i(23634),u=r({}.toString),p=r("".slice);v.exports=function(d){return p(u(d),8,-1)}},35329:(v,T,i)=>{var r=i(25014),u=i(52208),p=i(49806),e=i(91840)("toStringTag"),_=Object,y="Arguments"==p(function(){return arguments}());v.exports=r?p:function(A){var N,L,Z;return void 0===A?"Undefined":null===A?"Null":"string"==typeof(L=function(A,N){try{return A[N]}catch(L){}}(N=_(A),e))?L:y?p(N):"Object"==(Z=p(N))&&u(N.callee)?"Arguments":Z}},37353:(v,T,i)=>{"use strict";var r=i(25401),u=i(61812),p=i(64562);v.exports=function(){for(var S,e=p(this),_=u(e.delete),y=!0,A=0,N=arguments.length;A<N;A++)S=r(_,e,arguments[A]),y=y&&S;return!!y}},83483:(v,T,i)=>{"use strict";var r=i(76781),u=i(25401),p=i(61812),d=i(54356),e=i(43550),_=i(41605),y=[].push;v.exports=function(A){var Z,J,K,ee,N=arguments.length,L=N>1?arguments[1]:void 0;return d(this),(Z=void 0!==L)&&p(L),e(A)?new this:(J=[],Z?(K=0,ee=r(L,N>2?arguments[2]:void 0),_(A,function(ue){u(y,J,ee(ue,K++))})):_(A,y,{that:J}),new this(J))}},13067:(v,T,i)=>{"use strict";var r=i(37591);v.exports=function(){return new this(r(arguments))}},26650:(v,T,i)=>{"use strict";var r=i(48011).f,u=i(83272),p=i(84604),d=i(76781),e=i(54849),_=i(43550),y=i(41605),S=i(79077),A=i(28738),N=i(58014),L=i(49642),Z=i(57867).fastKey,J=i(91093),K=J.set,ee=J.getterFor;v.exports={getConstructor:function(ue,ae,H,se){var Ee=ue(function(ce,lt){e(ce,ie),K(ce,{type:ae,index:u(null),first:void 0,last:void 0,size:0}),L||(ce.size=0),_(lt)||y(lt,ce[se],{that:ce,AS_ENTRIES:H})}),ie=Ee.prototype,he=ee(ae),ge=function(ce,lt,Ve){var Pe,je,ze=he(ce),Be=De(ce,lt);return Be?Be.value=Ve:(ze.last=Be={index:je=Z(lt,!0),key:lt,value:Ve,previous:Pe=ze.last,next:void 0,removed:!1},ze.first||(ze.first=Be),Pe&&(Pe.next=Be),L?ze.size++:ce.size++,"F"!==je&&(ze.index[je]=Be)),ce},De=function(ce,lt){var Be,Ve=he(ce),ze=Z(lt);if("F"!==ze)return Ve.index[ze];for(Be=Ve.first;Be;Be=Be.next)if(Be.key==lt)return Be};return p(ie,{clear:function(){for(var Ve=he(this),ze=Ve.index,Be=Ve.first;Be;)Be.removed=!0,Be.previous&&(Be.previous=Be.previous.next=void 0),delete ze[Be.index],Be=Be.next;Ve.first=Ve.last=void 0,L?Ve.size=0:this.size=0},delete:function(ce){var Ve=he(this),ze=De(this,ce);if(ze){var Be=ze.next,Pe=ze.previous;delete Ve.index[ze.index],ze.removed=!0,Pe&&(Pe.next=Be),Be&&(Be.previous=Pe),Ve.first==ze&&(Ve.first=Be),Ve.last==ze&&(Ve.last=Pe),L?Ve.size--:this.size--}return!!ze},forEach:function(lt){for(var Be,Ve=he(this),ze=d(lt,arguments.length>1?arguments[1]:void 0);Be=Be?Be.next:Ve.first;)for(ze(Be.value,Be.key,this);Be&&Be.removed;)Be=Be.previous},has:function(lt){return!!De(this,lt)}}),p(ie,H?{get:function(lt){var Ve=De(this,lt);return Ve&&Ve.value},set:function(lt,Ve){return ge(this,0===lt?0:lt,Ve)}}:{add:function(lt){return ge(this,lt=0===lt?0:lt,lt)}}),L&&r(ie,"size",{get:function(){return he(this).size}}),Ee},setStrong:function(ue,ae,H){var se=ae+" Iterator",Ee=ee(ae),ie=ee(se);S(ue,ae,function(he,ge){K(this,{type:se,target:he,state:Ee(he),kind:ge,last:void 0})},function(){for(var he=ie(this),ge=he.kind,De=he.last;De&&De.removed;)De=De.previous;return he.target&&(he.last=De=De?De.next:he.state.first)?A("keys"==ge?De.key:"values"==ge?De.value:[De.key,De.value],!1):(he.target=void 0,A(void 0,!0))},H?"entries":"values",!H,!0),N(ae)}}},84049:(v,T,i)=>{"use strict";var r=i(23634),u=i(84604),p=i(57867).getWeakData,d=i(54849),e=i(64562),_=i(43550),y=i(77293),S=i(41605),A=i(68607),N=i(80112),L=i(91093),Z=L.set,J=L.getterFor,K=A.find,ee=A.findIndex,ue=r([].splice),ae=0,H=function(ie){return ie.frozen||(ie.frozen=new se)},se=function(){this.entries=[]},Ee=function(ie,he){return K(ie.entries,function(ge){return ge[0]===he})};se.prototype={get:function(ie){var he=Ee(this,ie);if(he)return he[1]},has:function(ie){return!!Ee(this,ie)},set:function(ie,he){var ge=Ee(this,ie);ge?ge[1]=he:this.entries.push([ie,he])},delete:function(ie){var he=ee(this.entries,function(ge){return ge[0]===ie});return~he&&ue(this.entries,he,1),!!~he}},v.exports={getConstructor:function(ie,he,ge,De){var ce=ie(function(Be,Pe){d(Be,lt),Z(Be,{type:he,id:ae++,frozen:void 0}),_(Pe)||S(Pe,Be[De],{that:Be,AS_ENTRIES:ge})}),lt=ce.prototype,Ve=J(he),ze=function(Be,Pe,je){var He=Ve(Be),Vt=p(e(Pe),!0);return!0===Vt?H(He).set(Pe,je):Vt[He.id]=je,Be};return u(lt,{delete:function(Be){var Pe=Ve(this);if(!y(Be))return!1;var je=p(Be);return!0===je?H(Pe).delete(Be):je&&N(je,Pe.id)&&delete je[Pe.id]},has:function(Pe){var je=Ve(this);if(!y(Pe))return!1;var He=p(Pe);return!0===He?H(je).has(Pe):He&&N(He,je.id)}}),u(lt,ge?{get:function(Pe){var je=Ve(this);if(y(Pe)){var He=p(Pe);return!0===He?H(je).get(Pe):He?He[je.id]:void 0}},set:function(Pe,je){return ze(this,Pe,je)}}:{add:function(Pe){return ze(this,Pe,!0)}}),ce}}},85116:(v,T,i)=>{"use strict";var r=i(90513),u=i(70009),p=i(57867),d=i(55756),e=i(65162),_=i(41605),y=i(54849),S=i(52208),A=i(77293),N=i(85681),L=i(48011).f,Z=i(68607).forEach,J=i(49642),K=i(91093),ee=K.set,ue=K.getterFor;v.exports=function(ae,H,se){var lt,Ee=-1!==ae.indexOf("Map"),ie=-1!==ae.indexOf("Weak"),he=Ee?"set":"add",ge=u[ae],De=ge&&ge.prototype,ce={};if(J&&S(ge)&&(ie||De.forEach&&!d(function(){(new ge).entries().next()}))){var Ve=(lt=H(function(Be,Pe){ee(y(Be,Ve),{type:ae,collection:new ge}),null!=Pe&&_(Pe,Be[he],{that:Be,AS_ENTRIES:Ee})})).prototype,ze=ue(ae);Z(["add","clear","delete","forEach","get","has","set","keys","values","entries"],function(Be){var Pe="add"==Be||"set"==Be;Be in De&&(!ie||"clear"!=Be)&&e(Ve,Be,function(je,He){var Vt=ze(this).collection;if(!Pe&&ie&&!A(je))return"get"==Be&&void 0;var it=Vt[Be](0===je?0:je,He);return Pe?this:it})}),ie||L(Ve,"size",{configurable:!0,get:function(){return ze(this).collection.size}})}else lt=se.getConstructor(H,ae,Ee,he),p.enable();return N(lt,ae,!1,!0),ce[ae]=lt,r({global:!0,forced:!0},ce),ie||se.setStrong(lt,ae,Ee),lt}},65031:(v,T,i)=>{var r=i(80112),u=i(59823),p=i(25525),d=i(48011);v.exports=function(e,_,y){for(var S=u(_),A=d.f,N=p.f,L=0;L<S.length;L++){var Z=S[L];!r(e,Z)&&(!y||!r(y,Z))&&A(e,Z,N(_,Z))}}},79668:(v,T,i)=>{var u=i(91840)("match");v.exports=function(p){var d=/./;try{"/./"[p](d)}catch(e){try{return d[u]=!1,"/./"[p](d)}catch(_){}}return!1}},37112:(v,T,i)=>{var r=i(55756);v.exports=!r(function(){function u(){}return u.prototype.constructor=null,Object.getPrototypeOf(new u)!==u.prototype})},28738:v=>{v.exports=function(T,i){return{value:T,done:i}}},65162:(v,T,i)=>{var r=i(49642),u=i(48011),p=i(51361);v.exports=r?function(d,e,_){return u.f(d,e,p(1,_))}:function(d,e,_){return d[e]=_,d}},51361:v=>{v.exports=function(T,i){return{enumerable:!(1&T),configurable:!(2&T),writable:!(4&T),value:i}}},46751:(v,T,i)=>{"use strict";var r=i(62939),u=i(48011),p=i(51361);v.exports=function(d,e,_){var y=r(e);y in d?u.f(d,y,p(0,_)):d[y]=_}},1707:(v,T,i)=>{var r=i(48011);v.exports=function(u,p,d){return r.f(u,p,d)}},42915:(v,T,i)=>{var r=i(65162);v.exports=function(u,p,d,e){return e&&e.enumerable?u[p]=d:r(u,p,d),u}},84604:(v,T,i)=>{var r=i(42915);v.exports=function(u,p,d){for(var e in p)d&&d.unsafe&&u[e]?u[e]=p[e]:r(u,e,p[e],d);return u}},34056:(v,T,i)=>{var r=i(70009),u=Object.defineProperty;v.exports=function(p,d){try{u(r,p,{value:d,configurable:!0,writable:!0})}catch(e){r[p]=d}return d}},67236:(v,T,i)=>{"use strict";var r=i(7378),u=TypeError;v.exports=function(p,d){if(!delete p[d])throw u("Cannot delete property "+r(d)+" of "+r(p))}},49642:(v,T,i)=>{var r=i(55756);v.exports=!r(function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]})},96682:(v,T,i)=>{var r=i(70009),u=i(77293),p=r.document,d=u(p)&&u(p.createElement);v.exports=function(e){return d?p.createElement(e):{}}},11594:v=>{var T=TypeError;v.exports=function(r){if(r>9007199254740991)throw T("Maximum allowed index exceeded");return r}},44125:v=>{v.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},36410:(v,T,i)=>{var u=i(86053).match(/firefox\/(\d+)/i);v.exports=!!u&&+u[1]},34008:(v,T,i)=>{var r=i(31813),u=i(3787);v.exports=!r&&!u&&"object"==typeof window&&"object"==typeof document},31813:v=>{v.exports="object"==typeof Deno&&Deno&&"object"==typeof Deno.version},5329:(v,T,i)=>{var r=i(86053);v.exports=/MSIE|Trident/.test(r)},16137:(v,T,i)=>{var r=i(86053),u=i(70009);v.exports=/ipad|iphone|ipod/i.test(r)&&void 0!==u.Pebble},3877:(v,T,i)=>{var r=i(86053);v.exports=/(?:ipad|iphone|ipod).*applewebkit/i.test(r)},3787:(v,T,i)=>{var r=i(49806),u=i(70009);v.exports="process"==r(u.process)},85308:(v,T,i)=>{var r=i(86053);v.exports=/web0s(?!.*chrome)/i.test(r)},86053:(v,T,i)=>{var r=i(7365);v.exports=r("navigator","userAgent")||""},63556:(v,T,i)=>{var y,S,r=i(70009),u=i(86053),p=r.process,d=r.Deno,e=p&&p.versions||d&&d.version,_=e&&e.v8;_&&(S=(y=_.split("."))[0]>0&&y[0]<4?1:+(y[0]+y[1])),!S&&u&&(!(y=u.match(/Edge\/(\d+)/))||y[1]>=74)&&(y=u.match(/Chrome\/(\d+)/))&&(S=+y[1]),v.exports=S},34545:(v,T,i)=>{var u=i(86053).match(/AppleWebKit\/(\d+)\./);v.exports=!!u&&+u[1]},97911:(v,T,i)=>{var r=i(13544);v.exports=function(u){return r[u+"Prototype"]}},44939:v=>{v.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},40039:(v,T,i)=>{var r=i(23634),u=Error,p=r("".replace),d=String(u("zxcasd").stack),e=/\n\s*at [^:]*:[^\n]*/,_=e.test(d);v.exports=function(y,S){if(_&&"string"==typeof y&&!u.prepareStackTrace)for(;S--;)y=p(y,e,"");return y}},50499:(v,T,i)=>{var r=i(55756),u=i(51361);v.exports=!r(function(){var p=Error("a");return!("stack"in p)||(Object.defineProperty(p,"stack",u(1,7)),7!==p.stack)})},90513:(v,T,i)=>{"use strict";var r=i(70009),u=i(2543),p=i(23634),d=i(52208),e=i(25525).f,_=i(79482),y=i(13544),S=i(76781),A=i(65162),N=i(80112),L=function(Z){var J=function(K,ee,ue){if(this instanceof J){switch(arguments.length){case 0:return new Z;case 1:return new Z(K);case 2:return new Z(K,ee)}return new Z(K,ee,ue)}return u(Z,this,arguments)};return J.prototype=Z.prototype,J};v.exports=function(Z,J){var he,ge,De,ce,lt,Ve,ze,Be,K=Z.target,ee=Z.global,ue=Z.stat,ae=Z.proto,H=ee?r:ue?r[K]:(r[K]||{}).prototype,se=ee?y:y[K]||A(y,K,{})[K],Ee=se.prototype;for(De in J)he=!_(ee?De:K+(ue?".":"#")+De,Z.forced)&&H&&N(H,De),lt=se[De],he&&(Ve=Z.dontCallGetSet?(Be=e(H,De))&&Be.value:H[De]),ce=he&&Ve?Ve:J[De],(!he||typeof lt!=typeof ce)&&(ze=Z.bind&&he?S(ce,r):Z.wrap&&he?L(ce):ae&&d(ce)?p(ce):ce,(Z.sham||ce&&ce.sham||lt&&lt.sham)&&A(ze,"sham",!0),A(se,De,ze),ae&&(N(y,ge=K+"Prototype")||A(y,ge,{}),A(y[ge],De,ce),Z.real&&Ee&&!Ee[De]&&A(Ee,De,ce)))}},55756:v=>{v.exports=function(T){try{return!!T()}catch(i){return!0}}},3124:(v,T,i)=>{var r=i(55756);v.exports=!r(function(){return Object.isExtensible(Object.preventExtensions({}))})},2543:(v,T,i)=>{var r=i(29046),u=Function.prototype,p=u.apply,d=u.call;v.exports="object"==typeof Reflect&&Reflect.apply||(r?d.bind(p):function(){return d.apply(p,arguments)})},76781:(v,T,i)=>{var r=i(23634),u=i(61812),p=i(29046),d=r(r.bind);v.exports=function(e,_){return u(e),void 0===_?e:p?d(e,_):function(){return e.apply(_,arguments)}}},29046:(v,T,i)=>{var r=i(55756);v.exports=!r(function(){var u=function(){}.bind();return"function"!=typeof u||u.hasOwnProperty("prototype")})},44197:(v,T,i)=>{"use strict";var r=i(23634),u=i(61812),p=i(77293),d=i(80112),e=i(37591),_=i(29046),y=Function,S=r([].concat),A=r([].join),N={},L=function(Z,J,K){if(!d(N,J)){for(var ee=[],ue=0;ue<J;ue++)ee[ue]="a["+ue+"]";N[J]=y("C,a","return new C("+A(ee,",")+")")}return N[J](Z,K)};v.exports=_?y.bind:function(J){var K=u(this),ee=K.prototype,ue=e(arguments,1),ae=function(){var se=S(ue,e(arguments));return this instanceof ae?L(K,se.length,se):K.apply(J,se)};return p(ee)&&(ae.prototype=ee),ae}},25401:(v,T,i)=>{var r=i(29046),u=Function.prototype.call;v.exports=r?u.bind(u):function(){return u.apply(u,arguments)}},29862:(v,T,i)=>{var r=i(49642),u=i(80112),p=Function.prototype,d=r&&Object.getOwnPropertyDescriptor,e=u(p,"name"),_=e&&"something"===function(){}.name,y=e&&(!r||r&&d(p,"name").configurable);v.exports={EXISTS:e,PROPER:_,CONFIGURABLE:y}},23634:(v,T,i)=>{var r=i(29046),u=Function.prototype,d=u.call,e=r&&u.bind.bind(d,d);v.exports=r?function(_){return _&&e(_)}:function(_){return _&&function(){return d.apply(_,arguments)}}},7365:(v,T,i)=>{var r=i(13544),u=i(70009),p=i(52208),d=function(e){return p(e)?e:void 0};v.exports=function(e,_){return arguments.length<2?d(r[e])||d(u[e]):r[e]&&r[e][_]||u[e]&&u[e][_]}},34014:(v,T,i)=>{var r=i(35329),u=i(34778),p=i(43550),d=i(84394),_=i(91840)("iterator");v.exports=function(y){if(!p(y))return u(y,_)||u(y,"@@iterator")||d[r(y)]}},88055:(v,T,i)=>{var r=i(25401),u=i(61812),p=i(64562),d=i(7378),e=i(34014),_=TypeError;v.exports=function(y,S){var A=arguments.length<2?e(y):S;if(u(A))return p(r(A,y));throw _(d(y)+" is not iterable")}},37444:(v,T,i)=>{var r=i(88055);v.exports=r},34778:(v,T,i)=>{var r=i(61812),u=i(43550);v.exports=function(p,d){var e=p[d];return u(e)?void 0:r(e)}},70009:v=>{var T=function(i){return i&&i.Math==Math&&i};v.exports=T("object"==typeof globalThis&&globalThis)||T("object"==typeof window&&window)||T("object"==typeof self&&self)||T("object"==typeof global&&global)||function(){return this}()||Function("return this")()},80112:(v,T,i)=>{var r=i(23634),u=i(70267),p=r({}.hasOwnProperty);v.exports=Object.hasOwn||function(e,_){return p(u(e),_)}},45599:v=>{v.exports={}},52912:(v,T,i)=>{var r=i(70009);v.exports=function(u,p){var d=r.console;d&&d.error&&(1==arguments.length?d.error(u):d.error(u,p))}},55690:(v,T,i)=>{var r=i(7365);v.exports=r("document","documentElement")},50495:(v,T,i)=>{var r=i(49642),u=i(55756),p=i(96682);v.exports=!r&&!u(function(){return 7!=Object.defineProperty(p("div"),"a",{get:function(){return 7}}).a})},20973:(v,T,i)=>{var r=i(23634),u=i(55756),p=i(49806),d=Object,e=r("".split);v.exports=u(function(){return!d("z").propertyIsEnumerable(0)})?function(_){return"String"==p(_)?e(_,""):d(_)}:d},26699:(v,T,i)=>{var r=i(23634),u=i(52208),p=i(24766),d=r(Function.toString);u(p.inspectSource)||(p.inspectSource=function(e){return d(e)}),v.exports=p.inspectSource},33411:(v,T,i)=>{var r=i(77293),u=i(65162);v.exports=function(p,d){r(d)&&"cause"in d&&u(p,"cause",d.cause)}},57867:(v,T,i)=>{var r=i(90513),u=i(23634),p=i(45599),d=i(77293),e=i(80112),_=i(48011).f,y=i(51518),S=i(62469),A=i(46401),N=i(13708),L=i(3124),Z=!1,J=N("meta"),K=0,ee=function(ie){_(ie,J,{value:{objectID:"O"+K++,weakData:{}}})},Ee=v.exports={enable:function(){Ee.enable=function(){},Z=!0;var ie=y.f,he=u([].splice),ge={};ge[J]=1,ie(ge).length&&(y.f=function(De){for(var ce=ie(De),lt=0,Ve=ce.length;lt<Ve;lt++)if(ce[lt]===J){he(ce,lt,1);break}return ce},r({target:"Object",stat:!0,forced:!0},{getOwnPropertyNames:S.f}))},fastKey:function(ie,he){if(!d(ie))return"symbol"==typeof ie?ie:("string"==typeof ie?"S":"P")+ie;if(!e(ie,J)){if(!A(ie))return"F";if(!he)return"E";ee(ie)}return ie[J].objectID},getWeakData:function(ie,he){if(!e(ie,J)){if(!A(ie))return!0;if(!he)return!1;ee(ie)}return ie[J].weakData},onFreeze:function(ie){return L&&Z&&A(ie)&&!e(ie,J)&&ee(ie),ie}};p[J]=!0},91093:(v,T,i)=>{var J,K,ee,r=i(81101),u=i(70009),p=i(23634),d=i(77293),e=i(65162),_=i(80112),y=i(24766),S=i(86066),A=i(45599),N="Object already initialized",L=u.TypeError;if(r||y.state){var H=y.state||(y.state=new(0,u.WeakMap)),se=p(H.get),Ee=p(H.has),ie=p(H.set);J=function(ge,De){if(Ee(H,ge))throw L(N);return De.facade=ge,ie(H,ge,De),De},K=function(ge){return se(H,ge)||{}},ee=function(ge){return Ee(H,ge)}}else{var he=S("state");A[he]=!0,J=function(ge,De){if(_(ge,he))throw L(N);return De.facade=ge,e(ge,he,De),De},K=function(ge){return _(ge,he)?ge[he]:{}},ee=function(ge){return _(ge,he)}}v.exports={set:J,get:K,has:ee,enforce:function(ge){return ee(ge)?K(ge):J(ge,{})},getterFor:function(ge){return function(De){var ce;if(!d(De)||(ce=K(De)).type!==ge)throw L("Incompatible receiver, "+ge+" required");return ce}}}},39918:(v,T,i)=>{var r=i(91840),u=i(84394),p=r("iterator"),d=Array.prototype;v.exports=function(e){return void 0!==e&&(u.Array===e||d[p]===e)}},89735:(v,T,i)=>{var r=i(49806);v.exports=Array.isArray||function(p){return"Array"==r(p)}},52208:v=>{v.exports=function(T){return"function"==typeof T}},81177:(v,T,i)=>{var r=i(23634),u=i(55756),p=i(52208),d=i(35329),e=i(7365),_=i(26699),y=function(){},S=[],A=e("Reflect","construct"),N=/^\s*(?:class|function)\b/,L=r(N.exec),Z=!N.exec(y),J=function(ue){if(!p(ue))return!1;try{return A(y,S,ue),!0}catch(ae){return!1}},K=function(ue){if(!p(ue))return!1;switch(d(ue)){case"AsyncFunction":case"GeneratorFunction":case"AsyncGeneratorFunction":return!1}try{return Z||!!L(N,_(ue))}catch(ae){return!0}};K.sham=!0,v.exports=!A||u(function(){var ee;return J(J.call)||!J(Object)||!J(function(){ee=!0})||ee})?K:J},27029:(v,T,i)=>{var r=i(80112);v.exports=function(u){return void 0!==u&&(r(u,"value")||r(u,"writable"))}},79482:(v,T,i)=>{var r=i(55756),u=i(52208),p=/#|\.prototype\./,d=function(A,N){var L=_[e(A)];return L==S||L!=y&&(u(N)?r(N):!!N)},e=d.normalize=function(A){return String(A).replace(p,".").toLowerCase()},_=d.data={},y=d.NATIVE="N",S=d.POLYFILL="P";v.exports=d},43550:v=>{v.exports=function(T){return null==T}},77293:(v,T,i)=>{var r=i(52208),u="object"==typeof document&&document.all;v.exports=void 0===u&&void 0!==u?function(d){return"object"==typeof d?null!==d:r(d)||d===u}:function(d){return"object"==typeof d?null!==d:r(d)}},81124:v=>{v.exports=!0},60373:(v,T,i)=>{var r=i(77293),u=i(49806),d=i(91840)("match");v.exports=function(e){var _;return r(e)&&(void 0!==(_=e[d])?!!_:"RegExp"==u(e))}},74717:(v,T,i)=>{var r=i(7365),u=i(52208),p=i(23336),d=i(99554),e=Object;v.exports=d?function(_){return"symbol"==typeof _}:function(_){var y=r("Symbol");return u(y)&&p(y.prototype,e(_))}},41605:(v,T,i)=>{var r=i(76781),u=i(25401),p=i(64562),d=i(7378),e=i(39918),_=i(6381),y=i(23336),S=i(88055),A=i(34014),N=i(40798),L=TypeError,Z=function(K,ee){this.stopped=K,this.result=ee},J=Z.prototype;v.exports=function(K,ee,ue){var ge,De,ce,lt,Ve,ze,Be,H=!(!ue||!ue.AS_ENTRIES),se=!(!ue||!ue.IS_RECORD),Ee=!(!ue||!ue.IS_ITERATOR),ie=!(!ue||!ue.INTERRUPTED),he=r(ee,ue&&ue.that),Pe=function(He){return ge&&N(ge,"normal",He),new Z(!0,He)},je=function(He){return H?(p(He),ie?he(He[0],He[1],Pe):he(He[0],He[1])):ie?he(He,Pe):he(He)};if(se)ge=K.iterator;else if(Ee)ge=K;else{if(!(De=A(K)))throw L(d(K)+" is not iterable");if(e(De)){for(ce=0,lt=_(K);lt>ce;ce++)if((Ve=je(K[ce]))&&y(J,Ve))return Ve;return new Z(!1)}ge=S(K,De)}for(ze=se?K.next:ge.next;!(Be=u(ze,ge)).done;){try{Ve=je(Be.value)}catch(He){N(ge,"throw",He)}if("object"==typeof Ve&&Ve&&y(J,Ve))return Ve}return new Z(!1)}},40798:(v,T,i)=>{var r=i(25401),u=i(64562),p=i(34778);v.exports=function(d,e,_){var y,S;u(d);try{if(!(y=p(d,"return"))){if("throw"===e)throw _;return _}y=r(y,d)}catch(A){S=!0,y=A}if("throw"===e)throw _;if(S)throw y;return u(y),_}},14554:(v,T,i)=>{"use strict";var r=i(38432).IteratorPrototype,u=i(83272),p=i(51361),d=i(85681),e=i(84394),_=function(){return this};v.exports=function(y,S,A,N){var L=S+" Iterator";return y.prototype=u(r,{next:p(+!N,A)}),d(y,L,!1,!0),e[L]=_,y}},79077:(v,T,i)=>{"use strict";var r=i(90513),u=i(25401),p=i(81124),d=i(29862),e=i(52208),_=i(14554),y=i(31426),S=i(54945),A=i(85681),N=i(65162),L=i(42915),Z=i(91840),J=i(84394),K=i(38432),ee=d.PROPER,ue=d.CONFIGURABLE,ae=K.IteratorPrototype,H=K.BUGGY_SAFARI_ITERATORS,se=Z("iterator"),ie="values",he="entries",ge=function(){return this};v.exports=function(De,ce,lt,Ve,ze,Be,Pe){_(lt,ce,Ve);var Ut,Bt,bt,je=function(Gt){if(Gt===ze&&It)return It;if(!H&&Gt in it)return it[Gt];switch(Gt){case"keys":case ie:case he:return function(){return new lt(this,Gt)}}return function(){return new lt(this)}},He=ce+" Iterator",Vt=!1,it=De.prototype,tn=it[se]||it["@@iterator"]||ze&&it[ze],It=!H&&tn||je(ze),Zt="Array"==ce&&it.entries||tn;if(Zt&&(Ut=y(Zt.call(new De)))!==Object.prototype&&Ut.next&&(!p&&y(Ut)!==ae&&(S?S(Ut,ae):e(Ut[se])||L(Ut,se,ge)),A(Ut,He,!0,!0),p&&(J[He]=ge)),ee&&ze==ie&&tn&&tn.name!==ie&&(!p&&ue?N(it,"name",ie):(Vt=!0,It=function(){return u(tn,this)})),ze)if(Bt={values:je(ie),keys:Be?It:je("keys"),entries:je(he)},Pe)for(bt in Bt)(H||Vt||!(bt in it))&&L(it,bt,Bt[bt]);else r({target:ce,proto:!0,forced:H||Vt},Bt);return(!p||Pe)&&it[se]!==It&&L(it,se,It,{name:ze}),J[ce]=It,Bt}},38432:(v,T,i)=>{"use strict";var L,Z,J,r=i(55756),u=i(52208),p=i(77293),d=i(83272),e=i(31426),_=i(42915),y=i(91840),S=i(81124),A=y("iterator"),N=!1;[].keys&&("next"in(J=[].keys())?(Z=e(e(J)))!==Object.prototype&&(L=Z):N=!0),!p(L)||r(function(){var ee={};return L[A].call(ee)!==ee})?L={}:S&&(L=d(L)),u(L[A])||_(L,A,function(){return this}),v.exports={IteratorPrototype:L,BUGGY_SAFARI_ITERATORS:N}},84394:v=>{v.exports={}},6381:(v,T,i)=>{var r=i(48869);v.exports=function(u){return r(u.length)}},12864:(v,T,i)=>{"use strict";var r=i(25401),u=i(61812),p=i(64562);v.exports=function(e,_){var L,Z,y=p(this),S=u(y.get),A=u(y.has),N=u(y.set);return r(A,y,e)?(L=r(S,y,e),"update"in _&&(L=_.update(L,e,y),r(N,y,e,L)),L):(Z=_.insert(e,y),r(N,y,e,Z),Z)}},57729:(v,T,i)=>{"use strict";var r=i(25401),u=i(61812),p=i(52208),d=i(64562),e=TypeError;v.exports=function(y,S){var K,A=d(this),N=u(A.get),L=u(A.has),Z=u(A.set),J=arguments.length>2?arguments[2]:void 0;if(!p(S)&&!p(J))throw e("At least one callback required");return r(L,A,y)?(K=r(N,A,y),p(S)&&(K=S(K),r(Z,A,y,K))):p(J)&&(K=J(),r(Z,A,y,K)),K}},8651:v=>{var T=Math.ceil,i=Math.floor;v.exports=Math.trunc||function(u){var p=+u;return(p>0?i:T)(p)}},58991:(v,T,i)=>{var ee,ue,ae,H,se,Ee,ie,he,r=i(70009),u=i(76781),p=i(25525).f,d=i(37352).set,e=i(3877),_=i(16137),y=i(85308),S=i(3787),A=r.MutationObserver||r.WebKitMutationObserver,N=r.document,L=r.process,Z=r.Promise,J=p(r,"queueMicrotask"),K=J&&J.value;K||(ee=function(){var ge,De;for(S&&(ge=L.domain)&&ge.exit();ue;){De=ue.fn,ue=ue.next;try{De()}catch(ce){throw ue?H():ae=void 0,ce}}ae=void 0,ge&&ge.enter()},e||S||y||!A||!N?!_&&Z&&Z.resolve?((ie=Z.resolve(void 0)).constructor=Z,he=u(ie.then,ie),H=function(){he(ee)}):S?H=function(){L.nextTick(ee)}:(d=u(d,r),H=function(){d(ee)}):(se=!0,Ee=N.createTextNode(""),new A(ee).observe(Ee,{characterData:!0}),H=function(){Ee.data=se=!se})),v.exports=K||function(ge){var De={fn:ge,next:void 0};ae&&(ae.next=De),ue||(ue=De,H()),ae=De}},54256:(v,T,i)=>{"use strict";var r=i(61812),u=TypeError,p=function(d){var e,_;this.promise=new d(function(y,S){if(void 0!==e||void 0!==_)throw u("Bad Promise constructor");e=y,_=S}),this.resolve=r(e),this.reject=r(_)};v.exports.f=function(d){return new p(d)}},63313:(v,T,i)=>{var r=i(41433);v.exports=function(u,p){return void 0===u?arguments.length<2?"":p:r(u)}},56421:(v,T,i)=>{var r=i(60373),u=TypeError;v.exports=function(p){if(r(p))throw u("The method doesn't accept regular expressions");return p}},75791:(v,T,i)=>{"use strict";var r=i(49642),u=i(23634),p=i(25401),d=i(55756),e=i(28474),_=i(47238),y=i(25558),S=i(70267),A=i(20973),N=Object.assign,L=Object.defineProperty,Z=u([].concat);v.exports=!N||d(function(){if(r&&1!==N({b:1},N(L({},"a",{enumerable:!0,get:function(){L(this,"b",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var J={},K={},ee=Symbol(),ue="abcdefghijklmnopqrst";return J[ee]=7,ue.split("").forEach(function(ae){K[ae]=ae}),7!=N({},J)[ee]||e(N({},K)).join("")!=ue})?function(K,ee){for(var ue=S(K),ae=arguments.length,H=1,se=_.f,Ee=y.f;ae>H;)for(var ce,ie=A(arguments[H++]),he=se?Z(e(ie),se(ie)):e(ie),ge=he.length,De=0;ge>De;)ce=he[De++],(!r||p(Ee,ie,ce))&&(ue[ce]=ie[ce]);return ue}:N},83272:(v,T,i)=>{var ae,r=i(64562),u=i(25913),p=i(44939),d=i(45599),e=i(55690),_=i(96682),y=i(86066),N="prototype",L="script",Z=y("IE_PROTO"),J=function(){},K=function(se){return"<"+L+">"+se+"</"+L+">"},ee=function(se){se.write(K("")),se.close();var Ee=se.parentWindow.Object;return se=null,Ee},H=function(){try{ae=new ActiveXObject("htmlfile")}catch(Ee){}H="undefined"!=typeof document?document.domain&&ae?ee(ae):function(){var ie,se=_("iframe");return se.style.display="none",e.appendChild(se),se.src=String("javascript:"),(ie=se.contentWindow.document).open(),ie.write(K("document.F=Object")),ie.close(),ie.F}():ee(ae);for(var se=p.length;se--;)delete H[N][p[se]];return H()};d[Z]=!0,v.exports=Object.create||function(Ee,ie){var he;return null!==Ee?(J[N]=r(Ee),he=new J,J[N]=null,he[Z]=Ee):he=H(),void 0===ie?he:u.f(he,ie)}},25913:(v,T,i)=>{var r=i(49642),u=i(47960),p=i(48011),d=i(64562),e=i(81010),_=i(28474);T.f=r&&!u?Object.defineProperties:function(S,A){d(S);for(var K,N=e(A),L=_(A),Z=L.length,J=0;Z>J;)p.f(S,K=L[J++],N[K]);return S}},48011:(v,T,i)=>{var r=i(49642),u=i(50495),p=i(47960),d=i(64562),e=i(62939),_=TypeError,y=Object.defineProperty,S=Object.getOwnPropertyDescriptor,A="enumerable",N="configurable",L="writable";T.f=r?p?function(J,K,ee){if(d(J),K=e(K),d(ee),"function"==typeof J&&"prototype"===K&&"value"in ee&&L in ee&&!ee[L]){var ue=S(J,K);ue&&ue[L]&&(J[K]=ee.value,ee={configurable:N in ee?ee[N]:ue[N],enumerable:A in ee?ee[A]:ue[A],writable:!1})}return y(J,K,ee)}:y:function(J,K,ee){if(d(J),K=e(K),d(ee),u)try{return y(J,K,ee)}catch(ue){}if("get"in ee||"set"in ee)throw _("Accessors not supported");return"value"in ee&&(J[K]=ee.value),J}},25525:(v,T,i)=>{var r=i(49642),u=i(25401),p=i(25558),d=i(51361),e=i(81010),_=i(62939),y=i(80112),S=i(50495),A=Object.getOwnPropertyDescriptor;T.f=r?A:function(L,Z){if(L=e(L),Z=_(Z),S)try{return A(L,Z)}catch(J){}if(y(L,Z))return d(!u(p.f,L,Z),L[Z])}},62469:(v,T,i)=>{var r=i(49806),u=i(81010),p=i(51518).f,d=i(8681),e="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];v.exports.f=function(S){return e&&"Window"==r(S)?function(y){try{return p(y)}catch(S){return d(e)}}(S):p(u(S))}},51518:(v,T,i)=>{var r=i(66250),p=i(44939).concat("length","prototype");T.f=Object.getOwnPropertyNames||function(e){return r(e,p)}},47238:(v,T)=>{T.f=Object.getOwnPropertySymbols},31426:(v,T,i)=>{var r=i(80112),u=i(52208),p=i(70267),d=i(86066),e=i(37112),_=d("IE_PROTO"),y=Object,S=y.prototype;v.exports=e?y.getPrototypeOf:function(A){var N=p(A);if(r(N,_))return N[_];var L=N.constructor;return u(L)&&N instanceof L?L.prototype:N instanceof y?S:null}},46401:(v,T,i)=>{var r=i(55756),u=i(77293),p=i(49806),d=i(76318),e=Object.isExtensible,_=r(function(){e(1)});v.exports=_||d?function(S){return!(!u(S)||d&&"ArrayBuffer"==p(S))&&(!e||e(S))}:e},23336:(v,T,i)=>{var r=i(23634);v.exports=r({}.isPrototypeOf)},66250:(v,T,i)=>{var r=i(23634),u=i(80112),p=i(81010),d=i(95171).indexOf,e=i(45599),_=r([].push);v.exports=function(y,S){var Z,A=p(y),N=0,L=[];for(Z in A)!u(e,Z)&&u(A,Z)&&_(L,Z);for(;S.length>N;)u(A,Z=S[N++])&&(~d(L,Z)||_(L,Z));return L}},28474:(v,T,i)=>{var r=i(66250),u=i(44939);v.exports=Object.keys||function(d){return r(d,u)}},25558:(v,T)=>{"use strict";var i={}.propertyIsEnumerable,r=Object.getOwnPropertyDescriptor,u=r&&!i.call({1:2},1);T.f=u?function(d){var e=r(this,d);return!!e&&e.enumerable}:i},54945:(v,T,i)=>{var r=i(23634),u=i(64562),p=i(93221);v.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var _,d=!1,e={};try{(_=r(Object.getOwnPropertyDescriptor(Object.prototype,"__proto__").set))(e,[]),d=e instanceof Array}catch(y){}return function(S,A){return u(S),p(A),d?_(S,A):S.__proto__=A,S}}():void 0)},36805:(v,T,i)=>{var r=i(49642),u=i(23634),p=i(28474),d=i(81010),_=u(i(25558).f),y=u([].push),S=function(A){return function(N){for(var ue,L=d(N),Z=p(L),J=Z.length,K=0,ee=[];J>K;)ue=Z[K++],(!r||_(L,ue))&&y(ee,A?[ue,L[ue]]:L[ue]);return ee}};v.exports={entries:S(!0),values:S(!1)}},97686:(v,T,i)=>{"use strict";var r=i(25014),u=i(35329);v.exports=r?{}.toString:function(){return"[object "+u(this)+"]"}},71689:(v,T,i)=>{var r=i(25401),u=i(52208),p=i(77293),d=TypeError;v.exports=function(e,_){var y,S;if("string"===_&&u(y=e.toString)&&!p(S=r(y,e))||u(y=e.valueOf)&&!p(S=r(y,e))||"string"!==_&&u(y=e.toString)&&!p(S=r(y,e)))return S;throw d("Can't convert object to primitive value")}},59823:(v,T,i)=>{var r=i(7365),u=i(23634),p=i(51518),d=i(47238),e=i(64562),_=u([].concat);v.exports=r("Reflect","ownKeys")||function(S){var A=p.f(e(S)),N=d.f;return N?_(A,N(S)):A}},13544:v=>{v.exports={}},26975:v=>{v.exports=function(T){try{return{error:!1,value:T()}}catch(i){return{error:!0,value:i}}}},9936:(v,T,i)=>{var r=i(70009),u=i(46456),p=i(52208),d=i(79482),e=i(26699),_=i(91840),y=i(34008),S=i(31813),A=i(81124),N=i(63556),L=u&&u.prototype,Z=_("species"),J=!1,K=p(r.PromiseRejectionEvent),ee=d("Promise",function(){var ue=e(u),ae=ue!==String(u);if(!ae&&66===N||A&&(!L.catch||!L.finally))return!0;if(!N||N<51||!/native code/.test(ue)){var H=new u(function(ie){ie(1)}),se=function(ie){ie(function(){},function(){})};if((H.constructor={})[Z]=se,!(J=H.then(function(){})instanceof se))return!0}return!ae&&(y||S)&&!K});v.exports={CONSTRUCTOR:ee,REJECTION_EVENT:K,SUBCLASSING:J}},46456:(v,T,i)=>{var r=i(70009);v.exports=r.Promise},25524:(v,T,i)=>{var r=i(64562),u=i(77293),p=i(54256);v.exports=function(d,e){if(r(d),u(e)&&e.constructor===d)return e;var _=p.f(d);return(0,_.resolve)(e),_.promise}},95758:(v,T,i)=>{var r=i(46456),u=i(5253),p=i(9936).CONSTRUCTOR;v.exports=p||!u(function(d){r.all(d).then(void 0,function(){})})},70918:v=>{var T=function(){this.head=null,this.tail=null};T.prototype={add:function(i){var r={item:i,next:null};this.head?this.tail.next=r:this.head=r,this.tail=r},get:function(){var i=this.head;if(i)return this.head=i.next,this.tail===i&&(this.tail=null),i.item}},v.exports=T},67917:(v,T,i)=>{var r=i(43550),u=TypeError;v.exports=function(p){if(r(p))throw u("Can't call method on "+p);return p}},29627:v=>{v.exports=function(T,i){return T===i||T!=T&&i!=i}},53814:(v,T,i)=>{var r=i(70009),u=i(2543),p=i(52208),d=i(86053),e=i(37591),_=i(15086),y=/MSIE .\./.test(d),S=r.Function,A=function(N){return y?function(L,Z){var J=_(arguments.length,1)>2,K=p(L)?L:S(L),ee=J?e(arguments,2):void 0;return N(J?function(){u(K,this,ee)}:K,Z)}:N};v.exports={setTimeout:A(r.setTimeout),setInterval:A(r.setInterval)}},58014:(v,T,i)=>{"use strict";var r=i(7365),u=i(48011),p=i(91840),d=i(49642),e=p("species");v.exports=function(_){var y=r(_);d&&y&&!y[e]&&(0,u.f)(y,e,{configurable:!0,get:function(){return this}})}},85681:(v,T,i)=>{var r=i(25014),u=i(48011).f,p=i(65162),d=i(80112),e=i(97686),y=i(91840)("toStringTag");v.exports=function(S,A,N,L){if(S){var Z=N?S:S.prototype;d(Z,y)||u(Z,y,{configurable:!0,value:A}),L&&!r&&p(Z,"toString",e)}}},86066:(v,T,i)=>{var r=i(64579),u=i(13708),p=r("keys");v.exports=function(d){return p[d]||(p[d]=u(d))}},24766:(v,T,i)=>{var r=i(70009),u=i(34056),p="__core-js_shared__",d=r[p]||u(p,{});v.exports=d},64579:(v,T,i)=>{var r=i(81124),u=i(24766);(v.exports=function(p,d){return u[p]||(u[p]=void 0!==d?d:{})})("versions",[]).push({version:"3.25.1",mode:r?"pure":"global",copyright:"\xa9 2014-2022 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.25.1/LICENSE",source:"https://github.com/zloirock/core-js"})},95869:(v,T,i)=>{var r=i(64562),u=i(54356),p=i(43550),e=i(91840)("species");v.exports=function(_,y){var A,S=r(_).constructor;return void 0===S||p(A=r(S)[e])?y:u(A)}},61557:(v,T,i)=>{var r=i(23634),u=i(33912),p=i(41433),d=i(67917),e=r("".charAt),_=r("".charCodeAt),y=r("".slice),S=function(A){return function(N,L){var ee,ue,Z=p(d(N)),J=u(L),K=Z.length;return J<0||J>=K?A?"":void 0:(ee=_(Z,J))<55296||ee>56319||J+1===K||(ue=_(Z,J+1))<56320||ue>57343?A?e(Z,J):ee:A?y(Z,J,J+2):ue-56320+(ee-55296<<10)+65536}};v.exports={codeAt:S(!1),charAt:S(!0)}},26662:(v,T,i)=>{"use strict";var r=i(23634),u=2147483647,L=/[^\0-\u007E]/,Z=/[.\u3002\uFF0E\uFF61]/g,J="Overflow: input needs wider integers to process",ee=RangeError,ue=r(Z.exec),ae=Math.floor,H=String.fromCharCode,se=r("".charCodeAt),Ee=r([].join),ie=r([].push),he=r("".replace),ge=r("".split),De=r("".toLowerCase),lt=function(Be){return Be+22+75*(Be<26)},Ve=function(Be,Pe,je){var He=0;for(Be=je?ae(Be/700):Be>>1,Be+=ae(Be/Pe);Be>455;)Be=ae(Be/35),He+=36;return ae(He+36*Be/(Be+38))},ze=function(Be){var tn,It,Pe=[],je=(Be=function(Be){for(var Pe=[],je=0,He=Be.length;je<He;){var Vt=se(Be,je++);if(Vt>=55296&&Vt<=56319&&je<He){var it=se(Be,je++);56320==(64512&it)?ie(Pe,((1023&Vt)<<10)+(1023&it)+65536):(ie(Pe,Vt),je--)}else ie(Pe,Vt)}return Pe}(Be)).length,He=128,Vt=0,it=72;for(tn=0;tn<Be.length;tn++)(It=Be[tn])<128&&ie(Pe,H(It));var Zt=Pe.length,Ut=Zt;for(Zt&&ie(Pe,"-");Ut<je;){var Bt=u;for(tn=0;tn<Be.length;tn++)(It=Be[tn])>=He&&It<Bt&&(Bt=It);var bt=Ut+1;if(Bt-He>ae((u-Vt)/bt))throw ee(J);for(Vt+=(Bt-He)*bt,He=Bt,tn=0;tn<Be.length;tn++){if((It=Be[tn])<He&&++Vt>u)throw ee(J);if(It==He){for(var Gt=Vt,xt=36;;){var Xt=xt<=it?1:xt>=it+26?26:xt-it;if(Gt<Xt)break;var Zn=Gt-Xt,Ur=36-Xt;ie(Pe,H(lt(Xt+Zn%Ur))),Gt=ae(Zn/Ur),xt+=36}ie(Pe,H(lt(Gt))),it=Ve(Vt,bt,Ut==Zt),Vt=0,Ut++}}Vt++,He++}return Ee(Pe,"")};v.exports=function(Be){var He,Vt,Pe=[],je=ge(he(De(Be),Z,"."),".");for(He=0;He<je.length;He++)ie(Pe,ue(L,Vt=je[He])?"xn--"+ze(Vt):Vt);return Ee(Pe,".")}},53411:(v,T,i)=>{"use strict";var r=i(33912),u=i(41433),p=i(67917),d=RangeError;v.exports=function(_){var y=u(p(this)),S="",A=r(_);if(A<0||A==1/0)throw d("Wrong number of repetitions");for(;A>0;(A>>>=1)&&(y+=y))1&A&&(S+=y);return S}},85462:(v,T,i)=>{var r=i(29862).PROPER,u=i(55756),p=i(88185);v.exports=function(e){return u(function(){return!!p[e]()||"\u200b\x85\u180e"!=="\u200b\x85\u180e"[e]()||r&&p[e].name!==e})}},89858:(v,T,i)=>{var r=i(23634),u=i(67917),p=i(41433),d=i(88185),e=r("".replace),_="["+d+"]",y=RegExp("^"+_+_+"*"),S=RegExp(_+_+"*$"),A=function(N){return function(L){var Z=p(u(L));return 1&N&&(Z=e(Z,y,"")),2&N&&(Z=e(Z,S,"")),Z}};v.exports={start:A(1),end:A(2),trim:A(3)}},98535:(v,T,i)=>{var r=i(63556),u=i(55756);v.exports=!!Object.getOwnPropertySymbols&&!u(function(){var p=Symbol();return!String(p)||!(Object(p)instanceof Symbol)||!Symbol.sham&&r&&r<41})},56992:(v,T,i)=>{var r=i(25401),u=i(7365),p=i(91840),d=i(42915);v.exports=function(){var e=u("Symbol"),_=e&&e.prototype,y=_&&_.valueOf,S=p("toPrimitive");_&&!_[S]&&d(_,S,function(A){return r(y,this)},{arity:1})}},56709:(v,T,i)=>{var r=i(98535);v.exports=r&&!!Symbol.for&&!!Symbol.keyFor},37352:(v,T,i)=>{var ge,De,ce,lt,r=i(70009),u=i(2543),p=i(76781),d=i(52208),e=i(80112),_=i(55756),y=i(55690),S=i(37591),A=i(96682),N=i(15086),L=i(3877),Z=i(3787),J=r.setImmediate,K=r.clearImmediate,ee=r.process,ue=r.Dispatch,ae=r.Function,H=r.MessageChannel,se=r.String,Ee=0,ie={},he="onreadystatechange";try{ge=r.location}catch(je){}var Ve=function(je){if(e(ie,je)){var He=ie[je];delete ie[je],He()}},ze=function(je){return function(){Ve(je)}},Be=function(je){Ve(je.data)},Pe=function(je){r.postMessage(se(je),ge.protocol+"//"+ge.host)};(!J||!K)&&(J=function(He){N(arguments.length,1);var Vt=d(He)?He:ae(He),it=S(arguments,1);return ie[++Ee]=function(){u(Vt,void 0,it)},De(Ee),Ee},K=function(He){delete ie[He]},Z?De=function(je){ee.nextTick(ze(je))}:ue&&ue.now?De=function(je){ue.now(ze(je))}:H&&!L?(lt=(ce=new H).port2,ce.port1.onmessage=Be,De=p(lt.postMessage,lt)):r.addEventListener&&d(r.postMessage)&&!r.importScripts&&ge&&"file:"!==ge.protocol&&!_(Pe)?(De=Pe,r.addEventListener("message",Be,!1)):De=he in A("script")?function(je){y.appendChild(A("script"))[he]=function(){y.removeChild(this),Ve(je)}}:function(je){setTimeout(ze(je),0)}),v.exports={set:J,clear:K}},19401:(v,T,i)=>{var r=i(33912),u=Math.max,p=Math.min;v.exports=function(d,e){var _=r(d);return _<0?u(_+e,0):p(_,e)}},81010:(v,T,i)=>{var r=i(20973),u=i(67917);v.exports=function(p){return r(u(p))}},33912:(v,T,i)=>{var r=i(8651);v.exports=function(u){var p=+u;return p!=p||0===p?0:r(p)}},48869:(v,T,i)=>{var r=i(33912),u=Math.min;v.exports=function(p){return p>0?u(r(p),9007199254740991):0}},70267:(v,T,i)=>{var r=i(67917),u=Object;v.exports=function(p){return u(r(p))}},1645:(v,T,i)=>{var r=i(25401),u=i(77293),p=i(74717),d=i(34778),e=i(71689),_=i(91840),y=TypeError,S=_("toPrimitive");v.exports=function(A,N){if(!u(A)||p(A))return A;var Z,L=d(A,S);if(L){if(void 0===N&&(N="default"),Z=r(L,A,N),!u(Z)||p(Z))return Z;throw y("Can't convert object to primitive value")}return void 0===N&&(N="number"),e(A,N)}},62939:(v,T,i)=>{var r=i(1645),u=i(74717);v.exports=function(p){var d=r(p,"string");return u(d)?d:d+""}},25014:(v,T,i)=>{var p={};p[i(91840)("toStringTag")]="z",v.exports="[object z]"===String(p)},41433:(v,T,i)=>{var r=i(35329),u=String;v.exports=function(p){if("Symbol"===r(p))throw TypeError("Cannot convert a Symbol value to a string");return u(p)}},7378:v=>{var T=String;v.exports=function(i){try{return T(i)}catch(r){return"Object"}}},13708:(v,T,i)=>{var r=i(23634),u=0,p=Math.random(),d=r(1..toString);v.exports=function(e){return"Symbol("+(void 0===e?"":e)+")_"+d(++u+p,36)}},54933:(v,T,i)=>{var r=i(55756),u=i(91840),p=i(81124),d=u("iterator");v.exports=!r(function(){var e=new URL("b?a=1&b=2&c=3","http://a"),_=e.searchParams,y="";return e.pathname="c%20d",_.forEach(function(S,A){_.delete("b"),y+=A+S}),p&&!e.toJSON||!_.sort||"http://a/c%20d?a=1&c=3"!==e.href||"3"!==_.get("c")||"a=1"!==String(new URLSearchParams("?a=1"))||!_[d]||"a"!==new URL("https://a@b").username||"b"!==new URLSearchParams(new URLSearchParams("a=b")).get("a")||"xn--e1aybc"!==new URL("http://\u0442\u0435\u0441\u0442").host||"#%D0%B1"!==new URL("http://a#\u0431").hash||"a1c3"!==y||"x"!==new URL("http://x",void 0).host})},99554:(v,T,i)=>{var r=i(98535);v.exports=r&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},47960:(v,T,i)=>{var r=i(49642),u=i(55756);v.exports=r&&u(function(){return 42!=Object.defineProperty(function(){},"prototype",{value:42,writable:!1}).prototype})},15086:v=>{var T=TypeError;v.exports=function(i,r){if(i<r)throw T("Not enough arguments");return i}},81101:(v,T,i)=>{var r=i(70009),u=i(52208),p=r.WeakMap;v.exports=u(p)&&/native code/.test(String(p))},25374:(v,T,i)=>{var r=i(13544),u=i(80112),p=i(89734),d=i(48011).f;v.exports=function(e){var _=r.Symbol||(r.Symbol={});u(_,e)||d(_,e,{value:p.f(e)})}},89734:(v,T,i)=>{var r=i(91840);T.f=r},91840:(v,T,i)=>{var r=i(70009),u=i(64579),p=i(80112),d=i(13708),e=i(98535),_=i(99554),y=u("wks"),S=r.Symbol,A=S&&S.for,N=_?S:S&&S.withoutSetter||d;v.exports=function(L){if(!p(y,L)||!e&&"string"!=typeof y[L]){var Z="Symbol."+L;y[L]=e&&p(S,L)?S[L]:_&&A?A(Z):N(Z)}return y[L]}},88185:v=>{v.exports="\t\n\v\f\r \xa0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff"},70210:(v,T,i)=>{"use strict";var r=i(90513),u=i(23336),p=i(31426),d=i(54945),e=i(65031),_=i(83272),y=i(65162),S=i(51361),A=i(40039),N=i(33411),L=i(41605),Z=i(63313),J=i(91840),K=i(50499),ee=J("toStringTag"),ue=Error,ae=[].push,H=function(ie,he){var ce,ge=arguments.length>2?arguments[2]:void 0,De=u(se,this);d?ce=d(ue(),De?p(this):se):(ce=De?this:_(se),y(ce,ee,"Error")),void 0!==he&&y(ce,"message",Z(he)),K&&y(ce,"stack",A(ce.stack,1)),N(ce,ge);var lt=[];return L(ie,ae,{that:lt}),y(ce,"errors",lt),ce};d?d(H,ue):e(H,ue,{name:!0});var se=H.prototype=_(ue.prototype,{constructor:S(1,H),message:S(1,""),name:S(1,"AggregateError")});r({global:!0,constructor:!0,arity:2},{AggregateError:H})},10901:(v,T,i)=>{i(70210)},1625:(v,T,i)=>{"use strict";var r=i(90513),u=i(55756),p=i(89735),d=i(77293),e=i(70267),_=i(6381),y=i(11594),S=i(46751),A=i(2103),N=i(95913),L=i(91840),Z=i(63556),J=L("isConcatSpreadable"),K=Z>=51||!u(function(){var H=[];return H[J]=!1,H.concat()[0]!==H}),ee=N("concat"),ue=function(H){if(!d(H))return!1;var se=H[J];return void 0!==se?!!se:p(H)};r({target:"Array",proto:!0,arity:1,forced:!K||!ee},{concat:function(se){var ge,De,ce,lt,Ve,Ee=e(this),ie=A(Ee,0),he=0;for(ge=-1,ce=arguments.length;ge<ce;ge++)if(ue(Ve=-1===ge?Ee:arguments[ge]))for(lt=_(Ve),y(he+lt),De=0;De<lt;De++,he++)De in Ve&&S(ie,he,Ve[De]);else y(he+1),S(ie,he++,Ve);return ie.length=he,ie}})},70466:(v,T,i)=>{"use strict";var r=i(90513),u=i(68607).every;r({target:"Array",proto:!0,forced:!i(33620)("every")},{every:function(_){return u(this,_,arguments.length>1?arguments[1]:void 0)}})},24990:(v,T,i)=>{var r=i(90513),u=i(35277),p=i(82196);r({target:"Array",proto:!0},{fill:u}),p("fill")},56534:(v,T,i)=>{"use strict";var r=i(90513),u=i(68607).filter;r({target:"Array",proto:!0,forced:!i(95913)("filter")},{filter:function(_){return u(this,_,arguments.length>1?arguments[1]:void 0)}})},12773:(v,T,i)=>{"use strict";var r=i(90513),u=i(68607).findIndex,p=i(82196),d="findIndex",e=!0;d in[]&&Array(1)[d](function(){e=!1}),r({target:"Array",proto:!0,forced:e},{findIndex:function(y){return u(this,y,arguments.length>1?arguments[1]:void 0)}}),p(d)},60326:(v,T,i)=>{"use strict";var r=i(90513),u=i(68607).find,p=i(82196),d="find",e=!0;d in[]&&Array(1)[d](function(){e=!1}),r({target:"Array",proto:!0,forced:e},{find:function(y){return u(this,y,arguments.length>1?arguments[1]:void 0)}}),p(d)},98792:(v,T,i)=>{"use strict";var r=i(90513),u=i(8366);r({target:"Array",proto:!0,forced:[].forEach!=u},{forEach:u})},261:(v,T,i)=>{var r=i(90513),u=i(51923);r({target:"Array",stat:!0,forced:!i(5253)(function(e){Array.from(e)})},{from:u})},77059:(v,T,i)=>{"use strict";var r=i(90513),u=i(95171).includes,p=i(55756),d=i(82196);r({target:"Array",proto:!0,forced:p(function(){return!Array(1).includes()})},{includes:function(y){return u(this,y,arguments.length>1?arguments[1]:void 0)}}),d("includes")},2795:(v,T,i)=>{"use strict";var r=i(90513),u=i(23634),p=i(95171).indexOf,d=i(33620),e=u([].indexOf),_=!!e&&1/e([1],1,-0)<0,y=d("indexOf");r({target:"Array",proto:!0,forced:_||!y},{indexOf:function(A){var N=arguments.length>1?arguments[1]:void 0;return _?e(this,A,N)||0:p(this,A,N)}})},2862:(v,T,i)=>{i(90513)({target:"Array",stat:!0},{isArray:i(89735)})},1285:(v,T,i)=>{"use strict";var r=i(81010),u=i(82196),p=i(84394),d=i(91093),e=i(48011).f,_=i(79077),y=i(28738),S=i(81124),A=i(49642),N="Array Iterator",L=d.set,Z=d.getterFor(N);v.exports=_(Array,"Array",function(K,ee){L(this,{type:N,target:r(K),index:0,kind:ee})},function(){var K=Z(this),ee=K.target,ue=K.kind,ae=K.index++;return!ee||ae>=ee.length?(K.target=void 0,y(void 0,!0)):y("keys"==ue?ae:"values"==ue?ee[ae]:[ae,ee[ae]],!1)},"values");var J=p.Arguments=p.Array;if(u("keys"),u("values"),u("entries"),!S&&A&&"values"!==J.name)try{e(J,"name",{value:"values"})}catch(K){}},74926:(v,T,i)=>{var r=i(90513),u=i(78375);r({target:"Array",proto:!0,forced:u!==[].lastIndexOf},{lastIndexOf:u})},88119:(v,T,i)=>{"use strict";var r=i(90513),u=i(68607).map;r({target:"Array",proto:!0,forced:!i(95913)("map")},{map:function(_){return u(this,_,arguments.length>1?arguments[1]:void 0)}})},46250:(v,T,i)=>{"use strict";var r=i(90513),u=i(88908).left,p=i(33620),d=i(63556),e=i(3787);r({target:"Array",proto:!0,forced:!p("reduce")||!e&&d>79&&d<83},{reduce:function(A){var N=arguments.length;return u(this,A,N,N>1?arguments[1]:void 0)}})},32836:(v,T,i)=>{"use strict";var r=i(90513),u=i(23634),p=i(89735),d=u([].reverse),e=[1,2];r({target:"Array",proto:!0,forced:String(e)===String(e.reverse())},{reverse:function(){return p(this)&&(this.length=this.length),d(this)}})},72999:(v,T,i)=>{"use strict";var r=i(90513),u=i(89735),p=i(81177),d=i(77293),e=i(19401),_=i(6381),y=i(81010),S=i(46751),A=i(91840),N=i(95913),L=i(37591),Z=N("slice"),J=A("species"),K=Array,ee=Math.max;r({target:"Array",proto:!0,forced:!Z},{slice:function(ae,H){var ge,De,ce,se=y(this),Ee=_(se),ie=e(ae,Ee),he=e(void 0===H?Ee:H,Ee);if(u(se)&&((p(ge=se.constructor)&&(ge===K||u(ge.prototype))||d(ge)&&null===(ge=ge[J]))&&(ge=void 0),ge===K||void 0===ge))return L(se,ie,he);for(De=new(void 0===ge?K:ge)(ee(he-ie,0)),ce=0;ie<he;ie++,ce++)ie in se&&S(De,ce,se[ie]);return De.length=ce,De}})},50733:(v,T,i)=>{"use strict";var r=i(90513),u=i(68607).some;r({target:"Array",proto:!0,forced:!i(33620)("some")},{some:function(_){return u(this,_,arguments.length>1?arguments[1]:void 0)}})},93639:(v,T,i)=>{"use strict";var r=i(90513),u=i(23634),p=i(61812),d=i(70267),e=i(6381),_=i(67236),y=i(41433),S=i(55756),A=i(84865),N=i(33620),L=i(36410),Z=i(5329),J=i(63556),K=i(34545),ee=[],ue=u(ee.sort),ae=u(ee.push),H=S(function(){ee.sort(void 0)}),se=S(function(){ee.sort(null)}),Ee=N("sort"),ie=!S(function(){if(J)return J<70;if(!(L&&L>3)){if(Z)return!0;if(K)return K<603;var ce,lt,Ve,ze,De="";for(ce=65;ce<76;ce++){switch(lt=String.fromCharCode(ce),ce){case 66:case 69:case 70:case 72:Ve=3;break;case 68:case 71:Ve=4;break;default:Ve=2}for(ze=0;ze<47;ze++)ee.push({k:lt+ze,v:Ve})}for(ee.sort(function(Be,Pe){return Pe.v-Be.v}),ze=0;ze<ee.length;ze++)lt=ee[ze].k.charAt(0),De.charAt(De.length-1)!==lt&&(De+=lt);return"DGBEFHACIJK"!==De}});r({target:"Array",proto:!0,forced:H||!se||!Ee||!ie},{sort:function(ce){void 0!==ce&&p(ce);var lt=d(this);if(ie)return void 0===ce?ue(lt):ue(lt,ce);var Be,Pe,Ve=[],ze=e(lt);for(Pe=0;Pe<ze;Pe++)Pe in lt&&ae(Ve,lt[Pe]);for(A(Ve,function(De){return function(ce,lt){return void 0===lt?-1:void 0===ce?1:void 0!==De?+De(ce,lt)||0:y(ce)>y(lt)?1:-1}}(ce)),Be=e(Ve),Pe=0;Pe<Be;)lt[Pe]=Ve[Pe++];for(;Pe<ze;)_(lt,Pe++);return lt}})},63117:(v,T,i)=>{"use strict";var r=i(90513),u=i(70267),p=i(19401),d=i(33912),e=i(6381),_=i(54716),y=i(11594),S=i(2103),A=i(46751),N=i(67236),Z=i(95913)("splice"),J=Math.max,K=Math.min;r({target:"Array",proto:!0,forced:!Z},{splice:function(ue,ae){var he,ge,De,ce,lt,Ve,H=u(this),se=e(H),Ee=p(ue,se),ie=arguments.length;for(0===ie?he=ge=0:1===ie?(he=0,ge=se-Ee):(he=ie-2,ge=K(J(d(ae),0),se-Ee)),y(se+he-ge),De=S(H,ge),ce=0;ce<ge;ce++)(lt=Ee+ce)in H&&A(De,ce,H[lt]);if(De.length=ge,he<ge){for(ce=Ee;ce<se-ge;ce++)Ve=ce+he,(lt=ce+ge)in H?H[Ve]=H[lt]:N(H,Ve);for(ce=se;ce>se-ge+he;ce--)N(H,ce-1)}else if(he>ge)for(ce=se-ge;ce>Ee;ce--)Ve=ce+he-1,(lt=ce+ge-1)in H?H[Ve]=H[lt]:N(H,Ve);for(ce=0;ce<he;ce++)H[ce+Ee]=arguments[ce+2];return _(H,se-ge+he),De}})},34699:(v,T,i)=>{var r=i(90513),u=i(23634),p=Date,d=u(p.prototype.getTime);r({target:"Date",stat:!0},{now:function(){return d(new p)}})},33379:(v,T,i)=>{var r=i(90513),u=i(44197);r({target:"Function",proto:!0,forced:Function.bind!==u},{bind:u})},87404:(v,T,i)=>{var r=i(90513),u=i(70009);r({global:!0,forced:u.globalThis!==u},{globalThis:u})},75071:(v,T,i)=>{var r=i(90513),u=i(7365),p=i(2543),d=i(25401),e=i(23634),_=i(55756),y=i(89735),S=i(52208),A=i(77293),N=i(74717),L=i(37591),Z=i(98535),J=u("JSON","stringify"),K=e(/./.exec),ee=e("".charAt),ue=e("".charCodeAt),ae=e("".replace),H=e(1..toString),se=/[\uD800-\uDFFF]/g,Ee=/^[\uD800-\uDBFF]$/,ie=/^[\uDC00-\uDFFF]$/,he=!Z||_(function(){var lt=u("Symbol")();return"[null]"!=J([lt])||"{}"!=J({a:lt})||"{}"!=J(Object(lt))}),ge=_(function(){return'"\\udf06\\ud834"'!==J("\udf06\ud834")||'"\\udead"'!==J("\udead")}),De=function(lt,Ve){var ze=L(arguments),Be=Ve;if((A(Ve)||void 0!==lt)&&!N(lt))return y(Ve)||(Ve=function(Pe,je){if(S(Be)&&(je=d(Be,this,Pe,je)),!N(je))return je}),ze[1]=Ve,p(J,null,ze)},ce=function(lt,Ve,ze){var Be=ee(ze,Ve-1),Pe=ee(ze,Ve+1);return K(Ee,lt)&&!K(ie,Pe)||K(ie,lt)&&!K(Ee,Be)?"\\u"+H(ue(lt,0),16):lt};J&&r({target:"JSON",stat:!0,arity:3,forced:he||ge},{stringify:function(Ve,ze,Be){var Pe=L(arguments),je=p(he?De:J,null,Pe);return ge&&"string"==typeof je?ae(je,se,ce):je}})},32300:(v,T,i)=>{var r=i(70009);i(85681)(r.JSON,"JSON",!0)},83616:(v,T,i)=>{"use strict";i(85116)("Map",function(p){return function(){return p(this,arguments.length?arguments[0]:void 0)}},i(26650))},85140:(v,T,i)=>{i(83616)},63603:()=>{},67234:(v,T,i)=>{var r=i(90513),u=i(75791);r({target:"Object",stat:!0,arity:2,forced:Object.assign!==u},{assign:u})},86516:(v,T,i)=>{i(90513)({target:"Object",stat:!0,sham:!i(49642)},{create:i(83272)})},36255:(v,T,i)=>{var r=i(90513),u=i(49642),p=i(25913).f;r({target:"Object",stat:!0,forced:Object.defineProperties!==p,sham:!u},{defineProperties:p})},84468:(v,T,i)=>{var r=i(90513),u=i(49642),p=i(48011).f;r({target:"Object",stat:!0,forced:Object.defineProperty!==p,sham:!u},{defineProperty:p})},54989:(v,T,i)=>{var r=i(90513),u=i(36805).entries;r({target:"Object",stat:!0},{entries:function(d){return u(d)}})},86627:(v,T,i)=>{var r=i(90513),u=i(55756),p=i(81010),d=i(25525).f,e=i(49642),_=u(function(){d(1)});r({target:"Object",stat:!0,forced:!e||_,sham:!e},{getOwnPropertyDescriptor:function(A,N){return d(p(A),N)}})},78275:(v,T,i)=>{var r=i(90513),u=i(49642),p=i(59823),d=i(81010),e=i(25525),_=i(46751);r({target:"Object",stat:!0,sham:!u},{getOwnPropertyDescriptors:function(S){for(var K,ee,A=d(S),N=e.f,L=p(A),Z={},J=0;L.length>J;)void 0!==(ee=N(A,K=L[J++]))&&_(Z,K,ee);return Z}})},37764:(v,T,i)=>{var r=i(90513),u=i(98535),p=i(55756),d=i(47238),e=i(70267);r({target:"Object",stat:!0,forced:!u||p(function(){d.f(1)})},{getOwnPropertySymbols:function(S){var A=d.f;return A?A(e(S)):[]}})},31193:(v,T,i)=>{var r=i(90513),u=i(55756),p=i(70267),d=i(31426),e=i(37112);r({target:"Object",stat:!0,forced:u(function(){d(1)}),sham:!e},{getPrototypeOf:function(S){return d(p(S))}})},56557:(v,T,i)=>{var r=i(90513),u=i(70267),p=i(28474);r({target:"Object",stat:!0,forced:i(55756)(function(){p(1)})},{keys:function(y){return p(u(y))}})},17971:(v,T,i)=>{i(90513)({target:"Object",stat:!0},{setPrototypeOf:i(54945)})},17221:()=>{},88923:(v,T,i)=>{var r=i(90513),u=i(36805).values;r({target:"Object",stat:!0},{values:function(d){return u(d)}})},84798:(v,T,i)=>{"use strict";var r=i(90513),u=i(25401),p=i(61812),d=i(54256),e=i(26975),_=i(41605);r({target:"Promise",stat:!0},{allSettled:function(S){var A=this,N=d.f(A),L=N.resolve,Z=N.reject,J=e(function(){var K=p(A.resolve),ee=[],ue=0,ae=1;_(S,function(H){var se=ue++,Ee=!1;ae++,u(K,A,H).then(function(ie){Ee||(Ee=!0,ee[se]={status:"fulfilled",value:ie},--ae||L(ee))},function(ie){Ee||(Ee=!0,ee[se]={status:"rejected",reason:ie},--ae||L(ee))})}),--ae||L(ee)});return J.error&&Z(J.value),N.promise}})},58085:(v,T,i)=>{"use strict";var r=i(90513),u=i(25401),p=i(61812),d=i(54256),e=i(26975),_=i(41605);r({target:"Promise",stat:!0,forced:i(95758)},{all:function(A){var N=this,L=d.f(N),Z=L.resolve,J=L.reject,K=e(function(){var ee=p(N.resolve),ue=[],ae=0,H=1;_(A,function(se){var Ee=ae++,ie=!1;H++,u(ee,N,se).then(function(he){ie||(ie=!0,ue[Ee]=he,--H||Z(ue))},J)}),--H||Z(ue)});return K.error&&J(K.value),L.promise}})},98857:(v,T,i)=>{"use strict";var r=i(90513),u=i(25401),p=i(61812),d=i(7365),e=i(54256),_=i(26975),y=i(41605),S="No one promise resolved";r({target:"Promise",stat:!0},{any:function(N){var L=this,Z=d("AggregateError"),J=e.f(L),K=J.resolve,ee=J.reject,ue=_(function(){var ae=p(L.resolve),H=[],se=0,Ee=1,ie=!1;y(N,function(he){var ge=se++,De=!1;Ee++,u(ae,L,he).then(function(ce){De||ie||(ie=!0,K(ce))},function(ce){De||ie||(De=!0,H[ge]=ce,--Ee||ee(new Z(H,S)))})}),--Ee||ee(new Z(H,S))});return ue.error&&ee(ue.value),J.promise}})},5846:(v,T,i)=>{"use strict";var r=i(90513),u=i(81124),p=i(9936).CONSTRUCTOR,d=i(46456),e=i(7365),_=i(52208),y=i(42915),S=d&&d.prototype;if(r({target:"Promise",proto:!0,forced:p,real:!0},{catch:function(N){return this.then(void 0,N)}}),!u&&_(d)){var A=e("Promise").prototype.catch;S.catch!==A&&y(S,"catch",A,{unsafe:!0})}},38206:(v,T,i)=>{"use strict";var di,Lr,Kr,r=i(90513),u=i(81124),p=i(3787),d=i(70009),e=i(25401),_=i(42915),y=i(54945),S=i(85681),A=i(58014),N=i(61812),L=i(52208),Z=i(77293),J=i(54849),K=i(95869),ee=i(37352).set,ue=i(58991),ae=i(52912),H=i(26975),se=i(70918),Ee=i(91093),ie=i(46456),he=i(9936),ge=i(54256),De="Promise",ce=he.CONSTRUCTOR,lt=he.REJECTION_EVENT,Ve=he.SUBCLASSING,ze=Ee.getterFor(De),Be=Ee.set,Pe=ie&&ie.prototype,je=ie,He=Pe,Vt=d.TypeError,it=d.document,tn=d.process,It=ge.f,Zt=It,Ut=!!(it&&it.createEvent&&d.dispatchEvent),Bt="unhandledrejection",ei=function(Wt){var zn;return!(!Z(Wt)||!L(zn=Wt.then))&&zn},Nn=function(Wt,zn){var br,Dr,gn,rr=zn.value,Fr=1==zn.state,Gn=Fr?Wt.ok:Wt.fail,Jr=Wt.resolve,_i=Wt.reject,wi=Wt.domain;try{Gn?(Fr||(2===zn.rejection&&ki(zn),zn.rejection=1),!0===Gn?br=rr:(wi&&wi.enter(),br=Gn(rr),wi&&(wi.exit(),gn=!0)),br===Wt.promise?_i(Vt("Promise-chain cycle")):(Dr=ei(br))?e(Dr,br,Jr,_i):Jr(br)):_i(rr)}catch(yn){wi&&!gn&&wi.exit(),_i(yn)}},$n=function(Wt,zn){Wt.notified||(Wt.notified=!0,ue(function(){for(var Fr,rr=Wt.reactions;Fr=rr.get();)Nn(Fr,Wt);Wt.notified=!1,zn&&!Wt.rejection&&Yr(Wt)}))},Br=function(Wt,zn,rr){var Fr,Gn;Ut?((Fr=it.createEvent("Event")).promise=zn,Fr.reason=rr,Fr.initEvent(Wt,!1,!0),d.dispatchEvent(Fr)):Fr={promise:zn,reason:rr},!lt&&(Gn=d["on"+Wt])?Gn(Fr):Wt===Bt&&ae("Unhandled promise rejection",rr)},Yr=function(Wt){e(ee,d,function(){var Gn,zn=Wt.facade,rr=Wt.value;if(fi(Wt)&&(Gn=H(function(){p?tn.emit("unhandledRejection",rr,zn):Br(Bt,zn,rr)}),Wt.rejection=p||fi(Wt)?2:1,Gn.error))throw Gn.value})},fi=function(Wt){return 1!==Wt.rejection&&!Wt.parent},ki=function(Wt){e(ee,d,function(){var zn=Wt.facade;p?tn.emit("rejectionHandled",zn):Br("rejectionhandled",zn,Wt.value)})},Hi=function(Wt,zn,rr){return function(Fr){Wt(zn,Fr,rr)}},Zr=function(Wt,zn,rr){Wt.done||(Wt.done=!0,rr&&(Wt=rr),Wt.value=zn,Wt.state=2,$n(Wt,!0))},Cn=function(Wt,zn,rr){if(!Wt.done){Wt.done=!0,rr&&(Wt=rr);try{if(Wt.facade===zn)throw Vt("Promise can't be resolved itself");var Fr=ei(zn);Fr?ue(function(){var Gn={done:!1};try{e(Fr,zn,Hi(Cn,Gn,Wt),Hi(Zr,Gn,Wt))}catch(Jr){Zr(Gn,Jr,Wt)}}):(Wt.value=zn,Wt.state=1,$n(Wt,!1))}catch(Gn){Zr({done:!1},Gn,Wt)}}};if(ce&&(je=function(zn){J(this,He),N(zn),e(di,this);var rr=ze(this);try{zn(Hi(Cn,rr),Hi(Zr,rr))}catch(Fr){Zr(rr,Fr)}},(di=function(zn){Be(this,{type:De,done:!1,notified:!1,parent:!1,reactions:new se,rejection:!1,state:0,value:void 0})}).prototype=_(He=je.prototype,"then",function(zn,rr){var Fr=ze(this),Gn=It(K(this,je));return Fr.parent=!0,Gn.ok=!L(zn)||zn,Gn.fail=L(rr)&&rr,Gn.domain=p?tn.domain:void 0,0==Fr.state?Fr.reactions.add(Gn):ue(function(){Nn(Gn,Fr)}),Gn.promise}),Lr=function(){var Wt=new di,zn=ze(Wt);this.promise=Wt,this.resolve=Hi(Cn,zn),this.reject=Hi(Zr,zn)},ge.f=It=function(Wt){return Wt===je||void 0===Wt?new Lr(Wt):Zt(Wt)},!u&&L(ie)&&Pe!==Object.prototype)){Kr=Pe.then,Ve||_(Pe,"then",function(zn,rr){var Fr=this;return new je(function(Gn,Jr){e(Kr,Fr,Gn,Jr)}).then(zn,rr)},{unsafe:!0});try{delete Pe.constructor}catch(Wt){}y&&y(Pe,He)}r({global:!0,constructor:!0,wrap:!0,forced:ce},{Promise:je}),S(je,De,!1,!0),A(De)},30185:(v,T,i)=>{"use strict";var r=i(90513),u=i(81124),p=i(46456),d=i(55756),e=i(7365),_=i(52208),y=i(95869),S=i(25524),A=i(42915),N=p&&p.prototype;if(r({target:"Promise",proto:!0,real:!0,forced:!!p&&d(function(){N.finally.call({then:function(){}},function(){})})},{finally:function(J){var K=y(this,e("Promise")),ee=_(J);return this.then(ee?function(ue){return S(K,J()).then(function(){return ue})}:J,ee?function(ue){return S(K,J()).then(function(){throw ue})}:J)}}),!u&&_(p)){var Z=e("Promise").prototype.finally;N.finally!==Z&&A(N,"finally",Z,{unsafe:!0})}},66793:(v,T,i)=>{i(38206),i(58085),i(5846),i(44738),i(74767),i(4991)},44738:(v,T,i)=>{"use strict";var r=i(90513),u=i(25401),p=i(61812),d=i(54256),e=i(26975),_=i(41605);r({target:"Promise",stat:!0,forced:i(95758)},{race:function(A){var N=this,L=d.f(N),Z=L.reject,J=e(function(){var K=p(N.resolve);_(A,function(ee){u(K,N,ee).then(L.resolve,Z)})});return J.error&&Z(J.value),L.promise}})},74767:(v,T,i)=>{"use strict";var r=i(90513),u=i(25401),p=i(54256);r({target:"Promise",stat:!0,forced:i(9936).CONSTRUCTOR},{reject:function(_){var y=p.f(this);return u(y.reject,void 0,_),y.promise}})},4991:(v,T,i)=>{"use strict";var r=i(90513),u=i(7365),p=i(81124),d=i(46456),e=i(9936).CONSTRUCTOR,_=i(25524),y=u("Promise"),S=p&&!e;r({target:"Promise",stat:!0,forced:p||e},{resolve:function(N){return _(S&&this===y?d:this,N)}})},19539:(v,T,i)=>{var r=i(90513),u=i(7365),p=i(2543),d=i(44197),e=i(54356),_=i(64562),y=i(77293),S=i(83272),A=i(55756),N=u("Reflect","construct"),L=Object.prototype,Z=[].push,J=A(function(){function ue(){}return!(N(function(){},[],ue)instanceof ue)}),K=!A(function(){N(function(){})}),ee=J||K;r({target:"Reflect",stat:!0,forced:ee,sham:ee},{construct:function(ae,H){e(ae),_(H);var se=arguments.length<3?ae:e(arguments[2]);if(K&&!J)return N(ae,H,se);if(ae==se){switch(H.length){case 0:return new ae;case 1:return new ae(H[0]);case 2:return new ae(H[0],H[1]);case 3:return new ae(H[0],H[1],H[2]);case 4:return new ae(H[0],H[1],H[2],H[3])}var Ee=[null];return p(Z,Ee,H),new(p(d,ae,Ee))}var ie=se.prototype,he=S(y(ie)?ie:L),ge=p(ae,he,H);return y(ge)?ge:he}})},60851:(v,T,i)=>{var r=i(90513),u=i(25401),p=i(77293),d=i(64562),e=i(27029),_=i(25525),y=i(31426);r({target:"Reflect",stat:!0},{get:function S(A,N){var Z,J,L=arguments.length<3?A:arguments[2];return d(A)===L?A[N]:(Z=_.f(A,N))?e(Z)?Z.value:void 0===Z.get?void 0:u(Z.get,L):p(J=y(A))?S(J,N,L):void 0}})},44864:()=>{},97764:(v,T,i)=>{"use strict";var r=i(90513),u=i(23634),p=i(56421),d=i(67917),e=i(41433),_=i(79668),y=u("".indexOf);r({target:"String",proto:!0,forced:!_("includes")},{includes:function(A){return!!~y(e(d(this)),e(p(A)),arguments.length>1?arguments[1]:void 0)}})},3934:(v,T,i)=>{"use strict";var r=i(61557).charAt,u=i(41433),p=i(91093),d=i(79077),e=i(28738),_="String Iterator",y=p.set,S=p.getterFor(_);d(String,"String",function(A){y(this,{type:_,string:u(A),index:0})},function(){var J,N=S(this),L=N.string,Z=N.index;return Z>=L.length?e(void 0,!0):(J=r(L,Z),N.index+=J.length,e(J,!1))})},3588:(v,T,i)=>{i(90513)({target:"String",proto:!0},{repeat:i(53411)})},24655:(v,T,i)=>{"use strict";var ee,r=i(90513),u=i(23634),p=i(25525).f,d=i(48869),e=i(41433),_=i(56421),y=i(67917),S=i(79668),A=i(81124),N=u("".startsWith),L=u("".slice),Z=Math.min,J=S("startsWith");r({target:"String",proto:!0,forced:!(!A&&!J&&(ee=p(String.prototype,"startsWith"),ee&&!ee.writable)||J)},{startsWith:function(ue){var ae=e(y(this));_(ue);var H=d(Z(arguments.length>1?arguments[1]:void 0,ae.length)),se=e(ue);return N?N(ae,se,H):L(ae,H,H+se.length)===se}})},90451:(v,T,i)=>{"use strict";var r=i(90513),u=i(89858).trim;r({target:"String",proto:!0,forced:i(85462)("trim")},{trim:function(){return u(this)}})},16426:(v,T,i)=>{i(25374)("asyncIterator")},17858:(v,T,i)=>{"use strict";var r=i(90513),u=i(70009),p=i(25401),d=i(23634),e=i(81124),_=i(49642),y=i(98535),S=i(55756),A=i(80112),N=i(23336),L=i(64562),Z=i(81010),J=i(62939),K=i(41433),ee=i(51361),ue=i(83272),ae=i(28474),H=i(51518),se=i(62469),Ee=i(47238),ie=i(25525),he=i(48011),ge=i(25913),De=i(25558),ce=i(42915),lt=i(64579),Ve=i(86066),ze=i(45599),Be=i(13708),Pe=i(91840),je=i(89734),He=i(25374),Vt=i(56992),it=i(85681),tn=i(91093),It=i(68607).forEach,Zt=Ve("hidden"),Ut="Symbol",Bt="prototype",bt=tn.set,Gt=tn.getterFor(Ut),xt=Object[Bt],Xt=u.Symbol,Zn=Xt&&Xt[Bt],Ur=u.TypeError,di=u.QObject,Lr=ie.f,Mr=he.f,Kr=se.f,ei=De.f,Nn=d([].push),$n=lt("symbols"),Br=lt("op-symbols"),Yr=lt("wks"),fi=!di||!di[Bt]||!di[Bt].findChild,ki=_&&S(function(){return 7!=ue(Mr({},"a",{get:function(){return Mr(this,"a",{value:7}).a}})).a})?function(Jr,_i,wi){var br=Lr(xt,_i);br&&delete xt[_i],Mr(Jr,_i,wi),br&&Jr!==xt&&Mr(xt,_i,br)}:Mr,Hi=function(Jr,_i){var wi=$n[Jr]=ue(Zn);return bt(wi,{type:Ut,tag:Jr,description:_i}),_||(wi.description=_i),wi},Zr=function(_i,wi,br){_i===xt&&Zr(Br,wi,br),L(_i);var Dr=J(wi);return L(br),A($n,Dr)?(br.enumerable?(A(_i,Zt)&&_i[Zt][Dr]&&(_i[Zt][Dr]=!1),br=ue(br,{enumerable:ee(0,!1)})):(A(_i,Zt)||Mr(_i,Zt,ee(1,{})),_i[Zt][Dr]=!0),ki(_i,Dr,br)):Mr(_i,Dr,br)},Cn=function(_i,wi){L(_i);var br=Z(wi),Dr=ae(br).concat(Gn(br));return It(Dr,function(gn){(!_||p(zn,br,gn))&&Zr(_i,gn,br[gn])}),_i},zn=function(_i){var wi=J(_i),br=p(ei,this,wi);return!(this===xt&&A($n,wi)&&!A(Br,wi))&&(!(br||!A(this,wi)||!A($n,wi)||A(this,Zt)&&this[Zt][wi])||br)},rr=function(_i,wi){var br=Z(_i),Dr=J(wi);if(br!==xt||!A($n,Dr)||A(Br,Dr)){var gn=Lr(br,Dr);return gn&&A($n,Dr)&&!(A(br,Zt)&&br[Zt][Dr])&&(gn.enumerable=!0),gn}},Fr=function(_i){var wi=Kr(Z(_i)),br=[];return It(wi,function(Dr){!A($n,Dr)&&!A(ze,Dr)&&Nn(br,Dr)}),br},Gn=function(Jr){var _i=Jr===xt,wi=Kr(_i?Br:Z(Jr)),br=[];return It(wi,function(Dr){A($n,Dr)&&(!_i||A(xt,Dr))&&Nn(br,$n[Dr])}),br};y||(ce(Zn=(Xt=function(){if(N(Zn,this))throw Ur("Symbol is not a constructor");var _i=arguments.length&&void 0!==arguments[0]?K(arguments[0]):void 0,wi=Be(_i),br=function(Dr){this===xt&&p(br,Br,Dr),A(this,Zt)&&A(this[Zt],wi)&&(this[Zt][wi]=!1),ki(this,wi,ee(1,Dr))};return _&&fi&&ki(xt,wi,{configurable:!0,set:br}),Hi(wi,_i)})[Bt],"toString",function(){return Gt(this).tag}),ce(Xt,"withoutSetter",function(Jr){return Hi(Be(Jr),Jr)}),De.f=zn,he.f=Zr,ge.f=Cn,ie.f=rr,H.f=se.f=Fr,Ee.f=Gn,je.f=function(Jr){return Hi(Pe(Jr),Jr)},_&&(Mr(Zn,"description",{configurable:!0,get:function(){return Gt(this).description}}),e||ce(xt,"propertyIsEnumerable",zn,{unsafe:!0}))),r({global:!0,constructor:!0,wrap:!0,forced:!y,sham:!y},{Symbol:Xt}),It(ae(Yr),function(Jr){He(Jr)}),r({target:Ut,stat:!0,forced:!y},{useSetter:function(){fi=!0},useSimple:function(){fi=!1}}),r({target:"Object",stat:!0,forced:!y,sham:!_},{create:function(_i,wi){return void 0===wi?ue(_i):Cn(ue(_i),wi)},defineProperty:Zr,defineProperties:Cn,getOwnPropertyDescriptor:rr}),r({target:"Object",stat:!0,forced:!y},{getOwnPropertyNames:Fr}),Vt(),it(Xt,Ut),ze[Zt]=!0},1172:()=>{},12353:(v,T,i)=>{var r=i(90513),u=i(7365),p=i(80112),d=i(41433),e=i(64579),_=i(56709),y=e("string-to-symbol-registry"),S=e("symbol-to-string-registry");r({target:"Symbol",stat:!0,forced:!_},{for:function(A){var N=d(A);if(p(y,N))return y[N];var L=u("Symbol")(N);return y[N]=L,S[L]=N,L}})},99579:(v,T,i)=>{i(25374)("hasInstance")},41258:(v,T,i)=>{i(25374)("isConcatSpreadable")},2383:(v,T,i)=>{i(25374)("iterator")},56728:(v,T,i)=>{i(17858),i(12353),i(27632),i(75071),i(37764)},27632:(v,T,i)=>{var r=i(90513),u=i(80112),p=i(74717),d=i(7378),e=i(64579),_=i(56709),y=e("symbol-to-string-registry");r({target:"Symbol",stat:!0,forced:!_},{keyFor:function(A){if(!p(A))throw TypeError(d(A)+" is not a symbol");if(u(y,A))return y[A]}})},64776:(v,T,i)=>{i(25374)("matchAll")},44339:(v,T,i)=>{i(25374)("match")},88215:(v,T,i)=>{i(25374)("replace")},65389:(v,T,i)=>{i(25374)("search")},12733:(v,T,i)=>{i(25374)("species")},97977:(v,T,i)=>{i(25374)("split")},59792:(v,T,i)=>{var r=i(25374),u=i(56992);r("toPrimitive"),u()},60242:(v,T,i)=>{var r=i(7365),u=i(25374),p=i(85681);u("toStringTag"),p(r("Symbol"),"Symbol")},26291:(v,T,i)=>{i(25374)("unscopables")},3119:(v,T,i)=>{"use strict";var Z,r=i(70009),u=i(23634),p=i(84604),d=i(57867),e=i(85116),_=i(84049),y=i(77293),S=i(46401),A=i(91093).enforce,N=i(81101),L=!r.ActiveXObject&&"ActiveXObject"in r,J=function(Ee){return function(){return Ee(this,arguments.length?arguments[0]:void 0)}},K=e("WeakMap",J,_);if(N&&L){Z=_.getConstructor(J,"WeakMap",!0),d.enable();var ee=K.prototype,ue=u(ee.delete),ae=u(ee.has),H=u(ee.get),se=u(ee.set);p(ee,{delete:function(Ee){if(y(Ee)&&!S(Ee)){var ie=A(this);return ie.frozen||(ie.frozen=new Z),ue(this,Ee)||ie.frozen.delete(Ee)}return ue(this,Ee)},has:function(ie){if(y(ie)&&!S(ie)){var he=A(this);return he.frozen||(he.frozen=new Z),ae(this,ie)||he.frozen.has(ie)}return ae(this,ie)},get:function(ie){if(y(ie)&&!S(ie)){var he=A(this);return he.frozen||(he.frozen=new Z),ae(this,ie)?H(this,ie):he.frozen.get(ie)}return H(this,ie)},set:function(ie,he){if(y(ie)&&!S(ie)){var ge=A(this);ge.frozen||(ge.frozen=new Z),ae(this,ie)?se(this,ie,he):ge.frozen.set(ie,he)}else se(this,ie,he);return this}})}},90770:(v,T,i)=>{i(3119)},67670:(v,T,i)=>{i(10901)},65237:(v,T,i)=>{i(87404)},10509:(v,T,i)=>{"use strict";i(90513)({target:"Map",proto:!0,real:!0,forced:!0},{deleteAll:i(37353)})},30887:(v,T,i)=>{"use strict";i(90513)({target:"Map",proto:!0,real:!0,forced:!0},{emplace:i(12864)})},54547:(v,T,i)=>{"use strict";var r=i(90513),u=i(64562),p=i(76781),d=i(37444),e=i(41605);r({target:"Map",proto:!0,real:!0,forced:!0},{every:function(y){var S=u(this),A=d(S),N=p(y,arguments.length>1?arguments[1]:void 0);return!e(A,function(L,Z,J){if(!N(Z,L,S))return J()},{AS_ENTRIES:!0,IS_ITERATOR:!0,INTERRUPTED:!0}).stopped}})},68996:(v,T,i)=>{"use strict";var r=i(90513),u=i(7365),p=i(76781),d=i(25401),e=i(61812),_=i(64562),y=i(95869),S=i(37444),A=i(41605);r({target:"Map",proto:!0,real:!0,forced:!0},{filter:function(L){var Z=_(this),J=S(Z),K=p(L,arguments.length>1?arguments[1]:void 0),ee=new(y(Z,u("Map"))),ue=e(ee.set);return A(J,function(ae,H){K(H,ae,Z)&&d(ue,ee,ae,H)},{AS_ENTRIES:!0,IS_ITERATOR:!0}),ee}})},60176:(v,T,i)=>{"use strict";var r=i(90513),u=i(64562),p=i(76781),d=i(37444),e=i(41605);r({target:"Map",proto:!0,real:!0,forced:!0},{findKey:function(y){var S=u(this),A=d(S),N=p(y,arguments.length>1?arguments[1]:void 0);return e(A,function(L,Z,J){if(N(Z,L,S))return J(L)},{AS_ENTRIES:!0,IS_ITERATOR:!0,INTERRUPTED:!0}).result}})},1530:(v,T,i)=>{"use strict";var r=i(90513),u=i(64562),p=i(76781),d=i(37444),e=i(41605);r({target:"Map",proto:!0,real:!0,forced:!0},{find:function(y){var S=u(this),A=d(S),N=p(y,arguments.length>1?arguments[1]:void 0);return e(A,function(L,Z,J){if(N(Z,L,S))return J(Z)},{AS_ENTRIES:!0,IS_ITERATOR:!0,INTERRUPTED:!0}).result}})},78271:(v,T,i)=>{i(90513)({target:"Map",stat:!0,forced:!0},{from:i(83483)})},41554:(v,T,i)=>{"use strict";var r=i(90513),u=i(25401),p=i(23634),d=i(61812),e=i(88055),_=i(41605),y=p([].push);r({target:"Map",stat:!0,forced:!0},{groupBy:function(A,N){d(N);var L=e(A),Z=new this,J=d(Z.has),K=d(Z.get),ee=d(Z.set);return _(L,function(ue){var ae=N(ue);u(J,Z,ae)?y(u(K,Z,ae),ue):u(ee,Z,ae,[ue])},{IS_ITERATOR:!0}),Z}})},41688:(v,T,i)=>{"use strict";var r=i(90513),u=i(64562),p=i(37444),d=i(29627),e=i(41605);r({target:"Map",proto:!0,real:!0,forced:!0},{includes:function(y){return e(p(u(this)),function(S,A,N){if(d(A,y))return N()},{AS_ENTRIES:!0,IS_ITERATOR:!0,INTERRUPTED:!0}).stopped}})},92847:(v,T,i)=>{"use strict";var r=i(90513),u=i(25401),p=i(41605),d=i(61812);r({target:"Map",stat:!0,forced:!0},{keyBy:function(_,y){var S=new this;d(y);var A=d(S.set);return p(_,function(N){u(A,S,y(N),N)}),S}})},17316:(v,T,i)=>{"use strict";var r=i(90513),u=i(64562),p=i(37444),d=i(41605);r({target:"Map",proto:!0,real:!0,forced:!0},{keyOf:function(_){return d(p(u(this)),function(y,S,A){if(S===_)return A(y)},{AS_ENTRIES:!0,IS_ITERATOR:!0,INTERRUPTED:!0}).result}})},58786:(v,T,i)=>{"use strict";var r=i(90513),u=i(7365),p=i(76781),d=i(25401),e=i(61812),_=i(64562),y=i(95869),S=i(37444),A=i(41605);r({target:"Map",proto:!0,real:!0,forced:!0},{mapKeys:function(L){var Z=_(this),J=S(Z),K=p(L,arguments.length>1?arguments[1]:void 0),ee=new(y(Z,u("Map"))),ue=e(ee.set);return A(J,function(ae,H){d(ue,ee,K(H,ae,Z),H)},{AS_ENTRIES:!0,IS_ITERATOR:!0}),ee}})},35517:(v,T,i)=>{"use strict";var r=i(90513),u=i(7365),p=i(76781),d=i(25401),e=i(61812),_=i(64562),y=i(95869),S=i(37444),A=i(41605);r({target:"Map",proto:!0,real:!0,forced:!0},{mapValues:function(L){var Z=_(this),J=S(Z),K=p(L,arguments.length>1?arguments[1]:void 0),ee=new(y(Z,u("Map"))),ue=e(ee.set);return A(J,function(ae,H){d(ue,ee,ae,K(H,ae,Z))},{AS_ENTRIES:!0,IS_ITERATOR:!0}),ee}})},12783:(v,T,i)=>{"use strict";var r=i(90513),u=i(61812),p=i(64562),d=i(41605);r({target:"Map",proto:!0,real:!0,arity:1,forced:!0},{merge:function(_){for(var y=p(this),S=u(y.set),A=arguments.length,N=0;N<A;)d(arguments[N++],S,{that:y,AS_ENTRIES:!0});return y}})},60854:(v,T,i)=>{i(90513)({target:"Map",stat:!0,forced:!0},{of:i(13067)})},69773:(v,T,i)=>{"use strict";var r=i(90513),u=i(64562),p=i(61812),d=i(37444),e=i(41605),_=TypeError;r({target:"Map",proto:!0,real:!0,forced:!0},{reduce:function(S){var A=u(this),N=d(A),L=arguments.length<2,Z=L?void 0:arguments[1];if(p(S),e(N,function(J,K){L?(L=!1,Z=K):Z=S(Z,K,J,A)},{AS_ENTRIES:!0,IS_ITERATOR:!0}),L)throw _("Reduce of empty map with no initial value");return Z}})},22337:(v,T,i)=>{"use strict";var r=i(90513),u=i(64562),p=i(76781),d=i(37444),e=i(41605);r({target:"Map",proto:!0,real:!0,forced:!0},{some:function(y){var S=u(this),A=d(S),N=p(y,arguments.length>1?arguments[1]:void 0);return e(A,function(L,Z,J){if(N(Z,L,S))return J()},{AS_ENTRIES:!0,IS_ITERATOR:!0,INTERRUPTED:!0}).stopped}})},84131:(v,T,i)=>{"use strict";i(90513)({target:"Map",proto:!0,real:!0,name:"upsert",forced:!0},{updateOrInsert:i(57729)})},40199:(v,T,i)=>{"use strict";var r=i(90513),u=i(25401),p=i(64562),d=i(61812),e=TypeError;r({target:"Map",proto:!0,real:!0,forced:!0},{update:function(y,S){var A=p(this),N=d(A.get),L=d(A.has),Z=d(A.set),J=arguments.length;d(S);var K=u(L,A,y);if(!K&&J<3)throw e("Updating absent value");var ee=K?u(N,A,y):d(J>2?arguments[2]:void 0)(y,A);return u(Z,A,y,S(ee,y,A)),A}})},69046:(v,T,i)=>{"use strict";i(90513)({target:"Map",proto:!0,real:!0,forced:!0},{upsert:i(57729)})},61127:(v,T,i)=>{i(84798)},45975:(v,T,i)=>{i(98857)},93114:(v,T,i)=>{"use strict";var r=i(90513),u=i(54256),p=i(26975);r({target:"Promise",stat:!0,forced:!0},{try:function(d){var e=u.f(this),_=p(d);return(_.error?e.reject:e.resolve)(_.value),e.promise}})},55461:(v,T,i)=>{i(25374)("asyncDispose")},5737:(v,T,i)=>{i(25374)("dispose")},87097:(v,T,i)=>{i(25374)("matcher")},29559:(v,T,i)=>{i(25374)("metadataKey")},71985:(v,T,i)=>{i(25374)("metadata")},90212:(v,T,i)=>{i(25374)("observable")},93770:(v,T,i)=>{i(25374)("patternMatch")},47743:(v,T,i)=>{i(25374)("replaceAll")},33089:(v,T,i)=>{i(1285);var r=i(44125),u=i(70009),p=i(35329),d=i(65162),e=i(84394),y=i(91840)("toStringTag");for(var S in r){var A=u[S],N=A&&A.prototype;N&&p(N)!==y&&d(N,y,S),e[S]=e.Array}},94784:(v,T,i)=>{var r=i(90513),u=i(70009),p=i(53814).setInterval;r({global:!0,bind:!0,forced:u.setInterval!==p},{setInterval:p})},36445:(v,T,i)=>{var r=i(90513),u=i(70009),p=i(53814).setTimeout;r({global:!0,bind:!0,forced:u.setTimeout!==p},{setTimeout:p})},69280:(v,T,i)=>{i(94784),i(36445)},73842:(v,T,i)=>{"use strict";i(1285);var r=i(90513),u=i(70009),p=i(25401),d=i(23634),e=i(49642),_=i(54933),y=i(42915),S=i(84604),A=i(85681),N=i(14554),L=i(91093),Z=i(54849),J=i(52208),K=i(80112),ee=i(76781),ue=i(35329),ae=i(64562),H=i(77293),se=i(41433),Ee=i(83272),ie=i(51361),he=i(88055),ge=i(34014),De=i(15086),ce=i(91840),lt=i(84865),Ve=ce("iterator"),ze="URLSearchParams",Be=ze+"Iterator",Pe=L.set,je=L.getterFor(ze),He=L.getterFor(Be),Vt=Object.getOwnPropertyDescriptor,it=function(Dr){if(!e)return u[Dr];var gn=Vt(u,Dr);return gn&&gn.value},tn=it("fetch"),It=it("Request"),Zt=it("Headers"),Ut=It&&It.prototype,Bt=Zt&&Zt.prototype,bt=u.RegExp,Gt=u.TypeError,xt=u.decodeURIComponent,Xt=u.encodeURIComponent,Zn=d("".charAt),Ur=d([].join),di=d([].push),Lr=d("".replace),Mr=d([].shift),Kr=d([].splice),ei=d("".split),Nn=d("".slice),$n=/\+/g,Br=Array(4),Yr=function(Dr){return Br[Dr-1]||(Br[Dr-1]=bt("((?:%[\\da-f]{2}){"+Dr+"})","gi"))},fi=function(Dr){try{return xt(Dr)}catch(gn){return Dr}},ki=function(Dr){var gn=Lr(Dr,$n," "),yn=4;try{return xt(gn)}catch(gr){for(;yn;)gn=Lr(gn,Yr(yn--),fi);return gn}},Hi=/[!'()~]|%20/g,Zr={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+"},Cn=function(Dr){return Zr[Dr]},Wt=function(Dr){return Lr(Xt(Dr),Hi,Cn)},zn=N(function(gn,yn){Pe(this,{type:Be,iterator:he(je(gn).entries),kind:yn})},"Iterator",function(){var gn=He(this),yn=gn.kind,gr=gn.iterator.next(),Jt=gr.value;return gr.done||(gr.value="keys"===yn?Jt.key:"values"===yn?Jt.value:[Jt.key,Jt.value]),gr},!0),rr=function(Dr){this.entries=[],this.url=null,void 0!==Dr&&(H(Dr)?this.parseObject(Dr):this.parseQuery("string"==typeof Dr?"?"===Zn(Dr,0)?Nn(Dr,1):Dr:se(Dr)))};rr.prototype={type:ze,bindURL:function(Dr){this.url=Dr,this.update()},parseObject:function(Dr){var yn,gr,Jt,Vn,mr,Dn,Pr,gn=ge(Dr);if(gn)for(gr=(yn=he(Dr,gn)).next;!(Jt=p(gr,yn)).done;){if(Vn=he(ae(Jt.value)),(Dn=p(mr=Vn.next,Vn)).done||(Pr=p(mr,Vn)).done||!p(mr,Vn).done)throw Gt("Expected sequence with length 2");di(this.entries,{key:se(Dn.value),value:se(Pr.value)})}else for(var Yt in Dr)K(Dr,Yt)&&di(this.entries,{key:Yt,value:se(Dr[Yt])})},parseQuery:function(Dr){if(Dr)for(var gr,Jt,gn=ei(Dr,"&"),yn=0;yn<gn.length;)(gr=gn[yn++]).length&&(Jt=ei(gr,"="),di(this.entries,{key:ki(Mr(Jt)),value:ki(Ur(Jt,"="))}))},serialize:function(){for(var gr,Dr=this.entries,gn=[],yn=0;yn<Dr.length;)gr=Dr[yn++],di(gn,Wt(gr.key)+"="+Wt(gr.value));return Ur(gn,"&")},update:function(){this.entries.length=0,this.parseQuery(this.url.query)},updateURL:function(){this.url&&this.url.update()}};var Fr=function(){Z(this,Gn);var gn=arguments.length>0?arguments[0]:void 0;Pe(this,new rr(gn))},Gn=Fr.prototype;if(S(Gn,{append:function(gn,yn){De(arguments.length,2);var gr=je(this);di(gr.entries,{key:se(gn),value:se(yn)}),gr.updateURL()},delete:function(Dr){De(arguments.length,1);for(var gn=je(this),yn=gn.entries,gr=se(Dr),Jt=0;Jt<yn.length;)yn[Jt].key===gr?Kr(yn,Jt,1):Jt++;gn.updateURL()},get:function(gn){De(arguments.length,1);for(var yn=je(this).entries,gr=se(gn),Jt=0;Jt<yn.length;Jt++)if(yn[Jt].key===gr)return yn[Jt].value;return null},getAll:function(gn){De(arguments.length,1);for(var yn=je(this).entries,gr=se(gn),Jt=[],Vn=0;Vn<yn.length;Vn++)yn[Vn].key===gr&&di(Jt,yn[Vn].value);return Jt},has:function(gn){De(arguments.length,1);for(var yn=je(this).entries,gr=se(gn),Jt=0;Jt<yn.length;)if(yn[Jt++].key===gr)return!0;return!1},set:function(gn,yn){De(arguments.length,1);for(var Yt,gr=je(this),Jt=gr.entries,Vn=!1,mr=se(gn),Dn=se(yn),Pr=0;Pr<Jt.length;Pr++)(Yt=Jt[Pr]).key===mr&&(Vn?Kr(Jt,Pr--,1):(Vn=!0,Yt.value=Dn));Vn||di(Jt,{key:mr,value:Dn}),gr.updateURL()},sort:function(){var gn=je(this);lt(gn.entries,function(yn,gr){return yn.key>gr.key?1:-1}),gn.updateURL()},forEach:function(gn){for(var Vn,yn=je(this).entries,gr=ee(gn,arguments.length>1?arguments[1]:void 0),Jt=0;Jt<yn.length;)gr((Vn=yn[Jt++]).value,Vn.key,this)},keys:function(){return new zn(this,"keys")},values:function(){return new zn(this,"values")},entries:function(){return new zn(this,"entries")}},{enumerable:!0}),y(Gn,Ve,Gn.entries,{name:"entries"}),y(Gn,"toString",function(){return je(this).serialize()},{enumerable:!0}),A(Fr,ze),r({global:!0,constructor:!0,forced:!_},{URLSearchParams:Fr}),!_&&J(Zt)){var Jr=d(Bt.has),_i=d(Bt.set),wi=function(Dr){if(H(Dr)){var yn,gn=Dr.body;if(ue(gn)===ze)return yn=Dr.headers?new Zt(Dr.headers):new Zt,Jr(yn,"content-type")||_i(yn,"content-type","application/x-www-form-urlencoded;charset=UTF-8"),Ee(Dr,{body:ie(0,se(gn)),headers:ie(0,yn)})}return Dr};if(J(tn)&&r({global:!0,enumerable:!0,dontCallGetSet:!0,forced:!0},{fetch:function(gn){return tn(gn,arguments.length>1?wi(arguments[1]):{})}}),J(It)){var br=function(gn){return Z(this,Ut),new It(gn,arguments.length>1?wi(arguments[1]):{})};Ut.constructor=br,br.prototype=Ut,r({global:!0,constructor:!0,dontCallGetSet:!0,forced:!0},{Request:br})}}v.exports={URLSearchParams:Fr,getState:je}},26953:(v,T,i)=>{i(73842)},80504:(v,T,i)=>{"use strict";i(3934);var Hi,r=i(90513),u=i(49642),p=i(54933),d=i(70009),e=i(76781),_=i(23634),y=i(42915),S=i(1707),A=i(54849),N=i(80112),L=i(75791),Z=i(51923),J=i(8681),K=i(61557).codeAt,ee=i(26662),ue=i(41433),ae=i(85681),H=i(15086),se=i(73842),Ee=i(91093),ie=Ee.set,he=Ee.getterFor("URL"),ge=se.URLSearchParams,De=se.getState,ce=d.URL,lt=d.TypeError,Ve=d.parseInt,ze=Math.floor,Be=Math.pow,Pe=_("".charAt),je=_(/./.exec),He=_([].join),Vt=_(1..toString),it=_([].pop),tn=_([].push),It=_("".replace),Zt=_([].shift),Ut=_("".split),Bt=_("".slice),bt=_("".toLowerCase),Gt=_([].unshift),Xt="Invalid scheme",Zn="Invalid host",Ur="Invalid port",di=/[a-z]/i,Lr=/[\d+-.a-z]/i,Mr=/\d/,Kr=/^0x/i,ei=/^[0-7]+$/,Nn=/^\d+$/,$n=/^[\da-f]+$/i,Br=/[\0\t\n\r #%/:<>?@[\\\]^|]/,Yr=/[\0\t\n\r #/:<>?@[\\\]^|]/,fi=/^[\u0000-\u0020]+|[\u0000-\u0020]+$/g,ki=/[\t\n\r]/g,zn=function(Bn){var lr,vr,er,ri;if("number"==typeof Bn){for(lr=[],vr=0;vr<4;vr++)Gt(lr,Bn%256),Bn=ze(Bn/256);return He(lr,".")}if("object"==typeof Bn){for(lr="",er=function(Bn){for(var lr=null,vr=1,er=null,ri=0,uo=0;uo<8;uo++)0!==Bn[uo]?(ri>vr&&(lr=er,vr=ri),er=null,ri=0):(null===er&&(er=uo),++ri);return ri>vr&&(lr=er,vr=ri),lr}(Bn),vr=0;vr<8;vr++)ri&&0===Bn[vr]||(ri&&(ri=!1),er===vr?(lr+=vr?":":"::",ri=!0):(lr+=Vt(Bn[vr],16),vr<7&&(lr+=":")));return"["+lr+"]"}return Bn},rr={},Fr=L({},rr,{" ":1,'"':1,"<":1,">":1,"`":1}),Gn=L({},Fr,{"#":1,"?":1,"{":1,"}":1}),Jr=L({},Gn,{"/":1,":":1,";":1,"=":1,"@":1,"[":1,"\\":1,"]":1,"^":1,"|":1}),_i=function(Bn,lr){var vr=K(Bn,0);return vr>32&&vr<127&&!N(lr,Bn)?Bn:encodeURIComponent(Bn)},wi={ftp:21,file:null,http:80,https:443,ws:80,wss:443},br=function(Bn,lr){var vr;return 2==Bn.length&&je(di,Pe(Bn,0))&&(":"==(vr=Pe(Bn,1))||!lr&&"|"==vr)},Dr=function(Bn){var lr;return Bn.length>1&&br(Bt(Bn,0,2))&&(2==Bn.length||"/"===(lr=Pe(Bn,2))||"\\"===lr||"?"===lr||"#"===lr)},gn=function(Bn){return"."===Bn||"%2e"===bt(Bn)},yn=function(Bn){return".."===(Bn=bt(Bn))||"%2e."===Bn||".%2e"===Bn||"%2e%2e"===Bn},gr={},Jt={},Vn={},mr={},Dn={},Pr={},Yt={},_n={},Ge={},kr={},mi={},An={},Er={},Wr={},dr={},Fn={},ar={},Wi={},lo={},vo={},Co={},Gi=function(Bn,lr,vr){var ri,uo,Ci,er=ue(Bn);if(lr){if(uo=this.parse(er))throw lt(uo);this.searchParams=null}else{if(void 0!==vr&&(ri=new Gi(vr,!0)),uo=this.parse(er,null,ri))throw lt(uo);(Ci=De(new ge)).bindURL(this),this.searchParams=Ci}};Gi.prototype={type:"URL",parse:function(Bn,lr,vr){var Rt,_t,mt,jt,er=this,ri=lr||gr,uo=0,Ci="",$o=!1,tr=!1,Ar=!1;for(Bn=ue(Bn),lr||(er.scheme="",er.username="",er.password="",er.host=null,er.port=null,er.path=[],er.query=null,er.fragment=null,er.cannotBeABaseURL=!1,Bn=It(Bn,fi,"")),Bn=It(Bn,ki,""),Rt=Z(Bn);uo<=Rt.length;){switch(_t=Rt[uo],ri){case gr:if(!_t||!je(di,_t)){if(lr)return Xt;ri=Vn;continue}Ci+=bt(_t),ri=Jt;break;case Jt:if(_t&&(je(Lr,_t)||"+"==_t||"-"==_t||"."==_t))Ci+=bt(_t);else{if(":"!=_t){if(lr)return Xt;Ci="",ri=Vn,uo=0;continue}if(lr&&(er.isSpecial()!=N(wi,Ci)||"file"==Ci&&(er.includesCredentials()||null!==er.port)||"file"==er.scheme&&!er.host))return;if(er.scheme=Ci,lr)return void(er.isSpecial()&&wi[er.scheme]==er.port&&(er.port=null));Ci="","file"==er.scheme?ri=Wr:er.isSpecial()&&vr&&vr.scheme==er.scheme?ri=mr:er.isSpecial()?ri=_n:"/"==Rt[uo+1]?(ri=Dn,uo++):(er.cannotBeABaseURL=!0,tn(er.path,""),ri=lo)}break;case Vn:if(!vr||vr.cannotBeABaseURL&&"#"!=_t)return Xt;if(vr.cannotBeABaseURL&&"#"==_t){er.scheme=vr.scheme,er.path=J(vr.path),er.query=vr.query,er.fragment="",er.cannotBeABaseURL=!0,ri=Co;break}ri="file"==vr.scheme?Wr:Pr;continue;case mr:if("/"!=_t||"/"!=Rt[uo+1]){ri=Pr;continue}ri=Ge,uo++;break;case Dn:if("/"==_t){ri=kr;break}ri=Wi;continue;case Pr:if(er.scheme=vr.scheme,_t==Hi)er.username=vr.username,er.password=vr.password,er.host=vr.host,er.port=vr.port,er.path=J(vr.path),er.query=vr.query;else if("/"==_t||"\\"==_t&&er.isSpecial())ri=Yt;else if("?"==_t)er.username=vr.username,er.password=vr.password,er.host=vr.host,er.port=vr.port,er.path=J(vr.path),er.query="",ri=vo;else{if("#"!=_t){er.username=vr.username,er.password=vr.password,er.host=vr.host,er.port=vr.port,er.path=J(vr.path),er.path.length--,ri=Wi;continue}er.username=vr.username,er.password=vr.password,er.host=vr.host,er.port=vr.port,er.path=J(vr.path),er.query=vr.query,er.fragment="",ri=Co}break;case Yt:if(!er.isSpecial()||"/"!=_t&&"\\"!=_t){if("/"!=_t){er.username=vr.username,er.password=vr.password,er.host=vr.host,er.port=vr.port,ri=Wi;continue}ri=kr}else ri=Ge;break;case _n:if(ri=Ge,"/"!=_t||"/"!=Pe(Ci,uo+1))continue;uo++;break;case Ge:if("/"!=_t&&"\\"!=_t){ri=kr;continue}break;case kr:if("@"==_t){$o&&(Ci="%40"+Ci),$o=!0,mt=Z(Ci);for(var on=0;on<mt.length;on++){var si=mt[on];if(":"!=si||Ar){var Vi=_i(si,Jr);Ar?er.password+=Vi:er.username+=Vi}else Ar=!0}Ci=""}else if(_t==Hi||"/"==_t||"?"==_t||"#"==_t||"\\"==_t&&er.isSpecial()){if($o&&""==Ci)return"Invalid authority";uo-=Z(Ci).length+1,Ci="",ri=mi}else Ci+=_t;break;case mi:case An:if(lr&&"file"==er.scheme){ri=Fn;continue}if(":"!=_t||tr){if(_t==Hi||"/"==_t||"?"==_t||"#"==_t||"\\"==_t&&er.isSpecial()){if(er.isSpecial()&&""==Ci)return Zn;if(lr&&""==Ci&&(er.includesCredentials()||null!==er.port))return;if(jt=er.parseHost(Ci))return jt;if(Ci="",ri=ar,lr)return;continue}"["==_t?tr=!0:"]"==_t&&(tr=!1),Ci+=_t}else{if(""==Ci)return Zn;if(jt=er.parseHost(Ci))return jt;if(Ci="",ri=Er,lr==An)return}break;case Er:if(!je(Mr,_t)){if(_t==Hi||"/"==_t||"?"==_t||"#"==_t||"\\"==_t&&er.isSpecial()||lr){if(""!=Ci){var _o=Ve(Ci,10);if(_o>65535)return Ur;er.port=er.isSpecial()&&_o===wi[er.scheme]?null:_o,Ci=""}if(lr)return;ri=ar;continue}return Ur}Ci+=_t;break;case Wr:if(er.scheme="file","/"==_t||"\\"==_t)ri=dr;else{if(!vr||"file"!=vr.scheme){ri=Wi;continue}if(_t==Hi)er.host=vr.host,er.path=J(vr.path),er.query=vr.query;else if("?"==_t)er.host=vr.host,er.path=J(vr.path),er.query="",ri=vo;else{if("#"!=_t){Dr(He(J(Rt,uo),""))||(er.host=vr.host,er.path=J(vr.path),er.shortenPath()),ri=Wi;continue}er.host=vr.host,er.path=J(vr.path),er.query=vr.query,er.fragment="",ri=Co}}break;case dr:if("/"==_t||"\\"==_t){ri=Fn;break}vr&&"file"==vr.scheme&&!Dr(He(J(Rt,uo),""))&&(br(vr.path[0],!0)?tn(er.path,vr.path[0]):er.host=vr.host),ri=Wi;continue;case Fn:if(_t==Hi||"/"==_t||"\\"==_t||"?"==_t||"#"==_t){if(!lr&&br(Ci))ri=Wi;else if(""==Ci){if(er.host="",lr)return;ri=ar}else{if(jt=er.parseHost(Ci))return jt;if("localhost"==er.host&&(er.host=""),lr)return;Ci="",ri=ar}continue}Ci+=_t;break;case ar:if(er.isSpecial()){if(ri=Wi,"/"!=_t&&"\\"!=_t)continue}else if(lr||"?"!=_t)if(lr||"#"!=_t){if(_t!=Hi&&(ri=Wi,"/"!=_t))continue}else er.fragment="",ri=Co;else er.query="",ri=vo;break;case Wi:if(_t==Hi||"/"==_t||"\\"==_t&&er.isSpecial()||!lr&&("?"==_t||"#"==_t)){if(yn(Ci)?(er.shortenPath(),"/"!=_t&&!("\\"==_t&&er.isSpecial())&&tn(er.path,"")):gn(Ci)?"/"!=_t&&!("\\"==_t&&er.isSpecial())&&tn(er.path,""):("file"==er.scheme&&!er.path.length&&br(Ci)&&(er.host&&(er.host=""),Ci=Pe(Ci,0)+":"),tn(er.path,Ci)),Ci="","file"==er.scheme&&(_t==Hi||"?"==_t||"#"==_t))for(;er.path.length>1&&""===er.path[0];)Zt(er.path);"?"==_t?(er.query="",ri=vo):"#"==_t&&(er.fragment="",ri=Co)}else Ci+=_i(_t,Gn);break;case lo:"?"==_t?(er.query="",ri=vo):"#"==_t?(er.fragment="",ri=Co):_t!=Hi&&(er.path[0]+=_i(_t,rr));break;case vo:lr||"#"!=_t?_t!=Hi&&("'"==_t&&er.isSpecial()?er.query+="%27":er.query+="#"==_t?"%23":_i(_t,rr)):(er.fragment="",ri=Co);break;case Co:_t!=Hi&&(er.fragment+=_i(_t,Fr))}uo++}},parseHost:function(Bn){var lr,vr,er;if("["==Pe(Bn,0)){if("]"!=Pe(Bn,Bn.length-1)||!(lr=function(Bn){var uo,Ci,$o,tr,Ar,Rt,_t,lr=[0,0,0,0,0,0,0,0],vr=0,er=null,ri=0,mt=function(){return Pe(Bn,ri)};if(":"==mt()){if(":"!=Pe(Bn,1))return;ri+=2,er=++vr}for(;mt();){if(8==vr)return;if(":"!=mt()){for(uo=Ci=0;Ci<4&&je($n,mt());)uo=16*uo+Ve(mt(),16),ri++,Ci++;if("."==mt()){if(0==Ci||(ri-=Ci,vr>6))return;for($o=0;mt();){if(tr=null,$o>0){if(!("."==mt()&&$o<4))return;ri++}if(!je(Mr,mt()))return;for(;je(Mr,mt());){if(Ar=Ve(mt(),10),null===tr)tr=Ar;else{if(0==tr)return;tr=10*tr+Ar}if(tr>255)return;ri++}lr[vr]=256*lr[vr]+tr,(2==++$o||4==$o)&&vr++}if(4!=$o)return;break}if(":"==mt()){if(ri++,!mt())return}else if(mt())return;lr[vr++]=uo}else{if(null!==er)return;ri++,er=++vr}}if(null!==er)for(Rt=vr-er,vr=7;0!=vr&&Rt>0;)_t=lr[vr],lr[vr--]=lr[er+Rt-1],lr[er+--Rt]=_t;else if(8!=vr)return;return lr}(Bt(Bn,1,-1))))return Zn;this.host=lr}else if(this.isSpecial()){if(Bn=ee(Bn),je(Br,Bn)||null===(lr=function(Bn){var vr,er,ri,uo,Ci,$o,tr,lr=Ut(Bn,".");if(lr.length&&""==lr[lr.length-1]&&lr.length--,(vr=lr.length)>4)return Bn;for(er=[],ri=0;ri<vr;ri++){if(""==(uo=lr[ri]))return Bn;if(Ci=10,uo.length>1&&"0"==Pe(uo,0)&&(Ci=je(Kr,uo)?16:8,uo=Bt(uo,8==Ci?1:2)),""===uo)$o=0;else{if(!je(10==Ci?Nn:8==Ci?ei:$n,uo))return Bn;$o=Ve(uo,Ci)}tn(er,$o)}for(ri=0;ri<vr;ri++)if($o=er[ri],ri==vr-1){if($o>=Be(256,5-vr))return null}else if($o>255)return null;for(tr=it(er),ri=0;ri<er.length;ri++)tr+=er[ri]*Be(256,3-ri);return tr}(Bn)))return Zn;this.host=lr}else{if(je(Yr,Bn))return Zn;for(lr="",vr=Z(Bn),er=0;er<vr.length;er++)lr+=_i(vr[er],rr);this.host=lr}},cannotHaveUsernamePasswordPort:function(){return!this.host||this.cannotBeABaseURL||"file"==this.scheme},includesCredentials:function(){return""!=this.username||""!=this.password},isSpecial:function(){return N(wi,this.scheme)},shortenPath:function(){var Bn=this.path,lr=Bn.length;lr&&("file"!=this.scheme||1!=lr||!br(Bn[0],!0))&&Bn.length--},serialize:function(){var Bn=this,lr=Bn.scheme,vr=Bn.username,er=Bn.password,ri=Bn.host,uo=Bn.port,Ci=Bn.path,$o=Bn.query,tr=Bn.fragment,Ar=lr+":";return null!==ri?(Ar+="//",Bn.includesCredentials()&&(Ar+=vr+(er?":"+er:"")+"@"),Ar+=zn(ri),null!==uo&&(Ar+=":"+uo)):"file"==lr&&(Ar+="//"),Ar+=Bn.cannotBeABaseURL?Ci[0]:Ci.length?"/"+He(Ci,"/"):"",null!==$o&&(Ar+="?"+$o),null!==tr&&(Ar+="#"+tr),Ar},setHref:function(Bn){var lr=this.parse(Bn);if(lr)throw lt(lr);this.searchParams.update()},getOrigin:function(){var Bn=this.scheme,lr=this.port;if("blob"==Bn)try{return new os(Bn.path[0]).origin}catch(vr){return"null"}return"file"!=Bn&&this.isSpecial()?Bn+"://"+zn(this.host)+(null!==lr?":"+lr:""):"null"},getProtocol:function(){return this.scheme+":"},setProtocol:function(Bn){this.parse(ue(Bn)+":",gr)},getUsername:function(){return this.username},setUsername:function(Bn){var lr=Z(ue(Bn));if(!this.cannotHaveUsernamePasswordPort()){this.username="";for(var vr=0;vr<lr.length;vr++)this.username+=_i(lr[vr],Jr)}},getPassword:function(){return this.password},setPassword:function(Bn){var lr=Z(ue(Bn));if(!this.cannotHaveUsernamePasswordPort()){this.password="";for(var vr=0;vr<lr.length;vr++)this.password+=_i(lr[vr],Jr)}},getHost:function(){var Bn=this.host,lr=this.port;return null===Bn?"":null===lr?zn(Bn):zn(Bn)+":"+lr},setHost:function(Bn){this.cannotBeABaseURL||this.parse(Bn,mi)},getHostname:function(){var Bn=this.host;return null===Bn?"":zn(Bn)},setHostname:function(Bn){this.cannotBeABaseURL||this.parse(Bn,An)},getPort:function(){var Bn=this.port;return null===Bn?"":ue(Bn)},setPort:function(Bn){this.cannotHaveUsernamePasswordPort()||(""==(Bn=ue(Bn))?this.port=null:this.parse(Bn,Er))},getPathname:function(){var Bn=this.path;return this.cannotBeABaseURL?Bn[0]:Bn.length?"/"+He(Bn,"/"):""},setPathname:function(Bn){this.cannotBeABaseURL||(this.path=[],this.parse(Bn,ar))},getSearch:function(){var Bn=this.query;return Bn?"?"+Bn:""},setSearch:function(Bn){""==(Bn=ue(Bn))?this.query=null:("?"==Pe(Bn,0)&&(Bn=Bt(Bn,1)),this.query="",this.parse(Bn,vo)),this.searchParams.update()},getSearchParams:function(){return this.searchParams.facade},getHash:function(){var Bn=this.fragment;return Bn?"#"+Bn:""},setHash:function(Bn){""!=(Bn=ue(Bn))?("#"==Pe(Bn,0)&&(Bn=Bt(Bn,1)),this.fragment="",this.parse(Bn,Co)):this.fragment=null},update:function(){this.query=this.searchParams.serialize()||null}};var os=function(lr){var vr=A(this,jo),er=H(arguments.length,1)>1?arguments[1]:void 0,ri=ie(vr,new Gi(lr,!1,er));u||(vr.href=ri.serialize(),vr.origin=ri.getOrigin(),vr.protocol=ri.getProtocol(),vr.username=ri.getUsername(),vr.password=ri.getPassword(),vr.host=ri.getHost(),vr.hostname=ri.getHostname(),vr.port=ri.getPort(),vr.pathname=ri.getPathname(),vr.search=ri.getSearch(),vr.searchParams=ri.getSearchParams(),vr.hash=ri.getHash())},jo=os.prototype,To=function(Bn,lr){return{get:function(){return he(this)[Bn]()},set:lr&&function(vr){return he(this)[lr](vr)},configurable:!0,enumerable:!0}};if(u&&(S(jo,"href",To("serialize","setHref")),S(jo,"origin",To("getOrigin")),S(jo,"protocol",To("getProtocol","setProtocol")),S(jo,"username",To("getUsername","setUsername")),S(jo,"password",To("getPassword","setPassword")),S(jo,"host",To("getHost","setHost")),S(jo,"hostname",To("getHostname","setHostname")),S(jo,"port",To("getPort","setPort")),S(jo,"pathname",To("getPathname","setPathname")),S(jo,"search",To("getSearch","setSearch")),S(jo,"searchParams",To("getSearchParams")),S(jo,"hash",To("getHash","setHash"))),y(jo,"toJSON",function(){return he(this).serialize()},{enumerable:!0}),y(jo,"toString",function(){return he(this).serialize()},{enumerable:!0}),ce){var Mi=ce.createObjectURL,li=ce.revokeObjectURL;Mi&&y(os,"createObjectURL",e(Mi,ce)),li&&y(os,"revokeObjectURL",e(li,ce))}ae(os,"URL"),r({global:!0,constructor:!0,forced:!p,sham:!u},{URL:os})},95981:(v,T,i)=>{i(80504)},71324:()=>{},75242:(v,T,i)=>{var r=i(74771);v.exports=r},10323:(v,T,i)=>{var r=i(8412);v.exports=r},99940:(v,T,i)=>{var r=i(399);v.exports=r},89919:(v,T,i)=>{var r=i(98812);v.exports=r},14869:(v,T,i)=>{var r=i(33195);v.exports=r},4475:(v,T,i)=>{var r=i(46332);v.exports=r},38762:(v,T,i)=>{var r=i(42618);v.exports=r},8748:(v,T,i)=>{var r=i(63791);i(33089),v.exports=r},47506:(v,T,i)=>{var r=i(27959);v.exports=r},71873:(v,T,i)=>{var r=i(69029);v.exports=r},61599:(v,T,i)=>{var r=i(28924);v.exports=r},34097:(v,T,i)=>{i(33089);var r=i(35329),u=i(80112),p=i(23336),d=i(99940),e=Array.prototype,_={DOMTokenList:!0,NodeList:!0};v.exports=function(y){var S=y.entries;return y===e||p(e,y)&&S===e.entries||u(_,r(y))?d:S}},15149:(v,T,i)=>{var r=i(98709);v.exports=r},83361:(v,T,i)=>{var r=i(65991);v.exports=r},19095:(v,T,i)=>{var r=i(64158);v.exports=r},71420:(v,T,i)=>{var r=i(91799);v.exports=r},13178:(v,T,i)=>{var r=i(26155);v.exports=r},52049:(v,T,i)=>{i(33089);var r=i(35329),u=i(80112),p=i(23336),d=i(89919),e=Array.prototype,_={DOMTokenList:!0,NodeList:!0};v.exports=function(y){var S=y.forEach;return y===e||p(e,y)&&S===e.forEach||u(_,r(y))?d:S}},83655:(v,T,i)=>{var r=i(33758);v.exports=r},87054:(v,T,i)=>{var r=i(7592);v.exports=r},51946:(v,T,i)=>{i(33089);var r=i(35329),u=i(80112),p=i(23336),d=i(14869),e=Array.prototype,_={DOMTokenList:!0,NodeList:!0};v.exports=function(y){var S=y.keys;return y===e||p(e,y)&&S===e.keys||u(_,r(y))?d:S}},40764:(v,T,i)=>{var r=i(17480);v.exports=r},81214:(v,T,i)=>{var r=i(20681);v.exports=r},50881:(v,T,i)=>{var r=i(90949);v.exports=r},38813:(v,T,i)=>{var r=i(99316);v.exports=r},45284:(v,T,i)=>{var r=i(62212);v.exports=r},70157:(v,T,i)=>{var r=i(49073);v.exports=r},3502:(v,T,i)=>{var r=i(24146);v.exports=r},81610:(v,T,i)=>{var r=i(40104);v.exports=r},19543:(v,T,i)=>{var r=i(3555);v.exports=r},74046:(v,T,i)=>{var r=i(68333);v.exports=r},13731:(v,T,i)=>{var r=i(65786);v.exports=r},80129:(v,T,i)=>{i(33089);var r=i(35329),u=i(80112),p=i(23336),d=i(4475),e=Array.prototype,_={DOMTokenList:!0,NodeList:!0};v.exports=function(y){var S=y.values;return y===e||p(e,y)&&S===e.values||u(_,r(y))?d:S}},43720:(v,T,i)=>{var r=i(66306);v.exports=r},640:(v,T,i)=>{var r=i(31845);i(33089),v.exports=r},50320:(v,T,i)=>{var r=i(44168);v.exports=r},93006:(v,T,i)=>{var r=i(25852);v.exports=r},36226:(v,T,i)=>{var r=i(24457);v.exports=r},21968:(v,T,i)=>{var r=i(99671);v.exports=r},15554:(v,T,i)=>{var r=i(35161);v.exports=r},87259:(v,T,i)=>{var r=i(38007);v.exports=r},62021:(v,T,i)=>{var r=i(57432);v.exports=r},57682:(v,T,i)=>{var r=i(36541);v.exports=r},94222:(v,T,i)=>{var r=i(17303);v.exports=r},1162:(v,T,i)=>{var r=i(62149);v.exports=r},82805:(v,T,i)=>{var r=i(86537);v.exports=r},70809:(v,T,i)=>{var r=i(79553);v.exports=r},26498:(v,T,i)=>{var r=i(80092);i(33089),v.exports=r},44850:(v,T,i)=>{var r=i(472);v.exports=r},9634:(v,T,i)=>{var r=i(4678);v.exports=r},12118:(v,T,i)=>{i(69280);var r=i(13544);v.exports=r.setTimeout},96551:(v,T,i)=>{var r=i(61697);i(33089),v.exports=r},98908:(v,T,i)=>{var r=i(42497);i(33089),v.exports=r},44675:(v,T,i)=>{var r=i(41530);i(33089),v.exports=r},70906:(v,T,i)=>{var r=i(75081);v.exports=r},95050:(v,T,i)=>{var r=i(58255);i(33089),v.exports=r},41530:(v,T,i)=>{i(26953);var r=i(13544);v.exports=r.URLSearchParams},75081:(v,T,i)=>{i(95981),i(71324),i(26953);var r=i(13544);v.exports=r.URL},71577:function(){var v;v="undefined"!=typeof self?self:this,function(i){var r_searchParams="URLSearchParams"in v,r_iterable="Symbol"in v&&"iterator"in Symbol,r_blob="FileReader"in v&&"Blob"in v&&function(){try{return new Blob,!0}catch(De){return!1}}(),r_formData="FormData"in v,r_arrayBuffer="ArrayBuffer"in v;if(r_arrayBuffer)var p=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],d=ArrayBuffer.isView||function(De){return De&&p.indexOf(Object.prototype.toString.call(De))>-1};function e(De){if("string"!=typeof De&&(De=String(De)),/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(De))throw new TypeError("Invalid character in header field name");return De.toLowerCase()}function _(De){return"string"!=typeof De&&(De=String(De)),De}function y(De){var ce={next:function(){var lt=De.shift();return{done:void 0===lt,value:lt}}};return r_iterable&&(ce[Symbol.iterator]=function(){return ce}),ce}function S(De){this.map={},De instanceof S?De.forEach(function(ce,lt){this.append(lt,ce)},this):Array.isArray(De)?De.forEach(function(ce){this.append(ce[0],ce[1])},this):De&&Object.getOwnPropertyNames(De).forEach(function(ce){this.append(ce,De[ce])},this)}function A(De){if(De.bodyUsed)return Promise.reject(new TypeError("Already read"));De.bodyUsed=!0}function N(De){return new Promise(function(ce,lt){De.onload=function(){ce(De.result)},De.onerror=function(){lt(De.error)}})}function L(De){var ce=new FileReader,lt=N(ce);return ce.readAsArrayBuffer(De),lt}function K(De){if(De.slice)return De.slice(0);var ce=new Uint8Array(De.byteLength);return ce.set(new Uint8Array(De)),ce.buffer}function ee(){return this.bodyUsed=!1,this._initBody=function(De){this._bodyInit=De,De?"string"==typeof De?this._bodyText=De:r_blob&&Blob.prototype.isPrototypeOf(De)?this._bodyBlob=De:r_formData&&FormData.prototype.isPrototypeOf(De)?this._bodyFormData=De:r_searchParams&&URLSearchParams.prototype.isPrototypeOf(De)?this._bodyText=De.toString():r_arrayBuffer&&r_blob&&function(De){return De&&DataView.prototype.isPrototypeOf(De)}(De)?(this._bodyArrayBuffer=K(De.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer])):r_arrayBuffer&&(ArrayBuffer.prototype.isPrototypeOf(De)||d(De))?this._bodyArrayBuffer=K(De):this._bodyText=De=Object.prototype.toString.call(De):this._bodyText="",this.headers.get("content-type")||("string"==typeof De?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):r_searchParams&&URLSearchParams.prototype.isPrototypeOf(De)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},r_blob&&(this.blob=function(){var De=A(this);if(De)return De;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this._bodyArrayBuffer?A(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(L)}),this.text=function(){var De=A(this);if(De)return De;if(this._bodyBlob)return function(De){var ce=new FileReader,lt=N(ce);return ce.readAsText(De),lt}(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(function(De){for(var ce=new Uint8Array(De),lt=new Array(ce.length),Ve=0;Ve<ce.length;Ve++)lt[Ve]=String.fromCharCode(ce[Ve]);return lt.join("")}(this._bodyArrayBuffer));if(this._bodyFormData)throw new Error("could not read FormData body as text");return Promise.resolve(this._bodyText)},r_formData&&(this.formData=function(){return this.text().then(se)}),this.json=function(){return this.text().then(JSON.parse)},this}S.prototype.append=function(De,ce){De=e(De),ce=_(ce);var lt=this.map[De];this.map[De]=lt?lt+", "+ce:ce},S.prototype.delete=function(De){delete this.map[e(De)]},S.prototype.get=function(De){return De=e(De),this.has(De)?this.map[De]:null},S.prototype.has=function(De){return this.map.hasOwnProperty(e(De))},S.prototype.set=function(De,ce){this.map[e(De)]=_(ce)},S.prototype.forEach=function(De,ce){for(var lt in this.map)this.map.hasOwnProperty(lt)&&De.call(ce,this.map[lt],lt,this)},S.prototype.keys=function(){var De=[];return this.forEach(function(ce,lt){De.push(lt)}),y(De)},S.prototype.values=function(){var De=[];return this.forEach(function(ce){De.push(ce)}),y(De)},S.prototype.entries=function(){var De=[];return this.forEach(function(ce,lt){De.push([lt,ce])}),y(De)},r_iterable&&(S.prototype[Symbol.iterator]=S.prototype.entries);var ue=["DELETE","GET","HEAD","OPTIONS","POST","PUT"];function H(De,ce){var lt=(ce=ce||{}).body;if(De instanceof H){if(De.bodyUsed)throw new TypeError("Already read");this.url=De.url,this.credentials=De.credentials,ce.headers||(this.headers=new S(De.headers)),this.method=De.method,this.mode=De.mode,this.signal=De.signal,!lt&&null!=De._bodyInit&&(lt=De._bodyInit,De.bodyUsed=!0)}else this.url=String(De);if(this.credentials=ce.credentials||this.credentials||"same-origin",(ce.headers||!this.headers)&&(this.headers=new S(ce.headers)),this.method=function(De){var ce=De.toUpperCase();return ue.indexOf(ce)>-1?ce:De}(ce.method||this.method||"GET"),this.mode=ce.mode||this.mode||null,this.signal=ce.signal||this.signal,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&lt)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(lt)}function se(De){var ce=new FormData;return De.trim().split("&").forEach(function(lt){if(lt){var Ve=lt.split("="),ze=Ve.shift().replace(/\+/g," "),Be=Ve.join("=").replace(/\+/g," ");ce.append(decodeURIComponent(ze),decodeURIComponent(Be))}}),ce}function Ee(De){var ce=new S;return De.replace(/\r?\n[\t ]+/g," ").split(/\r?\n/).forEach(function(Ve){var ze=Ve.split(":"),Be=ze.shift().trim();if(Be){var Pe=ze.join(":").trim();ce.append(Be,Pe)}}),ce}function ie(De,ce){ce||(ce={}),this.type="default",this.status=void 0===ce.status?200:ce.status,this.ok=this.status>=200&&this.status<300,this.statusText="statusText"in ce?ce.statusText:"OK",this.headers=new S(ce.headers),this.url=ce.url||"",this._initBody(De)}H.prototype.clone=function(){return new H(this,{body:this._bodyInit})},ee.call(H.prototype),ee.call(ie.prototype),ie.prototype.clone=function(){return new ie(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new S(this.headers),url:this.url})},ie.error=function(){var De=new ie(null,{status:0,statusText:""});return De.type="error",De};var he=[301,302,303,307,308];ie.redirect=function(De,ce){if(-1===he.indexOf(ce))throw new RangeError("Invalid status code");return new ie(null,{status:ce,headers:{location:De}})},i.DOMException=v.DOMException;try{new i.DOMException}catch(De){i.DOMException=function(ce,lt){this.message=ce,this.name=lt;var Ve=Error(ce);this.stack=Ve.stack},i.DOMException.prototype=Object.create(Error.prototype),i.DOMException.prototype.constructor=i.DOMException}function ge(De,ce){return new Promise(function(lt,Ve){var ze=new H(De,ce);if(ze.signal&&ze.signal.aborted)return Ve(new i.DOMException("Aborted","AbortError"));var Be=new XMLHttpRequest;function Pe(){Be.abort()}Be.onload=function(){var je={status:Be.status,statusText:Be.statusText,headers:Ee(Be.getAllResponseHeaders()||"")};je.url="responseURL"in Be?Be.responseURL:je.headers.get("X-Request-URL"),lt(new ie("response"in Be?Be.response:Be.responseText,je))},Be.onerror=function(){Ve(new TypeError("Network request failed"))},Be.ontimeout=function(){Ve(new TypeError("Network request failed"))},Be.onabort=function(){Ve(new i.DOMException("Aborted","AbortError"))},Be.open(ze.method,ze.url,!0),"include"===ze.credentials?Be.withCredentials=!0:"omit"===ze.credentials&&(Be.withCredentials=!1),"responseType"in Be&&r_blob&&(Be.responseType="blob"),ze.headers.forEach(function(je,He){Be.setRequestHeader(He,je)}),ze.signal&&(ze.signal.addEventListener("abort",Pe),Be.onreadystatechange=function(){4===Be.readyState&&ze.signal.removeEventListener("abort",Pe)}),Be.send(void 0===ze._bodyInit?null:ze._bodyInit)})}ge.polyfill=!0,v.fetch||(v.fetch=ge,v.Headers=S,v.Request=H,v.Response=ie),i.Headers=S,i.Request=H,i.Response=ie,i.fetch=ge,Object.defineProperty(i,"__esModule",{value:!0})}({})},52243:function(v){var T;T="undefined"!=typeof global?global:this,v.exports=function(T){if(T.CSS&&T.CSS.escape)return T.CSS.escape;var i=function(r){if(0==arguments.length)throw new TypeError("`CSS.escape` requires an argument.");for(var e,u=String(r),p=u.length,d=-1,_="",y=u.charCodeAt(0);++d<p;)0!=(e=u.charCodeAt(d))?_+=e>=1&&e<=31||127==e||0==d&&e>=48&&e<=57||1==d&&e>=48&&e<=57&&45==y?"\\"+e.toString(16)+" ":0==d&&1==p&&45==e||!(e>=128||45==e||95==e||e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122)?"\\"+u.charAt(d):u.charAt(d):_+="\ufffd";return _};return T.CSS||(T.CSS={}),T.CSS.escape=i,i}(T)},89225:v=>{"use strict";var T=function(ae){return!(!(ue=ae)||"object"!=typeof ue||function(ue){var ae=Object.prototype.toString.call(ue);return"[object RegExp]"===ae||"[object Date]"===ae||function(ue){return ue.$$typeof===p}(ue)}(ae));var ue},p="function"==typeof Symbol&&Symbol.for?Symbol.for("react.element"):60103;function _(ue,ae){return!1!==ae.clone&&ae.isMergeableObject(ue)?K(function(ue){return Array.isArray(ue)?[]:{}}(ue),ue,ae):ue}function y(ue,ae,H){return ue.concat(ae).map(function(se){return _(se,H)})}function N(ue){return Object.keys(ue).concat(function(ue){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(ue).filter(function(ae){return ue.propertyIsEnumerable(ae)}):[]}(ue))}function L(ue,ae){try{return ae in ue}catch(H){return!1}}function K(ue,ae,H){(H=H||{}).arrayMerge=H.arrayMerge||y,H.isMergeableObject=H.isMergeableObject||T,H.cloneUnlessOtherwiseSpecified=_;var se=Array.isArray(ae);return se===Array.isArray(ue)?se?H.arrayMerge(ue,ae,H):function(ue,ae,H){var se={};return H.isMergeableObject(ue)&&N(ue).forEach(function(Ee){se[Ee]=_(ue[Ee],H)}),N(ae).forEach(function(Ee){(function(ue,ae){return L(ue,ae)&&!(Object.hasOwnProperty.call(ue,ae)&&Object.propertyIsEnumerable.call(ue,ae))})(ue,Ee)||(se[Ee]=L(ue,Ee)&&H.isMergeableObject(ae[Ee])?function(ue,ae){if(!ae.customMerge)return K;var H=ae.customMerge(ue);return"function"==typeof H?H:K}(Ee,H)(ue[Ee],ae[Ee],H):_(ae[Ee],H))}),se}(ue,ae,H):_(ae,H)}K.all=function(ae,H){if(!Array.isArray(ae))throw new Error("first argument should be an array");return ae.reduce(function(se,Ee){return K(se,Ee,H)},{})},v.exports=K},97057:(v,T,i)=>{"use strict";i.d(T,{qY:()=>Z});var u=function(Ee,ie,he){this.name=Ee,this.version=ie,this.os=he,this.type="browser"},p=function(Ee){this.version=Ee,this.type="node",this.name="node",this.os=process.platform},d=function(Ee,ie,he,ge){this.name=Ee,this.version=ie,this.os=he,this.bot=ge,this.type="bot-device"},e=function(){this.type="bot",this.bot=!0,this.name="bot",this.version=null,this.os=null},_=function(){this.type="react-native",this.name="react-native",this.version=null,this.os=null},S=/(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask\ Jeeves\/Teoma|ia_archiver)/,N=[["aol",/AOLShield\/([0-9\._]+)/],["edge",/Edge\/([0-9\._]+)/],["edge-ios",/EdgiOS\/([0-9\._]+)/],["yandexbrowser",/YaBrowser\/([0-9\._]+)/],["kakaotalk",/KAKAOTALK\s([0-9\.]+)/],["samsung",/SamsungBrowser\/([0-9\.]+)/],["silk",/\bSilk\/([0-9._-]+)\b/],["miui",/MiuiBrowser\/([0-9\.]+)$/],["beaker",/BeakerBrowser\/([0-9\.]+)/],["edge-chromium",/EdgA?\/([0-9\.]+)/],["chromium-webview",/(?!Chrom.*OPR)wv\).*Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/],["chrome",/(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/],["phantomjs",/PhantomJS\/([0-9\.]+)(:?\s|$)/],["crios",/CriOS\/([0-9\.]+)(:?\s|$)/],["firefox",/Firefox\/([0-9\.]+)(?:\s|$)/],["fxios",/FxiOS\/([0-9\.]+)/],["opera-mini",/Opera Mini.*Version\/([0-9\.]+)/],["opera",/Opera\/([0-9\.]+)(?:\s|$)/],["opera",/OPR\/([0-9\.]+)(:?\s|$)/],["ie",/Trident\/7\.0.*rv\:([0-9\.]+).*\).*Gecko$/],["ie",/MSIE\s([0-9\.]+);.*Trident\/[4-7].0/],["ie",/MSIE\s(7\.0)/],["bb10",/BB10;\sTouch.*Version\/([0-9\.]+)/],["android",/Android\s([0-9\.]+)/],["ios",/Version\/([0-9\._]+).*Mobile.*Safari.*/],["safari",/Version\/([0-9\._]+).*Safari/],["facebook",/FBAV\/([0-9\.]+)/],["instagram",/Instagram\s([0-9\.]+)/],["ios-webview",/AppleWebKit\/([0-9\.]+).*Mobile/],["ios-webview",/AppleWebKit\/([0-9\.]+).*Gecko\)$/],["searchbot",/alexa|bot|crawl(er|ing)|facebookexternalhit|feedburner|google web preview|nagios|postrank|pingdom|slurp|spider|yahoo!|yandex/]],L=[["iOS",/iP(hone|od|ad)/],["Android OS",/Android/],["BlackBerry OS",/BlackBerry|BB10/],["Windows Mobile",/IEMobile/],["Amazon OS",/Kindle/],["Windows 3.11",/Win16/],["Windows 95",/(Windows 95)|(Win95)|(Windows_95)/],["Windows 98",/(Windows 98)|(Win98)/],["Windows 2000",/(Windows NT 5.0)|(Windows 2000)/],["Windows XP",/(Windows NT 5.1)|(Windows XP)/],["Windows Server 2003",/(Windows NT 5.2)/],["Windows Vista",/(Windows NT 6.0)/],["Windows 7",/(Windows NT 6.1)/],["Windows 8",/(Windows NT 6.2)/],["Windows 8.1",/(Windows NT 6.3)/],["Windows 10",/(Windows NT 10.0)/],["Windows ME",/Windows ME/],["Open BSD",/OpenBSD/],["Sun OS",/SunOS/],["Chrome OS",/CrOS/],["Linux",/(Linux)|(X11)/],["Mac OS",/(Mac_PowerPC)|(Macintosh)/],["QNX",/QNX/],["BeOS",/BeOS/],["OS/2",/OS\/2/]];function Z(se){return se?ee(se):"undefined"==typeof document&&"undefined"!=typeof navigator&&"ReactNative"===navigator.product?new _:"undefined"!=typeof navigator?ee(navigator.userAgent):"undefined"!=typeof process&&process.version?new p(process.version.slice(1)):null}function ee(se){var Ee=function(se){return""!==se&&N.reduce(function(Ee,ie){var he=ie[0];if(Ee)return Ee;var De=ie[1].exec(se);return!!De&&[he,De]},!1)}(se);if(!Ee)return null;var ie=Ee[0],he=Ee[1];if("searchbot"===ie)return new e;var ge=he[1]&&he[1].split(/[._]/).slice(0,3);ge?ge.length<3&&(ge=function(){for(var se=0,Ee=0,ie=arguments.length;Ee<ie;Ee++)se+=arguments[Ee].length;var he=Array(se),ge=0;for(Ee=0;Ee<ie;Ee++)for(var De=arguments[Ee],ce=0,lt=De.length;ce<lt;ce++,ge++)he[ge]=De[ce];return he}(ge,function(se){for(var Ee=[],ie=0;ie<se;ie++)Ee.push("0");return Ee}(3-ge.length))):ge=[];var De=ge.join("."),ce=function(se){for(var Ee=0,ie=L.length;Ee<ie;Ee++){var he=L[Ee],ge=he[0];if(he[1].exec(se))return ge}return null}(se),lt=S.exec(se);return lt&&lt[1]?new d(ie,De,ce,lt[1]):new u(ie,De,ce)}},23358:function(v){v.exports=function(){"use strict";var i=Object.hasOwnProperty,r=Object.setPrototypeOf,u=Object.isFrozen,p=Object.getPrototypeOf,d=Object.getOwnPropertyDescriptor,e=Object.freeze,_=Object.seal,y=Object.create,S="undefined"!=typeof Reflect&&Reflect,A=S.apply,N=S.construct;A||(A=function(Nn,$n,Br){return Nn.apply($n,Br)}),e||(e=function(Nn){return Nn}),_||(_=function(Nn){return Nn}),N||(N=function(Nn,$n){return new(Function.prototype.bind.apply(Nn,[null].concat(function(ei){if(Array.isArray(ei)){for(var Nn=0,$n=Array(ei.length);Nn<ei.length;Nn++)$n[Nn]=ei[Nn];return $n}return Array.from(ei)}($n))))});var ei,L=ie(Array.prototype.forEach),Z=ie(Array.prototype.pop),J=ie(Array.prototype.push),K=ie(String.prototype.toLowerCase),ee=ie(String.prototype.match),ue=ie(String.prototype.replace),ae=ie(String.prototype.indexOf),H=ie(String.prototype.trim),se=ie(RegExp.prototype.test),Ee=(ei=TypeError,function(){for(var Nn=arguments.length,$n=Array(Nn),Br=0;Br<Nn;Br++)$n[Br]=arguments[Br];return N(ei,$n)});function ie(ei){return function(Nn){for(var $n=arguments.length,Br=Array($n>1?$n-1:0),Yr=1;Yr<$n;Yr++)Br[Yr-1]=arguments[Yr];return A(ei,Nn,Br)}}function ge(ei,Nn){r&&r(ei,null);for(var $n=Nn.length;$n--;){var Br=Nn[$n];if("string"==typeof Br){var Yr=K(Br);Yr!==Br&&(u(Nn)||(Nn[$n]=Yr),Br=Yr)}ei[Br]=!0}return ei}function De(ei){var Nn=y(null),$n=void 0;for($n in ei)A(i,ei,[$n])&&(Nn[$n]=ei[$n]);return Nn}function ce(ei,Nn){for(;null!==ei;){var $n=d(ei,Nn);if($n){if($n.get)return ie($n.get);if("function"==typeof $n.value)return ie($n.value)}ei=p(ei)}return function(Yr){return console.warn("fallback value for",Yr),null}}var lt=e(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),Ve=e(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),ze=e(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),Be=e(["animate","color-profile","cursor","discard","fedropshadow","feimage","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),Pe=e(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover"]),je=e(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),He=e(["#text"]),Vt=e(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","xmlns","slot"]),it=e(["accent-height","accumulate","additive","alignment-baseline","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","targetx","targety","transform","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),tn=e(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),It=e(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),Zt=_(/\{\{[\s\S]*|[\s\S]*\}\}/gm),Ut=_(/<%[\s\S]*|[\s\S]*%>/gm),Bt=_(/^data-[\-\w.\u00B7-\uFFFF]/),bt=_(/^aria-[\-\w]+$/),Gt=_(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),xt=_(/^(?:\w+script|data):/i),Xt=_(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),Zn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(ei){return typeof ei}:function(ei){return ei&&"function"==typeof Symbol&&ei.constructor===Symbol&&ei!==Symbol.prototype?"symbol":typeof ei};function Ur(ei){if(Array.isArray(ei)){for(var Nn=0,$n=Array(ei.length);Nn<ei.length;Nn++)$n[Nn]=ei[Nn];return $n}return Array.from(ei)}var di=function(){return"undefined"==typeof window?null:window},Lr=function(Nn,$n){if("object"!==(void 0===Nn?"undefined":Zn(Nn))||"function"!=typeof Nn.createPolicy)return null;var Br=null,Yr="data-tt-policy-suffix";$n.currentScript&&$n.currentScript.hasAttribute(Yr)&&(Br=$n.currentScript.getAttribute(Yr));var fi="dompurify"+(Br?"#"+Br:"");try{return Nn.createPolicy(fi,{createHTML:function(Hi){return Hi}})}catch(ki){return console.warn("TrustedTypes policy "+fi+" could not be created."),null}};return function Mr(){var ei=arguments.length>0&&void 0!==arguments[0]?arguments[0]:di(),Nn=function($r){return Mr($r)};if(Nn.version="2.3.3",Nn.removed=[],!ei||!ei.document||9!==ei.document.nodeType)return Nn.isSupported=!1,Nn;var $n=ei.document,Br=ei.document,Yr=ei.DocumentFragment,fi=ei.HTMLTemplateElement,ki=ei.Node,Hi=ei.Element,Zr=ei.NodeFilter,Cn=ei.NamedNodeMap,Wt=void 0===Cn?ei.NamedNodeMap||ei.MozNamedAttrMap:Cn,zn=ei.Text,rr=ei.Comment,Fr=ei.DOMParser,Gn=ei.trustedTypes,Jr=Hi.prototype,_i=ce(Jr,"cloneNode"),wi=ce(Jr,"nextSibling"),br=ce(Jr,"childNodes"),Dr=ce(Jr,"parentNode");if("function"==typeof fi){var gn=Br.createElement("template");gn.content&&gn.content.ownerDocument&&(Br=gn.content.ownerDocument)}var yn=Lr(Gn,$n),gr=yn&&uo?yn.createHTML(""):"",Vn=Br.implementation,mr=Br.createNodeIterator,Dn=Br.createDocumentFragment,Pr=Br.getElementsByTagName,Yt=$n.importNode,_n={};try{_n=De(Br).documentMode?Br.documentMode:{}}catch(So){}var Ge={};Nn.isSupported="function"==typeof Dr&&Vn&&void 0!==Vn.createHTMLDocument&&9!==_n;var kr=Zt,mi=Ut,An=Bt,Er=bt,Wr=xt,dr=Xt,Fn=Gt,ar=null,Wi=ge({},[].concat(Ur(lt),Ur(Ve),Ur(ze),Ur(Pe),Ur(He))),lo=null,vo=ge({},[].concat(Ur(Vt),Ur(it),Ur(tn),Ur(It))),Co=null,Gi=null,os=!0,jo=!0,To=!1,Mi=!1,li=!1,Bn=!1,lr=!1,vr=!1,er=!1,ri=!0,uo=!1,Ci=!0,$o=!0,tr=!1,Ar={},Rt=null,_t=ge({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),mt=null,jt=ge({},["audio","video","img","source","image","track"]),on=null,si=ge({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Vi="http://www.w3.org/1998/Math/MathML",_o="http://www.w3.org/2000/svg",co="http://www.w3.org/1999/xhtml",Es=co,Zs=!1,ls=void 0,La=["application/xhtml+xml","text/html"],ta="text/html",Is=void 0,us=null,ya=Br.createElement("form"),el=function($r){us&&us===$r||((!$r||"object"!==(void 0===$r?"undefined":Zn($r)))&&($r={}),$r=De($r),ar="ALLOWED_TAGS"in $r?ge({},$r.ALLOWED_TAGS):Wi,lo="ALLOWED_ATTR"in $r?ge({},$r.ALLOWED_ATTR):vo,on="ADD_URI_SAFE_ATTR"in $r?ge(De(si),$r.ADD_URI_SAFE_ATTR):si,mt="ADD_DATA_URI_TAGS"in $r?ge(De(jt),$r.ADD_DATA_URI_TAGS):jt,Rt="FORBID_CONTENTS"in $r?ge({},$r.FORBID_CONTENTS):_t,Co="FORBID_TAGS"in $r?ge({},$r.FORBID_TAGS):{},Gi="FORBID_ATTR"in $r?ge({},$r.FORBID_ATTR):{},Ar="USE_PROFILES"in $r&&$r.USE_PROFILES,os=!1!==$r.ALLOW_ARIA_ATTR,jo=!1!==$r.ALLOW_DATA_ATTR,To=$r.ALLOW_UNKNOWN_PROTOCOLS||!1,Mi=$r.SAFE_FOR_TEMPLATES||!1,li=$r.WHOLE_DOCUMENT||!1,vr=$r.RETURN_DOM||!1,er=$r.RETURN_DOM_FRAGMENT||!1,ri=!1!==$r.RETURN_DOM_IMPORT,uo=$r.RETURN_TRUSTED_TYPE||!1,lr=$r.FORCE_BODY||!1,Ci=!1!==$r.SANITIZE_DOM,$o=!1!==$r.KEEP_CONTENT,tr=$r.IN_PLACE||!1,Fn=$r.ALLOWED_URI_REGEXP||Fn,Es=$r.NAMESPACE||co,ls=ls=-1===La.indexOf($r.PARSER_MEDIA_TYPE)?ta:$r.PARSER_MEDIA_TYPE,Is="application/xhtml+xml"===ls?function(to){return to}:K,Mi&&(jo=!1),er&&(vr=!0),Ar&&(ar=ge({},[].concat(Ur(He))),lo=[],!0===Ar.html&&(ge(ar,lt),ge(lo,Vt)),!0===Ar.svg&&(ge(ar,Ve),ge(lo,it),ge(lo,It)),!0===Ar.svgFilters&&(ge(ar,ze),ge(lo,it),ge(lo,It)),!0===Ar.mathMl&&(ge(ar,Pe),ge(lo,tn),ge(lo,It))),$r.ADD_TAGS&&(ar===Wi&&(ar=De(ar)),ge(ar,$r.ADD_TAGS)),$r.ADD_ATTR&&(lo===vo&&(lo=De(lo)),ge(lo,$r.ADD_ATTR)),$r.ADD_URI_SAFE_ATTR&&ge(on,$r.ADD_URI_SAFE_ATTR),$r.FORBID_CONTENTS&&(Rt===_t&&(Rt=De(Rt)),ge(Rt,$r.FORBID_CONTENTS)),$o&&(ar["#text"]=!0),li&&ge(ar,["html","head","body"]),ar.table&&(ge(ar,["tbody"]),delete Co.tbody),e&&e($r),us=$r)},ca=ge({},["mi","mo","mn","ms","mtext"]),$s=ge({},["foreignobject","desc","title","annotation-xml"]),da=ge({},Ve);ge(da,ze),ge(da,Be);var Il=ge({},Pe);ge(Il,je);var fo=function($r){var to=Dr($r);(!to||!to.tagName)&&(to={namespaceURI:co,tagName:"template"});var tt=K($r.tagName),sn=K(to.tagName);if($r.namespaceURI===_o)return to.namespaceURI===co?"svg"===tt:to.namespaceURI===Vi?"svg"===tt&&("annotation-xml"===sn||ca[sn]):Boolean(da[tt]);if($r.namespaceURI===Vi)return to.namespaceURI===co?"math"===tt:to.namespaceURI===_o?"math"===tt&&$s[sn]:Boolean(Il[tt]);if($r.namespaceURI===co){if(to.namespaceURI===_o&&!$s[sn]||to.namespaceURI===Vi&&!ca[sn])return!1;var ne=ge({},["title","style","font","a","script"]);return!Il[tt]&&(ne[tt]||!da[tt])}return!1},Ya=function($r){J(Nn.removed,{element:$r});try{$r.parentNode.removeChild($r)}catch(to){try{$r.outerHTML=gr}catch(tt){$r.remove()}}},Ao=function($r,to){try{J(Nn.removed,{attribute:to.getAttributeNode($r),from:to})}catch(tt){J(Nn.removed,{attribute:null,from:to})}if(to.removeAttribute($r),"is"===$r&&!lo[$r])if(vr||er)try{Ya(to)}catch(tt){}else try{to.setAttribute($r,"")}catch(tt){}},fs=function($r){var to=void 0,tt=void 0;if(lr)$r="<remove></remove>"+$r;else{var sn=ee($r,/^[\r\n\t ]+/);tt=sn&&sn[0]}"application/xhtml+xml"===ls&&($r='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+$r+"</body></html>");var ne=yn?yn.createHTML($r):$r;if(Es===co)try{to=(new Fr).parseFromString(ne,ls)}catch(Lt){}if(!to||!to.documentElement){to=Vn.createDocument(Es,"template",null);try{to.documentElement.innerHTML=Zs?"":ne}catch(Lt){}}var $e=to.body||to.documentElement;return $r&&tt&&$e.insertBefore(Br.createTextNode(tt),$e.childNodes[0]||null),Es===co?Pr.call(to,li?"html":"body")[0]:li?to.documentElement:$e},Ca=function($r){return mr.call($r.ownerDocument||$r,$r,Zr.SHOW_ELEMENT|Zr.SHOW_COMMENT|Zr.SHOW_TEXT,null,!1)},Ra=function($r){return!($r instanceof zn||$r instanceof rr||"string"==typeof $r.nodeName&&"string"==typeof $r.textContent&&"function"==typeof $r.removeChild&&$r.attributes instanceof Wt&&"function"==typeof $r.removeAttribute&&"function"==typeof $r.setAttribute&&"string"==typeof $r.namespaceURI&&"function"==typeof $r.insertBefore)},pl=function($r){return"object"===(void 0===ki?"undefined":Zn(ki))?$r instanceof ki:$r&&"object"===(void 0===$r?"undefined":Zn($r))&&"number"==typeof $r.nodeType&&"string"==typeof $r.nodeName},Ws=function($r,to,tt){!Ge[$r]||L(Ge[$r],function(sn){sn.call(Nn,to,tt,us)})},Po=function($r){var to=void 0;if(Ws("beforeSanitizeElements",$r,null),Ra($r)||ee($r.nodeName,/[\u0080-\uFFFF]/))return Ya($r),!0;var tt=Is($r.nodeName);if(Ws("uponSanitizeElement",$r,{tagName:tt,allowedTags:ar}),!pl($r.firstElementChild)&&(!pl($r.content)||!pl($r.content.firstElementChild))&&se(/<[/\w]/g,$r.innerHTML)&&se(/<[/\w]/g,$r.textContent)||"select"===tt&&se(/<template/i,$r.innerHTML))return Ya($r),!0;if(!ar[tt]||Co[tt]){if($o&&!Rt[tt]){var sn=Dr($r)||$r.parentNode,ne=br($r)||$r.childNodes;if(ne&&sn)for(var Lt=ne.length-1;Lt>=0;--Lt)sn.insertBefore(_i(ne[Lt],!0),wi($r))}return Ya($r),!0}return $r instanceof Hi&&!fo($r)||("noscript"===tt||"noembed"===tt)&&se(/<\/no(script|embed)/i,$r.innerHTML)?(Ya($r),!0):(Mi&&3===$r.nodeType&&(to=ue(to=$r.textContent,kr," "),to=ue(to,mi," "),$r.textContent!==to&&(J(Nn.removed,{element:$r.cloneNode()}),$r.textContent=to)),Ws("afterSanitizeElements",$r,null),!1)},bo=function($r,to,tt){if(Ci&&("id"===to||"name"===to)&&(tt in Br||tt in ya))return!1;if((!jo||Gi[to]||!se(An,to))&&(!os||!se(Er,to))){if(!lo[to]||Gi[to])return!1;if(!on[to]&&!se(Fn,ue(tt,dr,""))&&("src"!==to&&"xlink:href"!==to&&"href"!==to||"script"===$r||0!==ae(tt,"data:")||!mt[$r])&&(!To||se(Wr,ue(tt,dr,"")))&&tt)return!1}return!0},Ls=function($r){var to=void 0,tt=void 0,sn=void 0,ne=void 0;Ws("beforeSanitizeAttributes",$r,null);var $e=$r.attributes;if($e){var Lt={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:lo};for(ne=$e.length;ne--;){var ti=(to=$e[ne]).name,pi=to.namespaceURI;if(tt=H(to.value),sn=Is(ti),Lt.attrName=sn,Lt.attrValue=tt,Lt.keepAttr=!0,Lt.forceKeepAttr=void 0,Ws("uponSanitizeAttribute",$r,Lt),tt=Lt.attrValue,!Lt.forceKeepAttr&&(Ao(ti,$r),Lt.keepAttr)){if(se(/\/>/i,tt)){Ao(ti,$r);continue}Mi&&(tt=ue(tt,kr," "),tt=ue(tt,mi," "));var xi=Is($r.nodeName);if(bo(xi,sn,tt))try{pi?$r.setAttributeNS(pi,ti,tt):$r.setAttribute(ti,tt),Z(Nn.removed)}catch(ts){}}}Ws("afterSanitizeAttributes",$r,null)}},ps=function So($r){var to=void 0,tt=Ca($r);for(Ws("beforeSanitizeShadowDOM",$r,null);to=tt.nextNode();)Ws("uponSanitizeShadowNode",to,null),!Po(to)&&(to.content instanceof Yr&&So(to.content),Ls(to));Ws("afterSanitizeShadowDOM",$r,null)};return Nn.sanitize=function(So,$r){var to=void 0,tt=void 0,sn=void 0,ne=void 0,$e=void 0;if((Zs=!So)&&(So="\x3c!--\x3e"),"string"!=typeof So&&!pl(So)){if("function"!=typeof So.toString)throw Ee("toString is not a function");if("string"!=typeof(So=So.toString()))throw Ee("dirty is not a string, aborting")}if(!Nn.isSupported){if("object"===Zn(ei.toStaticHTML)||"function"==typeof ei.toStaticHTML){if("string"==typeof So)return ei.toStaticHTML(So);if(pl(So))return ei.toStaticHTML(So.outerHTML)}return So}if(Bn||el($r),Nn.removed=[],"string"==typeof So&&(tr=!1),!tr)if(So instanceof ki)1===(tt=(to=fs("\x3c!----\x3e")).ownerDocument.importNode(So,!0)).nodeType&&"BODY"===tt.nodeName||"HTML"===tt.nodeName?to=tt:to.appendChild(tt);else{if(!vr&&!Mi&&!li&&-1===So.indexOf("<"))return yn&&uo?yn.createHTML(So):So;if(!(to=fs(So)))return vr?null:gr}to&&lr&&Ya(to.firstChild);for(var Lt=Ca(tr?So:to);sn=Lt.nextNode();)3===sn.nodeType&&sn===ne||Po(sn)||(sn.content instanceof Yr&&ps(sn.content),Ls(sn),ne=sn);if(ne=null,tr)return So;if(vr){if(er)for($e=Dn.call(to.ownerDocument);to.firstChild;)$e.appendChild(to.firstChild);else $e=to;return ri&&($e=Yt.call($n,$e,!0)),$e}var an=li?to.outerHTML:to.innerHTML;return Mi&&(an=ue(an,kr," "),an=ue(an,mi," ")),yn&&uo?yn.createHTML(an):an},Nn.setConfig=function(So){el(So),Bn=!0},Nn.clearConfig=function(){us=null,Bn=!1},Nn.isValidAttribute=function(So,$r,to){us||el({});var tt=Is(So),sn=Is($r);return bo(tt,sn,to)},Nn.addHook=function(So,$r){"function"==typeof $r&&(Ge[So]=Ge[So]||[],J(Ge[So],$r))},Nn.removeHook=function(So){Ge[So]&&Z(Ge[So])},Nn.removeHooks=function(So){Ge[So]&&(Ge[So]=[])},Nn.removeAllHooks=function(){Ge={}},Nn}()}()},32582:v=>{"use strict";class T{constructor(u,p){this.low=u,this.high=p,this.length=1+p-u}overlaps(u){return!(this.high<u.low||this.low>u.high)}touches(u){return!(this.high+1<u.low||this.low-1>u.high)}add(u){return new T(Math.min(this.low,u.low),Math.max(this.high,u.high))}subtract(u){return u.low<=this.low&&u.high>=this.high?[]:u.low>this.low&&u.high<this.high?[new T(this.low,u.low-1),new T(u.high+1,this.high)]:u.low<=this.low?[new T(u.high+1,this.high)]:[new T(this.low,u.low-1)]}toString(){return this.low==this.high?this.low.toString():this.low+"-"+this.high}}class i{constructor(u,p){this.ranges=[],this.length=0,null!=u&&this.add(u,p)}_update_length(){this.length=this.ranges.reduce((u,p)=>u+p.length,0)}add(u,p){var d=e=>{for(var _=0;_<this.ranges.length&&!e.touches(this.ranges[_]);)_++;for(var y=this.ranges.slice(0,_);_<this.ranges.length&&e.touches(this.ranges[_]);)e=e.add(this.ranges[_]),_++;y.push(e),this.ranges=y.concat(this.ranges.slice(_)),this._update_length()};return u instanceof i?u.ranges.forEach(d):(null==p&&(p=u),d(new T(u,p))),this}subtract(u,p){var d=e=>{for(var _=0;_<this.ranges.length&&!e.overlaps(this.ranges[_]);)_++;for(var y=this.ranges.slice(0,_);_<this.ranges.length&&e.overlaps(this.ranges[_]);)y=y.concat(this.ranges[_].subtract(e)),_++;this.ranges=y.concat(this.ranges.slice(_)),this._update_length()};return u instanceof i?u.ranges.forEach(d):(null==p&&(p=u),d(new T(u,p))),this}intersect(u,p){var d=[],e=_=>{for(var y=0;y<this.ranges.length&&!_.overlaps(this.ranges[y]);)y++;for(;y<this.ranges.length&&_.overlaps(this.ranges[y]);){var S=Math.max(this.ranges[y].low,_.low),A=Math.min(this.ranges[y].high,_.high);d.push(new T(S,A)),y++}};return u instanceof i?u.ranges.forEach(e):(null==p&&(p=u),e(new T(u,p))),this.ranges=d,this._update_length(),this}index(u){for(var p=0;p<this.ranges.length&&this.ranges[p].length<=u;)u-=this.ranges[p].length,p++;return this.ranges[p].low+u}toString(){return"[ "+this.ranges.join(", ")+" ]"}clone(){return new i(this)}numbers(){return this.ranges.reduce((u,p)=>{for(var d=p.low;d<=p.high;)u.push(d),d++;return u},[])}subranges(){return this.ranges.map(u=>({low:u.low,high:u.high,length:1+u.high-u.low}))}}v.exports=i},11926:(v,T,i)=>{"use strict";var r=i(88430),u=p(Error);function p(d){return e.displayName=d.displayName||d.name,e;function e(_){return _&&(_=r.apply(null,arguments)),new d(_)}}v.exports=u,u.eval=p(EvalError),u.range=p(RangeError),u.reference=p(ReferenceError),u.syntax=p(SyntaxError),u.type=p(TypeError),u.uri=p(URIError),u.create=p},49457:function(v,T){var i,u;void 0!==(u="function"==typeof(i=function(){"use strict";function d(A,N,L){var Z=new XMLHttpRequest;Z.open("GET",A),Z.responseType="blob",Z.onload=function(){S(Z.response,N,L)},Z.onerror=function(){console.error("could not download file")},Z.send()}function e(A){var N=new XMLHttpRequest;N.open("HEAD",A,!1);try{N.send()}catch(L){}return 200<=N.status&&299>=N.status}function _(A){try{A.dispatchEvent(new MouseEvent("click"))}catch(L){var N=document.createEvent("MouseEvents");N.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),A.dispatchEvent(N)}}var y="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof global&&global.global===global?global:void 0,S=y.saveAs||("object"!=typeof window||window!==y?function(){}:"download"in HTMLAnchorElement.prototype?function(A,N,L){var Z=y.URL||y.webkitURL,J=document.createElement("a");J.download=N=N||A.name||"download",J.rel="noopener","string"==typeof A?(J.href=A,J.origin===location.origin?_(J):e(J.href)?d(A,N,L):_(J,J.target="_blank")):(J.href=Z.createObjectURL(A),setTimeout(function(){Z.revokeObjectURL(J.href)},4e4),setTimeout(function(){_(J)},0))}:"msSaveOrOpenBlob"in navigator?function(A,N,L){if(N=N||A.name||"download","string"!=typeof A)navigator.msSaveOrOpenBlob(function(A,N){return void 0===N?N={autoBom:!1}:"object"!=typeof N&&(console.warn("Deprecated: Expected third argument to be a object"),N={autoBom:!N}),N.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(A.type)?new Blob(["\ufeff",A],{type:A.type}):A}(A,L),N);else if(e(A))d(A,N,L);else{var Z=document.createElement("a");Z.href=A,Z.target="_blank",setTimeout(function(){_(Z)})}}:function(A,N,L,Z){if((Z=Z||open("","_blank"))&&(Z.document.title=Z.document.body.innerText="downloading..."),"string"==typeof A)return d(A,N,L);var J="application/octet-stream"===A.type,K=/constructor/i.test(y.HTMLElement)||y.safari,ee=/CriOS\/[\d]+/.test(navigator.userAgent);if((ee||J&&K)&&"object"==typeof FileReader){var ue=new FileReader;ue.onloadend=function(){var se=ue.result;se=ee?se:se.replace(/^data:[^;]*;/,"data:attachment/file;"),Z?Z.location.href=se:location=se,Z=null},ue.readAsDataURL(A)}else{var ae=y.URL||y.webkitURL,H=ae.createObjectURL(A);Z?Z.location=H:location.href=H,Z=null,setTimeout(function(){ae.revokeObjectURL(H)},4e4)}});y.saveAs=S.saveAs=S,v.exports=S})?i.apply(T,[]):i)&&(v.exports=u)},88430:v=>{!function(){var T;function u(p){for(var A,L,Z,K,d=1,e=[].slice.call(arguments),_=0,y=p.length,S="",N=!1,J=!1,ee=function(){return e[d++]},ue=function(){for(var ae="";/\d/.test(p[_]);)ae+=p[_++],A=p[_];return ae.length>0?parseInt(ae):null};_<y;++_)if(A=p[_],N)switch(N=!1,"."==A?(J=!1,A=p[++_]):"0"==A&&"."==p[_+1]?(J=!0,_+=2,A=p[_]):J=!0,K=ue(),A){case"b":S+=parseInt(ee(),10).toString(2);break;case"c":S+="string"==typeof(L=ee())||L instanceof String?L:String.fromCharCode(parseInt(L,10));break;case"d":S+=parseInt(ee(),10);break;case"f":Z=String(parseFloat(ee()).toFixed(K||6)),S+=J?Z:Z.replace(/^0/,"");break;case"j":S+=JSON.stringify(ee());break;case"o":S+="0"+parseInt(ee(),10).toString(8);break;case"s":S+=ee();break;case"x":S+="0x"+parseInt(ee(),10).toString(16);break;case"X":S+="0x"+parseInt(ee(),10).toString(16).toUpperCase();break;default:S+=A}else"%"===A?N=!0:S+=A;return S}(T=v.exports=u).format=u,T.vsprintf=function(p,d){return u.apply(null,[p].concat(d))},"undefined"!=typeof console&&"function"==typeof console.log&&(T.printf=function(){console.log(u.apply(null,arguments))})}()},31609:v=>{"use strict";var T="Function.prototype.bind called on incompatible ",i=Array.prototype.slice,r=Object.prototype.toString,u="[object Function]";v.exports=function(d){var e=this;if("function"!=typeof e||r.call(e)!==u)throw new TypeError(T+e);for(var y,_=i.call(arguments,1),S=function(){if(this instanceof y){var J=e.apply(this,_.concat(i.call(arguments)));return Object(J)===J?J:this}return e.apply(d,_.concat(i.call(arguments)))},A=Math.max(0,e.length-_.length),N=[],L=0;L<A;L++)N.push("$"+L);if(y=Function("binder","return function ("+N.join(",")+"){ return binder.apply(this,arguments); }")(S),e.prototype){var Z=function(){};Z.prototype=e.prototype,y.prototype=new Z,Z.prototype=null}return y}},75396:(v,T,i)=>{"use strict";var r=i(31609);v.exports=Function.prototype.bind||r},18540:(v,T,i)=>{"use strict";var r,u=SyntaxError,p=Function,d=TypeError,e=function(Ve){try{return p('"use strict"; return ('+Ve+").constructor;")()}catch(ze){}},_=Object.getOwnPropertyDescriptor;if(_)try{_({},"")}catch(Ve){_=null}var y=function(){throw new d},S=_?function(){try{return y}catch(Ve){try{return _(arguments,"callee").get}catch(ze){return y}}}():y,A=i(59326)(),N=Object.getPrototypeOf||function(Ve){return Ve.__proto__},L={},Z="undefined"==typeof Uint8Array?r:N(Uint8Array),J={"%AggregateError%":"undefined"==typeof AggregateError?r:AggregateError,"%Array%":Array,"%ArrayBuffer%":"undefined"==typeof ArrayBuffer?r:ArrayBuffer,"%ArrayIteratorPrototype%":A?N([][Symbol.iterator]()):r,"%AsyncFromSyncIteratorPrototype%":r,"%AsyncFunction%":L,"%AsyncGenerator%":L,"%AsyncGeneratorFunction%":L,"%AsyncIteratorPrototype%":L,"%Atomics%":"undefined"==typeof Atomics?r:Atomics,"%BigInt%":"undefined"==typeof BigInt?r:BigInt,"%Boolean%":Boolean,"%DataView%":"undefined"==typeof DataView?r:DataView,"%Date%":Date,"%decodeURI%":decodeURI,"%decodeURIComponent%":decodeURIComponent,"%encodeURI%":encodeURI,"%encodeURIComponent%":encodeURIComponent,"%Error%":Error,"%eval%":eval,"%EvalError%":EvalError,"%Float32Array%":"undefined"==typeof Float32Array?r:Float32Array,"%Float64Array%":"undefined"==typeof Float64Array?r:Float64Array,"%FinalizationRegistry%":"undefined"==typeof FinalizationRegistry?r:FinalizationRegistry,"%Function%":p,"%GeneratorFunction%":L,"%Int8Array%":"undefined"==typeof Int8Array?r:Int8Array,"%Int16Array%":"undefined"==typeof Int16Array?r:Int16Array,"%Int32Array%":"undefined"==typeof Int32Array?r:Int32Array,"%isFinite%":isFinite,"%isNaN%":isNaN,"%IteratorPrototype%":A?N(N([][Symbol.iterator]())):r,"%JSON%":"object"==typeof JSON?JSON:r,"%Map%":"undefined"==typeof Map?r:Map,"%MapIteratorPrototype%":"undefined"!=typeof Map&&A?N((new Map)[Symbol.iterator]()):r,"%Math%":Math,"%Number%":Number,"%Object%":Object,"%parseFloat%":parseFloat,"%parseInt%":parseInt,"%Promise%":"undefined"==typeof Promise?r:Promise,"%Proxy%":"undefined"==typeof Proxy?r:Proxy,"%RangeError%":RangeError,"%ReferenceError%":ReferenceError,"%Reflect%":"undefined"==typeof Reflect?r:Reflect,"%RegExp%":RegExp,"%Set%":"undefined"==typeof Set?r:Set,"%SetIteratorPrototype%":"undefined"!=typeof Set&&A?N((new Set)[Symbol.iterator]()):r,"%SharedArrayBuffer%":"undefined"==typeof SharedArrayBuffer?r:SharedArrayBuffer,"%String%":String,"%StringIteratorPrototype%":A?N(""[Symbol.iterator]()):r,"%Symbol%":A?Symbol:r,"%SyntaxError%":u,"%ThrowTypeError%":S,"%TypedArray%":Z,"%TypeError%":d,"%Uint8Array%":"undefined"==typeof Uint8Array?r:Uint8Array,"%Uint8ClampedArray%":"undefined"==typeof Uint8ClampedArray?r:Uint8ClampedArray,"%Uint16Array%":"undefined"==typeof Uint16Array?r:Uint16Array,"%Uint32Array%":"undefined"==typeof Uint32Array?r:Uint32Array,"%URIError%":URIError,"%WeakMap%":"undefined"==typeof WeakMap?r:WeakMap,"%WeakRef%":"undefined"==typeof WeakRef?r:WeakRef,"%WeakSet%":"undefined"==typeof WeakSet?r:WeakSet},K=function Ve(ze){var Be;if("%AsyncFunction%"===ze)Be=e("async function () {}");else if("%GeneratorFunction%"===ze)Be=e("function* () {}");else if("%AsyncGeneratorFunction%"===ze)Be=e("async function* () {}");else if("%AsyncGenerator%"===ze){var Pe=Ve("%AsyncGeneratorFunction%");Pe&&(Be=Pe.prototype)}else if("%AsyncIteratorPrototype%"===ze){var je=Ve("%AsyncGenerator%");je&&(Be=N(je.prototype))}return J[ze]=Be,Be},ee={"%ArrayBufferPrototype%":["ArrayBuffer","prototype"],"%ArrayPrototype%":["Array","prototype"],"%ArrayProto_entries%":["Array","prototype","entries"],"%ArrayProto_forEach%":["Array","prototype","forEach"],"%ArrayProto_keys%":["Array","prototype","keys"],"%ArrayProto_values%":["Array","prototype","values"],"%AsyncFunctionPrototype%":["AsyncFunction","prototype"],"%AsyncGenerator%":["AsyncGeneratorFunction","prototype"],"%AsyncGeneratorPrototype%":["AsyncGeneratorFunction","prototype","prototype"],"%BooleanPrototype%":["Boolean","prototype"],"%DataViewPrototype%":["DataView","prototype"],"%DatePrototype%":["Date","prototype"],"%ErrorPrototype%":["Error","prototype"],"%EvalErrorPrototype%":["EvalError","prototype"],"%Float32ArrayPrototype%":["Float32Array","prototype"],"%Float64ArrayPrototype%":["Float64Array","prototype"],"%FunctionPrototype%":["Function","prototype"],"%Generator%":["GeneratorFunction","prototype"],"%GeneratorPrototype%":["GeneratorFunction","prototype","prototype"],"%Int8ArrayPrototype%":["Int8Array","prototype"],"%Int16ArrayPrototype%":["Int16Array","prototype"],"%Int32ArrayPrototype%":["Int32Array","prototype"],"%JSONParse%":["JSON","parse"],"%JSONStringify%":["JSON","stringify"],"%MapPrototype%":["Map","prototype"],"%NumberPrototype%":["Number","prototype"],"%ObjectPrototype%":["Object","prototype"],"%ObjProto_toString%":["Object","prototype","toString"],"%ObjProto_valueOf%":["Object","prototype","valueOf"],"%PromisePrototype%":["Promise","prototype"],"%PromiseProto_then%":["Promise","prototype","then"],"%Promise_all%":["Promise","all"],"%Promise_reject%":["Promise","reject"],"%Promise_resolve%":["Promise","resolve"],"%RangeErrorPrototype%":["RangeError","prototype"],"%ReferenceErrorPrototype%":["ReferenceError","prototype"],"%RegExpPrototype%":["RegExp","prototype"],"%SetPrototype%":["Set","prototype"],"%SharedArrayBufferPrototype%":["SharedArrayBuffer","prototype"],"%StringPrototype%":["String","prototype"],"%SymbolPrototype%":["Symbol","prototype"],"%SyntaxErrorPrototype%":["SyntaxError","prototype"],"%TypedArrayPrototype%":["TypedArray","prototype"],"%TypeErrorPrototype%":["TypeError","prototype"],"%Uint8ArrayPrototype%":["Uint8Array","prototype"],"%Uint8ClampedArrayPrototype%":["Uint8ClampedArray","prototype"],"%Uint16ArrayPrototype%":["Uint16Array","prototype"],"%Uint32ArrayPrototype%":["Uint32Array","prototype"],"%URIErrorPrototype%":["URIError","prototype"],"%WeakMapPrototype%":["WeakMap","prototype"],"%WeakSetPrototype%":["WeakSet","prototype"]},ue=i(75396),ae=i(57709),H=ue.call(Function.call,Array.prototype.concat),se=ue.call(Function.apply,Array.prototype.splice),Ee=ue.call(Function.call,String.prototype.replace),ie=ue.call(Function.call,String.prototype.slice),he=ue.call(Function.call,RegExp.prototype.exec),ge=/[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g,De=/\\(\\)?/g,ce=function(ze){var Be=ie(ze,0,1),Pe=ie(ze,-1);if("%"===Be&&"%"!==Pe)throw new u("invalid intrinsic syntax, expected closing `%`");if("%"===Pe&&"%"!==Be)throw new u("invalid intrinsic syntax, expected opening `%`");var je=[];return Ee(ze,ge,function(He,Vt,it,tn){je[je.length]=it?Ee(tn,De,"$1"):Vt||He}),je},lt=function(ze,Be){var je,Pe=ze;if(ae(ee,Pe)&&(Pe="%"+(je=ee[Pe])[0]+"%"),ae(J,Pe)){var He=J[Pe];if(He===L&&(He=K(Pe)),void 0===He&&!Be)throw new d("intrinsic "+ze+" exists, but is not available. Please file an issue!");return{alias:je,name:Pe,value:He}}throw new u("intrinsic "+ze+" does not exist!")};v.exports=function(ze,Be){if("string"!=typeof ze||0===ze.length)throw new d("intrinsic name must be a non-empty string");if(arguments.length>1&&"boolean"!=typeof Be)throw new d('"allowMissing" argument must be a boolean');if(null===he(/^%?[^%]*%?$/g,ze))throw new u("`%` may not be present anywhere but at the beginning and end of the intrinsic name");var Pe=ce(ze),je=Pe.length>0?Pe[0]:"",He=lt("%"+je+"%",Be),Vt=He.name,it=He.value,tn=!1,It=He.alias;It&&(je=It[0],se(Pe,H([0,1],It)));for(var Zt=1,Ut=!0;Zt<Pe.length;Zt+=1){var Bt=Pe[Zt],bt=ie(Bt,0,1),Gt=ie(Bt,-1);if(('"'===bt||"'"===bt||"`"===bt||'"'===Gt||"'"===Gt||"`"===Gt)&&bt!==Gt)throw new u("property names with quotes must have matching quotes");if(("constructor"===Bt||!Ut)&&(tn=!0),ae(J,Vt="%"+(je+="."+Bt)+"%"))it=J[Vt];else if(null!=it){if(!(Bt in it)){if(!Be)throw new d("base intrinsic for "+ze+" exists, but the property is not available.");return}if(_&&Zt+1>=Pe.length){var xt=_(it,Bt);it=(Ut=!!xt)&&"get"in xt&&!("originalValue"in xt.get)?xt.get:it[Bt]}else Ut=ae(it,Bt),it=it[Bt];Ut&&!tn&&(J[Vt]=it)}}return it}},59326:(v,T,i)=>{"use strict";var r="undefined"!=typeof Symbol&&Symbol,u=i(79045);v.exports=function(){return"function"==typeof r&&"function"==typeof Symbol&&"symbol"==typeof r("foo")&&"symbol"==typeof Symbol("bar")&&u()}},79045:v=>{"use strict";v.exports=function(){if("function"!=typeof Symbol||"function"!=typeof Object.getOwnPropertySymbols)return!1;if("symbol"==typeof Symbol.iterator)return!0;var i={},r=Symbol("test"),u=Object(r);if("string"==typeof r||"[object Symbol]"!==Object.prototype.toString.call(r)||"[object Symbol]"!==Object.prototype.toString.call(u))return!1;for(r in i[r]=42,i)return!1;if("function"==typeof Object.keys&&0!==Object.keys(i).length||"function"==typeof Object.getOwnPropertyNames&&0!==Object.getOwnPropertyNames(i).length)return!1;var d=Object.getOwnPropertySymbols(i);if(1!==d.length||d[0]!==r||!Object.prototype.propertyIsEnumerable.call(i,r))return!1;if("function"==typeof Object.getOwnPropertyDescriptor){var e=Object.getOwnPropertyDescriptor(i,r);if(42!==e.value||!0!==e.enumerable)return!1}return!0}},57709:(v,T,i)=>{"use strict";var r=i(75396);v.exports=r.call(Function.call,Object.prototype.hasOwnProperty)},7856:v=>{function T(Jt){return Jt instanceof Map?Jt.clear=Jt.delete=Jt.set=function(){throw new Error("map is read-only")}:Jt instanceof Set&&(Jt.add=Jt.clear=Jt.delete=function(){throw new Error("set is read-only")}),Object.freeze(Jt),Object.getOwnPropertyNames(Jt).forEach(function(Vn){var mr=Jt[Vn];"object"==typeof mr&&!Object.isFrozen(mr)&&T(mr)}),Jt}var i=T;i.default=T;class u{constructor(Vn){void 0===Vn.data&&(Vn.data={}),this.data=Vn.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}}function p(Jt){return Jt.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;")}function d(Jt,...Vn){const mr=Object.create(null);for(const Dn in Jt)mr[Dn]=Jt[Dn];return Vn.forEach(function(Dn){for(const Pr in Dn)mr[Pr]=Dn[Pr]}),mr}const _=Jt=>!!Jt.kind;class y{constructor(Vn,mr){this.buffer="",this.classPrefix=mr.classPrefix,Vn.walk(this)}addText(Vn){this.buffer+=p(Vn)}openNode(Vn){if(!_(Vn))return;let mr=Vn.kind;Vn.sublanguage||(mr=`${this.classPrefix}${mr}`),this.span(mr)}closeNode(Vn){!_(Vn)||(this.buffer+="</span>")}value(){return this.buffer}span(Vn){this.buffer+=`<span class="${Vn}">`}}class S{constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(Vn){this.top.children.push(Vn)}openNode(Vn){const mr={kind:Vn,children:[]};this.add(mr),this.stack.push(mr)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(Vn){return this.constructor._walk(Vn,this.rootNode)}static _walk(Vn,mr){return"string"==typeof mr?Vn.addText(mr):mr.children&&(Vn.openNode(mr),mr.children.forEach(Dn=>this._walk(Vn,Dn)),Vn.closeNode(mr)),Vn}static _collapse(Vn){"string"!=typeof Vn&&(!Vn.children||(Vn.children.every(mr=>"string"==typeof mr)?Vn.children=[Vn.children.join("")]:Vn.children.forEach(mr=>{S._collapse(mr)})))}}class A extends S{constructor(Vn){super(),this.options=Vn}addKeyword(Vn,mr){""!==Vn&&(this.openNode(mr),this.addText(Vn),this.closeNode())}addText(Vn){""!==Vn&&this.add(Vn)}addSublanguage(Vn,mr){const Dn=Vn.root;Dn.kind=mr,Dn.sublanguage=!0,this.add(Dn)}toHTML(){return new y(this,this.options).value()}finalize(){return!0}}function L(Jt){return Jt?"string"==typeof Jt?Jt:Jt.source:null}const ue=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,se="[a-zA-Z]\\w*",Ee="[a-zA-Z_]\\w*",ie="\\b\\d+(\\.\\d+)?",he="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",ge="\\b(0b[01]+)",lt={begin:"\\\\[\\s\\S]",relevance:0},Ve={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[lt]},ze={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[lt]},Be={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},Pe=function(Jt,Vn,mr={}){const Dn=d({className:"comment",begin:Jt,end:Vn,contains:[]},mr);return Dn.contains.push(Be),Dn.contains.push({className:"doctag",begin:"(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):",relevance:0}),Dn},je=Pe("//","$"),He=Pe("/\\*","\\*/"),Vt=Pe("#","$");var Xt=Object.freeze({__proto__:null,MATCH_NOTHING_RE:/\b\B/,IDENT_RE:se,UNDERSCORE_IDENT_RE:Ee,NUMBER_RE:ie,C_NUMBER_RE:he,BINARY_NUMBER_RE:ge,RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",SHEBANG:(Jt={})=>{const Vn=/^#![ ]*\//;return Jt.binary&&(Jt.begin=function(...Jt){return Jt.map(mr=>L(mr)).join("")}(Vn,/.*\b/,Jt.binary,/\b.*/)),d({className:"meta",begin:Vn,end:/$/,relevance:0,"on:begin":(mr,Dn)=>{0!==mr.index&&Dn.ignoreMatch()}},Jt)},BACKSLASH_ESCAPE:lt,APOS_STRING_MODE:Ve,QUOTE_STRING_MODE:ze,PHRASAL_WORDS_MODE:Be,COMMENT:Pe,C_LINE_COMMENT_MODE:je,C_BLOCK_COMMENT_MODE:He,HASH_COMMENT_MODE:Vt,NUMBER_MODE:{className:"number",begin:ie,relevance:0},C_NUMBER_MODE:{className:"number",begin:he,relevance:0},BINARY_NUMBER_MODE:{className:"number",begin:ge,relevance:0},CSS_NUMBER_MODE:{className:"number",begin:ie+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},REGEXP_MODE:{begin:/(?=\/[^/\n]*\/)/,contains:[{className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[lt,{begin:/\[/,end:/\]/,relevance:0,contains:[lt]}]}]},TITLE_MODE:{className:"title",begin:se,relevance:0},UNDERSCORE_TITLE_MODE:{className:"title",begin:Ee,relevance:0},METHOD_GUARD:{begin:"\\.\\s*"+Ee,relevance:0},END_SAME_AS_BEGIN:function(Jt){return Object.assign(Jt,{"on:begin":(Vn,mr)=>{mr.data._beginMatch=Vn[1]},"on:end":(Vn,mr)=>{mr.data._beginMatch!==Vn[1]&&mr.ignoreMatch()}})}});function Zn(Jt,Vn){"."===Jt.input[Jt.index-1]&&Vn.ignoreMatch()}function Ur(Jt,Vn){!Vn||!Jt.beginKeywords||(Jt.begin="\\b("+Jt.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",Jt.__beforeBegin=Zn,Jt.keywords=Jt.keywords||Jt.beginKeywords,delete Jt.beginKeywords,void 0===Jt.relevance&&(Jt.relevance=0))}function di(Jt,Vn){!Array.isArray(Jt.illegal)||(Jt.illegal=function(...Jt){return"("+Jt.map(mr=>L(mr)).join("|")+")"}(...Jt.illegal))}function Lr(Jt,Vn){if(Jt.match){if(Jt.begin||Jt.end)throw new Error("begin & end are not supported with match");Jt.begin=Jt.match,delete Jt.match}}function Mr(Jt,Vn){void 0===Jt.relevance&&(Jt.relevance=1)}const Kr=["of","and","for","in","not","or","if","then","parent","list","value"];function Nn(Jt,Vn,mr="keyword"){const Dn={};return"string"==typeof Jt?Pr(mr,Jt.split(" ")):Array.isArray(Jt)?Pr(mr,Jt):Object.keys(Jt).forEach(function(Yt){Object.assign(Dn,Nn(Jt[Yt],Vn,Yt))}),Dn;function Pr(Yt,_n){Vn&&(_n=_n.map(Ge=>Ge.toLowerCase())),_n.forEach(function(Ge){const kr=Ge.split("|");Dn[kr[0]]=[Yt,$n(kr[0],kr[1])]})}}function $n(Jt,Vn){return Vn?Number(Vn):function(Jt){return Kr.includes(Jt.toLowerCase())}(Jt)?0:1}function Yr(Jt,{}){function mr(Ge,kr){return new RegExp(L(Ge),"m"+(Jt.case_insensitive?"i":"")+(kr?"g":""))}class Dn{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(kr,mi){mi.position=this.position++,this.matchIndexes[this.matchAt]=mi,this.regexes.push([mi,kr]),this.matchAt+=function(Jt){return new RegExp(Jt.toString()+"|").exec("").length-1}(kr)+1}compile(){0===this.regexes.length&&(this.exec=()=>null);const kr=this.regexes.map(mi=>mi[1]);this.matcherRe=mr(function(Jt,Vn="|"){let mr=0;return Jt.map(Dn=>{mr+=1;const Pr=mr;let Yt=L(Dn),_n="";for(;Yt.length>0;){const Ge=ue.exec(Yt);if(!Ge){_n+=Yt;break}_n+=Yt.substring(0,Ge.index),Yt=Yt.substring(Ge.index+Ge[0].length),"\\"===Ge[0][0]&&Ge[1]?_n+="\\"+String(Number(Ge[1])+Pr):(_n+=Ge[0],"("===Ge[0]&&mr++)}return _n}).map(Dn=>`(${Dn})`).join(Vn)}(kr),!0),this.lastIndex=0}exec(kr){this.matcherRe.lastIndex=this.lastIndex;const mi=this.matcherRe.exec(kr);if(!mi)return null;const An=mi.findIndex((Wr,dr)=>dr>0&&void 0!==Wr),Er=this.matchIndexes[An];return mi.splice(0,An),Object.assign(mi,Er)}}class Pr{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(kr){if(this.multiRegexes[kr])return this.multiRegexes[kr];const mi=new Dn;return this.rules.slice(kr).forEach(([An,Er])=>mi.addRule(An,Er)),mi.compile(),this.multiRegexes[kr]=mi,mi}resumingScanAtSamePosition(){return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(kr,mi){this.rules.push([kr,mi]),"begin"===mi.type&&this.count++}exec(kr){const mi=this.getMatcher(this.regexIndex);mi.lastIndex=this.lastIndex;let An=mi.exec(kr);if(this.resumingScanAtSamePosition()&&(!An||An.index!==this.lastIndex)){const Er=this.getMatcher(0);Er.lastIndex=this.lastIndex+1,An=Er.exec(kr)}return An&&(this.regexIndex+=An.position+1,this.regexIndex===this.count&&this.considerAll()),An}}if(Jt.compilerExtensions||(Jt.compilerExtensions=[]),Jt.contains&&Jt.contains.includes("self"))throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return Jt.classNameAliases=d(Jt.classNameAliases||{}),function _n(Ge,kr){const mi=Ge;if(Ge.isCompiled)return mi;[Lr].forEach(Er=>Er(Ge,kr)),Jt.compilerExtensions.forEach(Er=>Er(Ge,kr)),Ge.__beforeBegin=null,[Ur,di,Mr].forEach(Er=>Er(Ge,kr)),Ge.isCompiled=!0;let An=null;if("object"==typeof Ge.keywords&&(An=Ge.keywords.$pattern,delete Ge.keywords.$pattern),Ge.keywords&&(Ge.keywords=Nn(Ge.keywords,Jt.case_insensitive)),Ge.lexemes&&An)throw new Error("ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) ");return An=An||Ge.lexemes||/\w+/,mi.keywordPatternRe=mr(An,!0),kr&&(Ge.begin||(Ge.begin=/\B|\b/),mi.beginRe=mr(Ge.begin),Ge.endSameAsBegin&&(Ge.end=Ge.begin),!Ge.end&&!Ge.endsWithParent&&(Ge.end=/\B|\b/),Ge.end&&(mi.endRe=mr(Ge.end)),mi.terminatorEnd=L(Ge.end)||"",Ge.endsWithParent&&kr.terminatorEnd&&(mi.terminatorEnd+=(Ge.end?"|":"")+kr.terminatorEnd)),Ge.illegal&&(mi.illegalRe=mr(Ge.illegal)),Ge.contains||(Ge.contains=[]),Ge.contains=[].concat(...Ge.contains.map(function(Er){return function(Jt){return Jt.variants&&!Jt.cachedVariants&&(Jt.cachedVariants=Jt.variants.map(function(Vn){return d(Jt,{variants:null},Vn)})),Jt.cachedVariants?Jt.cachedVariants:fi(Jt)?d(Jt,{starts:Jt.starts?d(Jt.starts):null}):Object.isFrozen(Jt)?d(Jt):Jt}("self"===Er?Ge:Er)})),Ge.contains.forEach(function(Er){_n(Er,mi)}),Ge.starts&&_n(Ge.starts,kr),mi.matcher=function(Ge){const kr=new Pr;return Ge.contains.forEach(mi=>kr.addRule(mi.begin,{rule:mi,type:"begin"})),Ge.terminatorEnd&&kr.addRule(Ge.terminatorEnd,{type:"end"}),Ge.illegal&&kr.addRule(Ge.illegal,{type:"illegal"}),kr}(mi),mi}(Jt)}function fi(Jt){return!!Jt&&(Jt.endsWithParent||fi(Jt.starts))}function Cn(Jt){const Vn={props:["language","code","autodetect"],data:function(){return{detectedLanguage:"",unknownLanguage:!1}},computed:{className(){return this.unknownLanguage?"":"hljs "+this.detectedLanguage},highlighted(){if(!this.autoDetect&&!Jt.getLanguage(this.language))return console.warn(`The language "${this.language}" you specified could not be found.`),this.unknownLanguage=!0,p(this.code);let Dn={};return this.autoDetect?(Dn=Jt.highlightAuto(this.code),this.detectedLanguage=Dn.language):(Dn=Jt.highlight(this.language,this.code,this.ignoreIllegals),this.detectedLanguage=this.language),Dn.value},autoDetect(){return!this.language||function(Jt){return Boolean(Jt||""===Jt)}(this.autodetect)},ignoreIllegals:()=>!0},render(Dn){return Dn("pre",{},[Dn("code",{class:this.className,domProps:{innerHTML:this.highlighted}})])}};return{Component:Vn,VuePlugin:{install(Dn){Dn.component("highlightjs",Vn)}}}}const Wt={"after:highlightElement":({el:Jt,result:Vn,text:mr})=>{const Dn=rr(Jt);if(!Dn.length)return;const Pr=document.createElement("div");Pr.innerHTML=Vn.value,Vn.value=function(Jt,Vn,mr){let Dn=0,Pr="";const Yt=[];function _n(){return Jt.length&&Vn.length?Jt[0].offset!==Vn[0].offset?Jt[0].offset<Vn[0].offset?Jt:Vn:"start"===Vn[0].event?Jt:Vn:Jt.length?Jt:Vn}function Ge(An){Pr+="<"+zn(An)+[].map.call(An.attributes,function(Wr){return" "+Wr.nodeName+'="'+p(Wr.value)+'"'}).join("")+">"}function kr(An){Pr+="</"+zn(An)+">"}function mi(An){("start"===An.event?Ge:kr)(An.node)}for(;Jt.length||Vn.length;){let An=_n();if(Pr+=p(mr.substring(Dn,An[0].offset)),Dn=An[0].offset,An===Jt){Yt.reverse().forEach(kr);do{mi(An.splice(0,1)[0]),An=_n()}while(An===Jt&&An.length&&An[0].offset===Dn);Yt.reverse().forEach(Ge)}else"start"===An[0].event?Yt.push(An[0].node):Yt.pop(),mi(An.splice(0,1)[0])}return Pr+p(mr.substr(Dn))}(Dn,rr(Pr),mr)}};function zn(Jt){return Jt.nodeName.toLowerCase()}function rr(Jt){const Vn=[];return function mr(Dn,Pr){for(let Yt=Dn.firstChild;Yt;Yt=Yt.nextSibling)3===Yt.nodeType?Pr+=Yt.nodeValue.length:1===Yt.nodeType&&(Vn.push({event:"start",offset:Pr,node:Yt}),Pr=mr(Yt,Pr),zn(Yt).match(/br|hr|img|input/)||Vn.push({event:"stop",offset:Pr,node:Yt}));return Pr}(Jt,0),Vn}const Gn={},Jr=Jt=>{console.error(Jt)},_i=(Jt,...Vn)=>{console.log(`WARN: ${Jt}`,...Vn)},wi=(Jt,Vn)=>{Gn[`${Jt}/${Vn}`]||(console.log(`Deprecated as of ${Jt}. ${Vn}`),Gn[`${Jt}/${Vn}`]=!0)},br=p,Dr=d,gn=Symbol("nomatch");var gr=function(Jt){const Vn=Object.create(null),mr=Object.create(null),Dn=[];let Pr=!0;const Yt=/(^(<[^>]+>|\t|)+|\n)/gm,_n="Could not find the language '{}', did you forget to load/include a language module?",Ge={disableAutodetect:!0,name:"Plain text",contains:[]};let kr={noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:null,__emitter:A};function mi(jt){return kr.noHighlightRe.test(jt)}function Er(jt,on,si,Vi){let _o="",co="";"object"==typeof on?(_o=jt,si=on.ignoreIllegals,co=on.language,Vi=void 0):(wi("10.7.0","highlight(lang, code, ...args) has been deprecated."),wi("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"),co=jt,_o=on);const Es={code:_o,language:co};Rt("before:highlight",Es);const Zs=Es.result?Es.result:Wr(Es.language,Es.code,si,Vi);return Zs.code=Es.code,Rt("after:highlight",Zs),Zs}function Wr(jt,on,si,Vi){function _o(Po,bo){const Ls=$s.case_insensitive?bo[0].toLowerCase():bo[0];return Object.prototype.hasOwnProperty.call(Po.keywords,Ls)&&Po.keywords[Ls]}function Zs(){null!=fo.subLanguage?function(){if(""===fs)return;let Po=null;if("string"==typeof fo.subLanguage){if(!Vn[fo.subLanguage])return void Ao.addText(fs);Po=Wr(fo.subLanguage,fs,!0,Ya[fo.subLanguage]),Ya[fo.subLanguage]=Po.top}else Po=Fn(fs,fo.subLanguage.length?fo.subLanguage:null);fo.relevance>0&&(Ca+=Po.relevance),Ao.addSublanguage(Po.emitter,Po.language)}():function(){if(!fo.keywords)return void Ao.addText(fs);let Po=0;fo.keywordPatternRe.lastIndex=0;let bo=fo.keywordPatternRe.exec(fs),Ls="";for(;bo;){Ls+=fs.substring(Po,bo.index);const ps=_o(fo,bo);if(ps){const[So,$r]=ps;Ao.addText(Ls),Ls="",Ca+=$r,So.startsWith("_")?Ls+=bo[0]:Ao.addKeyword(bo[0],$s.classNameAliases[So]||So)}else Ls+=bo[0];Po=fo.keywordPatternRe.lastIndex,bo=fo.keywordPatternRe.exec(fs)}Ls+=fs.substr(Po),Ao.addText(Ls)}(),fs=""}function ls(Po){return Po.className&&Ao.openNode($s.classNameAliases[Po.className]||Po.className),fo=Object.create(Po,{parent:{value:fo}}),fo}function La(Po,bo,Ls){let ps=function(Jt,Vn){const mr=Jt&&Jt.exec(Vn);return mr&&0===mr.index}(Po.endRe,Ls);if(ps){if(Po["on:end"]){const So=new u(Po);Po["on:end"](bo,So),So.isMatchIgnored&&(ps=!1)}if(ps){for(;Po.endsParent&&Po.parent;)Po=Po.parent;return Po}}if(Po.endsWithParent)return La(Po.parent,bo,Ls)}function ta(Po){return 0===fo.matcher.regexIndex?(fs+=Po[0],1):(Ws=!0,0)}function us(Po){const bo=Po[0],Ls=on.substr(Po.index),ps=La(fo,Po,Ls);if(!ps)return gn;const So=fo;So.skip?fs+=bo:(So.returnEnd||So.excludeEnd||(fs+=bo),Zs(),So.excludeEnd&&(fs=bo));do{fo.className&&Ao.closeNode(),!fo.skip&&!fo.subLanguage&&(Ca+=fo.relevance),fo=fo.parent}while(fo!==ps.parent);return ps.starts&&(ps.endSameAsBegin&&(ps.starts.endRe=ps.endRe),ls(ps.starts)),So.returnEnd?0:bo.length}let el={};function ca(Po,bo){const Ls=bo&&bo[0];if(fs+=Po,null==Ls)return Zs(),0;if("begin"===el.type&&"end"===bo.type&&el.index===bo.index&&""===Ls){if(fs+=on.slice(bo.index,bo.index+1),!Pr){const ps=new Error("0 width match regex");throw ps.languageName=jt,ps.badRule=el.rule,ps}return 1}if(el=bo,"begin"===bo.type)return function(Po){const bo=Po[0],Ls=Po.rule,ps=new u(Ls),So=[Ls.__beforeBegin,Ls["on:begin"]];for(const $r of So)if($r&&($r(Po,ps),ps.isMatchIgnored))return ta(bo);return Ls&&Ls.endSameAsBegin&&(Ls.endRe=function(Jt){return new RegExp(Jt.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")}(bo)),Ls.skip?fs+=bo:(Ls.excludeBegin&&(fs+=bo),Zs(),!Ls.returnBegin&&!Ls.excludeBegin&&(fs=bo)),ls(Ls),Ls.returnBegin?0:bo.length}(bo);if("illegal"===bo.type&&!si){const ps=new Error('Illegal lexeme "'+Ls+'" for mode "'+(fo.className||"<unnamed>")+'"');throw ps.mode=fo,ps}if("end"===bo.type){const ps=us(bo);if(ps!==gn)return ps}if("illegal"===bo.type&&""===Ls)return 1;if(pl>1e5&&pl>3*bo.index)throw new Error("potential infinite loop, way more iterations than matches");return fs+=Ls,Ls.length}const $s=uo(jt);if(!$s)throw Jr(_n.replace("{}",jt)),new Error('Unknown language: "'+jt+'"');const da=Yr($s,{plugins:Dn});let Il="",fo=Vi||da;const Ya={},Ao=new kr.__emitter(kr);!function(){const Po=[];for(let bo=fo;bo!==$s;bo=bo.parent)bo.className&&Po.unshift(bo.className);Po.forEach(bo=>Ao.openNode(bo))}();let fs="",Ca=0,Ra=0,pl=0,Ws=!1;try{for(fo.matcher.considerAll();;){pl++,Ws?Ws=!1:fo.matcher.considerAll(),fo.matcher.lastIndex=Ra;const Po=fo.matcher.exec(on);if(!Po)break;const Ls=ca(on.substring(Ra,Po.index),Po);Ra=Po.index+Ls}return ca(on.substr(Ra)),Ao.closeAllNodes(),Ao.finalize(),Il=Ao.toHTML(),{relevance:Math.floor(Ca),value:Il,language:jt,illegal:!1,emitter:Ao,top:fo}}catch(Po){if(Po.message&&Po.message.includes("Illegal"))return{illegal:!0,illegalBy:{msg:Po.message,context:on.slice(Ra-100,Ra+100),mode:Po.mode},sofar:Il,relevance:0,value:br(on),emitter:Ao};if(Pr)return{illegal:!1,relevance:0,value:br(on),emitter:Ao,language:jt,top:fo,errorRaised:Po};throw Po}}function Fn(jt,on){on=on||kr.languages||Object.keys(Vn);const si=function(jt){const on={relevance:0,emitter:new kr.__emitter(kr),value:br(jt),illegal:!1,top:Ge};return on.emitter.addText(jt),on}(jt),Vi=on.filter(uo).filter($o).map(ls=>Wr(ls,jt,!1));Vi.unshift(si);const _o=Vi.sort((ls,La)=>{if(ls.relevance!==La.relevance)return La.relevance-ls.relevance;if(ls.language&&La.language){if(uo(ls.language).supersetOf===La.language)return 1;if(uo(La.language).supersetOf===ls.language)return-1}return 0}),[co,Es]=_o,Zs=co;return Zs.second_best=Es,Zs}const lo={"before:highlightElement":({el:jt})=>{kr.useBR&&(jt.innerHTML=jt.innerHTML.replace(/\n/g,"").replace(/<br[ /]*>/g,"\n"))},"after:highlightElement":({result:jt})=>{kr.useBR&&(jt.value=jt.value.replace(/\n/g,"<br>"))}},vo=/^(<[^>]+>|\t)+/gm,Co={"after:highlightElement":({result:jt})=>{kr.tabReplace&&(jt.value=jt.value.replace(vo,on=>on.replace(/\t/g,kr.tabReplace)))}};function Gi(jt){let on=null;const si=function(jt){let on=jt.className+" ";on+=jt.parentNode?jt.parentNode.className:"";const si=kr.languageDetectRe.exec(on);if(si){const Vi=uo(si[1]);return Vi||(_i(_n.replace("{}",si[1])),_i("Falling back to no-highlight mode for this block.",jt)),Vi?si[1]:"no-highlight"}return on.split(/\s+/).find(Vi=>mi(Vi)||uo(Vi))}(jt);if(mi(si))return;Rt("before:highlightElement",{el:jt,language:si}),on=jt;const Vi=on.textContent,_o=si?Er(Vi,{language:si,ignoreIllegals:!0}):Fn(Vi);Rt("after:highlightElement",{el:jt,result:_o,text:Vi}),jt.innerHTML=_o.value,function(jt,on,si){const Vi=on?mr[on]:si;jt.classList.add("hljs"),Vi&&jt.classList.add(Vi)}(jt,si,_o.language),jt.result={language:_o.language,re:_o.relevance,relavance:_o.relevance},_o.second_best&&(jt.second_best={language:_o.second_best.language,re:_o.second_best.relevance,relavance:_o.second_best.relevance})}const jo=()=>{jo.called||(jo.called=!0,wi("10.6.0","initHighlighting() is deprecated. Use highlightAll() instead."),document.querySelectorAll("pre code").forEach(Gi))};let Mi=!1;function li(){"loading"!==document.readyState?document.querySelectorAll("pre code").forEach(Gi):Mi=!0}function uo(jt){return jt=(jt||"").toLowerCase(),Vn[jt]||Vn[mr[jt]]}function Ci(jt,{languageName:on}){"string"==typeof jt&&(jt=[jt]),jt.forEach(si=>{mr[si.toLowerCase()]=on})}function $o(jt){const on=uo(jt);return on&&!on.disableAutodetect}function Rt(jt,on){const si=jt;Dn.forEach(function(Vi){Vi[si]&&Vi[si](on)})}"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",function(){Mi&&li()},!1),Object.assign(Jt,{highlight:Er,highlightAuto:Fn,highlightAll:li,fixMarkup:function(jt){return wi("10.2.0","fixMarkup will be removed entirely in v11.0"),wi("10.2.0","Please see https://github.com/highlightjs/highlight.js/issues/2534"),function(jt){return kr.tabReplace||kr.useBR?jt.replace(Yt,on=>"\n"===on?kr.useBR?"<br>":on:kr.tabReplace?on.replace(/\t/g,kr.tabReplace):on):jt}(jt)},highlightElement:Gi,highlightBlock:function(jt){return wi("10.7.0","highlightBlock will be removed entirely in v12.0"),wi("10.7.0","Please use highlightElement now."),Gi(jt)},configure:function(jt){jt.useBR&&(wi("10.3.0","'useBR' will be removed entirely in v11.0"),wi("10.3.0","Please see https://github.com/highlightjs/highlight.js/issues/2559")),kr=Dr(kr,jt)},initHighlighting:jo,initHighlightingOnLoad:function(){wi("10.6.0","initHighlightingOnLoad() is deprecated. Use highlightAll() instead."),Mi=!0},registerLanguage:function(jt,on){let si=null;try{si=on(Jt)}catch(Vi){if(Jr("Language definition for '{}' could not be registered.".replace("{}",jt)),!Pr)throw Vi;Jr(Vi),si=Ge}si.name||(si.name=jt),Vn[jt]=si,si.rawDefinition=on.bind(null,Jt),si.aliases&&Ci(si.aliases,{languageName:jt})},unregisterLanguage:function(jt){delete Vn[jt];for(const on of Object.keys(mr))mr[on]===jt&&delete mr[on]},listLanguages:function(){return Object.keys(Vn)},getLanguage:uo,registerAliases:Ci,requireLanguage:function(jt){wi("10.4.0","requireLanguage will be removed entirely in v11."),wi("10.4.0","Please see https://github.com/highlightjs/highlight.js/pull/2844");const on=uo(jt);if(on)return on;throw new Error("The '{}' language is required, but not loaded.".replace("{}",jt))},autoDetection:$o,inherit:Dr,addPlugin:function(jt){(function(jt){jt["before:highlightBlock"]&&!jt["before:highlightElement"]&&(jt["before:highlightElement"]=on=>{jt["before:highlightBlock"](Object.assign({block:on.el},on))}),jt["after:highlightBlock"]&&!jt["after:highlightElement"]&&(jt["after:highlightElement"]=on=>{jt["after:highlightBlock"](Object.assign({block:on.el},on))})})(jt),Dn.push(jt)},vuePlugin:Cn(Jt).VuePlugin}),Jt.debugMode=function(){Pr=!1},Jt.safeMode=function(){Pr=!0},Jt.versionString="10.7.3";for(const jt in Xt)"object"==typeof Xt[jt]&&i(Xt[jt]);return Object.assign(Jt,Xt),Jt.addPlugin(lo),Jt.addPlugin(Wt),Jt.addPlugin(Co),Jt}({});v.exports=gr},4357:v=>{function i(...u){return u.map(d=>function(u){return u?"string"==typeof u?u:u.source:null}(d)).join("")}v.exports=function(u){const p={},d={begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[p]}]};Object.assign(p,{className:"variable",variants:[{begin:i(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},d]});const e={className:"subst",begin:/\$\(/,end:/\)/,contains:[u.BACKSLASH_ESCAPE]},_={begin:/<<-?\s*(?=\w+)/,starts:{contains:[u.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,className:"string"})]}},y={className:"string",begin:/"/,end:/"/,contains:[u.BACKSLASH_ESCAPE,p,e]};e.contains.push(y);const N={begin:/\$\(\(/,end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},u.NUMBER_MODE,p]},Z=u.SHEBANG({binary:`(${["fish","bash","zsh","sh","csh","ksh","tcsh","dash","scsh"].join("|")})`,relevance:10}),J={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[u.inherit(u.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{name:"Bash",aliases:["sh","zsh"],keywords:{$pattern:/\b[a-z._-]+\b/,keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp"},contains:[Z,u.SHEBANG(),J,N,u.HASH_COMMENT_MODE,_,y,{className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},p]}}},28390:v=>{function i(...u){return u.map(d=>function(u){return u?"string"==typeof u?u:u.source:null}(d)).join("")}v.exports=function(u){const p="HTTP/(2|1\\.[01])",e={className:"attribute",begin:i("^",/[A-Za-z][A-Za-z0-9-]*/,"(?=\\:\\s)"),starts:{contains:[{className:"punctuation",begin:/: /,relevance:0,starts:{end:"$",relevance:0}}]}},_=[e,{begin:"\\n\\n",starts:{subLanguage:[],endsWithParent:!0}}];return{name:"HTTP",aliases:["https"],illegal:/\S/,contains:[{begin:"^(?="+p+" \\d{3})",end:/$/,contains:[{className:"meta",begin:p},{className:"number",begin:"\\b\\d{3}\\b"}],starts:{end:/\b\B/,illegal:/\S/,contains:_}},{begin:"(?=^[A-Z]+ (.*?) "+p+"$)",end:/$/,contains:[{className:"string",begin:" ",end:" ",excludeBegin:!0,excludeEnd:!0},{className:"meta",begin:p},{className:"keyword",begin:"[A-Z]+"}],starts:{end:/\b\B/,illegal:/\S/,contains:_}},u.inherit(e,{relevance:0})]}}},36147:v=>{const T="[A-Za-z$_][0-9A-Za-z$_]*",i=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],r=["true","false","null","undefined","NaN","Infinity"],_=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer","BigInt64Array","BigUint64Array","BigInt"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);function S(L){return A("(?=",L,")")}function A(...L){return L.map(J=>function(L){return L?"string"==typeof L?L:L.source:null}(J)).join("")}v.exports=function(L){const J=T,ee={begin:/<[A-Za-z0-9\\._:-]+/,end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(je,He)=>{const Vt=je[0].length+je.index,it=je.input[Vt];"<"!==it?">"===it&&(((je,{after:He})=>{const Vt="</"+je[0].slice(1);return-1!==je.input.indexOf(Vt,He)})(je,{after:Vt})||He.ignoreMatch()):He.ignoreMatch()}},ue={$pattern:T,keyword:i,literal:r,built_in:_},ae="[0-9](_?[0-9])*",H=`\\.(${ae})`,se="0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*",Ee={className:"number",variants:[{begin:`(\\b(${se})((${H})|\\.)?|(${H}))[eE][+-]?(${ae})\\b`},{begin:`\\b(${se})\\b((${H})\\b|\\.)?|(${H})\\b`},{begin:"\\b(0|[1-9](_?[0-9])*)n\\b"},{begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*n?\\b"},{begin:"\\b0[oO][0-7](_?[0-7])*n?\\b"},{begin:"\\b0[0-7]+n?\\b"}],relevance:0},ie={className:"subst",begin:"\\$\\{",end:"\\}",keywords:ue,contains:[]},he={begin:"html`",end:"",starts:{end:"`",returnEnd:!1,contains:[L.BACKSLASH_ESCAPE,ie],subLanguage:"xml"}},ge={begin:"css`",end:"",starts:{end:"`",returnEnd:!1,contains:[L.BACKSLASH_ESCAPE,ie],subLanguage:"css"}},De={className:"string",begin:"`",end:"`",contains:[L.BACKSLASH_ESCAPE,ie]},lt={className:"comment",variants:[L.COMMENT(/\/\*\*(?!\/)/,"\\*/",{relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+",contains:[{className:"type",begin:"\\{",end:"\\}",relevance:0},{className:"variable",begin:J+"(?=\\s*(-)|$)",endsParent:!0,relevance:0},{begin:/(?=[^\n])\s/,relevance:0}]}]}),L.C_BLOCK_COMMENT_MODE,L.C_LINE_COMMENT_MODE]},Ve=[L.APOS_STRING_MODE,L.QUOTE_STRING_MODE,he,ge,De,Ee,L.REGEXP_MODE];ie.contains=Ve.concat({begin:/\{/,end:/\}/,keywords:ue,contains:["self"].concat(Ve)});const ze=[].concat(lt,ie.contains),Be=ze.concat([{begin:/\(/,end:/\)/,keywords:ue,contains:["self"].concat(ze)}]),Pe={className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:ue,contains:Be};return{name:"Javascript",aliases:["js","jsx","mjs","cjs"],keywords:ue,exports:{PARAMS_CONTAINS:Be},illegal:/#(?![$_A-z])/,contains:[L.SHEBANG({label:"shebang",binary:"node",relevance:5}),{label:"use_strict",className:"meta",relevance:10,begin:/^\s*['"]use (strict|asm)['"]/},L.APOS_STRING_MODE,L.QUOTE_STRING_MODE,he,ge,De,lt,Ee,{begin:A(/[{,\n]\s*/,S(A(/(((\/\/.*$)|(\/\*(\*[^/]|[^*])*\*\/))\s*)*/,J+"\\s*:"))),relevance:0,contains:[{className:"attr",begin:J+S("\\s*:"),relevance:0}]},{begin:"("+L.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",contains:[lt,L.REGEXP_MODE,{className:"function",begin:"(\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)|"+L.UNDERSCORE_IDENT_RE+")\\s*=>",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:L.UNDERSCORE_IDENT_RE,relevance:0},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:ue,contains:Be}]}]},{begin:/,/,relevance:0},{className:"",begin:/\s/,end:/\s*/,skip:!0},{variants:[{begin:"<>",end:"</>"},{begin:ee.begin,"on:begin":ee.isTrulyOpeningTag,end:ee.end}],subLanguage:"xml",contains:[{begin:ee.begin,end:ee.end,skip:!0,contains:["self"]}]}],relevance:0},{className:"function",beginKeywords:"function",end:/[{;]/,excludeEnd:!0,keywords:ue,contains:["self",L.inherit(L.TITLE_MODE,{begin:J}),Pe],illegal:/%/},{beginKeywords:"while if switch catch for"},{className:"function",begin:L.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",returnBegin:!0,contains:[Pe,L.inherit(L.TITLE_MODE,{begin:J})]},{variants:[{begin:"\\."+J},{begin:"\\$"+J}],relevance:0},{className:"class",beginKeywords:"class",end:/[{;=]/,excludeEnd:!0,illegal:/[:"[\]]/,contains:[{beginKeywords:"extends"},L.UNDERSCORE_TITLE_MODE]},{begin:/\b(?=constructor)/,end:/[{;]/,excludeEnd:!0,contains:[L.inherit(L.TITLE_MODE,{begin:J}),"self",Pe]},{begin:"(get|set)\\s+(?="+J+"\\()",end:/\{/,keywords:"get set",contains:[L.inherit(L.TITLE_MODE,{begin:J}),{begin:/\(\)/},Pe]},{begin:/\$[(.]/}]}}},92229:v=>{v.exports=function(i){const r={literal:"true false null"},u=[i.C_LINE_COMMENT_MODE,i.C_BLOCK_COMMENT_MODE],p=[i.QUOTE_STRING_MODE,i.C_NUMBER_MODE],d={end:",",endsWithParent:!0,excludeEnd:!0,contains:p,keywords:r},e={begin:/\{/,end:/\}/,contains:[{className:"attr",begin:/"/,end:/"/,contains:[i.BACKSLASH_ESCAPE],illegal:"\\n"},i.inherit(d,{begin:/:/})].concat(u),illegal:"\\S"},_={begin:"\\[",end:"\\]",contains:[i.inherit(d)],illegal:"\\S"};return p.push(e,_),u.forEach(function(y){p.push(y)}),{name:"JSON",contains:p,keywords:r,illegal:"\\S"}}},78932:v=>{v.exports=function(i){const d={$pattern:/-?[A-z\.\-]+\b/,keyword:"if else foreach return do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch hidden static parameter",built_in:"ac asnp cat cd CFS chdir clc clear clhy cli clp cls clv cnsn compare copy cp cpi cpp curl cvpa dbp del diff dir dnsn ebp echo|0 epal epcsv epsn erase etsn exsn fc fhx fl ft fw gal gbp gc gcb gci gcm gcs gdr gerr ghy gi gin gjb gl gm gmo gp gps gpv group gsn gsnp gsv gtz gu gv gwmi h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi iwr kill lp ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv oh popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo rni rnp rp rsn rsnp rujb rv rvpa rwmi sajb sal saps sasv sbp sc scb select set shcm si sl sleep sls sort sp spjb spps spsv start stz sujb sv swmi tee trcm type wget where wjb write"},_={begin:"`[\\s\\S]",relevance:0},y={className:"variable",variants:[{begin:/\$\B/},{className:"keyword",begin:/\$this/},{begin:/\$[\w\d][\w\d_:]*/}]},A={className:"string",variants:[{begin:/"/,end:/"/},{begin:/@"/,end:/^"@/}],contains:[_,y,{className:"variable",begin:/\$[A-z]/,end:/[^A-z]/}]},N={className:"string",variants:[{begin:/'/,end:/'/},{begin:/@'/,end:/^'@/}]},Z=i.inherit(i.COMMENT(null,null),{variants:[{begin:/#/,end:/$/},{begin:/<#/,end:/#>/}],contains:[{className:"doctag",variants:[{begin:/\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/},{begin:/\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\s+\S+/}]}]}),J={className:"built_in",variants:[{begin:"(".concat("Add|Clear|Close|Copy|Enter|Exit|Find|Format|Get|Hide|Join|Lock|Move|New|Open|Optimize|Pop|Push|Redo|Remove|Rename|Reset|Resize|Search|Select|Set|Show|Skip|Split|Step|Switch|Undo|Unlock|Watch|Backup|Checkpoint|Compare|Compress|Convert|ConvertFrom|ConvertTo|Dismount|Edit|Expand|Export|Group|Import|Initialize|Limit|Merge|Mount|Out|Publish|Restore|Save|Sync|Unpublish|Update|Approve|Assert|Build|Complete|Confirm|Deny|Deploy|Disable|Enable|Install|Invoke|Register|Request|Restart|Resume|Start|Stop|Submit|Suspend|Uninstall|Unregister|Wait|Debug|Measure|Ping|Repair|Resolve|Test|Trace|Connect|Disconnect|Read|Receive|Send|Write|Block|Grant|Protect|Revoke|Unblock|Unprotect|Use|ForEach|Sort|Tee|Where",")+(-)[\\w\\d]+")}]},K={className:"class",beginKeywords:"class enum",end:/\s*[{]/,excludeEnd:!0,relevance:0,contains:[i.TITLE_MODE]},ee={className:"function",begin:/function\s+/,end:/\s*\{|$/,excludeEnd:!0,returnBegin:!0,relevance:0,contains:[{begin:"function",relevance:0,className:"keyword"},{className:"title",begin:/\w[\w\d]*((-)[\w\d]+)*/,relevance:0},{begin:/\(/,end:/\)/,className:"params",relevance:0,contains:[y]}]},ue={begin:/using\s/,end:/$/,returnBegin:!0,contains:[A,N,{className:"keyword",begin:/(using|assembly|command|module|namespace|type)/}]},ae={variants:[{className:"operator",begin:"(".concat("-and|-as|-band|-bnot|-bor|-bxor|-casesensitive|-ccontains|-ceq|-cge|-cgt|-cle|-clike|-clt|-cmatch|-cne|-cnotcontains|-cnotlike|-cnotmatch|-contains|-creplace|-csplit|-eq|-exact|-f|-file|-ge|-gt|-icontains|-ieq|-ige|-igt|-ile|-ilike|-ilt|-imatch|-in|-ine|-inotcontains|-inotlike|-inotmatch|-ireplace|-is|-isnot|-isplit|-join|-le|-like|-lt|-match|-ne|-not|-notcontains|-notin|-notlike|-notmatch|-or|-regex|-replace|-shl|-shr|-split|-wildcard|-xor",")\\b")},{className:"literal",begin:/(-)[\w\d]+/,relevance:0}]},se={className:"function",begin:/\[.*\]\s*[\w]+[ ]??\(/,end:/$/,returnBegin:!0,relevance:0,contains:[{className:"keyword",begin:"(".concat(d.keyword.toString().replace(/\s/g,"|"),")\\b"),endsParent:!0,relevance:0},i.inherit(i.TITLE_MODE,{endsParent:!0})]},Ee=[se,Z,_,i.NUMBER_MODE,A,N,J,y,{className:"literal",begin:/\$(null|true|false)\b/},{className:"selector-tag",begin:/@\B/,relevance:0}],ie={begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[].concat("self",Ee,{begin:"("+["string","char","byte","int","long","bool","decimal","single","double","DateTime","xml","array","hashtable","void"].join("|")+")",className:"built_in",relevance:0},{className:"type",begin:/[\.\w\d]+/,relevance:0})};return se.contains.unshift(ie),{name:"PowerShell",aliases:["ps","ps1"],case_insensitive:!0,keywords:d,contains:Ee.concat(K,ee,ue,ae,ie)}}},13546:v=>{function T(e){return e?"string"==typeof e?e:e.source:null}function i(e){return u("(?=",e,")")}function u(...e){return e.map(y=>T(y)).join("")}function p(...e){return"("+e.map(y=>T(y)).join("|")+")"}v.exports=function(e){const _=u(/[A-Z_]/,u("(",/[A-Z0-9_.-]*:/,")?"),/[A-Z0-9_.-]*/),S={className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},A={begin:/\s/,contains:[{className:"meta-keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]},N=e.inherit(A,{begin:/\(/,end:/\)/}),L=e.inherit(e.APOS_STRING_MODE,{className:"meta-string"}),Z=e.inherit(e.QUOTE_STRING_MODE,{className:"meta-string"}),J={endsWithParent:!0,illegal:/</,relevance:0,contains:[{className:"attr",begin:/[A-Za-z0-9._:-]+/,relevance:0},{begin:/=\s*/,relevance:0,contains:[{className:"string",endsParent:!0,variants:[{begin:/"/,end:/"/,contains:[S]},{begin:/'/,end:/'/,contains:[S]},{begin:/[^\s"'=<>`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,contains:[{className:"meta",begin:/<![a-z]/,end:/>/,relevance:10,contains:[A,Z,L,N,{begin:/\[/,end:/\]/,contains:[{className:"meta",begin:/<![a-z]/,end:/>/,contains:[A,N,Z,L]}]}]},e.COMMENT(/<!--/,/-->/,{relevance:10}),{begin:/<!\[CDATA\[/,end:/\]\]>/,relevance:10},S,{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:/<style(?=\s|>)/,end:/>/,keywords:{name:"style"},contains:[J],starts:{end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:/<script(?=\s|>)/,end:/>/,keywords:{name:"script"},contains:[J],starts:{end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{className:"tag",begin:/<>|<\/>/},{className:"tag",begin:u(/</,i(u(_,p(/\/>/,/>/,/\s/)))),end:/\/?>/,contains:[{className:"name",begin:_,relevance:0,starts:J}]},{className:"tag",begin:u(/<\//,i(u(_,/>/))),contains:[{className:"name",begin:_,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}}},44776:v=>{v.exports=function(i){var r="true false yes no null",u="[\\w#;/?:@&=+$,.~*'()[\\]]+",e={className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/\S+/}],contains:[i.BACKSLASH_ESCAPE,{className:"template-variable",variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},_=i.inherit(e,{variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),Z={end:",",endsWithParent:!0,excludeEnd:!0,keywords:r,relevance:0},ee=[{className:"attr",variants:[{begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---\\s*$",relevance:10},{className:"string",begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:"!\\w+!"+u},{className:"type",begin:"!<"+u+">"},{className:"type",begin:"!"+u},{className:"type",begin:"!!"+u},{className:"meta",begin:"&"+i.UNDERSCORE_IDENT_RE+"$"},{className:"meta",begin:"\\*"+i.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)",relevance:0},i.HASH_COMMENT_MODE,{beginKeywords:r,keywords:{literal:r}},{className:"number",begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b"},{className:"number",begin:i.C_NUMBER_RE+"\\b",relevance:0},{begin:/\{/,end:/\}/,contains:[Z],illegal:"\\n",relevance:0},{begin:"\\[",end:"\\]",contains:[Z],illegal:"\\n",relevance:0},e],ue=[...ee];return ue.pop(),ue.push(_),Z.contains=ue,{name:"YAML",case_insensitive:!0,aliases:["yml"],contains:ee}}},62568:(v,T,i)=>{"use strict";var r=i(38308),u={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},p={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},e={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},_={};function y(ee){return r.isMemo(ee)?e:_[ee.$$typeof]||u}_[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},_[r.Memo]=e;var S=Object.defineProperty,A=Object.getOwnPropertyNames,N=Object.getOwnPropertySymbols,L=Object.getOwnPropertyDescriptor,Z=Object.getPrototypeOf,J=Object.prototype;v.exports=function K(ee,ue,ae){if("string"!=typeof ue){if(J){var H=Z(ue);H&&H!==J&&K(ee,H,ae)}var se=A(ue);N&&(se=se.concat(N(ue)));for(var Ee=y(ee),ie=y(ue),he=0;he<se.length;++he){var ge=se[he];if(!(p[ge]||ae&&ae[ge]||ie&&ie[ge]||Ee&&Ee[ge])){var De=L(ue,ge);try{S(ee,ge,De)}catch(ce){}}}}return ee}},12658:(v,T)=>{T.read=function(i,r,u,p,d){var e,_,y=8*d-p-1,S=(1<<y)-1,A=S>>1,N=-7,L=u?d-1:0,Z=u?-1:1,J=i[r+L];for(L+=Z,e=J&(1<<-N)-1,J>>=-N,N+=y;N>0;e=256*e+i[r+L],L+=Z,N-=8);for(_=e&(1<<-N)-1,e>>=-N,N+=p;N>0;_=256*_+i[r+L],L+=Z,N-=8);if(0===e)e=1-A;else{if(e===S)return _?NaN:1/0*(J?-1:1);_+=Math.pow(2,p),e-=A}return(J?-1:1)*_*Math.pow(2,e-p)},T.write=function(i,r,u,p,d,e){var _,y,S,A=8*e-d-1,N=(1<<A)-1,L=N>>1,Z=23===d?Math.pow(2,-24)-Math.pow(2,-77):0,J=p?0:e-1,K=p?1:-1,ee=r<0||0===r&&1/r<0?1:0;for(r=Math.abs(r),isNaN(r)||r===1/0?(y=isNaN(r)?1:0,_=N):(_=Math.floor(Math.log(r)/Math.LN2),r*(S=Math.pow(2,-_))<1&&(_--,S*=2),(r+=_+L>=1?Z/S:Z*Math.pow(2,1-L))*S>=2&&(_++,S/=2),_+L>=N?(y=0,_=N):_+L>=1?(y=(r*S-1)*Math.pow(2,d),_+=L):(y=r*Math.pow(2,L-1)*Math.pow(2,d),_=0));d>=8;i[u+J]=255&y,J+=K,y/=256,d-=8);for(_=_<<d|y,A+=d;A>0;i[u+J]=255&_,J+=K,_/=256,A-=8);i[u+J-K]|=128*ee}},16482:function(v){v.exports=function(){"use strict";var T=Array.prototype.slice;function i(V,Ae){Ae&&(V.prototype=Object.create(Ae.prototype)),V.prototype.constructor=V}function r(V){return e(V)?V:di(V)}function u(V){return _(V)?V:Lr(V)}function p(V){return y(V)?V:Mr(V)}function d(V){return e(V)&&!S(V)?V:Kr(V)}function e(V){return!(!V||!V[N])}function _(V){return!(!V||!V[L])}function y(V){return!(!V||!V[Z])}function S(V){return _(V)||y(V)}function A(V){return!(!V||!V[J])}i(u,r),i(p,r),i(d,r),r.isIterable=e,r.isKeyed=_,r.isIndexed=y,r.isAssociative=S,r.isOrdered=A,r.Keyed=u,r.Indexed=p,r.Set=d;var N="@@__IMMUTABLE_ITERABLE__@@",L="@@__IMMUTABLE_KEYED__@@",Z="@@__IMMUTABLE_INDEXED__@@",J="@@__IMMUTABLE_ORDERED__@@",K="delete",H={},se={value:!1},Ee={value:!1};function ie(V){return V.value=!1,V}function he(V){V&&(V.value=!0)}function ge(){}function De(V,Ae){Ae=Ae||0;for(var st=Math.max(0,V.length-Ae),vt=new Array(st),ut=0;ut<st;ut++)vt[ut]=V[ut+Ae];return vt}function ce(V){return void 0===V.size&&(V.size=V.__iterate(Ve)),V.size}function lt(V,Ae){if("number"!=typeof Ae){var st=Ae>>>0;if(""+st!==Ae||4294967295===st)return NaN;Ae=st}return Ae<0?ce(V)+Ae:Ae}function Ve(){return!0}function ze(V,Ae,st){return(0===V||void 0!==st&&V<=-st)&&(void 0===Ae||void 0!==st&&Ae>=st)}function Be(V,Ae){return je(V,Ae,0)}function Pe(V,Ae){return je(V,Ae,Ae)}function je(V,Ae,st){return void 0===V?st:V<0?Math.max(0,Ae+V):void 0===Ae?V:Math.min(Ae,V)}var tn="function"==typeof Symbol&&Symbol.iterator,It="@@iterator",Zt=tn||It;function Ut(V){this.next=V}function Bt(V,Ae,st,vt){var ut=0===V?Ae:1===V?st:[Ae,st];return vt?vt.value=ut:vt={value:ut,done:!1},vt}function bt(){return{value:void 0,done:!0}}function Gt(V){return!!Zn(V)}function xt(V){return V&&"function"==typeof V.next}function Xt(V){var Ae=Zn(V);return Ae&&Ae.call(V)}function Zn(V){var Ae=V&&(tn&&V[tn]||V[It]);if("function"==typeof Ae)return Ae}function Ur(V){return V&&"number"==typeof V.length}function di(V){return null==V?Hi():e(V)?V.toSeq():function(V){var Ae=zn(V)||"object"==typeof V&&new $n(V);if(!Ae)throw new TypeError("Expected Array or iterable object of values, or keyed object: "+V);return Ae}(V)}function Lr(V){return null==V?Hi().toKeyedSeq():e(V)?_(V)?V.toSeq():V.fromEntrySeq():Zr(V)}function Mr(V){return null==V?Hi():e(V)?_(V)?V.entrySeq():V.toIndexedSeq():Cn(V)}function Kr(V){return(null==V?Hi():e(V)?_(V)?V.entrySeq():V:Cn(V)).toSetSeq()}Ut.prototype.toString=function(){return"[Iterator]"},Ut.KEYS=0,Ut.VALUES=1,Ut.ENTRIES=2,Ut.prototype.inspect=Ut.prototype.toSource=function(){return this.toString()},Ut.prototype[Zt]=function(){return this},i(di,r),di.of=function(){return di(arguments)},di.prototype.toSeq=function(){return this},di.prototype.toString=function(){return this.__toString("Seq {","}")},di.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},di.prototype.__iterate=function(V,Ae){return rr(this,V,Ae,!0)},di.prototype.__iterator=function(V,Ae){return Fr(this,V,Ae,!0)},i(Lr,di),Lr.prototype.toKeyedSeq=function(){return this},i(Mr,di),Mr.of=function(){return Mr(arguments)},Mr.prototype.toIndexedSeq=function(){return this},Mr.prototype.toString=function(){return this.__toString("Seq [","]")},Mr.prototype.__iterate=function(V,Ae){return rr(this,V,Ae,!1)},Mr.prototype.__iterator=function(V,Ae){return Fr(this,V,Ae,!1)},i(Kr,di),Kr.of=function(){return Kr(arguments)},Kr.prototype.toSetSeq=function(){return this},di.isSeq=fi,di.Keyed=Lr,di.Set=Kr,di.Indexed=Mr;var ki,yn,Vn,ei="@@__IMMUTABLE_SEQ__@@";function Nn(V){this._array=V,this.size=V.length}function $n(V){var Ae=Object.keys(V);this._object=V,this._keys=Ae,this.size=Ae.length}function Br(V){this._iterable=V,this.size=V.length||V.size}function Yr(V){this._iterator=V,this._iteratorCache=[]}function fi(V){return!(!V||!V[ei])}function Hi(){return ki||(ki=new Nn([]))}function Zr(V){var Ae=Array.isArray(V)?new Nn(V).fromEntrySeq():xt(V)?new Yr(V).fromEntrySeq():Gt(V)?new Br(V).fromEntrySeq():"object"==typeof V?new $n(V):void 0;if(!Ae)throw new TypeError("Expected Array or iterable object of [k, v] entries, or keyed object: "+V);return Ae}function Cn(V){var Ae=zn(V);if(!Ae)throw new TypeError("Expected Array or iterable object of values: "+V);return Ae}function zn(V){return Ur(V)?new Nn(V):xt(V)?new Yr(V):Gt(V)?new Br(V):void 0}function rr(V,Ae,st,vt){var ut=V._cache;if(ut){for(var un=ut.length-1,mn=0;mn<=un;mn++){var Or=ut[st?un-mn:mn];if(!1===Ae(Or[1],vt?Or[0]:mn,V))return mn+1}return mn}return V.__iterateUncached(Ae,st)}function Fr(V,Ae,st,vt){var ut=V._cache;if(ut){var un=ut.length-1,mn=0;return new Ut(function(){var Or=ut[st?un-mn:mn];return mn++>un?{value:void 0,done:!0}:Bt(Ae,vt?Or[0]:mn-1,Or[1])})}return V.__iteratorUncached(Ae,st)}function Gn(V,Ae){return Ae?Jr(Ae,V,"",{"":V}):_i(V)}function Jr(V,Ae,st,vt){return Array.isArray(Ae)?V.call(vt,st,Mr(Ae).map(function(ut,un){return Jr(V,ut,un,Ae)})):wi(Ae)?V.call(vt,st,Lr(Ae).map(function(ut,un){return Jr(V,ut,un,Ae)})):Ae}function _i(V){return Array.isArray(V)?Mr(V).map(_i).toList():wi(V)?Lr(V).map(_i).toMap():V}function wi(V){return V&&(V.constructor===Object||void 0===V.constructor)}function br(V,Ae){if(V===Ae||V!=V&&Ae!=Ae)return!0;if(!V||!Ae)return!1;if("function"==typeof V.valueOf&&"function"==typeof Ae.valueOf){if((V=V.valueOf())===(Ae=Ae.valueOf())||V!=V&&Ae!=Ae)return!0;if(!V||!Ae)return!1}return!("function"!=typeof V.equals||"function"!=typeof Ae.equals||!V.equals(Ae))}function Dr(V,Ae){if(V===Ae)return!0;if(!e(Ae)||void 0!==V.size&&void 0!==Ae.size&&V.size!==Ae.size||void 0!==V.__hash&&void 0!==Ae.__hash&&V.__hash!==Ae.__hash||_(V)!==_(Ae)||y(V)!==y(Ae)||A(V)!==A(Ae))return!1;if(0===V.size&&0===Ae.size)return!0;var st=!S(V);if(A(V)){var vt=V.entries();return Ae.every(function(zr,gi){var ai=vt.next().value;return ai&&br(ai[1],zr)&&(st||br(ai[0],gi))})&&vt.next().done}var ut=!1;if(void 0===V.size)if(void 0===Ae.size)"function"==typeof V.cacheResult&&V.cacheResult();else{ut=!0;var un=V;V=Ae,Ae=un}var mn=!0,Or=Ae.__iterate(function(zr,gi){if(st?!V.has(zr):ut?!br(zr,V.get(gi,H)):!br(V.get(gi,H),zr))return mn=!1,!1});return mn&&V.size===Or}function gn(V,Ae){if(!(this instanceof gn))return new gn(V,Ae);if(this._value=V,this.size=void 0===Ae?1/0:Math.max(0,Ae),0===this.size){if(yn)return yn;yn=this}}function gr(V,Ae){if(!V)throw new Error(Ae)}function Jt(V,Ae,st){if(!(this instanceof Jt))return new Jt(V,Ae,st);if(gr(0!==st,"Cannot step a Range by 0"),V=V||0,void 0===Ae&&(Ae=1/0),st=void 0===st?1:Math.abs(st),Ae<V&&(st=-st),this._start=V,this._end=Ae,this._step=st,this.size=Math.max(0,Math.ceil((Ae-V)/st-1)+1),0===this.size){if(Vn)return Vn;Vn=this}}function mr(){throw TypeError("Abstract")}function Dn(){}function Pr(){}function Yt(){}di.prototype[ei]=!0,i(Nn,Mr),Nn.prototype.get=function(V,Ae){return this.has(V)?this._array[lt(this,V)]:Ae},Nn.prototype.__iterate=function(V,Ae){for(var st=this._array,vt=st.length-1,ut=0;ut<=vt;ut++)if(!1===V(st[Ae?vt-ut:ut],ut,this))return ut+1;return ut},Nn.prototype.__iterator=function(V,Ae){var st=this._array,vt=st.length-1,ut=0;return new Ut(function(){return ut>vt?{value:void 0,done:!0}:Bt(V,ut,st[Ae?vt-ut++:ut++])})},i($n,Lr),$n.prototype.get=function(V,Ae){return void 0===Ae||this.has(V)?this._object[V]:Ae},$n.prototype.has=function(V){return this._object.hasOwnProperty(V)},$n.prototype.__iterate=function(V,Ae){for(var st=this._object,vt=this._keys,ut=vt.length-1,un=0;un<=ut;un++){var mn=vt[Ae?ut-un:un];if(!1===V(st[mn],mn,this))return un+1}return un},$n.prototype.__iterator=function(V,Ae){var st=this._object,vt=this._keys,ut=vt.length-1,un=0;return new Ut(function(){var mn=vt[Ae?ut-un:un];return un++>ut?{value:void 0,done:!0}:Bt(V,mn,st[mn])})},$n.prototype[J]=!0,i(Br,Mr),Br.prototype.__iterateUncached=function(V,Ae){if(Ae)return this.cacheResult().__iterate(V,Ae);var vt=Xt(this._iterable),ut=0;if(xt(vt))for(var un;!(un=vt.next()).done&&!1!==V(un.value,ut++,this););return ut},Br.prototype.__iteratorUncached=function(V,Ae){if(Ae)return this.cacheResult().__iterator(V,Ae);var vt=Xt(this._iterable);if(!xt(vt))return new Ut(bt);var ut=0;return new Ut(function(){var un=vt.next();return un.done?un:Bt(V,ut++,un.value)})},i(Yr,Mr),Yr.prototype.__iterateUncached=function(V,Ae){if(Ae)return this.cacheResult().__iterate(V,Ae);for(var st=this._iterator,vt=this._iteratorCache,ut=0;ut<vt.length;)if(!1===V(vt[ut],ut++,this))return ut;for(var un;!(un=st.next()).done;){var mn=un.value;if(vt[ut]=mn,!1===V(mn,ut++,this))break}return ut},Yr.prototype.__iteratorUncached=function(V,Ae){if(Ae)return this.cacheResult().__iterator(V,Ae);var st=this._iterator,vt=this._iteratorCache,ut=0;return new Ut(function(){if(ut>=vt.length){var un=st.next();if(un.done)return un;vt[ut]=un.value}return Bt(V,ut,vt[ut++])})},i(gn,Mr),gn.prototype.toString=function(){return 0===this.size?"Repeat []":"Repeat [ "+this._value+" "+this.size+" times ]"},gn.prototype.get=function(V,Ae){return this.has(V)?this._value:Ae},gn.prototype.includes=function(V){return br(this._value,V)},gn.prototype.slice=function(V,Ae){var st=this.size;return ze(V,Ae,st)?this:new gn(this._value,Pe(Ae,st)-Be(V,st))},gn.prototype.reverse=function(){return this},gn.prototype.indexOf=function(V){return br(this._value,V)?0:-1},gn.prototype.lastIndexOf=function(V){return br(this._value,V)?this.size:-1},gn.prototype.__iterate=function(V,Ae){for(var st=0;st<this.size;st++)if(!1===V(this._value,st,this))return st+1;return st},gn.prototype.__iterator=function(V,Ae){var st=this,vt=0;return new Ut(function(){return vt<st.size?Bt(V,vt++,st._value):{value:void 0,done:!0}})},gn.prototype.equals=function(V){return V instanceof gn?br(this._value,V._value):Dr(V)},i(Jt,Mr),Jt.prototype.toString=function(){return 0===this.size?"Range []":"Range [ "+this._start+"..."+this._end+(1!==this._step?" by "+this._step:"")+" ]"},Jt.prototype.get=function(V,Ae){return this.has(V)?this._start+lt(this,V)*this._step:Ae},Jt.prototype.includes=function(V){var Ae=(V-this._start)/this._step;return Ae>=0&&Ae<this.size&&Ae===Math.floor(Ae)},Jt.prototype.slice=function(V,Ae){return ze(V,Ae,this.size)?this:(V=Be(V,this.size),(Ae=Pe(Ae,this.size))<=V?new Jt(0,0):new Jt(this.get(V,this._end),this.get(Ae,this._end),this._step))},Jt.prototype.indexOf=function(V){var Ae=V-this._start;if(Ae%this._step==0){var st=Ae/this._step;if(st>=0&&st<this.size)return st}return-1},Jt.prototype.lastIndexOf=function(V){return this.indexOf(V)},Jt.prototype.__iterate=function(V,Ae){for(var st=this.size-1,vt=this._step,ut=Ae?this._start+st*vt:this._start,un=0;un<=st;un++){if(!1===V(ut,un,this))return un+1;ut+=Ae?-vt:vt}return un},Jt.prototype.__iterator=function(V,Ae){var st=this.size-1,vt=this._step,ut=Ae?this._start+st*vt:this._start,un=0;return new Ut(function(){var mn=ut;return ut+=Ae?-vt:vt,un>st?{value:void 0,done:!0}:Bt(V,un++,mn)})},Jt.prototype.equals=function(V){return V instanceof Jt?this._start===V._start&&this._end===V._end&&this._step===V._step:Dr(this,V)},i(mr,r),i(Dn,mr),i(Pr,mr),i(Yt,mr),mr.Keyed=Dn,mr.Indexed=Pr,mr.Set=Yt;var _n="function"==typeof Math.imul&&-2===Math.imul(4294967295,2)?Math.imul:function(Ae,st){var vt=65535&(Ae|=0),ut=65535&(st|=0);return vt*ut+((Ae>>>16)*ut+vt*(st>>>16)<<16>>>0)|0};function Ge(V){return V>>>1&1073741824|3221225471&V}function kr(V){if(!1===V||null==V||"function"==typeof V.valueOf&&(!1===(V=V.valueOf())||null==V))return 0;if(!0===V)return 1;var Ae=typeof V;if("number"===Ae){if(V!=V||V===1/0)return 0;var st=0|V;for(st!==V&&(st^=4294967295*V);V>4294967295;)st^=V/=4294967295;return Ge(st)}if("string"===Ae)return V.length>Co?function(V){var Ae=jo[V];return void 0===Ae&&(Ae=An(V),os===Gi&&(os=0,jo={}),os++,jo[V]=Ae),Ae}(V):An(V);if("function"==typeof V.hashCode)return V.hashCode();if("object"===Ae)return function(V){var Ae;if(ar&&void 0!==(Ae=Wi.get(V))||void 0!==(Ae=V[vo])||!dr&&(void 0!==(Ae=V.propertyIsEnumerable&&V.propertyIsEnumerable[vo])||void 0!==(Ae=function(V){if(V&&V.nodeType>0)switch(V.nodeType){case 1:return V.uniqueID;case 9:return V.documentElement&&V.documentElement.uniqueID}}(V))))return Ae;if(Ae=++lo,1073741824&lo&&(lo=0),ar)Wi.set(V,Ae);else{if(void 0!==Wr&&!1===Wr(V))throw new Error("Non-extensible objects are not allowed as keys.");if(dr)Object.defineProperty(V,vo,{enumerable:!1,configurable:!1,writable:!1,value:Ae});else if(void 0!==V.propertyIsEnumerable&&V.propertyIsEnumerable===V.constructor.prototype.propertyIsEnumerable)V.propertyIsEnumerable=function(){return this.constructor.prototype.propertyIsEnumerable.apply(this,arguments)},V.propertyIsEnumerable[vo]=Ae;else{if(void 0===V.nodeType)throw new Error("Unable to set a non-enumerable property on object.");V[vo]=Ae}}return Ae}(V);if("function"==typeof V.toString)return An(V.toString());throw new Error("Value type "+Ae+" cannot be hashed.")}function An(V){for(var Ae=0,st=0;st<V.length;st++)Ae=31*Ae+V.charCodeAt(st)|0;return Ge(Ae)}var Wr=Object.isExtensible,dr=function(){try{return Object.defineProperty({},"@",{}),!0}catch(V){return!1}}();var Wi,ar="function"==typeof WeakMap;ar&&(Wi=new WeakMap);var lo=0,vo="__immutablehash__";"function"==typeof Symbol&&(vo=Symbol(vo));var Co=16,Gi=255,os=0,jo={};function To(V){gr(V!==1/0,"Cannot perform this action with an infinite size.")}function Mi(V){return null==V?mt():li(V)&&!A(V)?V:mt().withMutations(function(Ae){var st=u(V);To(st.size),st.forEach(function(vt,ut){return Ae.set(ut,vt)})})}function li(V){return!(!V||!V[Bn])}i(Mi,Dn),Mi.of=function(){var V=T.call(arguments,0);return mt().withMutations(function(Ae){for(var st=0;st<V.length;st+=2){if(st+1>=V.length)throw new Error("Missing value for key: "+V[st]);Ae.set(V[st],V[st+1])}})},Mi.prototype.toString=function(){return this.__toString("Map {","}")},Mi.prototype.get=function(V,Ae){return this._root?this._root.get(0,void 0,V,Ae):Ae},Mi.prototype.set=function(V,Ae){return jt(this,V,Ae)},Mi.prototype.setIn=function(V,Ae){return this.updateIn(V,H,function(){return Ae})},Mi.prototype.remove=function(V){return jt(this,V,H)},Mi.prototype.deleteIn=function(V){return this.updateIn(V,function(){return H})},Mi.prototype.update=function(V,Ae,st){return 1===arguments.length?V(this):this.updateIn([V],Ae,st)},Mi.prototype.updateIn=function(V,Ae,st){st||(st=Ae,Ae=void 0);var vt=Is(this,Qi(V),Ae,st);return vt===H?void 0:vt},Mi.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._root=null,this.__hash=void 0,this.__altered=!0,this):mt()},Mi.prototype.merge=function(){return Zs(this,void 0,arguments)},Mi.prototype.mergeWith=function(V){return Zs(this,V,T.call(arguments,1))},Mi.prototype.mergeIn=function(V){var Ae=T.call(arguments,1);return this.updateIn(V,mt(),function(st){return"function"==typeof st.merge?st.merge.apply(st,Ae):Ae[Ae.length-1]})},Mi.prototype.mergeDeep=function(){return Zs(this,ls,arguments)},Mi.prototype.mergeDeepWith=function(V){var Ae=T.call(arguments,1);return Zs(this,La(V),Ae)},Mi.prototype.mergeDeepIn=function(V){var Ae=T.call(arguments,1);return this.updateIn(V,mt(),function(st){return"function"==typeof st.mergeDeep?st.mergeDeep.apply(st,Ae):Ae[Ae.length-1]})},Mi.prototype.sort=function(V){return ne(tl(this,V))},Mi.prototype.sortBy=function(V,Ae){return ne(tl(this,Ae,V))},Mi.prototype.withMutations=function(V){var Ae=this.asMutable();return V(Ae),Ae.wasAltered()?Ae.__ensureOwner(this.__ownerID):this},Mi.prototype.asMutable=function(){return this.__ownerID?this:this.__ensureOwner(new ge)},Mi.prototype.asImmutable=function(){return this.__ensureOwner()},Mi.prototype.wasAltered=function(){return this.__altered},Mi.prototype.__iterator=function(V,Ae){return new $o(this,V,Ae)},Mi.prototype.__iterate=function(V,Ae){var st=this,vt=0;return this._root&&this._root.iterate(function(ut){return vt++,V(ut[1],ut[0],st)},Ae),vt},Mi.prototype.__ensureOwner=function(V){return V===this.__ownerID?this:V?Rt(this.size,this._root,V,this.__hash):(this.__ownerID=V,this.__altered=!1,this)},Mi.isMap=li;var _t,Bn="@@__IMMUTABLE_MAP__@@",lr=Mi.prototype;function vr(V,Ae){this.ownerID=V,this.entries=Ae}function er(V,Ae,st){this.ownerID=V,this.bitmap=Ae,this.nodes=st}function ri(V,Ae,st){this.ownerID=V,this.count=Ae,this.nodes=st}function uo(V,Ae,st){this.ownerID=V,this.keyHash=Ae,this.entries=st}function Ci(V,Ae,st){this.ownerID=V,this.keyHash=Ae,this.entry=st}function $o(V,Ae,st){this._type=Ae,this._reverse=st,this._stack=V._root&&Ar(V._root)}function tr(V,Ae){return Bt(V,Ae[0],Ae[1])}function Ar(V,Ae){return{node:V,index:0,__prev:Ae}}function Rt(V,Ae,st,vt){var ut=Object.create(lr);return ut.size=V,ut._root=Ae,ut.__ownerID=st,ut.__hash=vt,ut.__altered=!1,ut}function mt(){return _t||(_t=Rt(0))}function jt(V,Ae,st){var vt,ut;if(V._root){var un=ie(se),mn=ie(Ee);if(vt=on(V._root,V.__ownerID,0,void 0,Ae,st,un,mn),!mn.value)return V;ut=V.size+(un.value?st===H?-1:1:0)}else{if(st===H)return V;ut=1,vt=new vr(V.__ownerID,[[Ae,st]])}return V.__ownerID?(V.size=ut,V._root=vt,V.__hash=void 0,V.__altered=!0,V):vt?Rt(ut,vt):mt()}function on(V,Ae,st,vt,ut,un,mn,Or){return V?V.update(Ae,st,vt,ut,un,mn,Or):un===H?V:(he(Or),he(mn),new Ci(Ae,vt,[ut,un]))}function si(V){return V.constructor===Ci||V.constructor===uo}function Vi(V,Ae,st,vt,ut){if(V.keyHash===vt)return new uo(Ae,vt,[V.entry,ut]);var Or,un=31&(0===st?V.keyHash:V.keyHash>>>st),mn=31&(0===st?vt:vt>>>st);return new er(Ae,1<<un|1<<mn,un===mn?[Vi(V,Ae,st+5,vt,ut)]:(Or=new Ci(Ae,vt,ut),un<mn?[V,Or]:[Or,V]))}function Zs(V,Ae,st){for(var vt=[],ut=0;ut<st.length;ut++){var un=st[ut],mn=u(un);e(un)||(mn=mn.map(function(Or){return Gn(Or)})),vt.push(mn)}return ta(V,Ae,vt)}function ls(V,Ae,st){return V&&V.mergeDeep&&e(Ae)?V.mergeDeep(Ae):br(V,Ae)?V:Ae}function La(V){return function(Ae,st,vt){if(Ae&&Ae.mergeDeepWith&&e(st))return Ae.mergeDeepWith(V,st);var ut=V(Ae,st,vt);return br(Ae,ut)?Ae:ut}}function ta(V,Ae,st){return 0===(st=st.filter(function(vt){return 0!==vt.size})).length?V:0!==V.size||V.__ownerID||1!==st.length?V.withMutations(function(vt){for(var ut=Ae?function(mn,Or){vt.update(Or,H,function(zr){return zr===H?mn:Ae(zr,mn,Or)})}:function(mn,Or){vt.set(Or,mn)},un=0;un<st.length;un++)st[un].forEach(ut)}):V.constructor(st[0])}function Is(V,Ae,st,vt){var ut=V===H,un=Ae.next();if(un.done){var mn=ut?st:V,Or=vt(mn);return Or===mn?V:Or}gr(ut||V&&V.set,"invalid keyPath");var zr=un.value,gi=ut?H:V.get(zr,H),ai=Is(gi,Ae,st,vt);return ai===gi?V:ai===H?V.remove(zr):(ut?mt():V).set(zr,ai)}function us(V){return V=(V=(858993459&(V-=V>>1&1431655765))+(V>>2&858993459))+(V>>4)&252645135,127&(V+=V>>8)+(V>>16)}function ya(V,Ae,st,vt){var ut=vt?V:De(V);return ut[Ae]=st,ut}lr[Bn]=!0,lr[K]=lr.remove,lr.removeIn=lr.deleteIn,vr.prototype.get=function(V,Ae,st,vt){for(var ut=this.entries,un=0,mn=ut.length;un<mn;un++)if(br(st,ut[un][0]))return ut[un][1];return vt},vr.prototype.update=function(V,Ae,st,vt,ut,un,mn){for(var Or=ut===H,zr=this.entries,gi=0,ai=zr.length;gi<ai&&!br(vt,zr[gi][0]);gi++);var Io=gi<ai;if(Io?zr[gi][1]===ut:Or)return this;if(he(mn),(Or||!Io)&&he(un),!Or||1!==zr.length){if(!Io&&!Or&&zr.length>=$s)return function(V,Ae,st,vt){V||(V=new ge);for(var ut=new Ci(V,kr(st),[st,vt]),un=0;un<Ae.length;un++){var mn=Ae[un];ut=ut.update(V,0,void 0,mn[0],mn[1])}return ut}(V,zr,vt,ut);var Fo=V&&V===this.ownerID,In=Fo?zr:De(zr);return Io?Or?gi===ai-1?In.pop():In[gi]=In.pop():In[gi]=[vt,ut]:In.push([vt,ut]),Fo?(this.entries=In,this):new vr(V,In)}},er.prototype.get=function(V,Ae,st,vt){void 0===Ae&&(Ae=kr(st));var ut=1<<(31&(0===V?Ae:Ae>>>V)),un=this.bitmap;return 0==(un&ut)?vt:this.nodes[us(un&ut-1)].get(V+5,Ae,st,vt)},er.prototype.update=function(V,Ae,st,vt,ut,un,mn){void 0===st&&(st=kr(vt));var Or=31&(0===Ae?st:st>>>Ae),zr=1<<Or,gi=this.bitmap,ai=0!=(gi&zr);if(!ai&&ut===H)return this;var Io=us(gi&zr-1),Fo=this.nodes,In=ai?Fo[Io]:void 0,Cr=on(In,V,Ae+5,st,vt,ut,un,mn);if(Cr===In)return this;if(!ai&&Cr&&Fo.length>=da)return function(V,Ae,st,vt,ut){for(var un=0,mn=new Array(32),Or=0;0!==st;Or++,st>>>=1)mn[Or]=1&st?Ae[un++]:void 0;return mn[vt]=ut,new ri(V,un+1,mn)}(V,Fo,gi,Or,Cr);if(ai&&!Cr&&2===Fo.length&&si(Fo[1^Io]))return Fo[1^Io];if(ai&&Cr&&1===Fo.length&&si(Cr))return Cr;var hr=V&&V===this.ownerID,ao=ai?Cr?gi:gi^zr:gi|zr,ys=ai?Cr?ya(Fo,Io,Cr,hr):function(V,Ae,st){var vt=V.length-1;if(st&&Ae===vt)return V.pop(),V;for(var ut=new Array(vt),un=0,mn=0;mn<vt;mn++)mn===Ae&&(un=1),ut[mn]=V[mn+un];return ut}(Fo,Io,hr):function(V,Ae,st,vt){var ut=V.length+1;if(vt&&Ae+1===ut)return V[Ae]=st,V;for(var un=new Array(ut),mn=0,Or=0;Or<ut;Or++)Or===Ae?(un[Or]=st,mn=-1):un[Or]=V[Or+mn];return un}(Fo,Io,Cr,hr);return hr?(this.bitmap=ao,this.nodes=ys,this):new er(V,ao,ys)},ri.prototype.get=function(V,Ae,st,vt){void 0===Ae&&(Ae=kr(st));var un=this.nodes[31&(0===V?Ae:Ae>>>V)];return un?un.get(V+5,Ae,st,vt):vt},ri.prototype.update=function(V,Ae,st,vt,ut,un,mn){void 0===st&&(st=kr(vt));var Or=31&(0===Ae?st:st>>>Ae),gi=this.nodes,ai=gi[Or];if(ut===H&&!ai)return this;var Io=on(ai,V,Ae+5,st,vt,ut,un,mn);if(Io===ai)return this;var Fo=this.count;if(ai){if(!Io&&--Fo<Il)return function(V,Ae,st,vt){for(var ut=0,un=0,mn=new Array(st),Or=0,zr=1,gi=Ae.length;Or<gi;Or++,zr<<=1){var ai=Ae[Or];void 0!==ai&&Or!==vt&&(ut|=zr,mn[un++]=ai)}return new er(V,ut,mn)}(V,gi,Fo,Or)}else Fo++;var In=V&&V===this.ownerID,Cr=ya(gi,Or,Io,In);return In?(this.count=Fo,this.nodes=Cr,this):new ri(V,Fo,Cr)},uo.prototype.get=function(V,Ae,st,vt){for(var ut=this.entries,un=0,mn=ut.length;un<mn;un++)if(br(st,ut[un][0]))return ut[un][1];return vt},uo.prototype.update=function(V,Ae,st,vt,ut,un,mn){void 0===st&&(st=kr(vt));var Or=ut===H;if(st!==this.keyHash)return Or?this:(he(mn),he(un),Vi(this,V,Ae,st,[vt,ut]));for(var zr=this.entries,gi=0,ai=zr.length;gi<ai&&!br(vt,zr[gi][0]);gi++);var Io=gi<ai;if(Io?zr[gi][1]===ut:Or)return this;if(he(mn),(Or||!Io)&&he(un),Or&&2===ai)return new Ci(V,this.keyHash,zr[1^gi]);var Fo=V&&V===this.ownerID,In=Fo?zr:De(zr);return Io?Or?gi===ai-1?In.pop():In[gi]=In.pop():In[gi]=[vt,ut]:In.push([vt,ut]),Fo?(this.entries=In,this):new uo(V,this.keyHash,In)},Ci.prototype.get=function(V,Ae,st,vt){return br(st,this.entry[0])?this.entry[1]:vt},Ci.prototype.update=function(V,Ae,st,vt,ut,un,mn){var Or=ut===H,zr=br(vt,this.entry[0]);return(zr?ut===this.entry[1]:Or)?this:(he(mn),Or?void he(un):zr?V&&V===this.ownerID?(this.entry[1]=ut,this):new Ci(V,this.keyHash,[vt,ut]):(he(un),Vi(this,V,Ae,kr(vt),[vt,ut])))},vr.prototype.iterate=uo.prototype.iterate=function(V,Ae){for(var st=this.entries,vt=0,ut=st.length-1;vt<=ut;vt++)if(!1===V(st[Ae?ut-vt:vt]))return!1},er.prototype.iterate=ri.prototype.iterate=function(V,Ae){for(var st=this.nodes,vt=0,ut=st.length-1;vt<=ut;vt++){var un=st[Ae?ut-vt:vt];if(un&&!1===un.iterate(V,Ae))return!1}},Ci.prototype.iterate=function(V,Ae){return V(this.entry)},i($o,Ut),$o.prototype.next=function(){for(var V=this._type,Ae=this._stack;Ae;){var ut,st=Ae.node,vt=Ae.index++;if(st.entry){if(0===vt)return tr(V,st.entry)}else if(st.entries){if(vt<=(ut=st.entries.length-1))return tr(V,st.entries[this._reverse?ut-vt:vt])}else if(vt<=(ut=st.nodes.length-1)){var un=st.nodes[this._reverse?ut-vt:vt];if(un){if(un.entry)return tr(V,un.entry);Ae=this._stack=Ar(un,Ae)}continue}Ae=this._stack=this._stack.__prev}return{value:void 0,done:!0}};var $s=8,da=16,Il=8;function fo(V){var Ae=bo();if(null==V)return Ae;if(Ya(V))return V;var st=p(V),vt=st.size;return 0===vt?Ae:(To(vt),vt>0&&vt<32?Ws(0,vt,5,null,new Ca(st.toArray())):Ae.withMutations(function(ut){ut.setSize(vt),st.forEach(function(un,mn){return ut.set(mn,un)})}))}function Ya(V){return!(!V||!V[Ao])}i(fo,Pr),fo.of=function(){return this(arguments)},fo.prototype.toString=function(){return this.__toString("List [","]")},fo.prototype.get=function(V,Ae){if((V=lt(this,V))>=0&&V<this.size){var st=$r(this,V+=this._origin);return st&&st.array[31&V]}return Ae},fo.prototype.set=function(V,Ae){return function(V,Ae,st){if((Ae=lt(V,Ae))!=Ae)return V;if(Ae>=V.size||Ae<0)return V.withMutations(function(mn){Ae<0?to(mn,Ae).set(0,st):to(mn,0,Ae+1).set(Ae,st)});Ae+=V._origin;var vt=V._tail,ut=V._root,un=ie(Ee);return Ae>=sn(V._capacity)?vt=ps(vt,V.__ownerID,0,Ae,st,un):ut=ps(ut,V.__ownerID,V._level,Ae,st,un),un.value?V.__ownerID?(V._root=ut,V._tail=vt,V.__hash=void 0,V.__altered=!0,V):Ws(V._origin,V._capacity,V._level,ut,vt):V}(this,V,Ae)},fo.prototype.remove=function(V){return this.has(V)?0===V?this.shift():V===this.size-1?this.pop():this.splice(V,1):this},fo.prototype.insert=function(V,Ae){return this.splice(V,0,Ae)},fo.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=this._origin=this._capacity=0,this._level=5,this._root=this._tail=null,this.__hash=void 0,this.__altered=!0,this):bo()},fo.prototype.push=function(){var V=arguments,Ae=this.size;return this.withMutations(function(st){to(st,0,Ae+V.length);for(var vt=0;vt<V.length;vt++)st.set(Ae+vt,V[vt])})},fo.prototype.pop=function(){return to(this,0,-1)},fo.prototype.unshift=function(){var V=arguments;return this.withMutations(function(Ae){to(Ae,-V.length);for(var st=0;st<V.length;st++)Ae.set(st,V[st])})},fo.prototype.shift=function(){return to(this,1)},fo.prototype.merge=function(){return tt(this,void 0,arguments)},fo.prototype.mergeWith=function(V){return tt(this,V,T.call(arguments,1))},fo.prototype.mergeDeep=function(){return tt(this,ls,arguments)},fo.prototype.mergeDeepWith=function(V){var Ae=T.call(arguments,1);return tt(this,La(V),Ae)},fo.prototype.setSize=function(V){return to(this,0,V)},fo.prototype.slice=function(V,Ae){var st=this.size;return ze(V,Ae,st)?this:to(this,Be(V,st),Pe(Ae,st))},fo.prototype.__iterator=function(V,Ae){var st=0,vt=pl(this,Ae);return new Ut(function(){var ut=vt();return ut===Ra?{value:void 0,done:!0}:Bt(V,st++,ut)})},fo.prototype.__iterate=function(V,Ae){for(var ut,st=0,vt=pl(this,Ae);(ut=vt())!==Ra&&!1!==V(ut,st++,this););return st},fo.prototype.__ensureOwner=function(V){return V===this.__ownerID?this:V?Ws(this._origin,this._capacity,this._level,this._root,this._tail,V,this.__hash):(this.__ownerID=V,this)},fo.isList=Ya;var Ao="@@__IMMUTABLE_LIST__@@",fs=fo.prototype;function Ca(V,Ae){this.array=V,this.ownerID=Ae}fs[Ao]=!0,fs[K]=fs.remove,fs.setIn=lr.setIn,fs.deleteIn=fs.removeIn=lr.removeIn,fs.update=lr.update,fs.updateIn=lr.updateIn,fs.mergeIn=lr.mergeIn,fs.mergeDeepIn=lr.mergeDeepIn,fs.withMutations=lr.withMutations,fs.asMutable=lr.asMutable,fs.asImmutable=lr.asImmutable,fs.wasAltered=lr.wasAltered,Ca.prototype.removeBefore=function(V,Ae,st){if(st===Ae?1<<Ae:0===this.array.length)return this;var vt=st>>>Ae&31;if(vt>=this.array.length)return new Ca([],V);var un,ut=0===vt;if(Ae>0){var mn=this.array[vt];if((un=mn&&mn.removeBefore(V,Ae-5,st))===mn&&ut)return this}if(ut&&!un)return this;var Or=So(this,V);if(!ut)for(var zr=0;zr<vt;zr++)Or.array[zr]=void 0;return un&&(Or.array[vt]=un),Or},Ca.prototype.removeAfter=function(V,Ae,st){if(st===(Ae?1<<Ae:0)||0===this.array.length)return this;var ut,vt=st-1>>>Ae&31;if(vt>=this.array.length)return this;if(Ae>0){var un=this.array[vt];if((ut=un&&un.removeAfter(V,Ae-5,st))===un&&vt===this.array.length-1)return this}var mn=So(this,V);return mn.array.splice(vt+1),ut&&(mn.array[vt]=ut),mn};var Po,an,Ra={};function pl(V,Ae){var st=V._origin,vt=V._capacity,ut=sn(vt),un=V._tail;return mn(V._root,V._level,0);function mn(gi,ai,Io){return 0===ai?function(gi,ai){var Io=ai===ut?un&&un.array:gi&&gi.array,Fo=ai>st?0:st-ai,In=vt-ai;return In>32&&(In=32),function(){if(Fo===In)return Ra;var Cr=Ae?--In:Fo++;return Io&&Io[Cr]}}(gi,Io):function(gi,ai,Io){var Fo,In=gi&&gi.array,Cr=Io>st?0:st-Io>>ai,hr=1+(vt-Io>>ai);return hr>32&&(hr=32),function(){for(;;){if(Fo){var ao=Fo();if(ao!==Ra)return ao;Fo=null}if(Cr===hr)return Ra;var ys=Ae?--hr:Cr++;Fo=mn(In&&In[ys],ai-5,Io+(ys<<ai))}}}(gi,ai,Io)}}function Ws(V,Ae,st,vt,ut,un,mn){var Or=Object.create(fs);return Or.size=Ae-V,Or._origin=V,Or._capacity=Ae,Or._level=st,Or._root=vt,Or._tail=ut,Or.__ownerID=un,Or.__hash=mn,Or.__altered=!1,Or}function bo(){return Po||(Po=Ws(0,0,5))}function ps(V,Ae,st,vt,ut,un){var zr,mn=vt>>>st&31,Or=V&&mn<V.array.length;if(!Or&&void 0===ut)return V;if(st>0){var gi=V&&V.array[mn],ai=ps(gi,Ae,st-5,vt,ut,un);return ai===gi?V:((zr=So(V,Ae)).array[mn]=ai,zr)}return Or&&V.array[mn]===ut?V:(he(un),zr=So(V,Ae),void 0===ut&&mn===zr.array.length-1?zr.array.pop():zr.array[mn]=ut,zr)}function So(V,Ae){return Ae&&V&&Ae===V.ownerID?V:new Ca(V?V.array.slice():[],Ae)}function $r(V,Ae){if(Ae>=sn(V._capacity))return V._tail;if(Ae<1<<V._level+5){for(var st=V._root,vt=V._level;st&&vt>0;)st=st.array[Ae>>>vt&31],vt-=5;return st}}function to(V,Ae,st){void 0!==Ae&&(Ae|=0),void 0!==st&&(st|=0);var vt=V.__ownerID||new ge,ut=V._origin,un=V._capacity,mn=ut+Ae,Or=void 0===st?un:st<0?un+st:ut+st;if(mn===ut&&Or===un)return V;if(mn>=Or)return V.clear();for(var zr=V._level,gi=V._root,ai=0;mn+ai<0;)gi=new Ca(gi&&gi.array.length?[void 0,gi]:[],vt),ai+=1<<(zr+=5);ai&&(mn+=ai,ut+=ai,Or+=ai,un+=ai);for(var Io=sn(un),Fo=sn(Or);Fo>=1<<zr+5;)gi=new Ca(gi&&gi.array.length?[gi]:[],vt),zr+=5;var In=V._tail,Cr=Fo<Io?$r(V,Or-1):Fo>Io?new Ca([],vt):In;if(In&&Fo>Io&&mn<un&&In.array.length){for(var hr=gi=So(gi,vt),ao=zr;ao>5;ao-=5){var ys=Io>>>ao&31;hr=hr.array[ys]=So(hr.array[ys],vt)}hr.array[Io>>>5&31]=In}if(Or<un&&(Cr=Cr&&Cr.removeAfter(vt,0,Or)),mn>=Fo)mn-=Fo,Or-=Fo,zr=5,gi=null,Cr=Cr&&Cr.removeBefore(vt,0,mn);else if(mn>ut||Fo<Io){for(ai=0;gi;){var Na=mn>>>zr&31;if(Na!==Fo>>>zr&31)break;Na&&(ai+=(1<<zr)*Na),zr-=5,gi=gi.array[Na]}gi&&mn>ut&&(gi=gi.removeBefore(vt,zr,mn-ai)),gi&&Fo<Io&&(gi=gi.removeAfter(vt,zr,Fo-ai)),ai&&(mn-=ai,Or-=ai)}return V.__ownerID?(V.size=Or-mn,V._origin=mn,V._capacity=Or,V._level=zr,V._root=gi,V._tail=Cr,V.__hash=void 0,V.__altered=!0,V):Ws(mn,Or,zr,gi,Cr)}function tt(V,Ae,st){for(var vt=[],ut=0,un=0;un<st.length;un++){var mn=st[un],Or=p(mn);Or.size>ut&&(ut=Or.size),e(mn)||(Or=Or.map(function(zr){return Gn(zr)})),vt.push(Or)}return ut>V.size&&(V=V.setSize(ut)),ta(V,Ae,vt)}function sn(V){return V<32?0:V-1>>>5<<5}function ne(V){return null==V?ti():$e(V)?V:ti().withMutations(function(Ae){var st=u(V);To(st.size),st.forEach(function(vt,ut){return Ae.set(ut,vt)})})}function $e(V){return li(V)&&A(V)}function Lt(V,Ae,st,vt){var ut=Object.create(ne.prototype);return ut.size=V?V.size:0,ut._map=V,ut._list=Ae,ut.__ownerID=st,ut.__hash=vt,ut}function ti(){return an||(an=Lt(mt(),bo()))}function pi(V,Ae,st){var Or,zr,vt=V._map,ut=V._list,un=vt.get(Ae),mn=void 0!==un;if(st===H){if(!mn)return V;ut.size>=32&&ut.size>=2*vt.size?(Or=(zr=ut.filter(function(gi,ai){return void 0!==gi&&un!==ai})).toKeyedSeq().map(function(gi){return gi[0]}).flip().toMap(),V.__ownerID&&(Or.__ownerID=zr.__ownerID=V.__ownerID)):(Or=vt.remove(Ae),zr=un===ut.size-1?ut.pop():ut.set(un,void 0))}else if(mn){if(st===ut.get(un)[1])return V;Or=vt,zr=ut.set(un,[Ae,st])}else Or=vt.set(Ae,ut.size),zr=ut.set(ut.size,[Ae,st]);return V.__ownerID?(V.size=Or.size,V._map=Or,V._list=zr,V.__hash=void 0,V):Lt(Or,zr)}function xi(V,Ae){this._iter=V,this._useKeys=Ae,this.size=V.size}function ts(V){this._iter=V,this.size=V.size}function wo(V){this._iter=V,this.size=V.size}function ko(V){this._iter=V,this.size=V.size}function Eo(V){var Ae=xe(V);return Ae._iter=V,Ae.size=V.size,Ae.flip=function(){return V},Ae.reverse=function(){var st=V.reverse.apply(this);return st.flip=function(){return V.reverse()},st},Ae.has=function(st){return V.includes(st)},Ae.includes=function(st){return V.has(st)},Ae.cacheResult=Ct,Ae.__iterateUncached=function(st,vt){var ut=this;return V.__iterate(function(un,mn){return!1!==st(mn,un,ut)},vt)},Ae.__iteratorUncached=function(st,vt){if(2===st){var ut=V.__iterator(st,vt);return new Ut(function(){var un=ut.next();if(!un.done){var mn=un.value[0];un.value[0]=un.value[1],un.value[1]=mn}return un})}return V.__iterator(1===st?0:1,vt)},Ae}function ba(V,Ae,st){var vt=xe(V);return vt.size=V.size,vt.has=function(ut){return V.has(ut)},vt.get=function(ut,un){var mn=V.get(ut,H);return mn===H?un:Ae.call(st,mn,ut,V)},vt.__iterateUncached=function(ut,un){var mn=this;return V.__iterate(function(Or,zr,gi){return!1!==ut(Ae.call(st,Or,zr,gi),zr,mn)},un)},vt.__iteratorUncached=function(ut,un){var mn=V.__iterator(2,un);return new Ut(function(){var Or=mn.next();if(Or.done)return Or;var zr=Or.value,gi=zr[0];return Bt(ut,gi,Ae.call(st,zr[1],gi,V),Or)})},vt}function sl(V,Ae){var st=xe(V);return st._iter=V,st.size=V.size,st.reverse=function(){return V},V.flip&&(st.flip=function(){var vt=Eo(V);return vt.reverse=function(){return V.flip()},vt}),st.get=function(vt,ut){return V.get(Ae?vt:-1-vt,ut)},st.has=function(vt){return V.has(Ae?vt:-1-vt)},st.includes=function(vt){return V.includes(vt)},st.cacheResult=Ct,st.__iterate=function(vt,ut){var un=this;return V.__iterate(function(mn,Or){return vt(mn,Or,un)},!ut)},st.__iterator=function(vt,ut){return V.__iterator(vt,!ut)},st}function tc(V,Ae,st,vt){var ut=xe(V);return vt&&(ut.has=function(un){var mn=V.get(un,H);return mn!==H&&!!Ae.call(st,mn,un,V)},ut.get=function(un,mn){var Or=V.get(un,H);return Or!==H&&Ae.call(st,Or,un,V)?Or:mn}),ut.__iterateUncached=function(un,mn){var Or=this,zr=0;return V.__iterate(function(gi,ai,Io){if(Ae.call(st,gi,ai,Io))return zr++,un(gi,vt?ai:zr-1,Or)},mn),zr},ut.__iteratorUncached=function(un,mn){var Or=V.__iterator(2,mn),zr=0;return new Ut(function(){for(;;){var gi=Or.next();if(gi.done)return gi;var ai=gi.value,Io=ai[0],Fo=ai[1];if(Ae.call(st,Fo,Io,V))return Bt(un,vt?Io:zr++,Fo,gi)}})},ut}function Ec(V,Ae,st,vt){var ut=V.size;if(void 0!==Ae&&(Ae|=0),void 0!==st&&(st===1/0?st=ut:st|=0),ze(Ae,st,ut))return V;var un=Be(Ae,ut),mn=Pe(st,ut);if(un!=un||mn!=mn)return Ec(V.toSeq().cacheResult(),Ae,st,vt);var zr,Or=mn-un;Or==Or&&(zr=Or<0?0:Or);var gi=xe(V);return gi.size=0===zr?zr:V.size&&zr||void 0,!vt&&fi(V)&&zr>=0&&(gi.get=function(ai,Io){return(ai=lt(this,ai))>=0&&ai<zr?V.get(ai+un,Io):Io}),gi.__iterateUncached=function(ai,Io){var Fo=this;if(0===zr)return 0;if(Io)return this.cacheResult().__iterate(ai,Io);var In=0,Cr=!0,hr=0;return V.__iterate(function(ao,ys){if(!Cr||!(Cr=In++<un))return hr++,!1!==ai(ao,vt?ys:hr-1,Fo)&&hr!==zr}),hr},gi.__iteratorUncached=function(ai,Io){if(0!==zr&&Io)return this.cacheResult().__iterator(ai,Io);var Fo=0!==zr&&V.__iterator(ai,Io),In=0,Cr=0;return new Ut(function(){for(;In++<un;)Fo.next();if(++Cr>zr)return{value:void 0,done:!0};var hr=Fo.next();return vt||1===ai?hr:Bt(ai,Cr-1,0===ai?void 0:hr.value[1],hr)})},gi}function Hl(V,Ae,st,vt){var ut=xe(V);return ut.__iterateUncached=function(un,mn){var Or=this;if(mn)return this.cacheResult().__iterate(un,mn);var zr=!0,gi=0;return V.__iterate(function(ai,Io,Fo){if(!zr||!(zr=Ae.call(st,ai,Io,Fo)))return gi++,un(ai,vt?Io:gi-1,Or)}),gi},ut.__iteratorUncached=function(un,mn){var Or=this;if(mn)return this.cacheResult().__iterator(un,mn);var zr=V.__iterator(2,mn),gi=!0,ai=0;return new Ut(function(){var Io,Fo,In;do{if((Io=zr.next()).done)return vt||1===un?Io:Bt(un,ai++,0===un?void 0:Io.value[1],Io);var Cr=Io.value;Fo=Cr[0],In=Cr[1],gi&&(gi=Ae.call(st,In,Fo,Or))}while(gi);return 2===un?Io:Bt(un,Fo,In,Io)})},ut}function Yl(V,Ae){var st=_(V),vt=[V].concat(Ae).map(function(mn){return e(mn)?st&&(mn=u(mn)):mn=st?Zr(mn):Cn(Array.isArray(mn)?mn:[mn]),mn}).filter(function(mn){return 0!==mn.size});if(0===vt.length)return V;if(1===vt.length){var ut=vt[0];if(ut===V||st&&_(ut)||y(V)&&y(ut))return ut}var un=new Nn(vt);return st?un=un.toKeyedSeq():y(V)||(un=un.toSetSeq()),(un=un.flatten(!0)).size=vt.reduce(function(mn,Or){if(void 0!==mn){var zr=Or.size;if(void 0!==zr)return mn+zr}},0),un}function Fs(V,Ae,st){var vt=xe(V);return vt.__iterateUncached=function(ut,un){var mn=0,Or=!1;return function zr(gi,ai){var Io=this;gi.__iterate(function(Fo,In){return(!Ae||ai<Ae)&&e(Fo)?zr(Fo,ai+1):!1===ut(Fo,st?In:mn++,Io)&&(Or=!0),!Or},un)}(V,0),mn},vt.__iteratorUncached=function(ut,un){var mn=V.__iterator(ut,un),Or=[],zr=0;return new Ut(function(){for(;mn;){var gi=mn.next();if(!1===gi.done){var ai=gi.value;if(2===ut&&(ai=ai[1]),Ae&&!(Or.length<Ae)||!e(ai))return st?gi:Bt(ut,zr++,ai,gi);Or.push(mn),mn=ai.__iterator(ut,un)}else mn=Or.pop()}return{value:void 0,done:!0}})},vt}function tl(V,Ae,st){Ae||(Ae=ur);var vt=_(V),ut=0,un=V.toSeq().map(function(mn,Or){return[Or,mn,ut++,st?st(mn,Or,V):mn]}).toArray();return un.sort(function(mn,Or){return Ae(mn[3],Or[3])||mn[2]-Or[2]}).forEach(vt?function(mn,Or){un[Or].length=2}:function(mn,Or){un[Or]=mn[1]}),vt?Lr(un):y(V)?Mr(un):Kr(un)}function Su(V,Ae,st){if(Ae||(Ae=ur),st){var vt=V.toSeq().map(function(ut,un){return[ut,st(ut,un,V)]}).reduce(function(ut,un){return Zl(Ae,ut[1],un[1])?un:ut});return vt&&vt[0]}return V.reduce(function(ut,un){return Zl(Ae,ut,un)?un:ut})}function Zl(V,Ae,st){var vt=V(st,Ae);return 0===vt&&st!==Ae&&(null==st||st!=st)||vt>0}function rt(V,Ae,st){var vt=xe(V);return vt.size=new Nn(st).map(function(ut){return ut.size}).min(),vt.__iterate=function(ut,un){for(var Or,mn=this.__iterator(1,un),zr=0;!(Or=mn.next()).done&&!1!==ut(Or.value,zr++,this););return zr},vt.__iteratorUncached=function(ut,un){var mn=st.map(function(gi){return gi=r(gi),Xt(un?gi.reverse():gi)}),Or=0,zr=!1;return new Ut(function(){var gi;return zr||(gi=mn.map(function(ai){return ai.next()}),zr=gi.some(function(ai){return ai.done})),zr?{value:void 0,done:!0}:Bt(ut,Or++,Ae.apply(null,gi.map(function(ai){return ai.value})))})},vt}function Pt(V,Ae){return fi(V)?Ae:V.constructor(Ae)}function dt(V){if(V!==Object(V))throw new TypeError("Expected [K, V] tuple: "+V)}function Te(V){return To(V.size),ce(V)}function Me(V){return _(V)?u:y(V)?p:d}function xe(V){return Object.create((_(V)?Lr:y(V)?Mr:Kr).prototype)}function Ct(){return this._iter.cacheResult?(this._iter.cacheResult(),this.size=this._iter.size,this):di.prototype.cacheResult.call(this)}function ur(V,Ae){return V>Ae?1:V<Ae?-1:0}function Qi(V){var Ae=Xt(V);if(!Ae){if(!Ur(V))throw new TypeError("Expected iterable or array-like: "+V);Ae=Xt(r(V))}return Ae}function Go(V,Ae){var st,vt=function(mn){if(mn instanceof vt)return mn;if(!(this instanceof vt))return new vt(mn);if(!st){st=!0;var Or=Object.keys(V);(function(V,Ae){try{Ae.forEach(au.bind(void 0,V))}catch(st){}})(ut,Or),ut.size=Or.length,ut._name=Ae,ut._keys=Or,ut._defaultValues=V}this._map=Mi(mn)},ut=vt.prototype=Object.create(ms);return ut.constructor=vt,vt}i(ne,Mi),ne.of=function(){return this(arguments)},ne.prototype.toString=function(){return this.__toString("OrderedMap {","}")},ne.prototype.get=function(V,Ae){var st=this._map.get(V);return void 0!==st?this._list.get(st)[1]:Ae},ne.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._map.clear(),this._list.clear(),this):ti()},ne.prototype.set=function(V,Ae){return pi(this,V,Ae)},ne.prototype.remove=function(V){return pi(this,V,H)},ne.prototype.wasAltered=function(){return this._map.wasAltered()||this._list.wasAltered()},ne.prototype.__iterate=function(V,Ae){var st=this;return this._list.__iterate(function(vt){return vt&&V(vt[1],vt[0],st)},Ae)},ne.prototype.__iterator=function(V,Ae){return this._list.fromEntrySeq().__iterator(V,Ae)},ne.prototype.__ensureOwner=function(V){if(V===this.__ownerID)return this;var Ae=this._map.__ensureOwner(V),st=this._list.__ensureOwner(V);return V?Lt(Ae,st,V,this.__hash):(this.__ownerID=V,this._map=Ae,this._list=st,this)},ne.isOrderedMap=$e,ne.prototype[J]=!0,ne.prototype[K]=ne.prototype.remove,i(xi,Lr),xi.prototype.get=function(V,Ae){return this._iter.get(V,Ae)},xi.prototype.has=function(V){return this._iter.has(V)},xi.prototype.valueSeq=function(){return this._iter.valueSeq()},xi.prototype.reverse=function(){var V=this,Ae=sl(this,!0);return this._useKeys||(Ae.valueSeq=function(){return V._iter.toSeq().reverse()}),Ae},xi.prototype.map=function(V,Ae){var st=this,vt=ba(this,V,Ae);return this._useKeys||(vt.valueSeq=function(){return st._iter.toSeq().map(V,Ae)}),vt},xi.prototype.__iterate=function(V,Ae){var vt,st=this;return this._iter.__iterate(this._useKeys?function(ut,un){return V(ut,un,st)}:(vt=Ae?Te(this):0,function(ut){return V(ut,Ae?--vt:vt++,st)}),Ae)},xi.prototype.__iterator=function(V,Ae){if(this._useKeys)return this._iter.__iterator(V,Ae);var st=this._iter.__iterator(1,Ae),vt=Ae?Te(this):0;return new Ut(function(){var ut=st.next();return ut.done?ut:Bt(V,Ae?--vt:vt++,ut.value,ut)})},xi.prototype[J]=!0,i(ts,Mr),ts.prototype.includes=function(V){return this._iter.includes(V)},ts.prototype.__iterate=function(V,Ae){var st=this,vt=0;return this._iter.__iterate(function(ut){return V(ut,vt++,st)},Ae)},ts.prototype.__iterator=function(V,Ae){var st=this._iter.__iterator(1,Ae),vt=0;return new Ut(function(){var ut=st.next();return ut.done?ut:Bt(V,vt++,ut.value,ut)})},i(wo,Kr),wo.prototype.has=function(V){return this._iter.includes(V)},wo.prototype.__iterate=function(V,Ae){var st=this;return this._iter.__iterate(function(vt){return V(vt,vt,st)},Ae)},wo.prototype.__iterator=function(V,Ae){var st=this._iter.__iterator(1,Ae);return new Ut(function(){var vt=st.next();return vt.done?vt:Bt(V,vt.value,vt.value,vt)})},i(ko,Lr),ko.prototype.entrySeq=function(){return this._iter.toSeq()},ko.prototype.__iterate=function(V,Ae){var st=this;return this._iter.__iterate(function(vt){if(vt){dt(vt);var ut=e(vt);return V(ut?vt.get(1):vt[1],ut?vt.get(0):vt[0],st)}},Ae)},ko.prototype.__iterator=function(V,Ae){var st=this._iter.__iterator(1,Ae);return new Ut(function(){for(;;){var vt=st.next();if(vt.done)return vt;var ut=vt.value;if(ut){dt(ut);var un=e(ut);return Bt(V,un?ut.get(0):ut[0],un?ut.get(1):ut[1],vt)}}})},ts.prototype.cacheResult=xi.prototype.cacheResult=wo.prototype.cacheResult=ko.prototype.cacheResult=Ct,i(Go,Dn),Go.prototype.toString=function(){return this.__toString(Ts(this)+" {","}")},Go.prototype.has=function(V){return this._defaultValues.hasOwnProperty(V)},Go.prototype.get=function(V,Ae){if(!this.has(V))return Ae;var st=this._defaultValues[V];return this._map?this._map.get(V,st):st},Go.prototype.clear=function(){if(this.__ownerID)return this._map&&this._map.clear(),this;var V=this.constructor;return V._empty||(V._empty=hs(this,mt()))},Go.prototype.set=function(V,Ae){if(!this.has(V))throw new Error('Cannot set unknown key "'+V+'" on '+Ts(this));if(this._map&&!this._map.has(V)&&Ae===this._defaultValues[V])return this;var vt=this._map&&this._map.set(V,Ae);return this.__ownerID||vt===this._map?this:hs(this,vt)},Go.prototype.remove=function(V){if(!this.has(V))return this;var Ae=this._map&&this._map.remove(V);return this.__ownerID||Ae===this._map?this:hs(this,Ae)},Go.prototype.wasAltered=function(){return this._map.wasAltered()},Go.prototype.__iterator=function(V,Ae){var st=this;return u(this._defaultValues).map(function(vt,ut){return st.get(ut)}).__iterator(V,Ae)},Go.prototype.__iterate=function(V,Ae){var st=this;return u(this._defaultValues).map(function(vt,ut){return st.get(ut)}).__iterate(V,Ae)},Go.prototype.__ensureOwner=function(V){if(V===this.__ownerID)return this;var Ae=this._map&&this._map.__ensureOwner(V);return V?hs(this,Ae,V):(this.__ownerID=V,this._map=Ae,this)};var ms=Go.prototype;function hs(V,Ae,st){var vt=Object.create(Object.getPrototypeOf(V));return vt._map=Ae,vt.__ownerID=st,vt}function Ts(V){return V._name||V.constructor.name||"Record"}function au(V,Ae){Object.defineProperty(V,Ae,{get:function(){return this.get(Ae)},set:function(st){gr(this.__ownerID,"Cannot set on an immutable record."),this.set(Ae,st)}})}function Wa(V){return null==V?Fc():Rl(V)&&!A(V)?V:Fc().withMutations(function(Ae){var st=d(V);To(st.size),st.forEach(function(vt){return Ae.add(vt)})})}function Rl(V){return!(!V||!V[nc])}ms[K]=ms.remove,ms.deleteIn=ms.removeIn=lr.removeIn,ms.merge=lr.merge,ms.mergeWith=lr.mergeWith,ms.mergeIn=lr.mergeIn,ms.mergeDeep=lr.mergeDeep,ms.mergeDeepWith=lr.mergeDeepWith,ms.mergeDeepIn=lr.mergeDeepIn,ms.setIn=lr.setIn,ms.update=lr.update,ms.updateIn=lr.updateIn,ms.withMutations=lr.withMutations,ms.asMutable=lr.asMutable,ms.asImmutable=lr.asImmutable,i(Wa,Yt),Wa.of=function(){return this(arguments)},Wa.fromKeys=function(V){return this(u(V).keySeq())},Wa.prototype.toString=function(){return this.__toString("Set {","}")},Wa.prototype.has=function(V){return this._map.has(V)},Wa.prototype.add=function(V){return vs(this,this._map.set(V,!0))},Wa.prototype.remove=function(V){return vs(this,this._map.remove(V))},Wa.prototype.clear=function(){return vs(this,this._map.clear())},Wa.prototype.union=function(){var V=T.call(arguments,0);return 0===(V=V.filter(function(Ae){return 0!==Ae.size})).length?this:0!==this.size||this.__ownerID||1!==V.length?this.withMutations(function(Ae){for(var st=0;st<V.length;st++)d(V[st]).forEach(function(vt){return Ae.add(vt)})}):this.constructor(V[0])},Wa.prototype.intersect=function(){var V=T.call(arguments,0);if(0===V.length)return this;V=V.map(function(st){return d(st)});var Ae=this;return this.withMutations(function(st){Ae.forEach(function(vt){V.every(function(ut){return ut.includes(vt)})||st.remove(vt)})})},Wa.prototype.subtract=function(){var V=T.call(arguments,0);if(0===V.length)return this;V=V.map(function(st){return d(st)});var Ae=this;return this.withMutations(function(st){Ae.forEach(function(vt){V.some(function(ut){return ut.includes(vt)})&&st.remove(vt)})})},Wa.prototype.merge=function(){return this.union.apply(this,arguments)},Wa.prototype.mergeWith=function(V){var Ae=T.call(arguments,1);return this.union.apply(this,Ae)},Wa.prototype.sort=function(V){return Cu(tl(this,V))},Wa.prototype.sortBy=function(V,Ae){return Cu(tl(this,Ae,V))},Wa.prototype.wasAltered=function(){return this._map.wasAltered()},Wa.prototype.__iterate=function(V,Ae){var st=this;return this._map.__iterate(function(vt,ut){return V(ut,ut,st)},Ae)},Wa.prototype.__iterator=function(V,Ae){return this._map.map(function(st,vt){return vt}).__iterator(V,Ae)},Wa.prototype.__ensureOwner=function(V){if(V===this.__ownerID)return this;var Ae=this._map.__ensureOwner(V);return V?this.__make(Ae,V):(this.__ownerID=V,this._map=Ae,this)},Wa.isSet=Rl;var Tc,nc="@@__IMMUTABLE_SET__@@",Al=Wa.prototype;function vs(V,Ae){return V.__ownerID?(V.size=Ae.size,V._map=Ae,V):Ae===V._map?V:0===Ae.size?V.__empty():V.__make(Ae)}function Lc(V,Ae){var st=Object.create(Al);return st.size=V?V.size:0,st._map=V,st.__ownerID=Ae,st}function Fc(){return Tc||(Tc=Lc(mt()))}function Cu(V){return null==V?sa():kc(V)?V:sa().withMutations(function(Ae){var st=d(V);To(st.size),st.forEach(function(vt){return Ae.add(vt)})})}function kc(V){return Rl(V)&&A(V)}Al[nc]=!0,Al[K]=Al.remove,Al.mergeDeep=Al.merge,Al.mergeDeepWith=Al.mergeWith,Al.withMutations=lr.withMutations,Al.asMutable=lr.asMutable,Al.asImmutable=lr.asImmutable,Al.__empty=Fc,Al.__make=Lc,i(Cu,Wa),Cu.of=function(){return this(arguments)},Cu.fromKeys=function(V){return this(u(V).keySeq())},Cu.prototype.toString=function(){return this.__toString("OrderedSet {","}")},Cu.isOrderedSet=kc;var Li,gd=Cu.prototype;function rc(V,Ae){var st=Object.create(gd);return st.size=V?V.size:0,st._map=V,st.__ownerID=Ae,st}function sa(){return Li||(Li=rc(ti()))}function Aa(V){return null==V?lu():Ss(V)?V:lu().unshiftAll(V)}function Ss(V){return!(!V||!V[$u])}gd[J]=!0,gd.__empty=sa,gd.__make=rc,i(Aa,Pr),Aa.of=function(){return this(arguments)},Aa.prototype.toString=function(){return this.__toString("Stack [","]")},Aa.prototype.get=function(V,Ae){var st=this._head;for(V=lt(this,V);st&&V--;)st=st.next;return st?st.value:Ae},Aa.prototype.peek=function(){return this._head&&this._head.value},Aa.prototype.push=function(){if(0===arguments.length)return this;for(var V=this.size+arguments.length,Ae=this._head,st=arguments.length-1;st>=0;st--)Ae={value:arguments[st],next:Ae};return this.__ownerID?(this.size=V,this._head=Ae,this.__hash=void 0,this.__altered=!0,this):Mu(V,Ae)},Aa.prototype.pushAll=function(V){if(0===(V=p(V)).size)return this;To(V.size);var Ae=this.size,st=this._head;return V.reverse().forEach(function(vt){Ae++,st={value:vt,next:st}}),this.__ownerID?(this.size=Ae,this._head=st,this.__hash=void 0,this.__altered=!0,this):Mu(Ae,st)},Aa.prototype.pop=function(){return this.slice(1)},Aa.prototype.unshift=function(){return this.push.apply(this,arguments)},Aa.prototype.unshiftAll=function(V){return this.pushAll(V)},Aa.prototype.shift=function(){return this.pop.apply(this,arguments)},Aa.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._head=void 0,this.__hash=void 0,this.__altered=!0,this):lu()},Aa.prototype.slice=function(V,Ae){if(ze(V,Ae,this.size))return this;var st=Be(V,this.size);if(Pe(Ae,this.size)!==this.size)return Pr.prototype.slice.call(this,V,Ae);for(var ut=this.size-st,un=this._head;st--;)un=un.next;return this.__ownerID?(this.size=ut,this._head=un,this.__hash=void 0,this.__altered=!0,this):Mu(ut,un)},Aa.prototype.__ensureOwner=function(V){return V===this.__ownerID?this:V?Mu(this.size,this._head,V,this.__hash):(this.__ownerID=V,this.__altered=!1,this)},Aa.prototype.__iterate=function(V,Ae){if(Ae)return this.reverse().__iterate(V);for(var st=0,vt=this._head;vt&&!1!==V(vt.value,st++,this);)vt=vt.next;return st},Aa.prototype.__iterator=function(V,Ae){if(Ae)return this.reverse().__iterator(V);var st=0,vt=this._head;return new Ut(function(){if(vt){var ut=vt.value;return vt=vt.next,Bt(V,st++,ut)}return{value:void 0,done:!0}})},Aa.isStack=Ss;var yu,$u="@@__IMMUTABLE_STACK__@@",yl=Aa.prototype;function Mu(V,Ae,st,vt){var ut=Object.create(yl);return ut.size=V,ut._head=Ae,ut.__ownerID=st,ut.__hash=vt,ut.__altered=!1,ut}function lu(){return yu||(yu=Mu(0))}function js(V,Ae){var st=function(vt){V.prototype[vt]=Ae[vt]};return Object.keys(Ae).forEach(st),Object.getOwnPropertySymbols&&Object.getOwnPropertySymbols(Ae).forEach(st),V}yl[$u]=!0,yl.withMutations=lr.withMutations,yl.asMutable=lr.asMutable,yl.asImmutable=lr.asImmutable,yl.wasAltered=lr.wasAltered,r.Iterator=Ut,js(r,{toArray:function(){To(this.size);var V=new Array(this.size||0);return this.valueSeq().__iterate(function(Ae,st){V[st]=Ae}),V},toIndexedSeq:function(){return new ts(this)},toJS:function(){return this.toSeq().map(function(V){return V&&"function"==typeof V.toJS?V.toJS():V}).__toJS()},toJSON:function(){return this.toSeq().map(function(V){return V&&"function"==typeof V.toJSON?V.toJSON():V}).__toJS()},toKeyedSeq:function(){return new xi(this,!0)},toMap:function(){return Mi(this.toKeyedSeq())},toObject:function(){To(this.size);var V={};return this.__iterate(function(Ae,st){V[st]=Ae}),V},toOrderedMap:function(){return ne(this.toKeyedSeq())},toOrderedSet:function(){return Cu(_(this)?this.valueSeq():this)},toSet:function(){return Wa(_(this)?this.valueSeq():this)},toSetSeq:function(){return new wo(this)},toSeq:function(){return y(this)?this.toIndexedSeq():_(this)?this.toKeyedSeq():this.toSetSeq()},toStack:function(){return Aa(_(this)?this.valueSeq():this)},toList:function(){return fo(_(this)?this.valueSeq():this)},toString:function(){return"[Iterable]"},__toString:function(V,Ae){return 0===this.size?V+Ae:V+" "+this.toSeq().map(this.__toStringMapper).join(", ")+" "+Ae},concat:function(){return Pt(this,Yl(this,T.call(arguments,0)))},includes:function(V){return this.some(function(Ae){return br(Ae,V)})},entries:function(){return this.__iterator(2)},every:function(V,Ae){To(this.size);var st=!0;return this.__iterate(function(vt,ut,un){if(!V.call(Ae,vt,ut,un))return st=!1,!1}),st},filter:function(V,Ae){return Pt(this,tc(this,V,Ae,!0))},find:function(V,Ae,st){var vt=this.findEntry(V,Ae);return vt?vt[1]:st},forEach:function(V,Ae){return To(this.size),this.__iterate(Ae?V.bind(Ae):V)},join:function(V){To(this.size),V=void 0!==V?""+V:",";var Ae="",st=!0;return this.__iterate(function(vt){st?st=!1:Ae+=V,Ae+=null!=vt?vt.toString():""}),Ae},keys:function(){return this.__iterator(0)},map:function(V,Ae){return Pt(this,ba(this,V,Ae))},reduce:function(V,Ae,st){var vt,ut;return To(this.size),arguments.length<2?ut=!0:vt=Ae,this.__iterate(function(un,mn,Or){ut?(ut=!1,vt=un):vt=V.call(st,vt,un,mn,Or)}),vt},reduceRight:function(V,Ae,st){var vt=this.toKeyedSeq().reverse();return vt.reduce.apply(vt,arguments)},reverse:function(){return Pt(this,sl(this,!0))},slice:function(V,Ae){return Pt(this,Ec(this,V,Ae,!0))},some:function(V,Ae){return!this.every(wr(V),Ae)},sort:function(V){return Pt(this,tl(this,V))},values:function(){return this.__iterator(1)},butLast:function(){return this.slice(0,-1)},isEmpty:function(){return void 0!==this.size?0===this.size:!this.some(function(){return!0})},count:function(V,Ae){return ce(V?this.toSeq().filter(V,Ae):this)},countBy:function(V,Ae){return function(V,Ae,st){var vt=Mi().asMutable();return V.__iterate(function(ut,un){vt.update(Ae.call(st,ut,un,V),0,function(mn){return mn+1})}),vt.asImmutable()}(this,V,Ae)},equals:function(V){return Dr(this,V)},entrySeq:function(){var V=this;if(V._cache)return new Nn(V._cache);var Ae=V.toSeq().map(uu).toIndexedSeq();return Ae.fromEntrySeq=function(){return V.toSeq()},Ae},filterNot:function(V,Ae){return this.filter(wr(V),Ae)},findEntry:function(V,Ae,st){var vt=st;return this.__iterate(function(ut,un,mn){if(V.call(Ae,ut,un,mn))return vt=[un,ut],!1}),vt},findKey:function(V,Ae){var st=this.findEntry(V,Ae);return st&&st[0]},findLast:function(V,Ae,st){return this.toKeyedSeq().reverse().find(V,Ae,st)},findLastEntry:function(V,Ae,st){return this.toKeyedSeq().reverse().findEntry(V,Ae,st)},findLastKey:function(V,Ae){return this.toKeyedSeq().reverse().findKey(V,Ae)},first:function(){return this.find(Ve)},flatMap:function(V,Ae){return Pt(this,function(V,Ae,st){var vt=Me(V);return V.toSeq().map(function(ut,un){return vt(Ae.call(st,ut,un,V))}).flatten(!0)}(this,V,Ae))},flatten:function(V){return Pt(this,Fs(this,V,!0))},fromEntrySeq:function(){return new ko(this)},get:function(V,Ae){return this.find(function(st,vt){return br(vt,V)},void 0,Ae)},getIn:function(V,Ae){for(var ut,st=this,vt=Qi(V);!(ut=vt.next()).done;)if((st=st&&st.get?st.get(ut.value,H):H)===H)return Ae;return st},groupBy:function(V,Ae){return function(V,Ae,st){var vt=_(V),ut=(A(V)?ne():Mi()).asMutable();V.__iterate(function(mn,Or){ut.update(Ae.call(st,mn,Or,V),function(zr){return(zr=zr||[]).push(vt?[Or,mn]:mn),zr})});var un=Me(V);return ut.map(function(mn){return Pt(V,un(mn))})}(this,V,Ae)},has:function(V){return this.get(V,H)!==H},hasIn:function(V){return this.getIn(V,H)!==H},isSubset:function(V){return V="function"==typeof V.includes?V:r(V),this.every(function(Ae){return V.includes(Ae)})},isSuperset:function(V){return(V="function"==typeof V.isSubset?V:r(V)).isSubset(this)},keyOf:function(V){return this.findKey(function(Ae){return br(Ae,V)})},keySeq:function(){return this.toSeq().map(Bo).toIndexedSeq()},last:function(){return this.toSeq().reverse().first()},lastKeyOf:function(V){return this.toKeyedSeq().reverse().keyOf(V)},max:function(V){return Su(this,V)},maxBy:function(V,Ae){return Su(this,Ae,V)},min:function(V){return Su(this,V?fa(V):jl)},minBy:function(V,Ae){return Su(this,Ae?fa(Ae):jl,V)},rest:function(){return this.slice(1)},skip:function(V){return this.slice(Math.max(0,V))},skipLast:function(V){return Pt(this,this.toSeq().reverse().skip(V).reverse())},skipWhile:function(V,Ae){return Pt(this,Hl(this,V,Ae,!0))},skipUntil:function(V,Ae){return this.skipWhile(wr(V),Ae)},sortBy:function(V,Ae){return Pt(this,tl(this,Ae,V))},take:function(V){return this.slice(0,Math.max(0,V))},takeLast:function(V){return Pt(this,this.toSeq().reverse().take(V).reverse())},takeWhile:function(V,Ae){return Pt(this,function(V,Ae,st){var vt=xe(V);return vt.__iterateUncached=function(ut,un){var mn=this;if(un)return this.cacheResult().__iterate(ut,un);var Or=0;return V.__iterate(function(zr,gi,ai){return Ae.call(st,zr,gi,ai)&&++Or&&ut(zr,gi,mn)}),Or},vt.__iteratorUncached=function(ut,un){var mn=this;if(un)return this.cacheResult().__iterator(ut,un);var Or=V.__iterator(2,un),zr=!0;return new Ut(function(){if(!zr)return{value:void 0,done:!0};var gi=Or.next();if(gi.done)return gi;var ai=gi.value,Io=ai[0],Fo=ai[1];return Ae.call(st,Fo,Io,mn)?2===ut?gi:Bt(ut,Io,Fo,gi):(zr=!1,{value:void 0,done:!0})})},vt}(this,V,Ae))},takeUntil:function(V,Ae){return this.takeWhile(wr(V),Ae)},valueSeq:function(){return this.toIndexedSeq()},hashCode:function(){return this.__hash||(this.__hash=function(V){if(V.size===1/0)return 0;var Ae=A(V),st=_(V),vt=Ae?1:0;return function(V,Ae){return Ae=_n(Ae,3432918353),Ae=_n(Ae<<15|Ae>>>-15,461845907),Ae=_n(Ae<<13|Ae>>>-13,5),Ae=_n((Ae=(Ae+3864292196|0)^V)^Ae>>>16,2246822507),Ge((Ae=_n(Ae^Ae>>>13,3266489909))^Ae>>>16)}(V.__iterate(st?Ae?function(un,mn){vt=31*vt+Ul(kr(un),kr(mn))|0}:function(un,mn){vt=vt+Ul(kr(un),kr(mn))|0}:Ae?function(un){vt=31*vt+kr(un)|0}:function(un){vt=vt+kr(un)|0}),vt)}(this))}});var Hu=r.prototype;Hu[N]=!0,Hu[Zt]=Hu.values,Hu.__toJS=Hu.toArray,Hu.__toStringMapper=pu,Hu.inspect=Hu.toSource=function(){return this.toString()},Hu.chain=Hu.flatMap,Hu.contains=Hu.includes,js(u,{flip:function(){return Pt(this,Eo(this))},mapEntries:function(V,Ae){var st=this,vt=0;return Pt(this,this.toSeq().map(function(ut,un){return V.call(Ae,[un,ut],vt++,st)}).fromEntrySeq())},mapKeys:function(V,Ae){var st=this;return Pt(this,this.toSeq().flip().map(function(vt,ut){return V.call(Ae,vt,ut,st)}).flip())}});var Uu=u.prototype;function Bo(V,Ae){return Ae}function uu(V,Ae){return[Ae,V]}function wr(V){return function(){return!V.apply(this,arguments)}}function fa(V){return function(){return-V.apply(this,arguments)}}function pu(V){return"string"==typeof V?JSON.stringify(V):String(V)}function aa(){return De(arguments)}function jl(V,Ae){return V<Ae?1:V>Ae?-1:0}function Ul(V,Ae){return V^Ae+2654435769+(V<<6)+(V>>2)|0}return Uu[L]=!0,Uu[Zt]=Hu.entries,Uu.__toJS=Hu.toObject,Uu.__toStringMapper=function(V,Ae){return JSON.stringify(Ae)+": "+pu(V)},js(p,{toKeyedSeq:function(){return new xi(this,!1)},filter:function(V,Ae){return Pt(this,tc(this,V,Ae,!1))},findIndex:function(V,Ae){var st=this.findEntry(V,Ae);return st?st[0]:-1},indexOf:function(V){var Ae=this.keyOf(V);return void 0===Ae?-1:Ae},lastIndexOf:function(V){var Ae=this.lastKeyOf(V);return void 0===Ae?-1:Ae},reverse:function(){return Pt(this,sl(this,!1))},slice:function(V,Ae){return Pt(this,Ec(this,V,Ae,!1))},splice:function(V,Ae){var st=arguments.length;if(Ae=Math.max(0|Ae,0),0===st||2===st&&!Ae)return this;V=Be(V,V<0?this.count():this.size);var vt=this.slice(0,V);return Pt(this,1===st?vt:vt.concat(De(arguments,2),this.slice(V+Ae)))},findLastIndex:function(V,Ae){var st=this.findLastEntry(V,Ae);return st?st[0]:-1},first:function(){return this.get(0)},flatten:function(V){return Pt(this,Fs(this,V,!1))},get:function(V,Ae){return(V=lt(this,V))<0||this.size===1/0||void 0!==this.size&&V>this.size?Ae:this.find(function(st,vt){return vt===V},void 0,Ae)},has:function(V){return(V=lt(this,V))>=0&&(void 0!==this.size?this.size===1/0||V<this.size:-1!==this.indexOf(V))},interpose:function(V){return Pt(this,function(V,Ae){var st=xe(V);return st.size=V.size&&2*V.size-1,st.__iterateUncached=function(vt,ut){var un=this,mn=0;return V.__iterate(function(Or,zr){return(!mn||!1!==vt(Ae,mn++,un))&&!1!==vt(Or,mn++,un)},ut),mn},st.__iteratorUncached=function(vt,ut){var Or,un=V.__iterator(1,ut),mn=0;return new Ut(function(){return(!Or||mn%2)&&(Or=un.next()).done?Or:mn%2?Bt(vt,mn++,Ae):Bt(vt,mn++,Or.value,Or)})},st}(this,V))},interleave:function(){var V=[this].concat(De(arguments)),Ae=rt(this.toSeq(),Mr.of,V),st=Ae.flatten(!0);return Ae.size&&(st.size=Ae.size*V.length),Pt(this,st)},keySeq:function(){return Jt(0,this.size)},last:function(){return this.get(-1)},skipWhile:function(V,Ae){return Pt(this,Hl(this,V,Ae,!1))},zip:function(){return Pt(this,rt(this,aa,[this].concat(De(arguments))))},zipWith:function(V){var Ae=De(arguments);return Ae[0]=this,Pt(this,rt(this,V,Ae))}}),p.prototype[Z]=!0,p.prototype[J]=!0,js(d,{get:function(V,Ae){return this.has(V)?V:Ae},includes:function(V){return this.has(V)},keySeq:function(){return this.valueSeq()}}),d.prototype.has=Hu.includes,d.prototype.contains=d.prototype.includes,js(Lr,u.prototype),js(Mr,p.prototype),js(Kr,d.prototype),js(Dn,u.prototype),js(Pr,p.prototype),js(Yt,d.prototype),{Iterable:r,Seq:di,Collection:mr,Map:Mi,OrderedMap:ne,List:fo,Stack:Aa,Set:Wa,OrderedSet:Cu,Record:Go,Range:Jt,Repeat:gn,is:br,fromJS:Gn}}()},74299:v=>{v.exports=function(T,i,r,u){var d=new Blob(void 0!==u?[u,T]:[T],{type:r||"application/octet-stream"});if(void 0!==window.navigator.msSaveBlob)window.navigator.msSaveBlob(d,i);else{var e=window.URL&&window.URL.createObjectURL?window.URL.createObjectURL(d):window.webkitURL.createObjectURL(d),_=document.createElement("a");_.style.display="none",_.href=e,_.setAttribute("download",i),void 0===_.download&&_.setAttribute("target","_blank"),document.body.appendChild(_),_.click(),setTimeout(function(){document.body.removeChild(_),window.URL.revokeObjectURL(e)},200)}}},86906:v=>{var u=/^\s+|\s+$/g,p=/^[-+]0x[0-9a-f]+$/i,d=/^0b[01]+$/i,e=/^0o[0-7]+$/i,_=parseInt,y="object"==typeof global&&global&&global.Object===Object&&global,S="object"==typeof self&&self&&self.Object===Object&&self,A=y||S||Function("return this")(),L=Object.prototype.toString,Z=Math.max,J=Math.min,K=function(){return A.Date.now()};function ue(Ee){var ie=typeof Ee;return!!Ee&&("object"==ie||"function"==ie)}function se(Ee){if("number"==typeof Ee)return Ee;if(function(Ee){return"symbol"==typeof Ee||function(Ee){return!!Ee&&"object"==typeof Ee}(Ee)&&"[object Symbol]"==L.call(Ee)}(Ee))return NaN;if(ue(Ee)){var ie="function"==typeof Ee.valueOf?Ee.valueOf():Ee;Ee=ue(ie)?ie+"":ie}if("string"!=typeof Ee)return 0===Ee?Ee:+Ee;Ee=Ee.replace(u,"");var he=d.test(Ee);return he||e.test(Ee)?_(Ee.slice(2),he?2:8):p.test(Ee)?NaN:+Ee}v.exports=function(Ee,ie,he){var ge,De,ce,lt,Ve,ze,Be=0,Pe=!1,je=!1,He=!0;if("function"!=typeof Ee)throw new TypeError("Expected a function");function Vt(xt){var Xt=ge,Zn=De;return ge=De=void 0,Be=xt,lt=Ee.apply(Zn,Xt)}function it(xt){return Be=xt,Ve=setTimeout(Zt,ie),Pe?Vt(xt):lt}function It(xt){var Xt=xt-ze;return void 0===ze||Xt>=ie||Xt<0||je&&xt-Be>=ce}function Zt(){var xt=K();if(It(xt))return Ut(xt);Ve=setTimeout(Zt,function(xt){var Ur=ie-(xt-ze);return je?J(Ur,ce-(xt-Be)):Ur}(xt))}function Ut(xt){return Ve=void 0,He&&ge?Vt(xt):(ge=De=void 0,lt)}function Gt(){var xt=K(),Xt=It(xt);if(ge=arguments,De=this,ze=xt,Xt){if(void 0===Ve)return it(ze);if(je)return Ve=setTimeout(Zt,ie),Vt(ze)}return void 0===Ve&&(Ve=setTimeout(Zt,ie)),lt}return ie=se(ie)||0,ue(he)&&(Pe=!!he.leading,ce=(je="maxWait"in he)?Z(se(he.maxWait)||0,ie):ce,He="trailing"in he?!!he.trailing:He),Gt.cancel=function(){void 0!==Ve&&clearTimeout(Ve),Be=0,ge=ze=De=Ve=void 0},Gt.flush=function(){return void 0===Ve?lt:Ut(K())},Gt}},66941:v=>{var Nn,i="__lodash_hash_undefined__",d=/^\[object .+?Constructor\]$/,e="object"==typeof global&&global&&global.Object===Object&&global,_="object"==typeof self&&self&&self.Object===Object&&self,y=e||_||Function("return this")(),N=Array.prototype,L=Function.prototype,Z=Object.prototype,J=y["__core-js_shared__"],K=(Nn=/[^.]+$/.exec(J&&J.keys&&J.keys.IE_PROTO||""))?"Symbol(src)_1."+Nn:"",ee=L.toString,ue=Z.hasOwnProperty,ae=Z.toString,H=RegExp("^"+ee.call(ue).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),se=N.splice,Ee=Xt(y,"Map"),ie=Xt(Object,"create");function he(Nn){var $n=-1,Br=Nn?Nn.length:0;for(this.clear();++$n<Br;){var Yr=Nn[$n];this.set(Yr[0],Yr[1])}}function ze(Nn){var $n=-1,Br=Nn?Nn.length:0;for(this.clear();++$n<Br;){var Yr=Nn[$n];this.set(Yr[0],Yr[1])}}function it(Nn){var $n=-1,Br=Nn?Nn.length:0;for(this.clear();++$n<Br;){var Yr=Nn[$n];this.set(Yr[0],Yr[1])}}function bt(Nn,$n){for(var Br=Nn.length;Br--;)if(Mr(Nn[Br][0],$n))return Br;return-1}function xt(Nn,$n){var Br=Nn.__data__;return function(Nn){var $n=typeof Nn;return"string"==$n||"number"==$n||"symbol"==$n||"boolean"==$n?"__proto__"!==Nn:null===Nn}($n)?Br["string"==typeof $n?"string":"hash"]:Br.map}function Xt(Nn,$n){var Br=function(Nn,$n){return null==Nn?void 0:Nn[$n]}(Nn,$n);return function(Nn){return!(!ei(Nn)||function(Nn){return!!K&&K in Nn}(Nn))&&(function(Nn){var $n=ei(Nn)?ae.call(Nn):"";return"[object Function]"==$n||"[object GeneratorFunction]"==$n}(Nn)||function(Nn){var $n=!1;if(null!=Nn&&"function"!=typeof Nn.toString)try{$n=!!(Nn+"")}catch(Br){}return $n}(Nn)?H:d).test(function(Nn){if(null!=Nn){try{return ee.call(Nn)}catch($n){}try{return Nn+""}catch($n){}}return""}(Nn))}(Br)?Br:void 0}function Lr(Nn,$n){if("function"!=typeof Nn||$n&&"function"!=typeof $n)throw new TypeError("Expected a function");var Br=function(){var Yr=arguments,fi=$n?$n.apply(this,Yr):Yr[0],ki=Br.cache;if(ki.has(fi))return ki.get(fi);var Hi=Nn.apply(this,Yr);return Br.cache=ki.set(fi,Hi),Hi};return Br.cache=new(Lr.Cache||it),Br}function Mr(Nn,$n){return Nn===$n||Nn!=Nn&&$n!=$n}function ei(Nn){var $n=typeof Nn;return!!Nn&&("object"==$n||"function"==$n)}he.prototype.clear=function(){this.__data__=ie?ie(null):{}},he.prototype.delete=function(Nn){return this.has(Nn)&&delete this.__data__[Nn]},he.prototype.get=function(Nn){var $n=this.__data__;if(ie){var Br=$n[Nn];return Br===i?void 0:Br}return ue.call($n,Nn)?$n[Nn]:void 0},he.prototype.has=function(Nn){var $n=this.__data__;return ie?void 0!==$n[Nn]:ue.call($n,Nn)},he.prototype.set=function(Nn,$n){return this.__data__[Nn]=ie&&void 0===$n?i:$n,this},ze.prototype.clear=function(){this.__data__=[]},ze.prototype.delete=function(Nn){var $n=this.__data__,Br=bt($n,Nn);return!(Br<0||(Br==$n.length-1?$n.pop():se.call($n,Br,1),0))},ze.prototype.get=function(Nn){var $n=this.__data__,Br=bt($n,Nn);return Br<0?void 0:$n[Br][1]},ze.prototype.has=function(Nn){return bt(this.__data__,Nn)>-1},ze.prototype.set=function(Nn,$n){var Br=this.__data__,Yr=bt(Br,Nn);return Yr<0?Br.push([Nn,$n]):Br[Yr][1]=$n,this},it.prototype.clear=function(){this.__data__={hash:new he,map:new(Ee||ze),string:new he}},it.prototype.delete=function(Nn){return xt(this,Nn).delete(Nn)},it.prototype.get=function(Nn){return xt(this,Nn).get(Nn)},it.prototype.has=function(Nn){return xt(this,Nn).has(Nn)},it.prototype.set=function(Nn,$n){return xt(this,Nn).set(Nn,$n),this},Lr.Cache=it,v.exports=Lr},6123:v=>{var T="Expected a function",u=/^\s+|\s+$/g,p=/^[-+]0x[0-9a-f]+$/i,d=/^0b[01]+$/i,e=/^0o[0-7]+$/i,_=parseInt,y="object"==typeof global&&global&&global.Object===Object&&global,S="object"==typeof self&&self&&self.Object===Object&&self,A=y||S||Function("return this")(),L=Object.prototype.toString,Z=Math.max,J=Math.min,K=function(){return A.Date.now()};function ae(ie){var he=typeof ie;return!!ie&&("object"==he||"function"==he)}function Ee(ie){if("number"==typeof ie)return ie;if(function(ie){return"symbol"==typeof ie||function(ie){return!!ie&&"object"==typeof ie}(ie)&&"[object Symbol]"==L.call(ie)}(ie))return NaN;if(ae(ie)){var he="function"==typeof ie.valueOf?ie.valueOf():ie;ie=ae(he)?he+"":he}if("string"!=typeof ie)return 0===ie?ie:+ie;ie=ie.replace(u,"");var ge=d.test(ie);return ge||e.test(ie)?_(ie.slice(2),ge?2:8):p.test(ie)?NaN:+ie}v.exports=function(ie,he,ge){var De=!0,ce=!0;if("function"!=typeof ie)throw new TypeError(T);return ae(ge)&&(De="leading"in ge?!!ge.leading:De,ce="trailing"in ge?!!ge.trailing:ce),function(ie,he,ge){var De,ce,lt,Ve,ze,Be,Pe=0,je=!1,He=!1,Vt=!0;if("function"!=typeof ie)throw new TypeError(T);function it(Xt){var Zn=De,Ur=ce;return De=ce=void 0,Pe=Xt,Ve=ie.apply(Ur,Zn)}function tn(Xt){return Pe=Xt,ze=setTimeout(Ut,he),je?it(Xt):Ve}function Zt(Xt){var Zn=Xt-Be;return void 0===Be||Zn>=he||Zn<0||He&&Xt-Pe>=lt}function Ut(){var Xt=K();if(Zt(Xt))return Bt(Xt);ze=setTimeout(Ut,function(Xt){var di=he-(Xt-Be);return He?J(di,lt-(Xt-Pe)):di}(Xt))}function Bt(Xt){return ze=void 0,Vt&&De?it(Xt):(De=ce=void 0,Ve)}function xt(){var Xt=K(),Zn=Zt(Xt);if(De=arguments,ce=this,Be=Xt,Zn){if(void 0===ze)return tn(Be);if(He)return ze=setTimeout(Ut,he),it(Be)}return void 0===ze&&(ze=setTimeout(Ut,he)),Ve}return he=Ee(he)||0,ae(ge)&&(je=!!ge.leading,lt=(He="maxWait"in ge)?Z(Ee(ge.maxWait)||0,he):lt,Vt="trailing"in ge?!!ge.trailing:Vt),xt.cancel=function(){void 0!==ze&&clearTimeout(ze),Pe=0,De=Be=ce=ze=void 0},xt.flush=function(){return void 0===ze?Ve:Bt(K())},xt}(ie,he,{leading:De,maxWait:he,trailing:ce})}},81235:(v,T,i)=>{var p=i(4153)(i(27038),"DataView");v.exports=p},41505:(v,T,i)=>{var r=i(59410),u=i(21143),p=i(604),d=i(80584),e=i(7792);function _(y){var S=-1,A=null==y?0:y.length;for(this.clear();++S<A;){var N=y[S];this.set(N[0],N[1])}}_.prototype.clear=r,_.prototype.delete=u,_.prototype.get=p,_.prototype.has=d,_.prototype.set=e,v.exports=_},73545:(v,T,i)=>{var r=i(63391),u=i(68971),p=i(18858),d=i(13913),e=i(68944);function _(y){var S=-1,A=null==y?0:y.length;for(this.clear();++S<A;){var N=y[S];this.set(N[0],N[1])}}_.prototype.clear=r,_.prototype.delete=u,_.prototype.get=p,_.prototype.has=d,_.prototype.set=e,v.exports=_},39046:(v,T,i)=>{var p=i(4153)(i(27038),"Map");v.exports=p},93177:(v,T,i)=>{var r=i(70536),u=i(61502),p=i(94960),d=i(61539),e=i(34138);function _(y){var S=-1,A=null==y?0:y.length;for(this.clear();++S<A;){var N=y[S];this.set(N[0],N[1])}}_.prototype.clear=r,_.prototype.delete=u,_.prototype.get=p,_.prototype.has=d,_.prototype.set=e,v.exports=_},97129:(v,T,i)=>{var p=i(4153)(i(27038),"Promise");v.exports=p},74918:(v,T,i)=>{var p=i(4153)(i(27038),"Set");v.exports=p},48690:(v,T,i)=>{var r=i(93177),u=i(30365),p=i(58235);function d(e){var _=-1,y=null==e?0:e.length;for(this.__data__=new r;++_<y;)this.add(e[_])}d.prototype.add=d.prototype.push=u,d.prototype.has=p,v.exports=d},33667:(v,T,i)=>{var r=i(73545),u=i(18034),p=i(37238),d=i(75887),e=i(81450),_=i(61386);function y(S){var A=this.__data__=new r(S);this.size=A.size}y.prototype.clear=u,y.prototype.delete=p,y.prototype.get=d,y.prototype.has=e,y.prototype.set=_,v.exports=y},57333:(v,T,i)=>{var r=i(27038);v.exports=r.Symbol},96820:(v,T,i)=>{var r=i(27038);v.exports=r.Uint8Array},54203:(v,T,i)=>{var p=i(4153)(i(27038),"WeakMap");v.exports=p},81638:v=>{v.exports=function(i,r,u){switch(u.length){case 0:return i.call(r);case 1:return i.call(r,u[0]);case 2:return i.call(r,u[0],u[1]);case 3:return i.call(r,u[0],u[1],u[2])}return i.apply(r,u)}},4500:v=>{v.exports=function(i,r){for(var u=-1,p=null==i?0:i.length;++u<p&&!1!==r(i[u],u,i););return i}},11375:v=>{v.exports=function(i,r){for(var u=-1,p=null==i?0:i.length,d=0,e=[];++u<p;){var _=i[u];r(_,u,i)&&(e[d++]=_)}return e}},71890:(v,T,i)=>{var r=i(48282),u=i(2952),p=i(81690),d=i(84444),e=i(20968),_=i(47679),S=Object.prototype.hasOwnProperty;v.exports=function(N,L){var Z=p(N),J=!Z&&u(N),K=!Z&&!J&&d(N),ee=!Z&&!J&&!K&&_(N),ue=Z||J||K||ee,ae=ue?r(N.length,String):[],H=ae.length;for(var se in N)(L||S.call(N,se))&&(!ue||!("length"==se||K&&("offset"==se||"parent"==se)||ee&&("buffer"==se||"byteLength"==se||"byteOffset"==se)||e(se,H)))&&ae.push(se);return ae}},14992:v=>{v.exports=function(i,r){for(var u=-1,p=null==i?0:i.length,d=Array(p);++u<p;)d[u]=r(i[u],u,i);return d}},94165:v=>{v.exports=function(i,r){for(var u=-1,p=r.length,d=i.length;++u<p;)i[d+u]=r[u];return i}},89731:v=>{v.exports=function(i,r,u,p){var d=-1,e=null==i?0:i.length;for(p&&e&&(u=i[++d]);++d<e;)u=r(u,i[d],d,i);return u}},8141:v=>{v.exports=function(i,r){for(var u=-1,p=null==i?0:i.length;++u<p;)if(r(i[u],u,i))return!0;return!1}},87280:v=>{v.exports=function(i){return i.split("")}},54561:v=>{var T=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;v.exports=function(r){return r.match(T)||[]}},63530:(v,T,i)=>{var r=i(92007),u=i(71166);v.exports=function(d,e,_){(void 0!==_&&!u(d[e],_)||void 0===_&&!(e in d))&&r(d,e,_)}},23898:(v,T,i)=>{var r=i(92007),u=i(71166),d=Object.prototype.hasOwnProperty;v.exports=function(_,y,S){var A=_[y];(!d.call(_,y)||!u(A,S)||void 0===S&&!(y in _))&&r(_,y,S)}},15758:(v,T,i)=>{var r=i(71166);v.exports=function(p,d){for(var e=p.length;e--;)if(r(p[e][0],d))return e;return-1}},22067:(v,T,i)=>{var r=i(11694),u=i(59108);v.exports=function(d,e){return d&&r(e,u(e),d)}},70882:(v,T,i)=>{var r=i(11694),u=i(42970);v.exports=function(d,e){return d&&r(e,u(e),d)}},92007:(v,T,i)=>{var r=i(20395);v.exports=function(p,d,e){"__proto__"==d&&r?r(p,d,{configurable:!0,enumerable:!0,value:e,writable:!0}):p[d]=e}},77007:(v,T,i)=>{var r=i(33667),u=i(4500),p=i(23898),d=i(22067),e=i(70882),_=i(50694),y=i(53595),S=i(14746),A=i(78857),N=i(58605),L=i(51675),Z=i(26663),J=i(62963),K=i(32143),ee=i(31563),ue=i(81690),ae=i(84444),H=i(32e3),se=i(53867),Ee=i(48855),ie=i(59108),he=i(42970),lt="[object Arguments]",je="[object Function]",tn="[object Object]",$n={};$n[lt]=$n["[object Array]"]=$n["[object ArrayBuffer]"]=$n["[object DataView]"]=$n["[object Boolean]"]=$n["[object Date]"]=$n["[object Float32Array]"]=$n["[object Float64Array]"]=$n["[object Int8Array]"]=$n["[object Int16Array]"]=$n["[object Int32Array]"]=$n["[object Map]"]=$n["[object Number]"]=$n[tn]=$n["[object RegExp]"]=$n["[object Set]"]=$n["[object String]"]=$n["[object Symbol]"]=$n["[object Uint8Array]"]=$n["[object Uint8ClampedArray]"]=$n["[object Uint16Array]"]=$n["[object Uint32Array]"]=!0,$n["[object Error]"]=$n[je]=$n["[object WeakMap]"]=!1,v.exports=function Br(Yr,fi,ki,Hi,Zr,Cn){var Wt,zn=1&fi,rr=2&fi,Fr=4&fi;if(ki&&(Wt=Zr?ki(Yr,Hi,Zr,Cn):ki(Yr)),void 0!==Wt)return Wt;if(!se(Yr))return Yr;var Gn=ue(Yr);if(Gn){if(Wt=J(Yr),!zn)return y(Yr,Wt)}else{var Jr=Z(Yr),_i=Jr==je||"[object GeneratorFunction]"==Jr;if(ae(Yr))return _(Yr,zn);if(Jr==tn||Jr==lt||_i&&!Zr){if(Wt=rr||_i?{}:ee(Yr),!zn)return rr?A(Yr,e(Wt,Yr)):S(Yr,d(Wt,Yr))}else{if(!$n[Jr])return Zr?Yr:{};Wt=K(Yr,Jr,zn)}}Cn||(Cn=new r);var wi=Cn.get(Yr);if(wi)return wi;Cn.set(Yr,Wt),Ee(Yr)?Yr.forEach(function(gn){Wt.add(Br(gn,fi,ki,gn,Yr,Cn))}):H(Yr)&&Yr.forEach(function(gn,yn){Wt.set(yn,Br(gn,fi,ki,yn,Yr,Cn))});var Dr=Gn?void 0:(Fr?rr?L:N:rr?he:ie)(Yr);return u(Dr||Yr,function(gn,yn){Dr&&(gn=Yr[yn=gn]),p(Wt,yn,Br(gn,fi,ki,yn,Yr,Cn))}),Wt}},60920:(v,T,i)=>{var r=i(53867),u=Object.create,p=function(){function d(){}return function(e){if(!r(e))return{};if(u)return u(e);d.prototype=e;var _=new d;return d.prototype=void 0,_}}();v.exports=p},59026:(v,T,i)=>{var r=i(18022),p=i(99889)(r);v.exports=p},12229:v=>{v.exports=function(i,r,u,p){for(var d=i.length,e=u+(p?1:-1);p?e--:++e<d;)if(r(i[e],e,i))return e;return-1}},56369:(v,T,i)=>{var r=i(94165),u=i(21006);v.exports=function p(d,e,_,y,S){var A=-1,N=d.length;for(_||(_=u),S||(S=[]);++A<N;){var L=d[A];e>0&&_(L)?e>1?p(L,e-1,_,y,S):r(S,L):y||(S[S.length]=L)}return S}},75290:(v,T,i)=>{var u=i(8269)();v.exports=u},18022:(v,T,i)=>{var r=i(75290),u=i(59108);v.exports=function(d,e){return d&&r(d,e,u)}},93436:(v,T,i)=>{var r=i(64667),u=i(82773);v.exports=function(d,e){for(var _=0,y=(e=r(e,d)).length;null!=d&&_<y;)d=d[u(e[_++])];return _&&_==y?d:void 0}},19215:(v,T,i)=>{var r=i(94165),u=i(81690);v.exports=function(d,e,_){var y=e(d);return u(d)?y:r(y,_(d))}},72802:(v,T,i)=>{var r=i(57333),u=i(21613),p=i(81244),_=r?r.toStringTag:void 0;v.exports=function(S){return null==S?void 0===S?"[object Undefined]":"[object Null]":_&&_ in Object(S)?u(S):p(S)}},55333:v=>{v.exports=function(i,r){return null!=i&&r in Object(i)}},77090:(v,T,i)=>{var r=i(72802),u=i(27503);v.exports=function(e){return u(e)&&"[object Arguments]"==r(e)}},30696:(v,T,i)=>{var r=i(36863),u=i(27503);v.exports=function p(d,e,_,y,S){return d===e||(null==d||null==e||!u(d)&&!u(e)?d!=d&&e!=e:r(d,e,_,y,p,S))}},36863:(v,T,i)=>{var r=i(33667),u=i(27667),p=i(64630),d=i(70838),e=i(26663),_=i(81690),y=i(84444),S=i(47679),N="[object Arguments]",L="[object Array]",Z="[object Object]",K=Object.prototype.hasOwnProperty;v.exports=function(ue,ae,H,se,Ee,ie){var he=_(ue),ge=_(ae),De=he?L:e(ue),ce=ge?L:e(ae),lt=(De=De==N?Z:De)==Z,Ve=(ce=ce==N?Z:ce)==Z,ze=De==ce;if(ze&&y(ue)){if(!y(ae))return!1;he=!0,lt=!1}if(ze&&!lt)return ie||(ie=new r),he||S(ue)?u(ue,ae,H,se,Ee,ie):p(ue,ae,De,H,se,Ee,ie);if(!(1&H)){var Be=lt&&K.call(ue,"__wrapped__"),Pe=Ve&&K.call(ae,"__wrapped__");if(Be||Pe){var je=Be?ue.value():ue,He=Pe?ae.value():ae;return ie||(ie=new r),Ee(je,He,H,se,ie)}}return!!ze&&(ie||(ie=new r),d(ue,ae,H,se,Ee,ie))}},63434:(v,T,i)=>{var r=i(26663),u=i(27503);v.exports=function(e){return u(e)&&"[object Map]"==r(e)}},88783:(v,T,i)=>{var r=i(33667),u=i(30696);v.exports=function(_,y,S,A){var N=S.length,L=N,Z=!A;if(null==_)return!L;for(_=Object(_);N--;){var J=S[N];if(Z&&J[2]?J[1]!==_[J[0]]:!(J[0]in _))return!1}for(;++N<L;){var K=(J=S[N])[0],ee=_[K],ue=J[1];if(Z&&J[2]){if(void 0===ee&&!(K in _))return!1}else{var ae=new r;if(A)var H=A(ee,ue,K,_,y,ae);if(!(void 0===H?u(ue,ee,3,A,ae):H))return!1}}return!0}},43540:(v,T,i)=>{var r=i(55836),u=i(38466),p=i(53867),d=i(51217),_=/^\[object .+?Constructor\]$/,L=RegExp("^"+Function.prototype.toString.call(Object.prototype.hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");v.exports=function(J){return!(!p(J)||u(J))&&(r(J)?L:_).test(d(J))}},67495:(v,T,i)=>{var r=i(26663),u=i(27503);v.exports=function(e){return u(e)&&"[object Set]"==r(e)}},99390:(v,T,i)=>{var r=i(72802),u=i(8613),p=i(27503),ze={};ze["[object Float32Array]"]=ze["[object Float64Array]"]=ze["[object Int8Array]"]=ze["[object Int16Array]"]=ze["[object Int32Array]"]=ze["[object Uint8Array]"]=ze["[object Uint8ClampedArray]"]=ze["[object Uint16Array]"]=ze["[object Uint32Array]"]=!0,ze["[object Arguments]"]=ze["[object Array]"]=ze["[object ArrayBuffer]"]=ze["[object Boolean]"]=ze["[object DataView]"]=ze["[object Date]"]=ze["[object Error]"]=ze["[object Function]"]=ze["[object Map]"]=ze["[object Number]"]=ze["[object Object]"]=ze["[object RegExp]"]=ze["[object Set]"]=ze["[object String]"]=ze["[object WeakMap]"]=!1,v.exports=function(Pe){return p(Pe)&&u(Pe.length)&&!!ze[r(Pe)]}},5245:(v,T,i)=>{var r=i(69433),u=i(68608),p=i(80290),d=i(81690),e=i(63354);v.exports=function(y){return"function"==typeof y?y:null==y?p:"object"==typeof y?d(y)?u(y[0],y[1]):r(y):e(y)}},92488:(v,T,i)=>{var r=i(58845),u=i(36700),d=Object.prototype.hasOwnProperty;v.exports=function(_){if(!r(_))return u(_);var y=[];for(var S in Object(_))d.call(_,S)&&"constructor"!=S&&y.push(S);return y}},50762:(v,T,i)=>{var r=i(53867),u=i(58845),p=i(25618),e=Object.prototype.hasOwnProperty;v.exports=function(y){if(!r(y))return p(y);var S=u(y),A=[];for(var N in y)"constructor"==N&&(S||!e.call(y,N))||A.push(N);return A}},69433:(v,T,i)=>{var r=i(88783),u=i(48834),p=i(63587);v.exports=function(e){var _=u(e);return 1==_.length&&_[0][2]?p(_[0][0],_[0][1]):function(y){return y===e||r(y,e,_)}}},68608:(v,T,i)=>{var r=i(30696),u=i(58102),p=i(18303),d=i(99743),e=i(45774),_=i(63587),y=i(82773);v.exports=function(L,Z){return d(L)&&e(Z)?_(y(L),Z):function(J){var K=u(J,L);return void 0===K&&K===Z?p(J,L):r(Z,K,3)}}},9085:(v,T,i)=>{var r=i(33667),u=i(63530),p=i(75290),d=i(23607),e=i(53867),_=i(42970),y=i(45959);v.exports=function S(A,N,L,Z,J){A!==N&&p(N,function(K,ee){if(J||(J=new r),e(K))d(A,N,ee,L,S,Z,J);else{var ue=Z?Z(y(A,ee),K,ee+"",A,N,J):void 0;void 0===ue&&(ue=K),u(A,ee,ue)}},_)}},23607:(v,T,i)=>{var r=i(63530),u=i(50694),p=i(96282),d=i(53595),e=i(31563),_=i(2952),y=i(81690),S=i(82027),A=i(84444),N=i(55836),L=i(53867),Z=i(82358),J=i(47679),K=i(45959),ee=i(31413);v.exports=function(ae,H,se,Ee,ie,he,ge){var De=K(ae,se),ce=K(H,se),lt=ge.get(ce);if(lt)r(ae,se,lt);else{var Ve=he?he(De,ce,se+"",ae,H,ge):void 0,ze=void 0===Ve;if(ze){var Be=y(ce),Pe=!Be&&A(ce),je=!Be&&!Pe&&J(ce);Ve=ce,Be||Pe||je?y(De)?Ve=De:S(De)?Ve=d(De):Pe?(ze=!1,Ve=u(ce,!0)):je?(ze=!1,Ve=p(ce,!0)):Ve=[]:Z(ce)||_(ce)?(Ve=De,_(De)?Ve=ee(De):(!L(De)||N(De))&&(Ve=e(ce))):ze=!1}ze&&(ge.set(ce,Ve),ie(Ve,ce,Ee,he,ge),ge.delete(ce)),r(ae,se,Ve)}}},68840:v=>{v.exports=function(i){return function(r){return null==r?void 0:r[i]}}},59866:(v,T,i)=>{var r=i(93436);v.exports=function(p){return function(d){return r(d,p)}}},17421:v=>{v.exports=function(i){return function(r){return null==i?void 0:i[r]}}},85105:v=>{v.exports=function(i,r,u,p,d){return d(i,function(e,_,y){u=p?(p=!1,e):r(u,e,_,y)}),u}},84441:(v,T,i)=>{var r=i(80290),u=i(15529),p=i(39009);v.exports=function(e,_){return p(u(e,_,r),e+"")}},32773:(v,T,i)=>{var r=i(23898),u=i(64667),p=i(20968),d=i(53867),e=i(82773);v.exports=function(y,S,A,N){if(!d(y))return y;for(var L=-1,Z=(S=u(S,y)).length,J=Z-1,K=y;null!=K&&++L<Z;){var ee=e(S[L]),ue=A;if("__proto__"===ee||"constructor"===ee||"prototype"===ee)return y;if(L!=J){var ae=K[ee];void 0===(ue=N?N(ae,ee,K):void 0)&&(ue=d(ae)?ae:p(S[L+1])?[]:{})}r(K,ee,ue),K=K[ee]}return y}},99372:(v,T,i)=>{var r=i(45654),u=i(20395),p=i(80290);v.exports=u?function(e,_){return u(e,"toString",{configurable:!0,enumerable:!1,value:r(_),writable:!0})}:p},63586:v=>{v.exports=function(i,r,u){var p=-1,d=i.length;r<0&&(r=-r>d?0:d+r),(u=u>d?d:u)<0&&(u+=d),d=r>u?0:u-r>>>0,r>>>=0;for(var e=Array(d);++p<d;)e[p]=i[p+r];return e}},37834:(v,T,i)=>{var r=i(59026);v.exports=function(p,d){var e;return r(p,function(_,y,S){return!(e=d(_,y,S))}),!!e}},48282:v=>{v.exports=function(i,r){for(var u=-1,p=Array(i);++u<i;)p[u]=r(u);return p}},68166:(v,T,i)=>{var r=i(57333),u=i(14992),p=i(81690),d=i(7786),_=r?r.prototype:void 0,y=_?_.toString:void 0;v.exports=function S(A){if("string"==typeof A)return A;if(p(A))return u(A,S)+"";if(d(A))return y?y.call(A):"";var N=A+"";return"0"==N&&1/A==-1/0?"-0":N}},13743:(v,T,i)=>{var r=i(87478),u=/^\s+/;v.exports=function(d){return d&&d.slice(0,r(d)+1).replace(u,"")}},70544:v=>{v.exports=function(i){return function(r){return i(r)}}},72064:(v,T,i)=>{var r=i(64667),u=i(27842),p=i(61746),d=i(82773);v.exports=function(_,y){return y=r(y,_),null==(_=p(_,y))||delete _[d(u(y))]}},25687:v=>{v.exports=function(i,r,u){for(var p=-1,d=i.length,e=r.length,_={};++p<d;)u(_,i[p],p<e?r[p]:void 0);return _}},13747:v=>{v.exports=function(i,r){return i.has(r)}},64667:(v,T,i)=>{var r=i(81690),u=i(99743),p=i(89775),d=i(41233);v.exports=function(_,y){return r(_)?_:u(_,y)?[_]:p(d(_))}},26477:(v,T,i)=>{var r=i(63586);v.exports=function(p,d,e){var _=p.length;return e=void 0===e?_:e,!d&&e>=_?p:r(p,d,e)}},88461:(v,T,i)=>{var r=i(96820);v.exports=function(p){var d=new p.constructor(p.byteLength);return new r(d).set(new r(p)),d}},50694:(v,T,i)=>{v=i.nmd(v);var r=i(27038),u=T&&!T.nodeType&&T,p=u&&v&&!v.nodeType&&v,e=p&&p.exports===u?r.Buffer:void 0,_=e?e.allocUnsafe:void 0;v.exports=function(S,A){if(A)return S.slice();var N=S.length,L=_?_(N):new S.constructor(N);return S.copy(L),L}},59757:(v,T,i)=>{var r=i(88461);v.exports=function(p,d){var e=d?r(p.buffer):p.buffer;return new p.constructor(e,p.byteOffset,p.byteLength)}},83615:v=>{var T=/\w*$/;v.exports=function(r){var u=new r.constructor(r.source,T.exec(r));return u.lastIndex=r.lastIndex,u}},42282:(v,T,i)=>{var r=i(57333),u=r?r.prototype:void 0,p=u?u.valueOf:void 0;v.exports=function(e){return p?Object(p.call(e)):{}}},96282:(v,T,i)=>{var r=i(88461);v.exports=function(p,d){var e=d?r(p.buffer):p.buffer;return new p.constructor(e,p.byteOffset,p.length)}},53595:v=>{v.exports=function(i,r){var u=-1,p=i.length;for(r||(r=Array(p));++u<p;)r[u]=i[u];return r}},11694:(v,T,i)=>{var r=i(23898),u=i(92007);v.exports=function(d,e,_,y){var S=!_;_||(_={});for(var A=-1,N=e.length;++A<N;){var L=e[A],Z=y?y(_[L],d[L],L,_,d):void 0;void 0===Z&&(Z=d[L]),S?u(_,L,Z):r(_,L,Z)}return _}},14746:(v,T,i)=>{var r=i(11694),u=i(10296);v.exports=function(d,e){return r(d,u(d),e)}},78857:(v,T,i)=>{var r=i(11694),u=i(29572);v.exports=function(d,e){return r(d,u(d),e)}},93412:(v,T,i)=>{var r=i(27038);v.exports=r["__core-js_shared__"]},30906:(v,T,i)=>{var r=i(84441),u=i(71100);v.exports=function(d){return r(function(e,_){var y=-1,S=_.length,A=S>1?_[S-1]:void 0,N=S>2?_[2]:void 0;for(A=d.length>3&&"function"==typeof A?(S--,A):void 0,N&&u(_[0],_[1],N)&&(A=S<3?void 0:A,S=1),e=Object(e);++y<S;){var L=_[y];L&&d(e,L,y,A)}return e})}},99889:(v,T,i)=>{var r=i(93406);v.exports=function(p,d){return function(e,_){if(null==e)return e;if(!r(e))return p(e,_);for(var y=e.length,S=d?y:-1,A=Object(e);(d?S--:++S<y)&&!1!==_(A[S],S,A););return e}}},8269:v=>{v.exports=function(i){return function(r,u,p){for(var d=-1,e=Object(r),_=p(r),y=_.length;y--;){var S=_[i?y:++d];if(!1===u(e[S],S,e))break}return r}}},66803:(v,T,i)=>{var r=i(26477),u=i(407),p=i(2150),d=i(41233);v.exports=function(_){return function(y){y=d(y);var S=u(y)?p(y):void 0,A=S?S[0]:y.charAt(0),N=S?r(S,1).join(""):y.slice(1);return A[_]()+N}}},17407:(v,T,i)=>{var r=i(89731),u=i(75289),p=i(96590),e=RegExp("['\u2019]","g");v.exports=function(y){return function(S){return r(p(u(S).replace(e,"")),y,"")}}},44674:(v,T,i)=>{var r=i(5245),u=i(93406),p=i(59108);v.exports=function(e){return function(_,y,S){var A=Object(_);if(!u(_)){var N=r(y,3);_=p(_),y=function(Z){return N(A[Z],Z,A)}}var L=e(_,y,S);return L>-1?A[N?_[L]:L]:void 0}}},925:(v,T,i)=>{var r=i(82358);v.exports=function(p){return r(p)?void 0:p}},4068:(v,T,i)=>{var p=i(17421)({\u00c0:"A",\u00c1:"A",\u00c2:"A",\u00c3:"A",\u00c4:"A",\u00c5:"A",\u00e0:"a",\u00e1:"a",\u00e2:"a",\u00e3:"a",\u00e4:"a",\u00e5:"a",\u00c7:"C",\u00e7:"c",\u00d0:"D",\u00f0:"d",\u00c8:"E",\u00c9:"E",\u00ca:"E",\u00cb:"E",\u00e8:"e",\u00e9:"e",\u00ea:"e",\u00eb:"e",\u00cc:"I",\u00cd:"I",\u00ce:"I",\u00cf:"I",\u00ec:"i",\u00ed:"i",\u00ee:"i",\u00ef:"i",\u00d1:"N",\u00f1:"n",\u00d2:"O",\u00d3:"O",\u00d4:"O",\u00d5:"O",\u00d6:"O",\u00d8:"O",\u00f2:"o",\u00f3:"o",\u00f4:"o",\u00f5:"o",\u00f6:"o",\u00f8:"o",\u00d9:"U",\u00da:"U",\u00db:"U",\u00dc:"U",\u00f9:"u",\u00fa:"u",\u00fb:"u",\u00fc:"u",\u00dd:"Y",\u00fd:"y",\u00ff:"y",\u00c6:"Ae",\u00e6:"ae",\u00de:"Th",\u00fe:"th",\u00df:"ss",\u0100:"A",\u0102:"A",\u0104:"A",\u0101:"a",\u0103:"a",\u0105:"a",\u0106:"C",\u0108:"C",\u010a:"C",\u010c:"C",\u0107:"c",\u0109:"c",\u010b:"c",\u010d:"c",\u010e:"D",\u0110:"D",\u010f:"d",\u0111:"d",\u0112:"E",\u0114:"E",\u0116:"E",\u0118:"E",\u011a:"E",\u0113:"e",\u0115:"e",\u0117:"e",\u0119:"e",\u011b:"e",\u011c:"G",\u011e:"G",\u0120:"G",\u0122:"G",\u011d:"g",\u011f:"g",\u0121:"g",\u0123:"g",\u0124:"H",\u0126:"H",\u0125:"h",\u0127:"h",\u0128:"I",\u012a:"I",\u012c:"I",\u012e:"I",\u0130:"I",\u0129:"i",\u012b:"i",\u012d:"i",\u012f:"i",\u0131:"i",\u0134:"J",\u0135:"j",\u0136:"K",\u0137:"k",\u0138:"k",\u0139:"L",\u013b:"L",\u013d:"L",\u013f:"L",\u0141:"L",\u013a:"l",\u013c:"l",\u013e:"l",\u0140:"l",\u0142:"l",\u0143:"N",\u0145:"N",\u0147:"N",\u014a:"N",\u0144:"n",\u0146:"n",\u0148:"n",\u014b:"n",\u014c:"O",\u014e:"O",\u0150:"O",\u014d:"o",\u014f:"o",\u0151:"o",\u0154:"R",\u0156:"R",\u0158:"R",\u0155:"r",\u0157:"r",\u0159:"r",\u015a:"S",\u015c:"S",\u015e:"S",\u0160:"S",\u015b:"s",\u015d:"s",\u015f:"s",\u0161:"s",\u0162:"T",\u0164:"T",\u0166:"T",\u0163:"t",\u0165:"t",\u0167:"t",\u0168:"U",\u016a:"U",\u016c:"U",\u016e:"U",\u0170:"U",\u0172:"U",\u0169:"u",\u016b:"u",\u016d:"u",\u016f:"u",\u0171:"u",\u0173:"u",\u0174:"W",\u0175:"w",\u0176:"Y",\u0177:"y",\u0178:"Y",\u0179:"Z",\u017b:"Z",\u017d:"Z",\u017a:"z",\u017c:"z",\u017e:"z",\u0132:"IJ",\u0133:"ij",\u0152:"Oe",\u0153:"oe",\u0149:"'n",\u017f:"s"});v.exports=p},20395:(v,T,i)=>{var r=i(4153),u=function(){try{var p=r(Object,"defineProperty");return p({},"",{}),p}catch(d){}}();v.exports=u},27667:(v,T,i)=>{var r=i(48690),u=i(8141),p=i(13747);v.exports=function(y,S,A,N,L,Z){var J=1&A,K=y.length,ee=S.length;if(K!=ee&&!(J&&ee>K))return!1;var ue=Z.get(y),ae=Z.get(S);if(ue&&ae)return ue==S&&ae==y;var H=-1,se=!0,Ee=2&A?new r:void 0;for(Z.set(y,S),Z.set(S,y);++H<K;){var ie=y[H],he=S[H];if(N)var ge=J?N(he,ie,H,S,y,Z):N(ie,he,H,y,S,Z);if(void 0!==ge){if(ge)continue;se=!1;break}if(Ee){if(!u(S,function(De,ce){if(!p(Ee,ce)&&(ie===De||L(ie,De,A,N,Z)))return Ee.push(ce)})){se=!1;break}}else if(ie!==he&&!L(ie,he,A,N,Z)){se=!1;break}}return Z.delete(y),Z.delete(S),se}},64630:(v,T,i)=>{var r=i(57333),u=i(96820),p=i(71166),d=i(27667),e=i(37461),_=i(57673),Ee=r?r.prototype:void 0,ie=Ee?Ee.valueOf:void 0;v.exports=function(ge,De,ce,lt,Ve,ze,Be){switch(ce){case"[object DataView]":if(ge.byteLength!=De.byteLength||ge.byteOffset!=De.byteOffset)return!1;ge=ge.buffer,De=De.buffer;case"[object ArrayBuffer]":return!(ge.byteLength!=De.byteLength||!ze(new u(ge),new u(De)));case"[object Boolean]":case"[object Date]":case"[object Number]":return p(+ge,+De);case"[object Error]":return ge.name==De.name&&ge.message==De.message;case"[object RegExp]":case"[object String]":return ge==De+"";case"[object Map]":var Pe=e;case"[object Set]":if(Pe||(Pe=_),ge.size!=De.size&&!(1&lt))return!1;var He=Be.get(ge);if(He)return He==De;lt|=2,Be.set(ge,De);var Vt=d(Pe(ge),Pe(De),lt,Ve,ze,Be);return Be.delete(ge),Vt;case"[object Symbol]":if(ie)return ie.call(ge)==ie.call(De)}return!1}},70838:(v,T,i)=>{var r=i(58605),d=Object.prototype.hasOwnProperty;v.exports=function(_,y,S,A,N,L){var Z=1&S,J=r(_),K=J.length;if(K!=r(y).length&&!Z)return!1;for(var ae=K;ae--;){var H=J[ae];if(!(Z?H in y:d.call(y,H)))return!1}var se=L.get(_),Ee=L.get(y);if(se&&Ee)return se==y&&Ee==_;var ie=!0;L.set(_,y),L.set(y,_);for(var he=Z;++ae<K;){var ge=_[H=J[ae]],De=y[H];if(A)var ce=Z?A(De,ge,H,y,_,L):A(ge,De,H,_,y,L);if(!(void 0===ce?ge===De||N(ge,De,S,A,L):ce)){ie=!1;break}he||(he="constructor"==H)}if(ie&&!he){var lt=_.constructor,Ve=y.constructor;lt!=Ve&&"constructor"in _&&"constructor"in y&&!("function"==typeof lt&&lt instanceof lt&&"function"==typeof Ve&&Ve instanceof Ve)&&(ie=!1)}return L.delete(_),L.delete(y),ie}},10058:(v,T,i)=>{var r=i(94694),u=i(15529),p=i(39009);v.exports=function(e){return p(u(e,void 0,r),e+"")}},61138:v=>{var T="object"==typeof global&&global&&global.Object===Object&&global;v.exports=T},58605:(v,T,i)=>{var r=i(19215),u=i(10296),p=i(59108);v.exports=function(e){return r(e,p,u)}},51675:(v,T,i)=>{var r=i(19215),u=i(29572),p=i(42970);v.exports=function(e){return r(e,p,u)}},85556:(v,T,i)=>{var r=i(36586);v.exports=function(p,d){var e=p.__data__;return r(d)?e["string"==typeof d?"string":"hash"]:e.map}},48834:(v,T,i)=>{var r=i(45774),u=i(59108);v.exports=function(d){for(var e=u(d),_=e.length;_--;){var y=e[_],S=d[y];e[_]=[y,S,r(S)]}return e}},4153:(v,T,i)=>{var r=i(43540),u=i(36825);v.exports=function(d,e){var _=u(d,e);return r(_)?_:void 0}},52398:(v,T,i)=>{var u=i(93332)(Object.getPrototypeOf,Object);v.exports=u},21613:(v,T,i)=>{var r=i(57333),u=Object.prototype,p=u.hasOwnProperty,d=u.toString,e=r?r.toStringTag:void 0;v.exports=function(y){var S=p.call(y,e),A=y[e];try{y[e]=void 0;var N=!0}catch(Z){}var L=d.call(y);return N&&(S?y[e]=A:delete y[e]),L}},10296:(v,T,i)=>{var r=i(11375),u=i(65336),d=Object.prototype.propertyIsEnumerable,e=Object.getOwnPropertySymbols;v.exports=e?function(y){return null==y?[]:(y=Object(y),r(e(y),function(S){return d.call(y,S)}))}:u},29572:(v,T,i)=>{var r=i(94165),u=i(52398),p=i(10296),d=i(65336);v.exports=Object.getOwnPropertySymbols?function(y){for(var S=[];y;)r(S,p(y)),y=u(y);return S}:d},26663:(v,T,i)=>{var r=i(81235),u=i(39046),p=i(97129),d=i(74918),e=i(54203),_=i(72802),y=i(51217),S="[object Map]",N="[object Promise]",L="[object Set]",Z="[object WeakMap]",J="[object DataView]",K=y(r),ee=y(u),ue=y(p),ae=y(d),H=y(e),se=_;(r&&se(new r(new ArrayBuffer(1)))!=J||u&&se(new u)!=S||p&&se(p.resolve())!=N||d&&se(new d)!=L||e&&se(new e)!=Z)&&(se=function(Ee){var ie=_(Ee),he="[object Object]"==ie?Ee.constructor:void 0,ge=he?y(he):"";if(ge)switch(ge){case K:return J;case ee:return S;case ue:return N;case ae:return L;case H:return Z}return ie}),v.exports=se},36825:v=>{v.exports=function(i,r){return null==i?void 0:i[r]}},82138:(v,T,i)=>{var r=i(64667),u=i(2952),p=i(81690),d=i(20968),e=i(8613),_=i(82773);v.exports=function(S,A,N){for(var L=-1,Z=(A=r(A,S)).length,J=!1;++L<Z;){var K=_(A[L]);if(!(J=null!=S&&N(S,K)))break;S=S[K]}return J||++L!=Z?J:!!(Z=null==S?0:S.length)&&e(Z)&&d(K,Z)&&(p(S)||u(S))}},407:v=>{var _=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]");v.exports=function(S){return _.test(S)}},59316:v=>{var T=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;v.exports=function(r){return T.test(r)}},59410:(v,T,i)=>{var r=i(95969);v.exports=function(){this.__data__=r?r(null):{},this.size=0}},21143:v=>{v.exports=function(i){var r=this.has(i)&&delete this.__data__[i];return this.size-=r?1:0,r}},604:(v,T,i)=>{var r=i(95969),d=Object.prototype.hasOwnProperty;v.exports=function(_){var y=this.__data__;if(r){var S=y[_];return"__lodash_hash_undefined__"===S?void 0:S}return d.call(y,_)?y[_]:void 0}},80584:(v,T,i)=>{var r=i(95969),p=Object.prototype.hasOwnProperty;v.exports=function(e){var _=this.__data__;return r?void 0!==_[e]:p.call(_,e)}},7792:(v,T,i)=>{var r=i(95969);v.exports=function(d,e){var _=this.__data__;return this.size+=this.has(d)?0:1,_[d]=r&&void 0===e?"__lodash_hash_undefined__":e,this}},62963:v=>{var i=Object.prototype.hasOwnProperty;v.exports=function(u){var p=u.length,d=new u.constructor(p);return p&&"string"==typeof u[0]&&i.call(u,"index")&&(d.index=u.index,d.input=u.input),d}},32143:(v,T,i)=>{var r=i(88461),u=i(59757),p=i(83615),d=i(42282),e=i(96282);v.exports=function(lt,Ve,ze){var Be=lt.constructor;switch(Ve){case"[object ArrayBuffer]":return r(lt);case"[object Boolean]":case"[object Date]":return new Be(+lt);case"[object DataView]":return u(lt,ze);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return e(lt,ze);case"[object Map]":return new Be;case"[object Number]":case"[object String]":return new Be(lt);case"[object RegExp]":return p(lt);case"[object Set]":return new Be;case"[object Symbol]":return d(lt)}}},31563:(v,T,i)=>{var r=i(60920),u=i(52398),p=i(58845);v.exports=function(e){return"function"!=typeof e.constructor||p(e)?{}:r(u(e))}},21006:(v,T,i)=>{var r=i(57333),u=i(2952),p=i(81690),d=r?r.isConcatSpreadable:void 0;v.exports=function(_){return p(_)||u(_)||!!(d&&_&&_[d])}},20968:v=>{var i=/^(?:0|[1-9]\d*)$/;v.exports=function(u,p){var d=typeof u;return!!(p=null==p?9007199254740991:p)&&("number"==d||"symbol"!=d&&i.test(u))&&u>-1&&u%1==0&&u<p}},71100:(v,T,i)=>{var r=i(71166),u=i(93406),p=i(20968),d=i(53867);v.exports=function(_,y,S){if(!d(S))return!1;var A=typeof y;return!!("number"==A?u(S)&&p(y,S.length):"string"==A&&y in S)&&r(S[y],_)}},99743:(v,T,i)=>{var r=i(81690),u=i(7786),p=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,d=/^\w*$/;v.exports=function(_,y){if(r(_))return!1;var S=typeof _;return!("number"!=S&&"symbol"!=S&&"boolean"!=S&&null!=_&&!u(_))||d.test(_)||!p.test(_)||null!=y&&_ in Object(y)}},36586:v=>{v.exports=function(i){var r=typeof i;return"string"==r||"number"==r||"symbol"==r||"boolean"==r?"__proto__"!==i:null===i}},38466:(v,T,i)=>{var d,r=i(93412),u=(d=/[^.]+$/.exec(r&&r.keys&&r.keys.IE_PROTO||""))?"Symbol(src)_1."+d:"";v.exports=function(d){return!!u&&u in d}},58845:v=>{var T=Object.prototype;v.exports=function(r){var u=r&&r.constructor;return r===("function"==typeof u&&u.prototype||T)}},45774:(v,T,i)=>{var r=i(53867);v.exports=function(p){return p==p&&!r(p)}},63391:v=>{v.exports=function(){this.__data__=[],this.size=0}},68971:(v,T,i)=>{var r=i(15758),p=Array.prototype.splice;v.exports=function(e){var _=this.__data__,y=r(_,e);return!(y<0||(y==_.length-1?_.pop():p.call(_,y,1),--this.size,0))}},18858:(v,T,i)=>{var r=i(15758);v.exports=function(p){var d=this.__data__,e=r(d,p);return e<0?void 0:d[e][1]}},13913:(v,T,i)=>{var r=i(15758);v.exports=function(p){return r(this.__data__,p)>-1}},68944:(v,T,i)=>{var r=i(15758);v.exports=function(p,d){var e=this.__data__,_=r(e,p);return _<0?(++this.size,e.push([p,d])):e[_][1]=d,this}},70536:(v,T,i)=>{var r=i(41505),u=i(73545),p=i(39046);v.exports=function(){this.size=0,this.__data__={hash:new r,map:new(p||u),string:new r}}},61502:(v,T,i)=>{var r=i(85556);v.exports=function(p){var d=r(this,p).delete(p);return this.size-=d?1:0,d}},94960:(v,T,i)=>{var r=i(85556);v.exports=function(p){return r(this,p).get(p)}},61539:(v,T,i)=>{var r=i(85556);v.exports=function(p){return r(this,p).has(p)}},34138:(v,T,i)=>{var r=i(85556);v.exports=function(p,d){var e=r(this,p),_=e.size;return e.set(p,d),this.size+=e.size==_?0:1,this}},37461:v=>{v.exports=function(i){var r=-1,u=Array(i.size);return i.forEach(function(p,d){u[++r]=[d,p]}),u}},63587:v=>{v.exports=function(i,r){return function(u){return null!=u&&u[i]===r&&(void 0!==r||i in Object(u))}}},43911:(v,T,i)=>{var r=i(97425);v.exports=function(d){var e=r(d,function(y){return 500===_.size&&_.clear(),y}),_=e.cache;return e}},95969:(v,T,i)=>{var u=i(4153)(Object,"create");v.exports=u},36700:(v,T,i)=>{var u=i(93332)(Object.keys,Object);v.exports=u},25618:v=>{v.exports=function(i){var r=[];if(null!=i)for(var u in Object(i))r.push(u);return r}},70938:(v,T,i)=>{v=i.nmd(v);var r=i(61138),u=T&&!T.nodeType&&T,p=u&&v&&!v.nodeType&&v,e=p&&p.exports===u&&r.process,_=function(){try{return p&&p.require&&p.require("util").types||e&&e.binding&&e.binding("util")}catch(S){}}();v.exports=_},81244:v=>{var i=Object.prototype.toString;v.exports=function(u){return i.call(u)}},93332:v=>{v.exports=function(i,r){return function(u){return i(r(u))}}},15529:(v,T,i)=>{var r=i(81638),u=Math.max;v.exports=function(d,e,_){return e=u(void 0===e?d.length-1:e,0),function(){for(var y=arguments,S=-1,A=u(y.length-e,0),N=Array(A);++S<A;)N[S]=y[e+S];S=-1;for(var L=Array(e+1);++S<e;)L[S]=y[S];return L[e]=_(N),r(d,this,L)}}},61746:(v,T,i)=>{var r=i(93436),u=i(63586);v.exports=function(d,e){return e.length<2?d:r(d,u(e,0,-1))}},27038:(v,T,i)=>{var r=i(61138),u="object"==typeof self&&self&&self.Object===Object&&self,p=r||u||Function("return this")();v.exports=p},45959:v=>{v.exports=function(i,r){if(("constructor"!==r||"function"!=typeof i[r])&&"__proto__"!=r)return i[r]}},30365:v=>{v.exports=function(r){return this.__data__.set(r,"__lodash_hash_undefined__"),this}},58235:v=>{v.exports=function(i){return this.__data__.has(i)}},57673:v=>{v.exports=function(i){var r=-1,u=Array(i.size);return i.forEach(function(p){u[++r]=p}),u}},39009:(v,T,i)=>{var r=i(99372),p=i(44094)(r);v.exports=p},44094:v=>{var r=Date.now;v.exports=function(p){var d=0,e=0;return function(){var _=r(),y=16-(_-e);if(e=_,y>0){if(++d>=800)return arguments[0]}else d=0;return p.apply(void 0,arguments)}}},18034:(v,T,i)=>{var r=i(73545);v.exports=function(){this.__data__=new r,this.size=0}},37238:v=>{v.exports=function(i){var r=this.__data__,u=r.delete(i);return this.size=r.size,u}},75887:v=>{v.exports=function(i){return this.__data__.get(i)}},81450:v=>{v.exports=function(i){return this.__data__.has(i)}},61386:(v,T,i)=>{var r=i(73545),u=i(39046),p=i(93177);v.exports=function(_,y){var S=this.__data__;if(S instanceof r){var A=S.__data__;if(!u||A.length<199)return A.push([_,y]),this.size=++S.size,this;S=this.__data__=new p(A)}return S.set(_,y),this.size=S.size,this}},2150:(v,T,i)=>{var r=i(87280),u=i(407),p=i(1879);v.exports=function(e){return u(e)?p(e):r(e)}},89775:(v,T,i)=>{var r=i(43911),u=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,p=/\\(\\)?/g,d=r(function(e){var _=[];return 46===e.charCodeAt(0)&&_.push(""),e.replace(u,function(y,S,A,N){_.push(A?N.replace(p,"$1"):S||y)}),_});v.exports=d},82773:(v,T,i)=>{var r=i(7786);v.exports=function(d){if("string"==typeof d||r(d))return d;var e=d+"";return"0"==e&&1/d==-1/0?"-0":e}},51217:v=>{var i=Function.prototype.toString;v.exports=function(u){if(null!=u){try{return i.call(u)}catch(p){}try{return u+""}catch(p){}}return""}},87478:v=>{var T=/\s/;v.exports=function(r){for(var u=r.length;u--&&T.test(r.charAt(u)););return u}},1879:v=>{var T="\\ud800-\\udfff",e="["+T+"]",_="[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]",y="\\ud83c[\\udffb-\\udfff]",A="[^"+T+"]",N="(?:\\ud83c[\\udde6-\\uddff]){2}",L="[\\ud800-\\udbff][\\udc00-\\udfff]",J="(?:"+_+"|"+y+")?",K="[\\ufe0e\\ufe0f]?",ue=K+J+"(?:\\u200d(?:"+[A,N,L].join("|")+")"+K+J+")*",ae="(?:"+[A+_+"?",_,N,L,e].join("|")+")",H=RegExp(y+"(?="+y+")|"+ae+ue,"g");v.exports=function(Ee){return Ee.match(H)||[]}},58863:v=>{var T="\\ud800-\\udfff",d="\\u2700-\\u27bf",e="a-z\\xdf-\\xf6\\xf8-\\xff",N="A-Z\\xc0-\\xd6\\xd8-\\xde",Z="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",K="["+Z+"]",ue="\\d+",ae="["+d+"]",H="["+e+"]",se="[^"+T+Z+ue+d+e+N+"]",ge="(?:\\ud83c[\\udde6-\\uddff]){2}",De="[\\ud800-\\udbff][\\udc00-\\udfff]",ce="["+N+"]",Ve="(?:"+H+"|"+se+")",ze="(?:"+ce+"|"+se+")",Be="(?:['\u2019](?:d|ll|m|re|s|t|ve))?",Pe="(?:['\u2019](?:D|LL|M|RE|S|T|VE))?",je="(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?",He="[\\ufe0e\\ufe0f]?",It=He+je+"(?:\\u200d(?:"+["[^"+T+"]",ge,De].join("|")+")"+He+je+")*",Zt="(?:"+[ae,ge,De].join("|")+")"+It,Ut=RegExp([ce+"?"+H+"+"+Be+"(?="+[K,ce,"$"].join("|")+")",ze+"+"+Pe+"(?="+[K,ce+Ve,"$"].join("|")+")",ce+"?"+Ve+"+"+Be,ce+"+"+Pe,"\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",ue,Zt].join("|"),"g");v.exports=function(bt){return bt.match(Ut)||[]}},35037:(v,T,i)=>{var r=i(76974),p=i(17407)(function(d,e,_){return e=e.toLowerCase(),d+(_?r(e):e)});v.exports=p},76974:(v,T,i)=>{var r=i(41233),u=i(93890);v.exports=function(d){return u(r(d).toLowerCase())}},45654:v=>{v.exports=function(i){return function(){return i}}},41776:(v,T,i)=>{var r=i(53867),u=i(30765),p=i(45038),e=Math.max,_=Math.min;v.exports=function(S,A,N){var L,Z,J,K,ee,ue,ae=0,H=!1,se=!1,Ee=!0;if("function"!=typeof S)throw new TypeError("Expected a function");function ie(Pe){var je=L,He=Z;return L=Z=void 0,ae=Pe,K=S.apply(He,je)}function he(Pe){return ae=Pe,ee=setTimeout(ce,A),H?ie(Pe):K}function De(Pe){var je=Pe-ue;return void 0===ue||je>=A||je<0||se&&Pe-ae>=J}function ce(){var Pe=u();if(De(Pe))return lt(Pe);ee=setTimeout(ce,function(Pe){var Vt=A-(Pe-ue);return se?_(Vt,J-(Pe-ae)):Vt}(Pe))}function lt(Pe){return ee=void 0,Ee&&L?ie(Pe):(L=Z=void 0,K)}function Be(){var Pe=u(),je=De(Pe);if(L=arguments,Z=this,ue=Pe,je){if(void 0===ee)return he(ue);if(se)return clearTimeout(ee),ee=setTimeout(ce,A),ie(ue)}return void 0===ee&&(ee=setTimeout(ce,A)),K}return A=p(A)||0,r(N)&&(H=!!N.leading,J=(se="maxWait"in N)?e(p(N.maxWait)||0,A):J,Ee="trailing"in N?!!N.trailing:Ee),Be.cancel=function(){void 0!==ee&&clearTimeout(ee),ae=0,L=ue=Z=ee=void 0},Be.flush=function(){return void 0===ee?K:lt(u())},Be}},75289:(v,T,i)=>{var r=i(4068),u=i(41233),p=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,A=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g");v.exports=function(L){return(L=u(L))&&L.replace(p,r).replace(A,"")}},71166:v=>{v.exports=function(i,r){return i===r||i!=i&&r!=r}},98990:(v,T,i)=>{var p=i(44674)(i(84857));v.exports=p},84857:(v,T,i)=>{var r=i(12229),u=i(5245),p=i(32781),d=Math.max;v.exports=function(_,y,S){var A=null==_?0:_.length;if(!A)return-1;var N=null==S?0:p(S);return N<0&&(N=d(A+N,0)),r(_,u(y,3),N)}},94694:(v,T,i)=>{var r=i(56369);v.exports=function(p){return null!=p&&p.length?r(p,1):[]}},58102:(v,T,i)=>{var r=i(93436);v.exports=function(p,d,e){var _=null==p?void 0:r(p,d);return void 0===_?e:_}},18303:(v,T,i)=>{var r=i(55333),u=i(82138);v.exports=function(d,e){return null!=d&&u(d,e,r)}},80290:v=>{v.exports=function(i){return i}},2952:(v,T,i)=>{var r=i(77090),u=i(27503),p=Object.prototype,d=p.hasOwnProperty,e=p.propertyIsEnumerable,_=r(function(){return arguments}())?r:function(y){return u(y)&&d.call(y,"callee")&&!e.call(y,"callee")};v.exports=_},81690:v=>{v.exports=Array.isArray},93406:(v,T,i)=>{var r=i(55836),u=i(8613);v.exports=function(d){return null!=d&&u(d.length)&&!r(d)}},82027:(v,T,i)=>{var r=i(93406),u=i(27503);v.exports=function(d){return u(d)&&r(d)}},84444:(v,T,i)=>{v=i.nmd(v);var r=i(27038),u=i(61711),p=T&&!T.nodeType&&T,d=p&&v&&!v.nodeType&&v,_=d&&d.exports===p?r.Buffer:void 0;v.exports=(_?_.isBuffer:void 0)||u},12232:(v,T,i)=>{var r=i(92488),u=i(26663),p=i(2952),d=i(81690),e=i(93406),_=i(84444),y=i(58845),S=i(47679),Z=Object.prototype.hasOwnProperty;v.exports=function(K){if(null==K)return!0;if(e(K)&&(d(K)||"string"==typeof K||"function"==typeof K.splice||_(K)||S(K)||p(K)))return!K.length;var ee=u(K);if("[object Map]"==ee||"[object Set]"==ee)return!K.size;if(y(K))return!r(K).length;for(var ue in K)if(Z.call(K,ue))return!1;return!0}},55836:(v,T,i)=>{var r=i(72802),u=i(53867);v.exports=function(S){if(!u(S))return!1;var A=r(S);return"[object Function]"==A||"[object GeneratorFunction]"==A||"[object AsyncFunction]"==A||"[object Proxy]"==A}},8613:v=>{v.exports=function(r){return"number"==typeof r&&r>-1&&r%1==0&&r<=9007199254740991}},32e3:(v,T,i)=>{var r=i(63434),u=i(70544),p=i(70938),d=p&&p.isMap,e=d?u(d):r;v.exports=e},53867:v=>{v.exports=function(i){var r=typeof i;return null!=i&&("object"==r||"function"==r)}},27503:v=>{v.exports=function(i){return null!=i&&"object"==typeof i}},82358:(v,T,i)=>{var r=i(72802),u=i(52398),p=i(27503),y=Function.prototype.toString,S=Object.prototype.hasOwnProperty,A=y.call(Object);v.exports=function(L){if(!p(L)||"[object Object]"!=r(L))return!1;var Z=u(L);if(null===Z)return!0;var J=S.call(Z,"constructor")&&Z.constructor;return"function"==typeof J&&J instanceof J&&y.call(J)==A}},48855:(v,T,i)=>{var r=i(67495),u=i(70544),p=i(70938),d=p&&p.isSet,e=d?u(d):r;v.exports=e},64871:(v,T,i)=>{var r=i(72802),u=i(81690),p=i(27503);v.exports=function(_){return"string"==typeof _||!u(_)&&p(_)&&"[object String]"==r(_)}},7786:(v,T,i)=>{var r=i(72802),u=i(27503);v.exports=function(e){return"symbol"==typeof e||u(e)&&"[object Symbol]"==r(e)}},47679:(v,T,i)=>{var r=i(99390),u=i(70544),p=i(70938),d=p&&p.isTypedArray,e=d?u(d):r;v.exports=e},59108:(v,T,i)=>{var r=i(71890),u=i(92488),p=i(93406);v.exports=function(e){return p(e)?r(e):u(e)}},42970:(v,T,i)=>{var r=i(71890),u=i(50762),p=i(93406);v.exports=function(e){return p(e)?r(e,!0):u(e)}},27842:v=>{v.exports=function(i){var r=null==i?0:i.length;return r?i[r-1]:void 0}},23815:function(v,T,i){var r;v=i.nmd(v),function(){var u,_="Expected a function",S="__lodash_hash_undefined__",N="__lodash_placeholder__",Vt=1/0,it=9007199254740991,Zt=4294967295,bt=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]],Gt="[object Arguments]",xt="[object Array]",Zn="[object Boolean]",Ur="[object Date]",Lr="[object Error]",Mr="[object Function]",Kr="[object GeneratorFunction]",ei="[object Map]",Nn="[object Number]",Br="[object Object]",Yr="[object Promise]",ki="[object RegExp]",Hi="[object Set]",Zr="[object String]",Cn="[object Symbol]",zn="[object WeakMap]",Fr="[object ArrayBuffer]",Gn="[object DataView]",Jr="[object Float32Array]",_i="[object Float64Array]",wi="[object Int8Array]",br="[object Int16Array]",Dr="[object Int32Array]",gn="[object Uint8Array]",yn="[object Uint8ClampedArray]",gr="[object Uint16Array]",Jt="[object Uint32Array]",Vn=/\b__p \+= '';/g,mr=/\b(__p \+=) '' \+/g,Dn=/(__e\(.*?\)|\b__t\)) \+\n'';/g,Pr=/&(?:amp|lt|gt|quot|#39);/g,Yt=/[&<>"']/g,_n=RegExp(Pr.source),Ge=RegExp(Yt.source),kr=/<%-([\s\S]+?)%>/g,mi=/<%([\s\S]+?)%>/g,An=/<%=([\s\S]+?)%>/g,Er=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Wr=/^\w*$/,dr=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,Fn=/[\\^$.*+?()[\]{}|]/g,ar=RegExp(Fn.source),Wi=/^\s+/,lo=/\s/,vo=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,Co=/\{\n\/\* \[wrapped with (.+)\] \*/,Gi=/,? & /,os=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,jo=/[()=,{}\[\]\/\s]/,To=/\\(\\)?/g,Mi=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,li=/\w*$/,Bn=/^[-+]0x[0-9a-f]+$/i,lr=/^0b[01]+$/i,vr=/^\[object .+?Constructor\]$/,er=/^0o[0-7]+$/i,ri=/^(?:0|[1-9]\d*)$/,uo=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,Ci=/($^)/,$o=/['\n\r\u2028\u2029\\]/g,tr="\\ud800-\\udfff",mt="\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff",jt="\\u2700-\\u27bf",on="a-z\\xdf-\\xf6\\xf8-\\xff",Es="A-Z\\xc0-\\xd6\\xd8-\\xde",Zs="\\ufe0e\\ufe0f",ls="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",ta="["+tr+"]",Is="["+ls+"]",us="["+mt+"]",ya="\\d+",el="["+jt+"]",ca="["+on+"]",$s="[^"+tr+ls+ya+jt+on+Es+"]",da="\\ud83c[\\udffb-\\udfff]",fo="[^"+tr+"]",Ya="(?:\\ud83c[\\udde6-\\uddff]){2}",Ao="[\\ud800-\\udbff][\\udc00-\\udfff]",fs="["+Es+"]",Ra="(?:"+ca+"|"+$s+")",pl="(?:"+fs+"|"+$s+")",Ws="(?:['\u2019](?:d|ll|m|re|s|t|ve))?",Po="(?:['\u2019](?:D|LL|M|RE|S|T|VE))?",bo="(?:"+us+"|"+da+")?",Ls="["+Zs+"]?",to=Ls+bo+"(?:\\u200d(?:"+[fo,Ya,Ao].join("|")+")"+Ls+bo+")*",tt="(?:"+[el,Ya,Ao].join("|")+")"+to,sn="(?:"+[fo+us+"?",us,Ya,Ao,ta].join("|")+")",ne=RegExp("['\u2019]","g"),$e=RegExp(us,"g"),Lt=RegExp(da+"(?="+da+")|"+sn+to,"g"),an=RegExp([fs+"?"+ca+"+"+Ws+"(?="+[Is,fs,"$"].join("|")+")",pl+"+"+Po+"(?="+[Is,fs+Ra,"$"].join("|")+")",fs+"?"+Ra+"+"+Ws,fs+"+"+Po,"\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",ya,tt].join("|"),"g"),ti=RegExp("[\\u200d"+tr+mt+Zs+"]"),pi=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,xi=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],ts=-1,wo={};wo[Jr]=wo[_i]=wo[wi]=wo[br]=wo[Dr]=wo[gn]=wo[yn]=wo[gr]=wo[Jt]=!0,wo[Gt]=wo[xt]=wo[Fr]=wo[Zn]=wo[Gn]=wo[Ur]=wo[Lr]=wo[Mr]=wo[ei]=wo[Nn]=wo[Br]=wo[ki]=wo[Hi]=wo[Zr]=wo[zn]=!1;var ko={};ko[Gt]=ko[xt]=ko[Fr]=ko[Gn]=ko[Zn]=ko[Ur]=ko[Jr]=ko[_i]=ko[wi]=ko[br]=ko[Dr]=ko[ei]=ko[Nn]=ko[Br]=ko[ki]=ko[Hi]=ko[Zr]=ko[Cn]=ko[gn]=ko[yn]=ko[gr]=ko[Jt]=!0,ko[Lr]=ko[Mr]=ko[zn]=!1;var tc={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Nu=parseFloat,bc=parseInt,Ec="object"==typeof global&&global&&global.Object===Object&&global,qc="object"==typeof self&&self&&self.Object===Object&&self,Hl=Ec||qc||Function("return this")(),Yl=T&&!T.nodeType&&T,Fs=Yl&&v&&!v.nodeType&&v,dc=Fs&&Fs.exports===Yl,iu=dc&&Ec.process,tl=function(){try{return Fs&&Fs.require&&Fs.require("util").types||iu&&iu.binding&&iu.binding("util")}catch(Cr){}}(),Su=tl&&tl.isArrayBuffer,Zl=tl&&tl.isDate,rt=tl&&tl.isMap,Pt=tl&&tl.isRegExp,dt=tl&&tl.isSet,Te=tl&&tl.isTypedArray;function Me(In,Cr,hr){switch(hr.length){case 0:return In.call(Cr);case 1:return In.call(Cr,hr[0]);case 2:return In.call(Cr,hr[0],hr[1]);case 3:return In.call(Cr,hr[0],hr[1],hr[2])}return In.apply(Cr,hr)}function xe(In,Cr,hr,ao){for(var ys=-1,Na=null==In?0:In.length;++ys<Na;){var Tl=In[ys];Cr(ao,Tl,hr(Tl),In)}return ao}function Ct(In,Cr){for(var hr=-1,ao=null==In?0:In.length;++hr<ao&&!1!==Cr(In[hr],hr,In););return In}function ur(In,Cr){for(var hr=null==In?0:In.length;hr--&&!1!==Cr(In[hr],hr,In););return In}function Qi(In,Cr){for(var hr=-1,ao=null==In?0:In.length;++hr<ao;)if(!Cr(In[hr],hr,In))return!1;return!0}function Go(In,Cr){for(var hr=-1,ao=null==In?0:In.length,ys=0,Na=[];++hr<ao;){var Tl=In[hr];Cr(Tl,hr,In)&&(Na[ys++]=Tl)}return Na}function ms(In,Cr){return!(null==In||!In.length)&&Fc(In,Cr,0)>-1}function hs(In,Cr,hr){for(var ao=-1,ys=null==In?0:In.length;++ao<ys;)if(hr(Cr,In[ao]))return!0;return!1}function Ts(In,Cr){for(var hr=-1,ao=null==In?0:In.length,ys=Array(ao);++hr<ao;)ys[hr]=Cr(In[hr],hr,In);return ys}function Ma(In,Cr){for(var hr=-1,ao=Cr.length,ys=In.length;++hr<ao;)In[ys+hr]=Cr[hr];return In}function au(In,Cr,hr,ao){var ys=-1,Na=null==In?0:In.length;for(ao&&Na&&(hr=In[++ys]);++ys<Na;)hr=Cr(hr,In[ys],ys,In);return hr}function Wa(In,Cr,hr,ao){var ys=null==In?0:In.length;for(ao&&ys&&(hr=In[--ys]);ys--;)hr=Cr(hr,In[ys],ys,In);return hr}function Rl(In,Cr){for(var hr=-1,ao=null==In?0:In.length;++hr<ao;)if(Cr(In[hr],hr,In))return!0;return!1}var nc=rc("length");function Lc(In,Cr,hr){var ao;return hr(In,function(ys,Na,Tl){if(Cr(ys,Na,Tl))return ao=Na,!1}),ao}function Tc(In,Cr,hr,ao){for(var ys=In.length,Na=hr+(ao?1:-1);ao?Na--:++Na<ys;)if(Cr(In[Na],Na,In))return Na;return-1}function Fc(In,Cr,hr){return Cr==Cr?function(In,Cr,hr){for(var ao=hr-1,ys=In.length;++ao<ys;)if(In[ao]===Cr)return ao;return-1}(In,Cr,hr):Tc(In,kc,hr)}function Cu(In,Cr,hr,ao){for(var ys=hr-1,Na=In.length;++ys<Na;)if(ao(In[ys],Cr))return ys;return-1}function kc(In){return In!=In}function gd(In,Cr){var hr=null==In?0:In.length;return hr?Ss(In,Cr)/hr:NaN}function rc(In){return function(Cr){return null==Cr?u:Cr[In]}}function Li(In){return function(Cr){return null==In?u:In[Cr]}}function sa(In,Cr,hr,ao,ys){return ys(In,function(Na,Tl,Qs){hr=ao?(ao=!1,Na):Cr(hr,Na,Tl,Qs)}),hr}function Ss(In,Cr){for(var hr,ao=-1,ys=In.length;++ao<ys;){var Na=Cr(In[ao]);Na!==u&&(hr=hr===u?Na:hr+Na)}return hr}function $u(In,Cr){for(var hr=-1,ao=Array(In);++hr<In;)ao[hr]=Cr(hr);return ao}function Mu(In){return In&&In.slice(0,mn(In)+1).replace(Wi,"")}function yu(In){return function(Cr){return In(Cr)}}function lu(In,Cr){return Ts(Cr,function(hr){return In[hr]})}function js(In,Cr){return In.has(Cr)}function Hu(In,Cr){for(var hr=-1,ao=In.length;++hr<ao&&Fc(Cr,In[hr],0)>-1;);return hr}function Uu(In,Cr){for(var hr=In.length;hr--&&Fc(Cr,In[hr],0)>-1;);return hr}function Bo(In,Cr){for(var hr=In.length,ao=0;hr--;)In[hr]===Cr&&++ao;return ao}var uu=Li({\u00c0:"A",\u00c1:"A",\u00c2:"A",\u00c3:"A",\u00c4:"A",\u00c5:"A",\u00e0:"a",\u00e1:"a",\u00e2:"a",\u00e3:"a",\u00e4:"a",\u00e5:"a",\u00c7:"C",\u00e7:"c",\u00d0:"D",\u00f0:"d",\u00c8:"E",\u00c9:"E",\u00ca:"E",\u00cb:"E",\u00e8:"e",\u00e9:"e",\u00ea:"e",\u00eb:"e",\u00cc:"I",\u00cd:"I",\u00ce:"I",\u00cf:"I",\u00ec:"i",\u00ed:"i",\u00ee:"i",\u00ef:"i",\u00d1:"N",\u00f1:"n",\u00d2:"O",\u00d3:"O",\u00d4:"O",\u00d5:"O",\u00d6:"O",\u00d8:"O",\u00f2:"o",\u00f3:"o",\u00f4:"o",\u00f5:"o",\u00f6:"o",\u00f8:"o",\u00d9:"U",\u00da:"U",\u00db:"U",\u00dc:"U",\u00f9:"u",\u00fa:"u",\u00fb:"u",\u00fc:"u",\u00dd:"Y",\u00fd:"y",\u00ff:"y",\u00c6:"Ae",\u00e6:"ae",\u00de:"Th",\u00fe:"th",\u00df:"ss",\u0100:"A",\u0102:"A",\u0104:"A",\u0101:"a",\u0103:"a",\u0105:"a",\u0106:"C",\u0108:"C",\u010a:"C",\u010c:"C",\u0107:"c",\u0109:"c",\u010b:"c",\u010d:"c",\u010e:"D",\u0110:"D",\u010f:"d",\u0111:"d",\u0112:"E",\u0114:"E",\u0116:"E",\u0118:"E",\u011a:"E",\u0113:"e",\u0115:"e",\u0117:"e",\u0119:"e",\u011b:"e",\u011c:"G",\u011e:"G",\u0120:"G",\u0122:"G",\u011d:"g",\u011f:"g",\u0121:"g",\u0123:"g",\u0124:"H",\u0126:"H",\u0125:"h",\u0127:"h",\u0128:"I",\u012a:"I",\u012c:"I",\u012e:"I",\u0130:"I",\u0129:"i",\u012b:"i",\u012d:"i",\u012f:"i",\u0131:"i",\u0134:"J",\u0135:"j",\u0136:"K",\u0137:"k",\u0138:"k",\u0139:"L",\u013b:"L",\u013d:"L",\u013f:"L",\u0141:"L",\u013a:"l",\u013c:"l",\u013e:"l",\u0140:"l",\u0142:"l",\u0143:"N",\u0145:"N",\u0147:"N",\u014a:"N",\u0144:"n",\u0146:"n",\u0148:"n",\u014b:"n",\u014c:"O",\u014e:"O",\u0150:"O",\u014d:"o",\u014f:"o",\u0151:"o",\u0154:"R",\u0156:"R",\u0158:"R",\u0155:"r",\u0157:"r",\u0159:"r",\u015a:"S",\u015c:"S",\u015e:"S",\u0160:"S",\u015b:"s",\u015d:"s",\u015f:"s",\u0161:"s",\u0162:"T",\u0164:"T",\u0166:"T",\u0163:"t",\u0165:"t",\u0167:"t",\u0168:"U",\u016a:"U",\u016c:"U",\u016e:"U",\u0170:"U",\u0172:"U",\u0169:"u",\u016b:"u",\u016d:"u",\u016f:"u",\u0171:"u",\u0173:"u",\u0174:"W",\u0175:"w",\u0176:"Y",\u0177:"y",\u0178:"Y",\u0179:"Z",\u017b:"Z",\u017d:"Z",\u017a:"z",\u017c:"z",\u017e:"z",\u0132:"IJ",\u0133:"ij",\u0152:"Oe",\u0153:"oe",\u0149:"'n",\u017f:"s"}),wr=Li({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"});function fa(In){return"\\"+tc[In]}function aa(In){return ti.test(In)}function El(In){var Cr=-1,hr=Array(In.size);return In.forEach(function(ao,ys){hr[++Cr]=[ys,ao]}),hr}function Ul(In,Cr){return function(hr){return In(Cr(hr))}}function ks(In,Cr){for(var hr=-1,ao=In.length,ys=0,Na=[];++hr<ao;){var Tl=In[hr];(Tl===Cr||Tl===N)&&(In[hr]=N,Na[ys++]=hr)}return Na}function V(In){var Cr=-1,hr=Array(In.size);return In.forEach(function(ao){hr[++Cr]=ao}),hr}function ut(In){return aa(In)?function(In){for(var Cr=Lt.lastIndex=0;Lt.test(In);)++Cr;return Cr}(In):nc(In)}function un(In){return aa(In)?function(In){return In.match(Lt)||[]}(In):function(In){return In.split("")}(In)}function mn(In){for(var Cr=In.length;Cr--&&lo.test(In.charAt(Cr)););return Cr}var Or=Li({"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"}),Fo=function In(Cr){var O,hr=(Cr=null==Cr?Hl:Fo.defaults(Hl.Object(),Cr,Fo.pick(Hl,xi))).Array,ao=Cr.Date,ys=Cr.Error,Na=Cr.Function,Tl=Cr.Math,Qs=Cr.Object,ed=Cr.RegExp,$c=Cr.String,Gl=Cr.TypeError,$i=hr.prototype,pa=Qs.prototype,hl=Cr["__core-js_shared__"],Bl=Na.prototype.toString,Js=pa.hasOwnProperty,md=0,Mn=(O=/[^.]+$/.exec(hl&&hl.keys&&hl.keys.IE_PROTO||""))?"Symbol(src)_1."+O:"",Nl=pa.toString,td=Bl.call(Qs),zd=Hl._,ss=ed("^"+Bl.call(Js).replace(Fn,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),la=dc?Cr.Buffer:u,Zc=Cr.Symbol,ic=Cr.Uint8Array,df=la?la.allocUnsafe:u,al=Ul(Qs.getPrototypeOf,Qs),Wd=Qs.create,Jd=pa.propertyIsEnumerable,Ye=$i.splice,Ie=Zc?Zc.isConcatSpreadable:u,Ce=Zc?Zc.iterator:u,ot=Zc?Zc.toStringTag:u,Et=function(){try{var O=Zu(Qs,"defineProperty");return O({},"",{}),O}catch($){}}(),qt=Cr.clearTimeout!==Hl.clearTimeout&&Cr.clearTimeout,Hn=ao&&ao.now!==Hl.Date.now&&ao.now,Xn=Cr.setTimeout!==Hl.setTimeout&&Cr.setTimeout,Ei=Tl.ceil,Yo=Tl.floor,$a=Qs.getOwnPropertySymbols,ns=la?la.isBuffer:u,Oa=Cr.isFinite,Hs=$i.join,fc=Ul(Qs.keys,Qs),ga=Tl.max,Ol=Tl.min,ll=ao.now,Za=Cr.parseInt,ja=Tl.random,ul=$i.reverse,Of=Zu(Cr,"DataView"),Rd=Zu(Cr,"Map"),Qd=Zu(Cr,"Promise"),Sc=Zu(Cr,"Set"),Wu=Zu(Cr,"WeakMap"),Cc=Zu(Qs,"create"),Xd=Wu&&new Wu,jc={},$f=Rf(Of),Ju=Rf(Rd),Sl=Rf(Qd),wl=Rf(Sc),kl=Rf(Wu),Pu=Zc?Zc.prototype:u,Ja=Pu?Pu.valueOf:u,Qu=Pu?Pu.toString:u;function en(O){if(Ic(O)&&!ui(O)&&!(O instanceof nl)){if(O instanceof Iu)return O;if(Js.call(O,"__wrapped__"))return _g(O)}return new Iu(O)}var Oc=function(){function O(){}return function($){if(!ju($))return{};if(Wd)return Wd($);O.prototype=$;var pe=new O;return O.prototype=u,pe}}();function Au(){}function Iu(O,$){this.__wrapped__=O,this.__actions__=[],this.__chain__=!!$,this.__index__=0,this.__values__=u}function nl(O){this.__wrapped__=O,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=Zt,this.__views__=[]}function wc(O){var $=-1,pe=null==O?0:O.length;for(this.clear();++$<pe;){var Ke=O[$];this.set(Ke[0],Ke[1])}}function hu(O){var $=-1,pe=null==O?0:O.length;for(this.clear();++$<pe;){var Ke=O[$];this.set(Ke[0],Ke[1])}}function Ql(O){var $=-1,pe=null==O?0:O.length;for(this.clear();++$<pe;){var Ke=O[$];this.set(Ke[0],Ke[1])}}function Xl(O){var $=-1,pe=null==O?0:O.length;for(this.__data__=new Ql;++$<pe;)this.add(O[$])}function Ll(O){var $=this.__data__=new hu(O);this.size=$.size}function wf(O,$){var pe=ui(O),Ke=!pe&&fr(O),Ht=!pe&&!Ke&&ql(O),pn=!pe&&!Ke&&!Ht&&Nm(O),Kn=pe||Ke||Ht||pn,Sr=Kn?$u(O.length,$c):[],qr=Sr.length;for(var no in O)($||Js.call(O,no))&&(!Kn||!("length"==no||Ht&&("offset"==no||"parent"==no)||pn&&("buffer"==no||"byteLength"==no||"byteOffset"==no)||id(no,qr)))&&Sr.push(no);return Sr}function Vl(O){var $=O.length;return $?O[dd(0,$-1)]:u}function Id(O,$){return fh(vi(O),bu($,0,O.length))}function oc(O){return fh(vi(O))}function hc(O,$,pe){(pe!==u&&!at(O[$],pe)||pe===u&&!($ in O))&&Ou(O,$,pe)}function _u(O,$,pe){var Ke=O[$];(!Js.call(O,$)||!at(Ke,pe)||pe===u&&!($ in O))&&Ou(O,$,pe)}function Mc(O,$){for(var pe=O.length;pe--;)if(at(O[pe][0],$))return pe;return-1}function Hc(O,$,pe,Ke){return de(O,function(Ht,pn,Kn){$(Ke,Ht,pe(Ht),Kn)}),Ke}function cu(O,$){return O&&zi($,Md($),O)}function Ou(O,$,pe){"__proto__"==$&&Et?Et(O,$,{configurable:!0,enumerable:!0,value:pe,writable:!0}):O[$]=pe}function Rc(O,$){for(var pe=-1,Ke=$.length,Ht=hr(Ke),pn=null==O;++pe<Ke;)Ht[pe]=pn?u:_1(O,$[pe]);return Ht}function bu(O,$,pe){return O==O&&(pe!==u&&(O=O<=pe?O:pe),$!==u&&(O=O>=$?O:$)),O}function h(O,$,pe,Ke,Ht,pn){var Kn,Sr=1&$,qr=2&$,no=4&$;if(pe&&(Kn=Ht?pe(O,Ke,Ht,pn):pe(O)),Kn!==u)return Kn;if(!ju(O))return O;var ro=ui(O);if(ro){if(Kn=function(O){var $=O.length,pe=new O.constructor($);return $&&"string"==typeof O[0]&&Js.call(O,"index")&&(pe.index=O.index,pe.input=O.input),pe}(O),!Sr)return vi(O,Kn)}else{var mo=Pc(O),ds=mo==Mr||mo==Kr;if(ql(O))return k_(O,Sr);if(mo==Br||mo==Gt||ds&&!Ht){if(Kn=qr||ds?{}:tp(O),!Sr)return qr?function(O,$){return zi(O,Gf(O),$)}(O,function(O,$){return O&&zi($,sd($),O)}(Kn,O)):function(O,$){return zi(O,Yp(O),$)}(O,cu(Kn,O))}else{if(!ko[mo])return Ht?O:{};Kn=function(O,$,pe){var Ke=O.constructor;switch($){case Fr:return o_(O);case Zn:case Ur:return new Ke(+O);case Gn:return function(O,$){var pe=$?o_(O.buffer):O.buffer;return new O.constructor(pe,O.byteOffset,O.byteLength)}(O,pe);case Jr:case _i:case wi:case br:case Dr:case gn:case yn:case gr:case Jt:return X(O,pe);case ei:return new Ke;case Nn:case Zr:return new Ke(O);case ki:return function(O){var $=new O.constructor(O.source,li.exec(O));return $.lastIndex=O.lastIndex,$}(O);case Hi:return new Ke;case Cn:return function(O){return Ja?Qs(Ja.call(O)):{}}(O)}}(O,mo,Sr)}}pn||(pn=new Ll);var oa=pn.get(O);if(oa)return oa;pn.set(O,Kn),f1(O)?O.forEach(function(Va){Kn.add(h(Va,$,pe,Va,O,pn))}):D0(O)&&O.forEach(function(Va,su){Kn.set(su,h(Va,$,pe,su,O,pn))});var Pl=ro?u:(no?qr?d_:c_:qr?sd:Md)(O);return Ct(Pl||O,function(Va,su){Pl&&(Va=O[su=Va]),_u(Kn,su,h(Va,$,pe,su,O,pn))}),Kn}function R(O,$,pe){var Ke=pe.length;if(null==O)return!Ke;for(O=Qs(O);Ke--;){var Ht=pe[Ke],Kn=O[Ht];if(Kn===u&&!(Ht in O)||!(0,$[Ht])(Kn))return!1}return!0}function F(O,$,pe){if("function"!=typeof O)throw new Gl(_);return dh(function(){O.apply(u,pe)},$)}function q(O,$,pe,Ke){var Ht=-1,pn=ms,Kn=!0,Sr=O.length,qr=[],no=$.length;if(!Sr)return qr;pe&&($=Ts($,yu(pe))),Ke?(pn=hs,Kn=!1):$.length>=200&&(pn=js,Kn=!1,$=new Xl($));e:for(;++Ht<Sr;){var ro=O[Ht],mo=null==pe?ro:pe(ro);if(ro=Ke||0!==ro?ro:0,Kn&&mo==mo){for(var ds=no;ds--;)if($[ds]===mo)continue e;qr.push(ro)}else pn($,mo,Ke)||qr.push(ro)}return qr}en.templateSettings={escape:kr,evaluate:mi,interpolate:An,variable:"",imports:{_:en}},(en.prototype=Au.prototype).constructor=en,(Iu.prototype=Oc(Au.prototype)).constructor=Iu,(nl.prototype=Oc(Au.prototype)).constructor=nl,wc.prototype.clear=function(){this.__data__=Cc?Cc(null):{},this.size=0},wc.prototype.delete=function(O){var $=this.has(O)&&delete this.__data__[O];return this.size-=$?1:0,$},wc.prototype.get=function(O){var $=this.__data__;if(Cc){var pe=$[O];return pe===S?u:pe}return Js.call($,O)?$[O]:u},wc.prototype.has=function(O){var $=this.__data__;return Cc?$[O]!==u:Js.call($,O)},wc.prototype.set=function(O,$){var pe=this.__data__;return this.size+=this.has(O)?0:1,pe[O]=Cc&&$===u?S:$,this},hu.prototype.clear=function(){this.__data__=[],this.size=0},hu.prototype.delete=function(O){var $=this.__data__,pe=Mc($,O);return!(pe<0||(pe==$.length-1?$.pop():Ye.call($,pe,1),--this.size,0))},hu.prototype.get=function(O){var $=this.__data__,pe=Mc($,O);return pe<0?u:$[pe][1]},hu.prototype.has=function(O){return Mc(this.__data__,O)>-1},hu.prototype.set=function(O,$){var pe=this.__data__,Ke=Mc(pe,O);return Ke<0?(++this.size,pe.push([O,$])):pe[Ke][1]=$,this},Ql.prototype.clear=function(){this.size=0,this.__data__={hash:new wc,map:new(Rd||hu),string:new wc}},Ql.prototype.delete=function(O){var $=vp(this,O).delete(O);return this.size-=$?1:0,$},Ql.prototype.get=function(O){return vp(this,O).get(O)},Ql.prototype.has=function(O){return vp(this,O).has(O)},Ql.prototype.set=function(O,$){var pe=vp(this,O),Ke=pe.size;return pe.set(O,$),this.size+=pe.size==Ke?0:1,this},Xl.prototype.add=Xl.prototype.push=function(O){return this.__data__.set(O,S),this},Xl.prototype.has=function(O){return this.__data__.has(O)},Ll.prototype.clear=function(){this.__data__=new hu,this.size=0},Ll.prototype.delete=function(O){var $=this.__data__,pe=$.delete(O);return this.size=$.size,pe},Ll.prototype.get=function(O){return this.__data__.get(O)},Ll.prototype.has=function(O){return this.__data__.has(O)},Ll.prototype.set=function(O,$){var pe=this.__data__;if(pe instanceof hu){var Ke=pe.__data__;if(!Rd||Ke.length<199)return Ke.push([O,$]),this.size=++pe.size,this;pe=this.__data__=new Ql(Ke)}return pe.set(O,$),this.size=pe.size,this};var de=ma(xn),ye=ma(ir,!0);function Ue(O,$){var pe=!0;return de(O,function(Ke,Ht,pn){return pe=!!$(Ke,Ht,pn)}),pe}function Oe(O,$,pe){for(var Ke=-1,Ht=O.length;++Ke<Ht;){var pn=O[Ke],Kn=$(pn);if(null!=Kn&&(Sr===u?Kn==Kn&&!Gu(Kn):pe(Kn,Sr)))var Sr=Kn,qr=pn}return qr}function gt(O,$){var pe=[];return de(O,function(Ke,Ht,pn){$(Ke,Ht,pn)&&pe.push(Ke)}),pe}function yt(O,$,pe,Ke,Ht){var pn=-1,Kn=O.length;for(pe||(pe=G_),Ht||(Ht=[]);++pn<Kn;){var Sr=O[pn];$>0&&pe(Sr)?$>1?yt(Sr,$-1,pe,Ke,Ht):Ma(Ht,Sr):Ke||(Ht[Ht.length]=Sr)}return Ht}var nn=Vs(),Pn=Vs(!0);function xn(O,$){return O&&nn(O,$,Md)}function ir(O,$){return O&&Pn(O,$,Md)}function Gr(O,$){return Go($,function(pe){return tf(O[pe])})}function Pi(O,$){for(var pe=0,Ke=($=Zf($,O)).length;null!=O&&pe<Ke;)O=O[Bc($[pe++])];return pe&&pe==Ke?O:u}function Zo(O,$,pe){var Ke=$(O);return ui(O)?Ke:Ma(Ke,pe(O))}function Lo(O){return null==O?O===u?"[object Undefined]":"[object Null]":ot&&ot in Qs(O)?function(O){var $=Js.call(O,ot),pe=O[ot];try{O[ot]=u;var Ke=!0}catch(pn){}var Ht=Nl.call(O);return Ke&&($?O[ot]=pe:delete O[ot]),Ht}(O):function(O){return Nl.call(O)}(O)}function Gs(O,$){return O>$}function Xs(O,$){return null!=O&&Js.call(O,$)}function dl(O,$){return null!=O&&$ in Qs(O)}function ia(O,$,pe){for(var Ke=pe?hs:ms,Ht=O[0].length,pn=O.length,Kn=pn,Sr=hr(pn),qr=1/0,no=[];Kn--;){var ro=O[Kn];Kn&&$&&(ro=Ts(ro,yu($))),qr=Ol(ro.length,qr),Sr[Kn]=!pe&&($||Ht>=120&&ro.length>=120)?new Xl(Kn&&ro):u}ro=O[0];var mo=-1,ds=Sr[0];e:for(;++mo<Ht&&no.length<qr;){var oa=ro[mo],Ia=$?$(oa):oa;if(oa=pe||0!==oa?oa:0,!(ds?js(ds,Ia):Ke(no,Ia,pe))){for(Kn=pn;--Kn;){var Pl=Sr[Kn];if(!(Pl?js(Pl,Ia):Ke(O[Kn],Ia,pe)))continue e}ds&&ds.push(Ia),no.push(oa)}}return no}function il(O,$,pe){var Ke=null==(O=bf(O,$=Zf($,O)))?O:O[Bc(Jc($))];return null==Ke?u:Me(Ke,O,pe)}function Eu(O){return Ic(O)&&Lo(O)==Gt}function gu(O,$,pe,Ke,Ht){return O===$||(null==O||null==$||!Ic(O)&&!Ic($)?O!=O&&$!=$:function(O,$,pe,Ke,Ht,pn){var Kn=ui(O),Sr=ui($),qr=Kn?xt:Pc(O),no=Sr?xt:Pc($),ro=(qr=qr==Gt?Br:qr)==Br,mo=(no=no==Gt?Br:no)==Br,ds=qr==no;if(ds&&ql(O)){if(!ql($))return!1;Kn=!0,ro=!1}if(ds&&!ro)return pn||(pn=new Ll),Kn||Nm(O)?rd(O,$,pe,Ke,Ht,pn):function(O,$,pe,Ke,Ht,pn,Kn){switch(pe){case Gn:if(O.byteLength!=$.byteLength||O.byteOffset!=$.byteOffset)return!1;O=O.buffer,$=$.buffer;case Fr:return!(O.byteLength!=$.byteLength||!pn(new ic(O),new ic($)));case Zn:case Ur:case Nn:return at(+O,+$);case Lr:return O.name==$.name&&O.message==$.message;case ki:case Zr:return O==$+"";case ei:var Sr=El;case Hi:if(Sr||(Sr=V),O.size!=$.size&&!(1&Ke))return!1;var no=Kn.get(O);if(no)return no==$;Ke|=2,Kn.set(O,$);var ro=rd(Sr(O),Sr($),Ke,Ht,pn,Kn);return Kn.delete(O),ro;case Cn:if(Ja)return Ja.call(O)==Ja.call($)}return!1}(O,$,qr,pe,Ke,Ht,pn);if(!(1&pe)){var oa=ro&&Js.call(O,"__wrapped__"),Ia=mo&&Js.call($,"__wrapped__");if(oa||Ia){var Pl=oa?O.value():O,Va=Ia?$.value():$;return pn||(pn=new Ll),Ht(Pl,Va,pe,Ke,pn)}}return!!ds&&(pn||(pn=new Ll),function(O,$,pe,Ke,Ht,pn){var Kn=1&pe,Sr=c_(O),qr=Sr.length;if(qr!=c_($).length&&!Kn)return!1;for(var mo=qr;mo--;){var ds=Sr[mo];if(!(Kn?ds in $:Js.call($,ds)))return!1}var oa=pn.get(O),Ia=pn.get($);if(oa&&Ia)return oa==$&&Ia==O;var Pl=!0;pn.set(O,$),pn.set($,O);for(var Va=Kn;++mo<qr;){var su=O[ds=Sr[mo]],vu=$[ds];if(Ke)var xp=Kn?Ke(vu,su,ds,$,O,pn):Ke(su,vu,ds,O,$,pn);if(!(xp===u?su===vu||Ht(su,vu,pe,Ke,pn):xp)){Pl=!1;break}Va||(Va="constructor"==ds)}if(Pl&&!Va){var op=O.constructor,Dp=$.constructor;op!=Dp&&"constructor"in O&&"constructor"in $&&!("function"==typeof op&&op instanceof op&&"function"==typeof Dp&&Dp instanceof Dp)&&(Pl=!1)}return pn.delete(O),pn.delete($),Pl}(O,$,pe,Ke,Ht,pn))}(O,$,pe,Ke,gu,Ht))}function gf(O,$,pe,Ke){var Ht=pe.length,pn=Ht,Kn=!Ke;if(null==O)return!pn;for(O=Qs(O);Ht--;){var Sr=pe[Ht];if(Kn&&Sr[2]?Sr[1]!==O[Sr[0]]:!(Sr[0]in O))return!1}for(;++Ht<pn;){var qr=(Sr=pe[Ht])[0],no=O[qr],ro=Sr[1];if(Kn&&Sr[2]){if(no===u&&!(qr in O))return!1}else{var mo=new Ll;if(Ke)var ds=Ke(no,ro,qr,O,$,mo);if(!(ds===u?gu(ro,no,3,Ke,mo):ds))return!1}}return!0}function Ga(O){return!(!ju(O)||function(O){return!!Mn&&Mn in O}(O))&&(tf(O)?ss:vr).test(Rf(O))}function Tt(O){return"function"==typeof O?O:null==O?Nf:"object"==typeof O?ui(O)?na(O[0],O[1]):xa(O):sy(O)}function Qt(O){if(!Ud(O))return fc(O);var $=[];for(var pe in Qs(O))Js.call(O,pe)&&"constructor"!=pe&&$.push(pe);return $}function bi(O,$){return O<$}function cs(O,$){var pe=-1,Ke=Vo(O)?hr(O.length):[];return de(O,function(Ht,pn,Kn){Ke[++pe]=$(Ht,pn,Kn)}),Ke}function xa(O){var $=uh(O);return 1==$.length&&$[0][2]?p_($[0][0],$[0][1]):function(pe){return pe===O||gf(pe,O,$)}}function na(O,$){return $h(O)&&yf($)?p_(Bc(O),$):function(pe){var Ke=_1(pe,O);return Ke===u&&Ke===$?$0(pe,O):gu($,Ke,3)}}function _l(O,$,pe,Ke,Ht){O!==$&&nn($,function(pn,Kn){if(Ht||(Ht=new Ll),ju(pn))!function(O,$,pe,Ke,Ht,pn,Kn){var Sr=ch(O,pe),qr=ch($,pe),no=Kn.get(qr);if(no)hc(O,pe,no);else{var ro=pn?pn(Sr,qr,pe+"",O,$,Kn):u,mo=ro===u;if(mo){var ds=ui(qr),oa=!ds&&ql(qr),Ia=!ds&&!oa&&Nm(qr);ro=qr,ds||oa||Ia?ui(Sr)?ro=Sr:Ms(Sr)?ro=vi(Sr):oa?(mo=!1,ro=k_(qr,!0)):Ia?(mo=!1,ro=X(qr,!0)):ro=[]:gv(qr)||fr(qr)?(ro=Sr,fr(Sr)?ro=mS(Sr):(!ju(Sr)||tf(Sr))&&(ro=tp(qr))):mo=!1}mo&&(Kn.set(qr,ro),Ht(ro,qr,Ke,pn,Kn),Kn.delete(qr)),hc(O,pe,ro)}}(O,$,Kn,pe,_l,Ke,Ht);else{var Sr=Ke?Ke(ch(O,Kn),pn,Kn+"",O,$,Ht):u;Sr===u&&(Sr=pn),hc(O,Kn,Sr)}},sd)}function zc(O,$){var pe=O.length;if(pe)return id($+=$<0?pe:0,pe)?O[$]:u}function qf(O,$,pe){$=$.length?Ts($,function(pn){return ui(pn)?function(Kn){return Pi(Kn,1===pn.length?pn[0]:pn)}:pn}):[Nf];var Ke=-1;return $=Ts($,yu(Ds())),function(In,Cr){var hr=In.length;for(In.sort(function(pn,Kn){return function(O,$,pe){for(var Ke=-1,Ht=O.criteria,pn=$.criteria,Kn=Ht.length,Sr=pe.length;++Ke<Kn;){var qr=ke(Ht[Ke],pn[Ke]);if(qr)return Ke>=Sr?qr:qr*("desc"==pe[Ke]?-1:1)}return O.index-$.index}(pn,Kn,pe)});hr--;)In[hr]=In[hr].value;return In}(cs(O,function(pn,Kn,Sr){return{criteria:Ts($,function(no){return no(pn)}),index:++Ke,value:pn}}))}function Hp(O,$,pe){for(var Ke=-1,Ht=$.length,pn={};++Ke<Ht;){var Kn=$[Ke],Sr=Pi(O,Kn);pe(Sr,Kn)&&Bf(pn,Zf(Kn,O),Sr)}return pn}function mf(O,$,pe,Ke){var Ht=Ke?Cu:Fc,pn=-1,Kn=$.length,Sr=O;for(O===$&&($=vi($)),pe&&(Sr=Ts(O,yu(pe)));++pn<Kn;)for(var qr=0,no=$[pn],ro=pe?pe(no):no;(qr=Ht(Sr,ro,qr,Ke))>-1;)Sr!==O&&Ye.call(Sr,qr,1),Ye.call(O,qr,1);return O}function Uf(O,$){for(var pe=O?$.length:0,Ke=pe-1;pe--;){var Ht=$[pe];if(pe==Ke||Ht!==pn){var pn=Ht;id(Ht)?Ye.call(O,Ht,1):Ph(O,Ht)}}return O}function dd(O,$){return O+Yo(ja()*($-O+1))}function pp(O,$){var pe="";if(!O||$<1||$>it)return pe;do{$%2&&(pe+=O),($=Yo($/2))&&(O+=O)}while($);return pe}function fl(O,$){return Df(fd(O,$,Nf),O+"")}function i_(O){return Vl(km(O))}function F_(O,$){var pe=km(O);return fh(pe,bu($,0,pe.length))}function Bf(O,$,pe,Ke){if(!ju(O))return O;for(var Ht=-1,pn=($=Zf($,O)).length,Kn=pn-1,Sr=O;null!=Sr&&++Ht<pn;){var qr=Bc($[Ht]),no=pe;if("__proto__"===qr||"constructor"===qr||"prototype"===qr)return O;if(Ht!=Kn){var ro=Sr[qr];(no=Ke?Ke(ro,qr,Sr):u)===u&&(no=ju(ro)?ro:id($[Ht+1])?[]:{})}_u(Sr,qr,no),Sr=Sr[qr]}return O}var kd=Xd?function(O,$){return Xd.set(O,$),O}:Nf,Yf=Et?function(O,$){return Et(O,"toString",{configurable:!0,enumerable:!1,value:ry($),writable:!0})}:Nf;function eh(O){return fh(km(O))}function bd(O,$,pe){var Ke=-1,Ht=O.length;$<0&&($=-$>Ht?0:Ht+$),(pe=pe>Ht?Ht:pe)<0&&(pe+=Ht),Ht=$>pe?0:pe-$>>>0,$>>>=0;for(var pn=hr(Ht);++Ke<Ht;)pn[Ke]=O[Ke+$];return pn}function Rh(O,$){var pe;return de(O,function(Ke,Ht,pn){return!(pe=$(Ke,Ht,pn))}),!!pe}function th(O,$,pe){var Ke=0,Ht=null==O?Ke:O.length;if("number"==typeof $&&$==$&&Ht<=2147483647){for(;Ke<Ht;){var pn=Ke+Ht>>>1,Kn=O[pn];null!==Kn&&!Gu(Kn)&&(pe?Kn<=$:Kn<$)?Ke=pn+1:Ht=pn}return Ht}return nh(O,$,Nf,pe)}function nh(O,$,pe,Ke){var Ht=0,pn=null==O?0:O.length;if(0===pn)return 0;for(var Kn=($=pe($))!=$,Sr=null===$,qr=Gu($),no=$===u;Ht<pn;){var ro=Yo((Ht+pn)/2),mo=pe(O[ro]),ds=mo!==u,oa=null===mo,Ia=mo==mo,Pl=Gu(mo);if(Kn)var Va=Ke||Ia;else Va=no?Ia&&(Ke||ds):Sr?Ia&&ds&&(Ke||!oa):qr?Ia&&ds&&!oa&&(Ke||!Pl):!oa&&!Pl&&(Ke?mo<=$:mo<$);Va?Ht=ro+1:pn=ro}return Ol(pn,4294967294)}function Nh(O,$){for(var pe=-1,Ke=O.length,Ht=0,pn=[];++pe<Ke;){var Kn=O[pe],Sr=$?$(Kn):Kn;if(!pe||!at(Sr,qr)){var qr=Sr;pn[Ht++]=0===Kn?0:Kn}}return pn}function rh(O){return"number"==typeof O?O:Gu(O)?NaN:+O}function Ed(O){if("string"==typeof O)return O;if(ui(O))return Ts(O,Ed)+"";if(Gu(O))return Qu?Qu.call(O):"";var $=O+"";return"0"==$&&1/O==-Vt?"-0":$}function xf(O,$,pe){var Ke=-1,Ht=ms,pn=O.length,Kn=!0,Sr=[],qr=Sr;if(pe)Kn=!1,Ht=hs;else if(pn>=200){var no=$?null:Fh(O);if(no)return V(no);Kn=!1,Ht=js,qr=new Xl}else qr=$?[]:Sr;e:for(;++Ke<pn;){var ro=O[Ke],mo=$?$(ro):ro;if(ro=pe||0!==ro?ro:0,Kn&&mo==mo){for(var ds=qr.length;ds--;)if(qr[ds]===mo)continue e;$&&qr.push(mo),Sr.push(ro)}else Ht(qr,mo,pe)||(qr!==Sr&&qr.push(mo),Sr.push(ro))}return Sr}function Ph(O,$){return null==(O=bf(O,$=Zf($,O)))||delete O[Bc(Jc($))]}function Bp(O,$,pe,Ke){return Bf(O,$,pe(Pi(O,$)),Ke)}function ih(O,$,pe,Ke){for(var Ht=O.length,pn=Ke?Ht:-1;(Ke?pn--:++pn<Ht)&&$(O[pn],pn,O););return pe?bd(O,Ke?0:pn,Ke?pn+1:Ht):bd(O,Ke?pn+1:0,Ke?Ht:pn)}function Ih(O,$){var pe=O;return pe instanceof nl&&(pe=pe.value()),au($,function(Ke,Ht){return Ht.func.apply(Ht.thisArg,Ma([Ke],Ht.args))},pe)}function vf(O,$,pe){var Ke=O.length;if(Ke<2)return Ke?xf(O[0]):[];for(var Ht=-1,pn=hr(Ke);++Ht<Ke;)for(var Kn=O[Ht],Sr=-1;++Sr<Ke;)Sr!=Ht&&(pn[Ht]=q(pn[Ht]||Kn,O[Sr],$,pe));return xf(yt(pn,1),$,pe)}function Lh(O,$,pe){for(var Ke=-1,Ht=O.length,pn=$.length,Kn={};++Ke<Ht;)pe(Kn,O[Ke],Ke<pn?$[Ke]:u);return Kn}function $d(O){return Ms(O)?O:[]}function hp(O){return"function"==typeof O?O:Nf}function Zf(O,$){return ui(O)?O:$h(O,$)?[O]:__(Vu(O))}var qd=fl;function ac(O,$,pe){var Ke=O.length;return pe=pe===u?Ke:pe,!$&&pe>=Ke?O:bd(O,$,pe)}var oh=qt||function(O){return Hl.clearTimeout(O)};function k_(O,$){if($)return O.slice();var pe=O.length,Ke=df?df(pe):new O.constructor(pe);return O.copy(Ke),Ke}function o_(O){var $=new O.constructor(O.byteLength);return new ic($).set(new ic(O)),$}function X(O,$){var pe=$?o_(O.buffer):O.buffer;return new O.constructor(pe,O.byteOffset,O.length)}function ke(O,$){if(O!==$){var pe=O!==u,Ke=null===O,Ht=O==O,pn=Gu(O),Kn=$!==u,Sr=null===$,qr=$==$,no=Gu($);if(!Sr&&!no&&!pn&&O>$||pn&&Kn&&qr&&!Sr&&!no||Ke&&Kn&&qr||!pe&&qr||!Ht)return 1;if(!Ke&&!pn&&!no&&O<$||no&&pe&&Ht&&!Ke&&!pn||Sr&&pe&&Ht||!Kn&&Ht||!qr)return-1}return 0}function Jn(O,$,pe,Ke){for(var Ht=-1,pn=O.length,Kn=pe.length,Sr=-1,qr=$.length,no=ga(pn-Kn,0),ro=hr(qr+no),mo=!Ke;++Sr<qr;)ro[Sr]=$[Sr];for(;++Ht<Kn;)(mo||Ht<pn)&&(ro[pe[Ht]]=O[Ht]);for(;no--;)ro[Sr++]=O[Ht++];return ro}function Ir(O,$,pe,Ke){for(var Ht=-1,pn=O.length,Kn=-1,Sr=pe.length,qr=-1,no=$.length,ro=ga(pn-Sr,0),mo=hr(ro+no),ds=!Ke;++Ht<ro;)mo[Ht]=O[Ht];for(var oa=Ht;++qr<no;)mo[oa+qr]=$[qr];for(;++Kn<Sr;)(ds||Ht<pn)&&(mo[oa+pe[Kn]]=O[Ht++]);return mo}function vi(O,$){var pe=-1,Ke=O.length;for($||($=hr(Ke));++pe<Ke;)$[pe]=O[pe];return $}function zi(O,$,pe,Ke){var Ht=!pe;pe||(pe={});for(var pn=-1,Kn=$.length;++pn<Kn;){var Sr=$[pn],qr=Ke?Ke(pe[Sr],O[Sr],Sr,pe,O):u;qr===u&&(qr=O[Sr]),Ht?Ou(pe,Sr,qr):_u(pe,Sr,qr)}return pe}function Xo(O,$){return function(pe,Ke){var Ht=ui(pe)?xe:Hc,pn=$?$():{};return Ht(pe,O,Ds(Ke,2),pn)}}function Rs(O){return fl(function($,pe){var Ke=-1,Ht=pe.length,pn=Ht>1?pe[Ht-1]:u,Kn=Ht>2?pe[2]:u;for(pn=O.length>3&&"function"==typeof pn?(Ht--,pn):u,Kn&&gc(pe[0],pe[1],Kn)&&(pn=Ht<3?u:pn,Ht=1),$=Qs($);++Ke<Ht;){var Sr=pe[Ke];Sr&&O($,Sr,Ke,pn)}return $})}function ma(O,$){return function(pe,Ke){if(null==pe)return pe;if(!Vo(pe))return O(pe,Ke);for(var Ht=pe.length,pn=$?Ht:-1,Kn=Qs(pe);($?pn--:++pn<Ht)&&!1!==Ke(Kn[pn],pn,Kn););return pe}}function Vs(O){return function($,pe,Ke){for(var Ht=-1,pn=Qs($),Kn=Ke($),Sr=Kn.length;Sr--;){var qr=Kn[O?Sr:++Ht];if(!1===pe(pn[qr],qr,pn))break}return $}}function nd(O){return function($){var pe=aa($=Vu($))?un($):u,Ke=pe?pe[0]:$.charAt(0),Ht=pe?ac(pe,1).join(""):$.slice(1);return Ke[O]()+Ht}}function wu(O){return function($){return au($b(j0($).replace(ne,"")),O,"")}}function Hd(O){return function(){var $=arguments;switch($.length){case 0:return new O;case 1:return new O($[0]);case 2:return new O($[0],$[1]);case 3:return new O($[0],$[1],$[2]);case 4:return new O($[0],$[1],$[2],$[3]);case 5:return new O($[0],$[1],$[2],$[3],$[4]);case 6:return new O($[0],$[1],$[2],$[3],$[4],$[5]);case 7:return new O($[0],$[1],$[2],$[3],$[4],$[5],$[6])}var pe=Oc(O.prototype),Ke=O.apply(pe,$);return ju(Ke)?Ke:pe}}function sh(O){return function($,pe,Ke){var Ht=Qs($);if(!Vo($)){var pn=Ds(pe,3);$=Md($),pe=function(Sr){return pn(Ht[Sr],Sr,Ht)}}var Kn=O($,pe,Ke);return Kn>-1?Ht[pn?$[Kn]:Kn]:u}}function ah(O){return mp(function($){var pe=$.length,Ke=pe,Ht=Iu.prototype.thru;for(O&&$.reverse();Ke--;){var pn=$[Ke];if("function"!=typeof pn)throw new Gl(_);if(Ht&&!Kn&&"wrapper"==Uc(pn))var Kn=new Iu([],!0)}for(Ke=Kn?Ke:pe;++Ke<pe;){var Sr=Uc(pn=$[Ke]),qr="wrapper"==Sr?Ea(pn):u;Kn=qr&&Uh(qr[0])&&424==qr[1]&&!qr[4].length&&1==qr[9]?Kn[Uc(qr[0])].apply(Kn,qr[3]):1==pn.length&&Uh(pn)?Kn[Sr]():Kn.thru(pn)}return function(){var no=arguments,ro=no[0];if(Kn&&1==no.length&&ui(ro))return Kn.plant(ro).value();for(var mo=0,ds=pe?$[mo].apply(this,no):ro;++mo<pe;)ds=$[mo].call(this,ds);return ds}})}function _p(O,$,pe,Ke,Ht,pn,Kn,Sr,qr,no){var ro=128&$,mo=1&$,ds=2&$,oa=24&$,Ia=512&$,Pl=ds?u:Hd(O);return function Va(){for(var su=arguments.length,vu=hr(su),xp=su;xp--;)vu[xp]=arguments[xp];if(oa)var op=Xu(Va),Dp=Bo(vu,op);if(Ke&&(vu=Jn(vu,Ke,Ht,oa)),pn&&(vu=Ir(vu,pn,Kn,oa)),su-=Dp,oa&&su<no){var hd=ks(vu,op);return B_(O,$,_p,Va.placeholder,pe,vu,hd,Sr,qr,no-su)}var Rp=mo?pe:this,vh=ds?Rp[O]:O;return su=vu.length,Sr?vu=zf(vu,Sr):Ia&&su>1&&vu.reverse(),ro&&qr<su&&(vu.length=qr),this&&this!==Hl&&this instanceof Va&&(vh=Pl||Hd(vh)),vh.apply(Rp,vu)}}function jf(O,$){return function(pe,Ke){return function(O,$,pe,Ke){return xn(O,function(Ht,pn,Kn){$(Ke,pe(Ht),pn,Kn)}),Ke}(pe,O,$(Ke),{})}}function H_(O,$){return function(pe,Ke){var Ht;if(pe===u&&Ke===u)return $;if(pe!==u&&(Ht=pe),Ke!==u){if(Ht===u)return Ke;"string"==typeof pe||"string"==typeof Ke?(pe=Ed(pe),Ke=Ed(Ke)):(pe=rh(pe),Ke=rh(Ke)),Ht=O(pe,Ke)}return Ht}}function fg(O){return mp(function($){return $=Ts($,yu(Ds())),fl(function(pe){var Ke=this;return O($,function(Ht){return Me(Ht,Ke,pe)})})})}function gp(O,$){var pe=($=$===u?" ":Ed($)).length;if(pe<2)return pe?pp($,O):$;var Ke=pp($,Ei(O/ut($)));return aa($)?ac(un(Ke),0,O).join(""):Ke.slice(0,O)}function U_(O){return function($,pe,Ke){return Ke&&"number"!=typeof Ke&&gc($,pe,Ke)&&(pe=Ke=u),$=Xh($),pe===u?(pe=$,$=0):pe=Xh(pe),function(O,$,pe,Ke){for(var Ht=-1,pn=ga(Ei(($-O)/(pe||1)),0),Kn=hr(pn);pn--;)Kn[Ke?pn:++Ht]=O,O+=pe;return Kn}($,pe,Ke=Ke===u?$<pe?1:-1:Xh(Ke),O)}}function s_(O){return function($,pe){return"string"==typeof $&&"string"==typeof pe||($=Ef($),pe=Ef(pe)),O($,pe)}}function B_(O,$,pe,Ke,Ht,pn,Kn,Sr,qr,no){var ro=8&$;$|=ro?32:64,4&($&=~(ro?64:32))||($&=-4);var Pl=[O,$,Ht,ro?pn:u,ro?Kn:u,ro?u:pn,ro?u:Kn,Sr,qr,no],Va=pe.apply(u,Pl);return Uh(O)&&od(Va,Pl),Va.placeholder=Ke,np(Va,O,$)}function Wc(O){var $=Tl[O];return function(pe,Ke){if(pe=Ef(pe),(Ke=null==Ke?0:Ol($l(Ke),292))&&Oa(pe)){var Ht=(Vu(pe)+"e").split("e");return+((Ht=(Vu($(Ht[0]+"e"+(+Ht[1]+Ke)))+"e").split("e"))[0]+"e"+(+Ht[1]-Ke))}return $(pe)}}var Fh=Sc&&1/V(new Sc([,-0]))[1]==Vt?function(O){return new Sc(O)}:tg;function a_(O){return function($){var pe=Pc($);return pe==ei?El($):pe==Hi?function(In){var Cr=-1,hr=Array(In.size);return In.forEach(function(ao){hr[++Cr]=[ao,ao]}),hr}($):function(In,Cr){return Ts(Cr,function(hr){return[hr,In[hr]]})}($,O($))}}function ep(O,$,pe,Ke,Ht,pn,Kn,Sr){var qr=2&$;if(!qr&&"function"!=typeof O)throw new Gl(_);var no=Ke?Ke.length:0;if(no||($&=-97,Ke=Ht=u),Kn=Kn===u?Kn:ga($l(Kn),0),Sr=Sr===u?Sr:$l(Sr),no-=Ht?Ht.length:0,64&$){var ro=Ke,mo=Ht;Ke=Ht=u}var ds=qr?u:Ea(O),oa=[O,$,pe,Ke,Ht,ro,mo,pn,Kn,Sr];if(ds&&function(O,$){var pe=O[1],Ke=$[1],Ht=pe|Ke;if(!(Ht<131||(128==Ke&&8==pe||128==Ke&&256==pe&&O[7].length<=$[8]||384==Ke&&$[7].length<=$[8]&&8==pe)))return O;1&Ke&&(O[2]=$[2],Ht|=1&pe?0:4);var Sr=$[3];if(Sr){var qr=O[3];O[3]=qr?Jn(qr,Sr,$[4]):Sr,O[4]=qr?ks(O[3],N):$[4]}(Sr=$[5])&&(O[5]=(qr=O[5])?Ir(qr,Sr,$[6]):Sr,O[6]=qr?ks(O[5],N):$[6]),(Sr=$[7])&&(O[7]=Sr),128&Ke&&(O[8]=null==O[8]?$[8]:Ol(O[8],$[8])),null==O[9]&&(O[9]=$[9]),O[0]=$[0],O[1]=Ht}(oa,ds),O=oa[0],$=oa[1],pe=oa[2],Ke=oa[3],Ht=oa[4],!(Sr=oa[9]=oa[9]===u?qr?0:O.length:ga(oa[9]-no,0))&&24&$&&($&=-25),$&&1!=$)Ia=8==$||16==$?function(O,$,pe){var Ke=Hd(O);return function Ht(){for(var pn=arguments.length,Kn=hr(pn),Sr=pn,qr=Xu(Ht);Sr--;)Kn[Sr]=arguments[Sr];var no=pn<3&&Kn[0]!==qr&&Kn[pn-1]!==qr?[]:ks(Kn,qr);return(pn-=no.length)<pe?B_(O,$,_p,Ht.placeholder,u,Kn,no,u,u,pe-pn):Me(this&&this!==Hl&&this instanceof Ht?Ke:O,this,Kn)}}(O,$,Sr):32!=$&&33!=$||Ht.length?_p.apply(u,oa):function(O,$,pe,Ke){var Ht=1&$,pn=Hd(O);return function Kn(){for(var Sr=-1,qr=arguments.length,no=-1,ro=Ke.length,mo=hr(ro+qr),ds=this&&this!==Hl&&this instanceof Kn?pn:O;++no<ro;)mo[no]=Ke[no];for(;qr--;)mo[no++]=arguments[++Sr];return Me(ds,Ht?pe:this,mo)}}(O,$,pe,Ke);else var Ia=function(O,$,pe){var Ke=1&$,Ht=Hd(O);return function pn(){return(this&&this!==Hl&&this instanceof pn?Ht:O).apply(Ke?pe:this,arguments)}}(O,$,pe);return np((ds?kd:od)(Ia,oa),O,$)}function l_(O,$,pe,Ke){return O===u||at(O,pa[pe])&&!Js.call(Ke,pe)?$:O}function lh(O,$,pe,Ke,Ht,pn){return ju(O)&&ju($)&&(pn.set($,O),_l(O,$,u,lh,pn),pn.delete($)),O}function u_(O){return gv(O)?u:O}function rd(O,$,pe,Ke,Ht,pn){var Kn=1&pe,Sr=O.length,qr=$.length;if(Sr!=qr&&!(Kn&&qr>Sr))return!1;var no=pn.get(O),ro=pn.get($);if(no&&ro)return no==$&&ro==O;var mo=-1,ds=!0,oa=2&pe?new Xl:u;for(pn.set(O,$),pn.set($,O);++mo<Sr;){var Ia=O[mo],Pl=$[mo];if(Ke)var Va=Kn?Ke(Pl,Ia,mo,$,O,pn):Ke(Ia,Pl,mo,O,$,pn);if(Va!==u){if(Va)continue;ds=!1;break}if(oa){if(!Rl($,function(su,vu){if(!js(oa,vu)&&(Ia===su||Ht(Ia,su,pe,Ke,pn)))return oa.push(vu)})){ds=!1;break}}else if(Ia!==Pl&&!Ht(Ia,Pl,pe,Ke,pn)){ds=!1;break}}return pn.delete(O),pn.delete($),ds}function mp(O){return Df(fd(O,u,z_),O+"")}function c_(O){return Zo(O,Md,Yp)}function d_(O){return Zo(O,sd,Gf)}var Ea=Xd?function(O){return Xd.get(O)}:tg;function Uc(O){for(var $=O.name+"",pe=jc[$],Ke=Js.call(jc,$)?pe.length:0;Ke--;){var Ht=pe[Ke],pn=Ht.func;if(null==pn||pn==O)return Ht.name}return $}function Xu(O){return(Js.call(en,"placeholder")?en:O).placeholder}function Ds(){var O=en.iteratee||S1;return O=O===S1?Tt:O,arguments.length?O(arguments[0],arguments[1]):O}function vp(O,$){var pe=O.__data__;return function(O){var $=typeof O;return"string"==$||"number"==$||"symbol"==$||"boolean"==$?"__proto__"!==O:null===O}($)?pe["string"==typeof $?"string":"hash"]:pe.map}function uh(O){for(var $=Md(O),pe=$.length;pe--;){var Ke=$[pe],Ht=O[Ke];$[pe]=[Ke,Ht,yf(Ht)]}return $}function Zu(O,$){var pe=function(In,Cr){return null==In?u:In[Cr]}(O,$);return Ga(pe)?pe:u}var Yp=$a?function(O){return null==O?[]:(O=Qs(O),Go($a(O),function($){return Jd.call(O,$)}))}:nf,Gf=$a?function(O){for(var $=[];O;)Ma($,Yp(O)),O=al(O);return $}:nf,Pc=Lo;function j_(O,$,pe){for(var Ke=-1,Ht=($=Zf($,O)).length,pn=!1;++Ke<Ht;){var Kn=Bc($[Ke]);if(!(pn=null!=O&&pe(O,Kn)))break;O=O[Kn]}return pn||++Ke!=Ht?pn:!!(Ht=null==O?0:O.length)&&wp(Ht)&&id(Kn,Ht)&&(ui(O)||fr(O))}function tp(O){return"function"!=typeof O.constructor||Ud(O)?{}:Oc(al(O))}function G_(O){return ui(O)||fr(O)||!!(Ie&&O&&O[Ie])}function id(O,$){var pe=typeof O;return!!($=null==$?it:$)&&("number"==pe||"symbol"!=pe&&ri.test(O))&&O>-1&&O%1==0&&O<$}function gc(O,$,pe){if(!ju(pe))return!1;var Ke=typeof $;return!!("number"==Ke?Vo(pe)&&id($,pe.length):"string"==Ke&&$ in pe)&&at(pe[$],O)}function $h(O,$){if(ui(O))return!1;var pe=typeof O;return!("number"!=pe&&"symbol"!=pe&&"boolean"!=pe&&null!=O&&!Gu(O))||Wr.test(O)||!Er.test(O)||null!=$&&O in Qs($)}function Uh(O){var $=Uc(O),pe=en[$];if("function"!=typeof pe||!($ in nl.prototype))return!1;if(O===pe)return!0;var Ke=Ea(pe);return!!Ke&&O===Ke[0]}(Of&&Pc(new Of(new ArrayBuffer(1)))!=Gn||Rd&&Pc(new Rd)!=ei||Qd&&Pc(Qd.resolve())!=Yr||Sc&&Pc(new Sc)!=Hi||Wu&&Pc(new Wu)!=zn)&&(Pc=function(O){var $=Lo(O),pe=$==Br?O.constructor:u,Ke=pe?Rf(pe):"";if(Ke)switch(Ke){case $f:return Gn;case Ju:return ei;case Sl:return Yr;case wl:return Hi;case kl:return zn}return $});var Vf=hl?tf:A_;function Ud(O){var $=O&&O.constructor;return O===("function"==typeof $&&$.prototype||pa)}function yf(O){return O==O&&!ju(O)}function p_(O,$){return function(pe){return null!=pe&&pe[O]===$&&($!==u||O in Qs(pe))}}function fd(O,$,pe){return $=ga($===u?O.length-1:$,0),function(){for(var Ke=arguments,Ht=-1,pn=ga(Ke.length-$,0),Kn=hr(pn);++Ht<pn;)Kn[Ht]=Ke[$+Ht];Ht=-1;for(var Sr=hr($+1);++Ht<$;)Sr[Ht]=Ke[Ht];return Sr[$]=pe(Kn),Me(O,this,Sr)}}function bf(O,$){return $.length<2?O:Pi(O,bd($,0,-1))}function zf(O,$){for(var pe=O.length,Ke=Ol($.length,pe),Ht=vi(O);Ke--;){var pn=$[Ke];O[Ke]=id(pn,pe)?Ht[pn]:u}return O}function ch(O,$){if(("constructor"!==$||"function"!=typeof O[$])&&"__proto__"!=$)return O[$]}var od=V_(kd),dh=Xn||function(O,$){return Hl.setTimeout(O,$)},Df=V_(Yf);function np(O,$,pe){var Ke=$+"";return Df(O,function(O,$){var pe=$.length;if(!pe)return O;var Ke=pe-1;return $[Ke]=(pe>1?"& ":"")+$[Ke],$=$.join(pe>2?", ":" "),O.replace(vo,"{\n/* [wrapped with "+$+"] */\n")}(Ke,function(O,$){return Ct(bt,function(pe){var Ke="_."+pe[0];$&pe[1]&&!ms(O,Ke)&&O.push(Ke)}),O.sort()}(function(O){var $=O.match(Co);return $?$[1].split(Gi):[]}(Ke),pe)))}function V_(O){var $=0,pe=0;return function(){var Ke=ll(),Ht=16-(Ke-pe);if(pe=Ke,Ht>0){if(++$>=800)return arguments[0]}else $=0;return O.apply(u,arguments)}}function fh(O,$){var pe=-1,Ke=O.length,Ht=Ke-1;for($=$===u?Ke:$;++pe<$;){var pn=dd(pe,Ht),Kn=O[pn];O[pn]=O[pe],O[pe]=Kn}return O.length=$,O}var $,pe,__=($=Cg(function(O){var $=[];return 46===O.charCodeAt(0)&&$.push(""),O.replace(dr,function(pe,Ke,Ht,pn){$.push(Ht?pn.replace(To,"$1"):Ke||pe)}),$},function(Ke){return 500===pe.size&&pe.clear(),Ke}),pe=$.cache,$);function Bc(O){if("string"==typeof O||Gu(O))return O;var $=O+"";return"0"==$&&1/O==-Vt?"-0":$}function Rf(O){if(null!=O){try{return Bl.call(O)}catch($){}try{return O+""}catch($){}}return""}function _g(O){if(O instanceof nl)return O.clone();var $=new Iu(O.__wrapped__,O.__chain__);return $.__actions__=vi(O.__actions__),$.__index__=O.__index__,$.__values__=O.__values__,$}var bm=fl(function(O,$){return Ms(O)?q(O,yt($,1,Ms,!0)):[]}),m_=fl(function(O,$){var pe=Jc($);return Ms(pe)&&(pe=u),Ms(O)?q(O,yt($,1,Ms,!0),Ds(pe,2)):[]}),Zp=fl(function(O,$){var pe=Jc($);return Ms(pe)&&(pe=u),Ms(O)?q(O,yt($,1,Ms,!0),u,pe):[]});function vg(O,$,pe){var Ke=null==O?0:O.length;if(!Ke)return-1;var Ht=null==pe?0:$l(pe);return Ht<0&&(Ht=ga(Ke+Ht,0)),Tc(O,Ds($,3),Ht)}function Ug(O,$,pe){var Ke=null==O?0:O.length;if(!Ke)return-1;var Ht=Ke-1;return pe!==u&&(Ht=$l(pe),Ht=pe<0?ga(Ke+Ht,0):Ol(Ht,Ke-1)),Tc(O,Ds($,3),Ht,!0)}function z_(O){return null!=O&&O.length?yt(O,1):[]}function W_(O){return O&&O.length?O[0]:u}var yg=fl(function(O){var $=Ts(O,$d);return $.length&&$[0]===O[0]?ia($):[]}),Yg=fl(function(O){var $=Jc(O),pe=Ts(O,$d);return $===Jc(pe)?$=u:pe.pop(),pe.length&&pe[0]===O[0]?ia(pe,Ds($,2)):[]}),Sp=fl(function(O){var $=Jc(O),pe=Ts(O,$d);return($="function"==typeof $?$:u)&&pe.pop(),pe.length&&pe[0]===O[0]?ia(pe,u,$):[]});function Jc(O){var $=null==O?0:O.length;return $?O[$-1]:u}var Zh=fl(bg);function bg(O,$){return O&&O.length&&$&&$.length?mf(O,$):O}var b_=mp(function(O,$){var pe=null==O?0:O.length,Ke=Rc(O,$);return Uf(O,Ts($,function(Ht){return id(Ht,pe)?+Ht:Ht}).sort(ke)),Ke});function E_(O){return null==O?O:ul.call(O)}var We=fl(function(O){return xf(yt(O,1,Ms,!0))}),Nt=fl(function(O){var $=Jc(O);return Ms($)&&($=u),xf(yt(O,1,Ms,!0),Ds($,2))}),rn=fl(function(O){var $=Jc(O);return $="function"==typeof $?$:u,xf(yt(O,1,Ms,!0),u,$)});function as(O){if(!O||!O.length)return[];var $=0;return O=Go(O,function(pe){if(Ms(pe))return $=ga(pe.length,$),!0}),$u($,function(pe){return Ts(O,rc(pe))})}function Ha(O,$){if(!O||!O.length)return[];var pe=as(O);return null==$?pe:Ts(pe,function(Ke){return Me($,u,Ke)})}var go=fl(function(O,$){return Ms(O)?q(O,$):[]}),po=fl(function(O){return vf(Go(O,Ms))}),Fa=fl(function(O){var $=Jc(O);return Ms($)&&($=u),vf(Go(O,Ms),Ds($,2))}),Ta=fl(function(O){var $=Jc(O);return $="function"==typeof $?$:u,vf(Go(O,Ms),u,$)}),ni=fl(as),Bi=fl(function(O){var $=O.length,pe=$>1?O[$-1]:u;return pe="function"==typeof pe?(O.pop(),pe):u,Ha(O,pe)});function io(O){var $=en(O);return $.__chain__=!0,$}function Cs(O,$){return $(O)}var Qa=mp(function(O){var $=O.length,pe=$?O[0]:0,Ke=this.__wrapped__,Ht=function(pn){return Rc(pn,O)};return!($>1||this.__actions__.length)&&Ke instanceof nl&&id(pe)?((Ke=Ke.slice(pe,+pe+($?1:0))).__actions__.push({func:Cs,args:[Ht],thisArg:u}),new Iu(Ke,this.__chain__).thru(function(pn){return $&&!pn.length&&pn.push(u),pn})):this.thru(Ht)}),iv=Xo(function(O,$,pe){Js.call(O,pe)?++O[pe]:Ou(O,pe,1)}),o1=sh(vg),_b=sh(Ug);function av(O,$){return(ui(O)?Ct:de)(O,Ds($,3))}function Mm(O,$){return(ui(O)?ur:ye)(O,Ds($,3))}var mc=Xo(function(O,$,pe){Js.call(O,pe)?O[pe].push($):Ou(O,pe,[$])}),Fu=fl(function(O,$,pe){var Ke=-1,Ht="function"==typeof $,pn=Vo(O)?hr(O.length):[];return de(O,function(Kn){pn[++Ke]=Ht?Me($,Kn,pe):il(Kn,$,pe)}),pn}),s1=Xo(function(O,$,pe){Ou(O,pe,$)});function Am(O,$){return(ui(O)?Ts:cs)(O,Ds($,3))}var Qo=Xo(function(O,$,pe){O[pe?0:1].push($)},function(){return[[],[]]}),dv=fl(function(O,$){if(null==O)return[];var pe=$.length;return pe>1&&gc(O,$[0],$[1])?$=[]:pe>2&&gc($[0],$[1],$[2])&&($=[$[0]]),qf(O,yt($,1),[])}),Q_=Hn||function(){return Hl.Date.now()};function jg(O,$,pe){return $=pe?u:$,ep(O,128,u,u,u,u,$=O&&null==$?O.length:$)}function fv(O,$){var pe;if("function"!=typeof $)throw new Gl(_);return O=$l(O),function(){return--O>0&&(pe=$.apply(this,arguments)),O<=1&&($=u),pe}}var Mp=fl(function(O,$,pe){var Ke=1;if(pe.length){var Ht=ks(pe,Xu(Mp));Ke|=32}return ep(O,Ke,$,pe,Ht)}),wm=fl(function(O,$,pe){var Ke=3;if(pe.length){var Ht=ks(pe,Xu(wm));Ke|=32}return ep($,Ke,O,pe,Ht)});function Gg(O,$,pe){var Ke,Ht,pn,Kn,Sr,qr,no=0,ro=!1,mo=!1,ds=!0;if("function"!=typeof O)throw new Gl(_);function oa(hd){var Rp=Ke,vh=Ht;return Ke=Ht=u,no=hd,Kn=O.apply(vh,Rp)}function Ia(hd){return no=hd,Sr=dh(su,$),ro?oa(hd):Kn}function Va(hd){var Rp=hd-qr;return qr===u||Rp>=$||Rp<0||mo&&hd-no>=pn}function su(){var hd=Q_();if(Va(hd))return vu(hd);Sr=dh(su,function(hd){var Ym=$-(hd-qr);return mo?Ol(Ym,pn-(hd-no)):Ym}(hd))}function vu(hd){return Sr=u,ds&&Ke?oa(hd):(Ke=Ht=u,Kn)}function Dp(){var hd=Q_(),Rp=Va(hd);if(Ke=arguments,Ht=this,qr=hd,Rp){if(Sr===u)return Ia(qr);if(mo)return oh(Sr),Sr=dh(su,$),oa(qr)}return Sr===u&&(Sr=dh(su,$)),Kn}return $=Ef($)||0,ju(pe)&&(ro=!!pe.leading,pn=(mo="maxWait"in pe)?ga(Ef(pe.maxWait)||0,$):pn,ds="trailing"in pe?!!pe.trailing:ds),Dp.cancel=function(){Sr!==u&&oh(Sr),no=0,Ke=qr=Ht=Sr=u},Dp.flush=function(){return Sr===u?Kn:vu(Q_())},Dp}var l1=fl(function(O,$){return F(O,1,$)}),hv=fl(function(O,$,pe){return F(O,Ef($)||0,pe)});function Cg(O,$){if("function"!=typeof O||null!=$&&"function"!=typeof $)throw new Gl(_);var pe=function(){var Ke=arguments,Ht=$?$.apply(this,Ke):Ke[0],pn=pe.cache;if(pn.has(Ht))return pn.get(Ht);var Kn=O.apply(this,Ke);return pe.cache=pn.set(Ht,Kn)||pn,Kn};return pe.cache=new(Cg.Cache||Ql),pe}function Ap(O){if("function"!=typeof O)throw new Gl(_);return function(){var $=arguments;switch($.length){case 0:return!O.call(this);case 1:return!O.call(this,$[0]);case 2:return!O.call(this,$[0],$[1]);case 3:return!O.call(this,$[0],$[1],$[2])}return!O.apply(this,$)}}Cg.Cache=Ql;var Jh=qd(function(O,$){var pe=($=1==$.length&&ui($[0])?Ts($[0],yu(Ds())):Ts(yt($,1),yu(Ds()))).length;return fl(function(Ke){for(var Ht=-1,pn=Ol(Ke.length,pe);++Ht<pn;)Ke[Ht]=$[Ht].call(this,Ke[Ht]);return Me(O,this,Ke)})}),Vp=fl(function(O,$){var pe=ks($,Xu(Vp));return ep(O,32,u,$,pe)}),X_=fl(function(O,$){var pe=ks($,Xu(X_));return ep(O,64,u,$,pe)}),C_=mp(function(O,$){return ep(O,256,u,u,u,$)});function at(O,$){return O===$||O!=O&&$!=$}var $t=s_(Gs),jn=s_(function(O,$){return O>=$}),fr=Eu(function(){return arguments}())?Eu:function(O){return Ic(O)&&Js.call(O,"callee")&&!Jd.call(O,"callee")},ui=hr.isArray,Ro=Su?yu(Su):function(O){return Ic(O)&&Lo(O)==Fr};function Vo(O){return null!=O&&wp(O.length)&&!tf(O)}function Ms(O){return Ic(O)&&Vo(O)}var ql=ns||A_,eu=Zl?yu(Zl):function(O){return Ic(O)&&Lo(O)==Ur};function K_(O){if(!Ic(O))return!1;var $=Lo(O);return $==Lr||"[object DOMException]"==$||"string"==typeof O.message&&"string"==typeof O.name&&!gv(O)}function tf(O){if(!ju(O))return!1;var $=Lo(O);return $==Mr||$==Kr||"[object AsyncFunction]"==$||"[object Proxy]"==$}function Qc(O){return"number"==typeof O&&O==$l(O)}function wp(O){return"number"==typeof O&&O>-1&&O%1==0&&O<=it}function ju(O){var $=typeof O;return null!=O&&("object"==$||"function"==$)}function Ic(O){return null!=O&&"object"==typeof O}var D0=rt?yu(rt):function(O){return Ic(O)&&Pc(O)==ei};function P0(O){return"number"==typeof O||Ic(O)&&Lo(O)==Nn}function gv(O){if(!Ic(O)||Lo(O)!=Br)return!1;var $=al(O);if(null===$)return!0;var pe=Js.call($,"constructor")&&$.constructor;return"function"==typeof pe&&pe instanceof pe&&Bl.call(pe)==td}var Wg=Pt?yu(Pt):function(O){return Ic(O)&&Lo(O)==ki},f1=dt?yu(dt):function(O){return Ic(O)&&Pc(O)==Hi};function p1(O){return"string"==typeof O||!ui(O)&&Ic(O)&&Lo(O)==Zr}function Gu(O){return"symbol"==typeof O||Ic(O)&&Lo(O)==Cn}var Nm=Te?yu(Te):function(O){return Ic(O)&&wp(O.length)&&!!wo[Lo(O)]},gS=s_(bi),L0=s_(function(O,$){return O<=$});function Pm(O){if(!O)return[];if(Vo(O))return p1(O)?un(O):vi(O);if(Ce&&O[Ce])return function(In){for(var Cr,hr=[];!(Cr=In.next()).done;)hr.push(Cr.value);return hr}(O[Ce]());var $=Pc(O);return($==ei?El:$==Hi?V:km)(O)}function Xh(O){return O?(O=Ef(O))===Vt||O===-Vt?17976931348623157e292*(O<0?-1:1):O==O?O:0:0===O?O:0}function $l(O){var $=Xh(O),pe=$%1;return $==$?pe?$-pe:$:0}function vb(O){return O?bu($l(O),0,Zt):0}function Ef(O){if("number"==typeof O)return O;if(Gu(O))return NaN;if(ju(O)){var $="function"==typeof O.valueOf?O.valueOf():O;O=ju($)?$+"":$}if("string"!=typeof O)return 0===O?O:+O;O=Mu(O);var pe=lr.test(O);return pe||er.test(O)?bc(O.slice(2),pe?2:8):Bn.test(O)?NaN:+O}function mS(O){return zi(O,sd(O))}function Vu(O){return null==O?"":Ed(O)}var yb=Rs(function(O,$){if(Ud($)||Vo($))zi($,Md($),O);else for(var pe in $)Js.call($,pe)&&_u(O,pe,$[pe])}),F0=Rs(function(O,$){zi($,sd($),O)}),mv=Rs(function(O,$,pe,Ke){zi($,sd($),O,Ke)}),bb=Rs(function(O,$,pe,Ke){zi($,Md($),O,Ke)}),eg=mp(Rc),Eb=fl(function(O,$){O=Qs(O);var pe=-1,Ke=$.length,Ht=Ke>2?$[2]:u;for(Ht&&gc($[0],$[1],Ht)&&(Ke=1);++pe<Ke;)for(var pn=$[pe],Kn=sd(pn),Sr=-1,qr=Kn.length;++Sr<qr;){var no=Kn[Sr],ro=O[no];(ro===u||at(ro,pa[no])&&!Js.call(O,no))&&(O[no]=pn[no])}return O}),Tb=fl(function(O){return O.push(u,lh),Me(Og,u,O)});function _1(O,$,pe){var Ke=null==O?u:Pi(O,$);return Ke===u?pe:Ke}function $0(O,$){return null!=O&&j_(O,$,dl)}var yv=jf(function(O,$,pe){null!=$&&"function"!=typeof $.toString&&($=Nl.call($)),O[$]=pe},ry(Nf)),H0=jf(function(O,$,pe){null!=$&&"function"!=typeof $.toString&&($=Nl.call($)),Js.call(O,$)?O[$].push(pe):O[$]=[pe]},Ds),bS=fl(il);function Md(O){return Vo(O)?wf(O):Qt(O)}function sd(O){return Vo(O)?wf(O,!0):function(O){if(!ju(O))return function(O){var $=[];if(null!=O)for(var pe in Qs(O))$.push(pe);return $}(O);var $=Ud(O),pe=[];for(var Ke in O)"constructor"==Ke&&($||!Js.call(O,Ke))||pe.push(Ke);return pe}(O)}var Qg=Rs(function(O,$,pe){_l(O,$,pe)}),Og=Rs(function(O,$,pe,Ke){_l(O,$,pe,Ke)}),Mb=mp(function(O,$){var pe={};if(null==O)return pe;var Ke=!1;$=Ts($,function(pn){return pn=Zf(pn,O),Ke||(Ke=pn.length>1),pn}),zi(O,d_(O),pe),Ke&&(pe=h(pe,7,u_));for(var Ht=$.length;Ht--;)Ph(pe,$[Ht]);return pe}),Ob=mp(function(O,$){return null==O?{}:function(O,$){return Hp(O,$,function(pe,Ke){return $0(O,Ke)})}(O,$)});function wg(O,$){if(null==O)return{};var pe=Ts(d_(O),function(Ke){return[Ke]});return $=Ds($),Hp(O,pe,function(Ke,Ht){return $(Ke,Ht[0])})}var Ac=a_(Md),bv=a_(sd);function km(O){return null==O?[]:lu(O,Md(O))}var Z0=wu(function(O,$,pe){return $=$.toLowerCase(),O+(pe?v1($):$)});function v1(O){return ey(Vu(O).toLowerCase())}function j0(O){return(O=Vu(O))&&O.replace(uo,uu).replace($e,"")}var G0=wu(function(O,$,pe){return O+(pe?"-":"")+$.toLowerCase()}),V0=wu(function(O,$,pe){return O+(pe?" ":"")+$.toLowerCase()}),z0=nd("toLowerCase"),SS=wu(function(O,$,pe){return O+(pe?"_":"")+$.toLowerCase()}),Lb=wu(function(O,$,pe){return O+(pe?" ":"")+ey($)}),OS=wu(function(O,$,pe){return O+(pe?" ":"")+$.toUpperCase()}),ey=nd("toUpperCase");function $b(O,$,pe){return O=Vu(O),($=pe?u:$)===u?function(In){return pi.test(In)}(O)?function(In){return In.match(an)||[]}(O):function(In){return In.match(os)||[]}(O):O.match($)||[]}var E1=fl(function(O,$){try{return Me(O,u,$)}catch(pe){return K_(pe)?pe:new ys(pe)}}),Ev=mp(function(O,$){return Ct($,function(pe){pe=Bc(pe),Ou(O,pe,Mp(O[pe],O))}),O});function ry(O){return function(){return O}}var T1=ah(),Hb=ah(!0);function Nf(O){return O}function S1(O){return Tt("function"==typeof O?O:h(O,1))}var Yb=fl(function(O,$){return function(pe){return il(pe,O,$)}}),Zb=fl(function(O,$){return function(pe){return il(O,pe,$)}});function C1(O,$,pe){var Ke=Md($),Ht=Gr($,Ke);null==pe&&(!ju($)||!Ht.length&&Ke.length)&&(pe=$,$=O,O=this,Ht=Gr($,Md($)));var pn=!(ju(pe)&&"chain"in pe&&!pe.chain),Kn=tf(O);return Ct(Ht,function(Sr){var qr=$[Sr];O[Sr]=qr,Kn&&(O.prototype[Sr]=function(){var no=this.__chain__;if(pn||no){var ro=O(this.__wrapped__),mo=ro.__actions__=vi(this.__actions__);return mo.push({func:qr,args:arguments,thisArg:O}),ro.__chain__=no,ro}return qr.apply(O,Ma([this.value()],arguments))})}),O}function tg(){}var mh=fg(Ts),Hm=fg(Qi),jb=fg(Rl);function sy(O){return $h(O)?rc(Bc(O)):function(O){return function($){return Pi($,O)}}(O)}var Kh=U_(),Um=U_(!0);function nf(){return[]}function A_(){return!1}var em=H_(function(O,$){return O+$},0),tm=Wc("ceil"),nm=H_(function(O,$){return O/$},1),rm=Wc("floor"),ng=H_(function(O,$){return O*$},1),Cv=Wc("round"),w1=H_(function(O,$){return O-$},0);return en.after=function(O,$){if("function"!=typeof $)throw new Gl(_);return O=$l(O),function(){if(--O<1)return $.apply(this,arguments)}},en.ary=jg,en.assign=yb,en.assignIn=F0,en.assignInWith=mv,en.assignWith=bb,en.at=eg,en.before=fv,en.bind=Mp,en.bindAll=Ev,en.bindKey=wm,en.castArray=function(){if(!arguments.length)return[];var O=arguments[0];return ui(O)?O:[O]},en.chain=io,en.chunk=function(O,$,pe){$=(pe?gc(O,$,pe):$===u)?1:ga($l($),0);var Ke=null==O?0:O.length;if(!Ke||$<1)return[];for(var Ht=0,pn=0,Kn=hr(Ei(Ke/$));Ht<Ke;)Kn[pn++]=bd(O,Ht,Ht+=$);return Kn},en.compact=function(O){for(var $=-1,pe=null==O?0:O.length,Ke=0,Ht=[];++$<pe;){var pn=O[$];pn&&(Ht[Ke++]=pn)}return Ht},en.concat=function(){var O=arguments.length;if(!O)return[];for(var $=hr(O-1),pe=arguments[0],Ke=O;Ke--;)$[Ke-1]=arguments[Ke];return Ma(ui(pe)?vi(pe):[pe],yt($,1))},en.cond=function(O){var $=null==O?0:O.length,pe=Ds();return O=$?Ts(O,function(Ke){if("function"!=typeof Ke[1])throw new Gl(_);return[pe(Ke[0]),Ke[1]]}):[],fl(function(Ke){for(var Ht=-1;++Ht<$;){var pn=O[Ht];if(Me(pn[0],this,Ke))return Me(pn[1],this,Ke)}})},en.conforms=function(O){return function(O){var $=Md(O);return function(pe){return R(pe,O,$)}}(h(O,1))},en.constant=ry,en.countBy=iv,en.create=function(O,$){var pe=Oc(O);return null==$?pe:cu(pe,$)},en.curry=function pv(O,$,pe){var Ke=ep(O,8,u,u,u,u,u,$=pe?u:$);return Ke.placeholder=pv.placeholder,Ke},en.curryRight=function a1(O,$,pe){var Ke=ep(O,16,u,u,u,u,u,$=pe?u:$);return Ke.placeholder=a1.placeholder,Ke},en.debounce=Gg,en.defaults=Eb,en.defaultsDeep=Tb,en.defer=l1,en.delay=hv,en.difference=bm,en.differenceBy=m_,en.differenceWith=Zp,en.drop=function(O,$,pe){var Ke=null==O?0:O.length;return Ke?bd(O,($=pe||$===u?1:$l($))<0?0:$,Ke):[]},en.dropRight=function(O,$,pe){var Ke=null==O?0:O.length;return Ke?bd(O,0,($=Ke-($=pe||$===u?1:$l($)))<0?0:$):[]},en.dropRightWhile=function(O,$){return O&&O.length?ih(O,Ds($,3),!0,!0):[]},en.dropWhile=function(O,$){return O&&O.length?ih(O,Ds($,3),!0):[]},en.fill=function(O,$,pe,Ke){var Ht=null==O?0:O.length;return Ht?(pe&&"number"!=typeof pe&&gc(O,$,pe)&&(pe=0,Ke=Ht),function(O,$,pe,Ke){var Ht=O.length;for((pe=$l(pe))<0&&(pe=-pe>Ht?0:Ht+pe),(Ke=Ke===u||Ke>Ht?Ht:$l(Ke))<0&&(Ke+=Ht),Ke=pe>Ke?0:vb(Ke);pe<Ke;)O[pe++]=$;return O}(O,$,pe,Ke)):[]},en.filter=function(O,$){return(ui(O)?Go:gt)(O,Ds($,3))},en.flatMap=function(O,$){return yt(Am(O,$),1)},en.flatMapDeep=function(O,$){return yt(Am(O,$),Vt)},en.flatMapDepth=function(O,$,pe){return pe=pe===u?1:$l(pe),yt(Am(O,$),pe)},en.flatten=z_,en.flattenDeep=function(O){return null!=O&&O.length?yt(O,Vt):[]},en.flattenDepth=function(O,$){return null!=O&&O.length?yt(O,$=$===u?1:$l($)):[]},en.flip=function(O){return ep(O,512)},en.flow=T1,en.flowRight=Hb,en.fromPairs=function(O){for(var $=-1,pe=null==O?0:O.length,Ke={};++$<pe;){var Ht=O[$];Ke[Ht[0]]=Ht[1]}return Ke},en.functions=function(O){return null==O?[]:Gr(O,Md(O))},en.functionsIn=function(O){return null==O?[]:Gr(O,sd(O))},en.groupBy=mc,en.initial=function(O){return null!=O&&O.length?bd(O,0,-1):[]},en.intersection=yg,en.intersectionBy=Yg,en.intersectionWith=Sp,en.invert=yv,en.invertBy=H0,en.invokeMap=Fu,en.iteratee=S1,en.keyBy=s1,en.keys=Md,en.keysIn=sd,en.map=Am,en.mapKeys=function(O,$){var pe={};return $=Ds($,3),xn(O,function(Ke,Ht,pn){Ou(pe,$(Ke,Ht,pn),Ke)}),pe},en.mapValues=function(O,$){var pe={};return $=Ds($,3),xn(O,function(Ke,Ht,pn){Ou(pe,Ht,$(Ke,Ht,pn))}),pe},en.matches=function(O){return xa(h(O,1))},en.matchesProperty=function(O,$){return na(O,h($,1))},en.memoize=Cg,en.merge=Qg,en.mergeWith=Og,en.method=Yb,en.methodOf=Zb,en.mixin=C1,en.negate=Ap,en.nthArg=function(O){return O=$l(O),fl(function($){return zc($,O)})},en.omit=Mb,en.omitBy=function(O,$){return wg(O,Ap(Ds($)))},en.once=function(O){return fv(2,O)},en.orderBy=function(O,$,pe,Ke){return null==O?[]:(ui($)||($=null==$?[]:[$]),ui(pe=Ke?u:pe)||(pe=null==pe?[]:[pe]),qf(O,$,pe))},en.over=mh,en.overArgs=Jh,en.overEvery=Hm,en.overSome=jb,en.partial=Vp,en.partialRight=X_,en.partition=Qo,en.pick=Ob,en.pickBy=wg,en.property=sy,en.propertyOf=function(O){return function($){return null==O?u:Pi(O,$)}},en.pull=Zh,en.pullAll=bg,en.pullAllBy=function(O,$,pe){return O&&O.length&&$&&$.length?mf(O,$,Ds(pe,2)):O},en.pullAllWith=function(O,$,pe){return O&&O.length&&$&&$.length?mf(O,$,u,pe):O},en.pullAt=b_,en.range=Kh,en.rangeRight=Um,en.rearg=C_,en.reject=function(O,$){return(ui(O)?Go:gt)(O,Ap(Ds($,3)))},en.remove=function(O,$){var pe=[];if(!O||!O.length)return pe;var Ke=-1,Ht=[],pn=O.length;for($=Ds($,3);++Ke<pn;){var Kn=O[Ke];$(Kn,Ke,O)&&(pe.push(Kn),Ht.push(Ke))}return Uf(O,Ht),pe},en.rest=function(O,$){if("function"!=typeof O)throw new Gl(_);return fl(O,$=$===u?$:$l($))},en.reverse=E_,en.sampleSize=function(O,$,pe){return $=(pe?gc(O,$,pe):$===u)?1:$l($),(ui(O)?Id:F_)(O,$)},en.set=function(O,$,pe){return null==O?O:Bf(O,$,pe)},en.setWith=function(O,$,pe,Ke){return Ke="function"==typeof Ke?Ke:u,null==O?O:Bf(O,$,pe,Ke)},en.shuffle=function(O){return(ui(O)?oc:eh)(O)},en.slice=function(O,$,pe){var Ke=null==O?0:O.length;return Ke?(pe&&"number"!=typeof pe&&gc(O,$,pe)?($=0,pe=Ke):($=null==$?0:$l($),pe=pe===u?Ke:$l(pe)),bd(O,$,pe)):[]},en.sortBy=dv,en.sortedUniq=function(O){return O&&O.length?Nh(O):[]},en.sortedUniqBy=function(O,$){return O&&O.length?Nh(O,Ds($,2)):[]},en.split=function(O,$,pe){return pe&&"number"!=typeof pe&&gc(O,$,pe)&&($=pe=u),(pe=pe===u?Zt:pe>>>0)?(O=Vu(O))&&("string"==typeof $||null!=$&&!Wg($))&&!($=Ed($))&&aa(O)?ac(un(O),0,pe):O.split($,pe):[]},en.spread=function(O,$){if("function"!=typeof O)throw new Gl(_);return $=null==$?0:ga($l($),0),fl(function(pe){var Ke=pe[$],Ht=ac(pe,0,$);return Ke&&Ma(Ht,Ke),Me(O,this,Ht)})},en.tail=function(O){var $=null==O?0:O.length;return $?bd(O,1,$):[]},en.take=function(O,$,pe){return O&&O.length?bd(O,0,($=pe||$===u?1:$l($))<0?0:$):[]},en.takeRight=function(O,$,pe){var Ke=null==O?0:O.length;return Ke?bd(O,($=Ke-($=pe||$===u?1:$l($)))<0?0:$,Ke):[]},en.takeRightWhile=function(O,$){return O&&O.length?ih(O,Ds($,3),!1,!0):[]},en.takeWhile=function(O,$){return O&&O.length?ih(O,Ds($,3)):[]},en.tap=function(O,$){return $(O),O},en.throttle=function(O,$,pe){var Ke=!0,Ht=!0;if("function"!=typeof O)throw new Gl(_);return ju(pe)&&(Ke="leading"in pe?!!pe.leading:Ke,Ht="trailing"in pe?!!pe.trailing:Ht),Gg(O,$,{leading:Ke,maxWait:$,trailing:Ht})},en.thru=Cs,en.toArray=Pm,en.toPairs=Ac,en.toPairsIn=bv,en.toPath=function(O){return ui(O)?Ts(O,Bc):Gu(O)?[O]:vi(__(Vu(O)))},en.toPlainObject=mS,en.transform=function(O,$,pe){var Ke=ui(O),Ht=Ke||ql(O)||Nm(O);if($=Ds($,4),null==pe){var pn=O&&O.constructor;pe=Ht?Ke?new pn:[]:ju(O)&&tf(pn)?Oc(al(O)):{}}return(Ht?Ct:xn)(O,function(Kn,Sr,qr){return $(pe,Kn,Sr,qr)}),pe},en.unary=function(O){return jg(O,1)},en.union=We,en.unionBy=Nt,en.unionWith=rn,en.uniq=function(O){return O&&O.length?xf(O):[]},en.uniqBy=function(O,$){return O&&O.length?xf(O,Ds($,2)):[]},en.uniqWith=function(O,$){return $="function"==typeof $?$:u,O&&O.length?xf(O,u,$):[]},en.unset=function(O,$){return null==O||Ph(O,$)},en.unzip=as,en.unzipWith=Ha,en.update=function(O,$,pe){return null==O?O:Bp(O,$,hp(pe))},en.updateWith=function(O,$,pe,Ke){return Ke="function"==typeof Ke?Ke:u,null==O?O:Bp(O,$,hp(pe),Ke)},en.values=km,en.valuesIn=function(O){return null==O?[]:lu(O,sd(O))},en.without=go,en.words=$b,en.wrap=function(O,$){return Vp(hp($),O)},en.xor=po,en.xorBy=Fa,en.xorWith=Ta,en.zip=ni,en.zipObject=function(O,$){return Lh(O||[],$||[],_u)},en.zipObjectDeep=function(O,$){return Lh(O||[],$||[],Bf)},en.zipWith=Bi,en.entries=Ac,en.entriesIn=bv,en.extend=F0,en.extendWith=mv,C1(en,en),en.add=em,en.attempt=E1,en.camelCase=Z0,en.capitalize=v1,en.ceil=tm,en.clamp=function(O,$,pe){return pe===u&&(pe=$,$=u),pe!==u&&(pe=(pe=Ef(pe))==pe?pe:0),$!==u&&($=($=Ef($))==$?$:0),bu(Ef(O),$,pe)},en.clone=function(O){return h(O,4)},en.cloneDeep=function(O){return h(O,5)},en.cloneDeepWith=function(O,$){return h(O,5,$="function"==typeof $?$:u)},en.cloneWith=function(O,$){return h(O,4,$="function"==typeof $?$:u)},en.conformsTo=function(O,$){return null==$||R(O,$,Md($))},en.deburr=j0,en.defaultTo=function(O,$){return null==O||O!=O?$:O},en.divide=nm,en.endsWith=function(O,$,pe){O=Vu(O),$=Ed($);var Ke=O.length,Ht=pe=pe===u?Ke:bu($l(pe),0,Ke);return(pe-=$.length)>=0&&O.slice(pe,Ht)==$},en.eq=at,en.escape=function(O){return(O=Vu(O))&&Ge.test(O)?O.replace(Yt,wr):O},en.escapeRegExp=function(O){return(O=Vu(O))&&ar.test(O)?O.replace(Fn,"\\$&"):O},en.every=function(O,$,pe){var Ke=ui(O)?Qi:Ue;return pe&&gc(O,$,pe)&&($=u),Ke(O,Ds($,3))},en.find=o1,en.findIndex=vg,en.findKey=function(O,$){return Lc(O,Ds($,3),xn)},en.findLast=_b,en.findLastIndex=Ug,en.findLastKey=function(O,$){return Lc(O,Ds($,3),ir)},en.floor=rm,en.forEach=av,en.forEachRight=Mm,en.forIn=function(O,$){return null==O?O:nn(O,Ds($,3),sd)},en.forInRight=function(O,$){return null==O?O:Pn(O,Ds($,3),sd)},en.forOwn=function(O,$){return O&&xn(O,Ds($,3))},en.forOwnRight=function(O,$){return O&&ir(O,Ds($,3))},en.get=_1,en.gt=$t,en.gte=jn,en.has=function(O,$){return null!=O&&j_(O,$,Xs)},en.hasIn=$0,en.head=W_,en.identity=Nf,en.includes=function(O,$,pe,Ke){O=Vo(O)?O:km(O),pe=pe&&!Ke?$l(pe):0;var Ht=O.length;return pe<0&&(pe=ga(Ht+pe,0)),p1(O)?pe<=Ht&&O.indexOf($,pe)>-1:!!Ht&&Fc(O,$,pe)>-1},en.indexOf=function(O,$,pe){var Ke=null==O?0:O.length;if(!Ke)return-1;var Ht=null==pe?0:$l(pe);return Ht<0&&(Ht=ga(Ke+Ht,0)),Fc(O,$,Ht)},en.inRange=function(O,$,pe){return $=Xh($),pe===u?(pe=$,$=0):pe=Xh(pe),function(O,$,pe){return O>=Ol($,pe)&&O<ga($,pe)}(O=Ef(O),$,pe)},en.invoke=bS,en.isArguments=fr,en.isArray=ui,en.isArrayBuffer=Ro,en.isArrayLike=Vo,en.isArrayLikeObject=Ms,en.isBoolean=function(O){return!0===O||!1===O||Ic(O)&&Lo(O)==Zn},en.isBuffer=ql,en.isDate=eu,en.isElement=function(O){return Ic(O)&&1===O.nodeType&&!gv(O)},en.isEmpty=function(O){if(null==O)return!0;if(Vo(O)&&(ui(O)||"string"==typeof O||"function"==typeof O.splice||ql(O)||Nm(O)||fr(O)))return!O.length;var $=Pc(O);if($==ei||$==Hi)return!O.size;if(Ud(O))return!Qt(O).length;for(var pe in O)if(Js.call(O,pe))return!1;return!0},en.isEqual=function(O,$){return gu(O,$)},en.isEqualWith=function(O,$,pe){var Ke=(pe="function"==typeof pe?pe:u)?pe(O,$):u;return Ke===u?gu(O,$,u,pe):!!Ke},en.isError=K_,en.isFinite=function(O){return"number"==typeof O&&Oa(O)},en.isFunction=tf,en.isInteger=Qc,en.isLength=wp,en.isMap=D0,en.isMatch=function(O,$){return O===$||gf(O,$,uh($))},en.isMatchWith=function(O,$,pe){return pe="function"==typeof pe?pe:u,gf(O,$,uh($),pe)},en.isNaN=function(O){return P0(O)&&O!=+O},en.isNative=function(O){if(Vf(O))throw new ys("Unsupported core-js use. Try https://npms.io/search?q=ponyfill.");return Ga(O)},en.isNil=function(O){return null==O},en.isNull=function(O){return null===O},en.isNumber=P0,en.isObject=ju,en.isObjectLike=Ic,en.isPlainObject=gv,en.isRegExp=Wg,en.isSafeInteger=function(O){return Qc(O)&&O>=-it&&O<=it},en.isSet=f1,en.isString=p1,en.isSymbol=Gu,en.isTypedArray=Nm,en.isUndefined=function(O){return O===u},en.isWeakMap=function(O){return Ic(O)&&Pc(O)==zn},en.isWeakSet=function(O){return Ic(O)&&"[object WeakSet]"==Lo(O)},en.join=function(O,$){return null==O?"":Hs.call(O,$)},en.kebabCase=G0,en.last=Jc,en.lastIndexOf=function(O,$,pe){var Ke=null==O?0:O.length;if(!Ke)return-1;var Ht=Ke;return pe!==u&&(Ht=(Ht=$l(pe))<0?ga(Ke+Ht,0):Ol(Ht,Ke-1)),$==$?function(In,Cr,hr){for(var ao=hr+1;ao--;)if(In[ao]===Cr)return ao;return ao}(O,$,Ht):Tc(O,kc,Ht,!0)},en.lowerCase=V0,en.lowerFirst=z0,en.lt=gS,en.lte=L0,en.max=function(O){return O&&O.length?Oe(O,Nf,Gs):u},en.maxBy=function(O,$){return O&&O.length?Oe(O,Ds($,2),Gs):u},en.mean=function(O){return gd(O,Nf)},en.meanBy=function(O,$){return gd(O,Ds($,2))},en.min=function(O){return O&&O.length?Oe(O,Nf,bi):u},en.minBy=function(O,$){return O&&O.length?Oe(O,Ds($,2),bi):u},en.stubArray=nf,en.stubFalse=A_,en.stubObject=function(){return{}},en.stubString=function(){return""},en.stubTrue=function(){return!0},en.multiply=ng,en.nth=function(O,$){return O&&O.length?zc(O,$l($)):u},en.noConflict=function(){return Hl._===this&&(Hl._=zd),this},en.noop=tg,en.now=Q_,en.pad=function(O,$,pe){O=Vu(O);var Ke=($=$l($))?ut(O):0;if(!$||Ke>=$)return O;var Ht=($-Ke)/2;return gp(Yo(Ht),pe)+O+gp(Ei(Ht),pe)},en.padEnd=function(O,$,pe){O=Vu(O);var Ke=($=$l($))?ut(O):0;return $&&Ke<$?O+gp($-Ke,pe):O},en.padStart=function(O,$,pe){O=Vu(O);var Ke=($=$l($))?ut(O):0;return $&&Ke<$?gp($-Ke,pe)+O:O},en.parseInt=function(O,$,pe){return pe||null==$?$=0:$&&($=+$),Za(Vu(O).replace(Wi,""),$||0)},en.random=function(O,$,pe){if(pe&&"boolean"!=typeof pe&&gc(O,$,pe)&&($=pe=u),pe===u&&("boolean"==typeof $?(pe=$,$=u):"boolean"==typeof O&&(pe=O,O=u)),O===u&&$===u?(O=0,$=1):(O=Xh(O),$===u?($=O,O=0):$=Xh($)),O>$){var Ke=O;O=$,$=Ke}if(pe||O%1||$%1){var Ht=ja();return Ol(O+Ht*($-O+Nu("1e-"+((Ht+"").length-1))),$)}return dd(O,$)},en.reduce=function(O,$,pe){var Ke=ui(O)?au:sa,Ht=arguments.length<3;return Ke(O,Ds($,4),pe,Ht,de)},en.reduceRight=function(O,$,pe){var Ke=ui(O)?Wa:sa,Ht=arguments.length<3;return Ke(O,Ds($,4),pe,Ht,ye)},en.repeat=function(O,$,pe){return $=(pe?gc(O,$,pe):$===u)?1:$l($),pp(Vu(O),$)},en.replace=function(){var O=arguments,$=Vu(O[0]);return O.length<3?$:$.replace(O[1],O[2])},en.result=function(O,$,pe){var Ke=-1,Ht=($=Zf($,O)).length;for(Ht||(Ht=1,O=u);++Ke<Ht;){var pn=null==O?u:O[Bc($[Ke])];pn===u&&(Ke=Ht,pn=pe),O=tf(pn)?pn.call(O):pn}return O},en.round=Cv,en.runInContext=In,en.sample=function(O){return(ui(O)?Vl:i_)(O)},en.size=function(O){if(null==O)return 0;if(Vo(O))return p1(O)?ut(O):O.length;var $=Pc(O);return $==ei||$==Hi?O.size:Qt(O).length},en.snakeCase=SS,en.some=function(O,$,pe){var Ke=ui(O)?Rl:Rh;return pe&&gc(O,$,pe)&&($=u),Ke(O,Ds($,3))},en.sortedIndex=function(O,$){return th(O,$)},en.sortedIndexBy=function(O,$,pe){return nh(O,$,Ds(pe,2))},en.sortedIndexOf=function(O,$){var pe=null==O?0:O.length;if(pe){var Ke=th(O,$);if(Ke<pe&&at(O[Ke],$))return Ke}return-1},en.sortedLastIndex=function(O,$){return th(O,$,!0)},en.sortedLastIndexBy=function(O,$,pe){return nh(O,$,Ds(pe,2),!0)},en.sortedLastIndexOf=function(O,$){if(null!=O&&O.length){var Ke=th(O,$,!0)-1;if(at(O[Ke],$))return Ke}return-1},en.startCase=Lb,en.startsWith=function(O,$,pe){return O=Vu(O),pe=null==pe?0:bu($l(pe),0,O.length),$=Ed($),O.slice(pe,pe+$.length)==$},en.subtract=w1,en.sum=function(O){return O&&O.length?Ss(O,Nf):0},en.sumBy=function(O,$){return O&&O.length?Ss(O,Ds($,2)):0},en.template=function(O,$,pe){var Ke=en.templateSettings;pe&&gc(O,$,pe)&&($=u),O=Vu(O),$=mv({},$,Ke,l_);var Sr,qr,Ht=mv({},$.imports,Ke.imports,l_),pn=Md(Ht),Kn=lu(Ht,pn),no=0,ro=$.interpolate||Ci,mo="__p += '",ds=ed(($.escape||Ci).source+"|"+ro.source+"|"+(ro===An?Mi:Ci).source+"|"+($.evaluate||Ci).source+"|$","g"),oa="//# sourceURL="+(Js.call($,"sourceURL")?($.sourceURL+"").replace(/\s/g," "):"lodash.templateSources["+ ++ts+"]")+"\n";O.replace(ds,function(Va,su,vu,xp,op,Dp){return vu||(vu=xp),mo+=O.slice(no,Dp).replace($o,fa),su&&(Sr=!0,mo+="' +\n__e("+su+") +\n'"),op&&(qr=!0,mo+="';\n"+op+";\n__p += '"),vu&&(mo+="' +\n((__t = ("+vu+")) == null ? '' : __t) +\n'"),no=Dp+Va.length,Va}),mo+="';\n";var Ia=Js.call($,"variable")&&$.variable;if(Ia){if(jo.test(Ia))throw new ys("Invalid `variable` option passed into `_.template`")}else mo="with (obj) {\n"+mo+"\n}\n";mo=(qr?mo.replace(Vn,""):mo).replace(mr,"$1").replace(Dn,"$1;"),mo="function("+(Ia||"obj")+") {\n"+(Ia?"":"obj || (obj = {});\n")+"var __t, __p = ''"+(Sr?", __e = _.escape":"")+(qr?", __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\n":";\n")+mo+"return __p\n}";var Pl=E1(function(){return Na(pn,oa+"return "+mo).apply(u,Kn)});if(Pl.source=mo,K_(Pl))throw Pl;return Pl},en.times=function(O,$){if((O=$l(O))<1||O>it)return[];var pe=Zt,Ke=Ol(O,Zt);$=Ds($),O-=Zt;for(var Ht=$u(Ke,$);++pe<O;)$(pe);return Ht},en.toFinite=Xh,en.toInteger=$l,en.toLength=vb,en.toLower=function(O){return Vu(O).toLowerCase()},en.toNumber=Ef,en.toSafeInteger=function(O){return O?bu($l(O),-it,it):0===O?O:0},en.toString=Vu,en.toUpper=function(O){return Vu(O).toUpperCase()},en.trim=function(O,$,pe){if((O=Vu(O))&&(pe||$===u))return Mu(O);if(!O||!($=Ed($)))return O;var Ke=un(O),Ht=un($);return ac(Ke,Hu(Ke,Ht),Uu(Ke,Ht)+1).join("")},en.trimEnd=function(O,$,pe){if((O=Vu(O))&&(pe||$===u))return O.slice(0,mn(O)+1);if(!O||!($=Ed($)))return O;var Ke=un(O);return ac(Ke,0,Uu(Ke,un($))+1).join("")},en.trimStart=function(O,$,pe){if((O=Vu(O))&&(pe||$===u))return O.replace(Wi,"");if(!O||!($=Ed($)))return O;var Ke=un(O);return ac(Ke,Hu(Ke,un($))).join("")},en.truncate=function(O,$){var pe=30,Ke="...";if(ju($)){var Ht="separator"in $?$.separator:Ht;pe="length"in $?$l($.length):pe,Ke="omission"in $?Ed($.omission):Ke}var pn=(O=Vu(O)).length;if(aa(O)){var Kn=un(O);pn=Kn.length}if(pe>=pn)return O;var Sr=pe-ut(Ke);if(Sr<1)return Ke;var qr=Kn?ac(Kn,0,Sr).join(""):O.slice(0,Sr);if(Ht===u)return qr+Ke;if(Kn&&(Sr+=qr.length-Sr),Wg(Ht)){if(O.slice(Sr).search(Ht)){var no,ro=qr;for(Ht.global||(Ht=ed(Ht.source,Vu(li.exec(Ht))+"g")),Ht.lastIndex=0;no=Ht.exec(ro);)var mo=no.index;qr=qr.slice(0,mo===u?Sr:mo)}}else if(O.indexOf(Ed(Ht),Sr)!=Sr){var ds=qr.lastIndexOf(Ht);ds>-1&&(qr=qr.slice(0,ds))}return qr+Ke},en.unescape=function(O){return(O=Vu(O))&&_n.test(O)?O.replace(Pr,Or):O},en.uniqueId=function(O){var $=++md;return Vu(O)+$},en.upperCase=OS,en.upperFirst=ey,en.each=av,en.eachRight=Mm,en.first=W_,C1(en,function(){var O={};return xn(en,function($,pe){Js.call(en.prototype,pe)||(O[pe]=$)}),O}(),{chain:!1}),en.VERSION="4.17.21",Ct(["bind","bindKey","curry","curryRight","partial","partialRight"],function(O){en[O].placeholder=en}),Ct(["drop","take"],function(O,$){nl.prototype[O]=function(pe){pe=pe===u?1:ga($l(pe),0);var Ke=this.__filtered__&&!$?new nl(this):this.clone();return Ke.__filtered__?Ke.__takeCount__=Ol(pe,Ke.__takeCount__):Ke.__views__.push({size:Ol(pe,Zt),type:O+(Ke.__dir__<0?"Right":"")}),Ke},nl.prototype[O+"Right"]=function(pe){return this.reverse()[O](pe).reverse()}}),Ct(["filter","map","takeWhile"],function(O,$){var pe=$+1,Ke=1==pe||3==pe;nl.prototype[O]=function(Ht){var pn=this.clone();return pn.__iteratees__.push({iteratee:Ds(Ht,3),type:pe}),pn.__filtered__=pn.__filtered__||Ke,pn}}),Ct(["head","last"],function(O,$){var pe="take"+($?"Right":"");nl.prototype[O]=function(){return this[pe](1).value()[0]}}),Ct(["initial","tail"],function(O,$){var pe="drop"+($?"":"Right");nl.prototype[O]=function(){return this.__filtered__?new nl(this):this[pe](1)}}),nl.prototype.compact=function(){return this.filter(Nf)},nl.prototype.find=function(O){return this.filter(O).head()},nl.prototype.findLast=function(O){return this.reverse().find(O)},nl.prototype.invokeMap=fl(function(O,$){return"function"==typeof O?new nl(this):this.map(function(pe){return il(pe,O,$)})}),nl.prototype.reject=function(O){return this.filter(Ap(Ds(O)))},nl.prototype.slice=function(O,$){O=$l(O);var pe=this;return pe.__filtered__&&(O>0||$<0)?new nl(pe):(O<0?pe=pe.takeRight(-O):O&&(pe=pe.drop(O)),$!==u&&(pe=($=$l($))<0?pe.dropRight(-$):pe.take($-O)),pe)},nl.prototype.takeRightWhile=function(O){return this.reverse().takeWhile(O).reverse()},nl.prototype.toArray=function(){return this.take(Zt)},xn(nl.prototype,function(O,$){var pe=/^(?:filter|find|map|reject)|While$/.test($),Ke=/^(?:head|last)$/.test($),Ht=en[Ke?"take"+("last"==$?"Right":""):$],pn=Ke||/^find/.test($);!Ht||(en.prototype[$]=function(){var Kn=this.__wrapped__,Sr=Ke?[1]:arguments,qr=Kn instanceof nl,no=Sr[0],ro=qr||ui(Kn),mo=function(su){var vu=Ht.apply(en,Ma([su],Sr));return Ke&&ds?vu[0]:vu};ro&&pe&&"function"==typeof no&&1!=no.length&&(qr=ro=!1);var ds=this.__chain__,oa=!!this.__actions__.length,Ia=pn&&!ds,Pl=qr&&!oa;if(!pn&&ro){Kn=Pl?Kn:new nl(this);var Va=O.apply(Kn,Sr);return Va.__actions__.push({func:Cs,args:[mo],thisArg:u}),new Iu(Va,ds)}return Ia&&Pl?O.apply(this,Sr):(Va=this.thru(mo),Ia?Ke?Va.value()[0]:Va.value():Va)})}),Ct(["pop","push","shift","sort","splice","unshift"],function(O){var $=$i[O],pe=/^(?:push|sort|unshift)$/.test(O)?"tap":"thru",Ke=/^(?:pop|shift)$/.test(O);en.prototype[O]=function(){var Ht=arguments;if(Ke&&!this.__chain__){var pn=this.value();return $.apply(ui(pn)?pn:[],Ht)}return this[pe](function(Kn){return $.apply(ui(Kn)?Kn:[],Ht)})}}),xn(nl.prototype,function(O,$){var pe=en[$];if(pe){var Ke=pe.name+"";Js.call(jc,Ke)||(jc[Ke]=[]),jc[Ke].push({name:$,func:pe})}}),jc[_p(u,2).name]=[{name:"wrapper",func:u}],nl.prototype.clone=function(){var O=new nl(this.__wrapped__);return O.__actions__=vi(this.__actions__),O.__dir__=this.__dir__,O.__filtered__=this.__filtered__,O.__iteratees__=vi(this.__iteratees__),O.__takeCount__=this.__takeCount__,O.__views__=vi(this.__views__),O},nl.prototype.reverse=function(){if(this.__filtered__){var O=new nl(this);O.__dir__=-1,O.__filtered__=!0}else(O=this.clone()).__dir__*=-1;return O},nl.prototype.value=function(){var O=this.__wrapped__.value(),$=this.__dir__,pe=ui(O),Ke=$<0,Ht=pe?O.length:0,pn=function(O,$,pe){for(var Ke=-1,Ht=pe.length;++Ke<Ht;){var pn=pe[Ke],Kn=pn.size;switch(pn.type){case"drop":O+=Kn;break;case"dropRight":$-=Kn;break;case"take":$=Ol($,O+Kn);break;case"takeRight":O=ga(O,$-Kn)}}return{start:O,end:$}}(0,Ht,this.__views__),Kn=pn.start,Sr=pn.end,qr=Sr-Kn,no=Ke?Sr:Kn-1,ro=this.__iteratees__,mo=ro.length,ds=0,oa=Ol(qr,this.__takeCount__);if(!pe||!Ke&&Ht==qr&&oa==qr)return Ih(O,this.__actions__);var Ia=[];e:for(;qr--&&ds<oa;){for(var Pl=-1,Va=O[no+=$];++Pl<mo;){var su=ro[Pl],xp=su.type,op=(0,su.iteratee)(Va);if(2==xp)Va=op;else if(!op){if(1==xp)continue e;break e}}Ia[ds++]=Va}return Ia},en.prototype.at=Qa,en.prototype.chain=function(){return io(this)},en.prototype.commit=function(){return new Iu(this.value(),this.__chain__)},en.prototype.next=function(){this.__values__===u&&(this.__values__=Pm(this.value()));var O=this.__index__>=this.__values__.length;return{done:O,value:O?u:this.__values__[this.__index__++]}},en.prototype.plant=function(O){for(var $,pe=this;pe instanceof Au;){var Ke=_g(pe);Ke.__index__=0,Ke.__values__=u,$?Ht.__wrapped__=Ke:$=Ke;var Ht=Ke;pe=pe.__wrapped__}return Ht.__wrapped__=O,$},en.prototype.reverse=function(){var O=this.__wrapped__;if(O instanceof nl){var $=O;return this.__actions__.length&&($=new nl(this)),($=$.reverse()).__actions__.push({func:Cs,args:[E_],thisArg:u}),new Iu($,this.__chain__)}return this.thru(E_)},en.prototype.toJSON=en.prototype.valueOf=en.prototype.value=function(){return Ih(this.__wrapped__,this.__actions__)},en.prototype.first=en.prototype.head,Ce&&(en.prototype[Ce]=function(){return this}),en}();Hl._=Fo,(r=function(){return Fo}.call(T,i,T,v))!==u&&(v.exports=r)}.call(this)},97425:(v,T,i)=>{var r=i(93177);function p(d,e){if("function"!=typeof d||null!=e&&"function"!=typeof e)throw new TypeError("Expected a function");var _=function(){var y=arguments,S=e?e.apply(this,y):y[0],A=_.cache;if(A.has(S))return A.get(S);var N=d.apply(this,y);return _.cache=A.set(S,N)||A,N};return _.cache=new(p.Cache||r),_}p.Cache=r,v.exports=p},3912:(v,T,i)=>{var r=i(9085),p=i(30906)(function(d,e,_){r(d,e,_)});v.exports=p},30765:(v,T,i)=>{var r=i(27038);v.exports=function(){return r.Date.now()}},12482:(v,T,i)=>{var r=i(14992),u=i(77007),p=i(72064),d=i(64667),e=i(11694),_=i(925),y=i(10058),S=i(51675),Z=y(function(J,K){var ee={};if(null==J)return ee;var ue=!1;K=r(K,function(H){return H=d(H,J),ue||(ue=H.length>1),H}),e(J,S(J),ee),ue&&(ee=u(ee,7,_));for(var ae=K.length;ae--;)p(ee,K[ae]);return ee});v.exports=Z},63354:(v,T,i)=>{var r=i(68840),u=i(59866),p=i(99743),d=i(82773);v.exports=function(_){return p(_)?r(d(_)):u(_)}},86101:(v,T,i)=>{var r=i(89731),u=i(59026),p=i(5245),d=i(85105),e=i(81690);v.exports=function(y,S,A){var N=e(y)?r:d,L=arguments.length<3;return N(y,p(S,4),A,L,u)}},12666:(v,T,i)=>{var r=i(32773);v.exports=function(p,d,e){return null==p?p:r(p,d,e)}},52190:(v,T,i)=>{var r=i(8141),u=i(5245),p=i(37834),d=i(81690),e=i(71100);v.exports=function(y,S,A){var N=d(y)?r:p;return A&&e(y,S,A)&&(S=void 0),N(y,u(S,3))}},65336:v=>{v.exports=function(){return[]}},61711:v=>{v.exports=function(){return!1}},5152:(v,T,i)=>{var r=i(45038),u=1/0;v.exports=function(e){return e?(e=r(e))===u||e===-u?17976931348623157e292*(e<0?-1:1):e==e?e:0:0===e?e:0}},32781:(v,T,i)=>{var r=i(5152);v.exports=function(p){var d=r(p),e=d%1;return d==d?e?d-e:d:0}},69883:(v,T,i)=>{var r=i(41233);v.exports=function(p){return r(p).toLowerCase()}},45038:(v,T,i)=>{var r=i(13743),u=i(53867),p=i(7786),e=/^[-+]0x[0-9a-f]+$/i,_=/^0b[01]+$/i,y=/^0o[0-7]+$/i,S=parseInt;v.exports=function(N){if("number"==typeof N)return N;if(p(N))return NaN;if(u(N)){var L="function"==typeof N.valueOf?N.valueOf():N;N=u(L)?L+"":L}if("string"!=typeof N)return 0===N?N:+N;N=r(N);var Z=_.test(N);return Z||y.test(N)?S(N.slice(2),Z?2:8):e.test(N)?NaN:+N}},31413:(v,T,i)=>{var r=i(11694),u=i(42970);v.exports=function(d){return r(d,u(d))}},41233:(v,T,i)=>{var r=i(68166);v.exports=function(p){return null==p?"":r(p)}},93890:(v,T,i)=>{var u=i(66803)("toUpperCase");v.exports=u},96590:(v,T,i)=>{var r=i(54561),u=i(59316),p=i(41233),d=i(58863);v.exports=function(_,y,S){return _=p(_),void 0===(y=S?void 0:y)?u(_)?d(_):r(_):_.match(y)||[]}},31507:(v,T,i)=>{var r=i(23898),u=i(25687);v.exports=function(d,e){return u(d||[],e||[],r)}},74538:(v,T,i)=>{"use strict";var r=i(7856),u=i(11926);T.highlight=d,T.highlightAuto=function(ae,H){var De,ce,lt,Ve,se=H||{},Ee=se.subset||r.listLanguages(),ie=se.prefix,he=Ee.length,ge=-1;if(null==ie&&(ie=p),"string"!=typeof ae)throw u("Expected `string` for value, got `%s`",ae);for(ce={relevance:0,language:null,value:[]},De={relevance:0,language:null,value:[]};++ge<he;)r.getLanguage(Ve=Ee[ge])&&((lt=d(Ve,ae,H)).language=Ve,lt.relevance>ce.relevance&&(ce=lt),lt.relevance>De.relevance&&(ce=De,De=lt));return ce.language&&(De.secondBest=ce),De},T.registerLanguage=function(ae,H){r.registerLanguage(ae,H)},T.listLanguages=function(){return r.listLanguages()},T.registerAlias=function(ae,H){var Ee,se=ae;for(Ee in H&&((se={})[ae]=H),se)r.registerAliases(se[Ee],{languageName:Ee})},A.prototype.addText=function(ae){var se,Ee,H=this.stack;""!==ae&&((Ee=(se=H[H.length-1]).children[se.children.length-1])&&"text"===Ee.type?Ee.value+=ae:se.children.push({type:"text",value:ae}))},A.prototype.addKeyword=function(ae,H){this.openNode(H),this.addText(ae),this.closeNode()},A.prototype.addSublanguage=function(ae,H){var se=this.stack,Ee=se[se.length-1],ie=ae.rootNode.children;Ee.children=Ee.children.concat(H?{type:"element",tagName:"span",properties:{className:[H]},children:ie}:ie)},A.prototype.openNode=function(ae){var H=this.stack,ie={type:"element",tagName:"span",properties:{className:[this.options.classPrefix+ae]},children:[]};H[H.length-1].children.push(ie),H.push(ie)},A.prototype.closeNode=function(){this.stack.pop()},A.prototype.closeAllNodes=ue,A.prototype.finalize=ue,A.prototype.toHTML=function(){return""};var p="hljs-";function d(ae,H,se){var ge,Ee=r.configure({}),he=(se||{}).prefix;if("string"!=typeof ae)throw u("Expected `string` for name, got `%s`",ae);if(!r.getLanguage(ae))throw u("Unknown language: `%s` is not registered",ae);if("string"!=typeof H)throw u("Expected `string` for value, got `%s`",H);if(null==he&&(he=p),r.configure({__emitter:A,classPrefix:he}),ge=r.highlight(H,{language:ae,ignoreIllegals:!0}),r.configure(Ee||{}),ge.errorRaised)throw ge.errorRaised;return{relevance:ge.relevance,language:ge.language,value:ge.emitter.rootNode.children}}function A(ae){this.options=ae,this.rootNode={children:[]},this.stack=[this.rootNode]}function ue(){}},26431:function(v,T,i){!function(r){"use strict";r.defineLocale("af",{months:"Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember".split("_"),monthsShort:"Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des".split("_"),weekdays:"Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag".split("_"),weekdaysShort:"Son_Maa_Din_Woe_Don_Vry_Sat".split("_"),weekdaysMin:"So_Ma_Di_Wo_Do_Vr_Sa".split("_"),meridiemParse:/vm|nm/i,isPM:function(p){return/^nm$/i.test(p)},meridiem:function(p,d,e){return p<12?e?"vm":"VM":e?"nm":"NM"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Vandag om] LT",nextDay:"[M\xf4re om] LT",nextWeek:"dddd [om] LT",lastDay:"[Gister om] LT",lastWeek:"[Laas] dddd [om] LT",sameElse:"L"},relativeTime:{future:"oor %s",past:"%s gelede",s:"'n paar sekondes",ss:"%d sekondes",m:"'n minuut",mm:"%d minute",h:"'n uur",hh:"%d ure",d:"'n dag",dd:"%d dae",M:"'n maand",MM:"%d maande",y:"'n jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(p){return p+(1===p||8===p||p>=20?"ste":"de")},week:{dow:1,doy:4}})}(i(16738))},1616:function(v,T,i){!function(r){"use strict";var u=function(y){return 0===y?0:1===y?1:2===y?2:y%100>=3&&y%100<=10?3:y%100>=11?4:5},p={s:["\u0623\u0642\u0644 \u0645\u0646 \u062b\u0627\u0646\u064a\u0629","\u062b\u0627\u0646\u064a\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062b\u0627\u0646\u064a\u062a\u0627\u0646","\u062b\u0627\u0646\u064a\u062a\u064a\u0646"],"%d \u062b\u0648\u0627\u0646","%d \u062b\u0627\u0646\u064a\u0629","%d \u062b\u0627\u0646\u064a\u0629"],m:["\u0623\u0642\u0644 \u0645\u0646 \u062f\u0642\u064a\u0642\u0629","\u062f\u0642\u064a\u0642\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062f\u0642\u064a\u0642\u062a\u0627\u0646","\u062f\u0642\u064a\u0642\u062a\u064a\u0646"],"%d \u062f\u0642\u0627\u0626\u0642","%d \u062f\u0642\u064a\u0642\u0629","%d \u062f\u0642\u064a\u0642\u0629"],h:["\u0623\u0642\u0644 \u0645\u0646 \u0633\u0627\u0639\u0629","\u0633\u0627\u0639\u0629 \u0648\u0627\u062d\u062f\u0629",["\u0633\u0627\u0639\u062a\u0627\u0646","\u0633\u0627\u0639\u062a\u064a\u0646"],"%d \u0633\u0627\u0639\u0627\u062a","%d \u0633\u0627\u0639\u0629","%d \u0633\u0627\u0639\u0629"],d:["\u0623\u0642\u0644 \u0645\u0646 \u064a\u0648\u0645","\u064a\u0648\u0645 \u0648\u0627\u062d\u062f",["\u064a\u0648\u0645\u0627\u0646","\u064a\u0648\u0645\u064a\u0646"],"%d \u0623\u064a\u0627\u0645","%d \u064a\u0648\u0645\u064b\u0627","%d \u064a\u0648\u0645"],M:["\u0623\u0642\u0644 \u0645\u0646 \u0634\u0647\u0631","\u0634\u0647\u0631 \u0648\u0627\u062d\u062f",["\u0634\u0647\u0631\u0627\u0646","\u0634\u0647\u0631\u064a\u0646"],"%d \u0623\u0634\u0647\u0631","%d \u0634\u0647\u0631\u0627","%d \u0634\u0647\u0631"],y:["\u0623\u0642\u0644 \u0645\u0646 \u0639\u0627\u0645","\u0639\u0627\u0645 \u0648\u0627\u062d\u062f",["\u0639\u0627\u0645\u0627\u0646","\u0639\u0627\u0645\u064a\u0646"],"%d \u0623\u0639\u0648\u0627\u0645","%d \u0639\u0627\u0645\u064b\u0627","%d \u0639\u0627\u0645"]},d=function(y){return function(S,A,N,L){var Z=u(S),J=p[y][u(S)];return 2===Z&&(J=J[A?0:1]),J.replace(/%d/i,S)}},e=["\u062c\u0627\u0646\u0641\u064a","\u0641\u064a\u0641\u0631\u064a","\u0645\u0627\u0631\u0633","\u0623\u0641\u0631\u064a\u0644","\u0645\u0627\u064a","\u062c\u0648\u0627\u0646","\u062c\u0648\u064a\u0644\u064a\u0629","\u0623\u0648\u062a","\u0633\u0628\u062a\u0645\u0628\u0631","\u0623\u0643\u062a\u0648\u0628\u0631","\u0646\u0648\u0641\u0645\u0628\u0631","\u062f\u064a\u0633\u0645\u0628\u0631"];r.defineLocale("ar-dz",{months:e,monthsShort:e,weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/\u200fM/\u200fYYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0635|\u0645/,isPM:function(y){return"\u0645"===y},meridiem:function(y,S,A){return y<12?"\u0635":"\u0645"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u064b\u0627 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0628\u0639\u062f %s",past:"\u0645\u0646\u0630 %s",s:d("s"),ss:d("s"),m:d("m"),mm:d("m"),h:d("h"),hh:d("h"),d:d("d"),dd:d("d"),M:d("M"),MM:d("M"),y:d("y"),yy:d("y")},postformat:function(y){return y.replace(/,/g,"\u060c")},week:{dow:0,doy:4}})}(i(16738))},9759:function(v,T,i){!function(r){"use strict";r.defineLocale("ar-kw",{months:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648\u0632_\u063a\u0634\u062a_\u0634\u062a\u0646\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0646\u0628\u0631_\u062f\u062c\u0646\u0628\u0631".split("_"),monthsShort:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648\u0632_\u063a\u0634\u062a_\u0634\u062a\u0646\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0646\u0628\u0631_\u062f\u062c\u0646\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062a\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0627\u062d\u062f_\u0627\u062a\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},week:{dow:0,doy:12}})}(i(16738))},43160:function(v,T,i){!function(r){"use strict";var u={1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",0:"0"},p=function(S){return 0===S?0:1===S?1:2===S?2:S%100>=3&&S%100<=10?3:S%100>=11?4:5},d={s:["\u0623\u0642\u0644 \u0645\u0646 \u062b\u0627\u0646\u064a\u0629","\u062b\u0627\u0646\u064a\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062b\u0627\u0646\u064a\u062a\u0627\u0646","\u062b\u0627\u0646\u064a\u062a\u064a\u0646"],"%d \u062b\u0648\u0627\u0646","%d \u062b\u0627\u0646\u064a\u0629","%d \u062b\u0627\u0646\u064a\u0629"],m:["\u0623\u0642\u0644 \u0645\u0646 \u062f\u0642\u064a\u0642\u0629","\u062f\u0642\u064a\u0642\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062f\u0642\u064a\u0642\u062a\u0627\u0646","\u062f\u0642\u064a\u0642\u062a\u064a\u0646"],"%d \u062f\u0642\u0627\u0626\u0642","%d \u062f\u0642\u064a\u0642\u0629","%d \u062f\u0642\u064a\u0642\u0629"],h:["\u0623\u0642\u0644 \u0645\u0646 \u0633\u0627\u0639\u0629","\u0633\u0627\u0639\u0629 \u0648\u0627\u062d\u062f\u0629",["\u0633\u0627\u0639\u062a\u0627\u0646","\u0633\u0627\u0639\u062a\u064a\u0646"],"%d \u0633\u0627\u0639\u0627\u062a","%d \u0633\u0627\u0639\u0629","%d \u0633\u0627\u0639\u0629"],d:["\u0623\u0642\u0644 \u0645\u0646 \u064a\u0648\u0645","\u064a\u0648\u0645 \u0648\u0627\u062d\u062f",["\u064a\u0648\u0645\u0627\u0646","\u064a\u0648\u0645\u064a\u0646"],"%d \u0623\u064a\u0627\u0645","%d \u064a\u0648\u0645\u064b\u0627","%d \u064a\u0648\u0645"],M:["\u0623\u0642\u0644 \u0645\u0646 \u0634\u0647\u0631","\u0634\u0647\u0631 \u0648\u0627\u062d\u062f",["\u0634\u0647\u0631\u0627\u0646","\u0634\u0647\u0631\u064a\u0646"],"%d \u0623\u0634\u0647\u0631","%d \u0634\u0647\u0631\u0627","%d \u0634\u0647\u0631"],y:["\u0623\u0642\u0644 \u0645\u0646 \u0639\u0627\u0645","\u0639\u0627\u0645 \u0648\u0627\u062d\u062f",["\u0639\u0627\u0645\u0627\u0646","\u0639\u0627\u0645\u064a\u0646"],"%d \u0623\u0639\u0648\u0627\u0645","%d \u0639\u0627\u0645\u064b\u0627","%d \u0639\u0627\u0645"]},e=function(S){return function(A,N,L,Z){var J=p(A),K=d[S][p(A)];return 2===J&&(K=K[N?0:1]),K.replace(/%d/i,A)}},_=["\u064a\u0646\u0627\u064a\u0631","\u0641\u0628\u0631\u0627\u064a\u0631","\u0645\u0627\u0631\u0633","\u0623\u0628\u0631\u064a\u0644","\u0645\u0627\u064a\u0648","\u064a\u0648\u0646\u064a\u0648","\u064a\u0648\u0644\u064a\u0648","\u0623\u063a\u0633\u0637\u0633","\u0633\u0628\u062a\u0645\u0628\u0631","\u0623\u0643\u062a\u0648\u0628\u0631","\u0646\u0648\u0641\u0645\u0628\u0631","\u062f\u064a\u0633\u0645\u0628\u0631"];r.defineLocale("ar-ly",{months:_,monthsShort:_,weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/\u200fM/\u200fYYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0635|\u0645/,isPM:function(S){return"\u0645"===S},meridiem:function(S,A,N){return S<12?"\u0635":"\u0645"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u064b\u0627 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0628\u0639\u062f %s",past:"\u0645\u0646\u0630 %s",s:e("s"),ss:e("s"),m:e("m"),mm:e("m"),h:e("h"),hh:e("h"),d:e("d"),dd:e("d"),M:e("M"),MM:e("M"),y:e("y"),yy:e("y")},preparse:function(S){return S.replace(/\u060c/g,",")},postformat:function(S){return S.replace(/\d/g,function(A){return u[A]}).replace(/,/g,"\u060c")},week:{dow:6,doy:12}})}(i(16738))},62551:function(v,T,i){!function(r){"use strict";r.defineLocale("ar-ma",{months:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648\u0632_\u063a\u0634\u062a_\u0634\u062a\u0646\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0646\u0628\u0631_\u062f\u062c\u0646\u0628\u0631".split("_"),monthsShort:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648\u0632_\u063a\u0634\u062a_\u0634\u062a\u0646\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0646\u0628\u0631_\u062f\u062c\u0646\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0627\u062d\u062f_\u0627\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},week:{dow:1,doy:4}})}(i(16738))},79989:function(v,T,i){!function(r){"use strict";var u={1:"\u0661",2:"\u0662",3:"\u0663",4:"\u0664",5:"\u0665",6:"\u0666",7:"\u0667",8:"\u0668",9:"\u0669",0:"\u0660"},p={"\u0661":"1","\u0662":"2","\u0663":"3","\u0664":"4","\u0665":"5","\u0666":"6","\u0667":"7","\u0668":"8","\u0669":"9","\u0660":"0"};r.defineLocale("ar-sa",{months:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a\u0648_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648_\u0623\u063a\u0633\u0637\u0633_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),monthsShort:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a\u0648_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648_\u0623\u063a\u0633\u0637\u0633_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0635|\u0645/,isPM:function(e){return"\u0645"===e},meridiem:function(e,_,y){return e<12?"\u0635":"\u0645"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},preparse:function(e){return e.replace(/[\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u0660]/g,function(_){return p[_]}).replace(/\u060c/g,",")},postformat:function(e){return e.replace(/\d/g,function(_){return u[_]}).replace(/,/g,"\u060c")},week:{dow:0,doy:6}})}(i(16738))},6962:function(v,T,i){!function(r){"use strict";r.defineLocale("ar-tn",{months:"\u062c\u0627\u0646\u0641\u064a_\u0641\u064a\u0641\u0631\u064a_\u0645\u0627\u0631\u0633_\u0623\u0641\u0631\u064a\u0644_\u0645\u0627\u064a_\u062c\u0648\u0627\u0646_\u062c\u0648\u064a\u0644\u064a\u0629_\u0623\u0648\u062a_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),monthsShort:"\u062c\u0627\u0646\u0641\u064a_\u0641\u064a\u0641\u0631\u064a_\u0645\u0627\u0631\u0633_\u0623\u0641\u0631\u064a\u0644_\u0645\u0627\u064a_\u062c\u0648\u0627\u0646_\u062c\u0648\u064a\u0644\u064a\u0629_\u0623\u0648\u062a_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},week:{dow:1,doy:4}})}(i(16738))},81286:function(v,T,i){!function(r){"use strict";var u={1:"\u0661",2:"\u0662",3:"\u0663",4:"\u0664",5:"\u0665",6:"\u0666",7:"\u0667",8:"\u0668",9:"\u0669",0:"\u0660"},p={"\u0661":"1","\u0662":"2","\u0663":"3","\u0664":"4","\u0665":"5","\u0666":"6","\u0667":"7","\u0668":"8","\u0669":"9","\u0660":"0"},d=function(A){return 0===A?0:1===A?1:2===A?2:A%100>=3&&A%100<=10?3:A%100>=11?4:5},e={s:["\u0623\u0642\u0644 \u0645\u0646 \u062b\u0627\u0646\u064a\u0629","\u062b\u0627\u0646\u064a\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062b\u0627\u0646\u064a\u062a\u0627\u0646","\u062b\u0627\u0646\u064a\u062a\u064a\u0646"],"%d \u062b\u0648\u0627\u0646","%d \u062b\u0627\u0646\u064a\u0629","%d \u062b\u0627\u0646\u064a\u0629"],m:["\u0623\u0642\u0644 \u0645\u0646 \u062f\u0642\u064a\u0642\u0629","\u062f\u0642\u064a\u0642\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062f\u0642\u064a\u0642\u062a\u0627\u0646","\u062f\u0642\u064a\u0642\u062a\u064a\u0646"],"%d \u062f\u0642\u0627\u0626\u0642","%d \u062f\u0642\u064a\u0642\u0629","%d \u062f\u0642\u064a\u0642\u0629"],h:["\u0623\u0642\u0644 \u0645\u0646 \u0633\u0627\u0639\u0629","\u0633\u0627\u0639\u0629 \u0648\u0627\u062d\u062f\u0629",["\u0633\u0627\u0639\u062a\u0627\u0646","\u0633\u0627\u0639\u062a\u064a\u0646"],"%d \u0633\u0627\u0639\u0627\u062a","%d \u0633\u0627\u0639\u0629","%d \u0633\u0627\u0639\u0629"],d:["\u0623\u0642\u0644 \u0645\u0646 \u064a\u0648\u0645","\u064a\u0648\u0645 \u0648\u0627\u062d\u062f",["\u064a\u0648\u0645\u0627\u0646","\u064a\u0648\u0645\u064a\u0646"],"%d \u0623\u064a\u0627\u0645","%d \u064a\u0648\u0645\u064b\u0627","%d \u064a\u0648\u0645"],M:["\u0623\u0642\u0644 \u0645\u0646 \u0634\u0647\u0631","\u0634\u0647\u0631 \u0648\u0627\u062d\u062f",["\u0634\u0647\u0631\u0627\u0646","\u0634\u0647\u0631\u064a\u0646"],"%d \u0623\u0634\u0647\u0631","%d \u0634\u0647\u0631\u0627","%d \u0634\u0647\u0631"],y:["\u0623\u0642\u0644 \u0645\u0646 \u0639\u0627\u0645","\u0639\u0627\u0645 \u0648\u0627\u062d\u062f",["\u0639\u0627\u0645\u0627\u0646","\u0639\u0627\u0645\u064a\u0646"],"%d \u0623\u0639\u0648\u0627\u0645","%d \u0639\u0627\u0645\u064b\u0627","%d \u0639\u0627\u0645"]},_=function(A){return function(N,L,Z,J){var K=d(N),ee=e[A][d(N)];return 2===K&&(ee=ee[L?0:1]),ee.replace(/%d/i,N)}},y=["\u064a\u0646\u0627\u064a\u0631","\u0641\u0628\u0631\u0627\u064a\u0631","\u0645\u0627\u0631\u0633","\u0623\u0628\u0631\u064a\u0644","\u0645\u0627\u064a\u0648","\u064a\u0648\u0646\u064a\u0648","\u064a\u0648\u0644\u064a\u0648","\u0623\u063a\u0633\u0637\u0633","\u0633\u0628\u062a\u0645\u0628\u0631","\u0623\u0643\u062a\u0648\u0628\u0631","\u0646\u0648\u0641\u0645\u0628\u0631","\u062f\u064a\u0633\u0645\u0628\u0631"];r.defineLocale("ar",{months:y,monthsShort:y,weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/\u200fM/\u200fYYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0635|\u0645/,isPM:function(A){return"\u0645"===A},meridiem:function(A,N,L){return A<12?"\u0635":"\u0645"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u064b\u0627 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0628\u0639\u062f %s",past:"\u0645\u0646\u0630 %s",s:_("s"),ss:_("s"),m:_("m"),mm:_("m"),h:_("h"),hh:_("h"),d:_("d"),dd:_("d"),M:_("M"),MM:_("M"),y:_("y"),yy:_("y")},preparse:function(A){return A.replace(/[\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u0660]/g,function(N){return p[N]}).replace(/\u060c/g,",")},postformat:function(A){return A.replace(/\d/g,function(N){return u[N]}).replace(/,/g,"\u060c")},week:{dow:6,doy:12}})}(i(16738))},15887:function(v,T,i){!function(r){"use strict";var u={1:"-inci",5:"-inci",8:"-inci",70:"-inci",80:"-inci",2:"-nci",7:"-nci",20:"-nci",50:"-nci",3:"-\xfcnc\xfc",4:"-\xfcnc\xfc",100:"-\xfcnc\xfc",6:"-nc\u0131",9:"-uncu",10:"-uncu",30:"-uncu",60:"-\u0131nc\u0131",90:"-\u0131nc\u0131"};r.defineLocale("az",{months:"yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr".split("_"),monthsShort:"yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek".split("_"),weekdays:"Bazar_Bazar ert\u0259si_\xc7\u0259r\u015f\u0259nb\u0259 ax\u015fam\u0131_\xc7\u0259r\u015f\u0259nb\u0259_C\xfcm\u0259 ax\u015fam\u0131_C\xfcm\u0259_\u015e\u0259nb\u0259".split("_"),weekdaysShort:"Baz_BzE_\xc7Ax_\xc7\u0259r_CAx_C\xfcm_\u015e\u0259n".split("_"),weekdaysMin:"Bz_BE_\xc7A_\xc7\u0259_CA_C\xfc_\u015e\u0259".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bug\xfcn saat] LT",nextDay:"[sabah saat] LT",nextWeek:"[g\u0259l\u0259n h\u0259ft\u0259] dddd [saat] LT",lastDay:"[d\xfcn\u0259n] LT",lastWeek:"[ke\xe7\u0259n h\u0259ft\u0259] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s \u0259vv\u0259l",s:"bir ne\xe7\u0259 saniy\u0259",ss:"%d saniy\u0259",m:"bir d\u0259qiq\u0259",mm:"%d d\u0259qiq\u0259",h:"bir saat",hh:"%d saat",d:"bir g\xfcn",dd:"%d g\xfcn",M:"bir ay",MM:"%d ay",y:"bir il",yy:"%d il"},meridiemParse:/gec\u0259|s\u0259h\u0259r|g\xfcnd\xfcz|ax\u015fam/,isPM:function(d){return/^(g\xfcnd\xfcz|ax\u015fam)$/.test(d)},meridiem:function(d,e,_){return d<4?"gec\u0259":d<12?"s\u0259h\u0259r":d<17?"g\xfcnd\xfcz":"ax\u015fam"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0131nc\u0131|inci|nci|\xfcnc\xfc|nc\u0131|uncu)/,ordinal:function(d){if(0===d)return d+"-\u0131nc\u0131";var e=d%10;return d+(u[e]||u[d%100-e]||u[d>=100?100:null])},week:{dow:1,doy:7}})}(i(16738))},14572:function(v,T,i){!function(r){"use strict";function p(e,_,y){return"m"===y?_?"\u0445\u0432\u0456\u043b\u0456\u043d\u0430":"\u0445\u0432\u0456\u043b\u0456\u043d\u0443":"h"===y?_?"\u0433\u0430\u0434\u0437\u0456\u043d\u0430":"\u0433\u0430\u0434\u0437\u0456\u043d\u0443":e+" "+function(e,_){var y=e.split("_");return _%10==1&&_%100!=11?y[0]:_%10>=2&&_%10<=4&&(_%100<10||_%100>=20)?y[1]:y[2]}({ss:_?"\u0441\u0435\u043a\u0443\u043d\u0434\u0430_\u0441\u0435\u043a\u0443\u043d\u0434\u044b_\u0441\u0435\u043a\u0443\u043d\u0434":"\u0441\u0435\u043a\u0443\u043d\u0434\u0443_\u0441\u0435\u043a\u0443\u043d\u0434\u044b_\u0441\u0435\u043a\u0443\u043d\u0434",mm:_?"\u0445\u0432\u0456\u043b\u0456\u043d\u0430_\u0445\u0432\u0456\u043b\u0456\u043d\u044b_\u0445\u0432\u0456\u043b\u0456\u043d":"\u0445\u0432\u0456\u043b\u0456\u043d\u0443_\u0445\u0432\u0456\u043b\u0456\u043d\u044b_\u0445\u0432\u0456\u043b\u0456\u043d",hh:_?"\u0433\u0430\u0434\u0437\u0456\u043d\u0430_\u0433\u0430\u0434\u0437\u0456\u043d\u044b_\u0433\u0430\u0434\u0437\u0456\u043d":"\u0433\u0430\u0434\u0437\u0456\u043d\u0443_\u0433\u0430\u0434\u0437\u0456\u043d\u044b_\u0433\u0430\u0434\u0437\u0456\u043d",dd:"\u0434\u0437\u0435\u043d\u044c_\u0434\u043d\u0456_\u0434\u0437\u0451\u043d",MM:"\u043c\u0435\u0441\u044f\u0446_\u043c\u0435\u0441\u044f\u0446\u044b_\u043c\u0435\u0441\u044f\u0446\u0430\u045e",yy:"\u0433\u043e\u0434_\u0433\u0430\u0434\u044b_\u0433\u0430\u0434\u043e\u045e"}[y],+e)}r.defineLocale("be",{months:{format:"\u0441\u0442\u0443\u0434\u0437\u0435\u043d\u044f_\u043b\u044e\u0442\u0430\u0433\u0430_\u0441\u0430\u043a\u0430\u0432\u0456\u043a\u0430_\u043a\u0440\u0430\u0441\u0430\u0432\u0456\u043a\u0430_\u0442\u0440\u0430\u045e\u043d\u044f_\u0447\u044d\u0440\u0432\u0435\u043d\u044f_\u043b\u0456\u043f\u0435\u043d\u044f_\u0436\u043d\u0456\u045e\u043d\u044f_\u0432\u0435\u0440\u0430\u0441\u043d\u044f_\u043a\u0430\u0441\u0442\u0440\u044b\u0447\u043d\u0456\u043a\u0430_\u043b\u0456\u0441\u0442\u0430\u043f\u0430\u0434\u0430_\u0441\u043d\u0435\u0436\u043d\u044f".split("_"),standalone:"\u0441\u0442\u0443\u0434\u0437\u0435\u043d\u044c_\u043b\u044e\u0442\u044b_\u0441\u0430\u043a\u0430\u0432\u0456\u043a_\u043a\u0440\u0430\u0441\u0430\u0432\u0456\u043a_\u0442\u0440\u0430\u0432\u0435\u043d\u044c_\u0447\u044d\u0440\u0432\u0435\u043d\u044c_\u043b\u0456\u043f\u0435\u043d\u044c_\u0436\u043d\u0456\u0432\u0435\u043d\u044c_\u0432\u0435\u0440\u0430\u0441\u0435\u043d\u044c_\u043a\u0430\u0441\u0442\u0440\u044b\u0447\u043d\u0456\u043a_\u043b\u0456\u0441\u0442\u0430\u043f\u0430\u0434_\u0441\u043d\u0435\u0436\u0430\u043d\u044c".split("_")},monthsShort:"\u0441\u0442\u0443\u0434_\u043b\u044e\u0442_\u0441\u0430\u043a_\u043a\u0440\u0430\u0441_\u0442\u0440\u0430\u0432_\u0447\u044d\u0440\u0432_\u043b\u0456\u043f_\u0436\u043d\u0456\u0432_\u0432\u0435\u0440_\u043a\u0430\u0441\u0442_\u043b\u0456\u0441\u0442_\u0441\u043d\u0435\u0436".split("_"),weekdays:{format:"\u043d\u044f\u0434\u0437\u0435\u043b\u044e_\u043f\u0430\u043d\u044f\u0434\u0437\u0435\u043b\u0430\u043a_\u0430\u045e\u0442\u043e\u0440\u0430\u043a_\u0441\u0435\u0440\u0430\u0434\u0443_\u0447\u0430\u0446\u0432\u0435\u0440_\u043f\u044f\u0442\u043d\u0456\u0446\u0443_\u0441\u0443\u0431\u043e\u0442\u0443".split("_"),standalone:"\u043d\u044f\u0434\u0437\u0435\u043b\u044f_\u043f\u0430\u043d\u044f\u0434\u0437\u0435\u043b\u0430\u043a_\u0430\u045e\u0442\u043e\u0440\u0430\u043a_\u0441\u0435\u0440\u0430\u0434\u0430_\u0447\u0430\u0446\u0432\u0435\u0440_\u043f\u044f\u0442\u043d\u0456\u0446\u0430_\u0441\u0443\u0431\u043e\u0442\u0430".split("_"),isFormat:/\[ ?[\u0423\u0443\u045e] ?(?:\u043c\u0456\u043d\u0443\u043b\u0443\u044e|\u043d\u0430\u0441\u0442\u0443\u043f\u043d\u0443\u044e)? ?\] ?dddd/},weekdaysShort:"\u043d\u0434_\u043f\u043d_\u0430\u0442_\u0441\u0440_\u0447\u0446_\u043f\u0442_\u0441\u0431".split("_"),weekdaysMin:"\u043d\u0434_\u043f\u043d_\u0430\u0442_\u0441\u0440_\u0447\u0446_\u043f\u0442_\u0441\u0431".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY \u0433.",LLL:"D MMMM YYYY \u0433., HH:mm",LLLL:"dddd, D MMMM YYYY \u0433., HH:mm"},calendar:{sameDay:"[\u0421\u0451\u043d\u043d\u044f \u045e] LT",nextDay:"[\u0417\u0430\u045e\u0442\u0440\u0430 \u045e] LT",lastDay:"[\u0423\u0447\u043e\u0440\u0430 \u045e] LT",nextWeek:function(){return"[\u0423] dddd [\u045e] LT"},lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return"[\u0423 \u043c\u0456\u043d\u0443\u043b\u0443\u044e] dddd [\u045e] LT";case 1:case 2:case 4:return"[\u0423 \u043c\u0456\u043d\u0443\u043b\u044b] dddd [\u045e] LT"}},sameElse:"L"},relativeTime:{future:"\u043f\u0440\u0430\u0437 %s",past:"%s \u0442\u0430\u043c\u0443",s:"\u043d\u0435\u043a\u0430\u043b\u044c\u043a\u0456 \u0441\u0435\u043a\u0443\u043d\u0434",m:p,mm:p,h:p,hh:p,d:"\u0434\u0437\u0435\u043d\u044c",dd:p,M:"\u043c\u0435\u0441\u044f\u0446",MM:p,y:"\u0433\u043e\u0434",yy:p},meridiemParse:/\u043d\u043e\u0447\u044b|\u0440\u0430\u043d\u0456\u0446\u044b|\u0434\u043d\u044f|\u0432\u0435\u0447\u0430\u0440\u0430/,isPM:function(e){return/^(\u0434\u043d\u044f|\u0432\u0435\u0447\u0430\u0440\u0430)$/.test(e)},meridiem:function(e,_,y){return e<4?"\u043d\u043e\u0447\u044b":e<12?"\u0440\u0430\u043d\u0456\u0446\u044b":e<17?"\u0434\u043d\u044f":"\u0432\u0435\u0447\u0430\u0440\u0430"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0456|\u044b|\u0433\u0430)/,ordinal:function(e,_){switch(_){case"M":case"d":case"DDD":case"w":case"W":return e%10!=2&&e%10!=3||e%100==12||e%100==13?e+"-\u044b":e+"-\u0456";case"D":return e+"-\u0433\u0430";default:return e}},week:{dow:1,doy:7}})}(i(16738))},3276:function(v,T,i){!function(r){"use strict";r.defineLocale("bg",{months:"\u044f\u043d\u0443\u0430\u0440\u0438_\u0444\u0435\u0432\u0440\u0443\u0430\u0440\u0438_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0438\u043b_\u043c\u0430\u0439_\u044e\u043d\u0438_\u044e\u043b\u0438_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438_\u043e\u043a\u0442\u043e\u043c\u0432\u0440\u0438_\u043d\u043e\u0435\u043c\u0432\u0440\u0438_\u0434\u0435\u043a\u0435\u043c\u0432\u0440\u0438".split("_"),monthsShort:"\u044f\u043d\u0443_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0439_\u044e\u043d\u0438_\u044e\u043b\u0438_\u0430\u0432\u0433_\u0441\u0435\u043f_\u043e\u043a\u0442_\u043d\u043e\u0435_\u0434\u0435\u043a".split("_"),weekdays:"\u043d\u0435\u0434\u0435\u043b\u044f_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u044f\u0434\u0430_\u0447\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a_\u043f\u0435\u0442\u044a\u043a_\u0441\u044a\u0431\u043e\u0442\u0430".split("_"),weekdaysShort:"\u043d\u0435\u0434_\u043f\u043e\u043d_\u0432\u0442\u043e_\u0441\u0440\u044f_\u0447\u0435\u0442_\u043f\u0435\u0442_\u0441\u044a\u0431".split("_"),weekdaysMin:"\u043d\u0434_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[\u0414\u043d\u0435\u0441 \u0432] LT",nextDay:"[\u0423\u0442\u0440\u0435 \u0432] LT",nextWeek:"dddd [\u0432] LT",lastDay:"[\u0412\u0447\u0435\u0440\u0430 \u0432] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[\u041c\u0438\u043d\u0430\u043b\u0430\u0442\u0430] dddd [\u0432] LT";case 1:case 2:case 4:case 5:return"[\u041c\u0438\u043d\u0430\u043b\u0438\u044f] dddd [\u0432] LT"}},sameElse:"L"},relativeTime:{future:"\u0441\u043b\u0435\u0434 %s",past:"\u043f\u0440\u0435\u0434\u0438 %s",s:"\u043d\u044f\u043a\u043e\u043b\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434\u0438",ss:"%d \u0441\u0435\u043a\u0443\u043d\u0434\u0438",m:"\u043c\u0438\u043d\u0443\u0442\u0430",mm:"%d \u043c\u0438\u043d\u0443\u0442\u0438",h:"\u0447\u0430\u0441",hh:"%d \u0447\u0430\u0441\u0430",d:"\u0434\u0435\u043d",dd:"%d \u0434\u0435\u043d\u0430",w:"\u0441\u0435\u0434\u043c\u0438\u0446\u0430",ww:"%d \u0441\u0435\u0434\u043c\u0438\u0446\u0438",M:"\u043c\u0435\u0441\u0435\u0446",MM:"%d \u043c\u0435\u0441\u0435\u0446\u0430",y:"\u0433\u043e\u0434\u0438\u043d\u0430",yy:"%d \u0433\u043e\u0434\u0438\u043d\u0438"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0435\u0432|\u0435\u043d|\u0442\u0438|\u0432\u0438|\u0440\u0438|\u043c\u0438)/,ordinal:function(p){var d=p%10,e=p%100;return 0===p?p+"-\u0435\u0432":0===e?p+"-\u0435\u043d":e>10&&e<20?p+"-\u0442\u0438":1===d?p+"-\u0432\u0438":2===d?p+"-\u0440\u0438":7===d||8===d?p+"-\u043c\u0438":p+"-\u0442\u0438"},week:{dow:1,doy:7}})}(i(16738))},93344:function(v,T,i){!function(r){"use strict";r.defineLocale("bm",{months:"Zanwuyekalo_Fewuruyekalo_Marisikalo_Awirilikalo_M\u025bkalo_Zuw\u025bnkalo_Zuluyekalo_Utikalo_S\u025btanburukalo_\u0254kut\u0254burukalo_Nowanburukalo_Desanburukalo".split("_"),monthsShort:"Zan_Few_Mar_Awi_M\u025b_Zuw_Zul_Uti_S\u025bt_\u0254ku_Now_Des".split("_"),weekdays:"Kari_Nt\u025bn\u025bn_Tarata_Araba_Alamisa_Juma_Sibiri".split("_"),weekdaysShort:"Kar_Nt\u025b_Tar_Ara_Ala_Jum_Sib".split("_"),weekdaysMin:"Ka_Nt_Ta_Ar_Al_Ju_Si".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"MMMM [tile] D [san] YYYY",LLL:"MMMM [tile] D [san] YYYY [l\u025br\u025b] HH:mm",LLLL:"dddd MMMM [tile] D [san] YYYY [l\u025br\u025b] HH:mm"},calendar:{sameDay:"[Bi l\u025br\u025b] LT",nextDay:"[Sini l\u025br\u025b] LT",nextWeek:"dddd [don l\u025br\u025b] LT",lastDay:"[Kunu l\u025br\u025b] LT",lastWeek:"dddd [t\u025bm\u025bnen l\u025br\u025b] LT",sameElse:"L"},relativeTime:{future:"%s k\u0254n\u0254",past:"a b\u025b %s b\u0254",s:"sanga dama dama",ss:"sekondi %d",m:"miniti kelen",mm:"miniti %d",h:"l\u025br\u025b kelen",hh:"l\u025br\u025b %d",d:"tile kelen",dd:"tile %d",M:"kalo kelen",MM:"kalo %d",y:"san kelen",yy:"san %d"},week:{dow:1,doy:4}})}(i(16738))},83990:function(v,T,i){!function(r){"use strict";var u={1:"\u09e7",2:"\u09e8",3:"\u09e9",4:"\u09ea",5:"\u09eb",6:"\u09ec",7:"\u09ed",8:"\u09ee",9:"\u09ef",0:"\u09e6"},p={"\u09e7":"1","\u09e8":"2","\u09e9":"3","\u09ea":"4","\u09eb":"5","\u09ec":"6","\u09ed":"7","\u09ee":"8","\u09ef":"9","\u09e6":"0"};r.defineLocale("bn-bd",{months:"\u099c\u09be\u09a8\u09c1\u09df\u09be\u09b0\u09bf_\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09df\u09be\u09b0\u09bf_\u09ae\u09be\u09b0\u09cd\u099a_\u098f\u09aa\u09cd\u09b0\u09bf\u09b2_\u09ae\u09c7_\u099c\u09c1\u09a8_\u099c\u09c1\u09b2\u09be\u0987_\u0986\u0997\u09b8\u09cd\u099f_\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0_\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0_\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0_\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0".split("_"),monthsShort:"\u099c\u09be\u09a8\u09c1_\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1_\u09ae\u09be\u09b0\u09cd\u099a_\u098f\u09aa\u09cd\u09b0\u09bf\u09b2_\u09ae\u09c7_\u099c\u09c1\u09a8_\u099c\u09c1\u09b2\u09be\u0987_\u0986\u0997\u09b8\u09cd\u099f_\u09b8\u09c7\u09aa\u09cd\u099f_\u0985\u0995\u09cd\u099f\u09cb_\u09a8\u09ad\u09c7_\u09a1\u09bf\u09b8\u09c7".split("_"),weekdays:"\u09b0\u09ac\u09bf\u09ac\u09be\u09b0_\u09b8\u09cb\u09ae\u09ac\u09be\u09b0_\u09ae\u0999\u09cd\u0997\u09b2\u09ac\u09be\u09b0_\u09ac\u09c1\u09a7\u09ac\u09be\u09b0_\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf\u09ac\u09be\u09b0_\u09b6\u09c1\u0995\u09cd\u09b0\u09ac\u09be\u09b0_\u09b6\u09a8\u09bf\u09ac\u09be\u09b0".split("_"),weekdaysShort:"\u09b0\u09ac\u09bf_\u09b8\u09cb\u09ae_\u09ae\u0999\u09cd\u0997\u09b2_\u09ac\u09c1\u09a7_\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf_\u09b6\u09c1\u0995\u09cd\u09b0_\u09b6\u09a8\u09bf".split("_"),weekdaysMin:"\u09b0\u09ac\u09bf_\u09b8\u09cb\u09ae_\u09ae\u0999\u09cd\u0997\u09b2_\u09ac\u09c1\u09a7_\u09ac\u09c3\u09b9_\u09b6\u09c1\u0995\u09cd\u09b0_\u09b6\u09a8\u09bf".split("_"),longDateFormat:{LT:"A h:mm \u09b8\u09ae\u09df",LTS:"A h:mm:ss \u09b8\u09ae\u09df",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u09b8\u09ae\u09df",LLLL:"dddd, D MMMM YYYY, A h:mm \u09b8\u09ae\u09df"},calendar:{sameDay:"[\u0986\u099c] LT",nextDay:"[\u0986\u0997\u09be\u09ae\u09c0\u0995\u09be\u09b2] LT",nextWeek:"dddd, LT",lastDay:"[\u0997\u09a4\u0995\u09be\u09b2] LT",lastWeek:"[\u0997\u09a4] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u09aa\u09b0\u09c7",past:"%s \u0986\u0997\u09c7",s:"\u0995\u09df\u09c7\u0995 \u09b8\u09c7\u0995\u09c7\u09a8\u09cd\u09a1",ss:"%d \u09b8\u09c7\u0995\u09c7\u09a8\u09cd\u09a1",m:"\u098f\u0995 \u09ae\u09bf\u09a8\u09bf\u099f",mm:"%d \u09ae\u09bf\u09a8\u09bf\u099f",h:"\u098f\u0995 \u0998\u09a8\u09cd\u099f\u09be",hh:"%d \u0998\u09a8\u09cd\u099f\u09be",d:"\u098f\u0995 \u09a6\u09bf\u09a8",dd:"%d \u09a6\u09bf\u09a8",M:"\u098f\u0995 \u09ae\u09be\u09b8",MM:"%d \u09ae\u09be\u09b8",y:"\u098f\u0995 \u09ac\u099b\u09b0",yy:"%d \u09ac\u099b\u09b0"},preparse:function(e){return e.replace(/[\u09e7\u09e8\u09e9\u09ea\u09eb\u09ec\u09ed\u09ee\u09ef\u09e6]/g,function(_){return p[_]})},postformat:function(e){return e.replace(/\d/g,function(_){return u[_]})},meridiemParse:/\u09b0\u09be\u09a4|\u09ad\u09cb\u09b0|\u09b8\u0995\u09be\u09b2|\u09a6\u09c1\u09aa\u09c1\u09b0|\u09ac\u09bf\u0995\u09be\u09b2|\u09b8\u09a8\u09cd\u09a7\u09cd\u09af\u09be|\u09b0\u09be\u09a4/,meridiemHour:function(e,_){return 12===e&&(e=0),"\u09b0\u09be\u09a4"===_?e<4?e:e+12:"\u09ad\u09cb\u09b0"===_||"\u09b8\u0995\u09be\u09b2"===_?e:"\u09a6\u09c1\u09aa\u09c1\u09b0"===_?e>=3?e:e+12:"\u09ac\u09bf\u0995\u09be\u09b2"===_||"\u09b8\u09a8\u09cd\u09a7\u09cd\u09af\u09be"===_?e+12:void 0},meridiem:function(e,_,y){return e<4?"\u09b0\u09be\u09a4":e<6?"\u09ad\u09cb\u09b0":e<12?"\u09b8\u0995\u09be\u09b2":e<15?"\u09a6\u09c1\u09aa\u09c1\u09b0":e<18?"\u09ac\u09bf\u0995\u09be\u09b2":e<20?"\u09b8\u09a8\u09cd\u09a7\u09cd\u09af\u09be":"\u09b0\u09be\u09a4"},week:{dow:0,doy:6}})}(i(16738))},58985:function(v,T,i){!function(r){"use strict";var u={1:"\u09e7",2:"\u09e8",3:"\u09e9",4:"\u09ea",5:"\u09eb",6:"\u09ec",7:"\u09ed",8:"\u09ee",9:"\u09ef",0:"\u09e6"},p={"\u09e7":"1","\u09e8":"2","\u09e9":"3","\u09ea":"4","\u09eb":"5","\u09ec":"6","\u09ed":"7","\u09ee":"8","\u09ef":"9","\u09e6":"0"};r.defineLocale("bn",{months:"\u099c\u09be\u09a8\u09c1\u09df\u09be\u09b0\u09bf_\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09df\u09be\u09b0\u09bf_\u09ae\u09be\u09b0\u09cd\u099a_\u098f\u09aa\u09cd\u09b0\u09bf\u09b2_\u09ae\u09c7_\u099c\u09c1\u09a8_\u099c\u09c1\u09b2\u09be\u0987_\u0986\u0997\u09b8\u09cd\u099f_\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0_\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0_\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0_\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0".split("_"),monthsShort:"\u099c\u09be\u09a8\u09c1_\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1_\u09ae\u09be\u09b0\u09cd\u099a_\u098f\u09aa\u09cd\u09b0\u09bf\u09b2_\u09ae\u09c7_\u099c\u09c1\u09a8_\u099c\u09c1\u09b2\u09be\u0987_\u0986\u0997\u09b8\u09cd\u099f_\u09b8\u09c7\u09aa\u09cd\u099f_\u0985\u0995\u09cd\u099f\u09cb_\u09a8\u09ad\u09c7_\u09a1\u09bf\u09b8\u09c7".split("_"),weekdays:"\u09b0\u09ac\u09bf\u09ac\u09be\u09b0_\u09b8\u09cb\u09ae\u09ac\u09be\u09b0_\u09ae\u0999\u09cd\u0997\u09b2\u09ac\u09be\u09b0_\u09ac\u09c1\u09a7\u09ac\u09be\u09b0_\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf\u09ac\u09be\u09b0_\u09b6\u09c1\u0995\u09cd\u09b0\u09ac\u09be\u09b0_\u09b6\u09a8\u09bf\u09ac\u09be\u09b0".split("_"),weekdaysShort:"\u09b0\u09ac\u09bf_\u09b8\u09cb\u09ae_\u09ae\u0999\u09cd\u0997\u09b2_\u09ac\u09c1\u09a7_\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf_\u09b6\u09c1\u0995\u09cd\u09b0_\u09b6\u09a8\u09bf".split("_"),weekdaysMin:"\u09b0\u09ac\u09bf_\u09b8\u09cb\u09ae_\u09ae\u0999\u09cd\u0997\u09b2_\u09ac\u09c1\u09a7_\u09ac\u09c3\u09b9_\u09b6\u09c1\u0995\u09cd\u09b0_\u09b6\u09a8\u09bf".split("_"),longDateFormat:{LT:"A h:mm \u09b8\u09ae\u09df",LTS:"A h:mm:ss \u09b8\u09ae\u09df",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u09b8\u09ae\u09df",LLLL:"dddd, D MMMM YYYY, A h:mm \u09b8\u09ae\u09df"},calendar:{sameDay:"[\u0986\u099c] LT",nextDay:"[\u0986\u0997\u09be\u09ae\u09c0\u0995\u09be\u09b2] LT",nextWeek:"dddd, LT",lastDay:"[\u0997\u09a4\u0995\u09be\u09b2] LT",lastWeek:"[\u0997\u09a4] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u09aa\u09b0\u09c7",past:"%s \u0986\u0997\u09c7",s:"\u0995\u09df\u09c7\u0995 \u09b8\u09c7\u0995\u09c7\u09a8\u09cd\u09a1",ss:"%d \u09b8\u09c7\u0995\u09c7\u09a8\u09cd\u09a1",m:"\u098f\u0995 \u09ae\u09bf\u09a8\u09bf\u099f",mm:"%d \u09ae\u09bf\u09a8\u09bf\u099f",h:"\u098f\u0995 \u0998\u09a8\u09cd\u099f\u09be",hh:"%d \u0998\u09a8\u09cd\u099f\u09be",d:"\u098f\u0995 \u09a6\u09bf\u09a8",dd:"%d \u09a6\u09bf\u09a8",M:"\u098f\u0995 \u09ae\u09be\u09b8",MM:"%d \u09ae\u09be\u09b8",y:"\u098f\u0995 \u09ac\u099b\u09b0",yy:"%d \u09ac\u099b\u09b0"},preparse:function(e){return e.replace(/[\u09e7\u09e8\u09e9\u09ea\u09eb\u09ec\u09ed\u09ee\u09ef\u09e6]/g,function(_){return p[_]})},postformat:function(e){return e.replace(/\d/g,function(_){return u[_]})},meridiemParse:/\u09b0\u09be\u09a4|\u09b8\u0995\u09be\u09b2|\u09a6\u09c1\u09aa\u09c1\u09b0|\u09ac\u09bf\u0995\u09be\u09b2|\u09b0\u09be\u09a4/,meridiemHour:function(e,_){return 12===e&&(e=0),"\u09b0\u09be\u09a4"===_&&e>=4||"\u09a6\u09c1\u09aa\u09c1\u09b0"===_&&e<5||"\u09ac\u09bf\u0995\u09be\u09b2"===_?e+12:e},meridiem:function(e,_,y){return e<4?"\u09b0\u09be\u09a4":e<10?"\u09b8\u0995\u09be\u09b2":e<17?"\u09a6\u09c1\u09aa\u09c1\u09b0":e<20?"\u09ac\u09bf\u0995\u09be\u09b2":"\u09b0\u09be\u09a4"},week:{dow:0,doy:6}})}(i(16738))},94391:function(v,T,i){!function(r){"use strict";var u={1:"\u0f21",2:"\u0f22",3:"\u0f23",4:"\u0f24",5:"\u0f25",6:"\u0f26",7:"\u0f27",8:"\u0f28",9:"\u0f29",0:"\u0f20"},p={"\u0f21":"1","\u0f22":"2","\u0f23":"3","\u0f24":"4","\u0f25":"5","\u0f26":"6","\u0f27":"7","\u0f28":"8","\u0f29":"9","\u0f20":"0"};r.defineLocale("bo",{months:"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0f44\u0f0b\u0f54\u0f7c_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f49\u0f72\u0f66\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f66\u0f74\u0f58\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f5e\u0f72\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f63\u0f94\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0fb2\u0f74\u0f42\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f51\u0f74\u0f53\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f62\u0f92\u0fb1\u0f51\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0f42\u0f74\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f42\u0f45\u0f72\u0f42\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f42\u0f49\u0f72\u0f66\u0f0b\u0f54".split("_"),monthsShort:"\u0f5f\u0fb3\u0f0b1_\u0f5f\u0fb3\u0f0b2_\u0f5f\u0fb3\u0f0b3_\u0f5f\u0fb3\u0f0b4_\u0f5f\u0fb3\u0f0b5_\u0f5f\u0fb3\u0f0b6_\u0f5f\u0fb3\u0f0b7_\u0f5f\u0fb3\u0f0b8_\u0f5f\u0fb3\u0f0b9_\u0f5f\u0fb3\u0f0b10_\u0f5f\u0fb3\u0f0b11_\u0f5f\u0fb3\u0f0b12".split("_"),monthsShortRegex:/^(\u0f5f\u0fb3\u0f0b\d{1,2})/,monthsParseExact:!0,weekdays:"\u0f42\u0f5f\u0f60\u0f0b\u0f49\u0f72\u0f0b\u0f58\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f5f\u0fb3\u0f0b\u0f56\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f58\u0f72\u0f42\u0f0b\u0f51\u0f58\u0f62\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f63\u0fb7\u0f42\u0f0b\u0f54\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f55\u0f74\u0f62\u0f0b\u0f56\u0f74_\u0f42\u0f5f\u0f60\u0f0b\u0f54\u0f0b\u0f66\u0f44\u0f66\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f66\u0fa4\u0f7a\u0f53\u0f0b\u0f54\u0f0b".split("_"),weekdaysShort:"\u0f49\u0f72\u0f0b\u0f58\u0f0b_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b_\u0f58\u0f72\u0f42\u0f0b\u0f51\u0f58\u0f62\u0f0b_\u0f63\u0fb7\u0f42\u0f0b\u0f54\u0f0b_\u0f55\u0f74\u0f62\u0f0b\u0f56\u0f74_\u0f54\u0f0b\u0f66\u0f44\u0f66\u0f0b_\u0f66\u0fa4\u0f7a\u0f53\u0f0b\u0f54\u0f0b".split("_"),weekdaysMin:"\u0f49\u0f72_\u0f5f\u0fb3_\u0f58\u0f72\u0f42_\u0f63\u0fb7\u0f42_\u0f55\u0f74\u0f62_\u0f66\u0f44\u0f66_\u0f66\u0fa4\u0f7a\u0f53".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[\u0f51\u0f72\u0f0b\u0f62\u0f72\u0f44] LT",nextDay:"[\u0f66\u0f44\u0f0b\u0f49\u0f72\u0f53] LT",nextWeek:"[\u0f56\u0f51\u0f74\u0f53\u0f0b\u0f55\u0fb2\u0f42\u0f0b\u0f62\u0f97\u0f7a\u0f66\u0f0b\u0f58], LT",lastDay:"[\u0f41\u0f0b\u0f66\u0f44] LT",lastWeek:"[\u0f56\u0f51\u0f74\u0f53\u0f0b\u0f55\u0fb2\u0f42\u0f0b\u0f58\u0f50\u0f60\u0f0b\u0f58] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0f63\u0f0b",past:"%s \u0f66\u0f94\u0f53\u0f0b\u0f63",s:"\u0f63\u0f58\u0f0b\u0f66\u0f44",ss:"%d \u0f66\u0f90\u0f62\u0f0b\u0f46\u0f0d",m:"\u0f66\u0f90\u0f62\u0f0b\u0f58\u0f0b\u0f42\u0f45\u0f72\u0f42",mm:"%d \u0f66\u0f90\u0f62\u0f0b\u0f58",h:"\u0f46\u0f74\u0f0b\u0f5a\u0f7c\u0f51\u0f0b\u0f42\u0f45\u0f72\u0f42",hh:"%d \u0f46\u0f74\u0f0b\u0f5a\u0f7c\u0f51",d:"\u0f49\u0f72\u0f53\u0f0b\u0f42\u0f45\u0f72\u0f42",dd:"%d \u0f49\u0f72\u0f53\u0f0b",M:"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f45\u0f72\u0f42",MM:"%d \u0f5f\u0fb3\u0f0b\u0f56",y:"\u0f63\u0f7c\u0f0b\u0f42\u0f45\u0f72\u0f42",yy:"%d \u0f63\u0f7c"},preparse:function(e){return e.replace(/[\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\u0f29\u0f20]/g,function(_){return p[_]})},postformat:function(e){return e.replace(/\d/g,function(_){return u[_]})},meridiemParse:/\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c|\u0f5e\u0f7c\u0f42\u0f66\u0f0b\u0f40\u0f66|\u0f49\u0f72\u0f53\u0f0b\u0f42\u0f74\u0f44|\u0f51\u0f42\u0f7c\u0f44\u0f0b\u0f51\u0f42|\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c/,meridiemHour:function(e,_){return 12===e&&(e=0),"\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c"===_&&e>=4||"\u0f49\u0f72\u0f53\u0f0b\u0f42\u0f74\u0f44"===_&&e<5||"\u0f51\u0f42\u0f7c\u0f44\u0f0b\u0f51\u0f42"===_?e+12:e},meridiem:function(e,_,y){return e<4?"\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c":e<10?"\u0f5e\u0f7c\u0f42\u0f66\u0f0b\u0f40\u0f66":e<17?"\u0f49\u0f72\u0f53\u0f0b\u0f42\u0f74\u0f44":e<20?"\u0f51\u0f42\u0f7c\u0f44\u0f0b\u0f51\u0f42":"\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c"},week:{dow:0,doy:6}})}(i(16738))},46728:function(v,T,i){!function(r){"use strict";function u(ee,ue,ae){return ee+" "+function(ee,ue){return 2===ue?function(ee){var ue={m:"v",b:"v",d:"z"};return void 0===ue[ee.charAt(0)]?ee:ue[ee.charAt(0)]+ee.substring(1)}(ee):ee}({mm:"munutenn",MM:"miz",dd:"devezh"}[ae],ee)}function d(ee){return ee>9?d(ee%10):ee}var y=[/^gen/i,/^c[\u02bc\']hwe/i,/^meu/i,/^ebr/i,/^mae/i,/^(mez|eve)/i,/^gou/i,/^eos/i,/^gwe/i,/^her/i,/^du/i,/^ker/i],S=/^(genver|c[\u02bc\']hwevrer|meurzh|ebrel|mae|mezheven|gouere|eost|gwengolo|here|du|kerzu|gen|c[\u02bc\']hwe|meu|ebr|mae|eve|gou|eos|gwe|her|du|ker)/i,J=[/^Su/i,/^Lu/i,/^Me([^r]|$)/i,/^Mer/i,/^Ya/i,/^Gw/i,/^Sa/i];r.defineLocale("br",{months:"Genver_C\u02bchwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu".split("_"),monthsShort:"Gen_C\u02bchwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker".split("_"),weekdays:"Sul_Lun_Meurzh_Merc\u02bcher_Yaou_Gwener_Sadorn".split("_"),weekdaysShort:"Sul_Lun_Meu_Mer_Yao_Gwe_Sad".split("_"),weekdaysMin:"Su_Lu_Me_Mer_Ya_Gw_Sa".split("_"),weekdaysParse:J,fullWeekdaysParse:[/^sul/i,/^lun/i,/^meurzh/i,/^merc[\u02bc\']her/i,/^yaou/i,/^gwener/i,/^sadorn/i],shortWeekdaysParse:[/^Sul/i,/^Lun/i,/^Meu/i,/^Mer/i,/^Yao/i,/^Gwe/i,/^Sad/i],minWeekdaysParse:J,monthsRegex:S,monthsShortRegex:S,monthsStrictRegex:/^(genver|c[\u02bc\']hwevrer|meurzh|ebrel|mae|mezheven|gouere|eost|gwengolo|here|du|kerzu)/i,monthsShortStrictRegex:/^(gen|c[\u02bc\']hwe|meu|ebr|mae|eve|gou|eos|gwe|her|du|ker)/i,monthsParse:y,longMonthsParse:y,shortMonthsParse:y,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [a viz] MMMM YYYY",LLL:"D [a viz] MMMM YYYY HH:mm",LLLL:"dddd, D [a viz] MMMM YYYY HH:mm"},calendar:{sameDay:"[Hiziv da] LT",nextDay:"[Warc\u02bchoazh da] LT",nextWeek:"dddd [da] LT",lastDay:"[Dec\u02bch da] LT",lastWeek:"dddd [paset da] LT",sameElse:"L"},relativeTime:{future:"a-benn %s",past:"%s \u02bczo",s:"un nebeud segondenno\xf9",ss:"%d eilenn",m:"ur vunutenn",mm:u,h:"un eur",hh:"%d eur",d:"un devezh",dd:u,M:"ur miz",MM:u,y:"ur bloaz",yy:function(ee){switch(d(ee)){case 1:case 3:case 4:case 5:case 9:return ee+" bloaz";default:return ee+" vloaz"}}},dayOfMonthOrdinalParse:/\d{1,2}(a\xf1|vet)/,ordinal:function(ee){return ee+(1===ee?"a\xf1":"vet")},week:{dow:1,doy:4},meridiemParse:/a.m.|g.m./,isPM:function(ee){return"g.m."===ee},meridiem:function(ee,ue,ae){return ee<12?"a.m.":"g.m."}})}(i(16738))},5536:function(v,T,i){!function(r){"use strict";function u(d,e,_){var y=d+" ";switch(_){case"ss":return y+(1===d?"sekunda":2===d||3===d||4===d?"sekunde":"sekundi");case"m":return e?"jedna minuta":"jedne minute";case"mm":return y+(1===d?"minuta":2===d||3===d||4===d?"minute":"minuta");case"h":return e?"jedan sat":"jednog sata";case"hh":return y+(1===d?"sat":2===d||3===d||4===d?"sata":"sati");case"dd":return y+(1===d?"dan":"dana");case"MM":return y+(1===d?"mjesec":2===d||3===d||4===d?"mjeseca":"mjeseci");case"yy":return y+(1===d?"godina":2===d||3===d||4===d?"godine":"godina")}}r.defineLocale("bs",{months:"januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_\u010detvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._\u010det._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_\u010de_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[ju\u010der u] LT",lastWeek:function(){switch(this.day()){case 0:case 3:return"[pro\u0161lu] dddd [u] LT";case 6:return"[pro\u0161le] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[pro\u0161li] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",ss:u,m:u,mm:u,h:u,hh:u,d:"dan",dd:u,M:"mjesec",MM:u,y:"godinu",yy:u},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(i(16738))},41043:function(v,T,i){!function(r){"use strict";r.defineLocale("ca",{months:{standalone:"gener_febrer_mar\xe7_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"),format:"de gener_de febrer_de mar\xe7_d'abril_de maig_de juny_de juliol_d'agost_de setembre_d'octubre_de novembre_de desembre".split("_"),isFormat:/D[oD]?(\s)+MMMM/},monthsShort:"gen._febr._mar\xe7_abr._maig_juny_jul._ag._set._oct._nov._des.".split("_"),monthsParseExact:!0,weekdays:"diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"),weekdaysShort:"dg._dl._dt._dc._dj._dv._ds.".split("_"),weekdaysMin:"dg_dl_dt_dc_dj_dv_ds".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [de] YYYY",ll:"D MMM YYYY",LLL:"D MMMM [de] YYYY [a les] H:mm",lll:"D MMM YYYY, H:mm",LLLL:"dddd D MMMM [de] YYYY [a les] H:mm",llll:"ddd D MMM YYYY, H:mm"},calendar:{sameDay:function(){return"[avui a "+(1!==this.hours()?"les":"la")+"] LT"},nextDay:function(){return"[dem\xe0 a "+(1!==this.hours()?"les":"la")+"] LT"},nextWeek:function(){return"dddd [a "+(1!==this.hours()?"les":"la")+"] LT"},lastDay:function(){return"[ahir a "+(1!==this.hours()?"les":"la")+"] LT"},lastWeek:function(){return"[el] dddd [passat a "+(1!==this.hours()?"les":"la")+"] LT"},sameElse:"L"},relativeTime:{future:"d'aqu\xed %s",past:"fa %s",s:"uns segons",ss:"%d segons",m:"un minut",mm:"%d minuts",h:"una hora",hh:"%d hores",d:"un dia",dd:"%d dies",M:"un mes",MM:"%d mesos",y:"un any",yy:"%d anys"},dayOfMonthOrdinalParse:/\d{1,2}(r|n|t|\xe8|a)/,ordinal:function(p,d){var e=1===p?"r":2===p?"n":3===p?"r":4===p?"t":"\xe8";return("w"===d||"W"===d)&&(e="a"),p+e},week:{dow:1,doy:4}})}(i(16738))},70420:function(v,T,i){!function(r){"use strict";var u={format:"leden_\xfanor_b\u0159ezen_duben_kv\u011bten_\u010derven_\u010dervenec_srpen_z\xe1\u0159\xed_\u0159\xedjen_listopad_prosinec".split("_"),standalone:"ledna_\xfanora_b\u0159ezna_dubna_kv\u011btna_\u010dervna_\u010dervence_srpna_z\xe1\u0159\xed_\u0159\xedjna_listopadu_prosince".split("_")},p="led_\xfano_b\u0159e_dub_kv\u011b_\u010dvn_\u010dvc_srp_z\xe1\u0159_\u0159\xedj_lis_pro".split("_"),d=[/^led/i,/^\xfano/i,/^b\u0159e/i,/^dub/i,/^kv\u011b/i,/^(\u010dvn|\u010derven$|\u010dervna)/i,/^(\u010dvc|\u010dervenec|\u010dervence)/i,/^srp/i,/^z\xe1\u0159/i,/^\u0159\xedj/i,/^lis/i,/^pro/i],e=/^(leden|\xfanor|b\u0159ezen|duben|kv\u011bten|\u010dervenec|\u010dervence|\u010derven|\u010dervna|srpen|z\xe1\u0159\xed|\u0159\xedjen|listopad|prosinec|led|\xfano|b\u0159e|dub|kv\u011b|\u010dvn|\u010dvc|srp|z\xe1\u0159|\u0159\xedj|lis|pro)/i;function _(A){return A>1&&A<5&&1!=~~(A/10)}function y(A,N,L,Z){var J=A+" ";switch(L){case"s":return N||Z?"p\xe1r sekund":"p\xe1r sekundami";case"ss":return N||Z?J+(_(A)?"sekundy":"sekund"):J+"sekundami";case"m":return N?"minuta":Z?"minutu":"minutou";case"mm":return N||Z?J+(_(A)?"minuty":"minut"):J+"minutami";case"h":return N?"hodina":Z?"hodinu":"hodinou";case"hh":return N||Z?J+(_(A)?"hodiny":"hodin"):J+"hodinami";case"d":return N||Z?"den":"dnem";case"dd":return N||Z?J+(_(A)?"dny":"dn\xed"):J+"dny";case"M":return N||Z?"m\u011bs\xedc":"m\u011bs\xedcem";case"MM":return N||Z?J+(_(A)?"m\u011bs\xedce":"m\u011bs\xedc\u016f"):J+"m\u011bs\xedci";case"y":return N||Z?"rok":"rokem";case"yy":return N||Z?J+(_(A)?"roky":"let"):J+"lety"}}r.defineLocale("cs",{months:u,monthsShort:p,monthsRegex:e,monthsShortRegex:e,monthsStrictRegex:/^(leden|ledna|\xfanora|\xfanor|b\u0159ezen|b\u0159ezna|duben|dubna|kv\u011bten|kv\u011btna|\u010dervenec|\u010dervence|\u010derven|\u010dervna|srpen|srpna|z\xe1\u0159\xed|\u0159\xedjen|\u0159\xedjna|listopadu|listopad|prosinec|prosince)/i,monthsShortStrictRegex:/^(led|\xfano|b\u0159e|dub|kv\u011b|\u010dvn|\u010dvc|srp|z\xe1\u0159|\u0159\xedj|lis|pro)/i,monthsParse:d,longMonthsParse:d,shortMonthsParse:d,weekdays:"ned\u011ble_pond\u011bl\xed_\xfater\xfd_st\u0159eda_\u010dtvrtek_p\xe1tek_sobota".split("_"),weekdaysShort:"ne_po_\xfat_st_\u010dt_p\xe1_so".split("_"),weekdaysMin:"ne_po_\xfat_st_\u010dt_p\xe1_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm",l:"D. M. YYYY"},calendar:{sameDay:"[dnes v] LT",nextDay:"[z\xedtra v] LT",nextWeek:function(){switch(this.day()){case 0:return"[v ned\u011bli v] LT";case 1:case 2:return"[v] dddd [v] LT";case 3:return"[ve st\u0159edu v] LT";case 4:return"[ve \u010dtvrtek v] LT";case 5:return"[v p\xe1tek v] LT";case 6:return"[v sobotu v] LT"}},lastDay:"[v\u010dera v] LT",lastWeek:function(){switch(this.day()){case 0:return"[minulou ned\u011bli v] LT";case 1:case 2:return"[minul\xe9] dddd [v] LT";case 3:return"[minulou st\u0159edu v] LT";case 4:case 5:return"[minul\xfd] dddd [v] LT";case 6:return"[minulou sobotu v] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"p\u0159ed %s",s:y,ss:y,m:y,mm:y,h:y,hh:y,d:y,dd:y,M:y,MM:y,y,yy:y},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},33513:function(v,T,i){!function(r){"use strict";r.defineLocale("cv",{months:"\u043a\u04d1\u0440\u043b\u0430\u0447_\u043d\u0430\u0440\u04d1\u0441_\u043f\u0443\u0448_\u0430\u043a\u0430_\u043c\u0430\u0439_\u04ab\u04d7\u0440\u0442\u043c\u0435_\u0443\u0442\u04d1_\u04ab\u0443\u0440\u043b\u0430_\u0430\u0432\u04d1\u043d_\u044e\u043f\u0430_\u0447\u04f3\u043a_\u0440\u0430\u0448\u0442\u0430\u0432".split("_"),monthsShort:"\u043a\u04d1\u0440_\u043d\u0430\u0440_\u043f\u0443\u0448_\u0430\u043a\u0430_\u043c\u0430\u0439_\u04ab\u04d7\u0440_\u0443\u0442\u04d1_\u04ab\u0443\u0440_\u0430\u0432\u043d_\u044e\u043f\u0430_\u0447\u04f3\u043a_\u0440\u0430\u0448".split("_"),weekdays:"\u0432\u044b\u0440\u0441\u0430\u0440\u043d\u0438\u043a\u0443\u043d_\u0442\u0443\u043d\u0442\u0438\u043a\u0443\u043d_\u044b\u0442\u043b\u0430\u0440\u0438\u043a\u0443\u043d_\u044e\u043d\u043a\u0443\u043d_\u043a\u04d7\u04ab\u043d\u0435\u0440\u043d\u0438\u043a\u0443\u043d_\u044d\u0440\u043d\u0435\u043a\u0443\u043d_\u0448\u04d1\u043c\u0430\u0442\u043a\u0443\u043d".split("_"),weekdaysShort:"\u0432\u044b\u0440_\u0442\u0443\u043d_\u044b\u0442\u043b_\u044e\u043d_\u043a\u04d7\u04ab_\u044d\u0440\u043d_\u0448\u04d1\u043c".split("_"),weekdaysMin:"\u0432\u0440_\u0442\u043d_\u044b\u0442_\u044e\u043d_\u043a\u04ab_\u044d\u0440_\u0448\u043c".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"YYYY [\u04ab\u0443\u043b\u0445\u0438] MMMM [\u0443\u0439\u04d1\u0445\u04d7\u043d] D[-\u043c\u04d7\u0448\u04d7]",LLL:"YYYY [\u04ab\u0443\u043b\u0445\u0438] MMMM [\u0443\u0439\u04d1\u0445\u04d7\u043d] D[-\u043c\u04d7\u0448\u04d7], HH:mm",LLLL:"dddd, YYYY [\u04ab\u0443\u043b\u0445\u0438] MMMM [\u0443\u0439\u04d1\u0445\u04d7\u043d] D[-\u043c\u04d7\u0448\u04d7], HH:mm"},calendar:{sameDay:"[\u041f\u0430\u044f\u043d] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",nextDay:"[\u042b\u0440\u0430\u043d] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",lastDay:"[\u04d6\u043d\u0435\u0440] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",nextWeek:"[\u04aa\u0438\u0442\u0435\u0441] dddd LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",lastWeek:"[\u0418\u0440\u0442\u043d\u04d7] dddd LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",sameElse:"L"},relativeTime:{future:function(p){return p+(/\u0441\u0435\u0445\u0435\u0442$/i.exec(p)?"\u0440\u0435\u043d":/\u04ab\u0443\u043b$/i.exec(p)?"\u0442\u0430\u043d":"\u0440\u0430\u043d")},past:"%s \u043a\u0430\u044f\u043b\u043b\u0430",s:"\u043f\u04d7\u0440-\u0438\u043a \u04ab\u0435\u043a\u043a\u0443\u043d\u0442",ss:"%d \u04ab\u0435\u043a\u043a\u0443\u043d\u0442",m:"\u043f\u04d7\u0440 \u043c\u0438\u043d\u0443\u0442",mm:"%d \u043c\u0438\u043d\u0443\u0442",h:"\u043f\u04d7\u0440 \u0441\u0435\u0445\u0435\u0442",hh:"%d \u0441\u0435\u0445\u0435\u0442",d:"\u043f\u04d7\u0440 \u043a\u0443\u043d",dd:"%d \u043a\u0443\u043d",M:"\u043f\u04d7\u0440 \u0443\u0439\u04d1\u0445",MM:"%d \u0443\u0439\u04d1\u0445",y:"\u043f\u04d7\u0440 \u04ab\u0443\u043b",yy:"%d \u04ab\u0443\u043b"},dayOfMonthOrdinalParse:/\d{1,2}-\u043c\u04d7\u0448/,ordinal:"%d-\u043c\u04d7\u0448",week:{dow:1,doy:7}})}(i(16738))},6771:function(v,T,i){!function(r){"use strict";r.defineLocale("cy",{months:"Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr".split("_"),monthsShort:"Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag".split("_"),weekdays:"Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn".split("_"),weekdaysShort:"Sul_Llun_Maw_Mer_Iau_Gwe_Sad".split("_"),weekdaysMin:"Su_Ll_Ma_Me_Ia_Gw_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Heddiw am] LT",nextDay:"[Yfory am] LT",nextWeek:"dddd [am] LT",lastDay:"[Ddoe am] LT",lastWeek:"dddd [diwethaf am] LT",sameElse:"L"},relativeTime:{future:"mewn %s",past:"%s yn \xf4l",s:"ychydig eiliadau",ss:"%d eiliad",m:"munud",mm:"%d munud",h:"awr",hh:"%d awr",d:"diwrnod",dd:"%d diwrnod",M:"mis",MM:"%d mis",y:"blwyddyn",yy:"%d flynedd"},dayOfMonthOrdinalParse:/\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,ordinal:function(p){var e="";return p>20?e=40===p||50===p||60===p||80===p||100===p?"fed":"ain":p>0&&(e=["","af","il","ydd","ydd","ed","ed","ed","fed","fed","fed","eg","fed","eg","eg","fed","eg","eg","fed","eg","fed"][p]),p+e},week:{dow:1,doy:4}})}(i(16738))},47978:function(v,T,i){!function(r){"use strict";r.defineLocale("da",{months:"januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"s\xf8ndag_mandag_tirsdag_onsdag_torsdag_fredag_l\xf8rdag".split("_"),weekdaysShort:"s\xf8n_man_tir_ons_tor_fre_l\xf8r".split("_"),weekdaysMin:"s\xf8_ma_ti_on_to_fr_l\xf8".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd [d.] D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[i dag kl.] LT",nextDay:"[i morgen kl.] LT",nextWeek:"p\xe5 dddd [kl.] LT",lastDay:"[i g\xe5r kl.] LT",lastWeek:"[i] dddd[s kl.] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"f\xe5 sekunder",ss:"%d sekunder",m:"et minut",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dage",M:"en m\xe5ned",MM:"%d m\xe5neder",y:"et \xe5r",yy:"%d \xe5r"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},25204:function(v,T,i){!function(r){"use strict";function u(d,e,_,y){var S={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[d+" Tage",d+" Tagen"],w:["eine Woche","einer Woche"],M:["ein Monat","einem Monat"],MM:[d+" Monate",d+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[d+" Jahre",d+" Jahren"]};return e?S[_][0]:S[_][1]}r.defineLocale("de-at",{months:"J\xe4nner_Februar_M\xe4rz_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"J\xe4n._Feb._M\xe4rz_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:u,mm:"%d Minuten",h:u,hh:"%d Stunden",d:u,dd:u,w:u,ww:"%d Wochen",M:u,MM:u,y:u,yy:u},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},2653:function(v,T,i){!function(r){"use strict";function u(d,e,_,y){var S={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[d+" Tage",d+" Tagen"],w:["eine Woche","einer Woche"],M:["ein Monat","einem Monat"],MM:[d+" Monate",d+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[d+" Jahre",d+" Jahren"]};return e?S[_][0]:S[_][1]}r.defineLocale("de-ch",{months:"Januar_Februar_M\xe4rz_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Feb._M\xe4rz_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:u,mm:"%d Minuten",h:u,hh:"%d Stunden",d:u,dd:u,w:u,ww:"%d Wochen",M:u,MM:u,y:u,yy:u},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},46061:function(v,T,i){!function(r){"use strict";function u(d,e,_,y){var S={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[d+" Tage",d+" Tagen"],w:["eine Woche","einer Woche"],M:["ein Monat","einem Monat"],MM:[d+" Monate",d+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[d+" Jahre",d+" Jahren"]};return e?S[_][0]:S[_][1]}r.defineLocale("de",{months:"Januar_Februar_M\xe4rz_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Feb._M\xe4rz_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:u,mm:"%d Minuten",h:u,hh:"%d Stunden",d:u,dd:u,w:u,ww:"%d Wochen",M:u,MM:u,y:u,yy:u},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},85:function(v,T,i){!function(r){"use strict";var u=["\u0796\u07ac\u0782\u07aa\u0787\u07a6\u0783\u07a9","\u078a\u07ac\u0784\u07b0\u0783\u07aa\u0787\u07a6\u0783\u07a9","\u0789\u07a7\u0783\u07a8\u0797\u07aa","\u0787\u07ad\u0795\u07b0\u0783\u07a9\u078d\u07aa","\u0789\u07ad","\u0796\u07ab\u0782\u07b0","\u0796\u07aa\u078d\u07a6\u0787\u07a8","\u0787\u07af\u078e\u07a6\u0790\u07b0\u0793\u07aa","\u0790\u07ac\u0795\u07b0\u0793\u07ac\u0789\u07b0\u0784\u07a6\u0783\u07aa","\u0787\u07ae\u0786\u07b0\u0793\u07af\u0784\u07a6\u0783\u07aa","\u0782\u07ae\u0788\u07ac\u0789\u07b0\u0784\u07a6\u0783\u07aa","\u0791\u07a8\u0790\u07ac\u0789\u07b0\u0784\u07a6\u0783\u07aa"],p=["\u0787\u07a7\u078b\u07a8\u0787\u07b0\u078c\u07a6","\u0780\u07af\u0789\u07a6","\u0787\u07a6\u0782\u07b0\u078e\u07a7\u0783\u07a6","\u0784\u07aa\u078b\u07a6","\u0784\u07aa\u0783\u07a7\u0790\u07b0\u078a\u07a6\u078c\u07a8","\u0780\u07aa\u0786\u07aa\u0783\u07aa","\u0780\u07ae\u0782\u07a8\u0780\u07a8\u0783\u07aa"];r.defineLocale("dv",{months:u,monthsShort:u,weekdays:p,weekdaysShort:p,weekdaysMin:"\u0787\u07a7\u078b\u07a8_\u0780\u07af\u0789\u07a6_\u0787\u07a6\u0782\u07b0_\u0784\u07aa\u078b\u07a6_\u0784\u07aa\u0783\u07a7_\u0780\u07aa\u0786\u07aa_\u0780\u07ae\u0782\u07a8".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/M/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0789\u0786|\u0789\u078a/,isPM:function(e){return"\u0789\u078a"===e},meridiem:function(e,_,y){return e<12?"\u0789\u0786":"\u0789\u078a"},calendar:{sameDay:"[\u0789\u07a8\u0787\u07a6\u078b\u07aa] LT",nextDay:"[\u0789\u07a7\u078b\u07a6\u0789\u07a7] LT",nextWeek:"dddd LT",lastDay:"[\u0787\u07a8\u0787\u07b0\u0794\u07ac] LT",lastWeek:"[\u078a\u07a7\u0787\u07a8\u078c\u07aa\u0788\u07a8] dddd LT",sameElse:"L"},relativeTime:{future:"\u078c\u07ac\u0783\u07ad\u078e\u07a6\u0787\u07a8 %s",past:"\u0786\u07aa\u0783\u07a8\u0782\u07b0 %s",s:"\u0790\u07a8\u0786\u07aa\u0782\u07b0\u078c\u07aa\u0786\u07ae\u0785\u07ac\u0787\u07b0",ss:"d% \u0790\u07a8\u0786\u07aa\u0782\u07b0\u078c\u07aa",m:"\u0789\u07a8\u0782\u07a8\u0793\u07ac\u0787\u07b0",mm:"\u0789\u07a8\u0782\u07a8\u0793\u07aa %d",h:"\u078e\u07a6\u0791\u07a8\u0787\u07a8\u0783\u07ac\u0787\u07b0",hh:"\u078e\u07a6\u0791\u07a8\u0787\u07a8\u0783\u07aa %d",d:"\u078b\u07aa\u0788\u07a6\u0780\u07ac\u0787\u07b0",dd:"\u078b\u07aa\u0788\u07a6\u0790\u07b0 %d",M:"\u0789\u07a6\u0780\u07ac\u0787\u07b0",MM:"\u0789\u07a6\u0790\u07b0 %d",y:"\u0787\u07a6\u0780\u07a6\u0783\u07ac\u0787\u07b0",yy:"\u0787\u07a6\u0780\u07a6\u0783\u07aa %d"},preparse:function(e){return e.replace(/\u060c/g,",")},postformat:function(e){return e.replace(/,/g,"\u060c")},week:{dow:7,doy:12}})}(i(16738))},8579:function(v,T,i){!function(r){"use strict";r.defineLocale("el",{monthsNominativeEl:"\u0399\u03b1\u03bd\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2_\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2_\u039c\u03ac\u03c1\u03c4\u03b9\u03bf\u03c2_\u0391\u03c0\u03c1\u03af\u03bb\u03b9\u03bf\u03c2_\u039c\u03ac\u03b9\u03bf\u03c2_\u0399\u03bf\u03cd\u03bd\u03b9\u03bf\u03c2_\u0399\u03bf\u03cd\u03bb\u03b9\u03bf\u03c2_\u0391\u03cd\u03b3\u03bf\u03c5\u03c3\u03c4\u03bf\u03c2_\u03a3\u03b5\u03c0\u03c4\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2_\u039f\u03ba\u03c4\u03ce\u03b2\u03c1\u03b9\u03bf\u03c2_\u039d\u03bf\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2_\u0394\u03b5\u03ba\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2".split("_"),monthsGenitiveEl:"\u0399\u03b1\u03bd\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5_\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5_\u039c\u03b1\u03c1\u03c4\u03af\u03bf\u03c5_\u0391\u03c0\u03c1\u03b9\u03bb\u03af\u03bf\u03c5_\u039c\u03b1\u0390\u03bf\u03c5_\u0399\u03bf\u03c5\u03bd\u03af\u03bf\u03c5_\u0399\u03bf\u03c5\u03bb\u03af\u03bf\u03c5_\u0391\u03c5\u03b3\u03bf\u03cd\u03c3\u03c4\u03bf\u03c5_\u03a3\u03b5\u03c0\u03c4\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5_\u039f\u03ba\u03c4\u03c9\u03b2\u03c1\u03af\u03bf\u03c5_\u039d\u03bf\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5_\u0394\u03b5\u03ba\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5".split("_"),months:function(d,e){return d?"string"==typeof e&&/D/.test(e.substring(0,e.indexOf("MMMM")))?this._monthsGenitiveEl[d.month()]:this._monthsNominativeEl[d.month()]:this._monthsNominativeEl},monthsShort:"\u0399\u03b1\u03bd_\u03a6\u03b5\u03b2_\u039c\u03b1\u03c1_\u0391\u03c0\u03c1_\u039c\u03b1\u03ca_\u0399\u03bf\u03c5\u03bd_\u0399\u03bf\u03c5\u03bb_\u0391\u03c5\u03b3_\u03a3\u03b5\u03c0_\u039f\u03ba\u03c4_\u039d\u03bf\u03b5_\u0394\u03b5\u03ba".split("_"),weekdays:"\u039a\u03c5\u03c1\u03b9\u03b1\u03ba\u03ae_\u0394\u03b5\u03c5\u03c4\u03ad\u03c1\u03b1_\u03a4\u03c1\u03af\u03c4\u03b7_\u03a4\u03b5\u03c4\u03ac\u03c1\u03c4\u03b7_\u03a0\u03ad\u03bc\u03c0\u03c4\u03b7_\u03a0\u03b1\u03c1\u03b1\u03c3\u03ba\u03b5\u03c5\u03ae_\u03a3\u03ac\u03b2\u03b2\u03b1\u03c4\u03bf".split("_"),weekdaysShort:"\u039a\u03c5\u03c1_\u0394\u03b5\u03c5_\u03a4\u03c1\u03b9_\u03a4\u03b5\u03c4_\u03a0\u03b5\u03bc_\u03a0\u03b1\u03c1_\u03a3\u03b1\u03b2".split("_"),weekdaysMin:"\u039a\u03c5_\u0394\u03b5_\u03a4\u03c1_\u03a4\u03b5_\u03a0\u03b5_\u03a0\u03b1_\u03a3\u03b1".split("_"),meridiem:function(d,e,_){return d>11?_?"\u03bc\u03bc":"\u039c\u039c":_?"\u03c0\u03bc":"\u03a0\u039c"},isPM:function(d){return"\u03bc"===(d+"").toLowerCase()[0]},meridiemParse:/[\u03a0\u039c]\.?\u039c?\.?/i,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendarEl:{sameDay:"[\u03a3\u03ae\u03bc\u03b5\u03c1\u03b1 {}] LT",nextDay:"[\u0391\u03cd\u03c1\u03b9\u03bf {}] LT",nextWeek:"dddd [{}] LT",lastDay:"[\u03a7\u03b8\u03b5\u03c2 {}] LT",lastWeek:function(){switch(this.day()){case 6:return"[\u03c4\u03bf \u03c0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03bf] dddd [{}] LT";default:return"[\u03c4\u03b7\u03bd \u03c0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03b7] dddd [{}] LT"}},sameElse:"L"},calendar:function(d,e){var _=this._calendarEl[d],y=e&&e.hours();return function(d){return"undefined"!=typeof Function&&d instanceof Function||"[object Function]"===Object.prototype.toString.call(d)}(_)&&(_=_.apply(e)),_.replace("{}",y%12==1?"\u03c3\u03c4\u03b7":"\u03c3\u03c4\u03b9\u03c2")},relativeTime:{future:"\u03c3\u03b5 %s",past:"%s \u03c0\u03c1\u03b9\u03bd",s:"\u03bb\u03af\u03b3\u03b1 \u03b4\u03b5\u03c5\u03c4\u03b5\u03c1\u03cc\u03bb\u03b5\u03c0\u03c4\u03b1",ss:"%d \u03b4\u03b5\u03c5\u03c4\u03b5\u03c1\u03cc\u03bb\u03b5\u03c0\u03c4\u03b1",m:"\u03ad\u03bd\u03b1 \u03bb\u03b5\u03c0\u03c4\u03cc",mm:"%d \u03bb\u03b5\u03c0\u03c4\u03ac",h:"\u03bc\u03af\u03b1 \u03ce\u03c1\u03b1",hh:"%d \u03ce\u03c1\u03b5\u03c2",d:"\u03bc\u03af\u03b1 \u03bc\u03ad\u03c1\u03b1",dd:"%d \u03bc\u03ad\u03c1\u03b5\u03c2",M:"\u03ad\u03bd\u03b1\u03c2 \u03bc\u03ae\u03bd\u03b1\u03c2",MM:"%d \u03bc\u03ae\u03bd\u03b5\u03c2",y:"\u03ad\u03bd\u03b1\u03c2 \u03c7\u03c1\u03cc\u03bd\u03bf\u03c2",yy:"%d \u03c7\u03c1\u03cc\u03bd\u03b9\u03b1"},dayOfMonthOrdinalParse:/\d{1,2}\u03b7/,ordinal:"%d\u03b7",week:{dow:1,doy:4}})}(i(16738))},25724:function(v,T,i){!function(r){"use strict";r.defineLocale("en-au",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(p){var d=p%10;return p+(1==~~(p%100/10)?"th":1===d?"st":2===d?"nd":3===d?"rd":"th")},week:{dow:0,doy:4}})}(i(16738))},10525:function(v,T,i){!function(r){"use strict";r.defineLocale("en-ca",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"YYYY-MM-DD",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(p){var d=p%10;return p+(1==~~(p%100/10)?"th":1===d?"st":2===d?"nd":3===d?"rd":"th")}})}(i(16738))},52847:function(v,T,i){!function(r){"use strict";r.defineLocale("en-gb",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(p){var d=p%10;return p+(1==~~(p%100/10)?"th":1===d?"st":2===d?"nd":3===d?"rd":"th")},week:{dow:1,doy:4}})}(i(16738))},67216:function(v,T,i){!function(r){"use strict";r.defineLocale("en-ie",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(p){var d=p%10;return p+(1==~~(p%100/10)?"th":1===d?"st":2===d?"nd":3===d?"rd":"th")},week:{dow:1,doy:4}})}(i(16738))},39305:function(v,T,i){!function(r){"use strict";r.defineLocale("en-il",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(p){var d=p%10;return p+(1==~~(p%100/10)?"th":1===d?"st":2===d?"nd":3===d?"rd":"th")}})}(i(16738))},73364:function(v,T,i){!function(r){"use strict";r.defineLocale("en-in",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(p){var d=p%10;return p+(1==~~(p%100/10)?"th":1===d?"st":2===d?"nd":3===d?"rd":"th")},week:{dow:0,doy:6}})}(i(16738))},79130:function(v,T,i){!function(r){"use strict";r.defineLocale("en-nz",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(p){var d=p%10;return p+(1==~~(p%100/10)?"th":1===d?"st":2===d?"nd":3===d?"rd":"th")},week:{dow:1,doy:4}})}(i(16738))},11161:function(v,T,i){!function(r){"use strict";r.defineLocale("en-sg",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(p){var d=p%10;return p+(1==~~(p%100/10)?"th":1===d?"st":2===d?"nd":3===d?"rd":"th")},week:{dow:1,doy:4}})}(i(16738))},50802:function(v,T,i){!function(r){"use strict";r.defineLocale("eo",{months:"januaro_februaro_marto_aprilo_majo_junio_julio_a\u016dgusto_septembro_oktobro_novembro_decembro".split("_"),monthsShort:"jan_feb_mart_apr_maj_jun_jul_a\u016dg_sept_okt_nov_dec".split("_"),weekdays:"diman\u0109o_lundo_mardo_merkredo_\u0135a\u016ddo_vendredo_sabato".split("_"),weekdaysShort:"dim_lun_mard_merk_\u0135a\u016d_ven_sab".split("_"),weekdaysMin:"di_lu_ma_me_\u0135a_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"[la] D[-an de] MMMM, YYYY",LLL:"[la] D[-an de] MMMM, YYYY HH:mm",LLLL:"dddd[n], [la] D[-an de] MMMM, YYYY HH:mm",llll:"ddd, [la] D[-an de] MMM, YYYY HH:mm"},meridiemParse:/[ap]\.t\.m/i,isPM:function(p){return"p"===p.charAt(0).toLowerCase()},meridiem:function(p,d,e){return p>11?e?"p.t.m.":"P.T.M.":e?"a.t.m.":"A.T.M."},calendar:{sameDay:"[Hodia\u016d je] LT",nextDay:"[Morga\u016d je] LT",nextWeek:"dddd[n je] LT",lastDay:"[Hiera\u016d je] LT",lastWeek:"[pasintan] dddd[n je] LT",sameElse:"L"},relativeTime:{future:"post %s",past:"anta\u016d %s",s:"kelkaj sekundoj",ss:"%d sekundoj",m:"unu minuto",mm:"%d minutoj",h:"unu horo",hh:"%d horoj",d:"unu tago",dd:"%d tagoj",M:"unu monato",MM:"%d monatoj",y:"unu jaro",yy:"%d jaroj"},dayOfMonthOrdinalParse:/\d{1,2}a/,ordinal:"%da",week:{dow:1,doy:7}})}(i(16738))},45551:function(v,T,i){!function(r){"use strict";var u="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),p="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),d=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],e=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;r.defineLocale("es-do",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(y,S){return y?/-MMM-/.test(S)?p[y.month()]:u[y.month()]:u},monthsRegex:e,monthsShortRegex:e,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:d,longMonthsParse:d,shortMonthsParse:d,weekdays:"domingo_lunes_martes_mi\xe9rcoles_jueves_viernes_s\xe1bado".split("_"),weekdaysShort:"dom._lun._mar._mi\xe9._jue._vie._s\xe1b.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY h:mm A",LLLL:"dddd, D [de] MMMM [de] YYYY h:mm A"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[ma\xf1ana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un d\xeda",dd:"%d d\xedas",w:"una semana",ww:"%d semanas",M:"un mes",MM:"%d meses",y:"un a\xf1o",yy:"%d a\xf1os"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}(i(16738))},75615:function(v,T,i){!function(r){"use strict";var u="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),p="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),d=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],e=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;r.defineLocale("es-mx",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(y,S){return y?/-MMM-/.test(S)?p[y.month()]:u[y.month()]:u},monthsRegex:e,monthsShortRegex:e,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:d,longMonthsParse:d,shortMonthsParse:d,weekdays:"domingo_lunes_martes_mi\xe9rcoles_jueves_viernes_s\xe1bado".split("_"),weekdaysShort:"dom._lun._mar._mi\xe9._jue._vie._s\xe1b.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[ma\xf1ana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un d\xeda",dd:"%d d\xedas",w:"una semana",ww:"%d semanas",M:"un mes",MM:"%d meses",y:"un a\xf1o",yy:"%d a\xf1os"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:0,doy:4},invalidDate:"Fecha inv\xe1lida"})}(i(16738))},64790:function(v,T,i){!function(r){"use strict";var u="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),p="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),d=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],e=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;r.defineLocale("es-us",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(y,S){return y?/-MMM-/.test(S)?p[y.month()]:u[y.month()]:u},monthsRegex:e,monthsShortRegex:e,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:d,longMonthsParse:d,shortMonthsParse:d,weekdays:"domingo_lunes_martes_mi\xe9rcoles_jueves_viernes_s\xe1bado".split("_"),weekdaysShort:"dom._lun._mar._mi\xe9._jue._vie._s\xe1b.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"MM/DD/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY h:mm A",LLLL:"dddd, D [de] MMMM [de] YYYY h:mm A"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[ma\xf1ana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un d\xeda",dd:"%d d\xedas",w:"una semana",ww:"%d semanas",M:"un mes",MM:"%d meses",y:"un a\xf1o",yy:"%d a\xf1os"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:0,doy:6}})}(i(16738))},40328:function(v,T,i){!function(r){"use strict";var u="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),p="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),d=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],e=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;r.defineLocale("es",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(y,S){return y?/-MMM-/.test(S)?p[y.month()]:u[y.month()]:u},monthsRegex:e,monthsShortRegex:e,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:d,longMonthsParse:d,shortMonthsParse:d,weekdays:"domingo_lunes_martes_mi\xe9rcoles_jueves_viernes_s\xe1bado".split("_"),weekdaysShort:"dom._lun._mar._mi\xe9._jue._vie._s\xe1b.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[ma\xf1ana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un d\xeda",dd:"%d d\xedas",w:"una semana",ww:"%d semanas",M:"un mes",MM:"%d meses",y:"un a\xf1o",yy:"%d a\xf1os"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4},invalidDate:"Fecha inv\xe1lida"})}(i(16738))},96389:function(v,T,i){!function(r){"use strict";function u(d,e,_,y){var S={s:["m\xf5ne sekundi","m\xf5ni sekund","paar sekundit"],ss:[d+"sekundi",d+"sekundit"],m:["\xfche minuti","\xfcks minut"],mm:[d+" minuti",d+" minutit"],h:["\xfche tunni","tund aega","\xfcks tund"],hh:[d+" tunni",d+" tundi"],d:["\xfche p\xe4eva","\xfcks p\xe4ev"],M:["kuu aja","kuu aega","\xfcks kuu"],MM:[d+" kuu",d+" kuud"],y:["\xfche aasta","aasta","\xfcks aasta"],yy:[d+" aasta",d+" aastat"]};return e?S[_][2]?S[_][2]:S[_][1]:y?S[_][0]:S[_][1]}r.defineLocale("et",{months:"jaanuar_veebruar_m\xe4rts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember".split("_"),monthsShort:"jaan_veebr_m\xe4rts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets".split("_"),weekdays:"p\xfchap\xe4ev_esmasp\xe4ev_teisip\xe4ev_kolmap\xe4ev_neljap\xe4ev_reede_laup\xe4ev".split("_"),weekdaysShort:"P_E_T_K_N_R_L".split("_"),weekdaysMin:"P_E_T_K_N_R_L".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[T\xe4na,] LT",nextDay:"[Homme,] LT",nextWeek:"[J\xe4rgmine] dddd LT",lastDay:"[Eile,] LT",lastWeek:"[Eelmine] dddd LT",sameElse:"L"},relativeTime:{future:"%s p\xe4rast",past:"%s tagasi",s:u,ss:u,m:u,mm:u,h:u,hh:u,d:u,dd:"%d p\xe4eva",M:u,MM:u,y:u,yy:u},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},52961:function(v,T,i){!function(r){"use strict";r.defineLocale("eu",{months:"urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua".split("_"),monthsShort:"urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.".split("_"),monthsParseExact:!0,weekdays:"igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata".split("_"),weekdaysShort:"ig._al._ar._az._og._ol._lr.".split("_"),weekdaysMin:"ig_al_ar_az_og_ol_lr".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY[ko] MMMM[ren] D[a]",LLL:"YYYY[ko] MMMM[ren] D[a] HH:mm",LLLL:"dddd, YYYY[ko] MMMM[ren] D[a] HH:mm",l:"YYYY-M-D",ll:"YYYY[ko] MMM D[a]",lll:"YYYY[ko] MMM D[a] HH:mm",llll:"ddd, YYYY[ko] MMM D[a] HH:mm"},calendar:{sameDay:"[gaur] LT[etan]",nextDay:"[bihar] LT[etan]",nextWeek:"dddd LT[etan]",lastDay:"[atzo] LT[etan]",lastWeek:"[aurreko] dddd LT[etan]",sameElse:"L"},relativeTime:{future:"%s barru",past:"duela %s",s:"segundo batzuk",ss:"%d segundo",m:"minutu bat",mm:"%d minutu",h:"ordu bat",hh:"%d ordu",d:"egun bat",dd:"%d egun",M:"hilabete bat",MM:"%d hilabete",y:"urte bat",yy:"%d urte"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(i(16738))},26151:function(v,T,i){!function(r){"use strict";var u={1:"\u06f1",2:"\u06f2",3:"\u06f3",4:"\u06f4",5:"\u06f5",6:"\u06f6",7:"\u06f7",8:"\u06f8",9:"\u06f9",0:"\u06f0"},p={"\u06f1":"1","\u06f2":"2","\u06f3":"3","\u06f4":"4","\u06f5":"5","\u06f6":"6","\u06f7":"7","\u06f8":"8","\u06f9":"9","\u06f0":"0"};r.defineLocale("fa",{months:"\u0698\u0627\u0646\u0648\u06cc\u0647_\u0641\u0648\u0631\u06cc\u0647_\u0645\u0627\u0631\u0633_\u0622\u0648\u0631\u06cc\u0644_\u0645\u0647_\u0698\u0648\u0626\u0646_\u0698\u0648\u0626\u06cc\u0647_\u0627\u0648\u062a_\u0633\u067e\u062a\u0627\u0645\u0628\u0631_\u0627\u06a9\u062a\u0628\u0631_\u0646\u0648\u0627\u0645\u0628\u0631_\u062f\u0633\u0627\u0645\u0628\u0631".split("_"),monthsShort:"\u0698\u0627\u0646\u0648\u06cc\u0647_\u0641\u0648\u0631\u06cc\u0647_\u0645\u0627\u0631\u0633_\u0622\u0648\u0631\u06cc\u0644_\u0645\u0647_\u0698\u0648\u0626\u0646_\u0698\u0648\u0626\u06cc\u0647_\u0627\u0648\u062a_\u0633\u067e\u062a\u0627\u0645\u0628\u0631_\u0627\u06a9\u062a\u0628\u0631_\u0646\u0648\u0627\u0645\u0628\u0631_\u062f\u0633\u0627\u0645\u0628\u0631".split("_"),weekdays:"\u06cc\u06a9\u200c\u0634\u0646\u0628\u0647_\u062f\u0648\u0634\u0646\u0628\u0647_\u0633\u0647\u200c\u0634\u0646\u0628\u0647_\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647_\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647_\u062c\u0645\u0639\u0647_\u0634\u0646\u0628\u0647".split("_"),weekdaysShort:"\u06cc\u06a9\u200c\u0634\u0646\u0628\u0647_\u062f\u0648\u0634\u0646\u0628\u0647_\u0633\u0647\u200c\u0634\u0646\u0628\u0647_\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647_\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647_\u062c\u0645\u0639\u0647_\u0634\u0646\u0628\u0647".split("_"),weekdaysMin:"\u06cc_\u062f_\u0633_\u0686_\u067e_\u062c_\u0634".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/\u0642\u0628\u0644 \u0627\u0632 \u0638\u0647\u0631|\u0628\u0639\u062f \u0627\u0632 \u0638\u0647\u0631/,isPM:function(e){return/\u0628\u0639\u062f \u0627\u0632 \u0638\u0647\u0631/.test(e)},meridiem:function(e,_,y){return e<12?"\u0642\u0628\u0644 \u0627\u0632 \u0638\u0647\u0631":"\u0628\u0639\u062f \u0627\u0632 \u0638\u0647\u0631"},calendar:{sameDay:"[\u0627\u0645\u0631\u0648\u0632 \u0633\u0627\u0639\u062a] LT",nextDay:"[\u0641\u0631\u062f\u0627 \u0633\u0627\u0639\u062a] LT",nextWeek:"dddd [\u0633\u0627\u0639\u062a] LT",lastDay:"[\u062f\u06cc\u0631\u0648\u0632 \u0633\u0627\u0639\u062a] LT",lastWeek:"dddd [\u067e\u06cc\u0634] [\u0633\u0627\u0639\u062a] LT",sameElse:"L"},relativeTime:{future:"\u062f\u0631 %s",past:"%s \u067e\u06cc\u0634",s:"\u0686\u0646\u062f \u062b\u0627\u0646\u06cc\u0647",ss:"%d \u062b\u0627\u0646\u06cc\u0647",m:"\u06cc\u06a9 \u062f\u0642\u06cc\u0642\u0647",mm:"%d \u062f\u0642\u06cc\u0642\u0647",h:"\u06cc\u06a9 \u0633\u0627\u0639\u062a",hh:"%d \u0633\u0627\u0639\u062a",d:"\u06cc\u06a9 \u0631\u0648\u0632",dd:"%d \u0631\u0648\u0632",M:"\u06cc\u06a9 \u0645\u0627\u0647",MM:"%d \u0645\u0627\u0647",y:"\u06cc\u06a9 \u0633\u0627\u0644",yy:"%d \u0633\u0627\u0644"},preparse:function(e){return e.replace(/[\u06f0-\u06f9]/g,function(_){return p[_]}).replace(/\u060c/g,",")},postformat:function(e){return e.replace(/\d/g,function(_){return u[_]}).replace(/,/g,"\u060c")},dayOfMonthOrdinalParse:/\d{1,2}\u0645/,ordinal:"%d\u0645",week:{dow:6,doy:12}})}(i(16738))},7997:function(v,T,i){!function(r){"use strict";var u="nolla yksi kaksi kolme nelj\xe4 viisi kuusi seitsem\xe4n kahdeksan yhdeks\xe4n".split(" "),p=["nolla","yhden","kahden","kolmen","nelj\xe4n","viiden","kuuden",u[7],u[8],u[9]];function d(y,S,A,N){var L="";switch(A){case"s":return N?"muutaman sekunnin":"muutama sekunti";case"ss":L=N?"sekunnin":"sekuntia";break;case"m":return N?"minuutin":"minuutti";case"mm":L=N?"minuutin":"minuuttia";break;case"h":return N?"tunnin":"tunti";case"hh":L=N?"tunnin":"tuntia";break;case"d":return N?"p\xe4iv\xe4n":"p\xe4iv\xe4";case"dd":L=N?"p\xe4iv\xe4n":"p\xe4iv\xe4\xe4";break;case"M":return N?"kuukauden":"kuukausi";case"MM":L=N?"kuukauden":"kuukautta";break;case"y":return N?"vuoden":"vuosi";case"yy":L=N?"vuoden":"vuotta"}return function(y,S){return y<10?S?p[y]:u[y]:y}(y,N)+" "+L}r.defineLocale("fi",{months:"tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kes\xe4kuu_hein\xe4kuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),monthsShort:"tammi_helmi_maalis_huhti_touko_kes\xe4_hein\xe4_elo_syys_loka_marras_joulu".split("_"),weekdays:"sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),weekdaysShort:"su_ma_ti_ke_to_pe_la".split("_"),weekdaysMin:"su_ma_ti_ke_to_pe_la".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"Do MMMM[ta] YYYY",LLL:"Do MMMM[ta] YYYY, [klo] HH.mm",LLLL:"dddd, Do MMMM[ta] YYYY, [klo] HH.mm",l:"D.M.YYYY",ll:"Do MMM YYYY",lll:"Do MMM YYYY, [klo] HH.mm",llll:"ddd, Do MMM YYYY, [klo] HH.mm"},calendar:{sameDay:"[t\xe4n\xe4\xe4n] [klo] LT",nextDay:"[huomenna] [klo] LT",nextWeek:"dddd [klo] LT",lastDay:"[eilen] [klo] LT",lastWeek:"[viime] dddd[na] [klo] LT",sameElse:"L"},relativeTime:{future:"%s p\xe4\xe4st\xe4",past:"%s sitten",s:d,ss:d,m:d,mm:d,h:d,hh:d,d,dd:d,M:d,MM:d,y:d,yy:d},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},58898:function(v,T,i){!function(r){"use strict";r.defineLocale("fil",{months:"Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre".split("_"),monthsShort:"Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis".split("_"),weekdays:"Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado".split("_"),weekdaysShort:"Lin_Lun_Mar_Miy_Huw_Biy_Sab".split("_"),weekdaysMin:"Li_Lu_Ma_Mi_Hu_Bi_Sab".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"MM/D/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY HH:mm",LLLL:"dddd, MMMM DD, YYYY HH:mm"},calendar:{sameDay:"LT [ngayong araw]",nextDay:"[Bukas ng] LT",nextWeek:"LT [sa susunod na] dddd",lastDay:"LT [kahapon]",lastWeek:"LT [noong nakaraang] dddd",sameElse:"L"},relativeTime:{future:"sa loob ng %s",past:"%s ang nakalipas",s:"ilang segundo",ss:"%d segundo",m:"isang minuto",mm:"%d minuto",h:"isang oras",hh:"%d oras",d:"isang araw",dd:"%d araw",M:"isang buwan",MM:"%d buwan",y:"isang taon",yy:"%d taon"},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:function(p){return p},week:{dow:1,doy:4}})}(i(16738))},37779:function(v,T,i){!function(r){"use strict";r.defineLocale("fo",{months:"januar_februar_mars_apr\xedl_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),weekdays:"sunnudagur_m\xe1nadagur_t\xfdsdagur_mikudagur_h\xf3sdagur_fr\xedggjadagur_leygardagur".split("_"),weekdaysShort:"sun_m\xe1n_t\xfds_mik_h\xf3s_fr\xed_ley".split("_"),weekdaysMin:"su_m\xe1_t\xfd_mi_h\xf3_fr_le".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D. MMMM, YYYY HH:mm"},calendar:{sameDay:"[\xcd dag kl.] LT",nextDay:"[\xcd morgin kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[\xcd gj\xe1r kl.] LT",lastWeek:"[s\xed\xf0stu] dddd [kl] LT",sameElse:"L"},relativeTime:{future:"um %s",past:"%s s\xed\xf0ani",s:"f\xe1 sekund",ss:"%d sekundir",m:"ein minuttur",mm:"%d minuttir",h:"ein t\xedmi",hh:"%d t\xedmar",d:"ein dagur",dd:"%d dagar",M:"ein m\xe1na\xf0ur",MM:"%d m\xe1na\xf0ir",y:"eitt \xe1r",yy:"%d \xe1r"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},3287:function(v,T,i){!function(r){"use strict";r.defineLocale("fr-ca",{months:"janvier_f\xe9vrier_mars_avril_mai_juin_juillet_ao\xfbt_septembre_octobre_novembre_d\xe9cembre".split("_"),monthsShort:"janv._f\xe9vr._mars_avr._mai_juin_juil._ao\xfbt_sept._oct._nov._d\xe9c.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd\u2019hui \xe0] LT",nextDay:"[Demain \xe0] LT",nextWeek:"dddd [\xe0] LT",lastDay:"[Hier \xe0] LT",lastWeek:"dddd [dernier \xe0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|e)/,ordinal:function(p,d){switch(d){default:case"M":case"Q":case"D":case"DDD":case"d":return p+(1===p?"er":"e");case"w":case"W":return p+(1===p?"re":"e")}}})}(i(16738))},38867:function(v,T,i){!function(r){"use strict";r.defineLocale("fr-ch",{months:"janvier_f\xe9vrier_mars_avril_mai_juin_juillet_ao\xfbt_septembre_octobre_novembre_d\xe9cembre".split("_"),monthsShort:"janv._f\xe9vr._mars_avr._mai_juin_juil._ao\xfbt_sept._oct._nov._d\xe9c.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd\u2019hui \xe0] LT",nextDay:"[Demain \xe0] LT",nextWeek:"dddd [\xe0] LT",lastDay:"[Hier \xe0] LT",lastWeek:"dddd [dernier \xe0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|e)/,ordinal:function(p,d){switch(d){default:case"M":case"Q":case"D":case"DDD":case"d":return p+(1===p?"er":"e");case"w":case"W":return p+(1===p?"re":"e")}},week:{dow:1,doy:4}})}(i(16738))},28174:function(v,T,i){!function(r){"use strict";var d=/(janv\.?|f\xe9vr\.?|mars|avr\.?|mai|juin|juil\.?|ao\xfbt|sept\.?|oct\.?|nov\.?|d\xe9c\.?|janvier|f\xe9vrier|mars|avril|mai|juin|juillet|ao\xfbt|septembre|octobre|novembre|d\xe9cembre)/i,e=[/^janv/i,/^f\xe9vr/i,/^mars/i,/^avr/i,/^mai/i,/^juin/i,/^juil/i,/^ao\xfbt/i,/^sept/i,/^oct/i,/^nov/i,/^d\xe9c/i];r.defineLocale("fr",{months:"janvier_f\xe9vrier_mars_avril_mai_juin_juillet_ao\xfbt_septembre_octobre_novembre_d\xe9cembre".split("_"),monthsShort:"janv._f\xe9vr._mars_avr._mai_juin_juil._ao\xfbt_sept._oct._nov._d\xe9c.".split("_"),monthsRegex:d,monthsShortRegex:d,monthsStrictRegex:/^(janvier|f\xe9vrier|mars|avril|mai|juin|juillet|ao\xfbt|septembre|octobre|novembre|d\xe9cembre)/i,monthsShortStrictRegex:/(janv\.?|f\xe9vr\.?|mars|avr\.?|mai|juin|juil\.?|ao\xfbt|sept\.?|oct\.?|nov\.?|d\xe9c\.?)/i,monthsParse:e,longMonthsParse:e,shortMonthsParse:e,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd\u2019hui \xe0] LT",nextDay:"[Demain \xe0] LT",nextWeek:"dddd [\xe0] LT",lastDay:"[Hier \xe0] LT",lastWeek:"dddd [dernier \xe0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",w:"une semaine",ww:"%d semaines",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|)/,ordinal:function(y,S){switch(S){case"D":return y+(1===y?"er":"");default:case"M":case"Q":case"DDD":case"d":return y+(1===y?"er":"e");case"w":case"W":return y+(1===y?"re":"e")}},week:{dow:1,doy:4}})}(i(16738))},50452:function(v,T,i){!function(r){"use strict";var u="jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.".split("_"),p="jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_");r.defineLocale("fy",{months:"jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber".split("_"),monthsShort:function(e,_){return e?/-MMM-/.test(_)?p[e.month()]:u[e.month()]:u},monthsParseExact:!0,weekdays:"snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon".split("_"),weekdaysShort:"si._mo._ti._wo._to._fr._so.".split("_"),weekdaysMin:"Si_Mo_Ti_Wo_To_Fr_So".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[hjoed om] LT",nextDay:"[moarn om] LT",nextWeek:"dddd [om] LT",lastDay:"[juster om] LT",lastWeek:"[\xf4fr\xfbne] dddd [om] LT",sameElse:"L"},relativeTime:{future:"oer %s",past:"%s lyn",s:"in pear sekonden",ss:"%d sekonden",m:"ien min\xfat",mm:"%d minuten",h:"ien oere",hh:"%d oeren",d:"ien dei",dd:"%d dagen",M:"ien moanne",MM:"%d moannen",y:"ien jier",yy:"%d jierren"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(e){return e+(1===e||8===e||e>=20?"ste":"de")},week:{dow:1,doy:4}})}(i(16738))},45014:function(v,T,i){!function(r){"use strict";r.defineLocale("ga",{months:["Ean\xe1ir","Feabhra","M\xe1rta","Aibre\xe1n","Bealtaine","Meitheamh","I\xfail","L\xfanasa","Me\xe1n F\xf3mhair","Deireadh F\xf3mhair","Samhain","Nollaig"],monthsShort:["Ean","Feabh","M\xe1rt","Aib","Beal","Meith","I\xfail","L\xfan","M.F.","D.F.","Samh","Noll"],monthsParseExact:!0,weekdays:["D\xe9 Domhnaigh","D\xe9 Luain","D\xe9 M\xe1irt","D\xe9 C\xe9adaoin","D\xe9ardaoin","D\xe9 hAoine","D\xe9 Sathairn"],weekdaysShort:["Domh","Luan","M\xe1irt","C\xe9ad","D\xe9ar","Aoine","Sath"],weekdaysMin:["Do","Lu","M\xe1","C\xe9","D\xe9","A","Sa"],longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Inniu ag] LT",nextDay:"[Am\xe1rach ag] LT",nextWeek:"dddd [ag] LT",lastDay:"[Inn\xe9 ag] LT",lastWeek:"dddd [seo caite] [ag] LT",sameElse:"L"},relativeTime:{future:"i %s",past:"%s \xf3 shin",s:"c\xfapla soicind",ss:"%d soicind",m:"n\xf3im\xe9ad",mm:"%d n\xf3im\xe9ad",h:"uair an chloig",hh:"%d uair an chloig",d:"l\xe1",dd:"%d l\xe1",M:"m\xed",MM:"%d m\xedonna",y:"bliain",yy:"%d bliain"},dayOfMonthOrdinalParse:/\d{1,2}(d|na|mh)/,ordinal:function(S){return S+(1===S?"d":S%10==2?"na":"mh")},week:{dow:1,doy:4}})}(i(16738))},74127:function(v,T,i){!function(r){"use strict";r.defineLocale("gd",{months:["Am Faoilleach","An Gearran","Am M\xe0rt","An Giblean","An C\xe8itean","An t-\xd2gmhios","An t-Iuchar","An L\xf9nastal","An t-Sultain","An D\xe0mhair","An t-Samhain","An D\xf9bhlachd"],monthsShort:["Faoi","Gear","M\xe0rt","Gibl","C\xe8it","\xd2gmh","Iuch","L\xf9n","Sult","D\xe0mh","Samh","D\xf9bh"],monthsParseExact:!0,weekdays:["Did\xf2mhnaich","Diluain","Dim\xe0irt","Diciadain","Diardaoin","Dihaoine","Disathairne"],weekdaysShort:["Did","Dil","Dim","Dic","Dia","Dih","Dis"],weekdaysMin:["D\xf2","Lu","M\xe0","Ci","Ar","Ha","Sa"],longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[An-diugh aig] LT",nextDay:"[A-m\xe0ireach aig] LT",nextWeek:"dddd [aig] LT",lastDay:"[An-d\xe8 aig] LT",lastWeek:"dddd [seo chaidh] [aig] LT",sameElse:"L"},relativeTime:{future:"ann an %s",past:"bho chionn %s",s:"beagan diogan",ss:"%d diogan",m:"mionaid",mm:"%d mionaidean",h:"uair",hh:"%d uairean",d:"latha",dd:"%d latha",M:"m\xecos",MM:"%d m\xecosan",y:"bliadhna",yy:"%d bliadhna"},dayOfMonthOrdinalParse:/\d{1,2}(d|na|mh)/,ordinal:function(S){return S+(1===S?"d":S%10==2?"na":"mh")},week:{dow:1,doy:4}})}(i(16738))},72124:function(v,T,i){!function(r){"use strict";r.defineLocale("gl",{months:"xaneiro_febreiro_marzo_abril_maio_xu\xf1o_xullo_agosto_setembro_outubro_novembro_decembro".split("_"),monthsShort:"xan._feb._mar._abr._mai._xu\xf1._xul._ago._set._out._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"domingo_luns_martes_m\xe9rcores_xoves_venres_s\xe1bado".split("_"),weekdaysShort:"dom._lun._mar._m\xe9r._xov._ven._s\xe1b.".split("_"),weekdaysMin:"do_lu_ma_m\xe9_xo_ve_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoxe "+(1!==this.hours()?"\xe1s":"\xe1")+"] LT"},nextDay:function(){return"[ma\xf1\xe1 "+(1!==this.hours()?"\xe1s":"\xe1")+"] LT"},nextWeek:function(){return"dddd ["+(1!==this.hours()?"\xe1s":"a")+"] LT"},lastDay:function(){return"[onte "+(1!==this.hours()?"\xe1":"a")+"] LT"},lastWeek:function(){return"[o] dddd [pasado "+(1!==this.hours()?"\xe1s":"a")+"] LT"},sameElse:"L"},relativeTime:{future:function(p){return 0===p.indexOf("un")?"n"+p:"en "+p},past:"hai %s",s:"uns segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"unha hora",hh:"%d horas",d:"un d\xeda",dd:"%d d\xedas",M:"un mes",MM:"%d meses",y:"un ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}(i(16738))},6444:function(v,T,i){!function(r){"use strict";function u(d,e,_,y){var S={s:["\u0925\u094b\u0921\u092f\u093e \u0938\u0945\u0915\u0902\u0921\u093e\u0902\u0928\u0940","\u0925\u094b\u0921\u0947 \u0938\u0945\u0915\u0902\u0921"],ss:[d+" \u0938\u0945\u0915\u0902\u0921\u093e\u0902\u0928\u0940",d+" \u0938\u0945\u0915\u0902\u0921"],m:["\u090f\u0915\u093e \u092e\u093f\u0923\u091f\u093e\u0928","\u090f\u0915 \u092e\u093f\u0928\u0942\u091f"],mm:[d+" \u092e\u093f\u0923\u091f\u093e\u0902\u0928\u0940",d+" \u092e\u093f\u0923\u091f\u093e\u0902"],h:["\u090f\u0915\u093e \u0935\u0930\u093e\u0928","\u090f\u0915 \u0935\u0930"],hh:[d+" \u0935\u0930\u093e\u0902\u0928\u0940",d+" \u0935\u0930\u093e\u0902"],d:["\u090f\u0915\u093e \u0926\u093f\u0938\u093e\u0928","\u090f\u0915 \u0926\u0940\u0938"],dd:[d+" \u0926\u093f\u0938\u093e\u0902\u0928\u0940",d+" \u0926\u0940\u0938"],M:["\u090f\u0915\u093e \u092e\u094d\u0939\u092f\u0928\u094d\u092f\u093e\u0928","\u090f\u0915 \u092e\u094d\u0939\u092f\u0928\u094b"],MM:[d+" \u092e\u094d\u0939\u092f\u0928\u094d\u092f\u093e\u0928\u0940",d+" \u092e\u094d\u0939\u092f\u0928\u0947"],y:["\u090f\u0915\u093e \u0935\u0930\u094d\u0938\u093e\u0928","\u090f\u0915 \u0935\u0930\u094d\u0938"],yy:[d+" \u0935\u0930\u094d\u0938\u093e\u0902\u0928\u0940",d+" \u0935\u0930\u094d\u0938\u093e\u0902"]};return y?S[_][0]:S[_][1]}r.defineLocale("gom-deva",{months:{standalone:"\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940_\u092b\u0947\u092c\u094d\u0930\u0941\u0935\u093e\u0930\u0940_\u092e\u093e\u0930\u094d\u091a_\u090f\u092a\u094d\u0930\u0940\u0932_\u092e\u0947_\u091c\u0942\u0928_\u091c\u0941\u0932\u092f_\u0911\u0917\u0938\u094d\u091f_\u0938\u092a\u094d\u091f\u0947\u0902\u092c\u0930_\u0911\u0915\u094d\u091f\u094b\u092c\u0930_\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930_\u0921\u093f\u0938\u0947\u0902\u092c\u0930".split("_"),format:"\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940\u091a\u094d\u092f\u093e_\u092b\u0947\u092c\u094d\u0930\u0941\u0935\u093e\u0930\u0940\u091a\u094d\u092f\u093e_\u092e\u093e\u0930\u094d\u091a\u093e\u091a\u094d\u092f\u093e_\u090f\u092a\u094d\u0930\u0940\u0932\u093e\u091a\u094d\u092f\u093e_\u092e\u0947\u092f\u093e\u091a\u094d\u092f\u093e_\u091c\u0942\u0928\u093e\u091a\u094d\u092f\u093e_\u091c\u0941\u0932\u092f\u093e\u091a\u094d\u092f\u093e_\u0911\u0917\u0938\u094d\u091f\u093e\u091a\u094d\u092f\u093e_\u0938\u092a\u094d\u091f\u0947\u0902\u092c\u0930\u093e\u091a\u094d\u092f\u093e_\u0911\u0915\u094d\u091f\u094b\u092c\u0930\u093e\u091a\u094d\u092f\u093e_\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930\u093e\u091a\u094d\u092f\u093e_\u0921\u093f\u0938\u0947\u0902\u092c\u0930\u093e\u091a\u094d\u092f\u093e".split("_"),isFormat:/MMMM(\s)+D[oD]?/},monthsShort:"\u091c\u093e\u0928\u0947._\u092b\u0947\u092c\u094d\u0930\u0941._\u092e\u093e\u0930\u094d\u091a_\u090f\u092a\u094d\u0930\u0940._\u092e\u0947_\u091c\u0942\u0928_\u091c\u0941\u0932._\u0911\u0917._\u0938\u092a\u094d\u091f\u0947\u0902._\u0911\u0915\u094d\u091f\u094b._\u0928\u094b\u0935\u094d\u0939\u0947\u0902._\u0921\u093f\u0938\u0947\u0902.".split("_"),monthsParseExact:!0,weekdays:"\u0906\u092f\u0924\u093e\u0930_\u0938\u094b\u092e\u093e\u0930_\u092e\u0902\u0917\u0933\u093e\u0930_\u092c\u0941\u0927\u0935\u093e\u0930_\u092c\u093f\u0930\u0947\u0938\u094d\u0924\u093e\u0930_\u0938\u0941\u0915\u094d\u0930\u093e\u0930_\u0936\u0947\u0928\u0935\u093e\u0930".split("_"),weekdaysShort:"\u0906\u092f\u0924._\u0938\u094b\u092e._\u092e\u0902\u0917\u0933._\u092c\u0941\u0927._\u092c\u094d\u0930\u0947\u0938\u094d\u0924._\u0938\u0941\u0915\u094d\u0930._\u0936\u0947\u0928.".split("_"),weekdaysMin:"\u0906_\u0938\u094b_\u092e\u0902_\u092c\u0941_\u092c\u094d\u0930\u0947_\u0938\u0941_\u0936\u0947".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"A h:mm [\u0935\u093e\u091c\u0924\u093e\u0902]",LTS:"A h:mm:ss [\u0935\u093e\u091c\u0924\u093e\u0902]",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY A h:mm [\u0935\u093e\u091c\u0924\u093e\u0902]",LLLL:"dddd, MMMM Do, YYYY, A h:mm [\u0935\u093e\u091c\u0924\u093e\u0902]",llll:"ddd, D MMM YYYY, A h:mm [\u0935\u093e\u091c\u0924\u093e\u0902]"},calendar:{sameDay:"[\u0906\u092f\u091c] LT",nextDay:"[\u092b\u093e\u0932\u094d\u092f\u093e\u0902] LT",nextWeek:"[\u092b\u0941\u0921\u0932\u094b] dddd[,] LT",lastDay:"[\u0915\u093e\u0932] LT",lastWeek:"[\u092b\u093e\u091f\u0932\u094b] dddd[,] LT",sameElse:"L"},relativeTime:{future:"%s",past:"%s \u0906\u0926\u0940\u0902",s:u,ss:u,m:u,mm:u,h:u,hh:u,d:u,dd:u,M:u,MM:u,y:u,yy:u},dayOfMonthOrdinalParse:/\d{1,2}(\u0935\u0947\u0930)/,ordinal:function(d,e){switch(e){case"D":return d+"\u0935\u0947\u0930";default:case"M":case"Q":case"DDD":case"d":case"w":case"W":return d}},week:{dow:0,doy:3},meridiemParse:/\u0930\u093e\u0924\u0940|\u0938\u0915\u093e\u0933\u0940\u0902|\u0926\u0928\u092a\u093e\u0930\u093e\u0902|\u0938\u093e\u0902\u091c\u0947/,meridiemHour:function(d,e){return 12===d&&(d=0),"\u0930\u093e\u0924\u0940"===e?d<4?d:d+12:"\u0938\u0915\u093e\u0933\u0940\u0902"===e?d:"\u0926\u0928\u092a\u093e\u0930\u093e\u0902"===e?d>12?d:d+12:"\u0938\u093e\u0902\u091c\u0947"===e?d+12:void 0},meridiem:function(d,e,_){return d<4?"\u0930\u093e\u0924\u0940":d<12?"\u0938\u0915\u093e\u0933\u0940\u0902":d<16?"\u0926\u0928\u092a\u093e\u0930\u093e\u0902":d<20?"\u0938\u093e\u0902\u091c\u0947":"\u0930\u093e\u0924\u0940"}})}(i(16738))},37953:function(v,T,i){!function(r){"use strict";function u(d,e,_,y){var S={s:["thoddea sekondamni","thodde sekond"],ss:[d+" sekondamni",d+" sekond"],m:["eka mintan","ek minut"],mm:[d+" mintamni",d+" mintam"],h:["eka voran","ek vor"],hh:[d+" voramni",d+" voram"],d:["eka disan","ek dis"],dd:[d+" disamni",d+" dis"],M:["eka mhoinean","ek mhoino"],MM:[d+" mhoineamni",d+" mhoine"],y:["eka vorsan","ek voros"],yy:[d+" vorsamni",d+" vorsam"]};return y?S[_][0]:S[_][1]}r.defineLocale("gom-latn",{months:{standalone:"Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr".split("_"),format:"Janerachea_Febrerachea_Marsachea_Abrilachea_Maiachea_Junachea_Julaiachea_Agostachea_Setembrachea_Otubrachea_Novembrachea_Dezembrachea".split("_"),isFormat:/MMMM(\s)+D[oD]?/},monthsShort:"Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Aitar_Somar_Mongllar_Budhvar_Birestar_Sukrar_Son'var".split("_"),weekdaysShort:"Ait._Som._Mon._Bud._Bre._Suk._Son.".split("_"),weekdaysMin:"Ai_Sm_Mo_Bu_Br_Su_Sn".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"A h:mm [vazta]",LTS:"A h:mm:ss [vazta]",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY A h:mm [vazta]",LLLL:"dddd, MMMM Do, YYYY, A h:mm [vazta]",llll:"ddd, D MMM YYYY, A h:mm [vazta]"},calendar:{sameDay:"[Aiz] LT",nextDay:"[Faleam] LT",nextWeek:"[Fuddlo] dddd[,] LT",lastDay:"[Kal] LT",lastWeek:"[Fattlo] dddd[,] LT",sameElse:"L"},relativeTime:{future:"%s",past:"%s adim",s:u,ss:u,m:u,mm:u,h:u,hh:u,d:u,dd:u,M:u,MM:u,y:u,yy:u},dayOfMonthOrdinalParse:/\d{1,2}(er)/,ordinal:function(d,e){switch(e){case"D":return d+"er";default:case"M":case"Q":case"DDD":case"d":case"w":case"W":return d}},week:{dow:0,doy:3},meridiemParse:/rati|sokallim|donparam|sanje/,meridiemHour:function(d,e){return 12===d&&(d=0),"rati"===e?d<4?d:d+12:"sokallim"===e?d:"donparam"===e?d>12?d:d+12:"sanje"===e?d+12:void 0},meridiem:function(d,e,_){return d<4?"rati":d<12?"sokallim":d<16?"donparam":d<20?"sanje":"rati"}})}(i(16738))},76604:function(v,T,i){!function(r){"use strict";var u={1:"\u0ae7",2:"\u0ae8",3:"\u0ae9",4:"\u0aea",5:"\u0aeb",6:"\u0aec",7:"\u0aed",8:"\u0aee",9:"\u0aef",0:"\u0ae6"},p={"\u0ae7":"1","\u0ae8":"2","\u0ae9":"3","\u0aea":"4","\u0aeb":"5","\u0aec":"6","\u0aed":"7","\u0aee":"8","\u0aef":"9","\u0ae6":"0"};r.defineLocale("gu",{months:"\u0a9c\u0abe\u0aa8\u0acd\u0aaf\u0ac1\u0a86\u0ab0\u0ac0_\u0aab\u0ac7\u0aac\u0acd\u0ab0\u0ac1\u0a86\u0ab0\u0ac0_\u0aae\u0abe\u0ab0\u0acd\u0a9a_\u0a8f\u0aaa\u0acd\u0ab0\u0abf\u0ab2_\u0aae\u0ac7_\u0a9c\u0ac2\u0aa8_\u0a9c\u0ac1\u0ab2\u0abe\u0a88_\u0a91\u0a97\u0ab8\u0acd\u0a9f_\u0ab8\u0aaa\u0acd\u0a9f\u0ac7\u0aae\u0acd\u0aac\u0ab0_\u0a91\u0a95\u0acd\u0a9f\u0acd\u0aac\u0ab0_\u0aa8\u0ab5\u0ac7\u0aae\u0acd\u0aac\u0ab0_\u0aa1\u0abf\u0ab8\u0ac7\u0aae\u0acd\u0aac\u0ab0".split("_"),monthsShort:"\u0a9c\u0abe\u0aa8\u0acd\u0aaf\u0ac1._\u0aab\u0ac7\u0aac\u0acd\u0ab0\u0ac1._\u0aae\u0abe\u0ab0\u0acd\u0a9a_\u0a8f\u0aaa\u0acd\u0ab0\u0abf._\u0aae\u0ac7_\u0a9c\u0ac2\u0aa8_\u0a9c\u0ac1\u0ab2\u0abe._\u0a91\u0a97._\u0ab8\u0aaa\u0acd\u0a9f\u0ac7._\u0a91\u0a95\u0acd\u0a9f\u0acd._\u0aa8\u0ab5\u0ac7._\u0aa1\u0abf\u0ab8\u0ac7.".split("_"),monthsParseExact:!0,weekdays:"\u0ab0\u0ab5\u0abf\u0ab5\u0abe\u0ab0_\u0ab8\u0acb\u0aae\u0ab5\u0abe\u0ab0_\u0aae\u0a82\u0a97\u0ab3\u0ab5\u0abe\u0ab0_\u0aac\u0ac1\u0aa7\u0acd\u0ab5\u0abe\u0ab0_\u0a97\u0ac1\u0ab0\u0ac1\u0ab5\u0abe\u0ab0_\u0ab6\u0ac1\u0a95\u0acd\u0ab0\u0ab5\u0abe\u0ab0_\u0ab6\u0aa8\u0abf\u0ab5\u0abe\u0ab0".split("_"),weekdaysShort:"\u0ab0\u0ab5\u0abf_\u0ab8\u0acb\u0aae_\u0aae\u0a82\u0a97\u0ab3_\u0aac\u0ac1\u0aa7\u0acd_\u0a97\u0ac1\u0ab0\u0ac1_\u0ab6\u0ac1\u0a95\u0acd\u0ab0_\u0ab6\u0aa8\u0abf".split("_"),weekdaysMin:"\u0ab0_\u0ab8\u0acb_\u0aae\u0a82_\u0aac\u0ac1_\u0a97\u0ac1_\u0ab6\u0ac1_\u0ab6".split("_"),longDateFormat:{LT:"A h:mm \u0ab5\u0abe\u0a97\u0acd\u0aaf\u0ac7",LTS:"A h:mm:ss \u0ab5\u0abe\u0a97\u0acd\u0aaf\u0ac7",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u0ab5\u0abe\u0a97\u0acd\u0aaf\u0ac7",LLLL:"dddd, D MMMM YYYY, A h:mm \u0ab5\u0abe\u0a97\u0acd\u0aaf\u0ac7"},calendar:{sameDay:"[\u0a86\u0a9c] LT",nextDay:"[\u0a95\u0abe\u0ab2\u0ac7] LT",nextWeek:"dddd, LT",lastDay:"[\u0a97\u0a87\u0a95\u0abe\u0ab2\u0ac7] LT",lastWeek:"[\u0aaa\u0abe\u0a9b\u0ab2\u0abe] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0aae\u0abe",past:"%s \u0aaa\u0ab9\u0ac7\u0ab2\u0abe",s:"\u0a85\u0aae\u0ac1\u0a95 \u0aaa\u0ab3\u0acb",ss:"%d \u0ab8\u0ac7\u0a95\u0a82\u0aa1",m:"\u0a8f\u0a95 \u0aae\u0abf\u0aa8\u0abf\u0a9f",mm:"%d \u0aae\u0abf\u0aa8\u0abf\u0a9f",h:"\u0a8f\u0a95 \u0a95\u0ab2\u0abe\u0a95",hh:"%d \u0a95\u0ab2\u0abe\u0a95",d:"\u0a8f\u0a95 \u0aa6\u0abf\u0ab5\u0ab8",dd:"%d \u0aa6\u0abf\u0ab5\u0ab8",M:"\u0a8f\u0a95 \u0aae\u0ab9\u0abf\u0aa8\u0acb",MM:"%d \u0aae\u0ab9\u0abf\u0aa8\u0acb",y:"\u0a8f\u0a95 \u0ab5\u0ab0\u0acd\u0ab7",yy:"%d \u0ab5\u0ab0\u0acd\u0ab7"},preparse:function(e){return e.replace(/[\u0ae7\u0ae8\u0ae9\u0aea\u0aeb\u0aec\u0aed\u0aee\u0aef\u0ae6]/g,function(_){return p[_]})},postformat:function(e){return e.replace(/\d/g,function(_){return u[_]})},meridiemParse:/\u0ab0\u0abe\u0aa4|\u0aac\u0aaa\u0acb\u0ab0|\u0ab8\u0ab5\u0abe\u0ab0|\u0ab8\u0abe\u0a82\u0a9c/,meridiemHour:function(e,_){return 12===e&&(e=0),"\u0ab0\u0abe\u0aa4"===_?e<4?e:e+12:"\u0ab8\u0ab5\u0abe\u0ab0"===_?e:"\u0aac\u0aaa\u0acb\u0ab0"===_?e>=10?e:e+12:"\u0ab8\u0abe\u0a82\u0a9c"===_?e+12:void 0},meridiem:function(e,_,y){return e<4?"\u0ab0\u0abe\u0aa4":e<10?"\u0ab8\u0ab5\u0abe\u0ab0":e<17?"\u0aac\u0aaa\u0acb\u0ab0":e<20?"\u0ab8\u0abe\u0a82\u0a9c":"\u0ab0\u0abe\u0aa4"},week:{dow:0,doy:6}})}(i(16738))},1222:function(v,T,i){!function(r){"use strict";r.defineLocale("he",{months:"\u05d9\u05e0\u05d5\u05d0\u05e8_\u05e4\u05d1\u05e8\u05d5\u05d0\u05e8_\u05de\u05e8\u05e5_\u05d0\u05e4\u05e8\u05d9\u05dc_\u05de\u05d0\u05d9_\u05d9\u05d5\u05e0\u05d9_\u05d9\u05d5\u05dc\u05d9_\u05d0\u05d5\u05d2\u05d5\u05e1\u05d8_\u05e1\u05e4\u05d8\u05de\u05d1\u05e8_\u05d0\u05d5\u05e7\u05d8\u05d5\u05d1\u05e8_\u05e0\u05d5\u05d1\u05de\u05d1\u05e8_\u05d3\u05e6\u05de\u05d1\u05e8".split("_"),monthsShort:"\u05d9\u05e0\u05d5\u05f3_\u05e4\u05d1\u05e8\u05f3_\u05de\u05e8\u05e5_\u05d0\u05e4\u05e8\u05f3_\u05de\u05d0\u05d9_\u05d9\u05d5\u05e0\u05d9_\u05d9\u05d5\u05dc\u05d9_\u05d0\u05d5\u05d2\u05f3_\u05e1\u05e4\u05d8\u05f3_\u05d0\u05d5\u05e7\u05f3_\u05e0\u05d5\u05d1\u05f3_\u05d3\u05e6\u05de\u05f3".split("_"),weekdays:"\u05e8\u05d0\u05e9\u05d5\u05df_\u05e9\u05e0\u05d9_\u05e9\u05dc\u05d9\u05e9\u05d9_\u05e8\u05d1\u05d9\u05e2\u05d9_\u05d7\u05de\u05d9\u05e9\u05d9_\u05e9\u05d9\u05e9\u05d9_\u05e9\u05d1\u05ea".split("_"),weekdaysShort:"\u05d0\u05f3_\u05d1\u05f3_\u05d2\u05f3_\u05d3\u05f3_\u05d4\u05f3_\u05d5\u05f3_\u05e9\u05f3".split("_"),weekdaysMin:"\u05d0_\u05d1_\u05d2_\u05d3_\u05d4_\u05d5_\u05e9".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [\u05d1]MMMM YYYY",LLL:"D [\u05d1]MMMM YYYY HH:mm",LLLL:"dddd, D [\u05d1]MMMM YYYY HH:mm",l:"D/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[\u05d4\u05d9\u05d5\u05dd \u05d1\u05be]LT",nextDay:"[\u05de\u05d7\u05e8 \u05d1\u05be]LT",nextWeek:"dddd [\u05d1\u05e9\u05e2\u05d4] LT",lastDay:"[\u05d0\u05ea\u05de\u05d5\u05dc \u05d1\u05be]LT",lastWeek:"[\u05d1\u05d9\u05d5\u05dd] dddd [\u05d4\u05d0\u05d7\u05e8\u05d5\u05df \u05d1\u05e9\u05e2\u05d4] LT",sameElse:"L"},relativeTime:{future:"\u05d1\u05e2\u05d5\u05d3 %s",past:"\u05dc\u05e4\u05e0\u05d9 %s",s:"\u05de\u05e1\u05e4\u05e8 \u05e9\u05e0\u05d9\u05d5\u05ea",ss:"%d \u05e9\u05e0\u05d9\u05d5\u05ea",m:"\u05d3\u05e7\u05d4",mm:"%d \u05d3\u05e7\u05d5\u05ea",h:"\u05e9\u05e2\u05d4",hh:function(p){return 2===p?"\u05e9\u05e2\u05ea\u05d9\u05d9\u05dd":p+" \u05e9\u05e2\u05d5\u05ea"},d:"\u05d9\u05d5\u05dd",dd:function(p){return 2===p?"\u05d9\u05d5\u05de\u05d9\u05d9\u05dd":p+" \u05d9\u05de\u05d9\u05dd"},M:"\u05d7\u05d5\u05d3\u05e9",MM:function(p){return 2===p?"\u05d7\u05d5\u05d3\u05e9\u05d9\u05d9\u05dd":p+" \u05d7\u05d5\u05d3\u05e9\u05d9\u05dd"},y:"\u05e9\u05e0\u05d4",yy:function(p){return 2===p?"\u05e9\u05e0\u05ea\u05d9\u05d9\u05dd":p%10==0&&10!==p?p+" \u05e9\u05e0\u05d4":p+" \u05e9\u05e0\u05d9\u05dd"}},meridiemParse:/\u05d0\u05d7\u05d4"\u05e6|\u05dc\u05e4\u05e0\u05d4"\u05e6|\u05d0\u05d7\u05e8\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd|\u05dc\u05e4\u05e0\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd|\u05dc\u05e4\u05e0\u05d5\u05ea \u05d1\u05d5\u05e7\u05e8|\u05d1\u05d1\u05d5\u05e7\u05e8|\u05d1\u05e2\u05e8\u05d1/i,isPM:function(p){return/^(\u05d0\u05d7\u05d4"\u05e6|\u05d0\u05d7\u05e8\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd|\u05d1\u05e2\u05e8\u05d1)$/.test(p)},meridiem:function(p,d,e){return p<5?"\u05dc\u05e4\u05e0\u05d5\u05ea \u05d1\u05d5\u05e7\u05e8":p<10?"\u05d1\u05d1\u05d5\u05e7\u05e8":p<12?e?'\u05dc\u05e4\u05e0\u05d4"\u05e6':"\u05dc\u05e4\u05e0\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd":p<18?e?'\u05d0\u05d7\u05d4"\u05e6':"\u05d0\u05d7\u05e8\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd":"\u05d1\u05e2\u05e8\u05d1"}})}(i(16738))},74235:function(v,T,i){!function(r){"use strict";var u={1:"\u0967",2:"\u0968",3:"\u0969",4:"\u096a",5:"\u096b",6:"\u096c",7:"\u096d",8:"\u096e",9:"\u096f",0:"\u0966"},p={"\u0967":"1","\u0968":"2","\u0969":"3","\u096a":"4","\u096b":"5","\u096c":"6","\u096d":"7","\u096e":"8","\u096f":"9","\u0966":"0"},d=[/^\u091c\u0928/i,/^\u092b\u093c\u0930|\u092b\u0930/i,/^\u092e\u093e\u0930\u094d\u091a/i,/^\u0905\u092a\u094d\u0930\u0948/i,/^\u092e\u0908/i,/^\u091c\u0942\u0928/i,/^\u091c\u0941\u0932/i,/^\u0905\u0917/i,/^\u0938\u093f\u0924\u0902|\u0938\u093f\u0924/i,/^\u0905\u0915\u094d\u091f\u0942/i,/^\u0928\u0935|\u0928\u0935\u0902/i,/^\u0926\u093f\u0938\u0902|\u0926\u093f\u0938/i];r.defineLocale("hi",{months:{format:"\u091c\u0928\u0935\u0930\u0940_\u092b\u093c\u0930\u0935\u0930\u0940_\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u0948\u0932_\u092e\u0908_\u091c\u0942\u0928_\u091c\u0941\u0932\u093e\u0908_\u0905\u0917\u0938\u094d\u0924_\u0938\u093f\u0924\u092e\u094d\u092c\u0930_\u0905\u0915\u094d\u091f\u0942\u092c\u0930_\u0928\u0935\u092e\u094d\u092c\u0930_\u0926\u093f\u0938\u092e\u094d\u092c\u0930".split("_"),standalone:"\u091c\u0928\u0935\u0930\u0940_\u092b\u0930\u0935\u0930\u0940_\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u0948\u0932_\u092e\u0908_\u091c\u0942\u0928_\u091c\u0941\u0932\u093e\u0908_\u0905\u0917\u0938\u094d\u0924_\u0938\u093f\u0924\u0902\u092c\u0930_\u0905\u0915\u094d\u091f\u0942\u092c\u0930_\u0928\u0935\u0902\u092c\u0930_\u0926\u093f\u0938\u0902\u092c\u0930".split("_")},monthsShort:"\u091c\u0928._\u092b\u093c\u0930._\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u0948._\u092e\u0908_\u091c\u0942\u0928_\u091c\u0941\u0932._\u0905\u0917._\u0938\u093f\u0924._\u0905\u0915\u094d\u091f\u0942._\u0928\u0935._\u0926\u093f\u0938.".split("_"),weekdays:"\u0930\u0935\u093f\u0935\u093e\u0930_\u0938\u094b\u092e\u0935\u093e\u0930_\u092e\u0902\u0917\u0932\u0935\u093e\u0930_\u092c\u0941\u0927\u0935\u093e\u0930_\u0917\u0941\u0930\u0942\u0935\u093e\u0930_\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930_\u0936\u0928\u093f\u0935\u093e\u0930".split("_"),weekdaysShort:"\u0930\u0935\u093f_\u0938\u094b\u092e_\u092e\u0902\u0917\u0932_\u092c\u0941\u0927_\u0917\u0941\u0930\u0942_\u0936\u0941\u0915\u094d\u0930_\u0936\u0928\u093f".split("_"),weekdaysMin:"\u0930_\u0938\u094b_\u092e\u0902_\u092c\u0941_\u0917\u0941_\u0936\u0941_\u0936".split("_"),longDateFormat:{LT:"A h:mm \u092c\u091c\u0947",LTS:"A h:mm:ss \u092c\u091c\u0947",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u092c\u091c\u0947",LLLL:"dddd, D MMMM YYYY, A h:mm \u092c\u091c\u0947"},monthsParse:d,longMonthsParse:d,shortMonthsParse:[/^\u091c\u0928/i,/^\u092b\u093c\u0930/i,/^\u092e\u093e\u0930\u094d\u091a/i,/^\u0905\u092a\u094d\u0930\u0948/i,/^\u092e\u0908/i,/^\u091c\u0942\u0928/i,/^\u091c\u0941\u0932/i,/^\u0905\u0917/i,/^\u0938\u093f\u0924/i,/^\u0905\u0915\u094d\u091f\u0942/i,/^\u0928\u0935/i,/^\u0926\u093f\u0938/i],monthsRegex:/^(\u091c\u0928\u0935\u0930\u0940|\u091c\u0928\.?|\u092b\u093c\u0930\u0935\u0930\u0940|\u092b\u0930\u0935\u0930\u0940|\u092b\u093c\u0930\.?|\u092e\u093e\u0930\u094d\u091a?|\u0905\u092a\u094d\u0930\u0948\u0932|\u0905\u092a\u094d\u0930\u0948\.?|\u092e\u0908?|\u091c\u0942\u0928?|\u091c\u0941\u0932\u093e\u0908|\u091c\u0941\u0932\.?|\u0905\u0917\u0938\u094d\u0924|\u0905\u0917\.?|\u0938\u093f\u0924\u092e\u094d\u092c\u0930|\u0938\u093f\u0924\u0902\u092c\u0930|\u0938\u093f\u0924\.?|\u0905\u0915\u094d\u091f\u0942\u092c\u0930|\u0905\u0915\u094d\u091f\u0942\.?|\u0928\u0935\u092e\u094d\u092c\u0930|\u0928\u0935\u0902\u092c\u0930|\u0928\u0935\.?|\u0926\u093f\u0938\u092e\u094d\u092c\u0930|\u0926\u093f\u0938\u0902\u092c\u0930|\u0926\u093f\u0938\.?)/i,monthsShortRegex:/^(\u091c\u0928\u0935\u0930\u0940|\u091c\u0928\.?|\u092b\u093c\u0930\u0935\u0930\u0940|\u092b\u0930\u0935\u0930\u0940|\u092b\u093c\u0930\.?|\u092e\u093e\u0930\u094d\u091a?|\u0905\u092a\u094d\u0930\u0948\u0932|\u0905\u092a\u094d\u0930\u0948\.?|\u092e\u0908?|\u091c\u0942\u0928?|\u091c\u0941\u0932\u093e\u0908|\u091c\u0941\u0932\.?|\u0905\u0917\u0938\u094d\u0924|\u0905\u0917\.?|\u0938\u093f\u0924\u092e\u094d\u092c\u0930|\u0938\u093f\u0924\u0902\u092c\u0930|\u0938\u093f\u0924\.?|\u0905\u0915\u094d\u091f\u0942\u092c\u0930|\u0905\u0915\u094d\u091f\u0942\.?|\u0928\u0935\u092e\u094d\u092c\u0930|\u0928\u0935\u0902\u092c\u0930|\u0928\u0935\.?|\u0926\u093f\u0938\u092e\u094d\u092c\u0930|\u0926\u093f\u0938\u0902\u092c\u0930|\u0926\u093f\u0938\.?)/i,monthsStrictRegex:/^(\u091c\u0928\u0935\u0930\u0940?|\u092b\u093c\u0930\u0935\u0930\u0940|\u092b\u0930\u0935\u0930\u0940?|\u092e\u093e\u0930\u094d\u091a?|\u0905\u092a\u094d\u0930\u0948\u0932?|\u092e\u0908?|\u091c\u0942\u0928?|\u091c\u0941\u0932\u093e\u0908?|\u0905\u0917\u0938\u094d\u0924?|\u0938\u093f\u0924\u092e\u094d\u092c\u0930|\u0938\u093f\u0924\u0902\u092c\u0930|\u0938\u093f\u0924?\.?|\u0905\u0915\u094d\u091f\u0942\u092c\u0930|\u0905\u0915\u094d\u091f\u0942\.?|\u0928\u0935\u092e\u094d\u092c\u0930|\u0928\u0935\u0902\u092c\u0930?|\u0926\u093f\u0938\u092e\u094d\u092c\u0930|\u0926\u093f\u0938\u0902\u092c\u0930?)/i,monthsShortStrictRegex:/^(\u091c\u0928\.?|\u092b\u093c\u0930\.?|\u092e\u093e\u0930\u094d\u091a?|\u0905\u092a\u094d\u0930\u0948\.?|\u092e\u0908?|\u091c\u0942\u0928?|\u091c\u0941\u0932\.?|\u0905\u0917\.?|\u0938\u093f\u0924\.?|\u0905\u0915\u094d\u091f\u0942\.?|\u0928\u0935\.?|\u0926\u093f\u0938\.?)/i,calendar:{sameDay:"[\u0906\u091c] LT",nextDay:"[\u0915\u0932] LT",nextWeek:"dddd, LT",lastDay:"[\u0915\u0932] LT",lastWeek:"[\u092a\u093f\u091b\u0932\u0947] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u092e\u0947\u0902",past:"%s \u092a\u0939\u0932\u0947",s:"\u0915\u0941\u091b \u0939\u0940 \u0915\u094d\u0937\u0923",ss:"%d \u0938\u0947\u0915\u0902\u0921",m:"\u090f\u0915 \u092e\u093f\u0928\u091f",mm:"%d \u092e\u093f\u0928\u091f",h:"\u090f\u0915 \u0918\u0902\u091f\u093e",hh:"%d \u0918\u0902\u091f\u0947",d:"\u090f\u0915 \u0926\u093f\u0928",dd:"%d \u0926\u093f\u0928",M:"\u090f\u0915 \u092e\u0939\u0940\u0928\u0947",MM:"%d \u092e\u0939\u0940\u0928\u0947",y:"\u090f\u0915 \u0935\u0930\u094d\u0937",yy:"%d \u0935\u0930\u094d\u0937"},preparse:function(y){return y.replace(/[\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0966]/g,function(S){return p[S]})},postformat:function(y){return y.replace(/\d/g,function(S){return u[S]})},meridiemParse:/\u0930\u093e\u0924|\u0938\u0941\u092c\u0939|\u0926\u094b\u092a\u0939\u0930|\u0936\u093e\u092e/,meridiemHour:function(y,S){return 12===y&&(y=0),"\u0930\u093e\u0924"===S?y<4?y:y+12:"\u0938\u0941\u092c\u0939"===S?y:"\u0926\u094b\u092a\u0939\u0930"===S?y>=10?y:y+12:"\u0936\u093e\u092e"===S?y+12:void 0},meridiem:function(y,S,A){return y<4?"\u0930\u093e\u0924":y<10?"\u0938\u0941\u092c\u0939":y<17?"\u0926\u094b\u092a\u0939\u0930":y<20?"\u0936\u093e\u092e":"\u0930\u093e\u0924"},week:{dow:0,doy:6}})}(i(16738))},622:function(v,T,i){!function(r){"use strict";function u(d,e,_){var y=d+" ";switch(_){case"ss":return y+(1===d?"sekunda":2===d||3===d||4===d?"sekunde":"sekundi");case"m":return e?"jedna minuta":"jedne minute";case"mm":return y+(1===d?"minuta":2===d||3===d||4===d?"minute":"minuta");case"h":return e?"jedan sat":"jednog sata";case"hh":return y+(1===d?"sat":2===d||3===d||4===d?"sata":"sati");case"dd":return y+(1===d?"dan":"dana");case"MM":return y+(1===d?"mjesec":2===d||3===d||4===d?"mjeseca":"mjeseci");case"yy":return y+(1===d?"godina":2===d||3===d||4===d?"godine":"godina")}}r.defineLocale("hr",{months:{format:"sije\u010dnja_velja\u010de_o\u017eujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca".split("_"),standalone:"sije\u010danj_velja\u010da_o\u017eujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac".split("_")},monthsShort:"sij._velj._o\u017eu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_\u010detvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._\u010det._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_\u010de_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"Do MMMM YYYY",LLL:"Do MMMM YYYY H:mm",LLLL:"dddd, Do MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[ju\u010der u] LT",lastWeek:function(){switch(this.day()){case 0:return"[pro\u0161lu] [nedjelju] [u] LT";case 3:return"[pro\u0161lu] [srijedu] [u] LT";case 6:return"[pro\u0161le] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[pro\u0161li] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",ss:u,m:u,mm:u,h:u,hh:u,d:"dan",dd:u,M:"mjesec",MM:u,y:"godinu",yy:u},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(i(16738))},37735:function(v,T,i){!function(r){"use strict";var u="vas\xe1rnap h\xe9tf\u0151n kedden szerd\xe1n cs\xfct\xf6rt\xf6k\xf6n p\xe9nteken szombaton".split(" ");function p(_,y,S,A){var N=_;switch(S){case"s":return A||y?"n\xe9h\xe1ny m\xe1sodperc":"n\xe9h\xe1ny m\xe1sodperce";case"ss":return N+(A||y)?" m\xe1sodperc":" m\xe1sodperce";case"m":return"egy"+(A||y?" perc":" perce");case"mm":return N+(A||y?" perc":" perce");case"h":return"egy"+(A||y?" \xf3ra":" \xf3r\xe1ja");case"hh":return N+(A||y?" \xf3ra":" \xf3r\xe1ja");case"d":return"egy"+(A||y?" nap":" napja");case"dd":return N+(A||y?" nap":" napja");case"M":return"egy"+(A||y?" h\xf3nap":" h\xf3napja");case"MM":return N+(A||y?" h\xf3nap":" h\xf3napja");case"y":return"egy"+(A||y?" \xe9v":" \xe9ve");case"yy":return N+(A||y?" \xe9v":" \xe9ve")}return""}function d(_){return(_?"":"[m\xfalt] ")+"["+u[this.day()]+"] LT[-kor]"}r.defineLocale("hu",{months:"janu\xe1r_febru\xe1r_m\xe1rcius_\xe1prilis_m\xe1jus_j\xfanius_j\xfalius_augusztus_szeptember_okt\xf3ber_november_december".split("_"),monthsShort:"jan._feb._m\xe1rc._\xe1pr._m\xe1j._j\xfan._j\xfal._aug._szept._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"vas\xe1rnap_h\xe9tf\u0151_kedd_szerda_cs\xfct\xf6rt\xf6k_p\xe9ntek_szombat".split("_"),weekdaysShort:"vas_h\xe9t_kedd_sze_cs\xfct_p\xe9n_szo".split("_"),weekdaysMin:"v_h_k_sze_cs_p_szo".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"YYYY.MM.DD.",LL:"YYYY. MMMM D.",LLL:"YYYY. MMMM D. H:mm",LLLL:"YYYY. MMMM D., dddd H:mm"},meridiemParse:/de|du/i,isPM:function(_){return"u"===_.charAt(1).toLowerCase()},meridiem:function(_,y,S){return _<12?!0===S?"de":"DE":!0===S?"du":"DU"},calendar:{sameDay:"[ma] LT[-kor]",nextDay:"[holnap] LT[-kor]",nextWeek:function(){return d.call(this,!0)},lastDay:"[tegnap] LT[-kor]",lastWeek:function(){return d.call(this,!1)},sameElse:"L"},relativeTime:{future:"%s m\xfalva",past:"%s",s:p,ss:p,m:p,mm:p,h:p,hh:p,d:p,dd:p,M:p,MM:p,y:p,yy:p},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},90402:function(v,T,i){!function(r){"use strict";r.defineLocale("hy-am",{months:{format:"\u0570\u0578\u0582\u0576\u057e\u0561\u0580\u056b_\u0583\u0565\u057f\u0580\u057e\u0561\u0580\u056b_\u0574\u0561\u0580\u057f\u056b_\u0561\u057a\u0580\u056b\u056c\u056b_\u0574\u0561\u0575\u056b\u057d\u056b_\u0570\u0578\u0582\u0576\u056b\u057d\u056b_\u0570\u0578\u0582\u056c\u056b\u057d\u056b_\u0585\u0563\u0578\u057d\u057f\u0578\u057d\u056b_\u057d\u0565\u057a\u057f\u0565\u0574\u0562\u0565\u0580\u056b_\u0570\u0578\u056f\u057f\u0565\u0574\u0562\u0565\u0580\u056b_\u0576\u0578\u0575\u0565\u0574\u0562\u0565\u0580\u056b_\u0564\u0565\u056f\u057f\u0565\u0574\u0562\u0565\u0580\u056b".split("_"),standalone:"\u0570\u0578\u0582\u0576\u057e\u0561\u0580_\u0583\u0565\u057f\u0580\u057e\u0561\u0580_\u0574\u0561\u0580\u057f_\u0561\u057a\u0580\u056b\u056c_\u0574\u0561\u0575\u056b\u057d_\u0570\u0578\u0582\u0576\u056b\u057d_\u0570\u0578\u0582\u056c\u056b\u057d_\u0585\u0563\u0578\u057d\u057f\u0578\u057d_\u057d\u0565\u057a\u057f\u0565\u0574\u0562\u0565\u0580_\u0570\u0578\u056f\u057f\u0565\u0574\u0562\u0565\u0580_\u0576\u0578\u0575\u0565\u0574\u0562\u0565\u0580_\u0564\u0565\u056f\u057f\u0565\u0574\u0562\u0565\u0580".split("_")},monthsShort:"\u0570\u0576\u057e_\u0583\u057f\u0580_\u0574\u0580\u057f_\u0561\u057a\u0580_\u0574\u0575\u057d_\u0570\u0576\u057d_\u0570\u056c\u057d_\u0585\u0563\u057d_\u057d\u057a\u057f_\u0570\u056f\u057f_\u0576\u0574\u0562_\u0564\u056f\u057f".split("_"),weekdays:"\u056f\u056b\u0580\u0561\u056f\u056b_\u0565\u0580\u056f\u0578\u0582\u0577\u0561\u0562\u0569\u056b_\u0565\u0580\u0565\u0584\u0577\u0561\u0562\u0569\u056b_\u0579\u0578\u0580\u0565\u0584\u0577\u0561\u0562\u0569\u056b_\u0570\u056b\u0576\u0563\u0577\u0561\u0562\u0569\u056b_\u0578\u0582\u0580\u0562\u0561\u0569_\u0577\u0561\u0562\u0561\u0569".split("_"),weekdaysShort:"\u056f\u0580\u056f_\u0565\u0580\u056f_\u0565\u0580\u0584_\u0579\u0580\u0584_\u0570\u0576\u0563_\u0578\u0582\u0580\u0562_\u0577\u0562\u0569".split("_"),weekdaysMin:"\u056f\u0580\u056f_\u0565\u0580\u056f_\u0565\u0580\u0584_\u0579\u0580\u0584_\u0570\u0576\u0563_\u0578\u0582\u0580\u0562_\u0577\u0562\u0569".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY \u0569.",LLL:"D MMMM YYYY \u0569., HH:mm",LLLL:"dddd, D MMMM YYYY \u0569., HH:mm"},calendar:{sameDay:"[\u0561\u0575\u057d\u0585\u0580] LT",nextDay:"[\u057e\u0561\u0572\u0568] LT",lastDay:"[\u0565\u0580\u0565\u056f] LT",nextWeek:function(){return"dddd [\u0585\u0580\u0568 \u056a\u0561\u0574\u0568] LT"},lastWeek:function(){return"[\u0561\u0576\u0581\u0561\u056e] dddd [\u0585\u0580\u0568 \u056a\u0561\u0574\u0568] LT"},sameElse:"L"},relativeTime:{future:"%s \u0570\u0565\u057f\u0578",past:"%s \u0561\u057c\u0561\u057b",s:"\u0574\u056b \u0584\u0561\u0576\u056b \u057e\u0561\u0575\u0580\u056f\u0575\u0561\u0576",ss:"%d \u057e\u0561\u0575\u0580\u056f\u0575\u0561\u0576",m:"\u0580\u0578\u057a\u0565",mm:"%d \u0580\u0578\u057a\u0565",h:"\u056a\u0561\u0574",hh:"%d \u056a\u0561\u0574",d:"\u0585\u0580",dd:"%d \u0585\u0580",M:"\u0561\u0574\u056b\u057d",MM:"%d \u0561\u0574\u056b\u057d",y:"\u057f\u0561\u0580\u056b",yy:"%d \u057f\u0561\u0580\u056b"},meridiemParse:/\u0563\u056b\u0577\u0565\u0580\u057e\u0561|\u0561\u057c\u0561\u057e\u0578\u057f\u057e\u0561|\u0581\u0565\u0580\u0565\u056f\u057e\u0561|\u0565\u0580\u0565\u056f\u0578\u0575\u0561\u0576/,isPM:function(p){return/^(\u0581\u0565\u0580\u0565\u056f\u057e\u0561|\u0565\u0580\u0565\u056f\u0578\u0575\u0561\u0576)$/.test(p)},meridiem:function(p){return p<4?"\u0563\u056b\u0577\u0565\u0580\u057e\u0561":p<12?"\u0561\u057c\u0561\u057e\u0578\u057f\u057e\u0561":p<17?"\u0581\u0565\u0580\u0565\u056f\u057e\u0561":"\u0565\u0580\u0565\u056f\u0578\u0575\u0561\u0576"},dayOfMonthOrdinalParse:/\d{1,2}|\d{1,2}-(\u056b\u0576|\u0580\u0564)/,ordinal:function(p,d){switch(d){case"DDD":case"w":case"W":case"DDDo":return 1===p?p+"-\u056b\u0576":p+"-\u0580\u0564";default:return p}},week:{dow:1,doy:7}})}(i(16738))},59187:function(v,T,i){!function(r){"use strict";r.defineLocale("id",{months:"Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Mei_Jun_Jul_Agt_Sep_Okt_Nov_Des".split("_"),weekdays:"Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu".split("_"),weekdaysShort:"Min_Sen_Sel_Rab_Kam_Jum_Sab".split("_"),weekdaysMin:"Mg_Sn_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|siang|sore|malam/,meridiemHour:function(p,d){return 12===p&&(p=0),"pagi"===d?p:"siang"===d?p>=11?p:p+12:"sore"===d||"malam"===d?p+12:void 0},meridiem:function(p,d,e){return p<11?"pagi":p<15?"siang":p<19?"sore":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Besok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kemarin pukul] LT",lastWeek:"dddd [lalu pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lalu",s:"beberapa detik",ss:"%d detik",m:"semenit",mm:"%d menit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:0,doy:6}})}(i(16738))},30536:function(v,T,i){!function(r){"use strict";function u(e){return e%100==11||e%10!=1}function p(e,_,y,S){var A=e+" ";switch(y){case"s":return _||S?"nokkrar sek\xfandur":"nokkrum sek\xfandum";case"ss":return u(e)?A+(_||S?"sek\xfandur":"sek\xfandum"):A+"sek\xfanda";case"m":return _?"m\xedn\xfata":"m\xedn\xfatu";case"mm":return u(e)?A+(_||S?"m\xedn\xfatur":"m\xedn\xfatum"):_?A+"m\xedn\xfata":A+"m\xedn\xfatu";case"hh":return u(e)?A+(_||S?"klukkustundir":"klukkustundum"):A+"klukkustund";case"d":return _?"dagur":S?"dag":"degi";case"dd":return u(e)?_?A+"dagar":A+(S?"daga":"d\xf6gum"):_?A+"dagur":A+(S?"dag":"degi");case"M":return _?"m\xe1nu\xf0ur":S?"m\xe1nu\xf0":"m\xe1nu\xf0i";case"MM":return u(e)?_?A+"m\xe1nu\xf0ir":A+(S?"m\xe1nu\xf0i":"m\xe1nu\xf0um"):_?A+"m\xe1nu\xf0ur":A+(S?"m\xe1nu\xf0":"m\xe1nu\xf0i");case"y":return _||S?"\xe1r":"\xe1ri";case"yy":return u(e)?A+(_||S?"\xe1r":"\xe1rum"):A+(_||S?"\xe1r":"\xe1ri")}}r.defineLocale("is",{months:"jan\xfaar_febr\xfaar_mars_apr\xedl_ma\xed_j\xfan\xed_j\xfal\xed_\xe1g\xfast_september_okt\xf3ber_n\xf3vember_desember".split("_"),monthsShort:"jan_feb_mar_apr_ma\xed_j\xfan_j\xfal_\xe1g\xfa_sep_okt_n\xf3v_des".split("_"),weekdays:"sunnudagur_m\xe1nudagur_\xferi\xf0judagur_mi\xf0vikudagur_fimmtudagur_f\xf6studagur_laugardagur".split("_"),weekdaysShort:"sun_m\xe1n_\xferi_mi\xf0_fim_f\xf6s_lau".split("_"),weekdaysMin:"Su_M\xe1_\xder_Mi_Fi_F\xf6_La".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] H:mm",LLLL:"dddd, D. MMMM YYYY [kl.] H:mm"},calendar:{sameDay:"[\xed dag kl.] LT",nextDay:"[\xe1 morgun kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[\xed g\xe6r kl.] LT",lastWeek:"[s\xed\xf0asta] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"eftir %s",past:"fyrir %s s\xed\xf0an",s:p,ss:p,m:p,mm:p,h:"klukkustund",hh:p,d:p,dd:p,M:p,MM:p,y:p,yy:p},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},94667:function(v,T,i){!function(r){"use strict";r.defineLocale("it-ch",{months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"domenica_luned\xec_marted\xec_mercoled\xec_gioved\xec_venerd\xec_sabato".split("_"),weekdaysShort:"dom_lun_mar_mer_gio_ven_sab".split("_"),weekdaysMin:"do_lu_ma_me_gi_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:function(){switch(this.day()){case 0:return"[la scorsa] dddd [alle] LT";default:return"[lo scorso] dddd [alle] LT"}},sameElse:"L"},relativeTime:{future:function(p){return(/^[0-9].+$/.test(p)?"tra":"in")+" "+p},past:"%s fa",s:"alcuni secondi",ss:"%d secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}(i(16738))},35007:function(v,T,i){!function(r){"use strict";r.defineLocale("it",{months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"domenica_luned\xec_marted\xec_mercoled\xec_gioved\xec_venerd\xec_sabato".split("_"),weekdaysShort:"dom_lun_mar_mer_gio_ven_sab".split("_"),weekdaysMin:"do_lu_ma_me_gi_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:function(){return"[Oggi a"+(this.hours()>1?"lle ":0===this.hours()?" ":"ll'")+"]LT"},nextDay:function(){return"[Domani a"+(this.hours()>1?"lle ":0===this.hours()?" ":"ll'")+"]LT"},nextWeek:function(){return"dddd [a"+(this.hours()>1?"lle ":0===this.hours()?" ":"ll'")+"]LT"},lastDay:function(){return"[Ieri a"+(this.hours()>1?"lle ":0===this.hours()?" ":"ll'")+"]LT"},lastWeek:function(){switch(this.day()){case 0:return"[La scorsa] dddd [a"+(this.hours()>1?"lle ":0===this.hours()?" ":"ll'")+"]LT";default:return"[Lo scorso] dddd [a"+(this.hours()>1?"lle ":0===this.hours()?" ":"ll'")+"]LT"}},sameElse:"L"},relativeTime:{future:"tra %s",past:"%s fa",s:"alcuni secondi",ss:"%d secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",w:"una settimana",ww:"%d settimane",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}(i(16738))},62093:function(v,T,i){!function(r){"use strict";r.defineLocale("ja",{eras:[{since:"2019-05-01",offset:1,name:"\u4ee4\u548c",narrow:"\u32ff",abbr:"R"},{since:"1989-01-08",until:"2019-04-30",offset:1,name:"\u5e73\u6210",narrow:"\u337b",abbr:"H"},{since:"1926-12-25",until:"1989-01-07",offset:1,name:"\u662d\u548c",narrow:"\u337c",abbr:"S"},{since:"1912-07-30",until:"1926-12-24",offset:1,name:"\u5927\u6b63",narrow:"\u337d",abbr:"T"},{since:"1873-01-01",until:"1912-07-29",offset:6,name:"\u660e\u6cbb",narrow:"\u337e",abbr:"M"},{since:"0001-01-01",until:"1873-12-31",offset:1,name:"\u897f\u66a6",narrow:"AD",abbr:"AD"},{since:"0000-12-31",until:-1/0,offset:1,name:"\u7d00\u5143\u524d",narrow:"BC",abbr:"BC"}],eraYearOrdinalRegex:/(\u5143|\d+)\u5e74/,eraYearOrdinalParse:function(p,d){return"\u5143"===d[1]?1:parseInt(d[1]||p,10)},months:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u65e5\u66dc\u65e5_\u6708\u66dc\u65e5_\u706b\u66dc\u65e5_\u6c34\u66dc\u65e5_\u6728\u66dc\u65e5_\u91d1\u66dc\u65e5_\u571f\u66dc\u65e5".split("_"),weekdaysShort:"\u65e5_\u6708_\u706b_\u6c34_\u6728_\u91d1_\u571f".split("_"),weekdaysMin:"\u65e5_\u6708_\u706b_\u6c34_\u6728_\u91d1_\u571f".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5 HH:mm",LLLL:"YYYY\u5e74M\u6708D\u65e5 dddd HH:mm",l:"YYYY/MM/DD",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5(ddd) HH:mm"},meridiemParse:/\u5348\u524d|\u5348\u5f8c/i,isPM:function(p){return"\u5348\u5f8c"===p},meridiem:function(p,d,e){return p<12?"\u5348\u524d":"\u5348\u5f8c"},calendar:{sameDay:"[\u4eca\u65e5] LT",nextDay:"[\u660e\u65e5] LT",nextWeek:function(p){return p.week()!==this.week()?"[\u6765\u9031]dddd LT":"dddd LT"},lastDay:"[\u6628\u65e5] LT",lastWeek:function(p){return this.week()!==p.week()?"[\u5148\u9031]dddd LT":"dddd LT"},sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}\u65e5/,ordinal:function(p,d){switch(d){case"y":return 1===p?"\u5143\u5e74":p+"\u5e74";case"d":case"D":case"DDD":return p+"\u65e5";default:return p}},relativeTime:{future:"%s\u5f8c",past:"%s\u524d",s:"\u6570\u79d2",ss:"%d\u79d2",m:"1\u5206",mm:"%d\u5206",h:"1\u6642\u9593",hh:"%d\u6642\u9593",d:"1\u65e5",dd:"%d\u65e5",M:"1\u30f6\u6708",MM:"%d\u30f6\u6708",y:"1\u5e74",yy:"%d\u5e74"}})}(i(16738))},80059:function(v,T,i){!function(r){"use strict";r.defineLocale("jv",{months:"Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des".split("_"),weekdays:"Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu".split("_"),weekdaysShort:"Min_Sen_Sel_Reb_Kem_Jem_Sep".split("_"),weekdaysMin:"Mg_Sn_Sl_Rb_Km_Jm_Sp".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/enjing|siyang|sonten|ndalu/,meridiemHour:function(p,d){return 12===p&&(p=0),"enjing"===d?p:"siyang"===d?p>=11?p:p+12:"sonten"===d||"ndalu"===d?p+12:void 0},meridiem:function(p,d,e){return p<11?"enjing":p<15?"siyang":p<19?"sonten":"ndalu"},calendar:{sameDay:"[Dinten puniko pukul] LT",nextDay:"[Mbenjang pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kala wingi pukul] LT",lastWeek:"dddd [kepengker pukul] LT",sameElse:"L"},relativeTime:{future:"wonten ing %s",past:"%s ingkang kepengker",s:"sawetawis detik",ss:"%d detik",m:"setunggal menit",mm:"%d menit",h:"setunggal jam",hh:"%d jam",d:"sedinten",dd:"%d dinten",M:"sewulan",MM:"%d wulan",y:"setaun",yy:"%d taun"},week:{dow:1,doy:7}})}(i(16738))},66870:function(v,T,i){!function(r){"use strict";r.defineLocale("ka",{months:"\u10d8\u10d0\u10dc\u10d5\u10d0\u10e0\u10d8_\u10d7\u10d4\u10d1\u10d4\u10e0\u10d5\u10d0\u10da\u10d8_\u10db\u10d0\u10e0\u10e2\u10d8_\u10d0\u10de\u10e0\u10d8\u10da\u10d8_\u10db\u10d0\u10d8\u10e1\u10d8_\u10d8\u10d5\u10dc\u10d8\u10e1\u10d8_\u10d8\u10d5\u10da\u10d8\u10e1\u10d8_\u10d0\u10d2\u10d5\u10d8\u10e1\u10e2\u10dd_\u10e1\u10d4\u10e5\u10e2\u10d4\u10db\u10d1\u10d4\u10e0\u10d8_\u10dd\u10e5\u10e2\u10dd\u10db\u10d1\u10d4\u10e0\u10d8_\u10dc\u10dd\u10d4\u10db\u10d1\u10d4\u10e0\u10d8_\u10d3\u10d4\u10d9\u10d4\u10db\u10d1\u10d4\u10e0\u10d8".split("_"),monthsShort:"\u10d8\u10d0\u10dc_\u10d7\u10d4\u10d1_\u10db\u10d0\u10e0_\u10d0\u10de\u10e0_\u10db\u10d0\u10d8_\u10d8\u10d5\u10dc_\u10d8\u10d5\u10da_\u10d0\u10d2\u10d5_\u10e1\u10d4\u10e5_\u10dd\u10e5\u10e2_\u10dc\u10dd\u10d4_\u10d3\u10d4\u10d9".split("_"),weekdays:{standalone:"\u10d9\u10d5\u10d8\u10e0\u10d0_\u10dd\u10e0\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8_\u10e1\u10d0\u10db\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8_\u10dd\u10d7\u10ee\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8_\u10ee\u10e3\u10d7\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8_\u10de\u10d0\u10e0\u10d0\u10e1\u10d9\u10d4\u10d5\u10d8_\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8".split("_"),format:"\u10d9\u10d5\u10d8\u10e0\u10d0\u10e1_\u10dd\u10e0\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1_\u10e1\u10d0\u10db\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1_\u10dd\u10d7\u10ee\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1_\u10ee\u10e3\u10d7\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1_\u10de\u10d0\u10e0\u10d0\u10e1\u10d9\u10d4\u10d5\u10e1_\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1".split("_"),isFormat:/(\u10ec\u10d8\u10dc\u10d0|\u10e8\u10d4\u10db\u10d3\u10d4\u10d2)/},weekdaysShort:"\u10d9\u10d5\u10d8_\u10dd\u10e0\u10e8_\u10e1\u10d0\u10db_\u10dd\u10d7\u10ee_\u10ee\u10e3\u10d7_\u10de\u10d0\u10e0_\u10e8\u10d0\u10d1".split("_"),weekdaysMin:"\u10d9\u10d5_\u10dd\u10e0_\u10e1\u10d0_\u10dd\u10d7_\u10ee\u10e3_\u10de\u10d0_\u10e8\u10d0".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u10d3\u10e6\u10d4\u10e1] LT[-\u10d6\u10d4]",nextDay:"[\u10ee\u10d5\u10d0\u10da] LT[-\u10d6\u10d4]",lastDay:"[\u10d2\u10e3\u10e8\u10d8\u10dc] LT[-\u10d6\u10d4]",nextWeek:"[\u10e8\u10d4\u10db\u10d3\u10d4\u10d2] dddd LT[-\u10d6\u10d4]",lastWeek:"[\u10ec\u10d8\u10dc\u10d0] dddd LT-\u10d6\u10d4",sameElse:"L"},relativeTime:{future:function(p){return p.replace(/(\u10ec\u10d0\u10db|\u10ec\u10e3\u10d7|\u10e1\u10d0\u10d0\u10d7|\u10ec\u10d4\u10da|\u10d3\u10e6|\u10d7\u10d5)(\u10d8|\u10d4)/,function(d,e,_){return"\u10d8"===_?e+"\u10e8\u10d8":e+_+"\u10e8\u10d8"})},past:function(p){return/(\u10ec\u10d0\u10db\u10d8|\u10ec\u10e3\u10d7\u10d8|\u10e1\u10d0\u10d0\u10d7\u10d8|\u10d3\u10e6\u10d4|\u10d7\u10d5\u10d4)/.test(p)?p.replace(/(\u10d8|\u10d4)$/,"\u10d8\u10e1 \u10ec\u10d8\u10dc"):/\u10ec\u10d4\u10da\u10d8/.test(p)?p.replace(/\u10ec\u10d4\u10da\u10d8$/,"\u10ec\u10da\u10d8\u10e1 \u10ec\u10d8\u10dc"):p},s:"\u10e0\u10d0\u10db\u10d3\u10d4\u10dc\u10d8\u10db\u10d4 \u10ec\u10d0\u10db\u10d8",ss:"%d \u10ec\u10d0\u10db\u10d8",m:"\u10ec\u10e3\u10d7\u10d8",mm:"%d \u10ec\u10e3\u10d7\u10d8",h:"\u10e1\u10d0\u10d0\u10d7\u10d8",hh:"%d \u10e1\u10d0\u10d0\u10d7\u10d8",d:"\u10d3\u10e6\u10d4",dd:"%d \u10d3\u10e6\u10d4",M:"\u10d7\u10d5\u10d4",MM:"%d \u10d7\u10d5\u10d4",y:"\u10ec\u10d4\u10da\u10d8",yy:"%d \u10ec\u10d4\u10da\u10d8"},dayOfMonthOrdinalParse:/0|1-\u10da\u10d8|\u10db\u10d4-\d{1,2}|\d{1,2}-\u10d4/,ordinal:function(p){return 0===p?p:1===p?p+"-\u10da\u10d8":p<20||p<=100&&p%20==0||p%100==0?"\u10db\u10d4-"+p:p+"-\u10d4"},week:{dow:1,doy:7}})}(i(16738))},80880:function(v,T,i){!function(r){"use strict";var u={0:"-\u0448\u0456",1:"-\u0448\u0456",2:"-\u0448\u0456",3:"-\u0448\u0456",4:"-\u0448\u0456",5:"-\u0448\u0456",6:"-\u0448\u044b",7:"-\u0448\u0456",8:"-\u0448\u0456",9:"-\u0448\u044b",10:"-\u0448\u044b",20:"-\u0448\u044b",30:"-\u0448\u044b",40:"-\u0448\u044b",50:"-\u0448\u0456",60:"-\u0448\u044b",70:"-\u0448\u0456",80:"-\u0448\u0456",90:"-\u0448\u044b",100:"-\u0448\u0456"};r.defineLocale("kk",{months:"\u049b\u0430\u04a3\u0442\u0430\u0440_\u0430\u049b\u043f\u0430\u043d_\u043d\u0430\u0443\u0440\u044b\u0437_\u0441\u04d9\u0443\u0456\u0440_\u043c\u0430\u043c\u044b\u0440_\u043c\u0430\u0443\u0441\u044b\u043c_\u0448\u0456\u043b\u0434\u0435_\u0442\u0430\u043c\u044b\u0437_\u049b\u044b\u0440\u043a\u04af\u0439\u0435\u043a_\u049b\u0430\u0437\u0430\u043d_\u049b\u0430\u0440\u0430\u0448\u0430_\u0436\u0435\u043b\u0442\u043e\u049b\u0441\u0430\u043d".split("_"),monthsShort:"\u049b\u0430\u04a3_\u0430\u049b\u043f_\u043d\u0430\u0443_\u0441\u04d9\u0443_\u043c\u0430\u043c_\u043c\u0430\u0443_\u0448\u0456\u043b_\u0442\u0430\u043c_\u049b\u044b\u0440_\u049b\u0430\u0437_\u049b\u0430\u0440_\u0436\u0435\u043b".split("_"),weekdays:"\u0436\u0435\u043a\u0441\u0435\u043d\u0431\u0456_\u0434\u04af\u0439\u0441\u0435\u043d\u0431\u0456_\u0441\u0435\u0439\u0441\u0435\u043d\u0431\u0456_\u0441\u04d9\u0440\u0441\u0435\u043d\u0431\u0456_\u0431\u0435\u0439\u0441\u0435\u043d\u0431\u0456_\u0436\u04b1\u043c\u0430_\u0441\u0435\u043d\u0431\u0456".split("_"),weekdaysShort:"\u0436\u0435\u043a_\u0434\u04af\u0439_\u0441\u0435\u0439_\u0441\u04d9\u0440_\u0431\u0435\u0439_\u0436\u04b1\u043c_\u0441\u0435\u043d".split("_"),weekdaysMin:"\u0436\u043a_\u0434\u0439_\u0441\u0439_\u0441\u0440_\u0431\u0439_\u0436\u043c_\u0441\u043d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0411\u04af\u0433\u0456\u043d \u0441\u0430\u0493\u0430\u0442] LT",nextDay:"[\u0415\u0440\u0442\u0435\u04a3 \u0441\u0430\u0493\u0430\u0442] LT",nextWeek:"dddd [\u0441\u0430\u0493\u0430\u0442] LT",lastDay:"[\u041a\u0435\u0448\u0435 \u0441\u0430\u0493\u0430\u0442] LT",lastWeek:"[\u04e8\u0442\u043a\u0435\u043d \u0430\u043f\u0442\u0430\u043d\u044b\u04a3] dddd [\u0441\u0430\u0493\u0430\u0442] LT",sameElse:"L"},relativeTime:{future:"%s \u0456\u0448\u0456\u043d\u0434\u0435",past:"%s \u0431\u04b1\u0440\u044b\u043d",s:"\u0431\u0456\u0440\u043d\u0435\u0448\u0435 \u0441\u0435\u043a\u0443\u043d\u0434",ss:"%d \u0441\u0435\u043a\u0443\u043d\u0434",m:"\u0431\u0456\u0440 \u043c\u0438\u043d\u0443\u0442",mm:"%d \u043c\u0438\u043d\u0443\u0442",h:"\u0431\u0456\u0440 \u0441\u0430\u0493\u0430\u0442",hh:"%d \u0441\u0430\u0493\u0430\u0442",d:"\u0431\u0456\u0440 \u043a\u04af\u043d",dd:"%d \u043a\u04af\u043d",M:"\u0431\u0456\u0440 \u0430\u0439",MM:"%d \u0430\u0439",y:"\u0431\u0456\u0440 \u0436\u044b\u043b",yy:"%d \u0436\u044b\u043b"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0448\u0456|\u0448\u044b)/,ordinal:function(d){return d+(u[d]||u[d%10]||u[d>=100?100:null])},week:{dow:1,doy:7}})}(i(16738))},1083:function(v,T,i){!function(r){"use strict";var u={1:"\u17e1",2:"\u17e2",3:"\u17e3",4:"\u17e4",5:"\u17e5",6:"\u17e6",7:"\u17e7",8:"\u17e8",9:"\u17e9",0:"\u17e0"},p={"\u17e1":"1","\u17e2":"2","\u17e3":"3","\u17e4":"4","\u17e5":"5","\u17e6":"6","\u17e7":"7","\u17e8":"8","\u17e9":"9","\u17e0":"0"};r.defineLocale("km",{months:"\u1798\u1780\u179a\u17b6_\u1780\u17bb\u1798\u17d2\u1797\u17c8_\u1798\u17b8\u1793\u17b6_\u1798\u17c1\u179f\u17b6_\u17a7\u179f\u1797\u17b6_\u1798\u17b7\u1790\u17bb\u1793\u17b6_\u1780\u1780\u17d2\u1780\u178a\u17b6_\u179f\u17b8\u17a0\u17b6_\u1780\u1789\u17d2\u1789\u17b6_\u178f\u17bb\u179b\u17b6_\u179c\u17b7\u1785\u17d2\u1786\u17b7\u1780\u17b6_\u1792\u17d2\u1793\u17bc".split("_"),monthsShort:"\u1798\u1780\u179a\u17b6_\u1780\u17bb\u1798\u17d2\u1797\u17c8_\u1798\u17b8\u1793\u17b6_\u1798\u17c1\u179f\u17b6_\u17a7\u179f\u1797\u17b6_\u1798\u17b7\u1790\u17bb\u1793\u17b6_\u1780\u1780\u17d2\u1780\u178a\u17b6_\u179f\u17b8\u17a0\u17b6_\u1780\u1789\u17d2\u1789\u17b6_\u178f\u17bb\u179b\u17b6_\u179c\u17b7\u1785\u17d2\u1786\u17b7\u1780\u17b6_\u1792\u17d2\u1793\u17bc".split("_"),weekdays:"\u17a2\u17b6\u1791\u17b7\u178f\u17d2\u1799_\u1785\u17d0\u1793\u17d2\u1791_\u17a2\u1784\u17d2\u1782\u17b6\u179a_\u1796\u17bb\u1792_\u1796\u17d2\u179a\u17a0\u179f\u17d2\u1794\u178f\u17b7\u17cd_\u179f\u17bb\u1780\u17d2\u179a_\u179f\u17c5\u179a\u17cd".split("_"),weekdaysShort:"\u17a2\u17b6_\u1785_\u17a2_\u1796_\u1796\u17d2\u179a_\u179f\u17bb_\u179f".split("_"),weekdaysMin:"\u17a2\u17b6_\u1785_\u17a2_\u1796_\u1796\u17d2\u179a_\u179f\u17bb_\u179f".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/\u1796\u17d2\u179a\u17b9\u1780|\u179b\u17d2\u1784\u17b6\u1785/,isPM:function(e){return"\u179b\u17d2\u1784\u17b6\u1785"===e},meridiem:function(e,_,y){return e<12?"\u1796\u17d2\u179a\u17b9\u1780":"\u179b\u17d2\u1784\u17b6\u1785"},calendar:{sameDay:"[\u1790\u17d2\u1784\u17c3\u1793\u17c1\u17c7 \u1798\u17c9\u17c4\u1784] LT",nextDay:"[\u179f\u17d2\u17a2\u17c2\u1780 \u1798\u17c9\u17c4\u1784] LT",nextWeek:"dddd [\u1798\u17c9\u17c4\u1784] LT",lastDay:"[\u1798\u17d2\u179f\u17b7\u179b\u1798\u17b7\u1789 \u1798\u17c9\u17c4\u1784] LT",lastWeek:"dddd [\u179f\u1794\u17d2\u178f\u17b6\u17a0\u17cd\u1798\u17bb\u1793] [\u1798\u17c9\u17c4\u1784] LT",sameElse:"L"},relativeTime:{future:"%s\u1791\u17c0\u178f",past:"%s\u1798\u17bb\u1793",s:"\u1794\u17c9\u17bb\u1793\u17d2\u1798\u17b6\u1793\u179c\u17b7\u1793\u17b6\u1791\u17b8",ss:"%d \u179c\u17b7\u1793\u17b6\u1791\u17b8",m:"\u1798\u17bd\u1799\u1793\u17b6\u1791\u17b8",mm:"%d \u1793\u17b6\u1791\u17b8",h:"\u1798\u17bd\u1799\u1798\u17c9\u17c4\u1784",hh:"%d \u1798\u17c9\u17c4\u1784",d:"\u1798\u17bd\u1799\u1790\u17d2\u1784\u17c3",dd:"%d \u1790\u17d2\u1784\u17c3",M:"\u1798\u17bd\u1799\u1781\u17c2",MM:"%d \u1781\u17c2",y:"\u1798\u17bd\u1799\u1786\u17d2\u1793\u17b6\u17c6",yy:"%d \u1786\u17d2\u1793\u17b6\u17c6"},dayOfMonthOrdinalParse:/\u1791\u17b8\d{1,2}/,ordinal:"\u1791\u17b8%d",preparse:function(e){return e.replace(/[\u17e1\u17e2\u17e3\u17e4\u17e5\u17e6\u17e7\u17e8\u17e9\u17e0]/g,function(_){return p[_]})},postformat:function(e){return e.replace(/\d/g,function(_){return u[_]})},week:{dow:1,doy:4}})}(i(16738))},68785:function(v,T,i){!function(r){"use strict";var u={1:"\u0ce7",2:"\u0ce8",3:"\u0ce9",4:"\u0cea",5:"\u0ceb",6:"\u0cec",7:"\u0ced",8:"\u0cee",9:"\u0cef",0:"\u0ce6"},p={"\u0ce7":"1","\u0ce8":"2","\u0ce9":"3","\u0cea":"4","\u0ceb":"5","\u0cec":"6","\u0ced":"7","\u0cee":"8","\u0cef":"9","\u0ce6":"0"};r.defineLocale("kn",{months:"\u0c9c\u0ca8\u0cb5\u0cb0\u0cbf_\u0cab\u0cc6\u0cac\u0ccd\u0cb0\u0cb5\u0cb0\u0cbf_\u0cae\u0cbe\u0cb0\u0ccd\u0c9a\u0ccd_\u0c8f\u0caa\u0ccd\u0cb0\u0cbf\u0cb2\u0ccd_\u0cae\u0cc6\u0cd5_\u0c9c\u0cc2\u0ca8\u0ccd_\u0c9c\u0cc1\u0cb2\u0cc6\u0cd6_\u0c86\u0c97\u0cb8\u0ccd\u0c9f\u0ccd_\u0cb8\u0cc6\u0caa\u0ccd\u0c9f\u0cc6\u0c82\u0cac\u0cb0\u0ccd_\u0c85\u0c95\u0ccd\u0c9f\u0cc6\u0cc2\u0cd5\u0cac\u0cb0\u0ccd_\u0ca8\u0cb5\u0cc6\u0c82\u0cac\u0cb0\u0ccd_\u0ca1\u0cbf\u0cb8\u0cc6\u0c82\u0cac\u0cb0\u0ccd".split("_"),monthsShort:"\u0c9c\u0ca8_\u0cab\u0cc6\u0cac\u0ccd\u0cb0_\u0cae\u0cbe\u0cb0\u0ccd\u0c9a\u0ccd_\u0c8f\u0caa\u0ccd\u0cb0\u0cbf\u0cb2\u0ccd_\u0cae\u0cc6\u0cd5_\u0c9c\u0cc2\u0ca8\u0ccd_\u0c9c\u0cc1\u0cb2\u0cc6\u0cd6_\u0c86\u0c97\u0cb8\u0ccd\u0c9f\u0ccd_\u0cb8\u0cc6\u0caa\u0ccd\u0c9f\u0cc6\u0c82_\u0c85\u0c95\u0ccd\u0c9f\u0cc6\u0cc2\u0cd5_\u0ca8\u0cb5\u0cc6\u0c82_\u0ca1\u0cbf\u0cb8\u0cc6\u0c82".split("_"),monthsParseExact:!0,weekdays:"\u0cad\u0cbe\u0ca8\u0cc1\u0cb5\u0cbe\u0cb0_\u0cb8\u0cc6\u0cc2\u0cd5\u0cae\u0cb5\u0cbe\u0cb0_\u0cae\u0c82\u0c97\u0cb3\u0cb5\u0cbe\u0cb0_\u0cac\u0cc1\u0ca7\u0cb5\u0cbe\u0cb0_\u0c97\u0cc1\u0cb0\u0cc1\u0cb5\u0cbe\u0cb0_\u0cb6\u0cc1\u0c95\u0ccd\u0cb0\u0cb5\u0cbe\u0cb0_\u0cb6\u0ca8\u0cbf\u0cb5\u0cbe\u0cb0".split("_"),weekdaysShort:"\u0cad\u0cbe\u0ca8\u0cc1_\u0cb8\u0cc6\u0cc2\u0cd5\u0cae_\u0cae\u0c82\u0c97\u0cb3_\u0cac\u0cc1\u0ca7_\u0c97\u0cc1\u0cb0\u0cc1_\u0cb6\u0cc1\u0c95\u0ccd\u0cb0_\u0cb6\u0ca8\u0cbf".split("_"),weekdaysMin:"\u0cad\u0cbe_\u0cb8\u0cc6\u0cc2\u0cd5_\u0cae\u0c82_\u0cac\u0cc1_\u0c97\u0cc1_\u0cb6\u0cc1_\u0cb6".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[\u0c87\u0c82\u0ca6\u0cc1] LT",nextDay:"[\u0ca8\u0cbe\u0cb3\u0cc6] LT",nextWeek:"dddd, LT",lastDay:"[\u0ca8\u0cbf\u0ca8\u0ccd\u0ca8\u0cc6] LT",lastWeek:"[\u0c95\u0cc6\u0cc2\u0ca8\u0cc6\u0caf] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0ca8\u0c82\u0ca4\u0cb0",past:"%s \u0cb9\u0cbf\u0c82\u0ca6\u0cc6",s:"\u0c95\u0cc6\u0cb2\u0cb5\u0cc1 \u0c95\u0ccd\u0cb7\u0ca3\u0c97\u0cb3\u0cc1",ss:"%d \u0cb8\u0cc6\u0c95\u0cc6\u0c82\u0ca1\u0cc1\u0c97\u0cb3\u0cc1",m:"\u0c92\u0c82\u0ca6\u0cc1 \u0ca8\u0cbf\u0cae\u0cbf\u0cb7",mm:"%d \u0ca8\u0cbf\u0cae\u0cbf\u0cb7",h:"\u0c92\u0c82\u0ca6\u0cc1 \u0c97\u0c82\u0c9f\u0cc6",hh:"%d \u0c97\u0c82\u0c9f\u0cc6",d:"\u0c92\u0c82\u0ca6\u0cc1 \u0ca6\u0cbf\u0ca8",dd:"%d \u0ca6\u0cbf\u0ca8",M:"\u0c92\u0c82\u0ca6\u0cc1 \u0ca4\u0cbf\u0c82\u0c97\u0cb3\u0cc1",MM:"%d \u0ca4\u0cbf\u0c82\u0c97\u0cb3\u0cc1",y:"\u0c92\u0c82\u0ca6\u0cc1 \u0cb5\u0cb0\u0ccd\u0cb7",yy:"%d \u0cb5\u0cb0\u0ccd\u0cb7"},preparse:function(e){return e.replace(/[\u0ce7\u0ce8\u0ce9\u0cea\u0ceb\u0cec\u0ced\u0cee\u0cef\u0ce6]/g,function(_){return p[_]})},postformat:function(e){return e.replace(/\d/g,function(_){return u[_]})},meridiemParse:/\u0cb0\u0cbe\u0ca4\u0ccd\u0cb0\u0cbf|\u0cac\u0cc6\u0cb3\u0cbf\u0c97\u0ccd\u0c97\u0cc6|\u0cae\u0ca7\u0ccd\u0caf\u0cbe\u0cb9\u0ccd\u0ca8|\u0cb8\u0c82\u0c9c\u0cc6/,meridiemHour:function(e,_){return 12===e&&(e=0),"\u0cb0\u0cbe\u0ca4\u0ccd\u0cb0\u0cbf"===_?e<4?e:e+12:"\u0cac\u0cc6\u0cb3\u0cbf\u0c97\u0ccd\u0c97\u0cc6"===_?e:"\u0cae\u0ca7\u0ccd\u0caf\u0cbe\u0cb9\u0ccd\u0ca8"===_?e>=10?e:e+12:"\u0cb8\u0c82\u0c9c\u0cc6"===_?e+12:void 0},meridiem:function(e,_,y){return e<4?"\u0cb0\u0cbe\u0ca4\u0ccd\u0cb0\u0cbf":e<10?"\u0cac\u0cc6\u0cb3\u0cbf\u0c97\u0ccd\u0c97\u0cc6":e<17?"\u0cae\u0ca7\u0ccd\u0caf\u0cbe\u0cb9\u0ccd\u0ca8":e<20?"\u0cb8\u0c82\u0c9c\u0cc6":"\u0cb0\u0cbe\u0ca4\u0ccd\u0cb0\u0cbf"},dayOfMonthOrdinalParse:/\d{1,2}(\u0ca8\u0cc6\u0cd5)/,ordinal:function(e){return e+"\u0ca8\u0cc6\u0cd5"},week:{dow:0,doy:6}})}(i(16738))},21721:function(v,T,i){!function(r){"use strict";r.defineLocale("ko",{months:"1\uc6d4_2\uc6d4_3\uc6d4_4\uc6d4_5\uc6d4_6\uc6d4_7\uc6d4_8\uc6d4_9\uc6d4_10\uc6d4_11\uc6d4_12\uc6d4".split("_"),monthsShort:"1\uc6d4_2\uc6d4_3\uc6d4_4\uc6d4_5\uc6d4_6\uc6d4_7\uc6d4_8\uc6d4_9\uc6d4_10\uc6d4_11\uc6d4_12\uc6d4".split("_"),weekdays:"\uc77c\uc694\uc77c_\uc6d4\uc694\uc77c_\ud654\uc694\uc77c_\uc218\uc694\uc77c_\ubaa9\uc694\uc77c_\uae08\uc694\uc77c_\ud1a0\uc694\uc77c".split("_"),weekdaysShort:"\uc77c_\uc6d4_\ud654_\uc218_\ubaa9_\uae08_\ud1a0".split("_"),weekdaysMin:"\uc77c_\uc6d4_\ud654_\uc218_\ubaa9_\uae08_\ud1a0".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"YYYY.MM.DD.",LL:"YYYY\ub144 MMMM D\uc77c",LLL:"YYYY\ub144 MMMM D\uc77c A h:mm",LLLL:"YYYY\ub144 MMMM D\uc77c dddd A h:mm",l:"YYYY.MM.DD.",ll:"YYYY\ub144 MMMM D\uc77c",lll:"YYYY\ub144 MMMM D\uc77c A h:mm",llll:"YYYY\ub144 MMMM D\uc77c dddd A h:mm"},calendar:{sameDay:"\uc624\ub298 LT",nextDay:"\ub0b4\uc77c LT",nextWeek:"dddd LT",lastDay:"\uc5b4\uc81c LT",lastWeek:"\uc9c0\ub09c\uc8fc dddd LT",sameElse:"L"},relativeTime:{future:"%s \ud6c4",past:"%s \uc804",s:"\uba87 \ucd08",ss:"%d\ucd08",m:"1\ubd84",mm:"%d\ubd84",h:"\ud55c \uc2dc\uac04",hh:"%d\uc2dc\uac04",d:"\ud558\ub8e8",dd:"%d\uc77c",M:"\ud55c \ub2ec",MM:"%d\ub2ec",y:"\uc77c \ub144",yy:"%d\ub144"},dayOfMonthOrdinalParse:/\d{1,2}(\uc77c|\uc6d4|\uc8fc)/,ordinal:function(p,d){switch(d){case"d":case"D":case"DDD":return p+"\uc77c";case"M":return p+"\uc6d4";case"w":case"W":return p+"\uc8fc";default:return p}},meridiemParse:/\uc624\uc804|\uc624\ud6c4/,isPM:function(p){return"\uc624\ud6c4"===p},meridiem:function(p,d,e){return p<12?"\uc624\uc804":"\uc624\ud6c4"}})}(i(16738))},37851:function(v,T,i){!function(r){"use strict";var u={1:"\u0661",2:"\u0662",3:"\u0663",4:"\u0664",5:"\u0665",6:"\u0666",7:"\u0667",8:"\u0668",9:"\u0669",0:"\u0660"},p={"\u0661":"1","\u0662":"2","\u0663":"3","\u0664":"4","\u0665":"5","\u0666":"6","\u0667":"7","\u0668":"8","\u0669":"9","\u0660":"0"},d=["\u06a9\u0627\u0646\u0648\u0646\u06cc \u062f\u0648\u0648\u06d5\u0645","\u0634\u0648\u0628\u0627\u062a","\u0626\u0627\u0632\u0627\u0631","\u0646\u06cc\u0633\u0627\u0646","\u0626\u0627\u06cc\u0627\u0631","\u062d\u0648\u0632\u06d5\u06cc\u0631\u0627\u0646","\u062a\u06d5\u0645\u0645\u0648\u0632","\u0626\u0627\u0628","\u0626\u06d5\u06cc\u0644\u0648\u0648\u0644","\u062a\u0634\u0631\u06cc\u0646\u06cc \u06cc\u06d5\u0643\u06d5\u0645","\u062a\u0634\u0631\u06cc\u0646\u06cc \u062f\u0648\u0648\u06d5\u0645","\u0643\u0627\u0646\u0648\u0646\u06cc \u06cc\u06d5\u06a9\u06d5\u0645"];r.defineLocale("ku",{months:d,monthsShort:d,weekdays:"\u06cc\u0647\u200c\u0643\u0634\u0647\u200c\u0645\u0645\u0647\u200c_\u062f\u0648\u0648\u0634\u0647\u200c\u0645\u0645\u0647\u200c_\u0633\u06ce\u0634\u0647\u200c\u0645\u0645\u0647\u200c_\u0686\u0648\u0627\u0631\u0634\u0647\u200c\u0645\u0645\u0647\u200c_\u067e\u06ce\u0646\u062c\u0634\u0647\u200c\u0645\u0645\u0647\u200c_\u0647\u0647\u200c\u06cc\u0646\u06cc_\u0634\u0647\u200c\u0645\u0645\u0647\u200c".split("_"),weekdaysShort:"\u06cc\u0647\u200c\u0643\u0634\u0647\u200c\u0645_\u062f\u0648\u0648\u0634\u0647\u200c\u0645_\u0633\u06ce\u0634\u0647\u200c\u0645_\u0686\u0648\u0627\u0631\u0634\u0647\u200c\u0645_\u067e\u06ce\u0646\u062c\u0634\u0647\u200c\u0645_\u0647\u0647\u200c\u06cc\u0646\u06cc_\u0634\u0647\u200c\u0645\u0645\u0647\u200c".split("_"),weekdaysMin:"\u06cc_\u062f_\u0633_\u0686_\u067e_\u0647_\u0634".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/\u0626\u06ce\u0648\u0627\u0631\u0647\u200c|\u0628\u0647\u200c\u06cc\u0627\u0646\u06cc/,isPM:function(_){return/\u0626\u06ce\u0648\u0627\u0631\u0647\u200c/.test(_)},meridiem:function(_,y,S){return _<12?"\u0628\u0647\u200c\u06cc\u0627\u0646\u06cc":"\u0626\u06ce\u0648\u0627\u0631\u0647\u200c"},calendar:{sameDay:"[\u0626\u0647\u200c\u0645\u0631\u06c6 \u0643\u0627\u062a\u0698\u0645\u06ce\u0631] LT",nextDay:"[\u0628\u0647\u200c\u06cc\u0627\u0646\u06cc \u0643\u0627\u062a\u0698\u0645\u06ce\u0631] LT",nextWeek:"dddd [\u0643\u0627\u062a\u0698\u0645\u06ce\u0631] LT",lastDay:"[\u062f\u0648\u06ce\u0646\u06ce \u0643\u0627\u062a\u0698\u0645\u06ce\u0631] LT",lastWeek:"dddd [\u0643\u0627\u062a\u0698\u0645\u06ce\u0631] LT",sameElse:"L"},relativeTime:{future:"\u0644\u0647\u200c %s",past:"%s",s:"\u0686\u0647\u200c\u0646\u062f \u0686\u0631\u0643\u0647\u200c\u06cc\u0647\u200c\u0643",ss:"\u0686\u0631\u0643\u0647\u200c %d",m:"\u06cc\u0647\u200c\u0643 \u062e\u0648\u0644\u0647\u200c\u0643",mm:"%d \u062e\u0648\u0644\u0647\u200c\u0643",h:"\u06cc\u0647\u200c\u0643 \u0643\u0627\u062a\u0698\u0645\u06ce\u0631",hh:"%d \u0643\u0627\u062a\u0698\u0645\u06ce\u0631",d:"\u06cc\u0647\u200c\u0643 \u0695\u06c6\u0698",dd:"%d \u0695\u06c6\u0698",M:"\u06cc\u0647\u200c\u0643 \u0645\u0627\u0646\u06af",MM:"%d \u0645\u0627\u0646\u06af",y:"\u06cc\u0647\u200c\u0643 \u0633\u0627\u06b5",yy:"%d \u0633\u0627\u06b5"},preparse:function(_){return _.replace(/[\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u0660]/g,function(y){return p[y]}).replace(/\u060c/g,",")},postformat:function(_){return _.replace(/\d/g,function(y){return u[y]}).replace(/,/g,"\u060c")},week:{dow:6,doy:12}})}(i(16738))},1727:function(v,T,i){!function(r){"use strict";var u={0:"-\u0447\u04af",1:"-\u0447\u0438",2:"-\u0447\u0438",3:"-\u0447\u04af",4:"-\u0447\u04af",5:"-\u0447\u0438",6:"-\u0447\u044b",7:"-\u0447\u0438",8:"-\u0447\u0438",9:"-\u0447\u0443",10:"-\u0447\u0443",20:"-\u0447\u044b",30:"-\u0447\u0443",40:"-\u0447\u044b",50:"-\u0447\u04af",60:"-\u0447\u044b",70:"-\u0447\u0438",80:"-\u0447\u0438",90:"-\u0447\u0443",100:"-\u0447\u04af"};r.defineLocale("ky",{months:"\u044f\u043d\u0432\u0430\u0440\u044c_\u0444\u0435\u0432\u0440\u0430\u043b\u044c_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0435\u043b\u044c_\u043c\u0430\u0439_\u0438\u044e\u043d\u044c_\u0438\u044e\u043b\u044c_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c_\u043e\u043a\u0442\u044f\u0431\u0440\u044c_\u043d\u043e\u044f\u0431\u0440\u044c_\u0434\u0435\u043a\u0430\u0431\u0440\u044c".split("_"),monthsShort:"\u044f\u043d\u0432_\u0444\u0435\u0432_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440_\u043c\u0430\u0439_\u0438\u044e\u043d\u044c_\u0438\u044e\u043b\u044c_\u0430\u0432\u0433_\u0441\u0435\u043d_\u043e\u043a\u0442_\u043d\u043e\u044f_\u0434\u0435\u043a".split("_"),weekdays:"\u0416\u0435\u043a\u0448\u0435\u043c\u0431\u0438_\u0414\u04af\u0439\u0448\u04e9\u043c\u0431\u04af_\u0428\u0435\u0439\u0448\u0435\u043c\u0431\u0438_\u0428\u0430\u0440\u0448\u0435\u043c\u0431\u0438_\u0411\u0435\u0439\u0448\u0435\u043c\u0431\u0438_\u0416\u0443\u043c\u0430_\u0418\u0448\u0435\u043c\u0431\u0438".split("_"),weekdaysShort:"\u0416\u0435\u043a_\u0414\u04af\u0439_\u0428\u0435\u0439_\u0428\u0430\u0440_\u0411\u0435\u0439_\u0416\u0443\u043c_\u0418\u0448\u0435".split("_"),weekdaysMin:"\u0416\u043a_\u0414\u0439_\u0428\u0439_\u0428\u0440_\u0411\u0439_\u0416\u043c_\u0418\u0448".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0411\u04af\u0433\u04af\u043d \u0441\u0430\u0430\u0442] LT",nextDay:"[\u042d\u0440\u0442\u0435\u04a3 \u0441\u0430\u0430\u0442] LT",nextWeek:"dddd [\u0441\u0430\u0430\u0442] LT",lastDay:"[\u041a\u0435\u0447\u044d\u044d \u0441\u0430\u0430\u0442] LT",lastWeek:"[\u04e8\u0442\u043a\u04e9\u043d \u0430\u043f\u0442\u0430\u043d\u044b\u043d] dddd [\u043a\u04af\u043d\u04af] [\u0441\u0430\u0430\u0442] LT",sameElse:"L"},relativeTime:{future:"%s \u0438\u0447\u0438\u043d\u0434\u0435",past:"%s \u043c\u0443\u0440\u0443\u043d",s:"\u0431\u0438\u0440\u043d\u0435\u0447\u0435 \u0441\u0435\u043a\u0443\u043d\u0434",ss:"%d \u0441\u0435\u043a\u0443\u043d\u0434",m:"\u0431\u0438\u0440 \u043c\u04af\u043d\u04e9\u0442",mm:"%d \u043c\u04af\u043d\u04e9\u0442",h:"\u0431\u0438\u0440 \u0441\u0430\u0430\u0442",hh:"%d \u0441\u0430\u0430\u0442",d:"\u0431\u0438\u0440 \u043a\u04af\u043d",dd:"%d \u043a\u04af\u043d",M:"\u0431\u0438\u0440 \u0430\u0439",MM:"%d \u0430\u0439",y:"\u0431\u0438\u0440 \u0436\u044b\u043b",yy:"%d \u0436\u044b\u043b"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0447\u0438|\u0447\u044b|\u0447\u04af|\u0447\u0443)/,ordinal:function(d){return d+(u[d]||u[d%10]||u[d>=100?100:null])},week:{dow:1,doy:7}})}(i(16738))},40346:function(v,T,i){!function(r){"use strict";function u(y,S,A,N){var L={m:["eng Minutt","enger Minutt"],h:["eng Stonn","enger Stonn"],d:["een Dag","engem Dag"],M:["ee Mount","engem Mount"],y:["ee Joer","engem Joer"]};return S?L[A][0]:L[A][1]}function e(y){if(y=parseInt(y,10),isNaN(y))return!1;if(y<0)return!0;if(y<10)return 4<=y&&y<=7;if(y<100){var S=y%10;return e(0===S?y/10:S)}if(y<1e4){for(;y>=10;)y/=10;return e(y)}return e(y/=1e3)}r.defineLocale("lb",{months:"Januar_Februar_M\xe4erz_Abr\xebll_Mee_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonndeg_M\xe9indeg_D\xebnschdeg_M\xebttwoch_Donneschdeg_Freideg_Samschdeg".split("_"),weekdaysShort:"So._M\xe9._D\xeb._M\xeb._Do._Fr._Sa.".split("_"),weekdaysMin:"So_M\xe9_D\xeb_M\xeb_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm [Auer]",LTS:"H:mm:ss [Auer]",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm [Auer]",LLLL:"dddd, D. MMMM YYYY H:mm [Auer]"},calendar:{sameDay:"[Haut um] LT",sameElse:"L",nextDay:"[Muer um] LT",nextWeek:"dddd [um] LT",lastDay:"[G\xebschter um] LT",lastWeek:function(){switch(this.day()){case 2:case 4:return"[Leschten] dddd [um] LT";default:return"[Leschte] dddd [um] LT"}}},relativeTime:{future:function(y){return e(y.substr(0,y.indexOf(" ")))?"a "+y:"an "+y},past:function(y){return e(y.substr(0,y.indexOf(" ")))?"viru "+y:"virun "+y},s:"e puer Sekonnen",ss:"%d Sekonnen",m:u,mm:"%d Minutten",h:u,hh:"%d Stonnen",d:u,dd:"%d Deeg",M:u,MM:"%d M\xe9int",y:u,yy:"%d Joer"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},93002:function(v,T,i){!function(r){"use strict";r.defineLocale("lo",{months:"\u0ea1\u0eb1\u0e87\u0e81\u0ead\u0e99_\u0e81\u0eb8\u0ea1\u0e9e\u0eb2_\u0ea1\u0eb5\u0e99\u0eb2_\u0ec0\u0ea1\u0eaa\u0eb2_\u0e9e\u0eb6\u0e94\u0eaa\u0eb0\u0e9e\u0eb2_\u0ea1\u0eb4\u0e96\u0eb8\u0e99\u0eb2_\u0e81\u0ecd\u0ea5\u0eb0\u0e81\u0ebb\u0e94_\u0eaa\u0eb4\u0e87\u0eab\u0eb2_\u0e81\u0eb1\u0e99\u0e8d\u0eb2_\u0e95\u0eb8\u0ea5\u0eb2_\u0e9e\u0eb0\u0e88\u0eb4\u0e81_\u0e97\u0eb1\u0e99\u0ea7\u0eb2".split("_"),monthsShort:"\u0ea1\u0eb1\u0e87\u0e81\u0ead\u0e99_\u0e81\u0eb8\u0ea1\u0e9e\u0eb2_\u0ea1\u0eb5\u0e99\u0eb2_\u0ec0\u0ea1\u0eaa\u0eb2_\u0e9e\u0eb6\u0e94\u0eaa\u0eb0\u0e9e\u0eb2_\u0ea1\u0eb4\u0e96\u0eb8\u0e99\u0eb2_\u0e81\u0ecd\u0ea5\u0eb0\u0e81\u0ebb\u0e94_\u0eaa\u0eb4\u0e87\u0eab\u0eb2_\u0e81\u0eb1\u0e99\u0e8d\u0eb2_\u0e95\u0eb8\u0ea5\u0eb2_\u0e9e\u0eb0\u0e88\u0eb4\u0e81_\u0e97\u0eb1\u0e99\u0ea7\u0eb2".split("_"),weekdays:"\u0ead\u0eb2\u0e97\u0eb4\u0e94_\u0e88\u0eb1\u0e99_\u0ead\u0eb1\u0e87\u0e84\u0eb2\u0e99_\u0e9e\u0eb8\u0e94_\u0e9e\u0eb0\u0eab\u0eb1\u0e94_\u0eaa\u0eb8\u0e81_\u0ec0\u0eaa\u0ebb\u0eb2".split("_"),weekdaysShort:"\u0e97\u0eb4\u0e94_\u0e88\u0eb1\u0e99_\u0ead\u0eb1\u0e87\u0e84\u0eb2\u0e99_\u0e9e\u0eb8\u0e94_\u0e9e\u0eb0\u0eab\u0eb1\u0e94_\u0eaa\u0eb8\u0e81_\u0ec0\u0eaa\u0ebb\u0eb2".split("_"),weekdaysMin:"\u0e97_\u0e88_\u0ead\u0e84_\u0e9e_\u0e9e\u0eab_\u0eaa\u0e81_\u0eaa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"\u0ea7\u0eb1\u0e99dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0e95\u0ead\u0e99\u0ec0\u0e8a\u0ebb\u0ec9\u0eb2|\u0e95\u0ead\u0e99\u0ec1\u0ea5\u0e87/,isPM:function(p){return"\u0e95\u0ead\u0e99\u0ec1\u0ea5\u0e87"===p},meridiem:function(p,d,e){return p<12?"\u0e95\u0ead\u0e99\u0ec0\u0e8a\u0ebb\u0ec9\u0eb2":"\u0e95\u0ead\u0e99\u0ec1\u0ea5\u0e87"},calendar:{sameDay:"[\u0ea1\u0eb7\u0ec9\u0e99\u0eb5\u0ec9\u0ec0\u0ea7\u0ea5\u0eb2] LT",nextDay:"[\u0ea1\u0eb7\u0ec9\u0ead\u0eb7\u0ec8\u0e99\u0ec0\u0ea7\u0ea5\u0eb2] LT",nextWeek:"[\u0ea7\u0eb1\u0e99]dddd[\u0edc\u0ec9\u0eb2\u0ec0\u0ea7\u0ea5\u0eb2] LT",lastDay:"[\u0ea1\u0eb7\u0ec9\u0ea7\u0eb2\u0e99\u0e99\u0eb5\u0ec9\u0ec0\u0ea7\u0ea5\u0eb2] LT",lastWeek:"[\u0ea7\u0eb1\u0e99]dddd[\u0ec1\u0ea5\u0ec9\u0ea7\u0e99\u0eb5\u0ec9\u0ec0\u0ea7\u0ea5\u0eb2] LT",sameElse:"L"},relativeTime:{future:"\u0ead\u0eb5\u0e81 %s",past:"%s\u0e9c\u0ec8\u0eb2\u0e99\u0ea1\u0eb2",s:"\u0e9a\u0ecd\u0ec8\u0ec0\u0e97\u0ebb\u0ec8\u0eb2\u0ec3\u0e94\u0ea7\u0eb4\u0e99\u0eb2\u0e97\u0eb5",ss:"%d \u0ea7\u0eb4\u0e99\u0eb2\u0e97\u0eb5",m:"1 \u0e99\u0eb2\u0e97\u0eb5",mm:"%d \u0e99\u0eb2\u0e97\u0eb5",h:"1 \u0e8a\u0ebb\u0ec8\u0ea7\u0ec2\u0ea1\u0e87",hh:"%d \u0e8a\u0ebb\u0ec8\u0ea7\u0ec2\u0ea1\u0e87",d:"1 \u0ea1\u0eb7\u0ec9",dd:"%d \u0ea1\u0eb7\u0ec9",M:"1 \u0ec0\u0e94\u0eb7\u0ead\u0e99",MM:"%d \u0ec0\u0e94\u0eb7\u0ead\u0e99",y:"1 \u0e9b\u0eb5",yy:"%d \u0e9b\u0eb5"},dayOfMonthOrdinalParse:/(\u0e97\u0eb5\u0ec8)\d{1,2}/,ordinal:function(p){return"\u0e97\u0eb5\u0ec8"+p}})}(i(16738))},64035:function(v,T,i){!function(r){"use strict";var u={ss:"sekund\u0117_sekund\u017ei\u0173_sekundes",m:"minut\u0117_minut\u0117s_minut\u0119",mm:"minut\u0117s_minu\u010di\u0173_minutes",h:"valanda_valandos_valand\u0105",hh:"valandos_valand\u0173_valandas",d:"diena_dienos_dien\u0105",dd:"dienos_dien\u0173_dienas",M:"m\u0117nuo_m\u0117nesio_m\u0117nes\u012f",MM:"m\u0117nesiai_m\u0117nesi\u0173_m\u0117nesius",y:"metai_met\u0173_metus",yy:"metai_met\u0173_metus"};function d(A,N,L,Z){return N?_(L)[0]:Z?_(L)[1]:_(L)[2]}function e(A){return A%10==0||A>10&&A<20}function _(A){return u[A].split("_")}function y(A,N,L,Z){var J=A+" ";return 1===A?J+d(0,N,L[0],Z):N?J+(e(A)?_(L)[1]:_(L)[0]):Z?J+_(L)[1]:J+(e(A)?_(L)[1]:_(L)[2])}r.defineLocale("lt",{months:{format:"sausio_vasario_kovo_baland\u017eio_gegu\u017e\u0117s_bir\u017eelio_liepos_rugpj\u016b\u010dio_rugs\u0117jo_spalio_lapkri\u010dio_gruod\u017eio".split("_"),standalone:"sausis_vasaris_kovas_balandis_gegu\u017e\u0117_bir\u017eelis_liepa_rugpj\u016btis_rugs\u0117jis_spalis_lapkritis_gruodis".split("_"),isFormat:/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/},monthsShort:"sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd".split("_"),weekdays:{format:"sekmadien\u012f_pirmadien\u012f_antradien\u012f_tre\u010diadien\u012f_ketvirtadien\u012f_penktadien\u012f_\u0161e\u0161tadien\u012f".split("_"),standalone:"sekmadienis_pirmadienis_antradienis_tre\u010diadienis_ketvirtadienis_penktadienis_\u0161e\u0161tadienis".split("_"),isFormat:/dddd HH:mm/},weekdaysShort:"Sek_Pir_Ant_Tre_Ket_Pen_\u0160e\u0161".split("_"),weekdaysMin:"S_P_A_T_K_Pn_\u0160".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY [m.] MMMM D [d.]",LLL:"YYYY [m.] MMMM D [d.], HH:mm [val.]",LLLL:"YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]",l:"YYYY-MM-DD",ll:"YYYY [m.] MMMM D [d.]",lll:"YYYY [m.] MMMM D [d.], HH:mm [val.]",llll:"YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]"},calendar:{sameDay:"[\u0160iandien] LT",nextDay:"[Rytoj] LT",nextWeek:"dddd LT",lastDay:"[Vakar] LT",lastWeek:"[Pra\u0117jus\u012f] dddd LT",sameElse:"L"},relativeTime:{future:"po %s",past:"prie\u0161 %s",s:function(A,N,L,Z){return N?"kelios sekund\u0117s":Z?"keli\u0173 sekund\u017ei\u0173":"kelias sekundes"},ss:y,m:d,mm:y,h:d,hh:y,d,dd:y,M:d,MM:y,y:d,yy:y},dayOfMonthOrdinalParse:/\d{1,2}-oji/,ordinal:function(A){return A+"-oji"},week:{dow:1,doy:4}})}(i(16738))},56927:function(v,T,i){!function(r){"use strict";var u={ss:"sekundes_sekund\u0113m_sekunde_sekundes".split("_"),m:"min\u016btes_min\u016bt\u0113m_min\u016bte_min\u016btes".split("_"),mm:"min\u016btes_min\u016bt\u0113m_min\u016bte_min\u016btes".split("_"),h:"stundas_stund\u0101m_stunda_stundas".split("_"),hh:"stundas_stund\u0101m_stunda_stundas".split("_"),d:"dienas_dien\u0101m_diena_dienas".split("_"),dd:"dienas_dien\u0101m_diena_dienas".split("_"),M:"m\u0113ne\u0161a_m\u0113ne\u0161iem_m\u0113nesis_m\u0113ne\u0161i".split("_"),MM:"m\u0113ne\u0161a_m\u0113ne\u0161iem_m\u0113nesis_m\u0113ne\u0161i".split("_"),y:"gada_gadiem_gads_gadi".split("_"),yy:"gada_gadiem_gads_gadi".split("_")};function p(S,A,N){return N?A%10==1&&A%100!=11?S[2]:S[3]:A%10==1&&A%100!=11?S[0]:S[1]}function d(S,A,N){return S+" "+p(u[N],S,A)}function e(S,A,N){return p(u[N],S,A)}r.defineLocale("lv",{months:"janv\u0101ris_febru\u0101ris_marts_apr\u012blis_maijs_j\u016bnijs_j\u016blijs_augusts_septembris_oktobris_novembris_decembris".split("_"),monthsShort:"jan_feb_mar_apr_mai_j\u016bn_j\u016bl_aug_sep_okt_nov_dec".split("_"),weekdays:"sv\u0113tdiena_pirmdiena_otrdiena_tre\u0161diena_ceturtdiena_piektdiena_sestdiena".split("_"),weekdaysShort:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysMin:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY.",LL:"YYYY. [gada] D. MMMM",LLL:"YYYY. [gada] D. MMMM, HH:mm",LLLL:"YYYY. [gada] D. MMMM, dddd, HH:mm"},calendar:{sameDay:"[\u0160odien pulksten] LT",nextDay:"[R\u012bt pulksten] LT",nextWeek:"dddd [pulksten] LT",lastDay:"[Vakar pulksten] LT",lastWeek:"[Pag\u0101ju\u0161\u0101] dddd [pulksten] LT",sameElse:"L"},relativeTime:{future:"p\u0113c %s",past:"pirms %s",s:function(S,A){return A?"da\u017eas sekundes":"da\u017e\u0101m sekund\u0113m"},ss:d,m:e,mm:d,h:e,hh:d,d:e,dd:d,M:e,MM:d,y:e,yy:d},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},5634:function(v,T,i){!function(r){"use strict";var u={words:{ss:["sekund","sekunda","sekundi"],m:["jedan minut","jednog minuta"],mm:["minut","minuta","minuta"],h:["jedan sat","jednog sata"],hh:["sat","sata","sati"],dd:["dan","dana","dana"],MM:["mjesec","mjeseca","mjeseci"],yy:["godina","godine","godina"]},correctGrammaticalCase:function(d,e){return 1===d?e[0]:d>=2&&d<=4?e[1]:e[2]},translate:function(d,e,_){var y=u.words[_];return 1===_.length?e?y[0]:y[1]:d+" "+u.correctGrammaticalCase(d,y)}};r.defineLocale("me",{months:"januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_\u010detvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._\u010det._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_\u010de_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sjutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[ju\u010de u] LT",lastWeek:function(){return["[pro\u0161le] [nedjelje] [u] LT","[pro\u0161log] [ponedjeljka] [u] LT","[pro\u0161log] [utorka] [u] LT","[pro\u0161le] [srijede] [u] LT","[pro\u0161log] [\u010detvrtka] [u] LT","[pro\u0161log] [petka] [u] LT","[pro\u0161le] [subote] [u] LT"][this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"nekoliko sekundi",ss:u.translate,m:u.translate,mm:u.translate,h:u.translate,hh:u.translate,d:"dan",dd:u.translate,M:"mjesec",MM:u.translate,y:"godinu",yy:u.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(i(16738))},94173:function(v,T,i){!function(r){"use strict";r.defineLocale("mi",{months:"Kohi-t\u0101te_Hui-tanguru_Pout\u016b-te-rangi_Paenga-wh\u0101wh\u0101_Haratua_Pipiri_H\u014dngoingoi_Here-turi-k\u014dk\u0101_Mahuru_Whiringa-\u0101-nuku_Whiringa-\u0101-rangi_Hakihea".split("_"),monthsShort:"Kohi_Hui_Pou_Pae_Hara_Pipi_H\u014dngoi_Here_Mahu_Whi-nu_Whi-ra_Haki".split("_"),monthsRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsStrictRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsShortRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsShortStrictRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i,weekdays:"R\u0101tapu_Mane_T\u016brei_Wenerei_T\u0101ite_Paraire_H\u0101tarei".split("_"),weekdaysShort:"Ta_Ma_T\u016b_We_T\u0101i_Pa_H\u0101".split("_"),weekdaysMin:"Ta_Ma_T\u016b_We_T\u0101i_Pa_H\u0101".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [i] HH:mm",LLLL:"dddd, D MMMM YYYY [i] HH:mm"},calendar:{sameDay:"[i teie mahana, i] LT",nextDay:"[apopo i] LT",nextWeek:"dddd [i] LT",lastDay:"[inanahi i] LT",lastWeek:"dddd [whakamutunga i] LT",sameElse:"L"},relativeTime:{future:"i roto i %s",past:"%s i mua",s:"te h\u0113kona ruarua",ss:"%d h\u0113kona",m:"he meneti",mm:"%d meneti",h:"te haora",hh:"%d haora",d:"he ra",dd:"%d ra",M:"he marama",MM:"%d marama",y:"he tau",yy:"%d tau"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}(i(16738))},86320:function(v,T,i){!function(r){"use strict";r.defineLocale("mk",{months:"\u0458\u0430\u043d\u0443\u0430\u0440\u0438_\u0444\u0435\u0432\u0440\u0443\u0430\u0440\u0438_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0438\u043b_\u043c\u0430\u0458_\u0458\u0443\u043d\u0438_\u0458\u0443\u043b\u0438_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438_\u043e\u043a\u0442\u043e\u043c\u0432\u0440\u0438_\u043d\u043e\u0435\u043c\u0432\u0440\u0438_\u0434\u0435\u043a\u0435\u043c\u0432\u0440\u0438".split("_"),monthsShort:"\u0458\u0430\u043d_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0458_\u0458\u0443\u043d_\u0458\u0443\u043b_\u0430\u0432\u0433_\u0441\u0435\u043f_\u043e\u043a\u0442_\u043d\u043e\u0435_\u0434\u0435\u043a".split("_"),weekdays:"\u043d\u0435\u0434\u0435\u043b\u0430_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u0435\u0434\u0430_\u0447\u0435\u0442\u0432\u0440\u0442\u043e\u043a_\u043f\u0435\u0442\u043e\u043a_\u0441\u0430\u0431\u043e\u0442\u0430".split("_"),weekdaysShort:"\u043d\u0435\u0434_\u043f\u043e\u043d_\u0432\u0442\u043e_\u0441\u0440\u0435_\u0447\u0435\u0442_\u043f\u0435\u0442_\u0441\u0430\u0431".split("_"),weekdaysMin:"\u043de_\u043fo_\u0432\u0442_\u0441\u0440_\u0447\u0435_\u043f\u0435_\u0441a".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[\u0414\u0435\u043d\u0435\u0441 \u0432\u043e] LT",nextDay:"[\u0423\u0442\u0440\u0435 \u0432\u043e] LT",nextWeek:"[\u0412\u043e] dddd [\u0432\u043e] LT",lastDay:"[\u0412\u0447\u0435\u0440\u0430 \u0432\u043e] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[\u0418\u0437\u043c\u0438\u043d\u0430\u0442\u0430\u0442\u0430] dddd [\u0432\u043e] LT";case 1:case 2:case 4:case 5:return"[\u0418\u0437\u043c\u0438\u043d\u0430\u0442\u0438\u043e\u0442] dddd [\u0432\u043e] LT"}},sameElse:"L"},relativeTime:{future:"\u0437\u0430 %s",past:"\u043f\u0440\u0435\u0434 %s",s:"\u043d\u0435\u043a\u043e\u043b\u043a\u0443 \u0441\u0435\u043a\u0443\u043d\u0434\u0438",ss:"%d \u0441\u0435\u043a\u0443\u043d\u0434\u0438",m:"\u0435\u0434\u043d\u0430 \u043c\u0438\u043d\u0443\u0442\u0430",mm:"%d \u043c\u0438\u043d\u0443\u0442\u0438",h:"\u0435\u0434\u0435\u043d \u0447\u0430\u0441",hh:"%d \u0447\u0430\u0441\u0430",d:"\u0435\u0434\u0435\u043d \u0434\u0435\u043d",dd:"%d \u0434\u0435\u043d\u0430",M:"\u0435\u0434\u0435\u043d \u043c\u0435\u0441\u0435\u0446",MM:"%d \u043c\u0435\u0441\u0435\u0446\u0438",y:"\u0435\u0434\u043d\u0430 \u0433\u043e\u0434\u0438\u043d\u0430",yy:"%d \u0433\u043e\u0434\u0438\u043d\u0438"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0435\u0432|\u0435\u043d|\u0442\u0438|\u0432\u0438|\u0440\u0438|\u043c\u0438)/,ordinal:function(p){var d=p%10,e=p%100;return 0===p?p+"-\u0435\u0432":0===e?p+"-\u0435\u043d":e>10&&e<20?p+"-\u0442\u0438":1===d?p+"-\u0432\u0438":2===d?p+"-\u0440\u0438":7===d||8===d?p+"-\u043c\u0438":p+"-\u0442\u0438"},week:{dow:1,doy:7}})}(i(16738))},11705:function(v,T,i){!function(r){"use strict";r.defineLocale("ml",{months:"\u0d1c\u0d28\u0d41\u0d35\u0d30\u0d3f_\u0d2b\u0d46\u0d2c\u0d4d\u0d30\u0d41\u0d35\u0d30\u0d3f_\u0d2e\u0d3e\u0d7c\u0d1a\u0d4d\u0d1a\u0d4d_\u0d0f\u0d2a\u0d4d\u0d30\u0d3f\u0d7d_\u0d2e\u0d47\u0d2f\u0d4d_\u0d1c\u0d42\u0d7a_\u0d1c\u0d42\u0d32\u0d48_\u0d13\u0d17\u0d38\u0d4d\u0d31\u0d4d\u0d31\u0d4d_\u0d38\u0d46\u0d2a\u0d4d\u0d31\u0d4d\u0d31\u0d02\u0d2c\u0d7c_\u0d12\u0d15\u0d4d\u0d1f\u0d4b\u0d2c\u0d7c_\u0d28\u0d35\u0d02\u0d2c\u0d7c_\u0d21\u0d3f\u0d38\u0d02\u0d2c\u0d7c".split("_"),monthsShort:"\u0d1c\u0d28\u0d41._\u0d2b\u0d46\u0d2c\u0d4d\u0d30\u0d41._\u0d2e\u0d3e\u0d7c._\u0d0f\u0d2a\u0d4d\u0d30\u0d3f._\u0d2e\u0d47\u0d2f\u0d4d_\u0d1c\u0d42\u0d7a_\u0d1c\u0d42\u0d32\u0d48._\u0d13\u0d17._\u0d38\u0d46\u0d2a\u0d4d\u0d31\u0d4d\u0d31._\u0d12\u0d15\u0d4d\u0d1f\u0d4b._\u0d28\u0d35\u0d02._\u0d21\u0d3f\u0d38\u0d02.".split("_"),monthsParseExact:!0,weekdays:"\u0d1e\u0d3e\u0d2f\u0d31\u0d3e\u0d34\u0d4d\u0d1a_\u0d24\u0d3f\u0d19\u0d4d\u0d15\u0d33\u0d3e\u0d34\u0d4d\u0d1a_\u0d1a\u0d4a\u0d35\u0d4d\u0d35\u0d3e\u0d34\u0d4d\u0d1a_\u0d2c\u0d41\u0d27\u0d28\u0d3e\u0d34\u0d4d\u0d1a_\u0d35\u0d4d\u0d2f\u0d3e\u0d34\u0d3e\u0d34\u0d4d\u0d1a_\u0d35\u0d46\u0d33\u0d4d\u0d33\u0d3f\u0d2f\u0d3e\u0d34\u0d4d\u0d1a_\u0d36\u0d28\u0d3f\u0d2f\u0d3e\u0d34\u0d4d\u0d1a".split("_"),weekdaysShort:"\u0d1e\u0d3e\u0d2f\u0d7c_\u0d24\u0d3f\u0d19\u0d4d\u0d15\u0d7e_\u0d1a\u0d4a\u0d35\u0d4d\u0d35_\u0d2c\u0d41\u0d27\u0d7b_\u0d35\u0d4d\u0d2f\u0d3e\u0d34\u0d02_\u0d35\u0d46\u0d33\u0d4d\u0d33\u0d3f_\u0d36\u0d28\u0d3f".split("_"),weekdaysMin:"\u0d1e\u0d3e_\u0d24\u0d3f_\u0d1a\u0d4a_\u0d2c\u0d41_\u0d35\u0d4d\u0d2f\u0d3e_\u0d35\u0d46_\u0d36".split("_"),longDateFormat:{LT:"A h:mm -\u0d28\u0d41",LTS:"A h:mm:ss -\u0d28\u0d41",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm -\u0d28\u0d41",LLLL:"dddd, D MMMM YYYY, A h:mm -\u0d28\u0d41"},calendar:{sameDay:"[\u0d07\u0d28\u0d4d\u0d28\u0d4d] LT",nextDay:"[\u0d28\u0d3e\u0d33\u0d46] LT",nextWeek:"dddd, LT",lastDay:"[\u0d07\u0d28\u0d4d\u0d28\u0d32\u0d46] LT",lastWeek:"[\u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e\u0d4d",past:"%s \u0d2e\u0d41\u0d7b\u0d2a\u0d4d",s:"\u0d05\u0d7d\u0d2a \u0d28\u0d3f\u0d2e\u0d3f\u0d37\u0d19\u0d4d\u0d19\u0d7e",ss:"%d \u0d38\u0d46\u0d15\u0d4d\u0d15\u0d7b\u0d21\u0d4d",m:"\u0d12\u0d30\u0d41 \u0d2e\u0d3f\u0d28\u0d3f\u0d31\u0d4d\u0d31\u0d4d",mm:"%d \u0d2e\u0d3f\u0d28\u0d3f\u0d31\u0d4d\u0d31\u0d4d",h:"\u0d12\u0d30\u0d41 \u0d2e\u0d23\u0d3f\u0d15\u0d4d\u0d15\u0d42\u0d7c",hh:"%d \u0d2e\u0d23\u0d3f\u0d15\u0d4d\u0d15\u0d42\u0d7c",d:"\u0d12\u0d30\u0d41 \u0d26\u0d3f\u0d35\u0d38\u0d02",dd:"%d \u0d26\u0d3f\u0d35\u0d38\u0d02",M:"\u0d12\u0d30\u0d41 \u0d2e\u0d3e\u0d38\u0d02",MM:"%d \u0d2e\u0d3e\u0d38\u0d02",y:"\u0d12\u0d30\u0d41 \u0d35\u0d7c\u0d37\u0d02",yy:"%d \u0d35\u0d7c\u0d37\u0d02"},meridiemParse:/\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f|\u0d30\u0d3e\u0d35\u0d3f\u0d32\u0d46|\u0d09\u0d1a\u0d4d\u0d1a \u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e\u0d4d|\u0d35\u0d48\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d47\u0d30\u0d02|\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f/i,meridiemHour:function(p,d){return 12===p&&(p=0),"\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f"===d&&p>=4||"\u0d09\u0d1a\u0d4d\u0d1a \u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e\u0d4d"===d||"\u0d35\u0d48\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d47\u0d30\u0d02"===d?p+12:p},meridiem:function(p,d,e){return p<4?"\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f":p<12?"\u0d30\u0d3e\u0d35\u0d3f\u0d32\u0d46":p<17?"\u0d09\u0d1a\u0d4d\u0d1a \u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e\u0d4d":p<20?"\u0d35\u0d48\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d47\u0d30\u0d02":"\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f"}})}(i(16738))},31062:function(v,T,i){!function(r){"use strict";function u(d,e,_,y){switch(_){case"s":return e?"\u0445\u044d\u0434\u0445\u044d\u043d \u0441\u0435\u043a\u0443\u043d\u0434":"\u0445\u044d\u0434\u0445\u044d\u043d \u0441\u0435\u043a\u0443\u043d\u0434\u044b\u043d";case"ss":return d+(e?" \u0441\u0435\u043a\u0443\u043d\u0434":" \u0441\u0435\u043a\u0443\u043d\u0434\u044b\u043d");case"m":case"mm":return d+(e?" \u043c\u0438\u043d\u0443\u0442":" \u043c\u0438\u043d\u0443\u0442\u044b\u043d");case"h":case"hh":return d+(e?" \u0446\u0430\u0433":" \u0446\u0430\u0433\u0438\u0439\u043d");case"d":case"dd":return d+(e?" \u04e9\u0434\u04e9\u0440":" \u04e9\u0434\u0440\u0438\u0439\u043d");case"M":case"MM":return d+(e?" \u0441\u0430\u0440":" \u0441\u0430\u0440\u044b\u043d");case"y":case"yy":return d+(e?" \u0436\u0438\u043b":" \u0436\u0438\u043b\u0438\u0439\u043d");default:return d}}r.defineLocale("mn",{months:"\u041d\u044d\u0433\u0434\u04af\u0433\u044d\u044d\u0440 \u0441\u0430\u0440_\u0425\u043e\u0451\u0440\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0413\u0443\u0440\u0430\u0432\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0414\u04e9\u0440\u04e9\u0432\u0434\u04af\u0433\u044d\u044d\u0440 \u0441\u0430\u0440_\u0422\u0430\u0432\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0417\u0443\u0440\u0433\u0430\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0414\u043e\u043b\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u041d\u0430\u0439\u043c\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0415\u0441\u0434\u04af\u0433\u044d\u044d\u0440 \u0441\u0430\u0440_\u0410\u0440\u0430\u0432\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0410\u0440\u0432\u0430\u043d \u043d\u044d\u0433\u0434\u04af\u0433\u044d\u044d\u0440 \u0441\u0430\u0440_\u0410\u0440\u0432\u0430\u043d \u0445\u043e\u0451\u0440\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440".split("_"),monthsShort:"1 \u0441\u0430\u0440_2 \u0441\u0430\u0440_3 \u0441\u0430\u0440_4 \u0441\u0430\u0440_5 \u0441\u0430\u0440_6 \u0441\u0430\u0440_7 \u0441\u0430\u0440_8 \u0441\u0430\u0440_9 \u0441\u0430\u0440_10 \u0441\u0430\u0440_11 \u0441\u0430\u0440_12 \u0441\u0430\u0440".split("_"),monthsParseExact:!0,weekdays:"\u041d\u044f\u043c_\u0414\u0430\u0432\u0430\u0430_\u041c\u044f\u0433\u043c\u0430\u0440_\u041b\u0445\u0430\u0433\u0432\u0430_\u041f\u04af\u0440\u044d\u0432_\u0411\u0430\u0430\u0441\u0430\u043d_\u0411\u044f\u043c\u0431\u0430".split("_"),weekdaysShort:"\u041d\u044f\u043c_\u0414\u0430\u0432_\u041c\u044f\u0433_\u041b\u0445\u0430_\u041f\u04af\u0440_\u0411\u0430\u0430_\u0411\u044f\u043c".split("_"),weekdaysMin:"\u041d\u044f_\u0414\u0430_\u041c\u044f_\u041b\u0445_\u041f\u04af_\u0411\u0430_\u0411\u044f".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY \u043e\u043d\u044b MMMM\u044b\u043d D",LLL:"YYYY \u043e\u043d\u044b MMMM\u044b\u043d D HH:mm",LLLL:"dddd, YYYY \u043e\u043d\u044b MMMM\u044b\u043d D HH:mm"},meridiemParse:/\u04ae\u04e8|\u04ae\u0425/i,isPM:function(d){return"\u04ae\u0425"===d},meridiem:function(d,e,_){return d<12?"\u04ae\u04e8":"\u04ae\u0425"},calendar:{sameDay:"[\u04e8\u043d\u04e9\u04e9\u0434\u04e9\u0440] LT",nextDay:"[\u041c\u0430\u0440\u0433\u0430\u0430\u0448] LT",nextWeek:"[\u0418\u0440\u044d\u0445] dddd LT",lastDay:"[\u04e8\u0447\u0438\u0433\u0434\u04e9\u0440] LT",lastWeek:"[\u04e8\u043d\u0433\u04e9\u0440\u0441\u04e9\u043d] dddd LT",sameElse:"L"},relativeTime:{future:"%s \u0434\u0430\u0440\u0430\u0430",past:"%s \u04e9\u043c\u043d\u04e9",s:u,ss:u,m:u,mm:u,h:u,hh:u,d:u,dd:u,M:u,MM:u,y:u,yy:u},dayOfMonthOrdinalParse:/\d{1,2} \u04e9\u0434\u04e9\u0440/,ordinal:function(d,e){switch(e){case"d":case"D":case"DDD":return d+" \u04e9\u0434\u04e9\u0440";default:return d}}})}(i(16738))},92805:function(v,T,i){!function(r){"use strict";var u={1:"\u0967",2:"\u0968",3:"\u0969",4:"\u096a",5:"\u096b",6:"\u096c",7:"\u096d",8:"\u096e",9:"\u096f",0:"\u0966"},p={"\u0967":"1","\u0968":"2","\u0969":"3","\u096a":"4","\u096b":"5","\u096c":"6","\u096d":"7","\u096e":"8","\u096f":"9","\u0966":"0"};function d(_,y,S,A){var N="";if(y)switch(S){case"s":N="\u0915\u093e\u0939\u0940 \u0938\u0947\u0915\u0902\u0926";break;case"ss":N="%d \u0938\u0947\u0915\u0902\u0926";break;case"m":N="\u090f\u0915 \u092e\u093f\u0928\u093f\u091f";break;case"mm":N="%d \u092e\u093f\u0928\u093f\u091f\u0947";break;case"h":N="\u090f\u0915 \u0924\u093e\u0938";break;case"hh":N="%d \u0924\u093e\u0938";break;case"d":N="\u090f\u0915 \u0926\u093f\u0935\u0938";break;case"dd":N="%d \u0926\u093f\u0935\u0938";break;case"M":N="\u090f\u0915 \u092e\u0939\u093f\u0928\u093e";break;case"MM":N="%d \u092e\u0939\u093f\u0928\u0947";break;case"y":N="\u090f\u0915 \u0935\u0930\u094d\u0937";break;case"yy":N="%d \u0935\u0930\u094d\u0937\u0947"}else switch(S){case"s":N="\u0915\u093e\u0939\u0940 \u0938\u0947\u0915\u0902\u0926\u093e\u0902";break;case"ss":N="%d \u0938\u0947\u0915\u0902\u0926\u093e\u0902";break;case"m":N="\u090f\u0915\u093e \u092e\u093f\u0928\u093f\u091f\u093e";break;case"mm":N="%d \u092e\u093f\u0928\u093f\u091f\u093e\u0902";break;case"h":N="\u090f\u0915\u093e \u0924\u093e\u0938\u093e";break;case"hh":N="%d \u0924\u093e\u0938\u093e\u0902";break;case"d":N="\u090f\u0915\u093e \u0926\u093f\u0935\u0938\u093e";break;case"dd":N="%d \u0926\u093f\u0935\u0938\u093e\u0902";break;case"M":N="\u090f\u0915\u093e \u092e\u0939\u093f\u0928\u094d\u092f\u093e";break;case"MM":N="%d \u092e\u0939\u093f\u0928\u094d\u092f\u093e\u0902";break;case"y":N="\u090f\u0915\u093e \u0935\u0930\u094d\u0937\u093e";break;case"yy":N="%d \u0935\u0930\u094d\u0937\u093e\u0902"}return N.replace(/%d/i,_)}r.defineLocale("mr",{months:"\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940_\u092b\u0947\u092c\u094d\u0930\u0941\u0935\u093e\u0930\u0940_\u092e\u093e\u0930\u094d\u091a_\u090f\u092a\u094d\u0930\u093f\u0932_\u092e\u0947_\u091c\u0942\u0928_\u091c\u0941\u0932\u0948_\u0911\u0917\u0938\u094d\u091f_\u0938\u092a\u094d\u091f\u0947\u0902\u092c\u0930_\u0911\u0915\u094d\u091f\u094b\u092c\u0930_\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930_\u0921\u093f\u0938\u0947\u0902\u092c\u0930".split("_"),monthsShort:"\u091c\u093e\u0928\u0947._\u092b\u0947\u092c\u094d\u0930\u0941._\u092e\u093e\u0930\u094d\u091a._\u090f\u092a\u094d\u0930\u093f._\u092e\u0947._\u091c\u0942\u0928._\u091c\u0941\u0932\u0948._\u0911\u0917._\u0938\u092a\u094d\u091f\u0947\u0902._\u0911\u0915\u094d\u091f\u094b._\u0928\u094b\u0935\u094d\u0939\u0947\u0902._\u0921\u093f\u0938\u0947\u0902.".split("_"),monthsParseExact:!0,weekdays:"\u0930\u0935\u093f\u0935\u093e\u0930_\u0938\u094b\u092e\u0935\u093e\u0930_\u092e\u0902\u0917\u0933\u0935\u093e\u0930_\u092c\u0941\u0927\u0935\u093e\u0930_\u0917\u0941\u0930\u0942\u0935\u093e\u0930_\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930_\u0936\u0928\u093f\u0935\u093e\u0930".split("_"),weekdaysShort:"\u0930\u0935\u093f_\u0938\u094b\u092e_\u092e\u0902\u0917\u0933_\u092c\u0941\u0927_\u0917\u0941\u0930\u0942_\u0936\u0941\u0915\u094d\u0930_\u0936\u0928\u093f".split("_"),weekdaysMin:"\u0930_\u0938\u094b_\u092e\u0902_\u092c\u0941_\u0917\u0941_\u0936\u0941_\u0936".split("_"),longDateFormat:{LT:"A h:mm \u0935\u093e\u091c\u0924\u093e",LTS:"A h:mm:ss \u0935\u093e\u091c\u0924\u093e",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u0935\u093e\u091c\u0924\u093e",LLLL:"dddd, D MMMM YYYY, A h:mm \u0935\u093e\u091c\u0924\u093e"},calendar:{sameDay:"[\u0906\u091c] LT",nextDay:"[\u0909\u0926\u094d\u092f\u093e] LT",nextWeek:"dddd, LT",lastDay:"[\u0915\u093e\u0932] LT",lastWeek:"[\u092e\u093e\u0917\u0940\u0932] dddd, LT",sameElse:"L"},relativeTime:{future:"%s\u092e\u0927\u094d\u092f\u0947",past:"%s\u092a\u0942\u0930\u094d\u0935\u0940",s:d,ss:d,m:d,mm:d,h:d,hh:d,d,dd:d,M:d,MM:d,y:d,yy:d},preparse:function(_){return _.replace(/[\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0966]/g,function(y){return p[y]})},postformat:function(_){return _.replace(/\d/g,function(y){return u[y]})},meridiemParse:/\u092a\u0939\u093e\u091f\u0947|\u0938\u0915\u093e\u0933\u0940|\u0926\u0941\u092a\u093e\u0930\u0940|\u0938\u093e\u092f\u0902\u0915\u093e\u0933\u0940|\u0930\u093e\u0924\u094d\u0930\u0940/,meridiemHour:function(_,y){return 12===_&&(_=0),"\u092a\u0939\u093e\u091f\u0947"===y||"\u0938\u0915\u093e\u0933\u0940"===y?_:"\u0926\u0941\u092a\u093e\u0930\u0940"===y||"\u0938\u093e\u092f\u0902\u0915\u093e\u0933\u0940"===y||"\u0930\u093e\u0924\u094d\u0930\u0940"===y?_>=12?_:_+12:void 0},meridiem:function(_,y,S){return _>=0&&_<6?"\u092a\u0939\u093e\u091f\u0947":_<12?"\u0938\u0915\u093e\u0933\u0940":_<17?"\u0926\u0941\u092a\u093e\u0930\u0940":_<20?"\u0938\u093e\u092f\u0902\u0915\u093e\u0933\u0940":"\u0930\u093e\u0924\u094d\u0930\u0940"},week:{dow:0,doy:6}})}(i(16738))},59900:function(v,T,i){!function(r){"use strict";r.defineLocale("ms-my",{months:"Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),weekdays:"Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),weekdaysShort:"Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),weekdaysMin:"Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|tengahari|petang|malam/,meridiemHour:function(p,d){return 12===p&&(p=0),"pagi"===d?p:"tengahari"===d?p>=11?p:p+12:"petang"===d||"malam"===d?p+12:void 0},meridiem:function(p,d,e){return p<11?"pagi":p<15?"tengahari":p<19?"petang":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Esok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kelmarin pukul] LT",lastWeek:"dddd [lepas pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lepas",s:"beberapa saat",ss:"%d saat",m:"seminit",mm:"%d minit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}})}(i(16738))},11341:function(v,T,i){!function(r){"use strict";r.defineLocale("ms",{months:"Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),weekdays:"Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),weekdaysShort:"Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),weekdaysMin:"Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|tengahari|petang|malam/,meridiemHour:function(p,d){return 12===p&&(p=0),"pagi"===d?p:"tengahari"===d?p>=11?p:p+12:"petang"===d||"malam"===d?p+12:void 0},meridiem:function(p,d,e){return p<11?"pagi":p<15?"tengahari":p<19?"petang":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Esok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kelmarin pukul] LT",lastWeek:"dddd [lepas pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lepas",s:"beberapa saat",ss:"%d saat",m:"seminit",mm:"%d minit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}})}(i(16738))},37734:function(v,T,i){!function(r){"use strict";r.defineLocale("mt",{months:"Jannar_Frar_Marzu_April_Mejju_\u0120unju_Lulju_Awwissu_Settembru_Ottubru_Novembru_Di\u010bembru".split("_"),monthsShort:"Jan_Fra_Mar_Apr_Mej_\u0120un_Lul_Aww_Set_Ott_Nov_Di\u010b".split("_"),weekdays:"Il-\u0126add_It-Tnejn_It-Tlieta_L-Erbg\u0127a_Il-\u0126amis_Il-\u0120img\u0127a_Is-Sibt".split("_"),weekdaysShort:"\u0126ad_Tne_Tli_Erb_\u0126am_\u0120im_Sib".split("_"),weekdaysMin:"\u0126a_Tn_Tl_Er_\u0126a_\u0120i_Si".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Illum fil-]LT",nextDay:"[G\u0127ada fil-]LT",nextWeek:"dddd [fil-]LT",lastDay:"[Il-biera\u0127 fil-]LT",lastWeek:"dddd [li g\u0127adda] [fil-]LT",sameElse:"L"},relativeTime:{future:"f\u2019 %s",past:"%s ilu",s:"ftit sekondi",ss:"%d sekondi",m:"minuta",mm:"%d minuti",h:"sieg\u0127a",hh:"%d sieg\u0127at",d:"\u0121urnata",dd:"%d \u0121ranet",M:"xahar",MM:"%d xhur",y:"sena",yy:"%d sni"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}(i(16738))},19034:function(v,T,i){!function(r){"use strict";var u={1:"\u1041",2:"\u1042",3:"\u1043",4:"\u1044",5:"\u1045",6:"\u1046",7:"\u1047",8:"\u1048",9:"\u1049",0:"\u1040"},p={"\u1041":"1","\u1042":"2","\u1043":"3","\u1044":"4","\u1045":"5","\u1046":"6","\u1047":"7","\u1048":"8","\u1049":"9","\u1040":"0"};r.defineLocale("my",{months:"\u1007\u1014\u103a\u1014\u101d\u102b\u101b\u102e_\u1016\u1031\u1016\u1031\u102c\u103a\u101d\u102b\u101b\u102e_\u1019\u1010\u103a_\u1027\u1015\u103c\u102e_\u1019\u1031_\u1007\u103d\u1014\u103a_\u1007\u1030\u101c\u102d\u102f\u1004\u103a_\u101e\u103c\u1002\u102f\u1010\u103a_\u1005\u1000\u103a\u1010\u1004\u103a\u1018\u102c_\u1021\u1031\u102c\u1000\u103a\u1010\u102d\u102f\u1018\u102c_\u1014\u102d\u102f\u101d\u1004\u103a\u1018\u102c_\u1012\u102e\u1007\u1004\u103a\u1018\u102c".split("_"),monthsShort:"\u1007\u1014\u103a_\u1016\u1031_\u1019\u1010\u103a_\u1015\u103c\u102e_\u1019\u1031_\u1007\u103d\u1014\u103a_\u101c\u102d\u102f\u1004\u103a_\u101e\u103c_\u1005\u1000\u103a_\u1021\u1031\u102c\u1000\u103a_\u1014\u102d\u102f_\u1012\u102e".split("_"),weekdays:"\u1010\u1014\u1004\u103a\u1039\u1002\u1014\u103d\u1031_\u1010\u1014\u1004\u103a\u1039\u101c\u102c_\u1021\u1004\u103a\u1039\u1002\u102b_\u1017\u102f\u1012\u1039\u1013\u101f\u1030\u1038_\u1000\u103c\u102c\u101e\u1015\u1010\u1031\u1038_\u101e\u1031\u102c\u1000\u103c\u102c_\u1005\u1014\u1031".split("_"),weekdaysShort:"\u1014\u103d\u1031_\u101c\u102c_\u1002\u102b_\u101f\u1030\u1038_\u1000\u103c\u102c_\u101e\u1031\u102c_\u1014\u1031".split("_"),weekdaysMin:"\u1014\u103d\u1031_\u101c\u102c_\u1002\u102b_\u101f\u1030\u1038_\u1000\u103c\u102c_\u101e\u1031\u102c_\u1014\u1031".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u101a\u1014\u1031.] LT [\u1019\u103e\u102c]",nextDay:"[\u1019\u1014\u1000\u103a\u1016\u103c\u1014\u103a] LT [\u1019\u103e\u102c]",nextWeek:"dddd LT [\u1019\u103e\u102c]",lastDay:"[\u1019\u1014\u1031.\u1000] LT [\u1019\u103e\u102c]",lastWeek:"[\u1015\u103c\u102e\u1038\u1001\u1032\u1037\u101e\u1031\u102c] dddd LT [\u1019\u103e\u102c]",sameElse:"L"},relativeTime:{future:"\u101c\u102c\u1019\u100a\u103a\u1037 %s \u1019\u103e\u102c",past:"\u101c\u103d\u1014\u103a\u1001\u1032\u1037\u101e\u1031\u102c %s \u1000",s:"\u1005\u1000\u1039\u1000\u1014\u103a.\u1021\u1014\u100a\u103a\u1038\u1004\u101a\u103a",ss:"%d \u1005\u1000\u1039\u1000\u1014\u1037\u103a",m:"\u1010\u1005\u103a\u1019\u102d\u1014\u1005\u103a",mm:"%d \u1019\u102d\u1014\u1005\u103a",h:"\u1010\u1005\u103a\u1014\u102c\u101b\u102e",hh:"%d \u1014\u102c\u101b\u102e",d:"\u1010\u1005\u103a\u101b\u1000\u103a",dd:"%d \u101b\u1000\u103a",M:"\u1010\u1005\u103a\u101c",MM:"%d \u101c",y:"\u1010\u1005\u103a\u1014\u103e\u1005\u103a",yy:"%d \u1014\u103e\u1005\u103a"},preparse:function(e){return e.replace(/[\u1041\u1042\u1043\u1044\u1045\u1046\u1047\u1048\u1049\u1040]/g,function(_){return p[_]})},postformat:function(e){return e.replace(/\d/g,function(_){return u[_]})},week:{dow:1,doy:4}})}(i(16738))},9324:function(v,T,i){!function(r){"use strict";r.defineLocale("nb",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan._feb._mars_apr._mai_juni_juli_aug._sep._okt._nov._des.".split("_"),monthsParseExact:!0,weekdays:"s\xf8ndag_mandag_tirsdag_onsdag_torsdag_fredag_l\xf8rdag".split("_"),weekdaysShort:"s\xf8._ma._ti._on._to._fr._l\xf8.".split("_"),weekdaysMin:"s\xf8_ma_ti_on_to_fr_l\xf8".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] HH:mm",LLLL:"dddd D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[i dag kl.] LT",nextDay:"[i morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[i g\xe5r kl.] LT",lastWeek:"[forrige] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"noen sekunder",ss:"%d sekunder",m:"ett minutt",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dager",w:"en uke",ww:"%d uker",M:"en m\xe5ned",MM:"%d m\xe5neder",y:"ett \xe5r",yy:"%d \xe5r"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},46495:function(v,T,i){!function(r){"use strict";var u={1:"\u0967",2:"\u0968",3:"\u0969",4:"\u096a",5:"\u096b",6:"\u096c",7:"\u096d",8:"\u096e",9:"\u096f",0:"\u0966"},p={"\u0967":"1","\u0968":"2","\u0969":"3","\u096a":"4","\u096b":"5","\u096c":"6","\u096d":"7","\u096e":"8","\u096f":"9","\u0966":"0"};r.defineLocale("ne",{months:"\u091c\u0928\u0935\u0930\u0940_\u092b\u0947\u092c\u094d\u0930\u0941\u0935\u0930\u0940_\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u093f\u0932_\u092e\u0908_\u091c\u0941\u0928_\u091c\u0941\u0932\u093e\u0908_\u0905\u0917\u0937\u094d\u091f_\u0938\u0947\u092a\u094d\u091f\u0947\u092e\u094d\u092c\u0930_\u0905\u0915\u094d\u091f\u094b\u092c\u0930_\u0928\u094b\u092d\u0947\u092e\u094d\u092c\u0930_\u0921\u093f\u0938\u0947\u092e\u094d\u092c\u0930".split("_"),monthsShort:"\u091c\u0928._\u092b\u0947\u092c\u094d\u0930\u0941._\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u093f._\u092e\u0908_\u091c\u0941\u0928_\u091c\u0941\u0932\u093e\u0908._\u0905\u0917._\u0938\u0947\u092a\u094d\u091f._\u0905\u0915\u094d\u091f\u094b._\u0928\u094b\u092d\u0947._\u0921\u093f\u0938\u0947.".split("_"),monthsParseExact:!0,weekdays:"\u0906\u0907\u0924\u092c\u093e\u0930_\u0938\u094b\u092e\u092c\u093e\u0930_\u092e\u0919\u094d\u0917\u0932\u092c\u093e\u0930_\u092c\u0941\u0927\u092c\u093e\u0930_\u092c\u093f\u0939\u093f\u092c\u093e\u0930_\u0936\u0941\u0915\u094d\u0930\u092c\u093e\u0930_\u0936\u0928\u093f\u092c\u093e\u0930".split("_"),weekdaysShort:"\u0906\u0907\u0924._\u0938\u094b\u092e._\u092e\u0919\u094d\u0917\u0932._\u092c\u0941\u0927._\u092c\u093f\u0939\u093f._\u0936\u0941\u0915\u094d\u0930._\u0936\u0928\u093f.".split("_"),weekdaysMin:"\u0906._\u0938\u094b._\u092e\u0902._\u092c\u0941._\u092c\u093f._\u0936\u0941._\u0936.".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"A\u0915\u094b h:mm \u092c\u091c\u0947",LTS:"A\u0915\u094b h:mm:ss \u092c\u091c\u0947",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A\u0915\u094b h:mm \u092c\u091c\u0947",LLLL:"dddd, D MMMM YYYY, A\u0915\u094b h:mm \u092c\u091c\u0947"},preparse:function(e){return e.replace(/[\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0966]/g,function(_){return p[_]})},postformat:function(e){return e.replace(/\d/g,function(_){return u[_]})},meridiemParse:/\u0930\u093e\u0924\u093f|\u092c\u093f\u0939\u093e\u0928|\u0926\u093f\u0909\u0901\u0938\u094b|\u0938\u093e\u0901\u091d/,meridiemHour:function(e,_){return 12===e&&(e=0),"\u0930\u093e\u0924\u093f"===_?e<4?e:e+12:"\u092c\u093f\u0939\u093e\u0928"===_?e:"\u0926\u093f\u0909\u0901\u0938\u094b"===_?e>=10?e:e+12:"\u0938\u093e\u0901\u091d"===_?e+12:void 0},meridiem:function(e,_,y){return e<3?"\u0930\u093e\u0924\u093f":e<12?"\u092c\u093f\u0939\u093e\u0928":e<16?"\u0926\u093f\u0909\u0901\u0938\u094b":e<20?"\u0938\u093e\u0901\u091d":"\u0930\u093e\u0924\u093f"},calendar:{sameDay:"[\u0906\u091c] LT",nextDay:"[\u092d\u094b\u0932\u093f] LT",nextWeek:"[\u0906\u0909\u0901\u0926\u094b] dddd[,] LT",lastDay:"[\u0939\u093f\u091c\u094b] LT",lastWeek:"[\u0917\u090f\u0915\u094b] dddd[,] LT",sameElse:"L"},relativeTime:{future:"%s\u092e\u093e",past:"%s \u0905\u0917\u093e\u0921\u093f",s:"\u0915\u0947\u0939\u0940 \u0915\u094d\u0937\u0923",ss:"%d \u0938\u0947\u0915\u0947\u0923\u094d\u0921",m:"\u090f\u0915 \u092e\u093f\u0928\u0947\u091f",mm:"%d \u092e\u093f\u0928\u0947\u091f",h:"\u090f\u0915 \u0918\u0923\u094d\u091f\u093e",hh:"%d \u0918\u0923\u094d\u091f\u093e",d:"\u090f\u0915 \u0926\u093f\u0928",dd:"%d \u0926\u093f\u0928",M:"\u090f\u0915 \u092e\u0939\u093f\u0928\u093e",MM:"%d \u092e\u0939\u093f\u0928\u093e",y:"\u090f\u0915 \u092c\u0930\u094d\u0937",yy:"%d \u092c\u0930\u094d\u0937"},week:{dow:0,doy:6}})}(i(16738))},76272:function(v,T,i){!function(r){"use strict";var u="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),p="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),d=[/^jan/i,/^feb/i,/^maart|mrt.?$/i,/^apr/i,/^mei$/i,/^jun[i.]?$/i,/^jul[i.]?$/i,/^aug/i,/^sep/i,/^okt/i,/^nov/i,/^dec/i],e=/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;r.defineLocale("nl-be",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(y,S){return y?/-MMM-/.test(S)?p[y.month()]:u[y.month()]:u},monthsRegex:e,monthsShortRegex:e,monthsStrictRegex:/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i,monthsShortStrictRegex:/^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,monthsParse:d,longMonthsParse:d,shortMonthsParse:d,weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"zo_ma_di_wo_do_vr_za".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",ss:"%d seconden",m:"\xe9\xe9n minuut",mm:"%d minuten",h:"\xe9\xe9n uur",hh:"%d uur",d:"\xe9\xe9n dag",dd:"%d dagen",M:"\xe9\xe9n maand",MM:"%d maanden",y:"\xe9\xe9n jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(y){return y+(1===y||8===y||y>=20?"ste":"de")},week:{dow:1,doy:4}})}(i(16738))},70673:function(v,T,i){!function(r){"use strict";var u="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),p="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),d=[/^jan/i,/^feb/i,/^maart|mrt.?$/i,/^apr/i,/^mei$/i,/^jun[i.]?$/i,/^jul[i.]?$/i,/^aug/i,/^sep/i,/^okt/i,/^nov/i,/^dec/i],e=/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;r.defineLocale("nl",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(y,S){return y?/-MMM-/.test(S)?p[y.month()]:u[y.month()]:u},monthsRegex:e,monthsShortRegex:e,monthsStrictRegex:/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i,monthsShortStrictRegex:/^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,monthsParse:d,longMonthsParse:d,shortMonthsParse:d,weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"zo_ma_di_wo_do_vr_za".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",ss:"%d seconden",m:"\xe9\xe9n minuut",mm:"%d minuten",h:"\xe9\xe9n uur",hh:"%d uur",d:"\xe9\xe9n dag",dd:"%d dagen",w:"\xe9\xe9n week",ww:"%d weken",M:"\xe9\xe9n maand",MM:"%d maanden",y:"\xe9\xe9n jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(y){return y+(1===y||8===y||y>=20?"ste":"de")},week:{dow:1,doy:4}})}(i(16738))},72486:function(v,T,i){!function(r){"use strict";r.defineLocale("nn",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan._feb._mars_apr._mai_juni_juli_aug._sep._okt._nov._des.".split("_"),monthsParseExact:!0,weekdays:"sundag_m\xe5ndag_tysdag_onsdag_torsdag_fredag_laurdag".split("_"),weekdaysShort:"su._m\xe5._ty._on._to._fr._lau.".split("_"),weekdaysMin:"su_m\xe5_ty_on_to_fr_la".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] H:mm",LLLL:"dddd D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[I dag klokka] LT",nextDay:"[I morgon klokka] LT",nextWeek:"dddd [klokka] LT",lastDay:"[I g\xe5r klokka] LT",lastWeek:"[F\xf8reg\xe5ande] dddd [klokka] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s sidan",s:"nokre sekund",ss:"%d sekund",m:"eit minutt",mm:"%d minutt",h:"ein time",hh:"%d timar",d:"ein dag",dd:"%d dagar",w:"ei veke",ww:"%d veker",M:"ein m\xe5nad",MM:"%d m\xe5nader",y:"eit \xe5r",yy:"%d \xe5r"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},46219:function(v,T,i){!function(r){"use strict";r.defineLocale("oc-lnc",{months:{standalone:"geni\xe8r_febri\xe8r_mar\xe7_abril_mai_junh_julhet_agost_setembre_oct\xf2bre_novembre_decembre".split("_"),format:"de geni\xe8r_de febri\xe8r_de mar\xe7_d'abril_de mai_de junh_de julhet_d'agost_de setembre_d'oct\xf2bre_de novembre_de decembre".split("_"),isFormat:/D[oD]?(\s)+MMMM/},monthsShort:"gen._febr._mar\xe7_abr._mai_junh_julh._ago._set._oct._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"dimenge_diluns_dimars_dim\xe8cres_dij\xf2us_divendres_dissabte".split("_"),weekdaysShort:"dg._dl._dm._dc._dj._dv._ds.".split("_"),weekdaysMin:"dg_dl_dm_dc_dj_dv_ds".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [de] YYYY",ll:"D MMM YYYY",LLL:"D MMMM [de] YYYY [a] H:mm",lll:"D MMM YYYY, H:mm",LLLL:"dddd D MMMM [de] YYYY [a] H:mm",llll:"ddd D MMM YYYY, H:mm"},calendar:{sameDay:"[u\xe8i a] LT",nextDay:"[deman a] LT",nextWeek:"dddd [a] LT",lastDay:"[i\xe8r a] LT",lastWeek:"dddd [passat a] LT",sameElse:"L"},relativeTime:{future:"d'aqu\xed %s",past:"fa %s",s:"unas segondas",ss:"%d segondas",m:"una minuta",mm:"%d minutas",h:"una ora",hh:"%d oras",d:"un jorn",dd:"%d jorns",M:"un mes",MM:"%d meses",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(r|n|t|\xe8|a)/,ordinal:function(p,d){var e=1===p?"r":2===p?"n":3===p?"r":4===p?"t":"\xe8";return("w"===d||"W"===d)&&(e="a"),p+e},week:{dow:1,doy:4}})}(i(16738))},2829:function(v,T,i){!function(r){"use strict";var u={1:"\u0a67",2:"\u0a68",3:"\u0a69",4:"\u0a6a",5:"\u0a6b",6:"\u0a6c",7:"\u0a6d",8:"\u0a6e",9:"\u0a6f",0:"\u0a66"},p={"\u0a67":"1","\u0a68":"2","\u0a69":"3","\u0a6a":"4","\u0a6b":"5","\u0a6c":"6","\u0a6d":"7","\u0a6e":"8","\u0a6f":"9","\u0a66":"0"};r.defineLocale("pa-in",{months:"\u0a1c\u0a28\u0a35\u0a30\u0a40_\u0a2b\u0a3c\u0a30\u0a35\u0a30\u0a40_\u0a2e\u0a3e\u0a30\u0a1a_\u0a05\u0a2a\u0a4d\u0a30\u0a48\u0a32_\u0a2e\u0a08_\u0a1c\u0a42\u0a28_\u0a1c\u0a41\u0a32\u0a3e\u0a08_\u0a05\u0a17\u0a38\u0a24_\u0a38\u0a24\u0a70\u0a2c\u0a30_\u0a05\u0a15\u0a24\u0a42\u0a2c\u0a30_\u0a28\u0a35\u0a70\u0a2c\u0a30_\u0a26\u0a38\u0a70\u0a2c\u0a30".split("_"),monthsShort:"\u0a1c\u0a28\u0a35\u0a30\u0a40_\u0a2b\u0a3c\u0a30\u0a35\u0a30\u0a40_\u0a2e\u0a3e\u0a30\u0a1a_\u0a05\u0a2a\u0a4d\u0a30\u0a48\u0a32_\u0a2e\u0a08_\u0a1c\u0a42\u0a28_\u0a1c\u0a41\u0a32\u0a3e\u0a08_\u0a05\u0a17\u0a38\u0a24_\u0a38\u0a24\u0a70\u0a2c\u0a30_\u0a05\u0a15\u0a24\u0a42\u0a2c\u0a30_\u0a28\u0a35\u0a70\u0a2c\u0a30_\u0a26\u0a38\u0a70\u0a2c\u0a30".split("_"),weekdays:"\u0a10\u0a24\u0a35\u0a3e\u0a30_\u0a38\u0a4b\u0a2e\u0a35\u0a3e\u0a30_\u0a2e\u0a70\u0a17\u0a32\u0a35\u0a3e\u0a30_\u0a2c\u0a41\u0a27\u0a35\u0a3e\u0a30_\u0a35\u0a40\u0a30\u0a35\u0a3e\u0a30_\u0a38\u0a3c\u0a41\u0a71\u0a15\u0a30\u0a35\u0a3e\u0a30_\u0a38\u0a3c\u0a28\u0a40\u0a1a\u0a30\u0a35\u0a3e\u0a30".split("_"),weekdaysShort:"\u0a10\u0a24_\u0a38\u0a4b\u0a2e_\u0a2e\u0a70\u0a17\u0a32_\u0a2c\u0a41\u0a27_\u0a35\u0a40\u0a30_\u0a38\u0a3c\u0a41\u0a15\u0a30_\u0a38\u0a3c\u0a28\u0a40".split("_"),weekdaysMin:"\u0a10\u0a24_\u0a38\u0a4b\u0a2e_\u0a2e\u0a70\u0a17\u0a32_\u0a2c\u0a41\u0a27_\u0a35\u0a40\u0a30_\u0a38\u0a3c\u0a41\u0a15\u0a30_\u0a38\u0a3c\u0a28\u0a40".split("_"),longDateFormat:{LT:"A h:mm \u0a35\u0a1c\u0a47",LTS:"A h:mm:ss \u0a35\u0a1c\u0a47",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u0a35\u0a1c\u0a47",LLLL:"dddd, D MMMM YYYY, A h:mm \u0a35\u0a1c\u0a47"},calendar:{sameDay:"[\u0a05\u0a1c] LT",nextDay:"[\u0a15\u0a32] LT",nextWeek:"[\u0a05\u0a17\u0a32\u0a3e] dddd, LT",lastDay:"[\u0a15\u0a32] LT",lastWeek:"[\u0a2a\u0a3f\u0a1b\u0a32\u0a47] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0a35\u0a3f\u0a71\u0a1a",past:"%s \u0a2a\u0a3f\u0a1b\u0a32\u0a47",s:"\u0a15\u0a41\u0a1d \u0a38\u0a15\u0a3f\u0a70\u0a1f",ss:"%d \u0a38\u0a15\u0a3f\u0a70\u0a1f",m:"\u0a07\u0a15 \u0a2e\u0a3f\u0a70\u0a1f",mm:"%d \u0a2e\u0a3f\u0a70\u0a1f",h:"\u0a07\u0a71\u0a15 \u0a18\u0a70\u0a1f\u0a3e",hh:"%d \u0a18\u0a70\u0a1f\u0a47",d:"\u0a07\u0a71\u0a15 \u0a26\u0a3f\u0a28",dd:"%d \u0a26\u0a3f\u0a28",M:"\u0a07\u0a71\u0a15 \u0a2e\u0a39\u0a40\u0a28\u0a3e",MM:"%d \u0a2e\u0a39\u0a40\u0a28\u0a47",y:"\u0a07\u0a71\u0a15 \u0a38\u0a3e\u0a32",yy:"%d \u0a38\u0a3e\u0a32"},preparse:function(e){return e.replace(/[\u0a67\u0a68\u0a69\u0a6a\u0a6b\u0a6c\u0a6d\u0a6e\u0a6f\u0a66]/g,function(_){return p[_]})},postformat:function(e){return e.replace(/\d/g,function(_){return u[_]})},meridiemParse:/\u0a30\u0a3e\u0a24|\u0a38\u0a35\u0a47\u0a30|\u0a26\u0a41\u0a2a\u0a39\u0a3f\u0a30|\u0a38\u0a3c\u0a3e\u0a2e/,meridiemHour:function(e,_){return 12===e&&(e=0),"\u0a30\u0a3e\u0a24"===_?e<4?e:e+12:"\u0a38\u0a35\u0a47\u0a30"===_?e:"\u0a26\u0a41\u0a2a\u0a39\u0a3f\u0a30"===_?e>=10?e:e+12:"\u0a38\u0a3c\u0a3e\u0a2e"===_?e+12:void 0},meridiem:function(e,_,y){return e<4?"\u0a30\u0a3e\u0a24":e<10?"\u0a38\u0a35\u0a47\u0a30":e<17?"\u0a26\u0a41\u0a2a\u0a39\u0a3f\u0a30":e<20?"\u0a38\u0a3c\u0a3e\u0a2e":"\u0a30\u0a3e\u0a24"},week:{dow:0,doy:6}})}(i(16738))},78444:function(v,T,i){!function(r){"use strict";var u="stycze\u0144_luty_marzec_kwiecie\u0144_maj_czerwiec_lipiec_sierpie\u0144_wrzesie\u0144_pa\u017adziernik_listopad_grudzie\u0144".split("_"),p="stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_wrze\u015bnia_pa\u017adziernika_listopada_grudnia".split("_"),d=[/^sty/i,/^lut/i,/^mar/i,/^kwi/i,/^maj/i,/^cze/i,/^lip/i,/^sie/i,/^wrz/i,/^pa\u017a/i,/^lis/i,/^gru/i];function e(S){return S%10<5&&S%10>1&&~~(S/10)%10!=1}function _(S,A,N){var L=S+" ";switch(N){case"ss":return L+(e(S)?"sekundy":"sekund");case"m":return A?"minuta":"minut\u0119";case"mm":return L+(e(S)?"minuty":"minut");case"h":return A?"godzina":"godzin\u0119";case"hh":return L+(e(S)?"godziny":"godzin");case"ww":return L+(e(S)?"tygodnie":"tygodni");case"MM":return L+(e(S)?"miesi\u0105ce":"miesi\u0119cy");case"yy":return L+(e(S)?"lata":"lat")}}r.defineLocale("pl",{months:function(S,A){return S?/D MMMM/.test(A)?p[S.month()]:u[S.month()]:u},monthsShort:"sty_lut_mar_kwi_maj_cze_lip_sie_wrz_pa\u017a_lis_gru".split("_"),monthsParse:d,longMonthsParse:d,shortMonthsParse:d,weekdays:"niedziela_poniedzia\u0142ek_wtorek_\u015broda_czwartek_pi\u0105tek_sobota".split("_"),weekdaysShort:"ndz_pon_wt_\u015br_czw_pt_sob".split("_"),weekdaysMin:"Nd_Pn_Wt_\u015ar_Cz_Pt_So".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Dzi\u015b o] LT",nextDay:"[Jutro o] LT",nextWeek:function(){switch(this.day()){case 0:return"[W niedziel\u0119 o] LT";case 2:return"[We wtorek o] LT";case 3:return"[W \u015brod\u0119 o] LT";case 6:return"[W sobot\u0119 o] LT";default:return"[W] dddd [o] LT"}},lastDay:"[Wczoraj o] LT",lastWeek:function(){switch(this.day()){case 0:return"[W zesz\u0142\u0105 niedziel\u0119 o] LT";case 3:return"[W zesz\u0142\u0105 \u015brod\u0119 o] LT";case 6:return"[W zesz\u0142\u0105 sobot\u0119 o] LT";default:return"[W zesz\u0142y] dddd [o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"%s temu",s:"kilka sekund",ss:_,m:_,mm:_,h:_,hh:_,d:"1 dzie\u0144",dd:"%d dni",w:"tydzie\u0144",ww:_,M:"miesi\u0105c",MM:_,y:"rok",yy:_},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},66117:function(v,T,i){!function(r){"use strict";r.defineLocale("pt-br",{months:"janeiro_fevereiro_mar\xe7o_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),monthsShort:"jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),weekdays:"domingo_segunda-feira_ter\xe7a-feira_quarta-feira_quinta-feira_sexta-feira_s\xe1bado".split("_"),weekdaysShort:"dom_seg_ter_qua_qui_sex_s\xe1b".split("_"),weekdaysMin:"do_2\xaa_3\xaa_4\xaa_5\xaa_6\xaa_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY [\xe0s] HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY [\xe0s] HH:mm"},calendar:{sameDay:"[Hoje \xe0s] LT",nextDay:"[Amanh\xe3 \xe0s] LT",nextWeek:"dddd [\xe0s] LT",lastDay:"[Ontem \xe0s] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[\xdaltimo] dddd [\xe0s] LT":"[\xdaltima] dddd [\xe0s] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"h\xe1 %s",s:"poucos segundos",ss:"%d segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um m\xeas",MM:"%d meses",y:"um ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",invalidDate:"Data inv\xe1lida"})}(i(16738))},53170:function(v,T,i){!function(r){"use strict";r.defineLocale("pt",{months:"janeiro_fevereiro_mar\xe7o_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),monthsShort:"jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),weekdays:"Domingo_Segunda-feira_Ter\xe7a-feira_Quarta-feira_Quinta-feira_Sexta-feira_S\xe1bado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_S\xe1b".split("_"),weekdaysMin:"Do_2\xaa_3\xaa_4\xaa_5\xaa_6\xaa_S\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY HH:mm"},calendar:{sameDay:"[Hoje \xe0s] LT",nextDay:"[Amanh\xe3 \xe0s] LT",nextWeek:"dddd [\xe0s] LT",lastDay:"[Ontem \xe0s] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[\xdaltimo] dddd [\xe0s] LT":"[\xdaltima] dddd [\xe0s] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"h\xe1 %s",s:"segundos",ss:"%d segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",w:"uma semana",ww:"%d semanas",M:"um m\xeas",MM:"%d meses",y:"um ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}(i(16738))},96587:function(v,T,i){!function(r){"use strict";function u(d,e,_){var S=" ";return(d%100>=20||d>=100&&d%100==0)&&(S=" de "),d+S+{ss:"secunde",mm:"minute",hh:"ore",dd:"zile",ww:"s\u0103pt\u0103m\xe2ni",MM:"luni",yy:"ani"}[_]}r.defineLocale("ro",{months:"ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie".split("_"),monthsShort:"ian._feb._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"duminic\u0103_luni_mar\u021bi_miercuri_joi_vineri_s\xe2mb\u0103t\u0103".split("_"),weekdaysShort:"Dum_Lun_Mar_Mie_Joi_Vin_S\xe2m".split("_"),weekdaysMin:"Du_Lu_Ma_Mi_Jo_Vi_S\xe2".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[azi la] LT",nextDay:"[m\xe2ine la] LT",nextWeek:"dddd [la] LT",lastDay:"[ieri la] LT",lastWeek:"[fosta] dddd [la] LT",sameElse:"L"},relativeTime:{future:"peste %s",past:"%s \xeen urm\u0103",s:"c\xe2teva secunde",ss:u,m:"un minut",mm:u,h:"o or\u0103",hh:u,d:"o zi",dd:u,w:"o s\u0103pt\u0103m\xe2n\u0103",ww:u,M:"o lun\u0103",MM:u,y:"un an",yy:u},week:{dow:1,doy:7}})}(i(16738))},39264:function(v,T,i){!function(r){"use strict";function p(_,y,S){return"m"===S?y?"\u043c\u0438\u043d\u0443\u0442\u0430":"\u043c\u0438\u043d\u0443\u0442\u0443":_+" "+function(_,y){var S=_.split("_");return y%10==1&&y%100!=11?S[0]:y%10>=2&&y%10<=4&&(y%100<10||y%100>=20)?S[1]:S[2]}({ss:y?"\u0441\u0435\u043a\u0443\u043d\u0434\u0430_\u0441\u0435\u043a\u0443\u043d\u0434\u044b_\u0441\u0435\u043a\u0443\u043d\u0434":"\u0441\u0435\u043a\u0443\u043d\u0434\u0443_\u0441\u0435\u043a\u0443\u043d\u0434\u044b_\u0441\u0435\u043a\u0443\u043d\u0434",mm:y?"\u043c\u0438\u043d\u0443\u0442\u0430_\u043c\u0438\u043d\u0443\u0442\u044b_\u043c\u0438\u043d\u0443\u0442":"\u043c\u0438\u043d\u0443\u0442\u0443_\u043c\u0438\u043d\u0443\u0442\u044b_\u043c\u0438\u043d\u0443\u0442",hh:"\u0447\u0430\u0441_\u0447\u0430\u0441\u0430_\u0447\u0430\u0441\u043e\u0432",dd:"\u0434\u0435\u043d\u044c_\u0434\u043d\u044f_\u0434\u043d\u0435\u0439",ww:"\u043d\u0435\u0434\u0435\u043b\u044f_\u043d\u0435\u0434\u0435\u043b\u0438_\u043d\u0435\u0434\u0435\u043b\u044c",MM:"\u043c\u0435\u0441\u044f\u0446_\u043c\u0435\u0441\u044f\u0446\u0430_\u043c\u0435\u0441\u044f\u0446\u0435\u0432",yy:"\u0433\u043e\u0434_\u0433\u043e\u0434\u0430_\u043b\u0435\u0442"}[S],+_)}var d=[/^\u044f\u043d\u0432/i,/^\u0444\u0435\u0432/i,/^\u043c\u0430\u0440/i,/^\u0430\u043f\u0440/i,/^\u043c\u0430[\u0439\u044f]/i,/^\u0438\u044e\u043d/i,/^\u0438\u044e\u043b/i,/^\u0430\u0432\u0433/i,/^\u0441\u0435\u043d/i,/^\u043e\u043a\u0442/i,/^\u043d\u043e\u044f/i,/^\u0434\u0435\u043a/i];r.defineLocale("ru",{months:{format:"\u044f\u043d\u0432\u0430\u0440\u044f_\u0444\u0435\u0432\u0440\u0430\u043b\u044f_\u043c\u0430\u0440\u0442\u0430_\u0430\u043f\u0440\u0435\u043b\u044f_\u043c\u0430\u044f_\u0438\u044e\u043d\u044f_\u0438\u044e\u043b\u044f_\u0430\u0432\u0433\u0443\u0441\u0442\u0430_\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044f_\u043e\u043a\u0442\u044f\u0431\u0440\u044f_\u043d\u043e\u044f\u0431\u0440\u044f_\u0434\u0435\u043a\u0430\u0431\u0440\u044f".split("_"),standalone:"\u044f\u043d\u0432\u0430\u0440\u044c_\u0444\u0435\u0432\u0440\u0430\u043b\u044c_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0435\u043b\u044c_\u043c\u0430\u0439_\u0438\u044e\u043d\u044c_\u0438\u044e\u043b\u044c_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c_\u043e\u043a\u0442\u044f\u0431\u0440\u044c_\u043d\u043e\u044f\u0431\u0440\u044c_\u0434\u0435\u043a\u0430\u0431\u0440\u044c".split("_")},monthsShort:{format:"\u044f\u043d\u0432._\u0444\u0435\u0432\u0440._\u043c\u0430\u0440._\u0430\u043f\u0440._\u043c\u0430\u044f_\u0438\u044e\u043d\u044f_\u0438\u044e\u043b\u044f_\u0430\u0432\u0433._\u0441\u0435\u043d\u0442._\u043e\u043a\u0442._\u043d\u043e\u044f\u0431._\u0434\u0435\u043a.".split("_"),standalone:"\u044f\u043d\u0432._\u0444\u0435\u0432\u0440._\u043c\u0430\u0440\u0442_\u0430\u043f\u0440._\u043c\u0430\u0439_\u0438\u044e\u043d\u044c_\u0438\u044e\u043b\u044c_\u0430\u0432\u0433._\u0441\u0435\u043d\u0442._\u043e\u043a\u0442._\u043d\u043e\u044f\u0431._\u0434\u0435\u043a.".split("_")},weekdays:{standalone:"\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u0435\u0434\u0430_\u0447\u0435\u0442\u0432\u0435\u0440\u0433_\u043f\u044f\u0442\u043d\u0438\u0446\u0430_\u0441\u0443\u0431\u0431\u043e\u0442\u0430".split("_"),format:"\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u0435\u0434\u0443_\u0447\u0435\u0442\u0432\u0435\u0440\u0433_\u043f\u044f\u0442\u043d\u0438\u0446\u0443_\u0441\u0443\u0431\u0431\u043e\u0442\u0443".split("_"),isFormat:/\[ ?[\u0412\u0432] ?(?:\u043f\u0440\u043e\u0448\u043b\u0443\u044e|\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e|\u044d\u0442\u0443)? ?] ?dddd/},weekdaysShort:"\u0432\u0441_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),weekdaysMin:"\u0432\u0441_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),monthsParse:d,longMonthsParse:d,shortMonthsParse:d,monthsRegex:/^(\u044f\u043d\u0432\u0430\u0440[\u044c\u044f]|\u044f\u043d\u0432\.?|\u0444\u0435\u0432\u0440\u0430\u043b[\u044c\u044f]|\u0444\u0435\u0432\u0440?\.?|\u043c\u0430\u0440\u0442\u0430?|\u043c\u0430\u0440\.?|\u0430\u043f\u0440\u0435\u043b[\u044c\u044f]|\u0430\u043f\u0440\.?|\u043c\u0430[\u0439\u044f]|\u0438\u044e\u043d[\u044c\u044f]|\u0438\u044e\u043d\.?|\u0438\u044e\u043b[\u044c\u044f]|\u0438\u044e\u043b\.?|\u0430\u0432\u0433\u0443\u0441\u0442\u0430?|\u0430\u0432\u0433\.?|\u0441\u0435\u043d\u0442\u044f\u0431\u0440[\u044c\u044f]|\u0441\u0435\u043d\u0442?\.?|\u043e\u043a\u0442\u044f\u0431\u0440[\u044c\u044f]|\u043e\u043a\u0442\.?|\u043d\u043e\u044f\u0431\u0440[\u044c\u044f]|\u043d\u043e\u044f\u0431?\.?|\u0434\u0435\u043a\u0430\u0431\u0440[\u044c\u044f]|\u0434\u0435\u043a\.?)/i,monthsShortRegex:/^(\u044f\u043d\u0432\u0430\u0440[\u044c\u044f]|\u044f\u043d\u0432\.?|\u0444\u0435\u0432\u0440\u0430\u043b[\u044c\u044f]|\u0444\u0435\u0432\u0440?\.?|\u043c\u0430\u0440\u0442\u0430?|\u043c\u0430\u0440\.?|\u0430\u043f\u0440\u0435\u043b[\u044c\u044f]|\u0430\u043f\u0440\.?|\u043c\u0430[\u0439\u044f]|\u0438\u044e\u043d[\u044c\u044f]|\u0438\u044e\u043d\.?|\u0438\u044e\u043b[\u044c\u044f]|\u0438\u044e\u043b\.?|\u0430\u0432\u0433\u0443\u0441\u0442\u0430?|\u0430\u0432\u0433\.?|\u0441\u0435\u043d\u0442\u044f\u0431\u0440[\u044c\u044f]|\u0441\u0435\u043d\u0442?\.?|\u043e\u043a\u0442\u044f\u0431\u0440[\u044c\u044f]|\u043e\u043a\u0442\.?|\u043d\u043e\u044f\u0431\u0440[\u044c\u044f]|\u043d\u043e\u044f\u0431?\.?|\u0434\u0435\u043a\u0430\u0431\u0440[\u044c\u044f]|\u0434\u0435\u043a\.?)/i,monthsStrictRegex:/^(\u044f\u043d\u0432\u0430\u0440[\u044f\u044c]|\u0444\u0435\u0432\u0440\u0430\u043b[\u044f\u044c]|\u043c\u0430\u0440\u0442\u0430?|\u0430\u043f\u0440\u0435\u043b[\u044f\u044c]|\u043c\u0430[\u044f\u0439]|\u0438\u044e\u043d[\u044f\u044c]|\u0438\u044e\u043b[\u044f\u044c]|\u0430\u0432\u0433\u0443\u0441\u0442\u0430?|\u0441\u0435\u043d\u0442\u044f\u0431\u0440[\u044f\u044c]|\u043e\u043a\u0442\u044f\u0431\u0440[\u044f\u044c]|\u043d\u043e\u044f\u0431\u0440[\u044f\u044c]|\u0434\u0435\u043a\u0430\u0431\u0440[\u044f\u044c])/i,monthsShortStrictRegex:/^(\u044f\u043d\u0432\.|\u0444\u0435\u0432\u0440?\.|\u043c\u0430\u0440[\u0442.]|\u0430\u043f\u0440\.|\u043c\u0430[\u044f\u0439]|\u0438\u044e\u043d[\u044c\u044f.]|\u0438\u044e\u043b[\u044c\u044f.]|\u0430\u0432\u0433\.|\u0441\u0435\u043d\u0442?\.|\u043e\u043a\u0442\.|\u043d\u043e\u044f\u0431?\.|\u0434\u0435\u043a\.)/i,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY \u0433.",LLL:"D MMMM YYYY \u0433., H:mm",LLLL:"dddd, D MMMM YYYY \u0433., H:mm"},calendar:{sameDay:"[\u0421\u0435\u0433\u043e\u0434\u043d\u044f, \u0432] LT",nextDay:"[\u0417\u0430\u0432\u0442\u0440\u0430, \u0432] LT",lastDay:"[\u0412\u0447\u0435\u0440\u0430, \u0432] LT",nextWeek:function(_){if(_.week()===this.week())return 2===this.day()?"[\u0412\u043e] dddd, [\u0432] LT":"[\u0412] dddd, [\u0432] LT";switch(this.day()){case 0:return"[\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435] dddd, [\u0432] LT";case 1:case 2:case 4:return"[\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439] dddd, [\u0432] LT";case 3:case 5:case 6:return"[\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e] dddd, [\u0432] LT"}},lastWeek:function(_){if(_.week()===this.week())return 2===this.day()?"[\u0412\u043e] dddd, [\u0432] LT":"[\u0412] dddd, [\u0432] LT";switch(this.day()){case 0:return"[\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0435] dddd, [\u0432] LT";case 1:case 2:case 4:return"[\u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0439] dddd, [\u0432] LT";case 3:case 5:case 6:return"[\u0412 \u043f\u0440\u043e\u0448\u043b\u0443\u044e] dddd, [\u0432] LT"}},sameElse:"L"},relativeTime:{future:"\u0447\u0435\u0440\u0435\u0437 %s",past:"%s \u043d\u0430\u0437\u0430\u0434",s:"\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434",ss:p,m:p,mm:p,h:"\u0447\u0430\u0441",hh:p,d:"\u0434\u0435\u043d\u044c",dd:p,w:"\u043d\u0435\u0434\u0435\u043b\u044f",ww:p,M:"\u043c\u0435\u0441\u044f\u0446",MM:p,y:"\u0433\u043e\u0434",yy:p},meridiemParse:/\u043d\u043e\u0447\u0438|\u0443\u0442\u0440\u0430|\u0434\u043d\u044f|\u0432\u0435\u0447\u0435\u0440\u0430/i,isPM:function(_){return/^(\u0434\u043d\u044f|\u0432\u0435\u0447\u0435\u0440\u0430)$/.test(_)},meridiem:function(_,y,S){return _<4?"\u043d\u043e\u0447\u0438":_<12?"\u0443\u0442\u0440\u0430":_<17?"\u0434\u043d\u044f":"\u0432\u0435\u0447\u0435\u0440\u0430"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0439|\u0433\u043e|\u044f)/,ordinal:function(_,y){switch(y){case"M":case"d":case"DDD":return _+"-\u0439";case"D":return _+"-\u0433\u043e";case"w":case"W":return _+"-\u044f";default:return _}},week:{dow:1,doy:4}})}(i(16738))},42135:function(v,T,i){!function(r){"use strict";var u=["\u062c\u0646\u0648\u0631\u064a","\u0641\u064a\u0628\u0631\u0648\u0631\u064a","\u0645\u0627\u0631\u0686","\u0627\u067e\u0631\u064a\u0644","\u0645\u0626\u064a","\u062c\u0648\u0646","\u062c\u0648\u0644\u0627\u0621\u0650","\u0622\u06af\u0633\u067d","\u0633\u064a\u067e\u067d\u0645\u0628\u0631","\u0622\u06aa\u067d\u0648\u0628\u0631","\u0646\u0648\u0645\u0628\u0631","\u068a\u0633\u0645\u0628\u0631"],p=["\u0622\u0686\u0631","\u0633\u0648\u0645\u0631","\u0627\u06b1\u0627\u0631\u0648","\u0627\u0631\u0628\u0639","\u062e\u0645\u064a\u0633","\u062c\u0645\u0639","\u0687\u0646\u0687\u0631"];r.defineLocale("sd",{months:u,monthsShort:u,weekdays:p,weekdaysShort:p,weekdaysMin:p,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd\u060c D MMMM YYYY HH:mm"},meridiemParse:/\u0635\u0628\u062d|\u0634\u0627\u0645/,isPM:function(e){return"\u0634\u0627\u0645"===e},meridiem:function(e,_,y){return e<12?"\u0635\u0628\u062d":"\u0634\u0627\u0645"},calendar:{sameDay:"[\u0627\u0684] LT",nextDay:"[\u0633\u0680\u0627\u06bb\u064a] LT",nextWeek:"dddd [\u0627\u06b3\u064a\u0646 \u0647\u0641\u062a\u064a \u062a\u064a] LT",lastDay:"[\u06aa\u0627\u0644\u0647\u0647] LT",lastWeek:"[\u06af\u0632\u0631\u064a\u0644 \u0647\u0641\u062a\u064a] dddd [\u062a\u064a] LT",sameElse:"L"},relativeTime:{future:"%s \u067e\u0648\u0621",past:"%s \u0627\u06b3",s:"\u0686\u0646\u062f \u0633\u064a\u06aa\u0646\u068a",ss:"%d \u0633\u064a\u06aa\u0646\u068a",m:"\u0647\u06aa \u0645\u0646\u067d",mm:"%d \u0645\u0646\u067d",h:"\u0647\u06aa \u06aa\u0644\u0627\u06aa",hh:"%d \u06aa\u0644\u0627\u06aa",d:"\u0647\u06aa \u068f\u064a\u0646\u0647\u0646",dd:"%d \u068f\u064a\u0646\u0647\u0646",M:"\u0647\u06aa \u0645\u0647\u064a\u0646\u0648",MM:"%d \u0645\u0647\u064a\u0646\u0627",y:"\u0647\u06aa \u0633\u0627\u0644",yy:"%d \u0633\u0627\u0644"},preparse:function(e){return e.replace(/\u060c/g,",")},postformat:function(e){return e.replace(/,/g,"\u060c")},week:{dow:1,doy:4}})}(i(16738))},95366:function(v,T,i){!function(r){"use strict";r.defineLocale("se",{months:"o\u0111\u0111ajagem\xe1nnu_guovvam\xe1nnu_njuk\u010dam\xe1nnu_cuo\u014bom\xe1nnu_miessem\xe1nnu_geassem\xe1nnu_suoidnem\xe1nnu_borgem\xe1nnu_\u010dak\u010dam\xe1nnu_golggotm\xe1nnu_sk\xe1bmam\xe1nnu_juovlam\xe1nnu".split("_"),monthsShort:"o\u0111\u0111j_guov_njuk_cuo_mies_geas_suoi_borg_\u010dak\u010d_golg_sk\xe1b_juov".split("_"),weekdays:"sotnabeaivi_vuoss\xe1rga_ma\u014b\u014beb\xe1rga_gaskavahkku_duorastat_bearjadat_l\xe1vvardat".split("_"),weekdaysShort:"sotn_vuos_ma\u014b_gask_duor_bear_l\xe1v".split("_"),weekdaysMin:"s_v_m_g_d_b_L".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"MMMM D. [b.] YYYY",LLL:"MMMM D. [b.] YYYY [ti.] HH:mm",LLLL:"dddd, MMMM D. [b.] YYYY [ti.] HH:mm"},calendar:{sameDay:"[otne ti] LT",nextDay:"[ihttin ti] LT",nextWeek:"dddd [ti] LT",lastDay:"[ikte ti] LT",lastWeek:"[ovddit] dddd [ti] LT",sameElse:"L"},relativeTime:{future:"%s gea\u017ees",past:"ma\u014bit %s",s:"moadde sekunddat",ss:"%d sekunddat",m:"okta minuhta",mm:"%d minuhtat",h:"okta diimmu",hh:"%d diimmut",d:"okta beaivi",dd:"%d beaivvit",M:"okta m\xe1nnu",MM:"%d m\xe1nut",y:"okta jahki",yy:"%d jagit"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},93379:function(v,T,i){!function(r){"use strict";r.defineLocale("si",{months:"\u0da2\u0db1\u0dc0\u0dcf\u0dbb\u0dd2_\u0db4\u0dd9\u0db6\u0dbb\u0dc0\u0dcf\u0dbb\u0dd2_\u0db8\u0dcf\u0dbb\u0dca\u0dad\u0dd4_\u0d85\u0db4\u0dca\u200d\u0dbb\u0dda\u0dbd\u0dca_\u0db8\u0dd0\u0dba\u0dd2_\u0da2\u0dd6\u0db1\u0dd2_\u0da2\u0dd6\u0dbd\u0dd2_\u0d85\u0d9c\u0ddd\u0dc3\u0dca\u0dad\u0dd4_\u0dc3\u0dd0\u0db4\u0dca\u0dad\u0dd0\u0db8\u0dca\u0db6\u0dbb\u0dca_\u0d94\u0d9a\u0dca\u0dad\u0ddd\u0db6\u0dbb\u0dca_\u0db1\u0ddc\u0dc0\u0dd0\u0db8\u0dca\u0db6\u0dbb\u0dca_\u0daf\u0dd9\u0dc3\u0dd0\u0db8\u0dca\u0db6\u0dbb\u0dca".split("_"),monthsShort:"\u0da2\u0db1_\u0db4\u0dd9\u0db6_\u0db8\u0dcf\u0dbb\u0dca_\u0d85\u0db4\u0dca_\u0db8\u0dd0\u0dba\u0dd2_\u0da2\u0dd6\u0db1\u0dd2_\u0da2\u0dd6\u0dbd\u0dd2_\u0d85\u0d9c\u0ddd_\u0dc3\u0dd0\u0db4\u0dca_\u0d94\u0d9a\u0dca_\u0db1\u0ddc\u0dc0\u0dd0_\u0daf\u0dd9\u0dc3\u0dd0".split("_"),weekdays:"\u0d89\u0dbb\u0dd2\u0daf\u0dcf_\u0dc3\u0db3\u0dd4\u0daf\u0dcf_\u0d85\u0d9f\u0dc4\u0dbb\u0dd4\u0dc0\u0dcf\u0daf\u0dcf_\u0db6\u0daf\u0dcf\u0daf\u0dcf_\u0db6\u0dca\u200d\u0dbb\u0dc4\u0dc3\u0dca\u0db4\u0dad\u0dd2\u0db1\u0dca\u0daf\u0dcf_\u0dc3\u0dd2\u0d9a\u0dd4\u0dbb\u0dcf\u0daf\u0dcf_\u0dc3\u0dd9\u0db1\u0dc3\u0dd4\u0dbb\u0dcf\u0daf\u0dcf".split("_"),weekdaysShort:"\u0d89\u0dbb\u0dd2_\u0dc3\u0db3\u0dd4_\u0d85\u0d9f_\u0db6\u0daf\u0dcf_\u0db6\u0dca\u200d\u0dbb\u0dc4_\u0dc3\u0dd2\u0d9a\u0dd4_\u0dc3\u0dd9\u0db1".split("_"),weekdaysMin:"\u0d89_\u0dc3_\u0d85_\u0db6_\u0db6\u0dca\u200d\u0dbb_\u0dc3\u0dd2_\u0dc3\u0dd9".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"a h:mm",LTS:"a h:mm:ss",L:"YYYY/MM/DD",LL:"YYYY MMMM D",LLL:"YYYY MMMM D, a h:mm",LLLL:"YYYY MMMM D [\u0dc0\u0dd0\u0db1\u0dd2] dddd, a h:mm:ss"},calendar:{sameDay:"[\u0d85\u0daf] LT[\u0da7]",nextDay:"[\u0dc4\u0dd9\u0da7] LT[\u0da7]",nextWeek:"dddd LT[\u0da7]",lastDay:"[\u0d8a\u0dba\u0dda] LT[\u0da7]",lastWeek:"[\u0db4\u0dc3\u0dd4\u0d9c\u0dd2\u0dba] dddd LT[\u0da7]",sameElse:"L"},relativeTime:{future:"%s\u0d9a\u0dd2\u0db1\u0dca",past:"%s\u0d9a\u0da7 \u0db4\u0dd9\u0dbb",s:"\u0dad\u0dad\u0dca\u0db4\u0dbb \u0d9a\u0dd2\u0dc4\u0dd2\u0db4\u0dba",ss:"\u0dad\u0dad\u0dca\u0db4\u0dbb %d",m:"\u0db8\u0dd2\u0db1\u0dd2\u0dad\u0dca\u0dad\u0dd4\u0dc0",mm:"\u0db8\u0dd2\u0db1\u0dd2\u0dad\u0dca\u0dad\u0dd4 %d",h:"\u0db4\u0dd0\u0dba",hh:"\u0db4\u0dd0\u0dba %d",d:"\u0daf\u0dd2\u0db1\u0dba",dd:"\u0daf\u0dd2\u0db1 %d",M:"\u0db8\u0dcf\u0dc3\u0dba",MM:"\u0db8\u0dcf\u0dc3 %d",y:"\u0dc0\u0dc3\u0dbb",yy:"\u0dc0\u0dc3\u0dbb %d"},dayOfMonthOrdinalParse:/\d{1,2} \u0dc0\u0dd0\u0db1\u0dd2/,ordinal:function(p){return p+" \u0dc0\u0dd0\u0db1\u0dd2"},meridiemParse:/\u0db4\u0dd9\u0dbb \u0dc0\u0dbb\u0dd4|\u0db4\u0dc3\u0dca \u0dc0\u0dbb\u0dd4|\u0db4\u0dd9.\u0dc0|\u0db4.\u0dc0./,isPM:function(p){return"\u0db4.\u0dc0."===p||"\u0db4\u0dc3\u0dca \u0dc0\u0dbb\u0dd4"===p},meridiem:function(p,d,e){return p>11?e?"\u0db4.\u0dc0.":"\u0db4\u0dc3\u0dca \u0dc0\u0dbb\u0dd4":e?"\u0db4\u0dd9.\u0dc0.":"\u0db4\u0dd9\u0dbb \u0dc0\u0dbb\u0dd4"}})}(i(16738))},46143:function(v,T,i){!function(r){"use strict";var u="janu\xe1r_febru\xe1r_marec_apr\xedl_m\xe1j_j\xfan_j\xfal_august_september_okt\xf3ber_november_december".split("_"),p="jan_feb_mar_apr_m\xe1j_j\xfan_j\xfal_aug_sep_okt_nov_dec".split("_");function d(y){return y>1&&y<5}function e(y,S,A,N){var L=y+" ";switch(A){case"s":return S||N?"p\xe1r sek\xfand":"p\xe1r sekundami";case"ss":return S||N?L+(d(y)?"sekundy":"sek\xfand"):L+"sekundami";case"m":return S?"min\xfata":N?"min\xfatu":"min\xfatou";case"mm":return S||N?L+(d(y)?"min\xfaty":"min\xfat"):L+"min\xfatami";case"h":return S?"hodina":N?"hodinu":"hodinou";case"hh":return S||N?L+(d(y)?"hodiny":"hod\xedn"):L+"hodinami";case"d":return S||N?"de\u0148":"d\u0148om";case"dd":return S||N?L+(d(y)?"dni":"dn\xed"):L+"d\u0148ami";case"M":return S||N?"mesiac":"mesiacom";case"MM":return S||N?L+(d(y)?"mesiace":"mesiacov"):L+"mesiacmi";case"y":return S||N?"rok":"rokom";case"yy":return S||N?L+(d(y)?"roky":"rokov"):L+"rokmi"}}r.defineLocale("sk",{months:u,monthsShort:p,weekdays:"nede\u013ea_pondelok_utorok_streda_\u0161tvrtok_piatok_sobota".split("_"),weekdaysShort:"ne_po_ut_st_\u0161t_pi_so".split("_"),weekdaysMin:"ne_po_ut_st_\u0161t_pi_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm"},calendar:{sameDay:"[dnes o] LT",nextDay:"[zajtra o] LT",nextWeek:function(){switch(this.day()){case 0:return"[v nede\u013eu o] LT";case 1:case 2:return"[v] dddd [o] LT";case 3:return"[v stredu o] LT";case 4:return"[vo \u0161tvrtok o] LT";case 5:return"[v piatok o] LT";case 6:return"[v sobotu o] LT"}},lastDay:"[v\u010dera o] LT",lastWeek:function(){switch(this.day()){case 0:return"[minul\xfa nede\u013eu o] LT";case 1:case 2:return"[minul\xfd] dddd [o] LT";case 3:return"[minul\xfa stredu o] LT";case 4:case 5:return"[minul\xfd] dddd [o] LT";case 6:return"[minul\xfa sobotu o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"pred %s",s:e,ss:e,m:e,mm:e,h:e,hh:e,d:e,dd:e,M:e,MM:e,y:e,yy:e},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},196:function(v,T,i){!function(r){"use strict";function u(d,e,_,y){var S=d+" ";switch(_){case"s":return e||y?"nekaj sekund":"nekaj sekundami";case"ss":return S+(1===d?e?"sekundo":"sekundi":2===d?e||y?"sekundi":"sekundah":d<5?e||y?"sekunde":"sekundah":"sekund");case"m":return e?"ena minuta":"eno minuto";case"mm":return S+(1===d?e?"minuta":"minuto":2===d?e||y?"minuti":"minutama":d<5?e||y?"minute":"minutami":e||y?"minut":"minutami");case"h":return e?"ena ura":"eno uro";case"hh":return S+(1===d?e?"ura":"uro":2===d?e||y?"uri":"urama":d<5?e||y?"ure":"urami":e||y?"ur":"urami");case"d":return e||y?"en dan":"enim dnem";case"dd":return S+(1===d?e||y?"dan":"dnem":2===d?e||y?"dni":"dnevoma":e||y?"dni":"dnevi");case"M":return e||y?"en mesec":"enim mesecem";case"MM":return S+(1===d?e||y?"mesec":"mesecem":2===d?e||y?"meseca":"mesecema":d<5?e||y?"mesece":"meseci":e||y?"mesecev":"meseci");case"y":return e||y?"eno leto":"enim letom";case"yy":return S+(1===d?e||y?"leto":"letom":2===d?e||y?"leti":"letoma":d<5?e||y?"leta":"leti":e||y?"let":"leti")}}r.defineLocale("sl",{months:"januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedelja_ponedeljek_torek_sreda_\u010detrtek_petek_sobota".split("_"),weekdaysShort:"ned._pon._tor._sre._\u010det._pet._sob.".split("_"),weekdaysMin:"ne_po_to_sr_\u010de_pe_so".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danes ob] LT",nextDay:"[jutri ob] LT",nextWeek:function(){switch(this.day()){case 0:return"[v] [nedeljo] [ob] LT";case 3:return"[v] [sredo] [ob] LT";case 6:return"[v] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[v] dddd [ob] LT"}},lastDay:"[v\u010deraj ob] LT",lastWeek:function(){switch(this.day()){case 0:return"[prej\u0161njo] [nedeljo] [ob] LT";case 3:return"[prej\u0161njo] [sredo] [ob] LT";case 6:return"[prej\u0161njo] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[prej\u0161nji] dddd [ob] LT"}},sameElse:"L"},relativeTime:{future:"\u010dez %s",past:"pred %s",s:u,ss:u,m:u,mm:u,h:u,hh:u,d:u,dd:u,M:u,MM:u,y:u,yy:u},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(i(16738))},21082:function(v,T,i){!function(r){"use strict";r.defineLocale("sq",{months:"Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_N\xebntor_Dhjetor".split("_"),monthsShort:"Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_N\xebn_Dhj".split("_"),weekdays:"E Diel_E H\xebn\xeb_E Mart\xeb_E M\xebrkur\xeb_E Enjte_E Premte_E Shtun\xeb".split("_"),weekdaysShort:"Die_H\xebn_Mar_M\xebr_Enj_Pre_Sht".split("_"),weekdaysMin:"D_H_Ma_M\xeb_E_P_Sh".split("_"),weekdaysParseExact:!0,meridiemParse:/PD|MD/,isPM:function(p){return"M"===p.charAt(0)},meridiem:function(p,d,e){return p<12?"PD":"MD"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Sot n\xeb] LT",nextDay:"[Nes\xebr n\xeb] LT",nextWeek:"dddd [n\xeb] LT",lastDay:"[Dje n\xeb] LT",lastWeek:"dddd [e kaluar n\xeb] LT",sameElse:"L"},relativeTime:{future:"n\xeb %s",past:"%s m\xeb par\xeb",s:"disa sekonda",ss:"%d sekonda",m:"nj\xeb minut\xeb",mm:"%d minuta",h:"nj\xeb or\xeb",hh:"%d or\xeb",d:"nj\xeb dit\xeb",dd:"%d dit\xeb",M:"nj\xeb muaj",MM:"%d muaj",y:"nj\xeb vit",yy:"%d vite"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},98963:function(v,T,i){!function(r){"use strict";var u={words:{ss:["\u0441\u0435\u043a\u0443\u043d\u0434\u0430","\u0441\u0435\u043a\u0443\u043d\u0434\u0435","\u0441\u0435\u043a\u0443\u043d\u0434\u0438"],m:["\u0458\u0435\u0434\u0430\u043d \u043c\u0438\u043d\u0443\u0442","\u0458\u0435\u0434\u043d\u043e\u0433 \u043c\u0438\u043d\u0443\u0442\u0430"],mm:["\u043c\u0438\u043d\u0443\u0442","\u043c\u0438\u043d\u0443\u0442\u0430","\u043c\u0438\u043d\u0443\u0442\u0430"],h:["\u0458\u0435\u0434\u0430\u043d \u0441\u0430\u0442","\u0458\u0435\u0434\u043d\u043e\u0433 \u0441\u0430\u0442\u0430"],hh:["\u0441\u0430\u0442","\u0441\u0430\u0442\u0430","\u0441\u0430\u0442\u0438"],d:["\u0458\u0435\u0434\u0430\u043d \u0434\u0430\u043d","\u0458\u0435\u0434\u043d\u043e\u0433 \u0434\u0430\u043d\u0430"],dd:["\u0434\u0430\u043d","\u0434\u0430\u043d\u0430","\u0434\u0430\u043d\u0430"],M:["\u0458\u0435\u0434\u0430\u043d \u043c\u0435\u0441\u0435\u0446","\u0458\u0435\u0434\u043d\u043e\u0433 \u043c\u0435\u0441\u0435\u0446\u0430"],MM:["\u043c\u0435\u0441\u0435\u0446","\u043c\u0435\u0441\u0435\u0446\u0430","\u043c\u0435\u0441\u0435\u0446\u0438"],y:["\u0458\u0435\u0434\u043d\u0443 \u0433\u043e\u0434\u0438\u043d\u0443","\u0458\u0435\u0434\u043d\u0435 \u0433\u043e\u0434\u0438\u043d\u0435"],yy:["\u0433\u043e\u0434\u0438\u043d\u0443","\u0433\u043e\u0434\u0438\u043d\u0435","\u0433\u043e\u0434\u0438\u043d\u0430"]},correctGrammaticalCase:function(d,e){return d%10>=1&&d%10<=4&&(d%100<10||d%100>=20)?d%10==1?e[0]:e[1]:e[2]},translate:function(d,e,_,y){var A,S=u.words[_];return 1===_.length?"y"===_&&e?"\u0458\u0435\u0434\u043d\u0430 \u0433\u043e\u0434\u0438\u043d\u0430":y||e?S[0]:S[1]:(A=u.correctGrammaticalCase(d,S),"yy"===_&&e&&"\u0433\u043e\u0434\u0438\u043d\u0443"===A?d+" \u0433\u043e\u0434\u0438\u043d\u0430":d+" "+A)}};r.defineLocale("sr-cyrl",{months:"\u0458\u0430\u043d\u0443\u0430\u0440_\u0444\u0435\u0431\u0440\u0443\u0430\u0440_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0438\u043b_\u043c\u0430\u0458_\u0458\u0443\u043d_\u0458\u0443\u043b_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043f\u0442\u0435\u043c\u0431\u0430\u0440_\u043e\u043a\u0442\u043e\u0431\u0430\u0440_\u043d\u043e\u0432\u0435\u043c\u0431\u0430\u0440_\u0434\u0435\u0446\u0435\u043c\u0431\u0430\u0440".split("_"),monthsShort:"\u0458\u0430\u043d._\u0444\u0435\u0431._\u043c\u0430\u0440._\u0430\u043f\u0440._\u043c\u0430\u0458_\u0458\u0443\u043d_\u0458\u0443\u043b_\u0430\u0432\u0433._\u0441\u0435\u043f._\u043e\u043a\u0442._\u043d\u043e\u0432._\u0434\u0435\u0446.".split("_"),monthsParseExact:!0,weekdays:"\u043d\u0435\u0434\u0435\u0459\u0430_\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u0430\u043a_\u0443\u0442\u043e\u0440\u0430\u043a_\u0441\u0440\u0435\u0434\u0430_\u0447\u0435\u0442\u0432\u0440\u0442\u0430\u043a_\u043f\u0435\u0442\u0430\u043a_\u0441\u0443\u0431\u043e\u0442\u0430".split("_"),weekdaysShort:"\u043d\u0435\u0434._\u043f\u043e\u043d._\u0443\u0442\u043e._\u0441\u0440\u0435._\u0447\u0435\u0442._\u043f\u0435\u0442._\u0441\u0443\u0431.".split("_"),weekdaysMin:"\u043d\u0435_\u043f\u043e_\u0443\u0442_\u0441\u0440_\u0447\u0435_\u043f\u0435_\u0441\u0443".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D. M. YYYY.",LL:"D. MMMM YYYY.",LLL:"D. MMMM YYYY. H:mm",LLLL:"dddd, D. MMMM YYYY. H:mm"},calendar:{sameDay:"[\u0434\u0430\u043d\u0430\u0441 \u0443] LT",nextDay:"[\u0441\u0443\u0442\u0440\u0430 \u0443] LT",nextWeek:function(){switch(this.day()){case 0:return"[\u0443] [\u043d\u0435\u0434\u0435\u0459\u0443] [\u0443] LT";case 3:return"[\u0443] [\u0441\u0440\u0435\u0434\u0443] [\u0443] LT";case 6:return"[\u0443] [\u0441\u0443\u0431\u043e\u0442\u0443] [\u0443] LT";case 1:case 2:case 4:case 5:return"[\u0443] dddd [\u0443] LT"}},lastDay:"[\u0458\u0443\u0447\u0435 \u0443] LT",lastWeek:function(){return["[\u043f\u0440\u043e\u0448\u043b\u0435] [\u043d\u0435\u0434\u0435\u0459\u0435] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u043e\u0433] [\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u043a\u0430] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u043e\u0433] [\u0443\u0442\u043e\u0440\u043a\u0430] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u0435] [\u0441\u0440\u0435\u0434\u0435] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u043e\u0433] [\u0447\u0435\u0442\u0432\u0440\u0442\u043a\u0430] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u043e\u0433] [\u043f\u0435\u0442\u043a\u0430] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u0435] [\u0441\u0443\u0431\u043e\u0442\u0435] [\u0443] LT"][this.day()]},sameElse:"L"},relativeTime:{future:"\u0437\u0430 %s",past:"\u043f\u0440\u0435 %s",s:"\u043d\u0435\u043a\u043e\u043b\u0438\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434\u0438",ss:u.translate,m:u.translate,mm:u.translate,h:u.translate,hh:u.translate,d:u.translate,dd:u.translate,M:u.translate,MM:u.translate,y:u.translate,yy:u.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(i(16738))},91621:function(v,T,i){!function(r){"use strict";var u={words:{ss:["sekunda","sekunde","sekundi"],m:["jedan minut","jednog minuta"],mm:["minut","minuta","minuta"],h:["jedan sat","jednog sata"],hh:["sat","sata","sati"],d:["jedan dan","jednog dana"],dd:["dan","dana","dana"],M:["jedan mesec","jednog meseca"],MM:["mesec","meseca","meseci"],y:["jednu godinu","jedne godine"],yy:["godinu","godine","godina"]},correctGrammaticalCase:function(d,e){return d%10>=1&&d%10<=4&&(d%100<10||d%100>=20)?d%10==1?e[0]:e[1]:e[2]},translate:function(d,e,_,y){var A,S=u.words[_];return 1===_.length?"y"===_&&e?"jedna godina":y||e?S[0]:S[1]:(A=u.correctGrammaticalCase(d,S),"yy"===_&&e&&"godinu"===A?d+" godina":d+" "+A)}};r.defineLocale("sr",{months:"januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedelja_ponedeljak_utorak_sreda_\u010detvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sre._\u010det._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_\u010de_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D. M. YYYY.",LL:"D. MMMM YYYY.",LLL:"D. MMMM YYYY. H:mm",LLLL:"dddd, D. MMMM YYYY. H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedelju] [u] LT";case 3:return"[u] [sredu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[ju\u010de u] LT",lastWeek:function(){return["[pro\u0161le] [nedelje] [u] LT","[pro\u0161log] [ponedeljka] [u] LT","[pro\u0161log] [utorka] [u] LT","[pro\u0161le] [srede] [u] LT","[pro\u0161log] [\u010detvrtka] [u] LT","[pro\u0161log] [petka] [u] LT","[pro\u0161le] [subote] [u] LT"][this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"pre %s",s:"nekoliko sekundi",ss:u.translate,m:u.translate,mm:u.translate,h:u.translate,hh:u.translate,d:u.translate,dd:u.translate,M:u.translate,MM:u.translate,y:u.translate,yy:u.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(i(16738))},41404:function(v,T,i){!function(r){"use strict";r.defineLocale("ss",{months:"Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni".split("_"),monthsShort:"Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo".split("_"),weekdays:"Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo".split("_"),weekdaysShort:"Lis_Umb_Lsb_Les_Lsi_Lsh_Umg".split("_"),weekdaysMin:"Li_Us_Lb_Lt_Ls_Lh_Ug".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Namuhla nga] LT",nextDay:"[Kusasa nga] LT",nextWeek:"dddd [nga] LT",lastDay:"[Itolo nga] LT",lastWeek:"dddd [leliphelile] [nga] LT",sameElse:"L"},relativeTime:{future:"nga %s",past:"wenteka nga %s",s:"emizuzwana lomcane",ss:"%d mzuzwana",m:"umzuzu",mm:"%d emizuzu",h:"lihora",hh:"%d emahora",d:"lilanga",dd:"%d emalanga",M:"inyanga",MM:"%d tinyanga",y:"umnyaka",yy:"%d iminyaka"},meridiemParse:/ekuseni|emini|entsambama|ebusuku/,meridiem:function(p,d,e){return p<11?"ekuseni":p<15?"emini":p<19?"entsambama":"ebusuku"},meridiemHour:function(p,d){return 12===p&&(p=0),"ekuseni"===d?p:"emini"===d?p>=11?p:p+12:"entsambama"===d||"ebusuku"===d?0===p?0:p+12:void 0},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:"%d",week:{dow:1,doy:4}})}(i(16738))},55685:function(v,T,i){!function(r){"use strict";r.defineLocale("sv",{months:"januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"s\xf6ndag_m\xe5ndag_tisdag_onsdag_torsdag_fredag_l\xf6rdag".split("_"),weekdaysShort:"s\xf6n_m\xe5n_tis_ons_tor_fre_l\xf6r".split("_"),weekdaysMin:"s\xf6_m\xe5_ti_on_to_fr_l\xf6".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [kl.] HH:mm",LLLL:"dddd D MMMM YYYY [kl.] HH:mm",lll:"D MMM YYYY HH:mm",llll:"ddd D MMM YYYY HH:mm"},calendar:{sameDay:"[Idag] LT",nextDay:"[Imorgon] LT",lastDay:"[Ig\xe5r] LT",nextWeek:"[P\xe5] dddd LT",lastWeek:"[I] dddd[s] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"f\xf6r %s sedan",s:"n\xe5gra sekunder",ss:"%d sekunder",m:"en minut",mm:"%d minuter",h:"en timme",hh:"%d timmar",d:"en dag",dd:"%d dagar",M:"en m\xe5nad",MM:"%d m\xe5nader",y:"ett \xe5r",yy:"%d \xe5r"},dayOfMonthOrdinalParse:/\d{1,2}(\:e|\:a)/,ordinal:function(p){var d=p%10;return p+(1==~~(p%100/10)?":e":1===d||2===d?":a":":e")},week:{dow:1,doy:4}})}(i(16738))},3872:function(v,T,i){!function(r){"use strict";r.defineLocale("sw",{months:"Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des".split("_"),weekdays:"Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi".split("_"),weekdaysShort:"Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos".split("_"),weekdaysMin:"J2_J3_J4_J5_Al_Ij_J1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"hh:mm A",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[leo saa] LT",nextDay:"[kesho saa] LT",nextWeek:"[wiki ijayo] dddd [saat] LT",lastDay:"[jana] LT",lastWeek:"[wiki iliyopita] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s baadaye",past:"tokea %s",s:"hivi punde",ss:"sekunde %d",m:"dakika moja",mm:"dakika %d",h:"saa limoja",hh:"masaa %d",d:"siku moja",dd:"siku %d",M:"mwezi mmoja",MM:"miezi %d",y:"mwaka mmoja",yy:"miaka %d"},week:{dow:1,doy:7}})}(i(16738))},54106:function(v,T,i){!function(r){"use strict";var u={1:"\u0be7",2:"\u0be8",3:"\u0be9",4:"\u0bea",5:"\u0beb",6:"\u0bec",7:"\u0bed",8:"\u0bee",9:"\u0bef",0:"\u0be6"},p={"\u0be7":"1","\u0be8":"2","\u0be9":"3","\u0bea":"4","\u0beb":"5","\u0bec":"6","\u0bed":"7","\u0bee":"8","\u0bef":"9","\u0be6":"0"};r.defineLocale("ta",{months:"\u0b9c\u0ba9\u0bb5\u0bb0\u0bbf_\u0baa\u0bbf\u0baa\u0bcd\u0bb0\u0bb5\u0bb0\u0bbf_\u0bae\u0bbe\u0bb0\u0bcd\u0b9a\u0bcd_\u0b8f\u0baa\u0bcd\u0bb0\u0bb2\u0bcd_\u0bae\u0bc7_\u0b9c\u0bc2\u0ba9\u0bcd_\u0b9c\u0bc2\u0bb2\u0bc8_\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd_\u0b9a\u0bc6\u0baa\u0bcd\u0b9f\u0bc6\u0bae\u0bcd\u0baa\u0bb0\u0bcd_\u0b85\u0b95\u0bcd\u0b9f\u0bc7\u0bbe\u0baa\u0bb0\u0bcd_\u0ba8\u0bb5\u0bae\u0bcd\u0baa\u0bb0\u0bcd_\u0b9f\u0bbf\u0b9a\u0bae\u0bcd\u0baa\u0bb0\u0bcd".split("_"),monthsShort:"\u0b9c\u0ba9\u0bb5\u0bb0\u0bbf_\u0baa\u0bbf\u0baa\u0bcd\u0bb0\u0bb5\u0bb0\u0bbf_\u0bae\u0bbe\u0bb0\u0bcd\u0b9a\u0bcd_\u0b8f\u0baa\u0bcd\u0bb0\u0bb2\u0bcd_\u0bae\u0bc7_\u0b9c\u0bc2\u0ba9\u0bcd_\u0b9c\u0bc2\u0bb2\u0bc8_\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd_\u0b9a\u0bc6\u0baa\u0bcd\u0b9f\u0bc6\u0bae\u0bcd\u0baa\u0bb0\u0bcd_\u0b85\u0b95\u0bcd\u0b9f\u0bc7\u0bbe\u0baa\u0bb0\u0bcd_\u0ba8\u0bb5\u0bae\u0bcd\u0baa\u0bb0\u0bcd_\u0b9f\u0bbf\u0b9a\u0bae\u0bcd\u0baa\u0bb0\u0bcd".split("_"),weekdays:"\u0b9e\u0bbe\u0baf\u0bbf\u0bb1\u0bcd\u0bb1\u0bc1\u0b95\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0ba4\u0bbf\u0b99\u0bcd\u0b95\u0b9f\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0b9a\u0bc6\u0bb5\u0bcd\u0bb5\u0bbe\u0baf\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0baa\u0bc1\u0ba4\u0ba9\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0bb5\u0bbf\u0baf\u0bbe\u0bb4\u0b95\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0bb5\u0bc6\u0bb3\u0bcd\u0bb3\u0bbf\u0b95\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0b9a\u0ba9\u0bbf\u0b95\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8".split("_"),weekdaysShort:"\u0b9e\u0bbe\u0baf\u0bbf\u0bb1\u0bc1_\u0ba4\u0bbf\u0b99\u0bcd\u0b95\u0bb3\u0bcd_\u0b9a\u0bc6\u0bb5\u0bcd\u0bb5\u0bbe\u0baf\u0bcd_\u0baa\u0bc1\u0ba4\u0ba9\u0bcd_\u0bb5\u0bbf\u0baf\u0bbe\u0bb4\u0ba9\u0bcd_\u0bb5\u0bc6\u0bb3\u0bcd\u0bb3\u0bbf_\u0b9a\u0ba9\u0bbf".split("_"),weekdaysMin:"\u0b9e\u0bbe_\u0ba4\u0bbf_\u0b9a\u0bc6_\u0baa\u0bc1_\u0bb5\u0bbf_\u0bb5\u0bc6_\u0b9a".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, HH:mm",LLLL:"dddd, D MMMM YYYY, HH:mm"},calendar:{sameDay:"[\u0b87\u0ba9\u0bcd\u0bb1\u0bc1] LT",nextDay:"[\u0ba8\u0bbe\u0bb3\u0bc8] LT",nextWeek:"dddd, LT",lastDay:"[\u0ba8\u0bc7\u0bb1\u0bcd\u0bb1\u0bc1] LT",lastWeek:"[\u0b95\u0b9f\u0ba8\u0bcd\u0ba4 \u0bb5\u0bbe\u0bb0\u0bae\u0bcd] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0b87\u0bb2\u0bcd",past:"%s \u0bae\u0bc1\u0ba9\u0bcd",s:"\u0b92\u0bb0\u0bc1 \u0b9a\u0bbf\u0bb2 \u0bb5\u0bbf\u0ba8\u0bbe\u0b9f\u0bbf\u0b95\u0bb3\u0bcd",ss:"%d \u0bb5\u0bbf\u0ba8\u0bbe\u0b9f\u0bbf\u0b95\u0bb3\u0bcd",m:"\u0b92\u0bb0\u0bc1 \u0ba8\u0bbf\u0bae\u0bbf\u0b9f\u0bae\u0bcd",mm:"%d \u0ba8\u0bbf\u0bae\u0bbf\u0b9f\u0b99\u0bcd\u0b95\u0bb3\u0bcd",h:"\u0b92\u0bb0\u0bc1 \u0bae\u0ba3\u0bbf \u0ba8\u0bc7\u0bb0\u0bae\u0bcd",hh:"%d \u0bae\u0ba3\u0bbf \u0ba8\u0bc7\u0bb0\u0bae\u0bcd",d:"\u0b92\u0bb0\u0bc1 \u0ba8\u0bbe\u0bb3\u0bcd",dd:"%d \u0ba8\u0bbe\u0b9f\u0bcd\u0b95\u0bb3\u0bcd",M:"\u0b92\u0bb0\u0bc1 \u0bae\u0bbe\u0ba4\u0bae\u0bcd",MM:"%d \u0bae\u0bbe\u0ba4\u0b99\u0bcd\u0b95\u0bb3\u0bcd",y:"\u0b92\u0bb0\u0bc1 \u0bb5\u0bb0\u0bc1\u0b9f\u0bae\u0bcd",yy:"%d \u0b86\u0ba3\u0bcd\u0b9f\u0bc1\u0b95\u0bb3\u0bcd"},dayOfMonthOrdinalParse:/\d{1,2}\u0bb5\u0ba4\u0bc1/,ordinal:function(e){return e+"\u0bb5\u0ba4\u0bc1"},preparse:function(e){return e.replace(/[\u0be7\u0be8\u0be9\u0bea\u0beb\u0bec\u0bed\u0bee\u0bef\u0be6]/g,function(_){return p[_]})},postformat:function(e){return e.replace(/\d/g,function(_){return u[_]})},meridiemParse:/\u0baf\u0bbe\u0bae\u0bae\u0bcd|\u0bb5\u0bc8\u0b95\u0bb1\u0bc8|\u0b95\u0bbe\u0bb2\u0bc8|\u0ba8\u0ba3\u0bcd\u0baa\u0b95\u0bb2\u0bcd|\u0b8e\u0bb1\u0bcd\u0baa\u0bbe\u0b9f\u0bc1|\u0bae\u0bbe\u0bb2\u0bc8/,meridiem:function(e,_,y){return e<2?" \u0baf\u0bbe\u0bae\u0bae\u0bcd":e<6?" \u0bb5\u0bc8\u0b95\u0bb1\u0bc8":e<10?" \u0b95\u0bbe\u0bb2\u0bc8":e<14?" \u0ba8\u0ba3\u0bcd\u0baa\u0b95\u0bb2\u0bcd":e<18?" \u0b8e\u0bb1\u0bcd\u0baa\u0bbe\u0b9f\u0bc1":e<22?" \u0bae\u0bbe\u0bb2\u0bc8":" \u0baf\u0bbe\u0bae\u0bae\u0bcd"},meridiemHour:function(e,_){return 12===e&&(e=0),"\u0baf\u0bbe\u0bae\u0bae\u0bcd"===_?e<2?e:e+12:"\u0bb5\u0bc8\u0b95\u0bb1\u0bc8"===_||"\u0b95\u0bbe\u0bb2\u0bc8"===_||"\u0ba8\u0ba3\u0bcd\u0baa\u0b95\u0bb2\u0bcd"===_&&e>=10?e:e+12},week:{dow:0,doy:6}})}(i(16738))},39204:function(v,T,i){!function(r){"use strict";r.defineLocale("te",{months:"\u0c1c\u0c28\u0c35\u0c30\u0c3f_\u0c2b\u0c3f\u0c2c\u0c4d\u0c30\u0c35\u0c30\u0c3f_\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f_\u0c0f\u0c2a\u0c4d\u0c30\u0c3f\u0c32\u0c4d_\u0c2e\u0c47_\u0c1c\u0c42\u0c28\u0c4d_\u0c1c\u0c41\u0c32\u0c48_\u0c06\u0c17\u0c38\u0c4d\u0c1f\u0c41_\u0c38\u0c46\u0c2a\u0c4d\u0c1f\u0c46\u0c02\u0c2c\u0c30\u0c4d_\u0c05\u0c15\u0c4d\u0c1f\u0c4b\u0c2c\u0c30\u0c4d_\u0c28\u0c35\u0c02\u0c2c\u0c30\u0c4d_\u0c21\u0c3f\u0c38\u0c46\u0c02\u0c2c\u0c30\u0c4d".split("_"),monthsShort:"\u0c1c\u0c28._\u0c2b\u0c3f\u0c2c\u0c4d\u0c30._\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f_\u0c0f\u0c2a\u0c4d\u0c30\u0c3f._\u0c2e\u0c47_\u0c1c\u0c42\u0c28\u0c4d_\u0c1c\u0c41\u0c32\u0c48_\u0c06\u0c17._\u0c38\u0c46\u0c2a\u0c4d._\u0c05\u0c15\u0c4d\u0c1f\u0c4b._\u0c28\u0c35._\u0c21\u0c3f\u0c38\u0c46.".split("_"),monthsParseExact:!0,weekdays:"\u0c06\u0c26\u0c3f\u0c35\u0c3e\u0c30\u0c02_\u0c38\u0c4b\u0c2e\u0c35\u0c3e\u0c30\u0c02_\u0c2e\u0c02\u0c17\u0c33\u0c35\u0c3e\u0c30\u0c02_\u0c2c\u0c41\u0c27\u0c35\u0c3e\u0c30\u0c02_\u0c17\u0c41\u0c30\u0c41\u0c35\u0c3e\u0c30\u0c02_\u0c36\u0c41\u0c15\u0c4d\u0c30\u0c35\u0c3e\u0c30\u0c02_\u0c36\u0c28\u0c3f\u0c35\u0c3e\u0c30\u0c02".split("_"),weekdaysShort:"\u0c06\u0c26\u0c3f_\u0c38\u0c4b\u0c2e_\u0c2e\u0c02\u0c17\u0c33_\u0c2c\u0c41\u0c27_\u0c17\u0c41\u0c30\u0c41_\u0c36\u0c41\u0c15\u0c4d\u0c30_\u0c36\u0c28\u0c3f".split("_"),weekdaysMin:"\u0c06_\u0c38\u0c4b_\u0c2e\u0c02_\u0c2c\u0c41_\u0c17\u0c41_\u0c36\u0c41_\u0c36".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[\u0c28\u0c47\u0c21\u0c41] LT",nextDay:"[\u0c30\u0c47\u0c2a\u0c41] LT",nextWeek:"dddd, LT",lastDay:"[\u0c28\u0c3f\u0c28\u0c4d\u0c28] LT",lastWeek:"[\u0c17\u0c24] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0c32\u0c4b",past:"%s \u0c15\u0c4d\u0c30\u0c3f\u0c24\u0c02",s:"\u0c15\u0c4a\u0c28\u0c4d\u0c28\u0c3f \u0c15\u0c4d\u0c37\u0c23\u0c3e\u0c32\u0c41",ss:"%d \u0c38\u0c46\u0c15\u0c28\u0c4d\u0c32\u0c41",m:"\u0c12\u0c15 \u0c28\u0c3f\u0c2e\u0c3f\u0c37\u0c02",mm:"%d \u0c28\u0c3f\u0c2e\u0c3f\u0c37\u0c3e\u0c32\u0c41",h:"\u0c12\u0c15 \u0c17\u0c02\u0c1f",hh:"%d \u0c17\u0c02\u0c1f\u0c32\u0c41",d:"\u0c12\u0c15 \u0c30\u0c4b\u0c1c\u0c41",dd:"%d \u0c30\u0c4b\u0c1c\u0c41\u0c32\u0c41",M:"\u0c12\u0c15 \u0c28\u0c46\u0c32",MM:"%d \u0c28\u0c46\u0c32\u0c32\u0c41",y:"\u0c12\u0c15 \u0c38\u0c02\u0c35\u0c24\u0c4d\u0c38\u0c30\u0c02",yy:"%d \u0c38\u0c02\u0c35\u0c24\u0c4d\u0c38\u0c30\u0c3e\u0c32\u0c41"},dayOfMonthOrdinalParse:/\d{1,2}\u0c35/,ordinal:"%d\u0c35",meridiemParse:/\u0c30\u0c3e\u0c24\u0c4d\u0c30\u0c3f|\u0c09\u0c26\u0c2f\u0c02|\u0c2e\u0c27\u0c4d\u0c2f\u0c3e\u0c39\u0c4d\u0c28\u0c02|\u0c38\u0c3e\u0c2f\u0c02\u0c24\u0c4d\u0c30\u0c02/,meridiemHour:function(p,d){return 12===p&&(p=0),"\u0c30\u0c3e\u0c24\u0c4d\u0c30\u0c3f"===d?p<4?p:p+12:"\u0c09\u0c26\u0c2f\u0c02"===d?p:"\u0c2e\u0c27\u0c4d\u0c2f\u0c3e\u0c39\u0c4d\u0c28\u0c02"===d?p>=10?p:p+12:"\u0c38\u0c3e\u0c2f\u0c02\u0c24\u0c4d\u0c30\u0c02"===d?p+12:void 0},meridiem:function(p,d,e){return p<4?"\u0c30\u0c3e\u0c24\u0c4d\u0c30\u0c3f":p<10?"\u0c09\u0c26\u0c2f\u0c02":p<17?"\u0c2e\u0c27\u0c4d\u0c2f\u0c3e\u0c39\u0c4d\u0c28\u0c02":p<20?"\u0c38\u0c3e\u0c2f\u0c02\u0c24\u0c4d\u0c30\u0c02":"\u0c30\u0c3e\u0c24\u0c4d\u0c30\u0c3f"},week:{dow:0,doy:6}})}(i(16738))},83692:function(v,T,i){!function(r){"use strict";r.defineLocale("tet",{months:"Janeiru_Fevereiru_Marsu_Abril_Maiu_Ju\xf1u_Jullu_Agustu_Setembru_Outubru_Novembru_Dezembru".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingu_Segunda_Tersa_Kuarta_Kinta_Sesta_Sabadu".split("_"),weekdaysShort:"Dom_Seg_Ters_Kua_Kint_Sest_Sab".split("_"),weekdaysMin:"Do_Seg_Te_Ku_Ki_Ses_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Ohin iha] LT",nextDay:"[Aban iha] LT",nextWeek:"dddd [iha] LT",lastDay:"[Horiseik iha] LT",lastWeek:"dddd [semana kotuk] [iha] LT",sameElse:"L"},relativeTime:{future:"iha %s",past:"%s liuba",s:"segundu balun",ss:"segundu %d",m:"minutu ida",mm:"minutu %d",h:"oras ida",hh:"oras %d",d:"loron ida",dd:"loron %d",M:"fulan ida",MM:"fulan %d",y:"tinan ida",yy:"tinan %d"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(p){var d=p%10;return p+(1==~~(p%100/10)?"th":1===d?"st":2===d?"nd":3===d?"rd":"th")},week:{dow:1,doy:4}})}(i(16738))},86361:function(v,T,i){!function(r){"use strict";var u={0:"-\u0443\u043c",1:"-\u0443\u043c",2:"-\u044e\u043c",3:"-\u044e\u043c",4:"-\u0443\u043c",5:"-\u0443\u043c",6:"-\u0443\u043c",7:"-\u0443\u043c",8:"-\u0443\u043c",9:"-\u0443\u043c",10:"-\u0443\u043c",12:"-\u0443\u043c",13:"-\u0443\u043c",20:"-\u0443\u043c",30:"-\u044e\u043c",40:"-\u0443\u043c",50:"-\u0443\u043c",60:"-\u0443\u043c",70:"-\u0443\u043c",80:"-\u0443\u043c",90:"-\u0443\u043c",100:"-\u0443\u043c"};r.defineLocale("tg",{months:{format:"\u044f\u043d\u0432\u0430\u0440\u0438_\u0444\u0435\u0432\u0440\u0430\u043b\u0438_\u043c\u0430\u0440\u0442\u0438_\u0430\u043f\u0440\u0435\u043b\u0438_\u043c\u0430\u0439\u0438_\u0438\u044e\u043d\u0438_\u0438\u044e\u043b\u0438_\u0430\u0432\u0433\u0443\u0441\u0442\u0438_\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u0438_\u043e\u043a\u0442\u044f\u0431\u0440\u0438_\u043d\u043e\u044f\u0431\u0440\u0438_\u0434\u0435\u043a\u0430\u0431\u0440\u0438".split("_"),standalone:"\u044f\u043d\u0432\u0430\u0440_\u0444\u0435\u0432\u0440\u0430\u043b_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0435\u043b_\u043c\u0430\u0439_\u0438\u044e\u043d_\u0438\u044e\u043b_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043d\u0442\u044f\u0431\u0440_\u043e\u043a\u0442\u044f\u0431\u0440_\u043d\u043e\u044f\u0431\u0440_\u0434\u0435\u043a\u0430\u0431\u0440".split("_")},monthsShort:"\u044f\u043d\u0432_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0439_\u0438\u044e\u043d_\u0438\u044e\u043b_\u0430\u0432\u0433_\u0441\u0435\u043d_\u043e\u043a\u0442_\u043d\u043e\u044f_\u0434\u0435\u043a".split("_"),weekdays:"\u044f\u043a\u0448\u0430\u043d\u0431\u0435_\u0434\u0443\u0448\u0430\u043d\u0431\u0435_\u0441\u0435\u0448\u0430\u043d\u0431\u0435_\u0447\u043e\u0440\u0448\u0430\u043d\u0431\u0435_\u043f\u0430\u043d\u04b7\u0448\u0430\u043d\u0431\u0435_\u04b7\u0443\u043c\u044a\u0430_\u0448\u0430\u043d\u0431\u0435".split("_"),weekdaysShort:"\u044f\u0448\u0431_\u0434\u0448\u0431_\u0441\u0448\u0431_\u0447\u0448\u0431_\u043f\u0448\u0431_\u04b7\u0443\u043c_\u0448\u043d\u0431".split("_"),weekdaysMin:"\u044f\u0448_\u0434\u0448_\u0441\u0448_\u0447\u0448_\u043f\u0448_\u04b7\u043c_\u0448\u0431".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0418\u043c\u0440\u04ef\u0437 \u0441\u043e\u0430\u0442\u0438] LT",nextDay:"[\u0424\u0430\u0440\u0434\u043e \u0441\u043e\u0430\u0442\u0438] LT",lastDay:"[\u0414\u0438\u0440\u04ef\u0437 \u0441\u043e\u0430\u0442\u0438] LT",nextWeek:"dddd[\u0438] [\u04b3\u0430\u0444\u0442\u0430\u0438 \u043e\u044f\u043d\u0434\u0430 \u0441\u043e\u0430\u0442\u0438] LT",lastWeek:"dddd[\u0438] [\u04b3\u0430\u0444\u0442\u0430\u0438 \u0433\u0443\u0437\u0430\u0448\u0442\u0430 \u0441\u043e\u0430\u0442\u0438] LT",sameElse:"L"},relativeTime:{future:"\u0431\u0430\u044a\u0434\u0438 %s",past:"%s \u043f\u0435\u0448",s:"\u044f\u043a\u0447\u0430\u043d\u0434 \u0441\u043e\u043d\u0438\u044f",m:"\u044f\u043a \u0434\u0430\u049b\u0438\u049b\u0430",mm:"%d \u0434\u0430\u049b\u0438\u049b\u0430",h:"\u044f\u043a \u0441\u043e\u0430\u0442",hh:"%d \u0441\u043e\u0430\u0442",d:"\u044f\u043a \u0440\u04ef\u0437",dd:"%d \u0440\u04ef\u0437",M:"\u044f\u043a \u043c\u043e\u04b3",MM:"%d \u043c\u043e\u04b3",y:"\u044f\u043a \u0441\u043e\u043b",yy:"%d \u0441\u043e\u043b"},meridiemParse:/\u0448\u0430\u0431|\u0441\u0443\u0431\u04b3|\u0440\u04ef\u0437|\u0431\u0435\u0433\u043e\u04b3/,meridiemHour:function(d,e){return 12===d&&(d=0),"\u0448\u0430\u0431"===e?d<4?d:d+12:"\u0441\u0443\u0431\u04b3"===e?d:"\u0440\u04ef\u0437"===e?d>=11?d:d+12:"\u0431\u0435\u0433\u043e\u04b3"===e?d+12:void 0},meridiem:function(d,e,_){return d<4?"\u0448\u0430\u0431":d<11?"\u0441\u0443\u0431\u04b3":d<16?"\u0440\u04ef\u0437":d<19?"\u0431\u0435\u0433\u043e\u04b3":"\u0448\u0430\u0431"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0443\u043c|\u044e\u043c)/,ordinal:function(d){return d+(u[d]||u[d%10]||u[d>=100?100:null])},week:{dow:1,doy:7}})}(i(16738))},31735:function(v,T,i){!function(r){"use strict";r.defineLocale("th",{months:"\u0e21\u0e01\u0e23\u0e32\u0e04\u0e21_\u0e01\u0e38\u0e21\u0e20\u0e32\u0e1e\u0e31\u0e19\u0e18\u0e4c_\u0e21\u0e35\u0e19\u0e32\u0e04\u0e21_\u0e40\u0e21\u0e29\u0e32\u0e22\u0e19_\u0e1e\u0e24\u0e29\u0e20\u0e32\u0e04\u0e21_\u0e21\u0e34\u0e16\u0e38\u0e19\u0e32\u0e22\u0e19_\u0e01\u0e23\u0e01\u0e0e\u0e32\u0e04\u0e21_\u0e2a\u0e34\u0e07\u0e2b\u0e32\u0e04\u0e21_\u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19_\u0e15\u0e38\u0e25\u0e32\u0e04\u0e21_\u0e1e\u0e24\u0e28\u0e08\u0e34\u0e01\u0e32\u0e22\u0e19_\u0e18\u0e31\u0e19\u0e27\u0e32\u0e04\u0e21".split("_"),monthsShort:"\u0e21.\u0e04._\u0e01.\u0e1e._\u0e21\u0e35.\u0e04._\u0e40\u0e21.\u0e22._\u0e1e.\u0e04._\u0e21\u0e34.\u0e22._\u0e01.\u0e04._\u0e2a.\u0e04._\u0e01.\u0e22._\u0e15.\u0e04._\u0e1e.\u0e22._\u0e18.\u0e04.".split("_"),monthsParseExact:!0,weekdays:"\u0e2d\u0e32\u0e17\u0e34\u0e15\u0e22\u0e4c_\u0e08\u0e31\u0e19\u0e17\u0e23\u0e4c_\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23_\u0e1e\u0e38\u0e18_\u0e1e\u0e24\u0e2b\u0e31\u0e2a\u0e1a\u0e14\u0e35_\u0e28\u0e38\u0e01\u0e23\u0e4c_\u0e40\u0e2a\u0e32\u0e23\u0e4c".split("_"),weekdaysShort:"\u0e2d\u0e32\u0e17\u0e34\u0e15\u0e22\u0e4c_\u0e08\u0e31\u0e19\u0e17\u0e23\u0e4c_\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23_\u0e1e\u0e38\u0e18_\u0e1e\u0e24\u0e2b\u0e31\u0e2a_\u0e28\u0e38\u0e01\u0e23\u0e4c_\u0e40\u0e2a\u0e32\u0e23\u0e4c".split("_"),weekdaysMin:"\u0e2d\u0e32._\u0e08._\u0e2d._\u0e1e._\u0e1e\u0e24._\u0e28._\u0e2a.".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY \u0e40\u0e27\u0e25\u0e32 H:mm",LLLL:"\u0e27\u0e31\u0e19dddd\u0e17\u0e35\u0e48 D MMMM YYYY \u0e40\u0e27\u0e25\u0e32 H:mm"},meridiemParse:/\u0e01\u0e48\u0e2d\u0e19\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07|\u0e2b\u0e25\u0e31\u0e07\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07/,isPM:function(p){return"\u0e2b\u0e25\u0e31\u0e07\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07"===p},meridiem:function(p,d,e){return p<12?"\u0e01\u0e48\u0e2d\u0e19\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07":"\u0e2b\u0e25\u0e31\u0e07\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07"},calendar:{sameDay:"[\u0e27\u0e31\u0e19\u0e19\u0e35\u0e49 \u0e40\u0e27\u0e25\u0e32] LT",nextDay:"[\u0e1e\u0e23\u0e38\u0e48\u0e07\u0e19\u0e35\u0e49 \u0e40\u0e27\u0e25\u0e32] LT",nextWeek:"dddd[\u0e2b\u0e19\u0e49\u0e32 \u0e40\u0e27\u0e25\u0e32] LT",lastDay:"[\u0e40\u0e21\u0e37\u0e48\u0e2d\u0e27\u0e32\u0e19\u0e19\u0e35\u0e49 \u0e40\u0e27\u0e25\u0e32] LT",lastWeek:"[\u0e27\u0e31\u0e19]dddd[\u0e17\u0e35\u0e48\u0e41\u0e25\u0e49\u0e27 \u0e40\u0e27\u0e25\u0e32] LT",sameElse:"L"},relativeTime:{future:"\u0e2d\u0e35\u0e01 %s",past:"%s\u0e17\u0e35\u0e48\u0e41\u0e25\u0e49\u0e27",s:"\u0e44\u0e21\u0e48\u0e01\u0e35\u0e48\u0e27\u0e34\u0e19\u0e32\u0e17\u0e35",ss:"%d \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35",m:"1 \u0e19\u0e32\u0e17\u0e35",mm:"%d \u0e19\u0e32\u0e17\u0e35",h:"1 \u0e0a\u0e31\u0e48\u0e27\u0e42\u0e21\u0e07",hh:"%d \u0e0a\u0e31\u0e48\u0e27\u0e42\u0e21\u0e07",d:"1 \u0e27\u0e31\u0e19",dd:"%d \u0e27\u0e31\u0e19",w:"1 \u0e2a\u0e31\u0e1b\u0e14\u0e32\u0e2b\u0e4c",ww:"%d \u0e2a\u0e31\u0e1b\u0e14\u0e32\u0e2b\u0e4c",M:"1 \u0e40\u0e14\u0e37\u0e2d\u0e19",MM:"%d \u0e40\u0e14\u0e37\u0e2d\u0e19",y:"1 \u0e1b\u0e35",yy:"%d \u0e1b\u0e35"}})}(i(16738))},1568:function(v,T,i){!function(r){"use strict";var u={1:"'inji",5:"'inji",8:"'inji",70:"'inji",80:"'inji",2:"'nji",7:"'nji",20:"'nji",50:"'nji",3:"'\xfcnji",4:"'\xfcnji",100:"'\xfcnji",6:"'njy",9:"'unjy",10:"'unjy",30:"'unjy",60:"'ynjy",90:"'ynjy"};r.defineLocale("tk",{months:"\xddanwar_Fewral_Mart_Aprel_Ma\xfd_I\xfdun_I\xfdul_Awgust_Sent\xfdabr_Okt\xfdabr_No\xfdabr_Dekabr".split("_"),monthsShort:"\xddan_Few_Mar_Apr_Ma\xfd_I\xfdn_I\xfdl_Awg_Sen_Okt_No\xfd_Dek".split("_"),weekdays:"\xddek\u015fenbe_Du\u015fenbe_Si\u015fenbe_\xc7ar\u015fenbe_Pen\u015fenbe_Anna_\u015eenbe".split("_"),weekdaysShort:"\xddek_Du\u015f_Si\u015f_\xc7ar_Pen_Ann_\u015een".split("_"),weekdaysMin:"\xddk_D\u015f_S\u015f_\xc7r_Pn_An_\u015en".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bug\xfcn sagat] LT",nextDay:"[ertir sagat] LT",nextWeek:"[indiki] dddd [sagat] LT",lastDay:"[d\xfc\xfdn] LT",lastWeek:"[ge\xe7en] dddd [sagat] LT",sameElse:"L"},relativeTime:{future:"%s so\u0148",past:"%s \xf6\u0148",s:"birn\xe4\xe7e sekunt",m:"bir minut",mm:"%d minut",h:"bir sagat",hh:"%d sagat",d:"bir g\xfcn",dd:"%d g\xfcn",M:"bir a\xfd",MM:"%d a\xfd",y:"bir \xfdyl",yy:"%d \xfdyl"},ordinal:function(d,e){switch(e){case"d":case"D":case"Do":case"DD":return d;default:if(0===d)return d+"'unjy";var _=d%10;return d+(u[_]||u[d%100-_]||u[d>=100?100:null])}},week:{dow:1,doy:7}})}(i(16738))},96129:function(v,T,i){!function(r){"use strict";r.defineLocale("tl-ph",{months:"Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre".split("_"),monthsShort:"Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis".split("_"),weekdays:"Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado".split("_"),weekdaysShort:"Lin_Lun_Mar_Miy_Huw_Biy_Sab".split("_"),weekdaysMin:"Li_Lu_Ma_Mi_Hu_Bi_Sab".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"MM/D/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY HH:mm",LLLL:"dddd, MMMM DD, YYYY HH:mm"},calendar:{sameDay:"LT [ngayong araw]",nextDay:"[Bukas ng] LT",nextWeek:"LT [sa susunod na] dddd",lastDay:"LT [kahapon]",lastWeek:"LT [noong nakaraang] dddd",sameElse:"L"},relativeTime:{future:"sa loob ng %s",past:"%s ang nakalipas",s:"ilang segundo",ss:"%d segundo",m:"isang minuto",mm:"%d minuto",h:"isang oras",hh:"%d oras",d:"isang araw",dd:"%d araw",M:"isang buwan",MM:"%d buwan",y:"isang taon",yy:"%d taon"},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:function(p){return p},week:{dow:1,doy:4}})}(i(16738))},13759:function(v,T,i){!function(r){"use strict";var u="pagh_wa\u2019_cha\u2019_wej_loS_vagh_jav_Soch_chorgh_Hut".split("_");function e(S,A,N,L){var Z=function(S){var A=Math.floor(S%1e3/100),N=Math.floor(S%100/10),L=S%10,Z="";return A>0&&(Z+=u[A]+"vatlh"),N>0&&(Z+=(""!==Z?" ":"")+u[N]+"maH"),L>0&&(Z+=(""!==Z?" ":"")+u[L]),""===Z?"pagh":Z}(S);switch(N){case"ss":return Z+" lup";case"mm":return Z+" tup";case"hh":return Z+" rep";case"dd":return Z+" jaj";case"MM":return Z+" jar";case"yy":return Z+" DIS"}}r.defineLocale("tlh",{months:"tera\u2019 jar wa\u2019_tera\u2019 jar cha\u2019_tera\u2019 jar wej_tera\u2019 jar loS_tera\u2019 jar vagh_tera\u2019 jar jav_tera\u2019 jar Soch_tera\u2019 jar chorgh_tera\u2019 jar Hut_tera\u2019 jar wa\u2019maH_tera\u2019 jar wa\u2019maH wa\u2019_tera\u2019 jar wa\u2019maH cha\u2019".split("_"),monthsShort:"jar wa\u2019_jar cha\u2019_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa\u2019maH_jar wa\u2019maH wa\u2019_jar wa\u2019maH cha\u2019".split("_"),monthsParseExact:!0,weekdays:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),weekdaysShort:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),weekdaysMin:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[DaHjaj] LT",nextDay:"[wa\u2019leS] LT",nextWeek:"LLL",lastDay:"[wa\u2019Hu\u2019] LT",lastWeek:"LLL",sameElse:"L"},relativeTime:{future:function(S){var A=S;return-1!==S.indexOf("jaj")?A.slice(0,-3)+"leS":-1!==S.indexOf("jar")?A.slice(0,-3)+"waQ":-1!==S.indexOf("DIS")?A.slice(0,-3)+"nem":A+" pIq"},past:function(S){var A=S;return-1!==S.indexOf("jaj")?A.slice(0,-3)+"Hu\u2019":-1!==S.indexOf("jar")?A.slice(0,-3)+"wen":-1!==S.indexOf("DIS")?A.slice(0,-3)+"ben":A+" ret"},s:"puS lup",ss:e,m:"wa\u2019 tup",mm:e,h:"wa\u2019 rep",hh:e,d:"wa\u2019 jaj",dd:e,M:"wa\u2019 jar",MM:e,y:"wa\u2019 DIS",yy:e},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},81644:function(v,T,i){!function(r){"use strict";var u={1:"'inci",5:"'inci",8:"'inci",70:"'inci",80:"'inci",2:"'nci",7:"'nci",20:"'nci",50:"'nci",3:"'\xfcnc\xfc",4:"'\xfcnc\xfc",100:"'\xfcnc\xfc",6:"'nc\u0131",9:"'uncu",10:"'uncu",30:"'uncu",60:"'\u0131nc\u0131",90:"'\u0131nc\u0131"};r.defineLocale("tr",{months:"Ocak_\u015eubat_Mart_Nisan_May\u0131s_Haziran_Temmuz_A\u011fustos_Eyl\xfcl_Ekim_Kas\u0131m_Aral\u0131k".split("_"),monthsShort:"Oca_\u015eub_Mar_Nis_May_Haz_Tem_A\u011fu_Eyl_Eki_Kas_Ara".split("_"),weekdays:"Pazar_Pazartesi_Sal\u0131_\xc7ar\u015famba_Per\u015fembe_Cuma_Cumartesi".split("_"),weekdaysShort:"Paz_Pzt_Sal_\xc7ar_Per_Cum_Cmt".split("_"),weekdaysMin:"Pz_Pt_Sa_\xc7a_Pe_Cu_Ct".split("_"),meridiem:function(d,e,_){return d<12?_?"\xf6\xf6":"\xd6\xd6":_?"\xf6s":"\xd6S"},meridiemParse:/\xf6\xf6|\xd6\xd6|\xf6s|\xd6S/,isPM:function(d){return"\xf6s"===d||"\xd6S"===d},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bug\xfcn saat] LT",nextDay:"[yar\u0131n saat] LT",nextWeek:"[gelecek] dddd [saat] LT",lastDay:"[d\xfcn] LT",lastWeek:"[ge\xe7en] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s \xf6nce",s:"birka\xe7 saniye",ss:"%d saniye",m:"bir dakika",mm:"%d dakika",h:"bir saat",hh:"%d saat",d:"bir g\xfcn",dd:"%d g\xfcn",w:"bir hafta",ww:"%d hafta",M:"bir ay",MM:"%d ay",y:"bir y\u0131l",yy:"%d y\u0131l"},ordinal:function(d,e){switch(e){case"d":case"D":case"Do":case"DD":return d;default:if(0===d)return d+"'\u0131nc\u0131";var _=d%10;return d+(u[_]||u[d%100-_]||u[d>=100?100:null])}},week:{dow:1,doy:7}})}(i(16738))},90875:function(v,T,i){!function(r){"use strict";function p(d,e,_,y){var S={s:["viensas secunds","'iensas secunds"],ss:[d+" secunds",d+" secunds"],m:["'n m\xedut","'iens m\xedut"],mm:[d+" m\xeduts",d+" m\xeduts"],h:["'n \xfeora","'iensa \xfeora"],hh:[d+" \xfeoras",d+" \xfeoras"],d:["'n ziua","'iensa ziua"],dd:[d+" ziuas",d+" ziuas"],M:["'n mes","'iens mes"],MM:[d+" mesen",d+" mesen"],y:["'n ar","'iens ar"],yy:[d+" ars",d+" ars"]};return y||e?S[_][0]:S[_][1]}r.defineLocale("tzl",{months:"Januar_Fevraglh_Mar\xe7_Avr\xefu_Mai_G\xfcn_Julia_Guscht_Setemvar_Listop\xe4ts_Noemvar_Zecemvar".split("_"),monthsShort:"Jan_Fev_Mar_Avr_Mai_G\xfcn_Jul_Gus_Set_Lis_Noe_Zec".split("_"),weekdays:"S\xfaladi_L\xfane\xe7i_Maitzi_M\xe1rcuri_Xh\xfaadi_Vi\xe9ner\xe7i_S\xe1turi".split("_"),weekdaysShort:"S\xfal_L\xfan_Mai_M\xe1r_Xh\xfa_Vi\xe9_S\xe1t".split("_"),weekdaysMin:"S\xfa_L\xfa_Ma_M\xe1_Xh_Vi_S\xe1".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"D. MMMM [dallas] YYYY",LLL:"D. MMMM [dallas] YYYY HH.mm",LLLL:"dddd, [li] D. MMMM [dallas] YYYY HH.mm"},meridiemParse:/d\'o|d\'a/i,isPM:function(d){return"d'o"===d.toLowerCase()},meridiem:function(d,e,_){return d>11?_?"d'o":"D'O":_?"d'a":"D'A"},calendar:{sameDay:"[oxhi \xe0] LT",nextDay:"[dem\xe0 \xe0] LT",nextWeek:"dddd [\xe0] LT",lastDay:"[ieiri \xe0] LT",lastWeek:"[s\xfcr el] dddd [lasteu \xe0] LT",sameElse:"L"},relativeTime:{future:"osprei %s",past:"ja%s",s:p,ss:p,m:p,mm:p,h:p,hh:p,d:p,dd:p,M:p,MM:p,y:p,yy:p},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(i(16738))},11041:function(v,T,i){!function(r){"use strict";r.defineLocale("tzm-latn",{months:"innayr_br\u02e4ayr\u02e4_mar\u02e4s\u02e4_ibrir_mayyw_ywnyw_ywlywz_\u0263w\u0161t_\u0161wtanbir_kt\u02e4wbr\u02e4_nwwanbir_dwjnbir".split("_"),monthsShort:"innayr_br\u02e4ayr\u02e4_mar\u02e4s\u02e4_ibrir_mayyw_ywnyw_ywlywz_\u0263w\u0161t_\u0161wtanbir_kt\u02e4wbr\u02e4_nwwanbir_dwjnbir".split("_"),weekdays:"asamas_aynas_asinas_akras_akwas_asimwas_asi\u1e0dyas".split("_"),weekdaysShort:"asamas_aynas_asinas_akras_akwas_asimwas_asi\u1e0dyas".split("_"),weekdaysMin:"asamas_aynas_asinas_akras_akwas_asimwas_asi\u1e0dyas".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[asdkh g] LT",nextDay:"[aska g] LT",nextWeek:"dddd [g] LT",lastDay:"[assant g] LT",lastWeek:"dddd [g] LT",sameElse:"L"},relativeTime:{future:"dadkh s yan %s",past:"yan %s",s:"imik",ss:"%d imik",m:"minu\u1e0d",mm:"%d minu\u1e0d",h:"sa\u025ba",hh:"%d tassa\u025bin",d:"ass",dd:"%d ossan",M:"ayowr",MM:"%d iyyirn",y:"asgas",yy:"%d isgasn"},week:{dow:6,doy:12}})}(i(16738))},16878:function(v,T,i){!function(r){"use strict";r.defineLocale("tzm",{months:"\u2d49\u2d4f\u2d4f\u2d30\u2d62\u2d54_\u2d31\u2d55\u2d30\u2d62\u2d55_\u2d4e\u2d30\u2d55\u2d5a_\u2d49\u2d31\u2d54\u2d49\u2d54_\u2d4e\u2d30\u2d62\u2d62\u2d53_\u2d62\u2d53\u2d4f\u2d62\u2d53_\u2d62\u2d53\u2d4d\u2d62\u2d53\u2d63_\u2d56\u2d53\u2d5b\u2d5c_\u2d5b\u2d53\u2d5c\u2d30\u2d4f\u2d31\u2d49\u2d54_\u2d3d\u2d5f\u2d53\u2d31\u2d55_\u2d4f\u2d53\u2d61\u2d30\u2d4f\u2d31\u2d49\u2d54_\u2d37\u2d53\u2d4a\u2d4f\u2d31\u2d49\u2d54".split("_"),monthsShort:"\u2d49\u2d4f\u2d4f\u2d30\u2d62\u2d54_\u2d31\u2d55\u2d30\u2d62\u2d55_\u2d4e\u2d30\u2d55\u2d5a_\u2d49\u2d31\u2d54\u2d49\u2d54_\u2d4e\u2d30\u2d62\u2d62\u2d53_\u2d62\u2d53\u2d4f\u2d62\u2d53_\u2d62\u2d53\u2d4d\u2d62\u2d53\u2d63_\u2d56\u2d53\u2d5b\u2d5c_\u2d5b\u2d53\u2d5c\u2d30\u2d4f\u2d31\u2d49\u2d54_\u2d3d\u2d5f\u2d53\u2d31\u2d55_\u2d4f\u2d53\u2d61\u2d30\u2d4f\u2d31\u2d49\u2d54_\u2d37\u2d53\u2d4a\u2d4f\u2d31\u2d49\u2d54".split("_"),weekdays:"\u2d30\u2d59\u2d30\u2d4e\u2d30\u2d59_\u2d30\u2d62\u2d4f\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4f\u2d30\u2d59_\u2d30\u2d3d\u2d54\u2d30\u2d59_\u2d30\u2d3d\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4e\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d39\u2d62\u2d30\u2d59".split("_"),weekdaysShort:"\u2d30\u2d59\u2d30\u2d4e\u2d30\u2d59_\u2d30\u2d62\u2d4f\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4f\u2d30\u2d59_\u2d30\u2d3d\u2d54\u2d30\u2d59_\u2d30\u2d3d\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4e\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d39\u2d62\u2d30\u2d59".split("_"),weekdaysMin:"\u2d30\u2d59\u2d30\u2d4e\u2d30\u2d59_\u2d30\u2d62\u2d4f\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4f\u2d30\u2d59_\u2d30\u2d3d\u2d54\u2d30\u2d59_\u2d30\u2d3d\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4e\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d39\u2d62\u2d30\u2d59".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u2d30\u2d59\u2d37\u2d45 \u2d34] LT",nextDay:"[\u2d30\u2d59\u2d3d\u2d30 \u2d34] LT",nextWeek:"dddd [\u2d34] LT",lastDay:"[\u2d30\u2d5a\u2d30\u2d4f\u2d5c \u2d34] LT",lastWeek:"dddd [\u2d34] LT",sameElse:"L"},relativeTime:{future:"\u2d37\u2d30\u2d37\u2d45 \u2d59 \u2d62\u2d30\u2d4f %s",past:"\u2d62\u2d30\u2d4f %s",s:"\u2d49\u2d4e\u2d49\u2d3d",ss:"%d \u2d49\u2d4e\u2d49\u2d3d",m:"\u2d4e\u2d49\u2d4f\u2d53\u2d3a",mm:"%d \u2d4e\u2d49\u2d4f\u2d53\u2d3a",h:"\u2d59\u2d30\u2d44\u2d30",hh:"%d \u2d5c\u2d30\u2d59\u2d59\u2d30\u2d44\u2d49\u2d4f",d:"\u2d30\u2d59\u2d59",dd:"%d o\u2d59\u2d59\u2d30\u2d4f",M:"\u2d30\u2d62o\u2d53\u2d54",MM:"%d \u2d49\u2d62\u2d62\u2d49\u2d54\u2d4f",y:"\u2d30\u2d59\u2d33\u2d30\u2d59",yy:"%d \u2d49\u2d59\u2d33\u2d30\u2d59\u2d4f"},week:{dow:6,doy:12}})}(i(16738))},74357:function(v,T,i){!function(r){"use strict";r.defineLocale("ug-cn",{months:"\u064a\u0627\u0646\u06cb\u0627\u0631_\u0641\u06d0\u06cb\u0631\u0627\u0644_\u0645\u0627\u0631\u062a_\u0626\u0627\u067e\u0631\u06d0\u0644_\u0645\u0627\u064a_\u0626\u0649\u064a\u06c7\u0646_\u0626\u0649\u064a\u06c7\u0644_\u0626\u0627\u06cb\u063a\u06c7\u0633\u062a_\u0633\u06d0\u0646\u062a\u06d5\u0628\u0649\u0631_\u0626\u06c6\u0643\u062a\u06d5\u0628\u0649\u0631_\u0646\u0648\u064a\u0627\u0628\u0649\u0631_\u062f\u06d0\u0643\u0627\u0628\u0649\u0631".split("_"),monthsShort:"\u064a\u0627\u0646\u06cb\u0627\u0631_\u0641\u06d0\u06cb\u0631\u0627\u0644_\u0645\u0627\u0631\u062a_\u0626\u0627\u067e\u0631\u06d0\u0644_\u0645\u0627\u064a_\u0626\u0649\u064a\u06c7\u0646_\u0626\u0649\u064a\u06c7\u0644_\u0626\u0627\u06cb\u063a\u06c7\u0633\u062a_\u0633\u06d0\u0646\u062a\u06d5\u0628\u0649\u0631_\u0626\u06c6\u0643\u062a\u06d5\u0628\u0649\u0631_\u0646\u0648\u064a\u0627\u0628\u0649\u0631_\u062f\u06d0\u0643\u0627\u0628\u0649\u0631".split("_"),weekdays:"\u064a\u06d5\u0643\u0634\u06d5\u0646\u0628\u06d5_\u062f\u06c8\u0634\u06d5\u0646\u0628\u06d5_\u0633\u06d5\u064a\u0634\u06d5\u0646\u0628\u06d5_\u0686\u0627\u0631\u0634\u06d5\u0646\u0628\u06d5_\u067e\u06d5\u064a\u0634\u06d5\u0646\u0628\u06d5_\u062c\u06c8\u0645\u06d5_\u0634\u06d5\u0646\u0628\u06d5".split("_"),weekdaysShort:"\u064a\u06d5_\u062f\u06c8_\u0633\u06d5_\u0686\u0627_\u067e\u06d5_\u062c\u06c8_\u0634\u06d5".split("_"),weekdaysMin:"\u064a\u06d5_\u062f\u06c8_\u0633\u06d5_\u0686\u0627_\u067e\u06d5_\u062c\u06c8_\u0634\u06d5".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY-\u064a\u0649\u0644\u0649M-\u0626\u0627\u064a\u0646\u0649\u06adD-\u0643\u06c8\u0646\u0649",LLL:"YYYY-\u064a\u0649\u0644\u0649M-\u0626\u0627\u064a\u0646\u0649\u06adD-\u0643\u06c8\u0646\u0649\u060c HH:mm",LLLL:"dddd\u060c YYYY-\u064a\u0649\u0644\u0649M-\u0626\u0627\u064a\u0646\u0649\u06adD-\u0643\u06c8\u0646\u0649\u060c HH:mm"},meridiemParse:/\u064a\u06d0\u0631\u0649\u0645 \u0643\u06d0\u0686\u06d5|\u0633\u06d5\u06be\u06d5\u0631|\u0686\u06c8\u0634\u062a\u0649\u0646 \u0628\u06c7\u0631\u06c7\u0646|\u0686\u06c8\u0634|\u0686\u06c8\u0634\u062a\u0649\u0646 \u0643\u06d0\u064a\u0649\u0646|\u0643\u06d5\u0686/,meridiemHour:function(p,d){return 12===p&&(p=0),"\u064a\u06d0\u0631\u0649\u0645 \u0643\u06d0\u0686\u06d5"===d||"\u0633\u06d5\u06be\u06d5\u0631"===d||"\u0686\u06c8\u0634\u062a\u0649\u0646 \u0628\u06c7\u0631\u06c7\u0646"===d?p:"\u0686\u06c8\u0634\u062a\u0649\u0646 \u0643\u06d0\u064a\u0649\u0646"===d||"\u0643\u06d5\u0686"===d?p+12:p>=11?p:p+12},meridiem:function(p,d,e){var _=100*p+d;return _<600?"\u064a\u06d0\u0631\u0649\u0645 \u0643\u06d0\u0686\u06d5":_<900?"\u0633\u06d5\u06be\u06d5\u0631":_<1130?"\u0686\u06c8\u0634\u062a\u0649\u0646 \u0628\u06c7\u0631\u06c7\u0646":_<1230?"\u0686\u06c8\u0634":_<1800?"\u0686\u06c8\u0634\u062a\u0649\u0646 \u0643\u06d0\u064a\u0649\u0646":"\u0643\u06d5\u0686"},calendar:{sameDay:"[\u0628\u06c8\u06af\u06c8\u0646 \u0633\u0627\u0626\u06d5\u062a] LT",nextDay:"[\u0626\u06d5\u062a\u06d5 \u0633\u0627\u0626\u06d5\u062a] LT",nextWeek:"[\u0643\u06d0\u0644\u06d5\u0631\u0643\u0649] dddd [\u0633\u0627\u0626\u06d5\u062a] LT",lastDay:"[\u062a\u06c6\u0646\u06c8\u06af\u06c8\u0646] LT",lastWeek:"[\u0626\u0627\u0644\u062f\u0649\u0646\u0642\u0649] dddd [\u0633\u0627\u0626\u06d5\u062a] LT",sameElse:"L"},relativeTime:{future:"%s \u0643\u06d0\u064a\u0649\u0646",past:"%s \u0628\u06c7\u0631\u06c7\u0646",s:"\u0646\u06d5\u0686\u0686\u06d5 \u0633\u06d0\u0643\u0648\u0646\u062a",ss:"%d \u0633\u06d0\u0643\u0648\u0646\u062a",m:"\u0628\u0649\u0631 \u0645\u0649\u0646\u06c7\u062a",mm:"%d \u0645\u0649\u0646\u06c7\u062a",h:"\u0628\u0649\u0631 \u0633\u0627\u0626\u06d5\u062a",hh:"%d \u0633\u0627\u0626\u06d5\u062a",d:"\u0628\u0649\u0631 \u0643\u06c8\u0646",dd:"%d \u0643\u06c8\u0646",M:"\u0628\u0649\u0631 \u0626\u0627\u064a",MM:"%d \u0626\u0627\u064a",y:"\u0628\u0649\u0631 \u064a\u0649\u0644",yy:"%d \u064a\u0649\u0644"},dayOfMonthOrdinalParse:/\d{1,2}(-\u0643\u06c8\u0646\u0649|-\u0626\u0627\u064a|-\u06be\u06d5\u067e\u062a\u06d5)/,ordinal:function(p,d){switch(d){case"d":case"D":case"DDD":return p+"-\u0643\u06c8\u0646\u0649";case"w":case"W":return p+"-\u06be\u06d5\u067e\u062a\u06d5";default:return p}},preparse:function(p){return p.replace(/\u060c/g,",")},postformat:function(p){return p.replace(/,/g,"\u060c")},week:{dow:1,doy:7}})}(i(16738))},74810:function(v,T,i){!function(r){"use strict";function p(y,S,A){return"m"===A?S?"\u0445\u0432\u0438\u043b\u0438\u043d\u0430":"\u0445\u0432\u0438\u043b\u0438\u043d\u0443":"h"===A?S?"\u0433\u043e\u0434\u0438\u043d\u0430":"\u0433\u043e\u0434\u0438\u043d\u0443":y+" "+function(y,S){var A=y.split("_");return S%10==1&&S%100!=11?A[0]:S%10>=2&&S%10<=4&&(S%100<10||S%100>=20)?A[1]:A[2]}({ss:S?"\u0441\u0435\u043a\u0443\u043d\u0434\u0430_\u0441\u0435\u043a\u0443\u043d\u0434\u0438_\u0441\u0435\u043a\u0443\u043d\u0434":"\u0441\u0435\u043a\u0443\u043d\u0434\u0443_\u0441\u0435\u043a\u0443\u043d\u0434\u0438_\u0441\u0435\u043a\u0443\u043d\u0434",mm:S?"\u0445\u0432\u0438\u043b\u0438\u043d\u0430_\u0445\u0432\u0438\u043b\u0438\u043d\u0438_\u0445\u0432\u0438\u043b\u0438\u043d":"\u0445\u0432\u0438\u043b\u0438\u043d\u0443_\u0445\u0432\u0438\u043b\u0438\u043d\u0438_\u0445\u0432\u0438\u043b\u0438\u043d",hh:S?"\u0433\u043e\u0434\u0438\u043d\u0430_\u0433\u043e\u0434\u0438\u043d\u0438_\u0433\u043e\u0434\u0438\u043d":"\u0433\u043e\u0434\u0438\u043d\u0443_\u0433\u043e\u0434\u0438\u043d\u0438_\u0433\u043e\u0434\u0438\u043d",dd:"\u0434\u0435\u043d\u044c_\u0434\u043d\u0456_\u0434\u043d\u0456\u0432",MM:"\u043c\u0456\u0441\u044f\u0446\u044c_\u043c\u0456\u0441\u044f\u0446\u0456_\u043c\u0456\u0441\u044f\u0446\u0456\u0432",yy:"\u0440\u0456\u043a_\u0440\u043e\u043a\u0438_\u0440\u043e\u043a\u0456\u0432"}[A],+y)}function e(y){return function(){return y+"\u043e"+(11===this.hours()?"\u0431":"")+"] LT"}}r.defineLocale("uk",{months:{format:"\u0441\u0456\u0447\u043d\u044f_\u043b\u044e\u0442\u043e\u0433\u043e_\u0431\u0435\u0440\u0435\u0437\u043d\u044f_\u043a\u0432\u0456\u0442\u043d\u044f_\u0442\u0440\u0430\u0432\u043d\u044f_\u0447\u0435\u0440\u0432\u043d\u044f_\u043b\u0438\u043f\u043d\u044f_\u0441\u0435\u0440\u043f\u043d\u044f_\u0432\u0435\u0440\u0435\u0441\u043d\u044f_\u0436\u043e\u0432\u0442\u043d\u044f_\u043b\u0438\u0441\u0442\u043e\u043f\u0430\u0434\u0430_\u0433\u0440\u0443\u0434\u043d\u044f".split("_"),standalone:"\u0441\u0456\u0447\u0435\u043d\u044c_\u043b\u044e\u0442\u0438\u0439_\u0431\u0435\u0440\u0435\u0437\u0435\u043d\u044c_\u043a\u0432\u0456\u0442\u0435\u043d\u044c_\u0442\u0440\u0430\u0432\u0435\u043d\u044c_\u0447\u0435\u0440\u0432\u0435\u043d\u044c_\u043b\u0438\u043f\u0435\u043d\u044c_\u0441\u0435\u0440\u043f\u0435\u043d\u044c_\u0432\u0435\u0440\u0435\u0441\u0435\u043d\u044c_\u0436\u043e\u0432\u0442\u0435\u043d\u044c_\u043b\u0438\u0441\u0442\u043e\u043f\u0430\u0434_\u0433\u0440\u0443\u0434\u0435\u043d\u044c".split("_")},monthsShort:"\u0441\u0456\u0447_\u043b\u044e\u0442_\u0431\u0435\u0440_\u043a\u0432\u0456\u0442_\u0442\u0440\u0430\u0432_\u0447\u0435\u0440\u0432_\u043b\u0438\u043f_\u0441\u0435\u0440\u043f_\u0432\u0435\u0440_\u0436\u043e\u0432\u0442_\u043b\u0438\u0441\u0442_\u0433\u0440\u0443\u0434".split("_"),weekdays:function(y,S){var A={nominative:"\u043d\u0435\u0434\u0456\u043b\u044f_\u043f\u043e\u043d\u0435\u0434\u0456\u043b\u043e\u043a_\u0432\u0456\u0432\u0442\u043e\u0440\u043e\u043a_\u0441\u0435\u0440\u0435\u0434\u0430_\u0447\u0435\u0442\u0432\u0435\u0440_\u043f\u2019\u044f\u0442\u043d\u0438\u0446\u044f_\u0441\u0443\u0431\u043e\u0442\u0430".split("_"),accusative:"\u043d\u0435\u0434\u0456\u043b\u044e_\u043f\u043e\u043d\u0435\u0434\u0456\u043b\u043e\u043a_\u0432\u0456\u0432\u0442\u043e\u0440\u043e\u043a_\u0441\u0435\u0440\u0435\u0434\u0443_\u0447\u0435\u0442\u0432\u0435\u0440_\u043f\u2019\u044f\u0442\u043d\u0438\u0446\u044e_\u0441\u0443\u0431\u043e\u0442\u0443".split("_"),genitive:"\u043d\u0435\u0434\u0456\u043b\u0456_\u043f\u043e\u043d\u0435\u0434\u0456\u043b\u043a\u0430_\u0432\u0456\u0432\u0442\u043e\u0440\u043a\u0430_\u0441\u0435\u0440\u0435\u0434\u0438_\u0447\u0435\u0442\u0432\u0435\u0440\u0433\u0430_\u043f\u2019\u044f\u0442\u043d\u0438\u0446\u0456_\u0441\u0443\u0431\u043e\u0442\u0438".split("_")};return!0===y?A.nominative.slice(1,7).concat(A.nominative.slice(0,1)):y?A[/(\[[\u0412\u0432\u0423\u0443]\]) ?dddd/.test(S)?"accusative":/\[?(?:\u043c\u0438\u043d\u0443\u043b\u043e\u0457|\u043d\u0430\u0441\u0442\u0443\u043f\u043d\u043e\u0457)? ?\] ?dddd/.test(S)?"genitive":"nominative"][y.day()]:A.nominative},weekdaysShort:"\u043d\u0434_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),weekdaysMin:"\u043d\u0434_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY \u0440.",LLL:"D MMMM YYYY \u0440., HH:mm",LLLL:"dddd, D MMMM YYYY \u0440., HH:mm"},calendar:{sameDay:e("[\u0421\u044c\u043e\u0433\u043e\u0434\u043d\u0456 "),nextDay:e("[\u0417\u0430\u0432\u0442\u0440\u0430 "),lastDay:e("[\u0412\u0447\u043e\u0440\u0430 "),nextWeek:e("[\u0423] dddd ["),lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return e("[\u041c\u0438\u043d\u0443\u043b\u043e\u0457] dddd [").call(this);case 1:case 2:case 4:return e("[\u041c\u0438\u043d\u0443\u043b\u043e\u0433\u043e] dddd [").call(this)}},sameElse:"L"},relativeTime:{future:"\u0437\u0430 %s",past:"%s \u0442\u043e\u043c\u0443",s:"\u0434\u0435\u043a\u0456\u043b\u044c\u043a\u0430 \u0441\u0435\u043a\u0443\u043d\u0434",ss:p,m:p,mm:p,h:"\u0433\u043e\u0434\u0438\u043d\u0443",hh:p,d:"\u0434\u0435\u043d\u044c",dd:p,M:"\u043c\u0456\u0441\u044f\u0446\u044c",MM:p,y:"\u0440\u0456\u043a",yy:p},meridiemParse:/\u043d\u043e\u0447\u0456|\u0440\u0430\u043d\u043a\u0443|\u0434\u043d\u044f|\u0432\u0435\u0447\u043e\u0440\u0430/,isPM:function(y){return/^(\u0434\u043d\u044f|\u0432\u0435\u0447\u043e\u0440\u0430)$/.test(y)},meridiem:function(y,S,A){return y<4?"\u043d\u043e\u0447\u0456":y<12?"\u0440\u0430\u043d\u043a\u0443":y<17?"\u0434\u043d\u044f":"\u0432\u0435\u0447\u043e\u0440\u0430"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0439|\u0433\u043e)/,ordinal:function(y,S){switch(S){case"M":case"d":case"DDD":case"w":case"W":return y+"-\u0439";case"D":return y+"-\u0433\u043e";default:return y}},week:{dow:1,doy:7}})}(i(16738))},86794:function(v,T,i){!function(r){"use strict";var u=["\u062c\u0646\u0648\u0631\u06cc","\u0641\u0631\u0648\u0631\u06cc","\u0645\u0627\u0631\u0686","\u0627\u067e\u0631\u06cc\u0644","\u0645\u0626\u06cc","\u062c\u0648\u0646","\u062c\u0648\u0644\u0627\u0626\u06cc","\u0627\u06af\u0633\u062a","\u0633\u062a\u0645\u0628\u0631","\u0627\u06a9\u062a\u0648\u0628\u0631","\u0646\u0648\u0645\u0628\u0631","\u062f\u0633\u0645\u0628\u0631"],p=["\u0627\u062a\u0648\u0627\u0631","\u067e\u06cc\u0631","\u0645\u0646\u06af\u0644","\u0628\u062f\u06be","\u062c\u0645\u0639\u0631\u0627\u062a","\u062c\u0645\u0639\u06c1","\u06c1\u0641\u062a\u06c1"];r.defineLocale("ur",{months:u,monthsShort:u,weekdays:p,weekdaysShort:p,weekdaysMin:p,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd\u060c D MMMM YYYY HH:mm"},meridiemParse:/\u0635\u0628\u062d|\u0634\u0627\u0645/,isPM:function(e){return"\u0634\u0627\u0645"===e},meridiem:function(e,_,y){return e<12?"\u0635\u0628\u062d":"\u0634\u0627\u0645"},calendar:{sameDay:"[\u0622\u062c \u0628\u0648\u0642\u062a] LT",nextDay:"[\u06a9\u0644 \u0628\u0648\u0642\u062a] LT",nextWeek:"dddd [\u0628\u0648\u0642\u062a] LT",lastDay:"[\u06af\u0630\u0634\u062a\u06c1 \u0631\u0648\u0632 \u0628\u0648\u0642\u062a] LT",lastWeek:"[\u06af\u0630\u0634\u062a\u06c1] dddd [\u0628\u0648\u0642\u062a] LT",sameElse:"L"},relativeTime:{future:"%s \u0628\u0639\u062f",past:"%s \u0642\u0628\u0644",s:"\u0686\u0646\u062f \u0633\u06cc\u06a9\u0646\u0688",ss:"%d \u0633\u06cc\u06a9\u0646\u0688",m:"\u0627\u06cc\u06a9 \u0645\u0646\u0679",mm:"%d \u0645\u0646\u0679",h:"\u0627\u06cc\u06a9 \u06af\u06be\u0646\u0679\u06c1",hh:"%d \u06af\u06be\u0646\u0679\u06d2",d:"\u0627\u06cc\u06a9 \u062f\u0646",dd:"%d \u062f\u0646",M:"\u0627\u06cc\u06a9 \u0645\u0627\u06c1",MM:"%d \u0645\u0627\u06c1",y:"\u0627\u06cc\u06a9 \u0633\u0627\u0644",yy:"%d \u0633\u0627\u0644"},preparse:function(e){return e.replace(/\u060c/g,",")},postformat:function(e){return e.replace(/,/g,"\u060c")},week:{dow:1,doy:4}})}(i(16738))},77959:function(v,T,i){!function(r){"use strict";r.defineLocale("uz-latn",{months:"Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr".split("_"),monthsShort:"Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek".split("_"),weekdays:"Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba".split("_"),weekdaysShort:"Yak_Dush_Sesh_Chor_Pay_Jum_Shan".split("_"),weekdaysMin:"Ya_Du_Se_Cho_Pa_Ju_Sha".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"D MMMM YYYY, dddd HH:mm"},calendar:{sameDay:"[Bugun soat] LT [da]",nextDay:"[Ertaga] LT [da]",nextWeek:"dddd [kuni soat] LT [da]",lastDay:"[Kecha soat] LT [da]",lastWeek:"[O'tgan] dddd [kuni soat] LT [da]",sameElse:"L"},relativeTime:{future:"Yaqin %s ichida",past:"Bir necha %s oldin",s:"soniya",ss:"%d soniya",m:"bir daqiqa",mm:"%d daqiqa",h:"bir soat",hh:"%d soat",d:"bir kun",dd:"%d kun",M:"bir oy",MM:"%d oy",y:"bir yil",yy:"%d yil"},week:{dow:1,doy:7}})}(i(16738))},28966:function(v,T,i){!function(r){"use strict";r.defineLocale("uz",{months:"\u044f\u043d\u0432\u0430\u0440_\u0444\u0435\u0432\u0440\u0430\u043b_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0435\u043b_\u043c\u0430\u0439_\u0438\u044e\u043d_\u0438\u044e\u043b_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043d\u0442\u044f\u0431\u0440_\u043e\u043a\u0442\u044f\u0431\u0440_\u043d\u043e\u044f\u0431\u0440_\u0434\u0435\u043a\u0430\u0431\u0440".split("_"),monthsShort:"\u044f\u043d\u0432_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0439_\u0438\u044e\u043d_\u0438\u044e\u043b_\u0430\u0432\u0433_\u0441\u0435\u043d_\u043e\u043a\u0442_\u043d\u043e\u044f_\u0434\u0435\u043a".split("_"),weekdays:"\u042f\u043a\u0448\u0430\u043d\u0431\u0430_\u0414\u0443\u0448\u0430\u043d\u0431\u0430_\u0421\u0435\u0448\u0430\u043d\u0431\u0430_\u0427\u043e\u0440\u0448\u0430\u043d\u0431\u0430_\u041f\u0430\u0439\u0448\u0430\u043d\u0431\u0430_\u0416\u0443\u043c\u0430_\u0428\u0430\u043d\u0431\u0430".split("_"),weekdaysShort:"\u042f\u043a\u0448_\u0414\u0443\u0448_\u0421\u0435\u0448_\u0427\u043e\u0440_\u041f\u0430\u0439_\u0416\u0443\u043c_\u0428\u0430\u043d".split("_"),weekdaysMin:"\u042f\u043a_\u0414\u0443_\u0421\u0435_\u0427\u043e_\u041f\u0430_\u0416\u0443_\u0428\u0430".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"D MMMM YYYY, dddd HH:mm"},calendar:{sameDay:"[\u0411\u0443\u0433\u0443\u043d \u0441\u043e\u0430\u0442] LT [\u0434\u0430]",nextDay:"[\u042d\u0440\u0442\u0430\u0433\u0430] LT [\u0434\u0430]",nextWeek:"dddd [\u043a\u0443\u043d\u0438 \u0441\u043e\u0430\u0442] LT [\u0434\u0430]",lastDay:"[\u041a\u0435\u0447\u0430 \u0441\u043e\u0430\u0442] LT [\u0434\u0430]",lastWeek:"[\u0423\u0442\u0433\u0430\u043d] dddd [\u043a\u0443\u043d\u0438 \u0441\u043e\u0430\u0442] LT [\u0434\u0430]",sameElse:"L"},relativeTime:{future:"\u042f\u043a\u0438\u043d %s \u0438\u0447\u0438\u0434\u0430",past:"\u0411\u0438\u0440 \u043d\u0435\u0447\u0430 %s \u043e\u043b\u0434\u0438\u043d",s:"\u0444\u0443\u0440\u0441\u0430\u0442",ss:"%d \u0444\u0443\u0440\u0441\u0430\u0442",m:"\u0431\u0438\u0440 \u0434\u0430\u043a\u0438\u043a\u0430",mm:"%d \u0434\u0430\u043a\u0438\u043a\u0430",h:"\u0431\u0438\u0440 \u0441\u043e\u0430\u0442",hh:"%d \u0441\u043e\u0430\u0442",d:"\u0431\u0438\u0440 \u043a\u0443\u043d",dd:"%d \u043a\u0443\u043d",M:"\u0431\u0438\u0440 \u043e\u0439",MM:"%d \u043e\u0439",y:"\u0431\u0438\u0440 \u0439\u0438\u043b",yy:"%d \u0439\u0438\u043b"},week:{dow:1,doy:7}})}(i(16738))},35386:function(v,T,i){!function(r){"use strict";r.defineLocale("vi",{months:"th\xe1ng 1_th\xe1ng 2_th\xe1ng 3_th\xe1ng 4_th\xe1ng 5_th\xe1ng 6_th\xe1ng 7_th\xe1ng 8_th\xe1ng 9_th\xe1ng 10_th\xe1ng 11_th\xe1ng 12".split("_"),monthsShort:"Thg 01_Thg 02_Thg 03_Thg 04_Thg 05_Thg 06_Thg 07_Thg 08_Thg 09_Thg 10_Thg 11_Thg 12".split("_"),monthsParseExact:!0,weekdays:"ch\u1ee7 nh\u1eadt_th\u1ee9 hai_th\u1ee9 ba_th\u1ee9 t\u01b0_th\u1ee9 n\u0103m_th\u1ee9 s\xe1u_th\u1ee9 b\u1ea3y".split("_"),weekdaysShort:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysMin:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysParseExact:!0,meridiemParse:/sa|ch/i,isPM:function(p){return/^ch$/i.test(p)},meridiem:function(p,d,e){return p<12?e?"sa":"SA":e?"ch":"CH"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [n\u0103m] YYYY",LLL:"D MMMM [n\u0103m] YYYY HH:mm",LLLL:"dddd, D MMMM [n\u0103m] YYYY HH:mm",l:"DD/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[H\xf4m nay l\xfac] LT",nextDay:"[Ng\xe0y mai l\xfac] LT",nextWeek:"dddd [tu\u1ea7n t\u1edbi l\xfac] LT",lastDay:"[H\xf4m qua l\xfac] LT",lastWeek:"dddd [tu\u1ea7n tr\u01b0\u1edbc l\xfac] LT",sameElse:"L"},relativeTime:{future:"%s t\u1edbi",past:"%s tr\u01b0\u1edbc",s:"v\xe0i gi\xe2y",ss:"%d gi\xe2y",m:"m\u1ed9t ph\xfat",mm:"%d ph\xfat",h:"m\u1ed9t gi\u1edd",hh:"%d gi\u1edd",d:"m\u1ed9t ng\xe0y",dd:"%d ng\xe0y",w:"m\u1ed9t tu\u1ea7n",ww:"%d tu\u1ea7n",M:"m\u1ed9t th\xe1ng",MM:"%d th\xe1ng",y:"m\u1ed9t n\u0103m",yy:"%d n\u0103m"},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:function(p){return p},week:{dow:1,doy:4}})}(i(16738))},23156:function(v,T,i){!function(r){"use strict";r.defineLocale("x-pseudo",{months:"J~\xe1\xf1\xfa\xe1~r\xfd_F~\xe9br\xfa~\xe1r\xfd_~M\xe1rc~h_\xc1p~r\xedl_~M\xe1\xfd_~J\xfa\xf1\xe9~_J\xfal~\xfd_\xc1\xfa~g\xfast~_S\xe9p~t\xe9mb~\xe9r_\xd3~ct\xf3b~\xe9r_\xd1~\xf3v\xe9m~b\xe9r_~D\xe9c\xe9~mb\xe9r".split("_"),monthsShort:"J~\xe1\xf1_~F\xe9b_~M\xe1r_~\xc1pr_~M\xe1\xfd_~J\xfa\xf1_~J\xfal_~\xc1\xfag_~S\xe9p_~\xd3ct_~\xd1\xf3v_~D\xe9c".split("_"),monthsParseExact:!0,weekdays:"S~\xfa\xf1d\xe1~\xfd_M\xf3~\xf1d\xe1\xfd~_T\xfa\xe9~sd\xe1\xfd~_W\xe9d~\xf1\xe9sd~\xe1\xfd_T~h\xfars~d\xe1\xfd_~Fr\xedd~\xe1\xfd_S~\xe1t\xfar~d\xe1\xfd".split("_"),weekdaysShort:"S~\xfa\xf1_~M\xf3\xf1_~T\xfa\xe9_~W\xe9d_~Th\xfa_~Fr\xed_~S\xe1t".split("_"),weekdaysMin:"S~\xfa_M\xf3~_T\xfa_~W\xe9_T~h_Fr~_S\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[T~\xf3d\xe1~\xfd \xe1t] LT",nextDay:"[T~\xf3m\xf3~rr\xf3~w \xe1t] LT",nextWeek:"dddd [\xe1t] LT",lastDay:"[\xdd~\xe9st~\xe9rd\xe1~\xfd \xe1t] LT",lastWeek:"[L~\xe1st] dddd [\xe1t] LT",sameElse:"L"},relativeTime:{future:"\xed~\xf1 %s",past:"%s \xe1~g\xf3",s:"\xe1 ~f\xe9w ~s\xe9c\xf3~\xf1ds",ss:"%d s~\xe9c\xf3\xf1~ds",m:"\xe1 ~m\xed\xf1~\xfat\xe9",mm:"%d m~\xed\xf1\xfa~t\xe9s",h:"\xe1~\xf1 h\xf3~\xfar",hh:"%d h~\xf3\xfars",d:"\xe1 ~d\xe1\xfd",dd:"%d d~\xe1\xfds",M:"\xe1 ~m\xf3\xf1~th",MM:"%d m~\xf3\xf1t~hs",y:"\xe1 ~\xfd\xe9\xe1r",yy:"%d \xfd~\xe9\xe1rs"},dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(p){var d=p%10;return p+(1==~~(p%100/10)?"th":1===d?"st":2===d?"nd":3===d?"rd":"th")},week:{dow:1,doy:4}})}(i(16738))},68028:function(v,T,i){!function(r){"use strict";r.defineLocale("yo",{months:"S\u1eb9\u0301r\u1eb9\u0301_E\u0300re\u0300le\u0300_\u1eb8r\u1eb9\u0300na\u0300_I\u0300gbe\u0301_E\u0300bibi_O\u0300ku\u0300du_Ag\u1eb9mo_O\u0300gu\u0301n_Owewe_\u1ecc\u0300wa\u0300ra\u0300_Be\u0301lu\u0301_\u1ecc\u0300p\u1eb9\u0300\u0300".split("_"),monthsShort:"S\u1eb9\u0301r_E\u0300rl_\u1eb8rn_I\u0300gb_E\u0300bi_O\u0300ku\u0300_Ag\u1eb9_O\u0300gu\u0301_Owe_\u1ecc\u0300wa\u0300_Be\u0301l_\u1ecc\u0300p\u1eb9\u0300\u0300".split("_"),weekdays:"A\u0300i\u0300ku\u0301_Aje\u0301_I\u0300s\u1eb9\u0301gun_\u1eccj\u1ecd\u0301ru\u0301_\u1eccj\u1ecd\u0301b\u1ecd_\u1eb8ti\u0300_A\u0300ba\u0301m\u1eb9\u0301ta".split("_"),weekdaysShort:"A\u0300i\u0300k_Aje\u0301_I\u0300s\u1eb9\u0301_\u1eccjr_\u1eccjb_\u1eb8ti\u0300_A\u0300ba\u0301".split("_"),weekdaysMin:"A\u0300i\u0300_Aj_I\u0300s_\u1eccr_\u1eccb_\u1eb8t_A\u0300b".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[O\u0300ni\u0300 ni] LT",nextDay:"[\u1ecc\u0300la ni] LT",nextWeek:"dddd [\u1eccs\u1eb9\u0300 to\u0301n'b\u1ecd] [ni] LT",lastDay:"[A\u0300na ni] LT",lastWeek:"dddd [\u1eccs\u1eb9\u0300 to\u0301l\u1ecd\u0301] [ni] LT",sameElse:"L"},relativeTime:{future:"ni\u0301 %s",past:"%s k\u1ecdja\u0301",s:"i\u0300s\u1eb9ju\u0301 aaya\u0301 die",ss:"aaya\u0301 %d",m:"i\u0300s\u1eb9ju\u0301 kan",mm:"i\u0300s\u1eb9ju\u0301 %d",h:"wa\u0301kati kan",hh:"wa\u0301kati %d",d:"\u1ecdj\u1ecd\u0301 kan",dd:"\u1ecdj\u1ecd\u0301 %d",M:"osu\u0300 kan",MM:"osu\u0300 %d",y:"\u1ecddu\u0301n kan",yy:"\u1ecddu\u0301n %d"},dayOfMonthOrdinalParse:/\u1ecdj\u1ecd\u0301\s\d{1,2}/,ordinal:"\u1ecdj\u1ecd\u0301 %d",week:{dow:1,doy:4}})}(i(16738))},9330:function(v,T,i){!function(r){"use strict";r.defineLocale("zh-cn",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u5468\u65e5_\u5468\u4e00_\u5468\u4e8c_\u5468\u4e09_\u5468\u56db_\u5468\u4e94_\u5468\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5Ah\u70b9mm\u5206",LLLL:"YYYY\u5e74M\u6708D\u65e5ddddAh\u70b9mm\u5206",l:"YYYY/M/D",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm"},meridiemParse:/\u51cc\u6668|\u65e9\u4e0a|\u4e0a\u5348|\u4e2d\u5348|\u4e0b\u5348|\u665a\u4e0a/,meridiemHour:function(p,d){return 12===p&&(p=0),"\u51cc\u6668"===d||"\u65e9\u4e0a"===d||"\u4e0a\u5348"===d?p:"\u4e0b\u5348"===d||"\u665a\u4e0a"===d?p+12:p>=11?p:p+12},meridiem:function(p,d,e){var _=100*p+d;return _<600?"\u51cc\u6668":_<900?"\u65e9\u4e0a":_<1130?"\u4e0a\u5348":_<1230?"\u4e2d\u5348":_<1800?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:function(p){return p.week()!==this.week()?"[\u4e0b]dddLT":"[\u672c]dddLT"},lastDay:"[\u6628\u5929]LT",lastWeek:function(p){return this.week()!==p.week()?"[\u4e0a]dddLT":"[\u672c]dddLT"},sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(\u65e5|\u6708|\u5468)/,ordinal:function(p,d){switch(d){case"d":case"D":case"DDD":return p+"\u65e5";case"M":return p+"\u6708";case"w":case"W":return p+"\u5468";default:return p}},relativeTime:{future:"%s\u540e",past:"%s\u524d",s:"\u51e0\u79d2",ss:"%d \u79d2",m:"1 \u5206\u949f",mm:"%d \u5206\u949f",h:"1 \u5c0f\u65f6",hh:"%d \u5c0f\u65f6",d:"1 \u5929",dd:"%d \u5929",w:"1 \u5468",ww:"%d \u5468",M:"1 \u4e2a\u6708",MM:"%d \u4e2a\u6708",y:"1 \u5e74",yy:"%d \u5e74"},week:{dow:1,doy:4}})}(i(16738))},89380:function(v,T,i){!function(r){"use strict";r.defineLocale("zh-hk",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u9031\u65e5_\u9031\u4e00_\u9031\u4e8c_\u9031\u4e09_\u9031\u56db_\u9031\u4e94_\u9031\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5 HH:mm",LLLL:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm",l:"YYYY/M/D",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm"},meridiemParse:/\u51cc\u6668|\u65e9\u4e0a|\u4e0a\u5348|\u4e2d\u5348|\u4e0b\u5348|\u665a\u4e0a/,meridiemHour:function(p,d){return 12===p&&(p=0),"\u51cc\u6668"===d||"\u65e9\u4e0a"===d||"\u4e0a\u5348"===d?p:"\u4e2d\u5348"===d?p>=11?p:p+12:"\u4e0b\u5348"===d||"\u665a\u4e0a"===d?p+12:void 0},meridiem:function(p,d,e){var _=100*p+d;return _<600?"\u51cc\u6668":_<900?"\u65e9\u4e0a":_<1200?"\u4e0a\u5348":1200===_?"\u4e2d\u5348":_<1800?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(\u65e5|\u6708|\u9031)/,ordinal:function(p,d){switch(d){case"d":case"D":case"DDD":return p+"\u65e5";case"M":return p+"\u6708";case"w":case"W":return p+"\u9031";default:return p}},relativeTime:{future:"%s\u5f8c",past:"%s\u524d",s:"\u5e7e\u79d2",ss:"%d \u79d2",m:"1 \u5206\u9418",mm:"%d \u5206\u9418",h:"1 \u5c0f\u6642",hh:"%d \u5c0f\u6642",d:"1 \u5929",dd:"%d \u5929",M:"1 \u500b\u6708",MM:"%d \u500b\u6708",y:"1 \u5e74",yy:"%d \u5e74"}})}(i(16738))},60874:function(v,T,i){!function(r){"use strict";r.defineLocale("zh-mo",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u9031\u65e5_\u9031\u4e00_\u9031\u4e8c_\u9031\u4e09_\u9031\u56db_\u9031\u4e94_\u9031\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5 HH:mm",LLLL:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm",l:"D/M/YYYY",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm"},meridiemParse:/\u51cc\u6668|\u65e9\u4e0a|\u4e0a\u5348|\u4e2d\u5348|\u4e0b\u5348|\u665a\u4e0a/,meridiemHour:function(p,d){return 12===p&&(p=0),"\u51cc\u6668"===d||"\u65e9\u4e0a"===d||"\u4e0a\u5348"===d?p:"\u4e2d\u5348"===d?p>=11?p:p+12:"\u4e0b\u5348"===d||"\u665a\u4e0a"===d?p+12:void 0},meridiem:function(p,d,e){var _=100*p+d;return _<600?"\u51cc\u6668":_<900?"\u65e9\u4e0a":_<1130?"\u4e0a\u5348":_<1230?"\u4e2d\u5348":_<1800?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929] LT",nextDay:"[\u660e\u5929] LT",nextWeek:"[\u4e0b]dddd LT",lastDay:"[\u6628\u5929] LT",lastWeek:"[\u4e0a]dddd LT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(\u65e5|\u6708|\u9031)/,ordinal:function(p,d){switch(d){case"d":case"D":case"DDD":return p+"\u65e5";case"M":return p+"\u6708";case"w":case"W":return p+"\u9031";default:return p}},relativeTime:{future:"%s\u5167",past:"%s\u524d",s:"\u5e7e\u79d2",ss:"%d \u79d2",m:"1 \u5206\u9418",mm:"%d \u5206\u9418",h:"1 \u5c0f\u6642",hh:"%d \u5c0f\u6642",d:"1 \u5929",dd:"%d \u5929",M:"1 \u500b\u6708",MM:"%d \u500b\u6708",y:"1 \u5e74",yy:"%d \u5e74"}})}(i(16738))},96508:function(v,T,i){!function(r){"use strict";r.defineLocale("zh-tw",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u9031\u65e5_\u9031\u4e00_\u9031\u4e8c_\u9031\u4e09_\u9031\u56db_\u9031\u4e94_\u9031\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5 HH:mm",LLLL:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm",l:"YYYY/M/D",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm"},meridiemParse:/\u51cc\u6668|\u65e9\u4e0a|\u4e0a\u5348|\u4e2d\u5348|\u4e0b\u5348|\u665a\u4e0a/,meridiemHour:function(p,d){return 12===p&&(p=0),"\u51cc\u6668"===d||"\u65e9\u4e0a"===d||"\u4e0a\u5348"===d?p:"\u4e2d\u5348"===d?p>=11?p:p+12:"\u4e0b\u5348"===d||"\u665a\u4e0a"===d?p+12:void 0},meridiem:function(p,d,e){var _=100*p+d;return _<600?"\u51cc\u6668":_<900?"\u65e9\u4e0a":_<1130?"\u4e0a\u5348":_<1230?"\u4e2d\u5348":_<1800?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929] LT",nextDay:"[\u660e\u5929] LT",nextWeek:"[\u4e0b]dddd LT",lastDay:"[\u6628\u5929] LT",lastWeek:"[\u4e0a]dddd LT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(\u65e5|\u6708|\u9031)/,ordinal:function(p,d){switch(d){case"d":case"D":case"DDD":return p+"\u65e5";case"M":return p+"\u6708";case"w":case"W":return p+"\u9031";default:return p}},relativeTime:{future:"%s\u5f8c",past:"%s\u524d",s:"\u5e7e\u79d2",ss:"%d \u79d2",m:"1 \u5206\u9418",mm:"%d \u5206\u9418",h:"1 \u5c0f\u6642",hh:"%d \u5c0f\u6642",d:"1 \u5929",dd:"%d \u5929",M:"1 \u500b\u6708",MM:"%d \u500b\u6708",y:"1 \u5e74",yy:"%d \u5e74"}})}(i(16738))},16738:function(v,T,i){(v=i.nmd(v)).exports=function(){"use strict";var r,ue;function u(){return r.apply(null,arguments)}function d(Q){return Q instanceof Array||"[object Array]"===Object.prototype.toString.call(Q)}function e(Q){return null!=Q&&"[object Object]"===Object.prototype.toString.call(Q)}function _(Q,ve){return Object.prototype.hasOwnProperty.call(Q,ve)}function y(Q){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(Q).length;var ve;for(ve in Q)if(_(Q,ve))return!1;return!0}function S(Q){return void 0===Q}function A(Q){return"number"==typeof Q||"[object Number]"===Object.prototype.toString.call(Q)}function N(Q){return Q instanceof Date||"[object Date]"===Object.prototype.toString.call(Q)}function L(Q,ve){var Tt,nt=[],Qt=Q.length;for(Tt=0;Tt<Qt;++Tt)nt.push(ve(Q[Tt],Tt));return nt}function Z(Q,ve){for(var nt in ve)_(ve,nt)&&(Q[nt]=ve[nt]);return _(ve,"toString")&&(Q.toString=ve.toString),_(ve,"valueOf")&&(Q.valueOf=ve.valueOf),Q}function J(Q,ve,nt,Tt){return lu(Q,ve,nt,Tt,!0).utc()}function ee(Q){return null==Q._pf&&(Q._pf={empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidEra:null,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],era:null,meridiem:null,rfc2822:!1,weekdayMismatch:!1}),Q._pf}function ae(Q){if(null==Q._isValid){var ve=ee(Q),nt=ue.call(ve.parsedDateParts,function(Qt){return null!=Qt}),Tt=!isNaN(Q._d.getTime())&&ve.overflow<0&&!ve.empty&&!ve.invalidEra&&!ve.invalidMonth&&!ve.invalidWeekday&&!ve.weekdayMismatch&&!ve.nullInput&&!ve.invalidFormat&&!ve.userInvalidated&&(!ve.meridiem||ve.meridiem&&nt);if(Q._strict&&(Tt=Tt&&0===ve.charsLeftOver&&0===ve.unusedTokens.length&&void 0===ve.bigHour),null!=Object.isFrozen&&Object.isFrozen(Q))return Tt;Q._isValid=Tt}return Q._isValid}function H(Q){var ve=J(NaN);return null!=Q?Z(ee(ve),Q):ee(ve).userInvalidated=!0,ve}ue=Array.prototype.some?Array.prototype.some:function(Q){var Tt,ve=Object(this),nt=ve.length>>>0;for(Tt=0;Tt<nt;Tt++)if(Tt in ve&&Q.call(this,ve[Tt],Tt,ve))return!0;return!1};var se=u.momentProperties=[],Ee=!1;function ie(Q,ve){var nt,Tt,Qt,cr=se.length;if(S(ve._isAMomentObject)||(Q._isAMomentObject=ve._isAMomentObject),S(ve._i)||(Q._i=ve._i),S(ve._f)||(Q._f=ve._f),S(ve._l)||(Q._l=ve._l),S(ve._strict)||(Q._strict=ve._strict),S(ve._tzm)||(Q._tzm=ve._tzm),S(ve._isUTC)||(Q._isUTC=ve._isUTC),S(ve._offset)||(Q._offset=ve._offset),S(ve._pf)||(Q._pf=ee(ve)),S(ve._locale)||(Q._locale=ve._locale),cr>0)for(nt=0;nt<cr;nt++)S(Qt=ve[Tt=se[nt]])||(Q[Tt]=Qt);return Q}function he(Q){ie(this,Q),this._d=new Date(null!=Q._d?Q._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===Ee&&(Ee=!0,u.updateOffset(this),Ee=!1)}function ge(Q){return Q instanceof he||null!=Q&&null!=Q._isAMomentObject}function De(Q){!1===u.suppressDeprecationWarnings&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+Q)}function ce(Q,ve){var nt=!0;return Z(function(){if(null!=u.deprecationHandler&&u.deprecationHandler(null,Q),nt){var Qt,cr,bi,Tt=[],cs=arguments.length;for(cr=0;cr<cs;cr++){if(Qt="","object"==typeof arguments[cr]){for(bi in Qt+="\n["+cr+"] ",arguments[0])_(arguments[0],bi)&&(Qt+=bi+": "+arguments[0][bi]+", ");Qt=Qt.slice(0,-2)}else Qt=arguments[cr];Tt.push(Qt)}De(Q+"\nArguments: "+Array.prototype.slice.call(Tt).join("")+"\n"+(new Error).stack),nt=!1}return ve.apply(this,arguments)},ve)}var He,lt={};function Ve(Q,ve){null!=u.deprecationHandler&&u.deprecationHandler(Q,ve),lt[Q]||(De(ve),lt[Q]=!0)}function ze(Q){return"undefined"!=typeof Function&&Q instanceof Function||"[object Function]"===Object.prototype.toString.call(Q)}function Pe(Q,ve){var Tt,nt=Z({},Q);for(Tt in ve)_(ve,Tt)&&(e(Q[Tt])&&e(ve[Tt])?(nt[Tt]={},Z(nt[Tt],Q[Tt]),Z(nt[Tt],ve[Tt])):null!=ve[Tt]?nt[Tt]=ve[Tt]:delete nt[Tt]);for(Tt in Q)_(Q,Tt)&&!_(ve,Tt)&&e(Q[Tt])&&(nt[Tt]=Z({},nt[Tt]));return nt}function je(Q){null!=Q&&this.set(Q)}u.suppressDeprecationWarnings=!1,u.deprecationHandler=null,He=Object.keys?Object.keys:function(Q){var ve,nt=[];for(ve in Q)_(Q,ve)&&nt.push(ve);return nt};function tn(Q,ve,nt){var Tt=""+Math.abs(Q);return(Q>=0?nt?"+":"":"-")+Math.pow(10,Math.max(0,ve-Tt.length)).toString().substr(1)+Tt}var It=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,Zt=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,Ut={},Bt={};function bt(Q,ve,nt,Tt){var Qt=Tt;"string"==typeof Tt&&(Qt=function(){return this[Tt]()}),Q&&(Bt[Q]=Qt),ve&&(Bt[ve[0]]=function(){return tn(Qt.apply(this,arguments),ve[1],ve[2])}),nt&&(Bt[nt]=function(){return this.localeData().ordinal(Qt.apply(this,arguments),Q)})}function Gt(Q){return Q.match(/\[[\s\S]/)?Q.replace(/^\[|\]$/g,""):Q.replace(/\\/g,"")}function Xt(Q,ve){return Q.isValid()?(ve=Zn(ve,Q.localeData()),Ut[ve]=Ut[ve]||function(Q){var nt,Tt,ve=Q.match(It);for(nt=0,Tt=ve.length;nt<Tt;nt++)ve[nt]=Bt[ve[nt]]?Bt[ve[nt]]:Gt(ve[nt]);return function(Qt){var bi,cr="";for(bi=0;bi<Tt;bi++)cr+=ze(ve[bi])?ve[bi].call(Qt,Q):ve[bi];return cr}}(ve),Ut[ve](Q)):Q.localeData().invalidDate()}function Zn(Q,ve){var nt=5;function Tt(Qt){return ve.longDateFormat(Qt)||Qt}for(Zt.lastIndex=0;nt>=0&&Zt.test(Q);)Q=Q.replace(Zt,Tt),Zt.lastIndex=0,nt-=1;return Q}var fi={};function ki(Q,ve){var nt=Q.toLowerCase();fi[nt]=fi[nt+"s"]=fi[ve]=Q}function Hi(Q){return"string"==typeof Q?fi[Q]||fi[Q.toLowerCase()]:void 0}function Zr(Q){var nt,Tt,ve={};for(Tt in Q)_(Q,Tt)&&(nt=Hi(Tt))&&(ve[nt]=Q[Tt]);return ve}var Cn={};function Wt(Q,ve){Cn[Q]=ve}function rr(Q){return Q%4==0&&Q%100!=0||Q%400==0}function Fr(Q){return Q<0?Math.ceil(Q)||0:Math.floor(Q)}function Gn(Q){var ve=+Q,nt=0;return 0!==ve&&isFinite(ve)&&(nt=Fr(ve)),nt}function Jr(Q,ve){return function(nt){return null!=nt?(wi(this,Q,nt),u.updateOffset(this,ve),this):_i(this,Q)}}function _i(Q,ve){return Q.isValid()?Q._d["get"+(Q._isUTC?"UTC":"")+ve]():NaN}function wi(Q,ve,nt){Q.isValid()&&!isNaN(nt)&&("FullYear"===ve&&rr(Q.year())&&1===Q.month()&&29===Q.date()?(nt=Gn(nt),Q._d["set"+(Q._isUTC?"UTC":"")+ve](nt,Q.month(),tr(nt,Q.month()))):Q._d["set"+(Q._isUTC?"UTC":"")+ve](nt))}var Fn,gn=/\d/,yn=/\d\d/,gr=/\d{3}/,Jt=/\d{4}/,Vn=/[+-]?\d{6}/,mr=/\d\d?/,Dn=/\d\d\d\d?/,Pr=/\d\d\d\d\d\d?/,Yt=/\d{1,3}/,_n=/\d{1,4}/,Ge=/[+-]?\d{1,6}/,kr=/\d+/,mi=/[+-]?\d+/,An=/Z|[+-]\d\d:?\d\d/gi,Er=/Z|[+-]\d\d(?::?\d\d)?/gi,dr=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;function ar(Q,ve,nt){Fn[Q]=ze(ve)?ve:function(Tt,Qt){return Tt&&nt?nt:ve}}function Wi(Q,ve){return _(Fn,Q)?Fn[Q](ve._strict,ve._locale):new RegExp(function(Q){return vo(Q.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(ve,nt,Tt,Qt,cr){return nt||Tt||Qt||cr}))}(Q))}function vo(Q){return Q.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}Fn={};var Co={};function Gi(Q,ve){var nt,Qt,Tt=ve;for("string"==typeof Q&&(Q=[Q]),A(ve)&&(Tt=function(cr,bi){bi[ve]=Gn(cr)}),Qt=Q.length,nt=0;nt<Qt;nt++)Co[Q[nt]]=Tt}function os(Q,ve){Gi(Q,function(nt,Tt,Qt,cr){Qt._w=Qt._w||{},ve(nt,Qt._w,Qt,cr)})}function jo(Q,ve,nt){null!=ve&&_(Co,Q)&&Co[Q](ve,nt._a,nt,Q)}var $o;function tr(Q,ve){if(isNaN(Q)||isNaN(ve))return NaN;var nt=function(Q,ve){return(Q%ve+ve)%ve}(ve,12);return Q+=(ve-nt)/12,1===nt?rr(Q)?29:28:31-nt%7%2}$o=Array.prototype.indexOf?Array.prototype.indexOf:function(Q){var ve;for(ve=0;ve<this.length;++ve)if(this[ve]===Q)return ve;return-1},bt("M",["MM",2],"Mo",function(){return this.month()+1}),bt("MMM",0,0,function(Q){return this.localeData().monthsShort(this,Q)}),bt("MMMM",0,0,function(Q){return this.localeData().months(this,Q)}),ki("month","M"),Wt("month",8),ar("M",mr),ar("MM",mr,yn),ar("MMM",function(Q,ve){return ve.monthsShortRegex(Q)}),ar("MMMM",function(Q,ve){return ve.monthsRegex(Q)}),Gi(["M","MM"],function(Q,ve){ve[1]=Gn(Q)-1}),Gi(["MMM","MMMM"],function(Q,ve,nt,Tt){var Qt=nt._locale.monthsParse(Q,Tt,nt._strict);null!=Qt?ve[1]=Qt:ee(nt).invalidMonth=Q});var Ar="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),Rt="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),_t=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,mt=dr,jt=dr;function Vi(Q,ve,nt){var Tt,Qt,cr,bi=Q.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],Tt=0;Tt<12;++Tt)cr=J([2e3,Tt]),this._shortMonthsParse[Tt]=this.monthsShort(cr,"").toLocaleLowerCase(),this._longMonthsParse[Tt]=this.months(cr,"").toLocaleLowerCase();return nt?"MMM"===ve?-1!==(Qt=$o.call(this._shortMonthsParse,bi))?Qt:null:-1!==(Qt=$o.call(this._longMonthsParse,bi))?Qt:null:"MMM"===ve?-1!==(Qt=$o.call(this._shortMonthsParse,bi))||-1!==(Qt=$o.call(this._longMonthsParse,bi))?Qt:null:-1!==(Qt=$o.call(this._longMonthsParse,bi))||-1!==(Qt=$o.call(this._shortMonthsParse,bi))?Qt:null}function co(Q,ve){var nt;if(!Q.isValid())return Q;if("string"==typeof ve)if(/^\d+$/.test(ve))ve=Gn(ve);else if(!A(ve=Q.localeData().monthsParse(ve)))return Q;return nt=Math.min(Q.date(),tr(Q.year(),ve)),Q._d["set"+(Q._isUTC?"UTC":"")+"Month"](ve,nt),Q}function Es(Q){return null!=Q?(co(this,Q),u.updateOffset(this,!0),this):_i(this,"Month")}function ta(){function Q(bi,cs){return cs.length-bi.length}var Qt,cr,ve=[],nt=[],Tt=[];for(Qt=0;Qt<12;Qt++)cr=J([2e3,Qt]),ve.push(this.monthsShort(cr,"")),nt.push(this.months(cr,"")),Tt.push(this.months(cr,"")),Tt.push(this.monthsShort(cr,""));for(ve.sort(Q),nt.sort(Q),Tt.sort(Q),Qt=0;Qt<12;Qt++)ve[Qt]=vo(ve[Qt]),nt[Qt]=vo(nt[Qt]);for(Qt=0;Qt<24;Qt++)Tt[Qt]=vo(Tt[Qt]);this._monthsRegex=new RegExp("^("+Tt.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+nt.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+ve.join("|")+")","i")}function Is(Q){return rr(Q)?366:365}bt("Y",0,0,function(){var Q=this.year();return Q<=9999?tn(Q,4):"+"+Q}),bt(0,["YY",2],0,function(){return this.year()%100}),bt(0,["YYYY",4],0,"year"),bt(0,["YYYYY",5],0,"year"),bt(0,["YYYYYY",6,!0],0,"year"),ki("year","y"),Wt("year",1),ar("Y",mi),ar("YY",mr,yn),ar("YYYY",_n,Jt),ar("YYYYY",Ge,Vn),ar("YYYYYY",Ge,Vn),Gi(["YYYYY","YYYYYY"],0),Gi("YYYY",function(Q,ve){ve[0]=2===Q.length?u.parseTwoDigitYear(Q):Gn(Q)}),Gi("YY",function(Q,ve){ve[0]=u.parseTwoDigitYear(Q)}),Gi("Y",function(Q,ve){ve[0]=parseInt(Q,10)}),u.parseTwoDigitYear=function(Q){return Gn(Q)+(Gn(Q)>68?1900:2e3)};var us=Jr("FullYear",!0);function el(Q,ve,nt,Tt,Qt,cr,bi){var cs;return Q<100&&Q>=0?(cs=new Date(Q+400,ve,nt,Tt,Qt,cr,bi),isFinite(cs.getFullYear())&&cs.setFullYear(Q)):cs=new Date(Q,ve,nt,Tt,Qt,cr,bi),cs}function ca(Q){var ve,nt;return Q<100&&Q>=0?((nt=Array.prototype.slice.call(arguments))[0]=Q+400,ve=new Date(Date.UTC.apply(null,nt)),isFinite(ve.getUTCFullYear())&&ve.setUTCFullYear(Q)):ve=new Date(Date.UTC.apply(null,arguments)),ve}function $s(Q,ve,nt){var Tt=7+ve-nt;return-(7+ca(Q,0,Tt).getUTCDay()-ve)%7+Tt-1}function da(Q,ve,nt,Tt,Qt){var xa,na,cs=1+7*(ve-1)+(7+nt-Tt)%7+$s(Q,Tt,Qt);return cs<=0?na=Is(xa=Q-1)+cs:cs>Is(Q)?(xa=Q+1,na=cs-Is(Q)):(xa=Q,na=cs),{year:xa,dayOfYear:na}}function Il(Q,ve,nt){var cr,bi,Tt=$s(Q.year(),ve,nt),Qt=Math.floor((Q.dayOfYear()-Tt-1)/7)+1;return Qt<1?cr=Qt+fo(bi=Q.year()-1,ve,nt):Qt>fo(Q.year(),ve,nt)?(cr=Qt-fo(Q.year(),ve,nt),bi=Q.year()+1):(bi=Q.year(),cr=Qt),{week:cr,year:bi}}function fo(Q,ve,nt){var Tt=$s(Q,ve,nt),Qt=$s(Q+1,ve,nt);return(Is(Q)-Tt+Qt)/7}bt("w",["ww",2],"wo","week"),bt("W",["WW",2],"Wo","isoWeek"),ki("week","w"),ki("isoWeek","W"),Wt("week",5),Wt("isoWeek",5),ar("w",mr),ar("ww",mr,yn),ar("W",mr),ar("WW",mr,yn),os(["w","ww","W","WW"],function(Q,ve,nt,Tt){ve[Tt.substr(0,1)]=Gn(Q)});function bo(Q,ve){return Q.slice(ve,7).concat(Q.slice(0,ve))}bt("d",0,"do","day"),bt("dd",0,0,function(Q){return this.localeData().weekdaysMin(this,Q)}),bt("ddd",0,0,function(Q){return this.localeData().weekdaysShort(this,Q)}),bt("dddd",0,0,function(Q){return this.localeData().weekdays(this,Q)}),bt("e",0,0,"weekday"),bt("E",0,0,"isoWeekday"),ki("day","d"),ki("weekday","e"),ki("isoWeekday","E"),Wt("day",11),Wt("weekday",11),Wt("isoWeekday",11),ar("d",mr),ar("e",mr),ar("E",mr),ar("dd",function(Q,ve){return ve.weekdaysMinRegex(Q)}),ar("ddd",function(Q,ve){return ve.weekdaysShortRegex(Q)}),ar("dddd",function(Q,ve){return ve.weekdaysRegex(Q)}),os(["dd","ddd","dddd"],function(Q,ve,nt,Tt){var Qt=nt._locale.weekdaysParse(Q,Tt,nt._strict);null!=Qt?ve.d=Qt:ee(nt).invalidWeekday=Q}),os(["d","e","E"],function(Q,ve,nt,Tt){ve[Tt]=Gn(Q)});var Ls="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),ps="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),So="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),$r=dr,to=dr,tt=dr;function Lt(Q,ve,nt){var Tt,Qt,cr,bi=Q.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],Tt=0;Tt<7;++Tt)cr=J([2e3,1]).day(Tt),this._minWeekdaysParse[Tt]=this.weekdaysMin(cr,"").toLocaleLowerCase(),this._shortWeekdaysParse[Tt]=this.weekdaysShort(cr,"").toLocaleLowerCase(),this._weekdaysParse[Tt]=this.weekdays(cr,"").toLocaleLowerCase();return nt?"dddd"===ve?-1!==(Qt=$o.call(this._weekdaysParse,bi))?Qt:null:"ddd"===ve?-1!==(Qt=$o.call(this._shortWeekdaysParse,bi))?Qt:null:-1!==(Qt=$o.call(this._minWeekdaysParse,bi))?Qt:null:"dddd"===ve?-1!==(Qt=$o.call(this._weekdaysParse,bi))||-1!==(Qt=$o.call(this._shortWeekdaysParse,bi))||-1!==(Qt=$o.call(this._minWeekdaysParse,bi))?Qt:null:"ddd"===ve?-1!==(Qt=$o.call(this._shortWeekdaysParse,bi))||-1!==(Qt=$o.call(this._weekdaysParse,bi))||-1!==(Qt=$o.call(this._minWeekdaysParse,bi))?Qt:null:-1!==(Qt=$o.call(this._minWeekdaysParse,bi))||-1!==(Qt=$o.call(this._weekdaysParse,bi))||-1!==(Qt=$o.call(this._shortWeekdaysParse,bi))?Qt:null}function Eo(){function Q(_l,zl){return zl.length-_l.length}var cr,bi,cs,xa,na,ve=[],nt=[],Tt=[],Qt=[];for(cr=0;cr<7;cr++)bi=J([2e3,1]).day(cr),cs=vo(this.weekdaysMin(bi,"")),xa=vo(this.weekdaysShort(bi,"")),na=vo(this.weekdays(bi,"")),ve.push(cs),nt.push(xa),Tt.push(na),Qt.push(cs),Qt.push(xa),Qt.push(na);ve.sort(Q),nt.sort(Q),Tt.sort(Q),Qt.sort(Q),this._weekdaysRegex=new RegExp("^("+Qt.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+Tt.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+nt.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+ve.join("|")+")","i")}function ba(){return this.hours()%12||12}function tc(Q,ve){bt(Q,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),ve)})}function Nu(Q,ve){return ve._meridiemParse}bt("H",["HH",2],0,"hour"),bt("h",["hh",2],0,ba),bt("k",["kk",2],0,function(){return this.hours()||24}),bt("hmm",0,0,function(){return""+ba.apply(this)+tn(this.minutes(),2)}),bt("hmmss",0,0,function(){return""+ba.apply(this)+tn(this.minutes(),2)+tn(this.seconds(),2)}),bt("Hmm",0,0,function(){return""+this.hours()+tn(this.minutes(),2)}),bt("Hmmss",0,0,function(){return""+this.hours()+tn(this.minutes(),2)+tn(this.seconds(),2)}),tc("a",!0),tc("A",!1),ki("hour","h"),Wt("hour",13),ar("a",Nu),ar("A",Nu),ar("H",mr),ar("h",mr),ar("k",mr),ar("HH",mr,yn),ar("hh",mr,yn),ar("kk",mr,yn),ar("hmm",Dn),ar("hmmss",Pr),ar("Hmm",Dn),ar("Hmmss",Pr),Gi(["H","HH"],3),Gi(["k","kk"],function(Q,ve,nt){var Tt=Gn(Q);ve[3]=24===Tt?0:Tt}),Gi(["a","A"],function(Q,ve,nt){nt._isPm=nt._locale.isPM(Q),nt._meridiem=Q}),Gi(["h","hh"],function(Q,ve,nt){ve[3]=Gn(Q),ee(nt).bigHour=!0}),Gi("hmm",function(Q,ve,nt){var Tt=Q.length-2;ve[3]=Gn(Q.substr(0,Tt)),ve[4]=Gn(Q.substr(Tt)),ee(nt).bigHour=!0}),Gi("hmmss",function(Q,ve,nt){var Tt=Q.length-4,Qt=Q.length-2;ve[3]=Gn(Q.substr(0,Tt)),ve[4]=Gn(Q.substr(Tt,2)),ve[5]=Gn(Q.substr(Qt)),ee(nt).bigHour=!0}),Gi("Hmm",function(Q,ve,nt){var Tt=Q.length-2;ve[3]=Gn(Q.substr(0,Tt)),ve[4]=Gn(Q.substr(Tt))}),Gi("Hmmss",function(Q,ve,nt){var Tt=Q.length-4,Qt=Q.length-2;ve[3]=Gn(Q.substr(0,Tt)),ve[4]=Gn(Q.substr(Tt,2)),ve[5]=Gn(Q.substr(Qt))});var qc=Jr("Hours",!0);var iu,Yl={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Ar,monthsShort:Rt,week:{dow:0,doy:6},weekdays:Ls,weekdaysMin:So,weekdaysShort:ps,meridiemParse:/[ap]\.?m?\.?/i},Fs={},dc={};function tl(Q,ve){var nt,Tt=Math.min(Q.length,ve.length);for(nt=0;nt<Tt;nt+=1)if(Q[nt]!==ve[nt])return nt;return Tt}function Su(Q){return Q&&Q.toLowerCase().replace("_","-")}function Pt(Q){var ve=null;if(void 0===Fs[Q]&&v&&v.exports&&function(Q){return null!=Q.match("^[^/\\\\]*$")}(Q))try{ve=iu._abbr,i(46700)("./"+Q),dt(ve)}catch(Tt){Fs[Q]=null}return Fs[Q]}function dt(Q,ve){var nt;return Q&&((nt=S(ve)?xe(Q):Te(Q,ve))?iu=nt:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+Q+" not found. Did you forget to load it?")),iu._abbr}function Te(Q,ve){if(null!==ve){var nt,Tt=Yl;if(ve.abbr=Q,null!=Fs[Q])Ve("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),Tt=Fs[Q]._config;else if(null!=ve.parentLocale)if(null!=Fs[ve.parentLocale])Tt=Fs[ve.parentLocale]._config;else{if(null==(nt=Pt(ve.parentLocale)))return dc[ve.parentLocale]||(dc[ve.parentLocale]=[]),dc[ve.parentLocale].push({name:Q,config:ve}),null;Tt=nt._config}return Fs[Q]=new je(Pe(Tt,ve)),dc[Q]&&dc[Q].forEach(function(Qt){Te(Qt.name,Qt.config)}),dt(Q),Fs[Q]}return delete Fs[Q],null}function xe(Q){var ve;if(Q&&Q._locale&&Q._locale._abbr&&(Q=Q._locale._abbr),!Q)return iu;if(!d(Q)){if(ve=Pt(Q))return ve;Q=[Q]}return function(Q){for(var nt,Tt,Qt,cr,ve=0;ve<Q.length;){for(nt=(cr=Su(Q[ve]).split("-")).length,Tt=(Tt=Su(Q[ve+1]))?Tt.split("-"):null;nt>0;){if(Qt=Pt(cr.slice(0,nt).join("-")))return Qt;if(Tt&&Tt.length>=nt&&tl(cr,Tt)>=nt-1)break;nt--}ve++}return iu}(Q)}function ur(Q){var ve,nt=Q._a;return nt&&-2===ee(Q).overflow&&(ve=nt[1]<0||nt[1]>11?1:nt[2]<1||nt[2]>tr(nt[0],nt[1])?2:nt[3]<0||nt[3]>24||24===nt[3]&&(0!==nt[4]||0!==nt[5]||0!==nt[6])?3:nt[4]<0||nt[4]>59?4:nt[5]<0||nt[5]>59?5:nt[6]<0||nt[6]>999?6:-1,ee(Q)._overflowDayOfYear&&(ve<0||ve>2)&&(ve=2),ee(Q)._overflowWeeks&&-1===ve&&(ve=7),ee(Q)._overflowWeekday&&-1===ve&&(ve=8),ee(Q).overflow=ve),Q}var Qi=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Go=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ms=/Z|[+-]\d\d(?::?\d\d)?/,hs=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/],["YYYYMM",/\d{6}/,!1],["YYYY",/\d{4}/,!1]],Ts=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Ma=/^\/?Date\((-?\d+)/i,au=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/,Wa={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function Rl(Q){var ve,nt,cr,bi,cs,xa,Tt=Q._i,Qt=Qi.exec(Tt)||Go.exec(Tt),na=hs.length,_l=Ts.length;if(Qt){for(ee(Q).iso=!0,ve=0,nt=na;ve<nt;ve++)if(hs[ve][1].exec(Qt[1])){bi=hs[ve][0],cr=!1!==hs[ve][2];break}if(null==bi)return void(Q._isValid=!1);if(Qt[3]){for(ve=0,nt=_l;ve<nt;ve++)if(Ts[ve][1].exec(Qt[3])){cs=(Qt[2]||" ")+Ts[ve][0];break}if(null==cs)return void(Q._isValid=!1)}if(!cr&&null!=cs)return void(Q._isValid=!1);if(Qt[4]){if(!ms.exec(Qt[4]))return void(Q._isValid=!1);xa="Z"}Q._f=bi+(cs||"")+(xa||""),sa(Q)}else Q._isValid=!1}function Al(Q){var ve=parseInt(Q,10);return ve<=49?2e3+ve:ve<=999?1900+ve:ve}function Fc(Q){var nt,ve=au.exec(function(Q){return Q.replace(/\([^)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").replace(/^\s\s*/,"").replace(/\s\s*$/,"")}(Q._i));if(ve){if(nt=function(Q,ve,nt,Tt,Qt,cr){var bi=[Al(Q),Rt.indexOf(ve),parseInt(nt,10),parseInt(Tt,10),parseInt(Qt,10)];return cr&&bi.push(parseInt(cr,10)),bi}(ve[4],ve[3],ve[2],ve[5],ve[6],ve[7]),!function(Q,ve,nt){return!Q||ps.indexOf(Q)===new Date(ve[0],ve[1],ve[2]).getDay()||(ee(nt).weekdayMismatch=!0,nt._isValid=!1,!1)}(ve[1],nt,Q))return;Q._a=nt,Q._tzm=function(Q,ve,nt){if(Q)return Wa[Q];if(ve)return 0;var Tt=parseInt(nt,10),Qt=Tt%100;return(Tt-Qt)/100*60+Qt}(ve[8],ve[9],ve[10]),Q._d=ca.apply(null,Q._a),Q._d.setUTCMinutes(Q._d.getUTCMinutes()-Q._tzm),ee(Q).rfc2822=!0}else Q._isValid=!1}function kc(Q,ve,nt){return null!=Q?Q:null!=ve?ve:nt}function rc(Q){var ve,nt,Qt,cr,bi,Tt=[];if(!Q._d){for(Qt=function(Q){var ve=new Date(u.now());return Q._useUTC?[ve.getUTCFullYear(),ve.getUTCMonth(),ve.getUTCDate()]:[ve.getFullYear(),ve.getMonth(),ve.getDate()]}(Q),Q._w&&null==Q._a[2]&&null==Q._a[1]&&function(Q){var ve,nt,Tt,Qt,cr,bi,cs,xa,na;null!=(ve=Q._w).GG||null!=ve.W||null!=ve.E?(cr=1,bi=4,nt=kc(ve.GG,Q._a[0],Il(js(),1,4).year),Tt=kc(ve.W,1),((Qt=kc(ve.E,1))<1||Qt>7)&&(xa=!0)):(cr=Q._locale._week.dow,bi=Q._locale._week.doy,na=Il(js(),cr,bi),nt=kc(ve.gg,Q._a[0],na.year),Tt=kc(ve.w,na.week),null!=ve.d?((Qt=ve.d)<0||Qt>6)&&(xa=!0):null!=ve.e?(Qt=ve.e+cr,(ve.e<0||ve.e>6)&&(xa=!0)):Qt=cr),Tt<1||Tt>fo(nt,cr,bi)?ee(Q)._overflowWeeks=!0:null!=xa?ee(Q)._overflowWeekday=!0:(cs=da(nt,Tt,Qt,cr,bi),Q._a[0]=cs.year,Q._dayOfYear=cs.dayOfYear)}(Q),null!=Q._dayOfYear&&(bi=kc(Q._a[0],Qt[0]),(Q._dayOfYear>Is(bi)||0===Q._dayOfYear)&&(ee(Q)._overflowDayOfYear=!0),nt=ca(bi,0,Q._dayOfYear),Q._a[1]=nt.getUTCMonth(),Q._a[2]=nt.getUTCDate()),ve=0;ve<3&&null==Q._a[ve];++ve)Q._a[ve]=Tt[ve]=Qt[ve];for(;ve<7;ve++)Q._a[ve]=Tt[ve]=null==Q._a[ve]?2===ve?1:0:Q._a[ve];24===Q._a[3]&&0===Q._a[4]&&0===Q._a[5]&&0===Q._a[6]&&(Q._nextDay=!0,Q._a[3]=0),Q._d=(Q._useUTC?ca:el).apply(null,Tt),cr=Q._useUTC?Q._d.getUTCDay():Q._d.getDay(),null!=Q._tzm&&Q._d.setUTCMinutes(Q._d.getUTCMinutes()-Q._tzm),Q._nextDay&&(Q._a[3]=24),Q._w&&void 0!==Q._w.d&&Q._w.d!==cr&&(ee(Q).weekdayMismatch=!0)}}function sa(Q){if(Q._f!==u.ISO_8601)if(Q._f!==u.RFC_2822){Q._a=[],ee(Q).empty=!0;var nt,Tt,Qt,cr,bi,na,_l,ve=""+Q._i,cs=ve.length,xa=0;for(_l=(Qt=Zn(Q._f,Q._locale).match(It)||[]).length,nt=0;nt<_l;nt++)(Tt=(ve.match(Wi(cr=Qt[nt],Q))||[])[0])&&((bi=ve.substr(0,ve.indexOf(Tt))).length>0&&ee(Q).unusedInput.push(bi),ve=ve.slice(ve.indexOf(Tt)+Tt.length),xa+=Tt.length),Bt[cr]?(Tt?ee(Q).empty=!1:ee(Q).unusedTokens.push(cr),jo(cr,Tt,Q)):Q._strict&&!Tt&&ee(Q).unusedTokens.push(cr);ee(Q).charsLeftOver=cs-xa,ve.length>0&&ee(Q).unusedInput.push(ve),Q._a[3]<=12&&!0===ee(Q).bigHour&&Q._a[3]>0&&(ee(Q).bigHour=void 0),ee(Q).parsedDateParts=Q._a.slice(0),ee(Q).meridiem=Q._meridiem,Q._a[3]=function(Q,ve,nt){var Tt;return null==nt?ve:null!=Q.meridiemHour?Q.meridiemHour(ve,nt):(null!=Q.isPM&&((Tt=Q.isPM(nt))&&ve<12&&(ve+=12),!Tt&&12===ve&&(ve=0)),ve)}(Q._locale,Q._a[3],Q._meridiem),null!==(na=ee(Q).era)&&(Q._a[0]=Q._locale.erasConvertYear(na,Q._a[0])),rc(Q),ur(Q)}else Fc(Q);else Rl(Q)}function Mu(Q){var ve=Q._i,nt=Q._f;return Q._locale=Q._locale||xe(Q._l),null===ve||void 0===nt&&""===ve?H({nullInput:!0}):("string"==typeof ve&&(Q._i=ve=Q._locale.preparse(ve)),ge(ve)?new he(ur(ve)):(N(ve)?Q._d=ve:d(nt)?function(Q){var ve,nt,Tt,Qt,cr,bi,cs=!1,xa=Q._f.length;if(0===xa)return ee(Q).invalidFormat=!0,void(Q._d=new Date(NaN));for(Qt=0;Qt<xa;Qt++)cr=0,bi=!1,ve=ie({},Q),null!=Q._useUTC&&(ve._useUTC=Q._useUTC),ve._f=Q._f[Qt],sa(ve),ae(ve)&&(bi=!0),cr+=ee(ve).charsLeftOver,cr+=10*ee(ve).unusedTokens.length,ee(ve).score=cr,cs?cr<Tt&&(Tt=cr,nt=ve):(null==Tt||cr<Tt||bi)&&(Tt=cr,nt=ve,bi&&(cs=!0));Z(Q,nt||ve)}(Q):nt?sa(Q):function(Q){var ve=Q._i;S(ve)?Q._d=new Date(u.now()):N(ve)?Q._d=new Date(ve.valueOf()):"string"==typeof ve?function(Q){var ve=Ma.exec(Q._i);null===ve?(Rl(Q),!1===Q._isValid&&(delete Q._isValid,Fc(Q),!1===Q._isValid&&(delete Q._isValid,Q._strict?Q._isValid=!1:u.createFromInputFallback(Q)))):Q._d=new Date(+ve[1])}(Q):d(ve)?(Q._a=L(ve.slice(0),function(nt){return parseInt(nt,10)}),rc(Q)):e(ve)?function(Q){if(!Q._d){var ve=Zr(Q._i);Q._a=L([ve.year,ve.month,void 0===ve.day?ve.date:ve.day,ve.hour,ve.minute,ve.second,ve.millisecond],function(Tt){return Tt&&parseInt(Tt,10)}),rc(Q)}}(Q):A(ve)?Q._d=new Date(ve):u.createFromInputFallback(Q)}(Q),ae(Q)||(Q._d=null),Q))}function lu(Q,ve,nt,Tt,Qt){var cr={};return(!0===ve||!1===ve)&&(Tt=ve,ve=void 0),(!0===nt||!1===nt)&&(Tt=nt,nt=void 0),(e(Q)&&y(Q)||d(Q)&&0===Q.length)&&(Q=void 0),cr._isAMomentObject=!0,cr._useUTC=cr._isUTC=Qt,cr._l=nt,cr._i=Q,cr._f=ve,cr._strict=Tt,function(Q){var ve=new he(ur(Mu(Q)));return ve._nextDay&&(ve.add(1,"d"),ve._nextDay=void 0),ve}(cr)}function js(Q,ve,nt,Tt){return lu(Q,ve,nt,Tt,!1)}u.createFromInputFallback=ce("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(Q){Q._d=new Date(Q._i+(Q._useUTC?" UTC":""))}),u.ISO_8601=function(){},u.RFC_2822=function(){};var Hu=ce("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var Q=js.apply(null,arguments);return this.isValid()&&Q.isValid()?Q<this?this:Q:H()}),Uu=ce("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var Q=js.apply(null,arguments);return this.isValid()&&Q.isValid()?Q>this?this:Q:H()});function Bo(Q,ve){var nt,Tt;if(1===ve.length&&d(ve[0])&&(ve=ve[0]),!ve.length)return js();for(nt=ve[0],Tt=1;Tt<ve.length;++Tt)(!ve[Tt].isValid()||ve[Tt][Q](nt))&&(nt=ve[Tt]);return nt}var pu=["year","quarter","month","week","day","hour","minute","second","millisecond"];function El(Q){var ve=Zr(Q),nt=ve.year||0,Tt=ve.quarter||0,Qt=ve.month||0,cr=ve.week||ve.isoWeek||0,bi=ve.day||0,cs=ve.hour||0,xa=ve.minute||0,na=ve.second||0,_l=ve.millisecond||0;this._isValid=function(Q){var ve,Tt,nt=!1,Qt=pu.length;for(ve in Q)if(_(Q,ve)&&(-1===$o.call(pu,ve)||null!=Q[ve]&&isNaN(Q[ve])))return!1;for(Tt=0;Tt<Qt;++Tt)if(Q[pu[Tt]]){if(nt)return!1;parseFloat(Q[pu[Tt]])!==Gn(Q[pu[Tt]])&&(nt=!0)}return!0}(ve),this._milliseconds=+_l+1e3*na+6e4*xa+1e3*cs*60*60,this._days=+bi+7*cr,this._months=+Qt+3*Tt+12*nt,this._data={},this._locale=xe(),this._bubble()}function Ul(Q){return Q instanceof El}function ks(Q){return Q<0?-1*Math.round(-1*Q):Math.round(Q)}function Ae(Q,ve){bt(Q,0,0,function(){var nt=this.utcOffset(),Tt="+";return nt<0&&(nt=-nt,Tt="-"),Tt+tn(~~(nt/60),2)+ve+tn(~~nt%60,2)})}Ae("Z",":"),Ae("ZZ",""),ar("Z",Er),ar("ZZ",Er),Gi(["Z","ZZ"],function(Q,ve,nt){nt._useUTC=!0,nt._tzm=vt(Er,Q)});var st=/([\+\-]|\d\d)/gi;function vt(Q,ve){var Qt,cr,nt=(ve||"").match(Q);return null===nt?null:0===(cr=60*(Qt=((nt[nt.length-1]||[])+"").match(st)||["-",0,0])[1]+Gn(Qt[2]))?0:"+"===Qt[0]?cr:-cr}function ut(Q,ve){var nt,Tt;return ve._isUTC?(nt=ve.clone(),Tt=(ge(Q)||N(Q)?Q.valueOf():js(Q).valueOf())-nt.valueOf(),nt._d.setTime(nt._d.valueOf()+Tt),u.updateOffset(nt,!1),nt):js(Q).local()}function un(Q){return-Math.round(Q._d.getTimezoneOffset())}function ao(){return!!this.isValid()&&this._isUTC&&0===this._offset}u.updateOffset=function(){};var ys=/^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/,Na=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function Tl(Q,ve){var Qt,cr,bi,nt=Q,Tt=null;return Ul(Q)?nt={ms:Q._milliseconds,d:Q._days,M:Q._months}:A(Q)||!isNaN(+Q)?(nt={},ve?nt[ve]=+Q:nt.milliseconds=+Q):(Tt=ys.exec(Q))?(Qt="-"===Tt[1]?-1:1,nt={y:0,d:Gn(Tt[2])*Qt,h:Gn(Tt[3])*Qt,m:Gn(Tt[4])*Qt,s:Gn(Tt[5])*Qt,ms:Gn(ks(1e3*Tt[6]))*Qt}):(Tt=Na.exec(Q))?nt={y:Qs(Tt[2],Qt="-"===Tt[1]?-1:1),M:Qs(Tt[3],Qt),w:Qs(Tt[4],Qt),d:Qs(Tt[5],Qt),h:Qs(Tt[6],Qt),m:Qs(Tt[7],Qt),s:Qs(Tt[8],Qt)}:null==nt?nt={}:"object"==typeof nt&&("from"in nt||"to"in nt)&&(bi=function(Q,ve){var nt;return Q.isValid()&&ve.isValid()?(ve=ut(ve,Q),Q.isBefore(ve)?nt=ed(Q,ve):((nt=ed(ve,Q)).milliseconds=-nt.milliseconds,nt.months=-nt.months),nt):{milliseconds:0,months:0}}(js(nt.from),js(nt.to)),(nt={}).ms=bi.milliseconds,nt.M=bi.months),cr=new El(nt),Ul(Q)&&_(Q,"_locale")&&(cr._locale=Q._locale),Ul(Q)&&_(Q,"_isValid")&&(cr._isValid=Q._isValid),cr}function Qs(Q,ve){var nt=Q&&parseFloat(Q.replace(",","."));return(isNaN(nt)?0:nt)*ve}function ed(Q,ve){var nt={};return nt.months=ve.month()-Q.month()+12*(ve.year()-Q.year()),Q.clone().add(nt.months,"M").isAfter(ve)&&--nt.months,nt.milliseconds=+ve-+Q.clone().add(nt.months,"M"),nt}function Gl(Q,ve){return function(nt,Tt){var cr;return null!==Tt&&!isNaN(+Tt)&&(Ve(ve,"moment()."+ve+"(period, number) is deprecated. Please use moment()."+ve+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),cr=nt,nt=Tt,Tt=cr),$i(this,Tl(nt,Tt),Q),this}}function $i(Q,ve,nt,Tt){var Qt=ve._milliseconds,cr=ks(ve._days),bi=ks(ve._months);!Q.isValid()||(Tt=null==Tt||Tt,bi&&co(Q,_i(Q,"Month")+bi*nt),cr&&wi(Q,"Date",_i(Q,"Date")+cr*nt),Qt&&Q._d.setTime(Q._d.valueOf()+Qt*nt),Tt&&u.updateOffset(Q,cr||bi))}Tl.fn=El.prototype,Tl.invalid=function(){return Tl(NaN)};var xo=Gl(1,"add"),pa=Gl(-1,"subtract");function hl(Q){return"string"==typeof Q||Q instanceof String}function Bl(Q){return ge(Q)||N(Q)||hl(Q)||A(Q)||function(Q){var ve=d(Q),nt=!1;return ve&&(nt=0===Q.filter(function(Tt){return!A(Tt)&&hl(Q)}).length),ve&&nt}(Q)||function(Q){var Qt,ve=e(Q)&&!y(Q),nt=!1,Tt=["years","year","y","months","month","M","days","day","d","dates","date","D","hours","hour","h","minutes","minute","m","seconds","second","s","milliseconds","millisecond","ms"],bi=Tt.length;for(Qt=0;Qt<bi;Qt+=1)nt=nt||_(Q,Tt[Qt]);return ve&&nt}(Q)||null==Q}function Mn(Q){var Qt,ve=e(Q)&&!y(Q),nt=!1,Tt=["sameDay","nextDay","lastDay","nextWeek","lastWeek","sameElse"];for(Qt=0;Qt<Tt.length;Qt+=1)nt=nt||_(Q,Tt[Qt]);return ve&&nt}function Jd(Q,ve){if(Q.date()<ve.date())return-Jd(ve,Q);var nt=12*(ve.year()-Q.year())+(ve.month()-Q.month()),Tt=Q.clone().add(nt,"months");return-(nt+(ve-Tt<0?(ve-Tt)/(Tt-Q.clone().add(nt-1,"months")):(ve-Tt)/(Q.clone().add(nt+1,"months")-Tt)))||0}function Ei(Q){var ve;return void 0===Q?this._locale._abbr:(null!=(ve=xe(Q))&&(this._locale=ve),this)}u.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",u.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Yo=ce("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(Q){return void 0===Q?this.localeData():this.locale(Q)});function $a(){return this._locale}var Oa=6e4,Hs=60*Oa,fc=3506328*Hs;function ga(Q,ve){return(Q%ve+ve)%ve}function Ol(Q,ve,nt){return Q<100&&Q>=0?new Date(Q+400,ve,nt)-fc:new Date(Q,ve,nt).valueOf()}function ll(Q,ve,nt){return Q<100&&Q>=0?Date.UTC(Q+400,ve,nt)-fc:Date.UTC(Q,ve,nt)}function Iu(Q,ve){return ve.erasAbbrRegex(Q)}function vd(){var Qt,cr,Q=[],ve=[],nt=[],Tt=[],bi=this.eras();for(Qt=0,cr=bi.length;Qt<cr;++Qt)ve.push(vo(bi[Qt].name)),Q.push(vo(bi[Qt].abbr)),nt.push(vo(bi[Qt].narrow)),Tt.push(vo(bi[Qt].name)),Tt.push(vo(bi[Qt].abbr)),Tt.push(vo(bi[Qt].narrow));this._erasRegex=new RegExp("^("+Tt.join("|")+")","i"),this._erasNameRegex=new RegExp("^("+ve.join("|")+")","i"),this._erasAbbrRegex=new RegExp("^("+Q.join("|")+")","i"),this._erasNarrowRegex=new RegExp("^("+nt.join("|")+")","i")}function wc(Q,ve){bt(0,[Q,Q.length],0,ve)}function yd(Q,ve,nt,Tt,Qt){var cr;return null==Q?Il(this,Tt,Qt).year:(ve>(cr=fo(Q,Tt,Qt))&&(ve=cr),$p.call(this,Q,ve,nt,Tt,Qt))}function $p(Q,ve,nt,Tt,Qt){var cr=da(Q,ve,nt,Tt,Qt),bi=ca(cr.year,0,cr.dayOfYear);return this.year(bi.getUTCFullYear()),this.month(bi.getUTCMonth()),this.date(bi.getUTCDate()),this}bt("N",0,0,"eraAbbr"),bt("NN",0,0,"eraAbbr"),bt("NNN",0,0,"eraAbbr"),bt("NNNN",0,0,"eraName"),bt("NNNNN",0,0,"eraNarrow"),bt("y",["y",1],"yo","eraYear"),bt("y",["yy",2],0,"eraYear"),bt("y",["yyy",3],0,"eraYear"),bt("y",["yyyy",4],0,"eraYear"),ar("N",Iu),ar("NN",Iu),ar("NNN",Iu),ar("NNNN",function(Q,ve){return ve.erasNameRegex(Q)}),ar("NNNNN",function(Q,ve){return ve.erasNarrowRegex(Q)}),Gi(["N","NN","NNN","NNNN","NNNNN"],function(Q,ve,nt,Tt){var Qt=nt._locale.erasParse(Q,Tt,nt._strict);Qt?ee(nt).era=Qt:ee(nt).invalidEra=Q}),ar("y",kr),ar("yy",kr),ar("yyy",kr),ar("yyyy",kr),ar("yo",function(Q,ve){return ve._eraYearOrdinalRegex||kr}),Gi(["y","yy","yyy","yyyy"],0),Gi(["yo"],function(Q,ve,nt,Tt){var Qt;nt._locale._eraYearOrdinalRegex&&(Qt=Q.match(nt._locale._eraYearOrdinalRegex)),ve[0]=nt._locale.eraYearOrdinalParse?nt._locale.eraYearOrdinalParse(Q,Qt):parseInt(Q,10)}),bt(0,["gg",2],0,function(){return this.weekYear()%100}),bt(0,["GG",2],0,function(){return this.isoWeekYear()%100}),wc("gggg","weekYear"),wc("ggggg","weekYear"),wc("GGGG","isoWeekYear"),wc("GGGGG","isoWeekYear"),ki("weekYear","gg"),ki("isoWeekYear","GG"),Wt("weekYear",1),Wt("isoWeekYear",1),ar("G",mi),ar("g",mi),ar("GG",mr,yn),ar("gg",mr,yn),ar("GGGG",_n,Jt),ar("gggg",_n,Jt),ar("GGGGG",Ge,Vn),ar("ggggg",Ge,Vn),os(["gggg","ggggg","GGGG","GGGGG"],function(Q,ve,nt,Tt){ve[Tt.substr(0,2)]=Gn(Q)}),os(["gg","GG"],function(Q,ve,nt,Tt){ve[Tt]=u.parseTwoDigitYear(Q)}),bt("Q",0,"Qo","quarter"),ki("quarter","Q"),Wt("quarter",7),ar("Q",gn),Gi("Q",function(Q,ve){ve[1]=3*(Gn(Q)-1)}),bt("D",["DD",2],"Do","date"),ki("date","D"),Wt("date",9),ar("D",mr),ar("DD",mr,yn),ar("Do",function(Q,ve){return Q?ve._dayOfMonthOrdinalParse||ve._ordinalParse:ve._dayOfMonthOrdinalParseLenient}),Gi(["D","DD"],2),Gi("Do",function(Q,ve){ve[2]=Gn(Q.match(mr)[0])});var _f=Jr("Date",!0);bt("DDD",["DDDD",3],"DDDo","dayOfYear"),ki("dayOfYear","DDD"),Wt("dayOfYear",4),ar("DDD",Yt),ar("DDDD",gr),Gi(["DDD","DDDD"],function(Q,ve,nt){nt._dayOfYear=Gn(Q)}),bt("m",["mm",2],0,"minute"),ki("minute","m"),Wt("minute",14),ar("m",mr),ar("mm",mr,yn),Gi(["m","mm"],4);var Ql=Jr("Minutes",!1);bt("s",["ss",2],0,"second"),ki("second","s"),Wt("second",15),ar("s",mr),ar("ss",mr,yn),Gi(["s","ss"],5);var Bu,Kf,Hf=Jr("Seconds",!1);for(bt("S",0,0,function(){return~~(this.millisecond()/100)}),bt(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),bt(0,["SSS",3],0,"millisecond"),bt(0,["SSSS",4],0,function(){return 10*this.millisecond()}),bt(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),bt(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),bt(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),bt(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),bt(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),ki("millisecond","ms"),Wt("millisecond",16),ar("S",Yt,gn),ar("SS",Yt,yn),ar("SSS",Yt,gr),Bu="SSSS";Bu.length<=9;Bu+="S")ar(Bu,kr);function Nd(Q,ve){ve[6]=Gn(1e3*("0."+Q))}for(Bu="S";Bu.length<=9;Bu+="S")Gi(Bu,Nd);Kf=Jr("Milliseconds",!1),bt("z",0,0,"zoneAbbr"),bt("zz",0,0,"zoneName");var Ji=he.prototype;function Pd(Q){return Q}Ji.add=xo,Ji.calendar=function(Q,ve){1===arguments.length&&(arguments[0]?Bl(arguments[0])?(Q=arguments[0],ve=void 0):Mn(arguments[0])&&(ve=arguments[0],Q=void 0):(Q=void 0,ve=void 0));var nt=Q||js(),Tt=ut(nt,this).startOf("day"),Qt=u.calendarFormat(this,Tt)||"sameElse",cr=ve&&(ze(ve[Qt])?ve[Qt].call(this,nt):ve[Qt]);return this.format(cr||this.localeData().calendar(Qt,this,js(nt)))},Ji.clone=function(){return new he(this)},Ji.diff=function(Q,ve,nt){var Tt,Qt,cr;if(!this.isValid())return NaN;if(!(Tt=ut(Q,this)).isValid())return NaN;switch(Qt=6e4*(Tt.utcOffset()-this.utcOffset()),ve=Hi(ve)){case"year":cr=Jd(this,Tt)/12;break;case"month":cr=Jd(this,Tt);break;case"quarter":cr=Jd(this,Tt)/3;break;case"second":cr=(this-Tt)/1e3;break;case"minute":cr=(this-Tt)/6e4;break;case"hour":cr=(this-Tt)/36e5;break;case"day":cr=(this-Tt-Qt)/864e5;break;case"week":cr=(this-Tt-Qt)/6048e5;break;default:cr=this-Tt}return nt?cr:Fr(cr)},Ji.endOf=function(Q){var ve,nt;if(void 0===(Q=Hi(Q))||"millisecond"===Q||!this.isValid())return this;switch(nt=this._isUTC?ll:Ol,Q){case"year":ve=nt(this.year()+1,0,1)-1;break;case"quarter":ve=nt(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":ve=nt(this.year(),this.month()+1,1)-1;break;case"week":ve=nt(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":ve=nt(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":ve=nt(this.year(),this.month(),this.date()+1)-1;break;case"hour":ve=this._d.valueOf(),ve+=Hs-ga(ve+(this._isUTC?0:this.utcOffset()*Oa),Hs)-1;break;case"minute":ve=this._d.valueOf(),ve+=Oa-ga(ve,Oa)-1;break;case"second":ve=this._d.valueOf(),ve+=1e3-ga(ve,1e3)-1}return this._d.setTime(ve),u.updateOffset(this,!0),this},Ji.format=function(Q){Q||(Q=this.isUtc()?u.defaultFormatUtc:u.defaultFormat);var ve=Xt(this,Q);return this.localeData().postformat(ve)},Ji.from=function(Q,ve){return this.isValid()&&(ge(Q)&&Q.isValid()||js(Q).isValid())?Tl({to:this,from:Q}).locale(this.locale()).humanize(!ve):this.localeData().invalidDate()},Ji.fromNow=function(Q){return this.from(js(),Q)},Ji.to=function(Q,ve){return this.isValid()&&(ge(Q)&&Q.isValid()||js(Q).isValid())?Tl({from:this,to:Q}).locale(this.locale()).humanize(!ve):this.localeData().invalidDate()},Ji.toNow=function(Q){return this.to(js(),Q)},Ji.get=function(Q){return ze(this[Q=Hi(Q)])?this[Q]():this},Ji.invalidAt=function(){return ee(this).overflow},Ji.isAfter=function(Q,ve){var nt=ge(Q)?Q:js(Q);return!(!this.isValid()||!nt.isValid())&&("millisecond"===(ve=Hi(ve)||"millisecond")?this.valueOf()>nt.valueOf():nt.valueOf()<this.clone().startOf(ve).valueOf())},Ji.isBefore=function(Q,ve){var nt=ge(Q)?Q:js(Q);return!(!this.isValid()||!nt.isValid())&&("millisecond"===(ve=Hi(ve)||"millisecond")?this.valueOf()<nt.valueOf():this.clone().endOf(ve).valueOf()<nt.valueOf())},Ji.isBetween=function(Q,ve,nt,Tt){var Qt=ge(Q)?Q:js(Q),cr=ge(ve)?ve:js(ve);return!!(this.isValid()&&Qt.isValid()&&cr.isValid())&&("("===(Tt=Tt||"()")[0]?this.isAfter(Qt,nt):!this.isBefore(Qt,nt))&&(")"===Tt[1]?this.isBefore(cr,nt):!this.isAfter(cr,nt))},Ji.isSame=function(Q,ve){var Tt,nt=ge(Q)?Q:js(Q);return!(!this.isValid()||!nt.isValid())&&("millisecond"===(ve=Hi(ve)||"millisecond")?this.valueOf()===nt.valueOf():(Tt=nt.valueOf(),this.clone().startOf(ve).valueOf()<=Tt&&Tt<=this.clone().endOf(ve).valueOf()))},Ji.isSameOrAfter=function(Q,ve){return this.isSame(Q,ve)||this.isAfter(Q,ve)},Ji.isSameOrBefore=function(Q,ve){return this.isSame(Q,ve)||this.isBefore(Q,ve)},Ji.isValid=function(){return ae(this)},Ji.lang=Yo,Ji.locale=Ei,Ji.localeData=$a,Ji.max=Uu,Ji.min=Hu,Ji.parsingFlags=function(){return Z({},ee(this))},Ji.set=function(Q,ve){if("object"==typeof Q){var Tt,nt=function(Q){var nt,ve=[];for(nt in Q)_(Q,nt)&&ve.push({unit:nt,priority:Cn[nt]});return ve.sort(function(Tt,Qt){return Tt.priority-Qt.priority}),ve}(Q=Zr(Q)),Qt=nt.length;for(Tt=0;Tt<Qt;Tt++)this[nt[Tt].unit](Q[nt[Tt].unit])}else if(ze(this[Q=Hi(Q)]))return this[Q](ve);return this},Ji.startOf=function(Q){var ve,nt;if(void 0===(Q=Hi(Q))||"millisecond"===Q||!this.isValid())return this;switch(nt=this._isUTC?ll:Ol,Q){case"year":ve=nt(this.year(),0,1);break;case"quarter":ve=nt(this.year(),this.month()-this.month()%3,1);break;case"month":ve=nt(this.year(),this.month(),1);break;case"week":ve=nt(this.year(),this.month(),this.date()-this.weekday());break;case"isoWeek":ve=nt(this.year(),this.month(),this.date()-(this.isoWeekday()-1));break;case"day":case"date":ve=nt(this.year(),this.month(),this.date());break;case"hour":ve=this._d.valueOf(),ve-=ga(ve+(this._isUTC?0:this.utcOffset()*Oa),Hs);break;case"minute":ve=this._d.valueOf(),ve-=ga(ve,Oa);break;case"second":ve=this._d.valueOf(),ve-=ga(ve,1e3)}return this._d.setTime(ve),u.updateOffset(this,!0),this},Ji.subtract=pa,Ji.toArray=function(){var Q=this;return[Q.year(),Q.month(),Q.date(),Q.hour(),Q.minute(),Q.second(),Q.millisecond()]},Ji.toObject=function(){var Q=this;return{years:Q.year(),months:Q.month(),date:Q.date(),hours:Q.hours(),minutes:Q.minutes(),seconds:Q.seconds(),milliseconds:Q.milliseconds()}},Ji.toDate=function(){return new Date(this.valueOf())},Ji.toISOString=function(Q){if(!this.isValid())return null;var ve=!0!==Q,nt=ve?this.clone().utc():this;return nt.year()<0||nt.year()>9999?Xt(nt,ve?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):ze(Date.prototype.toISOString)?ve?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",Xt(nt,"Z")):Xt(nt,ve?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},Ji.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var nt,Tt,Q="moment",ve="";return this.isLocal()||(Q=0===this.utcOffset()?"moment.utc":"moment.parseZone",ve="Z"),nt="["+Q+'("]',Tt=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",this.format(nt+Tt+"-MM-DD[T]HH:mm:ss.SSS"+ve+'[")]')},"undefined"!=typeof Symbol&&null!=Symbol.for&&(Ji[Symbol.for("nodejs.util.inspect.custom")]=function(){return"Moment<"+this.format()+">"}),Ji.toJSON=function(){return this.isValid()?this.toISOString():null},Ji.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},Ji.unix=function(){return Math.floor(this.valueOf()/1e3)},Ji.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},Ji.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},Ji.eraName=function(){var Q,ve,nt,Tt=this.localeData().eras();for(Q=0,ve=Tt.length;Q<ve;++Q)if(nt=this.clone().startOf("day").valueOf(),Tt[Q].since<=nt&&nt<=Tt[Q].until||Tt[Q].until<=nt&&nt<=Tt[Q].since)return Tt[Q].name;return""},Ji.eraNarrow=function(){var Q,ve,nt,Tt=this.localeData().eras();for(Q=0,ve=Tt.length;Q<ve;++Q)if(nt=this.clone().startOf("day").valueOf(),Tt[Q].since<=nt&&nt<=Tt[Q].until||Tt[Q].until<=nt&&nt<=Tt[Q].since)return Tt[Q].narrow;return""},Ji.eraAbbr=function(){var Q,ve,nt,Tt=this.localeData().eras();for(Q=0,ve=Tt.length;Q<ve;++Q)if(nt=this.clone().startOf("day").valueOf(),Tt[Q].since<=nt&&nt<=Tt[Q].until||Tt[Q].until<=nt&&nt<=Tt[Q].since)return Tt[Q].abbr;return""},Ji.eraYear=function(){var Q,ve,nt,Tt,Qt=this.localeData().eras();for(Q=0,ve=Qt.length;Q<ve;++Q)if(nt=Qt[Q].since<=Qt[Q].until?1:-1,Tt=this.clone().startOf("day").valueOf(),Qt[Q].since<=Tt&&Tt<=Qt[Q].until||Qt[Q].until<=Tt&&Tt<=Qt[Q].since)return(this.year()-u(Qt[Q].since).year())*nt+Qt[Q].offset;return this.year()},Ji.year=us,Ji.isLeapYear=function(){return rr(this.year())},Ji.weekYear=function(Q){return yd.call(this,Q,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},Ji.isoWeekYear=function(Q){return yd.call(this,Q,this.isoWeek(),this.isoWeekday(),1,4)},Ji.quarter=Ji.quarters=function(Q){return null==Q?Math.ceil((this.month()+1)/3):this.month(3*(Q-1)+this.month()%3)},Ji.month=Es,Ji.daysInMonth=function(){return tr(this.year(),this.month())},Ji.week=Ji.weeks=function(Q){var ve=this.localeData().week(this);return null==Q?ve:this.add(7*(Q-ve),"d")},Ji.isoWeek=Ji.isoWeeks=function(Q){var ve=Il(this,1,4).week;return null==Q?ve:this.add(7*(Q-ve),"d")},Ji.weeksInYear=function(){var Q=this.localeData()._week;return fo(this.year(),Q.dow,Q.doy)},Ji.weeksInWeekYear=function(){var Q=this.localeData()._week;return fo(this.weekYear(),Q.dow,Q.doy)},Ji.isoWeeksInYear=function(){return fo(this.year(),1,4)},Ji.isoWeeksInISOWeekYear=function(){return fo(this.isoWeekYear(),1,4)},Ji.date=_f,Ji.day=Ji.days=function(Q){if(!this.isValid())return null!=Q?this:NaN;var ve=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=Q?(Q=function(Q,ve){return"string"!=typeof Q?Q:isNaN(Q)?"number"==typeof(Q=ve.weekdaysParse(Q))?Q:null:parseInt(Q,10)}(Q,this.localeData()),this.add(Q-ve,"d")):ve},Ji.weekday=function(Q){if(!this.isValid())return null!=Q?this:NaN;var ve=(this.day()+7-this.localeData()._week.dow)%7;return null==Q?ve:this.add(Q-ve,"d")},Ji.isoWeekday=function(Q){if(!this.isValid())return null!=Q?this:NaN;if(null!=Q){var ve=function(Q,ve){return"string"==typeof Q?ve.weekdaysParse(Q)%7||7:isNaN(Q)?null:Q}(Q,this.localeData());return this.day(this.day()%7?ve:ve-7)}return this.day()||7},Ji.dayOfYear=function(Q){var ve=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==Q?ve:this.add(Q-ve,"d")},Ji.hour=Ji.hours=qc,Ji.minute=Ji.minutes=Ql,Ji.second=Ji.seconds=Hf,Ji.millisecond=Ji.milliseconds=Kf,Ji.utcOffset=function(Q,ve,nt){var Qt,Tt=this._offset||0;if(!this.isValid())return null!=Q?this:NaN;if(null!=Q){if("string"==typeof Q){if(null===(Q=vt(Er,Q)))return this}else Math.abs(Q)<16&&!nt&&(Q*=60);return!this._isUTC&&ve&&(Qt=un(this)),this._offset=Q,this._isUTC=!0,null!=Qt&&this.add(Qt,"m"),Tt!==Q&&(!ve||this._changeInProgress?$i(this,Tl(Q-Tt,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,u.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?Tt:un(this)},Ji.utc=function(Q){return this.utcOffset(0,Q)},Ji.local=function(Q){return this._isUTC&&(this.utcOffset(0,Q),this._isUTC=!1,Q&&this.subtract(un(this),"m")),this},Ji.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var Q=vt(An,this._i);null!=Q?this.utcOffset(Q):this.utcOffset(0,!0)}return this},Ji.hasAlignedHourOffset=function(Q){return!!this.isValid()&&(Q=Q?js(Q).utcOffset():0,(this.utcOffset()-Q)%60==0)},Ji.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},Ji.isLocal=function(){return!!this.isValid()&&!this._isUTC},Ji.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},Ji.isUtc=ao,Ji.isUTC=ao,Ji.zoneAbbr=function(){return this._isUTC?"UTC":""},Ji.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},Ji.dates=ce("dates accessor is deprecated. Use date instead.",_f),Ji.months=ce("months accessor is deprecated. Use month instead",Es),Ji.years=ce("years accessor is deprecated. Use year instead",us),Ji.zone=ce("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(Q,ve){return null!=Q?("string"!=typeof Q&&(Q=-Q),this.utcOffset(Q,ve),this):-this.utcOffset()}),Ji.isDSTShifted=ce("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!S(this._isDSTShifted))return this._isDSTShifted;var ve,Q={};return ie(Q,this),(Q=Mu(Q))._a?(ve=Q._isUTC?J(Q._a):js(Q._a),this._isDSTShifted=this.isValid()&&function(Q,ve,nt){var bi,Tt=Math.min(Q.length,ve.length),Qt=Math.abs(Q.length-ve.length),cr=0;for(bi=0;bi<Tt;bi++)(nt&&Q[bi]!==ve[bi]||!nt&&Gn(Q[bi])!==Gn(ve[bi]))&&cr++;return cr+Qt}(Q._a,ve.toArray())>0):this._isDSTShifted=!1,this._isDSTShifted});var rl=je.prototype;function Yu(Q,ve,nt,Tt){var Qt=xe(),cr=J().set(Tt,ve);return Qt[nt](cr,Q)}function pc(Q,ve,nt){if(A(Q)&&(ve=Q,Q=void 0),Q=Q||"",null!=ve)return Yu(Q,ve,nt,"month");var Tt,Qt=[];for(Tt=0;Tt<12;Tt++)Qt[Tt]=Yu(Q,Tt,nt,"month");return Qt}function Kd(Q,ve,nt,Tt){"boolean"==typeof Q?(A(ve)&&(nt=ve,ve=void 0),ve=ve||""):(nt=ve=Q,Q=!1,A(ve)&&(nt=ve,ve=void 0),ve=ve||"");var bi,Qt=xe(),cr=Q?Qt._week.dow:0,cs=[];if(null!=nt)return Yu(ve,(nt+cr)%7,Tt,"day");for(bi=0;bi<7;bi++)cs[bi]=Yu(ve,(bi+cr)%7,Tt,"day");return cs}rl.calendar=function(Q,ve,nt){var Tt=this._calendar[Q]||this._calendar.sameElse;return ze(Tt)?Tt.call(ve,nt):Tt},rl.longDateFormat=function(Q){var ve=this._longDateFormat[Q],nt=this._longDateFormat[Q.toUpperCase()];return ve||!nt?ve:(this._longDateFormat[Q]=nt.match(It).map(function(Tt){return"MMMM"===Tt||"MM"===Tt||"DD"===Tt||"dddd"===Tt?Tt.slice(1):Tt}).join(""),this._longDateFormat[Q])},rl.invalidDate=function(){return this._invalidDate},rl.ordinal=function(Q){return this._ordinal.replace("%d",Q)},rl.preparse=Pd,rl.postformat=Pd,rl.relativeTime=function(Q,ve,nt,Tt){var Qt=this._relativeTime[nt];return ze(Qt)?Qt(Q,ve,nt,Tt):Qt.replace(/%d/i,Q)},rl.pastFuture=function(Q,ve){var nt=this._relativeTime[Q>0?"future":"past"];return ze(nt)?nt(ve):nt.replace(/%s/i,ve)},rl.set=function(Q){var ve,nt;for(nt in Q)_(Q,nt)&&(ze(ve=Q[nt])?this[nt]=ve:this["_"+nt]=ve);this._config=Q,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},rl.eras=function(Q,ve){var nt,Tt,Qt,cr=this._eras||xe("en")._eras;for(nt=0,Tt=cr.length;nt<Tt;++nt){switch(typeof cr[nt].since){case"string":Qt=u(cr[nt].since).startOf("day"),cr[nt].since=Qt.valueOf()}switch(typeof cr[nt].until){case"undefined":cr[nt].until=1/0;break;case"string":Qt=u(cr[nt].until).startOf("day").valueOf(),cr[nt].until=Qt.valueOf()}}return cr},rl.erasParse=function(Q,ve,nt){var Tt,Qt,bi,cs,xa,cr=this.eras();for(Q=Q.toUpperCase(),Tt=0,Qt=cr.length;Tt<Qt;++Tt)if(bi=cr[Tt].name.toUpperCase(),cs=cr[Tt].abbr.toUpperCase(),xa=cr[Tt].narrow.toUpperCase(),nt)switch(ve){case"N":case"NN":case"NNN":if(cs===Q)return cr[Tt];break;case"NNNN":if(bi===Q)return cr[Tt];break;case"NNNNN":if(xa===Q)return cr[Tt]}else if([bi,cs,xa].indexOf(Q)>=0)return cr[Tt]},rl.erasConvertYear=function(Q,ve){var nt=Q.since<=Q.until?1:-1;return void 0===ve?u(Q.since).year():u(Q.since).year()+(ve-Q.offset)*nt},rl.erasAbbrRegex=function(Q){return _(this,"_erasAbbrRegex")||vd.call(this),Q?this._erasAbbrRegex:this._erasRegex},rl.erasNameRegex=function(Q){return _(this,"_erasNameRegex")||vd.call(this),Q?this._erasNameRegex:this._erasRegex},rl.erasNarrowRegex=function(Q){return _(this,"_erasNarrowRegex")||vd.call(this),Q?this._erasNarrowRegex:this._erasRegex},rl.months=function(Q,ve){return Q?d(this._months)?this._months[Q.month()]:this._months[(this._months.isFormat||_t).test(ve)?"format":"standalone"][Q.month()]:d(this._months)?this._months:this._months.standalone},rl.monthsShort=function(Q,ve){return Q?d(this._monthsShort)?this._monthsShort[Q.month()]:this._monthsShort[_t.test(ve)?"format":"standalone"][Q.month()]:d(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},rl.monthsParse=function(Q,ve,nt){var Tt,Qt,cr;if(this._monthsParseExact)return Vi.call(this,Q,ve,nt);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),Tt=0;Tt<12;Tt++){if(Qt=J([2e3,Tt]),nt&&!this._longMonthsParse[Tt]&&(this._longMonthsParse[Tt]=new RegExp("^"+this.months(Qt,"").replace(".","")+"$","i"),this._shortMonthsParse[Tt]=new RegExp("^"+this.monthsShort(Qt,"").replace(".","")+"$","i")),!nt&&!this._monthsParse[Tt]&&(cr="^"+this.months(Qt,"")+"|^"+this.monthsShort(Qt,""),this._monthsParse[Tt]=new RegExp(cr.replace(".",""),"i")),nt&&"MMMM"===ve&&this._longMonthsParse[Tt].test(Q))return Tt;if(nt&&"MMM"===ve&&this._shortMonthsParse[Tt].test(Q))return Tt;if(!nt&&this._monthsParse[Tt].test(Q))return Tt}},rl.monthsRegex=function(Q){return this._monthsParseExact?(_(this,"_monthsRegex")||ta.call(this),Q?this._monthsStrictRegex:this._monthsRegex):(_(this,"_monthsRegex")||(this._monthsRegex=jt),this._monthsStrictRegex&&Q?this._monthsStrictRegex:this._monthsRegex)},rl.monthsShortRegex=function(Q){return this._monthsParseExact?(_(this,"_monthsRegex")||ta.call(this),Q?this._monthsShortStrictRegex:this._monthsShortRegex):(_(this,"_monthsShortRegex")||(this._monthsShortRegex=mt),this._monthsShortStrictRegex&&Q?this._monthsShortStrictRegex:this._monthsShortRegex)},rl.week=function(Q){return Il(Q,this._week.dow,this._week.doy).week},rl.firstDayOfYear=function(){return this._week.doy},rl.firstDayOfWeek=function(){return this._week.dow},rl.weekdays=function(Q,ve){var nt=d(this._weekdays)?this._weekdays:this._weekdays[Q&&!0!==Q&&this._weekdays.isFormat.test(ve)?"format":"standalone"];return!0===Q?bo(nt,this._week.dow):Q?nt[Q.day()]:nt},rl.weekdaysMin=function(Q){return!0===Q?bo(this._weekdaysMin,this._week.dow):Q?this._weekdaysMin[Q.day()]:this._weekdaysMin},rl.weekdaysShort=function(Q){return!0===Q?bo(this._weekdaysShort,this._week.dow):Q?this._weekdaysShort[Q.day()]:this._weekdaysShort},rl.weekdaysParse=function(Q,ve,nt){var Tt,Qt,cr;if(this._weekdaysParseExact)return Lt.call(this,Q,ve,nt);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),Tt=0;Tt<7;Tt++){if(Qt=J([2e3,1]).day(Tt),nt&&!this._fullWeekdaysParse[Tt]&&(this._fullWeekdaysParse[Tt]=new RegExp("^"+this.weekdays(Qt,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[Tt]=new RegExp("^"+this.weekdaysShort(Qt,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[Tt]=new RegExp("^"+this.weekdaysMin(Qt,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[Tt]||(cr="^"+this.weekdays(Qt,"")+"|^"+this.weekdaysShort(Qt,"")+"|^"+this.weekdaysMin(Qt,""),this._weekdaysParse[Tt]=new RegExp(cr.replace(".",""),"i")),nt&&"dddd"===ve&&this._fullWeekdaysParse[Tt].test(Q))return Tt;if(nt&&"ddd"===ve&&this._shortWeekdaysParse[Tt].test(Q))return Tt;if(nt&&"dd"===ve&&this._minWeekdaysParse[Tt].test(Q))return Tt;if(!nt&&this._weekdaysParse[Tt].test(Q))return Tt}},rl.weekdaysRegex=function(Q){return this._weekdaysParseExact?(_(this,"_weekdaysRegex")||Eo.call(this),Q?this._weekdaysStrictRegex:this._weekdaysRegex):(_(this,"_weekdaysRegex")||(this._weekdaysRegex=$r),this._weekdaysStrictRegex&&Q?this._weekdaysStrictRegex:this._weekdaysRegex)},rl.weekdaysShortRegex=function(Q){return this._weekdaysParseExact?(_(this,"_weekdaysRegex")||Eo.call(this),Q?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(_(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=to),this._weekdaysShortStrictRegex&&Q?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},rl.weekdaysMinRegex=function(Q){return this._weekdaysParseExact?(_(this,"_weekdaysRegex")||Eo.call(this),Q?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(_(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=tt),this._weekdaysMinStrictRegex&&Q?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},rl.isPM=function(Q){return"p"===(Q+"").toLowerCase().charAt(0)},rl.meridiem=function(Q,ve,nt){return Q>11?nt?"pm":"PM":nt?"am":"AM"},dt("en",{eras:[{since:"0001-01-01",until:1/0,offset:1,name:"Anno Domini",narrow:"AD",abbr:"AD"},{since:"0000-12-31",until:-1/0,offset:1,name:"Before Christ",narrow:"BC",abbr:"BC"}],dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(Q){var ve=Q%10;return Q+(1===Gn(Q%100/10)?"th":1===ve?"st":2===ve?"nd":3===ve?"rd":"th")}}),u.lang=ce("moment.lang is deprecated. Use moment.locale instead.",dt),u.langData=ce("moment.langData is deprecated. Use moment.localeData instead.",xe);var _u=Math.abs;function Hc(Q,ve,nt,Tt){var Qt=Tl(ve,nt);return Q._milliseconds+=Tt*Qt._milliseconds,Q._days+=Tt*Qt._days,Q._months+=Tt*Qt._months,Q._bubble()}function Ou(Q){return Q<0?Math.floor(Q):Math.ceil(Q)}function bu(Q){return 4800*Q/146097}function h(Q){return 146097*Q/4800}function F(Q){return function(){return this.as(Q)}}var q=F("ms"),de=F("s"),ye=F("m"),Ue=F("h"),Oe=F("d"),Xe=F("w"),gt=F("M"),yt=F("Q"),nn=F("y");function ir(Q){return function(){return this.isValid()?this._data[Q]:NaN}}var Gr=ir("milliseconds"),Pi=ir("seconds"),Zo=ir("minutes"),Lo=ir("hours"),Gs=ir("days"),Xs=ir("months"),dl=ir("years");var ia=Math.round,Pa={ss:44,s:45,m:45,h:22,d:26,w:null,M:11};function il(Q,ve,nt,Tt,Qt){return Qt.relativeTime(ve||1,!!nt,Q,Tt)}var Nc=Math.abs;function sc(Q){return(Q>0)-(Q<0)||+Q}function gf(){if(!this.isValid())return this.localeData().invalidDate();var Tt,Qt,cr,bi,xa,na,_l,zl,Q=Nc(this._milliseconds)/1e3,ve=Nc(this._days),nt=Nc(this._months),cs=this.asSeconds();return cs?(Tt=Fr(Q/60),Qt=Fr(Tt/60),Q%=60,Tt%=60,cr=Fr(nt/12),nt%=12,bi=Q?Q.toFixed(3).replace(/\.?0+$/,""):"",xa=cs<0?"-":"",na=sc(this._months)!==sc(cs)?"-":"",_l=sc(this._days)!==sc(cs)?"-":"",zl=sc(this._milliseconds)!==sc(cs)?"-":"",xa+"P"+(cr?na+cr+"Y":"")+(nt?na+nt+"M":"")+(ve?_l+ve+"D":"")+(Qt||Tt||Q?"T":"")+(Qt?zl+Qt+"H":"")+(Tt?zl+Tt+"M":"")+(Q?zl+bi+"S":"")):"P0D"}var Ga=El.prototype;return Ga.isValid=function(){return this._isValid},Ga.abs=function(){var Q=this._data;return this._milliseconds=_u(this._milliseconds),this._days=_u(this._days),this._months=_u(this._months),Q.milliseconds=_u(Q.milliseconds),Q.seconds=_u(Q.seconds),Q.minutes=_u(Q.minutes),Q.hours=_u(Q.hours),Q.months=_u(Q.months),Q.years=_u(Q.years),this},Ga.add=function(Q,ve){return Hc(this,Q,ve,1)},Ga.subtract=function(Q,ve){return Hc(this,Q,ve,-1)},Ga.as=function(Q){if(!this.isValid())return NaN;var ve,nt,Tt=this._milliseconds;if("month"===(Q=Hi(Q))||"quarter"===Q||"year"===Q)switch(ve=this._days+Tt/864e5,nt=this._months+bu(ve),Q){case"month":return nt;case"quarter":return nt/3;case"year":return nt/12}else switch(ve=this._days+Math.round(h(this._months)),Q){case"week":return ve/7+Tt/6048e5;case"day":return ve+Tt/864e5;case"hour":return 24*ve+Tt/36e5;case"minute":return 1440*ve+Tt/6e4;case"second":return 86400*ve+Tt/1e3;case"millisecond":return Math.floor(864e5*ve)+Tt;default:throw new Error("Unknown unit "+Q)}},Ga.asMilliseconds=q,Ga.asSeconds=de,Ga.asMinutes=ye,Ga.asHours=Ue,Ga.asDays=Oe,Ga.asWeeks=Xe,Ga.asMonths=gt,Ga.asQuarters=yt,Ga.asYears=nn,Ga.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*Gn(this._months/12):NaN},Ga._bubble=function(){var Qt,cr,bi,cs,xa,Q=this._milliseconds,ve=this._days,nt=this._months,Tt=this._data;return Q>=0&&ve>=0&&nt>=0||Q<=0&&ve<=0&&nt<=0||(Q+=864e5*Ou(h(nt)+ve),ve=0,nt=0),Tt.milliseconds=Q%1e3,Qt=Fr(Q/1e3),Tt.seconds=Qt%60,cr=Fr(Qt/60),Tt.minutes=cr%60,bi=Fr(cr/60),Tt.hours=bi%24,ve+=Fr(bi/24),nt+=xa=Fr(bu(ve)),ve-=Ou(h(xa)),cs=Fr(nt/12),nt%=12,Tt.days=ve,Tt.months=nt,Tt.years=cs,this},Ga.clone=function(){return Tl(this)},Ga.get=function(Q){return Q=Hi(Q),this.isValid()?this[Q+"s"]():NaN},Ga.milliseconds=Gr,Ga.seconds=Pi,Ga.minutes=Zo,Ga.hours=Lo,Ga.days=Gs,Ga.weeks=function(){return Fr(this.days()/7)},Ga.months=Xs,Ga.years=dl,Ga.humanize=function(Q,ve){if(!this.isValid())return this.localeData().invalidDate();var Qt,cr,nt=!1,Tt=Pa;return"object"==typeof Q&&(ve=Q,Q=!1),"boolean"==typeof Q&&(nt=Q),"object"==typeof ve&&(Tt=Object.assign({},Pa,ve),null!=ve.s&&null==ve.ss&&(Tt.ss=ve.s-1)),cr=function(Q,ve,nt,Tt){var Qt=Tl(Q).abs(),cr=ia(Qt.as("s")),bi=ia(Qt.as("m")),cs=ia(Qt.as("h")),xa=ia(Qt.as("d")),na=ia(Qt.as("M")),_l=ia(Qt.as("w")),zl=ia(Qt.as("y")),zc=cr<=nt.ss&&["s",cr]||cr<nt.s&&["ss",cr]||bi<=1&&["m"]||bi<nt.m&&["mm",bi]||cs<=1&&["h"]||cs<nt.h&&["hh",cs]||xa<=1&&["d"]||xa<nt.d&&["dd",xa];return null!=nt.w&&(zc=zc||_l<=1&&["w"]||_l<nt.w&&["ww",_l]),(zc=zc||na<=1&&["M"]||na<nt.M&&["MM",na]||zl<=1&&["y"]||["yy",zl])[2]=ve,zc[3]=+Q>0,zc[4]=Tt,il.apply(null,zc)}(this,!nt,Tt,Qt=this.localeData()),nt&&(cr=Qt.pastFuture(+this,cr)),Qt.postformat(cr)},Ga.toISOString=gf,Ga.toString=gf,Ga.toJSON=gf,Ga.locale=Ei,Ga.localeData=$a,Ga.toIsoString=ce("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",gf),Ga.lang=Yo,bt("X",0,0,"unix"),bt("x",0,0,"valueOf"),ar("x",mi),ar("X",/[+-]?\d+(\.\d{1,3})?/),Gi("X",function(Q,ve,nt){nt._d=new Date(1e3*parseFloat(Q))}),Gi("x",function(Q,ve,nt){nt._d=new Date(Gn(Q))}),u.version="2.29.3",r=js,u.fn=Ji,u.min=function(){return Bo("isBefore",[].slice.call(arguments,0))},u.max=function(){return Bo("isAfter",[].slice.call(arguments,0))},u.now=function(){return Date.now?Date.now():+new Date},u.utc=J,u.unix=function(Q){return js(1e3*Q)},u.months=function(Q,ve){return pc(Q,ve,"months")},u.isDate=N,u.locale=dt,u.invalid=H,u.duration=Tl,u.isMoment=ge,u.weekdays=function(Q,ve,nt){return Kd(Q,ve,nt,"weekdays")},u.parseZone=function(){return js.apply(null,arguments).parseZone()},u.localeData=xe,u.isDuration=Ul,u.monthsShort=function(Q,ve){return pc(Q,ve,"monthsShort")},u.weekdaysMin=function(Q,ve,nt){return Kd(Q,ve,nt,"weekdaysMin")},u.defineLocale=Te,u.updateLocale=function(Q,ve){if(null!=ve){var nt,Tt,Qt=Yl;null!=Fs[Q]&&null!=Fs[Q].parentLocale?Fs[Q].set(Pe(Fs[Q]._config,ve)):(null!=(Tt=Pt(Q))&&(Qt=Tt._config),ve=Pe(Qt,ve),null==Tt&&(ve.abbr=Q),(nt=new je(ve)).parentLocale=Fs[Q],Fs[Q]=nt),dt(Q)}else null!=Fs[Q]&&(null!=Fs[Q].parentLocale?(Fs[Q]=Fs[Q].parentLocale,Q===dt()&&dt(Q)):null!=Fs[Q]&&delete Fs[Q]);return Fs[Q]},u.locales=function(){return He(Fs)},u.weekdaysShort=function(Q,ve,nt){return Kd(Q,ve,nt,"weekdaysShort")},u.normalizeUnits=Hi,u.relativeTimeRounding=function(Q){return void 0===Q?ia:"function"==typeof Q&&(ia=Q,!0)},u.relativeTimeThreshold=function(Q,ve){return void 0!==Pa[Q]&&(void 0===ve?Pa[Q]:(Pa[Q]=ve,"s"===Q&&(Pa.ss=ve-1),!0))},u.calendarFormat=function(Q,ve){var nt=Q.diff(ve,"days",!0);return nt<-6?"sameElse":nt<-1?"lastWeek":nt<0?"lastDay":nt<1?"sameDay":nt<2?"nextDay":nt<7?"nextWeek":"sameElse"},u.prototype=Ji,u.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},u}()},11971:(v,T,i)=>{"use strict";i.d(T,{_:()=>_,w:()=>S});var r=i(74788),u=i(12057),p=function(A,N,L,Z){var ee,J=arguments.length,K=J<3?N:null===Z?Z=Object.getOwnPropertyDescriptor(N,L):Z;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)K=Reflect.decorate(A,N,L,Z);else for(var ue=A.length-1;ue>=0;ue--)(ee=A[ue])&&(K=(J<3?ee(K):J>3?ee(N,L,K):ee(N,L))||K);return J>3&&K&&Object.defineProperty(N,L,K),K},d=function(A,N){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(A,N)},e=function(A,N){return function(L,Z){N(L,Z,A)}},_=function(){function A(N,L,Z){this._el=N,this._ngZone=L,this.platformId=Z,this.clickOutsideEnabled=!0,this.attachOutsideOnClick=!1,this.delayClickOutsideInit=!1,this.emitOnBlur=!1,this.exclude="",this.excludeBeforeClick=!1,this.clickOutsideEvents="",this.clickOutside=new r.vpe,this._nodesExcluded=[],this._events=["click"],this._initOnClickBody=this._initOnClickBody.bind(this),this._onClickBody=this._onClickBody.bind(this),this._onWindowBlur=this._onWindowBlur.bind(this)}return A.prototype.ngOnInit=function(){!(0,u.NF)(this.platformId)||this._init()},A.prototype.ngOnDestroy=function(){!(0,u.NF)(this.platformId)||(this._removeClickOutsideListener(),this._removeAttachOutsideOnClickListener(),this._removeWindowBlurListener())},A.prototype.ngOnChanges=function(N){!(0,u.NF)(this.platformId)||(N.attachOutsideOnClick||N.exclude||N.emitOnBlur)&&this._init()},A.prototype._init=function(){""!==this.clickOutsideEvents&&(this._events=this.clickOutsideEvents.split(",").map(function(N){return N.trim()})),this._excludeCheck(),this.attachOutsideOnClick?this._initAttachOutsideOnClickListener():this._initOnClickBody(),this.emitOnBlur&&this._initWindowBlurListener()},A.prototype._initOnClickBody=function(){this.delayClickOutsideInit?setTimeout(this._initClickOutsideListener.bind(this)):this._initClickOutsideListener()},A.prototype._excludeCheck=function(){if(this.exclude)try{var N=Array.from(document.querySelectorAll(this.exclude));N&&(this._nodesExcluded=N)}catch(L){console.error("[ng-click-outside] Check your exclude selector syntax.",L)}},A.prototype._onClickBody=function(N){!this.clickOutsideEnabled||(this.excludeBeforeClick&&this._excludeCheck(),!this._el.nativeElement.contains(N.target)&&!this._shouldExclude(N.target)&&(this._emit(N),this.attachOutsideOnClick&&this._removeClickOutsideListener()))},A.prototype._onWindowBlur=function(N){var L=this;setTimeout(function(){document.hidden||L._emit(N)})},A.prototype._emit=function(N){var L=this;!this.clickOutsideEnabled||this._ngZone.run(function(){return L.clickOutside.emit(N)})},A.prototype._shouldExclude=function(N){for(var L=0,Z=this._nodesExcluded;L<Z.length;L++)if(Z[L].contains(N))return!0;return!1},A.prototype._initClickOutsideListener=function(){var N=this;this._ngZone.runOutsideAngular(function(){N._events.forEach(function(L){return document.addEventListener(L,N._onClickBody)})})},A.prototype._removeClickOutsideListener=function(){var N=this;this._ngZone.runOutsideAngular(function(){N._events.forEach(function(L){return document.removeEventListener(L,N._onClickBody)})})},A.prototype._initAttachOutsideOnClickListener=function(){var N=this;this._ngZone.runOutsideAngular(function(){N._events.forEach(function(L){return N._el.nativeElement.addEventListener(L,N._initOnClickBody)})})},A.prototype._removeAttachOutsideOnClickListener=function(){var N=this;this._ngZone.runOutsideAngular(function(){N._events.forEach(function(L){return N._el.nativeElement.removeEventListener(L,N._initOnClickBody)})})},A.prototype._initWindowBlurListener=function(){var N=this;this._ngZone.runOutsideAngular(function(){window.addEventListener("blur",N._onWindowBlur)})},A.prototype._removeWindowBlurListener=function(){var N=this;this._ngZone.runOutsideAngular(function(){window.removeEventListener("blur",N._onWindowBlur)})},p([(0,r.IIB)(),d("design:type",Boolean)],A.prototype,"clickOutsideEnabled",void 0),p([(0,r.IIB)(),d("design:type",Boolean)],A.prototype,"attachOutsideOnClick",void 0),p([(0,r.IIB)(),d("design:type",Boolean)],A.prototype,"delayClickOutsideInit",void 0),p([(0,r.IIB)(),d("design:type",Boolean)],A.prototype,"emitOnBlur",void 0),p([(0,r.IIB)(),d("design:type",String)],A.prototype,"exclude",void 0),p([(0,r.IIB)(),d("design:type",Boolean)],A.prototype,"excludeBeforeClick",void 0),p([(0,r.IIB)(),d("design:type",String)],A.prototype,"clickOutsideEvents",void 0),p([(0,r.r_U)(),d("design:type",r.vpe)],A.prototype,"clickOutside",void 0),(A=p([e(2,(0,r.tBr)(r.Lbi)),d("design:paramtypes",[r.SBq,r.R0b,Object])],A)).\u0275fac=function(L){return new(L||A)(r.Y36(r.SBq),r.Y36(r.R0b),r.Y36(r.Lbi))},A.\u0275dir=r.lG2({type:A,selectors:[["","clickOutside",""]],inputs:{clickOutsideEnabled:"clickOutsideEnabled",attachOutsideOnClick:"attachOutsideOnClick",delayClickOutsideInit:"delayClickOutsideInit",emitOnBlur:"emitOnBlur",exclude:"exclude",excludeBeforeClick:"excludeBeforeClick",clickOutsideEvents:"clickOutsideEvents"},outputs:{clickOutside:"clickOutside"},features:[r.TTD]}),A.\u0275prov=r.Yz7({token:A,factory:function(N){return A.\u0275fac(N)}}),A}(),S=function(){function A(){}return A.\u0275fac=function(L){return new(L||A)},A.\u0275mod=r.oAB({type:A}),A.\u0275inj=r.cJS({}),A}()},7194:(v,T,i)=>{"use strict";i.d(T,{jh:()=>ge,m9:()=>De});var r=i(74788),u=i(26215),p=i(57765);var S=i(6823);const A=[[255,99,132],[54,162,235],[255,206,86],[231,233,237],[75,192,192],[151,187,205],[220,220,220],[247,70,74],[70,191,189],[253,180,92],[148,159,177],[77,83,96]];function L(Be,Pe){return"rgba("+Be.concat(Pe).join(",")+")"}function Z(Be,Pe){return Math.floor(Math.random()*(Pe-Be+1))+Be}function ee(Be){return{backgroundColor:Be.map(Pe=>L(Pe,.6)),borderColor:Be.map(()=>"#fff"),pointBackgroundColor:Be.map(Pe=>L(Pe,1)),pointBorderColor:Be.map(()=>"#fff"),pointHoverBackgroundColor:Be.map(Pe=>L(Pe,1)),pointHoverBorderColor:Be.map(Pe=>L(Pe,1))}}function ae(){return[Z(0,255),Z(0,255),Z(0,255)]}function H(Be){return A[Be]||ae()}function se(Be){const Pe=new Array(Be);for(let je=0;je<Be;je++)Pe[je]=A[je]||ae();return Pe}let Ee=(()=>{class Be{constructor(){this.pColorschemesOptions={},this.colorschemesOptions=new u.X({})}setColorschemesOptions(je){this.pColorschemesOptions=je,this.colorschemesOptions.next(je)}getColorschemesOptions(){return this.pColorschemesOptions}}return Be.\u0275fac=function(je){return new(je||Be)},Be.\u0275prov=(0,r.Yz7)({factory:function(){return new Be},token:Be,providedIn:"root"}),Be})();const he={Default:0,Update:1,Refresh:2};he[he.Default]="Default",he[he.Update]="Update",he[he.Refresh]="Refresh";let ge=(()=>{class Be{constructor(je,He){this.element=je,this.themeService=He,this.options={},this.chartClick=new r.vpe,this.chartHover=new r.vpe,this.old={dataExists:!1,dataLength:0,datasetsExists:!1,datasetsLength:0,datasetsDataObjects:[],datasetsDataLengths:[],colorsExists:!1,colors:[],labelsExist:!1,labels:[],legendExists:!1,legend:{}},this.subs=[]}static registerPlugin(je){S.pluginService.register(je)}static unregisterPlugin(je){S.pluginService.unregister(je)}ngOnInit(){this.ctx=this.element.nativeElement.getContext("2d"),this.refresh(),this.subs.push(this.themeService.colorschemesOptions.subscribe(je=>this.themeChanged(je)))}themeChanged(je){this.refresh()}ngDoCheck(){if(!this.chart)return;let je=he.Default;const He=Vt=>{je=Vt>je?Vt:je};switch(!!this.data!==this.old.dataExists&&(this.propagateDataToDatasets(this.data),this.old.dataExists=!!this.data,He(he.Update)),this.data&&this.data.length!==this.old.dataLength&&(this.old.dataLength=this.data&&this.data.length||0,He(he.Update)),!!this.datasets!==this.old.datasetsExists&&(this.old.datasetsExists=!!this.datasets,He(he.Update)),this.datasets&&this.datasets.length!==this.old.datasetsLength&&(this.old.datasetsLength=this.datasets&&this.datasets.length||0,He(he.Update)),this.datasets&&this.datasets.filter((Vt,it)=>Vt.data!==this.old.datasetsDataObjects[it]).length&&(this.old.datasetsDataObjects=this.datasets.map(Vt=>Vt.data),He(he.Update)),this.datasets&&this.datasets.filter((Vt,it)=>Vt.data.length!==this.old.datasetsDataLengths[it]).length&&(this.old.datasetsDataLengths=this.datasets.map(Vt=>Vt.data.length),He(he.Update)),!!this.colors!==this.old.colorsExists&&(this.old.colorsExists=!!this.colors,this.updateColors(),He(he.Update)),this.colors&&this.colors.filter((Vt,it)=>!this.colorsEqual(Vt,this.old.colors[it])).length&&(this.old.colors=this.colors.map(Vt=>this.copyColor(Vt)),this.updateColors(),He(he.Update)),!!this.labels!==this.old.labelsExist&&(this.old.labelsExist=!!this.labels,He(he.Update)),this.labels&&this.labels.filter((Vt,it)=>!this.labelsEqual(Vt,this.old.labels[it])).length&&(this.old.labels=this.labels.map(Vt=>this.copyLabel(Vt)),He(he.Update)),!!this.options.legend!==this.old.legendExists&&(this.old.legendExists=!!this.options.legend,He(he.Refresh)),this.options.legend&&this.options.legend.position!==this.old.legend.position&&(this.old.legend.position=this.options.legend.position,He(he.Refresh)),je){case he.Default:break;case he.Update:this.update();break;case he.Refresh:this.refresh()}}copyLabel(je){return Array.isArray(je)?[...je]:je}labelsEqual(je,He){return Array.isArray(je)===Array.isArray(He)&&(Array.isArray(je)||je===He)&&(!Array.isArray(je)||je.length===He.length)&&(!Array.isArray(je)||0===je.filter((Vt,it)=>Vt!==He[it]).length)}copyColor(je){return{backgroundColor:je.backgroundColor,borderWidth:je.borderWidth,borderColor:je.borderColor,borderCapStyle:je.borderCapStyle,borderDash:je.borderDash,borderDashOffset:je.borderDashOffset,borderJoinStyle:je.borderJoinStyle,pointBorderColor:je.pointBorderColor,pointBackgroundColor:je.pointBackgroundColor,pointBorderWidth:je.pointBorderWidth,pointRadius:je.pointRadius,pointHoverRadius:je.pointHoverRadius,pointHitRadius:je.pointHitRadius,pointHoverBackgroundColor:je.pointHoverBackgroundColor,pointHoverBorderColor:je.pointHoverBorderColor,pointHoverBorderWidth:je.pointHoverBorderWidth,pointStyle:je.pointStyle,hoverBackgroundColor:je.hoverBackgroundColor,hoverBorderColor:je.hoverBorderColor,hoverBorderWidth:je.hoverBorderWidth}}colorsEqual(je,He){return!je==!He&&(!je||je.backgroundColor===He.backgroundColor&&je.borderWidth===He.borderWidth&&je.borderColor===He.borderColor&&je.borderCapStyle===He.borderCapStyle&&je.borderDash===He.borderDash&&je.borderDashOffset===He.borderDashOffset&&je.borderJoinStyle===He.borderJoinStyle&&je.pointBorderColor===He.pointBorderColor&&je.pointBackgroundColor===He.pointBackgroundColor&&je.pointBorderWidth===He.pointBorderWidth&&je.pointRadius===He.pointRadius&&je.pointHoverRadius===He.pointHoverRadius&&je.pointHitRadius===He.pointHitRadius&&je.pointHoverBackgroundColor===He.pointHoverBackgroundColor&&je.pointHoverBorderColor===He.pointHoverBorderColor&&je.pointHoverBorderWidth===He.pointHoverBorderWidth&&je.pointStyle===He.pointStyle&&je.hoverBackgroundColor===He.hoverBackgroundColor&&je.hoverBorderColor===He.hoverBorderColor&&je.hoverBorderWidth===He.hoverBorderWidth)}updateColors(){this.datasets.forEach((je,He)=>{this.colors&&this.colors[He]?Object.assign(je,this.colors[He]):Object.assign(je,function(Be,Pe,je){if("pie"===Be||"doughnut"===Be)return ee(se(je));if("polarArea"===Be)return function(Be){return{backgroundColor:Be.map(Pe=>L(Pe,.6)),borderColor:Be.map(Pe=>L(Pe,1)),hoverBackgroundColor:Be.map(Pe=>L(Pe,.8)),hoverBorderColor:Be.map(Pe=>L(Pe,1))}}(se(je));if("line"===Be||"radar"===Be)return function(Be){return{backgroundColor:L(Be,.4),borderColor:L(Be,1),pointBackgroundColor:L(Be,1),pointBorderColor:"#fff",pointHoverBackgroundColor:"#fff",pointHoverBorderColor:L(Be,.8)}}(H(Pe));if("bar"===Be||"horizontalBar"===Be)return function(Be){return{backgroundColor:L(Be,.6),borderColor:L(Be,1),hoverBackgroundColor:L(Be,.8),hoverBorderColor:L(Be,1)}}(H(Pe));if("bubble"===Be||"scatter"===Be)return ee(se(je));throw new Error(`getColors - Unsupported chart type ${Be}`)}(this.chartType,He,je.data.length),Object.assign({},je))})}ngOnChanges(je){let He=he.Default;const Vt=it=>{He=it>He?it:He};switch(je.hasOwnProperty("data")&&je.data.currentValue&&(this.propagateDataToDatasets(je.data.currentValue),Vt(he.Update)),je.hasOwnProperty("datasets")&&je.datasets.currentValue&&(this.propagateDatasetsToData(je.datasets.currentValue),Vt(he.Update)),je.hasOwnProperty("labels")&&(this.chart&&(this.chart.data.labels=je.labels.currentValue),Vt(he.Update)),je.hasOwnProperty("legend")&&(this.chart&&(this.chart.config.options.legend.display=je.legend.currentValue,this.chart.generateLegend()),Vt(he.Update)),je.hasOwnProperty("options")&&Vt(he.Refresh),He){case he.Update:this.update();break;case he.Refresh:case he.Default:this.refresh()}}ngOnDestroy(){this.chart&&(this.chart.destroy(),this.chart=void 0),this.subs.forEach(je=>je.unsubscribe())}update(je){if(this.chart)return this.chart.update(je)}hideDataset(je,He){this.chart.getDatasetMeta(je).hidden=He,this.chart.update()}isDatasetHidden(je){return this.chart.getDatasetMeta(je).hidden}toBase64Image(){return this.chart.toBase64Image()}getChartConfiguration(){const je=this.getDatasets(),He=Object.assign({},this.options);!1===this.legend&&(He.legend={display:!1}),He.hover=He.hover||{},He.hover.onHover||(He.hover.onHover=(it,tn)=>{tn&&!tn.length||this.chartHover.emit({event:it,active:tn})}),He.onClick||(He.onClick=(it,tn)=>{this.chartClick.emit({event:it,active:tn})});const Vt=this.smartMerge(He,this.themeService.getColorschemesOptions());return{type:this.chartType,data:{labels:this.labels||[],datasets:je},plugins:this.plugins,options:Vt}}getChartBuilder(je){const He=this.getChartConfiguration();return new S.Chart(je,He)}smartMerge(je,He,Vt=0){if(0===Vt&&(je=function(Be){return(0,p.Z)(Be,5)}(je)),Object.keys(He).forEach(tn=>{if(Array.isArray(He[tn])){const It=je[tn];It&&It.forEach(Zt=>{this.smartMerge(Zt,He[tn][0],Vt+1)})}else"object"==typeof He[tn]?(tn in je||(je[tn]={}),this.smartMerge(je[tn],He[tn],Vt+1)):je[tn]=He[tn]}),0===Vt)return je}isMultiLineLabel(je){return Array.isArray(je)}joinLabel(je){return je?this.isMultiLineLabel(je)?je.join(" "):je:null}propagateDatasetsToData(je){this.data=this.datasets.map(He=>He.data),this.chart&&(this.chart.data.datasets=je),this.updateColors()}propagateDataToDatasets(je){this.isMultiDataSet(je)?this.datasets&&je.length===this.datasets.length?this.datasets.forEach((He,Vt)=>{He.data=je[Vt]}):(this.datasets=je.map((He,Vt)=>({data:He,label:this.joinLabel(this.labels[Vt])||`Label ${Vt}`})),this.chart&&(this.chart.data.datasets=this.datasets)):this.datasets?(this.datasets[0]||(this.datasets[0]={}),this.datasets[0].data=je,this.datasets.splice(1)):(this.datasets=[{data:je}],this.chart&&(this.chart.data.datasets=this.datasets)),this.updateColors()}isMultiDataSet(je){return Array.isArray(je[0])}getDatasets(){if(!this.datasets&&!this.data)throw new Error(`ng-charts configuration error, data or datasets field are required to render chart ${this.chartType}`);return this.datasets?(this.propagateDatasetsToData(this.datasets),this.datasets):this.data?(this.propagateDataToDatasets(this.data),this.datasets):void 0}refresh(){this.chart&&(this.chart.destroy(),this.chart=void 0),this.ctx&&(this.chart=this.getChartBuilder(this.ctx))}}return Be.\u0275fac=function(je){return new(je||Be)(r.Y36(r.SBq),r.Y36(Ee))},Be.\u0275dir=r.lG2({type:Be,selectors:[["canvas","baseChart",""]],inputs:{options:"options",data:"data",datasets:"datasets",labels:"labels",chartType:"chartType",colors:"colors",legend:"legend",plugins:"plugins"},outputs:{chartClick:"chartClick",chartHover:"chartHover"},exportAs:["base-chart"],features:[r.TTD]}),Be})(),De=(()=>{class Be{}return Be.\u0275fac=function(je){return new(je||Be)},Be.\u0275mod=r.oAB({type:Be}),Be.\u0275inj=r.cJS({imports:[[]]}),Be})()},37496:(v,T,i)=>{"use strict";i.d(T,{b:()=>p,i:()=>u});var r=i(74788);let u=(()=>{class d{transform(_,y,S){return S?y.call(S,_):y(_)}}return d.\u0275fac=function(_){return new(_||d)},d.\u0275pipe=r.Yjl({name:"pipeFunction",type:d,pure:!0}),d})(),p=(()=>{class d{}return d.\u0275fac=function(_){return new(_||d)},d.\u0275mod=r.oAB({type:d}),d.\u0275inj=r.cJS({}),d})()},91376:(v,T,i)=>{"use strict";i.d(T,{Rh:()=>tn,_W:()=>He});var r=i(74788),u=i(56083),p=i(79765),d=i(91211),e=i(12057);const _=["toast-component",""];function y(bt,Gt){if(1&bt){const xt=r.EpF();r.TgZ(0,"button",5),r.NdJ("click",function(){return r.CHM(xt),r.oxw().remove()}),r.TgZ(1,"span",6),r._uU(2,"\xd7"),r.qZA(),r.qZA()}}function S(bt,Gt){if(1&bt&&(r.ynx(0),r._uU(1),r.BQk()),2&bt){const xt=r.oxw(2);r.xp6(1),r.hij("[",xt.duplicatesCount+1,"]")}}function A(bt,Gt){if(1&bt&&(r.TgZ(0,"div"),r._uU(1),r.YNc(2,S,2,1,"ng-container",4),r.qZA()),2&bt){const xt=r.oxw();r.Tol(xt.options.titleClass),r.uIk("aria-label",xt.title),r.xp6(1),r.hij(" ",xt.title," "),r.xp6(1),r.Q6J("ngIf",xt.duplicatesCount)}}function N(bt,Gt){if(1&bt&&r._UZ(0,"div",7),2&bt){const xt=r.oxw();r.Tol(xt.options.messageClass),r.Q6J("innerHTML",xt.message,r.oJD)}}function L(bt,Gt){if(1&bt&&(r.TgZ(0,"div",8),r._uU(1),r.qZA()),2&bt){const xt=r.oxw();r.Tol(xt.options.messageClass),r.uIk("aria-label",xt.message),r.xp6(1),r.hij(" ",xt.message," ")}}function Z(bt,Gt){if(1&bt&&(r.TgZ(0,"div"),r._UZ(1,"div",9),r.qZA()),2&bt){const xt=r.oxw();r.xp6(1),r.Udp("width",xt.width+"%")}}function J(bt,Gt){if(1&bt){const xt=r.EpF();r.TgZ(0,"button",5),r.NdJ("click",function(){return r.CHM(xt),r.oxw().remove()}),r.TgZ(1,"span",6),r._uU(2,"\xd7"),r.qZA(),r.qZA()}}function K(bt,Gt){if(1&bt&&(r.ynx(0),r._uU(1),r.BQk()),2&bt){const xt=r.oxw(2);r.xp6(1),r.hij("[",xt.duplicatesCount+1,"]")}}function ee(bt,Gt){if(1&bt&&(r.TgZ(0,"div"),r._uU(1),r.YNc(2,K,2,1,"ng-container",4),r.qZA()),2&bt){const xt=r.oxw();r.Tol(xt.options.titleClass),r.uIk("aria-label",xt.title),r.xp6(1),r.hij(" ",xt.title," "),r.xp6(1),r.Q6J("ngIf",xt.duplicatesCount)}}function ue(bt,Gt){if(1&bt&&r._UZ(0,"div",7),2&bt){const xt=r.oxw();r.Tol(xt.options.messageClass),r.Q6J("innerHTML",xt.message,r.oJD)}}function ae(bt,Gt){if(1&bt&&(r.TgZ(0,"div",8),r._uU(1),r.qZA()),2&bt){const xt=r.oxw();r.Tol(xt.options.messageClass),r.uIk("aria-label",xt.message),r.xp6(1),r.hij(" ",xt.message," ")}}function H(bt,Gt){if(1&bt&&(r.TgZ(0,"div"),r._UZ(1,"div",9),r.qZA()),2&bt){const xt=r.oxw();r.xp6(1),r.Udp("width",xt.width+"%")}}class ie{constructor(Gt,xt,Xt,Zn,Ur,di){this.toastId=Gt,this.config=xt,this.message=Xt,this.title=Zn,this.toastType=Ur,this.toastRef=di,this._onTap=new p.xQ,this._onAction=new p.xQ,this.toastRef.afterClosed().subscribe(()=>{this._onAction.complete(),this._onTap.complete()})}triggerTap(){this._onTap.next(),this.config.tapToDismiss&&this._onTap.complete()}onTap(){return this._onTap.asObservable()}triggerAction(Gt){this._onAction.next(Gt)}onAction(){return this._onAction.asObservable()}}const he={maxOpened:0,autoDismiss:!1,newestOnTop:!0,preventDuplicates:!1,countDuplicates:!1,resetTimeoutOnDuplicate:!1,includeTitleDuplicates:!1,iconClasses:{error:"toast-error",info:"toast-info",success:"toast-success",warning:"toast-warning"},closeButton:!1,disableTimeOut:!1,timeOut:5e3,extendedTimeOut:1e3,enableHtml:!1,progressBar:!1,toastClass:"ngx-toastr",positionClass:"toast-top-right",titleClass:"toast-title",messageClass:"toast-message",easing:"ease-in",easeTime:300,tapToDismiss:!0,onActivateTick:!1,progressAnimation:"decreasing",payload:null},ge=new r.OlP("ToastConfig");class De{constructor(Gt,xt){this.component=Gt,this.injector=xt}attach(Gt,xt){return this._attachedHost=Gt,Gt.attach(this,xt)}detach(){const Gt=this._attachedHost;if(Gt)return this._attachedHost=void 0,Gt.detach()}get isAttached(){return null!=this._attachedHost}setAttachedHost(Gt){this._attachedHost=Gt}}class lt extends class{attach(Gt,xt){return this._attachedPortal=Gt,this.attachComponentPortal(Gt,xt)}detach(){this._attachedPortal&&this._attachedPortal.setAttachedHost(),this._attachedPortal=void 0,this._disposeFn&&(this._disposeFn(),this._disposeFn=void 0)}setDisposeFn(Gt){this._disposeFn=Gt}}{constructor(Gt,xt,Xt){super(),this._hostDomElement=Gt,this._componentFactoryResolver=xt,this._appRef=Xt}attachComponentPortal(Gt,xt){const Xt=this._componentFactoryResolver.resolveComponentFactory(Gt.component);let Zn;return Zn=Xt.create(Gt.injector),this._appRef.attachView(Zn.hostView),this.setDisposeFn(()=>{this._appRef.detachView(Zn.hostView),Zn.destroy()}),xt?this._hostDomElement.insertBefore(this._getComponentRootNode(Zn),this._hostDomElement.firstChild):this._hostDomElement.appendChild(this._getComponentRootNode(Zn)),Zn}_getComponentRootNode(Gt){return Gt.hostView.rootNodes[0]}}let Ve=(()=>{class bt{constructor(xt){this._document=xt}ngOnDestroy(){this._containerElement&&this._containerElement.parentNode&&this._containerElement.parentNode.removeChild(this._containerElement)}getContainerElement(){return this._containerElement||this._createContainer(),this._containerElement}_createContainer(){const xt=this._document.createElement("div");xt.classList.add("overlay-container"),this._document.body.appendChild(xt),this._containerElement=xt}}return bt.\u0275fac=function(xt){return new(xt||bt)(r.LFG(e.K0))},bt.\u0275prov=r.Yz7({factory:function(){return new bt(r.LFG(e.K0))},token:bt,providedIn:"root"}),bt})();class ze{constructor(Gt){this._portalHost=Gt}attach(Gt,xt=!0){return this._portalHost.attach(Gt,xt)}detach(){return this._portalHost.detach()}}let Be=(()=>{class bt{constructor(xt,Xt,Zn,Ur){this._overlayContainer=xt,this._componentFactoryResolver=Xt,this._appRef=Zn,this._document=Ur,this._paneElements=new Map}create(xt,Xt){return this._createOverlayRef(this.getPaneElement(xt,Xt))}getPaneElement(xt="",Xt){return this._paneElements.get(Xt)||this._paneElements.set(Xt,{}),this._paneElements.get(Xt)[xt]||(this._paneElements.get(Xt)[xt]=this._createPaneElement(xt,Xt)),this._paneElements.get(Xt)[xt]}_createPaneElement(xt,Xt){const Zn=this._document.createElement("div");return Zn.id="toast-container",Zn.classList.add(xt),Zn.classList.add("toast-container"),Xt?Xt.getContainerElement().appendChild(Zn):this._overlayContainer.getContainerElement().appendChild(Zn),Zn}_createPortalHost(xt){return new lt(xt,this._componentFactoryResolver,this._appRef)}_createOverlayRef(xt){return new ze(this._createPortalHost(xt))}}return bt.\u0275fac=function(xt){return new(xt||bt)(r.LFG(Ve),r.LFG(r._Vd),r.LFG(r.z2F),r.LFG(e.K0))},bt.\u0275prov=r.Yz7({factory:function(){return new bt(r.LFG(Ve),r.LFG(r._Vd),r.LFG(r.z2F),r.LFG(e.K0))},token:bt,providedIn:"root"}),bt})();class Pe{constructor(Gt){this._overlayRef=Gt,this.duplicatesCount=0,this._afterClosed=new p.xQ,this._activate=new p.xQ,this._manualClose=new p.xQ,this._resetTimeout=new p.xQ,this._countDuplicate=new p.xQ}manualClose(){this._manualClose.next(),this._manualClose.complete()}manualClosed(){return this._manualClose.asObservable()}timeoutReset(){return this._resetTimeout.asObservable()}countDuplicate(){return this._countDuplicate.asObservable()}close(){this._overlayRef.detach(),this._afterClosed.next(),this._manualClose.next(),this._afterClosed.complete(),this._manualClose.complete(),this._activate.complete(),this._resetTimeout.complete(),this._countDuplicate.complete()}afterClosed(){return this._afterClosed.asObservable()}isInactive(){return this._activate.isStopped}activate(){this._activate.next(),this._activate.complete()}afterActivate(){return this._activate.asObservable()}onDuplicate(Gt,xt){Gt&&this._resetTimeout.next(),xt&&this._countDuplicate.next(++this.duplicatesCount)}}class je{constructor(Gt,xt){this._toastPackage=Gt,this._parentInjector=xt}get(Gt,xt,Xt){return Gt===ie?this._toastPackage:this._parentInjector.get(Gt,xt,Xt)}}let He=(()=>{class bt{constructor(xt,Xt,Zn,Ur,di){this.overlay=Xt,this._injector=Zn,this.sanitizer=Ur,this.ngZone=di,this.currentlyActive=0,this.toasts=[],this.index=0,this.toastrConfig=Object.assign(Object.assign({},xt.default),xt.config),xt.config.iconClasses&&(this.toastrConfig.iconClasses=Object.assign(Object.assign({},xt.default.iconClasses),xt.config.iconClasses))}show(xt,Xt,Zn={},Ur=""){return this._preBuildNotification(Ur,xt,Xt,this.applyConfig(Zn))}success(xt,Xt,Zn={}){return this._preBuildNotification(this.toastrConfig.iconClasses.success||"",xt,Xt,this.applyConfig(Zn))}error(xt,Xt,Zn={}){return this._preBuildNotification(this.toastrConfig.iconClasses.error||"",xt,Xt,this.applyConfig(Zn))}info(xt,Xt,Zn={}){return this._preBuildNotification(this.toastrConfig.iconClasses.info||"",xt,Xt,this.applyConfig(Zn))}warning(xt,Xt,Zn={}){return this._preBuildNotification(this.toastrConfig.iconClasses.warning||"",xt,Xt,this.applyConfig(Zn))}clear(xt){for(const Xt of this.toasts)if(void 0!==xt){if(Xt.toastId===xt)return void Xt.toastRef.manualClose()}else Xt.toastRef.manualClose()}remove(xt){const Xt=this._findToast(xt);if(!Xt||(Xt.activeToast.toastRef.close(),this.toasts.splice(Xt.index,1),this.currentlyActive=this.currentlyActive-1,!this.toastrConfig.maxOpened||!this.toasts.length))return!1;if(this.currentlyActive<this.toastrConfig.maxOpened&&this.toasts[this.currentlyActive]){const Zn=this.toasts[this.currentlyActive].toastRef;Zn.isInactive()||(this.currentlyActive=this.currentlyActive+1,Zn.activate())}return!0}findDuplicate(xt="",Xt="",Zn,Ur){const{includeTitleDuplicates:di}=this.toastrConfig;for(const Lr of this.toasts){const Mr=di&&Lr.title===xt;if((!di||Mr)&&Lr.message===Xt)return Lr.toastRef.onDuplicate(Zn,Ur),Lr}return null}applyConfig(xt={}){return Object.assign(Object.assign({},this.toastrConfig),xt)}_findToast(xt){for(let Xt=0;Xt<this.toasts.length;Xt++)if(this.toasts[Xt].toastId===xt)return{index:Xt,activeToast:this.toasts[Xt]};return null}_preBuildNotification(xt,Xt,Zn,Ur){return Ur.onActivateTick?this.ngZone.run(()=>this._buildNotification(xt,Xt,Zn,Ur)):this._buildNotification(xt,Xt,Zn,Ur)}_buildNotification(xt,Xt,Zn,Ur){if(!Ur.toastComponent)throw new Error("toastComponent required");const di=this.findDuplicate(Zn,Xt,this.toastrConfig.resetTimeoutOnDuplicate&&Ur.timeOut>0,this.toastrConfig.countDuplicates);if((this.toastrConfig.includeTitleDuplicates&&Zn||Xt)&&this.toastrConfig.preventDuplicates&&null!==di)return di;this.previousToastMessage=Xt;let Lr=!1;this.toastrConfig.maxOpened&&this.currentlyActive>=this.toastrConfig.maxOpened&&(Lr=!0,this.toastrConfig.autoDismiss&&this.clear(this.toasts[0].toastId));const Mr=this.overlay.create(Ur.positionClass,this.overlayContainer);this.index=this.index+1;let Kr=Xt;Xt&&Ur.enableHtml&&(Kr=this.sanitizer.sanitize(r.q3G.HTML,Xt));const ei=new Pe(Mr),Nn=new ie(this.index,Ur,Kr,Zn,xt,ei),$n=new je(Nn,this._injector),Br=new De(Ur.toastComponent,$n),Yr=Mr.attach(Br,this.toastrConfig.newestOnTop);ei.componentInstance=Yr.instance;const fi={toastId:this.index,title:Zn||"",message:Xt||"",toastRef:ei,onShown:ei.afterActivate(),onHidden:ei.afterClosed(),onTap:Nn.onTap(),onAction:Nn.onAction(),portal:Yr};return Lr||(this.currentlyActive=this.currentlyActive+1,setTimeout(()=>{fi.toastRef.activate()})),this.toasts.push(fi),fi}}return bt.\u0275fac=function(xt){return new(xt||bt)(r.LFG(ge),r.LFG(Be),r.LFG(r.zs3),r.LFG(d.H7),r.LFG(r.R0b))},bt.\u0275prov=r.Yz7({factory:function(){return new bt(r.LFG(ge),r.LFG(Be),r.LFG(r.gxx),r.LFG(d.H7),r.LFG(r.R0b))},token:bt,providedIn:"root"}),bt})(),Vt=(()=>{class bt{constructor(xt,Xt,Zn){this.toastrService=xt,this.toastPackage=Xt,this.ngZone=Zn,this.width=-1,this.toastClasses="",this.state={value:"inactive",params:{easeTime:this.toastPackage.config.easeTime,easing:"ease-in"}},this.message=Xt.message,this.title=Xt.title,this.options=Xt.config,this.originalTimeout=Xt.config.timeOut,this.toastClasses=`${Xt.toastType} ${Xt.config.toastClass}`,this.sub=Xt.toastRef.afterActivate().subscribe(()=>{this.activateToast()}),this.sub1=Xt.toastRef.manualClosed().subscribe(()=>{this.remove()}),this.sub2=Xt.toastRef.timeoutReset().subscribe(()=>{this.resetTimeout()}),this.sub3=Xt.toastRef.countDuplicate().subscribe(Ur=>{this.duplicatesCount=Ur})}get displayStyle(){if("inactive"===this.state.value)return"none"}ngOnDestroy(){this.sub.unsubscribe(),this.sub1.unsubscribe(),this.sub2.unsubscribe(),this.sub3.unsubscribe(),clearInterval(this.intervalId),clearTimeout(this.timeout)}activateToast(){this.state=Object.assign(Object.assign({},this.state),{value:"active"}),!0!==this.options.disableTimeOut&&"timeOut"!==this.options.disableTimeOut&&this.options.timeOut&&(this.outsideTimeout(()=>this.remove(),this.options.timeOut),this.hideTime=(new Date).getTime()+this.options.timeOut,this.options.progressBar&&this.outsideInterval(()=>this.updateProgress(),10))}updateProgress(){if(0===this.width||100===this.width||!this.options.timeOut)return;const xt=(new Date).getTime();this.width=(this.hideTime-xt)/this.options.timeOut*100,"increasing"===this.options.progressAnimation&&(this.width=100-this.width),this.width<=0&&(this.width=0),this.width>=100&&(this.width=100)}resetTimeout(){clearTimeout(this.timeout),clearInterval(this.intervalId),this.state=Object.assign(Object.assign({},this.state),{value:"active"}),this.outsideTimeout(()=>this.remove(),this.originalTimeout),this.options.timeOut=this.originalTimeout,this.hideTime=(new Date).getTime()+(this.options.timeOut||0),this.width=-1,this.options.progressBar&&this.outsideInterval(()=>this.updateProgress(),10)}remove(){"removed"!==this.state.value&&(clearTimeout(this.timeout),this.state=Object.assign(Object.assign({},this.state),{value:"removed"}),this.outsideTimeout(()=>this.toastrService.remove(this.toastPackage.toastId),+this.toastPackage.config.easeTime))}tapToast(){"removed"!==this.state.value&&(this.toastPackage.triggerTap(),this.options.tapToDismiss&&this.remove())}stickAround(){"removed"!==this.state.value&&(clearTimeout(this.timeout),this.options.timeOut=0,this.hideTime=0,clearInterval(this.intervalId),this.width=0)}delayedHideToast(){!0===this.options.disableTimeOut||"extendedTimeOut"===this.options.disableTimeOut||0===this.options.extendedTimeOut||"removed"===this.state.value||(this.outsideTimeout(()=>this.remove(),this.options.extendedTimeOut),this.options.timeOut=this.options.extendedTimeOut,this.hideTime=(new Date).getTime()+(this.options.timeOut||0),this.width=-1,this.options.progressBar&&this.outsideInterval(()=>this.updateProgress(),10))}outsideTimeout(xt,Xt){this.ngZone?this.ngZone.runOutsideAngular(()=>this.timeout=setTimeout(()=>this.runInsideAngular(xt),Xt)):this.timeout=setTimeout(()=>xt(),Xt)}outsideInterval(xt,Xt){this.ngZone?this.ngZone.runOutsideAngular(()=>this.intervalId=setInterval(()=>this.runInsideAngular(xt),Xt)):this.intervalId=setInterval(()=>xt(),Xt)}runInsideAngular(xt){this.ngZone?this.ngZone.run(()=>xt()):xt()}}return bt.\u0275fac=function(xt){return new(xt||bt)(r.Y36(He),r.Y36(ie),r.Y36(r.R0b))},bt.\u0275cmp=r.Xpm({type:bt,selectors:[["","toast-component",""]],hostVars:5,hostBindings:function(xt,Xt){1&xt&&r.NdJ("click",function(){return Xt.tapToast()})("mouseenter",function(){return Xt.stickAround()})("mouseleave",function(){return Xt.delayedHideToast()}),2&xt&&(r.d8E("@flyInOut",Xt.state),r.Tol(Xt.toastClasses),r.Udp("display",Xt.displayStyle))},attrs:_,decls:5,vars:5,consts:[["type","button","class","toast-close-button","aria-label","Close",3,"click",4,"ngIf"],[3,"class",4,"ngIf"],["role","alertdialog","aria-live","polite",3,"class","innerHTML",4,"ngIf"],["role","alertdialog","aria-live","polite",3,"class",4,"ngIf"],[4,"ngIf"],["type","button","aria-label","Close",1,"toast-close-button",3,"click"],["aria-hidden","true"],["role","alertdialog","aria-live","polite",3,"innerHTML"],["role","alertdialog","aria-live","polite"],[1,"toast-progress"]],template:function(xt,Xt){1&xt&&(r.YNc(0,y,3,0,"button",0),r.YNc(1,A,3,5,"div",1),r.YNc(2,N,1,3,"div",2),r.YNc(3,L,2,4,"div",3),r.YNc(4,Z,2,2,"div",4)),2&xt&&(r.Q6J("ngIf",Xt.options.closeButton),r.xp6(1),r.Q6J("ngIf",Xt.title),r.xp6(1),r.Q6J("ngIf",Xt.message&&Xt.options.enableHtml),r.xp6(1),r.Q6J("ngIf",Xt.message&&!Xt.options.enableHtml),r.xp6(1),r.Q6J("ngIf",Xt.options.progressBar))},directives:[e.O5],encapsulation:2,data:{animation:[(0,u.X$)("flyInOut",[(0,u.SB)("inactive",(0,u.oB)({opacity:0})),(0,u.SB)("active",(0,u.oB)({opacity:1})),(0,u.SB)("removed",(0,u.oB)({opacity:0})),(0,u.eR)("inactive => active",(0,u.jt)("{{ easeTime }}ms {{ easing }}")),(0,u.eR)("active => removed",(0,u.jt)("{{ easeTime }}ms {{ easing }}"))])]}}),bt})();const it=Object.assign(Object.assign({},he),{toastComponent:Vt});let tn=(()=>{class bt{static forRoot(xt={}){return{ngModule:bt,providers:[{provide:ge,useValue:{default:it,config:xt}}]}}}return bt.\u0275fac=function(xt){return new(xt||bt)},bt.\u0275mod=r.oAB({type:bt}),bt.\u0275inj=r.cJS({imports:[[e.ez]]}),bt})(),Zt=(()=>{class bt{constructor(xt,Xt,Zn){this.toastrService=xt,this.toastPackage=Xt,this.appRef=Zn,this.width=-1,this.toastClasses="",this.state="inactive",this.message=Xt.message,this.title=Xt.title,this.options=Xt.config,this.originalTimeout=Xt.config.timeOut,this.toastClasses=`${Xt.toastType} ${Xt.config.toastClass}`,this.sub=Xt.toastRef.afterActivate().subscribe(()=>{this.activateToast()}),this.sub1=Xt.toastRef.manualClosed().subscribe(()=>{this.remove()}),this.sub2=Xt.toastRef.timeoutReset().subscribe(()=>{this.resetTimeout()}),this.sub3=Xt.toastRef.countDuplicate().subscribe(Ur=>{this.duplicatesCount=Ur})}get displayStyle(){if("inactive"===this.state)return"none"}ngOnDestroy(){this.sub.unsubscribe(),this.sub1.unsubscribe(),this.sub2.unsubscribe(),this.sub3.unsubscribe(),clearInterval(this.intervalId),clearTimeout(this.timeout)}activateToast(){this.state="active",!(!0===this.options.disableTimeOut||"timeOut"===this.options.disableTimeOut)&&this.options.timeOut&&(this.timeout=setTimeout(()=>{this.remove()},this.options.timeOut),this.hideTime=(new Date).getTime()+this.options.timeOut,this.options.progressBar&&(this.intervalId=setInterval(()=>this.updateProgress(),10))),this.options.onActivateTick&&this.appRef.tick()}updateProgress(){if(0===this.width||100===this.width||!this.options.timeOut)return;const xt=(new Date).getTime();this.width=(this.hideTime-xt)/this.options.timeOut*100,"increasing"===this.options.progressAnimation&&(this.width=100-this.width),this.width<=0&&(this.width=0),this.width>=100&&(this.width=100)}resetTimeout(){clearTimeout(this.timeout),clearInterval(this.intervalId),this.state="active",this.options.timeOut=this.originalTimeout,this.timeout=setTimeout(()=>this.remove(),this.originalTimeout),this.hideTime=(new Date).getTime()+(this.originalTimeout||0),this.width=-1,this.options.progressBar&&(this.intervalId=setInterval(()=>this.updateProgress(),10))}remove(){"removed"!==this.state&&(clearTimeout(this.timeout),this.state="removed",this.timeout=setTimeout(()=>this.toastrService.remove(this.toastPackage.toastId)))}tapToast(){"removed"!==this.state&&(this.toastPackage.triggerTap(),this.options.tapToDismiss&&this.remove())}stickAround(){"removed"!==this.state&&(clearTimeout(this.timeout),this.options.timeOut=0,this.hideTime=0,clearInterval(this.intervalId),this.width=0)}delayedHideToast(){!0===this.options.disableTimeOut||"extendedTimeOut"===this.options.disableTimeOut||0===this.options.extendedTimeOut||"removed"===this.state||(this.timeout=setTimeout(()=>this.remove(),this.options.extendedTimeOut),this.options.timeOut=this.options.extendedTimeOut,this.hideTime=(new Date).getTime()+(this.options.timeOut||0),this.width=-1,this.options.progressBar&&(this.intervalId=setInterval(()=>this.updateProgress(),10)))}}return bt.\u0275fac=function(xt){return new(xt||bt)(r.Y36(He),r.Y36(ie),r.Y36(r.z2F))},bt.\u0275cmp=r.Xpm({type:bt,selectors:[["","toast-component",""]],hostVars:4,hostBindings:function(xt,Xt){1&xt&&r.NdJ("click",function(){return Xt.tapToast()})("mouseenter",function(){return Xt.stickAround()})("mouseleave",function(){return Xt.delayedHideToast()}),2&xt&&(r.Tol(Xt.toastClasses),r.Udp("display",Xt.displayStyle))},attrs:_,decls:5,vars:5,consts:[["type","button","class","toast-close-button","aria-label","Close",3,"click",4,"ngIf"],[3,"class",4,"ngIf"],["role","alert","aria-live","polite",3,"class","innerHTML",4,"ngIf"],["role","alert","aria-live","polite",3,"class",4,"ngIf"],[4,"ngIf"],["type","button","aria-label","Close",1,"toast-close-button",3,"click"],["aria-hidden","true"],["role","alert","aria-live","polite",3,"innerHTML"],["role","alert","aria-live","polite"],[1,"toast-progress"]],template:function(xt,Xt){1&xt&&(r.YNc(0,J,3,0,"button",0),r.YNc(1,ee,3,5,"div",1),r.YNc(2,ue,1,3,"div",2),r.YNc(3,ae,2,4,"div",3),r.YNc(4,H,2,2,"div",4)),2&xt&&(r.Q6J("ngIf",Xt.options.closeButton),r.xp6(1),r.Q6J("ngIf",Xt.title),r.xp6(1),r.Q6J("ngIf",Xt.message&&Xt.options.enableHtml),r.xp6(1),r.Q6J("ngIf",Xt.message&&!Xt.options.enableHtml),r.xp6(1),r.Q6J("ngIf",Xt.options.progressBar))},directives:[e.O5],encapsulation:2}),bt})();Object.assign(Object.assign({},he),{toastComponent:Zt})},18228:v=>{"use strict";var T=Object.getOwnPropertySymbols,i=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;function u(d){if(null==d)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(d)}v.exports=function(){try{if(!Object.assign)return!1;var d=new String("abc");if(d[5]="de","5"===Object.getOwnPropertyNames(d)[0])return!1;for(var e={},_=0;_<10;_++)e["_"+String.fromCharCode(_)]=_;if("0123456789"!==Object.getOwnPropertyNames(e).map(function(A){return e[A]}).join(""))return!1;var S={};return"abcdefghijklmnopqrst".split("").forEach(function(A){S[A]=A}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},S)).join("")}catch(A){return!1}}()?Object.assign:function(d,e){for(var _,S,y=u(d),A=1;A<arguments.length;A++){for(var N in _=Object(arguments[A]))i.call(_,N)&&(y[N]=_[N]);if(T){S=T(_);for(var L=0;L<S.length;L++)r.call(_,S[L])&&(y[S[L]]=_[S[L]])}}return y}},81380:(v,T,i)=>{var r="function"==typeof Map&&Map.prototype,u=Object.getOwnPropertyDescriptor&&r?Object.getOwnPropertyDescriptor(Map.prototype,"size"):null,p=r&&u&&"function"==typeof u.get?u.get:null,d=r&&Map.prototype.forEach,e="function"==typeof Set&&Set.prototype,_=Object.getOwnPropertyDescriptor&&e?Object.getOwnPropertyDescriptor(Set.prototype,"size"):null,y=e&&_&&"function"==typeof _.get?_.get:null,S=e&&Set.prototype.forEach,N="function"==typeof WeakMap&&WeakMap.prototype?WeakMap.prototype.has:null,Z="function"==typeof WeakSet&&WeakSet.prototype?WeakSet.prototype.has:null,K="function"==typeof WeakRef&&WeakRef.prototype?WeakRef.prototype.deref:null,ee=Boolean.prototype.valueOf,ue=Object.prototype.toString,ae=Function.prototype.toString,H=String.prototype.match,se=String.prototype.slice,Ee=String.prototype.replace,ie=String.prototype.toUpperCase,he=String.prototype.toLowerCase,ge=RegExp.prototype.test,De=Array.prototype.concat,ce=Array.prototype.join,lt=Array.prototype.slice,Ve=Math.floor,ze="function"==typeof BigInt?BigInt.prototype.valueOf:null,Be=Object.getOwnPropertySymbols,Pe="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?Symbol.prototype.toString:null,je="function"==typeof Symbol&&"object"==typeof Symbol.iterator,He="function"==typeof Symbol&&Symbol.toStringTag&&(Symbol,1)?Symbol.toStringTag:null,Vt=Object.prototype.propertyIsEnumerable,it=("function"==typeof Reflect?Reflect.getPrototypeOf:Object.getPrototypeOf)||([].__proto__===Array.prototype?function(gn){return gn.__proto__}:null);function tn(gn,yn){if(gn===1/0||gn===-1/0||gn!=gn||gn&&gn>-1e3&&gn<1e3||ge.call(/e/,yn))return yn;var gr=/[0-9](?=(?:[0-9]{3})+(?![0-9]))/g;if("number"==typeof gn){var Jt=gn<0?-Ve(-gn):Ve(gn);if(Jt!==gn){var Vn=String(Jt),mr=se.call(yn,Vn.length+1);return Ee.call(Vn,gr,"$&_")+"."+Ee.call(Ee.call(mr,/([0-9]{3})/g,"$&_"),/_$/,"")}}return Ee.call(yn,gr,"$&_")}var It=i(24654),Zt=It.custom,Ut=Mr(Zt)?Zt:null;function Bt(gn,yn,gr){var Jt="double"===(gr.quoteStyle||yn)?'"':"'";return Jt+gn+Jt}function bt(gn){return Ee.call(String(gn),/"/g,"&quot;")}function Gt(gn){return!("[object Array]"!==$n(gn)||He&&"object"==typeof gn&&He in gn)}function Xt(gn){return!("[object RegExp]"!==$n(gn)||He&&"object"==typeof gn&&He in gn)}function Mr(gn){if(je)return gn&&"object"==typeof gn&&gn instanceof Symbol;if("symbol"==typeof gn)return!0;if(!gn||"object"!=typeof gn||!Pe)return!1;try{return Pe.call(gn),!0}catch(yn){}return!1}v.exports=function gn(yn,gr,Jt,Vn){var mr=gr||{};if(Nn(mr,"quoteStyle")&&"single"!==mr.quoteStyle&&"double"!==mr.quoteStyle)throw new TypeError('option "quoteStyle" must be "single" or "double"');if(Nn(mr,"maxStringLength")&&("number"==typeof mr.maxStringLength?mr.maxStringLength<0&&mr.maxStringLength!==1/0:null!==mr.maxStringLength))throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');var Dn=!Nn(mr,"customInspect")||mr.customInspect;if("boolean"!=typeof Dn&&"symbol"!==Dn)throw new TypeError("option \"customInspect\", if provided, must be `true`, `false`, or `'symbol'`");if(Nn(mr,"indent")&&null!==mr.indent&&"\t"!==mr.indent&&!(parseInt(mr.indent,10)===mr.indent&&mr.indent>0))throw new TypeError('option "indent" must be "\\t", an integer > 0, or `null`');if(Nn(mr,"numericSeparator")&&"boolean"!=typeof mr.numericSeparator)throw new TypeError('option "numericSeparator", if provided, must be `true` or `false`');var Pr=mr.numericSeparator;if(void 0===yn)return"undefined";if(null===yn)return"null";if("boolean"==typeof yn)return yn?"true":"false";if("string"==typeof yn)return zn(yn,mr);if("number"==typeof yn){if(0===yn)return 1/0/yn>0?"0":"-0";var Yt=String(yn);return Pr?tn(yn,Yt):Yt}if("bigint"==typeof yn){var _n=String(yn)+"n";return Pr?tn(yn,_n):_n}var Ge=void 0===mr.depth?5:mr.depth;if(void 0===Jt&&(Jt=0),Jt>=Ge&&Ge>0&&"object"==typeof yn)return Gt(yn)?"[Array]":"[Object]";var kr=function(gn,yn){var gr;if("\t"===gn.indent)gr="\t";else{if(!("number"==typeof gn.indent&&gn.indent>0))return null;gr=ce.call(Array(gn.indent+1)," ")}return{base:gr,prev:ce.call(Array(yn+1),gr)}}(mr,Jt);if(void 0===Vn)Vn=[];else if(Yr(Vn,yn)>=0)return"[Circular]";function mi(Bn,lr,vr){if(lr&&(Vn=lt.call(Vn)).push(lr),vr){var er={depth:mr.depth};return Nn(mr,"quoteStyle")&&(er.quoteStyle=mr.quoteStyle),gn(Bn,er,Jt+1,Vn)}return gn(Bn,mr,Jt+1,Vn)}if("function"==typeof yn&&!Xt(yn)){var An=function(gn){if(gn.name)return gn.name;var yn=H.call(ae.call(gn),/^function\s*([\w$]+)/);return yn?yn[1]:null}(yn),Er=Dr(yn,mi);return"[Function"+(An?": "+An:" (anonymous)")+"]"+(Er.length>0?" { "+ce.call(Er,", ")+" }":"")}if(Mr(yn)){var Wr=je?Ee.call(String(yn),/^(Symbol\(.*\))_[^)]*$/,"$1"):Pe.call(yn);return"object"!=typeof yn||je?Wr:Fr(Wr)}if(function(gn){return!(!gn||"object"!=typeof gn)&&("undefined"!=typeof HTMLElement&&gn instanceof HTMLElement||"string"==typeof gn.nodeName&&"function"==typeof gn.getAttribute)}(yn)){for(var dr="<"+he.call(String(yn.nodeName)),Fn=yn.attributes||[],ar=0;ar<Fn.length;ar++)dr+=" "+Fn[ar].name+"="+Bt(bt(Fn[ar].value),"double",mr);return dr+=">",yn.childNodes&&yn.childNodes.length&&(dr+="..."),dr+"</"+he.call(String(yn.nodeName))+">"}if(Gt(yn)){if(0===yn.length)return"[]";var Wi=Dr(yn,mi);return kr&&!function(gn){for(var yn=0;yn<gn.length;yn++)if(Yr(gn[yn],"\n")>=0)return!1;return!0}(Wi)?"["+br(Wi,kr)+"]":"[ "+ce.call(Wi,", ")+" ]"}if(function(gn){return!("[object Error]"!==$n(gn)||He&&"object"==typeof gn&&He in gn)}(yn)){var lo=Dr(yn,mi);return"cause"in Error.prototype||!("cause"in yn)||Vt.call(yn,"cause")?0===lo.length?"["+String(yn)+"]":"{ ["+String(yn)+"] "+ce.call(lo,", ")+" }":"{ ["+String(yn)+"] "+ce.call(De.call("[cause]: "+mi(yn.cause),lo),", ")+" }"}if("object"==typeof yn&&Dn){if(Ut&&"function"==typeof yn[Ut]&&It)return It(yn,{depth:Ge-Jt});if("symbol"!==Dn&&"function"==typeof yn.inspect)return yn.inspect()}if(function(gn){if(!p||!gn||"object"!=typeof gn)return!1;try{p.call(gn);try{y.call(gn)}catch(yn){return!0}return gn instanceof Map}catch(yn){}return!1}(yn)){var vo=[];return d.call(yn,function(Bn,lr){vo.push(mi(lr,yn,!0)+" => "+mi(Bn,yn))}),Jr("Map",p.call(yn),vo,kr)}if(function(gn){if(!y||!gn||"object"!=typeof gn)return!1;try{y.call(gn);try{p.call(gn)}catch(yn){return!0}return gn instanceof Set}catch(yn){}return!1}(yn)){var Co=[];return S.call(yn,function(Bn){Co.push(mi(Bn,yn))}),Jr("Set",y.call(yn),Co,kr)}if(function(gn){if(!N||!gn||"object"!=typeof gn)return!1;try{N.call(gn,N);try{Z.call(gn,Z)}catch(yn){return!0}return gn instanceof WeakMap}catch(yn){}return!1}(yn))return Gn("WeakMap");if(function(gn){if(!Z||!gn||"object"!=typeof gn)return!1;try{Z.call(gn,Z);try{N.call(gn,N)}catch(yn){return!0}return gn instanceof WeakSet}catch(yn){}return!1}(yn))return Gn("WeakSet");if(function(gn){if(!K||!gn||"object"!=typeof gn)return!1;try{return K.call(gn),!0}catch(yn){}return!1}(yn))return Gn("WeakRef");if(function(gn){return!("[object Number]"!==$n(gn)||He&&"object"==typeof gn&&He in gn)}(yn))return Fr(mi(Number(yn)));if(function(gn){if(!gn||"object"!=typeof gn||!ze)return!1;try{return ze.call(gn),!0}catch(yn){}return!1}(yn))return Fr(mi(ze.call(yn)));if(function(gn){return!("[object Boolean]"!==$n(gn)||He&&"object"==typeof gn&&He in gn)}(yn))return Fr(ee.call(yn));if(function(gn){return!("[object String]"!==$n(gn)||He&&"object"==typeof gn&&He in gn)}(yn))return Fr(mi(String(yn)));if(!function(gn){return!("[object Date]"!==$n(gn)||He&&"object"==typeof gn&&He in gn)}(yn)&&!Xt(yn)){var Gi=Dr(yn,mi),os=it?it(yn)===Object.prototype:yn instanceof Object||yn.constructor===Object,jo=yn instanceof Object?"":"null prototype",To=!os&&He&&Object(yn)===yn&&He in yn?se.call($n(yn),8,-1):jo?"Object":"",li=(os||"function"!=typeof yn.constructor?"":yn.constructor.name?yn.constructor.name+" ":"")+(To||jo?"["+ce.call(De.call([],To||[],jo||[]),": ")+"] ":"");return 0===Gi.length?li+"{}":kr?li+"{"+br(Gi,kr)+"}":li+"{ "+ce.call(Gi,", ")+" }"}return String(yn)};var ei=Object.prototype.hasOwnProperty||function(gn){return gn in this};function Nn(gn,yn){return ei.call(gn,yn)}function $n(gn){return ue.call(gn)}function Yr(gn,yn){if(gn.indexOf)return gn.indexOf(yn);for(var gr=0,Jt=gn.length;gr<Jt;gr++)if(gn[gr]===yn)return gr;return-1}function zn(gn,yn){if(gn.length>yn.maxStringLength){var gr=gn.length-yn.maxStringLength,Jt="... "+gr+" more character"+(gr>1?"s":"");return zn(se.call(gn,0,yn.maxStringLength),yn)+Jt}return Bt(Ee.call(Ee.call(gn,/(['\\])/g,"\\$1"),/[\x00-\x1f]/g,rr),"single",yn)}function rr(gn){var yn=gn.charCodeAt(0),gr={8:"b",9:"t",10:"n",12:"f",13:"r"}[yn];return gr?"\\"+gr:"\\x"+(yn<16?"0":"")+ie.call(yn.toString(16))}function Fr(gn){return"Object("+gn+")"}function Gn(gn){return gn+" { ? }"}function Jr(gn,yn,gr,Jt){return gn+" ("+yn+") {"+(Jt?br(gr,Jt):ce.call(gr,", "))+"}"}function br(gn,yn){if(0===gn.length)return"";var gr="\n"+yn.prev+yn.base;return gr+ce.call(gn,","+gr)+"\n"+yn.prev}function Dr(gn,yn){var gr=Gt(gn),Jt=[];if(gr){Jt.length=gn.length;for(var Vn=0;Vn<gn.length;Vn++)Jt[Vn]=Nn(gn,Vn)?yn(gn[Vn],gn):""}var Dn,mr="function"==typeof Be?Be(gn):[];if(je){Dn={};for(var Pr=0;Pr<mr.length;Pr++)Dn["$"+mr[Pr]]=mr[Pr]}for(var Yt in gn)!Nn(gn,Yt)||gr&&String(Number(Yt))===Yt&&Yt<gn.length||je&&Dn["$"+Yt]instanceof Symbol||(ge.call(/[^\w$]/,Yt)?Jt.push(yn(Yt,gn)+": "+yn(gn[Yt],gn)):Jt.push(Yt+": "+yn(gn[Yt],gn)));if("function"==typeof Be)for(var _n=0;_n<mr.length;_n++)Vt.call(gn,mr[_n])&&Jt.push("["+yn(mr[_n])+"]: "+yn(gn[mr[_n]],gn));return Jt}},25119:(v,T,i)=>{"use strict";var r=i(88411);function u(){}function p(){}p.resetWarningCache=u,v.exports=function(){function d(y,S,A,N,L,Z){if(Z!==r){var J=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw J.name="Invariant Violation",J}}function e(){return d}d.isRequired=d;var _={array:d,bigint:d,bool:d,func:d,number:d,object:d,string:d,symbol:d,any:d,arrayOf:e,element:d,elementType:d,instanceOf:e,node:d,objectOf:e,oneOf:e,oneOfType:e,shape:e,exact:e,checkPropTypes:p,resetWarningCache:u};return _.PropTypes=_,_}},76874:(v,T,i)=>{v.exports=i(25119)()},88411:v=>{"use strict";v.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},87504:function(v,T,i){var r;v=i.nmd(v),function(u){"object"==typeof global&&global;var _,y=2147483647,S=36,ue=/^xn--/,ae=/[^\x20-\x7E]/,H=/[\x2E\u3002\uFF0E\uFF61]/g,se={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},ie=Math.floor,he=String.fromCharCode;function De(It){throw RangeError(se[It])}function ce(It,Zt){for(var Ut=It.length,Bt=[];Ut--;)Bt[Ut]=Zt(It[Ut]);return Bt}function lt(It,Zt){var Ut=It.split("@"),Bt="";return Ut.length>1&&(Bt=Ut[0]+"@",It=Ut[1]),Bt+ce((It=It.replace(H,".")).split("."),Zt).join(".")}function Ve(It){for(var bt,Gt,Zt=[],Ut=0,Bt=It.length;Ut<Bt;)(bt=It.charCodeAt(Ut++))>=55296&&bt<=56319&&Ut<Bt?56320==(64512&(Gt=It.charCodeAt(Ut++)))?Zt.push(((1023&bt)<<10)+(1023&Gt)+65536):(Zt.push(bt),Ut--):Zt.push(bt);return Zt}function ze(It){return ce(It,function(Zt){var Ut="";return Zt>65535&&(Ut+=he((Zt-=65536)>>>10&1023|55296),Zt=56320|1023&Zt),Ut+he(Zt)}).join("")}function Be(It){return It-48<10?It-22:It-65<26?It-65:It-97<26?It-97:S}function Pe(It,Zt){return It+22+75*(It<26)-((0!=Zt)<<5)}function je(It,Zt,Ut){var Bt=0;for(It=Ut?ie(It/700):It>>1,It+=ie(It/Zt);It>455;Bt+=S)It=ie(It/35);return ie(Bt+36*It/(It+38))}function He(It){var Bt,Xt,Zn,Ur,di,Lr,Mr,Kr,ei,Nn,Zt=[],Ut=It.length,bt=0,Gt=128,xt=72;for((Xt=It.lastIndexOf("-"))<0&&(Xt=0),Zn=0;Zn<Xt;++Zn)It.charCodeAt(Zn)>=128&&De("not-basic"),Zt.push(It.charCodeAt(Zn));for(Ur=Xt>0?Xt+1:0;Ur<Ut;){for(di=bt,Lr=1,Mr=S;Ur>=Ut&&De("invalid-input"),((Kr=Be(It.charCodeAt(Ur++)))>=S||Kr>ie((y-bt)/Lr))&&De("overflow"),bt+=Kr*Lr,!(Kr<(ei=Mr<=xt?1:Mr>=xt+26?26:Mr-xt));Mr+=S)Lr>ie(y/(Nn=S-ei))&&De("overflow"),Lr*=Nn;xt=je(bt-di,Bt=Zt.length+1,0==di),ie(bt/Bt)>y-Gt&&De("overflow"),Gt+=ie(bt/Bt),bt%=Bt,Zt.splice(bt++,0,Gt)}return ze(Zt)}function Vt(It){var Zt,Ut,Bt,bt,Gt,xt,Xt,Zn,Ur,di,Lr,Kr,ei,Nn,$n,Mr=[];for(Kr=(It=Ve(It)).length,Zt=128,Ut=0,Gt=72,xt=0;xt<Kr;++xt)(Lr=It[xt])<128&&Mr.push(he(Lr));for(Bt=bt=Mr.length,bt&&Mr.push("-");Bt<Kr;){for(Xt=y,xt=0;xt<Kr;++xt)(Lr=It[xt])>=Zt&&Lr<Xt&&(Xt=Lr);for(Xt-Zt>ie((y-Ut)/(ei=Bt+1))&&De("overflow"),Ut+=(Xt-Zt)*ei,Zt=Xt,xt=0;xt<Kr;++xt)if((Lr=It[xt])<Zt&&++Ut>y&&De("overflow"),Lr==Zt){for(Zn=Ut,Ur=S;!(Zn<(di=Ur<=Gt?1:Ur>=Gt+26?26:Ur-Gt));Ur+=S)Mr.push(he(Pe(di+($n=Zn-di)%(Nn=S-di),0))),Zn=ie($n/Nn);Mr.push(he(Pe(Zn,0))),Gt=je(Ut,ei,Bt==bt),Ut=0,++Bt}++Ut,++Zt}return Mr.join("")}_={version:"1.3.2",ucs2:{decode:Ve,encode:ze},decode:He,encode:Vt,toASCII:function(It){return lt(It,function(Zt){return ae.test(Zt)?"xn--"+Vt(Zt):Zt})},toUnicode:function(It){return lt(It,function(Zt){return ue.test(Zt)?He(Zt.slice(4).toLowerCase()):Zt})}},void 0!==(r=function(){return _}.call(T,i,T,v))&&(v.exports=r)}()},8157:v=>{"use strict";var T=String.prototype.replace,i=/%20/g;v.exports={default:"RFC3986",formatters:{RFC1738:function(u){return T.call(u,i,"+")},RFC3986:function(u){return String(u)}},RFC1738:"RFC1738",RFC3986:"RFC3986"}},59009:(v,T,i)=>{"use strict";var r=i(75672),u=i(19913),p=i(8157);v.exports={formats:p,parse:u,stringify:r}},19913:(v,T,i)=>{"use strict";var r=i(16835),u=Object.prototype.hasOwnProperty,p=Array.isArray,d={allowDots:!1,allowPrototypes:!1,allowSparse:!1,arrayLimit:20,charset:"utf-8",charsetSentinel:!1,comma:!1,decoder:r.decode,delimiter:"&",depth:5,ignoreQueryPrefix:!1,interpretNumericEntities:!1,parameterLimit:1e3,parseArrays:!0,plainObjects:!1,strictNullHandling:!1},_=function(J,K){return J&&"string"==typeof J&&K.comma&&J.indexOf(",")>-1?J.split(","):J},L=function(K,ee,ue,ae){if(K){var H=ue.allowDots?K.replace(/\.([^.[]+)/g,"[$1]"):K,Ee=/(\[[^[\]]*])/g,ie=ue.depth>0&&/(\[[^[\]]*])/.exec(H),he=ie?H.slice(0,ie.index):H,ge=[];if(he){if(!ue.plainObjects&&u.call(Object.prototype,he)&&!ue.allowPrototypes)return;ge.push(he)}for(var De=0;ue.depth>0&&null!==(ie=Ee.exec(H))&&De<ue.depth;){if(De+=1,!ue.plainObjects&&u.call(Object.prototype,ie[1].slice(1,-1))&&!ue.allowPrototypes)return;ge.push(ie[1])}return ie&&ge.push("["+H.slice(ie.index)+"]"),function(J,K,ee,ue){for(var ae=ue?K:_(K,ee),H=J.length-1;H>=0;--H){var se,Ee=J[H];if("[]"===Ee&&ee.parseArrays)se=[].concat(ae);else{se=ee.plainObjects?Object.create(null):{};var ie="["===Ee.charAt(0)&&"]"===Ee.charAt(Ee.length-1)?Ee.slice(1,-1):Ee,he=parseInt(ie,10);ee.parseArrays||""!==ie?!isNaN(he)&&Ee!==ie&&String(he)===ie&&he>=0&&ee.parseArrays&&he<=ee.arrayLimit?(se=[])[he]=ae:"__proto__"!==ie&&(se[ie]=ae):se={0:ae}}ae=se}return ae}(ge,ee,ue,ae)}};v.exports=function(J,K){var ee=function(K){if(!K)return d;if(null!=K.decoder&&"function"!=typeof K.decoder)throw new TypeError("Decoder has to be a function.");if(void 0!==K.charset&&"utf-8"!==K.charset&&"iso-8859-1"!==K.charset)throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");return{allowDots:void 0===K.allowDots?d.allowDots:!!K.allowDots,allowPrototypes:"boolean"==typeof K.allowPrototypes?K.allowPrototypes:d.allowPrototypes,allowSparse:"boolean"==typeof K.allowSparse?K.allowSparse:d.allowSparse,arrayLimit:"number"==typeof K.arrayLimit?K.arrayLimit:d.arrayLimit,charset:void 0===K.charset?d.charset:K.charset,charsetSentinel:"boolean"==typeof K.charsetSentinel?K.charsetSentinel:d.charsetSentinel,comma:"boolean"==typeof K.comma?K.comma:d.comma,decoder:"function"==typeof K.decoder?K.decoder:d.decoder,delimiter:"string"==typeof K.delimiter||r.isRegExp(K.delimiter)?K.delimiter:d.delimiter,depth:"number"==typeof K.depth||!1===K.depth?+K.depth:d.depth,ignoreQueryPrefix:!0===K.ignoreQueryPrefix,interpretNumericEntities:"boolean"==typeof K.interpretNumericEntities?K.interpretNumericEntities:d.interpretNumericEntities,parameterLimit:"number"==typeof K.parameterLimit?K.parameterLimit:d.parameterLimit,parseArrays:!1!==K.parseArrays,plainObjects:"boolean"==typeof K.plainObjects?K.plainObjects:d.plainObjects,strictNullHandling:"boolean"==typeof K.strictNullHandling?K.strictNullHandling:d.strictNullHandling}}(K);if(""===J||null==J)return ee.plainObjects?Object.create(null):{};for(var ue="string"==typeof J?function(K,ee){var ie,ue={},se=(ee.ignoreQueryPrefix?K.replace(/^\?/,""):K).split(ee.delimiter,ee.parameterLimit===1/0?void 0:ee.parameterLimit),Ee=-1,he=ee.charset;if(ee.charsetSentinel)for(ie=0;ie<se.length;++ie)0===se[ie].indexOf("utf8=")&&("utf8=%E2%9C%93"===se[ie]?he="utf-8":"utf8=%26%2310003%3B"===se[ie]&&(he="iso-8859-1"),Ee=ie,ie=se.length);for(ie=0;ie<se.length;++ie)if(ie!==Ee){var lt,Ve,ge=se[ie],De=ge.indexOf("]="),ce=-1===De?ge.indexOf("="):De+1;-1===ce?(lt=ee.decoder(ge,d.decoder,he,"key"),Ve=ee.strictNullHandling?null:""):(lt=ee.decoder(ge.slice(0,ce),d.decoder,he,"key"),Ve=r.maybeMap(_(ge.slice(ce+1),ee),function(ze){return ee.decoder(ze,d.decoder,he,"value")})),Ve&&ee.interpretNumericEntities&&"iso-8859-1"===he&&(Ve=Ve.replace(/&#(\d+);/g,function(K,ee){return String.fromCharCode(parseInt(ee,10))})),ge.indexOf("[]=")>-1&&(Ve=p(Ve)?[Ve]:Ve),ue[lt]=u.call(ue,lt)?r.combine(ue[lt],Ve):Ve}return ue}(J,ee):J,ae=ee.plainObjects?Object.create(null):{},H=Object.keys(ue),se=0;se<H.length;++se){var Ee=H[se],ie=L(Ee,ue[Ee],ee,"string"==typeof J);ae=r.merge(ae,ie,ee)}return!0===ee.allowSparse?ae:r.compact(ae)}},75672:(v,T,i)=>{"use strict";var r=i(11144),u=i(16835),p=i(8157),d=Object.prototype.hasOwnProperty,e={brackets:function(H){return H+"[]"},comma:"comma",indices:function(H,se){return H+"["+se+"]"},repeat:function(H){return H}},_=Array.isArray,y=String.prototype.split,S=Array.prototype.push,A=function(ae,H){S.apply(ae,_(H)?H:[H])},N=Date.prototype.toISOString,L=p.default,Z={addQueryPrefix:!1,allowDots:!1,charset:"utf-8",charsetSentinel:!1,delimiter:"&",encode:!0,encoder:u.encode,encodeValuesOnly:!1,format:L,formatter:p.formatters[L],indices:!1,serializeDate:function(H){return N.call(H)},skipNulls:!1,strictNullHandling:!1},K={},ee=function ae(H,se,Ee,ie,he,ge,De,ce,lt,Ve,ze,Be,Pe,je,He,Vt){for(var it=H,tn=Vt,It=0,Zt=!1;void 0!==(tn=tn.get(K))&&!Zt;){var Ut=tn.get(H);if(It+=1,void 0!==Ut){if(Ut===It)throw new RangeError("Cyclic object value");Zt=!0}void 0===tn.get(K)&&(It=0)}if("function"==typeof ce?it=ce(se,it):it instanceof Date?it=ze(it):"comma"===Ee&&_(it)&&(it=u.maybeMap(it,function($n){return $n instanceof Date?ze($n):$n})),null===it){if(he)return De&&!je?De(se,Z.encoder,He,"key",Be):se;it=""}if(function(H){return"string"==typeof H||"number"==typeof H||"boolean"==typeof H||"symbol"==typeof H||"bigint"==typeof H}(it)||u.isBuffer(it)){if(De){var Bt=je?se:De(se,Z.encoder,He,"key",Be);if("comma"===Ee&&je){for(var bt=y.call(String(it),","),Gt="",xt=0;xt<bt.length;++xt)Gt+=(0===xt?"":",")+Pe(De(bt[xt],Z.encoder,He,"value",Be));return[Pe(Bt)+(ie&&_(it)&&1===bt.length?"[]":"")+"="+Gt]}return[Pe(Bt)+"="+Pe(De(it,Z.encoder,He,"value",Be))]}return[Pe(se)+"="+Pe(String(it))]}var Zn,Xt=[];if(void 0===it)return Xt;if("comma"===Ee&&_(it))Zn=[{value:it.length>0?it.join(",")||null:void 0}];else if(_(ce))Zn=ce;else{var Ur=Object.keys(it);Zn=lt?Ur.sort(lt):Ur}for(var di=ie&&_(it)&&1===it.length?se+"[]":se,Lr=0;Lr<Zn.length;++Lr){var Mr=Zn[Lr],Kr="object"==typeof Mr&&void 0!==Mr.value?Mr.value:it[Mr];if(!ge||null!==Kr){var ei=_(it)?"function"==typeof Ee?Ee(di,Mr):di:di+(Ve?"."+Mr:"["+Mr+"]");Vt.set(H,It);var Nn=r();Nn.set(K,Vt),A(Xt,ae(Kr,ei,Ee,ie,he,ge,De,ce,lt,Ve,ze,Be,Pe,je,He,Nn))}}return Xt};v.exports=function(ae,H){var ie,se=ae,Ee=function(H){if(!H)return Z;if(null!=H.encoder&&"function"!=typeof H.encoder)throw new TypeError("Encoder has to be a function.");var se=H.charset||Z.charset;if(void 0!==H.charset&&"utf-8"!==H.charset&&"iso-8859-1"!==H.charset)throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");var Ee=p.default;if(void 0!==H.format){if(!d.call(p.formatters,H.format))throw new TypeError("Unknown format option provided.");Ee=H.format}var ie=p.formatters[Ee],he=Z.filter;return("function"==typeof H.filter||_(H.filter))&&(he=H.filter),{addQueryPrefix:"boolean"==typeof H.addQueryPrefix?H.addQueryPrefix:Z.addQueryPrefix,allowDots:void 0===H.allowDots?Z.allowDots:!!H.allowDots,charset:se,charsetSentinel:"boolean"==typeof H.charsetSentinel?H.charsetSentinel:Z.charsetSentinel,delimiter:void 0===H.delimiter?Z.delimiter:H.delimiter,encode:"boolean"==typeof H.encode?H.encode:Z.encode,encoder:"function"==typeof H.encoder?H.encoder:Z.encoder,encodeValuesOnly:"boolean"==typeof H.encodeValuesOnly?H.encodeValuesOnly:Z.encodeValuesOnly,filter:he,format:Ee,formatter:ie,serializeDate:"function"==typeof H.serializeDate?H.serializeDate:Z.serializeDate,skipNulls:"boolean"==typeof H.skipNulls?H.skipNulls:Z.skipNulls,sort:"function"==typeof H.sort?H.sort:null,strictNullHandling:"boolean"==typeof H.strictNullHandling?H.strictNullHandling:Z.strictNullHandling}}(H);"function"==typeof Ee.filter?se=(0,Ee.filter)("",se):_(Ee.filter)&&(ie=Ee.filter);var ge=[];if("object"!=typeof se||null===se)return"";var ce=e[H&&H.arrayFormat in e?H.arrayFormat:H&&"indices"in H?H.indices?"indices":"repeat":"indices"];if(H&&"commaRoundTrip"in H&&"boolean"!=typeof H.commaRoundTrip)throw new TypeError("`commaRoundTrip` must be a boolean, or absent");var lt="comma"===ce&&H&&H.commaRoundTrip;ie||(ie=Object.keys(se)),Ee.sort&&ie.sort(Ee.sort);for(var Ve=r(),ze=0;ze<ie.length;++ze){var Be=ie[ze];Ee.skipNulls&&null===se[Be]||A(ge,ee(se[Be],Be,ce,lt,Ee.strictNullHandling,Ee.skipNulls,Ee.encode?Ee.encoder:null,Ee.filter,Ee.sort,Ee.allowDots,Ee.serializeDate,Ee.format,Ee.formatter,Ee.encodeValuesOnly,Ee.charset,Ve))}var Pe=ge.join(Ee.delimiter),je=!0===Ee.addQueryPrefix?"?":"";return Ee.charsetSentinel&&(je+="iso-8859-1"===Ee.charset?"utf8=%26%2310003%3B&":"utf8=%E2%9C%93&"),Pe.length>0?je+Pe:""}},16835:(v,T,i)=>{"use strict";var r=i(8157),u=Object.prototype.hasOwnProperty,p=Array.isArray,d=function(){for(var ue=[],ae=0;ae<256;++ae)ue.push("%"+((ae<16?"0":"")+ae.toString(16)).toUpperCase());return ue}(),_=function(ae,H){for(var se=H&&H.plainObjects?Object.create(null):{},Ee=0;Ee<ae.length;++Ee)void 0!==ae[Ee]&&(se[Ee]=ae[Ee]);return se};v.exports={arrayToObject:_,assign:function(ae,H){return Object.keys(H).reduce(function(se,Ee){return se[Ee]=H[Ee],se},ae)},combine:function(ae,H){return[].concat(ae,H)},compact:function(ae){for(var H=[{obj:{o:ae},prop:"o"}],se=[],Ee=0;Ee<H.length;++Ee)for(var ie=H[Ee],he=ie.obj[ie.prop],ge=Object.keys(he),De=0;De<ge.length;++De){var ce=ge[De],lt=he[ce];"object"==typeof lt&&null!==lt&&-1===se.indexOf(lt)&&(H.push({obj:he,prop:ce}),se.push(lt))}return function(ae){for(;ae.length>1;){var H=ae.pop(),se=H.obj[H.prop];if(p(se)){for(var Ee=[],ie=0;ie<se.length;++ie)void 0!==se[ie]&&Ee.push(se[ie]);H.obj[H.prop]=Ee}}}(H),ae},decode:function(ue,ae,H){var se=ue.replace(/\+/g," ");if("iso-8859-1"===H)return se.replace(/%[0-9a-f]{2}/gi,unescape);try{return decodeURIComponent(se)}catch(Ee){return se}},encode:function(ae,H,se,Ee,ie){if(0===ae.length)return ae;var he=ae;if("symbol"==typeof ae?he=Symbol.prototype.toString.call(ae):"string"!=typeof ae&&(he=String(ae)),"iso-8859-1"===se)return escape(he).replace(/%u[0-9a-f]{4}/gi,function(lt){return"%26%23"+parseInt(lt.slice(2),16)+"%3B"});for(var ge="",De=0;De<he.length;++De){var ce=he.charCodeAt(De);45===ce||46===ce||95===ce||126===ce||ce>=48&&ce<=57||ce>=65&&ce<=90||ce>=97&&ce<=122||ie===r.RFC1738&&(40===ce||41===ce)?ge+=he.charAt(De):ce<128?ge+=d[ce]:ce<2048?ge+=d[192|ce>>6]+d[128|63&ce]:ce<55296||ce>=57344?ge+=d[224|ce>>12]+d[128|ce>>6&63]+d[128|63&ce]:(ce=65536+((1023&ce)<<10|1023&he.charCodeAt(De+=1)),ge+=d[240|ce>>18]+d[128|ce>>12&63]+d[128|ce>>6&63]+d[128|63&ce])}return ge},isBuffer:function(ae){return!(!ae||"object"!=typeof ae||!(ae.constructor&&ae.constructor.isBuffer&&ae.constructor.isBuffer(ae)))},isRegExp:function(ae){return"[object RegExp]"===Object.prototype.toString.call(ae)},maybeMap:function(ae,H){if(p(ae)){for(var se=[],Ee=0;Ee<ae.length;Ee+=1)se.push(H(ae[Ee]));return se}return H(ae)},merge:function ue(ae,H,se){if(!H)return ae;if("object"!=typeof H){if(p(ae))ae.push(H);else{if(!ae||"object"!=typeof ae)return[ae,H];(se&&(se.plainObjects||se.allowPrototypes)||!u.call(Object.prototype,H))&&(ae[H]=!0)}return ae}if(!ae||"object"!=typeof ae)return[ae].concat(H);var Ee=ae;return p(ae)&&!p(H)&&(Ee=_(ae,se)),p(ae)&&p(H)?(H.forEach(function(ie,he){if(u.call(ae,he)){var ge=ae[he];ge&&"object"==typeof ge&&ie&&"object"==typeof ie?ae[he]=ue(ge,ie,se):ae.push(ie)}else ae[he]=ie}),ae):Object.keys(H).reduce(function(ie,he){var ge=H[he];return ie[he]=u.call(ie,he)?ue(ie[he],ge,se):ge,ie},Ee)}}},98216:v=>{"use strict";function T(i,r){return Object.prototype.hasOwnProperty.call(i,r)}v.exports=function(i,r,u,p){u=u||"=";var d={};if("string"!=typeof i||0===i.length)return d;var e=/\+/g;i=i.split(r=r||"&");var _=1e3;p&&"number"==typeof p.maxKeys&&(_=p.maxKeys);var y=i.length;_>0&&y>_&&(y=_);for(var S=0;S<y;++S){var L,Z,J,K,A=i[S].replace(e,"%20"),N=A.indexOf(u);N>=0?(L=A.substr(0,N),Z=A.substr(N+1)):(L=A,Z=""),J=decodeURIComponent(L),K=decodeURIComponent(Z),T(d,J)?Array.isArray(d[J])?d[J].push(K):d[J]=[d[J],K]:d[J]=K}return d}},36173:v=>{"use strict";var T=function(i){switch(typeof i){case"string":return i;case"boolean":return i?"true":"false";case"number":return isFinite(i)?i:"";default:return""}};v.exports=function(i,r,u,p){return r=r||"&",u=u||"=",null===i&&(i=void 0),"object"==typeof i?Object.keys(i).map(function(d){var e=encodeURIComponent(T(d))+u;return Array.isArray(i[d])?i[d].map(function(_){return e+encodeURIComponent(T(_))}).join(r):e+encodeURIComponent(T(i[d]))}).join(r):p?encodeURIComponent(T(p))+u+encodeURIComponent(T(i)):""}},36284:(v,T,i)=>{"use strict";T.decode=T.parse=i(98216),T.encode=T.stringify=i(36173)},76959:(v,T)=>{"use strict";var i=Object.prototype.hasOwnProperty;function u(_){try{return decodeURIComponent(_.replace(/\+/g," "))}catch(y){return null}}function p(_){try{return encodeURIComponent(_)}catch(y){return null}}T.stringify=function(_,y){y=y||"";var A,N,S=[];for(N in"string"!=typeof y&&(y="?"),_)if(i.call(_,N)){if(!(A=_[N])&&(null==A||isNaN(A))&&(A=""),N=p(N),A=p(A),null===N||null===A)continue;S.push(N+"="+A)}return S.length?y+S.join("&"):""},T.parse=function(_){for(var A,y=/([^=?#&]+)=?([^&]*)/g,S={};A=y.exec(_);){var N=u(A[1]),L=u(A[2]);null===N||null===L||N in S||(S[N]=L)}return S}},17346:(v,T,i)=>{const r=i(66952),u=i(32582),p=r.types;v.exports=class pS{constructor(e,_){if(this._setDefaults(e),e instanceof RegExp)this.ignoreCase=e.ignoreCase,this.multiline=e.multiline,e=e.source;else{if("string"!=typeof e)throw new Error("Expected a regexp or string");this.ignoreCase=_&&-1!==_.indexOf("i"),this.multiline=_&&-1!==_.indexOf("m")}this.tokens=r(e)}_setDefaults(e){this.max=null!=e.max?e.max:null!=pS.prototype.max?pS.prototype.max:100,this.defaultRange=e.defaultRange?e.defaultRange:this.defaultRange.clone(),e.randInt&&(this.randInt=e.randInt)}gen(){return this._gen(this.tokens,[])}_gen(e,_){var y,S,A,N,L;switch(e.type){case p.ROOT:case p.GROUP:if(e.followedBy||e.notFollowedBy)return"";for(e.remember&&void 0===e.groupNumber&&(e.groupNumber=_.push(null)-1),S="",N=0,L=(y=e.options?this._randSelect(e.options):e.stack).length;N<L;N++)S+=this._gen(y[N],_);return e.remember&&(_[e.groupNumber]=S),S;case p.POSITION:return"";case p.SET:var Z=this._expand(e);return Z.length?String.fromCharCode(this._randSelect(Z)):"";case p.REPETITION:for(A=this.randInt(e.min,e.max===1/0?e.min+this.max:e.max),S="",N=0;N<A;N++)S+=this._gen(e.value,_);return S;case p.REFERENCE:return _[e.value-1]||"";case p.CHAR:var J=this.ignoreCase&&this._randBool()?this._toOtherCase(e.value):e.value;return String.fromCharCode(J)}}_toOtherCase(e){return e+(97<=e&&e<=122?-32:65<=e&&e<=90?32:0)}_randBool(){return!this.randInt(0,1)}_randSelect(e){return e instanceof u?e.index(this.randInt(0,e.length-1)):e[this.randInt(0,e.length-1)]}_expand(e){if(e.type===r.types.CHAR)return new u(e.value);if(e.type===r.types.RANGE)return new u(e.from,e.to);{let _=new u;for(let y=0;y<e.set.length;y++){let S=this._expand(e.set[y]);if(_.add(S),this.ignoreCase)for(let A=0;A<S.length;A++){let N=S.index(A),L=this._toOtherCase(N);N!==L&&_.add(L)}}return e.not?this.defaultRange.clone().subtract(_):this.defaultRange.clone().intersect(_)}}randInt(e,_){return e+Math.floor(Math.random()*(1+_-e))}get defaultRange(){return this._range=this._range||new u(32,126)}set defaultRange(e){this._range=e}static randexp(e,_){var y;return"string"==typeof e&&(e=new RegExp(e,_)),void 0===e._randexp?(y=new pS(e,_),e._randexp=y):(y=e._randexp)._setDefaults(e),y.gen()}static sugar(){RegExp.prototype.gen=function(){return pS.randexp(this)}}}},57021:(v,T,i)=>{"use strict";Object.defineProperty(T,"__esModule",{value:!0}),T.CopyToClipboard=void 0;var r=p(i(78139)),u=p(i(96967));function p(se){return se&&se.__esModule?se:{default:se}}function d(se){return(d="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(ie){return typeof ie}:function(ie){return ie&&"function"==typeof Symbol&&ie.constructor===Symbol&&ie!==Symbol.prototype?"symbol":typeof ie})(se)}function e(se,Ee){var ie=Object.keys(se);if(Object.getOwnPropertySymbols){var he=Object.getOwnPropertySymbols(se);Ee&&(he=he.filter(function(ge){return Object.getOwnPropertyDescriptor(se,ge).enumerable})),ie.push.apply(ie,he)}return ie}function A(se,Ee){if(!(se instanceof Ee))throw new TypeError("Cannot call a class as a function")}function N(se,Ee){for(var ie=0;ie<Ee.length;ie++){var he=Ee[ie];he.enumerable=he.enumerable||!1,he.configurable=!0,"value"in he&&(he.writable=!0),Object.defineProperty(se,he.key,he)}}function Z(se,Ee){return!Ee||"object"!==d(Ee)&&"function"!=typeof Ee?K(se):Ee}function J(se){return(J=Object.setPrototypeOf?Object.getPrototypeOf:function(ie){return ie.__proto__||Object.getPrototypeOf(ie)})(se)}function K(se){if(void 0===se)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return se}function ue(se,Ee){return(ue=Object.setPrototypeOf||function(he,ge){return he.__proto__=ge,he})(se,Ee)}function ae(se,Ee,ie){return Ee in se?Object.defineProperty(se,Ee,{value:ie,enumerable:!0,configurable:!0,writable:!0}):se[Ee]=ie,se}var H=function(se){function Ee(){var ie,he;A(this,Ee);for(var ge=arguments.length,De=new Array(ge),ce=0;ce<ge;ce++)De[ce]=arguments[ce];return ae(K(he=Z(this,(ie=J(Ee)).call.apply(ie,[this].concat(De)))),"onClick",function(lt){var Ve=he.props,ze=Ve.text,Be=Ve.onCopy,je=Ve.options,He=r.default.Children.only(Ve.children),Vt=(0,u.default)(ze,je);Be&&Be(ze,Vt),He&&He.props&&"function"==typeof He.props.onClick&&He.props.onClick(lt)}),he}return function(se,Ee){if("function"!=typeof Ee&&null!==Ee)throw new TypeError("Super expression must either be null or a function");se.prototype=Object.create(Ee&&Ee.prototype,{constructor:{value:se,writable:!0,configurable:!0}}),Ee&&ue(se,Ee)}(Ee,se),function(se,Ee,ie){Ee&&N(se.prototype,Ee)}(Ee,[{key:"render",value:function(){var he=this.props,lt=he.children,Ve=function(se,Ee){if(null==se)return{};var he,ge,ie=function(se,Ee){if(null==se)return{};var ge,De,ie={},he=Object.keys(se);for(De=0;De<he.length;De++)!(Ee.indexOf(ge=he[De])>=0)&&(ie[ge]=se[ge]);return ie}(se,Ee);if(Object.getOwnPropertySymbols){var De=Object.getOwnPropertySymbols(se);for(ge=0;ge<De.length;ge++)!(Ee.indexOf(he=De[ge])>=0)&&(!Object.prototype.propertyIsEnumerable.call(se,he)||(ie[he]=se[he]))}return ie}(he,["text","onCopy","options","children"]),ze=r.default.Children.only(lt);return r.default.cloneElement(ze,function(se){for(var Ee=1;Ee<arguments.length;Ee++){var ie=null!=arguments[Ee]?arguments[Ee]:{};Ee%2?e(ie,!0).forEach(function(he){ae(se,he,ie[he])}):Object.getOwnPropertyDescriptors?Object.defineProperties(se,Object.getOwnPropertyDescriptors(ie)):e(ie).forEach(function(he){Object.defineProperty(se,he,Object.getOwnPropertyDescriptor(ie,he))})}return se}({},Ve,{onClick:this.onClick}))}}]),Ee}(r.default.PureComponent);T.CopyToClipboard=H,ae(H,"defaultProps",{onCopy:void 0,options:void 0})},43409:(v,T,i)=>{"use strict";var u=i(57021).CopyToClipboard;u.CopyToClipboard=u,v.exports=u},16709:(v,T,i)=>{"use strict";Object.defineProperty(T,"__esModule",{value:!0}),T.DebounceInput=void 0;var r=p(i(78139)),u=p(i(86906));function p(ie){return ie&&ie.__esModule?ie:{default:ie}}function d(ie){return(d="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(ge){return typeof ge}:function(ge){return ge&&"function"==typeof Symbol&&ge.constructor===Symbol&&ge!==Symbol.prototype?"symbol":typeof ge})(ie)}function y(ie,he){var ge=Object.keys(ie);if(Object.getOwnPropertySymbols){var De=Object.getOwnPropertySymbols(ie);he&&(De=De.filter(function(ce){return Object.getOwnPropertyDescriptor(ie,ce).enumerable})),ge.push.apply(ge,De)}return ge}function S(ie){for(var he=1;he<arguments.length;he++){var ge=null!=arguments[he]?arguments[he]:{};he%2?y(Object(ge),!0).forEach(function(De){se(ie,De,ge[De])}):Object.getOwnPropertyDescriptors?Object.defineProperties(ie,Object.getOwnPropertyDescriptors(ge)):y(Object(ge)).forEach(function(De){Object.defineProperty(ie,De,Object.getOwnPropertyDescriptor(ge,De))})}return ie}function N(ie,he){for(var ge=0;ge<he.length;ge++){var De=he[ge];De.enumerable=De.enumerable||!1,De.configurable=!0,"value"in De&&(De.writable=!0),Object.defineProperty(ie,De.key,De)}}function J(ie,he){return(J=Object.setPrototypeOf||function(De,ce){return De.__proto__=ce,De})(ie,he)}function ee(ie,he){return!he||"object"!==d(he)&&"function"!=typeof he?ue(ie):he}function ue(ie){if(void 0===ie)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return ie}function H(ie){return(H=Object.setPrototypeOf?Object.getPrototypeOf:function(ge){return ge.__proto__||Object.getPrototypeOf(ge)})(ie)}function se(ie,he,ge){return he in ie?Object.defineProperty(ie,he,{value:ge,enumerable:!0,configurable:!0,writable:!0}):ie[he]=ge,ie}var Ee=function(ie){!function(ie,he){if("function"!=typeof he&&null!==he)throw new TypeError("Super expression must either be null or a function");ie.prototype=Object.create(he&&he.prototype,{constructor:{value:ie,writable:!0,configurable:!0}}),he&&J(ie,he)}(ge,ie);var he=function(ie){var he=function(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(ie){return!1}}();return function(){var ce,De=H(ie);if(he){var lt=H(this).constructor;ce=Reflect.construct(De,arguments,lt)}else ce=De.apply(this,arguments);return ee(this,ce)}}(ge);function ge(De){var ce;return function(ie,he){if(!(ie instanceof he))throw new TypeError("Cannot call a class as a function")}(this,ge),se(ue(ce=he.call(this,De)),"onChange",function(Ve){Ve.persist();var ze=ce.state.value,Be=ce.props.minLength;ce.setState({value:Ve.target.value},function(){var Pe=ce.state.value;Pe.length>=Be?ce.notify(Ve):ze.length>Pe.length&&ce.notify(S(S({},Ve),{},{target:S(S({},Ve.target),{},{value:""})}))})}),se(ue(ce),"onKeyDown",function(Ve){"Enter"===Ve.key&&ce.forceNotify(Ve);var ze=ce.props.onKeyDown;ze&&(Ve.persist(),ze(Ve))}),se(ue(ce),"onBlur",function(Ve){ce.forceNotify(Ve);var ze=ce.props.onBlur;ze&&(Ve.persist(),ze(Ve))}),se(ue(ce),"createNotifier",function(Ve){if(Ve<0)ce.notify=function(){return null};else if(0===Ve)ce.notify=ce.doNotify;else{var ze=(0,u.default)(function(Be){ce.isDebouncing=!1,ce.doNotify(Be)},Ve);ce.notify=function(Be){ce.isDebouncing=!0,ze(Be)},ce.flush=function(){return ze.flush()},ce.cancel=function(){ce.isDebouncing=!1,ze.cancel()}}}),se(ue(ce),"doNotify",function(){var Ve=ce.props.onChange;Ve.apply(void 0,arguments)}),se(ue(ce),"forceNotify",function(Ve){if(ce.isDebouncing||!(ce.props.debounceTimeout>0)){ce.cancel&&ce.cancel();var Be=ce.state.value;ce.doNotify(Be.length>=ce.props.minLength?Ve:S(S({},Ve),{},{target:S(S({},Ve.target),{},{value:Be})}))}}),ce.isDebouncing=!1,ce.state={value:null==De.value?"":De.value},ce.createNotifier(ce.props.debounceTimeout),ce}return function(ie,he,ge){he&&N(ie.prototype,he)}(ge,[{key:"componentDidUpdate",value:function(ce){if(!this.isDebouncing){var lt=this.props,Ve=lt.value,ze=lt.debounceTimeout,Be=ce.debounceTimeout;void 0!==Ve&&ce.value!==Ve&&this.state.value!==Ve&&this.setState({value:Ve}),ze!==Be&&this.createNotifier(ze)}}},{key:"componentWillUnmount",value:function(){this.flush&&this.flush()}},{key:"render",value:function(){var Ut,Bt,ce=this.props,lt=ce.element,je=ce.forceNotifyByEnter,He=ce.forceNotifyOnBlur,Vt=ce.onKeyDown,it=ce.onBlur,tn=ce.inputRef,It=function(ie,he){if(null==ie)return{};var De,ce,ge=function(ie,he){if(null==ie)return{};var ce,lt,ge={},De=Object.keys(ie);for(lt=0;lt<De.length;lt++)!(he.indexOf(ce=De[lt])>=0)&&(ge[ce]=ie[ce]);return ge}(ie,he);if(Object.getOwnPropertySymbols){var lt=Object.getOwnPropertySymbols(ie);for(ce=0;ce<lt.length;ce++)!(he.indexOf(De=lt[ce])>=0)&&(!Object.prototype.propertyIsEnumerable.call(ie,De)||(ge[De]=ie[De]))}return ge}(ce,["element","onChange","value","minLength","debounceTimeout","forceNotifyByEnter","forceNotifyOnBlur","onKeyDown","onBlur","inputRef"]),Zt=this.state.value;Ut=je?{onKeyDown:this.onKeyDown}:Vt?{onKeyDown:Vt}:{},Bt=He?{onBlur:this.onBlur}:it?{onBlur:it}:{};var bt=tn?{ref:tn}:{};return r.default.createElement(lt,S(S(S(S({},It),{},{onChange:this.onChange,value:Zt},Ut),Bt),bt))}}]),ge}(r.default.PureComponent);T.DebounceInput=Ee,se(Ee,"defaultProps",{element:"input",type:"text",onKeyDown:void 0,onBlur:void 0,value:void 0,minLength:0,debounceTimeout:100,forceNotifyByEnter:!0,forceNotifyOnBlur:!0,inputRef:void 0})},41205:(v,T,i)=>{"use strict";var u=i(16709).DebounceInput;u.DebounceInput=u,v.exports=u},85503:(v,T,i)=>{"use strict";var r=i(78139),u=i(18228),p=i(88712);function d(b){for(var x="https://reactjs.org/docs/error-decoder.html?invariant="+b,G=1;G<arguments.length;G++)x+="&args[]="+encodeURIComponent(arguments[G]);return"Minified React error #"+b+"; visit "+x+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}if(!r)throw Error(d(227));var e=new Set,_={};function y(b,x){S(b,x),S(b+"Capture",x)}function S(b,x){for(_[b]=x,b=0;b<x.length;b++)e.add(x[b])}var A=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),N=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,L=Object.prototype.hasOwnProperty,Z={},J={};function ae(b,x,G,Se,We,Nt,rn){this.acceptsBooleans=2===x||3===x||4===x,this.attributeName=Se,this.attributeNamespace=We,this.mustUseProperty=G,this.propertyName=b,this.type=x,this.sanitizeURL=Nt,this.removeEmptyString=rn}var H={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(b){H[b]=new ae(b,0,!1,b,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(b){var x=b[0];H[x]=new ae(x,1,!1,b[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(b){H[b]=new ae(b,2,!1,b.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(b){H[b]=new ae(b,2,!1,b,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(b){H[b]=new ae(b,3,!1,b.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(b){H[b]=new ae(b,3,!0,b,null,!1,!1)}),["capture","download"].forEach(function(b){H[b]=new ae(b,4,!1,b,null,!1,!1)}),["cols","rows","size","span"].forEach(function(b){H[b]=new ae(b,6,!1,b,null,!1,!1)}),["rowSpan","start"].forEach(function(b){H[b]=new ae(b,5,!1,b.toLowerCase(),null,!1,!1)});var se=/[\-:]([a-z])/g;function Ee(b){return b[1].toUpperCase()}function ie(b,x,G,Se){var We=H.hasOwnProperty(x)?H[x]:null;(null!==We?0===We.type:!Se&&2<x.length&&("o"===x[0]||"O"===x[0])&&("n"===x[1]||"N"===x[1]))||(function(b,x,G,Se){if(null==x||function(b,x,G,Se){if(null!==G&&0===G.type)return!1;switch(typeof x){case"function":case"symbol":return!0;case"boolean":return!Se&&(null!==G?!G.acceptsBooleans:"data-"!==(b=b.toLowerCase().slice(0,5))&&"aria-"!==b);default:return!1}}(b,x,G,Se))return!0;if(Se)return!1;if(null!==G)switch(G.type){case 3:return!x;case 4:return!1===x;case 5:return isNaN(x);case 6:return isNaN(x)||1>x}return!1}(x,G,We,Se)&&(G=null),Se||null===We?function(b){return!!L.call(J,b)||!L.call(Z,b)&&(N.test(b)?J[b]=!0:(Z[b]=!0,!1))}(x)&&(null===G?b.removeAttribute(x):b.setAttribute(x,""+G)):We.mustUseProperty?b[We.propertyName]=null===G?3!==We.type&&"":G:(x=We.attributeName,Se=We.attributeNamespace,null===G?b.removeAttribute(x):(G=3===(We=We.type)||4===We&&!0===G?"":""+G,Se?b.setAttributeNS(Se,x,G):b.setAttribute(x,G))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(b){var x=b.replace(se,Ee);H[x]=new ae(x,1,!1,b,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(b){var x=b.replace(se,Ee);H[x]=new ae(x,1,!1,b,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(b){var x=b.replace(se,Ee);H[x]=new ae(x,1,!1,b,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(b){H[b]=new ae(b,1,!1,b.toLowerCase(),null,!1,!1)}),H.xlinkHref=new ae("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(b){H[b]=new ae(b,1,!1,b.toLowerCase(),null,!0,!0)});var he=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,ge=60103,De=60106,ce=60107,lt=60108,Ve=60114,ze=60109,Be=60110,Pe=60112,je=60113,He=60120,Vt=60115,it=60116,tn=60121,It=60128,Zt=60129,Ut=60130,Bt=60131;if("function"==typeof Symbol&&Symbol.for){var bt=Symbol.for;ge=bt("react.element"),De=bt("react.portal"),ce=bt("react.fragment"),lt=bt("react.strict_mode"),Ve=bt("react.profiler"),ze=bt("react.provider"),Be=bt("react.context"),Pe=bt("react.forward_ref"),je=bt("react.suspense"),He=bt("react.suspense_list"),Vt=bt("react.memo"),it=bt("react.lazy"),tn=bt("react.block"),bt("react.scope"),It=bt("react.opaque.id"),Zt=bt("react.debug_trace_mode"),Ut=bt("react.offscreen"),Bt=bt("react.legacy_hidden")}var Xt,Gt="function"==typeof Symbol&&Symbol.iterator;function xt(b){return null===b||"object"!=typeof b?null:"function"==typeof(b=Gt&&b[Gt]||b["@@iterator"])?b:null}function Zn(b){if(void 0===Xt)try{throw Error()}catch(G){var x=G.stack.trim().match(/\n( *(at )?)/);Xt=x&&x[1]||""}return"\n"+Xt+b}var Ur=!1;function di(b,x){if(!b||Ur)return"";Ur=!0;var G=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(x)if(x=function(){throw Error()},Object.defineProperty(x.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(x,[])}catch(yr){var Se=yr}Reflect.construct(b,[],x)}else{try{x.call()}catch(yr){Se=yr}b.call(x.prototype)}else{try{throw Error()}catch(yr){Se=yr}b()}}catch(yr){if(yr&&Se&&"string"==typeof yr.stack){for(var We=yr.stack.split("\n"),Nt=Se.stack.split("\n"),rn=We.length-1,On=Nt.length-1;1<=rn&&0<=On&&We[rn]!==Nt[On];)On--;for(;1<=rn&&0<=On;rn--,On--)if(We[rn]!==Nt[On]){if(1!==rn||1!==On)do{if(rn--,0>--On||We[rn]!==Nt[On])return"\n"+We[rn].replace(" at new "," at ")}while(1<=rn&&0<=On);break}}}finally{Ur=!1,Error.prepareStackTrace=G}return(b=b?b.displayName||b.name:"")?Zn(b):""}function Lr(b){switch(b.tag){case 5:return Zn(b.type);case 16:return Zn("Lazy");case 13:return Zn("Suspense");case 19:return Zn("SuspenseList");case 0:case 2:case 15:return di(b.type,!1);case 11:return di(b.type.render,!1);case 22:return di(b.type._render,!1);case 1:return di(b.type,!0);default:return""}}function Mr(b){if(null==b)return null;if("function"==typeof b)return b.displayName||b.name||null;if("string"==typeof b)return b;switch(b){case ce:return"Fragment";case De:return"Portal";case Ve:return"Profiler";case lt:return"StrictMode";case je:return"Suspense";case He:return"SuspenseList"}if("object"==typeof b)switch(b.$$typeof){case Be:return(b.displayName||"Context")+".Consumer";case ze:return(b._context.displayName||"Context")+".Provider";case Pe:var x=b.render;return x=x.displayName||x.name||"",b.displayName||(""!==x?"ForwardRef("+x+")":"ForwardRef");case Vt:return Mr(b.type);case tn:return Mr(b._render);case it:x=b._payload,b=b._init;try{return Mr(b(x))}catch(G){}}return null}function Kr(b){switch(typeof b){case"boolean":case"number":case"object":case"string":case"undefined":return b;default:return""}}function ei(b){var x=b.type;return(b=b.nodeName)&&"input"===b.toLowerCase()&&("checkbox"===x||"radio"===x)}function $n(b){b._valueTracker||(b._valueTracker=function(b){var x=ei(b)?"checked":"value",G=Object.getOwnPropertyDescriptor(b.constructor.prototype,x),Se=""+b[x];if(!b.hasOwnProperty(x)&&void 0!==G&&"function"==typeof G.get&&"function"==typeof G.set){var We=G.get,Nt=G.set;return Object.defineProperty(b,x,{configurable:!0,get:function(){return We.call(this)},set:function(rn){Se=""+rn,Nt.call(this,rn)}}),Object.defineProperty(b,x,{enumerable:G.enumerable}),{getValue:function(){return Se},setValue:function(rn){Se=""+rn},stopTracking:function(){b._valueTracker=null,delete b[x]}}}}(b))}function Br(b){if(!b)return!1;var x=b._valueTracker;if(!x)return!0;var G=x.getValue(),Se="";return b&&(Se=ei(b)?b.checked?"true":"false":b.value),(b=Se)!==G&&(x.setValue(b),!0)}function Yr(b){if(void 0===(b=b||("undefined"!=typeof document?document:void 0)))return null;try{return b.activeElement||b.body}catch(x){return b.body}}function fi(b,x){var G=x.checked;return u({},x,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=G?G:b._wrapperState.initialChecked})}function ki(b,x){var G=null==x.defaultValue?"":x.defaultValue,Se=null!=x.checked?x.checked:x.defaultChecked;G=Kr(null!=x.value?x.value:G),b._wrapperState={initialChecked:Se,initialValue:G,controlled:"checkbox"===x.type||"radio"===x.type?null!=x.checked:null!=x.value}}function Hi(b,x){null!=(x=x.checked)&&ie(b,"checked",x,!1)}function Zr(b,x){Hi(b,x);var G=Kr(x.value),Se=x.type;if(null!=G)"number"===Se?(0===G&&""===b.value||b.value!=G)&&(b.value=""+G):b.value!==""+G&&(b.value=""+G);else if("submit"===Se||"reset"===Se)return void b.removeAttribute("value");x.hasOwnProperty("value")?Wt(b,x.type,G):x.hasOwnProperty("defaultValue")&&Wt(b,x.type,Kr(x.defaultValue)),null==x.checked&&null!=x.defaultChecked&&(b.defaultChecked=!!x.defaultChecked)}function Cn(b,x,G){if(x.hasOwnProperty("value")||x.hasOwnProperty("defaultValue")){var Se=x.type;if(("submit"===Se||"reset"===Se)&&null==x.value)return;x=""+b._wrapperState.initialValue,G||x===b.value||(b.value=x),b.defaultValue=x}""!==(G=b.name)&&(b.name=""),b.defaultChecked=!!b._wrapperState.initialChecked,""!==G&&(b.name=G)}function Wt(b,x,G){("number"!==x||Yr(b.ownerDocument)!==b)&&(null==G?b.defaultValue=""+b._wrapperState.initialValue:b.defaultValue!==""+G&&(b.defaultValue=""+G))}function rr(b,x){return b=u({children:void 0},x),(x=function(b){var x="";return r.Children.forEach(b,function(G){null!=G&&(x+=G)}),x}(x.children))&&(b.children=x),b}function Fr(b,x,G,Se){if(b=b.options,x){x={};for(var We=0;We<G.length;We++)x["$"+G[We]]=!0;for(G=0;G<b.length;G++)We=x.hasOwnProperty("$"+b[G].value),b[G].selected!==We&&(b[G].selected=We),We&&Se&&(b[G].defaultSelected=!0)}else{for(G=""+Kr(G),x=null,We=0;We<b.length;We++){if(b[We].value===G)return b[We].selected=!0,void(Se&&(b[We].defaultSelected=!0));null!==x||b[We].disabled||(x=b[We])}null!==x&&(x.selected=!0)}}function Gn(b,x){if(null!=x.dangerouslySetInnerHTML)throw Error(d(91));return u({},x,{value:void 0,defaultValue:void 0,children:""+b._wrapperState.initialValue})}function Jr(b,x){var G=x.value;if(null==G){if(G=x.children,x=x.defaultValue,null!=G){if(null!=x)throw Error(d(92));if(Array.isArray(G)){if(!(1>=G.length))throw Error(d(93));G=G[0]}x=G}null==x&&(x=""),G=x}b._wrapperState={initialValue:Kr(G)}}function _i(b,x){var G=Kr(x.value),Se=Kr(x.defaultValue);null!=G&&((G=""+G)!==b.value&&(b.value=G),null==x.defaultValue&&b.defaultValue!==G&&(b.defaultValue=G)),null!=Se&&(b.defaultValue=""+Se)}function wi(b){var x=b.textContent;x===b._wrapperState.initialValue&&""!==x&&null!==x&&(b.value=x)}var br_html="http://www.w3.org/1999/xhtml";function Dr(b){switch(b){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function gn(b,x){return null==b||"http://www.w3.org/1999/xhtml"===b?Dr(x):"http://www.w3.org/2000/svg"===b&&"foreignObject"===x?"http://www.w3.org/1999/xhtml":b}var yn,b,gr=(b=function(b,x){if("http://www.w3.org/2000/svg"!==b.namespaceURI||"innerHTML"in b)b.innerHTML=x;else{for((yn=yn||document.createElement("div")).innerHTML="<svg>"+x.valueOf().toString()+"</svg>",x=yn.firstChild;b.firstChild;)b.removeChild(b.firstChild);for(;x.firstChild;)b.appendChild(x.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(x,G,Se,We){MSApp.execUnsafeLocalFunction(function(){return b(x,G)})}:b);function Jt(b,x){if(x){var G=b.firstChild;if(G&&G===b.lastChild&&3===G.nodeType)return void(G.nodeValue=x)}b.textContent=x}var Vn={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},mr=["Webkit","ms","Moz","O"];function Dn(b,x,G){return null==x||"boolean"==typeof x||""===x?"":G||"number"!=typeof x||0===x||Vn.hasOwnProperty(b)&&Vn[b]?(""+x).trim():x+"px"}function Pr(b,x){for(var G in b=b.style,x)if(x.hasOwnProperty(G)){var Se=0===G.indexOf("--"),We=Dn(G,x[G],Se);"float"===G&&(G="cssFloat"),Se?b.setProperty(G,We):b[G]=We}}Object.keys(Vn).forEach(function(b){mr.forEach(function(x){x=x+b.charAt(0).toUpperCase()+b.substring(1),Vn[x]=Vn[b]})});var Yt=u({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function _n(b,x){if(x){if(Yt[b]&&(null!=x.children||null!=x.dangerouslySetInnerHTML))throw Error(d(137,b));if(null!=x.dangerouslySetInnerHTML){if(null!=x.children)throw Error(d(60));if("object"!=typeof x.dangerouslySetInnerHTML||!("__html"in x.dangerouslySetInnerHTML))throw Error(d(61))}if(null!=x.style&&"object"!=typeof x.style)throw Error(d(62))}}function Ge(b,x){if(-1===b.indexOf("-"))return"string"==typeof x.is;switch(b){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}function kr(b){return(b=b.target||b.srcElement||window).correspondingUseElement&&(b=b.correspondingUseElement),3===b.nodeType?b.parentNode:b}var mi=null,An=null,Er=null;function Wr(b){if(b=Wu(b)){if("function"!=typeof mi)throw Error(d(280));var x=b.stateNode;x&&(x=Xd(x),mi(b.stateNode,b.type,x))}}function dr(b){An?Er?Er.push(b):Er=[b]:An=b}function Fn(){if(An){var b=An,x=Er;if(Er=An=null,Wr(b),x)for(b=0;b<x.length;b++)Wr(x[b])}}function ar(b,x){return b(x)}function Wi(b,x,G,Se,We){return b(x,G,Se,We)}function lo(){}var vo=ar,Co=!1,Gi=!1;function os(){(null!==An||null!==Er)&&(lo(),Fn())}function To(b,x){var G=b.stateNode;if(null===G)return null;var Se=Xd(G);if(null===Se)return null;G=Se[x];e:switch(x){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(Se=!Se.disabled)||(Se=!("button"===(b=b.type)||"input"===b||"select"===b||"textarea"===b)),b=!Se;break e;default:b=!1}if(b)return null;if(G&&"function"!=typeof G)throw Error(d(231,x,typeof G));return G}var Mi=!1;if(A)try{var li={};Object.defineProperty(li,"passive",{get:function(){Mi=!0}}),window.addEventListener("test",li,li),window.removeEventListener("test",li,li)}catch(b){Mi=!1}function Bn(b,x,G,Se,We,Nt,rn,On,yr){var Si=Array.prototype.slice.call(arguments,3);try{x.apply(G,Si)}catch(as){this.onError(as)}}var lr=!1,vr=null,er=!1,ri=null,uo={onError:function(b){lr=!0,vr=b}};function Ci(b,x,G,Se,We,Nt,rn,On,yr){lr=!1,vr=null,Bn.apply(uo,arguments)}function tr(b){var x=b,G=b;if(b.alternate)for(;x.return;)x=x.return;else{b=x;do{0!=(1026&(x=b).flags)&&(G=x.return),b=x.return}while(b)}return 3===x.tag?G:null}function Ar(b){if(13===b.tag){var x=b.memoizedState;if(null===x&&null!==(b=b.alternate)&&(x=b.memoizedState),null!==x)return x.dehydrated}return null}function Rt(b){if(tr(b)!==b)throw Error(d(188))}function mt(b){if(!(b=function(b){var x=b.alternate;if(!x){if(null===(x=tr(b)))throw Error(d(188));return x!==b?null:b}for(var G=b,Se=x;;){var We=G.return;if(null===We)break;var Nt=We.alternate;if(null===Nt){if(null!==(Se=We.return)){G=Se;continue}break}if(We.child===Nt.child){for(Nt=We.child;Nt;){if(Nt===G)return Rt(We),b;if(Nt===Se)return Rt(We),x;Nt=Nt.sibling}throw Error(d(188))}if(G.return!==Se.return)G=We,Se=Nt;else{for(var rn=!1,On=We.child;On;){if(On===G){rn=!0,G=We,Se=Nt;break}if(On===Se){rn=!0,Se=We,G=Nt;break}On=On.sibling}if(!rn){for(On=Nt.child;On;){if(On===G){rn=!0,G=Nt,Se=We;break}if(On===Se){rn=!0,Se=Nt,G=We;break}On=On.sibling}if(!rn)throw Error(d(189))}}if(G.alternate!==Se)throw Error(d(190))}if(3!==G.tag)throw Error(d(188));return G.stateNode.current===G?b:x}(b)))return null;for(var x=b;;){if(5===x.tag||6===x.tag)return x;if(x.child)x.child.return=x,x=x.child;else{if(x===b)break;for(;!x.sibling;){if(!x.return||x.return===b)return null;x=x.return}x.sibling.return=x.return,x=x.sibling}}return null}function jt(b,x){for(var G=b.alternate;null!==x;){if(x===b||x===G)return!0;x=x.return}return!1}var on,si,Vi,_o,co=!1,Es=[],Zs=null,ls=null,La=null,ta=new Map,Is=new Map,us=[],ya="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function el(b,x,G,Se,We){return{blockedOn:b,domEventName:x,eventSystemFlags:16|G,nativeEvent:We,targetContainers:[Se]}}function ca(b,x){switch(b){case"focusin":case"focusout":Zs=null;break;case"dragenter":case"dragleave":ls=null;break;case"mouseover":case"mouseout":La=null;break;case"pointerover":case"pointerout":ta.delete(x.pointerId);break;case"gotpointercapture":case"lostpointercapture":Is.delete(x.pointerId)}}function $s(b,x,G,Se,We,Nt){return null===b||b.nativeEvent!==Nt?(b=el(x,G,Se,We,Nt),null!==x&&null!==(x=Wu(x))&&si(x),b):(b.eventSystemFlags|=Se,x=b.targetContainers,null!==We&&-1===x.indexOf(We)&&x.push(We),b)}function Il(b){var x=Sc(b.target);if(null!==x){var G=tr(x);if(null!==G)if(13===(x=G.tag)){if(null!==(x=Ar(G)))return b.blockedOn=x,void _o(b.lanePriority,function(){p.unstable_runWithPriority(b.priority,function(){Vi(G)})})}else if(3===x&&G.stateNode.hydrate)return void(b.blockedOn=3===G.tag?G.stateNode.containerInfo:null)}b.blockedOn=null}function fo(b){if(null!==b.blockedOn)return!1;for(var x=b.targetContainers;0<x.length;){var G=iu(b.domEventName,b.eventSystemFlags,x[0],b.nativeEvent);if(null!==G)return null!==(x=Wu(G))&&si(x),b.blockedOn=G,!1;x.shift()}return!0}function Ya(b,x,G){fo(b)&&G.delete(x)}function Ao(){for(co=!1;0<Es.length;){var b=Es[0];if(null!==b.blockedOn){null!==(b=Wu(b.blockedOn))&&on(b);break}for(var x=b.targetContainers;0<x.length;){var G=iu(b.domEventName,b.eventSystemFlags,x[0],b.nativeEvent);if(null!==G){b.blockedOn=G;break}x.shift()}null===b.blockedOn&&Es.shift()}null!==Zs&&fo(Zs)&&(Zs=null),null!==ls&&fo(ls)&&(ls=null),null!==La&&fo(La)&&(La=null),ta.forEach(Ya),Is.forEach(Ya)}function fs(b,x){b.blockedOn===x&&(b.blockedOn=null,co||(co=!0,p.unstable_scheduleCallback(p.unstable_NormalPriority,Ao)))}function Ca(b){function x(We){return fs(We,b)}if(0<Es.length){fs(Es[0],b);for(var G=1;G<Es.length;G++){var Se=Es[G];Se.blockedOn===b&&(Se.blockedOn=null)}}for(null!==Zs&&fs(Zs,b),null!==ls&&fs(ls,b),null!==La&&fs(La,b),ta.forEach(x),Is.forEach(x),G=0;G<us.length;G++)(Se=us[G]).blockedOn===b&&(Se.blockedOn=null);for(;0<us.length&&null===(G=us[0]).blockedOn;)Il(G),null===G.blockedOn&&us.shift()}function Ra(b,x){var G={};return G[b.toLowerCase()]=x.toLowerCase(),G["Webkit"+b]="webkit"+x,G["Moz"+b]="moz"+x,G}var pl={animationend:Ra("Animation","AnimationEnd"),animationiteration:Ra("Animation","AnimationIteration"),animationstart:Ra("Animation","AnimationStart"),transitionend:Ra("Transition","TransitionEnd")},Ws={},Po={};function bo(b){if(Ws[b])return Ws[b];if(!pl[b])return b;var G,x=pl[b];for(G in x)if(x.hasOwnProperty(G)&&G in Po)return Ws[b]=x[G];return b}A&&(Po=document.createElement("div").style,"AnimationEvent"in window||(delete pl.animationend.animation,delete pl.animationiteration.animation,delete pl.animationstart.animation),"TransitionEvent"in window||delete pl.transitionend.transition);var Ls=bo("animationend"),ps=bo("animationiteration"),So=bo("animationstart"),$r=bo("transitionend"),to=new Map,tt=new Map,sn=["abort","abort",Ls,"animationEnd",ps,"animationIteration",So,"animationStart","canplay","canPlay","canplaythrough","canPlayThrough","durationchange","durationChange","emptied","emptied","encrypted","encrypted","ended","ended","error","error","gotpointercapture","gotPointerCapture","load","load","loadeddata","loadedData","loadedmetadata","loadedMetadata","loadstart","loadStart","lostpointercapture","lostPointerCapture","playing","playing","progress","progress","seeking","seeking","stalled","stalled","suspend","suspend","timeupdate","timeUpdate",$r,"transitionEnd","waiting","waiting"];function ne(b,x){for(var G=0;G<b.length;G+=2){var Se=b[G],We=b[G+1];We="on"+(We[0].toUpperCase()+We.slice(1)),tt.set(Se,x),to.set(Se,We),y(We,[Se])}}(0,p.unstable_now)();var Lt=8;function an(b){if(0!=(1&b))return Lt=15,1;if(0!=(2&b))return Lt=14,2;if(0!=(4&b))return Lt=13,4;var x=24&b;return 0!==x?(Lt=12,x):0!=(32&b)?(Lt=11,32):0!=(x=192&b)?(Lt=10,x):0!=(256&b)?(Lt=9,256):0!=(x=3584&b)?(Lt=8,x):0!=(4096&b)?(Lt=7,4096):0!=(x=4186112&b)?(Lt=6,x):0!=(x=62914560&b)?(Lt=5,x):67108864&b?(Lt=4,67108864):0!=(134217728&b)?(Lt=3,134217728):0!=(x=805306368&b)?(Lt=2,x):0!=(1073741824&b)?(Lt=1,1073741824):(Lt=8,b)}function xi(b,x){var G=b.pendingLanes;if(0===G)return Lt=0;var Se=0,We=0,Nt=b.expiredLanes,rn=b.suspendedLanes,On=b.pingedLanes;if(0!==Nt)Se=Nt,We=Lt=15;else if(0!=(Nt=134217727&G)){var yr=Nt&~rn;0!==yr?(Se=an(yr),We=Lt):0!=(On&=Nt)&&(Se=an(On),We=Lt)}else 0!=(Nt=G&~rn)?(Se=an(Nt),We=Lt):0!==On&&(Se=an(On),We=Lt);if(0===Se)return 0;if(Se=G&((0>(Se=31-sl(Se))?0:1<<Se)<<1)-1,0!==x&&x!==Se&&0==(x&rn)){if(an(x),We<=Lt)return x;Lt=We}if(0!==(x=b.entangledLanes))for(b=b.entanglements,x&=Se;0<x;)Se|=b[G=31-sl(x)],x&=~(We=1<<G);return Se}function ts(b){return 0!=(b=-1073741825&b.pendingLanes)?b:1073741824&b?1073741824:0}function wo(b,x){switch(b){case 15:return 1;case 14:return 2;case 12:return 0===(b=ko(24&~x))?wo(10,x):b;case 10:return 0===(b=ko(192&~x))?wo(8,x):b;case 8:return 0===(b=ko(3584&~x))&&0===(b=ko(4186112&~x))&&(b=512),b;case 2:return 0===(x=ko(805306368&~x))&&(x=268435456),x}throw Error(d(358,b))}function ko(b){return b&-b}function Eo(b){for(var x=[],G=0;31>G;G++)x.push(b);return x}function ba(b,x,G){b.pendingLanes|=x;var Se=x-1;b.suspendedLanes&=Se,b.pingedLanes&=Se,(b=b.eventTimes)[x=31-sl(x)]=G}var sl=Math.clz32?Math.clz32:function(b){return 0===b?32:31-(tc(b)/Nu|0)|0},tc=Math.log,Nu=Math.LN2,Ec=p.unstable_UserBlockingPriority,qc=p.unstable_runWithPriority,Hl=!0;function Yl(b,x,G,Se){Co||lo();var We=dc,Nt=Co;Co=!0;try{Wi(We,b,x,G,Se)}finally{(Co=Nt)||os()}}function Fs(b,x,G,Se){qc(Ec,dc.bind(null,b,x,G,Se))}function dc(b,x,G,Se){var We;if(Hl)if((We=0==(4&x))&&0<Es.length&&-1<ya.indexOf(b))b=el(null,b,x,G,Se),Es.push(b);else{var Nt=iu(b,x,G,Se);if(null===Nt)We&&ca(b,Se);else{if(We){if(-1<ya.indexOf(b))return b=el(Nt,b,x,G,Se),void Es.push(b);if(function(b,x,G,Se,We){switch(x){case"focusin":return Zs=$s(Zs,b,x,G,Se,We),!0;case"dragenter":return ls=$s(ls,b,x,G,Se,We),!0;case"mouseover":return La=$s(La,b,x,G,Se,We),!0;case"pointerover":var Nt=We.pointerId;return ta.set(Nt,$s(ta.get(Nt)||null,b,x,G,Se,We)),!0;case"gotpointercapture":return Is.set(Nt=We.pointerId,$s(Is.get(Nt)||null,b,x,G,Se,We)),!0}return!1}(Nt,b,x,G,Se))return;ca(b,Se)}Ce(b,x,Se,null,G)}}}function iu(b,x,G,Se){var We=kr(Se);if(null!==(We=Sc(We))){var Nt=tr(We);if(null===Nt)We=null;else{var rn=Nt.tag;if(13===rn){if(null!==(We=Ar(Nt)))return We;We=null}else if(3===rn){if(Nt.stateNode.hydrate)return 3===Nt.tag?Nt.stateNode.containerInfo:null;We=null}else Nt!==We&&(We=null)}}return Ce(b,x,Se,We,G),null}var tl=null,Su=null,Zl=null;function rt(){if(Zl)return Zl;var b,Se,x=Su,G=x.length,We="value"in tl?tl.value:tl.textContent,Nt=We.length;for(b=0;b<G&&x[b]===We[b];b++);var rn=G-b;for(Se=1;Se<=rn&&x[G-Se]===We[Nt-Se];Se++);return Zl=We.slice(b,1<Se?1-Se:void 0)}function Pt(b){var x=b.keyCode;return"charCode"in b?0===(b=b.charCode)&&13===x&&(b=13):b=x,10===b&&(b=13),32<=b||13===b?b:0}function dt(){return!0}function Te(){return!1}function Me(b){function x(G,Se,We,Nt,rn){for(var On in this._reactName=G,this._targetInst=We,this.type=Se,this.nativeEvent=Nt,this.target=rn,this.currentTarget=null,b)b.hasOwnProperty(On)&&(this[On]=(G=b[On])?G(Nt):Nt[On]);return this.isDefaultPrevented=(null!=Nt.defaultPrevented?Nt.defaultPrevented:!1===Nt.returnValue)?dt:Te,this.isPropagationStopped=Te,this}return u(x.prototype,{preventDefault:function(){this.defaultPrevented=!0;var G=this.nativeEvent;G&&(G.preventDefault?G.preventDefault():"unknown"!=typeof G.returnValue&&(G.returnValue=!1),this.isDefaultPrevented=dt)},stopPropagation:function(){var G=this.nativeEvent;G&&(G.stopPropagation?G.stopPropagation():"unknown"!=typeof G.cancelBubble&&(G.cancelBubble=!0),this.isPropagationStopped=dt)},persist:function(){},isPersistent:dt}),x}var Go,ms,hs,xe={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(b){return b.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},Ct=Me(xe),ur=u({},xe,{view:0,detail:0}),Qi=Me(ur),Ts=u({},ur,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:sa,button:0,buttons:0,relatedTarget:function(b){return void 0===b.relatedTarget?b.fromElement===b.srcElement?b.toElement:b.fromElement:b.relatedTarget},movementX:function(b){return"movementX"in b?b.movementX:(b!==hs&&(hs&&"mousemove"===b.type?(Go=b.screenX-hs.screenX,ms=b.screenY-hs.screenY):ms=Go=0,hs=b),Go)},movementY:function(b){return"movementY"in b?b.movementY:ms}}),Ma=Me(Ts),Wa=Me(u({},Ts,{dataTransfer:0})),nc=Me(u({},ur,{relatedTarget:0})),vs=Me(u({},xe,{animationName:0,elapsedTime:0,pseudoElement:0})),Tc=Me(u({},xe,{clipboardData:function(b){return"clipboardData"in b?b.clipboardData:window.clipboardData}})),Cu=Me(u({},xe,{data:0})),kc={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},gd={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},rc={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Li(b){var x=this.nativeEvent;return x.getModifierState?x.getModifierState(b):!!(b=rc[b])&&!!x[b]}function sa(){return Li}var Ss=Me(u({},ur,{key:function(b){if(b.key){var x=kc[b.key]||b.key;if("Unidentified"!==x)return x}return"keypress"===b.type?13===(b=Pt(b))?"Enter":String.fromCharCode(b):"keydown"===b.type||"keyup"===b.type?gd[b.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:sa,charCode:function(b){return"keypress"===b.type?Pt(b):0},keyCode:function(b){return"keydown"===b.type||"keyup"===b.type?b.keyCode:0},which:function(b){return"keypress"===b.type?Pt(b):"keydown"===b.type||"keyup"===b.type?b.keyCode:0}})),yl=Me(u({},Ts,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),yu=Me(u({},ur,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:sa})),js=Me(u({},xe,{propertyName:0,elapsedTime:0,pseudoElement:0})),Uu=Me(u({},Ts,{deltaX:function(b){return"deltaX"in b?b.deltaX:"wheelDeltaX"in b?-b.wheelDeltaX:0},deltaY:function(b){return"deltaY"in b?b.deltaY:"wheelDeltaY"in b?-b.wheelDeltaY:"wheelDelta"in b?-b.wheelDelta:0},deltaZ:0,deltaMode:0})),Bo=[9,13,27,32],uu=A&&"CompositionEvent"in window,wr=null;A&&"documentMode"in document&&(wr=document.documentMode);var fa=A&&"TextEvent"in window&&!wr,pu=A&&(!uu||wr&&8<wr&&11>=wr),aa=String.fromCharCode(32),jl=!1;function bl(b,x){switch(b){case"keyup":return-1!==Bo.indexOf(x.keyCode);case"keydown":return 229!==x.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function El(b){return"object"==typeof(b=b.detail)&&"data"in b?b.data:null}var Ul=!1,Ae={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function st(b){var x=b&&b.nodeName&&b.nodeName.toLowerCase();return"input"===x?!!Ae[b.type]:"textarea"===x}function vt(b,x,G,Se){dr(Se),0<(x=Et(x,"onChange")).length&&(G=new Ct("onChange","change",null,G,Se),b.push({event:G,listeners:x}))}var ut=null,un=null;function mn(b){df(b,0)}function Or(b){if(Br(Cc(b)))return b}function zr(b,x){if("change"===b)return x}var gi=!1;if(A){var ai;if(A){var Io="oninput"in document;if(!Io){var Fo=document.createElement("div");Fo.setAttribute("oninput","return;"),Io="function"==typeof Fo.oninput}ai=Io}else ai=!1;gi=ai&&(!document.documentMode||9<document.documentMode)}function In(){ut&&(ut.detachEvent("onpropertychange",Cr),un=ut=null)}function Cr(b){if("value"===b.propertyName&&Or(un)){var x=[];if(vt(x,un,b,kr(b)),b=mn,Co)b(x);else{Co=!0;try{ar(b,x)}finally{Co=!1,os()}}}}function hr(b,x,G){"focusin"===b?(In(),un=G,(ut=x).attachEvent("onpropertychange",Cr)):"focusout"===b&&In()}function ao(b){if("selectionchange"===b||"keyup"===b||"keydown"===b)return Or(un)}function ys(b,x){if("click"===b)return Or(x)}function Na(b,x){if("input"===b||"change"===b)return Or(x)}var Qs="function"==typeof Object.is?Object.is:function(b,x){return b===x&&(0!==b||1/b==1/x)||b!=b&&x!=x},ed=Object.prototype.hasOwnProperty;function $c(b,x){if(Qs(b,x))return!0;if("object"!=typeof b||null===b||"object"!=typeof x||null===x)return!1;var G=Object.keys(b),Se=Object.keys(x);if(G.length!==Se.length)return!1;for(Se=0;Se<G.length;Se++)if(!ed.call(x,G[Se])||!Qs(b[G[Se]],x[G[Se]]))return!1;return!0}function Gl(b){for(;b&&b.firstChild;)b=b.firstChild;return b}function $i(b,x){var Se,G=Gl(b);for(b=0;G;){if(3===G.nodeType){if(Se=b+G.textContent.length,b<=x&&Se>=x)return{node:G,offset:x-b};b=Se}e:{for(;G;){if(G.nextSibling){G=G.nextSibling;break e}G=G.parentNode}G=void 0}G=Gl(G)}}function xo(b,x){return!(!b||!x)&&(b===x||(!b||3!==b.nodeType)&&(x&&3===x.nodeType?xo(b,x.parentNode):"contains"in b?b.contains(x):!!b.compareDocumentPosition&&!!(16&b.compareDocumentPosition(x))))}function pa(){for(var b=window,x=Yr();x instanceof b.HTMLIFrameElement;){try{var G="string"==typeof x.contentWindow.location.href}catch(Se){G=!1}if(!G)break;x=Yr((b=x.contentWindow).document)}return x}function hl(b){var x=b&&b.nodeName&&b.nodeName.toLowerCase();return x&&("input"===x&&("text"===b.type||"search"===b.type||"tel"===b.type||"url"===b.type||"password"===b.type)||"textarea"===x||"true"===b.contentEditable)}var Bl=A&&"documentMode"in document&&11>=document.documentMode,Js=null,md=null,Mn=null,Nl=!1;function td(b,x,G){var Se=G.window===G?G.document:9===G.nodeType?G:G.ownerDocument;Nl||null==Js||Js!==Yr(Se)||(Se="selectionStart"in(Se=Js)&&hl(Se)?{start:Se.selectionStart,end:Se.selectionEnd}:{anchorNode:(Se=(Se.ownerDocument&&Se.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:Se.anchorOffset,focusNode:Se.focusNode,focusOffset:Se.focusOffset},Mn&&$c(Mn,Se)||(Mn=Se,0<(Se=Et(md,"onSelect")).length&&(x=new Ct("onSelect","select",null,x,G),b.push({event:x,listeners:Se}),x.target=Js)))}ne("cancel cancel click click close close contextmenu contextMenu copy copy cut cut auxclick auxClick dblclick doubleClick dragend dragEnd dragstart dragStart drop drop focusin focus focusout blur input input invalid invalid keydown keyDown keypress keyPress keyup keyUp mousedown mouseDown mouseup mouseUp paste paste pause pause play play pointercancel pointerCancel pointerdown pointerDown pointerup pointerUp ratechange rateChange reset reset seeked seeked submit submit touchcancel touchCancel touchend touchEnd touchstart touchStart volumechange volumeChange".split(" "),0),ne("drag drag dragenter dragEnter dragexit dragExit dragleave dragLeave dragover dragOver mousemove mouseMove mouseout mouseOut mouseover mouseOver pointermove pointerMove pointerout pointerOut pointerover pointerOver scroll scroll toggle toggle touchmove touchMove wheel wheel".split(" "),1),ne(sn,2);for(var zd="change selectionchange textInput compositionstart compositionend compositionupdate".split(" "),ss=0;ss<zd.length;ss++)tt.set(zd[ss],0);S("onMouseEnter",["mouseout","mouseover"]),S("onMouseLeave",["mouseout","mouseover"]),S("onPointerEnter",["pointerout","pointerover"]),S("onPointerLeave",["pointerout","pointerover"]),y("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),y("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),y("onBeforeInput",["compositionend","keypress","textInput","paste"]),y("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),y("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),y("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var la="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Zc=new Set("cancel close invalid load scroll toggle".split(" ").concat(la));function ic(b,x,G){var Se=b.type||"unknown-event";b.currentTarget=G,function(b,x,G,Se,We,Nt,rn,On,yr){if(Ci.apply(this,arguments),lr){if(!lr)throw Error(d(198));var Si=vr;lr=!1,vr=null,er||(er=!0,ri=Si)}}(Se,x,void 0,b),b.currentTarget=null}function df(b,x){x=0!=(4&x);for(var G=0;G<b.length;G++){var Se=b[G],We=Se.event;Se=Se.listeners;e:{var Nt=void 0;if(x)for(var rn=Se.length-1;0<=rn;rn--){var On=Se[rn],yr=On.instance,Si=On.currentTarget;if(On=On.listener,yr!==Nt&&We.isPropagationStopped())break e;ic(We,On,Si),Nt=yr}else for(rn=0;rn<Se.length;rn++){if(yr=(On=Se[rn]).instance,Si=On.currentTarget,On=On.listener,yr!==Nt&&We.isPropagationStopped())break e;ic(We,On,Si),Nt=yr}}}if(er)throw b=ri,er=!1,ri=null,b}function al(b,x){var G=jc(x),Se=b+"__bubble";G.has(Se)||(Ie(x,b,2,!1),G.add(Se))}var Wd="_reactListening"+Math.random().toString(36).slice(2);function Jd(b){b[Wd]||(b[Wd]=!0,e.forEach(function(x){Zc.has(x)||Ye(x,!1,b,null),Ye(x,!0,b,null)}))}function Ye(b,x,G,Se){var We=4<arguments.length&&void 0!==arguments[4]?arguments[4]:0,Nt=G;if("selectionchange"===b&&9!==G.nodeType&&(Nt=G.ownerDocument),null!==Se&&!x&&Zc.has(b)){if("scroll"!==b)return;We|=2,Nt=Se}var rn=jc(Nt),On=b+"__"+(x?"capture":"bubble");rn.has(On)||(x&&(We|=4),Ie(Nt,b,We,x),rn.add(On))}function Ie(b,x,G,Se){var We=tt.get(x);switch(void 0===We?2:We){case 0:We=Yl;break;case 1:We=Fs;break;default:We=dc}G=We.bind(null,x,G,b),We=void 0,!Mi||"touchstart"!==x&&"touchmove"!==x&&"wheel"!==x||(We=!0),b.addEventListener(x,G,Se?void 0===We||{capture:!0,passive:We}:void 0!==We&&{passive:We})}function Ce(b,x,G,Se,We){var Nt=Se;if(0==(1&x)&&0==(2&x)&&null!==Se)e:for(;;){if(null===Se)return;var rn=Se.tag;if(3===rn||4===rn){var On=Se.stateNode.containerInfo;if(On===We||8===On.nodeType&&On.parentNode===We)break;if(4===rn)for(rn=Se.return;null!==rn;){var yr=rn.tag;if((3===yr||4===yr)&&((yr=rn.stateNode.containerInfo)===We||8===yr.nodeType&&yr.parentNode===We))return;rn=rn.return}for(;null!==On;){if(null===(rn=Sc(On)))return;if(5===(yr=rn.tag)||6===yr){Se=Nt=rn;continue e}On=On.parentNode}}Se=Se.return}!function(b,x,G){if(Gi)return b();Gi=!0;try{vo(b,x,G)}finally{Gi=!1,os()}}(function(){var Si=Nt,as=kr(G),Ha=[];e:{var go=to.get(b);if(void 0!==go){var po=Ct,Fa=b;switch(b){case"keypress":if(0===Pt(G))break e;case"keydown":case"keyup":po=Ss;break;case"focusin":Fa="focus",po=nc;break;case"focusout":Fa="blur",po=nc;break;case"beforeblur":case"afterblur":po=nc;break;case"click":if(2===G.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":po=Ma;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":po=Wa;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":po=yu;break;case Ls:case ps:case So:po=vs;break;case $r:po=js;break;case"scroll":po=Qi;break;case"wheel":po=Uu;break;case"copy":case"cut":case"paste":po=Tc;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":po=yl}var Ta=0!=(4&x),ni=!Ta&&"scroll"===b,Tr=Ta?null!==go?go+"Capture":null:go;Ta=[];for(var Bi,Qr=Si;null!==Qr;){var io=(Bi=Qr).stateNode;if(5===Bi.tag&&null!==io&&(Bi=io,null!==Tr&&null!=(io=To(Qr,Tr))&&Ta.push(ot(Qr,io,Bi))),ni)break;Qr=Qr.return}0<Ta.length&&(go=new po(go,Fa,null,G,as),Ha.push({event:go,listeners:Ta}))}}if(0==(7&x)){if(po="mouseout"===b||"pointerout"===b,(!(go="mouseover"===b||"pointerover"===b)||0!=(16&x)||!(Fa=G.relatedTarget||G.fromElement)||!Sc(Fa)&&!Fa[Rd])&&(po||go)&&(go=as.window===as?as:(go=as.ownerDocument)?go.defaultView||go.parentWindow:window,po?(po=Si,null!==(Fa=(Fa=G.relatedTarget||G.toElement)?Sc(Fa):null)&&(Fa!==(ni=tr(Fa))||5!==Fa.tag&&6!==Fa.tag)&&(Fa=null)):(po=null,Fa=Si),po!==Fa)){if(Ta=Ma,io="onMouseLeave",Tr="onMouseEnter",Qr="mouse",("pointerout"===b||"pointerover"===b)&&(Ta=yl,io="onPointerLeave",Tr="onPointerEnter",Qr="pointer"),ni=null==po?go:Cc(po),Bi=null==Fa?go:Cc(Fa),(go=new Ta(io,Qr+"leave",po,G,as)).target=ni,go.relatedTarget=Bi,io=null,Sc(as)===Si&&((Ta=new Ta(Tr,Qr+"enter",Fa,G,as)).target=Bi,Ta.relatedTarget=ni,io=Ta),ni=io,po&&Fa)t:{for(Tr=Fa,Qr=0,Bi=Ta=po;Bi;Bi=qt(Bi))Qr++;for(Bi=0,io=Tr;io;io=qt(io))Bi++;for(;0<Qr-Bi;)Ta=qt(Ta),Qr--;for(;0<Bi-Qr;)Tr=qt(Tr),Bi--;for(;Qr--;){if(Ta===Tr||null!==Tr&&Ta===Tr.alternate)break t;Ta=qt(Ta),Tr=qt(Tr)}Ta=null}else Ta=null;null!==po&&Hn(Ha,go,po,Ta,!1),null!==Fa&&null!==ni&&Hn(Ha,ni,Fa,Ta,!0)}if("select"===(po=(go=Si?Cc(Si):window).nodeName&&go.nodeName.toLowerCase())||"input"===po&&"file"===go.type)var va=zr;else if(st(go))if(gi)va=Na;else{va=ao;var Cs=hr}else(po=go.nodeName)&&"input"===po.toLowerCase()&&("checkbox"===go.type||"radio"===go.type)&&(va=ys);switch(va&&(va=va(b,Si))?vt(Ha,va,G,as):(Cs&&Cs(b,go,Si),"focusout"===b&&(Cs=go._wrapperState)&&Cs.controlled&&"number"===go.type&&Wt(go,"number",go.value)),Cs=Si?Cc(Si):window,b){case"focusin":(st(Cs)||"true"===Cs.contentEditable)&&(Js=Cs,md=Si,Mn=null);break;case"focusout":Mn=md=Js=null;break;case"mousedown":Nl=!0;break;case"contextmenu":case"mouseup":case"dragend":Nl=!1,td(Ha,G,as);break;case"selectionchange":if(Bl)break;case"keydown":case"keyup":td(Ha,G,as)}var Qa;if(uu)e:{switch(b){case"compositionstart":var xl="onCompositionStart";break e;case"compositionend":xl="onCompositionEnd";break e;case"compositionupdate":xl="onCompositionUpdate";break e}xl=void 0}else Ul?bl(b,G)&&(xl="onCompositionEnd"):"keydown"===b&&229===G.keyCode&&(xl="onCompositionStart");xl&&(pu&&"ko"!==G.locale&&(Ul||"onCompositionStart"!==xl?"onCompositionEnd"===xl&&Ul&&(Qa=rt()):(Su="value"in(tl=as)?tl.value:tl.textContent,Ul=!0)),0<(Cs=Et(Si,xl)).length&&(xl=new Cu(xl,b,null,G,as),Ha.push({event:xl,listeners:Cs}),(Qa||null!==(Qa=El(G)))&&(xl.data=Qa))),(Qa=fa?function(b,x){switch(b){case"compositionend":return El(x);case"keypress":return 32!==x.which?null:(jl=!0,aa);case"textInput":return(b=x.data)===aa&&jl?null:b;default:return null}}(b,G):function(b,x){if(Ul)return"compositionend"===b||!uu&&bl(b,x)?(b=rt(),Zl=Su=tl=null,Ul=!1,b):null;switch(b){case"paste":return null;case"keypress":if(!(x.ctrlKey||x.altKey||x.metaKey)||x.ctrlKey&&x.altKey){if(x.char&&1<x.char.length)return x.char;if(x.which)return String.fromCharCode(x.which)}return null;case"compositionend":return pu&&"ko"!==x.locale?null:x.data;default:return null}}(b,G))&&0<(Si=Et(Si,"onBeforeInput")).length&&(as=new Cu("onBeforeInput","beforeinput",null,G,as),Ha.push({event:as,listeners:Si}),as.data=Qa)}df(Ha,x)})}function ot(b,x,G){return{instance:b,listener:x,currentTarget:G}}function Et(b,x){for(var G=x+"Capture",Se=[];null!==b;){var We=b,Nt=We.stateNode;5===We.tag&&null!==Nt&&(We=Nt,null!=(Nt=To(b,G))&&Se.unshift(ot(b,Nt,We)),null!=(Nt=To(b,x))&&Se.push(ot(b,Nt,We))),b=b.return}return Se}function qt(b){if(null===b)return null;do{b=b.return}while(b&&5!==b.tag);return b||null}function Hn(b,x,G,Se,We){for(var Nt=x._reactName,rn=[];null!==G&&G!==Se;){var On=G,yr=On.alternate,Si=On.stateNode;if(null!==yr&&yr===Se)break;5===On.tag&&null!==Si&&(On=Si,We?null!=(yr=To(G,Nt))&&rn.unshift(ot(G,yr,On)):We||null!=(yr=To(G,Nt))&&rn.push(ot(G,yr,On))),G=G.return}0!==rn.length&&b.push({event:x,listeners:rn})}function Xn(){}var Ei=null,Yo=null;function $a(b,x){switch(b){case"button":case"input":case"select":case"textarea":return!!x.autoFocus}return!1}function ns(b,x){return"textarea"===b||"option"===b||"noscript"===b||"string"==typeof x.children||"number"==typeof x.children||"object"==typeof x.dangerouslySetInnerHTML&&null!==x.dangerouslySetInnerHTML&&null!=x.dangerouslySetInnerHTML.__html}var Oa="function"==typeof setTimeout?setTimeout:void 0,Hs="function"==typeof clearTimeout?clearTimeout:void 0;function fc(b){(1===b.nodeType||9===b.nodeType&&null!=(b=b.body))&&(b.textContent="")}function ga(b){for(;null!=b;b=b.nextSibling){var x=b.nodeType;if(1===x||3===x)break}return b}function Ol(b){b=b.previousSibling;for(var x=0;b;){if(8===b.nodeType){var G=b.data;if("$"===G||"$!"===G||"$?"===G){if(0===x)return b;x--}else"/$"===G&&x++}b=b.previousSibling}return null}var ll=0,ja=Math.random().toString(36).slice(2),ul="__reactFiber$"+ja,Of="__reactProps$"+ja,Rd="__reactContainer$"+ja,Qd="__reactEvents$"+ja;function Sc(b){var x=b[ul];if(x)return x;for(var G=b.parentNode;G;){if(x=G[Rd]||G[ul]){if(G=x.alternate,null!==x.child||null!==G&&null!==G.child)for(b=Ol(b);null!==b;){if(G=b[ul])return G;b=Ol(b)}return x}G=(b=G).parentNode}return null}function Wu(b){return!(b=b[ul]||b[Rd])||5!==b.tag&&6!==b.tag&&13!==b.tag&&3!==b.tag?null:b}function Cc(b){if(5===b.tag||6===b.tag)return b.stateNode;throw Error(d(33))}function Xd(b){return b[Of]||null}function jc(b){var x=b[Qd];return void 0===x&&(x=b[Qd]=new Set),x}var $f=[],Ju=-1;function Sl(b){return{current:b}}function wl(b){0>Ju||(b.current=$f[Ju],$f[Ju]=null,Ju--)}function kl(b,x){Ju++,$f[Ju]=b.current,b.current=x}var Pu={},Ja=Sl(Pu),Qu=Sl(!1),en=Pu;function Oc(b,x){var G=b.type.contextTypes;if(!G)return Pu;var Se=b.stateNode;if(Se&&Se.__reactInternalMemoizedUnmaskedChildContext===x)return Se.__reactInternalMemoizedMaskedChildContext;var Nt,We={};for(Nt in G)We[Nt]=x[Nt];return Se&&((b=b.stateNode).__reactInternalMemoizedUnmaskedChildContext=x,b.__reactInternalMemoizedMaskedChildContext=We),We}function Au(b){return null!=b.childContextTypes}function Iu(){wl(Qu),wl(Ja)}function nl(b,x,G){if(Ja.current!==Pu)throw Error(d(168));kl(Ja,x),kl(Qu,G)}function ff(b,x,G){var Se=b.stateNode;if(b=x.childContextTypes,"function"!=typeof Se.getChildContext)return G;for(var We in Se=Se.getChildContext())if(!(We in b))throw Error(d(108,Mr(x)||"Unknown",We));return u({},G,Se)}function Jl(b){return b=(b=b.stateNode)&&b.__reactInternalMemoizedMergedChildContext||Pu,en=Ja.current,kl(Ja,b),kl(Qu,Qu.current),!0}function vd(b,x,G){var Se=b.stateNode;if(!Se)throw Error(d(169));G?(b=ff(b,x,en),Se.__reactInternalMemoizedMergedChildContext=b,wl(Qu),wl(Ja),kl(Ja,b)):wl(Qu),kl(Qu,G)}var wc=null,Gc=null,pf=p.unstable_runWithPriority,xc=p.unstable_scheduleCallback,hf=p.unstable_cancelCallback,Vc=p.unstable_shouldYield,hu=p.unstable_requestPaint,yd=p.unstable_now,$p=p.unstable_getCurrentPriorityLevel,fp=p.unstable_ImmediatePriority,_f=p.unstable_UserBlockingPriority,Dh=p.unstable_NormalPriority,Ql=p.unstable_LowPriority,Hf=p.unstable_IdlePriority,Bu={},Kf=void 0!==hu?hu:function(){},Nd=null,Dc=null,Xl=!1,Ji=yd(),cl=1e4>Ji?yd:function(){return yd()-Ji};function Ll(){switch($p()){case fp:return 99;case _f:return 98;case Dh:return 97;case Ql:return 96;case Hf:return 95;default:throw Error(d(332))}}function Pd(b){switch(b){case 99:return fp;case 98:return _f;case 97:return Dh;case 96:return Ql;case 95:return Hf;default:throw Error(d(332))}}function rl(b,x){return b=Pd(b),pf(b,x)}function Yu(b,x,G){return b=Pd(b),xc(b,x,G)}function pc(){if(null!==Dc){var b=Dc;Dc=null,hf(b)}Kd()}function Kd(){if(!Xl&&null!==Nd){Xl=!0;var b=0;try{var x=Nd;rl(99,function(){for(;b<x.length;b++){var G=x[b];do{G=G(!0)}while(null!==G)}}),Nd=null}catch(G){throw null!==Nd&&(Nd=Nd.slice(b+1)),xc(fp,pc),G}finally{Xl=!1}}}var wf=he.ReactCurrentBatchConfig;function Vl(b,x){if(b&&b.defaultProps){for(var G in x=u({},x),b=b.defaultProps)void 0===x[G]&&(x[G]=b[G]);return x}return x}var Id=Sl(null),oc=null,hc=null,_u=null;function Mc(){_u=hc=oc=null}function Hc(b){var x=Id.current;wl(Id),b.type._context._currentValue=x}function cu(b,x){for(;null!==b;){var G=b.alternate;if((b.childLanes&x)===x){if(null===G||(G.childLanes&x)===x)break;G.childLanes|=x}else b.childLanes|=x,null!==G&&(G.childLanes|=x);b=b.return}}function Lu(b,x){oc=b,_u=hc=null,null!==(b=b.dependencies)&&null!==b.firstContext&&(0!=(b.lanes&x)&&(qd=!0),b.firstContext=null)}function Ou(b,x){if(_u!==b&&!1!==x&&0!==x)if(("number"!=typeof x||1073741823===x)&&(_u=b,x=1073741823),x={context:b,observedBits:x,next:null},null===hc){if(null===oc)throw Error(d(308));hc=x,oc.dependencies={lanes:0,firstContext:x,responders:null}}else hc=hc.next=x;return b._currentValue}var Rc=!1;function bu(b){b.updateQueue={baseState:b.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null},effects:null}}function h(b,x){x.updateQueue===(b=b.updateQueue)&&(x.updateQueue={baseState:b.baseState,firstBaseUpdate:b.firstBaseUpdate,lastBaseUpdate:b.lastBaseUpdate,shared:b.shared,effects:b.effects})}function E(b,x){return{eventTime:b,lane:x,tag:0,payload:null,callback:null,next:null}}function R(b,x){if(null!==(b=b.updateQueue)){var G=(b=b.shared).pending;null===G?x.next=x:(x.next=G.next,G.next=x),b.pending=x}}function F(b,x){var G=b.updateQueue,Se=b.alternate;if(null===Se||G!==(Se=Se.updateQueue))null===(b=G.lastBaseUpdate)?G.firstBaseUpdate=x:b.next=x,G.lastBaseUpdate=x;else{var We=null,Nt=null;if(null!==(G=G.firstBaseUpdate)){do{var rn={eventTime:G.eventTime,lane:G.lane,tag:G.tag,payload:G.payload,callback:G.callback,next:null};null===Nt?We=Nt=rn:Nt=Nt.next=rn,G=G.next}while(null!==G);null===Nt?We=Nt=x:Nt=Nt.next=x}else We=Nt=x;b.updateQueue=G={baseState:Se.baseState,firstBaseUpdate:We,lastBaseUpdate:Nt,shared:Se.shared,effects:Se.effects}}}function q(b,x,G,Se){var We=b.updateQueue;Rc=!1;var Nt=We.firstBaseUpdate,rn=We.lastBaseUpdate,On=We.shared.pending;if(null!==On){We.shared.pending=null;var yr=On,Si=yr.next;yr.next=null,null===rn?Nt=Si:rn.next=Si,rn=yr;var as=b.alternate;if(null!==as){var Ha=(as=as.updateQueue).lastBaseUpdate;Ha!==rn&&(null===Ha?as.firstBaseUpdate=Si:Ha.next=Si,as.lastBaseUpdate=yr)}}if(null!==Nt){for(Ha=We.baseState,rn=0,as=Si=yr=null;;){var go=Nt.eventTime;if((Se&(On=Nt.lane))===On){null!==as&&(as=as.next={eventTime:go,lane:0,tag:Nt.tag,payload:Nt.payload,callback:Nt.callback,next:null});e:{var po=b,Fa=Nt;switch(On=x,go=G,Fa.tag){case 1:if("function"==typeof(po=Fa.payload)){Ha=po.call(go,Ha,On);break e}Ha=po;break e;case 3:po.flags=-4097&po.flags|64;case 0:if(null==(On="function"==typeof(po=Fa.payload)?po.call(go,Ha,On):po))break e;Ha=u({},Ha,On);break e;case 2:Rc=!0}}null!==Nt.callback&&(b.flags|=32,null===(On=We.effects)?We.effects=[Nt]:On.push(Nt))}else go={eventTime:go,lane:On,tag:Nt.tag,payload:Nt.payload,callback:Nt.callback,next:null},null===as?(Si=as=go,yr=Ha):as=as.next=go,rn|=On;if(null===(Nt=Nt.next)){if(null===(On=We.shared.pending))break;Nt=On.next,On.next=null,We.lastBaseUpdate=On,We.shared.pending=null}}null===as&&(yr=Ha),We.baseState=yr,We.firstBaseUpdate=Si,We.lastBaseUpdate=as,Gf|=rn,b.lanes=rn,b.memoizedState=Ha}}function de(b,x,G){if(b=x.effects,x.effects=null,null!==b)for(x=0;x<b.length;x++){var Se=b[x],We=Se.callback;if(null!==We){if(Se.callback=null,Se=G,"function"!=typeof We)throw Error(d(191,We));We.call(Se)}}}var ye=(new r.Component).refs;function Ue(b,x,G,Se){G=null==(G=G(Se,x=b.memoizedState))?x:u({},x,G),b.memoizedState=G,0===b.lanes&&(b.updateQueue.baseState=G)}var Oe={isMounted:function(b){return!!(b=b._reactInternals)&&tr(b)===b},enqueueSetState:function(b,x,G){b=b._reactInternals;var Se=fd(),We=bf(b),Nt=E(Se,We);Nt.payload=x,null!=G&&(Nt.callback=G),R(b,Nt),zf(b,We,Se)},enqueueReplaceState:function(b,x,G){b=b._reactInternals;var Se=fd(),We=bf(b),Nt=E(Se,We);Nt.tag=1,Nt.payload=x,null!=G&&(Nt.callback=G),R(b,Nt),zf(b,We,Se)},enqueueForceUpdate:function(b,x){b=b._reactInternals;var G=fd(),Se=bf(b),We=E(G,Se);We.tag=2,null!=x&&(We.callback=x),R(b,We),zf(b,Se,G)}};function Xe(b,x,G,Se,We,Nt,rn){return"function"==typeof(b=b.stateNode).shouldComponentUpdate?b.shouldComponentUpdate(Se,Nt,rn):!(x.prototype&&x.prototype.isPureReactComponent&&$c(G,Se)&&$c(We,Nt))}function gt(b,x,G){var Se=!1,We=Pu,Nt=x.contextType;return"object"==typeof Nt&&null!==Nt?Nt=Ou(Nt):(We=Au(x)?en:Ja.current,Nt=(Se=null!=(Se=x.contextTypes))?Oc(b,We):Pu),x=new x(G,Nt),b.memoizedState=null!=x.state?x.state:null,x.updater=Oe,b.stateNode=x,x._reactInternals=b,Se&&((b=b.stateNode).__reactInternalMemoizedUnmaskedChildContext=We,b.__reactInternalMemoizedMaskedChildContext=Nt),x}function yt(b,x,G,Se){b=x.state,"function"==typeof x.componentWillReceiveProps&&x.componentWillReceiveProps(G,Se),"function"==typeof x.UNSAFE_componentWillReceiveProps&&x.UNSAFE_componentWillReceiveProps(G,Se),x.state!==b&&Oe.enqueueReplaceState(x,x.state,null)}function nn(b,x,G,Se){var We=b.stateNode;We.props=G,We.state=b.memoizedState,We.refs=ye,bu(b);var Nt=x.contextType;"object"==typeof Nt&&null!==Nt?We.context=Ou(Nt):(Nt=Au(x)?en:Ja.current,We.context=Oc(b,Nt)),q(b,G,We,Se),We.state=b.memoizedState,"function"==typeof(Nt=x.getDerivedStateFromProps)&&(Ue(b,x,Nt,G),We.state=b.memoizedState),"function"==typeof x.getDerivedStateFromProps||"function"==typeof We.getSnapshotBeforeUpdate||"function"!=typeof We.UNSAFE_componentWillMount&&"function"!=typeof We.componentWillMount||(x=We.state,"function"==typeof We.componentWillMount&&We.componentWillMount(),"function"==typeof We.UNSAFE_componentWillMount&&We.UNSAFE_componentWillMount(),x!==We.state&&Oe.enqueueReplaceState(We,We.state,null),q(b,G,We,Se),We.state=b.memoizedState),"function"==typeof We.componentDidMount&&(b.flags|=4)}var Pn=Array.isArray;function xn(b,x,G){if(null!==(b=G.ref)&&"function"!=typeof b&&"object"!=typeof b){if(G._owner){if(G=G._owner){if(1!==G.tag)throw Error(d(309));var Se=G.stateNode}if(!Se)throw Error(d(147,b));var We=""+b;return null!==x&&null!==x.ref&&"function"==typeof x.ref&&x.ref._stringRef===We?x.ref:((x=function(Nt){var rn=Se.refs;rn===ye&&(rn=Se.refs={}),null===Nt?delete rn[We]:rn[We]=Nt})._stringRef=We,x)}if("string"!=typeof b)throw Error(d(284));if(!G._owner)throw Error(d(290,b))}return b}function ir(b,x){if("textarea"!==b.type)throw Error(d(31,"[object Object]"===Object.prototype.toString.call(x)?"object with keys {"+Object.keys(x).join(", ")+"}":x))}function Gr(b){function x(ni,Tr){if(b){var Qr=ni.lastEffect;null!==Qr?(Qr.nextEffect=Tr,ni.lastEffect=Tr):ni.firstEffect=ni.lastEffect=Tr,Tr.nextEffect=null,Tr.flags=8}}function G(ni,Tr){if(!b)return null;for(;null!==Tr;)x(ni,Tr),Tr=Tr.sibling;return null}function Se(ni,Tr){for(ni=new Map;null!==Tr;)ni.set(null!==Tr.key?Tr.key:Tr.index,Tr),Tr=Tr.sibling;return ni}function We(ni,Tr){return(ni=Sp(ni,Tr)).index=0,ni.sibling=null,ni}function Nt(ni,Tr,Qr){return ni.index=Qr,b?null!==(Qr=ni.alternate)?(Qr=Qr.index)<Tr?(ni.flags=2,Tr):Qr:(ni.flags=2,Tr):Tr}function rn(ni){return b&&null===ni.alternate&&(ni.flags=2),ni}function On(ni,Tr,Qr,Bi){return null===Tr||6!==Tr.tag?((Tr=Yh(Qr,ni.mode,Bi)).return=ni,Tr):((Tr=We(Tr,Qr)).return=ni,Tr)}function yr(ni,Tr,Qr,Bi){return null!==Tr&&Tr.elementType===Qr.type?((Bi=We(Tr,Qr.props)).ref=xn(ni,Tr,Qr),Bi.return=ni,Bi):((Bi=v_(Qr.type,Qr.key,Qr.props,null,ni.mode,Bi)).ref=xn(ni,Tr,Qr),Bi.return=ni,Bi)}function Si(ni,Tr,Qr,Bi){return null===Tr||4!==Tr.tag||Tr.stateNode.containerInfo!==Qr.containerInfo||Tr.stateNode.implementation!==Qr.implementation?((Tr=Zh(Qr,ni.mode,Bi)).return=ni,Tr):((Tr=We(Tr,Qr.children||[])).return=ni,Tr)}function as(ni,Tr,Qr,Bi,io){return null===Tr||7!==Tr.tag?((Tr=Jc(Qr,ni.mode,Bi,io)).return=ni,Tr):((Tr=We(Tr,Qr)).return=ni,Tr)}function Ha(ni,Tr,Qr){if("string"==typeof Tr||"number"==typeof Tr)return(Tr=Yh(""+Tr,ni.mode,Qr)).return=ni,Tr;if("object"==typeof Tr&&null!==Tr){switch(Tr.$$typeof){case ge:return(Qr=v_(Tr.type,Tr.key,Tr.props,null,ni.mode,Qr)).ref=xn(ni,null,Tr),Qr.return=ni,Qr;case De:return(Tr=Zh(Tr,ni.mode,Qr)).return=ni,Tr}if(Pn(Tr)||xt(Tr))return(Tr=Jc(Tr,ni.mode,Qr,null)).return=ni,Tr;ir(ni,Tr)}return null}function go(ni,Tr,Qr,Bi){var io=null!==Tr?Tr.key:null;if("string"==typeof Qr||"number"==typeof Qr)return null!==io?null:On(ni,Tr,""+Qr,Bi);if("object"==typeof Qr&&null!==Qr){switch(Qr.$$typeof){case ge:return Qr.key===io?Qr.type===ce?as(ni,Tr,Qr.props.children,Bi,io):yr(ni,Tr,Qr,Bi):null;case De:return Qr.key===io?Si(ni,Tr,Qr,Bi):null}if(Pn(Qr)||xt(Qr))return null!==io?null:as(ni,Tr,Qr,Bi,null);ir(ni,Qr)}return null}function po(ni,Tr,Qr,Bi,io){if("string"==typeof Bi||"number"==typeof Bi)return On(Tr,ni=ni.get(Qr)||null,""+Bi,io);if("object"==typeof Bi&&null!==Bi){switch(Bi.$$typeof){case ge:return ni=ni.get(null===Bi.key?Qr:Bi.key)||null,Bi.type===ce?as(Tr,ni,Bi.props.children,io,Bi.key):yr(Tr,ni,Bi,io);case De:return Si(Tr,ni=ni.get(null===Bi.key?Qr:Bi.key)||null,Bi,io)}if(Pn(Bi)||xt(Bi))return as(Tr,ni=ni.get(Qr)||null,Bi,io,null);ir(Tr,Bi)}return null}return function(ni,Tr,Qr,Bi){var io="object"==typeof Qr&&null!==Qr&&Qr.type===ce&&null===Qr.key;io&&(Qr=Qr.props.children);var va="object"==typeof Qr&&null!==Qr;if(va)switch(Qr.$$typeof){case ge:e:{for(va=Qr.key,io=Tr;null!==io;){if(io.key===va){switch(io.tag){case 7:if(Qr.type===ce){G(ni,io.sibling),(Tr=We(io,Qr.props.children)).return=ni,ni=Tr;break e}break;default:if(io.elementType===Qr.type){G(ni,io.sibling),(Tr=We(io,Qr.props)).ref=xn(ni,io,Qr),Tr.return=ni,ni=Tr;break e}}G(ni,io);break}x(ni,io),io=io.sibling}Qr.type===ce?((Tr=Jc(Qr.props.children,ni.mode,Bi,Qr.key)).return=ni,ni=Tr):((Bi=v_(Qr.type,Qr.key,Qr.props,null,ni.mode,Bi)).ref=xn(ni,Tr,Qr),Bi.return=ni,ni=Bi)}return rn(ni);case De:e:{for(io=Qr.key;null!==Tr;){if(Tr.key===io){if(4===Tr.tag&&Tr.stateNode.containerInfo===Qr.containerInfo&&Tr.stateNode.implementation===Qr.implementation){G(ni,Tr.sibling),(Tr=We(Tr,Qr.children||[])).return=ni,ni=Tr;break e}G(ni,Tr);break}x(ni,Tr),Tr=Tr.sibling}(Tr=Zh(Qr,ni.mode,Bi)).return=ni,ni=Tr}return rn(ni)}if("string"==typeof Qr||"number"==typeof Qr)return Qr=""+Qr,null!==Tr&&6===Tr.tag?(G(ni,Tr.sibling),(Tr=We(Tr,Qr)).return=ni,ni=Tr):(G(ni,Tr),(Tr=Yh(Qr,ni.mode,Bi)).return=ni,ni=Tr),rn(ni);if(Pn(Qr))return function(ni,Tr,Qr,Bi){for(var io=null,va=null,Cs=Tr,Qa=Tr=0,xl=null;null!==Cs&&Qa<Qr.length;Qa++){Cs.index>Qa?(xl=Cs,Cs=null):xl=Cs.sibling;var Cl=go(ni,Cs,Qr[Qa],Bi);if(null===Cl){null===Cs&&(Cs=xl);break}b&&Cs&&null===Cl.alternate&&x(ni,Cs),Tr=Nt(Cl,Tr,Qa),null===va?io=Cl:va.sibling=Cl,va=Cl,Cs=xl}if(Qa===Qr.length)return G(ni,Cs),io;if(null===Cs){for(;Qa<Qr.length;Qa++)null!==(Cs=Ha(ni,Qr[Qa],Bi))&&(Tr=Nt(Cs,Tr,Qa),null===va?io=Cs:va.sibling=Cs,va=Cs);return io}for(Cs=Se(ni,Cs);Qa<Qr.length;Qa++)null!==(xl=po(Cs,ni,Qa,Qr[Qa],Bi))&&(b&&null!==xl.alternate&&Cs.delete(null===xl.key?Qa:xl.key),Tr=Nt(xl,Tr,Qa),null===va?io=xl:va.sibling=xl,va=xl);return b&&Cs.forEach(function(Gp){return x(ni,Gp)}),io}(ni,Tr,Qr,Bi);if(xt(Qr))return function(ni,Tr,Qr,Bi){var io=xt(Qr);if("function"!=typeof io)throw Error(d(150));if(null==(Qr=io.call(Qr)))throw Error(d(151));for(var va=io=null,Cs=Tr,Qa=Tr=0,xl=null,Cl=Qr.next();null!==Cs&&!Cl.done;Qa++,Cl=Qr.next()){Cs.index>Qa?(xl=Cs,Cs=null):xl=Cs.sibling;var Gp=go(ni,Cs,Cl.value,Bi);if(null===Gp){null===Cs&&(Cs=xl);break}b&&Cs&&null===Gp.alternate&&x(ni,Cs),Tr=Nt(Gp,Tr,Qa),null===va?io=Gp:va.sibling=Gp,va=Gp,Cs=xl}if(Cl.done)return G(ni,Cs),io;if(null===Cs){for(;!Cl.done;Qa++,Cl=Qr.next())null!==(Cl=Ha(ni,Cl.value,Bi))&&(Tr=Nt(Cl,Tr,Qa),null===va?io=Cl:va.sibling=Cl,va=Cl);return io}for(Cs=Se(ni,Cs);!Cl.done;Qa++,Cl=Qr.next())null!==(Cl=po(Cs,ni,Qa,Cl.value,Bi))&&(b&&null!==Cl.alternate&&Cs.delete(null===Cl.key?Qa:Cl.key),Tr=Nt(Cl,Tr,Qa),null===va?io=Cl:va.sibling=Cl,va=Cl);return b&&Cs.forEach(function(i1){return x(ni,i1)}),io}(ni,Tr,Qr,Bi);if(va&&ir(ni,Qr),void 0===Qr&&!io)switch(ni.tag){case 1:case 22:case 0:case 11:case 15:throw Error(d(152,Mr(ni.type)||"Component"))}return G(ni,Tr)}}var Pi=Gr(!0),Zo=Gr(!1),Lo={},Gs=Sl(Lo),Xs=Sl(Lo),dl=Sl(Lo);function ha(b){if(b===Lo)throw Error(d(174));return b}function ia(b,x){switch(kl(dl,x),kl(Xs,b),kl(Gs,Lo),b=x.nodeType){case 9:case 11:x=(x=x.documentElement)?x.namespaceURI:gn(null,"");break;default:x=gn(x=(b=8===b?x.parentNode:x).namespaceURI||null,b=b.tagName)}wl(Gs),kl(Gs,x)}function Pa(){wl(Gs),wl(Xs),wl(dl)}function il(b){ha(dl.current);var x=ha(Gs.current),G=gn(x,b.type);x!==G&&(kl(Xs,b),kl(Gs,G))}function Eu(b){Xs.current===b&&(wl(Gs),wl(Xs))}var wa=Sl(0);function ou(b){for(var x=b;null!==x;){if(13===x.tag){var G=x.memoizedState;if(null!==G&&(null===(G=G.dehydrated)||"$?"===G.data||"$!"===G.data))return x}else if(19===x.tag&&void 0!==x.memoizedProps.revealOrder){if(0!=(64&x.flags))return x}else if(null!==x.child){x.child.return=x,x=x.child;continue}if(x===b)break;for(;null===x.sibling;){if(null===x.return||x.return===b)return null;x=x.return}x.sibling.return=x.return,x=x.sibling}return null}var gu=null,Nc=null,sc=!1;function gf(b,x){var G=Yd(5,null,null,0);G.elementType="DELETED",G.type="DELETED",G.stateNode=x,G.return=b,G.flags=8,null!==b.lastEffect?(b.lastEffect.nextEffect=G,b.lastEffect=G):b.firstEffect=b.lastEffect=G}function Ga(b,x){switch(b.tag){case 5:return null!==(x=1!==x.nodeType||b.type.toLowerCase()!==x.nodeName.toLowerCase()?null:x)&&(b.stateNode=x,!0);case 6:return null!==(x=""===b.pendingProps||3!==x.nodeType?null:x)&&(b.stateNode=x,!0);case 13:default:return!1}}function Q(b){if(sc){var x=Nc;if(x){var G=x;if(!Ga(b,x)){if(!(x=ga(G.nextSibling))||!Ga(b,x))return b.flags=-1025&b.flags|2,sc=!1,void(gu=b);gf(gu,G)}gu=b,Nc=ga(x.firstChild)}else b.flags=-1025&b.flags|2,sc=!1,gu=b}}function ve(b){for(b=b.return;null!==b&&5!==b.tag&&3!==b.tag&&13!==b.tag;)b=b.return;gu=b}function nt(b){if(b!==gu)return!1;if(!sc)return ve(b),sc=!0,!1;var x=b.type;if(5!==b.tag||"head"!==x&&"body"!==x&&!ns(x,b.memoizedProps))for(x=Nc;x;)gf(b,x),x=ga(x.nextSibling);if(ve(b),13===b.tag){if(!(b=null!==(b=b.memoizedState)?b.dehydrated:null))throw Error(d(317));e:{for(b=b.nextSibling,x=0;b;){if(8===b.nodeType){var G=b.data;if("/$"===G){if(0===x){Nc=ga(b.nextSibling);break e}x--}else"$"!==G&&"$!"!==G&&"$?"!==G||x++}b=b.nextSibling}Nc=null}}else Nc=gu?ga(b.stateNode.nextSibling):null;return!0}function Tt(){Nc=gu=null,sc=!1}var Qt=[];function cr(){for(var b=0;b<Qt.length;b++)Qt[b]._workInProgressVersionPrimary=null;Qt.length=0}var bi=he.ReactCurrentDispatcher,cs=he.ReactCurrentBatchConfig,xa=0,na=null,_l=null,zl=null,zc=!1,qf=!1;function Ld(){throw Error(d(321))}function Hp(b,x){if(null===x)return!1;for(var G=0;G<x.length&&G<b.length;G++)if(!Qs(b[G],x[G]))return!1;return!0}function Up(b,x,G,Se,We,Nt){if(xa=Nt,na=x,x.memoizedState=null,x.updateQueue=null,x.lanes=0,bi.current=null===b||null===b.memoizedState?Lh:$d,b=G(Se,We),qf){Nt=0;do{if(qf=!1,!(25>Nt))throw Error(d(301));Nt+=1,zl=_l=null,x.updateQueue=null,bi.current=hp,b=G(Se,We)}while(qf)}if(bi.current=vf,x=null!==_l&&null!==_l.next,xa=0,zl=_l=na=null,zc=!1,x)throw Error(d(300));return b}function mf(){var b={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===zl?na.memoizedState=zl=b:zl=zl.next=b,zl}function Uf(){if(null===_l){var b=na.alternate;b=null!==b?b.memoizedState:null}else b=_l.next;var x=null===zl?na.memoizedState:zl.next;if(null!==x)zl=x,_l=b;else{if(null===b)throw Error(d(310));b={memoizedState:(_l=b).memoizedState,baseState:_l.baseState,baseQueue:_l.baseQueue,queue:_l.queue,next:null},null===zl?na.memoizedState=zl=b:zl=zl.next=b}return zl}function dd(b,x){return"function"==typeof x?x(b):x}function Fd(b){var x=Uf(),G=x.queue;if(null===G)throw Error(d(311));G.lastRenderedReducer=b;var Se=_l,We=Se.baseQueue,Nt=G.pending;if(null!==Nt){if(null!==We){var rn=We.next;We.next=Nt.next,Nt.next=rn}Se.baseQueue=We=Nt,G.pending=null}if(null!==We){Se=Se.baseState;var On=rn=Nt=null,yr=We=We.next;do{var Si=yr.lane;if((xa&Si)===Si)null!==On&&(On=On.next={lane:0,action:yr.action,eagerReducer:yr.eagerReducer,eagerState:yr.eagerState,next:null}),Se=yr.eagerReducer===b?yr.eagerState:b(Se,yr.action);else{var as={lane:Si,action:yr.action,eagerReducer:yr.eagerReducer,eagerState:yr.eagerState,next:null};null===On?(rn=On=as,Nt=Se):On=On.next=as,na.lanes|=Si,Gf|=Si}yr=yr.next}while(null!==yr&&yr!==We);null===On?Nt=Se:On.next=rn,Qs(Se,x.memoizedState)||(qd=!0),x.memoizedState=Se,x.baseState=Nt,x.baseQueue=On,G.lastRenderedState=Se}return[x.memoizedState,G.dispatch]}function pp(b){var x=Uf(),G=x.queue;if(null===G)throw Error(d(311));G.lastRenderedReducer=b;var Se=G.dispatch,We=G.pending,Nt=x.memoizedState;if(null!==We){G.pending=null;var rn=We=We.next;do{Nt=b(Nt,rn.action),rn=rn.next}while(rn!==We);Qs(Nt,x.memoizedState)||(qd=!0),x.memoizedState=Nt,null===x.baseQueue&&(x.baseState=Nt),G.lastRenderedState=Nt}return[Nt,Se]}function fl(b,x,G){var Se=x._getVersion;Se=Se(x._source);var We=x._workInProgressVersionPrimary;if(null!==We?b=We===Se:(b=(xa&(b=b.mutableReadLanes))===b)&&(x._workInProgressVersionPrimary=Se,Qt.push(x)),b)return G(x._source);throw Qt.push(x),Error(d(350))}function i_(b,x,G,Se){var We=Uc;if(null===We)throw Error(d(349));var Nt=x._getVersion,rn=Nt(x._source),On=bi.current,yr=On.useState(function(){return fl(We,x,G)}),Si=yr[1],as=yr[0];yr=zl;var Ha=b.memoizedState,go=Ha.refs,po=go.getSnapshot,Fa=Ha.source;Ha=Ha.subscribe;var Ta=na;return b.memoizedState={refs:go,source:x,subscribe:Se},On.useEffect(function(){go.getSnapshot=G,go.setSnapshot=Si;var ni=Nt(x._source);if(!Qs(rn,ni)){ni=G(x._source),Qs(as,ni)||(Si(ni),ni=bf(Ta),We.mutableReadLanes|=ni&We.pendingLanes),We.entangledLanes|=ni=We.mutableReadLanes;for(var Tr=We.entanglements,Qr=ni;0<Qr;){var Bi=31-sl(Qr),io=1<<Bi;Tr[Bi]|=ni,Qr&=~io}}},[G,x,Se]),On.useEffect(function(){return Se(x._source,function(){var ni=go.getSnapshot,Tr=go.setSnapshot;try{Tr(ni(x._source));var Qr=bf(Ta);We.mutableReadLanes|=Qr&We.pendingLanes}catch(Bi){Tr(function(){throw Bi})}})},[x,Se]),Qs(po,G)&&Qs(Fa,x)&&Qs(Ha,Se)||((b={pending:null,dispatch:null,lastRenderedReducer:dd,lastRenderedState:as}).dispatch=Si=Ih.bind(null,na,b),yr.queue=b,yr.baseQueue=null,as=fl(We,x,G),yr.memoizedState=yr.baseState=as),as}function F_(b,x,G){return i_(Uf(),b,x,G)}function Bf(b){var x=mf();return"function"==typeof b&&(b=b()),x.memoizedState=x.baseState=b,b=(b=x.queue={pending:null,dispatch:null,lastRenderedReducer:dd,lastRenderedState:b}).dispatch=Ih.bind(null,na,b),[x.memoizedState,b]}function kd(b,x,G,Se){return b={tag:b,create:x,destroy:G,deps:Se,next:null},null===(x=na.updateQueue)?(na.updateQueue=x={lastEffect:null},x.lastEffect=b.next=b):null===(G=x.lastEffect)?x.lastEffect=b.next=b:(Se=G.next,G.next=b,b.next=Se,x.lastEffect=b),b}function Yf(b){return mf().memoizedState={current:b}}function eh(){return Uf().memoizedState}function bd(b,x,G,Se){var We=mf();na.flags|=b,We.memoizedState=kd(1|x,G,void 0,void 0===Se?null:Se)}function Rh(b,x,G,Se){var We=Uf();Se=void 0===Se?null:Se;var Nt=void 0;if(null!==_l){var rn=_l.memoizedState;if(Nt=rn.destroy,null!==Se&&Hp(Se,rn.deps))return void kd(x,G,Nt,Se)}na.flags|=b,We.memoizedState=kd(1|x,G,Nt,Se)}function th(b,x){return bd(516,4,b,x)}function nh(b,x){return Rh(516,4,b,x)}function Nh(b,x){return Rh(4,2,b,x)}function rh(b,x){return"function"==typeof x?(b=b(),x(b),function(){x(null)}):null!=x?(b=b(),x.current=b,function(){x.current=null}):void 0}function Ed(b,x,G){return G=null!=G?G.concat([b]):null,Rh(4,2,rh.bind(null,x,b),G)}function xf(){}function Ph(b,x){var G=Uf();x=void 0===x?null:x;var Se=G.memoizedState;return null!==Se&&null!==x&&Hp(x,Se[1])?Se[0]:(G.memoizedState=[b,x],b)}function Bp(b,x){var G=Uf();x=void 0===x?null:x;var Se=G.memoizedState;return null!==Se&&null!==x&&Hp(x,Se[1])?Se[0]:(b=b(),G.memoizedState=[b,x],b)}function ih(b,x){var G=Ll();rl(98>G?98:G,function(){b(!0)}),rl(97<G?97:G,function(){var Se=cs.transition;cs.transition=1;try{b(!1),x()}finally{cs.transition=Se}})}function Ih(b,x,G){var Se=fd(),We=bf(b),Nt={lane:We,action:G,eagerReducer:null,eagerState:null,next:null},rn=x.pending;if(null===rn?Nt.next=Nt:(Nt.next=rn.next,rn.next=Nt),x.pending=Nt,rn=b.alternate,b===na||null!==rn&&rn===na)qf=zc=!0;else{if(0===b.lanes&&(null===rn||0===rn.lanes)&&null!==(rn=x.lastRenderedReducer))try{var On=x.lastRenderedState,yr=rn(On,G);if(Nt.eagerReducer=rn,Nt.eagerState=yr,Qs(yr,On))return}catch(Si){}zf(b,We,Se)}}var vf={readContext:Ou,useCallback:Ld,useContext:Ld,useEffect:Ld,useImperativeHandle:Ld,useLayoutEffect:Ld,useMemo:Ld,useReducer:Ld,useRef:Ld,useState:Ld,useDebugValue:Ld,useDeferredValue:Ld,useTransition:Ld,useMutableSource:Ld,useOpaqueIdentifier:Ld,unstable_isNewReconciler:!1},Lh={readContext:Ou,useCallback:function(b,x){return mf().memoizedState=[b,void 0===x?null:x],b},useContext:Ou,useEffect:th,useImperativeHandle:function(b,x,G){return G=null!=G?G.concat([b]):null,bd(4,2,rh.bind(null,x,b),G)},useLayoutEffect:function(b,x){return bd(4,2,b,x)},useMemo:function(b,x){var G=mf();return x=void 0===x?null:x,b=b(),G.memoizedState=[b,x],b},useReducer:function(b,x,G){var Se=mf();return x=void 0!==G?G(x):x,Se.memoizedState=Se.baseState=x,b=(b=Se.queue={pending:null,dispatch:null,lastRenderedReducer:b,lastRenderedState:x}).dispatch=Ih.bind(null,na,b),[Se.memoizedState,b]},useRef:Yf,useState:Bf,useDebugValue:xf,useDeferredValue:function(b){var x=Bf(b),G=x[0],Se=x[1];return th(function(){var We=cs.transition;cs.transition=1;try{Se(b)}finally{cs.transition=We}},[b]),G},useTransition:function(){var b=Bf(!1),x=b[0];return Yf(b=ih.bind(null,b[1])),[b,x]},useMutableSource:function(b,x,G){var Se=mf();return Se.memoizedState={refs:{getSnapshot:x,setSnapshot:null},source:b,subscribe:G},i_(Se,b,x,G)},useOpaqueIdentifier:function(){if(sc){var b=!1,x=function(b){return{$$typeof:It,toString:b,valueOf:b}}(function(){throw b||(b=!0,G("r:"+(ll++).toString(36))),Error(d(355))}),G=Bf(x)[1];return 0==(2&na.mode)&&(na.flags|=516,kd(5,function(){G("r:"+(ll++).toString(36))},void 0,null)),x}return Bf(x="r:"+(ll++).toString(36)),x},unstable_isNewReconciler:!1},$d={readContext:Ou,useCallback:Ph,useContext:Ou,useEffect:nh,useImperativeHandle:Ed,useLayoutEffect:Nh,useMemo:Bp,useReducer:Fd,useRef:eh,useState:function(){return Fd(dd)},useDebugValue:xf,useDeferredValue:function(b){var x=Fd(dd),G=x[0],Se=x[1];return nh(function(){var We=cs.transition;cs.transition=1;try{Se(b)}finally{cs.transition=We}},[b]),G},useTransition:function(){var b=Fd(dd)[0];return[eh().current,b]},useMutableSource:F_,useOpaqueIdentifier:function(){return Fd(dd)[0]},unstable_isNewReconciler:!1},hp={readContext:Ou,useCallback:Ph,useContext:Ou,useEffect:nh,useImperativeHandle:Ed,useLayoutEffect:Nh,useMemo:Bp,useReducer:pp,useRef:eh,useState:function(){return pp(dd)},useDebugValue:xf,useDeferredValue:function(b){var x=pp(dd),G=x[0],Se=x[1];return nh(function(){var We=cs.transition;cs.transition=1;try{Se(b)}finally{cs.transition=We}},[b]),G},useTransition:function(){var b=pp(dd)[0];return[eh().current,b]},useMutableSource:F_,useOpaqueIdentifier:function(){return pp(dd)[0]},unstable_isNewReconciler:!1},Zf=he.ReactCurrentOwner,qd=!1;function ac(b,x,G,Se){x.child=null===b?Zo(x,null,G,Se):Pi(x,b.child,G,Se)}function oh(b,x,G,Se,We){G=G.render;var Nt=x.ref;return Lu(x,We),Se=Up(b,x,G,Se,Nt,We),null===b||qd?(x.flags|=1,ac(b,x,Se,We),x.child):(x.updateQueue=b.updateQueue,x.flags&=-517,b.lanes&=~We,ma(b,x,We))}function k_(b,x,G,Se,We,Nt){if(null===b){var rn=G.type;return"function"!=typeof rn||yg(rn)||void 0!==rn.defaultProps||null!==G.compare||void 0!==G.defaultProps?((b=v_(G.type,null,Se,x,x.mode,Nt)).ref=x.ref,b.return=x,x.child=b):(x.tag=15,x.type=rn,o_(b,x,rn,Se,We,Nt))}return rn=b.child,0==(We&Nt)&&(G=null!==(G=G.compare)?G:$c)(We=rn.memoizedProps,Se)&&b.ref===x.ref?ma(b,x,Nt):(x.flags|=1,(b=Sp(rn,Se)).ref=x.ref,b.return=x,x.child=b)}function o_(b,x,G,Se,We,Nt){if(null!==b&&$c(b.memoizedProps,Se)&&b.ref===x.ref){if(qd=!1,0==(Nt&We))return x.lanes=b.lanes,ma(b,x,Nt);0!=(16384&b.flags)&&(qd=!0)}return w(b,x,G,Se,Nt)}function Y(b,x,G){var Se=x.pendingProps,We=Se.children,Nt=null!==b?b.memoizedState:null;if("hidden"===Se.mode||"unstable-defer-without-hiding"===Se.mode)if(0==(4&x.mode))x.memoizedState={baseLanes:0},Bc(0,G);else{if(0==(1073741824&G))return b=null!==Nt?Nt.baseLanes|G:G,x.lanes=x.childLanes=1073741824,x.memoizedState={baseLanes:b},Bc(0,b),null;x.memoizedState={baseLanes:0},Bc(0,null!==Nt?Nt.baseLanes:G)}else null!==Nt?(Se=Nt.baseLanes|G,x.memoizedState=null):Se=G,Bc(0,Se);return ac(b,x,We,G),x.child}function fe(b,x){var G=x.ref;(null===b&&null!==G||null!==b&&b.ref!==G)&&(x.flags|=128)}function w(b,x,G,Se,We){var Nt=Au(G)?en:Ja.current;return Nt=Oc(x,Nt),Lu(x,We),G=Up(b,x,G,Se,Nt,We),null===b||qd?(x.flags|=1,ac(b,x,G,We),x.child):(x.updateQueue=b.updateQueue,x.flags&=-517,b.lanes&=~We,ma(b,x,We))}function X(b,x,G,Se,We){if(Au(G)){var Nt=!0;Jl(x)}else Nt=!1;if(Lu(x,We),null===x.stateNode)null!==b&&(b.alternate=null,x.alternate=null,x.flags|=2),gt(x,G,Se),nn(x,G,Se,We),Se=!0;else if(null===b){var rn=x.stateNode,On=x.memoizedProps;rn.props=On;var yr=rn.context,Si=G.contextType;Si="object"==typeof Si&&null!==Si?Ou(Si):Oc(x,Si=Au(G)?en:Ja.current);var as=G.getDerivedStateFromProps,Ha="function"==typeof as||"function"==typeof rn.getSnapshotBeforeUpdate;Ha||"function"!=typeof rn.UNSAFE_componentWillReceiveProps&&"function"!=typeof rn.componentWillReceiveProps||(On!==Se||yr!==Si)&&yt(x,rn,Se,Si),Rc=!1;var go=x.memoizedState;rn.state=go,q(x,Se,rn,We),yr=x.memoizedState,On!==Se||go!==yr||Qu.current||Rc?("function"==typeof as&&(Ue(x,G,as,Se),yr=x.memoizedState),(On=Rc||Xe(x,G,On,Se,go,yr,Si))?(Ha||"function"!=typeof rn.UNSAFE_componentWillMount&&"function"!=typeof rn.componentWillMount||("function"==typeof rn.componentWillMount&&rn.componentWillMount(),"function"==typeof rn.UNSAFE_componentWillMount&&rn.UNSAFE_componentWillMount()),"function"==typeof rn.componentDidMount&&(x.flags|=4)):("function"==typeof rn.componentDidMount&&(x.flags|=4),x.memoizedProps=Se,x.memoizedState=yr),rn.props=Se,rn.state=yr,rn.context=Si,Se=On):("function"==typeof rn.componentDidMount&&(x.flags|=4),Se=!1)}else{rn=x.stateNode,h(b,x),On=x.memoizedProps,Si=x.type===x.elementType?On:Vl(x.type,On),rn.props=Si,Ha=x.pendingProps,go=rn.context,yr="object"==typeof(yr=G.contextType)&&null!==yr?Ou(yr):Oc(x,yr=Au(G)?en:Ja.current);var po=G.getDerivedStateFromProps;(as="function"==typeof po||"function"==typeof rn.getSnapshotBeforeUpdate)||"function"!=typeof rn.UNSAFE_componentWillReceiveProps&&"function"!=typeof rn.componentWillReceiveProps||(On!==Ha||go!==yr)&&yt(x,rn,Se,yr),Rc=!1,rn.state=go=x.memoizedState,q(x,Se,rn,We);var Fa=x.memoizedState;On!==Ha||go!==Fa||Qu.current||Rc?("function"==typeof po&&(Ue(x,G,po,Se),Fa=x.memoizedState),(Si=Rc||Xe(x,G,Si,Se,go,Fa,yr))?(as||"function"!=typeof rn.UNSAFE_componentWillUpdate&&"function"!=typeof rn.componentWillUpdate||("function"==typeof rn.componentWillUpdate&&rn.componentWillUpdate(Se,Fa,yr),"function"==typeof rn.UNSAFE_componentWillUpdate&&rn.UNSAFE_componentWillUpdate(Se,Fa,yr)),"function"==typeof rn.componentDidUpdate&&(x.flags|=4),"function"==typeof rn.getSnapshotBeforeUpdate&&(x.flags|=256)):("function"!=typeof rn.componentDidUpdate||On===b.memoizedProps&&go===b.memoizedState||(x.flags|=4),"function"!=typeof rn.getSnapshotBeforeUpdate||On===b.memoizedProps&&go===b.memoizedState||(x.flags|=256),x.memoizedProps=Se,x.memoizedState=Fa),rn.props=Se,rn.state=Fa,rn.context=yr,Se=Si):("function"!=typeof rn.componentDidUpdate||On===b.memoizedProps&&go===b.memoizedState||(x.flags|=4),"function"!=typeof rn.getSnapshotBeforeUpdate||On===b.memoizedProps&&go===b.memoizedState||(x.flags|=256),Se=!1)}return ke(b,x,G,Se,Nt,We)}function ke(b,x,G,Se,We,Nt){fe(b,x);var rn=0!=(64&x.flags);if(!Se&&!rn)return We&&vd(x,G,!1),ma(b,x,Nt);Se=x.stateNode,Zf.current=x;var On=rn&&"function"!=typeof G.getDerivedStateFromError?null:Se.render();return x.flags|=1,null!==b&&rn?(x.child=Pi(x,b.child,null,Nt),x.child=Pi(x,null,On,Nt)):ac(b,x,On,Nt),x.memoizedState=Se.state,We&&vd(x,G,!0),x.child}function ct(b){var x=b.stateNode;x.pendingContext?nl(0,x.pendingContext,x.pendingContext!==x.context):x.context&&nl(0,x.context,!1),ia(b,x.containerInfo)}var Vs,nd,wu,Jn={dehydrated:null,retryLane:0};function Ir(b,x,G){var rn,Se=x.pendingProps,We=wa.current,Nt=!1;return(rn=0!=(64&x.flags))||(rn=(null===b||null!==b.memoizedState)&&0!=(2&We)),rn?(Nt=!0,x.flags&=-65):null!==b&&null===b.memoizedState||void 0===Se.fallback||!0===Se.unstable_avoidThisFallback||(We|=1),kl(wa,1&We),null===b?(void 0!==Se.fallback&&Q(x),b=Se.children,We=Se.fallback,Nt?(b=vi(x,b,We,G),x.child.memoizedState={baseLanes:G},x.memoizedState=Jn,b):"number"==typeof Se.unstable_expectedLoadTime?(b=vi(x,b,We,G),x.child.memoizedState={baseLanes:G},x.memoizedState=Jn,x.lanes=33554432,b):((G=J_({mode:"visible",children:b},x.mode,G,null)).return=x,x.child=G)):Nt?(Se=function(b,x,G,Se,We){var Nt=x.mode,rn=b.child;b=rn.sibling;var On={mode:"hidden",children:G};return 0==(2&Nt)&&x.child!==rn?((G=x.child).childLanes=0,G.pendingProps=On,null!==(rn=G.lastEffect)?(x.firstEffect=G.firstEffect,x.lastEffect=rn,rn.nextEffect=null):x.firstEffect=x.lastEffect=null):G=Sp(rn,On),null!==b?Se=Sp(b,Se):(Se=Jc(Se,Nt,We,null)).flags|=2,Se.return=x,G.return=x,G.sibling=Se,x.child=G,Se}(b,x,Se.children,Se.fallback,G),(Nt=x.child).memoizedState=null===(We=b.child.memoizedState)?{baseLanes:G}:{baseLanes:We.baseLanes|G},Nt.childLanes=b.childLanes&~G,x.memoizedState=Jn,Se):(G=function(b,x,G,Se){var We=b.child;return b=We.sibling,G=Sp(We,{mode:"visible",children:G}),0==(2&x.mode)&&(G.lanes=Se),G.return=x,G.sibling=null,null!==b&&(b.nextEffect=null,b.flags=8,x.firstEffect=x.lastEffect=b),x.child=G}(b,x,Se.children,G),x.memoizedState=null,G)}function vi(b,x,G,Se){var We=b.mode,Nt=b.child;return x={mode:"hidden",children:x},0==(2&We)&&null!==Nt?(Nt.childLanes=0,Nt.pendingProps=x):Nt=J_(x,We,0,null),G=Jc(G,We,Se,null),Nt.return=b,G.return=b,Nt.sibling=G,b.child=Nt,G}function xs(b,x){b.lanes|=x;var G=b.alternate;null!==G&&(G.lanes|=x),cu(b.return,x)}function Xo(b,x,G,Se,We,Nt){var rn=b.memoizedState;null===rn?b.memoizedState={isBackwards:x,rendering:null,renderingStartTime:0,last:Se,tail:G,tailMode:We,lastEffect:Nt}:(rn.isBackwards=x,rn.rendering=null,rn.renderingStartTime=0,rn.last=Se,rn.tail=G,rn.tailMode=We,rn.lastEffect=Nt)}function Rs(b,x,G){var Se=x.pendingProps,We=Se.revealOrder,Nt=Se.tail;if(ac(b,x,Se.children,G),0!=(2&(Se=wa.current)))Se=1&Se|2,x.flags|=64;else{if(null!==b&&0!=(64&b.flags))e:for(b=x.child;null!==b;){if(13===b.tag)null!==b.memoizedState&&xs(b,G);else if(19===b.tag)xs(b,G);else if(null!==b.child){b.child.return=b,b=b.child;continue}if(b===x)break e;for(;null===b.sibling;){if(null===b.return||b.return===x)break e;b=b.return}b.sibling.return=b.return,b=b.sibling}Se&=1}if(kl(wa,Se),0==(2&x.mode))x.memoizedState=null;else switch(We){case"forwards":for(G=x.child,We=null;null!==G;)null!==(b=G.alternate)&&null===ou(b)&&(We=G),G=G.sibling;null===(G=We)?(We=x.child,x.child=null):(We=G.sibling,G.sibling=null),Xo(x,!1,We,G,Nt,x.lastEffect);break;case"backwards":for(G=null,We=x.child,x.child=null;null!==We;){if(null!==(b=We.alternate)&&null===ou(b)){x.child=We;break}b=We.sibling,We.sibling=G,G=We,We=b}Xo(x,!0,G,null,Nt,x.lastEffect);break;case"together":Xo(x,!1,null,null,void 0,x.lastEffect);break;default:x.memoizedState=null}return x.child}function ma(b,x,G){if(null!==b&&(x.dependencies=b.dependencies),Gf|=x.lanes,0!=(G&x.childLanes)){if(null!==b&&x.child!==b.child)throw Error(d(153));if(null!==x.child){for(G=Sp(b=x.child,b.pendingProps),x.child=G,G.return=x;null!==b.sibling;)(G=G.sibling=Sp(b=b.sibling,b.pendingProps)).return=x;G.sibling=null}return x.child}return null}function Hd(b,x){if(!sc)switch(b.tailMode){case"hidden":x=b.tail;for(var G=null;null!==x;)null!==x.alternate&&(G=x),x=x.sibling;null===G?b.tail=null:G.sibling=null;break;case"collapsed":G=b.tail;for(var Se=null;null!==G;)null!==G.alternate&&(Se=G),G=G.sibling;null===Se?x||null===b.tail?b.tail=null:b.tail.sibling=null:Se.sibling=null}}function $_(b,x,G){var Se=x.pendingProps;switch(x.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return null;case 1:return Au(x.type)&&Iu(),null;case 3:return Pa(),wl(Qu),wl(Ja),cr(),(Se=x.stateNode).pendingContext&&(Se.context=Se.pendingContext,Se.pendingContext=null),(null===b||null===b.child)&&(nt(x)?x.flags|=4:Se.hydrate||(x.flags|=256)),null;case 5:Eu(x);var We=ha(dl.current);if(G=x.type,null!==b&&null!=x.stateNode)nd(b,x,G,Se),b.ref!==x.ref&&(x.flags|=128);else{if(!Se){if(null===x.stateNode)throw Error(d(166));return null}if(b=ha(Gs.current),nt(x)){G=x.type;var Nt=x.memoizedProps;switch((Se=x.stateNode)[ul]=x,Se[Of]=Nt,G){case"dialog":al("cancel",Se),al("close",Se);break;case"iframe":case"object":case"embed":al("load",Se);break;case"video":case"audio":for(b=0;b<la.length;b++)al(la[b],Se);break;case"source":al("error",Se);break;case"img":case"image":case"link":al("error",Se),al("load",Se);break;case"details":al("toggle",Se);break;case"input":ki(Se,Nt),al("invalid",Se);break;case"select":Se._wrapperState={wasMultiple:!!Nt.multiple},al("invalid",Se);break;case"textarea":Jr(Se,Nt),al("invalid",Se)}for(var rn in _n(G,Nt),b=null,Nt)Nt.hasOwnProperty(rn)&&(We=Nt[rn],"children"===rn?"string"==typeof We?Se.textContent!==We&&(b=["children",We]):"number"==typeof We&&Se.textContent!==""+We&&(b=["children",""+We]):_.hasOwnProperty(rn)&&null!=We&&"onScroll"===rn&&al("scroll",Se));switch(G){case"input":$n(Se),Cn(Se,Nt,!0);break;case"textarea":$n(Se),wi(Se);break;case"select":case"option":break;default:"function"==typeof Nt.onClick&&(Se.onclick=Xn)}x.updateQueue=Se=b,null!==Se&&(x.flags|=4)}else{switch(rn=9===We.nodeType?We:We.ownerDocument,b===br_html&&(b=Dr(G)),b===br_html?"script"===G?((b=rn.createElement("div")).innerHTML="<script><\/script>",b=b.removeChild(b.firstChild)):"string"==typeof Se.is?b=rn.createElement(G,{is:Se.is}):(b=rn.createElement(G),"select"===G&&(rn=b,Se.multiple?rn.multiple=!0:Se.size&&(rn.size=Se.size))):b=rn.createElementNS(b,G),b[ul]=x,b[Of]=Se,Vs(b,x),x.stateNode=b,rn=Ge(G,Se),G){case"dialog":al("cancel",b),al("close",b),We=Se;break;case"iframe":case"object":case"embed":al("load",b),We=Se;break;case"video":case"audio":for(We=0;We<la.length;We++)al(la[We],b);We=Se;break;case"source":al("error",b),We=Se;break;case"img":case"image":case"link":al("error",b),al("load",b),We=Se;break;case"details":al("toggle",b),We=Se;break;case"input":ki(b,Se),We=fi(b,Se),al("invalid",b);break;case"option":We=rr(b,Se);break;case"select":b._wrapperState={wasMultiple:!!Se.multiple},We=u({},Se,{value:void 0}),al("invalid",b);break;case"textarea":Jr(b,Se),We=Gn(b,Se),al("invalid",b);break;default:We=Se}_n(G,We);var On=We;for(Nt in On)if(On.hasOwnProperty(Nt)){var yr=On[Nt];"style"===Nt?Pr(b,yr):"dangerouslySetInnerHTML"===Nt?null!=(yr=yr?yr.__html:void 0)&&gr(b,yr):"children"===Nt?"string"==typeof yr?("textarea"!==G||""!==yr)&&Jt(b,yr):"number"==typeof yr&&Jt(b,""+yr):"suppressContentEditableWarning"!==Nt&&"suppressHydrationWarning"!==Nt&&"autoFocus"!==Nt&&(_.hasOwnProperty(Nt)?null!=yr&&"onScroll"===Nt&&al("scroll",b):null!=yr&&ie(b,Nt,yr,rn))}switch(G){case"input":$n(b),Cn(b,Se,!1);break;case"textarea":$n(b),wi(b);break;case"option":null!=Se.value&&b.setAttribute("value",""+Kr(Se.value));break;case"select":b.multiple=!!Se.multiple,null!=(Nt=Se.value)?Fr(b,!!Se.multiple,Nt,!1):null!=Se.defaultValue&&Fr(b,!!Se.multiple,Se.defaultValue,!0);break;default:"function"==typeof We.onClick&&(b.onclick=Xn)}$a(G,Se)&&(x.flags|=4)}null!==x.ref&&(x.flags|=128)}return null;case 6:if(b&&null!=x.stateNode)wu(0,x,b.memoizedProps,Se);else{if("string"!=typeof Se&&null===x.stateNode)throw Error(d(166));G=ha(dl.current),ha(Gs.current),nt(x)?(G=x.memoizedProps,(Se=x.stateNode)[ul]=x,Se.nodeValue!==G&&(x.flags|=4)):((Se=(9===G.nodeType?G:G.ownerDocument).createTextNode(Se))[ul]=x,x.stateNode=Se)}return null;case 13:return wl(wa),Se=x.memoizedState,0!=(64&x.flags)?(x.lanes=G,x):(Se=null!==Se,G=!1,null===b?void 0!==x.memoizedProps.fallback&&nt(x):G=null!==b.memoizedState,Se&&!G&&0!=(2&x.mode)&&(null===b&&!0!==x.memoizedProps.unstable_avoidThisFallback||0!=(1&wa.current)?0===Zu&&(Zu=3):((0===Zu||3===Zu)&&(Zu=4),null===Uc||0==(134217727&Gf)&&0==(134217727&Pc)||Df(Uc,Ds))),(Se||G)&&(x.flags|=4),null);case 4:return Pa(),null===b&&Jd(x.stateNode.containerInfo),null;case 10:return Hc(x),null;case 17:return Au(x.type)&&Iu(),null;case 19:if(wl(wa),null===(Se=x.memoizedState))return null;if(Nt=0!=(64&x.flags),null===(rn=Se.rendering))if(Nt)Hd(Se,!1);else{if(0!==Zu||null!==b&&0!=(64&b.flags))for(b=x.child;null!==b;){if(null!==(rn=ou(b))){for(x.flags|=64,Hd(Se,!1),null!==(Nt=rn.updateQueue)&&(x.updateQueue=Nt,x.flags|=4),null===Se.lastEffect&&(x.firstEffect=null),x.lastEffect=Se.lastEffect,Se=G,G=x.child;null!==G;)b=Se,(Nt=G).flags&=2,Nt.nextEffect=null,Nt.firstEffect=null,Nt.lastEffect=null,null===(rn=Nt.alternate)?(Nt.childLanes=0,Nt.lanes=b,Nt.child=null,Nt.memoizedProps=null,Nt.memoizedState=null,Nt.updateQueue=null,Nt.dependencies=null,Nt.stateNode=null):(Nt.childLanes=rn.childLanes,Nt.lanes=rn.lanes,Nt.child=rn.child,Nt.memoizedProps=rn.memoizedProps,Nt.memoizedState=rn.memoizedState,Nt.updateQueue=rn.updateQueue,Nt.type=rn.type,Nt.dependencies=null===(b=rn.dependencies)?null:{lanes:b.lanes,firstContext:b.firstContext}),G=G.sibling;return kl(wa,1&wa.current|2),x.child}b=b.sibling}null!==Se.tail&&cl()>kh&&(x.flags|=64,Nt=!0,Hd(Se,!1),x.lanes=33554432)}else{if(!Nt)if(null!==(b=ou(rn))){if(x.flags|=64,Nt=!0,null!==(G=b.updateQueue)&&(x.updateQueue=G,x.flags|=4),Hd(Se,!0),null===Se.tail&&"hidden"===Se.tailMode&&!rn.alternate&&!sc)return null!==(x=x.lastEffect=Se.lastEffect)&&(x.nextEffect=null),null}else 2*cl()-Se.renderingStartTime>kh&&1073741824!==G&&(x.flags|=64,Nt=!0,Hd(Se,!1),x.lanes=33554432);Se.isBackwards?(rn.sibling=x.child,x.child=rn):(null!==(G=Se.last)?G.sibling=rn:x.child=rn,Se.last=rn)}return null!==Se.tail?(Se.rendering=G=Se.tail,Se.tail=G.sibling,Se.lastEffect=x.lastEffect,Se.renderingStartTime=cl(),G.sibling=null,x=wa.current,kl(wa,Nt?1&x|2:1&x),G):null;case 23:case 24:return Rf(),null!==b&&null!==b.memoizedState!=(null!==x.memoizedState)&&"unstable-defer-without-hiding"!==Se.mode&&(x.flags|=4),null}throw Error(d(156,x.tag))}function sh(b){switch(b.tag){case 1:Au(b.type)&&Iu();var x=b.flags;return 4096&x?(b.flags=-4097&x|64,b):null;case 3:if(Pa(),wl(Qu),wl(Ja),cr(),0!=(64&(x=b.flags)))throw Error(d(285));return b.flags=-4097&x|64,b;case 5:return Eu(b),null;case 13:return wl(wa),4096&(x=b.flags)?(b.flags=-4097&x|64,b):null;case 19:return wl(wa),null;case 4:return Pa(),null;case 10:return Hc(b),null;case 23:case 24:return Rf(),null;default:return null}}function ah(b,x){try{var G="",Se=x;do{G+=Lr(Se),Se=Se.return}while(Se);var We=G}catch(Nt){We="\nError generating stack: "+Nt.message+"\n"+Nt.stack}return{value:b,source:x,stack:We}}function _p(b,x){try{console.error(x.value)}catch(G){setTimeout(function(){throw G})}}Vs=function(b,x){for(var G=x.child;null!==G;){if(5===G.tag||6===G.tag)b.appendChild(G.stateNode);else if(4!==G.tag&&null!==G.child){G.child.return=G,G=G.child;continue}if(G===x)break;for(;null===G.sibling;){if(null===G.return||G.return===x)return;G=G.return}G.sibling.return=G.return,G=G.sibling}},nd=function(b,x,G,Se){var We=b.memoizedProps;if(We!==Se){b=x.stateNode,ha(Gs.current);var rn,Nt=null;switch(G){case"input":We=fi(b,We),Se=fi(b,Se),Nt=[];break;case"option":We=rr(b,We),Se=rr(b,Se),Nt=[];break;case"select":We=u({},We,{value:void 0}),Se=u({},Se,{value:void 0}),Nt=[];break;case"textarea":We=Gn(b,We),Se=Gn(b,Se),Nt=[];break;default:"function"!=typeof We.onClick&&"function"==typeof Se.onClick&&(b.onclick=Xn)}for(Si in _n(G,Se),G=null,We)if(!Se.hasOwnProperty(Si)&&We.hasOwnProperty(Si)&&null!=We[Si])if("style"===Si){var On=We[Si];for(rn in On)On.hasOwnProperty(rn)&&(G||(G={}),G[rn]="")}else"dangerouslySetInnerHTML"!==Si&&"children"!==Si&&"suppressContentEditableWarning"!==Si&&"suppressHydrationWarning"!==Si&&"autoFocus"!==Si&&(_.hasOwnProperty(Si)?Nt||(Nt=[]):(Nt=Nt||[]).push(Si,null));for(Si in Se){var yr=Se[Si];if(On=null!=We?We[Si]:void 0,Se.hasOwnProperty(Si)&&yr!==On&&(null!=yr||null!=On))if("style"===Si)if(On){for(rn in On)!On.hasOwnProperty(rn)||yr&&yr.hasOwnProperty(rn)||(G||(G={}),G[rn]="");for(rn in yr)yr.hasOwnProperty(rn)&&On[rn]!==yr[rn]&&(G||(G={}),G[rn]=yr[rn])}else G||(Nt||(Nt=[]),Nt.push(Si,G)),G=yr;else"dangerouslySetInnerHTML"===Si?(On=On?On.__html:void 0,null!=(yr=yr?yr.__html:void 0)&&On!==yr&&(Nt=Nt||[]).push(Si,yr)):"children"===Si?"string"!=typeof yr&&"number"!=typeof yr||(Nt=Nt||[]).push(Si,""+yr):"suppressContentEditableWarning"!==Si&&"suppressHydrationWarning"!==Si&&(_.hasOwnProperty(Si)?(null!=yr&&"onScroll"===Si&&al("scroll",b),Nt||On===yr||(Nt=[])):"object"==typeof yr&&null!==yr&&yr.$$typeof===It?yr.toString():(Nt=Nt||[]).push(Si,yr))}G&&(Nt=Nt||[]).push("style",G);var Si=Nt;(x.updateQueue=Si)&&(x.flags|=4)}},wu=function(b,x,G,Se){G!==Se&&(x.flags|=4)};var jf="function"==typeof WeakMap?WeakMap:Map;function H_(b,x,G){(G=E(-1,G)).tag=3,G.payload={element:null};var Se=x.value;return G.callback=function(){f_||(f_=!0,G_=Se),_p(0,x)},G}function fg(b,x,G){(G=E(-1,G)).tag=3;var Se=b.type.getDerivedStateFromError;if("function"==typeof Se){var We=x.value;G.payload=function(){return _p(0,x),Se(We)}}var Nt=b.stateNode;return null!==Nt&&"function"==typeof Nt.componentDidCatch&&(G.callback=function(){"function"!=typeof Se&&(null===id?id=new Set([this]):id.add(this),_p(0,x));var rn=x.stack;this.componentDidCatch(x.value,{componentStack:null!==rn?rn:""})}),G}var gp="function"==typeof WeakSet?WeakSet:Set;function Td(b){var x=b.ref;if(null!==x)if("function"==typeof x)try{x(null)}catch(G){Tp(b,G)}else x.current=null}function U_(b,x){switch(x.tag){case 0:case 11:case 15:case 22:return;case 1:if(256&x.flags&&null!==b){var G=b.memoizedProps,Se=b.memoizedState;x=(b=x.stateNode).getSnapshotBeforeUpdate(x.elementType===x.type?G:Vl(x.type,G),Se),b.__reactInternalSnapshotBeforeUpdate=x}return;case 3:return void(256&x.flags&&fc(x.stateNode.containerInfo));case 5:case 6:case 4:case 17:return}throw Error(d(163))}function s_(b,x,G){switch(G.tag){case 0:case 11:case 15:case 22:if(null!==(x=null!==(x=G.updateQueue)?x.lastEffect:null)){b=x=x.next;do{if(3==(3&b.tag)){var Se=b.create;b.destroy=Se()}b=b.next}while(b!==x)}if(null!==(x=null!==(x=G.updateQueue)?x.lastEffect:null)){b=x=x.next;do{var We=b;Se=We.next,0!=(4&(We=We.tag))&&0!=(1&We)&&(vg(G,b),mg(G,b)),b=Se}while(b!==x)}return;case 1:return b=G.stateNode,4&G.flags&&(null===x?b.componentDidMount():(Se=G.elementType===G.type?x.memoizedProps:Vl(G.type,x.memoizedProps),b.componentDidUpdate(Se,x.memoizedState,b.__reactInternalSnapshotBeforeUpdate))),void(null!==(x=G.updateQueue)&&de(G,x,b));case 3:if(null!==(x=G.updateQueue)){if(b=null,null!==G.child)switch(G.child.tag){case 5:b=G.child.stateNode;break;case 1:b=G.child.stateNode}de(G,x,b)}return;case 5:return b=G.stateNode,void(null===x&&4&G.flags&&$a(G.type,G.memoizedProps)&&b.focus());case 6:case 4:case 12:return;case 13:return void(null===G.memoizedState&&(G=G.alternate,null!==G&&(G=G.memoizedState,null!==G&&(G=G.dehydrated,null!==G&&Ca(G)))));case 19:case 17:case 20:case 21:case 23:case 24:return}throw Error(d(163))}function B_(b,x){for(var G=b;;){if(5===G.tag){var Se=G.stateNode;if(x)"function"==typeof(Se=Se.style).setProperty?Se.setProperty("display","none","important"):Se.display="none";else{Se=G.stateNode;var We=G.memoizedProps.style;We=null!=We&&We.hasOwnProperty("display")?We.display:null,Se.style.display=Dn("display",We)}}else if(6===G.tag)G.stateNode.nodeValue=x?"":G.memoizedProps;else if((23!==G.tag&&24!==G.tag||null===G.memoizedState||G===b)&&null!==G.child){G.child.return=G,G=G.child;continue}if(G===b)break;for(;null===G.sibling;){if(null===G.return||G.return===b)return;G=G.return}G.sibling.return=G.return,G=G.sibling}}function Wc(b,x){if(Gc&&"function"==typeof Gc.onCommitFiberUnmount)try{Gc.onCommitFiberUnmount(wc,x)}catch(Nt){}switch(x.tag){case 0:case 11:case 14:case 15:case 22:if(null!==(b=x.updateQueue)&&null!==(b=b.lastEffect)){var G=b=b.next;do{var Se=G,We=Se.destroy;if(Se=Se.tag,void 0!==We)if(0!=(4&Se))vg(x,G);else{Se=x;try{We()}catch(Nt){Tp(Se,Nt)}}G=G.next}while(G!==b)}break;case 1:if(Td(x),"function"==typeof(b=x.stateNode).componentWillUnmount)try{b.props=x.memoizedProps,b.state=x.memoizedState,b.componentWillUnmount()}catch(Nt){Tp(x,Nt)}break;case 5:Td(x);break;case 4:u_(b,x)}}function Fh(b){b.alternate=null,b.child=null,b.dependencies=null,b.firstEffect=null,b.lastEffect=null,b.memoizedProps=null,b.memoizedState=null,b.pendingProps=null,b.return=null,b.updateQueue=null}function a_(b){return 5===b.tag||3===b.tag||4===b.tag}function ep(b){e:{for(var x=b.return;null!==x;){if(a_(x))break e;x=x.return}throw Error(d(160))}var G=x;switch(x=G.stateNode,G.tag){case 5:var Se=!1;break;case 3:case 4:x=x.containerInfo,Se=!0;break;default:throw Error(d(161))}16&G.flags&&(Jt(x,""),G.flags&=-17);e:t:for(G=b;;){for(;null===G.sibling;){if(null===G.return||a_(G.return)){G=null;break e}G=G.return}for(G.sibling.return=G.return,G=G.sibling;5!==G.tag&&6!==G.tag&&18!==G.tag;){if(2&G.flags||null===G.child||4===G.tag)continue t;G.child.return=G,G=G.child}if(!(2&G.flags)){G=G.stateNode;break e}}Se?l_(b,G,x):lh(b,G,x)}function l_(b,x,G){var Se=b.tag,We=5===Se||6===Se;if(We)b=We?b.stateNode:b.stateNode.instance,x?8===G.nodeType?G.parentNode.insertBefore(b,x):G.insertBefore(b,x):(8===G.nodeType?(x=G.parentNode).insertBefore(b,G):(x=G).appendChild(b),null!=(G=G._reactRootContainer)||null!==x.onclick||(x.onclick=Xn));else if(4!==Se&&null!==(b=b.child))for(l_(b,x,G),b=b.sibling;null!==b;)l_(b,x,G),b=b.sibling}function lh(b,x,G){var Se=b.tag,We=5===Se||6===Se;if(We)b=We?b.stateNode:b.stateNode.instance,x?G.insertBefore(b,x):G.appendChild(b);else if(4!==Se&&null!==(b=b.child))for(lh(b,x,G),b=b.sibling;null!==b;)lh(b,x,G),b=b.sibling}function u_(b,x){for(var We,Nt,G=x,Se=!1;;){if(!Se){Se=G.return;e:for(;;){if(null===Se)throw Error(d(160));switch(We=Se.stateNode,Se.tag){case 5:Nt=!1;break e;case 3:case 4:We=We.containerInfo,Nt=!0;break e}Se=Se.return}Se=!0}if(5===G.tag||6===G.tag){e:for(var rn=b,On=G,yr=On;;)if(Wc(rn,yr),null!==yr.child&&4!==yr.tag)yr.child.return=yr,yr=yr.child;else{if(yr===On)break e;for(;null===yr.sibling;){if(null===yr.return||yr.return===On)break e;yr=yr.return}yr.sibling.return=yr.return,yr=yr.sibling}Nt?(On=G.stateNode,8===(rn=We).nodeType?rn.parentNode.removeChild(On):rn.removeChild(On)):We.removeChild(G.stateNode)}else if(4===G.tag){if(null!==G.child){We=G.stateNode.containerInfo,Nt=!0,G.child.return=G,G=G.child;continue}}else if(Wc(b,G),null!==G.child){G.child.return=G,G=G.child;continue}if(G===x)break;for(;null===G.sibling;){if(null===G.return||G.return===x)return;4===(G=G.return).tag&&(Se=!1)}G.sibling.return=G.return,G=G.sibling}}function rd(b,x){switch(x.tag){case 0:case 11:case 14:case 15:case 22:var G=x.updateQueue;if(null!==(G=null!==G?G.lastEffect:null)){var Se=G=G.next;do{3==(3&Se.tag)&&(b=Se.destroy,Se.destroy=void 0,void 0!==b&&b()),Se=Se.next}while(Se!==G)}return;case 1:return;case 5:if(null!=(G=x.stateNode)){Se=x.memoizedProps;var We=null!==b?b.memoizedProps:Se;b=x.type;var Nt=x.updateQueue;if(x.updateQueue=null,null!==Nt){for(G[Of]=Se,"input"===b&&"radio"===Se.type&&null!=Se.name&&Hi(G,Se),Ge(b,We),x=Ge(b,Se),We=0;We<Nt.length;We+=2){var rn=Nt[We],On=Nt[We+1];"style"===rn?Pr(G,On):"dangerouslySetInnerHTML"===rn?gr(G,On):"children"===rn?Jt(G,On):ie(G,rn,On,x)}switch(b){case"input":Zr(G,Se);break;case"textarea":_i(G,Se);break;case"select":b=G._wrapperState.wasMultiple,G._wrapperState.wasMultiple=!!Se.multiple,null!=(Nt=Se.value)?Fr(G,!!Se.multiple,Nt,!1):b!==!!Se.multiple&&(null!=Se.defaultValue?Fr(G,!!Se.multiple,Se.defaultValue,!0):Fr(G,!!Se.multiple,Se.multiple?[]:"",!1))}}}return;case 6:if(null===x.stateNode)throw Error(d(162));return void(x.stateNode.nodeValue=x.memoizedProps);case 3:return void((G=x.stateNode).hydrate&&(G.hydrate=!1,Ca(G.containerInfo)));case 12:return;case 13:return null!==x.memoizedState&&(j_=cl(),B_(x.child,!0)),void kg(x);case 19:return void kg(x);case 17:return;case 23:case 24:return void B_(x,null!==x.memoizedState)}throw Error(d(163))}function kg(b){var x=b.updateQueue;if(null!==x){b.updateQueue=null;var G=b.stateNode;null===G&&(G=b.stateNode=new gp),x.forEach(function(Se){var We=Bg.bind(null,b,Se);G.has(Se)||(G.add(Se),Se.then(We,We))})}}function $g(b,x){return null!==b&&(null===(b=b.memoizedState)||null!==b.dehydrated)&&null!==(x=x.memoizedState)&&null===x.dehydrated}var mp=Math.ceil,c_=he.ReactCurrentDispatcher,d_=he.ReactCurrentOwner,Ea=0,Uc=null,Xu=null,Ds=0,vp=0,uh=Sl(0),Zu=0,Y_=null,Yp=0,Gf=0,Pc=0,pg=0,Z_=null,j_=0,kh=1/0;function tp(){kh=cl()+500}var W_,Ko=null,f_=!1,G_=null,id=null,gc=!1,$h=null,Hh=90,Uh=[],hg=[],Vf=null,Ud=0,yf=null,p_=-1,yp=0,h_=0,bp=null,Bd=!1;function fd(){return 0!=(48&Ea)?cl():-1!==p_?p_:p_=cl()}function bf(b){if(0==(2&(b=b.mode)))return 1;if(0==(4&b))return 99===Ll()?1:2;if(0===yp&&(yp=Yp),0!==wf.transition){0!==h_&&(h_=null!==Z_?Z_.pendingLanes:0),b=yp;var x=4186112&~h_;return 0==(x&=-x)&&0==(x=(b=4186112&~b)&-b)&&(x=8192),x}return b=Ll(),b=wo(0!=(4&Ea)&&98===b?12:b=function(b){switch(b){case 99:return 15;case 98:return 10;case 97:case 96:return 8;case 95:return 2;default:return 0}}(b),yp)}function zf(b,x,G){if(50<Ud)throw Ud=0,yf=null,Error(d(185));if(null===(b=ch(b,x)))return null;ba(b,x,G),b===Uc&&(Pc|=x,4===Zu&&Df(b,Ds));var Se=Ll();1===x?0!=(8&Ea)&&0==(48&Ea)?np(b):(od(b,G),0===Ea&&(tp(),pc())):(0==(4&Ea)||98!==Se&&99!==Se||(null===Vf?Vf=new Set([b]):Vf.add(b)),od(b,G)),Z_=b}function ch(b,x){b.lanes|=x;var G=b.alternate;for(null!==G&&(G.lanes|=x),G=b,b=b.return;null!==b;)b.childLanes|=x,null!==(G=b.alternate)&&(G.childLanes|=x),G=b,b=b.return;return 3===G.tag?G.stateNode:null}function od(b,x){for(var G=b.callbackNode,Se=b.suspendedLanes,We=b.pingedLanes,Nt=b.expirationTimes,rn=b.pendingLanes;0<rn;){var On=31-sl(rn),yr=1<<On,Si=Nt[On];-1===Si?0!=(yr&Se)&&0==(yr&We)||(Si=x,an(yr),Nt[On]=10<=Lt?Si+250:6<=Lt?Si+5e3:-1):Si<=x&&(b.expiredLanes|=yr),rn&=~yr}if(Se=xi(b,b===Uc?Ds:0),x=Lt,0===Se)null!==G&&(G!==Bu&&hf(G),b.callbackNode=null,b.callbackPriority=0);else{if(null!==G){if(b.callbackPriority===x)return;G!==Bu&&hf(G)}15===x?(G=np.bind(null,b),null===Nd?(Nd=[G],Dc=xc(fp,Kd)):Nd.push(G),G=Bu):G=14===x?Yu(99,np.bind(null,b)):Yu(G=function(b){switch(b){case 15:case 14:return 99;case 13:case 12:case 11:case 10:return 98;case 9:case 8:case 7:case 6:case 4:case 5:return 97;case 3:case 2:case 1:return 95;case 0:return 90;default:throw Error(d(358,b))}}(x),dh.bind(null,b)),b.callbackPriority=x,b.callbackNode=G}}function dh(b){if(p_=-1,h_=yp=0,0!=(48&Ea))throw Error(d(327));var x=b.callbackNode;if(Ep()&&b.callbackNode!==x)return null;var G=xi(b,b===Uc?Ds:0);if(0===G)return null;var Se=G,We=Ea;Ea|=16;var Nt=Bh();for((Uc!==b||Ds!==Se)&&(tp(),ph(b,Se));;)try{bm();break}catch(On){_g(b,On)}if(Mc(),c_.current=Nt,Ea=We,null!==Xu?Se=0:(Uc=null,Ds=0,Se=Zu),0!=(Yp&Pc))ph(b,0);else if(0!==Se){if(2===Se&&(Ea|=64,b.hydrate&&(b.hydrate=!1,fc(b.containerInfo)),0!==(G=ts(b))&&(Se=g_(b,G))),1===Se)throw x=Y_,ph(b,0),Df(b,G),od(b,cl()),x;switch(b.finishedWork=b.current.alternate,b.finishedLanes=G,Se){case 0:case 1:throw Error(d(345));case 2:hh(b);break;case 3:if(Df(b,G),(62914560&G)===G&&10<(Se=j_+500-cl())){if(0!==xi(b,0))break;if(((We=b.suspendedLanes)&G)!==G){fd(),b.pingedLanes|=b.suspendedLanes&We;break}b.timeoutHandle=Oa(hh.bind(null,b),Se);break}hh(b);break;case 4:if(Df(b,G),(4186112&G)===G)break;for(Se=b.eventTimes,We=-1;0<G;){var rn=31-sl(G);Nt=1<<rn,(rn=Se[rn])>We&&(We=rn),G&=~Nt}if(G=We,10<(G=(120>(G=cl()-G)?120:480>G?480:1080>G?1080:1920>G?1920:3e3>G?3e3:4320>G?4320:1960*mp(G/1960))-G)){b.timeoutHandle=Oa(hh.bind(null,b),G);break}hh(b);break;case 5:hh(b);break;default:throw Error(d(329))}}return od(b,cl()),b.callbackNode===x?dh.bind(null,b):null}function Df(b,x){for(x&=~pg,b.suspendedLanes|=x&=~Pc,b.pingedLanes&=~x,b=b.expirationTimes;0<x;){var G=31-sl(x),Se=1<<G;b[G]=-1,x&=~Se}}function np(b){if(0!=(48&Ea))throw Error(d(327));if(Ep(),b===Uc&&0!=(b.expiredLanes&Ds)){var x=Ds,G=g_(b,x);0!=(Yp&Pc)&&(G=g_(b,x=xi(b,x)))}else G=g_(b,x=xi(b,0));if(0!==b.tag&&2===G&&(Ea|=64,b.hydrate&&(b.hydrate=!1,fc(b.containerInfo)),0!==(x=ts(b))&&(G=g_(b,x))),1===G)throw G=Y_,ph(b,0),Df(b,x),od(b,cl()),G;return b.finishedWork=b.current.alternate,b.finishedLanes=x,hh(b),od(b,cl()),null}function fh(b,x){var G=Ea;Ea|=1;try{return b(x)}finally{0===(Ea=G)&&(tp(),pc())}}function __(b,x){var G=Ea;Ea&=-2,Ea|=8;try{return b(x)}finally{0===(Ea=G)&&(tp(),pc())}}function Bc(b,x){kl(uh,vp),vp|=x,Yp|=x}function Rf(){vp=uh.current,wl(uh)}function ph(b,x){b.finishedWork=null,b.finishedLanes=0;var G=b.timeoutHandle;if(-1!==G&&(b.timeoutHandle=-1,Hs(G)),null!==Xu)for(G=Xu.return;null!==G;){var Se=G;switch(Se.tag){case 1:null!=(Se=Se.type.childContextTypes)&&Iu();break;case 3:Pa(),wl(Qu),wl(Ja),cr();break;case 5:Eu(Se);break;case 4:Pa();break;case 13:case 19:wl(wa);break;case 10:Hc(Se);break;case 23:case 24:Rf()}G=G.return}Uc=b,Xu=Sp(b.current,null),Ds=vp=Yp=x,Zu=0,Y_=null,pg=Pc=Gf=0}function _g(b,x){for(;;){var G=Xu;try{if(Mc(),bi.current=vf,zc){for(var Se=na.memoizedState;null!==Se;){var We=Se.queue;null!==We&&(We.pending=null),Se=Se.next}zc=!1}if(xa=0,zl=_l=na=null,qf=!1,d_.current=null,null===G||null===G.return){Zu=1,Y_=x,Xu=null;break}e:{var Nt=b,rn=G.return,On=G,yr=x;if(x=Ds,On.flags|=2048,On.firstEffect=On.lastEffect=null,null!==yr&&"object"==typeof yr&&"function"==typeof yr.then){var Si=yr;if(0==(2&On.mode)){var as=On.alternate;as?(On.updateQueue=as.updateQueue,On.memoizedState=as.memoizedState,On.lanes=as.lanes):(On.updateQueue=null,On.memoizedState=null)}var Ha=0!=(1&wa.current),go=rn;do{var po;if(po=13===go.tag){var Fa=go.memoizedState;if(null!==Fa)po=null!==Fa.dehydrated;else{var Ta=go.memoizedProps;po=void 0!==Ta.fallback&&(!0!==Ta.unstable_avoidThisFallback||!Ha)}}if(po){var ni=go.updateQueue;if(null===ni){var Tr=new Set;Tr.add(Si),go.updateQueue=Tr}else ni.add(Si);if(0==(2&go.mode)){if(go.flags|=64,On.flags|=16384,On.flags&=-2981,1===On.tag)if(null===On.alternate)On.tag=17;else{var Qr=E(-1,1);Qr.tag=2,R(On,Qr)}On.lanes|=1;break e}yr=void 0,On=x;var Bi=Nt.pingCache;if(null===Bi?(Bi=Nt.pingCache=new jf,yr=new Set,Bi.set(Si,yr)):void 0===(yr=Bi.get(Si))&&(yr=new Set,Bi.set(Si,yr)),!yr.has(On)){yr.add(On);var io=_h.bind(null,Nt,Si,On);Si.then(io,io)}go.flags|=4096,go.lanes=x;break e}go=go.return}while(null!==go);yr=Error((Mr(On.type)||"A React component")+" suspended while rendering, but no fallback UI was specified.\n\nAdd a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.")}5!==Zu&&(Zu=2),yr=ah(yr,On),go=rn;do{switch(go.tag){case 3:Nt=yr,go.flags|=4096,go.lanes|=x&=-x,F(go,H_(0,Nt,x));break e;case 1:Nt=yr;var Qa=go.stateNode;if(0==(64&go.flags)&&("function"==typeof go.type.getDerivedStateFromError||null!==Qa&&"function"==typeof Qa.componentDidCatch&&(null===id||!id.has(Qa)))){go.flags|=4096,go.lanes|=x&=-x,F(go,fg(go,Nt,x));break e}}go=go.return}while(null!==go)}Zp(G)}catch(Cl){x=Cl,Xu===G&&null!==G&&(Xu=G=G.return);continue}break}}function Bh(){var b=c_.current;return c_.current=vf,null===b?vf:b}function g_(b,x){var G=Ea;Ea|=16;var Se=Bh();for(Uc===b&&Ds===x||ph(b,x);;)try{ym();break}catch(We){_g(b,We)}if(Mc(),Ea=G,c_.current=Se,null!==Xu)throw Error(d(261));return Uc=null,Ds=0,Zu}function ym(){for(;null!==Xu;)m_(Xu)}function bm(){for(;null!==Xu&&!Vc();)m_(Xu)}function m_(b){var x=W_(b.alternate,b,vp);b.memoizedProps=b.pendingProps,null===x?Zp(b):Xu=x,d_.current=null}function Zp(b){var x=b;do{var G=x.alternate;if(b=x.return,0==(2048&x.flags)){if(null!==(G=$_(G,x,vp)))return void(Xu=G);if(24!==(G=x).tag&&23!==G.tag||null===G.memoizedState||0!=(1073741824&vp)||0==(4&G.mode)){for(var Se=0,We=G.child;null!==We;)Se|=We.lanes|We.childLanes,We=We.sibling;G.childLanes=Se}null!==b&&0==(2048&b.flags)&&(null===b.firstEffect&&(b.firstEffect=x.firstEffect),null!==x.lastEffect&&(null!==b.lastEffect&&(b.lastEffect.nextEffect=x.firstEffect),b.lastEffect=x.lastEffect),1<x.flags&&(null!==b.lastEffect?b.lastEffect.nextEffect=x:b.firstEffect=x,b.lastEffect=x))}else{if(null!==(G=sh(x)))return G.flags&=2047,void(Xu=G);null!==b&&(b.firstEffect=b.lastEffect=null,b.flags|=2048)}if(null!==(x=x.sibling))return void(Xu=x);Xu=x=b}while(null!==x);0===Zu&&(Zu=5)}function hh(b){var x=Ll();return rl(99,Hg.bind(null,b,x)),null}function Hg(b,x){do{Ep()}while(null!==$h);if(0!=(48&Ea))throw Error(d(327));var G=b.finishedWork;if(null===G)return null;if(b.finishedWork=null,b.finishedLanes=0,G===b.current)throw Error(d(177));b.callbackNode=null;var Se=G.lanes|G.childLanes,We=Se,Nt=b.pendingLanes&~We;b.pendingLanes=We,b.suspendedLanes=0,b.pingedLanes=0,b.expiredLanes&=We,b.mutableReadLanes&=We,b.entangledLanes&=We,We=b.entanglements;for(var rn=b.eventTimes,On=b.expirationTimes;0<Nt;){var yr=31-sl(Nt),Si=1<<yr;We[yr]=0,rn[yr]=-1,On[yr]=-1,Nt&=~Si}if(null!==Vf&&0==(24&Se)&&Vf.has(b)&&Vf.delete(b),b===Uc&&(Xu=Uc=null,Ds=0),1<G.flags?null!==G.lastEffect?(G.lastEffect.nextEffect=G,Se=G.firstEffect):Se=G:Se=G.firstEffect,null!==Se){if(We=Ea,Ea|=32,d_.current=null,Ei=Hl,hl(rn=pa())){if("selectionStart"in rn)On={start:rn.selectionStart,end:rn.selectionEnd};else if((Si=(On=(On=rn.ownerDocument)&&On.defaultView||window).getSelection&&On.getSelection())&&0!==Si.rangeCount){On=Si.anchorNode,Nt=Si.anchorOffset,yr=Si.focusNode,Si=Si.focusOffset;var as=0,Ha=-1,go=-1,po=0,Fa=0,Ta=rn,ni=null;t:for(;;){for(var Tr;Ta!==On||0!==Nt&&3!==Ta.nodeType||(Ha=as+Nt),Ta!==yr||0!==Si&&3!==Ta.nodeType||(go=as+Si),3===Ta.nodeType&&(as+=Ta.nodeValue.length),null!==(Tr=Ta.firstChild);)ni=Ta,Ta=Tr;for(;;){if(Ta===rn)break t;if(ni===On&&++po===Nt&&(Ha=as),ni===yr&&++Fa===Si&&(go=as),null!==(Tr=Ta.nextSibling))break;ni=(Ta=ni).parentNode}Ta=Tr}On=-1===Ha||-1===go?null:{start:Ha,end:go}}else On=null;On=On||{start:0,end:0}}else On=null;Yo={focusedElem:rn,selectionRange:On},Hl=!1,bp=null,Bd=!1,Ko=Se;do{try{gg()}catch(Cl){if(null===Ko)throw Error(d(330));Tp(Ko,Cl),Ko=Ko.nextEffect}}while(null!==Ko);bp=null,Ko=Se;do{try{for(rn=b;null!==Ko;){var Qr=Ko.flags;if(16&Qr&&Jt(Ko.stateNode,""),128&Qr){var Bi=Ko.alternate;if(null!==Bi){var io=Bi.ref;null!==io&&("function"==typeof io?io(null):io.current=null)}}switch(1038&Qr){case 2:ep(Ko),Ko.flags&=-3;break;case 6:ep(Ko),Ko.flags&=-3,rd(Ko.alternate,Ko);break;case 1024:Ko.flags&=-1025;break;case 1028:Ko.flags&=-1025,rd(Ko.alternate,Ko);break;case 4:rd(Ko.alternate,Ko);break;case 8:u_(rn,On=Ko);var va=On.alternate;Fh(On),null!==va&&Fh(va)}Ko=Ko.nextEffect}}catch(Cl){if(null===Ko)throw Error(d(330));Tp(Ko,Cl),Ko=Ko.nextEffect}}while(null!==Ko);if(io=Yo,Bi=pa(),rn=io.selectionRange,Bi!==(Qr=io.focusedElem)&&Qr&&Qr.ownerDocument&&xo(Qr.ownerDocument.documentElement,Qr)){for((null!==rn&&hl(Qr)&&(Bi=rn.start,void 0===(io=rn.end)&&(io=Bi),"selectionStart"in Qr?(Qr.selectionStart=Bi,Qr.selectionEnd=Math.min(io,Qr.value.length)):(io=(Bi=Qr.ownerDocument||document)&&Bi.defaultView||window).getSelection&&(io=io.getSelection(),On=Qr.textContent.length,va=Math.min(rn.start,On),rn=void 0===rn.end?va:Math.min(rn.end,On),!io.extend&&va>rn&&(On=rn,rn=va,va=On),On=$i(Qr,va),Nt=$i(Qr,rn),On&&Nt&&(1!==io.rangeCount||io.anchorNode!==On.node||io.anchorOffset!==On.offset||io.focusNode!==Nt.node||io.focusOffset!==Nt.offset)&&((Bi=Bi.createRange()).setStart(On.node,On.offset),io.removeAllRanges(),va>rn?(io.addRange(Bi),io.extend(Nt.node,Nt.offset)):(Bi.setEnd(Nt.node,Nt.offset),io.addRange(Bi))))),Bi=[],io=Qr);io=io.parentNode;)1===io.nodeType&&Bi.push({element:io,left:io.scrollLeft,top:io.scrollTop});for("function"==typeof Qr.focus&&Qr.focus(),Qr=0;Qr<Bi.length;Qr++)(io=Bi[Qr]).element.scrollLeft=io.left,io.element.scrollTop=io.top}Hl=!!Ei,Yo=Ei=null,b.current=G,Ko=Se;do{try{for(Qr=b;null!==Ko;){var Cs=Ko.flags;if(36&Cs&&s_(Qr,Ko.alternate,Ko),128&Cs){Bi=void 0;var Qa=Ko.ref;if(null!==Qa){var xl=Ko.stateNode;switch(Ko.tag){case 5:Bi=xl;break;default:Bi=xl}"function"==typeof Qa?Qa(Bi):Qa.current=Bi}}Ko=Ko.nextEffect}}catch(Cl){if(null===Ko)throw Error(d(330));Tp(Ko,Cl),Ko=Ko.nextEffect}}while(null!==Ko);Ko=null,Kf(),Ea=We}else b.current=G;if(gc)gc=!1,$h=b,Hh=x;else for(Ko=Se;null!==Ko;)x=Ko.nextEffect,Ko.nextEffect=null,8&Ko.flags&&((Cs=Ko).sibling=null,Cs.stateNode=null),Ko=x;if(0===(Se=b.pendingLanes)&&(id=null),1===Se?b===yf?Ud++:(Ud=0,yf=b):Ud=0,G=G.stateNode,Gc&&"function"==typeof Gc.onCommitFiberRoot)try{Gc.onCommitFiberRoot(wc,G,void 0,64==(64&G.current.flags))}catch(Cl){}if(od(b,cl()),f_)throw f_=!1,b=G_,G_=null,b;return 0!=(8&Ea)||pc(),null}function gg(){for(;null!==Ko;){var b=Ko.alternate;Bd||null===bp||(0!=(8&Ko.flags)?jt(Ko,bp)&&(Bd=!0):13===Ko.tag&&$g(b,Ko)&&jt(Ko,bp)&&(Bd=!0));var x=Ko.flags;0!=(256&x)&&U_(b,Ko),0==(512&x)||gc||(gc=!0,Yu(97,function(){return Ep(),null})),Ko=Ko.nextEffect}}function Ep(){if(90!==Hh){var b=97<Hh?97:Hh;return Hh=90,rl(b,Ug)}return!1}function mg(b,x){Uh.push(x,b),gc||(gc=!0,Yu(97,function(){return Ep(),null}))}function vg(b,x){hg.push(x,b),gc||(gc=!0,Yu(97,function(){return Ep(),null}))}function Ug(){if(null===$h)return!1;var b=$h;if($h=null,0!=(48&Ea))throw Error(d(331));var x=Ea;Ea|=32;var G=hg;hg=[];for(var Se=0;Se<G.length;Se+=2){var We=G[Se],Nt=G[Se+1],rn=We.destroy;if(We.destroy=void 0,"function"==typeof rn)try{rn()}catch(yr){if(null===Nt)throw Error(d(330));Tp(Nt,yr)}}for(G=Uh,Uh=[],Se=0;Se<G.length;Se+=2){We=G[Se],Nt=G[Se+1];try{var On=We.create;We.destroy=On()}catch(yr){if(null===Nt)throw Error(d(330));Tp(Nt,yr)}}for(On=b.current.firstEffect;null!==On;)b=On.nextEffect,On.nextEffect=null,8&On.flags&&(On.sibling=null,On.stateNode=null),On=b;return Ea=x,pc(),!0}function z_(b,x,G){R(b,x=H_(0,x=ah(G,x),1)),x=fd(),null!==(b=ch(b,1))&&(ba(b,1,x),od(b,x))}function Tp(b,x){if(3===b.tag)z_(b,b,x);else for(var G=b.return;null!==G;){if(3===G.tag){z_(G,b,x);break}if(1===G.tag){var Se=G.stateNode;if("function"==typeof G.type.getDerivedStateFromError||"function"==typeof Se.componentDidCatch&&(null===id||!id.has(Se))){var We=fg(G,b=ah(x,b),1);if(R(G,We),We=fd(),null!==(G=ch(G,1)))ba(G,1,We),od(G,We);else if("function"==typeof Se.componentDidCatch&&(null===id||!id.has(Se)))try{Se.componentDidCatch(x,b)}catch(Nt){}break}}G=G.return}}function _h(b,x,G){var Se=b.pingCache;null!==Se&&Se.delete(x),x=fd(),b.pingedLanes|=b.suspendedLanes&G,Uc===b&&(Ds&G)===G&&(4===Zu||3===Zu&&(62914560&Ds)===Ds&&500>cl()-j_?ph(b,0):pg|=G),od(b,x)}function Bg(b,x){var G=b.stateNode;null!==G&&G.delete(x),0==(x=0)&&(0==(2&(x=b.mode))?x=1:0==(4&x)?x=99===Ll()?1:2:(0===yp&&(yp=Yp),0===(x=ko(62914560&~yp))&&(x=4194304))),G=fd(),null!==(b=ch(b,x))&&(ba(b,x,G),od(b,G))}function Em(b,x,G,Se){this.tag=b,this.key=G,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=x,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=Se,this.flags=0,this.lastEffect=this.firstEffect=this.nextEffect=null,this.childLanes=this.lanes=0,this.alternate=null}function Yd(b,x,G,Se){return new Em(b,x,G,Se)}function yg(b){return!(!(b=b.prototype)||!b.isReactComponent)}function Sp(b,x){var G=b.alternate;return null===G?((G=Yd(b.tag,x,b.key,b.mode)).elementType=b.elementType,G.type=b.type,G.stateNode=b.stateNode,G.alternate=b,b.alternate=G):(G.pendingProps=x,G.type=b.type,G.flags=0,G.nextEffect=null,G.firstEffect=null,G.lastEffect=null),G.childLanes=b.childLanes,G.lanes=b.lanes,G.child=b.child,G.memoizedProps=b.memoizedProps,G.memoizedState=b.memoizedState,G.updateQueue=b.updateQueue,G.dependencies=null===(x=b.dependencies)?null:{lanes:x.lanes,firstContext:x.firstContext},G.sibling=b.sibling,G.index=b.index,G.ref=b.ref,G}function v_(b,x,G,Se,We,Nt){var rn=2;if(Se=b,"function"==typeof b)yg(b)&&(rn=1);else if("string"==typeof b)rn=5;else e:switch(b){case ce:return Jc(G.children,We,Nt,x);case Zt:rn=8,We|=16;break;case lt:rn=8,We|=1;break;case Ve:return(b=Yd(12,G,x,8|We)).elementType=Ve,b.type=Ve,b.lanes=Nt,b;case je:return(b=Yd(13,G,x,We)).type=je,b.elementType=je,b.lanes=Nt,b;case He:return(b=Yd(19,G,x,We)).elementType=He,b.lanes=Nt,b;case Ut:return J_(G,We,Nt,x);case Bt:return(b=Yd(24,G,x,We)).elementType=Bt,b.lanes=Nt,b;default:if("object"==typeof b&&null!==b)switch(b.$$typeof){case ze:rn=10;break e;case Be:rn=9;break e;case Pe:rn=11;break e;case Vt:rn=14;break e;case it:rn=16,Se=null;break e;case tn:rn=22;break e}throw Error(d(130,null==b?b:typeof b,""))}return(x=Yd(rn,G,x,We)).elementType=b,x.type=Se,x.lanes=Nt,x}function Jc(b,x,G,Se){return(b=Yd(7,b,Se,x)).lanes=G,b}function J_(b,x,G,Se){return(b=Yd(23,b,Se,x)).elementType=Ut,b.lanes=G,b}function Yh(b,x,G){return(b=Yd(6,b,null,x)).lanes=G,b}function Zh(b,x,G){return(x=Yd(4,null!==b.children?b.children:[],b.key,x)).lanes=G,x.stateNode={containerInfo:b.containerInfo,pendingChildren:null,implementation:b.implementation},x}function bg(b,x,G){this.tag=x,this.containerInfo=b,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.pendingContext=this.context=null,this.hydrate=G,this.callbackNode=null,this.callbackPriority=0,this.eventTimes=Eo(0),this.expirationTimes=Eo(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Eo(0),this.mutableSourceEagerHydrationData=null}function Eg(b,x,G){var Se=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:De,key:null==Se?null:""+Se,children:b,containerInfo:x,implementation:G}}function y_(b,x,G,Se){var We=x.current,Nt=fd(),rn=bf(We);e:if(G){t:{if(tr(G=G._reactInternals)!==G||1!==G.tag)throw Error(d(170));var On=G;do{switch(On.tag){case 3:On=On.stateNode.context;break t;case 1:if(Au(On.type)){On=On.stateNode.__reactInternalMemoizedMergedChildContext;break t}}On=On.return}while(null!==On);throw Error(d(171))}if(1===G.tag){var yr=G.type;if(Au(yr)){G=ff(G,yr,On);break e}}G=On}else G=Pu;return null===x.context?x.context=G:x.pendingContext=G,(x=E(Nt,rn)).payload={element:b},null!==(Se=void 0===Se?null:Se)&&(x.callback=Se),R(We,x),zf(We,rn,Nt),rn}function b_(b){if(!(b=b.current).child)return null;switch(b.child.tag){case 5:default:return b.child.stateNode}}function jh(b,x){if(null!==(b=b.memoizedState)&&null!==b.dehydrated){var G=b.retryLane;b.retryLane=0!==G&&G<x?G:x}}function E_(b,x){jh(b,x),(b=b.alternate)&&jh(b,x)}function Tg(b,x,G){var Se=null!=G&&null!=G.hydrationOptions&&G.hydrationOptions.mutableSources||null;if(G=new bg(b,x,null!=G&&!0===G.hydrate),x=Yd(3,null,null,2===x?7:1===x?3:0),G.current=x,x.stateNode=G,bu(x),b[Rd]=G.current,Jd(8===b.nodeType?b.parentNode:b),Se)for(b=0;b<Se.length;b++){var We=(x=Se[b])._getVersion;We=We(x._source),null==G.mutableSourceEagerHydrationData?G.mutableSourceEagerHydrationData=[x,We]:G.mutableSourceEagerHydrationData.push(x,We)}this._internalRoot=G}function T_(b){return!(!b||1!==b.nodeType&&9!==b.nodeType&&11!==b.nodeType&&(8!==b.nodeType||" react-mount-point-unstable "!==b.nodeValue))}function Gh(b,x,G,Se,We){var Nt=G._reactRootContainer;if(Nt){var rn=Nt._internalRoot;if("function"==typeof We){var On=We;We=function(){var Si=b_(rn);On.call(Si)}}y_(x,rn,b,We)}else{if(Nt=G._reactRootContainer=function(b,x){if(x||(x=!(!(x=b?9===b.nodeType?b.documentElement:b.firstChild:null)||1!==x.nodeType||!x.hasAttribute("data-reactroot"))),!x)for(var G;G=b.lastChild;)b.removeChild(G);return new Tg(b,0,x?{hydrate:!0}:void 0)}(G,Se),rn=Nt._internalRoot,"function"==typeof We){var yr=We;We=function(){var Si=b_(rn);yr.call(Si)}}__(function(){y_(x,rn,b,We)})}return b_(rn)}function Sg(b,x){var G=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!T_(x))throw Error(d(200));return Eg(b,x,null,G)}W_=function(b,x,G){var Se=x.lanes;if(null!==b)if(b.memoizedProps!==x.pendingProps||Qu.current)qd=!0;else{if(0==(G&Se)){switch(qd=!1,x.tag){case 3:ct(x),Tt();break;case 5:il(x);break;case 1:Au(x.type)&&Jl(x);break;case 4:ia(x,x.stateNode.containerInfo);break;case 10:Se=x.memoizedProps.value;var We=x.type._context;kl(Id,We._currentValue),We._currentValue=Se;break;case 13:if(null!==x.memoizedState)return 0!=(G&x.child.childLanes)?Ir(b,x,G):(kl(wa,1&wa.current),null!==(x=ma(b,x,G))?x.sibling:null);kl(wa,1&wa.current);break;case 19:if(Se=0!=(G&x.childLanes),0!=(64&b.flags)){if(Se)return Rs(b,x,G);x.flags|=64}if(null!==(We=x.memoizedState)&&(We.rendering=null,We.tail=null,We.lastEffect=null),kl(wa,wa.current),Se)break;return null;case 23:case 24:return x.lanes=0,Y(b,x,G)}return ma(b,x,G)}qd=0!=(16384&b.flags)}else qd=!1;switch(x.lanes=0,x.tag){case 2:if(Se=x.type,null!==b&&(b.alternate=null,x.alternate=null,x.flags|=2),b=x.pendingProps,We=Oc(x,Ja.current),Lu(x,G),We=Up(null,x,Se,b,We,G),x.flags|=1,"object"==typeof We&&null!==We&&"function"==typeof We.render&&void 0===We.$$typeof){if(x.tag=1,x.memoizedState=null,x.updateQueue=null,Au(Se)){var Nt=!0;Jl(x)}else Nt=!1;x.memoizedState=null!=We.state?We.state:null,bu(x);var rn=Se.getDerivedStateFromProps;"function"==typeof rn&&Ue(x,Se,rn,b),We.updater=Oe,x.stateNode=We,We._reactInternals=x,nn(x,Se,b,G),x=ke(null,x,Se,!0,Nt,G)}else x.tag=0,ac(null,x,We,G),x=x.child;return x;case 16:We=x.elementType;e:{switch(null!==b&&(b.alternate=null,x.alternate=null,x.flags|=2),b=x.pendingProps,We=(Nt=We._init)(We._payload),x.type=We,Nt=x.tag=function(b){if("function"==typeof b)return yg(b)?1:0;if(null!=b){if((b=b.$$typeof)===Pe)return 11;if(b===Vt)return 14}return 2}(We),b=Vl(We,b),Nt){case 0:x=w(null,x,We,b,G);break e;case 1:x=X(null,x,We,b,G);break e;case 11:x=oh(null,x,We,b,G);break e;case 14:x=k_(null,x,We,Vl(We.type,b),Se,G);break e}throw Error(d(306,We,""))}return x;case 0:return We=x.pendingProps,w(b,x,Se=x.type,We=x.elementType===Se?We:Vl(Se,We),G);case 1:return We=x.pendingProps,X(b,x,Se=x.type,We=x.elementType===Se?We:Vl(Se,We),G);case 3:if(ct(x),Se=x.updateQueue,null===b||null===Se)throw Error(d(282));if(Se=x.pendingProps,We=null!==(We=x.memoizedState)?We.element:null,h(b,x),q(x,Se,null,G),(Se=x.memoizedState.element)===We)Tt(),x=ma(b,x,G);else{if((Nt=(We=x.stateNode).hydrate)&&(Nc=ga(x.stateNode.containerInfo.firstChild),gu=x,Nt=sc=!0),Nt){if(null!=(b=We.mutableSourceEagerHydrationData))for(We=0;We<b.length;We+=2)(Nt=b[We])._workInProgressVersionPrimary=b[We+1],Qt.push(Nt);for(G=Zo(x,null,Se,G),x.child=G;G;)G.flags=-3&G.flags|1024,G=G.sibling}else ac(b,x,Se,G),Tt();x=x.child}return x;case 5:return il(x),null===b&&Q(x),Nt=null!==b?b.memoizedProps:null,rn=(We=x.pendingProps).children,ns(Se=x.type,We)?rn=null:null!==Nt&&ns(Se,Nt)&&(x.flags|=16),fe(b,x),ac(b,x,rn,G),x.child;case 6:return null===b&&Q(x),null;case 13:return Ir(b,x,G);case 4:return ia(x,x.stateNode.containerInfo),Se=x.pendingProps,null===b?x.child=Pi(x,null,Se,G):ac(b,x,Se,G),x.child;case 11:return We=x.pendingProps,oh(b,x,Se=x.type,We=x.elementType===Se?We:Vl(Se,We),G);case 7:return ac(b,x,x.pendingProps,G),x.child;case 8:case 12:return ac(b,x,x.pendingProps.children,G),x.child;case 10:e:{Se=x.type._context,rn=x.memoizedProps,Nt=(We=x.pendingProps).value;var On=x.type._context;if(kl(Id,On._currentValue),On._currentValue=Nt,null!==rn)if(0==(Nt=Qs(On=rn.value,Nt)?0:0|("function"==typeof Se._calculateChangedBits?Se._calculateChangedBits(On,Nt):1073741823))){if(rn.children===We.children&&!Qu.current){x=ma(b,x,G);break e}}else for(null!==(On=x.child)&&(On.return=x);null!==On;){var yr=On.dependencies;if(null!==yr){rn=On.child;for(var Si=yr.firstContext;null!==Si;){if(Si.context===Se&&0!=(Si.observedBits&Nt)){1===On.tag&&((Si=E(-1,G&-G)).tag=2,R(On,Si)),On.lanes|=G,null!==(Si=On.alternate)&&(Si.lanes|=G),cu(On.return,G),yr.lanes|=G;break}Si=Si.next}}else rn=10===On.tag&&On.type===x.type?null:On.child;if(null!==rn)rn.return=On;else for(rn=On;null!==rn;){if(rn===x){rn=null;break}if(null!==(On=rn.sibling)){On.return=rn.return,rn=On;break}rn=rn.return}On=rn}ac(b,x,We.children,G),x=x.child}return x;case 9:return We=x.type,Se=(Nt=x.pendingProps).children,Lu(x,G),Se=Se(We=Ou(We,Nt.unstable_observedBits)),x.flags|=1,ac(b,x,Se,G),x.child;case 14:return Nt=Vl(We=x.type,x.pendingProps),k_(b,x,We,Nt=Vl(We.type,Nt),Se,G);case 15:return o_(b,x,x.type,x.pendingProps,Se,G);case 17:return We=x.pendingProps,We=x.elementType===(Se=x.type)?We:Vl(Se,We),null!==b&&(b.alternate=null,x.alternate=null,x.flags|=2),x.tag=1,Au(Se)?(b=!0,Jl(x)):b=!1,Lu(x,G),gt(x,Se,We),nn(x,Se,We,G),ke(null,x,Se,!0,b,G);case 19:return Rs(b,x,G);case 23:case 24:return Y(b,x,G)}throw Error(d(156,x.tag))},Tg.prototype.render=function(b){y_(b,this._internalRoot,null,null)},Tg.prototype.unmount=function(){var b=this._internalRoot,x=b.containerInfo;y_(null,b,null,function(){x[Rd]=null})},on=function(b){13===b.tag&&(zf(b,4,fd()),E_(b,4))},si=function(b){13===b.tag&&(zf(b,67108864,fd()),E_(b,67108864))},Vi=function(b){if(13===b.tag){var x=fd(),G=bf(b);zf(b,G,x),E_(b,G)}},_o=function(b,x){return x()},mi=function(b,x,G){switch(x){case"input":if(Zr(b,G),x=G.name,"radio"===G.type&&null!=x){for(G=b;G.parentNode;)G=G.parentNode;for(G=G.querySelectorAll("input[name="+JSON.stringify(""+x)+'][type="radio"]'),x=0;x<G.length;x++){var Se=G[x];if(Se!==b&&Se.form===b.form){var We=Xd(Se);if(!We)throw Error(d(90));Br(Se),Zr(Se,We)}}}break;case"textarea":_i(b,G);break;case"select":null!=(x=G.value)&&Fr(b,!!G.multiple,x,!1)}},ar=fh,Wi=function(b,x,G,Se,We){var Nt=Ea;Ea|=4;try{return rl(98,b.bind(null,x,G,Se,We))}finally{0===(Ea=Nt)&&(tp(),pc())}},lo=function(){0==(49&Ea)&&(function(){if(null!==Vf){var b=Vf;Vf=null,b.forEach(function(x){x.expiredLanes|=24&x.pendingLanes,od(x,cl())})}pc()}(),Ep())},vo=function(b,x){var G=Ea;Ea|=2;try{return b(x)}finally{0===(Ea=G)&&(tp(),pc())}};var rv={Events:[Wu,Cc,Xd,dr,Fn,Ep,{current:!1}]},Vh={findFiberByHostInstance:Sc,bundleType:0,version:"17.0.2",rendererPackageName:"react-dom"},Tm={bundleType:Vh.bundleType,version:Vh.version,rendererPackageName:Vh.rendererPackageName,rendererConfig:Vh.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:he.ReactCurrentDispatcher,findHostInstanceByFiber:function(b){return null===(b=mt(b))?null:b.stateNode},findFiberByHostInstance:Vh.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var S_=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!S_.isDisabled&&S_.supportsFiber)try{wc=S_.inject(Tm),Gc=S_}catch(b){}}T.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=rv,T.createPortal=Sg,T.findDOMNode=function(b){if(null==b)return null;if(1===b.nodeType)return b;var x=b._reactInternals;if(void 0===x)throw"function"==typeof b.render?Error(d(188)):Error(d(268,Object.keys(b)));return null===(b=mt(x))?null:b.stateNode},T.flushSync=function(b,x){var G=Ea;if(0!=(48&G))return b(x);Ea|=1;try{if(b)return rl(99,b.bind(null,x))}finally{Ea=G,pc()}},T.hydrate=function(b,x,G){if(!T_(x))throw Error(d(200));return Gh(null,b,x,!0,G)},T.render=function(b,x,G){if(!T_(x))throw Error(d(200));return Gh(null,b,x,!1,G)},T.unmountComponentAtNode=function(b){if(!T_(b))throw Error(d(40));return!!b._reactRootContainer&&(__(function(){Gh(null,null,b,!1,function(){b._reactRootContainer=null,b[Rd]=null})}),!0)},T.unstable_batchedUpdates=fh,T.unstable_createPortal=function(b,x){return Sg(b,x,2<arguments.length&&void 0!==arguments[2]?arguments[2]:null)},T.unstable_renderSubtreeIntoContainer=function(b,x,G,Se){if(!T_(G))throw Error(d(200));if(null==b||void 0===b._reactInternals)throw Error(d(38));return Gh(b,x,G,!1,Se)},T.version="17.0.2"},88768:(v,T,i)=>{"use strict";(function r(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(r)}catch(u){console.error(u)}})(),v.exports=i(85503)},14395:(v,T,i)=>{"use strict";var p,r=i(16482),u="<<anonymous>>",d=function(){invariant(!1,"ImmutablePropTypes type checking code is stripped in production.")};d.isRequired=d;var e=function(){return d};function A(ce,lt){return function(ce,lt){return function(ce){function lt(ze,Be,Pe,je,He,Vt){for(var it=arguments.length,tn=Array(it>6?it-6:0),It=6;It<it;It++)tn[It-6]=arguments[It];return Vt=Vt||Pe,je=je||u,null!=Be[Pe]?ce.apply(void 0,[Be,Pe,je,He,Vt].concat(tn)):ze?new Error("Required "+He+" `"+Vt+"` was not specified in `"+je+"`."):void 0}var Ve=lt.bind(null,!1);return Ve.isRequired=lt.bind(null,!0),Ve}(function(ze,Be,Pe,je,He){var Vt=ze[Be];if(!lt(Vt)){var it=function(ce){var lt=typeof ce;return Array.isArray(ce)?"array":ce instanceof RegExp?"object":ce instanceof r.Iterable?"Immutable."+ce.toSource().split(" ")[0]:lt}(Vt);return new Error("Invalid "+je+" `"+He+"` of type `"+it+"` supplied to `"+Pe+"`, expected `"+ce+"`.")}return null})}("Iterable."+ce,function(Ve){return r.Iterable.isIterable(Ve)&&lt(Ve)})}(p={listOf:e,mapOf:e,orderedMapOf:e,setOf:e,orderedSetOf:e,stackOf:e,iterableOf:e,recordOf:e,shape:e,contains:e,mapContains:e,orderedMapContains:e,list:d,map:d,orderedMap:d,set:d,orderedSet:d,stack:d,seq:d,record:d,iterable:d}).iterable.indexed=A("Indexed",r.Iterable.isIndexed),p.iterable.keyed=A("Keyed",r.Iterable.isKeyed),v.exports=p},6249:(v,T)=>{"use strict";var i="function"==typeof Symbol&&Symbol.for,r=i?Symbol.for("react.element"):60103,u=i?Symbol.for("react.portal"):60106,p=i?Symbol.for("react.fragment"):60107,d=i?Symbol.for("react.strict_mode"):60108,e=i?Symbol.for("react.profiler"):60114,_=i?Symbol.for("react.provider"):60109,y=i?Symbol.for("react.context"):60110,S=i?Symbol.for("react.async_mode"):60111,A=i?Symbol.for("react.concurrent_mode"):60111,N=i?Symbol.for("react.forward_ref"):60112,L=i?Symbol.for("react.suspense"):60113,Z=i?Symbol.for("react.suspense_list"):60120,J=i?Symbol.for("react.memo"):60115,K=i?Symbol.for("react.lazy"):60116,ee=i?Symbol.for("react.block"):60121,ue=i?Symbol.for("react.fundamental"):60117,ae=i?Symbol.for("react.responder"):60118,H=i?Symbol.for("react.scope"):60119;function se(ie){if("object"==typeof ie&&null!==ie){var he=ie.$$typeof;switch(he){case r:switch(ie=ie.type){case S:case A:case p:case e:case d:case L:return ie;default:switch(ie=ie&&ie.$$typeof){case y:case N:case K:case J:case _:return ie;default:return he}}case u:return he}}}function Ee(ie){return se(ie)===A}T.AsyncMode=S,T.ConcurrentMode=A,T.ContextConsumer=y,T.ContextProvider=_,T.Element=r,T.ForwardRef=N,T.Fragment=p,T.Lazy=K,T.Memo=J,T.Portal=u,T.Profiler=e,T.StrictMode=d,T.Suspense=L,T.isAsyncMode=function(ie){return Ee(ie)||se(ie)===S},T.isConcurrentMode=Ee,T.isContextConsumer=function(ie){return se(ie)===y},T.isContextProvider=function(ie){return se(ie)===_},T.isElement=function(ie){return"object"==typeof ie&&null!==ie&&ie.$$typeof===r},T.isForwardRef=function(ie){return se(ie)===N},T.isFragment=function(ie){return se(ie)===p},T.isLazy=function(ie){return se(ie)===K},T.isMemo=function(ie){return se(ie)===J},T.isPortal=function(ie){return se(ie)===u},T.isProfiler=function(ie){return se(ie)===e},T.isStrictMode=function(ie){return se(ie)===d},T.isSuspense=function(ie){return se(ie)===L},T.isValidElementType=function(ie){return"string"==typeof ie||"function"==typeof ie||ie===p||ie===A||ie===e||ie===d||ie===L||ie===Z||"object"==typeof ie&&null!==ie&&(ie.$$typeof===K||ie.$$typeof===J||ie.$$typeof===_||ie.$$typeof===y||ie.$$typeof===N||ie.$$typeof===ue||ie.$$typeof===ae||ie.$$typeof===H||ie.$$typeof===ee)},T.typeOf=se},38308:(v,T,i)=>{"use strict";v.exports=i(6249)},1422:(v,T)=>{"use strict";var r=60103,u=60106,p=60107,d=60108,e=60114,_=60109,y=60110,S=60112,A=60113,N=60120,L=60115,Z=60116;if("function"==typeof Symbol&&Symbol.for){var H=Symbol.for;r=H("react.element"),u=H("react.portal"),p=H("react.fragment"),d=H("react.strict_mode"),e=H("react.profiler"),_=H("react.provider"),y=H("react.context"),S=H("react.forward_ref"),A=H("react.suspense"),N=H("react.suspense_list"),L=H("react.memo"),Z=H("react.lazy"),H("react.block"),H("react.server.block"),H("react.fundamental"),H("react.debug_trace_mode"),H("react.legacy_hidden")}T.isContextConsumer=function(Pe){return function(Pe){if("object"==typeof Pe&&null!==Pe){var je=Pe.$$typeof;switch(je){case r:switch(Pe=Pe.type){case p:case e:case d:case A:case N:return Pe;default:switch(Pe=Pe&&Pe.$$typeof){case y:case S:case Z:case L:case _:return Pe;default:return je}}case u:return je}}}(Pe)===y}},56261:(v,T,i)=>{"use strict";v.exports=i(1422)},55429:(v,T,i)=>{"use strict";var r=i(18228),u=60103,p=60106;T.Fragment=60107,T.StrictMode=60108,T.Profiler=60114;var d=60109,e=60110,_=60112;T.Suspense=60113;var y=60115,S=60116;if("function"==typeof Symbol&&Symbol.for){var A=Symbol.for;u=A("react.element"),p=A("react.portal"),T.Fragment=A("react.fragment"),T.StrictMode=A("react.strict_mode"),T.Profiler=A("react.profiler"),d=A("react.provider"),e=A("react.context"),_=A("react.forward_ref"),T.Suspense=A("react.suspense"),y=A("react.memo"),S=A("react.lazy")}var N="function"==typeof Symbol&&Symbol.iterator;function Z(it){for(var tn="https://reactjs.org/docs/error-decoder.html?invariant="+it,It=1;It<arguments.length;It++)tn+="&args[]="+encodeURIComponent(arguments[It]);return"Minified React error #"+it+"; visit "+tn+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var J={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},K={};function ee(it,tn,It){this.props=it,this.context=tn,this.refs=K,this.updater=It||J}function ue(){}function ae(it,tn,It){this.props=it,this.context=tn,this.refs=K,this.updater=It||J}ee.prototype.isReactComponent={},ee.prototype.setState=function(it,tn){if("object"!=typeof it&&"function"!=typeof it&&null!=it)throw Error(Z(85));this.updater.enqueueSetState(this,it,tn,"setState")},ee.prototype.forceUpdate=function(it){this.updater.enqueueForceUpdate(this,it,"forceUpdate")},ue.prototype=ee.prototype;var H=ae.prototype=new ue;H.constructor=ae,r(H,ee.prototype),H.isPureReactComponent=!0;var se={current:null},Ee=Object.prototype.hasOwnProperty,ie={key:!0,ref:!0,__self:!0,__source:!0};function he(it,tn,It){var Zt,Ut={},Bt=null,bt=null;if(null!=tn)for(Zt in void 0!==tn.ref&&(bt=tn.ref),void 0!==tn.key&&(Bt=""+tn.key),tn)Ee.call(tn,Zt)&&!ie.hasOwnProperty(Zt)&&(Ut[Zt]=tn[Zt]);var Gt=arguments.length-2;if(1===Gt)Ut.children=It;else if(1<Gt){for(var xt=Array(Gt),Xt=0;Xt<Gt;Xt++)xt[Xt]=arguments[Xt+2];Ut.children=xt}if(it&&it.defaultProps)for(Zt in Gt=it.defaultProps)void 0===Ut[Zt]&&(Ut[Zt]=Gt[Zt]);return{$$typeof:u,type:it,key:Bt,ref:bt,props:Ut,_owner:se.current}}function De(it){return"object"==typeof it&&null!==it&&it.$$typeof===u}var lt=/\/+/g;function Ve(it,tn){return"object"==typeof it&&null!==it&&null!=it.key?function(it){var tn={"=":"=0",":":"=2"};return"$"+it.replace(/[=:]/g,function(It){return tn[It]})}(""+it.key):tn.toString(36)}function ze(it,tn,It,Zt,Ut){var Bt=typeof it;("undefined"===Bt||"boolean"===Bt)&&(it=null);var bt=!1;if(null===it)bt=!0;else switch(Bt){case"string":case"number":bt=!0;break;case"object":switch(it.$$typeof){case u:case p:bt=!0}}if(bt)return Ut=Ut(bt=it),it=""===Zt?"."+Ve(bt,0):Zt,Array.isArray(Ut)?(It="",null!=it&&(It=it.replace(lt,"$&/")+"/"),ze(Ut,tn,It,"",function(Xt){return Xt})):null!=Ut&&(De(Ut)&&(Ut=function(it,tn){return{$$typeof:u,type:it.type,key:tn,ref:it.ref,props:it.props,_owner:it._owner}}(Ut,It+(!Ut.key||bt&&bt.key===Ut.key?"":(""+Ut.key).replace(lt,"$&/")+"/")+it)),tn.push(Ut)),1;if(bt=0,Zt=""===Zt?".":Zt+":",Array.isArray(it))for(var Gt=0;Gt<it.length;Gt++){var xt=Zt+Ve(Bt=it[Gt],Gt);bt+=ze(Bt,tn,It,xt,Ut)}else if("function"==typeof(xt=function(it){return null===it||"object"!=typeof it?null:"function"==typeof(it=N&&it[N]||it["@@iterator"])?it:null}(it)))for(it=xt.call(it),Gt=0;!(Bt=it.next()).done;)bt+=ze(Bt=Bt.value,tn,It,xt=Zt+Ve(Bt,Gt++),Ut);else if("object"===Bt)throw tn=""+it,Error(Z(31,"[object Object]"===tn?"object with keys {"+Object.keys(it).join(", ")+"}":tn));return bt}function Be(it,tn,It){if(null==it)return it;var Zt=[],Ut=0;return ze(it,Zt,"","",function(Bt){return tn.call(It,Bt,Ut++)}),Zt}function Pe(it){if(-1===it._status){var tn=it._result;tn=tn(),it._status=0,it._result=tn,tn.then(function(It){0===it._status&&(It=It.default,it._status=1,it._result=It)},function(It){0===it._status&&(it._status=2,it._result=It)})}if(1===it._status)return it._result;throw it._result}var je={current:null};function He(){var it=je.current;if(null===it)throw Error(Z(321));return it}var Vt={ReactCurrentDispatcher:je,ReactCurrentBatchConfig:{transition:0},ReactCurrentOwner:se,IsSomeRendererActing:{current:!1},assign:r};T.Children={map:Be,forEach:function(it,tn,It){Be(it,function(){tn.apply(this,arguments)},It)},count:function(it){var tn=0;return Be(it,function(){tn++}),tn},toArray:function(it){return Be(it,function(tn){return tn})||[]},only:function(it){if(!De(it))throw Error(Z(143));return it}},T.Component=ee,T.PureComponent=ae,T.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=Vt,T.cloneElement=function(it,tn,It){if(null==it)throw Error(Z(267,it));var Zt=r({},it.props),Ut=it.key,Bt=it.ref,bt=it._owner;if(null!=tn){if(void 0!==tn.ref&&(Bt=tn.ref,bt=se.current),void 0!==tn.key&&(Ut=""+tn.key),it.type&&it.type.defaultProps)var Gt=it.type.defaultProps;for(xt in tn)Ee.call(tn,xt)&&!ie.hasOwnProperty(xt)&&(Zt[xt]=void 0===tn[xt]&&void 0!==Gt?Gt[xt]:tn[xt])}var xt=arguments.length-2;if(1===xt)Zt.children=It;else if(1<xt){Gt=Array(xt);for(var Xt=0;Xt<xt;Xt++)Gt[Xt]=arguments[Xt+2];Zt.children=Gt}return{$$typeof:u,type:it.type,key:Ut,ref:Bt,props:Zt,_owner:bt}},T.createContext=function(it,tn){return void 0===tn&&(tn=null),(it={$$typeof:e,_calculateChangedBits:tn,_currentValue:it,_currentValue2:it,_threadCount:0,Provider:null,Consumer:null}).Provider={$$typeof:d,_context:it},it.Consumer=it},T.createElement=he,T.createFactory=function(it){var tn=he.bind(null,it);return tn.type=it,tn},T.createRef=function(){return{current:null}},T.forwardRef=function(it){return{$$typeof:_,render:it}},T.isValidElement=De,T.lazy=function(it){return{$$typeof:S,_payload:{_status:-1,_result:it},_init:Pe}},T.memo=function(it,tn){return{$$typeof:y,type:it,compare:void 0===tn?null:tn}},T.useCallback=function(it,tn){return He().useCallback(it,tn)},T.useContext=function(it,tn){return He().useContext(it,tn)},T.useDebugValue=function(){},T.useEffect=function(it,tn){return He().useEffect(it,tn)},T.useImperativeHandle=function(it,tn,It){return He().useImperativeHandle(it,tn,It)},T.useLayoutEffect=function(it,tn){return He().useLayoutEffect(it,tn)},T.useMemo=function(it,tn){return He().useMemo(it,tn)},T.useReducer=function(it,tn,It){return He().useReducer(it,tn,It)},T.useRef=function(it){return He().useRef(it)},T.useState=function(it){return He().useState(it)},T.version="17.0.2"},78139:(v,T,i)=>{"use strict";v.exports=i(55429)},59882:(v,T,i)=>{"use strict";Object.defineProperty(T,"__esModule",{value:!0});var e,u=(e=i(16482))&&e.__esModule?e:{default:e},p=i(11715);T.default=function(e){var _=arguments.length>1&&void 0!==arguments[1]?arguments[1]:u.default.Map,y=Object.keys(e);return function(){var S=arguments.length>0&&void 0!==arguments[0]?arguments[0]:_(),A=arguments[1];return S.withMutations(function(L){y.forEach(function(Z){var ee=(0,e[Z])(L.get(Z),A);(0,p.validateNextState)(ee,Z,A),L.set(Z,ee)})})}},v.exports=T.default},31208:(v,T,i)=>{"use strict";T.U=void 0;var e,p=(e=i(59882))&&e.__esModule?e:{default:e};T.U=p.default},46944:(v,T)=>{"use strict";Object.defineProperty(T,"__esModule",{value:!0}),T.default=function(i){return i&&"@@redux/INIT"===i.type?"initialState argument passed to createStore":"previous state received by the reducer"},v.exports=T.default},99319:(v,T,i)=>{"use strict";Object.defineProperty(T,"__esModule",{value:!0});var u=e(i(16482)),d=e(i(46944));function e(_){return _&&_.__esModule?_:{default:_}}T.default=function(_,y,S){var A=Object.keys(y);if(!A.length)return"Store does not have a valid reducer. Make sure the argument passed to combineReducers is an object whose values are reducers.";var N=(0,d.default)(S);if(u.default.isImmutable?!u.default.isImmutable(_):!u.default.Iterable.isIterable(_))return"The "+N+' is of unexpected type. Expected argument to be an instance of Immutable.Collection or Immutable.Record with the following properties: "'+A.join('", "')+'".';var L=_.toSeq().keySeq().toArray().filter(function(Z){return!y.hasOwnProperty(Z)});return L.length>0?"Unexpected "+(1===L.length?"property":"properties")+' "'+L.join('", "')+'" found in '+N+'. Expected to find one of the known reducer property names instead: "'+A.join('", "')+'". Unexpected properties will be ignored.':null},v.exports=T.default},11715:(v,T,i)=>{"use strict";Object.defineProperty(T,"__esModule",{value:!0}),T.validateNextState=T.getUnexpectedInvocationParameterMessage=T.getStateName=void 0;var u=y(i(46944)),d=y(i(99319)),_=y(i(95159));function y(S){return S&&S.__esModule?S:{default:S}}T.getStateName=u.default,T.getUnexpectedInvocationParameterMessage=d.default,T.validateNextState=_.default},95159:(v,T)=>{"use strict";Object.defineProperty(T,"__esModule",{value:!0}),T.default=function(i,r,u){if(void 0===i)throw new Error('Reducer "'+r+'" returned undefined when handling "'+u.type+'" action. To ignore an action, you must explicitly return the previous state.')},v.exports=T.default},88280:v=>{"use strict";var i,T="";v.exports=function(u,p){if("string"!=typeof u)throw new TypeError("expected a string");if(1===p)return u;if(2===p)return u+u;var d=u.length*p;if(i!==u||void 0===i)i=u,T="";else if(T.length>=d)return T.substr(0,d);for(;d>T.length&&p>1;)1&p&&(T+=u),p>>=1,u+=u;return T=(T+=u).substr(0,d)}},90465:v=>{"use strict";v.exports=function(i,r){if(r=r.split(":")[0],!(i=+i))return!1;switch(r){case"http":case"ws":return 80!==i;case"https":case"wss":return 443!==i;case"ftp":return 21!==i;case"gopher":return 70!==i;case"file":return!1}return 0!==i}},66952:(v,T,i)=>{const r=i(18514),u=i(29394),p=i(87931),d=i(45899);v.exports=e=>{var y,S,_=0,A={type:u.ROOT,stack:[]},N=A,L=A.stack,Z=[],J=he=>{r.error(e,"Nothing to repeat at column "+(he-1))},K=r.strToChars(e);for(y=K.length;_<y;)switch(S=K[_++],S){case"\\":switch(S=K[_++]){case"b":L.push(d.wordBoundary());break;case"B":L.push(d.nonWordBoundary());break;case"w":L.push(p.words());break;case"W":L.push(p.notWords());break;case"d":L.push(p.ints());break;case"D":L.push(p.notInts());break;case"s":L.push(p.whitespace());break;case"S":L.push(p.notWhitespace());break;default:/\d/.test(S)?L.push({type:u.REFERENCE,value:parseInt(S,10)}):L.push({type:u.CHAR,value:S.charCodeAt(0)})}break;case"^":L.push(d.begin());break;case"$":L.push(d.end());break;case"[":var ee;"^"===K[_]?(ee=!0,_++):ee=!1;var ue=r.tokenizeClass(K.slice(_),e);_+=ue[1],L.push({type:u.SET,set:ue[0],not:ee});break;case".":L.push(p.anyChar());break;case"(":var ae={type:u.GROUP,stack:[],remember:!0};"?"===(S=K[_])&&(S=K[_+1],_+=2,"="===S?ae.followedBy=!0:"!"===S?ae.notFollowedBy=!0:":"!==S&&r.error(e,`Invalid group, character '${S}' after '?' at column ${_-1}`),ae.remember=!1),L.push(ae),Z.push(N),N=ae,L=ae.stack;break;case")":0===Z.length&&r.error(e,"Unmatched ) at column "+(_-1)),L=(N=Z.pop()).options?N.options[N.options.length-1]:N.stack;break;case"|":N.options||(N.options=[N.stack],delete N.stack);var H=[];N.options.push(H),L=H;break;case"{":var Ee,ie,se=/^(\d+)(,(\d+)?)?\}/.exec(K.slice(_));null!==se?(0===L.length&&J(_),Ee=parseInt(se[1],10),ie=se[2]?se[3]?parseInt(se[3],10):1/0:Ee,_+=se[0].length,L.push({type:u.REPETITION,min:Ee,max:ie,value:L.pop()})):L.push({type:u.CHAR,value:123});break;case"?":0===L.length&&J(_),L.push({type:u.REPETITION,min:0,max:1,value:L.pop()});break;case"+":0===L.length&&J(_),L.push({type:u.REPETITION,min:1,max:1/0,value:L.pop()});break;case"*":0===L.length&&J(_),L.push({type:u.REPETITION,min:0,max:1/0,value:L.pop()});break;default:L.push({type:u.CHAR,value:S.charCodeAt(0)})}return 0!==Z.length&&r.error(e,"Unterminated group"),A},v.exports.types=u},45899:(v,T,i)=>{const r=i(29394);T.wordBoundary=()=>({type:r.POSITION,value:"b"}),T.nonWordBoundary=()=>({type:r.POSITION,value:"B"}),T.begin=()=>({type:r.POSITION,value:"^"}),T.end=()=>({type:r.POSITION,value:"$"})},87931:(v,T,i)=>{const r=i(29394),u=()=>[{type:r.RANGE,from:48,to:57}],p=()=>[{type:r.CHAR,value:95},{type:r.RANGE,from:97,to:122},{type:r.RANGE,from:65,to:90}].concat(u()),d=()=>[{type:r.CHAR,value:9},{type:r.CHAR,value:10},{type:r.CHAR,value:11},{type:r.CHAR,value:12},{type:r.CHAR,value:13},{type:r.CHAR,value:32},{type:r.CHAR,value:160},{type:r.CHAR,value:5760},{type:r.RANGE,from:8192,to:8202},{type:r.CHAR,value:8232},{type:r.CHAR,value:8233},{type:r.CHAR,value:8239},{type:r.CHAR,value:8287},{type:r.CHAR,value:12288},{type:r.CHAR,value:65279}];T.words=()=>({type:r.SET,set:p(),not:!1}),T.notWords=()=>({type:r.SET,set:p(),not:!0}),T.ints=()=>({type:r.SET,set:u(),not:!1}),T.notInts=()=>({type:r.SET,set:u(),not:!0}),T.whitespace=()=>({type:r.SET,set:d(),not:!1}),T.notWhitespace=()=>({type:r.SET,set:d(),not:!0}),T.anyChar=()=>({type:r.SET,set:[{type:r.CHAR,value:10},{type:r.CHAR,value:13},{type:r.CHAR,value:8232},{type:r.CHAR,value:8233}],not:!0})},29394:v=>{v.exports={ROOT:0,GROUP:1,POSITION:2,SET:3,RANGE:4,REPETITION:5,REFERENCE:6,CHAR:7}},18514:(v,T,i)=>{const r=i(29394),u=i(87931),d={0:0,t:9,n:10,v:11,f:12,r:13};T.strToChars=function(e){return e.replace(/(\[\\b\])|(\\)?\\(?:u([A-F0-9]{4})|x([A-F0-9]{2})|(0?[0-7]{2})|c([@A-Z[\\\]^?])|([0tnvfr]))/g,function(y,S,A,N,L,Z,J,K){if(A)return y;var ee=S?8:N?parseInt(N,16):L?parseInt(L,16):Z?parseInt(Z,8):J?"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ ?".indexOf(J):d[K],ue=String.fromCharCode(ee);return/[[\]{}^$.|?*+()]/.test(ue)&&(ue="\\"+ue),ue})},T.tokenizeClass=(e,_)=>{for(var A,N,y=[],S=/\\(?:(w)|(d)|(s)|(W)|(D)|(S))|((?:(?:\\)(.)|([^\]\\]))-(?:\\)?([^\]]))|(\])|(?:\\)?([^])/g;null!=(A=S.exec(e));)if(A[1])y.push(u.words());else if(A[2])y.push(u.ints());else if(A[3])y.push(u.whitespace());else if(A[4])y.push(u.notWords());else if(A[5])y.push(u.notInts());else if(A[6])y.push(u.notWhitespace());else if(A[7])y.push({type:r.RANGE,from:(A[8]||A[9]).charCodeAt(0),to:A[10].charCodeAt(0)});else{if(!(N=A[12]))return[y,S.lastIndex];y.push({type:r.CHAR,value:N.charCodeAt(0)})}T.error(_,"Unterminated character class")},T.error=(e,_)=>{throw new SyntaxError("Invalid regular expression: /"+e+"/: "+_)}},26215:(v,T,i)=>{"use strict";i.d(T,{X:()=>p});var r=i(79765),u=i(77971);class p extends r.xQ{constructor(e){super(),this._value=e}get value(){return this.getValue()}_subscribe(e){const _=super._subscribe(e);return _&&!_.closed&&e.next(this._value),_}getValue(){if(this.hasError)throw this.thrownError;if(this.closed)throw new u.N;return this._value}next(e){super.next(this._value=e)}}},23098:(v,T,i)=>{"use strict";i.d(T,{P:()=>e});var r=i(59193),u=i(25917),p=i(40205);class e{constructor(y,S,A){this.kind=y,this.value=S,this.error=A,this.hasValue="N"===y}observe(y){switch(this.kind){case"N":return y.next&&y.next(this.value);case"E":return y.error&&y.error(this.error);case"C":return y.complete&&y.complete()}}do(y,S,A){switch(this.kind){case"N":return y&&y(this.value);case"E":return S&&S(this.error);case"C":return A&&A()}}accept(y,S,A){return y&&"function"==typeof y.next?this.observe(y):this.do(y,S,A)}toObservable(){switch(this.kind){case"N":return(0,u.of)(this.value);case"E":return(0,p._)(this.error);case"C":return(0,r.c)()}throw new Error("unexpected notification kind value")}static createNext(y){return void 0!==y?new e("N",y):e.undefinedValueNotification}static createError(y){return new e("E",void 0,y)}static createComplete(){return e.completeNotification}}e.completeNotification=new e("C"),e.undefinedValueNotification=new e("N",void 0)},18891:(v,T,i)=>{"use strict";i.d(T,{y:()=>A});var r=i(77393),p=i(29181),d=i(46490),_=i(16554),y=i(34022),S=i(82494);let A=(()=>{class L{constructor(J){this._isScalar=!1,J&&(this._subscribe=J)}lift(J){const K=new L;return K.source=this,K.operator=J,K}subscribe(J,K,ee){const{operator:ue}=this,ae=function(L,Z,J){if(L){if(L instanceof r.L)return L;if(L[p.b])return L[p.b]()}return L||Z||J?new r.L(L,Z,J):new r.L(d.c)}(J,K,ee);if(ae.add(ue?ue.call(ae,this.source):this.source||S.v.useDeprecatedSynchronousErrorHandling&&!ae.syncErrorThrowable?this._subscribe(ae):this._trySubscribe(ae)),S.v.useDeprecatedSynchronousErrorHandling&&ae.syncErrorThrowable&&(ae.syncErrorThrowable=!1,ae.syncErrorThrown))throw ae.syncErrorValue;return ae}_trySubscribe(J){try{return this._subscribe(J)}catch(K){S.v.useDeprecatedSynchronousErrorHandling&&(J.syncErrorThrown=!0,J.syncErrorValue=K),function(L){for(;L;){const{closed:Z,destination:J,isStopped:K}=L;if(Z||K)return!1;L=J&&J instanceof r.L?J:null}return!0}(J)?J.error(K):console.warn(K)}}forEach(J,K){return new(K=N(K))((ee,ue)=>{let ae;ae=this.subscribe(H=>{try{J(H)}catch(se){ue(se),ae&&ae.unsubscribe()}},ue,ee)})}_subscribe(J){const{source:K}=this;return K&&K.subscribe(J)}[_.L](){return this}pipe(...J){return 0===J.length?this:(0,y.U)(J)(this)}toPromise(J){return new(J=N(J))((K,ee)=>{let ue;this.subscribe(ae=>ue=ae,ae=>ee(ae),()=>K(ue))})}}return L.create=Z=>new L(Z),L})();function N(L){if(L||(L=S.v.Promise||Promise),!L)throw new Error("no Promise impl found");return L}},46490:(v,T,i)=>{"use strict";i.d(T,{c:()=>p});var r=i(82494),u=i(54449);const p={closed:!0,next(d){},error(d){if(r.v.useDeprecatedSynchronousErrorHandling)throw d;(0,u.z)(d)},complete(){}}},55197:(v,T,i)=>{"use strict";i.d(T,{L:()=>u});var r=i(77393);class u extends r.L{notifyNext(d,e,_,y,S){this.destination.next(e)}notifyError(d,e){this.destination.error(d)}notifyComplete(d){this.destination.complete()}}},80226:(v,T,i)=>{"use strict";i.d(T,{t:()=>Z});var r=i(79765),u=i(36465),d=i(16102);const y=new class extends d.v{}(class extends u.o{constructor(ee,ue){super(ee,ue),this.scheduler=ee,this.work=ue}schedule(ee,ue=0){return ue>0?super.schedule(ee,ue):(this.delay=ue,this.state=ee,this.scheduler.flush(this),this)}execute(ee,ue){return ue>0||this.closed?super.execute(ee,ue):this._execute(ee,ue)}requestAsyncId(ee,ue,ae=0){return null!==ae&&ae>0||null===ae&&this.delay>0?super.requestAsyncId(ee,ue,ae):ee.flush(this)}});var S=i(75319),A=i(59746),N=i(77971),L=i(78858);class Z extends r.xQ{constructor(ee=Number.POSITIVE_INFINITY,ue=Number.POSITIVE_INFINITY,ae){super(),this.scheduler=ae,this._events=[],this._infiniteTimeWindow=!1,this._bufferSize=ee<1?1:ee,this._windowTime=ue<1?1:ue,ue===Number.POSITIVE_INFINITY?(this._infiniteTimeWindow=!0,this.next=this.nextInfiniteTimeWindow):this.next=this.nextTimeWindow}nextInfiniteTimeWindow(ee){if(!this.isStopped){const ue=this._events;ue.push(ee),ue.length>this._bufferSize&&ue.shift()}super.next(ee)}nextTimeWindow(ee){this.isStopped||(this._events.push(new J(this._getNow(),ee)),this._trimBufferThenGetEvents()),super.next(ee)}_subscribe(ee){const ue=this._infiniteTimeWindow,ae=ue?this._events:this._trimBufferThenGetEvents(),H=this.scheduler,se=ae.length;let Ee;if(this.closed)throw new N.N;if(this.isStopped||this.hasError?Ee=S.w.EMPTY:(this.observers.push(ee),Ee=new L.W(this,ee)),H&&ee.add(ee=new A.ht(ee,H)),ue)for(let ie=0;ie<se&&!ee.closed;ie++)ee.next(ae[ie]);else for(let ie=0;ie<se&&!ee.closed;ie++)ee.next(ae[ie].value);return this.hasError?ee.error(this.thrownError):this.isStopped&&ee.complete(),Ee}_getNow(){return(this.scheduler||y).now()}_trimBufferThenGetEvents(){const ee=this._getNow(),ue=this._bufferSize,ae=this._windowTime,H=this._events,se=H.length;let Ee=0;for(;Ee<se&&!(ee-H[Ee].time<ae);)Ee++;return se>ue&&(Ee=Math.max(Ee,se-ue)),Ee>0&&H.splice(0,Ee),H}}class J{constructor(ee,ue){this.time=ee,this.value=ue}}},79765:(v,T,i)=>{"use strict";i.d(T,{Yc:()=>y,xQ:()=>S});var r=i(18891),u=i(77393),p=i(75319),d=i(77971),e=i(78858),_=i(29181);class y extends u.L{constructor(L){super(L),this.destination=L}}let S=(()=>{class N extends r.y{constructor(){super(),this.observers=[],this.closed=!1,this.isStopped=!1,this.hasError=!1,this.thrownError=null}[_.b](){return new y(this)}lift(Z){const J=new A(this,this);return J.operator=Z,J}next(Z){if(this.closed)throw new d.N;if(!this.isStopped){const{observers:J}=this,K=J.length,ee=J.slice();for(let ue=0;ue<K;ue++)ee[ue].next(Z)}}error(Z){if(this.closed)throw new d.N;this.hasError=!0,this.thrownError=Z,this.isStopped=!0;const{observers:J}=this,K=J.length,ee=J.slice();for(let ue=0;ue<K;ue++)ee[ue].error(Z);this.observers.length=0}complete(){if(this.closed)throw new d.N;this.isStopped=!0;const{observers:Z}=this,J=Z.length,K=Z.slice();for(let ee=0;ee<J;ee++)K[ee].complete();this.observers.length=0}unsubscribe(){this.isStopped=!0,this.closed=!0,this.observers=null}_trySubscribe(Z){if(this.closed)throw new d.N;return super._trySubscribe(Z)}_subscribe(Z){if(this.closed)throw new d.N;return this.hasError?(Z.error(this.thrownError),p.w.EMPTY):this.isStopped?(Z.complete(),p.w.EMPTY):(this.observers.push(Z),new e.W(this,Z))}asObservable(){const Z=new r.y;return Z.source=this,Z}}return N.create=(L,Z)=>new A(L,Z),N})();class A extends S{constructor(L,Z){super(),this.destination=L,this.source=Z}next(L){const{destination:Z}=this;Z&&Z.next&&Z.next(L)}error(L){const{destination:Z}=this;Z&&Z.error&&this.destination.error(L)}complete(){const{destination:L}=this;L&&L.complete&&this.destination.complete()}_subscribe(L){const{source:Z}=this;return Z?this.source.subscribe(L):p.w.EMPTY}}},78858:(v,T,i)=>{"use strict";i.d(T,{W:()=>u});var r=i(75319);class u extends r.w{constructor(d,e){super(),this.subject=d,this.subscriber=e,this.closed=!1}unsubscribe(){if(this.closed)return;this.closed=!0;const d=this.subject,e=d.observers;if(this.subject=null,!e||0===e.length||d.isStopped||d.closed)return;const _=e.indexOf(this.subscriber);-1!==_&&e.splice(_,1)}}},77393:(v,T,i)=>{"use strict";i.d(T,{L:()=>y});var r=i(69105),u=i(46490),p=i(75319),d=i(29181),e=i(82494),_=i(54449);class y extends p.w{constructor(N,L,Z){switch(super(),this.syncErrorValue=null,this.syncErrorThrown=!1,this.syncErrorThrowable=!1,this.isStopped=!1,arguments.length){case 0:this.destination=u.c;break;case 1:if(!N){this.destination=u.c;break}if("object"==typeof N){N instanceof y?(this.syncErrorThrowable=N.syncErrorThrowable,this.destination=N,N.add(this)):(this.syncErrorThrowable=!0,this.destination=new S(this,N));break}default:this.syncErrorThrowable=!0,this.destination=new S(this,N,L,Z)}}[d.b](){return this}static create(N,L,Z){const J=new y(N,L,Z);return J.syncErrorThrowable=!1,J}next(N){this.isStopped||this._next(N)}error(N){this.isStopped||(this.isStopped=!0,this._error(N))}complete(){this.isStopped||(this.isStopped=!0,this._complete())}unsubscribe(){this.closed||(this.isStopped=!0,super.unsubscribe())}_next(N){this.destination.next(N)}_error(N){this.destination.error(N),this.unsubscribe()}_complete(){this.destination.complete(),this.unsubscribe()}_unsubscribeAndRecycle(){const{_parentOrParents:N}=this;return this._parentOrParents=null,this.unsubscribe(),this.closed=!1,this.isStopped=!1,this._parentOrParents=N,this}}class S extends y{constructor(N,L,Z,J){super(),this._parentSubscriber=N;let K,ee=this;(0,r.m)(L)?K=L:L&&(K=L.next,Z=L.error,J=L.complete,L!==u.c&&(ee=Object.create(L),(0,r.m)(ee.unsubscribe)&&this.add(ee.unsubscribe.bind(ee)),ee.unsubscribe=this.unsubscribe.bind(this))),this._context=ee,this._next=K,this._error=Z,this._complete=J}next(N){if(!this.isStopped&&this._next){const{_parentSubscriber:L}=this;e.v.useDeprecatedSynchronousErrorHandling&&L.syncErrorThrowable?this.__tryOrSetError(L,this._next,N)&&this.unsubscribe():this.__tryOrUnsub(this._next,N)}}error(N){if(!this.isStopped){const{_parentSubscriber:L}=this,{useDeprecatedSynchronousErrorHandling:Z}=e.v;if(this._error)Z&&L.syncErrorThrowable?(this.__tryOrSetError(L,this._error,N),this.unsubscribe()):(this.__tryOrUnsub(this._error,N),this.unsubscribe());else if(L.syncErrorThrowable)Z?(L.syncErrorValue=N,L.syncErrorThrown=!0):(0,_.z)(N),this.unsubscribe();else{if(this.unsubscribe(),Z)throw N;(0,_.z)(N)}}}complete(){if(!this.isStopped){const{_parentSubscriber:N}=this;if(this._complete){const L=()=>this._complete.call(this._context);e.v.useDeprecatedSynchronousErrorHandling&&N.syncErrorThrowable?(this.__tryOrSetError(N,L),this.unsubscribe()):(this.__tryOrUnsub(L),this.unsubscribe())}else this.unsubscribe()}}__tryOrUnsub(N,L){try{N.call(this._context,L)}catch(Z){if(this.unsubscribe(),e.v.useDeprecatedSynchronousErrorHandling)throw Z;(0,_.z)(Z)}}__tryOrSetError(N,L,Z){if(!e.v.useDeprecatedSynchronousErrorHandling)throw new Error("bad call");try{L.call(this._context,Z)}catch(J){return e.v.useDeprecatedSynchronousErrorHandling?(N.syncErrorValue=J,N.syncErrorThrown=!0,!0):((0,_.z)(J),!0)}return!1}_unsubscribe(){const{_parentSubscriber:N}=this;this._context=null,this._parentSubscriber=null,N.unsubscribe()}}},75319:(v,T,i)=>{"use strict";i.d(T,{w:()=>_});var r=i(59796),u=i(81555),p=i(69105);const e=(()=>{function S(A){return Error.call(this),this.message=A?`${A.length} errors occurred during unsubscription:\n${A.map((N,L)=>`${L+1}) ${N.toString()}`).join("\n ")}`:"",this.name="UnsubscriptionError",this.errors=A,this}return S.prototype=Object.create(Error.prototype),S})();class _{constructor(A){this.closed=!1,this._parentOrParents=null,this._subscriptions=null,A&&(this._ctorUnsubscribe=!0,this._unsubscribe=A)}unsubscribe(){let A;if(this.closed)return;let{_parentOrParents:N,_ctorUnsubscribe:L,_unsubscribe:Z,_subscriptions:J}=this;if(this.closed=!0,this._parentOrParents=null,this._subscriptions=null,N instanceof _)N.remove(this);else if(null!==N)for(let K=0;K<N.length;++K)N[K].remove(this);if((0,p.m)(Z)){L&&(this._unsubscribe=void 0);try{Z.call(this)}catch(K){A=K instanceof e?y(K.errors):[K]}}if((0,r.k)(J)){let K=-1,ee=J.length;for(;++K<ee;){const ue=J[K];if((0,u.K)(ue))try{ue.unsubscribe()}catch(ae){A=A||[],ae instanceof e?A=A.concat(y(ae.errors)):A.push(ae)}}}if(A)throw new e(A)}add(A){let N=A;if(!A)return _.EMPTY;switch(typeof A){case"function":N=new _(A);case"object":if(N===this||N.closed||"function"!=typeof N.unsubscribe)return N;if(this.closed)return N.unsubscribe(),N;if(!(N instanceof _)){const J=N;N=new _,N._subscriptions=[J]}break;default:throw new Error("unrecognized teardown "+A+" added to Subscription.")}let{_parentOrParents:L}=N;if(null===L)N._parentOrParents=this;else if(L instanceof _){if(L===this)return N;N._parentOrParents=[L,this]}else{if(-1!==L.indexOf(this))return N;L.push(this)}const Z=this._subscriptions;return null===Z?this._subscriptions=[N]:Z.push(N),N}remove(A){const N=this._subscriptions;if(N){const L=N.indexOf(A);-1!==L&&N.splice(L,1)}}}var S;function y(S){return S.reduce((A,N)=>A.concat(N instanceof e?N.errors:N),[])}_.EMPTY=((S=new _).closed=!0,S)},82494:(v,T,i)=>{"use strict";i.d(T,{v:()=>u});let r=!1;const u={Promise:void 0,set useDeprecatedSynchronousErrorHandling(p){if(p){const d=new Error;console.warn("DEPRECATED! RxJS was set to use deprecated synchronous error handling behavior by code at: \n"+d.stack)}else r&&console.log("RxJS: Back to a better error behavior. Thank you. <3");r=p},get useDeprecatedSynchronousErrorHandling(){return r}}},85345:(v,T,i)=>{"use strict";i.d(T,{IY:()=>d,Ds:()=>_,ft:()=>S});var r=i(77393),u=i(18891),p=i(87444);class d extends r.L{constructor(N){super(),this.parent=N}_next(N){this.parent.notifyNext(N)}_error(N){this.parent.notifyError(N),this.unsubscribe()}_complete(){this.parent.notifyComplete(),this.unsubscribe()}}class _ extends r.L{notifyNext(N){this.destination.next(N)}notifyError(N){this.destination.error(N)}notifyComplete(){this.destination.complete()}}function S(A,N){if(!N.closed)return A instanceof u.y?A.subscribe(N):(0,p.s)(A)(N)}},52441:(v,T,i)=>{"use strict";i.d(T,{c:()=>e,N:()=>_});var r=i(79765),u=i(18891),p=i(75319),d=i(51307);class e extends u.y{constructor(L,Z){super(),this.source=L,this.subjectFactory=Z,this._refCount=0,this._isComplete=!1}_subscribe(L){return this.getSubject().subscribe(L)}getSubject(){const L=this._subject;return(!L||L.isStopped)&&(this._subject=this.subjectFactory()),this._subject}connect(){let L=this._connection;return L||(this._isComplete=!1,L=this._connection=new p.w,L.add(this.source.subscribe(new y(this.getSubject(),this))),L.closed&&(this._connection=null,L=p.w.EMPTY)),L}refCount(){return(0,d.x)()(this)}}const _=(()=>{const N=e.prototype;return{operator:{value:null},_refCount:{value:0,writable:!0},_subject:{value:null,writable:!0},_connection:{value:null,writable:!0},_subscribe:{value:N._subscribe},_isComplete:{value:N._isComplete,writable:!0},getSubject:{value:N.getSubject},connect:{value:N.connect},refCount:{value:N.refCount}}})();class y extends r.Yc{constructor(L,Z){super(L),this.connectable=Z}_error(L){this._unsubscribe(),super._error(L)}_complete(){this.connectable._isComplete=!0,this._unsubscribe(),super._complete()}_unsubscribe(){const L=this.connectable;if(L){this.connectable=null;const Z=L._connection;L._refCount=0,L._subject=null,L._connection=null,Z&&Z.unsubscribe()}}}},9112:(v,T,i)=>{"use strict";i.d(T,{aj:()=>y});var r=i(54869),u=i(59796),p=i(55197),d=i(20509),e=i(56693);const _={};function y(...N){let L,Z;return(0,r.K)(N[N.length-1])&&(Z=N.pop()),"function"==typeof N[N.length-1]&&(L=N.pop()),1===N.length&&(0,u.k)(N[0])&&(N=N[0]),(0,e.n)(N,Z).lift(new S(L))}class S{constructor(L){this.resultSelector=L}call(L,Z){return Z.subscribe(new A(L,this.resultSelector))}}class A extends p.L{constructor(L,Z){super(L),this.resultSelector=Z,this.active=0,this.values=[],this.observables=[]}_next(L){this.values.push(_),this.observables.push(L)}_complete(){const L=this.observables,Z=L.length;if(0===Z)this.destination.complete();else{this.active=Z,this.toRespond=Z;for(let J=0;J<Z;J++)this.add((0,d.D)(this,L[J],void 0,J))}}notifyComplete(L){0==(this.active-=1)&&this.destination.complete()}notifyNext(L,Z,J){const K=this.values,ue=this.toRespond?K[J]===_?--this.toRespond:this.toRespond:0;K[J]=Z,0===ue&&(this.resultSelector?this._tryResultSelector(K):this.destination.next(K.slice()))}_tryResultSelector(L){let Z;try{Z=this.resultSelector.apply(this,L)}catch(J){return void this.destination.error(J)}this.destination.next(Z)}}},58071:(v,T,i)=>{"use strict";i.d(T,{z:()=>d});var r=i(25917),u=i(63282);function d(...e){return(0,u.J)(1)((0,r.of)(...e))}},59193:(v,T,i)=>{"use strict";i.d(T,{E:()=>u,c:()=>p});var r=i(18891);const u=new r.y(e=>e.complete());function p(e){return e?function(e){return new r.y(_=>e.schedule(()=>_.complete()))}(e):u}},35758:(v,T,i)=>{"use strict";i.d(T,{D:()=>_});var r=i(18891),u=i(59796),p=i(88002),d=i(81555),e=i(94402);function _(...S){if(1===S.length){const A=S[0];if((0,u.k)(A))return y(A,null);if((0,d.K)(A)&&Object.getPrototypeOf(A)===Object.prototype){const N=Object.keys(A);return y(N.map(L=>A[L]),N)}}if("function"==typeof S[S.length-1]){const A=S.pop();return y(S=1===S.length&&(0,u.k)(S[0])?S[0]:S,null).pipe((0,p.U)(N=>A(...N)))}return y(S,null)}function y(S,A){return new r.y(N=>{const L=S.length;if(0===L)return void N.complete();const Z=new Array(L);let J=0,K=0;for(let ee=0;ee<L;ee++){const ue=(0,e.D)(S[ee]);let ae=!1;N.add(ue.subscribe({next:H=>{ae||(ae=!0,K++),Z[ee]=H},error:H=>N.error(H),complete:()=>{J++,(J===L||!ae)&&(K===L&&N.next(A?A.reduce((H,se,Ee)=>(H[se]=Z[Ee],H),{}):Z),N.complete())}}))}})}},94402:(v,T,i)=>{"use strict";i.d(T,{D:()=>ee});var r=i(18891),u=i(87444),p=i(75319),d=i(16554),y=i(94087),S=i(20377),L=i(44072),Z=i(69489);function ee(ue,ae){return ae?function(ue,ae){if(null!=ue){if(function(ue){return ue&&"function"==typeof ue[d.L]}(ue))return function(ue,ae){return new r.y(H=>{const se=new p.w;return se.add(ae.schedule(()=>{const Ee=ue[d.L]();se.add(Ee.subscribe({next(ie){se.add(ae.schedule(()=>H.next(ie)))},error(ie){se.add(ae.schedule(()=>H.error(ie)))},complete(){se.add(ae.schedule(()=>H.complete()))}}))})),se})}(ue,ae);if((0,L.t)(ue))return function(ue,ae){return new r.y(H=>{const se=new p.w;return se.add(ae.schedule(()=>ue.then(Ee=>{se.add(ae.schedule(()=>{H.next(Ee),se.add(ae.schedule(()=>H.complete()))}))},Ee=>{se.add(ae.schedule(()=>H.error(Ee)))}))),se})}(ue,ae);if((0,Z.z)(ue))return(0,y.r)(ue,ae);if(function(ue){return ue&&"function"==typeof ue[S.hZ]}(ue)||"string"==typeof ue)return function(ue,ae){if(!ue)throw new Error("Iterable cannot be null");return new r.y(H=>{const se=new p.w;let Ee;return se.add(()=>{Ee&&"function"==typeof Ee.return&&Ee.return()}),se.add(ae.schedule(()=>{Ee=ue[S.hZ](),se.add(ae.schedule(function(){if(H.closed)return;let ie,he;try{const ge=Ee.next();ie=ge.value,he=ge.done}catch(ge){return void H.error(ge)}he?H.complete():(H.next(ie),this.schedule())}))})),se})}(ue,ae)}throw new TypeError((null!==ue&&typeof ue||ue)+" is not observable")}(ue,ae):ue instanceof r.y?ue:new r.y((0,u.s)(ue))}},56693:(v,T,i)=>{"use strict";i.d(T,{n:()=>d});var r=i(18891),u=i(55015),p=i(94087);function d(e,_){return _?(0,p.r)(e,_):new r.y((0,u.V)(e))}},22759:(v,T,i)=>{"use strict";i.d(T,{R:()=>_});var r=i(18891),u=i(59796),p=i(69105),d=i(88002);function _(L,Z,J,K){return(0,p.m)(J)&&(K=J,J=void 0),K?_(L,Z,J).pipe((0,d.U)(ee=>(0,u.k)(ee)?K(...ee):K(ee))):new r.y(ee=>{y(L,Z,function(ae){ee.next(arguments.length>1?Array.prototype.slice.call(arguments):ae)},ee,J)})}function y(L,Z,J,K,ee){let ue;if(function(L){return L&&"function"==typeof L.addEventListener&&"function"==typeof L.removeEventListener}(L)){const ae=L;L.addEventListener(Z,J,ee),ue=()=>ae.removeEventListener(Z,J,ee)}else if(function(L){return L&&"function"==typeof L.on&&"function"==typeof L.off}(L)){const ae=L;L.on(Z,J),ue=()=>ae.off(Z,J)}else if(function(L){return L&&"function"==typeof L.addListener&&"function"==typeof L.removeListener}(L)){const ae=L;L.addListener(Z,J),ue=()=>ae.removeListener(Z,J)}else{if(!L||!L.length)throw new TypeError("Invalid event target");for(let ae=0,H=L.length;ae<H;ae++)y(L[ae],Z,J,K,ee)}K.add(ue)}},66682:(v,T,i)=>{"use strict";i.d(T,{T:()=>e});var r=i(18891),u=i(54869),p=i(63282),d=i(56693);function e(..._){let y=Number.POSITIVE_INFINITY,S=null,A=_[_.length-1];return(0,u.K)(A)?(S=_.pop(),_.length>1&&"number"==typeof _[_.length-1]&&(y=_.pop())):"number"==typeof A&&(y=_.pop()),null===S&&1===_.length&&_[0]instanceof r.y?_[0]:(0,p.J)(y)((0,d.n)(_,S))}},17757:(v,T,i)=>{"use strict";i.d(T,{C:()=>p});var r=i(18891),u=i(98640);const p=new r.y(u.Z)},25917:(v,T,i)=>{"use strict";i.d(T,{of:()=>d});var r=i(54869),u=i(56693),p=i(94087);function d(...e){let _=e[e.length-1];return(0,r.K)(_)?(e.pop(),(0,p.r)(e,_)):(0,u.n)(e)}},40205:(v,T,i)=>{"use strict";i.d(T,{_:()=>u});var r=i(18891);function u(d,e){return new r.y(e?_=>e.schedule(p,0,{error:d,subscriber:_}):_=>_.error(d))}function p({error:d,subscriber:e}){e.error(d)}},46797:(v,T,i)=>{"use strict";i.d(T,{H:()=>e});var r=i(18891),u=i(33637),p=i(26561),d=i(54869);function e(y=0,S,A){let N=-1;return(0,p.k)(S)?N=Number(S)<1?1:Number(S):(0,d.K)(S)&&(A=S),(0,d.K)(A)||(A=u.P),new r.y(L=>{const Z=(0,p.k)(y)?y:+y-A.now();return A.schedule(_,Z,{index:0,period:N,subscriber:L})})}function _(y){const{index:S,period:A,subscriber:N}=y;if(N.next(S),!N.closed){if(-1===A)return N.complete();y.index=S+1,this.schedule(y,A)}}},5304:(v,T,i)=>{"use strict";i.d(T,{K:()=>u});var r=i(85345);function u(e){return function(y){const S=new p(e),A=y.lift(S);return S.caught=A}}class p{constructor(_){this.selector=_}call(_,y){return y.subscribe(new d(_,this.selector,this.caught))}}class d extends r.Ds{constructor(_,y,S){super(_),this.selector=y,this.caught=S}error(_){if(!this.isStopped){let y;try{y=this.selector(_,this.caught)}catch(N){return void super.error(N)}this._unsubscribeAndRecycle();const S=new r.IY(this);this.add(S);const A=(0,r.ft)(y,S);A!==S&&this.add(A)}}}},94612:(v,T,i)=>{"use strict";i.d(T,{b:()=>u});var r=i(19773);function u(p,d){return(0,r.zg)(p,d,1)}},95242:(v,T,i)=>{"use strict";i.d(T,{d:()=>u});var r=i(77393);function u(e=null){return _=>_.lift(new p(e))}class p{constructor(_){this.defaultValue=_}call(_,y){return y.subscribe(new d(_,this.defaultValue))}}class d extends r.L{constructor(_,y){super(_),this.defaultValue=y,this.isEmpty=!0}_next(_){this.isEmpty=!1,this.destination.next(_)}_complete(){this.isEmpty&&this.destination.next(this.defaultValue),this.destination.complete()}}},71289:(v,T,i)=>{"use strict";i.d(T,{g:()=>e});var r=i(33637),p=i(77393),d=i(23098);function e(A,N=r.P){const Z=function(A){return A instanceof Date&&!isNaN(+A)}(A)?+A-N.now():Math.abs(A);return J=>J.lift(new _(Z,N))}class _{constructor(N,L){this.delay=N,this.scheduler=L}call(N,L){return L.subscribe(new y(N,this.delay,this.scheduler))}}class y extends p.L{constructor(N,L,Z){super(N),this.delay=L,this.scheduler=Z,this.queue=[],this.active=!1,this.errored=!1}static dispatch(N){const L=N.source,Z=L.queue,J=N.scheduler,K=N.destination;for(;Z.length>0&&Z[0].time-J.now()<=0;)Z.shift().notification.observe(K);if(Z.length>0){const ee=Math.max(0,Z[0].time-J.now());this.schedule(N,ee)}else this.unsubscribe(),L.active=!1}_schedule(N){this.active=!0,this.destination.add(N.schedule(y.dispatch,this.delay,{source:this,destination:this.destination,scheduler:N}))}scheduleNotification(N){if(!0===this.errored)return;const L=this.scheduler,Z=new S(L.now()+this.delay,N);this.queue.push(Z),!1===this.active&&this._schedule(L)}_next(N){this.scheduleNotification(d.P.createNext(N))}_error(N){this.errored=!0,this.queue=[],this.destination.error(N),this.unsubscribe()}_complete(){this.scheduleNotification(d.P.createComplete()),this.unsubscribe()}}class S{constructor(N,L){this.time=N,this.notification=L}}},87519:(v,T,i)=>{"use strict";i.d(T,{x:()=>u});var r=i(77393);function u(e,_){return y=>y.lift(new p(e,_))}class p{constructor(_,y){this.compare=_,this.keySelector=y}call(_,y){return y.subscribe(new d(_,this.compare,this.keySelector))}}class d extends r.L{constructor(_,y,S){super(_),this.keySelector=S,this.hasKey=!1,"function"==typeof y&&(this.compare=y)}compare(_,y){return _===y}_next(_){let y;try{const{keySelector:A}=this;y=A?A(_):_}catch(A){return this.destination.error(A)}let S=!1;if(this.hasKey)try{const{compare:A}=this;S=A(this.key,y)}catch(A){return this.destination.error(A)}else this.hasKey=!0;S||(this.key=y,this.destination.next(_))}}},45435:(v,T,i)=>{"use strict";i.d(T,{h:()=>u});var r=i(77393);function u(e,_){return function(S){return S.lift(new p(e,_))}}class p{constructor(_,y){this.predicate=_,this.thisArg=y}call(_,y){return y.subscribe(new d(_,this.predicate,this.thisArg))}}class d extends r.L{constructor(_,y,S){super(_),this.predicate=y,this.thisArg=S,this.count=0}_next(_){let y;try{y=this.predicate.call(this.thisArg,_,this.count++)}catch(S){return void this.destination.error(S)}y&&this.destination.next(_)}}},68939:(v,T,i)=>{"use strict";i.d(T,{x:()=>p});var r=i(77393),u=i(75319);function p(_){return y=>y.lift(new d(_))}class d{constructor(y){this.callback=y}call(y,S){return S.subscribe(new e(y,this.callback))}}class e extends r.L{constructor(y,S){super(y),this.add(new u.w(S))}}},28049:(v,T,i)=>{"use strict";i.d(T,{P:()=>y});var r=i(13410),u=i(45435),p=i(15257),d=i(95242),e=i(44635),_=i(54487);function y(S,A){const N=arguments.length>=2;return L=>L.pipe(S?(0,u.h)((Z,J)=>S(Z,J,L)):_.y,(0,p.q)(1),N?(0,d.d)(A):(0,e.T)(()=>new r.K))}},12627:(v,T,i)=>{"use strict";i.d(T,{Z:()=>y});var r=i(13410),u=i(45435),p=i(548),d=i(44635),e=i(95242),_=i(54487);function y(S,A){const N=arguments.length>=2;return L=>L.pipe(S?(0,u.h)((Z,J)=>S(Z,J,L)):_.y,(0,p.h)(1),N?(0,e.d)(A):(0,d.T)(()=>new r.K))}},88002:(v,T,i)=>{"use strict";i.d(T,{U:()=>u});var r=i(77393);function u(e,_){return function(S){if("function"!=typeof e)throw new TypeError("argument is not a function. Are you looking for `mapTo()`?");return S.lift(new p(e,_))}}class p{constructor(_,y){this.project=_,this.thisArg=y}call(_,y){return y.subscribe(new d(_,this.project,this.thisArg))}}class d extends r.L{constructor(_,y,S){super(_),this.project=y,this.count=0,this.thisArg=S||this}_next(_){let y;try{y=this.project.call(this.thisArg,_,this.count++)}catch(S){return void this.destination.error(S)}this.destination.next(y)}}},96736:(v,T,i)=>{"use strict";i.d(T,{h:()=>u});var r=i(77393);function u(e){return _=>_.lift(new p(e))}class p{constructor(_){this.value=_}call(_,y){return y.subscribe(new d(_,this.value))}}class d extends r.L{constructor(_,y){super(_),this.value=y}_next(_){this.destination.next(this.value)}}},63282:(v,T,i)=>{"use strict";i.d(T,{J:()=>p});var r=i(19773),u=i(54487);function p(d=Number.POSITIVE_INFINITY){return(0,r.zg)(u.y,d)}},19773:(v,T,i)=>{"use strict";i.d(T,{zg:()=>d});var r=i(88002),u=i(94402),p=i(85345);function d(S,A,N=Number.POSITIVE_INFINITY){return"function"==typeof A?L=>L.pipe(d((Z,J)=>(0,u.D)(S(Z,J)).pipe((0,r.U)((K,ee)=>A(Z,K,J,ee))),N)):("number"==typeof A&&(N=A),L=>L.lift(new e(S,N)))}class e{constructor(A,N=Number.POSITIVE_INFINITY){this.project=A,this.concurrent=N}call(A,N){return N.subscribe(new _(A,this.project,this.concurrent))}}class _ extends p.Ds{constructor(A,N,L=Number.POSITIVE_INFINITY){super(A),this.project=N,this.concurrent=L,this.hasCompleted=!1,this.buffer=[],this.active=0,this.index=0}_next(A){this.active<this.concurrent?this._tryNext(A):this.buffer.push(A)}_tryNext(A){let N;const L=this.index++;try{N=this.project(A,L)}catch(Z){return void this.destination.error(Z)}this.active++,this._innerSub(N)}_innerSub(A){const N=new p.IY(this),L=this.destination;L.add(N);const Z=(0,p.ft)(A,N);Z!==N&&L.add(Z)}_complete(){this.hasCompleted=!0,0===this.active&&0===this.buffer.length&&this.destination.complete(),this.unsubscribe()}notifyNext(A){this.destination.next(A)}notifyComplete(){const A=this.buffer;this.active--,A.length>0?this._next(A.shift()):0===this.active&&this.hasCompleted&&this.destination.complete()}}},59746:(v,T,i)=>{"use strict";i.d(T,{QV:()=>p,ht:()=>e});var r=i(77393),u=i(23098);function p(y,S=0){return function(N){return N.lift(new d(y,S))}}class d{constructor(S,A=0){this.scheduler=S,this.delay=A}call(S,A){return A.subscribe(new e(S,this.scheduler,this.delay))}}class e extends r.L{constructor(S,A,N=0){super(S),this.scheduler=A,this.delay=N}static dispatch(S){const{notification:A,destination:N}=S;A.observe(N),this.unsubscribe()}scheduleMessage(S){this.destination.add(this.scheduler.schedule(e.dispatch,this.delay,new _(S,this.destination)))}_next(S){this.scheduleMessage(u.P.createNext(S))}_error(S){this.scheduleMessage(u.P.createError(S)),this.unsubscribe()}_complete(){this.scheduleMessage(u.P.createComplete()),this.unsubscribe()}}class _{constructor(S,A){this.notification=S,this.destination=A}}},51307:(v,T,i)=>{"use strict";i.d(T,{x:()=>u});var r=i(77393);function u(){return function(_){return _.lift(new p(_))}}class p{constructor(_){this.connectable=_}call(_,y){const{connectable:S}=this;S._refCount++;const A=new d(_,S),N=y.subscribe(A);return A.closed||(A.connection=S.connect()),N}}class d extends r.L{constructor(_,y){super(_),this.connectable=y}_unsubscribe(){const{connectable:_}=this;if(!_)return void(this.connection=null);this.connectable=null;const y=_._refCount;if(y<=0)return void(this.connection=null);if(_._refCount=y-1,y>1)return void(this.connection=null);const{connection:S}=this,A=_._connection;this.connection=null,A&&(!S||A===S)&&A.unsubscribe()}}},42145:(v,T,i)=>{"use strict";i.d(T,{R:()=>u});var r=i(77393);function u(e,_){let y=!1;return arguments.length>=2&&(y=!0),function(A){return A.lift(new p(e,_,y))}}class p{constructor(_,y,S=!1){this.accumulator=_,this.seed=y,this.hasSeed=S}call(_,y){return y.subscribe(new d(_,this.accumulator,this.seed,this.hasSeed))}}class d extends r.L{constructor(_,y,S,A){super(_),this.accumulator=y,this._seed=S,this.hasSeed=A,this.index=0}get seed(){return this._seed}set seed(_){this.hasSeed=!0,this._seed=_}_next(_){if(this.hasSeed)return this._tryNext(_);this.seed=_,this.destination.next(_)}_tryNext(_){const y=this.index++;let S;try{S=this.accumulator(this.seed,_,y)}catch(A){this.destination.error(A)}this.seed=S,this.destination.next(S)}}},18819:(v,T,i)=>{"use strict";i.d(T,{B:()=>y});var r=i(52441);var d=i(51307),e=i(79765);function _(){return new e.xQ}function y(){return S=>(0,d.x)()(function(S,A){return function(L){let Z;Z="function"==typeof S?S:function(){return S};const J=Object.create(L,r.N);return J.source=L,J.subjectFactory=Z,J}}(_)(S))}},47349:(v,T,i)=>{"use strict";i.d(T,{d:()=>u});var r=i(80226);function u(d,e,_){let y;return y=d&&"object"==typeof d?d:{bufferSize:d,windowTime:e,refCount:!1,scheduler:_},S=>S.lift(function({bufferSize:d=Number.POSITIVE_INFINITY,windowTime:e=Number.POSITIVE_INFINITY,refCount:_,scheduler:y}){let S,N,A=0,L=!1,Z=!1;return function(K){let ee;A++,!S||L?(L=!1,S=new r.t(d,e,y),ee=S.subscribe(this),N=K.subscribe({next(ue){S.next(ue)},error(ue){L=!0,S.error(ue)},complete(){Z=!0,N=void 0,S.complete()}})):ee=S.subscribe(this),this.add(()=>{A--,ee.unsubscribe(),N&&!Z&&_&&0===A&&(N.unsubscribe(),N=void 0,S=void 0)})}}(y))}},39761:(v,T,i)=>{"use strict";i.d(T,{O:()=>p});var r=i(58071),u=i(54869);function p(...d){const e=d[d.length-1];return(0,u.K)(e)?(d.pop(),_=>(0,r.z)(d,_,e)):_=>(0,r.z)(d,_)}},43190:(v,T,i)=>{"use strict";i.d(T,{w:()=>d});var r=i(88002),u=i(94402),p=i(85345);function d(y,S){return"function"==typeof S?A=>A.pipe(d((N,L)=>(0,u.D)(y(N,L)).pipe((0,r.U)((Z,J)=>S(N,Z,L,J))))):A=>A.lift(new e(y))}class e{constructor(S){this.project=S}call(S,A){return A.subscribe(new _(S,this.project))}}class _ extends p.Ds{constructor(S,A){super(S),this.project=A,this.index=0}_next(S){let A;const N=this.index++;try{A=this.project(S,N)}catch(L){return void this.destination.error(L)}this._innerSub(A)}_innerSub(S){const A=this.innerSubscription;A&&A.unsubscribe();const N=new p.IY(this),L=this.destination;L.add(N),this.innerSubscription=(0,p.ft)(S,N),this.innerSubscription!==N&&L.add(this.innerSubscription)}_complete(){const{innerSubscription:S}=this;(!S||S.closed)&&super._complete(),this.unsubscribe()}_unsubscribe(){this.innerSubscription=void 0}notifyComplete(){this.innerSubscription=void 0,this.isStopped&&super._complete()}notifyNext(S){this.destination.next(S)}}},15257:(v,T,i)=>{"use strict";i.d(T,{q:()=>d});var r=i(77393),u=i(7108),p=i(59193);function d(y){return S=>0===y?(0,p.c)():S.lift(new e(y))}class e{constructor(S){if(this.total=S,this.total<0)throw new u.W}call(S,A){return A.subscribe(new _(S,this.total))}}class _ extends r.L{constructor(S,A){super(S),this.total=A,this.count=0}_next(S){const A=this.total,N=++this.count;N<=A&&(this.destination.next(S),N===A&&(this.destination.complete(),this.unsubscribe()))}}},548:(v,T,i)=>{"use strict";i.d(T,{h:()=>d});var r=i(77393),u=i(7108),p=i(59193);function d(y){return function(A){return 0===y?(0,p.c)():A.lift(new e(y))}}class e{constructor(S){if(this.total=S,this.total<0)throw new u.W}call(S,A){return A.subscribe(new _(S,this.total))}}class _ extends r.L{constructor(S,A){super(S),this.total=A,this.ring=new Array,this.count=0}_next(S){const A=this.ring,N=this.total,L=this.count++;A.length<N?A.push(S):A[L%N]=S}_complete(){const S=this.destination;let A=this.count;if(A>0){const N=this.count>=this.total?this.total:this.count,L=this.ring;for(let Z=0;Z<N;Z++){const J=A++%N;S.next(L[J])}}S.complete()}}},46782:(v,T,i)=>{"use strict";i.d(T,{R:()=>u});var r=i(85345);function u(e){return _=>_.lift(new p(e))}class p{constructor(_){this.notifier=_}call(_,y){const S=new d(_),A=(0,r.ft)(this.notifier,new r.IY(S));return A&&!S.seenValue?(S.add(A),y.subscribe(S)):S}}class d extends r.Ds{constructor(_){super(_),this.seenValue=!1}notifyNext(){this.seenValue=!0,this.complete()}notifyComplete(){}}},68307:(v,T,i)=>{"use strict";i.d(T,{b:()=>d});var r=i(77393),u=i(98640),p=i(69105);function d(y,S,A){return function(L){return L.lift(new e(y,S,A))}}class e{constructor(S,A,N){this.nextOrObserver=S,this.error=A,this.complete=N}call(S,A){return A.subscribe(new _(S,this.nextOrObserver,this.error,this.complete))}}class _ extends r.L{constructor(S,A,N,L){super(S),this._tapNext=u.Z,this._tapError=u.Z,this._tapComplete=u.Z,this._tapError=N||u.Z,this._tapComplete=L||u.Z,(0,p.m)(A)?(this._context=this,this._tapNext=A):A&&(this._context=A,this._tapNext=A.next||u.Z,this._tapError=A.error||u.Z,this._tapComplete=A.complete||u.Z)}_next(S){try{this._tapNext.call(this._context,S)}catch(A){return void this.destination.error(A)}this.destination.next(S)}_error(S){try{this._tapError.call(this._context,S)}catch(A){return void this.destination.error(A)}this.destination.error(S)}_complete(){try{this._tapComplete.call(this._context)}catch(S){return void this.destination.error(S)}return this.destination.complete()}}},44635:(v,T,i)=>{"use strict";i.d(T,{T:()=>p});var r=i(13410),u=i(77393);function p(y=_){return S=>S.lift(new d(y))}class d{constructor(S){this.errorFactory=S}call(S,A){return A.subscribe(new e(S,this.errorFactory))}}class e extends u.L{constructor(S,A){super(S),this.errorFactory=A,this.hasValue=!1}_next(S){this.hasValue=!0,this.destination.next(S)}_complete(){if(this.hasValue)return this.destination.complete();{let S;try{S=this.errorFactory()}catch(A){S=A}this.destination.error(S)}}}function _(){return new r.K}},94087:(v,T,i)=>{"use strict";i.d(T,{r:()=>p});var r=i(18891),u=i(75319);function p(d,e){return new r.y(_=>{const y=new u.w;let S=0;return y.add(e.schedule(function(){S!==d.length?(_.next(d[S++]),_.closed||y.add(this.schedule())):_.complete()})),y})}},36465:(v,T,i)=>{"use strict";i.d(T,{o:()=>p});var r=i(75319);class u extends r.w{constructor(e,_){super()}schedule(e,_=0){return this}}class p extends u{constructor(e,_){super(e,_),this.scheduler=e,this.work=_,this.pending=!1}schedule(e,_=0){if(this.closed)return this;this.state=e;const y=this.id,S=this.scheduler;return null!=y&&(this.id=this.recycleAsyncId(S,y,_)),this.pending=!0,this.delay=_,this.id=this.id||this.requestAsyncId(S,this.id,_),this}requestAsyncId(e,_,y=0){return setInterval(e.flush.bind(e,this),y)}recycleAsyncId(e,_,y=0){if(null!==y&&this.delay===y&&!1===this.pending)return _;clearInterval(_)}execute(e,_){if(this.closed)return new Error("executing a cancelled action");this.pending=!1;const y=this._execute(e,_);if(y)return y;!1===this.pending&&null!=this.id&&(this.id=this.recycleAsyncId(this.scheduler,this.id,null))}_execute(e,_){let S,y=!1;try{this.work(e)}catch(A){y=!0,S=!!A&&A||new Error(A)}if(y)return this.unsubscribe(),S}_unsubscribe(){const e=this.id,_=this.scheduler,y=_.actions,S=y.indexOf(this);this.work=null,this.state=null,this.pending=!1,this.scheduler=null,-1!==S&&y.splice(S,1),null!=e&&(this.id=this.recycleAsyncId(_,e,null)),this.delay=null}}},16102:(v,T,i)=>{"use strict";i.d(T,{v:()=>u});let r=(()=>{class p{constructor(e,_=p.now){this.SchedulerAction=e,this.now=_}schedule(e,_=0,y){return new this.SchedulerAction(this,e).schedule(y,_)}}return p.now=()=>Date.now(),p})();class u extends r{constructor(d,e=r.now){super(d,()=>u.delegate&&u.delegate!==this?u.delegate.now():e()),this.actions=[],this.active=!1,this.scheduled=void 0}schedule(d,e=0,_){return u.delegate&&u.delegate!==this?u.delegate.schedule(d,e,_):super.schedule(d,e,_)}flush(d){const{actions:e}=this;if(this.active)return void e.push(d);let _;this.active=!0;do{if(_=d.execute(d.state,d.delay))break}while(d=e.shift());if(this.active=!1,_){for(;d=e.shift();)d.unsubscribe();throw _}}}},33637:(v,T,i)=>{"use strict";i.d(T,{z:()=>p,P:()=>d});var r=i(36465);const p=new(i(16102).v)(r.o),d=p},20377:(v,T,i)=>{"use strict";i.d(T,{hZ:()=>u});const u="function"==typeof Symbol&&Symbol.iterator?Symbol.iterator:"@@iterator"},16554:(v,T,i)=>{"use strict";i.d(T,{L:()=>r});const r="function"==typeof Symbol&&Symbol.observable||"@@observable"},29181:(v,T,i)=>{"use strict";i.d(T,{b:()=>r});const r="function"==typeof Symbol?Symbol("rxSubscriber"):"@@rxSubscriber_"+Math.random()},7108:(v,T,i)=>{"use strict";i.d(T,{W:()=>u});const u=(()=>{function p(){return Error.call(this),this.message="argument out of range",this.name="ArgumentOutOfRangeError",this}return p.prototype=Object.create(Error.prototype),p})()},13410:(v,T,i)=>{"use strict";i.d(T,{K:()=>u});const u=(()=>{function p(){return Error.call(this),this.message="no elements in sequence",this.name="EmptyError",this}return p.prototype=Object.create(Error.prototype),p})()},77971:(v,T,i)=>{"use strict";i.d(T,{N:()=>u});const u=(()=>{function p(){return Error.call(this),this.message="object unsubscribed",this.name="ObjectUnsubscribedError",this}return p.prototype=Object.create(Error.prototype),p})()},54449:(v,T,i)=>{"use strict";function r(u){setTimeout(()=>{throw u},0)}i.d(T,{z:()=>r})},54487:(v,T,i)=>{"use strict";function r(u){return u}i.d(T,{y:()=>r})},59796:(v,T,i)=>{"use strict";i.d(T,{k:()=>r});const r=Array.isArray||(u=>u&&"number"==typeof u.length)},69489:(v,T,i)=>{"use strict";i.d(T,{z:()=>r});const r=u=>u&&"number"==typeof u.length&&"function"!=typeof u},69105:(v,T,i)=>{"use strict";function r(u){return"function"==typeof u}i.d(T,{m:()=>r})},26561:(v,T,i)=>{"use strict";i.d(T,{k:()=>u});var r=i(59796);function u(p){return!(0,r.k)(p)&&p-parseFloat(p)+1>=0}},81555:(v,T,i)=>{"use strict";function r(u){return null!==u&&"object"==typeof u}i.d(T,{K:()=>r})},44072:(v,T,i)=>{"use strict";function r(u){return!!u&&"function"!=typeof u.subscribe&&"function"==typeof u.then}i.d(T,{t:()=>r})},54869:(v,T,i)=>{"use strict";function r(u){return u&&"function"==typeof u.schedule}i.d(T,{K:()=>r})},98640:(v,T,i)=>{"use strict";function r(){}i.d(T,{Z:()=>r})},34022:(v,T,i)=>{"use strict";i.d(T,{z:()=>u,U:()=>p});var r=i(54487);function u(...d){return p(d)}function p(d){return 0===d.length?r.y:1===d.length?d[0]:function(_){return d.reduce((y,S)=>S(y),_)}}},87444:(v,T,i)=>{"use strict";i.d(T,{s:()=>L});var r=i(55015),u=i(54449),d=i(20377),_=i(16554),S=i(69489),A=i(44072),N=i(81555);const L=Z=>{if(Z&&"function"==typeof Z[_.L])return(Z=>J=>{const K=Z[_.L]();if("function"!=typeof K.subscribe)throw new TypeError("Provided object does not correctly implement Symbol.observable");return K.subscribe(J)})(Z);if((0,S.z)(Z))return(0,r.V)(Z);if((0,A.t)(Z))return(Z=>J=>(Z.then(K=>{J.closed||(J.next(K),J.complete())},K=>J.error(K)).then(null,u.z),J))(Z);if(Z&&"function"==typeof Z[d.hZ])return(Z=>J=>{const K=Z[d.hZ]();for(;;){let ee;try{ee=K.next()}catch(ue){return J.error(ue),J}if(ee.done){J.complete();break}if(J.next(ee.value),J.closed)break}return"function"==typeof K.return&&J.add(()=>{K.return&&K.return()}),J})(Z);{const K=`You provided ${(0,N.K)(Z)?"an invalid object":`'${Z}'`} where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.`;throw new TypeError(K)}}},55015:(v,T,i)=>{"use strict";i.d(T,{V:()=>r});const r=u=>p=>{for(let d=0,e=u.length;d<e&&!p.closed;d++)p.next(u[d]);p.complete()}},20509:(v,T,i)=>{"use strict";i.d(T,{D:()=>e});var r=i(77393);class u extends r.L{constructor(y,S,A){super(),this.parent=y,this.outerValue=S,this.outerIndex=A,this.index=0}_next(y){this.parent.notifyNext(this.outerValue,y,this.outerIndex,this.index++,this)}_error(y){this.parent.notifyError(y,this),this.unsubscribe()}_complete(){this.parent.notifyComplete(this),this.unsubscribe()}}var p=i(87444),d=i(18891);function e(_,y,S,A,N=new u(_,S,A)){if(!N.closed)return y instanceof d.y?y.subscribe(N):(0,p.s)(y)(N)}},59771:(v,T)=>{"use strict";var i,r,u,p;if("object"==typeof performance&&"function"==typeof performance.now){var d=performance;T.unstable_now=function(){return d.now()}}else{var e=Date,_=e.now();T.unstable_now=function(){return e.now()-_}}if("undefined"==typeof window||"function"!=typeof MessageChannel){var y=null,S=null,A=function(){if(null!==y)try{var It=T.unstable_now();y(!0,It),y=null}catch(Zt){throw setTimeout(A,0),Zt}};i=function(It){null!==y?setTimeout(i,0,It):(y=It,setTimeout(A,0))},r=function(It,Zt){S=setTimeout(It,Zt)},u=function(){clearTimeout(S)},T.unstable_shouldYield=function(){return!1},p=T.unstable_forceFrameRate=function(){}}else{var N=window.setTimeout,L=window.clearTimeout;if("undefined"!=typeof console){var Z=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills"),"function"!=typeof Z&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills")}var J=!1,K=null,ee=-1,ue=5,ae=0;T.unstable_shouldYield=function(){return T.unstable_now()>=ae},p=function(){},T.unstable_forceFrameRate=function(It){0>It||125<It?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):ue=0<It?Math.floor(1e3/It):5};var H=new MessageChannel,se=H.port2;H.port1.onmessage=function(){if(null!==K){var It=T.unstable_now();ae=It+ue;try{K(!0,It)?se.postMessage(null):(J=!1,K=null)}catch(Zt){throw se.postMessage(null),Zt}}else J=!1},i=function(It){K=It,J||(J=!0,se.postMessage(null))},r=function(It,Zt){ee=N(function(){It(T.unstable_now())},Zt)},u=function(){L(ee),ee=-1}}function Ee(It,Zt){var Ut=It.length;It.push(Zt);e:for(;;){var Bt=Ut-1>>>1,bt=It[Bt];if(!(void 0!==bt&&0<ge(bt,Zt)))break e;It[Bt]=Zt,It[Ut]=bt,Ut=Bt}}function ie(It){return void 0===(It=It[0])?null:It}function he(It){var Zt=It[0];if(void 0!==Zt){var Ut=It.pop();if(Ut!==Zt){It[0]=Ut;e:for(var Bt=0,bt=It.length;Bt<bt;){var Gt=2*(Bt+1)-1,xt=It[Gt],Xt=Gt+1,Zn=It[Xt];if(void 0!==xt&&0>ge(xt,Ut))void 0!==Zn&&0>ge(Zn,xt)?(It[Bt]=Zn,It[Xt]=Ut,Bt=Xt):(It[Bt]=xt,It[Gt]=Ut,Bt=Gt);else{if(!(void 0!==Zn&&0>ge(Zn,Ut)))break e;It[Bt]=Zn,It[Xt]=Ut,Bt=Xt}}}return Zt}return null}function ge(It,Zt){var Ut=It.sortIndex-Zt.sortIndex;return 0!==Ut?Ut:It.id-Zt.id}var De=[],ce=[],lt=1,Ve=null,ze=3,Be=!1,Pe=!1,je=!1;function He(It){for(var Zt=ie(ce);null!==Zt;){if(null===Zt.callback)he(ce);else{if(!(Zt.startTime<=It))break;he(ce),Zt.sortIndex=Zt.expirationTime,Ee(De,Zt)}Zt=ie(ce)}}function Vt(It){if(je=!1,He(It),!Pe)if(null!==ie(De))Pe=!0,i(it);else{var Zt=ie(ce);null!==Zt&&r(Vt,Zt.startTime-It)}}function it(It,Zt){Pe=!1,je&&(je=!1,u()),Be=!0;var Ut=ze;try{for(He(Zt),Ve=ie(De);null!==Ve&&(!(Ve.expirationTime>Zt)||It&&!T.unstable_shouldYield());){var Bt=Ve.callback;if("function"==typeof Bt){Ve.callback=null,ze=Ve.priorityLevel;var bt=Bt(Ve.expirationTime<=Zt);Zt=T.unstable_now(),"function"==typeof bt?Ve.callback=bt:Ve===ie(De)&&he(De),He(Zt)}else he(De);Ve=ie(De)}if(null!==Ve)var Gt=!0;else{var xt=ie(ce);null!==xt&&r(Vt,xt.startTime-Zt),Gt=!1}return Gt}finally{Ve=null,ze=Ut,Be=!1}}var tn=p;T.unstable_IdlePriority=5,T.unstable_ImmediatePriority=1,T.unstable_LowPriority=4,T.unstable_NormalPriority=3,T.unstable_Profiling=null,T.unstable_UserBlockingPriority=2,T.unstable_cancelCallback=function(It){It.callback=null},T.unstable_continueExecution=function(){Pe||Be||(Pe=!0,i(it))},T.unstable_getCurrentPriorityLevel=function(){return ze},T.unstable_getFirstCallbackNode=function(){return ie(De)},T.unstable_next=function(It){switch(ze){case 1:case 2:case 3:var Zt=3;break;default:Zt=ze}var Ut=ze;ze=Zt;try{return It()}finally{ze=Ut}},T.unstable_pauseExecution=function(){},T.unstable_requestPaint=tn,T.unstable_runWithPriority=function(It,Zt){switch(It){case 1:case 2:case 3:case 4:case 5:break;default:It=3}var Ut=ze;ze=It;try{return Zt()}finally{ze=Ut}},T.unstable_scheduleCallback=function(It,Zt,Ut){var Bt=T.unstable_now();switch(Ut="object"==typeof Ut&&null!==Ut&&"number"==typeof(Ut=Ut.delay)&&0<Ut?Bt+Ut:Bt,It){case 1:var bt=-1;break;case 2:bt=250;break;case 5:bt=1073741823;break;case 4:bt=1e4;break;default:bt=5e3}return It={id:lt++,callback:Zt,priorityLevel:It,startTime:Ut,expirationTime:bt=Ut+bt,sortIndex:-1},Ut>Bt?(It.sortIndex=Ut,Ee(ce,It),null===ie(De)&&It===ie(ce)&&(je?u():je=!0,r(Vt,Ut-Bt))):(It.sortIndex=bt,Ee(De,It),Pe||Be||(Pe=!0,i(it))),It},T.unstable_wrapCallback=function(It){var Zt=ze;return function(){var Ut=ze;ze=Zt;try{return It.apply(this,arguments)}finally{ze=Ut}}}},88712:(v,T,i)=>{"use strict";v.exports=i(59771)},4043:v=>{"use strict";class T extends Error{constructor(y){super(T._prepareSuperMessage(y)),Object.defineProperty(this,"name",{value:"NonError",configurable:!0,writable:!0}),Error.captureStackTrace&&Error.captureStackTrace(this,T)}static _prepareSuperMessage(y){try{return JSON.stringify(y)}catch(S){return String(y)}}}const i=[{property:"name",enumerable:!1},{property:"message",enumerable:!1},{property:"stack",enumerable:!1},{property:"code",enumerable:!0}],r=Symbol(".toJSON called"),p=({from:_,seen:y,to_:S,forceEnumerable:A,maxDepth:N,depth:L})=>{const Z=S||(Array.isArray(_)?[]:{});if(y.push(_),L>=N)return Z;if("function"==typeof _.toJSON&&!0!==_[r])return(_=>{_[r]=!0;const y=_.toJSON();return delete _[r],y})(_);for(const[J,K]of Object.entries(_))if("function"==typeof Buffer&&Buffer.isBuffer(K))Z[J]="[object Buffer]";else if("function"!=typeof K){if(!K||"object"!=typeof K){Z[J]=K;continue}if(!y.includes(_[J])){L++,Z[J]=p({from:_[J],seen:y.slice(),forceEnumerable:A,maxDepth:N,depth:L});continue}Z[J]="[Circular]"}for(const{property:J,enumerable:K}of i)"string"==typeof _[J]&&Object.defineProperty(Z,J,{value:_[J],enumerable:!!A||K,configurable:!0,writable:!0});return Z};v.exports={serializeError:(_,y={})=>{const{maxDepth:S=Number.POSITIVE_INFINITY}=y;return"object"==typeof _&&null!==_?p({from:_,seen:[],forceEnumerable:!0,maxDepth:S,depth:0}):"function"==typeof _?`[Function: ${_.name||"anonymous"}]`:_},deserializeError:(_,y={})=>{const{maxDepth:S=Number.POSITIVE_INFINITY}=y;if(_ instanceof Error)return _;if("object"==typeof _&&null!==_&&!Array.isArray(_)){const A=new Error;return p({from:_,seen:[],to_:A,maxDepth:S,depth:0}),A}return new T(_)}}},11144:(v,T,i)=>{"use strict";var r=i(18540),u=i(19568),p=i(81380),d=r("%TypeError%"),e=r("%WeakMap%",!0),_=r("%Map%",!0),y=u("WeakMap.prototype.get",!0),S=u("WeakMap.prototype.set",!0),A=u("WeakMap.prototype.has",!0),N=u("Map.prototype.get",!0),L=u("Map.prototype.set",!0),Z=u("Map.prototype.has",!0),J=function(ae,H){for(var Ee,se=ae;null!==(Ee=se.next);se=Ee)if(Ee.key===H)return se.next=Ee.next,Ee.next=ae.next,ae.next=Ee,Ee};v.exports=function(){var H,se,Ee,ie={assert:function(he){if(!ie.has(he))throw new d("Side channel does not contain "+p(he))},get:function(he){if(e&&he&&("object"==typeof he||"function"==typeof he)){if(H)return y(H,he)}else if(_){if(se)return N(se,he)}else if(Ee)return function(ae,H){var se=J(ae,H);return se&&se.value}(Ee,he)},has:function(he){if(e&&he&&("object"==typeof he||"function"==typeof he)){if(H)return A(H,he)}else if(_){if(se)return Z(se,he)}else if(Ee)return function(ae,H){return!!J(ae,H)}(Ee,he);return!1},set:function(he,ge){e&&he&&("object"==typeof he||"function"==typeof he)?(H||(H=new e),S(H,he,ge)):_?(se||(se=new _),L(se,he,ge)):(Ee||(Ee={key:{},next:null}),function(ae,H,se){var Ee=J(ae,H);Ee?Ee.value=se:ae.next={key:H,next:ae.next,value:se}}(Ee,he,ge))}};return ie}},34863:(v,T,i)=>{"use strict";i.d(T,{M:()=>kr,t:()=>mi}),i(21581),i(8868),i(85443),i(35704),i(66837),i(13744),i(63438),i(22603);var Xt,A=i(6123),N=i.n(A),L=i(86906),Z=i.n(L),J=i(66941),K=i.n(J),ee=[],H="ResizeObserver loop completed with undelivered notifications.",Ee=(()=>{return(An=Ee||(Ee={})).BORDER_BOX="border-box",An.CONTENT_BOX="content-box",An.DEVICE_PIXEL_CONTENT_BOX="device-pixel-content-box",Ee;var An})(),ie=function(An){return Object.freeze(An)},he=function(Er,Wr){this.inlineSize=Er,this.blockSize=Wr,ie(this)},ge=function(){function An(Er,Wr,dr,Fn){return this.x=Er,this.y=Wr,this.width=dr,this.height=Fn,this.top=this.y,this.left=this.x,this.bottom=this.top+this.height,this.right=this.left+this.width,ie(this)}return An.prototype.toJSON=function(){var Er=this;return{x:Er.x,y:Er.y,top:Er.top,right:Er.right,bottom:Er.bottom,left:Er.left,width:Er.width,height:Er.height}},An.fromRect=function(Er){return new An(Er.x,Er.y,Er.width,Er.height)},An}(),De=function(An){return An instanceof SVGElement&&"getBBox"in An},ce=function(An){if(De(An)){var Er=An.getBBox();return!Er.width&&!Er.height}return!(An.offsetWidth||An.offsetHeight||An.getClientRects().length)},lt=function(An){var Er;if(An instanceof Element)return!0;var Wr=null===(Er=null==An?void 0:An.ownerDocument)||void 0===Er?void 0:Er.defaultView;return!!(Wr&&An instanceof Wr.Element)},ze="undefined"!=typeof window?window:{},Be=new WeakMap,Pe=/auto|scroll/,je=/^tb|vertical/,He=/msie|trident/i.test(ze.navigator&&ze.navigator.userAgent),Vt=function(An){return parseFloat(An||"0")},it=function(An,Er,Wr){return void 0===An&&(An=0),void 0===Er&&(Er=0),void 0===Wr&&(Wr=!1),new he((Wr?Er:An)||0,(Wr?An:Er)||0)},tn=ie({devicePixelContentBoxSize:it(),borderBoxSize:it(),contentBoxSize:it(),contentRect:new ge(0,0,0,0)}),It=function(An,Er){if(void 0===Er&&(Er=!1),Be.has(An)&&!Er)return Be.get(An);if(ce(An))return Be.set(An,tn),tn;var Wr=getComputedStyle(An),dr=De(An)&&An.ownerSVGElement&&An.getBBox(),Fn=!He&&"border-box"===Wr.boxSizing,ar=je.test(Wr.writingMode||""),Wi=!dr&&Pe.test(Wr.overflowY||""),lo=!dr&&Pe.test(Wr.overflowX||""),vo=dr?0:Vt(Wr.paddingTop),Co=dr?0:Vt(Wr.paddingRight),Gi=dr?0:Vt(Wr.paddingBottom),os=dr?0:Vt(Wr.paddingLeft),jo=dr?0:Vt(Wr.borderTopWidth),To=dr?0:Vt(Wr.borderRightWidth),Mi=dr?0:Vt(Wr.borderBottomWidth),Bn=os+Co,lr=vo+Gi,vr=(dr?0:Vt(Wr.borderLeftWidth))+To,er=jo+Mi,ri=lo?An.offsetHeight-er-An.clientHeight:0,uo=Wi?An.offsetWidth-vr-An.clientWidth:0,Ci=Fn?Bn+vr:0,$o=Fn?lr+er:0,tr=dr?dr.width:Vt(Wr.width)-Ci-uo,Ar=dr?dr.height:Vt(Wr.height)-$o-ri,Rt=tr+Bn+uo+vr,_t=Ar+lr+ri+er,mt=ie({devicePixelContentBoxSize:it(Math.round(tr*devicePixelRatio),Math.round(Ar*devicePixelRatio),ar),borderBoxSize:it(Rt,_t,ar),contentBoxSize:it(tr,Ar,ar),contentRect:new ge(os,vo,tr,Ar)});return Be.set(An,mt),mt},Zt=function(An,Er,Wr){var dr=It(An,Wr),Fn=dr.borderBoxSize,ar=dr.contentBoxSize,Wi=dr.devicePixelContentBoxSize;switch(Er){case Ee.DEVICE_PIXEL_CONTENT_BOX:return Wi;case Ee.BORDER_BOX:return Fn;default:return ar}},Ut=function(Er){var Wr=It(Er);this.target=Er,this.contentRect=Wr.contentRect,this.borderBoxSize=ie([Wr.borderBoxSize]),this.contentBoxSize=ie([Wr.contentBoxSize]),this.devicePixelContentBoxSize=ie([Wr.devicePixelContentBoxSize])},Bt=function(An){if(ce(An))return 1/0;for(var Er=0,Wr=An.parentNode;Wr;)Er+=1,Wr=Wr.parentNode;return Er},bt=function(){var An=1/0,Er=[];ee.forEach(function(Wi){if(0!==Wi.activeTargets.length){var lo=[];Wi.activeTargets.forEach(function(Co){var Gi=new Ut(Co.target),os=Bt(Co.target);lo.push(Gi),Co.lastReportedSize=Zt(Co.target,Co.observedBox),os<An&&(An=os)}),Er.push(function(){Wi.callback.call(Wi.observer,lo,Wi.observer)}),Wi.activeTargets.splice(0,Wi.activeTargets.length)}});for(var Wr=0,dr=Er;Wr<dr.length;Wr++)(0,dr[Wr])();return An},Gt=function(An){ee.forEach(function(Wr){Wr.activeTargets.splice(0,Wr.activeTargets.length),Wr.skippedTargets.splice(0,Wr.skippedTargets.length),Wr.observationTargets.forEach(function(Fn){Fn.isActive()&&(Bt(Fn.target)>An?Wr.activeTargets.push(Fn):Wr.skippedTargets.push(Fn))})})},Zn=[],Mr=0,Nn={attributes:!0,characterData:!0,childList:!0,subtree:!0},$n=["resize","load","transitionend","animationend","animationstart","animationiteration","keyup","keydown","mouseup","mousedown","mouseover","mouseout","blur","focus"],Br=function(An){return void 0===An&&(An=0),Date.now()+An},Yr=!1,ki=new(function(){function An(){var Er=this;this.stopped=!0,this.listener=function(){return Er.schedule()}}return An.prototype.run=function(Er){var Wr=this;if(void 0===Er&&(Er=250),!Yr){Yr=!0;var dr=Br(Er);!function(An){!function(An){if(!Xt){var Er=0,Wr=document.createTextNode("");new MutationObserver(function(){return Zn.splice(0).forEach(function(An){return An()})}).observe(Wr,{characterData:!0}),Xt=function(){Wr.textContent="".concat(Er?Er--:Er++)}}Zn.push(An),Xt()}(function(){requestAnimationFrame(An)})}(function(){var Fn=!1;try{Fn=function(){var An=0;for(Gt(An);ee.some(function(An){return An.activeTargets.length>0});)An=bt(),Gt(An);return ee.some(function(An){return An.skippedTargets.length>0})&&function(){var An;"function"==typeof ErrorEvent?An=new ErrorEvent("error",{message:H}):((An=document.createEvent("Event")).initEvent("error",!1,!1),An.message=H),window.dispatchEvent(An)}(),An>0}()}finally{if(Yr=!1,Er=dr-Br(),!Mr)return;Fn?Wr.run(1e3):Er>0?Wr.run(Er):Wr.start()}})}},An.prototype.schedule=function(){this.stop(),this.run()},An.prototype.observe=function(){var Er=this,Wr=function(){return Er.observer&&Er.observer.observe(document.body,Nn)};document.body?Wr():ze.addEventListener("DOMContentLoaded",Wr)},An.prototype.start=function(){var Er=this;this.stopped&&(this.stopped=!1,this.observer=new MutationObserver(this.listener),this.observe(),$n.forEach(function(Wr){return ze.addEventListener(Wr,Er.listener,!0)}))},An.prototype.stop=function(){var Er=this;this.stopped||(this.observer&&this.observer.disconnect(),$n.forEach(function(Wr){return ze.removeEventListener(Wr,Er.listener,!0)}),this.stopped=!0)},An}()),Hi=function(An){!Mr&&An>0&&ki.start(),!(Mr+=An)&&ki.stop()},Cn=function(){function An(Er,Wr){this.target=Er,this.observedBox=Wr||Ee.CONTENT_BOX,this.lastReportedSize={inlineSize:0,blockSize:0}}return An.prototype.isActive=function(){var Er=Zt(this.target,this.observedBox,!0);return function(An){return!De(An)&&!function(An){switch(An.tagName){case"INPUT":if("image"!==An.type)break;case"VIDEO":case"AUDIO":case"EMBED":case"OBJECT":case"CANVAS":case"IFRAME":case"IMG":return!0}return!1}(An)&&"inline"===getComputedStyle(An).display}(this.target)&&(this.lastReportedSize=Er),this.lastReportedSize.inlineSize!==Er.inlineSize||this.lastReportedSize.blockSize!==Er.blockSize},An}(),Wt=function(Er,Wr){this.activeTargets=[],this.skippedTargets=[],this.observationTargets=[],this.observer=Er,this.callback=Wr},zn=new WeakMap,rr=function(An,Er){for(var Wr=0;Wr<An.length;Wr+=1)if(An[Wr].target===Er)return Wr;return-1},Fr=function(){function An(){}return An.connect=function(Er,Wr){var dr=new Wt(Er,Wr);zn.set(Er,dr)},An.observe=function(Er,Wr,dr){var Fn=zn.get(Er),ar=0===Fn.observationTargets.length;rr(Fn.observationTargets,Wr)<0&&(ar&&ee.push(Fn),Fn.observationTargets.push(new Cn(Wr,dr&&dr.box)),Hi(1),ki.schedule())},An.unobserve=function(Er,Wr){var dr=zn.get(Er),Fn=rr(dr.observationTargets,Wr);Fn>=0&&(1===dr.observationTargets.length&&ee.splice(ee.indexOf(dr),1),dr.observationTargets.splice(Fn,1),Hi(-1))},An.disconnect=function(Er){var Wr=this,dr=zn.get(Er);dr.observationTargets.slice().forEach(function(Fn){return Wr.unobserve(Er,Fn.target)}),dr.activeTargets.splice(0,dr.activeTargets.length)},An}(),Gn=function(){function An(Er){if(0===arguments.length)throw new TypeError("Failed to construct 'ResizeObserver': 1 argument required, but only 0 present.");if("function"!=typeof Er)throw new TypeError("Failed to construct 'ResizeObserver': The callback provided as parameter 1 is not a function.");Fr.connect(this,Er)}return An.prototype.observe=function(Er,Wr){if(0===arguments.length)throw new TypeError("Failed to execute 'observe' on 'ResizeObserver': 1 argument required, but only 0 present.");if(!lt(Er))throw new TypeError("Failed to execute 'observe' on 'ResizeObserver': parameter 1 is not of type 'Element");Fr.observe(this,Er,Wr)},An.prototype.unobserve=function(Er){if(0===arguments.length)throw new TypeError("Failed to execute 'unobserve' on 'ResizeObserver': 1 argument required, but only 0 present.");if(!lt(Er))throw new TypeError("Failed to execute 'unobserve' on 'ResizeObserver': parameter 1 is not of type 'Element");Fr.unobserve(this,Er)},An.prototype.disconnect=function(){Fr.disconnect(this)},An.toString=function(){return"function ResizeObserver () { [polyfill code] }"},An}(),Jr=i(72318),_i=i.n(Jr);function gr(An){return An&&An.ownerDocument&&An.ownerDocument.defaultView?An.ownerDocument.defaultView:window}function Jt(An){return An&&An.ownerDocument?An.ownerDocument:document}i(35319),i(69665),i(26954),i(80477),i(66262);var Vn=null,mr=null;function Dn(An){if(null===Vn){var Er=Jt(An);if(void 0===Er)return Vn=0;var Wr=Er.body,dr=Er.createElement("div");dr.classList.add("simplebar-hide-scrollbar"),Wr.appendChild(dr);var Fn=dr.getBoundingClientRect().right;Wr.removeChild(dr),Vn=Fn}return Vn}_i()&&window.addEventListener("resize",function(){mr!==window.devicePixelRatio&&(mr=window.devicePixelRatio,Vn=null)});var Pr=function(){function An(Wr,dr){var Fn=this;this.onScroll=function(){var ar=gr(Fn.el);Fn.scrollXTicking||(ar.requestAnimationFrame(Fn.scrollX),Fn.scrollXTicking=!0),Fn.scrollYTicking||(ar.requestAnimationFrame(Fn.scrollY),Fn.scrollYTicking=!0)},this.scrollX=function(){Fn.axis.x.isOverflowing&&(Fn.showScrollbar("x"),Fn.positionScrollbar("x")),Fn.scrollXTicking=!1},this.scrollY=function(){Fn.axis.y.isOverflowing&&(Fn.showScrollbar("y"),Fn.positionScrollbar("y")),Fn.scrollYTicking=!1},this.onMouseEnter=function(){Fn.showScrollbar("x"),Fn.showScrollbar("y")},this.onMouseMove=function(ar){Fn.mouseX=ar.clientX,Fn.mouseY=ar.clientY,(Fn.axis.x.isOverflowing||Fn.axis.x.forceVisible)&&Fn.onMouseMoveForAxis("x"),(Fn.axis.y.isOverflowing||Fn.axis.y.forceVisible)&&Fn.onMouseMoveForAxis("y")},this.onMouseLeave=function(){Fn.onMouseMove.cancel(),(Fn.axis.x.isOverflowing||Fn.axis.x.forceVisible)&&Fn.onMouseLeaveForAxis("x"),(Fn.axis.y.isOverflowing||Fn.axis.y.forceVisible)&&Fn.onMouseLeaveForAxis("y"),Fn.mouseX=-1,Fn.mouseY=-1},this.onWindowResize=function(){Fn.scrollbarWidth=Fn.getScrollbarWidth(),Fn.hideNativeScrollbar()},this.hideScrollbars=function(){Fn.axis.x.track.rect=Fn.axis.x.track.el.getBoundingClientRect(),Fn.axis.y.track.rect=Fn.axis.y.track.el.getBoundingClientRect(),Fn.isWithinBounds(Fn.axis.y.track.rect)||(Fn.axis.y.scrollbar.el.classList.remove(Fn.classNames.visible),Fn.axis.y.isVisible=!1),Fn.isWithinBounds(Fn.axis.x.track.rect)||(Fn.axis.x.scrollbar.el.classList.remove(Fn.classNames.visible),Fn.axis.x.isVisible=!1)},this.onPointerEvent=function(ar){var Wi,lo;Fn.axis.x.track.rect=Fn.axis.x.track.el.getBoundingClientRect(),Fn.axis.y.track.rect=Fn.axis.y.track.el.getBoundingClientRect(),(Fn.axis.x.isOverflowing||Fn.axis.x.forceVisible)&&(Wi=Fn.isWithinBounds(Fn.axis.x.track.rect)),(Fn.axis.y.isOverflowing||Fn.axis.y.forceVisible)&&(lo=Fn.isWithinBounds(Fn.axis.y.track.rect)),(Wi||lo)&&(ar.preventDefault(),ar.stopPropagation(),"mousedown"===ar.type&&(Wi&&(Fn.axis.x.scrollbar.rect=Fn.axis.x.scrollbar.el.getBoundingClientRect(),Fn.isWithinBounds(Fn.axis.x.scrollbar.rect)?Fn.onDragStart(ar,"x"):Fn.onTrackClick(ar,"x")),lo&&(Fn.axis.y.scrollbar.rect=Fn.axis.y.scrollbar.el.getBoundingClientRect(),Fn.isWithinBounds(Fn.axis.y.scrollbar.rect)?Fn.onDragStart(ar,"y"):Fn.onTrackClick(ar,"y"))))},this.drag=function(ar){var lo=Fn.axis[Fn.draggedAxis].track,vo=lo.rect[Fn.axis[Fn.draggedAxis].sizeAttr],Co=Fn.axis[Fn.draggedAxis].scrollbar,Gi=Fn.contentWrapperEl[Fn.axis[Fn.draggedAxis].scrollSizeAttr],os=parseInt(Fn.elStyles[Fn.axis[Fn.draggedAxis].sizeAttr],10);ar.preventDefault(),ar.stopPropagation();var Mi=(("y"===Fn.draggedAxis?ar.pageY:ar.pageX)-lo.rect[Fn.axis[Fn.draggedAxis].offsetAttr]-Fn.axis[Fn.draggedAxis].dragOffset)/(vo-Co.size)*(Gi-os);"x"===Fn.draggedAxis&&(Mi=Fn.isRtl&&An.getRtlHelpers().isRtlScrollbarInverted?Mi-(vo+Co.size):Mi,Mi=Fn.isRtl&&An.getRtlHelpers().isRtlScrollingInverted?-Mi:Mi),Fn.contentWrapperEl[Fn.axis[Fn.draggedAxis].scrollOffsetAttr]=Mi},this.onEndDrag=function(ar){var Wi=Jt(Fn.el),lo=gr(Fn.el);ar.preventDefault(),ar.stopPropagation(),Fn.el.classList.remove(Fn.classNames.dragging),Wi.removeEventListener("mousemove",Fn.drag,!0),Wi.removeEventListener("mouseup",Fn.onEndDrag,!0),Fn.removePreventClickId=lo.setTimeout(function(){Wi.removeEventListener("click",Fn.preventClick,!0),Wi.removeEventListener("dblclick",Fn.preventClick,!0),Fn.removePreventClickId=null})},this.preventClick=function(ar){ar.preventDefault(),ar.stopPropagation()},this.el=Wr,this.minScrollbarWidth=20,this.options=Object.assign({},An.defaultOptions,dr),this.classNames=Object.assign({},An.defaultOptions.classNames,this.options.classNames),this.axis={x:{scrollOffsetAttr:"scrollLeft",sizeAttr:"width",scrollSizeAttr:"scrollWidth",offsetSizeAttr:"offsetWidth",offsetAttr:"left",overflowAttr:"overflowX",dragOffset:0,isOverflowing:!0,isVisible:!1,forceVisible:!1,track:{},scrollbar:{}},y:{scrollOffsetAttr:"scrollTop",sizeAttr:"height",scrollSizeAttr:"scrollHeight",offsetSizeAttr:"offsetHeight",offsetAttr:"top",overflowAttr:"overflowY",dragOffset:0,isOverflowing:!0,isVisible:!1,forceVisible:!1,track:{},scrollbar:{}}},this.removePreventClickId=null,!An.instances.has(this.el)&&(this.recalculate=N()(this.recalculate.bind(this),64),this.onMouseMove=N()(this.onMouseMove.bind(this),64),this.hideScrollbars=Z()(this.hideScrollbars.bind(this),this.options.timeout),this.onWindowResize=Z()(this.onWindowResize.bind(this),64,{leading:!0}),An.getRtlHelpers=K()(An.getRtlHelpers),this.init())}An.getRtlHelpers=function(){var dr=document.createElement("div");dr.innerHTML='<div class="hs-dummy-scrollbar-size"><div style="height: 200%; width: 200%; margin: 10px 0;"></div></div>';var Fn=dr.firstElementChild;document.body.appendChild(Fn);var ar=Fn.firstElementChild;Fn.scrollLeft=0;var Wi=An.getOffset(Fn),lo=An.getOffset(ar);Fn.scrollLeft=999;var vo=An.getOffset(ar);return{isRtlScrollingInverted:Wi.left!==lo.left&&lo.left-vo.left!=0,isRtlScrollbarInverted:Wi.left!==lo.left}},An.getOffset=function(dr){var Fn=dr.getBoundingClientRect(),ar=Jt(dr),Wi=gr(dr);return{top:Fn.top+(Wi.pageYOffset||ar.documentElement.scrollTop),left:Fn.left+(Wi.pageXOffset||ar.documentElement.scrollLeft)}};var Er=An.prototype;return Er.init=function(){An.instances.set(this.el,this),_i()&&(this.initDOM(),this.setAccessibilityAttributes(),this.scrollbarWidth=this.getScrollbarWidth(),this.recalculate(),this.initListeners())},Er.initDOM=function(){var dr=this;if(Array.prototype.filter.call(this.el.children,function(Wi){return Wi.classList.contains(dr.classNames.wrapper)}).length)this.wrapperEl=this.el.querySelector("."+this.classNames.wrapper),this.contentWrapperEl=this.options.scrollableNode||this.el.querySelector("."+this.classNames.contentWrapper),this.contentEl=this.options.contentNode||this.el.querySelector("."+this.classNames.contentEl),this.offsetEl=this.el.querySelector("."+this.classNames.offset),this.maskEl=this.el.querySelector("."+this.classNames.mask),this.placeholderEl=this.findChild(this.wrapperEl,"."+this.classNames.placeholder),this.heightAutoObserverWrapperEl=this.el.querySelector("."+this.classNames.heightAutoObserverWrapperEl),this.heightAutoObserverEl=this.el.querySelector("."+this.classNames.heightAutoObserverEl),this.axis.x.track.el=this.findChild(this.el,"."+this.classNames.track+"."+this.classNames.horizontal),this.axis.y.track.el=this.findChild(this.el,"."+this.classNames.track+"."+this.classNames.vertical);else{for(this.wrapperEl=document.createElement("div"),this.contentWrapperEl=document.createElement("div"),this.offsetEl=document.createElement("div"),this.maskEl=document.createElement("div"),this.contentEl=document.createElement("div"),this.placeholderEl=document.createElement("div"),this.heightAutoObserverWrapperEl=document.createElement("div"),this.heightAutoObserverEl=document.createElement("div"),this.wrapperEl.classList.add(this.classNames.wrapper),this.contentWrapperEl.classList.add(this.classNames.contentWrapper),this.offsetEl.classList.add(this.classNames.offset),this.maskEl.classList.add(this.classNames.mask),this.contentEl.classList.add(this.classNames.contentEl),this.placeholderEl.classList.add(this.classNames.placeholder),this.heightAutoObserverWrapperEl.classList.add(this.classNames.heightAutoObserverWrapperEl),this.heightAutoObserverEl.classList.add(this.classNames.heightAutoObserverEl);this.el.firstChild;)this.contentEl.appendChild(this.el.firstChild);this.contentWrapperEl.appendChild(this.contentEl),this.offsetEl.appendChild(this.contentWrapperEl),this.maskEl.appendChild(this.offsetEl),this.heightAutoObserverWrapperEl.appendChild(this.heightAutoObserverEl),this.wrapperEl.appendChild(this.heightAutoObserverWrapperEl),this.wrapperEl.appendChild(this.maskEl),this.wrapperEl.appendChild(this.placeholderEl),this.el.appendChild(this.wrapperEl)}if(!this.axis.x.track.el||!this.axis.y.track.el){var Fn=document.createElement("div"),ar=document.createElement("div");Fn.classList.add(this.classNames.track),ar.classList.add(this.classNames.scrollbar),Fn.appendChild(ar),this.axis.x.track.el=Fn.cloneNode(!0),this.axis.x.track.el.classList.add(this.classNames.horizontal),this.axis.y.track.el=Fn.cloneNode(!0),this.axis.y.track.el.classList.add(this.classNames.vertical),this.el.appendChild(this.axis.x.track.el),this.el.appendChild(this.axis.y.track.el)}this.axis.x.scrollbar.el=this.axis.x.track.el.querySelector("."+this.classNames.scrollbar),this.axis.y.scrollbar.el=this.axis.y.track.el.querySelector("."+this.classNames.scrollbar),this.options.autoHide||(this.axis.x.scrollbar.el.classList.add(this.classNames.visible),this.axis.y.scrollbar.el.classList.add(this.classNames.visible)),this.el.setAttribute("data-simplebar","init")},Er.setAccessibilityAttributes=function(){var dr=this.options.ariaLabel||"scrollable content";this.contentWrapperEl.setAttribute("tabindex","0"),this.contentWrapperEl.setAttribute("role","region"),this.contentWrapperEl.setAttribute("aria-label",dr)},Er.initListeners=function(){var dr=this,Fn=gr(this.el);this.options.autoHide&&this.el.addEventListener("mouseenter",this.onMouseEnter),["mousedown","click","dblclick"].forEach(function(lo){dr.el.addEventListener(lo,dr.onPointerEvent,!0)}),["touchstart","touchend","touchmove"].forEach(function(lo){dr.el.addEventListener(lo,dr.onPointerEvent,{capture:!0,passive:!0})}),this.el.addEventListener("mousemove",this.onMouseMove),this.el.addEventListener("mouseleave",this.onMouseLeave),this.contentWrapperEl.addEventListener("scroll",this.onScroll),Fn.addEventListener("resize",this.onWindowResize);var ar=!1;this.resizeObserver=new(Fn.ResizeObserver||Gn)(function(){!ar||dr.recalculate()}),this.resizeObserver.observe(this.el),this.resizeObserver.observe(this.contentEl),Fn.requestAnimationFrame(function(){ar=!0}),this.mutationObserver=new Fn.MutationObserver(this.recalculate),this.mutationObserver.observe(this.contentEl,{childList:!0,subtree:!0,characterData:!0})},Er.recalculate=function(){var dr=gr(this.el);this.elStyles=dr.getComputedStyle(this.el),this.isRtl="rtl"===this.elStyles.direction;var Fn=this.heightAutoObserverEl.offsetHeight<=1,ar=this.heightAutoObserverEl.offsetWidth<=1,Wi=this.contentEl.offsetWidth,lo=this.contentWrapperEl.offsetWidth,vo=this.elStyles.overflowX,Co=this.elStyles.overflowY;this.contentEl.style.padding=this.elStyles.paddingTop+" "+this.elStyles.paddingRight+" "+this.elStyles.paddingBottom+" "+this.elStyles.paddingLeft,this.wrapperEl.style.margin="-"+this.elStyles.paddingTop+" -"+this.elStyles.paddingRight+" -"+this.elStyles.paddingBottom+" -"+this.elStyles.paddingLeft;var Gi=this.contentEl.scrollHeight,os=this.contentEl.scrollWidth;this.contentWrapperEl.style.height=Fn?"auto":"100%",this.placeholderEl.style.width=ar?Wi+"px":"auto",this.placeholderEl.style.height=Gi+"px";var jo=this.contentWrapperEl.offsetHeight;this.axis.x.isOverflowing=os>Wi,this.axis.y.isOverflowing=Gi>jo,this.axis.x.isOverflowing="hidden"!==vo&&this.axis.x.isOverflowing,this.axis.y.isOverflowing="hidden"!==Co&&this.axis.y.isOverflowing,this.axis.x.forceVisible="x"===this.options.forceVisible||!0===this.options.forceVisible,this.axis.y.forceVisible="y"===this.options.forceVisible||!0===this.options.forceVisible,this.hideNativeScrollbar();var To=this.axis.x.isOverflowing?this.scrollbarWidth:0;this.axis.x.isOverflowing=this.axis.x.isOverflowing&&os>lo-(this.axis.y.isOverflowing?this.scrollbarWidth:0),this.axis.y.isOverflowing=this.axis.y.isOverflowing&&Gi>jo-To,this.axis.x.scrollbar.size=this.getScrollbarSize("x"),this.axis.y.scrollbar.size=this.getScrollbarSize("y"),this.axis.x.scrollbar.el.style.width=this.axis.x.scrollbar.size+"px",this.axis.y.scrollbar.el.style.height=this.axis.y.scrollbar.size+"px",this.positionScrollbar("x"),this.positionScrollbar("y"),this.toggleTrackVisibility("x"),this.toggleTrackVisibility("y")},Er.getScrollbarSize=function(dr){if(void 0===dr&&(dr="y"),!this.axis[dr].isOverflowing)return 0;var Wi,ar=this.axis[dr].track.el[this.axis[dr].offsetSizeAttr];return Wi=Math.max(~~(ar/this.contentEl[this.axis[dr].scrollSizeAttr]*ar),this.options.scrollbarMinSize),this.options.scrollbarMaxSize&&(Wi=Math.min(Wi,this.options.scrollbarMaxSize)),Wi},Er.positionScrollbar=function(dr){if(void 0===dr&&(dr="y"),this.axis[dr].isOverflowing){var Fn=this.contentWrapperEl[this.axis[dr].scrollSizeAttr],ar=this.axis[dr].track.el[this.axis[dr].offsetSizeAttr],Wi=parseInt(this.elStyles[this.axis[dr].sizeAttr],10),lo=this.axis[dr].scrollbar,vo=this.contentWrapperEl[this.axis[dr].scrollOffsetAttr],Gi=~~((vo="x"===dr&&this.isRtl&&An.getRtlHelpers().isRtlScrollingInverted?-vo:vo)/(Fn-Wi)*(ar-lo.size));Gi="x"===dr&&this.isRtl&&An.getRtlHelpers().isRtlScrollbarInverted?Gi+(ar-lo.size):Gi,lo.el.style.transform="x"===dr?"translate3d("+Gi+"px, 0, 0)":"translate3d(0, "+Gi+"px, 0)"}},Er.toggleTrackVisibility=function(dr){void 0===dr&&(dr="y");var Fn=this.axis[dr].track.el,ar=this.axis[dr].scrollbar.el;this.axis[dr].isOverflowing||this.axis[dr].forceVisible?(Fn.style.visibility="visible",this.contentWrapperEl.style[this.axis[dr].overflowAttr]="scroll"):(Fn.style.visibility="hidden",this.contentWrapperEl.style[this.axis[dr].overflowAttr]="hidden"),ar.style.display=this.axis[dr].isOverflowing?"block":"none"},Er.hideNativeScrollbar=function(){this.offsetEl.style[this.isRtl?"left":"right"]=this.axis.y.isOverflowing||this.axis.y.forceVisible?"-"+this.scrollbarWidth+"px":0,this.offsetEl.style.bottom=this.axis.x.isOverflowing||this.axis.x.forceVisible?"-"+this.scrollbarWidth+"px":0},Er.onMouseMoveForAxis=function(dr){void 0===dr&&(dr="y"),this.axis[dr].track.rect=this.axis[dr].track.el.getBoundingClientRect(),this.axis[dr].scrollbar.rect=this.axis[dr].scrollbar.el.getBoundingClientRect(),this.isWithinBounds(this.axis[dr].scrollbar.rect)?this.axis[dr].scrollbar.el.classList.add(this.classNames.hover):this.axis[dr].scrollbar.el.classList.remove(this.classNames.hover),this.isWithinBounds(this.axis[dr].track.rect)?(this.showScrollbar(dr),this.axis[dr].track.el.classList.add(this.classNames.hover)):this.axis[dr].track.el.classList.remove(this.classNames.hover)},Er.onMouseLeaveForAxis=function(dr){void 0===dr&&(dr="y"),this.axis[dr].track.el.classList.remove(this.classNames.hover),this.axis[dr].scrollbar.el.classList.remove(this.classNames.hover)},Er.showScrollbar=function(dr){void 0===dr&&(dr="y"),this.axis[dr].isVisible||(this.axis[dr].scrollbar.el.classList.add(this.classNames.visible),this.axis[dr].isVisible=!0),this.options.autoHide&&this.hideScrollbars()},Er.onDragStart=function(dr,Fn){void 0===Fn&&(Fn="y");var ar=Jt(this.el),Wi=gr(this.el);this.axis[Fn].dragOffset=("y"===Fn?dr.pageY:dr.pageX)-this.axis[Fn].scrollbar.rect[this.axis[Fn].offsetAttr],this.draggedAxis=Fn,this.el.classList.add(this.classNames.dragging),ar.addEventListener("mousemove",this.drag,!0),ar.addEventListener("mouseup",this.onEndDrag,!0),null===this.removePreventClickId?(ar.addEventListener("click",this.preventClick,!0),ar.addEventListener("dblclick",this.preventClick,!0)):(Wi.clearTimeout(this.removePreventClickId),this.removePreventClickId=null)},Er.onTrackClick=function(dr,Fn){var ar=this;if(void 0===Fn&&(Fn="y"),this.options.clickOnTrack){var Wi=gr(this.el);this.axis[Fn].scrollbar.rect=this.axis[Fn].scrollbar.el.getBoundingClientRect();var vo=this.axis[Fn].scrollbar.rect[this.axis[Fn].offsetAttr],Co=parseInt(this.elStyles[this.axis[Fn].sizeAttr],10),Gi=this.contentWrapperEl[this.axis[Fn].scrollOffsetAttr],jo=("y"===Fn?this.mouseY-vo:this.mouseX-vo)<0?-1:1,To=-1===jo?Gi-Co:Gi+Co;!function li(){var Bn;if(-1===jo)Gi>To&&(ar.contentWrapperEl.scrollTo(((Bn={})[ar.axis[Fn].offsetAttr]=Gi-=ar.options.clickOnTrackSpeed,Bn)),Wi.requestAnimationFrame(li));else if(Gi<To){var lr;ar.contentWrapperEl.scrollTo(((lr={})[ar.axis[Fn].offsetAttr]=Gi+=ar.options.clickOnTrackSpeed,lr)),Wi.requestAnimationFrame(li)}}()}},Er.getContentElement=function(){return this.contentEl},Er.getScrollElement=function(){return this.contentWrapperEl},Er.getScrollbarWidth=function(){try{return"none"===getComputedStyle(this.contentWrapperEl,"::-webkit-scrollbar").display||"scrollbarWidth"in document.documentElement.style||"-ms-overflow-style"in document.documentElement.style?0:Dn(this.el)}catch(dr){return Dn(this.el)}},Er.removeListeners=function(){var dr=this,Fn=gr(this.el);this.options.autoHide&&this.el.removeEventListener("mouseenter",this.onMouseEnter),["mousedown","click","dblclick"].forEach(function(ar){dr.el.removeEventListener(ar,dr.onPointerEvent,!0)}),["touchstart","touchend","touchmove"].forEach(function(ar){dr.el.removeEventListener(ar,dr.onPointerEvent,{capture:!0,passive:!0})}),this.el.removeEventListener("mousemove",this.onMouseMove),this.el.removeEventListener("mouseleave",this.onMouseLeave),this.contentWrapperEl&&this.contentWrapperEl.removeEventListener("scroll",this.onScroll),Fn.removeEventListener("resize",this.onWindowResize),this.mutationObserver&&this.mutationObserver.disconnect(),this.resizeObserver&&this.resizeObserver.disconnect(),this.recalculate.cancel(),this.onMouseMove.cancel(),this.hideScrollbars.cancel(),this.onWindowResize.cancel()},Er.unMount=function(){this.removeListeners(),An.instances.delete(this.el)},Er.isWithinBounds=function(dr){return this.mouseX>=dr.left&&this.mouseX<=dr.left+dr.width&&this.mouseY>=dr.top&&this.mouseY<=dr.top+dr.height},Er.findChild=function(dr,Fn){var ar=dr.matches||dr.webkitMatchesSelector||dr.mozMatchesSelector||dr.msMatchesSelector;return Array.prototype.filter.call(dr.children,function(Wi){return ar.call(Wi,Fn)})[0]},An}();Pr.defaultOptions={autoHide:!0,forceVisible:!1,clickOnTrack:!0,clickOnTrackSpeed:40,classNames:{contentEl:"simplebar-content",contentWrapper:"simplebar-content-wrapper",offset:"simplebar-offset",mask:"simplebar-mask",wrapper:"simplebar-wrapper",placeholder:"simplebar-placeholder",scrollbar:"simplebar-scrollbar",track:"simplebar-track",heightAutoObserverWrapperEl:"simplebar-height-auto-observer-wrapper",heightAutoObserverEl:"simplebar-height-auto-observer",visible:"simplebar-visible",horizontal:"simplebar-horizontal",vertical:"simplebar-vertical",hover:"simplebar-hover",dragging:"simplebar-dragging"},scrollbarMinSize:25,scrollbarMaxSize:0,timeout:1e3},Pr.instances=new WeakMap;const Yt=Pr;var _n=i(74788);const Ge=["*"];let kr=(()=>{class An{constructor(Wr){this.elRef=Wr}ngOnInit(){}ngAfterViewInit(){this.SimpleBar=new Yt(this.elRef.nativeElement,this.options||{})}ngOnDestroy(){this.SimpleBar.unMount(),this.SimpleBar=null}}return An.\u0275fac=function(Wr){return new(Wr||An)(_n.Y36(_n.SBq))},An.\u0275cmp=_n.Xpm({type:An,selectors:[["ngx-simplebar"]],hostAttrs:["data-simplebar","init"],inputs:{options:"options"},ngContentSelectors:Ge,decls:13,vars:0,consts:[[1,"simplebar-wrapper"],[1,"simplebar-height-auto-observer-wrapper"],[1,"simplebar-height-auto-observer"],[1,"simplebar-mask"],[1,"simplebar-offset"],[1,"simplebar-content-wrapper"],[1,"simplebar-content"],[1,"simplebar-placeholder"],[1,"simplebar-track","simplebar-horizontal"],[1,"simplebar-scrollbar"],[1,"simplebar-track","simplebar-vertical"]],template:function(Wr,dr){1&Wr&&(_n.F$t(),_n.TgZ(0,"div",0),_n.TgZ(1,"div",1),_n._UZ(2,"div",2),_n.qZA(),_n.TgZ(3,"div",3),_n.TgZ(4,"div",4),_n.TgZ(5,"div",5),_n.TgZ(6,"div",6),_n.Hsn(7),_n.qZA(),_n.qZA(),_n.qZA(),_n.qZA(),_n._UZ(8,"div",7),_n.qZA(),_n.TgZ(9,"div",8),_n._UZ(10,"div",9),_n.qZA(),_n.TgZ(11,"div",10),_n._UZ(12,"div",9),_n.qZA())},styles:["[data-simplebar]{position:relative;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column;flex-wrap:wrap;-webkit-box-pack:start;justify-content:flex-start;align-content:flex-start;-webkit-box-align:start;align-items:flex-start}.simplebar-wrapper{overflow:hidden;width:inherit;height:inherit;max-width:inherit;max-height:inherit}.simplebar-mask{direction:inherit;position:absolute;overflow:hidden;padding:0;margin:0;left:0;top:0;bottom:0;right:0;width:auto!important;height:auto!important;z-index:0}.simplebar-offset{direction:inherit!important;box-sizing:inherit!important;resize:none!important;position:absolute;top:0;left:0;bottom:0;right:0;padding:0;margin:0;-webkit-overflow-scrolling:touch}.simplebar-content-wrapper{direction:inherit;box-sizing:border-box!important;position:relative;display:block;height:100%;width:auto;max-width:100%;max-height:100%;scrollbar-width:none;-ms-overflow-style:none}.simplebar-content-wrapper::-webkit-scrollbar,.simplebar-hide-scrollbar::-webkit-scrollbar{width:0;height:0}.simplebar-content:after,.simplebar-content:before{content:' ';display:table}.simplebar-placeholder{max-height:100%;max-width:100%;width:100%;pointer-events:none}.simplebar-height-auto-observer-wrapper{box-sizing:inherit!important;height:100%;width:100%;max-width:1px;position:relative;float:left;max-height:1px;overflow:hidden;z-index:-1;padding:0;margin:0;pointer-events:none;-webkit-box-flex:inherit;flex-grow:inherit;flex-shrink:0;flex-basis:0}.simplebar-height-auto-observer{box-sizing:inherit;display:block;opacity:0;position:absolute;top:0;left:0;height:1000%;width:1000%;min-height:1px;min-width:1px;overflow:hidden;pointer-events:none;z-index:-1}.simplebar-track{z-index:1;position:absolute;right:0;bottom:0;pointer-events:none;overflow:hidden}[data-simplebar].simplebar-dragging .simplebar-content{pointer-events:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-user-select:none}[data-simplebar].simplebar-dragging .simplebar-track{pointer-events:all}.simplebar-scrollbar{position:absolute;left:0;right:0;min-height:10px}.simplebar-scrollbar:before{position:absolute;content:'';background:#000;border-radius:7px;left:2px;right:2px;opacity:0;-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.simplebar-scrollbar.simplebar-visible:before{opacity:.5;-webkit-transition:opacity linear;transition:opacity linear}.simplebar-track.simplebar-vertical{top:0;width:11px}.simplebar-track.simplebar-vertical .simplebar-scrollbar:before{top:2px;bottom:2px}.simplebar-track.simplebar-horizontal{left:0;height:11px}.simplebar-track.simplebar-horizontal .simplebar-scrollbar:before{height:100%;left:2px;right:2px}.simplebar-track.simplebar-horizontal .simplebar-scrollbar{right:auto;left:0;top:2px;height:7px;min-height:0;min-width:10px;width:auto}[data-simplebar-direction=rtl] .simplebar-track.simplebar-vertical{right:auto;left:0}.hs-dummy-scrollbar-size{direction:rtl;position:fixed;opacity:0;visibility:hidden;height:500px;width:500px;overflow-y:hidden;overflow-x:scroll}.simplebar-hide-scrollbar{position:fixed;left:0;visibility:hidden;overflow-y:scroll;scrollbar-width:none;-ms-overflow-style:none}","ngx-simplebar{display:block}"],encapsulation:2}),An})(),mi=(()=>{class An{}return An.\u0275fac=function(Wr){return new(Wr||An)},An.\u0275mod=_n.oAB({type:An}),An.\u0275inj=_n.cJS({imports:[[]]}),An})()},35311:v=>{v.exports=function(){var T=document.getSelection();if(!T.rangeCount)return function(){};for(var i=document.activeElement,r=[],u=0;u<T.rangeCount;u++)r.push(T.getRangeAt(u));switch(i.tagName.toUpperCase()){case"INPUT":case"TEXTAREA":i.blur();break;default:i=null}return T.removeAllRanges(),function(){"Caret"===T.type&&T.removeAllRanges(),T.rangeCount||r.forEach(function(p){T.addRange(p)}),i&&i.focus()}}},18807:v=>{var T=v.exports=function(K){return new i(K)};function i(K){this.value=K}function r(K,ee,ue){var ae=[],H=[],se=!0;return function Ee(ie){var he=ue?u(ie):ie,ge={},De=!0,ce={node:he,node_:ie,path:[].concat(ae),parent:H[H.length-1],parents:H,key:ae.slice(-1)[0],isRoot:0===ae.length,level:ae.length,circular:null,update:function(ze,Be){ce.isRoot||(ce.parent.node[ce.key]=ze),ce.node=ze,Be&&(De=!1)},delete:function(ze){delete ce.parent.node[ce.key],ze&&(De=!1)},remove:function(ze){L(ce.parent.node)?ce.parent.node.splice(ce.key,1):delete ce.parent.node[ce.key],ze&&(De=!1)},keys:null,before:function(ze){ge.before=ze},after:function(ze){ge.after=ze},pre:function(ze){ge.pre=ze},post:function(ze){ge.post=ze},stop:function(){se=!1},block:function(){De=!1}};if(!se)return ce;function lt(){if("object"==typeof ce.node&&null!==ce.node){(!ce.keys||ce.node_!==ce.node)&&(ce.keys=p(ce.node)),ce.isLeaf=0==ce.keys.length;for(var ze=0;ze<H.length;ze++)if(H[ze].node_===ie){ce.circular=H[ze];break}}else ce.isLeaf=!0,ce.keys=null;ce.notLeaf=!ce.isLeaf,ce.notRoot=!ce.isRoot}lt();var Ve=ee.call(ce,ce.node);return void 0!==Ve&&ce.update&&ce.update(Ve),ge.before&&ge.before.call(ce,ce.node),De&&("object"==typeof ce.node&&null!==ce.node&&!ce.circular&&(H.push(ce),lt(),Z(ce.keys,function(ze,Be){ae.push(ze),ge.pre&&ge.pre.call(ce,ce.node[ze],ze);var Pe=Ee(ce.node[ze]);ue&&J.call(ce.node,ze)&&(ce.node[ze]=Pe.node),Pe.isLast=Be==ce.keys.length-1,Pe.isFirst=0==Be,ge.post&&ge.post.call(ce,Pe),ae.pop()}),H.pop()),ge.after&&ge.after.call(ce,ce.node)),ce}(K).node}function u(K){if("object"==typeof K&&null!==K){var ee;if(L(K))ee=[];else if(function(K){return"[object Date]"===d(K)}(K))ee=new Date(K.getTime?K.getTime():K);else if(function(K){return"[object RegExp]"===d(K)}(K))ee=new RegExp(K);else if(function(K){return"[object Error]"===d(K)}(K))ee={message:K.message};else if(function(K){return"[object Boolean]"===d(K)}(K))ee=new Boolean(K);else if(function(K){return"[object Number]"===d(K)}(K))ee=new Number(K);else if(function(K){return"[object String]"===d(K)}(K))ee=new String(K);else if(Object.create&&Object.getPrototypeOf)ee=Object.create(Object.getPrototypeOf(K));else if(K.constructor===Object)ee={};else{var ae=function(){};ae.prototype=K.constructor&&K.constructor.prototype||K.__proto__||{},ee=new ae}return Z(p(K),function(H){ee[H]=K[H]}),ee}return K}i.prototype.get=function(K){for(var ee=this.value,ue=0;ue<K.length;ue++){var ae=K[ue];if(!ee||!J.call(ee,ae)){ee=void 0;break}ee=ee[ae]}return ee},i.prototype.has=function(K){for(var ee=this.value,ue=0;ue<K.length;ue++){var ae=K[ue];if(!ee||!J.call(ee,ae))return!1;ee=ee[ae]}return!0},i.prototype.set=function(K,ee){for(var ue=this.value,ae=0;ae<K.length-1;ae++){var H=K[ae];J.call(ue,H)||(ue[H]={}),ue=ue[H]}return ue[K[ae]]=ee,ee},i.prototype.map=function(K){return r(this.value,K,!0)},i.prototype.forEach=function(K){return this.value=r(this.value,K,!1),this.value},i.prototype.reduce=function(K,ee){var ue=1===arguments.length,ae=ue?this.value:ee;return this.forEach(function(H){(!this.isRoot||!ue)&&(ae=K.call(this,ae,H))}),ae},i.prototype.paths=function(){var K=[];return this.forEach(function(ee){K.push(this.path)}),K},i.prototype.nodes=function(){var K=[];return this.forEach(function(ee){K.push(this.node)}),K},i.prototype.clone=function(){var K=[],ee=[];return function ue(ae){for(var H=0;H<K.length;H++)if(K[H]===ae)return ee[H];if("object"==typeof ae&&null!==ae){var se=u(ae);return K.push(ae),ee.push(se),Z(p(ae),function(Ee){se[Ee]=ue(ae[Ee])}),K.pop(),ee.pop(),se}return ae}(this.value)};var p=Object.keys||function(ee){var ue=[];for(var ae in ee)ue.push(ae);return ue};function d(K){return Object.prototype.toString.call(K)}var L=Array.isArray||function(ee){return"[object Array]"===Object.prototype.toString.call(ee)},Z=function(K,ee){if(K.forEach)return K.forEach(ee);for(var ue=0;ue<K.length;ue++)ee(K[ue],ue,K)};Z(p(i.prototype),function(K){T[K]=function(ee){var ue=[].slice.call(arguments,1),ae=new i(ee);return ae[K].apply(ae,ue)}});var J=Object.hasOwnProperty||function(K,ee){return ee in K}},2135:(v,T,i)=>{"use strict";var r=i(90465),u=i(76959),p=/^[\x00-\x20\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/,d=/[\n\r\t]/g,e=/^[A-Za-z][A-Za-z0-9+-.]*:\/\//,_=/:\d+$/,y=/^([a-z][a-z0-9.+-]*:)?(\/\/)?([\\/]+)?([\S\s]*)/i,S=/^[a-zA-Z]:/;function A(se){return(se||"").toString().replace(p,"")}var N=[["#","hash"],["?","query"],function(Ee,ie){return J(ie.protocol)?Ee.replace(/\\/g,"/"):Ee},["/","pathname"],["@","auth",1],[NaN,"host",void 0,1,1],[/:(\d*)$/,"port",void 0,1],[NaN,"hostname",void 0,1,1]],L={hash:1,query:1};function Z(se){var Ee;Ee="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var De,he={},ge=typeof(se=se||Ee.location||{});if("blob:"===se.protocol)he=new ue(unescape(se.pathname),{});else if("string"===ge)for(De in he=new ue(se,{}),L)delete he[De];else if("object"===ge){for(De in se)De in L||(he[De]=se[De]);void 0===he.slashes&&(he.slashes=e.test(se.href))}return he}function J(se){return"file:"===se||"ftp:"===se||"http:"===se||"https:"===se||"ws:"===se||"wss:"===se}function K(se,Ee){se=(se=A(se)).replace(d,""),Ee=Ee||{};var lt,ie=y.exec(se),he=ie[1]?ie[1].toLowerCase():"",ge=!!ie[2],De=!!ie[3],ce=0;return ge?De?(lt=ie[2]+ie[3]+ie[4],ce=ie[2].length+ie[3].length):(lt=ie[2]+ie[4],ce=ie[2].length):De?(lt=ie[3]+ie[4],ce=ie[3].length):lt=ie[4],"file:"===he?ce>=2&&(lt=lt.slice(2)):J(he)?lt=ie[4]:he?ge&&(lt=lt.slice(2)):ce>=2&&J(Ee.protocol)&&(lt=ie[4]),{protocol:he,slashes:ge||J(he),slashesCount:ce,rest:lt}}function ue(se,Ee,ie){if(se=(se=A(se)).replace(d,""),!(this instanceof ue))return new ue(se,Ee,ie);var he,ge,De,ce,lt,Ve,ze=N.slice(),Be=typeof Ee,Pe=this,je=0;for("object"!==Be&&"string"!==Be&&(ie=Ee,Ee=null),ie&&"function"!=typeof ie&&(ie=u.parse),he=!(ge=K(se||"",Ee=Z(Ee))).protocol&&!ge.slashes,Pe.slashes=ge.slashes||he&&Ee.slashes,Pe.protocol=ge.protocol||Ee.protocol||"",se=ge.rest,("file:"===ge.protocol&&(2!==ge.slashesCount||S.test(se))||!ge.slashes&&(ge.protocol||ge.slashesCount<2||!J(Pe.protocol)))&&(ze[3]=[/(.*)/,"pathname"]);je<ze.length;je++)"function"!=typeof(ce=ze[je])?(Ve=ce[1],(De=ce[0])!=De?Pe[Ve]=se:"string"==typeof De?~(lt="@"===De?se.lastIndexOf(De):se.indexOf(De))&&("number"==typeof ce[2]?(Pe[Ve]=se.slice(0,lt),se=se.slice(lt+ce[2])):(Pe[Ve]=se.slice(lt),se=se.slice(0,lt))):(lt=De.exec(se))&&(Pe[Ve]=lt[1],se=se.slice(0,lt.index)),Pe[Ve]=Pe[Ve]||he&&ce[3]&&Ee[Ve]||"",ce[4]&&(Pe[Ve]=Pe[Ve].toLowerCase())):se=ce(se,Pe);ie&&(Pe.query=ie(Pe.query)),he&&Ee.slashes&&"/"!==Pe.pathname.charAt(0)&&(""!==Pe.pathname||""!==Ee.pathname)&&(Pe.pathname=function(se,Ee){if(""===se)return Ee;for(var ie=(Ee||"/").split("/").slice(0,-1).concat(se.split("/")),he=ie.length,ge=ie[he-1],De=!1,ce=0;he--;)"."===ie[he]?ie.splice(he,1):".."===ie[he]?(ie.splice(he,1),ce++):ce&&(0===he&&(De=!0),ie.splice(he,1),ce--);return De&&ie.unshift(""),("."===ge||".."===ge)&&ie.push(""),ie.join("/")}(Pe.pathname,Ee.pathname)),"/"!==Pe.pathname.charAt(0)&&J(Pe.protocol)&&(Pe.pathname="/"+Pe.pathname),r(Pe.port,Pe.protocol)||(Pe.host=Pe.hostname,Pe.port=""),Pe.username=Pe.password="",Pe.auth&&(~(lt=Pe.auth.indexOf(":"))?(Pe.username=Pe.auth.slice(0,lt),Pe.username=encodeURIComponent(decodeURIComponent(Pe.username)),Pe.password=Pe.auth.slice(lt+1),Pe.password=encodeURIComponent(decodeURIComponent(Pe.password))):Pe.username=encodeURIComponent(decodeURIComponent(Pe.auth)),Pe.auth=Pe.password?Pe.username+":"+Pe.password:Pe.username),Pe.origin="file:"!==Pe.protocol&&J(Pe.protocol)&&Pe.host?Pe.protocol+"//"+Pe.host:"null",Pe.href=Pe.toString()}ue.prototype={set:function(se,Ee,ie){var he=this;switch(se){case"query":"string"==typeof Ee&&Ee.length&&(Ee=(ie||u.parse)(Ee)),he[se]=Ee;break;case"port":he[se]=Ee,r(Ee,he.protocol)?Ee&&(he.host=he.hostname+":"+Ee):(he.host=he.hostname,he[se]="");break;case"hostname":he[se]=Ee,he.port&&(Ee+=":"+he.port),he.host=Ee;break;case"host":he[se]=Ee,_.test(Ee)?(Ee=Ee.split(":"),he.port=Ee.pop(),he.hostname=Ee.join(":")):(he.hostname=Ee,he.port="");break;case"protocol":he.protocol=Ee.toLowerCase(),he.slashes=!ie;break;case"pathname":case"hash":if(Ee){var ge="pathname"===se?"/":"#";he[se]=Ee.charAt(0)!==ge?ge+Ee:Ee}else he[se]=Ee;break;case"username":case"password":he[se]=encodeURIComponent(Ee);break;case"auth":var De=Ee.indexOf(":");~De?(he.username=Ee.slice(0,De),he.username=encodeURIComponent(decodeURIComponent(he.username)),he.password=Ee.slice(De+1),he.password=encodeURIComponent(decodeURIComponent(he.password))):he.username=encodeURIComponent(decodeURIComponent(Ee))}for(var ce=0;ce<N.length;ce++){var lt=N[ce];lt[4]&&(he[lt[1]]=he[lt[1]].toLowerCase())}return he.auth=he.password?he.username+":"+he.password:he.username,he.origin="file:"!==he.protocol&&J(he.protocol)&&he.host?he.protocol+"//"+he.host:"null",he.href=he.toString(),he},toString:function(se){(!se||"function"!=typeof se)&&(se=u.stringify);var Ee,ie=this,he=ie.host,ge=ie.protocol;ge&&":"!==ge.charAt(ge.length-1)&&(ge+=":");var De=ge+(ie.protocol&&ie.slashes||J(ie.protocol)?"//":"");return ie.username?(De+=ie.username,ie.password&&(De+=":"+ie.password),De+="@"):ie.password?(De+=":"+ie.password,De+="@"):"file:"!==ie.protocol&&J(ie.protocol)&&!he&&"/"!==ie.pathname&&(De+="@"),(":"===he[he.length-1]||_.test(ie.hostname)&&!ie.port)&&(he+=":"),De+=he+ie.pathname,(Ee="object"==typeof ie.query?se(ie.query):ie.query)&&(De+="?"!==Ee.charAt(0)?"?"+Ee:Ee),ie.hash&&(De+=ie.hash),De}},ue.extractProtocol=K,ue.location=Z,ue.trimLeft=A,ue.qs=u,v.exports=ue},38505:(v,T,i)=>{"use strict";var r=i(87504),u=i(43745);function p(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}T.parse=se,T.resolve=function(ge,De){return se(ge,!1,!0).resolve(De)},T.resolveObject=function(ge,De){return ge?se(ge,!1,!0).resolveObject(De):De},T.format=function(ge){return u.isString(ge)&&(ge=se(ge)),ge instanceof p?ge.format():p.prototype.format.call(ge)},T.Url=p;var d=/^([a-z0-9.+-]+:)/i,e=/:[0-9]*$/,_=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,S=["{","}","|","\\","^","`"].concat(["<",">",'"',"`"," ","\r","\n","\t"]),A=["'"].concat(S),N=["%","/","?",";","#"].concat(A),L=["/","?","#"],J=/^[+a-z0-9A-Z_-]{0,63}$/,K=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,ee={javascript:!0,"javascript:":!0},ue={javascript:!0,"javascript:":!0},ae={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},H=i(36284);function se(ge,De,ce){if(ge&&u.isObject(ge)&&ge instanceof p)return ge;var lt=new p;return lt.parse(ge,De,ce),lt}p.prototype.parse=function(ge,De,ce){if(!u.isString(ge))throw new TypeError("Parameter 'url' must be a string, not "+typeof ge);var lt=ge.indexOf("?"),Ve=-1!==lt&&lt<ge.indexOf("#")?"?":"#",ze=ge.split(Ve);ze[0]=ze[0].replace(/\\/g,"/");var Pe=ge=ze.join(Ve);if(Pe=Pe.trim(),!ce&&1===ge.split("#").length){var je=_.exec(Pe);if(je)return this.path=Pe,this.href=Pe,this.pathname=je[1],je[2]?(this.search=je[2],this.query=De?H.parse(this.search.substr(1)):this.search.substr(1)):De&&(this.search="",this.query={}),this}var He=d.exec(Pe);if(He){var Vt=(He=He[0]).toLowerCase();this.protocol=Vt,Pe=Pe.substr(He.length)}if(ce||He||Pe.match(/^\/\/[^@\/]+@[^@\/]+/)){var it="//"===Pe.substr(0,2);it&&(!He||!ue[He])&&(Pe=Pe.substr(2),this.slashes=!0)}if(!ue[He]&&(it||He&&!ae[He])){for(var tn=-1,It=0;It<L.length;It++)-1!==(Zt=Pe.indexOf(L[It]))&&(-1===tn||Zt<tn)&&(tn=Zt);var Ut,Bt;for(-1!==(Bt=-1===tn?Pe.lastIndexOf("@"):Pe.lastIndexOf("@",tn))&&(Ut=Pe.slice(0,Bt),Pe=Pe.slice(Bt+1),this.auth=decodeURIComponent(Ut)),tn=-1,It=0;It<N.length;It++){var Zt;-1!==(Zt=Pe.indexOf(N[It]))&&(-1===tn||Zt<tn)&&(tn=Zt)}-1===tn&&(tn=Pe.length),this.host=Pe.slice(0,tn),Pe=Pe.slice(tn),this.parseHost(),this.hostname=this.hostname||"";var bt="["===this.hostname[0]&&"]"===this.hostname[this.hostname.length-1];if(!bt)for(var Gt=this.hostname.split(/\./),xt=(It=0,Gt.length);It<xt;It++){var Xt=Gt[It];if(Xt&&!Xt.match(J)){for(var Zn="",Ur=0,di=Xt.length;Ur<di;Ur++)Xt.charCodeAt(Ur)>127?Zn+="x":Zn+=Xt[Ur];if(!Zn.match(J)){var Lr=Gt.slice(0,It),Mr=Gt.slice(It+1),Kr=Xt.match(K);Kr&&(Lr.push(Kr[1]),Mr.unshift(Kr[2])),Mr.length&&(Pe="/"+Mr.join(".")+Pe),this.hostname=Lr.join(".");break}}}this.hostname=this.hostname.length>255?"":this.hostname.toLowerCase(),bt||(this.hostname=r.toASCII(this.hostname)),this.host=(this.hostname||"")+(this.port?":"+this.port:""),this.href+=this.host,bt&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==Pe[0]&&(Pe="/"+Pe))}if(!ee[Vt])for(It=0,xt=A.length;It<xt;It++){var $n=A[It];if(-1!==Pe.indexOf($n)){var Br=encodeURIComponent($n);Br===$n&&(Br=escape($n)),Pe=Pe.split($n).join(Br)}}var Yr=Pe.indexOf("#");-1!==Yr&&(this.hash=Pe.substr(Yr),Pe=Pe.slice(0,Yr));var fi=Pe.indexOf("?");return-1!==fi?(this.search=Pe.substr(fi),this.query=Pe.substr(fi+1),De&&(this.query=H.parse(this.query)),Pe=Pe.slice(0,fi)):De&&(this.search="",this.query={}),Pe&&(this.pathname=Pe),ae[Vt]&&this.hostname&&!this.pathname&&(this.pathname="/"),(this.pathname||this.search)&&(this.path=(this.pathname||"")+(this.search||"")),this.href=this.format(),this},p.prototype.format=function(){var ge=this.auth||"";ge&&(ge=(ge=encodeURIComponent(ge)).replace(/%3A/i,":"),ge+="@");var De=this.protocol||"",ce=this.pathname||"",lt=this.hash||"",Ve=!1,ze="";this.host?Ve=ge+this.host:this.hostname&&(Ve=ge+(-1===this.hostname.indexOf(":")?this.hostname:"["+this.hostname+"]"),this.port&&(Ve+=":"+this.port)),this.query&&u.isObject(this.query)&&Object.keys(this.query).length&&(ze=H.stringify(this.query));var Be=this.search||ze&&"?"+ze||"";return De&&":"!==De.substr(-1)&&(De+=":"),this.slashes||(!De||ae[De])&&!1!==Ve?(Ve="//"+(Ve||""),ce&&"/"!==ce.charAt(0)&&(ce="/"+ce)):Ve||(Ve=""),lt&&"#"!==lt.charAt(0)&&(lt="#"+lt),Be&&"?"!==Be.charAt(0)&&(Be="?"+Be),De+Ve+(ce=ce.replace(/[?#]/g,function(Pe){return encodeURIComponent(Pe)}))+(Be=Be.replace("#","%23"))+lt},p.prototype.resolve=function(ge){return this.resolveObject(se(ge,!1,!0)).format()},p.prototype.resolveObject=function(ge){if(u.isString(ge)){var De=new p;De.parse(ge,!1,!0),ge=De}for(var ce=new p,lt=Object.keys(this),Ve=0;Ve<lt.length;Ve++){var ze=lt[Ve];ce[ze]=this[ze]}if(ce.hash=ge.hash,""===ge.href)return ce.href=ce.format(),ce;if(ge.slashes&&!ge.protocol){for(var Be=Object.keys(ge),Pe=0;Pe<Be.length;Pe++){var je=Be[Pe];"protocol"!==je&&(ce[je]=ge[je])}return ae[ce.protocol]&&ce.hostname&&!ce.pathname&&(ce.path=ce.pathname="/"),ce.href=ce.format(),ce}if(ge.protocol&&ge.protocol!==ce.protocol){if(!ae[ge.protocol]){for(var He=Object.keys(ge),Vt=0;Vt<He.length;Vt++){var it=He[Vt];ce[it]=ge[it]}return ce.href=ce.format(),ce}if(ce.protocol=ge.protocol,ge.host||ue[ge.protocol])ce.pathname=ge.pathname;else{for(var xt=(ge.pathname||"").split("/");xt.length&&!(ge.host=xt.shift()););ge.host||(ge.host=""),ge.hostname||(ge.hostname=""),""!==xt[0]&&xt.unshift(""),xt.length<2&&xt.unshift(""),ce.pathname=xt.join("/")}return ce.search=ge.search,ce.query=ge.query,ce.host=ge.host||"",ce.auth=ge.auth,ce.hostname=ge.hostname||ge.host,ce.port=ge.port,(ce.pathname||ce.search)&&(ce.path=(ce.pathname||"")+(ce.search||"")),ce.slashes=ce.slashes||ge.slashes,ce.href=ce.format(),ce}var Zt=ce.pathname&&"/"===ce.pathname.charAt(0),Ut=ge.host||ge.pathname&&"/"===ge.pathname.charAt(0),Bt=Ut||Zt||ce.host&&ge.pathname,bt=Bt,Gt=ce.pathname&&ce.pathname.split("/")||[],Xt=(xt=ge.pathname&&ge.pathname.split("/")||[],ce.protocol&&!ae[ce.protocol]);if(Xt&&(ce.hostname="",ce.port=null,ce.host&&(""===Gt[0]?Gt[0]=ce.host:Gt.unshift(ce.host)),ce.host="",ge.protocol&&(ge.hostname=null,ge.port=null,ge.host&&(""===xt[0]?xt[0]=ge.host:xt.unshift(ge.host)),ge.host=null),Bt=Bt&&(""===xt[0]||""===Gt[0])),Ut)ce.host=ge.host||""===ge.host?ge.host:ce.host,ce.hostname=ge.hostname||""===ge.hostname?ge.hostname:ce.hostname,ce.search=ge.search,ce.query=ge.query,Gt=xt;else if(xt.length)Gt||(Gt=[]),Gt.pop(),Gt=Gt.concat(xt),ce.search=ge.search,ce.query=ge.query;else if(!u.isNullOrUndefined(ge.search))return Xt&&(ce.hostname=ce.host=Gt.shift(),(Zn=!!(ce.host&&ce.host.indexOf("@")>0)&&ce.host.split("@"))&&(ce.auth=Zn.shift(),ce.host=ce.hostname=Zn.shift())),ce.search=ge.search,ce.query=ge.query,(!u.isNull(ce.pathname)||!u.isNull(ce.search))&&(ce.path=(ce.pathname?ce.pathname:"")+(ce.search?ce.search:"")),ce.href=ce.format(),ce;if(!Gt.length)return ce.pathname=null,ce.path=ce.search?"/"+ce.search:null,ce.href=ce.format(),ce;for(var Ur=Gt.slice(-1)[0],di=(ce.host||ge.host||Gt.length>1)&&("."===Ur||".."===Ur)||""===Ur,Lr=0,Mr=Gt.length;Mr>=0;Mr--)"."===(Ur=Gt[Mr])?Gt.splice(Mr,1):".."===Ur?(Gt.splice(Mr,1),Lr++):Lr&&(Gt.splice(Mr,1),Lr--);if(!Bt&&!bt)for(;Lr--;Lr)Gt.unshift("..");Bt&&""!==Gt[0]&&(!Gt[0]||"/"!==Gt[0].charAt(0))&&Gt.unshift(""),di&&"/"!==Gt.join("/").substr(-1)&&Gt.push("");var Zn,Kr=""===Gt[0]||Gt[0]&&"/"===Gt[0].charAt(0);return Xt&&(ce.hostname=ce.host=Kr?"":Gt.length?Gt.shift():"",(Zn=!!(ce.host&&ce.host.indexOf("@")>0)&&ce.host.split("@"))&&(ce.auth=Zn.shift(),ce.host=ce.hostname=Zn.shift())),(Bt=Bt||ce.host&&Gt.length)&&!Kr&&Gt.unshift(""),Gt.length?ce.pathname=Gt.join("/"):(ce.pathname=null,ce.path=null),(!u.isNull(ce.pathname)||!u.isNull(ce.search))&&(ce.path=(ce.pathname?ce.pathname:"")+(ce.search?ce.search:"")),ce.auth=ge.auth||ce.auth,ce.slashes=ce.slashes||ge.slashes,ce.href=ce.format(),ce},p.prototype.parseHost=function(){var ge=this.host,De=e.exec(ge);De&&(":"!==(De=De[0])&&(this.port=De.substr(1)),ge=ge.substr(0,ge.length-De.length)),ge&&(this.hostname=ge)}},43745:v=>{"use strict";v.exports={isString:function(T){return"string"==typeof T},isObject:function(T){return"object"==typeof T&&null!==T},isNull:function(T){return null===T},isNullOrUndefined:function(T){return null==T}}},58734:(v,T,i)=>{"use strict";var r=i(88280),d=function(N){return/<\/+[^>]+>/.test(N)},e=function(N){return/<[^>]+\/>/.test(N)};function y(A){return(N=A,N.split(/(<\/?[^>]+>)/g).filter(function(L){return""!==L.trim()})).map(function(L){return{value:L,type:S(L)}});var N}function S(A){return d(A)?"ClosingTag":!function(N){return/<[^>!]+>/.test(N)}(N=A)||d(N)||e(N)?e(A)?"SelfClosingTag":"Text":"OpeningTag";var N}v.exports=function(A){var N=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},L=N.indentor,Z=N.textNodesOnSameLine,J=0,K=[];L=L||" ";var ee=y(A).map(function(ue,ae,H){var se=ue.value,Ee=ue.type;"ClosingTag"===Ee&&J--;var ie=r(L,J),he=ie+se;if("OpeningTag"===Ee&&J++,Z){var ge=H[ae-1],De=H[ae-2];"ClosingTag"===Ee&&"Text"===ge.type&&"OpeningTag"===De.type&&(he=""+ie+De.value+ge.value+se,K.push(ae-2,ae-1))}return he});return K.forEach(function(ue){return ee[ue]=null}),ee.filter(function(ue){return!!ue}).join("\n")}},1653:function(v,T){var i,r,u;r=[],void 0!==(u="function"==typeof(i=function(){"use strict";var p=function(L){return L&&"getComputedStyle"in window&&"smooth"===window.getComputedStyle(L)["scroll-behavior"]};if("undefined"==typeof window||!("document"in window))return{};var d=function(L,Z,J){Z=Z||999,!J&&0!==J&&(J=9);var K,ee=function(ge){K=ge},ue=function(){clearTimeout(K),ee(0)},ae=function(ge){return Math.max(0,L.getTopOf(ge)-J)},H=function(ge,De,ce){if(ue(),0===De||De&&De<0||p(L.body))L.toY(ge),ce&&ce();else{var lt=L.getY(),Ve=Math.max(0,ge)-lt,ze=(new Date).getTime();De=De||Math.min(Math.abs(Ve),Z),function Be(){ee(setTimeout(function(){var Pe=Math.min(1,((new Date).getTime()-ze)/De),je=Math.max(0,Math.floor(lt+Ve*(Pe<.5?2*Pe*Pe:Pe*(4-2*Pe)-1)));L.toY(je),Pe<1&&L.getHeight()+je<L.body.scrollHeight?Be():(setTimeout(ue,99),ce&&ce())},9))}()}},se=function(ge,De,ce){H(ae(ge),De,ce)};return{setup:function(ge,De){return(0===ge||ge)&&(Z=ge),(0===De||De)&&(J=De),{defaultDuration:Z,edgeOffset:J}},to:se,toY:H,intoView:function(ge,De,ce){var lt=ge.getBoundingClientRect().height,Ve=L.getTopOf(ge)+lt,ze=L.getHeight(),Be=L.getY(),Pe=Be+ze;ae(ge)<Be||lt+J>ze?se(ge,De,ce):Ve+J>Pe?H(Ve-ze+J,De,ce):ce&&ce()},center:function(ge,De,ce,lt){H(Math.max(0,L.getTopOf(ge)-L.getHeight()/2+(ce||ge.getBoundingClientRect().height/2)),De,lt)},stop:ue,moving:function(){return!!K},getY:L.getY,getTopOf:L.getTopOf}},e=document.documentElement,_=function(){return window.scrollY||e.scrollTop},y=d({body:document.scrollingElement||document.body,toY:function(L){window.scrollTo(0,L)},getY:_,getHeight:function(){return window.innerHeight||e.clientHeight},getTopOf:function(L){return L.getBoundingClientRect().top+_()-e.offsetTop}});if(y.createScroller=function(L,Z,J){return d({body:L,toY:function(K){L.scrollTop=K},getY:function(){return L.scrollTop},getHeight:function(){return Math.min(L.clientHeight,window.innerHeight||e.clientHeight)},getTopOf:function(K){return K.offsetTop}},Z,J)},"addEventListener"in window&&!window.noZensmooth&&!p(document.body)){var S="history"in window&&"pushState"in history,A=S&&"scrollRestoration"in history;A&&(history.scrollRestoration="auto"),window.addEventListener("load",function(){A&&(setTimeout(function(){history.scrollRestoration="manual"},9),window.addEventListener("popstate",function(L){L.state&&"zenscrollY"in L.state&&y.toY(L.state.zenscrollY)},!1)),window.location.hash&&setTimeout(function(){var L=y.setup().edgeOffset;if(L){var Z=document.getElementById(window.location.href.split("#")[1]);if(Z){var J=Math.max(0,y.getTopOf(Z)-L),K=y.getY()-J;0<=K&&K<9&&window.scrollTo(0,J)}}},9)},!1);var N=new RegExp("(^|\\s)noZensmooth(\\s|$)");window.addEventListener("click",function(L){for(var Z=L.target;Z&&"A"!==Z.tagName;)Z=Z.parentNode;if(!(!Z||1!==L.which||L.shiftKey||L.metaKey||L.ctrlKey||L.altKey)){if(A){var J=history.state&&"object"==typeof history.state?history.state:{};J.zenscrollY=y.getY();try{history.replaceState(J,"")}catch(se){}}var K=Z.getAttribute("href")||"";if(0===K.indexOf("#")&&!N.test(Z.className)){var ee=0,ue=document.getElementById(K.substring(1));if("#"!==K){if(!ue)return;ee=y.getTopOf(ue)}L.preventDefault();var ae=function(){window.location=K},H=y.setup().edgeOffset;H&&(ee=Math.max(0,ee-H),S&&(ae=function(){history.pushState({},"",K)})),y.toY(ee,null,ae)}}},!1)}return y}())?i.apply(T,r):i)&&(v.exports=u)},66265:(v,T,i)=>{"use strict";i.d(T,{B:()=>e});var r=i(12057),u=i(6283),p=i(44466),d=i(74788);let e=(()=>{class _{}return _.\u0275fac=function(S){return new(S||_)},_.\u0275mod=d.oAB({type:_}),_.\u0275inj=d.cJS({imports:[[r.ez,p.m,u.Bz]]}),_})()},98056:(v,T,i)=>{"use strict";i.d(T,{p:()=>ue});var r=i(64762),u=i(58497),p=i(25917),d=i(19773),e=i(93523),_=i(74788);let y=class{constructor(H){this.http=H,this.url="api/perf_counters"}list(){return this.http.get(this.url)}get(H,se){return this.http.get(`${this.url}/${H}/${se}`).pipe((0,d.zg)(Ee=>(0,p.of)(Ee.counters)))}};y.\u0275fac=function(H){return new(H||y)(_.LFG(u.eN))},y.\u0275prov=_.Yz7({token:y,factory:y.\u0275fac,providedIn:"root"}),y=(0,r.gn)([e.o,(0,r.w6)("design:paramtypes",[u.eN])],y);var S=i(12057),A=i(35905),N=i(34501),L=i(66369);const Z=["valueTpl"];function J(ae,H){if(1&ae&&(_._uU(0),_.ALo(1,"dimless")),2&ae){const se=H.row;_.AsE(" ",_.lcZ(1,2,se.value)," ",se.unit," ")}}function K(ae,H){if(1&ae){const se=_.EpF();_.TgZ(0,"cd-table",2),_.NdJ("fetchData",function(ie){return _.CHM(se),_.oxw().getCounters(ie)}),_.YNc(1,J,2,4,"ng-template",null,3,_.W1O),_.qZA()}if(2&ae){const se=_.oxw();_.Q6J("data",se.counters)("columns",se.columns)("autoSave",!1)}}function ee(ae,H){1&ae&&(_.TgZ(0,"cd-alert-panel",4),_.SDv(1,5),_.qZA())}let ue=(()=>{class ae{constructor(se){this.performanceCounterService=se,this.columns=[],this.counters=[]}ngOnInit(){this.columns=[{name:"Name",prop:"name",flexGrow:1},{name:"Description",prop:"description",flexGrow:1},{name:"Value",prop:"value",cellTemplate:this.valueTpl,flexGrow:1}]}getCounters(se){this.performanceCounterService.get(this.serviceType,this.serviceId).subscribe(Ee=>{this.counters=Ee},Ee=>{404===Ee.status?(Ee.preventDefault(),this.counters=null):se.error()})}}return ae.\u0275fac=function(se){return new(se||ae)(_.Y36(y))},ae.\u0275cmp=_.Xpm({type:ae,selectors:[["cd-table-performance-counter"]],viewQuery:function(se,Ee){if(1&se&&_.Gf(Z,5),2&se){let ie;_.iGM(ie=_.CRH())&&(Ee.valueTpl=ie.first)}},inputs:{serviceType:"serviceType",serviceId:"serviceId"},decls:3,vars:2,consts:function(){let H;return H="Performance counters not available",[["columnMode","flex",3,"data","columns","autoSave","fetchData",4,"ngIf","ngIfElse"],["warning",""],["columnMode","flex",3,"data","columns","autoSave","fetchData"],["valueTpl",""],["type","warning"],H]},template:function(se,Ee){if(1&se&&(_.YNc(0,K,3,3,"cd-table",0),_.YNc(1,ee,2,0,"ng-template",null,1,_.W1O)),2&se){const ie=_.MAs(2);_.Q6J("ngIf",Ee.counters)("ngIfElse",ie)}},directives:[S.O5,A.a,N.G],pipes:[L.n],styles:[""]}),ae})()},370:(v,T,i)=>{"use strict";i.d(T,{t:()=>y});var r=i(12057),u=i(38549),p=i(37496),d=i(2149),e=i(44466),_=i(74788);let y=(()=>{class S{}return S.\u0275fac=function(N){return new(N||S)},S.\u0275mod=_.oAB({type:S}),S.\u0275inj=_.cJS({imports:[[r.ez,d.t,e.m,u.Oz,p.b]]}),S})()},49671:(v,T,i)=>{"use strict";i.d(T,{j:()=>_});var r=i(23815),u=i.n(r),p=i(370);class d{constructor(S){if(this.type=S,!this.isValidType())throw new Error("Wrong placement group category type");this.setTypeStates()}isValidType(){return d.VALID_CATEGORIES.includes(this.type)}setTypeStates(){switch(this.type){case d.CATEGORY_CLEAN:this.states=["active","clean"];break;case d.CATEGORY_WORKING:this.states=["activating","backfill_wait","backfilling","creating","deep","degraded","forced_backfill","forced_recovery","peering","peered","recovering","recovery_wait","repair","scrubbing","snaptrim","snaptrim_wait"];break;case d.CATEGORY_WARNING:this.states=["backfill_toofull","backfill_unfound","down","incomplete","inconsistent","recovery_toofull","recovery_unfound","remapped","snaptrim_error","stale","undersized"];break;default:this.states=[]}}}d.CATEGORY_CLEAN="clean",d.CATEGORY_WORKING="working",d.CATEGORY_WARNING="warning",d.CATEGORY_UNKNOWN="unknown",d.VALID_CATEGORIES=[d.CATEGORY_CLEAN,d.CATEGORY_WORKING,d.CATEGORY_WARNING,d.CATEGORY_UNKNOWN];var e=i(74788);let _=(()=>{class y{constructor(){this.categories=this.createCategories()}getAllTypes(){return d.VALID_CATEGORIES}getTypeByStates(A){const N=this.getPgStatesFromText(A);if(0===N.length)return d.CATEGORY_UNKNOWN;const L=u().zipObject(d.VALID_CATEGORIES,d.VALID_CATEGORIES.map(J=>u().intersection(this.categories[J].states,N).length));if(L[d.CATEGORY_WARNING]>0)return d.CATEGORY_WARNING;const Z=L[d.CATEGORY_WORKING];return N.length>L[d.CATEGORY_CLEAN]+Z?d.CATEGORY_UNKNOWN:Z?d.CATEGORY_WORKING:d.CATEGORY_CLEAN}createCategories(){return u().zipObject(d.VALID_CATEGORIES,d.VALID_CATEGORIES.map(A=>new d(A)))}getPgStatesFromText(A){const N=A.replace(/[^a-z_]+/g," ").trim().split(" ");return u().uniq(N)}}return y.\u0275fac=function(A){return new(A||y)},y.\u0275prov=e.Yz7({token:y,factory:y.\u0275fac,providedIn:p.t}),y})()},49552:(v,T,i)=>{"use strict";i.r(T),i.d(T,{AuthModule:()=>uo,RoutedAuthModule:()=>$o});var r=i(12057),u=i(24751),p=i(6283),d=i(38549),e=i(37496),_=i(79512),y=i(44466),S=i(23815),A=i.n(S),N=i(35758),L=i(18001),Z=i(93614),J=i(95463),K=i(77205),ee=i(97161),ue=(()=>((ue||(ue={})).editing="editing",ue))();class ae{}var H=i(74788),se=i(25917),Ee=i(19773),ie=i(58497);let he=(()=>{class tr{constructor(Rt){this.http=Rt}list(){return this.http.get("api/role")}delete(Rt){return this.http.delete(`api/role/${Rt}`)}get(Rt){return this.http.get(`api/role/${Rt}`)}create(Rt){return this.http.post("api/role",Rt)}clone(Rt,_t){return this.http.post(`api/role/${Rt}/clone`,{new_name:_t})}update(Rt){return this.http.put(`api/role/${Rt.name}`,Rt)}exists(Rt){return this.list().pipe((0,Ee.zg)(_t=>{const mt=_t.some(jt=>jt.name===Rt);return(0,se.of)(mt)}))}}return tr.\u0275fac=function(Rt){return new(Rt||tr)(H.LFG(ie.eN))},tr.\u0275prov=H.Yz7({token:tr,factory:tr.\u0275fac,providedIn:"root"}),tr})(),ge=(()=>{class tr{constructor(Rt){this.http=Rt}list(){return this.http.get("ui-api/scope")}}return tr.\u0275fac=function(Rt){return new(Rt||tr)(H.LFG(ie.eN))},tr.\u0275prov=H.Yz7({token:tr,factory:tr.\u0275fac,providedIn:"root"}),tr})();var De=i(63622),ce=i(41582),lt=i(56310),Ve=i(87925),ze=i(94276),Be=i(82945),Pe=i(35905),je=i(30839),He=i(10545);const Vt=["headerPermissionCheckboxTpl"],it=["cellScopeCheckboxTpl"],tn=["cellPermissionCheckboxTpl"];function It(tr,Ar){1&tr&&(H.TgZ(0,"span",25),H.SDv(1,26),H.qZA())}function Zt(tr,Ar){1&tr&&(H.TgZ(0,"span",25),H.SDv(1,27),H.qZA())}const Ut=function(tr){return{required:tr}};function Bt(tr,Ar){if(1&tr){const Rt=H.EpF();H.TgZ(0,"div",4),H.TgZ(1,"form",5,6),H.TgZ(3,"div",7),H.TgZ(4,"div",8),H.SDv(5,9),H.ALo(6,"titlecase"),H.ALo(7,"upperFirst"),H.qZA(),H.TgZ(8,"div",10),H.TgZ(9,"div",11),H.TgZ(10,"label",12),H.SDv(11,13),H.qZA(),H.TgZ(12,"div",14),H._UZ(13,"input",15),H.YNc(14,It,2,0,"span",16),H.YNc(15,Zt,2,0,"span",16),H.qZA(),H.qZA(),H.TgZ(16,"div",11),H.TgZ(17,"label",17),H.SDv(18,18),H.qZA(),H.TgZ(19,"div",14),H._UZ(20,"input",19),H.qZA(),H.qZA(),H.TgZ(21,"div",11),H.TgZ(22,"label",20),H.SDv(23,21),H.qZA(),H.TgZ(24,"div",14),H._UZ(25,"cd-table",22),H.qZA(),H.qZA(),H.qZA(),H.TgZ(26,"div",23),H.TgZ(27,"cd-form-button-panel",24),H.NdJ("submitActionEvent",function(){return H.CHM(Rt),H.oxw().submit()}),H.ALo(28,"titlecase"),H.ALo(29,"upperFirst"),H.qZA(),H.qZA(),H.qZA(),H.qZA(),H.qZA()}if(2&tr){const Rt=H.MAs(2),_t=H.oxw();H.xp6(1),H.Q6J("formGroup",_t.roleForm),H.xp6(6),H.pQV(H.lcZ(6,15,_t.action))(H.lcZ(7,17,_t.resource)),H.QtT(5),H.xp6(3),H.Q6J("ngClass",H.VKq(23,Ut,_t.mode!==_t.roleFormMode.editing)),H.xp6(4),H.Q6J("ngIf",_t.roleForm.showError("name",Rt,"required")),H.xp6(1),H.Q6J("ngIf",_t.roleForm.showError("name",Rt,"notUnique")),H.xp6(10),H.Q6J("data",_t.scopes_permissions)("columns",_t.columns)("toolHeader",!1)("autoReload",!1)("autoSave",!1)("footer",!1)("limit",0),H.xp6(2),H.Q6J("form",_t.roleForm)("submitText",H.lcZ(28,19,_t.action)+" "+H.lcZ(29,21,_t.resource))}}function bt(tr,Ar){if(1&tr){const Rt=H.EpF();H.TgZ(0,"div",28),H.TgZ(1,"input",29),H.NdJ("change",function(mt){const jt=H.CHM(Rt),on=jt.row,si=jt.column;return H.oxw().onClickCellCheckbox(on.scope,si.prop,mt)}),H.qZA(),H.TgZ(2,"label",30),H._uU(3),H.qZA(),H.qZA()}if(2&tr){const Rt=Ar.row,_t=Ar.value,mt=H.oxw();H.xp6(1),H.MGl("id","scope_",Rt.scope,""),H.Q6J("checked",mt.isRowChecked(Rt.scope)),H.xp6(1),H.MGl("for","scope_",Rt.scope,""),H.xp6(1),H.Oqu(_t)}}function Gt(tr,Ar){if(1&tr){const Rt=H.EpF();H.TgZ(0,"div",28),H.TgZ(1,"input",31),H.NdJ("change",function(mt){const jt=H.CHM(Rt),on=jt.row,si=jt.column;return H.oxw().onClickCellCheckbox(on.scope,si.prop,mt)}),H.qZA(),H._UZ(2,"label",32),H.qZA()}if(2&tr){const Rt=Ar.column,_t=Ar.row,mt=Ar.value;H.xp6(1),H.Q6J("checked",mt)("id",_t.scope+"-"+Rt.prop),H.xp6(1),H.Q6J("for",_t.scope+"-"+Rt.prop)}}function xt(tr,Ar){if(1&tr){const Rt=H.EpF();H.TgZ(0,"div",28),H.TgZ(1,"input",29),H.NdJ("change",function(mt){const on=H.CHM(Rt).column;return H.oxw().onClickHeaderCheckbox(on.prop,mt)}),H.qZA(),H.TgZ(2,"label",33),H._uU(3),H.qZA(),H.qZA()}if(2&tr){const Rt=Ar.column,_t=H.oxw();H.xp6(1),H.MGl("id","header_",Rt.prop,""),H.Q6J("checked",_t.isHeaderChecked(Rt.prop)),H.xp6(1),H.MGl("for","header_",Rt.prop,""),H.xp6(1),H.Oqu(Rt.name)}}let Xt=(()=>{class tr extends Z.E{constructor(Rt,_t,mt,jt,on,si){super(),this.route=Rt,this.router=_t,this.roleService=mt,this.scopeService=jt,this.notificationService=on,this.actionLabels=si,this.scopes=[],this.scopes_permissions=[],this.roleFormMode=ue,this.resource="role",this.createForm(),this.listenToChanges()}createForm(){this.roleForm=new J.d({name:new u.NI("",{validators:[u.kI.required],asyncValidators:[K.h.unique(this.roleService.exists,this.roleService)]}),description:new u.NI(""),scopes_permissions:new u.NI({})})}ngOnInit(){this.columns=[{prop:"scope",name:"All",flexGrow:2,cellTemplate:this.cellScopeCheckboxTpl,headerTemplate:this.headerPermissionCheckboxTpl},{prop:"read",name:"Read",flexGrow:1,cellClass:"text-center",cellTemplate:this.cellPermissionCheckboxTpl,headerTemplate:this.headerPermissionCheckboxTpl},{prop:"create",name:"Create",flexGrow:1,cellClass:"text-center",cellTemplate:this.cellPermissionCheckboxTpl,headerTemplate:this.headerPermissionCheckboxTpl},{prop:"update",name:"Update",flexGrow:1,cellClass:"text-center",cellTemplate:this.cellPermissionCheckboxTpl,headerTemplate:this.headerPermissionCheckboxTpl},{prop:"delete",name:"Delete",flexGrow:1,cellClass:"text-center",cellTemplate:this.cellPermissionCheckboxTpl,headerTemplate:this.headerPermissionCheckboxTpl}],this.router.url.startsWith("/user-management/roles/edit")?(this.mode=this.roleFormMode.editing,this.action=this.actionLabels.EDIT):this.action=this.actionLabels.CREATE,this.mode===this.roleFormMode.editing?this.initEdit():this.initCreate()}initCreate(){this.scopeService.list().subscribe(Rt=>{this.scopes=Rt,this.roleForm.get("scopes_permissions").setValue({}),this.loadingReady()})}initEdit(){this.roleForm.get("name").disable(),this.route.params.subscribe(Rt=>{const _t=[];_t.push(this.scopeService.list()),_t.push(this.roleService.get(Rt.name)),(0,N.D)(_t).subscribe(mt=>{this.scopes=mt[0],["name","description","scopes_permissions"].forEach(jt=>this.roleForm.get(jt).setValue(mt[1][jt])),this.loadingReady()})})}listenToChanges(){this.roleForm.get("scopes_permissions").valueChanges.subscribe(Rt=>{const _t=[];A().each(this.scopes,mt=>{const jt={read:!1,create:!1,update:!1,delete:!1};jt.scope=mt,mt in Rt&&A().each(Rt[mt],on=>{jt[on]=!0}),_t.push(jt)}),this.scopes_permissions=_t})}isRowChecked(Rt){const _t=A().find(this.scopes_permissions,mt=>mt.scope===Rt);return!A().isUndefined(_t)&&_t.read&&_t.create&&_t.update&&_t.delete}isHeaderChecked(Rt){let _t=[Rt];return"scope"===Rt&&(_t=["read","create","update","delete"]),_t.every(mt=>this.scopes_permissions.every(jt=>jt[mt]))}onClickCellCheckbox(Rt,_t,mt=null){const jt=A().cloneDeep(this.roleForm.getValue("scopes_permissions"));let on=[_t];"scope"===_t&&(on=["read","create","update","delete"]),Rt in jt||(jt[Rt]=[]),mt&&mt.target.checked||!A().isEqual(on.sort(),A().intersection(jt[Rt],on).sort())?jt[Rt]=A().union(jt[Rt],on):(jt[Rt]=A().difference(jt[Rt],on),A().isEmpty(jt[Rt])&&A().unset(jt,Rt)),this.roleForm.get("scopes_permissions").setValue(jt)}onClickHeaderCheckbox(Rt,_t){const mt=A().cloneDeep(this.roleForm.getValue("scopes_permissions"));let jt=[Rt];"scope"===Rt&&(jt=["read","create","update","delete"]),A().each(jt,on=>{A().each(this.scopes,si=>{_t.target.checked?mt[si]=A().union(mt[si],[on]):(mt[si]=A().difference(mt[si],[on]),A().isEmpty(mt[si])&&A().unset(mt,si))})}),this.roleForm.get("scopes_permissions").setValue(mt)}getRequest(){const Rt=new ae;return["name","description","scopes_permissions"].forEach(_t=>Rt[_t]=this.roleForm.get(_t).value),Rt}createAction(){const Rt=this.getRequest();this.roleService.create(Rt).subscribe(()=>{this.notificationService.show(L.k.success,"Created role '" + Rt.name + "'"),this.router.navigate(["/user-management/roles"])},()=>{this.roleForm.setErrors({cdSubmitButton:!0})})}editAction(){const Rt=this.getRequest();this.roleService.update(Rt).subscribe(()=>{this.notificationService.show(L.k.success,"Updated role '" + Rt.name + "'"),this.router.navigate(["/user-management/roles"])},()=>{this.roleForm.setErrors({cdSubmitButton:!0})})}submit(){this.mode===this.roleFormMode.editing?this.editAction():this.createAction()}}return tr.\u0275fac=function(Rt){return new(Rt||tr)(H.Y36(p.gz),H.Y36(p.F0),H.Y36(he),H.Y36(ge),H.Y36(ee.g),H.Y36(_.p4))},tr.\u0275cmp=H.Xpm({type:tr,selectors:[["cd-role-form"]],viewQuery:function(Rt,_t){if(1&Rt&&(H.Gf(Vt,7),H.Gf(it,7),H.Gf(tn,7)),2&Rt){let mt;H.iGM(mt=H.CRH())&&(_t.headerPermissionCheckboxTpl=mt.first),H.iGM(mt=H.CRH())&&(_t.cellScopeCheckboxTpl=mt.first),H.iGM(mt=H.CRH())&&(_t.cellPermissionCheckboxTpl=mt.first)}},features:[H.qOj],decls:7,vars:1,consts:function(){let Ar,Rt,_t,mt,jt,on,si,Vi;return Ar="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",Rt="Name",_t="Name...",mt="Description",jt="Description...",on="Permissions",si="This field is required.",Vi="The chosen name is already in use.",[["class","cd-col-form",4,"cdFormLoading"],["cellScopeCheckboxTpl",""],["cellPermissionCheckboxTpl",""],["headerPermissionCheckboxTpl",""],[1,"cd-col-form"],["name","roleForm","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"card"],[1,"card-header"],Ar,[1,"card-body"],[1,"form-group","row"],["for","name",1,"cd-col-form-label",3,"ngClass"],Rt,[1,"cd-col-form-input"],["type","text","placeholder",_t,"id","name","name","name","formControlName","name","autofocus","",1,"form-control"],["class","invalid-feedback",4,"ngIf"],["for","description",1,"cd-col-form-label"],mt,["type","text","placeholder",jt,"id","description","name","description","formControlName","description",1,"form-control"],[1,"cd-col-form-label"],on,["columnMode","flex",3,"data","columns","toolHeader","autoReload","autoSave","footer","limit"],[1,"card-footer"],["wrappingClass","text-right",3,"form","submitText","submitActionEvent"],[1,"invalid-feedback"],si,Vi,[1,"custom-control","custom-checkbox"],["type","checkbox",1,"custom-control-input",3,"id","checked","change"],[1,"datatable-permissions-scope-cell-label","custom-control-label",3,"for"],["type","checkbox",1,"custom-control-input",3,"checked","id","change"],[1,"custom-control-label",3,"for"],[1,"datatable-permissions-header-cell-label","custom-control-label",3,"for"]]},template:function(Rt,_t){1&Rt&&(H.YNc(0,Bt,30,25,"div",0),H.YNc(1,bt,4,4,"ng-template",null,1,H.W1O),H.YNc(3,Gt,3,3,"ng-template",null,2,H.W1O),H.YNc(5,xt,4,4,"ng-template",null,3,H.W1O)),2&Rt&&H.Q6J("cdFormLoading",_t.loading)},directives:[De.y,u._Y,u.JL,u.sg,ce.V,lt.P,r.mk,Ve.o,u.Fj,ze.b,u.JJ,u.u,Be.U,r.O5,Pe.a,je.p],pipes:[r.rS,He.m],styles:[".datatable-permissions-header-cell-label[_ngcontent-%COMP%], .datatable-permissions-scope-cell-label[_ngcontent-%COMP%]{font-weight:bold}"]}),tr})();var Zn=i(68136),Ur=i(30982),di=i(65683),Lr=i(99466),Mr=i(65862),Kr=i(68774),ei=i(41039),Nn=i(51847),$n=i(74937),Br=i(63285);let Yr=(()=>{class tr{constructor(Rt){this.router=Rt}}return tr.\u0275fac=function(Rt){return new(Rt||tr)(H.Y36(p.F0))},tr.\u0275cmp=H.Xpm({type:tr,selectors:[["cd-user-tabs"]],decls:8,vars:1,consts:function(){let Ar,Rt;return Ar="Users",Rt="Roles",[["ngbNav","",1,"nav-tabs",3,"activeId","navChange"],["nav","ngbNav"],["ngbNavItem","/user-management/users"],["ngbNavLink",""],Ar,["ngbNavItem","/user-management/roles"],Rt]},template:function(Rt,_t){1&Rt&&(H.TgZ(0,"ul",0,1),H.NdJ("navChange",function(jt){return _t.router.navigate([jt.nextId])}),H.TgZ(2,"li",2),H.TgZ(3,"a",3),H.SDv(4,4),H.qZA(),H.qZA(),H.TgZ(5,"li",5),H.TgZ(6,"a",3),H.SDv(7,6),H.qZA(),H.qZA(),H.qZA()),2&Rt&&H.Q6J("activeId",_t.router.url)},directives:[d.Pz,d.nv,d.Vx],styles:[""]}),tr})();var fi=i(94928);function ki(tr,Ar){if(1&tr&&(H.ynx(0),H._UZ(1,"cd-table",1),H.BQk()),2&tr){const Rt=H.oxw();H.xp6(1),H.Q6J("data",Rt.scopes_permissions)("columns",Rt.columns)("toolHeader",!1)("autoReload",!1)("autoSave",!1)("footer",!1)("limit",0)}}let Hi=(()=>{class tr{constructor(){this.scopes_permissions=[]}ngOnInit(){this.columns=[{prop:"scope",name:"Scope",flexGrow:2},{prop:"read",name:"Read",flexGrow:1,cellClass:"text-center",cellTransformation:Lr.e.checkIcon},{prop:"create",name:"Create",flexGrow:1,cellClass:"text-center",cellTransformation:Lr.e.checkIcon},{prop:"update",name:"Update",flexGrow:1,cellClass:"text-center",cellTransformation:Lr.e.checkIcon},{prop:"delete",name:"Delete",flexGrow:1,cellClass:"text-center",cellTransformation:Lr.e.checkIcon}]}ngOnChanges(){if(this.selection){this.selectedItem=this.selection;const Rt=[];A().each(this.scopes,_t=>{const mt={read:!1,create:!1,update:!1,delete:!1};mt.scope=_t,_t in this.selectedItem.scopes_permissions&&A().each(this.selectedItem.scopes_permissions[_t],jt=>{mt[jt]=!0}),Rt.push(mt)}),this.scopes_permissions=Rt}}}return tr.\u0275fac=function(Rt){return new(Rt||tr)},tr.\u0275cmp=H.Xpm({type:tr,selectors:[["cd-role-details"]],inputs:{selection:"selection",scopes:"scopes"},features:[H.TTD],decls:1,vars:1,consts:[[4,"ngIf"],["columnMode","flex",3,"data","columns","toolHeader","autoReload","autoSave","footer","limit"]],template:function(Rt,_t){1&Rt&&H.YNc(0,ki,2,7,"ng-container",0),2&Rt&&H.Q6J("ngIf",_t.selection)},directives:[r.O5,Pe.a],styles:[".fa[_ngcontent-%COMP%]{font-size:large}.fa.fa-square-o[_ngcontent-%COMP%]{color:#ced4da}"]}),tr})(),Cn=(()=>{class tr extends Zn.o{constructor(Rt,_t,mt,jt,on,si,Vi,_o){super(),this.roleService=Rt,this.scopeService=_t,this.emptyPipe=mt,this.authStorageService=jt,this.modalService=on,this.notificationService=si,this.urlBuilder=Vi,this.actionLabels=_o,this.selection=new Kr.r,this.permission=this.authStorageService.getPermissions().user,this.tableActions=[{permission:"create",icon:Mr.P.add,routerLink:()=>this.urlBuilder.getCreate(),name:this.actionLabels.CREATE},{permission:"create",icon:Mr.P.clone,name:this.actionLabels.CLONE,disable:()=>!this.selection.hasSingleSelection,click:()=>this.cloneRole()},{permission:"update",icon:Mr.P.edit,disable:()=>!this.selection.hasSingleSelection||this.selection.first().system,routerLink:()=>this.selection.first()&&this.urlBuilder.getEdit(this.selection.first().name),name:this.actionLabels.EDIT},{permission:"delete",icon:Mr.P.destroy,disable:()=>!this.selection.hasSingleSelection||this.selection.first().system,click:()=>this.deleteRoleModal(),name:this.actionLabels.DELETE}]}ngOnInit(){this.columns=[{name:"Name",prop:"name",flexGrow:3},{name:"Description",prop:"description",flexGrow:5,pipe:this.emptyPipe},{name:"System Role",prop:"system",cellClass:"text-center",flexGrow:1,cellTransformation:Lr.e.checkIcon}]}getRoles(){(0,N.D)([this.roleService.list(),this.scopeService.list()]).subscribe(Rt=>{this.roles=Rt[0],this.scopes=Rt[1]})}updateSelection(Rt){this.selection=Rt}deleteRole(Rt){this.roleService.delete(Rt).subscribe(()=>{this.getRoles(),this.modalRef.close(),this.notificationService.show(L.k.success,"Deleted role '" + Rt + "'")},()=>{this.modalRef.componentInstance.stopLoadingSpinner()})}deleteRoleModal(){const Rt=this.selection.first().name;this.modalRef=this.modalService.show(Ur.M,{itemDescription:"Role",itemNames:[Rt],submitAction:()=>this.deleteRole(Rt)})}cloneRole(){const Rt=this.selection.first().name;this.modalRef=this.modalService.show(di.X,{fields:[{type:"text",name:"newName",value:`${Rt}_clone`,label:"New name",required:!0}],titleText:"Clone Role",submitButtonText:"Clone Role",onSubmit:_t=>{this.roleService.clone(Rt,_t.newName).subscribe(()=>{this.getRoles(),this.notificationService.show(L.k.success,"Cloned role '" + _t.newName + "' from '" + Rt + "'")})}})}}return tr.\u0275fac=function(Rt){return new(Rt||tr)(H.Y36(he),H.Y36(ge),H.Y36(ei.W),H.Y36($n.j),H.Y36(Br.Z),H.Y36(ee.g),H.Y36(Nn.F),H.Y36(_.p4))},tr.\u0275cmp=H.Xpm({type:tr,selectors:[["cd-role-list"]],features:[H._Bn([{provide:Nn.F,useValue:new Nn.F("user-management/roles")}]),H.qOj],decls:4,vars:8,consts:[["columnMode","flex","identifier","name","selectionType","single",3,"data","columns","hasDetails","setExpandedRow","fetchData","updateSelection"],[1,"table-actions",3,"permission","selection","tableActions"],["cdTableDetail","",3,"selection","scopes"]],template:function(Rt,_t){1&Rt&&(H._UZ(0,"cd-user-tabs"),H.TgZ(1,"cd-table",0),H.NdJ("setExpandedRow",function(jt){return _t.setExpandedRow(jt)})("fetchData",function(){return _t.getRoles()})("updateSelection",function(jt){return _t.updateSelection(jt)}),H._UZ(2,"cd-table-actions",1),H._UZ(3,"cd-role-details",2),H.qZA()),2&Rt&&(H.xp6(1),H.Q6J("data",_t.roles)("columns",_t.columns)("hasDetails",!0),H.xp6(1),H.Q6J("permission",_t.permission)("selection",_t.selection)("tableActions",_t.tableActions),H.xp6(1),H.Q6J("selection",_t.expandedRow)("scopes",_t.scopes))},directives:[Yr,Pe.a,fi.K,Hi],styles:[""]}),tr})();var Wt=i(16738),zn=i.n(Wt),rr=i(39219),Fr=i(9837),Gn=i(36169),Jr=i(7022),_i=i(51907),wi=i(33888),br=(()=>((br||(br={})).editing="editing",br))();class Dr{}var gn=i(32057),yn=i(62862),gr=i(4416),Jt=i(18372),Vn=i(60192),mr=i(52266);const Dn=["removeSelfUserReadUpdatePermissionTpl"];function Pr(tr,Ar){1&tr&&(H.TgZ(0,"span",28),H.SDv(1,29),H.qZA())}function Yt(tr,Ar){1&tr&&(H.TgZ(0,"span",28),H.SDv(1,30),H.qZA())}function _n(tr,Ar){if(1&tr&&H._UZ(0,"cd-helper",40),2&tr){const Rt=H.oxw(3);H.s9C("html",Rt.passwordPolicyHelpText)}}function Ge(tr,Ar){1&tr&&(H.TgZ(0,"span",28),H.SDv(1,41),H.qZA())}function kr(tr,Ar){if(1&tr&&(H.TgZ(0,"span",28),H._uU(1),H.qZA()),2&tr){const Rt=H.oxw(3);H.xp6(1),H.hij(" ",Rt.passwordValuation," ")}}function mi(tr,Ar){if(1&tr&&(H.TgZ(0,"div",10),H.TgZ(1,"label",31),H.ynx(2),H.SDv(3,32),H.BQk(),H.YNc(4,_n,1,1,"cd-helper",33),H.qZA(),H.TgZ(5,"div",13),H.TgZ(6,"div",34),H._UZ(7,"input",35),H.TgZ(8,"span",36),H._UZ(9,"button",37),H.qZA(),H.qZA(),H.TgZ(10,"div",38),H._UZ(11,"div",39),H.qZA(),H.YNc(12,Ge,2,0,"span",15),H.YNc(13,kr,2,1,"span",15),H.qZA(),H.qZA()),2&tr){H.oxw();const Rt=H.MAs(2),_t=H.oxw();H.xp6(4),H.Q6J("ngIf",_t.passwordPolicyHelpText.length>0),H.xp6(7),H.Tol(_t.passwordStrengthLevelClass),H.s9C("title",_t.passwordValuation),H.xp6(1),H.Q6J("ngIf",_t.userForm.showError("password",Rt,"required")),H.xp6(1),H.Q6J("ngIf",_t.userForm.showError("password",Rt,"passwordPolicy"))}}function An(tr,Ar){1&tr&&(H.TgZ(0,"span",28),H.SDv(1,46),H.qZA())}function Er(tr,Ar){1&tr&&(H.TgZ(0,"span",28),H.SDv(1,47),H.qZA())}function Wr(tr,Ar){if(1&tr&&(H.TgZ(0,"div",10),H.TgZ(1,"label",42),H.SDv(2,43),H.qZA(),H.TgZ(3,"div",13),H.TgZ(4,"div",34),H._UZ(5,"input",44),H.TgZ(6,"span",36),H._UZ(7,"button",45),H.qZA(),H.YNc(8,An,2,0,"span",15),H.qZA(),H.YNc(9,Er,2,0,"span",15),H.qZA(),H.qZA()),2&tr){H.oxw();const Rt=H.MAs(2),_t=H.oxw();H.xp6(8),H.Q6J("ngIf",_t.userForm.showError("confirmpassword",Rt,"match")),H.xp6(1),H.Q6J("ngIf",_t.userForm.showError("confirmpassword",Rt,"required"))}}function dr(tr,Ar){1&tr&&(H.TgZ(0,"cd-helper",54),H.TgZ(1,"p"),H._uU(2," The Dashboard setting defining the expiration interval of passwords is currently set to "),H.TgZ(3,"strong"),H._uU(4,"0"),H.qZA(),H._uU(5,". This means if a date is set, the user password will only expire once. "),H.qZA(),H.TgZ(6,"p"),H._uU(7," Consider configuring the Dashboard setting "),H.TgZ(8,"a",55),H._uU(9,"USER_PWD_EXPIRATION_SPAN"),H.qZA(),H._uU(10," in order to let passwords expire periodically. "),H.qZA(),H.qZA())}function Fn(tr,Ar){1&tr&&(H.TgZ(0,"span",28),H.SDv(1,56),H.qZA())}const ar=function(tr){return{required:tr}};function Wi(tr,Ar){if(1&tr){const Rt=H.EpF();H.TgZ(0,"div",10),H.TgZ(1,"label",48),H.ynx(2),H.SDv(3,49),H.BQk(),H.YNc(4,dr,11,0,"cd-helper",50),H.qZA(),H.TgZ(5,"div",13),H.TgZ(6,"div",34),H.TgZ(7,"input",51,52),H.NdJ("click",function(){return H.CHM(Rt),H.MAs(8).open()})("keypress",function(){return H.CHM(Rt),H.MAs(8).close()}),H.qZA(),H.TgZ(9,"span",36),H.TgZ(10,"button",53),H.NdJ("click",function(){return H.CHM(Rt),H.oxw(2).clearExpirationDate()}),H._UZ(11,"i"),H.qZA(),H.qZA(),H.YNc(12,Fn,2,0,"span",15),H.qZA(),H.qZA(),H.qZA()}if(2&tr){H.oxw();const Rt=H.MAs(2),_t=H.oxw(),mt=H.MAs(4);H.xp6(1),H.Q6J("ngClass",H.VKq(7,ar,_t.pwdExpirationSettings.pwdExpirationSpan>0)),H.xp6(3),H.Q6J("ngIf",0==_t.pwdExpirationSettings.pwdExpirationSpan),H.xp6(3),H.Q6J("ngbPopover",mt),H.xp6(4),H.Gre("icon-prepend ",_t.icons.destroy,""),H.xp6(1),H.Q6J("ngIf",_t.userForm.showError("pwdExpirationDate",Rt,"required"))}}function lo(tr,Ar){1&tr&&(H.TgZ(0,"span",28),H.SDv(1,57),H.qZA())}function vo(tr,Ar){if(1&tr&&(H.TgZ(0,"span",58),H._UZ(1,"cd-select-badges",59),H.qZA()),2&tr){const Rt=H.oxw(2);H.xp6(1),H.Q6J("data",Rt.userForm.controls.roles.value)("options",Rt.allRoles)("messages",Rt.messages)}}function Co(tr,Ar){1&tr&&(H.TgZ(0,"div",10),H.TgZ(1,"div",60),H.TgZ(2,"div",61),H._UZ(3,"input",62),H.TgZ(4,"label",63),H.SDv(5,64),H.qZA(),H.qZA(),H.qZA(),H.qZA())}function Gi(tr,Ar){1&tr&&(H.TgZ(0,"div",10),H.TgZ(1,"div",60),H.TgZ(2,"div",61),H._UZ(3,"input",65),H.TgZ(4,"label",66),H.SDv(5,67),H.qZA(),H.qZA(),H.qZA(),H.qZA())}function os(tr,Ar){if(1&tr){const Rt=H.EpF();H.TgZ(0,"div",3),H.TgZ(1,"form",4,5),H.TgZ(3,"div",6),H.TgZ(4,"div",7),H.SDv(5,8),H.ALo(6,"titlecase"),H.ALo(7,"upperFirst"),H.qZA(),H.TgZ(8,"div",9),H.TgZ(9,"div",10),H.TgZ(10,"label",11),H.SDv(11,12),H.qZA(),H.TgZ(12,"div",13),H._UZ(13,"input",14),H.YNc(14,Pr,2,0,"span",15),H.YNc(15,Yt,2,0,"span",15),H.qZA(),H.qZA(),H.YNc(16,mi,14,7,"div",16),H.YNc(17,Wr,10,2,"div",16),H.YNc(18,Wi,13,9,"div",16),H.TgZ(19,"div",10),H.TgZ(20,"label",17),H.SDv(21,18),H.qZA(),H.TgZ(22,"div",13),H._UZ(23,"input",19),H.qZA(),H.qZA(),H.TgZ(24,"div",10),H.TgZ(25,"label",20),H.SDv(26,21),H.qZA(),H.TgZ(27,"div",13),H._UZ(28,"input",22),H.YNc(29,lo,2,0,"span",15),H.qZA(),H.qZA(),H.TgZ(30,"div",10),H.TgZ(31,"label",23),H.SDv(32,24),H.qZA(),H.TgZ(33,"div",13),H.YNc(34,vo,2,3,"span",25),H.qZA(),H.qZA(),H.YNc(35,Co,6,0,"div",16),H.YNc(36,Gi,6,0,"div",16),H.qZA(),H.TgZ(37,"div",26),H.TgZ(38,"cd-form-button-panel",27),H.NdJ("submitActionEvent",function(){return H.CHM(Rt),H.oxw().submit()}),H.ALo(39,"titlecase"),H.ALo(40,"upperFirst"),H.qZA(),H.qZA(),H.qZA(),H.qZA(),H.qZA()}if(2&tr){const Rt=H.MAs(2),_t=H.oxw();H.xp6(1),H.Q6J("formGroup",_t.userForm),H.xp6(6),H.pQV(H.lcZ(6,15,_t.action))(H.lcZ(7,17,_t.resource)),H.QtT(5),H.xp6(3),H.Q6J("ngClass",H.VKq(23,ar,_t.mode!==_t.userFormMode.editing)),H.xp6(4),H.Q6J("ngIf",_t.userForm.showError("username",Rt,"required")),H.xp6(1),H.Q6J("ngIf",_t.userForm.showError("username",Rt,"notUnique")),H.xp6(1),H.Q6J("ngIf",!_t.authStorageService.isSSO()),H.xp6(1),H.Q6J("ngIf",!_t.authStorageService.isSSO()),H.xp6(1),H.Q6J("ngIf",!_t.authStorageService.isSSO()),H.xp6(11),H.Q6J("ngIf",_t.userForm.showError("email",Rt,"email")),H.xp6(5),H.Q6J("ngIf",_t.allRoles),H.xp6(1),H.Q6J("ngIf",!_t.isCurrentUser()),H.xp6(1),H.Q6J("ngIf",!_t.isCurrentUser()&&!_t.authStorageService.isSSO()),H.xp6(2),H.Q6J("form",_t.userForm)("submitText",H.lcZ(39,19,_t.action)+" "+H.lcZ(40,21,_t.resource))}}function jo(tr,Ar){1&tr&&(H.TgZ(0,"p"),H.TgZ(1,"strong"),H.SDv(2,68),H.qZA(),H.qZA(),H._UZ(3,"br"),H.TgZ(4,"p"),H.SDv(5,69),H.qZA(),H.ynx(6),H.SDv(7,70),H.BQk())}function To(tr,Ar){if(1&tr&&H._UZ(0,"cd-date-time-picker",71),2&tr){const Rt=H.oxw();H.Q6J("control",Rt.userForm.get("pwdExpirationDate"))("hasTime",!1)}}let Mi=(()=>{class tr extends Z.E{constructor(Rt,_t,mt,jt,on,si,Vi,_o,co,Es,Zs,ls){super(),this.authService=Rt,this.authStorageService=_t,this.route=mt,this.router=jt,this.modalService=on,this.roleService=si,this.userService=Vi,this.notificationService=_o,this.actionLabels=co,this.passwordPolicyService=Es,this.formBuilder=Zs,this.settingsService=ls,this.userFormMode=br,this.messages=new Jr.a({empty:"There are no roles."}),this.passwordPolicyHelpText="",this.icons=Mr.P,this.pwdExpirationFormat="YYYY-MM-DD",this.resource="user",this.createForm(),this.messages=new Jr.a({empty:"There are no roles."})}createForm(){this.passwordPolicyService.getHelpText().subscribe(Rt=>{this.passwordPolicyHelpText=Rt}),this.userForm=this.formBuilder.group({username:["",[u.kI.required],[K.h.unique(this.userService.validateUserName,this.userService)]],name:[""],password:["",[],[K.h.passwordPolicy(this.userService,()=>this.userForm.getValue("username"),(Rt,_t,mt)=>{this.passwordStrengthLevelClass=this.passwordPolicyService.mapCreditsToCssClass(_t),this.passwordValuation=A().defaultTo(mt,"")})]],confirmpassword:[""],pwdExpirationDate:[void 0],email:["",[K.h.email]],roles:[[]],enabled:[!0,[u.kI.required]],pwdUpdateRequired:[!0]},{validators:[K.h.match("password","confirmpassword")]})}ngOnInit(){this.router.url.startsWith("/user-management/users/edit")?(this.mode=this.userFormMode.editing,this.action=this.actionLabels.EDIT):this.action=this.actionLabels.CREATE;const Rt=[this.roleService.list(),this.settingsService.getStandardSettings()];(0,N.D)(Rt).subscribe(_t=>{if(this.allRoles=A().map(_t[0],mt=>(mt.enabled=!0,mt)),this.pwdExpirationSettings=new _i.G(_t[1]),this.mode===this.userFormMode.editing)this.initEdit();else{if(this.pwdExpirationSettings.pwdExpirationSpan>0){const mt=this.userForm.get("pwdExpirationDate"),jt=zn()();jt.add(this.pwdExpirationSettings.pwdExpirationSpan,"day"),mt.setValue(jt.format(this.pwdExpirationFormat)),mt.setValidators([u.kI.required])}this.loadingReady()}})}initEdit(){this.disableForEdit(),this.route.params.subscribe(Rt=>{this.userService.get(Rt.username).subscribe(mt=>{this.response=A().cloneDeep(mt),this.setResponse(mt),this.loadingReady()})})}disableForEdit(){this.userForm.get("username").disable()}setResponse(Rt){["username","name","email","roles","enabled","pwdUpdateRequired"].forEach(mt=>this.userForm.get(mt).setValue(Rt[mt]));const _t=Rt.pwdExpirationDate;_t&&this.userForm.get("pwdExpirationDate").setValue(zn()(1e3*_t).format(this.pwdExpirationFormat))}getRequest(){const Rt=new Dr;["username","password","name","email","roles","enabled","pwdUpdateRequired"].forEach(mt=>Rt[mt]=this.userForm.get(mt).value);const _t=this.userForm.get("pwdExpirationDate").value;if(_t){const mt=zn()(_t,this.pwdExpirationFormat);(this.mode!==this.userFormMode.editing||this.response.pwdExpirationDate!==mt.unix())&&mt.set({hour:23,minute:59,second:59}),Rt.pwdExpirationDate=mt.unix()}return Rt}createAction(){const Rt=this.getRequest();this.userService.create(Rt).subscribe(()=>{this.notificationService.show(L.k.success,"Created user '" + Rt.username + "'"),this.router.navigate(["/user-management/users"])},()=>{this.userForm.setErrors({cdSubmitButton:!0})})}editAction(){if(this.isUserRemovingNeededRolePermissions()){const Rt={titleText:"Update user",buttonText:"Continue",bodyTpl:this.removeSelfUserReadUpdatePermissionTpl,onSubmit:()=>{this.modalRef.close(),this.doEditAction()},onCancel:()=>{this.userForm.setErrors({cdSubmitButton:!0}),this.userForm.get("roles").reset(this.userForm.get("roles").value)}};this.modalRef=this.modalService.show(Gn.Y,Rt)}else this.doEditAction()}isCurrentUser(){return this.authStorageService.getUsername()===this.userForm.getValue("username")}isUserChangingRoles(){return this.isCurrentUser()&&this.response&&!A().isEqual(this.response.roles,this.userForm.getValue("roles"))}isUserRemovingNeededRolePermissions(){return this.isCurrentUser()&&!this.hasUserReadUpdatePermissions(this.userForm.getValue("roles"))}hasUserReadUpdatePermissions(Rt=[]){for(const _t of this.allRoles)if(-1!==Rt.indexOf(_t.name)&&_t.scopes_permissions.user){const mt=_t.scopes_permissions.user;return["read","update"].every(jt=>-1!==mt.indexOf(jt))}return!1}doEditAction(){const Rt=this.getRequest();this.userService.update(Rt).subscribe(()=>{this.isUserChangingRoles()?this.authService.logout(()=>{this.notificationService.show(L.k.info,"You were automatically logged out because your roles have been changed.")}):(this.notificationService.show(L.k.success,"Updated user '" + Rt.username + "'"),this.router.navigate(["/user-management/users"]))},()=>{this.userForm.setErrors({cdSubmitButton:!0})})}clearExpirationDate(){this.userForm.get("pwdExpirationDate").setValue(void 0)}submit(){this.mode===this.userFormMode.editing?this.editAction():this.createAction()}}return tr.\u0275fac=function(Rt){return new(Rt||tr)(H.Y36(rr.e),H.Y36($n.j),H.Y36(p.gz),H.Y36(p.F0),H.Y36(Br.Z),H.Y36(he),H.Y36(gn.K),H.Y36(ee.g),H.Y36(_.p4),H.Y36(wi.q),H.Y36(yn.O),H.Y36(Fr.g))},tr.\u0275cmp=H.Xpm({type:tr,selectors:[["cd-user-form"]],viewQuery:function(Rt,_t){if(1&Rt&&H.Gf(Dn,7),2&Rt){let mt;H.iGM(mt=H.CRH())&&(_t.removeSelfUserReadUpdatePermissionTpl=mt.first)}},features:[H.qOj],decls:5,vars:1,consts:function(){let Ar,Rt,_t,mt,jt,on,si,Vi,_o,co,Es,Zs,ls,La,ta,Is,us,ya,el,ca,$s;return Ar="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",Rt="Username",_t="Full name",mt="Email",jt="Roles",on="This field is required.",si="The username already exists.",Vi="Password",_o="This field is required.",co="Confirm password",Es="Password confirmation doesn't match the password.",Zs="This field is required.",ls="Password expiration date",La="Password expiration date...",ta="This field is required.",Is="Invalid email.",us="Enabled",ya="User must change password at next logon",el="You are about to remove \"user read / update\" permissions from your own user.",ca="If you continue, you will no longer be able to add or remove roles from any user.",$s="Are you sure you want to continue?",[["class","cd-col-form",4,"cdFormLoading"],["removeSelfUserReadUpdatePermissionTpl",""],["popContent",""],[1,"cd-col-form"],["name","userForm","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"card"],[1,"card-header"],Ar,[1,"card-body"],[1,"form-group","row"],["for","username",1,"cd-col-form-label",3,"ngClass"],Rt,[1,"cd-col-form-input"],["type","text","placeholder","Username...","id","username","name","username","formControlName","username","autocomplete","off","autofocus","",1,"form-control"],["class","invalid-feedback",4,"ngIf"],["class","form-group row",4,"ngIf"],["for","name",1,"cd-col-form-label"],_t,["type","text","placeholder","Full name...","id","name","name","name","formControlName","name",1,"form-control"],["for","email",1,"cd-col-form-label"],mt,["type","email","placeholder","Email...","id","email","name","email","formControlName","email",1,"form-control"],[1,"cd-col-form-label"],jt,["class","no-border full-height",4,"ngIf"],[1,"card-footer"],["wrappingClass","text-right",3,"form","submitText","submitActionEvent"],[1,"invalid-feedback"],on,si,["for","password",1,"cd-col-form-label"],Vi,["class","text-pre-wrap",3,"html",4,"ngIf"],[1,"input-group"],["type","password","placeholder","Password...","id","password","name","password","autocomplete","new-password","formControlName","password",1,"form-control"],[1,"input-group-append"],["type","button","cdPasswordButton","password",1,"btn","btn-light"],[1,"password-strength-level"],["data-toggle","tooltip",3,"title"],[1,"text-pre-wrap",3,"html"],_o,["for","confirmpassword",1,"cd-col-form-label"],co,["type","password","placeholder","Confirm password...","id","confirmpassword","name","confirmpassword","autocomplete","new-password","formControlName","confirmpassword",1,"form-control"],["type","button","cdPasswordButton","confirmpassword",1,"btn","btn-light"],Es,Zs,["for","pwdExpirationDate",1,"cd-col-form-label",3,"ngClass"],ls,["class","text-pre-wrap",4,"ngIf"],["placeholder",La,"id","pwdExpirationDate","name","pwdExpirationDate","formControlName","pwdExpirationDate","triggers","manual",1,"form-control",3,"ngbPopover","click","keypress"],["p","ngbPopover"],["type","button",1,"btn","btn-light",3,"click"],[1,"text-pre-wrap"],["routerLink","/mgr-modules/edit/dashboard",1,"alert-link"],ta,Is,[1,"no-border","full-height"],[3,"data","options","messages"],[1,"cd-col-form-offset"],[1,"custom-control","custom-checkbox"],["type","checkbox","id","enabled","name","enabled","formControlName","enabled",1,"custom-control-input"],["for","enabled",1,"custom-control-label"],us,["type","checkbox","id","pwdUpdateRequired","name","pwdUpdateRequired","formControlName","pwdUpdateRequired",1,"custom-control-input"],["for","pwdUpdateRequired",1,"custom-control-label"],ya,el,ca,$s,[3,"control","hasTime"]]},template:function(Rt,_t){1&Rt&&(H.YNc(0,os,41,25,"div",0),H.YNc(1,jo,8,0,"ng-template",null,1,H.W1O),H.YNc(3,To,1,2,"ng-template",null,2,H.W1O)),2&Rt&&H.Q6J("cdFormLoading",_t.loading)},directives:[De.y,u._Y,u.JL,u.sg,ce.V,lt.P,r.mk,Ve.o,u.Fj,ze.b,u.JJ,u.u,Be.U,r.O5,je.p,gr.C,Jt.S,d.o8,p.yS,Vn.m,u.Wl,mr.J],pipes:[r.rS,He.m],styles:[""]}),tr})();var li=i(96102);const Bn=["userRolesTpl"];function lr(tr,Ar){if(1&tr&&(H.TgZ(0,"span"),H._uU(1),H.qZA()),2&tr){const Rt=Ar.$implicit,_t=Ar.last;H.xp6(1),H.AsE(" ",Rt,"",_t?"":", "," ")}}function vr(tr,Ar){1&tr&&H.YNc(0,lr,2,2,"span",3),2&tr&&H.Q6J("ngForOf",Ar.value)}let ri=(()=>{class tr{constructor(Rt,_t,mt,jt,on,si,Vi,_o){this.userService=Rt,this.emptyPipe=_t,this.modalService=mt,this.notificationService=jt,this.authStorageService=on,this.urlBuilder=si,this.cdDatePipe=Vi,this.actionLabels=_o,this.selection=new Kr.r,this.permission=this.authStorageService.getPermissions().user,this.tableActions=[{permission:"create",icon:Mr.P.add,routerLink:()=>this.urlBuilder.getCreate(),name:this.actionLabels.CREATE},{permission:"update",icon:Mr.P.edit,routerLink:()=>this.selection.first()&&this.urlBuilder.getEdit(this.selection.first().username),name:this.actionLabels.EDIT},{permission:"delete",icon:Mr.P.destroy,click:()=>this.deleteUserModal(),name:this.actionLabels.DELETE}]}ngOnInit(){this.columns=[{name:"Username",prop:"username",flexGrow:1},{name:"Name",prop:"name",flexGrow:1,pipe:this.emptyPipe},{name:"Email",prop:"email",flexGrow:1,pipe:this.emptyPipe},{name:"Roles",prop:"roles",flexGrow:1,cellTemplate:this.userRolesTpl},{name:"Enabled",prop:"enabled",flexGrow:1,cellTransformation:Lr.e.checkIcon},{name:"Password expiration date",prop:"pwdExpirationDate",flexGrow:1,pipe:this.cdDatePipe}]}getUsers(){this.userService.list().subscribe(Rt=>{Rt.forEach(_t=>{_t.pwdExpirationDate&&_t.pwdExpirationDate>0&&(_t.pwdExpirationDate=1e3*_t.pwdExpirationDate)}),this.users=Rt})}updateSelection(Rt){this.selection=Rt}deleteUser(Rt){this.userService.delete(Rt).subscribe(()=>{this.getUsers(),this.modalRef.close(),this.notificationService.show(L.k.success,"Deleted user '" + Rt + "'")},()=>{this.modalRef.componentInstance.stopLoadingSpinner()})}deleteUserModal(){const Rt=this.authStorageService.getUsername(),_t=this.selection.first().username;Rt!==_t?this.modalRef=this.modalService.show(Ur.M,{itemDescription:"User",itemNames:[_t],submitAction:()=>this.deleteUser(_t)}):this.notificationService.show(L.k.error,"Failed to delete user '" + _t + "'","You are currently logged in as '" + _t + "'.")}}return tr.\u0275fac=function(Rt){return new(Rt||tr)(H.Y36(gn.K),H.Y36(ei.W),H.Y36(Br.Z),H.Y36(ee.g),H.Y36($n.j),H.Y36(Nn.F),H.Y36(li.N),H.Y36(_.p4))},tr.\u0275cmp=H.Xpm({type:tr,selectors:[["cd-user-list"]],viewQuery:function(Rt,_t){if(1&Rt&&H.Gf(Bn,7),2&Rt){let mt;H.iGM(mt=H.CRH())&&(_t.userRolesTpl=mt.first)}},features:[H._Bn([{provide:Nn.F,useValue:new Nn.F("user-management/users")}])],decls:5,vars:5,consts:[["columnMode","flex","identifier","username","selectionType","single",3,"data","columns","fetchData","updateSelection"],[1,"table-actions",3,"permission","selection","tableActions"],["userRolesTpl",""],[4,"ngFor","ngForOf"]],template:function(Rt,_t){1&Rt&&(H._UZ(0,"cd-user-tabs"),H.TgZ(1,"cd-table",0),H.NdJ("fetchData",function(){return _t.getUsers()})("updateSelection",function(jt){return _t.updateSelection(jt)}),H._UZ(2,"cd-table-actions",1),H.qZA(),H.YNc(3,vr,1,1,"ng-template",null,2,H.W1O)),2&Rt&&(H.xp6(1),H.Q6J("data",_t.users)("columns",_t.columns),H.xp6(1),H.Q6J("permission",_t.permission)("selection",_t.selection)("tableActions",_t.tableActions))},directives:[Yr,Pe.a,fi.K,r.sg],styles:[""]}),tr})(),uo=(()=>{class tr{}return tr.\u0275fac=function(Rt){return new(Rt||tr)},tr.\u0275mod=H.oAB({type:tr}),tr.\u0275inj=H.cJS({imports:[[r.ez,u.u5,u.UX,y.m,d.Oz,d.dT,e.b,p.Bz]]}),tr})();const Ci=[{path:"",redirectTo:"users",pathMatch:"full"},{path:"users",data:{breadcrumbs:"Users"},children:[{path:"",component:ri},{path:_.MQ.CREATE,component:Mi,data:{breadcrumbs:_.Qn.CREATE}},{path:`${_.MQ.EDIT}/:username`,component:Mi,data:{breadcrumbs:_.Qn.EDIT}}]},{path:"roles",data:{breadcrumbs:"Roles"},children:[{path:"",component:Cn},{path:_.MQ.CREATE,component:Xt,data:{breadcrumbs:_.Qn.CREATE}},{path:`${_.MQ.EDIT}/:name`,component:Xt,data:{breadcrumbs:_.Qn.EDIT}}]}];let $o=(()=>{class tr{}return tr.\u0275fac=function(Rt){return new(Rt||tr)},tr.\u0275mod=H.oAB({type:tr}),tr.\u0275inj=H.cJS({imports:[[uo,p.Bz.forChild(Ci)]]}),tr})()},26504:(v,T,i)=>{"use strict";i.d(T,{s9:()=>u,_2:()=>p,mM:()=>e});var r=i(65862);class u extends Error{}class p extends u{constructor(){super(...arguments),this.header="Page Not Found",this.message="Sorry, we couldn\u2019t find what you were looking for.\n The page you requested may have been changed or moved.",this.icon=r.P.warning}}class e extends u{constructor(){super(...arguments),this.header="User Denied",this.message="Sorry, the user does not exist in Ceph.\n You'll be logged out from the Identity Provider when you retry logging in.",this.icon=r.P.warning}}},76189:(v,T,i)=>{"use strict";i.d(T,{S:()=>r});class r{getVersionHeaderValue(p,d){return`application/vnd.ceph.api.v${p}.${d}+json`}}},39219:(v,T,i)=>{"use strict";i.d(T,{e:()=>S});var r=i(23815),p=i(68307),d=i(74788),e=i(74937),_=i(58497),y=i(6283);let S=(()=>{class A{constructor(L,Z,J,K){this.authStorageService=L,this.http=Z,this.router=J,this.route=K}check(L){return this.http.post("api/auth/check",{token:L})}login(L){return this.http.post("api/auth",L).pipe((0,p.b)(Z=>{this.authStorageService.set(Z.username,Z.permissions,Z.sso,Z.pwdExpirationDate,Z.pwdUpdateRequired)}))}logout(L=null){return this.http.post("api/auth/logout",null).subscribe(Z=>{this.authStorageService.remove();const J=r.get(this.route.snapshot.queryParams,"returnUrl","/login");this.router.navigate([J],{skipLocationChange:!0}),L&&L(),window.location.replace(Z.redirect_url)})}}return A.\u0275fac=function(L){return new(L||A)(d.LFG(e.j),d.LFG(_.eN),d.LFG(y.F0),d.LFG(y.gz))},A.\u0275prov=d.Yz7({token:A,factory:A.\u0275fac,providedIn:"root"}),A})()},64724:(v,T,i)=>{"use strict";i.d(T,{e:()=>p});var r=i(74788),u=i(58497);let p=(()=>{class d{constructor(_){this.http=_}findValue(_,y){if(_.value)return _.value.find(S=>S.section===y)}getValue(_,y){let S=this.findValue(_,y);if(!S){const A=y.indexOf(".");-1!==A&&(S=this.findValue(_,y.substring(0,A)))}return S||(S=this.findValue(_,"global")),S?S.value:_.default}getConfigData(){return this.http.get("api/cluster_conf/")}get(_){return this.http.get(`api/cluster_conf/${_}`)}filter(_){return this.http.get(`api/cluster_conf/filter?names=${_.join(",")}`)}create(_){return this.http.post("api/cluster_conf/",_)}delete(_,y){return this.http.delete(`api/cluster_conf/${_}?section=${y}`)}bulkCreate(_){return this.http.put("api/cluster_conf/",_)}}return d.\u0275fac=function(_){return new(_||d)(r.LFG(u.eN))},d.\u0275prov=r.Yz7({token:d,factory:d.\u0275fac,providedIn:"root"}),d})()},83608:(v,T,i)=>{"use strict";i.d(T,{H:()=>p});var r=i(74788),u=i(58497);let p=(()=>{class d{constructor(_){this.http=_,this.apiPath="api/crush_rule",this.formTooltips={root:"The name of the node under which data should be placed.",failure_domain:"The type of CRUSH nodes across which we should separate replicas.",device_class:"The device class data should be placed on."}}create(_){return this.http.post(this.apiPath,_,{observe:"response"})}delete(_){return this.http.delete(`${this.apiPath}/${_}`,{observe:"response"})}getInfo(){return this.http.get(`ui-${this.apiPath}/info`)}}return d.\u0275fac=function(_){return new(_||d)(r.LFG(u.eN))},d.\u0275prov=r.Yz7({token:d,factory:d.\u0275fac,providedIn:"root"}),d})()},7273:(v,T,i)=>{"use strict";i.d(T,{N:()=>p});var r=i(74788),u=i(58497);let p=(()=>{class d{constructor(_){this.http=_,this.url="api/mgr/module"}list(){return this.http.get(`${this.url}`)}getConfig(_){return this.http.get(`${this.url}/${_}`)}updateConfig(_,y){return this.http.put(`${this.url}/${_}`,{config:y})}enable(_){return this.http.post(`${this.url}/${_}/enable`,null)}disable(_){return this.http.post(`${this.url}/${_}/disable`,null)}getOptions(_){return this.http.get(`${this.url}/${_}/options`)}}return d.\u0275fac=function(_){return new(_||d)(r.LFG(u.eN))},d.\u0275prov=r.Yz7({token:d,factory:d.\u0275fac,providedIn:"root"}),d})()},80842:(v,T,i)=>{"use strict";i.d(T,{q:()=>y});var r=i(64762),u=i(58497),p=i(88002),d=i(93523),e=i(34089),_=i(74788);let y=class{constructor(A,N){this.http=A,this.rbdConfigurationService=N,this.apiPath="api/pool"}create(A){return this.http.post(this.apiPath,A,{observe:"response"})}update(A){let N;return A.hasOwnProperty("srcpool")?(N=A.srcpool,delete A.srcpool):(N=A.pool,delete A.pool),this.http.put(`${this.apiPath}/${encodeURIComponent(N)}`,A,{observe:"response"})}delete(A){return this.http.delete(`${this.apiPath}/${A}`,{observe:"response"})}get(A){return this.http.get(`${this.apiPath}/${A}`)}getList(){return this.http.get(`${this.apiPath}?stats=true`)}getConfiguration(A){return this.http.get(`${this.apiPath}/${A}/configuration`).pipe((0,p.U)(N=>N.map(L=>Object.assign(L,this.rbdConfigurationService.getOptionByName(L.name)))))}getInfo(){return this.http.get(`ui-${this.apiPath}/info`)}list(A=[]){const N=A.join(",");return this.http.get(`${this.apiPath}?attrs=${N}`).toPromise().then(L=>L)}};y.\u0275fac=function(A){return new(A||y)(_.LFG(u.eN),_.LFG(e.n))},y.\u0275prov=_.Yz7({token:y,factory:y.\u0275fac,providedIn:"root"}),y=(0,r.gn)([d.o,(0,r.w6)("design:paramtypes",[u.eN,e.n])],y)},95152:(v,T,i)=>{"use strict";i.d(T,{o:()=>Z});var r=i(64762),u=i(58497),p=i(23815),d=i.n(p),e=i(25917),_=i(96736),y=i(5304),S=i(76189),A=i(20523),N=i(93523),L=i(74788);let Z=class extends S.S{constructor(K,ee){super(),this.http=K,this.rgwDaemonService=ee,this.url="api/rgw/bucket"}list(K=!1,ee=""){return this.rgwDaemonService.request(ue=>(ue=ue.append("stats",K.toString()),ee&&(ue=ue.append("uid",ee)),this.http.get(this.url,{headers:{Accept:this.getVersionHeaderValue(1,1)},params:ue})))}get(K){return this.rgwDaemonService.request(ee=>this.http.get(`${this.url}/${K}`,{params:ee}))}create(K,ee,ue,ae,H,se,Ee){return this.rgwDaemonService.request(ie=>this.http.post(this.url,null,{params:new u.LE({fromObject:{bucket:K,uid:ee,zonegroup:ue,placement_target:ae,lock_enabled:String(H),lock_mode:se,lock_retention_period_days:Ee,daemon_name:ie.get("daemon_name")}})}))}update(K,ee,ue,ae,H,se,Ee,ie,he){return this.rgwDaemonService.request(ge=>(ge=(ge=(ge=(ge=(ge=(ge=(ge=(ge=ge.append("bucket_id",ee)).append("uid",ue)).append("versioning_state",ae)).append("mfa_delete",H)).append("mfa_token_serial",se)).append("mfa_token_pin",Ee)).append("lock_mode",ie)).append("lock_retention_period_days",he),this.http.put(`${this.url}/${K}`,null,{params:ge})))}delete(K,ee=!0){return this.rgwDaemonService.request(ue=>(ue=ue.append("purge_objects",ee?"true":"false"),this.http.delete(`${this.url}/${K}`,{params:ue})))}exists(K){return this.get(K).pipe((0,_.h)(!0),(0,y.K)(ee=>(d().isFunction(ee.preventDefault)&&ee.preventDefault(),(0,e.of)(!1))))}getLockDays(K){return K.lock_retention_period_years>0?Math.floor(365.242*K.lock_retention_period_years):K.lock_retention_period_days||0}};Z.\u0275fac=function(K){return new(K||Z)(L.LFG(u.eN),L.LFG(A.b))},Z.\u0275prov=L.Yz7({token:Z,factory:Z.\u0275fac,providedIn:"root"}),Z=(0,r.gn)([N.o,(0,r.w6)("design:paramtypes",[u.eN,A.b])],Z)},20523:(v,T,i)=>{"use strict";i.d(T,{b:()=>J});var r=i(64762),u=i(58497),p=i(23815),d=i.n(p),e=i(26215),_=i(40205),y=i(25917),S=i(68307),A=i(19773),N=i(15257),L=i(93523),Z=i(74788);let J=class{constructor(ee){this.http=ee,this.url="api/rgw/daemon",this.daemons=new e.X([]),this.daemons$=this.daemons.asObservable(),this.selectedDaemon=new e.X(null),this.selectedDaemon$=this.selectedDaemon.asObservable()}list(){return this.http.get(this.url).pipe((0,S.b)(ee=>{this.daemons.next(ee);const ue=this.selectedDaemon.getValue();(d().isEmpty(ue)||void 0===d().find(ee,{id:ue.id}))&&this.selectDefaultDaemon(ee)}))}get(ee){return this.http.get(`${this.url}/${ee}`)}selectDaemon(ee){this.selectedDaemon.next(ee)}selectDefaultDaemon(ee){if(0===ee.length)return null;for(const ue of ee)if(ue.default)return this.selectDaemon(ue),ue;return this.selectDaemon(ee[0]),ee[0]}request(ee){return this.selectedDaemon.pipe((0,A.zg)(ue=>d().isEmpty(ue)?this.list().pipe((0,A.zg)(ae=>d().isEmpty(ae)?(0,_._)("No RGW daemons found!"):this.selectedDaemon$)):(0,y.of)(ue)),(0,N.q)(1),(0,A.zg)(ue=>{let ae=new u.LE;return ae=ae.append("daemon_name",ue.id),ee(ae)}))}};J.\u0275fac=function(ee){return new(ee||J)(Z.LFG(u.eN))},J.\u0275prov=Z.Yz7({token:J,factory:J.\u0275fac,providedIn:"root"}),J=(0,r.gn)([L.o,(0,r.w6)("design:paramtypes",[u.eN])],J)},33394:(v,T,i)=>{"use strict";i.d(T,{I:()=>S});var r=i(64762),u=i(58497),p=i(19773),d=i(88002),e=i(20523),_=i(93523),y=i(74788);let S=class{constructor(N,L){this.http=N,this.rgwDaemonService=L,this.url="api/rgw/site"}get(N){return this.rgwDaemonService.request(L=>(N&&(L=L.append("query",N)),this.http.get(this.url,{params:L})))}isDefaultRealm(){return this.get("default-realm").pipe((0,p.zg)(N=>this.rgwDaemonService.selectedDaemon$.pipe((0,d.U)(L=>L.realm_name===N))))}};S.\u0275fac=function(N){return new(N||S)(y.LFG(u.eN),y.LFG(e.b))},S.\u0275prov=y.Yz7({token:S,factory:S.\u0275fac,providedIn:"root"}),S=(0,r.gn)([_.o,(0,r.w6)("design:paramtypes",[u.eN,e.b])],S)},9837:(v,T,i)=>{"use strict";i.d(T,{g:()=>y});var r=i(23815),u=i.n(r),p=i(88002),d=i(74788),e=i(58497);let y=(()=>{class S{constructor(N){this.http=N,this.settings={}}getValues(N){return u().isArray(N)&&(N=N.join(",")),this.http.get(`api/settings?names=${N}`).pipe((0,p.U)(L=>{const Z={};return u().forEach(L,J=>{u().set(Z,J.name,J.value)}),Z}))}ifSettingConfigured(N,L,Z){const J=this.settings[N];void 0===J?this.http.get(N).subscribe(K=>{this.settings[N]=this.getSettingsValue(K),this.ifSettingConfigured(N,L,Z)},K=>{401!==K.status&&(this.settings[N]="")}):""!==J?L(J):Z&&Z()}disableSetting(N){this.settings[N]=""}getSettingsValue(N){return N.value||N.instance||""}validateGrafanaDashboardUrl(N){return this.http.get(`api/grafana/validation/${N}`)}getStandardSettings(){return this.http.get("ui-api/standard_settings")}}return S.\u0275fac=function(N){return new(N||S)(d.LFG(e.eN))},S.\u0275prov=d.Yz7({token:S,factory:S.\u0275fac,providedIn:"root"}),S})()},32057:(v,T,i)=>{"use strict";i.d(T,{K:()=>_});var r=i(25917),u=i(96736),p=i(5304),d=i(74788),e=i(58497);let _=(()=>{class y{constructor(A){this.http=A}list(){return this.http.get("api/user")}delete(A){return this.http.delete(`api/user/${A}`)}get(A){return this.http.get(`api/user/${A}`)}create(A){return this.http.post("api/user",A)}update(A){return this.http.put(`api/user/${A.username}`,A)}changePassword(A,N,L){return this.http.post(`api/user/${A}/change_password`,{old_password:N,new_password:L})}validateUserName(A){return this.get(A).pipe((0,u.h)(!0),(0,p.K)(N=>(N.preventDefault(),(0,r.of)(!1))))}validatePassword(A,N=null,L=null){return this.http.post("api/user/validate_password",{password:A,username:N,old_password:L})}}return y.\u0275fac=function(A){return new(A||y)(d.LFG(e.eN))},y.\u0275prov=d.Yz7({token:y,factory:y.\u0275fac,providedIn:"root"}),y})()},51295:(v,T,i)=>{"use strict";i.d(T,{T:()=>p});var r=i(23815),u=i.n(r);class p{static updateChanged(e,_){let y=!1;return Object.keys(_).forEach(S=>{const A=_[S];u().isEqual(A,e[S])||(e[S]=A,y=!0)}),y}static cdVersionHeader(e,_){return`application/vnd.ceph.api.v${e}.${_}+json`}}},99475:(v,T,i)=>{"use strict";i.d(T,{P:()=>r});class r{propertyValue(p){return getComputedStyle(document.body).getPropertyValue(`--${p}`)}}},68136:(v,T,i)=>{"use strict";i.d(T,{o:()=>u});var r=i(71225);class u{constructor(d){this.ngZone=d}setExpandedRow(d){this.expandedRow=d}setTableRefreshTimeout(){clearTimeout(this.staleTimeout),this.ngZone.runOutsideAngular(()=>{this.staleTimeout=window.setTimeout(()=>{this.ngZone.run(()=>{this.tableStatus=new r.c("warning","The user list data might be stale. If needed, you can manually reload it.")})},1e4)})}}},69158:(v,T,i)=>{"use strict";i.d(T,{E:()=>p});var r=i(91801),u=i(71225);class p extends u.c{constructor(e=r.T.ValueOk,_=""){switch(super(),e){case r.T.ValueOk:this.type="light",this.msg="";break;case r.T.ValueNone:this.type="info",this.msg=(_?"Retrieving data for " + _ + ".":"Retrieving data.")+" "+"Please wait...";break;case r.T.ValueStale:this.type="warning",this.msg=_?"Displaying previously cached data for " + _ + ".":"Displaying previously cached data.";break;case r.T.ValueException:this.type="danger",this.msg=(_?"Could not load data for " + _ + ".":"Could not load data.")+" "+"Please check the cluster health."}}}},71225:(v,T,i)=>{"use strict";i.d(T,{c:()=>r});class r{constructor(p="light",d=""){this.type=p,this.msg=d}}},34501:(v,T,i)=>{"use strict";i.d(T,{G:()=>ue});var r=i(74788),u=i(65862),p=i(38549),d=i(12057);const e=function(ae){return[ae]};function _(ae,H){if(1&ae&&(r.TgZ(0,"td",8),r._UZ(1,"i",9),r.qZA()),2&ae){const se=r.oxw(2);r.xp6(1),r.MT6("alert-",se.bootstrapClass," ",se.typeIcon,""),r.Q6J("ngClass",r.VKq(5,e,se.icons.large3x))}}function y(ae,H){if(1&ae&&(r.TgZ(0,"td",10),r._uU(1),r.qZA()),2&ae){const se=r.oxw(2);r.xp6(1),r.Oqu(se.title)}}function S(ae,H){1&ae&&r.GkF(0)}function A(ae,H){if(1&ae&&(r.ynx(0),r.TgZ(1,"tr"),r.YNc(2,_,2,7,"td",4),r.YNc(3,y,2,1,"td",5),r.qZA(),r.TgZ(4,"tr"),r.TgZ(5,"td",6),r.YNc(6,S,1,0,"ng-container",7),r.qZA(),r.qZA(),r.BQk()),2&ae){const se=r.oxw(),Ee=r.MAs(6);r.xp6(2),r.Q6J("ngIf",se.showIcon),r.xp6(1),r.Q6J("ngIf",se.showTitle),r.xp6(3),r.Q6J("ngTemplateOutlet",Ee)}}function N(ae,H){if(1&ae&&(r.TgZ(0,"td",12),r._UZ(1,"i",13),r.qZA()),2&ae){const se=r.oxw(2);r.xp6(1),r.MT6("alert-",se.bootstrapClass," ",se.typeIcon,"")}}function L(ae,H){if(1&ae&&(r.TgZ(0,"td",10),r._uU(1),r.qZA()),2&ae){const se=r.oxw(2);r.xp6(1),r.Oqu(se.title)}}function Z(ae,H){1&ae&&r.GkF(0)}function J(ae,H){if(1&ae&&(r.TgZ(0,"tr"),r.YNc(1,N,2,4,"td",11),r.YNc(2,L,2,1,"td",5),r.TgZ(3,"td",6),r.YNc(4,Z,1,0,"ng-container",7),r.qZA(),r.qZA()),2&ae){const se=r.oxw(),Ee=r.MAs(6);r.xp6(1),r.Q6J("ngIf",se.showIcon),r.xp6(1),r.Q6J("ngIf",se.showTitle),r.xp6(2),r.Q6J("ngTemplateOutlet",Ee)}}function K(ae,H){1&ae&&r.Hsn(0)}const ee=["*"];let ue=(()=>{class ae{constructor(){this.title="",this.bootstrapClass="",this.size="normal",this.showIcon=!0,this.showTitle=!0,this.dismissible=!1,this.dismissed=new r.vpe,this.icons=u.P}ngOnInit(){switch(this.type){case"warning":this.title=this.title||"Warning",this.typeIcon=this.typeIcon||u.P.warning,this.bootstrapClass=this.bootstrapClass||"warning";break;case"error":this.title=this.title||"Error",this.typeIcon=this.typeIcon||u.P.destroyCircle,this.bootstrapClass=this.bootstrapClass||"danger";break;case"info":this.title=this.title||"Information",this.typeIcon=this.typeIcon||u.P.infoCircle,this.bootstrapClass=this.bootstrapClass||"info";break;case"success":this.title=this.title||"Success",this.typeIcon=this.typeIcon||u.P.check,this.bootstrapClass=this.bootstrapClass||"success";break;case"danger":this.title=this.title||"Danger",this.typeIcon=this.typeIcon||u.P.warning,this.bootstrapClass=this.bootstrapClass||"danger"}}onClose(){this.dismissed.emit()}}return ae.\u0275fac=function(se){return new(se||ae)},ae.\u0275cmp=r.Xpm({type:ae,selectors:[["cd-alert-panel"]],inputs:{title:"title",bootstrapClass:"bootstrapClass",type:"type",typeIcon:"typeIcon",size:"size",showIcon:"showIcon",showTitle:"showTitle",dismissible:"dismissible"},outputs:{dismissed:"dismissed"},ngContentSelectors:ee,decls:7,vars:4,consts:[[3,"type","dismissible","closed"],[4,"ngIf","ngIfElse"],["slim",""],["content",""],["rowspan","2","class","alert-panel-icon",4,"ngIf"],["class","alert-panel-title",4,"ngIf"],[1,"alert-panel-text"],[4,"ngTemplateOutlet"],["rowspan","2",1,"alert-panel-icon"],["aria-hidden","true",3,"ngClass"],[1,"alert-panel-title"],["class","alert-panel-icon",4,"ngIf"],[1,"alert-panel-icon"],["aria-hidden","true"]],template:function(se,Ee){if(1&se&&(r.F$t(),r.TgZ(0,"ngb-alert",0),r.NdJ("closed",function(){return Ee.onClose()}),r.TgZ(1,"table"),r.YNc(2,A,7,3,"ng-container",1),r.YNc(3,J,5,3,"ng-template",null,2,r.W1O),r.qZA(),r.qZA(),r.YNc(5,K,1,0,"ng-template",null,3,r.W1O)),2&se){const ie=r.MAs(4);r.s9C("type",Ee.bootstrapClass),r.Q6J("dismissible",Ee.dismissible),r.xp6(2),r.Q6J("ngIf","normal"===Ee.size)("ngIfElse",ie)}},directives:[p.xm,d.O5,d.tP,d.mk],styles:[".alert-panel-icon[_ngcontent-%COMP%]{padding-right:.5em;vertical-align:top}.alert-panel-title[_ngcontent-%COMP%]{font-weight:bold}.alert[_ngcontent-%COMP%]{margin-bottom:0}"]}),ae})()},13472:(v,T,i)=>{"use strict";i.d(T,{W:()=>e});var r=i(74788),u=i(79512),p=i(12057),d=i(87925);let e=(()=>{class _{constructor(S,A){this.location=S,this.actionLabels=A,this.backAction=new r.vpe,this.name=this.actionLabels.CANCEL}back(){0===this.backAction.observers.length?this.location.back():this.backAction.emit()}}return _.\u0275fac=function(S){return new(S||_)(r.Y36(p.Ye),r.Y36(u.p4))},_.\u0275cmp=r.Xpm({type:_,selectors:[["cd-back-button"]],inputs:{name:"name"},outputs:{backAction:"backAction"},decls:2,vars:1,consts:[["type","button",1,"btn","btn-light","tc_backButton",3,"click"]],template:function(S,A){1&S&&(r.TgZ(0,"button",0),r.NdJ("click",function(){return A.back()}),r._uU(1),r.qZA()),2&S&&(r.xp6(1),r.hij(" ",A.name,"\n"))},directives:[d.o],styles:[""]}),_})()},15626:(v,T,i)=>{"use strict";i.d(T,{K:()=>L});var r=i(12057),u=i(24751),p=i(6283),d=i(38549),e=i(11971),_=i(7194),y=i(34863),S=i(35540),A=i(85953),N=i(74788);let L=(()=>{class Z{}return Z.\u0275fac=function(K){return new(K||Z)},Z.\u0275mod=N.oAB({type:Z}),Z.\u0275inj=N.cJS({providers:[],imports:[[r.ez,u.u5,u.UX,d._A,d.dT,d.ZQ,d.HK,_.m9,u.UX,A.D,S.o,d.XC,e.w,y.t,p.Bz,d.M,d.UL]]}),Z})()},36169:(v,T,i)=>{"use strict";i.d(T,{Y:()=>L});var r=i(24751),u=i(74788),p=i(38549),d=i(60312),e=i(12057),_=i(41582),y=i(30839);function S(Z,J){1&Z&&(u.TgZ(0,"span",11),u._UZ(1,"i",12),u.qZA())}function A(Z,J){1&Z&&u.GkF(0)}function N(Z,J){if(1&Z&&(u.TgZ(0,"p"),u._uU(1),u.qZA()),2&Z){const K=u.oxw();u.xp6(1),u.hij(" ",K.description," ")}}let L=(()=>{class Z{constructor(K){this.activeModal=K,this.warning=!1,this.showSubmit=!0,this.boundCancel=this.cancel.bind(this),this.canceled=!1,this.confirmationForm=new r.cw({})}ngOnInit(){if(this.bodyContext=this.bodyContext||{},this.bodyContext.$implicit=this.bodyData,!this.onSubmit)throw new Error("No submit action defined");if(!this.buttonText)throw new Error("No action name defined");if(!this.titleText)throw new Error("No title defined");if(!this.bodyTpl&&!this.description)throw new Error("No description defined")}ngOnDestroy(){this.onCancel&&this.canceled&&this.onCancel()}cancel(){this.canceled=!0,this.activeModal.close()}stopLoadingSpinner(){this.confirmationForm.setErrors({cdSubmitButton:!0})}}return Z.\u0275fac=function(K){return new(K||Z)(u.Y36(p.Kz))},Z.\u0275cmp=u.Xpm({type:Z,selectors:[["cd-confirmation-modal"]],decls:12,vars:9,consts:[[3,"hide"],[1,"modal-title"],["class","text-warning",4,"ngIf"],[1,"modal-content"],["name","confirmationForm","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],[4,"ngTemplateOutlet","ngTemplateOutletContext"],[4,"ngIf"],[1,"modal-footer"],[3,"form","submitText","showSubmit","submitActionEvent","backActionEvent"],[1,"text-warning"],[1,"fa","fa-exclamation-triangle","fa-1x"]],template:function(K,ee){1&K&&(u.TgZ(0,"cd-modal",0),u.NdJ("hide",function(){return ee.cancel()}),u.ynx(1,1),u.YNc(2,S,2,0,"span",2),u._uU(3),u.BQk(),u.ynx(4,3),u.TgZ(5,"form",4,5),u.TgZ(7,"div",6),u.YNc(8,A,1,0,"ng-container",7),u.YNc(9,N,2,1,"p",8),u.qZA(),u.TgZ(10,"div",9),u.TgZ(11,"cd-form-button-panel",10),u.NdJ("submitActionEvent",function(){return ee.onSubmit(ee.confirmationForm.value)})("backActionEvent",function(){return ee.boundCancel()}),u.qZA(),u.qZA(),u.qZA(),u.BQk(),u.qZA()),2&K&&(u.xp6(2),u.Q6J("ngIf",ee.warning),u.xp6(1),u.Oqu(ee.titleText),u.xp6(2),u.Q6J("formGroup",ee.confirmationForm),u.xp6(3),u.Q6J("ngTemplateOutlet",ee.bodyTpl)("ngTemplateOutletContext",ee.bodyContext),u.xp6(1),u.Q6J("ngIf",ee.description),u.xp6(2),u.Q6J("form",ee.confirmationForm)("submitText",ee.buttonText)("showSubmit",ee.showSubmit))},directives:[d.z,e.O5,r._Y,r.JL,r.sg,_.V,e.tP,y.p],styles:[""]}),Z})()},58039:(v,T,i)=>{"use strict";i.d(T,{s:()=>S});var r=i(97057),u=i(65862),p=i(74788),d=i(91376),e=i(87925),_=i(12057);const y=function(A){return[A]};let S=(()=>{class A{constructor(L){this.toastr=L,this.byId=!0,this.icons=u.P}getText(){return document.getElementById(this.source).value}onClick(){try{const L=(0,r.qY)(),Z=this.byId?this.getText():this.source,J=()=>{this.toastr.success("Copied text to the clipboard successfully.")};["firefox","ie","ios","safari"].includes(L.name)?navigator.clipboard.writeText(Z).then(()=>J()):navigator.permissions.query({name:"clipboard-write"}).then(K=>{("granted"===K.state||"prompt"===K.state)&&navigator.clipboard.writeText(Z).then(()=>J())})}catch(L){this.toastr.error("Failed to copy text to the clipboard.")}}}return A.\u0275fac=function(L){return new(L||A)(p.Y36(d._W))},A.\u0275cmp=p.Xpm({type:A,selectors:[["cd-copy-2-clipboard-button"]],hostBindings:function(L,Z){1&L&&p.NdJ("click",function(){return Z.onClick()})},inputs:{source:"source",byId:"byId"},decls:2,vars:3,consts:function(){let N;return N="Copy to Clipboard",[["type","button","title",N,1,"btn","btn-light",3,"click"],[3,"ngClass"]]},template:function(L,Z){1&L&&(p.TgZ(0,"button",0),p.NdJ("click",function(){return Z.onClick()}),p._UZ(1,"i",1),p.qZA()),2&L&&(p.xp6(1),p.Q6J("ngClass",p.VKq(1,y,Z.icons.clipboard)))},directives:[e.o,_.mk],styles:[""]}),A})()},30982:(v,T,i)=>{"use strict";i.d(T,{M:()=>De});var r=i(24751),u=i(95463),p=i(39749),d=i(74788),e=i(38549),_=i(60312),y=i(12057),S=i(41582),A=i(56310),N=i(87925),L=i(94276),Z=i(82945),J=i(30839);function K(ce,lt){1&ce&&d.GkF(0)}function ee(ce,lt){1&ce&&d.GkF(0)}function ue(ce,lt){if(1&ce&&(d.TgZ(0,"p"),d.tHW(1,21),d.ALo(2,"lowercase"),d._UZ(3,"strong"),d.N_p(),d.qZA()),2&ce){const Ve=d.oxw(2);d.xp6(3),d.pQV(d.lcZ(2,2,Ve.actionDescription))(Ve.itemNames[0]),d.QtT(1)}}function ae(ce,lt){if(1&ce&&(d.TgZ(0,"li"),d.TgZ(1,"strong"),d._uU(2),d.qZA(),d.qZA()),2&ce){const Ve=lt.$implicit;d.xp6(2),d.Oqu(Ve)}}function H(ce,lt){if(1&ce&&(d.TgZ(0,"p"),d.SDv(1,22),d.ALo(2,"lowercase"),d.qZA(),d.TgZ(3,"ul"),d.YNc(4,ae,3,1,"li",23),d.qZA()),2&ce){const Ve=d.oxw(2);d.xp6(2),d.pQV(d.lcZ(2,2,Ve.actionDescription)),d.QtT(1),d.xp6(2),d.Q6J("ngForOf",Ve.itemNames)}}function se(ce,lt){if(1&ce&&(d.TgZ(0,"span"),d.YNc(1,ue,4,4,"p",10),d.YNc(2,H,5,4,"ng-template",null,20,d.W1O),d.qZA()),2&ce){const Ve=d.MAs(3),ze=d.oxw();d.xp6(1),d.Q6J("ngIf",1===ze.itemNames.length)("ngIfElse",Ve)}}function Ee(ce,lt){if(1&ce&&(d.TgZ(0,"p"),d.SDv(1,24),d.ALo(2,"lowercase"),d.qZA()),2&ce){const Ve=d.oxw();d.xp6(2),d.pQV(d.lcZ(2,2,Ve.actionDescription))(Ve.itemDescription),d.QtT(1)}}function ie(ce,lt){1&ce&&d.GkF(0)}function he(ce,lt){if(1&ce&&(d._uU(0),d.ALo(1,"titlecase")),2&ce){const Ve=d.oxw();d.AsE(" ",d.lcZ(1,2,Ve.actionDescription)," ",Ve.itemDescription,"\n")}}const ge=function(ce){return{form:ce}};let De=(()=>{class ce{constructor(Ve){this.activeModal=Ve,this.actionDescription="delete"}ngOnInit(){const Ve={confirmation:new r.NI(!1,[r.kI.requiredTrue])};if(this.childFormGroup&&(Ve.child=this.childFormGroup),this.deletionForm=new u.d(Ve),!this.submitAction&&!this.submitActionObservable)throw new Error("No submit action defined")}callSubmitAction(){this.submitActionObservable?this.submitActionObservable().subscribe({error:this.stopLoadingSpinner.bind(this),complete:this.hideModal.bind(this)}):this.submitAction()}hideModal(){this.activeModal.close()}stopLoadingSpinner(){this.deletionForm.setErrors({cdSubmitButton:!0})}}return ce.\u0275fac=function(Ve){return new(Ve||ce)(d.Y36(e.Kz))},ce.\u0275cmp=d.Xpm({type:ce,selectors:[["cd-deletion-modal"]],viewQuery:function(Ve,ze){if(1&Ve&&d.Gf(p.w,7),2&Ve){let Be;d.iGM(Be=d.CRH())&&(ze.submitButton=Be.first)}},decls:24,vars:15,consts:function(){let lt,Ve,ze,Be;return lt="Yes, I am sure.",Ve="Are you sure that you want to " + "\ufffd0\ufffd" + " " + "\ufffd#3\ufffd" + "" + "\ufffd1\ufffd" + "" + "\ufffd/#3\ufffd" + "?",ze="Are you sure that you want to " + "\ufffd0\ufffd" + " the selected items?",Be="Are you sure that you want to " + "\ufffd0\ufffd" + " the selected " + "\ufffd1\ufffd" + "?",[[3,"modalRef"],["modal",""],[1,"modal-title"],[4,"ngTemplateOutlet"],[1,"modal-content"],["name","deletionForm","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],[4,"ngTemplateOutlet","ngTemplateOutletContext"],[1,"question"],[4,"ngIf","ngIfElse"],["noNames",""],[1,"form-group"],[1,"custom-control","custom-checkbox"],["type","checkbox","name","confirmation","id","confirmation","formControlName","confirmation","autofocus","",1,"custom-control-input"],["for","confirmation",1,"custom-control-label"],lt,[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],["deletionHeading",""],["manyNames",""],Ve,ze,[4,"ngFor","ngForOf"],Be]},template:function(Ve,ze){if(1&Ve&&(d.TgZ(0,"cd-modal",0,1),d.ynx(2,2),d.YNc(3,K,1,0,"ng-container",3),d.BQk(),d.ynx(4,4),d.TgZ(5,"form",5,6),d.TgZ(7,"div",7),d.YNc(8,ee,1,0,"ng-container",8),d.TgZ(9,"div",9),d.YNc(10,se,4,2,"span",10),d.YNc(11,Ee,3,4,"ng-template",null,11,d.W1O),d.YNc(13,ie,1,0,"ng-container",8),d.TgZ(14,"div",12),d.TgZ(15,"div",13),d._UZ(16,"input",14),d.TgZ(17,"label",15),d.SDv(18,16),d.qZA(),d.qZA(),d.qZA(),d.qZA(),d.qZA(),d.TgZ(19,"div",17),d.TgZ(20,"cd-form-button-panel",18),d.NdJ("submitActionEvent",function(){return ze.callSubmitAction()}),d.ALo(21,"titlecase"),d.qZA(),d.qZA(),d.qZA(),d.BQk(),d.qZA(),d.YNc(22,he,2,4,"ng-template",null,19,d.W1O)),2&Ve){const Be=d.MAs(12),Pe=d.MAs(23);d.Q6J("modalRef",ze.activeModal),d.xp6(3),d.Q6J("ngTemplateOutlet",Pe),d.xp6(2),d.Q6J("formGroup",ze.deletionForm),d.xp6(3),d.Q6J("ngTemplateOutlet",ze.bodyTemplate)("ngTemplateOutletContext",ze.bodyContext),d.xp6(2),d.Q6J("ngIf",ze.itemNames)("ngIfElse",Be),d.xp6(3),d.Q6J("ngTemplateOutlet",ze.childFormGroupTemplate)("ngTemplateOutletContext",d.VKq(13,ge,ze.deletionForm)),d.xp6(7),d.Q6J("form",ze.deletionForm)("submitText",d.lcZ(21,11,ze.actionDescription)+" "+ze.itemDescription)}},directives:[_.z,y.tP,r._Y,r.JL,r.sg,S.V,y.O5,A.P,N.o,r.Wl,L.b,r.JJ,r.u,Z.U,J.p,y.sg],pipes:[y.rS,y.i8],styles:[".modal-body[_ngcontent-%COMP%] .question[_ngcontent-%COMP%]{margin-top:1em}.modal-body[_ngcontent-%COMP%] label[_ngcontent-%COMP%]{font-weight:bold}.modal-body[_ngcontent-%COMP%] .question[_ngcontent-%COMP%] .form-check[_ngcontent-%COMP%]{padding-top:7px}"]}),ce})()},52266:(v,T,i)=>{"use strict";i.d(T,{J:()=>S});var r=i(16738),u=i.n(r),p=i(74788),d=i(38549),e=i(24751),_=i(12057);function y(A,N){if(1&A){const L=p.EpF();p.TgZ(0,"div",0),p.TgZ(1,"ngb-timepicker",4),p.NdJ("ngModelChange",function(J){return p.CHM(L),p.oxw().time=J})("ngModelChange",function(){return p.CHM(L),p.oxw().onModelChange()}),p.qZA(),p.qZA()}if(2&A){const L=p.oxw();p.xp6(1),p.Q6J("seconds",L.hasSeconds)("ngModel",L.time)}}let S=(()=>{class A{constructor(L){this.calendar=L,this.hasSeconds=!0,this.hasTime=!0}ngOnInit(){var L;this.minDate=this.calendar.getToday(),this.format=this.hasTime?this.hasSeconds?"YYYY-MM-DD HH:mm:ss":"YYYY-MM-DD HH:mm":"YYYY-MM-DD";let Z=u()(null===(L=this.control)||void 0===L?void 0:L.value,this.format);(!Z.isValid()||Z.isBefore(u()()))&&(Z=u()()),this.date={year:Z.year(),month:Z.month()+1,day:Z.date()},this.time={hour:Z.hour(),minute:Z.minute(),second:Z.second()},this.onModelChange()}onModelChange(){if(this.date){const L=Object.assign({},this.date,this.time);L.month--,setTimeout(()=>{this.control.setValue(u()(L).format(this.format))})}else setTimeout(()=>{this.control.setValue("")})}}return A.\u0275fac=function(L){return new(L||A)(p.Y36(d.vL))},A.\u0275cmp=p.Xpm({type:A,selectors:[["cd-date-time-picker"]],inputs:{control:"control",hasSeconds:"hasSeconds",hasTime:"hasTime"},decls:4,vars:3,consts:[[1,"d-flex","justify-content-center"],[3,"ngModel","minDate","ngModelChange"],["dp",""],["class","d-flex justify-content-center",4,"ngIf"],[3,"seconds","ngModel","ngModelChange"]],template:function(L,Z){1&L&&(p.TgZ(0,"div",0),p.TgZ(1,"ngb-datepicker",1,2),p.NdJ("ngModelChange",function(K){return Z.date=K})("ngModelChange",function(){return Z.onModelChange()}),p.qZA(),p.qZA(),p.YNc(3,y,2,2,"div",3)),2&L&&(p.xp6(1),p.Q6J("ngModel",Z.date)("minDate",Z.minDate),p.xp6(2),p.Q6J("ngIf",Z.hasTime))},directives:[d.VL,e.JJ,e.On,_.O5,d.Pm],styles:[""]}),A})()},30490:(v,T,i)=>{"use strict";i.d(T,{K:()=>p});var r=i(72625),u=i(74788);let p=(()=>{class d{constructor(_){this.docService=_,this.docText="documentation"}ngOnInit(){this.noSubscribe?this.docUrl=this.docService.urlGenerator(this.section):this.docService.subscribeOnce(this.section,_=>{this.docUrl=_})}}return d.\u0275fac=function(_){return new(_||d)(u.Y36(r.R))},d.\u0275cmp=u.Xpm({type:d,selectors:[["cd-doc"]],inputs:{section:"section",docText:"docText",noSubscribe:"noSubscribe"},decls:2,vars:2,consts:[["target","_blank",3,"href"]],template:function(_,y){1&_&&(u.TgZ(0,"a",0),u._uU(1),u.qZA()),2&_&&(u.s9C("href",y.docUrl,u.LSH),u.xp6(1),u.Oqu(y.docText))},styles:[""]}),d})()},30839:(v,T,i)=>{"use strict";i.d(T,{p:()=>S});var r=i(74788),u=i(79512),p=i(39749),d=i(12057),e=i(63285),_=i(13472);function y(A,N){if(1&A){const L=r.EpF();r.TgZ(0,"cd-submit-button",2),r.NdJ("submitAction",function(){return r.CHM(L),r.oxw().submitAction()}),r._uU(1),r.qZA()}if(2&A){const L=r.oxw();r.Q6J("disabled",L.disabled)("form",L.form)("ariaLabel",L.submitText),r.xp6(1),r.Oqu(L.submitText)}}let S=(()=>{class A{constructor(L,Z,J){this.location=L,this.actionLabels=Z,this.modalService=J,this.submitActionEvent=new r.vpe,this.backActionEvent=new r.vpe,this.showSubmit=!0,this.wrappingClass="",this.btnClass="",this.submitText=this.actionLabels.CREATE,this.cancelText=this.actionLabels.CANCEL,this.disabled=!1}submitAction(){this.submitActionEvent.emit()}backAction(){0===this.backActionEvent.observers.length?this.modalService.hasOpenModals()?this.modalService.dismissAll():this.location.back():this.backActionEvent.emit()}}return A.\u0275fac=function(L){return new(L||A)(r.Y36(d.Ye),r.Y36(u.p4),r.Y36(e.Z))},A.\u0275cmp=r.Xpm({type:A,selectors:[["cd-form-button-panel"]],viewQuery:function(L,Z){if(1&L&&r.Gf(p.w,5),2&L){let J;r.iGM(J=r.CRH())&&(Z.submitButton=J.first)}},inputs:{form:"form",showSubmit:"showSubmit",wrappingClass:"wrappingClass",btnClass:"btnClass",submitText:"submitText",cancelText:"cancelText",disabled:"disabled"},outputs:{submitActionEvent:"submitActionEvent",backActionEvent:"backActionEvent"},decls:3,vars:4,consts:[[1,"m-2",3,"name","backAction"],["data-cy","submitBtn",3,"disabled","form","ariaLabel","submitAction",4,"ngIf"],["data-cy","submitBtn",3,"disabled","form","ariaLabel","submitAction"]],template:function(L,Z){1&L&&(r.TgZ(0,"div"),r.TgZ(1,"cd-back-button",0),r.NdJ("backAction",function(){return Z.backAction()}),r.qZA(),r.YNc(2,y,2,4,"cd-submit-button",1),r.qZA()),2&L&&(r.Tol(Z.wrappingClass),r.xp6(1),r.Q6J("name",Z.cancelText),r.xp6(1),r.Q6J("ngIf",Z.showSubmit))},directives:[_.W,d.O5,p.w],styles:[""]}),A})()},65683:(v,T,i)=>{"use strict";i.d(T,{X:()=>je});var r=i(24751),u=i(23815),p=i.n(u),d=i(47557),e=i(28211),_=i(74788),y=i(38549),S=i(62862),A=i(60312),N=i(12057),L=i(41582),Z=i(30839),J=i(87925),K=i(94276),ee=i(17932),ue=i(60192);function ae(He,Vt){if(1&He&&(_.ynx(0,10),_._uU(1),_.BQk()),2&He){const it=_.oxw();_.xp6(1),_.hij(" ",it.titleText," ")}}function H(He,Vt){if(1&He&&(_.TgZ(0,"p"),_._uU(1),_.qZA()),2&He){const it=_.oxw();_.xp6(1),_.Oqu(it.message)}}const se=function(He){return{required:He}};function Ee(He,Vt){if(1&He&&(_.TgZ(0,"label",18),_._uU(1),_.qZA()),2&He){const it=_.oxw().$implicit;_.Q6J("ngClass",_.VKq(3,se,!0===(null==it?null:it.required)))("for",it.name),_.xp6(1),_.hij(" ",it.label," ")}}function ie(He,Vt){if(1&He&&_._UZ(0,"input",19),2&He){const it=_.oxw().$implicit;_.Q6J("type",it.type)("id",it.name)("name",it.name)("formControlName",it.name)}}function he(He,Vt){if(1&He&&_._UZ(0,"input",20),2&He){const it=_.oxw().$implicit;_.Q6J("id",it.name)("name",it.name)("formControlName",it.name)}}function ge(He,Vt){if(1&He&&(_.TgZ(0,"option",24),_._uU(1),_.qZA()),2&He){const it=_.oxw(2).$implicit;_.Q6J("ngValue",null),_.xp6(1),_.hij(" ",null==it||null==it.typeConfig?null:it.typeConfig.placeholder," ")}}function De(He,Vt){if(1&He&&(_.TgZ(0,"option",25),_._uU(1),_.qZA()),2&He){const it=Vt.$implicit;_.Q6J("value",it.value),_.xp6(1),_.hij(" ",it.text," ")}}function ce(He,Vt){if(1&He&&(_.TgZ(0,"select",21),_.YNc(1,ge,2,2,"option",22),_.YNc(2,De,2,2,"option",23),_.qZA()),2&He){const it=_.oxw().$implicit;_.Q6J("id",it.name)("formControlName",it.name),_.xp6(1),_.Q6J("ngIf",null==it||null==it.typeConfig?null:it.typeConfig.placeholder),_.xp6(1),_.Q6J("ngForOf",null==it||null==it.typeConfig?null:it.typeConfig.options)}}function lt(He,Vt){if(1&He&&_._UZ(0,"cd-select-badges",26),2&He){const it=_.oxw().$implicit;_.Q6J("id",it.name)("data",it.value)("customBadges",null==it||null==it.typeConfig?null:it.typeConfig.customBadges)("options",null==it||null==it.typeConfig?null:it.typeConfig.options)("messages",null==it||null==it.typeConfig?null:it.typeConfig.messages)}}function Ve(He,Vt){if(1&He&&(_.TgZ(0,"span",27),_._uU(1),_.qZA()),2&He){const it=_.oxw().$implicit,tn=_.oxw();_.xp6(1),_.hij(" ",tn.getError(it)," ")}}const ze=function(He,Vt){return{"cd-col-form-input":He,"col-sm-12":Vt}},Be=function(){return["text","number"]};function Pe(He,Vt){if(1&He&&(_.ynx(0),_.TgZ(1,"div"),_.YNc(2,Ee,2,5,"label",11),_.TgZ(3,"div",12),_.YNc(4,ie,1,4,"input",13),_.YNc(5,he,1,3,"input",14),_.YNc(6,ce,3,4,"select",15),_.YNc(7,lt,1,5,"cd-select-badges",16),_.YNc(8,Ve,2,1,"span",17),_.qZA(),_.qZA(),_.BQk()),2&He){const it=Vt.$implicit,tn=_.oxw(),It=_.MAs(4);_.xp6(1),_.Gre("form-group row cd-",it.name,"-form-group"),_.xp6(1),_.Q6J("ngIf",it.label),_.xp6(1),_.Q6J("ngClass",_.WLB(10,ze,it.label,!it.label)),_.xp6(1),_.Q6J("ngIf",_.DdM(13,Be).includes(it.type)),_.xp6(1),_.Q6J("ngIf","binary"===it.type),_.xp6(1),_.Q6J("ngIf","select"===it.type),_.xp6(1),_.Q6J("ngIf","select-badges"===it.type),_.xp6(1),_.Q6J("ngIf",tn.formGroup.showError(it.name,It))}}let je=(()=>{class He{constructor(it,tn,It,Zt){this.activeModal=it,this.formBuilder=tn,this.formatter=It,this.dimlessBinaryPipe=Zt}ngOnInit(){this.createForm()}createForm(){const it={};this.fields.forEach(tn=>{it[tn.name]=this.createFormControl(tn)}),this.formGroup=this.formBuilder.group(it)}createFormControl(it){let tn=[];return p().isBoolean(it.required)&&it.required&&tn.push(r.kI.required),it.validators&&(tn=tn.concat(it.validators)),new r.NI(p().defaultTo("binary"===it.type?this.dimlessBinaryPipe.transform(it.value):it.value,null),{validators:tn})}getError(it){const tn=this.formGroup.get(it.name).errors;return Object.keys(tn).map(Zt=>this.getErrorMessage(Zt,tn[Zt],it.errors)).join("<br>")}getErrorMessage(it,tn,It){if(It){const Zt=It[it];if(Zt)return Zt}return["binaryMin","binaryMax"].includes(it)?tn():"required"===it?"This field is required.":"An error occurred."}onSubmitForm(it){this.fields.filter(It=>"binary"===It.type).map(It=>It.name).forEach(It=>{const Zt=it[It];Zt&&(it[It]=this.formatter.toBytes(Zt))}),this.activeModal.close(),p().isFunction(this.onSubmit)&&this.onSubmit(it)}}return He.\u0275fac=function(it){return new(it||He)(_.Y36(y.Kz),_.Y36(S.O),_.Y36(e.H),_.Y36(d.$))},He.\u0275cmp=_.Xpm({type:He,selectors:[["cd-form-modal"]],decls:10,vars:7,consts:[[3,"modalRef"],["class","modal-title",4,"ngIf"],[1,"modal-content"],["novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],[4,"ngIf"],[4,"ngFor","ngForOf"],[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],[1,"modal-title"],["class","cd-col-form-label",3,"ngClass","for",4,"ngIf"],[3,"ngClass"],["class","form-control",3,"type","id","name","formControlName",4,"ngIf"],["type","text","class","form-control","cdDimlessBinary","",3,"id","name","formControlName",4,"ngIf"],["class","form-control",3,"id","formControlName",4,"ngIf"],[3,"id","data","customBadges","options","messages",4,"ngIf"],["class","invalid-feedback",4,"ngIf"],[1,"cd-col-form-label",3,"ngClass","for"],[1,"form-control",3,"type","id","name","formControlName"],["type","text","cdDimlessBinary","",1,"form-control",3,"id","name","formControlName"],[1,"form-control",3,"id","formControlName"],[3,"ngValue",4,"ngIf"],[3,"value",4,"ngFor","ngForOf"],[3,"ngValue"],[3,"value"],[3,"id","data","customBadges","options","messages"],[1,"invalid-feedback"]],template:function(it,tn){1&it&&(_.TgZ(0,"cd-modal",0),_.YNc(1,ae,2,1,"ng-container",1),_.ynx(2,2),_.TgZ(3,"form",3,4),_.TgZ(5,"div",5),_.YNc(6,H,2,1,"p",6),_.YNc(7,Pe,9,14,"ng-container",7),_.qZA(),_.TgZ(8,"div",8),_.TgZ(9,"cd-form-button-panel",9),_.NdJ("submitActionEvent",function(){return tn.onSubmitForm(tn.formGroup.value)}),_.qZA(),_.qZA(),_.qZA(),_.BQk(),_.qZA()),2&it&&(_.Q6J("modalRef",tn.activeModal),_.xp6(1),_.Q6J("ngIf",tn.titleText),_.xp6(2),_.Q6J("formGroup",tn.formGroup),_.xp6(3),_.Q6J("ngIf",tn.message),_.xp6(1),_.Q6J("ngForOf",tn.fields),_.xp6(2),_.Q6J("form",tn.formGroup)("submitText",tn.submitButtonText))},directives:[A.z,N.O5,r._Y,r.JL,r.sg,L.V,N.sg,Z.p,N.mk,J.o,r.Fj,K.b,r.JJ,r.u,ee.Q,r.EJ,r.YN,r.Kr,ue.m],styles:[""]}),He})()},76317:(v,T,i)=>{"use strict";i.d(T,{F:()=>Ee});var r=i(9837),u=i(65862),p=i(74788),d=i(91211),e=i(12057),_=i(8958),y=i(34501),S=i(30490),A=i(87925),N=i(24751);function L(ie,he){1&ie&&(p.TgZ(0,"cd-loading-panel"),p.SDv(1,2),p.qZA())}function Z(ie,he){1&ie&&(p.TgZ(0,"cd-alert-panel",3),p.tHW(1,4),p._UZ(2,"cd-doc",5),p.N_p(),p.qZA())}function J(ie,he){1&ie&&(p.TgZ(0,"cd-alert-panel",3),p.tHW(1,6),p._UZ(2,"cd-doc",5),p.N_p(),p.qZA())}function K(ie,he){if(1&ie&&(p.TgZ(0,"option",21),p._uU(1),p.qZA()),2&ie){const ge=he.$implicit;p.Q6J("ngValue",ge.value),p.xp6(1),p.hij("",ge.name," ")}}function ee(ie,he){if(1&ie){const ge=p.EpF();p.TgZ(0,"cd-alert-panel",24),p.NdJ("dismissed",function(){return p.CHM(ge),p.oxw(3).showMessage=!1}),p.tHW(1,25),p._UZ(2,"a",26),p.N_p(),p.qZA()}if(2&ie){const ge=p.oxw(3);p.xp6(2),p.Q6J("href",ge.grafanaSrc,p.LSH)}}function ue(ie,he){if(1&ie&&(p.TgZ(0,"div",22),p.YNc(1,ee,3,1,"cd-alert-panel",23),p.qZA()),2&ie){const ge=p.oxw(2);p.xp6(1),p.Q6J("ngIf",ge.showMessage)}}const ae=function(ie){return[ie]},H=function(ie,he){return[ie,he]};function se(ie,he){if(1&ie){const ge=p.EpF();p.ynx(0),p.TgZ(1,"div",7),p.TgZ(2,"div",8),p.TgZ(3,"div",9),p.TgZ(4,"label",10),p.SDv(5,11),p.qZA(),p.TgZ(6,"select",12),p.NdJ("ngModelChange",function(ce){return p.CHM(ge),p.oxw().time=ce})("ngModelChange",function(ce){return p.CHM(ge),p.oxw().onTimepickerChange(ce)}),p.YNc(7,K,2,2,"option",13),p.qZA(),p.TgZ(8,"button",14),p.NdJ("click",function(){return p.CHM(ge),p.oxw().reset()}),p._UZ(9,"i",15),p.qZA(),p.TgZ(10,"button",16),p.NdJ("click",function(){p.CHM(ge);const ce=p.oxw();return ce.showMessage=!ce.showMessage}),p._UZ(11,"i",15),p.qZA(),p.qZA(),p.qZA(),p.qZA(),p.TgZ(12,"div",7),p.YNc(13,ue,2,1,"div",17),p.qZA(),p.TgZ(14,"div",7),p.TgZ(15,"div",8),p.TgZ(16,"div",18),p._UZ(17,"iframe",19,20),p.qZA(),p.qZA(),p.qZA(),p.BQk()}if(2&ie){const ge=p.oxw();p.xp6(6),p.Q6J("ngModel",ge.time),p.xp6(1),p.Q6J("ngForOf",ge.grafanaTimes),p.xp6(2),p.Q6J("ngClass",p.VKq(7,ae,ge.icons.undo)),p.xp6(2),p.Q6J("ngClass",p.WLB(9,H,ge.icons.infoCircle,ge.icons.large)),p.xp6(2),p.Q6J("ngIf",ge.showMessage),p.xp6(4),p.Q6J("src",ge.grafanaSrc,p.uOi)("ngClass",ge.panelStyle)}}let Ee=(()=>{class ie{constructor(ge,De){this.sanitizer=ge,this.settingsService=De,this.grafanaExist=!1,this.mode="&kiosk",this.datasource="Dashboard1",this.loading=!0,this.styles={},this.dashboardExist=!0,this.showMessage=!1,this.icons=u.P,this.DEFAULT_TIME="from=now-1h&to=now",this.grafanaTimes=[{name:"Last 5 minutes",value:"from=now-5m&to=now"},{name:"Last 15 minutes",value:"from=now-15m&to=now"},{name:"Last 30 minutes",value:"from=now-30m&to=now"},{name:"Last 1 hour (Default)",value:"from=now-1h&to=now"},{name:"Last 3 hours",value:"from=now-3h&to=now"},{name:"Last 6 hours",value:"from=now-6h&to=now"},{name:"Last 12 hours",value:"from=now-12h&to=now"},{name:"Last 24 hours",value:"from=now-24h&to=now"},{name:"Yesterday",value:"from=now-1d%2Fd&to=now-1d%2Fd"},{name:"Today so far",value:"from=now%2Fd&to=now"},{name:"Day before yesterday",value:"from=now-2d%2Fd&to=now-2d%2Fd"},{name:"Last 2 days",value:"from=now-2d&to=now"},{name:"This day last week",value:"from=now-7d%2Fd&to=now-7d%2Fd"},{name:"Previous week",value:"from=now-1w%2Fw&to=now-1w%2Fw"},{name:"This week so far",value:"from=now%2Fw&to=now"},{name:"Last 7 days",value:"from=now-7d&to=now"},{name:"Previous month",value:"from=now-1M%2FM&to=now-1M%2FM"},{name:"This month so far",value:"from=now%2FM&to=now"},{name:"Last 30 days",value:"from=now-30d&to=now"},{name:"Last 90 days",value:"from=now-90d&to=now"},{name:"Last 6 months",value:"from=now-6M&to=now"},{name:"Last 1 year",value:"from=now-1y&to=now"},{name:"Previous year",value:"from=now-1y%2Fy&to=now-1y%2Fy"},{name:"This year so far",value:"from=now%2Fy&to=now"},{name:"Last 2 years",value:"from=now-2y&to=now"},{name:"Last 5 years",value:"from=now-5y&to=now"}]}ngOnInit(){this.time=this.DEFAULT_TIME,this.styles={one:"grafana_one",two:"grafana_two",three:"grafana_three",four:"grafana_four"},this.settingsService.ifSettingConfigured("api/grafana/url",ge=>{this.grafanaExist=!0,this.loading=!1,this.baseUrl=ge+"/d/",this.getFrame()}),this.panelStyle=this.styles[this.grafanaStyle]}getFrame(){this.settingsService.validateGrafanaDashboardUrl(this.uid).subscribe(ge=>this.dashboardExist=200===ge),this.url=this.baseUrl+this.uid+"/"+this.grafanaPath+`&refresh=2s&var-datasource=${this.datasource}`+this.mode+"&"+this.time,this.grafanaSrc=this.sanitizer.bypassSecurityTrustResourceUrl(this.url)}onTimepickerChange(){this.grafanaExist&&this.getFrame()}reset(){this.time=this.DEFAULT_TIME,this.grafanaExist&&this.getFrame()}ngOnChanges(){this.grafanaExist&&this.getFrame()}}return ie.\u0275fac=function(ge){return new(ge||ie)(p.Y36(d.H7),p.Y36(r.g))},ie.\u0275cmp=p.Xpm({type:ie,selectors:[["cd-grafana"]],inputs:{grafanaPath:"grafanaPath",grafanaStyle:"grafanaStyle",uid:"uid"},features:[p.TTD],decls:4,vars:4,consts:function(){let he,ge,De,ce,lt,Ve,ze;return he="Loading panel data...",ge="Please consult the " + "\ufffd#2\ufffd" + "" + "\ufffd/#2\ufffd" + " on how to configure and enable the monitoring functionality.",De="Grafana Dashboard doesn't exist. Please refer to " + "\ufffd#2\ufffd" + "" + "\ufffd/#2\ufffd" + " on how to add dashboards to Grafana.",ce="Grafana Time Picker",lt="Reset Settings",Ve="Show hidden information",ze="If no embedded Grafana Dashboard appeared below, please follow " + "\ufffd#2\ufffd" + "this link " + "\ufffd/#2\ufffd" + " to check if Grafana is reachable and there are no HTTPS certificate issues. You may need to reload this page after accepting any Browser certificate exceptions",[[4,"ngIf"],["type","info",4,"ngIf"],he,["type","info"],ge,["section","grafana"],De,[1,"row"],[1,"col"],[1,"form-inline","timepicker"],["for","timepicker",1,"ml-1","my-1"],ce,["id","timepicker","name","timepicker",1,"custom-select","my-1","mx-3",3,"ngModel","ngModelChange"],[3,"ngValue",4,"ngFor","ngForOf"],["title",lt,1,"btn","btn-light","my-1",3,"click"],[3,"ngClass"],["title",Ve,1,"btn","btn-light","my-1","ml-3",3,"click"],["class","col my-3",4,"ngIf"],[1,"grafana-container"],["id","iframe","frameborder","0","scrolling","no",1,"grafana",3,"src","ngClass"],["iframe",""],[3,"ngValue"],[1,"col","my-3"],["type","info","class","mb-3","dismissible","true",3,"dismissed",4,"ngIf"],["type","info","dismissible","true",1,"mb-3",3,"dismissed"],ze,["target","_blank","noopener","","noreferrer","",3,"href"]]},template:function(ge,De){1&ge&&(p.YNc(0,L,2,0,"cd-loading-panel",0),p.YNc(1,Z,3,0,"cd-alert-panel",1),p.YNc(2,J,3,0,"cd-alert-panel",1),p.YNc(3,se,19,12,"ng-container",0)),2&ge&&(p.Q6J("ngIf",De.loading&&De.grafanaExist),p.xp6(1),p.Q6J("ngIf",!De.grafanaExist),p.xp6(1),p.Q6J("ngIf",!De.dashboardExist),p.xp6(1),p.Q6J("ngIf",De.grafanaExist&&De.dashboardExist))},directives:[e.O5,_.b,y.G,S.K,A.o,N.EJ,N.JJ,N.On,e.sg,e.mk,N.YN,N.Kr],styles:[".grafana[_ngcontent-%COMP%]{height:600px;width:100%;z-index:0}.grafana_one[_ngcontent-%COMP%]{height:400px}.grafana_two[_ngcontent-%COMP%]{height:750px}.grafana_three[_ngcontent-%COMP%]{height:900px}.grafana_four[_ngcontent-%COMP%]{height:1160px}.timepicker[_ngcontent-%COMP%] label[_ngcontent-%COMP%]{font-weight:700}.dropdown-menu[_ngcontent-%COMP%]{left:auto;right:20px;top:20px}"]}),ie})()},18372:(v,T,i)=>{"use strict";i.d(T,{S:()=>S});var r=i(65862),u=i(74788),p=i(12057),d=i(38549);function e(A,N){if(1&A&&(u._UZ(0,"div",2),u.Hsn(1)),2&A){const L=u.oxw();u.Tol(L.class),u.Q6J("innerHtml",L.html,u.oJD)}}const _=function(A){return[A]},y=["*"];let S=(()=>{class A{constructor(){this.icons=r.P}}return A.\u0275fac=function(L){return new(L||A)},A.\u0275cmp=u.Xpm({type:A,selectors:[["cd-helper"]],inputs:{class:"class",html:"html"},ngContentSelectors:y,decls:3,vars:4,consts:[["popoverTpl",""],["aria-hidden","true",3,"ngClass","ngbPopover","click"],[3,"innerHtml"]],template:function(L,Z){if(1&L&&(u.F$t(),u.YNc(0,e,2,3,"ng-template",null,0,u.W1O),u.TgZ(2,"i",1),u.NdJ("click",function(K){return K.preventDefault()}),u.qZA()),2&L){const J=u.MAs(1);u.xp6(2),u.Q6J("ngClass",u.VKq(2,_,Z.icons.questionCircle))("ngbPopover",J)}},directives:[p.mk,d.o8],styles:["i[_ngcontent-%COMP%]{color:#2b99a8;cursor:pointer;padding-left:4px}"]}),A})()},8958:(v,T,i)=>{"use strict";i.d(T,{b:()=>y});var r=i(65862),u=i(74788),p=i(38549),d=i(12057);const e=function(S,A){return[S,A]},_=["*"];let y=(()=>{class S{constructor(){this.icons=r.P}}return S.\u0275fac=function(N){return new(N||S)},S.\u0275cmp=u.Xpm({type:S,selectors:[["cd-loading-panel"]],ngContentSelectors:_,decls:4,vars:5,consts:[["type","info",3,"dismissible"],["aria-hidden","true",1,"mr-2",3,"ngClass"]],template:function(N,L){1&N&&(u.F$t(),u.TgZ(0,"ngb-alert",0),u.TgZ(1,"strong"),u._UZ(2,"i",1),u.qZA(),u.Hsn(3),u.qZA()),2&N&&(u.Q6J("dismissible",!1),u.xp6(2),u.Q6J("ngClass",u.WLB(2,e,L.icons.spinner,L.icons.spin)))},directives:[p.xm,d.mk],styles:[""]}),S})()},60312:(v,T,i)=>{"use strict";i.d(T,{z:()=>y});var r=i(74788),u=i(6283),p=i(12057),d=i(87925);const e=[[["",8,"modal-title"]],[["",8,"modal-content"]]],_=[".modal-title",".modal-content"];let y=(()=>{class S{constructor(N){this.router=N,this.hide=new r.vpe}close(){var N;this.pageURL?this.router.navigate([this.pageURL,{outlets:{modal:null}}]):null===(N=this.modalRef)||void 0===N||N.close(),this.hide.emit()}}return S.\u0275fac=function(N){return new(N||S)(r.Y36(u.F0))},S.\u0275cmp=r.Xpm({type:S,selectors:[["cd-modal"]],inputs:{modalRef:"modalRef",pageURL:"pageURL"},outputs:{hide:"hide"},ngContentSelectors:_,decls:10,vars:2,consts:[[3,"ngClass"],[1,"modal-content"],[1,"modal-header"],[1,"modal-title","float-left"],["type","button","aria-label","Close",1,"close","float-right",3,"click"],["aria-hidden","true"]],template:function(N,L){1&N&&(r.F$t(e),r.TgZ(0,"div",0),r.TgZ(1,"div",0),r.TgZ(2,"div",1),r.TgZ(3,"div",2),r.TgZ(4,"h4",3),r.Hsn(5),r.qZA(),r.TgZ(6,"button",4),r.NdJ("click",function(){return L.close()}),r.TgZ(7,"span",5),r._uU(8,"\xd7"),r.qZA(),r.qZA(),r.qZA(),r.Hsn(9,1),r.qZA(),r.qZA(),r.qZA()),2&N&&(r.Q6J("ngClass",L.pageURL?"modal":""),r.xp6(1),r.Q6J("ngClass",L.pageURL?"modal-dialog":""))},directives:[p.mk,d.o],styles:[".modal-header[_ngcontent-%COMP%]{background-color:#e9ecef;border-bottom:1px solid #ced4da;border-radius:5px 5px 0 0} cd-modal .modal-footer{background-color:#e9ecef;border-bottom:1px solid #ced4da;border-radius:0 0 5px 5px} cd-modal .modal-body{max-height:70vh;overflow-x:hidden;overflow-y:auto}button.close[_ngcontent-%COMP%]{outline:none}"]}),S})()},60192:(v,T,i)=>{"use strict";i.d(T,{m:()=>A});var r=i(74788),u=i(65862),p=i(7022),d=i(39092),e=i(12057);const _=["cdSelect"],y=function(N){return[N]};function S(N,L){if(1&N){const Z=r.EpF();r.TgZ(0,"span"),r.TgZ(1,"span",4),r.TgZ(2,"span",5),r._uU(3),r.qZA(),r.TgZ(4,"a",6),r.NdJ("click",function(){const ee=r.CHM(Z).$implicit;return r.oxw(),r.MAs(1).removeItem(ee)}),r._UZ(5,"i",7),r.qZA(),r.qZA(),r.qZA()}if(2&N){const Z=L.$implicit,J=r.oxw();r.xp6(3),r.Oqu(Z),r.xp6(2),r.Q6J("ngClass",r.VKq(2,y,J.icons.destroy))}}let A=(()=>{class N{constructor(){this.data=[],this.options=[],this.messages=new p.a({}),this.customBadges=!1,this.customBadgeValidators=[],this.selection=new r.vpe,this.icons=u.P}}return N.\u0275fac=function(Z){return new(Z||N)},N.\u0275cmp=r.Xpm({type:N,selectors:[["cd-select-badges"]],viewQuery:function(Z,J){if(1&Z&&r.Gf(_,7),2&Z){let K;r.iGM(K=r.CRH())&&(J.cdSelect=K.first)}},inputs:{data:"data",options:"options",messages:"messages",selectionLimit:"selectionLimit",customBadges:"customBadges",customBadgeValidators:"customBadgeValidators"},outputs:{selection:"selection"},decls:4,vars:10,consts:[["elemClass","mr-2 select-menu-edit",3,"data","options","messages","selectionLimit","customBadges","customBadgeValidators","selection"],["cdSelect",""],[3,"ngClass"],[4,"ngFor","ngForOf"],[1,"badge","badge-dark","mr-2"],[1,"mr-2"],[1,"badge-remove",3,"click"],["aria-hidden","true",3,"ngClass"]],template:function(Z,J){1&Z&&(r.TgZ(0,"cd-select",0,1),r.NdJ("selection",function(ee){return J.selection.emit(ee)}),r._UZ(2,"i",2),r.qZA(),r.YNc(3,S,6,4,"span",3)),2&Z&&(r.Q6J("data",J.data)("options",J.options)("messages",J.messages)("selectionLimit",J.selectionLimit)("customBadges",J.customBadges)("customBadgeValidators",J.customBadgeValidators),r.xp6(2),r.Q6J("ngClass",r.VKq(8,y,J.icons.edit)),r.xp6(1),r.Q6J("ngForOf",J.data))},directives:[d.H,e.mk,e.sg],styles:[".badge-remove[_ngcontent-%COMP%]{color:#fff}i.fa-pencil[_ngcontent-%COMP%]{font-size:1.1rem}"]}),N})()},7022:(v,T,i)=>{"use strict";i.d(T,{a:()=>p});var r=i(23815),u=i.n(r);class p{constructor(e){this.customValidations={},this.empty="No items selected.",this.selectionLimit={tooltip:"Deselect item to select again",text:"Selection limit reached"},this.filter="Filter tags",this.add="Add badge",this.noOptions="There are no items available.",u().merge(this,e)}}},14745:(v,T,i)=>{"use strict";i.d(T,{$:()=>r});class r{constructor(p,d,e,_=!0){this.selected=p,this.name=d,this.description=e,this.enabled=_}}},39092:(v,T,i)=>{"use strict";i.d(T,{H:()=>Be});var r=i(74788),u=i(24751),p=i(23815),d=i.n(p),e=i(65862),_=i(95463),y=i(7022),S=i(14745),A=i(12057),N=i(41582),L=i(87925),Z=i(94276),J=i(38549);function K(Pe,je){if(1&Pe&&(r.TgZ(0,"span",12),r._uU(1),r.qZA()),2&Pe){const He=r.oxw().$implicit,Vt=r.oxw(2);r.xp6(1),r.hij(" ",Vt.messages.customValidations[He]," ")}}function ee(Pe,je){if(1&Pe&&(r.ynx(0),r.YNc(1,K,2,1,"span",11),r.BQk()),2&Pe){const He=je.$implicit;r.oxw();const Vt=r.MAs(1),it=r.oxw();r.xp6(1),r.Q6J("ngIf",it.form.showError("filter",Vt)&&it.filter.hasError(He))}}const ue=function(Pe){return[Pe]};function ae(Pe,je){if(1&Pe&&r._UZ(0,"i",18),2&Pe){const He=r.oxw(3);r.Q6J("ngClass",r.VKq(1,ue,He.icons.check))}}function H(Pe,je){if(1&Pe&&(r.ynx(0),r._UZ(1,"br"),r.TgZ(2,"small",19),r._uU(3),r.qZA(),r.BQk()),2&Pe){const He=r.oxw().$implicit;r.xp6(3),r.hij(" ",He.description,"\xa0 ")}}const se=function(Pe){return{"help-block disabled":Pe}};function Ee(Pe,je){if(1&Pe){const He=r.EpF();r.TgZ(0,"div",13),r.NdJ("click",function(){const tn=r.CHM(He).$implicit;return r.oxw(2).triggerSelection(tn)}),r.TgZ(1,"div",14),r.YNc(2,ae,1,3,"i",15),r._uU(3," \xa0 "),r.qZA(),r.TgZ(4,"div",16),r._uU(5),r.YNc(6,H,4,1,"ng-container",17),r.qZA(),r.qZA()}if(2&Pe){const He=je.$implicit,Vt=r.oxw(2);r.Q6J("ngClass",r.VKq(4,se,!(Vt.data.length!==Vt.selectionLimit&&He.enabled||He.selected))),r.xp6(2),r.Q6J("ngIf",He.selected),r.xp6(3),r.hij(" ",He.name," "),r.xp6(1),r.Q6J("ngIf",He.description)}}function ie(Pe,je){if(1&Pe){const He=r.EpF();r.TgZ(0,"div",20),r.NdJ("click",function(){return r.CHM(He),r.oxw(2).addCustomOption()}),r.TgZ(1,"div",14),r._UZ(2,"i",18),r._uU(3," \xa0 "),r.qZA(),r.TgZ(4,"div",16),r._uU(5),r.qZA(),r.qZA()}if(2&Pe){const He=r.oxw(2);r.xp6(2),r.Q6J("ngClass",r.VKq(3,ue,He.icons.tag)),r.xp6(3),r.AsE(" ",He.messages.add," '",He.filter.value,"' ")}}function he(Pe,je){if(1&Pe&&(r.TgZ(0,"span",23),r._uU(1),r.qZA()),2&Pe){const He=r.oxw(3);r.Q6J("ngbTooltip",He.messages.selectionLimit.tooltip),r.xp6(1),r.hij(" ",He.messages.selectionLimit.text," ")}}function ge(Pe,je){if(1&Pe&&(r.TgZ(0,"div",21),r.YNc(1,he,2,2,"span",22),r.qZA()),2&Pe){const He=r.oxw(2);r.xp6(1),r.Q6J("ngIf",He.data.length===He.selectionLimit)}}function De(Pe,je){if(1&Pe){const He=r.EpF();r.TgZ(0,"form",4,5),r.TgZ(2,"div"),r.TgZ(3,"input",6),r.NdJ("keyup",function(it){r.CHM(He);const tn=r.oxw();return 13==it.keyCode?tn.selectOption():tn.updateFilter()}),r.qZA(),r.YNc(4,ee,2,1,"ng-container",7),r.qZA(),r.qZA(),r.YNc(5,Ee,7,6,"div",8),r.YNc(6,ie,6,5,"div",9),r.YNc(7,ge,2,1,"div",10)}if(2&Pe){const He=r.oxw();r.Q6J("formGroup",He.form),r.xp6(3),r.Q6J("placeholder",He.messages.filter),r.xp6(1),r.Q6J("ngForOf",He.Object.keys(He.messages.customValidations)),r.xp6(1),r.Q6J("ngForOf",He.filteredOptions),r.xp6(1),r.Q6J("ngIf",He.isCreatable()),r.xp6(1),r.Q6J("ngIf",He.data.length===He.selectionLimit)}}function ce(Pe,je){if(1&Pe&&(r.TgZ(0,"a",24),r.Hsn(1),r.qZA()),2&Pe){const He=r.oxw(),Vt=r.MAs(1);r.Q6J("ngClass",He.elemClass)("ngbPopover",Vt)}}function lt(Pe,je){if(1&Pe&&(r.TgZ(0,"span",25),r._uU(1),r.qZA()),2&Pe){const He=r.oxw();r.xp6(1),r.hij(" ",He.messages.empty,"\n")}}function Ve(Pe,je){if(1&Pe&&(r.TgZ(0,"span",25),r._uU(1),r.qZA()),2&Pe){const He=r.oxw();r.xp6(1),r.hij(" ",He.messages.noOptions,"\n")}}const ze=["*"];let Be=(()=>{class Pe{constructor(){this.data=[],this.options=[],this.messages=new y.a({}),this.customBadges=!1,this.customBadgeValidators=[],this.selection=new r.vpe,this.Object=Object,this.filteredOptions=[],this.icons=e.P}ngOnInit(){this.initFilter(),this.data.length>0&&this.initMissingOptions(),this.options=d().sortBy(this.options,["name"]),this.updateOptions()}initFilter(){this.filter=new u.NI("",{validators:this.customBadgeValidators}),this.form=new _.d({filter:this.filter}),this.filteredOptions=[...this.options||[]]}initMissingOptions(){const He=this.options.map(it=>it.name);this.data.filter(it=>-1===He.indexOf(it)).forEach(it=>this.addOption(it)),this.forceOptionsToReflectData()}addOption(He){this.options.push(new S.$(!1,He,"")),this.options=d().sortBy(this.options,["name"]),this.triggerSelection(this.options.find(Vt=>Vt.name===He))}triggerSelection(He){!He||this.selectionLimit&&!He.selected&&this.data.length>=this.selectionLimit||(He.selected=!He.selected,this.updateOptions(),this.selection.emit({option:He}))}updateOptions(){this.data.splice(0,this.data.length),this.options.forEach(He=>{He.selected&&this.data.push(He.name)}),this.updateFilter()}updateFilter(){this.filteredOptions=this.options.filter(He=>He.name.includes(this.filter.value))}forceOptionsToReflectData(){this.options.forEach(He=>{-1!==this.data.indexOf(He.name)&&(He.selected=!0)})}ngOnChanges(){this.filter&&this.updateFilter(),this.options&&this.data&&0!==this.data.length&&this.forceOptionsToReflectData()}selectOption(){0===this.filteredOptions.length?this.addCustomOption():(this.triggerSelection(this.filteredOptions[0]),this.resetFilter())}addCustomOption(){!this.isCreatable()||(this.addOption(this.filter.value),this.resetFilter())}isCreatable(){return this.customBadges&&this.filter.valid&&this.filter.value.length>0&&this.filteredOptions.every(He=>He.name!==this.filter.value)}resetFilter(){this.filter.setValue(""),this.updateFilter()}removeItem(He){this.triggerSelection(this.options.find(Vt=>Vt.name===He&&Vt.selected))}}return Pe.\u0275fac=function(He){return new(He||Pe)},Pe.\u0275cmp=r.Xpm({type:Pe,selectors:[["cd-select"]],inputs:{elemClass:"elemClass",data:"data",options:"options",messages:"messages",selectionLimit:"selectionLimit",customBadges:"customBadges",customBadgeValidators:"customBadgeValidators"},outputs:{selection:"selection"},features:[r.TTD],ngContentSelectors:ze,decls:5,vars:3,consts:[["popTemplate",""],["class","select-menu-edit float-left","data-testid","select-menu-edit",3,"ngClass","ngbPopover",4,"ngIf"],["class","form-text text-muted float-left",4,"ngIf"],["class","form-text text-muted float-left",4,"ngIf"],["name","form","novalidate","",3,"formGroup"],["formDir","ngForm"],["type","text","formControlName","filter",1,"form-control","text-center",3,"placeholder","keyup"],[4,"ngFor","ngForOf"],["class","select-menu-item",3,"ngClass","click",4,"ngFor","ngForOf"],["class","select-menu-item",3,"click",4,"ngIf"],["class","is-invalid",4,"ngIf"],["class","invalid-feedback text-center d-block",4,"ngIf"],[1,"invalid-feedback","text-center","d-block"],[1,"select-menu-item",3,"ngClass","click"],[1,"select-menu-item-icon"],["aria-hidden","true",3,"ngClass",4,"ngIf"],[1,"select-menu-item-content"],[4,"ngIf"],["aria-hidden","true",3,"ngClass"],[1,"form-text","text-muted"],[1,"select-menu-item",3,"click"],[1,"is-invalid"],["class","form-text text-muted text-center text-warning",3,"ngbTooltip",4,"ngIf"],[1,"form-text","text-muted","text-center","text-warning",3,"ngbTooltip"],["data-testid","select-menu-edit",1,"select-menu-edit","float-left",3,"ngClass","ngbPopover"],[1,"form-text","text-muted","float-left"]],template:function(He,Vt){1&He&&(r.F$t(),r.YNc(0,De,8,6,"ng-template",null,0,r.W1O),r.YNc(2,ce,2,2,"a",1),r.YNc(3,lt,2,1,"span",2),r.YNc(4,Ve,2,1,"span",3)),2&He&&(r.xp6(2),r.Q6J("ngIf",Vt.customBadges||Vt.options.length>0),r.xp6(1),r.Q6J("ngIf",0===Vt.data.length&&!(!Vt.customBadges&&0===Vt.options.length)),r.xp6(1),r.Q6J("ngIf",!Vt.customBadges&&0===Vt.options.length))},directives:[A.O5,u._Y,u.JL,u.sg,N.V,L.o,u.Fj,Z.b,u.JJ,u.u,A.sg,A.mk,J._L,J.o8],styles:[".select-menu-item[_ngcontent-%COMP%]{border-bottom:1px solid rgba(0,0,0,.09);cursor:pointer;display:block;font-size:1rem}.select-menu-item[_ngcontent-%COMP%]:hover{background-color:#e9ecef}.select-menu-item-icon[_ngcontent-%COMP%]{float:left;padding:.5em;width:3em}.select-menu-item-content[_ngcontent-%COMP%]{padding:.5em}.select-menu-item-content[_ngcontent-%COMP%] .form-text[_ngcontent-%COMP%]{display:flex}"]}),Pe})()},76446:(v,T,i)=>{"use strict";i.d(T,{l:()=>S});var r=i(87311),u=i(47557),p=i(74788),d=i(12057),e=i(7194);const _=["sparkCanvas"],y=["sparkTooltip"];let S=(()=>{class A{constructor(L){this.dimlessBinaryPipe=L,this.style={height:"30px",width:"100px"},this.colors=[{backgroundColor:"rgba(40,140,234,0.2)",borderColor:"rgba(40,140,234,1)",pointBackgroundColor:"rgba(40,140,234,1)",pointBorderColor:"#fff",pointHoverBackgroundColor:"#fff",pointHoverBorderColor:"rgba(40,140,234,0.8)"}],this.options={animation:{duration:0},responsive:!0,maintainAspectRatio:!1,legend:{display:!1},elements:{line:{borderWidth:1}},tooltips:{enabled:!1,mode:"index",intersect:!1,custom:void 0,callbacks:{label:Z=>this.isBinary?this.dimlessBinaryPipe.transform(Z.yLabel):Z.yLabel,title:()=>""}},scales:{yAxes:[{display:!1}],xAxes:[{display:!1}]}},this.datasets=[{data:[]}],this.labels=[]}ngOnInit(){const J=new r.h(this.chartCanvasRef,this.chartTooltipRef,(K,ee)=>ee+K.caretX+"px",K=>K.caretY-K.height-K.yPadding-5+"px");J.customColors={backgroundColor:this.colors[0].pointBackgroundColor,borderColor:this.colors[0].pointBorderColor},this.options.tooltips.custom=K=>{J.customTooltips(K)}}ngOnChanges(L){this.datasets[0].data=L.data.currentValue,this.labels=[...Array(L.data.currentValue.length)]}}return A.\u0275fac=function(L){return new(L||A)(p.Y36(u.$))},A.\u0275cmp=p.Xpm({type:A,selectors:[["cd-sparkline"]],viewQuery:function(L,Z){if(1&L&&(p.Gf(_,7),p.Gf(y,7)),2&L){let J;p.iGM(J=p.CRH())&&(Z.chartCanvasRef=J.first),p.iGM(J=p.CRH())&&(Z.chartTooltipRef=J.first)}},inputs:{data:"data",style:"style",isBinary:"isBinary"},features:[p.TTD],decls:6,vars:6,consts:[[1,"chart-container",3,"ngStyle"],["baseChart","",3,"labels","datasets","options","colors","chartType"],["sparkCanvas",""],[1,"chartjs-tooltip"],["sparkTooltip",""]],template:function(L,Z){1&L&&(p.TgZ(0,"div",0),p._UZ(1,"canvas",1,2),p.TgZ(3,"div",3,4),p._UZ(5,"table"),p.qZA(),p.qZA()),2&L&&(p.Q6J("ngStyle",Z.style),p.xp6(1),p.Q6J("labels",Z.labels)("datasets",Z.datasets)("options",Z.options)("colors",Z.colors)("chartType","line"))},directives:[d.PC,e.jh],styles:['.chart-container[_ngcontent-%COMP%]{cursor:pointer;margin:auto;overflow:visible;position:absolute}canvas[_ngcontent-%COMP%]{user-select:none}.chartjs-tooltip[_ngcontent-%COMP%]{background:rgba(0,0,0,.7);border-radius:3px;color:#fff;font-family:"Helvetica Neue","Helvetica","Arial",sans-serif!important;opacity:0;pointer-events:none;position:absolute;transform:translate(-50%);transition:all .1s ease}.chartjs-tooltip.transform-left[_ngcontent-%COMP%]{transform:translate(-10%)}.chartjs-tooltip.transform-left[_ngcontent-%COMP%]:after{left:10%}.chartjs-tooltip.transform-right[_ngcontent-%COMP%]{transform:translate(-90%)}.chartjs-tooltip.transform-right[_ngcontent-%COMP%]:after{left:90%}.chartjs-tooltip[_ngcontent-%COMP%]:after{border-color:#000 transparent transparent transparent;border-style:solid;border-width:5px;content:" ";left:50%;margin-left:-5px;position:absolute;top:100%} .chartjs-tooltip-key{display:inline-block;height:10px;margin-right:10px;width:10px}.chart-container[_ngcontent-%COMP%]{position:static!important}']}),A})()},39749:(v,T,i)=>{"use strict";i.d(T,{w:()=>L});var r=i(74788),u=i(24751),p=i(23815),d=i.n(p),e=i(65862),_=i(87925),y=i(12057);const S=function(Z,J){return[Z,J]};function A(Z,J){if(1&Z&&(r.TgZ(0,"span"),r._UZ(1,"i",2),r.qZA()),2&Z){const K=r.oxw();r.xp6(1),r.Q6J("ngClass",r.WLB(1,S,K.icons.spinner,K.icons.spin))}}const N=["*"];let L=(()=>{class Z{constructor(K){this.elRef=K,this.type="submit",this.disabled=!1,this.submitAction=new r.vpe,this.loading=!1,this.icons=e.P}ngOnInit(){this.form.statusChanges.subscribe(()=>{d().has(this.form.errors,"cdSubmitButton")&&(this.loading=!1,d().unset(this.form.errors,"cdSubmitButton"),this.form instanceof u.TO&&this.form.updateValueAndValidity())})}submit(K){this.focusButton(),this.form instanceof u.sg&&this.form.onSubmit(K),this.form.invalid?this.focusInvalid():(this.loading=!0,this.submitAction.emit())}focusButton(){this.elRef.nativeElement.offsetParent.querySelector(`button[type="${this.type}"]`).focus()}focusInvalid(){const K=this.elRef.nativeElement.offsetParent.querySelector("input.ng-invalid, select.ng-invalid");K&&K.focus()}}return Z.\u0275fac=function(K){return new(K||Z)(r.Y36(r.SBq))},Z.\u0275cmp=r.Xpm({type:Z,selectors:[["cd-submit-button"]],inputs:{form:"form",type:"type",disabled:"disabled",btnClass:"btnClass",ariaLabel:"ariaLabel"},outputs:{submitAction:"submitAction"},ngContentSelectors:N,decls:3,vars:5,consts:[[1,"btn","btn-accent","tc_submitButton",3,"type","ngClass","disabled","click"],[4,"ngIf"],[3,"ngClass"]],template:function(K,ee){1&K&&(r.F$t(),r.TgZ(0,"button",0),r.NdJ("click",function(ae){return ee.submit(ae)}),r.Hsn(1),r.YNc(2,A,2,4,"span",1),r.qZA()),2&K&&(r.Q6J("type",ee.type)("ngClass",ee.btnClass)("disabled",ee.loading||ee.disabled),r.uIk("aria-label",ee.ariaLabel),r.xp6(2),r.Q6J("ngIf",ee.loading))},directives:[_.o,y.mk,y.O5],styles:[""]}),Z})()},60251:(v,T,i)=>{"use strict";i.d(T,{O:()=>A});var r=i(74788),u=i(38549),p=i(12057),d=i(47557),e=i(66369);function _(N,L){if(1&N&&(r.TgZ(0,"tr"),r.TgZ(1,"td",4),r._uU(2,"Free:\xa0"),r.qZA(),r.TgZ(3,"td",7),r.TgZ(4,"strong"),r._uU(5),r.ALo(6,"dimlessBinary"),r.ALo(7,"dimless"),r.qZA(),r.qZA(),r.qZA()),2&N){const Z=r.oxw(2);r.xp6(5),r.Oqu(Z.isBinary?r.lcZ(6,1,Z.total-Z.used):r.lcZ(7,3,Z.total-Z.used))}}function y(N,L){if(1&N&&(r.TgZ(0,"table"),r.TgZ(1,"tr"),r.TgZ(2,"td",4),r._uU(3,"Used:\xa0"),r.qZA(),r.TgZ(4,"td",5),r.TgZ(5,"strong"),r._uU(6),r.ALo(7,"dimlessBinary"),r.ALo(8,"dimless"),r.qZA(),r.qZA(),r.qZA(),r.YNc(9,_,8,5,"tr",6),r.qZA()),2&N){const Z=r.oxw();r.xp6(6),r.hij(" ",Z.isBinary?r.lcZ(7,2,Z.used):r.lcZ(8,4,Z.used),""),r.xp6(3),r.Q6J("ngIf",Z.calculatePerc)}}const S=function(N,L){return{"bg-warning":N,"bg-danger":L}};let A=(()=>{class N{constructor(){this.isBinary=!0,this.decimals=0,this.calculatePerc=!0}ngOnChanges(){this.calculatePerc?(this.usedPercentage=this.total>0?this.used/this.total*100:0,this.freePercentage=100-this.usedPercentage):this.used?(this.used=this.used.slice(0,-1),this.usedPercentage=Number(this.used),this.freePercentage=100-this.usedPercentage):this.usedPercentage=0}}return N.\u0275fac=function(Z){return new(Z||N)},N.\u0275cmp=r.Xpm({type:N,selectors:[["cd-usage-bar"]],inputs:{total:"total",used:"used",warningThreshold:"warningThreshold",errorThreshold:"errorThreshold",isBinary:"isBinary",decimals:"decimals",calculatePerc:"calculatePerc"},features:[r.TTD],decls:8,vars:13,consts:[["usageTooltipTpl",""],["data-placement","left",1,"progress",3,"ngbTooltip"],["role","progressbar",1,"progress-bar","bg-info",3,"ngClass"],["role","progressbar",1,"progress-bar","bg-freespace"],[1,"text-left"],[1,"text-right"],[4,"ngIf"],[1,"'text-right"]],template:function(Z,J){if(1&Z&&(r.YNc(0,y,10,6,"ng-template",null,0,r.W1O),r.TgZ(2,"div",1),r.TgZ(3,"div",2),r.TgZ(4,"span"),r._uU(5),r.ALo(6,"number"),r.qZA(),r.qZA(),r._UZ(7,"div",3),r.qZA()),2&Z){const K=r.MAs(1);r.xp6(2),r.Q6J("ngbTooltip",K),r.xp6(1),r.Udp("width",J.usedPercentage+"%"),r.Q6J("ngClass",r.WLB(10,S,J.usedPercentage/100>=J.warningThreshold,J.usedPercentage/100>=J.errorThreshold)),r.xp6(2),r.hij("",r.xi3(6,7,J.usedPercentage,"1.0-"+J.decimals),"%"),r.xp6(2),r.Udp("width",J.freePercentage+"%")}},directives:[u._L,p.mk,p.O5],pipes:[p.JJ,d.$,e.n],styles:[".bg-info[_ngcontent-%COMP%]{background-color:#2b99a8!important}.bg-warning[_ngcontent-%COMP%]{background-color:#ffc200!important}.bg-danger[_ngcontent-%COMP%]{background-color:#ef5c55!important}.bg-freespace[_ngcontent-%COMP%]{background-color:#ced4da!important}.progress[_ngcontent-%COMP%]{height:20px;margin-bottom:0;position:relative}.progress[_ngcontent-%COMP%] div.progress-bar[_ngcontent-%COMP%]{position:static}.progress[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{color:#000;display:block;font-weight:normal;position:absolute;width:100%}"]}),N})()},79512:(v,T,i)=>{"use strict";i.d(T,{$x:()=>p,MQ:()=>d,Qn:()=>e,p4:()=>_,aX:()=>y});var r=i(92340),u=i(74788);class p{}p.organization="ceph",p.projectName="Ceph Dashboard",p.license="Free software (LGPL 2.1).",p.copyright="Copyright(c) "+r.N.year+" Ceph contributors.",p.cephLogo="assets/Ceph_Logo.svg";var d=(()=>{return(S=d||(d={})).CREATE="create",S.EDIT="edit",S.UPDATE="update",S.REMOVE="remove",S.DELETE="delete",S.ADD="add",S.COPY="copy",S.CLONE="clone",S.RECREATE="recreate",S.EXPIRE="expire",S.RESTART="Restart",d;var S})(),e=(()=>{return(S=e||(e={})).CREATE="Create",S.DELETE="Delete",S.ADD="Add",S.REMOVE="Remove",S.EDIT="Edit",S.CANCEL="Cancel",S.COPY="Copy",S.CLONE="Clone",S.UPDATE="Update",S.EVICT="Evict",S.SHOW="Show",S.RECREATE="Recreate",S.EXPIRE="Expire",S.START="Start",S.STOP="Stop",S.REDEPLOY="Redeploy",S.RESTART="Restart",e;var S})();let _=(()=>{class S{constructor(){this.CREATE="Create",this.DELETE="Delete",this.ADD="Add",this.SET="Set",this.SUBMIT="Submit",this.REMOVE="Remove",this.UNSET="Unset",this.EDIT="Edit",this.UPDATE="Update",this.CANCEL="Cancel",this.PREVIEW="Preview",this.MOVE="Move",this.NEXT="Next",this.BACK="Back",this.CLONE="Clone",this.COPY="Copy",this.DEEP_SCRUB="Deep Scrub",this.DESTROY="Destroy",this.EVICT="Evict",this.FLATTEN="Flatten",this.MARK_DOWN="Mark Down",this.MARK_IN="Mark In",this.MARK_LOST="Mark Lost",this.MARK_OUT="Mark Out",this.PROTECT="Protect",this.PURGE="Purge",this.RENAME="Rename",this.RESTORE="Restore",this.REWEIGHT="Reweight",this.ROLLBACK="Rollback",this.SCRUB="Scrub",this.SHOW="Show",this.TRASH="Move to Trash",this.UNPROTECT="Unprotect",this.CHANGE="Change",this.FLAGS="Flags",this.ENTER_MAINTENANCE="Enter Maintenance",this.EXIT_MAINTENANCE="Exit Maintenance",this.START_DRAIN="Start Drain",this.STOP_DRAIN="Stop Drain",this.RESYNC="Resync",this.RECREATE="Recreate",this.EXPIRE="Expire",this.START="Start",this.STOP="Stop",this.REDEPLOY="Redeploy",this.RESTART="Restart",this.REMOVE_SCHEDULING="Remove Scheduling",this.PROMOTE="Promote",this.DEMOTE="Demote"}}return S.\u0275fac=function(N){return new(N||S)},S.\u0275prov=u.Yz7({token:S,factory:S.\u0275fac,providedIn:"root"}),S})(),y=(()=>{class S{constructor(){this.CREATED="Created",this.DELETED="Deleted",this.ADDED="Added",this.REMOVED="Removed",this.EDITED="Edited",this.CANCELED="Canceled",this.PREVIEWED="Previewed",this.MOVED="Moved",this.CLONED="Cloned",this.COPIED="Copied",this.DEEP_SCRUBBED="Deep Scrubbed",this.DESTROYED="Destroyed",this.FLATTENED="Flattened",this.MARKED_DOWN="Marked Down",this.MARKED_IN="Marked In",this.MARKED_LOST="Marked Lost",this.MARKED_OUT="Marked Out",this.PROTECTED="Protected",this.PURGED="Purged",this.RENAMED="Renamed",this.RESTORED="Restored",this.REWEIGHTED="Reweighted",this.ROLLED_BACK="Rolled back",this.SCRUBBED="Scrubbed",this.SHOWED="Showed",this.TRASHED="Moved to Trash",this.UNPROTECTED="Unprotected",this.CHANGE="Change",this.RECREATED="Recreated",this.EXPIRED="Expired",this.START="Start",this.STOP="Stop",this.REDEPLOY="Redeploy",this.RESTART="Restart"}}return S.\u0275fac=function(N){return new(N||S)},S.\u0275prov=u.Yz7({token:S,factory:S.\u0275fac,providedIn:"root"}),S})()},2149:(v,T,i)=>{"use strict";i.d(T,{t:()=>N});var r=i(12057),u=i(24751),p=i(6283),d=i(38549),e=i(84051),_=i(37496),y=i(15626),S=i(85953),A=i(74788);let N=(()=>{class L{}return L.\u0275fac=function(J){return new(J||L)},L.\u0275mod=A.oAB({type:L}),L.\u0275inj=A.cJS({imports:[[r.ez,e.xD,_.b,u.u5,d.XC,d.HK,S.D,y.K,p.Bz],e.xD]}),L})()},94928:(v,T,i)=>{"use strict";i.d(T,{K:()=>ue});var r=i(23815),u=i.n(r),p=i(65862),d=i(74788),e=i(12057),_=i(6283),y=i(38549);const S=function(ae){return{disabled:ae}},A=function(ae){return[ae]};function N(ae,H){if(1&ae){const se=d.EpF();d.ynx(0),d.TgZ(1,"button",3),d.NdJ("click",function(){d.CHM(se);const ie=d.oxw();return ie.useClickAction(ie.currentAction)}),d._UZ(2,"i",4),d.TgZ(3,"span"),d._uU(4),d.qZA(),d.qZA(),d.BQk()}if(2&ae){const se=d.oxw();d.xp6(1),d.Gre("btn btn-",se.btnColor,""),d.s9C("title",se.useDisableDesc(se.currentAction)),d.Q6J("ngClass",d.VKq(10,S,se.disableSelectionAction(se.currentAction)))("routerLink",se.useRouterLink(se.currentAction))("preserveFragment",se.currentAction.preserveFragment?"":null),d.uIk("aria-label",se.currentAction.name),d.xp6(1),d.Q6J("ngClass",d.VKq(12,A,se.currentAction.icon)),d.xp6(2),d.Oqu(se.currentAction.name)}}function L(ae,H){if(1&ae&&(d.ynx(0),d._uU(1),d.BQk()),2&ae){const se=d.oxw(2);d.xp6(1),d.hij("",se.dropDownOnly," ")}}function Z(ae,H){1&ae&&d._UZ(0,"span",10)}const J=function(ae){return[ae,"action-icon"]};function K(ae,H){if(1&ae){const se=d.EpF();d.ynx(0),d.TgZ(1,"button",11),d.NdJ("click",function(){const he=d.CHM(se).$implicit;return d.oxw(2).useClickAction(he)}),d._UZ(2,"i",4),d.TgZ(3,"span"),d._uU(4),d.qZA(),d.qZA(),d.BQk()}if(2&ae){const se=H.$implicit,Ee=d.oxw(2);d.xp6(1),d.Tol(Ee.toClassName(se)),d.s9C("title",Ee.useDisableDesc(se)),d.Q6J("routerLink",Ee.useRouterLink(se))("preserveFragment",se.preserveFragment?"":null)("disabled",Ee.disableSelectionAction(se)),d.uIk("aria-label",se.name),d.xp6(1),d.Q6J("ngClass",d.VKq(10,J,se.icon)),d.xp6(2),d.Oqu(se.name)}}function ee(ae,H){if(1&ae&&(d.TgZ(0,"div",5),d.TgZ(1,"button",6),d.YNc(2,L,2,1,"ng-container",1),d.YNc(3,Z,1,0,"span",7),d.qZA(),d.TgZ(4,"div",8),d.YNc(5,K,5,12,"ng-container",9),d.qZA(),d.qZA()),2&ae){const se=d.oxw();d.xp6(1),d.Gre("btn btn-",se.btnColor," dropdown-toggle-split"),d.xp6(1),d.Q6J("ngIf",se.dropDownOnly),d.xp6(1),d.Q6J("ngIf",!se.dropDownOnly),d.xp6(2),d.Q6J("ngForOf",se.dropDownActions)}}let ue=(()=>{class ae{constructor(){this.btnColor="accent",this.dropDownActions=[],this.icons=p.P}ngOnInit(){this.removeActionsWithNoPermissions(),this.onSelectionChange()}ngOnChanges(se){se.selection&&this.onSelectionChange()}onSelectionChange(){this.updateDropDownActions(),this.updateCurrentAction()}toClassName(se){return se.name.replace(/ /g,"-").replace(/[^a-z-]/gi,"").toLowerCase()}removeActionsWithNoPermissions(){if(!this.permission)return void(this.tableActions=[]);const se=Object.keys(this.permission).filter(Ee=>this.permission[Ee]);this.tableActions=this.tableActions.filter(Ee=>se.includes(Ee.permission))}updateDropDownActions(){this.dropDownActions=this.tableActions.filter(se=>se.visible?se.visible(this.selection):se)}updateCurrentAction(){if(this.dropDownOnly)return void(this.currentAction=void 0);let se=this.dropDownActions.find(Ee=>this.showableAction(Ee));!se&&this.dropDownActions.length>0&&(se=this.dropDownActions[0]),this.currentAction=se}showableAction(se){const Ee=se.canBePrimary,ie=this.selection.hasSingleSelection,he="create"===se.permission?!ie:ie;return Ee&&Ee(this.selection)||!Ee&&he}useRouterLink(se){if(se.routerLink&&!this.disableSelectionAction(se))return u().isString(se.routerLink)?se.routerLink:se.routerLink()}disableSelectionAction(se){const Ee=se.disable;if(Ee)return Boolean(Ee(this.selection));const ie=se.permission,he=this.selection.hasSingleSelection&&this.selection.first();return Boolean(["update","delete"].includes(ie)&&(!he||he.cdExecuting))}useClickAction(se){return!this.disableSelectionAction(se)&&se.click&&se.click()}useDisableDesc(se){if(se.disable){const Ee=se.disable(this.selection);return u().isString(Ee)?Ee:void 0}}}return ae.\u0275fac=function(se){return new(se||ae)},ae.\u0275cmp=d.Xpm({type:ae,selectors:[["cd-table-actions"]],inputs:{permission:"permission",selection:"selection",tableActions:"tableActions",btnColor:"btnColor",dropDownOnly:"dropDownOnly"},features:[d.TTD],decls:3,vars:2,consts:[[1,"btn-group"],[4,"ngIf"],["class","btn-group","ngbDropdown","","role","group","aria-label","Button group with nested dropdown",4,"ngIf"],["type","button",3,"title","ngClass","routerLink","preserveFragment","click"],[3,"ngClass"],["ngbDropdown","","role","group","aria-label","Button group with nested dropdown",1,"btn-group"],["ngbDropdownToggle",""],["class","sr-only",4,"ngIf"],["ngbDropdownMenu","",1,"dropdown-menu"],[4,"ngFor","ngForOf"],[1,"sr-only"],["ngbDropdownItem","",3,"title","routerLink","preserveFragment","disabled","click"]],template:function(se,Ee){1&se&&(d.TgZ(0,"div",0),d.YNc(1,N,5,14,"ng-container",1),d.YNc(2,ee,6,6,"div",2),d.qZA()),2&se&&(d.xp6(1),d.Q6J("ngIf",Ee.currentAction),d.xp6(1),d.Q6J("ngIf",Ee.dropDownActions.length>1))},directives:[e.O5,e.mk,_.rH,y.jt,y.iD,y.Vi,e.sg,y.TH],styles:["button.disabled[_ngcontent-%COMP%]{cursor:default!important;pointer-events:auto}.action-icon[_ngcontent-%COMP%]{padding-right:1.5rem}"]}),ae})()},61350:(v,T,i)=>{"use strict";i.d(T,{b:()=>y});var r=i(74788),u=i(23815),p=i.n(u),d=i(99466),e=i(35905),_=i(96102);let y=(()=>{class S{constructor(N){this.datePipe=N,this.autoReload=5e3,this.renderObjects=!1,this.appendParentKey=!0,this.hideEmpty=!1,this.hideKeys=[],this.columns=[],this.fetchData=new r.vpe}ngOnInit(){this.columns=[{prop:"key",flexGrow:1,cellTransformation:d.e.bold},{prop:"value",flexGrow:3}],this.customCss&&(this.columns[1].cellTransformation=d.e.classAdding),this.fetchData.observers.length>0&&this.table.fetchData.subscribe(()=>{this.fetchData.emit()}),this.useData()}ngOnChanges(){this.useData()}useData(){if(!this.data)return;let N=this.makePairs(this.data);this.hideKeys&&(N=N.filter(L=>!this.hideKeys.includes(L.key))),this.tableData=N}makePairs(N){let L=[];if(N){if(p().isArray(N))L=this.makePairsFromArray(N);else{if(!p().isObject(N))throw new Error("Wrong data format");L=this.makePairsFromObject(N)}return L=L.map(Z=>(Z.value=this.convertValue(Z.value),Z)).filter(Z=>null!==Z.value),p().sortBy(this.renderObjects?this.insertFlattenObjects(L):L,"key")}}makePairsFromArray(N){let L=[];const Z=N[0];if(p().isArray(Z)){if(2!==Z.length)throw new Error(`Array contains too many elements (${Z.length}). Needs to be of type [string, any][]`);L=N.map(J=>({key:J[0],value:J[1]}))}else p().isObject(Z)&&(L=p().has(Z,"key")&&p().has(Z,"value")?[...N]:N.reduce((J,K)=>J.concat(this.makePairsFromObject(K)),L));return L}makePairsFromObject(N){return Object.keys(N).map(L=>({key:L,value:N[L]}))}insertFlattenObjects(N){return p().flattenDeep(N.map(L=>{const Z=L.value,J=p().isObject(Z);return!J||p().isEmpty(Z)?(J&&(L.value=""),L):this.splitItemIntoItems(L)}))}splitItemIntoItems(N){return this.makePairs(N.value).map(L=>(this.appendParentKey&&(L.key=N.key+" "+L.key),L))}convertValue(N){if(p().isArray(N)){if(p().isEmpty(N)&&this.hideEmpty)return null;N=N.map(L=>p().isObject(L)?JSON.stringify(L):L).join(", ")}else if(p().isObject(N)){if(this.hideEmpty&&p().isEmpty(N)||!this.renderObjects)return null}else if(p().isString(N)){if(""===N&&this.hideEmpty)return null;this.isDate(N)&&(N=this.datePipe.transform(N)||N)}return N}isDate(N){const L="[ -:.TZ]",Z="\\d{2}"+L;return N.match(new RegExp("^\\d{4}"+L+Z+Z+Z+Z+Z+"\\d*Z?$"))}}return S.\u0275fac=function(N){return new(N||S)(r.Y36(_.N))},S.\u0275cmp=r.Xpm({type:S,selectors:[["cd-table-key-value"]],viewQuery:function(N,L){if(1&N&&r.Gf(e.a,7),2&N){let Z;r.iGM(Z=r.CRH())&&(L.table=Z.first)}},inputs:{data:"data",autoReload:"autoReload",renderObjects:"renderObjects",appendParentKey:"appendParentKey",hideEmpty:"hideEmpty",hideKeys:"hideKeys",customCss:"customCss"},outputs:{fetchData:"fetchData"},features:[r.TTD],decls:2,vars:9,consts:[["columnMode","flex",3,"data","columns","toolHeader","autoReload","customCss","autoSave","header","footer","limit"],["table",""]],template:function(N,L){1&N&&r._UZ(0,"cd-table",0,1),2&N&&r.Q6J("data",L.tableData)("columns",L.columns)("toolHeader",!1)("autoReload",L.autoReload)("customCss",L.customCss)("autoSave",!1)("header",!1)("footer",!1)("limit",0)},directives:[e.a],styles:[""]}),S})()},35905:(v,T,i)=>{"use strict";i.d(T,{a:()=>mr});var r=i(74788),u=i(84051),p=i(23815),d=i.n(p),e=i(25917),_=i(18891),y=i(71225),S=i(99466),A=i(65862),N=i(86919),L=i(68774),Z=i(46947),J=i(12057),K=i(38549),ee=i(24751),ue=i(76446),ae=i(6283),H=i(70442),se=i(66369),Ee=i(37496),ie=i(47187),he=i(78877),ge=i(52821);const De=["tableCellBoldTpl"],ce=["sparklineTpl"],lt=["routerLinkTpl"],Ve=["checkIconTpl"],ze=["perSecondTpl"],Be=["executingTpl"],Pe=["classAddingTpl"],je=["badgeTpl"],He=["mapTpl"],Vt=["truncateTpl"],it=["rowDetailsTpl"];function tn(Dn,Pr){1&Dn&&(r.TgZ(0,"div",20),r.TgZ(1,"div",21),r.Hsn(2),r.qZA(),r.qZA())}function It(Dn,Pr){if(1&Dn){const Yt=r.EpF();r.ynx(0),r.TgZ(1,"button",36),r.NdJ("click",function(){const kr=r.CHM(Yt).$implicit;return r.oxw(3).onSelectFilter(kr),!1}),r._uU(2),r.qZA(),r.BQk()}if(2&Dn){const Yt=Pr.$implicit;r.xp6(2),r.Oqu(Yt.column.name)}}const Zt=function(Dn){return[Dn]};function Ut(Dn,Pr){if(1&Dn&&r._UZ(0,"i",28),2&Dn){const Yt=r.oxw(4);r.Q6J("ngClass",r.VKq(1,Zt,Yt.icons.check))}}function Bt(Dn,Pr){if(1&Dn){const Yt=r.EpF();r.ynx(0),r.TgZ(1,"button",36),r.NdJ("click",function(){const kr=r.CHM(Yt).$implicit,mi=r.oxw(3);return mi.onChangeFilter(mi.selectedFilter,kr),!1}),r._uU(2),r.YNc(3,Ut,1,3,"i",37),r.qZA(),r.BQk()}if(2&Dn){const Yt=Pr.$implicit,_n=r.oxw(3);r.xp6(2),r.hij(" ",Yt.formatted," "),r.xp6(1),r.Q6J("ngIf",void 0!==_n.selectedFilter.value&&_n.selectedFilter.value.raw===Yt.raw)}}const bt=function(Dn,Pr){return[Dn,Pr]};function Gt(Dn,Pr){if(1&Dn&&(r.TgZ(0,"div",32),r.TgZ(1,"div",33),r.TgZ(2,"button",34),r._UZ(3,"i",28),r._uU(4),r.qZA(),r.TgZ(5,"div",29),r.YNc(6,It,3,1,"ng-container",30),r.qZA(),r.qZA(),r.TgZ(7,"div",35),r.TgZ(8,"button",34),r._uU(9),r.qZA(),r.TgZ(10,"div",29),r.YNc(11,Bt,4,2,"ng-container",30),r.qZA(),r.qZA(),r.qZA()),2&Dn){const Yt=r.oxw(2);r.xp6(3),r.Q6J("ngClass",r.WLB(7,bt,Yt.icons.large,Yt.icons.filter)),r.xp6(1),r.hij(" ",Yt.selectedFilter.column.name," "),r.xp6(2),r.Q6J("ngForOf",Yt.columnFilters),r.xp6(2),r.ekj("disabled",0===Yt.selectedFilter.options.length),r.xp6(1),r.hij(" ",Yt.selectedFilter.value?Yt.selectedFilter.value.formatted:"Any"," "),r.xp6(2),r.Q6J("ngForOf",Yt.selectedFilter.options)}}function xt(Dn,Pr){if(1&Dn){const Yt=r.EpF();r.TgZ(0,"div",38),r.TgZ(1,"span",39),r.TgZ(2,"span",40),r._UZ(3,"i",28),r.qZA(),r.qZA(),r.TgZ(4,"input",41),r.NdJ("ngModelChange",function(Ge){return r.CHM(Yt),r.oxw(2).search=Ge})("keyup",function(){return r.CHM(Yt),r.oxw(2).updateFilter()}),r.qZA(),r.TgZ(5,"div",42),r.TgZ(6,"button",43),r.NdJ("click",function(){return r.CHM(Yt),r.oxw(2).onClearSearch()}),r._UZ(7,"i"),r.qZA(),r.qZA(),r.qZA()}if(2&Dn){const Yt=r.oxw(2);r.xp6(3),r.Q6J("ngClass",r.VKq(5,Zt,Yt.icons.search)),r.xp6(1),r.Q6J("ngModel",Yt.search),r.xp6(3),r.Gre("icon-prepend ",Yt.icons.destroy,"")}}function Xt(Dn,Pr){if(1&Dn){const Yt=r.EpF();r.TgZ(0,"div",44),r.TgZ(1,"input",45),r.NdJ("click",function(Ge){return r.CHM(Yt),r.oxw(2).setLimit(Ge)})("keyup",function(Ge){return r.CHM(Yt),r.oxw(2).setLimit(Ge)})("blur",function(Ge){return r.CHM(Yt),r.oxw(2).setLimit(Ge)}),r.qZA(),r.qZA()}if(2&Dn){const Yt=r.oxw(2);r.xp6(1),r.Q6J("value",Yt.userConfig.limit)}}function Zn(Dn,Pr){if(1&Dn){const Yt=r.EpF();r.TgZ(0,"button",36),r.NdJ("click",function(){r.CHM(Yt);const Ge=r.oxw().$implicit;return r.oxw(2).toggleColumn(Ge),!1}),r.TgZ(1,"div",47),r._UZ(2,"input",48),r.TgZ(3,"label",49),r._uU(4),r.qZA(),r.qZA(),r.qZA()}if(2&Dn){const Yt=r.oxw().$implicit;r.xp6(2),r.Q6J("name",Yt.prop)("id",Yt.prop)("checked",!Yt.isHidden),r.xp6(1),r.Q6J("for",Yt.prop),r.xp6(1),r.Oqu(Yt.name)}}function Ur(Dn,Pr){if(1&Dn&&(r.ynx(0),r.YNc(1,Zn,5,5,"button",46),r.BQk()),2&Dn){const Yt=Pr.$implicit;r.xp6(1),r.Q6J("ngIf",""!==Yt.name)}}function di(Dn,Pr){if(1&Dn){const Yt=r.EpF();r.TgZ(0,"div",50),r.TgZ(1,"button",51),r.NdJ("click",function(){return r.CHM(Yt),r.oxw(2).refreshBtn()}),r._UZ(2,"i",28),r.qZA(),r.qZA()}if(2&Dn){const Yt=r.oxw(2);r.xp6(1),r.Tol("btn btn-"+Yt.status.type),r.Q6J("ngbTooltip",Yt.status.msg),r.xp6(1),r.ekj("fa-spin",Yt.updating||Yt.loadingIndicator),r.Q6J("ngClass",r.WLB(6,bt,Yt.icons.large,Yt.icons.refresh))}}function Lr(Dn,Pr){if(1&Dn&&(r.TgZ(0,"div",20),r.TgZ(1,"div",21),r.Hsn(2,1),r.qZA(),r.YNc(3,Gt,12,10,"div",22),r.YNc(4,xt,8,7,"div",23),r.YNc(5,Xt,2,1,"div",24),r.TgZ(6,"div",25),r.TgZ(7,"div",26),r.TgZ(8,"button",27),r._UZ(9,"i",28),r.qZA(),r.TgZ(10,"div",29),r.YNc(11,Ur,2,1,"ng-container",30),r.qZA(),r.qZA(),r.qZA(),r.YNc(12,di,3,9,"div",31),r.qZA()),2&Dn){const Yt=r.oxw();r.xp6(3),r.Q6J("ngIf",0!==Yt.columnFilters.length),r.xp6(1),r.Q6J("ngIf",Yt.searchField),r.xp6(1),r.Q6J("ngIf",Yt.limit),r.xp6(4),r.Q6J("ngClass",r.WLB(6,bt,Yt.icons.large,Yt.icons.table)),r.xp6(2),r.Q6J("ngForOf",Yt.columns),r.xp6(1),r.Q6J("ngIf",Yt.fetchData.observers.length>0)}}function Mr(Dn,Pr){if(1&Dn){const Yt=r.EpF();r.TgZ(0,"span",56),r.TgZ(1,"span",57),r._uU(2),r.qZA(),r.TgZ(3,"a",58),r.NdJ("click",function(){r.CHM(Yt);const Ge=r.oxw().$implicit;return r.oxw(2).onChangeFilter(Ge),!1}),r._UZ(4,"i",59),r.qZA(),r.qZA()}if(2&Dn){const Yt=r.oxw().$implicit,_n=r.oxw(2);r.xp6(2),r.AsE("",Yt.column.name,": ",Yt.value.formatted,""),r.xp6(2),r.Q6J("ngClass",r.VKq(3,Zt,_n.icons.destroy))}}function Kr(Dn,Pr){if(1&Dn&&(r.TgZ(0,"span"),r.YNc(1,Mr,5,5,"span",55),r.qZA()),2&Dn){const Yt=Pr.$implicit;r.xp6(1),r.Q6J("ngIf",Yt.value)}}function ei(Dn,Pr){if(1&Dn){const Yt=r.EpF();r.TgZ(0,"div",20),r.TgZ(1,"div",52),r.YNc(2,Kr,2,1,"span",30),r.TgZ(3,"a",53),r.NdJ("click",function(){return r.CHM(Yt),r.oxw().onClearFilters(),!1}),r.ynx(4),r.SDv(5,54),r.BQk(),r.qZA(),r.qZA(),r.qZA()}if(2&Dn){const Yt=r.oxw();r.xp6(2),r.Q6J("ngForOf",Yt.columnFilters)}}function Nn(Dn,Pr){1&Dn&&r.Hsn(0,2)}function $n(Dn,Pr){if(1&Dn&&(r.TgZ(0,"span"),r._uU(1),r.ynx(2),r.SDv(3,65),r.BQk(),r._uU(4," / "),r.qZA()),2&Dn){const Yt=r.oxw().selectedCount;r.xp6(1),r.hij(" ",Yt," ")}}function Br(Dn,Pr){if(1&Dn&&(r.TgZ(0,"span"),r._uU(1),r.ynx(2),r.SDv(3,67),r.BQk(),r._uU(4," / "),r.qZA()),2&Dn){const Yt=r.oxw(2).rowCount;r.xp6(1),r.hij(" ",Yt," ")}}function Yr(Dn,Pr){if(1&Dn&&(r.TgZ(0,"span"),r.YNc(1,Br,5,1,"span",61),r._uU(2),r.ynx(3),r.SDv(4,66),r.BQk(),r.qZA()),2&Dn){const Yt=r.oxw().rowCount,_n=r.oxw();r.xp6(1),r.Q6J("ngIf",Yt!=(null==_n.data?null:_n.data.length)),r.xp6(1),r.hij(" ",(null==_n.data?null:_n.data.length)||0," ")}}function fi(Dn,Pr){if(1&Dn&&(r._uU(0),r.ynx(1),r.SDv(2,68),r.BQk(),r._uU(3),r.ynx(4),r.SDv(5,69),r.BQk()),2&Dn){const Yt=r.oxw().rowCount,_n=r.oxw();r.hij(" ",(null==_n.data?null:_n.data.length)||0," "),r.xp6(3),r.hij(" / ",Yt," ")}}function ki(Dn,Pr){if(1&Dn){const Yt=r.EpF();r.TgZ(0,"div",60),r.YNc(1,$n,5,1,"span",61),r.YNc(2,Yr,5,2,"span",62),r.YNc(3,fi,6,2,"ng-template",null,63,r.W1O),r.qZA(),r.TgZ(5,"datatable-pager",64),r.NdJ("change",function(Ge){return r.CHM(Yt),r.oxw(),r.MAs(5).onFooterPage(Ge)}),r.qZA()}if(2&Dn){const Yt=Pr.rowCount,_n=Pr.pageSize,Ge=Pr.curPage,kr=r.MAs(4),mi=r.oxw();r.xp6(1),r.Q6J("ngIf",mi.selectionType),r.xp6(1),r.Q6J("ngIf",!mi.serverSide)("ngIfElse",kr),r.xp6(3),r.Q6J("pagerLeftArrowIcon",mi.paginationClasses.pagerPrevious)("pagerRightArrowIcon",mi.paginationClasses.pagerNext)("pagerPreviousIcon",mi.paginationClasses.pagerLeftArrow)("pagerNextIcon",mi.paginationClasses.pagerRightArrow)("page",Ge)("size",_n)("count",Yt)("hidden",!(Yt/_n>1))}}function Hi(Dn,Pr){if(1&Dn&&(r.TgZ(0,"strong"),r._uU(1),r.qZA()),2&Dn){const Yt=Pr.value;r.xp6(1),r.Oqu(Yt)}}function Zr(Dn,Pr){if(1&Dn&&r._UZ(0,"cd-sparkline",70),2&Dn){const Yt=Pr.row;r.Q6J("data",Pr.value)("isBinary",Yt.cdIsBinary)}}function Cn(Dn,Pr){if(1&Dn&&(r.TgZ(0,"a",71),r._uU(1),r.qZA()),2&Dn){const Yt=Pr.row,_n=Pr.value;r.Q6J("routerLink",r.VKq(3,Zt,Yt.cdLink))("queryParams",Yt.cdParams),r.xp6(1),r.Oqu(_n)}}function Wt(Dn,Pr){if(1&Dn&&(r._UZ(0,"i",72),r.ALo(1,"boolean")),2&Dn){const Yt=Pr.value,_n=r.oxw();r.Q6J("ngClass",r.VKq(4,Zt,_n.icons.check))("hidden",!r.lcZ(1,2,Yt))}}function zn(Dn,Pr){1&Dn&&(r._uU(0),r.ALo(1,"dimless")),2&Dn&&r.hij(" ",r.lcZ(1,1,Pr.value)," /s\n")}function rr(Dn,Pr){if(1&Dn&&r._UZ(0,"i",28),2&Dn){const Yt=r.oxw(2);r.Q6J("ngClass",r.WLB(1,bt,Yt.icons.spinner,Yt.icons.spin))}}function Fr(Dn,Pr){if(1&Dn&&(r.TgZ(0,"span",28),r._uU(1),r.qZA()),2&Dn){const Yt=r.oxw(),_n=Yt.column,Ge=Yt.row;r.Q6J("ngClass",null!=_n&&null!=_n.customTemplateConfig&&_n.customTemplateConfig.executingClass?_n.customTemplateConfig.executingClass:"text-muted italic"),r.xp6(1),r.hij("(",Ge.cdExecuting,")")}}function Gn(Dn,Pr){if(1&Dn&&(r.YNc(0,rr,1,4,"i",37),r.TgZ(1,"span",28),r._uU(2),r.qZA(),r.YNc(3,Fr,2,2,"span",37)),2&Dn){const Yt=Pr.column,_n=Pr.row,Ge=Pr.value;r.Q6J("ngIf",_n.cdExecuting),r.xp6(1),r.Q6J("ngClass",null==Yt||null==Yt.customTemplateConfig?null:Yt.customTemplateConfig.valueClass),r.xp6(1),r.hij(" ",Ge," "),r.xp6(1),r.Q6J("ngIf",_n.cdExecuting)}}function Jr(Dn,Pr){if(1&Dn&&(r.TgZ(0,"span"),r.ALo(1,"pipeFunction"),r._uU(2),r.qZA()),2&Dn){const Yt=Pr.value,_n=r.oxw();r.Tol(r.Dn7(1,4,Yt,_n.useCustomClass,_n)),r.xp6(2),r.Oqu(Yt)}}function _i(Dn,Pr){if(1&Dn&&(r.TgZ(0,"span",74),r._uU(1),r.qZA()),2&Dn){const Yt=r.oxw().$implicit,_n=r.oxw().column;r.Q6J("ngClass",null!=_n&&null!=_n.customTemplateConfig&&_n.customTemplateConfig.map&&null!=_n&&null!=_n.customTemplateConfig&&null!=_n.customTemplateConfig.map[Yt]&&_n.customTemplateConfig.map[Yt].class?_n.customTemplateConfig.map[Yt].class:null!=_n&&null!=_n.customTemplateConfig&&_n.customTemplateConfig.class?_n.customTemplateConfig.class:"badge-primary"),r.xp6(1),r.hij(" ",null!=_n&&null!=_n.customTemplateConfig&&_n.customTemplateConfig.map&&null!=_n&&null!=_n.customTemplateConfig&&null!=_n.customTemplateConfig.map[Yt]&&_n.customTemplateConfig.map[Yt].value?_n.customTemplateConfig.map[Yt].value:null!=_n&&null!=_n.customTemplateConfig&&_n.customTemplateConfig.prefix?_n.customTemplateConfig.prefix+Yt:Yt," ")}}function wi(Dn,Pr){1&Dn&&(r.TgZ(0,"span"),r._uU(1,"\xa0"),r.qZA())}function br(Dn,Pr){if(1&Dn&&(r.TgZ(0,"span"),r.YNc(1,_i,2,2,"span",73),r.YNc(2,wi,2,0,"span",61),r.qZA()),2&Dn){const Yt=Pr.$implicit,_n=Pr.last,Ge=r.oxw().column;r.xp6(1),r.Q6J("ngIf",null!=Ge&&null!=Ge.customTemplateConfig&&Ge.customTemplateConfig.map&&null!=Ge&&null!=Ge.customTemplateConfig&&null!=Ge.customTemplateConfig.map[Yt]&&Ge.customTemplateConfig.map[Yt].value?Ge.customTemplateConfig.map[Yt].value:null!=Ge&&null!=Ge.customTemplateConfig&&Ge.customTemplateConfig.prefix?Ge.customTemplateConfig.prefix+Yt:Yt),r.xp6(1),r.Q6J("ngIf",!_n)}}function Dr(Dn,Pr){1&Dn&&(r.YNc(0,br,3,2,"span",30),r.ALo(1,"array")),2&Dn&&r.Q6J("ngForOf",r.lcZ(1,1,Pr.value))}function gn(Dn,Pr){if(1&Dn&&(r.TgZ(0,"span"),r._uU(1),r.ALo(2,"map"),r.qZA()),2&Dn){const Yt=Pr.column,_n=Pr.value;r.xp6(1),r.Oqu(r.xi3(2,1,_n,null==Yt?null:Yt.customTemplateConfig))}}function yn(Dn,Pr){if(1&Dn&&(r.TgZ(0,"span",75),r._uU(1),r.ALo(2,"truncate"),r.qZA()),2&Dn){const Yt=Pr.column,_n=Pr.value;r.Q6J("title",_n),r.xp6(1),r.Oqu(r.Dn7(2,2,_n,null==Yt||null==Yt.customTemplateConfig?null:Yt.customTemplateConfig.length,null==Yt||null==Yt.customTemplateConfig?null:Yt.customTemplateConfig.omission))}}function gr(Dn,Pr){if(1&Dn){const Yt=r.EpF();r.TgZ(0,"a",76),r.NdJ("click",function(Ge){const kr=r.CHM(Yt),mi=kr.row,An=kr.expanded;return r.oxw().toggleExpandRow(mi,An,Ge)}),r.qZA()}if(2&Dn){const Yt=Pr.expanded;r.ekj("expand-collapse-icon-right",!Yt)("expand-collapse-icon-down",Yt)}}const Jt=[[["",8,"only-table-actions"]],[["",8,"table-actions"]],[["","cdTableDetail",""]]],Vn=[".only-table-actions",".table-actions","[cdTableDetail]"];let mr=(()=>{class Dn{constructor(Yt,_n){this.cdRef=Yt,this.timerService=_n,this.columnMode="flex",this.onlyActionHeader=!1,this.toolHeader=!0,this.searchField=!0,this.header=!0,this.footer=!0,this.limit=10,this.maxLimit=9999,this.hasDetails=!1,this.autoReload=5e3,this.identifier="id",this.forceIdentifier=!1,this.selectionType=void 0,this.updateSelectionOnRefresh="onChange",this.updateExpandedOnRefresh="onChange",this.autoSave=!0,this.searchableObjects=!1,this.extraFilterableColumns=[],this.status=new y.c,this.serverSide=!1,this.count=0,this.fetchData=new r.vpe,this.updateSelection=new r.vpe,this.setExpandedRow=new r.vpe,this.columnFiltersChanged=new r.vpe,this.selection=new L.r,this.expanded=void 0,this.icons=A.P,this.cellTemplates={},this.search="",this.rows=[],this.loadingIndicator=!0,this.paginationClasses={pagerLeftArrow:A.P.leftArrowDouble,pagerRightArrow:A.P.rightArrowDouble,pagerPrevious:A.P.leftArrow,pagerNext:A.P.rightArrow},this.userConfig={},this.localStorage=window.localStorage,this.updating=!1,this.columnFilters=[]}get columnFiltered(){return d().some(this.columnFilters,Yt=>void 0!==Yt.value)}static prepareSearch(Yt){return(Yt=Yt.toLowerCase().replace(/,/g,"")).match(/['"][^'"]+['"]/)&&(Yt=Yt.replace(/['"][^'"]+['"]/g,_n=>_n.replace(/(['"])([^'"]+)(['"])/g,"$2").replace(/ /g,"+"))),Yt.split(" ").filter(_n=>_n)}ngOnInit(){if(this.localColumns=d().clone(this.columns),this.serverSide&&(this.reloadData=d().debounce(this.reloadData,1e3)),this.table.element.addEventListener("mouseenter",Yt=>Yt.stopPropagation()),this._addTemplates(),!this.sorts){const Yt=-1!==d().findIndex(this.localColumns,["prop",this.identifier]);this.sorts=this.createSortingDefinition(Yt?this.identifier:this.localColumns[0].prop+""),!Yt&&!this.forceIdentifier&&(this.identifier=this.localColumns[0].prop+"")}this.initUserConfig(),this.localColumns.forEach(Yt=>{Yt.cellTransformation&&(Yt.cellTemplate=this.cellTemplates[Yt.cellTransformation]),Yt.flexGrow||(Yt.flexGrow=Yt.prop+""===this.identifier?1:2),Yt.resizeable||(Yt.resizeable=!1)}),this.initExpandCollapseColumn(),this.initCheckboxColumn(),this.filterHiddenColumns(),this.initColumnFilters(),this.updateColumnFilterOptions(),this.updateSelection.emit(new L.r),this.fetchData.observers.length>0&&(this.loadingIndicator=!0),d().isInteger(this.autoReload)&&this.autoReload>0?this.reloadSubscriber=this.timerService.get(()=>(0,e.of)(0),this.autoReload).subscribe(()=>{this.reloadData()}):this.autoReload?this.useData():this.reloadData(),"single"===this.selectionType&&(this.table.selectCheck=this.singleSelectCheck.bind(this))}initUserConfig(){this.autoSave&&(this.tableName=this._calculateUniqueTableName(this.localColumns),this._loadUserConfig(),this._initUserConfigAutoSave()),this.userConfig.limit||(this.userConfig.limit=this.limit),this.userConfig.offset>=0||(this.userConfig.offset=this.table.offset),this.userConfig.search||(this.userConfig.search=this.search),this.userConfig.sorts||(this.userConfig.sorts=this.sorts),this.userConfig.columns?this.userConfig.columns.forEach(Yt=>{for(let _n=0;_n<this.localColumns.length;_n++)this.localColumns[_n].prop===Yt.prop&&(this.localColumns[_n].isHidden=Yt.isHidden)}):this.updateUserColumns()}_calculateUniqueTableName(Yt){const _n=Ge=>{if(!d().isString(Ge))return 0;let kr=0;for(let mi=0;mi<Ge.length;mi++)kr+=Ge.charCodeAt(mi)*mi;return kr};return Yt.reduce((Ge,kr,mi)=>(_n(kr.prop)+_n(kr.name))*(mi+1)+Ge,0).toString()}_loadUserConfig(){const Yt=this.localStorage.getItem(this.tableName);Yt&&(this.userConfig=JSON.parse(Yt))}_initUserConfigAutoSave(){const Yt=new _.y(this._initUserConfigProxy.bind(this));this.saveSubscriber=Yt.subscribe(this._saveUserConfig.bind(this))}_initUserConfigProxy(Yt){this.userConfig=new Proxy(this.userConfig,{set:(_n,Ge,kr)=>(_n[Ge]=kr,Yt.next(_n),!0)})}_saveUserConfig(Yt){this.localStorage.setItem(this.tableName,JSON.stringify(Yt))}updateUserColumns(){this.userConfig.columns=this.localColumns.map(Yt=>({prop:Yt.prop,name:Yt.name,isHidden:!!Yt.isHidden}))}initCheckboxColumn(){"multiClick"===this.selectionType&&this.localColumns.unshift({prop:void 0,resizeable:!1,sortable:!1,draggable:!1,checkboxable:!0,canAutoResize:!1,cellClass:"cd-datatable-checkbox",width:30})}initExpandCollapseColumn(){this.hasDetails&&this.localColumns.unshift({prop:void 0,resizeable:!1,sortable:!1,draggable:!1,isHidden:!1,canAutoResize:!1,cellClass:"cd-datatable-expand-collapse",width:40,cellTemplate:this.rowDetailsTpl})}filterHiddenColumns(){this.tableColumns=this.localColumns.filter(Yt=>!Yt.isHidden)}initColumnFilters(){let Yt=d().filter(this.localColumns,{filterable:!0});Yt=[...Yt,...this.extraFilterableColumns],this.columnFilters=Yt.map(_n=>({column:_n,options:[],value:_n.filterInitValue?this.createColumnFilterOption(_n.filterInitValue,_n.pipe):void 0})),this.selectedFilter=d().first(this.columnFilters)}createColumnFilterOption(Yt,_n){return{raw:d().toString(Yt),formatted:_n?_n.transform(Yt):d().toString(Yt)}}updateColumnFilterOptions(){this.columnFilters.forEach(Yt=>{let _n=[];if(d().isUndefined(Yt.column.filterOptions)){const kr=d().filter(d().map(this.data,Yt.column.prop),mi=>d().isString(mi)&&""!==mi||d().isBoolean(mi)||d().isFinite(mi)||d().isDate(mi));_n=d().sortedUniq(kr.sort())}else _n=Yt.column.filterOptions;const Ge=_n.map(kr=>this.createColumnFilterOption(kr,Yt.column.pipe));Yt.value&&d().isUndefined(d().find(Ge,{raw:Yt.value.raw}))&&(Yt.value=void 0),Yt.options=Ge})}onSelectFilter(Yt){this.selectedFilter=Yt}onChangeFilter(Yt,_n){Yt.value=d().isEqual(Yt.value,_n)?void 0:_n,this.updateFilter()}doColumnFiltering(){const Yt=[];let _n=[...this.data],Ge=[];return this.columnFilters.forEach(kr=>{if(void 0===kr.value)return;Yt.push({name:kr.column.name,prop:kr.column.prop,value:kr.value});const mi=d().partition(_n,An=>{const Wr=(0,u.Hg)(kr.column.prop)(An,kr.column.prop);return d().isUndefined(kr.column.filterPredicate)?`${Wr}`===kr.value.raw:kr.column.filterPredicate(An,kr.value.raw)});_n=mi[0],Ge=[...Ge,...mi[1]]}),this.columnFiltersChanged.emit({filters:Yt,data:_n,dataOut:Ge}),d().forEach(this.selection.selected,kr=>{void 0===d().find(_n,{[this.identifier]:kr[this.identifier]})&&(this.selection=new L.r,this.onSelect(this.selection))}),_n}ngOnDestroy(){this.reloadSubscriber&&this.reloadSubscriber.unsubscribe(),this.saveSubscriber&&this.saveSubscriber.unsubscribe()}ngAfterContentChecked(){this.table&&this.table.element.clientWidth!==this.currentWidth&&(this.currentWidth=this.table.element.clientWidth,this.table.recalculate(),d().get(this.table,"cd").markForCheck())}_addTemplates(){this.cellTemplates.bold=this.tableCellBoldTpl,this.cellTemplates.checkIcon=this.checkIconTpl,this.cellTemplates.sparkline=this.sparklineTpl,this.cellTemplates.routerLink=this.routerLinkTpl,this.cellTemplates.perSecond=this.perSecondTpl,this.cellTemplates.executing=this.executingTpl,this.cellTemplates.classAdding=this.classAddingTpl,this.cellTemplates.badge=this.badgeTpl,this.cellTemplates.map=this.mapTpl,this.cellTemplates.truncate=this.truncateTpl}useCustomClass(Yt){if(!this.customCss)throw new Error("Custom classes are not set!");const _n=Object.keys(this.customCss),Ge=Object.values(this.customCss).map((kr,mi)=>(d().isFunction(kr)&&kr(Yt)||kr===Yt)&&_n[mi]).filter(kr=>kr).join(" ");return d().isEmpty(Ge)?void 0:Ge}ngOnChanges(Yt){Yt.data&&Yt.data.currentValue&&this.useData()}setLimit(Yt){const _n=Number(Yt.target.value);_n>0&&(this.maxLimit&&_n>this.maxLimit?(this.userConfig.limit=this.maxLimit,Yt.srcElement.value=this.maxLimit):this.userConfig.limit=_n),this.serverSide&&this.reloadData()}reloadData(){var Yt;if(!this.updating){this.status=new y.c;const _n=new N.E(()=>{_n.errorConfig.displayError&&(this.status=new y.c("danger","Failed to load data.")),_n.errorConfig.resetData&&(this.data=[]),this.useData()});if(_n.pageInfo.offset=this.userConfig.offset,_n.pageInfo.limit=this.userConfig.limit,_n.search=this.userConfig.search,null===(Yt=this.userConfig.sorts)||void 0===Yt?void 0:Yt.length){const Ge=this.userConfig.sorts[0];_n.sort=`${"desc"===Ge.dir?"-":"+"}${Ge.prop}`}this.fetchData.emit(_n),this.updating=!0}}refreshBtn(){this.loadingIndicator=!0,this.reloadData()}changePage(Yt){this.userConfig.offset=Yt.offset,this.userConfig.limit=Yt.limit,this.serverSide&&this.reloadData()}rowIdentity(){return Yt=>{const _n=Yt[this.identifier];if(d().isUndefined(_n))throw new Error(`Wrong identifier "${this.identifier}" -> "${_n}"`);return _n}}useData(){!this.data||(this.updateColumnFilterOptions(),this.updateFilter(),this.reset(),this.updateSelected(),this.updateExpanded())}reset(){this.loadingIndicator=!1,this.updating=!1}updateSelected(){if("never"===this.updateSelectionOnRefresh)return;const Yt=new Set;this.selection.selected.forEach(Ge=>{for(const kr of this.data)Ge[this.identifier]===kr[this.identifier]&&Yt.add(kr)});const _n=Array.from(Yt.values());"onChange"===this.updateSelectionOnRefresh&&d().isEqual(this.selection.selected,_n)||(this.selection.selected=_n,this.onSelect(this.selection))}updateExpanded(){if(d().isUndefined(this.expanded)||"never"===this.updateExpandedOnRefresh)return;const Yt=this.expanded[this.identifier],_n=d().find(this.data,Ge=>Yt===Ge[this.identifier]);"onChange"===this.updateExpandedOnRefresh&&d().isEqual(this.expanded,_n)||(this.expanded=_n,this.setExpandedRow.emit(_n))}onSelect(Yt){d().has(Yt,"selected")&&(this.selection.selected=Yt.selected),this.updateSelection.emit(d().clone(this.selection))}singleSelectCheck(Yt){return-1===this.selection.selected.indexOf(Yt)}toggleColumn(Yt){const _n=Yt.prop,Ge=!Yt.isHidden;Ge&&1===this.tableColumns.length?Yt.isHidden=!0:(d().find(this.localColumns,kr=>kr.prop===_n).isHidden=Ge,this.updateColumns())}updateColumns(){this.updateUserColumns(),this.filterHiddenColumns();const Yt=this.userConfig.sorts[0].prop;d().find(this.tableColumns,_n=>_n.prop===Yt)||(this.userConfig.sorts=this.createSortingDefinition(this.tableColumns[0].prop)),this.table.recalculate(),this.cdRef.detectChanges()}createSortingDefinition(Yt){return[{prop:Yt,dir:u.Sr.asc}]}changeSorting({sorts:Yt}){this.userConfig.sorts=Yt,this.serverSide&&(this.userConfig.offset=0,this.reloadData())}onClearSearch(){this.search="",this.updateFilter()}onClearFilters(){this.columnFilters.forEach(Yt=>{Yt.value=void 0}),this.selectedFilter=d().first(this.columnFilters),this.updateFilter()}updateFilter(){if(this.serverSide)this.userConfig.search!==this.search&&(this.userConfig.offset=0,this.userConfig.limit=this.limit,this.userConfig.search=this.search,this.updating=!1,this.reloadData()),this.rows=this.data;else{let Yt=0!==this.columnFilters.length?this.doColumnFiltering():this.data;if(this.search.length>0&&Yt){const _n=this.localColumns.filter(Ge=>Ge.cellTransformation!==S.e.sparkline);Yt=this.subSearch(Yt,Dn.prepareSearch(this.search),_n),this.table.offset=0}this.rows=Yt}}subSearch(Yt,_n,Ge){if(0===_n.length||0===Yt.length)return Yt;const kr=_n.pop().replace(/\+/g," ").split(":"),mi=[...Ge];return 2===kr.length&&(Ge=mi.filter(An=>-1!==An.name.toLowerCase().indexOf(kr[0]))),Yt=this.basicDataSearch(d().last(kr),Yt,Ge),this.subSearch(Yt,_n,mi)}basicDataSearch(Yt,_n,Ge){return 0===Yt.length?_n:_n.filter(kr=>Ge.filter(mi=>{let An=d().get(kr,mi.prop);if(d().isUndefined(mi.pipe)||(An=mi.pipe.transform(An)),d().isUndefined(An)||d().isNull(An))return!1;if(d().isArray(An)?An=An.join(" "):(d().isNumber(An)||d().isBoolean(An))&&(An=An.toString()),d().isObjectLike(An)){if(!this.searchableObjects)return!1;An=JSON.stringify(An)}return-1!==An.toLowerCase().indexOf(Yt)}).length>0)}getRowClass(){return()=>({clickable:!d().isUndefined(this.selectionType)})}toggleExpandRow(Yt,_n,Ge){Ge.stopPropagation(),_n?(this.expanded=void 0,this.setExpandedRow.emit(void 0)):(this.expanded=Yt,this.table.rowDetail.collapseAllRows(),this.setExpandedRow.emit(Yt)),this.table.rowDetail.toggleExpandRow(Yt)}}return Dn.\u0275fac=function(Yt){return new(Yt||Dn)(r.Y36(r.sBO),r.Y36(Z.f))},Dn.\u0275cmp=r.Xpm({type:Dn,selectors:[["cd-table"]],viewQuery:function(Yt,_n){if(1&Yt&&(r.Gf(u.nE,7),r.Gf(De,7),r.Gf(ce,7),r.Gf(lt,7),r.Gf(Ve,7),r.Gf(ze,7),r.Gf(Be,7),r.Gf(Pe,7),r.Gf(je,7),r.Gf(He,7),r.Gf(Vt,7),r.Gf(it,7)),2&Yt){let Ge;r.iGM(Ge=r.CRH())&&(_n.table=Ge.first),r.iGM(Ge=r.CRH())&&(_n.tableCellBoldTpl=Ge.first),r.iGM(Ge=r.CRH())&&(_n.sparklineTpl=Ge.first),r.iGM(Ge=r.CRH())&&(_n.routerLinkTpl=Ge.first),r.iGM(Ge=r.CRH())&&(_n.checkIconTpl=Ge.first),r.iGM(Ge=r.CRH())&&(_n.perSecondTpl=Ge.first),r.iGM(Ge=r.CRH())&&(_n.executingTpl=Ge.first),r.iGM(Ge=r.CRH())&&(_n.classAddingTpl=Ge.first),r.iGM(Ge=r.CRH())&&(_n.badgeTpl=Ge.first),r.iGM(Ge=r.CRH())&&(_n.mapTpl=Ge.first),r.iGM(Ge=r.CRH())&&(_n.truncateTpl=Ge.first),r.iGM(Ge=r.CRH())&&(_n.rowDetailsTpl=Ge.first)}},inputs:{data:"data",columns:"columns",sorts:"sorts",columnMode:"columnMode",onlyActionHeader:"onlyActionHeader",toolHeader:"toolHeader",searchField:"searchField",header:"header",footer:"footer",limit:"limit",maxLimit:"maxLimit",hasDetails:"hasDetails",autoReload:"autoReload",identifier:"identifier",forceIdentifier:"forceIdentifier",selectionType:"selectionType",updateSelectionOnRefresh:"updateSelectionOnRefresh",updateExpandedOnRefresh:"updateExpandedOnRefresh",autoSave:"autoSave",searchableObjects:"searchableObjects",customCss:"customCss",extraFilterableColumns:"extraFilterableColumns",status:"status",serverSide:"serverSide",count:"count"},outputs:{fetchData:"fetchData",updateSelection:"updateSelection",setExpandedRow:"setExpandedRow",columnFiltersChanged:"columnFiltersChanged"},features:[r.TTD],ngContentSelectors:Vn,decls:33,vars:21,consts:function(){let Pr,Yt,_n,Ge,kr,mi,An;return Pr="Clear filters",Yt="selected",_n="total",Ge="found",kr="found",mi="total",An="Expand/Collapse Row",[[1,"dataTables_wrapper"],["class","dataTables_header clearfix",4,"ngIf"],[1,"bootstrap","cd-datatable",3,"cssClasses","selectionType","selected","sorts","columns","columnMode","rows","rowClass","headerHeight","footerHeight","count","externalPaging","externalSorting","limit","offset","loadingIndicator","rowIdentity","rowHeight","select","sort","page"],["table",""],["rowHeight","auto"],["detailRow",""],["ngx-datatable-row-detail-template",""],["ngx-datatable-footer-template",""],["tableCellBoldTpl",""],["sparklineTpl",""],["routerLinkTpl",""],["checkIconTpl",""],["perSecondTpl",""],["executingTpl",""],["classAddingTpl",""],["badgeTpl",""],["mapTpl",""],["truncateTpl",""],["ngx-datatable-cell-template",""],["rowDetailsTpl",""],[1,"dataTables_header","clearfix"],[1,"cd-datatable-actions"],["class","btn-group widget-toolbar",4,"ngIf"],["class","input-group search",4,"ngIf"],["class","input-group dataTables_paginate",4,"ngIf"],[1,"widget-toolbar"],["ngbDropdown","","autoClose","outside",1,"tc_menuitem"],["ngbDropdownToggle","",1,"btn","btn-light","tc_columnBtn"],[3,"ngClass"],["ngbDropdownMenu",""],[4,"ngFor","ngForOf"],["class","widget-toolbar tc_refreshBtn",4,"ngIf"],[1,"btn-group","widget-toolbar"],["ngbDropdown","","placement","bottom-right",1,"tc_filter_name"],["ngbDropdownToggle","",1,"btn","btn-light"],["ngbDropdown","","placement","bottom-right",1,"tc_filter_option"],["ngbDropdownItem","",3,"click"],[3,"ngClass",4,"ngIf"],[1,"input-group","search"],[1,"input-group-prepend"],[1,"input-group-text"],["type","text",1,"form-control",3,"ngModel","ngModelChange","keyup"],[1,"input-group-append"],["type","button",1,"btn","btn-light",3,"click"],[1,"input-group","dataTables_paginate"],["type","number","min","1","max","9999",1,"form-control",3,"value","click","keyup","blur"],["ngbDropdownItem","",3,"click",4,"ngIf"],[1,"custom-control","custom-checkbox","py-0"],["type","checkbox",1,"custom-control-input",3,"name","id","checked"],[1,"custom-control-label",3,"for"],[1,"widget-toolbar","tc_refreshBtn"],["type","button",3,"ngbTooltip","click"],[1,"filter-chips"],["href","",1,"tc_clearSelections",3,"click"],Pr,["class","badge badge-info mr-2",4,"ngIf"],[1,"badge","badge-info","mr-2"],[1,"mr-2"],[1,"badge-remove",3,"click"],["aria-hidden","true",3,"ngClass"],[1,"page-count"],[4,"ngIf"],[4,"ngIf","ngIfElse"],["serverSideTpl",""],[3,"pagerLeftArrowIcon","pagerRightArrowIcon","pagerPreviousIcon","pagerNextIcon","page","size","count","hidden","change"],Yt,_n,Ge,kr,mi,[3,"data","isBinary"],[3,"routerLink","queryParams"],[3,"ngClass","hidden"],["class","badge",3,"ngClass",4,"ngIf"],[1,"badge",3,"ngClass"],["data-toggle","tooltip",3,"title"],["href","javascript:void(0)","title",An,1,"expand-collapse-icon","tc_expand-collapse",3,"click"]]},template:function(Yt,_n){1&Yt&&(r.F$t(Jt),r.TgZ(0,"div",0),r.YNc(1,tn,3,0,"div",1),r.YNc(2,Lr,13,9,"div",1),r.YNc(3,ei,6,1,"div",1),r.TgZ(4,"ngx-datatable",2,3),r.NdJ("select",function(kr){return _n.onSelect(kr)})("sort",function(kr){return _n.changeSorting(kr)})("page",function(kr){return _n.changePage(kr)}),r.TgZ(6,"ngx-datatable-row-detail",4,5),r.YNc(8,Nn,1,0,"ng-template",6),r.qZA(),r.TgZ(9,"ngx-datatable-footer"),r.YNc(10,ki,6,11,"ng-template",7),r.qZA(),r.qZA(),r.qZA(),r.YNc(11,Hi,2,1,"ng-template",null,8,r.W1O),r.YNc(13,Zr,1,2,"ng-template",null,9,r.W1O),r.YNc(15,Cn,2,5,"ng-template",null,10,r.W1O),r.YNc(17,Wt,2,6,"ng-template",null,11,r.W1O),r.YNc(19,zn,2,3,"ng-template",null,12,r.W1O),r.YNc(21,Gn,4,4,"ng-template",null,13,r.W1O),r.YNc(23,Jr,3,8,"ng-template",null,14,r.W1O),r.YNc(25,Dr,2,3,"ng-template",null,15,r.W1O),r.YNc(27,gn,3,4,"ng-template",null,16,r.W1O),r.YNc(29,yn,3,6,"ng-template",null,17,r.W1O),r.YNc(31,gr,1,4,"ng-template",18,19,r.W1O)),2&Yt&&(r.xp6(1),r.Q6J("ngIf",_n.onlyActionHeader),r.xp6(1),r.Q6J("ngIf",_n.toolHeader),r.xp6(1),r.Q6J("ngIf",_n.toolHeader&&_n.columnFiltered),r.xp6(1),r.Q6J("cssClasses",_n.paginationClasses)("selectionType",_n.selectionType)("selected",_n.selection.selected)("sorts",_n.userConfig.sorts)("columns",_n.tableColumns)("columnMode",_n.columnMode)("rows",_n.rows)("rowClass",_n.getRowClass())("headerHeight",_n.header?"auto":0)("footerHeight",_n.footer?"auto":0)("count",_n.count)("externalPaging",_n.serverSide)("externalSorting",_n.serverSide)("limit",_n.userConfig.limit>0?_n.userConfig.limit:void 0)("offset",_n.userConfig.offset>=0?_n.userConfig.offset:0)("loadingIndicator",_n.loadingIndicator)("rowIdentity",_n.rowIdentity())("rowHeight","auto"))},directives:[J.O5,u.nE,u.$7,u.AR,u.dX,u.ii,u.vq,K.jt,K.iD,J.mk,K.Vi,J.sg,K.TH,ee.Fj,ee.JJ,ee.On,K._L,u.Ke,ue.l,ae.yS],pipes:[H.i,se.n,Ee.i,ie.I,he.b,ge.W],styles:['@charset "UTF-8";.dataTables_wrapper[_ngcontent-%COMP%]{margin-bottom:25px;max-width:99.9%}.dataTables_wrapper[_ngcontent-%COMP%] .separator[_ngcontent-%COMP%]{border-left:1px solid rgba(0,0,0,.09);display:inline-block;height:30px;margin-left:5px;padding-left:5px;vertical-align:middle}.dataTables_wrapper[_ngcontent-%COMP%] .widget-toolbar[_ngcontent-%COMP%]{border-left:1px solid rgba(0,0,0,.09);float:right;padding:0 8px}.dataTables_wrapper[_ngcontent-%COMP%] .widget-toolbar[_ngcontent-%COMP%] .form-check[_ngcontent-%COMP%]{padding-left:0}.dataTables_wrapper[_ngcontent-%COMP%] .dataTables_length[_ngcontent-%COMP%] > input[_ngcontent-%COMP%]{line-height:25px;text-align:right}.dataTables_header[_ngcontent-%COMP%]{background-color:#f8f9fa;border:1px solid #ced4da;border-bottom:0;padding:5px;position:relative}.dataTables_header[_ngcontent-%COMP%] .cd-datatable-actions[_ngcontent-%COMP%]{float:left}.dataTables_header[_ngcontent-%COMP%] .form-group[_ngcontent-%COMP%]{padding-left:8px}.dataTables_header[_ngcontent-%COMP%] .input-group[_ngcontent-%COMP%]{border-left:1px solid rgba(0,0,0,.09);float:right;max-width:250px;padding-left:8px;padding-right:8px;width:40%}.dataTables_header[_ngcontent-%COMP%] .input-group[_ngcontent-%COMP%] .form-control[_ngcontent-%COMP%]{height:30px}.dataTables_header[_ngcontent-%COMP%] .input-group.dataTables_paginate[_ngcontent-%COMP%]{min-width:85px;padding-right:8px;width:8%}.dataTables_header[_ngcontent-%COMP%] .filter-chips[_ngcontent-%COMP%]{float:right;padding:0 8px}.dataTables_header[_ngcontent-%COMP%] .filter-chips[_ngcontent-%COMP%] .badge-remove[_ngcontent-%COMP%]{color:#fff} cd-table .cd-datatable{border:1px solid #ced4da;margin-bottom:0;max-width:none!important} cd-table .cd-datatable .progress-linear{display:block;height:5px;margin:0;padding:0;position:relative;width:100%} cd-table .cd-datatable .progress-linear .container{background-color:#2b99a8} cd-table .cd-datatable .progress-linear .container .bar{background-color:#2b99a8;height:100%;left:0;overflow:hidden;position:absolute;width:100%} cd-table .cd-datatable .progress-linear .container .bar:before{animation:progress-loading 3s linear infinite;background-color:#2b99a8;content:"";display:block;height:100%;left:-200px;position:absolute;width:200px} cd-table .cd-datatable .datatable-header{background-clip:padding-box;background-color:#f8f9fa;background-image:linear-gradient(to bottom,#f8f9fa 0,#e9ecef 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#fffafafa",endColorstr="#ffededed",GradientType=0)} cd-table .cd-datatable .datatable-header .sort-asc, cd-table .cd-datatable .datatable-header .sort-desc{color:#2b99a8} cd-table .cd-datatable .datatable-header .datatable-header-cell{border:0;border-bottom:1px solid #ced4da;border-left:1px solid #ced4da;padding:5px;font-weight:bold;text-align:left} cd-table .cd-datatable .datatable-header .datatable-header-cell .datatable-header-cell-label:after{font-family:ForkAwesome;font-weight:400;height:9px;left:10px;line-height:12px;position:relative;vertical-align:baseline;width:12px} cd-table .cd-datatable .datatable-header .datatable-header-cell.sortable .datatable-header-cell-label:after{content:" \\f0dc"} cd-table .cd-datatable .datatable-header .datatable-header-cell.sortable.sort-active.sort-asc .datatable-header-cell-label:after{content:" \\f160"} cd-table .cd-datatable .datatable-header .datatable-header-cell.sortable.sort-active.sort-desc .datatable-header-cell-label:after{content:" \\f161"} cd-table .cd-datatable .datatable-header .datatable-header-cell:first-child{border-left:0} cd-table .cd-datatable .datatable-body{margin-bottom:-6px} cd-table .cd-datatable .datatable-body .empty-row{background-color:#c8ecf1;font-style:italic;font-weight:bold;padding-bottom:5px;padding-top:5px;text-align:center} cd-table .cd-datatable .datatable-body .datatable-body-row.clickable:hover .datatable-row-group{background-color:#c8ecf1;transition-duration:.3s;transition-property:background;transition-timing-function:linear} cd-table .cd-datatable .datatable-body .datatable-body-row.datatable-row-even{background-color:#fff} cd-table .cd-datatable .datatable-body .datatable-body-row.datatable-row-odd{background-color:#f8f9fa} cd-table .cd-datatable .datatable-body .datatable-body-row.active, cd-table .cd-datatable .datatable-body .datatable-body-row.active:hover{background-color:#9fdee6} cd-table .cd-datatable .datatable-body .datatable-body-row .datatable-body-cell{border:0;border-bottom:1px solid #ced4da;border-left:1px solid #ced4da;padding:5px} cd-table .cd-datatable .datatable-body .datatable-body-row .datatable-body-cell:first-child{border-left:0} cd-table .cd-datatable .datatable-body .datatable-body-row .datatable-body-cell .datatable-body-cell-label{display:block;height:100%} cd-table .cd-datatable .datatable-body .datatable-row-detail{border-bottom:2px solid #ced4da;overflow-y:visible!important;padding:20px} cd-table .cd-datatable .datatable-body .expand-collapse-icon{display:block;height:100%;text-align:center} cd-table .cd-datatable .datatable-body .expand-collapse-icon:hover{text-decoration:none} cd-table .cd-datatable .datatable-body .expand-collapse-icon-right:before{color:#212529;font-family:"ForkAwesome",sans-serif;font-size:1rem;line-height:1;content:"\\f105"} cd-table .cd-datatable .datatable-body .expand-collapse-icon-down:before{color:#212529;font-family:"ForkAwesome",sans-serif;font-size:1rem;line-height:1;content:"\\f107"} cd-table .cd-datatable .datatable-footer .selected-count, cd-table .cd-datatable .datatable-footer .page-count{font-style:italic;min-height:2rem;padding-left:.3rem;padding-top:.3rem} cd-table .cd-datatable .cd-datatable-checkbox{text-align:center}@keyframes progress-loading{0%{left:-200px;width:15%}50%{width:30%}70%{width:70%}80%{left:50%}95%{left:120%}to{left:100%}}'],changeDetection:0}),Dn})()},93523:(v,T,i)=>{"use strict";i.d(T,{o:()=>p,G:()=>d});var r=i(23815),u=i.n(r);function p(...y){switch(y.length){case 1:return e.apply(void 0,y);case 3:return _.apply(void 0,y);default:throw new Error}}function d(y,S,A){const N=`__ignore_${S}`;Array.isArray(y[N])?y[N].push(A):y[N]=[A]}function e(y){for(const S of Object.getOwnPropertyNames(y.prototype)){const A=Object.getOwnPropertyDescriptor(y.prototype,S);!(A.value instanceof Function)||"constructor"===S||(_(y.prototype,S,A),Object.defineProperty(y.prototype,S,A))}}function _(y,S,A){void 0===A&&(A=Object.getOwnPropertyDescriptor(y,S));const N=A.value;A.value=function(){const L=`__ignore_${S}`,Z=y[L]||[],J=[];for(let ee=0;ee<arguments.length;ee++)J[ee]=u().isString(arguments[ee])&&-1===Z.indexOf(ee)?encodeURIComponent(arguments[ee]):arguments[ee];return N.apply(this,J)}}},82945:(v,T,i)=>{"use strict";i.d(T,{U:()=>d});var r=i(23815),u=i.n(r),p=i(74788);let d=(()=>{class e{constructor(y){this.elementRef=y,this.focus=!0}ngAfterViewInit(){const y=this.elementRef.nativeElement;this.focus&&u().isFunction(y.focus)&&y.focus()}set autofocus(y){u().isBoolean(y)?this.focus=y:u().isFunction(y)&&(this.focus=y())}}return e.\u0275fac=function(y){return new(y||e)(p.Y36(p.SBq))},e.\u0275dir=p.lG2({type:e,selectors:[["","autofocus",""]],inputs:{autofocus:"autofocus"}}),e})()},17932:(v,T,i)=>{"use strict";i.d(T,{Q:()=>y});var r=i(74788),u=i(23815),p=i.n(u),d=i(47557),e=i(28211),_=i(24751);let y=(()=>{class S{constructor(N,L,Z,J){this.elementRef=N,this.control=L,this.dimlessBinaryPipe=Z,this.formatter=J,this.ngModelChange=new r.vpe,this.el=this.elementRef.nativeElement}ngOnInit(){this.setValue(this.el.value)}setValue(N){/^[\d.]+$/.test(N)&&(N+=this.defaultUnit||"m");const L=this.formatter.toBytes(N),Z=this.round(L);this.el.value=this.dimlessBinaryPipe.transform(Z),null!==L?(this.ngModelChange.emit(this.el.value),this.control.control.setValue(this.el.value)):(this.ngModelChange.emit(null),this.control.control.setValue(null))}round(N){if(null!==N&&0!==N){if(!p().isUndefined(this.minBytes)&&N<this.minBytes)return this.minBytes;if(!p().isUndefined(this.maxBytes)&&N>this.maxBytes)return this.maxBytes;if(!p().isUndefined(this.roundPower)){const L=Math.round(Math.log(N)/Math.log(this.roundPower));return Math.pow(this.roundPower,L)}}return N}onBlur(N){this.setValue(N)}}return S.\u0275fac=function(N){return new(N||S)(r.Y36(r.SBq),r.Y36(_.a5),r.Y36(d.$),r.Y36(e.H))},S.\u0275dir=r.lG2({type:S,selectors:[["","cdDimlessBinary",""]],hostBindings:function(N,L){1&N&&r.NdJ("blur",function(J){return L.onBlur(J.target.value)})},inputs:{minBytes:"minBytes",maxBytes:"maxBytes",roundPower:"roundPower",defaultUnit:"defaultUnit"},outputs:{ngModelChange:"ngModelChange"}}),S})()},35540:(v,T,i)=>{"use strict";i.d(T,{o:()=>u});var r=i(74788);let u=(()=>{class p{}return p.\u0275fac=function(e){return new(e||p)},p.\u0275mod=r.oAB({type:p}),p.\u0275inj=r.cJS({imports:[[]]}),p})()},87925:(v,T,i)=>{"use strict";i.d(T,{o:()=>d});var r=i(74788),u=i(84333),p=i(74937);let d=(()=>{class e{constructor(y,S,A){this.formScope=y,this.authStorageService=S,this.elementRef=A}ngAfterViewInit(){var y,S,A;this.permissions=this.authStorageService.getPermissions();const N=null===(y=this.formScope)||void 0===y?void 0:y.cdFormScope;N&&!(null===(A=null===(S=this.permissions)||void 0===S?void 0:S[N])||void 0===A?void 0:A.update)&&(this.elementRef.nativeElement.disabled=!0)}}return e.\u0275fac=function(y){return new(y||e)(r.Y36(u.T,8),r.Y36(p.j),r.Y36(r.SBq))},e.\u0275dir=r.lG2({type:e,selectors:[["input",3,"cdNoFormInputDisable",""],["select",3,"cdNoFormInputDisable",""],["button",3,"cdNoFormInputDisable",""],["","cdFormInputDisable",""]]}),e})()},63622:(v,T,i)=>{"use strict";i.d(T,{y:()=>e});var r=i(34501),u=i(8958),p=i(93614),d=i(74788);let e=(()=>{class _{constructor(S,A,N){this.templateRef=S,this.viewContainer=A,this.componentFactoryResolver=N}set cdFormLoading(S){let A,N;switch(this.viewContainer.clear(),S){case p.Q.Loading:A=this.componentFactoryResolver.resolveComponentFactory(u.b),N=this.resolveNgContent("Loading form data..."),this.viewContainer.createComponent(A,null,null,N);break;case p.Q.Ready:this.viewContainer.createEmbeddedView(this.templateRef);break;case p.Q.Error:A=this.componentFactoryResolver.resolveComponentFactory(r.G),N=this.resolveNgContent("Form data could not be loaded."),this.viewContainer.createComponent(A,null,null,N).instance.type="error"}}resolveNgContent(S){return[[document.createTextNode(S)]]}}return _.\u0275fac=function(S){return new(S||_)(d.Y36(d.Rgc),d.Y36(d.s_b),d.Y36(d._Vd))},_.\u0275dir=d.lG2({type:_,selectors:[["","cdFormLoading",""]],inputs:{cdFormLoading:"cdFormLoading"}}),_})()},84333:(v,T,i)=>{"use strict";i.d(T,{T:()=>u});var r=i(74788);let u=(()=>{class p{}return p.\u0275fac=function(e){return new(e||p)},p.\u0275dir=r.lG2({type:p,selectors:[["","cdFormScope",""]],inputs:{cdFormScope:"cdFormScope"}}),p})()},94276:(v,T,i)=>{"use strict";i.d(T,{b:()=>d});var r=i(74788),u=i(24751);let d=(()=>{class e{constructor(y){this.parent=y}get validClass(){return!!this.control&&this.control.valid&&(this.control.touched||this.control.dirty)}get invalidClass(){return!!this.control&&this.control.invalid&&this.control.touched&&this.control.dirty}get path(){return function(e,_){return[..._.path,e]}(this.formControlName,this.parent)}get control(){return this.formDirective&&this.formDirective.getControl(this)}get formDirective(){return this.parent?this.parent.formDirective:null}}return e.\u0275fac=function(y){return new(y||e)(r.Y36(u.gN,13))},e.\u0275dir=r.lG2({type:e,selectors:[["",8,"form-control"],["",8,"form-check-input"],["",8,"custom-control-input"]],hostVars:4,hostBindings:function(y,S){2&y&&r.ekj("is-valid",S.validClass)("is-invalid",S.invalidClass)},inputs:{formControlName:"formControlName",formControl:"formControl"}}),e})()},56310:(v,T,i)=>{"use strict";i.d(T,{P:()=>p});var r=i(24751),u=i(74788);let p=(()=>{class d{constructor(_){this.elRef=_,this.validationDisabled=!1}get hasErrors(){return this.formControlNames.some(_=>!_.valid&&_.dirty&&_.touched)&&!this.validationDisabled}get hasSuccess(){return!this.formControlNames.some(_=>!_.valid)&&this.formControlNames.some(_=>_.dirty&&_.touched)&&!this.validationDisabled}get label(){const _=this.elRef.nativeElement.querySelector("label");return _&&_.textContent?_.textContent.trim():"This field"}get isDirtyAndTouched(){return this.formControlNames.some(_=>_.dirty&&_.touched)}}return d.\u0275fac=function(_){return new(_||d)(u.Y36(u.SBq))},d.\u0275dir=u.lG2({type:d,selectors:[["",8,"form-group"]],contentQueries:function(_,y,S){if(1&_&&u.Suo(S,r.u,4),2&_){let A;u.iGM(A=u.CRH())&&(y.formControlNames=A)}},hostVars:4,hostBindings:function(_,y){2&_&&u.ekj("has-error",y.hasErrors)("has-success",y.hasSuccess)},inputs:{validationDisabled:"validationDisabled"}}),d})()},41582:(v,T,i)=>{"use strict";i.d(T,{V:()=>p});var r=i(74788),u=i(24751);let p=(()=>{class d{constructor(){this.validSubmit=new r.vpe}onSubmit(){this.markAsTouchedAndDirty(this.formGroup),this.formGroup.valid&&this.validSubmit.emit(this.formGroup.value)}markAsTouchedAndDirty(_){_ instanceof u.cw?Object.keys(_.controls).forEach(y=>this.markAsTouchedAndDirty(_.controls[y])):_ instanceof u.Oe?_.controls.forEach(y=>this.markAsTouchedAndDirty(y)):_ instanceof u.NI&&_.enabled&&(_.markAsDirty(),_.markAsTouched(),_.updateValueAndValidity())}}return d.\u0275fac=function(_){return new(_||d)},d.\u0275dir=r.lG2({type:d,selectors:[["","formGroup",""]],hostBindings:function(_,y){1&_&&r.NdJ("submit",function(){return y.onSubmit()})},inputs:{formGroup:"formGroup"},outputs:{validSubmit:"validSubmit"}}),d})()},4416:(v,T,i)=>{"use strict";i.d(T,{C:()=>u});var r=i(74788);let u=(()=>{class p{constructor(e,_){this.elementRef=e,this.renderer=_}ngOnInit(){this.renderer.setAttribute(this.elementRef.nativeElement,"tabindex","-1"),this.iElement=this.renderer.createElement("i"),this.renderer.addClass(this.iElement,"fa"),this.renderer.appendChild(this.elementRef.nativeElement,this.iElement),this.update()}getInputElement(){return document.getElementById(this.cdPasswordButton)}update(){const e=this.getInputElement();e&&"text"===e.type?(this.renderer.removeClass(this.iElement,"fa-eye"),this.renderer.addClass(this.iElement,"fa-eye-slash")):(this.renderer.removeClass(this.iElement,"fa-eye-slash"),this.renderer.addClass(this.iElement,"fa-eye"))}onClick(){const e=this.getInputElement();e.type="password"===e.type?"text":"password",this.update()}}return p.\u0275fac=function(e){return new(e||p)(r.Y36(r.SBq),r.Y36(r.Qsj))},p.\u0275dir=r.lG2({type:p,selectors:[["","cdPasswordButton",""]],hostBindings:function(e,_){1&e&&r.NdJ("click",function(){return _.onClick()})},inputs:{cdPasswordButton:"cdPasswordButton"}}),p})()},59376:(v,T,i)=>{"use strict";i.d(T,{m:()=>p});var r=i(74788),u=i(38549);let p=(()=>{class d{constructor(_){this.nav=_,this.localStorage=window.localStorage}ngOnInit(){const _=this.localStorage.getItem(`tabset_${this.cdStatefulTab}`);_&&this.nav.select(_)}onNavChange(_){this.cdStatefulTab&&_.nextId&&this.localStorage.setItem(`tabset_${this.cdStatefulTab}`,_.nextId)}}return d.\u0275fac=function(_){return new(_||d)(r.Y36(u.Pz,9))},d.\u0275dir=r.lG2({type:d,selectors:[["","cdStatefulTab",""]],hostBindings:function(_,y){1&_&&r.NdJ("navChange",function(A){return y.onNavChange(A)})},inputs:{cdStatefulTab:"cdStatefulTab"}}),d})()},99466:(v,T,i)=>{"use strict";i.d(T,{e:()=>r});var r=(()=>{return(u=r||(r={})).bold="bold",u.sparkline="sparkline",u.perSecond="perSecond",u.checkIcon="checkIcon",u.routerLink="routerLink",u.executing="executing",u.classAdding="classAdding",u.badge="badge",u.map="map",u.truncate="truncate",r;var u})()},65862:(v,T,i)=>{"use strict";i.d(T,{P:()=>r});var r=(()=>{return(u=r||(r={})).add="fa fa-plus",u.addCircle="fa fa-plus-circle",u.minusCircle="fa fa-minus-circle",u.edit="fa fa-pencil",u.destroy="fa fa-times",u.destroyCircle="fa fa-times-circle",u.exchange="fa fa-exchange",u.copy="fa fa-copy",u.clipboard="fa fa-clipboard",u.flatten="fa fa-chain-broken",u.trash="fa fa-trash-o",u.lock="fa fa-lock",u.unlock="fa fa-unlock",u.clone="fa fa-clone",u.undo="fa fa-undo",u.search="fa fa-search",u.start="fa fa-play",u.stop="fa fa-stop",u.analyse="fa fa-stethoscope",u.deepCheck="fa fa-cog",u.reweight="fa fa-balance-scale",u.left="fa fa-arrow-left",u.right="fa fa-arrow-right",u.down="fa fa-arrow-down",u.erase="fa fa-eraser",u.user="fa fa-user",u.users="fa fa-users",u.share="fa fa-share-alt",u.key="fa fa-key-modern",u.warning="fa fa-exclamation-triangle",u.info="fa fa-info",u.infoCircle="fa fa-info-circle",u.questionCircle="fa fa-question-circle-o",u.check="fa fa-check",u.show="fa fa-eye",u.paragraph="fa fa-paragraph",u.terminal="fa fa-terminal",u.magic="fa fa-magic",u.hourglass="fa fa-hourglass-o",u.filledHourglass="fa fa-hourglass",u.table="fa fa-table",u.spinner="fa fa-spinner",u.refresh="fa fa-refresh",u.bullseye="fa fa-bullseye",u.disk="fa fa-hdd-o",u.server="fa fa-server",u.filter="fa fa-filter",u.lineChart="fa fa-line-chart",u.signOut="fa fa-sign-out",u.health="fa fa-heartbeat",u.circle="fa fa-circle",u.bell="fa fa-bell",u.tag="fa fa-tag",u.leftArrow="fa fa-angle-left",u.rightArrow="fa fa-angle-right",u.leftArrowDouble="fa fa-angle-double-left",u.rightArrowDouble="fa fa-angle-double-right",u.flag="fa fa-flag",u.clearFilters="fa fa-window-close",u.download="fa fa-download",u.upload="fa fa-upload",u.close="fa fa-times",u.json="fa fa-file-code-o",u.text="fa fa-file-text",u.wrench="fa fa-wrench",u.enter="fa fa-sign-in",u.exit="fa fa-sign-out",u.restart="fa fa-history",u.deploy="fa fa-cube",u.large="fa fa-lg",u.large2x="fa fa-2x",u.large3x="fa fa-3x",u.stack="fa fa-stack",u.stack1x="fa fa-stack-1x",u.stack2x="fa fa-stack-2x",u.pulse="fa fa-pulse",u.spin="fa fa-spin",u.inverse="fa fa-inverse",r;var u})()},18001:(v,T,i)=>{"use strict";i.d(T,{k:()=>r});var r=(()=>{return(u=r||(r={}))[u.error=0]="error",u[u.info=1]="info",u[u.success=2]="success",r;var u})()},91801:(v,T,i)=>{"use strict";i.d(T,{T:()=>r});var r=(()=>{return(u=r||(r={}))[u.ValueOk=0]="ValueOk",u[u.ValueStale=1]="ValueStale",u[u.ValueNone=2]="ValueNone",u[u.ValueException=3]="ValueException",r;var u})()},62862:(v,T,i)=>{"use strict";i.d(T,{O:()=>d});var r=i(24751),u=i(95463),p=i(74788);let d=(()=>{class e extends r.qu{group(y,S=null){const A=super.group(y,S);return new u.d(A.controls,A.validator,A.asyncValidator)}}return e.\u0275fac=function(){let _;return function(S){return(_||(_=p.n5z(e)))(S||e)}}(),e.\u0275prov=p.Yz7({token:e,factory:e.\u0275fac,providedIn:"root"}),e})()},95463:(v,T,i)=>{"use strict";i.d(T,{d:()=>u});var r=i(24751);class u extends r.cw{constructor(d,e,_){super(d,e,_),this.controls=d}get(d){const e=this._get(d);if(!e)throw new Error(`Control '${d}' could not be found!`);return e}_get(d){return super.get(d)||Object.values(this.controls).filter(e=>e.get).map(e=>e instanceof u?e._get(d):e.get(d)).find(e=>Boolean(e))}getValue(d){return this.get(d).value}silentSet(d,e){this.get(d).setValue(e,{emitEvent:!1})}showError(d,e,_){const y=this.get(d);return(e.submitted||y.dirty)&&(_?y.hasError(_):y.invalid)}}},93614:(v,T,i)=>{"use strict";i.d(T,{Q:()=>r,E:()=>u});var r=(()=>{return(p=r||(r={}))[p.Loading=0]="Loading",p[p.Ready=1]="Ready",p[p.Error=2]="Error",p[p.None=3]="None",r;var p})();class u{constructor(){this.loading=r.Loading}loadingStart(){this.loading=r.Loading}loadingReady(){this.loading=r.Ready}loadingError(){this.loading=r.Error}loadingNone(){this.loading=r.None}}},77205:(v,T,i)=>{"use strict";i.d(T,{h:()=>J,P:()=>Z});var r=i(24751),u=i(23815),p=i.n(u),d=i(25917),e=i(46797),_=i(43190);function y(K,ee){return ee?(0,_.w)(()=>K,ee):(0,_.w)(()=>K)}var S=i(88002),A=i(15257),N=i(47557),L=i(28211);function Z(K){return null==K||0===K.length}class J{static email(ee){return Z(ee.value)?null:r.kI.email(ee)}static ip(ee=0){const ue=/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i,ae=/^(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}$/i;return r.kI.pattern(4===ee?ue:6===ee?ae:new RegExp(ue.source+"|"+ae.source))}static number(ee=!0){return r.kI.pattern(ee?/^-?[0-9]+$/i:/^[0-9]+$/i)}static decimalNumber(ee=!0){return r.kI.pattern(ee?/^-?[0-9]+(.[0-9]+)?$/i:/^[0-9]+(.[0-9]+)?$/i)}static sslCert(){return r.kI.pattern(/^-----BEGIN CERTIFICATE-----(\n|\r|\f)((.+)?((\n|\r|\f).+)*)(\n|\r|\f)-----END CERTIFICATE-----[\n\r\f]*$/)}static sslPrivKey(){return r.kI.pattern(/^-----BEGIN RSA PRIVATE KEY-----(\n|\r|\f)((.+)?((\n|\r|\f).+)*)(\n|\r|\f)-----END RSA PRIVATE KEY-----[\n\r\f]*$/)}static pemCert(){return r.kI.pattern(/^-----BEGIN .+-----$.+^-----END .+-----$/ms)}static requiredIf(ee,ue){let ae=!1;return H=>(!ae&&H.parent&&(Object.keys(ee).forEach(Ee=>{H.parent.get(Ee).valueChanges.subscribe(()=>{H.updateValueAndValidity({emitEvent:!1})})}),ae=!0),Object.keys(ee).every(Ee=>{if(!H.parent)return!1;const ie=H.parent.get(Ee).value,he=ee[Ee];if(p().isObjectLike(he)){let ge=!1;switch(he.op){case"empty":ge=p().isEmpty(ie);break;case"!empty":ge=!p().isEmpty(ie);break;case"equal":ge=ie===he.arg1;break;case"!equal":ge=ie!==he.arg1;break;case"minLength":p().isString(ie)&&(ge=ie.length>=he.arg1)}return ge}return ie===he})&&(p().isFunction(ue)?ue.call(ue,H.value):Z(H.value))?{required:!0}:null)}static composeIf(ee,ue){let ae=!1;return H=>(!ae&&H.parent&&(Object.keys(ee).forEach(se=>{H.parent.get(se).valueChanges.subscribe(()=>{H.updateValueAndValidity({emitEvent:!1})})}),ae=!0),Object.keys(ee).every(se=>H.parent&&H.parent.get(se).value===ee[se])?r.kI.compose(ue)(H):null)}static custom(ee,ue){return ae=>{const H=ue.call(this,ae.value);return H?{[ee]:H}:null}}static validateIf(ee,ue,ae,H=[],se=[]){ae=ae.concat(H),ee.setValidators(Ee=>ue.call(this)?r.kI.compose(ae)(Ee):H.length>0?r.kI.compose(H)(Ee):null),se.forEach(Ee=>{Ee.valueChanges.subscribe(()=>{ee.updateValueAndValidity({emitEvent:!1})})})}static match(ee,ue){return ae=>{const H=ae.get(ee),se=ae.get(ue);if(!H||!se)return null;if(H.value!==se.value)se.setErrors({match:!0});else if(se.hasError("match")){const ie=se.errors;p().unset(ie,"match"),se.setErrors(p().isEmpty(p().keys(ie))?null:ie)}return null}}static unique(ee,ue=null,ae,H=!1){let se;return Ee=>Ee.pristine||Z(Ee.value)?(0,d.of)(null):(se=Ee.value,p().isFunction(ae)&&null!==ae()&&""!==ae()&&(se=H?`${Ee.value}$${ae()}`:`${ae()}$${Ee.value}`),(0,e.H)().pipe(y(ee.call(ue,se)),(0,S.U)(ie=>ie?{notUnique:!0}:null),(0,A.q)(1)))}static uuid(ee=!1){const ue=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;return ae=>ae.pristine&&ae.untouched||!ee&&!ae.value||ue.test(ae.value)?null:{invalidUuid:"This is not a valid UUID"}}static binaryMin(ee){return ue=>{const ae=new L.H,H=(new L.H).toBytes(ue.value);if(ee<=H)return null;const se=new N.$(ae).transform(ee);return{binaryMin:()=>"Size has to be at least " + se + " or more"}}}static binaryMax(ee){return ue=>{const ae=new L.H,H=ae.toBytes(ue.value);if(ee>=H)return null;const se=new N.$(ae).transform(ee);return{binaryMax:()=>"Size has to be at most " + se + " or less"}}}static passwordPolicy(ee,ue,ae){return H=>{if(H.pristine||""===H.value)return p().isFunction(ae)&&ae(!0,0),(0,d.of)(null);let se;return p().isFunction(ue)&&(se=ue()),(0,e.H)(500).pipe(y(p().invoke(ee,"validatePassword",H.value,se)),(0,S.U)(Ee=>(p().isFunction(ae)&&ae(Ee.valid,Ee.credits,Ee.valuation),Ee.valid?null:{passwordPolicy:!0})),(0,A.q)(1))}}static bucketName(){return ee=>{if(ee.pristine||!ee.value)return(0,d.of)({required:!0});const ue=[];let ae;return ue.push(()=>{const Ee=ee.value;let ie=!0;return(/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i.test(Ee)||/^(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}$/i.test(Ee))&&(ae="ipAddress",ie=!1),ie}),ue.push(H=>p().inRange(H.length,3,64)?!!/^[0-9a-z.-]+$/.test(ee.value)||(ae="bucketNameInvalid",!1):(ae="shouldBeInRange",!1)),ue.push(H=>{const se=p().split(H,".");return p().every(se,Ee=>Ee!==p().toLower(Ee)||Ee.includes("_")?(ae="containsUpperCase",!1):/^[0-9a-z-]+$/.test(Ee)?p().every([0,Ee.length-1],ie=>(ae="lowerCaseOrNumber",/[a-z]/.test(Ee[ie])||p().isInteger(p().parseInt(Ee[ie])))):(ae="onlyLowerCaseAndNumbers",!1))}),p().every(ue,H=>H(ee.value))?(0,d.of)(null):(0,d.of)((()=>{switch(ae){case"onlyLowerCaseAndNumbers":return{onlyLowerCaseAndNumbers:!0};case"shouldBeInRange":return{shouldBeInRange:!0};case"ipAddress":return{ipAddress:!0};case"containsUpperCase":return{containsUpperCase:!0};case"lowerCaseOrNumber":return{lowerCaseOrNumber:!0};default:return{bucketNameInvalid:!0}}})())}}static bucketExistence(ee,ue){return ae=>ae.pristine||!ae.value?(0,d.of)({required:!0}):ue.exists(ae.value).pipe((0,S.U)(H=>H===ee?null:{bucketNameNotAllowed:!0}))}}},61355:(v,T,i)=>{"use strict";i.d(T,{T:()=>p,e:()=>d});var r=i(65862),u=i(18001);class p{constructor(_=u.k.info,y,S,A,N="Ceph"){this.type=_,this.title=y,this.message=S,this.options=A,this.application=N,this.isFinishedTask=!1,this.classes={Ceph:"ceph-icon",Prometheus:"prometheus-icon"},this.applicationClass=this.classes[this.application]}}class d extends p{constructor(_=new p){super(_.type,_.title,_.message,_.options,_.application),this.config=_,this.textClasses=["text-danger","text-info","text-success"],this.iconClasses=[r.P.warning,r.P.info,r.P.check],this.borderClasses=["border-danger","border-info","border-success"],delete this.config,this.timestamp=(new Date).toJSON(),this.iconClass=this.iconClasses[this.type],this.textClass=this.textClasses[this.type],this.borderClass=this.borderClasses[this.type],this.isFinishedTask=_.isFinishedTask}}},51907:(v,T,i)=>{"use strict";i.d(T,{G:()=>r});class r{constructor(p){this.pwdExpirationSpan=0,this.pwdExpirationSpan=p.user_pwd_expiration_span,this.pwdExpirationWarning1=p.user_pwd_expiration_warning_1,this.pwdExpirationWarning2=p.user_pwd_expiration_warning_2}}},86919:(v,T,i)=>{"use strict";i.d(T,{E:()=>d});var r=i(58497);class p{constructor(){this.offset=0,this.limit=10,this.pageSize=10}}class d{constructor(_){this.errorConfig={resetData:!0,displayError:!0},this.pageInfo=new p,this.search="",this.sort="+name",this.error=_}toParams(){return null===this.pageInfo.limit&&(this.pageInfo.limit=0),this.search||(this.search=""),(!this.sort||this.sort.length<2)&&(this.sort="+name"),new r.LE({fromObject:{offset:String(this.pageInfo.offset*this.pageInfo.limit),limit:String(this.pageInfo.limit),search:this.search,sort:this.sort}})}}},68774:(v,T,i)=>{"use strict";i.d(T,{r:()=>r});class r{constructor(p){this._selected=[],p&&(this._selected=p),this.update()}update(){this.hasSelection=this._selected.length>0,this.hasSingleSelection=1===this._selected.length,this.hasMultiSelection=this._selected.length>1}set selected(p){this._selected=p,this.update()}get selected(){return this._selected}add(p){this._selected.push(p),this.update()}first(){return this.hasSelection?this._selected[0]:null}}},87311:(v,T,i)=>{"use strict";i.d(T,{h:()=>r});class r{constructor(p,d,e,_){this.customColors={backgroundColor:void 0,borderColor:void 0},this.checkOffset=!1,this.chartEl=p.nativeElement,this.getStyleLeft=e,this.getStyleTop=_,this.tooltipEl=d.nativeElement}customTooltips(p){if(0===p.opacity)return void(this.tooltipEl.style.opacity=0);if(this.tooltipEl.classList.remove("above","below","no-transform"),this.tooltipEl.classList.add(p.yAlign?p.yAlign:"no-transform"),p.body){const _=p.title||[],y=p.body.map(N=>N.lines);let S="<thead>";_.forEach(N=>{S+="<tr><th>"+this.getTitle(N)+"</th></tr>"}),S+="</thead><tbody>",y.forEach((N,L)=>{const Z=p.labelColors[L];let J="background:"+(this.customColors.backgroundColor||Z.backgroundColor);J+="; border-color:"+(this.customColors.borderColor||Z.borderColor),J+="; border-width: 2px",S+='<tr><td nowrap><span class="chartjs-tooltip-key" style="'+J+'"></span>'+this.getBody(N)+"</td></tr>"}),S+="</tbody>",this.tooltipEl.querySelector("table").innerHTML=S}const d=this.chartEl.offsetTop,e=this.chartEl.offsetLeft;if(this.checkOffset){const _=p.width/2;this.tooltipEl.classList.remove("transform-left"),this.tooltipEl.classList.remove("transform-right"),p.caretX-_<0?this.tooltipEl.classList.add("transform-left"):p.caretX+_>this.chartEl.width&&this.tooltipEl.classList.add("transform-right")}this.tooltipEl.style.left=this.getStyleLeft(p,e),this.tooltipEl.style.top=this.getStyleTop(p,d),this.tooltipEl.style.opacity=1,this.tooltipEl.style.fontFamily=p._fontFamily,this.tooltipEl.style.fontSize=p.fontSize,this.tooltipEl.style.fontStyle=p._fontStyle,this.tooltipEl.style.padding=p.yPadding+"px "+p.xPadding+"px"}getBody(p){return p}getTitle(p){return p}}},30633:(v,T,i)=>{"use strict";i.d(T,{h:()=>r,r:()=>u});var r=(()=>{return(p=r||(r={}))[p.global=0]="global",p[p.pool=1]="pool",p[p.image=2]="image",r;var p})(),u=(()=>{return(p=u||(u={}))[p.bps=0]="bps",p[p.iops=1]="iops",p[p.milliseconds=2]="milliseconds",u;var p})()},60737:(v,T,i)=>{"use strict";i.d(T,{o:()=>u});var r=i(29075);class u extends r.i{}},76111:(v,T,i)=>{"use strict";i.d(T,{R:()=>u});var r=i(29075);class u extends r.i{}},19358:(v,T,i)=>{"use strict";i.d(T,{N:()=>r});class r{constructor(p,d,e){this.poolName=p,this.namespace=d,this.imageName=e}static fromString(p){const d=p.split("/");return new this(d[0],d.length>=3?d[1]:null,d.length>=3?d[2]:d[1])}getNameSpace(){return this.namespace?`${this.namespace}/`:""}toString(){return`${this.poolName}/${this.getNameSpace()}${this.imageName}`}toStringEncoded(){return encodeURIComponent(`${this.poolName}/${this.getNameSpace()}${this.imageName}`)}}},29075:(v,T,i)=>{"use strict";i.d(T,{i:()=>r});class r{constructor(p,d){this.name=p,this.metadata=d}}},47187:(v,T,i)=>{"use strict";i.d(T,{I:()=>d});var r=i(23815),u=i.n(r),p=i(74788);let d=(()=>{class e{transform(y,S=!1){let A=y;return(!u().isArray(y)||u().isArray(y)&&S)&&(A=[y]),A}}return e.\u0275fac=function(y){return new(y||e)},e.\u0275pipe=p.Yjl({name:"array",type:e,pure:!0}),e})()},68962:(v,T,i)=>{"use strict";i.d(T,{T:()=>u});var r=i(74788);let u=(()=>{class p{transform(e,_="Yes",y="No"){return Boolean(e)?_:y}}return p.\u0275fac=function(e){return new(e||p)},p.\u0275pipe=r.Yjl({name:"booleanText",type:p,pure:!0}),p})()},70442:(v,T,i)=>{"use strict";i.d(T,{i:()=>u});var r=i(74788);let u=(()=>{class p{transform(e){let _=!1;switch(e){case!0:case 1:case"y":case"yes":case"t":case"true":case"on":case"1":_=!0}return _}}return p.\u0275fac=function(e){return new(e||p)},p.\u0275pipe=r.Yjl({name:"boolean",type:p,pure:!0}),p})()},96102:(v,T,i)=>{"use strict";i.d(T,{N:()=>p});var r=i(74788),u=i(12057);let p=(()=>{class d{constructor(_){this.datePipe=_}transform(_){return null===_||""===_?"":this.datePipe.transform(_,"shortDate")+" "+this.datePipe.transform(_,"mediumTime")}}return d.\u0275fac=function(_){return new(_||d)(r.Y36(u.uU,16))},d.\u0275pipe=r.Yjl({name:"cdDate",type:d,pure:!0}),d})()},24310:(v,T,i)=>{"use strict";i.d(T,{t:()=>u});var r=i(74788);let u=(()=>{class p{transform(e){const _=/ceph version\s+[^ ]+\s+\(.+\)\s+(.+)\s+\((.+)\)/.exec(e);return _?"dev"===_[2]?"main":_[1]:e}}return p.\u0275fac=function(e){return new(e||p)},p.\u0275pipe=r.Yjl({name:"cephReleaseName",type:p,pure:!0}),p})()},58111:(v,T,i)=>{"use strict";i.d(T,{F:()=>u});var r=i(74788);let u=(()=>{class p{transform(e){const _=/ceph version\s+([^ ]+)\s+\(.+\)/.exec(e);return _?_[1]:e}}return p.\u0275fac=function(e){return new(e||p)},p.\u0275pipe=r.Yjl({name:"cephShortVersion",type:p,pure:!0}),p})()},20044:(v,T,i)=>{"use strict";i.d(T,{O:()=>p});var r=i(28211),u=i(74788);let p=(()=>{class d{constructor(_){this.formatter=_}transform(_){return this.formatter.format_number(_,1024,["B/s","kB/s","MB/s","GB/s","TB/s","PB/s","EB/s","ZB/s","YB/s"])}}return d.\u0275fac=function(_){return new(_||d)(u.Y36(r.H,16))},d.\u0275pipe=u.Yjl({name:"dimlessBinaryPerSecond",type:d,pure:!0}),d})()},47557:(v,T,i)=>{"use strict";i.d(T,{$:()=>p});var r=i(28211),u=i(74788);let p=(()=>{class d{constructor(_){this.formatter=_}transform(_){return this.formatter.format_number(_,1024,["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"])}}return d.\u0275fac=function(_){return new(_||d)(u.Y36(r.H,16))},d.\u0275pipe=u.Yjl({name:"dimlessBinary",type:d,pure:!0}),d})()},66369:(v,T,i)=>{"use strict";i.d(T,{n:()=>p});var r=i(28211),u=i(74788);let p=(()=>{class d{constructor(_){this.formatter=_}transform(_){return this.formatter.format_number(_,1e3,["","k","M","G","T","P","E","Z","Y"])}}return d.\u0275fac=function(_){return new(_||d)(u.Y36(r.H,16))},d.\u0275pipe=u.Yjl({name:"dimless",type:d,pure:!0}),d})()},41039:(v,T,i)=>{"use strict";i.d(T,{W:()=>d});var r=i(23815),u=i.n(r),p=i(74788);let d=(()=>{class e{transform(y){return u().isUndefined(y)||u().isNull(y)?"-":y}}return e.\u0275fac=function(y){return new(y||e)},e.\u0275pipe=p.Yjl({name:"empty",type:e,pure:!0}),e})()},21766:(v,T,i)=>{"use strict";i.d(T,{A:()=>u});var r=i(74788);let u=(()=>{class p{transform(e){return`${e} IOPS`}}return p.\u0275fac=function(e){return new(e||p)},p.\u0275pipe=r.Yjl({name:"iops",type:p,pure:!0}),p})()},88820:(v,T,i)=>{"use strict";i.d(T,{V:()=>u});var r=i(74788);let u=(()=>{class p{transform(e){switch(e){case"user:rbd":return"user:rbd (tcmu-runner)";default:return e}}}return p.\u0275fac=function(e){return new(e||p)},p.\u0275pipe=r.Yjl({name:"iscsiBackstore",type:p,pure:!0}),p})()},86969:(v,T,i)=>{"use strict";i.d(T,{A:()=>u});var r=i(74788);let u=(()=>{class p{transform(e){return e.join(", ")}}return p.\u0275fac=function(e){return new(e||p)},p.\u0275pipe=r.Yjl({name:"join",type:p,pure:!0}),p})()},42746:(v,T,i)=>{"use strict";i.d(T,{e:()=>u});var r=i(74788);let u=(()=>{class p{transform(e){return"[DBG]"===e?"debug":"[INF]"===e?"info":"[WRN]"===e?"warn":"[ERR]"===e?"err":""}}return p.\u0275fac=function(e){return new(e||p)},p.\u0275pipe=r.Yjl({name:"logPriority",type:p,pure:!0}),p})()},78877:(v,T,i)=>{"use strict";i.d(T,{b:()=>d});var r=i(23815),u=i.n(r),p=i(74788);let d=(()=>{class e{transform(y,S){return u().isPlainObject(S)?u().get(S,y,y):y}}return e.\u0275fac=function(y){return new(y||e)},e.\u0275pipe=p.Yjl({name:"map",type:e,pure:!0}),e})()},48537:(v,T,i)=>{"use strict";i.d(T,{J:()=>u});var r=i(74788);let u=(()=>{class p{transform(e){return`${e} ms`}}return p.\u0275fac=function(e){return new(e||p)},p.\u0275pipe=r.Yjl({name:"milliseconds",type:p,pure:!0}),p})()},55657:(v,T,i)=>{"use strict";i.d(T,{g:()=>d});var r=i(23815),u=i.n(r),p=i(74788);let d=(()=>{class e{transform(y,S){return""===y?u().defaultTo(S,"n/a"):y}}return e.\u0275fac=function(y){return new(y||e)},e.\u0275pipe=p.Yjl({name:"notAvailable",type:e,pure:!0}),e})()},36569:(v,T,i)=>{"use strict";i.d(T,{f:()=>u});var r=i(74788);let u=(()=>{class p{transform(e){const _=parseInt(e,10);return isNaN(_)?e:e+(1===Math.floor(_/10)?"th":_%10==1?"st":_%10==2?"nd":_%10==3?"rd":"th")}}return p.\u0275fac=function(e){return new(e||p)},p.\u0275pipe=r.Yjl({name:"ordinal",type:p,pure:!0}),p})()},85953:(v,T,i)=>{"use strict";i.d(T,{D:()=>lt});var r=i(12057),u=i(47187),p=i(68962),d=i(70442),e=i(96102),_=i(24310),y=i(58111),S=i(20044),A=i(47557),N=i(66369),L=i(41039),Z=i(74788);let J=(()=>{class Ve{transform(Be){return encodeURIComponent(Be)}}return Ve.\u0275fac=function(Be){return new(Be||Ve)},Ve.\u0275pipe=Z.Yjl({name:"encodeUri",type:Ve,pure:!0}),Ve})();var K=i(21766),ee=i(88820),ue=i(86969),ae=i(42746),H=i(78877),se=i(48537),Ee=i(55657),ie=i(36569),he=i(90068),ge=i(60793),De=i(52821),ce=i(10545);let lt=(()=>{class Ve{}return Ve.\u0275fac=function(Be){return new(Be||Ve)},Ve.\u0275mod=Z.oAB({type:Ve}),Ve.\u0275inj=Z.cJS({providers:[u.I,d.i,p.T,r.uU,y.F,_.t,A.$,S.O,N.n,he.h,ee.V,ue.A,ae.e,e.N,L.W,J,ie.f,K.A,se.J,Ee.g,ce.m,H.b,De.W,ge.A],imports:[[r.ez]]}),Ve})()},90068:(v,T,i)=>{"use strict";i.d(T,{h:()=>_});var r=i(23815),u=i.n(r),p=i(16738),d=i.n(p),e=i(74788);d().updateLocale("en",{relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"}});let _=(()=>{class y{transform(A,N=!0){let L;if(L=u().isNumber(A)?d().unix(A):d()(A),!L.isValid())return"";let Z=L.fromNow();return N&&(Z=u().upperFirst(Z)),Z}}return y.\u0275fac=function(A){return new(A||y)},y.\u0275pipe=e.Yjl({name:"relativeDate",type:y,pure:!1}),y})()},60793:(v,T,i)=>{"use strict";i.d(T,{A:()=>p});var r=i(74788),u=i(91211);let p=(()=>{class d{constructor(_){this.domSanitizer=_}transform(_){return this.domSanitizer.sanitize(r.q3G.HTML,_)}}return d.\u0275fac=function(_){return new(_||d)(r.Y36(u.H7,16))},d.\u0275pipe=r.Yjl({name:"sanitizeHtml",type:d,pure:!0}),d})()},52821:(v,T,i)=>{"use strict";i.d(T,{W:()=>d});var r=i(23815),u=i.n(r),p=i(74788);let d=(()=>{class e{transform(y,S,A){return u().isString(y)?(A=u().defaultTo(A,""),u().truncate(y,{length:S,omission:A})):y}}return e.\u0275fac=function(y){return new(y||e)},e.\u0275pipe=p.Yjl({name:"truncate",type:e,pure:!0}),e})()},10545:(v,T,i)=>{"use strict";i.d(T,{m:()=>d});var r=i(23815),u=i.n(r),p=i(74788);let d=(()=>{class e{transform(y){return u().upperFirst(y)}}return e.\u0275fac=function(y){return new(y||e)},e.\u0275pipe=p.Yjl({name:"upperFirst",type:e,pure:!0}),e})()},49083:(v,T,i)=>{"use strict";function r(ee,ue){function ae(){return!ae.pred.apply(ae.thisArg,arguments)}return ae.pred=ee,ae.thisArg=ue,ae}i.d(T,{r:()=>K});var u=i(87444),p=i(45435),d=i(18891),_=i(22759),y=i(79765),S=i(85345);class N{constructor(ue){this.notifier=ue}call(ue,ae){return ae.subscribe(new L(ue,this.notifier,ae))}}class L extends S.Ds{constructor(ue,ae,H){super(ue),this.notifier=ae,this.source=H,this.sourceIsBeingSubscribedTo=!0}notifyNext(){this.sourceIsBeingSubscribedTo=!0,this.source.subscribe(this)}notifyComplete(){if(!1===this.sourceIsBeingSubscribedTo)return super.complete()}complete(){if(this.sourceIsBeingSubscribedTo=!1,!this.isStopped){if(this.retries||this.subscribeToRetries(),!this.retriesSubscription||this.retriesSubscription.closed)return super.complete();this._unsubscribeAndRecycle(),this.notifications.next(void 0)}}_unsubscribe(){const{notifications:ue,retriesSubscription:ae}=this;ue&&(ue.unsubscribe(),this.notifications=void 0),ae&&(ae.unsubscribe(),this.retriesSubscription=void 0),this.retries=void 0}_unsubscribeAndRecycle(){const{_unsubscribe:ue}=this;return this._unsubscribe=null,super._unsubscribeAndRecycle(),this._unsubscribe=ue,this}subscribeToRetries(){let ue;this.notifications=new y.xQ;try{const{notifier:ae}=this;ue=ae(this.notifications)}catch(ae){return super.complete()}this.retries=ue,this.retriesSubscription=(0,S.ft)(ue,new S.IY(this))}}var Z=i(47349),J=i(46782);function K(){const ee=(0,_.R)(document,"visibilitychange").pipe((0,Z.d)({refCount:!0,bufferSize:1})),[ue,ae]=function(ee,ue,ae){return[(0,p.h)(ue,undefined)(new d.y((0,u.s)(ee))),(0,p.h)(r(ue,undefined))(new d.y((0,u.s)(ee)))]}(ee,()=>"visible"===document.visibilityState);return function(H){return H.pipe((0,J.R)(ae),function(ee){return ue=>ue.lift(new N(ee))}(()=>ue))}}},45510:(v,T,i)=>{"use strict";i.d(T,{P:()=>d});var r=i(74788),u=i(6283),p=i(74937);let d=(()=>{class e{constructor(y,S){this.router=y,this.authStorageService=S}canActivate(y,S){return!!this.authStorageService.isLoggedIn()||(this.router.navigate(["/login"],{queryParams:{returnUrl:S.url}}),!1)}canActivateChild(y,S){return this.canActivate(y,S)}}return e.\u0275fac=function(y){return new(y||e)(r.LFG(u.F0),r.LFG(p.j))},e.\u0275prov=r.Yz7({token:e,factory:e.\u0275fac,providedIn:"root"}),e})()},74937:(v,T,i)=>{"use strict";i.d(T,{j:()=>e});var r=i(26215);class u{constructor(y=[]){["read","create","update","delete"].forEach(S=>this[S]=y.includes(S))}}class p{constructor(y){this.hosts=new u(y.hosts),this.configOpt=new u(y["config-opt"]),this.pool=new u(y.pool),this.osd=new u(y.osd),this.monitor=new u(y.monitor),this.rbdImage=new u(y["rbd-image"]),this.iscsi=new u(y.iscsi),this.rbdMirroring=new u(y["rbd-mirroring"]),this.rgw=new u(y.rgw),this.cephfs=new u(y.cephfs),this.manager=new u(y.manager),this.log=new u(y.log),this.user=new u(y.user),this.grafana=new u(y.grafana),this.prometheus=new u(y.prometheus),this.nfs=new u(y["nfs-ganesha"])}}var d=i(74788);let e=(()=>{class _{constructor(){this.isPwdDisplayedSource=new r.X(!1),this.isPwdDisplayed$=this.isPwdDisplayedSource.asObservable()}set(S,A={},N=!1,L=null,Z=!1){localStorage.setItem("dashboard_username",S),localStorage.setItem("dashboard_permissions",JSON.stringify(new p(A))),localStorage.setItem("user_pwd_expiration_date",String(L)),localStorage.setItem("user_pwd_update_required",String(Z)),localStorage.setItem("sso",String(N))}remove(){localStorage.removeItem("dashboard_username"),localStorage.removeItem("user_pwd_expiration_data"),localStorage.removeItem("user_pwd_update_required")}isLoggedIn(){return null!==localStorage.getItem("dashboard_username")}getUsername(){return localStorage.getItem("dashboard_username")}getPermissions(){return JSON.parse(localStorage.getItem("dashboard_permissions")||JSON.stringify(new p({})))}getPwdExpirationDate(){return Number(localStorage.getItem("user_pwd_expiration_date"))}getPwdUpdateRequired(){return"true"===localStorage.getItem("user_pwd_update_required")}isSSO(){return"true"===localStorage.getItem("sso")}}return _.\u0275fac=function(S){return new(S||_)},_.\u0275prov=d.Yz7({token:_,factory:_.\u0275fac,providedIn:"root"}),_})()},72625:(v,T,i)=>{"use strict";i.d(T,{R:()=>S});var r=i(26215),u=i(45435),p=i(88002),d=i(28049),e=i(74255),_=i(74788),y=i(24310);let S=(()=>{class A{constructor(L,Z){this.summaryservice=L,this.cephReleaseNamePipe=Z,this.releaseDataSource=new r.X(null),this.releaseData$=this.releaseDataSource.asObservable(),this.summaryservice.subscribeOnce(J=>{const K=this.cephReleaseNamePipe.transform(J.version);this.releaseDataSource.next(K)})}urlGenerator(L,Z="master"){const K=`https://docs.ceph.com/en/${"master"===Z?"latest":Z}/`,ee="https://ceph.io/";return{iscsi:`${K}mgr/dashboard/#enabling-iscsi-management`,prometheus:`${K}mgr/dashboard/#enabling-prometheus-alerting`,"nfs-ganesha":`${K}mgr/dashboard/#configuring-nfs-ganesha-in-the-dashboard`,"rgw-nfs":`${K}radosgw/nfs`,rgw:`${K}mgr/dashboard/#enabling-the-object-gateway-management-frontend`,dashboard:`${K}mgr/dashboard`,grafana:`${K}mgr/dashboard/#enabling-the-embedding-of-grafana-dashboards`,orch:`${K}mgr/orchestrator`,pgs:`${ee}pgcalc`,help:`${ee}help/`,security:`${ee}security/`,trademarks:`${ee}legal-page/trademarks/`,"dashboard-landing-page-status":`${K}mgr/dashboard/#dashboard-landing-page-status`,"dashboard-landing-page-performance":`${K}mgr/dashboard/#dashboard-landing-page-performance`,"dashboard-landing-page-capacity":`${K}mgr/dashboard/#dashboard-landing-page-capacity`}[L]}subscribeOnce(L,Z,J){return this.releaseData$.pipe((0,u.h)(K=>!!K),(0,p.U)(K=>this.urlGenerator(L,K)),(0,d.P)()).subscribe(Z,J)}}return A.\u0275fac=function(L){return new(L||A)(_.LFG(e.J),_.LFG(y.t))},A.\u0275prov=_.Yz7({token:A,factory:A.\u0275fac,providedIn:"root"}),A})()},4222:(v,T,i)=>{"use strict";i.d(T,{T:()=>e});var r=i(88002),u=i(26504),p=i(74788),d=i(89154);let e=(()=>{class _{constructor(S){this.featureToggles=S}canActivate(S){return this.featureToggles.get().pipe((0,r.U)(A=>{if(!1===A[S.routeConfig.path])throw new u._2;return!0}))}canActivateChild(S){return this.canActivate(S.parent)}}return _.\u0275fac=function(S){return new(S||_)(p.LFG(d.l))},_.\u0275prov=p.Yz7({token:_,factory:_.\u0275fac,providedIn:"root"}),_})()},89154:(v,T,i)=>{"use strict";i.d(T,{l:()=>e});var r=i(74788),u=i(58497),p=i(46947);let e=(()=>{class _{constructor(S,A){this.http=S,this.timerService=A,this.API_URL="api/feature_toggles",this.REFRESH_INTERVAL=3e4,this.featureToggleMap$=this.timerService.get(()=>this.http.get(this.API_URL),this.REFRESH_INTERVAL)}get(){return this.featureToggleMap$}}return _.\u0275fac=function(S){return new(S||_)(r.LFG(u.eN),r.LFG(p.f))},_.\u0275prov=r.Yz7({token:_,factory:_.\u0275fac,providedIn:"root"}),_})()},28211:(v,T,i)=>{"use strict";i.d(T,{H:()=>d});var r=i(23815),u=i.n(r),p=i(74788);let d=(()=>{class e{format_number(y,S,A,N=1){if(u().isString(y)&&(y=Number(y)),!u().isNumber(y))return"-";let L=y<1?0:Math.floor(Math.log(y)/Math.log(S));L=L>=A.length?A.length-1:L;let Z=u().round(y/Math.pow(S,L),N).toString();return""===Z?"-":(""!==A[L]&&(Z=`${Z} ${A[L]}`),Z)}toBytes(y,S=null){const N=["b","k","m","g","t","p","e","z","y"],L=RegExp("^(\\d+(.\\d+)?) ?(["+N.join("")+"]?(b|ib|B/s)?)?$","i").exec(y);if(null===L)return S;let Z=parseFloat(L[1]);return u().isString(L[3])&&(Z*=Math.pow(1024,N.indexOf(L[3].toLowerCase()[0]))),Math.round(Z)}toMilliseconds(y){const A=/^\s*(\d+)\s*(ms)?\s*$/i.exec(y);return null!==A?+A[1]:0}toIops(y){const A=/^\s*(\d+)\s*(IOPS)?\s*$/i.exec(y);return null!==A?+A[1]:0}}return e.\u0275fac=function(y){return new(y||e)},e.\u0275prov=p.Yz7({token:e,factory:e.\u0275fac,providedIn:"root"}),e})()},63285:(v,T,i)=>{"use strict";i.d(T,{Z:()=>p});var r=i(74788),u=i(38549);let p=(()=>{class d{constructor(_){this.modal=_}show(_,y,S){const A=this.modal.open(_,S);return y&&Object.assign(A.componentInstance,y),A}dismissAll(){this.modal.dismissAll()}hasOpenModals(){return this.modal.hasOpenModals()}}return d.\u0275fac=function(_){return new(_||d)(r.LFG(u.FF))},d.\u0275prov=r.Yz7({token:d,factory:d.\u0275fac,providedIn:"root"}),d})()},54462:(v,T,i)=>{"use strict";i.d(T,{P:()=>A});var r=i(25917),u=i(88002),p=i(5304),d=i(65862),e=i(74788),_=i(58497),y=i(6283),S=i(7273);let A=(()=>{class N{constructor(Z,J,K){this.http=Z,this.router=J,this.mgrModuleService=K}canActivate(Z){return this.doCheck(Z)}canActivateChild(Z){return this.doCheck(Z)}doCheck(Z){if(Z.url.length>0&&N.ALLOWLIST.includes(Z.url[0].path))return(0,r.of)(!0);const J=Z.data.moduleStatusGuardConfig;let K=!1;return J.backend&&this.mgrModuleService.getConfig("orchestrator").subscribe(ee=>{K=J.backend===ee.orchestrator},()=>(this.router.navigate([J.redirectTo]),(0,r.of)(!1))),this.http.get(`ui-api/${J.uiApiPath}/status`).pipe((0,u.U)(ee=>(!ee.available&&!K&&this.router.navigate([J.redirectTo||""],{state:{header:J.header,message:ee.message,section:J.section,section_info:J.section_info,button_name:J.button_name,button_route:J.button_route,button_title:J.button_title,uiConfig:J.uiConfig,uiApiPath:J.uiApiPath,icon:d.P.wrench,component:J.component}}),ee.available)),(0,p.K)(()=>(this.router.navigate([J.redirectTo]),(0,r.of)(!1))))}}return N.ALLOWLIST=["501"],N.\u0275fac=function(Z){return new(Z||N)(e.LFG(_.eN),e.LFG(y.F0),e.LFG(S.N))},N.\u0275prov=e.Yz7({token:N,factory:N.\u0275fac,providedIn:"root"}),N})()},97161:(v,T,i)=>{"use strict";i.d(T,{g:()=>L});var r=i(23815),u=i.n(r),p=i(26215),d=i(79765),e=i(18001),_=i(61355),y=i(74788),S=i(91376),A=i(68879),N=i(96102);let L=(()=>{class Z{constructor(K,ee,ue){this.toastr=K,this.taskMessageService=ee,this.cdDatePipe=ue,this.hideToasties=!1,this.dataSource=new p.X([]),this.data$=this.dataSource.asObservable(),this.sidebarSubject=new d.xQ,this.queued=[],this.KEY="cdNotifications";const ae=localStorage.getItem(this.KEY);let H=[];u().isString(ae)&&(H=JSON.parse(ae,(se,Ee)=>u().isPlainObject(Ee)?u().assign(new _.e,Ee):Ee)),this.dataSource.next(H)}removeAll(){localStorage.removeItem(this.KEY),this.dataSource.next([])}remove(K){const ee=this.dataSource.getValue();ee.splice(K,1),this.dataSource.next(ee),localStorage.setItem(this.KEY,JSON.stringify(ee))}save(K){const ee=this.dataSource.getValue();for(ee.push(K),ee.sort((ue,ae)=>ue.timestamp>ae.timestamp?-1:1);ee.length>10;)ee.pop();this.dataSource.next(ee),localStorage.setItem(this.KEY,JSON.stringify(ee))}show(K,ee,ue,ae,H){return window.setTimeout(()=>{let se;se=u().isFunction(K)?K():u().isObject(K)?K:new _.T(K,ee,ue,ae,H),this.queueToShow(se)},10)}queueToShow(K){this.cancel(this.queuedTimeoutId),this.queued.find(ee=>u().isEqual(ee,K))||this.queued.push(K),this.queuedTimeoutId=window.setTimeout(()=>{this.showQueued()},500)}showQueued(){this.getUnifiedTitleQueue().forEach(K=>{const ee=new _.e(K);ee.isFinishedTask||this.save(ee),this.showToasty(ee)})}getUnifiedTitleQueue(){return Object.values(this.queueShiftByTitle()).map(K=>{const ee=K[0];return K.length>1&&(ee.message="<ul>"+K.map(ue=>`<li>${ue.message}</li>`).join("")+"</ul>"),ee})}queueShiftByTitle(){const K={};let ee;for(;ee=this.queued.shift();)K[ee.title]||(K[ee.title]=[]),K[ee.title].push(ee);return K}showToasty(K){this.hideToasties||this.toastr[["error","info","success"][K.type]]((K.message?K.message+"<br>":"")+this.renderTimeAndApplicationHtml(K),K.title,K.options)}renderTimeAndApplicationHtml(K){return`<small class="date">${this.cdDatePipe.transform(K.timestamp)}</small><i class="float-right custom-icon ${K.applicationClass}" title="${K.application}"></i>`}notifyTask(K,ee=!0){const ue=this.finishedTaskToNotification(K,ee);return ue.isFinishedTask=!0,this.show(ue)}finishedTaskToNotification(K,ee=!0){let ue;return ue=K.success&&ee?new _.T(e.k.success,this.taskMessageService.getSuccessTitle(K)):new _.T(e.k.error,this.taskMessageService.getErrorTitle(K),this.taskMessageService.getErrorMessage(K)),ue.isFinishedTask=!0,ue}cancel(K){window.clearTimeout(K)}suspendToasties(K){this.hideToasties=K}toggleSidebar(K=!1){this.sidebarSubject.next(K)}}return Z.\u0275fac=function(K){return new(K||Z)(y.LFG(S._W),y.LFG(A.p),y.LFG(N.N))},Z.\u0275prov=y.Yz7({token:Z,factory:Z.\u0275fac,providedIn:"root"}),Z})()},33888:(v,T,i)=>{"use strict";i.d(T,{q:()=>y});var r=i(23815),u=i.n(r),p=i(88002),d=i(9837);class e{constructor(A){this.pwdPolicyEnabled=A.pwd_policy_enabled,this.pwdPolicyMinLength=A.pwd_policy_min_length,this.pwdPolicyCheckLengthEnabled=A.pwd_policy_check_length_enabled,this.pwdPolicyCheckOldpwdEnabled=A.pwd_policy_check_oldpwd_enabled,this.pwdPolicyCheckUsernameEnabled=A.pwd_policy_check_username_enabled,this.pwdPolicyCheckExclusionListEnabled=A.pwd_policy_check_exclusion_list_enabled,this.pwdPolicyCheckRepetitiveCharsEnabled=A.pwd_policy_check_repetitive_chars_enabled,this.pwdPolicyCheckSequentialCharsEnabled=A.pwd_policy_check_sequential_chars_enabled,this.pwdPolicyCheckComplexityEnabled=A.pwd_policy_check_complexity_enabled}}var _=i(74788);let y=(()=>{class S{constructor(N){this.settingsService=N}getHelpText(){return this.settingsService.getStandardSettings().pipe((0,p.U)(N=>{const L=new e(N);let Z=[];if(L.pwdPolicyEnabled){Z.push("Required rules for passwords:");const J={pwdPolicyCheckLengthEnabled:"Must contain at least " + L.pwdPolicyMinLength + " characters",pwdPolicyCheckOldpwdEnabled:"Must not be the same as the previous one",pwdPolicyCheckUsernameEnabled:"Cannot contain the username",pwdPolicyCheckExclusionListEnabled:"Cannot contain any configured keyword",pwdPolicyCheckRepetitiveCharsEnabled:"Cannot contain any repetitive characters e.g. \"aaa\"",pwdPolicyCheckSequentialCharsEnabled:"Cannot contain any sequential characters e.g. \"abc\"",pwdPolicyCheckComplexityEnabled:"Must consist of characters from the following groups:\n * Alphabetic a-z, A-Z\n * Numbers 0-9\n * Special chars: !\"#$%& '()*+,-./:;<=>?@[\\]^_`{{|}}~\n * Any other characters (signs)"};Z=Z.concat(u().keys(J).filter(K=>u().get(L,K)).map(K=>"- "+u().get(J,K)))}return Z.join("\n")}))}mapCreditsToCssClass(N){let L="very-strong";return N<10?L="too-weak":N<15?L="weak":N<20?L="ok":N<25&&(L="strong"),L}}return S.\u0275fac=function(N){return new(N||S)(_.LFG(d.g))},S.\u0275prov=_.Yz7({token:S,factory:S.\u0275fac,providedIn:"root"}),S})()},34089:(v,T,i)=>{"use strict";i.d(T,{n:()=>p});var r=i(30633),u=i(74788);let p=(()=>{class d{constructor(){this.sections=[{heading:"Quality of Service",class:"quality-of-service",options:[{name:"rbd_qos_bps_limit",displayName:"BPS Limit",description:"The desired limit of IO bytes per second.",type:r.r.bps},{name:"rbd_qos_iops_limit",displayName:"IOPS Limit",description:"The desired limit of IO operations per second.",type:r.r.iops},{name:"rbd_qos_read_bps_limit",displayName:"Read BPS Limit",description:"The desired limit of read bytes per second.",type:r.r.bps},{name:"rbd_qos_read_iops_limit",displayName:"Read IOPS Limit",description:"The desired limit of read operations per second.",type:r.r.iops},{name:"rbd_qos_write_bps_limit",displayName:"Write BPS Limit",description:"The desired limit of write bytes per second.",type:r.r.bps},{name:"rbd_qos_write_iops_limit",displayName:"Write IOPS Limit",description:"The desired limit of write operations per second.",type:r.r.iops},{name:"rbd_qos_bps_burst",displayName:"BPS Burst",description:"The desired burst limit of IO bytes.",type:r.r.bps},{name:"rbd_qos_iops_burst",displayName:"IOPS Burst",description:"The desired burst limit of IO operations.",type:r.r.iops},{name:"rbd_qos_read_bps_burst",displayName:"Read BPS Burst",description:"The desired burst limit of read bytes.",type:r.r.bps},{name:"rbd_qos_read_iops_burst",displayName:"Read IOPS Burst",description:"The desired burst limit of read operations.",type:r.r.iops},{name:"rbd_qos_write_bps_burst",displayName:"Write BPS Burst",description:"The desired burst limit of write bytes.",type:r.r.bps},{name:"rbd_qos_write_iops_burst",displayName:"Write IOPS Burst",description:"The desired burst limit of write operations.",type:r.r.iops}]}]}static getOptionsFromSections(_){return _.map(y=>y.options).reduce((y,S)=>y.concat(S))}filterConfigOptionsByName(_){return d.getOptionsFromSections(this.sections).filter(y=>y.name===_)}getOptionValueByName(_,y,S=""){const A=this.filterConfigOptionsByName(_);return 1===A.length?A.pop()[y]:S}getWritableSections(){return this.sections.map(_=>(_.options=_.options.filter(y=>!y.readOnly),_))}getOptionFields(){return d.getOptionsFromSections(this.sections)}getWritableOptionFields(){return d.getOptionsFromSections(this.getWritableSections())}getOptionByName(_){return this.filterConfigOptionsByName(_).pop()}getDisplayName(_){return this.getOptionValueByName(_,"displayName")}getDescription(_){return this.getOptionValueByName(_,"description")}}return d.\u0275fac=function(_){return new(_||d)},d.\u0275prov=u.Yz7({token:d,factory:d.\u0275fac,providedIn:"root"}),d})()},74255:(v,T,i)=>{"use strict";i.d(T,{J:()=>A});var r=i(23815),u=i.n(r),p=i(26215),d=i(45435),e=i(28049),_=i(74788),y=i(58497),S=i(46947);let A=(()=>{class N{constructor(Z,J){this.http=Z,this.timerService=J,this.REFRESH_INTERVAL=5e3,this.summaryDataSource=new p.X(null),this.summaryData$=this.summaryDataSource.asObservable()}startPolling(){return this.timerService.get(()=>this.retrieveSummaryObservable(),this.REFRESH_INTERVAL).subscribe(this.retrieveSummaryObserver())}refresh(){return this.retrieveSummaryObservable().subscribe(this.retrieveSummaryObserver())}retrieveSummaryObservable(){return this.http.get("api/summary")}retrieveSummaryObserver(){return Z=>{this.summaryDataSource.next(Z)}}subscribeOnce(Z,J){return this.summaryData$.pipe((0,d.h)(K=>!!K),(0,e.P)()).subscribe(Z,J)}subscribe(Z,J){return this.summaryData$.pipe((0,d.h)(K=>!!K)).subscribe(Z,J)}addRunningTask(Z){const J=this.summaryDataSource.getValue();!J||(u().isArray(J.executing_tasks)?J.executing_tasks.find(ee=>ee.name===Z.name&&u().isEqual(ee.metadata,Z.metadata))||J.executing_tasks.push(Z):J.executing_tasks=[Z],this.summaryDataSource.next(J))}}return N.\u0275fac=function(Z){return new(Z||N)(_.LFG(y.eN),_.LFG(S.f))},N.\u0275prov=_.Yz7({token:N,factory:N.\u0275fac,providedIn:"root"}),N})()},38047:(v,T,i)=>{"use strict";i.d(T,{j:()=>d});var r=i(74255),u=i(74788),p=i(68879);let d=(()=>{class e{constructor(y,S){this.taskMessageService=y,this.summaryService=S}init(y,S,A,N,L,Z,J){this.getUpdate=y,this.preProcessing=S,this.setList=A,this.onFetchError=N,this.taskFilter=L,this.itemFilter=Z,this.builders=J||{},this.summaryDataSubscription=this.summaryService.subscribe(K=>{this.summary=K,this.fetch()},this.onFetchError)}fetch(y=null){this.getUpdate(y).subscribe(S=>{var A;this.updateData(S,null===(A=this.summary)||void 0===A?void 0:A.executing_tasks.filter(this.taskFilter))},this.onFetchError)}updateData(y,S){const A=this.preProcessing?this.preProcessing(y):y;this.addMissing(A,S),A.forEach(N=>{const L=S.filter(Z=>this.itemFilter(N,Z));N.cdExecuting=this.getTaskAction(L)}),this.setList(A)}addMissing(y,S){const A=this.builders.default;null==S||S.forEach(N=>{const L=y.find(J=>this.itemFilter(J,N)),Z=this.builders[N.name];!L&&(Z||A)&&y.push(Z?Z(N.metadata):A(N.metadata))})}getTaskAction(y){if(0!==y.length)return y.map(S=>{const A=S.progress?` ${S.progress}%`:"";return this.taskMessageService.getRunningText(S)+"..."+A}).join(", ")}ngOnDestroy(){this.summaryDataSubscription&&this.summaryDataSubscription.unsubscribe()}}return e.\u0275fac=function(y){return new(y||e)(u.LFG(p.p),u.LFG(r.J))},e.\u0275prov=u.Yz7({token:e,factory:e.\u0275fac}),e})()},71099:(v,T,i)=>{"use strict";i.d(T,{k:()=>e});var r=i(23815),u=i.n(r),p=i(74788);class d{constructor(y,S,A){this.name=y,this.metadata=S,this.onTaskFinished=A}}let e=(()=>{class _{constructor(){this.subscriptions=[]}init(S){return S.subscribe(A=>{const N=A.executing_tasks,L=A.finished_tasks,Z=[];for(const J of this.subscriptions){const K=this._getTask(J,L),ee=this._getTask(J,N);null!==K&&null===ee&&J.onTaskFinished(K),null!==ee&&Z.push(J),this.subscriptions=Z}})}subscribe(S,A,N){this.subscriptions.push(new d(S,A,N))}_getTask(S,A){for(const N of A)if(N.name===S.name&&u().isEqual(N.metadata,S.metadata))return N;return null}}return _.\u0275fac=function(S){return new(S||_)},_.\u0275prov=p.Yz7({token:_,factory:_.\u0275fac,providedIn:"root"}),_})()},68879:(v,T,i)=>{"use strict";i.d(T,{p:()=>_});var r=(()=>{return(y=r||(r={})).auth="Login",y.cephfs="CephFS",y.rbd="RBD",y.pool="Pool",y.osd="OSD",y.role="Role",y.user="User",r;var y})(),u=i(19358),p=i(74788);class d{constructor(S,A,N){this.running=S,this.failure=A,this.success=N}}class e{constructor(S,A,N){this.operation=S,this.involves=A,this.errors=N||(()=>({}))}failure(S){return "Failed to " + this.operation.failure + " " + this.involves(S) + ""}running(S){return`${this.operation.running} ${this.involves(S)}`}success(S){return`${this.operation.success} ${this.involves(S)}`}}let _=(()=>{class y{constructor(){this.defaultMessage=this.newTaskMessage(new d("Executing","execute","Executed"),A=>A&&(r[A.component]||A.component)||"unknown task",()=>({})),this.commonOperations={create:new d("Creating","create","Created"),update:new d("Updating","update","Updated"),delete:new d("Deleting","delete","Deleted"),add:new d("Adding","add","Added"),remove:new d("Removing","remove","Removed"),import:new d("Importing","import","Imported")},this.rbd={default:A=>"RBD '" + A.image_spec + "'",create:A=>{const N=new u.N(A.pool_name,A.namespace,A.image_name).toString();return "RBD '" + N + "'"},child:A=>{const N=new u.N(A.child_pool_name,A.child_namespace,A.child_image_name).toString();return "RBD '" + N + "'"},destination:A=>{const N=new u.N(A.dest_pool_name,A.dest_namespace,A.dest_image_name).toString();return "RBD '" + N + "'"},snapshot:A=>"RBD snapshot '" + A.image_spec + "@" + A.snapshot_name + "'"},this.rbd_mirroring={site_name:()=>"mirroring site name",bootstrap:()=>"bootstrap token",pool:A=>"mirror mode for pool '" + A.pool_name + "'",pool_peer:A=>"mirror peer for pool '" + A.pool_name + "'"},this.grafana={update_dashboards:()=>"all dashboards"},this.messages={"host/add":this.newTaskMessage(this.commonOperations.add,A=>this.host(A)),"host/remove":this.newTaskMessage(this.commonOperations.remove,A=>this.host(A)),"host/identify_device":this.newTaskMessage(new d("Identifying","identify","Identified"),A=>"device '" + A.device + "' on host '" + A.hostname + "'"),"osd/create":this.newTaskMessage(this.commonOperations.create,A=>"OSDs (DriveGroups: " + A.tracking_id + ")"),"osd/delete":this.newTaskMessage(this.commonOperations.delete,A=>this.osd(A)),"pool/create":this.newTaskMessage(this.commonOperations.create,A=>this.pool(A),A=>({17:"Name is already used by " + this.pool(A) + "."})),"pool/edit":this.newTaskMessage(this.commonOperations.update,A=>this.pool(A),A=>({17:"Name is already used by " + this.pool(A) + "."})),"pool/delete":this.newTaskMessage(this.commonOperations.delete,A=>this.pool(A)),"ecp/create":this.newTaskMessage(this.commonOperations.create,A=>this.ecp(A),A=>({17:"Name is already used by " + this.ecp(A) + "."})),"ecp/delete":this.newTaskMessage(this.commonOperations.delete,A=>this.ecp(A)),"crushRule/create":this.newTaskMessage(this.commonOperations.create,A=>this.crushRule(A),A=>({17:"Name is already used by " + this.crushRule(A) + "."})),"crushRule/delete":this.newTaskMessage(this.commonOperations.delete,A=>this.crushRule(A)),"rbd/create":this.newTaskMessage(this.commonOperations.create,this.rbd.create,A=>({17:"Name is already used by " + this.rbd.create(A) + "."})),"rbd/edit":this.newTaskMessage(this.commonOperations.update,this.rbd.default,A=>({17:"Name is already used by " + this.rbd.default(A) + "."})),"rbd/delete":this.newTaskMessage(this.commonOperations.delete,this.rbd.default,A=>({16:"" + this.rbd.default(A) + " is busy.",39:"" + this.rbd.default(A) + " contains snapshots."})),"rbd/clone":this.newTaskMessage(new d("Cloning","clone","Cloned"),this.rbd.child,A=>({17:"Name is already used by " + this.rbd.child(A) + ".",22:"Snapshot of " + this.rbd.child(A) + " must be protected."})),"rbd/copy":this.newTaskMessage(new d("Copying","copy","Copied"),this.rbd.destination,A=>({17:"Name is already used by " + this.rbd.destination(A) + "."})),"rbd/flatten":this.newTaskMessage(new d("Flattening","flatten","Flattened"),this.rbd.default),"rbd/snap/create":this.newTaskMessage(this.commonOperations.create,this.rbd.snapshot,A=>({17:"Name is already used by " + this.rbd.snapshot(A) + "."})),"rbd/snap/edit":this.newTaskMessage(this.commonOperations.update,this.rbd.snapshot,A=>({16:"Cannot unprotect " + this.rbd.snapshot(A) + " because it contains child images."})),"rbd/snap/delete":this.newTaskMessage(this.commonOperations.delete,this.rbd.snapshot,A=>({16:"Cannot delete " + this.rbd.snapshot(A) + " because it's protected."})),"rbd/snap/rollback":this.newTaskMessage(new d("Rolling back","rollback","Rolled back"),this.rbd.snapshot),"rbd/trash/move":this.newTaskMessage(new d("Moving","move","Moved"),A=>"image '" + A.image_spec + "' to trash",()=>({2:"Could not find image."})),"rbd/trash/restore":this.newTaskMessage(new d("Restoring","restore","Restored"),A=>"image '" + A.image_id_spec + "' into '" + A.new_image_name + "'",A=>({17:"Image name '" + A.new_image_name + "' is already in use."})),"rbd/trash/remove":this.newTaskMessage(new d("Deleting","delete","Deleted"),A=>"image '" + A.image_id_spec + "'"),"rbd/trash/purge":this.newTaskMessage(new d("Purging","purge","Purged"),A=>{let N="all pools";return A.pool_name&&(N=`'${A.pool_name}'`),"images from " + N + ""}),"rbd/mirroring/site_name/edit":this.newTaskMessage(this.commonOperations.update,this.rbd_mirroring.site_name,()=>({})),"rbd/mirroring/bootstrap/create":this.newTaskMessage(this.commonOperations.create,this.rbd_mirroring.bootstrap,()=>({})),"rbd/mirroring/bootstrap/import":this.newTaskMessage(this.commonOperations.import,this.rbd_mirroring.bootstrap,()=>({})),"rbd/mirroring/pool/edit":this.newTaskMessage(this.commonOperations.update,this.rbd_mirroring.pool,()=>({16:"Cannot disable mirroring because it contains a peer."})),"rbd/mirroring/peer/add":this.newTaskMessage(this.commonOperations.create,this.rbd_mirroring.pool_peer,()=>({})),"rbd/mirroring/peer/edit":this.newTaskMessage(this.commonOperations.update,this.rbd_mirroring.pool_peer,()=>({})),"rbd/mirroring/peer/delete":this.newTaskMessage(this.commonOperations.delete,this.rbd_mirroring.pool_peer,()=>({})),"iscsi/target/create":this.newTaskMessage(this.commonOperations.create,A=>this.iscsiTarget(A)),"iscsi/target/edit":this.newTaskMessage(this.commonOperations.update,A=>this.iscsiTarget(A)),"iscsi/target/delete":this.newTaskMessage(this.commonOperations.delete,A=>this.iscsiTarget(A)),"nfs/create":this.newTaskMessage(this.commonOperations.create,A=>this.nfs(A)),"nfs/edit":this.newTaskMessage(this.commonOperations.update,A=>this.nfs(A)),"nfs/delete":this.newTaskMessage(this.commonOperations.delete,A=>this.nfs(A)),"grafana/dashboards/update":this.newTaskMessage(this.commonOperations.update,this.grafana.update_dashboards,()=>({})),"service/create":this.newTaskMessage(this.commonOperations.create,A=>this.service(A)),"service/edit":this.newTaskMessage(this.commonOperations.update,A=>this.service(A)),"service/delete":this.newTaskMessage(this.commonOperations.delete,A=>this.service(A))}}newTaskMessage(A,N,L){return new e(A,N,L)}host(A){return "host '" + A.hostname + "'"}osd(A){return "OSD '" + A.svc_id + "'"}pool(A){return "pool '" + A.pool_name + "'"}ecp(A){return "erasure code profile '" + A.name + "'"}crushRule(A){return "crush rule '" + A.name + "'"}iscsiTarget(A){return "target '" + A.target_iqn + "'"}nfs(A){return "NFS '" + A.cluster_id + ":" + (A.export_id ? A.export_id : A.path) + "'"}service(A){return "Service '" + A.service_name + "'"}_getTaskTitle(A){return A.name&&A.name.startsWith("progress/")?this.newTaskMessage(new d(A.name.replace("progress/",""),"",A.name.replace("progress/","")),N=>""):this.messages[A.name]||this.defaultMessage}getSuccessTitle(A){return this._getTaskTitle(A).success(A.metadata)}getErrorMessage(A){return this._getTaskTitle(A).errors(A.metadata)[A.exception.code]||A.exception.detail}getErrorTitle(A){return this._getTaskTitle(A).failure(A.metadata)}getRunningTitle(A){return this._getTaskTitle(A).running(A.metadata)}getRunningText(A){return this._getTaskTitle(A).operation.running}}return y.\u0275fac=function(A){return new(A||y)},y.\u0275prov=p.Yz7({token:y,factory:y.\u0275fac,providedIn:"root"}),y})()},32337:(v,T,i)=>{"use strict";i.d(T,{P:()=>N});var r=i(18891),u=i(18001),p=i(61355),d=i(60737),e=i(97161),_=i(74255),y=i(71099),S=i(74788),A=i(68879);let N=(()=>{class L{constructor(J,K,ee,ue){this.notificationService=J,this.summaryService=K,this.taskMessageService=ee,this.taskManagerService=ue}wrapTaskAroundCall({task:J,call:K}){return new r.y(ee=>{K.subscribe(ue=>{202===ue.status?this._handleExecutingTasks(J):(this.summaryService.refresh(),J.success=!0,this.notificationService.notifyTask(J))},ue=>{J.success=!1,J.exception=ue.error,ee.error(ue)},()=>{ee.complete()})})}_handleExecutingTasks(J){const K=new p.T(u.k.info,this.taskMessageService.getRunningTitle(J));K.isFinishedTask=!0,this.notificationService.show(K);const ee=new d.o(J.name,J.metadata);this.summaryService.addRunningTask(ee),this.taskManagerService.subscribe(ee.name,ee.metadata,ue=>{this.notificationService.notifyTask(ue)})}}return L.\u0275fac=function(J){return new(J||L)(S.LFG(e.g),S.LFG(_.J),S.LFG(A.p),S.LFG(y.k))},L.\u0275prov=S.Yz7({token:L,factory:L.\u0275fac,providedIn:"root"}),L})()},46947:(v,T,i)=>{"use strict";i.d(T,{f:()=>Z});var r=i(46797),u=i(59746),p=i(43190),d=i(47349),e=i(49083),_=i(74788),y=i(33637);class S{constructor(K){this.zone=K,this.scheduler=y.z}now(){return this.scheduler.now()}}let A=(()=>{class J extends S{constructor(ee){super(ee)}schedule(...ee){return this.zone.runOutsideAngular(()=>this.scheduler.schedule.apply(this.scheduler,ee))}}return J.\u0275fac=function(ee){return new(ee||J)(_.LFG(_.R0b))},J.\u0275prov=_.Yz7({token:J,factory:J.\u0275fac,providedIn:"root"}),J})(),N=(()=>{class J extends S{constructor(ee){super(ee)}schedule(...ee){return this.zone.run(()=>this.scheduler.schedule.apply(this.scheduler,ee))}}return J.\u0275fac=function(ee){return new(ee||J)(_.LFG(_.R0b))},J.\u0275prov=_.Yz7({token:J,factory:J.\u0275fac,providedIn:"root"}),J})(),L=(()=>{class J{constructor(ee,ue){this.leave=ee,this.enter=ue}}return J.\u0275fac=function(ee){return new(ee||J)(_.LFG(A),_.LFG(N))},J.\u0275prov=_.Yz7({token:J,factory:J.\u0275fac,providedIn:"root"}),J})(),Z=(()=>{class J{constructor(ee){this.ngZone=ee,this.DEFAULT_REFRESH_INTERVAL=5e3,this.DEFAULT_DUE_TIME=0}get(ee,ue=this.DEFAULT_REFRESH_INTERVAL,ae=this.DEFAULT_DUE_TIME){return(0,r.H)(ae,ue,this.ngZone.leave).pipe((0,u.QV)(this.ngZone.enter),(0,p.w)(ee),(0,d.d)({refCount:!0,bufferSize:1}),(0,e.r)())}}return J.\u0275fac=function(ee){return new(ee||J)(_.LFG(L))},J.\u0275prov=_.Yz7({token:J,factory:J.\u0275fac,providedIn:"root"}),J})()},51847:(v,T,i)=>{"use strict";i.d(T,{F:()=>p});var r=i(12057),u=i(79512);class p{constructor(e){this.base=e}static concatURLSegments(e){return e.reduce(r.Ye.joinWithSlash)}static buildURL(e,..._){return p.concatURLSegments([...e?["/"]:[],..._])}getURL(e,_=!0,...y){return p.buildURL(_,this.base,e,...y)}getCreate(e=!0){return this.getURL(u.MQ.CREATE,e)}getCreateFrom(e,_=!0){return this.getURL(u.MQ.CREATE,_,e)}getDelete(e=!0){return this.getURL(u.MQ.DELETE,e)}getEdit(e,_=!0){return this.getURL(u.MQ.EDIT,_,e)}getUpdate(e,_=!0){return this.getURL(u.MQ.UPDATE,_,e)}getAdd(e=!0){return this.getURL(u.MQ.ADD,e)}getRemove(e=!0){return this.getURL(u.MQ.REMOVE,e)}getRecreate(e,_=!0){return this.getURL(u.MQ.RECREATE,_,e)}}},44466:(v,T,i)=>{"use strict";i.d(T,{m:()=>L});var r=i(12057),u=i(99475),p=i(15626),d=i(2149),e=i(35540),_=i(85953),y=i(45510),S=i(74937),A=i(28211),N=i(74788);let L=(()=>{class Z{}return Z.\u0275fac=function(K){return new(K||Z)},Z.\u0275mod=N.oAB({type:Z}),Z.\u0275inj=N.cJS({providers:[S.j,y.P,A.H,u.P],imports:[[r.ez,_.D,p.K,d.t,e.o],p.K,_.D,d.t,e.o]}),Z})()},92340:(v,T,i)=>{"use strict";i.d(T,{N:()=>r});const r={default_lang:"en-US",production:!0,year:"2023"}},1087:(v,T,i)=>{"use strict";var r={};i.r(r),i.d(r,{JsonPatchError:()=>yc,_areEquals:()=>v0,applyOperation:()=>qm,applyPatch:()=>lg,applyReducer:()=>y3,deepClone:()=>_0,getValueByPointer:()=>g0,validate:()=>WT,validator:()=>m0});var u={};i.r(u),i.d(u,{compare:()=>CA,generate:()=>QT,observe:()=>E3,unobserve:()=>Xv});var p={};i.r(p),i.d(p,{cookie:()=>a8,header:()=>s8,path:()=>r8,query:()=>i8});var d=i(91211),e=i(74788),_=i(12057),y=i(58497),S=i(56083);function A(){return"undefined"!=typeof window&&void 0!==window.document}function N(){return"undefined"!=typeof process&&"[object process]"==={}.toString.call(process)}function L(n){switch(n.length){case 0:return new S.ZN;case 1:return n[0];default:return new S.ZE(n)}}function Z(n,s,t,o,c={},g={}){const C=[],D=[];let P=-1,j=null;if(o.forEach(W=>{const re=W.offset,oe=re==P,me=oe&&j||{};Object.keys(W).forEach(_e=>{let Fe=_e,Re=W[_e];if("offset"!==_e)switch(Fe=s.normalizePropertyName(Fe,C),Re){case S.k1:Re=c[_e];break;case S.l3:Re=g[_e];break;default:Re=s.normalizeStyleValue(_e,Fe,Re,C)}me[Fe]=Re}),oe||D.push(me),j=me,P=re}),C.length){const W="\n - ";throw new Error(`Unable to animate due to the following errors:${W}${C.join(W)}`)}return D}function J(n,s,t,o){switch(s){case"start":n.onStart(()=>o(t&&K(t,"start",n)));break;case"done":n.onDone(()=>o(t&&K(t,"done",n)));break;case"destroy":n.onDestroy(()=>o(t&&K(t,"destroy",n)))}}function K(n,s,t){const o=t.totalTime,g=ee(n.element,n.triggerName,n.fromState,n.toState,s||n.phaseName,null==o?n.totalTime:o,!!t.disabled),C=n._data;return null!=C&&(g._data=C),g}function ee(n,s,t,o,c="",g=0,C){return{element:n,triggerName:s,fromState:t,toState:o,phaseName:c,totalTime:g,disabled:!!C}}function ue(n,s,t){let o;return n instanceof Map?(o=n.get(s),o||n.set(s,o=t)):(o=n[s],o||(o=n[s]=t)),o}function ae(n){const s=n.indexOf(":");return[n.substring(1,s),n.substr(s+1)]}let H=(n,s)=>!1,Ee=(n,s)=>!1,he=(n,s,t)=>[];const De=N();(De||"undefined"!=typeof Element)&&(H=A()?(n,s)=>{for(;s&&s!==document.documentElement;){if(s===n)return!0;s=s.parentNode||s.host}return!1}:(n,s)=>n.contains(s),Ee=(()=>{if(De||Element.prototype.matches)return(n,s)=>n.matches(s);{const n=Element.prototype,s=n.matchesSelector||n.mozMatchesSelector||n.msMatchesSelector||n.oMatchesSelector||n.webkitMatchesSelector;return s?(t,o)=>s.apply(t,[o]):Ee}})(),he=(n,s,t)=>{let o=[];if(t){const c=n.querySelectorAll(s);for(let g=0;g<c.length;g++)o.push(c[g])}else{const c=n.querySelector(s);c&&o.push(c)}return o});let lt=null,Ve=!1;function ze(n){lt||(lt=("undefined"!=typeof document?document.body:null)||{},Ve=!!lt.style&&"WebkitAppearance"in lt.style);let s=!0;return lt.style&&!function(n){return"ebkit"==n.substring(1,6)}(n)&&(s=n in lt.style,!s&&Ve&&(s="Webkit"+n.charAt(0).toUpperCase()+n.substr(1)in lt.style)),s}const Pe=Ee,je=H,He=he;function Vt(n){const s={};return Object.keys(n).forEach(t=>{const o=t.replace(/([a-z])([A-Z])/g,"$1-$2");s[o]=n[t]}),s}let it=(()=>{class n{validateStyleProperty(t){return ze(t)}matchesElement(t,o){return Pe(t,o)}containsElement(t,o){return je(t,o)}query(t,o,c){return He(t,o,c)}computeStyle(t,o,c){return c||""}animate(t,o,c,g,C,D=[],P){return new S.ZN(c,g)}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac}),n})(),tn=(()=>{class n{}return n.NOOP=new it,n})();const Bt="ng-enter",bt="ng-leave",Xt="ng-trigger",Zn=".ng-trigger",Ur="ng-animating",di=".ng-animating";function Lr(n){if("number"==typeof n)return n;const s=n.match(/^(-?[\.\d]+)(m?s)/);return!s||s.length<2?0:Mr(parseFloat(s[1]),s[2])}function Mr(n,s){switch(s){case"s":return 1e3*n;default:return n}}function Kr(n,s,t){return n.hasOwnProperty("duration")?n:function(n,s,t){let c,g=0,C="";if("string"==typeof n){const D=n.match(/^(-?[\.\d]+)(m?s)(?:\s+(-?[\.\d]+)(m?s))?(?:\s+([-a-z]+(?:\(.+?\))?))?$/i);if(null===D)return s.push(`The provided timing value "${n}" is invalid.`),{duration:0,delay:0,easing:""};c=Mr(parseFloat(D[1]),D[2]);const P=D[3];null!=P&&(g=Mr(parseFloat(P),D[4]));const j=D[5];j&&(C=j)}else c=n;if(!t){let D=!1,P=s.length;c<0&&(s.push("Duration values below 0 are not allowed for this animation step."),D=!0),g<0&&(s.push("Delay values below 0 are not allowed for this animation step."),D=!0),D&&s.splice(P,0,`The provided timing value "${n}" is invalid.`)}return{duration:c,delay:g,easing:C}}(n,s,t)}function Nn(n,s={}){return Object.keys(n).forEach(t=>{s[t]=n[t]}),s}function Br(n,s,t={}){if(s)for(let o in n)t[o]=n[o];else Nn(n,t);return t}function Yr(n,s,t){return t?s+":"+t+";":""}function fi(n){let s="";for(let t=0;t<n.style.length;t++){const o=n.style.item(t);s+=Yr(0,o,n.style.getPropertyValue(o))}for(const t in n.style)n.style.hasOwnProperty(t)&&!t.startsWith("_")&&(s+=Yr(0,_i(t),n.style[t]));n.setAttribute("style",s)}function ki(n,s,t){n.style&&(Object.keys(s).forEach(o=>{const c=Jr(o);t&&!t.hasOwnProperty(o)&&(t[o]=n.style[c]),n.style[c]=s[o]}),N()&&fi(n))}function Hi(n,s){n.style&&(Object.keys(s).forEach(t=>{const o=Jr(t);n.style[o]=""}),N()&&fi(n))}function Zr(n){return Array.isArray(n)?1==n.length?n[0]:(0,S.vP)(n):n}const Wt=new RegExp("{{\\s*(.+?)\\s*}}","g");function zn(n){let s=[];if("string"==typeof n){let t;for(;t=Wt.exec(n);)s.push(t[1]);Wt.lastIndex=0}return s}function rr(n,s,t){const o=n.toString(),c=o.replace(Wt,(g,C)=>{let D=s[C];return s.hasOwnProperty(C)||(t.push(`Please provide a value for the animation param ${C}`),D=""),D.toString()});return c==o?n:c}function Fr(n){const s=[];let t=n.next();for(;!t.done;)s.push(t.value),t=n.next();return s}const Gn=/-+([a-z0-9])/g;function Jr(n){return n.replace(Gn,(...s)=>s[1].toUpperCase())}function _i(n){return n.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}function wi(n,s){return 0===n||0===s}function br(n,s,t){const o=Object.keys(t);if(o.length&&s.length){let g=s[0],C=[];if(o.forEach(D=>{g.hasOwnProperty(D)||C.push(D),g[D]=t[D]}),C.length)for(var c=1;c<s.length;c++){let D=s[c];C.forEach(function(P){D[P]=gn(n,P)})}}return s}function Dr(n,s,t){switch(s.type){case 7:return n.visitTrigger(s,t);case 0:return n.visitState(s,t);case 1:return n.visitTransition(s,t);case 2:return n.visitSequence(s,t);case 3:return n.visitGroup(s,t);case 4:return n.visitAnimate(s,t);case 5:return n.visitKeyframes(s,t);case 6:return n.visitStyle(s,t);case 8:return n.visitReference(s,t);case 9:return n.visitAnimateChild(s,t);case 10:return n.visitAnimateRef(s,t);case 11:return n.visitQuery(s,t);case 12:return n.visitStagger(s,t);default:throw new Error(`Unable to resolve animation metadata node #${s.type}`)}}function gn(n,s){return window.getComputedStyle(n)[s]}function gr(n,s){const t=[];return"string"==typeof n?n.split(/\s*,\s*/).forEach(o=>function(n,s,t){if(":"==n[0]){const P=function(n,s){switch(n){case":enter":return"void => *";case":leave":return"* => void";case":increment":return(t,o)=>parseFloat(o)>parseFloat(t);case":decrement":return(t,o)=>parseFloat(o)<parseFloat(t);default:return s.push(`The transition alias value "${n}" is not supported`),"* => *"}}(n,t);if("function"==typeof P)return void s.push(P);n=P}const o=n.match(/^(\*|[-\w]+)\s*(<?[=-]>)\s*(\*|[-\w]+)$/);if(null==o||o.length<4)return t.push(`The provided transition expression "${n}" is not supported`),s;const c=o[1],g=o[2],C=o[3];s.push(Pr(c,C));"<"==g[0]&&!("*"==c&&"*"==C)&&s.push(Pr(C,c))}(o,t,s)):t.push(n),t}const mr=new Set(["true","1"]),Dn=new Set(["false","0"]);function Pr(n,s){const t=mr.has(n)||Dn.has(n),o=mr.has(s)||Dn.has(s);return(c,g)=>{let C="*"==n||n==c,D="*"==s||s==g;return!C&&t&&"boolean"==typeof c&&(C=c?mr.has(n):Dn.has(n)),!D&&o&&"boolean"==typeof g&&(D=g?mr.has(s):Dn.has(s)),C&&D}}const _n=new RegExp("s*:selfs*,?","g");function Ge(n,s,t){return new mi(n).build(s,t)}class mi{constructor(s){this._driver=s}build(s,t){const o=new Wr(t);return this._resetContextStyleTimingState(o),Dr(this,Zr(s),o)}_resetContextStyleTimingState(s){s.currentQuerySelector="",s.collectedStyles={},s.collectedStyles[""]={},s.currentTime=0}visitTrigger(s,t){let o=t.queryCount=0,c=t.depCount=0;const g=[],C=[];return"@"==s.name.charAt(0)&&t.errors.push("animation triggers cannot be prefixed with an `@` sign (e.g. trigger('@foo', [...]))"),s.definitions.forEach(D=>{if(this._resetContextStyleTimingState(t),0==D.type){const P=D,j=P.name;j.toString().split(/\s*,\s*/).forEach(W=>{P.name=W,g.push(this.visitState(P,t))}),P.name=j}else if(1==D.type){const P=this.visitTransition(D,t);o+=P.queryCount,c+=P.depCount,C.push(P)}else t.errors.push("only state() and transition() definitions can sit inside of a trigger()")}),{type:7,name:s.name,states:g,transitions:C,queryCount:o,depCount:c,options:null}}visitState(s,t){const o=this.visitStyle(s.styles,t),c=s.options&&s.options.params||null;if(o.containsDynamicStyles){const g=new Set,C=c||{};if(o.styles.forEach(D=>{if(Fn(D)){const P=D;Object.keys(P).forEach(j=>{zn(P[j]).forEach(W=>{C.hasOwnProperty(W)||g.add(W)})})}}),g.size){const D=Fr(g.values());t.errors.push(`state("${s.name}", ...) must define default values for all the following style substitutions: ${D.join(", ")}`)}}return{type:0,name:s.name,style:o,options:c?{params:c}:null}}visitTransition(s,t){t.queryCount=0,t.depCount=0;const o=Dr(this,Zr(s.animation),t);return{type:1,matchers:gr(s.expr,t.errors),animation:o,queryCount:t.queryCount,depCount:t.depCount,options:Wi(s.options)}}visitSequence(s,t){return{type:2,steps:s.steps.map(o=>Dr(this,o,t)),options:Wi(s.options)}}visitGroup(s,t){const o=t.currentTime;let c=0;const g=s.steps.map(C=>{t.currentTime=o;const D=Dr(this,C,t);return c=Math.max(c,t.currentTime),D});return t.currentTime=c,{type:3,steps:g,options:Wi(s.options)}}visitAnimate(s,t){const o=function(n,s){let t=null;if(n.hasOwnProperty("duration"))t=n;else if("number"==typeof n)return lo(Kr(n,s).duration,0,"");const o=n;if(o.split(/\s+/).some(g=>"{"==g.charAt(0)&&"{"==g.charAt(1))){const g=lo(0,0,"");return g.dynamic=!0,g.strValue=o,g}return t=t||Kr(o,s),lo(t.duration,t.delay,t.easing)}(s.timings,t.errors);t.currentAnimateTimings=o;let c,g=s.styles?s.styles:(0,S.oB)({});if(5==g.type)c=this.visitKeyframes(g,t);else{let C=s.styles,D=!1;if(!C){D=!0;const j={};o.easing&&(j.easing=o.easing),C=(0,S.oB)(j)}t.currentTime+=o.duration+o.delay;const P=this.visitStyle(C,t);P.isEmptyStep=D,c=P}return t.currentAnimateTimings=null,{type:4,timings:o,style:c,options:null}}visitStyle(s,t){const o=this._makeStyleAst(s,t);return this._validateStyleAst(o,t),o}_makeStyleAst(s,t){const o=[];Array.isArray(s.styles)?s.styles.forEach(C=>{"string"==typeof C?C==S.l3?o.push(C):t.errors.push(`The provided style string value ${C} is not allowed.`):o.push(C)}):o.push(s.styles);let c=!1,g=null;return o.forEach(C=>{if(Fn(C)){const D=C,P=D.easing;if(P&&(g=P,delete D.easing),!c)for(let j in D)if(D[j].toString().indexOf("{{")>=0){c=!0;break}}}),{type:6,styles:o,easing:g,offset:s.offset,containsDynamicStyles:c,options:null}}_validateStyleAst(s,t){const o=t.currentAnimateTimings;let c=t.currentTime,g=t.currentTime;o&&g>0&&(g-=o.duration+o.delay),s.styles.forEach(C=>{"string"!=typeof C&&Object.keys(C).forEach(D=>{if(!this._driver.validateStyleProperty(D))return void t.errors.push(`The provided animation property "${D}" is not a supported CSS property for animations`);const P=t.collectedStyles[t.currentQuerySelector],j=P[D];let W=!0;j&&(g!=c&&g>=j.startTime&&c<=j.endTime&&(t.errors.push(`The CSS property "${D}" that exists between the times of "${j.startTime}ms" and "${j.endTime}ms" is also being animated in a parallel animation between the times of "${g}ms" and "${c}ms"`),W=!1),g=j.startTime),W&&(P[D]={startTime:g,endTime:c}),t.options&&function(n,s,t){const o=s.params||{},c=zn(n);c.length&&c.forEach(g=>{o.hasOwnProperty(g)||t.push(`Unable to resolve the local animation param ${g} in the given list of values`)})}(C[D],t.options,t.errors)})})}visitKeyframes(s,t){const o={type:5,styles:[],options:null};if(!t.currentAnimateTimings)return t.errors.push("keyframes() must be placed inside of a call to animate()"),o;let g=0;const C=[];let D=!1,P=!1,j=0;const W=s.steps.map(Le=>{const we=this._makeStyleAst(Le,t);let U=null!=we.offset?we.offset:function(n){if("string"==typeof n)return null;let s=null;if(Array.isArray(n))n.forEach(t=>{if(Fn(t)&&t.hasOwnProperty("offset")){const o=t;s=parseFloat(o.offset),delete o.offset}});else if(Fn(n)&&n.hasOwnProperty("offset")){const t=n;s=parseFloat(t.offset),delete t.offset}return s}(we.styles),pt=0;return null!=U&&(g++,pt=we.offset=U),P=P||pt<0||pt>1,D=D||pt<j,j=pt,C.push(pt),we});P&&t.errors.push("Please ensure that all keyframe offsets are between 0 and 1"),D&&t.errors.push("Please ensure that all keyframe offsets are in order");const re=s.steps.length;let oe=0;g>0&&g<re?t.errors.push("Not all style() steps within the declared keyframes() contain offsets"):0==g&&(oe=1/(re-1));const me=re-1,_e=t.currentTime,Fe=t.currentAnimateTimings,Re=Fe.duration;return W.forEach((Le,we)=>{const U=oe>0?we==me?1:oe*we:C[we],pt=U*Re;t.currentTime=_e+Fe.delay+pt,Fe.duration=pt,this._validateStyleAst(Le,t),Le.offset=U,o.styles.push(Le)}),o}visitReference(s,t){return{type:8,animation:Dr(this,Zr(s.animation),t),options:Wi(s.options)}}visitAnimateChild(s,t){return t.depCount++,{type:9,options:Wi(s.options)}}visitAnimateRef(s,t){return{type:10,animation:this.visitReference(s.animation,t),options:Wi(s.options)}}visitQuery(s,t){const o=t.currentQuerySelector,c=s.options||{};t.queryCount++,t.currentQuery=s;const[g,C]=function(n){const s=!!n.split(/\s*,\s*/).find(t=>":self"==t);return s&&(n=n.replace(_n,"")),[n=n.replace(/@\*/g,Zn).replace(/@\w+/g,t=>Zn+"-"+t.substr(1)).replace(/:animating/g,di),s]}(s.selector);t.currentQuerySelector=o.length?o+" "+g:g,ue(t.collectedStyles,t.currentQuerySelector,{});const D=Dr(this,Zr(s.animation),t);return t.currentQuery=null,t.currentQuerySelector=o,{type:11,selector:g,limit:c.limit||0,optional:!!c.optional,includeSelf:C,animation:D,originalSelector:s.selector,options:Wi(s.options)}}visitStagger(s,t){t.currentQuery||t.errors.push("stagger() can only be used inside of query()");const o="full"===s.timings?{duration:0,delay:0,easing:"full"}:Kr(s.timings,t.errors,!0);return{type:12,animation:Dr(this,Zr(s.animation),t),timings:o,options:null}}}class Wr{constructor(s){this.errors=s,this.queryCount=0,this.depCount=0,this.currentTransition=null,this.currentQuery=null,this.currentQuerySelector=null,this.currentAnimateTimings=null,this.currentTime=0,this.collectedStyles={},this.options=null}}function Fn(n){return!Array.isArray(n)&&"object"==typeof n}function Wi(n){return n?(n=Nn(n)).params&&(n.params=function(n){return n?Nn(n):null}(n.params)):n={},n}function lo(n,s,t){return{duration:n,delay:s,easing:t}}function vo(n,s,t,o,c,g,C=null,D=!1){return{type:1,element:n,keyframes:s,preStyleProps:t,postStyleProps:o,duration:c,delay:g,totalTime:c+g,easing:C,subTimeline:D}}class Co{constructor(){this._map=new Map}consume(s){let t=this._map.get(s);return t?this._map.delete(s):t=[],t}append(s,t){let o=this._map.get(s);o||this._map.set(s,o=[]),o.push(...t)}has(s){return this._map.has(s)}clear(){this._map.clear()}}const jo=new RegExp(":enter","g"),Mi=new RegExp(":leave","g");function li(n,s,t,o,c,g={},C={},D,P,j=[]){return(new Bn).buildKeyframes(n,s,t,o,c,g,C,D,P,j)}class Bn{buildKeyframes(s,t,o,c,g,C,D,P,j,W=[]){j=j||new Co;const re=new vr(s,t,j,c,g,W,[]);re.options=P,re.currentTimeline.setStyles([C],null,re.errors,P),Dr(this,o,re);const oe=re.timelines.filter(me=>me.containsAnimation());if(oe.length&&Object.keys(D).length){const me=oe[oe.length-1];me.allowOnlyTimelineStyles()||me.setStyles([D],null,re.errors,P)}return oe.length?oe.map(me=>me.buildKeyframes()):[vo(t,[],[],[],0,0,"",!1)]}visitTrigger(s,t){}visitState(s,t){}visitTransition(s,t){}visitAnimateChild(s,t){const o=t.subInstructions.consume(t.element);if(o){const c=t.createSubContext(s.options),g=t.currentTimeline.currentTime,C=this._visitSubInstructions(o,c,c.options);g!=C&&t.transformIntoNewTimeline(C)}t.previousNode=s}visitAnimateRef(s,t){const o=t.createSubContext(s.options);o.transformIntoNewTimeline(),this.visitReference(s.animation,o),t.transformIntoNewTimeline(o.currentTimeline.currentTime),t.previousNode=s}_visitSubInstructions(s,t,o){let g=t.currentTimeline.currentTime;const C=null!=o.duration?Lr(o.duration):null,D=null!=o.delay?Lr(o.delay):null;return 0!==C&&s.forEach(P=>{const j=t.appendInstructionToTimeline(P,C,D);g=Math.max(g,j.duration+j.delay)}),g}visitReference(s,t){t.updateOptions(s.options,!0),Dr(this,s.animation,t),t.previousNode=s}visitSequence(s,t){const o=t.subContextCount;let c=t;const g=s.options;if(g&&(g.params||g.delay)&&(c=t.createSubContext(g),c.transformIntoNewTimeline(),null!=g.delay)){6==c.previousNode.type&&(c.currentTimeline.snapshotCurrentStyles(),c.previousNode=lr);const C=Lr(g.delay);c.delayNextStep(C)}s.steps.length&&(s.steps.forEach(C=>Dr(this,C,c)),c.currentTimeline.applyStylesToKeyframe(),c.subContextCount>o&&c.transformIntoNewTimeline()),t.previousNode=s}visitGroup(s,t){const o=[];let c=t.currentTimeline.currentTime;const g=s.options&&s.options.delay?Lr(s.options.delay):0;s.steps.forEach(C=>{const D=t.createSubContext(s.options);g&&D.delayNextStep(g),Dr(this,C,D),c=Math.max(c,D.currentTimeline.currentTime),o.push(D.currentTimeline)}),o.forEach(C=>t.currentTimeline.mergeTimelineCollectedStyles(C)),t.transformIntoNewTimeline(c),t.previousNode=s}_visitTiming(s,t){if(s.dynamic){const o=s.strValue;return Kr(t.params?rr(o,t.params,t.errors):o,t.errors)}return{duration:s.duration,delay:s.delay,easing:s.easing}}visitAnimate(s,t){const o=t.currentAnimateTimings=this._visitTiming(s.timings,t),c=t.currentTimeline;o.delay&&(t.incrementTime(o.delay),c.snapshotCurrentStyles());const g=s.style;5==g.type?this.visitKeyframes(g,t):(t.incrementTime(o.duration),this.visitStyle(g,t),c.applyStylesToKeyframe()),t.currentAnimateTimings=null,t.previousNode=s}visitStyle(s,t){const o=t.currentTimeline,c=t.currentAnimateTimings;!c&&o.getCurrentStyleProperties().length&&o.forwardFrame();const g=c&&c.easing||s.easing;s.isEmptyStep?o.applyEmptyStep(g):o.setStyles(s.styles,g,t.errors,t.options),t.previousNode=s}visitKeyframes(s,t){const o=t.currentAnimateTimings,c=t.currentTimeline.duration,g=o.duration,D=t.createSubContext().currentTimeline;D.easing=o.easing,s.styles.forEach(P=>{D.forwardTime((P.offset||0)*g),D.setStyles(P.styles,P.easing,t.errors,t.options),D.applyStylesToKeyframe()}),t.currentTimeline.mergeTimelineCollectedStyles(D),t.transformIntoNewTimeline(c+g),t.previousNode=s}visitQuery(s,t){const o=t.currentTimeline.currentTime,c=s.options||{},g=c.delay?Lr(c.delay):0;g&&(6===t.previousNode.type||0==o&&t.currentTimeline.getCurrentStyleProperties().length)&&(t.currentTimeline.snapshotCurrentStyles(),t.previousNode=lr);let C=o;const D=t.invokeQuery(s.selector,s.originalSelector,s.limit,s.includeSelf,!!c.optional,t.errors);t.currentQueryTotal=D.length;let P=null;D.forEach((j,W)=>{t.currentQueryIndex=W;const re=t.createSubContext(s.options,j);g&&re.delayNextStep(g),j===t.element&&(P=re.currentTimeline),Dr(this,s.animation,re),re.currentTimeline.applyStylesToKeyframe(),C=Math.max(C,re.currentTimeline.currentTime)}),t.currentQueryIndex=0,t.currentQueryTotal=0,t.transformIntoNewTimeline(C),P&&(t.currentTimeline.mergeTimelineCollectedStyles(P),t.currentTimeline.snapshotCurrentStyles()),t.previousNode=s}visitStagger(s,t){const o=t.parentContext,c=t.currentTimeline,g=s.timings,C=Math.abs(g.duration),D=C*(t.currentQueryTotal-1);let P=C*t.currentQueryIndex;switch(g.duration<0?"reverse":g.easing){case"reverse":P=D-P;break;case"full":P=o.currentStaggerTime}const W=t.currentTimeline;P&&W.delayNextStep(P);const re=W.currentTime;Dr(this,s.animation,t),t.previousNode=s,o.currentStaggerTime=c.currentTime-re+(c.startTime-o.currentTimeline.startTime)}}const lr={};class vr{constructor(s,t,o,c,g,C,D,P){this._driver=s,this.element=t,this.subInstructions=o,this._enterClassName=c,this._leaveClassName=g,this.errors=C,this.timelines=D,this.parentContext=null,this.currentAnimateTimings=null,this.previousNode=lr,this.subContextCount=0,this.options={},this.currentQueryIndex=0,this.currentQueryTotal=0,this.currentStaggerTime=0,this.currentTimeline=P||new er(this._driver,t,0),D.push(this.currentTimeline)}get params(){return this.options.params}updateOptions(s,t){if(!s)return;const o=s;let c=this.options;null!=o.duration&&(c.duration=Lr(o.duration)),null!=o.delay&&(c.delay=Lr(o.delay));const g=o.params;if(g){let C=c.params;C||(C=this.options.params={}),Object.keys(g).forEach(D=>{(!t||!C.hasOwnProperty(D))&&(C[D]=rr(g[D],C,this.errors))})}}_copyOptions(){const s={};if(this.options){const t=this.options.params;if(t){const o=s.params={};Object.keys(t).forEach(c=>{o[c]=t[c]})}}return s}createSubContext(s=null,t,o){const c=t||this.element,g=new vr(this._driver,c,this.subInstructions,this._enterClassName,this._leaveClassName,this.errors,this.timelines,this.currentTimeline.fork(c,o||0));return g.previousNode=this.previousNode,g.currentAnimateTimings=this.currentAnimateTimings,g.options=this._copyOptions(),g.updateOptions(s),g.currentQueryIndex=this.currentQueryIndex,g.currentQueryTotal=this.currentQueryTotal,g.parentContext=this,this.subContextCount++,g}transformIntoNewTimeline(s){return this.previousNode=lr,this.currentTimeline=this.currentTimeline.fork(this.element,s),this.timelines.push(this.currentTimeline),this.currentTimeline}appendInstructionToTimeline(s,t,o){const c={duration:null!=t?t:s.duration,delay:this.currentTimeline.currentTime+(null!=o?o:0)+s.delay,easing:""},g=new ri(this._driver,s.element,s.keyframes,s.preStyleProps,s.postStyleProps,c,s.stretchStartingKeyframe);return this.timelines.push(g),c}incrementTime(s){this.currentTimeline.forwardTime(this.currentTimeline.duration+s)}delayNextStep(s){s>0&&this.currentTimeline.delayNextStep(s)}invokeQuery(s,t,o,c,g,C){let D=[];if(c&&D.push(this.element),s.length>0){s=(s=s.replace(jo,"."+this._enterClassName)).replace(Mi,"."+this._leaveClassName);let j=this._driver.query(this.element,s,1!=o);0!==o&&(j=o<0?j.slice(j.length+o,j.length):j.slice(0,o)),D.push(...j)}return!g&&0==D.length&&C.push(`\`query("${t}")\` returned zero elements. (Use \`query("${t}", { optional: true })\` if you wish to allow this.)`),D}}class er{constructor(s,t,o,c){this._driver=s,this.element=t,this.startTime=o,this._elementTimelineStylesLookup=c,this.duration=0,this._previousKeyframe={},this._currentKeyframe={},this._keyframes=new Map,this._styleSummary={},this._pendingStyles={},this._backFill={},this._currentEmptyStepKeyframe=null,this._elementTimelineStylesLookup||(this._elementTimelineStylesLookup=new Map),this._localTimelineStyles=Object.create(this._backFill,{}),this._globalTimelineStyles=this._elementTimelineStylesLookup.get(t),this._globalTimelineStyles||(this._globalTimelineStyles=this._localTimelineStyles,this._elementTimelineStylesLookup.set(t,this._localTimelineStyles)),this._loadKeyframe()}containsAnimation(){switch(this._keyframes.size){case 0:return!1;case 1:return this.getCurrentStyleProperties().length>0;default:return!0}}getCurrentStyleProperties(){return Object.keys(this._currentKeyframe)}get currentTime(){return this.startTime+this.duration}delayNextStep(s){const t=1==this._keyframes.size&&Object.keys(this._pendingStyles).length;this.duration||t?(this.forwardTime(this.currentTime+s),t&&this.snapshotCurrentStyles()):this.startTime+=s}fork(s,t){return this.applyStylesToKeyframe(),new er(this._driver,s,t||this.currentTime,this._elementTimelineStylesLookup)}_loadKeyframe(){this._currentKeyframe&&(this._previousKeyframe=this._currentKeyframe),this._currentKeyframe=this._keyframes.get(this.duration),this._currentKeyframe||(this._currentKeyframe=Object.create(this._backFill,{}),this._keyframes.set(this.duration,this._currentKeyframe))}forwardFrame(){this.duration+=1,this._loadKeyframe()}forwardTime(s){this.applyStylesToKeyframe(),this.duration=s,this._loadKeyframe()}_updateStyle(s,t){this._localTimelineStyles[s]=t,this._globalTimelineStyles[s]=t,this._styleSummary[s]={time:this.currentTime,value:t}}allowOnlyTimelineStyles(){return this._currentEmptyStepKeyframe!==this._currentKeyframe}applyEmptyStep(s){s&&(this._previousKeyframe.easing=s),Object.keys(this._globalTimelineStyles).forEach(t=>{this._backFill[t]=this._globalTimelineStyles[t]||S.l3,this._currentKeyframe[t]=S.l3}),this._currentEmptyStepKeyframe=this._currentKeyframe}setStyles(s,t,o,c){t&&(this._previousKeyframe.easing=t);const g=c&&c.params||{},C=function(n,s){const t={};let o;return n.forEach(c=>{"*"===c?(o=o||Object.keys(s),o.forEach(g=>{t[g]=S.l3})):Br(c,!1,t)}),t}(s,this._globalTimelineStyles);Object.keys(C).forEach(D=>{const P=rr(C[D],g,o);this._pendingStyles[D]=P,this._localTimelineStyles.hasOwnProperty(D)||(this._backFill[D]=this._globalTimelineStyles.hasOwnProperty(D)?this._globalTimelineStyles[D]:S.l3),this._updateStyle(D,P)})}applyStylesToKeyframe(){const s=this._pendingStyles,t=Object.keys(s);0!=t.length&&(this._pendingStyles={},t.forEach(o=>{this._currentKeyframe[o]=s[o]}),Object.keys(this._localTimelineStyles).forEach(o=>{this._currentKeyframe.hasOwnProperty(o)||(this._currentKeyframe[o]=this._localTimelineStyles[o])}))}snapshotCurrentStyles(){Object.keys(this._localTimelineStyles).forEach(s=>{const t=this._localTimelineStyles[s];this._pendingStyles[s]=t,this._updateStyle(s,t)})}getFinalKeyframe(){return this._keyframes.get(this.duration)}get properties(){const s=[];for(let t in this._currentKeyframe)s.push(t);return s}mergeTimelineCollectedStyles(s){Object.keys(s._styleSummary).forEach(t=>{const o=this._styleSummary[t],c=s._styleSummary[t];(!o||c.time>o.time)&&this._updateStyle(t,c.value)})}buildKeyframes(){this.applyStylesToKeyframe();const s=new Set,t=new Set,o=1===this._keyframes.size&&0===this.duration;let c=[];this._keyframes.forEach((D,P)=>{const j=Br(D,!0);Object.keys(j).forEach(W=>{const re=j[W];re==S.k1?s.add(W):re==S.l3&&t.add(W)}),o||(j.offset=P/this.duration),c.push(j)});const g=s.size?Fr(s.values()):[],C=t.size?Fr(t.values()):[];if(o){const D=c[0],P=Nn(D);D.offset=0,P.offset=1,c=[D,P]}return vo(this.element,c,g,C,this.duration,this.startTime,this.easing,!1)}}class ri extends er{constructor(s,t,o,c,g,C,D=!1){super(s,t,C.delay),this.keyframes=o,this.preStyleProps=c,this.postStyleProps=g,this._stretchStartingKeyframe=D,this.timings={duration:C.duration,delay:C.delay,easing:C.easing}}containsAnimation(){return this.keyframes.length>1}buildKeyframes(){let s=this.keyframes,{delay:t,duration:o,easing:c}=this.timings;if(this._stretchStartingKeyframe&&t){const g=[],C=o+t,D=t/C,P=Br(s[0],!1);P.offset=0,g.push(P);const j=Br(s[0],!1);j.offset=uo(D),g.push(j);const W=s.length-1;for(let re=1;re<=W;re++){let oe=Br(s[re],!1);oe.offset=uo((t+oe.offset*o)/C),g.push(oe)}o=C,t=0,c="",s=g}return vo(this.element,s,this.preStyleProps,this.postStyleProps,o,t,c,!0)}}function uo(n,s=3){const t=Math.pow(10,s-1);return Math.round(n*t)/t}class tr{}class Rt extends tr{normalizePropertyName(s,t){return Jr(s)}normalizeStyleValue(s,t,o,c){let g="";const C=o.toString().trim();if(mt[t]&&0!==o&&"0"!==o)if("number"==typeof o)g="px";else{const D=o.match(/^[+-]?[\d\.]+([a-z]*)$/);D&&0==D[1].length&&c.push(`Please provide a CSS unit value for ${s}:${o}`)}return C+g}}const mt=(()=>function(n){const s={};return n.forEach(t=>s[t]=!0),s}("width,height,minWidth,minHeight,maxWidth,maxHeight,left,top,bottom,right,fontSize,outlineWidth,outlineOffset,paddingTop,paddingLeft,paddingBottom,paddingRight,marginTop,marginLeft,marginBottom,marginRight,borderRadius,borderWidth,borderTopWidth,borderLeftWidth,borderRightWidth,borderBottomWidth,textIndent,perspective".split(",")))();function on(n,s,t,o,c,g,C,D,P,j,W,re,oe){return{type:0,element:n,triggerName:s,isRemovalTransition:c,fromState:t,fromStyles:g,toState:o,toStyles:C,timelines:D,queriedElements:P,preStyleProps:j,postStyleProps:W,totalTime:re,errors:oe}}const si={};class Vi{constructor(s,t,o){this._triggerName=s,this.ast=t,this._stateStyles=o}match(s,t,o,c){return function(n,s,t,o,c){return n.some(g=>g(s,t,o,c))}(this.ast.matchers,s,t,o,c)}buildStyles(s,t,o){const c=this._stateStyles["*"],g=this._stateStyles[s],C=c?c.buildStyles(t,o):{};return g?g.buildStyles(t,o):C}build(s,t,o,c,g,C,D,P,j,W){const re=[],oe=this.ast.options&&this.ast.options.params||si,_e=this.buildStyles(o,D&&D.params||si,re),Fe=P&&P.params||si,Re=this.buildStyles(c,Fe,re),Le=new Set,we=new Map,U=new Map,pt="void"===c,ht={params:Object.assign(Object.assign({},oe),Fe)},Dt=W?[]:li(s,t,this.ast.animation,g,C,_e,Re,ht,j,re);let Ft=0;if(Dt.forEach(kt=>{Ft=Math.max(kt.duration+kt.delay,Ft)}),re.length)return on(t,this._triggerName,o,c,pt,_e,Re,[],[],we,U,Ft,re);Dt.forEach(kt=>{const wn=kt.element,Tn=ue(we,wn,{});kt.preStyleProps.forEach(sr=>Tn[sr]=!0);const Hr=ue(U,wn,{});kt.postStyleProps.forEach(sr=>Hr[sr]=!0),wn!==t&&Le.add(wn)});const cn=Fr(Le.values());return on(t,this._triggerName,o,c,pt,_e,Re,Dt,cn,we,U,Ft)}}class co{constructor(s,t,o){this.styles=s,this.defaultParams=t,this.normalizer=o}buildStyles(s,t){const o={},c=Nn(this.defaultParams);return Object.keys(s).forEach(g=>{const C=s[g];null!=C&&(c[g]=C)}),this.styles.styles.forEach(g=>{if("string"!=typeof g){const C=g;Object.keys(C).forEach(D=>{let P=C[D];P.length>1&&(P=rr(P,c,t));const j=this.normalizer.normalizePropertyName(D,t);P=this.normalizer.normalizeStyleValue(D,j,P,t),o[j]=P})}}),o}}class Zs{constructor(s,t,o){this.name=s,this.ast=t,this._normalizer=o,this.transitionFactories=[],this.states={},t.states.forEach(c=>{this.states[c.name]=new co(c.style,c.options&&c.options.params||{},o)}),La(this.states,"true","1"),La(this.states,"false","0"),t.transitions.forEach(c=>{this.transitionFactories.push(new Vi(s,c,this.states))}),this.fallbackTransition=function(n,s,t){return new Vi(n,{type:1,animation:{type:2,steps:[],options:null},matchers:[(C,D)=>!0],options:null,queryCount:0,depCount:0},s)}(s,this.states)}get containsQueries(){return this.ast.queryCount>0}matchTransition(s,t,o,c){return this.transitionFactories.find(C=>C.match(s,t,o,c))||null}matchStyles(s,t,o){return this.fallbackTransition.buildStyles(s,t,o)}}function La(n,s,t){n.hasOwnProperty(s)?n.hasOwnProperty(t)||(n[t]=n[s]):n.hasOwnProperty(t)&&(n[s]=n[t])}const ta=new Co;class Is{constructor(s,t,o){this.bodyNode=s,this._driver=t,this._normalizer=o,this._animations={},this._playersById={},this.players=[]}register(s,t){const o=[],c=Ge(this._driver,t,o);if(o.length)throw new Error(`Unable to build the animation due to the following errors: ${o.join("\n")}`);this._animations[s]=c}_buildPlayer(s,t,o){const c=s.element,g=Z(0,this._normalizer,0,s.keyframes,t,o);return this._driver.animate(c,g,s.duration,s.delay,s.easing,[],!0)}create(s,t,o={}){const c=[],g=this._animations[s];let C;const D=new Map;if(g?(C=li(this._driver,t,g,Bt,bt,{},{},o,ta,c),C.forEach(W=>{const re=ue(D,W.element,{});W.postStyleProps.forEach(oe=>re[oe]=null)})):(c.push("The requested animation doesn't exist or has already been destroyed"),C=[]),c.length)throw new Error(`Unable to create the animation due to the following errors: ${c.join("\n")}`);D.forEach((W,re)=>{Object.keys(W).forEach(oe=>{W[oe]=this._driver.computeStyle(re,oe,S.l3)})});const j=L(C.map(W=>{const re=D.get(W.element);return this._buildPlayer(W,{},re)}));return this._playersById[s]=j,j.onDestroy(()=>this.destroy(s)),this.players.push(j),j}destroy(s){const t=this._getPlayer(s);t.destroy(),delete this._playersById[s];const o=this.players.indexOf(t);o>=0&&this.players.splice(o,1)}_getPlayer(s){const t=this._playersById[s];if(!t)throw new Error(`Unable to find the timeline player referenced by ${s}`);return t}listen(s,t,o,c){const g=ee(t,"","","");return J(this._getPlayer(s),o,g,c),()=>{}}command(s,t,o,c){if("register"==o)return void this.register(s,c[0]);if("create"==o)return void this.create(s,t,c[0]||{});const g=this._getPlayer(s);switch(o){case"play":g.play();break;case"pause":g.pause();break;case"reset":g.reset();break;case"restart":g.restart();break;case"finish":g.finish();break;case"init":g.init();break;case"setPosition":g.setPosition(parseFloat(c[0]));break;case"destroy":this.destroy(s)}}}const us="ng-animate-queued",el="ng-animate-disabled",ca=".ng-animate-disabled",Il=[],fo={namespaceId:"",setForRemoval:!1,setForMove:!1,hasAnimation:!1,removedBeforeQueried:!1},Ya={namespaceId:"",setForMove:!1,setForRemoval:!1,hasAnimation:!1,removedBeforeQueried:!0},Ao="__ng_removed";class fs{constructor(s,t=""){this.namespaceId=t;const o=s&&s.hasOwnProperty("value");if(this.value=null!=(n=o?s.value:s)?n:null,o){const g=Nn(s);delete g.value,this.options=g}else this.options={};var n;this.options.params||(this.options.params={})}get params(){return this.options.params}absorbOptions(s){const t=s.params;if(t){const o=this.options.params;Object.keys(t).forEach(c=>{null==o[c]&&(o[c]=t[c])})}}}const Ca="void",Ra=new fs(Ca);class pl{constructor(s,t,o){this.id=s,this.hostElement=t,this._engine=o,this.players=[],this._triggers={},this._queue=[],this._elementListeners=new Map,this._hostClassName="ng-tns-"+s,$e(t,this._hostClassName)}listen(s,t,o,c){if(!this._triggers.hasOwnProperty(t))throw new Error(`Unable to listen on the animation trigger event "${o}" because the animation trigger "${t}" doesn't exist!`);if(null==o||0==o.length)throw new Error(`Unable to listen on the animation trigger "${t}" because the provided event is undefined!`);if("start"!=(n=o)&&"done"!=n)throw new Error(`The provided animation trigger event "${o}" for the animation trigger "${t}" is not supported!`);var n;const g=ue(this._elementListeners,s,[]),C={name:t,phase:o,callback:c};g.push(C);const D=ue(this._engine.statesByElement,s,{});return D.hasOwnProperty(t)||($e(s,Xt),$e(s,Xt+"-"+t),D[t]=Ra),()=>{this._engine.afterFlush(()=>{const P=g.indexOf(C);P>=0&&g.splice(P,1),this._triggers[t]||delete D[t]})}}register(s,t){return!this._triggers[s]&&(this._triggers[s]=t,!0)}_getTrigger(s){const t=this._triggers[s];if(!t)throw new Error(`The provided animation trigger "${s}" has not been registered!`);return t}trigger(s,t,o,c=!0){const g=this._getTrigger(t),C=new Po(this.id,t,s);let D=this._engine.statesByElement.get(s);D||($e(s,Xt),$e(s,Xt+"-"+t),this._engine.statesByElement.set(s,D={}));let P=D[t];const j=new fs(o,this.id);if(!(o&&o.hasOwnProperty("value"))&&P&&j.absorbOptions(P.options),D[t]=j,P||(P=Ra),j.value!==Ca&&P.value===j.value){if(!function(n,s){const t=Object.keys(n),o=Object.keys(s);if(t.length!=o.length)return!1;for(let c=0;c<t.length;c++){const g=t[c];if(!s.hasOwnProperty(g)||n[g]!==s[g])return!1}return!0}(P.params,j.params)){const Fe=[],Re=g.matchStyles(P.value,P.params,Fe),Le=g.matchStyles(j.value,j.params,Fe);Fe.length?this._engine.reportError(Fe):this._engine.afterFlush(()=>{Hi(s,Re),ki(s,Le)})}return}const oe=ue(this._engine.playersByElement,s,[]);oe.forEach(Fe=>{Fe.namespaceId==this.id&&Fe.triggerName==t&&Fe.queued&&Fe.destroy()});let me=g.matchTransition(P.value,j.value,s,j.params),_e=!1;if(!me){if(!c)return;me=g.fallbackTransition,_e=!0}return this._engine.totalQueuedPlayers++,this._queue.push({element:s,triggerName:t,transition:me,fromState:P,toState:j,player:C,isFallbackTransition:_e}),_e||($e(s,us),C.onStart(()=>{Lt(s,us)})),C.onDone(()=>{let Fe=this.players.indexOf(C);Fe>=0&&this.players.splice(Fe,1);const Re=this._engine.playersByElement.get(s);if(Re){let Le=Re.indexOf(C);Le>=0&&Re.splice(Le,1)}}),this.players.push(C),oe.push(C),C}deregister(s){delete this._triggers[s],this._engine.statesByElement.forEach((t,o)=>{delete t[s]}),this._elementListeners.forEach((t,o)=>{this._elementListeners.set(o,t.filter(c=>c.name!=s))})}clearElementCache(s){this._engine.statesByElement.delete(s),this._elementListeners.delete(s);const t=this._engine.playersByElement.get(s);t&&(t.forEach(o=>o.destroy()),this._engine.playersByElement.delete(s))}_signalRemovalForInnerTriggers(s,t){const o=this._engine.driver.query(s,Zn,!0);o.forEach(c=>{if(c[Ao])return;const g=this._engine.fetchNamespacesByElement(c);g.size?g.forEach(C=>C.triggerLeaveAnimation(c,t,!1,!0)):this.clearElementCache(c)}),this._engine.afterFlushAnimationsDone(()=>o.forEach(c=>this.clearElementCache(c)))}triggerLeaveAnimation(s,t,o,c){const g=this._engine.statesByElement.get(s);if(g){const C=[];if(Object.keys(g).forEach(D=>{if(this._triggers[D]){const P=this.trigger(s,D,Ca,c);P&&C.push(P)}}),C.length)return this._engine.markElementAsRemoved(this.id,s,!0,t),o&&L(C).onDone(()=>this._engine.processLeaveNode(s)),!0}return!1}prepareLeaveAnimationListeners(s){const t=this._elementListeners.get(s),o=this._engine.statesByElement.get(s);if(t&&o){const c=new Set;t.forEach(g=>{const C=g.name;if(c.has(C))return;c.add(C);const P=this._triggers[C].fallbackTransition,j=o[C]||Ra,W=new fs(Ca),re=new Po(this.id,C,s);this._engine.totalQueuedPlayers++,this._queue.push({element:s,triggerName:C,transition:P,fromState:j,toState:W,player:re,isFallbackTransition:!0})})}}removeNode(s,t){const o=this._engine;if(s.childElementCount&&this._signalRemovalForInnerTriggers(s,t),this.triggerLeaveAnimation(s,t,!0))return;let c=!1;if(o.totalAnimations){const g=o.players.length?o.playersByQueriedElement.get(s):[];if(g&&g.length)c=!0;else{let C=s;for(;C=C.parentNode;)if(o.statesByElement.get(C)){c=!0;break}}}if(this.prepareLeaveAnimationListeners(s),c)o.markElementAsRemoved(this.id,s,!1,t);else{const g=s[Ao];(!g||g===fo)&&(o.afterFlush(()=>this.clearElementCache(s)),o.destroyInnerAnimations(s),o._onRemovalComplete(s,t))}}insertNode(s,t){$e(s,this._hostClassName)}drainQueuedTransitions(s){const t=[];return this._queue.forEach(o=>{const c=o.player;if(c.destroyed)return;const g=o.element,C=this._elementListeners.get(g);C&&C.forEach(D=>{if(D.name==o.triggerName){const P=ee(g,o.triggerName,o.fromState.value,o.toState.value);P._data=s,J(o.player,D.phase,P,D.callback)}}),c.markedForDestroy?this._engine.afterFlush(()=>{c.destroy()}):t.push(o)}),this._queue=[],t.sort((o,c)=>{const g=o.transition.ast.depCount,C=c.transition.ast.depCount;return 0==g||0==C?g-C:this._engine.driver.containsElement(o.element,c.element)?1:-1})}destroy(s){this.players.forEach(t=>t.destroy()),this._signalRemovalForInnerTriggers(this.hostElement,s)}elementContainsData(s){let t=!1;return this._elementListeners.has(s)&&(t=!0),t=!!this._queue.find(o=>o.element===s)||t,t}}class Ws{constructor(s,t,o){this.bodyNode=s,this.driver=t,this._normalizer=o,this.players=[],this.newHostElements=new Map,this.playersByElement=new Map,this.playersByQueriedElement=new Map,this.statesByElement=new Map,this.disabledNodes=new Set,this.totalAnimations=0,this.totalQueuedPlayers=0,this._namespaceLookup={},this._namespaceList=[],this._flushFns=[],this._whenQuietFns=[],this.namespacesByHostElement=new Map,this.collectedEnterElements=[],this.collectedLeaveElements=[],this.onRemovalComplete=(c,g)=>{}}_onRemovalComplete(s,t){this.onRemovalComplete(s,t)}get queuedPlayers(){const s=[];return this._namespaceList.forEach(t=>{t.players.forEach(o=>{o.queued&&s.push(o)})}),s}createNamespace(s,t){const o=new pl(s,t,this);return this.bodyNode&&this.driver.containsElement(this.bodyNode,t)?this._balanceNamespaceList(o,t):(this.newHostElements.set(t,o),this.collectEnterElement(t)),this._namespaceLookup[s]=o}_balanceNamespaceList(s,t){const o=this._namespaceList.length-1;if(o>=0){let c=!1;for(let g=o;g>=0;g--)if(this.driver.containsElement(this._namespaceList[g].hostElement,t)){this._namespaceList.splice(g+1,0,s),c=!0;break}c||this._namespaceList.splice(0,0,s)}else this._namespaceList.push(s);return this.namespacesByHostElement.set(t,s),s}register(s,t){let o=this._namespaceLookup[s];return o||(o=this.createNamespace(s,t)),o}registerTrigger(s,t,o){let c=this._namespaceLookup[s];c&&c.register(t,o)&&this.totalAnimations++}destroy(s,t){if(!s)return;const o=this._fetchNamespace(s);this.afterFlush(()=>{this.namespacesByHostElement.delete(o.hostElement),delete this._namespaceLookup[s];const c=this._namespaceList.indexOf(o);c>=0&&this._namespaceList.splice(c,1)}),this.afterFlushAnimationsDone(()=>o.destroy(t))}_fetchNamespace(s){return this._namespaceLookup[s]}fetchNamespacesByElement(s){const t=new Set,o=this.statesByElement.get(s);if(o){const c=Object.keys(o);for(let g=0;g<c.length;g++){const C=o[c[g]].namespaceId;if(C){const D=this._fetchNamespace(C);D&&t.add(D)}}}return t}trigger(s,t,o,c){if(ps(t)){const g=this._fetchNamespace(s);if(g)return g.trigger(t,o,c),!0}return!1}insertNode(s,t,o,c){if(!ps(t))return;const g=t[Ao];if(g&&g.setForRemoval){g.setForRemoval=!1,g.setForMove=!0;const C=this.collectedLeaveElements.indexOf(t);C>=0&&this.collectedLeaveElements.splice(C,1)}if(s){const C=this._fetchNamespace(s);C&&C.insertNode(t,o)}c&&this.collectEnterElement(t)}collectEnterElement(s){this.collectedEnterElements.push(s)}markElementAsDisabled(s,t){t?this.disabledNodes.has(s)||(this.disabledNodes.add(s),$e(s,el)):this.disabledNodes.has(s)&&(this.disabledNodes.delete(s),Lt(s,el))}removeNode(s,t,o,c){if(ps(t)){const g=s?this._fetchNamespace(s):null;if(g?g.removeNode(t,c):this.markElementAsRemoved(s,t,!1,c),o){const C=this.namespacesByHostElement.get(t);C&&C.id!==s&&C.removeNode(t,c)}}else this._onRemovalComplete(t,c)}markElementAsRemoved(s,t,o,c){this.collectedLeaveElements.push(t),t[Ao]={namespaceId:s,setForRemoval:c,hasAnimation:o,removedBeforeQueried:!1}}listen(s,t,o,c,g){return ps(t)?this._fetchNamespace(s).listen(t,o,c,g):()=>{}}_buildInstruction(s,t,o,c,g){return s.transition.build(this.driver,s.element,s.fromState.value,s.toState.value,o,c,s.fromState.options,s.toState.options,t,g)}destroyInnerAnimations(s){let t=this.driver.query(s,Zn,!0);t.forEach(o=>this.destroyActiveAnimationsForElement(o)),0!=this.playersByQueriedElement.size&&(t=this.driver.query(s,di,!0),t.forEach(o=>this.finishActiveQueriedAnimationOnElement(o)))}destroyActiveAnimationsForElement(s){const t=this.playersByElement.get(s);t&&t.forEach(o=>{o.queued?o.markedForDestroy=!0:o.destroy()})}finishActiveQueriedAnimationOnElement(s){const t=this.playersByQueriedElement.get(s);t&&t.forEach(o=>o.finish())}whenRenderingDone(){return new Promise(s=>{if(this.players.length)return L(this.players).onDone(()=>s());s()})}processLeaveNode(s){const t=s[Ao];if(t&&t.setForRemoval){if(s[Ao]=fo,t.namespaceId){this.destroyInnerAnimations(s);const o=this._fetchNamespace(t.namespaceId);o&&o.clearElementCache(s)}this._onRemovalComplete(s,t.setForRemoval)}this.driver.matchesElement(s,ca)&&this.markElementAsDisabled(s,!1),this.driver.query(s,ca,!0).forEach(o=>{this.markElementAsDisabled(o,!1)})}flush(s=-1){let t=[];if(this.newHostElements.size&&(this.newHostElements.forEach((o,c)=>this._balanceNamespaceList(o,c)),this.newHostElements.clear()),this.totalAnimations&&this.collectedEnterElements.length)for(let o=0;o<this.collectedEnterElements.length;o++)$e(this.collectedEnterElements[o],"ng-star-inserted");if(this._namespaceList.length&&(this.totalQueuedPlayers||this.collectedLeaveElements.length)){const o=[];try{t=this._flushAnimations(o,s)}finally{for(let c=0;c<o.length;c++)o[c]()}}else for(let o=0;o<this.collectedLeaveElements.length;o++)this.processLeaveNode(this.collectedLeaveElements[o]);if(this.totalQueuedPlayers=0,this.collectedEnterElements.length=0,this.collectedLeaveElements.length=0,this._flushFns.forEach(o=>o()),this._flushFns=[],this._whenQuietFns.length){const o=this._whenQuietFns;this._whenQuietFns=[],t.length?L(t).onDone(()=>{o.forEach(c=>c())}):o.forEach(c=>c())}}reportError(s){throw new Error(`Unable to process animations due to the following failed trigger transitions\n ${s.join("\n")}`)}_flushAnimations(s,t){const o=new Co,c=[],g=new Map,C=[],D=new Map,P=new Map,j=new Map,W=new Set;this.disabledNodes.forEach(fn=>{W.add(fn);const Rn=this.driver.query(fn,".ng-animate-queued",!0);for(let kn=0;kn<Rn.length;kn++)W.add(Rn[kn])});const re=this.bodyNode,oe=Array.from(this.statesByElement.keys()),me=tt(oe,this.collectedEnterElements),_e=new Map;let Fe=0;me.forEach((fn,Rn)=>{const kn=Bt+Fe++;_e.set(Rn,kn),fn.forEach(Wn=>$e(Wn,kn))});const Re=[],Le=new Set,we=new Set;for(let fn=0;fn<this.collectedLeaveElements.length;fn++){const Rn=this.collectedLeaveElements[fn],kn=Rn[Ao];kn&&kn.setForRemoval&&(Re.push(Rn),Le.add(Rn),kn.hasAnimation?this.driver.query(Rn,".ng-star-inserted",!0).forEach(Wn=>Le.add(Wn)):we.add(Rn))}const U=new Map,pt=tt(oe,Array.from(Le));pt.forEach((fn,Rn)=>{const kn=bt+Fe++;U.set(Rn,kn),fn.forEach(Wn=>$e(Wn,kn))}),s.push(()=>{me.forEach((fn,Rn)=>{const kn=_e.get(Rn);fn.forEach(Wn=>Lt(Wn,kn))}),pt.forEach((fn,Rn)=>{const kn=U.get(Rn);fn.forEach(Wn=>Lt(Wn,kn))}),Re.forEach(fn=>{this.processLeaveNode(fn)})});const ht=[],Dt=[];for(let fn=this._namespaceList.length-1;fn>=0;fn--)this._namespaceList[fn].drainQueuedTransitions(t).forEach(kn=>{const Wn=kn.player,bn=kn.element;if(ht.push(Wn),this.collectedEnterElements.length){const Sn=bn[Ao];if(Sn&&Sn.setForMove)return void Wn.destroy()}const jr=!re||!this.driver.containsElement(re,bn),ji=U.get(bn),oi=_e.get(bn),Ui=this._buildInstruction(kn,o,oi,ji,jr);if(Ui.errors&&Ui.errors.length)Dt.push(Ui);else{if(jr)return Wn.onStart(()=>Hi(bn,Ui.fromStyles)),Wn.onDestroy(()=>ki(bn,Ui.toStyles)),void c.push(Wn);if(kn.isFallbackTransition)return Wn.onStart(()=>Hi(bn,Ui.fromStyles)),Wn.onDestroy(()=>ki(bn,Ui.toStyles)),void c.push(Wn);Ui.timelines.forEach(Sn=>Sn.stretchStartingKeyframe=!0),o.append(bn,Ui.timelines),C.push({instruction:Ui,player:Wn,element:bn}),Ui.queriedElements.forEach(Sn=>ue(D,Sn,[]).push(Wn)),Ui.preStyleProps.forEach((Sn,hn)=>{const _r=Object.keys(Sn);if(_r.length){let Fi=P.get(hn);Fi||P.set(hn,Fi=new Set),_r.forEach(_s=>Fi.add(_s))}}),Ui.postStyleProps.forEach((Sn,hn)=>{const _r=Object.keys(Sn);let Fi=j.get(hn);Fi||j.set(hn,Fi=new Set),_r.forEach(_s=>Fi.add(_s))})}});if(Dt.length){const fn=[];Dt.forEach(Rn=>{fn.push(`@${Rn.triggerName} has failed due to:\n`),Rn.errors.forEach(kn=>fn.push(`- ${kn}\n`))}),ht.forEach(Rn=>Rn.destroy()),this.reportError(fn)}const Ft=new Map,cn=new Map;C.forEach(fn=>{const Rn=fn.element;o.has(Rn)&&(cn.set(Rn,Rn),this._beforeAnimationBuild(fn.player.namespaceId,fn.instruction,Ft))}),c.forEach(fn=>{const Rn=fn.element;this._getPreviousPlayers(Rn,!1,fn.namespaceId,fn.triggerName,null).forEach(Wn=>{ue(Ft,Rn,[]).push(Wn),Wn.destroy()})});const kt=Re.filter(fn=>ts(fn,P,j)),wn=new Map;to(wn,this.driver,we,j,S.l3).forEach(fn=>{ts(fn,P,j)&&kt.push(fn)});const Hr=new Map;me.forEach((fn,Rn)=>{to(Hr,this.driver,new Set(fn),P,S.k1)}),kt.forEach(fn=>{const Rn=wn.get(fn),kn=Hr.get(fn);wn.set(fn,Object.assign(Object.assign({},Rn),kn))});const sr=[],Nr=[],xr={};C.forEach(fn=>{const{element:Rn,player:kn,instruction:Wn}=fn;if(o.has(Rn)){if(W.has(Rn))return kn.onDestroy(()=>ki(Rn,Wn.toStyles)),kn.disabled=!0,kn.overrideTotalTime(Wn.totalTime),void c.push(kn);let bn=xr;if(cn.size>1){let ji=Rn;const oi=[];for(;ji=ji.parentNode;){const Ui=cn.get(ji);if(Ui){bn=Ui;break}oi.push(ji)}oi.forEach(Ui=>cn.set(Ui,bn))}const jr=this._buildAnimation(kn.namespaceId,Wn,Ft,g,Hr,wn);if(kn.setRealPlayer(jr),bn===xr)sr.push(kn);else{const ji=this.playersByElement.get(bn);ji&&ji.length&&(kn.parentPlayer=L(ji)),c.push(kn)}}else Hi(Rn,Wn.fromStyles),kn.onDestroy(()=>ki(Rn,Wn.toStyles)),Nr.push(kn),W.has(Rn)&&c.push(kn)}),Nr.forEach(fn=>{const Rn=g.get(fn.element);if(Rn&&Rn.length){const kn=L(Rn);fn.setRealPlayer(kn)}}),c.forEach(fn=>{fn.parentPlayer?fn.syncPlayerEvents(fn.parentPlayer):fn.destroy()});for(let fn=0;fn<Re.length;fn++){const Rn=Re[fn],kn=Rn[Ao];if(Lt(Rn,bt),kn&&kn.hasAnimation)continue;let Wn=[];if(D.size){let jr=D.get(Rn);jr&&jr.length&&Wn.push(...jr);let ji=this.driver.query(Rn,di,!0);for(let oi=0;oi<ji.length;oi++){let Ui=D.get(ji[oi]);Ui&&Ui.length&&Wn.push(...Ui)}}const bn=Wn.filter(jr=>!jr.destroyed);bn.length?an(this,Rn,bn):this.processLeaveNode(Rn)}return Re.length=0,sr.forEach(fn=>{this.players.push(fn),fn.onDone(()=>{fn.destroy();const Rn=this.players.indexOf(fn);this.players.splice(Rn,1)}),fn.play()}),sr}elementContainsData(s,t){let o=!1;const c=t[Ao];return c&&c.setForRemoval&&(o=!0),this.playersByElement.has(t)&&(o=!0),this.playersByQueriedElement.has(t)&&(o=!0),this.statesByElement.has(t)&&(o=!0),this._fetchNamespace(s).elementContainsData(t)||o}afterFlush(s){this._flushFns.push(s)}afterFlushAnimationsDone(s){this._whenQuietFns.push(s)}_getPreviousPlayers(s,t,o,c,g){let C=[];if(t){const D=this.playersByQueriedElement.get(s);D&&(C=D)}else{const D=this.playersByElement.get(s);if(D){const P=!g||g==Ca;D.forEach(j=>{j.queued||!P&&j.triggerName!=c||C.push(j)})}}return(o||c)&&(C=C.filter(D=>!(o&&o!=D.namespaceId||c&&c!=D.triggerName))),C}_beforeAnimationBuild(s,t,o){const g=t.element,C=t.isRemovalTransition?void 0:s,D=t.isRemovalTransition?void 0:t.triggerName;for(const P of t.timelines){const j=P.element,W=j!==g,re=ue(o,j,[]);this._getPreviousPlayers(j,W,C,D,t.toState).forEach(me=>{const _e=me.getRealPlayer();_e.beforeDestroy&&_e.beforeDestroy(),me.destroy(),re.push(me)})}Hi(g,t.fromStyles)}_buildAnimation(s,t,o,c,g,C){const D=t.triggerName,P=t.element,j=[],W=new Set,re=new Set,oe=t.timelines.map(_e=>{const Fe=_e.element;W.add(Fe);const Re=Fe[Ao];if(Re&&Re.removedBeforeQueried)return new S.ZN(_e.duration,_e.delay);const Le=Fe!==P,we=function(n){const s=[];return pi(n,s),s}((o.get(Fe)||Il).map(Ft=>Ft.getRealPlayer())).filter(Ft=>!!Ft.element&&Ft.element===Fe),U=g.get(Fe),pt=C.get(Fe),ht=Z(0,this._normalizer,0,_e.keyframes,U,pt),Dt=this._buildPlayer(_e,ht,we);if(_e.subTimeline&&c&&re.add(Fe),Le){const Ft=new Po(s,D,Fe);Ft.setRealPlayer(Dt),j.push(Ft)}return Dt});j.forEach(_e=>{ue(this.playersByQueriedElement,_e.element,[]).push(_e),_e.onDone(()=>function(n,s,t){let o;if(n instanceof Map){if(o=n.get(s),o){if(o.length){const c=o.indexOf(t);o.splice(c,1)}0==o.length&&n.delete(s)}}else if(o=n[s],o){if(o.length){const c=o.indexOf(t);o.splice(c,1)}0==o.length&&delete n[s]}return o}(this.playersByQueriedElement,_e.element,_e))}),W.forEach(_e=>$e(_e,Ur));const me=L(oe);return me.onDestroy(()=>{W.forEach(_e=>Lt(_e,Ur)),ki(P,t.toStyles)}),re.forEach(_e=>{ue(c,_e,[]).push(me)}),me}_buildPlayer(s,t,o){return t.length>0?this.driver.animate(s.element,t,s.duration,s.delay,s.easing,o):new S.ZN(s.duration,s.delay)}}class Po{constructor(s,t,o){this.namespaceId=s,this.triggerName=t,this.element=o,this._player=new S.ZN,this._containsRealPlayer=!1,this._queuedCallbacks={},this.destroyed=!1,this.markedForDestroy=!1,this.disabled=!1,this.queued=!0,this.totalTime=0}setRealPlayer(s){this._containsRealPlayer||(this._player=s,Object.keys(this._queuedCallbacks).forEach(t=>{this._queuedCallbacks[t].forEach(o=>J(s,t,void 0,o))}),this._queuedCallbacks={},this._containsRealPlayer=!0,this.overrideTotalTime(s.totalTime),this.queued=!1)}getRealPlayer(){return this._player}overrideTotalTime(s){this.totalTime=s}syncPlayerEvents(s){const t=this._player;t.triggerCallback&&s.onStart(()=>t.triggerCallback("start")),s.onDone(()=>this.finish()),s.onDestroy(()=>this.destroy())}_queueEvent(s,t){ue(this._queuedCallbacks,s,[]).push(t)}onDone(s){this.queued&&this._queueEvent("done",s),this._player.onDone(s)}onStart(s){this.queued&&this._queueEvent("start",s),this._player.onStart(s)}onDestroy(s){this.queued&&this._queueEvent("destroy",s),this._player.onDestroy(s)}init(){this._player.init()}hasStarted(){return!this.queued&&this._player.hasStarted()}play(){!this.queued&&this._player.play()}pause(){!this.queued&&this._player.pause()}restart(){!this.queued&&this._player.restart()}finish(){this._player.finish()}destroy(){this.destroyed=!0,this._player.destroy()}reset(){!this.queued&&this._player.reset()}setPosition(s){this.queued||this._player.setPosition(s)}getPosition(){return this.queued?0:this._player.getPosition()}triggerCallback(s){const t=this._player;t.triggerCallback&&t.triggerCallback(s)}}function ps(n){return n&&1===n.nodeType}function $r(n,s){const t=n.style.display;return n.style.display=null!=s?s:"none",t}function to(n,s,t,o,c){const g=[];t.forEach(P=>g.push($r(P)));const C=[];o.forEach((P,j)=>{const W={};P.forEach(re=>{const oe=W[re]=s.computeStyle(j,re,c);(!oe||0==oe.length)&&(j[Ao]=Ya,C.push(j))}),n.set(j,W)});let D=0;return t.forEach(P=>$r(P,g[D++])),C}function tt(n,s){const t=new Map;if(n.forEach(D=>t.set(D,[])),0==s.length)return t;const c=new Set(s),g=new Map;function C(D){if(!D)return 1;let P=g.get(D);if(P)return P;const j=D.parentNode;return P=t.has(j)?j:c.has(j)?1:C(j),g.set(D,P),P}return s.forEach(D=>{const P=C(D);1!==P&&t.get(P).push(D)}),t}const sn="$$classes";function $e(n,s){if(n.classList)n.classList.add(s);else{let t=n[sn];t||(t=n[sn]={}),t[s]=!0}}function Lt(n,s){if(n.classList)n.classList.remove(s);else{let t=n[sn];t&&delete t[s]}}function an(n,s,t){L(t).onDone(()=>n.processLeaveNode(s))}function pi(n,s){for(let t=0;t<n.length;t++){const o=n[t];o instanceof S.ZE?pi(o.players,s):s.push(o)}}function ts(n,s,t){const o=t.get(n);if(!o)return!1;let c=s.get(n);return c?o.forEach(g=>c.add(g)):s.set(n,o),t.delete(n),!0}class wo{constructor(s,t,o){this.bodyNode=s,this._driver=t,this._normalizer=o,this._triggerCache={},this.onRemovalComplete=(c,g)=>{},this._transitionEngine=new Ws(s,t,o),this._timelineEngine=new Is(s,t,o),this._transitionEngine.onRemovalComplete=(c,g)=>this.onRemovalComplete(c,g)}registerTrigger(s,t,o,c,g){const C=s+"-"+c;let D=this._triggerCache[C];if(!D){const P=[],j=Ge(this._driver,g,P);if(P.length)throw new Error(`The animation trigger "${c}" has failed to build due to the following errors:\n - ${P.join("\n - ")}`);D=function(n,s,t){return new Zs(n,s,t)}(c,j,this._normalizer),this._triggerCache[C]=D}this._transitionEngine.registerTrigger(t,c,D)}register(s,t){this._transitionEngine.register(s,t)}destroy(s,t){this._transitionEngine.destroy(s,t)}onInsert(s,t,o,c){this._transitionEngine.insertNode(s,t,o,c)}onRemove(s,t,o,c){this._transitionEngine.removeNode(s,t,c||!1,o)}disableAnimations(s,t){this._transitionEngine.markElementAsDisabled(s,t)}process(s,t,o,c){if("@"==o.charAt(0)){const[g,C]=ae(o);this._timelineEngine.command(g,t,C,c)}else this._transitionEngine.trigger(s,t,o,c)}listen(s,t,o,c,g){if("@"==o.charAt(0)){const[C,D]=ae(o);return this._timelineEngine.listen(C,t,D,g)}return this._transitionEngine.listen(s,t,o,c,g)}flush(s=-1){this._transitionEngine.flush(s)}get players(){return this._transitionEngine.players.concat(this._timelineEngine.players)}whenRenderingDone(){return this._transitionEngine.whenRenderingDone()}}function ko(n,s){let t=null,o=null;return Array.isArray(s)&&s.length?(t=ba(s[0]),s.length>1&&(o=ba(s[s.length-1]))):s&&(t=ba(s)),t||o?new Eo(n,t,o):null}let Eo=(()=>{class n{constructor(t,o,c){this._element=t,this._startStyles=o,this._endStyles=c,this._state=0;let g=n.initialStylesByElement.get(t);g||n.initialStylesByElement.set(t,g={}),this._initialStyles=g}start(){this._state<1&&(this._startStyles&&ki(this._element,this._startStyles,this._initialStyles),this._state=1)}finish(){this.start(),this._state<2&&(ki(this._element,this._initialStyles),this._endStyles&&(ki(this._element,this._endStyles),this._endStyles=null),this._state=1)}destroy(){this.finish(),this._state<3&&(n.initialStylesByElement.delete(this._element),this._startStyles&&(Hi(this._element,this._startStyles),this._endStyles=null),this._endStyles&&(Hi(this._element,this._endStyles),this._endStyles=null),ki(this._element,this._initialStyles),this._state=3)}}return n.initialStylesByElement=new WeakMap,n})();function ba(n){let s=null;const t=Object.keys(n);for(let o=0;o<t.length;o++){const c=t[o];sl(c)&&(s=s||{},s[c]=n[c])}return s}function sl(n){return"display"===n||"position"===n}const Nu="animation",bc="animationend";class qc{constructor(s,t,o,c,g,C,D){this._element=s,this._name=t,this._duration=o,this._delay=c,this._easing=g,this._fillMode=C,this._onDoneFn=D,this._finished=!1,this._destroyed=!1,this._startTime=0,this._position=0,this._eventFn=P=>this._handleCallback(P)}apply(){(function(n,s){const t=Zl(n,"").trim();let o=0;t.length&&(function(n,s){let t=0;for(let o=0;o<n.length;o++)","===n.charAt(o)&&t++;return t}(t)+1,s=`${t}, ${s}`),Su(n,"",s)})(this._element,`${this._duration}ms ${this._easing} ${this._delay}ms 1 normal ${this._fillMode} ${this._name}`),tl(this._element,this._eventFn,!1),this._startTime=Date.now()}pause(){Hl(this._element,this._name,"paused")}resume(){Hl(this._element,this._name,"running")}setPosition(s){const t=dc(this._element,this._name);this._position=s*this._duration,Su(this._element,"Delay",`-${this._position}ms`,t)}getPosition(){return this._position}_handleCallback(s){const t=s._ngTestManualTimestamp||Date.now(),o=1e3*parseFloat(s.elapsedTime.toFixed(3));s.animationName==this._name&&Math.max(t-this._startTime,0)>=this._delay&&o>=this._duration&&this.finish()}finish(){this._finished||(this._finished=!0,this._onDoneFn(),tl(this._element,this._eventFn,!0))}destroy(){this._destroyed||(this._destroyed=!0,this.finish(),function(n,s){const o=Zl(n,"").split(","),c=iu(o,s);c>=0&&(o.splice(c,1),Su(n,"",o.join(",")))}(this._element,this._name))}}function Hl(n,s,t){Su(n,"PlayState",t,dc(n,s))}function dc(n,s){const t=Zl(n,"");return t.indexOf(",")>0?iu(t.split(","),s):iu([t],s)}function iu(n,s){for(let t=0;t<n.length;t++)if(n[t].indexOf(s)>=0)return t;return-1}function tl(n,s,t){t?n.removeEventListener(bc,s):n.addEventListener(bc,s)}function Su(n,s,t,o){const c=Nu+s;if(null!=o){const g=n.style[c];if(g.length){const C=g.split(",");C[o]=t,t=C.join(",")}}n.style[c]=t}function Zl(n,s){return n.style[Nu+s]||""}class Te{constructor(s,t,o,c,g,C,D,P){this.element=s,this.keyframes=t,this.animationName=o,this._duration=c,this._delay=g,this._finalStyles=D,this._specialStyles=P,this._onDoneFns=[],this._onStartFns=[],this._onDestroyFns=[],this.currentSnapshot={},this._state=0,this.easing=C||"linear",this.totalTime=c+g,this._buildStyler()}onStart(s){this._onStartFns.push(s)}onDone(s){this._onDoneFns.push(s)}onDestroy(s){this._onDestroyFns.push(s)}destroy(){this.init(),!(this._state>=4)&&(this._state=4,this._styler.destroy(),this._flushStartFns(),this._flushDoneFns(),this._specialStyles&&this._specialStyles.destroy(),this._onDestroyFns.forEach(s=>s()),this._onDestroyFns=[])}_flushDoneFns(){this._onDoneFns.forEach(s=>s()),this._onDoneFns=[]}_flushStartFns(){this._onStartFns.forEach(s=>s()),this._onStartFns=[]}finish(){this.init(),!(this._state>=3)&&(this._state=3,this._styler.finish(),this._flushStartFns(),this._specialStyles&&this._specialStyles.finish(),this._flushDoneFns())}setPosition(s){this._styler.setPosition(s)}getPosition(){return this._styler.getPosition()}hasStarted(){return this._state>=2}init(){this._state>=1||(this._state=1,this._styler.apply(),this._delay&&this._styler.pause())}play(){this.init(),this.hasStarted()||(this._flushStartFns(),this._state=2,this._specialStyles&&this._specialStyles.start()),this._styler.resume()}pause(){this.init(),this._styler.pause()}restart(){this.reset(),this.play()}reset(){this._state=0,this._styler.destroy(),this._buildStyler(),this._styler.apply()}_buildStyler(){this._styler=new qc(this.element,this.animationName,this._duration,this._delay,this.easing,"forwards",()=>this.finish())}triggerCallback(s){const t="start"==s?this._onStartFns:this._onDoneFns;t.forEach(o=>o()),t.length=0}beforeDestroy(){this.init();const s={};if(this.hasStarted()){const t=this._state>=3;Object.keys(this._finalStyles).forEach(o=>{"offset"!=o&&(s[o]=t?this._finalStyles[o]:gn(this.element,o))})}this.currentSnapshot=s}}class Me extends S.ZN{constructor(s,t){super(),this.element=s,this._startingStyles={},this.__initialized=!1,this._styles=Vt(t)}init(){this.__initialized||!this._startingStyles||(this.__initialized=!0,Object.keys(this._styles).forEach(s=>{this._startingStyles[s]=this.element.style[s]}),super.init())}play(){!this._startingStyles||(this.init(),Object.keys(this._styles).forEach(s=>this.element.style.setProperty(s,this._styles[s])),super.play())}destroy(){!this._startingStyles||(Object.keys(this._startingStyles).forEach(s=>{const t=this._startingStyles[s];t?this.element.style.setProperty(s,t):this.element.style.removeProperty(s)}),this._startingStyles=null,super.destroy())}}class ur{constructor(){this._count=0}validateStyleProperty(s){return ze(s)}matchesElement(s,t){return Pe(s,t)}containsElement(s,t){return je(s,t)}query(s,t,o){return He(s,t,o)}computeStyle(s,t,o){return window.getComputedStyle(s)[t]}buildKeyframeElement(s,t,o){o=o.map(D=>Vt(D));let c=`@keyframes ${t} {\n`,g="";o.forEach(D=>{g=" ";const P=parseFloat(D.offset);c+=`${g}${100*P}% {\n`,g+=" ",Object.keys(D).forEach(j=>{const W=D[j];switch(j){case"offset":return;case"easing":return void(W&&(c+=`${g}animation-timing-function: ${W};\n`));default:return void(c+=`${g}${j}: ${W};\n`)}}),c+=`${g}}\n`}),c+="}\n";const C=document.createElement("style");return C.textContent=c,C}animate(s,t,o,c,g,C=[],D){const P=C.filter(Re=>Re instanceof Te),j={};wi(o,c)&&P.forEach(Re=>{let Le=Re.currentSnapshot;Object.keys(Le).forEach(we=>j[we]=Le[we])});const W=function(n){let s={};return n&&(Array.isArray(n)?n:[n]).forEach(o=>{Object.keys(o).forEach(c=>{"offset"==c||"easing"==c||(s[c]=o[c])})}),s}(t=br(s,t,j));if(0==o)return new Me(s,W);const re="gen_css_kf_"+this._count++,oe=this.buildKeyframeElement(s,re,t);(function(n){var s;const t=null===(s=n.getRootNode)||void 0===s?void 0:s.call(n);return"undefined"!=typeof ShadowRoot&&t instanceof ShadowRoot?t:document.head})(s).appendChild(oe);const _e=ko(s,t),Fe=new Te(s,t,re,o,c,g,W,_e);return Fe.onDestroy(()=>{var n;(n=oe).parentNode.removeChild(n)}),Fe}}class Ma{constructor(s,t,o,c){this.element=s,this.keyframes=t,this.options=o,this._specialStyles=c,this._onDoneFns=[],this._onStartFns=[],this._onDestroyFns=[],this._initialized=!1,this._finished=!1,this._started=!1,this._destroyed=!1,this.time=0,this.parentPlayer=null,this.currentSnapshot={},this._duration=o.duration,this._delay=o.delay||0,this.time=this._duration+this._delay}_onFinish(){this._finished||(this._finished=!0,this._onDoneFns.forEach(s=>s()),this._onDoneFns=[])}init(){this._buildPlayer(),this._preparePlayerBeforeStart()}_buildPlayer(){if(this._initialized)return;this._initialized=!0;const s=this.keyframes;this.domPlayer=this._triggerWebAnimation(this.element,s,this.options),this._finalKeyframe=s.length?s[s.length-1]:{},this.domPlayer.addEventListener("finish",()=>this._onFinish())}_preparePlayerBeforeStart(){this._delay?this._resetDomPlayerState():this.domPlayer.pause()}_triggerWebAnimation(s,t,o){return s.animate(t,o)}onStart(s){this._onStartFns.push(s)}onDone(s){this._onDoneFns.push(s)}onDestroy(s){this._onDestroyFns.push(s)}play(){this._buildPlayer(),this.hasStarted()||(this._onStartFns.forEach(s=>s()),this._onStartFns=[],this._started=!0,this._specialStyles&&this._specialStyles.start()),this.domPlayer.play()}pause(){this.init(),this.domPlayer.pause()}finish(){this.init(),this._specialStyles&&this._specialStyles.finish(),this._onFinish(),this.domPlayer.finish()}reset(){this._resetDomPlayerState(),this._destroyed=!1,this._finished=!1,this._started=!1}_resetDomPlayerState(){this.domPlayer&&this.domPlayer.cancel()}restart(){this.reset(),this.play()}hasStarted(){return this._started}destroy(){this._destroyed||(this._destroyed=!0,this._resetDomPlayerState(),this._onFinish(),this._specialStyles&&this._specialStyles.destroy(),this._onDestroyFns.forEach(s=>s()),this._onDestroyFns=[])}setPosition(s){void 0===this.domPlayer&&this.init(),this.domPlayer.currentTime=s*this.time}getPosition(){return this.domPlayer.currentTime/this.time}get totalTime(){return this._delay+this._duration}beforeDestroy(){const s={};this.hasStarted()&&Object.keys(this._finalKeyframe).forEach(t=>{"offset"!=t&&(s[t]=this._finished?this._finalKeyframe[t]:gn(this.element,t))}),this.currentSnapshot=s}triggerCallback(s){const t="start"==s?this._onStartFns:this._onDoneFns;t.forEach(o=>o()),t.length=0}}class au{constructor(){this._isNativeImpl=/\{\s*\[native\s+code\]\s*\}/.test(Rl().toString()),this._cssKeyframesDriver=new ur}validateStyleProperty(s){return ze(s)}matchesElement(s,t){return Pe(s,t)}containsElement(s,t){return je(s,t)}query(s,t,o){return He(s,t,o)}computeStyle(s,t,o){return window.getComputedStyle(s)[t]}overrideWebAnimationsSupport(s){this._isNativeImpl=s}animate(s,t,o,c,g,C=[],D){if(!D&&!this._isNativeImpl)return this._cssKeyframesDriver.animate(s,t,o,c,g,C);const W={duration:o,delay:c,fill:0==c?"both":"forwards"};g&&(W.easing=g);const re={},oe=C.filter(_e=>_e instanceof Ma);wi(o,c)&&oe.forEach(_e=>{let Fe=_e.currentSnapshot;Object.keys(Fe).forEach(Re=>re[Re]=Fe[Re])});const me=ko(s,t=br(s,t=t.map(_e=>Br(_e,!1)),re));return new Ma(s,t,W,me)}}function Rl(){return A()&&Element.prototype.animate||{}}let nc=(()=>{class n extends S._j{constructor(t,o){super(),this._nextAnimationId=0,this._renderer=t.createRenderer(o.body,{id:"0",encapsulation:e.ifc.None,styles:[],data:{animation:[]}})}build(t){const o=this._nextAnimationId.toString();this._nextAnimationId++;const c=Array.isArray(t)?(0,S.vP)(t):t;return Lc(this._renderer,null,o,"register",[c]),new Al(o,this._renderer)}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(e.FYo),e.LFG(_.K0))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac}),n})();class Al extends S.LC{constructor(s,t){super(),this._id=s,this._renderer=t}create(s,t){return new vs(this._id,s,t||{},this._renderer)}}class vs{constructor(s,t,o,c){this.id=s,this.element=t,this._renderer=c,this.parentPlayer=null,this._started=!1,this.totalTime=0,this._command("create",o)}_listen(s,t){return this._renderer.listen(this.element,`@@${this.id}:${s}`,t)}_command(s,...t){return Lc(this._renderer,this.element,this.id,s,t)}onDone(s){this._listen("done",s)}onStart(s){this._listen("start",s)}onDestroy(s){this._listen("destroy",s)}init(){this._command("init")}hasStarted(){return this._started}play(){this._command("play"),this._started=!0}pause(){this._command("pause")}restart(){this._command("restart")}finish(){this._command("finish")}destroy(){this._command("destroy")}reset(){this._command("reset"),this._started=!1}setPosition(s){this._command("setPosition",s)}getPosition(){var s,t;return null!==(t=null===(s=this._renderer.engine.players[+this.id])||void 0===s?void 0:s.getPosition())&&void 0!==t?t:0}}function Lc(n,s,t,o,c){return n.setProperty(s,`@@${t}:${o}`,c)}const Fc="@.disabled";let Cu=(()=>{class n{constructor(t,o,c){this.delegate=t,this.engine=o,this._zone=c,this._currentId=0,this._microtaskId=1,this._animationCallbacksBuffer=[],this._rendererCache=new Map,this._cdRecurDepth=0,this.promise=Promise.resolve(0),o.onRemovalComplete=(g,C)=>{C&&C.parentNode(g)&&C.removeChild(g.parentNode,g)}}createRenderer(t,o){const g=this.delegate.createRenderer(t,o);if(!(t&&o&&o.data&&o.data.animation)){let W=this._rendererCache.get(g);return W||(W=new kc("",g,this.engine),this._rendererCache.set(g,W)),W}const C=o.id,D=o.id+"-"+this._currentId;this._currentId++,this.engine.register(D,t);const P=W=>{Array.isArray(W)?W.forEach(P):this.engine.registerTrigger(C,D,t,W.name,W)};return o.data.animation.forEach(P),new gd(this,D,g,this.engine)}begin(){this._cdRecurDepth++,this.delegate.begin&&this.delegate.begin()}_scheduleCountTask(){this.promise.then(()=>{this._microtaskId++})}scheduleListenerCallback(t,o,c){t>=0&&t<this._microtaskId?this._zone.run(()=>o(c)):(0==this._animationCallbacksBuffer.length&&Promise.resolve(null).then(()=>{this._zone.run(()=>{this._animationCallbacksBuffer.forEach(g=>{const[C,D]=g;C(D)}),this._animationCallbacksBuffer=[]})}),this._animationCallbacksBuffer.push([o,c]))}end(){this._cdRecurDepth--,0==this._cdRecurDepth&&this._zone.runOutsideAngular(()=>{this._scheduleCountTask(),this.engine.flush(this._microtaskId)}),this.delegate.end&&this.delegate.end()}whenRenderingDone(){return this.engine.whenRenderingDone()}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(e.FYo),e.LFG(wo),e.LFG(e.R0b))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac}),n})();class kc{constructor(s,t,o){this.namespaceId=s,this.delegate=t,this.engine=o,this.destroyNode=this.delegate.destroyNode?c=>t.destroyNode(c):null}get data(){return this.delegate.data}destroy(){this.engine.destroy(this.namespaceId,this.delegate),this.delegate.destroy()}createElement(s,t){return this.delegate.createElement(s,t)}createComment(s){return this.delegate.createComment(s)}createText(s){return this.delegate.createText(s)}appendChild(s,t){this.delegate.appendChild(s,t),this.engine.onInsert(this.namespaceId,t,s,!1)}insertBefore(s,t,o,c=!0){this.delegate.insertBefore(s,t,o),this.engine.onInsert(this.namespaceId,t,s,c)}removeChild(s,t,o){this.engine.onRemove(this.namespaceId,t,this.delegate,o)}selectRootElement(s,t){return this.delegate.selectRootElement(s,t)}parentNode(s){return this.delegate.parentNode(s)}nextSibling(s){return this.delegate.nextSibling(s)}setAttribute(s,t,o,c){this.delegate.setAttribute(s,t,o,c)}removeAttribute(s,t,o){this.delegate.removeAttribute(s,t,o)}addClass(s,t){this.delegate.addClass(s,t)}removeClass(s,t){this.delegate.removeClass(s,t)}setStyle(s,t,o,c){this.delegate.setStyle(s,t,o,c)}removeStyle(s,t,o){this.delegate.removeStyle(s,t,o)}setProperty(s,t,o){"@"==t.charAt(0)&&t==Fc?this.disableAnimations(s,!!o):this.delegate.setProperty(s,t,o)}setValue(s,t){this.delegate.setValue(s,t)}listen(s,t,o){return this.delegate.listen(s,t,o)}disableAnimations(s,t){this.engine.disableAnimations(s,t)}}class gd extends kc{constructor(s,t,o,c){super(t,o,c),this.factory=s,this.namespaceId=t}setProperty(s,t,o){"@"==t.charAt(0)?"."==t.charAt(1)&&t==Fc?this.disableAnimations(s,o=void 0===o||!!o):this.engine.process(this.namespaceId,s,t.substr(1),o):this.delegate.setProperty(s,t,o)}listen(s,t,o){if("@"==t.charAt(0)){const c=function(n){switch(n){case"body":return document.body;case"document":return document;case"window":return window;default:return n}}(s);let g=t.substr(1),C="";return"@"!=g.charAt(0)&&([g,C]=function(n){const s=n.indexOf(".");return[n.substring(0,s),n.substr(s+1)]}(g)),this.engine.listen(this.namespaceId,c,g,C,D=>{this.factory.scheduleListenerCallback(D._data||-1,o,D)})}return this.delegate.listen(s,t,o)}}let sa=(()=>{class n extends wo{constructor(t,o,c){super(t.body,o,c)}ngOnDestroy(){this.flush()}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(_.K0),e.LFG(tn),e.LFG(tr))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac}),n})();const yl=new e.OlP("AnimationModuleType"),Mu=[{provide:S._j,useClass:nc},{provide:tr,useFactory:function(){return new Rt}},{provide:wo,useClass:sa},{provide:e.FYo,useFactory:function(n,s,t){return new Cu(n,s,t)},deps:[d.se,wo,e.R0b]}],yu=[{provide:tn,useFactory:function(){return"function"==typeof Rl()?new au:new ur}},{provide:yl,useValue:"BrowserAnimations"},...Mu],lu=[{provide:tn,useClass:it},{provide:yl,useValue:"NoopAnimations"},...Mu];let js=(()=>{class n{static withConfig(t){return{ngModule:n,providers:t.disableAnimations?lu:yu}}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275mod=e.oAB({type:n}),n.\u0275inj=e.cJS({providers:yu,imports:[d.b2]}),n})();var Uu=i(91376),Bo=i(6283),uu=i(23815),wr=i.n(uu),fa=i(64762),pu=i(93523);let aa=class{constructor(s){this.http=s,this.baseURL="api/cephfs",this.baseUiURL="ui-api/cephfs"}list(){return this.http.get(`${this.baseURL}`)}lsDir(s,t){let o=`${this.baseUiURL}/${s}/ls_dir?depth=2`;return t&&(o+=`&path=${encodeURIComponent(t)}`),this.http.get(o)}getCephfs(s){return this.http.get(`${this.baseURL}/${s}`)}getTabs(s){return this.http.get(`ui-api/cephfs/${s}/tabs`)}getClients(s){return this.http.get(`${this.baseURL}/${s}/clients`)}evictClient(s,t){return this.http.delete(`${this.baseURL}/${s}/client/${t}`)}getMdsCounters(s){return this.http.get(`${this.baseURL}/${s}/mds_counters`)}mkSnapshot(s,t,o){let c=new y.LE;return c=c.append("path",t),wr().isUndefined(o)||(c=c.append("name",o)),this.http.post(`${this.baseURL}/${s}/snapshot`,null,{params:c})}rmSnapshot(s,t,o){let c=new y.LE;return c=c.append("path",t),c=c.append("name",o),this.http.delete(`${this.baseURL}/${s}/snapshot`,{params:c})}quota(s,t,o){let c=new y.LE;return c=c.append("path",t),this.http.put(`${this.baseURL}/${s}/quota`,o,{observe:"response",params:c})}};aa.\u0275fac=function(s){return new(s||aa)(e.LFG(y.eN))},aa.\u0275prov=e.Yz7({token:aa,factory:aa.\u0275fac,providedIn:"root"}),aa=(0,fa.gn)([pu.o,(0,fa.w6)("design:paramtypes",[y.eN])],aa);var jl=i(68136),bl=i(99466),El=i(68774),Ul=i(96102),ks=i(35905),V=i(46797),Ae=i(69158),st=i(91801),vt=i(74937),ut=i(38549),un=i(59376),mn=i(47557),Or=i(66369),zr=i(61350),gi=i(16738),ai=i.n(gi),Io=i(87311),Fo=i(7194);const In=["chartCanvas"],Cr=["chartTooltip"];let hr=(()=>{class n{constructor(){this.lhsCounter="mds_mem.ino",this.rhsCounter="mds_server.handle_client_request",this.chart={datasets:[{label:this.lhsCounter,yAxisID:"LHS",data:[],lineTension:.1},{label:this.rhsCounter,yAxisID:"RHS",data:[],lineTension:.1}],options:{title:{text:"",display:!0},responsive:!0,maintainAspectRatio:!1,legend:{position:"top"},scales:{xAxes:[{position:"top",type:"time",time:{displayFormats:{quarter:"MMM YYYY"}},ticks:{maxRotation:0}}],yAxes:[{id:"LHS",type:"linear",position:"left"},{id:"RHS",type:"linear",position:"right"}]},tooltips:{enabled:!1,mode:"index",intersect:!1,position:"nearest",callbacks:{title:(t,o)=>{let c=0;if(t.length>0){const g=t[0];c=o.datasets[g.datasetIndex].data[g.index].x}return c.toString()}}}},chartType:"line"}}ngOnInit(){wr().isUndefined(this.mdsCounter)||(this.setChartTooltip(),this.updateChart())}ngOnChanges(){wr().isUndefined(this.mdsCounter)||this.updateChart()}setChartTooltip(){const t=new Io.h(this.chartCanvas,this.chartTooltip,c=>c.caretX+"px",c=>c.caretY-c.height-23+"px");t.getTitle=c=>ai()(c,"x").format("LTS"),t.checkOffset=!0;const o={title:{text:this.mdsCounter.name},tooltips:{custom:c=>t.customTooltips(c)}};wr().merge(this.chart,{options:o})}updateChart(){const t=[{data:this.convertTimeSeries(this.mdsCounter[this.lhsCounter])},{data:this.deltaTimeSeries(this.mdsCounter[this.rhsCounter])}];wr().merge(this.chart,{datasets:t}),this.chart.datasets=[...this.chart.datasets]}convertTimeSeries(t){const o=[];return wr().each(t,c=>{o.push({x:1e3*c[0],y:c[1]})}),o.shift(),o}deltaTimeSeries(t){let o,c=t[0];const g=[];for(o=1;o<t.length;o++){const C=t[o];g.push({x:1e3*C[0],y:C[1]-c[1]}),c=C}return g}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-cephfs-chart"]],viewQuery:function(t,o){if(1&t&&(e.Gf(In,7),e.Gf(Cr,7)),2&t){let c;e.iGM(c=e.CRH())&&(o.chartCanvas=c.first),e.iGM(c=e.CRH())&&(o.chartTooltip=c.first)}},inputs:{mdsCounter:"mdsCounter"},features:[e.TTD],decls:6,vars:3,consts:[[1,"chart-container"],["baseChart","",3,"datasets","options","chartType"],["chartCanvas",""],[1,"chartjs-tooltip"],["chartTooltip",""]],template:function(t,o){1&t&&(e.TgZ(0,"div",0),e._UZ(1,"canvas",1,2),e.TgZ(3,"div",3,4),e._UZ(5,"table"),e.qZA(),e.qZA()),2&t&&(e.xp6(1),e.Q6J("datasets",o.chart.datasets)("options",o.chart.options)("chartType",o.chart.chartType))},directives:[Fo.jh],styles:['.chart-container[_ngcontent-%COMP%]{cursor:pointer;margin:auto;overflow:visible;position:absolute}canvas[_ngcontent-%COMP%]{user-select:none}.chartjs-tooltip[_ngcontent-%COMP%]{background:rgba(0,0,0,.7);border-radius:3px;color:#fff;font-family:"Helvetica Neue","Helvetica","Arial",sans-serif!important;opacity:0;pointer-events:none;position:absolute;transform:translate(-50%);transition:all .1s ease}.chartjs-tooltip.transform-left[_ngcontent-%COMP%]{transform:translate(-10%)}.chartjs-tooltip.transform-left[_ngcontent-%COMP%]:after{left:10%}.chartjs-tooltip.transform-right[_ngcontent-%COMP%]{transform:translate(-90%)}.chartjs-tooltip.transform-right[_ngcontent-%COMP%]:after{left:90%}.chartjs-tooltip[_ngcontent-%COMP%]:after{border-color:#000 transparent transparent transparent;border-style:solid;border-width:5px;content:" ";left:50%;margin-left:-5px;position:absolute;top:100%} .chartjs-tooltip-key{display:inline-block;height:10px;margin-right:10px;width:10px}.chart-container[_ngcontent-%COMP%]{height:500px;margin-bottom:20px;position:relative;width:100%}']}),n})();var ao=i(60251);const ys=["poolUsageTpl"],Na=["activityTmpl"];function Tl(n,s){if(1&n&&(e.TgZ(0,"div",0),e.TgZ(1,"div",11),e._UZ(2,"cd-cephfs-chart",12),e.qZA(),e.qZA()),2&n){const t=s.$implicit;e.xp6(2),e.Q6J("mdsCounter",t)}}function Qs(n,s){if(1&n&&e._UZ(0,"cd-usage-bar",13),2&n){const t=s.row;e.Q6J("total",t.size)("used",t.used)}}function ed(n,s){1&n&&(e._uU(0),e.ALo(1,"dimless")),2&n&&e.AsE(" ","standby-replay"===s.row.state?"Evts":"Reqs",": ",e.lcZ(1,2,s.value)," /s\n")}let $c=(()=>{class n{constructor(t,o){this.dimlessBinary=t,this.dimless=o,this.standbys=[],this.objectValues=Object.values}ngOnChanges(){this.setStandbys()}setStandbys(){this.standbys=[{key:"Standby daemons",value:this.data.standbys}]}ngOnInit(){this.columns={ranks:[{prop:"rank",name:"Rank"},{prop:"state",name:"State"},{prop:"mds",name:"Daemon"},{prop:"activity",name:"Activity",cellTemplate:this.activityTmpl},{prop:"dns",name:"Dentries",pipe:this.dimless},{prop:"inos",name:"Inodes",pipe:this.dimless},{prop:"dirs",name:"Dirs",pipe:this.dimless},{prop:"caps",name:"Caps",pipe:this.dimless}],pools:[{prop:"pool",name:"Pool"},{prop:"type",name:"Type"},{prop:"size",name:"Size",pipe:this.dimlessBinary},{name:"Usage",cellTemplate:this.poolUsageTpl,comparator:(t,o,c,g)=>{const C=c.used/c.avail,D=g.used/g.avail;return C===D?0:C>D?1:-1}}]}}trackByFn(t,o){return o.name}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(mn.$),e.Y36(Or.n))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-cephfs-detail"]],viewQuery:function(t,o){if(1&t&&(e.Gf(ys,7),e.Gf(Na,7)),2&t){let c;e.iGM(c=e.CRH())&&(o.poolUsageTpl=c.first),e.iGM(c=e.CRH())&&(o.activityTmpl=c.first)}},inputs:{data:"data"},features:[e.TTD],decls:19,vars:9,consts:function(){let s,t,o,c;return s="Ranks",t="Standbys",o="Pools",c="MDS performance counters",[[1,"row"],[1,"col-sm-6"],s,[3,"data","columns","toolHeader"],t,[3,"data"],o,c,["class","row",4,"ngFor","ngForOf","ngForTrackBy"],["poolUsageTpl",""],["activityTmpl",""],[1,"col-md-12"],[3,"mdsCounter"],[3,"total","used"]]},template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"div",1),e.TgZ(2,"legend"),e.SDv(3,2),e.qZA(),e._UZ(4,"cd-table",3),e.TgZ(5,"legend"),e.SDv(6,4),e.qZA(),e._UZ(7,"cd-table-key-value",5),e.qZA(),e.TgZ(8,"div",1),e.TgZ(9,"legend"),e.SDv(10,6),e.qZA(),e._UZ(11,"cd-table",3),e.qZA(),e.qZA(),e.TgZ(12,"legend"),e.SDv(13,7),e.qZA(),e.YNc(14,Tl,3,1,"div",8),e.YNc(15,Qs,1,2,"ng-template",null,9,e.W1O),e.YNc(17,ed,2,4,"ng-template",null,10,e.W1O)),2&t&&(e.xp6(4),e.Q6J("data",o.data.ranks)("columns",o.columns.ranks)("toolHeader",!1),e.xp6(3),e.Q6J("data",o.standbys),e.xp6(4),e.Q6J("data",o.data.pools)("columns",o.columns.pools)("toolHeader",!1),e.xp6(3),e.Q6J("ngForOf",o.objectValues(o.data.mdsCounters))("ngForTrackBy",o.trackByFn))},directives:[ks.a,zr.b,_.sg,hr,ao.O],pipes:[Or.n],styles:[".progress[_ngcontent-%COMP%]{margin-bottom:0}"]}),n})();var Gl=i(30982),$i=i(79512),xo=i(65862),pa=i(18001),hl=i(97161),Bl=i(63285),Js=i(94928);let md=(()=>{class n{constructor(t,o,c,g,C){this.cephfsService=t,this.modalService=o,this.notificationService=c,this.authStorageService=g,this.actionLabels=C,this.triggerApiUpdate=new e.vpe,this.selection=new El.r,this.permission=this.authStorageService.getPermissions().cephfs,this.tableActions=[{permission:"update",icon:xo.P.signOut,click:()=>this.evictClientModal(),name:this.actionLabels.EVICT}]}ngOnInit(){this.columns=[{prop:"id",name:"id"},{prop:"type",name:"type"},{prop:"state",name:"state"},{prop:"version",name:"version"},{prop:"hostname",name:"Host"},{prop:"root",name:"root"}]}updateSelection(t){this.selection=t}evictClient(t){this.cephfsService.evictClient(this.id,t).subscribe(()=>{this.triggerApiUpdate.emit(),this.modalRef.close(),this.notificationService.show(pa.k.success,"Evicted client '" + t + "'")},()=>{this.modalRef.componentInstance.stopLoadingSpinner()})}evictClientModal(){const t=this.selection.first().id;this.modalRef=this.modalService.show(Gl.M,{itemDescription:"client",itemNames:[t],actionDescription:"evict",submitAction:()=>this.evictClient(t)})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(aa),e.Y36(Bl.Z),e.Y36(hl.g),e.Y36(vt.j),e.Y36($i.p4))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-cephfs-clients"]],inputs:{id:"id",clients:"clients"},outputs:{triggerApiUpdate:"triggerApiUpdate"},decls:2,vars:7,consts:[["selectionType","single",3,"data","columns","status","autoReload","fetchData","updateSelection"],[1,"table-actions",3,"permission","selection","tableActions"]],template:function(t,o){1&t&&(e.TgZ(0,"cd-table",0),e.NdJ("fetchData",function(){return o.triggerApiUpdate.emit()})("updateSelection",function(g){return o.updateSelection(g)}),e._UZ(1,"cd-table-actions",1),e.qZA()),2&t&&(e.Q6J("data",o.clients.data)("columns",o.columns)("status",o.clients.status)("autoReload",-1),e.xp6(1),e.Q6J("permission",o.permission)("selection",o.selection)("tableActions",o.tableActions))},directives:[ks.a,Js.K],styles:[""]}),n})();var Mn=i(24751),Nl=i(19723),td=i(36169),zd=i(65683),ss=i(77205),la=i(87925);const Zc=["origin"],ic=function(n,s){return[n,s]};function df(n,s){if(1&n&&e._UZ(0,"i",5),2&n){const t=e.oxw(2);e.Q6J("ngClass",e.WLB(1,ic,t.icons.spinner,t.icons.spin))}}function al(n,s){if(1&n&&(e.TgZ(0,"tree-root",10),e.YNc(1,df,1,4,"ng-template",null,11,e.W1O),e.qZA()),2&n){const t=e.oxw();e.Q6J("nodes",t.nodes)("options",t.treeOptions)}}function Wd(n,s){if(1&n){const t=e.EpF();e.ynx(0),e.TgZ(1,"legend"),e.SDv(2,17),e.qZA(),e.TgZ(3,"cd-table",18),e.NdJ("updateSelection",function(c){return e.CHM(t),e.oxw(2).quota.updateSelection(c)}),e._UZ(4,"cd-table-actions",19),e.qZA(),e.BQk()}if(2&n){const t=e.oxw(2);e.xp6(3),e.Q6J("data",t.settings)("columns",t.quota.columns)("limit",0)("footer",!1)("onlyActionHeader",!0)("forceIdentifier",!0)("toolHeader",!1),e.xp6(1),e.Q6J("permission",t.permission)("selection",t.quota.selection)("tableActions",t.quota.tableActions)}}function Jd(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",12),e.TgZ(1,"div",2),e.TgZ(2,"div",3),e._uU(3),e.qZA(),e.TgZ(4,"div",6),e.YNc(5,Wd,5,10,"ng-container",13),e.TgZ(6,"legend"),e.SDv(7,14),e.qZA(),e.TgZ(8,"cd-table",15),e.NdJ("updateSelection",function(c){return e.CHM(t),e.oxw().snapshot.updateSelection(c)}),e._UZ(9,"cd-table-actions",16),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=e.oxw();e.xp6(3),e.hij(" ",t.selectedDir.path," "),e.xp6(2),e.Q6J("ngIf","/"!==t.selectedDir.path),e.xp6(3),e.Q6J("data",t.selectedDir.snapshots)("columns",t.snapshot.columns),e.xp6(1),e.Q6J("permission",t.permission)("selection",t.snapshot.selection)("tableActions",t.snapshot.tableActions)}}function Ye(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"span",20),e.NdJ("click",function(){const g=e.CHM(t).value;return e.oxw().selectOrigin(g)}),e._uU(1),e.qZA()}if(2&n){const t=s.value;e.xp6(1),e.Oqu(t)}}let Ce=(()=>{class n{constructor(t,o,c,g,C,D,P){this.authStorageService=t,this.modalService=o,this.cephfsService=c,this.cdDatePipe=g,this.actionLabels=C,this.notificationService=D,this.dimlessBinaryPipe=P,this.icons=xo.P,this.loadingIndicator=!1,this.loading={},this.treeOptions={useVirtualScroll:!0,getChildren:j=>this.updateDirectory(j.id),actionMapping:{mouse:{click:this.selectAndShowNode.bind(this),expanderClick:this.selectAndShowNode.bind(this)}}}}selectAndShowNode(t,o,c){Nl.iM.TOGGLE_EXPANDED(t,o,c),this.selectNode(o)}selectNode(t){Nl.iM.TOGGLE_ACTIVE(void 0,t,void 0),this.selectedDir=this.getDirectory(t),"/"!==t.id&&this.setSettings(t)}ngOnInit(){this.permission=this.authStorageService.getPermissions().cephfs,this.setUpQuotaTable(),this.setUpSnapshotTable()}setUpQuotaTable(){this.quota={columns:[{prop:"row.name",name:"Name",flexGrow:1},{prop:"row.value",name:"Value",sortable:!1,flexGrow:1},{prop:"row.originPath",name:"Origin",sortable:!1,cellTemplate:this.originTmpl,flexGrow:1}],selection:new El.r,updateSelection:t=>{this.quota.selection=t},tableActions:[{name:this.actionLabels.SET,icon:xo.P.edit,permission:"update",visible:t=>!t.hasSelection||t.first()&&0===t.first().dirValue,click:()=>this.updateQuotaModal()},{name:this.actionLabels.UPDATE,icon:xo.P.edit,permission:"update",visible:t=>t.first()&&t.first().dirValue>0,click:()=>this.updateQuotaModal()},{name:this.actionLabels.UNSET,icon:xo.P.destroy,permission:"update",disable:t=>!t.hasSelection||t.first()&&0===t.first().dirValue,click:()=>this.unsetQuotaModal()}]}}setUpSnapshotTable(){this.snapshot={columns:[{prop:"name",name:"Name",flexGrow:1},{prop:"path",name:"Path",isHidden:!0,flexGrow:2},{prop:"created",name:"Created",flexGrow:1,pipe:this.cdDatePipe}],selection:new El.r,updateSelection:t=>{this.snapshot.selection=t},tableActions:[{name:this.actionLabels.CREATE,icon:xo.P.add,permission:"create",canBePrimary:t=>!t.hasSelection,click:()=>this.createSnapshot(),disable:()=>this.disableCreateSnapshot()},{name:this.actionLabels.DELETE,icon:xo.P.destroy,permission:"delete",click:()=>this.deleteSnapshotModal(),canBePrimary:t=>t.hasSelection,disable:t=>!t.hasSelection}]}}disableCreateSnapshot(){const t=this.selectedDir.path.split("/").slice(1);return t.length>=4&&"volumes"===t[0]&&"Cannot create snapshots for files/folders in the subvolume " + t[2] + ""}ngOnChanges(){this.selectedDir=void 0,this.dirs=[],this.requestedPaths=[],this.nodeIds={},this.id&&(this.setRootNode(),this.firstCall())}setRootNode(){this.nodes=[{name:"/",id:"/",isExpanded:!0}]}firstCall(){setTimeout(()=>{this.getNode("/").loadNodeChildren()},10)}updateDirectory(t){if(this.unsetLoadingIndicator(),this.requestedPaths.includes(t)){if(!0===this.loading[t])return}else this.requestedPaths.push(t);return new Promise(o=>{this.setLoadingIndicator(t,!0),this.cephfsService.lsDir(this.id,t).subscribe(c=>{this.updateTreeStructure(c),this.updateQuotaTable(),this.updateTree(),o(this.getChildren(t)),this.setLoadingIndicator(t,!1)})})}setLoadingIndicator(t,o){this.loading[t]=o,this.unsetLoadingIndicator()}getSubDirectories(t,o=this.dirs){return o.filter(c=>c.parent===t)}getChildren(t){const o=this.getSubTree(t);return wr().sortBy(this.getSubDirectories(t),"path").map(c=>this.createNode(c,o))}createNode(t,o){return this.nodeIds[t.path]=t,o||this.getSubTree(t.parent),{name:t.name,id:t.path,hasChildren:this.getSubDirectories(t.path,o).length>0}}getSubTree(t){return this.dirs.filter(o=>o.parent&&o.parent.startsWith(t))}setSettings(t){const o=(c,g)=>c?g?g(c):c:"";this.settings=[this.getQuota(t,"max_files",o),this.getQuota(t,"max_bytes",c=>o(c,g=>this.dimlessBinaryPipe.transform(g)))]}getQuota(t,o,c){const g=t.id;t=this.getOrigin(t,o);const C=this.getDirectory(t),D=C.quotas[o];let P=D,j=C.path;if(t.id===g)if("/"===t.parent.id)P=0;else{const W=this.getDirectory(this.getOrigin(t.parent,o));P=W.quotas[o],j=W.path}return{row:{name:"max_bytes"===o?"Max size":"Max files",value:c(D),originPath:D?C.path:""},quotaKey:o,dirValue:this.nodeIds[g].quotas[o],nextTreeMaximum:{value:P,path:P?j:""}}}getOrigin(t,o){if(t.parent&&"/"!==t.parent.id){const c=this.getQuotaFromTree(t,o),g=this.getOrigin(t.parent,o),C=this.getQuotaFromTree(g,o);return 0===c||0!==C&&C<c?g:t}return t}getQuotaFromTree(t,o){return this.getDirectory(t).quotas[o]}getDirectory(t){return this.nodeIds[t.id]}selectOrigin(t){this.selectNode(this.getNode(t))}getNode(t){return this.treeComponent.treeModel.getNodeById(t)}updateQuotaModal(){const t=this.selectedDir.path,o=this.quota.selection.first(),c=o.nextTreeMaximum,g=o.quotaKey,C=o.dirValue;this.modalService.show(zd.X,{titleText:this.getModalQuotaTitle(0===C?this.actionLabels.SET:this.actionLabels.UPDATE,t),message:c.value?"The inherited " + this.getQuotaValueFromPathMsg(c.value, c.path) + " is the maximum value to be used.":void 0,fields:[this.getQuotaFormField(o.row.name,g,C,c.value)],submitButtonText:"Save",onSubmit:D=>this.updateQuota(D)})}getModalQuotaTitle(t,o){return "" + t + " CephFS " + this.getQuotaName() + " quota for '" + o + "'"}getQuotaName(){return this.isBytesQuotaSelected()?"size":"files"}isBytesQuotaSelected(){return"max_bytes"===this.quota.selection.first().quotaKey}getQuotaValueFromPathMsg(t,o){return t=this.isBytesQuotaSelected()?this.dimlessBinaryPipe.transform(t):t,"" + this.getQuotaName() + " quota " + t + " from '" + o + "'"}getQuotaFormField(t,o,c,g){const C="max_bytes"===o,D=[C?ss.h.binaryMin(0):Mn.kI.min(0)];g&&D.push(C?ss.h.binaryMax(g):Mn.kI.max(g));const P={type:C?"binary":"number",label:t,name:o,value:c,validators:D,required:!0};return C||(P.errors={min:"Value has to be at least 0 or more",max:"Value has to be at most " + g + " or less"}),P}updateQuota(t,o){const c=this.selectedDir.path,g=this.quota.selection.first().quotaKey,C=0===this.selectedDir.quotas[g]?this.actionLabels.SET:0===t[g]?this.actionLabels.UNSET:"Updated";this.cephfsService.quota(this.id,c,t).subscribe(()=>{o&&o(),this.notificationService.show(pa.k.success,this.getModalQuotaTitle(C,c)),this.forceDirRefresh()})}unsetQuotaModal(){const t=this.selectedDir.path,o=this.quota.selection.first(),c=o.quotaKey,g=o.nextTreeMaximum,C=o.dirValue,D=this.getQuotaValueFromPathMsg(g.value,g.path),P=g.value>0?g.value>C?"in order to inherit " + D + "":"which isn't used because of the inheritance of " + D + "":"in order to have no quota on the directory";this.modalRef=this.modalService.show(td.Y,{titleText:this.getModalQuotaTitle(this.actionLabels.UNSET,t),buttonText:this.actionLabels.UNSET,description:"" + this.actionLabels.UNSET + " " + this.getQuotaValueFromPathMsg(C, t) + " " + P + ".",onSubmit:()=>this.updateQuota({[c]:0},()=>this.modalRef.close())})}createSnapshot(){const t=this.selectedDir.path;this.modalService.show(zd.X,{titleText:"Create Snapshot",message:"Please enter the name of the snapshot.",fields:[{type:"text",name:"name",value:`${ai()().toISOString(!0)}`,required:!0,validators:[this.validateValue.bind(this)]}],submitButtonText:"Create Snapshot",onSubmit:o=>{this.alreadyExists?this.notificationService.show(pa.k.error,"Snapshot name '" + o.name + "' is already in use. Please use another name."):this.cephfsService.mkSnapshot(this.id,t,o.name).subscribe(c=>{this.notificationService.show(pa.k.success,"Created snapshot '" + c + "' for '" + t + "'"),this.forceDirRefresh()})}})}validateValue(t){this.alreadyExists=this.selectedDir.snapshots.some(o=>o.name===t.value)}forceDirRefresh(t){if(!t){const c=this.selectedDir;if(!c)throw new Error("This function can only be called without path if an selection was made");t=c.parent?c.parent:c.path}this.getNode(t).loadNodeChildren()}updateTreeStructure(t){const o=(g,C)=>{const D=g.filter(j=>j.parent===C),P=D.map(j=>j.path);return{children:D,paths:P}};wr().uniq(t.map(g=>g.parent).sort()).forEach(g=>{const C=o(t,g),D=o(this.dirs,g);D.children.forEach(P=>{C.paths.includes(P.path)||this.removeOldDirectory(P)}),C.children.forEach(P=>{D.paths.includes(P.path)?this.updateExistingDirectory(D.children,P):this.addNewDirectory(P)})})}removeOldDirectory(t){const o=t.path;wr().remove(this.dirs,c=>c.path===o),delete this.nodeIds[o],this.updateDirectoriesParentNode(t)}updateDirectoriesParentNode(t){const o=t.parent;if(!o)return;const c=this.getNode(o);if(!c)return;const g=this.getChildren(o);c.data.children=g,c.data.hasChildren=g.length>0,this.treeComponent.treeModel.update()}addNewDirectory(t){this.dirs.push(t),this.nodeIds[t.path]=t,this.updateDirectoriesParentNode(t)}updateExistingDirectory(t,o){const c=t.find(g=>g.path===o.path);Object.assign(c,o)}updateQuotaTable(){const t=this.selectedDir?this.getNode(this.selectedDir.path):void 0;t&&"/"!==t.id&&this.setSettings(t)}updateTree(t=!1){this.loadingIndicator&&!t||(this.treeComponent.treeModel.update(),this.nodes=[...this.nodes],this.treeComponent.sizeChanged())}deleteSnapshotModal(){this.modalRef=this.modalService.show(Gl.M,{itemDescription:"CephFs Snapshot",itemNames:this.snapshot.selection.selected.map(t=>t.name),submitAction:()=>this.deleteSnapshot()})}deleteSnapshot(){const t=this.selectedDir.path;this.snapshot.selection.selected.forEach(o=>{const c=o.name;this.cephfsService.rmSnapshot(this.id,t,c).subscribe(()=>{this.notificationService.show(pa.k.success,"Deleted snapshot '" + c + "' for '" + t + "'")})}),this.modalRef.close(),this.forceDirRefresh()}refreshAllDirectories(){this.loadingIndicator=!0,this.requestedPaths.map(o=>this.forceDirRefresh(o));const t=setInterval(()=>{this.updateTree(!0),this.loadingIndicator||clearInterval(t)},3e3)}unsetLoadingIndicator(){!this.loadingIndicator||(clearTimeout(this.loadingTimeout),this.loadingTimeout=setTimeout(()=>{if(Object.values(this.loading).some(o=>o))return this.unsetLoadingIndicator();this.loadingIndicator=!1,this.updateTree()},3e3))}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(vt.j),e.Y36(Bl.Z),e.Y36(aa),e.Y36(Ul.N),e.Y36($i.p4),e.Y36(hl.g),e.Y36(mn.$))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-cephfs-directories"]],viewQuery:function(t,o){if(1&t&&(e.Gf(Nl.qr,5),e.Gf(Zc,7)),2&t){let c;e.iGM(c=e.CRH())&&(o.treeComponent=c.first),e.iGM(c=e.CRH())&&(o.originTmpl=c.first)}},inputs:{id:"id"},features:[e.TTD],decls:11,vars:10,consts:function(){let s,t;return s="Snapshots",t="Quotas",[[1,"row"],[1,"col-sm-4","pr-0"],[1,"card"],[1,"card-header"],["type","button",1,"btn","btn-light","pull-right",3,"click"],[3,"ngClass"],[1,"card-body"],[3,"nodes","options",4,"ngIf"],["class","col-sm-8 metadata",4,"ngIf"],["origin",""],[3,"nodes","options"],["loadingTemplate",""],[1,"col-sm-8","metadata"],[4,"ngIf"],s,["identifier","name","forceIdentifier","true","selectionType","multiClick",3,"data","columns","updateSelection"],[1,"table-actions",3,"permission","selection","tableActions"],t,["selectionType","single","identifier","quotaKey",3,"data","columns","limit","footer","onlyActionHeader","forceIdentifier","toolHeader","updateSelection"],[1,"only-table-actions",3,"permission","selection","tableActions"],[1,"quota-origin",3,"click"]]},template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"div",1),e.TgZ(2,"div",2),e.TgZ(3,"div",3),e.TgZ(4,"button",4),e.NdJ("click",function(){return o.refreshAllDirectories()}),e._UZ(5,"i",5),e.qZA(),e.qZA(),e.TgZ(6,"div",6),e.YNc(7,al,3,2,"tree-root",7),e.qZA(),e.qZA(),e.qZA(),e.YNc(8,Jd,10,7,"div",8),e.qZA(),e.YNc(9,Ye,2,1,"ng-template",null,9,e.W1O)),2&t&&(e.xp6(4),e.ekj("disabled",o.loadingIndicator),e.xp6(1),e.ekj("fa-spin",o.loadingIndicator),e.Q6J("ngClass",e.WLB(7,ic,o.icons.large,o.icons.refresh)),e.xp6(2),e.Q6J("ngIf",o.nodes),e.xp6(1),e.Q6J("ngIf",o.selectedDir))},directives:[la.o,_.mk,_.O5,Nl.qr,ks.a,Js.K],styles:["cd-cephfs-directories tree-root .tree-children{overflow:inherit}.quota-origin[_ngcontent-%COMP%]{color:#2b99a8;cursor:pointer}.quota-origin[_ngcontent-%COMP%]:hover{color:#212529}"]}),n})();var ot=i(76317);function Et(n,s){if(1&n&&e._UZ(0,"cd-cephfs-detail",15),2&n){const t=e.oxw(2);e.Q6J("data",t.details)}}function qt(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-cephfs-clients",16),e.NdJ("triggerApiUpdate",function(){return e.CHM(t),e.oxw(2).refresh()}),e.qZA()}if(2&n){const t=e.oxw(2);e.Q6J("id",t.id)("clients",t.clients)}}function Hn(n,s){if(1&n&&e._UZ(0,"cd-cephfs-directories",17),2&n){const t=e.oxw(2);e.Q6J("id",t.id)}}function Xn(n,s){if(1&n&&e._UZ(0,"cd-grafana",18),2&n){const t=e.oxw(2);e.Q6J("grafanaPath","mds-performance?var-mds_servers=mds."+t.grafanaId)}}function Ei(n,s){if(1&n){const t=e.EpF();e.ynx(0),e.TgZ(1,"ul",1,2),e.NdJ("navChange",function(){return e.CHM(t),e.oxw().softRefresh()}),e.TgZ(3,"li",3),e.TgZ(4,"a",4),e.SDv(5,5),e.qZA(),e.YNc(6,Et,1,1,"ng-template",6),e.qZA(),e.TgZ(7,"li",7),e.TgZ(8,"a",4),e.ynx(9),e.SDv(10,8),e.BQk(),e.TgZ(11,"span",9),e._uU(12),e.qZA(),e.qZA(),e.YNc(13,qt,1,2,"ng-template",6),e.qZA(),e.TgZ(14,"li",10),e.TgZ(15,"a",4),e.SDv(16,11),e.qZA(),e.YNc(17,Hn,1,1,"ng-template",6),e.qZA(),e.TgZ(18,"li",12),e.TgZ(19,"a",4),e.SDv(20,13),e.qZA(),e.YNc(21,Xn,1,1,"ng-template",6),e.qZA(),e.qZA(),e._UZ(22,"div",14),e.BQk()}if(2&n){const t=e.MAs(2),o=e.oxw();e.xp6(12),e.Oqu(o.clients.data.length),e.xp6(10),e.Q6J("ngbNavOutlet",t)}}let Yo=(()=>{class n{constructor(t,o,c){this.ngZone=t,this.authStorageService=o,this.cephfsService=c,this.clients={data:[],status:new Ae.E(st.T.ValueNone)},this.details={standbys:"",pools:[],ranks:[],mdsCounters:{},name:""},this.grafanaPermission=this.authStorageService.getPermissions().grafana}ngOnChanges(){this.selection?this.selection.id!==this.id&&this.setupSelected(this.selection.id,this.selection.mdsmap.info):this.unsubscribeInterval()}setupSelected(t,o){this.id=t;const c=wr().first(Object.values(o));this.grafanaId=c&&c.name,this.details={standbys:"",pools:[],ranks:[],mdsCounters:{},name:""},this.clients={data:[],status:new Ae.E(st.T.ValueNone)},this.updateInterval()}updateInterval(){this.unsubscribeInterval(),this.subscribeInterval()}unsubscribeInterval(){this.reloadSubscriber&&this.reloadSubscriber.unsubscribe()}subscribeInterval(){this.ngZone.runOutsideAngular(()=>this.reloadSubscriber=(0,V.H)(0,5e3).subscribe(()=>this.ngZone.run(()=>this.refresh())))}refresh(){this.cephfsService.getTabs(this.id).subscribe(t=>{this.data=t,this.softRefresh()},()=>{this.clients.status=new Ae.E(st.T.ValueException)})}softRefresh(){const t=wr().cloneDeep(this.data);this.clients=t.clients,this.clients.status=new Ae.E(this.clients.status),this.details={standbys:t.standbys,pools:t.pools,ranks:t.ranks,mdsCounters:t.mds_counters,name:t.name}}ngOnDestroy(){this.unsubscribeInterval()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(e.R0b),e.Y36(vt.j),e.Y36(aa))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-cephfs-tabs"]],inputs:{selection:"selection"},features:[e.TTD],decls:1,vars:1,consts:function(){let s,t,o,c;return s="Details",t="Clients",o="Directories",c="Performance Details",[[4,"ngIf"],["ngbNav","","cdStatefulTab","cephfs-tabs",1,"nav-tabs",3,"navChange"],["nav","ngbNav"],["ngbNavItem","details"],["ngbNavLink",""],s,["ngbNavContent",""],["ngbNavItem","clients"],t,[1,"badge","badge-pill","badge-tab","ml-1"],["ngbNavItem","directories"],o,["ngbNavItem","performance-details"],c,[3,"ngbNavOutlet"],[3,"data"],[3,"id","clients","triggerApiUpdate"],[3,"id"],["uid","tbO9LAiZz","grafanaStyle","one",3,"grafanaPath"]]},template:function(t,o){1&t&&e.YNc(0,Ei,23,2,"ng-container",0),2&t&&e.Q6J("ngIf",o.selection)},directives:[_.O5,ut.Pz,un.m,ut.nv,ut.Vx,ut.uN,ut.tO,$c,md,Ce,ot.F],styles:[""]}),n})(),$a=(()=>{class n extends jl.o{constructor(t,o){super(),this.cephfsService=t,this.cdDatePipe=o,this.filesystems=[],this.selection=new El.r}ngOnInit(){this.columns=[{name:"Name",prop:"mdsmap.fs_name",flexGrow:2},{name:"Created",prop:"mdsmap.created",flexGrow:2,pipe:this.cdDatePipe},{name:"Enabled",prop:"mdsmap.enabled",flexGrow:1,cellTransformation:bl.e.checkIcon}]}loadFilesystems(t){this.cephfsService.list().subscribe(o=>{this.filesystems=o},()=>{t.error()})}updateSelection(t){this.selection=t}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(aa),e.Y36(Ul.N))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-cephfs-list"]],features:[e.qOj],decls:2,vars:4,consts:[["columnMode","flex","identifier","id","forceIdentifier","true","selectionType","single",3,"data","columns","hasDetails","fetchData","setExpandedRow","updateSelection"],["cdTableDetail","",3,"selection"]],template:function(t,o){1&t&&(e.TgZ(0,"cd-table",0),e.NdJ("fetchData",function(g){return o.loadFilesystems(g)})("setExpandedRow",function(g){return o.setExpandedRow(g)})("updateSelection",function(g){return o.updateSelection(g)}),e._UZ(1,"cd-cephfs-tabs",1),e.qZA()),2&t&&(e.Q6J("data",o.filesystems)("columns",o.columns)("hasDetails",!0),e.xp6(1),e.Q6J("selection",o.expandedRow))},directives:[ks.a,Yo],styles:[""]}),n})(),ns=(()=>{class n{static getType(t){const o=wr().find(this.knownTypes,c=>c.name===t);if(void 0!==o)return o;throw new Error('Found unknown type "'+t+'" for config option.')}static getTypeValidators(t){const o=n.getType(t.type);if("bool"===o.name||"str"===o.name)return;const c={validators:[],patternHelpText:o.patternHelpText};return o.isNumberType?(t.max&&""!==t.max&&(c.max=t.max,c.validators.push(Mn.kI.max(t.max))),t.min&&""!==t.min?(c.min=t.min,c.validators.push(Mn.kI.min(t.min))):"defaultMin"in o&&(c.min=o.defaultMin,c.validators.push(Mn.kI.min(o.defaultMin))),c.validators.push("float"===t.type?ss.h.decimalNumber():ss.h.number(o.allowsNegative))):"addr"===t.type?c.validators=[ss.h.ip()]:"uuid"===t.type&&(c.validators=[ss.h.uuid()]),c}static getTypeStep(t,o){if(["uint","int","size","secs"].includes(t))return 1;if("float"===t){if(null!==o&&-1!==o.toString().indexOf(".")){const C=o.toString().split(".");return Math.pow(10,-C[1].length)}return.1}}}return n.knownTypes=[{name:"uint",inputType:"number",humanReadable:"Unsigned integer value",defaultMin:0,patternHelpText:"The entered value needs to be an unsigned number.",isNumberType:!0,allowsNegative:!1},{name:"int",inputType:"number",humanReadable:"Integer value",patternHelpText:"The entered value needs to be a number.",isNumberType:!0,allowsNegative:!0},{name:"size",inputType:"number",humanReadable:"Unsigned integer value (>=16bit)",defaultMin:0,patternHelpText:"The entered value needs to be a unsigned number.",isNumberType:!0,allowsNegative:!1},{name:"secs",inputType:"number",humanReadable:"Number of seconds",defaultMin:1,patternHelpText:"The entered value needs to be a number >= 1.",isNumberType:!0,allowsNegative:!1},{name:"float",inputType:"number",humanReadable:"Double value",patternHelpText:"The entered value needs to be a number or decimal.",isNumberType:!0,allowsNegative:!0},{name:"str",inputType:"text",humanReadable:"Text",isNumberType:!1},{name:"addr",inputType:"text",humanReadable:"IPv4 or IPv6 address",patternHelpText:"The entered value needs to be a valid IP address.",isNumberType:!1},{name:"uuid",inputType:"text",humanReadable:"UUID",patternHelpText:"The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8",isNumberType:!1},{name:"bool",inputType:"checkbox",humanReadable:"Boolean value",isNumberType:!1}],n})();var Oa=i(93614),Hs=i(95463);class fc{constructor(){this.value=[]}}var ga=i(64724),Ol=i(63622),ll=i(41582),Za=i(56310),ja=i(94276),ul=i(30839);function Of(n,s){1&n&&(e.TgZ(0,"div",8),e.TgZ(1,"label",9),e.SDv(2,20),e.qZA(),e.TgZ(3,"div",11),e.TgZ(4,"textarea",21),e._uU(5," "),e.qZA(),e.qZA(),e.qZA())}function Rd(n,s){1&n&&(e.TgZ(0,"div",8),e.TgZ(1,"label",9),e.SDv(2,22),e.qZA(),e.TgZ(3,"div",11),e.TgZ(4,"textarea",23),e._uU(5," "),e.qZA(),e.qZA(),e.qZA())}function Qd(n,s){1&n&&(e.TgZ(0,"div",8),e.TgZ(1,"label",9),e.SDv(2,24),e.qZA(),e.TgZ(3,"div",11),e._UZ(4,"input",25),e.qZA(),e.qZA())}function Sc(n,s){1&n&&(e.TgZ(0,"div",8),e.TgZ(1,"label",9),e.SDv(2,26),e.qZA(),e.TgZ(3,"div",11),e._UZ(4,"input",27),e.qZA(),e.qZA())}function Wu(n,s){if(1&n&&(e.TgZ(0,"span",30),e.TgZ(1,"span",31),e._uU(2),e.qZA(),e.qZA()),2&n){const t=s.$implicit;e.xp6(2),e.Oqu(t)}}function Cc(n,s){if(1&n&&(e.TgZ(0,"div",8),e.TgZ(1,"label",9),e.SDv(2,28),e.qZA(),e.TgZ(3,"div",11),e.YNc(4,Wu,3,1,"span",29),e.qZA(),e.qZA()),2&n){const t=e.oxw(2);e.xp6(4),e.Q6J("ngForOf",t.configForm.getValue("services"))}}function Xd(n,s){if(1&n&&(e.TgZ(0,"div",8),e.TgZ(1,"label",32),e._uU(2),e.qZA(),e.TgZ(3,"div",11),e.TgZ(4,"select",33),e.TgZ(5,"option",34),e.SDv(6,35),e.qZA(),e.TgZ(7,"option",34),e.SDv(8,36),e.qZA(),e.TgZ(9,"option",34),e.SDv(10,37),e.qZA(),e.qZA(),e.qZA(),e.qZA()),2&n){const t=e.oxw().$implicit;e.xp6(1),e.Q6J("for",t),e.xp6(1),e.hij("",t," "),e.xp6(2),e.Q6J("formControlName",t),e.xp6(1),e.Q6J("ngValue",null),e.xp6(2),e.Q6J("ngValue",!0),e.xp6(2),e.Q6J("ngValue",!1)}}function jc(n,s){if(1&n&&(e.TgZ(0,"span",40),e._uU(1),e.qZA()),2&n){const t=e.oxw(4);e.xp6(1),e.hij(" ",t.patternHelpText," ")}}function $f(n,s){if(1&n&&(e.TgZ(0,"span",40),e._uU(1),e.qZA()),2&n){const t=e.oxw(4);e.xp6(1),e.hij(" ",t.patternHelpText," ")}}function Ju(n,s){if(1&n&&(e.TgZ(0,"span",40),e.SDv(1,41),e.qZA()),2&n){const t=e.oxw(4);e.xp6(1),e.pQV(t.maxValue),e.QtT(1)}}function Sl(n,s){if(1&n&&(e.TgZ(0,"span",40),e.SDv(1,42),e.qZA()),2&n){const t=e.oxw(4);e.xp6(1),e.pQV(t.minValue),e.QtT(1)}}function wl(n,s){if(1&n&&(e.TgZ(0,"div",8),e.TgZ(1,"label",32),e._uU(2),e.qZA(),e.TgZ(3,"div",11),e._UZ(4,"input",38),e.YNc(5,jc,2,1,"span",39),e.YNc(6,$f,2,1,"span",39),e.YNc(7,Ju,2,1,"span",39),e.YNc(8,Sl,2,1,"span",39),e.qZA(),e.qZA()),2&n){const t=e.oxw().$implicit;e.oxw();const o=e.MAs(2),c=e.oxw();e.xp6(1),e.Q6J("for",t),e.xp6(1),e.hij("",t," "),e.xp6(2),e.Q6J("type",c.inputType)("id",t)("placeholder",c.humanReadableType)("formControlName",t)("step",c.getStep(c.type,c.configForm.getValue(t))),e.xp6(1),e.Q6J("ngIf",c.configForm.showError(t,o,"pattern")),e.xp6(1),e.Q6J("ngIf",c.configForm.showError(t,o,"invalidUuid")),e.xp6(1),e.Q6J("ngIf",c.configForm.showError(t,o,"max")),e.xp6(1),e.Q6J("ngIf",c.configForm.showError(t,o,"min"))}}function kl(n,s){if(1&n&&(e.ynx(0),e.YNc(1,Xd,11,6,"div",13),e.YNc(2,wl,9,11,"div",13),e.BQk()),2&n){const t=e.oxw(2);e.xp6(1),e.Q6J("ngIf","bool"===t.type),e.xp6(1),e.Q6J("ngIf","bool"!==t.type)}}function Pu(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",1),e.TgZ(1,"form",2,3),e.TgZ(3,"div",4),e.TgZ(4,"div",5),e.ynx(5,6),e._uU(6,"Edit"),e.BQk(),e._uU(7),e.qZA(),e.TgZ(8,"div",7),e.TgZ(9,"div",8),e.TgZ(10,"label",9),e.SDv(11,10),e.qZA(),e.TgZ(12,"div",11),e._UZ(13,"input",12),e.qZA(),e.qZA(),e.YNc(14,Of,6,0,"div",13),e.YNc(15,Rd,6,0,"div",13),e.YNc(16,Qd,5,0,"div",13),e.YNc(17,Sc,5,0,"div",13),e.YNc(18,Cc,5,1,"div",13),e.TgZ(19,"div",14),e.TgZ(20,"h3",15),e.SDv(21,16),e.qZA(),e.YNc(22,kl,3,2,"ng-container",17),e.qZA(),e.qZA(),e.TgZ(23,"div",18),e.TgZ(24,"cd-form-button-panel",19),e.NdJ("submitActionEvent",function(){return e.CHM(t),e.oxw().submit()}),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=e.oxw();e.xp6(1),e.Q6J("formGroup",t.configForm),e.xp6(6),e.hij(" ",t.configForm.getValue("name")," "),e.xp6(7),e.Q6J("ngIf",t.configForm.getValue("desc")),e.xp6(1),e.Q6J("ngIf",t.configForm.getValue("long_desc")),e.xp6(1),e.Q6J("ngIf",""!==t.configForm.getValue("default")),e.xp6(1),e.Q6J("ngIf",""!==t.configForm.getValue("daemon_default")),e.xp6(1),e.Q6J("ngIf",t.configForm.getValue("services").length>0),e.xp6(4),e.Q6J("ngForOf",t.availSections),e.xp6(2),e.Q6J("form",t.configForm)("submitText",t.actionLabels.UPDATE)}}let Ja=(()=>{class n extends Oa.E{constructor(t,o,c,g,C){super(),this.actionLabels=t,this.route=o,this.router=c,this.configService=g,this.notificationService=C,this.availSections=["global","mon","mgr","osd","mds","client"],this.createForm()}createForm(){const t={name:new Mn.NI({value:null}),desc:new Mn.NI({value:null}),long_desc:new Mn.NI({value:null}),values:new Mn.cw({}),default:new Mn.NI({value:null}),daemon_default:new Mn.NI({value:null}),services:new Mn.NI([])};this.availSections.forEach(o=>{t.values.addControl(o,new Mn.NI(null))}),this.configForm=new Hs.d(t)}ngOnInit(){this.route.params.subscribe(t=>{this.configService.get(t.name).subscribe(c=>{this.setResponse(c),this.loadingReady()})})}getValidators(t){const o=ns.getTypeValidators(t);if(o)return this.patternHelpText=o.patternHelpText,"max"in o&&""!==o.max&&(this.maxValue=o.max),"min"in o&&""!==o.min&&(this.minValue=o.min),o.validators}getStep(t,o){return ns.getTypeStep(t,o)}setResponse(t){this.response=t;const o=this.getValidators(t);this.configForm.get("name").setValue(t.name),this.configForm.get("desc").setValue(t.desc),this.configForm.get("long_desc").setValue(t.long_desc),this.configForm.get("default").setValue(t.default),this.configForm.get("daemon_default").setValue(t.daemon_default),this.configForm.get("services").setValue(t.services),this.response.value&&this.response.value.forEach(g=>{let C=null;C="true"===g.value||"false"!==g.value&&g.value,this.configForm.get("values").get(g.section).setValue(C)}),this.availSections.forEach(g=>{this.configForm.get("values").get(g).setValidators(o)});const c=ns.getType(t.type);this.type=c.name,this.inputType=c.inputType,this.humanReadableType=c.humanReadable}createRequest(){const t=[];if(this.availSections.forEach(o=>{const c=this.configForm.getValue(o);null!==c&&""!==c&&t.push({section:o,value:c})}),!wr().isEqual(this.response.value,t)){const o=new fc;return o.name=this.configForm.getValue("name"),o.value=t,o}return null}submit(){const t=this.createRequest();t&&this.configService.create(t).subscribe(()=>{this.notificationService.show(pa.k.success,"Updated config option " + t.name + ""),this.router.navigate(["/configuration"])},()=>{this.configForm.setErrors({cdSubmitButton:!0})}),this.router.navigate(["/configuration"])}}return n.\u0275fac=function(t){return new(t||n)(e.Y36($i.p4),e.Y36(Bo.gz),e.Y36(Bo.F0),e.Y36(ga.e),e.Y36(hl.g))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-configuration-form"]],features:[e.qOj],decls:1,vars:1,consts:function(){let s,t,o,c,g,C,D,P,j,W,re,oe;return s="Name",t="Values",o="Description",c="Long description",g="Default",C="Daemon default",D="Services",P="-- Default --",j="true",W="false",re="The entered value is too high! It must not be greater than " + "\ufffd0\ufffd" + ".",oe="The entered value is too low! It must not be lower than " + "\ufffd0\ufffd" + ".",[["class","cd-col-form",4,"cdFormLoading"],[1,"cd-col-form"],["name","configForm","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"card"],[1,"card-header"],["i18",""],[1,"card-body"],[1,"form-group","row"],[1,"cd-col-form-label"],s,[1,"cd-col-form-input"],["type","text","id","name","formControlName","name","readonly","",1,"form-control"],["class","form-group row",4,"ngIf"],["formGroupName","values"],[1,"cd-header"],t,[4,"ngFor","ngForOf"],[1,"card-footer"],["wrappingClass","text-right",3,"form","submitText","submitActionEvent"],o,["id","desc","formControlName","desc","readonly","",1,"form-control","resize-vertical"],c,["id","long_desc","formControlName","long_desc","readonly","",1,"form-control","resize-vertical"],g,["type","text","id","default","formControlName","default","readonly","",1,"form-control"],C,["type","text","id","daemon_default","formControlName","daemon_default","readonly","",1,"form-control"],D,["class","form-component-badge",4,"ngFor","ngForOf"],[1,"form-component-badge"],[1,"badge","badge-dark"],[1,"cd-col-form-label",3,"for"],["id","pool","name","pool",1,"form-control",3,"formControlName"],[3,"ngValue"],P,j,W,[1,"form-control",3,"type","id","placeholder","formControlName","step"],["class","invalid-feedback",4,"ngIf"],[1,"invalid-feedback"],re,oe]},template:function(t,o){1&t&&e.YNc(0,Pu,25,10,"div",0),2&t&&e.Q6J("cdFormLoading",o.loading)},directives:[Ol.y,Mn._Y,Mn.JL,ll.V,Mn.sg,Za.P,la.o,Mn.Fj,ja.b,Mn.JJ,Mn.u,_.O5,Mn.x0,_.sg,ul.p,Mn.EJ,Mn.YN,Mn.Kr],styles:[".form-component-badge[_ngcontent-%COMP%]{display:block;height:34px}.form-component-badge[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{margin-top:7px}.resize-vertical[_ngcontent-%COMP%]{resize:vertical}"]}),n})();var Qu=i(68962);function en(n,s){if(1&n&&(e.TgZ(0,"span"),e._uU(1),e._UZ(2,"br"),e.qZA()),2&n){const t=s.$implicit,o=s.last;e.xp6(1),e.lnq(" ",t.section,": ",t.value,"",o?"":",","")}}function Oc(n,s){if(1&n&&(e.TgZ(0,"span"),e.TgZ(1,"span",23),e.TgZ(2,"span",24),e._uU(3),e.ALo(4,"uppercase"),e.qZA(),e.qZA(),e.qZA()),2&n){const t=s.$implicit,o=e.oxw(2);e.xp6(1),e.s9C("title",o.flags[t]),e.xp6(2),e.Oqu(e.lcZ(4,2,t))}}function Au(n,s){if(1&n&&(e.TgZ(0,"span"),e.TgZ(1,"span",24),e._uU(2),e.qZA(),e.qZA()),2&n){const t=s.$implicit;e.xp6(2),e.Oqu(t)}}function Iu(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"table",1),e.TgZ(2,"tbody"),e.TgZ(3,"tr"),e.TgZ(4,"td",2),e.SDv(5,3),e.qZA(),e.TgZ(6,"td",4),e._uU(7),e.qZA(),e.qZA(),e.TgZ(8,"tr"),e.TgZ(9,"td",5),e.SDv(10,6),e.qZA(),e.TgZ(11,"td"),e._uU(12),e.qZA(),e.qZA(),e.TgZ(13,"tr"),e.TgZ(14,"td",5),e.SDv(15,7),e.qZA(),e.TgZ(16,"td"),e._uU(17),e.qZA(),e.qZA(),e.TgZ(18,"tr"),e.TgZ(19,"td",5),e.SDv(20,8),e.qZA(),e.TgZ(21,"td"),e.YNc(22,en,3,3,"span",9),e.qZA(),e.qZA(),e.TgZ(23,"tr"),e.TgZ(24,"td",5),e.SDv(25,10),e.qZA(),e.TgZ(26,"td"),e._uU(27),e.qZA(),e.qZA(),e.TgZ(28,"tr"),e.TgZ(29,"td",5),e.SDv(30,11),e.qZA(),e.TgZ(31,"td"),e._uU(32),e.qZA(),e.qZA(),e.TgZ(33,"tr"),e.TgZ(34,"td",5),e.SDv(35,12),e.qZA(),e.TgZ(36,"td"),e._uU(37),e.qZA(),e.qZA(),e.TgZ(38,"tr"),e.TgZ(39,"td",5),e.SDv(40,13),e.qZA(),e.TgZ(41,"td"),e._uU(42),e.qZA(),e.qZA(),e.TgZ(43,"tr"),e.TgZ(44,"td",5),e.SDv(45,14),e.qZA(),e.TgZ(46,"td"),e._uU(47),e.qZA(),e.qZA(),e.TgZ(48,"tr"),e.TgZ(49,"td",5),e.SDv(50,15),e.qZA(),e.TgZ(51,"td"),e.YNc(52,Oc,5,4,"span",9),e.qZA(),e.qZA(),e.TgZ(53,"tr"),e.TgZ(54,"td",5),e.SDv(55,16),e.qZA(),e.TgZ(56,"td"),e.YNc(57,Au,3,1,"span",9),e.qZA(),e.qZA(),e.TgZ(58,"tr"),e.TgZ(59,"td",5),e.SDv(60,17),e.qZA(),e.TgZ(61,"td"),e._uU(62),e.qZA(),e.qZA(),e.TgZ(63,"tr"),e.TgZ(64,"td",5),e.SDv(65,18),e.qZA(),e.TgZ(66,"td"),e._uU(67),e.qZA(),e.qZA(),e.TgZ(68,"tr"),e.TgZ(69,"td",5),e.SDv(70,19),e.qZA(),e.TgZ(71,"td"),e._uU(72),e.ALo(73,"booleanText"),e.qZA(),e.qZA(),e.TgZ(74,"tr"),e.TgZ(75,"td",5),e.SDv(76,20),e.qZA(),e.TgZ(77,"td"),e._uU(78),e.qZA(),e.qZA(),e.TgZ(79,"tr"),e.TgZ(80,"td",5),e.SDv(81,21),e.qZA(),e.TgZ(82,"td"),e._uU(83),e.qZA(),e.qZA(),e.TgZ(84,"tr"),e.TgZ(85,"td",5),e.SDv(86,22),e.qZA(),e.TgZ(87,"td"),e._uU(88),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.BQk()),2&n){const t=e.oxw();e.xp6(7),e.Oqu(t.selection.name),e.xp6(5),e.Oqu(t.selection.desc),e.xp6(5),e.Oqu(t.selection.long_desc),e.xp6(5),e.Q6J("ngForOf",t.selection.value),e.xp6(5),e.Oqu(t.selection.default),e.xp6(5),e.Oqu(t.selection.daemon_default),e.xp6(5),e.Oqu(t.selection.type),e.xp6(5),e.Oqu(t.selection.min),e.xp6(5),e.Oqu(t.selection.max),e.xp6(5),e.Q6J("ngForOf",t.selection.flags),e.xp6(5),e.Q6J("ngForOf",t.selection.services),e.xp6(5),e.Oqu(t.selection.source),e.xp6(5),e.Oqu(t.selection.level),e.xp6(5),e.Oqu(e.lcZ(73,17,t.selection.can_update_at_runtime)),e.xp6(6),e.Oqu(t.selection.tags),e.xp6(5),e.Oqu(t.selection.enum_values),e.xp6(5),e.Oqu(t.selection.see_also)}}let nl=(()=>{class n{constructor(){this.flags={runtime:"The value can be updated at runtime.",no_mon_update:"Daemons/clients do not pull this value from the\n monitor config database. We disallow setting this option via 'ceph config\n set ...'. This option should be configured via ceph.conf or via the\n command line.",startup:"Option takes effect only during daemon startup.",cluster_create:"Option only affects cluster creation.",create:"Option only affects daemon creation."}}ngOnChanges(){this.selection&&(this.selection.services=wr().split(this.selection.services,","))}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-configuration-details"]],inputs:{selection:"selection"},features:[e.TTD],decls:1,vars:1,consts:function(){let s,t,o,c,g,C,D,P,j,W,re,oe,me,_e,Fe,Re,Le;return s="Name",t="Description",o="Long description",c="Current values",g="Default",C="Daemon default",D="Type",P="Min",j="Max",W="Flags",re="Services",oe="Source",me="Level",_e="Can be updated at runtime (editable)",Fe="Tags",Re="Enum values",Le="See also",[[4,"ngIf"],[1,"table","table-striped","table-bordered"],[1,"bold","w-25"],s,[1,"w-75"],[1,"bold"],t,o,c,[4,"ngFor","ngForOf"],g,C,D,P,j,W,re,oe,me,_e,Fe,Re,Le,[3,"title"],[1,"badge","badge-dark","mr-2"]]},template:function(t,o){1&t&&e.YNc(0,Iu,89,19,"ng-container",0),2&t&&e.Q6J("ngIf",o.selection)},directives:[_.O5,_.sg],pipes:[Qu.T,_.gd],styles:[""]}),n})();const ff=["confValTpl"],Jl=["confFlagTpl"];function vd(n,s){if(1&n&&(e.TgZ(0,"span"),e._uU(1),e._UZ(2,"br"),e.qZA()),2&n){const t=s.$implicit,o=s.last;e.xp6(1),e.lnq(" ",t.section,": ",t.value,"",o?"":",","")}}function wc(n,s){if(1&n&&(e.TgZ(0,"span"),e.YNc(1,vd,3,3,"span",5),e.qZA()),2&n){const t=e.oxw().value;e.xp6(1),e.Q6J("ngForOf",t)}}function Gc(n,s){1&n&&e.YNc(0,wc,2,1,"span",4),2&n&&e.Q6J("ngIf",s.value)}let pf=(()=>{class n extends jl.o{constructor(t,o,c){super(),this.authStorageService=t,this.configurationService=o,this.actionLabels=c,this.data=[],this.icons=xo.P,this.selection=new El.r,this.filters=[{name:"Level",prop:"level",filterOptions:["basic","advanced","dev"],filterInitValue:"basic",filterPredicate:(D,P)=>{let j;var re;return(re=j||(j={}))[re.basic=0]="basic",re[re.advanced=1]="advanced",re[re.dev=2]="dev",j[D.level]<=j[P]}},{name:"Service",prop:"services",filterOptions:["mon","mgr","osd","mds","common","mds_client","rgw"],filterPredicate:(D,P)=>D.services.includes(P)},{name:"Source",prop:"source",filterOptions:["mon"],filterPredicate:(D,P)=>!!D.hasOwnProperty("source")&&D.source.includes(P)},{name:"Modified",prop:"modified",filterOptions:["yes","no"],filterPredicate:(D,P)=>!!("yes"===P&&D.hasOwnProperty("value")||"no"===P&&!D.hasOwnProperty("value"))}],this.permission=this.authStorageService.getPermissions().configOpt;const g=()=>this.selection.first()&&`${encodeURIComponent(this.selection.first().name)}`;this.tableActions=[{permission:"update",icon:xo.P.edit,routerLink:()=>`/configuration/edit/${g()}`,name:this.actionLabels.EDIT,disable:()=>!this.isEditable(this.selection)}]}ngOnInit(){this.columns=[{canAutoResize:!0,prop:"name",name:"Name"},{prop:"desc",name:"Description",cellClass:"wrap"},{prop:"value",name:"Current value",cellClass:"wrap",cellTemplate:this.confValTpl},{prop:"default",name:"Default",cellClass:"wrap"},{prop:"can_update_at_runtime",name:"Editable",cellTransformation:bl.e.checkIcon,flexGrow:.4,cellClass:"text-center"}]}updateSelection(t){this.selection=t}getConfigurationList(t){this.configurationService.getConfigData().subscribe(o=>{this.data=o},()=>{t.error()})}isEditable(t){return 1===t.selected.length&&t.selected[0].can_update_at_runtime}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(vt.j),e.Y36(ga.e),e.Y36($i.p4))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-configuration"]],viewQuery:function(t,o){if(1&t&&(e.Gf(ff,7),e.Gf(Jl,5)),2&t){let c;e.iGM(c=e.CRH())&&(o.confValTpl=c.first),e.iGM(c=e.CRH())&&(o.confFlagTpl=c.first)}},features:[e.qOj],decls:5,vars:8,consts:[["selectionType","single",3,"data","columns","extraFilterableColumns","hasDetails","fetchData","setExpandedRow","updateSelection"],[1,"table-actions",3,"permission","selection","tableActions"],["cdTableDetail","",3,"selection"],["confValTpl",""],[4,"ngIf"],[4,"ngFor","ngForOf"]],template:function(t,o){1&t&&(e.TgZ(0,"cd-table",0),e.NdJ("fetchData",function(g){return o.getConfigurationList(g)})("setExpandedRow",function(g){return o.setExpandedRow(g)})("updateSelection",function(g){return o.updateSelection(g)}),e._UZ(1,"cd-table-actions",1),e._UZ(2,"cd-configuration-details",2),e.qZA(),e.YNc(3,Gc,1,1,"ng-template",null,3,e.W1O)),2&t&&(e.Q6J("data",o.data)("columns",o.columns)("extraFilterableColumns",o.filters)("hasDetails",!0),e.xp6(1),e.Q6J("permission",o.permission)("selection",o.selection)("tableActions",o.tableActions),e.xp6(1),e.Q6J("selection",o.expandedRow))},directives:[ks.a,Js.K,nl,_.O5,_.sg],styles:[".filter[_ngcontent-%COMP%]{padding-right:8px}.fa-stack[_ngcontent-%COMP%]{font-size:.79rem}.fa-stack[_ngcontent-%COMP%] .fa-stack-1x[_ngcontent-%COMP%]{margin-left:8px;margin-top:5px} cd-configuration datatable-body-cell.wrap{word-break:break-all}"]}),n})();var xc=i(35758),hf=i(68939),Vc=i(25917),hu=i(88002),yd=i(42145),$p=i(548),fp=i(95242),_f=i(34022);function Ql(n,s,t){return 0===t?[s]:(n.push(s),n)}function Hf(){return function(n,s){return arguments.length>=2?function(o){return(0,_f.z)((0,yd.R)(n,s),(0,$p.h)(1),(0,fp.d)(s))(o)}:function(o){return(0,_f.z)((0,yd.R)((c,g,C)=>n(c,g,C+1)),(0,$p.h)(1))(o)}}(Ql,[])}var Bu=i(19773),Kf=i(76189),Nd=i(51295);let Dc=(()=>{class n{calculateAdditionalData(t){if(!t.life_expectancy_min||!t.life_expectancy_max)return t.state="unknown",t;const o=P=>!!Number.parseFloat(P),c=(P,j)=>P&&j&&o(P)&&o(j)?ai().duration(ai()(P).diff(ai()(j))).asWeeks():null,g=ai().duration(ai()(ai().now()).diff(ai()(t.life_expectancy_stamp))).asWeeks(),C=c(t.life_expectancy_max,t.life_expectancy_stamp),D=c(t.life_expectancy_min,t.life_expectancy_stamp);return t.state=g>1?"stale":null!==C&&C<=2?"bad":null!==D&&D<=4?"warning":"good",t.life_expectancy_weeks={max:null!==C?Math.round(C):null,min:null!==D?Math.round(D):null},t}readable(t){return t.readableDaemons=t.daemons.join(" "),t}prepareDevice(t){return this.readable(this.calculateAdditionalData(t))}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})(),Xl=(()=>{class n extends Kf.S{constructor(t,o){super(),this.http=t,this.deviceService=o,this.baseURL="api/host",this.baseUIURL="ui-api/host",this.predefinedLabels=["mon","mgr","osd","mds","rgw","nfs","iscsi","rbd","grafana"]}list(t){return this.http.get(this.baseURL,{headers:{Accept:"application/vnd.ceph.api.v1.1+json"},params:{facts:t}})}create(t,o,c,g){return this.http.post(this.baseURL,{hostname:t,addr:o,labels:c,status:g},{observe:"response",headers:{Accept:Nd.T.cdVersionHeader("0","1")}})}delete(t){return this.http.delete(`${this.baseURL}/${t}`,{observe:"response"})}getDevices(t){return this.http.get(`${this.baseURL}/${t}/devices`).pipe((0,hu.U)(o=>o.map(c=>this.deviceService.prepareDevice(c))))}getSmartData(t){return this.http.get(`${this.baseURL}/${t}/smart`)}getDaemons(t){return this.http.get(`${this.baseURL}/${t}/daemons`)}getLabels(){return this.http.get(`${this.baseUIURL}/labels`)}update(t,o=!1,c=[],g=!1,C=!1,D=!1){return this.http.put(`${this.baseURL}/${t}`,{update_labels:o,labels:c,maintenance:g,force:C,drain:D},{headers:{Accept:this.getVersionHeaderValue(0,1)}})}identifyDevice(t,o,c){return this.http.post(`${this.baseURL}/${t}/identify_device`,{device:o,duration:c})}getInventoryParams(t){let o=new y.LE;return t&&(o=o.append("refresh",wr().toString(t))),o}getInventory(t,o){const c=this.getInventoryParams(o);return this.http.get(`${this.baseURL}/${t}/inventory`,{params:c})}inventoryList(t){const o=this.getInventoryParams(t);return this.http.get(`${this.baseUIURL}/inventory`,{params:o})}inventoryDeviceList(t,o){let c;return c=t?this.getInventory(t,o).pipe(Hf()):this.inventoryList(o),c.pipe((0,Bu.zg)(g=>{const C=wr().flatMap(g,D=>D.devices.map(P=>(P.hostname=D.name,P.uid=P.device_id?`${P.device_id}-${P.hostname}-${P.path}`:`${P.hostname}-${P.path}`,P)));return(0,Vc.of)(C)}))}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(y.eN),e.LFG(Dc))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})(),Ji=(()=>{class n{constructor(t,o){this.http=t,this.deviceService=o,this.path="api/osd",this.uiPath="ui-api/osd",this.osdDevices=[],this.osdRecvSpeedModalPriorities={KNOWN_PRIORITIES:[{name:null,text:"-- Select the priority --",values:{osd_max_backfills:null,osd_recovery_max_active:null,osd_recovery_max_single_start:null,osd_recovery_sleep:null}},{name:"low",text:"Low",values:{osd_max_backfills:1,osd_recovery_max_active:1,osd_recovery_max_single_start:1,osd_recovery_sleep:.5}},{name:"default",text:"Default",values:{osd_max_backfills:1,osd_recovery_max_active:3,osd_recovery_max_single_start:1,osd_recovery_sleep:0}},{name:"high",text:"High",values:{osd_max_backfills:4,osd_recovery_max_active:4,osd_recovery_max_single_start:4,osd_recovery_sleep:0}}]}}create(t,o,c="drive_groups"){return this.http.post(this.path,{method:c,data:t,tracking_id:o},{observe:"response"})}getList(){return this.http.get(`${this.path}`)}getOsdSettings(){return this.http.get(`${this.path}/settings`,{headers:{Accept:"application/vnd.ceph.api.v0.1+json"}})}getDetails(t){return this.http.get(`${this.path}/${t}`)}getSmartData(t){return this.http.get(`${this.path}/${t}/smart`)}scrub(t,o){return this.http.post(`${this.path}/${t}/scrub?deep=${o}`,null)}getDeploymentOptions(){return this.http.get(`${this.uiPath}/deployment_options`)}getFlags(){return this.http.get(`${this.path}/flags`)}updateFlags(t){return this.http.put(`${this.path}/flags`,{flags:t})}updateIndividualFlags(t,o){return this.http.put(`${this.path}/flags/individual`,{flags:t,ids:o})}markOut(t){return this.http.put(`${this.path}/${t}/mark`,{action:"out"})}markIn(t){return this.http.put(`${this.path}/${t}/mark`,{action:"in"})}markDown(t){return this.http.put(`${this.path}/${t}/mark`,{action:"down"})}reweight(t,o){return this.http.post(`${this.path}/${t}/reweight`,{weight:o})}update(t,o){return this.http.put(`${this.path}/${t}`,{device_class:o})}markLost(t){return this.http.put(`${this.path}/${t}/mark`,{action:"lost"})}purge(t){return this.http.post(`${this.path}/${t}/purge`,null)}destroy(t){return this.http.post(`${this.path}/${t}/destroy`,null)}delete(t,o,c){return this.http.delete(`${this.path}/${t}`,{observe:"response",params:{preserve_id:o?"true":"false",force:c?"true":"false"}})}safeToDestroy(t){return this.http.get(`${this.path}/safe_to_destroy?ids=${t}`)}safeToDelete(t){return this.http.get(`${this.path}/safe_to_delete?svc_ids=${t}`)}getDevices(t){return this.http.get(`${this.path}/${t}/devices`).pipe((0,hu.U)(o=>o.map(c=>this.deviceService.prepareDevice(c))))}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(y.eN),e.LFG(Dc))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();var cl=i(76111),Ll=i(32337),Pd=i(26215);const rl=[{stepIndex:1,isComplete:!1}];let Yu=(()=>{class n{constructor(){this.currentStep$=new Pd.X(null),this.steps$=new Pd.X(rl),this.currentStep$.next(this.steps$.value[0])}setTotalSteps(t){const o=[];for(let c=1;c<=t;c++)o.push({stepIndex:c,isComplete:!1});this.steps$=new Pd.X(o)}setCurrentStep(t){this.currentStep$.next(t)}getCurrentStep(){return this.currentStep$.asObservable()}getSteps(){return this.steps$.asObservable()}moveToNextStep(){this.currentStep$.next(this.steps$.value[this.currentStep$.value.stepIndex])}moveToPreviousStep(){this.currentStep$.next(this.steps$.value[this.currentStep$.value.stepIndex-1-1])}isLastStep(){return this.currentStep$.value.stepIndex===this.steps$.value.length}isFirstStep(){var t;return(null===(t=this.currentStep$.value)||void 0===t?void 0:t.stepIndex)-1==0}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();var pc=i(28211);class Kd{constructor(){this.reset(),this.formatterService=new pc.H,this.deviceSelectionAttrs={"sys_api.vendor":{name:"vendor"},"sys_api.model":{name:"model"},device_id:{name:"device_id"},human_readable_type:{name:"rotational",formatter:s=>"hdd"===s.toLowerCase()},"sys_api.size":{name:"size",formatter:s=>this.formatterService.format_number(s,1024,["B","KB","MB","GB","TB","PB"]).replace(" ","")}}}reset(){this.spec={service_type:"osd",service_id:`dashboard-${wr().now()}`}}setName(s){this.spec.service_id=s}setHostPattern(s){this.spec.host_pattern=s}setDeviceSelection(s,t){const o=`${s}_devices`;this.spec[o]={},t.forEach(c=>{const g=this.deviceSelectionAttrs[c.prop];g&&(this.spec[o][g.name]=g.formatter?g.formatter(c.value.raw):c.value.raw)})}clearDeviceSelection(s){delete this.spec[`${s}_devices`]}setSlots(s,t){const o=`${s}_slots`;0===t?delete this.spec[o]:this.spec[o]=t}setFeature(s,t){t?this.spec[s]=!0:delete this.spec[s]}}let wf=(()=>{class n{constructor(t){this.http=t,this.baseURL="api/cluster"}getStatus(){return this.http.get(`${this.baseURL}`,{headers:{Accept:"application/vnd.ceph.api.v0.1+json"}})}updateStatus(t){return this.http.put(`${this.baseURL}`,{status:t},{headers:{Accept:"application/vnd.ceph.api.v0.1+json"}})}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(y.eN))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();const Vl=function(n){return{active:n}};function Id(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"ul",4),e.TgZ(1,"li",5),e.TgZ(2,"a",6),e.NdJ("click",function(){const g=e.CHM(t).$implicit;return e.oxw().onStepClick(g)}),e.TgZ(3,"span",7),e.SDv(4,8),e.qZA(),e.TgZ(5,"span"),e.SDv(6,9),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=s.$implicit,o=s.index,c=e.oxw();e.xp6(2),e.Q6J("ngClass",e.VKq(4,Vl,c.currentStep.stepIndex===t.stepIndex)),e.xp6(1),e.Q6J("ngClass",e.VKq(6,Vl,c.currentStep.stepIndex===t.stepIndex)),e.xp6(1),e.pQV(t.stepIndex),e.QtT(4),e.xp6(2),e.pQV(c.stepsTitle[o]),e.QtT(6)}}let oc=(()=>{class n{constructor(t){this.stepsService=t}ngOnInit(){this.stepsService.setTotalSteps(this.stepsTitle.length),this.steps=this.stepsService.getSteps(),this.currentStepSub=this.stepsService.getCurrentStep().subscribe(t=>{this.currentStep=t})}onStepClick(t){this.stepsService.setCurrentStep(t)}ngOnDestroy(){this.currentStepSub.unsubscribe()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Yu))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-wizard"]],inputs:{stepsTitle:"stepsTitle"},decls:5,vars:3,consts:function(){let s,t;return s="" + "\ufffd0\ufffd" + "",t="" + "\ufffd0\ufffd" + "",[[1,"card-body"],[1,"row","m-7"],[1,"col"],["class","nav nav-pills flex-column",4,"ngFor","ngForOf"],[1,"nav","nav-pills","flex-column"],[1,"nav-item"],[1,"nav-link",3,"ngClass","click"],[1,"circle-step",3,"ngClass"],s,t]},template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"div",1),e.TgZ(2,"nav",2),e.YNc(3,Id,7,8,"ul",3),e.ALo(4,"async"),e.qZA(),e.qZA(),e.qZA()),2&t&&(e.xp6(3),e.Q6J("ngForOf",e.lcZ(4,1,o.steps)))},directives:[_.sg,_.mk],pipes:[_.Ov],styles:["cd-wizard{width:15%}.card-body[_ngcontent-%COMP%]{padding-left:0}span.circle-step[_ngcontent-%COMP%]{background:#adb5bd;border-radius:.8em;color:#fff;display:inline-block;font-weight:bold;line-height:1.6em;margin-right:5px;text-align:center;width:1.6em}span.circle-step.active[_ngcontent-%COMP%]{background-color:#2b99a8}.nav-pills[_ngcontent-%COMP%] .nav-link[_ngcontent-%COMP%]{background-color:#fff;color:#343a40}.nav-pills[_ngcontent-%COMP%] .nav-link.active[_ngcontent-%COMP%]{color:#2b99a8}"]}),n})();var hc=i(13472),_u=i(75319);let Mc=(()=>{class n{constructor(t){this.http=t,this.url="ui-api/orchestrator",this.disableMessages={noOrchestrator:"The feature is disabled because Orchestrator is not available.",missingFeature:"The Orchestrator backend doesn't support this feature."}}status(){return this.http.get(`${this.url}/status`)}hasFeature(t,o){return wr().every(o,c=>wr().get(t.features,`${c}.available`))}getTableActionDisableDesc(t,o){return!!t&&(t.available?!this.hasFeature(t,o)&&this.disableMessages.missingFeature:this.disableMessages.noOrchestrator)}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(y.eN))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();var Hc=i(7022),cu=(()=>{return(n=cu||(cu={})).HOST_LIST="get_hosts",n.HOST_ADD="add_host",n.HOST_REMOVE="remove_host",n.HOST_LABEL_ADD="add_host_label",n.HOST_LABEL_REMOVE="remove_host_label",n.HOST_MAINTENANCE_ENTER="enter_host_maintenance",n.HOST_MAINTENANCE_EXIT="exit_host_maintenance",n.HOST_FACTS="get_facts",n.HOST_DRAIN="drain_host",n.SERVICE_LIST="describe_service",n.SERVICE_CREATE="apply",n.SERVICE_EDIT="apply",n.SERVICE_DELETE="remove_service",n.SERVICE_RELOAD="service_action",n.DAEMON_LIST="list_daemons",n.OSD_GET_REMOVE_STATUS="remove_osds_status",n.OSD_CREATE="apply_drivegroups",n.OSD_DELETE="remove_osds",n.DEVICE_LIST="get_inventory",n.DEVICE_BLINK_LIGHT="blink_device_light",cu;var n})(),Lu=i(51847),Ou=i(33512),Rc=i.n(Ou),bu=i(60312),h=i(18372),E=i(82945),R=i(60192),F=i(10545);function q(n,s){1&n&&(e.TgZ(0,"span",29),e.SDv(1,30),e.qZA())}function de(n,s){1&n&&(e.TgZ(0,"span",29),e.SDv(1,31),e.qZA())}function ye(n,s){1&n&&(e.TgZ(0,"span",29),e.SDv(1,35),e.qZA())}function Ue(n,s){if(1&n&&(e.TgZ(0,"div",8),e.TgZ(1,"label",32),e.SDv(2,33),e.qZA(),e.TgZ(3,"div",15),e._UZ(4,"input",34),e.YNc(5,ye,2,0,"span",17),e.qZA(),e.qZA()),2&n){e.oxw();const t=e.MAs(2),o=e.oxw();e.xp6(5),e.Q6J("ngIf",o.hostForm.showError("addr",t,"pattern"))}}function Oe(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div"),e.TgZ(1,"form",5,6),e.TgZ(3,"div",7),e.TgZ(4,"div",8),e.TgZ(5,"label",9),e.ynx(6),e.SDv(7,10),e.BQk(),e.TgZ(8,"cd-helper"),e.TgZ(9,"p"),e.SDv(10,11),e.qZA(),e.TgZ(11,"ul"),e.TgZ(12,"li"),e.tHW(13,12),e._UZ(14,"samp"),e.N_p(),e.qZA(),e.TgZ(15,"li"),e.tHW(16,13),e._UZ(17,"samp"),e.N_p(),e.qZA(),e.TgZ(18,"li"),e.tHW(19,14),e._UZ(20,"samp"),e.N_p(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(21,"div",15),e.TgZ(22,"input",16),e.NdJ("keyup",function(){return e.CHM(t),e.oxw().checkHostNameValue()}),e.qZA(),e.YNc(23,q,2,0,"span",17),e.YNc(24,de,2,0,"span",17),e.qZA(),e.qZA(),e.YNc(25,Ue,6,1,"div",18),e.TgZ(26,"div",8),e.TgZ(27,"label",19),e.SDv(28,20),e.qZA(),e.TgZ(29,"div",15),e._UZ(30,"cd-select-badges",21),e.qZA(),e.qZA(),e.TgZ(31,"div",8),e.TgZ(32,"div",22),e.TgZ(33,"div",23),e._UZ(34,"input",24),e.TgZ(35,"label",25),e.SDv(36,26),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(37,"div",27),e.TgZ(38,"cd-form-button-panel",28),e.NdJ("submitActionEvent",function(){return e.CHM(t),e.oxw().submit()}),e.ALo(39,"titlecase"),e.ALo(40,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=e.MAs(2),o=e.oxw();e.xp6(1),e.Q6J("formGroup",o.hostForm),e.xp6(22),e.Q6J("ngIf",o.hostForm.showError("hostname",t,"required")),e.xp6(1),e.Q6J("ngIf",o.hostForm.showError("hostname",t,"uniqueName")),e.xp6(1),e.Q6J("ngIf",!o.hostPattern),e.xp6(5),e.Q6J("data",o.hostForm.controls.labels.value)("options",o.labelsOption)("customBadges",!0)("messages",o.messages),e.xp6(8),e.Q6J("form",o.hostForm)("submitText",e.lcZ(39,10,o.action)+" "+e.lcZ(40,12,o.resource))}}let Xe=(()=>{class n extends Oa.E{constructor(t,o,c,g,C){super(),this.router=t,this.actionLabels=o,this.hostService=c,this.taskWrapper=g,this.activeModal=C,this.hostnameArray=[],this.hostPattern=!1,this.labelsOption=[],this.messages=new Hc.a({empty:"There are no labels.",filter:"Filter or add labels",add:"Add label"}),this.resource="host",this.action=this.actionLabels.ADD}ngOnInit(){this.router.url.includes("hosts")&&(this.pageURL="hosts"),this.createForm(),this.hostService.list("false").subscribe(t=>{this.hostnames=t.map(o=>o.hostname),this.loadingReady()}),this.hostService.getLabels().subscribe(t=>{const o=new Set(t.concat(this.hostService.predefinedLabels));this.labelsOption=Array.from(o).map(c=>({enabled:!0,name:c,selected:!1,description:null}))})}checkHostNameValue(){this.hostPattern=!!this.hostForm.get("hostname").value.match(/[()\[\]{},]/g)}createForm(){this.hostForm=new Hs.d({hostname:new Mn.NI("",{validators:[Mn.kI.required,ss.h.custom("uniqueName",t=>this.hostnames&&-1!==this.hostnames.indexOf(t))]}),addr:new Mn.NI("",{validators:[ss.h.ip()]}),labels:new Mn.NI([]),maintenance:new Mn.NI({value:!1,disabled:"hosts"!==this.pageURL})})}isCommaSeparatedPattern(t){return t.includes(",")}isRangeTypePattern(t){return t.includes("[")&&t.includes("]")&&!t.match(/(?![^(]*\)),/g)}replaceBraces(t){return t.replace(/(\d)\s*-\s*(\d)/g,"$1..$2").replace(/\(/g,"{").replace(/\)/g,"}").replace(/\[/g,"{").replace(/]/g,"}")}checkHostNamePattern(t){if(this.isRangeTypePattern(t)){const o=this.replaceBraces(t);this.hostnameArray=Rc()(o)}else if(this.isCommaSeparatedPattern(t)){let o=[];o=t.split(","),o.forEach(c=>{if(this.isRangeTypePattern(c)){const g=this.replaceBraces(c);this.hostnameArray=this.hostnameArray.concat(Rc()(g))}else this.hostnameArray.push(c)})}else this.hostnameArray.push(t)}submit(){const t=this.hostForm.get("hostname").value;this.checkHostNamePattern(t),this.addr=this.hostForm.get("addr").value,this.status=this.hostForm.get("maintenance").value?"maintenance":"",this.allLabels=this.hostForm.get("labels").value,"hosts"!==this.pageURL&&!this.allLabels.includes("_no_schedule")&&this.allLabels.push("_no_schedule"),this.hostnameArray.forEach(o=>{this.taskWrapper.wrapTaskAroundCall({task:new cl.R("host/"+$i.MQ.ADD,{hostname:o}),call:this.hostService.create(o,this.addr,this.allLabels,this.status)}).subscribe({error:()=>{this.hostForm.setErrors({cdSubmitButton:!0})},complete:()=>{"hosts"===this.pageURL?this.router.navigate([this.pageURL,{outlets:{modal:null}}]):this.activeModal.close()}})})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Bo.F0),e.Y36($i.p4),e.Y36(Xl),e.Y36(Ll.P),e.Y36(ut.Kz))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-host-form"]],features:[e.qOj],decls:7,vars:9,consts:function(){let s,t,o,c,g,C,D,P,j,W,re,oe;return s="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",t="Hostname",o="To add multiple hosts at once, you can enter:",c="a comma-separated list of hostnames " + "\ufffd#14\ufffd" + "(e.g.: example-01,example-02,example-03)" + "\ufffd/#14\ufffd" + ",",g="a range expression " + "\ufffd#17\ufffd" + "(e.g.: example-[01-03].ceph)" + "\ufffd/#17\ufffd" + ",",C="a comma separated range expression " + "\ufffd#20\ufffd" + "(e.g.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)" + "\ufffd/#20\ufffd" + "",D="Labels",P="Maintenance Mode",j="This field is required.",W="The chosen hostname is already in use.",re="Network address",oe="The value is not a valid IP address.",[[3,"pageURL","modalRef"],[1,"modal-title"],s,[1,"modal-content"],[4,"cdFormLoading"],["name","hostForm","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],[1,"form-group","row"],["for","hostname",1,"cd-col-form-label","required"],t,o,c,g,C,[1,"cd-col-form-input"],["type","text","placeholder","mon-123","id","hostname","name","hostname","formControlName","hostname","autofocus","",1,"form-control",3,"keyup"],["class","invalid-feedback",4,"ngIf"],["class","form-group row",4,"ngIf"],["for","labels",1,"cd-col-form-label"],D,["id","labels",3,"data","options","customBadges","messages"],[1,"cd-col-form-offset"],[1,"custom-control","custom-checkbox"],["id","maintenance","type","checkbox","formControlName","maintenance",1,"custom-control-input"],["for","maintenance",1,"custom-control-label"],P,[1,"modal-footer"],["wrappingClass","text-right",3,"form","submitText","submitActionEvent"],[1,"invalid-feedback"],j,W,["for","addr",1,"cd-col-form-label"],re,["type","text","placeholder","192.168.0.1","id","addr","name","addr","formControlName","addr",1,"form-control"],oe]},template:function(t,o){1&t&&(e.TgZ(0,"cd-modal",0),e.TgZ(1,"span",1),e.SDv(2,2),e.ALo(3,"titlecase"),e.ALo(4,"upperFirst"),e.qZA(),e.ynx(5,3),e.YNc(6,Oe,41,14,"div",4),e.BQk(),e.qZA()),2&t&&(e.Q6J("pageURL",o.pageURL)("modalRef",o.activeModal),e.xp6(4),e.pQV(e.lcZ(3,5,o.action))(e.lcZ(4,7,o.resource)),e.QtT(2),e.xp6(2),e.Q6J("cdFormLoading",o.loading))},directives:[bu.z,Ol.y,Mn._Y,Mn.JL,ll.V,Mn.sg,Za.P,h.S,la.o,Mn.Fj,ja.b,Mn.JJ,Mn.u,E.U,_.O5,R.m,Mn.Wl,ul.p],pipes:[_.rS,F.m],styles:[""]}),n})();var gt=i(34501),yt=i(55657);const nn=["deviceLocation"],Pn=["lifeExpectancy"],xn=["lifeExpectancyTimestamp"];function ir(n,s){if(1&n&&e._UZ(0,"cd-table",5),2&n){const t=e.oxw();e.Q6J("data",t.devices)("columns",t.columns)}}function Gr(n,s){1&n&&(e.TgZ(0,"cd-alert-panel",6),e.SDv(1,7),e.qZA())}function Pi(n,s){if(1&n&&(e.TgZ(0,"span"),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.xp6(1),e.Oqu(t.dev)}}function Zo(n,s){1&n&&e.YNc(0,Pi,2,1,"span",8),2&n&&e.Q6J("ngForOf",s.value)}function Lo(n,s){1&n&&(e.TgZ(0,"span"),e.SDv(1,10),e.ALo(2,"notAvailable"),e.qZA()),2&n&&(e.xp6(2),e.pQV(e.lcZ(2,1,"")),e.QtT(1))}function Gs(n,s){if(1&n&&(e.TgZ(0,"span"),e._uU(1),e.ALo(2,"i18nPlural"),e.qZA()),2&n){const t=e.oxw().value,o=e.oxw();e.xp6(1),e.hij("> ",e.xi3(2,1,t.min,o.translationMapping),"")}}function Xs(n,s){if(1&n&&(e.TgZ(0,"span"),e._uU(1),e.ALo(2,"i18nPlural"),e.qZA()),2&n){const t=e.oxw().value,o=e.oxw();e.xp6(1),e.hij("< ",e.xi3(2,1,t.max,o.translationMapping),"")}}function dl(n,s){if(1&n&&(e.TgZ(0,"span"),e._uU(1),e.ALo(2,"i18nPlural"),e.qZA()),2&n){const t=e.oxw().value,o=e.oxw();e.xp6(1),e.AsE("",t.min," to ",e.xi3(2,2,t.max,o.translationMapping),"")}}function ha(n,s){if(1&n&&(e.YNc(0,Lo,3,3,"span",9),e.YNc(1,Gs,3,4,"span",9),e.YNc(2,Xs,3,4,"span",9),e.YNc(3,dl,3,5,"span",9)),2&n){const t=s.value;e.Q6J("ngIf",!t.life_expectancy_enabled),e.xp6(1),e.Q6J("ngIf",t.min&&!t.max),e.xp6(1),e.Q6J("ngIf",t.max&&!t.min),e.xp6(1),e.Q6J("ngIf",t.max&&t.min)}}function ia(n,s){1&n&&e._uU(0),2&n&&e.hij(" ",s.value,"\n")}let Pa=(()=>{class n{constructor(t,o,c){this.hostService=t,this.datePipe=o,this.osdService=c,this.hostname="",this.osdId=null,this.devices=null,this.columns=[],this.translationMapping={"=1":"# week",other:"# weeks"}}ngOnInit(){this.columns=[{prop:"devid",name:"Device ID",minWidth:200},{prop:"state",name:"State of Health",flexGrow:1,cellTransformation:bl.e.badge,customTemplateConfig:{map:{good:{value:"Good",class:"badge-success"},warning:{value:"Warning",class:"badge-warning"},bad:{value:"Bad",class:"badge-danger"},stale:{value:"Stale",class:"badge-info"},unknown:{value:"Unknown",class:"badge-dark"}}}},{prop:"life_expectancy_weeks",name:"Life Expectancy",cellTemplate:this.lifeExpectancyTemplate},{prop:"life_expectancy_stamp",name:"Prediction Creation Date",cellTemplate:this.lifeExpectancyTimestampTemplate,pipe:this.datePipe,isHidden:!0},{prop:"location",name:"Device Name",cellTemplate:this.locationTemplate},{prop:"readableDaemons",name:"Daemons"}]}ngOnChanges(){const t=o=>this.devices=o;this.hostname?this.hostService.getDevices(this.hostname).subscribe(t):null!==this.osdId&&this.osdService.getDevices(this.osdId).subscribe(t)}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Xl),e.Y36(_.uU),e.Y36(Ji))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-device-list"]],viewQuery:function(t,o){if(1&t&&(e.Gf(nn,7),e.Gf(Pn,7),e.Gf(xn,7)),2&t){let c;e.iGM(c=e.CRH())&&(o.locationTemplate=c.first),e.iGM(c=e.CRH())&&(o.lifeExpectancyTemplate=c.first),e.iGM(c=e.CRH())&&(o.lifeExpectancyTimestampTemplate=c.first)}},inputs:{hostname:"hostname",osdId:"osdId"},features:[e.TTD],decls:8,vars:2,consts:function(){let s,t;return s="Neither hostname nor OSD ID given",t="" + "\ufffd0\ufffd" + "",[[3,"data","columns",4,"ngIf"],["type","warning",4,"ngIf"],["deviceLocation",""],["lifeExpectancy",""],["lifeExpectancyTimestamp",""],[3,"data","columns"],["type","warning"],s,[4,"ngFor","ngForOf"],[4,"ngIf"],t]},template:function(t,o){1&t&&(e.YNc(0,ir,1,2,"cd-table",0),e.YNc(1,Gr,2,0,"cd-alert-panel",1),e.YNc(2,Zo,1,1,"ng-template",null,2,e.W1O),e.YNc(4,ha,4,4,"ng-template",null,3,e.W1O),e.YNc(6,ia,1,1,"ng-template",null,4,e.W1O)),2&t&&(e.Q6J("ngIf",o.hostname||null!==o.osdId),e.xp6(1),e.Q6J("ngIf",""===o.hostname&&null===o.osdId))},directives:[_.O5,ks.a,gt.G,_.sg],pipes:[yt.g,_.Gx],styles:[""]}),n})();var il=i(30490);function Eu(n,s){1&n&&(e.TgZ(0,"cd-alert-panel",2),e.SDv(1,3),e.qZA())}function wa(n,s){1&n&&(e.TgZ(0,"cd-alert-panel",2),e.tHW(1,4),e._UZ(2,"cd-doc",5),e.N_p(),e.qZA())}let ou=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-orchestrator-doc-panel"]],inputs:{missingFeatures:"missingFeatures"},decls:3,vars:2,consts:function(){let s,t;return s="The feature is not supported in the current Orchestrator.",t="Orchestrator is not available. Please consult the " + "\ufffd#2\ufffd" + "" + "\ufffd/#2\ufffd" + " on how to configure and enable the functionality.",[["type","info",4,"ngIf","ngIfElse"],["elseBlock",""],["type","info"],s,t,["section","orch"]]},template:function(t,o){if(1&t&&(e.YNc(0,Eu,2,0,"cd-alert-panel",0),e.YNc(1,wa,3,0,"ng-template",null,1,e.W1O)),2&t){const c=e.MAs(2);e.Q6J("ngIf",o.missingFeatures)("ngIfElse",c)}},directives:[_.O5,gt.G,il.K],styles:[""]}),n})(),gu=(()=>{class n{constructor(t,o,c,g,C,D){this.authStorageService=t,this.dimlessBinary=o,this.modalService=c,this.notificationService=g,this.orchService=C,this.hostService=D,this.devices=[],this.showAvailDeviceOnly=!1,this.hiddenColumns=[],this.filterColumns=["hostname","human_readable_type","available","sys_api.vendor","sys_api.model","sys_api.size"],this.selectionType=void 0,this.filterChange=new e.vpe,this.fetchInventory=new e.vpe,this.icons=xo.P,this.columns=[],this.selection=new El.r,this.orchStatus=void 0,this.actionOrchFeatures={identify:[cu.DEVICE_BLINK_LIGHT]}}ngOnInit(){this.permission=this.authStorageService.getPermissions().osd,this.tableActions=[{permission:"update",icon:xo.P.show,click:()=>this.identifyDevice(),name:"Identify",disable:o=>this.getDisable("identify",o),canBePrimary:o=>!o.hasSingleSelection,visible:()=>wr().isString(this.selectionType)}];const t=[{name:"Hostname",prop:"hostname",flexGrow:1},{name:"Device path",prop:"path",flexGrow:1},{name:"Type",prop:"human_readable_type",flexGrow:1,cellTransformation:bl.e.badge,customTemplateConfig:{map:{hdd:{value:"HDD",class:"badge-hdd"},ssd:{value:"SSD",class:"badge-ssd"}}}},{name:"Available",prop:"available",flexGrow:1,cellClass:"text-center",cellTransformation:bl.e.checkIcon},{name:"Vendor",prop:"sys_api.vendor",flexGrow:1},{name:"Model",prop:"sys_api.model",flexGrow:1},{name:"Size",prop:"sys_api.size",flexGrow:1,pipe:this.dimlessBinary},{name:"OSDs",prop:"osd_ids",flexGrow:1,cellTransformation:bl.e.badge,customTemplateConfig:{class:"badge-dark",prefix:"osd."}}];this.columns=t.filter(o=>!this.hiddenColumns.includes(o.prop)),wr().forEach(this.filterColumns,o=>{const c=wr().find(this.columns,{prop:o});c&&(c.filterable=!0)}),this.fetchInventory.observers.length>0&&(this.fetchInventorySub=this.table.fetchData.subscribe(()=>{this.fetchInventory.emit()}))}getDevices(){this.showAvailDeviceOnly?this.hostService.inventoryDeviceList().subscribe(t=>{this.devices=wr().filter(t,"available"),this.devices=[...this.devices]},()=>{this.devices=[]}):this.devices=[...this.devices]}ngOnDestroy(){this.fetchInventorySub&&this.fetchInventorySub.unsubscribe()}onColumnFiltersChanged(t){this.filterChange.emit(t)}getDisable(t,o){return!o.hasSingleSelection||this.orchService.getTableActionDisableDesc(this.orchStatus,this.actionOrchFeatures[t])}updateSelection(t){this.selection=t}identifyDevice(){const t=this.selection.first(),o=t.hostname,c=t.path||t.device_id;this.modalService.show(zd.X,{titleText:"Identify device " + c + "",message:"Please enter the duration how long to blink the LED.",fields:[{type:"select",name:"duration",value:300,required:!0,typeConfig:{options:[{text:"1 minute",value:60},{text:"2 minutes",value:120},{text:"5 minutes",value:300},{text:"10 minutes",value:600},{text:"15 minutes",value:900}]}}],submitButtonText:"Execute",onSubmit:g=>{this.hostService.identifyDevice(o,c,g.duration).subscribe(()=>{this.notificationService.show(pa.k.success,"Identifying '" + c + "' started on host '" + o + "'")})}})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(vt.j),e.Y36(mn.$),e.Y36(Bl.Z),e.Y36(hl.g),e.Y36(Mc),e.Y36(Xl))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-inventory-devices"]],viewQuery:function(t,o){if(1&t&&e.Gf(ks.a,7),2&t){let c;e.iGM(c=e.CRH())&&(o.table=c.first)}},inputs:{devices:"devices",showAvailDeviceOnly:"showAvailDeviceOnly",hiddenColumns:"hiddenColumns",filterColumns:"filterColumns",selectionType:"selectionType",orchStatus:"orchStatus"},outputs:{filterChange:"filterChange",fetchInventory:"fetchInventory"},decls:2,vars:8,consts:[["identifier","uid","columnMode","flex",3,"data","columns","forceIdentifier","selectionType","searchField","fetchData","updateSelection","columnFiltersChanged"],[1,"table-actions",3,"permission","selection","tableActions"]],template:function(t,o){1&t&&(e.TgZ(0,"cd-table",0),e.NdJ("fetchData",function(){return o.getDevices()})("updateSelection",function(g){return o.updateSelection(g)})("columnFiltersChanged",function(g){return o.onColumnFiltersChanged(g)}),e._UZ(1,"cd-table-actions",1),e.qZA()),2&t&&(e.Q6J("data",o.devices)("columns",o.columns)("forceIdentifier",!0)("selectionType",o.selectionType)("searchField",!1),e.xp6(1),e.Q6J("permission",o.permission)("selection",o.selection)("tableActions",o.tableActions))},directives:[ks.a,Js.K],styles:[".filter[_ngcontent-%COMP%]{padding-right:8px}.fa-stack[_ngcontent-%COMP%]{font-size:.79rem}.fa-stack[_ngcontent-%COMP%] .fa-stack-1x[_ngcontent-%COMP%]{margin-left:8px;margin-top:5px}"]}),n})();function Nc(n,s){1&n&&e._UZ(0,"cd-orchestrator-doc-panel")}const sc=function(){return[]},gf=function(){return["hostname"]};function Ga(n,s){if(1&n){const t=e.EpF();e.ynx(0),e.TgZ(1,"legend"),e.SDv(2,1),e.qZA(),e.TgZ(3,"div",2),e.TgZ(4,"div",3),e.TgZ(5,"cd-inventory-devices",4),e.NdJ("fetchInventory",function(){return e.CHM(t),e.oxw().refresh()}),e.qZA(),e.qZA(),e.qZA(),e.BQk()}if(2&n){const t=e.oxw();e.xp6(5),e.Q6J("devices",t.devices)("hiddenColumns",void 0===t.hostname?e.DdM(3,sc):e.DdM(4,gf))("orchStatus",t.orchStatus)}}let Q=(()=>{class n{constructor(t,o,c){this.orchService=t,this.hostService=o,this.ngZone=c,this.reloadInterval=5e3,this.firstRefresh=!0,this.icons=xo.P,this.showDocPanel=!1,this.devices=[]}ngOnInit(){this.orchService.status().subscribe(t=>{this.orchStatus=t,this.showDocPanel=!t.available,t.available&&this.ngZone.runOutsideAngular(()=>{this.reloadSubscriber=(0,V.H)(this.reloadInterval,this.reloadInterval).subscribe(()=>{this.ngZone.run(()=>{this.getInventory(!1)})})})})}ngOnDestroy(){var t;null===(t=this.reloadSubscriber)||void 0===t||t.unsubscribe()}ngOnChanges(){var t;(null===(t=this.orchStatus)||void 0===t?void 0:t.available)&&(this.devices=[],this.getInventory(!1))}getInventory(t){""!==this.hostname&&this.hostService.inventoryDeviceList(this.hostname,t).subscribe(o=>{this.devices=o},()=>{this.devices=[]})}refresh(){this.getInventory(!this.firstRefresh),this.firstRefresh=!1}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Mc),e.Y36(Xl),e.Y36(e.R0b))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-inventory"]],inputs:{hostname:"hostname"},features:[e.TTD],decls:2,vars:2,consts:function(){let s;return s="Physical Disks",[[4,"ngIf"],s,[1,"row"],[1,"col-md-12"],["selectionType","single",3,"devices","hiddenColumns","orchStatus","fetchInventory"]]},template:function(t,o){1&t&&(e.YNc(0,Nc,1,0,"cd-orchestrator-doc-panel",0),e.YNc(1,Ga,6,5,"ng-container",0)),2&t&&(e.Q6J("ngIf",o.showDocPanel),e.xp6(1),e.Q6J("ngIf",null==o.orchStatus?null:o.orchStatus.available))},directives:[_.O5,ou,gu],styles:[""]}),n})();var ve=i(15257);let nt=class{constructor(s){this.http=s,this.url="api/daemon"}action(s,t){return this.http.put(`${this.url}/${s}`,{action:t,container_image:null},{headers:{Accept:"application/vnd.ceph.api.v0.1+json"},observe:"response"})}};nt.\u0275fac=function(s){return new(s||nt)(e.LFG(y.eN))},nt.\u0275prov=e.Yz7({token:nt,factory:nt.\u0275fac,providedIn:"root"}),nt=(0,fa.gn)([pu.o,(0,fa.w6)("design:paramtypes",[y.eN])],nt);var Tt=i(90068);let Qt=(()=>{class n{constructor(t){this.http=t,this.url="api/service"}list(t){const o=t?{params:(new y.LE).set("service_name",t)}:{};return this.http.get(this.url,o)}getDaemons(t){return this.http.get(`${this.url}/${t}/daemons`)}create(t){return this.http.post(this.url,{service_name:t.service_id?`${t.service_type}.${t.service_id}`:t.service_type,service_spec:t},{observe:"response"})}update(t){const o=t.service_id?`${t.service_type}.${t.service_id}`:t.service_type;return this.http.put(`${this.url}/${o}`,{service_name:o,service_spec:t},{observe:"response"})}delete(t){return this.http.delete(`${this.url}/${t}`,{observe:"response"})}getKnownTypes(){return this.http.get(`${this.url}/known_types`)}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(y.eN))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();var cr=i(37496);const bi=["statusTpl"],cs=["listTpl"],xa=["cpuTpl"],na=["daemonsTable"];function _l(n,s){1&n&&e._UZ(0,"cd-orchestrator-doc-panel")}function zl(n,s){1&n&&e.GkF(0)}function zc(n,s){if(1&n&&(e.TgZ(0,"div"),e.YNc(1,zl,1,0,"ng-container",7),e.qZA()),2&n){e.oxw();const t=e.MAs(9);e.xp6(1),e.Q6J("ngTemplateOutlet",t)}}function qf(n,s){1&n&&e.GkF(0)}function Ld(n,s){if(1&n&&e.YNc(0,qf,1,0,"ng-container",7),2&n){e.oxw(2);const t=e.MAs(9);e.Q6J("ngTemplateOutlet",t)}}function Hp(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-table",18,19),e.NdJ("fetchData",function(c){return e.CHM(t),e.oxw(3).getServices(c)}),e.qZA()}if(2&n){const t=e.oxw(3);e.Q6J("data",t.services)("columns",t.serviceColumns)}}function Up(n,s){if(1&n&&e.YNc(0,Hp,2,2,"cd-table",17),2&n){const t=e.oxw(2);e.Q6J("ngIf",t.hasOrchestrator)}}function mf(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"ul",8,9),e.TgZ(3,"li",10),e.TgZ(4,"a",11),e.SDv(5,12),e.qZA(),e.YNc(6,Ld,1,1,"ng-template",13),e.qZA(),e.TgZ(7,"li",14),e.TgZ(8,"a",11),e.SDv(9,15),e.qZA(),e.YNc(10,Up,1,1,"ng-template",13),e.qZA(),e.qZA(),e._UZ(11,"div",16),e.BQk()),2&n){const t=e.MAs(2);e.xp6(11),e.Q6J("ngbNavOutlet",t)}}function Uf(n,s){if(1&n&&(e.TgZ(0,"span",20),e.ALo(1,"pipeFunction"),e._uU(2),e.qZA()),2&n){const t=s.row,o=e.oxw();e.Q6J("ngClass",e.xi3(1,2,t,o.getStatusClass)),e.xp6(2),e.hij(" ",t.status_desc," ")}}const dd=function(n){return[n]};function Fd(n,s){if(1&n&&(e.TgZ(0,"span"),e._UZ(1,"i",27),e.qZA()),2&n){const t=e.oxw(4);e.xp6(1),e.Q6J("ngClass",e.VKq(1,dd,t.icons.infoCircle))}}function pp(n,s){if(1&n&&(e.TgZ(0,"span"),e._UZ(1,"i",27),e.qZA()),2&n){const t=e.oxw(4);e.xp6(1),e.Q6J("ngClass",e.VKq(1,dd,t.icons.warning))}}function fl(n,s){if(1&n&&(e.TgZ(0,"li",25),e.TgZ(1,"b"),e._uU(2),e.ALo(3,"relativeDate"),e.qZA(),e.TgZ(4,"span",26),e._uU(5),e.qZA(),e._UZ(6,"br"),e.YNc(7,Fd,2,3,"span",0),e.YNc(8,pp,2,3,"span",0),e._uU(9),e.qZA()),2&n){const t=s.$implicit;e.xp6(2),e.hij("",e.lcZ(3,5,t.created)," - "),e.xp6(3),e.Oqu(t.subject),e.xp6(2),e.Q6J("ngIf","INFO"===t.level),e.xp6(1),e.Q6J("ngIf","ERROR"===t.level),e.xp6(1),e.hij(" ",t.message," ")}}function i_(n,s){if(1&n&&(e.TgZ(0,"ul",23),e.YNc(1,fl,10,7,"li",24),e.qZA()),2&n){const t=e.oxw().value,o=e.oxw();e.xp6(1),e.Q6J("ngForOf",t)("ngForTrackBy",o.trackByFn)}}function F_(n,s){1&n&&(e.TgZ(0,"div",25),e.TgZ(1,"span"),e._uU(2,"No data available"),e.qZA(),e.qZA())}function Bf(n,s){if(1&n&&e.YNc(0,F_,3,0,"div",28),2&n){const t=e.oxw().value;e.Q6J("ngIf",0===(null==t?null:t.length))}}function kd(n,s){if(1&n&&(e.YNc(0,i_,2,2,"ul",21),e.YNc(1,Bf,1,1,"ng-template",null,22,e.W1O)),2&n){const t=s.value,o=e.MAs(2);e.Q6J("ngIf",null==t?null:t.length)("ngIfElse",o)}}function Yf(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-table",30,31),e.NdJ("fetchData",function(c){return e.CHM(t),e.oxw(2).getDaemons(c)})("updateSelection",function(c){return e.CHM(t),e.oxw(2).updateSelection(c)}),e._UZ(2,"cd-table-actions",32),e.qZA()}if(2&n){const t=e.oxw(2);e.Q6J("data",t.daemons)("columns",t.columns),e.xp6(2),e.Q6J("selection",t.selection)("permission",t.permissions.hosts)("tableActions",t.tableActions)}}function eh(n,s){if(1&n&&e.YNc(0,Yf,3,5,"cd-table",29),2&n){const t=e.oxw();e.Q6J("ngIf",t.hasOrchestrator)}}function bd(n,s){if(1&n&&e._UZ(0,"cd-usage-bar",33),2&n){const t=s.row,o=e.oxw();e.Q6J("total",o.total)("calculatePerc",!1)("used",t.cpu_percentage)("isBinary",!1)("warningThreshold",o.warningThreshold)("errorThreshold",o.errorThreshold)}}let Rh=(()=>{class n{constructor(t,o,c,g,C,D,P,j,W){this.hostService=t,this.cephServiceService=o,this.orchService=c,this.relativeDatePipe=g,this.dimlessBinary=C,this.actionLabels=D,this.authStorageService=P,this.daemonService=j,this.notificationService=W,this.hiddenColumns=[],this.total=100,this.warningThreshold=.8,this.errorThreshold=.9,this.icons=xo.P,this.daemons=[],this.services=[],this.columns=[],this.serviceColumns=[],this.selection=new El.r,this.hasOrchestrator=!1,this.showDocPanel=!1}ngOnInit(){this.permissions=this.authStorageService.getPermissions(),this.tableActions=[{permission:"update",icon:xo.P.start,click:()=>this.daemonAction("start"),name:this.actionLabels.START,disable:()=>this.actionDisabled("start")},{permission:"update",icon:xo.P.stop,click:()=>this.daemonAction("stop"),name:this.actionLabels.STOP,disable:()=>this.actionDisabled("stop")},{permission:"update",icon:xo.P.restart,click:()=>this.daemonAction("restart"),name:this.actionLabels.RESTART,disable:()=>this.actionDisabled("restart")},{permission:"update",icon:xo.P.deploy,click:()=>this.daemonAction("redeploy"),name:this.actionLabels.REDEPLOY,disable:()=>this.actionDisabled("redeploy")}],this.columns=[{name:"Hostname",prop:"hostname",flexGrow:2,filterable:!0},{name:"Daemon name",prop:"daemon_name",flexGrow:1,filterable:!0},{name:"Version",prop:"version",flexGrow:1,filterable:!0},{name:"Status",prop:"status_desc",flexGrow:1,filterable:!0,cellTemplate:this.statusTpl},{name:"Last Refreshed",prop:"last_refresh",pipe:this.relativeDatePipe,flexGrow:1},{name:"CPU Usage",prop:"cpu_percentage",flexGrow:1,cellTemplate:this.cpuTpl},{name:"Memory Usage",prop:"memory_usage",flexGrow:1,pipe:this.dimlessBinary,cellClass:"text-right"},{name:"Daemon Events",prop:"events",flexGrow:2,cellTemplate:this.listTpl}],this.serviceColumns=[{name:"Service Name",prop:"service_name",flexGrow:2,filterable:!0},{name:"Service Type",prop:"service_type",flexGrow:1,filterable:!0},{name:"Service Events",prop:"events",flexGrow:5,cellTemplate:this.listTpl}],this.orchService.status().subscribe(t=>{this.hasOrchestrator=t.available,this.showDocPanel=!t.available}),this.columns=this.columns.filter(t=>!this.hiddenColumns.includes(t.prop))}ngOnChanges(){wr().isUndefined(this.daemonsTable)||this.daemonsTable.reloadData()}ngAfterViewInit(){this.daemonsTableTplsSub=this.daemonsTableTpls.changes.subscribe(t=>{this.daemonsTable=t.first})}ngOnDestroy(){this.daemonsTableTplsSub&&this.daemonsTableTplsSub.unsubscribe(),this.serviceSub&&this.serviceSub.unsubscribe()}getStatusClass(t){return wr().get({"-1":"badge-danger",0:"badge-warning",1:"badge-success"},t.status,"badge-dark")}getDaemons(t){let o;if(this.hostname)o=this.hostService.getDaemons(this.hostname);else{if(!this.serviceName)return void(this.daemons=[]);o=this.cephServiceService.getDaemons(this.serviceName)}o.subscribe(c=>{this.daemons=c,this.sortDaemonEvents()},()=>{this.daemons=[],t.error()})}sortDaemonEvents(){this.daemons.forEach(t=>{var o;null===(o=t.events)||void 0===o||o.sort((c,g)=>new Date(g.created).getTime()-new Date(c.created).getTime())})}getServices(t){this.serviceSub=this.cephServiceService.list(this.serviceName).subscribe(o=>{this.services=o},()=>{this.services=[],t.error()})}trackByFn(t,o){return o.created}updateSelection(t){this.selection=t}daemonAction(t){var o;this.daemonService.action(null===(o=this.selection.first())||void 0===o?void 0:o.daemon_name,t).pipe((0,ve.q)(1)).subscribe({next:c=>{this.notificationService.show(pa.k.success,`Daemon ${t} scheduled`,c.body.toString())},error:c=>{this.notificationService.show(pa.k.error,"Daemon action failed",c.body.toString())}})}actionDisabled(t){var o;if(null===(o=this.selection)||void 0===o?void 0:o.hasSelection){const c=this.selection.selected[0];if("mon"===c.daemon_type||"mgr"===c.daemon_type)return!0;switch(t){case"start":if("running"===c.status_desc)return!0;break;case"stop":if("stopped"===c.status_desc)return!0}return!1}return!0}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Xl),e.Y36(Qt),e.Y36(Mc),e.Y36(Tt.h),e.Y36(mn.$),e.Y36($i.p4),e.Y36(vt.j),e.Y36(nt),e.Y36(hl.g))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-service-daemon-list"]],viewQuery:function(t,o){if(1&t&&(e.Gf(bi,7),e.Gf(cs,7),e.Gf(xa,7),e.Gf(na,5)),2&t){let c;e.iGM(c=e.CRH())&&(o.statusTpl=c.first),e.iGM(c=e.CRH())&&(o.listTpl=c.first),e.iGM(c=e.CRH())&&(o.cpuTpl=c.first),e.iGM(c=e.CRH())&&(o.daemonsTableTpls=c)}},inputs:{serviceName:"serviceName",hostname:"hostname",hiddenColumns:"hiddenColumns",flag:"flag"},features:[e.TTD],decls:12,vars:3,consts:function(){let s,t;return s="Details",t="Service Events",[[4,"ngIf"],[4,"ngIf","ngIfElse"],["serviceDetailsTpl",""],["statusTpl",""],["listTpl",""],["serviceDaemonDetailsTpl",""],["cpuTpl",""],[4,"ngTemplateOutlet"],["ngbNav","","cdStatefulTab","service-details",1,"nav-tabs"],["nav","ngbNav"],["ngbNavItem","details"],["ngbNavLink",""],s,["ngbNavContent",""],["ngbNavItem","service_events"],t,[3,"ngbNavOutlet"],["columnMode","flex",3,"data","columns","fetchData",4,"ngIf"],["columnMode","flex",3,"data","columns","fetchData"],["serviceTable",""],[1,"badge",3,"ngClass"],["class","list-group list-group-flush",4,"ngIf","ngIfElse"],["noEventsAvailable",""],[1,"list-group","list-group-flush"],["class","list-group-item",4,"ngFor","ngForOf","ngForTrackBy"],[1,"list-group-item"],[1,"badge","badge-info"],["aria-hidden","true",3,"ngClass"],["class","list-group-item",4,"ngIf"],["selectionType","single","columnMode","flex","identifier","daemon_name",3,"data","columns","fetchData","updateSelection",4,"ngIf"],["selectionType","single","columnMode","flex","identifier","daemon_name",3,"data","columns","fetchData","updateSelection"],["daemonsTable",""],["id","service-daemon-list-actions",1,"table-actions",3,"selection","permission","tableActions"],[3,"total","calculatePerc","used","isBinary","warningThreshold","errorThreshold"]]},template:function(t,o){if(1&t&&(e.YNc(0,_l,1,0,"cd-orchestrator-doc-panel",0),e.YNc(1,zc,2,1,"div",1),e.YNc(2,mf,12,1,"ng-template",null,2,e.W1O),e.YNc(4,Uf,3,5,"ng-template",null,3,e.W1O),e.YNc(6,kd,3,2,"ng-template",null,4,e.W1O),e.YNc(8,eh,1,1,"ng-template",null,5,e.W1O),e.YNc(10,bd,1,6,"ng-template",null,6,e.W1O)),2&t){const c=e.MAs(3);e.Q6J("ngIf",o.showDocPanel),e.xp6(1),e.Q6J("ngIf","hostDetails"===o.flag)("ngIfElse",c)}},directives:[_.O5,ou,_.tP,ut.Pz,un.m,ut.nv,ut.Vx,ut.uN,ut.tO,ks.a,_.mk,_.sg,Js.K,ao.O],pipes:[cr.i,Tt.h],styles:[".fa-info-circle[_ngcontent-%COMP%]{color:#2b99a8}.fa-exclamation-triangle[_ngcontent-%COMP%]{color:#ef5c55}.list-group-item[_ngcontent-%COMP%]{background-color:transparent;border-width:0}"]}),n})();var th=i(8958);const nh=["innerNav"];function Nh(n,s){1&n&&(e.TgZ(0,"cd-alert-panel",5),e.SDv(1,6),e.qZA())}function rh(n,s){1&n&&(e.TgZ(0,"cd-alert-panel",7),e.SDv(1,8),e.qZA())}function Ed(n,s){1&n&&(e.TgZ(0,"cd-alert-panel",10),e.SDv(1,11),e.qZA())}function xf(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"cd-alert-panel",20),e._uU(2),e.qZA(),e.BQk()),2&n){const t=e.oxw(2).$implicit;e.xp6(2),e.Oqu(t.value.userMessage)}}function Ph(n,s){1&n&&(e.TgZ(0,"cd-alert-panel",23),e.SDv(1,24),e.qZA())}function Bp(n,s){1&n&&(e.ynx(0),e.TgZ(1,"cd-alert-panel",26),e.SDv(2,27),e.qZA(),e.BQk())}function ih(n,s){1&n&&(e.TgZ(0,"cd-alert-panel",28),e.SDv(1,29),e.qZA())}function Ih(n,s){if(1&n&&(e.YNc(0,Bp,3,0,"ng-container",0),e.YNc(1,ih,2,0,"ng-template",null,25,e.W1O)),2&n){const t=e.MAs(2),o=e.oxw(3).$implicit;e.Q6J("ngIf",o.value.info.smart_status.passed)("ngIfElse",t)}}function vf(n,s){if(1&n&&(e.YNc(0,Ph,2,0,"cd-alert-panel",21),e.ALo(1,"pipeFunction"),e.YNc(2,Ih,3,2,"ng-template",null,22,e.W1O)),2&n){const t=e.MAs(3),o=e.oxw(2).$implicit,c=e.oxw(4);e.Q6J("ngIf",e.xi3(1,2,null==o.value.info?null:o.value.info.smart_status,c.isEmpty))("ngIfElse",t)}}function Lh(n,s){if(1&n&&e._UZ(0,"cd-table-key-value",36),2&n){const t=e.oxw(4).$implicit;e.Q6J("renderObjects",!0)("data",t.value.info)}}function $d(n,s){1&n&&(e.TgZ(0,"cd-alert-panel",37),e.SDv(1,38),e.qZA())}function hp(n,s){if(1&n&&(e.YNc(0,Lh,1,2,"cd-table-key-value",34),e.ALo(1,"pipeFunction"),e.YNc(2,$d,2,0,"cd-alert-panel",35),e.ALo(3,"pipeFunction")),2&n){const t=e.oxw(3).$implicit,o=e.oxw(4);e.Q6J("ngIf",!e.xi3(1,2,t.value.info,o.isEmpty)),e.xp6(2),e.Q6J("ngIf",e.xi3(3,5,t.value.info,o.isEmpty))}}function Zf(n,s){if(1&n&&e._UZ(0,"cd-table",42),2&n){const t=e.oxw(4).$implicit,o=e.oxw(4);e.Q6J("data",t.value.smart.attributes.table)("columns",o.smartDataColumns)}}function qd(n,s){if(1&n&&e._UZ(0,"cd-table-key-value",43),2&n){const t=e.oxw(4).$implicit;e.Q6J("renderObjects",!0)("data",t.value.smart)}}function ac(n,s){if(1&n&&e._UZ(0,"cd-table-key-value",43),2&n){const t=e.oxw(4).$implicit;e.Q6J("renderObjects",!0)("data",t.value.smart.nvmeData)}}function oh(n,s){1&n&&(e.TgZ(0,"cd-alert-panel",44),e.SDv(1,45),e.qZA())}function k_(n,s){if(1&n&&(e.YNc(0,Zf,1,2,"cd-table",39),e.YNc(1,qd,1,2,"cd-table-key-value",40),e.YNc(2,ac,1,2,"cd-table-key-value",40),e.YNc(3,oh,2,0,"cd-alert-panel",41)),2&n){const t=e.oxw(3).$implicit;e.Q6J("ngIf",null==t.value.smart?null:t.value.smart.attributes),e.xp6(1),e.Q6J("ngIf",null==t.value.smart?null:t.value.smart.scsi_error_counter_log),e.xp6(1),e.Q6J("ngIf",null==t.value.smart?null:t.value.smart.nvmeData),e.xp6(1),e.Q6J("ngIf",!(null!=t.value.smart&&t.value.smart.attributes||null!=t.value.smart&&t.value.smart.nvmeData||null!=t.value.smart&&t.value.smart.scsi_error_counter_log))}}function o_(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"ul",12,30),e.TgZ(3,"li",31),e.TgZ(4,"a",17),e.SDv(5,32),e.qZA(),e.YNc(6,hp,4,8,"ng-template",18),e.qZA(),e.TgZ(7,"li",31),e.TgZ(8,"a",17),e.SDv(9,33),e.qZA(),e.YNc(10,k_,4,4,"ng-template",18),e.qZA(),e.qZA(),e._UZ(11,"div",15),e.BQk()),2&n){const t=e.MAs(2);e.xp6(3),e.Q6J("ngbNavItem",1),e.xp6(4),e.Q6J("ngbNavItem",2),e.xp6(4),e.Q6J("ngbNavOutlet",t)}}function Y(n,s){if(1&n&&(e.YNc(0,xf,3,1,"ng-container",0),e.YNc(1,vf,4,5,"ng-template",null,19,e.W1O),e.YNc(3,o_,12,3,"ng-container",4),e.ALo(4,"pipeFunction"),e.ALo(5,"pipeFunction")),2&n){const t=e.MAs(2),o=e.oxw().$implicit,c=e.oxw(4);e.Q6J("ngIf",o.value.error)("ngIfElse",t),e.xp6(3),e.Q6J("ngIf",!e.xi3(4,3,o.value.info,c.isEmpty)||!e.xi3(5,6,o.value.smart,c.isEmpty))}}function fe(n,s){if(1&n&&(e.TgZ(0,"li",16),e.TgZ(1,"a",17),e._uU(2),e.qZA(),e.YNc(3,Y,6,9,"ng-template",18),e.qZA()),2&n){const t=s.$implicit;e.xp6(2),e.AsE("",t.value.device," (",t.value.identifier,")")}}function w(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"ul",12,13),e.YNc(3,fe,4,2,"li",14),e.ALo(4,"keyvalue"),e.qZA(),e._UZ(5,"div",15),e.BQk()),2&n){const t=e.MAs(2),o=e.oxw(3);e.xp6(3),e.Q6J("ngForOf",e.lcZ(4,2,o.data)),e.xp6(2),e.Q6J("ngbNavOutlet",t)}}function X(n,s){if(1&n&&(e.ynx(0),e.YNc(1,Ed,2,0,"cd-alert-panel",9),e.ALo(2,"pipeFunction"),e.YNc(3,w,6,4,"ng-container",4),e.ALo(4,"pipeFunction"),e.BQk()),2&n){const t=e.oxw(2);e.xp6(1),e.Q6J("ngIf",e.xi3(2,2,t.data,t.isEmpty)),e.xp6(2),e.Q6J("ngIf",!e.xi3(4,5,t.data,t.isEmpty))}}function ke(n,s){if(1&n&&(e.ynx(0),e.YNc(1,Nh,2,0,"cd-alert-panel",2),e.YNc(2,rh,2,0,"cd-alert-panel",3),e.YNc(3,X,5,8,"ng-container",4),e.BQk()),2&n){const t=e.oxw();e.xp6(1),e.Q6J("ngIf",t.error),e.xp6(1),e.Q6J("ngIf",t.incompatible),e.xp6(1),e.Q6J("ngIf",!t.error&&!t.incompatible)}}function ct(n,s){1&n&&(e.TgZ(0,"cd-loading-panel"),e.SDv(1,46),e.qZA())}let Jn=(()=>{class n{constructor(t,o){this.osdService=t,this.hostService=o,this.osdId=null,this.hostname=null,this.loading=!1,this.incompatible=!1,this.error=!1,this.data={},this.isEmpty=wr().isEmpty}isSmartError(t){return void 0!==wr().get(t,"error")}isNvmeSmartData(t){return"nvme"===wr().get(t,"device.protocol","").toLowerCase()}isAtaSmartData(t){return"ata"===wr().get(t,"device.protocol","").toLowerCase()}isIscsiSmartData(t){return"scsi"===wr().get(t,"device.protocol","").toLowerCase()}fetchData(t){const o={};wr().each(t,(c,g)=>{if(this.isSmartError(c)){let C="";C=-22===c.smartctl_error_code?"Smartctl has received an unknown argument (error code " + c.smartctl_error_code + "). You may be using an incompatible version of smartmontools. Version >= 7.0 of smartmontools is required to successfully retrieve data.":"An error with error code " + c.smartctl_error_code + " occurred.",o[g]={error:c.error,smartctl_error_code:c.smartctl_error_code,smartctl_output:c.smartctl_output,userMessage:C,device:c.dev,identifier:c.nvme_vendor}}else 1!==c.json_format_version[0]?this.incompatible=!0:this.isAtaSmartData(c)?o[g]=this.extractAtaData(c):this.isIscsiSmartData(c)?o[g]=this.extractIscsiData(c):this.isNvmeSmartData(c)&&(o[g]=this.extractNvmeData(c))}),this.data=o,this.loading=!1}extractNvmeData(t){return{info:wr().omitBy(t,(c,g)=>["nvme_smart_health_information_log"].includes(g)),smart:{nvmeData:t.nvme_smart_health_information_log},device:t.device.name,identifier:t.serial_number}}extractIscsiData(t){const o=wr().omitBy(t,(c,g)=>["scsi_error_counter_log","scsi_grown_defect_list"].includes(g));return{info:o,smart:{scsi_error_counter_log:t.scsi_error_counter_log,scsi_grown_defect_list:t.scsi_grown_defect_list},device:o.device.name,identifier:o.serial_number}}extractAtaData(t){const o=wr().omitBy(t,(c,g)=>["ata_smart_attributes","ata_smart_selective_self_test_log","ata_smart_data"].includes(g));return{info:o,smart:{attributes:t.ata_smart_attributes,data:t.ata_smart_data},device:o.device.name,identifier:o.serial_number}}updateData(){this.loading=!0,null!==this.osdId?this.osdService.getSmartData(this.osdId).subscribe({next:this.fetchData.bind(this),error:t=>{t.preventDefault(),this.error=t,this.loading=!1}}):null!==this.hostname&&this.hostService.getSmartData(this.hostname).subscribe({next:this.fetchData.bind(this),error:t=>{t.preventDefault(),this.error=t,this.loading=!1}})}ngOnInit(){this.smartDataColumns=[{prop:"id",name:"ID"},{prop:"name",name:"Name"},{prop:"raw.value",name:"Raw"},{prop:"thresh",name:"Threshold"},{prop:"value",name:"Value"},{prop:"when_failed",name:"When Failed"},{prop:"worst",name:"Worst"}],this.scsiSmartDataColumns=[{prop:"correction_algorithm_invocations",name:"Correction Algorithm Invocations"},{prop:"errors_corrected_by_eccdelayed",name:"Errors Corrected by ECC (Delayed)"},{prop:"errors_corrected_by_eccfast",name:"Errors Corrected by ECC (Fast)"},{prop:"errors_corrected_by_rereads_rewrites",name:"Errors Corrected by Rereads/Rewrites"},{prop:"gigabytes_processed",name:"Gigabyes Processed"},{prop:"total_errors_corrected",name:"Total Errors Corrected"},{prop:"total_uncorrected_errors",name:"Total Errors Uncorrected"}]}ngOnChanges(t){this.data={},t.osdId?this.osdId=t.osdId.currentValue:t.hostname&&(this.hostname=t.hostname.currentValue),this.updateData()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Ji),e.Y36(Xl))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-smart-list"]],viewQuery:function(t,o){if(1&t&&e.Gf(nh,5),2&t){let c;e.iGM(c=e.CRH())&&(o.nav=c.first)}},inputs:{osdId:"osdId",hostname:"hostname"},features:[e.TTD],decls:3,vars:2,consts:function(){let s,t,o,c,g,C,D,P,j,W,re,oe,me,_e;return s="Failed to retrieve SMART data.",t="The data received has the JSON format version 2.x and is currently incompatible with the dashboard.",o="No SMART data available.",c="SMART overall-health self-assessment test result",g="unknown",C="SMART overall-health self-assessment test result",D="passed",P="SMART overall-health self-assessment test result",j="failed",W="Device Information",re="SMART",oe="No device information available for this device.",me="No SMART data available for this device.",_e="SMART data is loading.",[[4,"ngIf","ngIfElse"],["isLoading",""],["type","error",4,"ngIf"],["type","warning",4,"ngIf"],[4,"ngIf"],["type","error"],s,["type","warning"],t,["type","info",4,"ngIf"],["type","info"],o,["ngbNav","",1,"nav-tabs"],["nav","ngbNav"],["ngbNavItem","",4,"ngFor","ngForOf"],[3,"ngbNavOutlet"],["ngbNavItem",""],["ngbNavLink",""],["ngbNavContent",""],["noError",""],["id","alert-error","type","warning"],["id","alert-self-test-unknown","size","slim","type","warning","title",c,4,"ngIf","ngIfElse"],["hasSmartStatus",""],["id","alert-self-test-unknown","size","slim","type","warning","title",c],g,["selfTestFailed",""],["id","alert-self-test-passed","size","slim","type","info","title",C],D,["id","alert-self-test-failed","size","slim","type","warning","title",P],j,["innerNav","ngbNav"],[3,"ngbNavItem"],W,re,[3,"renderObjects","data",4,"ngIf"],["id","alert-device-info-unavailable","type","info",4,"ngIf"],[3,"renderObjects","data"],["id","alert-device-info-unavailable","type","info"],oe,["updateSelectionOnRefresh","never",3,"data","columns",4,"ngIf"],["updateSelectionOnRefresh","never",3,"renderObjects","data",4,"ngIf"],["id","alert-device-smart-data-unavailable","type","info",4,"ngIf"],["updateSelectionOnRefresh","never",3,"data","columns"],["updateSelectionOnRefresh","never",3,"renderObjects","data"],["id","alert-device-smart-data-unavailable","type","info"],me,_e]},template:function(t,o){if(1&t&&(e.YNc(0,ke,4,3,"ng-container",0),e.YNc(1,ct,2,0,"ng-template",null,1,e.W1O)),2&t){const c=e.MAs(2);e.Q6J("ngIf",!o.loading)("ngIfElse",c)}},directives:[_.O5,gt.G,ut.Pz,_.sg,ut.tO,ut.nv,ut.Vx,ut.uN,zr.b,ks.a,th.b],pipes:[cr.i,_.Nd],styles:[""]}),n})();function Ir(n,s){if(1&n&&e._UZ(0,"cd-device-list",14),2&n){const t=e.oxw(2);e.Q6J("hostname",t.selection.hostname)}}function vi(n,s){if(1&n&&e._UZ(0,"cd-inventory",14),2&n){const t=e.oxw(3);e.Q6J("hostname",t.selectedHostname)}}function zi(n,s){1&n&&(e.TgZ(0,"li",15),e.TgZ(1,"a",5),e.SDv(2,16),e.qZA(),e.YNc(3,vi,1,1,"ng-template",7),e.qZA())}const Do=function(){return["hostname"]};function xs(n,s){if(1&n&&e._UZ(0,"cd-service-daemon-list",19),2&n){const t=e.oxw(3);e.Q6J("hostname",t.selectedHostname)("hiddenColumns",e.DdM(2,Do))}}function Xo(n,s){1&n&&(e.TgZ(0,"li",17),e.TgZ(1,"a",5),e.SDv(2,18),e.qZA(),e.YNc(3,xs,1,3,"ng-template",7),e.qZA())}function Rs(n,s){if(1&n&&e._UZ(0,"cd-grafana",22),2&n){const t=e.oxw(3);e.Q6J("grafanaPath","host-details?var-ceph_hosts="+t.selectedHostname)}}function ma(n,s){1&n&&(e.TgZ(0,"li",20),e.TgZ(1,"a",5),e.SDv(2,21),e.qZA(),e.YNc(3,Rs,1,1,"ng-template",7),e.qZA())}function Vs(n,s){if(1&n&&e._UZ(0,"cd-smart-list",14),2&n){const t=e.oxw(3);e.Q6J("hostname",t.selectedHostname)}}function _c(n,s){if(1&n&&e.YNc(0,Vs,1,1,"cd-smart-list",23),2&n){const t=e.oxw(2),o=e.MAs(2);e.Q6J("ngIf",t.selectedHostname)("ngIfElse",o)}}function nd(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"ul",2,3),e.TgZ(3,"li",4),e.TgZ(4,"a",5),e.SDv(5,6),e.qZA(),e.YNc(6,Ir,1,1,"ng-template",7),e.qZA(),e.YNc(7,zi,4,0,"li",8),e.YNc(8,Xo,4,0,"li",9),e.YNc(9,ma,4,0,"li",10),e.TgZ(10,"li",11),e.TgZ(11,"a",5),e.SDv(12,12),e.qZA(),e.YNc(13,_c,1,2,"ng-template",7),e.qZA(),e.qZA(),e._UZ(14,"div",13),e.BQk()),2&n){const t=e.MAs(2),o=e.oxw();e.xp6(7),e.Q6J("ngIf",o.permissions.hosts.read),e.xp6(1),e.Q6J("ngIf",o.permissions.hosts.read),e.xp6(1),e.Q6J("ngIf",o.permissions.grafana.read),e.xp6(5),e.Q6J("ngbNavOutlet",t)}}function wu(n,s){1&n&&(e.TgZ(0,"cd-alert-panel",24),e.SDv(1,25),e.qZA())}let Hd=(()=>{class n{get selectedHostname(){return void 0!==this.selection?this.selection.hostname:null}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-host-details"]],inputs:{permissions:"permissions",selection:"selection"},decls:3,vars:1,consts:function(){let s,t,o,c,g,C;return s="Devices",t="Device health",o="Physical Disks",c="Daemons",g="Performance Details",C="No hostname found.",[[4,"ngIf"],["noHostname",""],["ngbNav","","cdStatefulTab","host-details",1,"nav-tabs"],["nav","ngbNav"],["ngbNavItem","devices"],["ngbNavLink",""],s,["ngbNavContent",""],["ngbNavItem","inventory",4,"ngIf"],["ngbNavItem","daemons",4,"ngIf"],["ngbNavItem","performance-details",4,"ngIf"],["ngbNavItem","device-health"],t,[3,"ngbNavOutlet"],[3,"hostname"],["ngbNavItem","inventory"],o,["ngbNavItem","daemons"],c,["flag","hostDetails",3,"hostname","hiddenColumns"],["ngbNavItem","performance-details"],g,["uid","rtOg0AiWz","grafanaStyle","four",3,"grafanaPath"],[3,"hostname",4,"ngIf","ngIfElse"],["type","error"],C]},template:function(t,o){1&t&&(e.YNc(0,nd,15,4,"ng-container",0),e.YNc(1,wu,2,0,"ng-template",null,1,e.W1O)),2&t&&e.Q6J("ngIf",o.selection)},directives:[_.O5,ut.Pz,un.m,ut.nv,ut.Vx,ut.uN,ut.tO,Pa,Q,Rh,ot.F,Jn,gt.G],styles:[""]}),n})();const $_=["servicesTpl"],sh=["maintenanceConfirmTpl"],ah=["orchTmpl"],_p=["flashTmpl"];function jf(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-table",13,14),e.NdJ("fetchData",function(c){return e.CHM(t),e.oxw().getHosts(c)})("setExpandedRow",function(c){return e.CHM(t),e.oxw().setExpandedRow(c)})("updateSelection",function(c){return e.CHM(t),e.oxw().updateSelection(c)}),e.TgZ(2,"div",15),e._UZ(3,"cd-table-actions",16),e.qZA(),e._UZ(4,"cd-host-details",17),e.qZA()}if(2&n){const t=e.oxw();e.Q6J("data",t.hosts)("columns",t.columns)("hasDetails",t.hasTableDetails)("toolHeader",!t.hideToolHeader),e.xp6(3),e.Q6J("permission",t.permissions.hosts)("selection",t.selection)("tableActions",t.tableActions),e.xp6(1),e.Q6J("permissions",t.permissions)("selection",t.expandedRow)}}function H_(n,s){1&n&&e._UZ(0,"cd-grafana",19),2&n&&e.Q6J("grafanaPath","host-overview?")}function fg(n,s){1&n&&(e.TgZ(0,"li",2),e.TgZ(1,"a",3),e.SDv(2,18),e.qZA(),e.YNc(3,H_,1,1,"ng-template",5),e.qZA())}function gp(n,s){1&n&&(e.ynx(0),e._uU(1,"\xa0"),e.BQk())}function Td(n,s){if(1&n&&(e.TgZ(0,"span"),e.TgZ(1,"span",21),e._uU(2),e.qZA(),e.YNc(3,gp,2,0,"ng-container",22),e.qZA()),2&n){const t=s.$implicit,o=s.last;e.xp6(2),e.Oqu(t),e.xp6(1),e.Q6J("ngIf",!o)}}function U_(n,s){1&n&&e.YNc(0,Td,4,2,"span",20),2&n&&e.Q6J("ngForOf",s.value)}function s_(n,s){if(1&n&&(e.TgZ(0,"ul"),e.TgZ(1,"li"),e.SDv(2,23),e.qZA(),e.qZA()),2&n){const t=e.oxw().$implicit;e.xp6(2),e.pQV(t),e.QtT(2)}}function B_(n,s){if(1&n&&(e.TgZ(0,"div"),e.YNc(1,s_,3,1,"ul",22),e.qZA()),2&n){const t=s.last,o=e.oxw(2);e.xp6(1),e.Q6J("ngIf",!t||"1"==o.errorMessage.length)}}function Wc(n,s){1&n&&(e.ynx(0),e.SDv(1,24),e.BQk())}function Fh(n,s){if(1&n&&(e.YNc(0,B_,2,1,"div",20),e.YNc(1,Wc,2,0,"ng-container",22)),2&n){const t=e.oxw();e.Q6J("ngForOf",t.errorMessage),e.xp6(1),e.Q6J("ngIf",t.showSubmit)}}function a_(n,s){1&n&&(e.TgZ(0,"span",25),e.SDv(1,26),e.qZA())}function ep(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,28),e.qZA())}let lh=(()=>{class n extends jl.o{constructor(t,o,c,g,C,D,P,j,W){super(),this.authStorageService=t,this.dimlessBinary=o,this.hostService=c,this.actionLabels=g,this.modalService=C,this.taskWrapper=D,this.router=P,this.notificationService=j,this.orchService=W,this.sub=new _u.w,this.hiddenColumns=[],this.hideTitle=!1,this.hideSubmitBtn=!1,this.hasTableDetails=!0,this.hideToolHeader=!1,this.showGeneralActionsOnly=!1,this.columns=[],this.hosts=[],this.isLoadingHosts=!1,this.cdParams={fromLink:"/hosts"},this.selection=new El.r,this.isExecuting=!1,this.icons=xo.P,this.messages={nonOrchHost:"The feature is disabled because the selected host is not managed by Orchestrator."},this.actionOrchFeatures={add:[cu.HOST_ADD],edit:[cu.HOST_LABEL_ADD,cu.HOST_LABEL_REMOVE],remove:[cu.HOST_REMOVE],maintenance:[cu.HOST_MAINTENANCE_ENTER,cu.HOST_MAINTENANCE_EXIT],drain:[cu.HOST_DRAIN]},this.permissions=this.authStorageService.getPermissions(),this.tableActions=[{name:this.actionLabels.ADD,permission:"create",icon:xo.P.add,click:()=>this.router.url.includes("/hosts")?this.router.navigate(["hosts",{outlets:{modal:[$i.MQ.ADD]}}]):this.bsModalRef=this.modalService.show(Xe),disable:re=>this.getDisable("add",re)},{name:this.actionLabels.EDIT,permission:"update",icon:xo.P.edit,click:()=>this.editAction(),disable:re=>this.getDisable("edit",re)},{name:this.actionLabels.START_DRAIN,permission:"update",icon:xo.P.exit,click:()=>this.hostDrain(),disable:re=>this.getDisable("drain",re)||!this.enableDrainBtn,visible:()=>!this.showGeneralActionsOnly&&this.enableDrainBtn},{name:this.actionLabels.STOP_DRAIN,permission:"update",icon:xo.P.exit,click:()=>this.hostDrain(!0),disable:re=>this.getDisable("drain",re)||this.enableDrainBtn,visible:()=>!this.showGeneralActionsOnly&&!this.enableDrainBtn},{name:this.actionLabels.REMOVE,permission:"delete",icon:xo.P.destroy,click:()=>this.deleteAction(),disable:re=>this.getDisable("remove",re)},{name:this.actionLabels.ENTER_MAINTENANCE,permission:"update",icon:xo.P.enter,click:()=>this.hostMaintenance(),disable:re=>this.getDisable("maintenance",re)||this.isExecuting||this.enableMaintenanceBtn,visible:()=>!this.showGeneralActionsOnly&&!this.enableMaintenanceBtn},{name:this.actionLabels.EXIT_MAINTENANCE,permission:"update",icon:xo.P.exit,click:()=>this.hostMaintenance(),disable:re=>this.getDisable("maintenance",re)||this.isExecuting||!this.enableMaintenanceBtn,visible:()=>!this.showGeneralActionsOnly&&this.enableMaintenanceBtn}]}ngOnInit(){this.columns=[{name:"Hostname",prop:"hostname",flexGrow:1},{name:"Service Instances",prop:"service_instances",flexGrow:1,cellTemplate:this.servicesTpl},{name:"Labels",prop:"labels",flexGrow:1,cellTransformation:bl.e.badge,customTemplateConfig:{class:"badge-dark"}},{name:"Status",prop:"status",flexGrow:1,cellTransformation:bl.e.badge,customTemplateConfig:{map:{maintenance:{class:"badge-warning"}}}},{name:"Model",prop:"model",flexGrow:1},{name:"CPUs",prop:"cpu_count",flexGrow:.3},{name:"Cores",prop:"cpu_cores",flexGrow:.3},{name:"Total Memory",prop:"memory_total_bytes",pipe:this.dimlessBinary,flexGrow:.4},{name:"Raw Capacity",prop:"raw_capacity",pipe:this.dimlessBinary,flexGrow:.5},{name:"HDDs",prop:"hdd_count",flexGrow:.3},{name:"Flash",prop:"flash_count",headerTemplate:this.flashTmpl,flexGrow:.3},{name:"NICs",prop:"nic_count",flexGrow:.3}],this.columns=this.columns.filter(t=>!this.hiddenColumns.includes(t.prop))}ngOnDestroy(){this.sub.unsubscribe()}updateSelection(t){this.selection=t,this.enableMaintenanceBtn=!1,this.enableDrainBtn=!1,this.selection.hasSelection&&("maintenance"===this.selection.first().status&&(this.enableMaintenanceBtn=!0),this.selection.first().labels.includes("_no_schedule")||(this.enableDrainBtn=!0))}editAction(){this.hostService.getLabels().subscribe(t=>{const o=this.selection.first(),c=new Set(t.concat(this.hostService.predefinedLabels)),g=Array.from(c).map(C=>({enabled:!0,name:C}));this.modalService.show(zd.X,{titleText:"Edit Host: " + o.hostname + "",fields:[{type:"select-badges",name:"labels",value:o.labels,label:"Labels",typeConfig:{customBadges:!0,options:g,messages:new Hc.a({empty:"There are no labels.",filter:"Filter or add labels",add:"Add label"})}}],submitButtonText:"Edit Host",onSubmit:C=>{this.hostService.update(o.hostname,!0,C.labels).subscribe(()=>{this.notificationService.show(pa.k.success,"Updated Host \"" + o.hostname + "\""),this.table.refreshBtn()})}})})}hostMaintenance(){this.isExecuting=!0;const t=this.selection.first();"maintenance"!==t.status?this.hostService.update(t.hostname,!1,[],!0).subscribe(()=>{this.isExecuting=!1,this.notificationService.show(pa.k.success,"\"" + t.hostname + "\" moved to maintenance"),this.table.refreshBtn()},o=>{if(this.isExecuting=!1,this.errorMessage=o.error.detail.split(/\n/),o.preventDefault(),!o.error.detail.includes("WARNING")||o.error.detail.includes("It is NOT safe to stop")||o.error.detail.includes("ALERT")||o.error.detail.includes("unsafe to stop"))this.notificationService.show(pa.k.error,"\"" + t.hostname + "\" cannot be put into maintenance","" + o.error.detail + "");else{const c={titleText:"Warning",buttonText:"Continue",warning:!0,bodyTpl:this.maintenanceConfirmTpl,showSubmit:!0,onSubmit:()=>{this.hostService.update(t.hostname,!1,[],!0,!0).subscribe(()=>{this.modalRef.close()},()=>this.modalRef.close())}};this.modalRef=this.modalService.show(td.Y,c)}}):this.hostService.update(t.hostname,!1,[],!0).subscribe(()=>{this.isExecuting=!1,this.notificationService.show(pa.k.success,"\"" + t.hostname + "\" has exited maintenance"),this.table.refreshBtn()})}hostDrain(t=!1){const o=this.selection.first();if(t){const c=o.labels.indexOf("_no_schedule",0);o.labels.splice(c,1),this.hostService.update(o.hostname,!0,o.labels).subscribe(()=>{this.notificationService.show(pa.k.info,"\"" + o.hostname + "\" stopped draining"),this.table.refreshBtn()})}else this.hostService.update(o.hostname,!1,[],!1,!1,!0).subscribe(()=>{this.notificationService.show(pa.k.info,"\"" + o.hostname + "\" started draining"),this.table.refreshBtn()})}getDisable(t,o){if("remove"===t||"edit"===t||"maintenance"===t||"drain"===t){if(!(null==o?void 0:o.hasSingleSelection))return!0;if(!wr().every(o.selected,"sources.orchestrator"))return this.messages.nonOrchHost}return this.orchService.getTableActionDisableDesc(this.orchStatus,this.actionOrchFeatures[t])}deleteAction(){const t=this.selection.first().hostname;this.modalRef=this.modalService.show(Gl.M,{itemDescription:"Host",itemNames:[t],actionDescription:"remove",submitActionObservable:()=>this.taskWrapper.wrapTaskAroundCall({task:new cl.R("host/remove",{hostname:t}),call:this.hostService.delete(t)})})}checkHostsFactsAvailable(){const t=this.orchStatus.features;return!wr().isEmpty(t)&&!!t.get_facts.available}transformHostsData(){if(this.checkHostsFactsAvailable())wr().forEach(this.hosts,t=>{t.memory_total_bytes=1024*t.memory_total_kb,t.raw_capacity=t.hdd_capacity_bytes+t.flash_capacity_bytes});else for(let t=4;t<this.columns.length;t++)this.columns[t].cellTemplate=this.orchTmpl}getHosts(t){this.isLoadingHosts||(this.isLoadingHosts=!0,this.sub=this.orchService.status().pipe((0,Bu.zg)(o=>{this.orchStatus=o;const c=this.checkHostsFactsAvailable();return this.hostService.list(`${c}`)}),(0,hu.U)(o=>o.map(c=>{var g;const C={};if(c.service_instances=new Set,null===(g=this.orchStatus)||void 0===g?void 0:g.available){let P,D=[];P=this.hostService.getDaemons(c.hostname),P.subscribe(j=>{D=j,D.forEach(W=>{C[W.daemon_type]=(C[W.daemon_type]||0)+1}),D.map(W=>{c.service_instances.add(`${W.daemon_type}: ${C[W.daemon_type]}`)})})}else c.services.forEach(D=>{C[D.type]=(C[D.type]||0)+1}),c.services.map(D=>{c.service_instances.add(`${D.type}: ${C[D.type]}`)});return c}))).subscribe(o=>{this.hosts=o,this.transformHostsData(),this.isLoadingHosts=!1},()=>{this.isLoadingHosts=!1,t.error()}))}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(vt.j),e.Y36(mn.$),e.Y36(Xl),e.Y36($i.p4),e.Y36(Bl.Z),e.Y36(Ll.P),e.Y36(Bo.F0),e.Y36(hl.g),e.Y36(Mc))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-hosts"]],viewQuery:function(t,o){if(1&t&&(e.Gf(ks.a,5),e.Gf($_,7),e.Gf(sh,7),e.Gf(ah,7),e.Gf(_p,7)),2&t){let c;e.iGM(c=e.CRH())&&(o.table=c.first),e.iGM(c=e.CRH())&&(o.servicesTpl=c.first),e.iGM(c=e.CRH())&&(o.maintenanceConfirmTpl=c.first),e.iGM(c=e.CRH())&&(o.orchTmpl=c.first),e.iGM(c=e.CRH())&&(o.flashTmpl=c.first)}},inputs:{hiddenColumns:"hiddenColumns",hideTitle:"hideTitle",hideSubmitBtn:"hideSubmitBtn",hasTableDetails:"hasTableDetails",hideToolHeader:"hideToolHeader",showGeneralActionsOnly:"showGeneralActionsOnly"},features:[e._Bn([{provide:Lu.F,useValue:new Lu.F("hosts")}]),e.qOj],decls:17,vars:2,consts:function(){let s,t,o,c,g,C,D,P;return s="Hosts List",t="Overall Performance",o="" + "\ufffd0\ufffd" + "",c="Are you sure you want to continue?",g="Data will be available only if Orchestrator is available.",C="N/A",D="SSD, NVMEs",P="Flash",[["ngbNav","",1,"nav-tabs"],["nav","ngbNav"],["ngbNavItem",""],["ngbNavLink",""],s,["ngbNavContent",""],["ngbNavItem","",4,"ngIf"],[3,"ngbNavOutlet"],["servicesTpl",""],["maintenanceConfirmTpl",""],["orchTmpl",""],["flashTmpl",""],["name","modal"],["columnMode","flex","selectionType","single",3,"data","columns","hasDetails","toolHeader","fetchData","setExpandedRow","updateSelection"],["table",""],[1,"table-actions","btn-toolbar"],["id","host-actions",1,"btn-group",3,"permission","selection","tableActions"],["cdTableDetail","",3,"permissions","selection"],t,["uid","y0KGL0iZz","grafanaStyle","two",3,"grafanaPath"],[4,"ngFor","ngForOf"],[1,"badge","badge-background-primary"],[4,"ngIf"],o,c,["ngbTooltip",g],C,["ngbTooltip",D],P]},template:function(t,o){if(1&t&&(e.TgZ(0,"ul",0,1),e.TgZ(2,"li",2),e.TgZ(3,"a",3),e.SDv(4,4),e.qZA(),e.YNc(5,jf,5,9,"ng-template",5),e.qZA(),e.YNc(6,fg,4,0,"li",6),e.qZA(),e._UZ(7,"div",7),e.YNc(8,U_,1,1,"ng-template",null,8,e.W1O),e.YNc(10,Fh,2,2,"ng-template",null,9,e.W1O),e.YNc(12,a_,2,0,"ng-template",null,10,e.W1O),e.YNc(14,ep,2,0,"ng-template",null,11,e.W1O),e._UZ(16,"router-outlet",12)),2&t){const c=e.MAs(1);e.xp6(6),e.Q6J("ngIf",o.permissions.grafana.read),e.xp6(1),e.Q6J("ngbNavOutlet",c)}},directives:[ut.Pz,ut.nv,ut.Vx,ut.uN,_.O5,ut.tO,Bo.lC,ks.a,Js.K,Hd,ot.F,_.sg,ut._L],styles:[""]}),n})();var u_=(()=>{return(n=u_||(u_={})).COST_CAPACITY="cost_capacity",n.THROUGHPUT="throughput_optimized",n.IOPS="iops_optimized",u_;var n})(),rd=i(62862);let kg=(()=>{class n{constructor(t,o,c,g,C){this.activeModal=t,this.actionLabels=o,this.formBuilder=c,this.osdService=g,this.taskWrapper=C,this.driveGroups=[],this.submitAction=new e.vpe,this.action=o.CREATE,this.createForm()}createForm(){this.formGroup=this.formBuilder.group({})}onSubmit(){const t=wr().join(wr().map(this.driveGroups,"service_id"),", ");this.taskWrapper.wrapTaskAroundCall({task:new cl.R("osd/"+$i.MQ.CREATE,{tracking_id:t}),call:this.osdService.create(this.driveGroups,t)}).subscribe({error:()=>{this.formGroup.setErrors({cdSubmitButton:!0})},complete:()=>{this.submitAction.emit(),this.activeModal.close()}})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(ut.Kz),e.Y36($i.p4),e.Y36(rd.O),e.Y36(Ji),e.Y36(Ll.P))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-osd-creation-preview-modal"]],inputs:{driveGroups:"driveGroups"},outputs:{submitAction:"submitAction"},decls:15,vars:9,consts:function(){let s,t;return s="OSD creation preview",t="DriveGroups",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["novalidate","",3,"formGroup"],["frm","ngForm"],[1,"modal-body"],t,[1,"modal-footer"],[3,"form","submitText","submitActionEvent"]]},template:function(t,o){1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.BQk(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.TgZ(7,"h4"),e.SDv(8,7),e.qZA(),e.TgZ(9,"pre"),e._uU(10),e.ALo(11,"json"),e.qZA(),e.qZA(),e.TgZ(12,"div",8),e.TgZ(13,"cd-form-button-panel",9),e.NdJ("submitActionEvent",function(){return o.onSubmit()}),e.ALo(14,"titlecase"),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t&&(e.Q6J("modalRef",o.activeModal),e.xp6(4),e.Q6J("formGroup",o.formGroup),e.xp6(6),e.Oqu(e.lcZ(11,5,o.driveGroups)),e.xp6(3),e.Q6J("form",o.formGroup)("submitText",e.lcZ(14,7,o.action)))},directives:[bu.z,Mn._Y,Mn.JL,ll.V,Mn.sg,ul.p],pipes:[_.Ts,_.rS],styles:[""]}),n})();const $g=["inventoryDevices"];function mp(n,s){if(1&n&&(e.TgZ(0,"span",16),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.xp6(1),e.hij(" ",t," ")}}function c_(n,s){if(1&n&&(e.TgZ(0,"cd-alert-panel",13),e.ynx(1),e.SDv(2,14),e.BQk(),e.YNc(3,mp,2,1,"span",15),e.qZA()),2&n){const t=e.oxw();e.Q6J("showTitle",!1),e.xp6(3),e.Q6J("ngForOf",t.requiredFilters)}}function d_(n,s){if(1&n&&(e.TgZ(0,"div"),e.TgZ(1,"p",17),e.TgZ(2,"span"),e.SDv(3,18),e.ALo(4,"dimlessBinary"),e.qZA(),e.qZA(),e.qZA()),2&n){const t=e.oxw();e.xp6(4),e.pQV(t.filteredDevices.length)(e.lcZ(4,2,t.capacity)),e.QtT(3)}}const Ea=function(){return["available","osd_ids"]};let Uc=(()=>{class n{constructor(t,o,c,g){this.formBuilder=t,this.activeModal=o,this.actionLabels=c,this.wizardStepService=g,this.submitAction=new e.vpe,this.icons=xo.P,this.filterColumns=[],this.devices=[],this.filteredDevices=[],this.capacity=0,this.canSubmit=!1,this.requiredFilters=[],this.action=c.ADD,this.createForm()}ngAfterViewInit(){const t=wr().filter(this.inventoryDevices.columns,o=>this.filterColumns.includes(o.prop)&&"hostname"!==o.prop);setTimeout(()=>{this.requiredFilters=wr().map(t,"name")},0)}createForm(){this.formGroup=this.formBuilder.group({})}onFilterChange(t){if(this.capacity=0,this.canSubmit=!1,wr().isEmpty(t.filters))this.filteredDevices=[],this.event=void 0;else{const o=t.filters.filter(c=>"hostname"!==c.prop);this.canSubmit=!wr().isEmpty(o),this.filteredDevices=t.data,this.capacity=wr().sumBy(this.filteredDevices,"sys_api.size"),this.event=t}}onSubmit(){this.submitAction.emit(this.event),this.activeModal.close()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(rd.O),e.Y36(ut.Kz),e.Y36($i.p4),e.Y36(Yu))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-osd-devices-selection-modal"]],viewQuery:function(t,o){if(1&t&&e.Gf($g,5),2&t){let c;e.iGM(c=e.CRH())&&(o.inventoryDevices=c.first)}},outputs:{submitAction:"submitAction"},decls:14,vars:15,consts:function(){let s,t,o;return s="" + "\ufffd0\ufffd" + " devices",t="At least one of these filters must be applied in order to proceed:",o="Number of devices: " + "\ufffd0\ufffd" + ". Raw capacity: " + "\ufffd1\ufffd" + ".",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["novalidate","",3,"formGroup"],["frm","ngForm"],[1,"modal-body"],["type","warning","size","slim",3,"showTitle",4,"ngIf"],[3,"devices","filterColumns","showAvailDeviceOnly","hiddenColumns","filterChange"],["inventoryDevices",""],[4,"ngIf"],[1,"modal-footer"],[3,"form","disabled","submitText","submitActionEvent"],["type","warning","size","slim",3,"showTitle"],t,["class","badge badge-dark ml-2",4,"ngFor","ngForOf"],[1,"badge","badge-dark","ml-2"],[1,"text-center"],o]},template:function(t,o){1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.BQk(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.YNc(7,c_,4,2,"cd-alert-panel",7),e.TgZ(8,"cd-inventory-devices",8,9),e.NdJ("filterChange",function(g){return o.onFilterChange(g)}),e.qZA(),e.YNc(10,d_,5,4,"div",10),e.qZA(),e.TgZ(11,"div",11),e.TgZ(12,"cd-form-button-panel",12),e.NdJ("submitActionEvent",function(){return o.onSubmit()}),e.ALo(13,"titlecase"),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t&&(e.Q6J("modalRef",o.activeModal),e.xp6(2),e.pQV(o.deviceType),e.QtT(2),e.xp6(2),e.Q6J("formGroup",o.formGroup),e.xp6(3),e.Q6J("ngIf",!o.canSubmit),e.xp6(1),e.Q6J("devices",o.devices)("filterColumns",o.filterColumns)("showAvailDeviceOnly",!0)("hiddenColumns",e.DdM(14,Ea)),e.xp6(2),e.Q6J("ngIf",o.canSubmit),e.xp6(2),e.Q6J("form",o.formGroup)("disabled",!o.canSubmit||0===o.filteredDevices.length)("submitText",e.lcZ(13,12,o.action)))},directives:[bu.z,Mn._Y,Mn.JL,ll.V,Mn.sg,_.O5,gu,ul.p,gt.G,_.sg],pipes:[_.rS,mn.$],styles:[""]}),n})();function Xu(n,s){1&n&&(e.TgZ(0,"span"),e.SDv(1,7),e.qZA())}function Ds(n,s){1&n&&(e.TgZ(0,"span"),e.SDv(1,8),e.qZA())}function vp(n,s){1&n&&(e.TgZ(0,"span"),e.SDv(1,9),e.qZA())}const uh=function(n){return[n]};function Zu(n,s){if(1&n){const t=e.EpF();e.ynx(0),e.TgZ(1,"button",10),e.NdJ("click",function(){return e.CHM(t),e.oxw().showSelectionModal()}),e._UZ(2,"i",11),e.ynx(3),e.SDv(4,12),e.BQk(),e.qZA(),e.BQk()}if(2&n){const t=e.oxw();e.xp6(1),e.Q6J("title",t.addButtonTooltip)("disabled",0===t.availDevices.length||!t.canSelect||t.expansionCanSelect),e.xp6(1),e.Q6J("ngClass",e.VKq(3,uh,t.icons.add))}}function Y_(n,s){if(1&n&&(e.TgZ(0,"span"),e.TgZ(1,"span",19),e._uU(2),e.qZA(),e.qZA()),2&n){const t=s.$implicit;e.xp6(2),e.AsE("",t.name,": ",t.value.formatted,"")}}function Yp(n,s){if(1&n&&(e.TgZ(0,"div",20),e.TgZ(1,"span"),e.SDv(2,21),e.ALo(3,"dimlessBinary"),e.qZA(),e.qZA()),2&n){const t=e.oxw(2);e.xp6(3),e.pQV(e.lcZ(3,1,t.capacity)),e.QtT(2)}}const Gf=function(){return["available","osd_ids"]},Pc=function(){return[]};function pg(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",13),e.YNc(1,Y_,3,2,"span",14),e.TgZ(2,"a",15),e.NdJ("click",function(){return e.CHM(t),e.oxw().clearDevices(),!1}),e._UZ(3,"i",11),e.ynx(4),e.SDv(5,16),e.BQk(),e.qZA(),e.qZA(),e.TgZ(6,"div"),e._UZ(7,"cd-inventory-devices",17),e.qZA(),e.YNc(8,Yp,4,3,"div",18)}if(2&n){const t=e.oxw();e.xp6(1),e.Q6J("ngForOf",t.appliedFilters),e.xp6(2),e.Q6J("ngClass",e.VKq(6,uh,t.icons.clearFilters)),e.xp6(4),e.Q6J("devices",t.devices)("hiddenColumns",e.DdM(8,Gf))("filterColumns",e.DdM(9,Pc)),e.xp6(1),e.Q6J("ngIf","data"===t.type)}}let Z_=(()=>{class n{constructor(t,o,c){this.modalService=t,this.osdService=o,this.router=c,this.selected=new e.vpe,this.cleared=new e.vpe,this.icons=xo.P,this.devices=[],this.capacity=0,this.appliedFilters=new Array,this.expansionCanSelect=!1,this.tooltips={noAvailDevices:"No available devices",addPrimaryFirst:"Please add primary devices first",addByFilters:"Add devices by using filters"},this.isOsdPage=this.router.url.includes("/osd")}ngOnInit(){var t,o,c;this.isOsdPage||(this.devices=(null===(t=this.osdService)||void 0===t?void 0:t.osdDevices[this.type])?this.osdService.osdDevices[this.type]:[],this.capacity=wr().sumBy(this.devices,"sys_api.size"),this.expansionCanSelect=!!(null===(o=this.osdService)||void 0===o?void 0:o.osdDevices)&&(null===(c=this.osdService)||void 0===c?void 0:c.osdDevices.disableSelect)),this.updateAddButtonTooltip()}ngOnChanges(){this.updateAddButtonTooltip()}showSelectionModal(){let t=["human_readable_type","sys_api.vendor","sys_api.model","sys_api.size"];"data"===this.type&&(t=["hostname",...t]),this.modalService.show(Uc,{hostname:this.hostname,deviceType:this.name,devices:this.availDevices,filterColumns:t},{size:"xl"}).componentInstance.submitAction.subscribe(g=>{this.devices=g.data,this.capacity=wr().sumBy(this.devices,"sys_api.size"),this.appliedFilters=g.filters;const C=wr().assign({type:this.type},g);this.isOsdPage||(this.osdService.osdDevices[this.type]=this.devices,this.osdService.osdDevices.disableSelect=this.canSelect||this.devices.length===this.availDevices.length,this.osdService.osdDevices[this.type].capacity=this.capacity),this.selected.emit(C)})}updateAddButtonTooltip(){this.addButtonTooltip="data"===this.type&&0===this.availDevices.length?this.tooltips.noAvailDevices:this.canSelect?0===this.availDevices.length?this.tooltips.noAvailDevices:this.tooltips.addByFilters:this.tooltips.addPrimaryFirst}clearDevices(){this.isOsdPage||(this.expansionCanSelect=!1,this.osdService.osdDevices.disableSelect=!1,this.osdService.osdDevices=[]);const t={type:this.type,clearedDevices:[...this.devices]};this.devices=[],this.cleared.emit(t)}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Bl.Z),e.Y36(Ji),e.Y36(Bo.F0))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-osd-devices-selection-groups"]],inputs:{type:"type",name:"name",hostname:"hostname",availDevices:"availDevices",canSelect:"canSelect"},outputs:{selected:"selected",cleared:"cleared"},features:[e.TTD],decls:12,vars:6,consts:function(){let s,t,o,c,g,C,D;return s="" + "\ufffd0\ufffd" + " devices",t="The primary storage devices. These devices contain all OSD data.",o="Write-Ahead-Log devices. These devices are used for BlueStore\u2019s internal journal. It is only useful to use a WAL device if the device is faster than the primary device (e.g. NVME devices or SSDs). If there is only a small amount of fast storage available (e.g., less than a gigabyte), we recommend using it as a WAL device.",c="DB devices can be used for storing BlueStore\u2019s internal metadata. It is only helpful to provision a DB device if it is faster than the primary device (e.g. NVME devices or SSD).",g="Add",C="Clear",D="Raw capacity: " + "\ufffd0\ufffd" + "",[[1,"form-group","row"],["for","createDeleteButton",1,"cd-col-form-label"],s,[4,"ngIf"],[1,"cd-col-form-input"],[4,"ngIf","ngIfElse"],["blockClearDevices",""],t,o,c,["type","button","data-toggle","tooltip",1,"btn","btn-light",3,"title","disabled","click"],[3,"ngClass"],g,[1,"pb-2","my-2","border-bottom"],[4,"ngFor","ngForOf"],["href","",1,"tc_clearSelections",3,"click"],C,[3,"devices","hiddenColumns","filterColumns"],["class","float-right",4,"ngIf"],[1,"badge","badge-dark","mr-2"],[1,"float-right"],D]},template:function(t,o){if(1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"label",1),e.ynx(2),e.SDv(3,2),e.BQk(),e.TgZ(4,"cd-helper"),e.YNc(5,Xu,2,0,"span",3),e.YNc(6,Ds,2,0,"span",3),e.YNc(7,vp,2,0,"span",3),e.qZA(),e.qZA(),e.TgZ(8,"div",4),e.YNc(9,Zu,5,5,"ng-container",5),e.YNc(10,pg,9,10,"ng-template",null,6,e.W1O),e.qZA(),e.qZA()),2&t){const c=e.MAs(11);e.xp6(3),e.pQV(o.name),e.QtT(3),e.xp6(2),e.Q6J("ngIf","data"===o.type),e.xp6(1),e.Q6J("ngIf","wal"===o.type),e.xp6(1),e.Q6J("ngIf","db"===o.type),e.xp6(2),e.Q6J("ngIf",0===o.devices.length)("ngIfElse",c)}},directives:[Za.P,h.S,_.O5,la.o,_.mk,_.sg,gu],pipes:[mn.$],styles:[".tc_clearSelections[_ngcontent-%COMP%]{text-decoration:none}"]}),n})();const j_=["dataDeviceSelectionGroups"],kh=["walDeviceSelectionGroups"],tp=["dbDeviceSelectionGroups"],Ko=["previewButtonPanel"];function f_(n,s){1&n&&e._UZ(0,"cd-orchestrator-doc-panel")}function G_(n,s){if(1&n&&(e.TgZ(0,"div",8),e.SDv(1,32),e.ALo(2,"titlecase"),e.ALo(3,"upperFirst"),e.qZA()),2&n){const t=e.oxw(2);e.xp6(3),e.pQV(e.lcZ(2,2,t.action))(e.lcZ(3,4,t.resource)),e.QtT(1)}}function id(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",33),e.TgZ(1,"div",34),e.TgZ(2,"input",35),e.NdJ("change",function(){return e.CHM(t),e.oxw(2).emitDeploymentSelection()}),e.qZA(),e.TgZ(3,"label",36),e.tHW(4,37),e.TgZ(5,"cd-helper"),e._UZ(6,"span"),e.qZA(),e.N_p(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=s.$implicit,o=e.oxw(2);e.xp6(2),e.Q6J("id",t)("value",t),e.uIk("disabled",null==o.deploymentOptions||!o.deploymentOptions.options[t].available||null),e.xp6(1),e.Q6J("id","label_"+t)("for",t),e.xp6(3),e.pQV(null==o.deploymentOptions?null:o.deploymentOptions.options[t].title)(o.deploymentOptions.recommended_option===t?"(Recommended)":"")(null==o.deploymentOptions?null:o.deploymentOptions.options[t].desc),e.QtT(4)}}function gc(n,s){1&n&&(e.TgZ(0,"span",46),e.SDv(1,47),e.qZA())}function $h(n,s){if(1&n&&(e.TgZ(0,"div",38),e.TgZ(1,"label",39),e.ynx(2),e.SDv(3,40),e.BQk(),e.TgZ(4,"cd-helper"),e.TgZ(5,"span"),e.SDv(6,41),e.qZA(),e._UZ(7,"br"),e.TgZ(8,"span"),e.SDv(9,42),e.qZA(),e.qZA(),e.qZA(),e.TgZ(10,"div",43),e._UZ(11,"input",44),e.YNc(12,gc,2,0,"span",45),e.qZA(),e.qZA()),2&n){e.oxw();const t=e.MAs(4),o=e.oxw();e.xp6(12),e.Q6J("ngIf",o.form.showError("walSlots",t,"min"))}}function Hh(n,s){1&n&&(e.TgZ(0,"span",46),e.SDv(1,53),e.qZA())}function Uh(n,s){if(1&n&&(e.TgZ(0,"div",38),e.TgZ(1,"label",48),e.ynx(2),e.SDv(3,49),e.BQk(),e.TgZ(4,"cd-helper"),e.TgZ(5,"span"),e.SDv(6,50),e.qZA(),e._UZ(7,"br"),e.TgZ(8,"span"),e.SDv(9,51),e.qZA(),e.qZA(),e.qZA(),e.TgZ(10,"div",43),e._UZ(11,"input",52),e.YNc(12,Hh,2,0,"span",45),e.qZA(),e.qZA()),2&n){e.oxw();const t=e.MAs(4),o=e.oxw();e.xp6(12),e.Q6J("ngIf",o.form.showError("dbSlots",t,"min"))}}function hg(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",54),e.TgZ(1,"input",55),e.NdJ("change",function(){return e.CHM(t),e.oxw(2).emitDeploymentSelection()}),e.qZA(),e.TgZ(2,"label",56),e._uU(3),e.qZA(),e.qZA()}if(2&n){const t=s.$implicit;e.xp6(1),e.s9C("id",t.key),e.s9C("name",t.key),e.s9C("formControlName",t.key),e.xp6(1),e.s9C("for",t.key),e.xp6(1),e.Oqu(t.desc)}}function Vf(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",57),e.TgZ(1,"cd-form-button-panel",58,59),e.NdJ("submitActionEvent",function(){return e.CHM(t),e.oxw(2).submit()}),e.qZA(),e.qZA()}if(2&n){e.oxw();const t=e.MAs(24),o=e.oxw();e.xp6(1),e.Q6J("form",o.form)("disabled",0===t.devices.length&&!o.simpleDeployment)("submitText",o.simpleDeployment?"Create OSDs":o.actionLabels.PREVIEW)}}const Ud=function(n){return{show:n}};function yf(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",2),e.YNc(1,G_,4,6,"div",3),e.TgZ(2,"div",4),e.TgZ(3,"form",5,6),e.TgZ(5,"div",7),e.TgZ(6,"div",2),e.TgZ(7,"div",8),e.TgZ(8,"h2",9),e.TgZ(9,"button",10),e.NdJ("click",function(){return e.CHM(t),e.oxw().emitDeploymentMode()}),e.SDv(10,11),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(11,"div",12),e.TgZ(12,"div",13),e.YNc(13,id,7,8,"div",14),e.qZA(),e.qZA(),e.TgZ(14,"div",2),e.TgZ(15,"div",8),e.TgZ(16,"h2",9),e.TgZ(17,"button",15),e.NdJ("click",function(){return e.CHM(t),e.oxw().emitDeploymentMode()}),e.SDv(18,16),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(19,"div",12),e.TgZ(20,"div",17),e.TgZ(21,"div",17),e.TgZ(22,"fieldset"),e.TgZ(23,"cd-osd-devices-selection-groups",18,19),e.NdJ("selected",function(c){return e.CHM(t),e.oxw().onDevicesSelected(c)})("cleared",function(c){return e.CHM(t),e.oxw().onDevicesCleared(c)}),e.qZA(),e.qZA(),e.TgZ(25,"fieldset"),e.TgZ(26,"legend"),e.SDv(27,20),e.qZA(),e.TgZ(28,"cd-osd-devices-selection-groups",21,22),e.NdJ("selected",function(c){return e.CHM(t),e.oxw().onDevicesSelected(c)})("cleared",function(c){return e.CHM(t),e.oxw().onDevicesCleared(c)}),e.qZA(),e.YNc(30,$h,13,1,"div",23),e.TgZ(31,"cd-osd-devices-selection-groups",24,25),e.NdJ("selected",function(c){return e.CHM(t),e.oxw().onDevicesSelected(c)})("cleared",function(c){return e.CHM(t),e.oxw().onDevicesCleared(c)}),e.qZA(),e.YNc(33,Uh,13,1,"div",23),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(34,"div",2),e.TgZ(35,"div",8),e.TgZ(36,"h2",9),e.TgZ(37,"button",26),e.SDv(38,27),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(39,"div",28),e.TgZ(40,"div",13),e.TgZ(41,"div",29),e.YNc(42,hg,4,5,"div",30),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(43,Vf,3,3,"div",31),e.qZA()}if(2&n){const t=e.MAs(24),o=e.MAs(29),c=e.MAs(32),g=e.oxw();e.xp6(1),e.Q6J("ngIf",!g.hideTitle),e.xp6(2),e.Q6J("formGroup",g.form),e.xp6(6),e.uIk("aria-expanded",g.simpleDeployment),e.xp6(2),e.Q6J("ngClass",e.VKq(17,Ud,g.simpleDeployment)),e.xp6(2),e.Q6J("ngForOf",g.optionNames),e.xp6(4),e.uIk("aria-expanded",!g.simpleDeployment),e.xp6(2),e.Q6J("ngClass",e.VKq(19,Ud,!g.simpleDeployment)),e.xp6(4),e.Q6J("availDevices",g.availDevices)("canSelect",0!==g.availDevices.length),e.xp6(5),e.Q6J("availDevices",g.availDevices)("canSelect",0!==t.devices.length),e.xp6(2),e.Q6J("ngIf",0!==o.devices.length),e.xp6(1),e.Q6J("availDevices",g.availDevices)("canSelect",0!==t.devices.length),e.xp6(2),e.Q6J("ngIf",0!==c.devices.length),e.xp6(9),e.Q6J("ngForOf",g.featureList),e.xp6(1),e.Q6J("ngIf",!g.hideSubmitBtn)}}let p_=(()=>{class n extends Oa.E{constructor(t,o,c,g,C,D,P,j){super(),this.actionLabels=t,this.authStorageService=o,this.orchService=c,this.hostService=g,this.router=C,this.modalService=D,this.osdService=P,this.taskWrapper=j,this.hideTitle=!1,this.hideSubmitBtn=!1,this.emitDriveGroup=new e.vpe,this.emitDeploymentOption=new e.vpe,this.emitMode=new e.vpe,this.icons=xo.P,this.columns=[],this.allDevices=[],this.availDevices=[],this.dataDeviceFilters=[],this.dbDeviceFilters=[],this.walDeviceFilters=[],this.hostname="",this.driveGroup=new Kd,this.featureList=[],this.hasOrchestrator=!0,this.simpleDeployment=!0,this.optionNames=Object.values(u_),this.resource="OSDs",this.action=this.actionLabels.CREATE,this.features={encrypted:{key:"encrypted",desc:"Encryption"}},this.featureList=wr().map(this.features,(W,re)=>Object.assign(W,{key:re})),this.createForm()}ngOnInit(){this.orchService.status().subscribe(t=>{this.hasOrchestrator=t.available,t.available?this.getDataDevices():this.loadingNone()}),this.osdService.getDeploymentOptions().subscribe(t=>{var o,c;this.deploymentOptions=t,this.form.get("deploymentOption").setValue(null===(o=this.deploymentOptions)||void 0===o?void 0:o.recommended_option),(null===(c=this.deploymentOptions)||void 0===c?void 0:c.recommended_option)&&this.enableFeatures()}),this.form.get("walSlots").valueChanges.subscribe(t=>this.setSlots("wal",t)),this.form.get("dbSlots").valueChanges.subscribe(t=>this.setSlots("db",t)),wr().each(this.features,t=>{this.form.get("features").get(t.key).valueChanges.subscribe(o=>this.featureFormUpdate(t.key,o))})}createForm(){this.form=new Hs.d({walSlots:new Mn.NI(0),dbSlots:new Mn.NI(0),features:new Hs.d(this.featureList.reduce((t,o)=>(t[o.key]=new Mn.NI({value:!1,disabled:!0}),t),{})),deploymentOption:new Mn.NI(0)})}getDataDevices(){this.hostService.inventoryDeviceList().subscribe(t=>{this.allDevices=wr().filter(t,"available"),this.availDevices=[...this.allDevices],this.loadingReady()},()=>{this.allDevices=[],this.availDevices=[],this.loadingError()})}setSlots(t,o){"number"==typeof o&&o>=0&&this.driveGroup.setSlots(t,o)}featureFormUpdate(t,o){this.driveGroup.setFeature(t,o)}enableFeatures(){this.featureList.forEach(t=>{this.form.get(t.key).enable({emitEvent:!1})})}disableFeatures(){this.featureList.forEach(t=>{const o=this.form.get(t.key);o.disable({emitEvent:!1}),o.setValue(!1,{emitEvent:!1})})}onDevicesSelected(t){if(this.availDevices=t.dataOut,"data"===t.type){const o=wr().find(t.filters,{prop:"hostname"});o?(this.hostname=o.value.raw,this.availDevices=t.dataOut.filter(c=>c.hostname===this.hostname),this.driveGroup.setHostPattern(this.hostname)):this.driveGroup.setHostPattern("*"),this.enableFeatures()}this.driveGroup.setDeviceSelection(t.type,t.filters),this.emitDriveGroup.emit(this.driveGroup)}onDevicesCleared(t){"data"===t.type?(this.availDevices=[...this.allDevices],this.walDeviceSelectionGroups.devices=[],this.dbDeviceSelectionGroups.devices=[],this.disableFeatures(),this.driveGroup.reset(),this.form.get("walSlots").setValue(0,{emitEvent:!1}),this.form.get("dbSlots").setValue(0,{emitEvent:!1})):(this.availDevices=[...this.availDevices,...t.clearedDevices],this.driveGroup.clearDeviceSelection(t.type),this.form.get(`${t.type}Slots`).setValue(0,{emitEvent:!1}))}emitDeploymentSelection(){const t=this.form.get("deploymentOption").value,o=this.form.get("encrypted").value;this.emitDeploymentOption.emit({option:t,encrypted:o})}emitDeploymentMode(){this.simpleDeployment=!this.simpleDeployment,this.simpleDeployment||0!==this.dataDeviceSelectionGroups.devices.length?this.enableFeatures():this.disableFeatures(),this.emitMode.emit(this.simpleDeployment)}submit(){if(this.simpleDeployment){const c={option:this.form.get("deploymentOption").value,encrypted:this.form.get("encrypted").value},C=`${this.deploymentOptions.options[c.option].title} deployment`;this.taskWrapper.wrapTaskAroundCall({task:new cl.R("osd/"+$i.MQ.CREATE,{tracking_id:C}),call:this.osdService.create([c],C,"predefined")}).subscribe({complete:()=>{this.router.navigate(["/osd"])}})}else{const t=this.authStorageService.getUsername();this.driveGroup.setName(`dashboard-${t}-${wr().now()}`),this.modalService.show(kg,{driveGroups:[this.driveGroup.spec]}).componentInstance.submitAction.subscribe(()=>{this.router.navigate(["/osd"])}),this.previewButtonPanel.submitButton.loading=!1}}}return n.\u0275fac=function(t){return new(t||n)(e.Y36($i.p4),e.Y36(vt.j),e.Y36(Mc),e.Y36(Xl),e.Y36(Bo.F0),e.Y36(Bl.Z),e.Y36(Ji),e.Y36(Ll.P))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-osd-form"]],viewQuery:function(t,o){if(1&t&&(e.Gf(j_,5),e.Gf(kh,5),e.Gf(tp,5),e.Gf(Ko,5)),2&t){let c;e.iGM(c=e.CRH())&&(o.dataDeviceSelectionGroups=c.first),e.iGM(c=e.CRH())&&(o.walDeviceSelectionGroups=c.first),e.iGM(c=e.CRH())&&(o.dbDeviceSelectionGroups=c.first),e.iGM(c=e.CRH())&&(o.previewButtonPanel=c.first)}},inputs:{hideTitle:"hideTitle",hideSubmitBtn:"hideSubmitBtn"},outputs:{emitDriveGroup:"emitDriveGroup",emitDeploymentOption:"emitDeploymentOption",emitMode:"emitMode"},features:[e.qOj],decls:2,vars:2,consts:function(){let s,t,o,c,g,C,D,P,j,W,re,oe,me,_e;return s="Deployment Options",t="Advanced Mode",o="Shared devices",c="Features",g="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",C="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + " " + "\ufffd#5\ufffd" + "" + "\ufffd#6\ufffd" + "" + "\ufffd2\ufffd" + "" + "\ufffd/#6\ufffd" + "" + "\ufffd/#5\ufffd" + "",D="WAL slots",P="How many OSDs per WAL device.",j="Specify 0 to let Orchestrator backend decide it.",W="Value should be greater than or equal to 0",re="DB slots",oe="How many OSDs per DB device.",me="Specify 0 to let Orchestrator backend decide it.",_e="Value should be greater than or equal to 0",[[4,"ngIf"],["class","card",4,"cdFormLoading"],[1,"card"],["class","card-header",4,"ngIf"],[1,"card-body","ml-2"],["name","form","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"accordion"],[1,"card-header"],[1,"mb-0"],["data-toggle","collapse","aria-label","toggle deployment options",1,"btn","btn-link","btn-block","text-left","dropdown-toggle",3,"click"],s,[1,"collapse",3,"ngClass"],[1,"card-body","d-flex","flex-column"],["class","pt-3 pb-3",4,"ngFor","ngForOf"],["data-toggle","collapse","aria-label","toggle advanced mode",1,"btn","btn-link","btn-block","text-left","dropdown-toggle",3,"click"],t,[1,"card-body"],["name","Primary","type","data",3,"availDevices","canSelect","selected","cleared"],["dataDeviceSelectionGroups",""],o,["name","WAL","type","wal",3,"availDevices","canSelect","selected","cleared"],["walDeviceSelectionGroups",""],["class","form-group row",4,"ngIf"],["name","DB","type","db",3,"availDevices","canSelect","selected","cleared"],["dbDeviceSelectionGroups",""],["data-toggle","collapse","aria-label","features","aria-expanded","true",1,"btn","btn-link","btn-block","text-left","dropdown-toggle"],c,[1,"collapse","show"],["formGroupName","features",1,"pt-3","pb-3"],["class","custom-control custom-checkbox",4,"ngFor","ngForOf"],["class","card-footer",4,"ngIf"],g,[1,"pt-3","pb-3"],[1,"custom-control","custom-radio","custom-control-inline"],["type","radio","name","deploymentOption","formControlName","deploymentOption",1,"custom-control-input",3,"id","value","change"],[1,"custom-control-label",3,"id","for"],C,[1,"form-group","row"],["for","walSlots",1,"cd-col-form-label"],D,P,j,[1,"cd-col-form-input"],["id","walSlots","name","walSlots","type","number","min","0","formControlName","walSlots",1,"form-control"],["class","invalid-feedback",4,"ngIf"],[1,"invalid-feedback"],W,["for","dbSlots",1,"cd-col-form-label"],re,oe,me,["id","dbSlots","name","dbSlots","type","number","min","0","formControlName","dbSlots",1,"form-control"],_e,[1,"custom-control","custom-checkbox"],["type","checkbox",1,"custom-control-input",3,"id","name","formControlName","change"],[1,"custom-control-label",3,"for"],[1,"card-footer"],["wrappingClass","text-right",3,"form","disabled","submitText","submitActionEvent"],["previewButtonPanel",""]]},template:function(t,o){1&t&&(e.YNc(0,f_,1,0,"cd-orchestrator-doc-panel",0),e.YNc(1,yf,44,21,"div",1)),2&t&&(e.Q6J("ngIf",!o.hasOrchestrator),e.xp6(1),e.Q6J("cdFormLoading",o.loading))},directives:[_.O5,Ol.y,ou,Mn._Y,Mn.JL,ll.V,Mn.sg,la.o,_.mk,_.sg,Z_,Mn.x0,Mn._,Mn.Fj,ja.b,Mn.JJ,Mn.u,h.S,Za.P,Mn.qQ,Mn.wV,Mn.Wl,ul.p],pipes:[_.rS,F.m],styles:[""]}),n})();var yp=i(71289);let h_=(()=>{class n{transform(t){if(wr().isUndefined(t))return "no spec";if(wr().get(t,"unmanaged",!1))return "unmanaged";const o=[],c=wr().get(t,"placement.hosts"),g=wr().get(t,"placement.count"),C=wr().get(t,"placement.label"),D=wr().get(t,"placement.host_pattern");return wr().isArray(c)&&o.push(...c),wr().isNumber(g)&&o.push("count:" + g + ""),wr().isString(C)&&o.push("label:" + C + ""),wr().isString(D)&&o.push(D),o.join(";")}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275pipe=e.Yjl({name:"placement",type:n,pure:!0}),n})();var bp=i(79765),Bd=i(66682),fd=i(77393),bf=i(33637);function zf(n,s=bf.P){return t=>t.lift(new ch(n,s))}class ch{constructor(s,t){this.dueTime=s,this.scheduler=t}call(s,t){return t.subscribe(new od(s,this.dueTime,this.scheduler))}}class od extends fd.L{constructor(s,t,o){super(s),this.dueTime=t,this.scheduler=o,this.debouncedSubscription=null,this.lastValue=null,this.hasValue=!1}_next(s){this.clearDebounce(),this.lastValue=s,this.hasValue=!0,this.add(this.debouncedSubscription=this.scheduler.schedule(dh,this.dueTime,this))}_complete(){this.debouncedNext(),this.destination.complete()}debouncedNext(){if(this.clearDebounce(),this.hasValue){const{lastValue:s}=this;this.lastValue=null,this.hasValue=!1,this.destination.next(s)}}clearDebounce(){const s=this.debouncedSubscription;null!==s&&(this.remove(s),s.unsubscribe(),this.debouncedSubscription=null)}}function dh(n){n.debouncedNext()}var Df=i(87519),np=i(45435),V_=i(80842),fh=i(14745),__=i(4416),Bc=i(58039);function Rf(n,s){if(1&n&&(e.TgZ(0,"option",26),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t),e.xp6(1),e.hij(" ",t," ")}}function ph(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,28),e.qZA())}function _g(n,s){1&n&&(e.TgZ(0,"option",12),e.SDv(1,33),e.qZA()),2&n&&e.Q6J("ngValue",null)}function Bh(n,s){1&n&&(e.TgZ(0,"option",12),e.SDv(1,34),e.qZA()),2&n&&e.Q6J("ngValue",null)}function g_(n,s){1&n&&(e.TgZ(0,"option",12),e.SDv(1,35),e.qZA()),2&n&&e.Q6J("ngValue",null)}function ym(n,s){if(1&n&&(e.TgZ(0,"option",26),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t.service_name),e.xp6(1),e.Oqu(t.service_name)}}function bm(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,36),e.qZA())}const m_=function(){return["ingress"]},Zp=function(n){return{required:n}};function hh(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",7),e.TgZ(1,"label",29),e.SDv(2,30),e.qZA(),e.TgZ(3,"div",10),e.TgZ(4,"select",31),e.NdJ("change",function(){return e.CHM(t),e.oxw().prePopulateId()}),e.YNc(5,_g,2,1,"option",32),e.YNc(6,Bh,2,1,"option",32),e.YNc(7,g_,2,1,"option",32),e.YNc(8,ym,2,2,"option",14),e.qZA(),e.YNc(9,bm,2,0,"span",15),e.qZA(),e.qZA()}if(2&n){const t=e.oxw(),o=e.MAs(7);e.xp6(1),e.Q6J("ngClass",e.VKq(7,Zp,e.DdM(6,m_).includes(t.serviceForm.controls.service_type.value))),e.xp6(4),e.Q6J("ngIf",null===t.services),e.xp6(1),e.Q6J("ngIf",null!==t.services&&0===t.services.length),e.xp6(1),e.Q6J("ngIf",null!==t.services&&t.services.length>0),e.xp6(1),e.Q6J("ngForOf",t.services),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("backend_service",o,"required"))}}function Hg(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,40),e.qZA())}function gg(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,41),e.qZA())}function Ep(n,s){1&n&&(e.TgZ(0,"span",27),e.tHW(1,42),e._UZ(2,"strong"),e.N_p(),e.qZA())}const mg=function(){return["mds","rgw","nfs","iscsi","ingress"]};function vg(n,s){if(1&n&&(e.TgZ(0,"div",7),e.TgZ(1,"label",37),e.SDv(2,38),e.qZA(),e.TgZ(3,"div",10),e._UZ(4,"input",39),e.YNc(5,Hg,2,0,"span",15),e.YNc(6,gg,2,0,"span",15),e.YNc(7,Ep,3,0,"span",15),e.qZA(),e.qZA()),2&n){const t=e.oxw(),o=e.MAs(7);e.xp6(1),e.Q6J("ngClass",e.VKq(5,Zp,e.DdM(4,mg).includes(t.serviceForm.controls.service_type.value))),e.xp6(4),e.Q6J("ngIf",t.serviceForm.showError("service_id",o,"required")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("service_id",o,"uniqueName")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("service_id",o,"rgwPattern"))}}function Ug(n,s){1&n&&(e.TgZ(0,"div",7),e.TgZ(1,"label",43),e.SDv(2,44),e.qZA(),e.TgZ(3,"div",10),e.TgZ(4,"select",45),e.TgZ(5,"option",46),e.SDv(6,47),e.qZA(),e.TgZ(7,"option",48),e.SDv(8,49),e.qZA(),e.qZA(),e.qZA(),e.qZA())}function z_(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,53),e.qZA())}function Tp(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",7),e.TgZ(1,"label",50),e.SDv(2,51),e.qZA(),e.TgZ(3,"div",10),e.TgZ(4,"input",52),e.NdJ("focus",function(c){return e.CHM(t),e.oxw().labelFocus.next(c.target.value)})("click",function(c){return e.CHM(t),e.oxw().labelClick.next(c.target.value)}),e.qZA(),e.YNc(5,z_,2,0,"span",15),e.qZA(),e.qZA()}if(2&n){const t=e.oxw(),o=e.MAs(7);e.xp6(4),e.Q6J("ngbTypeahead",t.searchLabels),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("label",o,"required"))}}function _h(n,s){if(1&n&&(e.TgZ(0,"div",7),e.TgZ(1,"label",54),e.SDv(2,55),e.qZA(),e.TgZ(3,"div",10),e._UZ(4,"cd-select-badges",56),e.qZA(),e.qZA()),2&n){const t=e.oxw();e.xp6(4),e.Q6J("data",t.serviceForm.controls.hosts.value)("options",t.hosts.options)("messages",t.hosts.messages)}}function Bg(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,61),e.qZA())}function W_(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,62),e.qZA())}function Em(n,s){if(1&n&&(e.TgZ(0,"div",7),e.TgZ(1,"label",57),e.TgZ(2,"span"),e.SDv(3,58),e.qZA(),e.TgZ(4,"cd-helper"),e.SDv(5,59),e.qZA(),e.qZA(),e.TgZ(6,"div",10),e._UZ(7,"input",60),e.YNc(8,Bg,2,0,"span",15),e.YNc(9,W_,2,0,"span",15),e.qZA(),e.qZA()),2&n){const t=e.oxw(),o=e.MAs(7);e.xp6(8),e.Q6J("ngIf",t.serviceForm.showError("count",o,"min")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("count",o,"pattern"))}}function Yd(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,66),e.qZA())}function yg(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,67),e.qZA())}function Yg(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,68),e.qZA())}function Sp(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"div",7),e.TgZ(2,"label",63),e.SDv(3,64),e.qZA(),e.TgZ(4,"div",10),e._UZ(5,"input",65),e.YNc(6,Yd,2,0,"span",15),e.YNc(7,yg,2,0,"span",15),e.YNc(8,Yg,2,0,"span",15),e.qZA(),e.qZA(),e.BQk()),2&n){const t=e.oxw(),o=e.MAs(7);e.xp6(6),e.Q6J("ngIf",t.serviceForm.showError("rgw_frontend_port",o,"pattern")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("rgw_frontend_port",o,"min")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("rgw_frontend_port",o,"max"))}}function v_(n,s){1&n&&(e.TgZ(0,"option",12),e.SDv(1,72),e.qZA()),2&n&&e.Q6J("ngValue",null)}function Jc(n,s){1&n&&(e.TgZ(0,"option",12),e.SDv(1,73),e.qZA()),2&n&&e.Q6J("ngValue",null)}function J_(n,s){1&n&&(e.TgZ(0,"option",12),e.SDv(1,74),e.qZA()),2&n&&e.Q6J("ngValue",null)}function Yh(n,s){if(1&n&&(e.TgZ(0,"option",26),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t.pool_name),e.xp6(1),e.Oqu(t.pool_name)}}function Zh(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,75),e.qZA())}function bg(n,s){if(1&n&&(e.TgZ(0,"div",7),e.TgZ(1,"label",69),e.SDv(2,70),e.qZA(),e.TgZ(3,"div",10),e.TgZ(4,"select",71),e.YNc(5,v_,2,1,"option",32),e.YNc(6,Jc,2,1,"option",32),e.YNc(7,J_,2,1,"option",32),e.YNc(8,Yh,2,2,"option",14),e.qZA(),e.YNc(9,Zh,2,0,"span",15),e.qZA(),e.qZA()),2&n){const t=e.oxw(),o=e.MAs(7);e.xp6(5),e.Q6J("ngIf",null===t.pools),e.xp6(1),e.Q6J("ngIf",t.pools&&0===t.pools.length),e.xp6(1),e.Q6J("ngIf",t.pools&&t.pools.length>0),e.xp6(1),e.Q6J("ngForOf",t.pools),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("pool",o,"required"))}}function Eg(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,94),e.qZA())}function y_(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,95),e.qZA())}function b_(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,96),e.qZA())}function jh(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,97),e.qZA())}function E_(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,98),e.qZA())}const jp=function(){return["iscsi"]};function Tg(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"div",7),e.TgZ(2,"label",76),e.TgZ(3,"span"),e.SDv(4,77),e.qZA(),e.TgZ(5,"cd-helper"),e.TgZ(6,"span"),e.SDv(7,78),e.qZA(),e._UZ(8,"br"),e.TgZ(9,"span"),e.tHW(10,79),e._UZ(11,"b"),e.N_p(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(12,"div",10),e._UZ(13,"input",80),e.qZA(),e.qZA(),e.TgZ(14,"div",7),e.TgZ(15,"label",81),e.SDv(16,82),e.qZA(),e.TgZ(17,"div",10),e._UZ(18,"input",83),e.YNc(19,Eg,2,0,"span",15),e.YNc(20,y_,2,0,"span",15),e.YNc(21,b_,2,0,"span",15),e.qZA(),e.qZA(),e.TgZ(22,"div",7),e.TgZ(23,"label",84),e.SDv(24,85),e.qZA(),e.TgZ(25,"div",10),e._UZ(26,"input",86),e.YNc(27,jh,2,0,"span",15),e.qZA(),e.qZA(),e.TgZ(28,"div",7),e.TgZ(29,"label",87),e.SDv(30,88),e.qZA(),e.TgZ(31,"div",10),e.TgZ(32,"div",89),e._UZ(33,"input",90),e.TgZ(34,"span",91),e._UZ(35,"button",92),e._UZ(36,"cd-copy-2-clipboard-button",93),e.qZA(),e.YNc(37,E_,2,0,"span",15),e.qZA(),e.qZA(),e.qZA(),e.BQk()),2&n){const t=e.oxw(),o=e.MAs(7);e.xp6(19),e.Q6J("ngIf",t.serviceForm.showError("api_port",o,"pattern")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("api_port",o,"min")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("api_port",o,"max")),e.xp6(2),e.Q6J("ngClass",e.VKq(8,Zp,e.DdM(7,jp).includes(t.serviceForm.controls.service_type.value))),e.xp6(4),e.Q6J("ngIf",t.serviceForm.showError("api_user",o,"required")),e.xp6(2),e.Q6J("ngClass",e.VKq(11,Zp,e.DdM(10,jp).includes(t.serviceForm.controls.service_type.value))),e.xp6(8),e.Q6J("ngIf",t.serviceForm.showError("api_password",o,"required"))}}function T_(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,111),e.qZA())}function Zg(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,112),e.qZA())}function Gh(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,113),e.qZA())}function Sg(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,114),e.qZA())}function rv(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,115),e.qZA())}function Vh(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,116),e.qZA())}function Tm(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,117),e.qZA())}function S_(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,118),e.qZA())}function b(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,119),e.qZA())}function x(n,s){1&n&&(e.TgZ(0,"div",7),e.TgZ(1,"label",120),e.TgZ(2,"span"),e.SDv(3,121),e.qZA(),e.TgZ(4,"cd-helper"),e.TgZ(5,"span"),e.SDv(6,122),e.qZA(),e.qZA(),e.qZA(),e.TgZ(7,"div",10),e._UZ(8,"input",123),e.qZA(),e.qZA())}function G(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"div",7),e.TgZ(2,"label",99),e.TgZ(3,"span"),e.SDv(4,100),e.qZA(),e.TgZ(5,"cd-helper"),e.TgZ(6,"span"),e.SDv(7,101),e.qZA(),e.qZA(),e.qZA(),e.TgZ(8,"div",10),e._UZ(9,"input",102),e.YNc(10,T_,2,0,"span",15),e.qZA(),e.qZA(),e.TgZ(11,"div",7),e.TgZ(12,"label",103),e.TgZ(13,"span"),e.SDv(14,104),e.qZA(),e.TgZ(15,"cd-helper"),e.TgZ(16,"span"),e.SDv(17,105),e.qZA(),e.qZA(),e.qZA(),e.TgZ(18,"div",10),e._UZ(19,"input",106),e.YNc(20,Zg,2,0,"span",15),e.YNc(21,Gh,2,0,"span",15),e.YNc(22,Sg,2,0,"span",15),e.YNc(23,rv,2,0,"span",15),e.qZA(),e.qZA(),e.TgZ(24,"div",7),e.TgZ(25,"label",107),e.TgZ(26,"span"),e.SDv(27,108),e.qZA(),e.TgZ(28,"cd-helper"),e.TgZ(29,"span"),e.SDv(30,109),e.qZA(),e.qZA(),e.qZA(),e.TgZ(31,"div",10),e._UZ(32,"input",110),e.YNc(33,Vh,2,0,"span",15),e.YNc(34,Tm,2,0,"span",15),e.YNc(35,S_,2,0,"span",15),e.YNc(36,b,2,0,"span",15),e.qZA(),e.qZA(),e.YNc(37,x,9,0,"div",16),e.BQk()),2&n){const t=e.oxw(),o=e.MAs(7);e.xp6(2),e.Q6J("ngClass",e.VKq(14,Zp,e.DdM(13,m_).includes(t.serviceForm.controls.service_type.value))),e.xp6(8),e.Q6J("ngIf",t.serviceForm.showError("virtual_ip",o,"required")),e.xp6(2),e.Q6J("ngClass",e.VKq(17,Zp,e.DdM(16,m_).includes(t.serviceForm.controls.service_type.value))),e.xp6(8),e.Q6J("ngIf",t.serviceForm.showError("frontend_port",o,"pattern")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("frontend_port",o,"min")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("frontend_port",o,"max")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("frontend_port",o,"required")),e.xp6(2),e.Q6J("ngClass",e.VKq(20,Zp,e.DdM(19,m_).includes(t.serviceForm.controls.service_type.value))),e.xp6(8),e.Q6J("ngIf",t.serviceForm.showError("monitor_port",o,"pattern")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("monitor_port",o,"min")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("monitor_port",o,"max")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("monitor_port",o,"required")),e.xp6(1),e.Q6J("ngIf",!t.serviceForm.controls.unmanaged.value)}}function Se(n,s){if(1&n&&(e.TgZ(0,"option",26),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t),e.xp6(1),e.Oqu(t)}}function We(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,133),e.qZA())}function Nt(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,134),e.qZA())}function rn(n,s){1&n&&(e.TgZ(0,"span",27),e.tHW(1,135),e._UZ(2,"strong"),e.N_p(),e.qZA())}function On(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,140),e.qZA())}function yr(n,s){1&n&&(e.TgZ(0,"span",27),e.tHW(1,141),e._UZ(2,"strong"),e.N_p(),e.qZA())}function Si(n,s){if(1&n&&(e.TgZ(0,"div",7),e.TgZ(1,"label",136),e.TgZ(2,"span"),e.SDv(3,137),e.qZA(),e.TgZ(4,"cd-helper"),e.TgZ(5,"span"),e.SDv(6,138),e.qZA(),e.qZA(),e.qZA(),e.TgZ(7,"div",10),e._UZ(8,"input",139),e.YNc(9,On,2,0,"span",15),e.YNc(10,yr,3,0,"span",15),e.qZA(),e.qZA()),2&n){const t=e.oxw(2),o=e.MAs(7);e.xp6(9),e.Q6J("ngIf",t.serviceForm.showError("engine_id",o,"required")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("engine_id",o,"snmpEngineIdPattern"))}}function as(n,s){if(1&n&&(e.TgZ(0,"option",26),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t),e.xp6(1),e.hij(" ",t," ")}}function Ha(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,146),e.qZA())}const go=function(){return["SHA","MD5"]};function po(n,s){if(1&n&&(e.TgZ(0,"div",7),e.TgZ(1,"label",142),e.SDv(2,143),e.qZA(),e.TgZ(3,"div",10),e.TgZ(4,"select",144),e.TgZ(5,"option",12),e.SDv(6,145),e.qZA(),e.YNc(7,as,2,2,"option",14),e.qZA(),e.YNc(8,Ha,2,0,"span",15),e.qZA(),e.qZA()),2&n){const t=e.oxw(2),o=e.MAs(7);e.xp6(5),e.Q6J("ngValue",null),e.xp6(2),e.Q6J("ngForOf",e.DdM(3,go)),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("auth_protocol",o,"required"))}}function Fa(n,s){if(1&n&&(e.TgZ(0,"option",26),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t),e.xp6(1),e.hij(" ",t," ")}}const Ta=function(){return["DES","AES"]};function ni(n,s){1&n&&(e.TgZ(0,"div",7),e.TgZ(1,"label",147),e.SDv(2,148),e.qZA(),e.TgZ(3,"div",10),e.TgZ(4,"select",149),e.TgZ(5,"option",12),e.SDv(6,150),e.qZA(),e.YNc(7,Fa,2,2,"option",14),e.qZA(),e.qZA(),e.qZA()),2&n&&(e.xp6(5),e.Q6J("ngValue",null),e.xp6(2),e.Q6J("ngForOf",e.DdM(2,Ta)))}function Tr(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,154),e.qZA())}function Qr(n,s){if(1&n&&(e.TgZ(0,"div",7),e.TgZ(1,"label",151),e.TgZ(2,"span"),e.SDv(3,152),e.qZA(),e.qZA(),e.TgZ(4,"div",10),e._UZ(5,"input",153),e.YNc(6,Tr,2,0,"span",15),e.qZA(),e.qZA()),2&n){const t=e.oxw(2),o=e.MAs(7);e.xp6(6),e.Q6J("ngIf",t.serviceForm.showError("snmp_community",o,"required"))}}function Bi(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,158),e.qZA())}function io(n,s){if(1&n&&(e.TgZ(0,"div",7),e.TgZ(1,"label",155),e.TgZ(2,"span"),e.SDv(3,156),e.qZA(),e.qZA(),e.TgZ(4,"div",10),e._UZ(5,"input",157),e.YNc(6,Bi,2,0,"span",15),e.qZA(),e.qZA()),2&n){const t=e.oxw(2),o=e.MAs(7);e.xp6(6),e.Q6J("ngIf",t.serviceForm.showError("snmp_v3_auth_username",o,"required"))}}function va(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,162),e.qZA())}function Cs(n,s){if(1&n&&(e.TgZ(0,"div",7),e.TgZ(1,"label",159),e.TgZ(2,"span"),e.SDv(3,160),e.qZA(),e.qZA(),e.TgZ(4,"div",10),e._UZ(5,"input",161),e.YNc(6,va,2,0,"span",15),e.qZA(),e.qZA()),2&n){const t=e.oxw(2),o=e.MAs(7);e.xp6(6),e.Q6J("ngIf",t.serviceForm.showError("snmp_v3_auth_password",o,"required"))}}function Qa(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,166),e.qZA())}function xl(n,s){if(1&n&&(e.TgZ(0,"div",7),e.TgZ(1,"label",163),e.TgZ(2,"span"),e.SDv(3,164),e.qZA(),e.qZA(),e.TgZ(4,"div",10),e._UZ(5,"input",165),e.YNc(6,Qa,2,0,"span",15),e.qZA(),e.qZA()),2&n){const t=e.oxw(2),o=e.MAs(7);e.xp6(6),e.Q6J("ngIf",t.serviceForm.showError("snmp_v3_priv_password",o,"required"))}}const Cl=function(){return["V2c","V3"]};function Gp(n,s){if(1&n){const t=e.EpF();e.ynx(0),e.TgZ(1,"div",7),e.TgZ(2,"label",124),e.SDv(3,125),e.qZA(),e.TgZ(4,"div",10),e.TgZ(5,"select",126),e.NdJ("change",function(){return e.CHM(t),e.oxw().clearValidations()}),e.TgZ(6,"option",12),e.SDv(7,127),e.qZA(),e.YNc(8,Se,2,2,"option",14),e.qZA(),e.YNc(9,We,2,0,"span",15),e.qZA(),e.qZA(),e.TgZ(10,"div",7),e.TgZ(11,"label",128),e.TgZ(12,"span"),e.SDv(13,129),e.qZA(),e.TgZ(14,"cd-helper"),e.TgZ(15,"span"),e.SDv(16,130),e.qZA(),e.qZA(),e.qZA(),e.TgZ(17,"div",10),e._UZ(18,"input",131),e.YNc(19,Nt,2,0,"span",15),e.YNc(20,rn,3,0,"span",15),e.qZA(),e.qZA(),e.YNc(21,Si,11,2,"div",16),e.YNc(22,po,9,4,"div",16),e.YNc(23,ni,8,3,"div",16),e.TgZ(24,"fieldset"),e.TgZ(25,"legend"),e.SDv(26,132),e.qZA(),e.YNc(27,Qr,7,1,"div",16),e.YNc(28,io,7,1,"div",16),e.YNc(29,Cs,7,1,"div",16),e.YNc(30,xl,7,1,"div",16),e.qZA(),e.BQk()}if(2&n){const t=e.oxw(),o=e.MAs(7);e.xp6(6),e.Q6J("ngValue",null),e.xp6(2),e.Q6J("ngForOf",e.DdM(12,Cl)),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("snmp_version",o,"required")),e.xp6(10),e.Q6J("ngIf",t.serviceForm.showError("snmp_destination",o,"required")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("snmp_destination",o,"snmpDestinationPattern")),e.xp6(1),e.Q6J("ngIf","V3"===t.serviceForm.controls.snmp_version.value),e.xp6(1),e.Q6J("ngIf","V3"===t.serviceForm.controls.snmp_version.value),e.xp6(1),e.Q6J("ngIf","V3"===t.serviceForm.controls.snmp_version.value),e.xp6(4),e.Q6J("ngIf","V2c"===t.serviceForm.controls.snmp_version.value),e.xp6(1),e.Q6J("ngIf","V3"===t.serviceForm.controls.snmp_version.value),e.xp6(1),e.Q6J("ngIf","V3"===t.serviceForm.controls.snmp_version.value),e.xp6(1),e.Q6J("ngIf","V3"===t.serviceForm.controls.snmp_version.value&&null!=t.serviceForm.controls.privacy_protocol.value)}}function i1(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,175),e.qZA())}function zh(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,176),e.qZA())}function Sm(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",7),e.TgZ(1,"label",170),e.TgZ(2,"span"),e.SDv(3,171),e.qZA(),e.TgZ(4,"cd-helper"),e.SDv(5,172),e.qZA(),e.qZA(),e.TgZ(6,"div",10),e.TgZ(7,"textarea",173),e._uU(8," "),e.qZA(),e.TgZ(9,"input",174),e.NdJ("change",function(c){return e.CHM(t),e.oxw(2).fileUpload(c.target.files,"ssl_cert")}),e.qZA(),e.YNc(10,i1,2,0,"span",15),e.YNc(11,zh,2,0,"span",15),e.qZA(),e.qZA()}if(2&n){const t=e.oxw(2),o=e.MAs(7);e.xp6(10),e.Q6J("ngIf",t.serviceForm.showError("ssl_cert",o,"required")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("ssl_cert",o,"pattern"))}}function Cm(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,181),e.qZA())}function iv(n,s){1&n&&(e.TgZ(0,"span",27),e.SDv(1,182),e.qZA())}function hb(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",7),e.TgZ(1,"label",177),e.TgZ(2,"span"),e.SDv(3,178),e.qZA(),e.TgZ(4,"cd-helper"),e.SDv(5,179),e.qZA(),e.qZA(),e.TgZ(6,"div",10),e.TgZ(7,"textarea",180),e._uU(8," "),e.qZA(),e.TgZ(9,"input",174),e.NdJ("change",function(c){return e.CHM(t),e.oxw(2).fileUpload(c.target.files,"ssl_key")}),e.qZA(),e.YNc(10,Cm,2,0,"span",15),e.YNc(11,iv,2,0,"span",15),e.qZA(),e.qZA()}if(2&n){const t=e.oxw(2),o=e.MAs(7);e.xp6(10),e.Q6J("ngIf",t.serviceForm.showError("ssl_key",o,"required")),e.xp6(1),e.Q6J("ngIf",t.serviceForm.showError("ssl_key",o,"pattern"))}}const x0=function(){return["rgw","ingress"]};function o1(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"div",7),e.TgZ(2,"div",17),e.TgZ(3,"div",18),e._UZ(4,"input",167),e.TgZ(5,"label",168),e.SDv(6,169),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(7,Sm,12,2,"div",16),e.YNc(8,hb,12,2,"div",16),e.BQk()),2&n){const t=e.oxw();e.xp6(7),e.Q6J("ngIf",t.serviceForm.controls.ssl.value),e.xp6(1),e.Q6J("ngIf",t.serviceForm.controls.ssl.value&&!e.DdM(2,x0).includes(t.serviceForm.controls.service_type.value))}}const _b=function(){return["rgw","iscsi","ingress"]};let ov=(()=>{class n extends Oa.E{constructor(t,o,c,g,C,D,P,j,W){super(),this.actionLabels=t,this.cephServiceService=o,this.formBuilder=c,this.hostService=g,this.poolService=C,this.router=D,this.taskWrapperService=P,this.route=j,this.activeModal=W,this.RGW_SVC_ID_PATTERN=/^([^.]+)(\.([^.]+)\.([^.]+))?$/,this.SNMP_DESTINATION_PATTERN=/^[^\:]+:[0-9]/,this.SNMP_ENGINE_ID_PATTERN=/^[0-9A-Fa-f]{10,64}/g,this.INGRESS_SUPPORTED_SERVICE_TYPES=["rgw","nfs"],this.hiddenServices=[],this.editing=!1,this.serviceTypes=[],this.serviceIds=[],this.labelClick=new bp.xQ,this.labelFocus=new bp.xQ,this.services=[],this.searchLabels=re=>(0,Bd.T)(re.pipe(zf(200),(0,Df.x)()),this.labelFocus,this.labelClick.pipe((0,np.h)(()=>!this.typeahead.isPopupOpen()))).pipe((0,hu.U)(oe=>this.labels.filter(me=>me.toLowerCase().indexOf(oe.toLowerCase())>-1).slice(0,10))),this.resource="service",this.hosts={options:[],messages:new Hc.a({empty:"There are no hosts.",filter:"Filter hosts"})},this.createForm()}createForm(){this.serviceForm=this.formBuilder.group({service_type:[null,[Mn.kI.required]],service_id:[null,[ss.h.requiredIf({service_type:"mds"}),ss.h.requiredIf({service_type:"nfs"}),ss.h.requiredIf({service_type:"iscsi"}),ss.h.requiredIf({service_type:"ingress"}),ss.h.composeIf({service_type:"rgw"},[Mn.kI.required,ss.h.custom("rgwPattern",t=>!wr().isEmpty(t)&&!this.RGW_SVC_ID_PATTERN.test(t))]),ss.h.custom("uniqueName",t=>this.serviceIds&&this.serviceIds.includes(t))]],placement:["hosts"],label:[null,[ss.h.requiredIf({placement:"label",unmanaged:!1})]],hosts:[[]],count:[null,[ss.h.number(!1)]],unmanaged:[!1],pool:[null,[ss.h.requiredIf({service_type:"iscsi"})]],rgw_frontend_port:[null,[ss.h.number(!1)]],trusted_ip_list:[null],api_port:[null,[ss.h.number(!1)]],api_user:[null,[ss.h.requiredIf({service_type:"iscsi",unmanaged:!1})]],api_password:[null,[ss.h.requiredIf({service_type:"iscsi",unmanaged:!1})]],backend_service:[null,[ss.h.requiredIf({service_type:"ingress"})]],virtual_ip:[null,[ss.h.requiredIf({service_type:"ingress"})]],frontend_port:[null,[ss.h.number(!1),ss.h.requiredIf({service_type:"ingress"})]],monitor_port:[null,[ss.h.number(!1),ss.h.requiredIf({service_type:"ingress"})]],virtual_interface_networks:[null],ssl:[!1],ssl_cert:["",[ss.h.composeIf({service_type:"rgw",unmanaged:!1,ssl:!0},[Mn.kI.required,ss.h.pemCert()]),ss.h.composeIf({service_type:"iscsi",unmanaged:!1,ssl:!0},[Mn.kI.required,ss.h.sslCert()]),ss.h.composeIf({service_type:"ingress",unmanaged:!1,ssl:!0},[Mn.kI.required,ss.h.pemCert()])]],ssl_key:["",[ss.h.composeIf({service_type:"iscsi",unmanaged:!1,ssl:!0},[Mn.kI.required,ss.h.sslPrivKey()])]],snmp_version:[null,[ss.h.requiredIf({service_type:"snmp-gateway"})]],snmp_destination:[null,{validators:[ss.h.requiredIf({service_type:"snmp-gateway"}),ss.h.custom("snmpDestinationPattern",t=>!wr().isEmpty(t)&&!this.SNMP_DESTINATION_PATTERN.test(t))]}],engine_id:[null,[ss.h.requiredIf({service_type:"snmp-gateway"}),ss.h.custom("snmpEngineIdPattern",t=>!wr().isEmpty(t)&&!this.SNMP_ENGINE_ID_PATTERN.test(t))]],auth_protocol:["SHA",[ss.h.requiredIf({service_type:"snmp-gateway"})]],privacy_protocol:[null],snmp_community:[null,[ss.h.requiredIf({snmp_version:"V2c"})]],snmp_v3_auth_username:[null,[ss.h.requiredIf({service_type:"snmp-gateway"})]],snmp_v3_auth_password:[null,[ss.h.requiredIf({service_type:"snmp-gateway"})]],snmp_v3_priv_password:[null,[ss.h.requiredIf({privacy_protocol:{op:"!empty"}})]]})}ngOnInit(){this.action=this.actionLabels.CREATE,this.router.url.includes("services/(modal:create")?this.pageURL="services":this.router.url.includes("services/(modal:edit")&&(this.editing=!0,this.pageURL="services",this.route.params.subscribe(t=>{this.serviceName=t.name,this.serviceType=t.type})),this.cephServiceService.list().subscribe(t=>{this.serviceList=t,this.services=t.filter(o=>this.INGRESS_SUPPORTED_SERVICE_TYPES.includes(o.service_type))}),this.cephServiceService.getKnownTypes().subscribe(t=>{this.hiddenServices.push("osd","container"),this.serviceTypes=wr().difference(t,this.hiddenServices).sort()}),this.hostService.list("false").subscribe(t=>{const o=[];wr().forEach(t,c=>{if(wr().get(c,"sources.orchestrator",!1)){const g=new fh.$(!1,wr().get(c,"hostname"),"");o.push(g)}}),this.hosts.options=[...o]}),this.hostService.getLabels().subscribe(t=>{this.labels=t}),this.poolService.getList().subscribe(t=>{this.pools=t}),this.editing&&(this.action=this.actionLabels.EDIT,this.disableForEditing(this.serviceType),this.cephServiceService.list(this.serviceName).subscribe(t=>{var o,c,g,C,D,P,j,W,re,oe,me,_e,Fe;if(["service_type","service_id","unmanaged"].forEach(Le=>{this.serviceForm.get(Le).setValue(t[0][Le])}),!t[0].unmanaged){const Le=Object.keys(t[0].placement)[0];let we;we=["hosts","label"].indexOf(Le)>=0?Le:"hosts",this.serviceForm.get("placement").setValue(we),this.serviceForm.get("count").setValue(t[0].placement.count),(null===(o=t[0])||void 0===o?void 0:o.placement[we])&&this.serviceForm.get(we).setValue(null===(c=t[0])||void 0===c?void 0:c.placement[we])}switch(this.serviceType){case"iscsi":["pool","api_password","api_user","trusted_ip_list","api_port"].forEach(pt=>{this.serviceForm.get(pt).setValue(t[0].spec[pt])}),this.serviceForm.get("ssl").setValue(null===(g=t[0].spec)||void 0===g?void 0:g.api_secure),(null===(C=t[0].spec)||void 0===C?void 0:C.api_secure)&&(this.serviceForm.get("ssl_cert").setValue(null===(D=t[0].spec)||void 0===D?void 0:D.ssl_cert),this.serviceForm.get("ssl_key").setValue(null===(P=t[0].spec)||void 0===P?void 0:P.ssl_key));break;case"rgw":this.serviceForm.get("rgw_frontend_port").setValue(null===(j=t[0].spec)||void 0===j?void 0:j.rgw_frontend_port),this.serviceForm.get("ssl").setValue(null===(W=t[0].spec)||void 0===W?void 0:W.ssl),(null===(re=t[0].spec)||void 0===re?void 0:re.ssl)&&this.serviceForm.get("ssl_cert").setValue(null===(oe=t[0].spec)||void 0===oe?void 0:oe.rgw_frontend_ssl_certificate);break;case"ingress":["backend_service","virtual_ip","frontend_port","monitor_port","virtual_interface_networks","ssl"].forEach(pt=>{this.serviceForm.get(pt).setValue(t[0].spec[pt])}),(null===(me=t[0].spec)||void 0===me?void 0:me.ssl)&&(this.serviceForm.get("ssl_cert").setValue(null===(_e=t[0].spec)||void 0===_e?void 0:_e.ssl_cert),this.serviceForm.get("ssl_key").setValue(null===(Fe=t[0].spec)||void 0===Fe?void 0:Fe.ssl_key));break;case"snmp-gateway":["snmp_version","snmp_destination"].forEach(pt=>{this.serviceForm.get(pt).setValue(t[0].spec[pt])}),"V3"===this.serviceForm.getValue("snmp_version")?["engine_id","auth_protocol","privacy_protocol","snmp_v3_auth_username","snmp_v3_auth_password","snmp_v3_priv_password"].forEach(ht=>{null!==ht&&("snmp_v3_auth_username"===ht||"snmp_v3_auth_password"===ht||"snmp_v3_priv_password"===ht?this.serviceForm.get(ht).setValue(t[0].spec.credentials[ht]):this.serviceForm.get(ht).setValue(t[0].spec[ht]))}):this.serviceForm.get("snmp_community").setValue(t[0].spec.credentials.snmp_community)}}))}getServiceIds(t){this.serviceIds=this.serviceList.filter(o=>o.service_type===t).map(o=>o.service_id)}disableForEditing(t){switch(["service_type","service_id"].forEach(c=>{this.serviceForm.get(c).disable()}),t){case"ingress":this.serviceForm.get("backend_service").disable()}}fileUpload(t,o){const c=t[0],g=new FileReader;g.addEventListener("load",C=>{const D=this.serviceForm.get(o);D.setValue(C.target.result),D.markAsDirty(),D.markAsTouched(),D.updateValueAndValidity()}),g.readAsText(c,"utf8")}prePopulateId(){const t=this.serviceForm.get("service_id"),o=this.serviceForm.getValue("backend_service");t.reset({value:o,disabled:!0})}onSubmit(){var t,o,c,g,C;const D=this,P=this.serviceForm.getRawValue(),j=P.service_type;let W=`service/${$i.MQ.CREATE}`;this.editing&&(W=`service/${$i.MQ.EDIT}`);const re={service_type:j,placement:{},unmanaged:P.unmanaged};let oe;if("rgw"===j){const Fe=P.service_id.match(this.RGW_SVC_ID_PATTERN);oe=Fe[1],Fe[3]&&(re.rgw_realm=Fe[3],re.rgw_zone=Fe[4])}else oe=P.service_id;const me=oe;let _e=j;switch(wr().isString(me)&&!wr().isEmpty(me)&&(_e=`${j}.${me}`,re.service_id=me),j){case"ingress":re.backend_service=P.backend_service,re.service_id=P.backend_service,wr().isNumber(P.frontend_port)&&P.frontend_port>0&&(re.frontend_port=P.frontend_port),wr().isString(P.virtual_ip)&&!wr().isEmpty(P.virtual_ip)&&(re.virtual_ip=P.virtual_ip.trim()),wr().isNumber(P.monitor_port)&&P.monitor_port>0&&(re.monitor_port=P.monitor_port);break;case"iscsi":re.pool=P.pool;break;case"snmp-gateway":re.credentials={},re.snmp_version=P.snmp_version,re.snmp_destination=P.snmp_destination,"V3"===P.snmp_version?(re.engine_id=P.engine_id,re.auth_protocol=P.auth_protocol,re.credentials.snmp_v3_auth_username=P.snmp_v3_auth_username,re.credentials.snmp_v3_auth_password=P.snmp_v3_auth_password,null!==P.privacy_protocol&&(re.privacy_protocol=P.privacy_protocol,re.credentials.snmp_v3_priv_password=P.snmp_v3_priv_password)):re.credentials.snmp_community=P.snmp_community}if(!P.unmanaged){switch(P.placement){case"hosts":P.hosts.length>0&&(re.placement.hosts=P.hosts);break;case"label":re.placement.label=P.label}switch(wr().isNumber(P.count)&&P.count>0&&(re.placement.count=P.count),j){case"rgw":wr().isNumber(P.rgw_frontend_port)&&P.rgw_frontend_port>0&&(re.rgw_frontend_port=P.rgw_frontend_port),re.ssl=P.ssl,P.ssl&&(re.rgw_frontend_ssl_certificate=null===(t=P.ssl_cert)||void 0===t?void 0:t.trim());break;case"iscsi":wr().isString(P.trusted_ip_list)&&!wr().isEmpty(P.trusted_ip_list)&&(re.trusted_ip_list=P.trusted_ip_list.trim()),wr().isNumber(P.api_port)&&P.api_port>0&&(re.api_port=P.api_port),re.api_user=P.api_user,re.api_password=P.api_password,re.api_secure=P.ssl,P.ssl&&(re.ssl_cert=null===(o=P.ssl_cert)||void 0===o?void 0:o.trim(),re.ssl_key=null===(c=P.ssl_key)||void 0===c?void 0:c.trim());break;case"ingress":re.ssl=P.ssl,P.ssl&&(re.ssl_cert=null===(g=P.ssl_cert)||void 0===g?void 0:g.trim(),re.ssl_key=null===(C=P.ssl_key)||void 0===C?void 0:C.trim()),re.virtual_interface_networks=P.virtual_interface_networks}}this.taskWrapperService.wrapTaskAroundCall({task:new cl.R(W,{service_name:_e}),call:this.editing?this.cephServiceService.update(re):this.cephServiceService.create(re)}).subscribe({error(){D.serviceForm.setErrors({cdSubmitButton:!0})},complete:()=>{"services"===this.pageURL?this.router.navigate([this.pageURL,{outlets:{modal:null}}]):this.activeModal.close()}})}clearValidations(){const t=this.serviceForm.getValue("snmp_version"),o=this.serviceForm.getValue("privacy_protocol");"V3"===t?this.serviceForm.get("snmp_community").clearValidators():(this.serviceForm.get("engine_id").clearValidators(),this.serviceForm.get("auth_protocol").clearValidators(),this.serviceForm.get("privacy_protocol").clearValidators(),this.serviceForm.get("snmp_v3_auth_username").clearValidators(),this.serviceForm.get("snmp_v3_auth_password").clearValidators()),null===o&&this.serviceForm.get("snmp_v3_priv_password").clearValidators()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36($i.p4),e.Y36(Qt),e.Y36(rd.O),e.Y36(Xl),e.Y36(V_.q),e.Y36(Bo.F0),e.Y36(Ll.P),e.Y36(Bo.gz),e.Y36(ut.Kz))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-service-form"]],viewQuery:function(t,o){if(1&t&&e.Gf(ut.dR,5),2&t){let c;e.iGM(c=e.CRH())&&(o.typeahead=c.first)}},inputs:{hiddenServices:"hiddenServices",editing:"editing",serviceName:"serviceName",serviceType:"serviceType"},features:[e.qOj],decls:41,vars:31,consts:function(){let s,t,o,c,g,C,D,P,j,W,re,oe,me,_e,Fe,Re,Le,we,U,pt,ht,Dt,Ft,cn,kt,wn,Tn,Hr,sr,Nr,xr,fn,Rn,kn,Wn,bn,jr,ji,oi,Ui,Xr,Sn,hn,_r,Fi,_s,Ho,yo,Us,zs,Di,oo,ho,Ze,Mt,St,Un,pr,Vr,Ri,Bs,Uo,ol,ml,tu,qu,Lf,Fl,Kc,cp,Ah,Qp,Oh,nu,Yc,Lp,Yi,or,yi,qi,No,Wo,qo,is,_a,Ka,Du,Qn,Ii,rs,Zi,As,es,fu,Ml;return s="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",t="Type",o="-- Select a service type --",c="Unmanaged",g="This field is required.",C="Backend Service",D="Loading...",P="-- No service available --",j="-- Select an existing service --",W="This field is required.",re="Id",oe="This field is required.",me="This service id is already in use.",_e="The value does not match the pattern " + "\ufffd#2\ufffd" + "<service_id>[.<realm_name>.<zone_name>]" + "\ufffd/#2\ufffd" + ".",Fe="Placement",Re="Hosts",Le="Label",we="Label",U="This field is required.",pt="Hosts",ht="Count",Dt="Only that number of daemons will be created.",Ft="The value must be at least 1.",cn="The entered value needs to be a number.",kt="Port",wn="The entered value needs to be a number.",Tn="The value must be at least 1.",Hr="The value cannot exceed 65535.",sr="Pool",Nr="Loading...",xr="-- No pools available --",fn="-- Select a pool --",Rn="This field is required.",kn="Trusted IPs",Wn="Comma separated list of IP addresses.",bn="Please add the " + "\ufffd#11\ufffd" + "Ceph Manager" + "\ufffd/#11\ufffd" + " IP addresses here, otherwise the iSCSI gateways can't be reached.",jr="Port",ji="User",oi="Password",Ui="The entered value needs to be a number.",Xr="The value must be at least 1.",Sn="The value cannot exceed 65535.",hn="This field is required.",_r="This field is required.",Fi="Virtual IP",_s="The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.",Ho="Frontend Port",yo="The port used to access the ingress service.",Us="Monitor Port",zs="The port used by haproxy for load balancer status.",Di="This field is required.",oo="The entered value needs to be a number.",ho="The value must be at least 1.",Ze="The value cannot exceed 65535.",Mt="This field is required.",St="The entered value needs to be a number.",Un="The value must be at least 1.",pr="The value cannot exceed 65535.",Vr="This field is required.",Ri="CIDR Networks",Bs="A list of networks to identify which network interface to use for the virtual IP address.",Uo="Version",ol="-- Select SNMP version --",ml="Destination",tu="Must be of the format hostname:port.",qu="Credentials",Lf="This field is required.",Fl="This field is required.",Kc="The value does not match the pattern: " + "\ufffd#2\ufffd" + "hostname:port" + "\ufffd/#2\ufffd" + "",cp="Engine Id",Ah="Unique identifier for the device (in hex).",Qp="This field is required.",Oh="The value does not match the pattern: " + "\ufffd#2\ufffd" + "Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64." + "\ufffd/#2\ufffd" + "",nu="Auth Protocol",Yc="-- Select auth protocol --",Lp="This field is required.",Yi="Privacy Protocol",or="-- Select privacy protocol --",yi="SNMP Community",qi="This field is required.",No="Username",Wo="This field is required.",qo="Password",is="This field is required.",_a="Encryption",Ka="This field is required.",Du="SSL",Qn="Certificate",Ii="The SSL certificate in PEM format.",rs="This field is required.",Zi="Invalid SSL certificate.",As="Private key",es="The SSL private key in PEM format.",fu="This field is required.",Ml="Invalid SSL private key.",[[3,"pageURL","modalRef"],[1,"modal-title"],s,[1,"modal-content"],["novalidate","",3,"formGroup"],["frm","ngForm"],[1,"modal-body"],[1,"form-group","row"],["for","service_type",1,"cd-col-form-label","required"],t,[1,"cd-col-form-input"],["id","service_type","name","service_type","formControlName","service_type",1,"form-control",3,"change"],[3,"ngValue"],o,[3,"value",4,"ngFor","ngForOf"],["class","invalid-feedback",4,"ngIf"],["class","form-group row",4,"ngIf"],[1,"cd-col-form-offset"],[1,"custom-control","custom-checkbox"],["id","unmanaged","type","checkbox","formControlName","unmanaged",1,"custom-control-input"],["for","unmanaged",1,"custom-control-label"],c,[4,"ngIf"],[1,"modal-footer"],[1,"text-right"],[3,"form","submitText","submitActionEvent"],[3,"value"],[1,"invalid-feedback"],g,["for","backend_service",1,"cd-col-form-label",3,"ngClass"],C,["id","backend_service","name","backend_service","formControlName","backend_service",1,"form-control",3,"change"],[3,"ngValue",4,"ngIf"],D,P,j,W,["for","service_id",1,"cd-col-form-label",3,"ngClass"],re,["id","service_id","type","text","formControlName","service_id",1,"form-control"],oe,me,_e,["for","placement",1,"cd-col-form-label"],Fe,["id","placement","formControlName","placement",1,"form-control"],["value","hosts"],Re,["value","label"],Le,["for","label",1,"cd-col-form-label"],we,["id","label","type","text","formControlName","label",1,"form-control",3,"ngbTypeahead","focus","click"],U,["for","hosts",1,"cd-col-form-label"],pt,["id","hosts",3,"data","options","messages"],["for","count",1,"cd-col-form-label"],ht,Dt,["id","count","type","number","formControlName","count","min","1",1,"form-control"],Ft,cn,["for","rgw_frontend_port",1,"cd-col-form-label"],kt,["id","rgw_frontend_port","type","number","formControlName","rgw_frontend_port","min","1","max","65535",1,"form-control"],wn,Tn,Hr,["for","pool",1,"cd-col-form-label","required"],sr,["id","pool","name","pool","formControlName","pool",1,"form-control"],Nr,xr,fn,Rn,["for","trusted_ip_list",1,"cd-col-form-label"],kn,Wn,bn,["id","trusted_ip_list","type","text","formControlName","trusted_ip_list",1,"form-control"],["for","api_port",1,"cd-col-form-label"],jr,["id","api_port","type","number","formControlName","api_port","min","1","max","65535",1,"form-control"],["for","api_user",1,"cd-col-form-label",3,"ngClass"],ji,["id","api_user","type","text","formControlName","api_user",1,"form-control"],["for","api_password",1,"cd-col-form-label",3,"ngClass"],oi,[1,"input-group"],["id","api_password","type","password","autocomplete","new-password","formControlName","api_password",1,"form-control"],[1,"input-group-append"],["type","button","cdPasswordButton","api_password",1,"btn","btn-light"],["source","api_password"],Ui,Xr,Sn,hn,_r,["for","virtual_ip",1,"cd-col-form-label",3,"ngClass"],Fi,_s,["id","virtual_ip","type","text","formControlName","virtual_ip",1,"form-control"],["for","frontend_port",1,"cd-col-form-label",3,"ngClass"],Ho,yo,["id","frontend_port","type","number","formControlName","frontend_port","min","1","max","65535",1,"form-control"],["for","monitor_port",1,"cd-col-form-label",3,"ngClass"],Us,zs,["id","monitor_port","type","number","formControlName","monitor_port","min","1","max","65535",1,"form-control"],Di,oo,ho,Ze,Mt,St,Un,pr,Vr,["for","virtual_interface_networks",1,"cd-col-form-label"],Ri,Bs,["id","virtual_interface_networks","type","text","formControlName","virtual_interface_networks",1,"form-control"],["for","snmp_version",1,"cd-col-form-label","required"],Uo,["id","snmp_version","name","snmp_version","formControlName","snmp_version",1,"form-control",3,"change"],ol,["for","snmp_destination",1,"cd-col-form-label","required"],ml,tu,["id","snmp_destination","type","text","formControlName","snmp_destination",1,"form-control"],qu,Lf,Fl,Kc,["for","engine_id",1,"cd-col-form-label","required"],cp,Ah,["id","engine_id","type","text","formControlName","engine_id",1,"form-control"],Qp,Oh,["for","auth_protocol",1,"cd-col-form-label","required"],nu,["id","auth_protocol","name","auth_protocol","formControlName","auth_protocol",1,"form-control"],Yc,Lp,["for","privacy_protocol",1,"cd-col-form-label"],Yi,["id","privacy_protocol","name","privacy_protocol","formControlName","privacy_protocol",1,"form-control"],or,["for","snmp_community",1,"cd-col-form-label","required"],yi,["id","snmp_community","type","text","formControlName","snmp_community",1,"form-control"],qi,["for","snmp_v3_auth_username",1,"cd-col-form-label","required"],No,["id","snmp_v3_auth_username","type","text","formControlName","snmp_v3_auth_username",1,"form-control"],Wo,["for","snmp_v3_auth_password",1,"cd-col-form-label","required"],qo,["id","snmp_v3_auth_password","type","password","formControlName","snmp_v3_auth_password",1,"form-control"],is,["for","snmp_v3_priv_password",1,"cd-col-form-label","required"],_a,["id","snmp_v3_priv_password","type","password","formControlName","snmp_v3_priv_password",1,"form-control"],Ka,["id","ssl","type","checkbox","formControlName","ssl",1,"custom-control-input"],["for","ssl",1,"custom-control-label"],Du,["for","ssl_cert",1,"cd-col-form-label"],Qn,Ii,["id","ssl_cert","formControlName","ssl_cert","rows","5",1,"form-control","resize-vertical","text-monospace","text-pre"],["type","file",3,"change"],rs,Zi,["for","ssl_key",1,"cd-col-form-label"],As,es,["id","ssl_key","formControlName","ssl_key","rows","5",1,"form-control","resize-vertical","text-monospace","text-pre"],fu,Ml]},template:function(t,o){if(1&t&&(e.TgZ(0,"cd-modal",0),e.TgZ(1,"span",1),e.SDv(2,2),e.ALo(3,"titlecase"),e.ALo(4,"upperFirst"),e.qZA(),e.ynx(5,3),e.TgZ(6,"form",4,5),e.TgZ(8,"div",6),e.TgZ(9,"div",7),e.TgZ(10,"label",8),e.SDv(11,9),e.qZA(),e.TgZ(12,"div",10),e.TgZ(13,"select",11),e.NdJ("change",function(g){return o.getServiceIds(g.target.value)}),e.TgZ(14,"option",12),e.SDv(15,13),e.qZA(),e.YNc(16,Rf,2,2,"option",14),e.qZA(),e.YNc(17,ph,2,0,"span",15),e.qZA(),e.qZA(),e.YNc(18,hh,10,9,"div",16),e.YNc(19,vg,8,7,"div",16),e.TgZ(20,"div",7),e.TgZ(21,"div",17),e.TgZ(22,"div",18),e._UZ(23,"input",19),e.TgZ(24,"label",20),e.SDv(25,21),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(26,Ug,9,0,"div",16),e.YNc(27,Tp,6,2,"div",16),e.YNc(28,_h,5,3,"div",16),e.YNc(29,Em,10,2,"div",16),e.YNc(30,Sp,9,3,"ng-container",22),e.YNc(31,bg,10,5,"div",16),e.YNc(32,Tg,38,13,"ng-container",22),e.YNc(33,G,38,22,"ng-container",22),e.YNc(34,Gp,31,13,"ng-container",22),e.YNc(35,o1,9,3,"ng-container",22),e.qZA(),e.TgZ(36,"div",23),e.TgZ(37,"div",24),e.TgZ(38,"cd-form-button-panel",25),e.NdJ("submitActionEvent",function(){return o.onSubmit()}),e.ALo(39,"titlecase"),e.ALo(40,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t){const c=e.MAs(7);e.Q6J("pageURL",o.pageURL)("modalRef",o.activeModal),e.xp6(4),e.pQV(e.lcZ(3,22,o.action))(e.lcZ(4,24,o.resource)),e.QtT(2),e.xp6(2),e.Q6J("formGroup",o.serviceForm),e.xp6(8),e.Q6J("ngValue",null),e.xp6(2),e.Q6J("ngForOf",o.serviceTypes),e.xp6(1),e.Q6J("ngIf",o.serviceForm.showError("service_type",c,"required")),e.xp6(1),e.Q6J("ngIf","ingress"===o.serviceForm.controls.service_type.value),e.xp6(1),e.Q6J("ngIf","snmp-gateway"!==o.serviceForm.controls.service_type.value),e.xp6(7),e.Q6J("ngIf",!o.serviceForm.controls.unmanaged.value),e.xp6(1),e.Q6J("ngIf",!o.serviceForm.controls.unmanaged.value&&"label"===o.serviceForm.controls.placement.value),e.xp6(1),e.Q6J("ngIf",!o.serviceForm.controls.unmanaged.value&&"hosts"===o.serviceForm.controls.placement.value),e.xp6(1),e.Q6J("ngIf",!o.serviceForm.controls.unmanaged.value),e.xp6(1),e.Q6J("ngIf",!o.serviceForm.controls.unmanaged.value&&"rgw"===o.serviceForm.controls.service_type.value),e.xp6(1),e.Q6J("ngIf","iscsi"===o.serviceForm.controls.service_type.value),e.xp6(1),e.Q6J("ngIf",!o.serviceForm.controls.unmanaged.value&&"iscsi"===o.serviceForm.controls.service_type.value),e.xp6(1),e.Q6J("ngIf","ingress"===o.serviceForm.controls.service_type.value),e.xp6(1),e.Q6J("ngIf","snmp-gateway"===o.serviceForm.controls.service_type.value),e.xp6(1),e.Q6J("ngIf",!o.serviceForm.controls.unmanaged.value&&e.DdM(30,_b).includes(o.serviceForm.controls.service_type.value)),e.xp6(3),e.Q6J("form",o.serviceForm)("submitText",e.lcZ(39,26,o.action)+" "+e.lcZ(40,28,o.resource))}},directives:[bu.z,Mn._Y,Mn.JL,ll.V,Mn.sg,Za.P,la.o,Mn.EJ,ja.b,Mn.JJ,Mn.u,Mn.YN,Mn.Kr,_.sg,_.O5,Mn.Wl,ul.p,_.mk,Mn.Fj,ut.dR,R.m,h.S,Mn.wV,Mn.qQ,Mn.Fd,__.C,Bc.s],pipes:[_.rS,F.m],styles:[""]}),n})();function rp(n,s){if(1&n&&(e.ynx(0),e._UZ(1,"cd-service-daemon-list",1),e.BQk()),2&n){const t=e.oxw();e.xp6(1),e.Q6J("serviceName",t.selection.service_name)}}let sv=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-service-details"]],inputs:{permissions:"permissions",selection:"selection"},decls:1,vars:1,consts:[[4,"ngIf"],[3,"serviceName"]],template:function(t,o){1&t&&e.YNc(0,rp,2,1,"ng-container",0),2&t&&e.Q6J("ngIf",o.selection)},directives:[_.O5,Rh],styles:[""]}),n})();function av(n,s){1&n&&e._UZ(0,"cd-orchestrator-doc-panel")}function Mm(n,s){if(1&n){const t=e.EpF();e.ynx(0),e.TgZ(1,"cd-table",2),e.NdJ("fetchData",function(c){return e.CHM(t),e.oxw().getServices(c)})("setExpandedRow",function(c){return e.CHM(t),e.oxw().setExpandedRow(c)})("updateSelection",function(c){return e.CHM(t),e.oxw().updateSelection(c)}),e._UZ(2,"cd-table-actions",3),e._UZ(3,"cd-service-details",4),e.qZA(),e.BQk()}if(2&n){const t=e.oxw();e.xp6(1),e.Q6J("data",t.services)("columns",t.columns)("autoReload",5e3)("hasDetails",t.hasDetails),e.xp6(1),e.Q6J("permission",t.permissions.hosts)("selection",t.selection)("tableActions",t.tableActions),e.xp6(1),e.Q6J("permissions",t.permissions)("selection",t.expandedRow)}}const mc="services";let ef=(()=>{class n extends jl.o{constructor(t,o,c,g,C,D,P,j){super(),this.actionLabels=t,this.authStorageService=o,this.modalService=c,this.orchService=g,this.cephServiceService=C,this.relativeDatePipe=D,this.taskWrapperService=P,this.router=j,this.hiddenColumns=[],this.hiddenServices=[],this.hasDetails=!0,this.routedModal=!0,this.showDocPanel=!1,this.actionOrchFeatures={create:[cu.SERVICE_CREATE],update:[cu.SERVICE_EDIT],delete:[cu.SERVICE_DELETE]},this.columns=[],this.services=[],this.isLoadingServices=!1,this.selection=new El.r,this.permissions=this.authStorageService.getPermissions(),this.tableActions=[{permission:"create",icon:xo.P.add,click:()=>this.openModal(),name:this.actionLabels.CREATE,canBePrimary:W=>!W.hasSelection,disable:W=>this.getDisable("create",W)},{permission:"update",icon:xo.P.edit,click:()=>this.openModal(!0),name:this.actionLabels.EDIT,disable:W=>this.getDisable("update",W)},{permission:"delete",icon:xo.P.destroy,click:()=>this.deleteAction(),name:this.actionLabels.DELETE,disable:W=>this.getDisable("delete",W)}]}openModal(t=!1){var o,c,g;if(this.routedModal)this.router.navigate(t?[mc,{outlets:{modal:[$i.MQ.EDIT,this.selection.first().service_type,this.selection.first().service_name]}}]:[mc,{outlets:{modal:[$i.MQ.CREATE]}}]);else{let C={};C=t?{serviceName:null===(o=this.selection.first())||void 0===o?void 0:o.service_name,serviceType:null===(g=null===(c=this.selection)||void 0===c?void 0:c.first())||void 0===g?void 0:g.service_type,hiddenServices:this.hiddenServices,editing:t}:{hiddenServices:this.hiddenServices,editing:t},this.bsModalRef=this.modalService.show(ov,C,{size:"lg"})}}ngOnInit(){const t=[{name:"Service",prop:"service_name",flexGrow:1},{name:"Placement",prop:"",pipe:new h_,flexGrow:2},{name:"Running",prop:"status.running",flexGrow:1},{name:"Size",prop:"status.size",flexGrow:1},{name:"Last Refreshed",prop:"status.last_refresh",pipe:this.relativeDatePipe,flexGrow:1}];this.columns=t.filter(o=>!this.hiddenColumns.includes(o.prop)),this.orchService.status().subscribe(o=>{this.orchStatus=o,this.showDocPanel=!o.available})}ngOnChanges(){var t;(null===(t=this.orchStatus)||void 0===t?void 0:t.available)&&(this.services=[],this.table.reloadData())}getDisable(t,o){var c;return"delete"===t&&!(null==o?void 0:o.hasSingleSelection)||"update"===t&&["osd","container"].indexOf(null===(c=this.selection.first())||void 0===c?void 0:c.service_type)>=0||this.orchService.getTableActionDisableDesc(this.orchStatus,this.actionOrchFeatures[t])}getServices(t){this.isLoadingServices||(this.isLoadingServices=!0,this.cephServiceService.list().subscribe(o=>{this.services=o,this.services=this.services.filter(c=>!this.hiddenServices.includes(c.service_name)),this.isLoadingServices=!1},()=>{this.isLoadingServices=!1,this.services=[],t.error()}))}updateSelection(t){this.selection=t}deleteAction(){const t=this.selection.first();this.modalService.show(Gl.M,{itemDescription:"Service",itemNames:[t.service_name],actionDescription:"delete",submitActionObservable:()=>this.taskWrapperService.wrapTaskAroundCall({task:new cl.R(`service/${$i.MQ.DELETE}`,{service_name:t.service_name}),call:this.cephServiceService.delete(t.service_name)}).pipe((0,yp.g)(5e3))})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36($i.p4),e.Y36(vt.j),e.Y36(Bl.Z),e.Y36(Mc),e.Y36(Qt),e.Y36(Tt.h),e.Y36(Ll.P),e.Y36(Bo.F0))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-services"]],viewQuery:function(t,o){if(1&t&&e.Gf(ks.a,7),2&t){let c;e.iGM(c=e.CRH())&&(o.table=c.first)}},inputs:{hostname:"hostname",hiddenColumns:"hiddenColumns",hiddenServices:"hiddenServices",hasDetails:"hasDetails",routedModal:"routedModal"},features:[e._Bn([{provide:Lu.F,useValue:new Lu.F(mc)}]),e.qOj,e.TTD],decls:3,vars:2,consts:[[4,"ngIf"],["name","modal"],["identifier","service_name","forceIdentifier","true","columnMode","flex","selectionType","single",3,"data","columns","autoReload","hasDetails","fetchData","setExpandedRow","updateSelection"],[1,"table-actions",3,"permission","selection","tableActions"],["cdTableDetail","",3,"permissions","selection"]],template:function(t,o){1&t&&(e.YNc(0,av,1,0,"cd-orchestrator-doc-panel",0),e.YNc(1,Mm,4,9,"ng-container",0),e._UZ(2,"router-outlet",1)),2&t&&(e.Q6J("ngIf",o.showDocPanel),e.xp6(1),e.Q6J("ngIf",null==o.orchStatus?null:o.orchStatus.available))},directives:[_.O5,Bo.lC,ou,ks.a,Js.K,sv],styles:[""]}),n})();const Fu=function(){return["services","status"]};let s1=(()=>{class n{constructor(t,o,c,g,C){this.wizardStepsService=t,this.cephServiceService=o,this.dimlessBinary=c,this.hostService=g,this.osdService=C,this.hosts=[],this.totalCapacity=0,this.services=[],this.totalCPUs=0,this.totalMemory=0}ngOnInit(){var t,o,c;let g=0,C=0,D=0,P=0,j=0,W=0;this.hostService.list("true").subscribe(re=>{this.hosts=re,this.hostsCount=this.hosts.length,wr().forEach(this.hosts,oe=>{this.totalCPUs=this.totalCPUs+oe.cpu_count,this.totalMemory=this.totalMemory+1024*oe.memory_total_kb}),this.totalMemory=this.dimlessBinary.transform(this.totalMemory)}),this.osdService.osdDevices.data&&(g=null===(t=this.osdService.osdDevices.data)||void 0===t?void 0:t.length,C=this.osdService.osdDevices.data.capacity),this.osdService.osdDevices.wal&&(D=null===(o=this.osdService.osdDevices.wal)||void 0===o?void 0:o.length,P=this.osdService.osdDevices.wal.capacity),this.osdService.osdDevices.db&&(j=null===(c=this.osdService.osdDevices.db)||void 0===c?void 0:c.length,W=this.osdService.osdDevices.db.capacity),this.totalDevices=g+D+j,this.osdService.osdDevices.totalDevices=this.totalDevices,this.totalCapacity=C+P+W}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Yu),e.Y36(Qt),e.Y36(mn.$),e.Y36(Xl),e.Y36(Ji))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-create-cluster-review"]],decls:43,vars:14,consts:function(){let s,t,o,c,g,C,D,P;return s="Cluster Resources",t="Hosts",o="Storage Capacity",c="Number of devices",g="Raw capacity",C="CPUs",D="Memory",P="Host Details",[[1,"row"],[1,"col-lg-3"],[1,"cd-header"],s,[1,"table","table-striped"],[1,"bold"],t,o,c,g,[1,"pt-5"],C,D,[1,"col-lg-9"],P,[3,"hiddenColumns","hideToolHeader","hideTitle","hideSubmitBtn","hasTableDetails","showGeneralActionsOnly"]]},template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"div",1),e.TgZ(2,"fieldset"),e.TgZ(3,"legend",2),e.SDv(4,3),e.qZA(),e.TgZ(5,"table",4),e.TgZ(6,"tr"),e.TgZ(7,"td",5),e.SDv(8,6),e.qZA(),e.TgZ(9,"td"),e._uU(10),e.qZA(),e.qZA(),e.TgZ(11,"tr"),e.TgZ(12,"td"),e.TgZ(13,"dl"),e.TgZ(14,"dt"),e.TgZ(15,"p"),e.SDv(16,7),e.qZA(),e.qZA(),e.TgZ(17,"dd"),e.TgZ(18,"p"),e.SDv(19,8),e.qZA(),e.qZA(),e.TgZ(20,"dd"),e.TgZ(21,"p"),e.SDv(22,9),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(23,"td",10),e.TgZ(24,"p"),e._uU(25),e.qZA(),e.TgZ(26,"p"),e._uU(27),e.ALo(28,"dimlessBinary"),e.qZA(),e.qZA(),e.qZA(),e.TgZ(29,"tr"),e.TgZ(30,"td",5),e.SDv(31,11),e.qZA(),e.TgZ(32,"td"),e._uU(33),e.qZA(),e.qZA(),e.TgZ(34,"tr"),e.TgZ(35,"td",5),e.SDv(36,12),e.qZA(),e.TgZ(37,"td"),e._uU(38),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(39,"div",13),e.TgZ(40,"legend",2),e.SDv(41,14),e.qZA(),e._UZ(42,"cd-hosts",15),e.qZA(),e.qZA()),2&t&&(e.xp6(10),e.Oqu(o.hostsCount),e.xp6(15),e.Oqu(o.totalDevices),e.xp6(2),e.hij(" ",e.lcZ(28,11,o.totalCapacity),""),e.xp6(6),e.Oqu(o.totalCPUs),e.xp6(5),e.Oqu(o.totalMemory),e.xp6(4),e.Q6J("hiddenColumns",e.DdM(13,Fu))("hideToolHeader",!0)("hideTitle",!0)("hideSubmitBtn",!0)("hasTableDetails",!1)("showGeneralActionsOnly",!0))},directives:[lh],pipes:[mn.$],styles:["cd-hosts[_ngcontent-%COMP%] .nav{display:none}"]}),n})();const Am=["skipConfirmTpl"];function mu(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",3),e.TgZ(1,"div",4),e.TgZ(2,"div",5),e._UZ(3,"img",6),e.TgZ(4,"h3",7),e.SDv(5,8),e.qZA(),e.TgZ(6,"div",9),e.TgZ(7,"h4",10),e.SDv(8,11),e.qZA(),e.TgZ(9,"div",12),e.TgZ(10,"button",13),e.NdJ("click",function(){return e.CHM(t),e.oxw().createCluster()}),e.SDv(11,14),e.qZA(),e.TgZ(12,"button",15),e.NdJ("click",function(){return e.CHM(t),e.oxw().skipClusterCreation()}),e.SDv(13,16),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=e.oxw();e.xp6(3),e.Q6J("src",t.projectConstants.cephLogo,e.LSH),e.xp6(2),e.pQV(t.projectConstants.projectName),e.QtT(5)}}const Qo=function(){return["services"]};function Kl(n,s){1&n&&(e.TgZ(0,"div",29),e.TgZ(1,"h4",30),e.SDv(2,31),e.qZA(),e._UZ(3,"br"),e._UZ(4,"cd-hosts",32),e.qZA()),2&n&&(e.xp6(4),e.Q6J("hiddenColumns",e.DdM(5,Qo))("hideTitle",!0)("hideSubmitBtn",!0)("hasTableDetails",!1)("showGeneralActionsOnly",!0))}function lv(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",29),e.TgZ(1,"h4",30),e.SDv(2,33),e.qZA(),e.TgZ(3,"div",34),e.TgZ(4,"cd-osd-form",35),e.NdJ("emitDriveGroup",function(c){return e.CHM(t),e.oxw(2).setDriveGroup(c)})("emitDeploymentOption",function(c){return e.CHM(t),e.oxw(2).setDeploymentOptions(c)})("emitMode",function(c){return e.CHM(t),e.oxw(2).setDeploymentMode(c)}),e.qZA(),e.qZA(),e.qZA()}2&n&&(e.xp6(4),e.Q6J("hideTitle",!0)("hideSubmitBtn",!0))}const Wh=function(){return["mon","mgr","crash","agent"]},Sd=function(){return["status.running","status.size","status.last_refresh"]};function uv(n,s){1&n&&(e.TgZ(0,"div",29),e.TgZ(1,"h4",30),e.SDv(2,36),e.qZA(),e._UZ(3,"br"),e._UZ(4,"cd-services",37),e.qZA()),2&n&&(e.xp6(4),e.Q6J("hasDetails",!1)("hiddenServices",e.DdM(4,Wh))("hiddenColumns",e.DdM(5,Sd))("routedModal",!1))}function Cp(n,s){1&n&&(e.TgZ(0,"div",29),e._UZ(1,"cd-create-cluster-review"),e.qZA())}function Wf(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",17),e.TgZ(1,"div",18),e.SDv(2,19),e.qZA(),e.TgZ(3,"div",20),e._UZ(4,"cd-wizard",21),e.TgZ(5,"div",22),e.ynx(6,23),e.YNc(7,Kl,5,6,"div",24),e.YNc(8,lv,5,2,"div",24),e.YNc(9,uv,5,6,"div",24),e.YNc(10,Cp,2,0,"div",24),e.BQk(),e.qZA(),e.qZA(),e.TgZ(11,"div",25),e.TgZ(12,"button",26),e.NdJ("click",function(){return e.CHM(t),e.oxw().onNextStep()}),e.SDv(13,27),e.qZA(),e.TgZ(14,"cd-back-button",28),e.NdJ("backAction",function(){return e.CHM(t),e.oxw().onPreviousStep()}),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=e.oxw();e.xp6(4),e.Q6J("stepsTitle",t.stepTitles),e.xp6(2),e.Q6J("ngSwitch",null==t.currentStep?null:t.currentStep.stepIndex),e.xp6(1),e.Q6J("ngSwitchCase","1"),e.xp6(1),e.Q6J("ngSwitchCase","2"),e.xp6(1),e.Q6J("ngSwitchCase","3"),e.xp6(1),e.Q6J("ngSwitchCase","4"),e.xp6(3),e.pQV(t.showSubmitButtonLabel()),e.QtT(13),e.xp6(1),e.Q6J("name",t.showCancelButtonLabel())}}function cv(n,s){1&n&&(e.TgZ(0,"span"),e.tHW(1,38),e._UZ(2,"strong"),e.N_p(),e.qZA(),e.TgZ(3,"div",39),e.SDv(4,40),e.qZA())}let dv=(()=>{class n{constructor(t,o,c,g,C,D,P,j,W,re){this.authStorageService=t,this.wizardStepsService=o,this.router=c,this.hostService=g,this.notificationService=C,this.actionLabels=D,this.clusterService=P,this.modalService=j,this.taskWrapper=W,this.osdService=re,this.projectConstants=$i.$x,this.stepTitles=["Add Hosts","Create OSDs","Create Services","Review"],this.startClusterCreation=!1,this.observables=[],this.driveGroup=new Kd,this.driveGroups=[],this.selectedOption={},this.simpleDeployment=!0,this.submitAction=new e.vpe,this.permissions=this.authStorageService.getPermissions(),this.currentStepSub=this.wizardStepsService.getCurrentStep().subscribe(oe=>{this.currentStep=oe}),this.currentStep.stepIndex=1}ngOnInit(){this.osdService.getDeploymentOptions().subscribe(t=>{this.deploymentOption=t,this.selectedOption={option:t.recommended_option}})}createCluster(){this.startClusterCreation=!0}skipClusterCreation(){const t={titleText:"Warning",buttonText:"Continue",warning:!0,bodyTpl:this.skipConfirmTpl,showSubmit:!0,onSubmit:()=>{this.clusterService.updateStatus("POST_INSTALLED").subscribe({error:()=>this.modalRef.close(),complete:()=>{this.notificationService.show(pa.k.info,"Cluster expansion skipped by user"),this.router.navigate(["/dashboard"]),this.modalRef.close()}})}};this.modalRef=this.modalService.show(td.Y,t)}onSubmit(){var t;if(this.hostService.list("false").subscribe(o=>{o.forEach(c=>{const g=c.labels.indexOf("_no_schedule",0);g>-1&&(c.labels.splice(g,1),this.observables.push(this.hostService.update(c.hostname,!0,c.labels)))}),(0,xc.D)(this.observables).pipe((0,hf.x)(()=>this.clusterService.updateStatus("POST_INSTALLED").subscribe(()=>{this.notificationService.show(pa.k.success,"Cluster expansion was successful"),this.router.navigate(["/dashboard"])}))).subscribe({error:c=>c.preventDefault()})}),this.driveGroup){const o=this.authStorageService.getUsername();this.driveGroup.setName(`dashboard-${o}-${wr().now()}`),this.driveGroups.push(this.driveGroup.spec)}if(this.simpleDeployment){const o=null===(t=this.deploymentOption)||void 0===t?void 0:t.options[this.selectedOption.option].title,c="" + o + " deployment";this.taskWrapper.wrapTaskAroundCall({task:new cl.R("osd/"+$i.MQ.CREATE,{tracking_id:c}),call:this.osdService.create([this.selectedOption],c,"predefined")}).subscribe({error:g=>g.preventDefault(),complete:()=>{this.submitAction.emit()}})}else if(this.osdService.osdDevices.totalDevices>0){this.driveGroup.setFeature("encrypted",this.selectedOption.encrypted);const o=wr().join(wr().map(this.driveGroups,"service_id"),", ");this.taskWrapper.wrapTaskAroundCall({task:new cl.R("osd/"+$i.MQ.CREATE,{tracking_id:o}),call:this.osdService.create(this.driveGroups,o)}).subscribe({error:c=>c.preventDefault(),complete:()=>{this.submitAction.emit(),this.osdService.osdDevices=[]}})}}setDriveGroup(t){this.driveGroup=t}setDeploymentOptions(t){this.selectedOption=t}setDeploymentMode(t){this.simpleDeployment=t}onNextStep(){this.wizardStepsService.isLastStep()?this.onSubmit():(this.wizardStepsService.getCurrentStep().subscribe(t=>{this.currentStep=t}),this.wizardStepsService.moveToNextStep())}onPreviousStep(){this.wizardStepsService.isFirstStep()?this.router.navigate(["/dashboard"]):this.wizardStepsService.moveToPreviousStep()}showSubmitButtonLabel(){return this.wizardStepsService.isLastStep()?"Expand Cluster":this.actionLabels.NEXT}showCancelButtonLabel(){return this.wizardStepsService.isFirstStep()?this.actionLabels.CANCEL:this.actionLabels.BACK}ngOnDestroy(){this.currentStepSub.unsubscribe()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(vt.j),e.Y36(Yu),e.Y36(Bo.F0),e.Y36(Xl),e.Y36(hl.g),e.Y36($i.p4),e.Y36(wf),e.Y36(Bl.Z),e.Y36(Ll.P),e.Y36(Ji))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-create-cluster"]],viewQuery:function(t,o){if(1&t&&e.Gf(Am,7),2&t){let c;e.iGM(c=e.CRH())&&(o.skipConfirmTpl=c.first)}},outputs:{submitAction:"submitAction"},decls:4,vars:2,consts:function(){let s,t,o,c,g,C,D,P,j,W,re;return s="Welcome to " + "\ufffd0\ufffd" + "",t="Please expand your cluster first",o="Expand Cluster",c="Skip",g="Expand Cluster",C="" + "\ufffd0\ufffd" + "",D="Add Hosts",P="Create OSDs",j="Create Services",W="You are about to skip the cluster expansion process. You\u2019ll need to " + "\ufffd#2\ufffd" + "navigate through the menu to add hosts and services." + "\ufffd/#2\ufffd" + "",re="Are you sure you want to continue?",[["class","container h-75",4,"ngIf"],["class","card",4,"ngIf"],["skipConfirmTpl",""],[1,"container","h-75"],[1,"row","h-100","justify-content-center","align-items-center"],[1,"blank-page"],["alt","Ceph",1,"img-fluid","mx-auto","d-block",3,"src"],[1,"text-center","m-2"],s,[1,"m-4"],[1,"text-center"],t,[1,"offset-md-2"],["name","expand-cluster","aria-label","Expand Cluster",1,"btn","btn-accent","m-2",3,"click"],o,["name","skip-cluster-creation","aria-label","Skip",1,"btn","btn-light",3,"click"],c,[1,"card"],[1,"card-header"],g,[1,"container-fluid"],[3,"stepsTitle"],[1,"card-body","vertical-line"],[3,"ngSwitch"],["class","ml-5",4,"ngSwitchCase"],[1,"card-footer"],["aria-label","Next",1,"btn","btn-accent","m-2","float-right",3,"click"],C,["aria-label","Close",1,"m-2","float-right",3,"name","backAction"],[1,"ml-5"],[1,"title"],D,[3,"hiddenColumns","hideTitle","hideSubmitBtn","hasTableDetails","showGeneralActionsOnly"],P,[1,"alignForm"],[3,"hideTitle","hideSubmitBtn","emitDriveGroup","emitDeploymentOption","emitMode"],j,[3,"hasDetails","hiddenServices","hiddenColumns","routedModal"],W,[1,"mt-4"],re]},template:function(t,o){1&t&&(e.YNc(0,mu,14,2,"div",0),e.YNc(1,Wf,15,8,"div",1),e.YNc(2,cv,5,0,"ng-template",null,2,e.W1O)),2&t&&(e.Q6J("ngIf",!o.startClusterCreation),e.xp6(1),e.Q6J("ngIf",o.startClusterCreation))},directives:[_.O5,la.o,oc,_.RF,_.n9,hc.W,lh,p_,ef,s1],styles:[".container-fluid[_ngcontent-%COMP%]{align-items:flex-start;display:flex;padding-left:0;width:100%}cd-hosts[_ngcontent-%COMP%] .nav{display:none}cd-osd-form[_ngcontent-%COMP%] .card{border:0}cd-osd-form[_ngcontent-%COMP%] .accordion{margin-left:-1.5rem}"]}),n})();var Q_=i(83608),Om=i(46947);const jg=["tree"],fv=function(n,s,t){return[n,s,t]};function Mp(n,s){if(1&n&&e._UZ(0,"i",12),2&n){const t=e.oxw();e.Q6J("ngClass",e.kEZ(1,fv,t.icons.large,t.icons.spinner,t.icons.spin))}}const wm=function(){return["in","up"]},pv=function(){return["down","out","destroyed"]},a1=function(n,s){return{"badge-success":n,"badge-danger":s}};function Gg(n,s){if(1&n&&(e.TgZ(0,"span",15),e._uU(1),e.qZA()),2&n){const t=e.oxw().$implicit;e.Q6J("ngClass",e.WLB(4,a1,e.DdM(2,wm).includes(t.data.status),e.DdM(3,pv).includes(t.data.status))),e.xp6(1),e.hij(" ",t.data.status," ")}}const l1=function(n){return{"type-osd":n}};function hv(n,s){if(1&n&&(e.YNc(0,Gg,2,7,"span",13),e.TgZ(1,"span"),e._uU(2,"\xa0"),e.qZA(),e._UZ(3,"span",14)),2&n){const t=s.$implicit;e.Q6J("ngIf",t.data.status),e.xp6(3),e.Q6J("ngClass",e.VKq(3,l1,"osd"===t.data.type))("innerHTML",t.data.name,e.oJD)}}function u1(n,s){if(1&n&&(e.TgZ(0,"div",16),e.TgZ(1,"legend"),e._uU(2),e.qZA(),e._UZ(3,"cd-table-key-value",17),e.qZA()),2&n){const t=e.oxw();e.xp6(2),e.Oqu(t.metadataTitle),e.xp6(1),e.Q6J("data",t.metadata)}}let Cg=(()=>{class n{constructor(t,o){this.crushRuleService=t,this.timerService=o,this.sub=new _u.w,this.icons=xo.P,this.loadingIndicator=!0,this.nodes=[],this.treeOptions={useVirtualScroll:!0,nodeHeight:22,actionMapping:{mouse:{click:this.onNodeSelected.bind(this)}}},this.metadataKeyMap={}}ngOnInit(){this.sub=this.timerService.get(()=>this.crushRuleService.getInfo(),5e3).subscribe(t=>{this.loadingIndicator=!1,this.nodes=this.abstractTreeData(t)})}ngOnDestroy(){this.sub.unsubscribe()}abstractTreeData(t){const o=t.nodes||[],c=t.roots||[],g={};if(0===o.length)return[{name:"No nodes!"}];const C=[];return o.reverse().forEach(P=>{c.includes(P.id)&&C.push(P.id),g[P.id]=this.generateTreeLeaf(P,g)}),C.map(P=>g[P])}generateTreeLeaf(t,o){const c=t.id;this.metadataKeyMap[c]=t;const D=[],P={name:t.name+" ("+t.type+")",status:t.status,cdId:c,type:t.type};return t.children&&(t.children.sort().forEach(j=>{D.push(o[j])}),P.children=D),P}onNodeSelected(t,o){if(Nl.iM.ACTIVATE(t,o,!0),void 0!==o.data.cdId){const c=this.metadataKeyMap[o.data.cdId],{name:g,type:C}=c,P=(0,fa._T)(c,["name","type","status"]);this.metadata=P,this.metadataTitle=g+" ("+C+")"}else delete this.metadata,delete this.metadataTitle}onUpdateData(){this.tree.treeModel.expandAll()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Q_.H),e.Y36(Om.f))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-crushmap"]],viewQuery:function(t,o){if(1&t&&e.Gf(jg,5),2&t){let c;e.iGM(c=e.CRH())&&(o.tree=c.first)}},decls:14,vars:4,consts:function(){let s;return s="CRUSH map viewer",[[1,"row"],[1,"col-sm-12","col-lg-12"],[1,"card"],[1,"card-header"],s,[1,"card-body"],[1,"col-sm-6","col-lg-6","tree-container"],[3,"ngClass",4,"ngIf"],[3,"nodes","options","updateData"],["tree",""],["treeNodeTemplate",""],["class","col-sm-6 col-lg-6 metadata",4,"ngIf"],[3,"ngClass"],["class","badge",3,"ngClass",4,"ngIf"],[1,"node-name",3,"ngClass","innerHTML"],[1,"badge",3,"ngClass"],[1,"col-sm-6","col-lg-6","metadata"],[3,"data"]]},template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"div",1),e.TgZ(2,"div",2),e.TgZ(3,"div",3),e.SDv(4,4),e.qZA(),e.TgZ(5,"div",5),e.TgZ(6,"div",0),e.TgZ(7,"div",6),e.YNc(8,Mp,1,5,"i",7),e.TgZ(9,"tree-root",8,9),e.NdJ("updateData",function(){return o.onUpdateData()}),e.YNc(11,hv,4,5,"ng-template",null,10,e.W1O),e.qZA(),e.qZA(),e.YNc(13,u1,4,2,"div",11),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()),2&t&&(e.xp6(8),e.Q6J("ngIf",o.loadingIndicator),e.xp6(1),e.Q6J("nodes",o.nodes)("options",o.treeOptions),e.xp6(4),e.Q6J("ngIf",o.metadata))},directives:[_.O5,Nl.qr,_.mk,zr.b],styles:[".tree-container[_ngcontent-%COMP%]{height:calc(100vh - 200px)}"]}),n})(),Ap=(()=>{class n{constructor(t){this.http=t}getLogs(){return this.http.get("api/logs/all")}validateDashboardUrl(t){return this.http.get(`api/grafana/validation/${t}`)}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(y.eN))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();var ip=i(49457);let Jh=(()=>{class n{download(t,o){(0,ip.saveAs)(new Blob([t]),o)}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();const Vp=function(n){return[n]};function X_(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"button",5),e.NdJ("click",function(){return e.CHM(t),e.oxw().download("json")}),e._UZ(1,"i",2),e.TgZ(2,"span"),e._uU(3,"JSON"),e.qZA(),e.qZA()}if(2&n){const t=e.oxw();e.xp6(1),e.Q6J("ngClass",e.VKq(1,Vp,t.icons.json))}}function C_(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"button",5),e.NdJ("click",function(){return e.CHM(t),e.oxw().download()}),e._UZ(1,"i",2),e.TgZ(2,"span"),e._uU(3,"Text"),e.qZA(),e.qZA()}if(2&n){const t=e.oxw();e.xp6(1),e.Q6J("ngClass",e.VKq(1,Vp,t.icons.text))}}let xm=(()=>{class n{constructor(t){this.textToDownloadService=t,this.title="Download",this.icons=xo.P}download(t){this.fileName=`${this.fileName}_${(new Date).toLocaleDateString()}`,"json"===t?this.textToDownloadService.download(JSON.stringify(this.objectItem,null,2),`${this.fileName}.json`):this.textToDownloadService.download(this.textItem,`${this.fileName}.txt`)}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Jh))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-download-button"]],inputs:{objectItem:"objectItem",textItem:"textItem",fileName:"fileName",title:"title"},decls:6,vars:6,consts:[["ngbDropdown","","placement","bottom-right"],["type","button","ngbDropdownToggle","",1,"btn","btn-light","dropdown-toggle-split",3,"title"],[3,"ngClass"],["ngbDropdownMenu",""],["ngbDropdownItem","",3,"click",4,"ngIf"],["ngbDropdownItem","",3,"click"]],template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"button",1),e._UZ(2,"i",2),e.qZA(),e.TgZ(3,"div",3),e.YNc(4,X_,4,3,"button",4),e.YNc(5,C_,4,3,"button",4),e.qZA(),e.qZA()),2&t&&(e.xp6(1),e.Q6J("title",o.title),e.xp6(1),e.Q6J("ngClass",e.VKq(4,Vp,o.icons.download)),e.xp6(2),e.Q6J("ngIf",o.objectItem),e.xp6(1),e.Q6J("ngIf",o.textItem))},directives:[ut.jt,la.o,ut.iD,_.mk,ut.Vi,_.O5,ut.TH],styles:[""]}),n})();var Dm=i(42746);let c1=(()=>{class n{transform(t,o){if(!o)return t;o=this.escapeRegExp(o);const c=new RegExp(o,"gi");return t.match(c)?t.replace(c,"<mark>$&</mark>"):t}escapeRegExp(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275pipe=e.Yjl({name:"searchHighlight",type:n,pure:!0}),n})();function Rm(n,s){1&n&&e.GkF(0)}function Vg(n,s){if(1&n&&(e.TgZ(0,"div",19),e._UZ(1,"cd-download-button",20),e._UZ(2,"cd-copy-2-clipboard-button",21),e.qZA()),2&n){const t=e.oxw(4);e.xp6(1),e.Q6J("objectItem",t.clog)("textItem",t.clogText),e.xp6(1),e.Q6J("source",t.clogText)("byId",!1)}}function _v(n,s){if(1&n&&(e.TgZ(0,"p"),e.TgZ(1,"span",22),e._uU(2),e.ALo(3,"cdDate"),e.qZA(),e.TgZ(4,"span"),e.ALo(5,"logPriority"),e._uU(6),e.qZA(),e._UZ(7,"span",23),e.ALo(8,"searchHighlight"),e.qZA()),2&n){const t=s.$implicit,o=e.oxw(4);e.xp6(2),e.Oqu(e.lcZ(3,6,t.stamp)),e.xp6(2),e.Gre("priority ",e.lcZ(5,8,t.priority),""),e.xp6(2),e.Oqu(t.priority),e.xp6(1),e.Q6J("innerHTML",e.xi3(8,10,t.message,o.search),e.oJD)}}function zg(n,s){1&n&&e.GkF(0)}function I(n,s){if(1&n&&(e.TgZ(0,"div",14),e.YNc(1,Vg,3,4,"div",15),e.TgZ(2,"div",16),e.YNc(3,_v,9,13,"p",17),e.YNc(4,zg,1,0,"ng-container",18),e.qZA(),e.qZA()),2&n){const t=e.oxw(3),o=e.MAs(4);e.xp6(1),e.Q6J("ngIf",t.clog.length),e.xp6(2),e.Q6J("ngForOf",t.clog),e.xp6(1),e.Q6J("ngIf",0!=t.clog.length)("ngIfElse",o)}}function z(n,s){if(1&n&&e.YNc(0,I,5,4,"div",13),2&n){const t=e.oxw(2);e.Q6J("ngIf",t.clog)}}function B(n,s){if(1&n&&(e.TgZ(0,"div",19),e._UZ(1,"cd-download-button",24),e._UZ(2,"cd-copy-2-clipboard-button",21),e.qZA()),2&n){const t=e.oxw(4);e.xp6(1),e.Q6J("objectItem",t.audit_log)("textItem",t.auditLogText),e.xp6(1),e.Q6J("source",t.auditLogText)("byId",!1)}}function be(n,s){if(1&n&&(e.TgZ(0,"p"),e.TgZ(1,"span",22),e._uU(2),e.ALo(3,"cdDate"),e.qZA(),e.TgZ(4,"span"),e.ALo(5,"logPriority"),e._uU(6),e.qZA(),e._UZ(7,"span",23),e.ALo(8,"searchHighlight"),e.qZA()),2&n){const t=s.$implicit,o=e.oxw(4);e.xp6(2),e.Oqu(e.lcZ(3,6,t.stamp)),e.xp6(2),e.Gre("priority ",e.lcZ(5,8,t.priority),""),e.xp6(2),e.Oqu(t.priority),e.xp6(1),e.Q6J("innerHTML",e.xi3(8,10,t.message,o.search),e.oJD)}}function at(n,s){1&n&&e.GkF(0)}function $t(n,s){if(1&n&&(e.TgZ(0,"div",14),e.YNc(1,B,3,4,"div",15),e.TgZ(2,"div",16),e.YNc(3,be,9,13,"p",17),e.YNc(4,at,1,0,"ng-container",18),e.qZA(),e.qZA()),2&n){const t=e.oxw(3),o=e.MAs(4);e.xp6(1),e.Q6J("ngIf",t.audit_log.length),e.xp6(2),e.Q6J("ngForOf",t.audit_log),e.xp6(1),e.Q6J("ngIf",0!=t.audit_log.length)("ngIfElse",o)}}function jn(n,s){if(1&n&&e.YNc(0,$t,5,4,"div",13),2&n){const t=e.oxw(2);e.Q6J("ngIf",t.audit_log)}}function fr(n,s){if(1&n&&(e.TgZ(0,"div"),e.YNc(1,Rm,1,0,"ng-container",3),e.TgZ(2,"ul",4,5),e.TgZ(4,"li",6),e.TgZ(5,"a",7),e.SDv(6,8),e.qZA(),e.YNc(7,z,1,1,"ng-template",9),e.qZA(),e.TgZ(8,"li",10),e.TgZ(9,"a",7),e.SDv(10,11),e.qZA(),e.YNc(11,jn,1,1,"ng-template",9),e.qZA(),e.qZA(),e._UZ(12,"div",12),e.qZA()),2&n){const t=e.MAs(3);e.oxw();const o=e.MAs(2);e.xp6(1),e.Q6J("ngTemplateOutlet",o),e.xp6(11),e.Q6J("ngbNavOutlet",t)}}function ui(n,s){if(1&n&&(e.TgZ(0,"option",46),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t.value),e.xp6(1),e.Oqu(t.name)}}const Ro=function(n){return[n]};function Vo(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",25),e.TgZ(1,"div",26),e.TgZ(2,"label",27),e.SDv(3,28),e.qZA(),e.TgZ(4,"select",29),e.NdJ("ngModelChange",function(c){return e.CHM(t),e.oxw().priority=c})("ngModelChange",function(){return e.CHM(t),e.oxw().filterLogs()}),e.YNc(5,ui,2,2,"option",30),e.qZA(),e.qZA(),e.TgZ(6,"div",26),e.TgZ(7,"label",31),e.SDv(8,32),e.qZA(),e.TgZ(9,"div",33),e.TgZ(10,"div",34),e.TgZ(11,"span",35),e._UZ(12,"i",36),e.qZA(),e.qZA(),e.TgZ(13,"input",37),e.NdJ("ngModelChange",function(c){return e.CHM(t),e.oxw().search=c})("keyup",function(){return e.CHM(t),e.oxw().filterLogs()}),e.qZA(),e.TgZ(14,"div",38),e.TgZ(15,"button",39),e.NdJ("click",function(){return e.CHM(t),e.oxw().clearSearchKey()}),e._UZ(16,"i"),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(17,"div",26),e.TgZ(18,"label",40),e.SDv(19,41),e.qZA(),e.TgZ(20,"div",33),e.TgZ(21,"input",42,43),e.NdJ("click",function(){return e.CHM(t),e.MAs(22).open()})("ngModelChange",function(c){return e.CHM(t),e.oxw().selectedDate=c})("ngModelChange",function(){return e.CHM(t),e.oxw().filterLogs()}),e.qZA(),e.TgZ(23,"span",38),e.TgZ(24,"button",39),e.NdJ("click",function(){return e.CHM(t),e.oxw().clearDate()}),e._UZ(25,"i"),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(26,"div",26),e.TgZ(27,"label"),e.SDv(28,44),e.qZA(),e.TgZ(29,"ngb-timepicker",45),e.NdJ("ngModelChange",function(c){return e.CHM(t),e.oxw().startTime=c})("ngModelChange",function(){return e.CHM(t),e.oxw().filterLogs()}),e.qZA(),e.TgZ(30,"span"),e._uU(31,"\xa0\u2014\xa0"),e.qZA(),e.TgZ(32,"ngb-timepicker",45),e.NdJ("ngModelChange",function(c){return e.CHM(t),e.oxw().endTime=c})("ngModelChange",function(){return e.CHM(t),e.oxw().filterLogs()}),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=e.oxw();e.xp6(4),e.Q6J("ngModel",t.priority),e.xp6(1),e.Q6J("ngForOf",t.priorities),e.xp6(7),e.Q6J("ngClass",e.VKq(16,Ro,t.icons.search)),e.xp6(1),e.Q6J("ngModel",t.search),e.xp6(3),e.Gre("icon-prepend ",t.icons.destroy,""),e.xp6(5),e.Q6J("maxDate",t.maxDate)("ngModel",t.selectedDate),e.xp6(4),e.Gre("icon-prepend ",t.icons.destroy,""),e.xp6(4),e.Q6J("spinners",!1)("ngModel",t.startTime),e.xp6(3),e.Q6J("spinners",!1)("ngModel",t.endTime)}}function Ms(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"span"),e.SDv(1,47),e.qZA(),e.TgZ(2,"span"),e._uU(3,"\xa0"),e.qZA(),e.TgZ(4,"a",48),e.NdJ("click",function(){return e.CHM(t),e.oxw().resetFilter()}),e.SDv(5,49),e.qZA()}}let Dl=(()=>{class n{constructor(t,o,c){this.logsService=t,this.datePipe=o,this.ngZone=c,this.icons=xo.P,this.priorities=[{name:"Debug",value:"[DBG]"},{name:"Info",value:"[INF]"},{name:"Warning",value:"[WRN]"},{name:"Error",value:"[ERR]"},{name:"All",value:"All"}],this.priority="All",this.search="",this.startTime={hour:0,minute:0},this.endTime={hour:23,minute:59},this.maxDate={year:(new Date).getFullYear(),month:(new Date).getMonth()+1,day:(new Date).getDate()}}ngOnInit(){this.getInfo(),this.ngZone.runOutsideAngular(()=>{this.interval=window.setInterval(()=>{this.ngZone.run(()=>{this.getInfo()})},5e3)})}ngOnDestroy(){clearInterval(this.interval)}getInfo(){this.logsService.getLogs().subscribe(t=>{this.contentData=t,this.clogText=this.logToText(this.contentData.clog),this.auditLogText=this.logToText(this.contentData.audit_log),this.filterLogs()})}abstractFilters(){var t,o,c,g,C,D,P,j;const W=this.priority,re=this.search.toLowerCase();let oe;if(this.selectedDate){const U=this.selectedDate.month,pt=this.selectedDate.day;oe=`${this.selectedDate.year}-${U<=9?`0${U}`:`${U}`}-${pt<=9?`0${pt}`:`${pt}`}`}else oe="";return{priority:W,key:re,yearMonthDay:oe,sTime:60*(null!==(o=null===(t=this.startTime)||void 0===t?void 0:t.hour)&&void 0!==o?o:0)+(null!==(g=null===(c=this.startTime)||void 0===c?void 0:c.minute)&&void 0!==g?g:0),eTime:60*(null!==(D=null===(C=this.endTime)||void 0===C?void 0:C.hour)&&void 0!==D?D:23)+(null!==(j=null===(P=this.endTime)||void 0===P?void 0:P.minute)&&void 0!==j?j:59)}}filterExecutor(t,o){return t.filter(c=>{const g=this.datePipe.transform(c.stamp,"mediumTime"),C=parseInt(g.split(":")[0],10),D=parseInt(g.split(":")[1],10);let P,j,W;return P="All"===o.priority?c.priority:o.priority,j=o.yearMonthDay?o.yearMonthDay:c.stamp,W=60*C+D,c.priority===P&&-1!==c.message.toLowerCase().indexOf(o.key)&&-1!==c.stamp.indexOf(j)&&W>=o.sTime&&W<=o.eTime})}filterLogs(){const t=this.abstractFilters();this.clog=this.filterExecutor(this.contentData.clog,t),this.audit_log=this.filterExecutor(this.contentData.audit_log,t)}clearSearchKey(){this.search="",this.filterLogs()}clearDate(){this.selectedDate=null,this.filterLogs()}resetFilter(){return this.priority="All",this.search="",this.selectedDate=null,this.startTime={hour:0,minute:0},this.endTime={hour:23,minute:59},this.filterLogs(),!1}logToText(t){let o="";for(const c of Object.keys(t))o=o+this.datePipe.transform(t[c].stamp,"medium")+"\t"+t[c].priority+"\t"+t[c].message+"\n";return o}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Ap),e.Y36(_.uU),e.Y36(e.R0b))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-logs"]],decls:5,vars:1,consts:function(){let s,t,o,c,g,C,D,P;return s="Cluster Logs",t="Audit Logs",o="Priority:",c="Keyword:",g="Date:",C="Time range:",D="No log entries found. Please try to select different filter options.",P="Reset filter.",[[4,"ngIf"],["logFiltersTpl",""],["noEntriesTpl",""],[4,"ngTemplateOutlet"],["ngbNav","","cdStatefulTab","logs",1,"nav-tabs"],["nav","ngbNav"],["ngbNavItem","cluster-logs"],["ngbNavLink",""],s,["ngbNavContent",""],["ngbNavItem","audit-logs"],t,[3,"ngbNavOutlet"],["class","card bg-light mb-3",4,"ngIf"],[1,"card","bg-light","mb-3"],["class","btn-group","role","group",4,"ngIf"],[1,"card-body"],[4,"ngFor","ngForOf"],[4,"ngIf","ngIfElse"],["role","group",1,"btn-group"],["fileName","cluster_log",3,"objectItem","textItem"],[3,"source","byId"],[1,"timestamp"],[1,"message",3,"innerHTML"],["fileName","audit_log",3,"objectItem","textItem"],[1,"form-inline"],[1,"form-group"],["for","logs-priority"],o,["id","logs-priority",1,"form-control",3,"ngModel","ngModelChange"],[3,"value",4,"ngFor","ngForOf"],["for","logs-keyword"],c,[1,"input-group"],[1,"input-group-prepend"],[1,"input-group-text"],[3,"ngClass"],["id","logs-keyword","type","text",1,"form-control",3,"ngModel","ngModelChange","keyup"],[1,"input-group-append"],["type","button",1,"btn","btn-light",3,"click"],["for","logs-date"],g,["id","logs-date","placeholder","YYYY-MM-DD","ngbDatepicker","",1,"form-control",3,"maxDate","ngModel","click","ngModelChange"],["d","ngbDatepicker"],C,[3,"spinners","ngModel","ngModelChange"],[3,"value"],D,["href","#",3,"click"],P]},template:function(t,o){1&t&&(e.YNc(0,fr,13,2,"div",0),e.YNc(1,Vo,33,18,"ng-template",null,1,e.W1O),e.YNc(3,Ms,6,0,"ng-template",null,2,e.W1O)),2&t&&e.Q6J("ngIf",o.contentData)},directives:[_.O5,_.tP,ut.Pz,un.m,ut.nv,ut.Vx,ut.uN,ut.tO,_.sg,xm,Bc.s,Za.P,la.o,Mn.EJ,ja.b,Mn.JJ,Mn.On,_.mk,Mn.Fj,ut.J4,ut.Pm,Mn.YN,Mn.Kr],pipes:[Ul.N,Dm.e,c1],styles:["p[_ngcontent-%COMP%]{font-family:monospace}.card[_ngcontent-%COMP%] .btn-group[_ngcontent-%COMP%]{margin-top:-45px;position:absolute;right:0}.card[_ngcontent-%COMP%] div[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{display:flex}.card[_ngcontent-%COMP%] div[_ngcontent-%COMP%] p[_ngcontent-%COMP%]:last-child{margin-bottom:0}.card[_ngcontent-%COMP%] .timestamp[_ngcontent-%COMP%]{flex-shrink:0;font-weight:bold}.card[_ngcontent-%COMP%] .priority[_ngcontent-%COMP%]{margin-left:.5rem}.card[_ngcontent-%COMP%] .message[_ngcontent-%COMP%]{margin-left:1rem}.card[_ngcontent-%COMP%] .err[_ngcontent-%COMP%]{color:#ef5c55}.card[_ngcontent-%COMP%] .warn[_ngcontent-%COMP%]{color:#ffc200}.card[_ngcontent-%COMP%] .info[_ngcontent-%COMP%]{color:#2b99a8}.card[_ngcontent-%COMP%] .debug[_ngcontent-%COMP%]{color:#495057} cd-logs ngb-timepicker input.ngb-tp-input{width:3.5rem!important}"]}),n})();var ql=i(7273);function eu(n,s){if(1&n&&(e.TgZ(0,"cd-helper"),e._uU(1),e.ALo(2,"upperFirst"),e.qZA()),2&n){const t=e.oxw().$implicit;e.xp6(1),e.hij(" ",e.lcZ(2,1,t.value.long_desc||t.value.desc)," ")}}function Ku(n,s){if(1&n&&(e.TgZ(0,"div",15),e.TgZ(1,"div",16),e._UZ(2,"input",17),e._UZ(3,"label",18),e.qZA(),e.qZA()),2&n){const t=e.oxw().$implicit;e.xp6(2),e.s9C("id",t.value.name),e.s9C("formControlName",t.value.name),e.xp6(1),e.s9C("for",t.value.name)}}function Zd(n,s){if(1&n&&e._UZ(0,"input",22),2&n){const t=e.oxw(2).$implicit;e.s9C("id",t.value.name),e.s9C("formControlName",t.value.name)}}function Cd(n,s){if(1&n&&(e.TgZ(0,"option",25),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("ngValue",t),e.xp6(1),e.hij(" ",t," ")}}function Op(n,s){if(1&n&&(e.TgZ(0,"select",23),e.YNc(1,Cd,2,2,"option",24),e.qZA()),2&n){const t=e.oxw(2).$implicit;e.s9C("id",t.value.name),e.s9C("formControlName",t.value.name),e.xp6(1),e.Q6J("ngForOf",t.value.enum_allowed)}}function K_(n,s){1&n&&(e.TgZ(0,"span",26),e.SDv(1,27),e.qZA())}function q_(n,s){1&n&&(e.TgZ(0,"span",26),e.SDv(1,28),e.qZA())}function tf(n,s){if(1&n&&(e.TgZ(0,"div",15),e.YNc(1,Zd,1,2,"input",19),e.YNc(2,Op,2,3,"select",20),e.YNc(3,K_,2,0,"span",21),e.YNc(4,q_,2,0,"span",21),e.qZA()),2&n){const t=e.oxw().$implicit;e.oxw();const o=e.MAs(2),c=e.oxw();e.xp6(1),e.Q6J("ngIf",0===t.value.enum_allowed.length),e.xp6(1),e.Q6J("ngIf",t.value.enum_allowed.length>0),e.xp6(1),e.Q6J("ngIf",c.mgrModuleForm.showError(t.value.name,o,"invalidUuid")),e.xp6(1),e.Q6J("ngIf",c.mgrModuleForm.showError(t.value.name,o,"pattern"))}}function Qc(n,s){1&n&&(e.TgZ(0,"span",26),e.SDv(1,30),e.qZA())}function wp(n,s){if(1&n&&(e.TgZ(0,"span",26),e.SDv(1,31),e.qZA()),2&n){const t=e.oxw(2).$implicit;e.xp6(1),e.pQV(t.value.max),e.QtT(1)}}function ju(n,s){if(1&n&&(e.TgZ(0,"span",26),e.SDv(1,32),e.qZA()),2&n){const t=e.oxw(2).$implicit;e.xp6(1),e.pQV(t.value.min),e.QtT(1)}}function Ic(n,s){1&n&&(e.TgZ(0,"span",26),e.SDv(1,33),e.qZA())}function D0(n,s){if(1&n&&(e.TgZ(0,"div",15),e._UZ(1,"input",29),e.YNc(2,Qc,2,0,"span",21),e.YNc(3,wp,2,1,"span",21),e.YNc(4,ju,2,1,"span",21),e.YNc(5,Ic,2,0,"span",21),e.qZA()),2&n){const t=e.oxw().$implicit;e.oxw();const o=e.MAs(2),c=e.oxw();e.xp6(1),e.s9C("id",t.value.name),e.s9C("formControlName",t.value.name),e.s9C("min",t.value.min),e.s9C("max",t.value.max),e.xp6(1),e.Q6J("ngIf",c.mgrModuleForm.showError(t.value.name,o,"required")),e.xp6(1),e.Q6J("ngIf",c.mgrModuleForm.showError(t.value.name,o,"max")),e.xp6(1),e.Q6J("ngIf",c.mgrModuleForm.showError(t.value.name,o,"min")),e.xp6(1),e.Q6J("ngIf",c.mgrModuleForm.showError(t.value.name,o,"pattern"))}}function R0(n,s){1&n&&(e.TgZ(0,"span",26),e.SDv(1,35),e.qZA())}function N0(n,s){1&n&&(e.TgZ(0,"span",26),e.SDv(1,36),e.qZA())}function gb(n,s){if(1&n&&(e.TgZ(0,"div",15),e._UZ(1,"input",34),e.YNc(2,R0,2,0,"span",21),e.YNc(3,N0,2,0,"span",21),e.qZA()),2&n){const t=e.oxw().$implicit;e.oxw();const o=e.MAs(2),c=e.oxw();e.xp6(1),e.s9C("id",t.value.name),e.s9C("formControlName",t.value.name),e.xp6(1),e.Q6J("ngIf",c.mgrModuleForm.showError(t.value.name,o,"required")),e.xp6(1),e.Q6J("ngIf",c.mgrModuleForm.showError(t.value.name,o,"pattern"))}}const Qh=function(){return["addr","str","uuid"]},d1=function(){return["uint","int","size","secs"]};function mb(n,s){if(1&n&&(e.TgZ(0,"div",11),e.TgZ(1,"label",12),e._uU(2),e.YNc(3,eu,3,3,"cd-helper",13),e.qZA(),e.YNc(4,Ku,4,3,"div",14),e.YNc(5,tf,5,4,"div",14),e.YNc(6,D0,6,8,"div",14),e.YNc(7,gb,4,4,"div",14),e.qZA()),2&n){const t=s.$implicit;e.xp6(1),e.s9C("for",t.value.name),e.xp6(1),e.hij(" ",t.value.name," "),e.xp6(1),e.Q6J("ngIf",t.value.long_desc||t.value.desc),e.xp6(1),e.Q6J("ngIf","bool"===t.value.type),e.xp6(1),e.Q6J("ngIf",e.DdM(7,Qh).includes(t.value.type)),e.xp6(1),e.Q6J("ngIf",e.DdM(8,d1).includes(t.value.type)),e.xp6(1),e.Q6J("ngIf","float"===t.value.type)}}function P0(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",1),e.TgZ(1,"form",2,3),e.TgZ(3,"div",4),e.TgZ(4,"div",5),e.SDv(5,6),e.qZA(),e.TgZ(6,"div",7),e.YNc(7,mb,8,9,"div",8),e.ALo(8,"keyvalue"),e.qZA(),e.TgZ(9,"div",9),e.TgZ(10,"cd-form-button-panel",10),e.NdJ("submitActionEvent",function(){return e.CHM(t),e.oxw().onSubmit()}),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=e.oxw();e.xp6(1),e.Q6J("formGroup",t.mgrModuleForm),e.xp6(6),e.Q6J("ngForOf",e.lcZ(8,4,t.moduleOptions)),e.xp6(3),e.Q6J("form",t.mgrModuleForm)("submitText",t.actionLabels.UPDATE)}}let gv=(()=>{class n extends Oa.E{constructor(t,o,c,g,C,D){super(),this.actionLabels=t,this.route=o,this.router=c,this.formBuilder=g,this.mgrModuleService=C,this.notificationService=D,this.moduleName="",this.moduleOptions=[]}ngOnInit(){this.route.params.subscribe(t=>{this.moduleName=decodeURIComponent(t.name);const o=[this.mgrModuleService.getOptions(this.moduleName),this.mgrModuleService.getConfig(this.moduleName)];(0,xc.D)(o).subscribe(c=>{this.moduleOptions=c[0],this.createForm(),this.mgrModuleForm.setValue(c[1]),this.loadingReady()},c=>{this.loadingError()})})}getValidators(t){const o=[];switch(t.type){case"addr":o.push(ss.h.ip());break;case"uint":case"int":case"size":case"secs":o.push(Mn.kI.required);break;case"str":wr().isNumber(t.min)&&o.push(Mn.kI.minLength(t.min)),wr().isNumber(t.max)&&o.push(Mn.kI.maxLength(t.max));break;case"float":o.push(Mn.kI.required),o.push(ss.h.decimalNumber());break;case"uuid":o.push(ss.h.uuid())}return o}createForm(){const t={};wr().forEach(this.moduleOptions,o=>{t[o.name]=[o.default_value,this.getValidators(o)]}),this.mgrModuleForm=this.formBuilder.group(t)}goToListView(){this.router.navigate(["/mgr-modules"])}onSubmit(){if(this.mgrModuleForm.pristine)return void this.goToListView();const t={};wr().forEach(this.moduleOptions,o=>{const c=this.mgrModuleForm.get(o.name);c.dirty&&c.valid&&(t[o.name]=c.value)}),this.mgrModuleService.updateConfig(this.moduleName,t).subscribe(()=>{this.notificationService.show(pa.k.success,"Updated options for module '" + this.moduleName + "'."),this.goToListView()},()=>{this.mgrModuleForm.setErrors({cdSubmitButton:!0})})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36($i.p4),e.Y36(Bo.gz),e.Y36(Bo.F0),e.Y36(rd.O),e.Y36(ql.N),e.Y36(hl.g))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-mgr-module-form"]],features:[e.qOj],decls:1,vars:1,consts:function(){let s,t,o,c,g,C,D,P,j;return s="Edit Manager module",t="The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8",o="The entered value needs to be a valid IP address.",c="This field is required.",g="The entered value is too high! It must be lower or equal to " + "\ufffd0\ufffd" + ".",C="The entered value is too low! It must be greater or equal to " + "\ufffd0\ufffd" + ".",D="The entered value needs to be a number.",P="This field is required.",j="The entered value needs to be a number or decimal.",[["class","cd-col-form",4,"cdFormLoading"],[1,"cd-col-form"],["name","mgrModuleForm","novalidate","",3,"formGroup"],["frm","ngForm"],[1,"card"],[1,"card-header"],s,[1,"card-body"],["class","form-group row",4,"ngFor","ngForOf"],[1,"card-footer"],["wrappingClass","text-right",3,"form","submitText","submitActionEvent"],[1,"form-group","row"],[1,"cd-col-form-label",3,"for"],[4,"ngIf"],["class","cd-col-form-input",4,"ngIf"],[1,"cd-col-form-input"],[1,"custom-control","custom-checkbox"],["type","checkbox",1,"custom-control-input",3,"id","formControlName"],[1,"custom-control-label",3,"for"],["class","form-control","type","text",3,"id","formControlName",4,"ngIf"],["class","form-control",3,"id","formControlName",4,"ngIf"],["class","invalid-feedback",4,"ngIf"],["type","text",1,"form-control",3,"id","formControlName"],[1,"form-control",3,"id","formControlName"],[3,"ngValue",4,"ngFor","ngForOf"],[3,"ngValue"],[1,"invalid-feedback"],t,o,["type","number",1,"form-control",3,"id","formControlName","min","max"],c,g,C,D,["type","number",1,"form-control",3,"id","formControlName"],P,j]},template:function(t,o){1&t&&e.YNc(0,P0,11,6,"div",0),2&t&&e.Q6J("cdFormLoading",o.loading)},directives:[Ol.y,Mn._Y,Mn.JL,Mn.sg,ll.V,_.sg,ul.p,Za.P,_.O5,h.S,la.o,Mn.Wl,ja.b,Mn.JJ,Mn.u,Mn.Fj,Mn.EJ,Mn.YN,Mn.Kr,Mn.wV,Mn.qQ,Mn.Fd],pipes:[_.Nd,F.m],styles:[""]}),n})();function Gu(n,s,t,o){var C,c=arguments.length,g=c<3?s:null===o?o=Object.getOwnPropertyDescriptor(s,t):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)g=Reflect.decorate(n,s,t,o);else for(var D=n.length-1;D>=0;D--)(C=n[D])&&(g=(c<3?C(g):c>3?C(s,t,g):C(s,t))||g);return c>3&&g&&Object.defineProperty(s,t,g),g}var vv=i(80226);const Eb=["*"],Tb=["templateOutlet"];function yS(n,s){if(1&n&&(e.TgZ(0,"div",6),e._uU(1),e.qZA()),2&n){const t=e.oxw(2);e.xp6(1),e.hij(" ",t.message||t.defaultMessage," ")}}function Jg(n,s){if(1&n&&(e.TgZ(0,"div",3),e._UZ(1,"div",4),e.YNc(2,yS,2,1,"div",5),e.qZA()),2&n){const t=e.oxw();e.xp6(2),e.Q6J("ngIf",t.message||t.defaultMessage)}}function k0(n,s){}function Im(n,s){1&n&&e.YNc(0,k0,0,0,"ng-template",null,7,e.W1O)}const Lm=function(n){return{active:n}};let pd=(()=>{class n{}return n.START="start",n.STOP="stop",n.UPDATE="update",n.RESET="reset",n.RESET_GLOBAL="reset_global",n.UNSUBSCRIBE="unsubscribe",n})();const Mg="block-ui-main";let Ag=(()=>{let n=class{constructor(){this.blockUISettings={},this.blockUIInstances={},this.blockUISubject=new vv.t(1),this.blockUIObservable=this.blockUISubject.asObservable(),this.blockUIObservable.subscribe(this.blockUIMiddleware.bind(this))}getSettings(){return this.blockUISettings}updateSettings(t={}){this.blockUISettings=Object.assign(Object.assign({},this.blockUISettings),t)}decorate(t=Mg){const o={name:t,isActive:!1,blockCount:0,start:this.dispatch(this.blockUISubject,pd.START,t),update:this.dispatch(this.blockUISubject,pd.UPDATE,t),stop:this.dispatch(this.blockUISubject,pd.STOP,t),reset:this.dispatch(this.blockUISubject,pd.RESET,t),resetGlobal:this.dispatch(this.blockUISubject,pd.RESET_GLOBAL,t),unsubscribe:this.dispatch(this.blockUISubject,pd.UNSUBSCRIBE,t)};return this.blockUIInstances[t]=this.blockUIInstances[t]||o,o}observe(){return this.blockUIObservable}clearInstance(t){this.dispatch(this.blockUISubject,pd.RESET,t)}blockUIMiddleware({action:t,name:o}){let c=null;switch(t){case pd.START:c=!0;break;case pd.STOP:case pd.RESET:c=!1}null!==c&&(this.blockUIInstances[o].isActive=c)}dispatch(t,o,c=Mg){return g=>{t.next({name:c,action:o,message:g})}}};return n.\u0275fac=function(t){return new(t||n)},n.\u0275prov=e.Yz7({token:n,factory:function(s){return n.\u0275fac(s)}}),n})(),_1=(()=>{let n=class{constructor(t){this.blockUI=t}ngOnInit(){this.name=this.name||Mg,this.template=this.template||this.blockUI.blockUISettings.template}};return n.\u0275fac=function(t){return new(t||n)(e.Y36(Ag))},n.\u0275cmp=e.Xpm({type:n,selectors:[["block-ui"]],inputs:{name:"name",template:"template",message:"message",delayStart:"delayStart",delayStop:"delayStop"},ngContentSelectors:Eb,decls:2,vars:5,consts:[[3,"name","message","template","delayStart","delayStop"]],template:function(t,o){1&t&&(e.F$t(),e.Hsn(0),e._UZ(1,"block-ui-content",0)),2&t&&(e.xp6(1),e.Q6J("name",o.name)("message",o.message)("template",o.template)("delayStart",o.delayStart)("delayStop",o.delayStop))},directives:function(){return[yv]},encapsulation:2}),Gu([(0,e.IIB)()],n.prototype,"name",void 0),Gu([(0,e.IIB)()],n.prototype,"message",void 0),Gu([(0,e.IIB)()],n.prototype,"delayStart",void 0),Gu([(0,e.IIB)()],n.prototype,"delayStop",void 0),Gu([(0,e.IIB)()],n.prototype,"template",void 0),n})(),yv=(()=>{let n=class{constructor(t,o,c){this.blockUI=t,this.resolver=o,this.changeDetectionRef=c,this.name=Mg,this.defaultBlockState={startTimeouts:[],stopTimeouts:[],updateTimeouts:[],blockCount:0,startCallCount:0,stopCallCount:0},this.state=Object.assign({},this.defaultBlockState)}ngOnInit(){this.settings=this.blockUI.getSettings(),this.blockUISubscription=this.subscribeToBlockUI(this.blockUI.observe())}ngAfterViewInit(){try{if(!this.templateCmp)return!1;if(this.templateCmp instanceof e.Rgc)this.templateOutlet.createEmbeddedView(this.templateCmp);else{const t=this.resolver.resolveComponentFactory(this.templateCmp);this.templateCompRef=this.templateOutlet.createComponent(t),this.updateBlockTemplate(this.message)}}catch(t){console.error("ng-block-ui:",t)}}ngAfterViewChecked(){this.detectChanges()}subscribeToBlockUI(t){return t.subscribe(o=>this.onDispatchedEvent(o))}onDispatchedEvent(t){switch(t.action){case pd.START:this.onStart(t);break;case pd.STOP:this.onStop(t);break;case pd.UPDATE:this.onUpdate(t);break;case pd.RESET:this.onReset(t);break;case pd.RESET_GLOBAL:this.resetState();break;case pd.UNSUBSCRIBE:this.onStop(t),this.onUnsubscribe(t.name)}}onStart({name:t,message:o}){if(t===this.name){const c=this.delayStart||this.settings.delayStart||0;this.state.startCallCount+=1;const g=setTimeout(()=>{this.state.blockCount+=1,this.showBlock(o),this.updateInstanceBlockCount()},c);this.state.startTimeouts.push(g)}}onStop({name:t}){if(t===this.name){const o=this.state.stopCallCount+1;if(this.state.startCallCount-o>=0){const c=this.delayStop||this.settings.delayStop||0;this.state.stopCallCount=o;const g=setTimeout(()=>{this.state.blockCount-=1,this.updateInstanceBlockCount(),this.detectChanges()},c);this.state.stopTimeouts.push(g)}}}onUpdate({name:t,message:o}){if(t===this.name){const c=this.delayStart||this.settings.delayStart||0;clearTimeout(this.state.updateTimeouts[0]);const g=setTimeout(()=>{this.updateMessage(o)},c);this.state.updateTimeouts.push(g)}}onReset({name:t}){t===this.name&&this.resetState()}updateMessage(t){this.showBlock(t)}showBlock(t){this.message=t||this.defaultMessage||this.settings.message,this.updateBlockTemplate(this.message),this.detectChanges()}updateBlockTemplate(t){this.templateCompRef&&this.templateCompRef instanceof e.UuU&&(this.templateCompRef.instance.message=t)}resetState(){[...this.state.startTimeouts,...this.state.stopTimeouts,...this.state.updateTimeouts].forEach(clearTimeout),this.state=Object.assign({},this.defaultBlockState),this.updateInstanceBlockCount(),this.detectChanges()}onUnsubscribe(t){this.blockUISubscription&&t===this.name&&this.blockUISubscription.unsubscribe()}updateInstanceBlockCount(){if(this.blockUI.blockUIInstances[this.name]){const{blockCount:t}=this.state;this.blockUI.blockUIInstances[this.name].blockCount=t}}detectChanges(){this.changeDetectionRef.destroyed||this.changeDetectionRef.detectChanges()}ngOnDestroy(){this.resetState(),this.onUnsubscribe(this.name),this.blockUI.clearInstance(this.name)}};return n.\u0275fac=function(t){return new(t||n)(e.Y36(Ag),e.Y36(e._Vd),e.Y36(e.sBO))},n.\u0275cmp=e.Xpm({type:n,selectors:[["block-ui-content"]],viewQuery:function(t,o){if(1&t&&e.Gf(Tb,5,e.s_b),2&t){let c;e.iGM(c=e.CRH())&&(o.templateOutlet=c.first)}},inputs:{name:"name",delayStart:"delayStart",delayStop:"delayStop",defaultMessage:["message","defaultMessage"],templateCmp:["template","templateCmp"]},decls:3,vars:9,consts:[[3,"ngClass"],["class","block-ui-spinner",4,"ngIf"],[4,"ngIf"],[1,"block-ui-spinner"],[1,"loader"],["class","message",4,"ngIf"],[1,"message"],["templateOutlet",""]],template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.YNc(1,Jg,3,1,"div",1),e.YNc(2,Im,2,0,void 0,2),e.qZA()),2&t&&(e.MT6("block-ui-wrapper ",o.name," ",o.className,""),e.Q6J("ngClass",e.VKq(7,Lm,o.state.blockCount>0)),e.xp6(1),e.Q6J("ngIf",!o.templateCmp),e.xp6(1),e.Q6J("ngIf",o.templateCmp))},directives:[_.mk,_.O5],styles:["\n.block-ui-wrapper {\n display: none;\n position: fixed;\n height: 100%;\n width: 100%;\n top: 0;\n left: 0;\n background: rgba(0, 0, 0, 0.70);\n z-index: 30000;\n cursor: wait;\n}\n\n.block-ui-wrapper.block-ui-wrapper--element {\n position: absolute;\n}\n\n.block-ui-wrapper.active {\n display: block;\n}\n\n.block-ui-wrapper.block-ui-main {\n position: fixed;\n}\n\n.block-ui-spinner,\n.block-ui-template {\n position: absolute;\n top: 40%;\n margin: 0 auto;\n left: 0;\n right: 0;\n transform: translateY(-50%);\n}\n\n.block-ui-spinner > .message {\n font-size: 1.3em;\n text-align: center;\n color: #fff;\n}\n\n.block-ui__element {\n position: relative;\n}\n\n.loader,\n.loader:after {\n border-radius: 50%;\n width: 10em;\n height: 10em;\n}\n.loader {\n margin: 7px auto;\n font-size: 5px;\n position: relative;\n text-indent: -9999em;\n border-top: 1.1em solid rgba(255, 255, 255, 0.2);\n border-right: 1.1em solid rgba(255, 255, 255, 0.2);\n border-bottom: 1.1em solid rgba(255, 255, 255, 0.2);\n border-left: 1.1em solid #ffffff;\n -webkit-transform: translateZ(0);\n -ms-transform: translateZ(0);\n transform: translateZ(0);\n -webkit-animation: load8 1.1s infinite linear;\n animation: load8 1.1s infinite linear;\n}\n\n@-webkit-keyframes load8 {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n\n@keyframes load8 {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n"],encapsulation:2}),Gu([(0,e.IIB)()],n.prototype,"name",void 0),Gu([(0,e.IIB)()],n.prototype,"delayStart",void 0),Gu([(0,e.IIB)()],n.prototype,"delayStop",void 0),Gu([(0,e.IIB)("message")],n.prototype,"defaultMessage",void 0),Gu([(0,e.IIB)("template")],n.prototype,"templateCmp",void 0),Gu([(0,e.i9L)("templateOutlet",{read:e.s_b})],n.prototype,"templateOutlet",void 0),n})(),H0=(()=>{let n=class{constructor(t){this.blockUIInstance=t,this.globalDispatch=this.blockUIInstance.decorate()}start(t,o){this.dispatch(t,pd.START,o)}stop(t){this.dispatch(t,pd.STOP)}reset(t){this.dispatch(t,pd.RESET)}resetGlobal(){this.globalDispatch.resetGlobal()}update(t,o){this.dispatch(t,pd.UPDATE,o)}unsubscribe(t){this.dispatch(t,pd.UNSUBSCRIBE)}isActive(t=null){const o=t?this.toArray(t):null,c=this.blockUIInstance.blockUIInstances;return Object.keys(c).some(g=>o?o.indexOf(c[g].name)>=0&&c[g].isActive:c[g].isActive)}dispatch(t=[],o,c){this.toArray(t).forEach(C=>this.blockUIInstance.decorate(C)[o](c))}toArray(t=[]){return"string"==typeof t?[t]:t}};return n.\u0275fac=function(t){return new(t||n)(e.LFG(Ag))},n.\u0275prov=e.Yz7({token:n,factory:function(s){return n.\u0275fac(s)}}),n})();var Md;const sd=new Ag,g1=new e.OlP("BlockUIModuleSettings");function Cb(n){return sd.updateSettings(n),sd}let Qg=Md=class{static forRoot(s={}){return{ngModule:Md,providers:[{provide:g1,useValue:s},{provide:Ag,useFactory:Cb,deps:[g1]},H0]}}};Qg.\u0275fac=function(s){return new(s||Qg)},Qg.\u0275mod=e.oAB({type:Qg}),Qg.\u0275inj=e.cJS({imports:[[_.ez]]});let Og=1;function Ab(n,s){if(1&n&&(e.ynx(0),e._UZ(1,"cd-table-key-value",1),e.BQk()),2&n){const t=e.oxw();e.xp6(1),e.Q6J("data",t.module_config)}}let Ob=(()=>{class n{constructor(t){this.mgrModuleService=t}ngOnChanges(){this.selection&&this.mgrModuleService.getConfig(this.selection.name).subscribe(t=>{this.module_config=t})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(ql.N))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-mgr-module-details"]],inputs:{selection:"selection"},features:[e.TTD],decls:1,vars:1,consts:[[4,"ngIf"],[3,"data"]],template:function(t,o){1&t&&e.YNc(0,Ab,2,1,"ng-container",0),2&t&&e.Q6J("ngIf",o.selection)},directives:[_.O5,zr.b],styles:[""]}),n})();class wg extends jl.o{constructor(s,t,o){super(),this.authStorageService=s,this.mgrModuleService=t,this.notificationService=o,this.columns=[],this.modules=[],this.selection=new El.r,this.permission=this.authStorageService.getPermissions().configOpt,this.columns=[{name:"Name",prop:"name",flexGrow:1},{name:"Enabled",prop:"enabled",flexGrow:1,cellClass:"text-center",cellTransformation:bl.e.checkIcon},{name:"Always-On",prop:"always_on",flexGrow:1,cellClass:"text-center",cellTransformation:bl.e.checkIcon}];const c=()=>this.selection.first()&&encodeURIComponent(this.selection.first().name);this.tableActions=[{name:"Edit",permission:"update",disable:()=>!this.selection.hasSelection||0===Object.values(this.selection.first().options).length,routerLink:()=>`/mgr-modules/edit/${c()}`,icon:xo.P.edit},{name:"Enable",permission:"update",click:()=>this.updateModuleState(),disable:()=>this.isTableActionDisabled("enabled"),icon:xo.P.start},{name:"Disable",permission:"update",click:()=>this.updateModuleState(),disable:()=>this.getTableActionDisabledDesc(),icon:xo.P.stop}]}getModuleList(s){this.mgrModuleService.list().subscribe(t=>{this.modules=t},()=>{s.error()})}updateSelection(s){this.selection=s}isTableActionDisabled(s){if(!this.selection.hasSelection)return!0;const t=this.selection.first();if("dashboard"===t.name||t.always_on)return!0;switch(s){case"enabled":return t.enabled;case"disabled":return!t.enabled}}getTableActionDisabledDesc(){var s;return(null===(s=this.selection.first())||void 0===s?void 0:s.always_on)?"This Manager module is always on.":this.isTableActionDisabled("disabled")}updateModuleState(){if(!this.selection.hasSelection)return;let s;const t=()=>{(0,V.H)(2e3).subscribe(()=>{this.mgrModuleService.list().subscribe(()=>{this.notificationService.suspendToasties(!1),this.blockUI.stop(),this.table.refreshBtn()},()=>{t()})})},o=this.selection.first();s=o.enabled?this.mgrModuleService.disable(o.name):this.mgrModuleService.enable(o.name),s.subscribe(()=>{},()=>{this.notificationService.suspendToasties(!0),this.blockUI.start("Reconnecting, please wait ..."),t()})}}wg.\u0275fac=function(s){return new(s||wg)(e.Y36(vt.j),e.Y36(ql.N),e.Y36(hl.g))},wg.\u0275cmp=e.Xpm({type:wg,selectors:[["cd-mgr-module-list"]],viewQuery:function(s,t){if(1&s&&e.Gf(ks.a,7),2&s){let o;e.iGM(o=e.CRH())&&(t.table=o.first)}},features:[e.qOj],decls:4,vars:8,consts:[["columnMode","flex","selectionType","single","identifier","module",3,"autoReload","data","columns","hasDetails","setExpandedRow","updateSelection","fetchData"],["table",""],[1,"table-actions",3,"permission","selection","tableActions"],["cdTableDetail","",3,"selection"]],template:function(s,t){1&s&&(e.TgZ(0,"cd-table",0,1),e.NdJ("setExpandedRow",function(c){return t.setExpandedRow(c)})("updateSelection",function(c){return t.updateSelection(c)})("fetchData",function(c){return t.getModuleList(c)}),e._UZ(2,"cd-table-actions",2),e._UZ(3,"cd-mgr-module-details",3),e.qZA()),2&s&&(e.Q6J("autoReload",!1)("data",t.modules)("columns",t.columns)("hasDetails",!0),e.xp6(2),e.Q6J("permission",t.permission)("selection",t.selection)("tableActions",t.tableActions),e.xp6(1),e.Q6J("selection",t.expandedRow))},directives:[ks.a,Js.K,Ob],styles:[""]}),(0,fa.gn)([function(n,s={}){return s.scopeToInstance?function(t,o){const c=`_${o}-block-ui`;Object.defineProperty(t,o,{get:function(){if(this[c])return this[c];const g=`${n}-${Og++}`;return this[c]=sd.decorate(g),this[c]},set:function(g){this[c]=g}})}:function(t,o){t[o]=sd.decorate(n)}}(),(0,fa.w6)("design:type",Object)],wg.prototype,"blockUI",void 0);let ES=(()=>{class n{constructor(t){this.http=t}getMonitor(){return this.http.get("api/monitor")}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(y.eN))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();function wb(n,s){if(1&n&&(e.TgZ(0,"table",11),e.TgZ(1,"tr"),e.TgZ(2,"td",12),e.SDv(3,13),e.qZA(),e.TgZ(4,"td"),e._uU(5),e.qZA(),e.qZA(),e.TgZ(6,"tr"),e.TgZ(7,"td",12),e.SDv(8,14),e.qZA(),e.TgZ(9,"td"),e._uU(10),e.ALo(11,"relativeDate"),e.qZA(),e.qZA(),e.TgZ(12,"tr"),e.TgZ(13,"td",12),e.SDv(14,15),e.qZA(),e.TgZ(15,"td"),e._uU(16),e.qZA(),e.qZA(),e.TgZ(17,"tr"),e.TgZ(18,"td",12),e.SDv(19,16),e.qZA(),e.TgZ(20,"td"),e._uU(21),e.qZA(),e.qZA(),e.TgZ(22,"tr"),e.TgZ(23,"td",12),e.SDv(24,17),e.qZA(),e.TgZ(25,"td"),e._uU(26),e.qZA(),e.qZA(),e.TgZ(27,"tr"),e.TgZ(28,"td",12),e.SDv(29,18),e.qZA(),e.TgZ(30,"td"),e._uU(31),e.qZA(),e.qZA(),e.TgZ(32,"tr"),e.TgZ(33,"td",12),e.SDv(34,19),e.qZA(),e.TgZ(35,"td"),e._uU(36),e.qZA(),e.qZA(),e.qZA()),2&n){const t=e.oxw();e.xp6(5),e.Oqu(t.mon_status.monmap.fsid),e.xp6(5),e.Oqu(e.lcZ(11,7,t.mon_status.monmap.modified)),e.xp6(6),e.Oqu(t.mon_status.monmap.epoch),e.xp6(5),e.Oqu(t.mon_status.features.quorum_con),e.xp6(5),e.Oqu(t.mon_status.features.quorum_mon),e.xp6(5),e.Oqu(t.mon_status.features.required_con),e.xp6(5),e.Oqu(t.mon_status.features.required_mon)}}let U0=(()=>{class n{constructor(t){this.monitorService=t,this.inQuorum={columns:[{prop:"name",name:"Name",cellTransformation:bl.e.routerLink},{prop:"rank",name:"Rank"},{prop:"public_addr",name:"Public Address"},{prop:"cdOpenSessions",name:"Open Sessions",cellTransformation:bl.e.sparkline,comparator:(o,c)=>{const g=wr().last(o),C=wr().last(c);return g&&C&&g!==C?g>C?1:-1:0}}]},this.notInQuorum={columns:[{prop:"name",name:"Name",cellTransformation:bl.e.routerLink},{prop:"rank",name:"Rank"},{prop:"public_addr",name:"Public Address"}]}}refresh(){this.monitorService.getMonitor().subscribe(t=>{t.in_quorum.map(o=>(o.cdOpenSessions=o.stats.num_sessions.map(c=>c[1]),o.cdLink="/perf_counters/mon/"+o.name,o.cdParams={fromLink:"/monitor"},o)),t.out_quorum.map(o=>(o.cdLink="/perf_counters/mon/"+o.name,o.cdParams={fromLink:"/monitor"},o)),this.inQuorum.data=[...t.in_quorum],this.notInQuorum.data=[...t.out_quorum],this.mon_status=t.mon_status})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(ES))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-monitor"]],decls:13,vars:5,consts:function(){let s,t,o,c,g,C,D,P,j,W;return s="Status",t="In Quorum",o="Not In Quorum",c="Cluster ID",g="monmap modified",C="monmap epoch",D="quorum con",P="quorum mon",j="required con",W="required mon",[[1,"row"],[1,"col-lg-4"],[1,"cd-header"],s,["class","table table-striped",4,"ngIf"],[1,"col-lg-8"],[1,"in-quorum","cd-header"],t,[3,"data","columns"],o,[3,"data","columns","fetchData"],[1,"table","table-striped"],[1,"bold"],c,g,C,D,P,j,W]},template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"div",1),e.TgZ(2,"fieldset"),e.TgZ(3,"legend",2),e.SDv(4,3),e.qZA(),e.YNc(5,wb,37,9,"table",4),e.qZA(),e.qZA(),e.TgZ(6,"div",5),e.TgZ(7,"legend",6),e.SDv(8,7),e.qZA(),e._UZ(9,"cd-table",8),e.TgZ(10,"legend",6),e.SDv(11,9),e.qZA(),e.TgZ(12,"cd-table",10),e.NdJ("fetchData",function(){return o.refresh()}),e.qZA(),e.qZA(),e.qZA()),2&t&&(e.xp6(5),e.Q6J("ngIf",o.mon_status),e.xp6(4),e.Q6J("data",o.inQuorum.data)("columns",o.inQuorum.columns),e.xp6(3),e.Q6J("data",o.notInQuorum.data)("columns",o.notInQuorum.columns))},directives:[_.O5,ks.a],pipes:[Tt.h],styles:[""]}),n})();class Ac{}function bv(n,s){if(1&n&&(e.TgZ(0,"span",18),e.SDv(1,19),e.qZA()),2&n){const t=e.oxw(2);e.Q6J("ngbTooltip",t.clusterWideTooltip)}}function TS(n,s){1&n&&e._UZ(0,"hr",20)}function M_(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",12),e.TgZ(1,"input",13),e.NdJ("change",function(){const g=e.CHM(t).$implicit;return e.oxw().changeValue(g)}),e.qZA(),e.TgZ(2,"label",14),e.TgZ(3,"strong"),e._uU(4),e.qZA(),e.YNc(5,bv,2,1,"span",15),e._UZ(6,"br"),e.TgZ(7,"span",16),e._uU(8),e.qZA(),e.qZA(),e.YNc(9,TS,1,0,"hr",17),e.qZA()}if(2&n){const t=s.$implicit,o=s.last;e.xp6(1),e.Q6J("checked",t.value)("indeterminate",t.indeterminate)("name",t.code)("id",t.code),e.xp6(1),e.Q6J("for",t.code),e.xp6(2),e.Oqu(t.name),e.xp6(1),e.Q6J("ngIf",t.clusterWide),e.xp6(3),e.Oqu(t.description),e.xp6(1),e.Q6J("ngIf",!o)}}let m1=(()=>{class n{constructor(t,o,c,g,C){this.activeModal=t,this.actionLabels=o,this.authStorageService=c,this.osdService=g,this.notificationService=C,this.initialSelection=[],this.osdFlagsForm=new Mn.cw({}),this.flags=[{code:"noup",name:"No Up",description:"OSDs are not allowed to start",value:!1,clusterWide:!1,indeterminate:!1},{code:"nodown",name:"No Down",description:"OSD failure reports are being ignored, such that the monitors will not mark OSDs down",value:!1,clusterWide:!1,indeterminate:!1},{code:"noin",name:"No In",description:"OSDs that were previously marked out will not be marked back in when they start",value:!1,clusterWide:!1,indeterminate:!1},{code:"noout",name:"No Out",description:"OSDs will not automatically be marked out after the configured interval",value:!1,clusterWide:!1,indeterminate:!1}],this.clusterWideTooltip="The flag has been enabled for the entire cluster.",this.permissions=this.authStorageService.getPermissions()}ngOnInit(){const t=this.selected.length;this.osdService.getFlags().subscribe(o=>{const c=this.getActivatedIndivFlags();this.flags.forEach(g=>{const C=c[g.code];o.includes(g.code)&&(g.clusterWide=!0),C===t?g.value=!0:C>0&&(g.indeterminate=!0)}),this.initialSelection=wr().cloneDeep(this.flags)})}getActivatedIndivFlags(){const t={};return this.flags.forEach(o=>{t[o.code]=0}),[].concat(...this.selected.map(o=>o.state)).map(o=>{Object.keys(t).includes(o)&&(t[o]=t[o]+1)}),t}changeValue(t){t.value=!t.value,t.indeterminate=!1}resetSelection(){this.flags=wr().cloneDeep(this.initialSelection)}submitAction(){const t={};this.flags.forEach(c=>{t[c.code]=c.indeterminate?null:c.value});const o=this.selected.map(c=>c.osd);this.osdService.updateIndividualFlags(t,o).subscribe(()=>{this.notificationService.show(pa.k.success,"Updated OSD Flags"),this.activeModal.close()},()=>{this.activeModal.close()})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(ut.Kz),e.Y36($i.p4),e.Y36(vt.j),e.Y36(Ji),e.Y36(hl.g))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-osd-flags-indiv-modal"]],decls:12,vars:6,consts:function(){let s,t,o;return s="Individual OSD Flags",t="Restore previous selection",o="Cluster-wide",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["name","osdFlagsForm","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"modal-body","osd-modal"],["class","custom-control custom-checkbox",4,"ngFor","ngForOf"],[1,"modal-footer"],["type","button",1,"btn","btn-light",3,"click"],t,[3,"form","showSubmit","submitText","submitActionEvent"],[1,"custom-control","custom-checkbox"],["type","checkbox",1,"custom-control-input",3,"checked","indeterminate","name","id","change"],["ng-class","['tc_' + key]",1,"custom-control-label",3,"for"],["class","badge badge-hdd ml-2",3,"ngbTooltip",4,"ngIf"],[1,"form-text","text-muted"],["class","m-1",4,"ngIf"],[1,"badge","badge-hdd","ml-2",3,"ngbTooltip"],o,[1,"m-1"]]},template:function(t,o){1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.BQk(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.YNc(7,M_,10,9,"div",7),e.qZA(),e.TgZ(8,"div",8),e.TgZ(9,"button",9),e.NdJ("click",function(){return o.resetSelection()}),e.SDv(10,10),e.qZA(),e.TgZ(11,"cd-form-button-panel",11),e.NdJ("submitActionEvent",function(){return o.submitAction()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t&&(e.Q6J("modalRef",o.activeModal),e.xp6(4),e.Q6J("formGroup",o.osdFlagsForm),e.xp6(3),e.Q6J("ngForOf",o.flags),e.xp6(4),e.Q6J("form",o.osdFlagsForm)("showSubmit",o.permissions.osd.update)("submitText",o.actionLabels.UPDATE))},directives:[bu.z,Mn._Y,Mn.JL,ll.V,Mn.sg,_.sg,la.o,ul.p,ja.b,_.O5,ut._L],styles:[""]}),n})();var Fm=i(84333);function km(n,s){1&n&&e._UZ(0,"hr",15)}function xb(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",10),e.TgZ(1,"input",11),e.NdJ("change",function(){const g=e.CHM(t).$implicit;return g.value=!g.value}),e.qZA(),e.TgZ(2,"label",12),e.TgZ(3,"strong"),e._uU(4),e.qZA(),e._UZ(5,"br"),e.TgZ(6,"span",13),e._uU(7),e.qZA(),e.qZA(),e.YNc(8,km,1,0,"hr",14),e.qZA()}if(2&n){const t=s.$implicit,o=s.last;e.xp6(1),e.Q6J("checked",t.value)("name",t.code)("id",t.code)("disabled",t.disabled),e.xp6(1),e.Q6J("for",t.code),e.xp6(2),e.Oqu(t.name),e.xp6(3),e.Oqu(t.description),e.xp6(1),e.Q6J("ngIf",!o)}}let Db=(()=>{class n{constructor(t,o,c,g,C){this.activeModal=t,this.actionLabels=o,this.authStorageService=c,this.osdService=g,this.notificationService=C,this.osdFlagsForm=new Mn.cw({}),this.allFlags={noin:{code:"noin",name:"No In",value:!1,description:"OSDs that were previously marked out will not be marked back in when they start"},noout:{code:"noout",name:"No Out",value:!1,description:"OSDs will not automatically be marked out after the configured interval"},noup:{code:"noup",name:"No Up",value:!1,description:"OSDs are not allowed to start"},nodown:{code:"nodown",name:"No Down",value:!1,description:"OSD failure reports are being ignored, such that the monitors will not mark OSDs down"},pause:{code:"pause",name:"Pause",value:!1,description:"Pauses reads and writes"},noscrub:{code:"noscrub",name:"No Scrub",value:!1,description:"Scrubbing is disabled"},"nodeep-scrub":{code:"nodeep-scrub",name:"No Deep Scrub",value:!1,description:"Deep Scrubbing is disabled"},nobackfill:{code:"nobackfill",name:"No Backfill",value:!1,description:"Backfilling of PGs is suspended"},norebalance:{code:"norebalance",name:"No Rebalance",value:!1,description:"OSD will choose not to backfill unless PG is also degraded"},norecover:{code:"norecover",name:"No Recover",value:!1,description:"Recovery of PGs is suspended"},sortbitwise:{code:"sortbitwise",name:"Bitwise Sort",value:!1,description:"Use bitwise sort",disabled:!0},purged_snapdirs:{code:"purged_snapdirs",name:"Purged Snapdirs",value:!1,description:"OSDs have converted snapsets",disabled:!0},recovery_deletes:{code:"recovery_deletes",name:"Recovery Deletes",value:!1,description:"Deletes performed during recovery instead of peering",disabled:!0},pglog_hardlimit:{code:"pglog_hardlimit",name:"PG Log Hard Limit",value:!1,description:"Puts a hard limit on pg log length",disabled:!0}},this.unknownFlags=[],this.permissions=this.authStorageService.getPermissions()}ngOnInit(){this.osdService.getFlags().subscribe(t=>{t.forEach(o=>{this.allFlags[o]?this.allFlags[o].value=!0:this.unknownFlags.push(o)}),this.flags=wr().toArray(this.allFlags)})}submitAction(){const t=this.flags.filter(o=>o.value).map(o=>o.code).concat(this.unknownFlags);this.osdService.updateFlags(t).subscribe(()=>{this.notificationService.show(pa.k.success,"Updated OSD Flags"),this.activeModal.close()},()=>{this.activeModal.close()})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(ut.Kz),e.Y36($i.p4),e.Y36(vt.j),e.Y36(Ji),e.Y36(hl.g))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-osd-flags-modal"]],decls:10,vars:6,consts:function(){let s;return s="Cluster-wide OSD Flags",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["name","osdFlagsForm","novalidate","","cdFormScope","osd",3,"formGroup"],["formDir","ngForm"],[1,"modal-body","osd-modal"],["class","custom-control custom-checkbox",4,"ngFor","ngForOf"],[1,"modal-footer"],[3,"form","showSubmit","submitText","submitActionEvent"],[1,"custom-control","custom-checkbox"],["type","checkbox",1,"custom-control-input",3,"checked","name","id","disabled","change"],["ng-class","['tc_' + key]",1,"custom-control-label",3,"for"],[1,"form-text","text-muted"],["class","m-1",4,"ngIf"],[1,"m-1"]]},template:function(t,o){1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.BQk(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.YNc(7,xb,9,8,"div",7),e.qZA(),e.TgZ(8,"div",8),e.TgZ(9,"cd-form-button-panel",9),e.NdJ("submitActionEvent",function(){return o.submitAction()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t&&(e.Q6J("modalRef",o.activeModal),e.xp6(4),e.Q6J("formGroup",o.osdFlagsForm),e.xp6(3),e.Q6J("ngForOf",o.flags),e.xp6(2),e.Q6J("form",o.osdFlagsForm)("showSubmit",o.permissions.osd.update)("submitText",o.actionLabels.UPDATE))},directives:[bu.z,Mn._Y,Mn.JL,Fm.T,ll.V,Mn.sg,_.sg,ul.p,la.o,ja.b,_.O5],styles:[""]}),n})();function B0(n,s){if(1&n&&(e.TgZ(0,"cd-helper"),e._uU(1),e.qZA()),2&n){const t=e.oxw(2).$implicit;e.xp6(1),e.hij(" ",t.long_desc,"")}}function Y0(n,s){if(1&n&&(e.TgZ(0,"div",4),e.TgZ(1,"label",5),e.TgZ(2,"b"),e._uU(3),e.qZA(),e._UZ(4,"br"),e.TgZ(5,"span",6),e._uU(6),e.YNc(7,B0,2,1,"cd-helper",7),e.qZA(),e.qZA(),e.TgZ(8,"div",8),e.TgZ(9,"div",9),e._UZ(10,"input",10),e._UZ(11,"label",11),e.qZA(),e.qZA(),e.qZA()),2&n){const t=e.oxw().$implicit;e.xp6(1),e.Q6J("for",t.name),e.xp6(2),e.Oqu(t.text),e.xp6(3),e.hij(" ",t.desc," "),e.xp6(1),e.Q6J("ngIf",t.long_desc),e.xp6(3),e.Q6J("id",t.name)("formControlName",t.name),e.xp6(1),e.Q6J("for",t.name)}}function Z0(n,s){if(1&n&&(e.TgZ(0,"cd-helper"),e._uU(1),e.qZA()),2&n){const t=e.oxw(2).$implicit;e.xp6(1),e.hij(" ",t.long_desc,"")}}const v1=function(n){return[n]};function j0(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",16),e.TgZ(1,"button",17),e.NdJ("click",function(){e.CHM(t);const c=e.oxw(2).$implicit;return e.oxw().resetValue(c.name)}),e._UZ(2,"i",18),e.qZA(),e.qZA()}if(2&n){const t=e.oxw(3);e.xp6(2),e.Q6J("ngClass",e.VKq(1,v1,t.icons.erase))}}function Rb(n,s){if(1&n&&(e.TgZ(0,"span",19),e._uU(1),e.qZA()),2&n){const t=e.oxw(2).$implicit;e.xp6(1),e.hij(" ",t.additionalTypeInfo.patternHelpText,"")}}function $m(n,s){if(1&n&&(e.TgZ(0,"span",19),e._uU(1),e.qZA()),2&n){const t=e.oxw(2).$implicit;e.xp6(1),e.hij(" ",t.additionalTypeInfo.patternHelpText,"")}}function y1(n,s){if(1&n&&(e.TgZ(0,"span",19),e.SDv(1,20),e.qZA()),2&n){const t=e.oxw(2).$implicit;e.xp6(1),e.pQV(t.maxValue),e.QtT(1)}}function G0(n,s){if(1&n&&(e.TgZ(0,"span",19),e.SDv(1,21),e.qZA()),2&n){const t=e.oxw(2).$implicit;e.xp6(1),e.pQV(t.minValue),e.QtT(1)}}function V0(n,s){if(1&n&&(e.TgZ(0,"div",4),e.TgZ(1,"label",5),e._uU(2),e._UZ(3,"br"),e.TgZ(4,"span",6),e._uU(5),e.YNc(6,Z0,2,1,"cd-helper",7),e.qZA(),e.qZA(),e.TgZ(7,"div",8),e.TgZ(8,"div",12),e._UZ(9,"input",13),e.YNc(10,j0,3,3,"div",14),e.qZA(),e.YNc(11,Rb,2,1,"span",15),e.YNc(12,$m,2,1,"span",15),e.YNc(13,y1,2,1,"span",15),e.YNc(14,G0,2,1,"span",15),e.qZA(),e.qZA()),2&n){const t=e.oxw().$implicit,o=e.oxw();e.xp6(1),e.Q6J("for",t.name),e.xp6(1),e.hij("",t.text," "),e.xp6(3),e.hij(" ",t.desc," "),e.xp6(1),e.Q6J("ngIf",t.long_desc),e.xp6(3),e.Q6J("type",t.additionalTypeInfo.inputType)("id",t.name)("placeholder",t.additionalTypeInfo.humanReadable)("formControlName",t.name)("step",o.getStep(t.type,o.optionsForm.getValue(t.name))),e.xp6(1),e.Q6J("ngIf",o.optionsFormShowReset),e.xp6(1),e.Q6J("ngIf",o.optionsForm.showError(t.name,o.optionsFormDir,"pattern")),e.xp6(1),e.Q6J("ngIf",o.optionsForm.showError(t.name,o.optionsFormDir,"invalidUuid")),e.xp6(1),e.Q6J("ngIf",o.optionsForm.showError(t.name,o.optionsFormDir,"max")),e.xp6(1),e.Q6J("ngIf",o.optionsForm.showError(t.name,o.optionsFormDir,"min"))}}function z0(n,s){1&n&&e._UZ(0,"hr",22)}function W0(n,s){if(1&n&&(e.TgZ(0,"div"),e.YNc(1,Y0,12,7,"div",2),e.YNc(2,V0,15,14,"div",2),e.YNc(3,z0,1,0,"hr",3),e.qZA()),2&n){const t=s.$implicit,o=s.last;e.xp6(1),e.Q6J("ngIf","bool"===t.type),e.xp6(1),e.Q6J("ngIf","bool"!==t.type),e.xp6(1),e.Q6J("ngIf",!o)}}let Nb=(()=>{class n{constructor(t){this.configService=t,this.optionNames=[],this.optionsForm=new Hs.d({}),this.optionsFormDir=new Mn.F([],[]),this.optionsFormGroupName="",this.optionsFormShowReset=!0,this.icons=xo.P,this.options=[],this.optionsFormGroup=new Hs.d({})}static optionNameToText(t){const o=["mon","mgr","osd","mds","client"];return t.split("_").filter((c,g)=>0!==g||!o.includes(c)).map(c=>c.charAt(0).toUpperCase()+c.substring(1)).join(" ")}ngOnInit(){this.createForm(),this.loadStoredData()}createForm(){this.optionsForm.addControl(this.optionsFormGroupName,this.optionsFormGroup),this.optionNames.forEach(t=>{this.optionsFormGroup.addControl(t,new Mn.NI(null))})}getStep(t,o){return ns.getTypeStep(t,o)}loadStoredData(){this.configService.filter(this.optionNames).subscribe(t=>{this.options=t.map(o=>{const c=this.optionsForm.get(o.name),g=ns.getTypeValidators(o);return o.additionalTypeInfo=ns.getType(o.type),o.text=n.optionNameToText(o.name),o.value=wr().find(o.value,C=>"osd"===C.section),o.value&&c.setValue("bool"===o.additionalTypeInfo.name?"true"===o.value.value:o.value.value),g&&(o.patternHelpText=g.patternHelpText,"max"in g&&""!==g.max&&(o.maxValue=g.max),"min"in g&&""!==g.min&&(o.minValue=g.min),c.setValidators(g.validators)),o})})}saveValues(){const t={};return this.optionNames.forEach(o=>{const c=this.optionsForm.getValue(o);null!==c&&""!==c&&(t[o]={section:"osd",value:c})}),this.configService.bulkCreate({options:t})}resetValue(t){this.configService.delete(t,"osd").subscribe(()=>{this.optionsForm.get(t).reset()})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(ga.e))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-config-option"]],inputs:{optionNames:"optionNames",optionsForm:"optionsForm",optionsFormDir:"optionsFormDir",optionsFormGroupName:"optionsFormGroupName",optionsFormShowReset:"optionsFormShowReset"},decls:2,vars:2,consts:function(){let s,t,o;return s="Remove the custom configuration value. The default configuration will be inherited and used instead.",t="The entered value is too high! It must not be greater than " + "\ufffd0\ufffd" + ".",o="The entered value is too low! It must not be lower than " + "\ufffd0\ufffd" + ".",[[3,"formGroup"],[4,"ngFor","ngForOf"],["class","form-group row pt-2",4,"ngIf"],["class","my-2",4,"ngIf"],[1,"form-group","row","pt-2"],[1,"cd-col-form-label",3,"for"],[1,"text-muted"],[4,"ngIf"],[1,"cd-col-form-input"],[1,"custom-control","custom-checkbox"],["type","checkbox",1,"custom-control-input",3,"id","formControlName"],[1,"custom-control-label",3,"for"],[1,"input-group"],[1,"form-control",3,"type","id","placeholder","formControlName","step"],["class","input-group-append",4,"ngIf"],["class","invalid-feedback",4,"ngIf"],[1,"input-group-append"],["type","button","data-toggle","button","title",s,1,"btn","btn-light",3,"click"],["aria-hidden","true",3,"ngClass"],[1,"invalid-feedback"],t,o,[1,"my-2"]]},template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.YNc(1,W0,4,3,"div",1),e.qZA()),2&t&&(e.Q6J("formGroup",o.optionsFormGroup),e.xp6(1),e.Q6J("ngForOf",o.options))},directives:[Mn.JL,Mn.sg,ll.V,_.sg,_.O5,Za.P,la.o,Mn.Wl,ja.b,Mn.JJ,Mn.u,h.S,Mn.Fj,_.mk],styles:[".custom-checkbox[_ngcontent-%COMP%] label[_ngcontent-%COMP%], .custom-checkbox[_ngcontent-%COMP%] input[_ngcontent-%COMP%]{cursor:pointer}.col-form-label[_ngcontent-%COMP%]{text-align:left}"]}),n})(),J0=(()=>{class n{}return n.basicOptions=["osd_scrub_during_recovery","osd_scrub_begin_hour","osd_scrub_end_hour","osd_scrub_begin_week_day","osd_scrub_end_week_day","osd_scrub_min_interval","osd_scrub_max_interval","osd_deep_scrub_interval","osd_scrub_auto_repair","osd_max_scrubs","osd_scrub_priority","osd_scrub_sleep"],n.advancedOptions=["osd_scrub_auto_repair_num_errors","osd_debug_deep_scrub_sleep","osd_deep_scrub_keys","osd_deep_scrub_large_omap_object_key_threshold","osd_deep_scrub_large_omap_object_value_sum_threshold","osd_deep_scrub_randomize_ratio","osd_deep_scrub_stride","osd_deep_scrub_update_digest_min_age","osd_requested_scrub_priority","osd_scrub_backoff_ratio","osd_scrub_chunk_max","osd_scrub_chunk_min","osd_scrub_cost","osd_scrub_interval_randomize_ratio","osd_scrub_invalid_stats","osd_scrub_load_threshold","osd_scrub_max_preemptions"],n})();const Pb=["basicOptionsValues"],Ib=["advancedOptionsValues"];function Q0(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"a",15),e.NdJ("click",function(){return e.CHM(t),e.oxw().advancedEnabled=!0}),e.SDv(1,16),e.qZA()}}function SS(n,s){if(1&n&&(e.TgZ(0,"div"),e.TgZ(1,"h3",17),e.SDv(2,18),e.qZA(),e._UZ(3,"cd-config-option",7,19),e.qZA()),2&n){const t=e.oxw(),o=e.MAs(7);e.xp6(3),e.Q6J("optionNames",t.advancedOptions)("optionsForm",t.osdPgScrubForm)("optionsFormDir",o)("optionsFormGroupName","advancedFormGroup")}}let X0=(()=>{class n{constructor(t,o,c,g){this.activeModal=t,this.authStorageService=o,this.notificationService=c,this.actionLabels=g,this.basicOptions=J0.basicOptions,this.advancedOptions=J0.advancedOptions,this.advancedEnabled=!1,this.osdPgScrubForm=new Hs.d({}),this.resource="PG scrub options",this.action=this.actionLabels.EDIT,this.permissions=this.authStorageService.getPermissions()}submitAction(){const t=[this.basicOptionsValues.saveValues()];this.advancedOptionsValues&&t.push(this.advancedOptionsValues.saveValues()),(0,xc.D)(t).subscribe(()=>{this.notificationService.show(pa.k.success,"Updated PG scrub options"),this.activeModal.close()},()=>{this.activeModal.close()})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(ut.Kz),e.Y36(vt.j),e.Y36(hl.g),e.Y36($i.p4))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-osd-pg-scrub-modal"]],viewQuery:function(t,o){if(1&t&&(e.Gf(Pb,7),e.Gf(Ib,5)),2&t){let c;e.iGM(c=e.CRH())&&(o.basicOptionsValues=c.first),e.iGM(c=e.CRH())&&(o.advancedOptionsValues=c.first)}},decls:19,vars:21,consts:function(){let s,t,o;return s="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",t="Advanced...",o="Advanced configuration options",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["novalidate","","cdFormScope","osd",3,"formGroup"],["formDir","ngForm"],[1,"modal-body","osd-modal"],[3,"optionNames","optionsForm","optionsFormDir","optionsFormGroupName"],["basicOptionsValues",""],[1,"row"],[1,"col-sm-12"],["class","pull-right margin-right-md",3,"click",4,"ngIf"],[4,"ngIf"],[1,"modal-footer"],[3,"form","showSubmit","submitText","submitActionEvent"],[1,"pull-right","margin-right-md",3,"click"],t,[1,"page-header"],o,["advancedOptionsValues",""]]},template:function(t,o){if(1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.ALo(3,"titlecase"),e.ALo(4,"upperFirst"),e.BQk(),e.ynx(5,3),e.TgZ(6,"form",4,5),e.TgZ(8,"div",6),e._UZ(9,"cd-config-option",7,8),e.TgZ(11,"div",9),e.TgZ(12,"div",10),e.YNc(13,Q0,2,0,"a",11),e.qZA(),e.qZA(),e.YNc(14,SS,5,4,"div",12),e.qZA(),e.TgZ(15,"div",13),e.TgZ(16,"cd-form-button-panel",14),e.NdJ("submitActionEvent",function(){return o.submitAction()}),e.ALo(17,"titlecase"),e.ALo(18,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t){const c=e.MAs(7);e.Q6J("modalRef",o.activeModal),e.xp6(4),e.pQV(e.lcZ(3,13,o.action))(e.lcZ(4,15,o.resource)),e.QtT(2),e.xp6(2),e.Q6J("formGroup",o.osdPgScrubForm),e.xp6(3),e.Q6J("optionNames",o.basicOptions)("optionsForm",o.osdPgScrubForm)("optionsFormDir",c)("optionsFormGroupName","basicFormGroup"),e.xp6(4),e.Q6J("ngIf",!o.advancedEnabled),e.xp6(1),e.Q6J("ngIf",o.advancedEnabled),e.xp6(2),e.Q6J("form",o.osdPgScrubForm)("showSubmit",o.permissions.configOpt.update)("submitText",e.lcZ(17,17,o.action)+" "+e.lcZ(18,19,o.resource))}},directives:[bu.z,Mn._Y,Mn.JL,Fm.T,ll.V,Mn.sg,Nb,_.O5,ul.p],pipes:[_.rS,F.m],styles:[""]}),n})();function Lb(n,s){if(1&n&&(e.TgZ(0,"option",22),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t.name),e.xp6(1),e.hij(" ",t.text," ")}}function Fb(n,s){1&n&&(e.TgZ(0,"span",23),e.SDv(1,24),e.qZA())}function CS(n,s){if(1&n&&(e.TgZ(0,"cd-helper"),e._uU(1),e.qZA()),2&n){const t=e.oxw().$implicit;e.xp6(1),e.Oqu(t.value.desc)}}function MS(n,s){1&n&&(e.TgZ(0,"span",23),e.SDv(1,29),e.qZA())}function b1(n,s){if(1&n&&(e.TgZ(0,"span",23),e.SDv(1,30),e.qZA()),2&n){const t=e.oxw().$implicit;e.xp6(1),e.pQV(t.value.patternHelpText),e.QtT(1)}}function kb(n,s){if(1&n&&(e.TgZ(0,"span",23),e.SDv(1,31),e.qZA()),2&n){const t=e.oxw().$implicit;e.xp6(1),e.pQV(t.value.maxValue),e.QtT(1)}}function K0(n,s){if(1&n&&(e.TgZ(0,"span",23),e.SDv(1,32),e.qZA()),2&n){const t=e.oxw().$implicit;e.xp6(1),e.pQV(t.value.minValue),e.QtT(1)}}const q0=function(n){return{required:n}};function AS(n,s){if(1&n&&(e.TgZ(0,"div",7),e.TgZ(1,"label",25),e.TgZ(2,"span",26),e._uU(3),e.qZA(),e.YNc(4,CS,2,1,"cd-helper",27),e.qZA(),e.TgZ(5,"div",10),e._UZ(6,"input",28),e.YNc(7,MS,2,0,"span",13),e.YNc(8,b1,2,1,"span",13),e.YNc(9,kb,2,1,"span",13),e.YNc(10,K0,2,1,"span",13),e.qZA(),e.qZA()),2&n){const t=s.$implicit,o=e.oxw(),c=e.MAs(5);e.xp6(1),e.Q6J("for",t.key),e.xp6(1),e.Q6J("ngClass",e.VKq(11,q0,o.osdRecvSpeedForm.getValue("customizePriority"))),e.xp6(1),e.hij(" ",t.value.text," "),e.xp6(1),e.Q6J("ngIf",t.value.desc),e.xp6(2),e.Q6J("id",t.key)("formControlName",t.key)("readonly",!o.osdRecvSpeedForm.getValue("customizePriority")),e.xp6(1),e.Q6J("ngIf",o.osdRecvSpeedForm.getValue("customizePriority")&&o.osdRecvSpeedForm.showError(t.key,c,"required")),e.xp6(1),e.Q6J("ngIf",o.osdRecvSpeedForm.getValue("customizePriority")&&o.osdRecvSpeedForm.showError(t.key,c,"pattern")),e.xp6(1),e.Q6J("ngIf",o.osdRecvSpeedForm.getValue("customizePriority")&&o.osdRecvSpeedForm.showError(t.key,c,"max")),e.xp6(1),e.Q6J("ngIf",o.osdRecvSpeedForm.getValue("customizePriority")&&o.osdRecvSpeedForm.showError(t.key,c,"min"))}}let gh=(()=>{class n{constructor(t,o,c,g,C,D){this.activeModal=t,this.actionLabels=o,this.authStorageService=c,this.configService=g,this.notificationService=C,this.osdService=D,this.priorities=[],this.priorityAttrs={},this.permissions=this.authStorageService.getPermissions(),this.priorities=this.osdService.osdRecvSpeedModalPriorities.KNOWN_PRIORITIES,this.osdRecvSpeedForm=new Hs.d({priority:new Mn.NI(null,{validators:[Mn.kI.required]}),customizePriority:new Mn.NI(!1)}),this.priorityAttrs={osd_max_backfills:{text:"Max Backfills",desc:"",patternHelpText:"",maxValue:void 0,minValue:void 0},osd_recovery_max_active:{text:"Recovery Max Active",desc:"",patternHelpText:"",maxValue:void 0,minValue:void 0},osd_recovery_max_single_start:{text:"Recovery Max Single Start",desc:"",patternHelpText:"",maxValue:void 0,minValue:void 0},osd_recovery_sleep:{text:"Recovery Sleep",desc:"",patternHelpText:"",maxValue:void 0,minValue:void 0}},Object.keys(this.priorityAttrs).forEach(P=>{this.osdRecvSpeedForm.addControl(P,new Mn.NI(null,{validators:[Mn.kI.required]}))})}ngOnInit(){this.configService.filter(Object.keys(this.priorityAttrs)).subscribe(t=>{const o=this.getCurrentValues(t);this.detectPriority(o.values,c=>{this.setPriority(c)}),this.setDescription(o.configOptions),this.setValidators(o.configOptions)})}detectPriority(t,o){const c=wr().find(this.priorities,g=>wr().isEqual(g.values,t));return this.osdRecvSpeedForm.controls.customizePriority.setValue(!1),c?o(c):4===Object.entries(t).length?(this.osdRecvSpeedForm.controls.customizePriority.setValue(!0),o(Object({name:"custom",text:"Custom",values:t}))):o(this.priorities[0])}getCurrentValues(t){const o={values:{},configOptions:[]};return t.forEach(c=>{o.configOptions.push(c),"value"in c?c.value.forEach(g=>{"osd"===g.section&&(o.values[c.name]=Number(g.value))}):"default"in c&&null!==c.default&&(o.values[c.name]=Number(c.default))}),o}setDescription(t){t.forEach(o=>{""!==o.desc&&(this.priorityAttrs[o.name].desc=o.desc)})}setPriority(t){const o=wr().find(this.priorities,c=>"custom"===c.name);"custom"===t.name?o||this.priorities.push(t):o&&this.priorities.splice(this.priorities.indexOf(o),1),this.osdRecvSpeedForm.controls.priority.setValue(t.name),Object.entries(t.values).forEach(([c,g])=>{this.osdRecvSpeedForm.controls[c].setValue(g)})}setValidators(t){t.forEach(o=>{const c=ns.getTypeValidators(o);c?(c.validators.push(Mn.kI.required),"max"in c&&""!==c.max&&(this.priorityAttrs[o.name].maxValue=c.max),"min"in c&&""!==c.min&&(this.priorityAttrs[o.name].minValue=c.min),this.priorityAttrs[o.name].patternHelpText=c.patternHelpText,this.osdRecvSpeedForm.controls[o.name].setValidators(c.validators)):this.osdRecvSpeedForm.controls[o.name].setValidators(Mn.kI.required)})}onCustomizePriorityChange(){const t={};if(Object.keys(this.priorityAttrs).forEach(o=>{t[o]=this.osdRecvSpeedForm.getValue(o)}),this.osdRecvSpeedForm.getValue("customizePriority")){const o={name:"custom",text:"Custom",values:t};this.setPriority(o)}else this.detectPriority(t,o=>{this.setPriority(o)})}onPriorityChange(t){const o=wr().find(this.priorities,c=>c.name===t)||this.priorities[0];this.osdRecvSpeedForm.get("customizePriority").setValue(!1),this.setPriority(o)}submitAction(){const t={};Object.keys(this.priorityAttrs).forEach(o=>{t[o]={section:"osd",value:this.osdRecvSpeedForm.getValue(o)}}),this.configService.bulkCreate({options:t}).subscribe(()=>{this.notificationService.show(pa.k.success,"Updated OSD recovery speed priority '" + this.osdRecvSpeedForm.getValue("priority") + "'"),this.activeModal.close()},()=>{this.activeModal.close()})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(ut.Kz),e.Y36($i.p4),e.Y36(vt.j),e.Y36(ga.e),e.Y36(hl.g),e.Y36(Ji))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-osd-recv-speed-modal"]],decls:24,vars:10,consts:function(){let s,t,o,c,g,C,D,P;return s="OSD Recovery Priority",t="Priority",o="Customize priority values",c="This field is required.",g="This field is required!",C="" + "\ufffd0\ufffd" + "",D="The entered value is too high! It must not be greater than " + "\ufffd0\ufffd" + ".",P="The entered value is too low! It must not be lower than " + "\ufffd0\ufffd" + ".",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],["novalidate","","cdFormScope","osd",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],[1,"form-group","row"],["for","priority",1,"cd-col-form-label","required"],t,[1,"cd-col-form-input"],["formControlName","priority","id","priority",1,"form-control",3,"change"],[3,"value",4,"ngFor","ngForOf"],["class","invalid-feedback",4,"ngIf"],[1,"cd-col-form-offset"],[1,"custom-control","custom-checkbox"],["formControlName","customizePriority","id","customizePriority","name","customizePriority","type","checkbox",1,"custom-control-input",3,"change"],["for","customizePriority",1,"custom-control-label"],o,["class","form-group row",4,"ngFor","ngForOf"],[1,"modal-footer"],[3,"form","submitText","showSubmit","submitActionEvent"],[3,"value"],[1,"invalid-feedback"],c,[1,"cd-col-form-label",3,"for"],[3,"ngClass"],[4,"ngIf"],["type","number",1,"form-control",3,"id","formControlName","readonly"],g,C,D,P]},template:function(t,o){if(1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.BQk(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.TgZ(7,"div",7),e.TgZ(8,"label",8),e.SDv(9,9),e.qZA(),e.TgZ(10,"div",10),e.TgZ(11,"select",11),e.NdJ("change",function(g){return o.onPriorityChange(g.target.value)}),e.YNc(12,Lb,2,2,"option",12),e.qZA(),e.YNc(13,Fb,2,0,"span",13),e.qZA(),e.qZA(),e.TgZ(14,"div",7),e.TgZ(15,"div",14),e.TgZ(16,"div",15),e.TgZ(17,"input",16),e.NdJ("change",function(){return o.onCustomizePriorityChange()}),e.qZA(),e.TgZ(18,"label",17),e.SDv(19,18),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(20,AS,11,13,"div",19),e.ALo(21,"keyvalue"),e.qZA(),e.TgZ(22,"div",20),e.TgZ(23,"cd-form-button-panel",21),e.NdJ("submitActionEvent",function(){return o.submitAction()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t){const c=e.MAs(5);e.Q6J("modalRef",o.activeModal),e.xp6(4),e.Q6J("formGroup",o.osdRecvSpeedForm),e.xp6(8),e.Q6J("ngForOf",o.priorities),e.xp6(1),e.Q6J("ngIf",o.osdRecvSpeedForm.showError("priority",c,"required")),e.xp6(7),e.Q6J("ngForOf",e.lcZ(21,8,o.priorityAttrs)),e.xp6(3),e.Q6J("form",o.osdRecvSpeedForm)("submitText",o.actionLabels.UPDATE)("showSubmit",o.permissions.configOpt.update)}},directives:[bu.z,Mn._Y,Mn.JL,Fm.T,ll.V,Mn.sg,Za.P,la.o,Mn.EJ,ja.b,Mn.JJ,Mn.u,_.sg,_.O5,Mn.Wl,ul.p,Mn.YN,Mn.Kr,_.mk,Mn.wV,Mn.Fj,h.S],pipes:[_.Nd],styles:[""]}),n})();function OS(n,s){1&n&&(e.TgZ(0,"span"),e.SDv(1,15),e.qZA())}function ey(n,s){1&n&&(e.TgZ(0,"span"),e.SDv(1,16),e.qZA())}function $b(n,s){if(1&n&&(e.TgZ(0,"span",13),e.YNc(1,OS,2,0,"span",14),e.YNc(2,ey,2,0,"span",14),e.qZA()),2&n){const t=e.oxw();e.xp6(1),e.Q6J("ngIf",null==t.weight.errors?null:t.weight.errors.required),e.xp6(1),e.Q6J("ngIf",(null==t.weight.errors?null:t.weight.errors.max)||(null==t.weight.errors?null:t.weight.errors.min))}}let E1=(()=>{class n{constructor(t,o,c,g){this.actionLabels=t,this.activeModal=o,this.osdService=c,this.fb=g,this.currentWeight=1}get weight(){return this.reweightForm.get("weight")}ngOnInit(){this.reweightForm=this.fb.group({weight:this.fb.control(this.currentWeight,[Mn.kI.required])})}reweight(){this.osdService.reweight(this.osdId,this.reweightForm.value.weight).subscribe(()=>this.activeModal.close())}}return n.\u0275fac=function(t){return new(t||n)(e.Y36($i.p4),e.Y36(ut.Kz),e.Y36(Ji),e.Y36(rd.O))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-osd-reweight-modal"]],decls:14,vars:7,consts:function(){let s,t,o;return s="Reweight OSD: " + "\ufffd0\ufffd" + "",t="This field is required.",o="The value needs to be between 0 and 1.",[[3,"modalRef"],[1,"modal-title"],s,[1,"modal-content"],[3,"formGroup"],[1,"modal-body"],[1,"row"],["for","weight",1,"cd-col-form-label"],[1,"cd-col-form-input"],["id","weight","type","number","step","0.1","formControlName","weight","min","0","max","1",1,"form-control",3,"value"],["class","invalid-feedback",4,"ngIf"],[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],[1,"invalid-feedback"],[4,"ngIf"],t,o]},template:function(t,o){1&t&&(e.TgZ(0,"cd-modal",0),e.ynx(1,1),e.SDv(2,2),e.BQk(),e.ynx(3,3),e.TgZ(4,"form",4),e.TgZ(5,"div",5),e.TgZ(6,"div",6),e.TgZ(7,"label",7),e._uU(8,"Weight"),e.qZA(),e.TgZ(9,"div",8),e._UZ(10,"input",9),e.YNc(11,$b,3,2,"span",10),e.qZA(),e.qZA(),e.qZA(),e.TgZ(12,"div",11),e.TgZ(13,"cd-form-button-panel",12),e.NdJ("submitActionEvent",function(){return o.reweight()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t&&(e.Q6J("modalRef",o.activeModal),e.xp6(2),e.pQV(o.osdId),e.QtT(2),e.xp6(2),e.Q6J("formGroup",o.reweightForm),e.xp6(6),e.Q6J("value",o.currentWeight),e.xp6(1),e.Q6J("ngIf",o.weight.errors),e.xp6(2),e.Q6J("form",o.reweightForm)("submitText",o.actionLabels.REWEIGHT))},directives:[bu.z,Mn._Y,Mn.JL,ll.V,Mn.sg,la.o,Mn.wV,Mn.qQ,Mn.Fd,Mn.Fj,ja.b,Mn.JJ,Mn.u,_.O5,ul.p],styles:[""]}),n})();var Ev=i(86969);let ty=(()=>{class n{constructor(t,o,c,g,C){this.activeModal=t,this.actionLabels=o,this.osdService=c,this.notificationService=g,this.joinPipe=C,this.selected=[]}ngOnInit(){this.scrubForm=new Mn.cw({})}scrub(){(0,xc.D)(this.selected.map(t=>this.osdService.scrub(t,this.deep))).subscribe(()=>{this.notificationService.show(pa.k.success,"" + (this.deep ? "Deep scrub" : "Scrub") + " was initialized in the following OSD(s): " + this.joinPipe.transform(this.selected) + ""),this.activeModal.close()},()=>this.activeModal.close())}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(ut.Kz),e.Y36($i.p4),e.Y36(Ji),e.Y36(hl.g),e.Y36(Ev.A))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-osd-scrub-modal"]],decls:13,vars:9,consts:function(){let s,t,o,c;return s="{VAR_SELECT, select, true {Deep } other {}}",s=e.Zx4(s,{VAR_SELECT:"\ufffd0\ufffd"}),t="OSDs " + s + "Scrub",o="{VAR_SELECT, select, true {deep } other {}}",o=e.Zx4(o,{VAR_SELECT:"\ufffd0\ufffd"}),c="You are about to apply a " + o + "scrub to the OSD(s): " + "\ufffd#9\ufffd" + "" + "\ufffd1\ufffd" + "" + "\ufffd/#9\ufffd" + ".",[[3,"modalRef"],[1,"modal-title"],t,[1,"modal-content"],["name","scrubForm","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],c,[1,"modal-footer"],[3,"form","submitText","submitActionEvent"]]},template:function(t,o){1&t&&(e.TgZ(0,"cd-modal",0),e.TgZ(1,"span",1),e.SDv(2,2),e.qZA(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.TgZ(7,"p"),e.tHW(8,7),e._UZ(9,"strong"),e.ALo(10,"join"),e.N_p(),e.qZA(),e.qZA(),e.TgZ(11,"div",8),e.TgZ(12,"cd-form-button-panel",9),e.NdJ("submitActionEvent",function(){return o.scrub()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t&&(e.Q6J("modalRef",o.activeModal),e.xp6(2),e.pQV(o.deep),e.QtT(2),e.xp6(2),e.Q6J("formGroup",o.scrubForm),e.xp6(6),e.pQV(o.deep)(e.lcZ(10,7,o.selected)),e.QtT(8),e.xp6(2),e.Q6J("form",o.scrubForm)("submitText",o.actionLabels.UPDATE))},directives:[bu.z,Mn._Y,Mn.JL,ll.V,Mn.sg,ul.p],pipes:[Ev.A],styles:[""]}),n})();var ny=i(98056);function ry(n,s){if(1&n&&e._UZ(0,"cd-device-list",17),2&n){const t=e.oxw(2);e.Q6J("osdId",null==t.osd?null:t.osd.id)}}function iy(n,s){if(1&n&&e._UZ(0,"cd-table-key-value",18),2&n){const t=e.oxw(2);e.Q6J("data",null==t.osd||null==t.osd.details?null:t.osd.details.osd_map)}}function T1(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-table-key-value",21),e.NdJ("fetchData",function(){return e.CHM(t),e.oxw(3).refresh()}),e.qZA()}if(2&n){const t=e.oxw(3);e.Q6J("data",null==t.osd||null==t.osd.details?null:t.osd.details.osd_metadata)}}function Hb(n,s){1&n&&(e.TgZ(0,"cd-alert-panel",22),e.SDv(1,23),e.qZA())}function Nf(n,s){if(1&n&&(e.YNc(0,T1,1,1,"cd-table-key-value",19),e.YNc(1,Hb,2,0,"ng-template",null,20,e.W1O)),2&n){const t=e.MAs(2),o=e.oxw(2);e.Q6J("ngIf",null==o.osd||null==o.osd.details?null:o.osd.details.osd_metadata)("ngIfElse",t)}}function S1(n,s){if(1&n&&e._UZ(0,"cd-smart-list",17),2&n){const t=e.oxw(2);e.Q6J("osdId",null==t.osd?null:t.osd.id)}}function Ub(n,s){if(1&n&&e._UZ(0,"cd-table-performance-counter",25),2&n){const t=e.oxw(3);e.Q6J("serviceId",null==t.osd?null:t.osd.id)}}function Bb(n,s){if(1&n&&e.YNc(0,Ub,1,1,"cd-table-performance-counter",24),2&n){const t=e.oxw(2);e.Q6J("ngIf",null==t.osd?null:t.osd.details)}}function Yb(n,s){if(1&n&&e._UZ(0,"cd-grafana",28),2&n){const t=e.oxw(3);e.Q6J("grafanaPath","osd-device-details?var-osd=osd."+t.osd.id)}}function Zb(n,s){1&n&&(e.TgZ(0,"li",26),e.TgZ(1,"a",4),e.SDv(2,27),e.qZA(),e.YNc(3,Yb,1,1,"ng-template",6),e.qZA())}function C1(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"ul",1,2),e.TgZ(3,"li",3),e.TgZ(4,"a",4),e.SDv(5,5),e.qZA(),e.YNc(6,ry,1,1,"ng-template",6),e.qZA(),e.TgZ(7,"li",7),e.TgZ(8,"a",4),e.SDv(9,8),e.qZA(),e.YNc(10,iy,1,1,"ng-template",6),e.qZA(),e.TgZ(11,"li",9),e.TgZ(12,"a",4),e.SDv(13,10),e.qZA(),e.YNc(14,Nf,3,2,"ng-template",6),e.qZA(),e.TgZ(15,"li",11),e.TgZ(16,"a",4),e.SDv(17,12),e.qZA(),e.YNc(18,S1,1,1,"ng-template",6),e.qZA(),e.TgZ(19,"li",13),e.TgZ(20,"a",4),e.SDv(21,14),e.qZA(),e.YNc(22,Bb,1,1,"ng-template",6),e.qZA(),e.YNc(23,Zb,4,0,"li",15),e.qZA(),e._UZ(24,"div",16),e.BQk()),2&n){const t=e.MAs(2),o=e.oxw();e.xp6(23),e.Q6J("ngIf",o.grafanaPermission.read),e.xp6(1),e.Q6J("ngbNavOutlet",t)}}let Tv=(()=>{class n{constructor(t,o){this.osdService=t,this.authStorageService=o,this.grafanaPermission=this.authStorageService.getPermissions().grafana}ngOnChanges(){var t,o,c;(null===(t=this.osd)||void 0===t?void 0:t.id)!==(null===(o=this.selection)||void 0===o?void 0:o.id)&&(this.osd=this.selection),wr().isNumber(null===(c=this.osd)||void 0===c?void 0:c.id)&&this.refresh()}refresh(){this.osdService.getDetails(this.osd.id).subscribe(t=>{this.osd.details=t})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Ji),e.Y36(vt.j))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-osd-details"]],inputs:{selection:"selection"},features:[e.TTD],decls:1,vars:1,consts:function(){let s,t,o,c,g,C,D;return s="Devices",t="Attributes (OSD map)",o="Metadata",c="Device health",g="Performance counter",C="Metadata not available",D="Performance Details",[[4,"ngIf"],["ngbNav","","id","tabset-osd-details","cdStatefulTab","osd-details",1,"nav-tabs"],["nav","ngbNav"],["ngbNavItem","devices"],["ngbNavLink",""],s,["ngbNavContent",""],["ngbNavItem","attributes"],t,["ngbNavItem","metadata"],o,["ngbNavItem","device-health"],c,["ngbNavItem","performance-counter"],g,["ngbNavItem","performance-details",4,"ngIf"],[3,"ngbNavOutlet"],[3,"osdId"],[3,"data"],[3,"data","fetchData",4,"ngIf","ngIfElse"],["noMetaData",""],[3,"data","fetchData"],["type","warning"],C,["serviceType","osd",3,"serviceId",4,"ngIf"],["serviceType","osd",3,"serviceId"],["ngbNavItem","performance-details"],D,["uid","CrAHE0iZz","grafanaStyle","three",3,"grafanaPath"]]},template:function(t,o){1&t&&e.YNc(0,C1,25,2,"ng-container",0),2&t&&e.Q6J("ngIf",o.selection)},directives:[_.O5,ut.Pz,un.m,ut.nv,ut.Vx,ut.uN,ut.tO,Pa,zr.b,gt.G,Jn,ny.p,ot.F],styles:[""]}),n})();const tg=["osdUsageTpl"],oy=["markOsdConfirmationTpl"],mh=["criticalConfirmationTpl"],Hm=["reweightBodyTpl"],jb=["safeToDestroyBodyTpl"],sy=["deleteOsdExtraTpl"],M1=["flagsTpl"],Kh=function(){return{read:!0}};function Um(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-table",13),e.NdJ("fetchData",function(){return e.CHM(t),e.oxw().getOsdList()})("setExpandedRow",function(c){return e.CHM(t),e.oxw().setExpandedRow(c)})("updateSelection",function(c){return e.CHM(t),e.oxw().updateSelection(c)}),e.TgZ(1,"div",14),e._UZ(2,"cd-table-actions",15),e._UZ(3,"cd-table-actions",16),e.qZA(),e._UZ(4,"cd-osd-details",17),e.qZA()}if(2&n){const t=e.oxw();e.Q6J("data",t.osds)("columns",t.columns)("hasDetails",!0)("updateSelectionOnRefresh","never"),e.xp6(2),e.Q6J("permission",t.permissions.osd)("selection",t.selection)("tableActions",t.tableActions),e.xp6(1),e.Q6J("permission",e.DdM(11,Kh))("selection",t.selection)("tableActions",t.clusterWideActions),e.xp6(1),e.Q6J("selection",t.expandedRow)}}function nf(n,s){1&n&&e._UZ(0,"cd-grafana",19),2&n&&e.Q6J("grafanaPath","osd-overview?")}function A_(n,s){1&n&&(e.TgZ(0,"li",2),e.TgZ(1,"a",3),e.SDv(2,18),e.qZA(),e.YNc(3,nf,1,1,"ng-template",5),e.qZA())}function Sv(n,s){if(1&n&&(e.ynx(0),e.tHW(1,20),e._UZ(2,"strong"),e.ALo(3,"join"),e._UZ(4,"strong"),e.N_p(),e.BQk()),2&n){const t=s.markActionDescription,o=s.osdIds;e.xp6(4),e.pQV(e.lcZ(3,2,o))(t),e.QtT(1)}}function zp(n,s){if(1&n&&(e.TgZ(0,"li"),e.SDv(1,28),e.ALo(2,"join"),e.qZA()),2&n){const t=e.oxw(2).active,o=e.oxw();e.xp6(2),e.pQV(o.selection.hasSingleSelection)(e.lcZ(2,3,t))(1===t.length),e.QtT(1)}}function A1(n,s){if(1&n&&(e.TgZ(0,"li"),e.SDv(1,29),e.ALo(2,"join"),e.qZA()),2&n){const t=e.oxw(2).missingStats,o=e.oxw();e.xp6(2),e.pQV(o.selection.hasSingleSelection)(e.lcZ(2,2,t)),e.QtT(1)}}function Xg(n,s){if(1&n&&(e.TgZ(0,"li"),e.SDv(1,30),e.ALo(2,"join"),e.qZA()),2&n){const t=e.oxw(2).storedPgs,o=e.oxw();e.xp6(2),e.pQV(o.selection.hasSingleSelection)(e.lcZ(2,2,t)),e.QtT(1)}}function Kg(n,s){if(1&n&&(e.TgZ(0,"li"),e._uU(1),e.qZA()),2&n){const t=e.oxw(2).message;e.xp6(1),e.hij(" ",t," ")}}function qg(n,s){if(1&n&&(e.TgZ(0,"div",23),e.TgZ(1,"cd-alert-panel",24),e.TgZ(2,"span"),e.SDv(3,25),e.qZA(),e._UZ(4,"br"),e.TgZ(5,"ul",26),e.YNc(6,zp,3,5,"li",27),e.YNc(7,A1,3,4,"li",27),e.YNc(8,Xg,3,4,"li",27),e.YNc(9,Kg,2,1,"li",27),e.qZA(),e.qZA(),e.qZA()),2&n){const t=e.oxw(),o=t.actionDescription,c=t.active,g=t.missingStats,C=t.storedPgs,D=t.message,P=e.oxw();e.xp6(3),e.pQV(P.selection.hasSingleSelection)(o),e.QtT(3),e.xp6(3),e.Q6J("ngIf",c.length>0),e.xp6(1),e.Q6J("ngIf",g.length>0),e.xp6(1),e.Q6J("ngIf",C.length>0),e.xp6(1),e.Q6J("ngIf",D)}}function em(n,s){if(1&n&&(e.TgZ(0,"div",23),e.TgZ(1,"cd-alert-panel",31),e.TgZ(2,"span"),e.SDv(3,32),e.qZA(),e.qZA(),e.qZA()),2&n){const t=e.oxw(2);e.xp6(3),e.pQV(t.selection.hasSingleSelection),e.QtT(3)}}function tm(n,s){if(1&n&&(e.YNc(0,qg,10,6,"div",21),e.YNc(1,em,4,1,"div",21),e.ynx(2),e.tHW(3,22),e._UZ(4,"strong"),e.ALo(5,"join"),e._UZ(6,"strong"),e.N_p(),e.BQk()),2&n){const t=s.safeToPerform,o=s.actionDescription,c=s.osdIds;e.Q6J("ngIf",!t),e.xp6(1),e.Q6J("ngIf",t),e.xp6(5),e.pQV(e.lcZ(5,4,c))(o),e.QtT(3)}}function nm(n,s){if(1&n&&(e.TgZ(0,"span",35),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.xp6(1),e.Oqu(t)}}function rm(n,s){if(1&n&&(e.TgZ(0,"span",36),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.xp6(1),e.Oqu(t)}}function im(n,s){if(1&n&&(e.YNc(0,nm,2,1,"span",33),e.YNc(1,rm,2,1,"span",34)),2&n){const t=s.row;e.Q6J("ngForOf",t.cdClusterFlags),e.xp6(1),e.Q6J("ngForOf",t.cdIndivFlags)}}function om(n,s){if(1&n&&e._UZ(0,"cd-usage-bar",37),2&n){const t=s.row,o=e.oxw();e.Q6J("total",t.stats.stat_bytes)("used",t.stats.stat_bytes_used)("warningThreshold",o.osdSettings.nearfull_ratio)("errorThreshold",o.osdSettings.full_ratio)}}function ay(n,s){1&n&&(e.ynx(0,38),e.ynx(1,39),e.TgZ(2,"div",40),e.TgZ(3,"div",41),e._UZ(4,"input",42),e.TgZ(5,"label",43),e.SDv(6,44),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.BQk()),2&n&&e.Q6J("formGroup",s.form)}let uy=(()=>{class n extends jl.o{constructor(t,o,c,g,C,D,P,j,W,re){super(),this.authStorageService=t,this.osdService=o,this.dimlessBinaryPipe=c,this.modalService=g,this.urlBuilder=C,this.router=D,this.taskWrapper=P,this.actionLabels=j,this.notificationService=W,this.orchService=re,this.icons=xo.P,this.osdSettings=new Ac,this.selection=new El.r,this.osds=[],this.disabledFlags=["sortbitwise","purged_snapdirs","recovery_deletes","pglog_hardlimit"],this.indivFlagNames=["noup","nodown","noin","noout"],this.actionOrchFeatures={create:[cu.OSD_CREATE],delete:[cu.OSD_DELETE]},this.permissions=this.authStorageService.getPermissions(),this.tableActions=[{name:this.actionLabels.CREATE,permission:"create",icon:xo.P.add,click:()=>this.router.navigate([this.urlBuilder.getCreate()]),disable:oe=>this.getDisable("create",oe),canBePrimary:oe=>!oe.hasSelection},{name:this.actionLabels.EDIT,permission:"update",icon:xo.P.edit,click:()=>this.editAction()},{name:this.actionLabels.FLAGS,permission:"update",icon:xo.P.flag,click:()=>this.configureFlagsIndivAction(),disable:()=>!this.hasOsdSelected},{name:this.actionLabels.SCRUB,permission:"update",icon:xo.P.analyse,click:()=>this.scrubAction(!1),disable:()=>!this.hasOsdSelected,canBePrimary:oe=>oe.hasSelection},{name:this.actionLabels.DEEP_SCRUB,permission:"update",icon:xo.P.deepCheck,click:()=>this.scrubAction(!0),disable:()=>!this.hasOsdSelected},{name:this.actionLabels.REWEIGHT,permission:"update",click:()=>this.reweight(),disable:()=>!this.hasOsdSelected||!this.selection.hasSingleSelection,icon:xo.P.reweight},{name:this.actionLabels.MARK_OUT,permission:"update",click:()=>this.showConfirmationModal("out",this.osdService.markOut),disable:()=>this.isNotSelectedOrInState("out"),icon:xo.P.left},{name:this.actionLabels.MARK_IN,permission:"update",click:()=>this.showConfirmationModal("in",this.osdService.markIn),disable:()=>this.isNotSelectedOrInState("in"),icon:xo.P.right},{name:this.actionLabels.MARK_DOWN,permission:"update",click:()=>this.showConfirmationModal("down",this.osdService.markDown),disable:()=>this.isNotSelectedOrInState("down"),icon:xo.P.down},{name:this.actionLabels.MARK_LOST,permission:"delete",click:()=>this.showCriticalConfirmationModal("Mark","OSD lost","marked lost",oe=>this.osdService.safeToDestroy(JSON.stringify(oe)),"is_safe_to_destroy",this.osdService.markLost),disable:()=>this.isNotSelectedOrInState("up"),icon:xo.P.flatten},{name:this.actionLabels.PURGE,permission:"delete",click:()=>this.showCriticalConfirmationModal("Purge","OSD","purged",oe=>this.osdService.safeToDestroy(JSON.stringify(oe)),"is_safe_to_destroy",oe=>(this.selection=new El.r,this.osdService.purge(oe))),disable:()=>this.isNotSelectedOrInState("up"),icon:xo.P.erase},{name:this.actionLabels.DESTROY,permission:"delete",click:()=>this.showCriticalConfirmationModal("destroy","OSD","destroyed",oe=>this.osdService.safeToDestroy(JSON.stringify(oe)),"is_safe_to_destroy",oe=>(this.selection=new El.r,this.osdService.destroy(oe))),disable:()=>this.isNotSelectedOrInState("up"),icon:xo.P.destroyCircle},{name:this.actionLabels.DELETE,permission:"delete",click:()=>this.delete(),disable:oe=>this.getDisable("delete",oe),icon:xo.P.destroy}]}static collectStates(t){const o=[t.in?"in":"out"];return t.up?o.push("up"):t.state.includes("destroyed")?o.push("destroyed"):o.push("down"),o}ngOnInit(){this.clusterWideActions=[{name:"Flags",icon:xo.P.flag,click:()=>this.configureFlagsAction(),permission:"read",visible:()=>this.permissions.osd.read},{name:"Recovery Priority",icon:xo.P.deepCheck,click:()=>this.configureQosParamsAction(),permission:"read",visible:()=>this.permissions.configOpt.read},{name:"PG scrub",icon:xo.P.analyse,click:()=>this.configurePgScrubAction(),permission:"read",visible:()=>this.permissions.configOpt.read}],this.columns=[{prop:"id",name:"ID",flexGrow:1,cellTransformation:bl.e.executing,customTemplateConfig:{valueClass:"bold"}},{prop:"host.name",name:"Host"},{prop:"collectedStates",name:"Status",flexGrow:1,cellTransformation:bl.e.badge,customTemplateConfig:{map:{in:{class:"badge-success"},up:{class:"badge-success"},down:{class:"badge-danger"},out:{class:"badge-danger"},destroyed:{class:"badge-danger"}}}},{prop:"tree.device_class",name:"Device class",flexGrow:1.2,cellTransformation:bl.e.badge,customTemplateConfig:{map:{hdd:{class:"badge-hdd"},ssd:{class:"badge-ssd"}}}},{prop:"stats.numpg",name:"PGs",flexGrow:1},{prop:"stats.stat_bytes",name:"Size",flexGrow:1,pipe:this.dimlessBinaryPipe},{prop:"state",name:"Flags",cellTemplate:this.flagsTpl},{prop:"stats.usage",name:"Usage",cellTemplate:this.osdUsageTpl},{prop:"stats_history.out_bytes",name:"Read bytes",cellTransformation:bl.e.sparkline},{prop:"stats_history.in_bytes",name:"Write bytes",cellTransformation:bl.e.sparkline},{prop:"stats.op_r",name:"Read ops",cellTransformation:bl.e.perSecond},{prop:"stats.op_w",name:"Write ops",cellTransformation:bl.e.perSecond}],this.orchService.status().subscribe(t=>this.orchStatus=t),this.osdService.getOsdSettings().pipe((0,ve.q)(1)).subscribe(t=>{this.osdSettings=t})}getDisable(t,o){if("delete"===t){if(!o.hasSelection)return!0;if(wr().some(this.getSelectedOsds(),g=>{const C=wr().get(g,"operational_status");return"deleting"===C||"unmanaged"===C}))return!0}return this.orchService.getTableActionDisableDesc(this.orchStatus,this.actionOrchFeatures[t])}getSelectedOsdIds(){const t=this.osds.map(o=>o.id);return this.selection.selected.map(o=>o.id).filter(o=>t.includes(o)).sort()}getSelectedOsds(){return this.osds.filter(t=>!wr().isUndefined(t)&&this.getSelectedOsdIds().includes(t.id))}get hasOsdSelected(){return this.getSelectedOsdIds().length>0}updateSelection(t){this.selection=t}isNotSelectedOrInState(t){const o=this.getSelectedOsds();if(0===o.length)return!0;switch(t){case"in":return o.some(c=>1===c.in);case"out":return o.some(c=>1!==c.in);case"down":return o.some(c=>1!==c.up);case"up":return o.some(c=>1===c.up)}}getOsdList(){const t=[this.osdService.getList(),this.osdService.getFlags()];(0,xc.D)(t).subscribe(o=>{this.osds=o[0].map(c=>{c.collectedStates=n.collectStates(c),c.stats_history.out_bytes=c.stats_history.op_out_bytes.map(C=>C[1]),c.stats_history.in_bytes=c.stats_history.op_in_bytes.map(C=>C[1]),c.stats.usage=c.stats.stat_bytes_used/c.stats.stat_bytes,c.cdIsBinary=!0,c.cdIndivFlags=c.state.filter(C=>this.indivFlagNames.includes(C)),c.cdClusterFlags=o[1].filter(C=>!this.disabledFlags.includes(C));const g=wr().get(c,"operational_status","unmanaged");return"unmanaged"!==g&&"working"!==g&&(c.cdExecuting=g),c})})}editAction(){const t=wr().filter(this.osds,["id",this.selection.first().id]).pop();this.modalService.show(zd.X,{titleText:"Edit OSD: " + t.id + "",fields:[{type:"text",name:"deviceClass",value:t.tree.device_class,label:"Device class",required:!0}],submitButtonText:"Edit OSD",onSubmit:o=>{this.osdService.update(t.id,o.deviceClass).subscribe(()=>{this.notificationService.show(pa.k.success,"Updated OSD '" + t.id + "'"),this.getOsdList()})}})}scrubAction(t){if(!this.hasOsdSelected)return;const o={selected:this.getSelectedOsdIds(),deep:t};this.bsModalRef=this.modalService.show(ty,o)}configureFlagsAction(){this.bsModalRef=this.modalService.show(Db)}configureFlagsIndivAction(){const t={selected:this.getSelectedOsds()};this.bsModalRef=this.modalService.show(m1,t)}showConfirmationModal(t,o){const c=this.getSelectedOsdIds();this.bsModalRef=this.modalService.show(td.Y,{titleText:"Mark OSD " + t + "",buttonText:"Mark " + t + "",bodyTpl:this.markOsdConfirmationTpl,bodyContext:{markActionDescription:t,osdIds:c},onSubmit:()=>{(0,xc.D)(this.getSelectedOsdIds().map(g=>o.call(this.osdService,g))).subscribe(()=>this.bsModalRef.close())}})}reweight(){const t=this.osds.filter(o=>o.id===this.selection.first().id).pop();this.bsModalRef=this.modalService.show(E1,{currentWeight:t.weight,osdId:t.id})}delete(){const t=new Hs.d({preserve:new Mn.NI(!1)});this.showCriticalConfirmationModal("delete","OSD","deleted",o=>this.osdService.safeToDelete(JSON.stringify(o)),"is_safe_to_delete",o=>(this.selection=new El.r,this.taskWrapper.wrapTaskAroundCall({task:new cl.R("osd/"+$i.MQ.DELETE,{svc_id:o}),call:this.osdService.delete(o,t.value.preserve,!0)})),!0,t,this.deleteOsdExtraTpl)}showCriticalConfirmationModal(t,o,c,g,C,D,P=!1,j,W){g(this.getSelectedOsdIds()).subscribe(re=>{const oe=this.modalService.show(Gl.M,{actionDescription:t,itemDescription:o,bodyTemplate:this.criticalConfirmationTpl,bodyContext:{safeToPerform:re[C],message:re.message,active:re.active,missingStats:re.missing_stats,storedPgs:re.stored_pgs,actionDescription:c,osdIds:this.getSelectedOsdIds()},childFormGroup:j,childFormGroupTemplate:W,submitAction:()=>{const me=(0,xc.D)(this.getSelectedOsdIds().map(_e=>D.call(this.osdService,_e)));P?me.subscribe({error:()=>{this.getOsdList(),oe.close()},complete:()=>oe.close()}):me.subscribe(()=>{this.getOsdList(),oe.close()},()=>oe.close())}})})}configureQosParamsAction(){this.bsModalRef=this.modalService.show(gh)}configurePgScrubAction(){this.bsModalRef=this.modalService.show(X0,void 0,{size:"lg"})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(vt.j),e.Y36(Ji),e.Y36(mn.$),e.Y36(Bl.Z),e.Y36(Lu.F),e.Y36(Bo.F0),e.Y36(Ll.P),e.Y36($i.p4),e.Y36(hl.g),e.Y36(Mc))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-osd-list"]],viewQuery:function(t,o){if(1&t&&(e.Gf(tg,7),e.Gf(oy,7),e.Gf(mh,7),e.Gf(Hm,5),e.Gf(jb,5),e.Gf(sy,5),e.Gf(M1,7)),2&t){let c;e.iGM(c=e.CRH())&&(o.osdUsageTpl=c.first),e.iGM(c=e.CRH())&&(o.markOsdConfirmationTpl=c.first),e.iGM(c=e.CRH())&&(o.criticalConfirmationTpl=c.first),e.iGM(c=e.CRH())&&(o.reweightBodyTpl=c.first),e.iGM(c=e.CRH())&&(o.safeToDestroyBodyTpl=c.first),e.iGM(c=e.CRH())&&(o.deleteOsdExtraTpl=c.first),e.iGM(c=e.CRH())&&(o.flagsTpl=c.first)}},features:[e._Bn([{provide:Lu.F,useValue:new Lu.F("osd")}]),e.qOj],decls:18,vars:2,consts:function(){let s,t,o,c,g,C,D,P,j,W,re,oe,me,_e,Fe,Re;return s="OSDs List",t="Overall Performance",o="" + "[\ufffd#2\ufffd|\ufffd#4\ufffd]" + "OSD(s) " + "\ufffd0\ufffd" + "" + "[\ufffd/#2\ufffd|\ufffd/#4\ufffd]" + " will be marked " + "[\ufffd#2\ufffd|\ufffd#4\ufffd]" + "" + "\ufffd1\ufffd" + "" + "[\ufffd/#2\ufffd|\ufffd/#4\ufffd]" + " if you proceed.",o=e.Zx4(o),c="" + "[\ufffd#4\ufffd|\ufffd#6\ufffd]" + "OSD " + "\ufffd0\ufffd" + "" + "[\ufffd/#4\ufffd|\ufffd/#6\ufffd]" + " will be " + "[\ufffd#4\ufffd|\ufffd#6\ufffd]" + "" + "\ufffd1\ufffd" + "" + "[\ufffd/#4\ufffd|\ufffd/#6\ufffd]" + " if you proceed.",c=e.Zx4(c),g="{VAR_SELECT, select, true {OSD is} other {OSDs are}}",g=e.Zx4(g,{VAR_SELECT:"\ufffd0\ufffd"}),C=" The " + g + " not safe to be " + "\ufffd1\ufffd" + "! ",D="{VAR_SELECT, select, true {} other {{INTERPOLATION} : }}",D=e.Zx4(D,{VAR_SELECT:"\ufffd0\ufffd",INTERPOLATION:"\ufffd1\ufffd"}),P="{VAR_SELECT, select, true {it} other {them}}",P=e.Zx4(P,{VAR_SELECT:"\ufffd2\ufffd"}),j=" " + D + " Some PGs are currently mapped to " + P + ". ",W="{VAR_SELECT, select, true {} other {{INTERPOLATION} : }}",W=e.Zx4(W,{VAR_SELECT:"\ufffd0\ufffd",INTERPOLATION:"\ufffd1\ufffd"}),re=" " + W + " There are no reported stats and not all PGs are active and clean. ",oe="{VAR_SELECT, select, true {OSD} other {{INTERPOLATION} : OSDs }}",oe=e.Zx4(oe,{VAR_SELECT:"\ufffd0\ufffd",INTERPOLATION:"\ufffd1\ufffd"}),me=" " + oe + " still store some PG data and not all PGs are active and clean. ",_e="{VAR_SELECT, select, true {OSD is} other {OSDs are}}",_e=e.Zx4(_e,{VAR_SELECT:"\ufffd0\ufffd"}),Fe=" The " + _e + " safe to destroy without reducing data durability. ",Re="Preserve OSD ID(s) for replacement.",[["ngbNav","",1,"nav-tabs"],["nav","ngbNav"],["ngbNavItem",""],["ngbNavLink",""],s,["ngbNavContent",""],["ngbNavItem","",4,"ngIf"],[3,"ngbNavOutlet"],["markOsdConfirmationTpl",""],["criticalConfirmationTpl",""],["flagsTpl",""],["osdUsageTpl",""],["deleteOsdExtraTpl",""],["selectionType","multiClick",3,"data","columns","hasDetails","updateSelectionOnRefresh","fetchData","setExpandedRow","updateSelection"],[1,"table-actions","btn-toolbar"],["id","osd-actions",1,"btn-group",3,"permission","selection","tableActions"],["dropDownOnly","Cluster-wide configuration","btnColor","light","id","cluster-wide-actions",1,"btn-group",3,"permission","selection","tableActions"],["cdTableDetail","",3,"selection"],t,["uid","lo02I1Aiz","grafanaStyle","four",3,"grafanaPath"],o,["class","danger mb-3",4,"ngIf"],c,[1,"danger","mb-3"],["type","warning"],C,[1,"mb-0","pl-4"],[4,"ngIf"],j,re,me,["type","info"],Fe,["class","badge badge-hdd mr-1",4,"ngFor","ngForOf"],["class","badge badge-info mr-1",4,"ngFor","ngForOf"],[1,"badge","badge-hdd","mr-1"],[1,"badge","badge-info","mr-1"],[3,"total","used","warningThreshold","errorThreshold"],[3,"formGroup"],["formGroupName","child"],[1,"form-group"],[1,"custom-control","custom-checkbox"],["type","checkbox","name","preserve","id","preserve","formControlName","preserve",1,"custom-control-input"],["for","preserve",1,"custom-control-label"],Re]},template:function(t,o){if(1&t&&(e.TgZ(0,"ul",0,1),e.TgZ(2,"li",2),e.TgZ(3,"a",3),e.SDv(4,4),e.qZA(),e.YNc(5,Um,5,12,"ng-template",5),e.qZA(),e.YNc(6,A_,4,0,"li",6),e.qZA(),e._UZ(7,"div",7),e.YNc(8,Sv,5,4,"ng-template",null,8,e.W1O),e.YNc(10,tm,7,6,"ng-template",null,9,e.W1O),e.YNc(12,im,2,2,"ng-template",null,10,e.W1O),e.YNc(14,om,1,4,"ng-template",null,11,e.W1O),e.YNc(16,ay,7,1,"ng-template",null,12,e.W1O)),2&t){const c=e.MAs(1);e.xp6(6),e.Q6J("ngIf",o.permissions.grafana.read),e.xp6(1),e.Q6J("ngbNavOutlet",c)}},directives:[ut.Pz,ut.nv,ut.Vx,ut.uN,_.O5,ut.tO,ks.a,Js.K,Tv,ot.F,gt.G,_.sg,ao.O,ll.V,Mn.JL,Mn.sg,Mn.x0,Za.P,la.o,Mn.Wl,ja.b,Mn.JJ,Mn.u],pipes:[Ev.A],styles:[""]}),n})();var O1=i(9837);let ng=(()=>{class n{constructor(t,o){this.http=t,this.settingsService=o,this.baseURL="api/prometheus",this.settingsKey={alertmanager:"api/settings/alertmanager-api-host",prometheus:"api/settings/prometheus-api-host"}}ifAlertmanagerConfigured(t,o){this.settingsService.ifSettingConfigured(this.settingsKey.alertmanager,t,o)}disableAlertmanagerConfig(){this.settingsService.disableSetting(this.settingsKey.alertmanager)}ifPrometheusConfigured(t,o){this.settingsService.ifSettingConfigured(this.settingsKey.prometheus,t,o)}disablePrometheusConfig(){this.settingsService.disableSetting(this.settingsKey.prometheus)}getAlerts(t={}){return this.http.get(this.baseURL,{params:t})}getSilences(t={}){return this.http.get(`${this.baseURL}/silences`,{params:t})}getRules(t="all"){return this.http.get(`${this.baseURL}/rules`).pipe((0,hu.U)(o=>(["alerting","rewrites"].includes(t)&&o.groups.map(c=>{c.rules=c.rules.filter(g=>g.type===t)}),o)))}setSilence(t){return this.http.post(`${this.baseURL}/silence`,t,{observe:"response"})}expireSilence(t){return this.http.delete(`${this.baseURL}/silence/${t}`,{observe:"response"})}getNotifications(t){return this.http.get(`${this.baseURL}/notifications?from=${t&&t.id?t.id:"last"}`)}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(y.eN),e.LFG(O1.g))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();var Cv=i(61355);let w1=(()=>{class n{constructor(t){this.notificationService=t}sendNotifications(t){t.forEach(o=>this.notificationService.show(o))}convertToCustomAlerts(t){return wr().uniqWith(t.map(o=>({status:wr().isObject(o.status)?o.status.state:this.getPrometheusNotificationStatus(o),name:o.labels.alertname,url:o.generatorURL,description:o.annotations.description,fingerprint:wr().isObject(o.status)&&o.fingerprint})),wr().isEqual)}getPrometheusNotificationStatus(t){const o=t.status;return"firing"===o?"active":o}convertAlertToNotification(t){return new Cv.T(this.formatType(t.status),`${t.name} (${t.status})`,this.appendSourceLink(t,t.description),void 0,"Prometheus")}formatType(t){return pa.k[wr().findKey({error:["firing","active"],info:["suppressed","unprocessed"],success:["resolved"]},c=>c.includes(t))]}appendSourceLink(t,o){return`${o} <a href="${t.url}" target="_blank"><i class="${xo.P.lineChart}"></i></a>`}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(hl.g))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})(),Bm=(()=>{class n{constructor(t,o){this.alertFormatter=t,this.prometheusService=o,this.canAlertsBeNotified=!1,this.alerts=[],this.rules=[]}getAlerts(){this.prometheusService.ifAlertmanagerConfigured(()=>{this.prometheusService.getAlerts().subscribe(t=>this.handleAlerts(t),t=>{[404,504].includes(t.status)&&this.prometheusService.disableAlertmanagerConfig()})})}getRules(){this.prometheusService.ifPrometheusConfigured(()=>{this.prometheusService.getRules("alerting").subscribe(t=>{this.rules=t.groups.reduce((o,c)=>o.concat(c.rules.map(g=>(g.group=c.name,g))),[])})})}refresh(){this.getAlerts(),this.getRules()}handleAlerts(t){this.canAlertsBeNotified&&this.notifyOnAlertChanges(t,this.alerts),this.activeAlerts=wr().reduce(this.alerts,(o,c)=>"active"===c.status.state?++o:o,0),this.alerts=t,this.canAlertsBeNotified=!0}notifyOnAlertChanges(t,o){const c=this.getChangedAlerts(this.alertFormatter.convertToCustomAlerts(t),this.alertFormatter.convertToCustomAlerts(o)),C=wr().filter(c,D=>"suppressed"!==D.status).map(D=>this.alertFormatter.convertAlertToNotification(D));this.alertFormatter.sendNotifications(C)}getChangedAlerts(t,o){return wr().differenceWith(t,o,wr().isEqual).concat(this.getVanishedAlerts(t,o))}getVanishedAlerts(t,o){return wr().differenceWith(o,t,(c,g)=>c.fingerprint===g.fingerprint).map(c=>(c.status="resolved",c))}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(w1),e.LFG(ng))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})(),Mv=(()=>{class n extends jl.o{constructor(t){super(),this.prometheusService=t,this.isPrometheusConfigured=!1,this.isAlertmanagerConfigured=!1}ngOnInit(){this.prometheusService.ifAlertmanagerConfigured(()=>{this.isAlertmanagerConfigured=!0}),this.prometheusService.ifPrometheusConfigured(()=>{this.isPrometheusConfigured=!0})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(ng))},n.\u0275dir=e.lG2({type:n,features:[e.qOj]}),n})(),O=(()=>{class n{constructor(t){this.router=t}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Bo.F0))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-prometheus-tabs"]],decls:11,vars:1,consts:function(){let s,t,o;return s="Active Alerts",t="Alerts",o="Silences",[["ngbNav","",1,"nav-tabs",3,"activeId","navChange"],["nav","ngbNav"],["ngbNavItem","/monitoring/active-alerts"],["ngbNavLink",""],s,["ngbNavItem","/monitoring/alerts"],t,["ngbNavItem","/monitoring/silences"],o]},template:function(t,o){1&t&&(e.TgZ(0,"ul",0,1),e.NdJ("navChange",function(g){return o.router.navigate([g.nextId])}),e.TgZ(2,"li",2),e.TgZ(3,"a",3),e.SDv(4,4),e.qZA(),e.qZA(),e.TgZ(5,"li",5),e.TgZ(6,"a",3),e.SDv(7,6),e.qZA(),e.qZA(),e.TgZ(8,"li",7),e.TgZ(9,"a",3),e.SDv(10,8),e.qZA(),e.qZA(),e.qZA()),2&t&&e.Q6J("activeId",o.router.url)},directives:[ut.Pz,ut.nv,ut.Vx],styles:[""]}),n})();const $=["externalLinkTpl"];function pe(n,s){1&n&&(e.TgZ(0,"cd-alert-panel",3),e.tHW(1,4),e._UZ(2,"cd-doc",5),e.N_p(),e.qZA())}function Ke(n,s){if(1&n&&e._UZ(0,"cd-table-key-value",9),2&n){const t=e.oxw(2);e.Q6J("renderObjects",!0)("hideEmpty",!0)("appendParentKey",!1)("data",t.expandedRow)("customCss",t.customCss)("autoReload",!1)}}function Ht(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-table",6),e.NdJ("setExpandedRow",function(c){return e.CHM(t),e.oxw().setExpandedRow(c)})("updateSelection",function(c){return e.CHM(t),e.oxw().updateSelection(c)}),e._UZ(1,"cd-table-actions",7),e.YNc(2,Ke,1,6,"cd-table-key-value",8),e.qZA()}if(2&n){const t=e.oxw();e.Q6J("data",t.prometheusAlertService.alerts)("columns",t.columns)("forceIdentifier",!0)("customCss",t.customCss)("hasDetails",!0),e.xp6(1),e.Q6J("permission",t.permission)("selection",t.selection)("tableActions",t.tableActions),e.xp6(1),e.Q6J("ngIf",t.expandedRow)}}const pn=function(n){return[n]};function Kn(n,s){if(1&n&&(e.TgZ(0,"a",10),e._UZ(1,"i",11),e._uU(2," Source"),e.qZA()),2&n){const t=s.value,o=e.oxw();e.Q6J("href",t,e.LSH),e.xp6(1),e.Q6J("ngClass",e.VKq(2,pn,o.icons.lineChart))}}let qr=(()=>{class n extends Mv{constructor(t,o,c,g,C){super(C),this.authStorageService=t,this.prometheusAlertService=o,this.urlBuilder=c,this.cdDatePipe=g,this.selection=new El.r,this.icons=xo.P,this.customCss={"badge badge-danger":"active","badge badge-warning":"unprocessed","badge badge-info":"suppressed"},this.permission=this.authStorageService.getPermissions().prometheus,this.tableActions=[{permission:"create",canBePrimary:D=>D.hasSingleSelection,disable:D=>!D.hasSingleSelection||D.first().cdExecuting,icon:xo.P.add,routerLink:()=>"/monitoring"+this.urlBuilder.getCreateFrom(this.selection.first().fingerprint),name:"Create Silence"}]}ngOnInit(){super.ngOnInit(),this.columns=[{name:"Name",prop:"labels.alertname",flexGrow:2},{name:"Job",prop:"labels.job",flexGrow:2},{name:"Severity",prop:"labels.severity"},{name:"State",prop:"status.state",cellTransformation:bl.e.classAdding},{name:"Started",prop:"startsAt",pipe:this.cdDatePipe},{name:"URL",prop:"generatorURL",sortable:!1,cellTemplate:this.externalLinkTpl}]}updateSelection(t){this.selection=t}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(vt.j),e.Y36(Bm),e.Y36(Lu.F),e.Y36(Ul.N),e.Y36(ng))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-active-alert-list"]],viewQuery:function(t,o){if(1&t&&e.Gf($,7),2&t){let c;e.iGM(c=e.CRH())&&(o.externalLinkTpl=c.first)}},features:[e._Bn([{provide:Lu.F,useValue:new Lu.F("silences")}]),e.qOj],decls:5,vars:2,consts:function(){let s;return s="To see all active Prometheus alerts, please provide the URL to the API of Prometheus' Alertmanager as described in the " + "\ufffd#2\ufffd" + "" + "\ufffd/#2\ufffd" + ".",[["type","info",4,"ngIf"],["identifier","fingerprint","selectionType","single",3,"data","columns","forceIdentifier","customCss","hasDetails","setExpandedRow","updateSelection",4,"ngIf"],["externalLinkTpl",""],["type","info"],s,["section","prometheus"],["identifier","fingerprint","selectionType","single",3,"data","columns","forceIdentifier","customCss","hasDetails","setExpandedRow","updateSelection"],[1,"table-actions",3,"permission","selection","tableActions"],["cdTableDetail","",3,"renderObjects","hideEmpty","appendParentKey","data","customCss","autoReload",4,"ngIf"],["cdTableDetail","",3,"renderObjects","hideEmpty","appendParentKey","data","customCss","autoReload"],["target","_blank",3,"href"],[3,"ngClass"]]},template:function(t,o){1&t&&(e._UZ(0,"cd-prometheus-tabs"),e.YNc(1,pe,3,0,"cd-alert-panel",0),e.YNc(2,Ht,3,9,"cd-table",1),e.YNc(3,Kn,3,4,"ng-template",null,2,e.W1O)),2&t&&(e.xp6(1),e.Q6J("ngIf",!o.isAlertmanagerConfigured),e.xp6(1),e.Q6J("ngIf",o.isAlertmanagerConfigured))},directives:[O,_.O5,gt.G,il.K,ks.a,Js.K,zr.b,_.mk],styles:[""]}),n})(),no=(()=>{class n{transform(t){const o=[[`${Math.floor(t/31536e3)}`,"years"],[`${Math.floor(t%31536e3/86400)}`,"days"],[`${Math.floor(t%86400/3600)}`,"hours"],[`${Math.floor(t%3600/60)}`,"minutes"],[`${Math.floor(t%60)}`,"seconds"]];let c="";for(let g=0,C=o.length;g<C;g++)"0"!==o[g][0]&&(c+=" "+o[g][0]+" "+("1"===o[g][0]?o[g][1].substr(0,o[g][1].length-1):o[g][1]));return c.trim()||"1 second"}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275pipe=e.Yjl({name:"duration",type:n,pure:!1}),n})();function ro(n,s){1&n&&(e.TgZ(0,"cd-alert-panel",2),e.tHW(1,3),e._UZ(2,"cd-doc",4),e.N_p(),e.qZA())}function mo(n,s){if(1&n&&e._UZ(0,"cd-table-key-value",7),2&n){const t=e.oxw(2);e.Q6J("data",t.expandedRow)("renderObjects",!0)("hideKeys",t.hideKeys)}}function ds(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-table",5),e.NdJ("setExpandedRow",function(c){return e.CHM(t),e.oxw().setExpandedRow(c)})("updateSelection",function(c){return e.CHM(t),e.oxw().updateSelection(c)}),e.YNc(1,mo,1,3,"cd-table-key-value",6),e.qZA()}if(2&n){const t=e.oxw();e.Q6J("data",t.prometheusAlertService.rules)("columns",t.columns)("selectionType","single")("hasDetails",!0),e.xp6(1),e.Q6J("ngIf",t.expandedRow)}}let oa=(()=>{class n extends Mv{constructor(t,o){super(o),this.prometheusAlertService=t,this.hideKeys=["alerts","type"]}ngOnInit(){super.ngOnInit(),this.columns=[{prop:"name",name:"Name"},{prop:"labels.severity",name:"Severity"},{prop:"group",name:"Group"},{prop:"duration",name:"Duration",pipe:new no},{prop:"query",name:"Query",isHidden:!0},{prop:"annotations.description",name:"Description"}]}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Bm),e.Y36(ng))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-rules-list"]],features:[e.qOj],decls:3,vars:2,consts:function(){let s;return s="To see all configured Prometheus alerts, please provide the URL to the API of Prometheus as described in the " + "\ufffd#2\ufffd" + "" + "\ufffd/#2\ufffd" + ".",[["type","info",4,"ngIf"],[3,"data","columns","selectionType","hasDetails","setExpandedRow","updateSelection",4,"ngIf"],["type","info"],s,["section","prometheus"],[3,"data","columns","selectionType","hasDetails","setExpandedRow","updateSelection"],["cdTableDetail","",3,"data","renderObjects","hideKeys",4,"ngIf"],["cdTableDetail","",3,"data","renderObjects","hideKeys"]]},template:function(t,o){1&t&&(e._UZ(0,"cd-prometheus-tabs"),e.YNc(1,ro,3,0,"cd-alert-panel",0),e.YNc(2,ds,2,5,"cd-table",1)),2&t&&(e.xp6(1),e.Q6J("ngIf",!o.isPrometheusConfigured),e.xp6(1),e.Q6J("ngIf",o.isPrometheusConfigured))},directives:[O,_.O5,gt.G,il.K,ks.a,zr.b],styles:[""]}),n})();var Ia=i(26504);let Pl=(()=>{class n{constructor(){this.valueAttributePath={alertname:"name",instance:"alerts.0.labels.instance",job:"alerts.0.labels.job",severity:"labels.severity"}}singleMatch(t,o){return this.multiMatch([t],o)}multiMatch(t,o){if(!t.some(c=>c.isRegex))return t.forEach(c=>{o=this.getMatchedRules(c,o)}),this.describeMatch(o)}getMatchedRules(t,o){const c=this.getAttributePath(t.name);return o.filter(g=>wr().get(g,c)===t.value)}describeMatch(t){let o=0;return t.forEach(c=>o+=c.alerts.length),{status:this.getMatchText(t.length,o),cssClass:o?"has-success":"has-warning"}}getAttributePath(t){return this.valueAttributePath[t]}getMatchText(t,o){const c={noRule:"Your matcher seems to match no currently defined rule or active alert.",noAlerts:"no active alerts",alert:"1 active alert",alerts:"" + o + " active alerts",rule:"Matches 1 rule",rules:"Matches " + t + " rules"};return t?"" + (t > 1 ? c.rules : c.rule) + " with " + (o ? o > 1 ? c.alerts : c.alert : c.noAlerts) + ".":c.noRule}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})(),Va=(()=>{class n{calculateDuration(t,o){const c=+t,g=+o,C=this.getDuration(Math.abs(c-g));return c>g?"-"+C:C}getDuration(t){const o=new Date(t),c=o.getUTCHours(),g=o.getUTCMinutes(),D=(P,j)=>P&&P+j;return[D(Math.floor(t/864e5),"d"),D(c,"h"),D(g,"m")].filter(P=>P).join(" ")}calculateDate(t,o,c){const g=+t;if(wr().isNaN(g))return;const C=this.getDurationMs(o)*(c?-1:1);return new Date(g+C)}getDurationMs(t){return 6e4*(60*(24*this.getNumbersFromString(t,"d")+this.getNumbersFromString(t,"h"))+this.getNumbersFromString(t,"m"))}getNumbersFromString(t,o){const c=t.match(new RegExp(`[0-9 ]+${o}`,"i"));return c?parseInt(c[0],10):0}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();function su(n,s){if(1&n&&(e.TgZ(0,"option",27),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t),e.xp6(1),e.hij(" ",t," ")}}function vu(n,s){1&n&&(e.TgZ(0,"span",28),e.SDv(1,29),e.qZA())}function xp(n,s){1&n&&(e.TgZ(0,"span",28),e.SDv(1,30),e.qZA())}function op(n,s){if(1&n&&(e.TgZ(0,"div",31),e.TgZ(1,"span"),e._uU(2),e.qZA(),e.qZA()),2&n){const t=e.oxw();e.Gre("cd-col-form-offset ",t.matcherMatch.cssClass,""),e.xp6(1),e.Gre("text-muted ",t.matcherMatch.cssClass,""),e.xp6(1),e.hij(" ",t.matcherMatch.status," ")}}let Dp=(()=>{class n{constructor(t,o,c,g){this.formBuilder=t,this.silenceMatcher=o,this.activeModal=c,this.actionLabels=g,this.submitAction=new e.vpe,this.editMode=!1,this.nameAttributes=["alertname","instance","job","severity"],this.possibleValues=[],this.matcherMatch=void 0,this.valueClick=new bp.xQ,this.valueFocus=new bp.xQ,this.search=C=>(0,Bd.T)(C.pipe(zf(200),(0,Df.x)()),this.valueFocus,this.valueClick.pipe((0,np.h)(()=>!this.typeahead.isPopupOpen()))).pipe((0,hu.U)(D=>(""===D?this.possibleValues:this.possibleValues.filter(P=>P.toLowerCase().indexOf(D.toLowerCase())>-1)).slice(0,10))),this.createForm(),this.subscribeToChanges()}createForm(){this.form=this.formBuilder.group({name:[null,[Mn.kI.required]],value:[{value:"",disabled:!0},[Mn.kI.required]],isRegex:new Mn.NI(!1)})}subscribeToChanges(){this.form.get("name").valueChanges.subscribe(t=>{null!==t?(this.setPossibleValues(t),this.form.get("value").enable()):this.form.get("value").disable()}),this.form.get("value").valueChanges.subscribe(t=>{const o=this.form.value;o.value=t,this.matcherMatch=this.silenceMatcher.singleMatch(o,this.rules)})}setPossibleValues(t){this.possibleValues=wr().sortedUniq(this.rules.map(o=>wr().get(o,this.silenceMatcher.getAttributePath(t))).filter(o=>o))}getMode(){return this.editMode?this.actionLabels.EDIT:this.actionLabels.ADD}preFillControls(t){this.form.setValue(t)}onSubmit(){this.submitAction.emit(this.form.value),this.activeModal.close()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(rd.O),e.Y36(Pl),e.Y36(ut.Kz),e.Y36($i.p4))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-silence-matcher-modal"]],viewQuery:function(t,o){if(1&t&&e.Gf(ut.dR,7),2&t){let c;e.iGM(c=e.CRH())&&(o.typeahead=c.first)}},outputs:{submitAction:"submitAction"},decls:31,vars:11,consts:function(){let s,t,o,c,g,C,D,P;return s="{VAR_SELECT, select, true {Edit} other {Add}}",s=e.Zx4(s,{VAR_SELECT:"\ufffd0\ufffd"}),t="" + s + " Matcher",o="Name",c="-- Select an attribute to match against --",g="Value",C="Use regular expression",D="This field is required!",P="This field is required!",[[3,"modalRef"],[1,"modal-title"],t,[1,"modal-content"],["novalidate","",1,"form",3,"formGroup"],["formDir","ngForm"],[1,"modal-body"],[1,"form-group","row"],["for","name",1,"cd-col-form-label","required"],o,[1,"cd-col-form-input"],["id","name","formControlName","name","name","name",1,"form-control"],[3,"ngValue"],c,[3,"value",4,"ngFor","ngForOf"],["class","help-block",4,"ngIf"],["for","value",1,"cd-col-form-label","required"],g,["id","value","container","body","type","text","formControlName","value",1,"form-control",3,"ngbTypeahead","focus","click"],["id","match-state",3,"class",4,"ngIf"],[1,"cd-col-form-offset"],[1,"custom-control","custom-checkbox"],["type","checkbox","formControlName","isRegex","name","is-regex","id","is-regex",1,"custom-control-input"],["for","is-regex",1,"custom-control-label"],C,[1,"modal-footer"],[3,"form","submitText","submitActionEvent"],[3,"value"],[1,"help-block"],D,P,["id","match-state"]]},template:function(t,o){if(1&t&&(e.TgZ(0,"cd-modal",0),e.TgZ(1,"span",1),e.SDv(2,2),e.qZA(),e.ynx(3,3),e.TgZ(4,"form",4,5),e.TgZ(6,"div",6),e.TgZ(7,"div",7),e.TgZ(8,"label",8),e.SDv(9,9),e.qZA(),e.TgZ(10,"div",10),e.TgZ(11,"select",11),e.TgZ(12,"option",12),e.SDv(13,13),e.qZA(),e.YNc(14,su,2,2,"option",14),e.qZA(),e.YNc(15,vu,2,0,"span",15),e.qZA(),e.qZA(),e.TgZ(16,"div",7),e.TgZ(17,"label",16),e.SDv(18,17),e.qZA(),e.TgZ(19,"div",10),e.TgZ(20,"input",18),e.NdJ("focus",function(g){return o.valueFocus.next(g.target.value)})("click",function(g){return o.valueClick.next(g.target.value)}),e.qZA(),e.YNc(21,xp,2,0,"span",15),e.qZA(),e.YNc(22,op,3,7,"div",19),e.qZA(),e.TgZ(23,"div",7),e.TgZ(24,"div",20),e.TgZ(25,"div",21),e._UZ(26,"input",22),e.TgZ(27,"label",23),e.SDv(28,24),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(29,"div",25),e.TgZ(30,"cd-form-button-panel",26),e.NdJ("submitActionEvent",function(){return o.onSubmit()}),e.qZA(),e.qZA(),e.qZA(),e.BQk(),e.qZA()),2&t){const c=e.MAs(5);e.Q6J("modalRef",o.activeModal),e.xp6(2),e.pQV(o.editMode),e.QtT(2),e.xp6(2),e.Q6J("formGroup",o.form),e.xp6(8),e.Q6J("ngValue",null),e.xp6(2),e.Q6J("ngForOf",o.nameAttributes),e.xp6(1),e.Q6J("ngIf",o.form.showError("name",c,"required")),e.xp6(5),e.Q6J("ngbTypeahead",o.search),e.xp6(1),e.Q6J("ngIf",o.form.showError("value",c,"required")),e.xp6(1),e.Q6J("ngIf",o.form.getValue("value")&&!o.form.getValue("isRegex")&&o.matcherMatch),e.xp6(8),e.Q6J("form",o.form)("submitText",o.getMode())}},directives:[bu.z,Mn._Y,Mn.JL,ll.V,Mn.sg,Za.P,la.o,Mn.EJ,ja.b,Mn.JJ,Mn.u,Mn.YN,Mn.Kr,_.sg,_.O5,Mn.Fj,ut.dR,Mn.Wl,ul.p],styles:[""]}),n})();var hd=i(52266);function Rp(n,s){if(1&n&&(e.ynx(0),e._UZ(1,"input",53),e.BQk()),2&n){const t=e.oxw().$implicit,o=e.oxw(),c=o.index,g=o.matcher;e.xp6(1),e.hYB("id","matcher-",t.attribute,"-",c,""),e.Q6J("value",g[t.attribute])}}function vh(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"div",47),e.TgZ(2,"div",54),e._UZ(3,"input",55),e.qZA(),e.qZA(),e.BQk()),2&n){const t=e.oxw().$implicit,o=e.oxw(),c=o.index,g=o.matcher;e.xp6(3),e.hYB("id","matcher-",t.attribute,"-",c,""),e.Q6J("checked",g[t.attribute])}}const Ym=function(n){return[n]};function fR(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"div",51),e.TgZ(2,"span",52),e._UZ(3,"i",38),e.qZA(),e.qZA(),e.YNc(4,Rp,2,3,"ng-container",7),e.YNc(5,vh,4,3,"ng-container",7),e.BQk()),2&n){const t=s.$implicit;e.xp6(2),e.Q6J("ngbTooltip",t.tooltip),e.xp6(1),e.Q6J("ngClass",e.VKq(4,Ym,t.icon)),e.xp6(1),e.Q6J("ngIf","isRegex"!==t.attribute),e.xp6(1),e.Q6J("ngIf","isRegex"===t.attribute)}}function pR(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",46),e.YNc(1,fR,6,6,"ng-container",34),e.TgZ(2,"span",47),e.TgZ(3,"button",48),e.NdJ("click",function(){const g=e.CHM(t).index;return e.oxw().showMatcherModal(g)}),e._UZ(4,"i",38),e.qZA(),e.TgZ(5,"button",49),e.NdJ("click",function(){const g=e.CHM(t).index;return e.oxw().deleteMatcher(g)}),e._UZ(6,"i",38),e.qZA(),e.qZA(),e.qZA(),e._UZ(7,"span",50)}if(2&n){const t=s.index,o=e.oxw();e.xp6(1),e.Q6J("ngForOf",o.matcherConfig),e.xp6(2),e.MGl("id","matcher-edit-",t,""),e.xp6(1),e.Q6J("ngClass",e.VKq(5,Ym,o.icons.edit)),e.xp6(1),e.MGl("id","matcher-delete-",t,""),e.xp6(1),e.Q6J("ngClass",e.VKq(7,Ym,o.icons.trash))}}function hR(n,s){1&n&&(e.TgZ(0,"cd-helper"),e.SDv(1,56),e.qZA())}function XA(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,58),e.qZA())}function wS(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,59),e.qZA())}function _R(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,60),e.qZA())}function KA(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,61),e.qZA())}function Av(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,62),e.qZA())}const qA=function(n,s){return{"text-warning":n,"text-danger":s}};function xS(n,s){if(1&n&&(e.TgZ(0,"h5",38),e.TgZ(1,"strong"),e.SDv(2,63),e.qZA(),e.qZA()),2&n){e.oxw();const t=e.MAs(4);e.Q6J("ngClass",e.WLB(1,qA,!t.submitted,t.submitted))}}function eO(n,s){1&n&&e.GkF(0)}const DS=function(n,s){return{index:n,matcher:s}};function cy(n,s){if(1&n&&(e.TgZ(0,"span"),e.YNc(1,eO,1,0,"ng-container",64),e.qZA()),2&n){const t=s.$implicit,o=s.index;e.oxw();const c=e.MAs(1);e.xp6(1),e.Q6J("ngTemplateOutlet",c)("ngTemplateOutletContext",e.WLB(2,DS,o,t))}}function tO(n,s){if(1&n&&(e.TgZ(0,"div",65),e.TgZ(1,"span"),e._uU(2),e.qZA(),e.qZA()),2&n){const t=e.oxw();e.Gre("cd-col-form-offset ",t.matcherMatch.cssClass,""),e.xp6(1),e.Gre("text-muted ",t.matcherMatch.cssClass,""),e.xp6(1),e.hij(" ",t.matcherMatch.status," ")}}function RS(n,s){if(1&n&&e._UZ(0,"cd-date-time-picker",66),2&n){const t=e.oxw();e.Q6J("control",t.form.get("startsAt"))("hasSeconds",!1)}}function nO(n,s){if(1&n&&e._UZ(0,"cd-date-time-picker",66),2&n){const t=e.oxw();e.Q6J("control",t.form.get("endsAt"))("hasSeconds",!1)}}const rO=function(n){return{"btn-warning":n}};let dy=(()=>{class n{constructor(t,o,c,g,C,D,P,j,W,re,oe){this.router=t,this.authStorageService=o,this.formBuilder=c,this.prometheusService=g,this.notificationService=C,this.route=D,this.timeDiff=P,this.modalService=j,this.silenceMatcher=W,this.actionLabels=re,this.succeededLabels=oe,this.icons=xo.P,this.recreate=!1,this.edit=!1,this.resource="silence",this.matchers=[],this.matcherMatch=void 0,this.matcherConfig=[{tooltip:"Attribute name",icon:this.icons.paragraph,attribute:"name"},{tooltip:"Value",icon:this.icons.terminal,attribute:"value"},{tooltip:"Regular expression",icon:this.icons.magic,attribute:"isRegex"}],this.datetimeFormat="YYYY-MM-DD HH:mm",this.init()}init(){this.chooseMode(),this.authenticate(),this.createForm(),this.setupDates(),this.getData()}chooseMode(){this.edit=this.router.url.startsWith("/monitoring/silences/edit"),this.recreate=this.router.url.startsWith("/monitoring/silences/recreate"),this.action=this.edit?this.actionLabels.EDIT:this.recreate?this.actionLabels.RECREATE:this.actionLabels.CREATE}authenticate(){if(this.permission=this.authStorageService.getPermissions().prometheus,!this.permission.read||!(this.edit?this.permission.update:this.permission.create))throw new Ia._2}createForm(){const t=ss.h.custom("format",o=>!(""===o||ai()(o,this.datetimeFormat).isValid()));this.form=this.formBuilder.group({startsAt:["",[Mn.kI.required,t]],duration:["2h",[Mn.kI.min(1)]],endsAt:["",[Mn.kI.required,t]],createdBy:[this.authStorageService.getUsername(),[Mn.kI.required]],comment:[null,[Mn.kI.required]]},{validators:ss.h.custom("matcherRequired",()=>0===this.matchers.length)})}setupDates(){const t=ai()().format(this.datetimeFormat);this.form.silentSet("startsAt",t),this.updateDate(),this.subscribeDateChanges()}updateDate(t){const o=ai()(this.form.getValue(t?"endsAt":"startsAt"),this.datetimeFormat).toDate(),c=this.timeDiff.calculateDate(o,this.form.getValue("duration"),t);if(c){const g=ai()(c).format(this.datetimeFormat);this.form.silentSet(t?"startsAt":"endsAt",g)}}subscribeDateChanges(){this.form.get("startsAt").valueChanges.subscribe(()=>{this.onDateChange()}),this.form.get("duration").valueChanges.subscribe(()=>{this.updateDate()}),this.form.get("endsAt").valueChanges.subscribe(()=>{this.onDateChange(!0)})}onDateChange(t){const o=ai()(this.form.getValue("startsAt"),this.datetimeFormat),c=ai()(this.form.getValue("endsAt"),this.datetimeFormat);o.isBefore(c)?this.updateDuration():this.updateDate(t)}updateDuration(){const t=ai()(this.form.getValue("startsAt"),this.datetimeFormat).toDate(),o=ai()(this.form.getValue("endsAt"),this.datetimeFormat).toDate();this.form.silentSet("duration",this.timeDiff.calculateDuration(t,o))}getData(){this.getRules(),this.getModeSpecificData()}getRules(){this.prometheusService.ifPrometheusConfigured(()=>this.prometheusService.getRules().subscribe(t=>{this.rules=t.groups.reduce((o,c)=>wr().concat(o,c.rules),[])},()=>{this.prometheusService.disablePrometheusConfig(),this.rules=[]}),()=>{this.rules=[],this.notificationService.show(pa.k.info,"Please add your Prometheus host to the dashboard configuration and refresh the page",void 0,void 0,"Prometheus")})}getModeSpecificData(){this.route.params.subscribe(t=>{!t.id||(this.edit||this.recreate?this.prometheusService.getSilences().subscribe(o=>{const c=wr().find(o,["id",t.id]);wr().isUndefined(c)||this.fillFormWithSilence(c)}):this.prometheusService.getAlerts().subscribe(o=>{const c=wr().find(o,["fingerprint",t.id]);wr().isUndefined(c)||this.fillFormByAlert(c)}))})}fillFormWithSilence(t){this.id=t.id,this.edit&&(["startsAt","endsAt"].forEach(o=>this.form.silentSet(o,ai()(t[o]).format(this.datetimeFormat))),this.updateDuration()),["createdBy","comment"].forEach(o=>this.form.silentSet(o,t[o])),this.matchers=t.matchers,this.validateMatchers()}validateMatchers(){this.rules?(this.matcherMatch=this.silenceMatcher.multiMatch(this.matchers,this.rules),this.form.markAsDirty(),this.form.updateValueAndValidity()):window.setTimeout(()=>this.validateMatchers(),100)}fillFormByAlert(t){const o=t.labels;Object.keys(o).forEach(c=>this.setMatcher({name:c,value:o[c],isRegex:!1}))}setMatcher(t,o){wr().isNumber(o)?this.matchers[o]=t:this.matchers.push(t),this.validateMatchers()}showMatcherModal(t){const c=this.modalService.show(Dp).componentInstance;c.rules=this.rules,wr().isNumber(t)&&(c.editMode=!0,c.preFillControls(this.matchers[t])),c.submitAction.subscribe(g=>{this.setMatcher(g,t)})}deleteMatcher(t){this.matchers.splice(t,1),this.validateMatchers()}submit(){this.form.invalid||this.prometheusService.setSilence(this.getSubmitData()).subscribe(t=>{this.router.navigate(["/monitoring/silences"]),this.notificationService.show(pa.k.success,this.getNotificationTile(t.body.silenceId),void 0,void 0,"Prometheus")},()=>this.form.setErrors({cdSubmitButton:!0}))}getSubmitData(){const t=this.form.value;return delete t.duration,t.startsAt=ai()(t.startsAt,this.datetimeFormat).toISOString(),t.endsAt=ai()(t.endsAt,this.datetimeFormat).toISOString(),t.matchers=this.matchers,this.edit&&(t.id=this.id),t}getNotificationTile(t){let o;return o=this.edit?this.succeededLabels.EDITED:this.recreate?this.succeededLabels.RECREATED:this.succeededLabels.CREATED,`${o} ${this.resource} ${t}`}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Bo.F0),e.Y36(vt.j),e.Y36(rd.O),e.Y36(ng),e.Y36(hl.g),e.Y36(Bo.gz),e.Y36(Va),e.Y36(Bl.Z),e.Y36(Pl),e.Y36($i.p4),e.Y36($i.aX))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-prometheus-form"]],decls:71,vars:30,consts:function(){let s,t,o,c,g,C,D,P,j,W,re,oe,me,_e,Fe,Re,Le,we;return s="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",t="Creator",o="Comment",c="Start time",g="If the start time lies in the past the creation time will be used",C="Duration",D="End time",P="Matchers",j="Add matcher",W="Edit",re="Delete",oe="Editing a silence will expire the old silence and recreate it as a new silence",me="This field is required!",_e="This field is required!",Fe="This field is required!",Re="This field is required!",Le="This field is required!",we="A silence requires at least one matcher",[["matcherTpl",""],[1,"cd-col-form"],["name","form","novalidate","",1,"form",3,"formGroup"],["formDir","ngForm"],[1,"card"],[1,"card-header"],s,[4,"ngIf"],[1,"card-body"],[1,"form-group","row"],["for","created-by",1,"cd-col-form-label","required"],t,[1,"cd-col-form-input"],["formControlName","createdBy","id","created-by","name","created-by","type","text",1,"form-control"],["class","invalid-feedback",4,"ngIf"],["for","comment",1,"cd-col-form-label","required"],o,["formControlName","comment","id","comment","name","comment","type","text",1,"form-control"],["for","starts-at",1,"cd-col-form-label"],[1,"required"],c,g,["formControlName","startsAt","triggers","manual",1,"form-control",3,"ngbPopover","click","keypress"],["ps","ngbPopover"],["for","duration",1,"cd-col-form-label","required"],C,["formControlName","duration","id","duration","name","duration","type","text",1,"form-control"],["for","ends-at",1,"cd-col-form-label","required"],D,["formControlName","endsAt","triggers","manual",1,"form-control",3,"ngbPopover","click","keypress"],["pe","ngbPopover"],P,[1,"cd-col-form-offset"],[3,"ngClass",4,"ngIf"],[4,"ngFor","ngForOf"],[1,"row"],[1,"col-12"],["type","button","id","add-matcher",1,"btn","btn-light","float-right","my-3",3,"ngClass","click"],[3,"ngClass"],j,["id","match-state",3,"class",4,"ngIf"],[1,"card-footer"],[1,"text-right"],[3,"form","submitText","submitActionEvent"],["popStart",""],["popEnd",""],[1,"input-group","my-2"],[1,"input-group-append"],["type","button","ngbTooltip",W,1,"btn","btn-light",3,"id","click"],["type","button","ngbTooltip",re,1,"btn","btn-light",3,"id","click"],[1,"help-block"],[1,"input-group-prepend"],[1,"input-group-text",3,"ngbTooltip"],["type","text","disabled","","readonly","",1,"form-control",3,"id","value"],[1,"input-group-text"],["type","checkbox","disabled","","readonly","",3,"id","checked"],oe,[1,"invalid-feedback"],me,_e,Fe,Re,Le,we,[4,"ngTemplateOutlet","ngTemplateOutletContext"],["id","match-state"],[3,"control","hasSeconds"]]},template:function(t,o){if(1&t){const c=e.EpF();e.YNc(0,pR,8,9,"ng-template",null,0,e.W1O),e.TgZ(2,"div",1),e.TgZ(3,"form",2,3),e.TgZ(5,"div",4),e.TgZ(6,"div",5),e.TgZ(7,"span"),e.SDv(8,6),e.ALo(9,"titlecase"),e.ALo(10,"upperFirst"),e.qZA(),e.YNc(11,hR,2,0,"cd-helper",7),e.qZA(),e.TgZ(12,"div",8),e.TgZ(13,"div",9),e.TgZ(14,"label",10),e.SDv(15,11),e.qZA(),e.TgZ(16,"div",12),e._UZ(17,"input",13),e.YNc(18,XA,2,0,"span",14),e.qZA(),e.qZA(),e.TgZ(19,"div",9),e.TgZ(20,"label",15),e.SDv(21,16),e.qZA(),e.TgZ(22,"div",12),e.TgZ(23,"textarea",17),e._uU(24," "),e.qZA(),e.YNc(25,wS,2,0,"span",14),e.qZA(),e.qZA(),e.TgZ(26,"div",9),e.TgZ(27,"label",18),e.TgZ(28,"span",19),e.SDv(29,20),e.qZA(),e.TgZ(30,"cd-helper"),e.SDv(31,21),e.qZA(),e.qZA(),e.TgZ(32,"div",12),e.TgZ(33,"input",22,23),e.NdJ("click",function(){return e.CHM(c),e.MAs(34).open()})("keypress",function(){return e.CHM(c),e.MAs(34).close()}),e.qZA(),e.YNc(35,_R,2,0,"span",14),e.qZA(),e.qZA(),e.TgZ(36,"div",9),e.TgZ(37,"label",24),e.SDv(38,25),e.qZA(),e.TgZ(39,"div",12),e._UZ(40,"input",26),e.YNc(41,KA,2,0,"span",14),e.qZA(),e.qZA(),e.TgZ(42,"div",9),e.TgZ(43,"label",27),e.SDv(44,28),e.qZA(),e.TgZ(45,"div",12),e.TgZ(46,"input",29,30),e.NdJ("click",function(){return e.CHM(c),e.MAs(47).open()})("keypress",function(){return e.CHM(c),e.MAs(47).close()}),e.qZA(),e.YNc(48,Av,2,0,"span",14),e.qZA(),e.qZA(),e.TgZ(49,"fieldset"),e.TgZ(50,"legend",19),e.SDv(51,31),e.qZA(),e.TgZ(52,"div",32),e.YNc(53,xS,3,4,"h5",33),e.YNc(54,cy,2,5,"span",34),e.TgZ(55,"div",35),e.TgZ(56,"div",36),e.TgZ(57,"button",37),e.NdJ("click",function(){return o.showMatcherModal()}),e._UZ(58,"i",38),e.ynx(59),e.SDv(60,39),e.BQk(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(61,tO,3,7,"div",40),e.qZA(),e.qZA(),e.TgZ(62,"div",41),e.TgZ(63,"div",42),e.TgZ(64,"cd-form-button-panel",43),e.NdJ("submitActionEvent",function(){return o.submit()}),e.ALo(65,"titlecase"),e.ALo(66,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(67,RS,1,2,"ng-template",null,44,e.W1O),e.YNc(69,nO,1,2,"ng-template",null,45,e.W1O)}if(2&t){const c=e.MAs(4),g=e.MAs(68),C=e.MAs(70);e.xp6(3),e.Q6J("formGroup",o.form),e.xp6(7),e.pQV(e.lcZ(9,18,o.action))(e.lcZ(10,20,o.resource)),e.QtT(8),e.xp6(1),e.Q6J("ngIf",o.edit),e.xp6(7),e.Q6J("ngIf",o.form.showError("createdBy",c,"required")),e.xp6(7),e.Q6J("ngIf",o.form.showError("comment",c,"required")),e.xp6(8),e.Q6J("ngbPopover",g),e.xp6(2),e.Q6J("ngIf",o.form.showError("startsAt",c,"required")),e.xp6(6),e.Q6J("ngIf",o.form.showError("duration",c,"required")),e.xp6(5),e.Q6J("ngbPopover",C),e.xp6(2),e.Q6J("ngIf",o.form.showError("endsAt",c,"required")),e.xp6(5),e.Q6J("ngIf",0===o.matchers.length),e.xp6(1),e.Q6J("ngForOf",o.matchers),e.xp6(3),e.Q6J("ngClass",e.VKq(26,rO,c.submitted&&0===o.matchers.length)),e.xp6(1),e.Q6J("ngClass",e.VKq(28,Ym,o.icons.add)),e.xp6(3),e.Q6J("ngIf",o.matchers.length&&o.matcherMatch),e.xp6(3),e.Q6J("form",o.form)("submitText",e.lcZ(65,22,o.action)+" "+e.lcZ(66,24,o.resource))}},directives:[Mn._Y,Mn.JL,ll.V,Mn.sg,_.O5,Za.P,la.o,Mn.Fj,ja.b,Mn.JJ,Mn.u,h.S,ut.o8,_.sg,_.mk,ul.p,ut._L,_.tP,hd.J],pipes:[_.rS,F.m],styles:["textarea[_ngcontent-%COMP%]{resize:vertical}"]}),n})();var iO=i(84051),Gb=i(18891);function NS(n,s){1&n&&(e.TgZ(0,"cd-alert-panel",2),e.tHW(1,3),e._UZ(2,"cd-doc",4),e.N_p(),e.qZA())}function oO(n,s){if(1&n&&e._UZ(0,"cd-table-key-value",8),2&n){const t=e.oxw(2);e.Q6J("renderObjects",!0)("hideEmpty",!0)("appendParentKey",!1)("data",t.expandedRow)("customCss",t.customCss)("autoReload",!1)}}function PS(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-table",5),e.NdJ("setExpandedRow",function(c){return e.CHM(t),e.oxw().setExpandedRow(c)})("fetchData",function(){return e.CHM(t),e.oxw().refresh()})("updateSelection",function(c){return e.CHM(t),e.oxw().updateSelection(c)}),e._UZ(1,"cd-table-actions",6),e.YNc(2,oO,1,6,"cd-table-key-value",7),e.qZA()}if(2&n){const t=e.oxw();e.Q6J("data",t.silences)("columns",t.columns)("forceIdentifier",!0)("customCss",t.customCss)("sorts",t.sorts)("hasDetails",!0),e.xp6(1),e.Q6J("permission",t.permission)("selection",t.selection)("tableActions",t.tableActions),e.xp6(1),e.Q6J("ngIf",t.expandedRow)}}let Vb=(()=>{class n extends Mv{constructor(t,o,c,g,C,D,P,j){super(j),this.authStorageService=t,this.cdDatePipe=o,this.modalService=c,this.notificationService=g,this.urlBuilder=C,this.actionLabels=D,this.succeededLabels=P,this.silences=[],this.selection=new El.r,this.customCss={"badge badge-danger":"active","badge badge-warning":"pending","badge badge-default":"expired"},this.sorts=[{prop:"endsAt",dir:iO.Sr.desc}],this.permission=this.authStorageService.getPermissions().prometheus;const W=re=>re.first()&&re.first().status&&"expired"===re.first().status.state;this.tableActions=[{permission:"create",icon:xo.P.add,routerLink:()=>this.urlBuilder.getCreate(),canBePrimary:re=>!re.hasSingleSelection,name:this.actionLabels.CREATE},{permission:"create",canBePrimary:re=>re.hasSingleSelection&&W(re),disable:re=>!re.hasSingleSelection||re.first().cdExecuting||re.first().cdExecuting&&W(re)||!W(re),icon:xo.P.copy,routerLink:()=>this.urlBuilder.getRecreate(this.selection.first().id),name:this.actionLabels.RECREATE},{permission:"update",icon:xo.P.edit,canBePrimary:re=>re.hasSingleSelection&&!W(re),disable:re=>!re.hasSingleSelection||re.first().cdExecuting||re.first().cdExecuting&&!W(re)||W(re),routerLink:()=>this.urlBuilder.getEdit(this.selection.first().id),name:this.actionLabels.EDIT},{permission:"delete",icon:xo.P.trash,canBePrimary:re=>re.hasSingleSelection&&!W(re),disable:re=>!re.hasSingleSelection||re.first().cdExecuting||W(re),click:()=>this.expireSilence(),name:this.actionLabels.EXPIRE}],this.columns=[{name:"ID",prop:"id",flexGrow:3},{name:"Created by",prop:"createdBy",flexGrow:2},{name:"Started",prop:"startsAt",pipe:this.cdDatePipe},{name:"Updated",prop:"updatedAt",pipe:this.cdDatePipe},{name:"Ends",prop:"endsAt",pipe:this.cdDatePipe},{name:"Status",prop:"status.state",cellTransformation:bl.e.classAdding}]}refresh(){this.prometheusService.ifAlertmanagerConfigured(()=>{this.prometheusService.getSilences().subscribe(t=>{this.silences=t},()=>{this.prometheusService.disableAlertmanagerConfig()})})}updateSelection(t){this.selection=t}expireSilence(){const t=this.selection.first().id,o="Silence",c="Prometheus";this.modalRef=this.modalService.show(Gl.M,{itemDescription:o,itemNames:[t],actionDescription:this.actionLabels.EXPIRE,submitActionObservable:()=>new Gb.y(g=>{this.prometheusService.expireSilence(t).subscribe(()=>{this.notificationService.show(pa.k.success,`${this.succeededLabels.EXPIRED} ${o} ${t}`,void 0,void 0,c)},C=>{C.application=c,g.error(C)},()=>{g.complete(),this.refresh()})})})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(vt.j),e.Y36(Ul.N),e.Y36(Bl.Z),e.Y36(hl.g),e.Y36(Lu.F),e.Y36($i.p4),e.Y36($i.aX),e.Y36(ng))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-silences-list"]],features:[e._Bn([{provide:Lu.F,useValue:new Lu.F("monitoring/silences")}]),e.qOj],decls:3,vars:2,consts:function(){let s;return s="To enable Silences, please provide the URL to the API of the Prometheus' Alertmanager as described in the " + "\ufffd#2\ufffd" + "" + "\ufffd/#2\ufffd" + ".",[["type","info",4,"ngIf"],["selectionType","single",3,"data","columns","forceIdentifier","customCss","sorts","hasDetails","setExpandedRow","fetchData","updateSelection",4,"ngIf"],["type","info"],s,["section","prometheus"],["selectionType","single",3,"data","columns","forceIdentifier","customCss","sorts","hasDetails","setExpandedRow","fetchData","updateSelection"],[1,"table-actions",3,"permission","selection","tableActions"],["cdTableDetail","",3,"renderObjects","hideEmpty","appendParentKey","data","customCss","autoReload",4,"ngIf"],["cdTableDetail","",3,"renderObjects","hideEmpty","appendParentKey","data","customCss","autoReload"]]},template:function(t,o){1&t&&(e._UZ(0,"cd-prometheus-tabs"),e.YNc(1,NS,3,0,"cd-alert-panel",0),e.YNc(2,PS,3,10,"cd-table",1)),2&t&&(e.xp6(1),e.Q6J("ngIf",!o.isAlertmanagerConfigured),e.xp6(1),e.Q6J("ngIf",o.isAlertmanagerConfigured))},directives:[O,_.O5,gt.G,il.K,ks.a,Js.K,zr.b],styles:[""]}),n})(),gR=(()=>{class n{constructor(t){this.http=t,this.url="api/telemetry"}getReport(){return this.http.get(`${this.url}/report`)}enable(t=!0){const o={enable:t};return t&&(o.license_name="sharing-1-0"),this.http.put(`${this.url}`,o)}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(y.eN))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})(),x1=(()=>{class n{constructor(){this.visible=!1,this.update=new e.vpe}setVisibility(t){this.visible=t,this.update.emit(t)}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();function sO(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div"),e._uU(1," The plugin is already "),e.TgZ(2,"b"),e._uU(3,"enabled"),e.qZA(),e._uU(4,". Click "),e.TgZ(5,"b"),e._uU(6,"Deactivate"),e.qZA(),e._uU(7," to disable it.\xa0 "),e.TgZ(8,"button",61),e.NdJ("click",function(){return e.CHM(t),e.oxw(3).disableModule("The Telemetry module has been disabled successfully.")}),e.SDv(9,62),e.qZA(),e.qZA()}}function mR(n,s){1&n&&(e.ynx(0),e.TgZ(1,"legend"),e.ynx(2),e.SDv(3,63),e.BQk(),e.TgZ(4,"cd-helper"),e.SDv(5,64),e.qZA(),e.qZA(),e.TgZ(6,"div",15),e.TgZ(7,"label",65),e.SDv(8,66),e.qZA(),e.TgZ(9,"div",24),e._UZ(10,"input",67),e.qZA(),e.qZA(),e.TgZ(11,"div",15),e.TgZ(12,"label",68),e.SDv(13,69),e.qZA(),e.TgZ(14,"div",24),e._UZ(15,"input",70),e.qZA(),e.qZA(),e.TgZ(16,"div",15),e.TgZ(17,"label",71),e.SDv(18,72),e.qZA(),e.TgZ(19,"div",24),e._UZ(20,"input",73),e.qZA(),e.qZA(),e.BQk())}function D1(n,s){1&n&&(e.TgZ(0,"span",74),e.SDv(1,75),e.qZA())}function aO(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div"),e.TgZ(1,"form",4,5),e.TgZ(3,"div",6),e.TgZ(4,"div",7),e.SDv(5,8),e.qZA(),e.TgZ(6,"div",9),e.TgZ(7,"p"),e.tHW(8,10),e._UZ(9,"br"),e._UZ(10,"a",11),e._UZ(11,"br"),e._UZ(12,"br"),e._UZ(13,"b"),e.N_p(),e.qZA(),e.YNc(14,sO,10,0,"div",12),e.TgZ(15,"legend"),e.SDv(16,13),e.qZA(),e.TgZ(17,"p"),e.SDv(18,14),e.qZA(),e.TgZ(19,"div",15),e.TgZ(20,"label",16),e.ynx(21),e.SDv(22,17),e.BQk(),e.TgZ(23,"cd-helper"),e.ynx(24),e.SDv(25,18),e.BQk(),e.TgZ(26,"ul"),e.TgZ(27,"li"),e.SDv(28,19),e.qZA(),e.TgZ(29,"li"),e.SDv(30,20),e.qZA(),e.TgZ(31,"li"),e.SDv(32,21),e.qZA(),e.TgZ(33,"li"),e.SDv(34,22),e.qZA(),e.TgZ(35,"li"),e.SDv(36,23),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(37,"div",24),e.TgZ(38,"div",25),e._UZ(39,"input",26),e._UZ(40,"label",27),e.qZA(),e.qZA(),e.qZA(),e.TgZ(41,"div",15),e.TgZ(42,"label",28),e.ynx(43),e.SDv(44,29),e.BQk(),e.TgZ(45,"cd-helper"),e.ynx(46),e.SDv(47,30),e.BQk(),e.TgZ(48,"ul"),e.TgZ(49,"li"),e.SDv(50,31),e.qZA(),e.TgZ(51,"li"),e.SDv(52,32),e.qZA(),e.TgZ(53,"li"),e.SDv(54,33),e.qZA(),e.TgZ(55,"li"),e.SDv(56,34),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(57,"div",24),e.TgZ(58,"div",25),e._UZ(59,"input",35),e._UZ(60,"label",36),e.qZA(),e.qZA(),e.qZA(),e.TgZ(61,"div",15),e.TgZ(62,"label",37),e.ynx(63),e.SDv(64,38),e.BQk(),e._UZ(65,"cd-helper",39),e.qZA(),e.TgZ(66,"div",24),e.TgZ(67,"div",25),e._UZ(68,"input",40),e._UZ(69,"label",41),e.qZA(),e.qZA(),e.qZA(),e.TgZ(70,"div",15),e.TgZ(71,"label",42),e.ynx(72),e.SDv(73,43),e.BQk(),e.TgZ(74,"cd-helper"),e.ynx(75),e.SDv(76,44),e.BQk(),e.TgZ(77,"ul"),e.TgZ(78,"li"),e._uU(79,"Cluster description"),e.qZA(),e.TgZ(80,"li"),e._uU(81,"Contact email address"),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(82,"div",24),e.TgZ(83,"div",25),e.TgZ(84,"input",45),e.NdJ("click",function(){return e.CHM(t),e.oxw(2).toggleIdent()}),e.qZA(),e._UZ(85,"label",46),e.qZA(),e.qZA(),e.qZA(),e.YNc(86,mR,21,0,"ng-container",12),e.TgZ(87,"legend"),e.SDv(88,47),e.qZA(),e.TgZ(89,"div",15),e.TgZ(90,"label",48),e.ynx(91),e.SDv(92,49),e.BQk(),e.TgZ(93,"cd-helper"),e.SDv(94,50),e.qZA(),e.qZA(),e.TgZ(95,"div",24),e._UZ(96,"input",51),e.YNc(97,D1,2,0,"span",52),e.qZA(),e.qZA(),e.TgZ(98,"div",15),e.TgZ(99,"label",53),e.ynx(100),e.SDv(101,54),e.BQk(),e.TgZ(102,"cd-helper"),e.TgZ(103,"p"),e.SDv(104,55),e.qZA(),e.TgZ(105,"p"),e.SDv(106,56),e.qZA(),e.qZA(),e.qZA(),e.TgZ(107,"div",24),e._UZ(108,"input",57),e.qZA(),e.qZA(),e._UZ(109,"br"),e.TgZ(110,"p"),e.tHW(111,58),e._UZ(112,"b"),e.N_p(),e.qZA(),e.qZA(),e.TgZ(113,"div",59),e.TgZ(114,"div",60),e.TgZ(115,"button",61),e.NdJ("click",function(){return e.CHM(t),e.oxw(2).next()}),e.ynx(116),e._uU(117),e.BQk(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=e.MAs(2),o=e.oxw(2);e.xp6(1),e.Q6J("formGroup",o.configForm),e.xp6(4),e.pQV(o.step),e.QtT(5),e.xp6(8),e.pQV(o.sendToUrl)(o.sendToDeviceUrl),e.QtT(8),e.xp6(1),e.Q6J("ngIf",o.moduleEnabled),e.xp6(72),e.Q6J("ngIf",o.showContactInfo),e.xp6(11),e.Q6J("ngIf",o.configForm.showError("interval",t,"min")),e.xp6(20),e.Oqu(o.actionLabels.NEXT)}}function zb(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div"),e.TgZ(1,"form",76,77),e.TgZ(3,"div",6),e.TgZ(4,"div",7),e.SDv(5,78),e.qZA(),e.TgZ(6,"div",9),e.TgZ(7,"div",15),e.TgZ(8,"label",79),e.tHW(9,80),e._UZ(10,"cd-helper",81),e.N_p(),e.qZA(),e.TgZ(11,"div",24),e._UZ(12,"input",82),e.qZA(),e.qZA(),e.TgZ(13,"div",15),e.TgZ(14,"label",83),e.tHW(15,84),e._UZ(16,"cd-helper",85),e.N_p(),e.qZA(),e.TgZ(17,"div",24),e._UZ(18,"textarea",86),e.qZA(),e.qZA(),e.TgZ(19,"div",15),e.TgZ(20,"div",87),e.TgZ(21,"div",88),e._UZ(22,"cd-download-button",89),e._UZ(23,"cd-copy-2-clipboard-button",90),e.qZA(),e.qZA(),e.qZA(),e.TgZ(24,"div",15),e.TgZ(25,"div",87),e.TgZ(26,"div",25),e._UZ(27,"input",91),e.TgZ(28,"label",92),e.tHW(29,93),e._UZ(30,"a",94),e.N_p(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(31,"div",59),e.TgZ(32,"div",60),e.TgZ(33,"cd-form-button-panel",95),e.NdJ("submitActionEvent",function(){return e.CHM(t),e.oxw(2).onSubmit()})("backActionEvent",function(){return e.CHM(t),e.oxw(2).back()}),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=e.oxw(2);e.xp6(1),e.Q6J("formGroup",t.previewForm),e.xp6(4),e.pQV(t.step),e.QtT(5),e.xp6(17),e.Q6J("objectItem",t.report),e.xp6(11),e.Q6J("form",t.previewForm)("submitText",t.actionLabels.UPDATE)("cancelText",t.actionLabels.BACK)}}function Wb(n,s){if(1&n&&(e.TgZ(0,"div",1),e.ynx(1,2),e.YNc(2,aO,118,8,"div",3),e.YNc(3,zb,34,6,"div",3),e.BQk(),e.qZA()),2&n){const t=e.oxw();e.xp6(1),e.Q6J("ngSwitch",t.step),e.xp6(1),e.Q6J("ngSwitchCase",1),e.xp6(1),e.Q6J("ngSwitchCase",2)}}let lO=(()=>{class n extends Oa.E{constructor(t,o,c,g,C,D,P){super(),this.actionLabels=t,this.formBuilder=o,this.mgrModuleService=c,this.notificationService=g,this.router=C,this.telemetryService=D,this.telemetryNotificationService=P,this.licenseAgrmt=!1,this.options={},this.newConfig={},this.configResp={},this.requiredFields=["channel_basic","channel_crash","channel_device","channel_ident","interval","proxy","contact","description","organization"],this.contactInfofields=["contact","description","organization"],this.report=void 0,this.reportId=void 0,this.sendToUrl="",this.sendToDeviceUrl="",this.step=1}ngOnInit(){const t=[this.mgrModuleService.getOptions("telemetry"),this.mgrModuleService.getConfig("telemetry")];(0,xc.D)(t).subscribe(o=>{const c=o[1];this.moduleEnabled=c.enabled,this.sendToUrl=c.url,this.sendToDeviceUrl=c.device_url,this.showContactInfo=c.channel_ident,this.options=wr().pick(o[0],this.requiredFields),this.configResp=wr().pick(c,this.requiredFields),this.createConfigForm(),this.configForm.setValue(this.configResp),this.loadingReady()},o=>{this.loadingError()})}createConfigForm(){const t={};wr().forEach(Object.values(this.options),o=>{t[o.name]=[o.default_value,this.getValidators(o)]}),this.configForm=this.formBuilder.group(t)}createPreviewForm(){const t={report:JSON.stringify(this.report,null,2),reportId:this.reportId,licenseAgrmt:[this.licenseAgrmt,Mn.kI.requiredTrue]};this.previewForm=this.formBuilder.group(t)}getValidators(t){const o=[];switch(t.type){case"int":o.push(Mn.kI.required);break;case"str":wr().isNumber(t.min)&&o.push(Mn.kI.minLength(t.min)),wr().isNumber(t.max)&&o.push(Mn.kI.maxLength(t.max))}return o}updateReportFromConfig(t={}){const o=this.report.report.channels_available,c=[];for(const g of o)t[`channel_${g}`]&&c.push(g);this.report.report.channels=c;for(const g of this.contactInfofields)this.report.report[g]=t[g]}getReport(){this.loadingStart(),this.telemetryService.getReport().subscribe(t=>{this.report=t,this.reportId=t.report.report_id,this.updateReportFromConfig(this.newConfig),this.createPreviewForm(),this.loadingReady(),this.step++},t=>{this.loadingError()})}toggleIdent(){this.showContactInfo=!this.showContactInfo}buildReport(){this.newConfig={};for(const t of Object.values(this.options)){const o=this.configForm.get(t.name);if(!o.valid)return void this.configForm.setErrors({cdSubmitButton:!0});this.newConfig[t.name]=o.value}if(!this.newConfig.channel_ident)for(const t of this.contactInfofields)this.newConfig[t]="";this.getReport()}disableModule(t=null,o=null){this.telemetryService.enable(!1).subscribe(()=>{this.telemetryNotificationService.setVisibility(!0),t&&this.notificationService.show(pa.k.success,t),o?o():this.router.navigate([""])})}next(){this.buildReport()}back(){this.step--}getChangedConfig(){const t={};return wr().forEach(this.requiredFields,o=>{wr().isEqual(this.configResp[o],this.newConfig[o])||(t[o]=this.newConfig[o])}),t}onSubmit(){const t=this.getChangedConfig(),o=[this.telemetryService.enable(),this.mgrModuleService.updateConfig("telemetry",t)];(0,xc.D)(o).subscribe(()=>{this.telemetryNotificationService.setVisibility(!1),this.notificationService.show(pa.k.success,"The Telemetry module has been configured and activated successfully.")},()=>{this.telemetryNotificationService.setVisibility(!1),this.notificationService.show(pa.k.error,"An Error occurred while updating the Telemetry module configuration. Please Try again"),this.previewForm.setErrors({cdSubmitButton:!0})},()=>{this.newConfig={},this.router.navigate([""])})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36($i.p4),e.Y36(rd.O),e.Y36(ql.N),e.Y36(hl.g),e.Y36(Bo.F0),e.Y36(gR),e.Y36(x1))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-telemetry"]],features:[e.qOj],decls:1,vars:1,consts:function(){let s,t,o,c,g,C,D,P,j,W,re,oe,me,_e,Fe,Re,Le,we,U,pt,ht,Dt,Ft,cn,kt,wn,Tn,Hr,sr,Nr,xr,fn,Rn,kn,Wn,bn,jr,ji,oi,Ui,Xr,Sn,hn;return s="Step " + "\ufffd0\ufffd" + " of 2: Telemetry report configuration",t="The telemetry module sends anonymous data about this Ceph cluster back to the Ceph developers to help understand how Ceph is used and what problems users may be experiencing." + "[\ufffd#9\ufffd\ufffd/#9\ufffd|\ufffd#11\ufffd\ufffd/#11\ufffd|\ufffd#12\ufffd\ufffd/#12\ufffd]" + " This data is visualized on " + "\ufffd#10\ufffd" + "public dashboards" + "\ufffd/#10\ufffd" + " that allow the community to quickly see summary statistics on how many clusters are reporting, their total capacity and OSD count, and version distribution trends." + "[\ufffd#9\ufffd\ufffd/#9\ufffd|\ufffd#11\ufffd\ufffd/#11\ufffd|\ufffd#12\ufffd\ufffd/#12\ufffd]" + "" + "[\ufffd#9\ufffd\ufffd/#9\ufffd|\ufffd#11\ufffd\ufffd/#11\ufffd|\ufffd#12\ufffd\ufffd/#12\ufffd]" + " The data being reported does " + "\ufffd#13\ufffd" + "not" + "\ufffd/#13\ufffd" + " contain any sensitive data like pool names, object names, object contents, hostnames, or device serial numbers. It contains counters and statistics on how the cluster has been deployed, the version of Ceph, the distribution of the hosts and other parameters which help the project to gain a better understanding of the way Ceph is used. The data is sent secured to " + "\ufffd0\ufffd" + " and " + "\ufffd1\ufffd" + " (device report).",t=e.Zx4(t),o="Channels",c="The telemetry report is broken down into several \"channels\", each with a different type of information that can be configured below.",g="Basic",C="Includes basic information about the cluster:",D="Capacity of the cluster",P="Number of monitors, managers, OSDs, MDSs, object gateways, or other daemons",j="Software version currently being used",W="Number and types of RADOS pools and CephFS file systems",re="Names of configuration options that have been changed from their default (but not their values)",oe="Crash",me="Includes information about daemon crashes:",_e="Type of daemon",Fe="Version of the daemon",Re="Operating system (OS distribution, kernel version)",Le="Stack trace identifying where in the Ceph code the crash occurred",we="Device",U="Includes information about device metrics like anonymized SMART metrics.",pt="Ident",ht="Includes user-provided identifying information about the cluster:",Dt="Advanced Settings",Ft="Interval",cn="The module compiles and sends a new report every 24 hours by default. You can adjust this interval by setting a different number of hours.",kt="Proxy",wn="If the cluster cannot directly connect to the configured telemetry endpoint (default telemetry.ceph.com), you can configure a HTTP/HTTPS proxy server by e.g. adding https://10.0.0.1:8080",Tn="You can also include a user:pass if needed e.g. https://ceph:telemetry@10.0.0.1:8080",Hr="" + "\ufffd#112\ufffd" + "Note:" + "\ufffd/#112\ufffd" + " By clicking 'Next' you will first see a preview of the report content before you can activate the automatic submission of your data.",sr="Deactivate",Nr="Contact Information",xr="Submitting any contact information is completely optional and disabled by default.",fn="Contact",Rn="Description",kn="My first Ceph cluster",Wn="Organization",bn="Organization name",jr="The entered value is too low! It must be greater or equal to 8.",ji="Step " + "\ufffd0\ufffd" + " of 2: Telemetry report preview",oi="A randomized UUID to identify a particular cluster over the course of several telemetry reports.",Ui="Report ID " + "\ufffd#10\ufffd" + "" + "\ufffd/#10\ufffd" + "",Xr="The actual telemetry data that will be submitted.",Sn="Report preview " + "\ufffd#16\ufffd" + "" + "\ufffd/#16\ufffd" + "",hn="I agree to my telemetry data being submitted under the " + "\ufffd#30\ufffd" + "Community Data License Agreement - Sharing - Version 1.0" + "\ufffd/#30\ufffd" + "",[["class","cd-col-form",4,"cdFormLoading"],[1,"cd-col-form"],[3,"ngSwitch"],[4,"ngSwitchCase"],["name","form","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"card"],[1,"card-header"],s,[1,"card-body"],t,["href","https://telemetry-public.ceph.com/"],[4,"ngIf"],o,c,[1,"form-group","row"],["for","channel_basic",1,"cd-col-form-label"],g,C,D,P,j,W,re,[1,"cd-col-form-input"],[1,"custom-control","custom-checkbox"],["type","checkbox","id","channel_basic","formControlName","channel_basic",1,"custom-control-input"],["for","channel_basic",1,"custom-control-label"],["for","channel_crash",1,"cd-col-form-label"],oe,me,_e,Fe,Re,Le,["type","checkbox","id","channel_crash","formControlName","channel_crash",1,"custom-control-input"],["for","channel_crash",1,"custom-control-label"],["for","channel_device",1,"cd-col-form-label"],we,["html",U],["type","checkbox","id","channel_device","formControlName","channel_device",1,"custom-control-input"],["for","channel_device",1,"custom-control-label"],["for","channel_ident",1,"cd-col-form-label"],pt,ht,["type","checkbox","id","channel_ident","formControlName","channel_ident",1,"custom-control-input",3,"click"],["for","channel_ident",1,"custom-control-label"],Dt,["for","interval",1,"cd-col-form-label"],Ft,cn,["id","interval","type","number","formControlName","interval","min","8",1,"form-control"],["class","invalid-feedback",4,"ngIf"],["for","proxy",1,"cd-col-form-label"],kt,wn,Tn,["id","proxy","type","text","formControlName","proxy","placeholder","https://10.0.0.1:8080",1,"form-control"],Hr,[1,"card-footer"],[1,"button-group","text-right"],["type","button",1,"btn","btn-light",3,"click"],sr,Nr,xr,["for","contact",1,"cd-col-form-label"],fn,["id","contact","type","text","formControlName","contact","placeholder","Example User <user@example.com>",1,"form-control"],["for","description",1,"cd-col-form-label"],Rn,["id","description","type","text","formControlName","description","placeholder",kn,1,"form-control"],["for","organization",1,"cd-col-form-label"],Wn,["id","organization","type","text","formControlName","organization","placeholder",bn,1,"form-control"],[1,"invalid-feedback"],jr,["name","previewForm","novalidate","",3,"formGroup"],["frm","ngForm"],ji,["for","reportId",1,"cd-col-form-label"],Ui,["html",oi],["type","text","id","reportId","formControlName","reportId","readonly","",1,"form-control"],["for","report",1,"cd-col-form-label"],Sn,["html",Xr],["id","report","formControlName","report","rows","15","readonly","",1,"form-control"],[1,"cd-col-form-offset"],["role","group",1,"btn-group"],["fileName","telemetry_report",3,"objectItem"],["source","report"],["type","checkbox","id","licenseAgrmt","name","licenseAgrmt","formControlName","licenseAgrmt",1,"custom-control-input"],["for","licenseAgrmt",1,"custom-control-label"],hn,["href","https://cdla.io/sharing-1-0/"],[3,"form","submitText","cancelText","submitActionEvent","backActionEvent"]]},template:function(t,o){1&t&&e.YNc(0,Wb,4,3,"div",0),2&t&&e.Q6J("cdFormLoading",o.loading)},directives:[Ol.y,_.RF,_.n9,Mn._Y,Mn.JL,ll.V,Mn.sg,_.O5,Za.P,h.S,la.o,Mn.Wl,ja.b,Mn.JJ,Mn.u,Mn.wV,Mn.qQ,Mn.Fj,xm,Bc.s,ul.p],styles:[""]}),n})();var Jb=i(26561);function LS(n){const{subscriber:s,counter:t,period:o}=n;s.next(t),this.schedule({subscriber:s,counter:t+1,period:o},o)}let uO=(()=>{class n{constructor(t){this.ngZone=t,this.intervalDataSource=new Pd.X(null),this.intervalData$=this.intervalDataSource.asObservable();const o=parseInt(sessionStorage.getItem("dashboard_interval"),10)||5e3;this.setRefreshInterval(o)}setRefreshInterval(t){this.intervalTime=t,sessionStorage.setItem("dashboard_interval",t.toString()),this.intervalSubscription&&this.intervalSubscription.unsubscribe(),this.ngZone.runOutsideAngular(()=>{this.intervalSubscription=function(n=0,s=bf.P){return(!(0,Jb.k)(n)||n<0)&&(n=0),(!s||"function"!=typeof s.schedule)&&(s=bf.P),new Gb.y(t=>(t.add(s.schedule(LS,n,{subscriber:t,counter:0,period:n})),t))}(this.intervalTime).subscribe(()=>this.ngZone.run(()=>{this.intervalDataSource.next(this.intervalTime)}))})}getRefreshInterval(){return this.intervalTime}ngOnDestroy(){this.intervalSubscription&&this.intervalSubscription.unsubscribe()}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(e.R0b))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();function cO(n,s){if(1&n&&(e.TgZ(0,"option",8),e._uU(1),e.qZA()),2&n){const t=s.$implicit,o=e.oxw();e.Q6J("value",o.intervalList[t]),e.xp6(1),e.Oqu(t)}}let Xb=(()=>{class n{constructor(t){this.refreshIntervalService=t,this.intervalList={"5 s":5e3,"10 s":1e4,"15 s":15e3,"30 s":3e4,"1 min":6e4,"3 min":18e4,"5 min":3e5},this.intervalKeys=Object.keys(this.intervalList)}ngOnInit(){this.selectedInterval=this.refreshIntervalService.getRefreshInterval()||5e3}changeRefreshInterval(t){this.refreshIntervalService.setRefreshInterval(t)}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(uO))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-refresh-selector"]],decls:8,vars:2,consts:function(){let s;return s="Refresh",[[1,"container-fluid"],[1,"row"],[1,"col","d-flex","justify-content-end"],[1,"form-inline"],["for","refreshInterval",1,"col-form-label","my-0","mx-2"],s,["id","refreshInterval","name","refreshInterval",1,"form-control",3,"ngModel","change","ngModelChange"],[3,"value",4,"ngFor","ngForOf"],[3,"value"]]},template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"div",1),e.TgZ(2,"div",2),e.TgZ(3,"form",3),e.TgZ(4,"label",4),e.SDv(5,5),e.qZA(),e.TgZ(6,"select",6),e.NdJ("change",function(g){return o.changeRefreshInterval(g.target.value)})("ngModelChange",function(g){return o.selectedInterval=g}),e.YNc(7,cO,2,2,"option",7),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()),2&t&&(e.xp6(6),e.Q6J("ngModel",o.selectedInterval),e.xp6(1),e.Q6J("ngForOf",o.intervalKeys))},directives:[Mn._Y,Mn.JL,Mn.F,la.o,Mn.EJ,ja.b,Mn.JJ,Mn.On,_.sg,Mn.YN,Mn.Kr],styles:[""]}),n})();var Kb=i(49671);let FS=(()=>{class n{constructor(t){this.http=t}getFullHealth(){return this.http.get("api/health/full")}getMinimalHealth(){return this.http.get("api/health/minimal")}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(y.eN))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();var fy=i(89154),Zm=i(99475);function kS(n,s){if(1&n&&(e.TgZ(0,"div",6),e.tHW(1,7),e.ALo(2,"lowercase"),e._UZ(3,"cd-doc",8),e.ALo(4,"lowercase"),e.N_p(),e.qZA()),2&n){const t=e.oxw();e.xp6(3),e.MGl("section","dashboard-landing-page-",e.lcZ(4,4,t.groupTitle),""),e.xp6(1),e.pQV(e.lcZ(2,2,t.groupTitle)),e.QtT(1)}}const qb=function(n,s){return[n,s]},eE=["*"];let $S=(()=>{class n{constructor(){this.icons=xo.P}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-info-group"]],inputs:{groupTitle:"groupTitle"},ngContentSelectors:eE,decls:11,vars:6,consts:function(){let s,t;return s="here",t="For an overview of " + "\ufffd0\ufffd" + " widgets click " + "\ufffd#3\ufffd" + "" + "\ufffd/#3\ufffd" + "",[[1,"row"],["triggers","",1,"info-group-title",3,"ngbPopover"],["popInfo","ngbPopover"],["type","button",1,"popover-icon","btn","btn-link","p-0",3,"click"],[3,"ngClass"],["popInfoTemplate",""],[1,"text-center"],t,["docText",s,3,"section"]]},template:function(t,o){if(1&t){const c=e.EpF();e.F$t(),e.TgZ(0,"div",0),e.TgZ(1,"div",1,2),e.TgZ(3,"span"),e._uU(4),e.qZA(),e.TgZ(5,"button",3),e.NdJ("click",function(){return e.CHM(c),e.MAs(2).toggle()}),e._UZ(6,"i",4),e.qZA(),e.qZA(),e.qZA(),e.TgZ(7,"div",0),e.Hsn(8),e.qZA(),e.YNc(9,kS,5,6,"ng-template",null,5,e.W1O)}if(2&t){const c=e.MAs(10);e.xp6(1),e.Q6J("ngbPopover",c),e.xp6(3),e.Oqu(o.groupTitle),e.xp6(2),e.Q6J("ngClass",e.WLB(3,qb,o.icons.infoCircle,o.icons.large))}},directives:[ut.o8,la.o,_.mk,il.K],pipes:[_.i8],styles:[".info-group-title[_ngcontent-%COMP%]{font-size:1.75rem;margin:0 0 .5vw .5vw}.popover-icon[_ngcontent-%COMP%]:focus{box-shadow:none}"]}),n})();function dO(n,s){if(1&n&&(e.TgZ(0,"a",6),e._uU(1),e.qZA()),2&n){const t=e.oxw();e.Q6J("routerLink",t.link),e.xp6(1),e.Oqu(t.cardTitle)}}function HS(n,s){if(1&n&&e._uU(0),2&n){const t=e.oxw();e.hij(" ",t.cardTitle," ")}}const US=["*"];let tE=(()=>{class n{constructor(){this.cardClass=""}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-info-card"]],inputs:{cardTitle:"cardTitle",link:"link",cardClass:"cardClass",contentClass:"contentClass"},ngContentSelectors:US,decls:8,vars:4,consts:[[1,"card","shadow-sm",3,"ngClass"],[1,"card-body","d-flex","align-items-center","justify-content-center"],[1,"card-title","m-4"],[3,"routerLink",4,"ngIf","ngIfElse"],["noLinkTitle",""],[1,"card-text","text-center",3,"ngClass"],[3,"routerLink"]],template:function(t,o){if(1&t&&(e.F$t(),e.TgZ(0,"div",0),e.TgZ(1,"div",1),e.TgZ(2,"h4",2),e.YNc(3,dO,2,2,"a",3),e.YNc(4,HS,1,1,"ng-template",null,4,e.W1O),e.qZA(),e.TgZ(6,"div",5),e.Hsn(7),e.qZA(),e.qZA(),e.qZA()),2&t){const c=e.MAs(5);e.Q6J("ngClass",o.cardClass),e.xp6(3),e.Q6J("ngIf",o.link)("ngIfElse",c),e.xp6(3),e.Q6J("ngClass",o.contentClass)}},directives:[_.mk,_.O5,Bo.yS],styles:[".card[_ngcontent-%COMP%]{font-size:12px;border:.5px solid #dee2e6;border-radius:3px;height:100%}@media screen and (min-width: 320px){.card[_ngcontent-%COMP%]{font-size:calc(12px + 9 * ((100vw - 320px) / 1728))}}@media screen and (min-width: 2048px){.card[_ngcontent-%COMP%]{font-size:21px}}.card[_ngcontent-%COMP%] .card-body[_ngcontent-%COMP%]{padding-top:40px!important}.card[_ngcontent-%COMP%] .card-body[_ngcontent-%COMP%] .card-title[_ngcontent-%COMP%]{left:-.6rem;position:absolute;top:-.3rem}.no-center[_ngcontent-%COMP%]{left:unset;position:unset;top:unset;transform:unset}.content-highlight[_ngcontent-%COMP%]{font-weight:bold}"]}),n})();var BS=i(6823);const fO=["chartCanvas"],YS=["chartTooltip"];let ZS=(()=>{class n{constructor(t,o,c){this.dimlessBinary=t,this.dimless=o,this.cssHelper=c,this.config={},this.isBytesData=!1,this.showLabelAsTooltip=!1,this.prepareFn=new e.vpe,this.chartConfig={chartType:"doughnut",dataset:[{label:null,borderWidth:0}],colors:[{backgroundColor:[this.cssHelper.propertyValue("chart-color-green"),this.cssHelper.propertyValue("chart-color-yellow"),this.cssHelper.propertyValue("chart-color-orange"),this.cssHelper.propertyValue("chart-color-red"),this.cssHelper.propertyValue("chart-color-blue")]}],options:{cutoutPercentage:90,events:["click","mouseout","touchstart"],legend:{display:!0,position:"right",labels:{boxWidth:10,usePointStyle:!1}},plugins:{center_text:!0},tooltips:{enabled:!0,displayColors:!1,backgroundColor:this.cssHelper.propertyValue("chart-color-tooltip-background"),cornerRadius:0,bodyFontSize:14,bodyFontStyle:"600",position:"nearest",xPadding:12,yPadding:12,callbacks:{label:(g,C)=>{let D=C.labels[g.index];return D.includes("%")||(D=`${D} (${C.datasets[g.datasetIndex].data[g.index]}%)`),D}}},title:{display:!1}}},this.doughnutChartPlugins=[{id:"center_text",beforeDraw(g){const C=new Zm.P,D="Helvetica Neue, Helvetica, Arial, sans-serif";BS.defaults.global.defaultFontFamily=D;const P=g.ctx;if(!g.options.plugins.center_text||!g.data.datasets[0].label)return;P.save();const j=g.data.datasets[0].label.split("\n"),W=(g.chartArea.left+g.chartArea.right)/2,re=(g.chartArea.top+g.chartArea.bottom)/2;P.textAlign="center",P.textBaseline="middle",P.font=`24px ${D}`,P.fillStyle=C.propertyValue("chart-color-center-text"),P.fillText(j[0],W,re-10),j.length>1&&(P.font=`14px ${D}`,P.fillStyle=C.propertyValue("chart-color-center-text-description"),P.fillText(j[1],W,re+10)),P.restore()}}]}ngOnInit(){new Io.h(this.chartCanvasRef,this.chartTooltipRef,(g,C)=>C+g.caretX+"px",(g,C)=>C+g.caretY-g.height-10+"px").getBody=g=>this.getChartTooltipBody(g),wr().merge(this.chartConfig,this.config),this.prepareFn.emit([this.chartConfig,this.data])}ngOnChanges(){this.prepareFn.emit([this.chartConfig,this.data]),this.setChartSliceBorderWidth()}getChartTooltipBody(t){const o=t[0].split(": ");return this.showLabelAsTooltip?o[0]:(o[1]=this.isBytesData?this.dimlessBinary.transform(o[1]):this.dimless.transform(o[1]),o.join(": "))}setChartSliceBorderWidth(){let t=0;wr().forEach(this.chartConfig.dataset[0].data,function(o){o>0&&(t+=1)}),this.chartConfig.dataset[0].borderWidth=t>1?1:0}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(mn.$),e.Y36(Or.n),e.Y36(Zm.P))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-health-pie"]],viewQuery:function(t,o){if(1&t&&(e.Gf(fO,7),e.Gf(YS,7)),2&t){let c;e.iGM(c=e.CRH())&&(o.chartCanvasRef=c.first),e.iGM(c=e.CRH())&&(o.chartTooltipRef=c.first)}},inputs:{data:"data",config:"config",isBytesData:"isBytesData",tooltipFn:"tooltipFn",showLabelAsTooltip:"showLabelAsTooltip"},outputs:{prepareFn:"prepareFn"},features:[e.TTD],decls:6,vars:6,consts:[[1,"chart-container"],["baseChart","",1,"chart-canvas",3,"datasets","chartType","options","labels","colors","plugins"],["chartCanvas",""],[1,"chartjs-tooltip"],["chartTooltip",""]],template:function(t,o){1&t&&(e.TgZ(0,"div",0),e._UZ(1,"canvas",1,2),e.TgZ(3,"div",3,4),e._UZ(5,"table"),e.qZA(),e.qZA()),2&t&&(e.xp6(1),e.Q6J("datasets",o.chartConfig.dataset)("chartType",o.chartConfig.chartType)("options",o.chartConfig.options)("labels",o.chartConfig.labels)("colors",o.chartConfig.colors)("plugins",o.doughnutChartPlugins))},directives:[Fo.jh],styles:['.chart-container[_ngcontent-%COMP%]{cursor:pointer;margin:auto;overflow:visible;position:absolute}canvas[_ngcontent-%COMP%]{user-select:none}.chartjs-tooltip[_ngcontent-%COMP%]{background:rgba(0,0,0,.7);border-radius:3px;color:#fff;font-family:"Helvetica Neue","Helvetica","Arial",sans-serif!important;opacity:0;pointer-events:none;position:absolute;transform:translate(-50%);transition:all .1s ease}.chartjs-tooltip.transform-left[_ngcontent-%COMP%]{transform:translate(-10%)}.chartjs-tooltip.transform-left[_ngcontent-%COMP%]:after{left:10%}.chartjs-tooltip.transform-right[_ngcontent-%COMP%]{transform:translate(-90%)}.chartjs-tooltip.transform-right[_ngcontent-%COMP%]:after{left:90%}.chartjs-tooltip[_ngcontent-%COMP%]:after{border-color:#000 transparent transparent transparent;border-style:solid;border-width:5px;content:" ";left:50%;margin-left:-5px;position:absolute;top:100%} .chartjs-tooltip-key{display:inline-block;height:10px;margin-right:10px;width:10px}.chart-container[_ngcontent-%COMP%]{height:100%;margin-left:auto;margin-right:auto;position:unset;width:100%}.chart-canvas[_ngcontent-%COMP%]{height:100%;margin-left:auto;margin-right:auto;max-height:100%;max-width:100%;position:unset;width:100%}']}),n})(),nE=(()=>{class n{transform(t){if(!t)return"";let o=0,c=0,g=0,C=0;wr().each(t.osds,W=>{W.in&&o++,W.up&&c++,W.state.includes("nearfull")&&g++,W.state.includes("full")&&C++});const D=[{content:`${t.osds.length} ${"total"}`,class:""}];D.push({content:"",class:"card-text-line-break"}),D.push({content:`${c} ${"up"}, ${o} ${"in"}`,class:""});const P=t.osds.length-c,j=t.osds.length-o;if(P>0||j>0){D.push({content:"",class:"card-text-line-break"});const W=P>0?`${P} ${"down"}`:"",oe=j>0?`${j} ${"out"}`:"";D.push({content:`${W}${P>0&&j>0?", ":""}${oe}`,class:"card-text-error"})}return g>0&&D.push({content:"",class:"card-text-line-break"},{content:`${g} ${"near full"}`,class:"card-text-error"},{content:"",class:"card-text-line-break"}),C>0&&D.push({content:`${C} ${"full"}`,class:"card-text-error"}),D}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275pipe=e.Yjl({name:"osdSummary",type:n,pure:!0}),n})(),py=(()=>{class n{transform(t){if(!t)return"";let o="",c="",g=0,C=0,D=0;wr().each(t.standbys,()=>{g+=1}),t.standbys&&!t.filesystems?(o=`${g} ${"up"}`,c="no filesystems"):0===t.filesystems.length?o="no filesystems":(wr().each(t.filesystems,Fe=>{wr().each(Fe.mdsmap.info,Re=>{"up:standby-replay"===Re.state?D+=1:C+=1})}),o=`${C} ${"active"}`,c=`${g+D} ${"standby"}`);const P=t.standbys.map(Fe=>Fe.name).join(", "),j=P?`${"standby daemons"}: ${P}`:"",W=t.filesystems?t.filesystems.length:0,oe=Object.values(W>0?t.filesystems[0].mdsmap.info:{}).map(Fe=>Fe.name).join(", ");let me=oe?`${"active daemon"}: ${oe}`:"";!C&&W>0&&(me=`${D} ${"standbyReplay"}`);const _e=[{content:o,class:"popover-info",titleText:me}];return c&&(_e.push({content:"",class:"card-text-line-break",titleText:""}),_e.push({content:c,class:"popover-info",titleText:j})),_e}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275pipe=e.Yjl({name:"mdsSummary",type:n,pure:!0}),n})();var xg=(()=>{return(n=xg||(xg={})).HEALTH_ERR="health-color-error",n.HEALTH_WARN="health-color-warning",n.HEALTH_OK="health-color-healthy",xg;var n})();let rE=(()=>{class n{constructor(t){this.cssHelper=t}transform(t){return Object.keys(xg).includes(t)?{color:this.cssHelper.propertyValue(xg[t])}:null}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Zm.P,16))},n.\u0275pipe=e.Yjl({name:"healthColor",type:n,pure:!0}),n})(),jS=(()=>{class n{transform(t){return t?"" + t.monmap.mons.length.toString() + " (quorum " + t.quorum.join(", ") + ")":""}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275pipe=e.Yjl({name:"monSummary",type:n,pure:!0}),n})(),GS=(()=>{class n{transform(t){if(!t)return"";let o="n/a";const c=wr().isUndefined(t.active_name)?"":`${"active daemon"}: ${t.active_name}`;c.length>0&&(o="1");const g=t.standbys.map(j=>j.name).join(", "),C=g?`${"standby daemons"}: ${g}`:"",D=t.standbys.length,P=[{content:`${o} ${"active"}`,class:"popover-info",titleText:c}];return P.push({content:"",class:"card-text-line-break",titleText:""}),P.push({content:`${D} ${"standby"}`,class:"popover-info",titleText:C}),P}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275pipe=e.Yjl({name:"mgrSummary",type:n,pure:!0}),n})();function VS(n,s){1&n&&e.GkF(0)}function zS(n,s){if(1&n&&(e.TgZ(0,"li"),e.TgZ(1,"span",22),e.ALo(2,"healthColor"),e._uU(3),e.qZA(),e._uU(4),e.qZA()),2&n){const t=s.$implicit;e.xp6(1),e.Q6J("ngStyle",e.lcZ(2,3,t.severity)),e.xp6(2),e.Oqu(t.type),e.xp6(1),e.hij(": ",t.summary.message," ")}}function WS(n,s){if(1&n&&(e.YNc(0,VS,1,0,"ng-container",20),e.TgZ(1,"ul"),e.YNc(2,zS,5,5,"li",21),e.qZA()),2&n){e.oxw(4);const t=e.MAs(5),o=e.oxw();e.Q6J("ngTemplateOutlet",t),e.xp6(2),e.Q6J("ngForOf",o.healthData.health.checks)}}function JS(n,s){1&n&&e._UZ(0,"i",23)}function vR(n,s){if(1&n&&(e.ynx(0),e.YNc(1,WS,3,2,"ng-template",null,17,e.W1O),e.TgZ(3,"div",18),e.ALo(4,"healthColor"),e._uU(5),e.YNc(6,JS,1,0,"i",19),e.qZA(),e.BQk()),2&n){const t=e.MAs(2),o=e.oxw(4);e.xp6(3),e.Q6J("ngStyle",e.lcZ(4,4,o.healthData.health.status))("ngbPopover",t),e.xp6(2),e.hij(" ",o.healthData.health.status," "),e.xp6(1),e.Q6J("ngIf","HEALTH_OK"!=(null==o.healthData.health?null:o.healthData.health.status))}}function pO(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"div",22),e.ALo(2,"healthColor"),e._uU(3),e.qZA(),e.BQk()),2&n){const t=e.oxw(4);e.xp6(1),e.Q6J("ngStyle",e.lcZ(2,2,t.healthData.health.status)),e.xp6(2),e.hij(" ",t.healthData.health.status," ")}}function hO(n,s){if(1&n&&(e.TgZ(0,"cd-info-card",15),e.YNc(1,vR,7,6,"ng-container",16),e.YNc(2,pO,4,4,"ng-container",16),e.qZA()),2&n){const t=e.oxw(3);e.xp6(1),e.Q6J("ngIf",(null==t.healthData.health||null==t.healthData.health.checks?null:t.healthData.health.checks.length)>0),e.xp6(1),e.Q6J("ngIf",!(null!=t.healthData.health&&null!=t.healthData.health.checks&&t.healthData.health.checks.length))}}function QS(n,s){if(1&n&&(e.TgZ(0,"cd-info-card",24),e._uU(1),e.qZA()),2&n){const t=e.oxw(3);e.xp6(1),e.hij(" ",t.healthData.hosts," total ")}}function _O(n,s){if(1&n&&(e.TgZ(0,"cd-info-card",25),e._uU(1),e.ALo(2,"monSummary"),e.qZA()),2&n){const t=e.oxw(3);e.xp6(1),e.hij(" ",e.lcZ(2,1,t.healthData.mon_status)," ")}}function Tf(n,s){if(1&n&&(e.TgZ(0,"span",28),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("ngClass",t.class),e.xp6(1),e.hij(" ",t.content," ")}}function XS(n,s){if(1&n&&(e.TgZ(0,"cd-info-card",26),e.YNc(1,Tf,2,2,"span",27),e.qZA()),2&n){const t=s.ngIf;e.xp6(1),e.Q6J("ngForOf",t)}}function gO(n,s){if(1&n&&(e.TgZ(0,"span",31),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("ngClass",t.class)("title",null!=t.titleText?t.titleText:""),e.xp6(1),e.hij(" ",t.content," ")}}function mO(n,s){if(1&n&&(e.TgZ(0,"cd-info-card",29),e.YNc(1,gO,2,3,"span",30),e.ALo(2,"mgrSummary"),e.qZA()),2&n){const t=e.oxw(3);e.xp6(1),e.Q6J("ngForOf",e.lcZ(2,1,t.healthData.mgr_map))}}function KS(n,s){if(1&n&&(e.TgZ(0,"cd-info-card",32),e._uU(1),e.qZA()),2&n){const t=e.oxw(3);e.xp6(1),e.hij(" ",t.healthData.rgw," total ")}}function vO(n,s){if(1&n&&(e.TgZ(0,"span",31),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("ngClass",t.class)("title",null!=t.titleText?t.titleText:""),e.xp6(1),e.hij(" ",t.content," ")}}function qS(n,s){if(1&n&&(e.TgZ(0,"cd-info-card",33),e.YNc(1,vO,2,3,"span",30),e.qZA()),2&n){const t=s.ngIf;e.Q6J("contentClass",(t.length>1?"text-area-size-2":"")+" content-highlight"),e.xp6(1),e.Q6J("ngForOf",t)}}const eC=function(n){return{"card-text-error":n}};function Ov(n,s){if(1&n&&(e.TgZ(0,"cd-info-card",34),e._uU(1),e._UZ(2,"span",35),e._uU(3),e.TgZ(4,"span",28),e._uU(5),e.qZA(),e.qZA()),2&n){const t=e.oxw(3);e.xp6(1),e.hij(" ",t.healthData.iscsi_daemons.up+t.healthData.iscsi_daemons.down," total "),e.xp6(2),e.hij(" ",t.healthData.iscsi_daemons.up," up, "),e.xp6(1),e.Q6J("ngClass",e.VKq(4,eC,t.healthData.iscsi_daemons.down>0)),e.xp6(1),e.hij("",t.healthData.iscsi_daemons.down," down")}}function yO(n,s){if(1&n&&(e.TgZ(0,"cd-info-group",6),e.YNc(1,hO,3,2,"cd-info-card",7),e.YNc(2,QS,2,1,"cd-info-card",8),e.YNc(3,_O,3,3,"cd-info-card",9),e.YNc(4,XS,2,1,"cd-info-card",10),e.ALo(5,"osdSummary"),e.YNc(6,mO,3,3,"cd-info-card",11),e.YNc(7,KS,2,1,"cd-info-card",12),e.YNc(8,qS,2,2,"cd-info-card",13),e.ALo(9,"mdsSummary"),e.YNc(10,Ov,6,6,"cd-info-card",14),e.qZA()),2&n){const t=e.oxw().ngIf,o=e.oxw();e.xp6(1),e.Q6J("ngIf",null==o.healthData.health?null:o.healthData.health.status),e.xp6(1),e.Q6J("ngIf",null!=o.healthData.hosts),e.xp6(1),e.Q6J("ngIf",o.healthData.mon_status),e.xp6(1),e.Q6J("ngIf",e.lcZ(5,8,o.healthData.osd_map)),e.xp6(2),e.Q6J("ngIf",o.healthData.mgr_map),e.xp6(1),e.Q6J("ngIf",t.rgw&&null!=o.healthData.rgw),e.xp6(1),e.Q6J("ngIf",e.lcZ(9,10,t.cephfs&&o.healthData.fs_map)),e.xp6(2),e.Q6J("ngIf",t.iscsi&&null!=o.healthData.iscsi_daemons)}}function bO(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-info-card",42),e.TgZ(1,"cd-health-pie",43),e.NdJ("prepareFn",function(c){return e.CHM(t),e.oxw(3).prepareRawUsage(c[0],c[1])}),e.qZA(),e.qZA()}if(2&n){const t=e.oxw(3);e.xp6(1),e.Q6J("data",t.healthData)("config",t.rawCapacityChartConfig)("isBytesData",!0)}}function tC(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-info-card",44),e.TgZ(1,"cd-health-pie",45),e.NdJ("prepareFn",function(c){return e.CHM(t),e.oxw(3).prepareObjects(c[0],c[1])}),e.qZA(),e.qZA()}if(2&n){const t=e.oxw(3);e.xp6(1),e.Q6J("data",t.healthData)}}function EO(n,s){1&n&&e.GkF(0)}function nC(n,s){if(1&n&&(e.TgZ(0,"li"),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.xp6(1),e.AsE(" ",t.key,": ",t.value," ")}}function yR(n,s){if(1&n&&(e.YNc(0,EO,1,0,"ng-container",20),e.TgZ(1,"ul"),e.YNc(2,nC,2,2,"li",21),e.ALo(3,"keyvalue"),e.qZA()),2&n){e.oxw(3);const t=e.MAs(5),o=e.oxw();e.Q6J("ngTemplateOutlet",t),e.xp6(2),e.Q6J("ngForOf",e.lcZ(3,2,o.healthData.pg_info.statuses))}}function iE(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-info-card",46),e.YNc(1,yR,4,4,"ng-template",null,47,e.W1O),e.TgZ(3,"div",48),e.TgZ(4,"div",49),e.TgZ(5,"cd-health-pie",50),e.NdJ("prepareFn",function(c){return e.CHM(t),e.oxw(3).preparePgStatus(c[0],c[1])}),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=e.MAs(2),o=e.oxw(3);e.xp6(4),e.Q6J("ngbPopover",t),e.xp6(1),e.Q6J("data",o.healthData)("config",o.pgStatusChartConfig)}}function oE(n,s){if(1&n&&(e.TgZ(0,"cd-info-card",51),e._uU(1),e.qZA()),2&n){const t=e.oxw(3);e.xp6(1),e.hij(" ",t.healthData.pools.length," ")}}function rg(n,s){if(1&n&&(e.TgZ(0,"cd-info-card",52),e._uU(1),e.ALo(2,"dimless"),e.qZA()),2&n){const t=e.oxw(3);e.xp6(1),e.hij(" ",e.lcZ(2,1,t.healthData.pg_info.pgs_per_osd)," ")}}function TO(n,s){if(1&n&&(e.TgZ(0,"cd-info-group",36),e.YNc(1,bO,2,3,"cd-info-card",37),e.YNc(2,tC,2,1,"cd-info-card",38),e.YNc(3,iE,6,3,"cd-info-card",39),e.YNc(4,oE,2,1,"cd-info-card",40),e.YNc(5,rg,3,3,"cd-info-card",41),e.qZA()),2&n){const t=e.oxw(2);e.xp6(1),e.Q6J("ngIf",t.healthData.df),e.xp6(1),e.Q6J("ngIf",null!=(null==t.healthData.pg_info||null==t.healthData.pg_info.object_stats?null:t.healthData.pg_info.object_stats.num_objects)),e.xp6(1),e.Q6J("ngIf",t.healthData.pg_info),e.xp6(1),e.Q6J("ngIf",t.healthData.pools),e.xp6(1),e.Q6J("ngIf",t.healthData.pg_info)}}function rC(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-info-card",58),e.TgZ(1,"cd-health-pie",50),e.NdJ("prepareFn",function(c){return e.CHM(t),e.oxw(3).prepareReadWriteRatio(c[0],c[1])}),e.qZA(),e.qZA()}if(2&n){const t=e.oxw(3);e.xp6(1),e.Q6J("data",t.healthData)("config",t.clientStatsConfig)}}function ig(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-info-card",59),e.TgZ(1,"cd-health-pie",50),e.NdJ("prepareFn",function(c){return e.CHM(t),e.oxw(3).prepareClientThroughput(c[0],c[1])}),e.qZA(),e.qZA()}if(2&n){const t=e.oxw(3);e.xp6(1),e.Q6J("data",t.healthData)("config",t.clientStatsConfig)}}function O_(n,s){if(1&n&&(e.TgZ(0,"cd-info-card",60),e._uU(1),e.ALo(2,"dimlessBinary"),e.qZA()),2&n){const t=e.oxw(3);e.xp6(1),e.hij(" ",e.lcZ(2,1,t.healthData.client_perf.recovering_bytes_per_sec)+"/s"," ")}}function w_(n,s){if(1&n&&(e.TgZ(0,"cd-info-card",61),e._uU(1),e.qZA()),2&n){const t=e.oxw(3);e.xp6(1),e.hij(" ",t.healthData.scrub_status," ")}}function iC(n,s){if(1&n&&(e.TgZ(0,"cd-info-group",53),e.YNc(1,rC,2,2,"cd-info-card",54),e.YNc(2,ig,2,2,"cd-info-card",55),e.YNc(3,O_,3,3,"cd-info-card",56),e.YNc(4,w_,2,1,"cd-info-card",57),e.qZA()),2&n){const t=e.oxw(2);e.xp6(1),e.Q6J("ngIf",t.healthData.client_perf),e.xp6(1),e.Q6J("ngIf",t.healthData.client_perf),e.xp6(1),e.Q6J("ngIf",t.healthData.client_perf),e.xp6(1),e.Q6J("ngIf",t.healthData.scrub_status)}}const oC=function(n){return[n]};function SO(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"p",62),e.tHW(2,63),e._UZ(3,"i",28),e._UZ(4,"a",64),e.N_p(),e.qZA(),e.BQk()),2&n){const t=e.oxw(3);e.xp6(3),e.Q6J("ngClass",e.VKq(1,oC,t.icons.infoCircle))}}function CO(n,s){if(1&n&&e.YNc(0,SO,5,3,"ng-container",16),2&n){const t=e.oxw(2);e.Q6J("ngIf",t.permissions.log.read)}}function MO(n,s){if(1&n&&(e.TgZ(0,"div",1),e.YNc(1,yO,11,12,"cd-info-group",2),e.YNc(2,TO,6,5,"cd-info-group",3),e.YNc(3,iC,5,4,"cd-info-group",4),e.YNc(4,CO,1,1,"ng-template",null,5,e.W1O),e.qZA()),2&n){const t=e.oxw();e.xp6(1),e.Q6J("ngIf",(null==t.healthData.health?null:t.healthData.health.status)||t.healthData.mon_status||t.healthData.osd_map||t.healthData.mgr_map||null!=t.healthData.hosts||null!=t.healthData.rgw||t.healthData.fs_map||null!=t.healthData.iscsi_daemons),e.xp6(1),e.Q6J("ngIf",t.healthData.pools||t.healthData.df||t.healthData.pg_info),e.xp6(1),e.Q6J("ngIf",t.healthData.client_perf||t.healthData.scrub_status)}}let AO=(()=>{class n{constructor(t,o,c,g,C,D,P,j,W){this.healthService=t,this.osdService=o,this.authStorageService=c,this.pgCategoryService=g,this.featureToggles=C,this.refreshIntervalService=D,this.dimlessBinary=P,this.dimless=j,this.cssHelper=W,this.osdSettings=new Ac,this.interval=new _u.w,this.icons=xo.P,this.clientStatsConfig={colors:[{backgroundColor:[this.cssHelper.propertyValue("chart-color-cyan"),this.cssHelper.propertyValue("chart-color-purple")]}]},this.rawCapacityChartConfig={colors:[{backgroundColor:[this.cssHelper.propertyValue("chart-color-blue"),this.cssHelper.propertyValue("chart-color-gray")]}]},this.pgStatusChartConfig={options:{events:[""]}},this.permissions=this.authStorageService.getPermissions(),this.enabledFeature$=this.featureToggles.get()}ngOnInit(){this.interval=this.refreshIntervalService.intervalData$.subscribe(()=>{this.getHealth()}),this.osdService.getOsdSettings().pipe((0,ve.q)(1)).subscribe(t=>{this.osdSettings=t})}ngOnDestroy(){this.interval.unsubscribe()}getHealth(){this.healthService.getMinimalHealth().subscribe(t=>{this.healthData=t})}prepareReadWriteRatio(t){const o=[],c=[],g=this.healthData.client_perf.write_op_per_sec+this.healthData.client_perf.read_op_per_sec;o.push(`${"Reads"}: ${this.dimless.transform(this.healthData.client_perf.read_op_per_sec)} ${"/s"}`),c.push(this.calcPercentage(this.healthData.client_perf.read_op_per_sec,g)),o.push(`${"Writes"}: ${this.dimless.transform(this.healthData.client_perf.write_op_per_sec)} ${"/s"}`),c.push(this.calcPercentage(this.healthData.client_perf.write_op_per_sec,g)),t.labels=o,t.dataset[0].data=c,t.dataset[0].label=`${this.dimless.transform(g)}\n${"IOPS"}`}prepareClientThroughput(t){const o=[],c=[],g=this.healthData.client_perf.read_bytes_sec+this.healthData.client_perf.write_bytes_sec;o.push(`${"Reads"}: ${this.dimlessBinary.transform(this.healthData.client_perf.read_bytes_sec)}${"/s"}`),c.push(this.calcPercentage(this.healthData.client_perf.read_bytes_sec,g)),o.push(`${"Writes"}: ${this.dimlessBinary.transform(this.healthData.client_perf.write_bytes_sec)}${"/s"}`),c.push(this.calcPercentage(this.healthData.client_perf.write_bytes_sec,g)),t.labels=o,t.dataset[0].data=c,t.dataset[0].label=`${this.dimlessBinary.transform(g).replace(" ","\n")}${"/s"}`}prepareRawUsage(t,o){const c=this.calcPercentage(o.df.stats.total_bytes-o.df.stats.total_used_raw_bytes,o.df.stats.total_bytes),g=this.calcPercentage(o.df.stats.total_used_raw_bytes,o.df.stats.total_bytes);this.color=g/100>=this.osdSettings.nearfull_ratio?"chart-color-red":g/100>=this.osdSettings.full_ratio?"chart-color-yellow":"chart-color-blue",this.rawCapacityChartConfig.colors[0].backgroundColor[0]=this.cssHelper.propertyValue(this.color),t.dataset[0].data=[g,c],t.labels=[`${"Used"}: ${this.dimlessBinary.transform(o.df.stats.total_used_raw_bytes)}`,`${"Avail."}: ${this.dimlessBinary.transform(o.df.stats.total_bytes-o.df.stats.total_used_raw_bytes)}`],t.dataset[0].label=`${g}%\nof ${this.dimlessBinary.transform(o.df.stats.total_bytes)}`}preparePgStatus(t,o){const c={};let g=0;wr().forEach(o.pg_info.statuses,(C,D)=>{const P=this.pgCategoryService.getTypeByStates(D);wr().isUndefined(c[P])&&(c[P]=0),c[P]+=C,g+=C});for(const C of this.pgCategoryService.getAllTypes())wr().isUndefined(c[C])&&(c[C]=0);t.dataset[0].data=this.pgCategoryService.getAllTypes().map(C=>this.calcPercentage(c[C],g)),t.labels=[`${"Clean"}: ${this.dimless.transform(c.clean)}`,`${"Working"}: ${this.dimless.transform(c.working)}`,`${"Warning"}: ${this.dimless.transform(c.warning)}`,`${"Unknown"}: ${this.dimless.transform(c.unknown)}`],t.dataset[0].label=`${g}\n${"PGs"}`}prepareObjects(t,o){const c=o.pg_info.object_stats.num_object_copies,C=this.calcPercentage(c-o.pg_info.object_stats.num_objects_misplaced-o.pg_info.object_stats.num_objects_degraded-o.pg_info.object_stats.num_objects_unfound,c),D=this.calcPercentage(o.pg_info.object_stats.num_objects_misplaced,c),P=this.calcPercentage(o.pg_info.object_stats.num_objects_degraded,c),j=this.calcPercentage(o.pg_info.object_stats.num_objects_unfound,c);t.labels=[`${"Healthy"}: ${C}%`,`${"Misplaced"}: ${D}%`,`${"Degraded"}: ${P}%`,`${"Unfound"}: ${j}%`],t.dataset[0].data=[C,D,P,j],t.dataset[0].label=`${this.dimless.transform(o.pg_info.object_stats.num_objects)}\n${"objects"}`}isClientReadWriteChartShowable(){return(this.healthData.client_perf.read_op_per_sec||0)+(this.healthData.client_perf.write_op_per_sec||0)>0}calcPercentage(t,o){return wr().isNumber(t)&&wr().isNumber(o)&&0!==o?Math.ceil(t/o*100*100)/100:0}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(FS),e.Y36(Ji),e.Y36(vt.j),e.Y36(Kb.j),e.Y36(fy.l),e.Y36(uO),e.Y36(mn.$),e.Y36(Or.n),e.Y36(Zm.P))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-health"]],decls:2,vars:3,consts:function(){let s,t,o,c,g,C,D,P,j,W,re,oe,me,_e,Fe,Re,Le,we,U,pt,ht;return s="Status",t="Capacity",o="Performance",c="Cluster Status",g="Hosts",C="Monitors",D="OSDs",P="Managers",j="Object Gateways",W="Metadata Servers",re="iSCSI Gateways",oe="Raw Capacity",me="Objects",_e="PG Status",Fe="Pools",Re="PGs per OSD",Le="Client Read/Write",we="Client Throughput",U="Recovery Throughput",pt="Scrubbing",ht="" + "\ufffd#3\ufffd" + "" + "\ufffd/#3\ufffd" + " See " + "\ufffd#4\ufffd" + "Logs" + "\ufffd/#4\ufffd" + " for more details.",[["class","container-fluid",4,"ngIf"],[1,"container-fluid"],["groupTitle",s,4,"ngIf"],["groupTitle",t,4,"ngIf"],["groupTitle",o,4,"ngIf"],["logsLink",""],["groupTitle",s],["cardTitle",c,"class","cd-status-card","contentClass","content-highlight",4,"ngIf"],["cardTitle",g,"link","/hosts","class","cd-status-card","contentClass","content-highlight",4,"ngIf"],["cardTitle",C,"link","/monitor","class","cd-status-card","contentClass","content-highlight",4,"ngIf"],["cardTitle",D,"link","/osd","class","cd-status-card","contentClass","content-highlight",4,"ngIf"],["cardTitle",P,"class","cd-status-card","contentClass","content-highlight",4,"ngIf"],["cardTitle",j,"link","/rgw/daemon","class","cd-status-card","contentClass","content-highlight",4,"ngIf"],["cardTitle",W,"class","cd-status-card",3,"contentClass",4,"ngIf"],["cardTitle",re,"link","/block/iscsi","class","cd-status-card","contentClass","content-highlight",4,"ngIf"],["cardTitle",c,"contentClass","content-highlight",1,"cd-status-card"],[4,"ngIf"],["healthChecks",""],["popoverClass","info-card-popover-cluster-status",1,"info-card-content-clickable",3,"ngStyle","ngbPopover"],["class","fa fa-exclamation-triangle",4,"ngIf"],[4,"ngTemplateOutlet"],[4,"ngFor","ngForOf"],[3,"ngStyle"],[1,"fa","fa-exclamation-triangle"],["cardTitle",g,"link","/hosts","contentClass","content-highlight",1,"cd-status-card"],["cardTitle",C,"link","/monitor","contentClass","content-highlight",1,"cd-status-card"],["cardTitle",D,"link","/osd","contentClass","content-highlight",1,"cd-status-card"],[3,"ngClass",4,"ngFor","ngForOf"],[3,"ngClass"],["cardTitle",P,"contentClass","content-highlight",1,"cd-status-card"],[3,"ngClass","title",4,"ngFor","ngForOf"],[3,"ngClass","title"],["cardTitle",j,"link","/rgw/daemon","contentClass","content-highlight",1,"cd-status-card"],["cardTitle",W,1,"cd-status-card",3,"contentClass"],["cardTitle",re,"link","/block/iscsi","contentClass","content-highlight",1,"cd-status-card"],[1,"card-text-line-break"],["groupTitle",t],["cardTitle",oe,"class","cd-capacity-card cd-chart-card","contentClass","content-chart",4,"ngIf"],["cardTitle",me,"class","cd-capacity-card cd-chart-card","contentClass","content-chart",4,"ngIf"],["cardTitle",_e,"class","cd-capacity-card cd-chart-card","contentClass","content-chart",4,"ngIf"],["cardTitle",Fe,"link","/pool","class","cd-capacity-card","contentClass","content-highlight",4,"ngIf"],["cardTitle",Re,"class","cd-capacity-card","contentClass","content-highlight",4,"ngIf"],["cardTitle",oe,"contentClass","content-chart",1,"cd-capacity-card","cd-chart-card"],[3,"data","config","isBytesData","prepareFn"],["cardTitle",me,"contentClass","content-chart",1,"cd-capacity-card","cd-chart-card"],[3,"data","prepareFn"],["cardTitle",_e,"contentClass","content-chart",1,"cd-capacity-card","cd-chart-card"],["pgStatus",""],[1,"pg-status-popover-wrapper"],[3,"ngbPopover"],[3,"data","config","prepareFn"],["cardTitle",Fe,"link","/pool","contentClass","content-highlight",1,"cd-capacity-card"],["cardTitle",Re,"contentClass","content-highlight",1,"cd-capacity-card"],["groupTitle",o],["cardTitle",Le,"class","cd-performance-card cd-chart-card","contentClass","content-chart",4,"ngIf"],["cardTitle",we,"class","cd-performance-card cd-chart-card","contentClass","content-chart",4,"ngIf"],["cardTitle",U,"class","cd-performance-card","contentClass","content-highlight",4,"ngIf"],["cardTitle",pt,"class","cd-performance-card","contentClass","content-highlight",4,"ngIf"],["cardTitle",Le,"contentClass","content-chart",1,"cd-performance-card","cd-chart-card"],["cardTitle",we,"contentClass","content-chart",1,"cd-performance-card","cd-chart-card"],["cardTitle",U,"contentClass","content-highlight",1,"cd-performance-card"],["cardTitle",pt,"contentClass","content-highlight",1,"cd-performance-card"],[1,"logs-link"],ht,["routerLink","/logs"]]},template:function(t,o){1&t&&(e.YNc(0,MO,6,3,"div",0),e.ALo(1,"async")),2&t&&e.Q6J("ngIf",e.lcZ(1,1,o.healthData&&o.enabledFeature$))},directives:[_.O5,$S,tE,_.PC,ut.o8,_.tP,_.sg,_.mk,ZS,Bo.yS],pipes:[_.Ov,nE,py,rE,jS,GS,_.Nd,Or.n,mn.$],styles:['cd-info-card[_ngcontent-%COMP%]{padding:0 .5vw} cd-health .pg-status-popover-wrapper{position:relative} cd-health .pg-status-popover-wrapper .popover{max-height:20vh;max-width:unset!important;min-width:unset!important;position:absolute;width:116%} cd-health .pg-status-popover-wrapper .popover .popover-body{font-size:1rem;max-height:19vh;max-width:100%}.logs-link[_ngcontent-%COMP%]{text-align:center}.card-text-error[_ngcontent-%COMP%]{color:#c9190b;display:inline}.card-text-line-break[_ngcontent-%COMP%]:after{content:"\\a";white-space:pre}.popover-info[_ngcontent-%COMP%]:hover{cursor:pointer}']}),n})();function sE(n,s){1&n&&e._UZ(0,"cd-health")}function R1(n,s){}function OO(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"ul",1,2),e.TgZ(3,"li",3),e.TgZ(4,"a",4),e.SDv(5,5),e.qZA(),e.YNc(6,sE,1,0,"ng-template",6),e.qZA(),e.TgZ(7,"li",3),e.TgZ(8,"a",4),e.SDv(9,7),e.qZA(),e.YNc(10,R1,0,0,"ng-template",6),e.qZA(),e.qZA(),e._UZ(11,"div",8),e.BQk()),2&n){const t=e.MAs(2);e.xp6(11),e.Q6J("ngbNavOutlet",t)}}function sC(n,s){1&n&&e._UZ(0,"cd-health")}let wO=(()=>{class n{constructor(){this.hasGrafana=!1}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-dashboard"]],decls:4,vars:2,consts:function(){let s,t;return s="Health",t="Statistics",[[4,"ngIf"],["ngbNav","",1,"nav-tabs"],["nav","ngbNav"],["ngbNavItem",""],["ngbNavLink",""],s,["ngbNavContent",""],t,[3,"ngbNavOutlet"]]},template:function(t,o){1&t&&(e.TgZ(0,"div"),e._UZ(1,"cd-refresh-selector"),e.YNc(2,OO,12,1,"ng-container",0),e.YNc(3,sC,1,0,"cd-health",0),e.qZA()),2&t&&(e.xp6(2),e.Q6J("ngIf",o.hasGrafana),e.xp6(1),e.Q6J("ngIf",!o.hasGrafana))},directives:[Xb,_.O5,ut.Pz,ut.nv,ut.Vx,ut.uN,ut.tO,AO],styles:["div[_ngcontent-%COMP%]{padding-top:20px}"]}),n})();var wv=i(5304),aC=i(95152),hy=i(33394),lC=i(40205);let _y=(()=>{class n extends Kf.S{constructor(t){super(),this.http=t,this.apiPath="api/nfs-ganesha",this.uiApiPath="ui-api/nfs-ganesha",this.nfsAccessType=[{value:"RW",help:"Allows all operations"},{value:"RO",help:"Allows only operations that do not modify the server"},{value:"NONE",help:"Allows no access at all"}],this.nfsFsal=[{value:"CEPH",descr:"CephFS",disabled:!1},{value:"RGW",descr:"Object Gateway",disabled:!1}],this.nfsSquash={no_root_squash:["no_root_squash","noidsquash","none"],root_id_squash:["root_id_squash","rootidsquash","rootid"],root_squash:["root_squash","rootsquash","root"],all_squash:["all_squash","allsquash","all","allanonymous","all_anonymous"]}}list(){return this.http.get(`${this.apiPath}/export`)}get(t,o){return this.http.get(`${this.apiPath}/export/${t}/${o}`)}create(t){return this.http.post(`${this.apiPath}/export`,t,{headers:{Accept:this.getVersionHeaderValue(2,0)},observe:"response"})}update(t,o,c){return this.http.put(`${this.apiPath}/export/${t}/${o}`,c,{headers:{Accept:this.getVersionHeaderValue(2,0)},observe:"response"})}delete(t,o){return this.http.delete(`${this.apiPath}/export/${t}/${o}`,{headers:{Accept:this.getVersionHeaderValue(2,0)},observe:"response"})}listClusters(){return this.http.get(`${this.apiPath}/cluster`,{headers:{Accept:this.getVersionHeaderValue(0,1)}})}lsDir(t,o){return t?this.http.get(`${this.uiApiPath}/lsdir/${t}?root_dir=${o}`):(0,lC._)("Please specify a filesystem volume.")}fsals(){return this.http.get(`${this.uiApiPath}/fsals`)}filesystems(){return this.http.get(`${this.uiApiPath}/cephfs/filesystems`)}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(y.eN))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();var uC=i(36569);const aE=["squashHelper"];function gy(n,s){1&n&&(e.TgZ(0,"span",14),e.TgZ(1,"span",15),e.SDv(2,16),e.qZA(),e.qZA())}function lE(n,s){1&n&&(e.TgZ(0,"span"),e.SDv(1,37),e.qZA())}function uE(n,s){1&n&&(e.TgZ(0,"span"),e.ynx(1),e.SDv(2,38),e.BQk(),e._UZ(3,"br"),e.ynx(4),e.SDv(5,39),e.BQk(),e._uU(6," 192.168.0.10, 192.168.1.0/8 "),e.qZA())}function cC(n,s){if(1&n&&(e.TgZ(0,"option",40),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t.value),e.xp6(1),e.Oqu(t.value)}}function dC(n,s){if(1&n&&(e.TgZ(0,"span",15),e._uU(1),e.qZA()),2&n){const t=e.oxw().index,o=e.oxw();e.xp6(1),e.hij(" ",o.getAccessTypeHelp(t)," ")}}function fC(n,s){1&n&&e.GkF(0)}function pC(n,s){if(1&n&&(e.TgZ(0,"option",40),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t),e.xp6(1),e.Oqu(t)}}function hC(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div"),e.TgZ(1,"div",17),e.TgZ(2,"div",18),e._uU(3),e.ALo(4,"ordinal"),e.TgZ(5,"span",19),e.NdJ("click",function(){const g=e.CHM(t).index;return e.oxw().removeClient(g)}),e._uU(6,"\xd7"),e.qZA(),e.qZA(),e.TgZ(7,"div",20),e.TgZ(8,"div",0),e.TgZ(9,"label",21),e.SDv(10,22),e.qZA(),e.TgZ(11,"div",23),e._UZ(12,"input",24),e.TgZ(13,"span",25),e.YNc(14,lE,2,0,"span",26),e.YNc(15,uE,7,0,"span",26),e.qZA(),e.qZA(),e.qZA(),e.TgZ(16,"div",0),e.TgZ(17,"label",27),e.SDv(18,28),e.qZA(),e.TgZ(19,"div",23),e.TgZ(20,"select",29),e.TgZ(21,"option",30),e._uU(22),e.qZA(),e.YNc(23,cC,2,2,"option",31),e.qZA(),e.YNc(24,dC,2,1,"span",32),e.qZA(),e.qZA(),e.TgZ(25,"div",0),e.TgZ(26,"label",33),e.TgZ(27,"span"),e.SDv(28,34),e.qZA(),e.YNc(29,fC,1,0,"ng-container",35),e.qZA(),e.TgZ(30,"div",23),e.TgZ(31,"select",36),e.TgZ(32,"option",30),e._uU(33),e.qZA(),e.YNc(34,pC,2,2,"option",31),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=s.$implicit,o=s.index,c=e.oxw(),g=e.MAs(4);e.xp6(1),e.Q6J("formGroup",t),e.xp6(2),e.hij(" ",e.lcZ(4,10,o+1)," "),e.xp6(11),e.Q6J("ngIf",c.showError(o,"addresses",g,"required")),e.xp6(1),e.Q6J("ngIf",c.showError(o,"addresses",g,"pattern")),e.xp6(7),e.Oqu(c.getNoAccessTypeDescr()),e.xp6(1),e.Q6J("ngForOf",c.nfsAccessType),e.xp6(1),e.Q6J("ngIf",c.getValue(o,"access_type")),e.xp6(5),e.Q6J("ngTemplateOutlet",c.squashHelperTpl),e.xp6(4),e.Oqu(c.getNoSquashDescr()),e.xp6(1),e.Q6J("ngForOf",c.nfsSquash)}}const _C=function(n){return[n]};let gC=(()=>{class n{constructor(t){this.nfsService=t,this.nfsSquash=Object.keys(this.nfsService.nfsSquash),this.nfsAccessType=this.nfsService.nfsAccessType,this.icons=xo.P}ngOnInit(){wr().forEach(this.clients,t=>{this.addClient().patchValue(t)}),this.clientsFormArray=this.form.get("clients")}getNoAccessTypeDescr(){return this.form.getValue("access_type")?`${this.form.getValue("access_type")} ${"(inherited from global config)"}`:"-- Select the access type --"}getAccessTypeHelp(t){const o=this.nfsAccessType.find(c=>this.getValue(t,"access_type")===c.value);return wr().isObjectLike(o)?o.help:""}getNoSquashDescr(){return this.form.getValue("squash")?`${this.form.getValue("squash")} (${"inherited from global config"})`:"-- Select what kind of user id squashing is performed --"}addClient(){this.clientsFormArray=this.form.get("clients");const t="(([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3}).([0-9]{1,3})([/](\\d|[1-2]\\d|3[0-2]))?)",c=new Hs.d({addresses:new Mn.NI("",{validators:[Mn.kI.required,Mn.kI.pattern(`${t}([ ,]{1,2}${t})*`)]}),access_type:new Mn.NI(""),squash:new Mn.NI("")});return this.clientsFormArray.push(c),c}removeClient(t){this.clientsFormArray=this.form.get("clients"),this.clientsFormArray.removeAt(t)}showError(t,o,c,g){return this.form.controls.clients.controls[t].showError(o,c,g)}getValue(t,o){return this.clientsFormArray=this.form.get("clients"),this.clientsFormArray.at(t).getValue(o)}trackByFn(t){return t}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(_y))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-nfs-form-client"]],contentQueries:function(t,o,c){if(1&t&&e.Suo(c,aE,7),2&t){let g;e.iGM(g=e.CRH())&&(o.squashHelperTpl=g.first)}},inputs:{form:"form",clients:"clients"},decls:15,vars:7,consts:function(){let s,t,o,c,g,C,D,P,j;return s="Clients",t="Add clients",o="Any client can access",c="Addresses",g="Access Type",C="Squash",D="This field is required.",P="Must contain one or more comma-separated values",j="For example:",[[1,"form-group","row"],[1,"cd-col-form-label"],s,[1,"cd-col-form-input",3,"formGroup"],["formDir","ngForm"],["class","no-border text-muted",4,"ngIf"],["formArrayName","clients"],[4,"ngFor","ngForOf","ngForTrackBy"],[1,"row"],[1,"col-12"],[1,"float-right"],["name","add_client",1,"btn","btn-light",3,"click"],[3,"ngClass"],t,[1,"no-border","text-muted"],[1,"form-text","text-muted"],o,[1,"card",3,"formGroup"],[1,"card-header"],["name","remove_client","ngbTooltip","Remove",1,"float-right","clickable",3,"click"],[1,"card-body"],["for","addresses",1,"cd-col-form-label","required"],c,[1,"cd-col-form-input"],["type","text","name","addresses","id","addresses","formControlName","addresses","placeholder","192.168.0.10, 192.168.1.0/8",1,"form-control"],[1,"invalid-feedback"],[4,"ngIf"],["for","access_type",1,"cd-col-form-label"],g,["name","access_type","id","access_type","formControlName","access_type",1,"form-control"],["value",""],[3,"value",4,"ngFor","ngForOf"],["class","form-text text-muted",4,"ngIf"],["for","squash",1,"cd-col-form-label"],C,[4,"ngTemplateOutlet"],["name","squash","id","squash","formControlName","squash",1,"form-control"],D,P,j,[3,"value"]]},template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"label",1),e.SDv(2,2),e.qZA(),e.TgZ(3,"div",3,4),e.YNc(5,gy,3,0,"span",5),e.ynx(6,6),e.YNc(7,hC,35,12,"div",7),e.BQk(),e.TgZ(8,"div",8),e.TgZ(9,"div",9),e.TgZ(10,"div",10),e.TgZ(11,"button",11),e.NdJ("click",function(){return o.addClient()}),e._UZ(12,"i",12),e.ynx(13),e.SDv(14,13),e.BQk(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()),2&t&&(e.xp6(3),e.Q6J("formGroup",o.form),e.xp6(2),e.Q6J("ngIf",0===o.form.get("clients").value.length),e.xp6(2),e.Q6J("ngForOf",o.clientsFormArray.controls)("ngForTrackBy",o.trackByFn),e.xp6(5),e.Q6J("ngClass",e.VKq(5,_C,o.icons.add)))},directives:[Za.P,Mn.JL,Mn.sg,ll.V,_.O5,Mn.CE,_.sg,la.o,_.mk,ut._L,Mn.Fj,ja.b,Mn.JJ,Mn.u,Mn.EJ,Mn.YN,Mn.Kr,_.tP],pipes:[uC.f],styles:[""]}),n})();const mC=["nfsClients"];function xO(n,s){1&n&&(e.TgZ(0,"option",52),e.SDv(1,53),e.qZA())}function vC(n,s){1&n&&(e.TgZ(0,"option",52),e.SDv(1,54),e.qZA())}function DO(n,s){1&n&&(e.TgZ(0,"option",52),e.SDv(1,55),e.qZA())}function RO(n,s){if(1&n&&(e.TgZ(0,"option",56),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t.cluster_id),e.xp6(1),e.Oqu(t.cluster_id)}}const NO=function(){return["create"]},PO=function(n){return{modal:n}},IO=function(n){return{outlets:n}},LO=function(n){return["/services",n]};function FO(n,s){1&n&&(e.TgZ(0,"span",57),e.tHW(1,58),e._UZ(2,"a",59),e.N_p(),e.qZA()),2&n&&(e.xp6(2),e.Q6J("routerLink",e.VKq(6,LO,e.VKq(4,IO,e.VKq(2,PO,e.DdM(1,NO))))))}function kO(n,s){1&n&&(e.TgZ(0,"option",52),e.SDv(1,60),e.qZA())}function $O(n,s){1&n&&(e.TgZ(0,"option",52),e.SDv(1,61),e.qZA())}function HO(n,s){1&n&&(e.TgZ(0,"option",52),e.SDv(1,62),e.qZA())}function UO(n,s){if(1&n&&(e.TgZ(0,"option",63),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t.value)("disabled",t.disabled),e.xp6(1),e.Oqu(t.descr)}}function BO(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,64),e.qZA())}function YO(n,s){if(1&n&&(e.TgZ(0,"span",57),e.SDv(1,65),e.qZA()),2&n){const t=e.oxw(2);e.xp6(1),e.pQV(t.fsalAvailabilityError),e.QtT(1)}}function ZO(n,s){1&n&&(e.TgZ(0,"option",52),e.SDv(1,69),e.qZA())}function yC(n,s){1&n&&(e.TgZ(0,"option",52),e.SDv(1,70),e.qZA())}function bC(n,s){1&n&&(e.TgZ(0,"option",52),e.SDv(1,71),e.qZA())}function EC(n,s){if(1&n&&(e.TgZ(0,"option",56),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t.name),e.xp6(1),e.Oqu(t.name)}}function TC(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,72),e.qZA())}function SC(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",8),e.TgZ(1,"label",66),e.SDv(2,67),e.qZA(),e.TgZ(3,"div",13),e.TgZ(4,"select",68),e.NdJ("change",function(){return e.CHM(t),e.oxw(2).pathChangeHandler()}),e.YNc(5,ZO,2,0,"option",15),e.YNc(6,yC,2,0,"option",15),e.YNc(7,bC,2,0,"option",15),e.YNc(8,EC,2,2,"option",16),e.qZA(),e.YNc(9,TC,2,0,"span",17),e.qZA(),e.qZA()}if(2&n){e.oxw();const t=e.MAs(2),o=e.oxw();e.xp6(5),e.Q6J("ngIf",null===o.allFsNames),e.xp6(1),e.Q6J("ngIf",null!==o.allFsNames&&0===o.allFsNames.length),e.xp6(1),e.Q6J("ngIf",null!==o.allFsNames&&o.allFsNames.length>0),e.xp6(1),e.Q6J("ngForOf",o.allFsNames),e.xp6(1),e.Q6J("ngIf",o.nfsForm.showError("fs_name",t,"required"))}}function CC(n,s){1&n&&e._UZ(0,"input",79)}function MC(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,80),e.qZA())}const AC=function(n){return{required:n}};function OC(n,s){if(1&n&&(e.TgZ(0,"div",8),e.TgZ(1,"label",73),e.SDv(2,74),e.qZA(),e.TgZ(3,"div",13),e.TgZ(4,"div",26),e._UZ(5,"input",75),e.TgZ(6,"label",76),e.SDv(7,77),e.qZA(),e.qZA(),e._UZ(8,"br"),e.YNc(9,CC,1,0,"input",78),e.YNc(10,MC,2,0,"span",17),e.qZA(),e.qZA()),2&n){e.oxw();const t=e.MAs(2),o=e.oxw();e.xp6(1),e.Q6J("ngClass",e.VKq(3,AC,o.nfsForm.getValue("security_label"))),e.xp6(8),e.Q6J("ngIf",o.nfsForm.getValue("security_label")),e.xp6(1),e.Q6J("ngIf",o.nfsForm.showError("sec_label_xattr",t,"required"))}}function cE(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,85),e.qZA())}function dE(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,86),e.qZA())}function jm(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,87),e.qZA())}function jO(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",8),e.TgZ(1,"label",81),e.TgZ(2,"span",10),e.SDv(3,82),e.qZA(),e.TgZ(4,"cd-helper"),e.TgZ(5,"p"),e.SDv(6,83),e.qZA(),e.qZA(),e.qZA(),e.TgZ(7,"div",13),e.TgZ(8,"input",84),e.NdJ("selectItem",function(){return e.CHM(t),e.oxw(2).pathChangeHandler()})("blur",function(){return e.CHM(t),e.oxw(2).pathChangeHandler()}),e.qZA(),e.YNc(9,cE,2,0,"span",17),e.YNc(10,dE,2,0,"span",17),e.YNc(11,jm,2,0,"span",17),e.qZA(),e.qZA()}if(2&n){e.oxw();const t=e.MAs(2),o=e.oxw();e.xp6(8),e.Q6J("ngbTypeahead",o.pathDataSource),e.xp6(1),e.Q6J("ngIf",o.nfsForm.showError("path",t,"required")),e.xp6(1),e.Q6J("ngIf",o.nfsForm.showError("path",t,"pattern")),e.xp6(1),e.Q6J("ngIf",o.nfsForm.showError("path",t,"pathNameNotAllowed"))}}function GO(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,90),e.qZA())}function xv(n,s){1&n&&(e.TgZ(0,"span",57),e.tHW(1,91),e._UZ(2,"a",92),e.N_p(),e.qZA())}function bR(n,s){if(1&n&&(e.TgZ(0,"div",8),e.TgZ(1,"label",81),e.TgZ(2,"span",10),e.SDv(3,88),e.qZA(),e.qZA(),e.TgZ(4,"div",13),e._UZ(5,"input",89),e.YNc(6,GO,2,0,"span",17),e.YNc(7,xv,3,0,"span",17),e.qZA(),e.qZA()),2&n){e.oxw();const t=e.MAs(2),o=e.oxw();e.xp6(5),e.Q6J("ngbTypeahead",o.bucketDataSource),e.xp6(1),e.Q6J("ngIf",o.nfsForm.showError("path",t,"required")),e.xp6(1),e.Q6J("ngIf",o.nfsForm.showError("path",t,"bucketNameNotAllowed"))}}function fE(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,93),e.qZA())}function ER(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,99),e.qZA())}function wC(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,100),e.qZA())}function xC(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,101),e.qZA())}function TR(n,s){if(1&n&&(e.TgZ(0,"div",8),e.TgZ(1,"label",94),e.TgZ(2,"span",10),e.SDv(3,95),e.qZA(),e.TgZ(4,"cd-helper"),e.TgZ(5,"p"),e.tHW(6,96),e._UZ(7,"strong"),e._UZ(8,"strong"),e.N_p(),e.qZA(),e.TgZ(9,"p"),e.SDv(10,97),e.qZA(),e.qZA(),e.qZA(),e.TgZ(11,"div",13),e._UZ(12,"input",98),e.YNc(13,ER,2,0,"span",17),e.YNc(14,wC,2,0,"span",17),e.YNc(15,xC,2,0,"span",17),e.qZA(),e.qZA()),2&n){e.oxw();const t=e.MAs(2),o=e.oxw();e.xp6(13),e.Q6J("ngIf",o.nfsForm.showError("pseudo",t,"required")),e.xp6(1),e.Q6J("ngIf",o.nfsForm.showError("pseudo",t,"pseudoAlreadyExists")),e.xp6(1),e.Q6J("ngIf",o.nfsForm.showError("pseudo",t,"pattern"))}}function Ua(n,s){1&n&&(e.TgZ(0,"option",52),e.SDv(1,102),e.qZA())}function VO(n,s){1&n&&(e.TgZ(0,"option",52),e.SDv(1,103),e.qZA())}function zO(n,s){if(1&n&&(e.TgZ(0,"option",56),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t.value),e.xp6(1),e.Oqu(t.value)}}function WO(n,s){if(1&n&&(e.TgZ(0,"span",104),e._uU(1),e.qZA()),2&n){const t=e.oxw(2);e.xp6(1),e.hij(" ",t.getAccessTypeHelp(t.nfsForm.getValue("access_type"))," ")}}function my(n,s){1&n&&(e.TgZ(0,"span",105),e.tHW(1,106),e._UZ(2,"cd-doc",107),e.N_p(),e.qZA())}function JO(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,108),e.qZA())}function vy(n,s){1&n&&e.GkF(0)}function yy(n,s){1&n&&(e.TgZ(0,"option",52),e.SDv(1,109),e.qZA())}function Ad(n,s){1&n&&(e.TgZ(0,"option",52),e.SDv(1,110),e.qZA())}function SR(n,s){if(1&n&&(e.TgZ(0,"option",56),e._uU(1),e.qZA()),2&n){const t=s.$implicit;e.Q6J("value",t),e.xp6(1),e.Oqu(t)}}function DC(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,111),e.qZA())}function pE(n,s){1&n&&(e.TgZ(0,"span",57),e.SDv(1,112),e.qZA())}function QO(n,s){1&n&&(e.TgZ(0,"cd-helper"),e.TgZ(1,"ul",113),e.TgZ(2,"li"),e.TgZ(3,"span",114),e._uU(4,"no_root_squash: "),e.qZA(),e.TgZ(5,"span"),e.SDv(6,115),e.qZA(),e.qZA(),e.TgZ(7,"li"),e.TgZ(8,"span",114),e._uU(9,"root_id_squash: "),e.qZA(),e.TgZ(10,"span"),e.SDv(11,116),e.qZA(),e.qZA(),e.TgZ(12,"li"),e.TgZ(13,"span",114),e._uU(14,"root_squash: "),e.qZA(),e.TgZ(15,"span"),e.SDv(16,117),e.qZA(),e.qZA(),e.TgZ(17,"li"),e.TgZ(18,"span",114),e._uU(19,"all_squash: "),e.qZA(),e.TgZ(20,"span"),e.SDv(21,118),e.qZA(),e.qZA(),e.qZA(),e.qZA())}function RC(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",1),e.TgZ(1,"form",2,3),e.TgZ(3,"div",4),e.TgZ(4,"div",5),e.SDv(5,6),e.ALo(6,"titlecase"),e.ALo(7,"upperFirst"),e.qZA(),e.TgZ(8,"div",7),e.TgZ(9,"div",8),e.TgZ(10,"label",9),e.TgZ(11,"span",10),e.SDv(12,11),e.qZA(),e.TgZ(13,"cd-helper"),e.TgZ(14,"p"),e.SDv(15,12),e.qZA(),e.qZA(),e.qZA(),e.TgZ(16,"div",13),e.TgZ(17,"select",14),e.YNc(18,xO,2,0,"option",15),e.YNc(19,vC,2,0,"option",15),e.YNc(20,DO,2,0,"option",15),e.YNc(21,RO,2,2,"option",16),e.qZA(),e.YNc(22,FO,3,8,"span",17),e.qZA(),e.qZA(),e.TgZ(23,"div",18),e.TgZ(24,"div",8),e.TgZ(25,"label",19),e.SDv(26,20),e.qZA(),e.TgZ(27,"div",13),e.TgZ(28,"select",21),e.NdJ("change",function(){return e.CHM(t),e.oxw().fsalChangeHandler()}),e.YNc(29,kO,2,0,"option",15),e.YNc(30,$O,2,0,"option",15),e.YNc(31,HO,2,0,"option",15),e.YNc(32,UO,2,3,"option",22),e.qZA(),e.YNc(33,BO,2,0,"span",17),e.YNc(34,YO,2,1,"span",17),e.qZA(),e.qZA(),e.YNc(35,SC,10,5,"div",23),e.qZA(),e.YNc(36,OC,11,5,"div",23),e.YNc(37,jO,12,4,"div",23),e.YNc(38,bR,8,3,"div",23),e.TgZ(39,"div",8),e.TgZ(40,"label",24),e.SDv(41,25),e.qZA(),e.TgZ(42,"div",13),e.TgZ(43,"div",26),e._UZ(44,"input",27),e.TgZ(45,"label",28),e.SDv(46,29),e.qZA(),e.qZA(),e.YNc(47,fE,2,0,"span",17),e.qZA(),e.qZA(),e.YNc(48,TR,16,3,"div",23),e.TgZ(49,"div",8),e.TgZ(50,"label",30),e.SDv(51,31),e.qZA(),e.TgZ(52,"div",13),e.TgZ(53,"select",32),e.NdJ("change",function(){return e.CHM(t),e.oxw().accessTypeChangeHandler()}),e.YNc(54,Ua,2,0,"option",15),e.YNc(55,VO,2,0,"option",15),e.YNc(56,zO,2,2,"option",16),e.qZA(),e.YNc(57,WO,2,1,"span",33),e.YNc(58,my,3,0,"span",34),e.YNc(59,JO,2,0,"span",17),e.qZA(),e.qZA(),e.TgZ(60,"div",8),e.TgZ(61,"label",35),e.TgZ(62,"span"),e.SDv(63,36),e.qZA(),e.YNc(64,vy,1,0,"ng-container",37),e.qZA(),e.TgZ(65,"div",13),e.TgZ(66,"select",38),e.YNc(67,yy,2,0,"option",15),e.YNc(68,Ad,2,0,"option",15),e.YNc(69,SR,2,2,"option",16),e.qZA(),e.YNc(70,DC,2,0,"span",17),e.qZA(),e.qZA(),e.TgZ(71,"div",8),e.TgZ(72,"label",39),e.SDv(73,40),e.qZA(),e.TgZ(74,"div",13),e.TgZ(75,"div",26),e._UZ(76,"input",41),e.TgZ(77,"label",42),e.SDv(78,43),e.qZA(),e.qZA(),e.TgZ(79,"div",26),e._UZ(80,"input",44),e.TgZ(81,"label",45),e.SDv(82,46),e.qZA(),e.qZA(),e.YNc(83,pE,2,0,"span",17),e._UZ(84,"hr"),e.qZA(),e.qZA(),e.TgZ(85,"cd-nfs-form-client",47,48),e.YNc(87,QO,22,0,"ng-template",null,49,e.W1O),e.qZA(),e.qZA(),e.TgZ(89,"div",50),e.TgZ(90,"cd-form-button-panel",51),e.NdJ("submitActionEvent",function(){return e.CHM(t),e.oxw().submitAction()}),e.ALo(91,"titlecase"),e.ALo(92,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=e.MAs(2),o=e.MAs(88),c=e.oxw();e.xp6(1),e.Q6J("formGroup",c.nfsForm),e.xp6(6),e.pQV(e.lcZ(6,36,c.action))(e.lcZ(7,38,c.resource)),e.QtT(5),e.xp6(11),e.Q6J("ngIf",null===c.allClusters),e.xp6(1),e.Q6J("ngIf",null!==c.allClusters&&0===c.allClusters.length),e.xp6(1),e.Q6J("ngIf",null!==c.allClusters&&c.allClusters.length>0),e.xp6(1),e.Q6J("ngForOf",c.allClusters),e.xp6(1),e.Q6J("ngIf",c.nfsForm.showError("cluster_id",t,"required")||0===(null==c.allClusters?null:c.allClusters.length)),e.xp6(7),e.Q6J("ngIf",null===c.allFsals),e.xp6(1),e.Q6J("ngIf",null!==c.allFsals&&0===c.allFsals.length),e.xp6(1),e.Q6J("ngIf",null!==c.allFsals&&c.allFsals.length>0),e.xp6(1),e.Q6J("ngForOf",c.allFsals),e.xp6(1),e.Q6J("ngIf",c.nfsForm.showError("name",t,"required")),e.xp6(1),e.Q6J("ngIf",c.fsalAvailabilityError),e.xp6(1),e.Q6J("ngIf","CEPH"===c.nfsForm.getValue("name")),e.xp6(1),e.Q6J("ngIf","CEPH"===c.nfsForm.getValue("name")),e.xp6(1),e.Q6J("ngIf","CEPH"===c.nfsForm.getValue("name")),e.xp6(1),e.Q6J("ngIf","RGW"===c.nfsForm.getValue("name")),e.xp6(9),e.Q6J("ngIf",c.nfsForm.showError("protocolNfsv4",t,"required")),e.xp6(1),e.Q6J("ngIf",c.nfsForm.getValue("protocolNfsv4")),e.xp6(6),e.Q6J("ngIf",null===c.nfsAccessType),e.xp6(1),e.Q6J("ngIf",null!==c.nfsAccessType&&0===c.nfsAccessType.length),e.xp6(1),e.Q6J("ngForOf",c.nfsAccessType),e.xp6(1),e.Q6J("ngIf",c.nfsForm.getValue("access_type")),e.xp6(1),e.Q6J("ngIf","RW"===c.nfsForm.getValue("access_type")&&"RGW"===c.nfsForm.getValue("name")),e.xp6(1),e.Q6J("ngIf",c.nfsForm.showError("access_type",t,"required")),e.xp6(5),e.Q6J("ngTemplateOutlet",o),e.xp6(3),e.Q6J("ngIf",null===c.nfsSquash),e.xp6(1),e.Q6J("ngIf",null!==c.nfsSquash&&0===c.nfsSquash.length),e.xp6(1),e.Q6J("ngForOf",c.nfsSquash),e.xp6(1),e.Q6J("ngIf",c.nfsForm.showError("squash",t,"required")),e.xp6(13),e.Q6J("ngIf",c.nfsForm.showError("transportUDP",t,"required")||c.nfsForm.showError("transportTCP",t,"required")),e.xp6(2),e.Q6J("form",c.nfsForm)("clients",c.clients),e.xp6(5),e.Q6J("form",c.nfsForm)("submitText",e.lcZ(91,40,c.action)+" "+e.lcZ(92,42,c.resource))}}let hE=(()=>{class n extends Oa.E{constructor(t,o,c,g,C,D,P,j,W,re){super(),this.authStorageService=t,this.nfsService=o,this.route=c,this.router=g,this.rgwBucketService=C,this.rgwSiteService=D,this.formBuilder=P,this.taskWrapper=j,this.cdRef=W,this.actionLabels=re,this.clients=[],this.isEdit=!1,this.cluster_id=null,this.export_id=null,this.allClusters=null,this.icons=xo.P,this.allFsals=[],this.allFsNames=null,this.fsalAvailabilityError=null,this.defaultAccessType={RGW:"RO"},this.nfsAccessType=this.nfsService.nfsAccessType,this.nfsSquash=Object.keys(this.nfsService.nfsSquash),this.pathDataSource=oe=>oe.pipe(zf(200),(0,Df.x)(),(0,Bu.zg)(me=>this.getPathTypeahead(me)),(0,hu.U)(me=>me)),this.bucketDataSource=oe=>oe.pipe(zf(200),(0,Df.x)(),(0,Bu.zg)(me=>this.getBucketTypeahead(me))),this.permission=this.authStorageService.getPermissions().pool,this.resource="NFS export",this.createForm()}ngOnInit(){const t=[this.nfsService.listClusters(),this.nfsService.fsals(),this.nfsService.filesystems()];this.router.url.startsWith("/nfs/edit")&&(this.isEdit=!0),this.isEdit?(this.action=this.actionLabels.EDIT,this.route.params.subscribe(o=>{this.cluster_id=decodeURIComponent(o.cluster_id),this.export_id=decodeURIComponent(o.export_id),t.push(this.nfsService.get(this.cluster_id,this.export_id)),this.getData(t)}),this.nfsForm.get("cluster_id").disable()):(this.action=this.actionLabels.CREATE,this.getData(t))}getData(t){(0,xc.D)(t).subscribe(o=>{this.resolveClusters(o[0]),this.resolveFsals(o[1]),this.resolveFilesystems(o[2]),o[3]&&this.resolveModel(o[3]),this.loadingReady()})}createForm(){this.nfsForm=new Hs.d({cluster_id:new Mn.NI("",{validators:[Mn.kI.required]}),fsal:new Hs.d({name:new Mn.NI("",{validators:[Mn.kI.required]}),fs_name:new Mn.NI("",{validators:[ss.h.requiredIf({name:"CEPH"})]})}),path:new Mn.NI("/"),protocolNfsv4:new Mn.NI(!0),pseudo:new Mn.NI("",{validators:[ss.h.requiredIf({protocolNfsv4:!0}),Mn.kI.pattern("^/[^><|&()]*$")]}),access_type:new Mn.NI("RW"),squash:new Mn.NI(this.nfsSquash[0]),transportUDP:new Mn.NI(!0,{validators:[ss.h.requiredIf({transportTCP:!1},t=>!t)]}),transportTCP:new Mn.NI(!0,{validators:[ss.h.requiredIf({transportUDP:!1},t=>!t)]}),clients:this.formBuilder.array([]),security_label:new Mn.NI(!1),sec_label_xattr:new Mn.NI("security.selinux",ss.h.requiredIf({security_label:!0,"fsal.name":"CEPH"}))})}resolveModel(t){"CEPH"===t.fsal.name&&(t.sec_label_xattr=t.fsal.sec_label_xattr),t.protocolNfsv4=-1!==t.protocols.indexOf(4),delete t.protocols,t.transportTCP=-1!==t.transports.indexOf("TCP"),t.transportUDP=-1!==t.transports.indexOf("UDP"),delete t.transports,Object.entries(this.nfsService.nfsSquash).forEach(([o,c])=>{c.includes(t.squash)&&(t.squash=o)}),t.clients.forEach(o=>{let c="";o.addresses.forEach(g=>{c+=g+", "}),c.length>=2&&(c=c.substring(0,c.length-2)),o.addresses=c}),this.nfsForm.patchValue(t),this.setPathValidation(),this.clients=t.clients}resolveClusters(t){this.allClusters=[];for(const o of t)this.allClusters.push({cluster_id:o});!this.isEdit&&this.allClusters.length>0&&this.nfsForm.get("cluster_id").setValue(this.allClusters[0].cluster_id)}resolveFsals(t){t.forEach(o=>{const c=this.nfsService.nfsFsal.find(g=>o===g.value);wr().isObjectLike(c)&&this.allFsals.push(c)}),!this.isEdit&&this.allFsals.length>0&&this.nfsForm.patchValue({fsal:{name:this.allFsals[0].value}})}resolveFilesystems(t){this.allFsNames=t,!this.isEdit&&t.length>0&&this.nfsForm.patchValue({fsal:{fs_name:t[0].name}})}fsalChangeHandler(){this.setPathValidation();const t=this.nfsForm.getValue("name");("RGW"===t?this.rgwSiteService.get("realms").pipe((0,Bu.zg)(c=>0===c.length?(0,Vc.of)(!0):this.rgwSiteService.isDefaultRealm().pipe((0,Bu.zg)(g=>{if(!g)throw new Error("Selected realm is not the default.");return(0,Vc.of)(!0)})))):this.nfsService.filesystems()).subscribe({next:()=>{this.setFsalAvailability(t,!0),this.isEdit||this.nfsForm.patchValue({path:"RGW"===t?"":"/",pseudo:this.generatePseudo(),access_type:this.updateAccessType()}),this.cdRef.detectChanges()},error:c=>{this.setFsalAvailability(t,!1,c),this.nfsForm.get("name").setValue("")}})}setFsalAvailability(t,o,c=""){this.allFsals=this.allFsals.map(g=>(g.value===t&&(g.disabled=!o,this.fsalAvailabilityError=g.disabled?"" + g.descr + " backend is not available. " + c + "":null),g))}accessTypeChangeHandler(){const t=this.nfsForm.getValue("name"),o=this.nfsForm.getValue("access_type");this.defaultAccessType[t]=o}setPathValidation(){const t=this.nfsForm.get("path");t.setValidators([Mn.kI.required]),"RGW"===this.nfsForm.getValue("name")?t.setAsyncValidators([ss.h.bucketExistence(!0,this.rgwBucketService)]):t.setAsyncValidators([this.pathExistence(!0)]),this.isEdit&&t.markAsDirty()}getAccessTypeHelp(t){const o=this.nfsAccessType.find(c=>{if(t===c.value)return c});return wr().isObjectLike(o)?o.help:""}getId(){return wr().isString(this.nfsForm.getValue("cluster_id"))&&wr().isString(this.nfsForm.getValue("path"))?this.nfsForm.getValue("cluster_id")+":"+this.nfsForm.getValue("path"):""}getPathTypeahead(t){if(!wr().isString(t)||"/"===t)return(0,Vc.of)([]);const o=this.nfsForm.getValue("fsal").fs_name;return this.nfsService.lsDir(o,t).pipe((0,hu.U)(c=>c.paths.filter(g=>g.toLowerCase().includes(t)).slice(0,15)),(0,wv.K)(()=>(0,Vc.of)(["Error while retrieving paths."])))}pathChangeHandler(){this.isEdit||this.nfsForm.patchValue({pseudo:this.generatePseudo()})}getBucketTypeahead(t){return wr().isString(t)&&"/"!==t&&""!==t?this.rgwBucketService.list().pipe((0,hu.U)(o=>o.filter(c=>c.toLowerCase().includes(t)).slice(0,15)),(0,wv.K)(()=>(0,Vc.of)(["Error while retrieving bucket names."]))):(0,Vc.of)([])}generatePseudo(){let t=this.nfsForm.getValue("pseudo");return this.nfsForm.get("pseudo")&&!this.nfsForm.get("pseudo").dirty&&(t=void 0,"CEPH"===this.nfsForm.getValue("fsal")&&(t="/cephfs",wr().isString(this.nfsForm.getValue("path"))&&(t+=this.nfsForm.getValue("path")))),t}updateAccessType(){const t=this.nfsForm.getValue("name");let o=this.defaultAccessType[t];return o||(o="RW"),o}submitAction(){let t;const o=this.buildRequest();t=this.taskWrapper.wrapTaskAroundCall(this.isEdit?{task:new cl.R("nfs/edit",{cluster_id:this.cluster_id,export_id:wr().parseInt(this.export_id)}),call:this.nfsService.update(this.cluster_id,wr().parseInt(this.export_id),o)}:{task:new cl.R("nfs/create",{path:o.path,fsal:o.fsal,cluster_id:o.cluster_id}),call:this.nfsService.create(o)}),t.subscribe({error:c=>this.setFormErrors(c),complete:()=>this.router.navigate(["/nfs"])})}setFormErrors(t){t.error.detail&&t.error.detail.toString().includes(`Pseudo ${this.nfsForm.getValue("pseudo")} is already in use`)&&this.nfsForm.get("pseudo").setErrors({pseudoAlreadyExists:!0}),this.nfsForm.setErrors({cdSubmitButton:!0})}buildRequest(){const t=wr().cloneDeep(this.nfsForm.value);return this.isEdit&&(t.export_id=wr().parseInt(this.export_id)),"RGW"===t.fsal.name&&delete t.fsal.fs_name,t.protocols=[],t.protocolNfsv4?t.protocols.push(4):t.pseudo=null,delete t.protocolNfsv4,t.transports=[],t.transportTCP&&t.transports.push("TCP"),delete t.transportTCP,t.transportUDP&&t.transports.push("UDP"),delete t.transportUDP,t.clients.forEach(o=>{o.addresses=wr().isString(o.addresses)?wr()(o.addresses).split(/[ ,]+/).uniq().filter(c=>""!==c).value():[],o.squash||(o.squash=t.squash),o.access_type||(o.access_type=t.access_type)}),t.fsal.sec_label_xattr=!1===t.security_label||"RGW"===t.fsal.name?null:t.sec_label_xattr,delete t.sec_label_xattr,t}pathExistence(t){return o=>{if(o.pristine||!o.value)return(0,Vc.of)({required:!0});const c=this.nfsForm.getValue("fsal").fs_name;return this.nfsService.lsDir(c,o.value).pipe((0,hu.U)(g=>g.paths.includes(o.value)===t?null:{pathNameNotAllowed:!0}),(0,wv.K)(()=>(0,Vc.of)({pathNameNotAllowed:!0})))}}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(vt.j),e.Y36(_y),e.Y36(Bo.gz),e.Y36(Bo.F0),e.Y36(aC.o),e.Y36(hy.I),e.Y36(rd.O),e.Y36(Ll.P),e.Y36(e.sBO),e.Y36($i.p4))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-nfs-form"]],viewQuery:function(t,o){if(1&t&&e.Gf(mC,7),2&t){let c;e.iGM(c=e.CRH())&&(o.nfsClients=c.first)}},features:[e.qOj],decls:1,vars:1,consts:function(){let s,t,o,c,g,C,D,P,j,W,re,oe,me,_e,Fe,Re,Le,we,U,pt,ht,Dt,Ft,cn,kt,wn,Tn,Hr,sr,Nr,xr,fn,Rn,kn,Wn,bn,jr,ji,oi,Ui,Xr,Sn,hn,_r,Fi,_s,Ho,yo,Us,zs,Di,oo,ho,Ze,Mt;return s="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",t="Cluster",o="This is the ID of an NFS Service.",c="Storage Backend",g="NFS Protocol",C="NFSv4",D="Access Type",P="Squash",j="Transport Protocol",W="UDP",re="TCP",oe="Loading...",me="-- No cluster available --",_e="-- Select the cluster --",Fe="This field is required. To create a new NFS cluster, " + "\ufffd#2\ufffd" + "add a new NFS Service" + "\ufffd/#2\ufffd" + ".",Re="Loading...",Le="-- No data pools available --",we="-- Select the storage backend --",U="This field is required.",pt="" + "\ufffd0\ufffd" + "",ht="Volume",Dt="Loading...",Ft="-- No CephFS filesystem available --",cn="-- Select the CephFS filesystem --",kt="This field is required.",wn="Security Label",Tn="Enable security label",Hr="This field is required.",sr="CephFS Path",Nr="A path in a CephFS file system.",xr="This field is required.",fn="Path need to start with a '/' and can be followed by a word",Rn="The path does not exist in the selected volume.",kn="Bucket",Wn="This field is required.",bn="The bucket does not exist or is not in the default realm (if multiple realms are configured). To continue, " + "\ufffd#2\ufffd" + "create a new bucket" + "\ufffd/#2\ufffd" + ".",jr="This field is required.",ji="Pseudo",oi="The position that this " + "[\ufffd#7\ufffd|\ufffd#8\ufffd]" + "NFS v4" + "[\ufffd/#7\ufffd|\ufffd/#8\ufffd]" + " export occupies in the " + "[\ufffd#7\ufffd|\ufffd#8\ufffd]" + "Pseudo FS" + "[\ufffd/#7\ufffd|\ufffd/#8\ufffd]" + " (it must be unique).",oi=e.Zx4(oi),Ui="By using different Pseudo options, the same Path may be exported multiple times.",Xr="This field is required.",Sn="The pseudo is already in use by another export.",hn="Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ).",_r="Loading...",Fi="-- No access type available --",_s="The Object Gateway NFS backend has a number of limitations which will seriously affect applications writing to the share. Please consult the " + "\ufffd#2\ufffd" + "" + "\ufffd/#2\ufffd" + " for details before enabling write access.",Ho="This field is required.",yo="Loading...",Us="-- No squash available --",zs="This field is required.",Di="This field is required.",oo="No user id squashing is performed.",ho="uid 0 and gid 0 are squashed to the Anonymous_Uid and Anonymous_Gid gid 0 in alt_groups lists is also squashed.",Ze="uid 0 and gid of any value are squashed to the Anonymous_Uid and Anonymous_Gid alt_groups lists is discarded.",Mt="All users are squashed.",[["class","cd-col-form",4,"cdFormLoading"],[1,"cd-col-form"],["name","nfsForm","novalidate","",3,"formGroup"],["formDir","ngForm"],[1,"card"],[1,"card-header"],s,[1,"card-body"],[1,"form-group","row"],["for","cluster_id",1,"cd-col-form-label"],[1,"required"],t,o,[1,"cd-col-form-input"],["formControlName","cluster_id","name","cluster_id","id","cluster_id",1,"form-control"],["value","",4,"ngIf"],[3,"value",4,"ngFor","ngForOf"],["class","invalid-feedback",4,"ngIf"],["formGroupName","fsal"],["for","name",1,"cd-col-form-label","required"],c,["formControlName","name","name","name","id","name",1,"form-control",3,"change"],[3,"value","disabled",4,"ngFor","ngForOf"],["class","form-group row",4,"ngIf"],["for","protocols",1,"cd-col-form-label","required"],g,[1,"custom-control","custom-checkbox"],["type","checkbox","formControlName","protocolNfsv4","name","protocolNfsv4","id","protocolNfsv4","disabled","",1,"custom-control-input"],["for","protocolNfsv4",1,"custom-control-label"],C,["for","access_type",1,"cd-col-form-label","required"],D,["formControlName","access_type","name","access_type","id","access_type",1,"form-control",3,"change"],["class","form-text text-muted",4,"ngIf"],["class","form-text text-warning",4,"ngIf"],["for","squash",1,"cd-col-form-label"],P,[4,"ngTemplateOutlet"],["name","squash","formControlName","squash","id","squash",1,"form-control"],["for","transports",1,"cd-col-form-label","required"],j,["type","checkbox","formControlName","transportUDP","name","transportUDP","id","transportUDP",1,"custom-control-input"],["for","transportUDP",1,"custom-control-label"],W,["type","checkbox","formControlName","transportTCP","name","transportTCP","id","transportTCP",1,"custom-control-input"],["for","transportTCP",1,"custom-control-label"],re,[3,"form","clients"],["nfsClients",""],["squashHelper",""],[1,"card-footer"],["wrappingClass","text-right",3,"form","submitText","submitActionEvent"],["value",""],oe,me,_e,[3,"value"],[1,"invalid-feedback"],Fe,[1,"btn-link",3,"routerLink"],Re,Le,we,[3,"value","disabled"],U,pt,["for","fs_name",1,"cd-col-form-label","required"],ht,["formControlName","fs_name","name","fs_name","id","fs_name",1,"form-control",3,"change"],Dt,Ft,cn,kt,["for","security_label",1,"cd-col-form-label",3,"ngClass"],wn,["type","checkbox","formControlName","security_label","name","security_label","id","security_label",1,"custom-control-input"],["for","security_label",1,"custom-control-label"],Tn,["type","text","class","form-control","name","sec_label_xattr","id","sec_label_xattr","formControlName","sec_label_xattr",4,"ngIf"],["type","text","name","sec_label_xattr","id","sec_label_xattr","formControlName","sec_label_xattr",1,"form-control"],Hr,["for","path",1,"cd-col-form-label"],sr,Nr,["type","text","name","path","id","path","data-testid","fs_path","formControlName","path",1,"form-control",3,"ngbTypeahead","selectItem","blur"],xr,fn,Rn,kn,["type","text","name","path","id","path","data-testid","rgw_path","formControlName","path",1,"form-control",3,"ngbTypeahead"],Wn,bn,["routerLink","/rgw/bucket/create",1,"btn-link"],jr,["for","pseudo",1,"cd-col-form-label"],ji,oi,Ui,["type","text","name","pseudo","id","pseudo","formControlName","pseudo",1,"form-control"],Xr,Sn,hn,_r,Fi,[1,"form-text","text-muted"],[1,"form-text","text-warning"],_s,["section","rgw-nfs"],Ho,yo,Us,zs,Di,[1,"squash-helper"],[1,"squash-helper-item-value"],oo,ho,Ze,Mt]},template:function(t,o){1&t&&e.YNc(0,RC,93,44,"div",0),2&t&&e.Q6J("cdFormLoading",o.loading)},directives:[Ol.y,Mn._Y,Mn.JL,Mn.sg,ll.V,Za.P,h.S,la.o,Mn.EJ,ja.b,Mn.JJ,Mn.u,_.O5,_.sg,Mn.x0,Mn.Wl,_.tP,gC,ul.p,Mn.YN,Mn.Kr,Bo.yS,_.mk,Mn.Fj,ut.dR,il.K],pipes:[_.rS,F.m],styles:[".cd-mb[_ngcontent-%COMP%]{margin-bottom:10px}.squash-helper[_ngcontent-%COMP%]{padding-left:1rem}.squash-helper-item-value[_ngcontent-%COMP%]{font-weight:bold}"]}),n})();var _E=i(38047);function NC(n,s){if(1&n&&e._UZ(0,"cd-table-key-value",10),2&n){const t=e.oxw(2);e.Q6J("data",t.data)}}function XO(n,s){if(1&n&&e._UZ(0,"cd-table",11,12),2&n){const t=e.oxw(2);e.Q6J("data",t.clients)("columns",t.clientsColumns)}}function KO(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"ul",1,2),e.TgZ(3,"li",3),e.TgZ(4,"a",4),e.SDv(5,5),e.qZA(),e.YNc(6,NC,1,1,"ng-template",6),e.qZA(),e.TgZ(7,"li",7),e.TgZ(8,"a",4),e.SDv(9,8),e.qZA(),e.YNc(10,XO,2,2,"ng-template",6),e.qZA(),e.qZA(),e._UZ(11,"div",9),e.BQk()),2&n){const t=e.MAs(2),o=e.oxw();e.xp6(9),e.pQV(o.clients.length),e.QtT(9),e.xp6(2),e.Q6J("ngbNavOutlet",t)}}let qO=(()=>{class n{constructor(){this.clients=[],this.clientsColumns=[{name:"Addresses",prop:"addresses",flexGrow:2},{name:"Access Type",prop:"access_type",flexGrow:1},{name:"Squash",prop:"squash",flexGrow:1}]}ngOnChanges(){this.selection&&(this.selectedItem=this.selection,this.clients=this.selectedItem.clients,this.data={},this.data["Cluster"]=this.selectedItem.cluster_id,this.data["NFS Protocol"]=this.selectedItem.protocols.map(t=>"NFSv"+t),this.data["Pseudo"]=this.selectedItem.pseudo,this.data["Access Type"]=this.selectedItem.access_type,this.data["Squash"]=this.selectedItem.squash,this.data["Transport"]=this.selectedItem.transports,this.data["Path"]=this.selectedItem.path,"CEPH"===this.selectedItem.fsal.name?(this.data["Storage Backend"]="CephFS",this.data["CephFS User"]=this.selectedItem.fsal.user_id,this.data["CephFS Filesystem"]=this.selectedItem.fsal.fs_name,this.data["Security Label"]=this.selectedItem.fsal.sec_label_xattr):(this.data["Storage Backend"]="Object Gateway",this.data["Object Gateway User"]=this.selectedItem.fsal.user_id))}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-nfs-details"]],inputs:{selection:"selection"},features:[e.TTD],decls:1,vars:1,consts:function(){let s,t;return s="Details",t="Clients (" + "\ufffd0\ufffd" + ")",[[4,"ngIf"],["ngbNav","","cdStatefulTab","nfs-details",1,"nav-tabs"],["nav","ngbNav"],["ngbNavItem","details"],["ngbNavLink",""],s,["ngbNavContent",""],["ngbNavItem","clients"],t,[3,"ngbNavOutlet"],[3,"data"],["columnMode","flex","identifier","addresses","forceIdentifier","true","selectionType","",3,"data","columns"],["table",""]]},template:function(t,o){1&t&&e.YNc(0,KO,12,2,"ng-container",0),2&t&&e.Q6J("ngIf",o.selection)},directives:[_.O5,ut.Pz,un.m,ut.nv,ut.Vx,ut.uN,ut.tO,zr.b,ks.a],styles:[""]}),n})();const N1=["nfsState"],ew=["nfsFsal"],tw=["table"];function nw(n,s){1&n&&(e.ynx(0),e.SDv(1,7),e.BQk())}function by(n,s){1&n&&(e.ynx(0),e.SDv(1,8),e.BQk())}function PC(n,s){if(1&n&&(e.YNc(0,nw,2,0,"ng-container",6),e.YNc(1,by,2,0,"ng-container",6)),2&n){const t=s.value;e.Q6J("ngIf","CEPH"===t.name),e.xp6(1),e.Q6J("ngIf","RGW"===t.name)}}let IC=(()=>{class n extends jl.o{constructor(t,o,c,g,C,D){super(),this.authStorageService=t,this.modalService=o,this.nfsService=c,this.taskListService=g,this.taskWrapper=C,this.actionLabels=D,this.selection=new El.r,this.isDefaultCluster=!1,this.builders={"nfs/create":oe=>({path:oe.path,cluster_id:oe.cluster_id,fsal:oe.fsal})},this.permission=this.authStorageService.getPermissions().nfs;const P=()=>this.selection.first()&&`${encodeURI(this.selection.first().cluster_id)}/${encodeURI(this.selection.first().export_id)}`;this.tableActions=[{permission:"create",icon:xo.P.add,routerLink:()=>"/nfs/create",canBePrimary:oe=>!oe.hasSingleSelection,name:this.actionLabels.CREATE},{permission:"update",icon:xo.P.edit,routerLink:()=>`/nfs/edit/${P()}`,name:this.actionLabels.EDIT},{permission:"delete",icon:xo.P.destroy,click:()=>this.deleteNfsModal(),name:this.actionLabels.DELETE}]}ngOnInit(){this.columns=[{name:"Path",prop:"path",flexGrow:2,cellTransformation:bl.e.executing},{name:"Pseudo",prop:"pseudo",flexGrow:2},{name:"Cluster",prop:"cluster_id",flexGrow:2},{name:"Storage Backend",prop:"fsal",flexGrow:2,cellTemplate:this.nfsFsal},{name:"Access Type",prop:"access_type",flexGrow:2}],this.taskListService.init(()=>this.nfsService.list(),t=>this.prepareResponse(t),t=>this.exports=t,()=>this.onFetchError(),this.taskFilter,this.itemFilter,this.builders)}ngOnDestroy(){this.summaryDataSubscription&&this.summaryDataSubscription.unsubscribe()}prepareResponse(t){let o=[];return t.forEach(c=>{c.id=`${c.cluster_id}:${c.export_id}`,c.state="LOADING",o=o.concat(c)}),o}onFetchError(){this.table.reset(),this.viewCacheStatus={status:st.T.ValueException}}itemFilter(t,o){return t.cluster_id===o.metadata.cluster_id&&t.export_id===o.metadata.export_id}taskFilter(t){return["nfs/create","nfs/delete","nfs/edit"].includes(t.name)}updateSelection(t){this.selection=t}deleteNfsModal(){const t=this.selection.first().cluster_id,o=this.selection.first().export_id;this.modalRef=this.modalService.show(Gl.M,{itemDescription:"NFS export",itemNames:[`${t}:${o}`],submitActionObservable:()=>this.taskWrapper.wrapTaskAroundCall({task:new cl.R("nfs/delete",{cluster_id:t,export_id:o}),call:this.nfsService.delete(t,o)})})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(vt.j),e.Y36(Bl.Z),e.Y36(_y),e.Y36(_E.j),e.Y36(Ll.P),e.Y36($i.p4))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-nfs-list"]],viewQuery:function(t,o){if(1&t&&(e.Gf(N1,5),e.Gf(ew,7),e.Gf(tw,7)),2&t){let c;e.iGM(c=e.CRH())&&(o.nfsState=c.first),e.iGM(c=e.CRH())&&(o.nfsFsal=c.first),e.iGM(c=e.CRH())&&(o.table=c.first)}},features:[e._Bn([_E.j]),e.qOj],decls:7,vars:7,consts:function(){let s,t;return s="CephFS",t="Object Gateway",[["columnMode","flex","identifier","id","forceIdentifier","true","selectionType","single",3,"data","columns","hasDetails","setExpandedRow","updateSelection"],["table",""],[1,"table-actions","btn-toolbar"],[1,"btn-group",3,"permission","selection","tableActions"],["cdTableDetail","",3,"selection"],["nfsFsal",""],[4,"ngIf"],s,t]},template:function(t,o){1&t&&(e.TgZ(0,"cd-table",0,1),e.NdJ("setExpandedRow",function(g){return o.setExpandedRow(g)})("updateSelection",function(g){return o.updateSelection(g)}),e.TgZ(2,"div",2),e._UZ(3,"cd-table-actions",3),e.qZA(),e._UZ(4,"cd-nfs-details",4),e.qZA(),e.YNc(5,PC,2,2,"ng-template",null,5,e.W1O)),2&t&&(e.Q6J("data",o.exports)("columns",o.columns)("hasDetails",!0),e.xp6(3),e.Q6J("permission",o.permission)("selection",o.selection)("tableActions",o.tableActions),e.xp6(1),e.Q6J("selection",o.expandedRow))},directives:[ks.a,Js.K,qO,_.O5],styles:[""]}),n})(),LC=(()=>{class n{constructor(t){this.route=t,this.route.queryParams.subscribe(o=>{this.fromLink=o.fromLink||n.defaultFromLink}),this.route.params.subscribe(o=>{this.serviceId=decodeURIComponent(o.id),this.serviceType=o.type})}}return n.defaultFromLink="/hosts",n.\u0275fac=function(t){return new(t||n)(e.Y36(Bo.gz))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-performance-counter"]],decls:3,vars:4,consts:[[3,"serviceType","serviceId"]],template:function(t,o){1&t&&(e.TgZ(0,"legend"),e._uU(1),e.qZA(),e._UZ(2,"cd-table-performance-counter",0)),2&t&&(e.xp6(1),e.AsE("",o.serviceType,".",o.serviceId,""),e.xp6(1),e.Q6J("serviceType",o.serviceType)("serviceId",o.serviceId))},directives:[ny.p],styles:[""]}),n})();var gE=i(39219),Dv=i(33888),Gm=i(32057);function rw(n,s){1&n&&(e.TgZ(0,"span",30),e.SDv(1,31),e.qZA())}function iw(n,s){1&n&&(e.TgZ(0,"span",30),e.SDv(1,32),e.qZA())}function ow(n,s){if(1&n&&e._UZ(0,"cd-helper",33),2&n){const t=e.oxw();e.s9C("html",t.passwordPolicyHelpText)}}function FC(n,s){1&n&&(e.TgZ(0,"span",30),e.SDv(1,34),e.qZA())}function kC(n,s){1&n&&(e.TgZ(0,"span",30),e.SDv(1,35),e.qZA())}function $C(n,s){if(1&n&&(e.TgZ(0,"span",30),e._uU(1),e.qZA()),2&n){const t=e.oxw();e.xp6(1),e.hij(" ",t.passwordValuation," ")}}function sw(n,s){1&n&&(e.TgZ(0,"span",30),e.SDv(1,36),e.qZA())}function HC(n,s){1&n&&(e.TgZ(0,"span",30),e.SDv(1,37),e.qZA())}let UC=(()=>{class n{constructor(t,o,c,g,C,D,P){this.actionLabels=t,this.notificationService=o,this.userService=c,this.authStorageService=g,this.formBuilder=C,this.router=D,this.passwordPolicyService=P,this.passwordPolicyHelpText="",this.icons=xo.P,this.action=this.actionLabels.CHANGE,this.resource="password",this.createForm()}createForm(){this.passwordPolicyService.getHelpText().subscribe(t=>{this.passwordPolicyHelpText=t}),this.userForm=this.formBuilder.group({oldpassword:[null,[Mn.kI.required,ss.h.custom("notmatch",()=>this.userForm&&this.userForm.getValue("newpassword")===this.userForm.getValue("oldpassword"))]],newpassword:[null,[Mn.kI.required,ss.h.custom("notmatch",()=>this.userForm&&this.userForm.getValue("oldpassword")===this.userForm.getValue("newpassword"))],[ss.h.passwordPolicy(this.userService,()=>this.authStorageService.getUsername(),(t,o,c)=>{this.passwordStrengthLevelClass=this.passwordPolicyService.mapCreditsToCssClass(o),this.passwordValuation=wr().defaultTo(c,"")})]],confirmnewpassword:[null,[Mn.kI.required]]},{validators:[ss.h.match("newpassword","confirmnewpassword")]})}onSubmit(){if(this.userForm.pristine)return;const t=this.authStorageService.getUsername(),o=this.userForm.getValue("oldpassword"),c=this.userForm.getValue("newpassword");this.userService.changePassword(t,o,c).subscribe(()=>this.onPasswordChange(),()=>{this.userForm.setErrors({cdSubmitButton:!0})})}onPasswordChange(){this.notificationService.show(pa.k.success,"Updated user password\""),this.router.navigate(["/login"])}}return n.\u0275fac=function(t){return new(t||n)(e.Y36($i.p4),e.Y36(hl.g),e.Y36(Gm.K),e.Y36(vt.j),e.Y36(rd.O),e.Y36(Bo.F0),e.Y36(Dv.q))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-user-password-form"]],decls:48,vars:25,consts:function(){let s,t,o,c,g,C,D,P,j,W;return s="" + "\ufffd0\ufffd" + " " + "\ufffd1\ufffd" + "",t="Old password",o="New password",c="Confirm new password",g="This field is required.",C="The old and new passwords must be different.",D="This field is required.",P="The old and new passwords must be different.",j="This field is required.",W="Password confirmation doesn't match the new password.",[[1,"cd-col-form"],["novalidate","",3,"formGroup"],["frm","ngForm"],[1,"card"],[1,"card-header"],s,[1,"card-body"],[1,"form-group","row"],["for","oldpassword",1,"cd-col-form-label","required"],t,[1,"cd-col-form-input"],[1,"input-group"],["type","password","placeholder","Old password...","id","oldpassword","formControlName","oldpassword","autocomplete","new-password","autofocus","",1,"form-control"],[1,"input-group-append"],["cdPasswordButton","oldpassword",1,"btn","btn-light"],["class","invalid-feedback",4,"ngIf"],["for","newpassword",1,"cd-col-form-label"],[1,"required"],o,["class","text-pre-wrap",3,"html",4,"ngIf"],["type","password","placeholder","Password...","id","newpassword","autocomplete","new-password","formControlName","newpassword",1,"form-control"],["type","button","cdPasswordButton","newpassword",1,"btn","btn-light"],[1,"password-strength-level"],["data-toggle","tooltip",3,"title"],["for","confirmnewpassword",1,"cd-col-form-label","required"],c,["type","password","autocomplete","new-password","placeholder","Confirm new password...","id","confirmnewpassword","formControlName","confirmnewpassword",1,"form-control"],["cdPasswordButton","confirmnewpassword",1,"btn","btn-light"],[1,"card-footer"],["wrappingClass","text-right",3,"form","submitText","submitActionEvent"],[1,"invalid-feedback"],g,C,[1,"text-pre-wrap",3,"html"],D,P,j,W]},template:function(t,o){if(1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"form",1,2),e.TgZ(3,"div",3),e.TgZ(4,"div",4),e.SDv(5,5),e.ALo(6,"titlecase"),e.ALo(7,"upperFirst"),e.qZA(),e.TgZ(8,"div",6),e.TgZ(9,"div",7),e.TgZ(10,"label",8),e.SDv(11,9),e.qZA(),e.TgZ(12,"div",10),e.TgZ(13,"div",11),e._UZ(14,"input",12),e.TgZ(15,"span",13),e._UZ(16,"button",14),e.qZA(),e.qZA(),e.YNc(17,rw,2,0,"span",15),e.YNc(18,iw,2,0,"span",15),e.qZA(),e.qZA(),e.TgZ(19,"div",7),e.TgZ(20,"label",16),e.TgZ(21,"span",17),e.SDv(22,18),e.qZA(),e.YNc(23,ow,1,1,"cd-helper",19),e.qZA(),e.TgZ(24,"div",10),e.TgZ(25,"div",11),e._UZ(26,"input",20),e.TgZ(27,"span",13),e._UZ(28,"button",21),e.qZA(),e.qZA(),e.TgZ(29,"div",22),e._UZ(30,"div",23),e.qZA(),e.YNc(31,FC,2,0,"span",15),e.YNc(32,kC,2,0,"span",15),e.YNc(33,$C,2,1,"span",15),e.qZA(),e.qZA(),e.TgZ(34,"div",7),e.TgZ(35,"label",24),e.SDv(36,25),e.qZA(),e.TgZ(37,"div",10),e.TgZ(38,"div",11),e._UZ(39,"input",26),e.TgZ(40,"span",13),e._UZ(41,"button",27),e.qZA(),e.qZA(),e.YNc(42,sw,2,0,"span",15),e.YNc(43,HC,2,0,"span",15),e.qZA(),e.qZA(),e.qZA(),e.TgZ(44,"div",28),e.TgZ(45,"cd-form-button-panel",29),e.NdJ("submitActionEvent",function(){return o.onSubmit()}),e.ALo(46,"titlecase"),e.ALo(47,"upperFirst"),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()),2&t){const c=e.MAs(2);e.xp6(1),e.Q6J("formGroup",o.userForm),e.xp6(6),e.pQV(e.lcZ(6,17,o.action))(e.lcZ(7,19,o.resource)),e.QtT(5),e.xp6(10),e.Q6J("ngIf",o.userForm.showError("oldpassword",c,"required")),e.xp6(1),e.Q6J("ngIf",o.userForm.showError("oldpassword",c,"notmatch")),e.xp6(5),e.Q6J("ngIf",o.passwordPolicyHelpText.length>0),e.xp6(7),e.Tol(o.passwordStrengthLevelClass),e.s9C("title",o.passwordValuation),e.xp6(1),e.Q6J("ngIf",o.userForm.showError("newpassword",c,"required")),e.xp6(1),e.Q6J("ngIf",o.userForm.showError("newpassword",c,"notmatch")),e.xp6(1),e.Q6J("ngIf",o.userForm.showError("newpassword",c,"passwordPolicy")),e.xp6(9),e.Q6J("ngIf",o.userForm.showError("confirmnewpassword",c,"required")),e.xp6(1),e.Q6J("ngIf",o.userForm.showError("confirmnewpassword",c,"match")),e.xp6(2),e.Q6J("form",o.userForm)("submitText",e.lcZ(46,21,o.action)+" "+e.lcZ(47,23,o.resource))}},directives:[Mn._Y,Mn.JL,Mn.sg,ll.V,Za.P,la.o,Mn.Fj,ja.b,Mn.JJ,Mn.u,E.U,__.C,_.O5,ul.p,h.S],pipes:[_.rS,F.m],styles:[""]}),n})();function aw(n,s){1&n&&(e.TgZ(0,"span",17),e.SDv(1,18),e.qZA())}function CR(n,s){1&n&&(e.TgZ(0,"span",17),e.SDv(1,19),e.qZA())}function MR(n,s){1&n&&(e.TgZ(0,"span",17),e.SDv(1,20),e.qZA())}function AR(n,s){1&n&&(e.TgZ(0,"span",17),e.SDv(1,21),e.qZA())}function OR(n,s){if(1&n&&(e.TgZ(0,"span",17),e._uU(1),e.qZA()),2&n){const t=e.oxw();e.xp6(1),e.hij(" ",t.passwordValuation," ")}}function BC(n,s){1&n&&(e.TgZ(0,"span",17),e.SDv(1,22),e.qZA())}function Ey(n,s){1&n&&(e.TgZ(0,"span",17),e.SDv(1,23),e.qZA())}let lw=(()=>{class n extends UC{constructor(t,o,c,g,C,D,P,j){super(t,o,c,g,C,D,P),this.actionLabels=t,this.notificationService=o,this.userService=c,this.authStorageService=g,this.formBuilder=C,this.router=D,this.passwordPolicyService=P,this.authService=j}onPasswordChange(){this.authService.logout()}onCancel(){this.authService.logout()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36($i.p4),e.Y36(hl.g),e.Y36(Gm.K),e.Y36(vt.j),e.Y36(rd.O),e.Y36(Bo.F0),e.Y36(Dv.q),e.Y36(gE.e))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-login-password-form"]],features:[e.qOj],decls:34,vars:19,consts:function(){let s,t,o,c,g,C,D,P;return s="Please set a new password.",t="You will be redirected to the login page afterwards.",o="This field is required.",c="The old and new passwords must be different.",g="This field is required.",C="The old and new passwords must be different.",D="This field is required.",P="Password confirmation doesn't match the new password.",[s,t,["novalidate","",3,"formGroup"],["frm","ngForm"],[1,"form-group","has-feedback"],[1,"input-group"],["type","password","placeholder","Old password...","id","oldpassword","formControlName","oldpassword","autocomplete","new-password","autofocus","",1,"form-control"],[1,"input-group-append"],["cdPasswordButton","oldpassword",1,"btn","btn-outline-light","btn-password"],["class","invalid-feedback",4,"ngIf"],["type","password","placeholder","New password...","id","newpassword","autocomplete","new-password","formControlName","newpassword",1,"form-control"],["type","button","cdPasswordButton","newpassword",1,"btn","btn-outline-light","btn-password"],[1,"password-strength-level"],["data-toggle","tooltip",3,"title"],["type","password","autocomplete","new-password","placeholder","Confirm new password...","id","confirmnewpassword","formControlName","confirmnewpassword",1,"form-control"],["cdPasswordButton","confirmnewpassword",1,"btn","btn-outline-light","btn-password"],["wrappingClass","text-right",3,"form","disabled","submitText","submitActionEvent","backActionEvent"],[1,"invalid-feedback"],o,c,g,C,D,P]},template:function(t,o){if(1&t&&(e.TgZ(0,"div"),e.TgZ(1,"h2"),e.SDv(2,0),e.qZA(),e.TgZ(3,"h4"),e.SDv(4,1),e.qZA(),e.TgZ(5,"form",2,3),e.TgZ(7,"div",4),e.TgZ(8,"div",5),e._UZ(9,"input",6),e.TgZ(10,"span",7),e._UZ(11,"button",8),e.qZA(),e.qZA(),e.YNc(12,aw,2,0,"span",9),e.YNc(13,CR,2,0,"span",9),e.qZA(),e.TgZ(14,"div",4),e.TgZ(15,"div",5),e._UZ(16,"input",10),e.TgZ(17,"span",7),e._UZ(18,"button",11),e.qZA(),e.qZA(),e.TgZ(19,"div",12),e._UZ(20,"div",13),e.qZA(),e.YNc(21,MR,2,0,"span",9),e.YNc(22,AR,2,0,"span",9),e.YNc(23,OR,2,1,"span",9),e.qZA(),e.TgZ(24,"div",4),e.TgZ(25,"div",5),e._UZ(26,"input",14),e.TgZ(27,"span",7),e._UZ(28,"button",15),e.qZA(),e.qZA(),e.YNc(29,BC,2,0,"span",9),e.YNc(30,Ey,2,0,"span",9),e.qZA(),e.TgZ(31,"cd-form-button-panel",16),e.NdJ("submitActionEvent",function(){return o.onSubmit()})("backActionEvent",function(){return o.onCancel()}),e.ALo(32,"titlecase"),e.ALo(33,"upperFirst"),e.qZA(),e.qZA(),e.qZA()),2&t){const c=e.MAs(6);e.xp6(5),e.Q6J("formGroup",o.userForm),e.xp6(7),e.Q6J("ngIf",o.userForm.showError("oldpassword",c,"required")),e.xp6(1),e.Q6J("ngIf",o.userForm.showError("oldpassword",c,"notmatch")),e.xp6(7),e.Tol(o.passwordStrengthLevelClass),e.s9C("title",o.passwordValuation),e.xp6(1),e.Q6J("ngIf",o.userForm.showError("newpassword",c,"required")),e.xp6(1),e.Q6J("ngIf",o.userForm.showError("newpassword",c,"notmatch")),e.xp6(1),e.Q6J("ngIf",o.userForm.showError("newpassword",c,"passwordPolicy")),e.xp6(6),e.Q6J("ngIf",o.userForm.showError("confirmnewpassword",c,"required")),e.xp6(1),e.Q6J("ngIf",o.userForm.showError("confirmnewpassword",c,"match")),e.xp6(1),e.Q6J("form",o.userForm)("disabled",o.userForm.invalid)("submitText",e.lcZ(32,15,o.action)+" "+e.lcZ(33,17,o.resource))}},directives:[Mn._Y,Mn.JL,Mn.sg,ll.V,Za.P,la.o,Mn.Fj,ja.b,Mn.JJ,Mn.u,E.U,__.C,_.O5,ul.p],pipes:[_.rS,F.m],styles:["cd-login-password-form h4{margin:0 0 30px} cd-login-password-form .form-group{background-color:#2e373d;border-left:4px solid #fff} cd-login-password-form .form-group:focus-within{border-left:4px solid #ef5c55} cd-login-password-form .btn-password, cd-login-password-form .btn-password:focus, cd-login-password-form .form-control, cd-login-password-form .form-control:focus{background-color:#2e373d;border:0;box-shadow:none;color:#f8f9fa;filter:none;outline:none} cd-login-password-form .form-control::placeholder{color:#6c757d} cd-login-password-form .btn-password:focus{outline-color:#2b99a8} cd-login-password-form button.btn:not(:first-child){margin-left:5px}@keyframes autofill{to{background-color:#2e373d;color:#f8f9fa}}input[_ngcontent-%COMP%]:-webkit-autofill{animation-fill-mode:both;animation-name:autofill;border-radius:0;box-shadow:0 0 0 1000px #2e373d inset;-webkit-text-fill-color:#f8f9fa;-webkit-transition-property:none;transition-property:none}.invalid-feedback[_ngcontent-%COMP%]{padding-left:9px}.is-invalid.cd-form-control[_ngcontent-%COMP%]{border-color:transparent}"]}),n})();class uw{}function YC(n,s){1&n&&(e.TgZ(0,"div",20),e.SDv(1,21),e.qZA())}function P1(n,s){1&n&&(e.TgZ(0,"div",20),e.SDv(1,22),e.qZA())}function cw(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",1),e.TgZ(1,"form",2,3),e.NdJ("ngSubmit",function(){return e.CHM(t),e.oxw().login()}),e.TgZ(3,"div",4),e.TgZ(4,"label",5),e.SDv(5,6),e.qZA(),e.TgZ(6,"input",7,8),e.NdJ("ngModelChange",function(c){return e.CHM(t),e.oxw().model.username=c}),e.qZA(),e.YNc(8,YC,2,0,"div",9),e.qZA(),e.TgZ(9,"div",10),e.TgZ(10,"div",11),e.TgZ(11,"div",12),e.TgZ(12,"label",13),e.SDv(13,14),e.qZA(),e.TgZ(14,"input",15,16),e.NdJ("ngModelChange",function(c){return e.CHM(t),e.oxw().model.password=c}),e.qZA(),e.YNc(16,P1,2,0,"div",9),e.qZA(),e.TgZ(17,"span",17),e._UZ(18,"button",18),e.qZA(),e.qZA(),e.qZA(),e._UZ(19,"input",19),e.qZA(),e.qZA()}if(2&n){const t=e.MAs(2),o=e.MAs(7),c=e.MAs(15),g=e.oxw();e.xp6(6),e.Q6J("ngModel",g.model.username),e.uIk("aria-invalid",o.invalid),e.xp6(2),e.Q6J("ngIf",(t.submitted||o.dirty)&&o.invalid),e.xp6(6),e.Q6J("ngModel",g.model.password),e.uIk("aria-invalid",c.invalid),e.xp6(2),e.Q6J("ngIf",(t.submitted||c.dirty)&&c.invalid),e.xp6(3),e.Q6J("disabled",t.invalid)}}let dw=(()=>{class n{constructor(t,o,c,g,C){this.authService=t,this.authStorageService=o,this.modalService=c,this.route=g,this.router=C,this.model=new uw,this.isLoginActive=!1,this.postInstalled=!1}ngOnInit(){if(this.authStorageService.isLoggedIn())this.router.navigate([""]);else{this.modalService.dismissAll();let t=null;if(-1!==window.location.hash.indexOf("access_token=")){t=window.location.hash.split("access_token=")[1];const o=window.location.toString();window.history.replaceState({},document.title,o.split("?")[0])}this.authService.check(t).subscribe(o=>{o.login_url?(this.postInstalled="POST_INSTALLED"===o.cluster_status,"#/login"===o.login_url?this.isLoginActive=!0:window.location.replace(o.login_url)):(this.authStorageService.set(o.username,o.permissions,o.sso,o.pwdExpirationDate),this.router.navigate([""]))})}}login(){this.authService.login(this.model).subscribe(()=>{const t=this.postInstalled?"/":"/expand-cluster";let o=wr().get(this.route.snapshot.queryParams,"returnUrl",t);!this.postInstalled&&"/dashboard"===this.route.snapshot.queryParams.returnUrl&&(o="/expand-cluster"),this.router.navigate([o])})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(gE.e),e.Y36(vt.j),e.Y36(Bl.Z),e.Y36(Bo.gz),e.Y36(Bo.F0))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-login"]],decls:1,vars:1,consts:function(){let s,t,o,c,g;return s="Username",t="Password",o="Log in",c="Username is required",g="Password is required",[["class","container",4,"ngIf"],[1,"container"],["name","loginForm","novalidate","",3,"ngSubmit"],["loginForm","ngForm"],[1,"form-group","has-feedback","d-flex","flex-column","py-3"],["for","username",1,"placeholder","pl-4"],s,["id","username","name","username","type","text","aria-labelledby","username","required","","autofocus","",1,"form-control","pl-4",3,"ngModel","ngModelChange"],["username","ngModel"],["class","invalid-feedback pl-4",4,"ngIf"],["id","password-div",1,"form-group","has-feedback"],[1,"input-group","d-flex","flex-nowrap"],[1,"d-flex","flex-column","flex-grow-1","py-3"],["for","password",1,"placeholder","pl-4"],t,["id","password","name","password","type","password","aria-labelledby","password","required","",1,"form-control","pl-4",3,"ngModel","ngModelChange"],["password","ngModel"],[1,"form-group-append"],["type","button","cdPasswordButton","password",1,"btn","btn-outline-light","btn-password","h-100","px-4"],["type","submit","value",o,1,"btn","btn-accent","px-5","py-2",3,"disabled"],[1,"invalid-feedback","pl-4"],c,g]},template:function(t,o){1&t&&e.YNc(0,cw,20,7,"div",0),2&t&&e.Q6J("ngIf",o.isLoginActive)},directives:[_.O5,Mn._Y,Mn.JL,Mn.F,Za.P,la.o,Mn.Fj,ja.b,Mn.Q7,E.U,Mn.JJ,Mn.On,__.C],styles:["cd-login .form-group{background-color:#2e373d;border-left:4px solid #fff;height:auto;margin-bottom:2rem} cd-login .form-group:focus-within{border-left:4px solid #ef5c55} cd-login .btn-password, cd-login .btn-password:focus, cd-login .form-control, cd-login .form-control:focus{background-color:#2e373d;border:0;box-shadow:none;color:#f8f9fa;filter:none;outline:none} cd-login .placeholder{color:#6c757d} cd-login .btn-password:focus{outline-color:#2b99a8}@keyframes autofill{to{background-color:#2e373d;color:#f8f9fa}}input[_ngcontent-%COMP%]:-webkit-autofill{animation-fill-mode:both;animation-name:autofill;border-radius:0;box-shadow:0 0 0 1000px #2e373d inset;-webkit-text-fill-color:#f8f9fa;-webkit-transition-property:none;transition-property:none}"]}),n})();var ZC=i(72625);function fw(n,s){if(1&n&&(e.TgZ(0,"h4",14),e._uU(1),e.qZA()),2&n){const t=e.oxw(2);e.xp6(1),e.Oqu(t.message)}}function pw(n,s){if(1&n&&(e.TgZ(0,"h4"),e.tHW(1,15),e._UZ(2,"a",16),e.N_p(),e.qZA()),2&n){const t=e.oxw(2);e.xp6(2),e.s9C("href",t.docUrl,e.LSH),e.pQV(t.sectionInfo),e.QtT(1)}}function jC(n,s){if(1&n&&(e.TgZ(0,"div"),e._UZ(1,"i",10),e.TgZ(2,"div",11),e.TgZ(3,"h3"),e.TgZ(4,"b"),e._uU(5),e.qZA(),e.qZA(),e.YNc(6,fw,2,1,"h4",12),e.YNc(7,pw,3,2,"h4",13),e.qZA(),e.qZA()),2&n){const t=e.oxw();e.xp6(1),e.Q6J("ngClass",t.icon),e.xp6(4),e.Oqu(t.header),e.xp6(1),e.Q6J("ngIf",t.header!==t.message),e.xp6(1),e.Q6J("ngIf",t.section)}}function hw(n,s){if(1&n&&(e.TgZ(0,"button",19),e.SDv(1,20),e.qZA()),2&n){const t=e.oxw(2);e.Q6J("routerLink",t.buttonRoute),e.xp6(1),e.pQV(t.buttonName),e.QtT(1)}}function _w(n,s){if(1&n&&(e.TgZ(0,"div",17),e.YNc(1,hw,2,2,"button",18),e.qZA()),2&n){const t=e.oxw(),o=e.MAs(11);e.xp6(1),e.Q6J("ngIf",!t.uiConfig)("ngIfElse",o)}}function Rv(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"button",22),e.NdJ("click",function(){return e.CHM(t),e.oxw(2).doConfigure()}),e.SDv(1,23),e.qZA()}if(2&n){const t=e.oxw(2);e.uIk("title",t.buttonTitle),e.xp6(1),e.pQV(t.buttonName),e.QtT(1)}}function gw(n,s){if(1&n&&e.YNc(0,Rv,2,2,"button",21),2&n){const t=e.oxw();e.Q6J("ngIf",t.uiConfig)}}function GC(n,s){1&n&&(e._UZ(0,"i",24),e.TgZ(1,"div",11),e.TgZ(2,"h3"),e.tHW(3,25),e._UZ(4,"b"),e.N_p(),e.qZA(),e.TgZ(5,"h4",5),e.SDv(6,26),e.qZA(),e.qZA())}function mw(n,s){1&n&&(e.TgZ(0,"div",11),e.TgZ(1,"button",19),e.SDv(2,27),e.qZA(),e.qZA()),2&n&&(e.xp6(1),e.Q6J("routerLink","/dashboard"))}let VC=(()=>{class n{constructor(t,o,c,g){this.router=t,this.docService=o,this.http=c,this.notificationService=g}ngOnInit(){this.fetchData(),this.routerSubscription=this.router.events.pipe((0,np.h)(t=>t instanceof Bo.m2)).subscribe(()=>{this.fetchData()})}doConfigure(){this.http.post(`ui-api/${this.uiApiPath}/configure`,{}).subscribe({next:()=>{this.notificationService.show(pa.k.info,`Configuring ${this.component}`)},error:t=>{this.notificationService.show(pa.k.error,t)},complete:()=>{setTimeout(()=>{this.router.navigate([this.uiApiPath]),this.notificationService.show(pa.k.success,`Configured ${this.component}`)},3e3)}})}unloadHandler(t){t.returnValue=!1}fetchData(){try{this.router.onSameUrlNavigation="reload",this.message=history.state.message,this.header=history.state.header,this.section=history.state.section,this.sectionInfo=history.state.section_info,this.icon=history.state.icon,this.source=history.state.source,this.uiConfig=history.state.uiConfig,this.uiApiPath=history.state.uiApiPath,this.buttonRoute=history.state.button_route,this.buttonName=history.state.button_name,this.buttonTitle=history.state.button_title,this.component=history.state.component,this.docUrl=this.docService.urlGenerator(this.section)}catch(t){this.router.navigate(["/error"])}}ngOnDestroy(){this.routerSubscription&&this.routerSubscription.unsubscribe()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Bo.F0),e.Y36(ZC.R),e.Y36(y.eN),e.Y36(hl.g))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-error"]],hostBindings:function(t,o){1&t&&e.NdJ("beforeunload",function(g){return o.unloadHandler(g)},!1,e.Jf7)},decls:16,vars:4,consts:function(){let s,t,o,c,g,C;return s="Please consult the " + "\ufffd#2\ufffd" + "documentation" + "\ufffd/#2\ufffd" + " on how to configure and enable the " + "\ufffd0\ufffd" + " management functionality. ",t="" + "\ufffd0\ufffd" + "",o="" + "\ufffd0\ufffd" + "",c="" + "\ufffd#4\ufffd" + "Page not Found" + "\ufffd/#4\ufffd" + "",g="Sorry, we couldn\u2019t find what you were looking for. The page you requested may have been changed or moved.",C="Go To Dashboard",[["target","_blank"],[1,"container","h-75"],[1,"row","h-100","justify-content-center","align-items-center"],[1,"blank-page"],[4,"ngIf","ngIfElse"],[1,"mt-4"],["class","text-center",4,"ngIf","ngIfElse"],["configureButtonTpl",""],["elseBlock",""],["dashboardButton",""],[1,"mx-auto","d-block",3,"ngClass"],[1,"mt-4","text-center"],["class","mt-3",4,"ngIf"],[4,"ngIf"],[1,"mt-3"],s,[3,"href"],[1,"text-center"],["class","btn btn-primary",3,"routerLink",4,"ngIf","ngIfElse"],[1,"btn","btn-primary",3,"routerLink"],t,["class","btn btn-primary",3,"click",4,"ngIf"],[1,"btn","btn-primary",3,"click"],o,[1,"fa","fa-exclamation-triangle","mx-auto","d-block","text-danger"],c,g,C]},template:function(t,o){if(1&t&&(e.TgZ(0,"head"),e.TgZ(1,"title"),e._uU(2,"Error Page"),e.qZA(),e._UZ(3,"base",0),e.qZA(),e.TgZ(4,"div",1),e.TgZ(5,"div",2),e.TgZ(6,"div",3),e.YNc(7,jC,8,4,"div",4),e.TgZ(8,"div",5),e.YNc(9,_w,2,2,"div",6),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.YNc(10,gw,1,1,"ng-template",null,7,e.W1O),e.YNc(12,GC,7,0,"ng-template",null,8,e.W1O),e.YNc(14,mw,3,1,"ng-template",null,9,e.W1O)),2&t){const c=e.MAs(13),g=e.MAs(15);e.xp6(7),e.Q6J("ngIf",o.header&&o.message)("ngIfElse",c),e.xp6(2),e.Q6J("ngIf",o.buttonName&&o.buttonRoute||o.uiConfig)("ngIfElse",g)}},directives:[_.O5,_.mk,la.o,Bo.rH],styles:["h4[_ngcontent-%COMP%]{color:#495057}i[_ngcontent-%COMP%]{font-size:6em;margin-top:120px}.fa-lock[_ngcontent-%COMP%]{color:#ef5c55}.fa-wrench[_ngcontent-%COMP%]{color:#2b99a8}"]}),n})(),vw=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-blank-layout"]],decls:1,vars:0,template:function(t,o){1&t&&e._UZ(0,"router-outlet")},directives:[Bo.lC],styles:[""]}),n})();var mE=i(92340);let yw=(()=>{class n{constructor(t,o){this.http=t,this.localeId=o}getLocale(){return this.localeId||mE.N.default_lang}setLocale(t){document.cookie=`cd-lang=${t}`}getLanguages(){return this.http.get("ui-api/langs")}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(y.eN),e.LFG(e.soG))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();var Vm=(()=>{return(n=Vm||(Vm={})).cs="\u010ce\u0161tina",n.de="Deutsch",n["en-US"]="English",n.es="Espa\xf1ol",n.fr="Fran\xe7ais",n.id="Bahasa Indonesia",n.it="Italiano",n.ja="\u65e5\u672c\u8a9e",n.ko="\ud55c\uad6d\uc5b4",n.pl="Polski",n.pt="Portugu\xeas (brasileiro)",n["zh-Hans"]="\u4e2d\u6587 (\u7b80\u4f53)",n["zh-Hant"]="\u4e2d\u6587 (\u7e41\u9ad4\uff09",Vm;var n})();function bw(n,s){if(1&n){const t=e.EpF();e.ynx(0),e.TgZ(1,"button",4),e.NdJ("click",function(){const g=e.CHM(t).$implicit;return e.oxw().changeLanguage(g.key)}),e._uU(2),e.qZA(),e.BQk()}if(2&n){const t=s.$implicit;e.xp6(2),e.hij(" ",t.value," ")}}let vE=(()=>{class n{constructor(t){this.languageService=t,this.allLanguages=Vm,this.supportedLanguages={}}ngOnInit(){this.selectedLanguage=this.languageService.getLocale(),this.languageService.getLanguages().subscribe(t=>{this.supportedLanguages=wr().pick(Vm,t)})}reloadWindow(){window.location.reload()}changeLanguage(t){this.languageService.setLocale(t),this.reloadWindow()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(yw))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-language-selector"]],decls:6,vars:4,consts:function(){let s;return s="Select a Language",[["ngbDropdown","","display","dynamic","placement","bottom-right"],["ngbDropdownToggle","","title",s],["ngbDropdownMenu",""],[4,"ngFor","ngForOf"],["ngbDropdownItem","",3,"click"]]},template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"a",1),e._uU(2),e.qZA(),e.TgZ(3,"div",2),e.YNc(4,bw,3,1,"ng-container",3),e.ALo(5,"keyvalue"),e.qZA(),e.qZA()),2&t&&(e.xp6(2),e.hij(" ",o.allLanguages[o.selectedLanguage]," "),e.xp6(2),e.Q6J("ngForOf",e.lcZ(5,2,o.supportedLanguages)))},directives:[ut.jt,ut.iD,ut.Vi,_.sg,la.o,ut.TH],pipes:[_.Nd],styles:[""]}),n})(),zC=(()=>{class n{constructor(t){this.http=t,this.baseUiURL="ui-api/login/custom_banner"}getBannerText(){return this.http.get(this.baseUiURL)}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(y.eN))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();function Ew(n,s){if(1&n&&(e.TgZ(0,"p",1),e._uU(1),e.qZA()),2&n){const t=s.ngIf;e.xp6(1),e.Oqu(t)}}let Tw=(()=>{class n{constructor(t){this.customLoginBannerService=t}ngOnInit(){this.bannerText$=this.customLoginBannerService.getBannerText()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(zC))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-custom-login-banner"]],decls:2,vars:3,consts:[["class","login-text",4,"ngIf"],[1,"login-text"]],template:function(t,o){1&t&&(e.YNc(0,Ew,2,1,"p",0),e.ALo(1,"async")),2&t&&e.Q6J("ngIf",e.lcZ(1,1,o.bannerText$))},directives:[_.O5],pipes:[_.Ov],styles:[".login-text[_ngcontent-%COMP%]{font-weight:bold;margin:0;padding:12px 20% 12px 12px}"]}),n})();function Sw(n,s){if(1&n&&(e.TgZ(0,"li",11),e.TgZ(1,"cd-doc",12),e.DtL(2,13),e.qZA(),e.qZA()),2&n){const t=s.$implicit;e.xp6(1),e.pQV(t.text),e.QtT(2),e.s9C("section",t.section)}}let yE=(()=>{class n{constructor(){this.docItems=[{section:"help",text:"Help"},{section:"security",text:"Security"},{section:"trademarks",text:"Trademarks"}]}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-login-layout"]],decls:16,vars:1,consts:function(){let s;return s="" + "\ufffd0\ufffd" + "",[[1,"login","full-height"],[1,"navbar","p-4"],[1,"navbar-brand"],[1,"form-inline"],[1,"container"],[1,"row","full-height"],[1,"col-sm-12","col-md-6","d-sm-block","login-form"],[1,"col-sm-12","col-md-6","d-sm-block","branding-info"],["src","assets/Ceph_Ceph_Logo_with_text_white.svg","alt","Ceph",1,"img-fluid","pb-3"],[1,"list-inline"],["class","list-inline-item p-3",4,"ngFor","ngForOf"],[1,"list-inline-item","p-3"],["noSubscribe","true",3,"section",6,"docText"],["docText",s]]},template:function(t,o){1&t&&(e.TgZ(0,"main",0),e.TgZ(1,"header"),e.TgZ(2,"nav",1),e._UZ(3,"a",2),e.TgZ(4,"div",3),e._UZ(5,"cd-language-selector"),e.qZA(),e.qZA(),e.qZA(),e.TgZ(6,"section"),e.TgZ(7,"div",4),e.TgZ(8,"div",5),e.TgZ(9,"div",6),e._UZ(10,"router-outlet"),e.qZA(),e.TgZ(11,"div",7),e._UZ(12,"img",8),e.TgZ(13,"ul",9),e.YNc(14,Sw,3,2,"li",10),e.qZA(),e._UZ(15,"cd-custom-login-banner"),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA()),2&t&&(e.xp6(14),e.Q6J("ngForOf",o.docItems))},directives:[ut.M2,vE,Bo.lC,_.sg,Tw,il.K],styles:["cd-login-layout .login{background-color:#374249;background-image:url(ceph_background.e82dd79127290ddbe8cb.gif);background-position:right bottom;background-repeat:no-repeat;color:#f8f9fa} cd-login-layout .login header{position:absolute;width:100vw} cd-login-layout .login header .navbar .dropdown-menu{margin-top:.2rem} cd-login-layout .login header .navbar .dropdown-menu li a:hover{background-color:#2b99a8} cd-login-layout .login section{display:inline-flex;min-height:100vh;width:100vw} cd-login-layout .login .list-inline{margin-bottom:0;margin-left:20%} cd-login-layout .login a{color:#fff} cd-login-layout .login a:hover{color:#adb5bd}@media screen and (min-width: 576px){ cd-login-layout .login .login-form, cd-login-layout .login .branding-info{padding-top:30vh}}@media screen and (max-width: calc(768px - 1px)){ cd-login-layout .login .login-form{padding-top:10vh} cd-login-layout .login .branding-info{padding-top:0}}"]}),n})();var Nv=i(74255);let bE=(()=>{class n{constructor(t,o,c){this.document=t,this.summaryService=o,this.cssHelper=c}init(){var t;this.url=null===(t=this.document.getElementById("cdFavicon"))||void 0===t?void 0:t.getAttribute("href"),this.sub=this.summaryService.subscribe(o=>{this.changeIcon(o.health_status)})}changeIcon(t){if(t===this.oldStatus)return;this.oldStatus=t;const o=this.document.getElementById("cdFavicon"),C=this.document.createElement("canvas");C.width=16,C.height=16;const D=C.getContext("2d"),P=this.document.createElement("img");P.src=this.url,P.onload=()=>{D.drawImage(P,0,0,16,16),Object.keys(xg).includes(t)&&(D.save(),D.globalCompositeOperation="destination-out",D.beginPath(),D.arc(C.width-4,4,6,0,2*Math.PI),D.fill(),D.restore(),D.beginPath(),D.arc(C.width-4,4,4,0,2*Math.PI),D.fillStyle=this.cssHelper.propertyValue(xg[t]),D.fill()),o.setAttribute("href",C.toDataURL("image/png"))}}ngOnDestroy(){var t;this.changeIcon(),null===(t=this.sub)||void 0===t||t.unsubscribe()}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(_.K0),e.LFG(Nv.J),e.LFG(Zm.P))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac}),n})();var Cw=i(71099),WC=i(59193),Mw=i(68307);class JC{constructor(s,t){this.count=s,this.source=t}call(s,t){return t.subscribe(new Ow(s,this.count,this.source))}}class Ow extends fd.L{constructor(s,t,o){super(s),this.count=t,this.source=o}complete(){if(!this.isStopped){const{source:s,count:t}=this;if(0===t)return super.complete();t>-1&&(this.count=t-1),s.subscribe(this._unsubscribeAndRecycle())}}}var ww=i(49083);let xw=(()=>{class n{constructor(t){this.http=t,this.url="ui-api/motd"}get(){return this.http.get(this.url)}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(y.eN))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})(),Ty=(()=>{class n{constructor(t){this.motdService=t,this.motdSource=new Pd.X(null),this.localStorageKey="dashboard_motd_hidden",this.motd$=this.motdSource.asObservable(),this.subscription=(0,Vc.of)(!0).pipe((0,Bu.zg)(()=>this.motdService.get()),(0,wv.K)(o=>(uu.isFunction(o.preventDefault)&&o.preventDefault(),WC.E)),(0,Mw.b)(o=>this.processResponse(o)),(0,yp.g)(6e4),function(n=-1){return s=>0===n?(0,WC.c)():s.lift(new JC(n<0?-1:n-1,s))}(),(0,ww.r)()).subscribe()}ngOnDestroy(){this.subscription.unsubscribe()}hide(){const t=this.motdSource.getValue();if(t){const o=`${t.severity}:${t.md5}`;switch(t.severity){case"info":localStorage.setItem(this.localStorageKey,o),sessionStorage.removeItem(this.localStorageKey);break;case"warning":sessionStorage.setItem(this.localStorageKey,o),localStorage.removeItem(this.localStorageKey)}}this.motdSource.next(null)}processResponse(t){const o=sessionStorage.getItem(this.localStorageKey)||localStorage.getItem(this.localStorageKey);let c=uu.isNull(o);if(!c&&t){const[g,C]=o.split(":");(g!==t.severity||C!==t.md5)&&(c=!0,sessionStorage.removeItem(this.localStorageKey),localStorage.removeItem(this.localStorageKey))}c&&this.motdSource.next(t)}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(xw))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();var EE=i(51907);function QC(n,s){1&n&&(e.TgZ(0,"div"),e.tHW(1,3),e._UZ(2,"strong"),e._UZ(3,"a",4),e.N_p(),e.qZA())}function XC(n,s){if(1&n&&(e.TgZ(0,"div"),e.tHW(1,5),e._UZ(2,"strong"),e._UZ(3,"a",4),e.N_p(),e.qZA()),2&n){const t=e.oxw(2);e.xp6(3),e.pQV(t.expirationDays),e.QtT(1)}}function TE(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-alert-panel",1),e.NdJ("dismissed",function(){return e.CHM(t),e.oxw().onDismissed()}),e.YNc(1,QC,4,0,"div",2),e.YNc(2,XC,4,1,"div",2),e.qZA()}if(2&n){const t=e.oxw();e.Q6J("type",t.alertType)("showTitle",!1)("dismissible","danger"!==t.alertType),e.xp6(1),e.Q6J("ngIf",0===t.expirationDays),e.xp6(1),e.Q6J("ngIf",t.expirationDays>0)}}let KC=(()=>{class n{constructor(t,o){this.settingsService=t,this.authStorageService=o,this.displayNotification=!1}ngOnInit(){this.settingsService.getStandardSettings().subscribe(t=>{this.pwdExpirationSettings=new EE.G(t);const o=this.authStorageService.getPwdExpirationDate();o&&(this.expirationDays=this.getExpirationDays(o),this.alertType=this.expirationDays<=this.pwdExpirationSettings.pwdExpirationWarning2?"danger":"warning",this.displayNotification=this.expirationDays<=this.pwdExpirationSettings.pwdExpirationWarning1,this.authStorageService.isPwdDisplayedSource.next(this.displayNotification))})}ngOnDestroy(){this.authStorageService.isPwdDisplayedSource.next(!1)}getExpirationDays(t){const o=new Date,c=new Date(1e3*t);return Math.floor((c.valueOf()-o.valueOf())/864e5)}onDismissed(){this.authStorageService.isPwdDisplayedSource.next(!1),this.displayNotification=!1}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(O1.g),e.Y36(vt.j))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-pwd-expiration-notification"]],decls:1,vars:1,consts:function(){let s,t;return s="Your password will expire in " + "\ufffd#2\ufffd" + "less than 1" + "\ufffd/#2\ufffd" + " day. Click " + "\ufffd#3\ufffd" + "here" + "\ufffd/#3\ufffd" + " to change it now.",t="Your password will expire in " + "\ufffd#2\ufffd" + "" + "\ufffd0\ufffd" + "" + "\ufffd/#2\ufffd" + " day(s). Click " + "\ufffd#3\ufffd" + "here" + "\ufffd/#3\ufffd" + " to change it now.",[["class","no-margin-bottom","size","slim",3,"type","showTitle","dismissible","dismissed",4,"ngIf"],["size","slim",1,"no-margin-bottom",3,"type","showTitle","dismissible","dismissed"],[4,"ngIf"],s,["routerLink","/user-profile/edit",1,"alert-link"],t]},template:function(t,o){1&t&&e.YNc(0,TE,3,5,"cd-alert-panel",0),2&t&&e.Q6J("ngIf",o.displayNotification)},directives:[_.O5,gt.G,Bo.yS],styles:[".no-margin-bottom[_ngcontent-%COMP%]{margin-bottom:0}"]}),n})();function qC(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-alert-panel",1),e.NdJ("dismissed",function(){return e.CHM(t),e.oxw().onDismissed()}),e.TgZ(1,"div"),e.tHW(2,2),e._UZ(3,"a",3),e._UZ(4,"a",4),e.N_p(),e.qZA(),e.qZA()}if(2&n){const t=e.oxw();e.Q6J("showTitle",!1)("type",t.notificationSeverity)("dismissible","danger"!==t.notificationSeverity)}}let Dw=(()=>{class n{constructor(t,o,c,g){this.mgrModuleService=t,this.authStorageService=o,this.notificationService=c,this.telemetryNotificationService=g,this.displayNotification=!1,this.notificationSeverity="warning"}ngOnInit(){if(this.telemetryNotificationService.update.subscribe(t=>{this.displayNotification=t}),!this.isNotificationHidden()){const t=this.authStorageService.getPermissions().configOpt;wr().every(Object.values(t))&&this.mgrModuleService.getConfig("telemetry").subscribe(o=>{o.enabled||this.telemetryNotificationService.setVisibility(!0)})}}ngOnDestroy(){this.telemetryNotificationService.setVisibility(!1)}isNotificationHidden(){return"true"===localStorage.getItem("telemetry_notification_hidden")}onDismissed(){this.telemetryNotificationService.setVisibility(!1),localStorage.setItem("telemetry_notification_hidden","true"),this.notificationService.show(pa.k.success,"Telemetry activation reminder muted","You can activate the module on the Telemetry configuration page (<b>Dashboard Settings</b> -> <b>Telemetry configuration</b>) at any time.")}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(ql.N),e.Y36(vt.j),e.Y36(hl.g),e.Y36(x1))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-telemetry-notification"]],decls:1,vars:1,consts:function(){let s;return s="The Ceph community needs your help to continue improving: please " + "\ufffd#3\ufffd" + "Activate" + "[\ufffd/#3\ufffd|\ufffd/#4\ufffd]" + " the " + "\ufffd#4\ufffd" + "Telemetry" + "[\ufffd/#3\ufffd|\ufffd/#4\ufffd]" + " module.",s=e.Zx4(s),[["class","no-margin-bottom","size","slim",3,"showTitle","type","dismissible","dismissed",4,"ngIf"],["size","slim",1,"no-margin-bottom",3,"showTitle","type","dismissible","dismissed"],s,["routerLink","/telemetry",1,"btn","activate-button","alert-link","activate-text"],["href","https://docs.ceph.com/en/latest/mgr/telemetry/"]]},template:function(t,o){1&t&&e.YNc(0,qC,5,3,"cd-alert-panel",0),2&t&&e.Q6J("ngIf",o.displayNotification)},directives:[_.O5,gt.G,Bo.yS],styles:[".no-margin-bottom[_ngcontent-%COMP%]{margin-bottom:0}.activate-button[_ngcontent-%COMP%]{background-color:#fcecba;border:#495057 solid .5px;border-radius:10%;padding:.1rem .4rem}.activate-text[_ngcontent-%COMP%]{color:#495057;font-weight:bold}"]}),n})();var SE=i(60793);function CE(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"cd-alert-panel",1),e.NdJ("dismissed",function(){return e.CHM(t),e.oxw().onDismissed()}),e._UZ(1,"span",2),e.ALo(2,"sanitizeHtml"),e.qZA()}if(2&n){const t=e.oxw();e.Q6J("showTitle",!1)("type",t.motd.severity)("dismissible","danger"!==t.motd.severity),e.xp6(1),e.Q6J("innerHTML",e.lcZ(2,4,t.motd.message),e.oJD)}}let eM=(()=>{class n{constructor(t){this.motdNotificationService=t,this.motd=void 0}ngOnInit(){this.subscription=this.motdNotificationService.motd$.subscribe(t=>{this.motd=t})}ngOnDestroy(){this.subscription.unsubscribe()}onDismissed(){this.motdNotificationService.hide()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Ty))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-motd"]],decls:1,vars:1,consts:[["size","slim",3,"showTitle","type","dismissible","dismissed",4,"ngIf"],["size","slim",3,"showTitle","type","dismissible","dismissed"],[3,"innerHTML"]],template:function(t,o){1&t&&e.YNc(0,CE,3,6,"cd-alert-panel",0),2&t&&e.Q6J("ngIf",o.motd)},directives:[_.O5,gt.G],pipes:[SE.A],styles:[""]}),n})();class Rw{constructor(s){if(this._maxConcurrency=s,this._queue=[],s<=0)throw new Error("semaphore must be initialized to a positive value");this._value=s}acquire(){const s=this.isLocked(),t=new Promise(o=>this._queue.push(o));return s||this._dispatch(),t}runExclusive(s){return function(n,s,t,o){return new(t||(t=Promise))(function(g,C){function D(W){try{j(o.next(W))}catch(re){C(re)}}function P(W){try{j(o.throw(W))}catch(re){C(re)}}function j(W){W.done?g(W.value):function(g){return g instanceof t?g:new t(function(C){C(g)})}(W.value).then(D,P)}j((o=o.apply(n,s||[])).next())})}(this,void 0,void 0,function*(){const[t,o]=yield this.acquire();try{return yield s(t)}finally{o()}})}isLocked(){return this._value<=0}release(){if(this._maxConcurrency>1)throw new Error("this method is unavailabel on semaphores with concurrency > 1; use the scoped release returned by acquire instead");this._currentReleaser&&(this._currentReleaser(),this._currentReleaser=void 0)}_dispatch(){const s=this._queue.shift();if(!s)return;let t=!1;this._currentReleaser=()=>{t||(t=!0,this._value++,this._dispatch())},s([this._value--,this._currentReleaser])}}class AE{constructor(){this._semaphore=new Rw(1)}acquire(){return function(n,s,t,o){return new(t||(t=Promise))(function(g,C){function D(W){try{j(o.next(W))}catch(re){C(re)}}function P(W){try{j(o.throw(W))}catch(re){C(re)}}function j(W){W.done?g(W.value):function(g){return g instanceof t?g:new t(function(C){C(g)})}(W.value).then(D,P)}j((o=o.apply(n,s||[])).next())})}(this,void 0,void 0,function*(){const[,s]=yield this._semaphore.acquire();return s})}runExclusive(s){return this._semaphore.runExclusive(()=>s())}isLocked(){return this._semaphore.isLocked()}release(){this._semaphore.release()}}let nM=(()=>{class n{constructor(t,o){this.alertFormatter=t,this.prometheusService=o,this.backendFailure=!1,this.notifications=[]}refresh(){this.backendFailure||this.prometheusService.getNotifications(wr().last(this.notifications)).subscribe(t=>this.handleNotifications(t),()=>this.backendFailure=!0)}handleNotifications(t){0!==t.length&&(this.notifications.length>0&&this.alertFormatter.sendNotifications(wr().flatten(t.map(o=>this.formatNotification(o)))),this.notifications=this.notifications.concat(t))}formatNotification(t){return this.alertFormatter.convertToCustomAlerts(t.alerts).map(o=>this.alertFormatter.convertAlertToNotification(o))}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(w1),e.LFG(ng))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();var rM=i(68879),iM=i(11971),Sy=i(34863);const oM=function(n,s){return[n,s]},Iw=function(n,s,t,o){return[n,s,t,o]};function Pv(n,s){if(1&n&&(e.TgZ(0,"div"),e.TgZ(1,"div",12),e.TgZ(2,"div",13),e.TgZ(3,"div",14),e.TgZ(4,"span",15),e._UZ(5,"i",7),e._UZ(6,"i",7),e.qZA(),e.qZA(),e.TgZ(7,"div",16),e.TgZ(8,"div",17),e.TgZ(9,"h6",18),e._uU(10),e.qZA(),e.TgZ(11,"div",19),e._UZ(12,"ngb-progressbar",20),e.qZA(),e.TgZ(13,"p",21),e.TgZ(14,"small",22),e._uU(15),e.ALo(16,"cdDate"),e.qZA(),e.TgZ(17,"span",23),e._uU(18),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e._UZ(19,"hr"),e.qZA()),2&n){const t=s.$implicit,o=e.oxw(2);e.xp6(4),e.Q6J("ngClass",e.WLB(11,oM,o.icons.stack,o.icons.large2x)),e.xp6(1),e.Q6J("ngClass",e.WLB(14,oM,o.icons.stack2x,o.icons.circle)),e.xp6(1),e.Q6J("ngClass",e.l5B(17,Iw,o.icons.stack1x,o.icons.spinner,o.icons.spin,o.icons.inverse)),e.xp6(4),e.Oqu(t.description),e.xp6(2),e.Q6J("value",null==t?null:t.progress)("striped",!0)("animated",!0),e.xp6(3),e.hij(" ",e.lcZ(16,9,t.begin_time)," "),e.xp6(3),e.hij(" ",t.progress||0," % ")}}function wR(n,s){if(1&n&&e.YNc(0,Pv,20,22,"div",11),2&n){const t=e.oxw();e.Q6J("ngForOf",t.executingTasks)("ngForTrackBy",t.trackByFn)}}function OE(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"small"),e.ynx(2),e.SDv(3,35),e.BQk(),e._uU(4),e.ALo(5,"duration"),e.qZA(),e._UZ(6,"br"),e.BQk()),2&n){const t=e.oxw().$implicit;e.xp6(4),e.hij(" ",e.lcZ(5,1,t.duration)," ")}}const I1=function(n,s,t){return[n,s,t]},wE=function(n){return[n]};function Iv(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"div",7),e.TgZ(1,"div",29),e.TgZ(2,"div",13),e.TgZ(3,"div",14),e.TgZ(4,"span",7),e._UZ(5,"i",7),e._UZ(6,"i",7),e.qZA(),e.qZA(),e.TgZ(7,"div",30),e.TgZ(8,"div",17),e.TgZ(9,"button",31),e.NdJ("click",function(c){const C=e.CHM(t).index;return e.oxw(3).remove(C),c.stopPropagation()}),e._UZ(10,"i",7),e.qZA(),e.TgZ(11,"h6",18),e._uU(12),e.qZA(),e._UZ(13,"p",32),e.TgZ(14,"p",21),e.YNc(15,OE,7,3,"ng-container",24),e.TgZ(16,"small",33),e.ALo(17,"cdDate"),e._uU(18),e.ALo(19,"relativeDate"),e.qZA(),e._UZ(20,"i",34),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e._UZ(21,"hr"),e.qZA()}if(2&n){const t=s.$implicit,o=e.oxw(3);e.Q6J("ngClass",t.borderClass),e.xp6(4),e.Q6J("ngClass",e.kEZ(16,I1,o.icons.stack,o.icons.large2x,t.textClass)),e.xp6(1),e.Q6J("ngClass",e.WLB(20,oM,o.icons.circle,o.icons.stack2x)),e.xp6(1),e.Q6J("ngClass",e.kEZ(23,I1,o.icons.stack1x,o.icons.inverse,t.iconClass)),e.xp6(4),e.Q6J("ngClass",e.VKq(27,wE,o.icons.trash)),e.xp6(2),e.Oqu(t.title),e.xp6(1),e.Q6J("innerHtml",t.message,e.oJD),e.xp6(2),e.Q6J("ngIf",t.duration),e.xp6(1),e.Q6J("title",e.lcZ(17,12,t.timestamp)),e.xp6(2),e.Oqu(e.lcZ(19,14,t.timestamp)),e.xp6(2),e.Q6J("ngClass",e.VKq(29,wE,t.applicationClass))("title",t.application)}}function Lw(n,s){if(1&n){const t=e.EpF();e.ynx(0),e.TgZ(1,"button",25),e.NdJ("click",function(c){return e.CHM(t),e.oxw(2).removeAll(),c.stopPropagation()}),e._UZ(2,"i",26),e._uU(3," \xa0 "),e.ynx(4),e.SDv(5,27),e.BQk(),e.qZA(),e._UZ(6,"hr"),e.YNc(7,Iv,22,31,"div",28),e.BQk()}if(2&n){const t=e.oxw(2);e.xp6(2),e.Q6J("ngClass",e.VKq(2,wE,t.icons.trash)),e.xp6(5),e.Q6J("ngForOf",t.notifications)}}function xR(n,s){if(1&n&&e.YNc(0,Lw,8,4,"ng-container",24),2&n){const t=e.oxw();e.Q6J("ngIf",t.notifications.length>0)}}function Fw(n,s){1&n&&(e.TgZ(0,"div"),e.TgZ(1,"div",36),e.SDv(2,37),e.qZA(),e.qZA())}function og(n,s){if(1&n&&e.YNc(0,Fw,3,0,"div",24),2&n){const t=e.oxw();e.Q6J("ngIf",0===t.notifications.length&&0===t.executingTasks.length)}}function sM(n,s){1&n&&e.GkF(0)}function DR(n,s){1&n&&e.GkF(0)}function Cy(n,s){1&n&&e.GkF(0)}let kw=(()=>{class n{constructor(t,o,c,g,C,D,P,j){this.notificationService=t,this.summaryService=o,this.taskMessageService=c,this.prometheusNotificationService=g,this.authStorageService=C,this.prometheusAlertService=D,this.ngZone=P,this.cdRef=j,this.isSidebarOpened=!1,this.executingTasks=[],this.subs=new _u.w,this.icons=xo.P,this.last_task="",this.mutex=new AE,this.simplebar={autoHide:!1},this.notifications=[]}ngOnDestroy(){window.clearInterval(this.interval),window.clearTimeout(this.timeout),this.subs.unsubscribe()}ngOnInit(){this.last_task=window.localStorage.getItem("last_task");const t=this.authStorageService.getPermissions();t.prometheus.read&&t.configOpt.read&&(this.triggerPrometheusAlerts(),this.ngZone.runOutsideAngular(()=>{this.interval=window.setInterval(()=>{this.ngZone.run(()=>{this.triggerPrometheusAlerts()})},5e3)})),this.subs.add(this.notificationService.data$.subscribe(o=>{this.notifications=wr().orderBy(o,["timestamp"],["desc"]),this.cdRef.detectChanges()})),this.subs.add(this.notificationService.sidebarSubject.subscribe(o=>{this.isSidebarOpened=!o&&!this.isSidebarOpened,window.clearTimeout(this.timeout),this.timeout=window.setTimeout(()=>{this.cdRef.detectChanges()},0)})),this.subs.add(this.summaryService.subscribe(o=>{this._handleTasks(o.executing_tasks),this.mutex.acquire().then(c=>{wr().filter(o.finished_tasks,g=>!this.last_task||ai()(g.end_time).isAfter(this.last_task)).forEach(g=>{const C=this.notificationService.finishedTaskToNotification(g,g.success),D=new Cv.e(C);D.timestamp=g.end_time,D.duration=g.duration,(!this.last_task||ai()(g.end_time).isAfter(this.last_task))&&(this.last_task=g.end_time,window.localStorage.setItem("last_task",this.last_task)),this.notificationService.save(D)}),this.cdRef.detectChanges(),c()})}))}_handleTasks(t){for(const o of t)o.description=this.taskMessageService.getRunningTitle(o);this.executingTasks=t}triggerPrometheusAlerts(){this.prometheusAlertService.refresh(),this.prometheusNotificationService.refresh()}removeAll(){this.notificationService.removeAll()}remove(t){this.notificationService.remove(t)}closeSidebar(){this.isSidebarOpened=!1}trackByFn(t){return t}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(hl.g),e.Y36(Nv.J),e.Y36(rM.p),e.Y36(nM),e.Y36(vt.j),e.Y36(Bm),e.Y36(e.R0b),e.Y36(e.sBO))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-notifications-sidebar"]],hostVars:2,hostBindings:function(t,o){2&t&&e.ekj("active",o.isSidebarOpened)},decls:18,vars:6,consts:function(){let s,t,o,c,g;return s="Tasks and Notifications",t="Clear notifications",o="Remove notification",c="Duration:",g="There are no notifications.",[["tasksTpl",""],["notificationsTpl",""],["emptyTpl",""],[1,"card",3,"clickOutsideEnabled","clickOutside"],[1,"card-header"],s,["tabindex","-1","type","button",1,"close","float-right",3,"click"],[3,"ngClass"],[3,"options"],[1,"card-body"],[4,"ngTemplateOutlet"],[4,"ngFor","ngForOf","ngForTrackBy"],[1,"card","tc_task","border-0"],[1,"row","no-gutters"],[1,"col-md-2","text-center"],[1,"text-info",3,"ngClass"],[1,"col-md-9"],[1,"card-body","p-1"],[1,"card-title","bold"],[1,"mb-1"],["type","info",3,"value","striped","animated"],[1,"card-text","text-muted"],[1,"date","float-left"],[1,"float-right"],[4,"ngIf"],["type","button",1,"btn","btn-light","btn-block",3,"click"],["aria-hidden","true",3,"ngClass"],t,[3,"ngClass",4,"ngFor","ngForOf"],[1,"card","tc_notification","border-0"],[1,"col-md-10"],["title",o,1,"btn","btn-link","float-right","mt-0","pt-0",3,"click"],[1,"card-text",3,"innerHtml"],[1,"date",3,"title"],[1,"float-right","custom-icon",3,"ngClass","title"],c,[1,"message","text-center"],g]},template:function(t,o){if(1&t&&(e.YNc(0,wR,1,2,"ng-template",null,0,e.W1O),e.YNc(2,xR,1,1,"ng-template",null,1,e.W1O),e.YNc(4,og,1,1,"ng-template",null,2,e.W1O),e.TgZ(6,"div",3),e.NdJ("clickOutside",function(){return o.closeSidebar()}),e.TgZ(7,"div",4),e.ynx(8),e.SDv(9,5),e.BQk(),e.TgZ(10,"button",6),e.NdJ("click",function(){return o.closeSidebar()}),e.TgZ(11,"span"),e._UZ(12,"i",7),e.qZA(),e.qZA(),e.qZA(),e.TgZ(13,"ngx-simplebar",8),e.TgZ(14,"div",9),e.YNc(15,sM,1,0,"ng-container",10),e.YNc(16,DR,1,0,"ng-container",10),e.YNc(17,Cy,1,0,"ng-container",10),e.qZA(),e.qZA(),e.qZA()),2&t){const c=e.MAs(1),g=e.MAs(3),C=e.MAs(5);e.xp6(6),e.Q6J("clickOutsideEnabled",o.isSidebarOpened),e.xp6(6),e.Q6J("ngClass",o.icons.close),e.xp6(1),e.Q6J("options",o.simplebar),e.xp6(2),e.Q6J("ngTemplateOutlet",c),e.xp6(1),e.Q6J("ngTemplateOutlet",g),e.xp6(1),e.Q6J("ngTemplateOutlet",C)}},directives:[iM._,la.o,_.mk,Sy.M,_.tP,_.sg,ut.Ly,_.O5],pipes:[Ul.N,Tt.h,no],styles:["[_nghost-%COMP%]{bottom:10px;max-width:90vw;position:fixed;right:-350px;top:53px;transition:all .6s;width:350px;z-index:9}.active[_nghost-%COMP%]{right:20px}.card[_ngcontent-%COMP%]{height:100%}.card-body[_ngcontent-%COMP%]{padding-left:0;padding-right:5px;padding-top:3px}ngx-simplebar[_ngcontent-%COMP%]{height:calc(100% - 42.2px)}.separator[_ngcontent-%COMP%]{background-color:#e9ecef;color:#6c757d;font-size:1rem;padding:5px 12px}.btn-block[_ngcontent-%COMP%]{width:98%}.btn-link[_ngcontent-%COMP%] .fa-trash-o[_ngcontent-%COMP%]{color:#000}table[_ngcontent-%COMP%]{width:100%}.row[_ngcontent-%COMP%]{margin-left:0;margin-right:0;padding-bottom:1rem;padding-top:1rem}hr[_ngcontent-%COMP%]{margin-bottom:2px;margin-top:2px}.card-text[_ngcontent-%COMP%]{margin-right:15px}"],changeDetection:0}),n})();function $w(n,s){1&n&&e._UZ(0,"span",5)}const RR=function(n){return{running:n}},Hw=function(n){return[n]};let Uw=(()=>{class n{constructor(t,o){this.notificationService=t,this.summaryService=o,this.icons=xo.P,this.hasRunningTasks=!1,this.hasNotifications=!1,this.subs=new _u.w}ngOnInit(){this.subs.add(this.summaryService.subscribe(t=>{this.hasRunningTasks=t.executing_tasks.length>0})),this.subs.add(this.notificationService.data$.subscribe(t=>{this.hasNotifications=t.length>0}))}ngOnDestroy(){this.subs.unsubscribe()}toggleSidebar(){this.notificationService.toggleSidebar()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(hl.g),e.Y36(Nv.J))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-notifications"]],decls:5,vars:7,consts:function(){let s,t;return s="Tasks and Notifications",t="Tasks and Notifications",[["title",s,3,"ngClass","click"],[3,"ngClass"],["class","dot",4,"ngIf"],[1,"d-md-none"],t,[1,"dot"]]},template:function(t,o){1&t&&(e.TgZ(0,"a",0),e.NdJ("click",function(){return o.toggleSidebar()}),e._UZ(1,"i",1),e.YNc(2,$w,1,0,"span",2),e.TgZ(3,"span",3),e.SDv(4,4),e.qZA(),e.qZA()),2&t&&(e.Q6J("ngClass",e.VKq(3,RR,o.hasRunningTasks)),e.xp6(1),e.Q6J("ngClass",e.VKq(5,Hw,o.icons.bell)),e.xp6(1),e.Q6J("ngIf",o.hasNotifications))},directives:[_.mk,_.O5],styles:[".running[_ngcontent-%COMP%] i[_ngcontent-%COMP%]{color:#2b99a8}.running[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%]{color:#fff}a[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%]{background-color:#2b99a8;border:2px solid #374249;border-radius:50%;height:11px;position:absolute;right:17px;top:10px;width:10px}a[_ngcontent-%COMP%]:hover .dot[_ngcontent-%COMP%]{background-color:#fff;border-color:#2b99a8}"]}),n})();var Bw=i(97057);let xE=(()=>{class n{constructor(t,o,c,g){this.activeModal=t,this.summaryService=o,this.userService=c,this.authStorageService=g,this.userPermission=this.authStorageService.getPermissions().user}ngOnInit(){this.projectConstants=$i.$x,this.hostAddr=window.location.hostname,this.modalVariables=this.setVariables(),this.subs=this.summaryService.subscribe(t=>{const o=t.version.replace("ceph version ","").split(" ");this.hostAddr=t.mgr_host.replace(/(^\w+:|^)\/\//,"").replace(/\/$/,""),this.versionNumber=o[0],this.versionHash=o[1],this.versionName=o.slice(2,o.length).join(" ")})}ngOnDestroy(){this.subs.unsubscribe()}setVariables(){const t={};t.user=localStorage.getItem("dashboard_username"),t.role="user",this.userPermission.read&&this.userService.get(t.user).subscribe(c=>{t.role=c.roles});const o=(0,Bw.qY)();return t.browserName=o&&o.name?o.name:"Not detected",t.browserVersion=o&&o.version?o.version:"Not detected",t.browserOS=o&&o.os?o.os:"Not detected",t}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(ut.Kz),e.Y36(Nv.J),e.Y36(Gm.K),e.Y36(vt.j))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-about"]],decls:46,vars:13,consts:[[1,"about-container"],[1,"modal-header"],["type","button","aria-label","Close",1,"close","float-right",3,"click"],["aria-hidden","true"],[1,"modal-body"],["src","assets/Ceph_Ceph_Logo_with_text_red_white.svg",1,"ceph-logo",3,"alt"],[1,"product-versions"],[1,"modal-footer"],[1,"text-left"]],template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"div",1),e.TgZ(2,"button",2),e.NdJ("click",function(){return o.activeModal.close()}),e.TgZ(3,"span",3),e._uU(4,"\xd7"),e.qZA(),e.qZA(),e.qZA(),e.TgZ(5,"div",4),e._UZ(6,"img",5),e.TgZ(7,"h3"),e.TgZ(8,"strong"),e._uU(9),e.qZA(),e.qZA(),e.TgZ(10,"div",6),e.TgZ(11,"strong"),e._uU(12,"Version"),e.qZA(),e._UZ(13,"br"),e._uU(14),e._UZ(15,"br"),e._uU(16),e.qZA(),e._UZ(17,"br"),e.TgZ(18,"dl"),e.TgZ(19,"dt"),e._uU(20,"Ceph Manager"),e.qZA(),e.TgZ(21,"dd"),e._uU(22),e.qZA(),e.TgZ(23,"dt"),e._uU(24,"User"),e.qZA(),e.TgZ(25,"dd"),e._uU(26),e.qZA(),e.TgZ(27,"dt"),e._uU(28,"User Role"),e.qZA(),e.TgZ(29,"dd"),e._uU(30),e.qZA(),e.TgZ(31,"dt"),e._uU(32,"Browser"),e.qZA(),e.TgZ(33,"dd"),e._uU(34),e.qZA(),e.TgZ(35,"dt"),e._uU(36,"Browser Version"),e.qZA(),e.TgZ(37,"dd"),e._uU(38),e.qZA(),e.TgZ(39,"dt"),e._uU(40,"Browser OS"),e.qZA(),e.TgZ(41,"dd"),e._uU(42),e.qZA(),e.qZA(),e.qZA(),e.TgZ(43,"div",7),e.TgZ(44,"div",8),e._uU(45),e.qZA(),e.qZA(),e.qZA()),2&t&&(e.xp6(6),e.s9C("alt",o.projectConstants.organization),e.xp6(3),e.Oqu(o.projectConstants.projectName),e.xp6(5),e.AsE(" ",o.versionNumber," ",o.versionHash," "),e.xp6(2),e.hij(" ",o.versionName," "),e.xp6(6),e.Oqu(o.hostAddr),e.xp6(4),e.Oqu(o.modalVariables.user),e.xp6(4),e.Oqu(o.modalVariables.role),e.xp6(4),e.Oqu(o.modalVariables.browserName),e.xp6(4),e.Oqu(o.modalVariables.browserVersion),e.xp6(4),e.Oqu(o.modalVariables.browserOS),e.xp6(3),e.AsE(" ",o.projectConstants.copyright," ",o.projectConstants.license," "))},directives:[la.o],styles:[".about-container[_ngcontent-%COMP%]{background-color:#374249;background-image:url(ceph_background.e82dd79127290ddbe8cb.gif);background-position:right bottom;background-repeat:no-repeat;color:#fff;text-shadow:1px 1px #374249}.product-versions[_ngcontent-%COMP%]{margin-top:30px}.product-versions[_ngcontent-%COMP%] strong[_ngcontent-%COMP%]{margin-right:10px}.modal-header[_ngcontent-%COMP%]{border-bottom:0}.modal-header[_ngcontent-%COMP%] .close[_ngcontent-%COMP%]{color:#fff;font-size:2em}.modal-body[_ngcontent-%COMP%]{padding-left:80px;padding-right:80px}.ceph-logo[_ngcontent-%COMP%]{margin-bottom:30px;width:25%}.modal-footer[_ngcontent-%COMP%]{border-top:0;display:block;padding:15px 80px 35px}"]}),n})();const aM=function(n){return[n]},lM=function(n){return{disabled:n}};let uM=(()=>{class n{constructor(t,o){this.modalService=t,this.docService=o,this.icons=xo.P}ngOnInit(){this.docService.subscribeOnce("dashboard",t=>{this.docsUrl=t})}openAboutModal(){this.modalRef=this.modalService.show(xE,null,{size:"lg"})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Bl.Z),e.Y36(ZC.R))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-dashboard-help"]],decls:12,vars:7,consts:function(){let s,t,o,c,g;return s="Help",t="Help",o="documentation",c="API",g="About",[["ngbDropdown","","placement","bottom-right"],["ngbDropdownToggle","","title",s],[3,"ngClass"],[1,"d-md-none"],t,["ngbDropdownMenu",""],["ngbDropdownItem","","target","_blank",1,"text-capitalize",3,"ngClass","href"],o,["ngbDropdownItem","","routerLink","/api-docs","target","_blank"],c,["ngbDropdownItem","",3,"click"],g]},template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"a",1),e._UZ(2,"i",2),e.TgZ(3,"span",3),e.SDv(4,4),e.qZA(),e.qZA(),e.TgZ(5,"div",5),e.TgZ(6,"a",6),e.SDv(7,7),e.qZA(),e.TgZ(8,"a",8),e.SDv(9,9),e.qZA(),e.TgZ(10,"button",10),e.NdJ("click",function(){return o.openAboutModal()}),e.SDv(11,11),e.qZA(),e.qZA(),e.qZA()),2&t&&(e.xp6(2),e.Q6J("ngClass",e.VKq(3,aM,o.icons.questionCircle)),e.xp6(4),e.s9C("href",o.docsUrl,e.LSH),e.Q6J("ngClass",e.VKq(5,lM,!o.docsUrl)))},directives:[ut.jt,ut.iD,_.mk,ut.Vi,ut.TH,Bo.yS,la.o],styles:[""]}),n})();function Yw(n,s){1&n&&(e.TgZ(0,"button",9),e.SDv(1,10),e.qZA())}function NR(n,s){1&n&&(e.TgZ(0,"button",11),e.SDv(1,12),e.qZA())}const Zw=function(n){return[n]};function jw(n,s){if(1&n&&(e.TgZ(0,"div",1),e.TgZ(1,"a",2),e._UZ(2,"i",3),e.TgZ(3,"span",4),e.SDv(4,5),e.qZA(),e.qZA(),e.TgZ(5,"div",6),e.YNc(6,Yw,2,0,"button",7),e.YNc(7,NR,2,0,"button",8),e.qZA(),e.qZA()),2&n){const t=e.oxw();e.xp6(2),e.Q6J("ngClass",e.VKq(3,Zw,t.icons.deepCheck)),e.xp6(4),e.Q6J("ngIf",t.userPermission.read),e.xp6(1),e.Q6J("ngIf",t.configOptPermission.read)}}let Gw=(()=>{class n{constructor(t){this.authStorageService=t,this.icons=xo.P;const o=this.authStorageService.getPermissions();this.userPermission=o.user,this.configOptPermission=o.configOpt}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(vt.j))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-administration"]],decls:1,vars:1,consts:function(){let s,t,o,c;return s="Dashboard Settings",t="Dashboard Settings",o="User management",c="Telemetry configuration",[["ngbDropdown","","placement","bottom-right",4,"ngIf"],["ngbDropdown","","placement","bottom-right"],["ngbDropdownToggle","","title",s,1,"dropdown-toggle"],[3,"ngClass"],[1,"d-md-none"],t,["ngbDropdownMenu",""],["ngbDropdownItem","","routerLink","/user-management",4,"ngIf"],["ngbDropdownItem","","routerLink","/telemetry",4,"ngIf"],["ngbDropdownItem","","routerLink","/user-management"],o,["ngbDropdownItem","","routerLink","/telemetry"],c]},template:function(t,o){1&t&&e.YNc(0,jw,8,5,"div",0),2&t&&e.Q6J("ngIf",o.userPermission.read)},directives:[_.O5,ut.jt,ut.iD,_.mk,ut.Vi,la.o,ut.TH,Bo.rH],styles:[""]}),n})();const My=function(n){return[n]};function cM(n,s){if(1&n&&(e.TgZ(0,"button",12),e._UZ(1,"i",2),e.TgZ(2,"span"),e.SDv(3,13),e.qZA(),e.qZA()),2&n){const t=e.oxw();e.xp6(1),e.Q6J("ngClass",e.VKq(1,My,t.icons.lock))}}let dM=(()=>{class n{constructor(t,o){this.authStorageService=t,this.authService=o,this.icons=xo.P}ngOnInit(){this.username=this.authStorageService.getUsername(),this.sso=this.authStorageService.isSSO()}logout(){this.authService.logout()}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(vt.j),e.Y36(gE.e))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-identity"]],decls:15,vars:8,consts:function(){let s,t,o,c,g;return s="Logged in user",t="Logged in user",o="Signed in as " + "\ufffd#8\ufffd" + "" + "\ufffd0\ufffd" + "" + "\ufffd/#8\ufffd" + "",c="Sign out",g="Change password",[["ngbDropdown","","placement","bottom-right"],["ngbDropdownToggle","","title",s],[3,"ngClass"],[1,"d-md-none"],t,["ngbDropdownMenu",""],["ngbDropdownItem","","disabled",""],o,[1,"dropdown-divider"],["ngbDropdownItem","","routerLink","/user-profile/edit",4,"ngIf"],["ngbDropdownItem","",3,"click"],c,["ngbDropdownItem","","routerLink","/user-profile/edit"],g]},template:function(t,o){1&t&&(e.TgZ(0,"div",0),e.TgZ(1,"a",1),e._UZ(2,"i",2),e.TgZ(3,"span",3),e.SDv(4,4),e.qZA(),e.qZA(),e.TgZ(5,"div",5),e.TgZ(6,"button",6),e.tHW(7,7),e._UZ(8,"strong"),e.N_p(),e.qZA(),e._UZ(9,"li",8),e.YNc(10,cM,4,3,"button",9),e.TgZ(11,"button",10),e.NdJ("click",function(){return o.logout()}),e._UZ(12,"i",2),e.TgZ(13,"span"),e.SDv(14,11),e.qZA(),e.qZA(),e.qZA(),e.qZA()),2&t&&(e.xp6(2),e.Q6J("ngClass",e.VKq(4,My,o.icons.user)),e.xp6(6),e.pQV(o.username),e.QtT(7),e.xp6(2),e.Q6J("ngIf",!o.sso),e.xp6(2),e.Q6J("ngClass",e.VKq(6,My,o.icons.signOut)))},directives:[ut.jt,ut.iD,_.mk,ut.Vi,la.o,ut.TH,_.O5,Bo.rH],styles:[""]}),n})();function Vw(n,s){1&n&&e.GkF(0)}function zw(n,s){1&n&&e.GkF(0)}function fM(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"li",22),e._UZ(1,"cd-language-selector",23),e.qZA(),e.TgZ(2,"li",22),e.TgZ(3,"cd-notifications",24),e.NdJ("click",function(){return e.CHM(t),e.oxw().toggleRightSidebar()}),e.qZA(),e.qZA(),e.TgZ(4,"li",22),e._UZ(5,"cd-dashboard-help",23),e.qZA(),e.TgZ(6,"li",22),e._UZ(7,"cd-administration",23),e.qZA(),e.TgZ(8,"li",22),e._UZ(9,"cd-identity",23),e.qZA()}}function Ay(n,s){1&n&&(e.TgZ(0,"li",50),e.TgZ(1,"a",51),e.SDv(2,52),e.qZA(),e.qZA())}function Ww(n,s){1&n&&(e.TgZ(0,"li",53),e.TgZ(1,"a",54),e.SDv(2,55),e.qZA(),e.qZA())}function pM(n,s){1&n&&(e.TgZ(0,"li",56),e.TgZ(1,"a",57),e.SDv(2,58),e.qZA(),e.qZA())}function Oy(n,s){1&n&&(e.TgZ(0,"li",59),e.TgZ(1,"a",60),e.SDv(2,61),e.qZA(),e.qZA())}function wy(n,s){1&n&&(e.TgZ(0,"li",62),e.TgZ(1,"a",63),e.SDv(2,64),e.qZA(),e.qZA())}function L1(n,s){1&n&&(e.TgZ(0,"li",65),e.TgZ(1,"a",66),e.SDv(2,67),e.qZA(),e.qZA())}function Jw(n,s){1&n&&(e.TgZ(0,"li",68),e.TgZ(1,"a",69),e.SDv(2,70),e.qZA(),e.qZA())}function Qw(n,s){1&n&&(e.TgZ(0,"li",71),e.TgZ(1,"a",72),e.SDv(2,73),e.qZA(),e.qZA())}function PR(n,s){1&n&&(e.TgZ(0,"li",74),e.TgZ(1,"a",75),e.SDv(2,76),e.qZA(),e.qZA())}function Xw(n,s){if(1&n&&(e.TgZ(0,"small",81),e._uU(1),e.qZA()),2&n){const t=e.oxw(5);e.xp6(1),e.Oqu(t.prometheusAlertService.activeAlerts)}}function Kw(n,s){if(1&n&&(e.TgZ(0,"li",77),e.TgZ(1,"a",78),e.ynx(2),e.SDv(3,79),e.BQk(),e.YNc(4,Xw,2,1,"small",80),e.qZA(),e.qZA()),2&n){const t=e.oxw(4);e.xp6(4),e.Q6J("ngIf",t.prometheusAlertService.activeAlerts>0)}}function qw(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"li",36),e.TgZ(1,"a",37),e.NdJ("click",function(){return e.CHM(t),e.oxw(3).toggleSubMenu("cluster")}),e.ynx(2),e.SDv(3,38),e.BQk(),e.qZA(),e.TgZ(4,"ul",39),e.YNc(5,Ay,3,0,"li",40),e.YNc(6,Ww,3,0,"li",41),e.YNc(7,pM,3,0,"li",42),e.YNc(8,Oy,3,0,"li",43),e.YNc(9,wy,3,0,"li",44),e.YNc(10,L1,3,0,"li",45),e.YNc(11,Jw,3,0,"li",46),e.YNc(12,Qw,3,0,"li",47),e.YNc(13,PR,3,0,"li",48),e.YNc(14,Kw,5,1,"li",49),e.qZA(),e.qZA()}if(2&n){const t=e.oxw(3);e.xp6(1),e.uIk("aria-expanded","cluster"==t.displayedSubMenu),e.xp6(3),e.Q6J("ngbCollapse","cluster"!==t.displayedSubMenu),e.xp6(1),e.Q6J("ngIf",t.permissions.hosts.read),e.xp6(1),e.Q6J("ngIf",t.permissions.hosts.read),e.xp6(1),e.Q6J("ngIf",t.permissions.monitor.read),e.xp6(1),e.Q6J("ngIf",t.permissions.hosts.read),e.xp6(1),e.Q6J("ngIf",t.permissions.osd.read),e.xp6(1),e.Q6J("ngIf",t.permissions.configOpt.read),e.xp6(1),e.Q6J("ngIf",t.permissions.osd.read),e.xp6(1),e.Q6J("ngIf",t.permissions.configOpt.read),e.xp6(1),e.Q6J("ngIf",t.permissions.log.read),e.xp6(1),e.Q6J("ngIf",t.permissions.prometheus.read)}}function ex(n,s){1&n&&(e.TgZ(0,"li",82),e.TgZ(1,"a",83),e.SDv(2,84),e.qZA(),e.qZA())}function tx(n,s){1&n&&(e.TgZ(0,"li",91),e.TgZ(1,"a",92),e.SDv(2,93),e.qZA(),e.qZA())}function nx(n,s){if(1&n&&(e.TgZ(0,"small",98),e._uU(1),e.qZA()),2&n){const t=e.oxw(5);e.xp6(1),e.Oqu(null==t.summaryData||null==t.summaryData.rbd_mirroring?null:t.summaryData.rbd_mirroring.warnings)}}function rx(n,s){if(1&n&&(e.TgZ(0,"small",81),e._uU(1),e.qZA()),2&n){const t=e.oxw(5);e.xp6(1),e.Oqu(null==t.summaryData||null==t.summaryData.rbd_mirroring?null:t.summaryData.rbd_mirroring.errors)}}function ix(n,s){if(1&n&&(e.TgZ(0,"li",94),e.TgZ(1,"a",95),e.ynx(2),e.SDv(3,96),e.BQk(),e.YNc(4,nx,2,1,"small",97),e.YNc(5,rx,2,1,"small",80),e.qZA(),e.qZA()),2&n){const t=e.oxw(4);e.xp6(4),e.Q6J("ngIf",0!==(null==t.summaryData||null==t.summaryData.rbd_mirroring?null:t.summaryData.rbd_mirroring.warnings)),e.xp6(1),e.Q6J("ngIf",0!==(null==t.summaryData||null==t.summaryData.rbd_mirroring?null:t.summaryData.rbd_mirroring.errors))}}function ox(n,s){1&n&&(e.TgZ(0,"li",99),e.TgZ(1,"a",100),e.SDv(2,101),e.qZA(),e.qZA())}function IR(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"li",85),e.TgZ(1,"a",86),e.NdJ("click",function(){return e.CHM(t),e.oxw(3).toggleSubMenu("block")}),e.ynx(2),e.SDv(3,87),e.BQk(),e.qZA(),e.TgZ(4,"ul",39),e.YNc(5,tx,3,0,"li",88),e.YNc(6,ix,6,2,"li",89),e.YNc(7,ox,3,0,"li",90),e.qZA(),e.qZA()}if(2&n){const t=e.oxw().ngIf,o=e.oxw(2);e.xp6(1),e.Q6J("ngStyle",o.blockHealthColor()),e.uIk("aria-expanded","block"==o.displayedSubMenu),e.xp6(3),e.Q6J("ngbCollapse","block"!==o.displayedSubMenu),e.xp6(1),e.Q6J("ngIf",o.permissions.rbdImage.read&&t.rbd),e.xp6(1),e.Q6J("ngIf",o.permissions.rbdMirroring.read&&t.mirroring),e.xp6(1),e.Q6J("ngIf",o.permissions.iscsi.read&&t.iscsi)}}function sx(n,s){1&n&&(e.TgZ(0,"li",102),e.TgZ(1,"a",103),e.SDv(2,104),e.qZA(),e.qZA())}function F1(n,s){1&n&&(e.TgZ(0,"li",105),e.TgZ(1,"a",106),e.SDv(2,107),e.qZA(),e.qZA())}function ax(n,s){if(1&n){const t=e.EpF();e.TgZ(0,"li",108),e.TgZ(1,"a",37),e.NdJ("click",function(){return e.CHM(t),e.oxw(3).toggleSubMenu("rgw")}),e.ynx(2),e.SDv(3,109),e.BQk(),e.qZA(),e.TgZ(4,"ul",39),e.TgZ(5,"li",110),e.TgZ(6,"a",111),e.SDv(7,112),e.qZA(),e.qZA(),e.TgZ(8,"li",113),e.TgZ(9,"a",114),e.SDv(10,115),e.qZA(),e.qZA(),e.TgZ(11,"li",116),e.TgZ(12,"a",117),e.SDv(13,118),e.qZA(),e.qZA(),e.qZA(),e.qZA()}if(2&n){const t=e.oxw(3);e.xp6(1),e.uIk("aria-expanded","rgw"==t.displayedSubMenu),e.xp6(3),e.Q6J("ngbCollapse","rgw"!==t.displayedSubMenu)}}const lx=function(n){return[n]};function ux(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"li",26),e.TgZ(2,"a",27),e.TgZ(3,"span"),e.SDv(4,28),e.qZA(),e._uU(5,"\xa0 "),e._UZ(6,"i",29),e.ALo(7,"healthColor"),e.qZA(),e.qZA(),e.YNc(8,qw,15,12,"li",30),e.YNc(9,ex,3,0,"li",31),e.YNc(10,IR,8,6,"li",32),e.YNc(11,sx,3,0,"li",33),e.YNc(12,F1,3,0,"li",34),e.YNc(13,ax,14,2,"li",35),e.BQk()),2&n){const t=s.ngIf,o=e.oxw(2);e.xp6(6),e.Q6J("ngClass",e.VKq(10,lx,o.icons.health))("ngStyle",e.lcZ(7,8,null==o.summaryData?null:o.summaryData.health_status)),e.xp6(2),e.Q6J("ngIf",o.permissions.hosts.read||o.permissions.monitor.read||o.permissions.osd.read||o.permissions.configOpt.read||o.permissions.log.read||o.permissions.prometheus.read),e.xp6(1),e.Q6J("ngIf",o.permissions.pool.read),e.xp6(1),e.Q6J("ngIf",(o.permissions.rbdImage.read||o.permissions.rbdMirroring.read||o.permissions.iscsi.read)&&(t.rbd||t.mirroring||t.iscsi)),e.xp6(1),e.Q6J("ngIf",o.permissions.nfs.read&&t.nfs),e.xp6(1),e.Q6J("ngIf",o.permissions.cephfs.read&&t.cephfs),e.xp6(1),e.Q6J("ngIf",o.permissions.rgw.read&&t.rgw)}}function xy(n,s){if(1&n&&(e.YNc(0,ux,14,12,"ng-container",25),e.ALo(1,"async")),2&n){const t=e.oxw();e.Q6J("ngIf",e.lcZ(1,1,t.enabledFeature$))}}const zm=function(n){return{show:n}},DE=function(n){return{active:n}},cx=["*"];let LR=(()=>{class n{constructor(t,o,c,g,C,D){this.authStorageService=t,this.summaryService=o,this.featureToggles=c,this.telemetryNotificationService=g,this.prometheusAlertService=C,this.motdNotificationService=D,this.notifications=[],this.icons=xo.P,this.rightSidebarOpen=!1,this.showMenuSidebar=!0,this.displayedSubMenu="",this.simplebar={autoHide:!1},this.subs=new _u.w,this.permissions=this.authStorageService.getPermissions(),this.enabledFeature$=this.featureToggles.get()}get class(){return"top-notification-"+this.notifications.length}ngOnInit(){this.subs.add(this.summaryService.subscribe(t=>{this.summaryData=t})),this.subs.add(this.authStorageService.isPwdDisplayed$.subscribe(t=>{this.showTopNotification("isPwdDisplayed",t)})),this.subs.add(this.telemetryNotificationService.update.subscribe(t=>{this.showTopNotification("telemetryNotificationEnabled",t)})),this.subs.add(this.motdNotificationService.motd$.subscribe(t=>{this.showTopNotification("motdNotificationEnabled",uu.isPlainObject(t))}))}ngOnDestroy(){this.subs.unsubscribe()}blockHealthColor(){if(this.summaryData&&this.summaryData.rbd_mirroring){if(this.summaryData.rbd_mirroring.errors>0)return{color:"#d9534f"};if(this.summaryData.rbd_mirroring.warnings>0)return{color:"#f0ad4e"}}}toggleSubMenu(t){this.displayedSubMenu=this.displayedSubMenu===t?"":t}toggleRightSidebar(){this.rightSidebarOpen=!this.rightSidebarOpen}showTopNotification(t,o){if(o)this.notifications.includes(t)||this.notifications.push(t);else{const c=this.notifications.indexOf(t);c>=0&&this.notifications.splice(c,1)}}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(vt.j),e.Y36(Nv.J),e.Y36(fy.l),e.Y36(x1),e.Y36(Bm),e.Y36(Ty))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-navigation"]],hostVars:2,hostBindings:function(t,o){2&t&&e.Tol(o.class)},ngContentSelectors:cx,decls:30,vars:12,consts:function(){let s,t,o,c,g,C,D,P,j,W,re,oe,me,_e,Fe,Re,Le,we,U,pt,ht,Dt,Ft,cn;return s="Toggle navigation",t="Dashboard",o="Cluster",c="Hosts",g="Physical Disks",C="Monitors",D="Services",P="OSDs",j="Configuration",W="CRUSH map",re="Manager Modules",oe="Logs",me="Monitoring",_e="Pools",Fe="Block",Re="Images",Le="Mirroring",we="iSCSI",U="NFS",pt="File Systems",ht="Object Gateway",Dt="Daemons",Ft="Users",cn="Buckets",[[1,"cd-navbar-main"],[1,"cd-navbar-top"],[1,"navbar","navbar-expand-md","navbar-dark","cd-navbar-brand"],["aria-label","toggle sidebar visibility",1,"btn","btn-link","py-0",3,"click"],["aria-hidden","true",1,"fa","fa-bars","fa-2x"],["href","#",1,"navbar-brand","ml-2"],["src","assets/Ceph_Ceph_Logo_with_text_white.svg","alt","Ceph"],["type","button",1,"navbar-toggler",3,"click"],[1,"sr-only"],s,[1,""],[1,"fa","fa-navicon","fa-lg"],[1,"collapse","navbar-collapse",3,"ngClass"],[1,"nav","navbar-nav","cd-navbar-utility","my-2","my-md-0"],[4,"ngTemplateOutlet"],[1,"wrapper"],["id","sidebar",3,"ngClass"],[3,"options"],[1,"list-unstyled","components","cd-navbar-primary"],["id","content",3,"ngClass"],["cd_utilities",""],["cd_menu",""],[1,"nav-item"],[1,"cd-navbar"],[1,"cd-navbar",3,"click"],[4,"ngIf"],["routerLinkActive","active",1,"nav-item","tc_menuitem_dashboard"],["routerLink","/dashboard",1,"nav-link"],t,[3,"ngClass","ngStyle"],["routerLinkActive","active","class","nav-item tc_menuitem_cluster",4,"ngIf"],["routerLinkActive","active","class","nav-item tc_menuitem_pool",4,"ngIf"],["routerLinkActive","active","class","nav-item tc_menuitem_block",4,"ngIf"],["routerLinkActive","active","class","nav-item tc_menuitem_nfs",4,"ngIf"],["routerLinkActive","active","class","nav-item tc_menuitem_cephfs",4,"ngIf"],["routerLinkActive","active","class","nav-item tc_menuitem_rgw",4,"ngIf"],["routerLinkActive","active",1,"nav-item","tc_menuitem_cluster"],["aria-controls","collapseBasic",1,"nav-link","dropdown-toggle",3,"click"],o,[1,"list-unstyled",3,"ngbCollapse"],["routerLinkActive","active","class","tc_submenuitem tc_submenuitem_hosts",4,"ngIf"],["routerLinkActive","active","class","tc_submenuitem tc_submenuitem_cluster_inventory",4,"ngIf"],["routerLinkActive","active","class","tc_submenuitem tc_submenuitem_cluster_monitor",4,"ngIf"],["routerLinkActive","active","class","tc_submenuitem tc_submenuitem_cluster_services",4,"ngIf"],["routerLinkActive","active","class","tc_submenuitem tc_submenuitem_osds",4,"ngIf"],["routerLinkActive","active","class","tc_submenuitem tc_submenuitem_configuration",4,"ngIf"],["routerLinkActive","active","class","tc_submenuitem tc_submenuitem_crush",4,"ngIf"],["routerLinkActive","active","class","tc_submenuitem tc_submenuitem_modules",4,"ngIf"],["routerLinkActive","active","class","tc_submenuitem tc_submenuitem_log",4,"ngIf"],["routerLinkActive","active","class","tc_submenuitem tc_submenuitem_monitoring",4,"ngIf"],["routerLinkActive","active",1,"tc_submenuitem","tc_submenuitem_hosts"],["routerLink","/hosts"],c,["routerLinkActive","active",1,"tc_submenuitem","tc_submenuitem_cluster_inventory"],["routerLink","/inventory"],g,["routerLinkActive","active",1,"tc_submenuitem","tc_submenuitem_cluster_monitor"],["routerLink","/monitor/"],C,["routerLinkActive","active",1,"tc_submenuitem","tc_submenuitem_cluster_services"],["routerLink","/services/"],D,["routerLinkActive","active",1,"tc_submenuitem","tc_submenuitem_osds"],["routerLink","/osd"],P,["routerLinkActive","active",1,"tc_submenuitem","tc_submenuitem_configuration"],["routerLink","/configuration"],j,["routerLinkActive","active",1,"tc_submenuitem","tc_submenuitem_crush"],["routerLink","/crush-map"],W,["routerLinkActive","active",1,"tc_submenuitem","tc_submenuitem_modules"],["routerLink","/mgr-modules"],re,["routerLinkActive","active",1,"tc_submenuitem","tc_submenuitem_log"],["routerLink","/logs"],oe,["routerLinkActive","active",1,"tc_submenuitem","tc_submenuitem_monitoring"],["routerLink","/monitoring"],me,["class","badge badge-danger",4,"ngIf"],[1,"badge","badge-danger"],["routerLinkActive","active",1,"nav-item","tc_menuitem_pool"],["routerLink","/pool",1,"nav-link"],_e,["routerLinkActive","active",1,"nav-item","tc_menuitem_block"],["aria-controls","collapseBasic",1,"nav-link","dropdown-toggle",3,"ngStyle","click"],Fe,["routerLinkActive","active","class","tc_submenuitem tc_submenuitem_block_images",4,"ngIf"],["routerLinkActive","active","class","tc_submenuitem tc_submenuitem_block_mirroring",4,"ngIf"],["routerLinkActive","active","class","tc_submenuitem tc_submenuitem_block_iscsi",4,"ngIf"],["routerLinkActive","active",1,"tc_submenuitem","tc_submenuitem_block_images"],["routerLink","/block/rbd"],Re,["routerLinkActive","active",1,"tc_submenuitem","tc_submenuitem_block_mirroring"],["routerLink","/block/mirroring"],Le,["class","badge badge-warning",4,"ngIf"],[1,"badge","badge-warning"],["routerLinkActive","active",1,"tc_submenuitem","tc_submenuitem_block_iscsi"],["routerLink","/block/iscsi"],we,["routerLinkActive","active",1,"nav-item","tc_menuitem_nfs"],["routerLink","/nfs",1,"nav-link"],U,["routerLinkActive","active",1,"nav-item","tc_menuitem_cephfs"],["routerLink","/cephfs",1,"nav-link"],pt,["routerLinkActive","active",1,"nav-item","tc_menuitem_rgw"],ht,["routerLinkActive","active",1,"tc_submenuitem","tc_submenuitem_rgw_daemons"],["routerLink","/rgw/daemon"],Dt,["routerLinkActive","active",1,"tc_submenuitem","tc_submenuitem_rgw_users"],["routerLink","/rgw/user"],Ft,["routerLinkActive","active",1,"tc_submenuitem","tc_submenuitem_rgw_buckets"],["routerLink","/rgw/bucket"],cn]},template:function(t,o){if(1&t&&(e.F$t(),e.TgZ(0,"div",0),e._UZ(1,"cd-pwd-expiration-notification"),e._UZ(2,"cd-telemetry-notification"),e._UZ(3,"cd-motd"),e._UZ(4,"cd-notifications-sidebar"),e.TgZ(5,"div",1),e.TgZ(6,"nav",2),e.TgZ(7,"button",3),e.NdJ("click",function(){return o.showMenuSidebar=!o.showMenuSidebar}),e._UZ(8,"i",4),e.qZA(),e.TgZ(9,"a",5),e._UZ(10,"img",6),e.qZA(),e.TgZ(11,"button",7),e.NdJ("click",function(){return o.toggleRightSidebar()}),e.TgZ(12,"span",8),e.SDv(13,9),e.qZA(),e.TgZ(14,"span",10),e._UZ(15,"i",11),e.qZA(),e.qZA(),e.TgZ(16,"div",12),e.TgZ(17,"ul",13),e.YNc(18,Vw,1,0,"ng-container",14),e.qZA(),e.qZA(),e.qZA(),e.qZA(),e.TgZ(19,"div",15),e.TgZ(20,"nav",16),e.TgZ(21,"ngx-simplebar",17),e.TgZ(22,"ul",18),e.YNc(23,zw,1,0,"ng-container",14),e.qZA(),e.qZA(),e.qZA(),e.TgZ(24,"div",19),e.Hsn(25),e.qZA(),e.qZA(),e.YNc(26,fM,10,0,"ng-template",null,20,e.W1O),e.YNc(28,xy,2,3,"ng-template",null,21,e.W1O),e.qZA()),2&t){const c=e.MAs(27),g=e.MAs(29);e.xp6(16),e.Q6J("ngClass",e.VKq(6,zm,o.rightSidebarOpen)),e.xp6(2),e.Q6J("ngTemplateOutlet",c),e.xp6(2),e.Q6J("ngClass",e.VKq(8,DE,!o.showMenuSidebar)),e.xp6(1),e.Q6J("options",o.simplebar),e.xp6(2),e.Q6J("ngTemplateOutlet",g),e.xp6(1),e.Q6J("ngClass",e.VKq(10,DE,!o.showMenuSidebar))}},directives:[KC,Dw,eM,kw,ut.M2,la.o,_.mk,_.tP,Sy.M,vE,Uw,uM,Gw,dM,_.O5,Bo.Od,Bo.yS,_.PC,ut._D],pipes:[_.Ov,rE],styles:['@charset "UTF-8";.cd-navbar-main[_ngcontent-%COMP%]{display:flex;flex:1;flex-direction:column;height:100%} cd-navigation .cd-navbar-top .cd-navbar-brand{background:#374249;border-top:4px solid #2b99a8} cd-navigation .cd-navbar-top .cd-navbar-brand .navbar-brand, cd-navigation .cd-navbar-top .cd-navbar-brand .navbar-brand:hover{color:#e9ecef;height:auto;padding:0} cd-navigation .cd-navbar-top .cd-navbar-brand .navbar-brand>img{height:25px} cd-navigation .cd-navbar-top .cd-navbar-brand .navbar-toggler{border:0} cd-navigation .cd-navbar-top .cd-navbar-brand .navbar-toggler:focus, cd-navigation .cd-navbar-top .cd-navbar-brand .navbar-toggler:hover{outline:0} cd-navigation .cd-navbar-top .cd-navbar-brand .navbar-toggler .fa-navicon{color:#e9ecef} cd-navigation .cd-navbar-top .cd-navbar-brand .navbar-collapse{padding:0} cd-navigation .cd-navbar-top .cd-navbar-brand .cd-navbar-utility>.active>a{background-color:#2b99a8;color:#e9ecef} cd-navigation .cd-navbar-top .cd-navbar-brand .cd-navbar-utility>li>.open>a, cd-navigation .cd-navbar-top .cd-navbar-brand .cd-navbar-utility>li>.open>a:focus, cd-navigation .cd-navbar-top .cd-navbar-brand .cd-navbar-utility>li>.open>a:hover{background-color:transparent;border-color:transparent;color:#e9ecef} cd-navigation .cd-navbar-top .navbar-nav>li>.cd-navbar>[ngbDropdown]>a, cd-navigation .cd-navbar-top .navbar-nav>li>.cd-navbar>a, cd-navigation .cd-navbar-top .navbar-nav>li>a{color:#e9ecef;display:block;line-height:1;padding:13.5px 18px!important;position:relative;text-decoration:none} cd-navigation .cd-navbar-top .navbar-nav .nav-link, cd-navigation .cd-navbar-top .navbar-nav .nav-link:hover{color:#e9ecef} cd-navigation .cd-navbar-top .navbar-nav>li>.cd-navbar>[ngbDropdown]>a:hover, cd-navigation .cd-navbar-top .navbar-nav>li>.cd-navbar>[ngbDropdown].open>a, cd-navigation .cd-navbar-top .navbar-nav>li>.cd-navbar>a:hover, cd-navigation .cd-navbar-top .navbar-nav>li>a:hover, cd-navigation .cd-navbar-top .navbar-nav>li:hover{background-color:#2b99a8} cd-navigation .cd-navbar-top .navbar-nav>.open>.cd-navbar>[ngbDropdown]>a, cd-navigation .cd-navbar-top .navbar-nav>.open>.cd-navbar>[ngbDropdown]>a:hover, cd-navigation .cd-navbar-top .navbar-nav>.open>.cd-navbar>a, cd-navigation .cd-navbar-top .navbar-nav>.open>.cd-navbar>a:focus, cd-navigation .cd-navbar-top .navbar-nav>.open>.cd-navbar>a:hover, cd-navigation .cd-navbar-top .navbar-nav>.open>.cd-navbar>li>a:focus, cd-navigation .cd-navbar-top .navbar-nav>.open>a, cd-navigation .cd-navbar-top .navbar-nav>.open>a:focus, cd-navigation .cd-navbar-top .navbar-nav>.open>a:hover{background-color:transparent;border-color:transparent;color:#e9ecef}@media (min-width: 768px){ cd-navigation .cd-navbar-top .cd-navbar-utility{border-bottom:0;font-size:1.1rem;position:absolute;right:0;top:0}}@media (max-width: calc(768px - 1px)){ cd-navigation .cd-navbar-top .navbar-nav{margin:0} cd-navigation .cd-navbar-top .navbar-nav .fa{margin-right:.5em} cd-navigation .cd-navbar-top .navbar-nav .open .dropdown-menu{background-color:#2b99a8;border:0;padding-bottom:0;padding-top:0} cd-navigation .cd-navbar-top .navbar-nav .open .dropdown-menu>li>a{color:#e9ecef;padding:5px 15px 5px 35px} cd-navigation .cd-navbar-top .navbar-nav .open .dropdown-menu>.active>a{background-color:#2b99a8} cd-navigation .cd-navbar-top .navbar-nav>li>a:hover{background-color:#2b99a8}}.cd-navbar-primary[_ngcontent-%COMP%] .active[_ngcontent-%COMP%] > a[_ngcontent-%COMP%], .cd-navbar-primary[_ngcontent-%COMP%] > .active[_ngcontent-%COMP%] > a[_ngcontent-%COMP%]:focus, .cd-navbar-primary[_ngcontent-%COMP%] > .active[_ngcontent-%COMP%] > a[_ngcontent-%COMP%]:hover{background-color:#2b99a8!important;border:0!important;color:#e9ecef!important}.wrapper[_ngcontent-%COMP%]{display:flex;height:100%;width:100%}.wrapper[_ngcontent-%COMP%] #sidebar[_ngcontent-%COMP%]{background:#374249;bottom:0;color:#fff;height:auto;left:0;overflow-y:auto;position:relative;transition:all .3s;width:200px;z-index:999}.wrapper[_ngcontent-%COMP%] #sidebar.active[_ngcontent-%COMP%]{margin-left:-200px}.wrapper[_ngcontent-%COMP%] #sidebar[_ngcontent-%COMP%] ul.component[_ngcontent-%COMP%]{margin:0;padding:20px 0}.wrapper[_ngcontent-%COMP%] #sidebar[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{color:#fff;padding:10px}.wrapper[_ngcontent-%COMP%] #sidebar[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] li[_ngcontent-%COMP%] a[_ngcontent-%COMP%]{color:#fff;display:block;font-size:1.1em;padding:10px 10px 10px 27px;text-decoration:none}.wrapper[_ngcontent-%COMP%] #sidebar[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] li[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover{background:#2b99a8;color:#fff}.wrapper[_ngcontent-%COMP%] #sidebar[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] li[_ngcontent-%COMP%] a[_ngcontent-%COMP%] > .badge[_ngcontent-%COMP%]{margin-left:5px}.wrapper[_ngcontent-%COMP%] #sidebar[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] li.active[_ngcontent-%COMP%] > a[_ngcontent-%COMP%], .wrapper[_ngcontent-%COMP%] #sidebar[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] li[_ngcontent-%COMP%] > a[_ngcontent-%COMP%] a[aria-expanded=true][_ngcontent-%COMP%]{color:#fff}.wrapper[_ngcontent-%COMP%] a.dropdown-toggle[_ngcontent-%COMP%]{position:relative}.wrapper[_ngcontent-%COMP%] a.dropdown-toggle[_ngcontent-%COMP%]:after{border:0;content:"\\f054";font-family:"ForkAwesome";font-size:1rem;position:absolute;right:20px;transition:transform .3s ease-in-out}.wrapper[_ngcontent-%COMP%] a.dropdown-toggle[aria-expanded=true][_ngcontent-%COMP%]:after{transform:rotate(90deg)}.wrapper[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] a[_ngcontent-%COMP%]{background:#4d5c66;font-size:.9em!important;padding-left:40px!important}.wrapper[_ngcontent-%COMP%] .cd-navbar-primary[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:focus{outline:none}.wrapper[_ngcontent-%COMP%] ngx-simplebar[_ngcontent-%COMP%]{height:100%}#content[_ngcontent-%COMP%]{bottom:0;position:relative;right:0;transition:all .3s;width:calc(100% - 200px)}#content.active[_ngcontent-%COMP%]{width:100vw}']}),n})();var dx=i(17757),Dy=i(20523);function fx(n,s){if(1&n){const t=e.EpF();e.ynx(0),e.TgZ(1,"button",8),e.NdJ("click",function(){const g=e.CHM(t).$implicit;return e.oxw(3).onDaemonSelection(g)}),e._uU(2),e.qZA(),e.BQk()}if(2&n){const t=s.$implicit;e.xp6(2),e.AsE(" ",t.id," ( ",t.zonegroup_name," ) ")}}function px(n,s){if(1&n&&(e.ynx(0),e.TgZ(1,"div",1),e.TgZ(2,"span",2),e.SDv(3,3),e.qZA(),e.TgZ(4,"div",4),e.TgZ(5,"button",5),e._uU(6),e.qZA(),e.TgZ(7,"div",6),e.YNc(8,fx,3,2,"ng-container",7),e.qZA(),e.qZA(),e.qZA(),e.BQk()),2&n){const t=e.oxw().ngIf;e.xp6(6),e.AsE(" ",t.selectedDaemon.id," ( ",t.selectedDaemon.zonegroup_name," ) "),e.xp6(2),e.Q6J("ngForOf",t.daemons)}}function hM(n,s){if(1&n&&(e.ynx(0),e.YNc(1,px,9,3,"ng-container",0),e.BQk()),2&n){const t=s.ngIf,o=e.oxw();e.xp6(1),e.Q6J("ngIf",t.ftMap&&t.ftMap.rgw&&o.permissions.rgw.read&&o.isRgwRoute&&t.daemons.length>1)}}const _M=function(n,s,t){return{ftMap:n,daemons:s,selectedDaemon:t}};let RE=(()=>{class n{constructor(t,o,c,g,C){this.authStorageService=t,this.featureToggles=o,this.router=c,this.timerService=g,this.rgwDaemonService=C,this.REFRESH_INTERVAL=5e3,this.subs=new _u.w,this.rgwUrlPrefix="/rgw",this.isRgwRoute=document.location.href.includes(this.rgwUrlPrefix)}ngOnInit(){this.permissions=this.authStorageService.getPermissions(),this.featureToggleMap$=this.featureToggles.get(),this.subs.add(this.router.events.pipe((0,np.h)(t=>t instanceof Bo.m2)).subscribe(()=>this.isRgwRoute=this.router.url.startsWith(this.rgwUrlPrefix))),this.subs.add(this.timerService.get(()=>this.isRgwRoute?this.rgwDaemonService.list():dx.C,this.REFRESH_INTERVAL).subscribe())}ngOnDestroy(){this.subs.unsubscribe()}onDaemonSelection(t){this.rgwDaemonService.selectDaemon(t),this.reloadData()}reloadData(){const t=this.router.url;this.router.navigateByUrl(this.rgwUrlPrefix,{skipLocationChange:!0}).finally(()=>{this.router.navigate([t])})}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(vt.j),e.Y36(fy.l),e.Y36(Bo.F0),e.Y36(Om.f),e.Y36(Dy.b))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-context"]],decls:4,vars:11,consts:function(){let s,t;return s="Selected Object Gateway:",t="Select Object Gateway",[[4,"ngIf"],[1,"cd-context-bar","pt-3","pb-3"],[1,"mr-1"],s,["ngbDropdown","","placement","bottom-left",1,"d-inline-block","ml-2"],["ngbDropdownToggle","","title",t,1,"btn","btn-outline-info","ctx-bar-selected-rgw-daemon"],["ngbDropdownMenu",""],[4,"ngFor","ngForOf"],["ngbDropdownItem","",1,"ctx-bar-available-rgw-daemon",3,"click"]]},template:function(t,o){1&t&&(e.YNc(0,hM,2,1,"ng-container",0),e.ALo(1,"async"),e.ALo(2,"async"),e.ALo(3,"async")),2&t&&e.Q6J("ngIf",e.kEZ(7,_M,e.lcZ(1,1,o.featureToggleMap$),e.lcZ(2,3,o.rgwDaemonService.daemons$),e.lcZ(3,5,o.rgwDaemonService.selectedDaemon$)))},directives:[_.O5,ut.jt,la.o,ut.iD,ut.Vi,_.sg,ut.TH],pipes:[_.Ov],styles:[".cd-context-bar[_ngcontent-%COMP%]{border-bottom:1px solid #dee2e6}"]}),n})();var gM=i(58071),mM=i(94402),NE=i(85345);class vM{constructor(s,t){this.keySelector=s,this.flushes=t}call(s,t){return t.subscribe(new _x(s,this.keySelector,this.flushes))}}class _x extends NE.Ds{constructor(s,t,o){super(s),this.keySelector=t,this.values=new Set,o&&this.add((0,NE.ft)(o,new NE.IY(this)))}notifyNext(){this.values.clear()}notifyError(s){this._error(s)}_next(s){this.keySelector?this._useKeySelector(s):this._finalizeNext(s,s)}_useKeySelector(s){let t;const{destination:o}=this;try{t=this.keySelector(s)}catch(c){return void o.error(c)}this._finalizeNext(t,s)}_finalizeNext(s,t){const{values:o}=this;o.has(s)||(o.add(s),this.destination.next(t))}}var PE=i(28049);class Wm{resolve(s){const t=s.routeConfig.data,o=null===t.path?null:this.getFullPath(s);return(0,Vc.of)([{text:"string"==typeof t.breadcrumbs?t.breadcrumbs:t.breadcrumbs.text||t.text||o,path:o}])}getFullPath(s){return s.pathFromRoot.reduce((g,C)=>g+C.url.reduce((g,C)=>g+"/"+C.path,""),"")}}function Ry(n,s){if(1&n&&(e.TgZ(0,"a",6),e._uU(1),e.qZA()),2&n){const t=e.oxw().$implicit;e.Q6J("routerLink",t.path),e.xp6(1),e.Oqu(t.text)}}function FR(n,s){if(1&n&&(e.TgZ(0,"span"),e._uU(1),e.qZA()),2&n){const t=e.oxw().$implicit;e.xp6(1),e.Oqu(t.text)}}const k1=function(n){return{active:n}};function lc(n,s){if(1&n&&(e.TgZ(0,"li",3),e.YNc(1,Ry,2,2,"a",4),e.YNc(2,FR,2,1,"span",5),e.qZA()),2&n){const t=s.$implicit,o=s.last,c=e.oxw(2);e.Q6J("ngClass",e.VKq(3,k1,o&&c.finished)),e.xp6(1),e.Q6J("ngIf",!o&&null!==t.path),e.xp6(1),e.Q6J("ngIf",o||null===t.path)}}function sm(n,s){if(1&n&&(e.TgZ(0,"ol",1),e.YNc(1,lc,3,5,"li",2),e.qZA()),2&n){const t=e.oxw();e.xp6(1),e.Q6J("ngForOf",t.crumbs)}}let Lv=(()=>{class n{constructor(t,o){this.router=t,this.injector=o,this.crumbs=[],this.finished=!1,this.defaultResolver=new Wm,this.subscription=this.router.events.pipe((0,np.h)(c=>c instanceof Bo.OD)).subscribe(()=>{this.finished=!1}),this.subscription=this.router.events.pipe((0,np.h)(c=>c instanceof Bo.m2)).subscribe(()=>{this._resolveCrumbs(t.routerState.snapshot.root).pipe((0,Bu.zg)(g=>g),function(n,s){return t=>t.lift(new vM(n,undefined))}(g=>g.text),Hf(),(0,Bu.zg)(g=>{const C=this.postProcess(g);return this.wrapIntoObservable(C).pipe((0,PE.P)())})).subscribe(g=>{this.finished=!0,this.crumbs=g})})}ngOnDestroy(){this.subscription.unsubscribe()}_resolveCrumbs(t){let o;const c=t.routeConfig&&t.routeConfig.data;if(c&&c.breadcrumbs){let g;g=c.breadcrumbs.prototype instanceof Wm?this.injector.get(c.breadcrumbs):this.defaultResolver;const C=g.resolve(t);o=this.wrapIntoObservable(C).pipe((0,PE.P)())}else o=(0,Vc.of)([]);return t.firstChild&&(o=(0,gM.z)(o,this._resolveCrumbs(t.firstChild))),o}postProcess(t){const o=[];return t.forEach(c=>{const g=c.text.split("/");if(g.length>1){c.text=g[g.length-1];for(let C=0;C<g.length-1;C++)o.push({text:g[C],path:null})}o.push(c)}),o}isPromise(t){return t&&"function"==typeof t.then}wrapIntoObservable(t){return t instanceof Gb.y?t:this.isPromise(t)?(0,mM.D)(Promise.resolve(t)):(0,Vc.of)(t)}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Bo.F0),e.Y36(e.zs3))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-breadcrumbs"]],decls:1,vars:1,consts:[["class","breadcrumb",4,"ngIf"],[1,"breadcrumb"],["class","breadcrumb-item",3,"ngClass",4,"ngFor","ngForOf"],[1,"breadcrumb-item",3,"ngClass"],["preserveFragment","",3,"routerLink",4,"ngIf"],[4,"ngIf"],["preserveFragment","",3,"routerLink"]],template:function(t,o){1&t&&e.YNc(0,sm,2,1,"ol",0),2&t&&e.Q6J("ngIf",o.crumbs.length)},directives:[_.O5,_.sg,_.mk,Bo.yS],styles:['@charset "UTF-8";.breadcrumb[_ngcontent-%COMP%]{background-color:transparent;border-radius:0;margin-top:8px;padding:8px 0}.breadcrumb[_ngcontent-%COMP%] > li[_ngcontent-%COMP%] + li[_ngcontent-%COMP%]:before{content:"\\f101";font-family:"ForkAwesome";padding:0 5px 0 7px}']}),n})();const $1=function(n){return{dashboard:n}};let kR=(()=>{class n{constructor(t,o,c,g){this.router=t,this.summaryService=o,this.taskManagerService=c,this.faviconService=g,this.subs=new _u.w}ngOnInit(){this.subs.add(this.summaryService.startPolling()),this.subs.add(this.taskManagerService.init(this.summaryService)),this.faviconService.init()}ngOnDestroy(){this.subs.unsubscribe()}isDashboardPage(){return"/dashboard"===this.router.url}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(Bo.F0),e.Y36(Nv.J),e.Y36(Cw.k),e.Y36(bE))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-workbench-layout"]],features:[e._Bn([bE])],decls:6,vars:3,consts:[[1,"container-fluid","h-100",3,"ngClass"]],template:function(t,o){1&t&&(e.TgZ(0,"block-ui"),e.TgZ(1,"cd-navigation"),e.TgZ(2,"div",0),e._UZ(3,"cd-context"),e._UZ(4,"cd-breadcrumbs"),e._UZ(5,"router-outlet"),e.qZA(),e.qZA(),e.qZA()),2&t&&(e.xp6(2),e.Q6J("ngClass",e.VKq(1,$1,o.isDashboardPage())))},directives:[_1,LR,_.mk,RE,Lv,Bo.lC],styles:[".dashboard[_ngcontent-%COMP%]{background-color:#e9ecef;margin:0;padding:0}.container-fluid[_ngcontent-%COMP%]{overflow:auto;position:absolute}"]}),n})();var zo=i(78139),rf=i(16482),IE=i.n(rf);function sg(n){return(sg="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(s){return typeof s}:function(s){return s&&"function"==typeof Symbol&&s.constructor===Symbol&&s!==Symbol.prototype?"symbol":typeof s})(n)}function $R(n,s){if(!(n instanceof s))throw new TypeError("Cannot call a class as a function")}function LE(n,s){for(var t=0;t<s.length;t++){var o=s[t];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(n,o.key,o)}}function HR(n,s,t){return s in n?Object.defineProperty(n,s,{value:t,enumerable:!0,configurable:!0,writable:!0}):n[s]=t,n}function bM(n,s){var t=Object.keys(n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(n);s&&(o=o.filter(function(c){return Object.getOwnPropertyDescriptor(n,c).enumerable})),t.push.apply(t,o)}return t}function gx(n){for(var s=1;s<arguments.length;s++){var t=null!=arguments[s]?arguments[s]:{};s%2?bM(t,!0).forEach(function(o){HR(n,o,t[o])}):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(t)):bM(t).forEach(function(o){Object.defineProperty(n,o,Object.getOwnPropertyDescriptor(t,o))})}return n}function Xc(n){return(Xc=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(n)}function yh(n,s){return(yh=Object.setPrototypeOf||function(o,c){return o.__proto__=c,o})(n,s)}function mx(n,s){return!s||"object"!=typeof s&&"function"!=typeof s?function(n){if(void 0===n)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return n}(n):s}var FE={};function H1(n,s,t){return function(n){return null==n}(n)?t:function(n){return null!==n&&"object"===sg(n)&&"function"==typeof n.get&&"function"==typeof n.has}(n)?n.has(s)?n.get(s):t:hasOwnProperty.call(n,s)?n[s]:t}function TM(n,s,t){for(var o=0;o!==s.length;)if((n=H1(n,s[o++],FE))===FE)return t;return n}function Dg(n){var s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=vx(s,t),c=n||Object.keys(gx({},t,{},s));return c.every(o)}function vx(n,s){return function(t){if("string"==typeof t)return(0,rf.is)(s[t],n[t]);if(Array.isArray(t))return(0,rf.is)(TM(s,t),TM(n,t));throw new TypeError("Invalid key: expected Array or string: "+t)}}const U1=function(n){function s(){return $R(this,s),mx(this,Xc(s).apply(this,arguments))}return function(n,s){if("function"!=typeof s&&null!==s)throw new TypeError("Super expression must either be null or a function");n.prototype=Object.create(s&&s.prototype,{constructor:{value:n,writable:!0,configurable:!0}}),s&&yh(n,s)}(s,n),function(n,s,t){s&&LE(n.prototype,s)}(s,[{key:"shouldComponentUpdate",value:function(o){var c=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return!Dg(this.updateOnProps,this.props,o,"updateOnProps")||!Dg(this.updateOnStates,this.state,c,"updateOnStates")}}]),s}(zo.Component);function AM(n,s){if(Array.prototype.indexOf)return n.indexOf(s);for(var t=0,o=n.length;t<o;t++)if(n[t]===s)return t;return-1}function ag(n,s){for(var t=n.length-1;t>=0;t--)!0===s(n[t])&&n.splice(t,1)}function Ny(n){throw new Error("Unhandled case for value: '".concat(n,"'"))}var t,Py=function(){function n(s){void 0===s&&(s={}),this.tagName="",this.attrs={},this.innerHTML="",this.whitespaceRegex=/\s+/,this.tagName=s.tagName||"",this.attrs=s.attrs||{},this.innerHTML=s.innerHtml||s.innerHTML||""}return n.prototype.setTagName=function(s){return this.tagName=s,this},n.prototype.getTagName=function(){return this.tagName||""},n.prototype.setAttr=function(s,t){return this.getAttrs()[s]=t,this},n.prototype.getAttr=function(s){return this.getAttrs()[s]},n.prototype.setAttrs=function(s){return Object.assign(this.getAttrs(),s),this},n.prototype.getAttrs=function(){return this.attrs||(this.attrs={})},n.prototype.setClass=function(s){return this.setAttr("class",s)},n.prototype.addClass=function(s){for(var C,t=this.getClass(),o=this.whitespaceRegex,c=t?t.split(o):[],g=s.split(o);C=g.shift();)-1===AM(c,C)&&c.push(C);return this.getAttrs().class=c.join(" "),this},n.prototype.removeClass=function(s){for(var C,t=this.getClass(),o=this.whitespaceRegex,c=t?t.split(o):[],g=s.split(o);c.length&&(C=g.shift());){var D=AM(c,C);-1!==D&&c.splice(D,1)}return this.getAttrs().class=c.join(" "),this},n.prototype.getClass=function(){return this.getAttrs().class||""},n.prototype.hasClass=function(s){return-1!==(" "+this.getClass()+" ").indexOf(" "+s+" ")},n.prototype.setInnerHTML=function(s){return this.innerHTML=s,this},n.prototype.setInnerHtml=function(s){return this.setInnerHTML(s)},n.prototype.getInnerHTML=function(){return this.innerHTML||""},n.prototype.getInnerHtml=function(){return this.getInnerHTML()},n.prototype.toAnchorString=function(){var s=this.getTagName(),t=this.buildAttrsStr();return["<",s,t=t?" "+t:"",">",this.getInnerHtml(),"</",s,">"].join("")},n.prototype.buildAttrsStr=function(){if(!this.attrs)return"";var s=this.getAttrs(),t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(o+'="'+s[o]+'"');return t.join(" ")},n}(),Ly=function(){function n(s){void 0===s&&(s={}),this.newWindow=!1,this.truncate={},this.className="",this.newWindow=s.newWindow||!1,this.truncate=s.truncate||{},this.className=s.className||""}return n.prototype.build=function(s){return new Py({tagName:"a",attrs:this.createAttrs(s),innerHtml:this.processAnchorText(s.getAnchorText())})},n.prototype.createAttrs=function(s){var t={href:s.getAnchorHref()},o=this.createCssClass(s);return o&&(t.class=o),this.newWindow&&(t.target="_blank",t.rel="noopener noreferrer"),this.truncate&&this.truncate.length&&this.truncate.length<s.getAnchorText().length&&(t.title=s.getAnchorHref()),t},n.prototype.createCssClass=function(s){var t=this.className;if(t){for(var o=[t],c=s.getCssClassSuffixes(),g=0,C=c.length;g<C;g++)o.push(t+"-"+c[g]);return o.join(" ")}return""},n.prototype.processAnchorText=function(s){return this.doTruncate(s)},n.prototype.doTruncate=function(s){var t=this.truncate;if(!t||!t.length)return s;var o=t.length,c=t.location;return"smart"===c?function(n,s,t){var o,c;null==t?(t="&hellip;",c=3,o=8):(c=t.length,o=t.length);var C=function(we){var U="";return we.scheme&&we.host&&(U+=we.scheme+"://"),we.host&&(U+=we.host),we.path&&(U+="/"+we.path),we.query&&(U+="?"+we.query),we.fragment&&(U+="#"+we.fragment),U},D=function(we,U){var pt=U/2,ht=Math.ceil(pt),Dt=-1*Math.floor(pt),Ft="";return Dt<0&&(Ft=we.substr(Dt)),we.substr(0,ht)+t+Ft};if(n.length<=s)return n;var U,pt,ht,P=s-c,j=(U={},(ht=(pt=n).match(/^([a-z]+):\/\//i))&&(U.scheme=ht[1],pt=pt.substr(ht[0].length)),(ht=pt.match(/^(.*?)(?=(\?|#|\/|$))/i))&&(U.host=ht[1],pt=pt.substr(ht[0].length)),(ht=pt.match(/^\/(.*?)(?=(\?|#|$))/i))&&(U.path=ht[1],pt=pt.substr(ht[0].length)),(ht=pt.match(/^\?(.*?)(?=(#|$))/i))&&(U.query=ht[1],pt=pt.substr(ht[0].length)),(ht=pt.match(/^#(.*?)$/i))&&(U.fragment=ht[1]),U);if(j.query){var W=j.query.match(/^(.*?)(?=(\?|\#))(.*?)$/i);W&&(j.query=j.query.substr(0,W[1].length),n=C(j))}if(n.length<=s||(j.host&&(j.host=j.host.replace(/^www\./,""),n=C(j)),n.length<=s))return n;var re="";if(j.host&&(re+=j.host),re.length>=P)return j.host.length==s?(j.host.substr(0,s-c)+t).substr(0,P+o):D(re,P).substr(0,P+o);var oe="";if(j.path&&(oe+="/"+j.path),j.query&&(oe+="?"+j.query),oe){if((re+oe).length>=P)return(re+oe).length==s?(re+oe).substr(0,s):(re+D(oe,P-re.length)).substr(0,P+o);re+=oe}if(j.fragment){var _e="#"+j.fragment;if((re+_e).length>=P)return(re+_e).length==s?(re+_e).substr(0,s):(re+D(_e,P-re.length)).substr(0,P+o);re+=_e}if(j.scheme&&j.host){var Re=j.scheme+"://";if((re+Re).length<P)return(Re+re).substr(0,s)}if(re.length<=s)return re;var Le="";return P>0&&(Le=re.substr(-1*Math.floor(P/2))),(re.substr(0,Math.ceil(P/2))+t+Le).substr(0,P+o)}(s,o):"middle"===c?function(n,s,t){if(n.length<=s)return n;var o,c;null==t?(t="&hellip;",o=8,c=3):(o=t.length,c=t.length);var g=s-c,C="";return g>0&&(C=n.substr(-1*Math.floor(g/2))),(n.substr(0,Math.ceil(g/2))+t+C).substr(0,g+o)}(s,o):function(n,s,t){return function(n,s,t){var o;return n.length>s&&(null==t?(t="&hellip;",o=3):o=t.length,n=n.substring(0,s-o)+t),n}(n,s,void 0)}(s,o)},n}(),B1=function(){function n(s){this.__jsduckDummyDocProp=null,this.matchedText="",this.offset=0,this.tagBuilder=s.tagBuilder,this.matchedText=s.matchedText,this.offset=s.offset}return n.prototype.getMatchedText=function(){return this.matchedText},n.prototype.setOffset=function(s){this.offset=s},n.prototype.getOffset=function(){return this.offset},n.prototype.getCssClassSuffixes=function(){return[this.getType()]},n.prototype.buildTag=function(){return this.tagBuilder.build(this)},n}(),bx=function(n){function s(t){var o=n.call(this,t)||this;return o.email="",o.email=t.email,o}return(0,fa.ZT)(s,n),s.prototype.getType=function(){return"email"},s.prototype.getEmail=function(){return this.email},s.prototype.getAnchorHref=function(){return"mailto:"+this.email},s.prototype.getAnchorText=function(){return this.email},s}(B1),gl=function(n){function s(t){var o=n.call(this,t)||this;return o.serviceName="",o.hashtag="",o.serviceName=t.serviceName,o.hashtag=t.hashtag,o}return(0,fa.ZT)(s,n),s.prototype.getType=function(){return"hashtag"},s.prototype.getServiceName=function(){return this.serviceName},s.prototype.getHashtag=function(){return this.hashtag},s.prototype.getAnchorHref=function(){var t=this.serviceName,o=this.hashtag;switch(t){case"twitter":return"https://twitter.com/hashtag/"+o;case"facebook":return"https://www.facebook.com/hashtag/"+o;case"instagram":return"https://instagram.com/explore/tags/"+o;case"tiktok":return"https://www.tiktok.com/tag/"+o;default:throw new Error("Unknown service name to point hashtag to: "+t)}},s.prototype.getAnchorText=function(){return"#"+this.hashtag},s}(B1),Ex=function(n){function s(t){var o=n.call(this,t)||this;return o.serviceName="twitter",o.mention="",o.mention=t.mention,o.serviceName=t.serviceName,o}return(0,fa.ZT)(s,n),s.prototype.getType=function(){return"mention"},s.prototype.getMention=function(){return this.mention},s.prototype.getServiceName=function(){return this.serviceName},s.prototype.getAnchorHref=function(){switch(this.serviceName){case"twitter":return"https://twitter.com/"+this.mention;case"instagram":return"https://instagram.com/"+this.mention;case"soundcloud":return"https://soundcloud.com/"+this.mention;case"tiktok":return"https://www.tiktok.com/@"+this.mention;default:throw new Error("Unknown service name to point mention to: "+this.serviceName)}},s.prototype.getAnchorText=function(){return"@"+this.mention},s.prototype.getCssClassSuffixes=function(){var t=n.prototype.getCssClassSuffixes.call(this),o=this.getServiceName();return o&&t.push(o),t},s}(B1),$v=function(n){function s(t){var o=n.call(this,t)||this;return o.number="",o.plusSign=!1,o.number=t.number,o.plusSign=t.plusSign,o}return(0,fa.ZT)(s,n),s.prototype.getType=function(){return"phone"},s.prototype.getPhoneNumber=function(){return this.number},s.prototype.getNumber=function(){return this.getPhoneNumber()},s.prototype.getAnchorHref=function(){return"tel:"+(this.plusSign?"+":"")+this.number},s.prototype.getAnchorText=function(){return this.matchedText},s}(B1),wM=function(n){function s(t){var o=n.call(this,t)||this;return o.url="",o.urlMatchType="scheme",o.protocolUrlMatch=!1,o.protocolRelativeMatch=!1,o.stripPrefix={scheme:!0,www:!0},o.stripTrailingSlash=!0,o.decodePercentEncoding=!0,o.schemePrefixRegex=/^(https?:\/\/)?/i,o.wwwPrefixRegex=/^(https?:\/\/)?(www\.)?/i,o.protocolRelativeRegex=/^\/\//,o.protocolPrepended=!1,o.urlMatchType=t.urlMatchType,o.url=t.url,o.protocolUrlMatch=t.protocolUrlMatch,o.protocolRelativeMatch=t.protocolRelativeMatch,o.stripPrefix=t.stripPrefix,o.stripTrailingSlash=t.stripTrailingSlash,o.decodePercentEncoding=t.decodePercentEncoding,o}return(0,fa.ZT)(s,n),s.prototype.getType=function(){return"url"},s.prototype.getUrlMatchType=function(){return this.urlMatchType},s.prototype.getUrl=function(){var t=this.url;return!this.protocolRelativeMatch&&!this.protocolUrlMatch&&!this.protocolPrepended&&(t=this.url="http://"+t,this.protocolPrepended=!0),t},s.prototype.getAnchorHref=function(){return this.getUrl().replace(/&amp;/g,"&")},s.prototype.getAnchorText=function(){var t=this.getMatchedText();return this.protocolRelativeMatch&&(t=this.stripProtocolRelativePrefix(t)),this.stripPrefix.scheme&&(t=this.stripSchemePrefix(t)),this.stripPrefix.www&&(t=this.stripWwwPrefix(t)),this.stripTrailingSlash&&(t=this.removeTrailingSlash(t)),this.decodePercentEncoding&&(t=this.removePercentEncoding(t)),t},s.prototype.stripSchemePrefix=function(t){return t.replace(this.schemePrefixRegex,"")},s.prototype.stripWwwPrefix=function(t){return t.replace(this.wwwPrefixRegex,"$1")},s.prototype.stripProtocolRelativePrefix=function(t){return t.replace(this.protocolRelativeRegex,"")},s.prototype.removeTrailingSlash=function(t){return"/"===t.charAt(t.length-1)&&(t=t.slice(0,-1)),t},s.prototype.removePercentEncoding=function(t){var o=t.replace(/%22/gi,"&quot;").replace(/%26/gi,"&amp;").replace(/%27/gi,"&#39;").replace(/%3C/gi,"&lt;").replace(/%3E/gi,"&gt;");try{return decodeURIComponent(o)}catch(c){return o}},s}(B1),Hv=function(s){this.__jsduckDummyDocProp=null,this.tagBuilder=s.tagBuilder},UE=/[A-Za-z]/,UR=/[\d]/,BR=/[\D]/,Jm=/\s/,Pf=/['"]/,Tx=/[\x00-\x1F\x7F]/,xM=/A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC/.source,DM=xM+/\u2700-\u27bf\udde6-\uddff\ud800-\udbff\udc00-\udfff\ufe0e\ufe0f\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0\ud83c\udffb-\udfff\u200d\u3299\u3297\u303d\u3030\u24c2\ud83c\udd70-\udd71\udd7e-\udd7f\udd8e\udd91-\udd9a\udde6-\uddff\ude01-\ude02\ude1a\ude2f\ude32-\ude3a\ude50-\ude51\u203c\u2049\u25aa-\u25ab\u25b6\u25c0\u25fb-\u25fe\u00a9\u00ae\u2122\u2139\udc04\u2600-\u26FF\u2b05\u2b06\u2b07\u2b1b\u2b1c\u2b50\u2b55\u231a\u231b\u2328\u23cf\u23e9-\u23f3\u23f8-\u23fa\udccf\u2935\u2934\u2190-\u21ff/.source+/\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D4-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u192B\u1930-\u193B\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFB-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C5\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F/.source,Fy=/0-9\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19/.source,Cx=DM+Fy,ad=DM+Fy,Y1=new RegExp("[".concat(ad,"]")),YE="(?:["+Fy+"]{1,3}\\.){3}["+Fy+"]{1,3}",Mx="["+ad+"](?:["+ad+"\\-_]{0,61}["+ad+"])?",RM=function(n){return"(?=("+Mx+"))\\"+n},ky=function(n){return"(?:"+RM(n)+"(?:\\."+RM(n+1)+"){0,126}|"+YE+")"},$y=(new RegExp("["+ad+".\\-]*["+ad+"\\-]"),Y1),Ax=/(?:xn--vermgensberatung-pwb|xn--vermgensberater-ctb|xn--clchc0ea0b2g2a9gcd|xn--w4r85el8fhu5dnra|northwesternmutual|travelersinsurance|verm\xf6gensberatung|xn--5su34j936bgsg|xn--bck1b9a5dre4c|xn--mgbah1a3hjkrd|xn--mgbai9azgqp6j|xn--mgberp4a5d4ar|xn--xkc2dl3a5ee0h|verm\xf6gensberater|xn--fzys8d69uvgm|xn--mgba7c0bbn0a|xn--mgbcpq6gpa1a|xn--xkc2al3hye2a|americanexpress|kerryproperties|sandvikcoromant|xn--i1b6b1a6a2e|xn--kcrx77d1x4a|xn--lgbbat1ad8j|xn--mgba3a4f16a|xn--mgbaakc7dvf|xn--mgbc0a9azcg|xn--nqv7fs00ema|americanfamily|bananarepublic|cancerresearch|cookingchannel|kerrylogistics|weatherchannel|xn--54b7fta0cc|xn--6qq986b3xl|xn--80aqecdr1a|xn--b4w605ferd|xn--fiq228c5hs|xn--h2breg3eve|xn--jlq480n2rg|xn--jlq61u9w7b|xn--mgba3a3ejt|xn--mgbaam7a8h|xn--mgbayh7gpa|xn--mgbbh1a71e|xn--mgbca7dzdo|xn--mgbi4ecexp|xn--mgbx4cd0ab|xn--rvc1e0am3e|international|lifeinsurance|travelchannel|wolterskluwer|xn--cckwcxetd|xn--eckvdtc9d|xn--fpcrj9c3d|xn--fzc2c9e2c|xn--h2brj9c8c|xn--tiq49xqyj|xn--yfro4i67o|xn--ygbi2ammx|construction|lplfinancial|scholarships|versicherung|xn--3e0b707e|xn--45br5cyl|xn--4dbrk0ce|xn--80adxhks|xn--80asehdb|xn--8y0a063a|xn--gckr3f0f|xn--mgb9awbf|xn--mgbab2bd|xn--mgbgu82a|xn--mgbpl2fh|xn--mgbt3dhd|xn--mk1bu44c|xn--ngbc5azd|xn--ngbe9e0a|xn--ogbpf8fl|xn--qcka1pmc|accountants|barclaycard|blackfriday|blockbuster|bridgestone|calvinklein|contractors|creditunion|engineering|enterprises|foodnetwork|investments|kerryhotels|lamborghini|motorcycles|olayangroup|photography|playstation|productions|progressive|redumbrella|williamhill|xn--11b4c3d|xn--1ck2e1b|xn--1qqw23a|xn--2scrj9c|xn--3bst00m|xn--3ds443g|xn--3hcrj9c|xn--42c2d9a|xn--45brj9c|xn--55qw42g|xn--6frz82g|xn--80ao21a|xn--9krt00a|xn--cck2b3b|xn--czr694b|xn--d1acj3b|xn--efvy88h|xn--fct429k|xn--fjq720a|xn--flw351e|xn--g2xx48c|xn--gecrj9c|xn--gk3at1e|xn--h2brj9c|xn--hxt814e|xn--imr513n|xn--j6w193g|xn--jvr189m|xn--kprw13d|xn--kpry57d|xn--mgbbh1a|xn--mgbtx2b|xn--mix891f|xn--nyqy26a|xn--otu796d|xn--pgbs0dh|xn--q9jyb4c|xn--rhqv96g|xn--rovu88b|xn--s9brj9c|xn--ses554g|xn--t60b56a|xn--vuq861b|xn--w4rs40l|xn--xhq521b|xn--zfr164b|\u0b9a\u0bbf\u0b99\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0bc2\u0bb0\u0bcd|accountant|apartments|associates|basketball|bnpparibas|boehringer|capitalone|consulting|creditcard|cuisinella|eurovision|extraspace|foundation|healthcare|immobilien|industries|management|mitsubishi|nextdirect|properties|protection|prudential|realestate|republican|restaurant|schaeffler|tatamotors|technology|university|vlaanderen|volkswagen|xn--30rr7y|xn--3pxu8k|xn--45q11c|xn--4gbrim|xn--55qx5d|xn--5tzm5g|xn--80aswg|xn--90a3ac|xn--9dbq2a|xn--9et52u|xn--c2br7g|xn--cg4bki|xn--czrs0t|xn--czru2d|xn--fiq64b|xn--fiqs8s|xn--fiqz9s|xn--io0a7i|xn--kput3i|xn--mxtq1m|xn--o3cw4h|xn--pssy2u|xn--q7ce6a|xn--unup4y|xn--wgbh1c|xn--wgbl6a|xn--y9a3aq|accenture|alfaromeo|allfinanz|amsterdam|analytics|aquarelle|barcelona|bloomberg|christmas|community|directory|education|equipment|fairwinds|financial|firestone|fresenius|frontdoor|furniture|goldpoint|hisamitsu|homedepot|homegoods|homesense|institute|insurance|kuokgroup|lancaster|landrover|lifestyle|marketing|marshalls|melbourne|microsoft|panasonic|passagens|pramerica|richardli|shangrila|solutions|statebank|statefarm|stockholm|travelers|vacations|xn--90ais|xn--c1avg|xn--d1alf|xn--e1a4c|xn--fhbei|xn--j1aef|xn--j1amh|xn--l1acc|xn--ngbrx|xn--nqv7f|xn--p1acf|xn--qxa6a|xn--tckwe|xn--vhquv|yodobashi|\u0645\u0648\u0631\u064a\u062a\u0627\u0646\u064a\u0627|abudhabi|airforce|allstate|attorney|barclays|barefoot|bargains|baseball|boutique|bradesco|broadway|brussels|builders|business|capetown|catering|catholic|cipriani|cityeats|cleaning|clinique|clothing|commbank|computer|delivery|deloitte|democrat|diamonds|discount|discover|download|engineer|ericsson|etisalat|exchange|feedback|fidelity|firmdale|football|frontier|goodyear|grainger|graphics|guardian|hdfcbank|helsinki|holdings|hospital|infiniti|ipiranga|istanbul|jpmorgan|lighting|lundbeck|marriott|maserati|mckinsey|memorial|merckmsd|mortgage|observer|partners|pharmacy|pictures|plumbing|property|redstone|reliance|saarland|samsclub|security|services|shopping|showtime|softbank|software|stcgroup|supplies|training|vanguard|ventures|verisign|woodside|xn--90ae|xn--node|xn--p1ai|xn--qxam|yokohama|\u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629|abogado|academy|agakhan|alibaba|android|athleta|auction|audible|auspost|avianca|banamex|bauhaus|bentley|bestbuy|booking|brother|bugatti|capital|caravan|careers|channel|charity|chintai|citadel|clubmed|college|cologne|comcast|company|compare|contact|cooking|corsica|country|coupons|courses|cricket|cruises|dentist|digital|domains|exposed|express|farmers|fashion|ferrari|ferrero|finance|fishing|fitness|flights|florist|flowers|forsale|frogans|fujitsu|gallery|genting|godaddy|grocery|guitars|hamburg|hangout|hitachi|holiday|hosting|hoteles|hotmail|hyundai|ismaili|jewelry|juniper|kitchen|komatsu|lacaixa|lanxess|lasalle|latrobe|leclerc|limited|lincoln|markets|monster|netbank|netflix|network|neustar|okinawa|oldnavy|organic|origins|philips|pioneer|politie|realtor|recipes|rentals|reviews|rexroth|samsung|sandvik|schmidt|schwarz|science|shiksha|singles|staples|storage|support|surgery|systems|temasek|theater|theatre|tickets|tiffany|toshiba|trading|walmart|wanggou|watches|weather|website|wedding|whoswho|windows|winners|xfinity|yamaxun|youtube|zuerich|\u043a\u0430\u0442\u043e\u043b\u0438\u043a|\u0627\u062a\u0635\u0627\u0644\u0627\u062a|\u0627\u0644\u0628\u062d\u0631\u064a\u0646|\u0627\u0644\u062c\u0632\u0627\u0626\u0631|\u0627\u0644\u0639\u0644\u064a\u0627\u0646|\u067e\u0627\u06a9\u0633\u062a\u0627\u0646|\u0643\u0627\u062b\u0648\u0644\u064a\u0643|\u0b87\u0ba8\u0bcd\u0ba4\u0bbf\u0baf\u0bbe|abarth|abbott|abbvie|africa|agency|airbus|airtel|alipay|alsace|alstom|amazon|anquan|aramco|author|bayern|beauty|berlin|bharti|bostik|boston|broker|camera|career|casino|center|chanel|chrome|church|circle|claims|clinic|coffee|comsec|condos|coupon|credit|cruise|dating|datsun|dealer|degree|dental|design|direct|doctor|dunlop|dupont|durban|emerck|energy|estate|events|expert|family|flickr|futbol|gallup|garden|george|giving|global|google|gratis|health|hermes|hiphop|hockey|hotels|hughes|imamat|insure|intuit|jaguar|joburg|juegos|kaufen|kinder|kindle|kosher|lancia|latino|lawyer|lefrak|living|locker|london|luxury|madrid|maison|makeup|market|mattel|mobile|monash|mormon|moscow|museum|mutual|nagoya|natura|nissan|nissay|norton|nowruz|office|olayan|online|oracle|orange|otsuka|pfizer|photos|physio|pictet|quebec|racing|realty|reisen|repair|report|review|rocher|rogers|ryukyu|safety|sakura|sanofi|school|schule|search|secure|select|shouji|soccer|social|stream|studio|supply|suzuki|swatch|sydney|taipei|taobao|target|tattoo|tennis|tienda|tjmaxx|tkmaxx|toyota|travel|unicom|viajes|viking|villas|virgin|vision|voting|voyage|vuelos|walter|webcam|xihuan|yachts|yandex|zappos|\u043c\u043e\u0441\u043a\u0432\u0430|\u043e\u043d\u043b\u0430\u0439\u043d|\u0627\u0628\u0648\u0638\u0628\u064a|\u0627\u0631\u0627\u0645\u0643\u0648|\u0627\u0644\u0627\u0631\u062f\u0646|\u0627\u0644\u0645\u063a\u0631\u0628|\u0627\u0645\u0627\u0631\u0627\u062a|\u0641\u0644\u0633\u0637\u064a\u0646|\u0645\u0644\u064a\u0633\u064a\u0627|\u092d\u093e\u0930\u0924\u092e\u094d|\u0b87\u0bb2\u0b99\u0bcd\u0b95\u0bc8|\u30d5\u30a1\u30c3\u30b7\u30e7\u30f3|actor|adult|aetna|amfam|amica|apple|archi|audio|autos|azure|baidu|beats|bible|bingo|black|boats|bosch|build|canon|cards|chase|cheap|cisco|citic|click|cloud|coach|codes|crown|cymru|dabur|dance|deals|delta|drive|dubai|earth|edeka|email|epson|faith|fedex|final|forex|forum|gallo|games|gifts|gives|glass|globo|gmail|green|gripe|group|gucci|guide|homes|honda|horse|house|hyatt|ikano|irish|jetzt|koeln|kyoto|lamer|lease|legal|lexus|lilly|linde|lipsy|loans|locus|lotte|lotto|macys|mango|media|miami|money|movie|music|nexus|nikon|ninja|nokia|nowtv|omega|osaka|paris|parts|party|phone|photo|pizza|place|poker|praxi|press|prime|promo|quest|radio|rehab|reise|ricoh|rocks|rodeo|rugby|salon|sener|seven|sharp|shell|shoes|skype|sling|smart|smile|solar|space|sport|stada|store|study|style|sucks|swiss|tatar|tires|tirol|tmall|today|tokyo|tools|toray|total|tours|trade|trust|tunes|tushu|ubank|vegas|video|vodka|volvo|wales|watch|weber|weibo|works|world|xerox|yahoo|\u05d9\u05e9\u05e8\u05d0\u05dc|\u0627\u06cc\u0631\u0627\u0646|\u0628\u0627\u0632\u0627\u0631|\u0628\u06be\u0627\u0631\u062a|\u0633\u0648\u062f\u0627\u0646|\u0633\u0648\u0631\u064a\u0629|\u0647\u0645\u0631\u0627\u0647|\u092d\u093e\u0930\u094b\u0924|\u0938\u0902\u0917\u0920\u0928|\u09ac\u09be\u0982\u09b2\u09be|\u0c2d\u0c3e\u0c30\u0c24\u0c4d|\u0d2d\u0d3e\u0d30\u0d24\u0d02|\u5609\u91cc\u5927\u9152\u5e97|aarp|able|adac|aero|akdn|ally|amex|arab|army|arpa|arte|asda|asia|audi|auto|baby|band|bank|bbva|beer|best|bike|bing|blog|blue|bofa|bond|book|buzz|cafe|call|camp|care|cars|casa|case|cash|cbre|cern|chat|citi|city|club|cool|coop|cyou|data|date|dclk|deal|dell|desi|diet|dish|docs|dvag|erni|fage|fail|fans|farm|fast|fiat|fido|film|fire|fish|flir|food|ford|free|fund|game|gbiz|gent|ggee|gift|gmbh|gold|golf|goog|guge|guru|hair|haus|hdfc|help|here|hgtv|host|hsbc|icbc|ieee|imdb|immo|info|itau|java|jeep|jobs|jprs|kddi|kids|kiwi|kpmg|kred|land|lego|lgbt|lidl|life|like|limo|link|live|loan|loft|love|ltda|luxe|maif|meet|meme|menu|mini|mint|mobi|moda|moto|name|navy|news|next|nico|nike|ollo|open|page|pars|pccw|pics|ping|pink|play|plus|pohl|porn|post|prod|prof|qpon|read|reit|rent|rest|rich|room|rsvp|ruhr|safe|sale|sarl|save|saxo|scot|seat|seek|sexy|shaw|shia|shop|show|silk|sina|site|skin|sncf|sohu|song|sony|spot|star|surf|talk|taxi|team|tech|teva|tiaa|tips|town|toys|tube|vana|visa|viva|vivo|vote|voto|wang|weir|wien|wiki|wine|work|xbox|yoga|zara|zero|zone|\u0434\u0435\u0442\u0438|\u0441\u0430\u0439\u0442|\u0628\u0627\u0631\u062a|\u0628\u064a\u062a\u0643|\u0680\u0627\u0631\u062a|\u062a\u0648\u0646\u0633|\u0634\u0628\u0643\u0629|\u0639\u0631\u0627\u0642|\u0639\u0645\u0627\u0646|\u0645\u0648\u0642\u0639|\u092d\u093e\u0930\u0924|\u09ad\u09be\u09b0\u09a4|\u09ad\u09be\u09f0\u09a4|\u0a2d\u0a3e\u0a30\u0a24|\u0aad\u0abe\u0ab0\u0aa4|\u0b2d\u0b3e\u0b30\u0b24|\u0cad\u0cbe\u0cb0\u0ca4|\u0dbd\u0d82\u0d9a\u0dcf|\u30a2\u30de\u30be\u30f3|\u30b0\u30fc\u30b0\u30eb|\u30af\u30e9\u30a6\u30c9|\u30dd\u30a4\u30f3\u30c8|\u7ec4\u7ec7\u673a\u6784|\u96fb\u8a0a\u76c8\u79d1|\u9999\u683c\u91cc\u62c9|aaa|abb|abc|aco|ads|aeg|afl|aig|anz|aol|app|art|aws|axa|bar|bbc|bbt|bcg|bcn|bet|bid|bio|biz|bms|bmw|bom|boo|bot|box|buy|bzh|cab|cal|cam|car|cat|cba|cbn|cbs|ceo|cfa|cfd|com|cpa|crs|dad|day|dds|dev|dhl|diy|dnp|dog|dot|dtv|dvr|eat|eco|edu|esq|eus|fan|fit|fly|foo|fox|frl|ftr|fun|fyi|gal|gap|gay|gdn|gea|gle|gmo|gmx|goo|gop|got|gov|hbo|hiv|hkt|hot|how|ibm|ice|icu|ifm|inc|ing|ink|int|ist|itv|jcb|jio|jll|jmp|jnj|jot|joy|kfh|kia|kim|kpn|krd|lat|law|lds|llc|llp|lol|lpl|ltd|man|map|mba|med|men|mil|mit|mlb|mls|mma|moe|moi|mom|mov|msd|mtn|mtr|nab|nba|nec|net|new|nfl|ngo|nhk|now|nra|nrw|ntt|nyc|obi|one|ong|onl|ooo|org|ott|ovh|pay|pet|phd|pid|pin|pnc|pro|pru|pub|pwc|red|ren|ril|rio|rip|run|rwe|sap|sas|sbi|sbs|sca|scb|ses|sew|sex|sfr|ski|sky|soy|spa|srl|stc|tab|tax|tci|tdk|tel|thd|tjx|top|trv|tui|tvs|ubs|uno|uol|ups|vet|vig|vin|vip|wed|win|wme|wow|wtc|wtf|xin|xxx|xyz|you|yun|zip|\u0431\u0435\u043b|\u043a\u043e\u043c|\u049b\u0430\u0437|\u043c\u043a\u0434|\u043c\u043e\u043d|\u043e\u0440\u0433|\u0440\u0443\u0441|\u0441\u0440\u0431|\u0443\u043a\u0440|\u0570\u0561\u0575|\u05e7\u05d5\u05dd|\u0639\u0631\u0628|\u0642\u0637\u0631|\u0643\u0648\u0645|\u0645\u0635\u0631|\u0915\u0949\u092e|\u0928\u0947\u091f|\u0e04\u0e2d\u0e21|\u0e44\u0e17\u0e22|\u0ea5\u0eb2\u0ea7|\u30b9\u30c8\u30a2|\u30bb\u30fc\u30eb|\u307f\u3093\u306a|\u4e2d\u6587\u7f51|\u4e9a\u9a6c\u900a|\u5929\u4e3b\u6559|\u6211\u7231\u4f60|\u65b0\u52a0\u5761|\u6de1\u9a6c\u9521|\u8bfa\u57fa\u4e9a|\u98de\u5229\u6d66|ac|ad|ae|af|ag|ai|al|am|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw|\u03b5\u03bb|\u03b5\u03c5|\u0431\u0433|\u0435\u044e|\u0440\u0444|\u10d2\u10d4|\ub2f7\ub137|\ub2f7\ucef4|\uc0bc\uc131|\ud55c\uad6d|\u30b3\u30e0|\u4e16\u754c|\u4e2d\u4fe1|\u4e2d\u56fd|\u4e2d\u570b|\u4f01\u4e1a|\u4f5b\u5c71|\u4fe1\u606f|\u5065\u5eb7|\u516b\u5366|\u516c\u53f8|\u516c\u76ca|\u53f0\u6e7e|\u53f0\u7063|\u5546\u57ce|\u5546\u5e97|\u5546\u6807|\u5609\u91cc|\u5728\u7ebf|\u5927\u62ff|\u5a31\u4e50|\u5bb6\u96fb|\u5e7f\u4e1c|\u5fae\u535a|\u6148\u5584|\u624b\u673a|\u62db\u8058|\u653f\u52a1|\u653f\u5e9c|\u65b0\u95fb|\u65f6\u5c1a|\u66f8\u7c4d|\u673a\u6784|\u6e38\u620f|\u6fb3\u9580|\u70b9\u770b|\u79fb\u52a8|\u7f51\u5740|\u7f51\u5e97|\u7f51\u7ad9|\u7f51\u7edc|\u8054\u901a|\u8c37\u6b4c|\u8d2d\u7269|\u901a\u8ca9|\u96c6\u56e2|\u98df\u54c1|\u9910\u5385|\u9999\u6e2f)/,Ox=new RegExp("[".concat(ad,"!#$%&'*+/=?^_`{|}~-]")),wx=new RegExp("^".concat(Ax.source,"$")),PM=function(n){function s(){var t=null!==n&&n.apply(this,arguments)||this;return t.localPartCharRegex=Ox,t.strictTldRegex=wx,t}return(0,fa.ZT)(s,n),s.prototype.parseMatches=function(t){for(var o=this.tagBuilder,c=this.localPartCharRegex,g=this.strictTldRegex,C=[],D=t.length,P=new Hy,j={m:"a",a:"i",i:"l",l:"t",t:"o",o:":"},W=0,re=0,oe=P;W<D;){var me=t.charAt(W);switch(re){case 0:"m"===(kt=me)?Dt(1):c.test(kt)&&Dt();break;case 1:Fe(t.charAt(W-1),me);break;case 2:Re(me);break;case 3:Le(me);break;case 4:we(me);break;case 5:U(me);break;case 6:pt(me);break;case 7:ht(me);break;default:Ny(re)}W++}var kt;return cn(),C;function Fe(kt,wn){":"===kt?c.test(wn)?(re=2,oe=new Hy((0,fa.pi)((0,fa.pi)({},oe),{hasMailtoPrefix:!0}))):Ft():j[kt]===wn||(c.test(wn)?re=2:"."===wn?re=3:"@"===wn?re=4:Ft())}function Re(kt){"."===kt?re=3:"@"===kt?re=4:c.test(kt)||Ft()}function Le(kt){"."===kt||"@"===kt?Ft():c.test(kt)?re=2:Ft()}function we(kt){$y.test(kt)?re=5:Ft()}function U(kt){"."===kt?re=7:"-"===kt?re=6:$y.test(kt)||cn()}function pt(kt){"-"===kt||"."===kt?cn():$y.test(kt)?re=5:cn()}function ht(kt){"."===kt||"-"===kt?cn():$y.test(kt)?(re=5,oe=new Hy((0,fa.pi)((0,fa.pi)({},oe),{hasDomainDot:!0}))):cn()}function Dt(kt){void 0===kt&&(kt=2),re=kt,oe=new Hy({idx:W})}function Ft(){re=0,oe=P}function cn(){if(oe.hasDomainDot){var kt=t.slice(oe.idx,W);/[-.]$/.test(kt)&&(kt=kt.slice(0,-1));var wn=oe.hasMailtoPrefix?kt.slice("mailto:".length):kt;Nr=(wn.split(".").pop()||"").toLowerCase(),g.test(Nr)&&C.push(new bx({tagBuilder:o,matchedText:kt,offset:oe.idx,email:wn}))}var Nr;Ft()}},s}(Hv),Hy=function(s){void 0===s&&(s={}),this.idx=void 0!==s.idx?s.idx:-1,this.hasMailtoPrefix=!!s.hasMailtoPrefix,this.hasDomainDot=!!s.hasDomainDot},xx=function(){function n(){}return n.isValid=function(s,t){return!(t&&!this.isValidUriScheme(t)||this.urlMatchDoesNotHaveProtocolOrDot(s,t)||this.urlMatchDoesNotHaveAtLeastOneWordChar(s,t)&&!this.isValidIpAddress(s)||this.containsMultipleDots(s))},n.isValidIpAddress=function(s){var t=new RegExp(this.hasFullProtocolRegex.source+this.ipRegex.source);return null!==s.match(t)},n.containsMultipleDots=function(s){var t=s;return this.hasFullProtocolRegex.test(s)&&(t=s.split("://")[1]),t.split("/")[0].indexOf("..")>-1},n.isValidUriScheme=function(s){var t=s.match(this.uriSchemeRegex),o=t&&t[0].toLowerCase();return"javascript:"!==o&&"vbscript:"!==o},n.urlMatchDoesNotHaveProtocolOrDot=function(s,t){return!(!s||t&&this.hasFullProtocolRegex.test(t)||-1!==s.indexOf("."))},n.urlMatchDoesNotHaveAtLeastOneWordChar=function(s,t){return!(!s||!t||this.hasFullProtocolRegex.test(t)||this.hasWordCharAfterProtocolRegex.test(s))},n.hasFullProtocolRegex=/^[A-Za-z][-.+A-Za-z0-9]*:\/\//,n.uriSchemeRegex=/^[A-Za-z][-.+A-Za-z0-9]*:/,n.hasWordCharAfterProtocolRegex=new RegExp(":[^\\s]*?["+xM+"]"),n.ipRegex=/[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?(:[0-9]*)?\/?$/,n}(),Dx=(t=new RegExp("[/?#](?:["+ad+"\\-+&@#/%=~_()|'$*\\[\\]{}?!:,.;^\u2713]*["+ad+"\\-+&@#/%=~_()|'$*\\[\\]{}\u2713])?"),new RegExp(["(?:","(",/(?:[A-Za-z][-.+A-Za-z0-9]{0,63}:(?![A-Za-z][-.+A-Za-z0-9]{0,63}:\/\/)(?!\d+\/?)(?:\/\/)?)/.source,ky(2),")","|","(","(//)?",/(?:www\.)/.source,ky(6),")","|","(","(//)?",ky(10)+"\\.",Ax.source,"(?![-"+Cx+"])",")",")","(?::[0-9]+)?","(?:"+t.source+")?"].join(""),"gi")),Z1=new RegExp("["+ad+"]"),IM=function(n){function s(t){var o=n.call(this,t)||this;return o.stripPrefix={scheme:!0,www:!0},o.stripTrailingSlash=!0,o.decodePercentEncoding=!0,o.matcherRegex=Dx,o.wordCharRegExp=Z1,o.stripPrefix=t.stripPrefix,o.stripTrailingSlash=t.stripTrailingSlash,o.decodePercentEncoding=t.decodePercentEncoding,o}return(0,fa.ZT)(s,n),s.prototype.parseMatches=function(t){for(var j,o=this.matcherRegex,c=this.stripPrefix,g=this.stripTrailingSlash,C=this.decodePercentEncoding,D=this.tagBuilder,P=[],W=function(){var oe=j[0],me=j[1],_e=j[4],Le=j.index,we=j[5]||j[9],U=t.charAt(Le-1);if(!xx.isValid(oe,me)||Le>0&&"@"===U||Le>0&&we&&re.wordCharRegExp.test(U))return"continue";if(/\?$/.test(oe)&&(oe=oe.substr(0,oe.length-1)),re.matchHasUnbalancedClosingParen(oe))oe=oe.substr(0,oe.length-1);else{var pt=re.matchHasInvalidCharAfterTld(oe,me);pt>-1&&(oe=oe.substr(0,pt))}var ht=["http://","https://"].find(function(kt){return!!me&&-1!==me.indexOf(kt)});if(ht){var Dt=oe.indexOf(ht);oe=oe.substr(Dt),me=me.substr(Dt),Le+=Dt}P.push(new wM({tagBuilder:D,matchedText:oe,offset:Le,urlMatchType:me?"scheme":_e?"www":"tld",url:oe,protocolUrlMatch:!!me,protocolRelativeMatch:!!we,stripPrefix:c,stripTrailingSlash:g,decodePercentEncoding:C}))},re=this;null!==(j=o.exec(t));)W();return P},s.prototype.matchHasUnbalancedClosingParen=function(t){var c,o=t.charAt(t.length-1);if(")"===o)c="(";else if("]"===o)c="[";else{if("}"!==o)return!1;c="{"}for(var g=0,C=0,D=t.length-1;C<D;C++){var P=t.charAt(C);P===c?g++:P===o&&(g=Math.max(g-1,0))}return 0===g},s.prototype.matchHasInvalidCharAfterTld=function(t,o){if(!t)return-1;var c=0;o&&(c=t.indexOf(":"),t=t.slice(c));var C=new RegExp("^((.?//)?[-."+ad+"]*[-"+ad+"]\\.[-"+ad+"]+)").exec(t);return null===C?-1:(c+=C[1].length,t=t.slice(C[1].length),/^[^-.A-Za-z0-9:\/?#]/.test(t)?c:-1)},s}(Hv),LM=new RegExp("[_".concat(ad,"]")),ZE=function(n){function s(t){var o=n.call(this,t)||this;return o.serviceName="twitter",o.serviceName=t.serviceName,o}return(0,fa.ZT)(s,n),s.prototype.parseMatches=function(t){for(var o=this.tagBuilder,c=this.serviceName,g=[],C=t.length,D=0,P=-1,j=0;D<C;){var W=t.charAt(D);switch(j){case 0:"#"===(Re=W)?(j=2,P=D):Y1.test(Re)&&(j=1);break;case 1:oe(W);break;case 2:me(W);break;case 3:_e(W);break;default:Ny(j)}D++}var Re;return Fe(),g;function oe(Re){Y1.test(Re)||(j=0)}function me(Re){j=LM.test(Re)?3:Y1.test(Re)?1:0}function _e(Re){LM.test(Re)||(Fe(),P=-1,j=Y1.test(Re)?1:0)}function Fe(){if(P>-1&&D-P<=140){var Re=t.slice(P,D),Le=new gl({tagBuilder:o,matchedText:Re,offset:P,serviceName:c,hashtag:Re.slice(1)});g.push(Le)}}},s}(Hv),j1=["twitter","facebook","instagram","tiktok"],Rx=new RegExp("".concat(/(?:(?:(?:(\+)?\d{1,3}[-\040.]?)?\(?\d{3}\)?[-\040.]?\d{3}[-\040.]?\d{4})|(?:(\+)(?:9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)[-\040.]?(?:\d[-\040.]?){6,12}\d+))([,;]+[0-9]+#?)*/.source,"|").concat(/(0([1-9]{1}-?[1-9]\d{3}|[1-9]{2}-?\d{3}|[1-9]{2}\d{1}-?\d{2}|[1-9]{2}\d{2}-?\d{1})-?\d{4}|0[789]0-?\d{4}-?\d{4}|050-?\d{4}-?\d{4})/.source),"g"),kM=function(n){function s(){var t=null!==n&&n.apply(this,arguments)||this;return t.matcherRegex=Rx,t}return(0,fa.ZT)(s,n),s.prototype.parseMatches=function(t){for(var C,o=this.matcherRegex,c=this.tagBuilder,g=[];null!==(C=o.exec(t));){var D=C[0],P=D.replace(/[^0-9,;#]/g,""),j=!(!C[1]&&!C[2]),W=0==C.index?"":t.substr(C.index-1,1),re=t.substr(C.index+D.length,1),oe=!W.match(/\d/)&&!re.match(/\d/);this.testMatch(C[3])&&this.testMatch(D)&&oe&&g.push(new $v({tagBuilder:c,matchedText:D,offset:C.index,number:P,plusSign:j}))}return g},s.prototype.testMatch=function(t){return BR.test(t)},s}(Hv),Nx=new RegExp("@[_".concat(ad,"]{1,50}(?![_").concat(ad,"])"),"g"),Px=new RegExp("@[_.".concat(ad,"]{1,30}(?![_").concat(ad,"])"),"g"),Ix=new RegExp("@[-_.".concat(ad,"]{1,50}(?![-_").concat(ad,"])"),"g"),$M=new RegExp("@[_.".concat(ad,"]{1,23}[_").concat(ad,"](?![_").concat(ad,"])"),"g"),Lx=new RegExp("[^"+ad+"]"),HM=function(n){function s(t){var o=n.call(this,t)||this;return o.serviceName="twitter",o.matcherRegexes={twitter:Nx,instagram:Px,soundcloud:Ix,tiktok:$M},o.nonWordCharRegex=Lx,o.serviceName=t.serviceName,o}return(0,fa.ZT)(s,n),s.prototype.parseMatches=function(t){var P,o=this.serviceName,c=this.matcherRegexes[this.serviceName],g=this.nonWordCharRegex,C=this.tagBuilder,D=[];if(!c)return D;for(;null!==(P=c.exec(t));){var j=P.index,W=t.charAt(j-1);if(0===j||g.test(W)){var re=P[0].replace(/\.+$/g,""),oe=re.slice(1);D.push(new Ex({tagBuilder:C,matchedText:re,offset:j,serviceName:o,mention:oe}))}}return D},s}(Hv);var Rg=function(s){void 0===s&&(s={}),this.idx=void 0!==s.idx?s.idx:-1,this.type=s.type||"tag",this.name=s.name||"",this.isOpening=!!s.isOpening,this.isClosing=!!s.isClosing};const Fx=function(){function n(s){void 0===s&&(s={}),this.version=n.version,this.urls={},this.email=!0,this.phone=!0,this.hashtag=!1,this.mention=!1,this.newWindow=!0,this.stripPrefix={scheme:!0,www:!0},this.stripTrailingSlash=!0,this.decodePercentEncoding=!0,this.truncate={length:0,location:"end"},this.className="",this.replaceFn=null,this.context=void 0,this.sanitizeHtml=!1,this.matchers=null,this.tagBuilder=null,this.urls=this.normalizeUrlsCfg(s.urls),this.email="boolean"==typeof s.email?s.email:this.email,this.phone="boolean"==typeof s.phone?s.phone:this.phone,this.hashtag=s.hashtag||this.hashtag,this.mention=s.mention||this.mention,this.newWindow="boolean"==typeof s.newWindow?s.newWindow:this.newWindow,this.stripPrefix=this.normalizeStripPrefixCfg(s.stripPrefix),this.stripTrailingSlash="boolean"==typeof s.stripTrailingSlash?s.stripTrailingSlash:this.stripTrailingSlash,this.decodePercentEncoding="boolean"==typeof s.decodePercentEncoding?s.decodePercentEncoding:this.decodePercentEncoding,this.sanitizeHtml=s.sanitizeHtml||!1;var t=this.mention;if(!1!==t&&-1===["twitter","instagram","soundcloud","tiktok"].indexOf(t))throw new Error("invalid `mention` cfg '".concat(t,"' - see docs"));var o=this.hashtag;if(!1!==o&&-1===j1.indexOf(o))throw new Error("invalid `hashtag` cfg '".concat(o,"' - see docs"));this.truncate=this.normalizeTruncateCfg(s.truncate),this.className=s.className||this.className,this.replaceFn=s.replaceFn||this.replaceFn,this.context=s.context||this}return n.link=function(s,t){return new n(t).link(s)},n.parse=function(s,t){return new n(t).parse(s)},n.prototype.normalizeUrlsCfg=function(s){return null==s&&(s=!0),"boolean"==typeof s?{schemeMatches:s,wwwMatches:s,tldMatches:s}:{schemeMatches:"boolean"!=typeof s.schemeMatches||s.schemeMatches,wwwMatches:"boolean"!=typeof s.wwwMatches||s.wwwMatches,tldMatches:"boolean"!=typeof s.tldMatches||s.tldMatches}},n.prototype.normalizeStripPrefixCfg=function(s){return null==s&&(s=!0),"boolean"==typeof s?{scheme:s,www:s}:{scheme:"boolean"!=typeof s.scheme||s.scheme,www:"boolean"!=typeof s.www||s.www}},n.prototype.normalizeTruncateCfg=function(s){return"number"==typeof s?{length:s,location:"end"}:function(n,s){for(var t in s)s.hasOwnProperty(t)&&void 0===n[t]&&(n[t]=s[t]);return n}(s||{},{length:Number.POSITIVE_INFINITY,location:"end"})},n.prototype.parse=function(s){var t=this,o=["a","style","script"],c=0,g=[];return function(n,s){for(var t=s.onOpenTag,o=s.onCloseTag,c=s.onText,g=s.onComment,C=s.onDoctype,D=new Rg,P=0,j=n.length,W=0,re=0,oe=D;P<j;){var me=n.charAt(P);switch(W){case 0:"<"===me&&bn();break;case 1:"!"===(Xr=me)?W=13:"/"===Xr?(W=2,oe=new Rg((0,fa.pi)((0,fa.pi)({},oe),{isClosing:!0}))):"<"===Xr?bn():UE.test(Xr)?(W=3,oe=new Rg((0,fa.pi)((0,fa.pi)({},oe),{isOpening:!0}))):(W=0,oe=D);break;case 2:Le(me);break;case 3:Re(me);break;case 4:we(me);break;case 5:U(me);break;case 6:pt(me);break;case 7:ht(me);break;case 8:Dt(me);break;case 9:Ft(me);break;case 10:cn(me);break;case 11:kt(me);break;case 12:wn(me);break;case 13:"--"===n.substr(P,2)?(P+=2,oe=new Rg((0,fa.pi)((0,fa.pi)({},oe),{type:"comment"})),W=14):"DOCTYPE"===n.substr(P,7).toUpperCase()?(P+=7,oe=new Rg((0,fa.pi)((0,fa.pi)({},oe),{type:"doctype"})),W=20):Wn();break;case 14:Hr(me);break;case 15:sr(me);break;case 16:Nr(me);break;case 17:xr(me);break;case 18:fn(me);break;case 19:Rn(me);break;case 20:kn(me);break;default:Ny(W)}P++}var Xr;function Re(Xr){Jm.test(Xr)?(oe=new Rg((0,fa.pi)((0,fa.pi)({},oe),{name:oi()})),W=4):"<"===Xr?bn():"/"===Xr?(oe=new Rg((0,fa.pi)((0,fa.pi)({},oe),{name:oi()})),W=12):">"===Xr?(oe=new Rg((0,fa.pi)((0,fa.pi)({},oe),{name:oi()})),jr()):!UE.test(Xr)&&!UR.test(Xr)&&":"!==Xr&&Wn()}function Le(Xr){">"===Xr?Wn():UE.test(Xr)?W=3:Wn()}function we(Xr){Jm.test(Xr)||("/"===Xr?W=12:">"===Xr?jr():"<"===Xr?bn():"="===Xr||Pf.test(Xr)||Tx.test(Xr)?Wn():W=5)}function U(Xr){Jm.test(Xr)?W=6:"/"===Xr?W=12:"="===Xr?W=7:">"===Xr?jr():"<"===Xr?bn():Pf.test(Xr)&&Wn()}function pt(Xr){Jm.test(Xr)||("/"===Xr?W=12:"="===Xr?W=7:">"===Xr?jr():"<"===Xr?bn():Pf.test(Xr)?Wn():W=5)}function ht(Xr){Jm.test(Xr)||('"'===Xr?W=8:"'"===Xr?W=9:/[>=`]/.test(Xr)?Wn():"<"===Xr?bn():W=10)}function Dt(Xr){'"'===Xr&&(W=11)}function Ft(Xr){"'"===Xr&&(W=11)}function cn(Xr){Jm.test(Xr)?W=4:">"===Xr?jr():"<"===Xr&&bn()}function kt(Xr){Jm.test(Xr)?W=4:"/"===Xr?W=12:">"===Xr?jr():"<"===Xr?bn():(W=4,P--)}function wn(Xr){">"===Xr?(oe=new Rg((0,fa.pi)((0,fa.pi)({},oe),{isClosing:!0})),jr()):W=4}function Hr(Xr){"-"===Xr?W=15:">"===Xr?Wn():W=16}function sr(Xr){"-"===Xr?W=18:">"===Xr?Wn():W=16}function Nr(Xr){"-"===Xr&&(W=17)}function xr(Xr){W="-"===Xr?18:16}function fn(Xr){">"===Xr?jr():"!"===Xr?W=19:"-"===Xr||(W=16)}function Rn(Xr){"-"===Xr?W=17:">"===Xr?jr():W=16}function kn(Xr){">"===Xr?jr():"<"===Xr&&bn()}function Wn(){W=0,oe=D}function bn(){W=1,oe=new Rg({idx:P})}function jr(){var Xr=n.slice(re,oe.idx);Xr&&c(Xr,re),"comment"===oe.type?g(oe.idx):"doctype"===oe.type?C(oe.idx):(oe.isOpening&&t(oe.name,oe.idx),oe.isClosing&&o(oe.name,oe.idx)),Wn(),re=P+1}function oi(){return n.slice(oe.idx+(oe.isClosing?2:1),P).toLowerCase()}re<P&&function(){var Xr=n.slice(re,P);c(Xr,re),re=P+1}()}(s,{onOpenTag:function(C){o.indexOf(C)>=0&&c++},onText:function(C,D){if(0===c){var j=function(n,s){if(!s.global)throw new Error("`splitRegex` must have the 'g' flag set");for(var c,t=[],o=0;c=s.exec(n);)t.push(n.substring(o,c.index)),t.push(c[0]),o=c.index+c[0].length;return t.push(n.substring(o)),t}(C,/(&nbsp;|&#160;|&lt;|&#60;|&gt;|&#62;|&quot;|&#34;|&#39;)/gi),W=D;j.forEach(function(re,oe){if(oe%2==0){var me=t.parseText(re,W);g.push.apply(g,me)}W+=re.length})}},onCloseTag:function(C){o.indexOf(C)>=0&&(c=Math.max(c-1,0))},onComment:function(C){},onDoctype:function(C){}}),g=this.compactMatches(g),g=this.removeUnwantedMatches(g)},n.prototype.compactMatches=function(s){s.sort(function(P,j){return P.getOffset()-j.getOffset()});for(var t=0;t<s.length-1;){var o=s[t],c=o.getOffset(),g=o.getMatchedText().length,C=c+g;if(t+1<s.length){if(s[t+1].getOffset()===c){var D=s[t+1].getMatchedText().length>g?t:t+1;s.splice(D,1);continue}if(s[t+1].getOffset()<C){s.splice(t+1,1);continue}}t++}return s},n.prototype.removeUnwantedMatches=function(s){return this.hashtag||ag(s,function(t){return"hashtag"===t.getType()}),this.email||ag(s,function(t){return"email"===t.getType()}),this.phone||ag(s,function(t){return"phone"===t.getType()}),this.mention||ag(s,function(t){return"mention"===t.getType()}),this.urls.schemeMatches||ag(s,function(t){return"url"===t.getType()&&"scheme"===t.getUrlMatchType()}),this.urls.wwwMatches||ag(s,function(t){return"url"===t.getType()&&"www"===t.getUrlMatchType()}),this.urls.tldMatches||ag(s,function(t){return"url"===t.getType()&&"tld"===t.getUrlMatchType()}),s},n.prototype.parseText=function(s,t){void 0===t&&(t=0),t=t||0;for(var o=this.getMatchers(),c=[],g=0,C=o.length;g<C;g++){for(var D=o[g].parseMatches(s),P=0,j=D.length;P<j;P++)D[P].setOffset(t+D[P].getOffset());c.push.apply(c,D)}return c},n.prototype.link=function(s){if(!s)return"";this.sanitizeHtml&&(s=s.replace(/</g,"&lt;").replace(/>/g,"&gt;"));for(var t=this.parse(s),o=[],c=0,g=0,C=t.length;g<C;g++){var D=t[g];o.push(s.substring(c,D.getOffset())),o.push(this.createMatchReturnVal(D)),c=D.getOffset()+D.getMatchedText().length}return o.push(s.substring(c)),o.join("")},n.prototype.createMatchReturnVal=function(s){var t;return this.replaceFn&&(t=this.replaceFn.call(this.context,s)),"string"==typeof t?t:!1===t?s.getMatchedText():t instanceof Py?t.toAnchorString():s.buildTag().toAnchorString()},n.prototype.getMatchers=function(){if(this.matchers)return this.matchers;var s=this.getTagBuilder(),t=[new ZE({tagBuilder:s,serviceName:this.hashtag}),new PM({tagBuilder:s}),new kM({tagBuilder:s}),new HM({tagBuilder:s,serviceName:this.mention}),new IM({tagBuilder:s,stripPrefix:this.stripPrefix,stripTrailingSlash:this.stripTrailingSlash,decodePercentEncoding:this.decodePercentEncoding})];return this.matchers=t},n.prototype.getTagBuilder=function(){var s=this.tagBuilder;return s||(s=this.tagBuilder=new Ly({newWindow:this.newWindow,truncate:this.truncate,className:this.className})),s},n.version="3.16.2",n.AnchorTagBuilder=Ly,n.HtmlTag=Py,n.matcher={Email:PM,Hashtag:ZE,Matcher:Hv,Mention:HM,Phone:kM,Url:IM},n.match={Email:bx,Hashtag:gl,Match:B1,Mention:Ex,Phone:$v,Url:wM},n}();var kx=/www|@|\:\/\//;function $x(n){return/^<a[>\s]/i.test(n)}function Hx(n){return/^<\/a\s*>/i.test(n)}function Ux(){var n=[],s=new Fx({stripPrefix:!1,url:!0,email:!0,replaceFn:function(t){switch(t.getType()){case"url":n.push({text:t.matchedText,url:t.getUrl()});break;case"email":n.push({text:t.matchedText,url:"mailto:"+t.getEmail().replace(/^mailto:/i,"")})}return!1}});return{links:n,autolinker:s}}function Bx(n){var s,t,o,c,g,C,D,P,j,W,re,_e,Fe,oe=n.tokens,me=null;for(t=0,o=oe.length;t<o;t++)if("inline"===oe[t].type)for(re=0,s=(c=oe[t].children).length-1;s>=0;s--)if("link_close"!==(g=c[s]).type){if("htmltag"===g.type&&($x(g.content)&&re>0&&re--,Hx(g.content)&&re++),!(re>0)&&"text"===g.type&&kx.test(g.content)){if(me||(_e=(me=Ux()).links,Fe=me.autolinker),C=g.content,_e.length=0,Fe.link(C),!_e.length)continue;for(D=[],W=g.level,P=0;P<_e.length;P++)!n.inline.validateLink(_e[P].url)||((j=C.indexOf(_e[P].text))&&D.push({type:"text",content:C.slice(0,j),level:W}),D.push({type:"link_open",href:_e[P].url,title:"",level:W++}),D.push({type:"text",content:_e[P].text,level:W}),D.push({type:"link_close",level:--W}),C=C.slice(j+_e[P].text.length));C.length&&D.push({type:"text",content:C,level:W}),oe[t].children=c=[].concat(c.slice(0,s),D,c.slice(s+1))}}else for(s--;c[s].level!==g.level&&"link_open"!==c[s].type;)s--}function BM(n){n.core.ruler.push("linkify",Bx)}var jE=i(23358),Yx=i.n(jE),Uv=i(1653),sp=i.n(Uv),YM=i(86101),x_=i.n(YM),G1=i(64975);function ZM(n){if(G1(n))return n}var am=i(63380),Uy=i(66627),GE=i(8225);function jM(n){if(void 0!==am&&null!=Uy(n)||null!=n["@@iterator"])return GE(n)}var Zx=i(19621);function VE(n,s){(null==s||s>n.length)&&(s=n.length);for(var t=0,o=new Array(s);t<s;t++)o[t]=n[t];return o}function V1(n,s){var t;if(n){if("string"==typeof n)return VE(n,s);var o=Zx(t=Object.prototype.toString.call(n)).call(t,8,-1);if("Object"===o&&n.constructor&&(o=n.constructor.name),"Map"===o||"Set"===o)return GE(n);if("Arguments"===o||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(o))return VE(n,s)}}function GM(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function GR(n){return ZM(n)||jM(n)||V1(n)||GM()}var jx=i(53757),Gx=i.n(jx),Bv=i(48129),VR=i.n(Bv),VM=i(31507),Vx=i.n(VM),zR=i(17346),zM=i.n(zR),zx=i(12232),zE=i.n(zx),WE=i(69138);function JE(n,s,t,o,c,g,C){try{var D=n[g](C),P=D.value}catch(j){return void t(j)}D.done?s(P):WE.resolve(P).then(o,c)}function z1(n){return function(){var s=this,t=arguments;return new WE(function(o,c){var g=n.apply(s,t);function C(P){JE(g,o,c,C,D,"next",P)}function D(P){JE(g,o,c,C,D,"throw",P)}C(void 0)})}}var WM=i(33950),e_=i.n(WM),JM=i(86413),lm=i.n(JM),Wx=i(14226),Jx=i.n(Wx),Qx=i(64871),W1=i.n(Qx),QM=i(41776),XM=i.n(QM),KM=i(12666),qM=i.n(KM);function Ng(n,s){var t=void 0!==am&&Uy(n)||n["@@iterator"];if(!t){if(G1(n)||(t=V1(n))||s&&n&&"number"==typeof n.length){t&&(n=t);var o=0,c=function(){};return{s:c,n:function(){return o>=n.length?{done:!0}:{done:!1,value:n[o++]}},e:function(j){throw j},f:c}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var D,g=!0,C=!1;return{s:function(){t=t.call(n)},n:function(){var j=t.next();return g=j.done,j},e:function(j){C=!0,D=j},f:function(){try{!g&&null!=t.return&&t.return()}finally{if(C)throw D}}}}var e2=i(66342);function vc(n){return(vc="function"==typeof am&&"symbol"==typeof e2?function(s){return typeof s}:function(s){return s&&"function"==typeof am&&s.constructor===am&&s!==am.prototype?"symbol":typeof s})(n)}function bh(n,s){return ZM(n)||function(n,s){var t=null==n?null:void 0!==am&&Uy(n)||n["@@iterator"];if(null!=t){var C,D,o=[],c=!0,g=!1;try{for(t=t.call(n);!(c=(C=t.next()).done)&&(o.push(C.value),!s||o.length!==s);c=!0);}catch(P){g=!0,D=P}finally{try{!c&&null!=t.return&&t.return()}finally{if(g)throw D}}return o}}(n,s)||V1(n,s)||GM()}var n2=i(35524),Yv=i.n(n2),Xx=i(28086),Qm=i.n(Xx),J1=i(30071),QE=i.n(J1),XE=i(44859),Wp=i.n(XE),Kx=i(37940),Tu=i.n(Kx),qx=i(46245),xu=i.n(qx),WR=i(34377),ra=i.n(WR),KE=i(15865),qE=i.n(KE),eT=i(10068),Np=i.n(eT),eD=(i(71577),i(59009)),tT=i.n(eD);function r2(n){return null==n}var of={isNothing:r2,isObject:function(n){return"object"==typeof n&&null!==n},toArray:function(n){return Array.isArray(n)?n:r2(n)?[]:[n]},repeat:function(n,s){var o,t="";for(o=0;o<s;o+=1)t+=n;return t},isNegativeZero:function(n){return 0===n&&Number.NEGATIVE_INFINITY===1/n},extend:function(n,s){var t,o,c,g;if(s)for(t=0,o=(g=Object.keys(s)).length;t<o;t+=1)n[c=g[t]]=s[c];return n}};function rD(n,s){var t="",o=n.reason||"(unknown reason)";return n.mark?(n.mark.name&&(t+='in "'+n.mark.name+'" '),t+="("+(n.mark.line+1)+":"+(n.mark.column+1)+")",!s&&n.mark.snippet&&(t+="\n\n"+n.mark.snippet),o+" "+t):o}function Sf(n,s){Error.call(this),this.name="YAMLException",this.reason=n,this.mark=s,this.message=rD(this,!1),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||""}(Sf.prototype=Object.create(Error.prototype)).constructor=Sf,Sf.prototype.toString=function(s){return this.name+": "+rD(this,s)};var sf=Sf;function rT(n,s,t,o,c){var g="",C="",D=Math.floor(c/2)-1;return o-s>D&&(s=o-D+(g=" ... ").length),t-o>D&&(t=o+D-(C=" ...").length),{str:g+n.slice(s,t).replace(/\t/g,"\u2192")+C,pos:o-s+g.length}}function iT(n,s){return of.repeat(" ",s-n.length)+n}var iD=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],oT=["scalar","sequence","mapping"],Jf=function(n,s){if(s=s||{},Object.keys(s).forEach(function(t){if(-1===iD.indexOf(t))throw new sf('Unknown option "'+t+'" is met in definition of "'+n+'" YAML type.')}),this.options=s,this.tag=n,this.kind=s.kind||null,this.resolve=s.resolve||function(){return!0},this.construct=s.construct||function(t){return t},this.instanceOf=s.instanceOf||null,this.predicate=s.predicate||null,this.represent=s.represent||null,this.representName=s.representName||null,this.defaultStyle=s.defaultStyle||null,this.multi=s.multi||!1,this.styleAliases=function(n){var s={};return null!==n&&Object.keys(n).forEach(function(t){n[t].forEach(function(o){s[String(o)]=t})}),s}(s.styleAliases||null),-1===oT.indexOf(this.kind))throw new sf('Unknown kind "'+this.kind+'" is specified for "'+n+'" YAML type.')};function p2(n,s){var t=[];return n[s].forEach(function(o){var c=t.length;t.forEach(function(g,C){g.tag===o.tag&&g.kind===o.kind&&g.multi===o.multi&&(c=C)}),t[c]=o}),t}function By(n){return this.extend(n)}By.prototype.extend=function(s){var t=[],o=[];if(s instanceof Jf)o.push(s);else if(Array.isArray(s))o=o.concat(s);else{if(!s||!Array.isArray(s.implicit)&&!Array.isArray(s.explicit))throw new sf("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");s.implicit&&(t=t.concat(s.implicit)),s.explicit&&(o=o.concat(s.explicit))}t.forEach(function(g){if(!(g instanceof Jf))throw new sf("Specified list of YAML types (or a single Type object) contains a non-Type object.");if(g.loadKind&&"scalar"!==g.loadKind)throw new sf("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");if(g.multi)throw new sf("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.")}),o.forEach(function(g){if(!(g instanceof Jf))throw new sf("Specified list of YAML types (or a single Type object) contains a non-Type object.")});var c=Object.create(By.prototype);return c.implicit=(this.implicit||[]).concat(t),c.explicit=(this.explicit||[]).concat(o),c.compiledImplicit=p2(c,"implicit"),c.compiledExplicit=p2(c,"explicit"),c.compiledTypeMap=function(){var s,t,n={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}};function o(c){c.multi?(n.multi[c.kind].push(c),n.multi.fallback.push(c)):n[c.kind][c.tag]=n.fallback[c.tag]=c}for(s=0,t=arguments.length;s<t;s+=1)arguments[s].forEach(o);return n}(c.compiledImplicit,c.compiledExplicit),c};var aT=By,X1=new Jf("tag:yaml.org,2002:str",{kind:"scalar",construct:function(n){return null!==n?n:""}}),Yy=new Jf("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(n){return null!==n?n:[]}}),sD=new Jf("tag:yaml.org,2002:map",{kind:"mapping",construct:function(n){return null!==n?n:{}}}),lT=new aT({explicit:[X1,Yy,sD]}),uT=new Jf("tag:yaml.org,2002:null",{kind:"scalar",resolve:function(n){if(null===n)return!0;var s=n.length;return 1===s&&"~"===n||4===s&&("null"===n||"Null"===n||"NULL"===n)},construct:function(){return null},predicate:function(n){return null===n},represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"},empty:function(){return""}},defaultStyle:"lowercase"}),_2=new Jf("tag:yaml.org,2002:bool",{kind:"scalar",resolve:function(n){if(null===n)return!1;var s=n.length;return 4===s&&("true"===n||"True"===n||"TRUE"===n)||5===s&&("false"===n||"False"===n||"FALSE"===n)},construct:function(n){return"true"===n||"True"===n||"TRUE"===n},predicate:function(n){return"[object Boolean]"===Object.prototype.toString.call(n)},represent:{lowercase:function(n){return n?"true":"false"},uppercase:function(n){return n?"TRUE":"FALSE"},camelcase:function(n){return n?"True":"False"}},defaultStyle:"lowercase"});function uD(n){return 48<=n&&n<=57||65<=n&&n<=70||97<=n&&n<=102}function g2(n){return 48<=n&&n<=55}function m2(n){return 48<=n&&n<=57}var fT=new Jf("tag:yaml.org,2002:int",{kind:"scalar",resolve:function(n){if(null===n)return!1;var c,s=n.length,t=0,o=!1;if(!s)return!1;if(("-"===(c=n[t])||"+"===c)&&(c=n[++t]),"0"===c){if(t+1===s)return!0;if("b"===(c=n[++t])){for(t++;t<s;t++)if("_"!==(c=n[t])){if("0"!==c&&"1"!==c)return!1;o=!0}return o&&"_"!==c}if("x"===c){for(t++;t<s;t++)if("_"!==(c=n[t])){if(!uD(n.charCodeAt(t)))return!1;o=!0}return o&&"_"!==c}if("o"===c){for(t++;t<s;t++)if("_"!==(c=n[t])){if(!g2(n.charCodeAt(t)))return!1;o=!0}return o&&"_"!==c}}if("_"===c)return!1;for(;t<s;t++)if("_"!==(c=n[t])){if(!m2(n.charCodeAt(t)))return!1;o=!0}return!(!o||"_"===c)},construct:function(n){var o,s=n,t=1;if(-1!==s.indexOf("_")&&(s=s.replace(/_/g,"")),("-"===(o=s[0])||"+"===o)&&("-"===o&&(t=-1),o=(s=s.slice(1))[0]),"0"===s)return 0;if("0"===o){if("b"===s[1])return t*parseInt(s.slice(2),2);if("x"===s[1])return t*parseInt(s.slice(2),16);if("o"===s[1])return t*parseInt(s.slice(2),8)}return t*parseInt(s,10)},predicate:function(n){return"[object Number]"===Object.prototype.toString.call(n)&&n%1==0&&!of.isNegativeZero(n)},represent:{binary:function(n){return n>=0?"0b"+n.toString(2):"-0b"+n.toString(2).slice(1)},octal:function(n){return n>=0?"0o"+n.toString(8):"-0o"+n.toString(8).slice(1)},decimal:function(n){return n.toString(10)},hexadecimal:function(n){return n>=0?"0x"+n.toString(16).toUpperCase():"-0x"+n.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),dD=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"),pD=/^[-+]?[0-9]+e/,pT=new Jf("tag:yaml.org,2002:float",{kind:"scalar",resolve:function(n){return!(null===n||!dD.test(n)||"_"===n[n.length-1])},construct:function(n){var s,t;return t="-"===(s=n.replace(/_/g,"").toLowerCase())[0]?-1:1,"+-".indexOf(s[0])>=0&&(s=s.slice(1)),".inf"===s?1===t?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===s?NaN:t*parseFloat(s,10)},predicate:function(n){return"[object Number]"===Object.prototype.toString.call(n)&&(n%1!=0||of.isNegativeZero(n))},represent:function(n,s){var t;if(isNaN(n))switch(s){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===n)switch(s){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===n)switch(s){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(of.isNegativeZero(n))return"-0.0";return t=n.toString(10),pD.test(t)?t.replace("e",".e"):t},defaultStyle:"lowercase"}),hT=lT.extend({implicit:[uT,_2,fT,pT]}),S2=hT,C2=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),M2=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$"),hD=new Jf("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:function(n){return null!==n&&(null!==C2.exec(n)||null!==M2.exec(n))},construct:function(n){var s,t,o,c,g,C,D,oe,P=0,j=null;if(null===(s=C2.exec(n))&&(s=M2.exec(n)),null===s)throw new Error("Date resolve error");if(t=+s[1],o=+s[2]-1,c=+s[3],!s[4])return new Date(Date.UTC(t,o,c));if(g=+s[4],C=+s[5],D=+s[6],s[7]){for(P=s[7].slice(0,3);P.length<3;)P+="0";P=+P}return s[9]&&(j=6e4*(60*+s[10]+ +(s[11]||0)),"-"===s[9]&&(j=-j)),oe=new Date(Date.UTC(t,o,c,g,C,D,P)),j&&oe.setTime(oe.getTime()-j),oe},instanceOf:Date,represent:function(n){return n.toISOString()}}),_D=new Jf("tag:yaml.org,2002:merge",{kind:"scalar",resolve:function(n){return"<<"===n||null===n}}),O2="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r",w2=new Jf("tag:yaml.org,2002:binary",{kind:"scalar",resolve:function(n){if(null===n)return!1;var s,t,o=0,c=n.length,g=O2;for(t=0;t<c;t++)if(!((s=g.indexOf(n.charAt(t)))>64)){if(s<0)return!1;o+=6}return o%8==0},construct:function(n){var s,t,o=n.replace(/[\r\n=]/g,""),c=o.length,g=O2,C=0,D=[];for(s=0;s<c;s++)s%4==0&&s&&(D.push(C>>16&255),D.push(C>>8&255),D.push(255&C)),C=C<<6|g.indexOf(o.charAt(s));return 0==(t=c%4*6)?(D.push(C>>16&255),D.push(C>>8&255),D.push(255&C)):18===t?(D.push(C>>10&255),D.push(C>>2&255)):12===t&&D.push(C>>4&255),new Uint8Array(D)},predicate:function(n){return"[object Uint8Array]"===Object.prototype.toString.call(n)},represent:function(n){var o,c,s="",t=0,g=n.length,C=O2;for(o=0;o<g;o++)o%3==0&&o&&(s+=C[t>>18&63],s+=C[t>>12&63],s+=C[t>>6&63],s+=C[63&t]),t=(t<<8)+n[o];return 0==(c=g%3)?(s+=C[t>>18&63],s+=C[t>>12&63],s+=C[t>>6&63],s+=C[63&t]):2===c?(s+=C[t>>10&63],s+=C[t>>4&63],s+=C[t<<2&63],s+=C[64]):1===c&&(s+=C[t>>2&63],s+=C[t<<4&63],s+=C[64],s+=C[64]),s}}),iN=Object.prototype.hasOwnProperty,gD=Object.prototype.toString,mD=new Jf("tag:yaml.org,2002:omap",{kind:"sequence",resolve:function(n){if(null===n)return!0;var t,o,c,g,C,s=[],D=n;for(t=0,o=D.length;t<o;t+=1){if(C=!1,"[object Object]"!==gD.call(c=D[t]))return!1;for(g in c)if(iN.call(c,g)){if(C)return!1;C=!0}if(!C)return!1;if(-1!==s.indexOf(g))return!1;s.push(g)}return!0},construct:function(n){return null!==n?n:[]}}),aN=Object.prototype.toString,x2=new Jf("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:function(n){if(null===n)return!0;var s,t,o,c,g,C=n;for(g=new Array(C.length),s=0,t=C.length;s<t;s+=1){if("[object Object]"!==aN.call(o=C[s])||1!==(c=Object.keys(o)).length)return!1;g[s]=[c[0],o[c[0]]]}return!0},construct:function(n){if(null===n)return[];var s,t,o,c,g,C=n;for(g=new Array(C.length),s=0,t=C.length;s<t;s+=1)o=C[s],c=Object.keys(o),g[s]=[c[0],o[c[0]]];return g}}),lN=Object.prototype.hasOwnProperty,D2=new Jf("tag:yaml.org,2002:set",{kind:"mapping",resolve:function(n){if(null===n)return!0;var s,t=n;for(s in t)if(lN.call(t,s)&&null!==t[s])return!1;return!0},construct:function(n){return null!==n?n:{}}}),_T=S2.extend({implicit:[hD,_D],explicit:[w2,mD,x2,D2]}),um=Object.prototype.hasOwnProperty,yT=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,Zv=/[\x85\u2028\u2029]/,N2=/[,\[\]\{\}]/,P2=/^(?:!|!!|![a-z\-]+!)$/i,I2=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function jy(n){return Object.prototype.toString.call(n)}function D_(n){return 10===n||13===n}function cm(n){return 9===n||32===n}function Pp(n){return 9===n||32===n||10===n||13===n}function K1(n){return 44===n||91===n||93===n||123===n||125===n}function L2(n){var s;return 48<=n&&n<=57?n-48:97<=(s=32|n)&&s<=102?s-97+10:-1}function Gy(n){return 120===n?2:117===n?4:85===n?8:0}function F2(n){return 48<=n&&n<=57?n-48:-1}function TD(n){return 48===n?"\0":97===n?"\x07":98===n?"\b":116===n||9===n?"\t":110===n?"\n":118===n?"\v":102===n?"\f":114===n?"\r":101===n?"\x1b":32===n?" ":34===n?'"':47===n?"/":92===n?"\\":78===n?"\x85":95===n?"\xa0":76===n?"\u2028":80===n?"\u2029":""}function fN(n){return n<=65535?String.fromCharCode(n):String.fromCharCode(55296+(n-65536>>10),56320+(n-65536&1023))}for(var SD=new Array(256),k2=new Array(256),q1=0;q1<256;q1++)SD[q1]=TD(q1)?1:0,k2[q1]=TD(q1);function Vy(n,s){this.input=n,this.filename=s.filename||null,this.schema=s.schema||_T,this.onWarning=s.onWarning||null,this.legacy=s.legacy||!1,this.json=s.json||!1,this.listener=s.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=n.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function $2(n,s){var t={name:n.filename,buffer:n.input.slice(0,-1),position:n.position,line:n.line,column:n.position-n.lineStart};return t.snippet=function(n,s){if(s=Object.create(s||null),!n.buffer)return null;s.maxLength||(s.maxLength=79),"number"!=typeof s.indent&&(s.indent=1),"number"!=typeof s.linesBefore&&(s.linesBefore=3),"number"!=typeof s.linesAfter&&(s.linesAfter=2);for(var g,t=/\r?\n|\r|\0/g,o=[0],c=[],C=-1;g=t.exec(n.buffer);)c.push(g.index),o.push(g.index+g[0].length),n.position<=g.index&&C<0&&(C=o.length-2);C<0&&(C=o.length-1);var P,j,D="",W=Math.min(n.line+s.linesAfter,c.length).toString().length,re=s.maxLength-(s.indent+W+3);for(P=1;P<=s.linesBefore&&!(C-P<0);P++)j=rT(n.buffer,o[C-P],c[C-P],n.position-(o[C]-o[C-P]),re),D=of.repeat(" ",s.indent)+iT((n.line-P+1).toString(),W)+" | "+j.str+"\n"+D;for(j=rT(n.buffer,o[C],c[C],n.position,re),D+=of.repeat(" ",s.indent)+iT((n.line+1).toString(),W)+" | "+j.str+"\n",D+=of.repeat("-",s.indent+W+3+j.pos)+"^\n",P=1;P<=s.linesAfter&&!(C+P>=c.length);P++)j=rT(n.buffer,o[C+P],c[C+P],n.position-(o[C]-o[C+P]),re),D+=of.repeat(" ",s.indent)+iT((n.line+P+1).toString(),W)+" | "+j.str+"\n";return D.replace(/\n$/,"")}(t),new sf(s,t)}function Da(n,s){throw $2(n,s)}function bT(n,s){n.onWarning&&n.onWarning.call(null,$2(n,s))}var zy={YAML:function(s,t,o){var c,g,C;null!==s.version&&Da(s,"duplication of %YAML directive"),1!==o.length&&Da(s,"YAML directive accepts exactly one argument"),null===(c=/^([0-9]+)\.([0-9]+)$/.exec(o[0]))&&Da(s,"ill-formed argument of the YAML directive"),g=parseInt(c[1],10),C=parseInt(c[2],10),1!==g&&Da(s,"unacceptable YAML version of the document"),s.version=o[0],s.checkLineBreaks=C<2,1!==C&&2!==C&&bT(s,"unsupported YAML version of the document")},TAG:function(s,t,o){var c,g;2!==o.length&&Da(s,"TAG directive accepts exactly two arguments"),g=o[1],P2.test(c=o[0])||Da(s,"ill-formed tag handle (first argument) of the TAG directive"),um.call(s.tagMap,c)&&Da(s,'there is a previously declared suffix for "'+c+'" tag handle'),I2.test(g)||Da(s,"ill-formed tag prefix (second argument) of the TAG directive");try{g=decodeURIComponent(g)}catch(C){Da(s,"tag prefix is malformed: "+g)}s.tagMap[c]=g}};function dm(n,s,t,o){var c,g,C,D;if(s<t){if(D=n.input.slice(s,t),o)for(c=0,g=D.length;c<g;c+=1)9===(C=D.charCodeAt(c))||32<=C&&C<=1114111||Da(n,"expected valid JSON character");else yT.test(D)&&Da(n,"the stream contains non-printable characters");n.result+=D}}function CD(n,s,t,o){var c,g,C,D;for(of.isObject(t)||Da(n,"cannot merge mappings; the provided source object is unacceptable"),C=0,D=(c=Object.keys(t)).length;C<D;C+=1)um.call(s,g=c[C])||(s[g]=t[g],o[g]=!0)}function e0(n,s,t,o,c,g,C,D,P){var j,W;if(Array.isArray(c))for(j=0,W=(c=Array.prototype.slice.call(c)).length;j<W;j+=1)Array.isArray(c[j])&&Da(n,"nested arrays are not supported inside keys"),"object"==typeof c&&"[object Object]"===jy(c[j])&&(c[j]="[object Object]");if("object"==typeof c&&"[object Object]"===jy(c)&&(c="[object Object]"),c=String(c),null===s&&(s={}),"tag:yaml.org,2002:merge"===o)if(Array.isArray(g))for(j=0,W=g.length;j<W;j+=1)CD(n,s,g[j],t);else CD(n,s,g,t);else!n.json&&!um.call(t,c)&&um.call(s,c)&&(n.line=C||n.line,n.lineStart=D||n.lineStart,n.position=P||n.position,Da(n,"duplicated mapping key")),"__proto__"===c?Object.defineProperty(s,c,{configurable:!0,enumerable:!0,writable:!0,value:g}):s[c]=g,delete t[c];return s}function ET(n){var s;10===(s=n.input.charCodeAt(n.position))?n.position++:13===s?(n.position++,10===n.input.charCodeAt(n.position)&&n.position++):Da(n,"a line break is expected"),n.line+=1,n.lineStart=n.position,n.firstTabInLine=-1}function Cf(n,s,t){for(var o=0,c=n.input.charCodeAt(n.position);0!==c;){for(;cm(c);)9===c&&-1===n.firstTabInLine&&(n.firstTabInLine=n.position),c=n.input.charCodeAt(++n.position);if(s&&35===c)do{c=n.input.charCodeAt(++n.position)}while(10!==c&&13!==c&&0!==c);if(!D_(c))break;for(ET(n),c=n.input.charCodeAt(n.position),o++,n.lineIndent=0;32===c;)n.lineIndent++,c=n.input.charCodeAt(++n.position)}return-1!==t&&0!==o&&n.lineIndent<t&&bT(n,"deficient indentation"),o}function t0(n){var t,s=n.position;return!(45!==(t=n.input.charCodeAt(s))&&46!==t||t!==n.input.charCodeAt(s+1)||t!==n.input.charCodeAt(s+2)||(s+=3,t=n.input.charCodeAt(s),0!==t&&!Pp(t)))}function TT(n,s){1===s?n.result+=" ":s>1&&(n.result+=of.repeat("\n",s-1))}function H2(n,s){var t,P,o=n.tag,c=n.anchor,g=[],D=!1;if(-1!==n.firstTabInLine)return!1;for(null!==n.anchor&&(n.anchorMap[n.anchor]=g),P=n.input.charCodeAt(n.position);0!==P&&(-1!==n.firstTabInLine&&(n.position=n.firstTabInLine,Da(n,"tab characters must not be used in indentation")),45===P&&Pp(n.input.charCodeAt(n.position+1)));)if(D=!0,n.position++,Cf(n,!0,-1)&&n.lineIndent<=s)g.push(null),P=n.input.charCodeAt(n.position);else if(t=n.line,jv(n,s,3,!1,!0),g.push(n.result),Cf(n,!0,-1),P=n.input.charCodeAt(n.position),(n.line===t||n.lineIndent>s)&&0!==P)Da(n,"bad indentation of a sequence entry");else if(n.lineIndent<s)break;return!!D&&(n.tag=o,n.anchor=c,n.kind="sequence",n.result=g,!0)}function ST(n){var s,c,g,C,t=!1,o=!1;if(33!==(C=n.input.charCodeAt(n.position)))return!1;if(null!==n.tag&&Da(n,"duplication of a tag property"),60===(C=n.input.charCodeAt(++n.position))?(t=!0,C=n.input.charCodeAt(++n.position)):33===C?(o=!0,c="!!",C=n.input.charCodeAt(++n.position)):c="!",s=n.position,t){do{C=n.input.charCodeAt(++n.position)}while(0!==C&&62!==C);n.position<n.length?(g=n.input.slice(s,n.position),C=n.input.charCodeAt(++n.position)):Da(n,"unexpected end of the stream within a verbatim tag")}else{for(;0!==C&&!Pp(C);)33===C&&(o?Da(n,"tag suffix cannot contain exclamation marks"):(c=n.input.slice(s-1,n.position+1),P2.test(c)||Da(n,"named tag handle cannot contain such characters"),o=!0,s=n.position+1)),C=n.input.charCodeAt(++n.position);g=n.input.slice(s,n.position),N2.test(g)&&Da(n,"tag suffix cannot contain flow indicator characters")}g&&!I2.test(g)&&Da(n,"tag name cannot contain such characters: "+g);try{g=decodeURIComponent(g)}catch(D){Da(n,"tag name is malformed: "+g)}return t?n.tag=g:um.call(n.tagMap,c)?n.tag=n.tagMap[c]+g:"!"===c?n.tag="!"+g:"!!"===c?n.tag="tag:yaml.org,2002:"+g:Da(n,'undeclared tag handle "'+c+'"'),!0}function wD(n){var s,t;if(38!==(t=n.input.charCodeAt(n.position)))return!1;for(null!==n.anchor&&Da(n,"duplication of an anchor property"),t=n.input.charCodeAt(++n.position),s=n.position;0!==t&&!Pp(t)&&!K1(t);)t=n.input.charCodeAt(++n.position);return n.position===s&&Da(n,"name of an anchor node must contain at least one character"),n.anchor=n.input.slice(s,n.position),!0}function jv(n,s,t,o,c){var g,C,D,re,oe,me,_e,Fe,Re,P=1,j=!1,W=!1;if(null!==n.listener&&n.listener("open",n),n.tag=null,n.anchor=null,n.kind=null,n.result=null,g=C=D=4===t||3===t,o&&Cf(n,!0,-1)&&(j=!0,n.lineIndent>s?P=1:n.lineIndent===s?P=0:n.lineIndent<s&&(P=-1)),1===P)for(;ST(n)||wD(n);)Cf(n,!0,-1)?(j=!0,D=g,n.lineIndent>s?P=1:n.lineIndent===s?P=0:n.lineIndent<s&&(P=-1)):D=!1;if(D&&(D=j||c),(1===P||4===t)&&(Fe=1===t||2===t?s:s+1,Re=n.position-n.lineStart,1===P?D&&(H2(n,Re)||function(n,s,t){var o,c,g,C,D,P,we,j=n.tag,W=n.anchor,re={},oe=Object.create(null),me=null,_e=null,Fe=null,Re=!1,Le=!1;if(-1!==n.firstTabInLine)return!1;for(null!==n.anchor&&(n.anchorMap[n.anchor]=re),we=n.input.charCodeAt(n.position);0!==we;){if(!Re&&-1!==n.firstTabInLine&&(n.position=n.firstTabInLine,Da(n,"tab characters must not be used in indentation")),o=n.input.charCodeAt(n.position+1),g=n.line,63!==we&&58!==we||!Pp(o)){if(C=n.line,D=n.lineStart,P=n.position,!jv(n,t,2,!1,!0))break;if(n.line===g){for(we=n.input.charCodeAt(n.position);cm(we);)we=n.input.charCodeAt(++n.position);if(58===we)Pp(we=n.input.charCodeAt(++n.position))||Da(n,"a whitespace character is expected after the key-value separator within a block mapping"),Re&&(e0(n,re,oe,me,_e,null,C,D,P),me=_e=Fe=null),Le=!0,Re=!1,c=!1,me=n.tag,_e=n.result;else{if(!Le)return n.tag=j,n.anchor=W,!0;Da(n,"can not read an implicit mapping pair; a colon is missed")}}else{if(!Le)return n.tag=j,n.anchor=W,!0;Da(n,"can not read a block mapping entry; a multiline key may not be an implicit key")}}else 63===we?(Re&&(e0(n,re,oe,me,_e,null,C,D,P),me=_e=Fe=null),Le=!0,Re=!0,c=!0):Re?(Re=!1,c=!0):Da(n,"incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line"),n.position+=1,we=o;if((n.line===g||n.lineIndent>s)&&(Re&&(C=n.line,D=n.lineStart,P=n.position),jv(n,s,4,!0,c)&&(Re?_e=n.result:Fe=n.result),Re||(e0(n,re,oe,me,_e,Fe,C,D,P),me=_e=Fe=null),Cf(n,!0,-1),we=n.input.charCodeAt(n.position)),(n.line===g||n.lineIndent>s)&&0!==we)Da(n,"bad indentation of a mapping entry");else if(n.lineIndent<s)break}return Re&&e0(n,re,oe,me,_e,null,C,D,P),Le&&(n.tag=j,n.anchor=W,n.kind="mapping",n.result=re),Le}(n,Re,Fe))||function(n,s){var o,c,g,D,W,re,oe,me,Fe,Re,Le,we,t=!0,C=n.tag,P=n.anchor,_e=Object.create(null);if(91===(we=n.input.charCodeAt(n.position)))W=93,me=!1,D=[];else{if(123!==we)return!1;W=125,me=!0,D={}}for(null!==n.anchor&&(n.anchorMap[n.anchor]=D),we=n.input.charCodeAt(++n.position);0!==we;){if(Cf(n,!0,s),(we=n.input.charCodeAt(n.position))===W)return n.position++,n.tag=C,n.anchor=P,n.kind=me?"mapping":"sequence",n.result=D,!0;t?44===we&&Da(n,"expected the node content, but found ','"):Da(n,"missed comma between flow collection entries"),Le=null,re=oe=!1,63===we&&Pp(n.input.charCodeAt(n.position+1))&&(re=oe=!0,n.position++,Cf(n,!0,s)),o=n.line,c=n.lineStart,g=n.position,jv(n,s,1,!1,!0),Re=n.tag,Fe=n.result,Cf(n,!0,s),we=n.input.charCodeAt(n.position),(oe||n.line===o)&&58===we&&(re=!0,we=n.input.charCodeAt(++n.position),Cf(n,!0,s),jv(n,s,1,!1,!0),Le=n.result),me?e0(n,D,_e,Re,Fe,Le,o,c,g):D.push(re?e0(n,null,_e,Re,Fe,Le,o,c,g):Fe),Cf(n,!0,s),44===(we=n.input.charCodeAt(n.position))?(t=!0,we=n.input.charCodeAt(++n.position)):t=!1}Da(n,"unexpected end of the stream within a flow collection")}(n,Fe)?W=!0:(C&&function(n,s){var t,o,W,re,c=1,g=!1,C=!1,D=s,P=0,j=!1;if(124===(re=n.input.charCodeAt(n.position)))o=!1;else{if(62!==re)return!1;o=!0}for(n.kind="scalar",n.result="";0!==re;)if(43===(re=n.input.charCodeAt(++n.position))||45===re)1===c?c=43===re?3:2:Da(n,"repeat of a chomping mode identifier");else{if(!((W=F2(re))>=0))break;0===W?Da(n,"bad explicit indentation width of a block scalar; it cannot be less than one"):C?Da(n,"repeat of an indentation width identifier"):(D=s+W-1,C=!0)}if(cm(re)){do{re=n.input.charCodeAt(++n.position)}while(cm(re));if(35===re)do{re=n.input.charCodeAt(++n.position)}while(!D_(re)&&0!==re)}for(;0!==re;){for(ET(n),n.lineIndent=0,re=n.input.charCodeAt(n.position);(!C||n.lineIndent<D)&&32===re;)n.lineIndent++,re=n.input.charCodeAt(++n.position);if(!C&&n.lineIndent>D&&(D=n.lineIndent),D_(re))P++;else{if(n.lineIndent<D){3===c?n.result+=of.repeat("\n",g?1+P:P):1===c&&g&&(n.result+="\n");break}for(o?cm(re)?(j=!0,n.result+=of.repeat("\n",g?1+P:P)):j?(j=!1,n.result+=of.repeat("\n",P+1)):0===P?g&&(n.result+=" "):n.result+=of.repeat("\n",P):n.result+=of.repeat("\n",g?1+P:P),g=!0,C=!0,P=0,t=n.position;!D_(re)&&0!==re;)re=n.input.charCodeAt(++n.position);dm(n,t,n.position,!1)}}return!0}(n,Fe)||function(n,s){var t,o,c;if(39!==(t=n.input.charCodeAt(n.position)))return!1;for(n.kind="scalar",n.result="",n.position++,o=c=n.position;0!==(t=n.input.charCodeAt(n.position));)if(39===t){if(dm(n,o,n.position,!0),39!==(t=n.input.charCodeAt(++n.position)))return!0;o=n.position,n.position++,c=n.position}else D_(t)?(dm(n,o,c,!0),TT(n,Cf(n,!1,s)),o=c=n.position):n.position===n.lineStart&&t0(n)?Da(n,"unexpected end of the document within a single quoted scalar"):(n.position++,c=n.position);Da(n,"unexpected end of the stream within a single quoted scalar")}(n,Fe)||function(n,s){var t,o,c,g,C,D;if(34!==(D=n.input.charCodeAt(n.position)))return!1;for(n.kind="scalar",n.result="",n.position++,t=o=n.position;0!==(D=n.input.charCodeAt(n.position));){if(34===D)return dm(n,t,n.position,!0),n.position++,!0;if(92===D){if(dm(n,t,n.position,!0),D_(D=n.input.charCodeAt(++n.position)))Cf(n,!1,s);else if(D<256&&SD[D])n.result+=k2[D],n.position++;else if((C=Gy(D))>0){for(c=C,g=0;c>0;c--)(C=L2(D=n.input.charCodeAt(++n.position)))>=0?g=(g<<4)+C:Da(n,"expected hexadecimal character");n.result+=fN(g),n.position++}else Da(n,"unknown escape sequence");t=o=n.position}else D_(D)?(dm(n,t,o,!0),TT(n,Cf(n,!1,s)),t=o=n.position):n.position===n.lineStart&&t0(n)?Da(n,"unexpected end of the document within a double quoted scalar"):(n.position++,o=n.position)}Da(n,"unexpected end of the stream within a double quoted scalar")}(n,Fe)?W=!0:function(n){var s,t,o;if(42!==(o=n.input.charCodeAt(n.position)))return!1;for(o=n.input.charCodeAt(++n.position),s=n.position;0!==o&&!Pp(o)&&!K1(o);)o=n.input.charCodeAt(++n.position);return n.position===s&&Da(n,"name of an alias node must contain at least one character"),t=n.input.slice(s,n.position),um.call(n.anchorMap,t)||Da(n,'unidentified alias "'+t+'"'),n.result=n.anchorMap[t],Cf(n,!0,-1),!0}(n)?(W=!0,(null!==n.tag||null!==n.anchor)&&Da(n,"alias node should not have any properties")):function(n,s,t){var c,g,C,D,P,j,W,me,re=n.kind,oe=n.result;if(Pp(me=n.input.charCodeAt(n.position))||K1(me)||35===me||38===me||42===me||33===me||124===me||62===me||39===me||34===me||37===me||64===me||96===me||(63===me||45===me)&&(Pp(c=n.input.charCodeAt(n.position+1))||t&&K1(c)))return!1;for(n.kind="scalar",n.result="",g=C=n.position,D=!1;0!==me;){if(58===me){if(Pp(c=n.input.charCodeAt(n.position+1))||t&&K1(c))break}else if(35===me){if(Pp(n.input.charCodeAt(n.position-1)))break}else{if(n.position===n.lineStart&&t0(n)||t&&K1(me))break;if(D_(me)){if(P=n.line,j=n.lineStart,W=n.lineIndent,Cf(n,!1,-1),n.lineIndent>=s){D=!0,me=n.input.charCodeAt(n.position);continue}n.position=C,n.line=P,n.lineStart=j,n.lineIndent=W;break}}D&&(dm(n,g,C,!1),TT(n,n.line-P),g=C=n.position,D=!1),cm(me)||(C=n.position+1),me=n.input.charCodeAt(++n.position)}return dm(n,g,C,!1),!!n.result||(n.kind=re,n.result=oe,!1)}(n,Fe,1===t)&&(W=!0,null===n.tag&&(n.tag="?")),null!==n.anchor&&(n.anchorMap[n.anchor]=n.result)):0===P&&(W=D&&H2(n,Re))),null===n.tag)null!==n.anchor&&(n.anchorMap[n.anchor]=n.result);else if("?"===n.tag){for(null!==n.result&&"scalar"!==n.kind&&Da(n,'unacceptable node kind for !<?> tag; it should be "scalar", not "'+n.kind+'"'),re=0,oe=n.implicitTypes.length;re<oe;re+=1)if((_e=n.implicitTypes[re]).resolve(n.result)){n.result=_e.construct(n.result),n.tag=_e.tag,null!==n.anchor&&(n.anchorMap[n.anchor]=n.result);break}}else if("!"!==n.tag){if(um.call(n.typeMap[n.kind||"fallback"],n.tag))_e=n.typeMap[n.kind||"fallback"][n.tag];else for(_e=null,re=0,oe=(me=n.typeMap.multi[n.kind||"fallback"]).length;re<oe;re+=1)if(n.tag.slice(0,me[re].tag.length)===me[re].tag){_e=me[re];break}_e||Da(n,"unknown tag !<"+n.tag+">"),null!==n.result&&_e.kind!==n.kind&&Da(n,"unacceptable node kind for !<"+n.tag+'> tag; it should be "'+_e.kind+'", not "'+n.kind+'"'),_e.resolve(n.result,n.tag)?(n.result=_e.construct(n.result,n.tag),null!==n.anchor&&(n.anchorMap[n.anchor]=n.result)):Da(n,"cannot resolve a node with !<"+n.tag+"> explicit tag")}return null!==n.listener&&n.listener("close",n),null!==n.tag||null!==n.anchor||W}function CT(n){var t,o,c,C,s=n.position,g=!1;for(n.version=null,n.checkLineBreaks=n.legacy,n.tagMap=Object.create(null),n.anchorMap=Object.create(null);0!==(C=n.input.charCodeAt(n.position))&&(Cf(n,!0,-1),C=n.input.charCodeAt(n.position),!(n.lineIndent>0||37!==C));){for(g=!0,C=n.input.charCodeAt(++n.position),t=n.position;0!==C&&!Pp(C);)C=n.input.charCodeAt(++n.position);for(c=[],(o=n.input.slice(t,n.position)).length<1&&Da(n,"directive name must not be less than one character in length");0!==C;){for(;cm(C);)C=n.input.charCodeAt(++n.position);if(35===C){do{C=n.input.charCodeAt(++n.position)}while(0!==C&&!D_(C));break}if(D_(C))break;for(t=n.position;0!==C&&!Pp(C);)C=n.input.charCodeAt(++n.position);c.push(n.input.slice(t,n.position))}0!==C&&ET(n),um.call(zy,o)?zy[o](n,o,c):bT(n,'unknown document directive "'+o+'"')}Cf(n,!0,-1),0===n.lineIndent&&45===n.input.charCodeAt(n.position)&&45===n.input.charCodeAt(n.position+1)&&45===n.input.charCodeAt(n.position+2)?(n.position+=3,Cf(n,!0,-1)):g&&Da(n,"directives end mark is expected"),jv(n,n.lineIndent-1,4,!1,!0),Cf(n,!0,-1),n.checkLineBreaks&&Zv.test(n.input.slice(s,n.position))&&bT(n,"non-ASCII line breaks are interpreted as content"),n.documents.push(n.result),n.position===n.lineStart&&t0(n)?46===n.input.charCodeAt(n.position)&&(n.position+=3,Cf(n,!0,-1)):n.position<n.length-1&&Da(n,"end of the stream or a document separator is expected")}function U2(n,s){s=s||{},0!==(n=String(n)).length&&(10!==n.charCodeAt(n.length-1)&&13!==n.charCodeAt(n.length-1)&&(n+="\n"),65279===n.charCodeAt(0)&&(n=n.slice(1)));var t=new Vy(n,s),o=n.indexOf("\0");for(-1!==o&&(t.position=o,Da(t,"null byte is not allowed in input")),t.input+="\0";32===t.input.charCodeAt(t.position);)t.lineIndent+=1,t.position+=1;for(;t.position<t.length-1;)CT(t);return t.documents}var AT=Object.prototype.toString,OT=Object.prototype.hasOwnProperty,ap={0:"\\0",7:"\\a",8:"\\b",9:"\\t",10:"\\n",11:"\\v",12:"\\f",13:"\\r",27:"\\e",34:'\\"',92:"\\\\",133:"\\N",160:"\\_",8232:"\\L",8233:"\\P"},HD=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"],Q2=/^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/;function NT(n){var s,t,o;if(s=n.toString(16).toUpperCase(),n<=255)t="x",o=2;else if(n<=65535)t="u",o=4;else{if(!(n<=4294967295))throw new sf("code point within a string may not be greater than 0xFFFFFFFF");t="U",o=8}return"\\"+t+of.repeat("0",o-s.length)+s}function UD(n){this.schema=n.schema||_T,this.indent=Math.max(1,n.indent||2),this.noArrayIndent=n.noArrayIndent||!1,this.skipInvalid=n.skipInvalid||!1,this.flowLevel=of.isNothing(n.flowLevel)?-1:n.flowLevel,this.styleMap=function(n,s){var t,o,c,g,C,D,P;if(null===s)return{};for(t={},c=0,g=(o=Object.keys(s)).length;c<g;c+=1)C=o[c],D=String(s[C]),"!!"===C.slice(0,2)&&(C="tag:yaml.org,2002:"+C.slice(2)),(P=n.compiledTypeMap.fallback[C])&&OT.call(P.styleAliases,D)&&(D=P.styleAliases[D]),t[C]=D;return t}(this.schema,n.styles||null),this.sortKeys=n.sortKeys||!1,this.lineWidth=n.lineWidth||80,this.noRefs=n.noRefs||!1,this.noCompatMode=n.noCompatMode||!1,this.condenseFlow=n.condenseFlow||!1,this.quotingType='"'===n.quotingType?2:1,this.forceQuotes=n.forceQuotes||!1,this.replacer="function"==typeof n.replacer?n.replacer:null,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function BD(n,s){for(var C,t=of.repeat(" ",s),o=0,c=-1,g="",D=n.length;o<D;)-1===(c=n.indexOf("\n",o))?(C=n.slice(o),o=D):(C=n.slice(o,c+1),o=c+1),C.length&&"\n"!==C&&(g+=t),g+=C;return g}function K2(n,s){return"\n"+of.repeat(" ",n.indent*s)}function o0(n){return 32===n||9===n}function Gv(n){return 32<=n&&n<=126||161<=n&&n<=55295&&8232!==n&&8233!==n||57344<=n&&n<=65533&&65279!==n||65536<=n&&n<=1114111}function q2(n){return Gv(n)&&65279!==n&&13!==n&&10!==n}function eA(n,s,t){var o=q2(n),c=o&&!o0(n);return(t?o:o&&44!==n&&91!==n&&93!==n&&123!==n&&125!==n)&&35!==n&&!(58===s&&!c)||q2(s)&&!o0(s)&&35===n||58===s&&c}function Vv(n,s){var o,t=n.charCodeAt(s);return t>=55296&&t<=56319&&s+1<n.length&&(o=n.charCodeAt(s+1))>=56320&&o<=57343?1024*(t-55296)+o-56320+65536:t}function jD(n){return/^\n* /.test(n)}function nA(n,s,t,o,c){n.dump=function(){if(0===s.length)return 2===n.quotingType?'""':"''";if(!n.noCompatMode&&(-1!==HD.indexOf(s)||Q2.test(s)))return 2===n.quotingType?'"'+s+'"':"'"+s+"'";var g=n.indent*Math.max(1,t),C=-1===n.lineWidth?-1:Math.max(Math.min(n.lineWidth,40),n.lineWidth-g);switch(function(n,s,t,o,c,g,C,D){var P,j=0,W=null,re=!1,oe=!1,me=-1!==o,_e=-1,Fe=function(n){return Gv(n)&&65279!==n&&!o0(n)&&45!==n&&63!==n&&58!==n&&44!==n&&91!==n&&93!==n&&123!==n&&125!==n&&35!==n&&38!==n&&42!==n&&33!==n&&124!==n&&61!==n&&62!==n&&39!==n&&34!==n&&37!==n&&64!==n&&96!==n}(Vv(n,0))&&function(n){return!o0(n)&&58!==n}(Vv(n,n.length-1));if(s||C)for(P=0;P<n.length;j>=65536?P+=2:P++){if(!Gv(j=Vv(n,P)))return 5;Fe=Fe&&eA(j,W,D),W=j}else{for(P=0;P<n.length;j>=65536?P+=2:P++){if(10===(j=Vv(n,P)))re=!0,me&&(oe=oe||P-_e-1>o&&" "!==n[_e+1],_e=P);else if(!Gv(j))return 5;Fe=Fe&&eA(j,W,D),W=j}oe=oe||me&&P-_e-1>o&&" "!==n[_e+1]}return re||oe?t>9&&jD(n)?5:C?2===g?5:2:oe?4:3:!Fe||C||c(n)?2===g?5:2:1}(s,o||n.flowLevel>-1&&t>=n.flowLevel,n.indent,C,function(j){return function(n,s){var t,o;for(t=0,o=n.implicitTypes.length;t<o;t+=1)if(n.implicitTypes[t].resolve(s))return!0;return!1}(n,j)},n.quotingType,n.forceQuotes&&!o,c)){case 1:return s;case 2:return"'"+s.replace(/'/g,"''")+"'";case 3:return"|"+rA(s,n.indent)+a0(BD(s,g));case 4:return">"+rA(s,n.indent)+a0(BD(function(n,s){for(var g,C,t=/(\n+)([^\n]*)/g,o=(j=void 0,j=n.indexOf("\n"),t.lastIndex=j=-1!==j?j:n.length,iA(n.slice(0,j),s)),c="\n"===n[0]||" "===n[0];C=t.exec(n);){var P=C[2];g=" "===P[0],o+=C[1]+(c||g||""===P?"":"\n")+iA(P,s),c=g}var j;return o}(s,C),g));case 5:return'"'+function(n){for(var o,s="",t=0,c=0;c<n.length;t>=65536?c+=2:c++)t=Vv(n,c),!(o=ap[t])&&Gv(t)?(s+=n[c],t>=65536&&(s+=n[c+1])):s+=o||NT(t);return s}(s)+'"';default:throw new sf("impossible error: invalid scalar style")}}()}function rA(n,s){var t=jD(n)?String(s):"",o="\n"===n[n.length-1];return t+(!o||"\n"!==n[n.length-2]&&"\n"!==n?o?"":"-":"+")+"\n"}function a0(n){return"\n"===n[n.length-1]?n.slice(0,-1):n}function iA(n,s){if(""===n||" "===n[0])return n;for(var o,g,t=/ [^ ]/g,c=0,C=0,D=0,P="";o=t.exec(n);)(D=o.index)-c>s&&(P+="\n"+n.slice(c,g=C>c?C:D),c=g+1),C=D;return P+="\n",(P+=n.length-c>s&&C>c?n.slice(c,C)+"\n"+n.slice(C+1):n.slice(c)).slice(1)}function sA(n,s,t){var o,c,g,C,D,P;for(g=0,C=(c=t?n.explicitTypes:n.implicitTypes).length;g<C;g+=1)if(((D=c[g]).instanceOf||D.predicate)&&(!D.instanceOf||"object"==typeof s&&s instanceof D.instanceOf)&&(!D.predicate||D.predicate(s))){if(n.tag=t?D.multi&&D.representName?D.representName(s):D.tag:"?",D.represent){if(P=n.styleMap[D.tag]||D.defaultStyle,"[object Function]"===AT.call(D.represent))o=D.represent(s,P);else{if(!OT.call(D.represent,P))throw new sf("!<"+D.tag+'> tag resolver accepts not "'+P+'" style');o=D.represent[P](s,P)}n.dump=o}return!0}return!1}function t_(n,s,t,o,c,g,C){n.tag=null,n.dump=t,sA(n,t,!1)||sA(n,t,!0);var j,D=AT.call(n.dump),P=o;o&&(o=n.flowLevel<0||n.flowLevel>s);var re,oe,W="[object Object]"===D||"[object Array]"===D;if(W&&(oe=-1!==(re=n.duplicates.indexOf(t))),(null!==n.tag&&"?"!==n.tag||oe||2!==n.indent&&s>0)&&(c=!1),oe&&n.usedDuplicates[re])n.dump="*ref_"+re;else{if(W&&oe&&!n.usedDuplicates[re]&&(n.usedDuplicates[re]=!0),"[object Object]"===D)o&&0!==Object.keys(n.dump).length?(function(n,s,t,o){var D,P,j,W,re,oe,c="",g=n.tag,C=Object.keys(t);if(!0===n.sortKeys)C.sort();else if("function"==typeof n.sortKeys)C.sort(n.sortKeys);else if(n.sortKeys)throw new sf("sortKeys must be a boolean or a function");for(D=0,P=C.length;D<P;D+=1)oe="",(!o||""!==c)&&(oe+=K2(n,s)),W=t[j=C[D]],n.replacer&&(W=n.replacer.call(t,j,W)),t_(n,s+1,j,!0,!0,!0)&&((re=null!==n.tag&&"?"!==n.tag||n.dump&&n.dump.length>1024)&&(n.dump&&10===n.dump.charCodeAt(0)?oe+="?":oe+="? "),oe+=n.dump,re&&(oe+=K2(n,s)),t_(n,s+1,W,!0,re)&&(n.dump&&10===n.dump.charCodeAt(0)?oe+=":":oe+=": ",c+=oe+=n.dump));n.tag=g,n.dump=c||"{}"}(n,s,n.dump,c),oe&&(n.dump="&ref_"+re+n.dump)):(function(n,s,t){var C,D,P,j,W,o="",c=n.tag,g=Object.keys(t);for(C=0,D=g.length;C<D;C+=1)W="",""!==o&&(W+=", "),n.condenseFlow&&(W+='"'),j=t[P=g[C]],n.replacer&&(j=n.replacer.call(t,P,j)),t_(n,s,P,!1,!1)&&(n.dump.length>1024&&(W+="? "),W+=n.dump+(n.condenseFlow?'"':"")+":"+(n.condenseFlow?"":" "),t_(n,s,j,!1,!1)&&(o+=W+=n.dump));n.tag=c,n.dump="{"+o+"}"}(n,s,n.dump),oe&&(n.dump="&ref_"+re+" "+n.dump));else if("[object Array]"===D)o&&0!==n.dump.length?(function(n,s,t,o){var C,D,P,c="",g=n.tag;for(C=0,D=t.length;C<D;C+=1)P=t[C],n.replacer&&(P=n.replacer.call(t,String(C),P)),(t_(n,s+1,P,!0,!0,!1,!0)||void 0===P&&t_(n,s+1,null,!0,!0,!1,!0))&&((!o||""!==c)&&(c+=K2(n,s)),n.dump&&10===n.dump.charCodeAt(0)?c+="-":c+="- ",c+=n.dump);n.tag=g,n.dump=c||"[]"}(n,n.noArrayIndent&&!C&&s>0?s-1:s,n.dump,c),oe&&(n.dump="&ref_"+re+n.dump)):(function(n,s,t){var g,C,D,o="",c=n.tag;for(g=0,C=t.length;g<C;g+=1)D=t[g],n.replacer&&(D=n.replacer.call(t,String(g),D)),(t_(n,s,D,!1,!1)||void 0===D&&t_(n,s,null,!1,!1))&&(""!==o&&(o+=","+(n.condenseFlow?"":" ")),o+=n.dump);n.tag=c,n.dump="["+o+"]"}(n,s,n.dump),oe&&(n.dump="&ref_"+re+" "+n.dump));else{if("[object String]"!==D){if("[object Undefined]"===D)return!1;if(n.skipInvalid)return!1;throw new sf("unacceptable kind of an object to dump "+D)}"?"!==n.tag&&nA(n,n.dump,s,g,P)}null!==n.tag&&"?"!==n.tag&&(j=encodeURI("!"===n.tag[0]?n.tag.slice(1):n.tag).replace(/!/g,"%21"),j="!"===n.tag[0]?"!"+j:"tag:yaml.org,2002:"===j.slice(0,18)?"!!"+j.slice(18):"!<"+j+">",n.dump=j+" "+n.dump)}return!0}function zD(n,s){var c,g,t=[],o=[];for(l0(n,t,o),c=0,g=o.length;c<g;c+=1)s.duplicates.push(t[o[c]]);s.usedDuplicates=new Array(g)}function l0(n,s,t){var o,c,g;if(null!==n&&"object"==typeof n)if(-1!==(c=s.indexOf(n)))-1===t.indexOf(c)&&t.push(c);else if(s.push(n),Array.isArray(n))for(c=0,g=n.length;c<g;c+=1)l0(n[c],s,t);else for(c=0,g=(o=Object.keys(n)).length;c<g;c+=1)l0(n[o[c]],s,t)}function kT(n,s){return function(){throw new Error("Function yaml."+n+" is removed in js-yaml 4. Use yaml."+s+" instead, which is now safe by default.")}}var WD=Jf,bN=aT,Qy=lT,lA=hT,EN=S2,TN=_T,SN=function(n,s){var t=U2(n,s);if(0!==t.length){if(1===t.length)return t[0];throw new sf("expected a single document in the stream, but found more")}},JD=function(n,s,t){null!==s&&"object"==typeof s&&void 0===t&&(t=s,s=null);var o=U2(n,t);if("function"!=typeof s)return o;for(var c=0,g=o.length;c<g;c+=1)s(o[c])},QD=function(n,s){var t=new UD(s=s||{});t.noRefs||zD(n,t);var o=n;return t.replacer&&(o=t.replacer.call({"":o},"",o)),t_(t,0,o,!0,!0)?t.dump+"\n":""},XD=sf,KD={binary:w2,float:pT,map:sD,null:uT,pairs:x2,set:D2,timestamp:hD,bool:_2,int:fT,merge:_D,omap:mD,seq:Yy,str:X1},qD=kT("safeLoad","load"),CN=kT("safeLoadAll","loadAll"),e3=kT("safeDump","dump");const $T={Type:WD,Schema:bN,FAILSAFE_SCHEMA:Qy,JSON_SCHEMA:lA,CORE_SCHEMA:EN,DEFAULT_SCHEMA:TN,load:SN,loadAll:JD,dump:QD,YAMLException:XD,types:KD,safeLoad:qD,safeLoadAll:CN,safeDump:e3},MN="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:window,{FormData:n3,Blob:Xy,File:uA}=MN;function fm(n){return function(n){if(G1(n))return VE(n)}(n)||jM(n)||V1(n)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}var R_=i(46558),n_=i.n(R_),o3=function(s){return":/?#[]@!$&'()*+,;=".indexOf(s)>-1},s3=function(s){return/^[a-z0-9\-._~]+$/i.test(s)};function zv(n){var s,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=t.escape,c=arguments.length>2?arguments[2]:void 0;return"number"==typeof n&&(n=n.toString()),"string"==typeof n&&n.length&&o?c?JSON.parse(n):Tu()(s=fm(n)).call(s,function(g){var C,D;if(s3(g)||o3(g)&&"unsafe"===o)return g;var P=new TextEncoder;return Tu()(C=Tu()(D=QE()(P.encode(g))).call(D,function(W){var re;return n_()(re="0".concat(W.toString(16).toUpperCase())).call(re,-2)})).call(C,function(W){return"%".concat(W)}).join("")}).join(""):n}function cA(n){var s=n.value;return Array.isArray(s)?function(n){var s=n.key,t=n.value,o=n.style,c=n.explode,g=n.escape,C=function(re){return zv(re,{escape:g})};if("simple"===o)return Tu()(t).call(t,function(W){return C(W)}).join(",");if("label"===o)return".".concat(Tu()(t).call(t,function(W){return C(W)}).join("."));if("matrix"===o)return Tu()(t).call(t,function(W){return C(W)}).reduce(function(W,re){var oe,me,_e;return!W||c?ra()(me=ra()(_e="".concat(W||"",";")).call(_e,s,"=")).call(me,re):ra()(oe="".concat(W,",")).call(oe,re)},"");if("form"===o){var D=c?"&".concat(s,"="):",";return Tu()(t).call(t,function(W){return C(W)}).join(D)}if("spaceDelimited"===o){var P=c?"".concat(s,"="):"";return Tu()(t).call(t,function(W){return C(W)}).join(" ".concat(P))}if("pipeDelimited"===o){var j=c?"".concat(s,"="):"";return Tu()(t).call(t,function(W){return C(W)}).join("|".concat(j))}}(n):"object"===vc(s)?function(n){var s=n.key,t=n.value,o=n.style,c=n.explode,g=n.escape,C=function(j){return zv(j,{escape:g})},D=xu()(t);return"simple"===o?D.reduce(function(P,j){var W,re,oe,me=C(t[j]),_e=c?"=":",",Fe=P?"".concat(P,","):"";return ra()(W=ra()(re=ra()(oe="".concat(Fe)).call(oe,j)).call(re,_e)).call(W,me)},""):"label"===o?D.reduce(function(P,j){var W,re,oe,me=C(t[j]),_e=c?"=":".",Fe=P?"".concat(P,"."):".";return ra()(W=ra()(re=ra()(oe="".concat(Fe)).call(oe,j)).call(re,_e)).call(W,me)},""):"matrix"===o&&c?D.reduce(function(P,j){var W,re,oe=C(t[j]),me=P?"".concat(P,";"):";";return ra()(W=ra()(re="".concat(me)).call(re,j,"=")).call(W,oe)},""):"matrix"===o?D.reduce(function(P,j){var W,re,oe=C(t[j]),me=P?"".concat(P,","):";".concat(s,"=");return ra()(W=ra()(re="".concat(me)).call(re,j,",")).call(W,oe)},""):"form"===o?D.reduce(function(P,j){var W,re,oe,me,_e=C(t[j]),Fe=P?ra()(W="".concat(P)).call(W,c?"&":","):"",Re=c?"=":",";return ra()(re=ra()(oe=ra()(me="".concat(Fe)).call(me,j)).call(oe,Re)).call(re,_e)},""):void 0}(n):function(n){var C,s=n.key,t=n.value,o=n.style,c=n.escape,g=function(P){return zv(P,{escape:c})};return"simple"===o?g(t):"label"===o?".".concat(g(t)):"matrix"===o?ra()(C=";".concat(s,"=")).call(C,g(t)):"form"===o||"deepObject"===o?g(t):void 0}(n)}const dA=function(s,t){t.body=s};var fA={serializeRes:Ky,mergeInQueryOrForm:_A};function HT(n){return pA.apply(this,arguments)}function pA(){return(pA=z1(e_().mark(function n(s){var t,c,g,C,D=arguments;return e_().wrap(function(j){for(;;)switch(j.prev=j.next){case 0:if(t=D.length>1&&void 0!==D[1]?D[1]:{},"object"===vc(s)&&(s=(t=s).url),t.headers=t.headers||{},fA.mergeInQueryOrForm(t),t.headers&&xu()(t.headers).forEach(function(W){var re=t.headers[W];"string"==typeof re&&(t.headers[W]=re.replace(/\n+/g," "))}),!t.requestInterceptor){j.next=12;break}return j.next=8,t.requestInterceptor(t);case 8:if(j.t0=j.sent,j.t0){j.next=11;break}j.t0=t;case 11:t=j.t0;case 12:return/multipart\/form-data/i.test(t.headers["content-type"]||t.headers["Content-Type"])&&t.body instanceof n3&&(delete t.headers["content-type"],delete t.headers["Content-Type"]),j.prev=14,j.next=17,(t.userFetch||fetch)(t.url,t);case 17:return c=j.sent,j.next=20,fA.serializeRes(c,s,t);case 20:if(c=j.sent,!t.responseInterceptor){j.next=28;break}return j.next=24,t.responseInterceptor(c);case 24:if(j.t1=j.sent,j.t1){j.next=27;break}j.t1=c;case 27:c=j.t1;case 28:j.next=39;break;case 30:if(j.prev=30,j.t2=j.catch(14),c){j.next=34;break}throw j.t2;case 34:throw(g=new Error(c.statusText||"response status is ".concat(c.status))).status=c.status,g.statusCode=c.status,g.responseError=j.t2,g;case 39:if(c.ok){j.next=45;break}throw(C=new Error(c.statusText||"response status is ".concat(c.status))).status=c.status,C.statusCode=c.status,C.response=c,C;case 45:return j.abrupt("return",c);case 46:case"end":return j.stop()}},n,null,[[14,30]])}))).apply(this,arguments)}var AN=function(){var s=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return/(json|xml|yaml|text)\b/.test(s)};function ON(n,s){return s&&(0===s.indexOf("application/json")||s.indexOf("+json")>0)?JSON.parse(n):$T.load(n)}function Ky(n,s){var t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=t.loadSpec,c=void 0!==o&&o,g={ok:n.ok,url:n.url||s,status:n.status,statusText:n.statusText,headers:d3(n.headers)},C=g.headers["content-type"],D=c||AN(C),P=D?n.text:n.blob||n.buffer;return P.call(n).then(function(j){if(g.text=j,g.data=j,D)try{var W=ON(j,C);g.body=W,g.obj=W}catch(re){g.parseError=re}return g})}function c3(n){return Yv()(n).call(n,", ")?n.split(", "):n}function d3(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return"function"!=typeof Qm()(n)?{}:QE()(Qm()(n).call(n)).reduce(function(s,t){var o=bh(t,2);return s[o[0]]=c3(o[1]),s},{})}function UT(n,s){return!s&&"undefined"!=typeof navigator&&(s=navigator),s&&"ReactNative"===s.product?!(!n||"object"!==vc(n)||"string"!=typeof n.uri):!!(void 0!==uA&&n instanceof uA||void 0!==Xy&&n instanceof Xy||ArrayBuffer.isView(n))||null!==n&&"object"===vc(n)&&"function"==typeof n.pipe}function f3(n,s){return Array.isArray(n)&&n.some(function(t){return UT(t,s)})}var p3={form:",",spaceDelimited:"%20",pipeDelimited:"|"},h3={csv:",",ssv:"%20",tsv:"%09",pipes:"|"};function hA(n,s){var t=arguments.length>2&&void 0!==arguments[2]&&arguments[2],o=s.collectionFormat,c=s.allowEmptyValue,g=s.serializationOption,C=s.encoding,D="object"!==vc(s)||Array.isArray(s)?s:s.value,P=t?function(_e){return _e.toString()}:function(_e){return encodeURIComponent(_e)},j=P(n);if(void 0===D&&c)return[[j,""]];if(UT(D)||f3(D))return[[j,D]];if(g)return r_(n,D,t,g);if(C){if([vc(C.style),vc(C.explode),vc(C.allowReserved)].some(function(_e){return"undefined"!==_e})){var W=C.style,re=C.explode,oe=C.allowReserved;return r_(n,D,t,{style:W,explode:re,allowReserved:oe})}if(C.contentType){if("application/json"===C.contentType){var me="string"==typeof D?D:Wp()(D);return[[j,P(me)]]}return[[j,P(D.toString())]]}return"object"!==vc(D)?[[j,P(D)]]:Array.isArray(D)&&D.every(function(_e){return"object"!==vc(_e)})?[[j,Tu()(D).call(D,P).join(",")]]:[[j,P(Wp()(D))]]}return"object"!==vc(D)?[[j,P(D)]]:Array.isArray(D)?"multi"===o?[[j,Tu()(D).call(D,P)]]:[[j,Tu()(D).call(D,P).join(h3[o||"csv"])]]:[[j,""]]}function r_(n,s,t,o){var c,W,re,g=o.style||"form",C=void 0===o.explode?"form"===g:o.explode,D=!t&&(o&&o.allowReserved?"unsafe":"reserved"),P=function(me){return zv(me,{escape:D})},j=t?function(oe){return oe}:function(oe){return zv(oe,{escape:D})};return"object"!==vc(s)?[[j(n),P(s)]]:Array.isArray(s)?C?[[j(n),Tu()(s).call(s,P)]]:[[j(n),Tu()(s).call(s,P).join(p3[g])]]:"deepObject"===g?Tu()(W=xu()(s)).call(W,function(oe){var me;return[j(ra()(me="".concat(n,"[")).call(me,oe,"]")),P(s[oe])]}):C?Tu()(re=xu()(s)).call(re,function(oe){return[j(oe),P(s[oe])]}):[[j(n),Tu()(c=xu()(s)).call(c,function(oe){var me;return[ra()(me="".concat(j(oe),",")).call(me,P(s[oe]))]}).join(",")]]}function wN(n){return qE()(n).reduce(function(s,t){var D,o=bh(t,2),C=Ng(hA(o[0],o[1],!0));try{for(C.s();!(D=C.n()).done;){var P=bh(D.value,2),j=P[0],W=P[1];if(Array.isArray(W)){var oe,re=Ng(W);try{for(re.s();!(oe=re.n()).done;){var me=oe.value;if(ArrayBuffer.isView(me)){var _e=new Xy([me]);s.append(j,_e)}else s.append(j,me)}}catch(Re){re.e(Re)}finally{re.f()}}else if(ArrayBuffer.isView(W)){var Fe=new Xy([W]);s.append(j,Fe)}else s.append(j,W)}}catch(Re){C.e(Re)}finally{C.f()}return s},new n3)}function BT(n){var s=xu()(n).reduce(function(t,o){var g,c=Ng(hA(o,n[o]));try{for(c.s();!(g=c.n()).done;){var C=bh(g.value,2);t[C[0]]=C[1]}}catch(j){c.e(j)}finally{c.f()}return t},{});return tT().stringify(s,{encode:!1,indices:!1})||""}function _A(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},s=n.url,t=void 0===s?"":s,o=n.query,c=n.form,g=function(){for(var we=arguments.length,U=new Array(we),pt=0;pt<we;pt++)U[pt]=arguments[pt];var ht=Np()(U).call(U,function(Dt){return Dt}).join("&");return ht?"?".concat(ht):""};if(c){var C=xu()(c).some(function(Le){var we=c[Le].value;return UT(we)||f3(we)}),D=n.headers["content-type"]||n.headers["Content-Type"];if(C||/multipart\/form-data/i.test(D)){var P=wN(n.form);dA(P,n)}else n.body=BT(c);delete n.form}if(o){var j=t.split("?"),W=bh(j,2),re=W[0],oe=W[1],me="";if(oe){var _e=tT().parse(oe),Fe=xu()(o);Fe.forEach(function(Le){return delete _e[Le]}),me=tT().stringify(_e,{encode:!0})}var Re=g(me,BT(o));n.url=re+Re,delete n.query}return n}function gA(n,s,t){return t=t||function(o){return o},s=s||function(o){return o},function(o){return"string"==typeof o&&(o={url:o}),fA.mergeInQueryOrForm(o),o=s(o),t(n(o))}}var YT=i(22714),c0=i(23591),ZT=i(14306),d0=i(45862),qy=i(6379),f0=i(51134),eb=i(70891),Wv=i(77576);function jT(n,s,t){return s in n?Wv(n,s,{value:t,enumerable:!0,configurable:!0,writable:!0}):n[s]=t,n}function mA(n,s){var t=YT(n);if(c0){var o=c0(n);s&&(o=ZT(o).call(o,function(c){return d0(n,c).enumerable})),t.push.apply(t,o)}return t}function Od(n){for(var s=1;s<arguments.length;s++){var t,o,c=null!=arguments[s]?arguments[s]:{};s%2?qy(t=mA(Object(c),!0)).call(t,function(g){jT(n,g,c[g])}):f0?eb(n,f0(c)):qy(o=mA(Object(c))).call(o,function(g){Wv(n,g,d0(c,g))})}return n}function tb(n,s){if(!(n instanceof s))throw new TypeError("Cannot call a class as a function")}function vA(n,s){for(var t=0;t<s.length;t++){var o=s[t];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Wv(n,o.key,o)}}function GT(n,s,t){return s&&vA(n.prototype,s),t&&vA(n,t),Wv(n,"prototype",{writable:!1}),n}var n,_3=i(30508),Sh=i.n(_3),g3=i(45819),lp=i.n(g3),p0=i(33814),h0=i.n(p0),yA=(n=function(s,t){return(n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(o,c){o.__proto__=c}||function(o,c){for(var g in c)c.hasOwnProperty(g)&&(o[g]=c[g])})(s,t)},function(s,t){function o(){this.constructor=s}n(s,t),s.prototype=null===t?Object.create(t):(o.prototype=t.prototype,new o)}),nb=Object.prototype.hasOwnProperty;function Jv(n,s){return nb.call(n,s)}function rb(n){if(Array.isArray(n)){for(var s=new Array(n.length),t=0;t<s.length;t++)s[t]=""+t;return s}if(Object.keys)return Object.keys(n);var o=[];for(var c in n)Jv(n,c)&&o.push(c);return o}function up(n){switch(typeof n){case"object":return JSON.parse(JSON.stringify(n));case"undefined":return null;default:return n}}function VT(n){for(var o,s=0,t=n.length;s<t;){if(!((o=n.charCodeAt(s))>=48&&o<=57))return!1;s++}return!0}function Pg(n){return-1===n.indexOf("/")&&-1===n.indexOf("~")?n:n.replace(/~/g,"~0").replace(/\//g,"~1")}function bA(n){return n.replace(/~1/g,"/").replace(/~0/g,"~")}function zT(n){if(void 0===n)return!0;if(n)if(Array.isArray(n)){for(var s=0,t=n.length;s<t;s++)if(zT(n[s]))return!0}else if("object"==typeof n)for(var o=rb(n),c=o.length,g=0;g<c;g++)if(zT(n[o[g]]))return!0;return!1}function TA(n,s){var t=[n];for(var o in s){var c="object"==typeof s[o]?JSON.stringify(s[o],null,2):s[o];void 0!==c&&t.push(o+": "+c)}return t.join("\n")}var SA=function(n){function s(t,o,c,g,C){var D=this.constructor,P=n.call(this,TA(t,{name:o,index:c,operation:g,tree:C}))||this;return P.name=o,P.index=c,P.operation=g,P.tree=C,Object.setPrototypeOf(P,D.prototype),P.message=TA(t,{name:o,index:c,operation:g,tree:C}),P}return yA(s,n),s}(Error),yc=SA,_0=up,pm={add:function(n,s,t){return n[s]=this.value,{newDocument:t}},remove:function(n,s,t){var o=n[s];return delete n[s],{newDocument:t,removed:o}},replace:function(n,s,t){var o=n[s];return n[s]=this.value,{newDocument:t,removed:o}},move:function(n,s,t){var o=g0(t,this.path);o&&(o=up(o));var c=qm(t,{op:"remove",path:this.from}).removed;return qm(t,{op:"add",path:this.path,value:c}),{newDocument:t,removed:o}},copy:function(n,s,t){var o=g0(t,this.from);return qm(t,{op:"add",path:this.path,value:up(o)}),{newDocument:t}},test:function(n,s,t){return{newDocument:t,test:v0(n[s],this.value)}},_get:function(n,s,t){return this.value=n[s],{newDocument:t}}},v3={add:function(n,s,t){return VT(s)?n.splice(s,0,this.value):n[s]=this.value,{newDocument:t,index:s}},remove:function(n,s,t){return{newDocument:t,removed:n.splice(s,1)[0]}},replace:function(n,s,t){var o=n[s];return n[s]=this.value,{newDocument:t,removed:o}},move:pm.move,copy:pm.copy,test:pm.test,_get:pm._get};function g0(n,s){if(""==s)return n;var t={op:"_get",path:s};return qm(n,t),t.value}function qm(n,s,t,o,c,g){if(void 0===t&&(t=!1),void 0===o&&(o=!0),void 0===c&&(c=!0),void 0===g&&(g=0),t&&("function"==typeof t?t(s,0,n,s.path):m0(s,0)),""===s.path){var C={newDocument:n};if("add"===s.op)return C.newDocument=s.value,C;if("replace"===s.op)return C.newDocument=s.value,C.removed=n,C;if("move"===s.op||"copy"===s.op)return C.newDocument=g0(n,s.from),"move"===s.op&&(C.removed=n),C;if("test"===s.op){if(C.test=v0(n,s.value),!1===C.test)throw new yc("Test operation failed","TEST_OPERATION_FAILED",g,s,n);return C.newDocument=n,C}if("remove"===s.op)return C.removed=n,C.newDocument=null,C;if("_get"===s.op)return s.value=n,C;if(t)throw new yc("Operation `op` property is not one of operations defined in RFC-6902","OPERATION_OP_INVALID",g,s,n);return C}o||(n=up(n));var P=(s.path||"").split("/"),j=n,W=1,re=P.length,oe=void 0,me=void 0,_e=void 0;for(_e="function"==typeof t?t:m0;;){if((me=P[W])&&-1!=me.indexOf("~")&&(me=bA(me)),c&&("__proto__"==me||"prototype"==me&&W>0&&"constructor"==P[W-1]))throw new TypeError("JSON-Patch: modifying `__proto__` or `constructor/prototype` prop is banned for security reasons, if this was on purpose, please set `banPrototypeModifications` flag false and pass it to this function. More info in fast-json-patch README");if(t&&void 0===oe&&(void 0===j[me]?oe=P.slice(0,W).join("/"):W==re-1&&(oe=s.path),void 0!==oe&&_e(s,0,n,oe)),W++,Array.isArray(j)){if("-"===me)me=j.length;else{if(t&&!VT(me))throw new yc("Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index","OPERATION_PATH_ILLEGAL_ARRAY_INDEX",g,s,n);VT(me)&&(me=~~me)}if(W>=re){if(t&&"add"===s.op&&me>j.length)throw new yc("The specified index MUST NOT be greater than the number of elements in the array","OPERATION_VALUE_OUT_OF_BOUNDS",g,s,n);if(!1===(C=v3[s.op].call(s,j,me,n)).test)throw new yc("Test operation failed","TEST_OPERATION_FAILED",g,s,n);return C}}else if(W>=re){if(!1===(C=pm[s.op].call(s,j,me,n)).test)throw new yc("Test operation failed","TEST_OPERATION_FAILED",g,s,n);return C}if(j=j[me],t&&W<re&&(!j||"object"!=typeof j))throw new yc("Cannot perform operation at the desired path","OPERATION_PATH_UNRESOLVABLE",g,s,n)}}function lg(n,s,t,o,c){if(void 0===o&&(o=!0),void 0===c&&(c=!0),t&&!Array.isArray(s))throw new yc("Patch sequence must be an array","SEQUENCE_NOT_AN_ARRAY");o||(n=up(n));for(var g=new Array(s.length),C=0,D=s.length;C<D;C++)g[C]=qm(n,s[C],t,!0,c,C),n=g[C].newDocument;return g.newDocument=n,g}function y3(n,s,t){var o=qm(n,s);if(!1===o.test)throw new yc("Test operation failed","TEST_OPERATION_FAILED",t,s,n);return o.newDocument}function m0(n,s,t,o){if("object"!=typeof n||null===n||Array.isArray(n))throw new yc("Operation is not an object","OPERATION_NOT_AN_OBJECT",s,n,t);if(!pm[n.op])throw new yc("Operation `op` property is not one of operations defined in RFC-6902","OPERATION_OP_INVALID",s,n,t);if("string"!=typeof n.path)throw new yc("Operation `path` property is not a string","OPERATION_PATH_INVALID",s,n,t);if(0!==n.path.indexOf("/")&&n.path.length>0)throw new yc('Operation `path` property must start with "/"',"OPERATION_PATH_INVALID",s,n,t);if(("move"===n.op||"copy"===n.op)&&"string"!=typeof n.from)throw new yc("Operation `from` property is not present (applicable in `move` and `copy` operations)","OPERATION_FROM_REQUIRED",s,n,t);if(("add"===n.op||"replace"===n.op||"test"===n.op)&&void 0===n.value)throw new yc("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_REQUIRED",s,n,t);if(("add"===n.op||"replace"===n.op||"test"===n.op)&&zT(n.value))throw new yc("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED",s,n,t);if(t)if("add"==n.op){var c=n.path.split("/").length,g=o.split("/").length;if(c!==g+1&&c!==g)throw new yc("Cannot perform an `add` operation at the desired path","OPERATION_PATH_CANNOT_ADD",s,n,t)}else if("replace"===n.op||"remove"===n.op||"_get"===n.op){if(n.path!==o)throw new yc("Cannot perform the operation at a path that does not exist","OPERATION_PATH_UNRESOLVABLE",s,n,t)}else if("move"===n.op||"copy"===n.op){var D=WT([{op:"_get",path:n.from,value:void 0}],t);if(D&&"OPERATION_PATH_UNRESOLVABLE"===D.name)throw new yc("Cannot perform the operation from a path that does not exist","OPERATION_FROM_UNRESOLVABLE",s,n,t)}}function WT(n,s,t){try{if(!Array.isArray(n))throw new yc("Patch sequence must be an array","SEQUENCE_NOT_AN_ARRAY");if(s)lg(up(s),up(n),t||!0);else{t=t||m0;for(var o=0;o<n.length;o++)t(n[o],o,s,void 0)}}catch(c){if(c instanceof yc)return c;throw c}}function v0(n,s){if(n===s)return!0;if(n&&s&&"object"==typeof n&&"object"==typeof s){var c,g,C,t=Array.isArray(n),o=Array.isArray(s);if(t&&o){if((g=n.length)!=s.length)return!1;for(c=g;0!=c--;)if(!v0(n[c],s[c]))return!1;return!0}if(t!=o)return!1;var D=Object.keys(n);if((g=D.length)!==Object.keys(s).length)return!1;for(c=g;0!=c--;)if(!s.hasOwnProperty(D[c]))return!1;for(c=g;0!=c--;)if(!v0(n[C=D[c]],s[C]))return!1;return!0}return n!=n&&s!=s}var JT=new WeakMap,b3=function(s){this.observers=new Map,this.obj=s},Ig=function(s,t){this.callback=s,this.observer=t};function Xv(n,s){s.unobserve()}function E3(n,s){var o,c=function(n){return JT.get(n)}(n);if(c){var g=function(n,s){return n.observers.get(s)}(c,s);o=g&&g.observer}else c=new b3(n),JT.set(n,c);if(o)return o;if(o={},c.value=up(n),s){o.callback=s,o.next=null;var C=function(){QT(o)},D=function(){clearTimeout(o.next),o.next=setTimeout(C)};"undefined"!=typeof window&&(window.addEventListener("mouseup",D),window.addEventListener("keyup",D),window.addEventListener("mousedown",D),window.addEventListener("keydown",D),window.addEventListener("change",D))}return o.patches=[],o.object=n,o.unobserve=function(){QT(o),clearTimeout(o.next),function(n,s){n.observers.delete(s.callback)}(c,o),"undefined"!=typeof window&&(window.removeEventListener("mouseup",D),window.removeEventListener("keyup",D),window.removeEventListener("mousedown",D),window.removeEventListener("keydown",D),window.removeEventListener("change",D))},c.observers.set(s,new Ig(s,o)),o}function QT(n,s){void 0===s&&(s=!1);var t=JT.get(n.object);XT(t.value,n.object,n.patches,"",s),n.patches.length&&lg(t.value,n.patches);var o=n.patches;return o.length>0&&(n.patches=[],n.callback&&n.callback(o)),o}function XT(n,s,t,o,c){if(s!==n){"function"==typeof s.toJSON&&(s=s.toJSON());for(var g=rb(s),C=rb(n),P=!1,j=C.length-1;j>=0;j--){var re=n[W=C[j]];if(!Jv(s,W)||void 0===s[W]&&void 0!==re&&!1===Array.isArray(s))Array.isArray(n)===Array.isArray(s)?(c&&t.push({op:"test",path:o+"/"+Pg(W),value:up(re)}),t.push({op:"remove",path:o+"/"+Pg(W)}),P=!0):(c&&t.push({op:"test",path:o,value:n}),t.push({op:"replace",path:o,value:s}));else{var oe=s[W];"object"==typeof re&&null!=re&&"object"==typeof oe&&null!=oe&&Array.isArray(re)===Array.isArray(oe)?XT(re,oe,t,o+"/"+Pg(W),c):re!==oe&&(c&&t.push({op:"test",path:o+"/"+Pg(W),value:up(re)}),t.push({op:"replace",path:o+"/"+Pg(W),value:up(oe)}))}}if(P||g.length!=C.length)for(j=0;j<g.length;j++){var W;!Jv(n,W=g[j])&&void 0!==s[W]&&t.push({op:"add",path:o+"/"+Pg(W),value:up(s[W])})}}}function CA(n,s,t){void 0===t&&(t=!1);var o=[];return XT(n,s,o,"",t),o}Object.assign({},r,u,{JsonPatchError:SA,deepClone:up,escapePathComponent:Pg,unescapePathComponent:bA});var MA=i(89225),AA=i.n(MA);const zu={add:function(n,s){return{op:"add",path:n,value:s}},replace:ug,remove:function(n){return{op:"remove",path:n}},merge:function(n,s){return{type:"mutation",op:"merge",path:n,value:s}},mergeDeep:function(n,s){return{type:"mutation",op:"mergeDeep",path:n,value:s}},context:function(n,s){return{type:"context",path:n,value:s}},getIn:function(n,s){return s.reduce(function(t,o){return void 0!==o&&t?t[o]:t},n)},applyPatch:function(n,s,t){if(t=t||{},"merge"===(s=Od(Od({},s),{},{path:s.path&&OA(s.path)})).op){var o=le(n,s.path);Sh()(o,s.value),lg(n,[ug(s.path,o)])}else if("mergeDeep"===s.op){var c=le(n,s.path),g=AA()(c,s.value);n=lg(n,[ug(s.path,g)]).newDocument}else if("add"===s.op&&""===s.path&&Kv(s.value)){lg(n,xu()(s.value).reduce(function(re,oe){return re.push({op:"add",path:"/".concat(OA(oe)),value:s.value[oe]}),re},[]))}else if("replace"===s.op&&""===s.path){var P=s.value;t.allowMetaPatches&&s.meta&&M(s)&&(Array.isArray(s.value)||Kv(s.value))&&(P=Od(Od({},P),s.meta)),n=P}else if(lg(n,[s]),t.allowMetaPatches&&s.meta&&M(s)&&(Array.isArray(s.value)||Kv(s.value))){var W=Od(Od({},le(n,s.path)),s.meta);lg(n,[ug(s.path,W)])}return n},parentPathMatch:function(n,s){if(!Array.isArray(s))return!1;for(var t=0,o=s.length;t<o;t+=1)if(s[t]!==n[t])return!1;return!0},flatten:b0,fullyNormalizeArray:function(n){return w3(b0(O3(n)))},normalizeArray:O3,isPromise:function(n){return Kv(n)&&x3(n.then)},forEachNew:function(n,s){try{return A3(n,eS,s)}catch(t){return t}},forEachNewPrimitive:function(n,s){try{return A3(n,qT,s)}catch(t){return t}},isJsonPatch:l,isContextPatch:function(n){return te(n)&&"context"===n.type},isPatch:te,isMutation:m,isAdditiveMutation:M,isGenerator:function(n){return"[object GeneratorFunction]"===Object.prototype.toString.call(n)},isFunction:x3,isObject:Kv,isError:function(n){return n instanceof Error}};function OA(n){return Array.isArray(n)?n.length<1?"":"/".concat(Tu()(n).call(n,function(s){return(s+"").replace(/~/g,"~0").replace(/\//g,"~1")}).join("/")):n}function ug(n,s,t){return{op:"replace",path:n,value:s,meta:t}}function A3(n,s,t){var o;return w3(b0(Tu()(o=Np()(n).call(n,M)).call(o,function(D){return s(D.value,t,D.path)})||[]))}function qT(n,s,t){return t=t||[],Array.isArray(n)?Tu()(n).call(n,function(c,g){return qT(c,s,ra()(t).call(t,g))}):Kv(n)?Tu()(o=xu()(n)).call(o,function(c){return qT(n[c],s,ra()(t).call(t,c))}):s(n,t[t.length-1],t);var o}function eS(n,s,t){var o=[];if((t=t||[]).length>0){var c=s(n,t[t.length-1],t);c&&(o=ra()(o).call(o,c))}if(Array.isArray(n)){var g=Tu()(n).call(n,function(P,j){return eS(P,s,ra()(t).call(t,j))});g&&(o=ra()(o).call(o,g))}else if(Kv(n)){var C,D=Tu()(C=xu()(n)).call(C,function(P){return eS(n[P],s,ra()(t).call(t,P))});D&&(o=ra()(o).call(o,D))}return b0(o)}function O3(n){return Array.isArray(n)?n:[n]}function b0(n){var s;return ra()(s=[]).apply(s,fm(Tu()(n).call(n,function(t){return Array.isArray(t)?b0(t):t})))}function w3(n){return Np()(n).call(n,function(s){return void 0!==s})}function Kv(n){return n&&"object"===vc(n)}function x3(n){return n&&"function"==typeof n}function l(n){if(te(n)){var s=n.op;return"add"===s||"remove"===s||"replace"===s}return!1}function m(n){return l(n)||te(n)&&"mutation"===n.type}function M(n){return m(n)&&("add"===n.op||"replace"===n.op||"merge"===n.op||"mergeDeep"===n.op)}function te(n){return n&&"object"===vc(n)}function le(n,s){try{return g0(n,s)}catch(t){return console.error(t),{}}}var Ne=i(17015),qe=i.n(Ne),wt=i(71455),ln=i.n(wt),dn=i(38505);function nr(n,s){function t(){Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack;for(var o=arguments.length,c=new Array(o),g=0;g<o;g++)c[g]=arguments[g];this.message=c[0],s&&s.apply(this,c)}return(t.prototype=new Error).name=n,t.prototype.constructor=t,t}var Rr=i(18807),Ti=i.n(Rr),ii=["properties"],Oo=["properties"],Xi=["definitions","parameters","responses","securityDefinitions","components/schemas","components/responses","components/parameters","components/securitySchemes"],ua=["schema/example","items/example"];function Xa(n){var s=n[n.length-1],t=n[n.length-2],o=n.join("/");return ii.indexOf(s)>-1&&-1===Oo.indexOf(t)||Xi.indexOf(o)>-1||ua.some(function(c){return o.indexOf(c)>-1})}function jd(n,s){var t,c=bh(n.split("#"),2),C=c[1],D=dn.resolve(c[0]||"",s||"");return C?ra()(t="".concat(D,"#")).call(t,C):D}var Ch="application/json, application/yaml",E0=/^([a-z]+:\/\/|\/\/)/i,N_=nr("JSONRefError",function(s,t,o){this.originalError=o,Sh()(this,t||{})}),Jp={},ev=new(qe()),tS=[function(n){return"paths"===n[0]&&"responses"===n[3]&&"examples"===n[5]},function(n){return"paths"===n[0]&&"responses"===n[3]&&"content"===n[5]&&"example"===n[7]},function(n){return"paths"===n[0]&&"responses"===n[3]&&"content"===n[5]&&"examples"===n[7]&&"value"===n[9]},function(n){return"paths"===n[0]&&"requestBody"===n[3]&&"content"===n[4]&&"example"===n[6]},function(n){return"paths"===n[0]&&"requestBody"===n[3]&&"content"===n[4]&&"examples"===n[6]&&"value"===n[8]},function(n){return"paths"===n[0]&&"parameters"===n[2]&&"example"===n[4]},function(n){return"paths"===n[0]&&"parameters"===n[3]&&"example"===n[5]},function(n){return"paths"===n[0]&&"parameters"===n[2]&&"examples"===n[4]&&"value"===n[6]},function(n){return"paths"===n[0]&&"parameters"===n[3]&&"examples"===n[5]&&"value"===n[7]},function(n){return"paths"===n[0]&&"parameters"===n[2]&&"content"===n[4]&&"example"===n[6]},function(n){return"paths"===n[0]&&"parameters"===n[2]&&"content"===n[4]&&"examples"===n[6]&&"value"===n[8]},function(n){return"paths"===n[0]&&"parameters"===n[3]&&"content"===n[4]&&"example"===n[7]},function(n){return"paths"===n[0]&&"parameters"===n[3]&&"content"===n[5]&&"examples"===n[7]&&"value"===n[9]}],rS={key:"$ref",plugin:function(s,t,o,c){var g=c.getInstance(),C=n_()(o).call(o,0,-1);if(!Xa(C)&&!function(s){return tS.some(function(t){return t(s)})}(C)){var P=c.getContext(o).baseDoc;if("string"!=typeof s)return new N_("$ref: must be a string (JSON-Ref)",{$ref:s,baseDoc:P,fullPath:o});var oe,me,_e,j=kN(s),W=j[0],re=j[1]||"";try{oe=P||W?FN(W,P):null}catch(we){return D3(we,{pointer:re,$ref:s,basePath:oe,fullPath:o})}if(function(n,s,t,o){var c,g,C=ev.get(o);C||ev.set(o,C={});var D=function(n){return 0===n.length?"":"/".concat(Tu()(n).call(n,BN).join("/"))}(t),P=ra()(c="".concat(s||"<specmap-base>","#")).call(c,n),j=D.replace(/allOf\/\d+\/?/g,"");if(s===o.contextTree.get([]).baseDoc&&P3(j,n))return!0;var re="";if(t.some(function(me){var _e;return re=ra()(_e="".concat(re,"/")).call(_e,BN(me)),C[re]&&C[re].some(function(Fe){return P3(Fe,P)||P3(P,Fe)})}))return!0;C[j]=ra()(g=C[j]||[]).call(g,P)}(re,oe,C,c)&&!g.useCircularStructures){var Fe=jd(s,oe);return s===Fe?null:zu.replace(o,Fe)}if(null==oe?(_e=N3(re),void 0===(me=c.get(_e))&&(me=new N_("Could not resolve reference: ".concat(s),{pointer:re,$ref:s,baseDoc:P,fullPath:o}))):me=null!=(me=$N(oe,re)).__value?me.__value:me.catch(function(we){throw D3(we,{pointer:re,$ref:s,baseDoc:P,fullPath:o})}),me instanceof Error)return[zu.remove(o),me];var Re=jd(s,oe),Le=zu.replace(C,me,{$$ref:Re});if(oe&&oe!==P)return[Le,zu.context(C,{baseDoc:oe})];try{if(!function(n,s){var t=[n];return s.path.reduce(function(c,g){return t.push(c[g]),c[g]},n),function o(c){return zu.isObject(c)&&(t.indexOf(c)>=0||xu()(c).some(function(g){return o(c[g])}))}(s.value)}(c.state,Le)||g.useCircularStructures)return Le}catch(we){return null}}}},ob=Sh()(rS,{docCache:Jp,absoluteify:FN,clearCache:function(n){void 0!==n?delete Jp[n]:xu()(Jp).forEach(function(s){delete Jp[s]})},JSONRefError:N_,wrapError:D3,getDoc:HN,split:kN,extractFromDoc:$N,fetchJSON:function(n){return fetch(n,{headers:{Accept:Ch},loadSpec:!0}).then(function(s){return s.text()}).then(function(s){return $T.load(s)})},extract:R3,jsonPointerToArray:N3,unescapeJsonPointerToken:UN});const iS=ob;function FN(n,s){if(!E0.test(n)){var t;if(!s)throw new N_(ra()(t="Tried to resolve a relative URL, without having a basePath. path: '".concat(n,"' basePath: '")).call(t,s,"'"));return dn.resolve(s,n)}return n}function D3(n,s){var t,o;return t=n&&n.response&&n.response.body?ra()(o="".concat(n.response.body.code," ")).call(o,n.response.body.message):n.message,new N_("Could not resolve reference: ".concat(t),s,n)}function kN(n){return(n+"").split("#")}function $N(n,s){var t=Jp[n];if(t&&!zu.isPromise(t))try{var o=R3(s,t);return Sh()(lm().resolve(o),{__value:o})}catch(c){return lm().reject(c)}return HN(n).then(function(c){return R3(s,c)})}function HN(n){var s=Jp[n];return s?zu.isPromise(s)?s:lm().resolve(s):(Jp[n]=ob.fetchJSON(n).then(function(t){return Jp[n]=t,t}),Jp[n])}function R3(n,s){var t=N3(n);if(t.length<1)return s;var o=zu.getIn(s,t);if(void 0===o)throw new N_("Could not resolve pointer: ".concat(n," does not exist in document"),{pointer:n});return o}function N3(n){var s;if("string"!=typeof n)throw new TypeError("Expected a string, got a ".concat(vc(n)));return"/"===n[0]&&(n=n.substr(1)),""===n?[]:Tu()(s=n.split("/")).call(s,UN)}function UN(n){return"string"!=typeof n?n:new(ln())("=".concat(n.replace(/~1/g,"/").replace(/~0/g,"~"))).get("")}function BN(n){var s,t=new(ln())([["",n.replace(/~/g,"~0").replace(/\//g,"~1")]]);return n_()(s=t.toString()).call(s,1)}function P3(n,s){if(function(s){return!s||"/"===s||"#"===s}(s))return!0;var t=n.charAt(s.length),o=n_()(s).call(s,-1);return 0===n.indexOf(s)&&(!t||"/"===t||"#"===t)&&"#"!==o}const kP={key:"allOf",plugin:function(s,t,o,c,g){if(!g.meta||!g.meta.$$ref){var C=n_()(o).call(o,0,-1);if(!Xa(C)){if(!Array.isArray(s)){var D=new TypeError("allOf must be an array");return D.fullPath=o,D}var P=!1,j=g.value;if(C.forEach(function(me){!j||(j=j[me])}),j=Od({},j),0!==xu()(j).length){delete j.allOf;var re,oe,W=[];return W.push(c.replace(C,{})),s.forEach(function(me,_e){if(!c.isObject(me)){if(P)return null;P=!0;var Fe=new TypeError("Elements in allOf must be objects");return Fe.fullPath=o,W.push(Fe)}W.push(c.mergeDeep(C,me));var Le=function(n,s){var t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=t.specmap,c=t.getBaseUrlForNodePath,g=void 0===c?function(j){var W;return o.getContext(ra()(W=[]).call(W,fm(s),fm(j))).baseDoc}:c,C=t.targetKeys,D=void 0===C?["$ref","$$ref"]:C,P=[];return Ti()(n).forEach(function(){if(Yv()(D).call(D,this.key)&&"string"==typeof this.node){var W=this.path,re=ra()(s).call(s,this.path),oe=jd(this.node,g(W));P.push(o.replace(re,oe))}}),P}(me,n_()(o).call(o,0,-1),{getBaseUrlForNodePath:function(U){var pt;return c.getContext(ra()(pt=[]).call(pt,fm(o),[_e],fm(U))).baseDoc},specmap:c});W.push.apply(W,fm(Le))}),j.example&&W.push(c.remove(ra()(re=[]).call(re,C,"example"))),W.push(c.mergeDeep(C,j)),j.$$ref||W.push(c.remove(ra()(oe=[]).call(oe,C,"$$ref"))),W}}}}},$P={key:"parameters",plugin:function(s,t,o,c){if(Array.isArray(s)&&s.length){var g=Sh()([],s),C=n_()(o).call(o,0,-1),D=Od({},zu.getIn(c.spec,C));return s.forEach(function(P,j){try{g[j].default=c.parameterMacro(D,P)}catch(re){var W=new Error(re);return W.fullPath=o,W}}),zu.replace(o,g)}return zu.replace(o,s)}},HP={key:"properties",plugin:function(s,t,o,c){var g=Od({},s);for(var C in s)try{g[C].default=c.modelPropertyMacro(g[C])}catch(j){var D=new Error(j);return D.fullPath=o,D}return zu.replace(o,g)}};var UP=function(){function n(s){tb(this,n),this.root=I3(s||{})}return GT(n,[{key:"set",value:function(t,o){var c=this.getParent(t,!0);if(c){var g=t[t.length-1],C=c.children;C[g]?xA(C[g],o,c):C[g]=I3(o,c)}else xA(this.root,o,null)}},{key:"get",value:function(t){if((t=t||[]).length<1)return this.root.value;for(var c,g,o=this.root,C=0;C<t.length&&(c=o.children)[g=t[C]];C+=1)o=c[g];return o&&o.protoValue}},{key:"getParent",value:function(t,o){return!t||t.length<1?null:t.length<2?this.root:n_()(t).call(t,0,-1).reduce(function(c,g){if(!c)return c;var C=c.children;return!C[g]&&o&&(C[g]=I3(null,c)),C[g]},this.root)}}]),n}();function I3(n,s){return xA({children:{}},n,s)}function xA(n,s,t){return n.value=s||{},n.protoValue=t?Od(Od({},t.protoValue),n.value):n.value,xu()(n.children).forEach(function(o){var c=n.children[o];n.children[o]=xA(c,c.value,n)}),n}var ZN=function(){},BP=function(){function n(s){var o,c,t=this;tb(this,n),Sh()(this,{spec:"",debugLevel:"info",plugins:[],pluginHistory:{},errors:[],mutations:[],promisedPatches:[],state:{},patches:[],context:{},contextTree:new UP,showDebug:!1,allPatches:[],pluginProp:"specMap",libMethods:Sh()(Object.create(this),zu,{getInstance:function(){return t}}),allowMetaPatches:!1},s),this.get=this._get.bind(this),this.getContext=this._getContext.bind(this),this.hasRun=this._hasRun.bind(this),this.wrappedPlugins=Np()(o=Tu()(c=this.plugins).call(c,this.wrapPlugin.bind(this))).call(o,zu.isFunction),this.patches.push(zu.add([],this.spec)),this.patches.push(zu.context([],this.context)),this.updatePatches(this.patches)}return GT(n,[{key:"debug",value:function(t){if(this.debugLevel===t){for(var o,c=arguments.length,g=new Array(c>1?c-1:0),C=1;C<c;C++)g[C-1]=arguments[C];(o=console).log.apply(o,g)}}},{key:"verbose",value:function(t){if("verbose"===this.debugLevel){for(var o,c,g=arguments.length,C=new Array(g>1?g-1:0),D=1;D<g;D++)C[D-1]=arguments[D];(o=console).log.apply(o,ra()(c=["[".concat(t,"] ")]).call(c,C))}}},{key:"wrapPlugin",value:function(t,o){var C,P,j,c=this.pathDiscriminator,g=null;return t[this.pluginProp]?(g=t,C=t[this.pluginProp]):zu.isFunction(t)?C=t:zu.isObject(t)&&(P=t,j=function(re,oe){return!Array.isArray(re)||re.every(function(me,_e){return me===oe[_e]})},C=e_().mark(function W(re,oe){var me,_e,Fe,Re,Le,we;return e_().wrap(function(pt){for(;;)switch(pt.prev=pt.next){case 0:we=function(Dt,Ft,cn){var kt,wn,Tn,Hr,sr,Nr,xr,fn,Rn,kn,Wn,bn,jr;return e_().wrap(function(oi){for(;;)switch(oi.prev=oi.next){case 0:if(zu.isObject(Dt)){oi.next=6;break}if(P.key!==Ft[Ft.length-1]){oi.next=4;break}return oi.next=4,P.plugin(Dt,P.key,Ft,oe);case 4:oi.next=30;break;case 6:wn=Ft[kt=Ft.length-1],Tn=Ft.indexOf("properties"),Hr="properties"===wn&&kt===Tn,sr=oe.allowMetaPatches&&_e[Dt.$$ref],Nr=0,xr=xu()(Dt);case 12:if(!(Nr<xr.length)){oi.next=30;break}if(Rn=Dt[fn=xr[Nr]],kn=ra()(Ft).call(Ft,fn),Wn=zu.isObject(Rn),bn=Dt.$$ref,sr){oi.next=22;break}if(!Wn){oi.next=22;break}return oe.allowMetaPatches&&bn&&(_e[bn]=!0),oi.delegateYield(we(Rn,kn,cn),"t0",22);case 22:if(Hr||fn!==P.key){oi.next=27;break}if(jr=j(c,Ft),c&&!jr){oi.next=27;break}return oi.next=27,P.plugin(Rn,fn,kn,oe,cn);case 27:Nr++,oi.next=12;break;case 30:case"end":return oi.stop()}},me)},me=e_().mark(we),_e={},Fe=Ng(Np()(re).call(re,zu.isAdditiveMutation)),pt.prev=4,Fe.s();case 6:if((Re=Fe.n()).done){pt.next=11;break}return pt.delegateYield(we((Le=Re.value).value,Le.path,Le),"t0",9);case 9:pt.next=6;break;case 11:pt.next=16;break;case 13:pt.prev=13,pt.t1=pt.catch(4),Fe.e(pt.t1);case 16:return pt.prev=16,Fe.f(),pt.finish(16);case 19:case"end":return pt.stop()}},W,null,[[4,13,16,19]])})),Sh()(C.bind(g),{pluginName:t.name||o,isGenerator:zu.isGenerator(C)})}},{key:"nextPlugin",value:function(){var t,o=this;return lp()(t=this.wrappedPlugins).call(t,function(c){return o.getMutationsForPlugin(c).length>0})}},{key:"nextPromisedPatch",value:function(){var t;if(this.promisedPatches.length>0)return lm().race(Tu()(t=this.promisedPatches).call(t,function(o){return o.value}))}},{key:"getPluginHistory",value:function(t){var o=this.constructor.getPluginName(t);return this.pluginHistory[o]||[]}},{key:"getPluginRunCount",value:function(t){return this.getPluginHistory(t).length}},{key:"getPluginHistoryTip",value:function(t){var o=this.getPluginHistory(t);return o&&o[o.length-1]||{}}},{key:"getPluginMutationIndex",value:function(t){var o=this.getPluginHistoryTip(t).mutationIndex;return"number"!=typeof o?-1:o}},{key:"updatePluginHistory",value:function(t,o){var c=this.constructor.getPluginName(t);this.pluginHistory[c]=this.pluginHistory[c]||[],this.pluginHistory[c].push(o)}},{key:"updatePatches",value:function(t){var o=this;zu.normalizeArray(t).forEach(function(c){if(c instanceof Error)o.errors.push(c);else try{if(!zu.isObject(c))return void o.debug("updatePatches","Got a non-object patch",c);if(o.showDebug&&o.allPatches.push(c),zu.isPromise(c.value))return o.promisedPatches.push(c),void o.promisedPatchThen(c);if(zu.isContextPatch(c))return void o.setContext(c.path,c.value);if(zu.isMutation(c))return void o.updateMutations(c)}catch(g){console.error(g),o.errors.push(g)}})}},{key:"updateMutations",value:function(t){"object"===vc(t.value)&&!Array.isArray(t.value)&&this.allowMetaPatches&&(t.value=Od({},t.value));var o=zu.applyPatch(this.state,t,{allowMetaPatches:this.allowMetaPatches});o&&(this.mutations.push(t),this.state=o)}},{key:"removePromisedPatch",value:function(t){var o,c=this.promisedPatches.indexOf(t);c<0?this.debug("Tried to remove a promisedPatch that isn't there!"):h0()(o=this.promisedPatches).call(o,c,1)}},{key:"promisedPatchThen",value:function(t){var o=this;return t.value=t.value.then(function(c){var g=Od(Od({},t),{},{value:c});o.removePromisedPatch(t),o.updatePatches(g)}).catch(function(c){o.removePromisedPatch(t),o.updatePatches(c)}),t.value}},{key:"getMutations",value:function(t,o){var c;return t=t||0,"number"!=typeof o&&(o=this.mutations.length),n_()(c=this.mutations).call(c,t,o)}},{key:"getCurrentMutations",value:function(){return this.getMutationsForPlugin(this.getCurrentPlugin())}},{key:"getMutationsForPlugin",value:function(t){var o=this.getPluginMutationIndex(t);return this.getMutations(o+1)}},{key:"getCurrentPlugin",value:function(){return this.currentPlugin}},{key:"getLib",value:function(){return this.libMethods}},{key:"_get",value:function(t){return zu.getIn(this.state,t)}},{key:"_getContext",value:function(t){return this.contextTree.get(t)}},{key:"setContext",value:function(t,o){return this.contextTree.set(t,o)}},{key:"_hasRun",value:function(t){return this.getPluginRunCount(this.getCurrentPlugin())>(t||0)}},{key:"dispatch",value:function(){var D,t=this,o=this,c=this.nextPlugin();if(!c){var g=this.nextPromisedPatch();if(g)return g.then(function(){return t.dispatch()}).catch(function(){return t.dispatch()});var C={spec:this.state,errors:this.errors};return this.showDebug&&(C.patches=this.allPatches),lm().resolve(C)}if(o.pluginCount=o.pluginCount||{},o.pluginCount[c]=(o.pluginCount[c]||0)+1,o.pluginCount[c]>100)return lm().resolve({spec:o.state,errors:ra()(D=o.errors).call(D,new Error("We've reached a hard limit of ".concat(100," plugin runs")))});if(c!==this.currentPlugin&&this.promisedPatches.length){var P,j=Tu()(P=this.promisedPatches).call(P,function(oe){return oe.value});return lm().all(Tu()(j).call(j,function(oe){return oe.then(ZN,ZN)})).then(function(){return t.dispatch()})}return function(){o.currentPlugin=c;var oe=o.getCurrentMutations(),me=o.mutations.length-1;try{if(c.isGenerator){var Fe,_e=Ng(c(oe,o.getLib()));try{for(_e.s();!(Fe=_e.n()).done;)re(Fe.value)}catch(we){_e.e(we)}finally{_e.f()}}else re(c(oe,o.getLib()))}catch(we){console.error(we),re([Sh()(Object.create(we),{plugin:c})])}finally{o.updatePluginHistory(c,{mutationIndex:me})}return o.dispatch()}();function re(oe){oe&&(oe=zu.fullyNormalizeArray(oe),o.updatePatches(oe,c))}}}],[{key:"getPluginName",value:function(t){return t.pluginName}},{key:"getPatchesOfType",value:function(t,o){return Np()(t).call(t,o)}}]),n}(),sb={refs:iS,allOf:kP,parameters:$P,properties:HP},ZP=i(84220),jN=i.n(ZP),GN=function(s){return String.prototype.toLowerCase.call(s)},VN=function(s){return s.replace(/[^\w]/gi,"_")};function zN(n){var s=n.openapi;return!!s&&jN()(s).call(s,"3")}function L3(n,s){var t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},c=o.v2OperationIdCompatibilityMode;if(!n||"object"!==vc(n))return null;var g=(n.operationId||"").replace(/\s/g,"");return g.length?VN(n.operationId):jP(s,t,{v2OperationIdCompatibilityMode:c})}function jP(n,s){var t,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},c=o.v2OperationIdCompatibilityMode;if(c){var g,C,D=ra()(g="".concat(s.toLowerCase(),"_")).call(g,n).replace(/[\s!@#$%^&*()_+=[{\]};:<>|./?,\\'""-]/g,"_");return(D=D||ra()(C="".concat(n.substring(1),"_")).call(C,s)).replace(/((_){2,})/g,"_").replace(/^(_)*/g,"").replace(/([_])*$/g,"")}return ra()(t="".concat(GN(s))).call(t,VN(n))}function WN(n,s){var t;return ra()(t="".concat(GN(s),"-")).call(t,n)}function JN(n){var s=n.spec,t=s.paths,o={};if(!t||s.$$normalized)return n;for(var c in t){var g,C=t[c];if(null!=C&&Yv()(g=["object","function"]).call(g,vc(C))){var D=C.parameters,P=function(oe){var me,_e=C[oe];if(null==_e||!Yv()(me=["object","function"]).call(me,vc(_e)))return"continue";var Fe=L3(_e,c,oe);if(Fe){o[Fe]?o[Fe].push(_e):o[Fe]=[_e];var Re=o[Fe];if(Re.length>1)Re.forEach(function(Hr,sr){var Nr;Hr.__originalOperationId=Hr.__originalOperationId||Hr.operationId,Hr.operationId=ra()(Nr="".concat(Fe)).call(Nr,sr+1)});else if(void 0!==_e.operationId){var Le=Re[0];Le.__originalOperationId=Le.__originalOperationId||_e.operationId,Le.operationId=Fe}}if("parameters"!==oe){var we=[],U={};for(var pt in s)("produces"===pt||"consumes"===pt||"security"===pt)&&(U[pt]=s[pt],we.push(U));if(D&&(U.parameters=D,we.push(U)),we.length){var Dt,ht=Ng(we);try{for(ht.s();!(Dt=ht.n()).done;){var Ft=Dt.value;for(var cn in Ft)if(_e[cn]){if("parameters"===cn){var wn,kt=Ng(Ft[cn]);try{var Tn=function(){var sr=wn.value;_e[cn].some(function(xr){return xr.name&&xr.name===sr.name||xr.$ref&&xr.$ref===sr.$ref||xr.$$ref&&xr.$$ref===sr.$$ref||xr===sr})||_e[cn].push(sr)};for(kt.s();!(wn=kt.n()).done;)Tn()}catch(Hr){kt.e(Hr)}finally{kt.f()}}}else _e[cn]=Ft[cn]}}catch(Hr){ht.e(Hr)}finally{ht.f()}}}};for(var j in C)P(j)}}return s.$$normalized=!0,n}function QN(n){var s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},t=s.requestInterceptor,o=s.responseInterceptor,c=n.withCredentials?"include":"same-origin";return function(g){return n({url:g,loadSpec:!0,requestInterceptor:t,responseInterceptor:o,headers:{Accept:Ch},credentials:c}).then(function(C){return C.body})}}function XN(n){var t=n.spec,c=n.mode,g=n.allowMetaPatches,C=void 0===g||g,D=n.pathDiscriminator,P=n.modelPropertyMacro,j=n.parameterMacro,W=n.requestInterceptor,re=n.responseInterceptor,oe=n.skipNormalization,me=n.useCircularStructures,_e=n.http,Fe=n.baseDoc;return Fe=Fe||n.url,_e=n.fetch||_e||HT,t?Re(t):QN(_e,{requestInterceptor:W,responseInterceptor:re})(Fe).then(Re);function Re(Le){Fe&&(sb.refs.docCache[Fe]=Le),sb.refs.fetchJSON=QN(_e,{requestInterceptor:W,responseInterceptor:re});var we=[sb.refs];return"function"==typeof j&&we.push(sb.parameters),"function"==typeof P&&we.push(sb.properties),"strict"!==c&&we.push(sb.allOf),function(n){return new BP(n).dispatch()}({spec:Le,context:{baseDoc:Fe},plugins:we,allowMetaPatches:C,pathDiscriminator:D,parameterMacro:j,modelPropertyMacro:P,useCircularStructures:me}).then(oe?function(){var U=z1(e_().mark(function pt(ht){return e_().wrap(function(Ft){for(;;)switch(Ft.prev=Ft.next){case 0:return Ft.abrupt("return",ht);case 1:case"end":return Ft.stop()}},pt)}));return function(pt){return U.apply(this,arguments)}}():JN)}}var F3=i(72632);function KN(n,s){if(null==n)return{};var o,c,t=function(n,s){if(null==n)return{};var c,g,t={},o=YT(n);for(g=0;g<o.length;g++)c=o[g],!(F3(s).call(s,c)>=0)&&(t[c]=n[c]);return t}(n,s);if(c0){var g=c0(n);for(c=0;c<g.length;c++)o=g[c],!(F3(s).call(s,o)>=0)&&(!Object.prototype.propertyIsEnumerable.call(n,o)||(t[o]=n[o]))}return t}var JP=i(58102),ab=i.n(JP),QP=i(7281);function qN(n){return"[object Object]"===Object.prototype.toString.call(n)}function e6(n){var s,t;return!1!==qN(n)&&(void 0===(s=n.constructor)||!(!1===qN(t=s.prototype)||!1===t.hasOwnProperty("isPrototypeOf")))}const XP={body:function(n){n.req.body=n.value},header:function(n){var s=n.req,t=n.parameter,o=n.value;s.headers=s.headers||{},void 0!==o&&(s.headers[t.name]=o)},query:function(n){var s=n.req,t=n.value,o=n.parameter;if(s.query=s.query||{},!1===t&&"boolean"===o.type&&(t="false"),0===t&&["number","integer"].indexOf(o.type)>-1&&(t="0"),t)s.query[o.name]={collectionFormat:o.collectionFormat,value:t};else if(o.allowEmptyValue&&void 0!==t){var c=o.name;s.query[c]=s.query[c]||{},s.query[c].allowEmptyValue=!0}},path:function(n){var s=n.req,t=n.value;s.url=s.url.split("{".concat(n.parameter.name,"}")).join(encodeURIComponent(t))},formData:function(n){var s=n.req,t=n.value,o=n.parameter;(t||o.allowEmptyValue)&&(s.form=s.form||{},s.form[o.name]={value:t,allowEmptyValue:o.allowEmptyValue,collectionFormat:o.collectionFormat})}};function DA(n,s){return Yv()(s).call(s,"application/json")?"string"==typeof n?n:Wp()(n):n.toString()}function r8(n){var s=n.req,t=n.value,o=n.parameter,c=o.name,g=o.style,C=o.explode,D=o.content;if(D){var P=xu()(D)[0];s.url=s.url.split("{".concat(c,"}")).join(zv(DA(t,P),{escape:!0}))}else{var j=cA({key:o.name,value:t,style:g||"simple",explode:C||!1,escape:!0});s.url=s.url.split("{".concat(c,"}")).join(j)}}function i8(n){var s=n.req,t=n.value,o=n.parameter;if(s.query=s.query||{},o.content){var c=xu()(o.content)[0];s.query[o.name]=DA(t,c)}else if(!1===t&&(t="false"),0===t&&(t="0"),t)s.query[o.name]={value:t,serializationOption:{style:o.style,explode:o.explode,allowReserved:o.allowReserved}};else if(o.allowEmptyValue&&void 0!==t){var P=o.name;s.query[P]=s.query[P]||{},s.query[P].allowEmptyValue=!0}}var o8=["accept","authorization","content-type"];function s8(n){var s=n.req,t=n.parameter,o=n.value;if(s.headers=s.headers||{},!(o8.indexOf(t.name.toLowerCase())>-1)){if(t.content){var c=xu()(t.content)[0];return void(s.headers[t.name]=DA(o,c))}void 0!==o&&(s.headers[t.name]=cA({key:t.name,value:o,style:t.style||"simple",explode:void 0!==t.explode&&t.explode,escape:!1}))}}function a8(n){var s=n.req,t=n.parameter,o=n.value;s.headers=s.headers||{};var c=vc(o);if(t.content){var g,C=xu()(t.content)[0];s.headers.Cookie=ra()(g="".concat(t.name,"=")).call(g,DA(o,C))}else if("undefined"!==c){var D="object"===c&&!Array.isArray(o)&&t.explode?"":"".concat(t.name,"=");s.headers.Cookie=D+cA({key:t.name,value:o,escape:!1,style:t.style||"form",explode:void 0!==t.explode&&t.explode})}}var l8=i(24677),t6=i.n(l8);const n6=(void 0!==t6()?t6():"undefined"!=typeof self?self:window).btoa;var _8=["http","fetch","spec","operationId","pathName","method","parameters","securities"],r6=function(s){return Array.isArray(s)?s:[]},g8=nr("OperationNotFoundError",function(s,t,o){this.originalError=o,Sh()(this,t||{})}),y8={buildRequest:i6};function b8(n){var s=n.http,t=n.fetch,o=n.spec,c=n.operationId,g=n.pathName,C=n.method,D=n.parameters,P=n.securities,j=KN(n,_8),W=s||t||HT;g&&C&&!c&&(c=WN(g,C));var re=y8.buildRequest(Od({spec:o,operationId:c,parameters:D,securities:P,http:W},j));return re.body&&(e6(re.body)||Array.isArray(re.body))&&(re.body=Wp()(re.body)),W(re)}function i6(n){var s,t,o=n.spec,c=n.operationId,g=n.responseContentType,C=n.scheme,D=n.requestInterceptor,P=n.responseInterceptor,j=n.contextUrl,W=n.userFetch,re=n.server,oe=n.serverVariables,me=n.http,_e=n.signal,Fe=n.parameters,Re=n.parameterBuilders,Le=zN(o);Re||(Re=Le?p:XP);var U={url:"",credentials:me&&me.withCredentials?"include":"same-origin",headers:{},cookies:{}};_e&&(U.signal=_e),D&&(U.requestInterceptor=D),P&&(U.responseInterceptor=P),W&&(U.userFetch=W);var pt=function(n,s){return n&&n.paths?function(n,s){return function(n,s,t){if(!n||"object"!==vc(n)||!n.paths||"object"!==vc(n.paths))return null;var o=n.paths;for(var c in o)for(var g in o[c])if("PARAMETERS"!==g.toUpperCase()){var C=o[c][g];if(C&&"object"===vc(C)){var D={spec:n,pathName:c,method:g.toUpperCase(),operation:C};if(s(D))return D}}}(n,s)||null}(n,function(t){var o=t.pathName,c=t.method,g=t.operation;if(!g||"object"!==vc(g))return!1;var C=g.operationId;return[L3(g,o,c),WN(o,c),C].some(function(j){return j&&j===s})}):null}(o,c);if(!pt)throw new g8("Operation ".concat(c," not found"));var ht=pt.operation,Dt=void 0===ht?{}:ht,Ft=pt.method,cn=pt.pathName;if(U.url+=function(n){return zN(n.spec)?function(n){var s=n.spec,t=n.pathName,o=n.method,c=n.server,g=n.contextUrl,C=n.serverVariables,D=void 0===C?{}:C,P=ab()(s,["paths",t,(o||"").toLowerCase(),"servers"])||ab()(s,["paths",t,"servers"])||ab()(s,["servers"]),j="",W=null;if(c&&P&&P.length){var re=Tu()(P).call(P,function(_e){return _e.url});re.indexOf(c)>-1&&(j=c,W=P[re.indexOf(c)])}if(!j&&P&&P.length){j=P[0].url;var oe=bh(P,1);W=oe[0]}return j.indexOf("{")>-1&&function(n){for(var o,s=[],t=/{([^}]+)}/g;o=t.exec(n);)s.push(o[1]);return s}(j).forEach(function(_e){if(W.variables&&W.variables[_e]){var Re=D[_e]||W.variables[_e].default,Le=new RegExp("{".concat(_e,"}"),"g");j=j.replace(Le,Re)}}),function(){var D,P,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",t=dn.parse(n&&s?dn.resolve(s,n):n),o=dn.parse(s),c=k3(t.protocol)||k3(o.protocol)||"",g=t.host||o.host,C=t.pathname||"";return"/"===(D=c&&g?ra()(P="".concat(c,"://")).call(P,g+C):C)[D.length-1]?n_()(D).call(D,0,-1):D}(j,g)}(n):function(n){var W,re,s=n.spec,t=n.scheme,o=n.contextUrl,g=dn.parse(void 0===o?"":o),C=Array.isArray(s.schemes)?s.schemes[0]:null,D=t||C||k3(g.protocol)||"http",P=s.host||g.host||"",j=s.basePath||"";return"/"===(W=D&&P?ra()(re="".concat(D,"://")).call(re,P+j):j)[W.length-1]?n_()(W).call(W,0,-1):W}(n)}({spec:o,scheme:C,contextUrl:j,server:re,serverVariables:oe,pathName:cn,method:Ft}),!c)return delete U.cookies,U;U.url+=cn,U.method="".concat(Ft).toUpperCase(),Fe=Fe||{};var kt=o.paths[cn]||{};g&&(U.headers.accept=g);var wn=function(s){var t={};s.forEach(function(c){t[c.in]||(t[c.in]={}),t[c.in][c.name]=c});var o=[];return xu()(t).forEach(function(c){xu()(t[c]).forEach(function(g){o.push(t[c][g])})}),o}(ra()(s=ra()(t=[]).call(t,r6(Dt.parameters))).call(s,r6(kt.parameters)));wn.forEach(function(sr){var xr,fn,Nr=Re[sr.in];if("body"===sr.in&&sr.schema&&sr.schema.properties&&(xr=Fe),void 0===(xr=sr&&sr.name&&Fe[sr.name]))xr=sr&&sr.name&&Fe[ra()(fn="".concat(sr.in,".")).call(fn,sr.name)];else if(function(s,t){return Np()(t).call(t,function(o){return o.name===s})}(sr.name,wn).length>1){var Rn;console.warn(ra()(Rn="Parameter '".concat(sr.name,"' is ambiguous because the defined spec has more than one parameter with the name: '")).call(Rn,sr.name,"' and the passed-in parameter values did not define an 'in' value."))}if(null!==xr){if(void 0!==sr.default&&void 0===xr&&(xr=sr.default),void 0===xr&&sr.required&&!sr.allowEmptyValue)throw new Error("Required parameter ".concat(sr.name," is not provided"));if(Le&&sr.schema&&"object"===sr.schema.type&&"string"==typeof xr)try{xr=JSON.parse(xr)}catch(kn){throw new Error("Could not parse object parameter value string as JSON")}Nr&&Nr({req:U,parameter:sr,value:xr,operation:Dt,spec:o})}});var Tn=Od(Od({},n),{},{operation:Dt});if((U=Le?function(n,s){var t=n.operation,o=n.requestBody,C=n.attachContentTypeForEmptyPayload,D=n.requestContentType;s=function(n){var s=n.request,t=n.securities,o=void 0===t?{}:t,c=n.operation,g=void 0===c?{}:c,C=n.spec,D=Od({},s),P=o.authorized,j=void 0===P?{}:P,W=g.security||C.security||[],re=j&&!!xu()(j).length,oe=ab()(C,["components","securitySchemes"])||{};return D.headers=D.headers||{},D.query=D.query||{},xu()(o).length&&re&&W&&(!Array.isArray(g.security)||g.security.length)?(W.forEach(function(me){xu()(me).forEach(function(_e){var Fe=j[_e],Re=oe[_e];if(Fe){var Le=Fe.value||Fe,we=Re.type;if(Fe)if("apiKey"===we)"query"===Re.in&&(D.query[Re.name]=Le),"header"===Re.in&&(D.headers[Re.name]=Le),"cookie"===Re.in&&(D.cookies[Re.name]=Le);else if("http"===we){if(/^basic$/i.test(Re.scheme)){var U,pt=Le.username||"",ht=Le.password||"",Dt=n6(ra()(U="".concat(pt,":")).call(U,ht));D.headers.Authorization="Basic ".concat(Dt)}/^bearer$/i.test(Re.scheme)&&(D.headers.Authorization="Bearer ".concat(Le))}else if("oauth2"===we||"openIdConnect"===we){var Ft,cn=Fe.token||{},wn=cn[Re["x-tokenName"]||"access_token"],Tn=cn.token_type;(!Tn||"bearer"===Tn.toLowerCase())&&(Tn="Bearer"),D.headers.Authorization=ra()(Ft="".concat(Tn," ")).call(Ft,wn)}}})}),D):s}({request:s,securities:n.securities,operation:t,spec:n.spec});var P=t.requestBody||{},j=xu()(P.content||{}),W=D&&j.indexOf(D)>-1;if(o||C){if(D&&W)s.headers["Content-Type"]=D;else if(!D){var re=j[0];re&&(s.headers["Content-Type"]=re,D=re)}}else D&&W&&(s.headers["Content-Type"]=D);if(!n.responseContentType&&t.responses){var oe,me=Np()(oe=qE()(t.responses)).call(oe,function(Fe){var Re=bh(Fe,2),we=Re[1],U=parseInt(Re[0],10);return U>=200&&U<300&&e6(we.content)}).reduce(function(Fe,Re){var we=bh(Re,2)[1];return ra()(Fe).call(Fe,xu()(we.content))},[]);me.length>0&&(s.headers.accept=me.join(", "))}if(o)if(D){if(j.indexOf(D)>-1)if("application/x-www-form-urlencoded"===D||"multipart/form-data"===D)if("object"===vc(o)){var _e=(P.content[D]||{}).encoding||{};s.form={},xu()(o).forEach(function(Fe){s.form[Fe]={value:o[Fe],encoding:_e[Fe]||{}}})}else s.form=o;else s.body=o}else s.body=o;return s}(Tn,U):function(n,s){var P,j,t=n.spec,o=n.operation,g=n.requestContentType,C=n.responseContentType,D=n.attachContentTypeForEmptyPayload;if((s=function(n){var s=n.request,t=n.securities,o=void 0===t?{}:t,c=n.operation,g=void 0===c?{}:c,C=n.spec,D=Od({},s),P=o.authorized,j=void 0===P?{}:P,W=o.specSecurity,oe=g.security||(void 0===W?[]:W),me=j&&!!xu()(j).length,_e=C.securityDefinitions;return D.headers=D.headers||{},D.query=D.query||{},xu()(o).length&&me&&oe&&(!Array.isArray(g.security)||g.security.length)?(oe.forEach(function(Fe){xu()(Fe).forEach(function(Re){var Le=j[Re];if(Le){var we=Le.token,U=Le.value||Le,pt=_e[Re],ht=pt.type,Ft=we&&we[pt["x-tokenName"]||"access_token"],cn=we&&we.token_type;if(Le)if("apiKey"===ht){var kt="query"===pt.in?"query":"headers";D[kt]=D[kt]||{},D[kt][pt.name]=U}else if("basic"===ht)if(U.header)D.headers.authorization=U.header;else{var wn,Tn=U.username||"",Hr=U.password||"";U.base64=n6(ra()(wn="".concat(Tn,":")).call(wn,Hr)),D.headers.authorization="Basic ".concat(U.base64)}else if("oauth2"===ht&&Ft){var sr;cn=cn&&"bearer"!==cn.toLowerCase()?cn:"Bearer",D.headers.authorization=ra()(sr="".concat(cn," ")).call(sr,Ft)}}})}),D):s}({request:s,securities:n.securities,operation:o,spec:t})).body||s.form||D)if(g)s.headers["Content-Type"]=g;else if(Array.isArray(o.consumes)){var W=bh(o.consumes,1);s.headers["Content-Type"]=W[0]}else if(Array.isArray(t.consumes)){var re=bh(t.consumes,1);s.headers["Content-Type"]=re[0]}else o.parameters&&Np()(P=o.parameters).call(P,function(Re){return"file"===Re.type}).length?s.headers["Content-Type"]="multipart/form-data":o.parameters&&Np()(j=o.parameters).call(j,function(Re){return"formData"===Re.in}).length&&(s.headers["Content-Type"]="application/x-www-form-urlencoded");else if(g){var oe,me,_e=o.parameters&&Np()(oe=o.parameters).call(oe,function(Re){return"body"===Re.in}).length>0,Fe=o.parameters&&Np()(me=o.parameters).call(me,function(Re){return"formData"===Re.in}).length>0;(_e||Fe)&&(s.headers["Content-Type"]=g)}return!C&&Array.isArray(o.produces)&&o.produces.length>0&&(s.headers.accept=o.produces.join(", ")),s}(Tn,U)).cookies&&xu()(U.cookies).length){var Hr=xu()(U.cookies).reduce(function(sr,Nr){return sr+(sr?"&":"")+QP.serialize(Nr,U.cookies[Nr])},"");U.headers.Cookie=Hr}return U.cookies&&delete U.cookies,_A(U),U}var k3=function(s){return s?s.replace(/\W/g,""):null};function A8(n,s){return $3.apply(this,arguments)}function $3(){return($3=z1(e_().mark(function n(s,t){var o,c,re,oe,me,_e,Fe=arguments;return e_().wrap(function(Le){for(;;)switch(Le.prev=Le.next){case 0:return c=(o=Fe.length>2&&void 0!==Fe[2]?Fe[2]:{}).returnEntireTree,re={pathDiscriminator:t,baseDoc:o.baseDoc,requestInterceptor:o.requestInterceptor,responseInterceptor:o.responseInterceptor,parameterMacro:o.parameterMacro,modelPropertyMacro:o.modelPropertyMacro,useCircularStructures:o.useCircularStructures},oe=JN({spec:s}),me=oe.spec,Le.next=6,XN(Od(Od({},re),{},{spec:me,allowMetaPatches:!0,skipNormalization:!0}));case 6:return _e=Le.sent,!c&&Array.isArray(t)&&t.length&&(_e.spec=ab()(_e.spec,t)||null),Le.abrupt("return",_e);case 9:case"end":return Le.stop()}},n)}))).apply(this,arguments)}var o6=i(88768),s6=zo.createContext(null),a6=function(n){n()};var l6={notify:function(){},get:function(){return[]}};function u6(n,s){var t,o=l6;function C(){W.onStateChange&&W.onStateChange()}function P(){t||(t=s?s.addNestedSub(C):n.subscribe(C),o=function(){var n=a6,s=null,t=null;return{clear:function(){s=null,t=null},notify:function(){n(function(){for(var c=s;c;)c.callback(),c=c.next})},get:function(){for(var c=[],g=s;g;)c.push(g),g=g.next;return c},subscribe:function(c){var g=!0,C=t={callback:c,next:null,prev:t};return C.prev?C.prev.next=C:s=C,function(){!g||null===s||(g=!1,C.next?C.next.prev=C.prev:t=C.prev,C.prev?C.prev.next=C.next:s=C.next)}}}}())}var W={addNestedSub:function(re){return P(),o.subscribe(re)},notifyNestedSubs:function(){o.notify()},handleChangeWrapper:C,isSubscribed:function(){return Boolean(t)},trySubscribe:P,tryUnsubscribe:function(){t&&(t(),t=void 0,o.clear(),o=l6)},getListeners:function(){return o}};return W}var c6="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?zo.useLayoutEffect:zo.useEffect;const N8=function(n){var s=n.store,t=n.context,o=n.children,c=(0,zo.useMemo)(function(){var D=u6(s);return{store:s,subscription:D}},[s]),g=(0,zo.useMemo)(function(){return s.getState()},[s]);return c6(function(){var D=c.subscription;return D.onStateChange=D.notifyNestedSubs,D.trySubscribe(),g!==s.getState()&&D.notifyNestedSubs(),function(){D.tryUnsubscribe(),D.onStateChange=null}},[c,g]),zo.createElement((t||s6).Provider,{value:c},o)};function tv(){return(tv=Object.assign?Object.assign.bind():function(n){for(var s=1;s<arguments.length;s++){var t=arguments[s];for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(n[o]=t[o])}return n}).apply(this,arguments)}function oS(n,s){if(null==n)return{};var c,g,t={},o=Object.keys(n);for(g=0;g<o.length;g++)!(s.indexOf(c=o[g])>=0)&&(t[c]=n[c]);return t}var P8=i(62568),d6=i.n(P8),I8=i(56261),L8=["getDisplayName","methodName","renderCountProp","shouldHandleStateChanges","storeKey","withRef","forwardRef","context"],F8=["reactReduxForwardedRef"],k8=[],$8=[null,null];function H8(n,s){return[s.payload,n[1]+1]}function f6(n,s,t){c6(function(){return n.apply(void 0,s)},t)}function U8(n,s,t,o,c,g,C){n.current=o,s.current=c,t.current=!1,g.current&&(g.current=null,C())}function B8(n,s,t,o,c,g,C,D,P,j){if(n){var W=!1,re=null,oe=function(){if(!W){var Re,Le,Fe=s.getState();try{Re=o(Fe,c.current)}catch(we){Le=we,re=we}Le||(re=null),Re===g.current?C.current||P():(g.current=Re,D.current=Re,C.current=!0,j({type:"STORE_UPDATED",payload:{error:Le}}))}};return t.onStateChange=oe,t.trySubscribe(),oe(),function(){if(W=!0,t.tryUnsubscribe(),t.onStateChange=null,re)throw re}}}var Y8=function(){return[null,0]};function Z8(n,s){void 0===s&&(s={});var o=s.getDisplayName,c=void 0===o?function(Dt){return"ConnectAdvanced("+Dt+")"}:o,g=s.methodName,C=void 0===g?"connectAdvanced":g,D=s.renderCountProp,P=void 0===D?void 0:D,j=s.shouldHandleStateChanges,W=void 0===j||j,re=s.storeKey,oe=void 0===re?"store":re,Fe=s.forwardRef,Re=void 0!==Fe&&Fe,Le=s.context,we=void 0===Le?s6:Le,U=oS(s,L8),ht=we;return function(Ft){var cn=Ft.displayName||Ft.name||"Component",kt=c(cn),wn=tv({},U,{getDisplayName:c,methodName:C,renderCountProp:P,shouldHandleStateChanges:W,storeKey:oe,displayName:kt,wrappedComponentName:cn,WrappedComponent:Ft}),Tn=U.pure,sr=Tn?zo.useMemo:function(Rn){return Rn()};function Nr(Rn){var kn=(0,zo.useMemo)(function(){var Vr=Rn.reactReduxForwardedRef,Ri=oS(Rn,F8);return[Rn.context,Vr,Ri]},[Rn]),Wn=kn[0],bn=kn[1],jr=kn[2],ji=(0,zo.useMemo)(function(){return Wn&&Wn.Consumer&&(0,I8.isContextConsumer)(zo.createElement(Wn.Consumer,null))?Wn:ht},[Wn,ht]),oi=(0,zo.useContext)(ji),Ui=Boolean(Rn.store)&&Boolean(Rn.store.getState)&&Boolean(Rn.store.dispatch),Sn=(Boolean(oi)&&Boolean(oi.store),Ui?Rn.store:oi.store),hn=(0,zo.useMemo)(function(){return function(Rn){return n(Rn.dispatch,wn)}(Sn)},[Sn]),_r=(0,zo.useMemo)(function(){if(!W)return $8;var Vr=u6(Sn,Ui?null:oi.subscription),Ri=Vr.notifyNestedSubs.bind(Vr);return[Vr,Ri]},[Sn,Ui,oi]),Fi=_r[0],_s=_r[1],Ho=(0,zo.useMemo)(function(){return Ui?oi:tv({},oi,{subscription:Fi})},[Ui,oi,Fi]),yo=(0,zo.useReducer)(H8,k8,Y8),zs=yo[0][0],Di=yo[1];if(zs&&zs.error)throw zs.error;var oo=(0,zo.useRef)(),ho=(0,zo.useRef)(jr),Ze=(0,zo.useRef)(),Mt=(0,zo.useRef)(!1),St=sr(function(){return Ze.current&&jr===ho.current?Ze.current:hn(Sn.getState(),jr)},[Sn,zs,jr]);f6(U8,[ho,oo,Mt,jr,St,Ze,_s]),f6(B8,[W,Sn,Fi,hn,ho,oo,Mt,Ze,_s,Di],[Sn,Fi,hn]);var Un=(0,zo.useMemo)(function(){return zo.createElement(Ft,tv({},St,{ref:bn}))},[bn,Ft,St]);return(0,zo.useMemo)(function(){return W?zo.createElement(ji.Provider,{value:Ho},Un):Un},[ji,Un,Ho])}var xr=Tn?zo.memo(Nr):Nr;if(xr.WrappedComponent=Ft,xr.displayName=Nr.displayName=kt,Re){var fn=zo.forwardRef(function(kn,Wn){return zo.createElement(xr,tv({},kn,{reactReduxForwardedRef:Wn}))});return fn.displayName=kt,fn.WrappedComponent=Ft,d6()(fn,Ft)}return d6()(xr,Ft)}}function p6(n,s){return n===s?0!==n||0!==s||1/n==1/s:n!=n&&s!=s}function H3(n,s){if(p6(n,s))return!0;if("object"!=typeof n||null===n||"object"!=typeof s||null===s)return!1;var t=Object.keys(n),o=Object.keys(s);if(t.length!==o.length)return!1;for(var c=0;c<t.length;c++)if(!Object.prototype.hasOwnProperty.call(s,t[c])||!p6(n[t[c]],s[t[c]]))return!1;return!0}function U3(n){return function(t,o){var c=n(t,o);function g(){return c}return g.dependsOnOwnProps=!1,g}}function h6(n){return null!=n.dependsOnOwnProps?Boolean(n.dependsOnOwnProps):1!==n.length}function _6(n,s){return function(o,c){var C=function(P,j){return C.dependsOnOwnProps?C.mapToProps(P,j):C.mapToProps(P)};return C.dependsOnOwnProps=!0,C.mapToProps=function(P,j){C.mapToProps=n,C.dependsOnOwnProps=h6(n);var W=C(P,j);return"function"==typeof W&&(C.mapToProps=W,C.dependsOnOwnProps=h6(W),W=C(P,j)),W},C}}const W8=[function(n){return"function"==typeof n?_6(n):void 0},function(n){return n?void 0:U3(function(s){return{dispatch:s}})},function(n){return n&&"object"==typeof n?U3(function(s){return function(n,s){var t={},o=function(C){var D=n[C];"function"==typeof D&&(t[C]=function(){return s(D.apply(void 0,arguments))})};for(var c in n)o(c);return t}(n,s)}):void 0}],X8=[function(n){return"function"==typeof n?_6(n):void 0},function(n){return n?void 0:U3(function(){return{}})}];function K8(n,s,t){return tv({},t,n,s)}const nI=[function(n){return"function"==typeof n?function(n){return function(t,o){var P,g=o.pure,C=o.areMergedPropsEqual,D=!1;return function(W,re,oe){var me=n(W,re,oe);return D?(!g||!C(me,P))&&(P=me):(D=!0,P=me),P}}}(n):void 0},function(n){return n?void 0:function(){return K8}}];var rI=["initMapStateToProps","initMapDispatchToProps","initMergeProps"];function iI(n,s,t,o){return function(g,C){return t(n(g,C),s(o,C),C)}}function oI(n,s,t,o,c){var j,W,re,oe,me,g=c.areStatesEqual,C=c.areOwnPropsEqual,D=c.areStatePropsEqual,P=!1;return function(pt,ht){return P?function(U,pt){var ht=!C(pt,W),Dt=!g(U,j);return j=U,W=pt,ht&&Dt?(re=n(j,W),s.dependsOnOwnProps&&(oe=s(o,W)),me=t(re,oe,W)):ht?(n.dependsOnOwnProps&&(re=n(j,W)),s.dependsOnOwnProps&&(oe=s(o,W)),me=t(re,oe,W)):Dt?function(){var U=n(j,W),pt=!D(U,re);return re=U,pt&&(me=t(re,oe,W)),me}():me}(pt,ht):function(U,pt){return re=n(j=U,W=pt),oe=s(o,W),me=t(re,oe,W),P=!0,me}(pt,ht)}}function sI(n,s){var t=s.initMapStateToProps,o=s.initMapDispatchToProps,c=s.initMergeProps,g=oS(s,rI),C=t(n,g),D=o(n,g),P=c(n,g);return(g.pure?oI:iI)(C,D,P,n,g)}var aI=["pure","areStatesEqual","areOwnPropsEqual","areStatePropsEqual","areMergedPropsEqual"];function B3(n,s,t){for(var o=s.length-1;o>=0;o--){var c=s[o](n);if(c)return c}return function(g,C){throw new Error("Invalid value of type "+typeof n+" for "+t+" argument when connecting component "+C.wrappedComponentName+".")}}function lI(n,s){return n===s}function uI(n){var s=void 0===n?{}:n,t=s.connectHOC,o=void 0===t?Z8:t,c=s.mapStateToPropsFactories,g=void 0===c?X8:c,C=s.mapDispatchToPropsFactories,D=void 0===C?W8:C,P=s.mergePropsFactories,j=void 0===P?nI:P,W=s.selectorFactory,re=void 0===W?sI:W;return function(me,_e,Fe,Re){void 0===Re&&(Re={});var we=Re.pure,U=void 0===we||we,pt=Re.areStatesEqual,ht=void 0===pt?lI:pt,Dt=Re.areOwnPropsEqual,Ft=void 0===Dt?H3:Dt,cn=Re.areStatePropsEqual,kt=void 0===cn?H3:cn,wn=Re.areMergedPropsEqual,Tn=void 0===wn?H3:wn,Hr=oS(Re,aI),sr=B3(me,g,"mapStateToProps"),Nr=B3(_e,D,"mapDispatchToProps"),xr=B3(Fe,j,"mergeProps");return o(re,tv({methodName:"connect",getDisplayName:function(Rn){return"Connect("+Rn+")"},shouldHandleStateChanges:Boolean(me),initMapStateToProps:sr,initMapDispatchToProps:Nr,initMergeProps:xr,pure:U,areStatesEqual:ht,areOwnPropsEqual:Ft,areStatePropsEqual:kt,areMergedPropsEqual:Tn},Hr))}}const cI=uI();a6=o6.unstable_batchedUpdates;var pI=i(12482),hI=i.n(pI),_I=i(80290),gI=i.n(_I);function Y3(n,s){(null==s||s>n.length)&&(s=n.length);for(var t=0,o=new Array(s);t<s;t++)o[t]=n[t];return o}function TI(n){return function(n){if(Array.isArray(n))return Y3(n)}(n)||function(n){if("undefined"!=typeof Symbol&&null!=n[Symbol.iterator]||null!=n["@@iterator"])return Array.from(n)}(n)||function(n,s){if(n){if("string"==typeof n)return Y3(n,s);var t=Object.prototype.toString.call(n).slice(8,-1);if("Object"===t&&n.constructor&&(t=n.constructor.name),"Map"===t||"Set"===t)return Array.from(n);if("Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t))return Y3(n,s)}}(n)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Z3(n,s,t){return s in n?Object.defineProperty(n,s,{value:t,enumerable:!0,configurable:!0,writable:!0}):n[s]=t,n}function g6(n,s){var t=Object.keys(n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(n);s&&(o=o.filter(function(c){return Object.getOwnPropertyDescriptor(n,c).enumerable})),t.push.apply(t,o)}return t}function lb(n){for(var s=1;s<arguments.length;s++){var t=null!=arguments[s]?arguments[s]:{};s%2?g6(Object(t),!0).forEach(function(o){Z3(n,o,t[o])}):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(t)):g6(Object(t)).forEach(function(o){Object.defineProperty(n,o,Object.getOwnPropertyDescriptor(t,o))})}return n}var j3={};function CI(n){if(0===n.length||1===n.length)return n;var s=n.join(".");return j3[s]||(j3[s]=function(n){var s=n.length;return 0===s||1===s?n:2===s?[n[0],n[1],"".concat(n[0],".").concat(n[1]),"".concat(n[1],".").concat(n[0])]:3===s?[n[0],n[1],n[2],"".concat(n[0],".").concat(n[1]),"".concat(n[0],".").concat(n[2]),"".concat(n[1],".").concat(n[0]),"".concat(n[1],".").concat(n[2]),"".concat(n[2],".").concat(n[0]),"".concat(n[2],".").concat(n[1]),"".concat(n[0],".").concat(n[1],".").concat(n[2]),"".concat(n[0],".").concat(n[2],".").concat(n[1]),"".concat(n[1],".").concat(n[0],".").concat(n[2]),"".concat(n[1],".").concat(n[2],".").concat(n[0]),"".concat(n[2],".").concat(n[0],".").concat(n[1]),"".concat(n[2],".").concat(n[1],".").concat(n[0])]:s>=4?[n[0],n[1],n[2],n[3],"".concat(n[0],".").concat(n[1]),"".concat(n[0],".").concat(n[2]),"".concat(n[0],".").concat(n[3]),"".concat(n[1],".").concat(n[0]),"".concat(n[1],".").concat(n[2]),"".concat(n[1],".").concat(n[3]),"".concat(n[2],".").concat(n[0]),"".concat(n[2],".").concat(n[1]),"".concat(n[2],".").concat(n[3]),"".concat(n[3],".").concat(n[0]),"".concat(n[3],".").concat(n[1]),"".concat(n[3],".").concat(n[2]),"".concat(n[0],".").concat(n[1],".").concat(n[2]),"".concat(n[0],".").concat(n[1],".").concat(n[3]),"".concat(n[0],".").concat(n[2],".").concat(n[1]),"".concat(n[0],".").concat(n[2],".").concat(n[3]),"".concat(n[0],".").concat(n[3],".").concat(n[1]),"".concat(n[0],".").concat(n[3],".").concat(n[2]),"".concat(n[1],".").concat(n[0],".").concat(n[2]),"".concat(n[1],".").concat(n[0],".").concat(n[3]),"".concat(n[1],".").concat(n[2],".").concat(n[0]),"".concat(n[1],".").concat(n[2],".").concat(n[3]),"".concat(n[1],".").concat(n[3],".").concat(n[0]),"".concat(n[1],".").concat(n[3],".").concat(n[2]),"".concat(n[2],".").concat(n[0],".").concat(n[1]),"".concat(n[2],".").concat(n[0],".").concat(n[3]),"".concat(n[2],".").concat(n[1],".").concat(n[0]),"".concat(n[2],".").concat(n[1],".").concat(n[3]),"".concat(n[2],".").concat(n[3],".").concat(n[0]),"".concat(n[2],".").concat(n[3],".").concat(n[1]),"".concat(n[3],".").concat(n[0],".").concat(n[1]),"".concat(n[3],".").concat(n[0],".").concat(n[2]),"".concat(n[3],".").concat(n[1],".").concat(n[0]),"".concat(n[3],".").concat(n[1],".").concat(n[2]),"".concat(n[3],".").concat(n[2],".").concat(n[0]),"".concat(n[3],".").concat(n[2],".").concat(n[1]),"".concat(n[0],".").concat(n[1],".").concat(n[2],".").concat(n[3]),"".concat(n[0],".").concat(n[1],".").concat(n[3],".").concat(n[2]),"".concat(n[0],".").concat(n[2],".").concat(n[1],".").concat(n[3]),"".concat(n[0],".").concat(n[2],".").concat(n[3],".").concat(n[1]),"".concat(n[0],".").concat(n[3],".").concat(n[1],".").concat(n[2]),"".concat(n[0],".").concat(n[3],".").concat(n[2],".").concat(n[1]),"".concat(n[1],".").concat(n[0],".").concat(n[2],".").concat(n[3]),"".concat(n[1],".").concat(n[0],".").concat(n[3],".").concat(n[2]),"".concat(n[1],".").concat(n[2],".").concat(n[0],".").concat(n[3]),"".concat(n[1],".").concat(n[2],".").concat(n[3],".").concat(n[0]),"".concat(n[1],".").concat(n[3],".").concat(n[0],".").concat(n[2]),"".concat(n[1],".").concat(n[3],".").concat(n[2],".").concat(n[0]),"".concat(n[2],".").concat(n[0],".").concat(n[1],".").concat(n[3]),"".concat(n[2],".").concat(n[0],".").concat(n[3],".").concat(n[1]),"".concat(n[2],".").concat(n[1],".").concat(n[0],".").concat(n[3]),"".concat(n[2],".").concat(n[1],".").concat(n[3],".").concat(n[0]),"".concat(n[2],".").concat(n[3],".").concat(n[0],".").concat(n[1]),"".concat(n[2],".").concat(n[3],".").concat(n[1],".").concat(n[0]),"".concat(n[3],".").concat(n[0],".").concat(n[1],".").concat(n[2]),"".concat(n[3],".").concat(n[0],".").concat(n[2],".").concat(n[1]),"".concat(n[3],".").concat(n[1],".").concat(n[0],".").concat(n[2]),"".concat(n[3],".").concat(n[1],".").concat(n[2],".").concat(n[0]),"".concat(n[3],".").concat(n[2],".").concat(n[0],".").concat(n[1]),"".concat(n[3],".").concat(n[2],".").concat(n[1],".").concat(n[0])]:void 0}(n)),j3[s]}function MI(n){var s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},t=arguments.length>2?arguments[2]:void 0,o=n.filter(function(g){return"token"!==g}),c=CI(o);return c.reduce(function(g,C){return lb(lb({},g),t[C])},s)}function m6(n){return n.join(" ")}function v6(n){var s=n.node,t=n.stylesheet,o=n.style,c=void 0===o?{}:o,g=n.useInlineStyles,C=n.key,D=s.properties,j=s.tagName;if("text"===s.type)return s.value;if(j){var oe,re=function(n,s){var t=0;return function(o){return t+=1,o.map(function(c,g){return v6({node:c,stylesheet:n,useInlineStyles:s,key:"code-segment-".concat(t,"-").concat(g)})})}}(t,g);if(g){var me=Object.keys(t).reduce(function(Le,we){return we.split(".").forEach(function(U){Le.includes(U)||Le.push(U)}),Le},[]),_e=D.className&&D.className.includes("token")?["token"]:[],Fe=D.className&&_e.concat(D.className.filter(function(Le){return!me.includes(Le)}));oe=lb(lb({},D),{},{className:m6(Fe)||void 0,style:MI(D.className,Object.assign({},D.style,c),t)})}else oe=lb(lb({},D),{},{className:m6(D.className)});var Re=re(s.children);return zo.createElement(j,tv({key:C},oe),Re)}}var wI=["language","children","style","customStyle","codeTagProps","useInlineStyles","showLineNumbers","showInlineLineNumbers","startingLineNumber","lineNumberContainerStyle","lineNumberStyle","wrapLines","wrapLongLines","lineProps","renderer","PreTag","CodeTag","code","astGenerator"];function y6(n,s){var t=Object.keys(n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(n);s&&(o=o.filter(function(c){return Object.getOwnPropertyDescriptor(n,c).enumerable})),t.push.apply(t,o)}return t}function hm(n){for(var s=1;s<arguments.length;s++){var t=null!=arguments[s]?arguments[s]:{};s%2?y6(Object(t),!0).forEach(function(o){Z3(n,o,t[o])}):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(t)):y6(Object(t)).forEach(function(o){Object.defineProperty(n,o,Object.getOwnPropertyDescriptor(t,o))})}return n}var xI=/\n/g;function NI(n){var s=n.codeString,o=n.containerStyle,g=n.numberStyle,C=void 0===g?{}:g,D=n.startingLineNumber;return zo.createElement("code",{style:Object.assign({},n.codeStyle,void 0===o?{float:"left",paddingRight:"10px"}:o)},function(n){var t=n.startingLineNumber,o=n.style;return n.lines.map(function(c,g){var C=g+t;return zo.createElement("span",{key:"line-".concat(g),className:"react-syntax-highlighter-line-number",style:"function"==typeof o?o(C):o},"".concat(C,"\n"))})}({lines:s.replace(/\n$/,"").split("\n"),style:C,startingLineNumber:D}))}function PI(n){return"".concat(n.toString().length,".25em")}function b6(n,s){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(n),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:s},children:[{type:"text",value:n}]}}function E6(n,s,t){var o={display:"inline-block",minWidth:PI(t),paddingRight:"1em",textAlign:"right",userSelect:"none"},c="function"==typeof n?n(s):n;return hm(hm({},o),c)}function RA(n){var s=n.children,t=n.lineNumber,o=n.lineNumberStyle,c=n.largestLineNumber,g=n.showInlineLineNumbers,C=n.lineProps,D=void 0===C?{}:C,P=n.className,j=void 0===P?[]:P,W=n.showLineNumbers,re=n.wrapLongLines,oe="function"==typeof D?D(t):D;if(oe.className=j,t&&g){var me=E6(o,t,c);s.unshift(b6(t,me))}return re&W&&(oe.style=hm(hm({},oe.style),{},{display:"flex"})),{type:"element",tagName:"span",properties:oe,children:s}}function T6(n){for(var s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],o=0;o<n.length;o++){var c=n[o];if("text"===c.type)t.push(RA({children:[c],className:TI(new Set(s))}));else if(c.children){var g=s.concat(c.properties.className);T6(c.children,g).forEach(function(C){return t.push(C)})}}return t}function II(n,s,t,o,c,g,C,D,P){var j,W=T6(n.value),re=[],oe=-1,me=0;function _e(ht,Dt){var Ft=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return RA({children:ht,lineNumber:Dt,lineNumberStyle:D,largestLineNumber:C,showInlineLineNumbers:c,lineProps:t,className:Ft,showLineNumbers:o,wrapLongLines:P})}function Fe(ht,Dt){if(o&&Dt&&c){var Ft=E6(D,Dt,C);ht.unshift(b6(Dt,Ft))}return ht}function Re(ht,Dt){var Ft=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return s||Ft.length>0?_e(ht,Dt,Ft):Fe(ht,Dt)}for(var Le=function(){var Dt=W[me],Ft=Dt.children[0].value;if(function(n){return n.match(xI)}(Ft)){var kt=Ft.split("\n");kt.forEach(function(wn,Tn){var Hr=o&&re.length+g,sr={type:"text",value:"".concat(wn,"\n")};if(0===Tn){var xr=Re(W.slice(oe+1,me).concat(RA({children:[sr],className:Dt.properties.className})),Hr);re.push(xr)}else if(Tn===kt.length-1){var fn=W[me+1]&&W[me+1].children&&W[me+1].children[0],Rn={type:"text",value:"".concat(wn)};if(fn){var kn=RA({children:[Rn],className:Dt.properties.className});W.splice(me+1,0,kn)}else{var bn=Re([Rn],Hr,Dt.properties.className);re.push(bn)}}else{var ji=Re([sr],Hr,Dt.properties.className);re.push(ji)}}),oe=me}me++};me<W.length;)Le();if(oe!==W.length-1){var we=W.slice(oe+1,W.length);if(we&&we.length){var pt=Re(we,o&&re.length+g);re.push(pt)}}return s?re:(j=[]).concat.apply(j,re)}function LI(n){var t=n.stylesheet,o=n.useInlineStyles;return n.rows.map(function(c,g){return v6({node:c,stylesheet:t,useInlineStyles:o,key:"code-segement".concat(g)})})}function S6(n){return n&&void 0!==n.highlightAuto}var C6=i(74538),M6=function(n,s){return function(o){var c=o.language,g=o.children,C=o.style,D=void 0===C?s:C,P=o.customStyle,j=void 0===P?{}:P,W=o.codeTagProps,re=void 0===W?{className:c?"language-".concat(c):void 0,style:hm(hm({},D['code[class*="language-"]']),D['code[class*="language-'.concat(c,'"]')])}:W,oe=o.useInlineStyles,me=void 0===oe||oe,_e=o.showLineNumbers,Fe=void 0!==_e&&_e,Re=o.showInlineLineNumbers,Le=void 0===Re||Re,we=o.startingLineNumber,U=void 0===we?1:we,pt=o.lineNumberContainerStyle,ht=o.lineNumberStyle,Dt=void 0===ht?{}:ht,Ft=o.wrapLines,cn=o.wrapLongLines,kt=void 0!==cn&&cn,wn=o.lineProps,Tn=void 0===wn?{}:wn,Hr=o.renderer,sr=o.PreTag,Nr=void 0===sr?"pre":sr,xr=o.CodeTag,fn=void 0===xr?"code":xr,Rn=o.code,kn=void 0===Rn?(Array.isArray(g)?g[0]:g)||"":Rn,Wn=o.astGenerator,bn=function(n,s){if(null==n)return{};var o,c,t=oS(n,s);if(Object.getOwnPropertySymbols){var g=Object.getOwnPropertySymbols(n);for(c=0;c<g.length;c++)!(s.indexOf(o=g[c])>=0)&&(!Object.prototype.propertyIsEnumerable.call(n,o)||(t[o]=n[o]))}return t}(o,wI);Wn=Wn||n;var jr=Fe?zo.createElement(NI,{containerStyle:pt,codeStyle:re.style||{},numberStyle:Dt,startingLineNumber:U,codeString:kn}):null,ji=D.hljs||D['pre[class*="language-"]']||{backgroundColor:"#fff"},oi=S6(Wn)?"hljs":"prismjs",Ui=Object.assign({},bn,me?{style:Object.assign({},ji,j)}:{className:bn.className?"".concat(oi," ").concat(bn.className):oi,style:Object.assign({},j)});if(re.style=hm(hm({},re.style),{},kt?{whiteSpace:"pre-wrap"}:{whiteSpace:"pre"}),!Wn)return zo.createElement(Nr,Ui,jr,zo.createElement(fn,re,kn));(void 0===Ft&&Hr||kt)&&(Ft=!0),Hr=Hr||LI;var Xr=[{type:"text",value:kn}],Sn=function(n){var s=n.astGenerator,t=n.language,o=n.code,c=n.defaultCodeValue;if(S6(s)){var g=function(n,s){return-1!==n.listLanguages().indexOf(s)}(s,t);return"text"===t?{value:c,language:"text"}:g?s.highlight(t,o):s.highlightAuto(o)}try{return t&&"text"!==t?{value:s.highlight(o,t)}:{value:c}}catch(C){return{value:c}}}({astGenerator:Wn,language:c,code:kn,defaultCodeValue:Xr});null===Sn.language&&(Sn.value=Xr);var _r=II(Sn,Ft,Tn,Fe,Le,U,Sn.value.length+U,Dt,kt);return zo.createElement(Nr,Ui,zo.createElement(fn,re,!Le&&jr,Hr({rows:_r,stylesheet:D,useInlineStyles:me})))}}(C6,{});M6.registerLanguage=C6.registerLanguage;const $I=M6;var HI=i(36147);const BI=i.n(HI)();var YI=i(92229);const jI=i.n(YI)();var GI=i(13546);const zI=i.n(GI)();var WI=i(4357);const QI=i.n(WI)();var XI=i(44776);const qI=i.n(XI)();var e4=i(28390);const n4=i.n(e4)();var r4=i(78932);const o4=i.n(r4)(),s4={hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#333",color:"white"},"hljs-name":{fontWeight:"bold"},"hljs-strong":{fontWeight:"bold"},"hljs-code":{fontStyle:"italic",color:"#888"},"hljs-emphasis":{fontStyle:"italic"},"hljs-tag":{color:"#62c8f3"},"hljs-variable":{color:"#ade5fc"},"hljs-template-variable":{color:"#ade5fc"},"hljs-selector-id":{color:"#ade5fc"},"hljs-selector-class":{color:"#ade5fc"},"hljs-string":{color:"#a2fca2"},"hljs-bullet":{color:"#d36363"},"hljs-type":{color:"#ffa"},"hljs-title":{color:"#ffa"},"hljs-section":{color:"#ffa"},"hljs-attribute":{color:"#ffa"},"hljs-quote":{color:"#ffa"},"hljs-built_in":{color:"#ffa"},"hljs-builtin-name":{color:"#ffa"},"hljs-number":{color:"#d36363"},"hljs-symbol":{color:"#d36363"},"hljs-keyword":{color:"#fcc28c"},"hljs-selector-tag":{color:"#fcc28c"},"hljs-literal":{color:"#fcc28c"},"hljs-comment":{color:"#888"},"hljs-deletion":{color:"#333",backgroundColor:"#fc9b9b"},"hljs-regexp":{color:"#c6b4f0"},"hljs-link":{color:"#c6b4f0"},"hljs-meta":{color:"#fc9b9b"},"hljs-addition":{backgroundColor:"#a2fca2",color:"#333"}},a4={hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#222",color:"#aaa"},"hljs-subst":{color:"#aaa"},"hljs-section":{color:"#fff",fontWeight:"bold"},"hljs-comment":{color:"#444"},"hljs-quote":{color:"#444"},"hljs-meta":{color:"#444"},"hljs-string":{color:"#ffcc33"},"hljs-symbol":{color:"#ffcc33"},"hljs-bullet":{color:"#ffcc33"},"hljs-regexp":{color:"#ffcc33"},"hljs-number":{color:"#00cc66"},"hljs-addition":{color:"#00cc66"},"hljs-built_in":{color:"#32aaee"},"hljs-builtin-name":{color:"#32aaee"},"hljs-literal":{color:"#32aaee"},"hljs-type":{color:"#32aaee"},"hljs-template-variable":{color:"#32aaee"},"hljs-attribute":{color:"#32aaee"},"hljs-link":{color:"#32aaee"},"hljs-keyword":{color:"#6644aa"},"hljs-selector-tag":{color:"#6644aa"},"hljs-name":{color:"#6644aa"},"hljs-selector-id":{color:"#6644aa"},"hljs-selector-class":{color:"#6644aa"},"hljs-title":{color:"#bb1166"},"hljs-variable":{color:"#bb1166"},"hljs-deletion":{color:"#bb1166"},"hljs-template-tag":{color:"#bb1166"},"hljs-doctag":{fontWeight:"bold"},"hljs-strong":{fontWeight:"bold"},"hljs-emphasis":{fontStyle:"italic"}},l4={hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#272822",color:"#ddd"},"hljs-tag":{color:"#f92672"},"hljs-keyword":{color:"#f92672",fontWeight:"bold"},"hljs-selector-tag":{color:"#f92672",fontWeight:"bold"},"hljs-literal":{color:"#f92672",fontWeight:"bold"},"hljs-strong":{color:"#f92672"},"hljs-name":{color:"#f92672"},"hljs-code":{color:"#66d9ef"},"hljs-class .hljs-title":{color:"white"},"hljs-attribute":{color:"#bf79db"},"hljs-symbol":{color:"#bf79db"},"hljs-regexp":{color:"#bf79db"},"hljs-link":{color:"#bf79db"},"hljs-string":{color:"#a6e22e"},"hljs-bullet":{color:"#a6e22e"},"hljs-subst":{color:"#a6e22e"},"hljs-title":{color:"#a6e22e",fontWeight:"bold"},"hljs-section":{color:"#a6e22e",fontWeight:"bold"},"hljs-emphasis":{color:"#a6e22e"},"hljs-type":{color:"#a6e22e",fontWeight:"bold"},"hljs-built_in":{color:"#a6e22e"},"hljs-builtin-name":{color:"#a6e22e"},"hljs-selector-attr":{color:"#a6e22e"},"hljs-selector-pseudo":{color:"#a6e22e"},"hljs-addition":{color:"#a6e22e"},"hljs-variable":{color:"#a6e22e"},"hljs-template-tag":{color:"#a6e22e"},"hljs-template-variable":{color:"#a6e22e"},"hljs-comment":{color:"#75715e"},"hljs-quote":{color:"#75715e"},"hljs-deletion":{color:"#75715e"},"hljs-meta":{color:"#75715e"},"hljs-doctag":{fontWeight:"bold"},"hljs-selector-id":{fontWeight:"bold"}},u4={hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#2E3440",color:"#D8DEE9"},"hljs-subst":{color:"#D8DEE9"},"hljs-selector-tag":{color:"#81A1C1"},"hljs-selector-id":{color:"#8FBCBB",fontWeight:"bold"},"hljs-selector-class":{color:"#8FBCBB"},"hljs-selector-attr":{color:"#8FBCBB"},"hljs-selector-pseudo":{color:"#88C0D0"},"hljs-addition":{backgroundColor:"rgba(163, 190, 140, 0.5)"},"hljs-deletion":{backgroundColor:"rgba(191, 97, 106, 0.5)"},"hljs-built_in":{color:"#8FBCBB"},"hljs-type":{color:"#8FBCBB"},"hljs-class":{color:"#8FBCBB"},"hljs-function":{color:"#88C0D0"},"hljs-function > .hljs-title":{color:"#88C0D0"},"hljs-keyword":{color:"#81A1C1"},"hljs-literal":{color:"#81A1C1"},"hljs-symbol":{color:"#81A1C1"},"hljs-number":{color:"#B48EAD"},"hljs-regexp":{color:"#EBCB8B"},"hljs-string":{color:"#A3BE8C"},"hljs-title":{color:"#8FBCBB"},"hljs-params":{color:"#D8DEE9"},"hljs-bullet":{color:"#81A1C1"},"hljs-code":{color:"#8FBCBB"},"hljs-emphasis":{fontStyle:"italic"},"hljs-formula":{color:"#8FBCBB"},"hljs-strong":{fontWeight:"bold"},"hljs-link:hover":{textDecoration:"underline"},"hljs-quote":{color:"#4C566A"},"hljs-comment":{color:"#4C566A"},"hljs-doctag":{color:"#8FBCBB"},"hljs-meta":{color:"#5E81AC"},"hljs-meta-keyword":{color:"#5E81AC"},"hljs-meta-string":{color:"#A3BE8C"},"hljs-attr":{color:"#8FBCBB"},"hljs-attribute":{color:"#D8DEE9"},"hljs-builtin-name":{color:"#81A1C1"},"hljs-name":{color:"#81A1C1"},"hljs-section":{color:"#88C0D0"},"hljs-tag":{color:"#81A1C1"},"hljs-variable":{color:"#D8DEE9"},"hljs-template-variable":{color:"#D8DEE9"},"hljs-template-tag":{color:"#5E81AC"},"abnf .hljs-attribute":{color:"#88C0D0"},"abnf .hljs-symbol":{color:"#EBCB8B"},"apache .hljs-attribute":{color:"#88C0D0"},"apache .hljs-section":{color:"#81A1C1"},"arduino .hljs-built_in":{color:"#88C0D0"},"aspectj .hljs-meta":{color:"#D08770"},"aspectj > .hljs-title":{color:"#88C0D0"},"bnf .hljs-attribute":{color:"#8FBCBB"},"clojure .hljs-name":{color:"#88C0D0"},"clojure .hljs-symbol":{color:"#EBCB8B"},"coq .hljs-built_in":{color:"#88C0D0"},"cpp .hljs-meta-string":{color:"#8FBCBB"},"css .hljs-built_in":{color:"#88C0D0"},"css .hljs-keyword":{color:"#D08770"},"diff .hljs-meta":{color:"#8FBCBB"},"ebnf .hljs-attribute":{color:"#8FBCBB"},"glsl .hljs-built_in":{color:"#88C0D0"},"groovy .hljs-meta:not(:first-child)":{color:"#D08770"},"haxe .hljs-meta":{color:"#D08770"},"java .hljs-meta":{color:"#D08770"},"ldif .hljs-attribute":{color:"#8FBCBB"},"lisp .hljs-name":{color:"#88C0D0"},"lua .hljs-built_in":{color:"#88C0D0"},"moonscript .hljs-built_in":{color:"#88C0D0"},"nginx .hljs-attribute":{color:"#88C0D0"},"nginx .hljs-section":{color:"#5E81AC"},"pf .hljs-built_in":{color:"#88C0D0"},"processing .hljs-built_in":{color:"#88C0D0"},"scss .hljs-keyword":{color:"#81A1C1"},"stylus .hljs-keyword":{color:"#81A1C1"},"swift .hljs-meta":{color:"#D08770"},"vim .hljs-built_in":{color:"#88C0D0",fontStyle:"italic"},"yaml .hljs-meta":{color:"#D08770"}},c4={hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#282b2e",color:"#e0e2e4"},"hljs-keyword":{color:"#93c763",fontWeight:"bold"},"hljs-selector-tag":{color:"#93c763",fontWeight:"bold"},"hljs-literal":{color:"#93c763",fontWeight:"bold"},"hljs-selector-id":{color:"#93c763"},"hljs-number":{color:"#ffcd22"},"hljs-attribute":{color:"#668bb0"},"hljs-code":{color:"white"},"hljs-class .hljs-title":{color:"white"},"hljs-section":{color:"white",fontWeight:"bold"},"hljs-regexp":{color:"#d39745"},"hljs-link":{color:"#d39745"},"hljs-meta":{color:"#557182"},"hljs-tag":{color:"#8cbbad"},"hljs-name":{color:"#8cbbad",fontWeight:"bold"},"hljs-bullet":{color:"#8cbbad"},"hljs-subst":{color:"#8cbbad"},"hljs-emphasis":{color:"#8cbbad"},"hljs-type":{color:"#8cbbad",fontWeight:"bold"},"hljs-built_in":{color:"#8cbbad"},"hljs-selector-attr":{color:"#8cbbad"},"hljs-selector-pseudo":{color:"#8cbbad"},"hljs-addition":{color:"#8cbbad"},"hljs-variable":{color:"#8cbbad"},"hljs-template-tag":{color:"#8cbbad"},"hljs-template-variable":{color:"#8cbbad"},"hljs-string":{color:"#ec7600"},"hljs-symbol":{color:"#ec7600"},"hljs-comment":{color:"#818e96"},"hljs-quote":{color:"#818e96"},"hljs-deletion":{color:"#818e96"},"hljs-selector-class":{color:"#A082BD"},"hljs-doctag":{fontWeight:"bold"},"hljs-title":{fontWeight:"bold"},"hljs-strong":{fontWeight:"bold"}},d4={"hljs-comment":{color:"#969896"},"hljs-quote":{color:"#969896"},"hljs-variable":{color:"#cc6666"},"hljs-template-variable":{color:"#cc6666"},"hljs-tag":{color:"#cc6666"},"hljs-name":{color:"#cc6666"},"hljs-selector-id":{color:"#cc6666"},"hljs-selector-class":{color:"#cc6666"},"hljs-regexp":{color:"#cc6666"},"hljs-deletion":{color:"#cc6666"},"hljs-number":{color:"#de935f"},"hljs-built_in":{color:"#de935f"},"hljs-builtin-name":{color:"#de935f"},"hljs-literal":{color:"#de935f"},"hljs-type":{color:"#de935f"},"hljs-params":{color:"#de935f"},"hljs-meta":{color:"#de935f"},"hljs-link":{color:"#de935f"},"hljs-attribute":{color:"#f0c674"},"hljs-string":{color:"#b5bd68"},"hljs-symbol":{color:"#b5bd68"},"hljs-bullet":{color:"#b5bd68"},"hljs-addition":{color:"#b5bd68"},"hljs-title":{color:"#81a2be"},"hljs-section":{color:"#81a2be"},"hljs-keyword":{color:"#b294bb"},"hljs-selector-tag":{color:"#b294bb"},hljs:{display:"block",overflowX:"auto",background:"#1d1f21",color:"#c5c8c6",padding:"0.5em"},"hljs-emphasis":{fontStyle:"italic"},"hljs-strong":{fontWeight:"bold"}};var f4=i(43155),p4=i(35037),h4=i.n(p4),_4=i(93890),g4=i.n(_4),m4=i(98990),v4=i.n(m4),y4=i(52190),b4=i.n(y4),E4=i(71166),T4=i.n(E4),S4=i(52243),C4=i.n(S4),A6=i(15805),ub=i(68645),G3=i(62734),O6=i(76593);function T0(n){var s;return(T0=G3?ub(s=O6).call(s):function(o){return o.__proto__||O6(o)})(n)}function M4(n,s){for(;!Object.prototype.hasOwnProperty.call(n,s)&&null!==(n=T0(n)););return n}function NA(){var n;return(NA="undefined"!=typeof Reflect&&A6?ub(n=A6).call(n):function(t,o,c){var g=M4(t,o);if(g){var C=d0(g,o);return C.get?C.get.call(arguments.length<3?t:c):C.value}}).apply(this,arguments)}var w6=i(54839),x6=i(73921);function sS(n,s){var t;return(sS=G3?ub(t=G3).call(t):function(c,g){return c.__proto__=g,c})(n,s)}var aS=i(69244);function D6(){if("undefined"==typeof Reflect||!aS||aS.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(aS(Boolean,[],function(){})),!0}catch(n){return!1}}function PA(n,s,t){var o;return(PA=D6()?ub(o=aS).call(o):function(g,C,D){var P=[null];P.push.apply(P,C);var W=new(ub(Function).apply(g,P));return D&&sS(W,D.prototype),W}).apply(null,arguments)}function V3(n){var s="function"==typeof w6?new w6:void 0;return(V3=function(o){if(null===o||!function(n){var s;return-1!==F3(s=Function.toString.call(n)).call(s,"[native code]")}(o))return o;if("function"!=typeof o)throw new TypeError("Super expression must either be null or a function");if(void 0!==s){if(s.has(o))return s.get(o);s.set(o,c)}function c(){return PA(o,arguments,T0(this).constructor)}return c.prototype=x6(o.prototype,{constructor:{value:c,enumerable:!1,writable:!0,configurable:!0}}),sS(c,o)})(n)}var O4=i(45163),w4=i.n(O4),x4=i(58711),D4=i.n(x4),R4=i(15886),N4=i.n(R4),P4=i(56166),I4=i.n(P4),L4=i(84901),F4=i.n(L4),k4=i(71851),$4=i.n(k4),H4=i(91465),U4=i.n(H4),B4=i(35431),Y4=i.n(B4),Z4=i(53625),j4=i.n(Z4),G4=i(31978),V4=i.n(G4),z4=i(40984),W4=i.n(z4),J4=i(54082),Q4=i.n(J4),X4=i(69605),K4=i.n(X4),q4=i(87513),e5=i.n(q4),t5=i(69253),n5=i.n(t5);function R6(n){if(void 0===n)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return n}function r5(n,s){if(s&&("object"===vc(s)||"function"==typeof s))return s;if(void 0!==s)throw new TypeError("Derived constructors may only return object or undefined");return R6(n)}function i5(n){var s=D6();return function(){var c,o=T0(n);if(s){var g=T0(this).constructor;c=aS(o,arguments,g)}else c=o.apply(this,arguments);return r5(this,c)}}var N6=i(95343);function z3(){var n;return(z3=N6?ub(n=N6).call(n):function(s){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var c in o)Object.prototype.hasOwnProperty.call(o,c)&&(s[c]=o[c])}return s}).apply(this,arguments)}function o5(n,s){if("function"!=typeof s&&null!==s)throw new TypeError("Super expression must either be null or a function");n.prototype=x6(s&&s.prototype,{constructor:{value:n,writable:!0,configurable:!0}}),Wv(n,"prototype",{writable:!1}),s&&sS(n,s)}var s5=i(96434),a5=i.t(s5,2),l5=i(82885),u5=i.n(l5),c5=i(12658),d5=i.t(c5,2),f5=i(55836),p5=i.n(f5),h5=i(97425),_5=i.n(h5),g5=i(76874),m5=i.n(g5),v5=i(43409),y5=i(14395),b5=i.n(y5);function P6(n,s){var t=Object.keys(n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(n);s&&(o=o.filter(function(c){return Object.getOwnPropertyDescriptor(n,c).enumerable})),t.push.apply(t,o)}return t}function I6(n){for(var s=1;s<arguments.length;s++){var t=null!=arguments[s]?arguments[s]:{};s%2?P6(Object(t),!0).forEach(function(o){Z3(n,o,t[o])}):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(t)):P6(Object(t)).forEach(function(o){Object.defineProperty(n,o,Object.getOwnPropertyDescriptor(t,o))})}return n}function Ip(n){return"Minified Redux error #"+n+"; visit https://redux.js.org/Errors?code="+n+" for the full message or use the non-minified dev environment for full errors. "}var IA,L6="function"==typeof Symbol&&Symbol.observable||"@@observable",W3=function(){return Math.random().toString(36).substring(7).split("").join(".")},cb={INIT:"@@redux/INIT"+W3(),REPLACE:"@@redux/REPLACE"+W3(),PROBE_UNKNOWN_ACTION:function(){return"@@redux/PROBE_UNKNOWN_ACTION"+W3()}};function F6(n){if("object"!=typeof n||null===n)return!1;for(var s=n;null!==Object.getPrototypeOf(s);)s=Object.getPrototypeOf(s);return Object.getPrototypeOf(n)===s}function k6(n,s,t){var o;if("function"==typeof s&&"function"==typeof t||"function"==typeof t&&"function"==typeof arguments[3])throw new Error(Ip(0));if("function"==typeof s&&void 0===t&&(t=s,s=void 0),void 0!==t){if("function"!=typeof t)throw new Error(Ip(1));return t(k6)(n,s)}if("function"!=typeof n)throw new Error(Ip(2));var c=n,g=s,C=[],D=C,P=!1;function j(){D===C&&(D=C.slice())}function W(){if(P)throw new Error(Ip(3));return g}function re(Fe){if("function"!=typeof Fe)throw new Error(Ip(4));if(P)throw new Error(Ip(5));var Re=!0;return j(),D.push(Fe),function(){if(Re){if(P)throw new Error(Ip(6));Re=!1,j();var we=D.indexOf(Fe);D.splice(we,1),C=null}}}function oe(Fe){if(!F6(Fe))throw new Error(Ip(7));if(void 0===Fe.type)throw new Error(Ip(8));if(P)throw new Error(Ip(9));try{P=!0,g=c(g,Fe)}finally{P=!1}for(var Re=C=D,Le=0;Le<Re.length;Le++)(0,Re[Le])();return Fe}function me(Fe){if("function"!=typeof Fe)throw new Error(Ip(10));c=Fe,oe({type:cb.REPLACE})}function _e(){var Fe,Re=re;return(Fe={subscribe:function(we){if("object"!=typeof we||null===we)throw new Error(Ip(11));function U(){we.next&&we.next(W())}return U(),{unsubscribe:Re(U)}}})[L6]=function(){return this},Fe}return oe({type:cb.INIT}),(o={dispatch:oe,subscribe:re,getState:W,replaceReducer:me})[L6]=_e,o}function $6(n,s){return function(){return s(n.apply(this,arguments))}}function A5(n,s){if("function"==typeof n)return $6(n,s);if("object"!=typeof n||null===n)throw new Error(Ip(16));var t={};for(var o in n){var c=n[o];"function"==typeof c&&(t[o]=$6(c,s))}return t}function H6(){for(var n=arguments.length,s=new Array(n),t=0;t<n;t++)s[t]=arguments[t];return 0===s.length?function(o){return o}:1===s.length?s[0]:s.reduce(function(o,c){return function(){return o(c.apply(void 0,arguments))}})}function O5(){for(var n=arguments.length,s=new Array(n),t=0;t<n;t++)s[t]=arguments[t];return function(o){return function(){var c=o.apply(void 0,arguments),g=function(){throw new Error(Ip(15))},C={getState:c.getState,dispatch:function(){return g.apply(void 0,arguments)}},D=s.map(function(P){return P(C)});return g=H6.apply(void 0,D)(c.dispatch),I6(I6({},c),{},{dispatch:g})}}}function U6(n){return(IA=IA||document.createElement("textarea")).innerHTML="&"+n+";",IA.value}var D5=Object.prototype.hasOwnProperty;function J3(n){var s=[].slice.call(arguments,1);return s.forEach(function(t){if(t){if("object"!=typeof t)throw new TypeError(t+"must be object");Object.keys(t).forEach(function(o){n[o]=t[o]})}}),n}var R5=/\\([\\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g;function db(n){return n.indexOf("\\")<0?n:n.replace(R5,"$1")}function Q3(n){return!(n>=55296&&n<=57343||n>=64976&&n<=65007||65535==(65535&n)||65534==(65535&n)||n>=0&&n<=8||11===n||n>=14&&n<=31||n>=127&&n<=159||n>1114111)}function LA(n){return n>65535?(n-=65536,String.fromCharCode(55296+(n>>10),56320+(1023&n))):String.fromCharCode(n)}var N5=/&([a-z#][a-z0-9]{1,31});/gi,P5=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i;function I5(n,s){var t=0,o=U6(s);return s!==o?o:35===s.charCodeAt(0)&&P5.test(s)&&Q3(t="x"===s[1].toLowerCase()?parseInt(s.slice(2),16):parseInt(s.slice(1),10))?LA(t):n}function qv(n){return n.indexOf("&")<0?n:n.replace(N5,I5)}var L5=/[&<>"]/,F5=/[&<>"]/g,k5={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"};function $5(n){return k5[n]}function Mh(n){return L5.test(n)?n.replace(F5,$5):n}var Ks={};function Y6(n,s){return++s>=n.length-2?s:"paragraph_open"===n[s].type&&n[s].tight&&"inline"===n[s+1].type&&0===n[s+1].content.length&&"paragraph_close"===n[s+2].type&&n[s+2].tight?Y6(n,s+2):s}Ks.blockquote_open=function(){return"<blockquote>\n"},Ks.blockquote_close=function(n,s){return"</blockquote>"+S0(n,s)},Ks.code=function(n,s){return n[s].block?"<pre><code>"+Mh(n[s].content)+"</code></pre>"+S0(n,s):"<code>"+Mh(n[s].content)+"</code>"},Ks.fence=function(n,s,t,o,c){var j,W,g=n[s],C="",D=t.langPrefix;if(g.params){if(W=(j=g.params.split(/\s+/g)).join(" "),function(n,s){return!!n&&D5.call(n,s)}(c.rules.fence_custom,j[0]))return c.rules.fence_custom[j[0]](n,s,t,o,c);C=' class="'+D+Mh(qv(db(W)))+'"'}return"<pre><code"+C+">"+(t.highlight&&t.highlight.apply(t.highlight,[g.content].concat(j))||Mh(g.content))+"</code></pre>"+S0(n,s)},Ks.fence_custom={},Ks.heading_open=function(n,s){return"<h"+n[s].hLevel+">"},Ks.heading_close=function(n,s){return"</h"+n[s].hLevel+">\n"},Ks.hr=function(n,s,t){return(t.xhtmlOut?"<hr />":"<hr>")+S0(n,s)},Ks.bullet_list_open=function(){return"<ul>\n"},Ks.bullet_list_close=function(n,s){return"</ul>"+S0(n,s)},Ks.list_item_open=function(){return"<li>"},Ks.list_item_close=function(){return"</li>\n"},Ks.ordered_list_open=function(n,s){var t=n[s];return"<ol"+(t.order>1?' start="'+t.order+'"':"")+">\n"},Ks.ordered_list_close=function(n,s){return"</ol>"+S0(n,s)},Ks.paragraph_open=function(n,s){return n[s].tight?"":"<p>"},Ks.paragraph_close=function(n,s){return(n[s].tight?"":"</p>")+(n[s].tight&&s&&"inline"===n[s-1].type&&!n[s-1].content?"":S0(n,s))},Ks.link_open=function(n,s,t){var o=n[s].title?' title="'+Mh(qv(n[s].title))+'"':"",c=t.linkTarget?' target="'+t.linkTarget+'"':"";return'<a href="'+Mh(n[s].href)+'"'+o+c+">"},Ks.link_close=function(){return"</a>"},Ks.image=function(n,s,t){var o=' src="'+Mh(n[s].src)+'"',c=n[s].title?' title="'+Mh(qv(n[s].title))+'"':"";return"<img"+o+' alt="'+(n[s].alt?Mh(qv(db(n[s].alt))):"")+'"'+c+(t.xhtmlOut?" /":"")+">"},Ks.table_open=function(){return"<table>\n"},Ks.table_close=function(){return"</table>\n"},Ks.thead_open=function(){return"<thead>\n"},Ks.thead_close=function(){return"</thead>\n"},Ks.tbody_open=function(){return"<tbody>\n"},Ks.tbody_close=function(){return"</tbody>\n"},Ks.tr_open=function(){return"<tr>"},Ks.tr_close=function(){return"</tr>\n"},Ks.th_open=function(n,s){var t=n[s];return"<th"+(t.align?' style="text-align:'+t.align+'"':"")+">"},Ks.th_close=function(){return"</th>"},Ks.td_open=function(n,s){var t=n[s];return"<td"+(t.align?' style="text-align:'+t.align+'"':"")+">"},Ks.td_close=function(){return"</td>"},Ks.strong_open=function(){return"<strong>"},Ks.strong_close=function(){return"</strong>"},Ks.em_open=function(){return"<em>"},Ks.em_close=function(){return"</em>"},Ks.del_open=function(){return"<del>"},Ks.del_close=function(){return"</del>"},Ks.ins_open=function(){return"<ins>"},Ks.ins_close=function(){return"</ins>"},Ks.mark_open=function(){return"<mark>"},Ks.mark_close=function(){return"</mark>"},Ks.sub=function(n,s){return"<sub>"+Mh(n[s].content)+"</sub>"},Ks.sup=function(n,s){return"<sup>"+Mh(n[s].content)+"</sup>"},Ks.hardbreak=function(n,s,t){return t.xhtmlOut?"<br />\n":"<br>\n"},Ks.softbreak=function(n,s,t){return t.breaks?t.xhtmlOut?"<br />\n":"<br>\n":"\n"},Ks.text=function(n,s){return Mh(n[s].content)},Ks.htmlblock=function(n,s){return n[s].content},Ks.htmltag=function(n,s){return n[s].content},Ks.abbr_open=function(n,s){return'<abbr title="'+Mh(qv(n[s].title))+'">'},Ks.abbr_close=function(){return"</abbr>"},Ks.footnote_ref=function(n,s){var t=Number(n[s].id+1).toString(),o="fnref"+t;return n[s].subId>0&&(o+=":"+n[s].subId),'<sup class="footnote-ref"><a href="#fn'+t+'" id="'+o+'">['+t+"]</a></sup>"},Ks.footnote_block_open=function(n,s,t){return(t.xhtmlOut?'<hr class="footnotes-sep" />\n':'<hr class="footnotes-sep">\n')+'<section class="footnotes">\n<ol class="footnotes-list">\n'},Ks.footnote_block_close=function(){return"</ol>\n</section>\n"},Ks.footnote_open=function(n,s){return'<li id="fn'+Number(n[s].id+1).toString()+'" class="footnote-item">'},Ks.footnote_close=function(){return"</li>\n"},Ks.footnote_anchor=function(n,s){var o="fnref"+Number(n[s].id+1).toString();return n[s].subId>0&&(o+=":"+n[s].subId),' <a href="#'+o+'" class="footnote-backref">\u21a9</a>'},Ks.dl_open=function(){return"<dl>\n"},Ks.dt_open=function(){return"<dt>"},Ks.dd_open=function(){return"<dd>"},Ks.dl_close=function(){return"</dl>\n"},Ks.dt_close=function(){return"</dt>\n"},Ks.dd_close=function(){return"</dd>\n"};var S0=Ks.getBreak=function(s,t){return(t=Y6(s,t))<s.length&&"list_item_close"===s[t].type?"":"\n"};function X3(){this.rules=J3({},Ks),this.getBreak=Ks.getBreak}function P_(){this.__rules__=[],this.__cache__=null}function C0(n,s,t,o,c){this.src=n,this.env=o,this.options=t,this.parser=s,this.tokens=c,this.pos=0,this.posMax=this.src.length,this.level=0,this.pending="",this.pendingLevel=0,this.cache=[],this.isInLabel=!1,this.linkLevel=0,this.linkContent="",this.labelUnmatchedScopes=0}function lS(n,s){var t,o,c,g=-1,C=n.posMax,D=n.pos,P=n.isInLabel;if(n.isInLabel)return-1;if(n.labelUnmatchedScopes)return n.labelUnmatchedScopes--,-1;for(n.pos=s+1,n.isInLabel=!0,t=1;n.pos<C;){if(91===(c=n.src.charCodeAt(n.pos)))t++;else if(93===c&&0==--t){o=!0;break}n.parser.skipToken(n)}return o?(g=n.pos,n.labelUnmatchedScopes=0):n.labelUnmatchedScopes=t-1,n.pos=D,n.isInLabel=P,g}function U5(n,s,t,o){var c,g,C,D,P,j;if(42!==n.charCodeAt(0)||91!==n.charCodeAt(1)||-1===n.indexOf("]:")||(g=lS(c=new C0(n,s,t,o,[]),1))<0||58!==n.charCodeAt(g+1))return-1;for(D=c.posMax,C=g+2;C<D&&10!==c.src.charCodeAt(C);C++);return P=n.slice(2,g),0===(j=n.slice(g+2,C).trim()).length?-1:(o.abbreviations||(o.abbreviations={}),void 0===o.abbreviations[":"+P]&&(o.abbreviations[":"+P]=j),C)}function K3(n){var s=qv(n);try{s=decodeURI(s)}catch(t){}return encodeURI(s)}function Z6(n,s){var t,o,c,g=s,C=n.posMax;if(60===n.src.charCodeAt(s)){for(s++;s<C;){if(10===(t=n.src.charCodeAt(s)))return!1;if(62===t)return c=K3(db(n.src.slice(g+1,s))),!!n.parser.validateLink(c)&&(n.pos=s+1,n.linkContent=c,!0);92===t&&s+1<C?s+=2:s++}return!1}for(o=0;s<C&&!(32===(t=n.src.charCodeAt(s))||t<32||127===t);)if(92===t&&s+1<C)s+=2;else{if(40===t&&++o>1||41===t&&--o<0)break;s++}return!(g===s||(c=db(n.src.slice(g,s)),!n.parser.validateLink(c))||(n.linkContent=c,n.pos=s,0))}function j6(n,s){var t,o=s,c=n.posMax,g=n.src.charCodeAt(s);if(34!==g&&39!==g&&40!==g)return!1;for(s++,40===g&&(g=41);s<c;){if((t=n.src.charCodeAt(s))===g)return n.pos=s+1,n.linkContent=db(n.src.slice(o+1,s)),!0;92===t&&s+1<c?s+=2:s++}return!1}function G6(n){return n.trim().replace(/\s+/g," ").toUpperCase()}function Y5(n,s,t,o){var c,g,C,D,P,j,W,re,oe;if(91!==n.charCodeAt(0)||-1===n.indexOf("]:")||(g=lS(c=new C0(n,s,t,o,[]),0))<0||58!==n.charCodeAt(g+1))return-1;for(D=c.posMax,C=g+2;C<D&&(32===(P=c.src.charCodeAt(C))||10===P);C++);if(!Z6(c,C))return-1;for(W=c.linkContent,j=C=c.pos,C+=1;C<D&&(32===(P=c.src.charCodeAt(C))||10===P);C++);for(C<D&&j!==C&&j6(c,C)?(re=c.linkContent,C=c.pos):(re="",C=j);C<D&&32===c.src.charCodeAt(C);)C++;return C<D&&10!==c.src.charCodeAt(C)?-1:(oe=G6(n.slice(1,g)),void 0===o.references[oe]&&(o.references[oe]={title:re,href:W}),C)}X3.prototype.renderInline=function(n,s,t){for(var o=this.rules,c=n.length,g=0,C="";c--;)C+=o[n[g].type](n,g++,s,t,this);return C},X3.prototype.render=function(n,s,t){for(var o=this.rules,c=n.length,g=-1,C="";++g<c;)C+="inline"===n[g].type?this.renderInline(n[g].children,s,t):o[n[g].type](n,g,s,t,this);return C},P_.prototype.__find__=function(n){for(var s=this.__rules__.length,t=-1;s--;)if(this.__rules__[++t].name===n)return t;return-1},P_.prototype.__compile__=function(){var n=this,s=[""];n.__rules__.forEach(function(t){!t.enabled||t.alt.forEach(function(o){s.indexOf(o)<0&&s.push(o)})}),n.__cache__={},s.forEach(function(t){n.__cache__[t]=[],n.__rules__.forEach(function(o){!o.enabled||t&&o.alt.indexOf(t)<0||n.__cache__[t].push(o.fn)})})},P_.prototype.at=function(n,s,t){var o=this.__find__(n),c=t||{};if(-1===o)throw new Error("Parser rule not found: "+n);this.__rules__[o].fn=s,this.__rules__[o].alt=c.alt||[],this.__cache__=null},P_.prototype.before=function(n,s,t,o){var c=this.__find__(n),g=o||{};if(-1===c)throw new Error("Parser rule not found: "+n);this.__rules__.splice(c,0,{name:s,enabled:!0,fn:t,alt:g.alt||[]}),this.__cache__=null},P_.prototype.after=function(n,s,t,o){var c=this.__find__(n),g=o||{};if(-1===c)throw new Error("Parser rule not found: "+n);this.__rules__.splice(c+1,0,{name:s,enabled:!0,fn:t,alt:g.alt||[]}),this.__cache__=null},P_.prototype.push=function(n,s,t){this.__rules__.push({name:n,enabled:!0,fn:s,alt:(t||{}).alt||[]}),this.__cache__=null},P_.prototype.enable=function(n,s){n=Array.isArray(n)?n:[n],s&&this.__rules__.forEach(function(t){t.enabled=!1}),n.forEach(function(t){var o=this.__find__(t);if(o<0)throw new Error("Rules manager: invalid rule name "+t);this.__rules__[o].enabled=!0},this),this.__cache__=null},P_.prototype.disable=function(n){(n=Array.isArray(n)?n:[n]).forEach(function(s){var t=this.__find__(s);if(t<0)throw new Error("Rules manager: invalid rule name "+s);this.__rules__[t].enabled=!1},this),this.__cache__=null},P_.prototype.getRules=function(n){return null===this.__cache__&&this.__compile__(),this.__cache__[n]||[]},C0.prototype.pushPending=function(){this.tokens.push({type:"text",content:this.pending,level:this.pendingLevel}),this.pending=""},C0.prototype.push=function(n){this.pending&&this.pushPending(),this.tokens.push(n),this.pendingLevel=this.level},C0.prototype.cacheSet=function(n,s){for(var t=this.cache.length;t<=n;t++)this.cache.push(0);this.cache[n]=s},C0.prototype.cacheGet=function(n){return n<this.cache.length?this.cache[n]:0};var V6=" \n()[]'\".,!?-";function q3(n){return n.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g,"\\$1")}var z5=/\+-|\.\.|\?\?\?\?|!!!!|,,|--/,W5=/\((c|tm|r|p)\)/gi,J5={c:"\xa9",r:"\xae",p:"\xa7",tm:"\u2122"};function Q5(n){return n.indexOf("(")<0?n:n.replace(W5,function(s,t){return J5[t.toLowerCase()]})}var K5=/['"]/,z6=/['"]/g,q5=/[-\s()\[\]]/;function J6(n,s){return!(s<0||s>=n.length||q5.test(n[s]))}function fb(n,s,t){return n.substr(0,s)+t+n.substr(s+1)}var eR=[["block",function(n){n.inlineMode?n.tokens.push({type:"inline",content:n.src.replace(/\n/g," ").trim(),level:0,lines:[0,1],children:[]}):n.block.parse(n.src,n.options,n.env,n.tokens)}],["abbr",function(n){var t,o,c,g,s=n.tokens;if(!n.inlineMode)for(t=1,o=s.length-1;t<o;t++)if("paragraph_open"===s[t-1].type&&"inline"===s[t].type&&"paragraph_close"===s[t+1].type){for(c=s[t].content;c.length&&!((g=U5(c,n.inline,n.options,n.env))<0);)c=c.slice(g).trim();s[t].content=c,c.length||(s[t-1].tight=!0,s[t+1].tight=!0)}}],["references",function(n){var t,o,c,g,s=n.tokens;if(n.env.references=n.env.references||{},!n.inlineMode)for(t=1,o=s.length-1;t<o;t++)if("inline"===s[t].type&&"paragraph_open"===s[t-1].type&&"paragraph_close"===s[t+1].type){for(c=s[t].content;c.length&&!((g=Y5(c,n.inline,n.options,n.env))<0);)c=c.slice(g).trim();s[t].content=c,c.length||(s[t-1].tight=!0,s[t+1].tight=!0)}}],["inline",function(n){var t,o,c,s=n.tokens;for(o=0,c=s.length;o<c;o++)"inline"===(t=s[o]).type&&n.inline.parse(t.content,n.options,n.env,t.children)}],["footnote_tail",function(n){var s,t,o,c,g,C,D,P,j,W=0,re=!1,oe={};if(n.env.footnotes&&(n.tokens=n.tokens.filter(function(me){return"footnote_reference_open"===me.type?(re=!0,P=[],j=me.label,!1):"footnote_reference_close"===me.type?(re=!1,oe[":"+j]=P,!1):(re&&P.push(me),!re)}),n.env.footnotes.list)){for(C=n.env.footnotes.list,n.tokens.push({type:"footnote_block_open",level:W++}),s=0,t=C.length;s<t;s++){for(n.tokens.push({type:"footnote_open",id:s,level:W++}),C[s].tokens?((D=[]).push({type:"paragraph_open",tight:!1,level:W++}),D.push({type:"inline",content:"",level:W,children:C[s].tokens}),D.push({type:"paragraph_close",tight:!1,level:--W})):C[s].label&&(D=oe[":"+C[s].label]),n.tokens=n.tokens.concat(D),g="paragraph_close"===n.tokens[n.tokens.length-1].type?n.tokens.pop():null,c=C[s].count>0?C[s].count:1,o=0;o<c;o++)n.tokens.push({type:"footnote_anchor",id:s,subId:o,level:W});g&&n.tokens.push(g),n.tokens.push({type:"footnote_close",level:--W})}n.tokens.push({type:"footnote_block_close",level:--W})}}],["abbr2",function(n){var s,t,o,c,g,C,D,P,j,W,re,oe,me=n.tokens;if(n.env.abbreviations)for(n.env.abbrRegExp||(oe="(^|["+V6.split("").map(q3).join("")+"])("+Object.keys(n.env.abbreviations).map(function(_e){return _e.substr(1)}).sort(function(_e,Fe){return Fe.length-_e.length}).map(q3).join("|")+")($|["+V6.split("").map(q3).join("")+"])",n.env.abbrRegExp=new RegExp(oe,"g")),W=n.env.abbrRegExp,t=0,o=me.length;t<o;t++)if("inline"===me[t].type)for(s=(c=me[t].children).length-1;s>=0;s--)if("text"===(g=c[s]).type){for(P=0,C=g.content,W.lastIndex=0,j=g.level,D=[];re=W.exec(C);)W.lastIndex>P&&D.push({type:"text",content:C.slice(P,re.index+re[1].length),level:j}),D.push({type:"abbr_open",title:n.env.abbreviations[":"+re[2]],level:j++}),D.push({type:"text",content:re[2],level:j}),D.push({type:"abbr_close",level:--j}),P=W.lastIndex-re[3].length;!D.length||(P<C.length&&D.push({type:"text",content:C.slice(P),level:j}),me[t].children=c=[].concat(c.slice(0,s),D,c.slice(s+1)))}}],["replacements",function(n){var s,t,o,c,g;if(n.options.typographer)for(g=n.tokens.length-1;g>=0;g--)if("inline"===n.tokens[g].type)for(s=(c=n.tokens[g].children).length-1;s>=0;s--)"text"===(t=c[s]).type&&(o=Q5(o=t.content),z5.test(o)&&(o=o.replace(/\+-/g,"\xb1").replace(/\.{2,}/g,"\u2026").replace(/([?!])\u2026/g,"$1..").replace(/([?!]){4,}/g,"$1$1$1").replace(/,{2,}/g,",").replace(/(^|[^-])---([^-]|$)/gm,"$1\u2014$2").replace(/(^|\s)--(\s|$)/gm,"$1\u2013$2").replace(/(^|[^-\s])--([^-\s]|$)/gm,"$1\u2013$2")),t.content=o)}],["smartquotes",function(n){var s,t,o,c,g,C,D,P,j,W,re,oe,me,_e,Fe,Re,Le;if(n.options.typographer)for(Le=[],Fe=n.tokens.length-1;Fe>=0;Fe--)if("inline"===n.tokens[Fe].type)for(Re=n.tokens[Fe].children,Le.length=0,s=0;s<Re.length;s++)if("text"===(t=Re[s]).type&&!K5.test(t.text)){for(D=Re[s].level,me=Le.length-1;me>=0&&!(Le[me].level<=D);me--);Le.length=me+1,g=0,C=(o=t.content).length;e:for(;g<C&&(z6.lastIndex=g,c=z6.exec(o),c);)if(P=!J6(o,c.index-1),_e="'"===c[0],(j=!J6(o,g=c.index+1))||P){if(re=!j,oe=!P)for(me=Le.length-1;me>=0&&(W=Le[me],!(Le[me].level<D));me--)if(W.single===_e&&Le[me].level===D){W=Le[me],_e?(Re[W.token].content=fb(Re[W.token].content,W.pos,n.options.quotes[2]),t.content=fb(t.content,c.index,n.options.quotes[3])):(Re[W.token].content=fb(Re[W.token].content,W.pos,n.options.quotes[0]),t.content=fb(t.content,c.index,n.options.quotes[1])),Le.length=me;continue e}re?Le.push({token:s,pos:c.index,single:_e,level:D}):oe&&_e&&(t.content=fb(t.content,c.index,"\u2019"))}else _e&&(t.content=fb(t.content,c.index,"\u2019"))}}]];function Q6(){this.options={},this.ruler=new P_;for(var n=0;n<eR.length;n++)this.ruler.push(eR[n][0],eR[n][1])}function M0(n,s,t,o,c){var g,C,D,P,j,W,re;for(this.src=n,this.parser=s,this.options=t,this.env=o,this.tokens=c,this.bMarks=[],this.eMarks=[],this.tShift=[],this.blkIndent=0,this.line=0,this.lineMax=0,this.tight=!1,this.parentType="root",this.ddIndent=-1,this.level=0,this.result="",W=0,re=!1,D=P=W=0,j=(C=this.src).length;P<j;P++){if(g=C.charCodeAt(P),!re){if(32===g){W++;continue}re=!0}(10===g||P===j-1)&&(10!==g&&P++,this.bMarks.push(D),this.eMarks.push(P),this.tShift.push(W),re=!1,W=0,D=P+1)}this.bMarks.push(C.length),this.eMarks.push(C.length),this.tShift.push(0),this.lineMax=this.bMarks.length-1}function X6(n,s){var t,o,c;return(o=n.bMarks[s]+n.tShift[s])>=(c=n.eMarks[s])||42!==(t=n.src.charCodeAt(o++))&&45!==t&&43!==t||o<c&&32!==n.src.charCodeAt(o)?-1:o}function K6(n,s){var t,o=n.bMarks[s]+n.tShift[s],c=n.eMarks[s];if(o+1>=c||(t=n.src.charCodeAt(o++))<48||t>57)return-1;for(;;){if(o>=c)return-1;if(!((t=n.src.charCodeAt(o++))>=48&&t<=57)){if(41===t||46===t)break;return-1}}return o<c&&32!==n.src.charCodeAt(o)?-1:o}Q6.prototype.process=function(n){var s,t,o;for(s=0,t=(o=this.ruler.getRules("")).length;s<t;s++)o[s](n)},M0.prototype.isEmpty=function(s){return this.bMarks[s]+this.tShift[s]>=this.eMarks[s]},M0.prototype.skipEmptyLines=function(s){for(var t=this.lineMax;s<t&&!(this.bMarks[s]+this.tShift[s]<this.eMarks[s]);s++);return s},M0.prototype.skipSpaces=function(s){for(var t=this.src.length;s<t&&32===this.src.charCodeAt(s);s++);return s},M0.prototype.skipChars=function(s,t){for(var o=this.src.length;s<o&&this.src.charCodeAt(s)===t;s++);return s},M0.prototype.skipCharsBack=function(s,t,o){if(s<=o)return s;for(;s>o;)if(t!==this.src.charCodeAt(--s))return s+1;return s},M0.prototype.getLines=function(s,t,o,c){var g,C,P,j,W=s;if(s>=t)return"";if(W+1===t)return C=this.bMarks[W]+Math.min(this.tShift[W],o),this.src.slice(C,c?this.eMarks[W]+1:this.eMarks[W]);for(P=new Array(t-s),g=0;W<t;W++,g++)(j=this.tShift[W])>o&&(j=o),j<0&&(j=0),P[g]=this.src.slice(C=this.bMarks[W]+j,W+1<t||c?this.eMarks[W]+1:this.eMarks[W]);return P.join("")};var q6={};["article","aside","button","blockquote","body","canvas","caption","col","colgroup","dd","div","dl","dt","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","hr","iframe","li","map","object","ol","output","p","pre","progress","script","section","style","table","tbody","td","textarea","tfoot","th","tr","thead","ul","video"].forEach(function(n){q6[n]=!0});var cL=/^<([a-zA-Z]{1,15})[\s\/>]/,dL=/^<\/([a-zA-Z]{1,15})[\s>]/;function tR(n,s){var t=n.bMarks[s]+n.blkIndent;return n.src.substr(t,n.eMarks[s]-t)}function FA(n,s){var t,o,c=n.bMarks[s]+n.tShift[s],g=n.eMarks[s];return c>=g||126!==(o=n.src.charCodeAt(c++))&&58!==o||c===(t=n.skipSpaces(c))||t>=g?-1:t}var kA=[["code",function(n,s,t){var o,c;if(n.tShift[s]-n.blkIndent<4)return!1;for(c=o=s+1;o<t;)if(n.isEmpty(o))o++;else{if(!(n.tShift[o]-n.blkIndent>=4))break;c=++o}return n.line=o,n.tokens.push({type:"code",content:n.getLines(s,c,4+n.blkIndent,!0),block:!0,lines:[s,n.line],level:n.level}),!0}],["fences",function(n,s,t,o){var c,g,C,D,P,j=!1,W=n.bMarks[s]+n.tShift[s],re=n.eMarks[s];if(W+3>re||126!==(c=n.src.charCodeAt(W))&&96!==c||(P=W,(g=(W=n.skipChars(W,c))-P)<3)||(C=n.src.slice(W,re).trim()).indexOf("`")>=0)return!1;if(o)return!0;for(D=s;!(++D>=t||(W=P=n.bMarks[D]+n.tShift[D],re=n.eMarks[D],W<re&&n.tShift[D]<n.blkIndent));)if(!(n.src.charCodeAt(W)!==c||n.tShift[D]-n.blkIndent>=4||(W=n.skipChars(W,c),W-P<g||(W=n.skipSpaces(W),W<re)))){j=!0;break}return g=n.tShift[s],n.line=D+(j?1:0),n.tokens.push({type:"fence",params:C,content:n.getLines(s+1,D,g,!0),lines:[s,n.line],level:n.level}),!0},["paragraph","blockquote","list"]],["blockquote",function(n,s,t,o){var c,g,C,D,P,j,W,re,oe,me,_e,Fe=n.bMarks[s]+n.tShift[s],Re=n.eMarks[s];if(Fe>Re||62!==n.src.charCodeAt(Fe++)||n.level>=n.options.maxNesting)return!1;if(o)return!0;for(32===n.src.charCodeAt(Fe)&&Fe++,P=n.blkIndent,n.blkIndent=0,D=[n.bMarks[s]],n.bMarks[s]=Fe,g=(Fe=Fe<Re?n.skipSpaces(Fe):Fe)>=Re,C=[n.tShift[s]],n.tShift[s]=Fe-n.bMarks[s],re=n.parser.ruler.getRules("blockquote"),c=s+1;c<t&&!((Fe=n.bMarks[c]+n.tShift[c])>=(Re=n.eMarks[c]));c++)if(62!==n.src.charCodeAt(Fe++)){if(g)break;for(_e=!1,oe=0,me=re.length;oe<me;oe++)if(re[oe](n,c,t,!0)){_e=!0;break}if(_e)break;D.push(n.bMarks[c]),C.push(n.tShift[c]),n.tShift[c]=-1337}else 32===n.src.charCodeAt(Fe)&&Fe++,D.push(n.bMarks[c]),n.bMarks[c]=Fe,g=(Fe=Fe<Re?n.skipSpaces(Fe):Fe)>=Re,C.push(n.tShift[c]),n.tShift[c]=Fe-n.bMarks[c];for(j=n.parentType,n.parentType="blockquote",n.tokens.push({type:"blockquote_open",lines:W=[s,0],level:n.level++}),n.parser.tokenize(n,s,c),n.tokens.push({type:"blockquote_close",level:--n.level}),n.parentType=j,W[1]=n.line,oe=0;oe<C.length;oe++)n.bMarks[oe+s]=D[oe],n.tShift[oe+s]=C[oe];return n.blkIndent=P,!0},["paragraph","blockquote","list"]],["hr",function(n,s,t,o){var c,g,C,D=n.bMarks[s],P=n.eMarks[s];if((D+=n.tShift[s])>P||42!==(c=n.src.charCodeAt(D++))&&45!==c&&95!==c)return!1;for(g=1;D<P;){if((C=n.src.charCodeAt(D++))!==c&&32!==C)return!1;C===c&&g++}return!(g<3||(o||(n.line=s+1,n.tokens.push({type:"hr",lines:[s,n.line],level:n.level})),0))},["paragraph","blockquote","list"]],["list",function(n,s,t,o){var c,g,C,D,P,j,W,re,me,_e,Fe,Re,Le,we,U,pt,ht,Ft,cn,kt,wn,Dt=!0;if((re=K6(n,s))>=0)Re=!0;else{if(!((re=X6(n,s))>=0))return!1;Re=!1}if(n.level>=n.options.maxNesting)return!1;if(Fe=n.src.charCodeAt(re-1),o)return!0;for(we=n.tokens.length,Re?(W=n.bMarks[s]+n.tShift[s],_e=Number(n.src.substr(W,re-W-1)),n.tokens.push({type:"ordered_list_open",order:_e,lines:pt=[s,0],level:n.level++})):n.tokens.push({type:"bullet_list_open",lines:pt=[s,0],level:n.level++}),c=s,U=!1,Ft=n.parser.ruler.getRules("list");c<t&&((me=(Le=n.skipSpaces(re))>=n.eMarks[c]?1:Le-re)>4&&(me=1),me<1&&(me=1),g=re-n.bMarks[c]+me,n.tokens.push({type:"list_item_open",lines:ht=[s,0],level:n.level++}),D=n.blkIndent,P=n.tight,C=n.tShift[s],j=n.parentType,n.tShift[s]=Le-n.bMarks[s],n.blkIndent=g,n.tight=!0,n.parentType="list",n.parser.tokenize(n,s,t,!0),(!n.tight||U)&&(Dt=!1),U=n.line-s>1&&n.isEmpty(n.line-1),n.blkIndent=D,n.tShift[s]=C,n.tight=P,n.parentType=j,n.tokens.push({type:"list_item_close",level:--n.level}),c=s=n.line,ht[1]=c,Le=n.bMarks[s],!(c>=t||n.isEmpty(c)||n.tShift[c]<n.blkIndent));){for(wn=!1,cn=0,kt=Ft.length;cn<kt;cn++)if(Ft[cn](n,c,t,!0)){wn=!0;break}if(wn)break;if(Re){if((re=K6(n,c))<0)break}else if((re=X6(n,c))<0)break;if(Fe!==n.src.charCodeAt(re-1))break}return n.tokens.push({type:Re?"ordered_list_close":"bullet_list_close",level:--n.level}),pt[1]=c,n.line=c,Dt&&function(n,s){var t,o,c=n.level+2;for(t=s+2,o=n.tokens.length-2;t<o;t++)n.tokens[t].level===c&&"paragraph_open"===n.tokens[t].type&&(n.tokens[t+2].tight=!0,n.tokens[t].tight=!0,t+=2)}(n,we),!0},["paragraph","blockquote"]],["footnote",function(n,s,t,o){var c,g,C,D,P,j=n.bMarks[s]+n.tShift[s],W=n.eMarks[s];if(j+4>W||91!==n.src.charCodeAt(j)||94!==n.src.charCodeAt(j+1)||n.level>=n.options.maxNesting)return!1;for(D=j+2;D<W;D++){if(32===n.src.charCodeAt(D))return!1;if(93===n.src.charCodeAt(D))break}return!(D===j+2||D+1>=W||58!==n.src.charCodeAt(++D)||(o||(D++,n.env.footnotes||(n.env.footnotes={}),n.env.footnotes.refs||(n.env.footnotes.refs={}),P=n.src.slice(j+2,D-2),n.env.footnotes.refs[":"+P]=-1,n.tokens.push({type:"footnote_reference_open",label:P,level:n.level++}),c=n.bMarks[s],g=n.tShift[s],C=n.parentType,n.tShift[s]=n.skipSpaces(D)-D,n.bMarks[s]=D,n.blkIndent+=4,n.parentType="footnote",n.tShift[s]<n.blkIndent&&(n.tShift[s]+=n.blkIndent,n.bMarks[s]-=n.blkIndent),n.parser.tokenize(n,s,t,!0),n.parentType=C,n.blkIndent-=4,n.tShift[s]=g,n.bMarks[s]=c,n.tokens.push({type:"footnote_reference_close",level:--n.level})),0))},["paragraph"]],["heading",function(n,s,t,o){var c,g,C,D=n.bMarks[s]+n.tShift[s],P=n.eMarks[s];if(D>=P||35!==(c=n.src.charCodeAt(D))||D>=P)return!1;for(g=1,c=n.src.charCodeAt(++D);35===c&&D<P&&g<=6;)g++,c=n.src.charCodeAt(++D);return!(g>6||D<P&&32!==c||(o||(P=n.skipCharsBack(P,32,D),(C=n.skipCharsBack(P,35,D))>D&&32===n.src.charCodeAt(C-1)&&(P=C),n.line=s+1,n.tokens.push({type:"heading_open",hLevel:g,lines:[s,n.line],level:n.level}),D<P&&n.tokens.push({type:"inline",content:n.src.slice(D,P).trim(),level:n.level+1,lines:[s,n.line],children:[]}),n.tokens.push({type:"heading_close",hLevel:g,level:n.level})),0))},["paragraph","blockquote"]],["lheading",function(n,s,t){var o,c,g,C=s+1;return!(C>=t||n.tShift[C]<n.blkIndent||n.tShift[C]-n.blkIndent>3||(c=n.bMarks[C]+n.tShift[C],g=n.eMarks[C],c>=g)||(o=n.src.charCodeAt(c),45!==o&&61!==o)||(c=n.skipChars(c,o),c=n.skipSpaces(c),c<g)||(c=n.bMarks[s]+n.tShift[s],n.line=C+1,n.tokens.push({type:"heading_open",hLevel:61===o?1:2,lines:[s,n.line],level:n.level}),n.tokens.push({type:"inline",content:n.src.slice(c,n.eMarks[s]).trim(),level:n.level+1,lines:[s,n.line-1],children:[]}),n.tokens.push({type:"heading_close",hLevel:61===o?1:2,level:n.level}),0))}],["htmlblock",function(n,s,t,o){var c,g,C,D=n.bMarks[s],P=n.eMarks[s],j=n.tShift[s];if(D+=j,!n.options.html||j>3||D+2>=P||60!==n.src.charCodeAt(D))return!1;if(33===(c=n.src.charCodeAt(D+1))||63===c){if(o)return!0}else{if(47!==c&&!function(n){var s=32|n;return s>=97&&s<=122}(c))return!1;if(47===c){if(!(g=n.src.slice(D,P).match(dL)))return!1}else if(!(g=n.src.slice(D,P).match(cL)))return!1;if(!0!==q6[g[1].toLowerCase()])return!1;if(o)return!0}for(C=s+1;C<n.lineMax&&!n.isEmpty(C);)C++;return n.line=C,n.tokens.push({type:"htmlblock",level:n.level,lines:[s,n.line],content:n.getLines(s,C,0,!0)}),!0},["paragraph","blockquote"]],["table",function(n,s,t,o){var c,g,C,D,P,j,W,re,oe,me,_e;if(s+2>t||n.tShift[P=s+1]<n.blkIndent||(C=n.bMarks[P]+n.tShift[P])>=n.eMarks[P]||124!==(c=n.src.charCodeAt(C))&&45!==c&&58!==c||(g=tR(n,s+1),!/^[-:| ]+$/.test(g))||(j=g.split("|"))<=2)return!1;for(re=[],D=0;D<j.length;D++){if(!(oe=j[D].trim())){if(0===D||D===j.length-1)continue;return!1}if(!/^:?-+:?$/.test(oe))return!1;58===oe.charCodeAt(oe.length-1)?re.push(58===oe.charCodeAt(0)?"center":"right"):58===oe.charCodeAt(0)?re.push("left"):re.push("")}if(-1===(g=tR(n,s).trim()).indexOf("|")||(j=g.replace(/^\||\|$/g,"").split("|"),re.length!==j.length))return!1;if(o)return!0;for(n.tokens.push({type:"table_open",lines:me=[s,0],level:n.level++}),n.tokens.push({type:"thead_open",lines:[s,s+1],level:n.level++}),n.tokens.push({type:"tr_open",lines:[s,s+1],level:n.level++}),D=0;D<j.length;D++)n.tokens.push({type:"th_open",align:re[D],lines:[s,s+1],level:n.level++}),n.tokens.push({type:"inline",content:j[D].trim(),lines:[s,s+1],level:n.level,children:[]}),n.tokens.push({type:"th_close",level:--n.level});for(n.tokens.push({type:"tr_close",level:--n.level}),n.tokens.push({type:"thead_close",level:--n.level}),n.tokens.push({type:"tbody_open",lines:_e=[s+2,0],level:n.level++}),P=s+2;P<t&&!(n.tShift[P]<n.blkIndent||(g=tR(n,P).trim(),-1===g.indexOf("|")));P++){for(j=g.replace(/^\||\|$/g,"").split("|"),n.tokens.push({type:"tr_open",level:n.level++}),D=0;D<j.length;D++)n.tokens.push({type:"td_open",align:re[D],level:n.level++}),W=j[D].substring(124===j[D].charCodeAt(0)?1:0,124===j[D].charCodeAt(j[D].length-1)?j[D].length-1:j[D].length).trim(),n.tokens.push({type:"inline",content:W,level:n.level,children:[]}),n.tokens.push({type:"td_close",level:--n.level});n.tokens.push({type:"tr_close",level:--n.level})}return n.tokens.push({type:"tbody_close",level:--n.level}),n.tokens.push({type:"table_close",level:--n.level}),me[1]=_e[1]=P,n.line=P,!0},["paragraph"]],["deflist",function(n,s,t,o){var c,g,C,D,P,j,W,re,oe,me,_e,Fe,Re,Le;if(o)return!(n.ddIndent<0)&&FA(n,s)>=0;if(n.isEmpty(W=s+1)&&++W>t||n.tShift[W]<n.blkIndent||(c=FA(n,W))<0||n.level>=n.options.maxNesting)return!1;j=n.tokens.length,n.tokens.push({type:"dl_open",lines:P=[s,0],level:n.level++}),C=s,g=W;e:for(;;){for(Le=!0,Re=!1,n.tokens.push({type:"dt_open",lines:[C,C],level:n.level++}),n.tokens.push({type:"inline",content:n.getLines(C,C+1,n.blkIndent,!1).trim(),level:n.level+1,lines:[C,C],children:[]}),n.tokens.push({type:"dt_close",level:--n.level});;){if(n.tokens.push({type:"dd_open",lines:D=[W,0],level:n.level++}),Fe=n.tight,oe=n.ddIndent,re=n.blkIndent,_e=n.tShift[g],me=n.parentType,n.blkIndent=n.ddIndent=n.tShift[g]+2,n.tShift[g]=c-n.bMarks[g],n.tight=!0,n.parentType="deflist",n.parser.tokenize(n,g,t,!0),(!n.tight||Re)&&(Le=!1),Re=n.line-g>1&&n.isEmpty(n.line-1),n.tShift[g]=_e,n.tight=Fe,n.parentType=me,n.blkIndent=re,n.ddIndent=oe,n.tokens.push({type:"dd_close",level:--n.level}),D[1]=W=n.line,W>=t||n.tShift[W]<n.blkIndent)break e;if((c=FA(n,W))<0)break;g=W}if(W>=t||n.isEmpty(C=W)||n.tShift[C]<n.blkIndent||(g=C+1)>=t||(n.isEmpty(g)&&g++,g>=t)||n.tShift[g]<n.blkIndent||(c=FA(n,g))<0)break}return n.tokens.push({type:"dl_close",level:--n.level}),P[1]=W,n.line=W,Le&&function(n,s){var t,o,c=n.level+2;for(t=s+2,o=n.tokens.length-2;t<o;t++)n.tokens[t].level===c&&"paragraph_open"===n.tokens[t].type&&(n.tokens[t+2].tight=!0,n.tokens[t].tight=!0,t+=2)}(n,j),!0},["paragraph"]],["paragraph",function(n,s){var t,o,c,g,C,P,D=s+1;if(D<(t=n.lineMax)&&!n.isEmpty(D))for(P=n.parser.ruler.getRules("paragraph");D<t&&!n.isEmpty(D);D++)if(!(n.tShift[D]-n.blkIndent>3)){for(c=!1,g=0,C=P.length;g<C;g++)if(P[g](n,D,t,!0)){c=!0;break}if(c)break}return o=n.getLines(s,D,n.blkIndent,!1).trim(),n.line=D,o.length&&(n.tokens.push({type:"paragraph_open",tight:!1,lines:[s,n.line],level:n.level}),n.tokens.push({type:"inline",content:o,level:n.level+1,lines:[s,n.line],children:[]}),n.tokens.push({type:"paragraph_close",tight:!1,level:n.level})),!0}]];function nR(){this.ruler=new P_;for(var n=0;n<kA.length;n++)this.ruler.push(kA[n][0],kA[n][1],{alt:(kA[n][2]||[]).slice()})}nR.prototype.tokenize=function(n,s,t){for(var P,o=this.ruler.getRules(""),c=o.length,g=s,C=!1;g<t&&(n.line=g=n.skipEmptyLines(g),!(g>=t||n.tShift[g]<n.blkIndent));){for(P=0;P<c&&!o[P](n,g,t,!1);P++);if(n.tight=!C,n.isEmpty(n.line-1)&&(C=!0),(g=n.line)<t&&n.isEmpty(g)){if(C=!0,++g<t&&"list"===n.parentType&&n.isEmpty(g))break;n.line=g}}};var vL=/[\n\t]/g,yL=/\r[\n\u0085]|[\u2424\u2028\u0085]/g,bL=/\u00a0/g;function EL(n){switch(n){case 10:case 92:case 96:case 42:case 95:case 94:case 91:case 93:case 33:case 38:case 60:case 62:case 123:case 125:case 36:case 37:case 64:case 126:case 43:case 61:case 58:return!0;default:return!1}}nR.prototype.parse=function(n,s,t,o){var c,g=0,C=0;if(!n)return[];(n=(n=n.replace(bL," ")).replace(yL,"\n")).indexOf("\t")>=0&&(n=n.replace(vL,function(D,P){var j;return 10===n.charCodeAt(P)?(g=P+1,C=0,D):(j=" ".slice((P-g-C)%4),C=P-g+1,j)})),c=new M0(n,this,s,t,o),this.tokenize(c,c.line,c.lineMax)};for(var rR=[],eP=0;eP<256;eP++)rR.push(0);function tP(n){return n>=48&&n<=57||n>=65&&n<=90||n>=97&&n<=122}function nP(n,s){var o,c,g,t=s,C=!0,D=!0,P=n.posMax,j=n.src.charCodeAt(s);for(o=s>0?n.src.charCodeAt(s-1):-1;t<P&&n.src.charCodeAt(t)===j;)t++;return t>=P&&(C=!1),(g=t-s)>=4?C=D=!1:((32===(c=t<P?n.src.charCodeAt(t):-1)||10===c)&&(C=!1),(32===o||10===o)&&(D=!1),95===j&&(tP(o)&&(C=!1),tP(c)&&(D=!1))),{can_open:C,can_close:D,delims:g}}"\\!\"#$%&'()*+,./:;<=>?@[]^_`{|}~-".split("").forEach(function(n){rR[n.charCodeAt(0)]=1});var DL=/\\([ \\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g,NL=/\\([ \\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g,kL=["coap","doi","javascript","aaa","aaas","about","acap","cap","cid","crid","data","dav","dict","dns","file","ftp","geo","go","gopher","h323","http","https","iax","icap","im","imap","info","ipp","iris","iris.beep","iris.xpc","iris.xpcs","iris.lwz","ldap","mailto","mid","msrp","msrps","mtqp","mupdate","news","nfs","ni","nih","nntp","opaquelocktoken","pop","pres","rtsp","service","session","shttp","sieve","sip","sips","sms","snmp","soap.beep","soap.beeps","tag","tel","telnet","tftp","thismessage","tn3270","tip","tv","urn","vemmi","ws","wss","xcon","xcon-userid","xmlrpc.beep","xmlrpc.beeps","xmpp","z39.50r","z39.50s","adiumxtra","afp","afs","aim","apt","attachment","aw","beshare","bitcoin","bolo","callto","chrome","chrome-extension","com-eventbrite-attendee","content","cvs","dlna-playsingle","dlna-playcontainer","dtn","dvb","ed2k","facetime","feed","finger","fish","gg","git","gizmoproject","gtalk","hcp","icon","ipn","irc","irc6","ircs","itms","jar","jms","keyparc","lastfm","ldaps","magnet","maps","market","message","mms","ms-help","msnim","mumble","mvn","notes","oid","palm","paparazzi","platform","proxy","psyc","query","res","resource","rmi","rsync","rtmp","secondlife","sftp","sgn","skype","smb","soldat","spotify","ssh","steam","svn","teamspeak","things","udp","unreal","ut2004","ventrilo","view-source","webcal","wtai","wyciwyg","xfire","xri","ymsgr"],$L=/^<([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>/,HL=/^<([a-zA-Z.\-]{1,25}):([^<>\x00-\x20]*)>/;function $A(n,s){return n=n.source,s=s||"",function t(o,c){return o?(n=n.replace(o,c=c.source||c),t):new RegExp(n,s)}}var GL=$A(/(?:unquoted|single_quoted|double_quoted)/)("unquoted",/[^"'=<>`\x00-\x20]+/)("single_quoted",/'[^']*'/)("double_quoted",/"[^"]*"/)(),VL=$A(/(?:\s+attr_name(?:\s*=\s*attr_value)?)/)("attr_name",/[a-zA-Z_:][a-zA-Z0-9:._-]*/)("attr_value",GL)(),zL=$A(/<[A-Za-z][A-Za-z0-9]*attribute*\s*\/?>/)("attribute",VL)(),qL=$A(/^(?:open_tag|close_tag|comment|processing|declaration|cdata)/)("open_tag",zL)("close_tag",/<\/[A-Za-z][A-Za-z0-9]*\s*>/)("comment",/<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->/)("processing",/<[?].*?[?]>/)("declaration",/<![A-Z]+\s+[^>]*>/)("cdata",/<!\[CDATA\[[\s\S]*?\]\]>/)(),nF=/^&#((?:x[a-f0-9]{1,8}|[0-9]{1,8}));/i,rF=/^&([a-z][a-z0-9]{1,31});/i,iR=[["text",function(n,s){for(var t=n.pos;t<n.posMax&&!EL(n.src.charCodeAt(t));)t++;return t!==n.pos&&(s||(n.pending+=n.src.slice(n.pos,t)),n.pos=t,!0)}],["newline",function(n,s){var t,o,c=n.pos;if(10!==n.src.charCodeAt(c))return!1;if(t=n.pending.length-1,o=n.posMax,!s)if(t>=0&&32===n.pending.charCodeAt(t))if(t>=1&&32===n.pending.charCodeAt(t-1)){for(var g=t-2;g>=0;g--)if(32!==n.pending.charCodeAt(g)){n.pending=n.pending.substring(0,g+1);break}n.push({type:"hardbreak",level:n.level})}else n.pending=n.pending.slice(0,-1),n.push({type:"softbreak",level:n.level});else n.push({type:"softbreak",level:n.level});for(c++;c<o&&32===n.src.charCodeAt(c);)c++;return n.pos=c,!0}],["escape",function(n,s){var t,o=n.pos,c=n.posMax;if(92!==n.src.charCodeAt(o))return!1;if(++o<c){if((t=n.src.charCodeAt(o))<256&&0!==rR[t])return s||(n.pending+=n.src[o]),n.pos+=2,!0;if(10===t){for(s||n.push({type:"hardbreak",level:n.level}),o++;o<c&&32===n.src.charCodeAt(o);)o++;return n.pos=o,!0}}return s||(n.pending+="\\"),n.pos++,!0}],["backticks",function(n,s){var t,o,c,g,C,D=n.pos;if(96!==n.src.charCodeAt(D))return!1;for(t=D,D++,o=n.posMax;D<o&&96===n.src.charCodeAt(D);)D++;for(c=n.src.slice(t,D),g=C=D;-1!==(g=n.src.indexOf("`",C));){for(C=g+1;C<o&&96===n.src.charCodeAt(C);)C++;if(C-g===c.length)return s||n.push({type:"code",content:n.src.slice(D,g).replace(/[ \n]+/g," ").trim(),block:!1,level:n.level}),n.pos=C,!0}return s||(n.pending+=c),n.pos+=c.length,!0}],["del",function(n,s){var t,o,c,D,P,g=n.posMax,C=n.pos;if(126!==n.src.charCodeAt(C)||s||C+4>=g||126!==n.src.charCodeAt(C+1)||n.level>=n.options.maxNesting||(D=C>0?n.src.charCodeAt(C-1):-1,P=n.src.charCodeAt(C+2),126===D)||126===P||32===P||10===P)return!1;for(o=C+2;o<g&&126===n.src.charCodeAt(o);)o++;if(o>C+3)return n.pos+=o-C,s||(n.pending+=n.src.slice(C,o)),!0;for(n.pos=C+2,c=1;n.pos+1<g;){if(126===n.src.charCodeAt(n.pos)&&126===n.src.charCodeAt(n.pos+1)&&(D=n.src.charCodeAt(n.pos-1),126!==(P=n.pos+2<g?n.src.charCodeAt(n.pos+2):-1)&&126!==D&&(32!==D&&10!==D?c--:32!==P&&10!==P&&c++,c<=0))){t=!0;break}n.parser.skipToken(n)}return t?(n.posMax=n.pos,n.pos=C+2,s||(n.push({type:"del_open",level:n.level++}),n.parser.tokenize(n),n.push({type:"del_close",level:--n.level})),n.pos=n.posMax+2,n.posMax=g,!0):(n.pos=C,!1)}],["ins",function(n,s){var t,o,c,D,P,g=n.posMax,C=n.pos;if(43!==n.src.charCodeAt(C)||s||C+4>=g||43!==n.src.charCodeAt(C+1)||n.level>=n.options.maxNesting||(D=C>0?n.src.charCodeAt(C-1):-1,P=n.src.charCodeAt(C+2),43===D)||43===P||32===P||10===P)return!1;for(o=C+2;o<g&&43===n.src.charCodeAt(o);)o++;if(o!==C+2)return n.pos+=o-C,s||(n.pending+=n.src.slice(C,o)),!0;for(n.pos=C+2,c=1;n.pos+1<g;){if(43===n.src.charCodeAt(n.pos)&&43===n.src.charCodeAt(n.pos+1)&&(D=n.src.charCodeAt(n.pos-1),43!==(P=n.pos+2<g?n.src.charCodeAt(n.pos+2):-1)&&43!==D&&(32!==D&&10!==D?c--:32!==P&&10!==P&&c++,c<=0))){t=!0;break}n.parser.skipToken(n)}return t?(n.posMax=n.pos,n.pos=C+2,s||(n.push({type:"ins_open",level:n.level++}),n.parser.tokenize(n),n.push({type:"ins_close",level:--n.level})),n.pos=n.posMax+2,n.posMax=g,!0):(n.pos=C,!1)}],["mark",function(n,s){var t,o,c,D,P,g=n.posMax,C=n.pos;if(61!==n.src.charCodeAt(C)||s||C+4>=g||61!==n.src.charCodeAt(C+1)||n.level>=n.options.maxNesting||(D=C>0?n.src.charCodeAt(C-1):-1,P=n.src.charCodeAt(C+2),61===D)||61===P||32===P||10===P)return!1;for(o=C+2;o<g&&61===n.src.charCodeAt(o);)o++;if(o!==C+2)return n.pos+=o-C,s||(n.pending+=n.src.slice(C,o)),!0;for(n.pos=C+2,c=1;n.pos+1<g;){if(61===n.src.charCodeAt(n.pos)&&61===n.src.charCodeAt(n.pos+1)&&(D=n.src.charCodeAt(n.pos-1),61!==(P=n.pos+2<g?n.src.charCodeAt(n.pos+2):-1)&&61!==D&&(32!==D&&10!==D?c--:32!==P&&10!==P&&c++,c<=0))){t=!0;break}n.parser.skipToken(n)}return t?(n.posMax=n.pos,n.pos=C+2,s||(n.push({type:"mark_open",level:n.level++}),n.parser.tokenize(n),n.push({type:"mark_close",level:--n.level})),n.pos=n.posMax+2,n.posMax=g,!0):(n.pos=C,!1)}],["emphasis",function(n,s){var t,o,c,g,C,D,P,j=n.posMax,W=n.pos,re=n.src.charCodeAt(W);if(95!==re&&42!==re||s)return!1;if(t=(P=nP(n,W)).delims,!P.can_open)return n.pos+=t,s||(n.pending+=n.src.slice(W,n.pos)),!0;if(n.level>=n.options.maxNesting)return!1;for(n.pos=W+t,D=[t];n.pos<j;)if(n.src.charCodeAt(n.pos)!==re)n.parser.skipToken(n);else{if(o=(P=nP(n,n.pos)).delims,P.can_close){for(g=D.pop(),C=o;g!==C;){if(C<g){D.push(g-C);break}if(C-=g,0===D.length)break;n.pos+=g,g=D.pop()}if(0===D.length){t=g,c=!0;break}n.pos+=o;continue}P.can_open&&D.push(o),n.pos+=o}return c?(n.posMax=n.pos,n.pos=W+t,s||((2===t||3===t)&&n.push({type:"strong_open",level:n.level++}),(1===t||3===t)&&n.push({type:"em_open",level:n.level++}),n.parser.tokenize(n),(1===t||3===t)&&n.push({type:"em_close",level:--n.level}),(2===t||3===t)&&n.push({type:"strong_close",level:--n.level})),n.pos=n.posMax+t,n.posMax=j,!0):(n.pos=W,!1)}],["sub",function(n,s){var t,o,c=n.posMax,g=n.pos;if(126!==n.src.charCodeAt(g)||s||g+2>=c||n.level>=n.options.maxNesting)return!1;for(n.pos=g+1;n.pos<c;){if(126===n.src.charCodeAt(n.pos)){t=!0;break}n.parser.skipToken(n)}return!t||g+1===n.pos||(o=n.src.slice(g+1,n.pos)).match(/(^|[^\\])(\\\\)*\s/)?(n.pos=g,!1):(n.posMax=n.pos,n.pos=g+1,s||n.push({type:"sub",level:n.level,content:o.replace(DL,"$1")}),n.pos=n.posMax+1,n.posMax=c,!0)}],["sup",function(n,s){var t,o,c=n.posMax,g=n.pos;if(94!==n.src.charCodeAt(g)||s||g+2>=c||n.level>=n.options.maxNesting)return!1;for(n.pos=g+1;n.pos<c;){if(94===n.src.charCodeAt(n.pos)){t=!0;break}n.parser.skipToken(n)}return!t||g+1===n.pos||(o=n.src.slice(g+1,n.pos)).match(/(^|[^\\])(\\\\)*\s/)?(n.pos=g,!1):(n.posMax=n.pos,n.pos=g+1,s||n.push({type:"sup",level:n.level,content:o.replace(NL,"$1")}),n.pos=n.posMax+1,n.posMax=c,!0)}],["links",function(n,s){var t,o,c,g,C,D,P,j,W=!1,re=n.pos,oe=n.posMax,me=n.pos,_e=n.src.charCodeAt(me);if(33===_e&&(W=!0,_e=n.src.charCodeAt(++me)),91!==_e||n.level>=n.options.maxNesting||(t=me+1,(o=lS(n,me))<0))return!1;if((D=o+1)<oe&&40===n.src.charCodeAt(D)){for(D++;D<oe&&(32===(j=n.src.charCodeAt(D))||10===j);D++);if(D>=oe)return!1;for(me=D,Z6(n,D)?(g=n.linkContent,D=n.pos):g="",me=D;D<oe&&(32===(j=n.src.charCodeAt(D))||10===j);D++);if(D<oe&&me!==D&&j6(n,D))for(C=n.linkContent,D=n.pos;D<oe&&(32===(j=n.src.charCodeAt(D))||10===j);D++);else C="";if(D>=oe||41!==n.src.charCodeAt(D))return n.pos=re,!1;D++}else{if(n.linkLevel>0)return!1;for(;D<oe&&(32===(j=n.src.charCodeAt(D))||10===j);D++);if(D<oe&&91===n.src.charCodeAt(D)&&(me=D+1,(D=lS(n,D))>=0?c=n.src.slice(me,D++):D=me-1),c||(void 0===c&&(D=o+1),c=n.src.slice(t,o)),!(P=n.env.references[G6(c)]))return n.pos=re,!1;g=P.href,C=P.title}return s||(n.pos=t,n.posMax=o,W?n.push({type:"image",src:g,title:C,alt:n.src.substr(t,o-t),level:n.level}):(n.push({type:"link_open",href:g,title:C,level:n.level++}),n.linkLevel++,n.parser.tokenize(n),n.linkLevel--,n.push({type:"link_close",level:--n.level}))),n.pos=D,n.posMax=oe,!0}],["footnote_inline",function(n,s){var t,o,c,g,C=n.posMax,D=n.pos;return!(D+2>=C||94!==n.src.charCodeAt(D)||91!==n.src.charCodeAt(D+1)||n.level>=n.options.maxNesting||(t=D+2,o=lS(n,D+1),o<0)||(s||(n.env.footnotes||(n.env.footnotes={}),n.env.footnotes.list||(n.env.footnotes.list=[]),c=n.env.footnotes.list.length,n.pos=t,n.posMax=o,n.push({type:"footnote_ref",id:c,level:n.level}),n.linkLevel++,g=n.tokens.length,n.parser.tokenize(n),n.env.footnotes.list[c]={tokens:n.tokens.splice(g)},n.linkLevel--),n.pos=o+1,n.posMax=C,0))}],["footnote_ref",function(n,s){var t,o,c,g,C=n.posMax,D=n.pos;if(D+3>C||!n.env.footnotes||!n.env.footnotes.refs||91!==n.src.charCodeAt(D)||94!==n.src.charCodeAt(D+1)||n.level>=n.options.maxNesting)return!1;for(o=D+2;o<C;o++){if(32===n.src.charCodeAt(o)||10===n.src.charCodeAt(o))return!1;if(93===n.src.charCodeAt(o))break}return!(o===D+2||o>=C||(o++,t=n.src.slice(D+2,o-1),void 0===n.env.footnotes.refs[":"+t])||(s||(n.env.footnotes.list||(n.env.footnotes.list=[]),n.env.footnotes.refs[":"+t]<0?(n.env.footnotes.list[c=n.env.footnotes.list.length]={label:t,count:0},n.env.footnotes.refs[":"+t]=c):c=n.env.footnotes.refs[":"+t],g=n.env.footnotes.list[c].count,n.env.footnotes.list[c].count++,n.push({type:"footnote_ref",id:c,subId:g,level:n.level})),n.pos=o,n.posMax=C,0))}],["autolink",function(n,s){var t,o,c,g,C,D=n.pos;return!(60!==n.src.charCodeAt(D)||(t=n.src.slice(D),t.indexOf(">")<0)||((o=t.match(HL))?kL.indexOf(o[1].toLowerCase())<0||(g=o[0].slice(1,-1),C=K3(g),!n.parser.validateLink(g))||(s||(n.push({type:"link_open",href:C,level:n.level}),n.push({type:"text",content:g,level:n.level+1}),n.push({type:"link_close",level:n.level})),n.pos+=o[0].length,0):!(c=t.match($L))||(C=K3("mailto:"+(g=c[0].slice(1,-1))),!n.parser.validateLink(C)||(s||(n.push({type:"link_open",href:C,level:n.level}),n.push({type:"text",content:g,level:n.level+1}),n.push({type:"link_close",level:n.level})),n.pos+=c[0].length,0))))}],["htmltag",function(n,s){var t,o,c,g=n.pos;return!(!n.options.html||(c=n.posMax,60!==n.src.charCodeAt(g)||g+2>=c)||(t=n.src.charCodeAt(g+1),33!==t&&63!==t&&47!==t&&!function(n){var s=32|n;return s>=97&&s<=122}(t))||(o=n.src.slice(g).match(qL),!o)||(s||n.push({type:"htmltag",content:n.src.slice(g,g+o[0].length),level:n.level}),n.pos+=o[0].length,0))}],["entity",function(n,s){var o,c,g=n.pos,C=n.posMax;if(38!==n.src.charCodeAt(g))return!1;if(g+1<C)if(35===n.src.charCodeAt(g+1)){if(c=n.src.slice(g).match(nF))return s||(o="x"===c[1][0].toLowerCase()?parseInt(c[1].slice(1),16):parseInt(c[1],10),n.pending+=Q3(o)?LA(o):LA(65533)),n.pos+=c[0].length,!0}else if(c=n.src.slice(g).match(rF)){var D=U6(c[1]);if(c[1]!==D)return s||(n.pending+=D),n.pos+=c[0].length,!0}return s||(n.pending+="&"),n.pos++,!0}]];function HA(){this.ruler=new P_;for(var n=0;n<iR.length;n++)this.ruler.push(iR[n][0],iR[n][1]);this.validateLink=oF}function oF(n){var t=n.trim().toLowerCase();return!(-1!==(t=qv(t)).indexOf(":")&&-1!==["vbscript","javascript","file","data"].indexOf(t.split(":")[0]))}HA.prototype.skipToken=function(n){var c,g,s=this.ruler.getRules(""),t=s.length,o=n.pos;if((g=n.cacheGet(o))>0)n.pos=g;else{for(c=0;c<t;c++)if(s[c](n,!0))return void n.cacheSet(o,n.pos);n.pos++,n.cacheSet(o,n.pos)}},HA.prototype.tokenize=function(n){for(var c,g,s=this.ruler.getRules(""),t=s.length,o=n.posMax;n.pos<o;){for(g=0;g<t&&!(c=s[g](n,!1));g++);if(c){if(n.pos>=o)break}else n.pending+=n.src[n.pos++]}n.pending&&n.pushPending()},HA.prototype.parse=function(n,s,t,o){var c=new C0(n,this,s,t,o);this.tokenize(c)};var uF={default:{options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkTarget:"",typographer:!1,quotes:"\u201c\u201d\u2018\u2019",highlight:null,maxNesting:20},components:{core:{rules:["block","inline","references","replacements","smartquotes","references","abbr2","footnote_tail"]},block:{rules:["blockquote","code","fences","footnote","heading","hr","htmlblock","lheading","list","paragraph","table"]},inline:{rules:["autolink","backticks","del","emphasis","entity","escape","footnote_ref","htmltag","links","newline","text"]}}},full:{options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkTarget:"",typographer:!1,quotes:"\u201c\u201d\u2018\u2019",highlight:null,maxNesting:20},components:{core:{},block:{},inline:{}}},commonmark:{options:{html:!0,xhtmlOut:!0,breaks:!1,langPrefix:"language-",linkTarget:"",typographer:!1,quotes:"\u201c\u201d\u2018\u2019",highlight:null,maxNesting:20},components:{core:{rules:["block","inline","references","abbr2"]},block:{rules:["blockquote","code","fences","heading","hr","htmlblock","lheading","list","paragraph"]},inline:{rules:["autolink","backticks","emphasis","entity","escape","htmltag","links","newline","text"]}}}};function rP(n,s,t){this.src=s,this.env=t,this.options=n.options,this.tokens=[],this.inlineMode=!1,this.inline=n.inline,this.block=n.block,this.renderer=n.renderer,this.typographer=n.typographer}function e1(n,s){"string"!=typeof n&&(s=n,n="default"),s&&null!=s.linkify&&console.warn("linkify option is removed. Use linkify plugin instead:\n\nimport Remarkable from 'remarkable';\nimport linkify from 'remarkable/linkify';\nnew Remarkable().use(linkify)\n"),this.inline=new HA,this.block=new nR,this.core=new Q6,this.renderer=new X3,this.ruler=new P_,this.options={},this.configure(uF[n]),this.set(s||{})}e1.prototype.set=function(n){J3(this.options,n)},e1.prototype.configure=function(n){var s=this;if(!n)throw new Error("Wrong `remarkable` preset, check name/content");n.options&&s.set(n.options),n.components&&Object.keys(n.components).forEach(function(t){n.components[t].rules&&s[t].ruler.enable(n.components[t].rules,!0)})},e1.prototype.use=function(n,s){return n(this,s),this},e1.prototype.parse=function(n,s){var t=new rP(this,n,s);return this.core.process(t),t.tokens},e1.prototype.render=function(n,s){return this.renderer.render(this.parse(n,s=s||{}),this.options,s)},e1.prototype.parseInline=function(n,s){var t=new rP(this,n,s);return t.inlineMode=!0,this.core.process(t),t.tokens},e1.prototype.renderInline=function(n,s){return this.renderer.render(this.parseInline(n,s=s||{}),this.options,s)};var UA="NOT_FOUND",fF=function(s,t){return s===t};function hF(n,s){var t="object"==typeof s?s:{equalityCheck:s},o=t.equalityCheck,g=t.maxSize,C=void 0===g?1:g,D=t.resultEqualityCheck,P=function(n){return function(t,o){if(null===t||null===o||t.length!==o.length)return!1;for(var c=t.length,g=0;g<c;g++)if(!n(t[g],o[g]))return!1;return!0}}(void 0===o?fF:o),j=1===C?function(n){var s;return{get:function(o){return s&&n(s.key,o)?s.value:UA},put:function(o,c){s={key:o,value:c}},getEntries:function(){return s?[s]:[]},clear:function(){s=void 0}}}(P):function(n,s){var t=[];function o(D){var P=t.findIndex(function(W){return s(D,W.key)});if(P>-1){var j=t[P];return P>0&&(t.splice(P,1),t.unshift(j)),j.value}return UA}return{get:o,put:function(D,P){o(D)===UA&&(t.unshift({key:D,value:P}),t.length>n&&t.pop())},getEntries:function(){return t},clear:function(){t=[]}}}(C,P);function W(){var re=j.get(arguments);if(re===UA){if(re=n.apply(null,arguments),D){var oe=j.getEntries(),me=oe.find(function(_e){return D(_e.value,re)});me&&(re=me.value)}j.put(arguments,re)}return re}return W.clearCache=function(){return j.clear()},W}function _F(n){var s=Array.isArray(n[0])?n[0]:n;if(!s.every(function(o){return"function"==typeof o})){var t=s.map(function(o){return"function"==typeof o?"function "+(o.name||"unnamed")+"()":typeof o}).join(", ");throw new Error("createSelector expects all input-selectors to be functions, but received the following types: ["+t+"]")}return s}function gF(n){for(var s=arguments.length,t=new Array(s>1?s-1:0),o=1;o<s;o++)t[o-1]=arguments[o];var c=function(){for(var C=arguments.length,D=new Array(C),P=0;P<C;P++)D[P]=arguments[P];var W,j=0,re={memoizeOptions:void 0},oe=D.pop();if("object"==typeof oe&&(re=oe,oe=D.pop()),"function"!=typeof oe)throw new Error("createSelector expects an output function after the inputs, but received: ["+typeof oe+"]");var me=re,_e=me.memoizeOptions,Fe=void 0===_e?t:_e,Re=Array.isArray(Fe)?Fe:[Fe],Le=_F(D),we=n.apply(void 0,[function(){return j++,oe.apply(null,arguments)}].concat(Re)),U=n(function(){for(var ht=[],Dt=Le.length,Ft=0;Ft<Dt;Ft++)ht.push(Le[Ft].apply(null,arguments));return W=we.apply(null,ht)});return Object.assign(U,{resultFunc:oe,memoizedResultFunc:we,dependencies:Le,lastResult:function(){return W},recomputations:function(){return j},resetRecomputations:function(){return j=0}}),U};return c}var iP=gF(hF),mF=i(4043),vF=i(2135),yF=i.n(vF),bF=i(95327),EF=i.n(bF),TF=i(31208),SF=i(3912),CF=i.n(SF),MF=i(41233),AF=i.n(MF),OF=i(74299),wF=i.n(OF),xF=i(32322),DF=i.n(xF),RF=i(58734),NF=i.n(RF),PF=i(69883),IF=i.n(PF),LF=i(41205),FF=i.n(LF),kF={3978:(n,s,t)=>{n.exports=t(1910)},1543:(n,s,t)=>{t.d(s,{Z:()=>Le});var o=t(863),c=t(7344),g=t(8656),C=t(6340),D=t(9972),P=t(5416),j=t(775),W=t(5171),re=t(8818),oe=t(2565),me=t(810);const _e=(t.d(U={},{default:()=>U1}),U);var U,Fe=t(9569),Re=t(5053),Le=function(we){(0,D.default)(pt,we);var U=(0,P.default)(pt);function pt(){var ht,Dt;(0,c.default)(this,pt);for(var Ft=arguments.length,cn=new Array(Ft),kt=0;kt<Ft;kt++)cn[kt]=arguments[kt];return Dt=U.call.apply(U,(0,W.default)(ht=[this]).call(ht,cn)),(0,j.default)((0,C.default)(Dt),"getModelName",function(wn){return-1!==(0,re.default)(wn).call(wn,"#/definitions/")?wn.replace(/^.*#\/definitions\//,""):-1!==(0,re.default)(wn).call(wn,"#/components/schemas/")?wn.replace(/^.*#\/components\/schemas\//,""):void 0}),(0,j.default)((0,C.default)(Dt),"getRefSchema",function(wn){return Dt.props.specSelectors.findDefinition(wn)}),Dt}return(0,g.default)(pt,[{key:"render",value:function(){var ht=this.props,Dt=ht.getComponent,Ft=ht.getConfigs,cn=ht.specSelectors,kt=ht.schema,wn=ht.required,Tn=ht.name,Hr=ht.isRef,sr=ht.specPath,Nr=ht.displayName,xr=ht.includeReadOnly,fn=ht.includeWriteOnly,Rn=Dt("ObjectModel"),kn=Dt("ArrayModel"),Wn=Dt("PrimitiveModel"),bn="object",jr=kt&&kt.get("$$ref");if(!Tn&&jr&&(Tn=this.getModelName(jr)),!kt&&jr&&(kt=this.getRefSchema(Tn)),!kt)return me.default.createElement("span",{className:"model model-title"},me.default.createElement("span",{className:"model-title__text"},Nr||Tn),me.default.createElement("img",{src:t(2517),height:"20px",width:"20px"}));var ji=cn.isOAS3()&&kt.get("deprecated");switch(Hr=void 0!==Hr?Hr:!!jr,bn=kt&&kt.get("type")||bn){case"object":return me.default.createElement(Rn,(0,o.default)({className:"object"},this.props,{specPath:sr,getConfigs:Ft,schema:kt,name:Tn,deprecated:ji,isRef:Hr,includeReadOnly:xr,includeWriteOnly:fn}));case"array":return me.default.createElement(kn,(0,o.default)({className:"array"},this.props,{getConfigs:Ft,schema:kt,name:Tn,deprecated:ji,required:wn,includeReadOnly:xr,includeWriteOnly:fn}));default:return me.default.createElement(Wn,(0,o.default)({},this.props,{getComponent:Dt,getConfigs:Ft,schema:kt,name:Tn,deprecated:ji,required:wn}))}}}]),pt}(_e.default);(0,j.default)(Le,"propTypes",{schema:(0,oe.default)(Fe.default).isRequired,getComponent:Re.default.func.isRequired,getConfigs:Re.default.func.isRequired,specSelectors:Re.default.object.isRequired,name:Re.default.string,displayName:Re.default.string,isRef:Re.default.bool,required:Re.default.bool,expandDepth:Re.default.number,depth:Re.default.number,specPath:Fe.default.list.isRequired,includeReadOnly:Re.default.bool,includeWriteOnly:Re.default.bool})},5623:(n,s,t)=>{t.d(s,{Z:()=>Re});var o=t(1581),c=t(7344),g=t(8656),C=t(6340),D=t(9972),P=t(5416),j=t(775),W=t(2740),re=t(5171),oe=t(810),me=t(8900),_e=(t(5053),t(6298)),Fe=t(7504),Re=function(we){(0,D.default)(pt,we);var U=(0,P.default)(pt);function pt(ht,Dt){var Ft;(0,c.default)(this,pt),Ft=U.call(this,ht,Dt),(0,j.default)((0,C.default)(Ft),"getDefinitionUrl",function(){return new me.default(Ft.props.specSelectors.url(),Fe.Z.location).toString()});var cn=(0,ht.getConfigs)().validatorUrl;return Ft.state={url:Ft.getDefinitionUrl(),validatorUrl:void 0===cn?"https://validator.swagger.io/validator":cn},Ft}return(0,g.default)(pt,[{key:"UNSAFE_componentWillReceiveProps",value:function(ht){var Dt=(0,ht.getConfigs)().validatorUrl;this.setState({url:this.getDefinitionUrl(),validatorUrl:void 0===Dt?"https://validator.swagger.io/validator":Dt})}},{key:"render",value:function(){var ht,Dt,Ft=(0,this.props.getConfigs)().spec,cn=(0,_e.Nm)(this.state.validatorUrl);return"object"===(0,o.default)(Ft)&&(0,W.default)(Ft).length?null:this.state.url&&(0,_e.hW)(this.state.validatorUrl)&&(0,_e.hW)(this.state.url)?oe.default.createElement("span",{className:"float-right"},oe.default.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:(0,re.default)(ht="".concat(cn,"/debug?url=")).call(ht,encodeURIComponent(this.state.url))},oe.default.createElement(Le,{src:(0,re.default)(Dt="".concat(cn,"?url=")).call(Dt,encodeURIComponent(this.state.url)),alt:"Online validator badge"}))):null}}]),pt}(oe.default.Component),Le=function(we){(0,D.default)(pt,we);var U=(0,P.default)(pt);function pt(ht){var Dt;return(0,c.default)(this,pt),(Dt=U.call(this,ht)).state={loaded:!1,error:!1},Dt}return(0,g.default)(pt,[{key:"componentDidMount",value:function(){var ht=this,Dt=new Image;Dt.onload=function(){ht.setState({loaded:!0})},Dt.onerror=function(){ht.setState({error:!0})},Dt.src=this.props.src}},{key:"UNSAFE_componentWillReceiveProps",value:function(ht){var Dt=this;if(ht.src!==this.props.src){var Ft=new Image;Ft.onload=function(){Dt.setState({loaded:!0})},Ft.onerror=function(){Dt.setState({error:!0})},Ft.src=ht.src}}},{key:"render",value:function(){return this.state.error?oe.default.createElement("img",{alt:"Error"}):this.state.loaded?oe.default.createElement("img",{src:this.props.src,alt:this.props.alt}):null}}]),pt}(oe.default.Component)},5466:(n,s,t)=>{t.d(s,{Z:()=>j,s:()=>W});var o=t(810),c=(t(5053),t(3952));const g=(t.d(oe={},{linkify:()=>BM}),oe),C=(re=>{var oe={};return t.d(oe,re),oe})({default:()=>Yx()});var oe,D=t(8096);function P(re){var oe=re.source,me=re.className,_e=void 0===me?"":me,Fe=re.getConfigs;if("string"!=typeof oe)return null;var Re=new c.Remarkable({html:!0,typographer:!0,breaks:!0,linkTarget:"_blank"}).use(g.linkify);Re.core.ruler.disable(["replacements","smartquotes"]);var Le=Fe().useUnsafeMarkdown,we=Re.render(oe),U=W(we,{useUnsafeMarkdown:Le});return oe&&we&&U?o.default.createElement("div",{className:(0,D.default)(_e,"markdown"),dangerouslySetInnerHTML:{__html:U}}):null}C.default.addHook&&C.default.addHook("beforeSanitizeElements",function(re){return re.href&&re.setAttribute("rel","noopener noreferrer"),re}),P.defaultProps={getConfigs:function(){return{useUnsafeMarkdown:!1}}};const j=P;function W(re){var oe=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},me=oe.useUnsafeMarkdown,_e=void 0!==me&&me,Fe=_e,Re=_e?[]:["style","class"];return _e&&!W.hasWarnedAboutDeprecation&&(console.warn("useUnsafeMarkdown display configuration parameter is deprecated since >3.26.0 and will be removed in v4.0.0."),W.hasWarnedAboutDeprecation=!0),C.default.sanitize(re,{ADD_ATTR:["target"],FORBID_TAGS:["style","form"],ALLOW_DATA_ATTR:Fe,FORBID_ATTR:Re})}W.hasWarnedAboutDeprecation=!1},5308:(n,s,t)=>{t.r(s),t.d(s,{default:()=>W});var o,c=t(29),g=t(5487),C=t(6298),D=t(8102),P=t(5102),j={};const W=j;(0,c.default)(o=(0,g.default)(P).call(P)).call(o,function(re){if("./index.js"!==re){var oe=P(re);j[(0,C.Zl)(re)]=oe.default?oe.default:oe}}),j.SafeRender=D.default},5812:(n,s,t)=>{t.r(s),t.d(s,{SHOW_AUTH_POPUP:()=>j,AUTHORIZE:()=>W,LOGOUT:()=>re,PRE_AUTHORIZE_OAUTH2:()=>oe,AUTHORIZE_OAUTH2:()=>me,VALIDATE:()=>_e,CONFIGURE_AUTH:()=>Fe,RESTORE_AUTHORIZATION:()=>Re,showDefinitions:()=>Le,authorize:()=>we,authorizeWithPersistOption:()=>U,logout:()=>pt,logoutWithPersistOption:()=>ht,preAuthorizeImplicit:()=>Dt,authorizeOauth2:()=>Ft,authorizeOauth2WithPersistOption:()=>cn,authorizePassword:()=>kt,authorizeApplication:()=>wn,authorizeAccessCodeWithFormParams:()=>Tn,authorizeAccessCodeWithBasicAuthentication:()=>Hr,authorizeRequest:()=>sr,configureAuth:()=>Nr,restoreAuthorization:()=>xr,persistAuthorizationIfNeeded:()=>fn,authPopup:()=>Rn});var o=t(1581),c=t(313),g=t(7512),C=t(8900),D=t(7504),P=t(6298),j="show_popup",W="authorize",re="logout",oe="pre_authorize_oauth2",me="authorize_oauth2",_e="validate",Fe="configure_auth",Re="restore_authorization";function Le(kn){return{type:j,payload:kn}}function we(kn){return{type:W,payload:kn}}var U=function(kn){return function(Wn){var bn=Wn.authActions;bn.authorize(kn),bn.persistAuthorizationIfNeeded()}};function pt(kn){return{type:re,payload:kn}}var ht=function(kn){return function(Wn){var bn=Wn.authActions;bn.logout(kn),bn.persistAuthorizationIfNeeded()}},Dt=function(kn){return function(Wn){var bn=Wn.authActions,jr=Wn.errActions,ji=kn.auth,oi=kn.token,Ui=kn.isValid,Sn=ji.name,hn=ji.schema.get("flow");delete D.Z.swaggerUIRedirectOauth2,"accessCode"===hn||Ui||jr.newAuthErr({authId:Sn,source:"auth",level:"warning",message:"Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"}),oi.error?jr.newAuthErr({authId:Sn,source:"auth",level:"error",message:(0,c.default)(oi)}):bn.authorizeOauth2WithPersistOption({auth:ji,token:oi})}};function Ft(kn){return{type:me,payload:kn}}var cn=function(kn){return function(Wn){var bn=Wn.authActions;bn.authorizeOauth2(kn),bn.persistAuthorizationIfNeeded()}},kt=function(kn){return function(Wn){var _s,Ho,yo,bn=Wn.authActions,jr=kn.schema,ji=kn.name,oi=kn.username,Ui=kn.password,Xr=kn.passwordType,Sn=kn.clientId,hn=kn.clientSecret,_r={grant_type:"password",scope:kn.scopes.join(" "),username:oi,password:Ui},Fi={};switch(Xr){case"request-body":_s=_r,yo=hn,(Ho=Sn)&&(0,g.default)(_s,{client_id:Ho}),yo&&(0,g.default)(_s,{client_secret:yo});break;case"basic":Fi.Authorization="Basic "+(0,P.r3)(Sn+":"+hn);break;default:console.warn("Warning: invalid passwordType ".concat(Xr," was passed, not including client id and secret"))}return bn.authorizeRequest({body:(0,P.GZ)(_r),url:jr.get("tokenUrl"),name:ji,headers:Fi,query:{},auth:kn})}},wn=function(kn){return function(Wn){var bn=Wn.authActions,jr=kn.schema,ji=kn.scopes,oi=kn.name,Sn={Authorization:"Basic "+(0,P.r3)(kn.clientId+":"+kn.clientSecret)},hn={grant_type:"client_credentials",scope:ji.join(" ")};return bn.authorizeRequest({body:(0,P.GZ)(hn),name:oi,url:jr.get("tokenUrl"),auth:kn,headers:Sn})}},Tn=function(kn){var Wn=kn.auth,bn=kn.redirectUrl;return function(jr){var oi=Wn.schema,Ui=Wn.name;return jr.authActions.authorizeRequest({body:(0,P.GZ)({grant_type:"authorization_code",code:Wn.code,client_id:Wn.clientId,client_secret:Wn.clientSecret,redirect_uri:bn,code_verifier:Wn.codeVerifier}),name:Ui,url:oi.get("tokenUrl"),auth:Wn})}},Hr=function(kn){var Wn=kn.auth,bn=kn.redirectUrl;return function(jr){var ji=jr.authActions,oi=Wn.schema,Ui=Wn.name,Xr=Wn.clientId,hn=Wn.codeVerifier,_r={Authorization:"Basic "+(0,P.r3)(Xr+":"+Wn.clientSecret)};return ji.authorizeRequest({body:(0,P.GZ)({grant_type:"authorization_code",code:Wn.code,client_id:Xr,redirect_uri:bn,code_verifier:hn}),name:Ui,url:oi.get("tokenUrl"),auth:Wn,headers:_r})}},sr=function(kn){return function(Wn){var bn,jr=Wn.fn,ji=Wn.getConfigs,oi=Wn.authActions,Ui=Wn.errActions,Xr=Wn.oas3Selectors,Sn=Wn.specSelectors,_r=kn.body,Fi=kn.query,_s=void 0===Fi?{}:Fi,Ho=kn.headers,yo=void 0===Ho?{}:Ho,Us=kn.name,zs=kn.url,Di=kn.auth,oo=(Wn.authSelectors.getConfigs()||{}).additionalQueryStringParams;if(Sn.isOAS3()){var ho=Xr.serverEffectiveValue(Xr.selectedServer());bn=(0,C.default)(zs,ho,!0)}else bn=(0,C.default)(zs,Sn.url(),!0);"object"===(0,o.default)(oo)&&(bn.query=(0,g.default)({},bn.query,oo));var Ze=bn.toString(),Mt=(0,g.default)({Accept:"application/json, text/plain, */*","Content-Type":"application/x-www-form-urlencoded","X-Requested-With":"XMLHttpRequest"},yo);jr.fetch({url:Ze,method:"post",headers:Mt,query:_s,body:_r,requestInterceptor:ji().requestInterceptor,responseInterceptor:ji().responseInterceptor}).then(function(St){var Un=JSON.parse(St.data);St.ok?Un&&Un.error||Un&&Un.parseError?Ui.newAuthErr({authId:Us,level:"error",source:"auth",message:(0,c.default)(Un)}):oi.authorizeOauth2WithPersistOption({auth:Di,token:Un}):Ui.newAuthErr({authId:Us,level:"error",source:"auth",message:St.statusText})}).catch(function(St){var Un=new Error(St).message;if(St.response&&St.response.data){var pr=St.response.data;try{var Vr="string"==typeof pr?JSON.parse(pr):pr;Vr.error&&(Un+=", error: ".concat(Vr.error)),Vr.error_description&&(Un+=", description: ".concat(Vr.error_description))}catch(Ri){}}Ui.newAuthErr({authId:Us,level:"error",source:"auth",message:Un})})}};function Nr(kn){return{type:Fe,payload:kn}}function xr(kn){return{type:Re,payload:kn}}var fn=function(){return function(kn){var Wn=kn.authSelectors;if((0,kn.getConfigs)().persistAuthorization){var bn=Wn.authorized();localStorage.setItem("authorized",(0,c.default)(bn.toJS()))}}},Rn=function(kn,Wn){return function(){D.Z.swaggerUIRedirectOauth2=Wn,D.Z.open(kn)}}},3705:(n,s,t)=>{t.r(s),t.d(s,{default:()=>W,preauthorizeBasic:()=>re,preauthorizeApiKey:()=>oe});var o=t(775),c=t(5527),g=t(5171),C=t(3962),D=t(5812),P=t(35),j=t(8302);function W(){return{afterLoad:function(me){this.rootInjects=this.rootInjects||{},this.rootInjects.initOAuth=me.authActions.configureAuth,this.rootInjects.preauthorizeApiKey=(0,c.default)(oe).call(oe,null,me),this.rootInjects.preauthorizeBasic=(0,c.default)(re).call(re,null,me)},statePlugins:{auth:{reducers:C.default,actions:D,selectors:P},spec:{wrapActions:j}}}}function re(me,_e,Fe,Re){var Le,we=me.authActions.authorize,U=me.specSelectors,pt=U.specJson,ht=(0,U.isOAS3)()?["components","securitySchemes"]:["securityDefinitions"],Dt=pt().getIn((0,g.default)(Le=[]).call(Le,ht,[_e]));return Dt?we((0,o.default)({},_e,{value:{username:Fe,password:Re},schema:Dt.toJS()})):null}function oe(me,_e,Fe){var Re,Le=me.authActions.authorize,we=me.specSelectors,U=we.specJson,pt=(0,we.isOAS3)()?["components","securitySchemes"]:["securityDefinitions"],ht=U().getIn((0,g.default)(Re=[]).call(Re,pt,[_e]));return ht?Le((0,o.default)({},_e,{value:Fe,schema:ht.toJS()})):null}},3962:(n,s,t)=>{t.r(s),t.d(s,{default:()=>re});var o,c=t(775),g=t(9334),C=t(29),D=t(7512),P=t(9725),j=t(6298),W=t(5812);const re=((0,c.default)(o={},W.SHOW_AUTH_POPUP,function(oe,me){return oe.set("showDefinitions",me.payload)}),(0,c.default)(o,W.AUTHORIZE,function(oe,me){var _e,Re=(0,P.fromJS)(me.payload),Le=oe.get("authorized")||(0,P.Map)();return(0,C.default)(_e=Re.entrySeq()).call(_e,function(we){var U=(0,g.default)(we,2),pt=U[0],ht=U[1];if(!(0,j.Wl)(ht.getIn))return oe.set("authorized",Le);var Dt=ht.getIn(["schema","type"]);if("apiKey"===Dt||"http"===Dt)Le=Le.set(pt,ht);else if("basic"===Dt){var Ft=ht.getIn(["value","username"]),cn=ht.getIn(["value","password"]);Le=(Le=Le.setIn([pt,"value"],{username:Ft,header:"Basic "+(0,j.r3)(Ft+":"+cn)})).setIn([pt,"schema"],ht.get("schema"))}}),oe.set("authorized",Le)}),(0,c.default)(o,W.AUTHORIZE_OAUTH2,function(oe,me){var _e,Fe=me.payload,Re=Fe.auth;Re.token=(0,D.default)({},Fe.token),_e=(0,P.fromJS)(Re);var we=oe.get("authorized")||(0,P.Map)();return we=we.set(_e.get("name"),_e),oe.set("authorized",we)}),(0,c.default)(o,W.LOGOUT,function(oe,me){var _e=me.payload,Fe=oe.get("authorized").withMutations(function(Re){(0,C.default)(_e).call(_e,function(Le){Re.delete(Le)})});return oe.set("authorized",Fe)}),(0,c.default)(o,W.CONFIGURE_AUTH,function(oe,me){return oe.set("configs",me.payload)}),(0,c.default)(o,W.RESTORE_AUTHORIZATION,function(oe,me){return oe.set("authorized",(0,P.fromJS)(me.payload.authorized))}),o)},35:(n,s,t)=>{t.r(s),t.d(s,{shownDefinitions:()=>me,definitionsToAuthorize:()=>_e,getDefinitionsByNames:()=>Fe,definitionsForRequirements:()=>Re,authorized:()=>Le,isAuthorized:()=>we,getConfigs:()=>U});var o=t(9334),c=t(29),g=t(6145),C=t(9963),D=t(8818),P=t(2565),j=t(2740),W=t(8639),re=t(9725),oe=function(pt){return pt},me=(0,W.createSelector)(oe,function(pt){return pt.get("showDefinitions")}),_e=(0,W.createSelector)(oe,function(){return function(pt){var ht,Dt=pt.specSelectors.securityDefinitions()||(0,re.Map)({}),Ft=(0,re.List)();return(0,c.default)(ht=Dt.entrySeq()).call(ht,function(cn){var kt=(0,o.default)(cn,2),wn=kt[0],Tn=kt[1],Hr=(0,re.Map)();Hr=Hr.set(wn,Tn),Ft=Ft.push(Hr)}),Ft}}),Fe=function(pt,ht){return function(Dt){var Ft,cn=Dt.specSelectors;console.warn("WARNING: getDefinitionsByNames is deprecated and will be removed in the next major version.");var kt=cn.securityDefinitions(),wn=(0,re.List)();return(0,c.default)(Ft=ht.valueSeq()).call(Ft,function(Tn){var Hr,sr=(0,re.Map)();(0,c.default)(Hr=Tn.entrySeq()).call(Hr,function(Nr){var xr,fn,Rn=(0,o.default)(Nr,2),kn=Rn[0],Wn=Rn[1],bn=kt.get(kn);"oauth2"===bn.get("type")&&Wn.size&&(xr=bn.get("scopes"),(0,c.default)(fn=xr.keySeq()).call(fn,function(jr){Wn.contains(jr)||(xr=xr.delete(jr))}),bn=bn.set("allowedScopes",xr)),sr=sr.set(kn,bn)}),wn=wn.push(sr)}),wn}},Re=function(pt){var ht=arguments.length>1&&void 0!==arguments[1]?arguments[1]:(0,re.List)();return function(Dt){var Ft=Dt.authSelectors.definitionsToAuthorize()||(0,re.List)();return(0,g.default)(Ft).call(Ft,function(cn){return(0,C.default)(ht).call(ht,function(kt){return kt.get(cn.keySeq().first())})})}},Le=(0,W.createSelector)(oe,function(pt){return pt.get("authorized")||(0,re.Map)()}),we=function(pt,ht){return function(Dt){var Ft,cn=Dt.authSelectors.authorized();return re.List.isList(ht)?!!(0,g.default)(Ft=ht.toJS()).call(Ft,function(kt){var wn,Tn;return-1===(0,D.default)(wn=(0,P.default)(Tn=(0,j.default)(kt)).call(Tn,function(Hr){return!!cn.get(Hr)})).call(wn,!1)}).length:null}},U=(0,W.createSelector)(oe,function(pt){return pt.get("configs")})},8302:(n,s,t)=>{t.r(s),t.d(s,{execute:()=>c});var o=t(1013),c=function(g,C){var D=C.authSelectors,P=C.specSelectors;return function(j){var W=j.path,re=j.method,oe=j.operation,me=j.extras,_e={authorized:D.authorized()&&D.authorized().toJS(),definitions:P.securityDefinitions()&&P.securityDefinitions().toJS(),specSecurity:P.security()&&P.security().toJS()};return g((0,o.default)({path:W,method:re,operation:oe,securities:_e},me))}}},714:(n,s,t)=>{t.r(s),t.d(s,{UPDATE_CONFIGS:()=>c,TOGGLE_CONFIGS:()=>g,update:()=>C,toggle:()=>D,loaded:()=>P});var o=t(775),c="configs_update",g="configs_toggle";function C(j,W){return{type:c,payload:(0,o.default)({},j,W)}}function D(j){return{type:g,payload:j}}var P=function(){return function(j){var re=j.authActions;if((0,j.getConfigs)().persistAuthorization){var oe=localStorage.getItem("authorized");oe&&re.restoreAuthorization({authorized:JSON.parse(oe)})}}}},2256:(n,s,t)=>{t.r(s),t.d(s,{parseYamlConfig:()=>c});var o=t(626),c=function(g,C){try{return o.default.load(g)}catch(D){return C&&C.errActions.newThrownErr(new Error(D)),{}}}},1661:(n,s,t)=>{t.r(s),t.d(s,{default:()=>W});var o=t(5163),c=t(2256),g=t(714),C=t(2698),D=t(9018),P=t(7743),j={getLocalConfig:function(){return(0,c.parseYamlConfig)(o)}};function W(){return{statePlugins:{spec:{actions:C,selectors:j},configs:{reducers:P.default,actions:g,selectors:D}}}}},7743:(n,s,t)=>{t.r(s),t.d(s,{default:()=>D});var o,c=t(775),g=t(9725),C=t(714);const D=((0,c.default)(o={},C.UPDATE_CONFIGS,function(P,j){return P.merge((0,g.fromJS)(j.payload))}),(0,c.default)(o,C.TOGGLE_CONFIGS,function(P,j){var W=j.payload,re=P.get(W);return P.set(W,!re)}),o)},9018:(n,s,t)=>{t.r(s),t.d(s,{get:()=>c});var o=t(4163),c=function(g,C){return g.getIn((0,o.default)(C)?C:[C])}},2698:(n,s,t)=>{t.r(s),t.d(s,{downloadConfig:()=>c,getConfigByUrl:()=>g});var o=t(2256),c=function(C){return function(D){return(0,D.fn.fetch)(C)}},g=function(C,D){return function(P){var j=P.specActions;if(C)return j.downloadConfig(C).then(W,W);function W(re){re instanceof Error||re.status>=400?(j.updateLoadingStatus("failedConfig"),j.updateLoadingStatus("failedConfig"),j.updateUrl(""),console.error(re.statusText+" "+C.url),D(null)):D((0,o.parseYamlConfig)(re.text))}}}},1970:(n,s,t)=>{t.r(s),t.d(s,{setHash:()=>o});var o=function(c){return c?history.pushState(null,null,"#".concat(c)):window.location.hash=""}},4980:(n,s,t)=>{t.r(s),t.d(s,{default:()=>C});var o=t(5858),c=t(877),g=t(4584);function C(){return[o.default,{statePlugins:{configs:{wrapActions:{loaded:function(D,P){return function(){D.apply(void 0,arguments);var j=decodeURIComponent(window.location.hash);P.layoutActions.parseDeepLinkHash(j)}}}}},wrapComponents:{operation:c.default,OperationTag:g.default}}]}},5858:(n,s,t)=>{t.r(s),t.d(s,{clearScrollTo:()=>Dt,default:()=>Ft,parseDeepLinkHash:()=>U,readyToScroll:()=>pt,scrollTo:()=>we,scrollToElement:()=>ht,show:()=>Le});var o=t(775),c=t(9334),g=t(4163),C=t(5171),D=t(8136),P=t(2565),j=t(8818),W=t(1970);const re=(t.d(kt={},{default:()=>sp()}),kt);var kt,oe,me=t(6298),_e=t(9725),Fe="layout_scroll_to",Re="layout_clear_scroll",Le=function(cn,kt){var wn=kt.getConfigs,Tn=kt.layoutSelectors;return function(){for(var Hr=arguments.length,sr=new Array(Hr),Nr=0;Nr<Hr;Nr++)sr[Nr]=arguments[Nr];if(cn.apply(void 0,sr),wn().deepLinking)try{var xr=sr[0],fn=sr[1];xr=(0,g.default)(xr)?xr:[xr];var Rn=Tn.urlHashArrayFromIsShownKey(xr);if(!Rn.length)return;var kn,Wn=(0,c.default)(Rn,2),bn=Wn[0],jr=Wn[1];if(!fn)return(0,W.setHash)("/");2===Rn.length?(0,W.setHash)((0,me.oJ)((0,C.default)(kn="/".concat(encodeURIComponent(bn),"/")).call(kn,encodeURIComponent(jr)))):1===Rn.length&&(0,W.setHash)((0,me.oJ)("/".concat(encodeURIComponent(bn))))}catch(ji){console.error(ji)}}},we=function(cn){return{type:Fe,payload:(0,g.default)(cn)?cn:[cn]}},U=function(cn){return function(kt){var wn=kt.layoutActions,Tn=kt.layoutSelectors;if((0,kt.getConfigs)().deepLinking&&cn){var Hr,sr=(0,D.default)(cn).call(cn,1);"!"===sr[0]&&(sr=(0,D.default)(sr).call(sr,1)),"/"===sr[0]&&(sr=(0,D.default)(sr).call(sr,1));var Nr=(0,P.default)(Hr=sr.split("/")).call(Hr,function(oi){return oi||""}),xr=Tn.isShownKeyFromUrlHashArray(Nr),fn=(0,c.default)(xr,3),kn=fn[1],Wn=void 0===kn?"":kn,bn=fn[2],jr=void 0===bn?"":bn;if("operations"===fn[0]){var ji=Tn.isShownKeyFromUrlHashArray([Wn]);(0,j.default)(Wn).call(Wn,"_")>-1&&(console.warn("Warning: escaping deep link whitespace with `_` will be unsupported in v4.0, use `%20` instead."),wn.show((0,P.default)(ji).call(ji,function(oi){return oi.replace(/_/g," ")}),!0)),wn.show(ji,!0)}((0,j.default)(Wn).call(Wn,"_")>-1||(0,j.default)(jr).call(jr,"_")>-1)&&(console.warn("Warning: escaping deep link whitespace with `_` will be unsupported in v4.0, use `%20` instead."),wn.show((0,P.default)(xr).call(xr,function(oi){return oi.replace(/_/g," ")}),!0)),wn.show(xr,!0),wn.scrollTo(xr)}}},pt=function(cn,kt){return function(wn){var Tn=wn.layoutSelectors.getScrollToKey();_e.default.is(Tn,(0,_e.fromJS)(cn))&&(wn.layoutActions.scrollToElement(kt),wn.layoutActions.clearScrollTo())}},ht=function(cn,kt){return function(wn){try{kt=kt||wn.fn.getScrollParent(cn),re.default.createScroller(kt).to(cn)}catch(Tn){console.error(Tn)}}},Dt=function(){return{type:Re}};const Ft={fn:{getScrollParent:function(cn,kt){var wn=document.documentElement,Tn=getComputedStyle(cn),Hr="absolute"===Tn.position,sr=kt?/(auto|scroll|hidden)/:/(auto|scroll)/;if("fixed"===Tn.position)return wn;for(var Nr=cn;Nr=Nr.parentElement;)if(Tn=getComputedStyle(Nr),(!Hr||"static"!==Tn.position)&&sr.test(Tn.overflow+Tn.overflowY+Tn.overflowX))return Nr;return wn}},statePlugins:{layout:{actions:{scrollToElement:ht,scrollTo:we,clearScrollTo:Dt,readyToScroll:pt,parseDeepLinkHash:U},selectors:{getScrollToKey:function(cn){return cn.get("scrollToKey")},isShownKeyFromUrlHashArray:function(cn,kt){var wn=(0,c.default)(kt,2),Tn=wn[0],Hr=wn[1];return Hr?["operations",Tn,Hr]:Tn?["operations-tag",Tn]:[]},urlHashArrayFromIsShownKey:function(cn,kt){var wn=(0,c.default)(kt,3),Tn=wn[0],Hr=wn[1];return"operations"==Tn?[Hr,wn[2]]:"operations-tag"==Tn?[Hr]:[]}},reducers:(oe={},(0,o.default)(oe,Fe,function(cn,kt){return cn.set("scrollToKey",_e.default.fromJS(kt.payload))}),(0,o.default)(oe,Re,function(cn){return cn.delete("scrollToKey")}),oe),wrapActions:{show:Le}}}}},4584:(n,s,t)=>{t.r(s),t.d(s,{default:()=>re});var o=t(7344),c=t(8656),g=t(6340),C=t(9972),D=t(5416),P=t(775),j=t(5171),W=t(810);t(5053);const re=function(oe,me){return function(_e){(0,C.default)(Re,_e);var Fe=(0,D.default)(Re);function Re(){var Le,we;(0,o.default)(this,Re);for(var U=arguments.length,pt=new Array(U),ht=0;ht<U;ht++)pt[ht]=arguments[ht];return we=Fe.call.apply(Fe,(0,j.default)(Le=[this]).call(Le,pt)),(0,P.default)((0,g.default)(we),"onLoad",function(Dt){me.layoutActions.readyToScroll(["operations-tag",we.props.tag],Dt)}),we}return(0,c.default)(Re,[{key:"render",value:function(){return W.default.createElement("span",{ref:this.onLoad},W.default.createElement(oe,this.props))}}]),Re}(W.default.Component)}},877:(n,s,t)=>{t.r(s),t.d(s,{default:()=>re});var o=t(7344),c=t(8656),g=t(6340),C=t(9972),D=t(5416),P=t(775),j=t(5171),W=t(810);t(9569);const re=function(oe,me){return function(_e){(0,C.default)(Re,_e);var Fe=(0,D.default)(Re);function Re(){var Le,we;(0,o.default)(this,Re);for(var U=arguments.length,pt=new Array(U),ht=0;ht<U;ht++)pt[ht]=arguments[ht];return we=Fe.call.apply(Fe,(0,j.default)(Le=[this]).call(Le,pt)),(0,P.default)((0,g.default)(we),"onLoad",function(Dt){var Ft=we.props.operation,cn=Ft.toObject(),kt=cn.tag,wn=cn.operationId,Tn=Ft.toObject().isShownKey;me.layoutActions.readyToScroll(Tn=Tn||["operations",kt,wn],Dt)}),we}return(0,c.default)(Re,[{key:"render",value:function(){return W.default.createElement("span",{ref:this.onLoad},W.default.createElement(oe,this.props))}}]),Re}(W.default.Component)}},8011:(n,s,t)=>{t.r(s),t.d(s,{default:()=>re});var o=t(7512),c=t(3769),g=t(5171),C=t(8818),D=t(313),P=t(8639),j=t(9725),W=t(7504);function re(oe){var me=oe.fn;return{statePlugins:{spec:{actions:{download:function(_e){return function(Fe){var Re=Fe.errActions,Le=Fe.specSelectors,we=Fe.specActions,pt=me.fetch,ht=(0,Fe.getConfigs)();function Dt(Ft){if(Ft instanceof Error||Ft.status>=400)return we.updateLoadingStatus("failed"),Re.newThrownErr((0,o.default)(new Error((Ft.message||Ft.statusText)+" "+_e),{source:"fetch"})),void(!Ft.status&&Ft instanceof Error&&function(){try{var cn;if("URL"in W.Z?cn=new c.default(_e):(cn=document.createElement("a")).href=_e,"https:"!==cn.protocol&&"https:"===W.Z.location.protocol){var kt=(0,o.default)(new Error("Possible mixed-content issue? The page was loaded over https:// but a ".concat(cn.protocol,"// URL was specified. Check that you are not attempting to load mixed content.")),{source:"fetch"});return void Re.newThrownErr(kt)}if(cn.origin!==W.Z.location.origin){var wn,Tn=(0,o.default)(new Error((0,g.default)(wn="Possible cross-origin (CORS) issue? The URL origin (".concat(cn.origin,") does not match the page (")).call(wn,W.Z.location.origin,"). Check the server returns the correct 'Access-Control-Allow-*' headers.")),{source:"fetch"});Re.newThrownErr(Tn)}}catch(Hr){return}}());we.updateLoadingStatus("success"),we.updateSpec(Ft.text),Le.url()!==_e&&we.updateUrl(_e)}_e=_e||Le.url(),we.updateLoadingStatus("loading"),Re.clear({source:"fetch"}),pt({url:_e,loadSpec:!0,requestInterceptor:ht.requestInterceptor||function(Ft){return Ft},responseInterceptor:ht.responseInterceptor||function(Ft){return Ft},credentials:"same-origin",headers:{Accept:"application/json,*/*"}}).then(Dt,Dt)}},updateLoadingStatus:function(_e){var Fe,Re=[null,"loading","failed","success","failedConfig"];return-1===(0,C.default)(Re).call(Re,_e)&&console.error((0,g.default)(Fe="Error: ".concat(_e," is not one of ")).call(Fe,(0,D.default)(Re))),{type:"spec_update_loading_status",payload:_e}}},reducers:{spec_update_loading_status:function(_e,Fe){return"string"==typeof Fe.payload?_e.set("loadingStatus",Fe.payload):_e}},selectors:{loadingStatus:(0,P.createSelector)(function(_e){return _e||(0,j.Map)()},function(_e){return _e.get("loadingStatus")||null})}}}}}},4966:(n,s,t)=>{t.r(s),t.d(s,{NEW_THROWN_ERR:()=>c,NEW_THROWN_ERR_BATCH:()=>g,NEW_SPEC_ERR:()=>C,NEW_SPEC_ERR_BATCH:()=>D,NEW_AUTH_ERR:()=>P,CLEAR:()=>j,CLEAR_BY:()=>W,newThrownErr:()=>re,newThrownErrBatch:()=>oe,newSpecErr:()=>me,newSpecErrBatch:()=>_e,newAuthErr:()=>Fe,clear:()=>Re,clearBy:()=>Le});var o=t(8518),c="err_new_thrown_err",g="err_new_thrown_err_batch",C="err_new_spec_err",D="err_new_spec_err_batch",P="err_new_auth_err",j="err_clear",W="err_clear_by";function re(we){return{type:c,payload:(0,o.serializeError)(we)}}function oe(we){return{type:g,payload:we}}function me(we){return{type:C,payload:we}}function _e(we){return{type:D,payload:we}}function Fe(we){return{type:P,payload:we}}function Re(){var we=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return{type:j,payload:we}}function Le(){var we=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!0};return{type:W,payload:we}}},6808:(n,s,t)=>{t.r(s),t.d(s,{default:()=>D});var o=t(6145),c=t(2565);const g=(t.d(j={},{default:()=>x_()}),j);var j,C=[t(2392),t(1835)];function D(P){var j,W={jsSpec:{}},re=(0,g.default)(C,function(oe,me){try{var _e=me.transform(oe,W);return(0,o.default)(_e).call(_e,function(Fe){return!!Fe})}catch(Fe){return console.error("Transformer error:",Fe),oe}},P);return(0,c.default)(j=(0,o.default)(re).call(re,function(oe){return!!oe})).call(j,function(oe){return!oe.get("line")&&oe.get("path"),oe})}},2392:(n,s,t)=>{t.r(s),t.d(s,{transform:()=>D});var o=t(2565),c=t(8818),g=t(8136),C=t(6785);function D(P){return(0,o.default)(P).call(P,function(j){var W,Re,re="is not of a type(s)",oe=(0,c.default)(W=j.get("message")).call(W,re);if(oe>-1){var me,_e,Fe=(0,g.default)(me=j.get("message")).call(me,oe+re.length).split(",");return j.set("message",(0,g.default)(_e=j.get("message")).call(_e,0,oe)+(0,C.default)(Re=Fe).call(Re,function(Le,we,U,pt){return U===pt.length-1&&pt.length>1?Le+"or "+we:pt[U+1]&&pt.length>2?Le+we+", ":pt[U+1]?Le+we+" ":Le+we},"should be a"))}return j})}},1835:(n,s,t)=>{function o(c,g){return c}t.r(s),t.d(s,{transform:()=>o}),t(2565),t(8818),t(9908),t(9725)},7793:(n,s,t)=>{t.r(s),t.d(s,{default:()=>C});var o=t(3527),c=t(4966),g=t(7667);function C(D){return{statePlugins:{err:{reducers:(0,o.default)(D),actions:c,selectors:g}}}}},3527:(n,s,t)=>{t.r(s),t.d(s,{default:()=>me});var o=t(775),c=t(7512),g=t(2565),C=t(5171),D=t(6145),P=t(7930),j=t(4966),W=t(9725),re=t(6808),oe={line:0,level:"error",message:"Unknown error"};function me(){var _e;return(0,o.default)(_e={},j.NEW_THROWN_ERR,function(Fe,Re){var we=(0,c.default)(oe,Re.payload,{type:"thrown"});return Fe.update("errors",function(U){return(U||(0,W.List)()).push((0,W.fromJS)(we))}).update("errors",function(U){return(0,re.default)(U)})}),(0,o.default)(_e,j.NEW_THROWN_ERR_BATCH,function(Fe,Re){var Le=Re.payload;return Le=(0,g.default)(Le).call(Le,function(we){return(0,W.fromJS)((0,c.default)(oe,we,{type:"thrown"}))}),Fe.update("errors",function(we){var U;return(0,C.default)(U=we||(0,W.List)()).call(U,(0,W.fromJS)(Le))}).update("errors",function(we){return(0,re.default)(we)})}),(0,o.default)(_e,j.NEW_SPEC_ERR,function(Fe,Re){var we=(0,W.fromJS)(Re.payload);return we=we.set("type","spec"),Fe.update("errors",function(U){return(U||(0,W.List)()).push((0,W.fromJS)(we)).sortBy(function(pt){return pt.get("line")})}).update("errors",function(U){return(0,re.default)(U)})}),(0,o.default)(_e,j.NEW_SPEC_ERR_BATCH,function(Fe,Re){var Le=Re.payload;return Le=(0,g.default)(Le).call(Le,function(we){return(0,W.fromJS)((0,c.default)(oe,we,{type:"spec"}))}),Fe.update("errors",function(we){var U;return(0,C.default)(U=we||(0,W.List)()).call(U,(0,W.fromJS)(Le))}).update("errors",function(we){return(0,re.default)(we)})}),(0,o.default)(_e,j.NEW_AUTH_ERR,function(Fe,Re){var we=(0,W.fromJS)((0,c.default)({},Re.payload));return we=we.set("type","auth"),Fe.update("errors",function(U){return(U||(0,W.List)()).push((0,W.fromJS)(we))}).update("errors",function(U){return(0,re.default)(U)})}),(0,o.default)(_e,j.CLEAR,function(Fe,Re){var Le,we=Re.payload;if(!we||!Fe.get("errors"))return Fe;var U=(0,D.default)(Le=Fe.get("errors")).call(Le,function(pt){var ht;return(0,P.default)(ht=pt.keySeq()).call(ht,function(Dt){var Ft=pt.get(Dt),cn=we[Dt];return!cn||Ft!==cn})});return Fe.merge({errors:U})}),(0,o.default)(_e,j.CLEAR_BY,function(Fe,Re){var Le,we=Re.payload;if(!we||"function"!=typeof we)return Fe;var U=(0,D.default)(Le=Fe.get("errors")).call(Le,function(pt){return we(pt)});return Fe.merge({errors:U})}),_e}},7667:(n,s,t)=>{t.r(s),t.d(s,{allErrors:()=>g,lastError:()=>C});var o=t(9725),c=t(8639),g=(0,c.createSelector)(function(D){return D},function(D){return D.get("errors",(0,o.List)())}),C=(0,c.createSelector)(g,function(D){return D.last()})},9978:(n,s,t)=>{t.r(s),t.d(s,{default:()=>c});var o=t(4309);function c(){return{fn:{opsFilter:o.default}}}},4309:(n,s,t)=>{t.r(s),t.d(s,{default:()=>g});var o=t(6145),c=t(8818);function g(C,D){return(0,o.default)(C).call(C,function(P,j){return-1!==(0,c.default)(j).call(j,D)})}},5474:(n,s,t)=>{t.r(s),t.d(s,{UPDATE_LAYOUT:()=>c,UPDATE_FILTER:()=>g,UPDATE_MODE:()=>C,SHOW:()=>D,updateLayout:()=>P,updateFilter:()=>j,show:()=>W,changeMode:()=>re});var o=t(6298),c="layout_update_layout",g="layout_update_filter",C="layout_update_mode",D="layout_show";function P(oe){return{type:c,payload:oe}}function j(oe){return{type:g,payload:oe}}function W(oe){var me=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return oe=(0,o.AF)(oe),{type:D,payload:{thing:oe,shown:me}}}function re(oe){var me=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return oe=(0,o.AF)(oe),{type:C,payload:{thing:oe,mode:me}}}},6821:(n,s,t)=>{t.r(s),t.d(s,{default:()=>D});var o=t(5672),c=t(5474),g=t(4400),C=t(8989);function D(){return{statePlugins:{layout:{reducers:o.default,actions:c,selectors:g},spec:{wrapSelectors:C}}}}},5672:(n,s,t)=>{t.r(s),t.d(s,{default:()=>P});var o,c=t(775),g=t(5171),C=t(9725),D=t(5474);const P=((0,c.default)(o={},D.UPDATE_LAYOUT,function(j,W){return j.set("layout",W.payload)}),(0,c.default)(o,D.UPDATE_FILTER,function(j,W){return j.set("filter",W.payload)}),(0,c.default)(o,D.SHOW,function(j,W){var re=W.payload.shown,oe=(0,C.fromJS)(W.payload.thing);return j.update("shown",(0,C.fromJS)({}),function(me){return me.set(oe,re)})}),(0,c.default)(o,D.UPDATE_MODE,function(j,W){var re,oe=W.payload.thing,me=W.payload.mode;return j.setIn((0,g.default)(re=["modes"]).call(re,oe),(me||"")+"")}),o)},4400:(n,s,t)=>{t.r(s),t.d(s,{current:()=>P,currentFilter:()=>j,isShown:()=>W,whatMode:()=>re,showSummary:()=>oe});var o=t(2691),c=t(5171),g=t(8639),C=t(6298),D=t(9725),P=function(me){return me.get("layout")},j=function(me){return me.get("filter")},W=function(me,_e,Fe){return _e=(0,C.AF)(_e),me.get("shown",(0,D.fromJS)({})).get((0,D.fromJS)(_e),Fe)},re=function(me,_e){var Fe,Re=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return _e=(0,C.AF)(_e),me.getIn((0,c.default)(Fe=["modes"]).call(Fe,(0,o.default)(_e)),Re)},oe=(0,g.createSelector)(function(me){return me},function(me){return!W(me,"editor")})},8989:(n,s,t)=>{t.r(s),t.d(s,{taggedOperations:()=>g});var o=t(5171),c=t(8136),g=function(C,D){return function(P){for(var j,W=arguments.length,re=new Array(W>1?W-1:0),oe=1;oe<W;oe++)re[oe-1]=arguments[oe];var me=C.apply(void 0,(0,o.default)(j=[P]).call(j,re)),_e=D.getSystem(),Fe=_e.fn,Re=_e.layoutSelectors,Le=_e.getConfigs,we=Le(),U=we.maxDisplayedTags,pt=Re.currentFilter();return pt&&!0!==pt&&"true"!==pt&&"false"!==pt&&(me=Fe.opsFilter(me,pt)),U&&!isNaN(U)&&U>=0&&(me=(0,c.default)(me).call(me,0,U)),me}}},9150:(n,s,t)=>{t.r(s),t.d(s,{default:()=>c});var o=t(5527);function c(g){var D={debug:0,info:1,log:2,warn:3,error:4},P=function(oe){return D[oe]||-1},W=P(g.configs.logLevel);function re(oe){for(var me,_e=arguments.length,Fe=new Array(_e>1?_e-1:0),Re=1;Re<_e;Re++)Fe[Re-1]=arguments[Re];P(oe)>=W&&(me=console)[oe].apply(me,Fe)}return re.warn=(0,o.default)(re).call(re,null,"warn"),re.error=(0,o.default)(re).call(re,null,"error"),re.info=(0,o.default)(re).call(re,null,"info"),re.debug=(0,o.default)(re).call(re,null,"debug"),{rootInjects:{log:re}}}},7002:(n,s,t)=>{t.r(s),t.d(s,{UPDATE_SELECTED_SERVER:()=>o,UPDATE_REQUEST_BODY_VALUE:()=>c,UPDATE_REQUEST_BODY_VALUE_RETAIN_FLAG:()=>g,UPDATE_REQUEST_BODY_INCLUSION:()=>C,UPDATE_ACTIVE_EXAMPLES_MEMBER:()=>D,UPDATE_REQUEST_CONTENT_TYPE:()=>P,UPDATE_RESPONSE_CONTENT_TYPE:()=>j,UPDATE_SERVER_VARIABLE_VALUE:()=>W,SET_REQUEST_BODY_VALIDATE_ERROR:()=>re,CLEAR_REQUEST_BODY_VALIDATE_ERROR:()=>oe,CLEAR_REQUEST_BODY_VALUE:()=>me,setSelectedServer:()=>_e,setRequestBodyValue:()=>Fe,setRetainRequestBodyValueFlag:()=>Re,setRequestBodyInclusion:()=>Le,setActiveExamplesMember:()=>we,setRequestContentType:()=>U,setResponseContentType:()=>pt,setServerVariableValue:()=>ht,setRequestBodyValidateError:()=>Dt,clearRequestBodyValidateError:()=>Ft,initRequestBodyValidateError:()=>cn,clearRequestBodyValue:()=>kt});var o="oas3_set_servers",c="oas3_set_request_body_value",g="oas3_set_request_body_retain_flag",C="oas3_set_request_body_inclusion",D="oas3_set_active_examples_member",P="oas3_set_request_content_type",j="oas3_set_response_content_type",W="oas3_set_server_variable_value",re="oas3_set_request_body_validate_error",oe="oas3_clear_request_body_validate_error",me="oas3_clear_request_body_value";function _e(wn,Tn){return{type:o,payload:{selectedServerUrl:wn,namespace:Tn}}}function Fe(wn){return{type:c,payload:{value:wn.value,pathMethod:wn.pathMethod}}}var Re=function(wn){return{type:g,payload:{value:wn.value,pathMethod:wn.pathMethod}}};function Le(wn){return{type:C,payload:{value:wn.value,pathMethod:wn.pathMethod,name:wn.name}}}function we(wn){return{type:D,payload:{name:wn.name,pathMethod:wn.pathMethod,contextType:wn.contextType,contextName:wn.contextName}}}function U(wn){return{type:P,payload:{value:wn.value,pathMethod:wn.pathMethod}}}function pt(wn){return{type:j,payload:{value:wn.value,path:wn.path,method:wn.method}}}function ht(wn){return{type:W,payload:{server:wn.server,namespace:wn.namespace,key:wn.key,val:wn.val}}}var Dt=function(wn){return{type:re,payload:{path:wn.path,method:wn.method,validationErrors:wn.validationErrors}}},Ft=function(wn){return{type:oe,payload:{path:wn.path,method:wn.method}}},cn=function(wn){var Tn=wn.pathMethod;return{type:oe,payload:{path:Tn[0],method:Tn[1]}}},kt=function(wn){return{type:me,payload:{pathMethod:wn.pathMethod}}}},3723:(n,s,t)=>{t.r(s),t.d(s,{definitionsToAuthorize:()=>me});var oe,o=t(775),c=t(9334),g=t(5171),C=t(29),D=t(6145),P=t(6785),j=t(8639),W=t(9725),re=t(7779),me=(oe=(0,j.createSelector)(function(_e){return _e},function(_e){return _e.specSelectors.securityDefinitions()},function(_e,Fe){var Re,Le=(0,W.List)();return Fe&&(0,C.default)(Re=Fe.entrySeq()).call(Re,function(we){var U,pt=(0,c.default)(we,2),ht=pt[0],Dt=pt[1],Ft=Dt.get("type");if("oauth2"===Ft&&(0,C.default)(U=Dt.get("flows").entrySeq()).call(U,function(wn){var Tn=(0,c.default)(wn,2),sr=Tn[1],Nr=(0,W.fromJS)({flow:Tn[0],authorizationUrl:sr.get("authorizationUrl"),tokenUrl:sr.get("tokenUrl"),scopes:sr.get("scopes"),type:Dt.get("type"),description:Dt.get("description")});Le=Le.push(new W.Map((0,o.default)({},ht,(0,D.default)(Nr).call(Nr,function(xr){return void 0!==xr}))))}),"http"!==Ft&&"apiKey"!==Ft||(Le=Le.push(new W.Map((0,o.default)({},ht,Dt)))),"openIdConnect"===Ft&&Dt.get("openIdConnectData")){var cn=Dt.get("openIdConnectData"),kt=cn.get("grant_types_supported")||["authorization_code","implicit"];(0,C.default)(kt).call(kt,function(wn){var Tn,Hr=cn.get("scopes_supported")&&(0,P.default)(Tn=cn.get("scopes_supported")).call(Tn,function(Nr,xr){return Nr.set(xr,"")},new W.Map),sr=(0,W.fromJS)({flow:wn,authorizationUrl:cn.get("authorization_endpoint"),tokenUrl:cn.get("token_endpoint"),scopes:Hr,type:"oauth2",openIdConnectUrl:Dt.get("openIdConnectUrl")});Le=Le.push(new W.Map((0,o.default)({},ht,(0,D.default)(sr).call(sr,function(Nr){return void 0!==Nr}))))})}}),Le}),function(_e,Fe){return function(){for(var Re=Fe.getSystem().specSelectors.specJson(),Le=arguments.length,we=new Array(Le),U=0;U<Le;U++)we[U]=arguments[U];if((0,re.isOAS3)(Re)){var pt,ht=Fe.getState().getIn(["spec","resolvedSubtrees","components","securitySchemes"]);return oe.apply(void 0,(0,g.default)(pt=[Fe,ht]).call(pt,we))}return _e.apply(void 0,we)}})},3427:(n,s,t)=>{t.r(s),t.d(s,{default:()=>P});var o=t(863),c=t(9334),g=t(2565),C=t(810),D=(t(5053),t(9569),t(9725));const P=function(j){var W,re=j.callbacks,me=j.specPath,_e=(0,j.getComponent)("OperationContainer",!0);if(!re)return C.default.createElement("span",null,"No callbacks");var Fe=(0,g.default)(W=re.entrySeq()).call(W,function(Re){var Le,we=(0,c.default)(Re,2),U=we[0],pt=we[1];return C.default.createElement("div",{key:U},C.default.createElement("h2",null,U),(0,g.default)(Le=pt.entrySeq()).call(Le,function(ht){var Dt,Ft=(0,c.default)(ht,2),cn=Ft[0];return"$$ref"===cn?null:C.default.createElement("div",{key:cn},(0,g.default)(Dt=Ft[1].entrySeq()).call(Dt,function(wn){var Tn=(0,c.default)(wn,2),Hr=Tn[0];if("$$ref"===Hr)return null;var Nr=(0,D.fromJS)({operation:Tn[1]});return C.default.createElement(_e,(0,o.default)({},j,{op:Nr,key:Hr,tag:"",method:Hr,path:cn,specPath:me.push(U,cn,Hr),allowTryItOut:!1}))}))}))});return C.default.createElement("div",null,Fe)}},6775:(n,s,t)=>{t.r(s),t.d(s,{default:()=>me});var o=t(7344),c=t(8656),g=t(6340),C=t(9972),D=t(5416),P=t(775),j=t(7512),W=t(6145),re=t(2565),oe=t(810),me=(t(5053),function(_e){(0,C.default)(Re,_e);var Fe=(0,D.default)(Re);function Re(Le,we){var U;(0,o.default)(this,Re),U=Fe.call(this,Le,we),(0,P.default)((0,g.default)(U),"onChange",function(cn){var kt=U.props.onChange,wn=cn.target,Tn=wn.value,Hr=wn.name,sr=(0,j.default)({},U.state.value);Hr?sr[Hr]=Tn:sr=Tn,U.setState({value:sr},function(){return kt(U.state)})});var pt=U.props,ht=pt.name,Dt=pt.schema,Ft=U.getValue();return U.state={name:ht,schema:Dt,value:Ft},U}return(0,c.default)(Re,[{key:"getValue",value:function(){var Le=this.props,U=Le.authorized;return U&&U.getIn([Le.name,"value"])}},{key:"render",value:function(){var Le,we,U=this.props,pt=U.schema,ht=U.getComponent,Dt=U.errSelectors,Ft=U.name,cn=ht("Input"),kt=ht("Row"),wn=ht("Col"),Tn=ht("authError"),Hr=ht("Markdown",!0),sr=ht("JumpToPath",!0),Nr=(pt.get("scheme")||"").toLowerCase(),xr=this.getValue(),fn=(0,W.default)(Le=Dt.allErrors()).call(Le,function(Wn){return Wn.get("authId")===Ft});if("basic"===Nr){var Rn,kn=xr?xr.get("username"):null;return oe.default.createElement("div",null,oe.default.createElement("h4",null,oe.default.createElement("code",null,Ft||pt.get("name")),"\xa0 (http, Basic)",oe.default.createElement(sr,{path:["securityDefinitions",Ft]})),kn&&oe.default.createElement("h6",null,"Authorized"),oe.default.createElement(kt,null,oe.default.createElement(Hr,{source:pt.get("description")})),oe.default.createElement(kt,null,oe.default.createElement("label",null,"Username:"),kn?oe.default.createElement("code",null," ",kn," "):oe.default.createElement(wn,null,oe.default.createElement(cn,{type:"text",required:"required",name:"username","aria-label":"auth-basic-username",onChange:this.onChange,autoFocus:!0}))),oe.default.createElement(kt,null,oe.default.createElement("label",null,"Password:"),kn?oe.default.createElement("code",null," ****** "):oe.default.createElement(wn,null,oe.default.createElement(cn,{autoComplete:"new-password",name:"password",type:"password","aria-label":"auth-basic-password",onChange:this.onChange}))),(0,re.default)(Rn=fn.valueSeq()).call(Rn,function(Wn,bn){return oe.default.createElement(Tn,{error:Wn,key:bn})}))}return"bearer"===Nr?oe.default.createElement("div",null,oe.default.createElement("h4",null,oe.default.createElement("code",null,Ft||pt.get("name")),"\xa0 (http, Bearer)",oe.default.createElement(sr,{path:["securityDefinitions",Ft]})),xr&&oe.default.createElement("h6",null,"Authorized"),oe.default.createElement(kt,null,oe.default.createElement(Hr,{source:pt.get("description")})),oe.default.createElement(kt,null,oe.default.createElement("label",null,"Value:"),xr?oe.default.createElement("code",null," ****** "):oe.default.createElement(wn,null,oe.default.createElement(cn,{type:"text","aria-label":"auth-bearer-value",onChange:this.onChange,autoFocus:!0}))),(0,re.default)(we=fn.valueSeq()).call(we,function(Wn,bn){return oe.default.createElement(Tn,{error:Wn,key:bn})})):oe.default.createElement("div",null,oe.default.createElement("em",null,oe.default.createElement("b",null,Ft)," HTTP authentication: unsupported scheme ","'".concat(Nr,"'")))}}]),Re}(oe.default.Component))},6467:(n,s,t)=>{t.r(s),t.d(s,{default:()=>re});var o=t(3427),c=t(2458),g=t(5757),C=t(6617),D=t(9928),P=t(5327),j=t(6775),W=t(6796);const re={Callbacks:o.default,HttpAuth:j.default,RequestBody:c.default,Servers:C.default,ServersContainer:D.default,RequestBodyEditor:P.default,OperationServers:W.default,operationLink:g.default}},5757:(n,s,t)=>{t.r(s),t.d(s,{default:()=>W});var o=t(7344),c=t(8656),g=t(9972),C=t(5416),D=t(313),P=t(2565),j=t(810);t(5053),t(9569);const W=function(re){(0,g.default)(me,re);var oe=(0,C.default)(me);function me(){return(0,o.default)(this,me),oe.apply(this,arguments)}return(0,c.default)(me,[{key:"render",value:function(){var Dt,Ft,_e=this.props,Fe=_e.link,Re=_e.name,Le=(0,_e.getComponent)("Markdown",!0),we=Fe.get("operationId")||Fe.get("operationRef"),U=Fe.get("parameters")&&Fe.get("parameters").toJS(),pt=Fe.get("description");return j.default.createElement("div",{className:"operation-link"},j.default.createElement("div",{className:"description"},j.default.createElement("b",null,j.default.createElement("code",null,Re)),pt?j.default.createElement(Le,{source:pt}):null),j.default.createElement("pre",null,"Operation `",we,"`",j.default.createElement("br",null),j.default.createElement("br",null),"Parameters ",("string"!=typeof(Dt=(0,D.default)(U,null,2))?"":(0,P.default)(Ft=Dt.split("\n")).call(Ft,function(cn,kt){return kt>0?Array(1).join(" ")+cn:cn}).join("\n"))||"{}",j.default.createElement("br",null)))}}]),me}(j.Component)},6796:(n,s,t)=>{t.r(s),t.d(s,{default:()=>oe});var o=t(1013),c=t(7344),g=t(8656),C=t(6340),D=t(9972),P=t(5416),j=t(775),W=t(5171),re=t(810),oe=(t(5053),t(9569),function(me){(0,D.default)(Fe,me);var _e=(0,P.default)(Fe);function Fe(){var Re,Le;(0,c.default)(this,Fe);for(var we=arguments.length,U=new Array(we),pt=0;pt<we;pt++)U[pt]=arguments[pt];return Le=_e.call.apply(_e,(0,W.default)(Re=[this]).call(Re,U)),(0,j.default)((0,C.default)(Le),"setSelectedServer",function(ht){var Dt,Ft=Le.props,cn=Ft.path,kt=Ft.method;return Le.forceUpdate(),Le.props.setSelectedServer(ht,(0,W.default)(Dt="".concat(cn,":")).call(Dt,kt))}),(0,j.default)((0,C.default)(Le),"setServerVariableValue",function(ht){var Dt,Ft=Le.props,cn=Ft.path,kt=Ft.method;return Le.forceUpdate(),Le.props.setServerVariableValue((0,o.default)((0,o.default)({},ht),{},{namespace:(0,W.default)(Dt="".concat(cn,":")).call(Dt,kt)}))}),(0,j.default)((0,C.default)(Le),"getSelectedServer",function(){var ht,Dt=Le.props,cn=Dt.method;return Le.props.getSelectedServer((0,W.default)(ht="".concat(Dt.path,":")).call(ht,cn))}),(0,j.default)((0,C.default)(Le),"getServerVariable",function(ht,Dt){var Ft,cn=Le.props,wn=cn.method;return Le.props.getServerVariable({namespace:(0,W.default)(Ft="".concat(cn.path,":")).call(Ft,wn),server:ht},Dt)}),(0,j.default)((0,C.default)(Le),"getEffectiveServerValue",function(ht){var Dt,Ft=Le.props,kt=Ft.method;return Le.props.getEffectiveServerValue({server:ht,namespace:(0,W.default)(Dt="".concat(Ft.path,":")).call(Dt,kt)})}),Le}return(0,g.default)(Fe,[{key:"render",value:function(){var Re=this.props,Le=Re.operationServers,we=Re.pathServers;if(!Le&&!we)return null;var pt=(0,Re.getComponent)("Servers"),ht=Le||we,Dt=Le?"operation":"path";return re.default.createElement("div",{className:"opblock-section operation-servers"},re.default.createElement("div",{className:"opblock-section-header"},re.default.createElement("div",{className:"tab-header"},re.default.createElement("h4",{className:"opblock-title"},"Servers"))),re.default.createElement("div",{className:"opblock-description-wrapper"},re.default.createElement("h4",{className:"message"},"These ",Dt,"-level options override the global server options."),re.default.createElement(pt,{servers:ht,currentServer:this.getSelectedServer(),setSelectedServer:this.setSelectedServer,setServerVariableValue:this.setServerVariableValue,getServerVariable:this.getServerVariable,getEffectiveServerValue:this.getEffectiveServerValue})))}}]),Fe}(re.default.Component))},5327:(n,s,t)=>{t.r(s),t.d(s,{default:()=>me});var o=t(7344),c=t(8656),g=t(6340),C=t(9972),D=t(5416),P=t(775),j=t(810),W=(t(5053),t(8096)),re=t(6298),oe=Function.prototype,me=function(_e){(0,C.default)(Re,_e);var Fe=(0,D.default)(Re);function Re(Le,we){var U;return(0,o.default)(this,Re),U=Fe.call(this,Le,we),(0,P.default)((0,g.default)(U),"applyDefaultValue",function(pt){var ht=pt||U.props,Dt=ht.onChange,Ft=ht.defaultValue;return U.setState({value:Ft}),Dt(Ft)}),(0,P.default)((0,g.default)(U),"onChange",function(pt){U.props.onChange((0,re.Pz)(pt))}),(0,P.default)((0,g.default)(U),"onDomChange",function(pt){var ht=pt.target.value;U.setState({value:ht},function(){return U.onChange(ht)})}),U.state={value:(0,re.Pz)(Le.value)||Le.defaultValue},Le.onChange(Le.value),U}return(0,c.default)(Re,[{key:"UNSAFE_componentWillReceiveProps",value:function(Le){this.props.value!==Le.value&&Le.value!==this.state.value&&this.setState({value:(0,re.Pz)(Le.value)}),!Le.value&&Le.defaultValue&&this.state.value&&this.applyDefaultValue(Le)}},{key:"render",value:function(){var Le=this.props,U=Le.errors,pt=this.state.value,ht=U.size>0,Dt=(0,Le.getComponent)("TextArea");return j.default.createElement("div",{className:"body-param"},j.default.createElement(Dt,{className:(0,W.default)("body-param__text",{invalid:ht}),title:U.size?U.join(", "):"",value:pt,onChange:this.onDomChange}))}}]),Re}(j.PureComponent);(0,P.default)(me,"defaultProps",{onChange:oe,userHasEditedBody:!1})},2458:(n,s,t)=>{t.r(s),t.d(s,{getDefaultRequestBodyValue:()=>me,default:()=>_e});var o=t(9334),c=t(2565),g=t(8818),C=t(2372),D=t(5171),P=t(4163),j=t(810),W=(t(5053),t(9569),t(9725)),re=t(6298),oe=t(2518),me=function(Fe,Re,Le){var we=Fe.getIn(["content",Re]),U=we.get("schema").toJS(),pt=void 0!==we.get("examples"),ht=we.get("example"),Dt=pt?we.getIn(["examples",Le,"value"]):ht,Ft=(0,re.xi)(U,Re,{includeWriteOnly:!0},Dt);return(0,re.Pz)(Ft)};const _e=function(Fe){var Re=Fe.userHasEditedBody,Le=Fe.requestBody,we=Fe.requestBodyValue,U=Fe.requestBodyInclusionSetting,pt=Fe.requestBodyErrors,ht=Fe.getComponent,Dt=Fe.getConfigs,Ft=Fe.specSelectors,cn=Fe.fn,kt=Fe.contentType,wn=Fe.isExecute,Tn=Fe.specPath,Hr=Fe.onChange,sr=Fe.onChangeIncludeEmpty,Nr=Fe.activeExamplesKey,xr=Fe.updateActiveExamplesKey,fn=Fe.setRetainRequestBodyValueFlag,Rn=function(pr){var Vr={key:pr,shouldDispatchInit:!1,defaultValue:!0};return"no value"===U.get(pr,"no value")&&(Vr.shouldDispatchInit=!0),Vr},kn=ht("Markdown",!0),Wn=ht("modelExample"),bn=ht("RequestBodyEditor"),jr=ht("highlightCode"),ji=ht("ExamplesSelectValueRetainer"),oi=ht("Example"),Ui=ht("ParameterIncludeEmpty"),Xr=Dt().showCommonExtensions,Sn=Le&&Le.get("description")||null,hn=Le&&Le.get("content")||new W.OrderedMap;kt=kt||hn.keySeq().first()||"";var _r=hn.get(kt,(0,W.OrderedMap)()),Fi=_r.get("schema",(0,W.OrderedMap)()),_s=_r.get("examples",null),Ho=null==_s?void 0:(0,c.default)(_s).call(_s,function(pr,Vr){var Ri,Bs=null===(Ri=pr)||void 0===Ri?void 0:Ri.get("value",null);return Bs&&(pr=pr.set("value",me(Le,kt,Vr),Bs)),pr});if(pt=W.List.isList(pt)?pt:(0,W.List)(),!_r.size)return null;var yo="object"===_r.getIn(["schema","type"]),Us="binary"===_r.getIn(["schema","format"]),zs="base64"===_r.getIn(["schema","format"]);if("application/octet-stream"===kt||0===(0,g.default)(kt).call(kt,"image/")||0===(0,g.default)(kt).call(kt,"audio/")||0===(0,g.default)(kt).call(kt,"video/")||Us||zs){var Di=ht("Input");return wn?j.default.createElement(Di,{type:"file",onChange:function(pr){Hr(pr.target.files[0])}}):j.default.createElement("i",null,"Example values are not available for ",j.default.createElement("code",null,kt)," media types.")}if(yo&&("application/x-www-form-urlencoded"===kt||0===(0,g.default)(kt).call(kt,"multipart/"))&&Fi.get("properties",(0,W.OrderedMap)()).size>0){var oo,ho=ht("JsonSchemaForm"),Ze=ht("ParameterExt"),Mt=Fi.get("properties",(0,W.OrderedMap)());return we=W.Map.isMap(we)?we:(0,W.OrderedMap)(),j.default.createElement("div",{className:"table-container"},Sn&&j.default.createElement(kn,{source:Sn}),j.default.createElement("table",null,j.default.createElement("tbody",null,W.Map.isMap(Mt)&&(0,c.default)(oo=Mt.entrySeq()).call(oo,function(pr){var Vr,Ri,Bs=(0,o.default)(pr,2),Uo=Bs[0],ol=Bs[1];if(!ol.get("readOnly")){var ml=Xr?(0,re.po)(ol):null,tu=(0,C.default)(Vr=Fi.get("required",(0,W.List)())).call(Vr,Uo),qu=ol.get("type"),Lf=ol.get("format"),Fl=ol.get("description"),Kc=we.getIn([Uo,"value"]),cp=we.getIn([Uo,"errors"])||pt,Ah=U.get(Uo)||!1,Qp=ol.has("default")||ol.has("example")||ol.hasIn(["items","example"])||ol.hasIn(["items","default"]),Oh=ol.has("enum")&&(1===ol.get("enum").size||tu),nu=Qp||Oh,Yc="";"array"!==qu||nu||(Yc=[]),("object"===qu||nu)&&(Yc=(0,re.xi)(ol,!1,{includeWriteOnly:!0})),"string"!=typeof Yc&&"object"===qu&&(Yc=(0,re.Pz)(Yc)),"string"==typeof Yc&&"array"===qu&&(Yc=JSON.parse(Yc));var Lp="string"===qu&&("binary"===Lf||"base64"===Lf);return j.default.createElement("tr",{key:Uo,className:"parameters","data-property-name":Uo},j.default.createElement("td",{className:"parameters-col_name"},j.default.createElement("div",{className:tu?"parameter__name required":"parameter__name"},Uo,tu?j.default.createElement("span",null,"\xa0*"):null),j.default.createElement("div",{className:"parameter__type"},qu,Lf&&j.default.createElement("span",{className:"prop-format"},"($",Lf,")"),Xr&&ml.size?(0,c.default)(Ri=ml.entrySeq()).call(Ri,function(Yi){var or,yi=(0,o.default)(Yi,2),qi=yi[0],No=yi[1];return j.default.createElement(Ze,{key:(0,D.default)(or="".concat(qi,"-")).call(or,No),xKey:qi,xVal:No})}):null),j.default.createElement("div",{className:"parameter__deprecated"},ol.get("deprecated")?"deprecated":null)),j.default.createElement("td",{className:"parameters-col_description"},j.default.createElement(kn,{source:Fl}),wn?j.default.createElement("div",null,j.default.createElement(ho,{fn:cn,dispatchInitialValue:!Lp,schema:ol,description:Uo,getComponent:ht,value:void 0===Kc?Yc:Kc,required:tu,errors:cp,onChange:function(Yi){Hr(Yi,[Uo])}}),tu?null:j.default.createElement(Ui,{onChange:function(Yi){return sr(Uo,Yi)},isIncluded:Ah,isIncludedOptions:Rn(Uo),isDisabled:(0,P.default)(Kc)?0!==Kc.length:!(0,re.O2)(Kc)})):null))}}))))}var St=me(Le,kt,Nr),Un=null;return(0,oe.O)(St)&&(Un="json"),j.default.createElement("div",null,Sn&&j.default.createElement(kn,{source:Sn}),Ho?j.default.createElement(ji,{userHasEditedBody:Re,examples:Ho,currentKey:Nr,currentUserInputValue:we,onSelect:function(pr){xr(pr)},updateValue:Hr,defaultToFirstExample:!0,getComponent:ht,setRetainRequestBodyValueFlag:fn}):null,wn?j.default.createElement("div",null,j.default.createElement(bn,{value:we,errors:pt,defaultValue:St,onChange:Hr,getComponent:ht})):j.default.createElement(Wn,{getComponent:ht,getConfigs:Dt,specSelectors:Ft,expandDepth:1,isExecute:wn,schema:_r.get("schema"),specPath:Tn.push("content",kt),example:j.default.createElement(jr,{className:"body-param__example",getConfigs:Dt,language:Un,value:(0,re.Pz)(we)||St}),includeWriteOnly:!0}),Ho?j.default.createElement(oi,{example:Ho.get(Nr),getComponent:ht,getConfigs:Dt}):null)}},9928:(n,s,t)=>{t.r(s),t.d(s,{default:()=>P});var o=t(7344),c=t(8656),g=t(9972),C=t(5416),D=t(810),P=(t(5053),function(j){(0,g.default)(re,j);var W=(0,C.default)(re);function re(){return(0,o.default)(this,re),W.apply(this,arguments)}return(0,c.default)(re,[{key:"render",value:function(){var oe=this.props,_e=oe.oas3Selectors,Fe=oe.oas3Actions,Re=oe.getComponent,Le=oe.specSelectors.servers(),we=Re("Servers");return Le&&Le.size?D.default.createElement("div",null,D.default.createElement("span",{className:"servers-title"},"Servers"),D.default.createElement(we,{servers:Le,currentServer:_e.selectedServer(),setSelectedServer:Fe.setSelectedServer,setServerVariableValue:Fe.setServerVariableValue,getServerVariable:_e.serverVariableValue,getEffectiveServerValue:_e.serverEffectiveValue})):null}}]),re}(D.default.Component))},6617:(n,s,t)=>{t.r(s),t.d(s,{default:()=>Fe});var o=t(9334),c=t(7344),g=t(8656),C=t(6340),D=t(9972),P=t(5416),j=t(775),W=t(5171),re=t(1778),oe=t(2565),me=t(810),_e=t(9725),Fe=(t(5053),t(9569),function(Re){(0,D.default)(we,Re);var Le=(0,P.default)(we);function we(){var U,pt;(0,c.default)(this,we);for(var ht=arguments.length,Dt=new Array(ht),Ft=0;Ft<ht;Ft++)Dt[Ft]=arguments[Ft];return pt=Le.call.apply(Le,(0,W.default)(U=[this]).call(U,Dt)),(0,j.default)((0,C.default)(pt),"onServerChange",function(cn){pt.setServer(cn.target.value)}),(0,j.default)((0,C.default)(pt),"onServerVariableValueChange",function(cn){var kt=pt.props,wn=kt.setServerVariableValue,Tn=kt.currentServer,Hr=cn.target.getAttribute("data-variable");"function"==typeof wn&&wn({server:Tn,key:Hr,val:cn.target.value})}),(0,j.default)((0,C.default)(pt),"setServer",function(cn){(0,pt.props.setSelectedServer)(cn)}),pt}return(0,g.default)(we,[{key:"componentDidMount",value:function(){var U,pt=this.props;pt.currentServer||this.setServer(null===(U=pt.servers.first())||void 0===U?void 0:U.get("url"))}},{key:"UNSAFE_componentWillReceiveProps",value:function(U){var pt=this,ht=U.servers,Dt=U.setServerVariableValue,Ft=U.getServerVariable;if(this.props.currentServer!==U.currentServer||this.props.servers!==U.servers){var cn,kt=(0,re.default)(ht).call(ht,function(xr){return xr.get("url")===U.currentServer}),wn=(0,re.default)(cn=this.props.servers).call(cn,function(xr){return xr.get("url")===pt.props.currentServer})||(0,_e.OrderedMap)();if(!kt)return this.setServer(ht.first().get("url"));var Tn=wn.get("variables")||(0,_e.OrderedMap)(),Hr=((0,re.default)(Tn).call(Tn,function(xr){return xr.get("default")})||(0,_e.OrderedMap)()).get("default"),sr=kt.get("variables")||(0,_e.OrderedMap)(),Nr=((0,re.default)(sr).call(sr,function(xr){return xr.get("default")})||(0,_e.OrderedMap)()).get("default");(0,oe.default)(sr).call(sr,function(xr,fn){Ft(U.currentServer,fn)&&Hr===Nr||Dt({server:U.currentServer,key:fn,val:xr.get("default")||""})})}}},{key:"render",value:function(){var U,pt,ht=this,Dt=this.props,Ft=Dt.servers,cn=Dt.currentServer,kt=Dt.getServerVariable,wn=Dt.getEffectiveServerValue,Tn=((0,re.default)(Ft).call(Ft,function(sr){return sr.get("url")===cn})||(0,_e.OrderedMap)()).get("variables")||(0,_e.OrderedMap)(),Hr=0!==Tn.size;return me.default.createElement("div",{className:"servers"},me.default.createElement("label",{htmlFor:"servers"},me.default.createElement("select",{onChange:this.onServerChange,value:cn},(0,oe.default)(U=Ft.valueSeq()).call(U,function(sr){return me.default.createElement("option",{value:sr.get("url"),key:sr.get("url")},sr.get("url"),sr.get("description")&&" - ".concat(sr.get("description")))}).toArray())),Hr?me.default.createElement("div",null,me.default.createElement("div",{className:"computed-url"},"Computed URL:",me.default.createElement("code",null,wn(cn))),me.default.createElement("h4",null,"Server variables"),me.default.createElement("table",null,me.default.createElement("tbody",null,(0,oe.default)(pt=Tn.entrySeq()).call(pt,function(sr){var Nr,xr=(0,o.default)(sr,2),fn=xr[0],Rn=xr[1];return me.default.createElement("tr",{key:fn},me.default.createElement("td",null,fn),me.default.createElement("td",null,Rn.get("enum")?me.default.createElement("select",{"data-variable":fn,onChange:ht.onServerVariableValueChange},(0,oe.default)(Nr=Rn.get("enum")).call(Nr,function(kn){return me.default.createElement("option",{selected:kn===kt(cn,fn),key:kn,value:kn},kn)})):me.default.createElement("input",{type:"text",value:kt(cn,fn)||"",onChange:ht.onServerVariableValueChange,"data-variable":fn})))})))):null)}}]),we}(me.default.Component))},7779:(n,s,t)=>{t.r(s),t.d(s,{isOAS3:()=>C,isSwagger2:()=>D,OAS3ComponentWrapFactory:()=>P});var o=t(863),c=t(3590),g=t(810);function C(j){var W=j.get("openapi");return"string"==typeof W&&(0,c.default)(W).call(W,"3.0.")&&W.length>4}function D(j){var W=j.get("swagger");return"string"==typeof W&&(0,c.default)(W).call(W,"2.0")}function P(j){return function(W,re){return function(oe){return re&&re.specSelectors&&re.specSelectors.specJson?C(re.specSelectors.specJson())?g.default.createElement(j,(0,o.default)({},oe,re,{Ori:W})):g.default.createElement(W,oe):(console.warn("OAS3 wrapper: couldn't get spec"),null)}}}},7451:(n,s,t)=>{t.r(s),t.d(s,{default:()=>re});var o=t(2044),c=t(3723),g=t(1741),C=t(6467),D=t(7761),P=t(7002),j=t(5065),W=t(9666);function re(){return{components:C.default,wrapComponents:D.default,statePlugins:{spec:{wrapSelectors:o,selectors:g},auth:{wrapSelectors:c},oas3:{actions:P,reducers:W.default,selectors:j}}}}},9666:(n,s,t)=>{t.r(s),t.d(s,{default:()=>me});var o=t(775);const c=(t.d(Fe={},{default:()=>GR}),Fe);var Fe,g,C=t(9334),D=t(5487),P=t(8136),j=t(29),W=t(6785),re=t(9725),oe=t(7002);const me=((0,o.default)(g={},oe.UPDATE_SELECTED_SERVER,function(_e,Fe){var Re=Fe.payload,we=Re.namespace;return _e.setIn(we?[we,"selectedServer"]:["selectedServer"],Re.selectedServerUrl)}),(0,o.default)(g,oe.UPDATE_REQUEST_BODY_VALUE,function(_e,Fe){var Re=Fe.payload,Le=Re.value,U=(0,C.default)(Re.pathMethod,2),pt=U[0],ht=U[1];if(!re.Map.isMap(Le))return _e.setIn(["requestData",pt,ht,"bodyValue"],Le);var Dt,Ft=_e.getIn(["requestData",pt,ht,"bodyValue"])||(0,re.Map)();re.Map.isMap(Ft)||(Ft=(0,re.Map)());var cn=(0,D.default)(Le).call(Le),kt=(0,c.default)(cn),wn=(0,P.default)(kt).call(kt,0);return(0,j.default)(wn).call(wn,function(Tn){var Hr=Le.getIn([Tn]);Ft.has(Tn)&&re.Map.isMap(Hr)||(Dt=Ft.setIn([Tn,"value"],Hr))}),_e.setIn(["requestData",pt,ht,"bodyValue"],Dt)}),(0,o.default)(g,oe.UPDATE_REQUEST_BODY_VALUE_RETAIN_FLAG,function(_e,Fe){var Re=Fe.payload,Le=Re.value,U=(0,C.default)(Re.pathMethod,2);return _e.setIn(["requestData",U[0],U[1],"retainBodyValue"],Le)}),(0,o.default)(g,oe.UPDATE_REQUEST_BODY_INCLUSION,function(_e,Fe){var Re=Fe.payload,Le=Re.value,U=Re.name,pt=(0,C.default)(Re.pathMethod,2);return _e.setIn(["requestData",pt[0],pt[1],"bodyInclusion",U],Le)}),(0,o.default)(g,oe.UPDATE_ACTIVE_EXAMPLES_MEMBER,function(_e,Fe){var Re=Fe.payload,Le=Re.name,U=Re.contextType,pt=Re.contextName,ht=(0,C.default)(Re.pathMethod,2);return _e.setIn(["examples",ht[0],ht[1],U,pt,"activeExample"],Le)}),(0,o.default)(g,oe.UPDATE_REQUEST_CONTENT_TYPE,function(_e,Fe){var Re=Fe.payload,Le=Re.value,U=(0,C.default)(Re.pathMethod,2);return _e.setIn(["requestData",U[0],U[1],"requestContentType"],Le)}),(0,o.default)(g,oe.UPDATE_RESPONSE_CONTENT_TYPE,function(_e,Fe){var Re=Fe.payload;return _e.setIn(["requestData",Re.path,Re.method,"responseContentType"],Re.value)}),(0,o.default)(g,oe.UPDATE_SERVER_VARIABLE_VALUE,function(_e,Fe){var Re=Fe.payload,Le=Re.server,we=Re.namespace,U=Re.key;return _e.setIn(we?[we,"serverVariableValues",Le,U]:["serverVariableValues",Le,U],Re.val)}),(0,o.default)(g,oe.SET_REQUEST_BODY_VALIDATE_ERROR,function(_e,Fe){var Re=Fe.payload,Le=Re.path,we=Re.method,U=Re.validationErrors,pt=[];if(pt.push("Required field is not provided"),U.missingBodyValue)return _e.setIn(["requestData",Le,we,"errors"],(0,re.fromJS)(pt));if(U.missingRequiredKeys&&U.missingRequiredKeys.length>0){var ht=U.missingRequiredKeys;return _e.updateIn(["requestData",Le,we,"bodyValue"],(0,re.fromJS)({}),function(Dt){return(0,W.default)(ht).call(ht,function(Ft,cn){return Ft.setIn([cn,"errors"],(0,re.fromJS)(pt))},Dt)})}return console.warn("unexpected result: SET_REQUEST_BODY_VALIDATE_ERROR"),_e}),(0,o.default)(g,oe.CLEAR_REQUEST_BODY_VALIDATE_ERROR,function(_e,Fe){var Re=Fe.payload,Le=Re.path,we=Re.method,U=_e.getIn(["requestData",Le,we,"bodyValue"]);if(!re.Map.isMap(U))return _e.setIn(["requestData",Le,we,"errors"],(0,re.fromJS)([]));var pt=(0,D.default)(U).call(U),ht=(0,c.default)(pt),Dt=(0,P.default)(ht).call(ht,0);return Dt?_e.updateIn(["requestData",Le,we,"bodyValue"],(0,re.fromJS)({}),function(Ft){return(0,W.default)(Dt).call(Dt,function(cn,kt){return cn.setIn([kt,"errors"],(0,re.fromJS)([]))},Ft)}):_e}),(0,o.default)(g,oe.CLEAR_REQUEST_BODY_VALUE,function(_e,Fe){var Le=(0,C.default)(Fe.payload.pathMethod,2),we=Le[0],U=Le[1],pt=_e.getIn(["requestData",we,U,"bodyValue"]);return pt?re.Map.isMap(pt)?_e.setIn(["requestData",we,U,"bodyValue"],(0,re.Map)()):_e.setIn(["requestData",we,U,"bodyValue"],""):_e}),g)},5065:(n,s,t)=>{t.r(s),t.d(s,{selectedServer:()=>Fe,requestBodyValue:()=>Re,shouldRetainRequestBodyValue:()=>Le,hasUserEditedBody:()=>we,requestBodyInclusionSetting:()=>U,requestBodyErrors:()=>pt,activeExamplesMember:()=>ht,requestContentType:()=>Dt,responseContentType:()=>Ft,serverVariableValue:()=>cn,serverVariables:()=>kt,serverEffectiveValue:()=>wn,validateBeforeExecute:()=>Tn,validateShallowRequired:()=>Hr});var o=t(2691),c=t(5171),g=t(2565),C=t(29),D=t(2740),P=t(8818),j=t(9725),W=t(7779),re=t(2458),oe=t(6298);function me(sr){return function(){for(var Nr=arguments.length,xr=new Array(Nr),fn=0;fn<Nr;fn++)xr[fn]=arguments[fn];return function(Rn){var kn=Rn.getSystem().specSelectors.specJson();return(0,W.isOAS3)(kn)?sr.apply(void 0,xr):null}}}var _e,Fe=me(function(sr,Nr){return sr.getIn(Nr?[Nr,"selectedServer"]:["selectedServer"])||""}),Re=me(function(sr,Nr,xr){return sr.getIn(["requestData",Nr,xr,"bodyValue"])||null}),Le=me(function(sr,Nr,xr){return sr.getIn(["requestData",Nr,xr,"retainBodyValue"])||!1}),we=function(sr,Nr,xr){return function(fn){var Rn=fn.getSystem(),kn=Rn.oas3Selectors,Wn=Rn.specSelectors,bn=Wn.specJson();if((0,W.isOAS3)(bn)){var jr=!1,ji=kn.requestContentType(Nr,xr),oi=kn.requestBodyValue(Nr,xr);if(j.Map.isMap(oi)&&(oi=(0,oe.Pz)(oi.mapEntries(function(Xr){return j.Map.isMap(Xr[1])?[Xr[0],Xr[1].get("value")]:Xr}).toJS())),j.List.isList(oi)&&(oi=(0,oe.Pz)(oi)),ji){var Ui=(0,re.getDefaultRequestBodyValue)(Wn.specResolvedSubtree(["paths",Nr,xr,"requestBody"]),ji,kn.activeExamplesMember(Nr,xr,"requestBody","requestBody"));jr=!!oi&&oi!==Ui}return jr}return null}},U=me(function(sr,Nr,xr){return sr.getIn(["requestData",Nr,xr,"bodyInclusion"])||(0,j.Map)()}),pt=me(function(sr,Nr,xr){return sr.getIn(["requestData",Nr,xr,"errors"])||null}),ht=me(function(sr,Nr,xr,fn,Rn){return sr.getIn(["examples",Nr,xr,fn,Rn,"activeExample"])||null}),Dt=me(function(sr,Nr,xr){return sr.getIn(["requestData",Nr,xr,"requestContentType"])||null}),Ft=me(function(sr,Nr,xr){return sr.getIn(["requestData",Nr,xr,"responseContentType"])||null}),cn=me(function(sr,Nr,xr){var fn;if("string"!=typeof Nr){var Rn=Nr.server,kn=Nr.namespace;fn=kn?[kn,"serverVariableValues",Rn,xr]:["serverVariableValues",Rn,xr]}else fn=["serverVariableValues",Nr,xr];return sr.getIn(fn)||null}),kt=me(function(sr,Nr){var xr;if("string"!=typeof Nr){var fn=Nr.server,Rn=Nr.namespace;xr=Rn?[Rn,"serverVariableValues",fn]:["serverVariableValues",fn]}else xr=["serverVariableValues",Nr];return sr.getIn(xr)||(0,j.OrderedMap)()}),wn=me(function(sr,Nr){var xr,fn;if("string"!=typeof Nr){var kn=Nr.namespace;fn=Nr.server,xr=sr.getIn(kn?[kn,"serverVariableValues",fn]:["serverVariableValues",fn])}else xr=sr.getIn(["serverVariableValues",fn=Nr]);xr=xr||(0,j.OrderedMap)();var Wn=fn;return(0,g.default)(xr).call(xr,function(bn,jr){Wn=Wn.replace(new RegExp("{".concat(jr,"}"),"g"),bn)}),Wn}),Tn=(_e=function(sr,Nr){return fn=(fn=Nr)||[],!!sr.getIn((0,c.default)(Rn=["requestData"]).call(Rn,(0,o.default)(fn),["bodyValue"]));var fn,Rn},function(){for(var sr=arguments.length,Nr=new Array(sr),xr=0;xr<sr;xr++)Nr[xr]=arguments[xr];return function(fn){var Rn,kn,Wn=fn.getSystem().specSelectors.specJson(),bn=(0,c.default)(Rn=[]).call(Rn,Nr)[1]||[];return!Wn.getIn((0,c.default)(kn=["paths"]).call(kn,(0,o.default)(bn),["requestBody","required"]))||_e.apply(void 0,Nr)}}),Hr=function(sr,Nr){var xr,fn=Nr.oas3RequiredRequestBodyContentType,Rn=Nr.oas3RequestContentType,kn=Nr.oas3RequestBodyValue,Wn=[];if(!j.Map.isMap(kn))return Wn;var bn=[];return(0,C.default)(xr=(0,D.default)(fn.requestContentType)).call(xr,function(jr){if(jr===Rn){var ji=fn.requestContentType[jr];(0,C.default)(ji).call(ji,function(oi){(0,P.default)(bn).call(bn,oi)<0&&bn.push(oi)})}}),(0,C.default)(bn).call(bn,function(jr){kn.getIn([jr,"value"])||Wn.push(jr)}),Wn}},1741:(n,s,t)=>{t.r(s),t.d(s,{servers:()=>W,isSwagger2:()=>re});var C,o=t(8639),c=t(9725),g=t(7779),D=function(oe){return oe||(0,c.Map)()},P=(0,o.createSelector)(D,function(oe){return oe.get("json",(0,c.Map)())}),j=(0,o.createSelector)(D,function(oe){return oe.get("resolved",(0,c.Map)())}),W=(C=(0,o.createSelector)(function(oe){var me=j(oe);return me.count()<1&&(me=P(oe)),me},function(oe){return oe.getIn(["servers"])||(0,c.Map)()}),function(){return function(oe){var me=oe.getSystem().specSelectors.specJson();if((0,g.isOAS3)(me)){for(var _e=arguments.length,Fe=new Array(_e>1?_e-1:0),Re=1;Re<_e;Re++)Fe[Re-1]=arguments[Re];return C.apply(void 0,Fe)}return null}}),re=function(oe,me){return function(){var _e=me.getSystem().specSelectors.specJson();return(0,g.isSwagger2)(_e)}}},2044:(n,s,t)=>{t.r(s),t.d(s,{definitions:()=>me,hasHost:()=>_e,securityDefinitions:()=>Fe,host:()=>Re,basePath:()=>Le,consumes:()=>we,produces:()=>U,schemes:()=>pt,servers:()=>ht,isOAS3:()=>Dt,isSwagger2:()=>Ft});var o=t(8639),c=t(3881),g=t(9725),C=t(7779);function D(cn){return function(kt,wn){return function(){var Tn=wn.getSystem().specSelectors.specJson();return(0,C.isOAS3)(Tn)?cn.apply(void 0,arguments):kt.apply(void 0,arguments)}}}var P=function(cn){return cn||(0,g.Map)()},j=D((0,o.createSelector)(function(){return null})),W=(0,o.createSelector)(P,function(cn){return cn.get("json",(0,g.Map)())}),re=(0,o.createSelector)(P,function(cn){return cn.get("resolved",(0,g.Map)())}),oe=function(cn){var kt=re(cn);return kt.count()<1&&(kt=W(cn)),kt},me=D((0,o.createSelector)(oe,function(cn){var kt=cn.getIn(["components","schemas"]);return g.Map.isMap(kt)?kt:(0,g.Map)()})),_e=D(function(cn){return oe(cn).hasIn(["servers",0])}),Fe=D((0,o.createSelector)(c.specJsonWithResolvedSubtrees,function(cn){return cn.getIn(["components","securitySchemes"])||null})),Re=j,Le=j,we=j,U=j,pt=j,ht=D((0,o.createSelector)(oe,function(cn){return cn.getIn(["servers"])||(0,g.Map)()})),Dt=function(cn,kt){return function(){var wn=kt.getSystem().specSelectors.specJson();return(0,C.isOAS3)(g.Map.isMap(wn)?wn:(0,g.Map)())}},Ft=function(cn,kt){return function(){var wn=kt.getSystem().specSelectors.specJson();return(0,C.isSwagger2)(g.Map.isMap(wn)?wn:(0,g.Map)())}}},356:(n,s,t)=>{t.r(s),t.d(s,{default:()=>D});var o=t(302),c=t(810),g=t(7779),C=["Ori"];const D=(0,g.OAS3ComponentWrapFactory)(function(P){var j=P.Ori,W=(0,o.default)(P,C),re=W.schema,oe=W.getComponent,me=W.errSelectors,_e=W.authorized,Fe=W.onAuthChange,Re=W.name,Le=oe("HttpAuth");return"http"===re.get("type")?c.default.createElement(Le,{key:Re,schema:re,name:Re,errSelectors:me,authorized:_e,getComponent:oe,onChange:Fe}):c.default.createElement(j,W)})},7761:(n,s,t)=>{t.r(s),t.d(s,{default:()=>j});var o=t(2460),c=t(356),g=t(9487),C=t(58),D=t(3499),P=t(287);const j={Markdown:o.default,AuthItem:c.default,JsonSchema_string:P.default,VersionStamp:g.default,model:D.default,onlineValidatorBadge:C.default}},287:(n,s,t)=>{t.r(s),t.d(s,{default:()=>D});var o=t(302),c=t(810),g=t(7779),C=["Ori"];const D=(0,g.OAS3ComponentWrapFactory)(function(P){var j=P.Ori,W=(0,o.default)(P,C),re=W.schema,oe=W.getComponent,me=W.errors,_e=W.onChange,Fe=re&&re.get?re.get("format"):null,Re=re&&re.get?re.get("type"):null,Le=oe("Input");return Re&&"string"===Re&&Fe&&("binary"===Fe||"base64"===Fe)?c.default.createElement(Le,{type:"file",className:me.length?"invalid":"",title:me.length?me:"",onChange:function(we){_e(we.target.files[0])},disabled:j.isDisabled}):c.default.createElement(j,W)})},2460:(n,s,t)=>{t.r(s),t.d(s,{Markdown:()=>W,default:()=>re});var o=t(5942),c=t(810),g=(t(5053),t(8096)),C=t(3952),D=t(7779),P=t(5466),j=new C.Remarkable("commonmark");j.block.ruler.enable(["table"]),j.set({linkTarget:"_blank"});var W=function(oe){var me=oe.source,_e=oe.className,Fe=void 0===_e?"":_e;if("string"!=typeof me)return null;if(me){var Le,we=(0,oe.getConfigs)().useUnsafeMarkdown,U=j.render(me),pt=(0,P.s)(U,{useUnsafeMarkdown:we});return"string"==typeof pt&&(Le=(0,o.default)(pt).call(pt)),c.default.createElement("div",{dangerouslySetInnerHTML:{__html:Le},className:(0,g.default)(Fe,"renderedMarkdown")})}return null};W.defaultProps={getConfigs:function(){return{useUnsafeMarkdown:!1}}};const re=(0,D.OAS3ComponentWrapFactory)(W)},3499:(n,s,t)=>{t.r(s),t.d(s,{default:()=>oe});var o=t(863),c=t(7344),g=t(8656),C=t(9972),D=t(5416),P=t(810),j=(t(5053),t(7779)),W=t(1543),re=function(me){(0,C.default)(Fe,me);var _e=(0,D.default)(Fe);function Fe(){return(0,c.default)(this,Fe),_e.apply(this,arguments)}return(0,g.default)(Fe,[{key:"render",value:function(){var Re=this.props,Le=Re.getConfigs,we=["model-box"],U=null;return!0===Re.schema.get("deprecated")&&(we.push("deprecated"),U=P.default.createElement("span",{className:"model-deprecated-warning"},"Deprecated:")),P.default.createElement("div",{className:we.join(" ")},U,P.default.createElement(W.Z,(0,o.default)({},this.props,{getConfigs:Le,depth:1,expandDepth:this.props.expandDepth||0})))}}]),Fe}(P.Component);const oe=(0,j.OAS3ComponentWrapFactory)(re)},58:(n,s,t)=>{t.r(s),t.d(s,{default:()=>g});var o=t(7779),c=t(5623);const g=(0,o.OAS3ComponentWrapFactory)(c.Z)},9487:(n,s,t)=>{t.r(s),t.d(s,{default:()=>c});var o=t(810);const c=(0,t(7779).OAS3ComponentWrapFactory)(function(g){return o.default.createElement("span",null,o.default.createElement(g.Ori,g),o.default.createElement("small",{className:"version-stamp"},o.default.createElement("pre",{className:"version"},"OAS3")))})},8560:(n,s,t)=>{t.r(s),t.d(s,{default:()=>g});var o=t(6235),c=!1;function g(){return{statePlugins:{spec:{wrapActions:{updateSpec:function(C){return function(){return c=!0,C.apply(void 0,arguments)}},updateJsonSpec:function(C,D){return function(){var P=D.getConfigs().onComplete;return c&&"function"==typeof P&&((0,o.default)(P,0),c=!1),C.apply(void 0,arguments)}}}}}}}},4624:(n,s,t)=>{t.r(s),t.d(s,{requestSnippetGenerator_curl_bash:()=>Ft,requestSnippetGenerator_curl_cmd:()=>cn,requestSnippetGenerator_curl_powershell:()=>Dt});var o=t(2691),c=t(9334),g=t(3248),C=t(8818),D=t(5942),P=t(5171),j=t(313),W=t(2565);const re=(t.d(wn={},{default:()=>Gx()}),wn);var wn,oe=t(2954),me=t(2372),_e=t(7504),Fe=t(9725),Re=function(kt){var wn;return(0,C.default)(kt).call(kt,"_**[]")<0?kt:(0,D.default)(wn=kt.split("_**[]")[0]).call(wn)},Le=function(kt){return"-d "===kt||/^[_\/-]/g.test(kt)?kt:"'"+kt.replace(/'/g,"'\\''")+"'"},we=function(kt){return"-d "===(kt=kt.replace(/\^/g,"^^").replace(/\\"/g,'\\\\"').replace(/"/g,'""').replace(/\n/g,"^\n"))?kt.replace(/-d /g,"-d ^\n"):/^[_\/-]/g.test(kt)?kt:'"'+kt+'"'},U=function(kt){return"-d "===kt?kt:/\n/.test(kt)?'@"\n'+kt.replace(/"/g,'\\"').replace(/`/g,"``").replace(/\$/,"`$")+'\n"@':/^[_\/-]/g.test(kt)?kt:"'"+kt.replace(/"/g,'""').replace(/'/g,"''")+"'"};function pt(kt){var wn,Tn=[],Hr=(0,g.default)(kt.get("body").entrySeq());try{for(Hr.s();!(wn=Hr.n()).done;){var sr,Nr,xr,fn=(0,c.default)(wn.value,2),kn=fn[1],Wn=Re(fn[0]);Tn.push(kn instanceof _e.Z.File?(0,P.default)(sr=(0,P.default)(Nr=' "'.concat(Wn,'": {\n "name": "')).call(Nr,kn.name,'"')).call(sr,kn.type?',\n "type": "'.concat(kn.type,'"'):"","\n }"):(0,P.default)(xr=' "'.concat(Wn,'": ')).call(xr,(0,j.default)(kn,null,2).replace(/(\r\n|\r|\n)/g,"\n ")))}}catch(bn){Hr.e(bn)}finally{Hr.f()}return"{\n".concat(Tn.join(",\n"),"\n}")}var ht=function(kt,wn,Tn){var Hr=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"",sr=!1,Nr="",xr=function(){for(var St=arguments.length,Un=new Array(St),pr=0;pr<St;pr++)Un[pr]=arguments[pr];return Nr+=" "+(0,W.default)(Un).call(Un,wn).join(" ")},fn=function(){for(var St=arguments.length,Un=new Array(St),pr=0;pr<St;pr++)Un[pr]=arguments[pr];return Nr+=(0,W.default)(Un).call(Un,wn).join(" ")},Rn=function(){return Nr+=" ".concat(Tn)},kn=function(){var St,Un=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return Nr+=(0,re.default)(St=" ").call(St,Un)},Wn=kt.get("headers");if(Nr+="curl"+Hr,kt.has("curlOptions")&&xr.apply(void 0,(0,o.default)(kt.get("curlOptions"))),xr("-X",kt.get("method")),Rn(),kn(),fn("".concat(kt.get("url"))),Wn&&Wn.size){var bn,jr,ji=(0,g.default)((0,oe.default)(bn=kt.get("headers")).call(bn));try{for(ji.s();!(jr=ji.n()).done;){var oi,Ui=jr.value;Rn(),kn();var Xr=(0,c.default)(Ui,2),Sn=Xr[0],hn=Xr[1];fn("-H",(0,P.default)(oi="".concat(Sn,": ")).call(oi,hn)),sr=sr||/^content-type$/i.test(Sn)&&/^multipart\/form-data$/i.test(hn)}}catch(St){ji.e(St)}finally{ji.f()}}var _r,Fi=kt.get("body");if(Fi)if(sr&&(0,me.default)(_r=["POST","PUT","PATCH"]).call(_r,kt.get("method"))){var _s,Ho=(0,g.default)(Fi.entrySeq());try{for(Ho.s();!(_s=Ho.n()).done;){var yo,Us,zs,Di=(0,c.default)(_s.value,2),oo=Di[0],ho=Di[1],Ze=Re(oo);Rn(),kn(),fn("-F"),xr(ho instanceof _e.Z.File?(0,P.default)(yo=(0,P.default)(Us="".concat(Ze,"=@")).call(Us,ho.name)).call(yo,ho.type?";type=".concat(ho.type):""):(0,P.default)(zs="".concat(Ze,"=")).call(zs,ho))}}catch(St){Ho.e(St)}finally{Ho.f()}}else if(Fi instanceof _e.Z.File)Rn(),kn(),fn("--data-binary '@".concat(Fi.name,"'"));else{Rn(),kn(),fn("-d ");var Mt=Fi;Fe.Map.isMap(Mt)?fn(pt(kt)):("string"!=typeof Mt&&(Mt=(0,j.default)(Mt)),fn(Mt))}else Fi||"POST"!==kt.get("method")||(Rn(),kn(),fn("-d ''"));return Nr},Dt=function(kt){return ht(kt,U,"`\n",".exe")},Ft=function(kt){return ht(kt,Le,"\\\n")},cn=function(kt){return ht(kt,we,"^\n")}},6575:(n,s,t)=>{t.r(s),t.d(s,{default:()=>C});var o=t(4624),c=t(4669),g=t(4206);const C=function(){return{components:{RequestSnippets:g.default},fn:o,statePlugins:{requestSnippets:{selectors:c}}}}},4206:(n,s,t)=>{t.r(s),t.d(s,{default:()=>Fe});var o=t(9334),c=t(6145),g=t(8898),C=t(29),D=t(2565),P=t(810),j=(t(5053),t(9908)),W=t(7068),re=t(9874),oe=t(471),me={cursor:"pointer",lineHeight:1,display:"inline-flex",backgroundColor:"rgb(250, 250, 250)",paddingBottom:"0",paddingTop:"0",border:"1px solid rgb(51, 51, 51)",borderRadius:"4px 4px 0 0",boxShadow:"none",borderBottom:"none"},_e={cursor:"pointer",lineHeight:1,display:"inline-flex",backgroundColor:"rgb(51, 51, 51)",boxShadow:"none",border:"1px solid rgb(51, 51, 51)",paddingBottom:"0",paddingTop:"0",borderRadius:"4px 4px 0 0",marginTop:"-5px",marginRight:"-5px",marginLeft:"-5px",zIndex:"9999",borderBottom:"none"};const Fe=function(Re){var Le,we,U=Re.request,pt=Re.requestSnippetsSelectors,ht=Re.getConfigs,Dt=(0,W.default)(ht)?ht():null,Ft=!1!==(0,j.default)(Dt,"syntaxHighlight")&&(0,j.default)(Dt,"syntaxHighlight.activated",!0),cn=(0,P.useRef)(null),kt=(0,P.useState)(null===(Le=pt.getSnippetGenerators())||void 0===Le?void 0:Le.keySeq().first()),wn=(0,o.default)(kt,2),Tn=wn[0],Hr=wn[1],sr=(0,P.useState)(null==pt?void 0:pt.getDefaultExpanded()),Nr=(0,o.default)(sr,2),xr=Nr[0],fn=Nr[1];(0,P.useEffect)(function(){},[]),(0,P.useEffect)(function(){var Ui,Xr=(0,c.default)(Ui=(0,g.default)(cn.current.childNodes)).call(Ui,function(Sn){var hn;return!!Sn.nodeType&&(null===(hn=Sn.classList)||void 0===hn?void 0:hn.contains("curl-command"))});return(0,C.default)(Xr).call(Xr,function(Sn){return Sn.addEventListener("mousewheel",ji,{passive:!1})}),function(){(0,C.default)(Xr).call(Xr,function(Sn){return Sn.removeEventListener("mousewheel",ji)})}},[U]);var Rn=pt.getSnippetGenerators(),kn=Rn.get(Tn),Wn=kn.get("fn")(U),bn=function(){fn(!xr)},jr=function(Ui){return Ui===Tn?_e:me},ji=function(Ui){var Xr=Ui.target,Sn=Ui.deltaY,hn=Xr.scrollHeight,_r=Xr.offsetHeight,Fi=Xr.scrollTop;hn>_r&&(0===Fi&&Sn<0||_r+Fi>=hn&&Sn>0)&&Ui.preventDefault()},oi=Ft?P.default.createElement(oe.d3,{language:kn.get("syntax"),className:"curl microlight",style:(0,oe.C2)((0,j.default)(Dt,"syntaxHighlight.theme"))},Wn):P.default.createElement("textarea",{readOnly:!0,className:"curl",value:Wn});return P.default.createElement("div",{className:"request-snippets",ref:cn},P.default.createElement("div",{style:{width:"100%",display:"flex",justifyContent:"flex-start",alignItems:"center",marginBottom:"15px"}},P.default.createElement("h4",{onClick:function(){return bn()},style:{cursor:"pointer"}},"Snippets"),P.default.createElement("button",{onClick:function(){return bn()},style:{border:"none",background:"none"},title:xr?"Collapse operation":"Expand operation"},P.default.createElement("svg",{className:"arrow",width:"10",height:"10"},P.default.createElement("use",{href:xr?"#large-arrow-down":"#large-arrow",xlinkHref:xr?"#large-arrow-down":"#large-arrow"})))),xr&&P.default.createElement("div",{className:"curl-command"},P.default.createElement("div",{style:{paddingLeft:"15px",paddingRight:"10px",width:"100%",display:"flex"}},(0,D.default)(we=Rn.entrySeq()).call(we,function(Ui){var Xr=(0,o.default)(Ui,2),Sn=Xr[0],hn=Xr[1];return P.default.createElement("div",{style:jr(Sn),className:"btn",key:Sn,onClick:function(){var _r;Tn!==(_r=Sn)&&Hr(_r)}},P.default.createElement("h4",{style:Sn===Tn?{color:"white"}:{}},hn.get("title")))})),P.default.createElement("div",{className:"copy-to-clipboard"},P.default.createElement(re.CopyToClipboard,{text:Wn},P.default.createElement("button",null))),P.default.createElement("div",null,oi)))}},4669:(n,s,t)=>{t.r(s),t.d(s,{getGenerators:()=>j,getSnippetGenerators:()=>W,getActiveLanguage:()=>re,getDefaultExpanded:()=>oe});var o=t(6145),c=t(2372),g=t(2565),C=t(8639),D=t(9725),P=function(me){return me||(0,D.Map)()},j=(0,C.createSelector)(P,function(me){var _e=me.get("languages"),Fe=me.get("generators",(0,D.Map)());return!_e||_e.isEmpty()?Fe:(0,o.default)(Fe).call(Fe,function(Re,Le){return(0,c.default)(_e).call(_e,Le)})}),W=function(me){return function(_e){var Fe,Re,Le=_e.fn;return(0,o.default)(Fe=(0,g.default)(Re=j(me)).call(Re,function(we,U){var pt=Le["requestSnippetGenerator_".concat(U)];return"function"!=typeof pt?null:we.set("fn",pt)})).call(Fe,function(we){return we})}},re=(0,C.createSelector)(P,function(me){return me.get("activeLanguage")}),oe=(0,C.createSelector)(P,function(me){return me.get("defaultExpanded")})},6195:(n,s,t)=>{t.r(s),t.d(s,{ErrorBoundary:()=>re,default:()=>oe});var o=t(7344),c=t(8656),g=t(9972),C=t(5416),D=t(5171),P=(t(5053),t(810)),j=t(6189),W=t(9403),re=function(me){(0,g.default)(Fe,me);var _e=(0,C.default)(Fe);function Fe(){var Re,Le;(0,o.default)(this,Fe);for(var we=arguments.length,U=new Array(we),pt=0;pt<we;pt++)U[pt]=arguments[pt];return(Le=_e.call.apply(_e,(0,D.default)(Re=[this]).call(Re,U))).state={hasError:!1,error:null},Le}return(0,c.default)(Fe,[{key:"componentDidCatch",value:function(Re,Le){this.props.fn.componentDidCatch(Re,Le)}},{key:"render",value:function(){var Re=this.props,we=Re.targetName,U=Re.children;if(this.state.hasError){var pt=(0,Re.getComponent)("Fallback");return P.default.createElement(pt,{name:we})}return U}}],[{key:"getDerivedStateFromError",value:function(Re){return{hasError:!0,error:Re}}}]),Fe}(P.Component);re.defaultProps={targetName:"this component",getComponent:function(){return W.default},fn:{componentDidCatch:j.componentDidCatch},children:null};const oe=re},9403:(n,s,t)=>{t.r(s),t.d(s,{default:()=>c});var o=t(810);t(5053);const c=function(g){var C=g.name;return o.default.createElement("div",{className:"fallback"},"\u{1f631} ",o.default.createElement("i",null,"Could not render ","t"===C?"this component":C,", see the console."))}},6189:(n,s,t)=>{t.r(s),t.d(s,{componentDidCatch:()=>j,withErrorBoundary:()=>W});var o=t(863),c=t(7344),g=t(8656),C=t(9972),D=t(5416),P=t(810),j=console.error,W=function(re){return function(oe){var me,_e=re(),Fe=_e.getComponent,Re=_e.fn,Le=Fe("ErrorBoundary"),we=Re.getDisplayName(oe),U=function(pt){(0,C.default)(Dt,pt);var ht=(0,D.default)(Dt);function Dt(){return(0,c.default)(this,Dt),ht.apply(this,arguments)}return(0,g.default)(Dt,[{key:"render",value:function(){return P.default.createElement(Le,{targetName:we,getComponent:Fe,fn:Re},P.default.createElement(oe,(0,o.default)({},this.props,this.context)))}}]),Dt}(P.Component);return U.displayName="WithErrorBoundary(".concat(we,")"),(me=oe).prototype&&me.prototype.isReactComponent&&(U.prototype.mapStateToProps=oe.prototype.mapStateToProps),U}}},8102:(n,s,t)=>{t.r(s),t.d(s,{default:()=>W});var o=t(2691),c=t(5171);const g=(t.d(oe={},{default:()=>VR()}),oe),C=(re=>{var oe={};return t.d(oe,re),oe})({default:()=>Vx()});var oe,D=t(6195),P=t(9403),j=t(6189);const W=function(){var re=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},oe=re.componentList,me=void 0===oe?[]:oe,_e=re.fullOverride,Fe=void 0!==_e&&_e;return function(Re){var Le,we,U=Re.getSystem,pt=Fe?me:(0,c.default)(Le=[]).call(Le,["App","BaseLayout","VersionPragmaFilter","InfoContainer","ServersContainer","SchemesContainer","AuthorizeBtnContainer","FilterContainer","Operations","OperationContainer","parameters","responses","OperationServers","Models","ModelWrapper"],(0,o.default)(me)),ht=(0,C.default)(pt,(0,g.default)(we=Array(pt.length)).call(we,function(Dt,Ft){return Ft.fn.withErrorBoundary(Dt)}));return{fn:{componentDidCatch:j.componentDidCatch,withErrorBoundary:(0,j.withErrorBoundary)(U)},components:{ErrorBoundary:D.default,Fallback:P.default},wrapComponents:ht}}}},2473:(n,s,t)=>{t.r(s),t.d(s,{createXMLExample:()=>Nr,inferSchema:()=>sr,memoizedCreateXMLExample:()=>Rn,memoizedSampleFromSchema:()=>kn,sampleFromSchema:()=>xr,sampleFromSchemaGeneric:()=>Hr});var o=t(1581),c=t(5171),g=t(8818),C=t(29),D=t(4163),P=t(2372),j=t(9963),W=t(8136),re=t(1778),oe=t(2565),me=t(313),_e=t(3479),Fe=t.n(_e);const Re=(t.d(bn={},{default:()=>zM()}),bn),Le=(Wn=>{var bn={};return t.d(bn,Wn),bn})({default:()=>zE()});var bn,we=t(6298),U=t(8287),pt={string:function(Wn){return Wn.pattern?function(bn){try{return new Re.default(bn).gen()}catch(jr){return"string"}}(Wn.pattern):"string"},string_email:function(){return"user@example.com"},"string_date-time":function(){return(new Date).toISOString()},string_date:function(){return(new Date).toISOString().substring(0,10)},string_uuid:function(){return"3fa85f64-5717-4562-b3fc-2c963f66afa6"},string_hostname:function(){return"example.com"},string_ipv4:function(){return"198.51.100.42"},string_ipv6:function(){return"2001:0db8:5b96:0000:0000:426f:8e17:642a"},number:function(){return 0},number_float:function(){return 0},integer:function(){return 0},boolean:function(Wn){return"boolean"!=typeof Wn.default||Wn.default}},ht=function(Wn){var bn,jr=Wn=(0,we.mz)(Wn),ji=jr.type,oi=jr.format,Ui=pt[(0,c.default)(bn="".concat(ji,"_")).call(bn,oi)]||pt[ji];return(0,we.Wl)(Ui)?Ui(Wn):"Unknown Type: "+Wn.type},Dt=function(Wn){return(0,we.XV)(Wn,"$$ref",function(bn){return"string"==typeof bn&&(0,g.default)(bn).call(bn,"#")>-1})},Ft=["maxProperties","minProperties"],cn=["minItems","maxItems"],kt=["minimum","maximum","exclusiveMinimum","exclusiveMaximum"],wn=["minLength","maxLength"],Tn=function Wn(bn,jr){var ji,oi,Ui,Xr=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},Sn=function(_s){void 0===jr[_s]&&void 0!==bn[_s]&&(jr[_s]=bn[_s])};if((0,C.default)(ji=(0,c.default)(oi=["example","default","enum","xml","type"]).call(oi,Ft,cn,kt,wn)).call(ji,function(_s){return Sn(_s)}),void 0!==bn.required&&(0,D.default)(bn.required)&&(void 0!==jr.required&&jr.required.length||(jr.required=[]),(0,C.default)(Ui=bn.required).call(Ui,function(_s){var Ho;(0,P.default)(Ho=jr.required).call(Ho,_s)||jr.required.push(_s)})),bn.properties){jr.properties||(jr.properties={});var hn=(0,we.mz)(bn.properties);for(var _r in hn){var Fi;Object.prototype.hasOwnProperty.call(hn,_r)&&(!hn[_r]||!hn[_r].deprecated)&&(!hn[_r]||!hn[_r].readOnly||Xr.includeReadOnly)&&(!hn[_r]||!hn[_r].writeOnly||Xr.includeWriteOnly)&&(jr.properties[_r]||(jr.properties[_r]=hn[_r],!bn.required&&(0,D.default)(bn.required)&&-1!==(0,g.default)(Fi=bn.required).call(Fi,_r)&&(jr.required?jr.required.push(_r):jr.required=[_r])))}}return bn.items&&(jr.items||(jr.items={}),jr.items=Wn(bn.items,jr.items,Xr)),jr},Hr=function Wn(bn){var jr=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},ji=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,oi=arguments.length>3&&void 0!==arguments[3]&&arguments[3];bn&&(0,we.Wl)(bn.toJS)&&(bn=bn.toJS());var Ui=void 0!==ji||bn&&void 0!==bn.example||bn&&void 0!==bn.default,Xr=!Ui&&bn&&bn.oneOf&&bn.oneOf.length>0,Sn=!Ui&&bn&&bn.anyOf&&bn.anyOf.length>0;if(!Ui&&(Xr||Sn)){var hn=(0,we.mz)(Xr?bn.oneOf[0]:bn.anyOf[0]);if(Tn(hn,bn,jr),!bn.xml&&hn.xml&&(bn.xml=hn.xml),void 0!==bn.example&&void 0!==hn.example)Ui=!0;else if(hn.properties){bn.properties||(bn.properties={});var _r=(0,we.mz)(hn.properties);for(var Fi in _r){var _s;Object.prototype.hasOwnProperty.call(_r,Fi)&&(!_r[Fi]||!_r[Fi].deprecated)&&(!_r[Fi]||!_r[Fi].readOnly||jr.includeReadOnly)&&(!_r[Fi]||!_r[Fi].writeOnly||jr.includeWriteOnly)&&(bn.properties[Fi]||(bn.properties[Fi]=_r[Fi],!hn.required&&(0,D.default)(hn.required)&&-1!==(0,g.default)(_s=hn.required).call(_s,Fi)&&(bn.required?bn.required.push(Fi):bn.required=[Fi])))}}}var Ho,yo={},Us=bn||{},zs=Us.xml,Di=Us.type,oo=Us.example,ho=Us.properties,Ze=Us.additionalProperties,Mt=Us.items,St=jr.includeReadOnly,Un=jr.includeWriteOnly,pr=zs=zs||{},Vr=pr.name,Ri=pr.prefix,Bs=pr.namespace,Uo={};if(oi&&(Ho=(Ri?Ri+":":"")+(Vr=Vr||"notagname"),Bs)){var ol=Ri?"xmlns:"+Ri:"xmlns";yo[ol]=Bs}oi&&(Uo[Ho]=[]);var ml=function(Zi){return(0,j.default)(Zi).call(Zi,function(As){return Object.prototype.hasOwnProperty.call(bn,As)})};bn&&!Di&&(ho||Ze||ml(Ft)?Di="object":Mt||ml(cn)?Di="array":ml(kt)?(Di="number",bn.type="number"):Ui||bn.enum||(Di="string",bn.type="string"));var tu,qu,Lf=function(Zi){var As,es,fu,Ml,Ai;if(null!==(null===(As=bn)||void 0===As?void 0:As.maxItems)&&void 0!==(null===(es=bn)||void 0===es?void 0:es.maxItems)&&(Zi=(0,W.default)(Zi).call(Zi,0,null===(Ai=bn)||void 0===Ai?void 0:Ai.maxItems)),null!==(null===(fu=bn)||void 0===fu?void 0:fu.minItems)&&void 0!==(null===(Ml=bn)||void 0===Ml?void 0:Ml.minItems))for(var qa=0;Zi.length<(null===(Ba=bn)||void 0===Ba?void 0:Ba.minItems);){var Ba;Zi.push(Zi[qa++%Zi.length])}return Zi},Fl=(0,we.mz)(ho),Kc=0,cp=function(){return bn&&null!=bn.maxProperties&&Kc>=bn.maxProperties},Ah=function(){if(!bn||!bn.required)return 0;var Zi,As,es=0;return oi?(0,C.default)(Zi=bn.required).call(Zi,function(fu){return es+=void 0===Uo[fu]?0:1}):(0,C.default)(As=bn.required).call(As,function(fu){var Ml;return es+=void 0===(null===(Ml=Uo[Ho])||void 0===Ml?void 0:(0,re.default)(Ml).call(Ml,function(Ai){return void 0!==Ai[fu]}))?0:1}),bn.required.length-es},Qp=function(Zi){var As;return!(bn&&bn.required&&bn.required.length&&(0,P.default)(As=bn.required).call(As,Zi))},Oh=function(Zi){return!bn||null==bn.maxProperties||!cp()&&(!Qp(Zi)||bn.maxProperties-Kc-Ah()>0)};if(tu=oi?function(Zi){var As=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0;if(bn&&Fl[Zi]){if(Fl[Zi].xml=Fl[Zi].xml||{},Fl[Zi].xml.attribute){var es=(0,D.default)(Fl[Zi].enum)?Fl[Zi].enum[0]:void 0,fu=Fl[Zi].example,Ml=Fl[Zi].default;return void(yo[Fl[Zi].xml.name||Zi]=void 0!==fu?fu:void 0!==Ml?Ml:void 0!==es?es:ht(Fl[Zi]))}Fl[Zi].xml.name=Fl[Zi].xml.name||Zi}else Fl[Zi]||!1===Ze||(Fl[Zi]={xml:{name:Zi}});var Ai,qa=Wn(bn&&Fl[Zi]||void 0,jr,As,oi);Oh(Zi)&&(Kc++,(0,D.default)(qa)?Uo[Ho]=(0,c.default)(Ai=Uo[Ho]).call(Ai,qa):Uo[Ho].push(qa))}:function(Zi,As){Oh(Zi)&&(Uo[Zi]=Wn(Fl[Zi],jr,As,oi),Kc++)},Ui){var nu;if(nu=Dt(void 0!==ji?ji:void 0!==oo?oo:bn.default),!oi){if("number"==typeof nu&&"string"===Di)return"".concat(nu);if("string"!=typeof nu||"string"===Di)return nu;try{return JSON.parse(nu)}catch(Zi){return nu}}if(bn||(Di=(0,D.default)(nu)?"array":(0,o.default)(nu)),"array"===Di){if(!(0,D.default)(nu)){if("string"==typeof nu)return nu;nu=[nu]}var Yc=bn?bn.items:void 0;Yc&&(Yc.xml=Yc.xml||zs||{},Yc.xml.name=Yc.xml.name||zs.name);var Lp=(0,oe.default)(nu).call(nu,function(Zi){return Wn(Yc,jr,Zi,oi)});return Lp=Lf(Lp),zs.wrapped?(Uo[Ho]=Lp,(0,Le.default)(yo)||Uo[Ho].push({_attr:yo})):Uo=Lp,Uo}if("object"===Di){if("string"==typeof nu)return nu;for(var Yi in nu)Object.prototype.hasOwnProperty.call(nu,Yi)&&(bn&&Fl[Yi]&&Fl[Yi].readOnly&&!St||bn&&Fl[Yi]&&Fl[Yi].writeOnly&&!Un||(bn&&Fl[Yi]&&Fl[Yi].xml&&Fl[Yi].xml.attribute?yo[Fl[Yi].xml.name||Yi]=nu[Yi]:tu(Yi,nu[Yi])));return(0,Le.default)(yo)||Uo[Ho].push({_attr:yo}),Uo}return Uo[Ho]=(0,Le.default)(yo)?nu:[{_attr:yo},nu],Uo}if("object"===Di){for(var or in Fl)Object.prototype.hasOwnProperty.call(Fl,or)&&(Fl[or]&&Fl[or].deprecated||Fl[or]&&Fl[or].readOnly&&!St||Fl[or]&&Fl[or].writeOnly&&!Un||tu(or));if(oi&&yo&&Uo[Ho].push({_attr:yo}),cp())return Uo;if(!0===Ze)oi?Uo[Ho].push({additionalProp:"Anything can be here"}):Uo.additionalProp1={},Kc++;else if(Ze){var yi=(0,we.mz)(Ze),qi=Wn(yi,jr,void 0,oi);if(oi&&yi.xml&&yi.xml.name&&"notagname"!==yi.xml.name)Uo[Ho].push(qi);else for(var No=null!=bn.minProperties&&Kc<bn.minProperties?bn.minProperties-Kc:3,Wo=1;Wo<=No;Wo++){if(cp())return Uo;if(oi){var qo={};qo["additionalProp"+Wo]=qi.notagname,Uo[Ho].push(qo)}else Uo["additionalProp"+Wo]=qi;Kc++}}return Uo}if("array"===Di){if(!Mt)return;var is,_a,Ka;if(oi&&(Mt.xml=Mt.xml||(null===(_a=bn)||void 0===_a?void 0:_a.xml)||{},Mt.xml.name=Mt.xml.name||zs.name),(0,D.default)(Mt.anyOf))is=(0,oe.default)(Ka=Mt.anyOf).call(Ka,function(Zi){return Wn(Tn(Mt,Zi,jr),jr,void 0,oi)});else if((0,D.default)(Mt.oneOf)){var Du;is=(0,oe.default)(Du=Mt.oneOf).call(Du,function(Zi){return Wn(Tn(Mt,Zi,jr),jr,void 0,oi)})}else{if(!(!oi||oi&&zs.wrapped))return Wn(Mt,jr,void 0,oi);is=[Wn(Mt,jr,void 0,oi)]}return is=Lf(is),oi&&zs.wrapped?(Uo[Ho]=is,(0,Le.default)(yo)||Uo[Ho].push({_attr:yo}),Uo):is}if(bn&&(0,D.default)(bn.enum))qu=(0,we.AF)(bn.enum)[0];else{if(!bn)return;if("number"==typeof(qu=ht(bn))){var Qn=bn.minimum;null!=Qn&&(bn.exclusiveMinimum&&Qn++,qu=Qn);var Ii=bn.maximum;null!=Ii&&(bn.exclusiveMaximum&&Ii--,qu=Ii)}if("string"==typeof qu&&(null!=bn.maxLength&&(qu=(0,W.default)(qu).call(qu,0,bn.maxLength)),null!=bn.minLength))for(var rs=0;qu.length<bn.minLength;)qu+=qu[rs++%qu.length]}if("file"!==Di)return oi?(Uo[Ho]=(0,Le.default)(yo)?qu:[{_attr:yo},qu],Uo):qu},sr=function(Wn){return Wn.schema&&(Wn=Wn.schema),Wn.properties&&(Wn.type="object"),Wn},Nr=function(Wn,bn,jr){var ji=Hr(Wn,bn,jr,!0);if(ji)return"string"==typeof ji?ji:Fe()(ji,{declaration:!0,indent:"\t"})},xr=function(Wn,bn,jr){return Hr(Wn,bn,jr,!1)},fn=function(Wn,bn,jr){return[Wn,(0,me.default)(bn),(0,me.default)(jr)]},Rn=(0,U.Z)(Nr,fn),kn=(0,U.Z)(xr,fn)},8883:(n,s,t)=>{t.r(s),t.d(s,{default:()=>c});var o=t(2473);function c(){return{fn:o}}},1737:(n,s,t)=>{t.r(s),t.d(s,{CLEAR_REQUEST:()=>hn,CLEAR_RESPONSE:()=>Sn,CLEAR_VALIDATE_PARAMS:()=>_r,LOG_REQUEST:()=>Xr,SET_MUTATED_REQUEST:()=>Ui,SET_REQUEST:()=>oi,SET_RESPONSE:()=>ji,SET_SCHEME:()=>yo,UPDATE_EMPTY_PARAM_INCLUSION:()=>bn,UPDATE_JSON:()=>kn,UPDATE_OPERATION_META_VALUE:()=>Fi,UPDATE_PARAM:()=>Wn,UPDATE_RESOLVED:()=>_s,UPDATE_RESOLVED_SUBTREE:()=>Ho,UPDATE_SPEC:()=>fn,UPDATE_URL:()=>Rn,VALIDATE_PARAMS:()=>jr,changeConsumesValue:()=>qu,changeParam:()=>Vr,changeParamByIdentity:()=>Ri,changeProducesValue:()=>Lf,clearRequest:()=>Yc,clearResponse:()=>nu,clearValidateParams:()=>tu,execute:()=>Oh,executeRequest:()=>Qp,invalidateResolvedSubtreeCache:()=>Uo,logRequest:()=>Ah,parseToJson:()=>ho,requestResolvedSubtree:()=>pr,resolveSpec:()=>Mt,setMutatedRequest:()=>cp,setRequest:()=>Kc,setResponse:()=>Fl,setScheme:()=>Lp,updateEmptyParamInclusion:()=>ml,updateJsonSpec:()=>oo,updateResolved:()=>zs,updateResolvedSubtree:()=>Bs,updateSpec:()=>Us,updateUrl:()=>Di,validateParams:()=>ol});var o=t(1013),c=t(302);const g=(t.d(or={},{default:()=>z1}),or);var or,C=t(1581);const D=(Yi=>{var or={};return t.d(or,Yi),or})({default:()=>e_()});var P=t(4163),j=t(2565),W=t(3978),re=t.n(W),oe=t(6785),me=t(7930);const _e=(Yi=>{var or={};return t.d(or,Yi),or})({default:()=>lm()});var Fe=t(6145),Re=t(374),Le=t(8818),we=t(29),U=t(5171),pt=t(2740),ht=t(7512);const Dt=(Yi=>{var or={};return t.d(or,Yi),or})({default:()=>Jx()});var Ft=t(626),cn=t(9725),kt=t(8900),wn=t(8518);const Tn=(Yi=>{var or={};return t.d(or,Yi),or})({default:()=>W1()}),Hr=(Yi=>{var or={};return t.d(or,Yi),or})({default:()=>XM()}),sr=(Yi=>{var or={};return t.d(or,Yi),or})({default:()=>qM()});var Nr=t(6298),xr=["path","method"],fn="spec_update_spec",Rn="spec_update_url",kn="spec_update_json",Wn="spec_update_param",bn="spec_update_empty_param_inclusion",jr="spec_validate_param",ji="spec_set_response",oi="spec_set_request",Ui="spec_set_mutated_request",Xr="spec_log_request",Sn="spec_clear_response",hn="spec_clear_request",_r="spec_clear_validate_param",Fi="spec_update_operation_meta_value",_s="spec_update_resolved",Ho="spec_update_resolved_subtree",yo="set_scheme";function Us(Yi){var or,yi=(or=Yi,(0,Tn.default)(or)?or:"").replace(/\t/g," ");if("string"==typeof Yi)return{type:fn,payload:yi}}function zs(Yi){return{type:_s,payload:Yi}}function Di(Yi){return{type:Rn,payload:Yi}}function oo(Yi){return{type:kn,payload:Yi}}var ho=function(Yi){return function(or){var yi=or.specActions,No=or.errActions,Wo=or.specSelectors.specStr,qo=null;try{Yi=Yi||Wo(),No.clear({source:"parser"}),qo=Ft.default.load(Yi,{schema:Ft.JSON_SCHEMA})}catch(is){return console.error(is),No.newSpecErr({source:"parser",level:"error",message:is.reason,line:is.mark&&is.mark.line?is.mark.line+1:void 0})}return qo&&"object"===(0,C.default)(qo)?yi.updateJsonSpec(qo):{}}},Ze=!1,Mt=function(Yi,or){return function(yi){var qi=yi.specActions,No=yi.specSelectors,Wo=yi.errActions,qo=yi.fn,is=qo.fetch,_a=qo.resolve,Ka=qo.AST,Du=void 0===Ka?{}:Ka,Qn=yi.getConfigs;Ze||(console.warn("specActions.resolveSpec is deprecated since v3.10.0 and will be removed in v4.0.0; use requestResolvedSubtree instead!"),Ze=!0);var Ii=Qn(),rs=Ii.modelPropertyMacro,Zi=Ii.parameterMacro,As=Ii.requestInterceptor,es=Ii.responseInterceptor;void 0===Yi&&(Yi=No.specJson()),void 0===or&&(or=No.url());var fu=Du.getLineNumberForPath?Du.getLineNumberForPath:function(){},Ml=No.specStr();return _a({fetch:is,spec:Yi,baseDoc:or,modelPropertyMacro:rs,parameterMacro:Zi,requestInterceptor:As,responseInterceptor:es}).then(function(Ai){var qa=Ai.spec,Ba=Ai.errors;if(Wo.clear({type:"thrown"}),(0,P.default)(Ba)&&Ba.length>0){var ec=(0,j.default)(Ba).call(Ba,function(Ru){return console.error(Ru),Ru.line=Ru.fullPath?fu(Ml,Ru.fullPath):null,Ru.path=Ru.fullPath?Ru.fullPath.join("."):null,Ru.level="error",Ru.type="thrown",Ru.source="resolver",re()(Ru,"message",{enumerable:!0,value:Ru.message}),Ru});Wo.newThrownErrBatch(ec)}return qi.updateResolved(qa)})}},St=[],Un=(0,Hr.default)((0,g.default)(D.default.mark(function Yi(){var or,yi,qi,No,Wo,qo,is,_a,Ka,Du,Qn,Ii,rs,Zi,As,es,fu,Ml;return D.default.wrap(function(Ai){for(;;)switch(Ai.prev=Ai.next){case 0:if(or=St.system){Ai.next=4;break}return console.error("debResolveSubtrees: don't have a system to operate on, aborting."),Ai.abrupt("return");case 4:if(yi=or.errActions,qi=or.errSelectors,qo=(No=or.fn).fetch,_a=void 0===(is=No.AST)?{}:is,Ka=or.specSelectors,Du=or.specActions,Wo=No.resolveSubtree){Ai.next=8;break}return console.error("Error: Swagger-Client did not provide a `resolveSubtree` method, doing nothing."),Ai.abrupt("return");case 8:return Qn=_a.getLineNumberForPath?_a.getLineNumberForPath:function(){},Ii=Ka.specStr(),rs=or.getConfigs(),Zi=rs.modelPropertyMacro,As=rs.parameterMacro,es=rs.requestInterceptor,fu=rs.responseInterceptor,Ai.prev=11,Ai.next=14,(0,oe.default)(St).call(St,function(){var qa=(0,g.default)(D.default.mark(function Ba(ec,Ru){var Ff,Xp,Wl,Qf,cg,Kp,Lg,I_,t1;return D.default.wrap(function(qp){for(;;)switch(qp.prev=qp.next){case 0:return qp.next=2,ec;case 2:return Xp=(Ff=qp.sent).resultMap,Wl=Ff.specWithCurrentSubtrees,qp.next=7,Wo(Wl,Ru,{baseDoc:Ka.url(),modelPropertyMacro:Zi,parameterMacro:As,requestInterceptor:es,responseInterceptor:fu});case 7:if(cg=(Qf=qp.sent).errors,Kp=Qf.spec,qi.allErrors().size&&yi.clearBy(function(_d){var Fg;return"thrown"!==_d.get("type")||"resolver"!==_d.get("source")||!(0,me.default)(Fg=_d.get("fullPath")).call(Fg,function(gm,dg){return gm===Ru[dg]||void 0===Ru[dg]})}),(0,P.default)(cg)&&cg.length>0&&(Lg=(0,j.default)(cg).call(cg,function(_d){return _d.line=_d.fullPath?Qn(Ii,_d.fullPath):null,_d.path=_d.fullPath?_d.fullPath.join("."):null,_d.level="error",_d.type="thrown",_d.source="resolver",re()(_d,"message",{enumerable:!0,value:_d.message}),_d}),yi.newThrownErrBatch(Lg)),!Kp||!Ka.isOAS3()||"components"!==Ru[0]||"securitySchemes"!==Ru[1]){qp.next=15;break}return qp.next=15,_e.default.all((0,j.default)(I_=(0,Fe.default)(t1=(0,Re.default)(Kp)).call(t1,function(_d){return"openIdConnect"===_d.type})).call(I_,function(){var _d=(0,g.default)(D.default.mark(function Fg(gm){var dg,nv;return D.default.wrap(function(Fp){for(;;)switch(Fp.prev=Fp.next){case 0:return dg={url:gm.openIdConnectUrl,requestInterceptor:es,responseInterceptor:fu},Fp.prev=1,Fp.next=4,qo(dg);case 4:(nv=Fp.sent)instanceof Error||nv.status>=400?console.error(nv.statusText+" "+dg.url):gm.openIdConnectData=JSON.parse(nv.text),Fp.next=11;break;case 8:Fp.prev=8,Fp.t0=Fp.catch(1),console.error(Fp.t0);case 11:case"end":return Fp.stop()}},Fg,null,[[1,8]])}));return function(Fg){return _d.apply(this,arguments)}}()));case 15:return(0,sr.default)(Xp,Ru,Kp),(0,sr.default)(Wl,Ru,Kp),qp.abrupt("return",{resultMap:Xp,specWithCurrentSubtrees:Wl});case 18:case"end":return qp.stop()}},Ba)}));return function(Ba,ec){return qa.apply(this,arguments)}}(),_e.default.resolve({resultMap:(Ka.specResolvedSubtree([])||(0,cn.Map)()).toJS(),specWithCurrentSubtrees:Ka.specJson().toJS()}));case 14:Ml=Ai.sent,delete St.system,St=[],Ai.next=22;break;case 19:Ai.prev=19,Ai.t0=Ai.catch(11),console.error(Ai.t0);case 22:Du.updateResolvedSubtree([],Ml.resultMap);case 23:case"end":return Ai.stop()}},Yi,null,[[11,19]])})),35),pr=function(Yi){return function(or){var yi;(0,Le.default)(yi=(0,j.default)(St).call(St,function(qi){return qi.join("@@")})).call(yi,Yi.join("@@"))>-1||(St.push(Yi),St.system=or,Un())}};function Vr(Yi,or,yi,qi,No){return{type:Wn,payload:{path:Yi,value:qi,paramName:or,paramIn:yi,isXml:No}}}function Ri(Yi,or,yi,qi){return{type:Wn,payload:{path:Yi,param:or,value:yi,isXml:qi}}}var Bs=function(Yi,or){return{type:Ho,payload:{path:Yi,value:or}}},Uo=function(){return{type:Ho,payload:{path:[],value:(0,cn.Map)()}}},ol=function(Yi,or){return{type:jr,payload:{pathMethod:Yi,isOAS3:or}}},ml=function(Yi,or,yi,qi){return{type:bn,payload:{pathMethod:Yi,paramName:or,paramIn:yi,includeEmptyValue:qi}}};function tu(Yi){return{type:_r,payload:{pathMethod:Yi}}}function qu(Yi,or){return{type:Fi,payload:{path:Yi,value:or,key:"consumes_value"}}}function Lf(Yi,or){return{type:Fi,payload:{path:Yi,value:or,key:"produces_value"}}}var Fl=function(Yi,or,yi){return{payload:{path:Yi,method:or,res:yi},type:ji}},Kc=function(Yi,or,yi){return{payload:{path:Yi,method:or,req:yi},type:oi}},cp=function(Yi,or,yi){return{payload:{path:Yi,method:or,req:yi},type:Ui}},Ah=function(Yi){return{payload:Yi,type:Xr}},Qp=function(Yi){return function(or){var yi,qi,No=or.fn,Wo=or.specActions,qo=or.specSelectors,_a=or.oas3Selectors,Ka=Yi.pathName,Du=Yi.method,Qn=Yi.operation,Ii=(0,or.getConfigs)(),rs=Ii.requestInterceptor,Zi=Ii.responseInterceptor,As=Qn.toJS();if(Qn&&Qn.get("parameters")&&(0,we.default)(yi=(0,Fe.default)(qi=Qn.get("parameters")).call(qi,function(Wl){return Wl&&!0===Wl.get("allowEmptyValue")})).call(yi,function(Wl){if(qo.parameterInclusionSettingFor([Ka,Du],Wl.get("name"),Wl.get("in"))){Yi.parameters=Yi.parameters||{};var Qf=(0,Nr.cz)(Wl,Yi.parameters);(!Qf||Qf&&0===Qf.size)&&(Yi.parameters[Wl.get("name")]="")}}),Yi.contextUrl=(0,kt.default)(qo.url()).toString(),As&&As.operationId?Yi.operationId=As.operationId:As&&Ka&&Du&&(Yi.operationId=No.opId(As,Ka,Du)),qo.isOAS3()){var es,fu=(0,U.default)(es="".concat(Ka,":")).call(es,Du);Yi.server=_a.selectedServer(fu)||_a.selectedServer();var Ml=_a.serverVariables({server:Yi.server,namespace:fu}).toJS(),Ai=_a.serverVariables({server:Yi.server}).toJS();Yi.serverVariables=(0,pt.default)(Ml).length?Ml:Ai,Yi.requestContentType=_a.requestContentType(Ka,Du),Yi.responseContentType=_a.responseContentType(Ka,Du)||"*/*";var qa,Ba=_a.requestBodyValue(Ka,Du),ec=_a.requestBodyInclusionSetting(Ka,Du);Yi.requestBody=Ba&&Ba.toJS?(0,Fe.default)(qa=(0,j.default)(Ba).call(Ba,function(Wl){return cn.Map.isMap(Wl)?Wl.get("value"):Wl})).call(qa,function(Wl,Qf){return((0,P.default)(Wl)?0!==Wl.length:!(0,Nr.O2)(Wl))||ec.get(Qf)}).toJS():Ba}var Ru=(0,ht.default)({},Yi);Ru=No.buildRequest(Ru),Wo.setRequest(Yi.pathName,Yi.method,Ru);var Wl,Ff=(Wl=(0,g.default)(D.default.mark(function Qf(cg){var Kp,Lg;return D.default.wrap(function(I_){for(;;)switch(I_.prev=I_.next){case 0:return I_.next=2,rs.apply(void 0,[cg]);case 2:return Lg=(0,ht.default)({},Kp=I_.sent),Wo.setMutatedRequest(Yi.pathName,Yi.method,Lg),I_.abrupt("return",Kp);case 6:case"end":return I_.stop()}},Qf)})),function(Qf){return Wl.apply(this,arguments)});Yi.requestInterceptor=Ff,Yi.responseInterceptor=Zi;var Xp=(0,Dt.default)();return No.execute(Yi).then(function(Wl){Wl.duration=(0,Dt.default)()-Xp,Wo.setResponse(Yi.pathName,Yi.method,Wl)}).catch(function(Wl){"Failed to fetch"===Wl.message&&(Wl.name="",Wl.message='**Failed to fetch.** \n**Possible Reasons:** \n - CORS \n - Network Failure \n - URL scheme must be "http" or "https" for CORS request.'),Wo.setResponse(Yi.pathName,Yi.method,{error:!0,err:(0,wn.serializeError)(Wl)})})}},Oh=function(){var Yi=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},or=Yi.path,yi=Yi.method,qi=(0,c.default)(Yi,xr);return function(No){var Wo=No.fn.fetch,qo=No.specSelectors,is=No.specActions,_a=qo.specJsonWithResolvedSubtrees().toJS(),Ka=qo.operationScheme(or,yi),Du=qo.contentTypeValues([or,yi]).toJS(),Qn=Du.requestContentType,Ii=Du.responseContentType,rs=/xml/i.test(Qn),Zi=qo.parameterValues([or,yi],rs).toJS();return is.executeRequest((0,o.default)((0,o.default)({},qi),{},{fetch:Wo,spec:_a,pathName:or,method:yi,parameters:Zi,requestContentType:Qn,scheme:Ka,responseContentType:Ii}))}};function nu(Yi,or){return{type:Sn,payload:{path:Yi,method:or}}}function Yc(Yi,or){return{type:hn,payload:{path:Yi,method:or}}}function Lp(Yi,or,yi){return{type:yo,payload:{scheme:Yi,path:or,method:yi}}}},7038:(n,s,t)=>{t.r(s),t.d(s,{default:()=>D});var o=t(32),c=t(1737),g=t(3881),C=t(7508);function D(){return{statePlugins:{spec:{wrapActions:C,reducers:o.default,actions:c,selectors:g}}}}},32:(n,s,t)=>{t.r(s),t.d(s,{default:()=>Fe});var o,c=t(775),g=t(2691),C=t(5171),D=t(6785),P=t(2565),j=t(7512),W=t(9725),re=t(6298),oe=t(7504),me=t(3881),_e=t(1737);const Fe=((0,c.default)(o={},_e.UPDATE_SPEC,function(Re,Le){return"string"==typeof Le.payload?Re.set("spec",Le.payload):Re}),(0,c.default)(o,_e.UPDATE_URL,function(Re,Le){return Re.set("url",Le.payload+"")}),(0,c.default)(o,_e.UPDATE_JSON,function(Re,Le){return Re.set("json",(0,re.oG)(Le.payload))}),(0,c.default)(o,_e.UPDATE_RESOLVED,function(Re,Le){return Re.setIn(["resolved"],(0,re.oG)(Le.payload))}),(0,c.default)(o,_e.UPDATE_RESOLVED_SUBTREE,function(Re,Le){var we,U=Le.payload,pt=U.value,ht=U.path;return Re.setIn((0,C.default)(we=["resolvedSubtrees"]).call(we,(0,g.default)(ht)),(0,re.oG)(pt))}),(0,c.default)(o,_e.UPDATE_PARAM,function(Re,Le){var we,U,pt=Le.payload,ht=pt.path,Dt=pt.paramName,Ft=pt.paramIn,cn=pt.param,kt=pt.value,wn=pt.isXml,Tn=cn?(0,re.V9)(cn):(0,C.default)(we="".concat(Ft,".")).call(we,Dt),Hr=wn?"value_xml":"value";return Re.setIn((0,C.default)(U=["meta","paths"]).call(U,(0,g.default)(ht),["parameters",Tn,Hr]),kt)}),(0,c.default)(o,_e.UPDATE_EMPTY_PARAM_INCLUSION,function(Re,Le){var we,U,pt=Le.payload,ht=pt.pathMethod,Dt=pt.paramName,Ft=pt.paramIn,cn=pt.includeEmptyValue;if(!Dt||!Ft)return console.warn("Warning: UPDATE_EMPTY_PARAM_INCLUSION could not generate a paramKey."),Re;var kt=(0,C.default)(we="".concat(Ft,".")).call(we,Dt);return Re.setIn((0,C.default)(U=["meta","paths"]).call(U,(0,g.default)(ht),["parameter_inclusions",kt]),cn)}),(0,c.default)(o,_e.VALIDATE_PARAMS,function(Re,Le){var we,U,pt=Le.payload,ht=pt.pathMethod,Dt=pt.isOAS3,Ft=(0,me.specJsonWithResolvedSubtrees)(Re).getIn((0,C.default)(we=["paths"]).call(we,(0,g.default)(ht))),cn=(0,me.parameterValues)(Re,ht).toJS();return Re.updateIn((0,C.default)(U=["meta","paths"]).call(U,(0,g.default)(ht),["parameters"]),(0,W.fromJS)({}),function(kt){var wn;return(0,D.default)(wn=Ft.get("parameters",(0,W.List)())).call(wn,function(Tn,Hr){var sr=(0,re.cz)(Hr,cn),Nr=(0,me.parameterInclusionSettingFor)(Re,ht,Hr.get("name"),Hr.get("in")),xr=(0,re.Ik)(Hr,sr,{bypassRequiredCheck:Nr,isOAS3:Dt});return Tn.setIn([(0,re.V9)(Hr),"errors"],(0,W.fromJS)(xr))},kt)})}),(0,c.default)(o,_e.CLEAR_VALIDATE_PARAMS,function(Re,Le){var we,U=Le.payload.pathMethod;return Re.updateIn((0,C.default)(we=["meta","paths"]).call(we,(0,g.default)(U),["parameters"]),(0,W.fromJS)([]),function(pt){return(0,P.default)(pt).call(pt,function(ht){return ht.set("errors",(0,W.fromJS)([]))})})}),(0,c.default)(o,_e.SET_RESPONSE,function(Re,Le){var we,U=Le.payload,pt=U.res,ht=U.path,Dt=U.method;(we=pt.error?(0,j.default)({error:!0,name:pt.err.name,message:pt.err.message,statusCode:pt.err.statusCode},pt.err.response):pt).headers=we.headers||{};var Ft=Re.setIn(["responses",ht,Dt],(0,re.oG)(we));return oe.Z.Blob&&pt.data instanceof oe.Z.Blob&&(Ft=Ft.setIn(["responses",ht,Dt,"text"],pt.data)),Ft}),(0,c.default)(o,_e.SET_REQUEST,function(Re,Le){var we=Le.payload;return Re.setIn(["requests",we.path,we.method],(0,re.oG)(we.req))}),(0,c.default)(o,_e.SET_MUTATED_REQUEST,function(Re,Le){var we=Le.payload;return Re.setIn(["mutatedRequests",we.path,we.method],(0,re.oG)(we.req))}),(0,c.default)(o,_e.UPDATE_OPERATION_META_VALUE,function(Re,Le){var we,U,pt,ht,Dt,Ft,cn=Le.payload,kt=cn.path,wn=cn.value,Tn=cn.key,Hr=(0,C.default)(we=["paths"]).call(we,(0,g.default)(kt)),sr=(0,C.default)(U=["meta","paths"]).call(U,(0,g.default)(kt));return Re.getIn((0,C.default)(pt=["json"]).call(pt,(0,g.default)(Hr)))||Re.getIn((0,C.default)(ht=["resolved"]).call(ht,(0,g.default)(Hr)))||Re.getIn((0,C.default)(Dt=["resolvedSubtrees"]).call(Dt,(0,g.default)(Hr)))?Re.setIn((0,C.default)(Ft=[]).call(Ft,(0,g.default)(sr),[Tn]),(0,W.fromJS)(wn)):Re}),(0,c.default)(o,_e.CLEAR_RESPONSE,function(Re,Le){var we=Le.payload;return Re.deleteIn(["responses",we.path,we.method])}),(0,c.default)(o,_e.CLEAR_REQUEST,function(Re,Le){var we=Le.payload;return Re.deleteIn(["requests",we.path,we.method])}),(0,c.default)(o,_e.SET_SCHEME,function(Re,Le){var we=Le.payload,U=we.scheme,pt=we.path,ht=we.method;return pt&&ht?Re.setIn(["scheme",pt,ht],U):pt||ht?void 0:Re.setIn(["scheme","_defaultScheme"],U)}),o)},3881:(n,s,t)=>{t.r(s),t.d(s,{lastError:()=>ht,url:()=>Dt,specStr:()=>Ft,specSource:()=>cn,specJson:()=>kt,specResolved:()=>wn,specResolvedSubtree:()=>Tn,specJsonWithResolvedSubtrees:()=>sr,spec:()=>Nr,isOAS3:()=>xr,info:()=>fn,externalDocs:()=>Rn,version:()=>kn,semver:()=>Wn,paths:()=>bn,operations:()=>jr,consumes:()=>ji,produces:()=>oi,security:()=>Ui,securityDefinitions:()=>Xr,findDefinition:()=>Sn,definitions:()=>hn,basePath:()=>_r,host:()=>Fi,schemes:()=>_s,operationsWithRootInherited:()=>Ho,tags:()=>yo,tagDetails:()=>Us,operationsWithTags:()=>zs,taggedOperations:()=>Di,responses:()=>oo,requests:()=>ho,mutatedRequests:()=>Ze,responseFor:()=>Mt,requestFor:()=>St,mutatedRequestFor:()=>Un,allowTryItOutFor:()=>pr,parameterWithMetaByIdentity:()=>Vr,parameterInclusionSettingFor:()=>Ri,parameterWithMeta:()=>Bs,operationWithMeta:()=>Uo,getParameter:()=>ol,hasHost:()=>ml,parameterValues:()=>tu,parametersIncludeIn:()=>qu,parametersIncludeType:()=>Lf,contentTypeValues:()=>Fl,currentProducesFor:()=>Kc,producesOptionsFor:()=>cp,consumesOptionsFor:()=>Ah,operationScheme:()=>Qp,canExecuteScheme:()=>Oh,validateBeforeExecute:()=>nu,getOAS3RequiredRequestBodyContentType:()=>Yc,isMediaTypeSchemaPropertiesEqual:()=>Lp});var o=t(9334),c=t(2691),g=t(5171),C=t(8136),D=t(29),P=t(8818),j=t(2565),W=t(6145),re=t(1778),oe=t(6785),me=t(4350),_e=t(9963),Fe=t(4163),Re=t(8639),Le=t(6298),we=t(9725),U=["get","put","post","delete","options","head","patch","trace"],pt=function(or){return or||(0,we.Map)()},ht=(0,Re.createSelector)(pt,function(or){return or.get("lastError")}),Dt=(0,Re.createSelector)(pt,function(or){return or.get("url")}),Ft=(0,Re.createSelector)(pt,function(or){return or.get("spec")||""}),cn=(0,Re.createSelector)(pt,function(or){return or.get("specSource")||"not-editor"}),kt=(0,Re.createSelector)(pt,function(or){return or.get("json",(0,we.Map)())}),wn=(0,Re.createSelector)(pt,function(or){return or.get("resolved",(0,we.Map)())}),Tn=function(or,yi){var qi;return or.getIn((0,g.default)(qi=["resolvedSubtrees"]).call(qi,(0,c.default)(yi)),void 0)},Hr=function or(yi,qi){return we.Map.isMap(yi)&&we.Map.isMap(qi)?qi.get("$$ref")?qi:(0,we.OrderedMap)().mergeWith(or,yi,qi):qi},sr=(0,Re.createSelector)(pt,function(or){return(0,we.OrderedMap)().mergeWith(Hr,or.get("json"),or.get("resolvedSubtrees"))}),Nr=function(or){return kt(or)},xr=(0,Re.createSelector)(Nr,function(){return!1}),fn=(0,Re.createSelector)(Nr,function(or){return Yi(or&&or.get("info"))}),Rn=(0,Re.createSelector)(Nr,function(or){return Yi(or&&or.get("externalDocs"))}),kn=(0,Re.createSelector)(fn,function(or){return or&&or.get("version")}),Wn=(0,Re.createSelector)(kn,function(or){var yi;return(0,C.default)(yi=/v?([0-9]*)\.([0-9]*)\.([0-9]*)/i.exec(or)).call(yi,1)}),bn=(0,Re.createSelector)(sr,function(or){return or.get("paths")}),jr=(0,Re.createSelector)(bn,function(or){if(!or||or.size<1)return(0,we.List)();var yi=(0,we.List)();return or&&(0,D.default)(or)?((0,D.default)(or).call(or,function(qi,No){if(!qi||!(0,D.default)(qi))return{};(0,D.default)(qi).call(qi,function(Wo,qo){var is;(0,P.default)(U).call(U,qo)<0||(yi=yi.push((0,we.fromJS)({path:No,method:qo,operation:Wo,id:(0,g.default)(is="".concat(qo,"-")).call(is,No)})))})}),yi):(0,we.List)()}),ji=(0,Re.createSelector)(Nr,function(or){return(0,we.Set)(or.get("consumes"))}),oi=(0,Re.createSelector)(Nr,function(or){return(0,we.Set)(or.get("produces"))}),Ui=(0,Re.createSelector)(Nr,function(or){return or.get("security",(0,we.List)())}),Xr=(0,Re.createSelector)(Nr,function(or){return or.get("securityDefinitions")}),Sn=function(or,yi){var qi=or.getIn(["resolvedSubtrees","definitions",yi],null),No=or.getIn(["json","definitions",yi],null);return qi||No||null},hn=(0,Re.createSelector)(Nr,function(or){var yi=or.get("definitions");return we.Map.isMap(yi)?yi:(0,we.Map)()}),_r=(0,Re.createSelector)(Nr,function(or){return or.get("basePath")}),Fi=(0,Re.createSelector)(Nr,function(or){return or.get("host")}),_s=(0,Re.createSelector)(Nr,function(or){return or.get("schemes",(0,we.Map)())}),Ho=(0,Re.createSelector)(jr,ji,oi,function(or,yi,qi){return(0,j.default)(or).call(or,function(No){return No.update("operation",function(Wo){return Wo?we.Map.isMap(Wo)?Wo.withMutations(function(qo){return qo.get("consumes")||qo.update("consumes",function(is){return(0,we.Set)(is).merge(yi)}),qo.get("produces")||qo.update("produces",function(is){return(0,we.Set)(is).merge(qi)}),qo}):void 0:(0,we.Map)()})})}),yo=(0,Re.createSelector)(Nr,function(or){var yi=or.get("tags",(0,we.List)());return we.List.isList(yi)?(0,W.default)(yi).call(yi,function(qi){return we.Map.isMap(qi)}):(0,we.List)()}),Us=function(or,yi){var qi,No=yo(or)||(0,we.List)();return(0,re.default)(qi=(0,W.default)(No).call(No,we.Map.isMap)).call(qi,function(Wo){return Wo.get("name")===yi},(0,we.Map)())},zs=(0,Re.createSelector)(Ho,yo,function(or,yi){return(0,oe.default)(or).call(or,function(qi,No){var Wo=(0,we.Set)(No.getIn(["operation","tags"]));return Wo.count()<1?qi.update("default",(0,we.List)(),function(qo){return qo.push(No)}):(0,oe.default)(Wo).call(Wo,function(qo,is){return qo.update(is,(0,we.List)(),function(_a){return _a.push(No)})},qi)},(0,oe.default)(yi).call(yi,function(qi,No){return qi.set(No.get("name"),(0,we.List)())},(0,we.OrderedMap)()))}),Di=function(or){return function(yi){var qi,No=(0,yi.getConfigs)(),Wo=No.tagsSorter,qo=No.operationsSorter;return(0,j.default)(qi=zs(or).sortBy(function(is,_a){return _a},function(is,_a){var Ka="function"==typeof Wo?Wo:Le.wh.tagsSorter[Wo];return Ka?Ka(is,_a):null})).call(qi,function(is,_a){var Ka="function"==typeof qo?qo:Le.wh.operationsSorter[qo],Du=Ka?(0,me.default)(is).call(is,Ka):is;return(0,we.Map)({tagDetails:Us(or,_a),operations:Du})})}},oo=(0,Re.createSelector)(pt,function(or){return or.get("responses",(0,we.Map)())}),ho=(0,Re.createSelector)(pt,function(or){return or.get("requests",(0,we.Map)())}),Ze=(0,Re.createSelector)(pt,function(or){return or.get("mutatedRequests",(0,we.Map)())}),Mt=function(or,yi,qi){return oo(or).getIn([yi,qi],null)},St=function(or,yi,qi){return ho(or).getIn([yi,qi],null)},Un=function(or,yi,qi){return Ze(or).getIn([yi,qi],null)},pr=function(){return!0},Vr=function(or,yi,qi){var No,Wo,qo=sr(or).getIn((0,g.default)(No=["paths"]).call(No,(0,c.default)(yi),["parameters"]),(0,we.OrderedMap)()),is=or.getIn((0,g.default)(Wo=["meta","paths"]).call(Wo,(0,c.default)(yi),["parameters"]),(0,we.OrderedMap)()),_a=(0,j.default)(qo).call(qo,function(Ka){var Du,Qn,Ii,rs=is.get((0,g.default)(Du="".concat(qi.get("in"),".")).call(Du,qi.get("name"))),Zi=is.get((0,g.default)(Qn=(0,g.default)(Ii="".concat(qi.get("in"),".")).call(Ii,qi.get("name"),".hash-")).call(Qn,qi.hashCode()));return(0,we.OrderedMap)().merge(Ka,rs,Zi)});return(0,re.default)(_a).call(_a,function(Ka){return Ka.get("in")===qi.get("in")&&Ka.get("name")===qi.get("name")},(0,we.OrderedMap)())},Ri=function(or,yi,qi,No){var Wo,qo,is=(0,g.default)(Wo="".concat(No,".")).call(Wo,qi);return or.getIn((0,g.default)(qo=["meta","paths"]).call(qo,(0,c.default)(yi),["parameter_inclusions",is]),!1)},Bs=function(or,yi,qi,No){var Wo,qo=sr(or).getIn((0,g.default)(Wo=["paths"]).call(Wo,(0,c.default)(yi),["parameters"]),(0,we.OrderedMap)()),is=(0,re.default)(qo).call(qo,function(_a){return _a.get("in")===No&&_a.get("name")===qi},(0,we.OrderedMap)());return Vr(or,yi,is)},Uo=function(or,yi,qi){var No,Wo=sr(or).getIn(["paths",yi,qi],(0,we.OrderedMap)()),qo=or.getIn(["meta","paths",yi,qi],(0,we.OrderedMap)()),is=(0,j.default)(No=Wo.get("parameters",(0,we.List)())).call(No,function(_a){return Vr(or,[yi,qi],_a)});return(0,we.OrderedMap)().merge(Wo,qo).set("parameters",is)};function ol(or,yi,qi,No){var Wo;yi=yi||[];var qo=or.getIn((0,g.default)(Wo=["meta","paths"]).call(Wo,(0,c.default)(yi),["parameters"]),(0,we.fromJS)([]));return(0,re.default)(qo).call(qo,function(is){return we.Map.isMap(is)&&is.get("name")===qi&&is.get("in")===No})||(0,we.Map)()}var ml=(0,Re.createSelector)(Nr,function(or){var yi=or.get("host");return"string"==typeof yi&&yi.length>0&&"/"!==yi[0]});function tu(or,yi,qi){var No;yi=yi||[];var Wo=Uo.apply(void 0,(0,g.default)(No=[or]).call(No,(0,c.default)(yi))).get("parameters",(0,we.List)());return(0,oe.default)(Wo).call(Wo,function(qo,is){var _a=qi&&"body"===is.get("in")?is.get("value_xml"):is.get("value");return qo.set((0,Le.V9)(is,{allowHashes:!1}),_a)},(0,we.fromJS)({}))}function qu(or){var yi=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(we.List.isList(or))return(0,_e.default)(or).call(or,function(qi){return we.Map.isMap(qi)&&qi.get("in")===yi})}function Lf(or){var yi=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(we.List.isList(or))return(0,_e.default)(or).call(or,function(qi){return we.Map.isMap(qi)&&qi.get("type")===yi})}function Fl(or,yi){var qi,No;yi=yi||[];var Wo=sr(or).getIn((0,g.default)(qi=["paths"]).call(qi,(0,c.default)(yi)),(0,we.fromJS)({})),qo=or.getIn((0,g.default)(No=["meta","paths"]).call(No,(0,c.default)(yi)),(0,we.fromJS)({})),is=Kc(or,yi),_a=Wo.get("parameters")||new we.List,Ka=qo.get("consumes_value")?qo.get("consumes_value"):Lf(_a,"file")?"multipart/form-data":Lf(_a,"formData")?"application/x-www-form-urlencoded":void 0;return(0,we.fromJS)({requestContentType:Ka,responseContentType:is})}function Kc(or,yi){var qi,No;yi=yi||[];var Wo=sr(or).getIn((0,g.default)(qi=["paths"]).call(qi,(0,c.default)(yi)),null);if(null!==Wo){var qo=or.getIn((0,g.default)(No=["meta","paths"]).call(No,(0,c.default)(yi),["produces_value"]),null),is=Wo.getIn(["produces",0],null);return qo||is||"application/json"}}function cp(or,yi){var qi;yi=yi||[];var No=sr(or),Wo=No.getIn((0,g.default)(qi=["paths"]).call(qi,(0,c.default)(yi)),null);if(null!==Wo){var is=(0,o.default)(yi,1)[0],_a=Wo.get("produces",null),Ka=No.getIn(["paths",is,"produces"],null),Du=No.getIn(["produces"],null);return _a||Ka||Du}}function Ah(or,yi){var qi;yi=yi||[];var No=sr(or),Wo=No.getIn((0,g.default)(qi=["paths"]).call(qi,(0,c.default)(yi)),null);if(null!==Wo){var is=(0,o.default)(yi,1)[0],_a=Wo.get("consumes",null),Ka=No.getIn(["paths",is,"consumes"],null),Du=No.getIn(["consumes"],null);return _a||Ka||Du}}var Qp=function(or,yi,qi){var No=or.get("url").match(/^([a-z][a-z0-9+\-.]*):/),Wo=(0,Fe.default)(No)?No[1]:null;return or.getIn(["scheme",yi,qi])||or.getIn(["scheme","_defaultScheme"])||Wo||""},Oh=function(or,yi,qi){var No;return(0,P.default)(No=["http","https"]).call(No,Qp(or,yi,qi))>-1},nu=function(or,yi){var qi;yi=yi||[];var No=or.getIn((0,g.default)(qi=["meta","paths"]).call(qi,(0,c.default)(yi),["parameters"]),(0,we.fromJS)([])),Wo=!0;return(0,D.default)(No).call(No,function(qo){var is=qo.get("errors");is&&is.count()&&(Wo=!1)}),Wo},Yc=function(or,yi){var qi,No,Wo={requestBody:!1,requestContentType:{}},qo=or.getIn((0,g.default)(qi=["resolvedSubtrees","paths"]).call(qi,(0,c.default)(yi),["requestBody"]),(0,we.fromJS)([]));return qo.size<1||(qo.getIn(["required"])&&(Wo.requestBody=qo.getIn(["required"])),(0,D.default)(No=qo.getIn(["content"]).entrySeq()).call(No,function(is){var _a=is[0];if(is[1].getIn(["schema","required"])){var Ka=is[1].getIn(["schema","required"]).toJS();Wo.requestContentType[_a]=Ka}})),Wo},Lp=function(or,yi,qi,No){var Wo;if((qi||No)&&qi===No)return!0;var qo=or.getIn((0,g.default)(Wo=["resolvedSubtrees","paths"]).call(Wo,(0,c.default)(yi),["requestBody","content"]),(0,we.fromJS)([]));if(qo.size<2||!qi||!No)return!1;var is=qo.getIn([qi,"schema","properties"],(0,we.fromJS)([])),_a=qo.getIn([No,"schema","properties"],(0,we.fromJS)([]));return!!is.equals(_a)};function Yi(or){return we.Map.isMap(or)?or:new we.Map}},7508:(n,s,t)=>{t.r(s),t.d(s,{updateSpec:()=>C,updateJsonSpec:()=>D,executeRequest:()=>P,validateParams:()=>j});var o=t(2740),c=t(29),g=t(9908),C=function(W,re){var oe=re.specActions;return function(){W.apply(void 0,arguments),oe.parseToJson.apply(oe,arguments)}},D=function(W,re){var oe=re.specActions;return function(){for(var me=arguments.length,_e=new Array(me),Fe=0;Fe<me;Fe++)_e[Fe]=arguments[Fe];W.apply(void 0,_e),oe.invalidateResolvedSubtreeCache();var Re=_e[0],Le=(0,g.default)(Re,["paths"])||{},we=(0,o.default)(Le);(0,c.default)(we).call(we,function(U){(0,g.default)(Le,[U]).$ref&&oe.requestResolvedSubtree(["paths",U])}),oe.requestResolvedSubtree(["components","securitySchemes"])}},P=function(W,re){var oe=re.specActions;return function(me){return oe.logRequest(me),W(me)}},j=function(W,re){var oe=re.specSelectors;return function(me){return W(me,oe.isOAS3())}}},4852:(n,s,t)=>{t.r(s),t.d(s,{loaded:()=>o});var o=function(c,g){return function(){c.apply(void 0,arguments);var C=g.getConfigs().withCredentials;void 0!==C&&(g.fn.fetch.withCredentials="string"==typeof C?"true"===C:!!C)}}},2990:(n,s,t)=>{t.r(s),t.d(s,{default:()=>W});var o=t(5171);const c=(t.d(oe={},{default:()=>XN}),oe),g=(re=>{var oe={};return t.d(oe,re),oe})({buildRequest:()=>i6,execute:()=>b8}),C=(re=>{var oe={};return t.d(oe,re),oe})({default:()=>HT,makeHttp:()=>gA,serializeRes:()=>Ky}),D=(re=>{var oe={};return t.d(oe,re),oe})({default:()=>A8});var oe,P=t(5013),j=t(4852);function W(re){var oe=re.configs,me=re.getConfigs;return{fn:{fetch:(0,C.makeHttp)(C.default,oe.preFetch,oe.postFetch),buildRequest:g.buildRequest,execute:g.execute,resolve:c.default,resolveSubtree:function(_e,Fe,Re){var Le;if(void 0===Re){var we=me();Re={modelPropertyMacro:we.modelPropertyMacro,parameterMacro:we.parameterMacro,requestInterceptor:we.requestInterceptor,responseInterceptor:we.responseInterceptor}}for(var U=arguments.length,pt=new Array(U>3?U-3:0),ht=3;ht<U;ht++)pt[ht-3]=arguments[ht];return D.default.apply(void 0,(0,o.default)(Le=[_e,Fe,Re]).call(Le,pt))},serializeRes:C.serializeRes,opId:P.opId},statePlugins:{configs:{wrapActions:{loaded:j.loaded}}}}}},8525:(n,s,t)=>{t.r(s),t.d(s,{default:()=>c});var o=t(6298);function c(){return{fn:{shallowEqualKeys:o.be}}}},8347:(n,s,t)=>{t.r(s),t.d(s,{getDisplayName:()=>o});var o=function(c){return c.displayName||c.name||"Component"}},3420:(n,s,t)=>{t.r(s),t.d(s,{default:()=>P});var o=t(313),c=t(6298),g=t(5005),C=t(8347),D=t(8287);const P=function(j){var W,Re,re=j.getComponents,oe=j.getStore,me=j.getSystem,_e=(W=(0,g.getComponent)(me,oe,re),(0,c.HP)(W,function(){for(var Re=arguments.length,Le=new Array(Re),we=0;we<Re;we++)Le[we]=arguments[we];return(0,o.default)(Le)}));return{rootInjects:{getComponent:_e,makeMappedContainer:(Re=(0,g.withMappedContainer)(me,oe,_e),(0,D.Z)(Re,function(){for(var Le=arguments.length,we=new Array(Le),U=0;U<Le;U++)we[U]=arguments[U];return we})),render:(0,g.render)(me,oe,g.getComponent,re)},fn:{getDisplayName:C.getDisplayName}}}},5005:(n,s,t)=>{t.r(s),t.d(s,{getComponent:()=>ht,render:()=>pt,withMappedContainer:()=>U});var o=t(1581),c=t(1013),g=t(863),C=t(7344),D=t(8656),P=t(9972),j=t(5416),W=t(2740),re=t(810);const oe=(t.d(Ft={},{default:()=>o6}),Ft);var Ft,me=t(9871);const _e=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({Provider:()=>N8,connect:()=>cI}),Fe=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>hI()}),Re=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>gI()});var Le=function(Dt,Ft,cn){return(0,me.compose)(cn?(kt=Dt,wn=cn,function(Tn){var Hr=kt().fn,sr=function(Nr){(0,P.default)(fn,Nr);var xr=(0,j.default)(fn);function fn(){return(0,C.default)(this,fn),xr.apply(this,arguments)}return(0,D.default)(fn,[{key:"render",value:function(){return re.default.createElement(_e.Provider,{store:wn},re.default.createElement(Tn,(0,g.default)({},this.props,this.context)))}}]),fn}(re.Component);return sr.displayName="WithRoot(".concat(Hr.getDisplayName(Tn),")"),sr}):Re.default,(0,_e.connect)(function(kt,wn){var Tn,Hr=(0,c.default)((0,c.default)({},wn),Dt());return((null===(Tn=Ft.prototype)||void 0===Tn?void 0:Tn.mapStateToProps)||function(Nr){return{state:Nr}})(kt,Hr)}),function(kt){return function(wn){var Tn=kt().fn,Hr=function(sr){(0,P.default)(xr,sr);var Nr=(0,j.default)(xr);function xr(){return(0,C.default)(this,xr),Nr.apply(this,arguments)}return(0,D.default)(xr,[{key:"render",value:function(){return re.default.createElement(wn,(0,g.default)({},kt(),this.props,this.context))}}]),xr}(re.Component);return Hr.displayName="WithSystem(".concat(Tn.getDisplayName(wn),")"),Hr}}(Dt))(Ft);var kt,wn},we=function(Dt,Ft,cn,kt){for(var wn in Ft){var Tn=Ft[wn];"function"==typeof Tn&&Tn(cn[wn],kt[wn],Dt())}},U=function(Dt,Ft,cn){return function(kt,wn){var Tn=Dt().fn,Hr=cn(kt,"root"),sr=function(Nr){(0,P.default)(fn,Nr);var xr=(0,j.default)(fn);function fn(Rn,kn){var Wn;return(0,C.default)(this,fn),Wn=xr.call(this,Rn,kn),we(Dt,wn,Rn,{}),Wn}return(0,D.default)(fn,[{key:"UNSAFE_componentWillReceiveProps",value:function(Rn){we(Dt,wn,Rn,this.props)}},{key:"render",value:function(){var Rn=(0,Fe.default)(this.props,wn?(0,W.default)(wn):[]);return re.default.createElement(Hr,Rn)}}]),fn}(re.Component);return sr.displayName="WithMappedContainer(".concat(Tn.getDisplayName(Hr),")"),sr}},pt=function(Dt,Ft,cn,kt){return function(wn){var Tn=cn(Dt,Ft,kt)("App","root");oe.default.render(re.default.createElement(Tn,null),wn)}},ht=function(Dt,Ft,cn){return function(kt,wn){var Tn=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if("string"!=typeof kt)throw new TypeError("Need a string, to fetch a component. Was given a "+(0,o.default)(kt));var Hr=cn(kt);return Hr?wn?"root"===wn?Le(Dt,Hr,Ft()):Le(Dt,Hr):Hr:(Tn.failSilently||Dt().log.warn("Could not find component:",kt),null)}}},471:(n,s,t)=>{t.d(s,{d3:()=>g.default,C2:()=>ht});var o=t(2740),c=t(2372);const g=(t.d(Ft={},{default:()=>$I}),Ft),C=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>BI}),D=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>jI}),P=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>zI}),j=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>QI}),W=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>qI}),re=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>n4}),oe=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>o4}),me=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>s4}),_e=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>a4}),Fe=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>l4}),Re=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>u4}),Le=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>c4}),we=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>d4});var Ft;g.default.registerLanguage("json",D.default),g.default.registerLanguage("js",C.default),g.default.registerLanguage("xml",P.default),g.default.registerLanguage("yaml",W.default),g.default.registerLanguage("http",re.default),g.default.registerLanguage("bash",j.default),g.default.registerLanguage("powershell",oe.default),g.default.registerLanguage("javascript",C.default);var U={agate:me.default,arta:_e.default,monokai:Fe.default,nord:Re.default,obsidian:Le.default,"tomorrow-night":we.default},pt=(0,o.default)(U),ht=function(Dt){return(0,c.default)(pt).call(pt,Dt)?U[Dt]:(console.warn("Request style '".concat(Dt,"' is not available, returning default instead")),me.default)}},6298:(n,s,t)=>{t.d(s,{r3:()=>Fl,GZ:()=>cp,Xb:()=>_a,oJ:()=>Yc,XV:()=>yi,iQ:()=>Mt,J6:()=>Lp,DR:()=>Un,oG:()=>Fi,Uj:()=>is,QG:()=>nu,po:()=>or,nX:()=>Yi,gp:()=>St,xi:()=>qu,kJ:()=>zs,O2:()=>Du,LQ:()=>Ho,Wl:()=>Us,Kn:()=>yo,HP:()=>Di,AF:()=>_s,D$:()=>No,Ay:()=>oo,Q2:()=>ho,mz:()=>_r,V9:()=>Wo,cz:()=>qo,UG:()=>Lf,Zl:()=>pr,hW:()=>Oh,Nm:()=>Qp,be:()=>Ah,wh:()=>Kc,Pz:()=>qi,_5:()=>Ze,Ik:()=>Ri});var o=t(2691),c=(t(9334),t(1581)),g=t(3248),C=t(4163),D=t(2565),P=t(2954),j=t(5171),W=t(29),re=t(6145),oe=t(2740),me=(t(5527),t(6785)),_e=t(7512),Fe=t(4350),Re=t(8136),Le=t(9963),we=(t(2372),t(313)),U=t(8818),pt=t(1778),ht=t(3590),Dt=t(5942),Ft=t(9725);const cn=(t.d(Ii={},{sanitizeUrl:()=>f4.N}),Ii),kt=(Qn=>{var Ii={};return t.d(Ii,Qn),Ii})({default:()=>h4()}),wn=(Qn=>{var Ii={};return t.d(Ii,Qn),Ii})({default:()=>g4()});var Ii,Tn=t(5476);const Hr=(Qn=>{var Ii={};return t.d(Ii,Qn),Ii})({default:()=>v4()}),sr=(Qn=>{var Ii={};return t.d(Ii,Qn),Ii})({default:()=>b4()}),Nr=(Qn=>{var Ii={};return t.d(Ii,Qn),Ii})({default:()=>T4()});var xr=t(7068),fn=t(2473),Rn=t(7504);const kn=(Qn=>{var Ii={};return t.d(Ii,Qn),Ii})({default:()=>C4()});var Wn=t(9069),bn=t(1798),jr=t.n(bn),ji=t(9072),oi=t.n(ji),Ui=t(626),Xr=t(8764).Buffer,Sn="default",hn=function(Qn){return Ft.default.Iterable.isIterable(Qn)};function _r(Qn){return yo(Qn)?hn(Qn)?Qn.toJS():Qn:{}}function Fi(Qn){var Ii,rs;if(hn(Qn)||Qn instanceof Rn.Z.File||!yo(Qn))return Qn;if((0,C.default)(Qn))return(0,D.default)(rs=Ft.default.Seq(Qn)).call(rs,Fi).toList();if((0,xr.default)((0,P.default)(Qn))){var Zi,As=function(es){if(!(0,xr.default)((0,P.default)(es)))return es;var fu,Ml={},qa={},Ba=(0,g.default)((0,P.default)(es).call(es));try{for(Ba.s();!(fu=Ba.n()).done;){var Ru,Ff,Xp,Wl,ec=fu.value;Ml[ec[0]]||qa[ec[0]]&&qa[ec[0]].containsMultiple?(qa[ec[0]]||(qa[ec[0]]={containsMultiple:!0,length:1},Ml[(0,j.default)(Xp=(0,j.default)(Wl="".concat(ec[0])).call(Wl,"_**[]")).call(Xp,qa[ec[0]].length)]=Ml[ec[0]],delete Ml[ec[0]]),qa[ec[0]].length+=1,Ml[(0,j.default)(Ru=(0,j.default)(Ff="".concat(ec[0])).call(Ff,"_**[]")).call(Ru,qa[ec[0]].length)]=ec[1]):Ml[ec[0]]=ec[1]}}catch(Qf){Ba.e(Qf)}finally{Ba.f()}return Ml}(Qn);return(0,D.default)(Zi=Ft.default.OrderedMap(As)).call(Zi,Fi)}return(0,D.default)(Ii=Ft.default.OrderedMap(Qn)).call(Ii,Fi)}function _s(Qn){return(0,C.default)(Qn)?Qn:[Qn]}function Ho(Qn){return"function"==typeof Qn}function yo(Qn){return!!Qn&&"object"===(0,c.default)(Qn)}function Us(Qn){return"function"==typeof Qn}function zs(Qn){return(0,C.default)(Qn)}var Di=Tn.default;function oo(Qn,Ii){var rs;return(0,me.default)(rs=(0,oe.default)(Qn)).call(rs,function(Zi,As){return Zi[As]=Ii(Qn[As],As),Zi},{})}function ho(Qn,Ii){var rs;return(0,me.default)(rs=(0,oe.default)(Qn)).call(rs,function(Zi,As){var es=Ii(Qn[As],As);return es&&"object"===(0,c.default)(es)&&(0,_e.default)(Zi,es),Zi},{})}function Ze(Qn){return function(Ii){return function(rs){return function(Zi){return"function"==typeof Zi?Zi(Qn()):rs(Zi)}}}}function Mt(Qn){var Ii,rs=Qn.keySeq();return rs.contains(Sn)?Sn:(0,Fe.default)(Ii=(0,re.default)(rs).call(rs,function(Zi){return"2"===(Zi+"")[0]})).call(Ii).first()}function St(Qn,Ii){if(!Ft.default.Iterable.isIterable(Qn))return Ft.default.List();var rs=Qn.getIn((0,C.default)(Ii)?Ii:[Ii]);return Ft.default.List.isList(rs)?rs:Ft.default.List()}function Un(Qn){var Ii,rs=[/filename\*=[^']+'\w*'"([^"]+)";?/i,/filename\*=[^']+'\w*'([^;]+);?/i,/filename="([^;]*);?"/i,/filename=([^;]*);?/i];if((0,Le.default)(rs).call(rs,function(Zi){return null!==(Ii=Zi.exec(Qn))}),null!==Ii&&Ii.length>1)try{return decodeURIComponent(Ii[1])}catch(Zi){console.error(Zi)}return null}function pr(Qn){return Ii=Qn.replace(/\.[^./]*$/,""),(0,wn.default)((0,kt.default)(Ii));var Ii}function Vr(Qn,Ii,rs,Zi,As){if(!Ii)return[];var es=[],fu=Ii.get("nullable"),Ml=Ii.get("required"),Ai=Ii.get("maximum"),qa=Ii.get("minimum"),Ba=Ii.get("type"),ec=Ii.get("format"),Ru=Ii.get("maxLength"),Ff=Ii.get("minLength"),Xp=Ii.get("uniqueItems"),Wl=Ii.get("maxItems"),Qf=Ii.get("minItems"),cg=Ii.get("pattern"),Kp=rs||!0===Ml,Lg=null!=Qn;if(fu&&null===Qn||!Ba||!(Kp||Lg&&"array"===Ba||Kp||Lg))return[];var I_="string"===Ba&&Qn,t1="array"===Ba&&(0,C.default)(Qn)&&Qn.length,qp="array"===Ba&&Ft.default.List.isList(Qn)&&Qn.count(),_d=[I_,t1,qp,"array"===Ba&&"string"==typeof Qn&&Qn,"file"===Ba&&Qn instanceof Rn.Z.File,"boolean"===Ba&&(Qn||!1===Qn),"number"===Ba&&(Qn||0===Qn),"integer"===Ba&&(Qn||0===Qn),"object"===Ba&&"object"===(0,c.default)(Qn)&&null!==Qn,"object"===Ba&&"string"==typeof Qn&&Qn],Fg=(0,Le.default)(_d).call(_d,function(za){return!!za});if(Kp&&!Fg&&!Zi)return es.push("Required field is not provided"),es;if("object"===Ba&&(null===As||"application/json"===As)){var gm,dg=Qn;if("string"==typeof Qn)try{dg=JSON.parse(Qn)}catch(za){return es.push("Parameter string value must be valid JSON"),es}Ii&&Ii.has("required")&&Us(Ml.isList)&&Ml.isList()&&(0,W.default)(Ml).call(Ml,function(za){void 0===dg[za]&&es.push({propKey:za,error:"Required property not found"})}),Ii&&Ii.has("properties")&&(0,W.default)(gm=Ii.get("properties")).call(gm,function(za,ku){var ld=Vr(dg[ku],za,!1,Zi,As);es.push.apply(es,(0,o.default)((0,D.default)(ld).call(ld,function(A0){return{propKey:ku,error:A0}})))})}if(cg){var nv=function(za,ku){if(!new RegExp(ku).test(za))return"Value must follow pattern "+ku}(Qn,cg);nv&&es.push(nv)}if(Qf&&"array"===Ba){var Fp=function(za,ku){var ld;if(!za&&ku>=1||za&&za.length<ku)return(0,j.default)(ld="Array must contain at least ".concat(ku," item")).call(ld,1===ku?"":"s")}(Qn,Qf);Fp&&es.push(Fp)}if(Wl&&"array"===Ba){var YA=function(za,ku){var ld;if(za&&za.length>ku)return(0,j.default)(ld="Array must not contain more then ".concat(ku," item")).call(ld,1===ku?"":"s")}(Qn,Wl);YA&&es.push({needRemove:!0,error:YA})}if(Xp&&"array"===Ba){var wd=function(za,ku){if(za&&("true"===ku||!0===ku)){var ld=(0,Ft.fromJS)(za),A0=ld.toSet();if(za.length>A0.size){var n1=(0,Ft.Set)();if((0,W.default)(ld).call(ld,function(O0,kp){(0,re.default)(ld).call(ld,function(r1){return Us(r1.equals)?r1.equals(O0):r1===O0}).size>1&&(n1=n1.add(kp))}),0!==n1.size)return(0,D.default)(n1).call(n1,function(O0){return{index:O0,error:"No duplicates allowed."}}).toArray()}}}(Qn,Xp);wd&&es.push.apply(es,(0,o.default)(wd))}if(Ru||0===Ru){var ZA=function(za,ku){var ld;if(za.length>ku)return(0,j.default)(ld="Value must be no longer than ".concat(ku," character")).call(ld,1!==ku?"s":"")}(Qn,Ru);ZA&&es.push(ZA)}if(Ff){var cS=function(za,ku){var ld;if(za.length<ku)return(0,j.default)(ld="Value must be at least ".concat(ku," character")).call(ld,1!==ku?"s":"")}(Qn,Ff);cS&&es.push(cS)}if(Ai||0===Ai){var jA=function(za,ku){if(za>ku)return"Value must be less than ".concat(ku)}(Qn,Ai);jA&&es.push(jA)}if(qa||0===qa){var GA=function(za,ku){if(za<ku)return"Value must be greater than ".concat(ku)}(Qn,qa);GA&&es.push(GA)}if("string"===Ba){var dS;if(!(dS="date-time"===ec?function(za){if(isNaN(Date.parse(za)))return"Value must be a DateTime"}(Qn):"uuid"===ec?function(za){if(za=za.toString().toLowerCase(),!/^[{(]?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}[)}]?$/.test(za))return"Value must be a Guid"}(Qn):function(za){if(za&&"string"!=typeof za)return"Value must be a string"}(Qn)))return es;es.push(dS)}else if("boolean"===Ba){var pb=function(za){if("true"!==za&&"false"!==za&&!0!==za&&!1!==za)return"Value must be a boolean"}(Qn);if(!pb)return es;es.push(pb)}else if("number"===Ba){var VA=function(za){if(!/^-?\d+(\.?\d+)?$/.test(za))return"Value must be a number"}(Qn);if(!VA)return es;es.push(VA)}else if("integer"===Ba){var zA=function(za){if(!/^-?\d+$/.test(za))return"Value must be an integer"}(Qn);if(!zA)return es;es.push(zA)}else if("array"===Ba){if(!t1&&!qp)return es;Qn&&(0,W.default)(Qn).call(Qn,function(za,ku){var ld=Vr(za,Ii.get("items"),!1,Zi,As);es.push.apply(es,(0,o.default)((0,D.default)(ld).call(ld,function(A0){return{index:ku,error:A0}})))})}else if("file"===Ba){var WA=function(za){if(za&&!(za instanceof Rn.Z.File))return"Value must be a file"}(Qn);if(!WA)return es;es.push(WA)}return es}var Ri=function(Qn,Ii){var rs=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},Zi=rs.isOAS3,As=void 0!==Zi&&Zi,es=rs.bypassRequiredCheck,fu=void 0!==es&&es,Ml=Qn.get("required"),Ai=(0,Wn.Z)(Qn,{isOAS3:As}),qa=Ai.schema,Ba=Ai.parameterContentMediaType;return Vr(Ii,qa,Ml,fu,Ba)},Bs=function(Qn,Ii,rs){if(Qn&&(!Qn.xml||!Qn.xml.name)){if(Qn.xml=Qn.xml||{},!Qn.$$ref)return Qn.type||Qn.items||Qn.properties||Qn.additionalProperties?'<?xml version="1.0" encoding="UTF-8"?>\n\x3c!-- XML example cannot be generated; root element name is undefined --\x3e':null;var Zi=Qn.$$ref.match(/\S*\/(\S+)$/);Qn.xml.name=Zi[1]}return(0,fn.memoizedCreateXMLExample)(Qn,Ii,rs)},Uo=[{when:/json/,shouldStringifyTypes:["string"]}],ol=["object"],ml=function(Qn,Ii,rs,Zi){var As=(0,fn.memoizedSampleFromSchema)(Qn,Ii,Zi),es=(0,c.default)(As),fu=(0,me.default)(Uo).call(Uo,function(Ml,Ai){var qa;return Ai.when.test(rs)?(0,j.default)(qa=[]).call(qa,(0,o.default)(Ml),(0,o.default)(Ai.shouldStringifyTypes)):Ml},ol);return(0,sr.default)(fu,function(Ml){return Ml===es})?(0,we.default)(As,null,2):As},tu=function(Qn,Ii,rs,Zi){var As,es=ml(Qn,Ii,rs,Zi);try{"\n"===(As=Ui.default.dump(Ui.default.load(es),{lineWidth:-1},{schema:Ui.JSON_SCHEMA}))[As.length-1]&&(As=(0,Re.default)(As).call(As,0,As.length-1))}catch(fu){return console.error(fu),"error: could not generate yaml example"}return As.replace(/\t/g," ")},qu=function(Qn){var Ii=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",rs=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},Zi=arguments.length>3&&void 0!==arguments[3]?arguments[3]:void 0;return Qn&&Us(Qn.toJS)&&(Qn=Qn.toJS()),Zi&&Us(Zi.toJS)&&(Zi=Zi.toJS()),/xml/.test(Ii)?Bs(Qn,rs,Zi):/(yaml|yml)/.test(Ii)?tu(Qn,rs,Ii,Zi):ml(Qn,rs,Ii,Zi)},Lf=function(){var Qn={},Ii=Rn.Z.location.search;if(!Ii)return{};if(""!=Ii){var rs=Ii.substr(1).split("&");for(var Zi in rs)Object.prototype.hasOwnProperty.call(rs,Zi)&&(Zi=rs[Zi].split("="),Qn[decodeURIComponent(Zi[0])]=Zi[1]&&decodeURIComponent(Zi[1])||"")}return Qn},Fl=function(Qn){return(Qn instanceof Xr?Qn:Xr.from(Qn.toString(),"utf-8")).toString("base64")},Kc={operationsSorter:{alpha:function(Qn,Ii){return Qn.get("path").localeCompare(Ii.get("path"))},method:function(Qn,Ii){return Qn.get("method").localeCompare(Ii.get("method"))}},tagsSorter:{alpha:function(Qn,Ii){return Qn.localeCompare(Ii)}}},cp=function(Qn){var Ii=[];for(var rs in Qn){var Zi=Qn[rs];void 0!==Zi&&""!==Zi&&Ii.push([rs,"=",encodeURIComponent(Zi).replace(/%20/g,"+")].join(""))}return Ii.join("&")},Ah=function(Qn,Ii,rs){return!!(0,Hr.default)(rs,function(Zi){return(0,Nr.default)(Qn[Zi],Ii[Zi])})};function Qp(Qn){return"string"!=typeof Qn||""===Qn?"":(0,cn.sanitizeUrl)(Qn)}function Oh(Qn){return!(!Qn||(0,U.default)(Qn).call(Qn,"localhost")>=0||(0,U.default)(Qn).call(Qn,"127.0.0.1")>=0||"none"===Qn)}function nu(Qn){if(!Ft.default.OrderedMap.isOrderedMap(Qn)||!Qn.size)return null;var Ii=(0,pt.default)(Qn).call(Qn,function(As,es){return(0,ht.default)(es).call(es,"2")&&(0,oe.default)(As.get("content")||{}).length>0}),rs=Qn.get("default")||Ft.default.OrderedMap(),Zi=(rs.get("content")||Ft.default.OrderedMap()).keySeq().toJS().length?rs:null;return Ii||Zi}var Yc=function(Qn){return"string"==typeof Qn||Qn instanceof String?(0,Dt.default)(Qn).call(Qn).replace(/\s/g,"%20"):""},Lp=function(Qn){return(0,kn.default)(Yc(Qn).replace(/%20/g,"_"))},Yi=function(Qn){return(0,re.default)(Qn).call(Qn,function(Ii,rs){return/^x-/.test(rs)})},or=function(Qn){return(0,re.default)(Qn).call(Qn,function(Ii,rs){return/^pattern|maxLength|minLength|maximum|minimum/.test(rs)})};function yi(Qn,Ii){var rs,Zi=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){return!0};if("object"!==(0,c.default)(Qn)||(0,C.default)(Qn)||null===Qn||!Ii)return Qn;var As=(0,_e.default)({},Qn);return(0,W.default)(rs=(0,oe.default)(As)).call(rs,function(es){es===Ii&&Zi(As[es],es)?delete As[es]:As[es]=yi(As[es],Ii,Zi)}),As}function qi(Qn){if("string"==typeof Qn)return Qn;if(Qn&&Qn.toJS&&(Qn=Qn.toJS()),"object"===(0,c.default)(Qn)&&null!==Qn)try{return(0,we.default)(Qn,null,2)}catch(Ii){return String(Qn)}return null==Qn?"":Qn.toString()}function No(Qn){return"number"==typeof Qn?Qn.toString():Qn}function Wo(Qn){var Ii=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},rs=Ii.returnAll,Zi=void 0!==rs&&rs,As=Ii.allowHashes,es=void 0===As||As;if(!Ft.default.Map.isMap(Qn))throw new Error("paramToIdentifier: received a non-Im.Map parameter as input");var fu,Ml,Ai,qa=Qn.get("name"),Ba=Qn.get("in"),ec=[];return Qn&&Qn.hashCode&&Ba&&qa&&es&&ec.push((0,j.default)(fu=(0,j.default)(Ml="".concat(Ba,".")).call(Ml,qa,".hash-")).call(fu,Qn.hashCode())),Ba&&qa&&ec.push((0,j.default)(Ai="".concat(Ba,".")).call(Ai,qa)),ec.push(qa),Zi?ec:ec[0]||""}function qo(Qn,Ii){var rs,Zi=Wo(Qn,{returnAll:!0});return(0,re.default)(rs=(0,D.default)(Zi).call(Zi,function(As){return Ii[As]})).call(rs,function(As){return void 0!==As})[0]}function is(){return Ka(jr()(32).toString("base64"))}function _a(Qn){return Ka(oi()("sha256").update(Qn).digest("base64"))}function Ka(Qn){return Qn.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}var Du=function(Qn){return!Qn||!(!hn(Qn)||!Qn.isEmpty())}},2518:(n,s,t)=>{function o(c){return function(g){try{return!!JSON.parse(g)}catch(C){return null}}(c)?"json":null}t.d(s,{O:()=>o})},7504:(n,s,t)=>{t.d(s,{Z:()=>o});const o=function(){var c={location:{},history:{},open:function(){},close:function(){},File:function(){}};if("undefined"==typeof window)return c;try{c=window;for(var g=0,C=["File","Blob","FormData"];g<C.length;g++){var D=C[g];D in window&&(c[D]=window[D])}}catch(P){console.error(P)}return c}()},9069:(n,s,t)=>{t.d(s,{Z:()=>D});var o=t(6145),c=t(2372),g=t(9725),C=g.default.Set.of("type","format","items","default","maximum","exclusiveMaximum","minimum","exclusiveMinimum","maxLength","minLength","pattern","maxItems","minItems","uniqueItems","enum","multipleOf");function D(P){var j=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},W=j.isOAS3;if(!g.default.Map.isMap(P))return{schema:g.default.Map(),parameterContentMediaType:null};if(!W)return"body"===P.get("in")?{schema:P.get("schema",g.default.Map()),parameterContentMediaType:null}:{schema:(0,o.default)(P).call(P,function(me,_e){return(0,c.default)(C).call(C,_e)}),parameterContentMediaType:null};if(P.get("content")){var re=P.get("content",g.default.Map({})).keySeq(),oe=re.first();return{schema:P.getIn(["content",oe,"schema"],g.default.Map()),parameterContentMediaType:oe}}return{schema:P.get("schema",g.default.Map()),parameterContentMediaType:null}}},8287:(n,s,t)=>{t.d(s,{Z:()=>ht});var o=t(7344),c=t(8656);const g=(t.d(Ft={},{default:()=>NA}),Ft),C=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>T0});var Ft,D=t(9972),P=t(5416);const j=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>V3});var W=t(4163),re=t(7930),oe=t(8898),me=t(5487),_e=t(1778);const Fe=(Dt=>{var Ft={};return t.d(Ft,Dt),Ft})({default:()=>w4()});var Re=t(6914),Le=t(5476),we=function(Dt){return function(Ft){return(0,W.default)(Dt)&&(0,W.default)(Ft)&&Dt.length===Ft.length&&(0,re.default)(Dt).call(Dt,function(cn,kt){return cn===Ft[kt]})}},U=function(){for(var Dt=arguments.length,Ft=new Array(Dt),cn=0;cn<Dt;cn++)Ft[cn]=arguments[cn];return Ft},pt=function(Dt){(0,D.default)(cn,Dt);var Ft=(0,P.default)(cn);function cn(){return(0,o.default)(this,cn),Ft.apply(this,arguments)}return(0,c.default)(cn,[{key:"delete",value:function(kt){var wn=(0,oe.default)((0,me.default)(this).call(this)),Tn=(0,_e.default)(wn).call(wn,we(kt));return(0,g.default)((0,C.default)(cn.prototype),"delete",this).call(this,Tn)}},{key:"get",value:function(kt){var wn=(0,oe.default)((0,me.default)(this).call(this)),Tn=(0,_e.default)(wn).call(wn,we(kt));return(0,g.default)((0,C.default)(cn.prototype),"get",this).call(this,Tn)}},{key:"has",value:function(kt){var wn=(0,oe.default)((0,me.default)(this).call(this));return-1!==(0,Fe.default)(wn).call(wn,we(kt))}}]),cn}((0,j.default)(Re.default));const ht=function(Dt){var Ft=arguments.length>1&&void 0!==arguments[1]?arguments[1]:U,cn=Le.default.Cache;Le.default.Cache=pt;var kt=(0,Le.default)(Dt,Ft);return Le.default.Cache=cn,kt}},8764:(n,s,t)=>{const o=t(4780),c=t(3294),g="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;s.Buffer=P,s.SlowBuffer=function(Ze){return+Ze!=Ze&&(Ze=0),P.alloc(+Ze)},s.INSPECT_MAX_BYTES=50;const C=2147483647;function D(Ze){if(Ze>C)throw new RangeError('The value "'+Ze+'" is invalid for option "size"');const Mt=new Uint8Array(Ze);return Object.setPrototypeOf(Mt,P.prototype),Mt}function P(Ze,Mt,St){if("number"==typeof Ze){if("string"==typeof Mt)throw new TypeError('The "string" argument must be of type string. Received type number');return re(Ze)}return j(Ze,Mt,St)}function j(Ze,Mt,St){if("string"==typeof Ze)return function(Vr,Ri){if("string"==typeof Ri&&""!==Ri||(Ri="utf8"),!P.isEncoding(Ri))throw new TypeError("Unknown encoding: "+Ri);const Bs=0|Fe(Vr,Ri);let Uo=D(Bs);const ol=Uo.write(Vr,Ri);return ol!==Bs&&(Uo=Uo.slice(0,ol)),Uo}(Ze,Mt);if(ArrayBuffer.isView(Ze))return function(Vr){if(Us(Vr,Uint8Array)){const Ri=new Uint8Array(Vr);return me(Ri.buffer,Ri.byteOffset,Ri.byteLength)}return oe(Vr)}(Ze);if(null==Ze)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof Ze);if(Us(Ze,ArrayBuffer)||Ze&&Us(Ze.buffer,ArrayBuffer)||"undefined"!=typeof SharedArrayBuffer&&(Us(Ze,SharedArrayBuffer)||Ze&&Us(Ze.buffer,SharedArrayBuffer)))return me(Ze,Mt,St);if("number"==typeof Ze)throw new TypeError('The "value" argument must not be of type number. Received type number');const Un=Ze.valueOf&&Ze.valueOf();if(null!=Un&&Un!==Ze)return P.from(Un,Mt,St);const pr=function(Vr){if(P.isBuffer(Vr)){const Ri=0|_e(Vr.length),Bs=D(Ri);return 0===Bs.length||Vr.copy(Bs,0,0,Ri),Bs}return void 0!==Vr.length?"number"!=typeof Vr.length||zs(Vr.length)?D(0):oe(Vr):"Buffer"===Vr.type&&Array.isArray(Vr.data)?oe(Vr.data):void 0}(Ze);if(pr)return pr;if("undefined"!=typeof Symbol&&null!=Symbol.toPrimitive&&"function"==typeof Ze[Symbol.toPrimitive])return P.from(Ze[Symbol.toPrimitive]("string"),Mt,St);throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof Ze)}function W(Ze){if("number"!=typeof Ze)throw new TypeError('"size" argument must be of type number');if(Ze<0)throw new RangeError('The value "'+Ze+'" is invalid for option "size"')}function re(Ze){return W(Ze),D(Ze<0?0:0|_e(Ze))}function oe(Ze){const Mt=Ze.length<0?0:0|_e(Ze.length),St=D(Mt);for(let Un=0;Un<Mt;Un+=1)St[Un]=255&Ze[Un];return St}function me(Ze,Mt,St){if(Mt<0||Ze.byteLength<Mt)throw new RangeError('"offset" is outside of buffer bounds');if(Ze.byteLength<Mt+(St||0))throw new RangeError('"length" is outside of buffer bounds');let Un;return Un=void 0===Mt&&void 0===St?new Uint8Array(Ze):void 0===St?new Uint8Array(Ze,Mt):new Uint8Array(Ze,Mt,St),Object.setPrototypeOf(Un,P.prototype),Un}function _e(Ze){if(Ze>=C)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+C.toString(16)+" bytes");return 0|Ze}function Fe(Ze,Mt){if(P.isBuffer(Ze))return Ze.length;if(ArrayBuffer.isView(Ze)||Us(Ze,ArrayBuffer))return Ze.byteLength;if("string"!=typeof Ze)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof Ze);const St=Ze.length,Un=arguments.length>2&&!0===arguments[2];if(!Un&&0===St)return 0;let pr=!1;for(;;)switch(Mt){case"ascii":case"latin1":case"binary":return St;case"utf8":case"utf-8":return _s(Ze).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*St;case"hex":return St>>>1;case"base64":return Ho(Ze).length;default:if(pr)return Un?-1:_s(Ze).length;Mt=(""+Mt).toLowerCase(),pr=!0}}function Re(Ze,Mt,St){let Un=!1;if((void 0===Mt||Mt<0)&&(Mt=0),Mt>this.length||((void 0===St||St>this.length)&&(St=this.length),St<=0)||(St>>>=0)<=(Mt>>>=0))return"";for(Ze||(Ze="utf8");;)switch(Ze){case"hex":return Nr(this,Mt,St);case"utf8":case"utf-8":return wn(this,Mt,St);case"ascii":return Hr(this,Mt,St);case"latin1":case"binary":return sr(this,Mt,St);case"base64":return kt(this,Mt,St);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return xr(this,Mt,St);default:if(Un)throw new TypeError("Unknown encoding: "+Ze);Ze=(Ze+"").toLowerCase(),Un=!0}}function Le(Ze,Mt,St){const Un=Ze[Mt];Ze[Mt]=Ze[St],Ze[St]=Un}function we(Ze,Mt,St,Un,pr){if(0===Ze.length)return-1;if("string"==typeof St?(Un=St,St=0):St>2147483647?St=2147483647:St<-2147483648&&(St=-2147483648),zs(St=+St)&&(St=pr?0:Ze.length-1),St<0&&(St=Ze.length+St),St>=Ze.length){if(pr)return-1;St=Ze.length-1}else if(St<0){if(!pr)return-1;St=0}if("string"==typeof Mt&&(Mt=P.from(Mt,Un)),P.isBuffer(Mt))return 0===Mt.length?-1:U(Ze,Mt,St,Un,pr);if("number"==typeof Mt)return Mt&=255,"function"==typeof Uint8Array.prototype.indexOf?pr?Uint8Array.prototype.indexOf.call(Ze,Mt,St):Uint8Array.prototype.lastIndexOf.call(Ze,Mt,St):U(Ze,[Mt],St,Un,pr);throw new TypeError("val must be string, number or Buffer")}function U(Ze,Mt,St,Un,pr){let Vr,Ri=1,Bs=Ze.length,Uo=Mt.length;if(void 0!==Un&&("ucs2"===(Un=String(Un).toLowerCase())||"ucs-2"===Un||"utf16le"===Un||"utf-16le"===Un)){if(Ze.length<2||Mt.length<2)return-1;Ri=2,Bs/=2,Uo/=2,St/=2}function ol(ml,tu){return 1===Ri?ml[tu]:ml.readUInt16BE(tu*Ri)}if(pr){let ml=-1;for(Vr=St;Vr<Bs;Vr++)if(ol(Ze,Vr)===ol(Mt,-1===ml?0:Vr-ml)){if(-1===ml&&(ml=Vr),Vr-ml+1===Uo)return ml*Ri}else-1!==ml&&(Vr-=Vr-ml),ml=-1}else for(St+Uo>Bs&&(St=Bs-Uo),Vr=St;Vr>=0;Vr--){let ml=!0;for(let tu=0;tu<Uo;tu++)if(ol(Ze,Vr+tu)!==ol(Mt,tu)){ml=!1;break}if(ml)return Vr}return-1}function pt(Ze,Mt,St,Un){St=Number(St)||0;const pr=Ze.length-St;Un?(Un=Number(Un))>pr&&(Un=pr):Un=pr;const Vr=Mt.length;let Ri;for(Un>Vr/2&&(Un=Vr/2),Ri=0;Ri<Un;++Ri){const Bs=parseInt(Mt.substr(2*Ri,2),16);if(zs(Bs))return Ri;Ze[St+Ri]=Bs}return Ri}function ht(Ze,Mt,St,Un){return yo(_s(Mt,Ze.length-St),Ze,St,Un)}function Dt(Ze,Mt,St,Un){return yo(function(pr){const Vr=[];for(let Ri=0;Ri<pr.length;++Ri)Vr.push(255&pr.charCodeAt(Ri));return Vr}(Mt),Ze,St,Un)}function Ft(Ze,Mt,St,Un){return yo(Ho(Mt),Ze,St,Un)}function cn(Ze,Mt,St,Un){return yo(function(pr,Vr){let Ri,Bs,Uo;const ol=[];for(let ml=0;ml<pr.length&&!((Vr-=2)<0);++ml)Ri=pr.charCodeAt(ml),Bs=Ri>>8,Uo=Ri%256,ol.push(Uo),ol.push(Bs);return ol}(Mt,Ze.length-St),Ze,St,Un)}function kt(Ze,Mt,St){return o.fromByteArray(0===Mt&&St===Ze.length?Ze:Ze.slice(Mt,St))}function wn(Ze,Mt,St){St=Math.min(Ze.length,St);const Un=[];let pr=Mt;for(;pr<St;){const Vr=Ze[pr];let Ri=null,Bs=Vr>239?4:Vr>223?3:Vr>191?2:1;if(pr+Bs<=St){let Uo,ol,ml,tu;switch(Bs){case 1:Vr<128&&(Ri=Vr);break;case 2:Uo=Ze[pr+1],128==(192&Uo)&&(tu=(31&Vr)<<6|63&Uo,tu>127&&(Ri=tu));break;case 3:Uo=Ze[pr+1],ol=Ze[pr+2],128==(192&Uo)&&128==(192&ol)&&(tu=(15&Vr)<<12|(63&Uo)<<6|63&ol,tu>2047&&(tu<55296||tu>57343)&&(Ri=tu));break;case 4:Uo=Ze[pr+1],ol=Ze[pr+2],ml=Ze[pr+3],128==(192&Uo)&&128==(192&ol)&&128==(192&ml)&&(tu=(15&Vr)<<18|(63&Uo)<<12|(63&ol)<<6|63&ml,tu>65535&&tu<1114112&&(Ri=tu))}}null===Ri?(Ri=65533,Bs=1):Ri>65535&&(Ri-=65536,Un.push(Ri>>>10&1023|55296),Ri=56320|1023&Ri),Un.push(Ri),pr+=Bs}return function(Vr){const Ri=Vr.length;if(Ri<=Tn)return String.fromCharCode.apply(String,Vr);let Bs="",Uo=0;for(;Uo<Ri;)Bs+=String.fromCharCode.apply(String,Vr.slice(Uo,Uo+=Tn));return Bs}(Un)}s.kMaxLength=C,(P.TYPED_ARRAY_SUPPORT=function(){try{const Ze=new Uint8Array(1),Mt={foo:function(){return 42}};return Object.setPrototypeOf(Mt,Uint8Array.prototype),Object.setPrototypeOf(Ze,Mt),42===Ze.foo()}catch(Ze){return!1}}())||"undefined"==typeof console||"function"!=typeof console.error||console.error("This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support."),Object.defineProperty(P.prototype,"parent",{enumerable:!0,get:function(){if(P.isBuffer(this))return this.buffer}}),Object.defineProperty(P.prototype,"offset",{enumerable:!0,get:function(){if(P.isBuffer(this))return this.byteOffset}}),P.poolSize=8192,P.from=function(Ze,Mt,St){return j(Ze,Mt,St)},Object.setPrototypeOf(P.prototype,Uint8Array.prototype),Object.setPrototypeOf(P,Uint8Array),P.alloc=function(Ze,Mt,St){return pr=Mt,Vr=St,W(Un=Ze),Un<=0?D(Un):void 0!==pr?"string"==typeof Vr?D(Un).fill(pr,Vr):D(Un).fill(pr):D(Un);var Un,pr,Vr},P.allocUnsafe=function(Ze){return re(Ze)},P.allocUnsafeSlow=function(Ze){return re(Ze)},P.isBuffer=function(Ze){return null!=Ze&&!0===Ze._isBuffer&&Ze!==P.prototype},P.compare=function(Ze,Mt){if(Us(Ze,Uint8Array)&&(Ze=P.from(Ze,Ze.offset,Ze.byteLength)),Us(Mt,Uint8Array)&&(Mt=P.from(Mt,Mt.offset,Mt.byteLength)),!P.isBuffer(Ze)||!P.isBuffer(Mt))throw new TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');if(Ze===Mt)return 0;let St=Ze.length,Un=Mt.length;for(let pr=0,Vr=Math.min(St,Un);pr<Vr;++pr)if(Ze[pr]!==Mt[pr]){St=Ze[pr],Un=Mt[pr];break}return St<Un?-1:Un<St?1:0},P.isEncoding=function(Ze){switch(String(Ze).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"latin1":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},P.concat=function(Ze,Mt){if(!Array.isArray(Ze))throw new TypeError('"list" argument must be an Array of Buffers');if(0===Ze.length)return P.alloc(0);let St;if(void 0===Mt)for(Mt=0,St=0;St<Ze.length;++St)Mt+=Ze[St].length;const Un=P.allocUnsafe(Mt);let pr=0;for(St=0;St<Ze.length;++St){let Vr=Ze[St];if(Us(Vr,Uint8Array))pr+Vr.length>Un.length?(P.isBuffer(Vr)||(Vr=P.from(Vr)),Vr.copy(Un,pr)):Uint8Array.prototype.set.call(Un,Vr,pr);else{if(!P.isBuffer(Vr))throw new TypeError('"list" argument must be an Array of Buffers');Vr.copy(Un,pr)}pr+=Vr.length}return Un},P.byteLength=Fe,P.prototype._isBuffer=!0,P.prototype.swap16=function(){const Ze=this.length;if(Ze%2!=0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(let Mt=0;Mt<Ze;Mt+=2)Le(this,Mt,Mt+1);return this},P.prototype.swap32=function(){const Ze=this.length;if(Ze%4!=0)throw new RangeError("Buffer size must be a multiple of 32-bits");for(let Mt=0;Mt<Ze;Mt+=4)Le(this,Mt,Mt+3),Le(this,Mt+1,Mt+2);return this},P.prototype.swap64=function(){const Ze=this.length;if(Ze%8!=0)throw new RangeError("Buffer size must be a multiple of 64-bits");for(let Mt=0;Mt<Ze;Mt+=8)Le(this,Mt,Mt+7),Le(this,Mt+1,Mt+6),Le(this,Mt+2,Mt+5),Le(this,Mt+3,Mt+4);return this},P.prototype.toLocaleString=P.prototype.toString=function(){const Ze=this.length;return 0===Ze?"":0===arguments.length?wn(this,0,Ze):Re.apply(this,arguments)},P.prototype.equals=function(Ze){if(!P.isBuffer(Ze))throw new TypeError("Argument must be a Buffer");return this===Ze||0===P.compare(this,Ze)},P.prototype.inspect=function(){let Ze="";const Mt=s.INSPECT_MAX_BYTES;return Ze=this.toString("hex",0,Mt).replace(/(.{2})/g,"$1 ").trim(),this.length>Mt&&(Ze+=" ... "),"<Buffer "+Ze+">"},g&&(P.prototype[g]=P.prototype.inspect),P.prototype.compare=function(Ze,Mt,St,Un,pr){if(Us(Ze,Uint8Array)&&(Ze=P.from(Ze,Ze.offset,Ze.byteLength)),!P.isBuffer(Ze))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof Ze);if(void 0===Mt&&(Mt=0),void 0===St&&(St=Ze?Ze.length:0),void 0===Un&&(Un=0),void 0===pr&&(pr=this.length),Mt<0||St>Ze.length||Un<0||pr>this.length)throw new RangeError("out of range index");if(Un>=pr&&Mt>=St)return 0;if(Un>=pr)return-1;if(Mt>=St)return 1;if(this===Ze)return 0;let Vr=(pr>>>=0)-(Un>>>=0),Ri=(St>>>=0)-(Mt>>>=0);const Bs=Math.min(Vr,Ri),Uo=this.slice(Un,pr),ol=Ze.slice(Mt,St);for(let ml=0;ml<Bs;++ml)if(Uo[ml]!==ol[ml]){Vr=Uo[ml],Ri=ol[ml];break}return Vr<Ri?-1:Ri<Vr?1:0},P.prototype.includes=function(Ze,Mt,St){return-1!==this.indexOf(Ze,Mt,St)},P.prototype.indexOf=function(Ze,Mt,St){return we(this,Ze,Mt,St,!0)},P.prototype.lastIndexOf=function(Ze,Mt,St){return we(this,Ze,Mt,St,!1)},P.prototype.write=function(Ze,Mt,St,Un){if(void 0===Mt)Un="utf8",St=this.length,Mt=0;else if(void 0===St&&"string"==typeof Mt)Un=Mt,St=this.length,Mt=0;else{if(!isFinite(Mt))throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");Mt>>>=0,isFinite(St)?(St>>>=0,void 0===Un&&(Un="utf8")):(Un=St,St=void 0)}const pr=this.length-Mt;if((void 0===St||St>pr)&&(St=pr),Ze.length>0&&(St<0||Mt<0)||Mt>this.length)throw new RangeError("Attempt to write outside buffer bounds");Un||(Un="utf8");let Vr=!1;for(;;)switch(Un){case"hex":return pt(this,Ze,Mt,St);case"utf8":case"utf-8":return ht(this,Ze,Mt,St);case"ascii":case"latin1":case"binary":return Dt(this,Ze,Mt,St);case"base64":return Ft(this,Ze,Mt,St);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return cn(this,Ze,Mt,St);default:if(Vr)throw new TypeError("Unknown encoding: "+Un);Un=(""+Un).toLowerCase(),Vr=!0}},P.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};const Tn=4096;function Hr(Ze,Mt,St){let Un="";St=Math.min(Ze.length,St);for(let pr=Mt;pr<St;++pr)Un+=String.fromCharCode(127&Ze[pr]);return Un}function sr(Ze,Mt,St){let Un="";St=Math.min(Ze.length,St);for(let pr=Mt;pr<St;++pr)Un+=String.fromCharCode(Ze[pr]);return Un}function Nr(Ze,Mt,St){const Un=Ze.length;(!Mt||Mt<0)&&(Mt=0),(!St||St<0||St>Un)&&(St=Un);let pr="";for(let Vr=Mt;Vr<St;++Vr)pr+=Di[Ze[Vr]];return pr}function xr(Ze,Mt,St){const Un=Ze.slice(Mt,St);let pr="";for(let Vr=0;Vr<Un.length-1;Vr+=2)pr+=String.fromCharCode(Un[Vr]+256*Un[Vr+1]);return pr}function fn(Ze,Mt,St){if(Ze%1!=0||Ze<0)throw new RangeError("offset is not uint");if(Ze+Mt>St)throw new RangeError("Trying to access beyond buffer length")}function Rn(Ze,Mt,St,Un,pr,Vr){if(!P.isBuffer(Ze))throw new TypeError('"buffer" argument must be a Buffer instance');if(Mt>pr||Mt<Vr)throw new RangeError('"value" argument is out of bounds');if(St+Un>Ze.length)throw new RangeError("Index out of range")}function kn(Ze,Mt,St,Un,pr){Sn(Mt,Un,pr,Ze,St,7);let Vr=Number(Mt&BigInt(4294967295));Ze[St++]=Vr,Vr>>=8,Ze[St++]=Vr,Vr>>=8,Ze[St++]=Vr,Vr>>=8,Ze[St++]=Vr;let Ri=Number(Mt>>BigInt(32)&BigInt(4294967295));return Ze[St++]=Ri,Ri>>=8,Ze[St++]=Ri,Ri>>=8,Ze[St++]=Ri,Ri>>=8,Ze[St++]=Ri,St}function Wn(Ze,Mt,St,Un,pr){Sn(Mt,Un,pr,Ze,St,7);let Vr=Number(Mt&BigInt(4294967295));Ze[St+7]=Vr,Vr>>=8,Ze[St+6]=Vr,Vr>>=8,Ze[St+5]=Vr,Vr>>=8,Ze[St+4]=Vr;let Ri=Number(Mt>>BigInt(32)&BigInt(4294967295));return Ze[St+3]=Ri,Ri>>=8,Ze[St+2]=Ri,Ri>>=8,Ze[St+1]=Ri,Ri>>=8,Ze[St]=Ri,St+8}function bn(Ze,Mt,St,Un,pr,Vr){if(St+Un>Ze.length)throw new RangeError("Index out of range");if(St<0)throw new RangeError("Index out of range")}function jr(Ze,Mt,St,Un,pr){return Mt=+Mt,St>>>=0,pr||bn(Ze,0,St,4),c.write(Ze,Mt,St,Un,23,4),St+4}function ji(Ze,Mt,St,Un,pr){return Mt=+Mt,St>>>=0,pr||bn(Ze,0,St,8),c.write(Ze,Mt,St,Un,52,8),St+8}P.prototype.slice=function(Ze,Mt){const St=this.length;(Ze=~~Ze)<0?(Ze+=St)<0&&(Ze=0):Ze>St&&(Ze=St),(Mt=void 0===Mt?St:~~Mt)<0?(Mt+=St)<0&&(Mt=0):Mt>St&&(Mt=St),Mt<Ze&&(Mt=Ze);const Un=this.subarray(Ze,Mt);return Object.setPrototypeOf(Un,P.prototype),Un},P.prototype.readUintLE=P.prototype.readUIntLE=function(Ze,Mt,St){Ze>>>=0,Mt>>>=0,St||fn(Ze,Mt,this.length);let Un=this[Ze],pr=1,Vr=0;for(;++Vr<Mt&&(pr*=256);)Un+=this[Ze+Vr]*pr;return Un},P.prototype.readUintBE=P.prototype.readUIntBE=function(Ze,Mt,St){Ze>>>=0,Mt>>>=0,St||fn(Ze,Mt,this.length);let Un=this[Ze+--Mt],pr=1;for(;Mt>0&&(pr*=256);)Un+=this[Ze+--Mt]*pr;return Un},P.prototype.readUint8=P.prototype.readUInt8=function(Ze,Mt){return Ze>>>=0,Mt||fn(Ze,1,this.length),this[Ze]},P.prototype.readUint16LE=P.prototype.readUInt16LE=function(Ze,Mt){return Ze>>>=0,Mt||fn(Ze,2,this.length),this[Ze]|this[Ze+1]<<8},P.prototype.readUint16BE=P.prototype.readUInt16BE=function(Ze,Mt){return Ze>>>=0,Mt||fn(Ze,2,this.length),this[Ze]<<8|this[Ze+1]},P.prototype.readUint32LE=P.prototype.readUInt32LE=function(Ze,Mt){return Ze>>>=0,Mt||fn(Ze,4,this.length),(this[Ze]|this[Ze+1]<<8|this[Ze+2]<<16)+16777216*this[Ze+3]},P.prototype.readUint32BE=P.prototype.readUInt32BE=function(Ze,Mt){return Ze>>>=0,Mt||fn(Ze,4,this.length),16777216*this[Ze]+(this[Ze+1]<<16|this[Ze+2]<<8|this[Ze+3])},P.prototype.readBigUInt64LE=oo(function(Ze){hn(Ze>>>=0,"offset");const Mt=this[Ze],St=this[Ze+7];void 0!==Mt&&void 0!==St||_r(Ze,this.length-8);const Un=Mt+256*this[++Ze]+65536*this[++Ze]+this[++Ze]*vm(2,24),pr=this[++Ze]+256*this[++Ze]+65536*this[++Ze]+St*vm(2,24);return BigInt(Un)+(BigInt(pr)<<BigInt(32))}),P.prototype.readBigUInt64BE=oo(function(Ze){hn(Ze>>>=0,"offset");const Mt=this[Ze],St=this[Ze+7];void 0!==Mt&&void 0!==St||_r(Ze,this.length-8);const Un=Mt*vm(2,24)+65536*this[++Ze]+256*this[++Ze]+this[++Ze],pr=this[++Ze]*vm(2,24)+65536*this[++Ze]+256*this[++Ze]+St;return(BigInt(Un)<<BigInt(32))+BigInt(pr)}),P.prototype.readIntLE=function(Ze,Mt,St){Ze>>>=0,Mt>>>=0,St||fn(Ze,Mt,this.length);let Un=this[Ze],pr=1,Vr=0;for(;++Vr<Mt&&(pr*=256);)Un+=this[Ze+Vr]*pr;return pr*=128,Un>=pr&&(Un-=Math.pow(2,8*Mt)),Un},P.prototype.readIntBE=function(Ze,Mt,St){Ze>>>=0,Mt>>>=0,St||fn(Ze,Mt,this.length);let Un=Mt,pr=1,Vr=this[Ze+--Un];for(;Un>0&&(pr*=256);)Vr+=this[Ze+--Un]*pr;return pr*=128,Vr>=pr&&(Vr-=Math.pow(2,8*Mt)),Vr},P.prototype.readInt8=function(Ze,Mt){return Ze>>>=0,Mt||fn(Ze,1,this.length),128&this[Ze]?-1*(255-this[Ze]+1):this[Ze]},P.prototype.readInt16LE=function(Ze,Mt){Ze>>>=0,Mt||fn(Ze,2,this.length);const St=this[Ze]|this[Ze+1]<<8;return 32768&St?4294901760|St:St},P.prototype.readInt16BE=function(Ze,Mt){Ze>>>=0,Mt||fn(Ze,2,this.length);const St=this[Ze+1]|this[Ze]<<8;return 32768&St?4294901760|St:St},P.prototype.readInt32LE=function(Ze,Mt){return Ze>>>=0,Mt||fn(Ze,4,this.length),this[Ze]|this[Ze+1]<<8|this[Ze+2]<<16|this[Ze+3]<<24},P.prototype.readInt32BE=function(Ze,Mt){return Ze>>>=0,Mt||fn(Ze,4,this.length),this[Ze]<<24|this[Ze+1]<<16|this[Ze+2]<<8|this[Ze+3]},P.prototype.readBigInt64LE=oo(function(Ze){hn(Ze>>>=0,"offset");const Mt=this[Ze],St=this[Ze+7];return void 0!==Mt&&void 0!==St||_r(Ze,this.length-8),(BigInt(this[Ze+4]+256*this[Ze+5]+65536*this[Ze+6]+(St<<24))<<BigInt(32))+BigInt(Mt+256*this[++Ze]+65536*this[++Ze]+this[++Ze]*vm(2,24))}),P.prototype.readBigInt64BE=oo(function(Ze){hn(Ze>>>=0,"offset");const Mt=this[Ze],St=this[Ze+7];void 0!==Mt&&void 0!==St||_r(Ze,this.length-8);const Un=(Mt<<24)+65536*this[++Ze]+256*this[++Ze]+this[++Ze];return(BigInt(Un)<<BigInt(32))+BigInt(this[++Ze]*vm(2,24)+65536*this[++Ze]+256*this[++Ze]+St)}),P.prototype.readFloatLE=function(Ze,Mt){return Ze>>>=0,Mt||fn(Ze,4,this.length),c.read(this,Ze,!0,23,4)},P.prototype.readFloatBE=function(Ze,Mt){return Ze>>>=0,Mt||fn(Ze,4,this.length),c.read(this,Ze,!1,23,4)},P.prototype.readDoubleLE=function(Ze,Mt){return Ze>>>=0,Mt||fn(Ze,8,this.length),c.read(this,Ze,!0,52,8)},P.prototype.readDoubleBE=function(Ze,Mt){return Ze>>>=0,Mt||fn(Ze,8,this.length),c.read(this,Ze,!1,52,8)},P.prototype.writeUintLE=P.prototype.writeUIntLE=function(Ze,Mt,St,Un){Ze=+Ze,Mt>>>=0,St>>>=0,!Un&&Rn(this,Ze,Mt,St,Math.pow(2,8*St)-1,0);let pr=1,Vr=0;for(this[Mt]=255&Ze;++Vr<St&&(pr*=256);)this[Mt+Vr]=Ze/pr&255;return Mt+St},P.prototype.writeUintBE=P.prototype.writeUIntBE=function(Ze,Mt,St,Un){Ze=+Ze,Mt>>>=0,St>>>=0,!Un&&Rn(this,Ze,Mt,St,Math.pow(2,8*St)-1,0);let pr=St-1,Vr=1;for(this[Mt+pr]=255&Ze;--pr>=0&&(Vr*=256);)this[Mt+pr]=Ze/Vr&255;return Mt+St},P.prototype.writeUint8=P.prototype.writeUInt8=function(Ze,Mt,St){return Ze=+Ze,Mt>>>=0,St||Rn(this,Ze,Mt,1,255,0),this[Mt]=255&Ze,Mt+1},P.prototype.writeUint16LE=P.prototype.writeUInt16LE=function(Ze,Mt,St){return Ze=+Ze,Mt>>>=0,St||Rn(this,Ze,Mt,2,65535,0),this[Mt]=255&Ze,this[Mt+1]=Ze>>>8,Mt+2},P.prototype.writeUint16BE=P.prototype.writeUInt16BE=function(Ze,Mt,St){return Ze=+Ze,Mt>>>=0,St||Rn(this,Ze,Mt,2,65535,0),this[Mt]=Ze>>>8,this[Mt+1]=255&Ze,Mt+2},P.prototype.writeUint32LE=P.prototype.writeUInt32LE=function(Ze,Mt,St){return Ze=+Ze,Mt>>>=0,St||Rn(this,Ze,Mt,4,4294967295,0),this[Mt+3]=Ze>>>24,this[Mt+2]=Ze>>>16,this[Mt+1]=Ze>>>8,this[Mt]=255&Ze,Mt+4},P.prototype.writeUint32BE=P.prototype.writeUInt32BE=function(Ze,Mt,St){return Ze=+Ze,Mt>>>=0,St||Rn(this,Ze,Mt,4,4294967295,0),this[Mt]=Ze>>>24,this[Mt+1]=Ze>>>16,this[Mt+2]=Ze>>>8,this[Mt+3]=255&Ze,Mt+4},P.prototype.writeBigUInt64LE=oo(function(Ze,Mt=0){return kn(this,Ze,Mt,BigInt(0),BigInt("0xffffffffffffffff"))}),P.prototype.writeBigUInt64BE=oo(function(Ze,Mt=0){return Wn(this,Ze,Mt,BigInt(0),BigInt("0xffffffffffffffff"))}),P.prototype.writeIntLE=function(Ze,Mt,St,Un){if(Ze=+Ze,Mt>>>=0,!Un){const Bs=Math.pow(2,8*St-1);Rn(this,Ze,Mt,St,Bs-1,-Bs)}let pr=0,Vr=1,Ri=0;for(this[Mt]=255&Ze;++pr<St&&(Vr*=256);)Ze<0&&0===Ri&&0!==this[Mt+pr-1]&&(Ri=1),this[Mt+pr]=(Ze/Vr>>0)-Ri&255;return Mt+St},P.prototype.writeIntBE=function(Ze,Mt,St,Un){if(Ze=+Ze,Mt>>>=0,!Un){const Bs=Math.pow(2,8*St-1);Rn(this,Ze,Mt,St,Bs-1,-Bs)}let pr=St-1,Vr=1,Ri=0;for(this[Mt+pr]=255&Ze;--pr>=0&&(Vr*=256);)Ze<0&&0===Ri&&0!==this[Mt+pr+1]&&(Ri=1),this[Mt+pr]=(Ze/Vr>>0)-Ri&255;return Mt+St},P.prototype.writeInt8=function(Ze,Mt,St){return Ze=+Ze,Mt>>>=0,St||Rn(this,Ze,Mt,1,127,-128),Ze<0&&(Ze=255+Ze+1),this[Mt]=255&Ze,Mt+1},P.prototype.writeInt16LE=function(Ze,Mt,St){return Ze=+Ze,Mt>>>=0,St||Rn(this,Ze,Mt,2,32767,-32768),this[Mt]=255&Ze,this[Mt+1]=Ze>>>8,Mt+2},P.prototype.writeInt16BE=function(Ze,Mt,St){return Ze=+Ze,Mt>>>=0,St||Rn(this,Ze,Mt,2,32767,-32768),this[Mt]=Ze>>>8,this[Mt+1]=255&Ze,Mt+2},P.prototype.writeInt32LE=function(Ze,Mt,St){return Ze=+Ze,Mt>>>=0,St||Rn(this,Ze,Mt,4,2147483647,-2147483648),this[Mt]=255&Ze,this[Mt+1]=Ze>>>8,this[Mt+2]=Ze>>>16,this[Mt+3]=Ze>>>24,Mt+4},P.prototype.writeInt32BE=function(Ze,Mt,St){return Ze=+Ze,Mt>>>=0,St||Rn(this,Ze,Mt,4,2147483647,-2147483648),Ze<0&&(Ze=4294967295+Ze+1),this[Mt]=Ze>>>24,this[Mt+1]=Ze>>>16,this[Mt+2]=Ze>>>8,this[Mt+3]=255&Ze,Mt+4},P.prototype.writeBigInt64LE=oo(function(Ze,Mt=0){return kn(this,Ze,Mt,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))}),P.prototype.writeBigInt64BE=oo(function(Ze,Mt=0){return Wn(this,Ze,Mt,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))}),P.prototype.writeFloatLE=function(Ze,Mt,St){return jr(this,Ze,Mt,!0,St)},P.prototype.writeFloatBE=function(Ze,Mt,St){return jr(this,Ze,Mt,!1,St)},P.prototype.writeDoubleLE=function(Ze,Mt,St){return ji(this,Ze,Mt,!0,St)},P.prototype.writeDoubleBE=function(Ze,Mt,St){return ji(this,Ze,Mt,!1,St)},P.prototype.copy=function(Ze,Mt,St,Un){if(!P.isBuffer(Ze))throw new TypeError("argument should be a Buffer");if(St||(St=0),Un||0===Un||(Un=this.length),Mt>=Ze.length&&(Mt=Ze.length),Mt||(Mt=0),Un>0&&Un<St&&(Un=St),Un===St||0===Ze.length||0===this.length)return 0;if(Mt<0)throw new RangeError("targetStart out of bounds");if(St<0||St>=this.length)throw new RangeError("Index out of range");if(Un<0)throw new RangeError("sourceEnd out of bounds");Un>this.length&&(Un=this.length),Ze.length-Mt<Un-St&&(Un=Ze.length-Mt+St);const pr=Un-St;return this===Ze&&"function"==typeof Uint8Array.prototype.copyWithin?this.copyWithin(Mt,St,Un):Uint8Array.prototype.set.call(Ze,this.subarray(St,Un),Mt),pr},P.prototype.fill=function(Ze,Mt,St,Un){if("string"==typeof Ze){if("string"==typeof Mt?(Un=Mt,Mt=0,St=this.length):"string"==typeof St&&(Un=St,St=this.length),void 0!==Un&&"string"!=typeof Un)throw new TypeError("encoding must be a string");if("string"==typeof Un&&!P.isEncoding(Un))throw new TypeError("Unknown encoding: "+Un);if(1===Ze.length){const Vr=Ze.charCodeAt(0);("utf8"===Un&&Vr<128||"latin1"===Un)&&(Ze=Vr)}}else"number"==typeof Ze?Ze&=255:"boolean"==typeof Ze&&(Ze=Number(Ze));if(Mt<0||this.length<Mt||this.length<St)throw new RangeError("Out of range index");if(St<=Mt)return this;let pr;if(Mt>>>=0,St=void 0===St?this.length:St>>>0,Ze||(Ze=0),"number"==typeof Ze)for(pr=Mt;pr<St;++pr)this[pr]=Ze;else{const Vr=P.isBuffer(Ze)?Ze:P.from(Ze,Un),Ri=Vr.length;if(0===Ri)throw new TypeError('The value "'+Ze+'" is invalid for argument "value"');for(pr=0;pr<St-Mt;++pr)this[pr+Mt]=Vr[pr%Ri]}return this};const oi={};function Ui(Ze,Mt,St){oi[Ze]=class extends St{constructor(){super(),Object.defineProperty(this,"message",{value:Mt.apply(this,arguments),writable:!0,configurable:!0}),this.name=`${this.name} [${Ze}]`,delete this.name}get code(){return Ze}set code(Un){Object.defineProperty(this,"code",{configurable:!0,enumerable:!0,value:Un,writable:!0})}toString(){return`${this.name} [${Ze}]: ${this.message}`}}}function Xr(Ze){let Mt="",St=Ze.length;const Un="-"===Ze[0]?1:0;for(;St>=Un+4;St-=3)Mt=`_${Ze.slice(St-3,St)}${Mt}`;return`${Ze.slice(0,St)}${Mt}`}function Sn(Ze,Mt,St,Un,pr,Vr){if(Ze>St||Ze<Mt){const Ri="bigint"==typeof Mt?"n":"";let Bs;throw Bs=Vr>3?0===Mt||Mt===BigInt(0)?`>= 0${Ri} and < 2${Ri} ** ${8*(Vr+1)}${Ri}`:`>= -(2${Ri} ** ${8*(Vr+1)-1}${Ri}) and < 2 ** ${8*(Vr+1)-1}${Ri}`:`>= ${Mt}${Ri} and <= ${St}${Ri}`,new oi.ERR_OUT_OF_RANGE("value",Bs,Ze)}var Ri,Bs,Uo;Ri=Un,Uo=Vr,hn(Bs=pr,"offset"),void 0!==Ri[Bs]&&void 0!==Ri[Bs+Uo]||_r(Bs,Ri.length-(Uo+1))}function hn(Ze,Mt){if("number"!=typeof Ze)throw new oi.ERR_INVALID_ARG_TYPE(Mt,"number",Ze)}function _r(Ze,Mt,St){throw Math.floor(Ze)!==Ze?(hn(Ze,St),new oi.ERR_OUT_OF_RANGE(St||"offset","an integer",Ze)):Mt<0?new oi.ERR_BUFFER_OUT_OF_BOUNDS:new oi.ERR_OUT_OF_RANGE(St||"offset",`>= ${St?1:0} and <= ${Mt}`,Ze)}Ui("ERR_BUFFER_OUT_OF_BOUNDS",function(Ze){return Ze?`${Ze} is outside of buffer bounds`:"Attempt to access memory outside buffer bounds"},RangeError),Ui("ERR_INVALID_ARG_TYPE",function(Ze,Mt){return`The "${Ze}" argument must be of type number. Received type ${typeof Mt}`},TypeError),Ui("ERR_OUT_OF_RANGE",function(Ze,Mt,St){let Un=`The value of "${Ze}" is out of range.`,pr=St;return Number.isInteger(St)&&Math.abs(St)>vm(2,32)?pr=Xr(String(St)):"bigint"==typeof St&&(pr=String(St),(St>vm(BigInt(2),BigInt(32))||St<-vm(BigInt(2),BigInt(32)))&&(pr=Xr(pr)),pr+="n"),Un+=` It must be ${Mt}. Received ${pr}`,Un},RangeError);const Fi=/[^+/0-9A-Za-z-_]/g;function _s(Ze,Mt){let St;Mt=Mt||1/0;const Un=Ze.length;let pr=null;const Vr=[];for(let Ri=0;Ri<Un;++Ri){if(St=Ze.charCodeAt(Ri),St>55295&&St<57344){if(!pr){if(St>56319){(Mt-=3)>-1&&Vr.push(239,191,189);continue}if(Ri+1===Un){(Mt-=3)>-1&&Vr.push(239,191,189);continue}pr=St;continue}if(St<56320){(Mt-=3)>-1&&Vr.push(239,191,189),pr=St;continue}St=65536+(pr-55296<<10|St-56320)}else pr&&(Mt-=3)>-1&&Vr.push(239,191,189);if(pr=null,St<128){if((Mt-=1)<0)break;Vr.push(St)}else if(St<2048){if((Mt-=2)<0)break;Vr.push(St>>6|192,63&St|128)}else if(St<65536){if((Mt-=3)<0)break;Vr.push(St>>12|224,St>>6&63|128,63&St|128)}else{if(!(St<1114112))throw new Error("Invalid code point");if((Mt-=4)<0)break;Vr.push(St>>18|240,St>>12&63|128,St>>6&63|128,63&St|128)}}return Vr}function Ho(Ze){return o.toByteArray(function(Mt){if((Mt=(Mt=Mt.split("=")[0]).trim().replace(Fi,"")).length<2)return"";for(;Mt.length%4!=0;)Mt+="=";return Mt}(Ze))}function yo(Ze,Mt,St,Un){let pr;for(pr=0;pr<Un&&!(pr+St>=Mt.length||pr>=Ze.length);++pr)Mt[pr+St]=Ze[pr];return pr}function Us(Ze,Mt){return Ze instanceof Mt||null!=Ze&&null!=Ze.constructor&&null!=Ze.constructor.name&&Ze.constructor.name===Mt.name}function zs(Ze){return Ze!=Ze}const Di=function(){const Ze="0123456789abcdef",Mt=new Array(256);for(let St=0;St<16;++St){const Un=16*St;for(let pr=0;pr<16;++pr)Mt[Un+pr]=Ze[St]+Ze[pr]}return Mt}();function oo(Ze){return"undefined"==typeof BigInt?ho:Ze}function ho(){throw new Error("BigInt not supported")}},8171:(n,s,t)=>{t(6450);var o=t(4058).Object,c=n.exports=function(g,C,D){return o.defineProperty(g,C,D)};o.defineProperty.sham&&(c.sham=!0)},4883:(n,s,t)=>{var o=t(1899),c=t(7475),g=t(9826),C=o.TypeError;n.exports=function(D){if(c(D))return D;throw C(g(D)+" is not a function")}},6059:(n,s,t)=>{var o=t(1899),c=t(941),g=o.String,C=o.TypeError;n.exports=function(D){if(c(D))return D;throw C(g(D)+" is not an object")}},2532:(n,s,t)=>{var o=t(5329),c=o({}.toString),g=o("".slice);n.exports=function(C){return g(c(C),8,-1)}},2029:(n,s,t)=>{var o=t(5746),c=t(5988),g=t(1887);n.exports=o?function(C,D,P){return c.f(C,D,g(1,P))}:function(C,D,P){return C[D]=P,C}},1887:n=>{n.exports=function(s,t){return{enumerable:!(1&s),configurable:!(2&s),writable:!(4&s),value:t}}},5746:(n,s,t)=>{var o=t(5981);n.exports=!o(function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]})},1333:(n,s,t)=>{var o=t(1899),c=t(941),g=o.document,C=c(g)&&c(g.createElement);n.exports=function(D){return C?g.createElement(D):{}}},2861:(n,s,t)=>{var o=t(224);n.exports=o("navigator","userAgent")||""},3385:(n,s,t)=>{var o,c,g=t(1899),C=t(2861),D=g.process,P=g.Deno,j=D&&D.versions||P&&P.version,W=j&&j.v8;W&&(c=(o=W.split("."))[0]>0&&o[0]<4?1:+(o[0]+o[1])),!c&&C&&(!(o=C.match(/Edge\/(\d+)/))||o[1]>=74)&&(o=C.match(/Chrome\/(\d+)/))&&(c=+o[1]),n.exports=c},6887:(n,s,t)=>{var o=t(1899),c=t(9730),g=t(5329),C=t(7475),D=t(9677).f,P=t(7252),j=t(4058),W=t(6843),re=t(2029),oe=t(953),me=function(_e){var Fe=function(Re,Le,we){if(this instanceof Fe){switch(arguments.length){case 0:return new _e;case 1:return new _e(Re);case 2:return new _e(Re,Le)}return new _e(Re,Le,we)}return c(_e,this,arguments)};return Fe.prototype=_e.prototype,Fe};n.exports=function(_e,Fe){var Re,Le,we,U,pt,ht,Dt,Ft,cn=_e.target,kt=_e.global,wn=_e.stat,Tn=_e.proto,Hr=kt?o:wn?o[cn]:(o[cn]||{}).prototype,sr=kt?j:j[cn]||re(j,cn,{})[cn],Nr=sr.prototype;for(we in Fe)Re=!P(kt?we:cn+(wn?".":"#")+we,_e.forced)&&Hr&&oe(Hr,we),pt=sr[we],Re&&(ht=_e.noTargetGet?(Ft=D(Hr,we))&&Ft.value:Hr[we]),U=Re&&ht?ht:Fe[we],Re&&typeof pt==typeof U||(Dt=_e.bind&&Re?W(U,o):_e.wrap&&Re?me(U):Tn&&C(U)?g(U):U,(_e.sham||U&&U.sham||pt&&pt.sham)&&re(Dt,"sham",!0),re(sr,we,Dt),Tn&&(oe(j,Le=cn+"Prototype")||re(j,Le,{}),re(j[Le],we,U),_e.real&&Nr&&!Nr[we]&&re(Nr,we,U)))}},5981:n=>{n.exports=function(s){try{return!!s()}catch(t){return!0}}},9730:(n,s,t)=>{var o=t(8285),c=Function.prototype,g=c.apply,C=c.call;n.exports="object"==typeof Reflect&&Reflect.apply||(o?C.bind(g):function(){return C.apply(g,arguments)})},6843:(n,s,t)=>{var o=t(5329),c=t(4883),g=t(8285),C=o(o.bind);n.exports=function(D,P){return c(D),void 0===P?D:g?C(D,P):function(){return D.apply(P,arguments)}}},8285:(n,s,t)=>{var o=t(5981);n.exports=!o(function(){var c=function(){}.bind();return"function"!=typeof c||c.hasOwnProperty("prototype")})},8834:(n,s,t)=>{var o=t(8285),c=Function.prototype.call;n.exports=o?c.bind(c):function(){return c.apply(c,arguments)}},5329:(n,s,t)=>{var o=t(8285),c=Function.prototype,C=c.call,D=o&&c.bind.bind(C,C);n.exports=o?function(P){return P&&D(P)}:function(P){return P&&function(){return C.apply(P,arguments)}}},224:(n,s,t)=>{var o=t(4058),c=t(1899),g=t(7475),C=function(D){return g(D)?D:void 0};n.exports=function(D,P){return arguments.length<2?C(o[D])||C(c[D]):o[D]&&o[D][P]||c[D]&&c[D][P]}},9733:(n,s,t)=>{var o=t(4883);n.exports=function(c,g){var C=c[g];return null==C?void 0:o(C)}},1899:(n,s,t)=>{var o=function(c){return c&&c.Math==Math&&c};n.exports=o("object"==typeof globalThis&&globalThis)||o("object"==typeof window&&window)||o("object"==typeof self&&self)||o("object"==typeof t.g&&t.g)||function(){return this}()||Function("return this")()},953:(n,s,t)=>{var o=t(5329),c=t(9678),g=o({}.hasOwnProperty);n.exports=Object.hasOwn||function(C,D){return g(c(C),D)}},2840:(n,s,t)=>{var o=t(5746),c=t(5981),g=t(1333);n.exports=!o&&!c(function(){return 7!=Object.defineProperty(g("div"),"a",{get:function(){return 7}}).a})},7026:(n,s,t)=>{var o=t(1899),c=t(5329),g=t(5981),C=t(2532),D=o.Object,P=c("".split);n.exports=g(function(){return!D("z").propertyIsEnumerable(0)})?function(j){return"String"==C(j)?P(j,""):D(j)}:D},7475:n=>{n.exports=function(s){return"function"==typeof s}},7252:(n,s,t)=>{var o=t(5981),c=t(7475),g=/#|\.prototype\./,C=function(re,oe){var me=P[D(re)];return me==W||me!=j&&(c(oe)?o(oe):!!oe)},D=C.normalize=function(re){return String(re).replace(g,".").toLowerCase()},P=C.data={},j=C.NATIVE="N",W=C.POLYFILL="P";n.exports=C},941:(n,s,t)=>{var o=t(7475);n.exports=function(c){return"object"==typeof c?null!==c:o(c)}},2529:n=>{n.exports=!0},6664:(n,s,t)=>{var o=t(1899),c=t(224),g=t(7475),C=t(7046),D=t(2302),P=o.Object;n.exports=D?function(j){return"symbol"==typeof j}:function(j){var W=c("Symbol");return g(W)&&C(W.prototype,P(j))}},2497:(n,s,t)=>{var o=t(3385),c=t(5981);n.exports=!!Object.getOwnPropertySymbols&&!c(function(){var g=Symbol();return!String(g)||!(Object(g)instanceof Symbol)||!Symbol.sham&&o&&o<41})},5988:(n,s,t)=>{var o=t(1899),c=t(5746),g=t(2840),C=t(3937),D=t(6059),P=t(3894),j=o.TypeError,W=Object.defineProperty,re=Object.getOwnPropertyDescriptor;s.f=c?C?function(Fe,Re,Le){if(D(Fe),Re=P(Re),D(Le),"function"==typeof Fe&&"prototype"===Re&&"value"in Le&&"writable"in Le&&!Le.writable){var we=re(Fe,Re);we&&we.writable&&(Fe[Re]=Le.value,Le={configurable:"configurable"in Le?Le.configurable:we.configurable,enumerable:"enumerable"in Le?Le.enumerable:we.enumerable,writable:!1})}return W(Fe,Re,Le)}:W:function(Fe,Re,Le){if(D(Fe),Re=P(Re),D(Le),g)try{return W(Fe,Re,Le)}catch(we){}if("get"in Le||"set"in Le)throw j("Accessors not supported");return"value"in Le&&(Fe[Re]=Le.value),Fe}},9677:(n,s,t)=>{var o=t(5746),c=t(8834),g=t(6760),C=t(1887),D=t(4529),P=t(3894),j=t(953),W=t(2840),re=Object.getOwnPropertyDescriptor;s.f=o?re:function(oe,me){if(oe=D(oe),me=P(me),W)try{return re(oe,me)}catch(_e){}if(j(oe,me))return C(!c(g.f,oe,me),oe[me])}},7046:(n,s,t)=>{var o=t(5329);n.exports=o({}.isPrototypeOf)},6760:(n,s)=>{var t={}.propertyIsEnumerable,o=Object.getOwnPropertyDescriptor,c=o&&!t.call({1:2},1);s.f=c?function(g){var C=o(this,g);return!!C&&C.enumerable}:t},9811:(n,s,t)=>{var o=t(1899),c=t(8834),g=t(7475),C=t(941),D=o.TypeError;n.exports=function(P,j){var W,re;if("string"===j&&g(W=P.toString)&&!C(re=c(W,P))||g(W=P.valueOf)&&!C(re=c(W,P))||"string"!==j&&g(W=P.toString)&&!C(re=c(W,P)))return re;throw D("Can't convert object to primitive value")}},4058:n=>{n.exports={}},8219:(n,s,t)=>{var o=t(1899).TypeError;n.exports=function(c){if(null==c)throw o("Can't call method on "+c);return c}},4911:(n,s,t)=>{var o=t(1899),c=Object.defineProperty;n.exports=function(g,C){try{c(o,g,{value:C,configurable:!0,writable:!0})}catch(D){o[g]=C}return C}},3030:(n,s,t)=>{var o=t(1899),c=t(4911),g="__core-js_shared__",C=o[g]||c(g,{});n.exports=C},8726:(n,s,t)=>{var o=t(2529),c=t(3030);(n.exports=function(g,C){return c[g]||(c[g]=void 0!==C?C:{})})("versions",[]).push({version:"3.20.3",mode:o?"pure":"global",copyright:"\xa9 2014-2022 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.20.3/LICENSE",source:"https://github.com/zloirock/core-js"})},4529:(n,s,t)=>{var o=t(7026),c=t(8219);n.exports=function(g){return o(c(g))}},9678:(n,s,t)=>{var o=t(1899),c=t(8219),g=o.Object;n.exports=function(C){return g(c(C))}},6935:(n,s,t)=>{var o=t(1899),c=t(8834),g=t(941),C=t(6664),D=t(9733),P=t(9811),j=t(9813),W=o.TypeError,re=j("toPrimitive");n.exports=function(oe,me){if(!g(oe)||C(oe))return oe;var _e,Fe=D(oe,re);if(Fe){if(void 0===me&&(me="default"),_e=c(Fe,oe,me),!g(_e)||C(_e))return _e;throw W("Can't convert object to primitive value")}return void 0===me&&(me="number"),P(oe,me)}},3894:(n,s,t)=>{var o=t(6935),c=t(6664);n.exports=function(g){var C=o(g,"string");return c(C)?C:C+""}},9826:(n,s,t)=>{var o=t(1899).String;n.exports=function(c){try{return o(c)}catch(g){return"Object"}}},9418:(n,s,t)=>{var o=t(5329),c=0,g=Math.random(),C=o(1..toString);n.exports=function(D){return"Symbol("+(void 0===D?"":D)+")_"+C(++c+g,36)}},2302:(n,s,t)=>{var o=t(2497);n.exports=o&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},3937:(n,s,t)=>{var o=t(5746),c=t(5981);n.exports=o&&c(function(){return 42!=Object.defineProperty(function(){},"prototype",{value:42,writable:!1}).prototype})},9813:(n,s,t)=>{var o=t(1899),c=t(8726),g=t(953),C=t(9418),D=t(2497),P=t(2302),j=c("wks"),W=o.Symbol,re=W&&W.for,oe=P?W:W&&W.withoutSetter||C;n.exports=function(me){if(!g(j,me)||!D&&"string"!=typeof j[me]){var _e="Symbol."+me;j[me]=D&&g(W,me)?W[me]:P&&re?re(_e):oe(_e)}return j[me]}},6450:(n,s,t)=>{var o=t(6887),c=t(5746),g=t(5988).f;o({target:"Object",stat:!0,forced:Object.defineProperty!==g,sham:!c},{defineProperty:g})},1910:(n,s,t)=>{var o=t(8171);n.exports=o},7698:(n,s,t)=>{var o=t(8764).Buffer;function c(j){return j instanceof o||j instanceof Date||j instanceof RegExp}function g(j){if(j instanceof o){var W=o.alloc?o.alloc(j.length):new o(j.length);return j.copy(W),W}if(j instanceof Date)return new Date(j.getTime());if(j instanceof RegExp)return new RegExp(j);throw new Error("Unexpected situation")}function C(j){var W=[];return j.forEach(function(re,oe){W[oe]="object"==typeof re&&null!==re?Array.isArray(re)?C(re):c(re)?g(re):P({},re):re}),W}function D(j,W){return"__proto__"===W?void 0:j[W]}var P=n.exports=function(){if(arguments.length<1||"object"!=typeof arguments[0])return!1;if(arguments.length<2)return arguments[0];var j,W,re=arguments[0],oe=Array.prototype.slice.call(arguments,1);return oe.forEach(function(me){"object"!=typeof me||null===me||Array.isArray(me)||Object.keys(me).forEach(function(_e){return W=D(re,_e),(j=D(me,_e))===re?void 0:"object"!=typeof j||null===j?void(re[_e]=j):Array.isArray(j)?void(re[_e]=C(j)):c(j)?void(re[_e]=g(j)):"object"!=typeof W||null===W||Array.isArray(W)?void(re[_e]=P({},j)):void(re[_e]=P(W,j))})}),re}},7187:n=>{var s,t="object"==typeof Reflect?Reflect:null,o=t&&"function"==typeof t.apply?t.apply:function(Re,Le,we){return Function.prototype.apply.call(Re,Le,we)};s=t&&"function"==typeof t.ownKeys?t.ownKeys:Object.getOwnPropertySymbols?function(Re){return Object.getOwnPropertyNames(Re).concat(Object.getOwnPropertySymbols(Re))}:function(Re){return Object.getOwnPropertyNames(Re)};var c=Number.isNaN||function(Re){return Re!=Re};function g(){g.init.call(this)}n.exports=g,n.exports.once=function(Re,Le){return new Promise(function(we,U){function pt(Dt){Re.removeListener(Le,ht),U(Dt)}function ht(){"function"==typeof Re.removeListener&&Re.removeListener("error",pt),we([].slice.call(arguments))}var Dt;Fe(Re,Le,ht,{once:!0}),"error"!==Le&&("function"==typeof(Dt=Re).on&&Fe(Dt,"error",pt,{once:!0}))})},g.EventEmitter=g,g.prototype._events=void 0,g.prototype._eventsCount=0,g.prototype._maxListeners=void 0;var C=10;function D(Re){if("function"!=typeof Re)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof Re)}function P(Re){return void 0===Re._maxListeners?g.defaultMaxListeners:Re._maxListeners}function j(Re,Le,we,U){var pt,ht,Dt;if(D(we),void 0===(ht=Re._events)?(ht=Re._events=Object.create(null),Re._eventsCount=0):(void 0!==ht.newListener&&(Re.emit("newListener",Le,we.listener?we.listener:we),ht=Re._events),Dt=ht[Le]),void 0===Dt)Dt=ht[Le]=we,++Re._eventsCount;else if("function"==typeof Dt?Dt=ht[Le]=U?[we,Dt]:[Dt,we]:U?Dt.unshift(we):Dt.push(we),(pt=P(Re))>0&&Dt.length>pt&&!Dt.warned){Dt.warned=!0;var cn=new Error("Possible EventEmitter memory leak detected. "+Dt.length+" "+String(Le)+" listeners added. Use emitter.setMaxListeners() to increase limit");cn.name="MaxListenersExceededWarning",cn.emitter=Re,cn.type=Le,cn.count=Dt.length,console&&console.warn&&console.warn(cn)}return Re}function W(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function re(Re,Le,we){var U={fired:!1,wrapFn:void 0,target:Re,type:Le,listener:we},pt=W.bind(U);return pt.listener=we,U.wrapFn=pt,pt}function oe(Re,Le,we){var U=Re._events;if(void 0===U)return[];var pt=U[Le];return void 0===pt?[]:"function"==typeof pt?we?[pt.listener||pt]:[pt]:we?function(ht){for(var Dt=new Array(ht.length),Ft=0;Ft<Dt.length;++Ft)Dt[Ft]=ht[Ft].listener||ht[Ft];return Dt}(pt):_e(pt,pt.length)}function me(Re){var Le=this._events;if(void 0!==Le){var we=Le[Re];if("function"==typeof we)return 1;if(void 0!==we)return we.length}return 0}function _e(Re,Le){for(var we=new Array(Le),U=0;U<Le;++U)we[U]=Re[U];return we}function Fe(Re,Le,we,U){if("function"==typeof Re.on)U.once?Re.once(Le,we):Re.on(Le,we);else{if("function"!=typeof Re.addEventListener)throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type '+typeof Re);Re.addEventListener(Le,function pt(ht){U.once&&Re.removeEventListener(Le,pt),we(ht)})}}Object.defineProperty(g,"defaultMaxListeners",{enumerable:!0,get:function(){return C},set:function(Re){if("number"!=typeof Re||Re<0||c(Re))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+Re+".");C=Re}}),g.init=function(){void 0!==this._events&&this._events!==Object.getPrototypeOf(this)._events||(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0},g.prototype.setMaxListeners=function(Re){if("number"!=typeof Re||Re<0||c(Re))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+Re+".");return this._maxListeners=Re,this},g.prototype.getMaxListeners=function(){return P(this)},g.prototype.emit=function(Re){for(var Le=[],we=1;we<arguments.length;we++)Le.push(arguments[we]);var U="error"===Re,pt=this._events;if(void 0!==pt)U=U&&void 0===pt.error;else if(!U)return!1;if(U){var ht;if(Le.length>0&&(ht=Le[0]),ht instanceof Error)throw ht;var Dt=new Error("Unhandled error."+(ht?" ("+ht.message+")":""));throw Dt.context=ht,Dt}var Ft=pt[Re];if(void 0===Ft)return!1;if("function"==typeof Ft)o(Ft,this,Le);else{var cn=Ft.length,kt=_e(Ft,cn);for(we=0;we<cn;++we)o(kt[we],this,Le)}return!0},g.prototype.on=g.prototype.addListener=function(Re,Le){return j(this,Re,Le,!1)},g.prototype.prependListener=function(Re,Le){return j(this,Re,Le,!0)},g.prototype.once=function(Re,Le){return D(Le),this.on(Re,re(this,Re,Le)),this},g.prototype.prependOnceListener=function(Re,Le){return D(Le),this.prependListener(Re,re(this,Re,Le)),this},g.prototype.off=g.prototype.removeListener=function(Re,Le){var we,U,pt,ht,Dt;if(D(Le),void 0===(U=this._events))return this;if(void 0===(we=U[Re]))return this;if(we===Le||we.listener===Le)0==--this._eventsCount?this._events=Object.create(null):(delete U[Re],U.removeListener&&this.emit("removeListener",Re,we.listener||Le));else if("function"!=typeof we){for(pt=-1,ht=we.length-1;ht>=0;ht--)if(we[ht]===Le||we[ht].listener===Le){Dt=we[ht].listener,pt=ht;break}if(pt<0)return this;0===pt?we.shift():function(Ft,cn){for(;cn+1<Ft.length;cn++)Ft[cn]=Ft[cn+1];Ft.pop()}(we,pt),1===we.length&&(U[Re]=we[0]),void 0!==U.removeListener&&this.emit("removeListener",Re,Dt||Le)}return this},g.prototype.removeAllListeners=function(Re){var Le,we,U;if(void 0===(we=this._events))return this;if(void 0===we.removeListener)return 0===arguments.length?(this._events=Object.create(null),this._eventsCount=0):void 0!==we[Re]&&(0==--this._eventsCount?this._events=Object.create(null):delete we[Re]),this;if(0===arguments.length){var pt,ht=Object.keys(we);for(U=0;U<ht.length;++U)"removeListener"!==(pt=ht[U])&&this.removeAllListeners(pt);return this.removeAllListeners("removeListener"),this._events=Object.create(null),this._eventsCount=0,this}if("function"==typeof(Le=we[Re]))this.removeListener(Re,Le);else if(void 0!==Le)for(U=Le.length-1;U>=0;U--)this.removeListener(Re,Le[U]);return this},g.prototype.listeners=function(Re){return oe(this,Re,!0)},g.prototype.rawListeners=function(Re){return oe(this,Re,!1)},g.listenerCount=function(Re,Le){return"function"==typeof Re.listenerCount?Re.listenerCount(Le):me.call(Re,Le)},g.prototype.listenerCount=me,g.prototype.eventNames=function(){return this._eventsCount>0?s(this._events):[]}},5717:n=>{n.exports="function"==typeof Object.create?function(s,t){t&&(s.super_=t,s.prototype=Object.create(t.prototype,{constructor:{value:s,enumerable:!1,writable:!0,configurable:!0}}))}:function(s,t){if(t){s.super_=t;var o=function(){};o.prototype=t.prototype,s.prototype=new o,s.prototype.constructor=s}}},4155:n=>{var s,t,o=n.exports={};function c(){throw new Error("setTimeout has not been defined")}function g(){throw new Error("clearTimeout has not been defined")}function C(Fe){if(s===setTimeout)return setTimeout(Fe,0);if((s===c||!s)&&setTimeout)return s=setTimeout,setTimeout(Fe,0);try{return s(Fe,0)}catch(Re){try{return s.call(null,Fe,0)}catch(Le){return s.call(this,Fe,0)}}}!function(){try{s="function"==typeof setTimeout?setTimeout:c}catch(Fe){s=c}try{t="function"==typeof clearTimeout?clearTimeout:g}catch(Fe){t=g}}();var D,P=[],j=!1,W=-1;function re(){j&&D&&(j=!1,D.length?P=D.concat(P):W=-1,P.length&&oe())}function oe(){if(!j){var Fe=C(re);j=!0;for(var Re=P.length;Re;){for(D=P,P=[];++W<Re;)D&&D[W].run();W=-1,Re=P.length}D=null,j=!1,function(Le){if(t===clearTimeout)return clearTimeout(Le);if((t===g||!t)&&clearTimeout)return t=clearTimeout,clearTimeout(Le);try{t(Le)}catch(we){try{return t.call(null,Le)}catch(U){return t.call(this,Le)}}}(Fe)}}function me(Fe,Re){this.fun=Fe,this.array=Re}function _e(){}o.nextTick=function(Fe){var Re=new Array(arguments.length-1);if(arguments.length>1)for(var Le=1;Le<arguments.length;Le++)Re[Le-1]=arguments[Le];P.push(new me(Fe,Re)),1!==P.length||j||C(oe)},me.prototype.run=function(){this.fun.apply(null,this.array)},o.title="browser",o.browser=!0,o.env={},o.argv=[],o.version="",o.versions={},o.on=_e,o.addListener=_e,o.once=_e,o.off=_e,o.removeListener=_e,o.removeAllListeners=_e,o.emit=_e,o.prependListener=_e,o.prependOnceListener=_e,o.listeners=function(Fe){return[]},o.binding=function(Fe){throw new Error("process.binding is not supported")},o.cwd=function(){return"/"},o.chdir=function(Fe){throw new Error("process.chdir is not supported")},o.umask=function(){return 0}},1798:(n,s,t)=>{var o=t(4155),c=65536,C=t(396).Buffer,D=t.g.crypto||t.g.msCrypto;n.exports=D&&D.getRandomValues?function(P,j){if(P>4294967295)throw new RangeError("requested too many random bytes");var W=C.allocUnsafe(P);if(P>0)if(P>c)for(var re=0;re<P;re+=c)D.getRandomValues(W.slice(re,re+c));else D.getRandomValues(W);return"function"==typeof j?o.nextTick(function(){j(null,W)}):W}:function(){throw new Error("Secure random number generation is not supported by this browser.\nUse Chrome, Firefox or Internet Explorer 11")}},4281:n=>{var s={};function t(c,g,C){C||(C=Error);var D=function(P){var j,W;function re(oe,me,_e){return P.call(this,"string"==typeof g?g:g(oe,me,_e))||this}return W=P,(j=re).prototype=Object.create(W.prototype),j.prototype.constructor=j,j.__proto__=W,re}(C);D.prototype.name=C.name,D.prototype.code=c,s[c]=D}function o(c,g){if(Array.isArray(c)){var C=c.length;return c=c.map(function(D){return String(D)}),C>2?"one of ".concat(g," ").concat(c.slice(0,C-1).join(", "),", or ")+c[C-1]:2===C?"one of ".concat(g," ").concat(c[0]," or ").concat(c[1]):"of ".concat(g," ").concat(c[0])}return"of ".concat(g," ").concat(String(c))}t("ERR_INVALID_OPT_VALUE",function(c,g){return'The value "'+g+'" is invalid for option "'+c+'"'},TypeError),t("ERR_INVALID_ARG_TYPE",function(c,g,C){var D,W,oe,_e;if("string"==typeof g&&"not "===g.substr(0,"not ".length)?(D="must not be",g=g.replace(/^not /,"")):D="must be",oe=c,(void 0===_e||_e>oe.length)&&(_e=oe.length)," argument"===oe.substring(_e-" argument".length,_e))W="The ".concat(c," ").concat(D," ").concat(o(g,"type"));else{var re=function(oe,me,_e){return"number"!=typeof _e&&(_e=0),!(_e+".".length>oe.length)&&-1!==oe.indexOf(".",_e)}(c)?"property":"argument";W='The "'.concat(c,'" ').concat(re," ").concat(D," ").concat(o(g,"type"))}return W+". Received type ".concat(typeof C)},TypeError),t("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF"),t("ERR_METHOD_NOT_IMPLEMENTED",function(c){return"The "+c+" method is not implemented"}),t("ERR_STREAM_PREMATURE_CLOSE","Premature close"),t("ERR_STREAM_DESTROYED",function(c){return"Cannot call "+c+" after a stream was destroyed"}),t("ERR_MULTIPLE_CALLBACK","Callback called multiple times"),t("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable"),t("ERR_STREAM_WRITE_AFTER_END","write after end"),t("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError),t("ERR_UNKNOWN_ENCODING",function(c){return"Unknown encoding: "+c},TypeError),t("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event"),n.exports.q=s},6753:(n,s,t)=>{var o=t(4155),c=Object.keys||function(me){var _e=[];for(var Fe in me)_e.push(Fe);return _e};n.exports=W;var g=t(9481),C=t(4229);t(5717)(W,g);for(var D=c(C.prototype),P=0;P<D.length;P++){var j=D[P];W.prototype[j]||(W.prototype[j]=C.prototype[j])}function W(me){if(!(this instanceof W))return new W(me);g.call(this,me),C.call(this,me),this.allowHalfOpen=!0,me&&(!1===me.readable&&(this.readable=!1),!1===me.writable&&(this.writable=!1),!1===me.allowHalfOpen&&(this.allowHalfOpen=!1,this.once("end",re)))}function re(){this._writableState.ended||o.nextTick(oe,this)}function oe(me){me.end()}Object.defineProperty(W.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),Object.defineProperty(W.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}}),Object.defineProperty(W.prototype,"writableLength",{enumerable:!1,get:function(){return this._writableState.length}}),Object.defineProperty(W.prototype,"destroyed",{enumerable:!1,get:function(){return void 0!==this._readableState&&void 0!==this._writableState&&this._readableState.destroyed&&this._writableState.destroyed},set:function(me){void 0!==this._readableState&&void 0!==this._writableState&&(this._readableState.destroyed=me,this._writableState.destroyed=me)}})},2725:(n,s,t)=>{n.exports=c;var o=t(4605);function c(g){if(!(this instanceof c))return new c(g);o.call(this,g)}t(5717)(c,o),c.prototype._transform=function(g,C,D){D(null,g)}},9481:(n,s,t)=>{var o,c=t(4155);n.exports=kt,kt.ReadableState=cn,t(7187);var j,g=function(Sn,hn){return Sn.listeners(hn).length},C=t(2503),D=t(8764).Buffer,P=t.g.Uint8Array||function(){},W=t(4616);j=W&&W.debuglog?W.debuglog("stream"):function(){};var re,oe,me,_e=t(7327),Fe=t(1195),Re=t(2457).getHighWaterMark,Le=t(4281).q,we=Le.ERR_INVALID_ARG_TYPE,U=Le.ERR_STREAM_PUSH_AFTER_EOF,pt=Le.ERR_METHOD_NOT_IMPLEMENTED,ht=Le.ERR_STREAM_UNSHIFT_AFTER_END_EVENT;t(5717)(kt,C);var Dt=Fe.errorOrDestroy,Ft=["error","close","destroy","pause","resume"];function cn(Sn,hn,_r){o=o||t(6753),"boolean"!=typeof _r&&(_r=hn instanceof o),this.objectMode=!!(Sn=Sn||{}).objectMode,_r&&(this.objectMode=this.objectMode||!!Sn.readableObjectMode),this.highWaterMark=Re(this,Sn,"readableHighWaterMark",_r),this.buffer=new _e,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.paused=!0,this.emitClose=!1!==Sn.emitClose,this.autoDestroy=!!Sn.autoDestroy,this.destroyed=!1,this.defaultEncoding=Sn.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,Sn.encoding&&(re||(re=t(2553).s),this.decoder=new re(Sn.encoding),this.encoding=Sn.encoding)}function kt(Sn){if(o=o||t(6753),!(this instanceof kt))return new kt(Sn);this._readableState=new cn(Sn,this,this instanceof o),this.readable=!0,Sn&&("function"==typeof Sn.read&&(this._read=Sn.read),"function"==typeof Sn.destroy&&(this._destroy=Sn.destroy)),C.call(this)}function wn(Sn,hn,_r,Fi,_s){j("readableAddChunk",hn);var Ho,Us,zs,Di,oo,yo=Sn._readableState;if(null===hn)yo.reading=!1,function(Us,zs){if(j("onEofChunk"),!zs.ended){if(zs.decoder){var Di=zs.decoder.end();Di&&Di.length&&(zs.buffer.push(Di),zs.length+=zs.objectMode?1:Di.length)}zs.ended=!0,zs.sync?Nr(Us):(zs.needReadable=!1,zs.emittedReadable||(zs.emittedReadable=!0,xr(Us)))}}(Sn,yo);else if(_s||(Us=yo,D.isBuffer(oo=zs=hn)||oo instanceof P||"string"==typeof zs||void 0===zs||Us.objectMode||(Di=new we("chunk",["string","Buffer","Uint8Array"],zs)),Ho=Di),Ho)Dt(Sn,Ho);else if(yo.objectMode||hn&&hn.length>0)if("string"==typeof hn||yo.objectMode||Object.getPrototypeOf(hn)===D.prototype||(hn=function(Us){return D.from(Us)}(hn)),Fi)yo.endEmitted?Dt(Sn,new ht):Tn(Sn,yo,hn,!0);else if(yo.ended)Dt(Sn,new U);else{if(yo.destroyed)return!1;yo.reading=!1,yo.decoder&&!_r?(hn=yo.decoder.write(hn),yo.objectMode||0!==hn.length?Tn(Sn,yo,hn,!1):fn(Sn,yo)):Tn(Sn,yo,hn,!1)}else Fi||(yo.reading=!1,fn(Sn,yo));return!yo.ended&&(yo.length<yo.highWaterMark||0===yo.length)}function Tn(Sn,hn,_r,Fi){hn.flowing&&0===hn.length&&!hn.sync?(hn.awaitDrain=0,Sn.emit("data",_r)):(hn.length+=hn.objectMode?1:_r.length,Fi?hn.buffer.unshift(_r):hn.buffer.push(_r),hn.needReadable&&Nr(Sn)),fn(Sn,hn)}Object.defineProperty(kt.prototype,"destroyed",{enumerable:!1,get:function(){return void 0!==this._readableState&&this._readableState.destroyed},set:function(Sn){this._readableState&&(this._readableState.destroyed=Sn)}}),kt.prototype.destroy=Fe.destroy,kt.prototype._undestroy=Fe.undestroy,kt.prototype._destroy=function(Sn,hn){hn(Sn)},kt.prototype.push=function(Sn,hn){var _r,Fi=this._readableState;return Fi.objectMode?_r=!0:"string"==typeof Sn&&((hn=hn||Fi.defaultEncoding)!==Fi.encoding&&(Sn=D.from(Sn,hn),hn=""),_r=!0),wn(this,Sn,hn,!1,_r)},kt.prototype.unshift=function(Sn){return wn(this,Sn,null,!0,!1)},kt.prototype.isPaused=function(){return!1===this._readableState.flowing},kt.prototype.setEncoding=function(Sn){re||(re=t(2553).s);var hn=new re(Sn);this._readableState.decoder=hn,this._readableState.encoding=this._readableState.decoder.encoding;for(var _r=this._readableState.buffer.head,Fi="";null!==_r;)Fi+=hn.write(_r.data),_r=_r.next;return this._readableState.buffer.clear(),""!==Fi&&this._readableState.buffer.push(Fi),this._readableState.length=Fi.length,this};var Hr=1073741824;function sr(Sn,hn){return Sn<=0||0===hn.length&&hn.ended?0:hn.objectMode?1:Sn!=Sn?hn.flowing&&hn.length?hn.buffer.head.data.length:hn.length:(Sn>hn.highWaterMark&&(hn.highWaterMark=((_r=Sn)>=Hr?_r=Hr:(_r--,_r|=_r>>>1,_r|=_r>>>2,_r|=_r>>>4,_r|=_r>>>8,_r|=_r>>>16,_r++),_r)),Sn<=hn.length?Sn:hn.ended?hn.length:(hn.needReadable=!0,0));var _r}function Nr(Sn){var hn=Sn._readableState;j("emitReadable",hn.needReadable,hn.emittedReadable),hn.needReadable=!1,hn.emittedReadable||(j("emitReadable",hn.flowing),hn.emittedReadable=!0,c.nextTick(xr,Sn))}function xr(Sn){var hn=Sn._readableState;j("emitReadable_",hn.destroyed,hn.length,hn.ended),hn.destroyed||!hn.length&&!hn.ended||(Sn.emit("readable"),hn.emittedReadable=!1),hn.needReadable=!hn.flowing&&!hn.ended&&hn.length<=hn.highWaterMark,jr(Sn)}function fn(Sn,hn){hn.readingMore||(hn.readingMore=!0,c.nextTick(Rn,Sn,hn))}function Rn(Sn,hn){for(;!hn.reading&&!hn.ended&&(hn.length<hn.highWaterMark||hn.flowing&&0===hn.length);){var _r=hn.length;if(j("maybeReadMore read 0"),Sn.read(0),_r===hn.length)break}hn.readingMore=!1}function kn(Sn){var hn=Sn._readableState;hn.readableListening=Sn.listenerCount("readable")>0,hn.resumeScheduled&&!hn.paused?hn.flowing=!0:Sn.listenerCount("data")>0&&Sn.resume()}function Wn(Sn){j("readable nexttick read 0"),Sn.read(0)}function bn(Sn,hn){j("resume",hn.reading),hn.reading||Sn.read(0),hn.resumeScheduled=!1,Sn.emit("resume"),jr(Sn),hn.flowing&&!hn.reading&&Sn.read(0)}function jr(Sn){var hn=Sn._readableState;for(j("flow",hn.flowing);hn.flowing&&null!==Sn.read(););}function ji(Sn,hn){return 0===hn.length?null:(hn.objectMode?_r=hn.buffer.shift():!Sn||Sn>=hn.length?(_r=hn.decoder?hn.buffer.join(""):1===hn.buffer.length?hn.buffer.first():hn.buffer.concat(hn.length),hn.buffer.clear()):_r=hn.buffer.consume(Sn,hn.decoder),_r);var _r}function oi(Sn){var hn=Sn._readableState;j("endReadable",hn.endEmitted),hn.endEmitted||(hn.ended=!0,c.nextTick(Ui,hn,Sn))}function Ui(Sn,hn){if(j("endReadableNT",Sn.endEmitted,Sn.length),!Sn.endEmitted&&0===Sn.length&&(Sn.endEmitted=!0,hn.readable=!1,hn.emit("end"),Sn.autoDestroy)){var _r=hn._writableState;(!_r||_r.autoDestroy&&_r.finished)&&hn.destroy()}}function Xr(Sn,hn){for(var _r=0,Fi=Sn.length;_r<Fi;_r++)if(Sn[_r]===hn)return _r;return-1}kt.prototype.read=function(Sn){j("read",Sn),Sn=parseInt(Sn,10);var hn=this._readableState,_r=Sn;if(0!==Sn&&(hn.emittedReadable=!1),0===Sn&&hn.needReadable&&((0!==hn.highWaterMark?hn.length>=hn.highWaterMark:hn.length>0)||hn.ended))return j("read: emitReadable",hn.length,hn.ended),0===hn.length&&hn.ended?oi(this):Nr(this),null;if(0===(Sn=sr(Sn,hn))&&hn.ended)return 0===hn.length&&oi(this),null;var Fi,_s=hn.needReadable;return j("need readable",_s),(0===hn.length||hn.length-Sn<hn.highWaterMark)&&j("length less than watermark",_s=!0),hn.ended||hn.reading?j("reading or ended",_s=!1):_s&&(j("do read"),hn.reading=!0,hn.sync=!0,0===hn.length&&(hn.needReadable=!0),this._read(hn.highWaterMark),hn.sync=!1,hn.reading||(Sn=sr(_r,hn))),null===(Fi=Sn>0?ji(Sn,hn):null)?(hn.needReadable=hn.length<=hn.highWaterMark,Sn=0):(hn.length-=Sn,hn.awaitDrain=0),0===hn.length&&(hn.ended||(hn.needReadable=!0),_r!==Sn&&hn.ended&&oi(this)),null!==Fi&&this.emit("data",Fi),Fi},kt.prototype._read=function(Sn){Dt(this,new pt("_read()"))},kt.prototype.pipe=function(Sn,hn){var _r=this,Fi=this._readableState;switch(Fi.pipesCount){case 0:Fi.pipes=Sn;break;case 1:Fi.pipes=[Fi.pipes,Sn];break;default:Fi.pipes.push(Sn)}Fi.pipesCount+=1,j("pipe count=%d opts=%j",Fi.pipesCount,hn);var _s=hn&&!1===hn.end||Sn===c.stdout||Sn===c.stderr?Mt:yo;function yo(){j("onend"),Sn.end()}Fi.endEmitted?c.nextTick(_s):_r.once("end",_s),Sn.on("unpipe",function Ho(St,Un){j("onunpipe"),St===_r&&Un&&!1===Un.hasUnpiped&&(Un.hasUnpiped=!0,j("cleanup"),Sn.removeListener("close",ho),Sn.removeListener("finish",Ze),Sn.removeListener("drain",Us),Sn.removeListener("error",oo),Sn.removeListener("unpipe",Ho),_r.removeListener("end",yo),_r.removeListener("end",Mt),_r.removeListener("data",Di),zs=!0,!Fi.awaitDrain||Sn._writableState&&!Sn._writableState.needDrain||Us())});var St,Us=(St=_r,function(){var Un=St._readableState;j("pipeOnDrain",Un.awaitDrain),Un.awaitDrain&&Un.awaitDrain--,0===Un.awaitDrain&&g(St,"data")&&(Un.flowing=!0,jr(St))});Sn.on("drain",Us);var zs=!1;function Di(St){j("ondata");var Un=Sn.write(St);j("dest.write",Un),!1===Un&&((1===Fi.pipesCount&&Fi.pipes===Sn||Fi.pipesCount>1&&-1!==Xr(Fi.pipes,Sn))&&!zs&&(j("false write response, pause",Fi.awaitDrain),Fi.awaitDrain++),_r.pause())}function oo(St){j("onerror",St),Mt(),Sn.removeListener("error",oo),0===g(Sn,"error")&&Dt(Sn,St)}function ho(){Sn.removeListener("finish",Ze),Mt()}function Ze(){j("onfinish"),Sn.removeListener("close",ho),Mt()}function Mt(){j("unpipe"),_r.unpipe(Sn)}return _r.on("data",Di),function(St,Un,pr){if("function"==typeof St.prependListener)return St.prependListener(Un,pr);St._events&&St._events[Un]?Array.isArray(St._events[Un])?St._events[Un].unshift(pr):St._events[Un]=[pr,St._events[Un]]:St.on(Un,pr)}(Sn,"error",oo),Sn.once("close",ho),Sn.once("finish",Ze),Sn.emit("pipe",_r),Fi.flowing||(j("pipe resume"),_r.resume()),Sn},kt.prototype.unpipe=function(Sn){var hn=this._readableState,_r={hasUnpiped:!1};if(0===hn.pipesCount)return this;if(1===hn.pipesCount)return Sn&&Sn!==hn.pipes||(Sn||(Sn=hn.pipes),hn.pipes=null,hn.pipesCount=0,hn.flowing=!1,Sn&&Sn.emit("unpipe",this,_r)),this;if(!Sn){var Fi=hn.pipes,_s=hn.pipesCount;hn.pipes=null,hn.pipesCount=0,hn.flowing=!1;for(var Ho=0;Ho<_s;Ho++)Fi[Ho].emit("unpipe",this,{hasUnpiped:!1});return this}var yo=Xr(hn.pipes,Sn);return-1===yo||(hn.pipes.splice(yo,1),hn.pipesCount-=1,1===hn.pipesCount&&(hn.pipes=hn.pipes[0]),Sn.emit("unpipe",this,_r)),this},kt.prototype.addListener=kt.prototype.on=function(Sn,hn){var _r=C.prototype.on.call(this,Sn,hn),Fi=this._readableState;return"data"===Sn?(Fi.readableListening=this.listenerCount("readable")>0,!1!==Fi.flowing&&this.resume()):"readable"===Sn&&(Fi.endEmitted||Fi.readableListening||(Fi.readableListening=Fi.needReadable=!0,Fi.flowing=!1,Fi.emittedReadable=!1,j("on readable",Fi.length,Fi.reading),Fi.length?Nr(this):Fi.reading||c.nextTick(Wn,this))),_r},kt.prototype.removeListener=function(Sn,hn){var _r=C.prototype.removeListener.call(this,Sn,hn);return"readable"===Sn&&c.nextTick(kn,this),_r},kt.prototype.removeAllListeners=function(Sn){var hn=C.prototype.removeAllListeners.apply(this,arguments);return"readable"!==Sn&&void 0!==Sn||c.nextTick(kn,this),hn},kt.prototype.resume=function(){var _r,Sn=this._readableState;return Sn.flowing||(j("resume"),Sn.flowing=!Sn.readableListening,this,(_r=Sn).resumeScheduled||(_r.resumeScheduled=!0,c.nextTick(bn,this,_r))),Sn.paused=!1,this},kt.prototype.pause=function(){return j("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(j("pause"),this._readableState.flowing=!1,this.emit("pause")),this._readableState.paused=!0,this},kt.prototype.wrap=function(Sn){var hn=this,_r=this._readableState,Fi=!1;for(var _s in Sn.on("end",function(){if(j("wrapped end"),_r.decoder&&!_r.ended){var yo=_r.decoder.end();yo&&yo.length&&hn.push(yo)}hn.push(null)}),Sn.on("data",function(yo){j("wrapped data"),_r.decoder&&(yo=_r.decoder.write(yo)),_r.objectMode&&null==yo||(_r.objectMode||yo&&yo.length)&&(hn.push(yo)||(Fi=!0,Sn.pause()))}),Sn)void 0===this[_s]&&"function"==typeof Sn[_s]&&(this[_s]=function(yo){return function(){return Sn[yo].apply(Sn,arguments)}}(_s));for(var Ho=0;Ho<Ft.length;Ho++)Sn.on(Ft[Ho],this.emit.bind(this,Ft[Ho]));return this._read=function(yo){j("wrapped _read",yo),Fi&&(Fi=!1,Sn.resume())},this},"function"==typeof Symbol&&(kt.prototype[Symbol.asyncIterator]=function(){return void 0===oe&&(oe=t(5850)),oe(this)}),Object.defineProperty(kt.prototype,"readableHighWaterMark",{enumerable:!1,get:function(){return this._readableState.highWaterMark}}),Object.defineProperty(kt.prototype,"readableBuffer",{enumerable:!1,get:function(){return this._readableState&&this._readableState.buffer}}),Object.defineProperty(kt.prototype,"readableFlowing",{enumerable:!1,get:function(){return this._readableState.flowing},set:function(Sn){this._readableState&&(this._readableState.flowing=Sn)}}),kt._fromList=ji,Object.defineProperty(kt.prototype,"readableLength",{enumerable:!1,get:function(){return this._readableState.length}}),"function"==typeof Symbol&&(kt.from=function(Sn,hn){return void 0===me&&(me=t(5167)),me(kt,Sn,hn)})},4605:(n,s,t)=>{n.exports=W;var o=t(4281).q,c=o.ERR_METHOD_NOT_IMPLEMENTED,g=o.ERR_MULTIPLE_CALLBACK,C=o.ERR_TRANSFORM_ALREADY_TRANSFORMING,D=o.ERR_TRANSFORM_WITH_LENGTH_0,P=t(6753);function j(me,_e){var Fe=this._transformState;Fe.transforming=!1;var Re=Fe.writecb;if(null===Re)return this.emit("error",new g);Fe.writechunk=null,Fe.writecb=null,null!=_e&&this.push(_e),Re(me);var Le=this._readableState;Le.reading=!1,(Le.needReadable||Le.length<Le.highWaterMark)&&this._read(Le.highWaterMark)}function W(me){if(!(this instanceof W))return new W(me);P.call(this,me),this._transformState={afterTransform:j.bind(this),needTransform:!1,transforming:!1,writecb:null,writechunk:null,writeencoding:null},this._readableState.needReadable=!0,this._readableState.sync=!1,me&&("function"==typeof me.transform&&(this._transform=me.transform),"function"==typeof me.flush&&(this._flush=me.flush)),this.on("prefinish",re)}function re(){var me=this;"function"!=typeof this._flush||this._readableState.destroyed?oe(this,null,null):this._flush(function(_e,Fe){oe(me,_e,Fe)})}function oe(me,_e,Fe){if(_e)return me.emit("error",_e);if(null!=Fe&&me.push(Fe),me._writableState.length)throw new D;if(me._transformState.transforming)throw new C;return me.push(null)}t(5717)(W,P),W.prototype.push=function(me,_e){return this._transformState.needTransform=!1,P.prototype.push.call(this,me,_e)},W.prototype._transform=function(me,_e,Fe){Fe(new c("_transform()"))},W.prototype._write=function(me,_e,Fe){var Re=this._transformState;if(Re.writecb=Fe,Re.writechunk=me,Re.writeencoding=_e,!Re.transforming){var Le=this._readableState;(Re.needTransform||Le.needReadable||Le.length<Le.highWaterMark)&&this._read(Le.highWaterMark)}},W.prototype._read=function(me){var _e=this._transformState;null===_e.writechunk||_e.transforming?_e.needTransform=!0:(_e.transforming=!0,this._transform(_e.writechunk,_e.writeencoding,_e.afterTransform))},W.prototype._destroy=function(me,_e){P.prototype._destroy.call(this,me,function(Fe){_e(Fe)})}},4229:(n,s,t)=>{var o,c=t(4155);function g(fn){var Rn=this;this.next=null,this.entry=null,this.finish=function(){!function(kn,Wn,bn){var jr=kn.entry;for(kn.entry=null;jr;){var ji=jr.callback;Wn.pendingcb--,ji(void 0),jr=jr.next}Wn.corkedRequestsFree.next=kn}(Rn,fn)}}n.exports=kt,kt.WritableState=cn;var W,C={deprecate:t(4927)},D=t(2503),P=t(8764).Buffer,j=t.g.Uint8Array||function(){},re=t(1195),oe=t(2457).getHighWaterMark,me=t(4281).q,_e=me.ERR_INVALID_ARG_TYPE,Fe=me.ERR_METHOD_NOT_IMPLEMENTED,Re=me.ERR_MULTIPLE_CALLBACK,Le=me.ERR_STREAM_CANNOT_PIPE,we=me.ERR_STREAM_DESTROYED,U=me.ERR_STREAM_NULL_VALUES,pt=me.ERR_STREAM_WRITE_AFTER_END,ht=me.ERR_UNKNOWN_ENCODING,Dt=re.errorOrDestroy;function Ft(){}function cn(fn,Rn,kn){o=o||t(6753),"boolean"!=typeof kn&&(kn=Rn instanceof o),this.objectMode=!!(fn=fn||{}).objectMode,kn&&(this.objectMode=this.objectMode||!!fn.writableObjectMode),this.highWaterMark=oe(this,fn,"writableHighWaterMark",kn),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1,this.decodeStrings=!(!1===fn.decodeStrings),this.defaultEncoding=fn.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(bn){!function(jr,ji){var hn,oi=jr._writableState,Ui=oi.sync,Xr=oi.writecb;if("function"!=typeof Xr)throw new Re;if((hn=oi).writing=!1,hn.writecb=null,hn.length-=hn.writelen,hn.writelen=0,ji)!function(hn,_r,Fi,_s,Ho){--_r.pendingcb,Fi?(c.nextTick(Ho,_s),c.nextTick(xr,hn,_r),hn._writableState.errorEmitted=!0,Dt(hn,_s)):(Ho(_s),hn._writableState.errorEmitted=!0,Dt(hn,_s),xr(hn,_r))}(jr,oi,Ui,ji,Xr);else{var Sn=sr(oi)||jr.destroyed;Sn||oi.corked||oi.bufferProcessing||!oi.bufferedRequest||Hr(jr,oi),Ui?c.nextTick(Tn,jr,oi,Sn,Xr):Tn(jr,oi,Sn,Xr)}}(Rn,bn)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.emitClose=!1!==fn.emitClose,this.autoDestroy=!!fn.autoDestroy,this.bufferedRequestCount=0,this.corkedRequestsFree=new g(this)}function kt(fn){var Rn=this instanceof(o=o||t(6753));if(!Rn&&!W.call(kt,this))return new kt(fn);this._writableState=new cn(fn,this,Rn),this.writable=!0,fn&&("function"==typeof fn.write&&(this._write=fn.write),"function"==typeof fn.writev&&(this._writev=fn.writev),"function"==typeof fn.destroy&&(this._destroy=fn.destroy),"function"==typeof fn.final&&(this._final=fn.final)),D.call(this)}function wn(fn,Rn,kn,Wn,bn,jr,ji){Rn.writelen=Wn,Rn.writecb=ji,Rn.writing=!0,Rn.sync=!0,Rn.destroyed?Rn.onwrite(new we("write")):kn?fn._writev(bn,Rn.onwrite):fn._write(bn,jr,Rn.onwrite),Rn.sync=!1}function Tn(fn,Rn,kn,Wn){var bn,jr;kn||(bn=fn,0===(jr=Rn).length&&jr.needDrain&&(jr.needDrain=!1,bn.emit("drain"))),Rn.pendingcb--,Wn(),xr(fn,Rn)}function Hr(fn,Rn){Rn.bufferProcessing=!0;var kn=Rn.bufferedRequest;if(fn._writev&&kn&&kn.next){var bn=new Array(Rn.bufferedRequestCount),jr=Rn.corkedRequestsFree;jr.entry=kn;for(var ji=0,oi=!0;kn;)bn[ji]=kn,kn.isBuf||(oi=!1),kn=kn.next,ji+=1;bn.allBuffers=oi,wn(fn,Rn,!0,Rn.length,bn,"",jr.finish),Rn.pendingcb++,Rn.lastBufferedRequest=null,jr.next?(Rn.corkedRequestsFree=jr.next,jr.next=null):Rn.corkedRequestsFree=new g(Rn),Rn.bufferedRequestCount=0}else{for(;kn;){var Ui=kn.chunk;if(wn(fn,Rn,!1,Rn.objectMode?1:Ui.length,Ui,kn.encoding,kn.callback),kn=kn.next,Rn.bufferedRequestCount--,Rn.writing)break}null===kn&&(Rn.lastBufferedRequest=null)}Rn.bufferedRequest=kn,Rn.bufferProcessing=!1}function sr(fn){return fn.ending&&0===fn.length&&null===fn.bufferedRequest&&!fn.finished&&!fn.writing}function Nr(fn,Rn){fn._final(function(kn){Rn.pendingcb--,kn&&Dt(fn,kn),Rn.prefinished=!0,fn.emit("prefinish"),xr(fn,Rn)})}function xr(fn,Rn){var bn,jr,kn=sr(Rn);if(kn&&(bn=fn,(jr=Rn).prefinished||jr.finalCalled||("function"!=typeof bn._final||jr.destroyed?(jr.prefinished=!0,bn.emit("prefinish")):(jr.pendingcb++,jr.finalCalled=!0,c.nextTick(Nr,bn,jr))),0===Rn.pendingcb&&(Rn.finished=!0,fn.emit("finish"),Rn.autoDestroy))){var Wn=fn._readableState;(!Wn||Wn.autoDestroy&&Wn.endEmitted)&&fn.destroy()}return kn}t(5717)(kt,D),cn.prototype.getBuffer=function(){for(var fn=this.bufferedRequest,Rn=[];fn;)Rn.push(fn),fn=fn.next;return Rn},function(){try{Object.defineProperty(cn.prototype,"buffer",{get:C.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(fn){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(W=Function.prototype[Symbol.hasInstance],Object.defineProperty(kt,Symbol.hasInstance,{value:function(fn){return!!W.call(this,fn)||this===kt&&fn&&fn._writableState instanceof cn}})):W=function(fn){return fn instanceof this},kt.prototype.pipe=function(){Dt(this,new Le)},kt.prototype.write=function(fn,Rn,kn){var Wn,oi,Ui,Xr,bn=this._writableState,jr=!1,ji=!bn.objectMode&&(P.isBuffer(Wn=fn)||Wn instanceof j);return ji&&!P.isBuffer(fn)&&(fn=P.from(fn)),"function"==typeof Rn&&(kn=Rn,Rn=null),ji?Rn="buffer":Rn||(Rn=bn.defaultEncoding),"function"!=typeof kn&&(kn=Ft),bn.ending?(oi=this,Ui=kn,Xr=new pt,Dt(oi,Xr),c.nextTick(Ui,Xr)):(ji||function(oi,Ui,Xr,Sn){var hn;return null===Xr?hn=new U:"string"==typeof Xr||Ui.objectMode||(hn=new _e("chunk",["string","Buffer"],Xr)),!hn||(Dt(oi,hn),c.nextTick(Sn,hn),!1)}(this,bn,fn,kn))&&(bn.pendingcb++,jr=function(oi,Ui,Xr,Sn,hn,_r){if(!Xr){var Fi=(zs=Sn,(Us=Ui).objectMode||!1===Us.decodeStrings||"string"!=typeof zs||(zs=P.from(zs,hn)),zs);Sn!==Fi&&(Xr=!0,hn="buffer",Sn=Fi)}var Us,zs,_s=Ui.objectMode?1:Sn.length;Ui.length+=_s;var Ho=Ui.length<Ui.highWaterMark;if(Ho||(Ui.needDrain=!0),Ui.writing||Ui.corked){var yo=Ui.lastBufferedRequest;Ui.lastBufferedRequest={chunk:Sn,encoding:hn,isBuf:Xr,callback:_r,next:null},yo?yo.next=Ui.lastBufferedRequest:Ui.bufferedRequest=Ui.lastBufferedRequest,Ui.bufferedRequestCount+=1}else wn(oi,Ui,!1,_s,Sn,hn,_r);return Ho}(this,bn,ji,fn,Rn,kn)),jr},kt.prototype.cork=function(){this._writableState.corked++},kt.prototype.uncork=function(){var fn=this._writableState;fn.corked&&(fn.corked--,fn.writing||fn.corked||fn.bufferProcessing||!fn.bufferedRequest||Hr(this,fn))},kt.prototype.setDefaultEncoding=function(fn){if("string"==typeof fn&&(fn=fn.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((fn+"").toLowerCase())>-1))throw new ht(fn);return this._writableState.defaultEncoding=fn,this},Object.defineProperty(kt.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}}),Object.defineProperty(kt.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),kt.prototype._write=function(fn,Rn,kn){kn(new Fe("_write()"))},kt.prototype._writev=null,kt.prototype.end=function(fn,Rn,kn){var jr,ji,Wn=this._writableState;return"function"==typeof fn?(kn=fn,fn=null,Rn=null):"function"==typeof Rn&&(kn=Rn,Rn=null),null!=fn&&this.write(fn,Rn),Wn.corked&&(Wn.corked=1,this.uncork()),Wn.ending||(this,ji=kn,(jr=Wn).ending=!0,xr(this,jr),ji&&(jr.finished?c.nextTick(ji):this.once("finish",ji)),jr.ended=!0,this.writable=!1),this},Object.defineProperty(kt.prototype,"writableLength",{enumerable:!1,get:function(){return this._writableState.length}}),Object.defineProperty(kt.prototype,"destroyed",{enumerable:!1,get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(fn){this._writableState&&(this._writableState.destroyed=fn)}}),kt.prototype.destroy=re.destroy,kt.prototype._undestroy=re.undestroy,kt.prototype._destroy=function(fn,Rn){Rn(fn)}},5850:(n,s,t)=>{var o,c=t(4155);function g(U,pt,ht){return pt in U?Object.defineProperty(U,pt,{value:ht,enumerable:!0,configurable:!0,writable:!0}):U[pt]=ht,U}var C=t(8610),D=Symbol("lastResolve"),P=Symbol("lastReject"),j=Symbol("error"),W=Symbol("ended"),re=Symbol("lastPromise"),oe=Symbol("handlePromise"),me=Symbol("stream");function _e(U,pt){return{value:U,done:pt}}function Fe(U){var pt=U[D];if(null!==pt){var ht=U[me].read();null!==ht&&(U[re]=null,U[D]=null,U[P]=null,pt(_e(ht,!1)))}}function Re(U){c.nextTick(Fe,U)}var Le=Object.getPrototypeOf(function(){}),we=Object.setPrototypeOf((g(o={get stream(){return this[me]},next:function(){var U=this,pt=this[j];if(null!==pt)return Promise.reject(pt);if(this[W])return Promise.resolve(_e(void 0,!0));if(this[me].destroyed)return new Promise(function(cn,kt){c.nextTick(function(){U[j]?kt(U[j]):cn(_e(void 0,!0))})});var ht,cn,kt,Dt=this[re];if(Dt)ht=new Promise((cn=Dt,kt=this,function(wn,Tn){cn.then(function(){kt[W]?wn(_e(void 0,!0)):kt[oe](wn,Tn)},Tn)}));else{var Ft=this[me].read();if(null!==Ft)return Promise.resolve(_e(Ft,!1));ht=new Promise(this[oe])}return this[re]=ht,ht}},Symbol.asyncIterator,function(){return this}),g(o,"return",function(){var U=this;return new Promise(function(pt,ht){U[me].destroy(null,function(Dt){Dt?ht(Dt):pt(_e(void 0,!0))})})}),o),Le);n.exports=function(U){var pt,ht=Object.create(we,(g(pt={},me,{value:U,writable:!0}),g(pt,D,{value:null,writable:!0}),g(pt,P,{value:null,writable:!0}),g(pt,j,{value:null,writable:!0}),g(pt,W,{value:U._readableState.endEmitted,writable:!0}),g(pt,oe,{value:function(Dt,Ft){var cn=ht[me].read();cn?(ht[re]=null,ht[D]=null,ht[P]=null,Dt(_e(cn,!1))):(ht[D]=Dt,ht[P]=Ft)},writable:!0}),pt));return ht[re]=null,C(U,function(Dt){if(Dt&&"ERR_STREAM_PREMATURE_CLOSE"!==Dt.code){var Ft=ht[P];return null!==Ft&&(ht[re]=null,ht[D]=null,ht[P]=null,Ft(Dt)),void(ht[j]=Dt)}var cn=ht[D];null!==cn&&(ht[re]=null,ht[D]=null,ht[P]=null,cn(_e(void 0,!0))),ht[W]=!0}),U.on("readable",Re.bind(null,ht)),ht}},7327:(n,s,t)=>{function o(j,W){var re=Object.keys(j);if(Object.getOwnPropertySymbols){var oe=Object.getOwnPropertySymbols(j);W&&(oe=oe.filter(function(me){return Object.getOwnPropertyDescriptor(j,me).enumerable})),re.push.apply(re,oe)}return re}function c(j,W,re){return W in j?Object.defineProperty(j,W,{value:re,enumerable:!0,configurable:!0,writable:!0}):j[W]=re,j}var C=t(8764).Buffer,D=t(2361).inspect,P=D&&D.custom||"inspect";n.exports=function(){function j(){(function(me,_e){if(!(me instanceof _e))throw new TypeError("Cannot call a class as a function")})(this,j),this.head=null,this.tail=null,this.length=0}var re;return(re=[{key:"push",value:function(me){var _e={data:me,next:null};this.length>0?this.tail.next=_e:this.head=_e,this.tail=_e,++this.length}},{key:"unshift",value:function(me){var _e={data:me,next:this.head};0===this.length&&(this.tail=_e),this.head=_e,++this.length}},{key:"shift",value:function(){if(0!==this.length){var me=this.head.data;return this.head=1===this.length?this.tail=null:this.head.next,--this.length,me}}},{key:"clear",value:function(){this.head=this.tail=null,this.length=0}},{key:"join",value:function(me){if(0===this.length)return"";for(var _e=this.head,Fe=""+_e.data;_e=_e.next;)Fe+=me+_e.data;return Fe}},{key:"concat",value:function(me){if(0===this.length)return C.alloc(0);for(var Le=C.allocUnsafe(me>>>0),we=this.head,U=0;we;)C.prototype.copy.call(we.data,Le,U),U+=we.data.length,we=we.next;return Le}},{key:"consume",value:function(me,_e){var Fe;return me<this.head.data.length?(Fe=this.head.data.slice(0,me),this.head.data=this.head.data.slice(me)):Fe=me===this.head.data.length?this.shift():_e?this._getString(me):this._getBuffer(me),Fe}},{key:"first",value:function(){return this.head.data}},{key:"_getString",value:function(me){var _e=this.head,Fe=1,Re=_e.data;for(me-=Re.length;_e=_e.next;){var Le=_e.data,we=me>Le.length?Le.length:me;if(Re+=we===Le.length?Le:Le.slice(0,me),0==(me-=we)){we===Le.length?(++Fe,this.head=_e.next?_e.next:this.tail=null):(this.head=_e,_e.data=Le.slice(we));break}++Fe}return this.length-=Fe,Re}},{key:"_getBuffer",value:function(me){var _e=C.allocUnsafe(me),Fe=this.head,Re=1;for(Fe.data.copy(_e),me-=Fe.data.length;Fe=Fe.next;){var Le=Fe.data,we=me>Le.length?Le.length:me;if(Le.copy(_e,_e.length-me,0,we),0==(me-=we)){we===Le.length?(++Re,this.head=Fe.next?Fe.next:this.tail=null):(this.head=Fe,Fe.data=Le.slice(we));break}++Re}return this.length-=Re,_e}},{key:P,value:function(me,_e){return D(this,function(Fe){for(var Re=1;Re<arguments.length;Re++){var Le=null!=arguments[Re]?arguments[Re]:{};Re%2?o(Object(Le),!0).forEach(function(we){c(Fe,we,Le[we])}):Object.getOwnPropertyDescriptors?Object.defineProperties(Fe,Object.getOwnPropertyDescriptors(Le)):o(Object(Le)).forEach(function(we){Object.defineProperty(Fe,we,Object.getOwnPropertyDescriptor(Le,we))})}return Fe}({},_e,{depth:0,customInspect:!1}))}}])&&function(j,W){for(var re=0;re<W.length;re++){var oe=W[re];oe.enumerable=oe.enumerable||!1,oe.configurable=!0,"value"in oe&&(oe.writable=!0),Object.defineProperty(j,oe.key,oe)}}(j.prototype,re),j}()},1195:(n,s,t)=>{var o=t(4155);function c(D,P){C(D,P),g(D)}function g(D){D._writableState&&!D._writableState.emitClose||D._readableState&&!D._readableState.emitClose||D.emit("close")}function C(D,P){D.emit("error",P)}n.exports={destroy:function(D,P){var j=this;return this._readableState&&this._readableState.destroyed||this._writableState&&this._writableState.destroyed?(P?P(D):D&&(this._writableState?this._writableState.errorEmitted||(this._writableState.errorEmitted=!0,o.nextTick(C,this,D)):o.nextTick(C,this,D)),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(D||null,function(oe){!P&&oe?j._writableState?j._writableState.errorEmitted?o.nextTick(g,j):(j._writableState.errorEmitted=!0,o.nextTick(c,j,oe)):o.nextTick(c,j,oe):P?(o.nextTick(g,j),P(oe)):o.nextTick(g,j)}),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finalCalled=!1,this._writableState.prefinished=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)},errorOrDestroy:function(D,P){var j=D._readableState,W=D._writableState;j&&j.autoDestroy||W&&W.autoDestroy?D.destroy(P):D.emit("error",P)}}},8610:(n,s,t)=>{var o=t(4281).q.ERR_STREAM_PREMATURE_CLOSE;function c(){}n.exports=function g(C,D,P){if("function"==typeof D)return g(C,null,D);var U,pt;D||(D={}),U=P||c,pt=!1,P=function(){if(!pt){pt=!0;for(var ht=arguments.length,Dt=new Array(ht),Ft=0;Ft<ht;Ft++)Dt[Ft]=arguments[Ft];U.apply(this,Dt)}};var j=D.readable||!1!==D.readable&&C.readable,W=D.writable||!1!==D.writable&&C.writable,re=function(){C.writable||me()},oe=C._writableState&&C._writableState.finished,me=function(){W=!1,oe=!0,j||P.call(C)},_e=C._readableState&&C._readableState.endEmitted,Fe=function(){j=!1,_e=!0,W||P.call(C)},Re=function(U){P.call(C,U)},Le=function(){var U;return j&&!_e?(C._readableState&&C._readableState.ended||(U=new o),P.call(C,U)):W&&!oe?(C._writableState&&C._writableState.ended||(U=new o),P.call(C,U)):void 0},we=function(){C.req.on("finish",me)};return function(U){return U.setHeader&&"function"==typeof U.abort}(C)?(C.on("complete",me),C.on("abort",Le),C.req?we():C.on("request",we)):W&&!C._writableState&&(C.on("end",re),C.on("close",re)),C.on("end",Fe),C.on("finish",me),!1!==D.error&&C.on("error",Re),C.on("close",Le),function(){C.removeListener("complete",me),C.removeListener("abort",Le),C.removeListener("request",we),C.req&&C.req.removeListener("finish",me),C.removeListener("end",re),C.removeListener("close",re),C.removeListener("finish",me),C.removeListener("end",Fe),C.removeListener("error",Re),C.removeListener("close",Le)}}},5167:n=>{n.exports=function(){throw new Error("Readable.from is not available in the browser")}},9946:(n,s,t)=>{var o,c=t(4281).q,g=c.ERR_MISSING_ARGS,C=c.ERR_STREAM_DESTROYED;function D(oe){if(oe)throw oe}function P(oe,me,_e,Fe){var we,U;we=Fe,U=!1,Fe=function(){U||(U=!0,we.apply(void 0,arguments))};var Re=!1;oe.on("close",function(){Re=!0}),void 0===o&&(o=t(8610)),o(oe,{readable:me,writable:_e},function(we){if(we)return Fe(we);Re=!0,Fe()});var Le=!1;return function(we){if(!Re&&!Le)return Le=!0,function(U){return U.setHeader&&"function"==typeof U.abort}(oe)?oe.abort():"function"==typeof oe.destroy?oe.destroy():void Fe(we||new C("pipe"))}}function j(oe){oe()}function W(oe,me){return oe.pipe(me)}function re(oe){return oe.length?"function"!=typeof oe[oe.length-1]?D:oe.pop():D}n.exports=function(){for(var oe=arguments.length,me=new Array(oe),_e=0;_e<oe;_e++)me[_e]=arguments[_e];var Fe,Re=re(me);if(Array.isArray(me[0])&&(me=me[0]),me.length<2)throw new g("streams");var Le=me.map(function(we,U){var pt=U<me.length-1;return P(we,pt,U>0,function(ht){Fe||(Fe=ht),ht&&Le.forEach(j),pt||(Le.forEach(j),Re(Fe))})});return me.reduce(W)}},2457:(n,s,t)=>{var o=t(4281).q.ERR_INVALID_OPT_VALUE;n.exports={getHighWaterMark:function(c,g,C,D){var j,P=null!=(j=g).highWaterMark?j.highWaterMark:D?j[C]:null;if(null!=P){if(!isFinite(P)||Math.floor(P)!==P||P<0)throw new o(D?C:"highWaterMark",P);return Math.floor(P)}return c.objectMode?16:16384}}},2503:(n,s,t)=>{n.exports=t(7187).EventEmitter},4189:(n,s,t)=>{var o=t(396).Buffer;function c(g,C){this._block=o.alloc(g),this._finalSize=C,this._blockSize=g,this._len=0}c.prototype.update=function(g,C){"string"==typeof g&&(g=o.from(g,C=C||"utf8"));for(var D=this._block,P=this._blockSize,j=g.length,W=this._len,re=0;re<j;){for(var oe=W%P,me=Math.min(j-re,P-oe),_e=0;_e<me;_e++)D[oe+_e]=g[re+_e];re+=me,(W+=me)%P==0&&this._update(D)}return this._len+=j,this},c.prototype.digest=function(g){var C=this._len%this._blockSize;this._block[C]=128,this._block.fill(0,C+1),C>=this._finalSize&&(this._update(this._block),this._block.fill(0));var D=8*this._len;if(D<=4294967295)this._block.writeUInt32BE(D,this._blockSize-4);else{var P=(4294967295&D)>>>0;this._block.writeUInt32BE((D-P)/4294967296,this._blockSize-8),this._block.writeUInt32BE(P,this._blockSize-4)}this._update(this._block);var W=this._hash();return g?W.toString(g):W},c.prototype._update=function(){throw new Error("_update must be implemented by subclass")},n.exports=c},9072:(n,s,t)=>{var o=n.exports=function(c){c=c.toLowerCase();var g=o[c];if(!g)throw new Error(c+" is not supported (we accept pull requests)");return new g};o.sha=t(4448),o.sha1=t(8336),o.sha224=t(8432),o.sha256=t(7499),o.sha384=t(1686),o.sha512=t(7816)},4448:(n,s,t)=>{var o=t(5717),c=t(4189),g=t(396).Buffer,C=[1518500249,1859775393,-1894007588,-899497514],D=new Array(80);function P(){this.init(),this._w=D,c.call(this,64,56)}function j(re){return re<<30|re>>>2}function W(re,oe,me,_e){return 0===re?oe&me|~oe&_e:2===re?oe&me|oe&_e|me&_e:oe^me^_e}o(P,c),P.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},P.prototype._update=function(re){for(var oe,me=this._w,_e=0|this._a,Fe=0|this._b,Re=0|this._c,Le=0|this._d,we=0|this._e,U=0;U<16;++U)me[U]=re.readInt32BE(4*U);for(;U<80;++U)me[U]=me[U-3]^me[U-8]^me[U-14]^me[U-16];for(var pt=0;pt<80;++pt){var ht=~~(pt/20),Dt=0|((oe=_e)<<5|oe>>>27)+W(ht,Fe,Re,Le)+we+me[pt]+C[ht];we=Le,Le=Re,Re=j(Fe),Fe=_e,_e=Dt}this._a=_e+this._a|0,this._b=Fe+this._b|0,this._c=Re+this._c|0,this._d=Le+this._d|0,this._e=we+this._e|0},P.prototype._hash=function(){var re=g.allocUnsafe(20);return re.writeInt32BE(0|this._a,0),re.writeInt32BE(0|this._b,4),re.writeInt32BE(0|this._c,8),re.writeInt32BE(0|this._d,12),re.writeInt32BE(0|this._e,16),re},n.exports=P},8336:(n,s,t)=>{var o=t(5717),c=t(4189),g=t(396).Buffer,C=[1518500249,1859775393,-1894007588,-899497514],D=new Array(80);function P(){this.init(),this._w=D,c.call(this,64,56)}function j(oe){return oe<<5|oe>>>27}function W(oe){return oe<<30|oe>>>2}function re(oe,me,_e,Fe){return 0===oe?me&_e|~me&Fe:2===oe?me&_e|me&Fe|_e&Fe:me^_e^Fe}o(P,c),P.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},P.prototype._update=function(oe){for(var me,_e=this._w,Fe=0|this._a,Re=0|this._b,Le=0|this._c,we=0|this._d,U=0|this._e,pt=0;pt<16;++pt)_e[pt]=oe.readInt32BE(4*pt);for(;pt<80;++pt)_e[pt]=(me=_e[pt-3]^_e[pt-8]^_e[pt-14]^_e[pt-16])<<1|me>>>31;for(var ht=0;ht<80;++ht){var Dt=~~(ht/20),Ft=j(Fe)+re(Dt,Re,Le,we)+U+_e[ht]+C[Dt]|0;U=we,we=Le,Le=W(Re),Re=Fe,Fe=Ft}this._a=Fe+this._a|0,this._b=Re+this._b|0,this._c=Le+this._c|0,this._d=we+this._d|0,this._e=U+this._e|0},P.prototype._hash=function(){var oe=g.allocUnsafe(20);return oe.writeInt32BE(0|this._a,0),oe.writeInt32BE(0|this._b,4),oe.writeInt32BE(0|this._c,8),oe.writeInt32BE(0|this._d,12),oe.writeInt32BE(0|this._e,16),oe},n.exports=P},8432:(n,s,t)=>{var o=t(5717),c=t(7499),g=t(4189),C=t(396).Buffer,D=new Array(64);function P(){this.init(),this._w=D,g.call(this,64,56)}o(P,c),P.prototype.init=function(){return this._a=3238371032,this._b=914150663,this._c=812702999,this._d=4144912697,this._e=4290775857,this._f=1750603025,this._g=1694076839,this._h=3204075428,this},P.prototype._hash=function(){var j=C.allocUnsafe(28);return j.writeInt32BE(this._a,0),j.writeInt32BE(this._b,4),j.writeInt32BE(this._c,8),j.writeInt32BE(this._d,12),j.writeInt32BE(this._e,16),j.writeInt32BE(this._f,20),j.writeInt32BE(this._g,24),j},n.exports=P},7499:(n,s,t)=>{var o=t(5717),c=t(4189),g=t(396).Buffer,C=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],D=new Array(64);function P(){this.init(),this._w=D,c.call(this,64,56)}function j(_e,Fe,Re){return Re^_e&(Fe^Re)}function W(_e,Fe,Re){return _e&Fe|Re&(_e|Fe)}function re(_e){return(_e>>>2|_e<<30)^(_e>>>13|_e<<19)^(_e>>>22|_e<<10)}function oe(_e){return(_e>>>6|_e<<26)^(_e>>>11|_e<<21)^(_e>>>25|_e<<7)}function me(_e){return(_e>>>7|_e<<25)^(_e>>>18|_e<<14)^_e>>>3}o(P,c),P.prototype.init=function(){return this._a=1779033703,this._b=3144134277,this._c=1013904242,this._d=2773480762,this._e=1359893119,this._f=2600822924,this._g=528734635,this._h=1541459225,this},P.prototype._update=function(_e){for(var Fe,Re=this._w,Le=0|this._a,we=0|this._b,U=0|this._c,pt=0|this._d,ht=0|this._e,Dt=0|this._f,Ft=0|this._g,cn=0|this._h,kt=0;kt<16;++kt)Re[kt]=_e.readInt32BE(4*kt);for(;kt<64;++kt)Re[kt]=0|(((Fe=Re[kt-2])>>>17|Fe<<15)^(Fe>>>19|Fe<<13)^Fe>>>10)+Re[kt-7]+me(Re[kt-15])+Re[kt-16];for(var wn=0;wn<64;++wn){var Tn=cn+oe(ht)+j(ht,Dt,Ft)+C[wn]+Re[wn]|0,Hr=re(Le)+W(Le,we,U)|0;cn=Ft,Ft=Dt,Dt=ht,ht=pt+Tn|0,pt=U,U=we,we=Le,Le=Tn+Hr|0}this._a=Le+this._a|0,this._b=we+this._b|0,this._c=U+this._c|0,this._d=pt+this._d|0,this._e=ht+this._e|0,this._f=Dt+this._f|0,this._g=Ft+this._g|0,this._h=cn+this._h|0},P.prototype._hash=function(){var _e=g.allocUnsafe(32);return _e.writeInt32BE(this._a,0),_e.writeInt32BE(this._b,4),_e.writeInt32BE(this._c,8),_e.writeInt32BE(this._d,12),_e.writeInt32BE(this._e,16),_e.writeInt32BE(this._f,20),_e.writeInt32BE(this._g,24),_e.writeInt32BE(this._h,28),_e},n.exports=P},1686:(n,s,t)=>{var o=t(5717),c=t(7816),g=t(4189),C=t(396).Buffer,D=new Array(160);function P(){this.init(),this._w=D,g.call(this,128,112)}o(P,c),P.prototype.init=function(){return this._ah=3418070365,this._bh=1654270250,this._ch=2438529370,this._dh=355462360,this._eh=1731405415,this._fh=2394180231,this._gh=3675008525,this._hh=1203062813,this._al=3238371032,this._bl=914150663,this._cl=812702999,this._dl=4144912697,this._el=4290775857,this._fl=1750603025,this._gl=1694076839,this._hl=3204075428,this},P.prototype._hash=function(){var j=C.allocUnsafe(48);function W(re,oe,me){j.writeInt32BE(re,me),j.writeInt32BE(oe,me+4)}return W(this._ah,this._al,0),W(this._bh,this._bl,8),W(this._ch,this._cl,16),W(this._dh,this._dl,24),W(this._eh,this._el,32),W(this._fh,this._fl,40),j},n.exports=P},7816:(n,s,t)=>{var o=t(5717),c=t(4189),g=t(396).Buffer,C=[1116352408,3609767458,1899447441,602891725,3049323471,3964484399,3921009573,2173295548,961987163,4081628472,1508970993,3053834265,2453635748,2937671579,2870763221,3664609560,3624381080,2734883394,310598401,1164996542,607225278,1323610764,1426881987,3590304994,1925078388,4068182383,2162078206,991336113,2614888103,633803317,3248222580,3479774868,3835390401,2666613458,4022224774,944711139,264347078,2341262773,604807628,2007800933,770255983,1495990901,1249150122,1856431235,1555081692,3175218132,1996064986,2198950837,2554220882,3999719339,2821834349,766784016,2952996808,2566594879,3210313671,3203337956,3336571891,1034457026,3584528711,2466948901,113926993,3758326383,338241895,168717936,666307205,1188179964,773529912,1546045734,1294757372,1522805485,1396182291,2643833823,1695183700,2343527390,1986661051,1014477480,2177026350,1206759142,2456956037,344077627,2730485921,1290863460,2820302411,3158454273,3259730800,3505952657,3345764771,106217008,3516065817,3606008344,3600352804,1432725776,4094571909,1467031594,275423344,851169720,430227734,3100823752,506948616,1363258195,659060556,3750685593,883997877,3785050280,958139571,3318307427,1322822218,3812723403,1537002063,2003034995,1747873779,3602036899,1955562222,1575990012,2024104815,1125592928,2227730452,2716904306,2361852424,442776044,2428436474,593698344,2756734187,3733110249,3204031479,2999351573,3329325298,3815920427,3391569614,3928383900,3515267271,566280711,3940187606,3454069534,4118630271,4000239992,116418474,1914138554,174292421,2731055270,289380356,3203993006,460393269,320620315,685471733,587496836,852142971,1086792851,1017036298,365543100,1126000580,2618297676,1288033470,3409855158,1501505948,4234509866,1607167915,987167468,1816402316,1246189591],D=new Array(160);function P(){this.init(),this._w=D,c.call(this,128,112)}function j(we,U,pt){return pt^we&(U^pt)}function W(we,U,pt){return we&U|pt&(we|U)}function re(we,U){return(we>>>28|U<<4)^(U>>>2|we<<30)^(U>>>7|we<<25)}function oe(we,U){return(we>>>14|U<<18)^(we>>>18|U<<14)^(U>>>9|we<<23)}function me(we,U){return(we>>>1|U<<31)^(we>>>8|U<<24)^we>>>7}function _e(we,U){return(we>>>1|U<<31)^(we>>>8|U<<24)^(we>>>7|U<<25)}function Fe(we,U){return(we>>>19|U<<13)^(U>>>29|we<<3)^we>>>6}function Re(we,U){return(we>>>19|U<<13)^(U>>>29|we<<3)^(we>>>6|U<<26)}function Le(we,U){return we>>>0<U>>>0?1:0}o(P,c),P.prototype.init=function(){return this._ah=1779033703,this._bh=3144134277,this._ch=1013904242,this._dh=2773480762,this._eh=1359893119,this._fh=2600822924,this._gh=528734635,this._hh=1541459225,this._al=4089235720,this._bl=2227873595,this._cl=4271175723,this._dl=1595750129,this._el=2917565137,this._fl=725511199,this._gl=4215389547,this._hl=327033209,this},P.prototype._update=function(we){for(var U=this._w,pt=0|this._ah,ht=0|this._bh,Dt=0|this._ch,Ft=0|this._dh,cn=0|this._eh,kt=0|this._fh,wn=0|this._gh,Tn=0|this._hh,Hr=0|this._al,sr=0|this._bl,Nr=0|this._cl,xr=0|this._dl,fn=0|this._el,Rn=0|this._fl,kn=0|this._gl,Wn=0|this._hl,bn=0;bn<32;bn+=2)U[bn]=we.readInt32BE(4*bn),U[bn+1]=we.readInt32BE(4*bn+4);for(;bn<160;bn+=2){var jr=U[bn-30],ji=U[bn-30+1],oi=me(jr,ji),Ui=_e(ji,jr),Xr=Fe(jr=U[bn-4],ji=U[bn-4+1]),Sn=Re(ji,jr),Fi=U[bn-32],_s=U[bn-32+1],Ho=Ui+U[bn-14+1]|0,yo=oi+U[bn-14]+Le(Ho,Ui)|0;yo=(yo=yo+Xr+Le(Ho=Ho+Sn|0,Sn)|0)+Fi+Le(Ho=Ho+_s|0,_s)|0,U[bn]=yo,U[bn+1]=Ho}for(var Us=0;Us<160;Us+=2){yo=U[Us],Ho=U[Us+1];var zs=W(pt,ht,Dt),Di=W(Hr,sr,Nr),oo=re(pt,Hr),ho=re(Hr,pt),Ze=oe(cn,fn),Mt=oe(fn,cn),St=C[Us],Un=C[Us+1],pr=j(cn,kt,wn),Vr=j(fn,Rn,kn),Ri=Wn+Mt|0,Bs=Tn+Ze+Le(Ri,Wn)|0;Bs=(Bs=(Bs=Bs+pr+Le(Ri=Ri+Vr|0,Vr)|0)+St+Le(Ri=Ri+Un|0,Un)|0)+yo+Le(Ri=Ri+Ho|0,Ho)|0;var Uo=ho+Di|0,ol=oo+zs+Le(Uo,ho)|0;Tn=wn,Wn=kn,wn=kt,kn=Rn,kt=cn,Rn=fn,cn=Ft+Bs+Le(fn=xr+Ri|0,xr)|0,Ft=Dt,xr=Nr,Dt=ht,Nr=sr,ht=pt,sr=Hr,pt=Bs+ol+Le(Hr=Ri+Uo|0,Ri)|0}this._al=this._al+Hr|0,this._bl=this._bl+sr|0,this._cl=this._cl+Nr|0,this._dl=this._dl+xr|0,this._el=this._el+fn|0,this._fl=this._fl+Rn|0,this._gl=this._gl+kn|0,this._hl=this._hl+Wn|0,this._ah=this._ah+pt+Le(this._al,Hr)|0,this._bh=this._bh+ht+Le(this._bl,sr)|0,this._ch=this._ch+Dt+Le(this._cl,Nr)|0,this._dh=this._dh+Ft+Le(this._dl,xr)|0,this._eh=this._eh+cn+Le(this._el,fn)|0,this._fh=this._fh+kt+Le(this._fl,Rn)|0,this._gh=this._gh+wn+Le(this._gl,kn)|0,this._hh=this._hh+Tn+Le(this._hl,Wn)|0},P.prototype._hash=function(){var we=g.allocUnsafe(64);function U(pt,ht,Dt){we.writeInt32BE(pt,Dt),we.writeInt32BE(ht,Dt+4)}return U(this._ah,this._al,0),U(this._bh,this._bl,8),U(this._ch,this._cl,16),U(this._dh,this._dl,24),U(this._eh,this._el,32),U(this._fh,this._fl,40),U(this._gh,this._gl,48),U(this._hh,this._hl,56),we},n.exports=P},2830:(n,s,t)=>{n.exports=c;var o=t(7187).EventEmitter;function c(){o.call(this)}t(5717)(c,o),c.Readable=t(9481),c.Writable=t(4229),c.Duplex=t(6753),c.Transform=t(4605),c.PassThrough=t(2725),c.finished=t(8610),c.pipeline=t(9946),c.Stream=c,c.prototype.pipe=function(g,C){var D=this;function P(Fe){g.writable&&!1===g.write(Fe)&&D.pause&&D.pause()}function j(){D.readable&&D.resume&&D.resume()}D.on("data",P),g.on("drain",j),g._isStdio||C&&!1===C.end||(D.on("end",re),D.on("close",oe));var W=!1;function re(){W||(W=!0,g.end())}function oe(){W||(W=!0,"function"==typeof g.destroy&&g.destroy())}function me(Fe){if(_e(),0===o.listenerCount(this,"error"))throw Fe}function _e(){D.removeListener("data",P),g.removeListener("drain",j),D.removeListener("end",re),D.removeListener("close",oe),D.removeListener("error",me),g.removeListener("error",me),D.removeListener("end",_e),D.removeListener("close",_e),g.removeListener("close",_e)}return D.on("error",me),g.on("error",me),D.on("end",_e),D.on("close",_e),g.on("close",_e),g.emit("pipe",D),g}},2553:(n,s,t)=>{var o=t(396).Buffer,c=o.isEncoding||function(_e){switch((_e=""+_e)&&_e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function g(_e){var Fe;switch(this.encoding=function(Re){var Le=function(we){if(!we)return"utf8";for(var U;;)switch(we){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return we;default:if(U)return;we=(""+we).toLowerCase(),U=!0}}(Re);if("string"!=typeof Le&&(o.isEncoding===c||!c(Re)))throw new Error("Unknown encoding: "+Re);return Le||Re}(_e),this.encoding){case"utf16le":this.text=P,this.end=j,Fe=4;break;case"utf8":this.fillLast=D,Fe=4;break;case"base64":this.text=W,this.end=re,Fe=3;break;default:return this.write=oe,void(this.end=me)}this.lastNeed=0,this.lastTotal=0,this.lastChar=o.allocUnsafe(Fe)}function C(_e){return _e<=127?0:_e>>5==6?2:_e>>4==14?3:_e>>3==30?4:_e>>6==2?-1:-2}function D(_e){var Fe=this.lastTotal-this.lastNeed,Re=function(Le,we,U){if(128!=(192&we[0]))return Le.lastNeed=0,"\ufffd";if(Le.lastNeed>1&&we.length>1){if(128!=(192&we[1]))return Le.lastNeed=1,"\ufffd";if(Le.lastNeed>2&&we.length>2&&128!=(192&we[2]))return Le.lastNeed=2,"\ufffd"}}(this,_e);return void 0!==Re?Re:this.lastNeed<=_e.length?(_e.copy(this.lastChar,Fe,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(_e.copy(this.lastChar,Fe,0,_e.length),void(this.lastNeed-=_e.length))}function P(_e,Fe){if((_e.length-Fe)%2==0){var Re=_e.toString("utf16le",Fe);if(Re){var Le=Re.charCodeAt(Re.length-1);if(Le>=55296&&Le<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=_e[_e.length-2],this.lastChar[1]=_e[_e.length-1],Re.slice(0,-1)}return Re}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=_e[_e.length-1],_e.toString("utf16le",Fe,_e.length-1)}function j(_e){var Fe=_e&&_e.length?this.write(_e):"";return this.lastNeed?Fe+this.lastChar.toString("utf16le",0,this.lastTotal-this.lastNeed):Fe}function W(_e,Fe){var Re=(_e.length-Fe)%3;return 0===Re?_e.toString("base64",Fe):(this.lastNeed=3-Re,this.lastTotal=3,1===Re?this.lastChar[0]=_e[_e.length-1]:(this.lastChar[0]=_e[_e.length-2],this.lastChar[1]=_e[_e.length-1]),_e.toString("base64",Fe,_e.length-Re))}function re(_e){var Fe=_e&&_e.length?this.write(_e):"";return this.lastNeed?Fe+this.lastChar.toString("base64",0,3-this.lastNeed):Fe}function oe(_e){return _e.toString(this.encoding)}function me(_e){return _e&&_e.length?this.write(_e):""}s.s=g,g.prototype.write=function(_e){if(0===_e.length)return"";var Fe,Re;if(this.lastNeed){if(void 0===(Fe=this.fillLast(_e)))return"";Re=this.lastNeed,this.lastNeed=0}else Re=0;return Re<_e.length?Fe?Fe+this.text(_e,Re):this.text(_e,Re):Fe||""},g.prototype.end=function(_e){var Fe=_e&&_e.length?this.write(_e):"";return this.lastNeed?Fe+"\ufffd":Fe},g.prototype.text=function(_e,Fe){var Re=function(we,U,pt){var ht=U.length-1;if(ht<pt)return 0;var Dt=C(U[ht]);return Dt>=0?(Dt>0&&(we.lastNeed=Dt-1),Dt):--ht<pt||-2===Dt?0:(Dt=C(U[ht]))>=0?(Dt>0&&(we.lastNeed=Dt-2),Dt):--ht<pt||-2===Dt?0:(Dt=C(U[ht]))>=0?(Dt>0&&(2===Dt?Dt=0:we.lastNeed=Dt-3),Dt):0}(this,_e,Fe);if(!this.lastNeed)return _e.toString("utf8",Fe);this.lastTotal=Re;var Le=_e.length-(Re-this.lastNeed);return _e.copy(this.lastChar,0,Le),_e.toString("utf8",Fe,Le)},g.prototype.fillLast=function(_e){if(this.lastNeed<=_e.length)return _e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);_e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,_e.length),this.lastNeed-=_e.length}},396:(n,s,t)=>{var o=t(8764),c=o.Buffer;function g(D,P){for(var j in D)P[j]=D[j]}function C(D,P,j){return c(D,P,j)}c.from&&c.alloc&&c.allocUnsafe&&c.allocUnsafeSlow?n.exports=o:(g(o,s),s.Buffer=C),C.prototype=Object.create(c.prototype),g(c,C),C.from=function(D,P,j){if("number"==typeof D)throw new TypeError("Argument must not be a number");return c(D,P,j)},C.alloc=function(D,P,j){if("number"!=typeof D)throw new TypeError("Argument must be a number");var W=c(D);return void 0!==P?"string"==typeof j?W.fill(P,j):W.fill(P):W.fill(0),W},C.allocUnsafe=function(D){if("number"!=typeof D)throw new TypeError("Argument must be a number");return c(D)},C.allocUnsafeSlow=function(D){if("number"!=typeof D)throw new TypeError("Argument must be a number");return o.SlowBuffer(D)}},4927:(n,s,t)=>{function o(c){try{if(!t.g.localStorage)return!1}catch(C){return!1}var g=t.g.localStorage[c];return null!=g&&"true"===String(g).toLowerCase()}n.exports=function(c,g){if(o("noDeprecation"))return c;var C=!1;return function(){if(!C){if(o("throwDeprecation"))throw new Error(g);o("traceDeprecation")?console.trace(g):console.warn(g),C=!0}return c.apply(this,arguments)}}},255:n=>{var s={"&":"&amp;",'"':"&quot;","'":"&apos;","<":"&lt;",">":"&gt;"};n.exports=function(t){return t&&t.replace?t.replace(/([&"<>'])/g,function(o,c){return s[c]}):t}},3479:(n,s,t)=>{var o=t(4155),c=t(255),g=t(2830).Stream;function C(P,j,W){W=W||0;var re,oe,me=(re=j,new Array(W||0).join(re||"")),_e=P;if("object"==typeof P&&(_e=P[oe=Object.keys(P)[0]])&&_e._elem)return _e._elem.name=oe,_e._elem.icount=W,_e._elem.indent=j,_e._elem.indents=me,_e._elem.interrupt=_e,_e._elem;var Fe,Re=[],Le=[];function we(U){Object.keys(U).forEach(function(pt){Re.push(pt+'="'+c(U[pt])+'"')})}switch(typeof _e){case"object":if(null===_e)break;_e._attr&&we(_e._attr),_e._cdata&&Le.push(("<![CDATA["+_e._cdata).replace(/\]\]>/g,"]]]]><![CDATA[>")+"]]>"),_e.forEach&&(Fe=!1,Le.push(""),_e.forEach(function(U){"object"==typeof U?"_attr"==Object.keys(U)[0]?we(U._attr):Le.push(C(U,j,W+1)):(Le.pop(),Fe=!0,Le.push(c(U)))}),Fe||Le.push(""));break;default:Le.push(c(_e))}return{name:oe,interrupt:!1,attributes:Re,content:Le,icount:W,indents:me,indent:j}}function D(P,j,W){if("object"!=typeof j)return P(!1,j);var re=j.interrupt?1:j.content.length;function oe(){for(;j.content.length;){var _e=j.content.shift();if(void 0!==_e){if(me(_e))return;D(P,_e)}}P(!1,(re>1?j.indents:"")+(j.name?"</"+j.name+">":"")+(j.indent&&!W?"\n":"")),W&&W()}function me(_e){return!!_e.interrupt&&(_e.interrupt.append=P,_e.interrupt.end=oe,_e.interrupt=!1,P(!0),!0)}if(P(!1,j.indents+(j.name?"<"+j.name:"")+(j.attributes.length?" "+j.attributes.join(" "):"")+(re?j.name?">":"":j.name?"/>":"")+(j.indent&&re>1?"\n":"")),!re)return P(!1,j.indent?"\n":"");me(j)||oe()}n.exports=function(P,j){"object"!=typeof j&&(j={indent:j});var W,re,oe=j.stream?new g:null,me="",_e=!1,Fe=j.indent?!0===j.indent?" ":j.indent:"",Re=!0;function Le(ht){Re?o.nextTick(ht):ht()}function we(ht,Dt){if(void 0!==Dt&&(me+=Dt),ht&&!_e&&(oe=oe||new g,_e=!0),ht&&_e){var Ft=me;Le(function(){oe.emit("data",Ft)}),me=""}}function U(ht,Dt){D(we,C(ht,Fe,Fe?1:0),Dt)}function pt(){if(oe){var ht=me;Le(function(){oe.emit("data",ht),oe.emit("end"),oe.readable=!1,oe.emit("close")})}}return Le(function(){Re=!1}),j.declaration&&(re={version:"1.0",encoding:(W=j.declaration).encoding||"UTF-8"},W.standalone&&(re.standalone=W.standalone),U({"?xml":{_attr:re}}),me=me.replace("/>","?>")),P&&P.forEach?P.forEach(function(ht,Dt){var Ft;Dt+1===P.length&&(Ft=pt),U(ht,Ft)}):U(P,pt),oe?(oe.readable=!0,oe):me},n.exports.element=n.exports.Element=function(){var P=Array.prototype.slice.call(arguments),j={_elem:C(P),push:function(W){if(!this.append)throw new Error("not assigned to a parent!");var re=this,oe=this._elem.indent;D(this.append,C(W,oe,this._elem.icount+(oe?1:0)),function(){re.append(!0)})},close:function(W){void 0!==W&&this.push(W),this.end&&this.end()}};return j}},5102:(n,s,t)=>{var o={"./all.js":5308,"./auth/actions.js":5812,"./auth/index.js":3705,"./auth/reducers.js":3962,"./auth/selectors.js":35,"./auth/spec-wrap-actions.js":8302,"./configs/actions.js":714,"./configs/helpers.js":2256,"./configs/index.js":1661,"./configs/reducers.js":7743,"./configs/selectors.js":9018,"./configs/spec-actions.js":2698,"./deep-linking/helpers.js":1970,"./deep-linking/index.js":4980,"./deep-linking/layout.js":5858,"./deep-linking/operation-tag-wrapper.jsx":4584,"./deep-linking/operation-wrapper.jsx":877,"./download-url.js":8011,"./err/actions.js":4966,"./err/error-transformers/hook.js":6808,"./err/error-transformers/transformers/not-of-type.js":2392,"./err/error-transformers/transformers/parameter-oneof.js":1835,"./err/index.js":7793,"./err/reducers.js":3527,"./err/selectors.js":7667,"./filter/index.js":9978,"./filter/opsFilter.js":4309,"./layout/actions.js":5474,"./layout/index.js":6821,"./layout/reducers.js":5672,"./layout/selectors.js":4400,"./layout/spec-extensions/wrap-selector.js":8989,"./logs/index.js":9150,"./oas3/actions.js":7002,"./oas3/auth-extensions/wrap-selectors.js":3723,"./oas3/components/callbacks.jsx":3427,"./oas3/components/http-auth.jsx":6775,"./oas3/components/index.js":6467,"./oas3/components/operation-link.jsx":5757,"./oas3/components/operation-servers.jsx":6796,"./oas3/components/request-body-editor.jsx":5327,"./oas3/components/request-body.jsx":2458,"./oas3/components/servers-container.jsx":9928,"./oas3/components/servers.jsx":6617,"./oas3/helpers.jsx":7779,"./oas3/index.js":7451,"./oas3/reducers.js":9666,"./oas3/selectors.js":5065,"./oas3/spec-extensions/selectors.js":1741,"./oas3/spec-extensions/wrap-selectors.js":2044,"./oas3/wrap-components/auth-item.jsx":356,"./oas3/wrap-components/index.js":7761,"./oas3/wrap-components/json-schema-string.jsx":287,"./oas3/wrap-components/markdown.jsx":2460,"./oas3/wrap-components/model.jsx":3499,"./oas3/wrap-components/online-validator-badge.js":58,"./oas3/wrap-components/version-stamp.jsx":9487,"./on-complete/index.js":8560,"./request-snippets/fn.js":4624,"./request-snippets/index.js":6575,"./request-snippets/request-snippets.jsx":4206,"./request-snippets/selectors.js":4669,"./safe-render/components/error-boundary.jsx":6195,"./safe-render/components/fallback.jsx":9403,"./safe-render/fn.jsx":6189,"./safe-render/index.js":8102,"./samples/fn.js":2473,"./samples/index.js":8883,"./spec/actions.js":1737,"./spec/index.js":7038,"./spec/reducers.js":32,"./spec/selectors.js":3881,"./spec/wrap-actions.js":7508,"./swagger-js/configs-wrap-actions.js":4852,"./swagger-js/index.js":2990,"./util/index.js":8525,"./view/fn.js":8347,"./view/index.js":3420,"./view/root-injects.jsx":5005,"core/plugins/all.js":5308,"core/plugins/auth/actions.js":5812,"core/plugins/auth/index.js":3705,"core/plugins/auth/reducers.js":3962,"core/plugins/auth/selectors.js":35,"core/plugins/auth/spec-wrap-actions.js":8302,"core/plugins/configs/actions.js":714,"core/plugins/configs/helpers.js":2256,"core/plugins/configs/index.js":1661,"core/plugins/configs/reducers.js":7743,"core/plugins/configs/selectors.js":9018,"core/plugins/configs/spec-actions.js":2698,"core/plugins/deep-linking/helpers.js":1970,"core/plugins/deep-linking/index.js":4980,"core/plugins/deep-linking/layout.js":5858,"core/plugins/deep-linking/operation-tag-wrapper.jsx":4584,"core/plugins/deep-linking/operation-wrapper.jsx":877,"core/plugins/download-url.js":8011,"core/plugins/err/actions.js":4966,"core/plugins/err/error-transformers/hook.js":6808,"core/plugins/err/error-transformers/transformers/not-of-type.js":2392,"core/plugins/err/error-transformers/transformers/parameter-oneof.js":1835,"core/plugins/err/index.js":7793,"core/plugins/err/reducers.js":3527,"core/plugins/err/selectors.js":7667,"core/plugins/filter/index.js":9978,"core/plugins/filter/opsFilter.js":4309,"core/plugins/layout/actions.js":5474,"core/plugins/layout/index.js":6821,"core/plugins/layout/reducers.js":5672,"core/plugins/layout/selectors.js":4400,"core/plugins/layout/spec-extensions/wrap-selector.js":8989,"core/plugins/logs/index.js":9150,"core/plugins/oas3/actions.js":7002,"core/plugins/oas3/auth-extensions/wrap-selectors.js":3723,"core/plugins/oas3/components/callbacks.jsx":3427,"core/plugins/oas3/components/http-auth.jsx":6775,"core/plugins/oas3/components/index.js":6467,"core/plugins/oas3/components/operation-link.jsx":5757,"core/plugins/oas3/components/operation-servers.jsx":6796,"core/plugins/oas3/components/request-body-editor.jsx":5327,"core/plugins/oas3/components/request-body.jsx":2458,"core/plugins/oas3/components/servers-container.jsx":9928,"core/plugins/oas3/components/servers.jsx":6617,"core/plugins/oas3/helpers.jsx":7779,"core/plugins/oas3/index.js":7451,"core/plugins/oas3/reducers.js":9666,"core/plugins/oas3/selectors.js":5065,"core/plugins/oas3/spec-extensions/selectors.js":1741,"core/plugins/oas3/spec-extensions/wrap-selectors.js":2044,"core/plugins/oas3/wrap-components/auth-item.jsx":356,"core/plugins/oas3/wrap-components/index.js":7761,"core/plugins/oas3/wrap-components/json-schema-string.jsx":287,"core/plugins/oas3/wrap-components/markdown.jsx":2460,"core/plugins/oas3/wrap-components/model.jsx":3499,"core/plugins/oas3/wrap-components/online-validator-badge.js":58,"core/plugins/oas3/wrap-components/version-stamp.jsx":9487,"core/plugins/on-complete/index.js":8560,"core/plugins/request-snippets/fn.js":4624,"core/plugins/request-snippets/index.js":6575,"core/plugins/request-snippets/request-snippets.jsx":4206,"core/plugins/request-snippets/selectors.js":4669,"core/plugins/safe-render/components/error-boundary.jsx":6195,"core/plugins/safe-render/components/fallback.jsx":9403,"core/plugins/safe-render/fn.jsx":6189,"core/plugins/safe-render/index.js":8102,"core/plugins/samples/fn.js":2473,"core/plugins/samples/index.js":8883,"core/plugins/spec/actions.js":1737,"core/plugins/spec/index.js":7038,"core/plugins/spec/reducers.js":32,"core/plugins/spec/selectors.js":3881,"core/plugins/spec/wrap-actions.js":7508,"core/plugins/swagger-js/configs-wrap-actions.js":4852,"core/plugins/swagger-js/index.js":2990,"core/plugins/util/index.js":8525,"core/plugins/view/fn.js":8347,"core/plugins/view/index.js":3420,"core/plugins/view/root-injects.jsx":5005};function c(C){var D=g(C);return t(D)}function g(C){if(!t.o(o,C)){var D=new Error("Cannot find module '"+C+"'");throw D.code="MODULE_NOT_FOUND",D}return o[C]}c.keys=function(){return Object.keys(o)},c.resolve=g,n.exports=c,c.id=5102},2517:n=>{n.exports="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwcHgiICBoZWlnaHQ9IjIwMHB4IiAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiIGNsYXNzPSJsZHMtcm9sbGluZyIgc3R5bGU9ImJhY2tncm91bmQtaW1hZ2U6IG5vbmU7IGJhY2tncm91bmQtcG9zaXRpb246IGluaXRpYWwgaW5pdGlhbDsgYmFja2dyb3VuZC1yZXBlYXQ6IGluaXRpYWwgaW5pdGlhbDsiPjxjaXJjbGUgY3g9IjUwIiBjeT0iNTAiIGZpbGw9Im5vbmUiIG5nLWF0dHItc3Ryb2tlPSJ7e2NvbmZpZy5jb2xvcn19IiBuZy1hdHRyLXN0cm9rZS13aWR0aD0ie3tjb25maWcud2lkdGh9fSIgbmctYXR0ci1yPSJ7e2NvbmZpZy5yYWRpdXN9fSIgbmctYXR0ci1zdHJva2UtZGFzaGFycmF5PSJ7e2NvbmZpZy5kYXNoYXJyYXl9fSIgc3Ryb2tlPSIjNTU1NTU1IiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij48YW5pbWF0ZVRyYW5zZm9ybSBhdHRyaWJ1dGVOYW1lPSJ0cmFuc2Zvcm0iIHR5cGU9InJvdGF0ZSIgY2FsY01vZGU9ImxpbmVhciIgdmFsdWVzPSIwIDUwIDUwOzM2MCA1MCA1MCIga2V5VGltZXM9IjA7MSIgZHVyPSIxcyIgYmVnaW49IjBzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSI+PC9hbmltYXRlVHJhbnNmb3JtPjwvY2lyY2xlPjwvc3ZnPgo="},5163:n=>{n.exports='---\nurl: "https://petstore.swagger.io/v2/swagger.json"\ndom_id: "#swagger-ui"\nvalidatorUrl: "https://validator.swagger.io/validator"\n'},8898:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>QE()}),c)},4163:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>D4()}),c)},5527:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>N4()}),c)},5171:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>ra()}),c)},2954:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>Qm()}),c)},7930:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>I4()}),c)},6145:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>Np()}),c)},1778:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>lp()}),c)},29:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>F4()}),c)},2372:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>Yv()}),c)},8818:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>$4()}),c)},5487:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>U4()}),c)},2565:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>Tu()}),c)},6785:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>Y4()}),c)},8136:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>n_()}),c)},9963:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>j4()}),c)},4350:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>V4()}),c)},3590:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>jN()}),c)},5942:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>W4()}),c)},313:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>Wp()}),c)},6914:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>Q4()}),c)},7512:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>Sh()}),c)},2740:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>xu()}),c)},374:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>K4()}),c)},6235:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>e5()}),c)},3769:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>n5()}),c)},6340:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>R6}),c)},7344:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>tb}),c)},8656:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>GT}),c)},3248:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>Ng}),c)},5416:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>i5}),c)},775:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>jT}),c)},863:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>z3}),c)},9972:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>o5}),c)},1013:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>Od}),c)},302:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>KN}),c)},9334:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>bh}),c)},2691:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>fm}),c)},1581:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>vc}),c)},4780:n=>{n.exports=a5},8096:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>u5()}),c)},3294:n=>{n.exports=d5},9725:(n,s,t)=>{var c;n.exports=(t.d(c={},{List:()=>rf.List,Map:()=>rf.Map,OrderedMap:()=>rf.OrderedMap,Seq:()=>rf.Seq,Set:()=>rf.Set,default:()=>IE(),fromJS:()=>rf.fromJS}),c)},626:(n,s,t)=>{var c;n.exports=(t.d(c={},{JSON_SCHEMA:()=>lA,default:()=>$T}),c)},9908:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>ab()}),c)},7068:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>p5()}),c)},5476:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>_5()}),c)},5053:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>m5()}),c)},810:(n,s,t)=>{var c;n.exports=(t.d(c={},{Component:()=>zo.Component,PureComponent:()=>zo.PureComponent,default:()=>zo,useEffect:()=>zo.useEffect,useRef:()=>zo.useRef,useState:()=>zo.useState}),c)},9874:(n,s,t)=>{var c;n.exports=(t.d(c={},{CopyToClipboard:()=>v5.CopyToClipboard}),c)},9569:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>b5()}),c)},9871:(n,s,t)=>{var c;n.exports=(t.d(c={},{applyMiddleware:()=>O5,bindActionCreators:()=>A5,compose:()=>H6,createStore:()=>k6}),c)},3952:(n,s,t)=>{var c;n.exports=(t.d(c={},{Remarkable:()=>e1}),c)},8639:(n,s,t)=>{var c;n.exports=(t.d(c={},{createSelector:()=>iP}),c)},8518:(n,s,t)=>{var c;n.exports=(t.d(c={},{serializeError:()=>mF.serializeError}),c)},5013:(n,s,t)=>{var c;n.exports=(t.d(c={},{opId:()=>L3}),c)},8900:(n,s,t)=>{var c;n.exports=(t.d(c={},{default:()=>yF()}),c)},2361:()=>{},4616:()=>{}},oP={};function Mo(n){var s=oP[n];if(void 0!==s)return s.exports;var t=oP[n]={exports:{}};return kF[n](t,t.exports,Mo),t.exports}Mo.n=n=>{var s=n&&n.__esModule?()=>n.default:()=>n;return Mo.d(s,{a:s}),s},Mo.d=(n,s)=>{for(var t in s)Mo.o(s,t)&&!Mo.o(n,t)&&Object.defineProperty(n,t,{enumerable:!0,get:s[t]})},Mo.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(n){if("object"==typeof window)return window}}(),Mo.o=(n,s)=>Object.prototype.hasOwnProperty.call(n,s),Mo.r=n=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})};var sP={};(()=>{Mo.d(sP,{Z:()=>J7});var n={};Mo.r(n),Mo.d(n,{Button:()=>_P,Col:()=>i7,Collapse:()=>yP,Container:()=>r7,Input:()=>a7,Link:()=>mP,Row:()=>o7,Select:()=>gP,TextArea:()=>s7});var s={};Mo.r(s),Mo.d(s,{JsonSchemaArrayItemFile:()=>uR,JsonSchemaArrayItemText:()=>lR,JsonSchemaForm:()=>MP,JsonSchema_array:()=>OP,JsonSchema_boolean:()=>wP,JsonSchema_object:()=>xP,JsonSchema_string:()=>AP});var t=Mo(1581),o=Mo(5171);const c=(Mo.d(Kt={},{default:()=>EF()}),Kt);var Kt,g=Mo(6145),C=Mo(2740),D=Mo(313),P=Mo(7698),j=Mo.n(P),W=Mo(775),re=Mo(7344),oe=Mo(8656),me=Mo(5527),_e=Mo(7512),Fe=Mo(8136),Re=Mo(4163),Le=Mo(6785),we=Mo(2565),U=Mo(810),pt=Mo(9871),ht=Mo(9725);const Dt=(vn=>{var Kt={};return Mo.d(Kt,vn),Kt})({combineReducers:()=>TF.U});var Ft=Mo(8518);const cn=(vn=>{var Kt={};return Mo.d(Kt,vn),Kt})({default:()=>CF()});var kt=Mo(4966),wn=Mo(7504),Tn=Mo(6298),Hr=function(vn){return vn},sr=function(){function vn(){var Kt,ft=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};(0,re.default)(this,vn),j()(this,{state:{},plugins:[],pluginsOptions:{},system:{configs:{},fn:{},components:{},rootInjects:{},statePlugins:{}},boundSystem:{},toolbox:{}},ft),this.getSystem=(0,me.default)(Kt=this._getSystem).call(Kt,this),this.store=kn(Hr,(0,ht.fromJS)(this.state),this.getSystem),this.buildSystem(!1),this.register(this.plugins)}return(0,oe.default)(vn,[{key:"getStore",value:function(){return this.store}},{key:"register",value:function(Kt){var ft=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],Je=Nr(Kt,this.getSystem(),this.pluginsOptions);fn(this.system,Je),ft&&this.buildSystem();var Qe=xr.call(this.system,Kt,this.getSystem());Qe&&this.buildSystem()}},{key:"buildSystem",value:function(){var Kt=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],ft=this.getStore().dispatch,Je=this.getStore().getState;this.boundSystem=(0,_e.default)({},this.getRootInjects(),this.getWrappedAndBoundActions(ft),this.getWrappedAndBoundSelectors(Je,this.getSystem),this.getStateThunks(Je),this.getFn(),this.getConfigs()),Kt&&this.rebuildReducer()}},{key:"_getSystem",value:function(){return this.boundSystem}},{key:"getRootInjects",value:function(){var Kt,ft,Je;return(0,_e.default)({getSystem:this.getSystem,getStore:(0,me.default)(Kt=this.getStore).call(Kt,this),getComponents:(0,me.default)(ft=this.getComponents).call(ft,this),getState:this.getStore().getState,getConfigs:(0,me.default)(Je=this._getConfigs).call(Je,this),Im:ht.default,React:U.default},this.system.rootInjects||{})}},{key:"_getConfigs",value:function(){return this.system.configs}},{key:"getConfigs",value:function(){return{configs:this.system.configs}}},{key:"setConfigs",value:function(Kt){this.system.configs=Kt}},{key:"rebuildReducer",value:function(){var Kt,ft,Je;this.store.replaceReducer((Kt=(0,Tn.Ay)(this.system.statePlugins,function(et){return et.reducers}),Je=(0,Le.default)(ft=(0,C.default)(Kt)).call(ft,function(et,At){return et[At]=(Ot=Kt[At],function(){var zt=arguments.length>0&&void 0!==arguments[0]?arguments[0]:new ht.Map,En=arguments.length>1?arguments[1]:void 0;if(!Ot)return zt;var Yn=Ot[En.type];if(Yn){var Ln=Rn(Yn)(zt,En);return null===Ln?zt:Ln}return zt}),et;var Ot},{}),(0,C.default)(Je).length?(0,Dt.combineReducers)(Je):Hr))}},{key:"getType",value:function(Kt){var ft=Kt[0].toUpperCase()+(0,Fe.default)(Kt).call(Kt,1);return(0,Tn.Q2)(this.system.statePlugins,function(Je,Qe){var et=Je[Kt];if(et)return(0,W.default)({},Qe+ft,et)})}},{key:"getSelectors",value:function(){return this.getType("selectors")}},{key:"getActions",value:function(){var Kt=this.getType("actions");return(0,Tn.Ay)(Kt,function(ft){return(0,Tn.Q2)(ft,function(Je,Qe){if((0,Tn.LQ)(Je))return(0,W.default)({},Qe,Je)})})}},{key:"getWrappedAndBoundActions",value:function(Kt){var ft=this,Je=this.getBoundActions(Kt);return(0,Tn.Ay)(Je,function(Qe,et){var At=ft.system.statePlugins[(0,Fe.default)(et).call(et,0,-7)].wrapActions;return At?(0,Tn.Ay)(Qe,function(Ot,zt){var En=At[zt];return En?((0,Re.default)(En)||(En=[En]),(0,Le.default)(En).call(En,function(Yn,Ln){var qn=function(){return Ln(Yn,ft.getSystem()).apply(void 0,arguments)};if(!(0,Tn.LQ)(qn))throw new TypeError("wrapActions needs to return a function that returns a new function (ie the wrapped action)");return Rn(qn)},Ot||Function.prototype)):Ot}):Qe})}},{key:"getWrappedAndBoundSelectors",value:function(Kt,ft){var Je=this,Qe=this.getBoundSelectors(Kt,ft);return(0,Tn.Ay)(Qe,function(et,At){var Ot=[(0,Fe.default)(At).call(At,0,-9)],zt=Je.system.statePlugins[Ot].wrapSelectors;return zt?(0,Tn.Ay)(et,function(En,Yn){var Ln=zt[Yn];return Ln?((0,Re.default)(Ln)||(Ln=[Ln]),(0,Le.default)(Ln).call(Ln,function(qn,hi){var ci=function(){for(var Oi,Ni=arguments.length,so=new Array(Ni),Ki=0;Ki<Ni;Ki++)so[Ki]=arguments[Ki];return hi(qn,Je.getSystem()).apply(void 0,(0,o.default)(Oi=[Kt().getIn(Ot)]).call(Oi,so))};if(!(0,Tn.LQ)(ci))throw new TypeError("wrapSelector needs to return a function that returns a new function (ie the wrapped action)");return ci},En||Function.prototype)):En}):et})}},{key:"getStates",value:function(Kt){var ft;return(0,Le.default)(ft=(0,C.default)(this.system.statePlugins)).call(ft,function(Je,Qe){return Je[Qe]=Kt.get(Qe),Je},{})}},{key:"getStateThunks",value:function(Kt){var ft;return(0,Le.default)(ft=(0,C.default)(this.system.statePlugins)).call(ft,function(Je,Qe){return Je[Qe]=function(){return Kt().get(Qe)},Je},{})}},{key:"getFn",value:function(){return{fn:this.system.fn}}},{key:"getComponents",value:function(Kt){var ft=this,Je=this.system.components[Kt];return(0,Re.default)(Je)?(0,Le.default)(Je).call(Je,function(Qe,et){return et(Qe,ft.getSystem())}):void 0!==Kt?this.system.components[Kt]:this.system.components}},{key:"getBoundSelectors",value:function(Kt,ft){return(0,Tn.Ay)(this.getSelectors(),function(Je,Qe){var et=[(0,Fe.default)(Qe).call(Qe,0,-9)],At=function(){return Kt().getIn(et)};return(0,Tn.Ay)(Je,function(Ot){return function(){for(var zt,En=arguments.length,Yn=new Array(En),Ln=0;Ln<En;Ln++)Yn[Ln]=arguments[Ln];var qn=Rn(Ot).apply(null,(0,o.default)(zt=[At()]).call(zt,Yn));return"function"==typeof qn&&(qn=Rn(qn)(ft())),qn}})})}},{key:"getBoundActions",value:function(Kt){Kt=Kt||this.getStore().dispatch;var ft=this.getActions(),Je=function Qe(et){return"function"!=typeof et?(0,Tn.Ay)(et,function(At){return Qe(At)}):function(){var At=null;try{At=et.apply(void 0,arguments)}catch(Ot){At={type:kt.NEW_THROWN_ERR,error:!0,payload:(0,Ft.serializeError)(Ot)}}finally{return At}}};return(0,Tn.Ay)(ft,function(Qe){return(0,pt.bindActionCreators)(Je(Qe),Kt)})}},{key:"getMapStateToProps",value:function(){var Kt=this;return function(){return(0,_e.default)({},Kt.getSystem())}}},{key:"getMapDispatchToProps",value:function(Kt){var ft=this;return function(Je){return j()({},ft.getWrappedAndBoundActions(Je),ft.getFn(),Kt)}}}]),vn}();function Nr(vn,Kt,ft){if((0,Tn.Kn)(vn)&&!(0,Tn.kJ)(vn))return(0,cn.default)({},vn);if((0,Tn.Wl)(vn))return Nr(vn(Kt),Kt,ft);if((0,Tn.kJ)(vn)){var Je,Qe="chain"===ft.pluginLoadType?Kt.getComponents():{};return(0,Le.default)(Je=(0,we.default)(vn).call(vn,function(et){return Nr(et,Kt,ft)})).call(Je,fn,Qe)}return{}}function xr(vn,Kt){var ft=this,Je=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},Qe=Je.hasLoaded,et=Qe;return(0,Tn.Kn)(vn)&&!(0,Tn.kJ)(vn)&&"function"==typeof vn.afterLoad&&(et=!0,Rn(vn.afterLoad).call(this,Kt)),(0,Tn.Wl)(vn)?xr.call(this,vn(Kt),Kt,{hasLoaded:et}):(0,Tn.kJ)(vn)?(0,we.default)(vn).call(vn,function(At){return xr.call(ft,At,Kt,{hasLoaded:et})}):et}function fn(){var vn=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},Kt=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!(0,Tn.Kn)(vn))return{};if(!(0,Tn.Kn)(Kt))return vn;Kt.wrapComponents&&((0,Tn.Ay)(Kt.wrapComponents,function(hi,ci){var Oi=vn.components&&vn.components[ci];Oi&&(0,Re.default)(Oi)?(vn.components[ci]=(0,o.default)(Oi).call(Oi,[hi]),delete Kt.wrapComponents[ci]):Oi&&(vn.components[ci]=[Oi,hi],delete Kt.wrapComponents[ci])}),(0,C.default)(Kt.wrapComponents).length||delete Kt.wrapComponents);var ft=vn.statePlugins;if((0,Tn.Kn)(ft))for(var Je in ft){var Qe=ft[Je];if((0,Tn.Kn)(Qe)){var et=Qe.wrapActions,At=Qe.wrapSelectors;if((0,Tn.Kn)(et))for(var Ot in et){var zt,En=et[Ot];(0,Re.default)(En)||(et[Ot]=En=[En]),Kt&&Kt.statePlugins&&Kt.statePlugins[Je]&&Kt.statePlugins[Je].wrapActions&&Kt.statePlugins[Je].wrapActions[Ot]&&(Kt.statePlugins[Je].wrapActions[Ot]=(0,o.default)(zt=et[Ot]).call(zt,Kt.statePlugins[Je].wrapActions[Ot]))}if((0,Tn.Kn)(At))for(var Yn in At){var Ln,qn=At[Yn];(0,Re.default)(qn)||(At[Yn]=qn=[qn]),Kt&&Kt.statePlugins&&Kt.statePlugins[Je]&&Kt.statePlugins[Je].wrapSelectors&&Kt.statePlugins[Je].wrapSelectors[Yn]&&(Kt.statePlugins[Je].wrapSelectors[Yn]=(0,o.default)(Ln=At[Yn]).call(Ln,Kt.statePlugins[Je].wrapSelectors[Yn]))}}}return j()(vn,Kt)}function Rn(vn){var Kt=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},ft=Kt.logErrors,Je=void 0===ft||ft;return"function"!=typeof vn?vn:function(){try{for(var Qe,et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return vn.call.apply(vn,(0,o.default)(Qe=[this]).call(Qe,At))}catch(zt){return Je&&console.error(zt),null}}}function kn(vn,Kt,ft){var Qe,et,Ot;return Qe=vn,et=Kt,Ot=[(0,Tn._5)(ft)],(0,pt.createStore)(Qe,et,(wn.Z.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__||pt.compose)(pt.applyMiddleware.apply(void 0,Ot)))}var Wn=Mo(7793),bn=Mo(6821),jr=Mo(7038),ji=Mo(3420),oi=Mo(8883),Ui=Mo(6575),Xr=Mo(9150),Sn=Mo(2990),hn=Mo(3705),_r=Mo(8525),Fi=Mo(8011),_s=Mo(1661),Ho=Mo(4980),yo=Mo(9978),Us=Mo(8560),zs=Mo(8102),Di=Mo(6340),oo=Mo(9972),ho=Mo(5416),Ze=Mo(8818),Mt=(Mo(5053),Mo(9569),Mo(5013)),St=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(Je,Qe){var et;(0,re.default)(this,ft),et=Kt.call(this,Je,Qe),(0,W.default)((0,Di.default)(et),"toggleShown",function(){var Ot=et.props,zt=Ot.layoutActions,En=Ot.tag,Yn=Ot.operationId,Ln=Ot.isShown,qn=et.getResolvedSubtree();Ln||void 0!==qn||et.requestResolvedSubtree(),zt.show(["operations",En,Yn],!Ln)}),(0,W.default)((0,Di.default)(et),"onCancelClick",function(){et.setState({tryItOutEnabled:!et.state.tryItOutEnabled})}),(0,W.default)((0,Di.default)(et),"onTryoutClick",function(){et.setState({tryItOutEnabled:!et.state.tryItOutEnabled})}),(0,W.default)((0,Di.default)(et),"onExecute",function(){et.setState({executeInProgress:!0})}),(0,W.default)((0,Di.default)(et),"getResolvedSubtree",function(){var Ot=et.props,En=Ot.path,Yn=Ot.method,Ln=Ot.specPath;return Ot.specSelectors.specResolvedSubtree(Ln?Ln.toJS():["paths",En,Yn])}),(0,W.default)((0,Di.default)(et),"requestResolvedSubtree",function(){var Ot=et.props,En=Ot.path,Yn=Ot.method,Ln=Ot.specPath;return Ot.specActions.requestResolvedSubtree(Ln?Ln.toJS():["paths",En,Yn])});var At=Je.getConfigs().tryItOutEnabled;return et.state={tryItOutEnabled:!0===At||"true"===At,executeInProgress:!1},et}return(0,oe.default)(ft,[{key:"mapStateToProps",value:function(Je,Qe){var et,At=Qe.op,Ot=Qe.layoutSelectors,zt=(0,Qe.getConfigs)(),En=zt.docExpansion,Yn=zt.deepLinking,Ln=zt.displayOperationId,qn=zt.displayRequestDuration,hi=zt.supportedSubmitMethods,ci=Ot.showSummary(),Oi=At.getIn(["operation","__originalOperationId"])||At.getIn(["operation","operationId"])||(0,Mt.opId)(At.get("operation"),Qe.path,Qe.method)||At.get("id"),Ni=["operations",Qe.tag,Oi],so=Yn&&"false"!==Yn,Ki=(0,Ze.default)(hi).call(hi,Qe.method)>=0&&(void 0===Qe.allowTryItOut?Qe.specSelectors.allowTryItOutFor(Qe.path,Qe.method):Qe.allowTryItOut),eo=At.getIn(["operation","security"])||Qe.specSelectors.security();return{operationId:Oi,isDeepLinkingEnabled:so,showSummary:ci,displayOperationId:Ln,displayRequestDuration:qn,allowTryItOut:Ki,security:eo,isAuthorized:Qe.authSelectors.isAuthorized(eo),isShown:Ot.isShown(Ni,"full"===En),jumpToKey:(0,o.default)(et="paths.".concat(Qe.path,".")).call(et,Qe.method),response:Qe.specSelectors.responseFor(Qe.path,Qe.method),request:Qe.specSelectors.requestFor(Qe.path,Qe.method)}}},{key:"componentDidMount",value:function(){var Je=this.props.isShown,Qe=this.getResolvedSubtree();Je&&void 0===Qe&&this.requestResolvedSubtree()}},{key:"UNSAFE_componentWillReceiveProps",value:function(Je){var Qe=Je.response,et=Je.isShown,At=this.getResolvedSubtree();Qe!==this.props.response&&this.setState({executeInProgress:!1}),et&&void 0===At&&this.requestResolvedSubtree()}},{key:"render",value:function(){var Je=this.props,Qe=Je.op,et=Je.tag,At=Je.path,Ot=Je.method,zt=Je.security,En=Je.isAuthorized,Yn=Je.operationId,Ln=Je.showSummary,qn=Je.isShown,hi=Je.jumpToKey,ci=Je.allowTryItOut,Oi=Je.response,Ni=Je.request,so=Je.displayOperationId,Ki=Je.displayRequestDuration,eo=Je.isDeepLinkingEnabled,gs=Je.specPath,Ns=Je.specSelectors,qs=Je.specActions,Os=Je.getComponent,ws=Je.getConfigs,Ps=Je.layoutSelectors,bs=Je.layoutActions,ka=Je.authActions,Ys=Je.authSelectors,Sa=Je.oas3Actions,Jo=Je.oas3Selectors,ea=Je.fn,vl=Os("operation"),ud=this.getResolvedSubtree()||(0,ht.Map)(),af=(0,ht.fromJS)({op:ud,tag:et,path:At,summary:Qe.getIn(["operation","summary"])||"",deprecated:ud.get("deprecated")||Qe.getIn(["operation","deprecated"])||!1,method:Ot,security:zt,isAuthorized:En,operationId:Yn,originalOperationId:ud.getIn(["operation","__originalOperationId"]),showSummary:Ln,isShown:qn,jumpToKey:hi,allowTryItOut:ci,request:Ni,displayOperationId:so,displayRequestDuration:Ki,isDeepLinkingEnabled:eo,executeInProgress:this.state.executeInProgress,tryItOutEnabled:this.state.tryItOutEnabled});return U.default.createElement(vl,{operation:af,response:Oi,request:Ni,isShown:qn,toggleShown:this.toggleShown,onTryoutClick:this.onTryoutClick,onCancelClick:this.onCancelClick,onExecute:this.onExecute,specPath:gs,specActions:qs,specSelectors:Ns,oas3Actions:Sa,oas3Selectors:Jo,layoutActions:bs,layoutSelectors:Ps,authActions:ka,authSelectors:Ys,getComponent:Os,getConfigs:ws,fn:ea})}}]),ft}(U.PureComponent);(0,W.default)(St,"defaultProps",{showSummary:!0,response:null,allowTryItOut:!0,displayOperationId:!1,displayRequestDuration:!1});var Un=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"getLayout",value:function(){var Je=this.props,Qe=Je.getComponent,et=Je.layoutSelectors.current();return Qe(et,!0)||function(){return U.default.createElement("h1",null,' No layout defined for "',et,'" ')}}},{key:"render",value:function(){var Je=this.getLayout();return U.default.createElement(Je,null)}}]),ft}(U.default.Component);Un.defaultProps={};var pr=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"close",function(){Qe.props.authActions.showDefinitions(!1)}),Qe}return(0,oe.default)(ft,[{key:"render",value:function(){var Je,Qe=this.props,et=Qe.authSelectors,At=Qe.authActions,Ot=Qe.getComponent,zt=Qe.errSelectors,En=Qe.specSelectors,Yn=Qe.fn.AST,Ln=void 0===Yn?{}:Yn,qn=et.shownDefinitions(),hi=Ot("auths");return U.default.createElement("div",{className:"dialog-ux"},U.default.createElement("div",{className:"backdrop-ux"}),U.default.createElement("div",{className:"modal-ux"},U.default.createElement("div",{className:"modal-dialog-ux"},U.default.createElement("div",{className:"modal-ux-inner"},U.default.createElement("div",{className:"modal-ux-header"},U.default.createElement("h3",null,"Available authorizations"),U.default.createElement("button",{type:"button",className:"close-modal",onClick:this.close},U.default.createElement("svg",{width:"20",height:"20"},U.default.createElement("use",{href:"#close",xlinkHref:"#close"})))),U.default.createElement("div",{className:"modal-ux-content"},(0,we.default)(Je=qn.valueSeq()).call(Je,function(ci,Oi){return U.default.createElement(hi,{key:Oi,AST:Ln,definitions:ci,getComponent:Ot,errSelectors:zt,authSelectors:et,authActions:At,specSelectors:En})}))))))}}]),ft}(U.default.Component),Vr=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.isAuthorized,et=Je.showPopup,At=Je.onClick,Ot=(0,Je.getComponent)("authorizationPopup",!0);return U.default.createElement("div",{className:"auth-wrapper"},U.default.createElement("button",{className:Qe?"btn authorize locked":"btn authorize unlocked",onClick:At},U.default.createElement("span",null,"Authorize"),U.default.createElement("svg",{width:"20",height:"20"},U.default.createElement("use",{href:Qe?"#locked":"#unlocked",xlinkHref:Qe?"#locked":"#unlocked"}))),et&&U.default.createElement(Ot,null))}}]),ft}(U.default.Component),Ri=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.authActions,et=Je.authSelectors,Ot=Je.getComponent,zt=Je.specSelectors.securityDefinitions(),En=et.definitionsToAuthorize(),Yn=Ot("authorizeBtn");return zt?U.default.createElement(Yn,{onClick:function(){return Qe.showDefinitions(En)},isAuthorized:!!et.authorized().size,showPopup:!!et.shownDefinitions(),getComponent:Ot}):null}}]),ft}(U.default.Component),Bs=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"onClick",function(zt){zt.stopPropagation();var En=Qe.props.onClick;En&&En()}),Qe}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props.isAuthorized;return U.default.createElement("button",{className:Je?"authorization__btn locked":"authorization__btn unlocked","aria-label":Je?"authorization button locked":"authorization button unlocked",onClick:this.onClick},U.default.createElement("svg",{width:"20",height:"20"},U.default.createElement("use",{href:Je?"#locked":"#unlocked",xlinkHref:Je?"#locked":"#unlocked"})))}}]),ft}(U.default.Component),Uo=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(Je,Qe){var et;return(0,re.default)(this,ft),et=Kt.call(this,Je,Qe),(0,W.default)((0,Di.default)(et),"onAuthChange",function(At){et.setState((0,W.default)({},At.name,At))}),(0,W.default)((0,Di.default)(et),"submitAuth",function(At){At.preventDefault(),et.props.authActions.authorizeWithPersistOption(et.state)}),(0,W.default)((0,Di.default)(et),"logoutClick",function(At){At.preventDefault();var Ot=et.props,zt=Ot.authActions,En=Ot.definitions,Yn=(0,we.default)(En).call(En,function(Ln,qn){return qn}).toArray();et.setState((0,Le.default)(Yn).call(Yn,function(Ln,qn){return Ln[qn]="",Ln},{})),zt.logoutWithPersistOption(Yn)}),(0,W.default)((0,Di.default)(et),"close",function(At){At.preventDefault(),et.props.authActions.showDefinitions(!1)}),et.state={},et}return(0,oe.default)(ft,[{key:"render",value:function(){var Je,Qe=this,et=this.props,At=et.definitions,Ot=et.getComponent,zt=et.authSelectors,En=et.errSelectors,Yn=Ot("AuthItem"),Ln=Ot("oauth2",!0),qn=Ot("Button"),hi=zt.authorized(),ci=(0,g.default)(At).call(At,function(so,Ki){return!!hi.get(Ki)}),Oi=(0,g.default)(At).call(At,function(so){return"oauth2"!==so.get("type")}),Ni=(0,g.default)(At).call(At,function(so){return"oauth2"===so.get("type")});return U.default.createElement("div",{className:"auth-container"},!!Oi.size&&U.default.createElement("form",{onSubmit:this.submitAuth},(0,we.default)(Oi).call(Oi,function(so,Ki){return U.default.createElement(Yn,{key:Ki,schema:so,name:Ki,getComponent:Ot,onAuthChange:Qe.onAuthChange,authorized:hi,errSelectors:En})}).toArray(),U.default.createElement("div",{className:"auth-btn-wrapper"},Oi.size===ci.size?U.default.createElement(qn,{className:"btn modal-btn auth",onClick:this.logoutClick},"Logout"):U.default.createElement(qn,{type:"submit",className:"btn modal-btn auth authorize"},"Authorize"),U.default.createElement(qn,{className:"btn modal-btn auth btn-done",onClick:this.close},"Close"))),Ni&&Ni.size?U.default.createElement("div",null,U.default.createElement("div",{className:"scope-def"},U.default.createElement("p",null,"Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes."),U.default.createElement("p",null,"API requires the following scopes. Select which ones you want to grant to Swagger UI.")),(0,we.default)(Je=(0,g.default)(At).call(At,function(so){return"oauth2"===so.get("type")})).call(Je,function(so,Ki){return U.default.createElement("div",{key:Ki},U.default.createElement(Ln,{authorized:hi,schema:so,name:Ki}))}).toArray()):null)}}]),ft}(U.default.Component),ol=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je,Qe=this.props,et=Qe.schema,At=Qe.name,Ot=Qe.getComponent,zt=Qe.onAuthChange,En=Qe.authorized,Yn=Qe.errSelectors,Ln=Ot("apiKeyAuth"),qn=Ot("basicAuth"),hi=et.get("type");switch(hi){case"apiKey":Je=U.default.createElement(Ln,{key:At,schema:et,name:At,errSelectors:Yn,authorized:En,getComponent:Ot,onChange:zt});break;case"basic":Je=U.default.createElement(qn,{key:At,schema:et,name:At,errSelectors:Yn,authorized:En,getComponent:Ot,onChange:zt});break;default:Je=U.default.createElement("div",{key:At},"Unknown security definition type ",hi)}return U.default.createElement("div",{key:"".concat(At,"-jump")},Je)}}]),ft}(U.default.Component),ml=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props.error,Qe=Je.get("level"),et=Je.get("message"),At=Je.get("source");return U.default.createElement("div",{className:"errors"},U.default.createElement("b",null,At," ",Qe),U.default.createElement("span",null,et))}}]),ft}(U.default.Component),tu=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(Je,Qe){var et;(0,re.default)(this,ft),et=Kt.call(this,Je,Qe),(0,W.default)((0,Di.default)(et),"onChange",function(Yn){var Ln=et.props.onChange,hi=(0,_e.default)({},et.state,{value:Yn.target.value});et.setState(hi),Ln(hi)});var At=et.props,Ot=At.name,zt=At.schema,En=et.getValue();return et.state={name:Ot,schema:zt,value:En},et}return(0,oe.default)(ft,[{key:"getValue",value:function(){var Je=this.props,et=Je.authorized;return et&&et.getIn([Je.name,"value"])}},{key:"render",value:function(){var Je,Qe,et=this.props,At=et.schema,Ot=et.getComponent,zt=et.errSelectors,En=et.name,Yn=Ot("Input"),Ln=Ot("Row"),qn=Ot("Col"),hi=Ot("authError"),ci=Ot("Markdown",!0),Oi=Ot("JumpToPath",!0),Ni=this.getValue(),so=(0,g.default)(Je=zt.allErrors()).call(Je,function(Ki){return Ki.get("authId")===En});return U.default.createElement("div",null,U.default.createElement("h4",null,U.default.createElement("code",null,En||At.get("name")),"\xa0(apiKey)",U.default.createElement(Oi,{path:["securityDefinitions",En]})),Ni&&U.default.createElement("h6",null,"Authorized"),U.default.createElement(Ln,null,U.default.createElement(ci,{source:At.get("description")})),U.default.createElement(Ln,null,U.default.createElement("p",null,"Name: ",U.default.createElement("code",null,At.get("name")))),U.default.createElement(Ln,null,U.default.createElement("p",null,"In: ",U.default.createElement("code",null,At.get("in")))),U.default.createElement(Ln,null,U.default.createElement("label",null,"Value:"),Ni?U.default.createElement("code",null," ****** "):U.default.createElement(qn,null,U.default.createElement(Yn,{type:"text",onChange:this.onChange,autoFocus:!0}))),(0,we.default)(Qe=so.valueSeq()).call(Qe,function(Ki,eo){return U.default.createElement(hi,{error:Ki,key:eo})}))}}]),ft}(U.default.Component),qu=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(Je,Qe){var et;(0,re.default)(this,ft),et=Kt.call(this,Je,Qe),(0,W.default)((0,Di.default)(et),"onChange",function(Yn){var Ln=et.props.onChange,qn=Yn.target,Oi=et.state.value;Oi[qn.name]=qn.value,et.setState({value:Oi}),Ln(et.state)});var At=et.props,Ot=At.schema,zt=At.name,En=et.getValue().username;return et.state={name:zt,schema:Ot,value:En?{username:En}:{}},et}return(0,oe.default)(ft,[{key:"getValue",value:function(){var Je=this.props,Qe=Je.authorized;return Qe&&Qe.getIn([Je.name,"value"])||{}}},{key:"render",value:function(){var Je,Qe,et=this.props,At=et.schema,Ot=et.getComponent,zt=et.name,En=et.errSelectors,Yn=Ot("Input"),Ln=Ot("Row"),qn=Ot("Col"),hi=Ot("authError"),ci=Ot("JumpToPath",!0),Oi=Ot("Markdown",!0),Ni=this.getValue().username,so=(0,g.default)(Je=En.allErrors()).call(Je,function(Ki){return Ki.get("authId")===zt});return U.default.createElement("div",null,U.default.createElement("h4",null,"Basic authorization",U.default.createElement(ci,{path:["securityDefinitions",zt]})),Ni&&U.default.createElement("h6",null,"Authorized"),U.default.createElement(Ln,null,U.default.createElement(Oi,{source:At.get("description")})),U.default.createElement(Ln,null,U.default.createElement("label",null,"Username:"),Ni?U.default.createElement("code",null," ",Ni," "):U.default.createElement(qn,null,U.default.createElement(Yn,{type:"text",required:"required",name:"username",onChange:this.onChange,autoFocus:!0}))),U.default.createElement(Ln,null,U.default.createElement("label",null,"Password:"),Ni?U.default.createElement("code",null," ****** "):U.default.createElement(qn,null,U.default.createElement(Yn,{autoComplete:"new-password",name:"password",type:"password",onChange:this.onChange}))),(0,we.default)(Qe=so.valueSeq()).call(Qe,function(Ki,eo){return U.default.createElement(hi,{error:Ki,key:eo})}))}}]),ft}(U.default.Component);function Lf(vn){var Kt=vn.example,ft=vn.showValue,Je=vn.getComponent,Qe=vn.getConfigs,et=Je("Markdown",!0),At=Je("highlightCode");return Kt?U.default.createElement("div",{className:"example"},Kt.get("description")?U.default.createElement("section",{className:"example__section"},U.default.createElement("div",{className:"example__section-header"},"Example Description"),U.default.createElement("p",null,U.default.createElement(et,{source:Kt.get("description")}))):null,ft&&Kt.has("value")?U.default.createElement("section",{className:"example__section"},U.default.createElement("div",{className:"example__section-header"},"Example Value"),U.default.createElement(At,{getConfigs:Qe,value:(0,Tn.Pz)(Kt.get("value"))})):null):null}var Fl=Mo(6914),Kc=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"_onSelect",function(zt){var En=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},Yn=En.isSyntheticChange,Ln=void 0!==Yn&&Yn;"function"==typeof Qe.props.onSelect&&Qe.props.onSelect(zt,{isSyntheticChange:Ln})}),(0,W.default)((0,Di.default)(Qe),"_onDomSelect",function(zt){if("function"==typeof Qe.props.onSelect){var En=zt.target.selectedOptions[0].getAttribute("value");Qe._onSelect(En,{isSyntheticChange:!1})}}),(0,W.default)((0,Di.default)(Qe),"getCurrentExample",function(){var zt=Qe.props,En=zt.examples,Ln=En.get(zt.currentExampleKey),qn=En.keySeq().first(),hi=En.get(qn);return Ln||hi||(0,Fl.default)({})}),Qe}return(0,oe.default)(ft,[{key:"componentDidMount",value:function(){var Je=this.props,et=Je.examples;if("function"==typeof Je.onSelect){var At=et.first(),Ot=et.keyOf(At);this._onSelect(Ot,{isSyntheticChange:!0})}}},{key:"UNSAFE_componentWillReceiveProps",value:function(Je){var et=Je.examples;if(et!==this.props.examples&&!et.has(Je.currentExampleKey)){var At=et.first(),Ot=et.keyOf(At);this._onSelect(Ot,{isSyntheticChange:!0})}}},{key:"render",value:function(){var Je=this.props,Qe=Je.examples,et=Je.currentExampleKey,At=Je.isValueModified,Ot=Je.isModifiedValueAvailable;return U.default.createElement("div",{className:"examples-select"},Je.showLabels?U.default.createElement("span",{className:"examples-select__section-label"},"Examples: "):null,U.default.createElement("select",{className:"examples-select-element",onChange:this._onDomSelect,value:Ot&&At?"__MODIFIED__VALUE__":et||""},Ot?U.default.createElement("option",{value:"__MODIFIED__VALUE__"},"[Modified value]"):null,(0,we.default)(Qe).call(Qe,function(En,Yn){return U.default.createElement("option",{key:Yn,value:Yn},En.get("summary")||Yn)}).valueSeq()))}}]),ft}(U.default.PureComponent);(0,W.default)(Kc,"defaultProps",{examples:ht.default.Map({}),onSelect:function(){for(var vn,Kt,ft=arguments.length,Je=new Array(ft),Qe=0;Qe<ft;Qe++)Je[Qe]=arguments[Qe];return(vn=console).log.apply(vn,(0,o.default)(Kt=["DEBUG: ExamplesSelect was not given an onSelect callback"]).call(Kt,Je))},currentExampleKey:null,showLabels:!0});var cp=function(vn){return ht.List.isList(vn)?vn:(0,Tn.Pz)(vn)},Ah=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(Je){var Qe;(0,re.default)(this,ft),Qe=Kt.call(this,Je),(0,W.default)((0,Di.default)(Qe),"_getStateForCurrentNamespace",function(){return(Qe.state[Qe.props.currentNamespace]||(0,ht.Map)()).toObject()}),(0,W.default)((0,Di.default)(Qe),"_setStateForCurrentNamespace",function(At){return Qe._setStateForNamespace(Qe.props.currentNamespace,At)}),(0,W.default)((0,Di.default)(Qe),"_setStateForNamespace",function(At,Ot){var zt=(Qe.state[At]||(0,ht.Map)()).mergeDeep(Ot);return Qe.setState((0,W.default)({},At,zt))}),(0,W.default)((0,Di.default)(Qe),"_isCurrentUserInputSameAsExampleValue",function(){var At=Qe.props.currentUserInputValue;return Qe._getCurrentExampleValue()===At}),(0,W.default)((0,Di.default)(Qe),"_getValueForExample",function(At,Ot){return cp(((Ot||Qe.props).examples||(0,ht.Map)({})).getIn([At,"value"]))}),(0,W.default)((0,Di.default)(Qe),"_getCurrentExampleValue",function(At){return Qe._getValueForExample((At||Qe.props).currentKey,At||Qe.props)}),(0,W.default)((0,Di.default)(Qe),"_onExamplesSelect",function(At){var Ot=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},zt=Ot.isSyntheticChange,En=Qe.props,Yn=En.onSelect,Ln=En.updateValue,qn=En.currentUserInputValue,hi=En.userHasEditedBody,ci=Qe._getStateForCurrentNamespace(),Oi=ci.lastUserEditedValue,Ni=Qe._getValueForExample(At);if("__MODIFIED__VALUE__"===At)return Ln(cp(Oi)),Qe._setStateForCurrentNamespace({isModifiedValueSelected:!0});if("function"==typeof Yn){for(var so,Ki=arguments.length,eo=new Array(Ki>2?Ki-2:0),gs=2;gs<Ki;gs++)eo[gs-2]=arguments[gs];Yn.apply(void 0,(0,o.default)(so=[At,{isSyntheticChange:zt}]).call(so,eo))}Qe._setStateForCurrentNamespace({lastDownstreamValue:Ni,isModifiedValueSelected:zt&&hi||!!qn&&qn!==Ni}),zt||"function"==typeof Ln&&Ln(cp(Ni))});var et=Qe._getCurrentExampleValue();return Qe.state=(0,W.default)({},Je.currentNamespace,(0,ht.Map)({lastUserEditedValue:Qe.props.currentUserInputValue,lastDownstreamValue:et,isModifiedValueSelected:Qe.props.userHasEditedBody||Qe.props.currentUserInputValue!==et})),Qe}return(0,oe.default)(ft,[{key:"componentWillUnmount",value:function(){this.props.setRetainRequestBodyValueFlag(!1)}},{key:"UNSAFE_componentWillReceiveProps",value:function(Je){var Qe=Je.currentUserInputValue,et=Je.examples,At=Je.onSelect,Ot=Je.userHasEditedBody,zt=this._getStateForCurrentNamespace(),En=zt.lastUserEditedValue,Yn=zt.lastDownstreamValue,Ln=this._getValueForExample(Je.currentKey,Je),qn=(0,g.default)(et).call(et,function(hi){return hi.get("value")===Qe||(0,Tn.Pz)(hi.get("value"))===Qe});qn.size?At(qn.has(Je.currentKey)?Je.currentKey:qn.keySeq().first(),{isSyntheticChange:!0}):Qe!==this.props.currentUserInputValue&&Qe!==En&&Qe!==Yn&&(this.props.setRetainRequestBodyValueFlag(!0),this._setStateForNamespace(Je.currentNamespace,{lastUserEditedValue:Je.currentUserInputValue,isModifiedValueSelected:Ot||Qe!==Ln}))}},{key:"render",value:function(){var Je=this.props,Qe=Je.currentUserInputValue,et=Je.examples,At=Je.currentKey,Ot=Je.getComponent,zt=Je.userHasEditedBody,En=this._getStateForCurrentNamespace(),Yn=En.lastDownstreamValue,Ln=En.lastUserEditedValue,qn=En.isModifiedValueSelected,hi=Ot("ExamplesSelect");return U.default.createElement(hi,{examples:et,currentExampleKey:At,onSelect:this._onExamplesSelect,isModifiedValueAvailable:!!Ln&&Ln!==Yn,isValueModified:void 0!==Qe&&qn&&Qe!==this._getCurrentExampleValue()||zt})}}]),ft}(U.default.PureComponent);(0,W.default)(Ah,"defaultProps",{userHasEditedBody:!1,examples:(0,ht.Map)({}),currentNamespace:"__DEFAULT__NAMESPACE__",setRetainRequestBodyValueFlag:function(){},onSelect:function(){for(var vn,Kt,ft=arguments.length,Je=new Array(ft),Qe=0;Qe<ft;Qe++)Je[Qe]=arguments[Qe];return(vn=console).log.apply(vn,(0,o.default)(Kt=["ExamplesSelectValueRetainer: no `onSelect` function was provided"]).call(Kt,Je))},updateValue:function(){for(var vn,Kt,ft=arguments.length,Je=new Array(ft),Qe=0;Qe<ft;Qe++)Je[Qe]=arguments[Qe];return(vn=console).log.apply(vn,(0,o.default)(Kt=["ExamplesSelectValueRetainer: no `updateValue` function was provided"]).call(Kt,Je))}});var Qp=Mo(8898),Oh=Mo(5487),nu=Mo(2372),Yc=Mo(8900),Lp=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(Je,Qe){var et;(0,re.default)(this,ft),et=Kt.call(this,Je,Qe),(0,W.default)((0,Di.default)(et),"close",function(Ki){Ki.preventDefault(),et.props.authActions.showDefinitions(!1)}),(0,W.default)((0,Di.default)(et),"authorize",function(){var Ki=et.props,eo=Ki.authActions,gs=Ki.errActions,qs=Ki.authSelectors,Os=Ki.oas3Selectors,ws=(0,Ki.getConfigs)(),Ps=qs.getConfigs();gs.clear({authId:name,type:"auth",source:"auth"}),function(bs){var ka=bs.auth,Ys=bs.authActions,Sa=bs.errActions,Jo=bs.configs,ea=bs.authConfigs,vl=void 0===ea?{}:ea,ud=bs.currentServer,af=ka.schema,lf=ka.scopes,kf=ka.name,ru=ka.clientId,cd=af.get("flow"),uc=[];switch(cd){case"password":return void Ys.authorizePassword(ka);case"application":case"clientCredentials":case"client_credentials":return void Ys.authorizeApplication(ka);case"accessCode":case"authorizationCode":case"authorization_code":uc.push("response_type=code");break;case"implicit":uc.push("response_type=token")}"string"==typeof ru&&uc.push("client_id="+encodeURIComponent(ru));var dp=Jo.oauth2RedirectUrl;if(void 0!==dp){uc.push("redirect_uri="+encodeURIComponent(dp));var Xf=[];(0,Re.default)(lf)?Xf=lf:ht.default.List.isList(lf)&&(Xf=lf.toArray()),Xf.length>0&&uc.push("scope="+encodeURIComponent(Xf.join(vl.scopeSeparator||" ")));var Gd=(0,Tn.r3)(new Date);if(uc.push("state="+encodeURIComponent(Gd)),void 0!==vl.realm&&uc.push("realm="+encodeURIComponent(vl.realm)),("authorizationCode"===cd||"authorization_code"===cd||"accessCode"===cd)&&vl.usePkceWithAuthorizationCodeGrant){var cc=(0,Tn.Uj)(),Vd=(0,Tn.Xb)(cc);uc.push("code_challenge="+Vd),uc.push("code_challenge_method=S256"),ka.codeVerifier=cc}var uf=vl.additionalQueryStringParams;for(var cf in uf){var wh;void 0!==uf[cf]&&uc.push((0,we.default)(wh=[cf,uf[cf]]).call(wh,encodeURIComponent).join("="))}var Dd=af.get("authorizationUrl"),Af=[ud?(0,Yc.default)((0,Tn.Nm)(Dd),ud,!0).toString():(0,Tn.Nm)(Dd),uc.join("&")].join(-1===(0,Ze.default)(Dd).call(Dd,"?")?"?":"&");Ys.authPopup(Af,{auth:ka,state:Gd,redirectUrl:dp,callback:"implicit"===cd?Ys.preAuthorizeImplicit:vl.useBasicAuthenticationWithAccessCodeGrant?Ys.authorizeAccessCodeWithBasicAuthentication:Ys.authorizeAccessCodeWithFormParams,errCb:Sa.newAuthErr})}else Sa.newAuthErr({authId:kf,source:"validation",level:"error",message:"oauth2RedirectUrl configuration is not passed. Oauth2 authorization cannot be performed."})}({auth:et.state,currentServer:Os.serverEffectiveValue(Os.selectedServer()),authActions:eo,errActions:gs,configs:ws,authConfigs:Ps})}),(0,W.default)((0,Di.default)(et),"onScopeChange",function(Ki){var eo,gs,Ns=Ki.target,qs=Ns.checked,Os=Ns.dataset.value;if(qs&&-1===(0,Ze.default)(eo=et.state.scopes).call(eo,Os)){var ws,Ps=(0,o.default)(ws=et.state.scopes).call(ws,[Os]);et.setState({scopes:Ps})}else if(!qs&&(0,Ze.default)(gs=et.state.scopes).call(gs,Os)>-1){var bs;et.setState({scopes:(0,g.default)(bs=et.state.scopes).call(bs,function(ka){return ka!==Os})})}}),(0,W.default)((0,Di.default)(et),"onInputChange",function(Ki){var eo=Ki.target,qs=(0,W.default)({},eo.dataset.name,eo.value);et.setState(qs)}),(0,W.default)((0,Di.default)(et),"selectScopes",function(Ki){var eo;et.setState(Ki.target.dataset.all?{scopes:(0,Qp.default)((0,Oh.default)(eo=et.props.schema.get("allowedScopes")||et.props.schema.get("scopes")).call(eo))}:{scopes:[]})}),(0,W.default)((0,Di.default)(et),"logout",function(Ki){Ki.preventDefault();var eo=et.props,gs=eo.authActions,qs=eo.name;eo.errActions.clear({authId:qs,type:"auth",source:"auth"}),gs.logoutWithPersistOption([qs])});var At=et.props,Ot=At.name,zt=At.schema,En=At.authorized,Yn=At.authSelectors,Ln=En&&En.get(Ot),qn=Yn.getConfigs()||{},hi=Ln&&Ln.get("username")||"",ci=Ln&&Ln.get("clientId")||qn.clientId||"",Oi=Ln&&Ln.get("clientSecret")||qn.clientSecret||"",Ni=Ln&&Ln.get("passwordType")||"basic",so=Ln&&Ln.get("scopes")||qn.scopes||[];return"string"==typeof so&&(so=so.split(qn.scopeSeparator||" ")),et.state={appName:qn.appName,name:Ot,schema:zt,scopes:so,clientId:ci,clientSecret:Oi,username:hi,password:"",passwordType:Ni},et}return(0,oe.default)(ft,[{key:"render",value:function(){var Je,Qe,et=this,At=this.props,Ot=At.schema,zt=At.getComponent,En=At.authSelectors,Yn=At.errSelectors,Ln=At.name,qn=At.specSelectors,hi=zt("Input"),ci=zt("Row"),Oi=zt("Col"),Ni=zt("Button"),so=zt("authError"),Ki=zt("JumpToPath",!0),eo=zt("Markdown",!0),gs=zt("InitializedInput"),Ns=qn.isOAS3,qs=Ns()?Ot.get("openIdConnectUrl"):null,Os="implicit",ws="password",Ps=Ns()?qs?"authorization_code":"authorizationCode":"accessCode",bs=Ns()?qs?"client_credentials":"clientCredentials":"application",ka=!!(En.getConfigs()||{}).usePkceWithAuthorizationCodeGrant,Ys=Ot.get("flow"),Sa=Ys===Ps&&ka?Ys+" with PKCE":Ys,Jo=Ot.get("allowedScopes")||Ot.get("scopes"),ea=!!En.authorized().get(Ln),vl=(0,g.default)(Je=Yn.allErrors()).call(Je,function(lf){return lf.get("authId")===Ln}),ud=!(0,g.default)(vl).call(vl,function(lf){return"validation"===lf.get("source")}).size,af=Ot.get("description");return U.default.createElement("div",null,U.default.createElement("h4",null,Ln," (OAuth2, ",Sa,") ",U.default.createElement(Ki,{path:["securityDefinitions",Ln]})),this.state.appName?U.default.createElement("h5",null,"Application: ",this.state.appName," "):null,af&&U.default.createElement(eo,{source:Ot.get("description")}),ea&&U.default.createElement("h6",null,"Authorized"),qs&&U.default.createElement("p",null,"OpenID Connect URL: ",U.default.createElement("code",null,qs)),(Ys===Os||Ys===Ps)&&U.default.createElement("p",null,"Authorization URL: ",U.default.createElement("code",null,Ot.get("authorizationUrl"))),(Ys===ws||Ys===Ps||Ys===bs)&&U.default.createElement("p",null,"Token URL:",U.default.createElement("code",null," ",Ot.get("tokenUrl"))),U.default.createElement("p",{className:"flow"},"Flow: ",U.default.createElement("code",null,Sa)),Ys!==ws?null:U.default.createElement(ci,null,U.default.createElement(ci,null,U.default.createElement("label",{htmlFor:"oauth_username"},"username:"),ea?U.default.createElement("code",null," ",this.state.username," "):U.default.createElement(Oi,{tablet:10,desktop:10},U.default.createElement("input",{id:"oauth_username",type:"text","data-name":"username",onChange:this.onInputChange,autoFocus:!0}))),U.default.createElement(ci,null,U.default.createElement("label",{htmlFor:"oauth_password"},"password:"),ea?U.default.createElement("code",null," ****** "):U.default.createElement(Oi,{tablet:10,desktop:10},U.default.createElement("input",{id:"oauth_password",type:"password","data-name":"password",onChange:this.onInputChange}))),U.default.createElement(ci,null,U.default.createElement("label",{htmlFor:"password_type"},"Client credentials location:"),ea?U.default.createElement("code",null," ",this.state.passwordType," "):U.default.createElement(Oi,{tablet:10,desktop:10},U.default.createElement("select",{id:"password_type","data-name":"passwordType",onChange:this.onInputChange},U.default.createElement("option",{value:"basic"},"Authorization header"),U.default.createElement("option",{value:"request-body"},"Request body"))))),(Ys===bs||Ys===Os||Ys===Ps||Ys===ws)&&(!ea||ea&&this.state.clientId)&&U.default.createElement(ci,null,U.default.createElement("label",{htmlFor:"client_id"},"client_id:"),ea?U.default.createElement("code",null," ****** "):U.default.createElement(Oi,{tablet:10,desktop:10},U.default.createElement(gs,{id:"client_id",type:"text",required:Ys===ws,initialValue:this.state.clientId,"data-name":"clientId",onChange:this.onInputChange}))),(Ys===bs||Ys===Ps||Ys===ws)&&!ka&&U.default.createElement(ci,null,U.default.createElement("label",{htmlFor:"client_secret"},"client_secret:"),ea?U.default.createElement("code",null," ****** "):U.default.createElement(Oi,{tablet:10,desktop:10},U.default.createElement(gs,{id:"client_secret",initialValue:this.state.clientSecret,type:"password","data-name":"clientSecret",onChange:this.onInputChange}))),!ea&&Jo&&Jo.size?U.default.createElement("div",{className:"scopes"},U.default.createElement("h2",null,"Scopes:",U.default.createElement("a",{onClick:this.selectScopes,"data-all":!0},"select all"),U.default.createElement("a",{onClick:this.selectScopes},"select none")),(0,we.default)(Jo).call(Jo,function(lf,kf){var ru,cd,uc,dp,Xf;return U.default.createElement(ci,{key:kf},U.default.createElement("div",{className:"checkbox"},U.default.createElement(hi,{"data-value":kf,id:(0,o.default)(ru=(0,o.default)(cd="".concat(kf,"-")).call(cd,Ys,"-checkbox-")).call(ru,et.state.name),disabled:ea,checked:(0,nu.default)(uc=et.state.scopes).call(uc,kf),type:"checkbox",onChange:et.onScopeChange}),U.default.createElement("label",{htmlFor:(0,o.default)(dp=(0,o.default)(Xf="".concat(kf,"-")).call(Xf,Ys,"-checkbox-")).call(dp,et.state.name)},U.default.createElement("span",{className:"item"}),U.default.createElement("div",{className:"text"},U.default.createElement("p",{className:"name"},kf),U.default.createElement("p",{className:"description"},lf)))))}).toArray()):null,(0,we.default)(Qe=vl.valueSeq()).call(Qe,function(lf,kf){return U.default.createElement(so,{error:lf,key:kf})}),U.default.createElement("div",{className:"auth-btn-wrapper"},ud&&(ea?U.default.createElement(Ni,{className:"btn modal-btn auth authorize",onClick:this.logout},"Logout"):U.default.createElement(Ni,{className:"btn modal-btn auth authorize",onClick:this.authorize},"Authorize")),U.default.createElement(Ni,{className:"btn modal-btn auth btn-done",onClick:this.close},"Close")))}}]),ft}(U.default.Component),Yi=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"onClick",function(){var zt=Qe.props,En=zt.specActions,Yn=zt.path,Ln=zt.method;En.clearResponse(Yn,Ln),En.clearRequest(Yn,Ln)}),Qe}return(0,oe.default)(ft,[{key:"render",value:function(){return U.default.createElement("button",{className:"btn btn-clear opblock-control__btn",onClick:this.onClick},"Clear")}}]),ft}(U.Component),or=function(vn){var Kt=vn.headers;return U.default.createElement("div",null,U.default.createElement("h5",null,"Response headers"),U.default.createElement("pre",{className:"microlight"},Kt))},yi=function(vn){var Kt=vn.duration;return U.default.createElement("div",null,U.default.createElement("h5",null,"Request duration"),U.default.createElement("pre",{className:"microlight"},Kt," ms"))},qi=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"shouldComponentUpdate",value:function(Je){return this.props.response!==Je.response||this.props.path!==Je.path||this.props.method!==Je.method||this.props.displayRequestDuration!==Je.displayRequestDuration}},{key:"render",value:function(){var Je,Qe=this.props,et=Qe.response,At=Qe.getComponent,Ot=Qe.getConfigs,zt=Qe.displayRequestDuration,En=Qe.specSelectors,Yn=Qe.path,Ln=Qe.method,qn=Ot(),ci=qn.requestSnippetsEnabled,Oi=qn.showMutatedRequest?En.mutatedRequestFor(Yn,Ln):En.requestFor(Yn,Ln),Ni=et.get("status"),so=Oi.get("url"),Ki=et.get("headers").toJS(),eo=et.get("notDocumented"),gs=et.get("error"),Ns=et.get("text"),qs=et.get("duration"),Os=(0,C.default)(Ki),ws=Ki["content-type"]||Ki["Content-Type"],Ps=At("responseBody"),bs=(0,we.default)(Os).call(Os,function(ea){var vl=(0,Re.default)(Ki[ea])?Ki[ea].join():Ki[ea];return U.default.createElement("span",{className:"headerline",key:ea}," ",ea,": ",vl," ")}),ka=0!==bs.length,Ys=At("Markdown",!0),Sa=At("RequestSnippets",!0),Jo=At("curl");return U.default.createElement("div",null,Oi&&(!0===ci||"true"===ci?U.default.createElement(Sa,{request:Oi}):U.default.createElement(Jo,{request:Oi,getConfigs:Ot})),so&&U.default.createElement("div",null,U.default.createElement("div",{className:"request-url"},U.default.createElement("h4",null,"Request URL"),U.default.createElement("pre",{className:"microlight"},so))),U.default.createElement("h4",null,"Server response"),U.default.createElement("table",{className:"responses-table live-responses-table"},U.default.createElement("thead",null,U.default.createElement("tr",{className:"responses-header"},U.default.createElement("td",{className:"col_header response-col_status"},"Code"),U.default.createElement("td",{className:"col_header response-col_description"},"Details"))),U.default.createElement("tbody",null,U.default.createElement("tr",{className:"response"},U.default.createElement("td",{className:"response-col_status"},Ni,eo?U.default.createElement("div",{className:"response-undocumented"},U.default.createElement("i",null," Undocumented ")):null),U.default.createElement("td",{className:"response-col_description"},gs?U.default.createElement(Ys,{source:(0,o.default)(Je="".concat(""!==et.get("name")?"".concat(et.get("name"),": "):"")).call(Je,et.get("message"))}):null,Ns?U.default.createElement(Ps,{content:Ns,contentType:ws,url:so,headers:Ki,getConfigs:Ot,getComponent:At}):null,ka?U.default.createElement(or,{headers:bs}):null,zt&&qs?U.default.createElement(yi,{duration:qs}):null)))))}}]),ft}(U.default.Component),No=Mo(5623),Wo=["get","put","post","delete","options","head","patch"],qo=(0,o.default)(Wo).call(Wo,["trace"]),is=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"renderOperationTag",function(zt,En){var Yn=Qe.props,Ln=Yn.specSelectors,qn=Yn.getComponent,hi=Yn.oas3Selectors,ci=Yn.layoutSelectors,Oi=Yn.layoutActions,Ni=Yn.getConfigs,so=qn("OperationContainer",!0),Ki=qn("OperationTag"),eo=zt.get("operations");return U.default.createElement(Ki,{key:"operation-"+En,tagObj:zt,tag:En,oas3Selectors:hi,layoutSelectors:ci,layoutActions:Oi,getConfigs:Ni,getComponent:qn,specUrl:Ln.url()},U.default.createElement("div",{className:"operation-tag-content"},(0,we.default)(eo).call(eo,function(gs){var Ns,qs=gs.get("path"),Os=gs.get("method"),ws=ht.default.List(["paths",qs,Os]),Ps=Ln.isOAS3()?qo:Wo;return-1===(0,Ze.default)(Ps).call(Ps,Os)?null:U.default.createElement(so,{key:(0,o.default)(Ns="".concat(qs,"-")).call(Ns,Os),specPath:ws,op:gs,path:qs,method:Os,tag:En})}).toArray()))}),Qe}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props.specSelectors.taggedOperations();return 0===Je.size?U.default.createElement("h3",null," No operations defined in spec!"):U.default.createElement("div",null,(0,we.default)(Je).call(Je,this.renderOperationTag).toArray(),Je.size<1?U.default.createElement("h3",null," No operations defined in spec! "):null)}}]),ft}(U.default.Component),_a=Mo(3769);function Ka(vn){return vn.match(/^(?:[a-z]+:)?\/\//i)}function Du(vn,Kt){return vn?Ka(vn)?(ft=vn).match(/^\/\//i)?(0,o.default)(Je="".concat(window.location.protocol)).call(Je,ft):ft:new _a.default(vn,Kt).href:Kt;var ft,Je}function Qn(vn,Kt){var ft=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},Je=ft.selectedServer,Qe=void 0===Je?"":Je;if(vn){if(Ka(vn))return vn;var et=Du(Qe,Kt);return Ka(et)?new _a.default(vn,et).href:new _a.default(vn,window.location.href).href}}function Ii(vn,Kt){var ft=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},Je=ft.selectedServer,Qe=void 0===Je?"":Je;try{return Qn(vn,Kt,{selectedServer:Qe})}catch(et){return}}var rs=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je,Qe=this.props,et=Qe.tagObj,At=Qe.tag,Ot=Qe.children,zt=Qe.oas3Selectors,En=Qe.layoutSelectors,Yn=Qe.layoutActions,qn=Qe.getComponent,hi=Qe.specUrl,ci=(0,Qe.getConfigs)(),Oi=ci.docExpansion,Ni=ci.deepLinking,so=Ni&&"false"!==Ni,Ki=qn("Collapse"),eo=qn("Markdown",!0),gs=qn("DeepLink"),Ns=qn("Link"),qs=et.getIn(["tagDetails","description"],null),Os=et.getIn(["tagDetails","externalDocs","description"]),ws=et.getIn(["tagDetails","externalDocs","url"]);Je=(0,Tn.Wl)(zt)&&(0,Tn.Wl)(zt.selectedServer)?Ii(ws,hi,{selectedServer:zt.selectedServer()}):ws;var Ps=["operations-tag",At],bs=En.isShown(Ps,"full"===Oi||"list"===Oi);return U.default.createElement("div",{className:bs?"opblock-tag-section is-open":"opblock-tag-section"},U.default.createElement("h3",{onClick:function(){return Yn.show(Ps,!bs)},className:qs?"opblock-tag":"opblock-tag no-desc",id:(0,we.default)(Ps).call(Ps,function(ka){return(0,Tn.J6)(ka)}).join("-"),"data-tag":At,"data-is-open":bs},U.default.createElement(gs,{enabled:so,isShown:bs,path:(0,Tn.oJ)(At),text:At}),qs?U.default.createElement("small",null,U.default.createElement(eo,{source:qs})):U.default.createElement("small",null),Os?U.default.createElement("div",{className:"info__externaldocs"},U.default.createElement("small",null,Os,Je?": ":null,Je?U.default.createElement(Ns,{href:(0,Tn.Nm)(Je),onClick:function(ka){return ka.stopPropagation()},target:"_blank"},Je):null)):null,U.default.createElement("button",{"aria-expanded":bs,className:"expand-operation",title:bs?"Collapse operation":"Expand operation",onClick:function(){return Yn.show(Ps,!bs)}},U.default.createElement("svg",{className:"arrow",width:"20",height:"20","aria-hidden":"true",focusable:"false"},U.default.createElement("use",{href:bs?"#large-arrow-up":"#large-arrow-down",xlinkHref:bs?"#large-arrow-up":"#large-arrow-down"})))),U.default.createElement(Ki,{isOpened:bs},Ot))}}]),ft}(U.default.Component);(0,W.default)(rs,"defaultProps",{tagObj:ht.default.fromJS({}),tag:""});var Zi=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.specPath,et=Je.response,At=Je.request,Ot=Je.toggleShown,zt=Je.onTryoutClick,En=Je.onCancelClick,Yn=Je.onExecute,Ln=Je.fn,qn=Je.getComponent,hi=Je.getConfigs,ci=Je.specActions,Oi=Je.specSelectors,Ni=Je.authActions,so=Je.authSelectors,Ki=Je.oas3Actions,eo=Je.oas3Selectors,gs=this.props.operation,Ns=gs.toJS(),qs=Ns.deprecated,Os=Ns.isShown,ws=Ns.path,Ps=Ns.method,bs=Ns.op,ka=Ns.tag,Ys=Ns.operationId,Sa=Ns.allowTryItOut,Jo=Ns.displayRequestDuration,ea=Ns.tryItOutEnabled,vl=Ns.executeInProgress,ud=bs.description,af=bs.externalDocs,lf=bs.schemes,kf=af?Ii(af.url,Oi.url(),{selectedServer:eo.selectedServer()}):"",ru=gs.getIn(["op"]),cd=ru.get("responses"),uc=(0,Tn.gp)(ru,["parameters"]),dp=Oi.operationScheme(ws,Ps),Xf=["operations",ka,Ys],L_=(0,Tn.nX)(ru),Gd=qn("responses"),cc=qn("parameters"),Vd=qn("execute"),uf=qn("clear"),cf=qn("Collapse"),wh=qn("Markdown",!0),xd=qn("schemes"),Dd=qn("OperationServers"),Af=qn("OperationExt"),xh=qn("OperationSummary"),mm=qn("Link"),Q7=hi().showExtensions;if(cd&&et&&et.size>0){var X7=!cd.get(String(et.get("status")))&&!cd.get("default");et=et.set("notDocumented",X7)}var K7=[ws,Ps];return U.default.createElement("div",{className:qs?"opblock opblock-deprecated":Os?"opblock opblock-".concat(Ps," is-open"):"opblock opblock-".concat(Ps),id:(0,Tn.J6)(Xf.join("-"))},U.default.createElement(xh,{operationProps:gs,isShown:Os,toggleShown:Ot,getComponent:qn,authActions:Ni,authSelectors:so,specPath:Qe}),U.default.createElement(cf,{isOpened:Os},U.default.createElement("div",{className:"opblock-body"},ru&&ru.size||null===ru?null:U.default.createElement("img",{height:"32px",width:"32px",src:Mo(2517),className:"opblock-loading-animation"}),qs&&U.default.createElement("h4",{className:"opblock-title_normal"}," Warning: Deprecated"),ud&&U.default.createElement("div",{className:"opblock-description-wrapper"},U.default.createElement("div",{className:"opblock-description"},U.default.createElement(wh,{source:ud}))),kf?U.default.createElement("div",{className:"opblock-external-docs-wrapper"},U.default.createElement("h4",{className:"opblock-title_normal"},"Find more details"),U.default.createElement("div",{className:"opblock-external-docs"},U.default.createElement("span",{className:"opblock-external-docs__description"},U.default.createElement(wh,{source:af.description})),U.default.createElement(mm,{target:"_blank",className:"opblock-external-docs__link",href:(0,Tn.Nm)(kf)},kf))):null,ru&&ru.size?U.default.createElement(cc,{parameters:uc,specPath:Qe.push("parameters"),operation:ru,onChangeKey:K7,onTryoutClick:zt,onCancelClick:En,tryItOutEnabled:ea,allowTryItOut:Sa,fn:Ln,getComponent:qn,specActions:ci,specSelectors:Oi,pathMethod:[ws,Ps],getConfigs:hi,oas3Actions:Ki,oas3Selectors:eo}):null,ea?U.default.createElement(Dd,{getComponent:qn,path:ws,method:Ps,operationServers:ru.get("servers"),pathServers:Oi.paths().getIn([ws,"servers"]),getSelectedServer:eo.selectedServer,setSelectedServer:Ki.setSelectedServer,setServerVariableValue:Ki.setServerVariableValue,getServerVariable:eo.serverVariableValue,getEffectiveServerValue:eo.serverEffectiveValue}):null,ea&&Sa&&lf&&lf.size?U.default.createElement("div",{className:"opblock-schemes"},U.default.createElement(xd,{schemes:lf,path:ws,method:Ps,specActions:ci,currentScheme:dp})):null,U.default.createElement("div",{className:ea&&et&&Sa?"btn-group":"execute-wrapper"},ea&&Sa?U.default.createElement(Vd,{operation:ru,specActions:ci,specSelectors:Oi,oas3Selectors:eo,oas3Actions:Ki,path:ws,method:Ps,onExecute:Yn,disabled:vl}):null,ea&&et&&Sa?U.default.createElement(uf,{specActions:ci,path:ws,method:Ps}):null),vl?U.default.createElement("div",{className:"loading-container"},U.default.createElement("div",{className:"loading"})):null,cd?U.default.createElement(Gd,{responses:cd,request:At,tryItOutResponse:et,getComponent:qn,getConfigs:hi,specSelectors:Oi,oas3Actions:Ki,oas3Selectors:eo,specActions:ci,produces:Oi.producesOptionsFor([ws,Ps]),producesValue:Oi.currentProducesFor([ws,Ps]),specPath:Qe.push("responses"),path:ws,method:Ps,displayRequestDuration:Jo,fn:Ln}):null,Q7&&L_.size?U.default.createElement(Af,{extensions:L_,getComponent:qn}):null)))}}]),ft}(U.PureComponent);(0,W.default)(Zi,"defaultProps",{operation:null,response:null,request:null,specPath:(0,ht.List)(),summary:""});const As=(vn=>{var Kt={};return Mo.d(Kt,vn),Kt})({default:()=>AF()});var es=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je,Qe=this.props,et=Qe.isShown,At=Qe.toggleShown,Ot=Qe.getComponent,zt=Qe.authActions,En=Qe.authSelectors,Yn=Qe.operationProps,Ln=Qe.specPath,qn=Yn.toJS(),hi=qn.summary,ci=qn.isAuthorized,Oi=qn.method,so=qn.showSummary,Ki=qn.path,eo=qn.operationId,gs=qn.originalOperationId,Ns=qn.displayOperationId,qs=qn.op.summary,Os=Yn.get("security"),ws=Ot("authorizeOperationBtn"),Ps=Ot("OperationSummaryMethod"),bs=Ot("OperationSummaryPath"),ka=Ot("JumpToPath",!0),Ys=Os&&!!Os.count(),Sa=Ys&&1===Os.size&&Os.first().isEmpty(),Jo=!Ys||Sa;return U.default.createElement("div",{className:"opblock-summary opblock-summary-".concat(Oi)},U.default.createElement("button",{"aria-label":(0,o.default)(Je="".concat(Oi," ")).call(Je,Ki.replace(/\//g,"\u200b/")),"aria-expanded":et,className:"opblock-summary-control",onClick:At},U.default.createElement(Ps,{method:Oi}),U.default.createElement(bs,{getComponent:Ot,operationProps:Yn,specPath:Ln}),so?U.default.createElement("div",{className:"opblock-summary-description"},(0,As.default)(qs||hi)):null,Ns&&(gs||eo)?U.default.createElement("span",{className:"opblock-summary-operation-id"},gs||eo):null,U.default.createElement("svg",{className:"arrow",width:"20",height:"20","aria-hidden":"true",focusable:"false"},U.default.createElement("use",{href:et?"#large-arrow-up":"#large-arrow-down",xlinkHref:et?"#large-arrow-up":"#large-arrow-down"}))),Jo?null:U.default.createElement(ws,{isAuthorized:ci,onClick:function(){var ea=En.definitionsForRequirements(Os);zt.showDefinitions(ea)}}),U.default.createElement(ka,{path:Ln}))}}]),ft}(U.PureComponent);(0,W.default)(es,"defaultProps",{operationProps:null,specPath:(0,ht.List)(),summary:""});var fu=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){return U.default.createElement("span",{className:"opblock-summary-method"},this.props.method.toUpperCase())}}]),ft}(U.PureComponent);(0,W.default)(fu,"defaultProps",{operationProps:null});const Ml=(vn=>{var Kt={};return Mo.d(Kt,vn),Kt})({default:()=>h0()});var Ai=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){for(var Je,Qe=this.props,et=Qe.getComponent,At=Qe.operationProps.toJS(),Ot=At.deprecated,zt=At.isShown,En=At.path,Yn=At.tag,Ln=At.operationId,qn=At.isDeepLinkingEnabled,hi=En.split(/(?=\/)/g),ci=1;ci<hi.length;ci+=2)(0,Ml.default)(hi).call(hi,ci,0,U.default.createElement("wbr",{key:ci}));var Oi=et("DeepLink");return U.default.createElement("span",{className:Ot?"opblock-summary-path__deprecated":"opblock-summary-path","data-path":En},U.default.createElement(Oi,{enabled:qn,isShown:zt,path:(0,Tn.oJ)((0,o.default)(Je="".concat(Yn,"/")).call(Je,Ln)),text:hi}))}}]),ft}(U.PureComponent),qa=Mo(9334);const Ba=function(vn){var Kt,ft=vn.extensions,Je=(0,vn.getComponent)("OperationExtRow");return U.default.createElement("div",{className:"opblock-section"},U.default.createElement("div",{className:"opblock-section-header"},U.default.createElement("h4",null,"Extensions")),U.default.createElement("div",{className:"table-container"},U.default.createElement("table",null,U.default.createElement("thead",null,U.default.createElement("tr",null,U.default.createElement("td",{className:"col_header"},"Field"),U.default.createElement("td",{className:"col_header"},"Value"))),U.default.createElement("tbody",null,(0,we.default)(Kt=ft.entrySeq()).call(Kt,function(Qe){var et,At=(0,qa.default)(Qe,2),Ot=At[0],zt=At[1];return U.default.createElement(Je,{key:(0,o.default)(et="".concat(Ot,"-")).call(et,zt),xKey:Ot,xVal:zt})})))))},ec=function(vn){var Kt=vn.xKey,ft=vn.xVal,Je=ft?ft.toJS?ft.toJS():ft:null;return U.default.createElement("tr",null,U.default.createElement("td",null,Kt),U.default.createElement("td",null,(0,D.default)(Je)))};var Ru=Mo(29),Ff=Mo(8096),Xp=Mo(471),Wl=Mo(9908),Qf=Mo(7068);const cg=(vn=>{var Kt={};return Mo.d(Kt,vn),Kt})({default:()=>wF()});var Kp=Mo(9874),Lg=function(vn){var Kt=vn.value,ft=vn.fileName,Je=vn.className,Qe=vn.downloadable,et=vn.getConfigs,At=vn.canCopy,Ot=vn.language,zt=(0,Qf.default)(et)?et():null,En=!1!==(0,Wl.default)(zt,"syntaxHighlight")&&(0,Wl.default)(zt,"syntaxHighlight.activated",!0),Yn=(0,U.useRef)(null);(0,U.useEffect)(function(){var qn,hi=(0,g.default)(qn=(0,Qp.default)(Yn.current.childNodes)).call(qn,function(ci){return!!ci.nodeType&&ci.classList.contains("microlight")});return(0,Ru.default)(hi).call(hi,function(ci){return ci.addEventListener("mousewheel",Ln,{passive:!1})}),function(){(0,Ru.default)(hi).call(hi,function(ci){return ci.removeEventListener("mousewheel",Ln)})}},[Kt,Je,Ot]);var Ln=function(qn){var hi=qn.target,ci=qn.deltaY,Oi=hi.scrollHeight,Ni=hi.offsetHeight,so=hi.scrollTop;Oi>Ni&&(0===so&&ci<0||Ni+so>=Oi&&ci>0)&&qn.preventDefault()};return U.default.createElement("div",{className:"highlight-code",ref:Yn},Qe?U.default.createElement("div",{className:"download-contents",onClick:function(){(0,cg.default)(Kt,ft)}},"Download"):null,At&&U.default.createElement("div",{className:"copy-to-clipboard"},U.default.createElement(Kp.CopyToClipboard,{text:Kt},U.default.createElement("button",null))),En?U.default.createElement(Xp.d3,{language:Ot,className:(0,Ff.default)(Je,"microlight"),style:(0,Xp.C2)((0,Wl.default)(zt,"syntaxHighlight.theme","agate"))},Kt):U.default.createElement("pre",{className:(0,Ff.default)(Je,"microlight")},Kt))};Lg.defaultProps={fileName:"response.txt"};const I_=Lg;var t1=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"onChangeProducesWrapper",function(zt){return Qe.props.specActions.changeProducesValue([Qe.props.path,Qe.props.method],zt)}),(0,W.default)((0,Di.default)(Qe),"onResponseContentTypeChange",function(zt){var Ln=Qe.props;zt.controlsAcceptHeader&&Ln.oas3Actions.setResponseContentType({value:zt.value,path:Ln.path,method:Ln.method})}),Qe}return(0,oe.default)(ft,[{key:"render",value:function(){var Je,Qe,et=this,At=this.props,Ot=At.responses,zt=At.tryItOutResponse,En=At.getComponent,Yn=At.getConfigs,Ln=At.specSelectors,qn=At.fn,hi=At.producesValue,ci=At.displayRequestDuration,Oi=At.specPath,Ni=At.path,so=At.method,Ki=At.oas3Selectors,eo=At.oas3Actions,gs=(0,Tn.iQ)(Ot),Ns=En("contentType"),qs=En("liveResponse"),Os=En("response"),ws=this.props.produces&&this.props.produces.size?this.props.produces:ft.defaultProps.produces,Ps=Ln.isOAS3()?(0,Tn.QG)(Ot):null,bs=function(Ys){var Sa=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"_";return Ys.replace(/[^\w-]/g,Sa)}((0,o.default)(Je="".concat(so)).call(Je,Ni,"_responses")),ka="".concat(bs,"_select");return U.default.createElement("div",{className:"responses-wrapper"},U.default.createElement("div",{className:"opblock-section-header"},U.default.createElement("h4",null,"Responses"),Ln.isOAS3()?null:U.default.createElement("label",{htmlFor:ka},U.default.createElement("span",null,"Response content type"),U.default.createElement(Ns,{value:hi,ariaControls:bs,ariaLabel:"Response content type",className:"execute-content-type",contentTypes:ws,controlId:ka,onChange:this.onChangeProducesWrapper}))),U.default.createElement("div",{className:"responses-inner"},zt?U.default.createElement("div",null,U.default.createElement(qs,{response:zt,getComponent:En,getConfigs:Yn,specSelectors:Ln,path:this.props.path,method:this.props.method,displayRequestDuration:ci}),U.default.createElement("h4",null,"Responses")):null,U.default.createElement("table",{"aria-live":"polite",className:"responses-table",id:bs,role:"region"},U.default.createElement("thead",null,U.default.createElement("tr",{className:"responses-header"},U.default.createElement("td",{className:"col_header response-col_status"},"Code"),U.default.createElement("td",{className:"col_header response-col_description"},"Description"),Ln.isOAS3()?U.default.createElement("td",{className:"col col_header response-col_links"},"Links"):null)),U.default.createElement("tbody",null,(0,we.default)(Qe=Ot.entrySeq()).call(Qe,function(Ys){var Sa=(0,qa.default)(Ys,2),Jo=Sa[0],ea=Sa[1],vl=zt&&zt.get("status")==Jo?"response_current":"";return U.default.createElement(Os,{key:Jo,path:Ni,method:so,specPath:Oi.push(Jo),isDefault:gs===Jo,fn:qn,className:vl,code:Jo,response:ea,specSelectors:Ln,controlsAcceptHeader:ea===Ps,onContentTypeChange:et.onResponseContentTypeChange,contentType:hi,getConfigs:Yn,activeExamplesKey:Ki.activeExamplesMember(Ni,so,"responses",Jo),oas3Actions:eo,getComponent:En})}).toArray()))))}}]),ft}(U.default.Component);(0,W.default)(t1,"defaultProps",{tryItOutResponse:null,produces:(0,ht.fromJS)(["application/json"]),displayRequestDuration:!1});var qp=Mo(1013);const _d=(vn=>{var Kt={};return Mo.d(Kt,vn),Kt})({default:()=>DF()});var Fg=Mo(2518),gm=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(Je,Qe){var et;return(0,re.default)(this,ft),et=Kt.call(this,Je,Qe),(0,W.default)((0,Di.default)(et),"_onContentTypeChange",function(At){var Ot=et.props,zt=Ot.onContentTypeChange,En=Ot.controlsAcceptHeader;et.setState({responseContentType:At}),zt({value:At,controlsAcceptHeader:En})}),(0,W.default)((0,Di.default)(et),"getTargetExamplesKey",function(){var At=et.props,En=At.activeExamplesKey,Ln=At.response.getIn(["content",et.state.responseContentType||At.contentType],(0,ht.Map)({})).get("examples",null).keySeq().first();return En||Ln}),et.state={responseContentType:""},et}return(0,oe.default)(ft,[{key:"render",value:function(){var Je,Qe,et,At,Ot,zt=this.props,En=zt.path,Yn=zt.method,Ln=zt.code,qn=zt.response,hi=zt.className,ci=zt.specPath,Ni=zt.getComponent,so=zt.getConfigs,Ki=zt.specSelectors,eo=zt.contentType,gs=zt.controlsAcceptHeader,Ns=zt.oas3Actions,qs=zt.fn.inferSchema,Os=Ki.isOAS3(),ws=so().showExtensions,Ps=ws?(0,Tn.nX)(qn):null,bs=qn.get("headers"),ka=qn.get("links"),Ys=Ni("ResponseExtension"),Sa=Ni("headers"),Jo=Ni("highlightCode"),ea=Ni("modelExample"),vl=Ni("Markdown",!0),ud=Ni("operationLink"),af=Ni("contentType"),lf=Ni("ExamplesSelect"),kf=Ni("Example"),ru=this.state.responseContentType||eo,cd=qn.getIn(["content",ru],(0,ht.Map)({})),uc=cd.get("examples",null);if(Os){var dp=cd.get("schema");et=dp?qs(dp.toJS()):null,At=dp?(0,ht.List)(["content",this.state.responseContentType,"schema"]):ci}else et=qn.get("schema"),At=qn.has("schema")?ci.push("schema"):ci;var Xf,L_=!1,Gd={includeReadOnly:!0};if(Os){var cc;if(Xf=null===(cc=cd.get("schema"))||void 0===cc?void 0:cc.toJS(),uc){var Vd=this.getTargetExamplesKey(),uf=function(xd){return xd.get("value")};void 0===(Ot=uf(uc.get(Vd,(0,ht.Map)({}))))&&(Ot=uf((0,_d.default)(uc).call(uc).next().value)),L_=!0}else void 0!==cd.get("example")&&(Ot=cd.get("example"),L_=!0)}else{Xf=et,Gd=(0,qp.default)((0,qp.default)({},Gd),{},{includeWriteOnly:!0});var cf=qn.getIn(["examples",ru]);cf&&(Ot=cf,L_=!0)}var wh=function(xd,Dd,Af){if(null!=xd){var xh=null;return(0,Fg.O)(xd)&&(xh="json"),U.default.createElement("div",null,U.default.createElement(Dd,{className:"example",getConfigs:Af,language:xh,value:(0,Tn.Pz)(xd)}))}return null}((0,Tn.xi)(Xf,ru,Gd,L_?Ot:void 0),Jo,so);return U.default.createElement("tr",{className:"response "+(hi||""),"data-code":Ln},U.default.createElement("td",{className:"response-col_status"},Ln),U.default.createElement("td",{className:"response-col_description"},U.default.createElement("div",{className:"response-col_description__inner"},U.default.createElement(vl,{source:qn.get("description")})),ws&&Ps.size?(0,we.default)(Je=Ps.entrySeq()).call(Je,function(xd){var Dd,Af=(0,qa.default)(xd,2),xh=Af[0],mm=Af[1];return U.default.createElement(Ys,{key:(0,o.default)(Dd="".concat(xh,"-")).call(Dd,mm),xKey:xh,xVal:mm})}):null,Os&&qn.get("content")?U.default.createElement("section",{className:"response-controls"},U.default.createElement("div",{className:(0,Ff.default)("response-control-media-type",{"response-control-media-type--accept-controller":gs})},U.default.createElement("small",{className:"response-control-media-type__title"},"Media type"),U.default.createElement(af,{value:this.state.responseContentType,contentTypes:qn.get("content")?qn.get("content").keySeq():(0,ht.Seq)(),onChange:this._onContentTypeChange,ariaLabel:"Media Type"}),gs?U.default.createElement("small",{className:"response-control-media-type__accept-message"},"Controls ",U.default.createElement("code",null,"Accept")," header."):null),uc?U.default.createElement("div",{className:"response-control-examples"},U.default.createElement("small",{className:"response-control-examples__title"},"Examples"),U.default.createElement(lf,{examples:uc,currentExampleKey:this.getTargetExamplesKey(),onSelect:function(xd){return Ns.setActiveExamplesMember({name:xd,pathMethod:[En,Yn],contextType:"responses",contextName:Ln})},showLabels:!1})):null):null,wh||et?U.default.createElement(ea,{specPath:At,getComponent:Ni,getConfigs:so,specSelectors:Ki,schema:(0,Tn.oG)(et),example:wh,includeReadOnly:!0}):null,Os&&uc?U.default.createElement(kf,{example:uc.get(this.getTargetExamplesKey(),(0,ht.Map)({})),getComponent:Ni,getConfigs:so,omitValue:!0}):null,bs?U.default.createElement(Sa,{headers:bs,getComponent:Ni}):null),Os?U.default.createElement("td",{className:"response-col_links"},ka?(0,we.default)(Qe=ka.toSeq().entrySeq()).call(Qe,function(xd){var Dd=(0,qa.default)(xd,2),Af=Dd[0];return U.default.createElement(ud,{key:Af,name:Af,link:Dd[1],getComponent:Ni})}):U.default.createElement("i",null,"No links")):null)}}]),ft}(U.default.Component);(0,W.default)(gm,"defaultProps",{response:(0,ht.fromJS)({}),onContentTypeChange:function(){}});const dg=function(vn){return U.default.createElement("div",{className:"response__extension"},vn.xKey,": ",String(vn.xVal))},nv=(vn=>{var Kt={};return Mo.d(Kt,vn),Kt})({default:()=>NF()}),Fp=(vn=>{var Kt={};return Mo.d(Kt,vn),Kt})({default:()=>IF()});var YA=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"state",{parsedContent:null}),(0,W.default)((0,Di.default)(Qe),"updateParsedContent",function(zt){var En=Qe.props.content;if(zt!==En)if(En&&En instanceof Blob){var Yn=new FileReader;Yn.onload=function(){Qe.setState({parsedContent:Yn.result})},Yn.readAsText(En)}else Qe.setState({parsedContent:En.toString()})}),Qe}return(0,oe.default)(ft,[{key:"componentDidMount",value:function(){this.updateParsedContent(null)}},{key:"componentDidUpdate",value:function(Je){this.updateParsedContent(Je.content)}},{key:"render",value:function(){var Je,Qe,et=this.props,At=et.content,Ot=et.contentType,zt=et.url,En=et.headers,Yn=void 0===En?{}:En,Ln=et.getConfigs,hi=this.state.parsedContent,ci=(0,et.getComponent)("highlightCode"),Oi="response_"+(new Date).getTime();if(zt=zt||"",/^application\/octet-stream/i.test(Ot)||Yn["Content-Disposition"]&&/attachment/i.test(Yn["Content-Disposition"])||Yn["content-disposition"]&&/attachment/i.test(Yn["content-disposition"])||Yn["Content-Description"]&&/File Transfer/i.test(Yn["Content-Description"])||Yn["content-description"]&&/File Transfer/i.test(Yn["content-description"]))if("Blob"in window){var Ni=Ot||"text/html",so=At instanceof Blob?At:new Blob([At],{type:Ni}),Ki=_a.default.createObjectURL(so),eo=[Ni,zt.substr((0,c.default)(zt).call(zt,"/")+1),Ki].join(":"),gs=Yn["content-disposition"]||Yn["Content-Disposition"];if(void 0!==gs){var Ns=(0,Tn.DR)(gs);null!==Ns&&(eo=Ns)}Qe=U.default.createElement("div",null,U.default.createElement("a",wn.Z.navigator&&wn.Z.navigator.msSaveOrOpenBlob?{href:Ki,onClick:function(){return wn.Z.navigator.msSaveOrOpenBlob(so,eo)}}:{href:Ki,download:eo},"Download file"))}else Qe=U.default.createElement("pre",{className:"microlight"},"Download headers detected but your browser does not support downloading binary via XHR (Blob).");else if(/json/i.test(Ot)){var qs=null;(0,Fg.O)(At)&&(qs="json");try{Je=(0,D.default)(JSON.parse(At),null," ")}catch(Os){Je="can't parse JSON. Raw result:\n\n"+At}Qe=U.default.createElement(ci,{language:qs,downloadable:!0,fileName:"".concat(Oi,".json"),value:Je,getConfigs:Ln,canCopy:!0})}else/xml/i.test(Ot)?(Je=(0,nv.default)(At,{textNodesOnSameLine:!0,indentor:" "}),Qe=U.default.createElement(ci,{downloadable:!0,fileName:"".concat(Oi,".xml"),value:Je,getConfigs:Ln,canCopy:!0})):Qe="text/html"===(0,Fp.default)(Ot)||/text\/plain/.test(Ot)?U.default.createElement(ci,{downloadable:!0,fileName:"".concat(Oi,".html"),value:At,getConfigs:Ln,canCopy:!0}):"text/csv"===(0,Fp.default)(Ot)||/text\/csv/.test(Ot)?U.default.createElement(ci,{downloadable:!0,fileName:"".concat(Oi,".csv"),value:At,getConfigs:Ln,canCopy:!0}):/^image\//i.test(Ot)?(0,nu.default)(Ot).call(Ot,"svg")?U.default.createElement("div",null," ",At," "):U.default.createElement("img",{src:_a.default.createObjectURL(At)}):/^audio\//i.test(Ot)?U.default.createElement("pre",{className:"microlight"},U.default.createElement("audio",{controls:!0},U.default.createElement("source",{src:zt,type:Ot}))):"string"==typeof At?U.default.createElement(ci,{downloadable:!0,fileName:"".concat(Oi,".txt"),value:At,getConfigs:Ln,canCopy:!0}):At.size>0?hi?U.default.createElement("div",null,U.default.createElement("p",{className:"i"},"Unrecognized response type; displaying content as text."),U.default.createElement(ci,{downloadable:!0,fileName:"".concat(Oi,".txt"),value:hi,getConfigs:Ln,canCopy:!0})):U.default.createElement("p",{className:"i"},"Unrecognized response type; unable to display."):null;return Qe?U.default.createElement("div",null,U.default.createElement("h5",null,"Response body"),Qe):null}}]),ft}(U.default.PureComponent),wd=Mo(2691),ZA=Mo(374),cS=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(Je){var Qe;return(0,re.default)(this,ft),Qe=Kt.call(this,Je),(0,W.default)((0,Di.default)(Qe),"onChange",function(et,At,Ot){var zt=Qe.props;(0,zt.specActions.changeParamByIdentity)(zt.onChangeKey,et,At,Ot)}),(0,W.default)((0,Di.default)(Qe),"onChangeConsumesWrapper",function(et){var At=Qe.props;(0,At.specActions.changeConsumesValue)(At.onChangeKey,et)}),(0,W.default)((0,Di.default)(Qe),"toggleTab",function(et){return"parameters"===et?Qe.setState({parametersVisible:!0,callbackVisible:!1}):"callbacks"===et?Qe.setState({callbackVisible:!0,parametersVisible:!1}):void 0}),(0,W.default)((0,Di.default)(Qe),"onChangeMediaType",function(et){var At=et.value,Ot=et.pathMethod,zt=Qe.props,En=zt.specActions,Yn=zt.oas3Selectors,Ln=zt.oas3Actions,qn=Yn.hasUserEditedBody.apply(Yn,(0,wd.default)(Ot)),hi=Yn.shouldRetainRequestBodyValue.apply(Yn,(0,wd.default)(Ot));Ln.setRequestContentType({value:At,pathMethod:Ot}),Ln.initRequestBodyValidateError({pathMethod:Ot}),qn||(hi||Ln.setRequestBodyValue({value:void 0,pathMethod:Ot}),En.clearResponse.apply(En,(0,wd.default)(Ot)),En.clearRequest.apply(En,(0,wd.default)(Ot)),En.clearValidateParams(Ot))}),Qe.state={callbackVisible:!1,parametersVisible:!0},Qe}return(0,oe.default)(ft,[{key:"render",value:function(){var Je,Qe,et=this,At=this.props,Ot=At.onTryoutClick,zt=At.parameters,En=At.allowTryItOut,Yn=At.tryItOutEnabled,Ln=At.specPath,qn=At.fn,hi=At.getComponent,ci=At.getConfigs,Oi=At.specSelectors,Ni=At.specActions,so=At.pathMethod,Ki=At.oas3Actions,eo=At.oas3Selectors,gs=At.operation,Ns=hi("parameterRow"),qs=hi("TryItOutButton"),Os=hi("contentType"),ws=hi("Callbacks",!0),Ps=hi("RequestBody",!0),bs=Yn&&En,ka=Oi.isOAS3(),Ys=gs.get("requestBody"),Sa=(0,Le.default)(Je=(0,ZA.default)((0,Le.default)(zt).call(zt,function(Jo,ea){var vl,ud=ea.get("in");return null!==(vl=Jo[ud])&&void 0!==vl||(Jo[ud]=[]),Jo[ud].push(ea),Jo},{}))).call(Je,function(Jo,ea){return(0,o.default)(Jo).call(Jo,ea)},[]);return U.default.createElement("div",{className:"opblock-section"},U.default.createElement("div",{className:"opblock-section-header"},ka?U.default.createElement("div",{className:"tab-header"},U.default.createElement("div",{onClick:function(){return et.toggleTab("parameters")},className:"tab-item ".concat(this.state.parametersVisible&&"active")},U.default.createElement("h4",{className:"opblock-title"},U.default.createElement("span",null,"Parameters"))),gs.get("callbacks")?U.default.createElement("div",{onClick:function(){return et.toggleTab("callbacks")},className:"tab-item ".concat(this.state.callbackVisible&&"active")},U.default.createElement("h4",{className:"opblock-title"},U.default.createElement("span",null,"Callbacks"))):null):U.default.createElement("div",{className:"tab-header"},U.default.createElement("h4",{className:"opblock-title"},"Parameters")),En?U.default.createElement(qs,{isOAS3:Oi.isOAS3(),hasUserEditedBody:eo.hasUserEditedBody.apply(eo,(0,wd.default)(so)),enabled:Yn,onCancelClick:this.props.onCancelClick,onTryoutClick:Ot,onResetClick:function(){return Ki.setRequestBodyValue({value:void 0,pathMethod:so})}}):null),this.state.parametersVisible?U.default.createElement("div",{className:"parameters-container"},Sa.length?U.default.createElement("div",{className:"table-container"},U.default.createElement("table",{className:"parameters"},U.default.createElement("thead",null,U.default.createElement("tr",null,U.default.createElement("th",{className:"col_header parameters-col_name"},"Name"),U.default.createElement("th",{className:"col_header parameters-col_description"},"Description"))),U.default.createElement("tbody",null,(0,we.default)(Sa).call(Sa,function(Jo,ea){var vl;return U.default.createElement(Ns,{fn:qn,specPath:Ln.push(ea.toString()),getComponent:hi,getConfigs:ci,rawParam:Jo,param:Oi.parameterWithMetaByIdentity(so,Jo),key:(0,o.default)(vl="".concat(Jo.get("in"),".")).call(vl,Jo.get("name")),onChange:et.onChange,onChangeConsumes:et.onChangeConsumesWrapper,specSelectors:Oi,specActions:Ni,oas3Actions:Ki,oas3Selectors:eo,pathMethod:so,isExecute:bs})})))):U.default.createElement("div",{className:"opblock-description-wrapper"},U.default.createElement("p",null,"No parameters"))):null,this.state.callbackVisible?U.default.createElement("div",{className:"callbacks-container opblock-description-wrapper"},U.default.createElement(ws,{callbacks:(0,ht.Map)(gs.get("callbacks")),specPath:(0,Fe.default)(Ln).call(Ln,0,-1).push("callbacks")})):null,ka&&Ys&&this.state.parametersVisible&&U.default.createElement("div",{className:"opblock-section opblock-section-request-body"},U.default.createElement("div",{className:"opblock-section-header"},U.default.createElement("h4",{className:"opblock-title parameter__name ".concat(Ys.get("required")&&"required")},"Request body"),U.default.createElement("label",null,U.default.createElement(Os,{value:eo.requestContentType.apply(eo,(0,wd.default)(so)),contentTypes:Ys.get("content",(0,ht.List)()).keySeq(),onChange:function(Jo){et.onChangeMediaType({value:Jo,pathMethod:so})},className:"body-param-content-type",ariaLabel:"Request content type"}))),U.default.createElement("div",{className:"opblock-description-wrapper"},U.default.createElement(Ps,{setRetainRequestBodyValueFlag:function(Jo){return Ki.setRetainRequestBodyValueFlag({value:Jo,pathMethod:so})},userHasEditedBody:eo.hasUserEditedBody.apply(eo,(0,wd.default)(so)),specPath:(0,Fe.default)(Ln).call(Ln,0,-1).push("requestBody"),requestBody:Ys,requestBodyValue:eo.requestBodyValue.apply(eo,(0,wd.default)(so)),requestBodyInclusionSetting:eo.requestBodyInclusionSetting.apply(eo,(0,wd.default)(so)),requestBodyErrors:eo.requestBodyErrors.apply(eo,(0,wd.default)(so)),isExecute:bs,getConfigs:ci,activeExamplesKey:eo.activeExamplesMember.apply(eo,(0,o.default)(Qe=(0,wd.default)(so)).call(Qe,["requestBody","requestBody"])),updateActiveExamplesKey:function(Jo){et.props.oas3Actions.setActiveExamplesMember({name:Jo,pathMethod:et.props.pathMethod,contextType:"requestBody",contextName:"requestBody"})},onChange:function(Jo,ea){if(ea){var vl=eo.requestBodyValue.apply(eo,(0,wd.default)(so)),ud=ht.Map.isMap(vl)?vl:(0,ht.Map)();return Ki.setRequestBodyValue({pathMethod:so,value:ud.setIn(ea,Jo)})}Ki.setRequestBodyValue({value:Jo,pathMethod:so})},onChangeIncludeEmpty:function(Jo,ea){Ki.setRequestBodyInclusion({pathMethod:so,value:ea,name:Jo})},contentType:eo.requestContentType.apply(eo,(0,wd.default)(so))}))))}}]),ft}(U.Component);(0,W.default)(cS,"defaultProps",{onTryoutClick:Function.prototype,onCancelClick:Function.prototype,tryItOutEnabled:!1,allowTryItOut:!0,onChangeKey:[],specPath:[]});const jA=function(vn){return U.default.createElement("div",{className:"parameter__extension"},vn.xKey,": ",String(vn.xVal))};var dS=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"onCheckboxChange",function(zt){(0,Qe.props.onChange)(zt.target.checked)}),Qe}return(0,oe.default)(ft,[{key:"componentDidMount",value:function(){var Je=this.props,Qe=Je.isIncludedOptions;Qe.shouldDispatchInit&&(0,Je.onChange)(Qe.defaultValue)}},{key:"render",value:function(){var Je=this.props,Qe=Je.isIncluded,et=Je.isDisabled;return U.default.createElement("div",null,U.default.createElement("label",{className:(0,Ff.default)("parameter__empty_value_toggle",{disabled:et})},U.default.createElement("input",{type:"checkbox",disabled:et,checked:!et&&Qe,onChange:this.onCheckboxChange}),"Send empty value"))}}]),ft}(U.Component);(0,W.default)(dS,"defaultProps",{onChange:function(){},isIncludedOptions:{}});var pb=Mo(9069),VA=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(Je,Qe){var et;return(0,re.default)(this,ft),et=Kt.call(this,Je,Qe),(0,W.default)((0,Di.default)(et),"onChangeWrapper",function(At){var Ot=arguments.length>1&&void 0!==arguments[1]&&arguments[1],zt=et.props,En=zt.onChange,Yn=zt.rawParam;return En(Yn,""===At||At&&0===At.size?null:At,Ot)}),(0,W.default)((0,Di.default)(et),"_onExampleSelect",function(At){et.props.oas3Actions.setActiveExamplesMember({name:At,pathMethod:et.props.pathMethod,contextType:"parameters",contextName:et.getParamKey()})}),(0,W.default)((0,Di.default)(et),"onChangeIncludeEmpty",function(At){var Ot=et.props,zt=Ot.specActions,En=Ot.param,Yn=Ot.pathMethod,Ln=En.get("name"),qn=En.get("in");return zt.updateEmptyParamInclusion(Yn,Ln,qn,At)}),(0,W.default)((0,Di.default)(et),"setDefaultValue",function(){var At=et.props,Ot=At.specSelectors,zt=At.pathMethod,Yn=At.oas3Selectors,Ln=Ot.parameterWithMetaByIdentity(zt,At.rawParam)||(0,ht.Map)(),qn=(0,pb.Z)(Ln,{isOAS3:Ot.isOAS3()}).schema,hi=Ln.get("content",(0,ht.Map)()).keySeq().first(),ci=qn?(0,Tn.xi)(qn.toJS(),hi,{includeWriteOnly:!0}):null;if(Ln&&void 0===Ln.get("value")&&"body"!==Ln.get("in")){var Oi;if(Ot.isSwagger2())Oi=void 0!==Ln.get("x-example")?Ln.get("x-example"):void 0!==Ln.getIn(["schema","example"])?Ln.getIn(["schema","example"]):qn&&qn.getIn(["default"]);else if(Ot.isOAS3()){var Ni,so=Yn.activeExamplesMember.apply(Yn,(0,o.default)(Ni=(0,wd.default)(zt)).call(Ni,["parameters",et.getParamKey()]));Oi=void 0!==Ln.getIn(["examples",so,"value"])?Ln.getIn(["examples",so,"value"]):void 0!==Ln.getIn(["content",hi,"example"])?Ln.getIn(["content",hi,"example"]):void 0!==Ln.get("example")?Ln.get("example"):void 0!==(qn&&qn.get("example"))?qn&&qn.get("example"):void 0!==(qn&&qn.get("default"))?qn&&qn.get("default"):Ln.get("default")}void 0===Oi||ht.List.isList(Oi)||(Oi=(0,Tn.Pz)(Oi)),void 0!==Oi?et.onChangeWrapper(Oi):qn&&"object"===qn.get("type")&&ci&&!Ln.get("examples")&&et.onChangeWrapper(ht.List.isList(ci)?ci:(0,Tn.Pz)(ci))}}),et.setDefaultValue(),et}return(0,oe.default)(ft,[{key:"UNSAFE_componentWillReceiveProps",value:function(Je){var Qe,et=Je.specSelectors,At=Je.pathMethod,Ot=Je.rawParam,zt=et.isOAS3(),En=et.parameterWithMetaByIdentity(At,Ot)||new ht.Map;if(En=En.isEmpty()?Ot:En,zt){var Yn=(0,pb.Z)(En,{isOAS3:zt}).schema;Qe=Yn?Yn.get("enum"):void 0}else Qe=En?En.get("enum"):void 0;var Ln,qn=En?En.get("value"):void 0;void 0!==qn?Ln=qn:Ot.get("required")&&Qe&&Qe.size&&(Ln=Qe.first()),void 0!==Ln&&Ln!==qn&&this.onChangeWrapper((0,Tn.D$)(Ln)),this.setDefaultValue()}},{key:"getParamKey",value:function(){var Je,Qe=this.props.param;return Qe?(0,o.default)(Je="".concat(Qe.get("name"),"-")).call(Je,Qe.get("in")):null}},{key:"render",value:function(){var Je,Qe,et,At,Ot=this.props,zt=Ot.param,En=Ot.rawParam,Yn=Ot.getComponent,Ln=Ot.getConfigs,qn=Ot.isExecute,hi=Ot.fn,ci=Ot.onChangeConsumes,Oi=Ot.specSelectors,Ni=Ot.pathMethod,so=Ot.specPath,Ki=Ot.oas3Selectors,eo=Oi.isOAS3(),gs=Ln(),Ns=gs.showExtensions,qs=gs.showCommonExtensions;if(zt||(zt=En),!En)return null;var Os,ws,Ps,bs,ka=Yn("JsonSchemaForm"),Ys=Yn("ParamBody"),Sa=zt.get("in"),Jo="body"!==Sa?null:U.default.createElement(Ys,{getComponent:Yn,getConfigs:Ln,fn:hi,param:zt,consumes:Oi.consumesOptionsFor(Ni),consumesValue:Oi.contentTypeValues(Ni).get("requestContentType"),onChange:this.onChangeWrapper,onChangeConsumes:ci,isExecute:qn,specSelectors:Oi,pathMethod:Ni}),ea=Yn("modelExample"),vl=Yn("Markdown",!0),ud=Yn("ParameterExt"),af=Yn("ParameterIncludeEmpty"),lf=Yn("ExamplesSelectValueRetainer"),kf=Yn("Example"),ru=(0,pb.Z)(zt,{isOAS3:eo}).schema,cd=Oi.parameterWithMetaByIdentity(Ni,En)||(0,ht.Map)(),uc=ru?ru.get("format"):null,dp=ru?ru.get("type"):null,Xf=ru?ru.getIn(["items","type"]):null,L_="formData"===Sa,Gd="FormData"in wn.Z,cc=zt.get("required"),Vd=cd?cd.get("value"):"",uf=qs?(0,Tn.po)(ru):null,cf=Ns?(0,Tn.nX)(zt):null,wh=!1;return void 0!==zt&&ru&&(Os=ru.get("items")),void 0!==Os?(ws=Os.get("enum"),Ps=Os.get("default")):ru&&(ws=ru.get("enum")),ws&&ws.size&&ws.size>0&&(wh=!0),void 0!==zt&&(ru&&(Ps=ru.get("default")),void 0===Ps&&(Ps=zt.get("default")),void 0===(bs=zt.get("example"))&&(bs=zt.get("x-example"))),U.default.createElement("tr",{"data-param-name":zt.get("name"),"data-param-in":zt.get("in")},U.default.createElement("td",{className:"parameters-col_name"},U.default.createElement("div",{className:cc?"parameter__name required":"parameter__name"},zt.get("name"),cc?U.default.createElement("span",null,"\xa0*"):null),U.default.createElement("div",{className:"parameter__type"},dp,Xf&&"[".concat(Xf,"]"),uc&&U.default.createElement("span",{className:"prop-format"},"($",uc,")")),U.default.createElement("div",{className:"parameter__deprecated"},eo&&zt.get("deprecated")?"deprecated":null),U.default.createElement("div",{className:"parameter__in"},"(",zt.get("in"),")"),qs&&uf.size?(0,we.default)(Je=uf.entrySeq()).call(Je,function(xd){var Dd,Af=(0,qa.default)(xd,2),xh=Af[0],mm=Af[1];return U.default.createElement(ud,{key:(0,o.default)(Dd="".concat(xh,"-")).call(Dd,mm),xKey:xh,xVal:mm})}):null,Ns&&cf.size?(0,we.default)(Qe=cf.entrySeq()).call(Qe,function(xd){var Dd,Af=(0,qa.default)(xd,2),xh=Af[0],mm=Af[1];return U.default.createElement(ud,{key:(0,o.default)(Dd="".concat(xh,"-")).call(Dd,mm),xKey:xh,xVal:mm})}):null),U.default.createElement("td",{className:"parameters-col_description"},zt.get("description")?U.default.createElement(vl,{source:zt.get("description")}):null,!Jo&&qn||!wh?null:U.default.createElement(vl,{className:"parameter__enum",source:"<i>Available values</i> : "+(0,we.default)(ws).call(ws,function(xd){return xd}).toArray().join(", ")}),!Jo&&qn||void 0===Ps?null:U.default.createElement(vl,{className:"parameter__default",source:"<i>Default value</i> : "+Ps}),!Jo&&qn||void 0===bs?null:U.default.createElement(vl,{source:"<i>Example</i> : "+bs}),L_&&!Gd&&U.default.createElement("div",null,"Error: your browser does not support FormData"),eo&&zt.get("examples")?U.default.createElement("section",{className:"parameter-controls"},U.default.createElement(lf,{examples:zt.get("examples"),onSelect:this._onExampleSelect,updateValue:this.onChangeWrapper,getComponent:Yn,defaultToFirstExample:!0,currentKey:Ki.activeExamplesMember.apply(Ki,(0,o.default)(et=(0,wd.default)(Ni)).call(et,["parameters",this.getParamKey()])),currentUserInputValue:Vd})):null,Jo?null:U.default.createElement(ka,{fn:hi,getComponent:Yn,value:Vd,required:cc,disabled:!qn,description:zt.get("name"),onChange:this.onChangeWrapper,errors:cd.get("errors"),schema:ru}),Jo&&ru?U.default.createElement(ea,{getComponent:Yn,specPath:so.push("schema"),getConfigs:Ln,isExecute:qn,specSelectors:Oi,schema:ru,example:Jo,includeWriteOnly:!0}):null,!Jo&&qn&&zt.get("allowEmptyValue")?U.default.createElement(af,{onChange:this.onChangeIncludeEmpty,isIncluded:Oi.parameterInclusionSettingFor(Ni,zt.get("name"),zt.get("in")),isDisabled:!(0,Tn.O2)(Vd)}):null,eo&&zt.get("examples")?U.default.createElement(kf,{example:zt.getIn(["examples",Ki.activeExamplesMember.apply(Ki,(0,o.default)(At=(0,wd.default)(Ni)).call(At,["parameters",this.getParamKey()]))]),getComponent:Yn,getConfigs:Ln}):null))}}]),ft}(U.Component),zA=Mo(6235),WA=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"handleValidateParameters",function(){var zt=Qe.props,En=zt.specSelectors,Ln=zt.path,qn=zt.method;return zt.specActions.validateParams([Ln,qn]),En.validateBeforeExecute([Ln,qn])}),(0,W.default)((0,Di.default)(Qe),"handleValidateRequestBody",function(){var zt=Qe.props,En=zt.path,Yn=zt.method,Ln=zt.specSelectors,qn=zt.oas3Selectors,hi=zt.oas3Actions,ci={missingBodyValue:!1,missingRequiredKeys:[]};hi.clearRequestBodyValidateError({path:En,method:Yn});var Oi=Ln.getOAS3RequiredRequestBodyContentType([En,Yn]),Ni=qn.requestBodyValue(En,Yn),so=qn.validateBeforeExecute([En,Yn]),Ki=qn.requestContentType(En,Yn);if(!so)return ci.missingBodyValue=!0,hi.setRequestBodyValidateError({path:En,method:Yn,validationErrors:ci}),!1;if(!Oi)return!0;var eo=qn.validateShallowRequired({oas3RequiredRequestBodyContentType:Oi,oas3RequestContentType:Ki,oas3RequestBodyValue:Ni});return!eo||eo.length<1||((0,Ru.default)(eo).call(eo,function(gs){ci.missingRequiredKeys.push(gs)}),hi.setRequestBodyValidateError({path:En,method:Yn,validationErrors:ci}),!1)}),(0,W.default)((0,Di.default)(Qe),"handleValidationResultPass",function(){var zt=Qe.props,En=zt.specActions,Yn=zt.operation,Ln=zt.path,qn=zt.method;Qe.props.onExecute&&Qe.props.onExecute(),En.execute({operation:Yn,path:Ln,method:qn})}),(0,W.default)((0,Di.default)(Qe),"handleValidationResultFail",function(){var zt=Qe.props,En=zt.specActions,Yn=zt.path,Ln=zt.method;En.clearValidateParams([Yn,Ln]),(0,zA.default)(function(){En.validateParams([Yn,Ln])},40)}),(0,W.default)((0,Di.default)(Qe),"handleValidationResult",function(zt){zt?Qe.handleValidationResultPass():Qe.handleValidationResultFail()}),(0,W.default)((0,Di.default)(Qe),"onClick",function(){var zt=Qe.handleValidateParameters(),En=Qe.handleValidateRequestBody();Qe.handleValidationResult(zt&&En)}),(0,W.default)((0,Di.default)(Qe),"onChangeProducesWrapper",function(zt){return Qe.props.specActions.changeProducesValue([Qe.props.path,Qe.props.method],zt)}),Qe}return(0,oe.default)(ft,[{key:"render",value:function(){return U.default.createElement("button",{className:"btn execute opblock-control__btn",onClick:this.onClick,disabled:this.props.disabled},"Execute")}}]),ft}(U.Component),za=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je,Qe=this.props,et=Qe.headers,At=Qe.getComponent,Ot=At("Property"),zt=At("Markdown",!0);return et&&et.size?U.default.createElement("div",{className:"headers-wrapper"},U.default.createElement("h4",{className:"headers__title"},"Headers:"),U.default.createElement("table",{className:"headers"},U.default.createElement("thead",null,U.default.createElement("tr",{className:"header-row"},U.default.createElement("th",{className:"header-col"},"Name"),U.default.createElement("th",{className:"header-col"},"Description"),U.default.createElement("th",{className:"header-col"},"Type"))),U.default.createElement("tbody",null,(0,we.default)(Je=et.entrySeq()).call(Je,function(En){var Yn=(0,qa.default)(En,2),Ln=Yn[0],qn=Yn[1];if(!ht.default.Map.isMap(qn))return null;var hi=qn.get("description"),ci=qn.getIn(["schema"])?qn.getIn(["schema","type"]):qn.getIn(["type"]),Oi=qn.getIn(["schema","example"]);return U.default.createElement("tr",{key:Ln},U.default.createElement("td",{className:"header-col"},Ln),U.default.createElement("td",{className:"header-col"},hi?U.default.createElement(zt,{source:hi}):null),U.default.createElement("td",{className:"header-col"},ci," ",Oi?U.default.createElement(Ot,{propKey:"Example",propVal:Oi,propClass:"header-example"}):null))}).toArray()))):null}}]),ft}(U.default.Component),ku=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.editorActions,et=Je.errSelectors,At=Je.layoutSelectors,Ot=Je.layoutActions,zt=(0,Je.getComponent)("Collapse");if(Qe&&Qe.jumpToLine)var En=Qe.jumpToLine;var Yn=et.allErrors(),Ln=(0,g.default)(Yn).call(Yn,function(ci){return"thrown"===ci.get("type")||"error"===ci.get("level")});if(!Ln||Ln.count()<1)return null;var qn=At.isShown(["errorPane"],!0),hi=Ln.sortBy(function(ci){return ci.get("line")});return U.default.createElement("pre",{className:"errors-wrapper"},U.default.createElement("hgroup",{className:"error"},U.default.createElement("h4",{className:"errors__title"},"Errors"),U.default.createElement("button",{className:"btn errors__clear-btn",onClick:function(){return Ot.show(["errorPane"],!qn)}},qn?"Hide":"Show")),U.default.createElement(zt,{isOpened:qn,animated:!0},U.default.createElement("div",{className:"errors"},(0,we.default)(hi).call(hi,function(ci,Oi){var Ni=ci.get("type");return"thrown"===Ni||"auth"===Ni?U.default.createElement(ld,{key:Oi,error:ci.get("error")||ci,jumpToLine:En}):"spec"===Ni?U.default.createElement(A0,{key:Oi,error:ci,jumpToLine:En}):void 0}))))}}]),ft}(U.default.Component),ld=function(vn){var Kt=vn.error,ft=vn.jumpToLine;if(!Kt)return null;var Je=Kt.get("line");return U.default.createElement("div",{className:"error-wrapper"},Kt?U.default.createElement("div",null,U.default.createElement("h4",null,Kt.get("source")&&Kt.get("level")?n1(Kt.get("source"))+" "+Kt.get("level"):"",Kt.get("path")?U.default.createElement("small",null," at ",Kt.get("path")):null),U.default.createElement("span",{className:"message thrown"},Kt.get("message")),U.default.createElement("div",{className:"error-line"},Je&&ft?U.default.createElement("a",{onClick:(0,me.default)(ft).call(ft,null,Je)},"Jump to line ",Je):null)):null)},A0=function(vn){var Kt=vn.error,ft=vn.jumpToLine,Je=null;return Kt.get("path")?Je=ht.List.isList(Kt.get("path"))?U.default.createElement("small",null,"at ",Kt.get("path").join(".")):U.default.createElement("small",null,"at ",Kt.get("path")):Kt.get("line")&&!ft&&(Je=U.default.createElement("small",null,"on line ",Kt.get("line"))),U.default.createElement("div",{className:"error-wrapper"},Kt?U.default.createElement("div",null,U.default.createElement("h4",null,n1(Kt.get("source"))+" "+Kt.get("level"),"\xa0",Je),U.default.createElement("span",{className:"message"},Kt.get("message")),U.default.createElement("div",{className:"error-line"},ft?U.default.createElement("a",{onClick:(0,me.default)(ft).call(ft,null,Kt.get("line"))},"Jump to line ",Kt.get("line")):null)):null)};function n1(vn){var Kt;return(0,we.default)(Kt=(vn||"").split(" ")).call(Kt,function(ft){return ft[0].toUpperCase()+(0,Fe.default)(ft).call(ft,1)}).join(" ")}ld.defaultProps={jumpToLine:null};var O0=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"onChangeWrapper",function(zt){return Qe.props.onChange(zt.target.value)}),Qe}return(0,oe.default)(ft,[{key:"componentDidMount",value:function(){this.props.contentTypes&&this.props.onChange(this.props.contentTypes.first())}},{key:"UNSAFE_componentWillReceiveProps",value:function(Je){var Qe;Je.contentTypes&&Je.contentTypes.size&&((0,nu.default)(Qe=Je.contentTypes).call(Qe,Je.value)||Je.onChange(Je.contentTypes.first()))}},{key:"render",value:function(){var Je=this.props,Ot=Je.contentTypes;return Ot&&Ot.size?U.default.createElement("div",{className:"content-type-wrapper "+(Je.className||"")},U.default.createElement("select",{"aria-controls":Je.ariaControls,"aria-label":Je.ariaLabel,className:"content-type",id:Je.controlId,onChange:this.onChangeWrapper,value:Je.value||""},(0,we.default)(Ot).call(Ot,function(Yn){return U.default.createElement("option",{key:Yn,value:Yn},Yn)}).toArray())):null}}]),ft}(U.default.Component);(0,W.default)(O0,"defaultProps",{onChange:function(){},value:null,contentTypes:(0,ht.fromJS)(["application/json"])});var kp=Mo(863),r1=Mo(302),e7=Mo(5942),t7=["fullscreen","full"],n7=["hide","keepContents","mobile","tablet","desktop","large"];function fS(){for(var vn,Kt=arguments.length,ft=new Array(Kt),Je=0;Je<Kt;Je++)ft[Je]=arguments[Je];return(0,e7.default)(vn=(0,g.default)(ft).call(ft,function(Qe){return!!Qe}).join(" ")).call(vn)}var r7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.fullscreen,et=Je.full,At=(0,r1.default)(Je,t7);return U.default.createElement("section",Qe?At:(0,kp.default)({},At,{className:fS(At.className,"swagger-container"+(et?"-full":""))}))}}]),ft}(U.default.Component),sR={mobile:"",tablet:"-tablet",desktop:"-desktop",large:"-hd"},i7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je,Qe=this.props,et=Qe.hide,At=Qe.keepContents,Ot=(0,r1.default)(Qe,n7);if(et&&!At)return U.default.createElement("span",null);var zt=[];for(var En in sR)if(Object.prototype.hasOwnProperty.call(sR,En)){var Yn=sR[En];if(En in this.props){var Ln=this.props[En];if(Ln<1){zt.push("none"+Yn);continue}zt.push("block"+Yn),zt.push("col-"+Ln+Yn)}}et&&zt.push("hidden");var qn=fS.apply(void 0,(0,o.default)(Je=[Ot.className]).call(Je,zt));return U.default.createElement("section",(0,kp.default)({},Ot,{className:qn}))}}]),ft}(U.default.Component),o7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){return U.default.createElement("div",(0,kp.default)({},this.props,{className:fS(this.props.className,"wrapper")}))}}]),ft}(U.default.Component),_P=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){return U.default.createElement("button",(0,kp.default)({},this.props,{className:fS(this.props.className,"button")}))}}]),ft}(U.default.Component);(0,W.default)(_P,"defaultProps",{className:""});var s7=function(vn){return U.default.createElement("textarea",vn)},a7=function(vn){return U.default.createElement("input",vn)},gP=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(Je,Qe){var et;return(0,re.default)(this,ft),et=Kt.call(this,Je,Qe),(0,W.default)((0,Di.default)(et),"onChange",function(Ot){var zt,En,Yn=et.props,Ln=Yn.onChange,qn=Yn.multiple,hi=(0,Fe.default)([]).call(Ot.target.options);zt=qn?(0,we.default)(En=(0,g.default)(hi).call(hi,function(ci){return ci.selected})).call(En,function(ci){return ci.value}):Ot.target.value,et.setState({value:zt}),Ln&&Ln(zt)}),et.state={value:Je.value?Je.value:Je.multiple?[""]:""},et}return(0,oe.default)(ft,[{key:"UNSAFE_componentWillReceiveProps",value:function(Je){Je.value!==this.props.value&&this.setState({value:Je.value})}},{key:"render",value:function(){var Je,Qe,et=this.props,At=et.allowedValues,Ot=et.multiple,zt=et.allowEmptyValue,En=et.disabled,Yn=(null===(Je=this.state.value)||void 0===Je||null===(Qe=Je.toJS)||void 0===Qe?void 0:Qe.call(Je))||this.state.value;return U.default.createElement("select",{className:this.props.className,multiple:Ot,value:Yn,onChange:this.onChange,disabled:En},zt?U.default.createElement("option",{value:""},"--"):null,(0,we.default)(At).call(At,function(Ln,qn){return U.default.createElement("option",{key:qn,value:String(Ln)},String(Ln))}))}}]),ft}(U.default.Component);(0,W.default)(gP,"defaultProps",{multiple:!1,allowEmptyValue:!0});var mP=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){return U.default.createElement("a",(0,kp.default)({},this.props,{rel:"noopener noreferrer",className:fS(this.props.className,"link")}))}}]),ft}(U.default.Component),vP=function(vn){return U.default.createElement("div",{className:"no-margin"}," ",vn.children," ")},yP=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"renderNotAnimated",value:function(){return this.props.isOpened?U.default.createElement(vP,null,this.props.children):U.default.createElement("noscript",null)}},{key:"render",value:function(){var Je=this.props,At=Je.children;return Je.animated?U.default.createElement(vP,null,At=Je.isOpened?At:null):this.renderNotAnimated()}}]),ft}(U.default.Component);(0,W.default)(yP,"defaultProps",{isOpened:!1,animated:!1});var l7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe,et;(0,re.default)(this,ft);for(var At=arguments.length,Ot=new Array(At),zt=0;zt<At;zt++)Ot[zt]=arguments[zt];return(et=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,Ot))).setTagShown=(0,me.default)(Qe=et._setTagShown).call(Qe,(0,Di.default)(et)),et}return(0,oe.default)(ft,[{key:"_setTagShown",value:function(Je,Qe){this.props.layoutActions.show(Je,Qe)}},{key:"showOp",value:function(Je,Qe){this.props.layoutActions.show(Je,Qe)}},{key:"render",value:function(){var Je=this.props,et=Je.layoutSelectors,At=Je.layoutActions,Ot=Je.getComponent,zt=Je.specSelectors.taggedOperations(),En=Ot("Collapse");return U.default.createElement("div",null,U.default.createElement("h4",{className:"overview-title"},"Overview"),(0,we.default)(zt).call(zt,function(Yn,Ln){var qn=Yn.get("operations"),hi=["overview-tags",Ln],ci=et.isShown(hi,!0);return U.default.createElement("div",{key:"overview-"+Ln},U.default.createElement("h4",{onClick:function(){return At.show(hi,!ci)},className:"link overview-tag"}," ",ci?"-":"+",Ln),U.default.createElement(En,{isOpened:ci,animated:!0},(0,we.default)(qn).call(qn,function(Oi){var Ni=Oi.toObject(),so=Ni.path,Ki=Ni.method,eo=Ni.id,gs="operations",Ns=eo,qs=et.isShown([gs,Ns]);return U.default.createElement(u7,{key:eo,path:so,method:Ki,id:so+"-"+Ki,shown:qs,showOpId:Ns,showOpIdPrefix:gs,href:"#operation-".concat(Ns),onClick:At.show})}).toArray()))}).toArray(),zt.size<1&&U.default.createElement("h3",null," No operations defined in spec! "))}}]),ft}(U.default.Component),u7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(Je){var Qe,et;return(0,re.default)(this,ft),(et=Kt.call(this,Je)).onClick=(0,me.default)(Qe=et._onClick).call(Qe,(0,Di.default)(et)),et}return(0,oe.default)(ft,[{key:"_onClick",value:function(){var Je=this.props;(0,Je.onClick)([Je.showOpIdPrefix,Je.showOpId],!Je.shown)}},{key:"render",value:function(){var Je=this.props,Qe=Je.id,et=Je.method;return U.default.createElement(mP,{href:Je.href,onClick:this.onClick,className:"block opblock-link ".concat(Je.shown?"shown":"")},U.default.createElement("div",null,U.default.createElement("small",{className:"bold-label-".concat(et)},et.toUpperCase()),U.default.createElement("span",{className:"bold-label"},Qe)))}}]),ft}(U.default.Component),c7=["value","defaultValue","initialValue"],d7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"componentDidMount",value:function(){this.props.initialValue&&(this.inputRef.value=this.props.initialValue)}},{key:"render",value:function(){var Je=this,et=(0,r1.default)(this.props,c7);return U.default.createElement("input",(0,kp.default)({},et,{ref:function(At){return Je.inputRef=At}}))}}]),ft}(U.default.Component),f7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props;return U.default.createElement("pre",{className:"base-url"},"[ Base URL: ",Je.host,Je.basePath," ]")}}]),ft}(U.default.Component),p7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.data,et=Je.getComponent,At=Je.selectedServer,Ot=Je.url,zt=Qe.get("name")||"the developer",En=Ii(Qe.get("url"),Ot,{selectedServer:At}),Yn=Qe.get("email"),Ln=et("Link");return U.default.createElement("div",{className:"info__contact"},En&&U.default.createElement("div",null,U.default.createElement(Ln,{href:(0,Tn.Nm)(En),target:"_blank"},zt," - Website")),Yn&&U.default.createElement(Ln,{href:(0,Tn.Nm)("mailto:".concat(Yn))},En?"Send email to ".concat(zt):"Contact ".concat(zt)))}}]),ft}(U.default.Component),h7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.license,At=Je.selectedServer,Ot=Je.url,zt=(0,Je.getComponent)("Link"),En=Qe.get("name")||"License",Yn=Ii(Qe.get("url"),Ot,{selectedServer:At});return U.default.createElement("div",{className:"info__license"},Yn?U.default.createElement(zt,{target:"_blank",href:(0,Tn.Nm)(Yn)},En):U.default.createElement("span",null,En))}}]),ft}(U.default.Component),_7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.url,et=(0,Je.getComponent)("Link");return U.default.createElement(et,{target:"_blank",href:(0,Tn.Nm)(Qe)},U.default.createElement("span",{className:"url"}," ",Qe))}}]),ft}(U.default.PureComponent),g7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.info,et=Je.url,At=Je.host,Ot=Je.basePath,zt=Je.getComponent,En=Je.externalDocs,Yn=Je.selectedServer,Ln=Je.url,qn=Qe.get("version"),hi=Qe.get("description"),ci=Qe.get("title"),Oi=Ii(Qe.get("termsOfService"),Ln,{selectedServer:Yn}),Ni=Qe.get("contact"),so=Qe.get("license"),Ki=Ii(En&&En.get("url"),Ln,{selectedServer:Yn}),eo=En&&En.get("description"),gs=zt("Markdown",!0),Ns=zt("Link"),qs=zt("VersionStamp"),Os=zt("InfoUrl"),ws=zt("InfoBasePath");return U.default.createElement("div",{className:"info"},U.default.createElement("hgroup",{className:"main"},U.default.createElement("h2",{className:"title"},ci,qn&&U.default.createElement(qs,{version:qn})),At||Ot?U.default.createElement(ws,{host:At,basePath:Ot}):null,et&&U.default.createElement(Os,{getComponent:zt,url:et})),U.default.createElement("div",{className:"description"},U.default.createElement(gs,{source:hi})),Oi&&U.default.createElement("div",{className:"info__tos"},U.default.createElement(Ns,{target:"_blank",href:(0,Tn.Nm)(Oi)},"Terms of service")),Ni&&Ni.size?U.default.createElement(p7,{getComponent:zt,data:Ni,selectedServer:Yn,url:et}):null,so&&so.size?U.default.createElement(h7,{getComponent:zt,license:so,selectedServer:Yn,url:et}):null,Ki?U.default.createElement(Ns,{className:"info__extdocs",target:"_blank",href:(0,Tn.Nm)(Ki)},eo||Ki):null)}}]),ft}(U.default.Component),m7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.specSelectors,et=Je.getComponent,At=Je.oas3Selectors,Ot=Qe.info(),zt=Qe.url(),En=Qe.basePath(),Yn=Qe.host(),Ln=Qe.externalDocs(),qn=At.selectedServer(),hi=et("info");return U.default.createElement("div",null,Ot&&Ot.count()?U.default.createElement(hi,{info:Ot,url:zt,host:Yn,basePath:En,externalDocs:Ln,getComponent:et,selectedServer:qn}):null)}}]),ft}(U.default.Component),v7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){return null}}]),ft}(U.default.Component),y7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){return U.default.createElement("div",{className:"footer"})}}]),ft}(U.default.Component),b7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"onFilterChange",function(zt){Qe.props.layoutActions.updateFilter(zt.target.value)}),Qe}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.specSelectors,et=Je.layoutSelectors,At=(0,Je.getComponent)("Col"),Ot="loading"===Qe.loadingStatus(),zt="failed"===Qe.loadingStatus(),En=et.currentFilter(),Yn=["operation-filter-input"];return zt&&Yn.push("failed"),Ot&&Yn.push("loading"),U.default.createElement("div",null,null===En||!1===En||"false"===En?null:U.default.createElement("div",{className:"filter-container"},U.default.createElement(At,{className:"filter wrapper",mobile:12},U.default.createElement("input",{className:Yn.join(" "),placeholder:"Filter by tag",type:"text",onChange:this.onFilterChange,value:!0===En||"true"===En?"":En,disabled:Ot}))))}}]),ft}(U.default.Component),aR=Function.prototype,bP=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(Je,Qe){var et;return(0,re.default)(this,ft),et=Kt.call(this,Je,Qe),(0,W.default)((0,Di.default)(et),"updateValues",function(At){var Ot=At.param,zt=At.isExecute,En=At.consumesValue,Yn=void 0===En?"":En,Ln=/xml/i.test(Yn),qn=/json/i.test(Yn),hi=Ot.get(Ln?"value_xml":"value");if(void 0!==hi){var ci=!hi&&qn?"{}":hi;et.setState({value:ci}),et.onChange(ci,{isXml:Ln,isEditBox:zt})}else Ln?et.onChange(et.sample("xml"),{isXml:Ln,isEditBox:zt}):et.onChange(et.sample(),{isEditBox:zt})}),(0,W.default)((0,Di.default)(et),"sample",function(At){var Ot=et.props,En=(0,Ot.fn.inferSchema)(Ot.param.toJS());return(0,Tn.xi)(En,At,{includeWriteOnly:!0})}),(0,W.default)((0,Di.default)(et),"onChange",function(At,Ot){var En=Ot.isXml;et.setState({value:At,isEditBox:Ot.isEditBox}),et._onChange(At,En)}),(0,W.default)((0,Di.default)(et),"_onChange",function(At,Ot){(et.props.onChange||aR)(At,Ot)}),(0,W.default)((0,Di.default)(et),"handleOnChange",function(At){var zt=/xml/i.test(et.props.consumesValue);et.onChange(At.target.value,{isXml:zt,isEditBox:et.state.isEditBox})}),(0,W.default)((0,Di.default)(et),"toggleIsEditBox",function(){return et.setState(function(At){return{isEditBox:!At.isEditBox}})}),et.state={isEditBox:!1,value:""},et}return(0,oe.default)(ft,[{key:"componentDidMount",value:function(){this.updateValues.call(this,this.props)}},{key:"UNSAFE_componentWillReceiveProps",value:function(Je){this.updateValues.call(this,Je)}},{key:"render",value:function(){var Je=this.props,Qe=Je.onChangeConsumes,et=Je.param,At=Je.isExecute,Ot=Je.specSelectors,zt=Je.pathMethod,En=Je.getConfigs,Yn=Je.getComponent,Ln=Yn("Button"),qn=Yn("TextArea"),hi=Yn("highlightCode"),ci=Yn("contentType"),Oi=(Ot?Ot.parameterWithMetaByIdentity(zt,et):et).get("errors",(0,ht.List)()),Ni=Ot.contentTypeValues(zt).get("requestContentType"),so=this.props.consumes&&this.props.consumes.size?this.props.consumes:ft.defaultProp.consumes,Ki=this.state,eo=Ki.value,gs=Ki.isEditBox,Ns=null;return(0,Fg.O)(eo)&&(Ns="json"),U.default.createElement("div",{className:"body-param","data-param-name":et.get("name"),"data-param-in":et.get("in")},gs&&At?U.default.createElement(qn,{className:"body-param__text"+(Oi.count()?" invalid":""),value:eo,onChange:this.handleOnChange}):eo&&U.default.createElement(hi,{className:"body-param__example",language:Ns,getConfigs:En,value:eo}),U.default.createElement("div",{className:"body-param-options"},At?U.default.createElement("div",{className:"body-param-edit"},U.default.createElement(Ln,{className:gs?"btn cancel body-param__example-edit":"btn edit body-param__example-edit",onClick:this.toggleIsEditBox},gs?"Cancel":"Edit")):null,U.default.createElement("label",{htmlFor:""},U.default.createElement("span",null,"Parameter content type"),U.default.createElement(ci,{value:Ni,contentTypes:so,onChange:Qe,className:"body-param-content-type",ariaLabel:"Parameter content type"}))))}}]),ft}(U.PureComponent);(0,W.default)(bP,"defaultProp",{consumes:(0,ht.fromJS)(["application/json"]),param:(0,ht.fromJS)({}),onChange:aR,onChangeConsumes:aR});var E7=Mo(4624),T7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,et=Je.getConfigs,At=(0,E7.requestSnippetGenerator_curl_bash)(Je.request),Ot=et(),zt=(0,Wl.default)(Ot,"syntaxHighlight.activated")?U.default.createElement(Xp.d3,{language:"bash",className:"curl microlight",style:(0,Xp.C2)((0,Wl.default)(Ot,"syntaxHighlight.theme"))},At):U.default.createElement("textarea",{readOnly:!0,className:"curl",value:At});return U.default.createElement("div",{className:"curl-command"},U.default.createElement("h4",null,"Curl"),U.default.createElement("div",{className:"copy-to-clipboard"},U.default.createElement(Kp.CopyToClipboard,{text:At},U.default.createElement("button",null))),U.default.createElement("div",null,zt))}}]),ft}(U.default.Component),S7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"onChange",function(zt){Qe.setScheme(zt.target.value)}),(0,W.default)((0,Di.default)(Qe),"setScheme",function(zt){var En=Qe.props;En.specActions.setScheme(zt,En.path,En.method)}),Qe}return(0,oe.default)(ft,[{key:"UNSAFE_componentWillMount",value:function(){this.setScheme(this.props.schemes.first())}},{key:"UNSAFE_componentWillReceiveProps",value:function(Je){var Qe;this.props.currentScheme&&(0,nu.default)(Qe=Je.schemes).call(Qe,this.props.currentScheme)||this.setScheme(Je.schemes.first())}},{key:"render",value:function(){var Je,Qe=this.props,et=Qe.schemes,At=Qe.currentScheme;return U.default.createElement("label",{htmlFor:"schemes"},U.default.createElement("span",{className:"schemes-title"},"Schemes"),U.default.createElement("select",{onChange:this.onChange,value:At},(0,we.default)(Je=et.valueSeq()).call(Je,function(Ot){return U.default.createElement("option",{value:Ot,key:Ot},Ot)}).toArray()))}}]),ft}(U.default.Component),C7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.specActions,et=Je.specSelectors,At=Je.getComponent,Ot=et.operationScheme(),zt=et.schemes(),En=At("schemes");return zt&&zt.size?U.default.createElement(En,{currentScheme:Ot,schemes:zt,specActions:Qe}):null}}]),ft}(U.default.Component),EP=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(Je,Qe){var et;(0,re.default)(this,ft),et=Kt.call(this,Je,Qe),(0,W.default)((0,Di.default)(et),"toggleCollapsed",function(){et.props.onToggle&&et.props.onToggle(et.props.modelName,!et.state.expanded),et.setState({expanded:!et.state.expanded})}),(0,W.default)((0,Di.default)(et),"onLoad",function(En){if(En&&et.props.layoutSelectors){var Yn=et.props.layoutSelectors.getScrollToKey();ht.default.is(Yn,et.props.specPath)&&et.toggleCollapsed(),et.props.layoutActions.readyToScroll(et.props.specPath,En.parentElement)}});var At=et.props;return et.state={expanded:At.expanded,collapsedContent:At.collapsedContent||ft.defaultProps.collapsedContent},et}return(0,oe.default)(ft,[{key:"componentDidMount",value:function(){var Je=this.props,et=Je.expanded;Je.hideSelfOnExpand&&et&&this.props.onToggle(Je.modelName,et)}},{key:"UNSAFE_componentWillReceiveProps",value:function(Je){this.props.expanded!==Je.expanded&&this.setState({expanded:Je.expanded})}},{key:"render",value:function(){var Je=this.props,Qe=Je.title,et=Je.classes;return this.state.expanded&&this.props.hideSelfOnExpand?U.default.createElement("span",{className:et||""},this.props.children):U.default.createElement("span",{className:et||"",ref:this.onLoad},U.default.createElement("button",{"aria-expanded":this.state.expanded,className:"model-box-control",onClick:this.toggleCollapsed},Qe&&U.default.createElement("span",{className:"pointer"},Qe),U.default.createElement("span",{className:"model-toggle"+(this.state.expanded?"":" collapsed")}),!this.state.expanded&&U.default.createElement("span",null,this.state.collapsedContent)),this.state.expanded&&this.props.children)}}]),ft}(U.Component);(0,W.default)(EP,"defaultProps",{collapsedContent:"{...}",expanded:!1,title:null,onToggle:function(){},hideSelfOnExpand:!1,specPath:ht.default.List([])});var M7=Mo(1798),JA=Mo.n(M7),A7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(Je,Qe){var et;(0,re.default)(this,ft),et=Kt.call(this,Je,Qe),(0,W.default)((0,Di.default)(et),"activeTab",function(Ln){et.setState({activeTab:Ln.target.dataset.name})});var At=et.props,zt=At.isExecute,En=(0,At.getConfigs)().defaultModelRendering,Yn=En;return"example"!==En&&"model"!==En&&(Yn="example"),zt&&(Yn="example"),et.state={activeTab:Yn},et}return(0,oe.default)(ft,[{key:"UNSAFE_componentWillReceiveProps",value:function(Je){Je.isExecute&&!this.props.isExecute&&this.props.example&&this.setState({activeTab:"example"})}},{key:"render",value:function(){var Je=this.props,Qe=Je.getComponent,et=Je.specSelectors,At=Je.schema,Ot=Je.example,zt=Je.isExecute,En=Je.getConfigs,Yn=Je.specPath,Ln=Je.includeReadOnly,qn=Je.includeWriteOnly,hi=En().defaultModelExpandDepth,ci=Qe("ModelWrapper"),Oi=Qe("highlightCode"),Ni=JA()(5).toString("base64"),so=JA()(5).toString("base64"),Ki=JA()(5).toString("base64"),eo=JA()(5).toString("base64"),gs=et.isOAS3();return U.default.createElement("div",{className:"model-example"},U.default.createElement("ul",{className:"tab",role:"tablist"},U.default.createElement("li",{className:(0,Ff.default)("tabitem",{active:"example"===this.state.activeTab}),role:"presentation"},U.default.createElement("button",{"aria-controls":so,"aria-selected":"example"===this.state.activeTab,className:"tablinks","data-name":"example",id:Ni,onClick:this.activeTab,role:"tab"},zt?"Edit Value":"Example Value")),At&&U.default.createElement("li",{className:(0,Ff.default)("tabitem",{active:"model"===this.state.activeTab}),role:"presentation"},U.default.createElement("button",{"aria-controls":eo,"aria-selected":"model"===this.state.activeTab,className:(0,Ff.default)("tablinks",{inactive:zt}),"data-name":"model",id:Ki,onClick:this.activeTab,role:"tab"},gs?"Schema":"Model"))),"example"===this.state.activeTab&&U.default.createElement("div",{"aria-hidden":"example"!==this.state.activeTab,"aria-labelledby":Ni,"data-name":"examplePanel",id:so,role:"tabpanel",tabIndex:"0"},Ot||U.default.createElement(Oi,{value:"(no example available)",getConfigs:En})),"model"===this.state.activeTab&&U.default.createElement("div",{"aria-hidden":"example"===this.state.activeTab,"aria-labelledby":Ki,"data-name":"modelPanel",id:eo,role:"tabpanel",tabIndex:"0"},U.default.createElement(ci,{schema:At,getComponent:Qe,getConfigs:En,specSelectors:et,expandDepth:hi,specPath:Yn,includeReadOnly:Ln,includeWriteOnly:qn})))}}]),ft}(U.default.Component),O7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"onToggle",function(zt,En){Qe.props.layoutActions&&Qe.props.layoutActions.show(Qe.props.fullPath,En)}),Qe}return(0,oe.default)(ft,[{key:"render",value:function(){var Je,Qe=this.props,At=Qe.getConfigs,Ot=(0,Qe.getComponent)("Model");return this.props.layoutSelectors&&(Je=this.props.layoutSelectors.isShown(this.props.fullPath)),U.default.createElement("div",{className:"model-box"},U.default.createElement(Ot,(0,kp.default)({},this.props,{getConfigs:At,expanded:Je,depth:1,onToggle:this.onToggle,expandDepth:this.props.expandDepth||0})))}}]),ft}(U.Component),w7=Mo(1543),x7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"getSchemaBasePath",function(){return Qe.props.specSelectors.isOAS3()?["components","schemas"]:["definitions"]}),(0,W.default)((0,Di.default)(Qe),"getCollapsedContent",function(){return" "}),(0,W.default)((0,Di.default)(Qe),"handleToggle",function(zt,En){var Yn,Ln;Qe.props.layoutActions.show((0,o.default)(Yn=[]).call(Yn,(0,wd.default)(Qe.getSchemaBasePath()),[zt]),En),En&&Qe.props.specActions.requestResolvedSubtree((0,o.default)(Ln=[]).call(Ln,(0,wd.default)(Qe.getSchemaBasePath()),[zt]))}),(0,W.default)((0,Di.default)(Qe),"onLoadModels",function(zt){zt&&Qe.props.layoutActions.readyToScroll(Qe.getSchemaBasePath(),zt)}),(0,W.default)((0,Di.default)(Qe),"onLoadModel",function(zt){if(zt){var En,Yn=zt.getAttribute("data-name");Qe.props.layoutActions.readyToScroll((0,o.default)(En=[]).call(En,(0,wd.default)(Qe.getSchemaBasePath()),[Yn]),zt)}}),Qe}return(0,oe.default)(ft,[{key:"render",value:function(){var Je,Qe=this,et=this.props,At=et.specSelectors,Ot=et.getComponent,zt=et.layoutSelectors,En=et.layoutActions,Yn=et.getConfigs,Ln=At.definitions(),qn=Yn(),hi=qn.docExpansion,ci=qn.defaultModelsExpandDepth;if(!Ln.size||ci<0)return null;var Oi=this.getSchemaBasePath(),Ni=zt.isShown(Oi,ci>0&&"none"!==hi),so=At.isOAS3(),Ki=Ot("ModelWrapper"),eo=Ot("Collapse"),gs=Ot("ModelCollapse"),Ns=Ot("JumpToPath",!0);return U.default.createElement("section",{className:Ni?"models is-open":"models",ref:this.onLoadModels},U.default.createElement("h4",null,U.default.createElement("button",{"aria-expanded":Ni,className:"models-control",onClick:function(){return En.show(Oi,!Ni)}},U.default.createElement("span",null,so?"Schemas":"Models"),U.default.createElement("svg",{width:"20",height:"20","aria-hidden":"true",focusable:"false"},U.default.createElement("use",{xlinkHref:Ni?"#large-arrow-up":"#large-arrow-down"})))),U.default.createElement(eo,{isOpened:Ni},(0,we.default)(Je=Ln.entrySeq()).call(Je,function(qs){var Os,ws=(0,qa.default)(qs,1)[0],Ps=(0,o.default)(Os=[]).call(Os,(0,wd.default)(Oi),[ws]),bs=ht.default.List(Ps),ka=At.specResolvedSubtree(Ps),Ys=At.specJson().getIn(Ps),Sa=ht.Map.isMap(ka)?ka:ht.default.Map(),Jo=ht.Map.isMap(Ys)?Ys:ht.default.Map(),ea=Sa.get("title")||Jo.get("title")||ws,vl=zt.isShown(Ps,!1);vl&&0===Sa.size&&Jo.size>0&&Qe.props.specActions.requestResolvedSubtree(Ps);var ud=U.default.createElement(Ki,{name:ws,expandDepth:ci,schema:Sa||ht.default.Map(),displayName:ea,fullPath:Ps,specPath:bs,getComponent:Ot,specSelectors:At,getConfigs:Yn,layoutSelectors:zt,layoutActions:En,includeReadOnly:!0,includeWriteOnly:!0}),af=U.default.createElement("span",{className:"model-box"},U.default.createElement("span",{className:"model model-title"},ea));return U.default.createElement("div",{id:"model-".concat(ws),className:"model-container",key:"models-section-".concat(ws),"data-name":ws,ref:Qe.onLoadModel},U.default.createElement("span",{className:"models-jump-to-path"},U.default.createElement(Ns,{specPath:bs})),U.default.createElement(gs,{classes:"model-box",collapsedContent:Qe.getCollapsedContent(ws),onToggle:Qe.handleToggle,title:af,displayName:ea,modelName:ws,specPath:bs,layoutSelectors:zt,layoutActions:En,hideSelfOnExpand:!0,expanded:ci>0&&vl},ud))}).toArray()))}}]),ft}(U.Component);const D7=function(vn){var Kt=vn.value,ft=(0,vn.getComponent)("ModelCollapse"),Je=U.default.createElement("span",null,"Array [ ",Kt.count()," ]");return U.default.createElement("span",{className:"prop-enum"},"Enum:",U.default.createElement("br",null),U.default.createElement(ft,{collapsedContent:Je},"[ ",Kt.join(", ")," ]"))};var R7=["schema","name","displayName","isRef","getComponent","getConfigs","depth","onToggle","expanded","specPath"],N7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je,Qe,et,At,Ot=this.props,zt=Ot.schema,En=Ot.name,Yn=Ot.displayName,Ln=Ot.isRef,qn=Ot.getComponent,hi=Ot.getConfigs,ci=Ot.depth,Oi=Ot.onToggle,Ni=Ot.expanded,so=Ot.specPath,Ki=(0,r1.default)(Ot,R7),eo=Ki.specSelectors,gs=Ki.expandDepth,Ns=Ki.includeReadOnly,qs=Ki.includeWriteOnly,Os=eo.isOAS3;if(!zt)return null;var ws=hi().showExtensions,Ps=zt.get("description"),bs=zt.get("properties"),ka=zt.get("additionalProperties"),Ys=zt.get("title")||Yn||En,Sa=zt.get("required"),Jo=(0,g.default)(zt).call(zt,function(Gd,cc){var Vd;return-1!==(0,Ze.default)(Vd=["maxProperties","minProperties","nullable","example"]).call(Vd,cc)}),ea=zt.get("deprecated"),vl=qn("JumpToPath",!0),ud=qn("Markdown",!0),af=qn("Model"),lf=qn("ModelCollapse"),kf=qn("Property"),ru=function(){return U.default.createElement("span",{className:"model-jump-to-path"},U.default.createElement(vl,{specPath:so}))},cd=U.default.createElement("span",null,U.default.createElement("span",null,"{"),"...",U.default.createElement("span",null,"}"),Ln?U.default.createElement(ru,null):""),uc=eo.isOAS3()?zt.get("anyOf"):null,dp=eo.isOAS3()?zt.get("oneOf"):null,Xf=eo.isOAS3()?zt.get("not"):null,L_=Ys&&U.default.createElement("span",{className:"model-title"},Ln&&zt.get("$$ref")&&U.default.createElement("span",{className:"model-hint"},zt.get("$$ref")),U.default.createElement("span",{className:"model-title__text"},Ys));return U.default.createElement("span",{className:"model"},U.default.createElement(lf,{modelName:En,title:L_,onToggle:Oi,expanded:!!Ni||ci<=gs,collapsedContent:cd},U.default.createElement("span",{className:"brace-open object"},"{"),Ln?U.default.createElement(ru,null):null,U.default.createElement("span",{className:"inner-object"},U.default.createElement("table",{className:"model"},U.default.createElement("tbody",null,Ps?U.default.createElement("tr",{className:"description"},U.default.createElement("td",null,"description:"),U.default.createElement("td",null,U.default.createElement(ud,{source:Ps}))):null,ea?U.default.createElement("tr",{className:"property"},U.default.createElement("td",null,"deprecated:"),U.default.createElement("td",null,"true")):null,bs&&bs.size?(0,we.default)(Je=(0,g.default)(Qe=bs.entrySeq()).call(Qe,function(Gd){var cc=(0,qa.default)(Gd,2)[1];return(!cc.get("readOnly")||Ns)&&(!cc.get("writeOnly")||qs)})).call(Je,function(Gd){var cc,Vd,uf=(0,qa.default)(Gd,2),cf=uf[0],wh=uf[1],xd=Os()&&wh.get("deprecated"),Dd=ht.List.isList(Sa)&&Sa.contains(cf),Af=["property-row"];return xd&&Af.push("deprecated"),Dd&&Af.push("required"),U.default.createElement("tr",{key:cf,className:Af.join(" ")},U.default.createElement("td",null,cf,Dd&&U.default.createElement("span",{className:"star"},"*")),U.default.createElement("td",null,U.default.createElement(af,(0,kp.default)({key:(0,o.default)(cc=(0,o.default)(Vd="object-".concat(En,"-")).call(Vd,cf,"_")).call(cc,wh)},Ki,{required:Dd,getComponent:qn,specPath:so.push("properties",cf),getConfigs:hi,schema:wh,depth:ci+1}))))}).toArray():null,ws?U.default.createElement("tr",null,U.default.createElement("td",null,"\xa0")):null,ws?(0,we.default)(et=zt.entrySeq()).call(et,function(Gd){var cc=(0,qa.default)(Gd,2),Vd=cc[0],uf=cc[1];if("x-"===(0,Fe.default)(Vd).call(Vd,0,2)){var cf=uf?uf.toJS?uf.toJS():uf:null;return U.default.createElement("tr",{key:Vd,className:"extension"},U.default.createElement("td",null,Vd),U.default.createElement("td",null,(0,D.default)(cf)))}}).toArray():null,ka&&ka.size?U.default.createElement("tr",null,U.default.createElement("td",null,"< * >:"),U.default.createElement("td",null,U.default.createElement(af,(0,kp.default)({},Ki,{required:!1,getComponent:qn,specPath:so.push("additionalProperties"),getConfigs:hi,schema:ka,depth:ci+1})))):null,uc?U.default.createElement("tr",null,U.default.createElement("td",null,"anyOf ->"),U.default.createElement("td",null,(0,we.default)(uc).call(uc,function(Gd,cc){return U.default.createElement("div",{key:cc},U.default.createElement(af,(0,kp.default)({},Ki,{required:!1,getComponent:qn,specPath:so.push("anyOf",cc),getConfigs:hi,schema:Gd,depth:ci+1})))}))):null,dp?U.default.createElement("tr",null,U.default.createElement("td",null,"oneOf ->"),U.default.createElement("td",null,(0,we.default)(dp).call(dp,function(Gd,cc){return U.default.createElement("div",{key:cc},U.default.createElement(af,(0,kp.default)({},Ki,{required:!1,getComponent:qn,specPath:so.push("oneOf",cc),getConfigs:hi,schema:Gd,depth:ci+1})))}))):null,Xf?U.default.createElement("tr",null,U.default.createElement("td",null,"not ->"),U.default.createElement("td",null,U.default.createElement("div",null,U.default.createElement(af,(0,kp.default)({},Ki,{required:!1,getComponent:qn,specPath:so.push("not"),getConfigs:hi,schema:Xf,depth:ci+1}))))):null))),U.default.createElement("span",{className:"brace-close"},"}")),Jo.size?(0,we.default)(At=Jo.entrySeq()).call(At,function(Gd){var cc,Vd=(0,qa.default)(Gd,2),uf=Vd[0],cf=Vd[1];return U.default.createElement(kf,{key:(0,o.default)(cc="".concat(uf,"-")).call(cc,cf),propKey:uf,propVal:cf,propClass:"property"})}):null)}}]),ft}(U.Component),P7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je,Qe=this.props,et=Qe.getComponent,At=Qe.getConfigs,Ot=Qe.schema,zt=Qe.depth,En=Qe.expandDepth,Yn=Qe.name,Ln=Qe.displayName,qn=Qe.specPath,hi=Ot.get("description"),ci=Ot.get("items"),Oi=Ot.get("title")||Ln||Yn,Ni=(0,g.default)(Ot).call(Ot,function(qs,Os){var ws;return-1===(0,Ze.default)(ws=["type","items","description","$$ref"]).call(ws,Os)}),so=et("Markdown",!0),Ki=et("ModelCollapse"),eo=et("Model"),gs=et("Property"),Ns=Oi&&U.default.createElement("span",{className:"model-title"},U.default.createElement("span",{className:"model-title__text"},Oi));return U.default.createElement("span",{className:"model"},U.default.createElement(Ki,{title:Ns,expanded:zt<=En,collapsedContent:"[...]"},"[",Ni.size?(0,we.default)(Je=Ni.entrySeq()).call(Je,function(qs){var Os,ws=(0,qa.default)(qs,2),Ps=ws[0],bs=ws[1];return U.default.createElement(gs,{key:(0,o.default)(Os="".concat(Ps,"-")).call(Os,bs),propKey:Ps,propVal:bs,propClass:"property"})}):null,hi?U.default.createElement(so,{source:hi}):Ni.size?U.default.createElement("div",{className:"markdown"}):null,U.default.createElement("span",null,U.default.createElement(eo,(0,kp.default)({},this.props,{getConfigs:At,specPath:qn.push("items"),name:null,schema:ci,required:!1,depth:zt+1}))),"]"))}}]),ft}(U.Component),QA="property primitive",I7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je,Qe,et,At=this.props,Ot=At.schema,zt=At.getComponent,Yn=At.name,Ln=At.displayName,qn=At.depth,hi=At.expandDepth,ci=(0,At.getConfigs)().showExtensions;if(!Ot||!Ot.get)return U.default.createElement("div",null);var Oi=Ot.get("type"),Ni=Ot.get("format"),so=Ot.get("xml"),Ki=Ot.get("enum"),eo=Ot.get("title")||Ln||Yn,gs=Ot.get("description"),Ns=(0,Tn.nX)(Ot),qs=(0,g.default)(Ot).call(Ot,function(Ys,Sa){var Jo;return-1===(0,Ze.default)(Jo=["enum","type","format","description","$$ref"]).call(Jo,Sa)}).filterNot(function(Ys,Sa){return Ns.has(Sa)}),Os=zt("Markdown",!0),ws=zt("EnumModel"),Ps=zt("Property"),bs=zt("ModelCollapse"),ka=eo&&U.default.createElement("span",{className:"model-title"},U.default.createElement("span",{className:"model-title__text"},eo));return U.default.createElement("span",{className:"model"},U.default.createElement(bs,{title:ka,expanded:qn>=hi,collapsedContent:" ",hideSelfOnExpand:hi!==qn},U.default.createElement("span",{className:"prop"},Yn&&qn>1&&U.default.createElement("span",{className:"prop-name"},eo),U.default.createElement("span",{className:"prop-type"},Oi),Ni&&U.default.createElement("span",{className:"prop-format"},"($",Ni,")"),qs.size?(0,we.default)(Je=qs.entrySeq()).call(Je,function(Ys){var Sa,Jo=(0,qa.default)(Ys,2),ea=Jo[0],vl=Jo[1];return U.default.createElement(Ps,{key:(0,o.default)(Sa="".concat(ea,"-")).call(Sa,vl),propKey:ea,propVal:vl,propClass:QA})}):null,ci&&Ns.size?(0,we.default)(Qe=Ns.entrySeq()).call(Qe,function(Ys){var Sa,Jo=(0,qa.default)(Ys,2),ea=Jo[0],vl=Jo[1];return U.default.createElement(Ps,{key:(0,o.default)(Sa="".concat(ea,"-")).call(Sa,vl),propKey:ea,propVal:vl,propClass:QA})}):null,gs?U.default.createElement(Os,{source:gs}):null,so&&so.size?U.default.createElement("span",null,U.default.createElement("br",null),U.default.createElement("span",{className:QA},"xml:"),(0,we.default)(et=so.entrySeq()).call(et,function(Ys){var Sa,Jo=(0,qa.default)(Ys,2),ea=Jo[0],vl=Jo[1];return U.default.createElement("span",{key:(0,o.default)(Sa="".concat(ea,"-")).call(Sa,vl),className:QA},U.default.createElement("br",null),"\xa0\xa0\xa0",ea,": ",String(vl))}).toArray()):null,Ki&&U.default.createElement(ws,{value:Ki,getComponent:zt}))))}}]),ft}(U.Component);const L7=function(vn){var Kt=vn.propKey,ft=vn.propVal;return U.default.createElement("span",{className:vn.propClass},U.default.createElement("br",null),Kt,": ",String(ft))};var TP=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.onTryoutClick,At=Je.onResetClick,En=Je.isOAS3&&Je.hasUserEditedBody;return U.default.createElement("div",{className:En?"try-out btn-group":"try-out"},Je.enabled?U.default.createElement("button",{className:"btn try-out__btn cancel",onClick:Je.onCancelClick},"Cancel"):U.default.createElement("button",{className:"btn try-out__btn",onClick:Qe},"Try it out "),En&&U.default.createElement("button",{className:"btn try-out__btn reset",onClick:At},"Reset"))}}]),ft}(U.default.Component);(0,W.default)(TP,"defaultProps",{onTryoutClick:Function.prototype,onCancelClick:Function.prototype,onResetClick:Function.prototype,enabled:!1,hasUserEditedBody:!1,isOAS3:!1});var SP=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,et=Je.isSwagger2,At=Je.isOAS3,Ot=Je.alsoShow;return Je.bypass?U.default.createElement("div",null,this.props.children):et&&At?U.default.createElement("div",{className:"version-pragma"},Ot,U.default.createElement("div",{className:"version-pragma__message version-pragma__message--ambiguous"},U.default.createElement("div",null,U.default.createElement("h3",null,"Unable to render this definition"),U.default.createElement("p",null,U.default.createElement("code",null,"swagger")," and ",U.default.createElement("code",null,"openapi")," fields cannot be present in the same Swagger or OpenAPI definition. Please remove one of the fields."),U.default.createElement("p",null,"Supported version fields are ",U.default.createElement("code",null,"swagger: ",'"2.0"')," and those that match ",U.default.createElement("code",null,"openapi: 3.0.n")," (for example, ",U.default.createElement("code",null,"openapi: 3.0.0"),").")))):et||At?U.default.createElement("div",null,this.props.children):U.default.createElement("div",{className:"version-pragma"},Ot,U.default.createElement("div",{className:"version-pragma__message version-pragma__message--missing"},U.default.createElement("div",null,U.default.createElement("h3",null,"Unable to render this definition"),U.default.createElement("p",null,"The provided definition does not specify a valid version field."),U.default.createElement("p",null,"Please indicate a valid Swagger or OpenAPI version field. Supported version fields are ",U.default.createElement("code",null,"swagger: ",'"2.0"')," and those that match ",U.default.createElement("code",null,"openapi: 3.0.n")," (for example, ",U.default.createElement("code",null,"openapi: 3.0.0"),")."))))}}]),ft}(U.default.PureComponent);(0,W.default)(SP,"defaultProps",{alsoShow:null,children:null,bypass:!1});const F7=function(vn){return U.default.createElement("small",null,U.default.createElement("pre",{className:"version"}," ",vn.version," "))},k7=function(vn){var Kt=vn.enabled,Je=vn.text;return U.default.createElement("a",{className:"nostyle",onClick:Kt?function(Qe){return Qe.preventDefault()}:null,href:Kt?"#/".concat(vn.path):null},U.default.createElement("span",null,Je))},$7=function(){return U.default.createElement("div",null,U.default.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",xmlnsXlink:"http://www.w3.org/1999/xlink",className:"svg-assets"},U.default.createElement("defs",null,U.default.createElement("symbol",{viewBox:"0 0 20 20",id:"unlocked"},U.default.createElement("path",{d:"M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"})),U.default.createElement("symbol",{viewBox:"0 0 20 20",id:"locked"},U.default.createElement("path",{d:"M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z"})),U.default.createElement("symbol",{viewBox:"0 0 20 20",id:"close"},U.default.createElement("path",{d:"M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z"})),U.default.createElement("symbol",{viewBox:"0 0 20 20",id:"large-arrow"},U.default.createElement("path",{d:"M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z"})),U.default.createElement("symbol",{viewBox:"0 0 20 20",id:"large-arrow-down"},U.default.createElement("path",{d:"M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z"})),U.default.createElement("symbol",{viewBox:"0 0 20 20",id:"large-arrow-up"},U.default.createElement("path",{d:"M 17.418 14.908 C 17.69 15.176 18.127 15.176 18.397 14.908 C 18.667 14.64 18.668 14.207 18.397 13.939 L 10.489 6.109 C 10.219 5.841 9.782 5.841 9.51 6.109 L 1.602 13.939 C 1.332 14.207 1.332 14.64 1.602 14.908 C 1.873 15.176 2.311 15.176 2.581 14.908 L 10 7.767 L 17.418 14.908 Z"})),U.default.createElement("symbol",{viewBox:"0 0 24 24",id:"jump-to"},U.default.createElement("path",{d:"M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"})),U.default.createElement("symbol",{viewBox:"0 0 24 24",id:"expand"},U.default.createElement("path",{d:"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"})))))};var H7=Mo(5466),U7=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.errSelectors,et=Je.specSelectors,At=Je.getComponent,Ot=At("SvgAssets"),zt=At("InfoContainer",!0),En=At("VersionPragmaFilter"),Yn=At("operations",!0),Ln=At("Models",!0),qn=At("Row"),hi=At("Col"),ci=At("errors",!0),Oi=At("ServersContainer",!0),Ni=At("SchemesContainer",!0),so=At("AuthorizeBtnContainer",!0),Ki=At("FilterContainer",!0),eo=et.isSwagger2(),gs=et.isOAS3(),Ns=!et.specStr(),qs=et.loadingStatus(),Os=null;if("loading"===qs&&(Os=U.default.createElement("div",{className:"info"},U.default.createElement("div",{className:"loading-container"},U.default.createElement("div",{className:"loading"})))),"failed"===qs&&(Os=U.default.createElement("div",{className:"info"},U.default.createElement("div",{className:"loading-container"},U.default.createElement("h4",{className:"title"},"Failed to load API definition."),U.default.createElement(ci,null)))),"failedConfig"===qs){var ws=Qe.lastError(),Ps=ws?ws.get("message"):"";Os=U.default.createElement("div",{className:"info failed-config"},U.default.createElement("div",{className:"loading-container"},U.default.createElement("h4",{className:"title"},"Failed to load remote configuration."),U.default.createElement("p",null,Ps)))}if(!Os&&Ns&&(Os=U.default.createElement("h4",null,"No API definition provided.")),Os)return U.default.createElement("div",{className:"swagger-ui"},U.default.createElement("div",{className:"loading-container"},Os));var bs=et.servers(),ka=et.schemes(),Ys=bs&&bs.size,Sa=ka&&ka.size,Jo=!!et.securityDefinitions();return U.default.createElement("div",{className:"swagger-ui"},U.default.createElement(Ot,null),U.default.createElement(En,{isSwagger2:eo,isOAS3:gs,alsoShow:U.default.createElement(ci,null)},U.default.createElement(ci,null),U.default.createElement(qn,{className:"information-container"},U.default.createElement(hi,{mobile:12},U.default.createElement(zt,null))),Ys||Sa||Jo?U.default.createElement("div",{className:"scheme-container"},U.default.createElement(hi,{className:"schemes wrapper",mobile:12},Ys?U.default.createElement(Oi,null):null,Sa?U.default.createElement(Ni,null):null,Jo?U.default.createElement(so,null):null)):null,U.default.createElement(Ki,null),U.default.createElement(qn,null,U.default.createElement(hi,{mobile:12,desktop:12},U.default.createElement(Yn,null))),U.default.createElement(qn,null,U.default.createElement(hi,{mobile:12,desktop:12},U.default.createElement(Ln,null)))))}}]),ft}(U.default.Component);const CP=(vn=>{var Kt={};return Mo.d(Kt,vn),Kt})({default:()=>FF()});var w0={value:"",onChange:function(){},schema:{},keyName:"",required:!1,errors:(0,ht.List)()},MP=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){return(0,re.default)(this,ft),Kt.apply(this,arguments)}return(0,oe.default)(ft,[{key:"componentDidMount",value:function(){var Je=this.props,Qe=Je.dispatchInitialValue,At=Je.onChange;Qe?At(Je.value):!1===Qe&&At("")}},{key:"render",value:function(){var Je,Qe=this.props,et=Qe.schema,At=Qe.errors,Ot=Qe.value,zt=Qe.onChange,En=Qe.getComponent,Yn=Qe.fn,Ln=Qe.disabled,qn=et&&et.get?et.get("format"):null,hi=et&&et.get?et.get("type"):null,Oi=hi?En(qn?(0,o.default)(Je="JsonSchema_".concat(hi,"_")).call(Je,qn):"JsonSchema_".concat(hi),!1,{failSilently:!0}):En("JsonSchema_string");return Oi||(Oi=En("JsonSchema_string")),U.default.createElement(Oi,(0,kp.default)({},this.props,{errors:At,fn:Yn,getComponent:En,value:Ot,onChange:zt,schema:et,disabled:Ln}))}}]),ft}(U.Component);(0,W.default)(MP,"defaultProps",w0);var AP=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"onChange",function(zt){var En=Qe.props.schema&&"file"===Qe.props.schema.get("type")?zt.target.files[0]:zt.target.value;Qe.props.onChange(En,Qe.props.keyName)}),(0,W.default)((0,Di.default)(Qe),"onEnumChange",function(zt){return Qe.props.onChange(zt)}),Qe}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.getComponent,et=Je.value,At=Je.schema,Ot=Je.errors,zt=Je.required,En=Je.description,Yn=Je.disabled,Ln=At&&At.get?At.get("enum"):null,qn=At&&At.get?At.get("format"):null,hi=At&&At.get?At.get("type"):null,ci=At&&At.get?At.get("in"):null;if(et||(et=""),Ot=Ot.toJS?Ot.toJS():[],Ln){var Oi=Qe("Select");return U.default.createElement(Oi,{className:Ot.length?"invalid":"",title:Ot.length?Ot:"",allowedValues:Ln,value:et,allowEmptyValue:!zt,disabled:Yn,onChange:this.onEnumChange})}var Ni=Yn||ci&&"formData"===ci&&!("FormData"in window),so=Qe("Input");return hi&&"file"===hi?U.default.createElement(so,{type:"file",className:Ot.length?"invalid":"",title:Ot.length?Ot:"",onChange:this.onChange,disabled:Ni}):U.default.createElement(CP.default,{type:qn&&"password"===qn?"password":"text",className:Ot.length?"invalid":"",title:Ot.length?Ot:"",value:et,minLength:0,debounceTimeout:350,placeholder:En,onChange:this.onChange,disabled:Ni})}}]),ft}(U.Component);(0,W.default)(AP,"defaultProps",w0);var OP=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(Je,Qe){var et;return(0,re.default)(this,ft),et=Kt.call(this,Je,Qe),(0,W.default)((0,Di.default)(et),"onChange",function(){et.props.onChange(et.state.value)}),(0,W.default)((0,Di.default)(et),"onItemChange",function(At,Ot){et.setState(function(zt){return{value:zt.value.set(Ot,At)}},et.onChange)}),(0,W.default)((0,Di.default)(et),"removeItem",function(At){et.setState(function(Ot){return{value:Ot.value.delete(At)}},et.onChange)}),(0,W.default)((0,Di.default)(et),"addItem",function(){var At=cR(et.state.value);et.setState(function(){return{value:At.push((0,Tn.xi)(et.state.schema.get("items"),!1,{includeWriteOnly:!0}))}},et.onChange)}),(0,W.default)((0,Di.default)(et),"onEnumChange",function(At){et.setState(function(){return{value:At}},et.onChange)}),et.state={value:cR(Je.value),schema:Je.schema},et}return(0,oe.default)(ft,[{key:"UNSAFE_componentWillReceiveProps",value:function(Je){var Qe=cR(Je.value);Qe!==this.state.value&&this.setState({value:Qe}),Je.schema!==this.state.schema&&this.setState({schema:Je.schema})}},{key:"render",value:function(){var Je,Qe=this,et=this.props,At=et.getComponent,Ot=et.required,zt=et.schema,En=et.errors,Yn=et.fn,Ln=et.disabled;En=En.toJS?En.toJS():(0,Re.default)(En)?En:[];var qn,hi,ci=(0,g.default)(En).call(En,function(bs){return"string"==typeof bs}),Oi=(0,we.default)(Je=(0,g.default)(En).call(En,function(bs){return void 0!==bs.needRemove})).call(Je,function(bs){return bs.error}),Ni=this.state.value,so=!!(Ni&&Ni.count&&Ni.count()>0),Ki=zt.getIn(["items","enum"]),eo=zt.getIn(["items","type"]),gs=zt.getIn(["items","format"]),Ns=zt.get("items"),qs=!1,Os="file"===eo||"string"===eo&&"binary"===gs;if(eo&&gs?qn=At((0,o.default)(hi="JsonSchema_".concat(eo,"_")).call(hi,gs)):"boolean"!==eo&&"array"!==eo&&"object"!==eo||(qn=At("JsonSchema_".concat(eo))),qn||Os||(qs=!0),Ki){var ws=At("Select");return U.default.createElement(ws,{className:En.length?"invalid":"",title:En.length?En:"",multiple:!0,value:Ni,disabled:Ln,allowedValues:Ki,allowEmptyValue:!Ot,onChange:this.onEnumChange})}var Ps=At("Button");return U.default.createElement("div",{className:"json-schema-array"},so?(0,we.default)(Ni).call(Ni,function(bs,ka){var Ys,Sa=(0,ht.fromJS)((0,wd.default)((0,we.default)(Ys=(0,g.default)(En).call(En,function(Jo){return Jo.index===ka})).call(Ys,function(Jo){return Jo.error})));return U.default.createElement("div",{key:ka,className:"json-schema-form-item"},Os?U.default.createElement(uR,{value:bs,onChange:function(Jo){return Qe.onItemChange(Jo,ka)},disabled:Ln,errors:Sa,getComponent:At}):qs?U.default.createElement(lR,{value:bs,onChange:function(Jo){return Qe.onItemChange(Jo,ka)},disabled:Ln,errors:Sa}):U.default.createElement(qn,(0,kp.default)({},Qe.props,{value:bs,onChange:function(Jo){return Qe.onItemChange(Jo,ka)},disabled:Ln,errors:Sa,schema:Ns,getComponent:At,fn:Yn})),Ln?null:U.default.createElement(Ps,{className:"btn btn-sm json-schema-form-item-remove ".concat(Oi.length?"invalid":null),title:Oi.length?Oi:"",onClick:function(){return Qe.removeItem(ka)}}," - "))}):null,Ln?null:U.default.createElement(Ps,{className:"btn btn-sm json-schema-form-item-add ".concat(ci.length?"invalid":null),title:ci.length?ci:"",onClick:this.addItem},"Add ",eo?"".concat(eo," "):"","item"))}}]),ft}(U.PureComponent);(0,W.default)(OP,"defaultProps",w0);var lR=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"onChange",function(zt){Qe.props.onChange(zt.target.value,Qe.props.keyName)}),Qe}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.value,et=Je.errors,At=Je.description,Ot=Je.disabled;return Qe||(Qe=""),et=et.toJS?et.toJS():[],U.default.createElement(CP.default,{type:"text",className:et.length?"invalid":"",title:et.length?et:"",value:Qe,minLength:0,debounceTimeout:350,placeholder:At,onChange:this.onChange,disabled:Ot})}}]),ft}(U.Component);(0,W.default)(lR,"defaultProps",w0);var uR=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"onFileChange",function(zt){Qe.props.onChange(zt.target.files[0],Qe.props.keyName)}),Qe}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,et=Je.errors,At=Je.disabled,Ot=(0,Je.getComponent)("Input"),zt=At||!("FormData"in window);return U.default.createElement(Ot,{type:"file",className:et.length?"invalid":"",title:et.length?et:"",onChange:this.onFileChange,disabled:zt})}}]),ft}(U.Component);(0,W.default)(uR,"defaultProps",w0);var wP=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je,Qe;(0,re.default)(this,ft);for(var et=arguments.length,At=new Array(et),Ot=0;Ot<et;Ot++)At[Ot]=arguments[Ot];return Qe=Kt.call.apply(Kt,(0,o.default)(Je=[this]).call(Je,At)),(0,W.default)((0,Di.default)(Qe),"onEnumChange",function(zt){return Qe.props.onChange(zt)}),Qe}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,Qe=Je.getComponent,et=Je.value,At=Je.errors,Ot=Je.schema,zt=Je.required,En=Je.disabled;At=At.toJS?At.toJS():[];var Yn=Ot&&Ot.get?Ot.get("enum"):null,Ln=!Yn||!zt,qn=!Yn&&(0,ht.fromJS)(["true","false"]),hi=Qe("Select");return U.default.createElement(hi,{className:At.length?"invalid":"",title:At.length?At:"",value:String(et),disabled:En,allowedValues:Yn||qn,allowEmptyValue:Ln,onChange:this.onEnumChange})}}]),ft}(U.Component);(0,W.default)(wP,"defaultProps",w0);var B7=function(vn){return(0,we.default)(vn).call(vn,function(Kt){var ft,Qe="string"==typeof Kt?Kt:"string"==typeof Kt.error?Kt.error:null;if(!(void 0!==Kt.propKey?Kt.propKey:Kt.index)&&Qe)return Qe;for(var et=Kt.error,At="/".concat(Kt.propKey);"object"===(0,t.default)(et);){var Ot=void 0!==et.propKey?et.propKey:et.index;if(void 0===Ot||(At+="/".concat(Ot),!et.error))break;et=et.error}return(0,o.default)(ft="".concat(At,": ")).call(ft,et)})},xP=function(vn){(0,oo.default)(ft,vn);var Kt=(0,ho.default)(ft);function ft(){var Je;return(0,re.default)(this,ft),Je=Kt.call(this),(0,W.default)((0,Di.default)(Je),"onChange",function(Qe){Je.props.onChange(Qe)}),(0,W.default)((0,Di.default)(Je),"handleOnChange",function(Qe){Je.onChange(Qe.target.value)}),Je}return(0,oe.default)(ft,[{key:"render",value:function(){var Je=this.props,et=Je.value,At=Je.errors,Ot=Je.disabled,zt=(0,Je.getComponent)("TextArea");return At=At.toJS?At.toJS():(0,Re.default)(At)?At:[],U.default.createElement("div",null,U.default.createElement(zt,{className:(0,Ff.default)({invalid:At.length}),title:At.length?B7(At).join(", "):"",value:(0,Tn.Pz)(et),disabled:Ot,onChange:this.handleOnChange}))}}]),ft}(U.PureComponent);function cR(vn){return ht.List.isList(vn)?vn:(0,Re.default)(vn)?(0,ht.fromJS)(vn):(0,ht.List)()}function Y7(){return[_s.default,_r.default,Xr.default,ji.default,jr.default,Wn.default,bn.default,oi.default,{components:{App:Un,authorizationPopup:pr,authorizeBtn:Vr,AuthorizeBtnContainer:Ri,authorizeOperationBtn:Bs,auths:Uo,AuthItem:ol,authError:ml,oauth2:Lp,apiKeyAuth:tu,basicAuth:qu,clear:Yi,liveResponse:qi,InitializedInput:d7,info:g7,InfoContainer:m7,JumpToPath:v7,onlineValidatorBadge:No.Z,operations:is,operation:Zi,OperationSummary:es,OperationSummaryMethod:fu,OperationSummaryPath:Ai,highlightCode:I_,responses:t1,response:gm,ResponseExtension:dg,responseBody:YA,parameters:cS,parameterRow:VA,execute:WA,headers:za,errors:ku,contentType:O0,overview:l7,footer:y7,FilterContainer:b7,ParamBody:bP,curl:T7,schemes:S7,SchemesContainer:C7,modelExample:A7,ModelWrapper:O7,ModelCollapse:EP,Model:w7.Z,Models:x7,EnumModel:D7,ObjectModel:N7,ArrayModel:P7,PrimitiveModel:I7,Property:L7,TryItOutButton:TP,Markdown:H7.Z,BaseLayout:U7,VersionPragmaFilter:SP,VersionStamp:F7,OperationExt:Ba,OperationExtRow:ec,ParameterExt:jA,ParameterIncludeEmpty:dS,OperationTag:rs,OperationContainer:St,DeepLink:k7,InfoUrl:_7,InfoBasePath:f7,SvgAssets:$7,Example:Lf,ExamplesSelect:Kc,ExamplesSelectValueRetainer:Ah}},{components:n},Sn.default,{components:s},hn.default,Fi.default,Ho.default,yo.default,Us.default,Ui.default,(0,zs.default)()]}(0,W.default)(xP,"defaultProps",w0);var Z7=Mo(7451);function DP(){return[Y7,Z7.default]}var j7=Mo(5308);function dR(vn){var Kt,ft,Je;wn.Z.versions=wn.Z.versions||{},wn.Z.versions.swaggerUi={version:"4.12.0",gitRevision:"ga7e23b5",gitDirty:!0,buildTimestamp:"Fri, 03 Jun 2022 17:07:59 GMT"};var Qe={dom_id:null,domNode:null,spec:{},url:"",urls:null,layout:"BaseLayout",docExpansion:"list",maxDisplayedTags:null,filter:null,validatorUrl:"https://validator.swagger.io/validator",oauth2RedirectUrl:(0,o.default)(Kt=(0,o.default)(ft="".concat(window.location.protocol,"//")).call(ft,window.location.host)).call(Kt,window.location.pathname.substring(0,(0,c.default)(Je=window.location.pathname).call(Je,"/")),"/oauth2-redirect.html"),persistAuthorization:!1,configs:{},custom:{},displayOperationId:!1,displayRequestDuration:!1,deepLinking:!1,tryItOutEnabled:!1,requestInterceptor:function(ci){return ci},responseInterceptor:function(ci){return ci},showMutatedRequest:!0,defaultModelRendering:"example",defaultModelExpandDepth:1,defaultModelsExpandDepth:1,showExtensions:!1,showCommonExtensions:!1,withCredentials:void 0,requestSnippetsEnabled:!1,requestSnippets:{generators:{curl_bash:{title:"cURL (bash)",syntax:"bash"},curl_powershell:{title:"cURL (PowerShell)",syntax:"powershell"},curl_cmd:{title:"cURL (CMD)",syntax:"bash"}},defaultExpanded:!0,languages:null},supportedSubmitMethods:["get","put","post","delete","options","head","patch","trace"],queryConfigEnabled:!1,presets:[DP],plugins:[],pluginsOptions:{pluginLoadType:"legacy"},initialState:{},fn:{},components:{},syntaxHighlight:{activated:!0,theme:"agate"}},et=vn.queryConfigEnabled?(0,Tn.UG)():{},At=vn.domNode;delete vn.domNode;var Ot=j()({},Qe,vn,et),zt={system:{configs:Ot.configs},plugins:Ot.presets,pluginsOptions:Ot.pluginsOptions,state:j()({layout:{layout:Ot.layout,filter:(0,g.default)(Ot)},spec:{spec:"",url:Ot.url},requestSnippets:Ot.requestSnippets},Ot.initialState)};if(Ot.initialState)for(var En in Ot.initialState)Object.prototype.hasOwnProperty.call(Ot.initialState,En)&&void 0===Ot.initialState[En]&&delete zt.state[En];var Yn=new sr(zt);Yn.register([Ot.plugins,function(){return{fn:Ot.fn,components:Ot.components,state:Ot.state}}]);var Ln=Yn.getSystem(),qn=function(ci){var Oi=Ln.specSelectors.getLocalConfig?Ln.specSelectors.getLocalConfig():{},Ni=j()({},Oi,Ot,ci||{},et);if(At&&(Ni.domNode=At),Yn.setConfigs(Ni),Ln.configsActions.loaded(),null!==ci&&(!et.url&&"object"===(0,t.default)(Ni.spec)&&(0,C.default)(Ni.spec).length?(Ln.specActions.updateUrl(""),Ln.specActions.updateLoadingStatus("success"),Ln.specActions.updateSpec((0,D.default)(Ni.spec))):Ln.specActions.download&&Ni.url&&!Ni.urls&&(Ln.specActions.updateUrl(Ni.url),Ln.specActions.download(Ni.url))),Ni.domNode)Ln.render(Ni.domNode,"App");else if(Ni.dom_id){var so=document.querySelector(Ni.dom_id);Ln.render(so,"App")}else null===Ni.dom_id||null===Ni.domNode||console.error("Skipped rendering: no `dom_id` or `domNode` was specified");return Ln},hi=et.config||Ot.configUrl;return hi&&Ln.specActions&&Ln.specActions.getConfigByUrl?(Ln.specActions.getConfigByUrl({url:hi,loadRemoteConfig:!0,requestInterceptor:Ot.requestInterceptor,responseInterceptor:Ot.responseInterceptor},qn),Ln):qn()}dR.presets={apis:DP},dR.plugins=j7.default;const J7=dR})();var $F=sP.Z;let HF=(()=>{class n{ngOnInit(){$F({url:window.location.origin+"/docs/openapi.json",dom_id:"#swagger-ui",layout:"BaseLayout"})}}return n.\u0275fac=function(t){return new(t||n)},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-api-docs"]],decls:1,vars:0,consts:[["id","swagger-ui",1,"apiDocs"]],template:function(t,o){1&t&&e._UZ(0,"div",0)},styles:[".apiDocs[_ngcontent-%COMP%]{background:#f8f9fa;font-size:18px!important;margin-top:-48px!important}"]}),n})();var aP=i(45510);let lP=(()=>{class n{constructor(t,o){this.router=t,this.authStorageService=o}canActivate(t,o){return!(this.authStorageService.isLoggedIn()&&!this.authStorageService.isSSO()&&this.authStorageService.getPwdUpdateRequired()&&(this.router.navigate(["/login-change-password"],{queryParams:{returnUrl:o.url}}),1))}canActivateChild(t,o){return this.canActivate(t,o)}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(Bo.F0),e.LFG(vt.j))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})();var oR=i(4222),uS=i(54462);let uP=(()=>{class n{constructor(t){this.authStorageService=t}canActivate(){if(!this.authStorageService.isSSO())return!0;throw new Ia.mM}canActivateChild(){return this.canActivate()}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(vt.j))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})(),cP=(()=>{class n extends Wm{resolve(t){const o=[],c=t.queryParams.fromLink||null;let g="";switch(c){case"/monitor":g="Monitors";break;case"/hosts":g="Hosts"}return o.push({text:"Cluster",path:null}),o.push({text:g,path:c}),o.push({text:"Performance Counters",path:""}),o}}return n.\u0275fac=function(){let s;return function(o){return(s||(s=e.n5z(n)))(o||n)}}(),n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac}),n})(),dP=(()=>{class n extends Wm{resolve(t){const o=t.params.name;return[{text:`${wr().startCase(o)}/Edit`,path:o}]}}return n.\u0275fac=function(){let s;return function(o){return(s||(s=e.n5z(n)))(o||n)}}(),n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac}),n})();const UF=[{path:"",redirectTo:"dashboard",pathMatch:"full"},{path:"api-docs",component:HF},{path:"",component:kR,canActivate:[aP.P,lP],canActivateChild:[aP.P,lP],children:[{path:"dashboard",component:wO},{path:"error",component:VC},{path:"expand-cluster",component:dv,canActivate:[uS.P],data:{moduleStatusGuardConfig:{uiApiPath:"orchestrator",redirectTo:"dashboard",backend:"cephadm"},breadcrumbs:"Expand Cluster"}},{path:"hosts",component:lh,data:{breadcrumbs:"Cluster/Hosts"},children:[{path:$i.MQ.ADD,component:Xe,outlet:"modal"}]},{path:"monitor",component:U0,data:{breadcrumbs:"Cluster/Monitors"}},{path:"services",component:ef,canActivate:[uS.P],data:{moduleStatusGuardConfig:{uiApiPath:"orchestrator",redirectTo:"error",section:"orch",section_info:"Orchestrator",header:"Orchestrator is not available"},breadcrumbs:"Cluster/Services"},children:[{path:$i.MQ.CREATE,component:ov,outlet:"modal"},{path:`${$i.MQ.EDIT}/:type/:name`,component:ov,outlet:"modal"}]},{path:"inventory",canActivate:[uS.P],component:Q,data:{moduleStatusGuardConfig:{uiApiPath:"orchestrator",redirectTo:"error",section:"orch",section_info:"Orchestrator",header:"Orchestrator is not available"},breadcrumbs:"Cluster/Physical Disks"}},{path:"osd",data:{breadcrumbs:"Cluster/OSDs"},children:[{path:"",component:uy},{path:$i.MQ.CREATE,component:p_,data:{breadcrumbs:$i.Qn.CREATE}}]},{path:"configuration",data:{breadcrumbs:"Cluster/Configuration"},children:[{path:"",component:pf},{path:"edit/:name",component:Ja,data:{breadcrumbs:$i.Qn.EDIT}}]},{path:"crush-map",component:Cg,data:{breadcrumbs:"Cluster/CRUSH map"}},{path:"logs",component:Dl,data:{breadcrumbs:"Cluster/Logs"}},{path:"telemetry",component:lO,data:{breadcrumbs:"Telemetry configuration"}},{path:"monitoring",data:{breadcrumbs:"Cluster/Monitoring"},children:[{path:"",redirectTo:"active-alerts",pathMatch:"full"},{path:"active-alerts",data:{breadcrumbs:"Active Alerts"},component:qr},{path:"alerts",data:{breadcrumbs:"Alerts"},component:oa},{path:"silences",data:{breadcrumbs:"Silences"},children:[{path:"",component:Vb},{path:$i.MQ.CREATE,component:dy,data:{breadcrumbs:`${$i.Qn.CREATE} Silence`}},{path:`${$i.MQ.CREATE}/:id`,component:dy,data:{breadcrumbs:$i.Qn.CREATE}},{path:`${$i.MQ.EDIT}/:id`,component:dy,data:{breadcrumbs:$i.Qn.EDIT}},{path:`${$i.MQ.RECREATE}/:id`,component:dy,data:{breadcrumbs:$i.Qn.RECREATE}}]}]},{path:"perf_counters/:type/:id",component:LC,data:{breadcrumbs:cP}},{path:"mgr-modules",data:{breadcrumbs:"Cluster/Manager Modules"},children:[{path:"",component:wg},{path:"edit/:name",component:gv,data:{breadcrumbs:dP}}]},{path:"pool",data:{breadcrumbs:"Pools"},loadChildren:()=>Promise.all([i.e(483),i.e(117)]).then(i.bind(i,73117)).then(n=>n.RoutedPoolModule)},{path:"block",data:{breadcrumbs:!0,text:"Block",path:null},loadChildren:()=>i.e(483).then(i.bind(i,70483)).then(n=>n.RoutedBlockModule)},{path:"cephfs",component:$a,canActivate:[oR.T],data:{breadcrumbs:"File Systems"}},{path:"rgw",canActivateChild:[oR.T,uS.P],data:{moduleStatusGuardConfig:{uiApiPath:"rgw",redirectTo:"error",section:"rgw",section_info:"Object Gateway",header:"The Object Gateway Service is not configured"},breadcrumbs:!0,text:"Object Gateway",path:null},loadChildren:()=>i.e(281).then(i.bind(i,59281)).then(n=>n.RoutedRgwModule)},{path:"user-management",data:{breadcrumbs:"User management",path:null},loadChildren:()=>Promise.resolve().then(i.bind(i,49552)).then(n=>n.RoutedAuthModule)},{path:"user-profile",data:{breadcrumbs:"User profile",path:null},children:[{path:$i.MQ.EDIT,component:UC,canActivate:[uP],data:{breadcrumbs:$i.Qn.EDIT}}]},{path:"nfs",canActivateChild:[oR.T,uS.P],data:{moduleStatusGuardConfig:{uiApiPath:"nfs-ganesha",redirectTo:"error",section:"nfs-ganesha",section_info:"NFS GANESHA",header:"NFS-Ganesha is not configured"},breadcrumbs:"NFS"},children:[{path:"",component:IC},{path:$i.MQ.CREATE,component:hE,data:{breadcrumbs:$i.Qn.CREATE}},{path:`${$i.MQ.EDIT}/:cluster_id/:export_id`,component:hE,data:{breadcrumbs:$i.Qn.EDIT}}]}]},{path:"",component:yE,children:[{path:"login",component:dw},{path:"login-change-password",component:lw,canActivate:[uP]}]},{path:"",component:vw,children:[{path:"**",redirectTo:"/error"}]}];let BA=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275mod=e.oAB({type:n}),n.\u0275inj=e.cJS({providers:[dP,cP],imports:[[Bo.Bz.forRoot(UF,{useHash:!0,preloadingStrategy:Bo.wm,relativeLinkResolution:"legacy"})],Bo.Bz]}),n})(),BF=(()=>{class n{constructor(t,o){t.autoClose="outside",t.container="body",t.placement="bottom",o.container="body"}}return n.\u0275fac=function(t){return new(t||n)(e.Y36(ut.AX),e.Y36(ut.xI))},n.\u0275cmp=e.Xpm({type:n,selectors:[["cd-root"]],decls:1,vars:0,template:function(t,o){1&t&&e._UZ(0,"router-outlet")},directives:[Bo.lC],styles:[""]}),n})();var _m=i(44466);let YF=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275mod=e.oAB({type:n}),n.\u0275inj=e.cJS({imports:[[_.ez,_m.m,BA,Fo.m9,Nl.xc,ut.Oz]]}),n})();var fP=i(66265),pP=i(370);let ZF=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275mod=e.oAB({type:n}),n.\u0275inj=e.cJS({imports:[[BA,_.ez,Mn.UX,_m.m,ut.Oz]]}),n})(),jF=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275mod=e.oAB({type:n}),n.\u0275inj=e.cJS({providers:[ut.Kz],imports:[[_.ez,fP.B,ut.Oz,_m.m,Bo.Bz,Mn.u5,Mn.UX,ut.HK,ZF,ut.ZS,ut.UL,Nl.xc,pP.t,ut.M,ut.dT,ut.XC,cr.b]]}),n})(),GF=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275mod=e.oAB({type:n}),n.\u0275inj=e.cJS({imports:[[pP.t,_.ez,ut.Oz,_m.m,Fo.m9,Bo.Bz,ut.dT]]}),n})(),VF=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275mod=e.oAB({type:n}),n.\u0275inj=e.cJS({imports:[[Mn.UX,Bo.Bz,_m.m,ut.Oz,_.ez,ut.ZS,ut.HK]]}),n})(),zF=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275mod=e.oAB({type:n}),n.\u0275inj=e.cJS({imports:[[_.ez,jF,GF,fP.B,YF,VF,_m.m]]}),n})();var WF=i(49552);let hP=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275mod=e.oAB({type:n}),n.\u0275inj=e.cJS({imports:[[_.ez,WF.AuthModule,ut.lQ,ut.XC,BA,_m.m,Sy.t,Bo.Bz]]}),n})(),JF=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275mod=e.oAB({type:n}),n.\u0275inj=e.cJS({imports:[[Qg.forRoot(),_.ez,hP,ut.XC,Bo.Bz,_m.m],hP]}),n})(),QF=(()=>{class n{constructor(t,o,c){this.router=t,this.authStorageService=o,this.notificationService=c}intercept(t,o){const c=t.headers.get("Accept");let g;return g=c&&c.startsWith("application/vnd.ceph.api.v")?t.clone():t.clone({setHeaders:{Accept:Nd.T.cdVersionHeader("1","0")}}),o.handle(g).pipe((0,wv.K)(C=>{if(C instanceof y.UA){let D;switch(C.status){case 400:const P=new cl.R,j=C.error.task;wr().isPlainObject(j)?(j.metadata.component=j.metadata.component||C.error.component,P.name=j.name,P.metadata=j.metadata):P.metadata=C.error,P.success=!1,P.exception=C.error,D=this.notificationService.notifyTask(P);break;case 401:this.authStorageService.remove(),this.router.navigate(["/login"]);break;case 403:this.router.navigate(["error"],{state:{message:"Sorry, you don\u2019t have permission to view this page or resource.",header:"Access Denied",icon:"fa fa-lock",source:"forbidden"}});break;default:D=this.prepareNotification(C)}C.preventDefault=()=>{this.notificationService.cancel(D)},C.ignoreStatusCode=function(P){this.status===P&&this.preventDefault()}}return(0,lC._)(C)}))}prepareNotification(t){return this.notificationService.show(()=>{let o="";return wr().isPlainObject(t.error)&&wr().isString(t.error.detail)?o=t.error.detail:wr().isString(t.error)?o=t.error:wr().isString(t.message)&&(o=t.message),new Cv.T(pa.k.error,`${t.status} - ${t.statusText}`,o,void 0,t.application)})}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(Bo.F0),e.LFG(vt.j),e.LFG(hl.g))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})(),XF=(()=>{class n{constructor(t){this.http=t}jsError(t,o,c){return this.http.post("ui-api/logging/js-error",{url:t,message:o,stack:c})}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(y.eN))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac,providedIn:"root"}),n})(),KF=(()=>{class n{constructor(t,o){this.injector=t,this.router=o}handleError(t){const o=this.injector.get(XF),c=window.location.href;if(o.jsError(c,t&&t.message,t&&t.stack).subscribe(),!(t.rejection instanceof Ia.s9))throw t;setTimeout(()=>this.router.navigate(["error"],{state:{message:t.rejection.message,header:t.rejection.header,icon:t.rejection.icon}}),50)}}return n.\u0275fac=function(t){return new(t||n)(e.LFG(e.zs3),e.LFG(Bo.F0))},n.\u0275prov=e.Yz7({token:n,factory:n.\u0275fac}),n})(),qF=(()=>{class n{}return n.\u0275fac=function(t){return new(t||n)},n.\u0275mod=e.oAB({type:n,bootstrap:[BF]}),n.\u0275inj=e.cJS({providers:[{provide:e.qLn,useClass:KF},{provide:y.TP,useClass:QF,multi:!0},{provide:_.mr,useValue:"/"+(window.location.pathname.split("/",1)[1]||"")}],imports:[[y.JF,d.b2,js,Uu.Rh.forRoot({positionClass:"toast-top-right",preventDuplicates:!0,enableHtml:!0}),BA,JF,_m.m,zF],_m.m]}),n})();mE.N.production&&(0,e.G48)(),d.q6().bootstrapModule(qF).then(n=>{if((0,e.X6Q)()){const t=n.injector.get(e.z2F).components[0];(0,d.HJ)(t)}}).catch(n=>console.log(n))},77340:(v,T,i)=>{var r=i(25591),u=i(60802),p=TypeError;v.exports=function(d){if(r(d))return d;throw p(u(d)+" is not a function")}},95143:(v,T,i)=>{var r=i(25591),u=String,p=TypeError;v.exports=function(d){if("object"==typeof d||r(d))return d;throw p("Can't set "+u(d)+" as a prototype")}},24094:(v,T,i)=>{var r=i(84563),u=i(38724),p=i(52975).f,d=r("unscopables"),e=Array.prototype;null==e[d]&&p(e,d,{configurable:!0,value:u(null)}),v.exports=function(_){e[d][_]=!0}},27678:(v,T,i)=>{"use strict";var r=i(64487).charAt;v.exports=function(u,p,d){return p+(d?r(u,p).length:1)}},86063:(v,T,i)=>{var r=i(93290),u=TypeError;v.exports=function(p,d){if(r(d,p))return p;throw u("Incorrect invocation")}},21099:(v,T,i)=>{var r=i(60726),u=String,p=TypeError;v.exports=function(d){if(r(d))return d;throw p(u(d)+" is not an object")}},93241:(v,T,i)=>{var r=i(8597);v.exports=r(function(){if("function"==typeof ArrayBuffer){var u=new ArrayBuffer(8);Object.isExtensible(u)&&Object.defineProperty(u,"a",{value:8})}})},70452:(v,T,i)=>{var r=i(8643),u=i(20222),p=i(24196),d=function(e){return function(_,y,S){var Z,A=r(_),N=p(A),L=u(S,N);if(e&&y!=y){for(;N>L;)if((Z=A[L++])!=Z)return!0}else for(;N>L;L++)if((e||L in A)&&A[L]===y)return e||L||0;return!e&&-1}};v.exports={includes:d(!0),indexOf:d(!1)}},94115:(v,T,i)=>{var r=i(29727),u=i(47964),p=i(56169),d=i(16174),e=i(24196),_=i(62889),y=u([].push),S=function(A){var N=1==A,L=2==A,Z=3==A,J=4==A,K=6==A,ee=7==A,ue=5==A||K;return function(ae,H,se,Ee){for(var ze,Be,ie=d(ae),he=p(ie),ge=r(H,se),De=e(he),ce=0,lt=Ee||_,Ve=N?lt(ae,De):L||ee?lt(ae,0):void 0;De>ce;ce++)if((ue||ce in he)&&(Be=ge(ze=he[ce],ce,ie),A))if(N)Ve[ce]=Be;else if(Be)switch(A){case 3:return!0;case 5:return ze;case 6:return ce;case 2:y(Ve,ze)}else switch(A){case 4:return!1;case 7:y(Ve,ze)}return K?-1:Z||J?J:Ve}};v.exports={forEach:S(0),map:S(1),filter:S(2),some:S(3),every:S(4),find:S(5),findIndex:S(6),filterReject:S(7)}},37394:(v,T,i)=>{var r=i(8597),u=i(84563),p=i(17189),d=u("species");v.exports=function(e){return p>=51||!r(function(){var _=[];return(_.constructor={})[d]=function(){return{foo:1}},1!==_[e](Boolean).foo})}},47051:(v,T,i)=>{"use strict";var r=i(8597);v.exports=function(u,p){var d=[][u];return!!d&&r(function(){d.call(null,p||function(){return 1},1)})}},14716:(v,T,i)=>{var r=i(77340),u=i(16174),p=i(56169),d=i(24196),e=TypeError,_=function(y){return function(S,A,N,L){r(A);var Z=u(S),J=p(Z),K=d(Z),ee=y?K-1:0,ue=y?-1:1;if(N<2)for(;;){if(ee in J){L=J[ee],ee+=ue;break}if(ee+=ue,y?ee<0:K<=ee)throw e("Reduce of empty array with no initial value")}for(;y?ee>=0:K>ee;ee+=ue)ee in J&&(L=A(L,J[ee],ee,Z));return L}};v.exports={left:_(!1),right:_(!0)}},32342:(v,T,i)=>{var r=i(20222),u=i(24196),p=i(45347),d=Array,e=Math.max;v.exports=function(_,y,S){for(var A=u(_),N=r(y,A),L=r(void 0===S?A:S,A),Z=d(e(L-N,0)),J=0;N<L;N++,J++)p(Z,J,_[N]);return Z.length=J,Z}},71497:(v,T,i)=>{var r=i(47883),u=i(57995),p=i(60726),e=i(84563)("species"),_=Array;v.exports=function(y){var S;return r(y)&&(u(S=y.constructor)&&(S===_||r(S.prototype))||p(S)&&null===(S=S[e]))&&(S=void 0),void 0===S?_:S}},62889:(v,T,i)=>{var r=i(71497);v.exports=function(u,p){return new(r(u))(0===p?0:p)}},56297:(v,T,i)=>{var u=i(84563)("iterator"),p=!1;try{var d=0,e={next:function(){return{done:!!d++}},return:function(){p=!0}};e[u]=function(){return this},Array.from(e,function(){throw 2})}catch(_){}v.exports=function(_,y){if(!y&&!p)return!1;var S=!1;try{var A={};A[u]=function(){return{next:function(){return{done:S=!0}}}},_(A)}catch(N){}return S}},96644:(v,T,i)=>{var r=i(47964),u=r({}.toString),p=r("".slice);v.exports=function(d){return p(u(d),8,-1)}},99420:(v,T,i)=>{var r=i(72900),u=i(25591),p=i(96644),e=i(84563)("toStringTag"),_=Object,y="Arguments"==p(function(){return arguments}());v.exports=r?p:function(A){var N,L,Z;return void 0===A?"Undefined":null===A?"Null":"string"==typeof(L=function(A,N){try{return A[N]}catch(L){}}(N=_(A),e))?L:y?p(N):"Object"==(Z=p(N))&&u(N.callee)?"Arguments":Z}},96491:(v,T,i)=>{"use strict";var r=i(47964),u=i(41292),p=i(64238).getWeakData,d=i(86063),e=i(21099),_=i(37432),y=i(60726),S=i(53284),A=i(94115),N=i(62445),L=i(52493),Z=L.set,J=L.getterFor,K=A.find,ee=A.findIndex,ue=r([].splice),ae=0,H=function(ie){return ie.frozen||(ie.frozen=new se)},se=function(){this.entries=[]},Ee=function(ie,he){return K(ie.entries,function(ge){return ge[0]===he})};se.prototype={get:function(ie){var he=Ee(this,ie);if(he)return he[1]},has:function(ie){return!!Ee(this,ie)},set:function(ie,he){var ge=Ee(this,ie);ge?ge[1]=he:this.entries.push([ie,he])},delete:function(ie){var he=ee(this.entries,function(ge){return ge[0]===ie});return~he&&ue(this.entries,he,1),!!~he}},v.exports={getConstructor:function(ie,he,ge,De){var ce=ie(function(Be,Pe){d(Be,lt),Z(Be,{type:he,id:ae++,frozen:void 0}),_(Pe)||S(Pe,Be[De],{that:Be,AS_ENTRIES:ge})}),lt=ce.prototype,Ve=J(he),ze=function(Be,Pe,je){var He=Ve(Be),Vt=p(e(Pe),!0);return!0===Vt?H(He).set(Pe,je):Vt[He.id]=je,Be};return u(lt,{delete:function(Be){var Pe=Ve(this);if(!y(Be))return!1;var je=p(Be);return!0===je?H(Pe).delete(Be):je&&N(je,Pe.id)&&delete je[Pe.id]},has:function(Pe){var je=Ve(this);if(!y(Pe))return!1;var He=p(Pe);return!0===He?H(je).has(Pe):He&&N(He,je.id)}}),u(lt,ge?{get:function(Pe){var je=Ve(this);if(y(Pe)){var He=p(Pe);return!0===He?H(je).get(Pe):He?He[je.id]:void 0}},set:function(Pe,je){return ze(this,Pe,je)}}:{add:function(Pe){return ze(this,Pe,!0)}}),ce}}},41603:(v,T,i)=>{"use strict";var r=i(51163),u=i(31864),p=i(47964),d=i(87215),e=i(70688),_=i(64238),y=i(53284),S=i(86063),A=i(25591),N=i(37432),L=i(60726),Z=i(8597),J=i(56297),K=i(58242),ee=i(38267);v.exports=function(ue,ae,H){var se=-1!==ue.indexOf("Map"),Ee=-1!==ue.indexOf("Weak"),ie=se?"set":"add",he=u[ue],ge=he&&he.prototype,De=he,ce={},lt=function(Vt){var it=p(ge[Vt]);e(ge,Vt,"add"==Vt?function(It){return it(this,0===It?0:It),this}:"delete"==Vt?function(tn){return!(Ee&&!L(tn))&&it(this,0===tn?0:tn)}:"get"==Vt?function(It){return Ee&&!L(It)?void 0:it(this,0===It?0:It)}:"has"==Vt?function(It){return!(Ee&&!L(It))&&it(this,0===It?0:It)}:function(It,Zt){return it(this,0===It?0:It,Zt),this})};if(d(ue,!A(he)||!(Ee||ge.forEach&&!Z(function(){(new he).entries().next()}))))De=H.getConstructor(ae,ue,se,ie),_.enable();else if(d(ue,!0)){var ze=new De,Be=ze[ie](Ee?{}:-0,1)!=ze,Pe=Z(function(){ze.has(1)}),je=J(function(Vt){new he(Vt)}),He=!Ee&&Z(function(){for(var Vt=new he,it=5;it--;)Vt[ie](it,it);return!Vt.has(-0)});je||((De=ae(function(Vt,it){S(Vt,ge);var tn=ee(new he,Vt,De);return N(it)||y(it,tn[ie],{that:tn,AS_ENTRIES:se}),tn})).prototype=ge,ge.constructor=De),(Pe||He)&&(lt("delete"),lt("has"),se&&lt("get")),(He||Be)&&lt(ie),Ee&&ge.clear&&delete ge.clear}return ce[ue]=De,r({global:!0,constructor:!0,forced:De!=he},ce),K(De,ue),Ee||H.setStrong(De,ue,se),De}},30009:(v,T,i)=>{var r=i(62445),u=i(99376),p=i(93099),d=i(52975);v.exports=function(e,_,y){for(var S=u(_),A=d.f,N=p.f,L=0;L<S.length;L++){var Z=S[L];!r(e,Z)&&(!y||!r(y,Z))&&A(e,Z,N(_,Z))}}},51335:(v,T,i)=>{var r=i(8597);v.exports=!r(function(){function u(){}return u.prototype.constructor=null,Object.getPrototypeOf(new u)!==u.prototype})},15189:v=>{v.exports=function(T,i){return{value:T,done:i}}},815:(v,T,i)=>{var r=i(47012),u=i(52975),p=i(53203);v.exports=r?function(d,e,_){return u.f(d,e,p(1,_))}:function(d,e,_){return d[e]=_,d}},53203:v=>{v.exports=function(T,i){return{enumerable:!(1&T),configurable:!(2&T),writable:!(4&T),value:i}}},45347:(v,T,i)=>{"use strict";var r=i(16582),u=i(52975),p=i(53203);v.exports=function(d,e,_){var y=r(e);y in d?u.f(d,y,p(0,_)):d[y]=_}},70688:(v,T,i)=>{var r=i(25591),u=i(52975),p=i(74952),d=i(11996);v.exports=function(e,_,y,S){S||(S={});var A=S.enumerable,N=void 0!==S.name?S.name:_;if(r(y)&&p(y,N,S),S.global)A?e[_]=y:d(_,y);else{try{S.unsafe?e[_]&&(A=!0):delete e[_]}catch(L){}A?e[_]=y:u.f(e,_,{value:y,enumerable:!1,configurable:!S.nonConfigurable,writable:!S.nonWritable})}return e}},41292:(v,T,i)=>{var r=i(70688);v.exports=function(u,p,d){for(var e in p)r(u,e,p[e],d);return u}},11996:(v,T,i)=>{var r=i(31864),u=Object.defineProperty;v.exports=function(p,d){try{u(r,p,{value:d,configurable:!0,writable:!0})}catch(e){r[p]=d}return d}},47012:(v,T,i)=>{var r=i(8597);v.exports=!r(function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]})},85815:(v,T,i)=>{var r=i(31864),u=i(60726),p=r.document,d=u(p)&&u(p.createElement);v.exports=function(e){return d?p.createElement(e):{}}},26877:v=>{v.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},20713:(v,T,i)=>{var u=i(85815)("span").classList,p=u&&u.constructor&&u.constructor.prototype;v.exports=p===Object.prototype?void 0:p},32002:(v,T,i)=>{var r=i(96644),u=i(31864);v.exports="process"==r(u.process)},73792:(v,T,i)=>{var r=i(73626);v.exports=r("navigator","userAgent")||""},17189:(v,T,i)=>{var y,S,r=i(31864),u=i(73792),p=r.process,d=r.Deno,e=p&&p.versions||d&&d.version,_=e&&e.v8;_&&(S=(y=_.split("."))[0]>0&&y[0]<4?1:+(y[0]+y[1])),!S&&u&&(!(y=u.match(/Edge\/(\d+)/))||y[1]>=74)&&(y=u.match(/Chrome\/(\d+)/))&&(S=+y[1]),v.exports=S},71001:v=>{v.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},51163:(v,T,i)=>{var r=i(31864),u=i(93099).f,p=i(815),d=i(70688),e=i(11996),_=i(30009),y=i(87215);v.exports=function(S,A){var K,ee,ue,ae,H,N=S.target,L=S.global,Z=S.stat;if(K=L?r:Z?r[N]||e(N,{}):(r[N]||{}).prototype)for(ee in A){if(ae=A[ee],ue=S.dontCallGetSet?(H=u(K,ee))&&H.value:K[ee],!y(L?ee:N+(Z?".":"#")+ee,S.forced)&&void 0!==ue){if(typeof ae==typeof ue)continue;_(ae,ue)}(S.sham||ue&&ue.sham)&&p(ae,"sham",!0),d(K,ee,ae,S)}}},8597:v=>{v.exports=function(T){try{return!!T()}catch(i){return!0}}},9357:(v,T,i)=>{"use strict";i(69665);var r=i(47964),u=i(70688),p=i(93084),d=i(8597),e=i(84563),_=i(815),y=e("species"),S=RegExp.prototype;v.exports=function(A,N,L,Z){var J=e(A),K=!d(function(){var H={};return H[J]=function(){return 7},7!=""[A](H)}),ee=K&&!d(function(){var H=!1,se=/a/;return"split"===A&&((se={}).constructor={},se.constructor[y]=function(){return se},se.flags="",se[J]=/./[J]),se.exec=function(){return H=!0,null},se[J](""),!H});if(!K||!ee||L){var ue=r(/./[J]),ae=N(J,""[A],function(H,se,Ee,ie,he){var ge=r(H),De=se.exec;return De===p||De===S.exec?K&&!he?{done:!0,value:ue(se,Ee,ie)}:{done:!0,value:ge(Ee,se,ie)}:{done:!1}});u(String.prototype,A,ae[0]),u(S,J,ae[1])}Z&&_(S[J],"sham",!0)}},39352:(v,T,i)=>{var r=i(8597);v.exports=!r(function(){return Object.isExtensible(Object.preventExtensions({}))})},32328:(v,T,i)=>{var r=i(4459),u=Function.prototype,p=u.apply,d=u.call;v.exports="object"==typeof Reflect&&Reflect.apply||(r?d.bind(p):function(){return d.apply(p,arguments)})},29727:(v,T,i)=>{var r=i(47964),u=i(77340),p=i(4459),d=r(r.bind);v.exports=function(e,_){return u(e),void 0===_?e:p?d(e,_):function(){return e.apply(_,arguments)}}},4459:(v,T,i)=>{var r=i(8597);v.exports=!r(function(){var u=function(){}.bind();return"function"!=typeof u||u.hasOwnProperty("prototype")})},757:(v,T,i)=>{var r=i(4459),u=Function.prototype.call;v.exports=r?u.bind(u):function(){return u.apply(u,arguments)}},20538:(v,T,i)=>{var r=i(47012),u=i(62445),p=Function.prototype,d=r&&Object.getOwnPropertyDescriptor,e=u(p,"name"),_=e&&"something"===function(){}.name,y=e&&(!r||r&&d(p,"name").configurable);v.exports={EXISTS:e,PROPER:_,CONFIGURABLE:y}},47964:(v,T,i)=>{var r=i(4459),u=Function.prototype,d=u.call,e=r&&u.bind.bind(d,d);v.exports=r?function(_){return _&&e(_)}:function(_){return _&&function(){return d.apply(_,arguments)}}},73626:(v,T,i)=>{var r=i(31864),u=i(25591),p=function(d){return u(d)?d:void 0};v.exports=function(d,e){return arguments.length<2?p(r[d]):r[d]&&r[d][e]}},63076:(v,T,i)=>{var r=i(99420),u=i(35642),p=i(37432),d=i(72339),_=i(84563)("iterator");v.exports=function(y){if(!p(y))return u(y,_)||u(y,"@@iterator")||d[r(y)]}},36414:(v,T,i)=>{var r=i(757),u=i(77340),p=i(21099),d=i(60802),e=i(63076),_=TypeError;v.exports=function(y,S){var A=arguments.length<2?e(y):S;if(u(A))return p(r(A,y));throw _(d(y)+" is not iterable")}},35642:(v,T,i)=>{var r=i(77340),u=i(37432);v.exports=function(p,d){var e=p[d];return u(e)?void 0:r(e)}},16162:(v,T,i)=>{var r=i(47964),u=i(16174),p=Math.floor,d=r("".charAt),e=r("".replace),_=r("".slice),y=/\$([$&'`]|\d{1,2}|<[^>]*>)/g,S=/\$([$&'`]|\d{1,2})/g;v.exports=function(A,N,L,Z,J,K){var ee=L+A.length,ue=Z.length,ae=S;return void 0!==J&&(J=u(J),ae=y),e(K,ae,function(H,se){var Ee;switch(d(se,0)){case"$":return"$";case"&":return A;case"`":return _(N,0,L);case"'":return _(N,ee);case"<":Ee=J[_(se,1,-1)];break;default:var ie=+se;if(0===ie)return H;if(ie>ue){var he=p(ie/10);return 0===he?H:he<=ue?void 0===Z[he-1]?d(se,1):Z[he-1]+d(se,1):H}Ee=Z[ie-1]}return void 0===Ee?"":Ee})}},31864:v=>{var T=function(i){return i&&i.Math==Math&&i};v.exports=T("object"==typeof globalThis&&globalThis)||T("object"==typeof window&&window)||T("object"==typeof self&&self)||T("object"==typeof global&&global)||function(){return this}()||Function("return this")()},62445:(v,T,i)=>{var r=i(47964),u=i(16174),p=r({}.hasOwnProperty);v.exports=Object.hasOwn||function(e,_){return p(u(e),_)}},3536:v=>{v.exports={}},67538:(v,T,i)=>{var r=i(73626);v.exports=r("document","documentElement")},27091:(v,T,i)=>{var r=i(47012),u=i(8597),p=i(85815);v.exports=!r&&!u(function(){return 7!=Object.defineProperty(p("div"),"a",{get:function(){return 7}}).a})},56169:(v,T,i)=>{var r=i(47964),u=i(8597),p=i(96644),d=Object,e=r("".split);v.exports=u(function(){return!d("z").propertyIsEnumerable(0)})?function(_){return"String"==p(_)?e(_,""):d(_)}:d},38267:(v,T,i)=>{var r=i(25591),u=i(60726),p=i(91464);v.exports=function(d,e,_){var y,S;return p&&r(y=e.constructor)&&y!==_&&u(S=y.prototype)&&S!==_.prototype&&p(d,S),d}},87720:(v,T,i)=>{var r=i(47964),u=i(25591),p=i(59941),d=r(Function.toString);u(p.inspectSource)||(p.inspectSource=function(e){return d(e)}),v.exports=p.inspectSource},64238:(v,T,i)=>{var r=i(51163),u=i(47964),p=i(3536),d=i(60726),e=i(62445),_=i(52975).f,y=i(94564),S=i(7388),A=i(67117),N=i(94295),L=i(39352),Z=!1,J=N("meta"),K=0,ee=function(ie){_(ie,J,{value:{objectID:"O"+K++,weakData:{}}})},Ee=v.exports={enable:function(){Ee.enable=function(){},Z=!0;var ie=y.f,he=u([].splice),ge={};ge[J]=1,ie(ge).length&&(y.f=function(De){for(var ce=ie(De),lt=0,Ve=ce.length;lt<Ve;lt++)if(ce[lt]===J){he(ce,lt,1);break}return ce},r({target:"Object",stat:!0,forced:!0},{getOwnPropertyNames:S.f}))},fastKey:function(ie,he){if(!d(ie))return"symbol"==typeof ie?ie:("string"==typeof ie?"S":"P")+ie;if(!e(ie,J)){if(!A(ie))return"F";if(!he)return"E";ee(ie)}return ie[J].objectID},getWeakData:function(ie,he){if(!e(ie,J)){if(!A(ie))return!0;if(!he)return!1;ee(ie)}return ie[J].weakData},onFreeze:function(ie){return L&&Z&&A(ie)&&!e(ie,J)&&ee(ie),ie}};p[J]=!0},52493:(v,T,i)=>{var J,K,ee,r=i(28095),u=i(31864),p=i(47964),d=i(60726),e=i(815),_=i(62445),y=i(59941),S=i(42650),A=i(3536),N="Object already initialized",L=u.TypeError;if(r||y.state){var H=y.state||(y.state=new(0,u.WeakMap)),se=p(H.get),Ee=p(H.has),ie=p(H.set);J=function(ge,De){if(Ee(H,ge))throw L(N);return De.facade=ge,ie(H,ge,De),De},K=function(ge){return se(H,ge)||{}},ee=function(ge){return Ee(H,ge)}}else{var he=S("state");A[he]=!0,J=function(ge,De){if(_(ge,he))throw L(N);return De.facade=ge,e(ge,he,De),De},K=function(ge){return _(ge,he)?ge[he]:{}},ee=function(ge){return _(ge,he)}}v.exports={set:J,get:K,has:ee,enforce:function(ge){return ee(ge)?K(ge):J(ge,{})},getterFor:function(ge){return function(De){var ce;if(!d(De)||(ce=K(De)).type!==ge)throw L("Incompatible receiver, "+ge+" required");return ce}}}},81643:(v,T,i)=>{var r=i(84563),u=i(72339),p=r("iterator"),d=Array.prototype;v.exports=function(e){return void 0!==e&&(u.Array===e||d[p]===e)}},47883:(v,T,i)=>{var r=i(96644);v.exports=Array.isArray||function(p){return"Array"==r(p)}},25591:v=>{v.exports=function(T){return"function"==typeof T}},57995:(v,T,i)=>{var r=i(47964),u=i(8597),p=i(25591),d=i(99420),e=i(73626),_=i(87720),y=function(){},S=[],A=e("Reflect","construct"),N=/^\s*(?:class|function)\b/,L=r(N.exec),Z=!N.exec(y),J=function(ue){if(!p(ue))return!1;try{return A(y,S,ue),!0}catch(ae){return!1}},K=function(ue){if(!p(ue))return!1;switch(d(ue)){case"AsyncFunction":case"GeneratorFunction":case"AsyncGeneratorFunction":return!1}try{return Z||!!L(N,_(ue))}catch(ae){return!0}};K.sham=!0,v.exports=!A||u(function(){var ee;return J(J.call)||!J(Object)||!J(function(){ee=!0})||ee})?K:J},87215:(v,T,i)=>{var r=i(8597),u=i(25591),p=/#|\.prototype\./,d=function(A,N){var L=_[e(A)];return L==S||L!=y&&(u(N)?r(N):!!N)},e=d.normalize=function(A){return String(A).replace(p,".").toLowerCase()},_=d.data={},y=d.NATIVE="N",S=d.POLYFILL="P";v.exports=d},37432:v=>{v.exports=function(T){return null==T}},60726:(v,T,i)=>{var r=i(25591),u="object"==typeof document&&document.all;v.exports=void 0===u&&void 0!==u?function(d){return"object"==typeof d?null!==d:r(d)||d===u}:function(d){return"object"==typeof d?null!==d:r(d)}},97515:v=>{v.exports=!1},26186:(v,T,i)=>{var r=i(73626),u=i(25591),p=i(93290),d=i(24431),e=Object;v.exports=d?function(_){return"symbol"==typeof _}:function(_){var y=r("Symbol");return u(y)&&p(y.prototype,e(_))}},53284:(v,T,i)=>{var r=i(29727),u=i(757),p=i(21099),d=i(60802),e=i(81643),_=i(24196),y=i(93290),S=i(36414),A=i(63076),N=i(87883),L=TypeError,Z=function(K,ee){this.stopped=K,this.result=ee},J=Z.prototype;v.exports=function(K,ee,ue){var ge,De,ce,lt,Ve,ze,Be,H=!(!ue||!ue.AS_ENTRIES),se=!(!ue||!ue.IS_RECORD),Ee=!(!ue||!ue.IS_ITERATOR),ie=!(!ue||!ue.INTERRUPTED),he=r(ee,ue&&ue.that),Pe=function(He){return ge&&N(ge,"normal",He),new Z(!0,He)},je=function(He){return H?(p(He),ie?he(He[0],He[1],Pe):he(He[0],He[1])):ie?he(He,Pe):he(He)};if(se)ge=K.iterator;else if(Ee)ge=K;else{if(!(De=A(K)))throw L(d(K)+" is not iterable");if(e(De)){for(ce=0,lt=_(K);lt>ce;ce++)if((Ve=je(K[ce]))&&y(J,Ve))return Ve;return new Z(!1)}ge=S(K,De)}for(ze=se?K.next:ge.next;!(Be=u(ze,ge)).done;){try{Ve=je(Be.value)}catch(He){N(ge,"throw",He)}if("object"==typeof Ve&&Ve&&y(J,Ve))return Ve}return new Z(!1)}},87883:(v,T,i)=>{var r=i(757),u=i(21099),p=i(35642);v.exports=function(d,e,_){var y,S;u(d);try{if(!(y=p(d,"return"))){if("throw"===e)throw _;return _}y=r(y,d)}catch(A){S=!0,y=A}if("throw"===e)throw _;if(S)throw y;return u(y),_}},30281:(v,T,i)=>{"use strict";var r=i(92053).IteratorPrototype,u=i(38724),p=i(53203),d=i(58242),e=i(72339),_=function(){return this};v.exports=function(y,S,A,N){var L=S+" Iterator";return y.prototype=u(r,{next:p(+!N,A)}),d(y,L,!1,!0),e[L]=_,y}},43291:(v,T,i)=>{"use strict";var r=i(51163),u=i(757),p=i(97515),d=i(20538),e=i(25591),_=i(30281),y=i(3963),S=i(91464),A=i(58242),N=i(815),L=i(70688),Z=i(84563),J=i(72339),K=i(92053),ee=d.PROPER,ue=d.CONFIGURABLE,ae=K.IteratorPrototype,H=K.BUGGY_SAFARI_ITERATORS,se=Z("iterator"),ie="values",he="entries",ge=function(){return this};v.exports=function(De,ce,lt,Ve,ze,Be,Pe){_(lt,ce,Ve);var Ut,Bt,bt,je=function(Gt){if(Gt===ze&&It)return It;if(!H&&Gt in it)return it[Gt];switch(Gt){case"keys":case ie:case he:return function(){return new lt(this,Gt)}}return function(){return new lt(this)}},He=ce+" Iterator",Vt=!1,it=De.prototype,tn=it[se]||it["@@iterator"]||ze&&it[ze],It=!H&&tn||je(ze),Zt="Array"==ce&&it.entries||tn;if(Zt&&(Ut=y(Zt.call(new De)))!==Object.prototype&&Ut.next&&(!p&&y(Ut)!==ae&&(S?S(Ut,ae):e(Ut[se])||L(Ut,se,ge)),A(Ut,He,!0,!0),p&&(J[He]=ge)),ee&&ze==ie&&tn&&tn.name!==ie&&(!p&&ue?N(it,"name",ie):(Vt=!0,It=function(){return u(tn,this)})),ze)if(Bt={values:je(ie),keys:Be?It:je("keys"),entries:je(he)},Pe)for(bt in Bt)(H||Vt||!(bt in it))&&L(it,bt,Bt[bt]);else r({target:ce,proto:!0,forced:H||Vt},Bt);return(!p||Pe)&&it[se]!==It&&L(it,se,It,{name:ze}),J[ce]=It,Bt}},92053:(v,T,i)=>{"use strict";var L,Z,J,r=i(8597),u=i(25591),p=i(60726),d=i(38724),e=i(3963),_=i(70688),y=i(84563),S=i(97515),A=y("iterator"),N=!1;[].keys&&("next"in(J=[].keys())?(Z=e(e(J)))!==Object.prototype&&(L=Z):N=!0),!p(L)||r(function(){var ee={};return L[A].call(ee)!==ee})?L={}:S&&(L=d(L)),u(L[A])||_(L,A,function(){return this}),v.exports={IteratorPrototype:L,BUGGY_SAFARI_ITERATORS:N}},72339:v=>{v.exports={}},24196:(v,T,i)=>{var r=i(15902);v.exports=function(u){return r(u.length)}},74952:(v,T,i)=>{var r=i(8597),u=i(25591),p=i(62445),d=i(47012),e=i(20538).CONFIGURABLE,_=i(87720),y=i(52493),S=y.enforce,A=y.get,N=Object.defineProperty,L=d&&!r(function(){return 8!==N(function(){},"length",{value:8}).length}),Z=String(String).split("String"),J=v.exports=function(K,ee,ue){"Symbol("===String(ee).slice(0,7)&&(ee="["+String(ee).replace(/^Symbol\(([^)]*)\)/,"$1")+"]"),ue&&ue.getter&&(ee="get "+ee),ue&&ue.setter&&(ee="set "+ee),(!p(K,"name")||e&&K.name!==ee)&&(d?N(K,"name",{value:ee,configurable:!0}):K.name=ee),L&&ue&&p(ue,"arity")&&K.length!==ue.arity&&N(K,"length",{value:ue.arity});try{ue&&p(ue,"constructor")&&ue.constructor?d&&N(K,"prototype",{writable:!1}):K.prototype&&(K.prototype=void 0)}catch(H){}var ae=S(K);return p(ae,"source")||(ae.source=Z.join("string"==typeof ee?ee:"")),K};Function.prototype.toString=J(function(){return u(this)&&A(this).source||_(this)},"toString")},58194:v=>{var T=Math.ceil,i=Math.floor;v.exports=Math.trunc||function(u){var p=+u;return(p>0?i:T)(p)}},43656:(v,T,i)=>{var r=i(31864),u=i(8597),p=i(47964),d=i(73574),e=i(51664).trim,_=i(48004),y=r.parseInt,S=r.Symbol,A=S&&S.iterator,N=/^[+-]?0x/i,L=p(N.exec),Z=8!==y(_+"08")||22!==y(_+"0x16")||A&&!u(function(){y(Object(A))});v.exports=Z?function(K,ee){var ue=e(d(K));return y(ue,ee>>>0||(L(N,ue)?16:10))}:y},51746:(v,T,i)=>{"use strict";var r=i(47012),u=i(47964),p=i(757),d=i(8597),e=i(68032),_=i(77593),y=i(5600),S=i(16174),A=i(56169),N=Object.assign,L=Object.defineProperty,Z=u([].concat);v.exports=!N||d(function(){if(r&&1!==N({b:1},N(L({},"a",{enumerable:!0,get:function(){L(this,"b",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var J={},K={},ee=Symbol(),ue="abcdefghijklmnopqrst";return J[ee]=7,ue.split("").forEach(function(ae){K[ae]=ae}),7!=N({},J)[ee]||e(N({},K)).join("")!=ue})?function(K,ee){for(var ue=S(K),ae=arguments.length,H=1,se=_.f,Ee=y.f;ae>H;)for(var ce,ie=A(arguments[H++]),he=se?Z(e(ie),se(ie)):e(ie),ge=he.length,De=0;ge>De;)ce=he[De++],(!r||p(Ee,ie,ce))&&(ue[ce]=ie[ce]);return ue}:N},38724:(v,T,i)=>{var ae,r=i(21099),u=i(10988),p=i(71001),d=i(3536),e=i(67538),_=i(85815),y=i(42650),N="prototype",L="script",Z=y("IE_PROTO"),J=function(){},K=function(se){return"<"+L+">"+se+"</"+L+">"},ee=function(se){se.write(K("")),se.close();var Ee=se.parentWindow.Object;return se=null,Ee},H=function(){try{ae=new ActiveXObject("htmlfile")}catch(Ee){}H="undefined"!=typeof document?document.domain&&ae?ee(ae):function(){var ie,se=_("iframe");return se.style.display="none",e.appendChild(se),se.src=String("javascript:"),(ie=se.contentWindow.document).open(),ie.write(K("document.F=Object")),ie.close(),ie.F}():ee(ae);for(var se=p.length;se--;)delete H[N][p[se]];return H()};d[Z]=!0,v.exports=Object.create||function(Ee,ie){var he;return null!==Ee?(J[N]=r(Ee),he=new J,J[N]=null,he[Z]=Ee):he=H(),void 0===ie?he:u.f(he,ie)}},10988:(v,T,i)=>{var r=i(47012),u=i(52339),p=i(52975),d=i(21099),e=i(8643),_=i(68032);T.f=r&&!u?Object.defineProperties:function(S,A){d(S);for(var K,N=e(A),L=_(A),Z=L.length,J=0;Z>J;)p.f(S,K=L[J++],N[K]);return S}},52975:(v,T,i)=>{var r=i(47012),u=i(27091),p=i(52339),d=i(21099),e=i(16582),_=TypeError,y=Object.defineProperty,S=Object.getOwnPropertyDescriptor,A="enumerable",N="configurable",L="writable";T.f=r?p?function(J,K,ee){if(d(J),K=e(K),d(ee),"function"==typeof J&&"prototype"===K&&"value"in ee&&L in ee&&!ee[L]){var ue=S(J,K);ue&&ue[L]&&(J[K]=ee.value,ee={configurable:N in ee?ee[N]:ue[N],enumerable:A in ee?ee[A]:ue[A],writable:!1})}return y(J,K,ee)}:y:function(J,K,ee){if(d(J),K=e(K),d(ee),u)try{return y(J,K,ee)}catch(ue){}if("get"in ee||"set"in ee)throw _("Accessors not supported");return"value"in ee&&(J[K]=ee.value),J}},93099:(v,T,i)=>{var r=i(47012),u=i(757),p=i(5600),d=i(53203),e=i(8643),_=i(16582),y=i(62445),S=i(27091),A=Object.getOwnPropertyDescriptor;T.f=r?A:function(L,Z){if(L=e(L),Z=_(Z),S)try{return A(L,Z)}catch(J){}if(y(L,Z))return d(!u(p.f,L,Z),L[Z])}},7388:(v,T,i)=>{var r=i(96644),u=i(8643),p=i(94564).f,d=i(32342),e="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];v.exports.f=function(S){return e&&"Window"==r(S)?function(y){try{return p(y)}catch(S){return d(e)}}(S):p(u(S))}},94564:(v,T,i)=>{var r=i(77759),p=i(71001).concat("length","prototype");T.f=Object.getOwnPropertyNames||function(e){return r(e,p)}},77593:(v,T)=>{T.f=Object.getOwnPropertySymbols},3963:(v,T,i)=>{var r=i(62445),u=i(25591),p=i(16174),d=i(42650),e=i(51335),_=d("IE_PROTO"),y=Object,S=y.prototype;v.exports=e?y.getPrototypeOf:function(A){var N=p(A);if(r(N,_))return N[_];var L=N.constructor;return u(L)&&N instanceof L?L.prototype:N instanceof y?S:null}},67117:(v,T,i)=>{var r=i(8597),u=i(60726),p=i(96644),d=i(93241),e=Object.isExtensible,_=r(function(){e(1)});v.exports=_||d?function(S){return!(!u(S)||d&&"ArrayBuffer"==p(S))&&(!e||e(S))}:e},93290:(v,T,i)=>{var r=i(47964);v.exports=r({}.isPrototypeOf)},77759:(v,T,i)=>{var r=i(47964),u=i(62445),p=i(8643),d=i(70452).indexOf,e=i(3536),_=r([].push);v.exports=function(y,S){var Z,A=p(y),N=0,L=[];for(Z in A)!u(e,Z)&&u(A,Z)&&_(L,Z);for(;S.length>N;)u(A,Z=S[N++])&&(~d(L,Z)||_(L,Z));return L}},68032:(v,T,i)=>{var r=i(77759),u=i(71001);v.exports=Object.keys||function(d){return r(d,u)}},5600:(v,T)=>{"use strict";var i={}.propertyIsEnumerable,r=Object.getOwnPropertyDescriptor,u=r&&!i.call({1:2},1);T.f=u?function(d){var e=r(this,d);return!!e&&e.enumerable}:i},91464:(v,T,i)=>{var r=i(47964),u=i(21099),p=i(95143);v.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var _,d=!1,e={};try{(_=r(Object.getOwnPropertyDescriptor(Object.prototype,"__proto__").set))(e,[]),d=e instanceof Array}catch(y){}return function(S,A){return u(S),p(A),d?_(S,A):S.__proto__=A,S}}():void 0)},83119:(v,T,i)=>{"use strict";var r=i(72900),u=i(99420);v.exports=r?{}.toString:function(){return"[object "+u(this)+"]"}},48297:(v,T,i)=>{var r=i(757),u=i(25591),p=i(60726),d=TypeError;v.exports=function(e,_){var y,S;if("string"===_&&u(y=e.toString)&&!p(S=r(y,e))||u(y=e.valueOf)&&!p(S=r(y,e))||"string"!==_&&u(y=e.toString)&&!p(S=r(y,e)))return S;throw d("Can't convert object to primitive value")}},99376:(v,T,i)=>{var r=i(73626),u=i(47964),p=i(94564),d=i(77593),e=i(21099),_=u([].concat);v.exports=r("Reflect","ownKeys")||function(S){var A=p.f(e(S)),N=d.f;return N?_(A,N(S)):A}},53793:(v,T,i)=>{var r=i(757),u=i(21099),p=i(25591),d=i(96644),e=i(93084),_=TypeError;v.exports=function(y,S){var A=y.exec;if(p(A)){var N=r(A,y,S);return null!==N&&u(N),N}if("RegExp"===d(y))return r(e,y,S);throw _("RegExp#exec called on incompatible receiver")}},93084:(v,T,i)=>{"use strict";var he,ge,r=i(757),u=i(47964),p=i(73574),d=i(41891),e=i(29895),_=i(77719),y=i(38724),S=i(52493).get,A=i(38126),N=i(31053),L=_("native-string-replace",String.prototype.replace),Z=RegExp.prototype.exec,J=Z,K=u("".charAt),ee=u("".indexOf),ue=u("".replace),ae=u("".slice),H=(ge=/b*/g,r(Z,he=/a/,"a"),r(Z,ge,"a"),0!==he.lastIndex||0!==ge.lastIndex),se=e.BROKEN_CARET,Ee=void 0!==/()??/.exec("")[1];(H||Ee||se||A||N)&&(J=function(ge){var ze,Be,Pe,je,He,Vt,it,De=this,ce=S(De),lt=p(ge),Ve=ce.raw;if(Ve)return Ve.lastIndex=De.lastIndex,ze=r(J,Ve,lt),De.lastIndex=Ve.lastIndex,ze;var tn=ce.groups,It=se&&De.sticky,Zt=r(d,De),Ut=De.source,Bt=0,bt=lt;if(It&&(Zt=ue(Zt,"y",""),-1===ee(Zt,"g")&&(Zt+="g"),bt=ae(lt,De.lastIndex),De.lastIndex>0&&(!De.multiline||De.multiline&&"\n"!==K(lt,De.lastIndex-1))&&(Ut="(?: "+Ut+")",bt=" "+bt,Bt++),Be=new RegExp("^(?:"+Ut+")",Zt)),Ee&&(Be=new RegExp("^"+Ut+"$(?!\\s)",Zt)),H&&(Pe=De.lastIndex),je=r(Z,It?Be:De,bt),It?je?(je.input=ae(je.input,Bt),je[0]=ae(je[0],Bt),je.index=De.lastIndex,De.lastIndex+=je[0].length):De.lastIndex=0:H&&je&&(De.lastIndex=De.global?je.index+je[0].length:Pe),Ee&&je&&je.length>1&&r(L,je[0],Be,function(){for(He=1;He<arguments.length-2;He++)void 0===arguments[He]&&(je[He]=void 0)}),je&&tn)for(je.groups=Vt=y(null),He=0;He<tn.length;He++)Vt[(it=tn[He])[0]]=je[it[1]];return je}),v.exports=J},41891:(v,T,i)=>{"use strict";var r=i(21099);v.exports=function(){var u=r(this),p="";return u.hasIndices&&(p+="d"),u.global&&(p+="g"),u.ignoreCase&&(p+="i"),u.multiline&&(p+="m"),u.dotAll&&(p+="s"),u.unicode&&(p+="u"),u.unicodeSets&&(p+="v"),u.sticky&&(p+="y"),p}},29895:(v,T,i)=>{var r=i(8597),p=i(31864).RegExp,d=r(function(){var y=p("a","y");return y.lastIndex=2,null!=y.exec("abcd")}),e=d||r(function(){return!p("a","y").sticky}),_=d||r(function(){var y=p("^r","gy");return y.lastIndex=2,null!=y.exec("str")});v.exports={BROKEN_CARET:_,MISSED_STICKY:e,UNSUPPORTED_Y:d}},38126:(v,T,i)=>{var r=i(8597),p=i(31864).RegExp;v.exports=r(function(){var d=p(".","s");return!(d.dotAll&&d.exec("\n")&&"s"===d.flags)})},31053:(v,T,i)=>{var r=i(8597),p=i(31864).RegExp;v.exports=r(function(){var d=p("(?<a>b)","g");return"b"!==d.exec("b").groups.a||"bc"!=="b".replace(d,"$<a>c")})},95025:(v,T,i)=>{var r=i(37432),u=TypeError;v.exports=function(p){if(r(p))throw u("Can't call method on "+p);return p}},58242:(v,T,i)=>{var r=i(52975).f,u=i(62445),d=i(84563)("toStringTag");v.exports=function(e,_,y){e&&!y&&(e=e.prototype),e&&!u(e,d)&&r(e,d,{configurable:!0,value:_})}},42650:(v,T,i)=>{var r=i(77719),u=i(94295),p=r("keys");v.exports=function(d){return p[d]||(p[d]=u(d))}},59941:(v,T,i)=>{var r=i(31864),u=i(11996),p="__core-js_shared__",d=r[p]||u(p,{});v.exports=d},77719:(v,T,i)=>{var r=i(97515),u=i(59941);(v.exports=function(p,d){return u[p]||(u[p]=void 0!==d?d:{})})("versions",[]).push({version:"3.25.1",mode:r?"pure":"global",copyright:"\xa9 2014-2022 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.25.1/LICENSE",source:"https://github.com/zloirock/core-js"})},64487:(v,T,i)=>{var r=i(47964),u=i(22157),p=i(73574),d=i(95025),e=r("".charAt),_=r("".charCodeAt),y=r("".slice),S=function(A){return function(N,L){var ee,ue,Z=p(d(N)),J=u(L),K=Z.length;return J<0||J>=K?A?"":void 0:(ee=_(Z,J))<55296||ee>56319||J+1===K||(ue=_(Z,J+1))<56320||ue>57343?A?e(Z,J):ee:A?y(Z,J,J+2):ue-56320+(ee-55296<<10)+65536}};v.exports={codeAt:S(!1),charAt:S(!0)}},51664:(v,T,i)=>{var r=i(47964),u=i(95025),p=i(73574),d=i(48004),e=r("".replace),_="["+d+"]",y=RegExp("^"+_+_+"*"),S=RegExp(_+_+"*$"),A=function(N){return function(L){var Z=p(u(L));return 1&N&&(Z=e(Z,y,"")),2&N&&(Z=e(Z,S,"")),Z}};v.exports={start:A(1),end:A(2),trim:A(3)}},33021:(v,T,i)=>{var r=i(17189),u=i(8597);v.exports=!!Object.getOwnPropertySymbols&&!u(function(){var p=Symbol();return!String(p)||!(Object(p)instanceof Symbol)||!Symbol.sham&&r&&r<41})},20222:(v,T,i)=>{var r=i(22157),u=Math.max,p=Math.min;v.exports=function(d,e){var _=r(d);return _<0?u(_+e,0):p(_,e)}},8643:(v,T,i)=>{var r=i(56169),u=i(95025);v.exports=function(p){return r(u(p))}},22157:(v,T,i)=>{var r=i(58194);v.exports=function(u){var p=+u;return p!=p||0===p?0:r(p)}},15902:(v,T,i)=>{var r=i(22157),u=Math.min;v.exports=function(p){return p>0?u(r(p),9007199254740991):0}},16174:(v,T,i)=>{var r=i(95025),u=Object;v.exports=function(p){return u(r(p))}},28495:(v,T,i)=>{var r=i(757),u=i(60726),p=i(26186),d=i(35642),e=i(48297),_=i(84563),y=TypeError,S=_("toPrimitive");v.exports=function(A,N){if(!u(A)||p(A))return A;var Z,L=d(A,S);if(L){if(void 0===N&&(N="default"),Z=r(L,A,N),!u(Z)||p(Z))return Z;throw y("Can't convert object to primitive value")}return void 0===N&&(N="number"),e(A,N)}},16582:(v,T,i)=>{var r=i(28495),u=i(26186);v.exports=function(p){var d=r(p,"string");return u(d)?d:d+""}},72900:(v,T,i)=>{var p={};p[i(84563)("toStringTag")]="z",v.exports="[object z]"===String(p)},73574:(v,T,i)=>{var r=i(99420),u=String;v.exports=function(p){if("Symbol"===r(p))throw TypeError("Cannot convert a Symbol value to a string");return u(p)}},60802:v=>{var T=String;v.exports=function(i){try{return T(i)}catch(r){return"Object"}}},94295:(v,T,i)=>{var r=i(47964),u=0,p=Math.random(),d=r(1..toString);v.exports=function(e){return"Symbol("+(void 0===e?"":e)+")_"+d(++u+p,36)}},24431:(v,T,i)=>{var r=i(33021);v.exports=r&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},52339:(v,T,i)=>{var r=i(47012),u=i(8597);v.exports=r&&u(function(){return 42!=Object.defineProperty(function(){},"prototype",{value:42,writable:!1}).prototype})},28095:(v,T,i)=>{var r=i(31864),u=i(25591),p=r.WeakMap;v.exports=u(p)&&/native code/.test(String(p))},84563:(v,T,i)=>{var r=i(31864),u=i(77719),p=i(62445),d=i(94295),e=i(33021),_=i(24431),y=u("wks"),S=r.Symbol,A=S&&S.for,N=_?S:S&&S.withoutSetter||d;v.exports=function(L){if(!p(y,L)||!e&&"string"!=typeof y[L]){var Z="Symbol."+L;y[L]=e&&p(S,L)?S[L]:_&&A?A(Z):N(Z)}return y[L]}},48004:v=>{v.exports="\t\n\v\f\r \xa0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff"},85443:(v,T,i)=>{"use strict";var r=i(51163),u=i(94115).filter;r({target:"Array",proto:!0,forced:!i(37394)("filter")},{filter:function(_){return u(this,_,arguments.length>1?arguments[1]:void 0)}})},66837:(v,T,i)=>{"use strict";var r=i(8643),u=i(24094),p=i(72339),d=i(52493),e=i(52975).f,_=i(43291),y=i(15189),S=i(97515),A=i(47012),N="Array Iterator",L=d.set,Z=d.getterFor(N);v.exports=_(Array,"Array",function(K,ee){L(this,{type:N,target:r(K),index:0,kind:ee})},function(){var K=Z(this),ee=K.target,ue=K.kind,ae=K.index++;return!ee||ae>=ee.length?(K.target=void 0,y(void 0,!0)):y("keys"==ue?ae:"values"==ue?ee[ae]:[ae,ee[ae]],!1)},"values");var J=p.Arguments=p.Array;if(u("keys"),u("values"),u("entries"),!S&&A&&"values"!==J.name)try{e(J,"name",{value:"values"})}catch(K){}},35319:(v,T,i)=>{"use strict";var r=i(51163),u=i(14716).left,p=i(47051),d=i(17189),e=i(32002);r({target:"Array",proto:!0,forced:!p("reduce")||!e&&d>79&&d<83},{reduce:function(A){var N=arguments.length;return u(this,A,N,N>1?arguments[1]:void 0)}})},80477:(v,T,i)=>{var r=i(47012),u=i(20538).EXISTS,p=i(47964),d=i(52975).f,e=Function.prototype,_=p(e.toString),y=/function\b(?:\s|\/\*[\S\s]*?\*\/|\/\/[^\n\r]*[\n\r]+)*([^\s(/]*)/,S=p(y.exec);r&&!u&&d(e,"name",{configurable:!0,get:function(){try{return S(y,_(this))[1]}catch(N){return""}}})},8868:(v,T,i)=>{var r=i(51163),u=i(51746);r({target:"Object",stat:!0,arity:2,forced:Object.assign!==u},{assign:u})},35704:(v,T,i)=>{var r=i(72900),u=i(70688),p=i(83119);r||u(Object.prototype,"toString",p,{unsafe:!0})},21581:(v,T,i)=>{var r=i(51163),u=i(43656);r({global:!0,forced:parseInt!=u},{parseInt:u})},69665:(v,T,i)=>{"use strict";var r=i(51163),u=i(93084);r({target:"RegExp",proto:!0,forced:/./.exec!==u},{exec:u})},13744:(v,T,i)=>{"use strict";var r=i(64487).charAt,u=i(73574),p=i(52493),d=i(43291),e=i(15189),_="String Iterator",y=p.set,S=p.getterFor(_);d(String,"String",function(A){y(this,{type:_,string:u(A),index:0})},function(){var J,N=S(this),L=N.string,Z=N.index;return Z>=L.length?e(void 0,!0):(J=r(L,Z),N.index+=J.length,e(J,!1))})},26954:(v,T,i)=>{"use strict";var r=i(757),u=i(9357),p=i(21099),d=i(37432),e=i(15902),_=i(73574),y=i(95025),S=i(35642),A=i(27678),N=i(53793);u("match",function(L,Z,J){return[function(ee){var ue=y(this),ae=d(ee)?void 0:S(ee,L);return ae?r(ae,ee,ue):new RegExp(ee)[L](_(ue))},function(K){var ee=p(this),ue=_(K),ae=J(Z,ee,ue);if(ae.done)return ae.value;if(!ee.global)return N(ee,ue);var H=ee.unicode;ee.lastIndex=0;for(var ie,se=[],Ee=0;null!==(ie=N(ee,ue));){var he=_(ie[0]);se[Ee]=he,""===he&&(ee.lastIndex=A(ue,e(ee.lastIndex),H)),Ee++}return 0===Ee?null:se}]})},66262:(v,T,i)=>{"use strict";var r=i(32328),u=i(757),p=i(47964),d=i(9357),e=i(8597),_=i(21099),y=i(25591),S=i(37432),A=i(22157),N=i(15902),L=i(73574),Z=i(95025),J=i(27678),K=i(35642),ee=i(16162),ue=i(53793),H=i(84563)("replace"),se=Math.max,Ee=Math.min,ie=p([].concat),he=p([].push),ge=p("".indexOf),De=p("".slice),ce=function(Be){return void 0===Be?Be:String(Be)},lt="$0"==="a".replace(/./,"$0"),Ve=!!/./[H]&&""===/./[H]("a","$0");d("replace",function(Be,Pe,je){var He=Ve?"$":"$0";return[function(it,tn){var It=Z(this),Zt=S(it)?void 0:K(it,H);return Zt?u(Zt,it,It,tn):u(Pe,L(It),it,tn)},function(Vt,it){var tn=_(this),It=L(Vt);if("string"==typeof it&&-1===ge(it,He)&&-1===ge(it,"$<")){var Zt=je(Pe,tn,It,it);if(Zt.done)return Zt.value}var Ut=y(it);Ut||(it=L(it));var Bt=tn.global;if(Bt){var bt=tn.unicode;tn.lastIndex=0}for(var Gt=[];;){var xt=ue(tn,It);if(null===xt||(he(Gt,xt),!Bt))break;""===L(xt[0])&&(tn.lastIndex=J(It,N(tn.lastIndex),bt))}for(var Zn="",Ur=0,di=0;di<Gt.length;di++){for(var Lr=L((xt=Gt[di])[0]),Mr=se(Ee(A(xt.index),It.length),0),Kr=[],ei=1;ei<xt.length;ei++)he(Kr,ce(xt[ei]));var Nn=xt.groups;if(Ut){var $n=ie([Lr],Kr,Mr,It);void 0!==Nn&&he($n,Nn);var Br=L(r(it,void 0,$n))}else Br=ee(Lr,It,Mr,Kr,Nn,it);Mr>=Ur&&(Zn+=De(It,Ur,Mr)+Br,Ur=Mr+Lr.length)}return Zn+De(It,Ur)}]},!!e(function(){var Be=/./;return Be.exec=function(){var Pe=[];return Pe.groups={a:"7"},Pe},"7"!=="".replace(Be,"$<a>")})||!lt||Ve)},62913:(v,T,i)=>{"use strict";var Z,r=i(31864),u=i(47964),p=i(41292),d=i(64238),e=i(41603),_=i(96491),y=i(60726),S=i(67117),A=i(52493).enforce,N=i(28095),L=!r.ActiveXObject&&"ActiveXObject"in r,J=function(Ee){return function(){return Ee(this,arguments.length?arguments[0]:void 0)}},K=e("WeakMap",J,_);if(N&&L){Z=_.getConstructor(J,"WeakMap",!0),d.enable();var ee=K.prototype,ue=u(ee.delete),ae=u(ee.has),H=u(ee.get),se=u(ee.set);p(ee,{delete:function(Ee){if(y(Ee)&&!S(Ee)){var ie=A(this);return ie.frozen||(ie.frozen=new Z),ue(this,Ee)||ie.frozen.delete(Ee)}return ue(this,Ee)},has:function(ie){if(y(ie)&&!S(ie)){var he=A(this);return he.frozen||(he.frozen=new Z),ae(this,ie)||he.frozen.has(ie)}return ae(this,ie)},get:function(ie){if(y(ie)&&!S(ie)){var he=A(this);return he.frozen||(he.frozen=new Z),ae(this,ie)?H(this,ie):he.frozen.get(ie)}return H(this,ie)},set:function(ie,he){if(y(ie)&&!S(ie)){var ge=A(this);ge.frozen||(ge.frozen=new Z),ae(this,ie)?se(this,ie,he):ge.frozen.set(ie,he)}else se(this,ie,he);return this}})}},63438:(v,T,i)=>{i(62913)},22603:(v,T,i)=>{var r=i(31864),u=i(26877),p=i(20713),d=i(66837),e=i(815),_=i(84563),y=_("iterator"),S=_("toStringTag"),A=d.values,N=function(Z,J){if(Z){if(Z[y]!==A)try{e(Z,y,A)}catch(ee){Z[y]=A}if(Z[S]||e(Z,S,J),u[J])for(var K in d)if(Z[K]!==d[K])try{e(Z,K,d[K])}catch(ee){Z[K]=d[K]}}};for(var L in u)N(r[L]&&r[L].prototype,L);N(p,"DOMTokenList")},64762:(v,T,i)=>{"use strict";i.d(T,{ZT:()=>u,pi:()=>p,_T:()=>d,gn:()=>e,fM:()=>_,w6:()=>y});var r=function(Ve,ze){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(Be,Pe){Be.__proto__=Pe}||function(Be,Pe){for(var je in Pe)Object.prototype.hasOwnProperty.call(Pe,je)&&(Be[je]=Pe[je])})(Ve,ze)};function u(Ve,ze){if("function"!=typeof ze&&null!==ze)throw new TypeError("Class extends value "+String(ze)+" is not a constructor or null");function Be(){this.constructor=Ve}r(Ve,ze),Ve.prototype=null===ze?Object.create(ze):(Be.prototype=ze.prototype,new Be)}var p=function(){return(p=Object.assign||function(ze){for(var Be,Pe=1,je=arguments.length;Pe<je;Pe++)for(var He in Be=arguments[Pe])Object.prototype.hasOwnProperty.call(Be,He)&&(ze[He]=Be[He]);return ze}).apply(this,arguments)};function d(Ve,ze){var Be={};for(var Pe in Ve)Object.prototype.hasOwnProperty.call(Ve,Pe)&&ze.indexOf(Pe)<0&&(Be[Pe]=Ve[Pe]);if(null!=Ve&&"function"==typeof Object.getOwnPropertySymbols){var je=0;for(Pe=Object.getOwnPropertySymbols(Ve);je<Pe.length;je++)ze.indexOf(Pe[je])<0&&Object.prototype.propertyIsEnumerable.call(Ve,Pe[je])&&(Be[Pe[je]]=Ve[Pe[je]])}return Be}function e(Ve,ze,Be,Pe){var Vt,je=arguments.length,He=je<3?ze:null===Pe?Pe=Object.getOwnPropertyDescriptor(ze,Be):Pe;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)He=Reflect.decorate(Ve,ze,Be,Pe);else for(var it=Ve.length-1;it>=0;it--)(Vt=Ve[it])&&(He=(je<3?Vt(He):je>3?Vt(ze,Be,He):Vt(ze,Be))||He);return je>3&&He&&Object.defineProperty(ze,Be,He),He}function _(Ve,ze){return function(Be,Pe){ze(Be,Pe,Ve)}}function y(Ve,ze){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(Ve,ze)}},46700:(v,T,i)=>{var r={"./af":26431,"./af.js":26431,"./ar":81286,"./ar-dz":1616,"./ar-dz.js":1616,"./ar-kw":9759,"./ar-kw.js":9759,"./ar-ly":43160,"./ar-ly.js":43160,"./ar-ma":62551,"./ar-ma.js":62551,"./ar-sa":79989,"./ar-sa.js":79989,"./ar-tn":6962,"./ar-tn.js":6962,"./ar.js":81286,"./az":15887,"./az.js":15887,"./be":14572,"./be.js":14572,"./bg":3276,"./bg.js":3276,"./bm":93344,"./bm.js":93344,"./bn":58985,"./bn-bd":83990,"./bn-bd.js":83990,"./bn.js":58985,"./bo":94391,"./bo.js":94391,"./br":46728,"./br.js":46728,"./bs":5536,"./bs.js":5536,"./ca":41043,"./ca.js":41043,"./cs":70420,"./cs.js":70420,"./cv":33513,"./cv.js":33513,"./cy":6771,"./cy.js":6771,"./da":47978,"./da.js":47978,"./de":46061,"./de-at":25204,"./de-at.js":25204,"./de-ch":2653,"./de-ch.js":2653,"./de.js":46061,"./dv":85,"./dv.js":85,"./el":8579,"./el.js":8579,"./en-au":25724,"./en-au.js":25724,"./en-ca":10525,"./en-ca.js":10525,"./en-gb":52847,"./en-gb.js":52847,"./en-ie":67216,"./en-ie.js":67216,"./en-il":39305,"./en-il.js":39305,"./en-in":73364,"./en-in.js":73364,"./en-nz":79130,"./en-nz.js":79130,"./en-sg":11161,"./en-sg.js":11161,"./eo":50802,"./eo.js":50802,"./es":40328,"./es-do":45551,"./es-do.js":45551,"./es-mx":75615,"./es-mx.js":75615,"./es-us":64790,"./es-us.js":64790,"./es.js":40328,"./et":96389,"./et.js":96389,"./eu":52961,"./eu.js":52961,"./fa":26151,"./fa.js":26151,"./fi":7997,"./fi.js":7997,"./fil":58898,"./fil.js":58898,"./fo":37779,"./fo.js":37779,"./fr":28174,"./fr-ca":3287,"./fr-ca.js":3287,"./fr-ch":38867,"./fr-ch.js":38867,"./fr.js":28174,"./fy":50452,"./fy.js":50452,"./ga":45014,"./ga.js":45014,"./gd":74127,"./gd.js":74127,"./gl":72124,"./gl.js":72124,"./gom-deva":6444,"./gom-deva.js":6444,"./gom-latn":37953,"./gom-latn.js":37953,"./gu":76604,"./gu.js":76604,"./he":1222,"./he.js":1222,"./hi":74235,"./hi.js":74235,"./hr":622,"./hr.js":622,"./hu":37735,"./hu.js":37735,"./hy-am":90402,"./hy-am.js":90402,"./id":59187,"./id.js":59187,"./is":30536,"./is.js":30536,"./it":35007,"./it-ch":94667,"./it-ch.js":94667,"./it.js":35007,"./ja":62093,"./ja.js":62093,"./jv":80059,"./jv.js":80059,"./ka":66870,"./ka.js":66870,"./kk":80880,"./kk.js":80880,"./km":1083,"./km.js":1083,"./kn":68785,"./kn.js":68785,"./ko":21721,"./ko.js":21721,"./ku":37851,"./ku.js":37851,"./ky":1727,"./ky.js":1727,"./lb":40346,"./lb.js":40346,"./lo":93002,"./lo.js":93002,"./lt":64035,"./lt.js":64035,"./lv":56927,"./lv.js":56927,"./me":5634,"./me.js":5634,"./mi":94173,"./mi.js":94173,"./mk":86320,"./mk.js":86320,"./ml":11705,"./ml.js":11705,"./mn":31062,"./mn.js":31062,"./mr":92805,"./mr.js":92805,"./ms":11341,"./ms-my":59900,"./ms-my.js":59900,"./ms.js":11341,"./mt":37734,"./mt.js":37734,"./my":19034,"./my.js":19034,"./nb":9324,"./nb.js":9324,"./ne":46495,"./ne.js":46495,"./nl":70673,"./nl-be":76272,"./nl-be.js":76272,"./nl.js":70673,"./nn":72486,"./nn.js":72486,"./oc-lnc":46219,"./oc-lnc.js":46219,"./pa-in":2829,"./pa-in.js":2829,"./pl":78444,"./pl.js":78444,"./pt":53170,"./pt-br":66117,"./pt-br.js":66117,"./pt.js":53170,"./ro":96587,"./ro.js":96587,"./ru":39264,"./ru.js":39264,"./sd":42135,"./sd.js":42135,"./se":95366,"./se.js":95366,"./si":93379,"./si.js":93379,"./sk":46143,"./sk.js":46143,"./sl":196,"./sl.js":196,"./sq":21082,"./sq.js":21082,"./sr":91621,"./sr-cyrl":98963,"./sr-cyrl.js":98963,"./sr.js":91621,"./ss":41404,"./ss.js":41404,"./sv":55685,"./sv.js":55685,"./sw":3872,"./sw.js":3872,"./ta":54106,"./ta.js":54106,"./te":39204,"./te.js":39204,"./tet":83692,"./tet.js":83692,"./tg":86361,"./tg.js":86361,"./th":31735,"./th.js":31735,"./tk":1568,"./tk.js":1568,"./tl-ph":96129,"./tl-ph.js":96129,"./tlh":13759,"./tlh.js":13759,"./tr":81644,"./tr.js":81644,"./tzl":90875,"./tzl.js":90875,"./tzm":16878,"./tzm-latn":11041,"./tzm-latn.js":11041,"./tzm.js":16878,"./ug-cn":74357,"./ug-cn.js":74357,"./uk":74810,"./uk.js":74810,"./ur":86794,"./ur.js":86794,"./uz":28966,"./uz-latn":77959,"./uz-latn.js":77959,"./uz.js":28966,"./vi":35386,"./vi.js":35386,"./x-pseudo":23156,"./x-pseudo.js":23156,"./yo":68028,"./yo.js":68028,"./zh-cn":9330,"./zh-cn.js":9330,"./zh-hk":89380,"./zh-hk.js":89380,"./zh-mo":60874,"./zh-mo.js":60874,"./zh-tw":96508,"./zh-tw.js":96508};function u(d){var e=p(d);return i(e)}function p(d){if(!i.o(r,d)){var e=new Error("Cannot find module '"+d+"'");throw e.code="MODULE_NOT_FOUND",e}return r[d]}u.keys=function(){return Object.keys(r)},u.resolve=p,v.exports=u,u.id=46700},24654:()=>{},30071:(v,T,i)=>{v.exports=i(75242)},58711:(v,T,i)=>{v.exports=i(10323)},14226:(v,T,i)=>{v.exports=i(38762)},15886:(v,T,i)=>{v.exports=i(71873)},34377:(v,T,i)=>{v.exports=i(61599)},28086:(v,T,i)=>{v.exports=i(34097)},56166:(v,T,i)=>{v.exports=i(15149)},48129:(v,T,i)=>{v.exports=i(83361)},10068:(v,T,i)=>{v.exports=i(19095)},45163:(v,T,i)=>{v.exports=i(71420)},45819:(v,T,i)=>{v.exports=i(13178)},84901:(v,T,i)=>{v.exports=i(52049)},35524:(v,T,i)=>{v.exports=i(83655)},71851:(v,T,i)=>{v.exports=i(87054)},91465:(v,T,i)=>{v.exports=i(51946)},95327:(v,T,i)=>{v.exports=i(40764)},37940:(v,T,i)=>{v.exports=i(81214)},35431:(v,T,i)=>{v.exports=i(50881)},53757:(v,T,i)=>{v.exports=i(38813)},46558:(v,T,i)=>{v.exports=i(70157)},53625:(v,T,i)=>{v.exports=i(3502)},31978:(v,T,i)=>{v.exports=i(81610)},33814:(v,T,i)=>{v.exports=i(19543)},84220:(v,T,i)=>{v.exports=i(74046)},40984:(v,T,i)=>{v.exports=i(13731)},32322:(v,T,i)=>{v.exports=i(80129)},44859:(v,T,i)=>{v.exports=i(43720)},54082:(v,T,i)=>{v.exports=i(640)},30508:(v,T,i)=>{v.exports=i(50320)},15865:(v,T,i)=>{v.exports=i(15554)},46245:(v,T,i)=>{v.exports=i(1162)},69605:(v,T,i)=>{v.exports=i(70809)},86413:(v,T,i)=>{v.exports=i(26498)},87513:(v,T,i)=>{v.exports=i(12118)},71455:(v,T,i)=>{v.exports=i(44675)},69253:(v,T,i)=>{v.exports=i(70906)},17015:(v,T,i)=>{v.exports=i(95050)},8225:(v,T,i)=>{v.exports=i(56286)},64975:(v,T,i)=>{v.exports=i(54153)},66627:(v,T,i)=>{v.exports=i(90755)},24677:(v,T,i)=>{v.exports=i(60833)},68645:(v,T,i)=>{v.exports=i(98235)},14306:(v,T,i)=>{v.exports=i(78096)},6379:(v,T,i)=>{v.exports=i(31236)},72632:(v,T,i)=>{v.exports=i(15819)},28033:(v,T,i)=>{v.exports=i(44948)},19621:(v,T,i)=>{v.exports=i(96471)},54839:(v,T,i)=>{v.exports=i(5228)},95343:(v,T,i)=>{v.exports=i(50182)},73921:(v,T,i)=>{v.exports=i(41171)},70891:(v,T,i)=>{v.exports=i(54585)},77576:(v,T,i)=>{v.exports=i(62005)},45862:(v,T,i)=>{v.exports=i(39964)},51134:(v,T,i)=>{v.exports=i(70326)},23591:(v,T,i)=>{v.exports=i(98162)},76593:(v,T,i)=>{v.exports=i(42346)},22714:(v,T,i)=>{v.exports=i(4204)},62734:(v,T,i)=>{v.exports=i(24329)},69138:(v,T,i)=>{v.exports=i(2793)},69244:(v,T,i)=>{v.exports=i(42700)},15805:(v,T,i)=>{v.exports=i(70269)},63380:(v,T,i)=>{v.exports=i(88819)},66342:(v,T,i)=>{v.exports=i(55912)},12885:(v,T,i)=>{var r=i(79599).default,u=i(63380),p=i(77576),d=i(73921),e=i(76593),_=i(6379),y=i(62734),S=i(69138),A=i(28033),N=i(19621);function L(){"use strict";v.exports=L=function(){return Z},v.exports.__esModule=!0,v.exports.default=v.exports;var Z={},J=Object.prototype,K=J.hasOwnProperty,ee="function"==typeof u?u:{},ue=ee.iterator||"@@iterator",ae=ee.asyncIterator||"@@asyncIterator",H=ee.toStringTag||"@@toStringTag";function se(Ut,Bt,bt){return p(Ut,Bt,{value:bt,enumerable:!0,configurable:!0,writable:!0}),Ut[Bt]}try{se({},"")}catch(Ut){se=function(bt,Gt,xt){return bt[Gt]=xt}}function Ee(Ut,Bt,bt,Gt){var Ur,di,Lr,Mr,Xt=d((Bt&&Bt.prototype instanceof ge?Bt:ge).prototype),Zn=new tn(Gt||[]);return Xt._invoke=(Ur=Ut,di=bt,Lr=Zn,Mr="suspendedStart",function(Kr,ei){if("executing"===Mr)throw new Error("Generator is already running");if("completed"===Mr){if("throw"===Kr)throw ei;return{value:void 0,done:!0}}for(Lr.method=Kr,Lr.arg=ei;;){var Nn=Lr.delegate;if(Nn){var $n=He(Nn,Lr);if($n){if($n===he)continue;return $n}}if("next"===Lr.method)Lr.sent=Lr._sent=Lr.arg;else if("throw"===Lr.method){if("suspendedStart"===Mr)throw Mr="completed",Lr.arg;Lr.dispatchException(Lr.arg)}else"return"===Lr.method&&Lr.abrupt("return",Lr.arg);Mr="executing";var Br=ie(Ur,di,Lr);if("normal"===Br.type){if(Mr=Lr.done?"completed":"suspendedYield",Br.arg===he)continue;return{value:Br.arg,done:Lr.done}}"throw"===Br.type&&(Mr="completed",Lr.method="throw",Lr.arg=Br.arg)}}),Xt}function ie(Ut,Bt,bt){try{return{type:"normal",arg:Ut.call(Bt,bt)}}catch(Gt){return{type:"throw",arg:Gt}}}Z.wrap=Ee;var he={};function ge(){}function De(){}function ce(){}var lt={};se(lt,ue,function(){return this});var ze=e&&e(e(It([])));ze&&ze!==J&&K.call(ze,ue)&&(lt=ze);var Be=ce.prototype=ge.prototype=d(lt);function Pe(Ut){var Bt;_(Bt=["next","throw","return"]).call(Bt,function(bt){se(Ut,bt,function(Gt){return this._invoke(bt,Gt)})})}function je(Ut,Bt){function bt(xt,Xt,Zn,Ur){var di=ie(Ut[xt],Ut,Xt);if("throw"!==di.type){var Lr=di.arg,Mr=Lr.value;return Mr&&"object"==r(Mr)&&K.call(Mr,"__await")?Bt.resolve(Mr.__await).then(function(Kr){bt("next",Kr,Zn,Ur)},function(Kr){bt("throw",Kr,Zn,Ur)}):Bt.resolve(Mr).then(function(Kr){Lr.value=Kr,Zn(Lr)},function(Kr){return bt("throw",Kr,Zn,Ur)})}Ur(di.arg)}var Gt;this._invoke=function(xt,Xt){function Zn(){return new Bt(function(Ur,di){bt(xt,Xt,Ur,di)})}return Gt=Gt?Gt.then(Zn,Zn):Zn()}}function He(Ut,Bt){var bt=Ut.iterator[Bt.method];if(void 0===bt){if(Bt.delegate=null,"throw"===Bt.method){if(Ut.iterator.return&&(Bt.method="return",Bt.arg=void 0,He(Ut,Bt),"throw"===Bt.method))return he;Bt.method="throw",Bt.arg=new TypeError("The iterator does not provide a 'throw' method")}return he}var Gt=ie(bt,Ut.iterator,Bt.arg);if("throw"===Gt.type)return Bt.method="throw",Bt.arg=Gt.arg,Bt.delegate=null,he;var xt=Gt.arg;return xt?xt.done?(Bt[Ut.resultName]=xt.value,Bt.next=Ut.nextLoc,"return"!==Bt.method&&(Bt.method="next",Bt.arg=void 0),Bt.delegate=null,he):xt:(Bt.method="throw",Bt.arg=new TypeError("iterator result is not an object"),Bt.delegate=null,he)}function Vt(Ut){var Bt={tryLoc:Ut[0]};1 in Ut&&(Bt.catchLoc=Ut[1]),2 in Ut&&(Bt.finallyLoc=Ut[2],Bt.afterLoc=Ut[3]),this.tryEntries.push(Bt)}function it(Ut){var Bt=Ut.completion||{};Bt.type="normal",delete Bt.arg,Ut.completion=Bt}function tn(Ut){this.tryEntries=[{tryLoc:"root"}],_(Ut).call(Ut,Vt,this),this.reset(!0)}function It(Ut){if(Ut){var Bt=Ut[ue];if(Bt)return Bt.call(Ut);if("function"==typeof Ut.next)return Ut;if(!isNaN(Ut.length)){var bt=-1,Gt=function xt(){for(;++bt<Ut.length;)if(K.call(Ut,bt))return xt.value=Ut[bt],xt.done=!1,xt;return xt.value=void 0,xt.done=!0,xt};return Gt.next=Gt}}return{next:Zt}}function Zt(){return{value:void 0,done:!0}}return De.prototype=ce,se(Be,"constructor",ce),se(ce,"constructor",De),De.displayName=se(ce,H,"GeneratorFunction"),Z.isGeneratorFunction=function(Ut){var Bt="function"==typeof Ut&&Ut.constructor;return!!Bt&&(Bt===De||"GeneratorFunction"===(Bt.displayName||Bt.name))},Z.mark=function(Ut){return y?y(Ut,ce):(Ut.__proto__=ce,se(Ut,H,"GeneratorFunction")),Ut.prototype=d(Be),Ut},Z.awrap=function(Ut){return{__await:Ut}},Pe(je.prototype),se(je.prototype,ae,function(){return this}),Z.AsyncIterator=je,Z.async=function(Ut,Bt,bt,Gt,xt){void 0===xt&&(xt=S);var Xt=new je(Ee(Ut,Bt,bt,Gt),xt);return Z.isGeneratorFunction(Bt)?Xt:Xt.next().then(function(Zn){return Zn.done?Zn.value:Xt.next()})},Pe(Be),se(Be,H,"Generator"),se(Be,ue,function(){return this}),se(Be,"toString",function(){return"[object Generator]"}),Z.keys=function(Ut){var Bt=[];for(var bt in Ut)Bt.push(bt);return A(Bt).call(Bt),function Gt(){for(;Bt.length;){var xt=Bt.pop();if(xt in Ut)return Gt.value=xt,Gt.done=!1,Gt}return Gt.done=!0,Gt}},Z.values=It,tn.prototype={constructor:tn,reset:function(Bt){var bt;if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method="next",this.arg=void 0,_(bt=this.tryEntries).call(bt,it),!Bt)for(var Gt in this)"t"===Gt.charAt(0)&&K.call(this,Gt)&&!isNaN(+N(Gt).call(Gt,1))&&(this[Gt]=void 0)},stop:function(){this.done=!0;var Bt=this.tryEntries[0].completion;if("throw"===Bt.type)throw Bt.arg;return this.rval},dispatchException:function(Bt){if(this.done)throw Bt;var bt=this;function Gt(Lr,Mr){return Zn.type="throw",Zn.arg=Bt,bt.next=Lr,Mr&&(bt.method="next",bt.arg=void 0),!!Mr}for(var xt=this.tryEntries.length-1;xt>=0;--xt){var Xt=this.tryEntries[xt],Zn=Xt.completion;if("root"===Xt.tryLoc)return Gt("end");if(Xt.tryLoc<=this.prev){var Ur=K.call(Xt,"catchLoc"),di=K.call(Xt,"finallyLoc");if(Ur&&di){if(this.prev<Xt.catchLoc)return Gt(Xt.catchLoc,!0);if(this.prev<Xt.finallyLoc)return Gt(Xt.finallyLoc)}else if(Ur){if(this.prev<Xt.catchLoc)return Gt(Xt.catchLoc,!0)}else{if(!di)throw new Error("try statement without catch or finally");if(this.prev<Xt.finallyLoc)return Gt(Xt.finallyLoc)}}}},abrupt:function(Bt,bt){for(var Gt=this.tryEntries.length-1;Gt>=0;--Gt){var xt=this.tryEntries[Gt];if(xt.tryLoc<=this.prev&&K.call(xt,"finallyLoc")&&this.prev<xt.finallyLoc){var Xt=xt;break}}Xt&&("break"===Bt||"continue"===Bt)&&Xt.tryLoc<=bt&&bt<=Xt.finallyLoc&&(Xt=null);var Zn=Xt?Xt.completion:{};return Zn.type=Bt,Zn.arg=bt,Xt?(this.method="next",this.next=Xt.finallyLoc,he):this.complete(Zn)},complete:function(Bt,bt){if("throw"===Bt.type)throw Bt.arg;return"break"===Bt.type||"continue"===Bt.type?this.next=Bt.arg:"return"===Bt.type?(this.rval=this.arg=Bt.arg,this.method="return",this.next="end"):"normal"===Bt.type&&bt&&(this.next=bt),he},finish:function(Bt){for(var bt=this.tryEntries.length-1;bt>=0;--bt){var Gt=this.tryEntries[bt];if(Gt.finallyLoc===Bt)return this.complete(Gt.completion,Gt.afterLoc),it(Gt),he}},catch:function(Bt){for(var bt=this.tryEntries.length-1;bt>=0;--bt){var Gt=this.tryEntries[bt];if(Gt.tryLoc===Bt){var xt=Gt.completion;if("throw"===xt.type){var Xt=xt.arg;it(Gt)}return Xt}}throw new Error("illegal catch attempt")},delegateYield:function(Bt,bt,Gt){return this.delegate={iterator:It(Bt),resultName:bt,nextLoc:Gt},"next"===this.method&&(this.arg=void 0),he}},Z}v.exports=L,v.exports.__esModule=!0,v.exports.default=v.exports},79599:(v,T,i)=>{var r=i(63380),u=i(66342);function p(d){return v.exports=p="function"==typeof r&&"symbol"==typeof u?function(e){return typeof e}:function(e){return e&&"function"==typeof r&&e.constructor===r&&e!==r.prototype?"symbol":typeof e},v.exports.__esModule=!0,v.exports.default=v.exports,p(d)}v.exports=p,v.exports.__esModule=!0,v.exports.default=v.exports},33950:(v,T,i)=>{var r=i(12885)();v.exports=r;try{regeneratorRuntime=r}catch(u){"object"==typeof globalThis?globalThis.regeneratorRuntime=r:Function("r","regeneratorRuntime = r")(r)}},64291:(v,T,i)=>{"use strict";i.d(T,{Z:()=>ae});var p=i(66224);const e=function(H,se){for(var Ee=H.length;Ee--;)if((0,p.Z)(H[Ee][0],se))return Ee;return-1};var y=Array.prototype.splice;function ue(H){var se=-1,Ee=null==H?0:H.length;for(this.clear();++se<Ee;){var ie=H[se];this.set(ie[0],ie[1])}}ue.prototype.clear=function(){this.__data__=[],this.size=0},ue.prototype.delete=function(H){var se=this.__data__,Ee=e(se,H);return!(Ee<0||(Ee==se.length-1?se.pop():y.call(se,Ee,1),--this.size,0))},ue.prototype.get=function(H){var se=this.__data__,Ee=e(se,H);return Ee<0?void 0:se[Ee][1]},ue.prototype.has=function(H){return e(this.__data__,H)>-1},ue.prototype.set=function(H,se){var Ee=this.__data__,ie=e(Ee,H);return ie<0?(++this.size,Ee.push([H,se])):Ee[ie][1]=se,this};const ae=ue},54673:(v,T,i)=>{"use strict";i.d(T,{Z:()=>d});var r=i(30214),u=i(40309);const d=(0,r.Z)(u.Z,"Map")},79489:(v,T,i)=>{"use strict";i.d(T,{Z:()=>Bt});const p=(0,i(30214).Z)(Object,"create");var N=Object.prototype.hasOwnProperty;var K=Object.prototype.hasOwnProperty;function Ee(bt){var Gt=-1,xt=null==bt?0:bt.length;for(this.clear();++Gt<xt;){var Xt=bt[Gt];this.set(Xt[0],Xt[1])}}Ee.prototype.clear=function(){this.__data__=p?p(null):{},this.size=0},Ee.prototype.delete=function(bt){var Gt=this.has(bt)&&delete this.__data__[bt];return this.size-=Gt?1:0,Gt},Ee.prototype.get=function(bt){var Gt=this.__data__;if(p){var xt=Gt[bt];return"__lodash_hash_undefined__"===xt?void 0:xt}return N.call(Gt,bt)?Gt[bt]:void 0},Ee.prototype.has=function(bt){var Gt=this.__data__;return p?void 0!==Gt[bt]:K.call(Gt,bt)},Ee.prototype.set=function(bt,Gt){var xt=this.__data__;return this.size+=this.has(bt)?0:1,xt[bt]=p&&void 0===Gt?"__lodash_hash_undefined__":Gt,this};const ie=Ee;var he=i(64291),ge=i(54673);const Be=function(bt,Gt){var xt=bt.__data__;return function(bt){var Gt=typeof bt;return"string"==Gt||"number"==Gt||"symbol"==Gt||"boolean"==Gt?"__proto__"!==bt:null===bt}(Gt)?xt["string"==typeof Gt?"string":"hash"]:xt.map};function Ut(bt){var Gt=-1,xt=null==bt?0:bt.length;for(this.clear();++Gt<xt;){var Xt=bt[Gt];this.set(Xt[0],Xt[1])}}Ut.prototype.clear=function(){this.size=0,this.__data__={hash:new ie,map:new(ge.Z||he.Z),string:new ie}},Ut.prototype.delete=function(bt){var Gt=Be(this,bt).delete(bt);return this.size-=Gt?1:0,Gt},Ut.prototype.get=function(bt){return Be(this,bt).get(bt)},Ut.prototype.has=function(bt){return Be(this,bt).has(bt)},Ut.prototype.set=function(bt,Gt){var xt=Be(this,bt),Xt=xt.size;return xt.set(bt,Gt),this.size+=xt.size==Xt?0:1,this};const Bt=Ut},7475:(v,T,i)=>{"use strict";i.d(T,{Z:()=>ue});var r=i(64291);var N=i(54673),L=i(79489);function ee(ae){var H=this.__data__=new r.Z(ae);this.size=H.size}ee.prototype.clear=function(){this.__data__=new r.Z,this.size=0},ee.prototype.delete=function(ae){var H=this.__data__,se=H.delete(ae);return this.size=H.size,se},ee.prototype.get=function(ae){return this.__data__.get(ae)},ee.prototype.has=function(ae){return this.__data__.has(ae)},ee.prototype.set=function(ae,H){var se=this.__data__;if(se instanceof r.Z){var Ee=se.__data__;if(!N.Z||Ee.length<199)return Ee.push([ae,H]),this.size=++se.size,this;se=this.__data__=new L.Z(Ee)}return se.set(ae,H),this.size=se.size,this};const ue=ee},35770:(v,T,i)=>{"use strict";i.d(T,{Z:()=>p});const p=i(40309).Z.Symbol},83345:(v,T,i)=>{"use strict";i.d(T,{Z:()=>p});const p=i(40309).Z.Uint8Array},39434:(v,T,i)=>{"use strict";i.d(T,{Z:()=>L});var p=i(2172),d=i(34654),e=i(12434),_=i(28078),y=i(99436),A=Object.prototype.hasOwnProperty;const L=function(Z,J){var K=(0,d.Z)(Z),ee=!K&&(0,p.Z)(Z),ue=!K&&!ee&&(0,e.Z)(Z),ae=!K&&!ee&&!ue&&(0,y.Z)(Z),H=K||ee||ue||ae,se=H?function(Z,J){for(var K=-1,ee=Array(Z);++K<Z;)ee[K]=J(K);return ee}(Z.length,String):[],Ee=se.length;for(var ie in Z)(J||A.call(Z,ie))&&(!H||!("length"==ie||ue&&("offset"==ie||"parent"==ie)||ae&&("buffer"==ie||"byteLength"==ie||"byteOffset"==ie)||(0,_.Z)(ie,Ee)))&&se.push(ie);return se}},57052:(v,T,i)=>{"use strict";i.d(T,{Z:()=>u});const u=function(p,d){for(var e=-1,_=d.length,y=p.length;++e<_;)p[y+e]=d[e];return p}},15427:(v,T,i)=>{"use strict";i.d(T,{Z:()=>_});var r=i(2951),u=i(66224),d=Object.prototype.hasOwnProperty;const _=function(y,S,A){var N=y[S];(!d.call(y,S)||!(0,u.Z)(N,A)||void 0===A&&!(S in y))&&(0,r.Z)(y,S,A)}},2951:(v,T,i)=>{"use strict";i.d(T,{Z:()=>p});var r=i(99567);const p=function(d,e,_){"__proto__"==e&&r.Z?(0,r.Z)(d,e,{configurable:!0,enumerable:!0,value:_,writable:!0}):d[e]=_}},57765:(v,T,i)=>{"use strict";i.d(T,{Z:()=>_t});var r=i(7475);var d=i(15427),e=i(57640),_=i(6251);var A=i(76212);var Z=i(27672),J=i(36889),K=i(99913);var ae=i(74202);var Ee=i(22018),ie=i(23359),he=i(81901),De=Object.prototype.hasOwnProperty;var Ve=i(80609);var Pe=/\w*$/;var Vt=i(35770),it=Vt.Z?Vt.Z.prototype:void 0,tn=it?it.valueOf:void 0;var Ut=i(1044);const Cn=function(mt,jt,on){var si=mt.constructor;switch(jt){case"[object ArrayBuffer]":return(0,Ve.Z)(mt);case"[object Boolean]":case"[object Date]":return new si(+mt);case"[object DataView]":return function(mt,jt){var on=jt?(0,Ve.Z)(mt.buffer):mt.buffer;return new mt.constructor(on,mt.byteOffset,mt.byteLength)}(mt,on);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return(0,Ut.Z)(mt,on);case"[object Map]":return new si;case"[object Number]":case"[object String]":return new si(mt);case"[object RegExp]":return function(mt){var jt=new mt.constructor(mt.source,Pe.exec(mt));return jt.lastIndex=mt.lastIndex,jt}(mt);case"[object Set]":return new si;case"[object Symbol]":return function(mt){return tn?Object(tn.call(mt)):{}}(mt)}};var Wt=i(22595),zn=i(34654),rr=i(12434),Fr=i(6539);var wi=i(21162),br=i(48514),Dr=br.Z&&br.Z.isMap;const yn=Dr?(0,wi.Z)(Dr):function(mt){return(0,Fr.Z)(mt)&&"[object Map]"==(0,he.Z)(mt)};var gr=i(4214);var Dn=br.Z&&br.Z.isSet;const Yt=Dn?(0,wi.Z)(Dn):function(mt){return(0,Fr.Z)(mt)&&"[object Set]"==(0,he.Z)(mt)};var mi="[object Arguments]",Fn="[object Function]",vo="[object Object]",Ar={};Ar[mi]=Ar["[object Array]"]=Ar["[object ArrayBuffer]"]=Ar["[object DataView]"]=Ar["[object Boolean]"]=Ar["[object Date]"]=Ar["[object Float32Array]"]=Ar["[object Float64Array]"]=Ar["[object Int8Array]"]=Ar["[object Int16Array]"]=Ar["[object Int32Array]"]=Ar["[object Map]"]=Ar["[object Number]"]=Ar[vo]=Ar["[object RegExp]"]=Ar["[object Set]"]=Ar["[object String]"]=Ar["[object Symbol]"]=Ar["[object Uint8Array]"]=Ar["[object Uint8ClampedArray]"]=Ar["[object Uint16Array]"]=Ar["[object Uint32Array]"]=!0,Ar["[object Error]"]=Ar[Fn]=Ar["[object WeakMap]"]=!1;const _t=function Rt(mt,jt,on,si,Vi,_o){var co,Es=1&jt,Zs=2&jt,ls=4&jt;if(on&&(co=Vi?on(mt,si,Vi,_o):on(mt)),void 0!==co)return co;if(!(0,gr.Z)(mt))return mt;var La=(0,zn.Z)(mt);if(La){if(co=function(mt){var jt=mt.length,on=new mt.constructor(jt);return jt&&"string"==typeof mt[0]&&De.call(mt,"index")&&(on.index=mt.index,on.input=mt.input),on}(mt),!Es)return(0,J.Z)(mt,co)}else{var ta=(0,he.Z)(mt),Is=ta==Fn||"[object GeneratorFunction]"==ta;if((0,rr.Z)(mt))return(0,Z.Z)(mt,Es);if(ta==vo||ta==mi||Is&&!Vi){if(co=Zs||Is?{}:(0,Wt.Z)(mt),!Es)return Zs?function(mt,jt){return(0,e.Z)(mt,(0,ae.Z)(mt),jt)}(mt,function(mt,jt){return mt&&(0,e.Z)(jt,(0,A.Z)(jt),mt)}(co,mt)):function(mt,jt){return(0,e.Z)(mt,(0,K.Z)(mt),jt)}(mt,function(mt,jt){return mt&&(0,e.Z)(jt,(0,_.Z)(jt),mt)}(co,mt))}else{if(!Ar[ta])return Vi?mt:{};co=Cn(mt,ta,Es)}}_o||(_o=new r.Z);var us=_o.get(mt);if(us)return us;_o.set(mt,co),Yt(mt)?mt.forEach(function(ca){co.add(Rt(ca,jt,on,ca,mt,_o))}):yn(mt)&&mt.forEach(function(ca,$s){co.set($s,Rt(ca,jt,on,$s,mt,_o))});var el=La?void 0:(ls?Zs?ie.Z:Ee.Z:Zs?A.Z:_.Z)(mt);return function(mt,jt){for(var on=-1,si=null==mt?0:mt.length;++on<si&&!1!==jt(mt[on],on,mt););}(el||mt,function(ca,$s){el&&(ca=mt[$s=ca]),(0,d.Z)(co,$s,Rt(ca,jt,on,$s,mt,_o))}),co}},49137:(v,T,i)=>{"use strict";i.d(T,{Z:()=>d});var r=i(57052),u=i(34654);const d=function(e,_,y){var S=_(e);return(0,u.Z)(e)?S:(0,r.Z)(S,y(e))}},46382:(v,T,i)=>{"use strict";i.d(T,{Z:()=>ue});var r=i(35770),u=Object.prototype,p=u.hasOwnProperty,d=u.toString,e=r.Z?r.Z.toStringTag:void 0;var A=Object.prototype.toString;var K=r.Z?r.Z.toStringTag:void 0;const ue=function(ae){return null==ae?void 0===ae?"[object Undefined]":"[object Null]":K&&K in Object(ae)?function(ae){var H=p.call(ae,e),se=ae[e];try{ae[e]=void 0;var Ee=!0}catch(he){}var ie=d.call(ae);return Ee&&(H?ae[e]=se:delete ae[e]),ie}(ae):function(ae){return A.call(ae)}(ae)}},21162:(v,T,i)=>{"use strict";i.d(T,{Z:()=>u});const u=function(p){return function(d){return p(d)}}},80609:(v,T,i)=>{"use strict";i.d(T,{Z:()=>p});var r=i(83345);const p=function(d){var e=new d.constructor(d.byteLength);return new r.Z(e).set(new r.Z(d)),e}},27672:(v,T,i)=>{"use strict";i.d(T,{Z:()=>S});var r=i(40309),u="object"==typeof exports&&exports&&!exports.nodeType&&exports,p=u&&"object"==typeof module&&module&&!module.nodeType&&module,e=p&&p.exports===u?r.Z.Buffer:void 0,_=e?e.allocUnsafe:void 0;const S=function(A,N){if(N)return A.slice();var L=A.length,Z=_?_(L):new A.constructor(L);return A.copy(Z),Z}},1044:(v,T,i)=>{"use strict";i.d(T,{Z:()=>p});var r=i(80609);const p=function(d,e){var _=e?(0,r.Z)(d.buffer):d.buffer;return new d.constructor(_,d.byteOffset,d.length)}},36889:(v,T,i)=>{"use strict";i.d(T,{Z:()=>u});const u=function(p,d){var e=-1,_=p.length;for(d||(d=Array(_));++e<_;)d[e]=p[e];return d}},57640:(v,T,i)=>{"use strict";i.d(T,{Z:()=>d});var r=i(15427),u=i(2951);const d=function(e,_,y,S){var A=!y;y||(y={});for(var N=-1,L=_.length;++N<L;){var Z=_[N],J=S?S(y[Z],e[Z],Z,y,e):void 0;void 0===J&&(J=e[Z]),A?(0,u.Z)(y,Z,J):(0,r.Z)(y,Z,J)}return y}},99567:(v,T,i)=>{"use strict";i.d(T,{Z:()=>p});var r=i(30214);const p=function(){try{var d=(0,r.Z)(Object,"defineProperty");return d({},"",{}),d}catch(e){}}()},7746:(v,T,i)=>{"use strict";i.d(T,{Z:()=>u});const u="object"==typeof global&&global&&global.Object===Object&&global},22018:(v,T,i)=>{"use strict";i.d(T,{Z:()=>e});var r=i(49137),u=i(99913),p=i(6251);const e=function(_){return(0,r.Z)(_,p.Z,u.Z)}},23359:(v,T,i)=>{"use strict";i.d(T,{Z:()=>e});var r=i(49137),u=i(74202),p=i(76212);const e=function(_){return(0,r.Z)(_,p.Z,u.Z)}},30214:(v,T,i)=>{"use strict";i.d(T,{Z:()=>he});var ge,r=i(58209),p=i(40309).Z["__core-js_shared__"],e=(ge=/[^.]+$/.exec(p&&p.keys&&p.keys.IE_PROTO||""))?"Symbol(src)_1."+ge:"";var S=i(4214),A=i(22035),L=/^\[object .+?Constructor\]$/,ue=RegExp("^"+Function.prototype.toString.call(Object.prototype.hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");const H=function(ge){return!(!(0,S.Z)(ge)||function(ge){return!!e&&e in ge}(ge))&&((0,r.Z)(ge)?ue:L).test((0,A.Z)(ge))},he=function(ge,De){var ce=function(ge,De){return null==ge?void 0:ge[De]}(ge,De);return H(ce)?ce:void 0}},11595:(v,T,i)=>{"use strict";i.d(T,{Z:()=>p});const p=(0,i(24184).Z)(Object.getPrototypeOf,Object)},99913:(v,T,i)=>{"use strict";i.d(T,{Z:()=>S});var p=i(38387),e=Object.prototype.propertyIsEnumerable,_=Object.getOwnPropertySymbols;const S=_?function(A){return null==A?[]:(A=Object(A),function(A,N){for(var L=-1,Z=null==A?0:A.length,J=0,K=[];++L<Z;){var ee=A[L];N(ee,L,A)&&(K[J++]=ee)}return K}(_(A),function(N){return e.call(A,N)}))}:p.Z},74202:(v,T,i)=>{"use strict";i.d(T,{Z:()=>y});var r=i(57052),u=i(11595),p=i(99913),d=i(38387);const y=Object.getOwnPropertySymbols?function(S){for(var A=[];S;)(0,r.Z)(A,(0,p.Z)(S)),S=(0,u.Z)(S);return A}:d.Z},81901:(v,T,i)=>{"use strict";i.d(T,{Z:()=>lt});var r=i(30214),u=i(40309);const d=(0,r.Z)(u.Z,"DataView");var e=i(54673);const y=(0,r.Z)(u.Z,"Promise"),A=(0,r.Z)(u.Z,"Set"),L=(0,r.Z)(u.Z,"WeakMap");var Z=i(46382),J=i(22035),K="[object Map]",ue="[object Promise]",ae="[object Set]",H="[object WeakMap]",se="[object DataView]",Ee=(0,J.Z)(d),ie=(0,J.Z)(e.Z),he=(0,J.Z)(y),ge=(0,J.Z)(A),De=(0,J.Z)(L),ce=Z.Z;(d&&ce(new d(new ArrayBuffer(1)))!=se||e.Z&&ce(new e.Z)!=K||y&&ce(y.resolve())!=ue||A&&ce(new A)!=ae||L&&ce(new L)!=H)&&(ce=function(Ve){var ze=(0,Z.Z)(Ve),Be="[object Object]"==ze?Ve.constructor:void 0,Pe=Be?(0,J.Z)(Be):"";if(Pe)switch(Pe){case Ee:return se;case ie:return K;case he:return ue;case ge:return ae;case De:return H}return ze});const lt=ce},22595:(v,T,i)=>{"use strict";i.d(T,{Z:()=>S});var r=i(4214),u=Object.create;const d=function(){function A(){}return function(N){if(!(0,r.Z)(N))return{};if(u)return u(N);A.prototype=N;var L=new A;return A.prototype=void 0,L}}();var e=i(11595),_=i(31550);const S=function(A){return"function"!=typeof A.constructor||(0,_.Z)(A)?{}:d((0,e.Z)(A))}},28078:(v,T,i)=>{"use strict";i.d(T,{Z:()=>d});var u=/^(?:0|[1-9]\d*)$/;const d=function(e,_){var y=typeof e;return!!(_=null==_?9007199254740991:_)&&("number"==y||"symbol"!=y&&u.test(e))&&e>-1&&e%1==0&&e<_}},31550:(v,T,i)=>{"use strict";i.d(T,{Z:()=>p});var r=Object.prototype;const p=function(d){var e=d&&d.constructor;return d===("function"==typeof e&&e.prototype||r)}},48514:(v,T,i)=>{"use strict";i.d(T,{Z:()=>y});var r=i(7746),u="object"==typeof exports&&exports&&!exports.nodeType&&exports,p=u&&"object"==typeof module&&module&&!module.nodeType&&module,e=p&&p.exports===u&&r.Z.process;const y=function(){try{return p&&p.require&&p.require("util").types||e&&e.binding&&e.binding("util")}catch(A){}}()},24184:(v,T,i)=>{"use strict";i.d(T,{Z:()=>u});const u=function(p,d){return function(e){return p(d(e))}}},40309:(v,T,i)=>{"use strict";i.d(T,{Z:()=>d});var r=i(7746),u="object"==typeof self&&self&&self.Object===Object&&self;const d=r.Z||u||Function("return this")()},22035:(v,T,i)=>{"use strict";i.d(T,{Z:()=>d});var u=Function.prototype.toString;const d=function(e){if(null!=e){try{return u.call(e)}catch(_){}try{return e+""}catch(_){}}return""}},66224:(v,T,i)=>{"use strict";i.d(T,{Z:()=>u});const u=function(p,d){return p===d||p!=p&&d!=d}},2172:(v,T,i)=>{"use strict";i.d(T,{Z:()=>N});var r=i(46382),u=i(6539);const e=function(L){return(0,u.Z)(L)&&"[object Arguments]"==(0,r.Z)(L)};var _=Object.prototype,y=_.hasOwnProperty,S=_.propertyIsEnumerable;const N=e(function(){return arguments}())?e:function(L){return(0,u.Z)(L)&&y.call(L,"callee")&&!S.call(L,"callee")}},34654:(v,T,i)=>{"use strict";i.d(T,{Z:()=>u});const u=Array.isArray},18402:(v,T,i)=>{"use strict";i.d(T,{Z:()=>d});var r=i(58209),u=i(19238);const d=function(e){return null!=e&&(0,u.Z)(e.length)&&!(0,r.Z)(e)}},12434:(v,T,i)=>{"use strict";i.d(T,{Z:()=>N});var r=i(40309),d="object"==typeof exports&&exports&&!exports.nodeType&&exports,e=d&&"object"==typeof module&&module&&!module.nodeType&&module,y=e&&e.exports===d?r.Z.Buffer:void 0;const N=(y?y.isBuffer:void 0)||function(){return!1}},58209:(v,T,i)=>{"use strict";i.d(T,{Z:()=>S});var r=i(46382),u=i(4214);const S=function(A){if(!(0,u.Z)(A))return!1;var N=(0,r.Z)(A);return"[object Function]"==N||"[object GeneratorFunction]"==N||"[object AsyncFunction]"==N||"[object Proxy]"==N}},19238:(v,T,i)=>{"use strict";i.d(T,{Z:()=>p});const p=function(d){return"number"==typeof d&&d>-1&&d%1==0&&d<=9007199254740991}},4214:(v,T,i)=>{"use strict";i.d(T,{Z:()=>u});const u=function(p){var d=typeof p;return null!=p&&("object"==d||"function"==d)}},6539:(v,T,i)=>{"use strict";i.d(T,{Z:()=>u});const u=function(p){return null!=p&&"object"==typeof p}},99436:(v,T,i)=>{"use strict";i.d(T,{Z:()=>tn});var r=i(46382),u=i(19238),p=i(6539),ze={};ze["[object Float32Array]"]=ze["[object Float64Array]"]=ze["[object Int8Array]"]=ze["[object Int16Array]"]=ze["[object Int32Array]"]=ze["[object Uint8Array]"]=ze["[object Uint8ClampedArray]"]=ze["[object Uint16Array]"]=ze["[object Uint32Array]"]=!0,ze["[object Arguments]"]=ze["[object Array]"]=ze["[object ArrayBuffer]"]=ze["[object Boolean]"]=ze["[object DataView]"]=ze["[object Date]"]=ze["[object Error]"]=ze["[object Function]"]=ze["[object Map]"]=ze["[object Number]"]=ze["[object Object]"]=ze["[object RegExp]"]=ze["[object Set]"]=ze["[object String]"]=ze["[object WeakMap]"]=!1;var je=i(21162),He=i(48514),Vt=He.Z&&He.Z.isTypedArray;const tn=Vt?(0,je.Z)(Vt):function(It){return(0,p.Z)(It)&&(0,u.Z)(It.length)&&!!ze[(0,r.Z)(It)]}},6251:(v,T,i)=>{"use strict";i.d(T,{Z:()=>Z});var r=i(39434),u=i(31550);const e=(0,i(24184).Z)(Object.keys,Object);var y=Object.prototype.hasOwnProperty;var N=i(18402);const Z=function(J){return(0,N.Z)(J)?(0,r.Z)(J):function(J){if(!(0,u.Z)(J))return e(J);var K=[];for(var ee in Object(J))y.call(J,ee)&&"constructor"!=ee&&K.push(ee);return K}(J)}},76212:(v,T,i)=>{"use strict";i.d(T,{Z:()=>Z});var r=i(39434),u=i(4214),p=i(31550);var y=Object.prototype.hasOwnProperty;const A=function(J){if(!(0,u.Z)(J))return function(J){var K=[];if(null!=J)for(var ee in Object(J))K.push(ee);return K}(J);var K=(0,p.Z)(J),ee=[];for(var ue in J)"constructor"==ue&&(K||!y.call(J,ue))||ee.push(ue);return ee};var N=i(18402);const Z=function(J){return(0,N.Z)(J)?(0,r.Z)(J,!0):A(J)}},38387:(v,T,i)=>{"use strict";i.d(T,{Z:()=>u});const u=function(){return[]}}},v=>{v(v.s=1087)}]); \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/polyfills.2068f3f22a496426465b.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/polyfills.2068f3f22a496426465b.js
new file mode 100644
index 000000000..db37e3932
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/polyfills.2068f3f22a496426465b.js
@@ -0,0 +1 @@
+(self.webpackChunkceph_dashboard=self.webpackChunkceph_dashboard||[]).push([[429],{99140:(me,Se,we)=>{var ve,Le;void 0!==(Le="function"==typeof(ve=function(){"use strict";!function(e){var r=e.performance;function t(h){r&&r.mark&&r.mark(h)}function n(h,a){r&&r.measure&&r.measure(h,a)}t("Zone");var i=e.__Zone_symbol_prefix||"__zone_symbol__";function c(h){return i+h}var l=!0===e[c("forceDuplicateZoneCheck")];if(e.Zone){if(l||"function"!=typeof e.Zone.__symbol__)throw new Error("Zone already loaded.");return e.Zone}var _=function(){function h(a,o){this._parent=a,this._name=o?o.name||"unnamed":"<root>",this._properties=o&&o.properties||{},this._zoneDelegate=new d(this,this._parent&&this._parent._zoneDelegate,o)}return h.assertZonePatched=function(){if(e.Promise!==F.ZoneAwarePromise)throw new Error("Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has been overwritten.\nMost likely cause is that a Promise polyfill has been loaded after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)")},Object.defineProperty(h,"root",{get:function(){for(var a=h.current;a.parent;)a=a.parent;return a},enumerable:!0,configurable:!0}),Object.defineProperty(h,"current",{get:function(){return M.zone},enumerable:!0,configurable:!0}),Object.defineProperty(h,"currentTask",{get:function(){return oe},enumerable:!0,configurable:!0}),h.__load_patch=function(a,o){if(F.hasOwnProperty(a)){if(l)throw Error("Already loaded patch: "+a)}else if(!e["__Zone_disable_"+a]){var s="Zone:"+a;t(s),F[a]=o(e,h,R),n(s,s)}},Object.defineProperty(h.prototype,"parent",{get:function(){return this._parent},enumerable:!0,configurable:!0}),Object.defineProperty(h.prototype,"name",{get:function(){return this._name},enumerable:!0,configurable:!0}),h.prototype.get=function(a){var o=this.getZoneWith(a);if(o)return o._properties[a]},h.prototype.getZoneWith=function(a){for(var o=this;o;){if(o._properties.hasOwnProperty(a))return o;o=o._parent}return null},h.prototype.fork=function(a){if(!a)throw new Error("ZoneSpec required!");return this._zoneDelegate.fork(this,a)},h.prototype.wrap=function(a,o){if("function"!=typeof a)throw new Error("Expecting function got: "+a);var s=this._zoneDelegate.intercept(this,a,o),w=this;return function(){return w.runGuarded(s,this,arguments,o)}},h.prototype.run=function(a,o,s,w){M={parent:M,zone:this};try{return this._zoneDelegate.invoke(this,a,o,s,w)}finally{M=M.parent}},h.prototype.runGuarded=function(a,o,s,w){void 0===o&&(o=null),M={parent:M,zone:this};try{try{return this._zoneDelegate.invoke(this,a,o,s,w)}catch(N){if(this._zoneDelegate.handleError(this,N))throw N}}finally{M=M.parent}},h.prototype.runTask=function(a,o,s){if(a.zone!=this)throw new Error("A task can only be run in the zone of creation! (Creation: "+(a.zone||x).name+"; Execution: "+this.name+")");if(a.state!==A||a.type!==C&&a.type!==Y){var w=a.state!=P;w&&a._transitionTo(P,U),a.runCount++;var N=oe;oe=a,M={parent:M,zone:this};try{a.type==Y&&a.data&&!a.data.isPeriodic&&(a.cancelFn=void 0);try{return this._zoneDelegate.invokeTask(this,a,o,s)}catch(ae){if(this._zoneDelegate.handleError(this,ae))throw ae}}finally{a.state!==A&&a.state!==I&&(a.type==C||a.data&&a.data.isPeriodic?w&&a._transitionTo(U,P):(a.runCount=0,this._updateTaskCount(a,-1),w&&a._transitionTo(A,P,A))),M=M.parent,oe=N}}},h.prototype.scheduleTask=function(a){if(a.zone&&a.zone!==this)for(var o=this;o;){if(o===a.zone)throw Error("can not reschedule task to "+this.name+" which is descendants of the original zone "+a.zone.name);o=o.parent}a._transitionTo(V,A);var s=[];a._zoneDelegates=s,a._zone=this;try{a=this._zoneDelegate.scheduleTask(this,a)}catch(w){throw a._transitionTo(I,V,A),this._zoneDelegate.handleError(this,w),w}return a._zoneDelegates===s&&this._updateTaskCount(a,1),a.state==V&&a._transitionTo(U,V),a},h.prototype.scheduleMicroTask=function(a,o,s,w){return this.scheduleTask(new p(ee,a,o,s,w,void 0))},h.prototype.scheduleMacroTask=function(a,o,s,w,N){return this.scheduleTask(new p(Y,a,o,s,w,N))},h.prototype.scheduleEventTask=function(a,o,s,w,N){return this.scheduleTask(new p(C,a,o,s,w,N))},h.prototype.cancelTask=function(a){if(a.zone!=this)throw new Error("A task can only be cancelled in the zone of creation! (Creation: "+(a.zone||x).name+"; Execution: "+this.name+")");a._transitionTo($,U,P);try{this._zoneDelegate.cancelTask(this,a)}catch(o){throw a._transitionTo(I,$),this._zoneDelegate.handleError(this,o),o}return this._updateTaskCount(a,-1),a._transitionTo(A,$),a.runCount=0,a},h.prototype._updateTaskCount=function(a,o){var s=a._zoneDelegates;-1==o&&(a._zoneDelegates=null);for(var w=0;w<s.length;w++)s[w]._updateTaskCount(a.type,o)},h}();_.__symbol__=c;var z,T={name:"",onHasTask:function(h,a,o,s){return h.hasTask(o,s)},onScheduleTask:function(h,a,o,s){return h.scheduleTask(o,s)},onInvokeTask:function(h,a,o,s,w,N){return h.invokeTask(o,s,w,N)},onCancelTask:function(h,a,o,s){return h.cancelTask(o,s)}},d=function(){function h(a,o,s){this._taskCounts={microTask:0,macroTask:0,eventTask:0},this.zone=a,this._parentDelegate=o,this._forkZS=s&&(s&&s.onFork?s:o._forkZS),this._forkDlgt=s&&(s.onFork?o:o._forkDlgt),this._forkCurrZone=s&&(s.onFork?this.zone:o._forkCurrZone),this._interceptZS=s&&(s.onIntercept?s:o._interceptZS),this._interceptDlgt=s&&(s.onIntercept?o:o._interceptDlgt),this._interceptCurrZone=s&&(s.onIntercept?this.zone:o._interceptCurrZone),this._invokeZS=s&&(s.onInvoke?s:o._invokeZS),this._invokeDlgt=s&&(s.onInvoke?o:o._invokeDlgt),this._invokeCurrZone=s&&(s.onInvoke?this.zone:o._invokeCurrZone),this._handleErrorZS=s&&(s.onHandleError?s:o._handleErrorZS),this._handleErrorDlgt=s&&(s.onHandleError?o:o._handleErrorDlgt),this._handleErrorCurrZone=s&&(s.onHandleError?this.zone:o._handleErrorCurrZone),this._scheduleTaskZS=s&&(s.onScheduleTask?s:o._scheduleTaskZS),this._scheduleTaskDlgt=s&&(s.onScheduleTask?o:o._scheduleTaskDlgt),this._scheduleTaskCurrZone=s&&(s.onScheduleTask?this.zone:o._scheduleTaskCurrZone),this._invokeTaskZS=s&&(s.onInvokeTask?s:o._invokeTaskZS),this._invokeTaskDlgt=s&&(s.onInvokeTask?o:o._invokeTaskDlgt),this._invokeTaskCurrZone=s&&(s.onInvokeTask?this.zone:o._invokeTaskCurrZone),this._cancelTaskZS=s&&(s.onCancelTask?s:o._cancelTaskZS),this._cancelTaskDlgt=s&&(s.onCancelTask?o:o._cancelTaskDlgt),this._cancelTaskCurrZone=s&&(s.onCancelTask?this.zone:o._cancelTaskCurrZone),this._hasTaskZS=null,this._hasTaskDlgt=null,this._hasTaskDlgtOwner=null,this._hasTaskCurrZone=null;var w=s&&s.onHasTask;(w||o&&o._hasTaskZS)&&(this._hasTaskZS=w?s:T,this._hasTaskDlgt=o,this._hasTaskDlgtOwner=this,this._hasTaskCurrZone=a,s.onScheduleTask||(this._scheduleTaskZS=T,this._scheduleTaskDlgt=o,this._scheduleTaskCurrZone=this.zone),s.onInvokeTask||(this._invokeTaskZS=T,this._invokeTaskDlgt=o,this._invokeTaskCurrZone=this.zone),s.onCancelTask||(this._cancelTaskZS=T,this._cancelTaskDlgt=o,this._cancelTaskCurrZone=this.zone))}return h.prototype.fork=function(a,o){return this._forkZS?this._forkZS.onFork(this._forkDlgt,this.zone,a,o):new _(a,o)},h.prototype.intercept=function(a,o,s){return this._interceptZS?this._interceptZS.onIntercept(this._interceptDlgt,this._interceptCurrZone,a,o,s):o},h.prototype.invoke=function(a,o,s,w,N){return this._invokeZS?this._invokeZS.onInvoke(this._invokeDlgt,this._invokeCurrZone,a,o,s,w,N):o.apply(s,w)},h.prototype.handleError=function(a,o){return!this._handleErrorZS||this._handleErrorZS.onHandleError(this._handleErrorDlgt,this._handleErrorCurrZone,a,o)},h.prototype.scheduleTask=function(a,o){var s=o;if(this._scheduleTaskZS)this._hasTaskZS&&s._zoneDelegates.push(this._hasTaskDlgtOwner),(s=this._scheduleTaskZS.onScheduleTask(this._scheduleTaskDlgt,this._scheduleTaskCurrZone,a,o))||(s=o);else if(o.scheduleFn)o.scheduleFn(o);else{if(o.type!=ee)throw new Error("Task is missing scheduleFn.");m(o)}return s},h.prototype.invokeTask=function(a,o,s,w){return this._invokeTaskZS?this._invokeTaskZS.onInvokeTask(this._invokeTaskDlgt,this._invokeTaskCurrZone,a,o,s,w):o.callback.apply(s,w)},h.prototype.cancelTask=function(a,o){var s;if(this._cancelTaskZS)s=this._cancelTaskZS.onCancelTask(this._cancelTaskDlgt,this._cancelTaskCurrZone,a,o);else{if(!o.cancelFn)throw Error("Task is not cancelable");s=o.cancelFn(o)}return s},h.prototype.hasTask=function(a,o){try{this._hasTaskZS&&this._hasTaskZS.onHasTask(this._hasTaskDlgt,this._hasTaskCurrZone,a,o)}catch(s){this.handleError(a,s)}},h.prototype._updateTaskCount=function(a,o){var s=this._taskCounts,w=s[a],N=s[a]=w+o;if(N<0)throw new Error("More tasks executed then were scheduled.");0!=w&&0!=N||this.hasTask(this.zone,{microTask:s.microTask>0,macroTask:s.macroTask>0,eventTask:s.eventTask>0,change:a})},h}(),p=function(){function h(a,o,s,w,N,ae){if(this._zone=null,this.runCount=0,this._zoneDelegates=null,this._state="notScheduled",this.type=a,this.source=o,this.data=w,this.scheduleFn=N,this.cancelFn=ae,!s)throw new Error("callback is not defined");this.callback=s;var le=this;this.invoke=a===C&&w&&w.useG?h.invokeTask:function(){return h.invokeTask.call(e,le,this,arguments)}}return h.invokeTask=function(a,o,s){a||(a=this),te++;try{return a.runCount++,a.zone.runTask(a,o,s)}finally{1==te&&y(),te--}},Object.defineProperty(h.prototype,"zone",{get:function(){return this._zone},enumerable:!0,configurable:!0}),Object.defineProperty(h.prototype,"state",{get:function(){return this._state},enumerable:!0,configurable:!0}),h.prototype.cancelScheduleRequest=function(){this._transitionTo(A,V)},h.prototype._transitionTo=function(a,o,s){if(this._state!==o&&this._state!==s)throw new Error(this.type+" '"+this.source+"': can not transition to '"+a+"', expecting state '"+o+"'"+(s?" or '"+s+"'":"")+", was '"+this._state+"'.");this._state=a,a==A&&(this._zoneDelegates=null)},h.prototype.toString=function(){return this.data&&void 0!==this.data.handleId?this.data.handleId.toString():Object.prototype.toString.call(this)},h.prototype.toJSON=function(){return{type:this.type,state:this.state,source:this.source,zone:this.zone.name,runCount:this.runCount}},h}(),E=c("setTimeout"),k=c("Promise"),O=c("then"),S=[],Q=!1;function m(h){if(0===te&&0===S.length)if(z||e[k]&&(z=e[k].resolve(0)),z){var a=z[O];a||(a=z.then),a.call(z,y)}else e[E](y,0);h&&S.push(h)}function y(){if(!Q){for(Q=!0;S.length;){var h=S;S=[];for(var a=0;a<h.length;a++){var o=h[a];try{o.zone.runTask(o,null,null)}catch(s){R.onUnhandledError(s)}}}R.microtaskDrainDone(),Q=!1}}var x={name:"NO ZONE"},A="notScheduled",V="scheduling",U="scheduled",P="running",$="canceling",I="unknown",ee="microTask",Y="macroTask",C="eventTask",F={},R={symbol:c,currentZoneFrame:function(){return M},onUnhandledError:j,microtaskDrainDone:j,scheduleMicroTask:m,showUncaughtError:function(){return!_[c("ignoreConsoleErrorUncaughtError")]},patchEventTarget:function(){return[]},patchOnProperties:j,patchMethod:function(){return j},bindArguments:function(){return[]},patchThen:function(){return j},patchMacroTask:function(){return j},setNativePromise:function(h){h&&"function"==typeof h.resolve&&(z=h.resolve(0))},patchEventPrototype:function(){return j},isIEOrEdge:function(){return!1},getGlobalObjects:function(){},ObjectDefineProperty:function(){return j},ObjectGetOwnPropertyDescriptor:function(){},ObjectCreate:function(){},ArraySlice:function(){return[]},patchClass:function(){return j},wrapWithCurrentZone:function(){return j},filterProperties:function(){return[]},attachOriginToPatched:function(){return j},_redefineProperty:function(){return j},patchCallbacks:function(){return j}},M={parent:null,zone:new _(null,null)},oe=null,te=0;function j(){}n("Zone","Zone"),e.Zone=_}("undefined"!=typeof window&&window||"undefined"!=typeof self&&self||global),Zone.__load_patch("ZoneAwarePromise",function(e,r,t){var n=Object.getOwnPropertyDescriptor,i=Object.defineProperty;var l=t.symbol,_=[],T=!0===e[l("DISABLE_WRAPPING_UNCAUGHT_PROMISE_REJECTION")],d=l("Promise"),p=l("then");t.onUnhandledError=function(u){if(t.showUncaughtError()){var v=u&&u.rejection;v?console.error("Unhandled Promise rejection:",v instanceof Error?v.message:v,"; Zone:",u.zone.name,"; Task:",u.task&&u.task.source,"; Value:",v,v instanceof Error?v.stack:void 0):console.error(u)}},t.microtaskDrainDone=function(){for(var u=function(){var v=_.shift();try{v.zone.runGuarded(function(){throw v})}catch(f){!function(u){t.onUnhandledError(u);try{var v=r[k];"function"==typeof v&&v.call(this,u)}catch(f){}}(f)}};_.length;)u()};var k=l("unhandledPromiseRejectionHandler");function S(u){return u&&u.then}function Q(u){return u}function z(u){return o.reject(u)}var m=l("state"),y=l("value"),x=l("finally"),A=l("parentPromiseValue"),V=l("parentPromiseState"),P=null,$=!0,I=!1;function Y(u,v){return function(f){try{M(u,v,f)}catch(b){M(u,!1,b)}}}var R=l("currentTaskTrace");function M(u,v,f){var b=function(){var u=!1;return function(f){return function(){u||(u=!0,f.apply(null,arguments))}}}();if(u===f)throw new TypeError("Promise resolved with itself");if(u[m]===P){var L=null;try{("object"==typeof f||"function"==typeof f)&&(L=f&&f.then)}catch(W){return b(function(){M(u,!1,W)})(),u}if(v!==I&&f instanceof o&&f.hasOwnProperty(m)&&f.hasOwnProperty(y)&&f[m]!==P)te(f),M(u,f[m],f[y]);else if(v!==I&&"function"==typeof L)try{L.call(f,b(Y(u,v)),b(Y(u,!1)))}catch(W){b(function(){M(u,!1,W)})()}else{u[m]=v;var Z=u[y];if(u[y]=f,u[x]===x&&v===$&&(u[m]=u[V],u[y]=u[A]),v===I&&f instanceof Error){var D=r.currentTask&&r.currentTask.data&&r.currentTask.data.__creationTrace__;D&&i(f,R,{configurable:!0,enumerable:!1,writable:!0,value:D})}for(var H=0;H<Z.length;)j(u,Z[H++],Z[H++],Z[H++],Z[H++]);if(0==Z.length&&v==I){u[m]=0;var B=f;if(!T)try{throw new Error("Uncaught (in promise): "+function(u){return u&&u.toString===Object.prototype.toString?(u.constructor&&u.constructor.name||"")+": "+JSON.stringify(u):u?u.toString():Object.prototype.toString.call(u)}(f)+(f&&f.stack?"\n"+f.stack:""))}catch(W){B=W}B.rejection=f,B.promise=u,B.zone=r.current,B.task=r.currentTask,_.push(B),t.scheduleMicroTask()}}}return u}var oe=l("rejectionHandledHandler");function te(u){if(0===u[m]){try{var v=r[oe];v&&"function"==typeof v&&v.call(this,{rejection:u[y],promise:u})}catch(b){}u[m]=I;for(var f=0;f<_.length;f++)u===_[f].promise&&_.splice(f,1)}}function j(u,v,f,b,L){te(u);var Z=u[m],D=Z?"function"==typeof b?b:Q:"function"==typeof L?L:z;v.scheduleMicroTask("Promise.then",function(){try{var H=u[y],B=!!f&&x===f[x];B&&(f[A]=H,f[V]=Z);var W=v.run(D,void 0,B&&D!==z&&D!==Q?[]:[H]);M(f,!0,W)}catch(X){M(f,!1,X)}},f)}var a=function(){},o=function(){function u(v){var f=this;if(!(f instanceof u))throw new Error("Must be an instanceof Promise.");f[m]=P,f[y]=[];try{v&&v(Y(f,$),Y(f,I))}catch(b){M(f,!1,b)}}return u.toString=function(){return"function ZoneAwarePromise() { [native code] }"},u.resolve=function(v){return M(new this(null),$,v)},u.reject=function(v){return M(new this(null),I,v)},u.race=function(v){var f,b,L=new this(function(X,K){f=X,b=K});function Z(X){f(X)}function D(X){b(X)}for(var H=0,B=v;H<B.length;H++){var W=B[H];S(W)||(W=this.resolve(W)),W.then(Z,D)}return L},u.all=function(v){return u.allWithCallback(v)},u.allSettled=function(v){return(this&&this.prototype instanceof u?this:u).allWithCallback(v,{thenCallback:function(b){return{status:"fulfilled",value:b}},errorCallback:function(b){return{status:"rejected",reason:b}}})},u.allWithCallback=function(v,f){for(var b,L,Z=new this(function(_e,pe){b=_e,L=pe}),D=2,H=0,B=[],W=function(_e){S(_e)||(_e=X.resolve(_e));var pe=H;try{_e.then(function(se){B[pe]=f?f.thenCallback(se):se,0==--D&&b(B)},function(se){f?(B[pe]=f.errorCallback(se),0==--D&&b(B)):L(se)})}catch(se){L(se)}D++,H++},X=this,K=0,re=v;K<re.length;K++)W(re[K]);return 0==(D-=2)&&b(B),Z},Object.defineProperty(u.prototype,Symbol.toStringTag,{get:function(){return"Promise"},enumerable:!0,configurable:!0}),Object.defineProperty(u.prototype,Symbol.species,{get:function(){return u},enumerable:!0,configurable:!0}),u.prototype.then=function(v,f){var b=this.constructor[Symbol.species];(!b||"function"!=typeof b)&&(b=this.constructor||u);var L=new b(a),Z=r.current;return this[m]==P?this[y].push(Z,L,v,f):j(this,Z,L,v,f),L},u.prototype.catch=function(v){return this.then(null,v)},u.prototype.finally=function(v){var f=this.constructor[Symbol.species];(!f||"function"!=typeof f)&&(f=u);var b=new f(a);b[x]=x;var L=r.current;return this[m]==P?this[y].push(L,b,v,v):j(this,L,b,v,v),b},u}();o.resolve=o.resolve,o.reject=o.reject,o.race=o.race,o.all=o.all;var s=e[d]=e.Promise,w=r.__symbol__("ZoneAwarePromise"),N=n(e,"Promise");(!N||N.configurable)&&(N&&delete N.writable,N&&delete N.value,N||(N={configurable:!0,enumerable:!0}),N.get=function(){return e[w]?e[w]:e[d]},N.set=function(u){u===o?e[w]=u:(e[d]=u,u.prototype[p]||le(u),t.setNativePromise(u))},i(e,"Promise",N)),e.Promise=o;var u,ae=l("thenPatched");function le(u){var v=u.prototype,f=n(v,"then");if(!f||!1!==f.writable&&f.configurable){var b=v.then;v[p]=b,u.prototype.then=function(L,Z){var D=this;return new o(function(B,W){b.call(D,B,W)}).then(L,Z)},u[ae]=!0}}if(t.patchThen=le,s){le(s);var g=e.fetch;"function"==typeof g&&(e[t.symbol("fetch")]=g,e.fetch=(u=g,function(){var v=u.apply(this,arguments);if(v instanceof o)return v;var f=v.constructor;return f[ae]||le(f),v}))}return Promise[r.__symbol__("uncaughtPromiseErrors")]=_,o});var Re=Object.getOwnPropertyDescriptor,Ge=Object.defineProperty,Ve=Object.getPrototypeOf,Or=Object.create,Sr=Array.prototype.slice,Ue="addEventListener",ze="removeEventListener",We=Zone.__symbol__(Ue),Xe=Zone.__symbol__(ze),ue="true",ce="false",Ce=Zone.__symbol__("");function qe(e,r){return Zone.current.wrap(e,r)}function Ye(e,r,t,n,i){return Zone.current.scheduleMacroTask(e,r,t,n,i)}var G=Zone.__symbol__,Ie="undefined"!=typeof window,Te=Ie?window:void 0,J=Ie&&Te||"object"==typeof self&&self||global,Rr=[null];function Ke(e,r){for(var t=e.length-1;t>=0;t--)"function"==typeof e[t]&&(e[t]=qe(e[t],r+"_"+t));return e}function nr(e){return!e||!1!==e.writable&&!("function"==typeof e.get&&void 0===e.set)}var or="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,Me=!("nw"in J)&&void 0!==J.process&&"[object process]"==={}.toString.call(J.process),Je=!Me&&!or&&!(!Ie||!Te.HTMLElement),ar=void 0!==J.process&&"[object process]"==={}.toString.call(J.process)&&!or&&!(!Ie||!Te.HTMLElement),Ne={},ir=function(e){if(e=e||J.event){var r=Ne[e.type];r||(r=Ne[e.type]=G("ON_PROPERTY"+e.type));var i,t=this||e.target||J,n=t[r];return Je&&t===Te&&"error"===e.type?!0===(i=n&&n.call(this,e.message,e.filename,e.lineno,e.colno,e.error))&&e.preventDefault():null!=(i=n&&n.apply(this,arguments))&&!i&&e.preventDefault(),i}};function sr(e,r,t){var n=Re(e,r);if(!n&&t&&Re(t,r)&&(n={enumerable:!0,configurable:!0}),n&&n.configurable){var c=G("on"+r+"patched");if(!e.hasOwnProperty(c)||!e[c]){delete n.writable,delete n.value;var l=n.get,_=n.set,T=r.substr(2),d=Ne[T];d||(d=Ne[T]=G("ON_PROPERTY"+T)),n.set=function(p){var E=this;!E&&e===J&&(E=J),E&&(E[d]&&E.removeEventListener(T,ir),_&&_.apply(E,Rr),"function"==typeof p?(E[d]=p,E.addEventListener(T,ir,!1)):E[d]=null)},n.get=function(){var p=this;if(!p&&e===J&&(p=J),!p)return null;var E=p[d];if(E)return E;if(l){var k=l&&l.call(this);if(k)return n.set.call(this,k),"function"==typeof p.removeAttribute&&p.removeAttribute(r),k}return null},Ge(e,r,n),e[c]=!0}}}function ur(e,r,t){if(r)for(var n=0;n<r.length;n++)sr(e,"on"+r[n],t);else{var i=[];for(var c in e)"on"==c.substr(0,2)&&i.push(c);for(var l=0;l<i.length;l++)sr(e,i[l],t)}}var ie=G("originalInstance");function De(e){var r=J[e];if(r){J[G(e)]=r,J[e]=function(){var i=Ke(arguments,e);switch(i.length){case 0:this[ie]=new r;break;case 1:this[ie]=new r(i[0]);break;case 2:this[ie]=new r(i[0],i[1]);break;case 3:this[ie]=new r(i[0],i[1],i[2]);break;case 4:this[ie]=new r(i[0],i[1],i[2],i[3]);break;default:throw new Error("Arg list too long.")}},fe(J[e],r);var n,t=new r(function(){});for(n in t)"XMLHttpRequest"===e&&"responseBlob"===n||function(i){"function"==typeof t[i]?J[e].prototype[i]=function(){return this[ie][i].apply(this[ie],arguments)}:Ge(J[e].prototype,i,{set:function(c){"function"==typeof c?(this[ie][i]=qe(c,e+"."+i),fe(this[ie][i],c)):this[ie][i]=c},get:function(){return this[ie][i]}})}(n);for(n in r)"prototype"!==n&&r.hasOwnProperty(n)&&(J[e][n]=r[n])}}function he(e,r,t){for(var n=e;n&&!n.hasOwnProperty(r);)n=Ve(n);!n&&e[r]&&(n=e);var i=G(r),c=null;if(n&&!(c=n[i])&&(c=n[i]=n[r],nr(n&&Re(n,r)))){var _=t(c,i,r);n[r]=function(){return _(this,arguments)},fe(n[r],c)}return c}function Lr(e,r,t){var n=null;function i(c){var l=c.data;return l.args[l.cbIdx]=function(){c.invoke.apply(this,arguments)},n.apply(l.target,l.args),c}n=he(e,r,function(c){return function(l,_){var T=t(l,_);return T.cbIdx>=0&&"function"==typeof _[T.cbIdx]?Ye(T.name,_[T.cbIdx],T,i):c.apply(l,_)}})}function fe(e,r){e[G("OriginalDelegate")]=r}var cr=!1,Qe=!1;function Ir(){try{var e=Te.navigator.userAgent;if(-1!==e.indexOf("MSIE ")||-1!==e.indexOf("Trident/"))return!0}catch(r){}return!1}function Mr(){if(cr)return Qe;cr=!0;try{var e=Te.navigator.userAgent;(-1!==e.indexOf("MSIE ")||-1!==e.indexOf("Trident/")||-1!==e.indexOf("Edge/"))&&(Qe=!0)}catch(r){}return Qe}Zone.__load_patch("toString",function(e){var r=Function.prototype.toString,t=G("OriginalDelegate"),n=G("Promise"),i=G("Error"),c=function(){if("function"==typeof this){var d=this[t];if(d)return"function"==typeof d?r.call(d):Object.prototype.toString.call(d);if(this===Promise){var p=e[n];if(p)return r.call(p)}if(this===Error){var E=e[i];if(E)return r.call(E)}}return r.call(this)};c[t]=r,Function.prototype.toString=c;var l=Object.prototype.toString;Object.prototype.toString=function(){return this instanceof Promise?"[object Promise]":l.call(this)}});var ge=!1;if("undefined"!=typeof window)try{var Ae=Object.defineProperty({},"passive",{get:function(){ge=!0}});window.addEventListener("test",Ae,Ae),window.removeEventListener("test",Ae,Ae)}catch(e){ge=!1}var Nr={useG:!0},ne={},fr={},lr=new RegExp("^"+Ce+"(\\w+)(true|false)$"),$e=G("propagationStopped");function vr(e,r){var t=(r?r(e):e)+ce,n=(r?r(e):e)+ue,i=Ce+t,c=Ce+n;ne[e]={},ne[e][ce]=i,ne[e][ue]=c}function Ar(e,r,t){var n=t&&t.add||Ue,i=t&&t.rm||ze,c=t&&t.listeners||"eventListeners",l=t&&t.rmAll||"removeAllListeners",_=G(n),T="."+n+":",d="prependListener",E=function(m,y,x){if(!m.isRemoved){var A=m.callback;"object"==typeof A&&A.handleEvent&&(m.callback=function(P){return A.handleEvent(P)},m.originalDelegate=A),m.invoke(m,y,[x]);var V=m.options;V&&"object"==typeof V&&V.once&&y[i].call(y,x.type,m.originalDelegate?m.originalDelegate:m.callback,V)}},k=function(m){if(m=m||e.event){var y=this||m.target||e,x=y[ne[m.type][ce]];if(x)if(1===x.length)E(x[0],y,m);else for(var A=x.slice(),V=0;V<A.length&&(!m||!0!==m[$e]);V++)E(A[V],y,m)}},O=function(m){if(m=m||e.event){var y=this||m.target||e,x=y[ne[m.type][ue]];if(x)if(1===x.length)E(x[0],y,m);else for(var A=x.slice(),V=0;V<A.length&&(!m||!0!==m[$e]);V++)E(A[V],y,m)}};function S(m,y){if(!m)return!1;var x=!0;y&&void 0!==y.useG&&(x=y.useG);var A=y&&y.vh,V=!0;y&&void 0!==y.chkDup&&(V=y.chkDup);var U=!1;y&&void 0!==y.rt&&(U=y.rt);for(var P=m;P&&!P.hasOwnProperty(n);)P=Ve(P);if(!P&&m[n]&&(P=m),!P||P[_])return!1;var R,$=y&&y.eventNameToString,I={},ee=P[_]=P[n],Y=P[G(i)]=P[i],C=P[G(c)]=P[c],F=P[G(l)]=P[l];function M(g,u){return!ge&&"object"==typeof g&&g?!!g.capture:ge&&u?"boolean"==typeof g?{capture:g,passive:!0}:g?"object"==typeof g&&!1!==g.passive?Object.assign(Object.assign({},g),{passive:!0}):g:{passive:!0}:g}y&&y.prepend&&(R=P[G(y.prepend)]=P[y.prepend]);var o=x?function(g){if(!I.isExisting)return ee.call(I.target,I.eventName,I.capture?O:k,I.options)}:function(g){return ee.call(I.target,I.eventName,g.invoke,I.options)},s=x?function(g){if(!g.isRemoved){var u=ne[g.eventName],v=void 0;u&&(v=u[g.capture?ue:ce]);var f=v&&g.target[v];if(f)for(var b=0;b<f.length;b++)if(f[b]===g){f.splice(b,1),g.isRemoved=!0,0===f.length&&(g.allRemoved=!0,g.target[v]=null);break}}if(g.allRemoved)return Y.call(g.target,g.eventName,g.capture?O:k,g.options)}:function(g){return Y.call(g.target,g.eventName,g.invoke,g.options)},N=y&&y.diff?y.diff:function(g,u){var v=typeof u;return"function"===v&&g.callback===u||"object"===v&&g.originalDelegate===u},ae=Zone[G("BLACK_LISTED_EVENTS")],le=e[G("PASSIVE_EVENTS")],Be=function(g,u,v,f,b,L){return void 0===b&&(b=!1),void 0===L&&(L=!1),function(){var Z=this||e,D=arguments[0];y&&y.transferEventName&&(D=y.transferEventName(D));var H=arguments[1];if(!H)return g.apply(this,arguments);if(Me&&"uncaughtException"===D)return g.apply(this,arguments);var B=!1;if("function"!=typeof H){if(!H.handleEvent)return g.apply(this,arguments);B=!0}if(!A||A(g,H,Z,arguments)){var W=ge&&!!le&&-1!==le.indexOf(D),X=M(arguments[2],W);if(ae)for(var K=0;K<ae.length;K++)if(D===ae[K])return W?g.call(Z,D,H,X):g.apply(this,arguments);var re=!!X&&("boolean"==typeof X||X.capture),de=!(!X||"object"!=typeof X)&&X.once,_e=Zone.current,pe=ne[D];pe||(vr(D,$),pe=ne[D]);var se=pe[re?ue:ce],Oe=Z[se],br=!1;if(Oe){if(br=!0,V)for(K=0;K<Oe.length;K++)if(N(Oe[K],H))return}else Oe=Z[se]=[];var Fe,kr=Z.constructor.name,Pr=fr[kr];Pr&&(Fe=Pr[D]),Fe||(Fe=kr+u+($?$(D):D)),I.options=X,de&&(I.options.once=!1),I.target=Z,I.capture=re,I.eventName=D,I.isExisting=br;var Ze=x?Nr:void 0;Ze&&(Ze.taskData=I);var Ee=_e.scheduleEventTask(Fe,H,Ze,v,f);if(I.target=null,Ze&&(Ze.taskData=null),de&&(X.once=!0),!ge&&"boolean"==typeof Ee.options||(Ee.options=X),Ee.target=Z,Ee.capture=re,Ee.eventName=D,B&&(Ee.originalDelegate=H),L?Oe.unshift(Ee):Oe.push(Ee),b)return Z}}};return P[n]=Be(ee,T,o,s,U),R&&(P[d]=Be(R,".prependListener:",function(g){return R.call(I.target,I.eventName,g.invoke,I.options)},s,U,!0)),P[i]=function(){var g=this||e,u=arguments[0];y&&y.transferEventName&&(u=y.transferEventName(u));var v=arguments[2],f=!!v&&("boolean"==typeof v||v.capture),b=arguments[1];if(!b)return Y.apply(this,arguments);if(!A||A(Y,b,g,arguments)){var Z,L=ne[u];L&&(Z=L[f?ue:ce]);var D=Z&&g[Z];if(D)for(var H=0;H<D.length;H++){var B=D[H];if(N(B,b))return D.splice(H,1),B.isRemoved=!0,0===D.length&&(B.allRemoved=!0,g[Z]=null,"string"==typeof u)&&(g[Ce+"ON_PROPERTY"+u]=null),B.zone.cancelTask(B),U?g:void 0}return Y.apply(this,arguments)}},P[c]=function(){var g=this||e,u=arguments[0];y&&y.transferEventName&&(u=y.transferEventName(u));for(var v=[],f=hr(g,$?$(u):u),b=0;b<f.length;b++){var L=f[b];v.push(L.originalDelegate?L.originalDelegate:L.callback)}return v},P[l]=function(){var g=this||e,u=arguments[0];if(u){y&&y.transferEventName&&(u=y.transferEventName(u));var D=ne[u];if(D){var W=g[D[ce]],X=g[D[ue]];if(W)for(var K=W.slice(),f=0;f<K.length;f++)this[i].call(this,u,(re=K[f]).originalDelegate?re.originalDelegate:re.callback,re.options);if(X)for(K=X.slice(),f=0;f<K.length;f++){var re;this[i].call(this,u,(re=K[f]).originalDelegate?re.originalDelegate:re.callback,re.options)}}}else{var v=Object.keys(g);for(f=0;f<v.length;f++){var L=lr.exec(v[f]),Z=L&&L[1];Z&&"removeListener"!==Z&&this[l].call(this,Z)}this[l].call(this,"removeListener")}if(U)return this},fe(P[n],ee),fe(P[i],Y),F&&fe(P[l],F),C&&fe(P[c],C),!0}for(var Q=[],z=0;z<r.length;z++)Q[z]=S(r[z],t);return Q}function hr(e,r){if(!r){var t=[];for(var n in e){var i=lr.exec(n),c=i&&i[1];if(c&&(!r||c===r)){var l=e[n];if(l)for(var _=0;_<l.length;_++)t.push(l[_])}}return t}var T=ne[r];T||(vr(r),T=ne[r]);var d=e[T[ce]],p=e[T[ue]];return d?p?d.concat(p):d.slice():p?p.slice():[]}function jr(e,r){var t=e.Event;t&&t.prototype&&r.patchMethod(t.prototype,"stopImmediatePropagation",function(n){return function(i,c){i[$e]=!0,n&&n.apply(i,c)}})}function Hr(e,r,t,n,i){var c=Zone.__symbol__(n);if(!r[c]){var l=r[c]=r[n];r[n]=function(_,T,d){return T&&T.prototype&&i.forEach(function(p){var E=t+"."+n+"::"+p,k=T.prototype;if(k.hasOwnProperty(p)){var O=e.ObjectGetOwnPropertyDescriptor(k,p);O&&O.value?(O.value=e.wrapWithCurrentZone(O.value,E),e._redefineProperty(T.prototype,p,O)):k[p]&&(k[p]=e.wrapWithCurrentZone(k[p],E))}else k[p]&&(k[p]=e.wrapWithCurrentZone(k[p],E))}),l.call(r,_,T,d)},e.attachOriginToPatched(r[n],l)}}var je,He,yr,mr,ye,e,n,er=["absolutedeviceorientation","afterinput","afterprint","appinstalled","beforeinstallprompt","beforeprint","beforeunload","devicelight","devicemotion","deviceorientation","deviceorientationabsolute","deviceproximity","hashchange","languagechange","message","mozbeforepaint","offline","online","paint","pageshow","pagehide","popstate","rejectionhandled","storage","unhandledrejection","unload","userproximity","vrdisplayconnected","vrdisplaydisconnected","vrdisplaypresentchange"],Gr=["encrypted","waitingforkey","msneedkey","mozinterruptbegin","mozinterruptend"],dr=["load"],_r=["blur","error","focus","load","resize","scroll","messageerror"],Xr=["bounce","finish","start"],pr=["loadstart","progress","abort","error","load","progress","timeout","loadend","readystatechange"],be=["upgradeneeded","complete","abort","success","error","blocked","versionchange","close"],qr=["close","error","open","message"],Yr=["error","message"],ke=["abort","animationcancel","animationend","animationiteration","auxclick","beforeinput","blur","cancel","canplay","canplaythrough","change","compositionstart","compositionupdate","compositionend","cuechange","click","close","contextmenu","curechange","dblclick","drag","dragend","dragenter","dragexit","dragleave","dragover","drop","durationchange","emptied","ended","error","focus","focusin","focusout","gotpointercapture","input","invalid","keydown","keypress","keyup","load","loadstart","loadeddata","loadedmetadata","lostpointercapture","mousedown","mouseenter","mouseleave","mousemove","mouseout","mouseover","mouseup","mousewheel","orientationchange","pause","play","playing","pointercancel","pointerdown","pointerenter","pointerleave","pointerlockchange","mozpointerlockchange","webkitpointerlockerchange","pointerlockerror","mozpointerlockerror","webkitpointerlockerror","pointermove","pointout","pointerover","pointerup","progress","ratechange","reset","resize","scroll","seeked","seeking","select","selectionchange","selectstart","show","sort","stalled","submit","suspend","timeupdate","volumechange","touchcancel","touchmove","touchstart","touchend","transitioncancel","transitionend","waiting","wheel"].concat(["webglcontextrestored","webglcontextlost","webglcontextcreationerror"],["autocomplete","autocompleteerror"],["toggle"],["afterscriptexecute","beforescriptexecute","DOMContentLoaded","freeze","fullscreenchange","mozfullscreenchange","webkitfullscreenchange","msfullscreenchange","fullscreenerror","mozfullscreenerror","webkitfullscreenerror","msfullscreenerror","readystatechange","visibilitychange","resume"],er,["beforecopy","beforecut","beforepaste","copy","cut","paste","dragstart","loadend","animationstart","search","transitionrun","transitionstart","webkitanimationend","webkitanimationiteration","webkitanimationstart","webkittransitionend"],["activate","afterupdate","ariarequest","beforeactivate","beforedeactivate","beforeeditfocus","beforeupdate","cellchange","controlselect","dataavailable","datasetchanged","datasetcomplete","errorupdate","filterchange","layoutcomplete","losecapture","move","moveend","movestart","propertychange","resizeend","resizestart","rowenter","rowexit","rowsdelete","rowsinserted","command","compassneedscalibration","deactivate","help","mscontentzoom","msmanipulationstatechanged","msgesturechange","msgesturedoubletap","msgestureend","msgesturehold","msgesturestart","msgesturetap","msgotpointercapture","msinertiastart","mslostpointercapture","mspointercancel","mspointerdown","mspointerenter","mspointerhover","mspointerleave","mspointermove","mspointerout","mspointerover","mspointerup","pointerout","mssitemodejumplistitemremoved","msthumbnailclick","stop","storagecommit"]);function Er(e,r,t){if(!t||0===t.length)return r;var n=t.filter(function(c){return c.target===e});if(!n||0===n.length)return r;var i=n[0].ignoreProperties;return r.filter(function(c){return-1===i.indexOf(c)})}function q(e,r,t,n){e&&ur(e,Er(e,r,t),n)}function Kr(e,r){if((!Me||ar)&&!Zone[e.symbol("patchEvents")]){var t="undefined"!=typeof WebSocket,n=r.__Zone_ignore_on_properties;if(Je){var i=window,c=Ir?[{target:i,ignoreProperties:["error"]}]:[];q(i,ke.concat(["messageerror"]),n&&n.concat(c),Ve(i)),q(Document.prototype,ke,n),void 0!==i.SVGElement&&q(i.SVGElement.prototype,ke,n),q(Element.prototype,ke,n),q(HTMLElement.prototype,ke,n),q(HTMLMediaElement.prototype,Gr,n),q(HTMLFrameSetElement.prototype,er.concat(_r),n),q(HTMLBodyElement.prototype,er.concat(_r),n),q(HTMLFrameElement.prototype,dr,n),q(HTMLIFrameElement.prototype,dr,n);var l=i.HTMLMarqueeElement;l&&q(l.prototype,Xr,n);var _=i.Worker;_&&q(_.prototype,Yr,n)}var T=r.XMLHttpRequest;T&&q(T.prototype,pr,n);var d=r.XMLHttpRequestEventTarget;d&&q(d&&d.prototype,pr,n),"undefined"!=typeof IDBIndex&&(q(IDBIndex.prototype,be,n),q(IDBRequest.prototype,be,n),q(IDBOpenDBRequest.prototype,be,n),q(IDBDatabase.prototype,be,n),q(IDBTransaction.prototype,be,n),q(IDBCursor.prototype,be,n)),t&&q(WebSocket.prototype,qr,n)}}function Qr(e,r,t){var n=t.configurable;return gr(e,r,t=rr(e,r,t),n)}function Tr(e,r){return e&&e[ye]&&e[ye][r]}function rr(e,r,t){return Object.isFrozen(t)||(t.configurable=!0),t.configurable||(!e[ye]&&!Object.isFrozen(e)&&He(e,ye,{writable:!0,value:{}}),e[ye]&&(e[ye][r]=!0)),t}function gr(e,r,t,n){try{return He(e,r,t)}catch(c){if(!t.configurable)throw c;void 0===n?delete t.configurable:t.configurable=n;try{return He(e,r,t)}catch(l){var i=null;try{i=JSON.stringify(t)}catch(_){i=t.toString()}console.log("Attempting to configure '"+r+"' with descriptor '"+i+"' on object '"+e+"' and got error, giving up: "+l)}}}function rt(e,r){var t=e.getGlobalObjects();if((!t.isNode||t.isMix)&&!function(e,r){var t=e.getGlobalObjects();if((t.isBrowser||t.isMix)&&!e.ObjectGetOwnPropertyDescriptor(HTMLElement.prototype,"onclick")&&"undefined"!=typeof Element){var c=e.ObjectGetOwnPropertyDescriptor(Element.prototype,"onclick");if(c&&!c.configurable)return!1;if(c){e.ObjectDefineProperty(Element.prototype,"onclick",{enumerable:!0,configurable:!0,get:function(){return!0}});var _=!!document.createElement("div").onclick;return e.ObjectDefineProperty(Element.prototype,"onclick",c),_}}var T=r.XMLHttpRequest;if(!T)return!1;var d="onreadystatechange",p=T.prototype,E=e.ObjectGetOwnPropertyDescriptor(p,d);if(E)return e.ObjectDefineProperty(p,d,{enumerable:!0,configurable:!0,get:function(){return!0}}),_=!!(k=new T).onreadystatechange,e.ObjectDefineProperty(p,d,E||{}),_;var O=e.symbol("fake");e.ObjectDefineProperty(p,d,{enumerable:!0,configurable:!0,get:function(){return this[O]},set:function(m){this[O]=m}});var k,S=function(){};return(k=new T).onreadystatechange=S,_=k[O]===S,k.onreadystatechange=null,_}(e,r)){var c="undefined"!=typeof WebSocket;(function(e){for(var r=e.getGlobalObjects().eventNames,t=e.symbol("unbound"),n=function(c){var l=r[c],_="on"+l;self.addEventListener(l,function(T){var p,E,d=T.target;for(E=d?d.constructor.name+"."+_:"unknown."+_;d;)d[_]&&!d[_][t]&&((p=e.wrapWithCurrentZone(d[_],E))[t]=d[_],d[_]=p),d=d.parentElement},!0)},i=0;i<r.length;i++)n(i)})(e),e.patchClass("XMLHttpRequest"),c&&function(e,r){var t=e.getGlobalObjects(),n=t.ADD_EVENT_LISTENER_STR,i=t.REMOVE_EVENT_LISTENER_STR,c=r.WebSocket;r.EventTarget||e.patchEventTarget(r,[c.prototype]),r.WebSocket=function(T,d){var E,k,p=arguments.length>1?new c(T,d):new c(T),O=e.ObjectGetOwnPropertyDescriptor(p,"onmessage");return O&&!1===O.configurable?(E=e.ObjectCreate(p),k=p,[n,i,"send","close"].forEach(function(S){E[S]=function(){var Q=e.ArraySlice.call(arguments);if(S===n||S===i){var z=Q.length>0?Q[0]:void 0;if(z){var m=Zone.__symbol__("ON_PROPERTY"+z);p[m]=E[m]}}return p[S].apply(p,Q)}})):E=p,e.patchOnProperties(E,["close","error","message","open"],k),E};var l=r.WebSocket;for(var _ in c)l[_]=c[_]}(e,r),Zone[e.symbol("patchEvents")]=!0}}Zone.__load_patch("util",function(e,r,t){t.patchOnProperties=ur,t.patchMethod=he,t.bindArguments=Ke,t.patchMacroTask=Lr;var n=r.__symbol__("BLACK_LISTED_EVENTS"),i=r.__symbol__("UNPATCHED_EVENTS");e[i]&&(e[n]=e[i]),e[n]&&(r[n]=r[i]=e[n]),t.patchEventPrototype=jr,t.patchEventTarget=Ar,t.isIEOrEdge=Mr,t.ObjectDefineProperty=Ge,t.ObjectGetOwnPropertyDescriptor=Re,t.ObjectCreate=Or,t.ArraySlice=Sr,t.patchClass=De,t.wrapWithCurrentZone=qe,t.filterProperties=Er,t.attachOriginToPatched=fe,t._redefineProperty=Object.defineProperty,t.patchCallbacks=Hr,t.getGlobalObjects=function(){return{globalSources:fr,zoneSymbolEventNames:ne,eventNames:ke,isBrowser:Je,isMix:ar,isNode:Me,TRUE_STR:ue,FALSE_STR:ce,ZONE_SYMBOL_PREFIX:Ce,ADD_EVENT_LISTENER_STR:Ue,REMOVE_EVENT_LISTENER_STR:ze}}}),(e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{})[(n="legacyPatch",(e.__Zone_symbol_prefix||"__zone_symbol__")+n)]=function(){var n=e.Zone;n.__load_patch("defineProperty",function(i,c,l){l._redefineProperty=Qr,je=Zone.__symbol__,He=Object[je("defineProperty")]=Object.defineProperty,yr=Object[je("getOwnPropertyDescriptor")]=Object.getOwnPropertyDescriptor,mr=Object.create,ye=je("unconfigurables"),Object.defineProperty=function(e,r,t){if(Tr(e,r))throw new TypeError("Cannot assign to read only property '"+r+"' of "+e);var n=t.configurable;return"prototype"!==r&&(t=rr(e,r,t)),gr(e,r,t,n)},Object.defineProperties=function(e,r){return Object.keys(r).forEach(function(t){Object.defineProperty(e,t,r[t])}),e},Object.create=function(e,r){return"object"==typeof r&&!Object.isFrozen(r)&&Object.keys(r).forEach(function(t){r[t]=rr(e,t,r[t])}),mr(e,r)},Object.getOwnPropertyDescriptor=function(e,r){var t=yr(e,r);return t&&Tr(e,r)&&(t.configurable=!1),t}}),n.__load_patch("registerElement",function(i,c,l){!function(e,r){var t=r.getGlobalObjects();(t.isBrowser||t.isMix)&&"registerElement"in e.document&&r.patchCallbacks(r,document,"Document","registerElement",["createdCallback","attachedCallback","detachedCallback","attributeChangedCallback"])}(i,l)}),n.__load_patch("EventTargetLegacy",function(i,c,l){(function(e,r){var t=r.getGlobalObjects(),n=t.eventNames,i=t.globalSources,c=t.zoneSymbolEventNames,l=t.TRUE_STR,_=t.FALSE_STR,T=t.ZONE_SYMBOL_PREFIX,p="ApplicationCache,EventSource,FileReader,InputMethodContext,MediaController,MessagePort,Node,Performance,SVGElementInstance,SharedWorker,TextTrack,TextTrackCue,TextTrackList,WebKitNamedFlow,Window,Worker,WorkerGlobalScope,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestUpload,IDBRequest,IDBOpenDBRequest,IDBDatabase,IDBTransaction,IDBCursor,DBIndex,WebSocket".split(","),E="EventTarget",k=[],O=e.wtf,S="Anchor,Area,Audio,BR,Base,BaseFont,Body,Button,Canvas,Content,DList,Directory,Div,Embed,FieldSet,Font,Form,Frame,FrameSet,HR,Head,Heading,Html,IFrame,Image,Input,Keygen,LI,Label,Legend,Link,Map,Marquee,Media,Menu,Meta,Meter,Mod,OList,Object,OptGroup,Option,Output,Paragraph,Pre,Progress,Quote,Script,Select,Source,Span,Style,TableCaption,TableCell,TableCol,Table,TableRow,TableSection,TextArea,Title,Track,UList,Unknown,Video".split(",");O?k=S.map(function(j){return"HTML"+j+"Element"}).concat(p):e[E]?k.push(E):k=p;for(var Q=e.__Zone_disable_IE_check||!1,z=e.__Zone_enable_cross_context_check||!1,m=r.isIEOrEdge(),x="[object FunctionWrapper]",A="function __BROWSERTOOLS_CONSOLE_SAFEFUNC() { [native code] }",V={MSPointerCancel:"pointercancel",MSPointerDown:"pointerdown",MSPointerEnter:"pointerenter",MSPointerHover:"pointerhover",MSPointerLeave:"pointerleave",MSPointerMove:"pointermove",MSPointerOut:"pointerout",MSPointerOver:"pointerover",MSPointerUp:"pointerup"},U=0;U<n.length;U++){var ee=T+((P=n[U])+_),Y=T+(P+l);c[P]={},c[P][_]=ee,c[P][l]=Y}for(U=0;U<S.length;U++)for(var C=S[U],F=i[C]={},R=0;R<n.length;R++){var P;F[P=n[R]]=C+".addEventListener:"+P}var oe=[];for(U=0;U<k.length;U++){var te=e[k[U]];oe.push(te&&te.prototype)}r.patchEventTarget(e,oe,{vh:function(j,h,a,o){if(!Q&&m)if(z)try{if((s=h.toString())===x||s==A)return j.apply(a,o),!1}catch(w){return j.apply(a,o),!1}else{var s;if((s=h.toString())===x||s==A)return j.apply(a,o),!1}else if(z)try{h.toString()}catch(w){return j.apply(a,o),!1}return!0},transferEventName:function(j){return V[j]||j}}),Zone[r.symbol("patchEventTarget")]=!!e[E]})(i,l),rt(l,i)})};var xe=G("zoneTask");function Pe(e,r,t,n){var i=null,c=null;t+=n;var l={};function _(d){var p=d.data;return p.args[0]=function(){try{d.invoke.apply(this,arguments)}finally{d.data&&d.data.isPeriodic||("number"==typeof p.handleId?delete l[p.handleId]:p.handleId&&(p.handleId[xe]=null))}},p.handleId=i.apply(e,p.args),d}function T(d){return c(d.data.handleId)}i=he(e,r+=n,function(d){return function(p,E){if("function"==typeof E[0]){var O=Ye(r,E[0],{isPeriodic:"Interval"===n,delay:"Timeout"===n||"Interval"===n?E[1]||0:void 0,args:E},_,T);if(!O)return O;var S=O.data.handleId;return"number"==typeof S?l[S]=O:S&&(S[xe]=O),S&&S.ref&&S.unref&&"function"==typeof S.ref&&"function"==typeof S.unref&&(O.ref=S.ref.bind(S),O.unref=S.unref.bind(S)),"number"==typeof S||S?S:O}return d.apply(e,E)}}),c=he(e,t,function(d){return function(p,E){var O,k=E[0];"number"==typeof k?O=l[k]:(O=k&&k[xe])||(O=k),O&&"string"==typeof O.type?"notScheduled"!==O.state&&(O.cancelFn&&O.data.isPeriodic||0===O.runCount)&&("number"==typeof k?delete l[k]:k&&(k[xe]=null),O.zone.cancelTask(O)):d.apply(e,E)}})}Zone.__load_patch("legacy",function(e){var r=e[Zone.__symbol__("legacyPatch")];r&&r()}),Zone.__load_patch("timers",function(e){var r="set",t="clear";Pe(e,r,t,"Timeout"),Pe(e,r,t,"Interval"),Pe(e,r,t,"Immediate")}),Zone.__load_patch("requestAnimationFrame",function(e){Pe(e,"request","cancel","AnimationFrame"),Pe(e,"mozRequest","mozCancel","AnimationFrame"),Pe(e,"webkitRequest","webkitCancel","AnimationFrame")}),Zone.__load_patch("blocking",function(e,r){for(var t=["alert","prompt","confirm"],n=0;n<t.length;n++)he(e,t[n],function(c,l,_){return function(T,d){return r.current.run(c,e,d,_)}})}),Zone.__load_patch("EventTarget",function(e,r,t){(function(e,r){r.patchEventPrototype(e,r)})(e,t),function(e,r){if(!Zone[r.symbol("patchEventTarget")]){for(var t=r.getGlobalObjects(),n=t.eventNames,i=t.zoneSymbolEventNames,c=t.TRUE_STR,l=t.FALSE_STR,_=t.ZONE_SYMBOL_PREFIX,T=0;T<n.length;T++){var d=n[T],k=_+(d+l),O=_+(d+c);i[d]={},i[d][l]=k,i[d][c]=O}var S=e.EventTarget;if(S&&S.prototype)r.patchEventTarget(e,[S&&S.prototype])}}(e,t);var n=e.XMLHttpRequestEventTarget;n&&n.prototype&&t.patchEventTarget(e,[n.prototype]),De("MutationObserver"),De("WebKitMutationObserver"),De("IntersectionObserver"),De("FileReader")}),Zone.__load_patch("on_property",function(e,r,t){Kr(t,e)}),Zone.__load_patch("customElements",function(e,r,t){!function(e,r){var t=r.getGlobalObjects();(t.isBrowser||t.isMix)&&e.customElements&&"customElements"in e&&r.patchCallbacks(r,e.customElements,"customElements","define",["connectedCallback","disconnectedCallback","adoptedCallback","attributeChangedCallback"])}(e,t)}),Zone.__load_patch("XHR",function(e,r){!function(d){var p=d.XMLHttpRequest;if(p){var E=p.prototype,O=E[We],S=E[Xe];if(!O){var Q=d.XMLHttpRequestEventTarget;if(Q){var z=Q.prototype;O=z[We],S=z[Xe]}}var m="readystatechange",y="scheduled",U=he(E,"open",function(){return function(C,F){return C[n]=0==F[2],C[l]=F[1],U.apply(C,F)}}),$=G("fetchTaskAborting"),I=G("fetchTaskScheduling"),ee=he(E,"send",function(){return function(C,F){if(!0===r.current[I]||C[n])return ee.apply(C,F);var R={target:C,url:C[l],isPeriodic:!1,args:F,aborted:!1},M=Ye("XMLHttpRequest.send",A,R,x,V);C&&!0===C[_]&&!R.aborted&&M.state===y&&M.invoke()}}),Y=he(E,"abort",function(){return function(C,F){var R=function(C){return C[t]}(C);if(R&&"string"==typeof R.type){if(null==R.cancelFn||R.data&&R.data.aborted)return;R.zone.cancelTask(R)}else if(!0===r.current[$])return Y.apply(C,F)}})}function x(C){var F=C.data,R=F.target;R[c]=!1,R[_]=!1;var M=R[i];O||(O=R[We],S=R[Xe]),M&&S.call(R,m,M);var oe=R[i]=function(){if(R.readyState===R.DONE)if(!F.aborted&&R[c]&&C.state===y){var j=R[r.__symbol__("loadfalse")];if(j&&j.length>0){var h=C.invoke;C.invoke=function(){for(var a=R[r.__symbol__("loadfalse")],o=0;o<a.length;o++)a[o]===C&&a.splice(o,1);!F.aborted&&C.state===y&&h.call(C)},j.push(C)}else C.invoke()}else!F.aborted&&!1===R[c]&&(R[_]=!0)};return O.call(R,m,oe),R[t]||(R[t]=C),ee.apply(R,F.args),R[c]=!0,C}function A(){}function V(C){var F=C.data;return F.aborted=!0,Y.apply(F.target,F.args)}}(e);var t=G("xhrTask"),n=G("xhrSync"),i=G("xhrListener"),c=G("xhrScheduled"),l=G("xhrURL"),_=G("xhrErrorBeforeScheduled")}),Zone.__load_patch("geolocation",function(e){e.navigator&&e.navigator.geolocation&&function(e,r){for(var t=e.constructor.name,n=function(c){var d,p,l=r[c],_=e[l];if(_){if(!nr(Re(e,l)))return"continue";e[l]=(fe(p=function(){return d.apply(this,Ke(arguments,t+"."+l))},d=_),p)}},i=0;i<r.length;i++)n(i)}(e.navigator.geolocation,["getCurrentPosition","watchPosition"])}),Zone.__load_patch("PromiseRejectionEvent",function(e,r){function t(n){return function(i){hr(e,n).forEach(function(l){var _=e.PromiseRejectionEvent;if(_){var T=new _(n,{promise:i.promise,reason:i.rejection});l.invoke(T)}})}}e.PromiseRejectionEvent&&(r[G("unhandledPromiseRejectionHandler")]=t("unhandledrejection"),r[G("rejectionHandledHandler")]=t("rejectionhandled"))})})?ve.call(Se,we,Se,me):ve)&&(me.exports=Le)},7435:(me,Se,we)=>{"use strict";we(99140)}},me=>{me(me.s=7435)}]); \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/prometheus_logo.8b3183e5a2db0e87bb2b.svg b/src/pybind/mgr/dashboard/frontend/dist/en-US/prometheus_logo.8b3183e5a2db0e87bb2b.svg
new file mode 100644
index 000000000..5c51f66d9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/prometheus_logo.8b3183e5a2db0e87bb2b.svg
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ width="115.333px"
+ height="114px"
+ viewBox="0 0 115.333 114"
+ enable-background="new 0 0 115.333 114"
+ xml:space="preserve"
+ sodipodi:docname="prometheus_logo_orange.svg"
+ inkscape:version="0.92.1 r15371"><metadata
+ id="metadata4495"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs4493" /><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1484"
+ inkscape:window-height="886"
+ id="namedview4491"
+ showgrid="false"
+ inkscape:zoom="5.2784901"
+ inkscape:cx="60.603667"
+ inkscape:cy="60.329656"
+ inkscape:window-x="54"
+ inkscape:window-y="7"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="Layer_1" /><g
+ id="Layer_2" /><path
+ style="fill:#e6522c;fill-opacity:1"
+ inkscape:connector-curvature="0"
+ id="path4486"
+ d="M 56.667,0.667 C 25.372,0.667 0,26.036 0,57.332 c 0,31.295 25.372,56.666 56.667,56.666 31.295,0 56.666,-25.371 56.666,-56.666 0,-31.296 -25.372,-56.665 -56.666,-56.665 z m 0,106.055 c -8.904,0 -16.123,-5.948 -16.123,-13.283 H 72.79 c 0,7.334 -7.219,13.283 -16.123,13.283 z M 83.297,89.04 H 30.034 V 79.382 H 83.298 V 89.04 Z M 83.106,74.411 H 30.186 C 30.01,74.208 29.83,74.008 29.66,73.802 24.208,67.182 22.924,63.726 21.677,60.204 c -0.021,-0.116 6.611,1.355 11.314,2.413 0,0 2.42,0.56 5.958,1.205 -3.397,-3.982 -5.414,-9.044 -5.414,-14.218 0,-11.359 8.712,-21.285 5.569,-29.308 3.059,0.249 6.331,6.456 6.552,16.161 3.252,-4.494 4.613,-12.701 4.613,-17.733 0,-5.21 3.433,-11.262 6.867,-11.469 -3.061,5.045 0.793,9.37 4.219,20.099 1.285,4.03 1.121,10.812 2.113,15.113 C 63.797,33.534 65.333,20.5 71,16 c -2.5,5.667 0.37,12.758 2.333,16.167 3.167,5.5 5.087,9.667 5.087,17.548 0,5.284 -1.951,10.259 -5.242,14.148 3.742,-0.702 6.326,-1.335 6.326,-1.335 l 12.152,-2.371 c 10e-4,-10e-4 -1.765,7.261 -8.55,14.254 z" /></svg> \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/runtime.dfeb6a20b4d203b567dc.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/runtime.dfeb6a20b4d203b567dc.js
new file mode 100644
index 000000000..6c2b7326a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/runtime.dfeb6a20b4d203b567dc.js
@@ -0,0 +1 @@
+(()=>{"use strict";var e,h={},v={};function r(e){var n=v[e];if(void 0!==n)return n.exports;var t=v[e]={id:e,loaded:!1,exports:{}};return h[e].call(t.exports,t,t.exports,r),t.loaded=!0,t.exports}r.m=h,e=[],r.O=(n,t,f,i)=>{if(!t){var a=1/0;for(o=0;o<e.length;o++){for(var[t,f,i]=e[o],s=!0,d=0;d<t.length;d++)(!1&i||a>=i)&&Object.keys(r.O).every(b=>r.O[b](t[d]))?t.splice(d--,1):(s=!1,i<a&&(a=i));if(s){e.splice(o--,1);var l=f();void 0!==l&&(n=l)}}return n}i=i||0;for(var o=e.length;o>0&&e[o-1][2]>i;o--)e[o]=e[o-1];e[o]=[t,f,i]},r.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return r.d(n,{a:n}),n},(()=>{var n,e=Object.getPrototypeOf?t=>Object.getPrototypeOf(t):t=>t.__proto__;r.t=function(t,f){if(1&f&&(t=this(t)),8&f||"object"==typeof t&&t&&(4&f&&t.__esModule||16&f&&"function"==typeof t.then))return t;var i=Object.create(null);r.r(i);var o={};n=n||[null,e({}),e([]),e(e)];for(var a=2&f&&t;"object"==typeof a&&!~n.indexOf(a);a=e(a))Object.getOwnPropertyNames(a).forEach(s=>o[s]=()=>t[s]);return o.default=()=>t,r.d(i,o),i}})(),r.d=(e,n)=>{for(var t in n)r.o(n,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:n[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((n,t)=>(r.f[t](e,n),n),[])),r.u=e=>e+"."+{117:"9781bbf8cc6a4aaa7e8e",281:"0d0cd268ddc6a6760dd4",483:"f42c1d67e206231ecdac"}[e]+".js",r.miniCssF=e=>"styles.f05c06a6a64f4730faae.css",r.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),(()=>{var e={},n="ceph-dashboard:";r.l=(t,f,i,o)=>{if(e[t])e[t].push(f);else{var a,s;if(void 0!==i)for(var d=document.getElementsByTagName("script"),l=0;l<d.length;l++){var c=d[l];if(c.getAttribute("src")==t||c.getAttribute("data-webpack")==n+i){a=c;break}}a||(s=!0,(a=document.createElement("script")).charset="utf-8",a.timeout=120,r.nc&&a.setAttribute("nonce",r.nc),a.setAttribute("data-webpack",n+i),a.src=r.tu(t)),e[t]=[f];var u=(_,b)=>{a.onerror=a.onload=null,clearTimeout(p);var g=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),g&&g.forEach(y=>y(b)),_)return _(b)},p=setTimeout(u.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=u.bind(null,a.onerror),a.onload=u.bind(null,a.onload),s&&document.head.appendChild(a)}}})(),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e;r.tu=n=>(void 0===e&&(e={createScriptURL:t=>t},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e.createScriptURL(n))})(),r.p="",(()=>{var e={666:0};r.f.j=(f,i)=>{var o=r.o(e,f)?e[f]:void 0;if(0!==o)if(o)i.push(o[2]);else if(666!=f){var a=new Promise((c,u)=>o=e[f]=[c,u]);i.push(o[2]=a);var s=r.p+r.u(f),d=new Error;r.l(s,c=>{if(r.o(e,f)&&(0!==(o=e[f])&&(e[f]=void 0),o)){var u=c&&("load"===c.type?"missing":c.type),p=c&&c.target&&c.target.src;d.message="Loading chunk "+f+" failed.\n("+u+": "+p+")",d.name="ChunkLoadError",d.type=u,d.request=p,o[1](d)}},"chunk-"+f,f)}else e[f]=0},r.O.j=f=>0===e[f];var n=(f,i)=>{var d,l,[o,a,s]=i,c=0;for(d in a)r.o(a,d)&&(r.m[d]=a[d]);if(s)var u=s(r);for(f&&f(i);c<o.length;c++)r.o(e,l=o[c])&&e[l]&&e[l][0](),e[o[c]]=0;return r.O(u)},t=self.webpackChunkceph_dashboard=self.webpackChunkceph_dashboard||[];t.forEach(n.bind(null,0)),t.push=n.bind(null,t.push.bind(t))})()})(); \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/scripts.6bda3fa7e09a87cd4228.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/scripts.6bda3fa7e09a87cd4228.js
new file mode 100644
index 000000000..cdf19c70e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/scripts.6bda3fa7e09a87cd4228.js
@@ -0,0 +1,7 @@
+/*!
+ * Chart.js v2.9.4
+ * https://www.chartjs.org
+ * (c) 2020 Chart.js Contributors
+ * Released under the MIT License
+ */
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Chart=e()}(this,function(){"use strict";"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function t(){throw new Error("Dynamic requires are not currently supported by rollup-plugin-commonjs")}function e(t,e){return t(e={exports:{}},e.exports),e.exports}var n={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},i=e(function(t){var e={};for(var i in n)n.hasOwnProperty(i)&&(e[n[i]]=i);var a=t.exports={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};for(var r in a)if(a.hasOwnProperty(r)){if(!("channels"in a[r]))throw new Error("missing channels property: "+r);if(!("labels"in a[r]))throw new Error("missing channel labels property: "+r);if(a[r].labels.length!==a[r].channels)throw new Error("channel and label counts mismatch: "+r);var o=a[r].channels,s=a[r].labels;delete a[r].channels,delete a[r].labels,Object.defineProperty(a[r],"channels",{value:o}),Object.defineProperty(a[r],"labels",{value:s})}a.rgb.hsl=function(t){var e,n,i=t[0]/255,a=t[1]/255,r=t[2]/255,o=Math.min(i,a,r),s=Math.max(i,a,r),l=s-o;return s===o?e=0:i===s?e=(a-r)/l:a===s?e=2+(r-i)/l:r===s&&(e=4+(i-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),n=(o+s)/2,[e,100*(s===o?0:n<=.5?l/(s+o):l/(2-s-o)),100*n]},a.rgb.hsv=function(t){var e,n,i,a,r,o=t[0]/255,s=t[1]/255,l=t[2]/255,u=Math.max(o,s,l),d=u-Math.min(o,s,l),h=function(t){return(u-t)/6/d+.5};return 0===d?a=r=0:(r=d/u,e=h(o),n=h(s),i=h(l),o===u?a=i-n:s===u?a=1/3+e-i:l===u&&(a=2/3+n-e),a<0?a+=1:a>1&&(a-=1)),[360*a,100*r,100*u]},a.rgb.hwb=function(t){var e=t[0],n=t[1],i=t[2];return[a.rgb.hsl(t)[0],100*(1/255*Math.min(e,Math.min(n,i))),100*(i=1-1/255*Math.max(e,Math.max(n,i)))]},a.rgb.cmyk=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255;return[100*((1-n-(e=Math.min(1-n,1-i,1-a)))/(1-e)||0),100*((1-i-e)/(1-e)||0),100*((1-a-e)/(1-e)||0),100*e]},a.rgb.keyword=function(t){var i=e[t];if(i)return i;var a,r,o,s=1/0;for(var l in n)if(n.hasOwnProperty(l)){var u=n[l],d=(r=t,o=u,Math.pow(r[0]-o[0],2)+Math.pow(r[1]-o[1],2)+Math.pow(r[2]-o[2],2));d<s&&(s=d,a=l)}return a},a.keyword.rgb=function(t){return n[t]},a.rgb.xyz=function(t){var e=t[0]/255,n=t[1]/255,i=t[2]/255;return[100*(.4124*(e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)+.1805*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)),100*(.2126*e+.7152*n+.0722*i),100*(.0193*e+.1192*n+.9505*i)]},a.rgb.lab=function(t){var e=a.rgb.xyz(t),n=e[0],i=e[1],r=e[2];return i/=100,r/=108.883,n=(n/=95.047)>.008856?Math.pow(n,1/3):7.787*n+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(n-i),200*(i-(r=r>.008856?Math.pow(r,1/3):7.787*r+16/116))]},a.hsl.rgb=function(t){var e,n,i,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0===s)return[r=255*l,r,r];e=2*l-(n=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(i=o+1/3*-(u-1))<0&&i++,i>1&&i--,r=6*i<1?e+6*(n-e)*i:2*i<1?n:3*i<2?e+(n-e)*(2/3-i)*6:e,a[u]=255*r;return a},a.hsl.hsv=function(t){var e=t[0],n=t[1]/100,i=t[2]/100,a=n,r=Math.max(i,.01);return n*=(i*=2)<=1?i:2-i,a*=r<=1?r:2-r,[e,100*(0===i?2*a/(r+a):2*n/(i+n)),100*((i+n)/2)]},a.hsv.rgb=function(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*r),l=255*i*(1-n*(1-r));switch(i*=255,a){case 0:return[i,l,o];case 1:return[s,i,o];case 2:return[o,i,l];case 3:return[o,s,i];case 4:return[l,o,i];case 5:return[i,o,s]}},a.hsv.hsl=function(t){var e,n,i,a=t[0],r=t[1]/100,o=t[2]/100,s=Math.max(o,.01);return i=(2-r)*o,n=r*s,[a,100*(n=(n/=(e=(2-r)*s)<=1?e:2-e)||0),100*(i/=2)]},a.hwb.rgb=function(t){var e,n,i,a,r,o,s,l=t[0]/360,u=t[1]/100,d=t[2]/100,h=u+d;switch(h>1&&(u/=h,d/=h),i=6*l-(e=Math.floor(6*l)),0!=(1&e)&&(i=1-i),a=u+i*((n=1-d)-u),e){default:case 6:case 0:r=n,o=a,s=u;break;case 1:r=a,o=n,s=u;break;case 2:r=u,o=n,s=a;break;case 3:r=u,o=a,s=n;break;case 4:r=a,o=u,s=n;break;case 5:r=n,o=u,s=a}return[255*r,255*o,255*s]},a.cmyk.rgb=function(t){var e=t[0]/100,n=t[1]/100,i=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a))]},a.xyz.rgb=function(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return n=-.9689*a+1.8758*r+.0415*o,i=.0557*a+-.204*r+1.057*o,e=(e=3.2406*a+-1.5372*r+-.4986*o)>.0031308?1.055*Math.pow(e,1/2.4)-.055:12.92*e,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:12.92*n,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:12.92*i,[255*(e=Math.min(Math.max(0,e),1)),255*(n=Math.min(Math.max(0,n),1)),255*(i=Math.min(Math.max(0,i),1))]},a.xyz.lab=function(t){var e=t[0],n=t[1],i=t[2];return n/=100,i/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(e-n),200*(n-(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116))]},a.lab.xyz=function(t){var e,n,i,a=t[0];e=t[1]/500+(n=(a+16)/116),i=n-t[2]/200;var r=Math.pow(n,3),o=Math.pow(e,3),s=Math.pow(i,3);return n=r>.008856?r:(n-16/116)/7.787,e=o>.008856?o:(e-16/116)/7.787,i=s>.008856?s:(i-16/116)/7.787,[e*=95.047,n*=100,i*=108.883]},a.lab.lch=function(t){var e,n=t[0],i=t[1],a=t[2];return(e=360*Math.atan2(a,i)/2/Math.PI)<0&&(e+=360),[n,Math.sqrt(i*i+a*a),e]},a.lch.lab=function(t){var e,n=t[0],i=t[1];return e=t[2]/360*2*Math.PI,[n,i*Math.cos(e),i*Math.sin(e)]},a.rgb.ansi16=function(t){var e=t[0],n=t[1],i=t[2],r=1 in arguments?arguments[1]:a.rgb.hsv(t)[2];if(0===(r=Math.round(r/50)))return 30;var o=30+(Math.round(i/255)<<2|Math.round(n/255)<<1|Math.round(e/255));return 2===r&&(o+=60),o},a.hsv.ansi16=function(t){return a.rgb.ansi16(a.hsv.rgb(t),t[2])},a.rgb.ansi256=function(t){var e=t[0],n=t[1],i=t[2];return e===n&&n===i?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(n/255*5)+Math.round(i/255*5)},a.ansi16.rgb=function(t){var e=t%10;if(0===e||7===e)return t>50&&(e+=3.5),[e=e/10.5*255,e,e];var n=.5*(1+~~(t>50));return[(1&e)*n*255,(e>>1&1)*n*255,(e>>2&1)*n*255]},a.ansi256.rgb=function(t){if(t>=232){var e=10*(t-232)+8;return[e,e,e]}var n;return t-=16,[Math.floor(t/36)/5*255,Math.floor((n=t%36)/6)/5*255,n%6/5*255]},a.rgb.hex=function(t){var e=(((255&Math.round(t[0]))<<16)+((255&Math.round(t[1]))<<8)+(255&Math.round(t[2]))).toString(16).toUpperCase();return"000000".substring(e.length)+e},a.hex.rgb=function(t){var e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];var n=e[0];3===e[0].length&&(n=n.split("").map(function(t){return t+t}).join(""));var i=parseInt(n,16);return[i>>16&255,i>>8&255,255&i]},a.rgb.hcg=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255,r=Math.max(Math.max(n,i),a),o=Math.min(Math.min(n,i),a),s=r-o;return e=s<=0?0:r===n?(i-a)/s%6:r===i?2+(a-n)/s:4+(n-i)/s+4,e/=6,[360*(e%=1),100*s,100*(s<1?o/(1-s):0)]},a.hsl.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=1,a=0;return(i=n<.5?2*e*n:2*e*(1-n))<1&&(a=(n-.5*i)/(1-i)),[t[0],100*i,100*a]},a.hsv.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=e*n,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.hcg.rgb=function(t){var e=t[0]/360,n=t[1]/100,i=t[2]/100;if(0===n)return[255*i,255*i,255*i];var a,r=[0,0,0],o=e%1*6,s=o%1,l=1-s;switch(Math.floor(o)){case 0:r[0]=1,r[1]=s,r[2]=0;break;case 1:r[0]=l,r[1]=1,r[2]=0;break;case 2:r[0]=0,r[1]=1,r[2]=s;break;case 3:r[0]=0,r[1]=l,r[2]=1;break;case 4:r[0]=s,r[1]=0,r[2]=1;break;default:r[0]=1,r[1]=0,r[2]=l}return a=(1-n)*i,[255*(n*r[0]+a),255*(n*r[1]+a),255*(n*r[2]+a)]},a.hcg.hsv=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e),i=0;return n>0&&(i=e/n),[t[0],100*i,100*n]},a.hcg.hsl=function(t){var e=t[1]/100,n=t[2]/100*(1-e)+.5*e,i=0;return n>0&&n<.5?i=e/(2*n):n>=.5&&n<1&&(i=e/(2*(1-n))),[t[0],100*i,100*n]},a.hcg.hwb=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e);return[t[0],100*(n-e),100*(1-n)]},a.hwb.hcg=function(t){var e=t[1]/100,n=1-t[2]/100,i=n-e,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]},a.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]},a.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]},a.gray.hsl=a.gray.hsv=function(t){return[0,0,t[0]]},a.gray.hwb=function(t){return[0,100,t[0]]},a.gray.cmyk=function(t){return[0,0,0,t[0]]},a.gray.lab=function(t){return[t[0],0,0]},a.gray.hex=function(t){var e=255&Math.round(t[0]/100*255),n=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(n.length)+n},a.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}});i.rgb,i.hsl,i.hsv,i.hwb,i.cmyk,i.xyz,i.lab,i.lch,i.hex,i.keyword,i.ansi16,i.ansi256,i.hcg,i.apple,i.gray;function a(t){var e=function(){for(var t={},e=Object.keys(i),n=e.length,a=0;a<n;a++)t[e[a]]={distance:-1,parent:null};return t}(),n=[t];for(e[t].distance=0;n.length;)for(var a=n.pop(),r=Object.keys(i[a]),o=r.length,s=0;s<o;s++){var l=r[s],u=e[l];-1===u.distance&&(u.distance=e[a].distance+1,u.parent=a,n.unshift(l))}return e}function r(t,e){return function(n){return e(t(n))}}function o(t,e){for(var n=[e[t].parent,t],a=i[e[t].parent][t],o=e[t].parent;e[o].parent;)n.unshift(e[o].parent),a=r(i[e[o].parent][o],a),o=e[o].parent;return a.conversion=n,a}var s={};Object.keys(i).forEach(function(t){s[t]={},Object.defineProperty(s[t],"channels",{value:i[t].channels}),Object.defineProperty(s[t],"labels",{value:i[t].labels});var e=function(t){for(var e=a(t),n={},i=Object.keys(e),r=i.length,s=0;s<r;s++){var l=i[s];null!==e[l].parent&&(n[l]=o(l,e))}return n}(t);Object.keys(e).forEach(function(n){var i=e[n];s[t][n]=function(t){var e=function(e){if(null==e)return e;arguments.length>1&&(e=Array.prototype.slice.call(arguments));var n=t(e);if("object"==typeof n)for(var i=n.length,a=0;a<i;a++)n[a]=Math.round(n[a]);return n};return"conversion"in t&&(e.conversion=t.conversion),e}(i),s[t][n].raw=function(t){var e=function(e){return null==e?e:(arguments.length>1&&(e=Array.prototype.slice.call(arguments)),t(e))};return"conversion"in t&&(e.conversion=t.conversion),e}(i)})});var l=s,u={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},d={getRgba:h,getHsla:c,getRgb:function(t){var e=h(t);return e&&e.slice(0,3)},getHsl:function(t){var e=c(t);return e&&e.slice(0,3)},getHwb:f,getAlpha:function(t){var e=h(t);if(e)return e[3];if(e=c(t))return e[3];if(e=f(t))return e[3]},hexString:function(t,e){e=void 0!==e&&3===t.length?e:t[3];return"#"+b(t[0])+b(t[1])+b(t[2])+(e>=0&&e<1?b(Math.round(255*e)):"")},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return g(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:g,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return m(t,e);var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+n+"%, "+i+"%, "+a+"%)"},percentaString:m,hslString:function(t,e){if(e<1||t[3]&&t[3]<1)return p(t,e);return"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:p,hwbString:function(t,e){void 0===e&&(e=void 0!==t[3]?t[3]:1);return"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return y[t.slice(0,3)]}};function h(t){if(t){var e=[0,0,0],n=1,i=t.match(/^#([a-fA-F0-9]{3,4})$/i),a="";if(i){a=(i=i[1])[3];for(var r=0;r<e.length;r++)e[r]=parseInt(i[r]+i[r],16);a&&(n=Math.round(parseInt(a+a,16)/255*100)/100)}else if(i=t.match(/^#([a-fA-F0-9]{6}([a-fA-F0-9]{2})?)$/i)){a=i[2],i=i[1];for(r=0;r<e.length;r++)e[r]=parseInt(i.slice(2*r,2*r+2),16);a&&(n=Math.round(parseInt(a,16)/255*100)/100)}else if(i=t.match(/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(r=0;r<e.length;r++)e[r]=parseInt(i[r+1]);n=parseFloat(i[4])}else if(i=t.match(/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(r=0;r<e.length;r++)e[r]=Math.round(2.55*parseFloat(i[r+1]));n=parseFloat(i[4])}else if(i=t.match(/(\w+)/)){if("transparent"==i[1])return[0,0,0,0];if(!(e=u[i[1]]))return}for(r=0;r<e.length;r++)e[r]=v(e[r],0,255);return n=n||0==n?v(n,0,1):1,e[3]=n,e}}function c(t){if(t){var e=t.match(/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/);if(e){var n=parseFloat(e[4]);return[v(parseInt(e[1]),0,360),v(parseFloat(e[2]),0,100),v(parseFloat(e[3]),0,100),v(isNaN(n)?1:n,0,1)]}}}function f(t){if(t){var e=t.match(/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/);if(e){var n=parseFloat(e[4]);return[v(parseInt(e[1]),0,360),v(parseFloat(e[2]),0,100),v(parseFloat(e[3]),0,100),v(isNaN(n)?1:n,0,1)]}}}function g(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function m(t,e){return"rgba("+Math.round(t[0]/255*100)+"%, "+Math.round(t[1]/255*100)+"%, "+Math.round(t[2]/255*100)+"%, "+(e||t[3]||1)+")"}function p(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function v(t,e,n){return Math.min(Math.max(e,t),n)}function b(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var y={};for(var x in u)y[u[x]]=x;var _=function(t){return t instanceof _?t:this instanceof _?(this.valid=!1,this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1},void("string"==typeof t?(e=d.getRgba(t))?this.setValues("rgb",e):(e=d.getHsla(t))?this.setValues("hsl",e):(e=d.getHwb(t))&&this.setValues("hwb",e):"object"==typeof t&&(void 0!==(e=t).r||void 0!==e.red?this.setValues("rgb",e):void 0!==e.l||void 0!==e.lightness?this.setValues("hsl",e):void 0!==e.v||void 0!==e.value?this.setValues("hsv",e):void 0!==e.w||void 0!==e.whiteness?this.setValues("hwb",e):void 0===e.c&&void 0===e.cyan||this.setValues("cmyk",e)))):new _(t);var e};_.prototype={isValid:function(){return this.valid},rgb:function(){return this.setSpace("rgb",arguments)},hsl:function(){return this.setSpace("hsl",arguments)},hsv:function(){return this.setSpace("hsv",arguments)},hwb:function(){return this.setSpace("hwb",arguments)},cmyk:function(){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){var t=this.values;return 1!==t.alpha?t.hwb.concat([t.alpha]):t.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var t=this.values;return t.rgb.concat([t.alpha])},hslaArray:function(){var t=this.values;return t.hsl.concat([t.alpha])},alpha:function(t){return void 0===t?this.values.alpha:(this.setValues("alpha",t),this)},red:function(t){return this.setChannel("rgb",0,t)},green:function(t){return this.setChannel("rgb",1,t)},blue:function(t){return this.setChannel("rgb",2,t)},hue:function(t){return t&&(t=(t%=360)<0?360+t:t),this.setChannel("hsl",0,t)},saturation:function(t){return this.setChannel("hsl",1,t)},lightness:function(t){return this.setChannel("hsl",2,t)},saturationv:function(t){return this.setChannel("hsv",1,t)},whiteness:function(t){return this.setChannel("hwb",1,t)},blackness:function(t){return this.setChannel("hwb",2,t)},value:function(t){return this.setChannel("hsv",2,t)},cyan:function(t){return this.setChannel("cmyk",0,t)},magenta:function(t){return this.setChannel("cmyk",1,t)},yellow:function(t){return this.setChannel("cmyk",2,t)},black:function(t){return this.setChannel("cmyk",3,t)},hexString:function(){return d.hexString(this.values.rgb)},rgbString:function(){return d.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return d.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return d.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return d.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return d.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return d.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return d.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){var t=this.values.rgb;return t[0]<<16|t[1]<<8|t[2]},luminosity:function(){for(var t=this.values.rgb,e=[],n=0;n<t.length;n++){var i=t[n]/255;e[n]=i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),n=t.luminosity();return e>n?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=n<0?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=this,i=t,a=void 0===e?.5:e,r=2*a-1,o=n.alpha()-i.alpha(),s=((r*o==-1?r:(r+o)/(1+r*o))+1)/2,l=1-s;return this.rgb(s*n.red()+l*i.red(),s*n.green()+l*i.green(),s*n.blue()+l*i.blue()).alpha(n.alpha()*a+i.alpha()*(1-a))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new _,i=this.values,a=n.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],"[object Array]"===(e={}.toString.call(t))?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return n}},_.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},_.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},_.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i<t.length;i++)n[t.charAt(i)]=e[t][i];return 1!==e.alpha&&(n.a=e.alpha),n},_.prototype.setValues=function(t,e){var n,i,a=this.values,r=this.spaces,o=this.maxes,s=1;if(this.valid=!0,"alpha"===t)s=e;else if(e.length)a[t]=e.slice(0,t.length),s=e[t.length];else if(void 0!==e[t.charAt(0)]){for(n=0;n<t.length;n++)a[t][n]=e[t.charAt(n)];s=e.a}else if(void 0!==e[r[t][0]]){var u=r[t];for(n=0;n<t.length;n++)a[t][n]=e[u[n]];s=e.alpha}if(a.alpha=Math.max(0,Math.min(1,void 0===s?a.alpha:s)),"alpha"===t)return!1;for(n=0;n<t.length;n++)i=Math.max(0,Math.min(o[t][n],a[t][n])),a[t][n]=Math.round(i);for(var d in r)d!==t&&(a[d]=l[t][d](a[t]));return!0},_.prototype.setSpace=function(t,e){var n=e[0];return void 0===n?this.getValues(t):("number"==typeof n&&(n=Array.prototype.slice.call(e)),this.setValues(t,n),this)},_.prototype.setChannel=function(t,e,n){var i=this.values[t];return void 0===n?i[e]:(n===i[e]||(i[e]=n,this.setValues(t,i)),this)},"undefined"!=typeof window&&(window.Color=_);var w=_;function k(t){return-1===["__proto__","prototype","constructor"].indexOf(t)}var M,S={noop:function(){},uid:(M=0,function(){return M++}),isNullOrUndef:function(t){return null==t},isArray:function(t){if(Array.isArray&&Array.isArray(t))return!0;var e=Object.prototype.toString.call(t);return"[object"===e.substr(0,7)&&"Array]"===e.substr(-6)},isObject:function(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)},isFinite:function(t){return("number"==typeof t||t instanceof Number)&&isFinite(t)},valueOrDefault:function(t,e){return void 0===t?e:t},valueAtIndexOrDefault:function(t,e,n){return S.valueOrDefault(S.isArray(t)?t[e]:t,n)},callback:function(t,e,n){if(t&&"function"==typeof t.call)return t.apply(n,e)},each:function(t,e,n,i){var a,r,o;if(S.isArray(t))if(r=t.length,i)for(a=r-1;a>=0;a--)e.call(n,t[a],a);else for(a=0;a<r;a++)e.call(n,t[a],a);else if(S.isObject(t))for(r=(o=Object.keys(t)).length,a=0;a<r;a++)e.call(n,t[o[a]],o[a])},arrayEquals:function(t,e){var n,i,a,r;if(!t||!e||t.length!==e.length)return!1;for(n=0,i=t.length;n<i;++n)if(a=t[n],r=e[n],a instanceof Array&&r instanceof Array){if(!S.arrayEquals(a,r))return!1}else if(a!==r)return!1;return!0},clone:function(t){if(S.isArray(t))return t.map(S.clone);if(S.isObject(t)){for(var e=Object.create(t),n=Object.keys(t),i=n.length,a=0;a<i;++a)e[n[a]]=S.clone(t[n[a]]);return e}return t},_merger:function(t,e,n,i){if(k(t)){var a=e[t],r=n[t];S.isObject(a)&&S.isObject(r)?S.merge(a,r,i):e[t]=S.clone(r)}},_mergerIf:function(t,e,n){if(k(t)){var i=e[t],a=n[t];S.isObject(i)&&S.isObject(a)?S.mergeIf(i,a):e.hasOwnProperty(t)||(e[t]=S.clone(a))}},merge:function(t,e,n){var i,a,r,o,s,l=S.isArray(e)?e:[e],u=l.length;if(!S.isObject(t))return t;for(i=(n=n||{}).merger||S._merger,a=0;a<u;++a)if(e=l[a],S.isObject(e))for(s=0,o=(r=Object.keys(e)).length;s<o;++s)i(r[s],t,e,n);return t},mergeIf:function(t,e){return S.merge(t,e,{merger:S._mergerIf})},extend:Object.assign||function(t){return S.merge(t,[].slice.call(arguments,1),{merger:function(t,e,n){e[t]=n[t]}})},inherits:function(t){var e=this,n=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},i=function(){this.constructor=n};return i.prototype=e.prototype,n.prototype=new i,n.extend=S.inherits,t&&S.extend(n.prototype,t),n.__super__=e.prototype,n},_deprecated:function(t,e,n,i){void 0!==e&&console.warn(t+': "'+n+'" is deprecated. Please use "'+i+'" instead')}},D=S;S.callCallback=S.callback,S.indexOf=function(t,e,n){return Array.prototype.indexOf.call(t,e,n)},S.getValueOrDefault=S.valueOrDefault,S.getValueAtIndexOrDefault=S.valueAtIndexOrDefault;var C={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return(t-=1)*t*t+1},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-((t-=1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return t*t*t*t*t},easeOutQuint:function(t){return(t-=1)*t*t*t*t+1},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return 1-Math.cos(t*(Math.PI/2))},easeOutSine:function(t){return Math.sin(t*(Math.PI/2))},easeInOutSine:function(t){return-.5*(Math.cos(Math.PI*t)-1)},easeInExpo:function(t){return 0===t?0:Math.pow(2,10*(t-1))},easeOutExpo:function(t){return 1===t?1:1-Math.pow(2,-10*t)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(2-Math.pow(2,-10*--t))},easeInCirc:function(t){return t>=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2==(t/=.5)?1:(n||(n=.45),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),t<1?i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*-.5:i*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return t*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-C.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*C.easeInBounce(2*t):.5*C.easeOutBounce(2*t-1)+.5}},P={effects:C};D.easingEffects=C;var T=Math.PI,O=T/180,A=2*T,F=T/2,I=T/4,L=2*T/3,R={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,n,i,a,r){if(r){var o=Math.min(r,a/2,i/2),s=e+o,l=n+o,u=e+i-o,d=n+a-o;t.moveTo(e,l),s<u&&l<d?(t.arc(s,l,o,-T,-F),t.arc(u,l,o,-F,0),t.arc(u,d,o,0,F),t.arc(s,d,o,F,T)):s<u?(t.moveTo(s,n),t.arc(u,l,o,-F,F),t.arc(s,l,o,F,T+F)):l<d?(t.arc(s,l,o,-T,0),t.arc(s,d,o,0,T)):t.arc(s,l,o,-T,T),t.closePath(),t.moveTo(e,n)}else t.rect(e,n,i,a)},drawPoint:function(t,e,n,i,a,r){var o,s,l,u,d,h=(r||0)*O;if(e&&"object"==typeof e&&("[object HTMLImageElement]"===(o=e.toString())||"[object HTMLCanvasElement]"===o))return t.save(),t.translate(i,a),t.rotate(h),t.drawImage(e,-e.width/2,-e.height/2,e.width,e.height),void t.restore();if(!(isNaN(n)||n<=0)){switch(t.beginPath(),e){default:t.arc(i,a,n,0,A),t.closePath();break;case"triangle":t.moveTo(i+Math.sin(h)*n,a-Math.cos(h)*n),h+=L,t.lineTo(i+Math.sin(h)*n,a-Math.cos(h)*n),h+=L,t.lineTo(i+Math.sin(h)*n,a-Math.cos(h)*n),t.closePath();break;case"rectRounded":u=n-(d=.516*n),s=Math.cos(h+I)*u,l=Math.sin(h+I)*u,t.arc(i-s,a-l,d,h-T,h-F),t.arc(i+l,a-s,d,h-F,h),t.arc(i+s,a+l,d,h,h+F),t.arc(i-l,a+s,d,h+F,h+T),t.closePath();break;case"rect":if(!r){u=Math.SQRT1_2*n,t.rect(i-u,a-u,2*u,2*u);break}h+=I;case"rectRot":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+l,a-s),t.lineTo(i+s,a+l),t.lineTo(i-l,a+s),t.closePath();break;case"crossRot":h+=I;case"cross":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i+l,a-s),t.lineTo(i-l,a+s);break;case"star":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i+l,a-s),t.lineTo(i-l,a+s),h+=I,s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i+l,a-s),t.lineTo(i-l,a+s);break;case"line":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l);break;case"dash":t.moveTo(i,a),t.lineTo(i+Math.cos(h)*n,a+Math.sin(h)*n)}t.fill(),t.stroke()}},_isPointInArea:function(t,e){var n=1e-6;return t.x>e.left-n&&t.x<e.right+n&&t.y>e.top-n&&t.y<e.bottom+n},clipArea:function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},unclipArea:function(t){t.restore()},lineTo:function(t,e,n,i){var a=n.steppedLine;if(a){if("middle"===a){var r=(e.x+n.x)/2;t.lineTo(r,i?n.y:e.y),t.lineTo(r,i?e.y:n.y)}else"after"===a&&!i||"after"!==a&&i?t.lineTo(e.x,n.y):t.lineTo(n.x,e.y);t.lineTo(n.x,n.y)}else n.tension?t.bezierCurveTo(i?e.controlPointPreviousX:e.controlPointNextX,i?e.controlPointPreviousY:e.controlPointNextY,i?n.controlPointNextX:n.controlPointPreviousX,i?n.controlPointNextY:n.controlPointPreviousY,n.x,n.y):t.lineTo(n.x,n.y)}},N=R;D.clear=R.clear,D.drawRoundedRectangle=function(t){t.beginPath(),R.roundedRect.apply(R,arguments)};var W={_set:function(t,e){return D.merge(this[t]||(this[t]={}),e)}};W._set("global",{defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",defaultLineHeight:1.2,showLines:!0});var Y=W,z=D.valueOrDefault;var E={toLineHeight:function(t,e){var n=(""+t).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);if(!n||"normal"===n[1])return 1.2*e;switch(t=+n[2],n[3]){case"px":return t;case"%":t/=100}return e*t},toPadding:function(t){var e,n,i,a;return D.isObject(t)?(e=+t.top||0,n=+t.right||0,i=+t.bottom||0,a=+t.left||0):e=n=i=a=+t||0,{top:e,right:n,bottom:i,left:a,height:e+i,width:a+n}},_parseFont:function(t){var e=Y.global,n=z(t.fontSize,e.defaultFontSize),i={family:z(t.fontFamily,e.defaultFontFamily),lineHeight:D.options.toLineHeight(z(t.lineHeight,e.defaultLineHeight),n),size:n,style:z(t.fontStyle,e.defaultFontStyle),weight:null,string:""};return i.string=function(t){return!t||D.isNullOrUndef(t.size)||D.isNullOrUndef(t.family)?null:(t.style?t.style+" ":"")+(t.weight?t.weight+" ":"")+t.size+"px "+t.family}(i),i},resolve:function(t,e,n,i){var a,r,o,s=!0;for(a=0,r=t.length;a<r;++a)if(void 0!==(o=t[a])&&(void 0!==e&&"function"==typeof o&&(o=o(e),s=!1),void 0!==n&&D.isArray(o)&&(o=o[n],s=!1),void 0!==o))return i&&!s&&(i.cacheable=!1),o}},V={_factorize:function(t){var e,n=[],i=Math.sqrt(t);for(e=1;e<i;e++)t%e==0&&(n.push(e),n.push(t/e));return i===(0|i)&&n.push(i),n.sort(function(t,e){return t-e}).pop(),n},log10:Math.log10||function(t){var e=Math.log(t)*Math.LOG10E,n=Math.round(e);return t===Math.pow(10,n)?n:e}},H=V;D.log10=V.log10;var B=D,j=P,U=N,G=E,q=H,Z={getRtlAdapter:function(t,e,n){return t?function(t,e){return{x:function(n){return t+t+e-n},setWidth:function(t){e=t},textAlign:function(t){return"center"===t?t:"right"===t?"left":"right"},xPlus:function(t,e){return t-e},leftForLtr:function(t,e){return t-e}}}(e,n):{x:function(t){return t},setWidth:function(t){},textAlign:function(t){return t},xPlus:function(t,e){return t+e},leftForLtr:function(t,e){return t}}},overrideTextDirection:function(t,e){var n,i;"ltr"!==e&&"rtl"!==e||(i=[(n=t.canvas.style).getPropertyValue("direction"),n.getPropertyPriority("direction")],n.setProperty("direction",e,"important"),t.prevTextDirection=i)},restoreTextDirection:function(t){var e=t.prevTextDirection;void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty("direction",e[0],e[1]))}};B.easing=j,B.canvas=U,B.options=G,B.math=q,B.rtl=Z;var $=function(t){B.extend(this,t),this.initialize.apply(this,arguments)};B.extend($.prototype,{_type:void 0,initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=B.extend({},t._model)),t._start={},t},transition:function(t){var e=this,n=e._model,i=e._start,a=e._view;return n&&1!==t?(a||(a=e._view={}),i||(i=e._start={}),function(t,e,n,i){var a,r,o,s,l,u,d,h,c,f=Object.keys(n);for(a=0,r=f.length;a<r;++a)if(u=n[o=f[a]],e.hasOwnProperty(o)||(e[o]=u),(s=e[o])!==u&&"_"!==o[0]){if(t.hasOwnProperty(o)||(t[o]=s),(d=typeof u)==typeof(l=t[o]))if("string"===d){if((h=w(l)).valid&&(c=w(u)).valid){e[o]=c.mix(h,i).rgbString();continue}}else if(B.isFinite(l)&&B.isFinite(u)){e[o]=l+(u-l)*i;continue}e[o]=u}}(i,a,n,t),e):(e._view=B.extend({},n),e._start=null,e)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return B.isNumber(this._model.x)&&B.isNumber(this._model.y)}}),$.extend=B.inherits;var X=$,K=X.extend({chart:null,currentStep:0,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),J=K;Object.defineProperty(K.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(K.prototype,"chartInstance",{get:function(){return this.chart},set:function(t){this.chart=t}}),Y._set("global",{animation:{duration:1e3,easing:"easeOutQuart",onProgress:B.noop,onComplete:B.noop}});var Q={animations:[],request:null,addAnimation:function(t,e,n,i){var a,r,o=this.animations;for(e.chart=t,e.startTime=Date.now(),e.duration=n,i||(t.animating=!0),a=0,r=o.length;a<r;++a)if(o[a].chart===t)return void(o[a]=e);o.push(e),1===o.length&&this.requestAnimationFrame()},cancelAnimation:function(t){var e=B.findIndex(this.animations,function(e){return e.chart===t});-1!==e&&(this.animations.splice(e,1),t.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=B.requestAnimFrame.call(window,function(){t.request=null,t.startDigest()}))},startDigest:function(){var t=this;t.advance(),t.animations.length>0&&t.requestAnimationFrame()},advance:function(){for(var t,e,n,i,a=this.animations,r=0;r<a.length;)e=(t=a[r]).chart,n=t.numSteps,i=Math.floor((Date.now()-t.startTime)/t.duration*n)+1,t.currentStep=Math.min(i,n),B.callback(t.render,[e,t],e),B.callback(t.onAnimationProgress,[t],e),t.currentStep>=n?(B.callback(t.onAnimationComplete,[t],e),e.animating=!1,a.splice(r,1)):++r}},tt=B.options.resolve,et=["push","pop","shift","splice","unshift"];function nt(t,e){var n=t._chartjs;if(n){var i=n.listeners,a=i.indexOf(e);-1!==a&&i.splice(a,1),i.length>0||(et.forEach(function(e){delete t[e]}),delete t._chartjs)}}var it=function(t,e){this.initialize(t,e)};B.extend(it.prototype,{datasetElementType:null,dataElementType:null,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth"],_dataElementOptions:["backgroundColor","borderColor","borderWidth","pointStyle"],initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements(),n._type=n.getMeta().type},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),n=t.chart,i=n.scales,a=t.getDataset(),r=n.options.scales;null!==e.xAxisID&&e.xAxisID in i&&!a.xAxisID||(e.xAxisID=a.xAxisID||r.xAxes[0].id),null!==e.yAxisID&&e.yAxisID in i&&!a.yAxisID||(e.yAxisID=a.yAxisID||r.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},_getValueScaleId:function(){return this.getMeta().yAxisID},_getIndexScaleId:function(){return this.getMeta().xAxisID},_getValueScale:function(){return this.getScaleForId(this._getValueScaleId())},_getIndexScale:function(){return this.getScaleForId(this._getIndexScaleId())},reset:function(){this._update(!0)},destroy:function(){this._data&&nt(this._data,this)},createMetaDataset:function(){var t=this,e=t.datasetElementType;return e&&new e({_chart:t.chart,_datasetIndex:t.index})},createMetaData:function(t){var e=this,n=e.dataElementType;return n&&new n({_chart:e.chart,_datasetIndex:e.index,_index:t})},addElements:function(){var t,e,n=this,i=n.getMeta(),a=n.getDataset().data||[],r=i.data;for(t=0,e=a.length;t<e;++t)r[t]=r[t]||n.createMetaData(t);i.dataset=i.dataset||n.createMetaDataset()},addElementAndReset:function(t){var e=this.createMetaData(t);this.getMeta().data.splice(t,0,e),this.updateElement(e,t,!0)},buildOrUpdateElements:function(){var t,e,n=this,i=n.getDataset(),a=i.data||(i.data=[]);n._data!==a&&(n._data&&nt(n._data,n),a&&Object.isExtensible(a)&&(e=n,(t=a)._chartjs?t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),et.forEach(function(e){var n="onData"+e.charAt(0).toUpperCase()+e.slice(1),i=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value:function(){var e=Array.prototype.slice.call(arguments),a=i.apply(this,e);return B.each(t._chartjs.listeners,function(t){"function"==typeof t[n]&&t[n].apply(t,e)}),a}})}))),n._data=a),n.resyncElements()},_configure:function(){var t=this;t._config=B.merge(Object.create(null),[t.chart.options.datasets[t._type],t.getDataset()],{merger:function(t,e,n){"_meta"!==t&&"data"!==t&&B._merger(t,e,n)}})},_update:function(t){var e=this;e._configure(),e._cachedDataOpts=null,e.update(t)},update:B.noop,transition:function(t){for(var e=this.getMeta(),n=e.data||[],i=n.length,a=0;a<i;++a)n[a].transition(t);e.dataset&&e.dataset.transition(t)},draw:function(){var t=this.getMeta(),e=t.data||[],n=e.length,i=0;for(t.dataset&&t.dataset.draw();i<n;++i)e[i].draw()},getStyle:function(t){var e,n=this,i=n.getMeta(),a=i.dataset;return n._configure(),a&&void 0===t?e=n._resolveDatasetElementOptions(a||{}):(t=t||0,e=n._resolveDataElementOptions(i.data[t]||{},t)),!1!==e.fill&&null!==e.fill||(e.backgroundColor=e.borderColor),e},_resolveDatasetElementOptions:function(t,e){var n,i,a,r,o=this,s=o.chart,l=o._config,u=t.custom||{},d=s.options.elements[o.datasetElementType.prototype._type]||{},h=o._datasetElementOptions,c={},f={chart:s,dataset:o.getDataset(),datasetIndex:o.index,hover:e};for(n=0,i=h.length;n<i;++n)a=h[n],r=e?"hover"+a.charAt(0).toUpperCase()+a.slice(1):a,c[a]=tt([u[r],l[r],d[r]],f);return c},_resolveDataElementOptions:function(t,e){var n=this,i=t&&t.custom,a=n._cachedDataOpts;if(a&&!i)return a;var r,o,s,l,u=n.chart,d=n._config,h=u.options.elements[n.dataElementType.prototype._type]||{},c=n._dataElementOptions,f={},g={chart:u,dataIndex:e,dataset:n.getDataset(),datasetIndex:n.index},m={cacheable:!i};if(i=i||{},B.isArray(c))for(o=0,s=c.length;o<s;++o)f[l=c[o]]=tt([i[l],d[l],h[l]],g,e,m);else for(o=0,s=(r=Object.keys(c)).length;o<s;++o)f[l=r[o]]=tt([i[l],d[c[l]],d[l],h[l]],g,e,m);return m.cacheable&&(n._cachedDataOpts=Object.freeze(f)),f},removeHoverStyle:function(t){B.merge(t._model,t.$previousStyle||{}),delete t.$previousStyle},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t._index,i=t.custom||{},a=t._model,r=B.getHoverColor;t.$previousStyle={backgroundColor:a.backgroundColor,borderColor:a.borderColor,borderWidth:a.borderWidth},a.backgroundColor=tt([i.hoverBackgroundColor,e.hoverBackgroundColor,r(a.backgroundColor)],void 0,n),a.borderColor=tt([i.hoverBorderColor,e.hoverBorderColor,r(a.borderColor)],void 0,n),a.borderWidth=tt([i.hoverBorderWidth,e.hoverBorderWidth,a.borderWidth],void 0,n)},_removeDatasetHoverStyle:function(){var t=this.getMeta().dataset;t&&this.removeHoverStyle(t)},_setDatasetHoverStyle:function(){var t,e,n,i,a,r,o=this.getMeta().dataset,s={};if(o){for(r=o._model,a=this._resolveDatasetElementOptions(o,!0),t=0,e=(i=Object.keys(a)).length;t<e;++t)s[n=i[t]]=r[n],r[n]=a[n];o.$previousStyle=s}},resyncElements:function(){var t=this,e=t.getMeta(),n=t.getDataset().data,i=e.data.length,a=n.length;a<i?e.data.splice(a,i-a):a>i&&t.insertElements(i,a-i)},insertElements:function(t,e){for(var n=0;n<e;++n)this.addElementAndReset(t+n)},onDataPush:function(){var t=arguments.length;this.insertElements(this.getDataset().data.length-t,t)},onDataPop:function(){this.getMeta().data.pop()},onDataShift:function(){this.getMeta().data.shift()},onDataSplice:function(t,e){this.getMeta().data.splice(t,e),this.insertElements(t,arguments.length-2)},onDataUnshift:function(){this.insertElements(0,arguments.length)}}),it.extend=B.inherits;var at=it,rt=2*Math.PI;function ot(t,e){var n=e.startAngle,i=e.endAngle,a=e.pixelMargin,r=a/e.outerRadius,o=e.x,s=e.y;t.beginPath(),t.arc(o,s,e.outerRadius,n-r,i+r),e.innerRadius>a?(r=a/e.innerRadius,t.arc(o,s,e.innerRadius-a,i+r,n-r,!0)):t.arc(o,s,a,i+Math.PI/2,n-Math.PI/2),t.closePath(),t.clip()}function st(t,e,n){var i="inner"===e.borderAlign;i?(t.lineWidth=2*e.borderWidth,t.lineJoin="round"):(t.lineWidth=e.borderWidth,t.lineJoin="bevel"),n.fullCircles&&function(t,e,n,i){var a,r=n.endAngle;for(i&&(n.endAngle=n.startAngle+rt,ot(t,n),n.endAngle=r,n.endAngle===n.startAngle&&n.fullCircles&&(n.endAngle+=rt,n.fullCircles--)),t.beginPath(),t.arc(n.x,n.y,n.innerRadius,n.startAngle+rt,n.startAngle,!0),a=0;a<n.fullCircles;++a)t.stroke();for(t.beginPath(),t.arc(n.x,n.y,e.outerRadius,n.startAngle,n.startAngle+rt),a=0;a<n.fullCircles;++a)t.stroke()}(t,e,n,i),i&&ot(t,n),t.beginPath(),t.arc(n.x,n.y,e.outerRadius,n.startAngle,n.endAngle),t.arc(n.x,n.y,n.innerRadius,n.endAngle,n.startAngle,!0),t.closePath(),t.stroke()}Y._set("global",{elements:{arc:{backgroundColor:Y.global.defaultColor,borderColor:"#fff",borderWidth:2,borderAlign:"center"}}});var lt=X.extend({_type:"arc",inLabelRange:function(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)<Math.pow(e.radius+e.hoverRadius,2)},inRange:function(t,e){var n=this._view;if(n){for(var i=B.getAngleFromPoint(n,{x:t,y:e}),a=i.angle,r=i.distance,o=n.startAngle,s=n.endAngle;s<o;)s+=rt;for(;a>s;)a-=rt;for(;a<o;)a+=rt;var l=a>=o&&a<=s,u=r>=n.innerRadius&&r<=n.outerRadius;return l&&u}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t,e=this._chart.ctx,n=this._view,i="inner"===n.borderAlign?.33:0,a={x:n.x,y:n.y,innerRadius:n.innerRadius,outerRadius:Math.max(n.outerRadius-i,0),pixelMargin:i,startAngle:n.startAngle,endAngle:n.endAngle,fullCircles:Math.floor(n.circumference/rt)};if(e.save(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,a.fullCircles){for(a.endAngle=a.startAngle+rt,e.beginPath(),e.arc(a.x,a.y,a.outerRadius,a.startAngle,a.endAngle),e.arc(a.x,a.y,a.innerRadius,a.endAngle,a.startAngle,!0),e.closePath(),t=0;t<a.fullCircles;++t)e.fill();a.endAngle=a.startAngle+n.circumference%rt}e.beginPath(),e.arc(a.x,a.y,a.outerRadius,a.startAngle,a.endAngle),e.arc(a.x,a.y,a.innerRadius,a.endAngle,a.startAngle,!0),e.closePath(),e.fill(),n.borderWidth&&st(e,n,a),e.restore()}}),ut=B.valueOrDefault,dt=Y.global.defaultColor;Y._set("global",{elements:{line:{tension:.4,backgroundColor:dt,borderWidth:3,borderColor:dt,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}});var ht=X.extend({_type:"line",draw:function(){var t,e,n,i=this,a=i._view,r=i._chart.ctx,o=a.spanGaps,s=i._children.slice(),l=Y.global,u=l.elements.line,d=-1,h=i._loop;if(s.length){if(i._loop){for(t=0;t<s.length;++t)if(e=B.previousItem(s,t),!s[t]._view.skip&&e._view.skip){s=s.slice(t).concat(s.slice(0,t)),h=o;break}h&&s.push(s[0])}for(r.save(),r.lineCap=a.borderCapStyle||u.borderCapStyle,r.setLineDash&&r.setLineDash(a.borderDash||u.borderDash),r.lineDashOffset=ut(a.borderDashOffset,u.borderDashOffset),r.lineJoin=a.borderJoinStyle||u.borderJoinStyle,r.lineWidth=ut(a.borderWidth,u.borderWidth),r.strokeStyle=a.borderColor||l.defaultColor,r.beginPath(),(n=s[0]._view).skip||(r.moveTo(n.x,n.y),d=0),t=1;t<s.length;++t)n=s[t]._view,e=-1===d?B.previousItem(s,t):s[d],n.skip||(d!==t-1&&!o||-1===d?r.moveTo(n.x,n.y):B.canvas.lineTo(r,e._view,n),d=t);h&&r.closePath(),r.stroke(),r.restore()}}}),ct=B.valueOrDefault,ft=Y.global.defaultColor;function gt(t){var e=this._view;return!!e&&Math.abs(t-e.x)<e.radius+e.hitRadius}Y._set("global",{elements:{point:{radius:3,pointStyle:"circle",backgroundColor:ft,borderColor:ft,borderWidth:1,hitRadius:1,hoverRadius:4,hoverBorderWidth:1}}});var mt=X.extend({_type:"point",inRange:function(t,e){var n=this._view;return!!n&&Math.pow(t-n.x,2)+Math.pow(e-n.y,2)<Math.pow(n.hitRadius+n.radius,2)},inLabelRange:gt,inXRange:gt,inYRange:function(t){var e=this._view;return!!e&&Math.abs(t-e.y)<e.radius+e.hitRadius},getCenterPoint:function(){var t=this._view;return{x:t.x,y:t.y}},getArea:function(){return Math.PI*Math.pow(this._view.radius,2)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y,padding:t.radius+t.borderWidth}},draw:function(t){var e=this._view,n=this._chart.ctx,i=e.pointStyle,a=e.rotation,r=e.radius,o=e.x,s=e.y,l=Y.global,u=l.defaultColor;e.skip||(void 0===t||B.canvas._isPointInArea(e,t))&&(n.strokeStyle=e.borderColor||u,n.lineWidth=ct(e.borderWidth,l.elements.point.borderWidth),n.fillStyle=e.backgroundColor||u,B.canvas.drawPoint(n,i,r,o,s,a))}}),pt=Y.global.defaultColor;function vt(t){return t&&void 0!==t.width}function bt(t){var e,n,i,a,r;return vt(t)?(r=t.width/2,e=t.x-r,n=t.x+r,i=Math.min(t.y,t.base),a=Math.max(t.y,t.base)):(r=t.height/2,e=Math.min(t.x,t.base),n=Math.max(t.x,t.base),i=t.y-r,a=t.y+r),{left:e,top:i,right:n,bottom:a}}function yt(t,e,n){return t===e?n:t===n?e:t}function xt(t,e,n){var i,a,r,o,s=t.borderWidth,l=function(t){var e=t.borderSkipped,n={};return e?(t.horizontal?t.base>t.x&&(e=yt(e,"left","right")):t.base<t.y&&(e=yt(e,"bottom","top")),n[e]=!0,n):n}(t);return B.isObject(s)?(i=+s.top||0,a=+s.right||0,r=+s.bottom||0,o=+s.left||0):i=a=r=o=+s||0,{t:l.top||i<0?0:i>n?n:i,r:l.right||a<0?0:a>e?e:a,b:l.bottom||r<0?0:r>n?n:r,l:l.left||o<0?0:o>e?e:o}}function _t(t,e,n){var i=null===e,a=null===n,r=!(!t||i&&a)&&bt(t);return r&&(i||e>=r.left&&e<=r.right)&&(a||n>=r.top&&n<=r.bottom)}Y._set("global",{elements:{rectangle:{backgroundColor:pt,borderColor:pt,borderSkipped:"bottom",borderWidth:0}}});var wt=X.extend({_type:"rectangle",draw:function(){var t=this._chart.ctx,e=this._view,n=function(t){var e=bt(t),n=e.right-e.left,i=e.bottom-e.top,a=xt(t,n/2,i/2);return{outer:{x:e.left,y:e.top,w:n,h:i},inner:{x:e.left+a.l,y:e.top+a.t,w:n-a.l-a.r,h:i-a.t-a.b}}}(e),i=n.outer,a=n.inner;t.fillStyle=e.backgroundColor,t.fillRect(i.x,i.y,i.w,i.h),i.w===a.w&&i.h===a.h||(t.save(),t.beginPath(),t.rect(i.x,i.y,i.w,i.h),t.clip(),t.fillStyle=e.borderColor,t.rect(a.x,a.y,a.w,a.h),t.fill("evenodd"),t.restore())},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){return _t(this._view,t,e)},inLabelRange:function(t,e){var n=this._view;return vt(n)?_t(n,t,null):_t(n,null,e)},inXRange:function(t){return _t(this._view,t,null)},inYRange:function(t){return _t(this._view,null,t)},getCenterPoint:function(){var t,e,n=this._view;return vt(n)?(t=n.x,e=(n.y+n.base)/2):(t=(n.x+n.base)/2,e=n.y),{x:t,y:e}},getArea:function(){var t=this._view;return vt(t)?t.width*Math.abs(t.y-t.base):t.height*Math.abs(t.x-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}}),kt={},Mt=lt,St=ht,Dt=mt,Ct=wt;kt.Arc=Mt,kt.Line=St,kt.Point=Dt,kt.Rectangle=Ct;var Pt=B._deprecated,Tt=B.valueOrDefault;function Ot(t,e,n){var i,a,r=n.barThickness,o=e.stackCount,s=e.pixels[t],l=B.isNullOrUndef(r)?function(t,e){var n,i,a,r,o=t._length;for(a=1,r=e.length;a<r;++a)o=Math.min(o,Math.abs(e[a]-e[a-1]));for(a=0,r=t.getTicks().length;a<r;++a)i=t.getPixelForTick(a),o=a>0?Math.min(o,Math.abs(i-n)):o,n=i;return o}(e.scale,e.pixels):-1;return B.isNullOrUndef(r)?(i=l*n.categoryPercentage,a=n.barPercentage):(i=r*o,a=1),{chunk:i/o,ratio:a,start:s-i/2}}Y._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),Y._set("global",{datasets:{bar:{categoryPercentage:.8,barPercentage:.9}}});var At=at.extend({dataElementType:kt.Rectangle,_dataElementOptions:["backgroundColor","borderColor","borderSkipped","borderWidth","barPercentage","barThickness","categoryPercentage","maxBarThickness","minBarLength"],initialize:function(){var t,e,n=this;at.prototype.initialize.apply(n,arguments),(t=n.getMeta()).stack=n.getDataset().stack,t.bar=!0,e=n._getIndexScale().options,Pt("bar chart",e.barPercentage,"scales.[x/y]Axes.barPercentage","dataset.barPercentage"),Pt("bar chart",e.barThickness,"scales.[x/y]Axes.barThickness","dataset.barThickness"),Pt("bar chart",e.categoryPercentage,"scales.[x/y]Axes.categoryPercentage","dataset.categoryPercentage"),Pt("bar chart",n._getValueScale().options.minBarLength,"scales.[x/y]Axes.minBarLength","dataset.minBarLength"),Pt("bar chart",e.maxBarThickness,"scales.[x/y]Axes.maxBarThickness","dataset.maxBarThickness")},update:function(t){var e,n,i=this,a=i.getMeta().data;for(i._ruler=i.getRuler(),e=0,n=a.length;e<n;++e)i.updateElement(a[e],e,t)},updateElement:function(t,e,n){var i=this,a=i.getMeta(),r=i.getDataset(),o=i._resolveDataElementOptions(t,e);t._xScale=i.getScaleForId(a.xAxisID),t._yScale=i.getScaleForId(a.yAxisID),t._datasetIndex=i.index,t._index=e,t._model={backgroundColor:o.backgroundColor,borderColor:o.borderColor,borderSkipped:o.borderSkipped,borderWidth:o.borderWidth,datasetLabel:r.label,label:i.chart.data.labels[e]},B.isArray(r.data[e])&&(t._model.borderSkipped=null),i._updateElementGeometry(t,e,n,o),t.pivot()},_updateElementGeometry:function(t,e,n,i){var a=this,r=t._model,o=a._getValueScale(),s=o.getBasePixel(),l=o.isHorizontal(),u=a._ruler||a.getRuler(),d=a.calculateBarValuePixels(a.index,e,i),h=a.calculateBarIndexPixels(a.index,e,u,i);r.horizontal=l,r.base=n?s:d.base,r.x=l?n?s:d.head:h.center,r.y=l?h.center:n?s:d.head,r.height=l?h.size:void 0,r.width=l?void 0:h.size},_getStacks:function(t){var e,n,i=this._getIndexScale(),a=i._getMatchingVisibleMetas(this._type),r=i.options.stacked,o=a.length,s=[];for(e=0;e<o&&(n=a[e],(!1===r||-1===s.indexOf(n.stack)||void 0===r&&void 0===n.stack)&&s.push(n.stack),n.index!==t);++e);return s},getStackCount:function(){return this._getStacks().length},getStackIndex:function(t,e){var n=this._getStacks(t),i=void 0!==e?n.indexOf(e):-1;return-1===i?n.length-1:i},getRuler:function(){var t,e,n=this,i=n._getIndexScale(),a=[];for(t=0,e=n.getMeta().data.length;t<e;++t)a.push(i.getPixelForValue(null,t,n.index));return{pixels:a,start:i._startPixel,end:i._endPixel,stackCount:n.getStackCount(),scale:i}},calculateBarValuePixels:function(t,e,n){var i,a,r,o,s,l,u,d=this,h=d.chart,c=d._getValueScale(),f=c.isHorizontal(),g=h.data.datasets,m=c._getMatchingVisibleMetas(d._type),p=c._parseValue(g[t].data[e]),v=n.minBarLength,b=c.options.stacked,y=d.getMeta().stack,x=void 0===p.start?0:p.max>=0&&p.min>=0?p.min:p.max,_=void 0===p.start?p.end:p.max>=0&&p.min>=0?p.max-p.min:p.min-p.max,w=m.length;if(b||void 0===b&&void 0!==y)for(i=0;i<w&&(a=m[i]).index!==t;++i)a.stack===y&&(r=void 0===(u=c._parseValue(g[a.index].data[e])).start?u.end:u.min>=0&&u.max>=0?u.max:u.min,(p.min<0&&r<0||p.max>=0&&r>0)&&(x+=r));return o=c.getPixelForValue(x),l=(s=c.getPixelForValue(x+_))-o,void 0!==v&&Math.abs(l)<v&&(l=v,s=_>=0&&!f||_<0&&f?o-v:o+v),{size:l,base:o,head:s,center:s+l/2}},calculateBarIndexPixels:function(t,e,n,i){var a="flex"===i.barThickness?function(t,e,n){var i,a=e.pixels,r=a[t],o=t>0?a[t-1]:null,s=t<a.length-1?a[t+1]:null,l=n.categoryPercentage;return null===o&&(o=r-(null===s?e.end-e.start:s-r)),null===s&&(s=r+r-o),i=r-(r-Math.min(o,s))/2*l,{chunk:Math.abs(s-o)/2*l/e.stackCount,ratio:n.barPercentage,start:i}}(e,n,i):Ot(e,n,i),r=this.getStackIndex(t,this.getMeta().stack),o=a.start+a.chunk*r+a.chunk/2,s=Math.min(Tt(i.maxBarThickness,1/0),a.chunk*a.ratio);return{base:o-s/2,head:o+s/2,center:o,size:s}},draw:function(){var t=this,e=t.chart,n=t._getValueScale(),i=t.getMeta().data,a=t.getDataset(),r=i.length,o=0;for(B.canvas.clipArea(e.ctx,e.chartArea);o<r;++o){var s=n._parseValue(a.data[o]);isNaN(s.min)||isNaN(s.max)||i[o].draw()}B.canvas.unclipArea(e.ctx)},_resolveDataElementOptions:function(){var t=this,e=B.extend({},at.prototype._resolveDataElementOptions.apply(t,arguments)),n=t._getIndexScale().options,i=t._getValueScale().options;return e.barPercentage=Tt(n.barPercentage,e.barPercentage),e.barThickness=Tt(n.barThickness,e.barThickness),e.categoryPercentage=Tt(n.categoryPercentage,e.categoryPercentage),e.maxBarThickness=Tt(n.maxBarThickness,e.maxBarThickness),e.minBarLength=Tt(i.minBarLength,e.minBarLength),e}}),Ft=B.valueOrDefault,It=B.options.resolve;Y._set("bubble",{hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(){return""},label:function(t,e){var n=e.datasets[t.datasetIndex].label||"",i=e.datasets[t.datasetIndex].data[t.index];return n+": ("+t.xLabel+", "+t.yLabel+", "+i.r+")"}}}});var Lt=at.extend({dataElementType:kt.Point,_dataElementOptions:["backgroundColor","borderColor","borderWidth","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth","hoverRadius","hitRadius","pointStyle","rotation"],update:function(t){var e=this,n=e.getMeta().data;B.each(n,function(n,i){e.updateElement(n,i,t)})},updateElement:function(t,e,n){var i=this,a=i.getMeta(),r=t.custom||{},o=i.getScaleForId(a.xAxisID),s=i.getScaleForId(a.yAxisID),l=i._resolveDataElementOptions(t,e),u=i.getDataset().data[e],d=i.index,h=n?o.getPixelForDecimal(.5):o.getPixelForValue("object"==typeof u?u:NaN,e,d),c=n?s.getBasePixel():s.getPixelForValue(u,e,d);t._xScale=o,t._yScale=s,t._options=l,t._datasetIndex=d,t._index=e,t._model={backgroundColor:l.backgroundColor,borderColor:l.borderColor,borderWidth:l.borderWidth,hitRadius:l.hitRadius,pointStyle:l.pointStyle,rotation:l.rotation,radius:n?0:l.radius,skip:r.skip||isNaN(h)||isNaN(c),x:h,y:c},t.pivot()},setHoverStyle:function(t){var e=t._model,n=t._options,i=B.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=Ft(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Ft(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Ft(n.hoverBorderWidth,n.borderWidth),e.radius=n.radius+n.hoverRadius},_resolveDataElementOptions:function(t,e){var n=this,i=n.chart,a=n.getDataset(),r=t.custom||{},o=a.data[e]||{},s=at.prototype._resolveDataElementOptions.apply(n,arguments),l={chart:i,dataIndex:e,dataset:a,datasetIndex:n.index};return n._cachedDataOpts===s&&(s=B.extend({},s)),s.radius=It([r.radius,o.r,n._config.radius,i.options.elements.point.radius],l,e),s}}),Rt=B.valueOrDefault,Nt=Math.PI,Wt=2*Nt,Yt=Nt/2;Y._set("doughnut",{animation:{animateRotate:!0,animateScale:!1},hover:{mode:"single"},legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data,o=r.datasets,s=r.labels;if(a.setAttribute("class",t.id+"-legend"),o.length)for(e=0,n=o[0].data.length;e<n;++e)(i=a.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=o[0].backgroundColor[e],s[e]&&i.appendChild(document.createTextNode(s[e]));return a.outerHTML},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(n,i){var a=t.getDatasetMeta(0),r=a.controller.getStyle(i);return{text:n,fillStyle:r.backgroundColor,strokeStyle:r.borderColor,lineWidth:r.borderWidth,hidden:isNaN(e.datasets[0].data[i])||a.data[i].hidden,index:i}}):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;n<i;++n)(a=o.getDatasetMeta(n)).data[r]&&(a.data[r].hidden=!a.data[r].hidden);o.update()}},cutoutPercentage:50,rotation:-Yt,circumference:Wt,tooltips:{callbacks:{title:function(){return""},label:function(t,e){var n=e.labels[t.index],i=": "+e.datasets[t.datasetIndex].data[t.index];return B.isArray(n)?(n=n.slice())[0]+=i:n+=i,n}}}});var zt=at.extend({dataElementType:kt.Arc,linkScales:B.noop,_dataElementOptions:["backgroundColor","borderColor","borderWidth","borderAlign","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth"],getRingIndex:function(t){for(var e=0,n=0;n<t;++n)this.chart.isDatasetVisible(n)&&++e;return e},update:function(t){var e,n,i,a,r=this,o=r.chart,s=o.chartArea,l=o.options,u=1,d=1,h=0,c=0,f=r.getMeta(),g=f.data,m=l.cutoutPercentage/100||0,p=l.circumference,v=r._getRingWeight(r.index);if(p<Wt){var b=l.rotation%Wt,y=(b+=b>=Nt?-Wt:b<-Nt?Wt:0)+p,x=Math.cos(b),_=Math.sin(b),w=Math.cos(y),k=Math.sin(y),M=b<=0&&y>=0||y>=Wt,S=b<=Yt&&y>=Yt||y>=Wt+Yt,D=b<=-Yt&&y>=-Yt||y>=Nt+Yt,C=b===-Nt||y>=Nt?-1:Math.min(x,x*m,w,w*m),P=D?-1:Math.min(_,_*m,k,k*m),T=M?1:Math.max(x,x*m,w,w*m),O=S?1:Math.max(_,_*m,k,k*m);u=(T-C)/2,d=(O-P)/2,h=-(T+C)/2,c=-(O+P)/2}for(i=0,a=g.length;i<a;++i)g[i]._options=r._resolveDataElementOptions(g[i],i);for(o.borderWidth=r.getMaxBorderWidth(),e=(s.right-s.left-o.borderWidth)/u,n=(s.bottom-s.top-o.borderWidth)/d,o.outerRadius=Math.max(Math.min(e,n)/2,0),o.innerRadius=Math.max(o.outerRadius*m,0),o.radiusLength=(o.outerRadius-o.innerRadius)/(r._getVisibleDatasetWeightTotal()||1),o.offsetX=h*o.outerRadius,o.offsetY=c*o.outerRadius,f.total=r.calculateTotal(),r.outerRadius=o.outerRadius-o.radiusLength*r._getRingWeightOffset(r.index),r.innerRadius=Math.max(r.outerRadius-o.radiusLength*v,0),i=0,a=g.length;i<a;++i)r.updateElement(g[i],i,t)},updateElement:function(t,e,n){var i=this,a=i.chart,r=a.chartArea,o=a.options,s=o.animation,l=(r.left+r.right)/2,u=(r.top+r.bottom)/2,d=o.rotation,h=o.rotation,c=i.getDataset(),f=n&&s.animateRotate||t.hidden?0:i.calculateCircumference(c.data[e])*(o.circumference/Wt),g=n&&s.animateScale?0:i.innerRadius,m=n&&s.animateScale?0:i.outerRadius,p=t._options||{};B.extend(t,{_datasetIndex:i.index,_index:e,_model:{backgroundColor:p.backgroundColor,borderColor:p.borderColor,borderWidth:p.borderWidth,borderAlign:p.borderAlign,x:l+a.offsetX,y:u+a.offsetY,startAngle:d,endAngle:h,circumference:f,outerRadius:m,innerRadius:g,label:B.valueAtIndexOrDefault(c.label,e,a.data.labels[e])}});var v=t._model;n&&s.animateRotate||(v.startAngle=0===e?o.rotation:i.getMeta().data[e-1]._model.endAngle,v.endAngle=v.startAngle+v.circumference),t.pivot()},calculateTotal:function(){var t,e=this.getDataset(),n=this.getMeta(),i=0;return B.each(n.data,function(n,a){t=e.data[a],isNaN(t)||n.hidden||(i+=Math.abs(t))}),i},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?Wt*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){var e,n,i,a,r,o,s,l,u=0,d=this.chart;if(!t)for(e=0,n=d.data.datasets.length;e<n;++e)if(d.isDatasetVisible(e)){t=(i=d.getDatasetMeta(e)).data,e!==this.index&&(r=i.controller);break}if(!t)return 0;for(e=0,n=t.length;e<n;++e)a=t[e],r?(r._configure(),o=r._resolveDataElementOptions(a,e)):o=a._options,"inner"!==o.borderAlign&&(s=o.borderWidth,u=(l=o.hoverBorderWidth)>(u=s>u?s:u)?l:u);return u},setHoverStyle:function(t){var e=t._model,n=t._options,i=B.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=Rt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Rt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Rt(n.hoverBorderWidth,n.borderWidth)},_getRingWeightOffset:function(t){for(var e=0,n=0;n<t;++n)this.chart.isDatasetVisible(n)&&(e+=this._getRingWeight(n));return e},_getRingWeight:function(t){return Math.max(Rt(this.chart.data.datasets[t].weight,1),0)},_getVisibleDatasetWeightTotal:function(){return this._getRingWeightOffset(this.chart.data.datasets.length)}});Y._set("horizontalBar",{hover:{mode:"index",axis:"y"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{type:"category",position:"left",offset:!0,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{mode:"index",axis:"y"}}),Y._set("global",{datasets:{horizontalBar:{categoryPercentage:.8,barPercentage:.9}}});var Et=At.extend({_getValueScaleId:function(){return this.getMeta().xAxisID},_getIndexScaleId:function(){return this.getMeta().yAxisID}}),Vt=B.valueOrDefault,Ht=B.options.resolve,Bt=B.canvas._isPointInArea;function jt(t,e){var n=t&&t.options.ticks||{},i=n.reverse,a=void 0===n.min?e:0,r=void 0===n.max?e:0;return{start:i?r:a,end:i?a:r}}function Ut(t,e,n){var i=n/2,a=jt(t,i),r=jt(e,i);return{top:r.end,right:a.end,bottom:r.start,left:a.start}}function Gt(t){var e,n,i,a;return B.isObject(t)?(e=t.top,n=t.right,i=t.bottom,a=t.left):e=n=i=a=t,{top:e,right:n,bottom:i,left:a}}Y._set("line",{showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}});var qt=at.extend({datasetElementType:kt.Line,dataElementType:kt.Point,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth","cubicInterpolationMode","fill"],_dataElementOptions:{backgroundColor:"pointBackgroundColor",borderColor:"pointBorderColor",borderWidth:"pointBorderWidth",hitRadius:"pointHitRadius",hoverBackgroundColor:"pointHoverBackgroundColor",hoverBorderColor:"pointHoverBorderColor",hoverBorderWidth:"pointHoverBorderWidth",hoverRadius:"pointHoverRadius",pointStyle:"pointStyle",radius:"pointRadius",rotation:"pointRotation"},update:function(t){var e,n,i=this,a=i.getMeta(),r=a.dataset,o=a.data||[],s=i.chart.options,l=i._config,u=i._showLine=Vt(l.showLine,s.showLines);for(i._xScale=i.getScaleForId(a.xAxisID),i._yScale=i.getScaleForId(a.yAxisID),u&&(void 0!==l.tension&&void 0===l.lineTension&&(l.lineTension=l.tension),r._scale=i._yScale,r._datasetIndex=i.index,r._children=o,r._model=i._resolveDatasetElementOptions(r),r.pivot()),e=0,n=o.length;e<n;++e)i.updateElement(o[e],e,t);for(u&&0!==r._model.tension&&i.updateBezierControlPoints(),e=0,n=o.length;e<n;++e)o[e].pivot()},updateElement:function(t,e,n){var i,a,r=this,o=r.getMeta(),s=t.custom||{},l=r.getDataset(),u=r.index,d=l.data[e],h=r._xScale,c=r._yScale,f=o.dataset._model,g=r._resolveDataElementOptions(t,e);i=h.getPixelForValue("object"==typeof d?d:NaN,e,u),a=n?c.getBasePixel():r.calculatePointY(d,e,u),t._xScale=h,t._yScale=c,t._options=g,t._datasetIndex=u,t._index=e,t._model={x:i,y:a,skip:s.skip||isNaN(i)||isNaN(a),radius:g.radius,pointStyle:g.pointStyle,rotation:g.rotation,backgroundColor:g.backgroundColor,borderColor:g.borderColor,borderWidth:g.borderWidth,tension:Vt(s.tension,f?f.tension:0),steppedLine:!!f&&f.steppedLine,hitRadius:g.hitRadius}},_resolveDatasetElementOptions:function(t){var e=this,n=e._config,i=t.custom||{},a=e.chart.options,r=a.elements.line,o=at.prototype._resolveDatasetElementOptions.apply(e,arguments);return o.spanGaps=Vt(n.spanGaps,a.spanGaps),o.tension=Vt(n.lineTension,r.tension),o.steppedLine=Ht([i.steppedLine,n.steppedLine,r.stepped]),o.clip=Gt(Vt(n.clip,Ut(e._xScale,e._yScale,o.borderWidth))),o},calculatePointY:function(t,e,n){var i,a,r,o,s,l,u,d=this.chart,h=this._yScale,c=0,f=0;if(h.options.stacked){for(s=+h.getRightValue(t),u=(l=d._getSortedVisibleDatasetMetas()).length,i=0;i<u&&(r=l[i]).index!==n;++i)a=d.data.datasets[r.index],"line"===r.type&&r.yAxisID===h.id&&((o=+h.getRightValue(a.data[e]))<0?f+=o||0:c+=o||0);return s<0?h.getPixelForValue(f+s):h.getPixelForValue(c+s)}return h.getPixelForValue(t)},updateBezierControlPoints:function(){var t,e,n,i,a=this.chart,r=this.getMeta(),o=r.dataset._model,s=a.chartArea,l=r.data||[];function u(t,e,n){return Math.max(Math.min(t,n),e)}if(o.spanGaps&&(l=l.filter(function(t){return!t._model.skip})),"monotone"===o.cubicInterpolationMode)B.splineCurveMonotone(l);else for(t=0,e=l.length;t<e;++t)n=l[t]._model,i=B.splineCurve(B.previousItem(l,t)._model,n,B.nextItem(l,t)._model,o.tension),n.controlPointPreviousX=i.previous.x,n.controlPointPreviousY=i.previous.y,n.controlPointNextX=i.next.x,n.controlPointNextY=i.next.y;if(a.options.elements.line.capBezierPoints)for(t=0,e=l.length;t<e;++t)n=l[t]._model,Bt(n,s)&&(t>0&&Bt(l[t-1]._model,s)&&(n.controlPointPreviousX=u(n.controlPointPreviousX,s.left,s.right),n.controlPointPreviousY=u(n.controlPointPreviousY,s.top,s.bottom)),t<l.length-1&&Bt(l[t+1]._model,s)&&(n.controlPointNextX=u(n.controlPointNextX,s.left,s.right),n.controlPointNextY=u(n.controlPointNextY,s.top,s.bottom)))},draw:function(){var t,e=this,n=e.chart,i=e.getMeta(),a=i.data||[],r=n.chartArea,o=n.canvas,s=0,l=a.length;for(e._showLine&&(t=i.dataset._model.clip,B.canvas.clipArea(n.ctx,{left:!1===t.left?0:r.left-t.left,right:!1===t.right?o.width:r.right+t.right,top:!1===t.top?0:r.top-t.top,bottom:!1===t.bottom?o.height:r.bottom+t.bottom}),i.dataset.draw(),B.canvas.unclipArea(n.ctx));s<l;++s)a[s].draw(r)},setHoverStyle:function(t){var e=t._model,n=t._options,i=B.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=Vt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Vt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Vt(n.hoverBorderWidth,n.borderWidth),e.radius=Vt(n.hoverRadius,n.radius)}}),Zt=B.options.resolve;Y._set("polarArea",{scale:{type:"radialLinear",angleLines:{display:!1},gridLines:{circular:!0},pointLabels:{display:!1},ticks:{beginAtZero:!0}},animation:{animateRotate:!0,animateScale:!0},startAngle:-.5*Math.PI,legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data,o=r.datasets,s=r.labels;if(a.setAttribute("class",t.id+"-legend"),o.length)for(e=0,n=o[0].data.length;e<n;++e)(i=a.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=o[0].backgroundColor[e],s[e]&&i.appendChild(document.createTextNode(s[e]));return a.outerHTML},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(n,i){var a=t.getDatasetMeta(0),r=a.controller.getStyle(i);return{text:n,fillStyle:r.backgroundColor,strokeStyle:r.borderColor,lineWidth:r.borderWidth,hidden:isNaN(e.datasets[0].data[i])||a.data[i].hidden,index:i}}):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;n<i;++n)(a=o.getDatasetMeta(n)).data[r].hidden=!a.data[r].hidden;o.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}});var $t=at.extend({dataElementType:kt.Arc,linkScales:B.noop,_dataElementOptions:["backgroundColor","borderColor","borderWidth","borderAlign","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth"],_getIndexScaleId:function(){return this.chart.scale.id},_getValueScaleId:function(){return this.chart.scale.id},update:function(t){var e,n,i,a=this,r=a.getDataset(),o=a.getMeta(),s=a.chart.options.startAngle||0,l=a._starts=[],u=a._angles=[],d=o.data;for(a._updateRadius(),o.count=a.countVisibleElements(),e=0,n=r.data.length;e<n;e++)l[e]=s,i=a._computeAngle(e),u[e]=i,s+=i;for(e=0,n=d.length;e<n;++e)d[e]._options=a._resolveDataElementOptions(d[e],e),a.updateElement(d[e],e,t)},_updateRadius:function(){var t=this,e=t.chart,n=e.chartArea,i=e.options,a=Math.min(n.right-n.left,n.bottom-n.top);e.outerRadius=Math.max(a/2,0),e.innerRadius=Math.max(i.cutoutPercentage?e.outerRadius/100*i.cutoutPercentage:1,0),e.radiusLength=(e.outerRadius-e.innerRadius)/e.getVisibleDatasetCount(),t.outerRadius=e.outerRadius-e.radiusLength*t.index,t.innerRadius=t.outerRadius-e.radiusLength},updateElement:function(t,e,n){var i=this,a=i.chart,r=i.getDataset(),o=a.options,s=o.animation,l=a.scale,u=a.data.labels,d=l.xCenter,h=l.yCenter,c=o.startAngle,f=t.hidden?0:l.getDistanceFromCenterForValue(r.data[e]),g=i._starts[e],m=g+(t.hidden?0:i._angles[e]),p=s.animateScale?0:l.getDistanceFromCenterForValue(r.data[e]),v=t._options||{};B.extend(t,{_datasetIndex:i.index,_index:e,_scale:l,_model:{backgroundColor:v.backgroundColor,borderColor:v.borderColor,borderWidth:v.borderWidth,borderAlign:v.borderAlign,x:d,y:h,innerRadius:0,outerRadius:n?p:f,startAngle:n&&s.animateRotate?c:g,endAngle:n&&s.animateRotate?c:m,label:B.valueAtIndexOrDefault(u,e,u[e])}}),t.pivot()},countVisibleElements:function(){var t=this.getDataset(),e=this.getMeta(),n=0;return B.each(e.data,function(e,i){isNaN(t.data[i])||e.hidden||n++}),n},setHoverStyle:function(t){var e=t._model,n=t._options,i=B.getHoverColor,a=B.valueOrDefault;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=a(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=a(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=a(n.hoverBorderWidth,n.borderWidth)},_computeAngle:function(t){var e=this,n=this.getMeta().count,i=e.getDataset(),a=e.getMeta();if(isNaN(i.data[t])||a.data[t].hidden)return 0;var r={chart:e.chart,dataIndex:t,dataset:i,datasetIndex:e.index};return Zt([e.chart.options.elements.arc.angle,2*Math.PI/n],r,t)}});Y._set("pie",B.clone(Y.doughnut)),Y._set("pie",{cutoutPercentage:0});var Xt=zt,Kt=B.valueOrDefault;Y._set("radar",{spanGaps:!1,scale:{type:"radialLinear"},elements:{line:{fill:"start",tension:0}}});var Jt=at.extend({datasetElementType:kt.Line,dataElementType:kt.Point,linkScales:B.noop,_datasetElementOptions:["backgroundColor","borderWidth","borderColor","borderCapStyle","borderDash","borderDashOffset","borderJoinStyle","fill"],_dataElementOptions:{backgroundColor:"pointBackgroundColor",borderColor:"pointBorderColor",borderWidth:"pointBorderWidth",hitRadius:"pointHitRadius",hoverBackgroundColor:"pointHoverBackgroundColor",hoverBorderColor:"pointHoverBorderColor",hoverBorderWidth:"pointHoverBorderWidth",hoverRadius:"pointHoverRadius",pointStyle:"pointStyle",radius:"pointRadius",rotation:"pointRotation"},_getIndexScaleId:function(){return this.chart.scale.id},_getValueScaleId:function(){return this.chart.scale.id},update:function(t){var e,n,i=this,a=i.getMeta(),r=a.dataset,o=a.data||[],s=i.chart.scale,l=i._config;for(void 0!==l.tension&&void 0===l.lineTension&&(l.lineTension=l.tension),r._scale=s,r._datasetIndex=i.index,r._children=o,r._loop=!0,r._model=i._resolveDatasetElementOptions(r),r.pivot(),e=0,n=o.length;e<n;++e)i.updateElement(o[e],e,t);for(i.updateBezierControlPoints(),e=0,n=o.length;e<n;++e)o[e].pivot()},updateElement:function(t,e,n){var i=this,a=t.custom||{},r=i.getDataset(),o=i.chart.scale,s=o.getPointPositionForValue(e,r.data[e]),l=i._resolveDataElementOptions(t,e),u=i.getMeta().dataset._model,d=n?o.xCenter:s.x,h=n?o.yCenter:s.y;t._scale=o,t._options=l,t._datasetIndex=i.index,t._index=e,t._model={x:d,y:h,skip:a.skip||isNaN(d)||isNaN(h),radius:l.radius,pointStyle:l.pointStyle,rotation:l.rotation,backgroundColor:l.backgroundColor,borderColor:l.borderColor,borderWidth:l.borderWidth,tension:Kt(a.tension,u?u.tension:0),hitRadius:l.hitRadius}},_resolveDatasetElementOptions:function(){var t=this,e=t._config,n=t.chart.options,i=at.prototype._resolveDatasetElementOptions.apply(t,arguments);return i.spanGaps=Kt(e.spanGaps,n.spanGaps),i.tension=Kt(e.lineTension,n.elements.line.tension),i},updateBezierControlPoints:function(){var t,e,n,i,a=this.getMeta(),r=this.chart.chartArea,o=a.data||[];function s(t,e,n){return Math.max(Math.min(t,n),e)}for(a.dataset._model.spanGaps&&(o=o.filter(function(t){return!t._model.skip})),t=0,e=o.length;t<e;++t)n=o[t]._model,i=B.splineCurve(B.previousItem(o,t,!0)._model,n,B.nextItem(o,t,!0)._model,n.tension),n.controlPointPreviousX=s(i.previous.x,r.left,r.right),n.controlPointPreviousY=s(i.previous.y,r.top,r.bottom),n.controlPointNextX=s(i.next.x,r.left,r.right),n.controlPointNextY=s(i.next.y,r.top,r.bottom)},setHoverStyle:function(t){var e=t._model,n=t._options,i=B.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=Kt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Kt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Kt(n.hoverBorderWidth,n.borderWidth),e.radius=Kt(n.hoverRadius,n.radius)}});Y._set("scatter",{hover:{mode:"single"},scales:{xAxes:[{id:"x-axis-1",type:"linear",position:"bottom"}],yAxes:[{id:"y-axis-1",type:"linear",position:"left"}]},tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}}),Y._set("global",{datasets:{scatter:{showLine:!1}}});var Qt={bar:At,bubble:Lt,doughnut:zt,horizontalBar:Et,line:qt,polarArea:$t,pie:Xt,radar:Jt,scatter:qt};function te(t,e){return t.native?{x:t.x,y:t.y}:B.getRelativePosition(t,e)}function ee(t,e){var n,i,a,r,o,s,l=t._getSortedVisibleDatasetMetas();for(i=0,r=l.length;i<r;++i)for(a=0,o=(n=l[i].data).length;a<o;++a)(s=n[a])._view.skip||e(s)}function ne(t,e){var n=[];return ee(t,function(t){t.inRange(e.x,e.y)&&n.push(t)}),n}function ie(t,e,n,i){var a=Number.POSITIVE_INFINITY,r=[];return ee(t,function(t){if(!n||t.inRange(e.x,e.y)){var o=t.getCenterPoint(),s=i(e,o);s<a?(r=[t],a=s):s===a&&r.push(t)}}),r}function ae(t){var e=-1!==t.indexOf("x"),n=-1!==t.indexOf("y");return function(t,i){var a=e?Math.abs(t.x-i.x):0,r=n?Math.abs(t.y-i.y):0;return Math.sqrt(Math.pow(a,2)+Math.pow(r,2))}}function re(t,e,n){var i=te(e,t);n.axis=n.axis||"x";var a=ae(n.axis),r=n.intersect?ne(t,i):ie(t,i,!1,a),o=[];return r.length?(t._getSortedVisibleDatasetMetas().forEach(function(t){var e=t.data[r[0]._index];e&&!e._view.skip&&o.push(e)}),o):[]}var oe={modes:{single:function(t,e){var n=te(e,t),i=[];return ee(t,function(t){if(t.inRange(n.x,n.y))return i.push(t),i}),i.slice(0,1)},label:re,index:re,dataset:function(t,e,n){var i=te(e,t);n.axis=n.axis||"xy";var a=ae(n.axis),r=n.intersect?ne(t,i):ie(t,i,!1,a);return r.length>0&&(r=t.getDatasetMeta(r[0]._datasetIndex).data),r},"x-axis":function(t,e){return re(t,e,{intersect:!1})},point:function(t,e){return ne(t,te(e,t))},nearest:function(t,e,n){var i=te(e,t);n.axis=n.axis||"xy";var a=ae(n.axis);return ie(t,i,n.intersect,a)},x:function(t,e,n){var i=te(e,t),a=[],r=!1;return ee(t,function(t){t.inXRange(i.x)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)}),n.intersect&&!r&&(a=[]),a},y:function(t,e,n){var i=te(e,t),a=[],r=!1;return ee(t,function(t){t.inYRange(i.y)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)}),n.intersect&&!r&&(a=[]),a}}},se=B.extend;function le(t,e){return B.where(t,function(t){return t.pos===e})}function ue(t,e){return t.sort(function(t,n){var i=e?n:t,a=e?t:n;return i.weight===a.weight?i.index-a.index:i.weight-a.weight})}function de(t,e,n,i){return Math.max(t[n],e[n])+Math.max(t[i],e[i])}function he(t,e,n){var i,a,r=n.box,o=t.maxPadding;if(n.size&&(t[n.pos]-=n.size),n.size=n.horizontal?r.height:r.width,t[n.pos]+=n.size,r.getPadding){var s=r.getPadding();o.top=Math.max(o.top,s.top),o.left=Math.max(o.left,s.left),o.bottom=Math.max(o.bottom,s.bottom),o.right=Math.max(o.right,s.right)}if(i=e.outerWidth-de(o,t,"left","right"),a=e.outerHeight-de(o,t,"top","bottom"),i!==t.w||a!==t.h){t.w=i,t.h=a;var l=n.horizontal?[i,t.w]:[a,t.h];return!(l[0]===l[1]||isNaN(l[0])&&isNaN(l[1]))}}function ce(t,e){var n=e.maxPadding;function i(t){var i={left:0,top:0,right:0,bottom:0};return t.forEach(function(t){i[t]=Math.max(e[t],n[t])}),i}return i(t?["left","right"]:["top","bottom"])}function fe(t,e,n){var i,a,r,o,s,l,u=[];for(i=0,a=t.length;i<a;++i)(o=(r=t[i]).box).update(r.width||e.w,r.height||e.h,ce(r.horizontal,e)),he(e,n,r)&&(l=!0,u.length&&(s=!0)),o.fullWidth||u.push(r);return s&&fe(u,e,n)||l}function ge(t,e,n){var i,a,r,o,s=n.padding,l=e.x,u=e.y;for(i=0,a=t.length;i<a;++i)o=(r=t[i]).box,r.horizontal?(o.left=o.fullWidth?s.left:e.left,o.right=o.fullWidth?n.outerWidth-s.right:e.left+e.w,o.top=u,o.bottom=u+o.height,o.width=o.right-o.left,u=o.bottom):(o.left=l,o.right=l+o.width,o.top=e.top,o.bottom=e.top+e.h,o.height=o.bottom-o.top,l=o.right);e.x=l,e.y=u}Y._set("global",{layout:{padding:{top:0,right:0,bottom:0,left:0}}});var me,pe={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),e.fullWidth=e.fullWidth||!1,e.position=e.position||"top",e.weight=e.weight||0,e._layers=e._layers||function(){return[{z:0,draw:function(){e.draw.apply(e,arguments)}}]},t.boxes.push(e)},removeBox:function(t,e){var n=t.boxes?t.boxes.indexOf(e):-1;-1!==n&&t.boxes.splice(n,1)},configure:function(t,e,n){for(var i,a=["fullWidth","position","weight"],r=a.length,o=0;o<r;++o)i=a[o],n.hasOwnProperty(i)&&(e[i]=n[i])},update:function(t,e,n){if(t){var i=t.options.layout||{},a=B.options.toPadding(i.padding),r=e-a.width,o=n-a.height,s=function(t){var e=function(t){var e,n,i,a=[];for(e=0,n=(t||[]).length;e<n;++e)i=t[e],a.push({index:e,box:i,pos:i.position,horizontal:i.isHorizontal(),weight:i.weight});return a}(t),n=ue(le(e,"left"),!0),i=ue(le(e,"right")),a=ue(le(e,"top"),!0),r=ue(le(e,"bottom"));return{leftAndTop:n.concat(a),rightAndBottom:i.concat(r),chartArea:le(e,"chartArea"),vertical:n.concat(i),horizontal:a.concat(r)}}(t.boxes),l=s.vertical,u=s.horizontal,d=Object.freeze({outerWidth:e,outerHeight:n,padding:a,availableWidth:r,vBoxMaxWidth:r/2/l.length,hBoxMaxHeight:o/2}),h=se({maxPadding:se({},a),w:r,h:o,x:a.left,y:a.top},a);!function(t,e){var n,i,a;for(n=0,i=t.length;n<i;++n)(a=t[n]).width=a.horizontal?a.box.fullWidth&&e.availableWidth:e.vBoxMaxWidth,a.height=a.horizontal&&e.hBoxMaxHeight}(l.concat(u),d),fe(l,h,d),fe(u,h,d)&&fe(l,h,d),function(t){var e=t.maxPadding;function n(n){var i=Math.max(e[n]-t[n],0);return t[n]+=i,i}t.y+=n("top"),t.x+=n("left"),n("right"),n("bottom")}(h),ge(s.leftAndTop,h,d),h.x+=h.w,h.y+=h.h,ge(s.rightAndBottom,h,d),t.chartArea={left:h.left,top:h.top,right:h.left+h.w,bottom:h.top+h.h},B.each(s.chartArea,function(e){var n=e.box;se(n,t.chartArea),n.update(h.w,h.h)})}}},ve=(me=Object.freeze({__proto__:null,default:"/*\r\n * DOM element rendering detection\r\n * https://davidwalsh.name/detect-node-insertion\r\n */\r\n@keyframes chartjs-render-animation {\r\n\tfrom { opacity: 0.99; }\r\n\tto { opacity: 1; }\r\n}\r\n\r\n.chartjs-render-monitor {\r\n\tanimation: chartjs-render-animation 0.001s;\r\n}\r\n\r\n/*\r\n * DOM element resizing detection\r\n * https://github.com/marcj/css-element-queries\r\n */\r\n.chartjs-size-monitor,\r\n.chartjs-size-monitor-expand,\r\n.chartjs-size-monitor-shrink {\r\n\tposition: absolute;\r\n\tdirection: ltr;\r\n\tleft: 0;\r\n\ttop: 0;\r\n\tright: 0;\r\n\tbottom: 0;\r\n\toverflow: hidden;\r\n\tpointer-events: none;\r\n\tvisibility: hidden;\r\n\tz-index: -1;\r\n}\r\n\r\n.chartjs-size-monitor-expand > div {\r\n\tposition: absolute;\r\n\twidth: 1000000px;\r\n\theight: 1000000px;\r\n\tleft: 0;\r\n\ttop: 0;\r\n}\r\n\r\n.chartjs-size-monitor-shrink > div {\r\n\tposition: absolute;\r\n\twidth: 200%;\r\n\theight: 200%;\r\n\tleft: 0;\r\n\ttop: 0;\r\n}\r\n"}))&&me.default||me,be="chartjs-size-monitor",ye="chartjs-render-monitor",xe=["animationstart","webkitAnimationStart"],_e={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function we(t,e){var n=B.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}var ke=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("e",null,e)}catch(t){}return t}()&&{passive:!0};function Me(t,e,n){t.addEventListener(e,n,ke)}function Se(t,e,n){t.removeEventListener(e,n,ke)}function De(t,e,n,i,a){return{type:t,chart:e,native:a||null,x:void 0!==n?n:null,y:void 0!==i?i:null}}function Ce(t){var e=document.createElement("div");return e.className=t||"",e}function Pe(t,e,n){var i,a,r,o,s=t.$chartjs||(t.$chartjs={}),l=s.resizer=function(t){var e=1e6,n=Ce(be),i=Ce(be+"-expand"),a=Ce(be+"-shrink");i.appendChild(Ce()),a.appendChild(Ce()),n.appendChild(i),n.appendChild(a),n._reset=function(){i.scrollLeft=e,i.scrollTop=e,a.scrollLeft=e,a.scrollTop=e};var r=function(){n._reset(),t()};return Me(i,"scroll",r.bind(i,"expand")),Me(a,"scroll",r.bind(a,"shrink")),n}((i=function(){if(s.resizer){var i=n.options.maintainAspectRatio&&t.parentNode,a=i?i.clientWidth:0;e(De("resize",n)),i&&i.clientWidth<a&&n.canvas&&e(De("resize",n))}},r=!1,o=[],function(){o=Array.prototype.slice.call(arguments),a=a||this,r||(r=!0,B.requestAnimFrame.call(window,function(){r=!1,i.apply(a,o)}))}));!function(t,e){var n=t.$chartjs||(t.$chartjs={}),i=n.renderProxy=function(t){"chartjs-render-animation"===t.animationName&&e()};B.each(xe,function(e){Me(t,e,i)}),n.reflow=!!t.offsetParent,t.classList.add(ye)}(t,function(){if(s.resizer){var e=t.parentNode;e&&e!==l.parentNode&&e.insertBefore(l,e.firstChild),l._reset()}})}function Te(t){var e=t.$chartjs||{},n=e.resizer;delete e.resizer,function(t){var e=t.$chartjs||{},n=e.renderProxy;n&&(B.each(xe,function(e){Se(t,e,n)}),delete e.renderProxy),t.classList.remove(ye)}(t),n&&n.parentNode&&n.parentNode.removeChild(n)}var Oe={disableCSSInjection:!1,_enabled:"undefined"!=typeof window&&"undefined"!=typeof document,_ensureLoaded:function(t){if(!this.disableCSSInjection){var e=t.getRootNode?t.getRootNode():document;!function(t,e){var n=t.$chartjs||(t.$chartjs={});if(!n.containsStyles){n.containsStyles=!0,e="/* Chart.js */\n"+e;var i=document.createElement("style");i.setAttribute("type","text/css"),i.appendChild(document.createTextNode(e)),t.appendChild(i)}}(e.host?e:document.head,ve)}},acquireContext:function(t,e){"string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas);var n=t&&t.getContext&&t.getContext("2d");return n&&n.canvas===t?(this._ensureLoaded(t),function(t,e){var n=t.style,i=t.getAttribute("height"),a=t.getAttribute("width");if(t.$chartjs={initial:{height:i,width:a,style:{display:n.display,height:n.height,width:n.width}}},n.display=n.display||"block",null===a||""===a){var r=we(t,"width");void 0!==r&&(t.width=r)}if(null===i||""===i)if(""===t.style.height)t.height=t.width/(e.options.aspectRatio||2);else{var o=we(t,"height");void 0!==r&&(t.height=o)}}(t,e),n):null},releaseContext:function(t){var e=t.canvas;if(e.$chartjs){var n=e.$chartjs.initial;["height","width"].forEach(function(t){var i=n[t];B.isNullOrUndef(i)?e.removeAttribute(t):e.setAttribute(t,i)}),B.each(n.style||{},function(t,n){e.style[n]=t}),e.width=e.width,delete e.$chartjs}},addEventListener:function(t,e,n){var i=t.canvas;if("resize"!==e){var a=n.$chartjs||(n.$chartjs={});Me(i,e,(a.proxies||(a.proxies={}))[t.id+"_"+e]=function(e){n(function(t,e){var n=_e[t.type]||t.type,i=B.getRelativePosition(t,e);return De(n,e,i.x,i.y,t)}(e,t))})}else Pe(i,n,t)},removeEventListener:function(t,e,n){var i=t.canvas;if("resize"!==e){var a=((n.$chartjs||{}).proxies||{})[t.id+"_"+e];a&&Se(i,e,a)}else Te(i)}};B.addEvent=Me,B.removeEvent=Se;var Ae=Oe._enabled?Oe:{acquireContext:function(t){return t&&t.canvas&&(t=t.canvas),t&&t.getContext("2d")||null}},Fe=B.extend({initialize:function(){},acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},Ae);Y._set("global",{plugins:{}});var Ie={_plugins:[],_cacheId:0,register:function(t){var e=this._plugins;[].concat(t).forEach(function(t){-1===e.indexOf(t)&&e.push(t)}),this._cacheId++},unregister:function(t){var e=this._plugins;[].concat(t).forEach(function(t){var n=e.indexOf(t);-1!==n&&e.splice(n,1)}),this._cacheId++},clear:function(){this._plugins=[],this._cacheId++},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(t,e,n){var i,a,r,o,s,l=this.descriptors(t),u=l.length;for(i=0;i<u;++i)if("function"==typeof(s=(r=(a=l[i]).plugin)[e])&&((o=[t].concat(n||[])).push(a.options),!1===s.apply(r,o)))return!1;return!0},descriptors:function(t){var e=t.$plugins||(t.$plugins={});if(e.id===this._cacheId)return e.descriptors;var n=[],i=[],a=t&&t.config||{},r=a.options&&a.options.plugins||{};return this._plugins.concat(a.plugins||[]).forEach(function(t){if(-1===n.indexOf(t)){var e=t.id,a=r[e];!1!==a&&(!0===a&&(a=B.clone(Y.global.plugins[e])),n.push(t),i.push({plugin:t,options:a||{}}))}}),e.descriptors=i,e.id=this._cacheId,i},_invalidate:function(t){delete t.$plugins}},Le={constructors:{},defaults:{},registerScaleType:function(t,e,n){this.constructors[t]=e,this.defaults[t]=B.clone(n)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(t){return this.defaults.hasOwnProperty(t)?B.merge(Object.create(null),[Y.scale,this.defaults[t]]):{}},updateScaleDefaults:function(t,e){var n=this;n.defaults.hasOwnProperty(t)&&(n.defaults[t]=B.extend(n.defaults[t],e))},addScalesToLayout:function(t){B.each(t.scales,function(e){e.fullWidth=e.options.fullWidth,e.position=e.options.position,e.weight=e.options.weight,pe.addBox(t,e)})}},Re=B.valueOrDefault,Ne=B.rtl.getRtlAdapter;Y._set("global",{tooltips:{enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretPadding:2,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,borderColor:"rgba(0,0,0,0)",borderWidth:0,callbacks:{beforeTitle:B.noop,title:function(t,e){var n="",i=e.labels,a=i?i.length:0;if(t.length>0){var r=t[0];r.label?n=r.label:r.xLabel?n=r.xLabel:a>0&&r.index<a&&(n=i[r.index])}return n},afterTitle:B.noop,beforeBody:B.noop,beforeLabel:B.noop,label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n&&(n+=": "),B.isNullOrUndef(t.value)?n+=t.yLabel:n+=t.value,n},labelColor:function(t,e){var n=e.getDatasetMeta(t.datasetIndex).data[t.index]._view;return{borderColor:n.borderColor,backgroundColor:n.backgroundColor}},labelTextColor:function(){return this._options.bodyFontColor},afterLabel:B.noop,afterBody:B.noop,beforeFooter:B.noop,footer:B.noop,afterFooter:B.noop}}});var We={average:function(t){if(!t.length)return!1;var e,n,i=0,a=0,r=0;for(e=0,n=t.length;e<n;++e){var o=t[e];if(o&&o.hasValue()){var s=o.tooltipPosition();i+=s.x,a+=s.y,++r}}return{x:i/r,y:a/r}},nearest:function(t,e){var n,i,a,r=e.x,o=e.y,s=Number.POSITIVE_INFINITY;for(n=0,i=t.length;n<i;++n){var l=t[n];if(l&&l.hasValue()){var u=l.getCenterPoint(),d=B.distanceBetweenPoints(e,u);d<s&&(s=d,a=l)}}if(a){var h=a.tooltipPosition();r=h.x,o=h.y}return{x:r,y:o}}};function Ye(t,e){return e&&(B.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function ze(t){return("string"==typeof t||t instanceof String)&&t.indexOf("\n")>-1?t.split("\n"):t}function Ee(t){var e=Y.global;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,rtl:t.rtl,textDirection:t.textDirection,bodyFontColor:t.bodyFontColor,_bodyFontFamily:Re(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:Re(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:Re(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:Re(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:Re(t.titleFontStyle,e.defaultFontStyle),titleFontSize:Re(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:Re(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:Re(t.footerFontStyle,e.defaultFontStyle),footerFontSize:Re(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}function Ve(t,e){return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-t.xPadding:t.x+t.xPadding}function He(t){return Ye([],ze(t))}var Be=X.extend({initialize:function(){this._model=Ee(this._options),this._lastActive=[]},getTitle:function(){var t=this,e=t._options,n=e.callbacks,i=n.beforeTitle.apply(t,arguments),a=n.title.apply(t,arguments),r=n.afterTitle.apply(t,arguments),o=[];return o=Ye(o,ze(i)),o=Ye(o,ze(a)),o=Ye(o,ze(r))},getBeforeBody:function(){return He(this._options.callbacks.beforeBody.apply(this,arguments))},getBody:function(t,e){var n=this,i=n._options.callbacks,a=[];return B.each(t,function(t){var r={before:[],lines:[],after:[]};Ye(r.before,ze(i.beforeLabel.call(n,t,e))),Ye(r.lines,i.label.call(n,t,e)),Ye(r.after,ze(i.afterLabel.call(n,t,e))),a.push(r)}),a},getAfterBody:function(){return He(this._options.callbacks.afterBody.apply(this,arguments))},getFooter:function(){var t=this,e=t._options.callbacks,n=e.beforeFooter.apply(t,arguments),i=e.footer.apply(t,arguments),a=e.afterFooter.apply(t,arguments),r=[];return r=Ye(r,ze(n)),r=Ye(r,ze(i)),r=Ye(r,ze(a))},update:function(t){var e,n,i,a,r,o,s,l,u,d,h=this,c=h._options,f=h._model,g=h._model=Ee(c),m=h._active,p=h._data,v={xAlign:f.xAlign,yAlign:f.yAlign},b={x:f.x,y:f.y},y={width:f.width,height:f.height},x={x:f.caretX,y:f.caretY};if(m.length){g.opacity=1;var _=[],w=[];x=We[c.position].call(h,m,h._eventPosition);var k=[];for(e=0,n=m.length;e<n;++e)k.push((i=m[e],a=void 0,r=void 0,o=void 0,s=void 0,l=void 0,u=void 0,d=void 0,a=i._xScale,r=i._yScale||i._scale,o=i._index,s=i._datasetIndex,l=i._chart.getDatasetMeta(s).controller,u=l._getIndexScale(),d=l._getValueScale(),{xLabel:a?a.getLabelForIndex(o,s):"",yLabel:r?r.getLabelForIndex(o,s):"",label:u?""+u.getLabelForIndex(o,s):"",value:d?""+d.getLabelForIndex(o,s):"",index:o,datasetIndex:s,x:i._model.x,y:i._model.y}));c.filter&&(k=k.filter(function(t){return c.filter(t,p)})),c.itemSort&&(k=k.sort(function(t,e){return c.itemSort(t,e,p)})),B.each(k,function(t){_.push(c.callbacks.labelColor.call(h,t,h._chart)),w.push(c.callbacks.labelTextColor.call(h,t,h._chart))}),g.title=h.getTitle(k,p),g.beforeBody=h.getBeforeBody(k,p),g.body=h.getBody(k,p),g.afterBody=h.getAfterBody(k,p),g.footer=h.getFooter(k,p),g.x=x.x,g.y=x.y,g.caretPadding=c.caretPadding,g.labelColors=_,g.labelTextColors=w,g.dataPoints=k,y=function(t,e){var n=t._chart.ctx,i=2*e.yPadding,a=0,r=e.body,o=r.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);o+=e.beforeBody.length+e.afterBody.length;var s=e.title.length,l=e.footer.length,u=e.titleFontSize,d=e.bodyFontSize,h=e.footerFontSize;i+=s*u,i+=s?(s-1)*e.titleSpacing:0,i+=s?e.titleMarginBottom:0,i+=o*d,i+=o?(o-1)*e.bodySpacing:0,i+=l?e.footerMarginTop:0,i+=l*h,i+=l?(l-1)*e.footerSpacing:0;var c=0,f=function(t){a=Math.max(a,n.measureText(t).width+c)};return n.font=B.fontString(u,e._titleFontStyle,e._titleFontFamily),B.each(e.title,f),n.font=B.fontString(d,e._bodyFontStyle,e._bodyFontFamily),B.each(e.beforeBody.concat(e.afterBody),f),c=e.displayColors?d+2:0,B.each(r,function(t){B.each(t.before,f),B.each(t.lines,f),B.each(t.after,f)}),c=0,n.font=B.fontString(h,e._footerFontStyle,e._footerFontFamily),B.each(e.footer,f),{width:a+=2*e.xPadding,height:i}}(this,g),b=function(t,e,n,i){var a=t.x,r=t.y,o=t.caretSize,s=t.caretPadding,l=t.cornerRadius,u=n.xAlign,d=n.yAlign,h=o+s,c=l+s;return"right"===u?a-=e.width:"center"===u&&((a-=e.width/2)+e.width>i.width&&(a=i.width-e.width),a<0&&(a=0)),"top"===d?r+=h:r-="bottom"===d?e.height+h:e.height/2,"center"===d?"left"===u?a+=h:"right"===u&&(a-=h):"left"===u?a-=c:"right"===u&&(a+=c),{x:a,y:r}}(g,y,v=function(t,e){var n,i,a,r,o,s=t._model,l=t._chart,u=t._chart.chartArea,d="center",h="center";s.y<e.height?h="top":s.y>l.height-e.height&&(h="bottom");var c=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===h?(n=function(t){return t<=c},i=function(t){return t>c}):(n=function(t){return t<=e.width/2},i=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},r=function(t){return t-e.width-s.caretSize-s.caretPadding<0},o=function(t){return t<=f?"top":"bottom"},n(s.x)?(d="left",a(s.x)&&(d="center",h=o(s.y))):i(s.x)&&(d="right",r(s.x)&&(d="center",h=o(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:h}}(this,y),h._chart)}else g.opacity=0;return g.xAlign=v.xAlign,g.yAlign=v.yAlign,g.x=b.x,g.y=b.y,g.width=y.width,g.height=y.height,g.caretX=x.x,g.caretY=x.y,h._model=g,t&&c.custom&&c.custom.call(h,g),h},drawCaret:function(t,e){var n=this._chart.ctx,i=this._view,a=this.getCaretPosition(t,e,i);n.lineTo(a.x1,a.y1),n.lineTo(a.x2,a.y2),n.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,n){var i,a,r,o,s,l,u=n.caretSize,d=n.cornerRadius,h=n.xAlign,c=n.yAlign,f=t.x,g=t.y,m=e.width,p=e.height;if("center"===c)s=g+p/2,"left"===h?(a=(i=f)-u,r=i,o=s+u,l=s-u):(a=(i=f+m)+u,r=i,o=s-u,l=s+u);else if("left"===h?(i=(a=f+d+u)-u,r=a+u):"right"===h?(i=(a=f+m-d-u)-u,r=a+u):(i=(a=n.caretX)-u,r=a+u),"top"===c)s=(o=g)-u,l=o;else{s=(o=g+p)+u,l=o;var v=r;r=i,i=v}return{x1:i,x2:a,x3:r,y1:o,y2:s,y3:l}},drawTitle:function(t,e,n){var i,a,r,o=e.title,s=o.length;if(s){var l=Ne(e.rtl,e.x,e.width);for(t.x=Ve(e,e._titleAlign),n.textAlign=l.textAlign(e._titleAlign),n.textBaseline="middle",i=e.titleFontSize,a=e.titleSpacing,n.fillStyle=e.titleFontColor,n.font=B.fontString(i,e._titleFontStyle,e._titleFontFamily),r=0;r<s;++r)n.fillText(o[r],l.x(t.x),t.y+i/2),t.y+=i+a,r+1===s&&(t.y+=e.titleMarginBottom-a)}},drawBody:function(t,e,n){var i,a,r,o,s,l,u,d,h=e.bodyFontSize,c=e.bodySpacing,f=e._bodyAlign,g=e.body,m=e.displayColors,p=0,v=m?Ve(e,"left"):0,b=Ne(e.rtl,e.x,e.width),y=function(e){n.fillText(e,b.x(t.x+p),t.y+h/2),t.y+=h+c},x=b.textAlign(f);for(n.textAlign=f,n.textBaseline="middle",n.font=B.fontString(h,e._bodyFontStyle,e._bodyFontFamily),t.x=Ve(e,x),n.fillStyle=e.bodyFontColor,B.each(e.beforeBody,y),p=m&&"right"!==x?"center"===f?h/2+1:h+2:0,s=0,u=g.length;s<u;++s){for(i=g[s],a=e.labelTextColors[s],r=e.labelColors[s],n.fillStyle=a,B.each(i.before,y),l=0,d=(o=i.lines).length;l<d;++l){if(m){var _=b.x(v);n.fillStyle=e.legendColorBackground,n.fillRect(b.leftForLtr(_,h),t.y,h,h),n.lineWidth=1,n.strokeStyle=r.borderColor,n.strokeRect(b.leftForLtr(_,h),t.y,h,h),n.fillStyle=r.backgroundColor,n.fillRect(b.leftForLtr(b.xPlus(_,1),h-2),t.y+1,h-2,h-2),n.fillStyle=a}y(o[l])}B.each(i.after,y)}p=0,B.each(e.afterBody,y),t.y-=c},drawFooter:function(t,e,n){var i,a,r=e.footer,o=r.length;if(o){var s=Ne(e.rtl,e.x,e.width);for(t.x=Ve(e,e._footerAlign),t.y+=e.footerMarginTop,n.textAlign=s.textAlign(e._footerAlign),n.textBaseline="middle",i=e.footerFontSize,n.fillStyle=e.footerFontColor,n.font=B.fontString(i,e._footerFontStyle,e._footerFontFamily),a=0;a<o;++a)n.fillText(r[a],s.x(t.x),t.y+i/2),t.y+=i+e.footerSpacing}},drawBackground:function(t,e,n,i){n.fillStyle=e.backgroundColor,n.strokeStyle=e.borderColor,n.lineWidth=e.borderWidth;var a=e.xAlign,r=e.yAlign,o=t.x,s=t.y,l=i.width,u=i.height,d=e.cornerRadius;n.beginPath(),n.moveTo(o+d,s),"top"===r&&this.drawCaret(t,i),n.lineTo(o+l-d,s),n.quadraticCurveTo(o+l,s,o+l,s+d),"center"===r&&"right"===a&&this.drawCaret(t,i),n.lineTo(o+l,s+u-d),n.quadraticCurveTo(o+l,s+u,o+l-d,s+u),"bottom"===r&&this.drawCaret(t,i),n.lineTo(o+d,s+u),n.quadraticCurveTo(o,s+u,o,s+u-d),"center"===r&&"left"===a&&this.drawCaret(t,i),n.lineTo(o,s+d),n.quadraticCurveTo(o,s,o+d,s),n.closePath(),n.fill(),e.borderWidth>0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,r=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&r&&(t.save(),t.globalAlpha=a,this.drawBackground(i,e,t,n),i.y+=e.yPadding,B.rtl.overrideTextDirection(t,e.textDirection),this.drawTitle(i,e,t),this.drawBody(i,e,t),this.drawFooter(i,e,t),B.rtl.restoreTextDirection(t,e.textDirection),t.restore())}},handleEvent:function(t){var e,n=this,i=n._options;return n._lastActive=n._lastActive||[],"mouseout"===t.type?n._active=[]:(n._active=n._chart.getElementsAtEventForMode(t,i.mode,i),i.reverse&&n._active.reverse()),(e=!B.arrayEquals(n._active,n._lastActive))&&(n._lastActive=n._active,(i.enabled||i.custom)&&(n._eventPosition={x:t.x,y:t.y},n.update(!0),n.pivot())),e}}),je=We,Ue=Be;Ue.positioners=je;var Ge=B.valueOrDefault;function qe(){return B.merge(Object.create(null),[].slice.call(arguments),{merger:function(t,e,n,i){if("xAxes"===t||"yAxes"===t){var a,r,o,s=n[t].length;for(e[t]||(e[t]=[]),a=0;a<s;++a)o=n[t][a],r=Ge(o.type,"xAxes"===t?"category":"linear"),a>=e[t].length&&e[t].push({}),!e[t][a].type||o.type&&o.type!==e[t][a].type?B.merge(e[t][a],[Le.getScaleDefaults(r),o]):B.merge(e[t][a],o)}else B._merger(t,e,n,i)}})}function Ze(){return B.merge(Object.create(null),[].slice.call(arguments),{merger:function(t,e,n,i){var a=e[t]||Object.create(null),r=n[t];"scales"===t?e[t]=qe(a,r):"scale"===t?e[t]=B.merge(a,[Le.getScaleDefaults(r.type),r]):B._merger(t,e,n,i)}})}function $e(t){var e=t.options;B.each(t.scales,function(e){pe.removeBox(t,e)}),e=Ze(Y.global,Y[t.config.type],e),t.options=t.config.options=e,t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.tooltip._options=e.tooltips,t.tooltip.initialize()}function Xe(t,e,n){var i,a=function(t){return t.id===i};do{i=e+n++}while(B.findIndex(t,a)>=0);return i}function Ke(t){return"top"===t||"bottom"===t}function Je(t,e){return function(n,i){return n[t]===i[t]?n[e]-i[e]:n[t]-i[t]}}Y._set("global",{elements:{},events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,maintainAspectRatio:!0,responsive:!0,responsiveAnimationDuration:0});var Qe=function(t,e){return this.construct(t,e),this};B.extend(Qe.prototype,{construct:function(t,e){var n=this;e=function(t){var e=(t=t||Object.create(null)).data=t.data||{};return e.datasets=e.datasets||[],e.labels=e.labels||[],t.options=Ze(Y.global,Y[t.type],t.options||{}),t}(e);var i=Fe.acquireContext(t,e),a=i&&i.canvas,r=a&&a.height,o=a&&a.width;n.id=B.uid(),n.ctx=i,n.canvas=a,n.config=e,n.width=o,n.height=r,n.aspectRatio=r?o/r:null,n.options=e.options,n._bufferedRender=!1,n._layers=[],n.chart=n,n.controller=n,Qe.instances[n.id]=n,Object.defineProperty(n,"data",{get:function(){return n.config.data},set:function(t){n.config.data=t}}),i&&a?(n.initialize(),n.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return Ie.notify(t,"beforeInit"),B.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.initToolTip(),Ie.notify(t,"afterInit"),t},clear:function(){return B.canvas.clear(this),this},stop:function(){return Q.cancelAnimation(this),this},resize:function(t){var e=this,n=e.options,i=e.canvas,a=n.maintainAspectRatio&&e.aspectRatio||null,r=Math.max(0,Math.floor(B.getMaximumWidth(i))),o=Math.max(0,Math.floor(a?r/a:B.getMaximumHeight(i)));if((e.width!==r||e.height!==o)&&(i.width=e.width=r,i.height=e.height=o,i.style.width=r+"px",i.style.height=o+"px",B.retinaScale(e,n.devicePixelRatio),!t)){var s={width:r,height:o};Ie.notify(e,"resize",[s]),n.onResize&&n.onResize(e,s),e.stop(),e.update({duration:n.responsiveAnimationDuration})}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;B.each(e.xAxes,function(t,n){t.id||(t.id=Xe(e.xAxes,"x-axis-",n))}),B.each(e.yAxes,function(t,n){t.id||(t.id=Xe(e.yAxes,"y-axis-",n))}),n&&(n.id=n.id||"scale")},buildOrUpdateScales:function(){var t=this,e=t.options,n=t.scales||{},i=[],a=Object.keys(n).reduce(function(t,e){return t[e]=!1,t},{});e.scales&&(i=i.concat((e.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category",dposition:"bottom"}}),(e.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear",dposition:"left"}}))),e.scale&&i.push({options:e.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),B.each(i,function(e){var i=e.options,r=i.id,o=Ge(i.type,e.dtype);Ke(i.position)!==Ke(e.dposition)&&(i.position=e.dposition),a[r]=!0;var s=null;if(r in n&&n[r].type===o)(s=n[r]).options=i,s.ctx=t.ctx,s.chart=t;else{var l=Le.getScaleConstructor(o);if(!l)return;s=new l({id:r,type:o,options:i,ctx:t.ctx,chart:t}),n[s.id]=s}s.mergeTicksOptions(),e.isDefault&&(t.scale=s)}),B.each(a,function(t,e){t||delete n[e]}),t.scales=n,Le.addScalesToLayout(this)},buildOrUpdateControllers:function(){var t,e,n=this,i=[],a=n.data.datasets;for(t=0,e=a.length;t<e;t++){var r=a[t],o=n.getDatasetMeta(t),s=r.type||n.config.type;if(o.type&&o.type!==s&&(n.destroyDatasetMeta(t),o=n.getDatasetMeta(t)),o.type=s,o.order=r.order||0,o.index=t,o.controller)o.controller.updateIndex(t),o.controller.linkScales();else{var l=Qt[o.type];if(void 0===l)throw new Error('"'+o.type+'" is not a chart type.');o.controller=new l(n,t),i.push(o.controller)}}return i},resetElements:function(){var t=this;B.each(t.data.datasets,function(e,n){t.getDatasetMeta(n).controller.reset()},t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(t){var e,n,i=this;if(t&&"object"==typeof t||(t={duration:t,lazy:arguments[1]}),$e(i),Ie._invalidate(i),!1!==Ie.notify(i,"beforeUpdate")){i.tooltip._data=i.data;var a=i.buildOrUpdateControllers();for(e=0,n=i.data.datasets.length;e<n;e++)i.getDatasetMeta(e).controller.buildOrUpdateElements();i.updateLayout(),i.options.animation&&i.options.animation.duration&&B.each(a,function(t){t.reset()}),i.updateDatasets(),i.tooltip.initialize(),i.lastActive=[],Ie.notify(i,"afterUpdate"),i._layers.sort(Je("z","_idx")),i._bufferedRender?i._bufferedRequest={duration:t.duration,easing:t.easing,lazy:t.lazy}:i.render(t)}},updateLayout:function(){var t=this;!1!==Ie.notify(t,"beforeLayout")&&(pe.update(this,this.width,this.height),t._layers=[],B.each(t.boxes,function(e){e._configure&&e._configure(),t._layers.push.apply(t._layers,e._layers())},t),t._layers.forEach(function(t,e){t._idx=e}),Ie.notify(t,"afterScaleUpdate"),Ie.notify(t,"afterLayout"))},updateDatasets:function(){var t=this;if(!1!==Ie.notify(t,"beforeDatasetsUpdate")){for(var e=0,n=t.data.datasets.length;e<n;++e)t.updateDataset(e);Ie.notify(t,"afterDatasetsUpdate")}},updateDataset:function(t){var e=this,n=e.getDatasetMeta(t),i={meta:n,index:t};!1!==Ie.notify(e,"beforeDatasetUpdate",[i])&&(n.controller._update(),Ie.notify(e,"afterDatasetUpdate",[i]))},render:function(t){var e=this;t&&"object"==typeof t||(t={duration:t,lazy:arguments[1]});var n=e.options.animation,i=Ge(t.duration,n&&n.duration),a=t.lazy;if(!1!==Ie.notify(e,"beforeRender")){var r=function(t){Ie.notify(e,"afterRender"),B.callback(n&&n.onComplete,[t],e)};if(n&&i){var o=new J({numSteps:i/16.66,easing:t.easing||n.easing,render:function(t,e){var n=B.easing.effects[e.easing],i=e.currentStep,a=i/e.numSteps;t.draw(n(a),a,i)},onAnimationProgress:n.onProgress,onAnimationComplete:r});Q.addAnimation(e,o,i,a)}else e.draw(),r(new J({numSteps:0,chart:e}));return e}},draw:function(t){var e,n,i=this;if(i.clear(),B.isNullOrUndef(t)&&(t=1),i.transition(t),!(i.width<=0||i.height<=0)&&!1!==Ie.notify(i,"beforeDraw",[t])){for(n=i._layers,e=0;e<n.length&&n[e].z<=0;++e)n[e].draw(i.chartArea);for(i.drawDatasets(t);e<n.length;++e)n[e].draw(i.chartArea);i._drawTooltip(t),Ie.notify(i,"afterDraw",[t])}},transition:function(t){for(var e=this,n=0,i=(e.data.datasets||[]).length;n<i;++n)e.isDatasetVisible(n)&&e.getDatasetMeta(n).controller.transition(t);e.tooltip.transition(t)},_getSortedDatasetMetas:function(t){var e,n,i=this,a=[];for(e=0,n=(i.data.datasets||[]).length;e<n;++e)t&&!i.isDatasetVisible(e)||a.push(i.getDatasetMeta(e));return a.sort(Je("order","index")),a},_getSortedVisibleDatasetMetas:function(){return this._getSortedDatasetMetas(!0)},drawDatasets:function(t){var e,n,i=this;if(!1!==Ie.notify(i,"beforeDatasetsDraw",[t])){for(n=(e=i._getSortedVisibleDatasetMetas()).length-1;n>=0;--n)i.drawDataset(e[n],t);Ie.notify(i,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n={meta:t,index:t.index,easingValue:e};!1!==Ie.notify(this,"beforeDatasetDraw",[n])&&(t.controller.draw(e),Ie.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this,n=e.tooltip,i={tooltip:n,easingValue:t};!1!==Ie.notify(e,"beforeTooltipDraw",[i])&&(n.draw(),Ie.notify(e,"afterTooltipDraw",[i]))},getElementAtEvent:function(t){return oe.modes.single(this,t)},getElementsAtEvent:function(t){return oe.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return oe.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var i=oe.modes[e];return"function"==typeof i?i(this,t,n):[]},getDatasetAtEvent:function(t){return oe.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this,n=e.data.datasets[t];n._meta||(n._meta={});var i=n._meta[e.id];return i||(i=n._meta[e.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:n.order||0,index:t}),i},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;e<n;++e)this.isDatasetVisible(e)&&t++;return t},isDatasetVisible:function(t){var e=this.getDatasetMeta(t);return"boolean"==typeof e.hidden?!e.hidden:!this.data.datasets[t].hidden},generateLegend:function(){return this.options.legendCallback(this)},destroyDatasetMeta:function(t){var e=this.id,n=this.data.datasets[t],i=n._meta&&n._meta[e];i&&(i.controller.destroy(),delete n._meta[e])},destroy:function(){var t,e,n=this,i=n.canvas;for(n.stop(),t=0,e=n.data.datasets.length;t<e;++t)n.destroyDatasetMeta(t);i&&(n.unbindEvents(),B.canvas.clear(n),Fe.releaseContext(n.ctx),n.canvas=null,n.ctx=null),Ie.notify(n,"destroy"),delete Qe.instances[n.id]},toBase64Image:function(){return this.canvas.toDataURL.apply(this.canvas,arguments)},initToolTip:function(){var t=this;t.tooltip=new Ue({_chart:t,_chartInstance:t,_data:t.data,_options:t.options.tooltips},t)},bindEvents:function(){var t=this,e=t._listeners={},n=function(){t.eventHandler.apply(t,arguments)};B.each(t.options.events,function(i){Fe.addEventListener(t,i,n),e[i]=n}),t.options.responsive&&(n=function(){t.resize()},Fe.addEventListener(t,"resize",n),e.resize=n)},unbindEvents:function(){var t=this,e=t._listeners;e&&(delete t._listeners,B.each(e,function(e,n){Fe.removeEventListener(t,n,e)}))},updateHoverStyle:function(t,e,n){var i,a,r,o=n?"set":"remove";for(a=0,r=t.length;a<r;++a)(i=t[a])&&this.getDatasetMeta(i._datasetIndex).controller[o+"HoverStyle"](i);"dataset"===e&&this.getDatasetMeta(t[0]._datasetIndex).controller["_"+o+"DatasetHoverStyle"]()},eventHandler:function(t){var e=this,n=e.tooltip;if(!1!==Ie.notify(e,"beforeEvent",[t])){e._bufferedRender=!0,e._bufferedRequest=null;var i=e.handleEvent(t);n&&(i=n._start?n.handleEvent(t):i|n.handleEvent(t)),Ie.notify(e,"afterEvent",[t]);var a=e._bufferedRequest;return a?e.render(a):i&&!e.animating&&(e.stop(),e.render({duration:e.options.hover.animationDuration,lazy:!0})),e._bufferedRender=!1,e._bufferedRequest=null,e}},handleEvent:function(t){var e,n=this,i=n.options||{},a=i.hover;return n.lastActive=n.lastActive||[],"mouseout"===t.type?n.active=[]:n.active=n.getElementsAtEventForMode(t,a.mode,a),B.callback(i.onHover||i.hover.onHover,[t.native,n.active],n),"mouseup"!==t.type&&"click"!==t.type||i.onClick&&i.onClick.call(n,t.native,n.active),n.lastActive.length&&n.updateHoverStyle(n.lastActive,a.mode,!1),n.active.length&&a.mode&&n.updateHoverStyle(n.active,a.mode,!0),e=!B.arrayEquals(n.active,n.lastActive),n.lastActive=n.active,e}}),Qe.instances={};var tn=Qe;Qe.Controller=Qe,Qe.types={},B.configMerge=Ze,B.scaleMerge=qe;function en(){throw new Error("This method is not implemented: either no adapter can be found or an incomplete integration was provided.")}function nn(t){this.options=t||{}}B.extend(nn.prototype,{formats:en,parse:en,format:en,add:en,diff:en,startOf:en,endOf:en,_create:function(t){return t}}),nn.override=function(t){B.extend(nn.prototype,t)};var an={_date:nn},rn={formatters:{values:function(t){return B.isArray(t)?t:""+t},linear:function(t,e,n){var i=n.length>3?n[2]-n[1]:n[1]-n[0];Math.abs(i)>1&&t!==Math.floor(t)&&(i=t-Math.floor(t));var a=B.log10(Math.abs(i)),r="";if(0!==t)if(Math.max(Math.abs(n[0]),Math.abs(n[n.length-1]))<1e-4){var o=B.log10(Math.abs(t)),s=Math.floor(o)-Math.floor(a);s=Math.max(Math.min(s,20),0),r=t.toExponential(s)}else{var l=-1*Math.floor(a);l=Math.max(Math.min(l,20),0),r=t.toFixed(l)}else r="0";return r},logarithmic:function(t,e,n){var i=t/Math.pow(10,Math.floor(B.log10(t)));return 0===t?"0":1===i||2===i||5===i||0===e||e===n.length-1?t.toExponential():""}}},on=B.isArray,sn=B.isNullOrUndef,ln=B.valueOrDefault,un=B.valueAtIndexOrDefault;function dn(t,e,n){var i,a=t.getTicks().length,r=Math.min(e,a-1),o=t.getPixelForTick(r),s=t._startPixel,l=t._endPixel,u=1e-6;if(!(n&&(i=1===a?Math.max(o-s,l-o):0===e?(t.getPixelForTick(1)-o)/2:(o-t.getPixelForTick(r-1))/2,(o+=r<e?i:-i)<s-u||o>l+u)))return o}function hn(t,e,n,i){var a,r,o,s,l,u,d,h,c,f,g,m,p,v=n.length,b=[],y=[],x=[],_=0,w=0;for(a=0;a<v;++a){if(s=n[a].label,l=n[a].major?e.major:e.minor,t.font=u=l.string,d=i[u]=i[u]||{data:{},gc:[]},h=l.lineHeight,c=f=0,sn(s)||on(s)){if(on(s))for(r=0,o=s.length;r<o;++r)g=s[r],sn(g)||on(g)||(c=B.measureText(t,d.data,d.gc,c,g),f+=h)}else c=B.measureText(t,d.data,d.gc,c,s),f=h;b.push(c),y.push(f),x.push(h/2),_=Math.max(c,_),w=Math.max(f,w)}function k(t){return{width:b[t]||0,height:y[t]||0,offset:x[t]||0}}return function(t,e){B.each(t,function(t){var n,i=t.gc,a=i.length/2;if(a>e){for(n=0;n<a;++n)delete t.data[i[n]];i.splice(0,a)}})}(i,v),m=b.indexOf(_),p=y.indexOf(w),{first:k(0),last:k(v-1),widest:k(m),highest:k(p)}}function cn(t){return t.drawTicks?t.tickMarkLength:0}function fn(t){var e,n;return t.display?(e=B.options._parseFont(t),n=B.options.toPadding(t.padding),e.lineHeight+n.height):0}function gn(t,e){return B.extend(B.options._parseFont({fontFamily:ln(e.fontFamily,t.fontFamily),fontSize:ln(e.fontSize,t.fontSize),fontStyle:ln(e.fontStyle,t.fontStyle),lineHeight:ln(e.lineHeight,t.lineHeight)}),{color:B.options.resolve([e.fontColor,t.fontColor,Y.global.defaultFontColor])})}function mn(t){var e=gn(t,t.minor);return{minor:e,major:t.major.enabled?gn(t,t.major):e}}function pn(t){var e,n,i,a=[];for(n=0,i=t.length;n<i;++n)void 0!==(e=t[n])._index&&a.push(e);return a}function vn(t,e,n,i){var a,r,o,s,l=ln(n,0),u=Math.min(ln(i,t.length),t.length),d=0;for(e=Math.ceil(e),i&&(e=(a=i-n)/Math.floor(a/e)),s=l;s<0;)d++,s=Math.round(l+d*e);for(r=Math.max(l,0);r<u;r++)o=t[r],r===s?(o._index=r,d++,s=Math.round(l+d*e)):delete o.label}Y._set("scale",{display:!0,position:"left",offset:!1,gridLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickMarkLength:10,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",zeroLineBorderDash:[],zeroLineBorderDashOffset:0,offsetGridLines:!1,borderDash:[],borderDashOffset:0},scaleLabel:{display:!1,labelString:"",padding:{top:4,bottom:4}},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:0,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:rn.formatters.values,minor:{},major:{}}});var bn=X.extend({zeroLineIndex:0,getPadding:function(){var t=this;return{left:t.paddingLeft||0,top:t.paddingTop||0,right:t.paddingRight||0,bottom:t.paddingBottom||0}},getTicks:function(){return this._ticks},_getLabels:function(){var t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]},mergeTicksOptions:function(){},beforeUpdate:function(){B.callback(this.options.beforeUpdate,[this])},update:function(t,e,n){var i,a,r,o,s,l=this,u=l.options.ticks,d=u.sampleSize;if(l.beforeUpdate(),l.maxWidth=t,l.maxHeight=e,l.margins=B.extend({left:0,right:0,top:0,bottom:0},n),l._ticks=null,l.ticks=null,l._labelSizes=null,l._maxLabelLines=0,l.longestLabelWidth=0,l.longestTextCache=l.longestTextCache||{},l._gridLineItems=null,l._labelItems=null,l.beforeSetDimensions(),l.setDimensions(),l.afterSetDimensions(),l.beforeDataLimits(),l.determineDataLimits(),l.afterDataLimits(),l.beforeBuildTicks(),o=l.buildTicks()||[],(!(o=l.afterBuildTicks(o)||o)||!o.length)&&l.ticks)for(o=[],i=0,a=l.ticks.length;i<a;++i)o.push({value:l.ticks[i],major:!1});return l._ticks=o,s=d<o.length,r=l._convertTicksToLabels(s?function(t,e){for(var n=[],i=t.length/e,a=0,r=t.length;a<r;a+=i)n.push(t[Math.floor(a)]);return n}(o,d):o),l._configure(),l.beforeCalculateTickRotation(),l.calculateTickRotation(),l.afterCalculateTickRotation(),l.beforeFit(),l.fit(),l.afterFit(),l._ticksToDraw=u.display&&(u.autoSkip||"auto"===u.source)?l._autoSkip(o):o,s&&(r=l._convertTicksToLabels(l._ticksToDraw)),l.ticks=r,l.afterUpdate(),l.minSize},_configure:function(){var t,e,n=this,i=n.options.ticks.reverse;n.isHorizontal()?(t=n.left,e=n.right):(t=n.top,e=n.bottom,i=!i),n._startPixel=t,n._endPixel=e,n._reversePixels=i,n._length=e-t},afterUpdate:function(){B.callback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){B.callback(this.options.beforeSetDimensions,[this])},setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0},afterSetDimensions:function(){B.callback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){B.callback(this.options.beforeDataLimits,[this])},determineDataLimits:B.noop,afterDataLimits:function(){B.callback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){B.callback(this.options.beforeBuildTicks,[this])},buildTicks:B.noop,afterBuildTicks:function(t){var e=this;return on(t)&&t.length?B.callback(e.options.afterBuildTicks,[e,t]):(e.ticks=B.callback(e.options.afterBuildTicks,[e,e.ticks])||e.ticks,t)},beforeTickToLabelConversion:function(){B.callback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this,e=t.options.ticks;t.ticks=t.ticks.map(e.userCallback||e.callback,this)},afterTickToLabelConversion:function(){B.callback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){B.callback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var t,e,n,i,a,r,o,s=this,l=s.options,u=l.ticks,d=s.getTicks().length,h=u.minRotation||0,c=u.maxRotation,f=h;!s._isVisible()||!u.display||h>=c||d<=1||!s.isHorizontal()?s.labelRotation=h:(e=(t=s._getLabelSizes()).widest.width,n=t.highest.height-t.highest.offset,i=Math.min(s.maxWidth,s.chart.width-e),e+6>(a=l.offset?s.maxWidth/d:i/(d-1))&&(a=i/(d-(l.offset?.5:1)),r=s.maxHeight-cn(l.gridLines)-u.padding-fn(l.scaleLabel),o=Math.sqrt(e*e+n*n),f=B.toDegrees(Math.min(Math.asin(Math.min((t.highest.height+6)/a,1)),Math.asin(Math.min(r/o,1))-Math.asin(n/o))),f=Math.max(h,Math.min(c,f))),s.labelRotation=f)},afterCalculateTickRotation:function(){B.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){B.callback(this.options.beforeFit,[this])},fit:function(){var t=this,e=t.minSize={width:0,height:0},n=t.chart,i=t.options,a=i.ticks,r=i.scaleLabel,o=i.gridLines,s=t._isVisible(),l="bottom"===i.position,u=t.isHorizontal();if(u?e.width=t.maxWidth:s&&(e.width=cn(o)+fn(r)),u?s&&(e.height=cn(o)+fn(r)):e.height=t.maxHeight,a.display&&s){var d=mn(a),h=t._getLabelSizes(),c=h.first,f=h.last,g=h.widest,m=h.highest,p=.4*d.minor.lineHeight,v=a.padding;if(u){var b=0!==t.labelRotation,y=B.toRadians(t.labelRotation),x=Math.cos(y),_=Math.sin(y),w=_*g.width+x*(m.height-(b?m.offset:0))+(b?0:p);e.height=Math.min(t.maxHeight,e.height+w+v);var k,M,S=t.getPixelForTick(0)-t.left,D=t.right-t.getPixelForTick(t.getTicks().length-1);b?(k=l?x*c.width+_*c.offset:_*(c.height-c.offset),M=l?_*(f.height-f.offset):x*f.width+_*f.offset):(k=c.width/2,M=f.width/2),t.paddingLeft=Math.max((k-S)*t.width/(t.width-S),0)+3,t.paddingRight=Math.max((M-D)*t.width/(t.width-D),0)+3}else{var C=a.mirror?0:g.width+v+p;e.width=Math.min(t.maxWidth,e.width+C),t.paddingTop=c.height/2,t.paddingBottom=f.height/2}}t.handleMargins(),u?(t.width=t._length=n.width-t.margins.left-t.margins.right,t.height=e.height):(t.width=e.width,t.height=t._length=n.height-t.margins.top-t.margins.bottom)},handleMargins:function(){var t=this;t.margins&&(t.margins.left=Math.max(t.paddingLeft,t.margins.left),t.margins.top=Math.max(t.paddingTop,t.margins.top),t.margins.right=Math.max(t.paddingRight,t.margins.right),t.margins.bottom=Math.max(t.paddingBottom,t.margins.bottom))},afterFit:function(){B.callback(this.options.afterFit,[this])},isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(sn(t))return NaN;if(("number"==typeof t||t instanceof Number)&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},_convertTicksToLabels:function(t){var e,n,i,a=this;for(a.ticks=t.map(function(t){return t.value}),a.beforeTickToLabelConversion(),e=a.convertTicksToLabels(t)||a.ticks,a.afterTickToLabelConversion(),n=0,i=t.length;n<i;++n)t[n].label=e[n];return e},_getLabelSizes:function(){var t=this,e=t._labelSizes;return e||(t._labelSizes=e=hn(t.ctx,mn(t.options.ticks),t.getTicks(),t.longestTextCache),t.longestLabelWidth=e.widest.width),e},_parseValue:function(t){var e,n,i,a;return on(t)?(e=+this.getRightValue(t[0]),n=+this.getRightValue(t[1]),i=Math.min(e,n),a=Math.max(e,n)):(e=void 0,n=t=+this.getRightValue(t),i=t,a=t),{min:i,max:a,start:e,end:n}},_getScaleLabel:function(t){var e=this._parseValue(t);return void 0!==e.start?"["+e.start+", "+e.end+"]":+this.getRightValue(t)},getLabelForIndex:B.noop,getPixelForValue:B.noop,getValueForPixel:B.noop,getPixelForTick:function(t){var e=this,n=e.options.offset,i=e._ticks.length,a=1/Math.max(i-(n?0:1),1);return t<0||t>i-1?null:e.getPixelForDecimal(t*a+(n?a/2:0))},getPixelForDecimal:function(t){var e=this;return e._reversePixels&&(t=1-t),e._startPixel+t*e._length},getDecimalForPixel:function(t){var e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this,e=t.min,n=t.max;return t.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0},_autoSkip:function(t){var e,n,i,a,r=this,o=r.options.ticks,s=r._length,l=o.maxTicksLimit||s/r._tickSize()+1,u=o.major.enabled?function(t){var e,n,i=[];for(e=0,n=t.length;e<n;e++)t[e].major&&i.push(e);return i}(t):[],d=u.length,h=u[0],c=u[d-1];if(d>l)return function(t,e,n){var i,a,r=0,o=e[0];for(n=Math.ceil(n),i=0;i<t.length;i++)a=t[i],i===o?(a._index=i,o=e[++r*n]):delete a.label}(t,u,d/l),pn(t);if(i=function(t,e,n,i){var a,r,o,s,l=function(t){var e,n,i=t.length;if(i<2)return!1;for(n=t[0],e=1;e<i;++e)if(t[e]-t[e-1]!==n)return!1;return n}(t),u=(e.length-1)/i;if(!l)return Math.max(u,1);for(o=0,s=(a=B.math._factorize(l)).length-1;o<s;o++)if((r=a[o])>u)return r;return Math.max(u,1)}(u,t,0,l),d>0){for(e=0,n=d-1;e<n;e++)vn(t,i,u[e],u[e+1]);return a=d>1?(c-h)/(d-1):null,vn(t,i,B.isNullOrUndef(a)?0:h-a,h),vn(t,i,c,B.isNullOrUndef(a)?t.length:c+a),pn(t)}return vn(t,i),pn(t)},_tickSize:function(){var t=this,e=t.options.ticks,n=B.toRadians(t.labelRotation),i=Math.abs(Math.cos(n)),a=Math.abs(Math.sin(n)),r=t._getLabelSizes(),o=e.autoSkipPadding||0,s=r?r.widest.width+o:0,l=r?r.highest.height+o:0;return t.isHorizontal()?l*i>s*a?s/i:l/a:l*a<s*i?l/i:s/a},_isVisible:function(){var t,e,n,i=this,a=i.chart,r=i.options.display;if("auto"!==r)return!!r;for(t=0,e=a.data.datasets.length;t<e;++t)if(a.isDatasetVisible(t)&&((n=a.getDatasetMeta(t)).xAxisID===i.id||n.yAxisID===i.id))return!0;return!1},_computeGridLineItems:function(t){var e,n,i,a,r,o,s,l,u,d,h,c,f,g,m,p,v,b=this,y=b.chart,x=b.options,_=x.gridLines,w=x.position,k=_.offsetGridLines,M=b.isHorizontal(),S=b._ticksToDraw,D=S.length+(k?1:0),C=cn(_),P=[],T=_.drawBorder?un(_.lineWidth,0,0):0,O=T/2,A=B._alignPixel,F=function(t){return A(y,t,T)};for("top"===w?(e=F(b.bottom),s=b.bottom-C,u=e-O,h=F(t.top)+O,f=t.bottom):"bottom"===w?(e=F(b.top),h=t.top,f=F(t.bottom)-O,s=e+O,u=b.top+C):"left"===w?(e=F(b.right),o=b.right-C,l=e-O,d=F(t.left)+O,c=t.right):(e=F(b.left),d=t.left,c=F(t.right)-O,o=e+O,l=b.left+C),n=0;n<D;++n)i=S[n]||{},sn(i.label)&&n<S.length||(n===b.zeroLineIndex&&x.offset===k?(g=_.zeroLineWidth,m=_.zeroLineColor,p=_.zeroLineBorderDash||[],v=_.zeroLineBorderDashOffset||0):(g=un(_.lineWidth,n,1),m=un(_.color,n,"rgba(0,0,0,0.1)"),p=_.borderDash||[],v=_.borderDashOffset||0),void 0!==(a=dn(b,i._index||n,k))&&(r=A(y,a,g),M?o=l=d=c=r:s=u=h=f=r,P.push({tx1:o,ty1:s,tx2:l,ty2:u,x1:d,y1:h,x2:c,y2:f,width:g,color:m,borderDash:p,borderDashOffset:v})));return P.ticksLength=D,P.borderValue=e,P},_computeLabelItems:function(){var t,e,n,i,a,r,o,s,l,u,d,h,c=this,f=c.options,g=f.ticks,m=f.position,p=g.mirror,v=c.isHorizontal(),b=c._ticksToDraw,y=mn(g),x=g.padding,_=cn(f.gridLines),w=-B.toRadians(c.labelRotation),k=[];for("top"===m?(r=c.bottom-_-x,o=w?"left":"center"):"bottom"===m?(r=c.top+_+x,o=w?"right":"center"):"left"===m?(a=c.right-(p?0:_)-x,o=p?"left":"right"):(a=c.left+(p?0:_)+x,o=p?"right":"left"),t=0,e=b.length;t<e;++t)i=(n=b[t]).label,sn(i)||(s=c.getPixelForTick(n._index||t)+g.labelOffset,u=(l=n.major?y.major:y.minor).lineHeight,d=on(i)?i.length:1,v?(a=s,h="top"===m?((w?1:.5)-d)*u:(w?0:.5)*u):(r=s,h=(1-d)*u/2),k.push({x:a,y:r,rotation:w,label:i,font:l,textOffset:h,textAlign:o}));return k},_drawGrid:function(t){var e=this,n=e.options.gridLines;if(n.display){var i,a,r,o,s,l=e.ctx,u=e.chart,d=B._alignPixel,h=n.drawBorder?un(n.lineWidth,0,0):0,c=e._gridLineItems||(e._gridLineItems=e._computeGridLineItems(t));for(r=0,o=c.length;r<o;++r)i=(s=c[r]).width,a=s.color,i&&a&&(l.save(),l.lineWidth=i,l.strokeStyle=a,l.setLineDash&&(l.setLineDash(s.borderDash),l.lineDashOffset=s.borderDashOffset),l.beginPath(),n.drawTicks&&(l.moveTo(s.tx1,s.ty1),l.lineTo(s.tx2,s.ty2)),n.drawOnChartArea&&(l.moveTo(s.x1,s.y1),l.lineTo(s.x2,s.y2)),l.stroke(),l.restore());if(h){var f,g,m,p,v=h,b=un(n.lineWidth,c.ticksLength-1,1),y=c.borderValue;e.isHorizontal()?(f=d(u,e.left,v)-v/2,g=d(u,e.right,b)+b/2,m=p=y):(m=d(u,e.top,v)-v/2,p=d(u,e.bottom,b)+b/2,f=g=y),l.lineWidth=h,l.strokeStyle=un(n.color,0),l.beginPath(),l.moveTo(f,m),l.lineTo(g,p),l.stroke()}}},_drawLabels:function(){var t=this;if(t.options.ticks.display){var e,n,i,a,r,o,s,l,u=t.ctx,d=t._labelItems||(t._labelItems=t._computeLabelItems());for(e=0,i=d.length;e<i;++e){if(o=(r=d[e]).font,u.save(),u.translate(r.x,r.y),u.rotate(r.rotation),u.font=o.string,u.fillStyle=o.color,u.textBaseline="middle",u.textAlign=r.textAlign,s=r.label,l=r.textOffset,on(s))for(n=0,a=s.length;n<a;++n)u.fillText(""+s[n],0,l),l+=o.lineHeight;else u.fillText(s,0,l);u.restore()}}},_drawTitle:function(){var t=this,e=t.ctx,n=t.options,i=n.scaleLabel;if(i.display){var a,r,o=ln(i.fontColor,Y.global.defaultFontColor),s=B.options._parseFont(i),l=B.options.toPadding(i.padding),u=s.lineHeight/2,d=n.position,h=0;if(t.isHorizontal())a=t.left+t.width/2,r="bottom"===d?t.bottom-u-l.bottom:t.top+u+l.top;else{var c="left"===d;a=c?t.left+u+l.top:t.right-u-l.top,r=t.top+t.height/2,h=c?-.5*Math.PI:.5*Math.PI}e.save(),e.translate(a,r),e.rotate(h),e.textAlign="center",e.textBaseline="middle",e.fillStyle=o,e.font=s.string,e.fillText(i.labelString,0,0),e.restore()}},draw:function(t){var e=this;e._isVisible()&&(e._drawGrid(t),e._drawTitle(),e._drawLabels())},_layers:function(){var t=this,e=t.options,n=e.ticks&&e.ticks.z||0,i=e.gridLines&&e.gridLines.z||0;return t._isVisible()&&n!==i&&t.draw===t._draw?[{z:i,draw:function(){t._drawGrid.apply(t,arguments),t._drawTitle.apply(t,arguments)}},{z:n,draw:function(){t._drawLabels.apply(t,arguments)}}]:[{z:n,draw:function(){t.draw.apply(t,arguments)}}]},_getMatchingVisibleMetas:function(t){var e=this,n=e.isHorizontal();return e.chart._getSortedVisibleDatasetMetas().filter(function(i){return(!t||i.type===t)&&(n?i.xAxisID===e.id:i.yAxisID===e.id)})}});bn.prototype._draw=bn.prototype.draw;var yn=bn,xn=B.isNullOrUndef,_n=yn.extend({determineDataLimits:function(){var t,e=this,n=e._getLabels(),i=e.options.ticks,a=i.min,r=i.max,o=0,s=n.length-1;void 0!==a&&(t=n.indexOf(a))>=0&&(o=t),void 0!==r&&(t=n.indexOf(r))>=0&&(s=t),e.minIndex=o,e.maxIndex=s,e.min=n[o],e.max=n[s]},buildTicks:function(){var t=this,e=t._getLabels(),n=t.minIndex,i=t.maxIndex;t.ticks=0===n&&i===e.length-1?e:e.slice(n,i+1)},getLabelForIndex:function(t,e){var n=this,i=n.chart;return i.getDatasetMeta(e).controller._getValueScaleId()===n.id?n.getRightValue(i.data.datasets[e].data[t]):n._getLabels()[t]},_configure:function(){var t=this,e=t.options.offset,n=t.ticks;yn.prototype._configure.call(t),t.isHorizontal()||(t._reversePixels=!t._reversePixels),n&&(t._startValue=t.minIndex-(e?.5:0),t._valueRange=Math.max(n.length-(e?0:1),1))},getPixelForValue:function(t,e,n){var i,a,r,o=this;return xn(e)||xn(n)||(t=o.chart.data.datasets[n].data[e]),xn(t)||(i=o.isHorizontal()?t.x:t.y),(void 0!==i||void 0!==t&&isNaN(e))&&(a=o._getLabels(),t=B.valueOrDefault(i,t),e=-1!==(r=a.indexOf(t))?r:e,isNaN(e)&&(e=t)),o.getPixelForDecimal((e-o._startValue)/o._valueRange)},getPixelForTick:function(t){var e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t],t+this.minIndex)},getValueForPixel:function(t){var e=this,n=Math.round(e._startValue+e.getDecimalForPixel(t)*e._valueRange);return Math.min(Math.max(n,0),e.ticks.length-1)},getBasePixel:function(){return this.bottom}}),wn={position:"bottom"};_n._defaults=wn;var kn=B.noop,Mn=B.isNullOrUndef;var Sn=yn.extend({getRightValue:function(t){return"string"==typeof t?+t:yn.prototype.getRightValue.call(this,t)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var n=B.sign(t.min),i=B.sign(t.max);n<0&&i<0?t.max=0:n>0&&i>0&&(t.min=0)}var a=void 0!==e.min||void 0!==e.suggestedMin,r=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),a!==r&&t.min>=t.max&&(a?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:function(){var t,e=this,n=e.options.ticks,i=n.stepSize,a=n.maxTicksLimit;return i?t=Math.ceil(e.max/i)-Math.floor(e.min/i)+1:(t=e._computeTickLimit(),a=a||11),a&&(t=Math.min(a,t)),t},_computeTickLimit:function(){return Number.POSITIVE_INFINITY},handleDirectionalChanges:kn,buildTicks:function(){var t=this,e=t.options.ticks,n=t.getTickLimit(),i={maxTicks:n=Math.max(2,n),min:e.min,max:e.max,precision:e.precision,stepSize:B.valueOrDefault(e.fixedStepSize,e.stepSize)},a=t.ticks=function(t,e){var n,i,a,r,o=[],s=t.stepSize,l=s||1,u=t.maxTicks-1,d=t.min,h=t.max,c=t.precision,f=e.min,g=e.max,m=B.niceNum((g-f)/u/l)*l;if(m<1e-14&&Mn(d)&&Mn(h))return[f,g];(r=Math.ceil(g/m)-Math.floor(f/m))>u&&(m=B.niceNum(r*m/u/l)*l),s||Mn(c)?n=Math.pow(10,B._decimalPlaces(m)):(n=Math.pow(10,c),m=Math.ceil(m*n)/n),i=Math.floor(f/m)*m,a=Math.ceil(g/m)*m,s&&(!Mn(d)&&B.almostWhole(d/m,m/1e3)&&(i=d),!Mn(h)&&B.almostWhole(h/m,m/1e3)&&(a=h)),r=(a-i)/m,r=B.almostEquals(r,Math.round(r),m/1e3)?Math.round(r):Math.ceil(r),i=Math.round(i*n)/n,a=Math.round(a*n)/n,o.push(Mn(d)?i:d);for(var p=1;p<r;++p)o.push(Math.round((i+p*m)*n)/n);return o.push(Mn(h)?a:h),o}(i,t);t.handleDirectionalChanges(),t.max=B.max(a),t.min=B.min(a),e.reverse?(a.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){var t=this;t.ticksAsNumbers=t.ticks.slice(),t.zeroLineIndex=t.ticks.indexOf(0),yn.prototype.convertTicksToLabels.call(t)},_configure:function(){var t,e=this,n=e.getTicks(),i=e.min,a=e.max;yn.prototype._configure.call(e),e.options.offset&&n.length&&(i-=t=(a-i)/Math.max(n.length-1,1)/2,a+=t),e._startValue=i,e._endValue=a,e._valueRange=a-i}}),Dn={position:"left",ticks:{callback:rn.formatters.linear}};function Cn(t,e,n,i){var a,r,o=t.options,s=function(t,e,n){var i=[n.type,void 0===e&&void 0===n.stack?n.index:"",n.stack].join(".");return void 0===t[i]&&(t[i]={pos:[],neg:[]}),t[i]}(e,o.stacked,n),l=s.pos,u=s.neg,d=i.length;for(a=0;a<d;++a)r=t._parseValue(i[a]),isNaN(r.min)||isNaN(r.max)||n.data[a].hidden||(l[a]=l[a]||0,u[a]=u[a]||0,o.relativePoints?l[a]=100:r.min<0||r.max<0?u[a]+=r.min:l[a]+=r.max)}function Pn(t,e,n){var i,a,r=n.length;for(i=0;i<r;++i)a=t._parseValue(n[i]),isNaN(a.min)||isNaN(a.max)||e.data[i].hidden||(t.min=Math.min(t.min,a.min),t.max=Math.max(t.max,a.max))}var Tn=Sn.extend({determineDataLimits:function(){var t,e,n,i,a=this,r=a.options,o=a.chart.data.datasets,s=a._getMatchingVisibleMetas(),l=r.stacked,u={},d=s.length;if(a.min=Number.POSITIVE_INFINITY,a.max=Number.NEGATIVE_INFINITY,void 0===l)for(t=0;!l&&t<d;++t)l=void 0!==(e=s[t]).stack;for(t=0;t<d;++t)n=o[(e=s[t]).index].data,l?Cn(a,u,e,n):Pn(a,e,n);B.each(u,function(t){i=t.pos.concat(t.neg),a.min=Math.min(a.min,B.min(i)),a.max=Math.max(a.max,B.max(i))}),a.min=B.isFinite(a.min)&&!isNaN(a.min)?a.min:0,a.max=B.isFinite(a.max)&&!isNaN(a.max)?a.max:1,a.handleTickRangeOptions()},_computeTickLimit:function(){var t,e=this;return e.isHorizontal()?Math.ceil(e.width/40):(t=B.options._parseFont(e.options.ticks),Math.ceil(e.height/t.lineHeight))},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return this._getScaleLabel(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e=this;return e.getPixelForDecimal((+e.getRightValue(t)-e._startValue)/e._valueRange)},getValueForPixel:function(t){return this._startValue+this.getDecimalForPixel(t)*this._valueRange},getPixelForTick:function(t){var e=this.ticksAsNumbers;return t<0||t>e.length-1?null:this.getPixelForValue(e[t])}}),On=Dn;Tn._defaults=On;var An=B.valueOrDefault,Fn=B.math.log10;var In={position:"left",ticks:{callback:rn.formatters.logarithmic}};function Ln(t,e){return B.isFinite(t)&&t>=0?t:e}var Rn=yn.extend({determineDataLimits:function(){var t,e,n,i,a,r,o=this,s=o.options,l=o.chart,u=l.data.datasets,d=o.isHorizontal();function h(t){return d?t.xAxisID===o.id:t.yAxisID===o.id}o.min=Number.POSITIVE_INFINITY,o.max=Number.NEGATIVE_INFINITY,o.minNotZero=Number.POSITIVE_INFINITY;var c=s.stacked;if(void 0===c)for(t=0;t<u.length;t++)if(e=l.getDatasetMeta(t),l.isDatasetVisible(t)&&h(e)&&void 0!==e.stack){c=!0;break}if(s.stacked||c){var f={};for(t=0;t<u.length;t++){var g=[(e=l.getDatasetMeta(t)).type,void 0===s.stacked&&void 0===e.stack?t:"",e.stack].join(".");if(l.isDatasetVisible(t)&&h(e))for(void 0===f[g]&&(f[g]=[]),a=0,r=(i=u[t].data).length;a<r;a++){var m=f[g];n=o._parseValue(i[a]),isNaN(n.min)||isNaN(n.max)||e.data[a].hidden||n.min<0||n.max<0||(m[a]=m[a]||0,m[a]+=n.max)}}B.each(f,function(t){if(t.length>0){var e=B.min(t),n=B.max(t);o.min=Math.min(o.min,e),o.max=Math.max(o.max,n)}})}else for(t=0;t<u.length;t++)if(e=l.getDatasetMeta(t),l.isDatasetVisible(t)&&h(e))for(a=0,r=(i=u[t].data).length;a<r;a++)n=o._parseValue(i[a]),isNaN(n.min)||isNaN(n.max)||e.data[a].hidden||n.min<0||n.max<0||(o.min=Math.min(n.min,o.min),o.max=Math.max(n.max,o.max),0!==n.min&&(o.minNotZero=Math.min(n.min,o.minNotZero)));o.min=B.isFinite(o.min)?o.min:null,o.max=B.isFinite(o.max)?o.max:null,o.minNotZero=B.isFinite(o.minNotZero)?o.minNotZero:null,this.handleTickRangeOptions()},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;t.min=Ln(e.min,t.min),t.max=Ln(e.max,t.max),t.min===t.max&&(0!==t.min&&null!==t.min?(t.min=Math.pow(10,Math.floor(Fn(t.min))-1),t.max=Math.pow(10,Math.floor(Fn(t.max))+1)):(t.min=1,t.max=10)),null===t.min&&(t.min=Math.pow(10,Math.floor(Fn(t.max))-1)),null===t.max&&(t.max=0!==t.min?Math.pow(10,Math.floor(Fn(t.min))+1):10),null===t.minNotZero&&(t.min>0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(Fn(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,n=!t.isHorizontal(),i={min:Ln(e.min),max:Ln(e.max)},a=t.ticks=function(t,e){var n,i,a=[],r=An(t.min,Math.pow(10,Math.floor(Fn(e.min)))),o=Math.floor(Fn(e.max)),s=Math.ceil(e.max/Math.pow(10,o));0===r?(n=Math.floor(Fn(e.minNotZero)),i=Math.floor(e.minNotZero/Math.pow(10,n)),a.push(r),r=i*Math.pow(10,n)):(n=Math.floor(Fn(r)),i=Math.floor(r/Math.pow(10,n)));var l=n<0?Math.pow(10,Math.abs(n)):1;do{a.push(r),10==++i&&(i=1,l=++n>=0?1:l),r=Math.round(i*Math.pow(10,n)*l)/l}while(n<o||n===o&&i<s);var u=An(t.max,r);return a.push(u),a}(i,t);t.max=B.max(a),t.min=B.min(a),e.reverse?(n=!n,t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max),n&&a.reverse()},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),yn.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(t,e){return this._getScaleLabel(this.chart.data.datasets[e].data[t])},getPixelForTick:function(t){var e=this.tickValues;return t<0||t>e.length-1?null:this.getPixelForValue(e[t])},_getFirstTickValue:function(t){var e=Math.floor(Fn(t));return Math.floor(t/Math.pow(10,e))*Math.pow(10,e)},_configure:function(){var t=this,e=t.min,n=0;yn.prototype._configure.call(t),0===e&&(e=t._getFirstTickValue(t.minNotZero),n=An(t.options.ticks.fontSize,Y.global.defaultFontSize)/t._length),t._startValue=Fn(e),t._valueOffset=n,t._valueRange=(Fn(t.max)-Fn(e))/(1-n)},getPixelForValue:function(t){var e=this,n=0;return(t=+e.getRightValue(t))>e.min&&t>0&&(n=(Fn(t)-e._startValue)/e._valueRange+e._valueOffset),e.getPixelForDecimal(n)},getValueForPixel:function(t){var e=this,n=e.getDecimalForPixel(t);return 0===n&&0===e.min?0:Math.pow(10,e._startValue+(n-e._valueOffset)*e._valueRange)}}),Nn=In;Rn._defaults=Nn;var Wn=B.valueOrDefault,Yn=B.valueAtIndexOrDefault,zn=B.options.resolve,En={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,borderDash:[],borderDashOffset:0},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:rn.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function Vn(t){var e=t.ticks;return e.display&&t.display?Wn(e.fontSize,Y.global.defaultFontSize)+2*e.backdropPaddingY:0}function Hn(t,e,n,i,a){return t===i||t===a?{start:e-n/2,end:e+n/2}:t<i||t>a?{start:e-n,end:e}:{start:e,end:e+n}}function Bn(t){return 0===t||180===t?"center":t<180?"left":"right"}function jn(t,e,n,i){var a,r,o=n.y+i/2;if(B.isArray(e))for(a=0,r=e.length;a<r;++a)t.fillText(e[a],n.x,o),o+=i;else t.fillText(e,n.x,o)}function Un(t,e,n){90===t||270===t?n.y-=e.h/2:(t>270||t<90)&&(n.y-=e.h)}function Gn(t){return B.isNumber(t)?t:0}var qn=Sn.extend({setDimensions:function(){var t=this;t.width=t.maxWidth,t.height=t.maxHeight,t.paddingTop=Vn(t.options)/2,t.xCenter=Math.floor(t.width/2),t.yCenter=Math.floor((t.height-t.paddingTop)/2),t.drawingArea=Math.min(t.height-t.paddingTop,t.width)/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;B.each(e.data.datasets,function(a,r){if(e.isDatasetVisible(r)){var o=e.getDatasetMeta(r);B.each(a.data,function(e,a){var r=+t.getRightValue(e);isNaN(r)||o.data[a].hidden||(n=Math.min(r,n),i=Math.max(r,i))})}}),t.min=n===Number.POSITIVE_INFINITY?0:n,t.max=i===Number.NEGATIVE_INFINITY?0:i,t.handleTickRangeOptions()},_computeTickLimit:function(){return Math.ceil(this.drawingArea/Vn(this.options))},convertTicksToLabels:function(){var t=this;Sn.prototype.convertTicksToLabels.call(t),t.pointLabels=t.chart.data.labels.map(function(){var e=B.callback(t.options.pointLabels.callback,arguments,t);return e||0===e?e:""})},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t=this,e=t.options;e.display&&e.pointLabels.display?function(t){var e,n,i,a=B.options._parseFont(t.options.pointLabels),r={l:0,r:t.width,t:0,b:t.height-t.paddingTop},o={};t.ctx.font=a.string,t._pointLabelSizes=[];var s,l,u,d=t.chart.data.labels.length;for(e=0;e<d;e++){i=t.getPointPosition(e,t.drawingArea+5),s=t.ctx,l=a.lineHeight,u=t.pointLabels[e],n=B.isArray(u)?{w:B.longestText(s,s.font,u),h:u.length*l}:{w:s.measureText(u).width,h:l},t._pointLabelSizes[e]=n;var h=t.getIndexAngle(e),c=B.toDegrees(h)%360,f=Hn(c,i.x,n.w,0,180),g=Hn(c,i.y,n.h,90,270);f.start<r.l&&(r.l=f.start,o.l=h),f.end>r.r&&(r.r=f.end,o.r=h),g.start<r.t&&(r.t=g.start,o.t=h),g.end>r.b&&(r.b=g.end,o.b=h)}t.setReductions(t.drawingArea,r,o)}(t):t.setCenterPoint(0,0,0,0)},setReductions:function(t,e,n){var i=this,a=e.l/Math.sin(n.l),r=Math.max(e.r-i.width,0)/Math.sin(n.r),o=-e.t/Math.cos(n.t),s=-Math.max(e.b-(i.height-i.paddingTop),0)/Math.cos(n.b);a=Gn(a),r=Gn(r),o=Gn(o),s=Gn(s),i.drawingArea=Math.min(Math.floor(t-(a+r)/2),Math.floor(t-(o+s)/2)),i.setCenterPoint(a,r,o,s)},setCenterPoint:function(t,e,n,i){var a=this,r=a.width-e-a.drawingArea,o=t+a.drawingArea,s=n+a.drawingArea,l=a.height-a.paddingTop-i-a.drawingArea;a.xCenter=Math.floor((o+r)/2+a.left),a.yCenter=Math.floor((s+l)/2+a.top+a.paddingTop)},getIndexAngle:function(t){var e=this.chart,n=(t*(360/e.data.labels.length)+((e.options||{}).startAngle||0))%360;return(n<0?n+360:n)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(B.isNullOrUndef(t))return NaN;var n=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this,i=n.getIndexAngle(t)-Math.PI/2;return{x:Math.cos(i)*e+n.xCenter,y:Math.sin(i)*e+n.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(t){var e=this,n=e.min,i=e.max;return e.getPointPositionForValue(t||0,e.beginAtZero?0:n<0&&i<0?i:n>0&&i>0?n:0)},_drawGrid:function(){var t,e,n,i=this,a=i.ctx,r=i.options,o=r.gridLines,s=r.angleLines,l=Wn(s.lineWidth,o.lineWidth),u=Wn(s.color,o.color);if(r.pointLabels.display&&function(t){var e=t.ctx,n=t.options,i=n.pointLabels,a=Vn(n),r=t.getDistanceFromCenterForValue(n.ticks.reverse?t.min:t.max),o=B.options._parseFont(i);e.save(),e.font=o.string,e.textBaseline="middle";for(var s=t.chart.data.labels.length-1;s>=0;s--){var l=0===s?a/2:0,u=t.getPointPosition(s,r+l+5),d=Yn(i.fontColor,s,Y.global.defaultFontColor);e.fillStyle=d;var h=t.getIndexAngle(s),c=B.toDegrees(h);e.textAlign=Bn(c),Un(c,t._pointLabelSizes[s],u),jn(e,t.pointLabels[s],u,o.lineHeight)}e.restore()}(i),o.display&&B.each(i.ticks,function(t,n){0!==n&&(e=i.getDistanceFromCenterForValue(i.ticksAsNumbers[n]),function(t,e,n,i){var a,r=t.ctx,o=e.circular,s=t.chart.data.labels.length,l=Yn(e.color,i-1),u=Yn(e.lineWidth,i-1);if((o||s)&&l&&u){if(r.save(),r.strokeStyle=l,r.lineWidth=u,r.setLineDash&&(r.setLineDash(e.borderDash||[]),r.lineDashOffset=e.borderDashOffset||0),r.beginPath(),o)r.arc(t.xCenter,t.yCenter,n,0,2*Math.PI);else{a=t.getPointPosition(0,n),r.moveTo(a.x,a.y);for(var d=1;d<s;d++)a=t.getPointPosition(d,n),r.lineTo(a.x,a.y)}r.closePath(),r.stroke(),r.restore()}}(i,o,e,n))}),s.display&&l&&u){for(a.save(),a.lineWidth=l,a.strokeStyle=u,a.setLineDash&&(a.setLineDash(zn([s.borderDash,o.borderDash,[]])),a.lineDashOffset=zn([s.borderDashOffset,o.borderDashOffset,0])),t=i.chart.data.labels.length-1;t>=0;t--)e=i.getDistanceFromCenterForValue(r.ticks.reverse?i.min:i.max),n=i.getPointPosition(t,e),a.beginPath(),a.moveTo(i.xCenter,i.yCenter),a.lineTo(n.x,n.y),a.stroke();a.restore()}},_drawLabels:function(){var t=this,e=t.ctx,n=t.options.ticks;if(n.display){var i,a,r=t.getIndexAngle(0),o=B.options._parseFont(n),s=Wn(n.fontColor,Y.global.defaultFontColor);e.save(),e.font=o.string,e.translate(t.xCenter,t.yCenter),e.rotate(r),e.textAlign="center",e.textBaseline="middle",B.each(t.ticks,function(r,l){(0!==l||n.reverse)&&(i=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),n.showLabelBackdrop&&(a=e.measureText(r).width,e.fillStyle=n.backdropColor,e.fillRect(-a/2-n.backdropPaddingX,-i-o.size/2-n.backdropPaddingY,a+2*n.backdropPaddingX,o.size+2*n.backdropPaddingY)),e.fillStyle=s,e.fillText(r,0,-i))}),e.restore()}},_drawTitle:B.noop}),Zn=En;qn._defaults=Zn;var $n=B._deprecated,Xn=B.options.resolve,Kn=B.valueOrDefault,Jn=Number.MIN_SAFE_INTEGER||-9007199254740991,Qn=Number.MAX_SAFE_INTEGER||9007199254740991,ti={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},ei=Object.keys(ti);function ni(t,e){return t-e}function ii(t){return B.valueOrDefault(t.time.min,t.ticks.min)}function ai(t){return B.valueOrDefault(t.time.max,t.ticks.max)}function ri(t,e,n,i){var a=function(t,e,n){for(var i,a,r,o=0,s=t.length-1;o>=0&&o<=s;){if(a=t[(i=o+s>>1)-1]||null,r=t[i],!a)return{lo:null,hi:r};if(r[e]<n)o=i+1;else{if(!(a[e]>n))return{lo:a,hi:r};s=i-1}}return{lo:r,hi:null}}(t,e,n),r=a.lo?a.hi?a.lo:t[t.length-2]:t[0],o=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=o[e]-r[e],l=s?(n-r[e])/s:0,u=(o[i]-r[i])*l;return r[i]+u}function oi(t,e){var n=t._adapter,i=t.options.time,a=i.parser,r=a||i.format,o=e;return"function"==typeof a&&(o=a(o)),B.isFinite(o)||(o="string"==typeof r?n.parse(o,r):n.parse(o)),null!==o?+o:(a||"function"!=typeof r||(o=r(e),B.isFinite(o)||(o=n.parse(o))),o)}function si(t,e){if(B.isNullOrUndef(e))return null;var n=t.options.time,i=oi(t,t.getRightValue(e));return null===i||n.round&&(i=+t._adapter.startOf(i,n.round)),i}function li(t,e,n,i){var a,r,o,s=ei.length;for(a=ei.indexOf(t);a<s-1;++a)if(o=(r=ti[ei[a]]).steps?r.steps:Qn,r.common&&Math.ceil((n-e)/(o*r.size))<=i)return ei[a];return ei[s-1]}function ui(t,e,n){var i,a,r=[],o={},s=e.length;for(i=0;i<s;++i)o[a=e[i]]=i,r.push({value:a,major:!1});return 0!==s&&n?function(t,e,n,i){var a,r,o=t._adapter,s=+o.startOf(e[0].value,i),l=e[e.length-1].value;for(a=s;a<=l;a=+o.add(a,1,i))(r=n[a])>=0&&(e[r].major=!0);return e}(t,r,o,n):r}var di=yn.extend({initialize:function(){this.mergeTicksOptions(),yn.prototype.initialize.call(this)},update:function(){var t=this,e=t.options,n=e.time||(e.time={}),i=t._adapter=new an._date(e.adapters.date);return $n("time scale",n.format,"time.format","time.parser"),$n("time scale",n.min,"time.min","ticks.min"),$n("time scale",n.max,"time.max","ticks.max"),B.mergeIf(n.displayFormats,i.formats()),yn.prototype.update.apply(t,arguments)},getRightValue:function(t){return t&&void 0!==t.t&&(t=t.t),yn.prototype.getRightValue.call(this,t)},determineDataLimits:function(){var t,e,n,i,a,r,o,s=this,l=s.chart,u=s._adapter,d=s.options,h=d.time.unit||"day",c=Qn,f=Jn,g=[],m=[],p=[],v=s._getLabels();for(t=0,n=v.length;t<n;++t)p.push(si(s,v[t]));for(t=0,n=(l.data.datasets||[]).length;t<n;++t)if(l.isDatasetVisible(t))if(a=l.data.datasets[t].data,B.isObject(a[0]))for(m[t]=[],e=0,i=a.length;e<i;++e)r=si(s,a[e]),g.push(r),m[t][e]=r;else m[t]=p.slice(0),o||(g=g.concat(p),o=!0);else m[t]=[];p.length&&(c=Math.min(c,p[0]),f=Math.max(f,p[p.length-1])),g.length&&(g=n>1?function(t){var e,n,i,a={},r=[];for(e=0,n=t.length;e<n;++e)a[i=t[e]]||(a[i]=!0,r.push(i));return r}(g).sort(ni):g.sort(ni),c=Math.min(c,g[0]),f=Math.max(f,g[g.length-1])),c=si(s,ii(d))||c,f=si(s,ai(d))||f,c=c===Qn?+u.startOf(Date.now(),h):c,f=f===Jn?+u.endOf(Date.now(),h)+1:f,s.min=Math.min(c,f),s.max=Math.max(c+1,f),s._table=[],s._timestamps={data:g,datasets:m,labels:p}},buildTicks:function(){var t,e,n,i=this,a=i.min,r=i.max,o=i.options,s=o.ticks,l=o.time,u=i._timestamps,d=[],h=i.getLabelCapacity(a),c=s.source,f=o.distribution;for(u="data"===c||"auto"===c&&"series"===f?u.data:"labels"===c?u.labels:function(t,e,n,i){var a,r=t._adapter,o=t.options,s=o.time,l=s.unit||li(s.minUnit,e,n,i),u=Xn([s.stepSize,s.unitStepSize,1]),d="week"===l&&s.isoWeekday,h=e,c=[];if(d&&(h=+r.startOf(h,"isoWeek",d)),h=+r.startOf(h,d?"day":l),r.diff(n,e,l)>1e5*u)throw e+" and "+n+" are too far apart with stepSize of "+u+" "+l;for(a=h;a<n;a=+r.add(a,u,l))c.push(a);return a!==n&&"ticks"!==o.bounds||c.push(a),c}(i,a,r,h),"ticks"===o.bounds&&u.length&&(a=u[0],r=u[u.length-1]),a=si(i,ii(o))||a,r=si(i,ai(o))||r,t=0,e=u.length;t<e;++t)(n=u[t])>=a&&n<=r&&d.push(n);return i.min=a,i.max=r,i._unit=l.unit||(s.autoSkip?li(l.minUnit,i.min,i.max,h):function(t,e,n,i,a){var r,o;for(r=ei.length-1;r>=ei.indexOf(n);r--)if(o=ei[r],ti[o].common&&t._adapter.diff(a,i,o)>=e-1)return o;return ei[n?ei.indexOf(n):0]}(i,d.length,l.minUnit,i.min,i.max)),i._majorUnit=s.major.enabled&&"year"!==i._unit?function(t){for(var e=ei.indexOf(t)+1,n=ei.length;e<n;++e)if(ti[ei[e]].common)return ei[e]}(i._unit):void 0,i._table=function(t,e,n,i){if("linear"===i||!t.length)return[{time:e,pos:0},{time:n,pos:1}];var a,r,o,s,l,u=[],d=[e];for(a=0,r=t.length;a<r;++a)(s=t[a])>e&&s<n&&d.push(s);for(d.push(n),a=0,r=d.length;a<r;++a)l=d[a+1],o=d[a-1],s=d[a],void 0!==o&&void 0!==l&&Math.round((l+o)/2)===s||u.push({time:s,pos:a/(r-1)});return u}(i._timestamps.data,a,r,f),i._offsets=function(t,e,n,i,a){var r,o,s=0,l=0;return a.offset&&e.length&&(r=ri(t,"time",e[0],"pos"),s=1===e.length?1-r:(ri(t,"time",e[1],"pos")-r)/2,o=ri(t,"time",e[e.length-1],"pos"),l=1===e.length?o:(o-ri(t,"time",e[e.length-2],"pos"))/2),{start:s,end:l,factor:1/(s+1+l)}}(i._table,d,0,0,o),s.reverse&&d.reverse(),ui(i,d,i._majorUnit)},getLabelForIndex:function(t,e){var n=this,i=n._adapter,a=n.chart.data,r=n.options.time,o=a.labels&&t<a.labels.length?a.labels[t]:"",s=a.datasets[e].data[t];return B.isObject(s)&&(o=n.getRightValue(s)),r.tooltipFormat?i.format(oi(n,o),r.tooltipFormat):"string"==typeof o?o:i.format(oi(n,o),r.displayFormats.datetime)},tickFormatFunction:function(t,e,n,i){var a=this,r=a._adapter,o=a.options,s=o.time.displayFormats,l=s[a._unit],u=a._majorUnit,d=s[u],h=n[e],c=o.ticks,f=u&&d&&h&&h.major,g=r.format(t,i||(f?d:l)),m=f?c.major:c.minor,p=Xn([m.callback,m.userCallback,c.callback,c.userCallback]);return p?p(g,e,n):g},convertTicksToLabels:function(t){var e,n,i=[];for(e=0,n=t.length;e<n;++e)i.push(this.tickFormatFunction(t[e].value,e,t));return i},getPixelForOffset:function(t){var e=this,n=e._offsets,i=ri(e._table,"time",t,"pos");return e.getPixelForDecimal((n.start+i)*n.factor)},getPixelForValue:function(t,e,n){var i=this,a=null;if(void 0!==e&&void 0!==n&&(a=i._timestamps.datasets[n][e]),null===a&&(a=si(i,t)),null!==a)return i.getPixelForOffset(a)},getPixelForTick:function(t){var e=this.getTicks();return t>=0&&t<e.length?this.getPixelForOffset(e[t].value):null},getValueForPixel:function(t){var e=this,n=e._offsets,i=e.getDecimalForPixel(t)/n.factor-n.end,a=ri(e._table,"pos",i,"time");return e._adapter._create(a)},_getLabelSize:function(t){var e=this,n=e.options.ticks,i=e.ctx.measureText(t).width,a=B.toRadians(e.isHorizontal()?n.maxRotation:n.minRotation),r=Math.cos(a),o=Math.sin(a),s=Kn(n.fontSize,Y.global.defaultFontSize);return{w:i*r+s*o,h:i*o+s*r}},getLabelWidth:function(t){return this._getLabelSize(t).w},getLabelCapacity:function(t){var e=this,n=e.options.time,i=n.displayFormats,a=i[n.unit]||i.millisecond,r=e.tickFormatFunction(t,0,ui(e,[t],e._majorUnit),a),o=e._getLabelSize(r),s=Math.floor(e.isHorizontal()?e.width/o.w:e.height/o.h);return e.options.offset&&s--,s>0?s:1}}),hi={position:"bottom",distribution:"linear",bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}};di._defaults=hi;var ci={category:_n,linear:Tn,logarithmic:Rn,radialLinear:qn,time:di},fi=e(function(e,n){e.exports=function(){var n,i;function a(){return n.apply(null,arguments)}function r(t){n=t}function o(t){return t instanceof Array||"[object Array]"===Object.prototype.toString.call(t)}function s(t){return null!=t&&"[object Object]"===Object.prototype.toString.call(t)}function l(t){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(t).length;var e;for(e in t)if(t.hasOwnProperty(e))return!1;return!0}function u(t){return void 0===t}function d(t){return"number"==typeof t||"[object Number]"===Object.prototype.toString.call(t)}function h(t){return t instanceof Date||"[object Date]"===Object.prototype.toString.call(t)}function c(t,e){var n,i=[];for(n=0;n<t.length;++n)i.push(e(t[n],n));return i}function f(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function g(t,e){for(var n in e)f(e,n)&&(t[n]=e[n]);return f(e,"toString")&&(t.toString=e.toString),f(e,"valueOf")&&(t.valueOf=e.valueOf),t}function m(t,e,n,i){return Zn(t,e,n,i,!0).utc()}function p(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null,rfc2822:!1,weekdayMismatch:!1}}function v(t){return null==t._pf&&(t._pf=p()),t._pf}function b(t){if(null==t._isValid){var e=v(t),n=i.call(e.parsedDateParts,function(t){return null!=t}),a=!isNaN(t._d.getTime())&&e.overflow<0&&!e.empty&&!e.invalidMonth&&!e.invalidWeekday&&!e.weekdayMismatch&&!e.nullInput&&!e.invalidFormat&&!e.userInvalidated&&(!e.meridiem||e.meridiem&&n);if(t._strict&&(a=a&&0===e.charsLeftOver&&0===e.unusedTokens.length&&void 0===e.bigHour),null!=Object.isFrozen&&Object.isFrozen(t))return a;t._isValid=a}return t._isValid}function y(t){var e=m(NaN);return null!=t?g(v(e),t):v(e).userInvalidated=!0,e}i=Array.prototype.some?Array.prototype.some:function(t){for(var e=Object(this),n=e.length>>>0,i=0;i<n;i++)if(i in e&&t.call(this,e[i],i,e))return!0;return!1};var x=a.momentProperties=[];function _(t,e){var n,i,a;if(u(e._isAMomentObject)||(t._isAMomentObject=e._isAMomentObject),u(e._i)||(t._i=e._i),u(e._f)||(t._f=e._f),u(e._l)||(t._l=e._l),u(e._strict)||(t._strict=e._strict),u(e._tzm)||(t._tzm=e._tzm),u(e._isUTC)||(t._isUTC=e._isUTC),u(e._offset)||(t._offset=e._offset),u(e._pf)||(t._pf=v(e)),u(e._locale)||(t._locale=e._locale),x.length>0)for(n=0;n<x.length;n++)u(a=e[i=x[n]])||(t[i]=a);return t}var w=!1;function k(t){_(this,t),this._d=new Date(null!=t._d?t._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===w&&(w=!0,a.updateOffset(this),w=!1)}function M(t){return t instanceof k||null!=t&&null!=t._isAMomentObject}function S(t){return t<0?Math.ceil(t)||0:Math.floor(t)}function D(t){var e=+t,n=0;return 0!==e&&isFinite(e)&&(n=S(e)),n}function C(t,e,n){var i,a=Math.min(t.length,e.length),r=Math.abs(t.length-e.length),o=0;for(i=0;i<a;i++)(n&&t[i]!==e[i]||!n&&D(t[i])!==D(e[i]))&&o++;return o+r}function P(t){!1===a.suppressDeprecationWarnings&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+t)}function T(t,e){var n=!0;return g(function(){if(null!=a.deprecationHandler&&a.deprecationHandler(null,t),n){for(var i,r=[],o=0;o<arguments.length;o++){if(i="","object"==typeof arguments[o]){for(var s in i+="\n["+o+"] ",arguments[0])i+=s+": "+arguments[0][s]+", ";i=i.slice(0,-2)}else i=arguments[o];r.push(i)}P(t+"\nArguments: "+Array.prototype.slice.call(r).join("")+"\n"+(new Error).stack),n=!1}return e.apply(this,arguments)},e)}var O,A={};function F(t,e){null!=a.deprecationHandler&&a.deprecationHandler(t,e),A[t]||(P(e),A[t]=!0)}function I(t){return t instanceof Function||"[object Function]"===Object.prototype.toString.call(t)}function L(t){var e,n;for(n in t)I(e=t[n])?this[n]=e:this["_"+n]=e;this._config=t,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)}function R(t,e){var n,i=g({},t);for(n in e)f(e,n)&&(s(t[n])&&s(e[n])?(i[n]={},g(i[n],t[n]),g(i[n],e[n])):null!=e[n]?i[n]=e[n]:delete i[n]);for(n in t)f(t,n)&&!f(e,n)&&s(t[n])&&(i[n]=g({},i[n]));return i}function N(t){null!=t&&this.set(t)}a.suppressDeprecationWarnings=!1,a.deprecationHandler=null,O=Object.keys?Object.keys:function(t){var e,n=[];for(e in t)f(t,e)&&n.push(e);return n};var W={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"};function Y(t,e,n){var i=this._calendar[t]||this._calendar.sameElse;return I(i)?i.call(e,n):i}var z={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"};function E(t){var e=this._longDateFormat[t],n=this._longDateFormat[t.toUpperCase()];return e||!n?e:(this._longDateFormat[t]=n.replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t])}var V="Invalid date";function H(){return this._invalidDate}var B="%d",j=/\d{1,2}/;function U(t){return this._ordinal.replace("%d",t)}var G={future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"};function q(t,e,n,i){var a=this._relativeTime[n];return I(a)?a(t,e,n,i):a.replace(/%d/i,t)}function Z(t,e){var n=this._relativeTime[t>0?"future":"past"];return I(n)?n(e):n.replace(/%s/i,e)}var $={};function X(t,e){var n=t.toLowerCase();$[n]=$[n+"s"]=$[e]=t}function K(t){return"string"==typeof t?$[t]||$[t.toLowerCase()]:void 0}function J(t){var e,n,i={};for(n in t)f(t,n)&&(e=K(n))&&(i[e]=t[n]);return i}var Q={};function tt(t,e){Q[t]=e}function et(t){var e=[];for(var n in t)e.push({unit:n,priority:Q[n]});return e.sort(function(t,e){return t.priority-e.priority}),e}function nt(t,e,n){var i=""+Math.abs(t),a=e-i.length;return(t>=0?n?"+":"":"-")+Math.pow(10,Math.max(0,a)).toString().substr(1)+i}var it=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,at=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,rt={},ot={};function st(t,e,n,i){var a=i;"string"==typeof i&&(a=function(){return this[i]()}),t&&(ot[t]=a),e&&(ot[e[0]]=function(){return nt(a.apply(this,arguments),e[1],e[2])}),n&&(ot[n]=function(){return this.localeData().ordinal(a.apply(this,arguments),t)})}function lt(t){return t.match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"")}function ut(t){var e,n,i=t.match(it);for(e=0,n=i.length;e<n;e++)ot[i[e]]?i[e]=ot[i[e]]:i[e]=lt(i[e]);return function(e){var a,r="";for(a=0;a<n;a++)r+=I(i[a])?i[a].call(e,t):i[a];return r}}function dt(t,e){return t.isValid()?(e=ht(e,t.localeData()),rt[e]=rt[e]||ut(e),rt[e](t)):t.localeData().invalidDate()}function ht(t,e){var n=5;function i(t){return e.longDateFormat(t)||t}for(at.lastIndex=0;n>=0&&at.test(t);)t=t.replace(at,i),at.lastIndex=0,n-=1;return t}var ct=/\d/,ft=/\d\d/,gt=/\d{3}/,mt=/\d{4}/,pt=/[+-]?\d{6}/,vt=/\d\d?/,bt=/\d\d\d\d?/,yt=/\d\d\d\d\d\d?/,xt=/\d{1,3}/,_t=/\d{1,4}/,wt=/[+-]?\d{1,6}/,kt=/\d+/,Mt=/[+-]?\d+/,St=/Z|[+-]\d\d:?\d\d/gi,Dt=/Z|[+-]\d\d(?::?\d\d)?/gi,Ct=/[+-]?\d+(\.\d{1,3})?/,Pt=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,Tt={};function Ot(t,e,n){Tt[t]=I(e)?e:function(t,i){return t&&n?n:e}}function At(t,e){return f(Tt,t)?Tt[t](e._strict,e._locale):new RegExp(Ft(t))}function Ft(t){return It(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,e,n,i,a){return e||n||i||a}))}function It(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var Lt={};function Rt(t,e){var n,i=e;for("string"==typeof t&&(t=[t]),d(e)&&(i=function(t,n){n[e]=D(t)}),n=0;n<t.length;n++)Lt[t[n]]=i}function Nt(t,e){Rt(t,function(t,n,i,a){i._w=i._w||{},e(t,i._w,i,a)})}function Wt(t,e,n){null!=e&&f(Lt,t)&&Lt[t](e,n._a,n,t)}var Yt=0,zt=1,Et=2,Vt=3,Ht=4,Bt=5,jt=6,Ut=7,Gt=8;function qt(t){return Zt(t)?366:365}function Zt(t){return t%4==0&&t%100!=0||t%400==0}st("Y",0,0,function(){var t=this.year();return t<=9999?""+t:"+"+t}),st(0,["YY",2],0,function(){return this.year()%100}),st(0,["YYYY",4],0,"year"),st(0,["YYYYY",5],0,"year"),st(0,["YYYYYY",6,!0],0,"year"),X("year","y"),tt("year",1),Ot("Y",Mt),Ot("YY",vt,ft),Ot("YYYY",_t,mt),Ot("YYYYY",wt,pt),Ot("YYYYYY",wt,pt),Rt(["YYYYY","YYYYYY"],Yt),Rt("YYYY",function(t,e){e[Yt]=2===t.length?a.parseTwoDigitYear(t):D(t)}),Rt("YY",function(t,e){e[Yt]=a.parseTwoDigitYear(t)}),Rt("Y",function(t,e){e[Yt]=parseInt(t,10)}),a.parseTwoDigitYear=function(t){return D(t)+(D(t)>68?1900:2e3)};var $t,Xt=Jt("FullYear",!0);function Kt(){return Zt(this.year())}function Jt(t,e){return function(n){return null!=n?(te(this,t,n),a.updateOffset(this,e),this):Qt(this,t)}}function Qt(t,e){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+e]():NaN}function te(t,e,n){t.isValid()&&!isNaN(n)&&("FullYear"===e&&Zt(t.year())&&1===t.month()&&29===t.date()?t._d["set"+(t._isUTC?"UTC":"")+e](n,t.month(),ae(n,t.month())):t._d["set"+(t._isUTC?"UTC":"")+e](n))}function ee(t){return I(this[t=K(t)])?this[t]():this}function ne(t,e){if("object"==typeof t)for(var n=et(t=J(t)),i=0;i<n.length;i++)this[n[i].unit](t[n[i].unit]);else if(I(this[t=K(t)]))return this[t](e);return this}function ie(t,e){return(t%e+e)%e}function ae(t,e){if(isNaN(t)||isNaN(e))return NaN;var n=ie(e,12);return t+=(e-n)/12,1===n?Zt(t)?29:28:31-n%7%2}$t=Array.prototype.indexOf?Array.prototype.indexOf:function(t){var e;for(e=0;e<this.length;++e)if(this[e]===t)return e;return-1},st("M",["MM",2],"Mo",function(){return this.month()+1}),st("MMM",0,0,function(t){return this.localeData().monthsShort(this,t)}),st("MMMM",0,0,function(t){return this.localeData().months(this,t)}),X("month","M"),tt("month",8),Ot("M",vt),Ot("MM",vt,ft),Ot("MMM",function(t,e){return e.monthsShortRegex(t)}),Ot("MMMM",function(t,e){return e.monthsRegex(t)}),Rt(["M","MM"],function(t,e){e[zt]=D(t)-1}),Rt(["MMM","MMMM"],function(t,e,n,i){var a=n._locale.monthsParse(t,i,n._strict);null!=a?e[zt]=a:v(n).invalidMonth=t});var re=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,oe="January_February_March_April_May_June_July_August_September_October_November_December".split("_");function se(t,e){return t?o(this._months)?this._months[t.month()]:this._months[(this._months.isFormat||re).test(e)?"format":"standalone"][t.month()]:o(this._months)?this._months:this._months.standalone}var le="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_");function ue(t,e){return t?o(this._monthsShort)?this._monthsShort[t.month()]:this._monthsShort[re.test(e)?"format":"standalone"][t.month()]:o(this._monthsShort)?this._monthsShort:this._monthsShort.standalone}function de(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],i=0;i<12;++i)r=m([2e3,i]),this._shortMonthsParse[i]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[i]=this.months(r,"").toLocaleLowerCase();return n?"MMM"===e?-1!==(a=$t.call(this._shortMonthsParse,o))?a:null:-1!==(a=$t.call(this._longMonthsParse,o))?a:null:"MMM"===e?-1!==(a=$t.call(this._shortMonthsParse,o))||-1!==(a=$t.call(this._longMonthsParse,o))?a:null:-1!==(a=$t.call(this._longMonthsParse,o))||-1!==(a=$t.call(this._shortMonthsParse,o))?a:null}function he(t,e,n){var i,a,r;if(this._monthsParseExact)return de.call(this,t,e,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),i=0;i<12;i++){if(a=m([2e3,i]),n&&!this._longMonthsParse[i]&&(this._longMonthsParse[i]=new RegExp("^"+this.months(a,"").replace(".","")+"$","i"),this._shortMonthsParse[i]=new RegExp("^"+this.monthsShort(a,"").replace(".","")+"$","i")),n||this._monthsParse[i]||(r="^"+this.months(a,"")+"|^"+this.monthsShort(a,""),this._monthsParse[i]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===e&&this._longMonthsParse[i].test(t))return i;if(n&&"MMM"===e&&this._shortMonthsParse[i].test(t))return i;if(!n&&this._monthsParse[i].test(t))return i}}function ce(t,e){var n;if(!t.isValid())return t;if("string"==typeof e)if(/^\d+$/.test(e))e=D(e);else if(!d(e=t.localeData().monthsParse(e)))return t;return n=Math.min(t.date(),ae(t.year(),e)),t._d["set"+(t._isUTC?"UTC":"")+"Month"](e,n),t}function fe(t){return null!=t?(ce(this,t),a.updateOffset(this,!0),this):Qt(this,"Month")}function ge(){return ae(this.year(),this.month())}var me=Pt;function pe(t){return this._monthsParseExact?(f(this,"_monthsRegex")||ye.call(this),t?this._monthsShortStrictRegex:this._monthsShortRegex):(f(this,"_monthsShortRegex")||(this._monthsShortRegex=me),this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex)}var ve=Pt;function be(t){return this._monthsParseExact?(f(this,"_monthsRegex")||ye.call(this),t?this._monthsStrictRegex:this._monthsRegex):(f(this,"_monthsRegex")||(this._monthsRegex=ve),this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex)}function ye(){function t(t,e){return e.length-t.length}var e,n,i=[],a=[],r=[];for(e=0;e<12;e++)n=m([2e3,e]),i.push(this.monthsShort(n,"")),a.push(this.months(n,"")),r.push(this.months(n,"")),r.push(this.monthsShort(n,""));for(i.sort(t),a.sort(t),r.sort(t),e=0;e<12;e++)i[e]=It(i[e]),a[e]=It(a[e]);for(e=0;e<24;e++)r[e]=It(r[e]);this._monthsRegex=new RegExp("^("+r.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+i.join("|")+")","i")}function xe(t,e,n,i,a,r,o){var s;return t<100&&t>=0?(s=new Date(t+400,e,n,i,a,r,o),isFinite(s.getFullYear())&&s.setFullYear(t)):s=new Date(t,e,n,i,a,r,o),s}function _e(t){var e;if(t<100&&t>=0){var n=Array.prototype.slice.call(arguments);n[0]=t+400,e=new Date(Date.UTC.apply(null,n)),isFinite(e.getUTCFullYear())&&e.setUTCFullYear(t)}else e=new Date(Date.UTC.apply(null,arguments));return e}function we(t,e,n){var i=7+e-n;return-(7+_e(t,0,i).getUTCDay()-e)%7+i-1}function ke(t,e,n,i,a){var r,o,s=1+7*(e-1)+(7+n-i)%7+we(t,i,a);return s<=0?o=qt(r=t-1)+s:s>qt(t)?(r=t+1,o=s-qt(t)):(r=t,o=s),{year:r,dayOfYear:o}}function Me(t,e,n){var i,a,r=we(t.year(),e,n),o=Math.floor((t.dayOfYear()-r-1)/7)+1;return o<1?i=o+Se(a=t.year()-1,e,n):o>Se(t.year(),e,n)?(i=o-Se(t.year(),e,n),a=t.year()+1):(a=t.year(),i=o),{week:i,year:a}}function Se(t,e,n){var i=we(t,e,n),a=we(t+1,e,n);return(qt(t)-i+a)/7}function De(t){return Me(t,this._week.dow,this._week.doy).week}st("w",["ww",2],"wo","week"),st("W",["WW",2],"Wo","isoWeek"),X("week","w"),X("isoWeek","W"),tt("week",5),tt("isoWeek",5),Ot("w",vt),Ot("ww",vt,ft),Ot("W",vt),Ot("WW",vt,ft),Nt(["w","ww","W","WW"],function(t,e,n,i){e[i.substr(0,1)]=D(t)});var Ce={dow:0,doy:6};function Pe(){return this._week.dow}function Te(){return this._week.doy}function Oe(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")}function Ae(t){var e=Me(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")}function Fe(t,e){return"string"!=typeof t?t:isNaN(t)?"number"==typeof(t=e.weekdaysParse(t))?t:null:parseInt(t,10)}function Ie(t,e){return"string"==typeof t?e.weekdaysParse(t)%7||7:isNaN(t)?null:t}function Le(t,e){return t.slice(e,7).concat(t.slice(0,e))}st("d",0,"do","day"),st("dd",0,0,function(t){return this.localeData().weekdaysMin(this,t)}),st("ddd",0,0,function(t){return this.localeData().weekdaysShort(this,t)}),st("dddd",0,0,function(t){return this.localeData().weekdays(this,t)}),st("e",0,0,"weekday"),st("E",0,0,"isoWeekday"),X("day","d"),X("weekday","e"),X("isoWeekday","E"),tt("day",11),tt("weekday",11),tt("isoWeekday",11),Ot("d",vt),Ot("e",vt),Ot("E",vt),Ot("dd",function(t,e){return e.weekdaysMinRegex(t)}),Ot("ddd",function(t,e){return e.weekdaysShortRegex(t)}),Ot("dddd",function(t,e){return e.weekdaysRegex(t)}),Nt(["dd","ddd","dddd"],function(t,e,n,i){var a=n._locale.weekdaysParse(t,i,n._strict);null!=a?e.d=a:v(n).invalidWeekday=t}),Nt(["d","e","E"],function(t,e,n,i){e[i]=D(t)});var Re="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_");function Ne(t,e){var n=o(this._weekdays)?this._weekdays:this._weekdays[t&&!0!==t&&this._weekdays.isFormat.test(e)?"format":"standalone"];return!0===t?Le(n,this._week.dow):t?n[t.day()]:n}var We="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_");function Ye(t){return!0===t?Le(this._weekdaysShort,this._week.dow):t?this._weekdaysShort[t.day()]:this._weekdaysShort}var ze="Su_Mo_Tu_We_Th_Fr_Sa".split("_");function Ee(t){return!0===t?Le(this._weekdaysMin,this._week.dow):t?this._weekdaysMin[t.day()]:this._weekdaysMin}function Ve(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],i=0;i<7;++i)r=m([2e3,1]).day(i),this._minWeekdaysParse[i]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[i]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[i]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===e?-1!==(a=$t.call(this._weekdaysParse,o))?a:null:"ddd"===e?-1!==(a=$t.call(this._shortWeekdaysParse,o))?a:null:-1!==(a=$t.call(this._minWeekdaysParse,o))?a:null:"dddd"===e?-1!==(a=$t.call(this._weekdaysParse,o))||-1!==(a=$t.call(this._shortWeekdaysParse,o))||-1!==(a=$t.call(this._minWeekdaysParse,o))?a:null:"ddd"===e?-1!==(a=$t.call(this._shortWeekdaysParse,o))||-1!==(a=$t.call(this._weekdaysParse,o))||-1!==(a=$t.call(this._minWeekdaysParse,o))?a:null:-1!==(a=$t.call(this._minWeekdaysParse,o))||-1!==(a=$t.call(this._weekdaysParse,o))||-1!==(a=$t.call(this._shortWeekdaysParse,o))?a:null}function He(t,e,n){var i,a,r;if(this._weekdaysParseExact)return Ve.call(this,t,e,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),i=0;i<7;i++){if(a=m([2e3,1]).day(i),n&&!this._fullWeekdaysParse[i]&&(this._fullWeekdaysParse[i]=new RegExp("^"+this.weekdays(a,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[i]=new RegExp("^"+this.weekdaysShort(a,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[i]=new RegExp("^"+this.weekdaysMin(a,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[i]||(r="^"+this.weekdays(a,"")+"|^"+this.weekdaysShort(a,"")+"|^"+this.weekdaysMin(a,""),this._weekdaysParse[i]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===e&&this._fullWeekdaysParse[i].test(t))return i;if(n&&"ddd"===e&&this._shortWeekdaysParse[i].test(t))return i;if(n&&"dd"===e&&this._minWeekdaysParse[i].test(t))return i;if(!n&&this._weekdaysParse[i].test(t))return i}}function Be(t){if(!this.isValid())return null!=t?this:NaN;var e=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=t?(t=Fe(t,this.localeData()),this.add(t-e,"d")):e}function je(t){if(!this.isValid())return null!=t?this:NaN;var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")}function Ue(t){if(!this.isValid())return null!=t?this:NaN;if(null!=t){var e=Ie(t,this.localeData());return this.day(this.day()%7?e:e-7)}return this.day()||7}var Ge=Pt;function qe(t){return this._weekdaysParseExact?(f(this,"_weekdaysRegex")||Je.call(this),t?this._weekdaysStrictRegex:this._weekdaysRegex):(f(this,"_weekdaysRegex")||(this._weekdaysRegex=Ge),this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex)}var Ze=Pt;function $e(t){return this._weekdaysParseExact?(f(this,"_weekdaysRegex")||Je.call(this),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(f(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Ze),this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}var Xe=Pt;function Ke(t){return this._weekdaysParseExact?(f(this,"_weekdaysRegex")||Je.call(this),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(f(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Xe),this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function Je(){function t(t,e){return e.length-t.length}var e,n,i,a,r,o=[],s=[],l=[],u=[];for(e=0;e<7;e++)n=m([2e3,1]).day(e),i=this.weekdaysMin(n,""),a=this.weekdaysShort(n,""),r=this.weekdays(n,""),o.push(i),s.push(a),l.push(r),u.push(i),u.push(a),u.push(r);for(o.sort(t),s.sort(t),l.sort(t),u.sort(t),e=0;e<7;e++)s[e]=It(s[e]),l[e]=It(l[e]),u[e]=It(u[e]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Qe(){return this.hours()%12||12}function tn(){return this.hours()||24}function en(t,e){st(t,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)})}function nn(t,e){return e._meridiemParse}function an(t){return"p"===(t+"").toLowerCase().charAt(0)}st("H",["HH",2],0,"hour"),st("h",["hh",2],0,Qe),st("k",["kk",2],0,tn),st("hmm",0,0,function(){return""+Qe.apply(this)+nt(this.minutes(),2)}),st("hmmss",0,0,function(){return""+Qe.apply(this)+nt(this.minutes(),2)+nt(this.seconds(),2)}),st("Hmm",0,0,function(){return""+this.hours()+nt(this.minutes(),2)}),st("Hmmss",0,0,function(){return""+this.hours()+nt(this.minutes(),2)+nt(this.seconds(),2)}),en("a",!0),en("A",!1),X("hour","h"),tt("hour",13),Ot("a",nn),Ot("A",nn),Ot("H",vt),Ot("h",vt),Ot("k",vt),Ot("HH",vt,ft),Ot("hh",vt,ft),Ot("kk",vt,ft),Ot("hmm",bt),Ot("hmmss",yt),Ot("Hmm",bt),Ot("Hmmss",yt),Rt(["H","HH"],Vt),Rt(["k","kk"],function(t,e,n){var i=D(t);e[Vt]=24===i?0:i}),Rt(["a","A"],function(t,e,n){n._isPm=n._locale.isPM(t),n._meridiem=t}),Rt(["h","hh"],function(t,e,n){e[Vt]=D(t),v(n).bigHour=!0}),Rt("hmm",function(t,e,n){var i=t.length-2;e[Vt]=D(t.substr(0,i)),e[Ht]=D(t.substr(i)),v(n).bigHour=!0}),Rt("hmmss",function(t,e,n){var i=t.length-4,a=t.length-2;e[Vt]=D(t.substr(0,i)),e[Ht]=D(t.substr(i,2)),e[Bt]=D(t.substr(a)),v(n).bigHour=!0}),Rt("Hmm",function(t,e,n){var i=t.length-2;e[Vt]=D(t.substr(0,i)),e[Ht]=D(t.substr(i))}),Rt("Hmmss",function(t,e,n){var i=t.length-4,a=t.length-2;e[Vt]=D(t.substr(0,i)),e[Ht]=D(t.substr(i,2)),e[Bt]=D(t.substr(a))});var rn=/[ap]\.?m?\.?/i;function on(t,e,n){return t>11?n?"pm":"PM":n?"am":"AM"}var sn,ln=Jt("Hours",!0),un={calendar:W,longDateFormat:z,invalidDate:V,ordinal:B,dayOfMonthOrdinalParse:j,relativeTime:G,months:oe,monthsShort:le,week:Ce,weekdays:Re,weekdaysMin:ze,weekdaysShort:We,meridiemParse:rn},dn={},hn={};function cn(t){return t?t.toLowerCase().replace("_","-"):t}function fn(t){for(var e,n,i,a,r=0;r<t.length;){for(e=(a=cn(t[r]).split("-")).length,n=(n=cn(t[r+1]))?n.split("-"):null;e>0;){if(i=gn(a.slice(0,e).join("-")))return i;if(n&&n.length>=e&&C(a,n,!0)>=e-1)break;e--}r++}return sn}function gn(n){var i=null;if(!dn[n]&&e&&e.exports)try{i=sn._abbr,t(),mn(i)}catch(t){}return dn[n]}function mn(t,e){var n;return t&&((n=u(e)?bn(t):pn(t,e))?sn=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+t+" not found. Did you forget to load it?")),sn._abbr}function pn(t,e){if(null!==e){var n,i=un;if(e.abbr=t,null!=dn[t])F("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=dn[t]._config;else if(null!=e.parentLocale)if(null!=dn[e.parentLocale])i=dn[e.parentLocale]._config;else{if(null==(n=gn(e.parentLocale)))return hn[e.parentLocale]||(hn[e.parentLocale]=[]),hn[e.parentLocale].push({name:t,config:e}),null;i=n._config}return dn[t]=new N(R(i,e)),hn[t]&&hn[t].forEach(function(t){pn(t.name,t.config)}),mn(t),dn[t]}return delete dn[t],null}function vn(t,e){if(null!=e){var n,i,a=un;null!=(i=gn(t))&&(a=i._config),(n=new N(e=R(a,e))).parentLocale=dn[t],dn[t]=n,mn(t)}else null!=dn[t]&&(null!=dn[t].parentLocale?dn[t]=dn[t].parentLocale:null!=dn[t]&&delete dn[t]);return dn[t]}function bn(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return sn;if(!o(t)){if(e=gn(t))return e;t=[t]}return fn(t)}function yn(){return O(dn)}function xn(t){var e,n=t._a;return n&&-2===v(t).overflow&&(e=n[zt]<0||n[zt]>11?zt:n[Et]<1||n[Et]>ae(n[Yt],n[zt])?Et:n[Vt]<0||n[Vt]>24||24===n[Vt]&&(0!==n[Ht]||0!==n[Bt]||0!==n[jt])?Vt:n[Ht]<0||n[Ht]>59?Ht:n[Bt]<0||n[Bt]>59?Bt:n[jt]<0||n[jt]>999?jt:-1,v(t)._overflowDayOfYear&&(e<Yt||e>Et)&&(e=Et),v(t)._overflowWeeks&&-1===e&&(e=Ut),v(t)._overflowWeekday&&-1===e&&(e=Gt),v(t).overflow=e),t}function _n(t,e,n){return null!=t?t:null!=e?e:n}function wn(t){var e=new Date(a.now());return t._useUTC?[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()]:[e.getFullYear(),e.getMonth(),e.getDate()]}function kn(t){var e,n,i,a,r,o=[];if(!t._d){for(i=wn(t),t._w&&null==t._a[Et]&&null==t._a[zt]&&Mn(t),null!=t._dayOfYear&&(r=_n(t._a[Yt],i[Yt]),(t._dayOfYear>qt(r)||0===t._dayOfYear)&&(v(t)._overflowDayOfYear=!0),n=_e(r,0,t._dayOfYear),t._a[zt]=n.getUTCMonth(),t._a[Et]=n.getUTCDate()),e=0;e<3&&null==t._a[e];++e)t._a[e]=o[e]=i[e];for(;e<7;e++)t._a[e]=o[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[Vt]&&0===t._a[Ht]&&0===t._a[Bt]&&0===t._a[jt]&&(t._nextDay=!0,t._a[Vt]=0),t._d=(t._useUTC?_e:xe).apply(null,o),a=t._useUTC?t._d.getUTCDay():t._d.getDay(),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[Vt]=24),t._w&&void 0!==t._w.d&&t._w.d!==a&&(v(t).weekdayMismatch=!0)}}function Mn(t){var e,n,i,a,r,o,s,l;if(null!=(e=t._w).GG||null!=e.W||null!=e.E)r=1,o=4,n=_n(e.GG,t._a[Yt],Me($n(),1,4).year),i=_n(e.W,1),((a=_n(e.E,1))<1||a>7)&&(l=!0);else{r=t._locale._week.dow,o=t._locale._week.doy;var u=Me($n(),r,o);n=_n(e.gg,t._a[Yt],u.year),i=_n(e.w,u.week),null!=e.d?((a=e.d)<0||a>6)&&(l=!0):null!=e.e?(a=e.e+r,(e.e<0||e.e>6)&&(l=!0)):a=r}i<1||i>Se(n,r,o)?v(t)._overflowWeeks=!0:null!=l?v(t)._overflowWeekday=!0:(s=ke(n,i,a,r,o),t._a[Yt]=s.year,t._dayOfYear=s.dayOfYear)}var Sn=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Dn=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Cn=/Z|[+-]\d\d(?::?\d\d)?/,Pn=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Tn=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],On=/^\/?Date\((\-?\d+)/i;function An(t){var e,n,i,a,r,o,s=t._i,l=Sn.exec(s)||Dn.exec(s);if(l){for(v(t).iso=!0,e=0,n=Pn.length;e<n;e++)if(Pn[e][1].exec(l[1])){a=Pn[e][0],i=!1!==Pn[e][2];break}if(null==a)return void(t._isValid=!1);if(l[3]){for(e=0,n=Tn.length;e<n;e++)if(Tn[e][1].exec(l[3])){r=(l[2]||" ")+Tn[e][0];break}if(null==r)return void(t._isValid=!1)}if(!i&&null!=r)return void(t._isValid=!1);if(l[4]){if(!Cn.exec(l[4]))return void(t._isValid=!1);o="Z"}t._f=a+(r||"")+(o||""),Vn(t)}else t._isValid=!1}var Fn=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;function In(t,e,n,i,a,r){var o=[Ln(t),le.indexOf(e),parseInt(n,10),parseInt(i,10),parseInt(a,10)];return r&&o.push(parseInt(r,10)),o}function Ln(t){var e=parseInt(t,10);return e<=49?2e3+e:e<=999?1900+e:e}function Rn(t){return t.replace(/\([^)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").replace(/^\s\s*/,"").replace(/\s\s*$/,"")}function Nn(t,e,n){return!t||We.indexOf(t)===new Date(e[0],e[1],e[2]).getDay()||(v(n).weekdayMismatch=!0,n._isValid=!1,!1)}var Wn={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function Yn(t,e,n){if(t)return Wn[t];if(e)return 0;var i=parseInt(n,10),a=i%100;return(i-a)/100*60+a}function zn(t){var e=Fn.exec(Rn(t._i));if(e){var n=In(e[4],e[3],e[2],e[5],e[6],e[7]);if(!Nn(e[1],n,t))return;t._a=n,t._tzm=Yn(e[8],e[9],e[10]),t._d=_e.apply(null,t._a),t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),v(t).rfc2822=!0}else t._isValid=!1}function En(t){var e=On.exec(t._i);null===e?(An(t),!1===t._isValid&&(delete t._isValid,zn(t),!1===t._isValid&&(delete t._isValid,a.createFromInputFallback(t)))):t._d=new Date(+e[1])}function Vn(t){if(t._f!==a.ISO_8601)if(t._f!==a.RFC_2822){t._a=[],v(t).empty=!0;var e,n,i,r,o,s=""+t._i,l=s.length,u=0;for(i=ht(t._f,t._locale).match(it)||[],e=0;e<i.length;e++)r=i[e],(n=(s.match(At(r,t))||[])[0])&&((o=s.substr(0,s.indexOf(n))).length>0&&v(t).unusedInput.push(o),s=s.slice(s.indexOf(n)+n.length),u+=n.length),ot[r]?(n?v(t).empty=!1:v(t).unusedTokens.push(r),Wt(r,n,t)):t._strict&&!n&&v(t).unusedTokens.push(r);v(t).charsLeftOver=l-u,s.length>0&&v(t).unusedInput.push(s),t._a[Vt]<=12&&!0===v(t).bigHour&&t._a[Vt]>0&&(v(t).bigHour=void 0),v(t).parsedDateParts=t._a.slice(0),v(t).meridiem=t._meridiem,t._a[Vt]=Hn(t._locale,t._a[Vt],t._meridiem),kn(t),xn(t)}else zn(t);else An(t)}function Hn(t,e,n){var i;return null==n?e:null!=t.meridiemHour?t.meridiemHour(e,n):null!=t.isPM?((i=t.isPM(n))&&e<12&&(e+=12),i||12!==e||(e=0),e):e}function Bn(t){var e,n,i,a,r;if(0===t._f.length)return v(t).invalidFormat=!0,void(t._d=new Date(NaN));for(a=0;a<t._f.length;a++)r=0,e=_({},t),null!=t._useUTC&&(e._useUTC=t._useUTC),e._f=t._f[a],Vn(e),b(e)&&(r+=v(e).charsLeftOver,r+=10*v(e).unusedTokens.length,v(e).score=r,(null==i||r<i)&&(i=r,n=e));g(t,n||e)}function jn(t){if(!t._d){var e=J(t._i);t._a=c([e.year,e.month,e.day||e.date,e.hour,e.minute,e.second,e.millisecond],function(t){return t&&parseInt(t,10)}),kn(t)}}function Un(t){var e=new k(xn(Gn(t)));return e._nextDay&&(e.add(1,"d"),e._nextDay=void 0),e}function Gn(t){var e=t._i,n=t._f;return t._locale=t._locale||bn(t._l),null===e||void 0===n&&""===e?y({nullInput:!0}):("string"==typeof e&&(t._i=e=t._locale.preparse(e)),M(e)?new k(xn(e)):(h(e)?t._d=e:o(n)?Bn(t):n?Vn(t):qn(t),b(t)||(t._d=null),t))}function qn(t){var e=t._i;u(e)?t._d=new Date(a.now()):h(e)?t._d=new Date(e.valueOf()):"string"==typeof e?En(t):o(e)?(t._a=c(e.slice(0),function(t){return parseInt(t,10)}),kn(t)):s(e)?jn(t):d(e)?t._d=new Date(e):a.createFromInputFallback(t)}function Zn(t,e,n,i,a){var r={};return!0!==n&&!1!==n||(i=n,n=void 0),(s(t)&&l(t)||o(t)&&0===t.length)&&(t=void 0),r._isAMomentObject=!0,r._useUTC=r._isUTC=a,r._l=n,r._i=t,r._f=e,r._strict=i,Un(r)}function $n(t,e,n,i){return Zn(t,e,n,i,!1)}a.createFromInputFallback=T("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(t){t._d=new Date(t._i+(t._useUTC?" UTC":""))}),a.ISO_8601=function(){},a.RFC_2822=function(){};var Xn=T("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var t=$n.apply(null,arguments);return this.isValid()&&t.isValid()?t<this?this:t:y()}),Kn=T("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var t=$n.apply(null,arguments);return this.isValid()&&t.isValid()?t>this?this:t:y()});function Jn(t,e){var n,i;if(1===e.length&&o(e[0])&&(e=e[0]),!e.length)return $n();for(n=e[0],i=1;i<e.length;++i)e[i].isValid()&&!e[i][t](n)||(n=e[i]);return n}function Qn(){return Jn("isBefore",[].slice.call(arguments,0))}function ti(){return Jn("isAfter",[].slice.call(arguments,0))}var ei=function(){return Date.now?Date.now():+new Date},ni=["year","quarter","month","week","day","hour","minute","second","millisecond"];function ii(t){for(var e in t)if(-1===$t.call(ni,e)||null!=t[e]&&isNaN(t[e]))return!1;for(var n=!1,i=0;i<ni.length;++i)if(t[ni[i]]){if(n)return!1;parseFloat(t[ni[i]])!==D(t[ni[i]])&&(n=!0)}return!0}function ai(){return this._isValid}function ri(){return Ci(NaN)}function oi(t){var e=J(t),n=e.year||0,i=e.quarter||0,a=e.month||0,r=e.week||e.isoWeek||0,o=e.day||0,s=e.hour||0,l=e.minute||0,u=e.second||0,d=e.millisecond||0;this._isValid=ii(e),this._milliseconds=+d+1e3*u+6e4*l+1e3*s*60*60,this._days=+o+7*r,this._months=+a+3*i+12*n,this._data={},this._locale=bn(),this._bubble()}function si(t){return t instanceof oi}function li(t){return t<0?-1*Math.round(-1*t):Math.round(t)}function ui(t,e){st(t,0,0,function(){var t=this.utcOffset(),n="+";return t<0&&(t=-t,n="-"),n+nt(~~(t/60),2)+e+nt(~~t%60,2)})}ui("Z",":"),ui("ZZ",""),Ot("Z",Dt),Ot("ZZ",Dt),Rt(["Z","ZZ"],function(t,e,n){n._useUTC=!0,n._tzm=hi(Dt,t)});var di=/([\+\-]|\d\d)/gi;function hi(t,e){var n=(e||"").match(t);if(null===n)return null;var i=((n[n.length-1]||[])+"").match(di)||["-",0,0],a=60*i[1]+D(i[2]);return 0===a?0:"+"===i[0]?a:-a}function ci(t,e){var n,i;return e._isUTC?(n=e.clone(),i=(M(t)||h(t)?t.valueOf():$n(t).valueOf())-n.valueOf(),n._d.setTime(n._d.valueOf()+i),a.updateOffset(n,!1),n):$n(t).local()}function fi(t){return 15*-Math.round(t._d.getTimezoneOffset()/15)}function gi(t,e,n){var i,r=this._offset||0;if(!this.isValid())return null!=t?this:NaN;if(null!=t){if("string"==typeof t){if(null===(t=hi(Dt,t)))return this}else Math.abs(t)<16&&!n&&(t*=60);return!this._isUTC&&e&&(i=fi(this)),this._offset=t,this._isUTC=!0,null!=i&&this.add(i,"m"),r!==t&&(!e||this._changeInProgress?Fi(this,Ci(t-r,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?r:fi(this)}function mi(t,e){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,e),this):-this.utcOffset()}function pi(t){return this.utcOffset(0,t)}function vi(t){return this._isUTC&&(this.utcOffset(0,t),this._isUTC=!1,t&&this.subtract(fi(this),"m")),this}function bi(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var t=hi(St,this._i);null!=t?this.utcOffset(t):this.utcOffset(0,!0)}return this}function yi(t){return!!this.isValid()&&(t=t?$n(t).utcOffset():0,(this.utcOffset()-t)%60==0)}function xi(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function _i(){if(!u(this._isDSTShifted))return this._isDSTShifted;var t={};if(_(t,this),(t=Gn(t))._a){var e=t._isUTC?m(t._a):$n(t._a);this._isDSTShifted=this.isValid()&&C(t._a,e.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function wi(){return!!this.isValid()&&!this._isUTC}function ki(){return!!this.isValid()&&this._isUTC}function Mi(){return!!this.isValid()&&this._isUTC&&0===this._offset}a.updateOffset=function(){};var Si=/^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Di=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function Ci(t,e){var n,i,a,r=t,o=null;return si(t)?r={ms:t._milliseconds,d:t._days,M:t._months}:d(t)?(r={},e?r[e]=t:r.milliseconds=t):(o=Si.exec(t))?(n="-"===o[1]?-1:1,r={y:0,d:D(o[Et])*n,h:D(o[Vt])*n,m:D(o[Ht])*n,s:D(o[Bt])*n,ms:D(li(1e3*o[jt]))*n}):(o=Di.exec(t))?(n="-"===o[1]?-1:1,r={y:Pi(o[2],n),M:Pi(o[3],n),w:Pi(o[4],n),d:Pi(o[5],n),h:Pi(o[6],n),m:Pi(o[7],n),s:Pi(o[8],n)}):null==r?r={}:"object"==typeof r&&("from"in r||"to"in r)&&(a=Oi($n(r.from),$n(r.to)),(r={}).ms=a.milliseconds,r.M=a.months),i=new oi(r),si(t)&&f(t,"_locale")&&(i._locale=t._locale),i}function Pi(t,e){var n=t&&parseFloat(t.replace(",","."));return(isNaN(n)?0:n)*e}function Ti(t,e){var n={};return n.months=e.month()-t.month()+12*(e.year()-t.year()),t.clone().add(n.months,"M").isAfter(e)&&--n.months,n.milliseconds=+e-+t.clone().add(n.months,"M"),n}function Oi(t,e){var n;return t.isValid()&&e.isValid()?(e=ci(e,t),t.isBefore(e)?n=Ti(t,e):((n=Ti(e,t)).milliseconds=-n.milliseconds,n.months=-n.months),n):{milliseconds:0,months:0}}function Ai(t,e){return function(n,i){var a;return null===i||isNaN(+i)||(F(e,"moment()."+e+"(period, number) is deprecated. Please use moment()."+e+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),a=n,n=i,i=a),Fi(this,Ci(n="string"==typeof n?+n:n,i),t),this}}function Fi(t,e,n,i){var r=e._milliseconds,o=li(e._days),s=li(e._months);t.isValid()&&(i=null==i||i,s&&ce(t,Qt(t,"Month")+s*n),o&&te(t,"Date",Qt(t,"Date")+o*n),r&&t._d.setTime(t._d.valueOf()+r*n),i&&a.updateOffset(t,o||s))}Ci.fn=oi.prototype,Ci.invalid=ri;var Ii=Ai(1,"add"),Li=Ai(-1,"subtract");function Ri(t,e){var n=t.diff(e,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"}function Ni(t,e){var n=t||$n(),i=ci(n,this).startOf("day"),r=a.calendarFormat(this,i)||"sameElse",o=e&&(I(e[r])?e[r].call(this,n):e[r]);return this.format(o||this.localeData().calendar(r,this,$n(n)))}function Wi(){return new k(this)}function Yi(t,e){var n=M(t)?t:$n(t);return!(!this.isValid()||!n.isValid())&&("millisecond"===(e=K(e)||"millisecond")?this.valueOf()>n.valueOf():n.valueOf()<this.clone().startOf(e).valueOf())}function zi(t,e){var n=M(t)?t:$n(t);return!(!this.isValid()||!n.isValid())&&("millisecond"===(e=K(e)||"millisecond")?this.valueOf()<n.valueOf():this.clone().endOf(e).valueOf()<n.valueOf())}function Ei(t,e,n,i){var a=M(t)?t:$n(t),r=M(e)?e:$n(e);return!!(this.isValid()&&a.isValid()&&r.isValid())&&("("===(i=i||"()")[0]?this.isAfter(a,n):!this.isBefore(a,n))&&(")"===i[1]?this.isBefore(r,n):!this.isAfter(r,n))}function Vi(t,e){var n,i=M(t)?t:$n(t);return!(!this.isValid()||!i.isValid())&&("millisecond"===(e=K(e)||"millisecond")?this.valueOf()===i.valueOf():(n=i.valueOf(),this.clone().startOf(e).valueOf()<=n&&n<=this.clone().endOf(e).valueOf()))}function Hi(t,e){return this.isSame(t,e)||this.isAfter(t,e)}function Bi(t,e){return this.isSame(t,e)||this.isBefore(t,e)}function ji(t,e,n){var i,a,r;if(!this.isValid())return NaN;if(!(i=ci(t,this)).isValid())return NaN;switch(a=6e4*(i.utcOffset()-this.utcOffset()),e=K(e)){case"year":r=Ui(this,i)/12;break;case"month":r=Ui(this,i);break;case"quarter":r=Ui(this,i)/3;break;case"second":r=(this-i)/1e3;break;case"minute":r=(this-i)/6e4;break;case"hour":r=(this-i)/36e5;break;case"day":r=(this-i-a)/864e5;break;case"week":r=(this-i-a)/6048e5;break;default:r=this-i}return n?r:S(r)}function Ui(t,e){var n=12*(e.year()-t.year())+(e.month()-t.month()),i=t.clone().add(n,"months");return-(n+(e-i<0?(e-i)/(i-t.clone().add(n-1,"months")):(e-i)/(t.clone().add(n+1,"months")-i)))||0}function Gi(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function qi(t){if(!this.isValid())return null;var e=!0!==t,n=e?this.clone().utc():this;return n.year()<0||n.year()>9999?dt(n,e?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):I(Date.prototype.toISOString)?e?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",dt(n,"Z")):dt(n,e?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")}function Zi(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var t="moment",e="";this.isLocal()||(t=0===this.utcOffset()?"moment.utc":"moment.parseZone",e="Z");var n="["+t+'("]',i=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",a="-MM-DD[T]HH:mm:ss.SSS",r=e+'[")]';return this.format(n+i+a+r)}function $i(t){t||(t=this.isUtc()?a.defaultFormatUtc:a.defaultFormat);var e=dt(this,t);return this.localeData().postformat(e)}function Xi(t,e){return this.isValid()&&(M(t)&&t.isValid()||$n(t).isValid())?Ci({to:this,from:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()}function Ki(t){return this.from($n(),t)}function Ji(t,e){return this.isValid()&&(M(t)&&t.isValid()||$n(t).isValid())?Ci({from:this,to:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()}function Qi(t){return this.to($n(),t)}function ta(t){var e;return void 0===t?this._locale._abbr:(null!=(e=bn(t))&&(this._locale=e),this)}a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",a.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var ea=T("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(t){return void 0===t?this.localeData():this.locale(t)});function na(){return this._locale}var ia=1e3,aa=60*ia,ra=60*aa,oa=3506328*ra;function sa(t,e){return(t%e+e)%e}function la(t,e,n){return t<100&&t>=0?new Date(t+400,e,n)-oa:new Date(t,e,n).valueOf()}function ua(t,e,n){return t<100&&t>=0?Date.UTC(t+400,e,n)-oa:Date.UTC(t,e,n)}function da(t){var e;if(void 0===(t=K(t))||"millisecond"===t||!this.isValid())return this;var n=this._isUTC?ua:la;switch(t){case"year":e=n(this.year(),0,1);break;case"quarter":e=n(this.year(),this.month()-this.month()%3,1);break;case"month":e=n(this.year(),this.month(),1);break;case"week":e=n(this.year(),this.month(),this.date()-this.weekday());break;case"isoWeek":e=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1));break;case"day":case"date":e=n(this.year(),this.month(),this.date());break;case"hour":e=this._d.valueOf(),e-=sa(e+(this._isUTC?0:this.utcOffset()*aa),ra);break;case"minute":e=this._d.valueOf(),e-=sa(e,aa);break;case"second":e=this._d.valueOf(),e-=sa(e,ia)}return this._d.setTime(e),a.updateOffset(this,!0),this}function ha(t){var e;if(void 0===(t=K(t))||"millisecond"===t||!this.isValid())return this;var n=this._isUTC?ua:la;switch(t){case"year":e=n(this.year()+1,0,1)-1;break;case"quarter":e=n(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":e=n(this.year(),this.month()+1,1)-1;break;case"week":e=n(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":e=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":e=n(this.year(),this.month(),this.date()+1)-1;break;case"hour":e=this._d.valueOf(),e+=ra-sa(e+(this._isUTC?0:this.utcOffset()*aa),ra)-1;break;case"minute":e=this._d.valueOf(),e+=aa-sa(e,aa)-1;break;case"second":e=this._d.valueOf(),e+=ia-sa(e,ia)-1}return this._d.setTime(e),a.updateOffset(this,!0),this}function ca(){return this._d.valueOf()-6e4*(this._offset||0)}function fa(){return Math.floor(this.valueOf()/1e3)}function ga(){return new Date(this.valueOf())}function ma(){var t=this;return[t.year(),t.month(),t.date(),t.hour(),t.minute(),t.second(),t.millisecond()]}function pa(){var t=this;return{years:t.year(),months:t.month(),date:t.date(),hours:t.hours(),minutes:t.minutes(),seconds:t.seconds(),milliseconds:t.milliseconds()}}function va(){return this.isValid()?this.toISOString():null}function ba(){return b(this)}function ya(){return g({},v(this))}function xa(){return v(this).overflow}function _a(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function wa(t,e){st(0,[t,t.length],0,e)}function ka(t){return Ca.call(this,t,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)}function Ma(t){return Ca.call(this,t,this.isoWeek(),this.isoWeekday(),1,4)}function Sa(){return Se(this.year(),1,4)}function Da(){var t=this.localeData()._week;return Se(this.year(),t.dow,t.doy)}function Ca(t,e,n,i,a){var r;return null==t?Me(this,i,a).year:(e>(r=Se(t,i,a))&&(e=r),Pa.call(this,t,e,n,i,a))}function Pa(t,e,n,i,a){var r=ke(t,e,n,i,a),o=_e(r.year,0,r.dayOfYear);return this.year(o.getUTCFullYear()),this.month(o.getUTCMonth()),this.date(o.getUTCDate()),this}function Ta(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)}st(0,["gg",2],0,function(){return this.weekYear()%100}),st(0,["GG",2],0,function(){return this.isoWeekYear()%100}),wa("gggg","weekYear"),wa("ggggg","weekYear"),wa("GGGG","isoWeekYear"),wa("GGGGG","isoWeekYear"),X("weekYear","gg"),X("isoWeekYear","GG"),tt("weekYear",1),tt("isoWeekYear",1),Ot("G",Mt),Ot("g",Mt),Ot("GG",vt,ft),Ot("gg",vt,ft),Ot("GGGG",_t,mt),Ot("gggg",_t,mt),Ot("GGGGG",wt,pt),Ot("ggggg",wt,pt),Nt(["gggg","ggggg","GGGG","GGGGG"],function(t,e,n,i){e[i.substr(0,2)]=D(t)}),Nt(["gg","GG"],function(t,e,n,i){e[i]=a.parseTwoDigitYear(t)}),st("Q",0,"Qo","quarter"),X("quarter","Q"),tt("quarter",7),Ot("Q",ct),Rt("Q",function(t,e){e[zt]=3*(D(t)-1)}),st("D",["DD",2],"Do","date"),X("date","D"),tt("date",9),Ot("D",vt),Ot("DD",vt,ft),Ot("Do",function(t,e){return t?e._dayOfMonthOrdinalParse||e._ordinalParse:e._dayOfMonthOrdinalParseLenient}),Rt(["D","DD"],Et),Rt("Do",function(t,e){e[Et]=D(t.match(vt)[0])});var Oa=Jt("Date",!0);function Aa(t){var e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")}st("DDD",["DDDD",3],"DDDo","dayOfYear"),X("dayOfYear","DDD"),tt("dayOfYear",4),Ot("DDD",xt),Ot("DDDD",gt),Rt(["DDD","DDDD"],function(t,e,n){n._dayOfYear=D(t)}),st("m",["mm",2],0,"minute"),X("minute","m"),tt("minute",14),Ot("m",vt),Ot("mm",vt,ft),Rt(["m","mm"],Ht);var Fa=Jt("Minutes",!1);st("s",["ss",2],0,"second"),X("second","s"),tt("second",15),Ot("s",vt),Ot("ss",vt,ft),Rt(["s","ss"],Bt);var Ia,La=Jt("Seconds",!1);for(st("S",0,0,function(){return~~(this.millisecond()/100)}),st(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),st(0,["SSS",3],0,"millisecond"),st(0,["SSSS",4],0,function(){return 10*this.millisecond()}),st(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),st(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),st(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),st(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),st(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),X("millisecond","ms"),tt("millisecond",16),Ot("S",xt,ct),Ot("SS",xt,ft),Ot("SSS",xt,gt),Ia="SSSS";Ia.length<=9;Ia+="S")Ot(Ia,kt);function Ra(t,e){e[jt]=D(1e3*("0."+t))}for(Ia="S";Ia.length<=9;Ia+="S")Rt(Ia,Ra);var Na=Jt("Milliseconds",!1);function Wa(){return this._isUTC?"UTC":""}function Ya(){return this._isUTC?"Coordinated Universal Time":""}st("z",0,0,"zoneAbbr"),st("zz",0,0,"zoneName");var za=k.prototype;function Ea(t){return $n(1e3*t)}function Va(){return $n.apply(null,arguments).parseZone()}function Ha(t){return t}za.add=Ii,za.calendar=Ni,za.clone=Wi,za.diff=ji,za.endOf=ha,za.format=$i,za.from=Xi,za.fromNow=Ki,za.to=Ji,za.toNow=Qi,za.get=ee,za.invalidAt=xa,za.isAfter=Yi,za.isBefore=zi,za.isBetween=Ei,za.isSame=Vi,za.isSameOrAfter=Hi,za.isSameOrBefore=Bi,za.isValid=ba,za.lang=ea,za.locale=ta,za.localeData=na,za.max=Kn,za.min=Xn,za.parsingFlags=ya,za.set=ne,za.startOf=da,za.subtract=Li,za.toArray=ma,za.toObject=pa,za.toDate=ga,za.toISOString=qi,za.inspect=Zi,za.toJSON=va,za.toString=Gi,za.unix=fa,za.valueOf=ca,za.creationData=_a,za.year=Xt,za.isLeapYear=Kt,za.weekYear=ka,za.isoWeekYear=Ma,za.quarter=za.quarters=Ta,za.month=fe,za.daysInMonth=ge,za.week=za.weeks=Oe,za.isoWeek=za.isoWeeks=Ae,za.weeksInYear=Da,za.isoWeeksInYear=Sa,za.date=Oa,za.day=za.days=Be,za.weekday=je,za.isoWeekday=Ue,za.dayOfYear=Aa,za.hour=za.hours=ln,za.minute=za.minutes=Fa,za.second=za.seconds=La,za.millisecond=za.milliseconds=Na,za.utcOffset=gi,za.utc=pi,za.local=vi,za.parseZone=bi,za.hasAlignedHourOffset=yi,za.isDST=xi,za.isLocal=wi,za.isUtcOffset=ki,za.isUtc=Mi,za.isUTC=Mi,za.zoneAbbr=Wa,za.zoneName=Ya,za.dates=T("dates accessor is deprecated. Use date instead.",Oa),za.months=T("months accessor is deprecated. Use month instead",fe),za.years=T("years accessor is deprecated. Use year instead",Xt),za.zone=T("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",mi),za.isDSTShifted=T("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",_i);var Ba=N.prototype;function ja(t,e,n,i){var a=bn(),r=m().set(i,e);return a[n](r,t)}function Ua(t,e,n){if(d(t)&&(e=t,t=void 0),t=t||"",null!=e)return ja(t,e,n,"month");var i,a=[];for(i=0;i<12;i++)a[i]=ja(t,i,n,"month");return a}function Ga(t,e,n,i){"boolean"==typeof t?(d(e)&&(n=e,e=void 0),e=e||""):(n=e=t,t=!1,d(e)&&(n=e,e=void 0),e=e||"");var a,r=bn(),o=t?r._week.dow:0;if(null!=n)return ja(e,(n+o)%7,i,"day");var s=[];for(a=0;a<7;a++)s[a]=ja(e,(a+o)%7,i,"day");return s}function qa(t,e){return Ua(t,e,"months")}function Za(t,e){return Ua(t,e,"monthsShort")}function $a(t,e,n){return Ga(t,e,n,"weekdays")}function Xa(t,e,n){return Ga(t,e,n,"weekdaysShort")}function Ka(t,e,n){return Ga(t,e,n,"weekdaysMin")}Ba.calendar=Y,Ba.longDateFormat=E,Ba.invalidDate=H,Ba.ordinal=U,Ba.preparse=Ha,Ba.postformat=Ha,Ba.relativeTime=q,Ba.pastFuture=Z,Ba.set=L,Ba.months=se,Ba.monthsShort=ue,Ba.monthsParse=he,Ba.monthsRegex=be,Ba.monthsShortRegex=pe,Ba.week=De,Ba.firstDayOfYear=Te,Ba.firstDayOfWeek=Pe,Ba.weekdays=Ne,Ba.weekdaysMin=Ee,Ba.weekdaysShort=Ye,Ba.weekdaysParse=He,Ba.weekdaysRegex=qe,Ba.weekdaysShortRegex=$e,Ba.weekdaysMinRegex=Ke,Ba.isPM=an,Ba.meridiem=on,mn("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10;return t+(1===D(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")}}),a.lang=T("moment.lang is deprecated. Use moment.locale instead.",mn),a.langData=T("moment.langData is deprecated. Use moment.localeData instead.",bn);var Ja=Math.abs;function Qa(){var t=this._data;return this._milliseconds=Ja(this._milliseconds),this._days=Ja(this._days),this._months=Ja(this._months),t.milliseconds=Ja(t.milliseconds),t.seconds=Ja(t.seconds),t.minutes=Ja(t.minutes),t.hours=Ja(t.hours),t.months=Ja(t.months),t.years=Ja(t.years),this}function tr(t,e,n,i){var a=Ci(e,n);return t._milliseconds+=i*a._milliseconds,t._days+=i*a._days,t._months+=i*a._months,t._bubble()}function er(t,e){return tr(this,t,e,1)}function nr(t,e){return tr(this,t,e,-1)}function ir(t){return t<0?Math.floor(t):Math.ceil(t)}function ar(){var t,e,n,i,a,r=this._milliseconds,o=this._days,s=this._months,l=this._data;return r>=0&&o>=0&&s>=0||r<=0&&o<=0&&s<=0||(r+=864e5*ir(or(s)+o),o=0,s=0),l.milliseconds=r%1e3,t=S(r/1e3),l.seconds=t%60,e=S(t/60),l.minutes=e%60,n=S(e/60),l.hours=n%24,o+=S(n/24),s+=a=S(rr(o)),o-=ir(or(a)),i=S(s/12),s%=12,l.days=o,l.months=s,l.years=i,this}function rr(t){return 4800*t/146097}function or(t){return 146097*t/4800}function sr(t){if(!this.isValid())return NaN;var e,n,i=this._milliseconds;if("month"===(t=K(t))||"quarter"===t||"year"===t)switch(e=this._days+i/864e5,n=this._months+rr(e),t){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(e=this._days+Math.round(or(this._months)),t){case"week":return e/7+i/6048e5;case"day":return e+i/864e5;case"hour":return 24*e+i/36e5;case"minute":return 1440*e+i/6e4;case"second":return 86400*e+i/1e3;case"millisecond":return Math.floor(864e5*e)+i;default:throw new Error("Unknown unit "+t)}}function lr(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*D(this._months/12):NaN}function ur(t){return function(){return this.as(t)}}var dr=ur("ms"),hr=ur("s"),cr=ur("m"),fr=ur("h"),gr=ur("d"),mr=ur("w"),pr=ur("M"),vr=ur("Q"),br=ur("y");function yr(){return Ci(this)}function xr(t){return t=K(t),this.isValid()?this[t+"s"]():NaN}function _r(t){return function(){return this.isValid()?this._data[t]:NaN}}var wr=_r("milliseconds"),kr=_r("seconds"),Mr=_r("minutes"),Sr=_r("hours"),Dr=_r("days"),Cr=_r("months"),Pr=_r("years");function Tr(){return S(this.days()/7)}var Or=Math.round,Ar={ss:44,s:45,m:45,h:22,d:26,M:11};function Fr(t,e,n,i,a){return a.relativeTime(e||1,!!n,t,i)}function Ir(t,e,n){var i=Ci(t).abs(),a=Or(i.as("s")),r=Or(i.as("m")),o=Or(i.as("h")),s=Or(i.as("d")),l=Or(i.as("M")),u=Or(i.as("y")),d=a<=Ar.ss&&["s",a]||a<Ar.s&&["ss",a]||r<=1&&["m"]||r<Ar.m&&["mm",r]||o<=1&&["h"]||o<Ar.h&&["hh",o]||s<=1&&["d"]||s<Ar.d&&["dd",s]||l<=1&&["M"]||l<Ar.M&&["MM",l]||u<=1&&["y"]||["yy",u];return d[2]=e,d[3]=+t>0,d[4]=n,Fr.apply(null,d)}function Lr(t){return void 0===t?Or:"function"==typeof t&&(Or=t,!0)}function Rr(t,e){return void 0!==Ar[t]&&(void 0===e?Ar[t]:(Ar[t]=e,"s"===t&&(Ar.ss=e-1),!0))}function Nr(t){if(!this.isValid())return this.localeData().invalidDate();var e=this.localeData(),n=Ir(this,!t,e);return t&&(n=e.pastFuture(+this,n)),e.postformat(n)}var Wr=Math.abs;function Yr(t){return(t>0)-(t<0)||+t}function zr(){if(!this.isValid())return this.localeData().invalidDate();var t,e,n=Wr(this._milliseconds)/1e3,i=Wr(this._days),a=Wr(this._months);t=S(n/60),e=S(t/60),n%=60,t%=60;var r=S(a/12),o=a%=12,s=i,l=e,u=t,d=n?n.toFixed(3).replace(/\.?0+$/,""):"",h=this.asSeconds();if(!h)return"P0D";var c=h<0?"-":"",f=Yr(this._months)!==Yr(h)?"-":"",g=Yr(this._days)!==Yr(h)?"-":"",m=Yr(this._milliseconds)!==Yr(h)?"-":"";return c+"P"+(r?f+r+"Y":"")+(o?f+o+"M":"")+(s?g+s+"D":"")+(l||u||d?"T":"")+(l?m+l+"H":"")+(u?m+u+"M":"")+(d?m+d+"S":"")}var Er=oi.prototype;return Er.isValid=ai,Er.abs=Qa,Er.add=er,Er.subtract=nr,Er.as=sr,Er.asMilliseconds=dr,Er.asSeconds=hr,Er.asMinutes=cr,Er.asHours=fr,Er.asDays=gr,Er.asWeeks=mr,Er.asMonths=pr,Er.asQuarters=vr,Er.asYears=br,Er.valueOf=lr,Er._bubble=ar,Er.clone=yr,Er.get=xr,Er.milliseconds=wr,Er.seconds=kr,Er.minutes=Mr,Er.hours=Sr,Er.days=Dr,Er.weeks=Tr,Er.months=Cr,Er.years=Pr,Er.humanize=Nr,Er.toISOString=zr,Er.toString=zr,Er.toJSON=zr,Er.locale=ta,Er.localeData=na,Er.toIsoString=T("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",zr),Er.lang=ea,st("X",0,0,"unix"),st("x",0,0,"valueOf"),Ot("x",Mt),Ot("X",Ct),Rt("X",function(t,e,n){n._d=new Date(1e3*parseFloat(t,10))}),Rt("x",function(t,e,n){n._d=new Date(D(t))}),a.version="2.24.0",r($n),a.fn=za,a.min=Qn,a.max=ti,a.now=ei,a.utc=m,a.unix=Ea,a.months=qa,a.isDate=h,a.locale=mn,a.invalid=y,a.duration=Ci,a.isMoment=M,a.weekdays=$a,a.parseZone=Va,a.localeData=bn,a.isDuration=si,a.monthsShort=Za,a.weekdaysMin=Ka,a.defineLocale=pn,a.updateLocale=vn,a.locales=yn,a.weekdaysShort=Xa,a.normalizeUnits=K,a.relativeTimeRounding=Lr,a.relativeTimeThreshold=Rr,a.calendarFormat=Ri,a.prototype=za,a.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},a}()}),gi={datetime:"MMM D, YYYY, h:mm:ss a",millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"};an._date.override("function"==typeof fi?{_id:"moment",formats:function(){return gi},parse:function(t,e){return"string"==typeof t&&"string"==typeof e?t=fi(t,e):t instanceof fi||(t=fi(t)),t.isValid()?t.valueOf():null},format:function(t,e){return fi(t).format(e)},add:function(t,e,n){return fi(t).add(e,n).valueOf()},diff:function(t,e,n){return fi(t).diff(fi(e),n)},startOf:function(t,e,n){return t=fi(t),"isoWeek"===e?t.isoWeekday(n).valueOf():t.startOf(e).valueOf()},endOf:function(t,e){return fi(t).endOf(e).valueOf()},_create:function(t){return fi(t)}}:{}),Y._set("global",{plugins:{filler:{propagate:!0}}});var mi={dataset:function(t){var e=t.fill,n=t.chart,i=n.getDatasetMeta(e),a=i&&n.isDatasetVisible(e)&&i.dataset._children||[],r=a.length||0;return r?function(t,e){return e<r&&a[e]._view||null}:null},boundary:function(t){var e=t.boundary,n=e?e.x:null,i=e?e.y:null;return B.isArray(e)?function(t,n){return e[n]}:function(t){return{x:null===n?t.x:n,y:null===i?t.y:i}}}};function pi(t,e,n){var i,a=t._model||{},r=a.fill;if(void 0===r&&(r=!!a.backgroundColor),!1===r||null===r)return!1;if(!0===r)return"origin";if(i=parseFloat(r,10),isFinite(i)&&Math.floor(i)===i)return"-"!==r[0]&&"+"!==r[0]||(i=e+i),!(i===e||i<0||i>=n)&&i;switch(r){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return r;default:return!1}}function vi(t){return(t.el._scale||{}).getPointPositionForValue?function(t){var e,n,i,a,r,o=t.el._scale,s=o.options,l=o.chart.data.labels.length,u=t.fill,d=[];if(!l)return null;for(e=s.ticks.reverse?o.max:o.min,n=s.ticks.reverse?o.min:o.max,i=o.getPointPositionForValue(0,e),a=0;a<l;++a)r="start"===u||"end"===u?o.getPointPositionForValue(a,"start"===u?e:n):o.getBasePosition(a),s.gridLines.circular&&(r.cx=i.x,r.cy=i.y,r.angle=o.getIndexAngle(a)-Math.PI/2),d.push(r);return d}(t):function(t){var e,n=t.el._model||{},i=t.el._scale||{},a=t.fill,r=null;if(isFinite(a))return null;if("start"===a?r=void 0===n.scaleBottom?i.bottom:n.scaleBottom:"end"===a?r=void 0===n.scaleTop?i.top:n.scaleTop:void 0!==n.scaleZero?r=n.scaleZero:i.getBasePixel&&(r=i.getBasePixel()),null!=r){if(void 0!==r.x&&void 0!==r.y)return r;if(B.isFinite(r))return{x:(e=i.isHorizontal())?r:null,y:e?null:r}}return null}(t)}function bi(t,e,n){var i,a=t[e].fill,r=[e];if(!n)return a;for(;!1!==a&&-1===r.indexOf(a);){if(!isFinite(a))return a;if(!(i=t[a]))return!1;if(i.visible)return a;r.push(a),a=i.fill}return!1}function yi(t){var e=t.fill,n="dataset";return!1===e?null:(isFinite(e)||(n="boundary"),mi[n](t))}function xi(t){return t&&!t.skip}function _i(t,e,n,i,a){var r,o,s,l;if(i&&a){for(t.moveTo(e[0].x,e[0].y),r=1;r<i;++r)B.canvas.lineTo(t,e[r-1],e[r]);if(void 0===n[0].angle)for(t.lineTo(n[a-1].x,n[a-1].y),r=a-1;r>0;--r)B.canvas.lineTo(t,n[r],n[r-1],!0);else for(o=n[0].cx,s=n[0].cy,l=Math.sqrt(Math.pow(n[0].x-o,2)+Math.pow(n[0].y-s,2)),r=a-1;r>0;--r)t.arc(o,s,l,n[r].angle,n[r-1].angle,!0)}}function wi(t,e,n,i,a,r){var o,s,l,u,d,h,c,f,g=e.length,m=i.spanGaps,p=[],v=[],b=0,y=0;for(t.beginPath(),o=0,s=g;o<s;++o)d=n(u=e[l=o%g]._view,l,i),h=xi(u),c=xi(d),r&&void 0===f&&h&&(s=g+(f=o+1)),h&&c?(b=p.push(u),y=v.push(d)):b&&y&&(m?(h&&p.push(u),c&&v.push(d)):(_i(t,p,v,b,y),b=y=0,p=[],v=[]));_i(t,p,v,b,y),t.closePath(),t.fillStyle=a,t.fill()}var ki={id:"filler",afterDatasetsUpdate:function(t,e){var n,i,a,r,o=(t.data.datasets||[]).length,s=e.propagate,l=[];for(i=0;i<o;++i)r=null,(a=(n=t.getDatasetMeta(i)).dataset)&&a._model&&a instanceof kt.Line&&(r={visible:t.isDatasetVisible(i),fill:pi(a,i,o),chart:t,el:a}),n.$filler=r,l.push(r);for(i=0;i<o;++i)(r=l[i])&&(r.fill=bi(l,i,s),r.boundary=vi(r),r.mapper=yi(r))},beforeDatasetsDraw:function(t){var e,n,i,a,r,o,s,l=t._getSortedVisibleDatasetMetas(),u=t.ctx;for(n=l.length-1;n>=0;--n)(e=l[n].$filler)&&e.visible&&(a=(i=e.el)._view,r=i._children||[],o=e.mapper,s=a.backgroundColor||Y.global.defaultColor,o&&s&&r.length&&(B.canvas.clipArea(u,t.chartArea),wi(u,r,o,a,s,i._loop),B.canvas.unclipArea(u)))}},Mi=B.rtl.getRtlAdapter,Si=B.noop,Di=B.valueOrDefault;function Ci(t,e){return t.usePointStyle&&t.boxWidth>e?e:t.boxWidth}Y._set("global",{legend:{display:!0,position:"top",align:"center",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var n=e.datasetIndex,i=this.chart,a=i.getDatasetMeta(n);a.hidden=null===a.hidden?!i.data.datasets[n].hidden:null,i.update()},onHover:null,onLeave:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data.datasets,n=t.options.legend||{},i=n.labels&&n.labels.usePointStyle;return t._getSortedDatasetMetas().map(function(n){var a=n.controller.getStyle(i?0:void 0);return{text:e[n.index].label,fillStyle:a.backgroundColor,hidden:!t.isDatasetVisible(n.index),lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:a.borderWidth,strokeStyle:a.borderColor,pointStyle:a.pointStyle,rotation:a.rotation,datasetIndex:n.index}},this)}}},legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data.datasets;for(a.setAttribute("class",t.id+"-legend"),e=0,n=r.length;e<n;e++)(i=a.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=r[e].backgroundColor,r[e].label&&i.appendChild(document.createTextNode(r[e].label));return a.outerHTML}});var Pi=X.extend({initialize:function(t){var e=this;B.extend(e,t),e.legendHitBoxes=[],e._hoveredItem=null,e.doughnutMode=!1},beforeUpdate:Si,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:Si,beforeSetDimensions:Si,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:Si,beforeBuildLabels:Si,buildLabels:function(){var t=this,e=t.options.labels||{},n=B.callback(e.generateLabels,[t.chart],t)||[];e.filter&&(n=n.filter(function(n){return e.filter(n,t.chart.data)})),t.options.reverse&&n.reverse(),t.legendItems=n},afterBuildLabels:Si,beforeFit:Si,fit:function(){var t=this,e=t.options,n=e.labels,i=e.display,a=t.ctx,r=B.options._parseFont(n),o=r.size,s=t.legendHitBoxes=[],l=t.minSize,u=t.isHorizontal();if(u?(l.width=t.maxWidth,l.height=i?10:0):(l.width=i?10:0,l.height=t.maxHeight),i){if(a.font=r.string,u){var d=t.lineWidths=[0],h=0;a.textAlign="left",a.textBaseline="middle",B.each(t.legendItems,function(t,e){var i=Ci(n,o)+o/2+a.measureText(t.text).width;(0===e||d[d.length-1]+i+2*n.padding>l.width)&&(h+=o+n.padding,d[d.length-(e>0?0:1)]=0),s[e]={left:0,top:0,width:i,height:o},d[d.length-1]+=i+n.padding}),l.height+=h}else{var c=n.padding,f=t.columnWidths=[],g=t.columnHeights=[],m=n.padding,p=0,v=0;B.each(t.legendItems,function(t,e){var i=Ci(n,o)+o/2+a.measureText(t.text).width;e>0&&v+o+2*c>l.height&&(m+=p+n.padding,f.push(p),g.push(v),p=0,v=0),p=Math.max(p,i),v+=o+c,s[e]={left:0,top:0,width:i,height:o}}),m+=p,f.push(p),g.push(v),l.width+=m}t.width=l.width,t.height=l.height}else t.width=l.width=t.height=l.height=0},afterFit:Si,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,n=e.labels,i=Y.global,a=i.defaultColor,r=i.elements.line,o=t.height,s=t.columnHeights,l=t.width,u=t.lineWidths;if(e.display){var d,h=Mi(e.rtl,t.left,t.minSize.width),c=t.ctx,f=Di(n.fontColor,i.defaultFontColor),g=B.options._parseFont(n),m=g.size;c.textAlign=h.textAlign("left"),c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=g.string;var p=Ci(n,m),v=t.legendHitBoxes,b=function(t,i){switch(e.align){case"start":return n.padding;case"end":return t-i;default:return(t-i+n.padding)/2}},y=t.isHorizontal();d=y?{x:t.left+b(l,u[0]),y:t.top+n.padding,line:0}:{x:t.left+n.padding,y:t.top+b(o,s[0]),line:0},B.rtl.overrideTextDirection(t.ctx,e.textDirection);var x=m+n.padding;B.each(t.legendItems,function(e,i){var f=c.measureText(e.text).width,g=p+m/2+f,_=d.x,w=d.y;h.setWidth(t.minSize.width),y?i>0&&_+g+n.padding>t.left+t.minSize.width&&(w=d.y+=x,d.line++,_=d.x=t.left+b(l,u[d.line])):i>0&&w+x>t.top+t.minSize.height&&(_=d.x=_+t.columnWidths[d.line]+n.padding,d.line++,w=d.y=t.top+b(o,s[d.line]));var k=h.x(_);!function(t,e,i){if(!(isNaN(p)||p<=0)){c.save();var o=Di(i.lineWidth,r.borderWidth);if(c.fillStyle=Di(i.fillStyle,a),c.lineCap=Di(i.lineCap,r.borderCapStyle),c.lineDashOffset=Di(i.lineDashOffset,r.borderDashOffset),c.lineJoin=Di(i.lineJoin,r.borderJoinStyle),c.lineWidth=o,c.strokeStyle=Di(i.strokeStyle,a),c.setLineDash&&c.setLineDash(Di(i.lineDash,r.borderDash)),n&&n.usePointStyle){var s=p*Math.SQRT2/2,l=h.xPlus(t,p/2),u=e+m/2;B.canvas.drawPoint(c,i.pointStyle,s,l,u,i.rotation)}else c.fillRect(h.leftForLtr(t,p),e,p,m),0!==o&&c.strokeRect(h.leftForLtr(t,p),e,p,m);c.restore()}}(k,w,e),v[i].left=h.leftForLtr(k,v[i].width),v[i].top=w,function(t,e,n,i){var a=m/2,r=h.xPlus(t,p+a),o=e+a;c.fillText(n.text,r,o),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(r,o),c.lineTo(h.xPlus(r,i),o),c.stroke())}(k,w,e,f),y?d.x+=g+n.padding:d.y+=x}),B.rtl.restoreTextDirection(t.ctx,e.textDirection)}},_getLegendItemAt:function(t,e){var n,i,a,r=this;if(t>=r.left&&t<=r.right&&e>=r.top&&e<=r.bottom)for(a=r.legendHitBoxes,n=0;n<a.length;++n)if(t>=(i=a[n]).left&&t<=i.left+i.width&&e>=i.top&&e<=i.top+i.height)return r.legendItems[n];return null},handleEvent:function(t){var e,n=this,i=n.options,a="mouseup"===t.type?"click":t.type;if("mousemove"===a){if(!i.onHover&&!i.onLeave)return}else{if("click"!==a)return;if(!i.onClick)return}e=n._getLegendItemAt(t.x,t.y),"click"===a?e&&i.onClick&&i.onClick.call(n,t.native,e):(i.onLeave&&e!==n._hoveredItem&&(n._hoveredItem&&i.onLeave.call(n,t.native,n._hoveredItem),n._hoveredItem=e),i.onHover&&e&&i.onHover.call(n,t.native,e))}});function Ti(t,e){var n=new Pi({ctx:t.ctx,options:e,chart:t});pe.configure(t,n,e),pe.addBox(t,n),t.legend=n}var Oi={id:"legend",_element:Pi,beforeInit:function(t){var e=t.options.legend;e&&Ti(t,e)},beforeUpdate:function(t){var e=t.options.legend,n=t.legend;e?(B.mergeIf(e,Y.global.legend),n?(pe.configure(t,n,e),n.options=e):Ti(t,e)):n&&(pe.removeBox(t,n),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}},Ai=B.noop;Y._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,padding:10,position:"top",text:"",weight:2e3}});var Fi=X.extend({initialize:function(t){B.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:Ai,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:Ai,beforeSetDimensions:Ai,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:Ai,beforeBuildLabels:Ai,buildLabels:Ai,afterBuildLabels:Ai,beforeFit:Ai,fit:function(){var t,e=this,n=e.options,i=e.minSize={},a=e.isHorizontal();n.display?(t=(B.isArray(n.text)?n.text.length:1)*B.options._parseFont(n).lineHeight+2*n.padding,e.width=i.width=a?e.maxWidth:t,e.height=i.height=a?t:e.maxHeight):e.width=i.width=e.height=i.height=0},afterFit:Ai,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,n=t.options;if(n.display){var i,a,r,o=B.options._parseFont(n),s=o.lineHeight,l=s/2+n.padding,u=0,d=t.top,h=t.left,c=t.bottom,f=t.right;e.fillStyle=B.valueOrDefault(n.fontColor,Y.global.defaultFontColor),e.font=o.string,t.isHorizontal()?(a=h+(f-h)/2,r=d+l,i=f-h):(a="left"===n.position?h+l:f-l,r=d+(c-d)/2,i=c-d,u=Math.PI*("left"===n.position?-.5:.5)),e.save(),e.translate(a,r),e.rotate(u),e.textAlign="center",e.textBaseline="middle";var g=n.text;if(B.isArray(g))for(var m=0,p=0;p<g.length;++p)e.fillText(g[p],0,m,i),m+=s;else e.fillText(g,0,0,i);e.restore()}}});function Ii(t,e){var n=new Fi({ctx:t.ctx,options:e,chart:t});pe.configure(t,n,e),pe.addBox(t,n),t.titleBlock=n}var Li={},Ri=ki,Ni=Oi,Wi={id:"title",_element:Fi,beforeInit:function(t){var e=t.options.title;e&&Ii(t,e)},beforeUpdate:function(t){var e=t.options.title,n=t.titleBlock;e?(B.mergeIf(e,Y.global.title),n?(pe.configure(t,n,e),n.options=e):Ii(t,e)):n&&(pe.removeBox(t,n),delete t.titleBlock)}};for(var Yi in Li.filler=Ri,Li.legend=Ni,Li.title=Wi,tn.helpers=B,function(){function t(t,e,n){var i;return"string"==typeof t?(i=parseInt(t,10),-1!==t.indexOf("%")&&(i=i/100*e.parentNode[n])):i=t,i}function e(t){return null!=t&&"none"!==t}function n(n,i,a){var r=document.defaultView,o=B._getParentNode(n),s=r.getComputedStyle(n)[i],l=r.getComputedStyle(o)[i],u=e(s),d=e(l),h=Number.POSITIVE_INFINITY;return u||d?Math.min(u?t(s,n,a):h,d?t(l,o,a):h):"none"}B.where=function(t,e){if(B.isArray(t)&&Array.prototype.filter)return t.filter(e);var n=[];return B.each(t,function(t){e(t)&&n.push(t)}),n},B.findIndex=Array.prototype.findIndex?function(t,e,n){return t.findIndex(e,n)}:function(t,e,n){n=void 0===n?t:n;for(var i=0,a=t.length;i<a;++i)if(e.call(n,t[i],i,t))return i;return-1},B.findNextWhere=function(t,e,n){B.isNullOrUndef(n)&&(n=-1);for(var i=n+1;i<t.length;i++){var a=t[i];if(e(a))return a}},B.findPreviousWhere=function(t,e,n){B.isNullOrUndef(n)&&(n=t.length);for(var i=n-1;i>=0;i--){var a=t[i];if(e(a))return a}},B.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},B.almostEquals=function(t,e,n){return Math.abs(t-e)<n},B.almostWhole=function(t,e){var n=Math.round(t);return n-e<=t&&n+e>=t},B.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},B.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},B.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},B.toRadians=function(t){return t*(Math.PI/180)},B.toDegrees=function(t){return t*(180/Math.PI)},B._decimalPlaces=function(t){if(B.isFinite(t)){for(var e=1,n=0;Math.round(t*e)/e!==t;)e*=10,n++;return n}},B.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),r=Math.atan2(i,n);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},B.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},B.aliasPixel=function(t){return t%2==0?0:.5},B._alignPixel=function(t,e,n){var i=t.currentDevicePixelRatio,a=n/2;return Math.round((e-a)*i)/i+a},B.splineCurve=function(t,e,n,i){var a=t.skip?e:t,r=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l),h=i*(u=isNaN(u)?0:u),c=i*(d=isNaN(d)?0:d);return{previous:{x:r.x-h*(o.x-a.x),y:r.y-h*(o.y-a.y)},next:{x:r.x+c*(o.x-a.x),y:r.y+c*(o.y-a.y)}}},B.EPSILON=Number.EPSILON||1e-14,B.splineCurveMonotone=function(t){var e,n,i,a,r,o,s,l,u,d=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),h=d.length;for(e=0;e<h;++e)if(!(i=d[e]).model.skip){if(n=e>0?d[e-1]:null,(a=e<h-1?d[e+1]:null)&&!a.model.skip){var c=a.model.x-i.model.x;i.deltaK=0!==c?(a.model.y-i.model.y)/c:0}!n||n.model.skip?i.mK=i.deltaK:!a||a.model.skip?i.mK=n.deltaK:this.sign(n.deltaK)!==this.sign(i.deltaK)?i.mK=0:i.mK=(n.deltaK+i.deltaK)/2}for(e=0;e<h-1;++e)i=d[e],a=d[e+1],i.model.skip||a.model.skip||(B.almostEquals(i.deltaK,0,this.EPSILON)?i.mK=a.mK=0:(r=i.mK/i.deltaK,o=a.mK/i.deltaK,(l=Math.pow(r,2)+Math.pow(o,2))<=9||(s=3/Math.sqrt(l),i.mK=r*s*i.deltaK,a.mK=o*s*i.deltaK)));for(e=0;e<h;++e)(i=d[e]).model.skip||(n=e>0?d[e-1]:null,a=e<h-1?d[e+1]:null,n&&!n.model.skip&&(u=(i.model.x-n.model.x)/3,i.model.controlPointPreviousX=i.model.x-u,i.model.controlPointPreviousY=i.model.y-u*i.mK),a&&!a.model.skip&&(u=(a.model.x-i.model.x)/3,i.model.controlPointNextX=i.model.x+u,i.model.controlPointNextY=i.model.y+u*i.mK))},B.nextItem=function(t,e,n){return n?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},B.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},B.niceNum=function(t,e){var n=Math.floor(B.log10(t)),i=t/Math.pow(10,n);return(e?i<1.5?1:i<3?2:i<7?5:10:i<=1?1:i<=2?2:i<=5?5:10)*Math.pow(10,n)},B.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},B.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,r=t.target||t.srcElement,o=r.getBoundingClientRect(),s=a.touches;s&&s.length>0?(n=s[0].clientX,i=s[0].clientY):(n=a.clientX,i=a.clientY);var l=parseFloat(B.getStyle(r,"padding-left")),u=parseFloat(B.getStyle(r,"padding-top")),d=parseFloat(B.getStyle(r,"padding-right")),h=parseFloat(B.getStyle(r,"padding-bottom")),c=o.right-o.left-l-d,f=o.bottom-o.top-u-h;return{x:n=Math.round((n-o.left-l)/c*r.width/e.currentDevicePixelRatio),y:i=Math.round((i-o.top-u)/f*r.height/e.currentDevicePixelRatio)}},B.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},B.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},B._calculatePadding=function(t,e,n){return(e=B.getStyle(t,e)).indexOf("%")>-1?n*parseInt(e,10)/100:parseInt(e,10)},B._getParentNode=function(t){var e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e},B.getMaximumWidth=function(t){var e=B._getParentNode(t);if(!e)return t.clientWidth;var n=e.clientWidth,i=n-B._calculatePadding(e,"padding-left",n)-B._calculatePadding(e,"padding-right",n),a=B.getConstraintWidth(t);return isNaN(a)?i:Math.min(i,a)},B.getMaximumHeight=function(t){var e=B._getParentNode(t);if(!e)return t.clientHeight;var n=e.clientHeight,i=n-B._calculatePadding(e,"padding-top",n)-B._calculatePadding(e,"padding-bottom",n),a=B.getConstraintHeight(t);return isNaN(a)?i:Math.min(i,a)},B.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},B.retinaScale=function(t,e){var n=t.currentDevicePixelRatio=e||"undefined"!=typeof window&&window.devicePixelRatio||1;if(1!==n){var i=t.canvas,a=t.height,r=t.width;i.height=a*n,i.width=r*n,t.ctx.scale(n,n),i.style.height||i.style.width||(i.style.height=a+"px",i.style.width=r+"px")}},B.fontString=function(t,e,n){return e+" "+t+"px "+n},B.longestText=function(t,e,n,i){var a=(i=i||{}).data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var o,s,l,u,d,h=0,c=n.length;for(o=0;o<c;o++)if(null!=(u=n[o])&&!0!==B.isArray(u))h=B.measureText(t,a,r,h,u);else if(B.isArray(u))for(s=0,l=u.length;s<l;s++)null==(d=u[s])||B.isArray(d)||(h=B.measureText(t,a,r,h,d));var f=r.length/2;if(f>n.length){for(o=0;o<f;o++)delete a[r[o]];r.splice(0,f)}return h},B.measureText=function(t,e,n,i,a){var r=e[a];return r||(r=e[a]=t.measureText(a).width,n.push(a)),r>i&&(i=r),i},B.numberOfLabelLines=function(t){var e=1;return B.each(t,function(t){B.isArray(t)&&t.length>e&&(e=t.length)}),e},B.color=w?function(t){return t instanceof CanvasGradient&&(t=Y.global.defaultColor),w(t)}:function(t){return console.error("Color.js not found!"),t},B.getHoverColor=function(t){return t instanceof CanvasPattern||t instanceof CanvasGradient?t:B.color(t).saturate(.5).darken(.1).rgbString()}}(),tn._adapters=an,tn.Animation=J,tn.animationService=Q,tn.controllers=Qt,tn.DatasetController=at,tn.defaults=Y,tn.Element=X,tn.elements=kt,tn.Interaction=oe,tn.layouts=pe,tn.platform=Fe,tn.plugins=Ie,tn.Scale=yn,tn.scaleService=Le,tn.Ticks=rn,tn.Tooltip=Ue,tn.helpers.each(ci,function(t,e){tn.scaleService.registerScaleType(e,t,t._defaults)}),Li)Li.hasOwnProperty(Yi)&&tn.plugins.register(Li[Yi]);tn.platform.initialize();var zi=tn;return"undefined"!=typeof window&&(window.Chart=tn),tn.Chart=tn,tn.Legend=Li.legend._element,tn.Title=Li.title._element,tn.pluginService=tn.plugins,tn.PluginBase=tn.Element.extend({}),tn.canvasHelpers=tn.helpers.canvas,tn.layoutService=tn.layouts,tn.LinearScaleBase=Sn,tn.helpers.each(["Bar","Bubble","Doughnut","Line","PolarArea","Radar","Scatter"],function(t){tn[t]=function(e,n){return new tn(e,tn.helpers.merge(n||{},{type:t.charAt(0).toLowerCase()+t.slice(1)}))}}),zi}); \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/styles.f05c06a6a64f4730faae.css b/src/pybind/mgr/dashboard/frontend/dist/en-US/styles.f05c06a6a64f4730faae.css
new file mode 100644
index 000000000..a560d4e37
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/styles.f05c06a6a64f4730faae.css
@@ -0,0 +1,20 @@
+@charset "UTF-8";.swagger-ui{color:#3b4151;
+ /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */font-family:sans-serif}.swagger-ui html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;line-height:1.15}.swagger-ui body{margin:0}.swagger-ui article,.swagger-ui aside,.swagger-ui footer,.swagger-ui header,.swagger-ui nav,.swagger-ui section{display:block}.swagger-ui h1{font-size:2em;margin:.67em 0}.swagger-ui figcaption,.swagger-ui figure,.swagger-ui main{display:block}.swagger-ui figure{margin:1em 40px}.swagger-ui hr{box-sizing:initial;height:0;overflow:visible}.swagger-ui pre{font-family:monospace,monospace;font-size:1em}.swagger-ui a{-webkit-text-decoration-skip:objects;background-color:initial}.swagger-ui abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}.swagger-ui b,.swagger-ui strong{font-weight:inherit;font-weight:bolder}.swagger-ui code,.swagger-ui kbd,.swagger-ui samp{font-family:monospace,monospace;font-size:1em}.swagger-ui dfn{font-style:italic}.swagger-ui mark{background-color:#ff0;color:#000}.swagger-ui small{font-size:80%}.swagger-ui sub,.swagger-ui sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}.swagger-ui sub{bottom:-.25em}.swagger-ui sup{top:-.5em}.swagger-ui audio,.swagger-ui video{display:inline-block}.swagger-ui audio:not([controls]){display:none;height:0}.swagger-ui img{border-style:none}.swagger-ui svg:not(:root){overflow:hidden}.swagger-ui button,.swagger-ui input,.swagger-ui optgroup,.swagger-ui select,.swagger-ui textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}.swagger-ui button,.swagger-ui input{overflow:visible}.swagger-ui button,.swagger-ui select{text-transform:none}.swagger-ui [type=reset],.swagger-ui [type=submit],.swagger-ui button,.swagger-ui html [type=button]{-webkit-appearance:button}.swagger-ui [type=button]::-moz-focus-inner,.swagger-ui [type=reset]::-moz-focus-inner,.swagger-ui [type=submit]::-moz-focus-inner,.swagger-ui button::-moz-focus-inner{border-style:none;padding:0}.swagger-ui [type=button]:-moz-focusring,.swagger-ui [type=reset]:-moz-focusring,.swagger-ui [type=submit]:-moz-focusring,.swagger-ui button:-moz-focusring{outline:1px dotted ButtonText}.swagger-ui fieldset{padding:.35em .75em .625em}.swagger-ui legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}.swagger-ui progress{display:inline-block;vertical-align:initial}.swagger-ui textarea{overflow:auto}.swagger-ui [type=checkbox],.swagger-ui [type=radio]{box-sizing:border-box;padding:0}.swagger-ui [type=number]::-webkit-inner-spin-button,.swagger-ui [type=number]::-webkit-outer-spin-button{height:auto}.swagger-ui [type=search]{-webkit-appearance:textfield;outline-offset:-2px}.swagger-ui [type=search]::-webkit-search-cancel-button,.swagger-ui [type=search]::-webkit-search-decoration{-webkit-appearance:none}.swagger-ui ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.swagger-ui details,.swagger-ui menu{display:block}.swagger-ui summary{display:list-item}.swagger-ui canvas{display:inline-block}.swagger-ui [hidden],.swagger-ui template{display:none}.swagger-ui .debug *{outline:1px solid gold}.swagger-ui .debug-white *{outline:1px solid #fff}.swagger-ui .debug-black *{outline:1px solid #000}.swagger-ui .debug-grid{background:#0000 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTRDOTY4N0U2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTRDOTY4N0Q2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3NjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3NzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsBS+GMAAAAjSURBVHjaYvz//z8DLsD4gcGXiYEAGBIKGBne//fFpwAgwAB98AaF2pjlUQAAAABJRU5ErkJggg==) repeat 0 0}.swagger-ui .debug-grid-16{background:#0000 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODYyRjhERDU2N0YyMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODYyRjhERDQ2N0YyMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3QTY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3QjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvCS01IAAABMSURBVHjaYmR4/5+BFPBfAMFm/MBgx8RAGWCn1AAmSg34Q6kBDKMGMDCwICeMIemF/5QawEipAWwUhwEjMDvbAWlWkvVBwu8vQIABAEwBCph8U6c0AAAAAElFTkSuQmCC) repeat 0 0}.swagger-ui .debug-grid-8-solid{background:#fff url(data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAAAAAD/4QMxaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzExMSA3OS4xNTgzMjUsIDIwMTUvMDkvMTAtMDE6MTA6MjAgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkIxMjI0OTczNjdCMzExRTZCMkJDRTI0MDgxMDAyMTcxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkIxMjI0OTc0NjdCMzExRTZCMkJDRTI0MDgxMDAyMTcxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QjEyMjQ5NzE2N0IzMTFFNkIyQkNFMjQwODEwMDIxNzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QjEyMjQ5NzI2N0IzMTFFNkIyQkNFMjQwODEwMDIxNzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAbGhopHSlBJiZBQi8vL0JHPz4+P0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHAR0pKTQmND8oKD9HPzU/R0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0f/wAARCAAIAAgDASIAAhEBAxEB/8QAWQABAQAAAAAAAAAAAAAAAAAAAAYBAQEAAAAAAAAAAAAAAAAAAAIEEAEBAAMBAAAAAAAAAAAAAAABADECA0ERAAEDBQAAAAAAAAAAAAAAAAARITFBUWESIv/aAAwDAQACEQMRAD8AoOnTV1QTD7JJshP3vSM3P//Z) repeat 0 0}.swagger-ui .debug-grid-16-solid{background:#fff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzY3MkJEN0U2N0M1MTFFNkIyQkNFMjQwODEwMDIxNzEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzY3MkJEN0Y2N0M1MTFFNkIyQkNFMjQwODEwMDIxNzEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3QzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3RDY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pve6J3kAAAAzSURBVHjaYvz//z8D0UDsMwMjSRoYP5Gq4SPNbRjVMEQ1fCRDg+in/6+J1AJUxsgAEGAA31BAJMS0GYEAAAAASUVORK5CYII=) repeat 0 0}.swagger-ui .border-box,.swagger-ui a,.swagger-ui article,.swagger-ui body,.swagger-ui code,.swagger-ui dd,.swagger-ui div,.swagger-ui dl,.swagger-ui dt,.swagger-ui fieldset,.swagger-ui footer,.swagger-ui form,.swagger-ui h1,.swagger-ui h2,.swagger-ui h3,.swagger-ui h4,.swagger-ui h5,.swagger-ui h6,.swagger-ui header,.swagger-ui html,.swagger-ui input[type=email],.swagger-ui input[type=number],.swagger-ui input[type=password],.swagger-ui input[type=tel],.swagger-ui input[type=text],.swagger-ui input[type=url],.swagger-ui legend,.swagger-ui li,.swagger-ui main,.swagger-ui ol,.swagger-ui p,.swagger-ui pre,.swagger-ui section,.swagger-ui table,.swagger-ui td,.swagger-ui textarea,.swagger-ui th,.swagger-ui tr,.swagger-ui ul{box-sizing:border-box}.swagger-ui .aspect-ratio{height:0;position:relative}.swagger-ui .aspect-ratio--16x9{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1{padding-bottom:100%}.swagger-ui .aspect-ratio--object{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:100}@media screen and (min-width:30em){.swagger-ui .aspect-ratio-ns{height:0;position:relative}.swagger-ui .aspect-ratio--16x9-ns{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16-ns{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3-ns{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4-ns{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4-ns{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6-ns{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5-ns{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8-ns{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5-ns{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7-ns{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1-ns{padding-bottom:100%}.swagger-ui .aspect-ratio--object-ns{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:100}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .aspect-ratio-m{height:0;position:relative}.swagger-ui .aspect-ratio--16x9-m{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16-m{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3-m{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4-m{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4-m{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6-m{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5-m{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8-m{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5-m{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7-m{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1-m{padding-bottom:100%}.swagger-ui .aspect-ratio--object-m{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:100}}@media screen and (min-width:60em){.swagger-ui .aspect-ratio-l{height:0;position:relative}.swagger-ui .aspect-ratio--16x9-l{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16-l{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3-l{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4-l{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4-l{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6-l{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5-l{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8-l{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5-l{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7-l{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1-l{padding-bottom:100%}.swagger-ui .aspect-ratio--object-l{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:100}}.swagger-ui img{max-width:100%}.swagger-ui .cover{background-size:cover!important}.swagger-ui .contain{background-size:contain!important}@media screen and (min-width:30em){.swagger-ui .cover-ns{background-size:cover!important}.swagger-ui .contain-ns{background-size:contain!important}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .cover-m{background-size:cover!important}.swagger-ui .contain-m{background-size:contain!important}}@media screen and (min-width:60em){.swagger-ui .cover-l{background-size:cover!important}.swagger-ui .contain-l{background-size:contain!important}}.swagger-ui .bg-center{background-position:50%;background-repeat:no-repeat}.swagger-ui .bg-top{background-position:top;background-repeat:no-repeat}.swagger-ui .bg-right{background-position:100%;background-repeat:no-repeat}.swagger-ui .bg-bottom{background-position:bottom;background-repeat:no-repeat}.swagger-ui .bg-left{background-position:0;background-repeat:no-repeat}@media screen and (min-width:30em){.swagger-ui .bg-center-ns{background-position:50%;background-repeat:no-repeat}.swagger-ui .bg-top-ns{background-position:top;background-repeat:no-repeat}.swagger-ui .bg-right-ns{background-position:100%;background-repeat:no-repeat}.swagger-ui .bg-bottom-ns{background-position:bottom;background-repeat:no-repeat}.swagger-ui .bg-left-ns{background-position:0;background-repeat:no-repeat}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .bg-center-m{background-position:50%;background-repeat:no-repeat}.swagger-ui .bg-top-m{background-position:top;background-repeat:no-repeat}.swagger-ui .bg-right-m{background-position:100%;background-repeat:no-repeat}.swagger-ui .bg-bottom-m{background-position:bottom;background-repeat:no-repeat}.swagger-ui .bg-left-m{background-position:0;background-repeat:no-repeat}}@media screen and (min-width:60em){.swagger-ui .bg-center-l{background-position:50%;background-repeat:no-repeat}.swagger-ui .bg-top-l{background-position:top;background-repeat:no-repeat}.swagger-ui .bg-right-l{background-position:100%;background-repeat:no-repeat}.swagger-ui .bg-bottom-l{background-position:bottom;background-repeat:no-repeat}.swagger-ui .bg-left-l{background-position:0;background-repeat:no-repeat}}.swagger-ui .outline{outline:1px solid}.swagger-ui .outline-transparent{outline:1px solid #0000}.swagger-ui .outline-0{outline:0}@media screen and (min-width:30em){.swagger-ui .outline-ns{outline:1px solid}.swagger-ui .outline-transparent-ns{outline:1px solid #0000}.swagger-ui .outline-0-ns{outline:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .outline-m{outline:1px solid}.swagger-ui .outline-transparent-m{outline:1px solid #0000}.swagger-ui .outline-0-m{outline:0}}@media screen and (min-width:60em){.swagger-ui .outline-l{outline:1px solid}.swagger-ui .outline-transparent-l{outline:1px solid #0000}.swagger-ui .outline-0-l{outline:0}}.swagger-ui .ba{border-style:solid;border-width:1px}.swagger-ui .bt{border-top-style:solid;border-top-width:1px}.swagger-ui .br{border-right-style:solid;border-right-width:1px}.swagger-ui .bb{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl{border-left-style:solid;border-left-width:1px}.swagger-ui .bn{border-style:none;border-width:0}@media screen and (min-width:30em){.swagger-ui .ba-ns{border-style:solid;border-width:1px}.swagger-ui .bt-ns{border-top-style:solid;border-top-width:1px}.swagger-ui .br-ns{border-right-style:solid;border-right-width:1px}.swagger-ui .bb-ns{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl-ns{border-left-style:solid;border-left-width:1px}.swagger-ui .bn-ns{border-style:none;border-width:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .ba-m{border-style:solid;border-width:1px}.swagger-ui .bt-m{border-top-style:solid;border-top-width:1px}.swagger-ui .br-m{border-right-style:solid;border-right-width:1px}.swagger-ui .bb-m{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl-m{border-left-style:solid;border-left-width:1px}.swagger-ui .bn-m{border-style:none;border-width:0}}@media screen and (min-width:60em){.swagger-ui .ba-l{border-style:solid;border-width:1px}.swagger-ui .bt-l{border-top-style:solid;border-top-width:1px}.swagger-ui .br-l{border-right-style:solid;border-right-width:1px}.swagger-ui .bb-l{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl-l{border-left-style:solid;border-left-width:1px}.swagger-ui .bn-l{border-style:none;border-width:0}}.swagger-ui .b--black{border-color:#000}.swagger-ui .b--near-black{border-color:#111}.swagger-ui .b--dark-gray{border-color:#333}.swagger-ui .b--mid-gray{border-color:#555}.swagger-ui .b--gray{border-color:#777}.swagger-ui .b--silver{border-color:#999}.swagger-ui .b--light-silver{border-color:#aaa}.swagger-ui .b--moon-gray{border-color:#ccc}.swagger-ui .b--light-gray{border-color:#eee}.swagger-ui .b--near-white{border-color:#f4f4f4}.swagger-ui .b--white{border-color:#fff}.swagger-ui .b--white-90{border-color:#ffffffe6}.swagger-ui .b--white-80{border-color:#fffc}.swagger-ui .b--white-70{border-color:#ffffffb3}.swagger-ui .b--white-60{border-color:#fff9}.swagger-ui .b--white-50{border-color:#ffffff80}.swagger-ui .b--white-40{border-color:#fff6}.swagger-ui .b--white-30{border-color:#ffffff4d}.swagger-ui .b--white-20{border-color:#fff3}.swagger-ui .b--white-10{border-color:#ffffff1a}.swagger-ui .b--white-05{border-color:#ffffff0d}.swagger-ui .b--white-025{border-color:hsla(0,0%,100%,.025)}.swagger-ui .b--white-0125{border-color:hsla(0,0%,100%,.013)}.swagger-ui .b--black-90{border-color:#000000e6}.swagger-ui .b--black-80{border-color:#000c}.swagger-ui .b--black-70{border-color:#000000b3}.swagger-ui .b--black-60{border-color:#0009}.swagger-ui .b--black-50{border-color:#00000080}.swagger-ui .b--black-40{border-color:#0006}.swagger-ui .b--black-30{border-color:#0000004d}.swagger-ui .b--black-20{border-color:#0003}.swagger-ui .b--black-10{border-color:#0000001a}.swagger-ui .b--black-05{border-color:#0000000d}.swagger-ui .b--black-025{border-color:rgba(0,0,0,.025)}.swagger-ui .b--black-0125{border-color:rgba(0,0,0,.013)}.swagger-ui .b--dark-red{border-color:#e7040f}.swagger-ui .b--red{border-color:#ff4136}.swagger-ui .b--light-red{border-color:#ff725c}.swagger-ui .b--orange{border-color:#ff6300}.swagger-ui .b--gold{border-color:#ffb700}.swagger-ui .b--yellow{border-color:gold}.swagger-ui .b--light-yellow{border-color:#fbf1a9}.swagger-ui .b--purple{border-color:#5e2ca5}.swagger-ui .b--light-purple{border-color:#a463f2}.swagger-ui .b--dark-pink{border-color:#d5008f}.swagger-ui .b--hot-pink{border-color:#ff41b4}.swagger-ui .b--pink{border-color:#ff80cc}.swagger-ui .b--light-pink{border-color:#ffa3d7}.swagger-ui .b--dark-green{border-color:#137752}.swagger-ui .b--green{border-color:#19a974}.swagger-ui .b--light-green{border-color:#9eebcf}.swagger-ui .b--navy{border-color:#001b44}.swagger-ui .b--dark-blue{border-color:#00449e}.swagger-ui .b--blue{border-color:#357edd}.swagger-ui .b--light-blue{border-color:#96ccff}.swagger-ui .b--lightest-blue{border-color:#cdecff}.swagger-ui .b--washed-blue{border-color:#f6fffe}.swagger-ui .b--washed-green{border-color:#e8fdf5}.swagger-ui .b--washed-yellow{border-color:#fffceb}.swagger-ui .b--washed-red{border-color:#ffdfdf}.swagger-ui .b--transparent{border-color:#0000}.swagger-ui .b--inherit{border-color:inherit}.swagger-ui .br0{border-radius:0}.swagger-ui .br1{border-radius:.125rem}.swagger-ui .br2{border-radius:.25rem}.swagger-ui .br3{border-radius:.5rem}.swagger-ui .br4{border-radius:1rem}.swagger-ui .br-100{border-radius:100%}.swagger-ui .br-pill{border-radius:9999px}.swagger-ui .br--bottom{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right{border-bottom-left-radius:0;border-top-left-radius:0}.swagger-ui .br--left{border-bottom-right-radius:0;border-top-right-radius:0}@media screen and (min-width:30em){.swagger-ui .br0-ns{border-radius:0}.swagger-ui .br1-ns{border-radius:.125rem}.swagger-ui .br2-ns{border-radius:.25rem}.swagger-ui .br3-ns{border-radius:.5rem}.swagger-ui .br4-ns{border-radius:1rem}.swagger-ui .br-100-ns{border-radius:100%}.swagger-ui .br-pill-ns{border-radius:9999px}.swagger-ui .br--bottom-ns{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top-ns{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right-ns{border-bottom-left-radius:0;border-top-left-radius:0}.swagger-ui .br--left-ns{border-bottom-right-radius:0;border-top-right-radius:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .br0-m{border-radius:0}.swagger-ui .br1-m{border-radius:.125rem}.swagger-ui .br2-m{border-radius:.25rem}.swagger-ui .br3-m{border-radius:.5rem}.swagger-ui .br4-m{border-radius:1rem}.swagger-ui .br-100-m{border-radius:100%}.swagger-ui .br-pill-m{border-radius:9999px}.swagger-ui .br--bottom-m{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top-m{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right-m{border-bottom-left-radius:0;border-top-left-radius:0}.swagger-ui .br--left-m{border-bottom-right-radius:0;border-top-right-radius:0}}@media screen and (min-width:60em){.swagger-ui .br0-l{border-radius:0}.swagger-ui .br1-l{border-radius:.125rem}.swagger-ui .br2-l{border-radius:.25rem}.swagger-ui .br3-l{border-radius:.5rem}.swagger-ui .br4-l{border-radius:1rem}.swagger-ui .br-100-l{border-radius:100%}.swagger-ui .br-pill-l{border-radius:9999px}.swagger-ui .br--bottom-l{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top-l{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right-l{border-bottom-left-radius:0;border-top-left-radius:0}.swagger-ui .br--left-l{border-bottom-right-radius:0;border-top-right-radius:0}}.swagger-ui .b--dotted{border-style:dotted}.swagger-ui .b--dashed{border-style:dashed}.swagger-ui .b--solid{border-style:solid}.swagger-ui .b--none{border-style:none}@media screen and (min-width:30em){.swagger-ui .b--dotted-ns{border-style:dotted}.swagger-ui .b--dashed-ns{border-style:dashed}.swagger-ui .b--solid-ns{border-style:solid}.swagger-ui .b--none-ns{border-style:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .b--dotted-m{border-style:dotted}.swagger-ui .b--dashed-m{border-style:dashed}.swagger-ui .b--solid-m{border-style:solid}.swagger-ui .b--none-m{border-style:none}}@media screen and (min-width:60em){.swagger-ui .b--dotted-l{border-style:dotted}.swagger-ui .b--dashed-l{border-style:dashed}.swagger-ui .b--solid-l{border-style:solid}.swagger-ui .b--none-l{border-style:none}}.swagger-ui .bw0{border-width:0}.swagger-ui .bw1{border-width:.125rem}.swagger-ui .bw2{border-width:.25rem}.swagger-ui .bw3{border-width:.5rem}.swagger-ui .bw4{border-width:1rem}.swagger-ui .bw5{border-width:2rem}.swagger-ui .bt-0{border-top-width:0}.swagger-ui .br-0{border-right-width:0}.swagger-ui .bb-0{border-bottom-width:0}.swagger-ui .bl-0{border-left-width:0}@media screen and (min-width:30em){.swagger-ui .bw0-ns{border-width:0}.swagger-ui .bw1-ns{border-width:.125rem}.swagger-ui .bw2-ns{border-width:.25rem}.swagger-ui .bw3-ns{border-width:.5rem}.swagger-ui .bw4-ns{border-width:1rem}.swagger-ui .bw5-ns{border-width:2rem}.swagger-ui .bt-0-ns{border-top-width:0}.swagger-ui .br-0-ns{border-right-width:0}.swagger-ui .bb-0-ns{border-bottom-width:0}.swagger-ui .bl-0-ns{border-left-width:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .bw0-m{border-width:0}.swagger-ui .bw1-m{border-width:.125rem}.swagger-ui .bw2-m{border-width:.25rem}.swagger-ui .bw3-m{border-width:.5rem}.swagger-ui .bw4-m{border-width:1rem}.swagger-ui .bw5-m{border-width:2rem}.swagger-ui .bt-0-m{border-top-width:0}.swagger-ui .br-0-m{border-right-width:0}.swagger-ui .bb-0-m{border-bottom-width:0}.swagger-ui .bl-0-m{border-left-width:0}}@media screen and (min-width:60em){.swagger-ui .bw0-l{border-width:0}.swagger-ui .bw1-l{border-width:.125rem}.swagger-ui .bw2-l{border-width:.25rem}.swagger-ui .bw3-l{border-width:.5rem}.swagger-ui .bw4-l{border-width:1rem}.swagger-ui .bw5-l{border-width:2rem}.swagger-ui .bt-0-l{border-top-width:0}.swagger-ui .br-0-l{border-right-width:0}.swagger-ui .bb-0-l{border-bottom-width:0}.swagger-ui .bl-0-l{border-left-width:0}}.swagger-ui .shadow-1{box-shadow:0 0 4px 2px #0003}.swagger-ui .shadow-2{box-shadow:0 0 8px 2px #0003}.swagger-ui .shadow-3{box-shadow:2px 2px 4px 2px #0003}.swagger-ui .shadow-4{box-shadow:2px 2px 8px 0 #0003}.swagger-ui .shadow-5{box-shadow:4px 4px 8px 0 #0003}@media screen and (min-width:30em){.swagger-ui .shadow-1-ns{box-shadow:0 0 4px 2px #0003}.swagger-ui .shadow-2-ns{box-shadow:0 0 8px 2px #0003}.swagger-ui .shadow-3-ns{box-shadow:2px 2px 4px 2px #0003}.swagger-ui .shadow-4-ns{box-shadow:2px 2px 8px 0 #0003}.swagger-ui .shadow-5-ns{box-shadow:4px 4px 8px 0 #0003}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .shadow-1-m{box-shadow:0 0 4px 2px #0003}.swagger-ui .shadow-2-m{box-shadow:0 0 8px 2px #0003}.swagger-ui .shadow-3-m{box-shadow:2px 2px 4px 2px #0003}.swagger-ui .shadow-4-m{box-shadow:2px 2px 8px 0 #0003}.swagger-ui .shadow-5-m{box-shadow:4px 4px 8px 0 #0003}}@media screen and (min-width:60em){.swagger-ui .shadow-1-l{box-shadow:0 0 4px 2px #0003}.swagger-ui .shadow-2-l{box-shadow:0 0 8px 2px #0003}.swagger-ui .shadow-3-l{box-shadow:2px 2px 4px 2px #0003}.swagger-ui .shadow-4-l{box-shadow:2px 2px 8px 0 #0003}.swagger-ui .shadow-5-l{box-shadow:4px 4px 8px 0 #0003}}.swagger-ui .pre{overflow-x:auto;overflow-y:hidden;overflow:scroll}.swagger-ui .top-0{top:0}.swagger-ui .right-0{right:0}.swagger-ui .bottom-0{bottom:0}.swagger-ui .left-0{left:0}.swagger-ui .top-1{top:1rem}.swagger-ui .right-1{right:1rem}.swagger-ui .bottom-1{bottom:1rem}.swagger-ui .left-1{left:1rem}.swagger-ui .top-2{top:2rem}.swagger-ui .right-2{right:2rem}.swagger-ui .bottom-2{bottom:2rem}.swagger-ui .left-2{left:2rem}.swagger-ui .top--1{top:-1rem}.swagger-ui .right--1{right:-1rem}.swagger-ui .bottom--1{bottom:-1rem}.swagger-ui .left--1{left:-1rem}.swagger-ui .top--2{top:-2rem}.swagger-ui .right--2{right:-2rem}.swagger-ui .bottom--2{bottom:-2rem}.swagger-ui .left--2{left:-2rem}.swagger-ui .absolute--fill{bottom:0;left:0;right:0;top:0}@media screen and (min-width:30em){.swagger-ui .top-0-ns{top:0}.swagger-ui .left-0-ns{left:0}.swagger-ui .right-0-ns{right:0}.swagger-ui .bottom-0-ns{bottom:0}.swagger-ui .top-1-ns{top:1rem}.swagger-ui .left-1-ns{left:1rem}.swagger-ui .right-1-ns{right:1rem}.swagger-ui .bottom-1-ns{bottom:1rem}.swagger-ui .top-2-ns{top:2rem}.swagger-ui .left-2-ns{left:2rem}.swagger-ui .right-2-ns{right:2rem}.swagger-ui .bottom-2-ns{bottom:2rem}.swagger-ui .top--1-ns{top:-1rem}.swagger-ui .right--1-ns{right:-1rem}.swagger-ui .bottom--1-ns{bottom:-1rem}.swagger-ui .left--1-ns{left:-1rem}.swagger-ui .top--2-ns{top:-2rem}.swagger-ui .right--2-ns{right:-2rem}.swagger-ui .bottom--2-ns{bottom:-2rem}.swagger-ui .left--2-ns{left:-2rem}.swagger-ui .absolute--fill-ns{bottom:0;left:0;right:0;top:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .top-0-m{top:0}.swagger-ui .left-0-m{left:0}.swagger-ui .right-0-m{right:0}.swagger-ui .bottom-0-m{bottom:0}.swagger-ui .top-1-m{top:1rem}.swagger-ui .left-1-m{left:1rem}.swagger-ui .right-1-m{right:1rem}.swagger-ui .bottom-1-m{bottom:1rem}.swagger-ui .top-2-m{top:2rem}.swagger-ui .left-2-m{left:2rem}.swagger-ui .right-2-m{right:2rem}.swagger-ui .bottom-2-m{bottom:2rem}.swagger-ui .top--1-m{top:-1rem}.swagger-ui .right--1-m{right:-1rem}.swagger-ui .bottom--1-m{bottom:-1rem}.swagger-ui .left--1-m{left:-1rem}.swagger-ui .top--2-m{top:-2rem}.swagger-ui .right--2-m{right:-2rem}.swagger-ui .bottom--2-m{bottom:-2rem}.swagger-ui .left--2-m{left:-2rem}.swagger-ui .absolute--fill-m{bottom:0;left:0;right:0;top:0}}@media screen and (min-width:60em){.swagger-ui .top-0-l{top:0}.swagger-ui .left-0-l{left:0}.swagger-ui .right-0-l{right:0}.swagger-ui .bottom-0-l{bottom:0}.swagger-ui .top-1-l{top:1rem}.swagger-ui .left-1-l{left:1rem}.swagger-ui .right-1-l{right:1rem}.swagger-ui .bottom-1-l{bottom:1rem}.swagger-ui .top-2-l{top:2rem}.swagger-ui .left-2-l{left:2rem}.swagger-ui .right-2-l{right:2rem}.swagger-ui .bottom-2-l{bottom:2rem}.swagger-ui .top--1-l{top:-1rem}.swagger-ui .right--1-l{right:-1rem}.swagger-ui .bottom--1-l{bottom:-1rem}.swagger-ui .left--1-l{left:-1rem}.swagger-ui .top--2-l{top:-2rem}.swagger-ui .right--2-l{right:-2rem}.swagger-ui .bottom--2-l{bottom:-2rem}.swagger-ui .left--2-l{left:-2rem}.swagger-ui .absolute--fill-l{bottom:0;left:0;right:0;top:0}}.swagger-ui .cf:after,.swagger-ui .cf:before{content:" ";display:table}.swagger-ui .cf:after{clear:both}.swagger-ui .cf{*zoom:1}.swagger-ui .cl{clear:left}.swagger-ui .cr{clear:right}.swagger-ui .cb{clear:both}.swagger-ui .cn{clear:none}@media screen and (min-width:30em){.swagger-ui .cl-ns{clear:left}.swagger-ui .cr-ns{clear:right}.swagger-ui .cb-ns{clear:both}.swagger-ui .cn-ns{clear:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .cl-m{clear:left}.swagger-ui .cr-m{clear:right}.swagger-ui .cb-m{clear:both}.swagger-ui .cn-m{clear:none}}@media screen and (min-width:60em){.swagger-ui .cl-l{clear:left}.swagger-ui .cr-l{clear:right}.swagger-ui .cb-l{clear:both}.swagger-ui .cn-l{clear:none}}.swagger-ui .flex{display:flex}.swagger-ui .inline-flex{display:inline-flex}.swagger-ui .flex-auto{flex:1 1 auto;min-height:0;min-width:0}.swagger-ui .flex-none{flex:none}.swagger-ui .flex-column{flex-direction:column}.swagger-ui .flex-row{flex-direction:row}.swagger-ui .flex-wrap{flex-wrap:wrap}.swagger-ui .flex-nowrap{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse{flex-direction:column-reverse}.swagger-ui .flex-row-reverse{flex-direction:row-reverse}.swagger-ui .items-start{align-items:flex-start}.swagger-ui .items-end{align-items:flex-end}.swagger-ui .items-center{align-items:center}.swagger-ui .items-baseline{align-items:baseline}.swagger-ui .items-stretch{align-items:stretch}.swagger-ui .self-start{align-self:flex-start}.swagger-ui .self-end{align-self:flex-end}.swagger-ui .self-center{align-self:center}.swagger-ui .self-baseline{align-self:baseline}.swagger-ui .self-stretch{align-self:stretch}.swagger-ui .justify-start{justify-content:flex-start}.swagger-ui .justify-end{justify-content:flex-end}.swagger-ui .justify-center{justify-content:center}.swagger-ui .justify-between{justify-content:space-between}.swagger-ui .justify-around{justify-content:space-around}.swagger-ui .content-start{align-content:flex-start}.swagger-ui .content-end{align-content:flex-end}.swagger-ui .content-center{align-content:center}.swagger-ui .content-between{align-content:space-between}.swagger-ui .content-around{align-content:space-around}.swagger-ui .content-stretch{align-content:stretch}.swagger-ui .order-0{order:0}.swagger-ui .order-1{order:1}.swagger-ui .order-2{order:2}.swagger-ui .order-3{order:3}.swagger-ui .order-4{order:4}.swagger-ui .order-5{order:5}.swagger-ui .order-6{order:6}.swagger-ui .order-7{order:7}.swagger-ui .order-8{order:8}.swagger-ui .order-last{order:99999}.swagger-ui .flex-grow-0{flex-grow:0}.swagger-ui .flex-grow-1{flex-grow:1}.swagger-ui .flex-shrink-0{flex-shrink:0}.swagger-ui .flex-shrink-1{flex-shrink:1}@media screen and (min-width:30em){.swagger-ui .flex-ns{display:flex}.swagger-ui .inline-flex-ns{display:inline-flex}.swagger-ui .flex-auto-ns{flex:1 1 auto;min-height:0;min-width:0}.swagger-ui .flex-none-ns{flex:none}.swagger-ui .flex-column-ns{flex-direction:column}.swagger-ui .flex-row-ns{flex-direction:row}.swagger-ui .flex-wrap-ns{flex-wrap:wrap}.swagger-ui .flex-nowrap-ns{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse-ns{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse-ns{flex-direction:column-reverse}.swagger-ui .flex-row-reverse-ns{flex-direction:row-reverse}.swagger-ui .items-start-ns{align-items:flex-start}.swagger-ui .items-end-ns{align-items:flex-end}.swagger-ui .items-center-ns{align-items:center}.swagger-ui .items-baseline-ns{align-items:baseline}.swagger-ui .items-stretch-ns{align-items:stretch}.swagger-ui .self-start-ns{align-self:flex-start}.swagger-ui .self-end-ns{align-self:flex-end}.swagger-ui .self-center-ns{align-self:center}.swagger-ui .self-baseline-ns{align-self:baseline}.swagger-ui .self-stretch-ns{align-self:stretch}.swagger-ui .justify-start-ns{justify-content:flex-start}.swagger-ui .justify-end-ns{justify-content:flex-end}.swagger-ui .justify-center-ns{justify-content:center}.swagger-ui .justify-between-ns{justify-content:space-between}.swagger-ui .justify-around-ns{justify-content:space-around}.swagger-ui .content-start-ns{align-content:flex-start}.swagger-ui .content-end-ns{align-content:flex-end}.swagger-ui .content-center-ns{align-content:center}.swagger-ui .content-between-ns{align-content:space-between}.swagger-ui .content-around-ns{align-content:space-around}.swagger-ui .content-stretch-ns{align-content:stretch}.swagger-ui .order-0-ns{order:0}.swagger-ui .order-1-ns{order:1}.swagger-ui .order-2-ns{order:2}.swagger-ui .order-3-ns{order:3}.swagger-ui .order-4-ns{order:4}.swagger-ui .order-5-ns{order:5}.swagger-ui .order-6-ns{order:6}.swagger-ui .order-7-ns{order:7}.swagger-ui .order-8-ns{order:8}.swagger-ui .order-last-ns{order:99999}.swagger-ui .flex-grow-0-ns{flex-grow:0}.swagger-ui .flex-grow-1-ns{flex-grow:1}.swagger-ui .flex-shrink-0-ns{flex-shrink:0}.swagger-ui .flex-shrink-1-ns{flex-shrink:1}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .flex-m{display:flex}.swagger-ui .inline-flex-m{display:inline-flex}.swagger-ui .flex-auto-m{flex:1 1 auto;min-height:0;min-width:0}.swagger-ui .flex-none-m{flex:none}.swagger-ui .flex-column-m{flex-direction:column}.swagger-ui .flex-row-m{flex-direction:row}.swagger-ui .flex-wrap-m{flex-wrap:wrap}.swagger-ui .flex-nowrap-m{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse-m{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse-m{flex-direction:column-reverse}.swagger-ui .flex-row-reverse-m{flex-direction:row-reverse}.swagger-ui .items-start-m{align-items:flex-start}.swagger-ui .items-end-m{align-items:flex-end}.swagger-ui .items-center-m{align-items:center}.swagger-ui .items-baseline-m{align-items:baseline}.swagger-ui .items-stretch-m{align-items:stretch}.swagger-ui .self-start-m{align-self:flex-start}.swagger-ui .self-end-m{align-self:flex-end}.swagger-ui .self-center-m{align-self:center}.swagger-ui .self-baseline-m{align-self:baseline}.swagger-ui .self-stretch-m{align-self:stretch}.swagger-ui .justify-start-m{justify-content:flex-start}.swagger-ui .justify-end-m{justify-content:flex-end}.swagger-ui .justify-center-m{justify-content:center}.swagger-ui .justify-between-m{justify-content:space-between}.swagger-ui .justify-around-m{justify-content:space-around}.swagger-ui .content-start-m{align-content:flex-start}.swagger-ui .content-end-m{align-content:flex-end}.swagger-ui .content-center-m{align-content:center}.swagger-ui .content-between-m{align-content:space-between}.swagger-ui .content-around-m{align-content:space-around}.swagger-ui .content-stretch-m{align-content:stretch}.swagger-ui .order-0-m{order:0}.swagger-ui .order-1-m{order:1}.swagger-ui .order-2-m{order:2}.swagger-ui .order-3-m{order:3}.swagger-ui .order-4-m{order:4}.swagger-ui .order-5-m{order:5}.swagger-ui .order-6-m{order:6}.swagger-ui .order-7-m{order:7}.swagger-ui .order-8-m{order:8}.swagger-ui .order-last-m{order:99999}.swagger-ui .flex-grow-0-m{flex-grow:0}.swagger-ui .flex-grow-1-m{flex-grow:1}.swagger-ui .flex-shrink-0-m{flex-shrink:0}.swagger-ui .flex-shrink-1-m{flex-shrink:1}}@media screen and (min-width:60em){.swagger-ui .flex-l{display:flex}.swagger-ui .inline-flex-l{display:inline-flex}.swagger-ui .flex-auto-l{flex:1 1 auto;min-height:0;min-width:0}.swagger-ui .flex-none-l{flex:none}.swagger-ui .flex-column-l{flex-direction:column}.swagger-ui .flex-row-l{flex-direction:row}.swagger-ui .flex-wrap-l{flex-wrap:wrap}.swagger-ui .flex-nowrap-l{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse-l{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse-l{flex-direction:column-reverse}.swagger-ui .flex-row-reverse-l{flex-direction:row-reverse}.swagger-ui .items-start-l{align-items:flex-start}.swagger-ui .items-end-l{align-items:flex-end}.swagger-ui .items-center-l{align-items:center}.swagger-ui .items-baseline-l{align-items:baseline}.swagger-ui .items-stretch-l{align-items:stretch}.swagger-ui .self-start-l{align-self:flex-start}.swagger-ui .self-end-l{align-self:flex-end}.swagger-ui .self-center-l{align-self:center}.swagger-ui .self-baseline-l{align-self:baseline}.swagger-ui .self-stretch-l{align-self:stretch}.swagger-ui .justify-start-l{justify-content:flex-start}.swagger-ui .justify-end-l{justify-content:flex-end}.swagger-ui .justify-center-l{justify-content:center}.swagger-ui .justify-between-l{justify-content:space-between}.swagger-ui .justify-around-l{justify-content:space-around}.swagger-ui .content-start-l{align-content:flex-start}.swagger-ui .content-end-l{align-content:flex-end}.swagger-ui .content-center-l{align-content:center}.swagger-ui .content-between-l{align-content:space-between}.swagger-ui .content-around-l{align-content:space-around}.swagger-ui .content-stretch-l{align-content:stretch}.swagger-ui .order-0-l{order:0}.swagger-ui .order-1-l{order:1}.swagger-ui .order-2-l{order:2}.swagger-ui .order-3-l{order:3}.swagger-ui .order-4-l{order:4}.swagger-ui .order-5-l{order:5}.swagger-ui .order-6-l{order:6}.swagger-ui .order-7-l{order:7}.swagger-ui .order-8-l{order:8}.swagger-ui .order-last-l{order:99999}.swagger-ui .flex-grow-0-l{flex-grow:0}.swagger-ui .flex-grow-1-l{flex-grow:1}.swagger-ui .flex-shrink-0-l{flex-shrink:0}.swagger-ui .flex-shrink-1-l{flex-shrink:1}}.swagger-ui .dn{display:none}.swagger-ui .di{display:inline}.swagger-ui .db{display:block}.swagger-ui .dib{display:inline-block}.swagger-ui .dit{display:inline-table}.swagger-ui .dt{display:table}.swagger-ui .dtc{display:table-cell}.swagger-ui .dt-row{display:table-row}.swagger-ui .dt-row-group{display:table-row-group}.swagger-ui .dt-column{display:table-column}.swagger-ui .dt-column-group{display:table-column-group}.swagger-ui .dt--fixed{table-layout:fixed;width:100%}@media screen and (min-width:30em){.swagger-ui .dn-ns{display:none}.swagger-ui .di-ns{display:inline}.swagger-ui .db-ns{display:block}.swagger-ui .dib-ns{display:inline-block}.swagger-ui .dit-ns{display:inline-table}.swagger-ui .dt-ns{display:table}.swagger-ui .dtc-ns{display:table-cell}.swagger-ui .dt-row-ns{display:table-row}.swagger-ui .dt-row-group-ns{display:table-row-group}.swagger-ui .dt-column-ns{display:table-column}.swagger-ui .dt-column-group-ns{display:table-column-group}.swagger-ui .dt--fixed-ns{table-layout:fixed;width:100%}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .dn-m{display:none}.swagger-ui .di-m{display:inline}.swagger-ui .db-m{display:block}.swagger-ui .dib-m{display:inline-block}.swagger-ui .dit-m{display:inline-table}.swagger-ui .dt-m{display:table}.swagger-ui .dtc-m{display:table-cell}.swagger-ui .dt-row-m{display:table-row}.swagger-ui .dt-row-group-m{display:table-row-group}.swagger-ui .dt-column-m{display:table-column}.swagger-ui .dt-column-group-m{display:table-column-group}.swagger-ui .dt--fixed-m{table-layout:fixed;width:100%}}@media screen and (min-width:60em){.swagger-ui .dn-l{display:none}.swagger-ui .di-l{display:inline}.swagger-ui .db-l{display:block}.swagger-ui .dib-l{display:inline-block}.swagger-ui .dit-l{display:inline-table}.swagger-ui .dt-l{display:table}.swagger-ui .dtc-l{display:table-cell}.swagger-ui .dt-row-l{display:table-row}.swagger-ui .dt-row-group-l{display:table-row-group}.swagger-ui .dt-column-l{display:table-column}.swagger-ui .dt-column-group-l{display:table-column-group}.swagger-ui .dt--fixed-l{table-layout:fixed;width:100%}}.swagger-ui .fl{_display:inline;float:left}.swagger-ui .fr{_display:inline;float:right}.swagger-ui .fn{float:none}@media screen and (min-width:30em){.swagger-ui .fl-ns{_display:inline;float:left}.swagger-ui .fr-ns{_display:inline;float:right}.swagger-ui .fn-ns{float:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .fl-m{_display:inline;float:left}.swagger-ui .fr-m{_display:inline;float:right}.swagger-ui .fn-m{float:none}}@media screen and (min-width:60em){.swagger-ui .fl-l{_display:inline;float:left}.swagger-ui .fr-l{_display:inline;float:right}.swagger-ui .fn-l{float:none}}.swagger-ui .sans-serif{font-family:-apple-system,BlinkMacSystemFont,avenir next,avenir,helvetica,helvetica neue,ubuntu,roboto,noto,segoe ui,arial,sans-serif}.swagger-ui .serif{font-family:georgia,serif}.swagger-ui .system-sans-serif{font-family:sans-serif}.swagger-ui .system-serif{font-family:serif}.swagger-ui .code,.swagger-ui code{font-family:Consolas,monaco,monospace}.swagger-ui .courier{font-family:Courier Next,courier,monospace}.swagger-ui .helvetica{font-family:helvetica neue,helvetica,sans-serif}.swagger-ui .avenir{font-family:avenir next,avenir,sans-serif}.swagger-ui .athelas{font-family:athelas,georgia,serif}.swagger-ui .georgia{font-family:georgia,serif}.swagger-ui .times{font-family:times,serif}.swagger-ui .bodoni{font-family:Bodoni MT,serif}.swagger-ui .calisto{font-family:Calisto MT,serif}.swagger-ui .garamond{font-family:garamond,serif}.swagger-ui .baskerville{font-family:baskerville,serif}.swagger-ui .i{font-style:italic}.swagger-ui .fs-normal{font-style:normal}@media screen and (min-width:30em){.swagger-ui .i-ns{font-style:italic}.swagger-ui .fs-normal-ns{font-style:normal}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .i-m{font-style:italic}.swagger-ui .fs-normal-m{font-style:normal}}@media screen and (min-width:60em){.swagger-ui .i-l{font-style:italic}.swagger-ui .fs-normal-l{font-style:normal}}.swagger-ui .normal{font-weight:400}.swagger-ui .b{font-weight:700}.swagger-ui .fw1{font-weight:100}.swagger-ui .fw2{font-weight:200}.swagger-ui .fw3{font-weight:300}.swagger-ui .fw4{font-weight:400}.swagger-ui .fw5{font-weight:500}.swagger-ui .fw6{font-weight:600}.swagger-ui .fw7{font-weight:700}.swagger-ui .fw8{font-weight:800}.swagger-ui .fw9{font-weight:900}@media screen and (min-width:30em){.swagger-ui .normal-ns{font-weight:400}.swagger-ui .b-ns{font-weight:700}.swagger-ui .fw1-ns{font-weight:100}.swagger-ui .fw2-ns{font-weight:200}.swagger-ui .fw3-ns{font-weight:300}.swagger-ui .fw4-ns{font-weight:400}.swagger-ui .fw5-ns{font-weight:500}.swagger-ui .fw6-ns{font-weight:600}.swagger-ui .fw7-ns{font-weight:700}.swagger-ui .fw8-ns{font-weight:800}.swagger-ui .fw9-ns{font-weight:900}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .normal-m{font-weight:400}.swagger-ui .b-m{font-weight:700}.swagger-ui .fw1-m{font-weight:100}.swagger-ui .fw2-m{font-weight:200}.swagger-ui .fw3-m{font-weight:300}.swagger-ui .fw4-m{font-weight:400}.swagger-ui .fw5-m{font-weight:500}.swagger-ui .fw6-m{font-weight:600}.swagger-ui .fw7-m{font-weight:700}.swagger-ui .fw8-m{font-weight:800}.swagger-ui .fw9-m{font-weight:900}}@media screen and (min-width:60em){.swagger-ui .normal-l{font-weight:400}.swagger-ui .b-l{font-weight:700}.swagger-ui .fw1-l{font-weight:100}.swagger-ui .fw2-l{font-weight:200}.swagger-ui .fw3-l{font-weight:300}.swagger-ui .fw4-l{font-weight:400}.swagger-ui .fw5-l{font-weight:500}.swagger-ui .fw6-l{font-weight:600}.swagger-ui .fw7-l{font-weight:700}.swagger-ui .fw8-l{font-weight:800}.swagger-ui .fw9-l{font-weight:900}}.swagger-ui .input-reset{-webkit-appearance:none;-moz-appearance:none}.swagger-ui .button-reset::-moz-focus-inner,.swagger-ui .input-reset::-moz-focus-inner{border:0;padding:0}.swagger-ui .h1{height:1rem}.swagger-ui .h2{height:2rem}.swagger-ui .h3{height:4rem}.swagger-ui .h4{height:8rem}.swagger-ui .h5{height:16rem}.swagger-ui .h-25{height:25%}.swagger-ui .h-50{height:50%}.swagger-ui .h-75{height:75%}.swagger-ui .h-100{height:100%}.swagger-ui .min-h-100{min-height:100%}.swagger-ui .vh-25{height:25vh}.swagger-ui .vh-50{height:50vh}.swagger-ui .vh-75{height:75vh}.swagger-ui .vh-100{height:100vh}.swagger-ui .min-vh-100{min-height:100vh}.swagger-ui .h-auto{height:auto}.swagger-ui .h-inherit{height:inherit}@media screen and (min-width:30em){.swagger-ui .h1-ns{height:1rem}.swagger-ui .h2-ns{height:2rem}.swagger-ui .h3-ns{height:4rem}.swagger-ui .h4-ns{height:8rem}.swagger-ui .h5-ns{height:16rem}.swagger-ui .h-25-ns{height:25%}.swagger-ui .h-50-ns{height:50%}.swagger-ui .h-75-ns{height:75%}.swagger-ui .h-100-ns{height:100%}.swagger-ui .min-h-100-ns{min-height:100%}.swagger-ui .vh-25-ns{height:25vh}.swagger-ui .vh-50-ns{height:50vh}.swagger-ui .vh-75-ns{height:75vh}.swagger-ui .vh-100-ns{height:100vh}.swagger-ui .min-vh-100-ns{min-height:100vh}.swagger-ui .h-auto-ns{height:auto}.swagger-ui .h-inherit-ns{height:inherit}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .h1-m{height:1rem}.swagger-ui .h2-m{height:2rem}.swagger-ui .h3-m{height:4rem}.swagger-ui .h4-m{height:8rem}.swagger-ui .h5-m{height:16rem}.swagger-ui .h-25-m{height:25%}.swagger-ui .h-50-m{height:50%}.swagger-ui .h-75-m{height:75%}.swagger-ui .h-100-m{height:100%}.swagger-ui .min-h-100-m{min-height:100%}.swagger-ui .vh-25-m{height:25vh}.swagger-ui .vh-50-m{height:50vh}.swagger-ui .vh-75-m{height:75vh}.swagger-ui .vh-100-m{height:100vh}.swagger-ui .min-vh-100-m{min-height:100vh}.swagger-ui .h-auto-m{height:auto}.swagger-ui .h-inherit-m{height:inherit}}@media screen and (min-width:60em){.swagger-ui .h1-l{height:1rem}.swagger-ui .h2-l{height:2rem}.swagger-ui .h3-l{height:4rem}.swagger-ui .h4-l{height:8rem}.swagger-ui .h5-l{height:16rem}.swagger-ui .h-25-l{height:25%}.swagger-ui .h-50-l{height:50%}.swagger-ui .h-75-l{height:75%}.swagger-ui .h-100-l{height:100%}.swagger-ui .min-h-100-l{min-height:100%}.swagger-ui .vh-25-l{height:25vh}.swagger-ui .vh-50-l{height:50vh}.swagger-ui .vh-75-l{height:75vh}.swagger-ui .vh-100-l{height:100vh}.swagger-ui .min-vh-100-l{min-height:100vh}.swagger-ui .h-auto-l{height:auto}.swagger-ui .h-inherit-l{height:inherit}}.swagger-ui .tracked{letter-spacing:.1em}.swagger-ui .tracked-tight{letter-spacing:-.05em}.swagger-ui .tracked-mega{letter-spacing:.25em}@media screen and (min-width:30em){.swagger-ui .tracked-ns{letter-spacing:.1em}.swagger-ui .tracked-tight-ns{letter-spacing:-.05em}.swagger-ui .tracked-mega-ns{letter-spacing:.25em}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .tracked-m{letter-spacing:.1em}.swagger-ui .tracked-tight-m{letter-spacing:-.05em}.swagger-ui .tracked-mega-m{letter-spacing:.25em}}@media screen and (min-width:60em){.swagger-ui .tracked-l{letter-spacing:.1em}.swagger-ui .tracked-tight-l{letter-spacing:-.05em}.swagger-ui .tracked-mega-l{letter-spacing:.25em}}.swagger-ui .lh-solid{line-height:1}.swagger-ui .lh-title{line-height:1.25}.swagger-ui .lh-copy{line-height:1.5}@media screen and (min-width:30em){.swagger-ui .lh-solid-ns{line-height:1}.swagger-ui .lh-title-ns{line-height:1.25}.swagger-ui .lh-copy-ns{line-height:1.5}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .lh-solid-m{line-height:1}.swagger-ui .lh-title-m{line-height:1.25}.swagger-ui .lh-copy-m{line-height:1.5}}@media screen and (min-width:60em){.swagger-ui .lh-solid-l{line-height:1}.swagger-ui .lh-title-l{line-height:1.25}.swagger-ui .lh-copy-l{line-height:1.5}}.swagger-ui .link{text-decoration:none}.swagger-ui .link,.swagger-ui .link:active,.swagger-ui .link:focus,.swagger-ui .link:hover,.swagger-ui .link:link,.swagger-ui .link:visited{transition:color .15s ease-in}.swagger-ui .link:focus{outline:1px dotted currentColor}.swagger-ui .list{list-style-type:none}.swagger-ui .mw-100{max-width:100%}.swagger-ui .mw1{max-width:1rem}.swagger-ui .mw2{max-width:2rem}.swagger-ui .mw3{max-width:4rem}.swagger-ui .mw4{max-width:8rem}.swagger-ui .mw5{max-width:16rem}.swagger-ui .mw6{max-width:32rem}.swagger-ui .mw7{max-width:48rem}.swagger-ui .mw8{max-width:64rem}.swagger-ui .mw9{max-width:96rem}.swagger-ui .mw-none{max-width:none}@media screen and (min-width:30em){.swagger-ui .mw-100-ns{max-width:100%}.swagger-ui .mw1-ns{max-width:1rem}.swagger-ui .mw2-ns{max-width:2rem}.swagger-ui .mw3-ns{max-width:4rem}.swagger-ui .mw4-ns{max-width:8rem}.swagger-ui .mw5-ns{max-width:16rem}.swagger-ui .mw6-ns{max-width:32rem}.swagger-ui .mw7-ns{max-width:48rem}.swagger-ui .mw8-ns{max-width:64rem}.swagger-ui .mw9-ns{max-width:96rem}.swagger-ui .mw-none-ns{max-width:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .mw-100-m{max-width:100%}.swagger-ui .mw1-m{max-width:1rem}.swagger-ui .mw2-m{max-width:2rem}.swagger-ui .mw3-m{max-width:4rem}.swagger-ui .mw4-m{max-width:8rem}.swagger-ui .mw5-m{max-width:16rem}.swagger-ui .mw6-m{max-width:32rem}.swagger-ui .mw7-m{max-width:48rem}.swagger-ui .mw8-m{max-width:64rem}.swagger-ui .mw9-m{max-width:96rem}.swagger-ui .mw-none-m{max-width:none}}@media screen and (min-width:60em){.swagger-ui .mw-100-l{max-width:100%}.swagger-ui .mw1-l{max-width:1rem}.swagger-ui .mw2-l{max-width:2rem}.swagger-ui .mw3-l{max-width:4rem}.swagger-ui .mw4-l{max-width:8rem}.swagger-ui .mw5-l{max-width:16rem}.swagger-ui .mw6-l{max-width:32rem}.swagger-ui .mw7-l{max-width:48rem}.swagger-ui .mw8-l{max-width:64rem}.swagger-ui .mw9-l{max-width:96rem}.swagger-ui .mw-none-l{max-width:none}}.swagger-ui .w1{width:1rem}.swagger-ui .w2{width:2rem}.swagger-ui .w3{width:4rem}.swagger-ui .w4{width:8rem}.swagger-ui .w5{width:16rem}.swagger-ui .w-10{width:10%}.swagger-ui .w-20{width:20%}.swagger-ui .w-25{width:25%}.swagger-ui .w-30{width:30%}.swagger-ui .w-33{width:33%}.swagger-ui .w-34{width:34%}.swagger-ui .w-40{width:40%}.swagger-ui .w-50{width:50%}.swagger-ui .w-60{width:60%}.swagger-ui .w-70{width:70%}.swagger-ui .w-75{width:75%}.swagger-ui .w-80{width:80%}.swagger-ui .w-90{width:90%}.swagger-ui .w-100{width:100%}.swagger-ui .w-third{width:33.3333333333%}.swagger-ui .w-two-thirds{width:66.6666666667%}.swagger-ui .w-auto{width:auto}@media screen and (min-width:30em){.swagger-ui .w1-ns{width:1rem}.swagger-ui .w2-ns{width:2rem}.swagger-ui .w3-ns{width:4rem}.swagger-ui .w4-ns{width:8rem}.swagger-ui .w5-ns{width:16rem}.swagger-ui .w-10-ns{width:10%}.swagger-ui .w-20-ns{width:20%}.swagger-ui .w-25-ns{width:25%}.swagger-ui .w-30-ns{width:30%}.swagger-ui .w-33-ns{width:33%}.swagger-ui .w-34-ns{width:34%}.swagger-ui .w-40-ns{width:40%}.swagger-ui .w-50-ns{width:50%}.swagger-ui .w-60-ns{width:60%}.swagger-ui .w-70-ns{width:70%}.swagger-ui .w-75-ns{width:75%}.swagger-ui .w-80-ns{width:80%}.swagger-ui .w-90-ns{width:90%}.swagger-ui .w-100-ns{width:100%}.swagger-ui .w-third-ns{width:33.3333333333%}.swagger-ui .w-two-thirds-ns{width:66.6666666667%}.swagger-ui .w-auto-ns{width:auto}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .w1-m{width:1rem}.swagger-ui .w2-m{width:2rem}.swagger-ui .w3-m{width:4rem}.swagger-ui .w4-m{width:8rem}.swagger-ui .w5-m{width:16rem}.swagger-ui .w-10-m{width:10%}.swagger-ui .w-20-m{width:20%}.swagger-ui .w-25-m{width:25%}.swagger-ui .w-30-m{width:30%}.swagger-ui .w-33-m{width:33%}.swagger-ui .w-34-m{width:34%}.swagger-ui .w-40-m{width:40%}.swagger-ui .w-50-m{width:50%}.swagger-ui .w-60-m{width:60%}.swagger-ui .w-70-m{width:70%}.swagger-ui .w-75-m{width:75%}.swagger-ui .w-80-m{width:80%}.swagger-ui .w-90-m{width:90%}.swagger-ui .w-100-m{width:100%}.swagger-ui .w-third-m{width:33.3333333333%}.swagger-ui .w-two-thirds-m{width:66.6666666667%}.swagger-ui .w-auto-m{width:auto}}@media screen and (min-width:60em){.swagger-ui .w1-l{width:1rem}.swagger-ui .w2-l{width:2rem}.swagger-ui .w3-l{width:4rem}.swagger-ui .w4-l{width:8rem}.swagger-ui .w5-l{width:16rem}.swagger-ui .w-10-l{width:10%}.swagger-ui .w-20-l{width:20%}.swagger-ui .w-25-l{width:25%}.swagger-ui .w-30-l{width:30%}.swagger-ui .w-33-l{width:33%}.swagger-ui .w-34-l{width:34%}.swagger-ui .w-40-l{width:40%}.swagger-ui .w-50-l{width:50%}.swagger-ui .w-60-l{width:60%}.swagger-ui .w-70-l{width:70%}.swagger-ui .w-75-l{width:75%}.swagger-ui .w-80-l{width:80%}.swagger-ui .w-90-l{width:90%}.swagger-ui .w-100-l{width:100%}.swagger-ui .w-third-l{width:33.3333333333%}.swagger-ui .w-two-thirds-l{width:66.6666666667%}.swagger-ui .w-auto-l{width:auto}}.swagger-ui .overflow-visible{overflow:visible}.swagger-ui .overflow-hidden{overflow:hidden}.swagger-ui .overflow-scroll{overflow:scroll}.swagger-ui .overflow-auto{overflow:auto}.swagger-ui .overflow-x-visible{overflow-x:visible}.swagger-ui .overflow-x-hidden{overflow-x:hidden}.swagger-ui .overflow-x-scroll{overflow-x:scroll}.swagger-ui .overflow-x-auto{overflow-x:auto}.swagger-ui .overflow-y-visible{overflow-y:visible}.swagger-ui .overflow-y-hidden{overflow-y:hidden}.swagger-ui .overflow-y-scroll{overflow-y:scroll}.swagger-ui .overflow-y-auto{overflow-y:auto}@media screen and (min-width:30em){.swagger-ui .overflow-visible-ns{overflow:visible}.swagger-ui .overflow-hidden-ns{overflow:hidden}.swagger-ui .overflow-scroll-ns{overflow:scroll}.swagger-ui .overflow-auto-ns{overflow:auto}.swagger-ui .overflow-x-visible-ns{overflow-x:visible}.swagger-ui .overflow-x-hidden-ns{overflow-x:hidden}.swagger-ui .overflow-x-scroll-ns{overflow-x:scroll}.swagger-ui .overflow-x-auto-ns{overflow-x:auto}.swagger-ui .overflow-y-visible-ns{overflow-y:visible}.swagger-ui .overflow-y-hidden-ns{overflow-y:hidden}.swagger-ui .overflow-y-scroll-ns{overflow-y:scroll}.swagger-ui .overflow-y-auto-ns{overflow-y:auto}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .overflow-visible-m{overflow:visible}.swagger-ui .overflow-hidden-m{overflow:hidden}.swagger-ui .overflow-scroll-m{overflow:scroll}.swagger-ui .overflow-auto-m{overflow:auto}.swagger-ui .overflow-x-visible-m{overflow-x:visible}.swagger-ui .overflow-x-hidden-m{overflow-x:hidden}.swagger-ui .overflow-x-scroll-m{overflow-x:scroll}.swagger-ui .overflow-x-auto-m{overflow-x:auto}.swagger-ui .overflow-y-visible-m{overflow-y:visible}.swagger-ui .overflow-y-hidden-m{overflow-y:hidden}.swagger-ui .overflow-y-scroll-m{overflow-y:scroll}.swagger-ui .overflow-y-auto-m{overflow-y:auto}}@media screen and (min-width:60em){.swagger-ui .overflow-visible-l{overflow:visible}.swagger-ui .overflow-hidden-l{overflow:hidden}.swagger-ui .overflow-scroll-l{overflow:scroll}.swagger-ui .overflow-auto-l{overflow:auto}.swagger-ui .overflow-x-visible-l{overflow-x:visible}.swagger-ui .overflow-x-hidden-l{overflow-x:hidden}.swagger-ui .overflow-x-scroll-l{overflow-x:scroll}.swagger-ui .overflow-x-auto-l{overflow-x:auto}.swagger-ui .overflow-y-visible-l{overflow-y:visible}.swagger-ui .overflow-y-hidden-l{overflow-y:hidden}.swagger-ui .overflow-y-scroll-l{overflow-y:scroll}.swagger-ui .overflow-y-auto-l{overflow-y:auto}}.swagger-ui .static{position:static}.swagger-ui .relative{position:relative}.swagger-ui .absolute{position:absolute}.swagger-ui .fixed{position:fixed}@media screen and (min-width:30em){.swagger-ui .static-ns{position:static}.swagger-ui .relative-ns{position:relative}.swagger-ui .absolute-ns{position:absolute}.swagger-ui .fixed-ns{position:fixed}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .static-m{position:static}.swagger-ui .relative-m{position:relative}.swagger-ui .absolute-m{position:absolute}.swagger-ui .fixed-m{position:fixed}}@media screen and (min-width:60em){.swagger-ui .static-l{position:static}.swagger-ui .relative-l{position:relative}.swagger-ui .absolute-l{position:absolute}.swagger-ui .fixed-l{position:fixed}}.swagger-ui .o-100{opacity:1}.swagger-ui .o-90{opacity:.9}.swagger-ui .o-80{opacity:.8}.swagger-ui .o-70{opacity:.7}.swagger-ui .o-60{opacity:.6}.swagger-ui .o-50{opacity:.5}.swagger-ui .o-40{opacity:.4}.swagger-ui .o-30{opacity:.3}.swagger-ui .o-20{opacity:.2}.swagger-ui .o-10{opacity:.1}.swagger-ui .o-05{opacity:.05}.swagger-ui .o-025{opacity:.025}.swagger-ui .o-0{opacity:0}.swagger-ui .rotate-45{transform:rotate(45deg)}.swagger-ui .rotate-90{transform:rotate(90deg)}.swagger-ui .rotate-135{transform:rotate(135deg)}.swagger-ui .rotate-180{transform:rotate(180deg)}.swagger-ui .rotate-225{transform:rotate(225deg)}.swagger-ui .rotate-270{transform:rotate(270deg)}.swagger-ui .rotate-315{transform:rotate(315deg)}@media screen and (min-width:30em){.swagger-ui .rotate-45-ns{transform:rotate(45deg)}.swagger-ui .rotate-90-ns{transform:rotate(90deg)}.swagger-ui .rotate-135-ns{transform:rotate(135deg)}.swagger-ui .rotate-180-ns{transform:rotate(180deg)}.swagger-ui .rotate-225-ns{transform:rotate(225deg)}.swagger-ui .rotate-270-ns{transform:rotate(270deg)}.swagger-ui .rotate-315-ns{transform:rotate(315deg)}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .rotate-45-m{transform:rotate(45deg)}.swagger-ui .rotate-90-m{transform:rotate(90deg)}.swagger-ui .rotate-135-m{transform:rotate(135deg)}.swagger-ui .rotate-180-m{transform:rotate(180deg)}.swagger-ui .rotate-225-m{transform:rotate(225deg)}.swagger-ui .rotate-270-m{transform:rotate(270deg)}.swagger-ui .rotate-315-m{transform:rotate(315deg)}}@media screen and (min-width:60em){.swagger-ui .rotate-45-l{transform:rotate(45deg)}.swagger-ui .rotate-90-l{transform:rotate(90deg)}.swagger-ui .rotate-135-l{transform:rotate(135deg)}.swagger-ui .rotate-180-l{transform:rotate(180deg)}.swagger-ui .rotate-225-l{transform:rotate(225deg)}.swagger-ui .rotate-270-l{transform:rotate(270deg)}.swagger-ui .rotate-315-l{transform:rotate(315deg)}}.swagger-ui .black-90{color:#000000e6}.swagger-ui .black-80{color:#000c}.swagger-ui .black-70{color:#000000b3}.swagger-ui .black-60{color:#0009}.swagger-ui .black-50{color:#00000080}.swagger-ui .black-40{color:#0006}.swagger-ui .black-30{color:#0000004d}.swagger-ui .black-20{color:#0003}.swagger-ui .black-10{color:#0000001a}.swagger-ui .black-05{color:#0000000d}.swagger-ui .white-90{color:#ffffffe6}.swagger-ui .white-80{color:#fffc}.swagger-ui .white-70{color:#ffffffb3}.swagger-ui .white-60{color:#fff9}.swagger-ui .white-50{color:#ffffff80}.swagger-ui .white-40{color:#fff6}.swagger-ui .white-30{color:#ffffff4d}.swagger-ui .white-20{color:#fff3}.swagger-ui .white-10{color:#ffffff1a}.swagger-ui .black{color:#000}.swagger-ui .near-black{color:#111}.swagger-ui .dark-gray{color:#333}.swagger-ui .mid-gray{color:#555}.swagger-ui .gray{color:#777}.swagger-ui .silver{color:#999}.swagger-ui .light-silver{color:#aaa}.swagger-ui .moon-gray{color:#ccc}.swagger-ui .light-gray{color:#eee}.swagger-ui .near-white{color:#f4f4f4}.swagger-ui .white{color:#fff}.swagger-ui .dark-red{color:#e7040f}.swagger-ui .red{color:#ff4136}.swagger-ui .light-red{color:#ff725c}.swagger-ui .orange{color:#ff6300}.swagger-ui .gold{color:#ffb700}.swagger-ui .yellow{color:gold}.swagger-ui .light-yellow{color:#fbf1a9}.swagger-ui .purple{color:#5e2ca5}.swagger-ui .light-purple{color:#a463f2}.swagger-ui .dark-pink{color:#d5008f}.swagger-ui .hot-pink{color:#ff41b4}.swagger-ui .pink{color:#ff80cc}.swagger-ui .light-pink{color:#ffa3d7}.swagger-ui .dark-green{color:#137752}.swagger-ui .green{color:#19a974}.swagger-ui .light-green{color:#9eebcf}.swagger-ui .navy{color:#001b44}.swagger-ui .dark-blue{color:#00449e}.swagger-ui .blue{color:#357edd}.swagger-ui .light-blue{color:#96ccff}.swagger-ui .lightest-blue{color:#cdecff}.swagger-ui .washed-blue{color:#f6fffe}.swagger-ui .washed-green{color:#e8fdf5}.swagger-ui .washed-yellow{color:#fffceb}.swagger-ui .washed-red{color:#ffdfdf}.swagger-ui .color-inherit{color:inherit}.swagger-ui .bg-black-90{background-color:#000000e6}.swagger-ui .bg-black-80{background-color:#000c}.swagger-ui .bg-black-70{background-color:#000000b3}.swagger-ui .bg-black-60{background-color:#0009}.swagger-ui .bg-black-50{background-color:#00000080}.swagger-ui .bg-black-40{background-color:#0006}.swagger-ui .bg-black-30{background-color:#0000004d}.swagger-ui .bg-black-20{background-color:#0003}.swagger-ui .bg-black-10{background-color:#0000001a}.swagger-ui .bg-black-05{background-color:#0000000d}.swagger-ui .bg-white-90{background-color:#ffffffe6}.swagger-ui .bg-white-80{background-color:#fffc}.swagger-ui .bg-white-70{background-color:#ffffffb3}.swagger-ui .bg-white-60{background-color:#fff9}.swagger-ui .bg-white-50{background-color:#ffffff80}.swagger-ui .bg-white-40{background-color:#fff6}.swagger-ui .bg-white-30{background-color:#ffffff4d}.swagger-ui .bg-white-20{background-color:#fff3}.swagger-ui .bg-white-10{background-color:#ffffff1a}.swagger-ui .bg-black{background-color:#000}.swagger-ui .bg-near-black{background-color:#111}.swagger-ui .bg-dark-gray{background-color:#333}.swagger-ui .bg-mid-gray{background-color:#555}.swagger-ui .bg-gray{background-color:#777}.swagger-ui .bg-silver{background-color:#999}.swagger-ui .bg-light-silver{background-color:#aaa}.swagger-ui .bg-moon-gray{background-color:#ccc}.swagger-ui .bg-light-gray{background-color:#eee}.swagger-ui .bg-near-white{background-color:#f4f4f4}.swagger-ui .bg-white{background-color:#fff}.swagger-ui .bg-transparent{background-color:initial}.swagger-ui .bg-dark-red{background-color:#e7040f}.swagger-ui .bg-red{background-color:#ff4136}.swagger-ui .bg-light-red{background-color:#ff725c}.swagger-ui .bg-orange{background-color:#ff6300}.swagger-ui .bg-gold{background-color:#ffb700}.swagger-ui .bg-yellow{background-color:gold}.swagger-ui .bg-light-yellow{background-color:#fbf1a9}.swagger-ui .bg-purple{background-color:#5e2ca5}.swagger-ui .bg-light-purple{background-color:#a463f2}.swagger-ui .bg-dark-pink{background-color:#d5008f}.swagger-ui .bg-hot-pink{background-color:#ff41b4}.swagger-ui .bg-pink{background-color:#ff80cc}.swagger-ui .bg-light-pink{background-color:#ffa3d7}.swagger-ui .bg-dark-green{background-color:#137752}.swagger-ui .bg-green{background-color:#19a974}.swagger-ui .bg-light-green{background-color:#9eebcf}.swagger-ui .bg-navy{background-color:#001b44}.swagger-ui .bg-dark-blue{background-color:#00449e}.swagger-ui .bg-blue{background-color:#357edd}.swagger-ui .bg-light-blue{background-color:#96ccff}.swagger-ui .bg-lightest-blue{background-color:#cdecff}.swagger-ui .bg-washed-blue{background-color:#f6fffe}.swagger-ui .bg-washed-green{background-color:#e8fdf5}.swagger-ui .bg-washed-yellow{background-color:#fffceb}.swagger-ui .bg-washed-red{background-color:#ffdfdf}.swagger-ui .bg-inherit{background-color:inherit}.swagger-ui .hover-black:focus,.swagger-ui .hover-black:hover{color:#000}.swagger-ui .hover-near-black:focus,.swagger-ui .hover-near-black:hover{color:#111}.swagger-ui .hover-dark-gray:focus,.swagger-ui .hover-dark-gray:hover{color:#333}.swagger-ui .hover-mid-gray:focus,.swagger-ui .hover-mid-gray:hover{color:#555}.swagger-ui .hover-gray:focus,.swagger-ui .hover-gray:hover{color:#777}.swagger-ui .hover-silver:focus,.swagger-ui .hover-silver:hover{color:#999}.swagger-ui .hover-light-silver:focus,.swagger-ui .hover-light-silver:hover{color:#aaa}.swagger-ui .hover-moon-gray:focus,.swagger-ui .hover-moon-gray:hover{color:#ccc}.swagger-ui .hover-light-gray:focus,.swagger-ui .hover-light-gray:hover{color:#eee}.swagger-ui .hover-near-white:focus,.swagger-ui .hover-near-white:hover{color:#f4f4f4}.swagger-ui .hover-white:focus,.swagger-ui .hover-white:hover{color:#fff}.swagger-ui .hover-black-90:focus,.swagger-ui .hover-black-90:hover{color:#000000e6}.swagger-ui .hover-black-80:focus,.swagger-ui .hover-black-80:hover{color:#000c}.swagger-ui .hover-black-70:focus,.swagger-ui .hover-black-70:hover{color:#000000b3}.swagger-ui .hover-black-60:focus,.swagger-ui .hover-black-60:hover{color:#0009}.swagger-ui .hover-black-50:focus,.swagger-ui .hover-black-50:hover{color:#00000080}.swagger-ui .hover-black-40:focus,.swagger-ui .hover-black-40:hover{color:#0006}.swagger-ui .hover-black-30:focus,.swagger-ui .hover-black-30:hover{color:#0000004d}.swagger-ui .hover-black-20:focus,.swagger-ui .hover-black-20:hover{color:#0003}.swagger-ui .hover-black-10:focus,.swagger-ui .hover-black-10:hover{color:#0000001a}.swagger-ui .hover-white-90:focus,.swagger-ui .hover-white-90:hover{color:#ffffffe6}.swagger-ui .hover-white-80:focus,.swagger-ui .hover-white-80:hover{color:#fffc}.swagger-ui .hover-white-70:focus,.swagger-ui .hover-white-70:hover{color:#ffffffb3}.swagger-ui .hover-white-60:focus,.swagger-ui .hover-white-60:hover{color:#fff9}.swagger-ui .hover-white-50:focus,.swagger-ui .hover-white-50:hover{color:#ffffff80}.swagger-ui .hover-white-40:focus,.swagger-ui .hover-white-40:hover{color:#fff6}.swagger-ui .hover-white-30:focus,.swagger-ui .hover-white-30:hover{color:#ffffff4d}.swagger-ui .hover-white-20:focus,.swagger-ui .hover-white-20:hover{color:#fff3}.swagger-ui .hover-white-10:focus,.swagger-ui .hover-white-10:hover{color:#ffffff1a}.swagger-ui .hover-inherit:focus,.swagger-ui .hover-inherit:hover{color:inherit}.swagger-ui .hover-bg-black:focus,.swagger-ui .hover-bg-black:hover{background-color:#000}.swagger-ui .hover-bg-near-black:focus,.swagger-ui .hover-bg-near-black:hover{background-color:#111}.swagger-ui .hover-bg-dark-gray:focus,.swagger-ui .hover-bg-dark-gray:hover{background-color:#333}.swagger-ui .hover-bg-mid-gray:focus,.swagger-ui .hover-bg-mid-gray:hover{background-color:#555}.swagger-ui .hover-bg-gray:focus,.swagger-ui .hover-bg-gray:hover{background-color:#777}.swagger-ui .hover-bg-silver:focus,.swagger-ui .hover-bg-silver:hover{background-color:#999}.swagger-ui .hover-bg-light-silver:focus,.swagger-ui .hover-bg-light-silver:hover{background-color:#aaa}.swagger-ui .hover-bg-moon-gray:focus,.swagger-ui .hover-bg-moon-gray:hover{background-color:#ccc}.swagger-ui .hover-bg-light-gray:focus,.swagger-ui .hover-bg-light-gray:hover{background-color:#eee}.swagger-ui .hover-bg-near-white:focus,.swagger-ui .hover-bg-near-white:hover{background-color:#f4f4f4}.swagger-ui .hover-bg-white:focus,.swagger-ui .hover-bg-white:hover{background-color:#fff}.swagger-ui .hover-bg-transparent:focus,.swagger-ui .hover-bg-transparent:hover{background-color:initial}.swagger-ui .hover-bg-black-90:focus,.swagger-ui .hover-bg-black-90:hover{background-color:#000000e6}.swagger-ui .hover-bg-black-80:focus,.swagger-ui .hover-bg-black-80:hover{background-color:#000c}.swagger-ui .hover-bg-black-70:focus,.swagger-ui .hover-bg-black-70:hover{background-color:#000000b3}.swagger-ui .hover-bg-black-60:focus,.swagger-ui .hover-bg-black-60:hover{background-color:#0009}.swagger-ui .hover-bg-black-50:focus,.swagger-ui .hover-bg-black-50:hover{background-color:#00000080}.swagger-ui .hover-bg-black-40:focus,.swagger-ui .hover-bg-black-40:hover{background-color:#0006}.swagger-ui .hover-bg-black-30:focus,.swagger-ui .hover-bg-black-30:hover{background-color:#0000004d}.swagger-ui .hover-bg-black-20:focus,.swagger-ui .hover-bg-black-20:hover{background-color:#0003}.swagger-ui .hover-bg-black-10:focus,.swagger-ui .hover-bg-black-10:hover{background-color:#0000001a}.swagger-ui .hover-bg-white-90:focus,.swagger-ui .hover-bg-white-90:hover{background-color:#ffffffe6}.swagger-ui .hover-bg-white-80:focus,.swagger-ui .hover-bg-white-80:hover{background-color:#fffc}.swagger-ui .hover-bg-white-70:focus,.swagger-ui .hover-bg-white-70:hover{background-color:#ffffffb3}.swagger-ui .hover-bg-white-60:focus,.swagger-ui .hover-bg-white-60:hover{background-color:#fff9}.swagger-ui .hover-bg-white-50:focus,.swagger-ui .hover-bg-white-50:hover{background-color:#ffffff80}.swagger-ui .hover-bg-white-40:focus,.swagger-ui .hover-bg-white-40:hover{background-color:#fff6}.swagger-ui .hover-bg-white-30:focus,.swagger-ui .hover-bg-white-30:hover{background-color:#ffffff4d}.swagger-ui .hover-bg-white-20:focus,.swagger-ui .hover-bg-white-20:hover{background-color:#fff3}.swagger-ui .hover-bg-white-10:focus,.swagger-ui .hover-bg-white-10:hover{background-color:#ffffff1a}.swagger-ui .hover-dark-red:focus,.swagger-ui .hover-dark-red:hover{color:#e7040f}.swagger-ui .hover-red:focus,.swagger-ui .hover-red:hover{color:#ff4136}.swagger-ui .hover-light-red:focus,.swagger-ui .hover-light-red:hover{color:#ff725c}.swagger-ui .hover-orange:focus,.swagger-ui .hover-orange:hover{color:#ff6300}.swagger-ui .hover-gold:focus,.swagger-ui .hover-gold:hover{color:#ffb700}.swagger-ui .hover-yellow:focus,.swagger-ui .hover-yellow:hover{color:gold}.swagger-ui .hover-light-yellow:focus,.swagger-ui .hover-light-yellow:hover{color:#fbf1a9}.swagger-ui .hover-purple:focus,.swagger-ui .hover-purple:hover{color:#5e2ca5}.swagger-ui .hover-light-purple:focus,.swagger-ui .hover-light-purple:hover{color:#a463f2}.swagger-ui .hover-dark-pink:focus,.swagger-ui .hover-dark-pink:hover{color:#d5008f}.swagger-ui .hover-hot-pink:focus,.swagger-ui .hover-hot-pink:hover{color:#ff41b4}.swagger-ui .hover-pink:focus,.swagger-ui .hover-pink:hover{color:#ff80cc}.swagger-ui .hover-light-pink:focus,.swagger-ui .hover-light-pink:hover{color:#ffa3d7}.swagger-ui .hover-dark-green:focus,.swagger-ui .hover-dark-green:hover{color:#137752}.swagger-ui .hover-green:focus,.swagger-ui .hover-green:hover{color:#19a974}.swagger-ui .hover-light-green:focus,.swagger-ui .hover-light-green:hover{color:#9eebcf}.swagger-ui .hover-navy:focus,.swagger-ui .hover-navy:hover{color:#001b44}.swagger-ui .hover-dark-blue:focus,.swagger-ui .hover-dark-blue:hover{color:#00449e}.swagger-ui .hover-blue:focus,.swagger-ui .hover-blue:hover{color:#357edd}.swagger-ui .hover-light-blue:focus,.swagger-ui .hover-light-blue:hover{color:#96ccff}.swagger-ui .hover-lightest-blue:focus,.swagger-ui .hover-lightest-blue:hover{color:#cdecff}.swagger-ui .hover-washed-blue:focus,.swagger-ui .hover-washed-blue:hover{color:#f6fffe}.swagger-ui .hover-washed-green:focus,.swagger-ui .hover-washed-green:hover{color:#e8fdf5}.swagger-ui .hover-washed-yellow:focus,.swagger-ui .hover-washed-yellow:hover{color:#fffceb}.swagger-ui .hover-washed-red:focus,.swagger-ui .hover-washed-red:hover{color:#ffdfdf}.swagger-ui .hover-bg-dark-red:focus,.swagger-ui .hover-bg-dark-red:hover{background-color:#e7040f}.swagger-ui .hover-bg-red:focus,.swagger-ui .hover-bg-red:hover{background-color:#ff4136}.swagger-ui .hover-bg-light-red:focus,.swagger-ui .hover-bg-light-red:hover{background-color:#ff725c}.swagger-ui .hover-bg-orange:focus,.swagger-ui .hover-bg-orange:hover{background-color:#ff6300}.swagger-ui .hover-bg-gold:focus,.swagger-ui .hover-bg-gold:hover{background-color:#ffb700}.swagger-ui .hover-bg-yellow:focus,.swagger-ui .hover-bg-yellow:hover{background-color:gold}.swagger-ui .hover-bg-light-yellow:focus,.swagger-ui .hover-bg-light-yellow:hover{background-color:#fbf1a9}.swagger-ui .hover-bg-purple:focus,.swagger-ui .hover-bg-purple:hover{background-color:#5e2ca5}.swagger-ui .hover-bg-light-purple:focus,.swagger-ui .hover-bg-light-purple:hover{background-color:#a463f2}.swagger-ui .hover-bg-dark-pink:focus,.swagger-ui .hover-bg-dark-pink:hover{background-color:#d5008f}.swagger-ui .hover-bg-hot-pink:focus,.swagger-ui .hover-bg-hot-pink:hover{background-color:#ff41b4}.swagger-ui .hover-bg-pink:focus,.swagger-ui .hover-bg-pink:hover{background-color:#ff80cc}.swagger-ui .hover-bg-light-pink:focus,.swagger-ui .hover-bg-light-pink:hover{background-color:#ffa3d7}.swagger-ui .hover-bg-dark-green:focus,.swagger-ui .hover-bg-dark-green:hover{background-color:#137752}.swagger-ui .hover-bg-green:focus,.swagger-ui .hover-bg-green:hover{background-color:#19a974}.swagger-ui .hover-bg-light-green:focus,.swagger-ui .hover-bg-light-green:hover{background-color:#9eebcf}.swagger-ui .hover-bg-navy:focus,.swagger-ui .hover-bg-navy:hover{background-color:#001b44}.swagger-ui .hover-bg-dark-blue:focus,.swagger-ui .hover-bg-dark-blue:hover{background-color:#00449e}.swagger-ui .hover-bg-blue:focus,.swagger-ui .hover-bg-blue:hover{background-color:#357edd}.swagger-ui .hover-bg-light-blue:focus,.swagger-ui .hover-bg-light-blue:hover{background-color:#96ccff}.swagger-ui .hover-bg-lightest-blue:focus,.swagger-ui .hover-bg-lightest-blue:hover{background-color:#cdecff}.swagger-ui .hover-bg-washed-blue:focus,.swagger-ui .hover-bg-washed-blue:hover{background-color:#f6fffe}.swagger-ui .hover-bg-washed-green:focus,.swagger-ui .hover-bg-washed-green:hover{background-color:#e8fdf5}.swagger-ui .hover-bg-washed-yellow:focus,.swagger-ui .hover-bg-washed-yellow:hover{background-color:#fffceb}.swagger-ui .hover-bg-washed-red:focus,.swagger-ui .hover-bg-washed-red:hover{background-color:#ffdfdf}.swagger-ui .hover-bg-inherit:focus,.swagger-ui .hover-bg-inherit:hover{background-color:inherit}.swagger-ui .pa0{padding:0}.swagger-ui .pa1{padding:.25rem}.swagger-ui .pa2{padding:.5rem}.swagger-ui .pa3{padding:1rem}.swagger-ui .pa4{padding:2rem}.swagger-ui .pa5{padding:4rem}.swagger-ui .pa6{padding:8rem}.swagger-ui .pa7{padding:16rem}.swagger-ui .pl0{padding-left:0}.swagger-ui .pl1{padding-left:.25rem}.swagger-ui .pl2{padding-left:.5rem}.swagger-ui .pl3{padding-left:1rem}.swagger-ui .pl4{padding-left:2rem}.swagger-ui .pl5{padding-left:4rem}.swagger-ui .pl6{padding-left:8rem}.swagger-ui .pl7{padding-left:16rem}.swagger-ui .pr0{padding-right:0}.swagger-ui .pr1{padding-right:.25rem}.swagger-ui .pr2{padding-right:.5rem}.swagger-ui .pr3{padding-right:1rem}.swagger-ui .pr4{padding-right:2rem}.swagger-ui .pr5{padding-right:4rem}.swagger-ui .pr6{padding-right:8rem}.swagger-ui .pr7{padding-right:16rem}.swagger-ui .pb0{padding-bottom:0}.swagger-ui .pb1{padding-bottom:.25rem}.swagger-ui .pb2{padding-bottom:.5rem}.swagger-ui .pb3{padding-bottom:1rem}.swagger-ui .pb4{padding-bottom:2rem}.swagger-ui .pb5{padding-bottom:4rem}.swagger-ui .pb6{padding-bottom:8rem}.swagger-ui .pb7{padding-bottom:16rem}.swagger-ui .pt0{padding-top:0}.swagger-ui .pt1{padding-top:.25rem}.swagger-ui .pt2{padding-top:.5rem}.swagger-ui .pt3{padding-top:1rem}.swagger-ui .pt4{padding-top:2rem}.swagger-ui .pt5{padding-top:4rem}.swagger-ui .pt6{padding-top:8rem}.swagger-ui .pt7{padding-top:16rem}.swagger-ui .pv0{padding-bottom:0;padding-top:0}.swagger-ui .pv1{padding-bottom:.25rem;padding-top:.25rem}.swagger-ui .pv2{padding-bottom:.5rem;padding-top:.5rem}.swagger-ui .pv3{padding-bottom:1rem;padding-top:1rem}.swagger-ui .pv4{padding-bottom:2rem;padding-top:2rem}.swagger-ui .pv5{padding-bottom:4rem;padding-top:4rem}.swagger-ui .pv6{padding-bottom:8rem;padding-top:8rem}.swagger-ui .pv7{padding-bottom:16rem;padding-top:16rem}.swagger-ui .ph0{padding-left:0;padding-right:0}.swagger-ui .ph1{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0{margin:0}.swagger-ui .ma1{margin:.25rem}.swagger-ui .ma2{margin:.5rem}.swagger-ui .ma3{margin:1rem}.swagger-ui .ma4{margin:2rem}.swagger-ui .ma5{margin:4rem}.swagger-ui .ma6{margin:8rem}.swagger-ui .ma7{margin:16rem}.swagger-ui .ml0{margin-left:0}.swagger-ui .ml1{margin-left:.25rem}.swagger-ui .ml2{margin-left:.5rem}.swagger-ui .ml3{margin-left:1rem}.swagger-ui .ml4{margin-left:2rem}.swagger-ui .ml5{margin-left:4rem}.swagger-ui .ml6{margin-left:8rem}.swagger-ui .ml7{margin-left:16rem}.swagger-ui .mr0{margin-right:0}.swagger-ui .mr1{margin-right:.25rem}.swagger-ui .mr2{margin-right:.5rem}.swagger-ui .mr3{margin-right:1rem}.swagger-ui .mr4{margin-right:2rem}.swagger-ui .mr5{margin-right:4rem}.swagger-ui .mr6{margin-right:8rem}.swagger-ui .mr7{margin-right:16rem}.swagger-ui .mb0{margin-bottom:0}.swagger-ui .mb1{margin-bottom:.25rem}.swagger-ui .mb2{margin-bottom:.5rem}.swagger-ui .mb3{margin-bottom:1rem}.swagger-ui .mb4{margin-bottom:2rem}.swagger-ui .mb5{margin-bottom:4rem}.swagger-ui .mb6{margin-bottom:8rem}.swagger-ui .mb7{margin-bottom:16rem}.swagger-ui .mt0{margin-top:0}.swagger-ui .mt1{margin-top:.25rem}.swagger-ui .mt2{margin-top:.5rem}.swagger-ui .mt3{margin-top:1rem}.swagger-ui .mt4{margin-top:2rem}.swagger-ui .mt5{margin-top:4rem}.swagger-ui .mt6{margin-top:8rem}.swagger-ui .mt7{margin-top:16rem}.swagger-ui .mv0{margin-bottom:0;margin-top:0}.swagger-ui .mv1{margin-bottom:.25rem;margin-top:.25rem}.swagger-ui .mv2{margin-bottom:.5rem;margin-top:.5rem}.swagger-ui .mv3{margin-bottom:1rem;margin-top:1rem}.swagger-ui .mv4{margin-bottom:2rem;margin-top:2rem}.swagger-ui .mv5{margin-bottom:4rem;margin-top:4rem}.swagger-ui .mv6{margin-bottom:8rem;margin-top:8rem}.swagger-ui .mv7{margin-bottom:16rem;margin-top:16rem}.swagger-ui .mh0{margin-left:0;margin-right:0}.swagger-ui .mh1{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7{margin-left:16rem;margin-right:16rem}@media screen and (min-width:30em){.swagger-ui .pa0-ns{padding:0}.swagger-ui .pa1-ns{padding:.25rem}.swagger-ui .pa2-ns{padding:.5rem}.swagger-ui .pa3-ns{padding:1rem}.swagger-ui .pa4-ns{padding:2rem}.swagger-ui .pa5-ns{padding:4rem}.swagger-ui .pa6-ns{padding:8rem}.swagger-ui .pa7-ns{padding:16rem}.swagger-ui .pl0-ns{padding-left:0}.swagger-ui .pl1-ns{padding-left:.25rem}.swagger-ui .pl2-ns{padding-left:.5rem}.swagger-ui .pl3-ns{padding-left:1rem}.swagger-ui .pl4-ns{padding-left:2rem}.swagger-ui .pl5-ns{padding-left:4rem}.swagger-ui .pl6-ns{padding-left:8rem}.swagger-ui .pl7-ns{padding-left:16rem}.swagger-ui .pr0-ns{padding-right:0}.swagger-ui .pr1-ns{padding-right:.25rem}.swagger-ui .pr2-ns{padding-right:.5rem}.swagger-ui .pr3-ns{padding-right:1rem}.swagger-ui .pr4-ns{padding-right:2rem}.swagger-ui .pr5-ns{padding-right:4rem}.swagger-ui .pr6-ns{padding-right:8rem}.swagger-ui .pr7-ns{padding-right:16rem}.swagger-ui .pb0-ns{padding-bottom:0}.swagger-ui .pb1-ns{padding-bottom:.25rem}.swagger-ui .pb2-ns{padding-bottom:.5rem}.swagger-ui .pb3-ns{padding-bottom:1rem}.swagger-ui .pb4-ns{padding-bottom:2rem}.swagger-ui .pb5-ns{padding-bottom:4rem}.swagger-ui .pb6-ns{padding-bottom:8rem}.swagger-ui .pb7-ns{padding-bottom:16rem}.swagger-ui .pt0-ns{padding-top:0}.swagger-ui .pt1-ns{padding-top:.25rem}.swagger-ui .pt2-ns{padding-top:.5rem}.swagger-ui .pt3-ns{padding-top:1rem}.swagger-ui .pt4-ns{padding-top:2rem}.swagger-ui .pt5-ns{padding-top:4rem}.swagger-ui .pt6-ns{padding-top:8rem}.swagger-ui .pt7-ns{padding-top:16rem}.swagger-ui .pv0-ns{padding-bottom:0;padding-top:0}.swagger-ui .pv1-ns{padding-bottom:.25rem;padding-top:.25rem}.swagger-ui .pv2-ns{padding-bottom:.5rem;padding-top:.5rem}.swagger-ui .pv3-ns{padding-bottom:1rem;padding-top:1rem}.swagger-ui .pv4-ns{padding-bottom:2rem;padding-top:2rem}.swagger-ui .pv5-ns{padding-bottom:4rem;padding-top:4rem}.swagger-ui .pv6-ns{padding-bottom:8rem;padding-top:8rem}.swagger-ui .pv7-ns{padding-bottom:16rem;padding-top:16rem}.swagger-ui .ph0-ns{padding-left:0;padding-right:0}.swagger-ui .ph1-ns{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2-ns{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3-ns{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4-ns{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5-ns{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6-ns{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7-ns{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0-ns{margin:0}.swagger-ui .ma1-ns{margin:.25rem}.swagger-ui .ma2-ns{margin:.5rem}.swagger-ui .ma3-ns{margin:1rem}.swagger-ui .ma4-ns{margin:2rem}.swagger-ui .ma5-ns{margin:4rem}.swagger-ui .ma6-ns{margin:8rem}.swagger-ui .ma7-ns{margin:16rem}.swagger-ui .ml0-ns{margin-left:0}.swagger-ui .ml1-ns{margin-left:.25rem}.swagger-ui .ml2-ns{margin-left:.5rem}.swagger-ui .ml3-ns{margin-left:1rem}.swagger-ui .ml4-ns{margin-left:2rem}.swagger-ui .ml5-ns{margin-left:4rem}.swagger-ui .ml6-ns{margin-left:8rem}.swagger-ui .ml7-ns{margin-left:16rem}.swagger-ui .mr0-ns{margin-right:0}.swagger-ui .mr1-ns{margin-right:.25rem}.swagger-ui .mr2-ns{margin-right:.5rem}.swagger-ui .mr3-ns{margin-right:1rem}.swagger-ui .mr4-ns{margin-right:2rem}.swagger-ui .mr5-ns{margin-right:4rem}.swagger-ui .mr6-ns{margin-right:8rem}.swagger-ui .mr7-ns{margin-right:16rem}.swagger-ui .mb0-ns{margin-bottom:0}.swagger-ui .mb1-ns{margin-bottom:.25rem}.swagger-ui .mb2-ns{margin-bottom:.5rem}.swagger-ui .mb3-ns{margin-bottom:1rem}.swagger-ui .mb4-ns{margin-bottom:2rem}.swagger-ui .mb5-ns{margin-bottom:4rem}.swagger-ui .mb6-ns{margin-bottom:8rem}.swagger-ui .mb7-ns{margin-bottom:16rem}.swagger-ui .mt0-ns{margin-top:0}.swagger-ui .mt1-ns{margin-top:.25rem}.swagger-ui .mt2-ns{margin-top:.5rem}.swagger-ui .mt3-ns{margin-top:1rem}.swagger-ui .mt4-ns{margin-top:2rem}.swagger-ui .mt5-ns{margin-top:4rem}.swagger-ui .mt6-ns{margin-top:8rem}.swagger-ui .mt7-ns{margin-top:16rem}.swagger-ui .mv0-ns{margin-bottom:0;margin-top:0}.swagger-ui .mv1-ns{margin-bottom:.25rem;margin-top:.25rem}.swagger-ui .mv2-ns{margin-bottom:.5rem;margin-top:.5rem}.swagger-ui .mv3-ns{margin-bottom:1rem;margin-top:1rem}.swagger-ui .mv4-ns{margin-bottom:2rem;margin-top:2rem}.swagger-ui .mv5-ns{margin-bottom:4rem;margin-top:4rem}.swagger-ui .mv6-ns{margin-bottom:8rem;margin-top:8rem}.swagger-ui .mv7-ns{margin-bottom:16rem;margin-top:16rem}.swagger-ui .mh0-ns{margin-left:0;margin-right:0}.swagger-ui .mh1-ns{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2-ns{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3-ns{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4-ns{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5-ns{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6-ns{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7-ns{margin-left:16rem;margin-right:16rem}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .pa0-m{padding:0}.swagger-ui .pa1-m{padding:.25rem}.swagger-ui .pa2-m{padding:.5rem}.swagger-ui .pa3-m{padding:1rem}.swagger-ui .pa4-m{padding:2rem}.swagger-ui .pa5-m{padding:4rem}.swagger-ui .pa6-m{padding:8rem}.swagger-ui .pa7-m{padding:16rem}.swagger-ui .pl0-m{padding-left:0}.swagger-ui .pl1-m{padding-left:.25rem}.swagger-ui .pl2-m{padding-left:.5rem}.swagger-ui .pl3-m{padding-left:1rem}.swagger-ui .pl4-m{padding-left:2rem}.swagger-ui .pl5-m{padding-left:4rem}.swagger-ui .pl6-m{padding-left:8rem}.swagger-ui .pl7-m{padding-left:16rem}.swagger-ui .pr0-m{padding-right:0}.swagger-ui .pr1-m{padding-right:.25rem}.swagger-ui .pr2-m{padding-right:.5rem}.swagger-ui .pr3-m{padding-right:1rem}.swagger-ui .pr4-m{padding-right:2rem}.swagger-ui .pr5-m{padding-right:4rem}.swagger-ui .pr6-m{padding-right:8rem}.swagger-ui .pr7-m{padding-right:16rem}.swagger-ui .pb0-m{padding-bottom:0}.swagger-ui .pb1-m{padding-bottom:.25rem}.swagger-ui .pb2-m{padding-bottom:.5rem}.swagger-ui .pb3-m{padding-bottom:1rem}.swagger-ui .pb4-m{padding-bottom:2rem}.swagger-ui .pb5-m{padding-bottom:4rem}.swagger-ui .pb6-m{padding-bottom:8rem}.swagger-ui .pb7-m{padding-bottom:16rem}.swagger-ui .pt0-m{padding-top:0}.swagger-ui .pt1-m{padding-top:.25rem}.swagger-ui .pt2-m{padding-top:.5rem}.swagger-ui .pt3-m{padding-top:1rem}.swagger-ui .pt4-m{padding-top:2rem}.swagger-ui .pt5-m{padding-top:4rem}.swagger-ui .pt6-m{padding-top:8rem}.swagger-ui .pt7-m{padding-top:16rem}.swagger-ui .pv0-m{padding-bottom:0;padding-top:0}.swagger-ui .pv1-m{padding-bottom:.25rem;padding-top:.25rem}.swagger-ui .pv2-m{padding-bottom:.5rem;padding-top:.5rem}.swagger-ui .pv3-m{padding-bottom:1rem;padding-top:1rem}.swagger-ui .pv4-m{padding-bottom:2rem;padding-top:2rem}.swagger-ui .pv5-m{padding-bottom:4rem;padding-top:4rem}.swagger-ui .pv6-m{padding-bottom:8rem;padding-top:8rem}.swagger-ui .pv7-m{padding-bottom:16rem;padding-top:16rem}.swagger-ui .ph0-m{padding-left:0;padding-right:0}.swagger-ui .ph1-m{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2-m{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3-m{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4-m{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5-m{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6-m{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7-m{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0-m{margin:0}.swagger-ui .ma1-m{margin:.25rem}.swagger-ui .ma2-m{margin:.5rem}.swagger-ui .ma3-m{margin:1rem}.swagger-ui .ma4-m{margin:2rem}.swagger-ui .ma5-m{margin:4rem}.swagger-ui .ma6-m{margin:8rem}.swagger-ui .ma7-m{margin:16rem}.swagger-ui .ml0-m{margin-left:0}.swagger-ui .ml1-m{margin-left:.25rem}.swagger-ui .ml2-m{margin-left:.5rem}.swagger-ui .ml3-m{margin-left:1rem}.swagger-ui .ml4-m{margin-left:2rem}.swagger-ui .ml5-m{margin-left:4rem}.swagger-ui .ml6-m{margin-left:8rem}.swagger-ui .ml7-m{margin-left:16rem}.swagger-ui .mr0-m{margin-right:0}.swagger-ui .mr1-m{margin-right:.25rem}.swagger-ui .mr2-m{margin-right:.5rem}.swagger-ui .mr3-m{margin-right:1rem}.swagger-ui .mr4-m{margin-right:2rem}.swagger-ui .mr5-m{margin-right:4rem}.swagger-ui .mr6-m{margin-right:8rem}.swagger-ui .mr7-m{margin-right:16rem}.swagger-ui .mb0-m{margin-bottom:0}.swagger-ui .mb1-m{margin-bottom:.25rem}.swagger-ui .mb2-m{margin-bottom:.5rem}.swagger-ui .mb3-m{margin-bottom:1rem}.swagger-ui .mb4-m{margin-bottom:2rem}.swagger-ui .mb5-m{margin-bottom:4rem}.swagger-ui .mb6-m{margin-bottom:8rem}.swagger-ui .mb7-m{margin-bottom:16rem}.swagger-ui .mt0-m{margin-top:0}.swagger-ui .mt1-m{margin-top:.25rem}.swagger-ui .mt2-m{margin-top:.5rem}.swagger-ui .mt3-m{margin-top:1rem}.swagger-ui .mt4-m{margin-top:2rem}.swagger-ui .mt5-m{margin-top:4rem}.swagger-ui .mt6-m{margin-top:8rem}.swagger-ui .mt7-m{margin-top:16rem}.swagger-ui .mv0-m{margin-bottom:0;margin-top:0}.swagger-ui .mv1-m{margin-bottom:.25rem;margin-top:.25rem}.swagger-ui .mv2-m{margin-bottom:.5rem;margin-top:.5rem}.swagger-ui .mv3-m{margin-bottom:1rem;margin-top:1rem}.swagger-ui .mv4-m{margin-bottom:2rem;margin-top:2rem}.swagger-ui .mv5-m{margin-bottom:4rem;margin-top:4rem}.swagger-ui .mv6-m{margin-bottom:8rem;margin-top:8rem}.swagger-ui .mv7-m{margin-bottom:16rem;margin-top:16rem}.swagger-ui .mh0-m{margin-left:0;margin-right:0}.swagger-ui .mh1-m{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2-m{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3-m{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4-m{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5-m{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6-m{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7-m{margin-left:16rem;margin-right:16rem}}@media screen and (min-width:60em){.swagger-ui .pa0-l{padding:0}.swagger-ui .pa1-l{padding:.25rem}.swagger-ui .pa2-l{padding:.5rem}.swagger-ui .pa3-l{padding:1rem}.swagger-ui .pa4-l{padding:2rem}.swagger-ui .pa5-l{padding:4rem}.swagger-ui .pa6-l{padding:8rem}.swagger-ui .pa7-l{padding:16rem}.swagger-ui .pl0-l{padding-left:0}.swagger-ui .pl1-l{padding-left:.25rem}.swagger-ui .pl2-l{padding-left:.5rem}.swagger-ui .pl3-l{padding-left:1rem}.swagger-ui .pl4-l{padding-left:2rem}.swagger-ui .pl5-l{padding-left:4rem}.swagger-ui .pl6-l{padding-left:8rem}.swagger-ui .pl7-l{padding-left:16rem}.swagger-ui .pr0-l{padding-right:0}.swagger-ui .pr1-l{padding-right:.25rem}.swagger-ui .pr2-l{padding-right:.5rem}.swagger-ui .pr3-l{padding-right:1rem}.swagger-ui .pr4-l{padding-right:2rem}.swagger-ui .pr5-l{padding-right:4rem}.swagger-ui .pr6-l{padding-right:8rem}.swagger-ui .pr7-l{padding-right:16rem}.swagger-ui .pb0-l{padding-bottom:0}.swagger-ui .pb1-l{padding-bottom:.25rem}.swagger-ui .pb2-l{padding-bottom:.5rem}.swagger-ui .pb3-l{padding-bottom:1rem}.swagger-ui .pb4-l{padding-bottom:2rem}.swagger-ui .pb5-l{padding-bottom:4rem}.swagger-ui .pb6-l{padding-bottom:8rem}.swagger-ui .pb7-l{padding-bottom:16rem}.swagger-ui .pt0-l{padding-top:0}.swagger-ui .pt1-l{padding-top:.25rem}.swagger-ui .pt2-l{padding-top:.5rem}.swagger-ui .pt3-l{padding-top:1rem}.swagger-ui .pt4-l{padding-top:2rem}.swagger-ui .pt5-l{padding-top:4rem}.swagger-ui .pt6-l{padding-top:8rem}.swagger-ui .pt7-l{padding-top:16rem}.swagger-ui .pv0-l{padding-bottom:0;padding-top:0}.swagger-ui .pv1-l{padding-bottom:.25rem;padding-top:.25rem}.swagger-ui .pv2-l{padding-bottom:.5rem;padding-top:.5rem}.swagger-ui .pv3-l{padding-bottom:1rem;padding-top:1rem}.swagger-ui .pv4-l{padding-bottom:2rem;padding-top:2rem}.swagger-ui .pv5-l{padding-bottom:4rem;padding-top:4rem}.swagger-ui .pv6-l{padding-bottom:8rem;padding-top:8rem}.swagger-ui .pv7-l{padding-bottom:16rem;padding-top:16rem}.swagger-ui .ph0-l{padding-left:0;padding-right:0}.swagger-ui .ph1-l{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2-l{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3-l{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4-l{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5-l{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6-l{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7-l{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0-l{margin:0}.swagger-ui .ma1-l{margin:.25rem}.swagger-ui .ma2-l{margin:.5rem}.swagger-ui .ma3-l{margin:1rem}.swagger-ui .ma4-l{margin:2rem}.swagger-ui .ma5-l{margin:4rem}.swagger-ui .ma6-l{margin:8rem}.swagger-ui .ma7-l{margin:16rem}.swagger-ui .ml0-l{margin-left:0}.swagger-ui .ml1-l{margin-left:.25rem}.swagger-ui .ml2-l{margin-left:.5rem}.swagger-ui .ml3-l{margin-left:1rem}.swagger-ui .ml4-l{margin-left:2rem}.swagger-ui .ml5-l{margin-left:4rem}.swagger-ui .ml6-l{margin-left:8rem}.swagger-ui .ml7-l{margin-left:16rem}.swagger-ui .mr0-l{margin-right:0}.swagger-ui .mr1-l{margin-right:.25rem}.swagger-ui .mr2-l{margin-right:.5rem}.swagger-ui .mr3-l{margin-right:1rem}.swagger-ui .mr4-l{margin-right:2rem}.swagger-ui .mr5-l{margin-right:4rem}.swagger-ui .mr6-l{margin-right:8rem}.swagger-ui .mr7-l{margin-right:16rem}.swagger-ui .mb0-l{margin-bottom:0}.swagger-ui .mb1-l{margin-bottom:.25rem}.swagger-ui .mb2-l{margin-bottom:.5rem}.swagger-ui .mb3-l{margin-bottom:1rem}.swagger-ui .mb4-l{margin-bottom:2rem}.swagger-ui .mb5-l{margin-bottom:4rem}.swagger-ui .mb6-l{margin-bottom:8rem}.swagger-ui .mb7-l{margin-bottom:16rem}.swagger-ui .mt0-l{margin-top:0}.swagger-ui .mt1-l{margin-top:.25rem}.swagger-ui .mt2-l{margin-top:.5rem}.swagger-ui .mt3-l{margin-top:1rem}.swagger-ui .mt4-l{margin-top:2rem}.swagger-ui .mt5-l{margin-top:4rem}.swagger-ui .mt6-l{margin-top:8rem}.swagger-ui .mt7-l{margin-top:16rem}.swagger-ui .mv0-l{margin-bottom:0;margin-top:0}.swagger-ui .mv1-l{margin-bottom:.25rem;margin-top:.25rem}.swagger-ui .mv2-l{margin-bottom:.5rem;margin-top:.5rem}.swagger-ui .mv3-l{margin-bottom:1rem;margin-top:1rem}.swagger-ui .mv4-l{margin-bottom:2rem;margin-top:2rem}.swagger-ui .mv5-l{margin-bottom:4rem;margin-top:4rem}.swagger-ui .mv6-l{margin-bottom:8rem;margin-top:8rem}.swagger-ui .mv7-l{margin-bottom:16rem;margin-top:16rem}.swagger-ui .mh0-l{margin-left:0;margin-right:0}.swagger-ui .mh1-l{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2-l{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3-l{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4-l{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5-l{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6-l{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7-l{margin-left:16rem;margin-right:16rem}}.swagger-ui .na1{margin:-.25rem}.swagger-ui .na2{margin:-.5rem}.swagger-ui .na3{margin:-1rem}.swagger-ui .na4{margin:-2rem}.swagger-ui .na5{margin:-4rem}.swagger-ui .na6{margin:-8rem}.swagger-ui .na7{margin:-16rem}.swagger-ui .nl1{margin-left:-.25rem}.swagger-ui .nl2{margin-left:-.5rem}.swagger-ui .nl3{margin-left:-1rem}.swagger-ui .nl4{margin-left:-2rem}.swagger-ui .nl5{margin-left:-4rem}.swagger-ui .nl6{margin-left:-8rem}.swagger-ui .nl7{margin-left:-16rem}.swagger-ui .nr1{margin-right:-.25rem}.swagger-ui .nr2{margin-right:-.5rem}.swagger-ui .nr3{margin-right:-1rem}.swagger-ui .nr4{margin-right:-2rem}.swagger-ui .nr5{margin-right:-4rem}.swagger-ui .nr6{margin-right:-8rem}.swagger-ui .nr7{margin-right:-16rem}.swagger-ui .nb1{margin-bottom:-.25rem}.swagger-ui .nb2{margin-bottom:-.5rem}.swagger-ui .nb3{margin-bottom:-1rem}.swagger-ui .nb4{margin-bottom:-2rem}.swagger-ui .nb5{margin-bottom:-4rem}.swagger-ui .nb6{margin-bottom:-8rem}.swagger-ui .nb7{margin-bottom:-16rem}.swagger-ui .nt1{margin-top:-.25rem}.swagger-ui .nt2{margin-top:-.5rem}.swagger-ui .nt3{margin-top:-1rem}.swagger-ui .nt4{margin-top:-2rem}.swagger-ui .nt5{margin-top:-4rem}.swagger-ui .nt6{margin-top:-8rem}.swagger-ui .nt7{margin-top:-16rem}@media screen and (min-width:30em){.swagger-ui .na1-ns{margin:-.25rem}.swagger-ui .na2-ns{margin:-.5rem}.swagger-ui .na3-ns{margin:-1rem}.swagger-ui .na4-ns{margin:-2rem}.swagger-ui .na5-ns{margin:-4rem}.swagger-ui .na6-ns{margin:-8rem}.swagger-ui .na7-ns{margin:-16rem}.swagger-ui .nl1-ns{margin-left:-.25rem}.swagger-ui .nl2-ns{margin-left:-.5rem}.swagger-ui .nl3-ns{margin-left:-1rem}.swagger-ui .nl4-ns{margin-left:-2rem}.swagger-ui .nl5-ns{margin-left:-4rem}.swagger-ui .nl6-ns{margin-left:-8rem}.swagger-ui .nl7-ns{margin-left:-16rem}.swagger-ui .nr1-ns{margin-right:-.25rem}.swagger-ui .nr2-ns{margin-right:-.5rem}.swagger-ui .nr3-ns{margin-right:-1rem}.swagger-ui .nr4-ns{margin-right:-2rem}.swagger-ui .nr5-ns{margin-right:-4rem}.swagger-ui .nr6-ns{margin-right:-8rem}.swagger-ui .nr7-ns{margin-right:-16rem}.swagger-ui .nb1-ns{margin-bottom:-.25rem}.swagger-ui .nb2-ns{margin-bottom:-.5rem}.swagger-ui .nb3-ns{margin-bottom:-1rem}.swagger-ui .nb4-ns{margin-bottom:-2rem}.swagger-ui .nb5-ns{margin-bottom:-4rem}.swagger-ui .nb6-ns{margin-bottom:-8rem}.swagger-ui .nb7-ns{margin-bottom:-16rem}.swagger-ui .nt1-ns{margin-top:-.25rem}.swagger-ui .nt2-ns{margin-top:-.5rem}.swagger-ui .nt3-ns{margin-top:-1rem}.swagger-ui .nt4-ns{margin-top:-2rem}.swagger-ui .nt5-ns{margin-top:-4rem}.swagger-ui .nt6-ns{margin-top:-8rem}.swagger-ui .nt7-ns{margin-top:-16rem}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .na1-m{margin:-.25rem}.swagger-ui .na2-m{margin:-.5rem}.swagger-ui .na3-m{margin:-1rem}.swagger-ui .na4-m{margin:-2rem}.swagger-ui .na5-m{margin:-4rem}.swagger-ui .na6-m{margin:-8rem}.swagger-ui .na7-m{margin:-16rem}.swagger-ui .nl1-m{margin-left:-.25rem}.swagger-ui .nl2-m{margin-left:-.5rem}.swagger-ui .nl3-m{margin-left:-1rem}.swagger-ui .nl4-m{margin-left:-2rem}.swagger-ui .nl5-m{margin-left:-4rem}.swagger-ui .nl6-m{margin-left:-8rem}.swagger-ui .nl7-m{margin-left:-16rem}.swagger-ui .nr1-m{margin-right:-.25rem}.swagger-ui .nr2-m{margin-right:-.5rem}.swagger-ui .nr3-m{margin-right:-1rem}.swagger-ui .nr4-m{margin-right:-2rem}.swagger-ui .nr5-m{margin-right:-4rem}.swagger-ui .nr6-m{margin-right:-8rem}.swagger-ui .nr7-m{margin-right:-16rem}.swagger-ui .nb1-m{margin-bottom:-.25rem}.swagger-ui .nb2-m{margin-bottom:-.5rem}.swagger-ui .nb3-m{margin-bottom:-1rem}.swagger-ui .nb4-m{margin-bottom:-2rem}.swagger-ui .nb5-m{margin-bottom:-4rem}.swagger-ui .nb6-m{margin-bottom:-8rem}.swagger-ui .nb7-m{margin-bottom:-16rem}.swagger-ui .nt1-m{margin-top:-.25rem}.swagger-ui .nt2-m{margin-top:-.5rem}.swagger-ui .nt3-m{margin-top:-1rem}.swagger-ui .nt4-m{margin-top:-2rem}.swagger-ui .nt5-m{margin-top:-4rem}.swagger-ui .nt6-m{margin-top:-8rem}.swagger-ui .nt7-m{margin-top:-16rem}}@media screen and (min-width:60em){.swagger-ui .na1-l{margin:-.25rem}.swagger-ui .na2-l{margin:-.5rem}.swagger-ui .na3-l{margin:-1rem}.swagger-ui .na4-l{margin:-2rem}.swagger-ui .na5-l{margin:-4rem}.swagger-ui .na6-l{margin:-8rem}.swagger-ui .na7-l{margin:-16rem}.swagger-ui .nl1-l{margin-left:-.25rem}.swagger-ui .nl2-l{margin-left:-.5rem}.swagger-ui .nl3-l{margin-left:-1rem}.swagger-ui .nl4-l{margin-left:-2rem}.swagger-ui .nl5-l{margin-left:-4rem}.swagger-ui .nl6-l{margin-left:-8rem}.swagger-ui .nl7-l{margin-left:-16rem}.swagger-ui .nr1-l{margin-right:-.25rem}.swagger-ui .nr2-l{margin-right:-.5rem}.swagger-ui .nr3-l{margin-right:-1rem}.swagger-ui .nr4-l{margin-right:-2rem}.swagger-ui .nr5-l{margin-right:-4rem}.swagger-ui .nr6-l{margin-right:-8rem}.swagger-ui .nr7-l{margin-right:-16rem}.swagger-ui .nb1-l{margin-bottom:-.25rem}.swagger-ui .nb2-l{margin-bottom:-.5rem}.swagger-ui .nb3-l{margin-bottom:-1rem}.swagger-ui .nb4-l{margin-bottom:-2rem}.swagger-ui .nb5-l{margin-bottom:-4rem}.swagger-ui .nb6-l{margin-bottom:-8rem}.swagger-ui .nb7-l{margin-bottom:-16rem}.swagger-ui .nt1-l{margin-top:-.25rem}.swagger-ui .nt2-l{margin-top:-.5rem}.swagger-ui .nt3-l{margin-top:-1rem}.swagger-ui .nt4-l{margin-top:-2rem}.swagger-ui .nt5-l{margin-top:-4rem}.swagger-ui .nt6-l{margin-top:-8rem}.swagger-ui .nt7-l{margin-top:-16rem}}.swagger-ui .collapse{border-collapse:collapse;border-spacing:0}.swagger-ui .striped--light-silver:nth-child(odd){background-color:#aaa}.swagger-ui .striped--moon-gray:nth-child(odd){background-color:#ccc}.swagger-ui .striped--light-gray:nth-child(odd){background-color:#eee}.swagger-ui .striped--near-white:nth-child(odd){background-color:#f4f4f4}.swagger-ui .stripe-light:nth-child(odd){background-color:#ffffff1a}.swagger-ui .stripe-dark:nth-child(odd){background-color:#0000001a}.swagger-ui .strike{text-decoration:line-through}.swagger-ui .underline{text-decoration:underline}.swagger-ui .no-underline{text-decoration:none}@media screen and (min-width:30em){.swagger-ui .strike-ns{text-decoration:line-through}.swagger-ui .underline-ns{text-decoration:underline}.swagger-ui .no-underline-ns{text-decoration:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .strike-m{text-decoration:line-through}.swagger-ui .underline-m{text-decoration:underline}.swagger-ui .no-underline-m{text-decoration:none}}@media screen and (min-width:60em){.swagger-ui .strike-l{text-decoration:line-through}.swagger-ui .underline-l{text-decoration:underline}.swagger-ui .no-underline-l{text-decoration:none}}.swagger-ui .tl{text-align:left}.swagger-ui .tr{text-align:right}.swagger-ui .tc{text-align:center}.swagger-ui .tj{text-align:justify}@media screen and (min-width:30em){.swagger-ui .tl-ns{text-align:left}.swagger-ui .tr-ns{text-align:right}.swagger-ui .tc-ns{text-align:center}.swagger-ui .tj-ns{text-align:justify}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .tl-m{text-align:left}.swagger-ui .tr-m{text-align:right}.swagger-ui .tc-m{text-align:center}.swagger-ui .tj-m{text-align:justify}}@media screen and (min-width:60em){.swagger-ui .tl-l{text-align:left}.swagger-ui .tr-l{text-align:right}.swagger-ui .tc-l{text-align:center}.swagger-ui .tj-l{text-align:justify}}.swagger-ui .ttc{text-transform:capitalize}.swagger-ui .ttl{text-transform:lowercase}.swagger-ui .ttu{text-transform:uppercase}.swagger-ui .ttn{text-transform:none}@media screen and (min-width:30em){.swagger-ui .ttc-ns{text-transform:capitalize}.swagger-ui .ttl-ns{text-transform:lowercase}.swagger-ui .ttu-ns{text-transform:uppercase}.swagger-ui .ttn-ns{text-transform:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .ttc-m{text-transform:capitalize}.swagger-ui .ttl-m{text-transform:lowercase}.swagger-ui .ttu-m{text-transform:uppercase}.swagger-ui .ttn-m{text-transform:none}}@media screen and (min-width:60em){.swagger-ui .ttc-l{text-transform:capitalize}.swagger-ui .ttl-l{text-transform:lowercase}.swagger-ui .ttu-l{text-transform:uppercase}.swagger-ui .ttn-l{text-transform:none}}.swagger-ui .f-6,.swagger-ui .f-headline{font-size:6rem}.swagger-ui .f-5,.swagger-ui .f-subheadline{font-size:5rem}.swagger-ui .f1{font-size:3rem}.swagger-ui .f2{font-size:2.25rem}.swagger-ui .f3{font-size:1.5rem}.swagger-ui .f4{font-size:1.25rem}.swagger-ui .f5{font-size:1rem}.swagger-ui .f6{font-size:.875rem}.swagger-ui .f7{font-size:.75rem}@media screen and (min-width:30em){.swagger-ui .f-6-ns,.swagger-ui .f-headline-ns{font-size:6rem}.swagger-ui .f-5-ns,.swagger-ui .f-subheadline-ns{font-size:5rem}.swagger-ui .f1-ns{font-size:3rem}.swagger-ui .f2-ns{font-size:2.25rem}.swagger-ui .f3-ns{font-size:1.5rem}.swagger-ui .f4-ns{font-size:1.25rem}.swagger-ui .f5-ns{font-size:1rem}.swagger-ui .f6-ns{font-size:.875rem}.swagger-ui .f7-ns{font-size:.75rem}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .f-6-m,.swagger-ui .f-headline-m{font-size:6rem}.swagger-ui .f-5-m,.swagger-ui .f-subheadline-m{font-size:5rem}.swagger-ui .f1-m{font-size:3rem}.swagger-ui .f2-m{font-size:2.25rem}.swagger-ui .f3-m{font-size:1.5rem}.swagger-ui .f4-m{font-size:1.25rem}.swagger-ui .f5-m{font-size:1rem}.swagger-ui .f6-m{font-size:.875rem}.swagger-ui .f7-m{font-size:.75rem}}@media screen and (min-width:60em){.swagger-ui .f-6-l,.swagger-ui .f-headline-l{font-size:6rem}.swagger-ui .f-5-l,.swagger-ui .f-subheadline-l{font-size:5rem}.swagger-ui .f1-l{font-size:3rem}.swagger-ui .f2-l{font-size:2.25rem}.swagger-ui .f3-l{font-size:1.5rem}.swagger-ui .f4-l{font-size:1.25rem}.swagger-ui .f5-l{font-size:1rem}.swagger-ui .f6-l{font-size:.875rem}.swagger-ui .f7-l{font-size:.75rem}}.swagger-ui .measure{max-width:30em}.swagger-ui .measure-wide{max-width:34em}.swagger-ui .measure-narrow{max-width:20em}.swagger-ui .indent{margin-bottom:0;margin-top:0;text-indent:1em}.swagger-ui .small-caps{font-feature-settings:"smcp";font-variant:small-caps}.swagger-ui .truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media screen and (min-width:30em){.swagger-ui .measure-ns{max-width:30em}.swagger-ui .measure-wide-ns{max-width:34em}.swagger-ui .measure-narrow-ns{max-width:20em}.swagger-ui .indent-ns{margin-bottom:0;margin-top:0;text-indent:1em}.swagger-ui .small-caps-ns{font-feature-settings:"smcp";font-variant:small-caps}.swagger-ui .truncate-ns{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .measure-m{max-width:30em}.swagger-ui .measure-wide-m{max-width:34em}.swagger-ui .measure-narrow-m{max-width:20em}.swagger-ui .indent-m{margin-bottom:0;margin-top:0;text-indent:1em}.swagger-ui .small-caps-m{font-feature-settings:"smcp";font-variant:small-caps}.swagger-ui .truncate-m{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}@media screen and (min-width:60em){.swagger-ui .measure-l{max-width:30em}.swagger-ui .measure-wide-l{max-width:34em}.swagger-ui .measure-narrow-l{max-width:20em}.swagger-ui .indent-l{margin-bottom:0;margin-top:0;text-indent:1em}.swagger-ui .small-caps-l{font-feature-settings:"smcp";font-variant:small-caps}.swagger-ui .truncate-l{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}.swagger-ui .overflow-container{overflow-y:scroll}.swagger-ui .center{margin-left:auto;margin-right:auto}.swagger-ui .mr-auto{margin-right:auto}.swagger-ui .ml-auto{margin-left:auto}@media screen and (min-width:30em){.swagger-ui .center-ns{margin-left:auto;margin-right:auto}.swagger-ui .mr-auto-ns{margin-right:auto}.swagger-ui .ml-auto-ns{margin-left:auto}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .center-m{margin-left:auto;margin-right:auto}.swagger-ui .mr-auto-m{margin-right:auto}.swagger-ui .ml-auto-m{margin-left:auto}}@media screen and (min-width:60em){.swagger-ui .center-l{margin-left:auto;margin-right:auto}.swagger-ui .mr-auto-l{margin-right:auto}.swagger-ui .ml-auto-l{margin-left:auto}}.swagger-ui .clip{clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);position:fixed!important;_position:absolute!important}@media screen and (min-width:30em){.swagger-ui .clip-ns{clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);position:fixed!important;_position:absolute!important}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .clip-m{clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);position:fixed!important;_position:absolute!important}}@media screen and (min-width:60em){.swagger-ui .clip-l{clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);position:fixed!important;_position:absolute!important}}.swagger-ui .ws-normal{white-space:normal}.swagger-ui .nowrap{white-space:nowrap}.swagger-ui .pre{white-space:pre}@media screen and (min-width:30em){.swagger-ui .ws-normal-ns{white-space:normal}.swagger-ui .nowrap-ns{white-space:nowrap}.swagger-ui .pre-ns{white-space:pre}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .ws-normal-m{white-space:normal}.swagger-ui .nowrap-m{white-space:nowrap}.swagger-ui .pre-m{white-space:pre}}@media screen and (min-width:60em){.swagger-ui .ws-normal-l{white-space:normal}.swagger-ui .nowrap-l{white-space:nowrap}.swagger-ui .pre-l{white-space:pre}}.swagger-ui .v-base{vertical-align:initial}.swagger-ui .v-mid{vertical-align:middle}.swagger-ui .v-top{vertical-align:top}.swagger-ui .v-btm{vertical-align:bottom}@media screen and (min-width:30em){.swagger-ui .v-base-ns{vertical-align:initial}.swagger-ui .v-mid-ns{vertical-align:middle}.swagger-ui .v-top-ns{vertical-align:top}.swagger-ui .v-btm-ns{vertical-align:bottom}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .v-base-m{vertical-align:initial}.swagger-ui .v-mid-m{vertical-align:middle}.swagger-ui .v-top-m{vertical-align:top}.swagger-ui .v-btm-m{vertical-align:bottom}}@media screen and (min-width:60em){.swagger-ui .v-base-l{vertical-align:initial}.swagger-ui .v-mid-l{vertical-align:middle}.swagger-ui .v-top-l{vertical-align:top}.swagger-ui .v-btm-l{vertical-align:bottom}}.swagger-ui .dim{opacity:1;transition:opacity .15s ease-in}.swagger-ui .dim:focus,.swagger-ui .dim:hover{opacity:.5;transition:opacity .15s ease-in}.swagger-ui .dim:active{opacity:.8;transition:opacity .15s ease-out}.swagger-ui .glow{transition:opacity .15s ease-in}.swagger-ui .glow:focus,.swagger-ui .glow:hover{opacity:1;transition:opacity .15s ease-in}.swagger-ui .hide-child .child{opacity:0;transition:opacity .15s ease-in}.swagger-ui .hide-child:active .child,.swagger-ui .hide-child:focus .child,.swagger-ui .hide-child:hover .child{opacity:1;transition:opacity .15s ease-in}.swagger-ui .underline-hover:focus,.swagger-ui .underline-hover:hover{text-decoration:underline}.swagger-ui .grow{-moz-osx-font-smoothing:grayscale;backface-visibility:hidden;transform:translateZ(0);transition:transform .25s ease-out}.swagger-ui .grow:focus,.swagger-ui .grow:hover{transform:scale(1.05)}.swagger-ui .grow:active{transform:scale(.9)}.swagger-ui .grow-large{-moz-osx-font-smoothing:grayscale;backface-visibility:hidden;transform:translateZ(0);transition:transform .25s ease-in-out}.swagger-ui .grow-large:focus,.swagger-ui .grow-large:hover{transform:scale(1.2)}.swagger-ui .grow-large:active{transform:scale(.95)}.swagger-ui .pointer:hover{cursor:pointer}.swagger-ui .shadow-hover{cursor:pointer;position:relative;transition:all .5s cubic-bezier(.165,.84,.44,1)}.swagger-ui .shadow-hover:after{border-radius:inherit;box-shadow:0 0 16px 2px #0003;content:"";height:100%;left:0;opacity:0;position:absolute;top:0;transition:opacity .5s cubic-bezier(.165,.84,.44,1);width:100%;z-index:-1}.swagger-ui .shadow-hover:focus:after,.swagger-ui .shadow-hover:hover:after{opacity:1}.swagger-ui .bg-animate,.swagger-ui .bg-animate:focus,.swagger-ui .bg-animate:hover{transition:background-color .15s ease-in-out}.swagger-ui .z-0{z-index:0}.swagger-ui .z-1{z-index:1}.swagger-ui .z-2{z-index:2}.swagger-ui .z-3{z-index:3}.swagger-ui .z-4{z-index:4}.swagger-ui .z-5{z-index:5}.swagger-ui .z-999{z-index:999}.swagger-ui .z-9999{z-index:9999}.swagger-ui .z-max{z-index:2147483647}.swagger-ui .z-inherit{z-index:inherit}.swagger-ui .z-initial{z-index:auto}.swagger-ui .z-unset{z-index:unset}.swagger-ui .nested-copy-line-height ol,.swagger-ui .nested-copy-line-height p,.swagger-ui .nested-copy-line-height ul{line-height:1.5}.swagger-ui .nested-headline-line-height h1,.swagger-ui .nested-headline-line-height h2,.swagger-ui .nested-headline-line-height h3,.swagger-ui .nested-headline-line-height h4,.swagger-ui .nested-headline-line-height h5,.swagger-ui .nested-headline-line-height h6{line-height:1.25}.swagger-ui .nested-list-reset ol,.swagger-ui .nested-list-reset ul{list-style-type:none;margin-left:0;padding-left:0}.swagger-ui .nested-copy-indent p+p{margin-bottom:0;margin-top:0;text-indent:.1em}.swagger-ui .nested-copy-seperator p+p{margin-top:1.5em}.swagger-ui .nested-img img{display:block;max-width:100%;width:100%}.swagger-ui .nested-links a{color:#357edd;transition:color .15s ease-in}.swagger-ui .nested-links a:focus,.swagger-ui .nested-links a:hover{color:#96ccff;transition:color .15s ease-in}.swagger-ui .wrapper{box-sizing:border-box;margin:0 auto;max-width:1460px;padding:0 20px;width:100%}.swagger-ui .opblock-tag-section{display:flex;flex-direction:column}.swagger-ui .try-out.btn-group{display:flex;flex:0.1 2 auto;padding:0}.swagger-ui .try-out__btn{margin-left:1.25rem}.swagger-ui .opblock-tag{align-items:center;border-bottom:1px solid #3b41514d;cursor:pointer;display:flex;padding:10px 20px 10px 10px;transition:all .2s}.swagger-ui .opblock-tag:hover{background:#00000005}.swagger-ui .opblock-tag{color:#3b4151;font-family:sans-serif;font-size:24px;margin:0 0 5px}.swagger-ui .opblock-tag.no-desc span{flex:1}.swagger-ui .opblock-tag svg{transition:all .4s}.swagger-ui .opblock-tag small{color:#3b4151;flex:2;font-family:sans-serif;font-size:14px;font-weight:400;padding:0 10px}.swagger-ui .opblock-tag>div{flex:1 1 150px;font-weight:400;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.swagger-ui .parameter__type{color:#3b4151;font-family:monospace;font-size:12px;font-weight:600;padding:5px 0}.swagger-ui .parameter-controls{margin-top:.75em}.swagger-ui .examples__title{display:block;font-size:1.1em;font-weight:700;margin-bottom:.75em}.swagger-ui .examples__section{margin-top:1.5em}.swagger-ui .examples__section-header{font-size:.9rem;font-weight:700;margin-bottom:.5rem}.swagger-ui .examples-select{display:inline-block;margin-bottom:.75em}.swagger-ui .examples-select .examples-select-element{width:100%}.swagger-ui .examples-select__section-label{font-size:.9rem;font-weight:700;margin-right:.5rem}.swagger-ui .example__section{margin-top:1.5em}.swagger-ui .example__section-header{font-size:.9rem;font-weight:700;margin-bottom:.5rem}.swagger-ui .view-line-link{cursor:pointer;margin:0 5px;position:relative;top:3px;transition:all .5s;width:20px}.swagger-ui .opblock{border:1px solid #000;border-radius:4px;box-shadow:0 0 3px #00000030;margin:0 0 15px}.swagger-ui .opblock .tab-header{display:flex;flex:1}.swagger-ui .opblock .tab-header .tab-item{cursor:pointer;padding:0 40px}.swagger-ui .opblock .tab-header .tab-item:first-of-type{padding:0 40px 0 0}.swagger-ui .opblock .tab-header .tab-item.active h4 span{position:relative}.swagger-ui .opblock .tab-header .tab-item.active h4 span:after{background:gray;bottom:-15px;content:"";height:4px;left:50%;position:absolute;transform:translateX(-50%);width:120%}.swagger-ui .opblock.is-open .opblock-summary{border-bottom:1px solid #000}.swagger-ui .opblock .opblock-section-header{align-items:center;background:#fffc;box-shadow:0 1px 2px #0000001a;display:flex;min-height:50px;padding:8px 20px}.swagger-ui .opblock .opblock-section-header>label{align-items:center;color:#3b4151;display:flex;font-family:sans-serif;font-size:12px;font-weight:700;margin:0 0 0 auto}.swagger-ui .opblock .opblock-section-header>label>span{padding:0 10px 0 0}.swagger-ui .opblock .opblock-section-header h4{color:#3b4151;flex:1;font-family:sans-serif;font-size:14px;margin:0}.swagger-ui .opblock .opblock-summary-method{background:#000;border-radius:3px;color:#fff;font-family:sans-serif;font-size:14px;font-weight:700;min-width:80px;padding:6px 0;text-align:center;text-shadow:0 1px 0 #0000001a}.swagger-ui .opblock .opblock-summary-operation-id,.swagger-ui .opblock .opblock-summary-path,.swagger-ui .opblock .opblock-summary-path__deprecated{align-items:center;color:#3b4151;display:flex;font-family:monospace;font-size:16px;font-weight:600;padding:0 10px;word-break:break-word}@media (max-width:768px){.swagger-ui .opblock .opblock-summary-operation-id,.swagger-ui .opblock .opblock-summary-path,.swagger-ui .opblock .opblock-summary-path__deprecated{font-size:12px}}.swagger-ui .opblock .opblock-summary-path{flex-shrink:0;max-width:calc(100% - 110px - 15rem)}.swagger-ui .opblock .opblock-summary-path__deprecated{text-decoration:line-through}.swagger-ui .opblock .opblock-summary-operation-id{font-size:14px}.swagger-ui .opblock .opblock-summary-description{color:#3b4151;flex:1 1 auto;font-family:sans-serif;font-size:13px;word-break:break-word}.swagger-ui .opblock .opblock-summary{align-items:center;cursor:pointer;display:flex;padding:5px}.swagger-ui .opblock .opblock-summary .view-line-link{cursor:pointer;margin:0;position:relative;top:2px;transition:all .5s;width:0}.swagger-ui .opblock .opblock-summary:hover .view-line-link{margin:0 5px;width:18px}.swagger-ui .opblock.opblock-post{background:#49cc901a;border-color:#49cc90}.swagger-ui .opblock.opblock-post .opblock-summary-method{background:#49cc90}.swagger-ui .opblock.opblock-post .opblock-summary{border-color:#49cc90}.swagger-ui .opblock.opblock-post .tab-header .tab-item.active h4 span:after{background:#49cc90}.swagger-ui .opblock.opblock-put{background:#fca1301a;border-color:#fca130}.swagger-ui .opblock.opblock-put .opblock-summary-method{background:#fca130}.swagger-ui .opblock.opblock-put .opblock-summary{border-color:#fca130}.swagger-ui .opblock.opblock-put .tab-header .tab-item.active h4 span:after{background:#fca130}.swagger-ui .opblock.opblock-delete{background:#f93e3e1a;border-color:#f93e3e}.swagger-ui .opblock.opblock-delete .opblock-summary-method{background:#f93e3e}.swagger-ui .opblock.opblock-delete .opblock-summary{border-color:#f93e3e}.swagger-ui .opblock.opblock-delete .tab-header .tab-item.active h4 span:after{background:#f93e3e}.swagger-ui .opblock.opblock-get{background:#61affe1a;border-color:#61affe}.swagger-ui .opblock.opblock-get .opblock-summary-method{background:#61affe}.swagger-ui .opblock.opblock-get .opblock-summary{border-color:#61affe}.swagger-ui .opblock.opblock-get .tab-header .tab-item.active h4 span:after{background:#61affe}.swagger-ui .opblock.opblock-patch{background:#50e3c21a;border-color:#50e3c2}.swagger-ui .opblock.opblock-patch .opblock-summary-method{background:#50e3c2}.swagger-ui .opblock.opblock-patch .opblock-summary{border-color:#50e3c2}.swagger-ui .opblock.opblock-patch .tab-header .tab-item.active h4 span:after{background:#50e3c2}.swagger-ui .opblock.opblock-head{background:#9012fe1a;border-color:#9012fe}.swagger-ui .opblock.opblock-head .opblock-summary-method{background:#9012fe}.swagger-ui .opblock.opblock-head .opblock-summary{border-color:#9012fe}.swagger-ui .opblock.opblock-head .tab-header .tab-item.active h4 span:after{background:#9012fe}.swagger-ui .opblock.opblock-options{background:#0d5aa71a;border-color:#0d5aa7}.swagger-ui .opblock.opblock-options .opblock-summary-method{background:#0d5aa7}.swagger-ui .opblock.opblock-options .opblock-summary{border-color:#0d5aa7}.swagger-ui .opblock.opblock-options .tab-header .tab-item.active h4 span:after{background:#0d5aa7}.swagger-ui .opblock.opblock-deprecated{background:#ebebeb1a;border-color:#ebebeb;opacity:.6}.swagger-ui .opblock.opblock-deprecated .opblock-summary-method{background:#ebebeb}.swagger-ui .opblock.opblock-deprecated .opblock-summary{border-color:#ebebeb}.swagger-ui .opblock.opblock-deprecated .tab-header .tab-item.active h4 span:after{background:#ebebeb}.swagger-ui .opblock .opblock-schemes{padding:8px 20px}.swagger-ui .opblock .opblock-schemes .schemes-title{padding:0 10px 0 0}.swagger-ui .filter .operation-filter-input{border:2px solid #d8dde7;margin:20px 0;padding:10px;width:100%}.swagger-ui .download-url-wrapper .failed,.swagger-ui .filter .failed{color:red}.swagger-ui .download-url-wrapper .loading,.swagger-ui .filter .loading{color:#aaa}.swagger-ui .model-example{margin-top:1em}.swagger-ui .tab{display:flex;list-style:none;padding:0}.swagger-ui .tab li{color:#3b4151;cursor:pointer;font-family:sans-serif;font-size:12px;min-width:60px;padding:0}.swagger-ui .tab li:first-of-type{padding-left:0;padding-right:12px;position:relative}.swagger-ui .tab li:first-of-type:after{background:#0003;content:"";height:100%;position:absolute;right:6px;top:0;width:1px}.swagger-ui .tab li.active{font-weight:700}.swagger-ui .tab li button.tablinks{background:none;border:0;color:inherit;font-family:inherit;font-weight:inherit;padding:0}.swagger-ui .opblock-description-wrapper,.swagger-ui .opblock-external-docs-wrapper,.swagger-ui .opblock-title_normal{color:#3b4151;font-family:sans-serif;font-size:12px;margin:0 0 5px;padding:15px 20px}.swagger-ui .opblock-description-wrapper h4,.swagger-ui .opblock-external-docs-wrapper h4,.swagger-ui .opblock-title_normal h4{color:#3b4151;font-family:sans-serif;font-size:12px;margin:0 0 5px}.swagger-ui .opblock-description-wrapper p,.swagger-ui .opblock-external-docs-wrapper p,.swagger-ui .opblock-title_normal p{color:#3b4151;font-family:sans-serif;font-size:14px;margin:0}.swagger-ui .opblock-external-docs-wrapper h4{padding-left:0}.swagger-ui .execute-wrapper{padding:20px;text-align:right}.swagger-ui .execute-wrapper .btn{padding:8px 40px;width:100%}.swagger-ui .body-param-options{display:flex;flex-direction:column}.swagger-ui .body-param-options .body-param-edit{padding:10px 0}.swagger-ui .body-param-options label{padding:8px 0}.swagger-ui .body-param-options label select{margin:3px 0 0}.swagger-ui .responses-inner{padding:20px}.swagger-ui .responses-inner h4,.swagger-ui .responses-inner h5{color:#3b4151;font-family:sans-serif;font-size:12px;margin:10px 0 5px}.swagger-ui .responses-inner .curl{white-space:normal}.swagger-ui .response-col_status{color:#3b4151;font-family:sans-serif;font-size:14px}.swagger-ui .response-col_status .response-undocumented{color:#909090;font-family:monospace;font-size:11px;font-weight:600}.swagger-ui .response-col_links{color:#3b4151;font-family:sans-serif;font-size:14px;max-width:40em;padding-left:2em}.swagger-ui .response-col_links .response-undocumented{color:#909090;font-family:monospace;font-size:11px;font-weight:600}.swagger-ui .response-col_links .operation-link{margin-bottom:1.5em}.swagger-ui .response-col_links .operation-link .description{margin-bottom:.5em}.swagger-ui .opblock-body .opblock-loading-animation{display:block;margin:3em auto}.swagger-ui .opblock-body pre.microlight{word-wrap:break-word;background:#333;border-radius:4px;color:#fff;font-family:monospace;font-size:12px;font-weight:600;hyphens:auto;margin:0;padding:10px;white-space:pre-wrap;word-break:break-all;word-break:break-word}.swagger-ui .opblock-body pre.microlight .headerline{display:block}.swagger-ui .highlight-code{position:relative}.swagger-ui .highlight-code>.microlight{max-height:400px;min-height:6em;overflow-y:auto}.swagger-ui .highlight-code>.microlight code{white-space:pre-wrap!important;word-break:break-all}.swagger-ui .curl-command{position:relative}.swagger-ui .download-contents{align-items:center;background:#7d8293;border-radius:4px;bottom:10px;color:#fff;cursor:pointer;display:flex;font-family:sans-serif;font-size:14px;font-weight:600;height:30px;justify-content:center;padding:5px;position:absolute;right:10px;text-align:center}.swagger-ui .scheme-container{background:#fff;box-shadow:0 1px 2px 0 #00000026;margin:0 0 20px;padding:30px 0}.swagger-ui .scheme-container .schemes{align-items:flex-end;display:flex}.swagger-ui .scheme-container .schemes>label{color:#3b4151;display:flex;flex-direction:column;font-family:sans-serif;font-size:12px;font-weight:700;margin:-20px 15px 0 0}.swagger-ui .scheme-container .schemes>label select{min-width:130px;text-transform:uppercase}.swagger-ui .loading-container{align-items:center;display:flex;flex-direction:column;justify-content:center;margin-top:1em;min-height:1px;padding:40px 0 60px}.swagger-ui .loading-container .loading{position:relative}.swagger-ui .loading-container .loading:after{color:#3b4151;content:"loading";font-family:sans-serif;font-size:10px;font-weight:700;left:50%;position:absolute;text-transform:uppercase;top:50%;transform:translate(-50%,-50%)}.swagger-ui .loading-container .loading:before{animation:rotation 1s linear infinite,opacity .5s;backface-visibility:hidden;border-radius:100%;border:2px solid #5555551a;border-top-color:#0009;content:"";display:block;height:60px;left:50%;margin:-30px;opacity:1;position:absolute;top:50%;width:60px}@keyframes rotation{to{transform:rotate(1turn)}}.swagger-ui .response-controls{display:flex;padding-top:1em}.swagger-ui .response-control-media-type{margin-right:1em}.swagger-ui .response-control-media-type--accept-controller select{border-color:green}.swagger-ui .response-control-media-type__accept-message{color:green;font-size:.7em}.swagger-ui .response-control-examples__title,.swagger-ui .response-control-media-type__title{display:block;font-size:.7em;margin-bottom:.2em}@keyframes blinker{50%{opacity:0}}.swagger-ui .hidden{display:none}.swagger-ui .no-margin{border:none;height:auto;margin:0;padding:0}.swagger-ui .float-right{float:right}.swagger-ui .svg-assets{height:0;position:absolute;width:0}.swagger-ui section h3{color:#3b4151;font-family:sans-serif}.swagger-ui a.nostyle{display:inline}.swagger-ui a.nostyle,.swagger-ui a.nostyle:visited{color:inherit;cursor:pointer;text-decoration:inherit}.swagger-ui .fallback{color:#aaa;padding:1em}.swagger-ui .version-pragma{height:100%;padding:5em 0}.swagger-ui .version-pragma__message{display:flex;font-size:1.2em;height:100%;justify-content:center;line-height:1.5em;padding:0 .6em;text-align:center}.swagger-ui .version-pragma__message>div{flex:1;max-width:55ch}.swagger-ui .version-pragma__message code{background-color:#dedede;padding:4px 4px 2px;white-space:pre}.swagger-ui .opblock-link{font-weight:400}.swagger-ui .opblock-link.shown{font-weight:700}.swagger-ui span.token-string{color:#555}.swagger-ui span.token-not-formatted{color:#555;font-weight:700}.swagger-ui .btn{background:#0000;border:2px solid gray;border-radius:4px;box-shadow:0 1px 2px #0000001a;color:#3b4151;font-family:sans-serif;font-size:14px;font-weight:700;padding:5px 23px;transition:all .3s}.swagger-ui .btn.btn-sm{font-size:12px;padding:4px 23px}.swagger-ui .btn[disabled]{cursor:not-allowed;opacity:.3}.swagger-ui .btn:hover{box-shadow:0 0 5px #0000004d}.swagger-ui .btn.cancel{background-color:initial;border-color:#ff6060;color:#ff6060;font-family:sans-serif}.swagger-ui .btn.authorize{background-color:initial;border-color:#49cc90;color:#49cc90;display:inline;line-height:1}.swagger-ui .btn.authorize span{float:left;padding:4px 20px 0 0}.swagger-ui .btn.authorize svg{fill:#49cc90}.swagger-ui .btn.execute{background-color:#4990e2;border-color:#4990e2;color:#fff}.swagger-ui .btn-group{display:flex;padding:30px}.swagger-ui .btn-group .btn{flex:1}.swagger-ui .btn-group .btn:first-child{border-radius:4px 0 0 4px}.swagger-ui .btn-group .btn:last-child{border-radius:0 4px 4px 0}.swagger-ui .authorization__btn{background:none;border:none;padding:0 0 0 10px}.swagger-ui .authorization__btn.locked{opacity:1}.swagger-ui .authorization__btn.unlocked{opacity:.4}.swagger-ui .model-box-control,.swagger-ui .models-control,.swagger-ui .opblock-summary-control{all:inherit;border-bottom:0;cursor:pointer;flex:1;padding:0}.swagger-ui .model-box-control:focus,.swagger-ui .models-control:focus,.swagger-ui .opblock-summary-control:focus{outline:auto}.swagger-ui .expand-methods,.swagger-ui .expand-operation{background:none;border:none}.swagger-ui .expand-methods svg,.swagger-ui .expand-operation svg{height:20px;width:20px}.swagger-ui .expand-methods{padding:0 10px}.swagger-ui .expand-methods:hover svg{fill:#404040}.swagger-ui .expand-methods svg{fill:#707070;transition:all .3s}.swagger-ui button{cursor:pointer}.swagger-ui button.invalid{animation:shake .4s 1;background:#feebeb;border-color:#f93e3e}.swagger-ui .copy-to-clipboard{align-items:center;background:#7d8293;border:none;border-radius:4px;bottom:10px;display:flex;height:30px;justify-content:center;position:absolute;right:100px;width:30px}.swagger-ui .copy-to-clipboard button{background:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="15" aria-hidden="true"><path fill="%23fff" fill-rule="evenodd" d="M4 12h4v1H4v-1zm5-6H4v1h5V6zm2 3V7l-3 3 3 3v-2h5V9h-5zM6.5 8H4v1h2.5V8zM4 11h2.5v-1H4v1zm9 1h1v2c-.02.28-.11.52-.3.7-.19.18-.42.28-.7.3H3c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h3c0-1.11.89-2 2-2 1.11 0 2 .89 2 2h3c.55 0 1 .45 1 1v5h-1V5H3v9h10v-2zM4 4h8c0-.55-.45-1-1-1h-1c-.55 0-1-.45-1-1s-.45-1-1-1-1 .45-1 1-.45 1-1 1H5c-.55 0-1 .45-1 1z"/></svg>') 50% no-repeat;border:none;flex-grow:1;flex-shrink:1;height:25px}.swagger-ui .curl-command .copy-to-clipboard{bottom:5px;height:20px;right:10px;width:20px}.swagger-ui .curl-command .copy-to-clipboard button{height:18px}.swagger-ui select{appearance:none;background:#f7f7f7 url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M13.418 7.859a.695.695 0 0 1 .978 0 .68.68 0 0 1 0 .969l-3.908 3.83a.697.697 0 0 1-.979 0l-3.908-3.83a.68.68 0 0 1 0-.969.695.695 0 0 1 .978 0L10 11l3.418-3.141z"/></svg>') right 10px center no-repeat;background-size:20px;border:2px solid #41444e;border-radius:4px;box-shadow:0 1px 2px 0 #00000040;color:#3b4151;font-family:sans-serif;font-size:14px;font-weight:700;padding:5px 40px 5px 10px}.swagger-ui select[multiple]{background:#f7f7f7;margin:5px 0;padding:5px}.swagger-ui select.invalid{animation:shake .4s 1;background:#feebeb;border-color:#f93e3e}.swagger-ui .opblock-body select{min-width:230px}@media (max-width:768px){.swagger-ui .opblock-body select{min-width:180px}}.swagger-ui label{color:#3b4151;font-family:sans-serif;font-size:12px;font-weight:700;margin:0 0 5px}@media (max-width:768px){.swagger-ui input[type=email],.swagger-ui input[type=file],.swagger-ui input[type=password],.swagger-ui input[type=search],.swagger-ui input[type=text]{max-width:175px}}.swagger-ui input[type=email],.swagger-ui input[type=file],.swagger-ui input[type=password],.swagger-ui input[type=search],.swagger-ui input[type=text],.swagger-ui textarea{background:#fff;border:1px solid #d9d9d9;border-radius:4px;margin:5px 0;min-width:100px;padding:8px 10px}.swagger-ui input[type=email].invalid,.swagger-ui input[type=file].invalid,.swagger-ui input[type=password].invalid,.swagger-ui input[type=search].invalid,.swagger-ui input[type=text].invalid,.swagger-ui textarea.invalid{animation:shake .4s 1;background:#feebeb;border-color:#f93e3e}.swagger-ui input[disabled],.swagger-ui select[disabled],.swagger-ui textarea[disabled]{background-color:#fafafa;color:#888;cursor:not-allowed}.swagger-ui select[disabled]{border-color:#888}.swagger-ui textarea[disabled]{background-color:#41444e;color:#fff}@keyframes shake{10%,90%{transform:translate3d(-1px,0,0)}20%,80%{transform:translate3d(2px,0,0)}30%,50%,70%{transform:translate3d(-4px,0,0)}40%,60%{transform:translate3d(4px,0,0)}}.swagger-ui textarea{background:#fffc;border:none;border-radius:4px;color:#3b4151;font-family:monospace;font-size:12px;font-weight:600;min-height:280px;outline:none;padding:10px;width:100%}.swagger-ui textarea:focus{border:2px solid #61affe}.swagger-ui textarea.curl{background:#41444e;border-radius:4px;color:#fff;font-family:monospace;font-size:12px;font-weight:600;margin:0;min-height:100px;padding:10px;resize:none}.swagger-ui .checkbox{color:#303030;padding:5px 0 10px;transition:opacity .5s}.swagger-ui .checkbox label{display:flex}.swagger-ui .checkbox p{color:#3b4151;font-family:monospace;font-style:italic;font-weight:400!important;font-weight:600;margin:0!important}.swagger-ui .checkbox input[type=checkbox]{display:none}.swagger-ui .checkbox input[type=checkbox]+label>.item{background:#e8e8e8;border-radius:1px;box-shadow:0 0 0 2px #e8e8e8;cursor:pointer;display:inline-block;flex:none;height:16px;margin:0 8px 0 0;padding:5px;position:relative;top:3px;width:16px}.swagger-ui .checkbox input[type=checkbox]+label>.item:active{transform:scale(.9)}.swagger-ui .checkbox input[type=checkbox]:checked+label>.item{background:#e8e8e8 url('data:image/svg+xml;charset=utf-8,<svg width="10" height="8" viewBox="3 7 10 8" xmlns="http://www.w3.org/2000/svg"><path fill="%2341474E" fill-rule="evenodd" d="M6.333 15 3 11.667l1.333-1.334 2 2L11.667 7 13 8.333z"/></svg>') 50% no-repeat}.swagger-ui .dialog-ux{bottom:0;left:0;position:fixed;right:0;top:0;z-index:9999}.swagger-ui .dialog-ux .backdrop-ux{background:#000c;bottom:0;left:0;position:fixed;right:0;top:0}.swagger-ui .dialog-ux .modal-ux{background:#fff;border:1px solid #ebebeb;border-radius:4px;box-shadow:0 10px 30px 0 #0003;left:50%;max-width:650px;min-width:300px;position:absolute;top:50%;transform:translate(-50%,-50%);width:100%;z-index:9999}.swagger-ui .dialog-ux .modal-ux-content{max-height:540px;overflow-y:auto;padding:20px}.swagger-ui .dialog-ux .modal-ux-content p{color:#41444e;color:#3b4151;font-family:sans-serif;font-size:12px;margin:0 0 5px}.swagger-ui .dialog-ux .modal-ux-content h4{color:#3b4151;font-family:sans-serif;font-size:18px;font-weight:600;margin:15px 0 0}.swagger-ui .dialog-ux .modal-ux-header{align-items:center;border-bottom:1px solid #ebebeb;display:flex;padding:12px 0}.swagger-ui .dialog-ux .modal-ux-header .close-modal{appearance:none;background:none;border:none;padding:0 10px}.swagger-ui .dialog-ux .modal-ux-header h3{color:#3b4151;flex:1;font-family:sans-serif;font-size:20px;font-weight:600;margin:0;padding:0 20px}.swagger-ui .model{color:#3b4151;font-family:monospace;font-size:12px;font-weight:300;font-weight:600}.swagger-ui .model .deprecated span,.swagger-ui .model .deprecated td{color:#a0a0a0!important}.swagger-ui .model .deprecated>td:first-of-type{text-decoration:line-through}.swagger-ui .model-toggle{cursor:pointer;display:inline-block;font-size:10px;margin:auto .3em;position:relative;top:6px;transform:rotate(90deg);transform-origin:50% 50%;transition:transform .15s ease-in}.swagger-ui .model-toggle.collapsed{transform:rotate(0deg)}.swagger-ui .model-toggle:after{background:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>') 50% no-repeat;background-size:100%;content:"";display:block;height:20px;width:20px}.swagger-ui .model-jump-to-path{cursor:pointer;position:relative}.swagger-ui .model-jump-to-path .view-line-link{cursor:pointer;position:absolute;top:-.4em}.swagger-ui .model-title{position:relative}.swagger-ui .model-title:hover .model-hint{visibility:visible}.swagger-ui .model-hint{background:#000000b3;border-radius:4px;color:#ebebeb;padding:.1em .5em;position:absolute;top:-1.8em;visibility:hidden;white-space:nowrap}.swagger-ui .model p{margin:0 0 1em}.swagger-ui .model .property{color:#999;font-style:italic}.swagger-ui .model .property.primitive{color:#6b6b6b}.swagger-ui table.model tr.description{color:#666;font-weight:400}.swagger-ui table.model tr.description td:first-child,.swagger-ui table.model tr.property-row.required td:first-child{font-weight:700}.swagger-ui table.model tr.property-row td{vertical-align:top}.swagger-ui table.model tr.property-row td:first-child{padding-right:.2em}.swagger-ui table.model tr.property-row .star{color:red}.swagger-ui table.model tr.extension{color:#777}.swagger-ui table.model tr.extension td:last-child{vertical-align:top}.swagger-ui section.models{border:1px solid #3b41514d;border-radius:4px;margin:30px 0}.swagger-ui section.models .pointer{cursor:pointer}.swagger-ui section.models.is-open{padding:0 0 20px}.swagger-ui section.models.is-open h4{border-bottom:1px solid #3b41514d;margin:0 0 5px}.swagger-ui section.models h4{align-items:center;color:#606060;cursor:pointer;display:flex;font-family:sans-serif;font-size:16px;margin:0;padding:10px 20px 10px 10px;transition:all .2s}.swagger-ui section.models h4 svg{transition:all .4s}.swagger-ui section.models h4 span{flex:1}.swagger-ui section.models h4:hover{background:#00000005}.swagger-ui section.models h5{color:#707070;font-family:sans-serif;font-size:16px;margin:0 0 10px}.swagger-ui section.models .model-jump-to-path{position:relative;top:5px}.swagger-ui section.models .model-container{background:#0000000d;border-radius:4px;margin:0 20px 15px;position:relative;transition:all .5s}.swagger-ui section.models .model-container:hover{background:#00000012}.swagger-ui section.models .model-container:first-of-type{margin:20px}.swagger-ui section.models .model-container:last-of-type{margin:0 20px}.swagger-ui section.models .model-container .models-jump-to-path{opacity:.65;position:absolute;right:5px;top:8px}.swagger-ui section.models .model-box{background:none}.swagger-ui .model-box{background:#0000001a;border-radius:4px;display:inline-block;padding:10px}.swagger-ui .model-box .model-jump-to-path{position:relative;top:4px}.swagger-ui .model-box.deprecated{opacity:.5}.swagger-ui .model-title{color:#505050;font-family:sans-serif;font-size:16px}.swagger-ui .model-title img{bottom:0;margin-left:1em;position:relative}.swagger-ui .model-deprecated-warning{color:#f93e3e;font-family:sans-serif;font-size:16px;font-weight:600;margin-right:1em}.swagger-ui span>span.model .brace-close{padding:0 0 0 10px}.swagger-ui .prop-name{display:inline-block;margin-right:1em}.swagger-ui .prop-type{color:#55a}.swagger-ui .prop-enum{display:block}.swagger-ui .prop-format{color:#606060}.swagger-ui .servers>label{color:#3b4151;font-family:sans-serif;font-size:12px;margin:-20px 15px 0 0}.swagger-ui .servers>label select{max-width:100%;min-width:130px}.swagger-ui .servers h4.message{padding-bottom:2em}.swagger-ui .servers table tr{width:30em}.swagger-ui .servers table td{display:inline-block;max-width:15em;padding-bottom:10px;padding-top:10px;vertical-align:middle}.swagger-ui .servers table td:first-of-type{padding-right:1em}.swagger-ui .servers table td input{height:100%;width:100%}.swagger-ui .servers .computed-url{margin:2em 0}.swagger-ui .servers .computed-url code{display:inline-block;font-size:16px;margin:0 1em;padding:4px}.swagger-ui .servers-title{font-size:12px;font-weight:700}.swagger-ui .operation-servers h4.message{margin-bottom:2em}.swagger-ui table{border-collapse:collapse;padding:0 10px;width:100%}.swagger-ui table.model tbody tr td{padding:0;vertical-align:top}.swagger-ui table.model tbody tr td:first-of-type{padding:0 0 0 2em;width:174px}.swagger-ui table.headers td{color:#3b4151;font-family:monospace;font-size:12px;font-weight:300;font-weight:600;vertical-align:middle}.swagger-ui table.headers .header-example{color:#999;font-style:italic}.swagger-ui table tbody tr td{padding:10px 0 0;vertical-align:top}.swagger-ui table tbody tr td:first-of-type{min-width:6em;padding:10px 0}.swagger-ui table thead tr td,.swagger-ui table thead tr th{border-bottom:1px solid #3b415133;color:#3b4151;font-family:sans-serif;font-size:12px;font-weight:700;padding:12px 0;text-align:left}.swagger-ui .parameters-col_description{margin-bottom:2em;width:99%}.swagger-ui .parameters-col_description input[type=text]{max-width:340px;width:100%}.swagger-ui .parameters-col_description select{border-width:1px}.swagger-ui .parameter__name{color:#3b4151;font-family:sans-serif;font-size:16px;font-weight:400;margin-right:.75em}.swagger-ui .parameter__name.required{font-weight:700}.swagger-ui .parameter__name.required span{color:red}.swagger-ui .parameter__name.required:after{color:#f009;content:"required";font-size:10px;padding:5px;position:relative;top:-6px}.swagger-ui .parameter__extension,.swagger-ui .parameter__in{color:gray;font-family:monospace;font-size:12px;font-style:italic;font-weight:600}.swagger-ui .parameter__deprecated{color:red;font-family:monospace;font-size:12px;font-style:italic;font-weight:600}.swagger-ui .parameter__empty_value_toggle{display:block;font-size:13px;padding-bottom:12px;padding-top:5px}.swagger-ui .parameter__empty_value_toggle input{margin-right:7px}.swagger-ui .parameter__empty_value_toggle.disabled{opacity:.7}.swagger-ui .table-container{padding:20px}.swagger-ui .response-col_description{width:99%}.swagger-ui .response-col_links{min-width:6em}.swagger-ui .response__extension{color:gray;font-family:monospace;font-size:12px;font-style:italic;font-weight:600}.swagger-ui .topbar{background-color:#1b1b1b;padding:10px 0}.swagger-ui .topbar .topbar-wrapper,.swagger-ui .topbar a{align-items:center;display:flex}.swagger-ui .topbar a{color:#fff;flex:1;font-family:sans-serif;font-size:1.5em;font-weight:700;max-width:300px;text-decoration:none}.swagger-ui .topbar a span{margin:0;padding:0 10px}.swagger-ui .topbar .download-url-wrapper{display:flex;flex:3;justify-content:flex-end}.swagger-ui .topbar .download-url-wrapper input[type=text]{border:2px solid #62a03f;border-radius:4px 0 0 4px;margin:0;outline:none;width:100%}.swagger-ui .topbar .download-url-wrapper .select-label{align-items:center;color:#f0f0f0;display:flex;margin:0;max-width:600px;width:100%}.swagger-ui .topbar .download-url-wrapper .select-label span{flex:1;font-size:16px;padding:0 10px 0 0;text-align:right}.swagger-ui .topbar .download-url-wrapper .select-label select{border:2px solid #62a03f;box-shadow:none;flex:2;outline:none;width:100%}.swagger-ui .topbar .download-url-wrapper .download-url-button{background:#62a03f;border:none;border-radius:0 4px 4px 0;color:#fff;font-family:sans-serif;font-size:16px;font-weight:700;padding:4px 30px}.swagger-ui .info{margin:50px 0}.swagger-ui .info.failed-config{margin-left:auto;margin-right:auto;max-width:880px;text-align:center}.swagger-ui .info hgroup.main{margin:0 0 20px}.swagger-ui .info hgroup.main a{font-size:12px}.swagger-ui .info pre{font-size:14px}.swagger-ui .info li,.swagger-ui .info p,.swagger-ui .info table{color:#3b4151;font-family:sans-serif;font-size:14px}.swagger-ui .info h1,.swagger-ui .info h2,.swagger-ui .info h3,.swagger-ui .info h4,.swagger-ui .info h5{color:#3b4151;font-family:sans-serif}.swagger-ui .info a{color:#4990e2;font-family:sans-serif;font-size:14px;transition:all .4s}.swagger-ui .info a:hover{color:#1f69c0}.swagger-ui .info>div{margin:0 0 5px}.swagger-ui .info .base-url{color:#3b4151;font-family:monospace;font-size:12px;font-weight:300!important;font-weight:600;margin:0}.swagger-ui .info .title{color:#3b4151;font-family:sans-serif;font-size:36px;margin:0}.swagger-ui .info .title small{background:#7d8492;border-radius:57px;display:inline-block;font-size:10px;margin:0 0 0 5px;padding:2px 4px;position:relative;top:-5px;vertical-align:super}.swagger-ui .info .title small.version-stamp{background-color:#89bf04}.swagger-ui .info .title small pre{color:#fff;font-family:sans-serif;margin:0;padding:0}.swagger-ui .auth-btn-wrapper{display:flex;justify-content:center;padding:10px 0}.swagger-ui .auth-btn-wrapper .btn-done{margin-right:1em}.swagger-ui .auth-wrapper{display:flex;flex:1;justify-content:flex-end}.swagger-ui .auth-wrapper .authorize{margin-right:10px;padding-right:20px}.swagger-ui .auth-container{border-bottom:1px solid #ebebeb;margin:0 0 10px;padding:10px 20px}.swagger-ui .auth-container:last-of-type{border:0;margin:0;padding:10px 20px}.swagger-ui .auth-container h4{margin:5px 0 15px!important}.swagger-ui .auth-container .wrapper{margin:0;padding:0}.swagger-ui .auth-container input[type=password],.swagger-ui .auth-container input[type=text]{min-width:230px}.swagger-ui .auth-container .errors{background-color:#fee;border-radius:4px;color:red;color:#3b4151;font-family:monospace;font-size:12px;font-weight:600;margin:1em;padding:10px}.swagger-ui .auth-container .errors b{margin-right:1em;text-transform:capitalize}.swagger-ui .scopes h2{color:#3b4151;font-family:sans-serif;font-size:14px}.swagger-ui .scopes h2 a{color:#4990e2;cursor:pointer;font-size:12px;padding-left:10px;text-decoration:underline}.swagger-ui .scope-def{padding:0 0 20px}.swagger-ui .errors-wrapper{animation:scaleUp .5s;background:#f93e3e1a;border:2px solid #f93e3e;border-radius:4px;margin:20px;padding:10px 20px}.swagger-ui .errors-wrapper .error-wrapper{margin:0 0 10px}.swagger-ui .errors-wrapper .errors h4{color:#3b4151;font-family:monospace;font-size:14px;font-weight:600;margin:0}.swagger-ui .errors-wrapper .errors small{color:#606060}.swagger-ui .errors-wrapper .errors .message{white-space:pre-line}.swagger-ui .errors-wrapper .errors .message.thrown{max-width:100%}.swagger-ui .errors-wrapper .errors .error-line{cursor:pointer;text-decoration:underline}.swagger-ui .errors-wrapper hgroup{align-items:center;display:flex}.swagger-ui .errors-wrapper hgroup h4{color:#3b4151;flex:1;font-family:sans-serif;font-size:20px;margin:0}@keyframes scaleUp{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}.swagger-ui .Resizer.vertical.disabled{display:none}.swagger-ui .markdown p,.swagger-ui .markdown pre,.swagger-ui .renderedMarkdown p,.swagger-ui .renderedMarkdown pre{margin:1em auto;word-break:break-all;word-break:break-word}.swagger-ui .markdown pre,.swagger-ui .renderedMarkdown pre{background:none;color:#000;font-weight:400;padding:0;white-space:pre-wrap}.swagger-ui .markdown code,.swagger-ui .renderedMarkdown code{background:#0000000d;border-radius:4px;color:#9012fe;font-family:monospace;font-size:14px;font-weight:600;padding:5px 7px}.swagger-ui .markdown pre>code,.swagger-ui .renderedMarkdown pre>code{display:block}.toast-center-center{top:50%;left:50%;transform:translate(-50%,-50%)}.toast-top-center{top:0;right:0;width:100%}.toast-bottom-center{bottom:0;right:0;width:100%}.toast-top-full-width{top:0;right:0;width:100%}.toast-bottom-full-width{bottom:0;right:0;width:100%}.toast-top-left{top:12px;left:12px}.toast-top-right{top:12px;right:12px}.toast-bottom-right{right:12px;bottom:12px}.toast-bottom-left{bottom:12px;left:12px}.toast-title{font-weight:700}.toast-message{word-wrap:break-word}.toast-message a,.toast-message label{color:#fff}.toast-message a:hover{color:#ccc;text-decoration:none}.toast-close-button{position:relative;right:-.3em;top:-.3em;float:right;font-size:20px;font-weight:700;color:#fff;text-shadow:0 1px 0 #fff}.toast-close-button:focus,.toast-close-button:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4}button.toast-close-button{padding:0;cursor:pointer;background:#0000;border:0}.toast-container{pointer-events:none;position:fixed;z-index:999999}.toast-container *{box-sizing:border-box}.toast-container .ngx-toastr{position:relative;overflow:hidden;margin:0 0 6px;padding:15px 15px 15px 50px;width:300px;border-radius:3px 3px 3px 3px;background-position:15px;background-repeat:no-repeat;background-size:24px;box-shadow:0 0 12px #999;color:#fff}.toast-container .ngx-toastr:hover{box-shadow:0 0 12px #000;opacity:1;cursor:pointer}.toast-info{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCA1MTIgNTEyJyB3aWR0aD0nNTEyJyBoZWlnaHQ9JzUxMic+PHBhdGggZmlsbD0ncmdiKDI1NSwyNTUsMjU1KScgZD0nTTI1NiA4QzExOS4wNDMgOCA4IDExOS4wODMgOCAyNTZjMCAxMzYuOTk3IDExMS4wNDMgMjQ4IDI0OCAyNDhzMjQ4LTExMS4wMDMgMjQ4LTI0OEM1MDQgMTE5LjA4MyAzOTIuOTU3IDggMjU2IDh6bTAgMTEwYzIzLjE5NiAwIDQyIDE4LjgwNCA0MiA0MnMtMTguODA0IDQyLTQyIDQyLTQyLTE4LjgwNC00Mi00MiAxOC44MDQtNDIgNDItNDJ6bTU2IDI1NGMwIDYuNjI3LTUuMzczIDEyLTEyIDEyaC04OGMtNi42MjcgMC0xMi01LjM3My0xMi0xMnYtMjRjMC02LjYyNyA1LjM3My0xMiAxMi0xMmgxMnYtNjRoLTEyYy02LjYyNyAwLTEyLTUuMzczLTEyLTEydi0yNGMwLTYuNjI3IDUuMzczLTEyIDEyLTEyaDY0YzYuNjI3IDAgMTIgNS4zNzMgMTIgMTJ2MTAwaDEyYzYuNjI3IDAgMTIgNS4zNzMgMTIgMTJ2MjR6Jy8+PC9zdmc+")}.toast-error{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCA1MTIgNTEyJyB3aWR0aD0nNTEyJyBoZWlnaHQ9JzUxMic+PHBhdGggZmlsbD0ncmdiKDI1NSwyNTUsMjU1KScgZD0nTTI1NiA4QzExOSA4IDggMTE5IDggMjU2czExMSAyNDggMjQ4IDI0OCAyNDgtMTExIDI0OC0yNDhTMzkzIDggMjU2IDh6bTEyMS42IDMxMy4xYzQuNyA0LjcgNC43IDEyLjMgMCAxN0wzMzggMzc3LjZjLTQuNyA0LjctMTIuMyA0LjctMTcgMEwyNTYgMzEybC02NS4xIDY1LjZjLTQuNyA0LjctMTIuMyA0LjctMTcgMEwxMzQuNCAzMzhjLTQuNy00LjctNC43LTEyLjMgMC0xN2w2NS42LTY1LTY1LjYtNjUuMWMtNC43LTQuNy00LjctMTIuMyAwLTE3bDM5LjYtMzkuNmM0LjctNC43IDEyLjMtNC43IDE3IDBsNjUgNjUuNyA2NS4xLTY1LjZjNC43LTQuNyAxMi4zLTQuNyAxNyAwbDM5LjYgMzkuNmM0LjcgNC43IDQuNyAxMi4zIDAgMTdMMzEyIDI1Nmw2NS42IDY1LjF6Jy8+PC9zdmc+")}.toast-success{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCA1MTIgNTEyJyB3aWR0aD0nNTEyJyBoZWlnaHQ9JzUxMic+PHBhdGggZmlsbD0ncmdiKDI1NSwyNTUsMjU1KScgZD0nTTE3My44OTggNDM5LjQwNGwtMTY2LjQtMTY2LjRjLTkuOTk3LTkuOTk3LTkuOTk3LTI2LjIwNiAwLTM2LjIwNGwzNi4yMDMtMzYuMjA0YzkuOTk3LTkuOTk4IDI2LjIwNy05Ljk5OCAzNi4yMDQgMEwxOTIgMzEyLjY5IDQzMi4wOTUgNzIuNTk2YzkuOTk3LTkuOTk3IDI2LjIwNy05Ljk5NyAzNi4yMDQgMGwzNi4yMDMgMzYuMjA0YzkuOTk3IDkuOTk3IDkuOTk3IDI2LjIwNiAwIDM2LjIwNGwtMjk0LjQgMjk0LjQwMWMtOS45OTggOS45OTctMjYuMjA3IDkuOTk3LTM2LjIwNC0uMDAxeicvPjwvc3ZnPg==")}.toast-warning{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCA1NzYgNTEyJyB3aWR0aD0nNTc2JyBoZWlnaHQ9JzUxMic+PHBhdGggZmlsbD0ncmdiKDI1NSwyNTUsMjU1KScgZD0nTTU2OS41MTcgNDQwLjAxM0M1ODcuOTc1IDQ3Mi4wMDcgNTY0LjgwNiA1MTIgNTI3Ljk0IDUxMkg0OC4wNTRjLTM2LjkzNyAwLTU5Ljk5OS00MC4wNTUtNDEuNTc3LTcxLjk4N0wyNDYuNDIzIDIzLjk4NWMxOC40NjctMzIuMDA5IDY0LjcyLTMxLjk1MSA4My4xNTQgMGwyMzkuOTQgNDE2LjAyOHpNMjg4IDM1NGMtMjUuNDA1IDAtNDYgMjAuNTk1LTQ2IDQ2czIwLjU5NSA0NiA0NiA0NiA0Ni0yMC41OTUgNDYtNDYtMjAuNTk1LTQ2LTQ2LTQ2em0tNDMuNjczLTE2NS4zNDZsNy40MTggMTM2Yy4zNDcgNi4zNjQgNS42MDkgMTEuMzQ2IDExLjk4MiAxMS4zNDZoNDguNTQ2YzYuMzczIDAgMTEuNjM1LTQuOTgyIDExLjk4Mi0xMS4zNDZsNy40MTgtMTM2Yy4zNzUtNi44NzQtNS4wOTgtMTIuNjU0LTExLjk4Mi0xMi42NTRoLTYzLjM4M2MtNi44ODQgMC0xMi4zNTYgNS43OC0xMS45ODEgMTIuNjU0eicvPjwvc3ZnPg==")}.toast-container.toast-bottom-center .ngx-toastr,.toast-container.toast-top-center .ngx-toastr{width:300px;margin-left:auto;margin-right:auto}.toast-container.toast-bottom-full-width .ngx-toastr,.toast-container.toast-top-full-width .ngx-toastr{width:96%;margin-left:auto;margin-right:auto}.ngx-toastr{background-color:#030303;pointer-events:auto}.toast-success{background-color:#51a351}.toast-error{background-color:#bd362f}.toast-info{background-color:#2f96b4}.toast-warning{background-color:#f89406}.toast-progress{position:absolute;left:0;bottom:0;height:4px;background-color:#000;opacity:.4}@media all and (max-width: 240px){.toast-container .ngx-toastr.div{padding:8px 8px 8px 50px;width:11em}.toast-container .toast-close-button{right:-.2em;top:-.2em}}@media all and (min-width: 241px) and (max-width: 480px){.toast-container .ngx-toastr.div{padding:8px 8px 8px 50px;width:18em}.toast-container .toast-close-button{right:-.2em;top:-.2em}}@media all and (min-width: 481px) and (max-width: 768px){.toast-container .ngx-toastr.div{padding:15px 15px 15px 50px;width:25em}}.tree-children.tree-children-no-padding{padding-left:0}.tree-children{overflow:hidden}.node-drop-slot{display:block;height:2px}.node-drop-slot.is-dragging-over{background:#dfe;height:20px;border:2px dotted #888}.toggle-children-wrapper-expanded .toggle-children{transform:rotate(90deg)}.toggle-children-wrapper-collapsed .toggle-children{transform:rotate(0)}.toggle-children-wrapper{padding:2px 3px 5px 1px}.toggle-children{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABAhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ1dWlkOjY1RTYzOTA2ODZDRjExREJBNkUyRDg4N0NFQUNCNDA3IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkYzRkRFQjcxODUzNTExRTU4RTQwRkQwODFEOUZEMEE3IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkYzRkRFQjcwODUzNTExRTU4RTQwRkQwODFEOUZEMEE3IiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MTk5NzA1OGEtZDI3OC00NDZkLWE4ODgtNGM4MGQ4YWI1NzNmIiBzdFJlZjpkb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6YzRkZmQxMGMtY2NlNS0xMTc4LWE5OGQtY2NkZmM5ODk5YWYwIi8+IDxkYzp0aXRsZT4gPHJkZjpBbHQ+IDxyZGY6bGkgeG1sOmxhbmc9IngtZGVmYXVsdCI+Z2x5cGhpY29uczwvcmRmOmxpPiA8L3JkZjpBbHQ+IDwvZGM6dGl0bGU+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+5iogFwAAAGhJREFUeNpiYGBgKABigf///zOQg0EARH4A4gZyDIIZ8B/JoAJKDIDhB0CcQIkBRBtEyABkgxwoMQCGD6AbRKoBGAYxQgXIBRuZGKgAKPIC3QLxArnRSHZCIjspk52ZKMrOFBUoAAEGAKnq593MQAZtAAAAAElFTkSuQmCC");height:8px;width:9px;background-size:contain;background-repeat:no-repeat;background-position:50%}.toggle-children,.toggle-children-placeholder{display:inline-block;position:relative;top:1px}.toggle-children-placeholder{height:10px;width:10px;padding-right:3px}.node-content-wrapper{display:inline-block;padding:2px 5px;border-radius:2px;transition:background-color .15s,box-shadow .15s}.node-wrapper{display:flex;align-items:flex-start}.node-content-wrapper-active,.node-content-wrapper-active.node-content-wrapper-focused,.node-content-wrapper.node-content-wrapper-active:hover{background:#beebff}.node-content-wrapper-focused{background:#e7f4f9}.node-content-wrapper:hover{background:#f7fbff}.node-content-wrapper-active,.node-content-wrapper-focused,.node-content-wrapper:hover{box-shadow:inset 0 0 1px #999}.node-content-wrapper.is-dragging-over{background:#dfe;box-shadow:inset 0 0 1px #999}.node-content-wrapper.is-dragging-over-disabled{opacity:.5}tree-viewport{-webkit-tap-highlight-color:transparent;height:100%;overflow:auto;display:block}.tree-children{padding-left:20px}.empty-tree-drop-slot .node-drop-slot{height:20px;min-width:100px}.angular-tree-component{width:100%;position:relative;display:inline-block;cursor:pointer;-webkit-touch-callout:none;user-select:none}tree-root .angular-tree-component-rtl{direction:rtl}tree-root .angular-tree-component-rtl .toggle-children-wrapper-collapsed .toggle-children{transform:rotate(180deg)!important}tree-root .angular-tree-component-rtl .tree-children{padding-right:20px;padding-left:0}tree-node-checkbox{padding:1px}:root{--gray-100:#f8f9fa;--gray-200:#e9ecef;--gray-300:#dee2e6;--gray-400:#ced4da;--gray-500:#adb5bd;--gray-600:#6c757d;--gray-700:#495057;--gray-800:#343a40;--gray-900:#212529;--black:#000;--barley-white:#fcecba;--fg-color-over-dark-bg:#fff;--fg-hover-color-over-dark-bg:#adb5bd;--body-color-bright:#f8f9fa;--body-bg:#fff;--body-color:#212529;--body-bg-alt:#e9ecef;--health-color-error:red;--health-color-healthy:#0b0;--health-color-warning:orange;--chart-color-red:#c9190b;--chart-color-blue:#06c;--chart-color-orange:#ef9234;--chart-color-yellow:#f6d173;--chart-color-green:#7cc674;--chart-color-gray:#ededed;--chart-color-cyan:#73c5c5;--chart-color-purple:#3c3d99;--chart-color-center-text:#151515;--chart-color-center-text-description:#72767b;--chart-color-tooltip-background:#000;--chart-danger:#c9190b;--card-cap-bg:#f8f9fa;--grid-gutter-width:30px;--datatable-divider-color:#00000017;--nav-tabs-margin-bottom:1rem;--tooltip-color:#fff;--tooltip-bg:#212529;--screen-sm-min:576px;--screen-md-min:768px;--screen-lg-min:992px;--screen-xl-min:1200px;--screen-xs-max:calc(576px - 1px);--screen-sm-max:calc(768px - 1px);--screen-md-max:calc(992px - 1px);--screen-lg-max:calc(1200px - 1px);--navbar-height:43px;--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#a94442;--red:#ef5c55;--orange:#fd7e14;--yellow:#ffc200;--green:#0b0;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#2b99a8;--secondary:#374249;--success:#0b0;--info:#2b99a8;--warning:#ffc200;--danger:#ef5c55;--light:#f8f9fa;--dark:#777;--accent:#ef5c55;--warning-dark:#fd7e14;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--breakpoint-2xl:1450px;--font-family-sans-serif:"Helvetica Neue",Helvetica,Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}
+/*!
+ * Bootstrap v4.6.1 (https://getbootstrap.com/)
+ * Copyright 2011-2021 The Bootstrap Authors
+ * Copyright 2011-2021 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ */*,:after,:before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:Helvetica Neue,Helvetica,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:initial;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;text-decoration:underline dotted;cursor:help;border-bottom:0;text-decoration-skip-ink:none}address{font-style:normal;line-height:inherit}address,dl,ol,ul{margin-bottom:1rem}dl,ol,ul{margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}a{color:#2b99a8;text-decoration:none;background-color:initial}a:hover{color:#1b626b;text-decoration:underline}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{border-style:none}img,svg{vertical-align:middle}svg{overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:initial}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem}.display-1,.display-2{font-weight:300;line-height:1.2}.display-2{font-size:5.5rem}.display-3{font-size:4.5rem}.display-3,.display-4{font-weight:300;line-height:1.2}.display-4{font-size:3.5rem}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid #0000001a}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-inline,.list-unstyled{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer:before{content:"— "}.img-fluid,.img-thumbnail{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#a94442;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width: 576px){.container,.container-sm{max-width:540px}}@media (min-width: 768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width: 992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width: 1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row,cd-about dl{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.cd-col-form,.cd-col-form-input,.cd-col-form-label,.cd-col-form-offset,.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-2xl,.col-2xl-1,.col-2xl-10,.col-2xl-11,.col-2xl-12,.col-2xl-2,.col-2xl-3,.col-2xl-4,.col-2xl-5,.col-2xl-6,.col-2xl-7,.col-2xl-8,.col-2xl-9,.col-2xl-auto,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto,cd-about dd,cd-about dt,cd-health cd-info-card,cd-health cd-info-card.cd-capacity-card,cd-health cd-info-card.cd-chart-card,cd-health cd-info-card.cd-performance-card,cd-health cd-info-card.cd-status-card,cd-modal .cd-col-form-input,cd-modal .cd-col-form-label,cd-modal .cd-col-form-offset{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-1>*{flex:0 0 100%;max-width:100%}.row-cols-2>*{flex:0 0 50%;max-width:50%}.row-cols-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-4>*{flex:0 0 25%;max-width:25%}.row-cols-5>*{flex:0 0 20%;max-width:20%}.row-cols-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.33333333%;max-width:8.33333333%}.col-2{flex:0 0 16.66666667%;max-width:16.66666667%}.col-3{flex:0 0 25%;max-width:25%}.col-4,cd-about dt{flex:0 0 33.33333333%;max-width:33.33333333%}.col-5{flex:0 0 41.66666667%;max-width:41.66666667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.33333333%;max-width:58.33333333%}.col-8,cd-about dd{flex:0 0 66.66666667%;max-width:66.66666667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.33333333%;max-width:83.33333333%}.col-11{flex:0 0 91.66666667%;max-width:91.66666667%}.cd-col-form,.col-12,cd-health cd-info-card{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}@media (min-width: 576px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.33333333%;max-width:8.33333333%}.col-sm-2{flex:0 0 16.66666667%;max-width:16.66666667%}.col-sm-3{flex:0 0 25%;max-width:25%}.cd-col-form-label,.col-sm-4{flex:0 0 33.33333333%;max-width:33.33333333%}.col-sm-5{flex:0 0 41.66666667%;max-width:41.66666667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.33333333%;max-width:58.33333333%}.cd-col-form-input,.cd-col-form-offset,.col-sm-8{flex:0 0 66.66666667%;max-width:66.66666667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.33333333%;max-width:83.33333333%}.col-sm-11{flex:0 0 91.66666667%;max-width:91.66666667%}.col-sm-12,cd-health cd-info-card{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.cd-col-form-offset,.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}}@media (min-width: 768px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-md-1>*{flex:0 0 100%;max-width:100%}.row-cols-md-2>*{flex:0 0 50%;max-width:50%}.row-cols-md-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-md-4>*{flex:0 0 25%;max-width:25%}.row-cols-md-5>*{flex:0 0 20%;max-width:20%}.row-cols-md-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.33333333%;max-width:8.33333333%}.col-md-2{flex:0 0 16.66666667%;max-width:16.66666667%}.col-md-3{flex:0 0 25%;max-width:25%}.cd-col-form-label,.col-md-4{flex:0 0 33.33333333%;max-width:33.33333333%}.col-md-5{flex:0 0 41.66666667%;max-width:41.66666667%}.col-md-6,cd-health cd-info-card{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.33333333%;max-width:58.33333333%}.cd-col-form-input,.cd-col-form-offset,.col-md-8{flex:0 0 66.66666667%;max-width:66.66666667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.33333333%;max-width:83.33333333%}.col-md-11{flex:0 0 91.66666667%;max-width:91.66666667%}.col-md-12,cd-health cd-info-card.cd-chart-card{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}}@media (min-width: 992px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.33333333%;max-width:8.33333333%}.col-lg-2{flex:0 0 16.66666667%;max-width:16.66666667%}.cd-col-form-label,.col-lg-3,cd-health cd-info-card.cd-capacity-card{flex:0 0 25%;max-width:25%}.col-lg-4,cd-health cd-info-card,cd-modal .cd-col-form-label{flex:0 0 33.33333333%;max-width:33.33333333%}.col-lg-5{flex:0 0 41.66666667%;max-width:41.66666667%}.col-lg-6,cd-health cd-info-card.cd-chart-card,cd-health cd-info-card.cd-performance-card{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.33333333%;max-width:58.33333333%}.cd-col-form,.col-lg-8,cd-modal .cd-col-form-input,cd-modal .cd-col-form-offset{flex:0 0 66.66666667%;max-width:66.66666667%}.cd-col-form-input,.cd-col-form-offset,.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.33333333%;max-width:83.33333333%}.col-lg-11{flex:0 0 91.66666667%;max-width:91.66666667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.cd-col-form-offset,.offset-lg-3{margin-left:25%}.offset-lg-4,cd-modal .cd-col-form-offset{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}}@media (min-width: 1200px){.col-xl,cd-health cd-info-card.cd-capacity-card,cd-health cd-info-card.cd-performance-card{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.33333333%;max-width:8.33333333%}.col-xl-2{flex:0 0 16.66666667%;max-width:16.66666667%}.col-xl-3,cd-health cd-info-card.cd-status-card{flex:0 0 25%;max-width:25%}.col-xl-4,cd-health cd-info-card.cd-chart-card{flex:0 0 33.33333333%;max-width:33.33333333%}.col-xl-5{flex:0 0 41.66666667%;max-width:41.66666667%}.cd-col-form,.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.33333333%;max-width:58.33333333%}.col-xl-8{flex:0 0 66.66666667%;max-width:66.66666667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.33333333%;max-width:83.33333333%}.col-xl-11{flex:0 0 91.66666667%;max-width:91.66666667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}}@media (min-width: 1450px){.col-2xl{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-2xl-1>*{flex:0 0 100%;max-width:100%}.row-cols-2xl-2>*{flex:0 0 50%;max-width:50%}.row-cols-2xl-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-2xl-4>*{flex:0 0 25%;max-width:25%}.row-cols-2xl-5>*{flex:0 0 20%;max-width:20%}.row-cols-2xl-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-2xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-2xl-1{flex:0 0 8.33333333%;max-width:8.33333333%}.col-2xl-2{flex:0 0 16.66666667%;max-width:16.66666667%}.col-2xl-3,cd-health cd-info-card.cd-chart-card{flex:0 0 25%;max-width:25%}.col-2xl-4{flex:0 0 33.33333333%;max-width:33.33333333%}.col-2xl-5{flex:0 0 41.66666667%;max-width:41.66666667%}.col-2xl-6{flex:0 0 50%;max-width:50%}.col-2xl-7{flex:0 0 58.33333333%;max-width:58.33333333%}.col-2xl-8{flex:0 0 66.66666667%;max-width:66.66666667%}.col-2xl-9{flex:0 0 75%;max-width:75%}.col-2xl-10{flex:0 0 83.33333333%;max-width:83.33333333%}.col-2xl-11{flex:0 0 91.66666667%;max-width:91.66666667%}.col-2xl-12{flex:0 0 100%;max-width:100%}.order-2xl-first{order:-1}.order-2xl-last{order:13}.order-2xl-0{order:0}.order-2xl-1{order:1}.order-2xl-2{order:2}.order-2xl-3{order:3}.order-2xl-4{order:4}.order-2xl-5{order:5}.order-2xl-6{order:6}.order-2xl-7{order:7}.order-2xl-8{order:8}.order-2xl-9{order:9}.order-2xl-10{order:10}.order-2xl-11{order:11}.order-2xl-12{order:12}.offset-2xl-0{margin-left:0}.offset-2xl-1{margin-left:8.33333333%}.offset-2xl-2{margin-left:16.66666667%}.offset-2xl-3{margin-left:25%}.offset-2xl-4{margin-left:33.33333333%}.offset-2xl-5{margin-left:41.66666667%}.offset-2xl-6{margin-left:50%}.offset-2xl-7{margin-left:58.33333333%}.offset-2xl-8{margin-left:66.66666667%}.offset-2xl-9{margin-left:75%}.offset-2xl-10{margin-left:83.33333333%}.offset-2xl-11{margin-left:91.66666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered,.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:#0000000d}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#c4e2e7}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#91cad2}.table-hover .table-primary:hover,.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#b2d9e0}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#c7cacc}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#979da0}.table-hover .table-secondary:hover,.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#babdc0}.table-success,.table-success>td,.table-success>th{background-color:#b8ecb8}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#7adc7a}.table-hover .table-success:hover,.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#a4e7a4}.table-info,.table-info>td,.table-info>th{background-color:#c4e2e7}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#91cad2}.table-hover .table-info:hover,.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#b2d9e0}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeb8}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7a}.table-hover .table-warning:hover,.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe89f}.table-danger,.table-danger>td,.table-danger>th{background-color:#fbd1cf}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#f7aaa7}.table-hover .table-danger:hover,.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f9bab7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover,.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#d9d9d9}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#b8b8b8}.table-hover .table-dark:hover,.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#ccc}.table-accent,.table-accent>td,.table-accent>th{background-color:#fbd1cf}.table-accent tbody+tbody,.table-accent td,.table-accent th,.table-accent thead th{border-color:#f7aaa7}.table-hover .table-accent:hover,.table-hover .table-accent:hover>td,.table-hover .table-accent:hover>th{background-color:#f9bab7}.table-warning-dark,.table-warning-dark>td,.table-warning-dark>th{background-color:#fedbbd}.table-warning-dark tbody+tbody,.table-warning-dark td,.table-warning-dark th,.table-warning-dark thead th{border-color:#febc85}.table-hover .table-warning-dark:hover,.table-hover .table-warning-dark:hover>td,.table-hover .table-warning-dark:hover>th{background-color:#fecda4}.table-active,.table-active>td,.table-active>th,.table-hover .table-active:hover,.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:#ffffff0d}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:hsla(0,0%,100%,.075)}@media (max-width: 575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width: 767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width: 991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width: 1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}@media (max-width: 1449.98px){.table-responsive-2xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-2xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.cd-form-control,.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion: reduce){.cd-form-control,.form-control{transition:none}}.cd-form-control::-ms-expand,.form-control::-ms-expand{background-color:initial;border:0}.cd-form-control:focus,.form-control:focus{color:#495057;background-color:#fff;border-color:#76d0dc;box-shadow:0 0 0 .2rem #2b99a840}.cd-form-control::placeholder,.form-control::placeholder{color:#6c757d;opacity:1}.cd-form-control:disabled,.form-control:disabled,.form-control[readonly],[readonly].cd-form-control{background-color:#e9ecef;opacity:1}input[type=date].cd-form-control,input[type=date].form-control,input[type=datetime-local].cd-form-control,input[type=datetime-local].form-control,input[type=month].cd-form-control,input[type=month].form-control,input[type=time].cd-form-control,input[type=time].form-control{appearance:none}select.cd-form-control:-moz-focusring,select.form-control:-moz-focusring{color:#0000;text-shadow:0 0 0 #495057}select.cd-form-control:focus::-ms-value,select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.cd-col-form-label,.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:initial;border:solid #0000;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size],select[multiple].cd-form-control,select[size].cd-form-control,textarea.cd-form-control,textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:100%;color:#0b0}.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:#00bb00e6;border-radius:.25rem}.form-row>.col>.valid-tooltip,.form-row>[class*=col-]>.valid-tooltip{left:5px}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.is-valid.cd-form-control,.was-validated .cd-form-control:valid,.was-validated .form-control:valid{border-color:#0b0;padding-right:calc(1.5em + .75rem)!important;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%230b0' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.is-valid.cd-form-control:focus,.was-validated .cd-form-control:valid:focus,.was-validated .form-control:valid:focus{border-color:#0b0;box-shadow:0 0 0 .2rem #00bb0040}.was-validated select.cd-form-control:valid,.was-validated select.form-control:valid,select.form-control.is-valid,select.is-valid.cd-form-control{padding-right:3rem!important;background-position:right 1.5rem center}.was-validated textarea.cd-form-control:valid,.was-validated textarea.form-control:valid,textarea.form-control.is-valid,textarea.is-valid.cd-form-control{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#0b0;padding-right:calc(.75em + 2.3125rem)!important;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%230b0' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#0b0;box-shadow:0 0 0 .2rem #00bb0040}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#0b0}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#0b0}.custom-control-input.is-valid~.custom-control-label:before,.was-validated .custom-control-input:valid~.custom-control-label:before{border-color:#0b0}.custom-control-input.is-valid:checked~.custom-control-label:before,.was-validated .custom-control-input:valid:checked~.custom-control-label:before{border-color:#0e0;background-color:#0e0}.custom-control-input.is-valid:focus~.custom-control-label:before,.was-validated .custom-control-input:valid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem #00bb0040}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label:before,.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label:before,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#0b0}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#0b0;box-shadow:0 0 0 .2rem #00bb0040}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:100%;color:#ef5c55}.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:#ef5c55e6;border-radius:.25rem}.form-row>.col>.invalid-tooltip,.form-row>[class*=col-]>.invalid-tooltip{left:5px}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.is-invalid.cd-form-control,.was-validated .cd-form-control:invalid,.was-validated .form-control:invalid{border-color:#ef5c55;padding-right:calc(1.5em + .75rem)!important;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23ef5c55' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ef5c55' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.is-invalid.cd-form-control:focus,.was-validated .cd-form-control:invalid:focus,.was-validated .form-control:invalid:focus{border-color:#ef5c55;box-shadow:0 0 0 .2rem #ef5c5540}.was-validated select.cd-form-control:invalid,.was-validated select.form-control:invalid,select.form-control.is-invalid,select.is-invalid.cd-form-control{padding-right:3rem!important;background-position:right 1.5rem center}.was-validated textarea.cd-form-control:invalid,.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid,textarea.is-invalid.cd-form-control{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#ef5c55;padding-right:calc(.75em + 2.3125rem)!important;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23ef5c55' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ef5c55' stroke='none'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#ef5c55;box-shadow:0 0 0 .2rem #ef5c5540}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#ef5c55}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#ef5c55}.custom-control-input.is-invalid~.custom-control-label:before,.was-validated .custom-control-input:invalid~.custom-control-label:before{border-color:#ef5c55}.custom-control-input.is-invalid:checked~.custom-control-label:before,.was-validated .custom-control-input:invalid:checked~.custom-control-label:before{border-color:#f38984;background-color:#f38984}.custom-control-input.is-invalid:focus~.custom-control-label:before,.was-validated .custom-control-input:invalid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem #ef5c5540}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label:before,.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label:before,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#ef5c55}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#ef5c55;box-shadow:0 0 0 .2rem #ef5c5540}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width: 576px){.form-inline label{justify-content:center}.form-inline .form-group,.form-inline label{display:flex;align-items:center;margin-bottom:0}.form-inline .form-group{flex:0 0 auto;flex-flow:row wrap}.form-inline .cd-form-control,.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;user-select:none;background-color:initial;border:1px solid #0000;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem #2b99a840}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#2b99a8;border-color:#2b99a8}.btn-primary.focus,.btn-primary:focus,.btn-primary:hover{color:#fff;background-color:#237d8a;border-color:#21747f}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem #4ba8b580}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#2b99a8;border-color:#2b99a8}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#21747f;border-color:#1e6b75}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #4ba8b580}.btn-secondary{color:#fff;background-color:#374249;border-color:#374249}.btn-secondary.focus,.btn-secondary:focus,.btn-secondary:hover{color:#fff;background-color:#272e33;border-color:#21282c}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem #555e6480}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#374249;border-color:#374249}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#21282c;border-color:#1c2125}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #555e6480}.btn-success{color:#fff;background-color:#0b0;border-color:#0b0}.btn-success.focus,.btn-success:focus,.btn-success:hover{color:#fff;background-color:#009500;border-color:#080}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem #26c52680}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#0b0;border-color:#0b0}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#080;border-color:#007b00}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #26c52680}.btn-info{color:#fff;background-color:#2b99a8;border-color:#2b99a8}.btn-info.focus,.btn-info:focus,.btn-info:hover{color:#fff;background-color:#237d8a;border-color:#21747f}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem #4ba8b580}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#2b99a8;border-color:#2b99a8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#21747f;border-color:#1e6b75}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #4ba8b580}.btn-warning{color:#212529;background-color:#ffc200;border-color:#ffc200}.btn-warning.focus,.btn-warning:focus,.btn-warning:hover{color:#212529;background-color:#d9a500;border-color:#cc9b00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem #deaa0680}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc200;border-color:#ffc200}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#cc9b00;border-color:#bf9200}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #deaa0680}.btn-danger{color:#fff;background-color:#ef5c55;border-color:#ef5c55}.btn-danger.focus,.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#ec3a32;border-color:#eb2f26}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem #f1746f80}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#ef5c55;border-color:#ef5c55}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#eb2f26;border-color:#ea241b}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #f1746f80}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light.focus,.btn-light:focus,.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem #d8d9db80}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #d8d9db80}.btn-dark{color:#fff;background-color:#777;border-color:#777}.btn-dark.focus,.btn-dark:focus,.btn-dark:hover{color:#fff;background-color:#646464;border-color:#5e5e5e}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem #8b8b8b80}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#777;border-color:#777}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#5e5e5e;border-color:#575757}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #8b8b8b80}.btn-accent{color:#fff;background-color:#ef5c55;border-color:#ef5c55}.btn-accent.focus,.btn-accent:focus,.btn-accent:hover{color:#fff;background-color:#ec3a32;border-color:#eb2f26}.btn-accent.focus,.btn-accent:focus{box-shadow:0 0 0 .2rem #f1746f80}.btn-accent.disabled,.btn-accent:disabled{color:#fff;background-color:#ef5c55;border-color:#ef5c55}.btn-accent:not(:disabled):not(.disabled).active,.btn-accent:not(:disabled):not(.disabled):active,.show>.btn-accent.dropdown-toggle{color:#fff;background-color:#eb2f26;border-color:#ea241b}.btn-accent:not(:disabled):not(.disabled).active:focus,.btn-accent:not(:disabled):not(.disabled):active:focus,.show>.btn-accent.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #f1746f80}.btn-warning-dark{color:#212529;background-color:#fd7e14;border-color:#fd7e14}.btn-warning-dark.focus,.btn-warning-dark:focus,.btn-warning-dark:hover{color:#fff;background-color:#e96b02;border-color:#dc6502}.btn-warning-dark.focus,.btn-warning-dark:focus{box-shadow:0 0 0 .2rem #dc711780}.btn-warning-dark.disabled,.btn-warning-dark:disabled{color:#212529;background-color:#fd7e14;border-color:#fd7e14}.btn-warning-dark:not(:disabled):not(.disabled).active,.btn-warning-dark:not(:disabled):not(.disabled):active,.show>.btn-warning-dark.dropdown-toggle{color:#fff;background-color:#dc6502;border-color:#cf5f02}.btn-warning-dark:not(:disabled):not(.disabled).active:focus,.btn-warning-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-warning-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #dc711780}.btn-outline-primary{color:#2b99a8;border-color:#2b99a8}.btn-outline-primary:hover{color:#fff;background-color:#2b99a8;border-color:#2b99a8}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem #2b99a880}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#2b99a8;background-color:initial}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#2b99a8;border-color:#2b99a8}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #2b99a880}.btn-outline-secondary{color:#374249;border-color:#374249}.btn-outline-secondary:hover{color:#fff;background-color:#374249;border-color:#374249}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem #37424980}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#374249;background-color:initial}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#374249;border-color:#374249}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #37424980}.btn-outline-success{color:#0b0;border-color:#0b0}.btn-outline-success:hover{color:#fff;background-color:#0b0;border-color:#0b0}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem #00bb0080}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#0b0;background-color:initial}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#0b0;border-color:#0b0}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #00bb0080}.btn-outline-info{color:#2b99a8;border-color:#2b99a8}.btn-outline-info:hover{color:#fff;background-color:#2b99a8;border-color:#2b99a8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem #2b99a880}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#2b99a8;background-color:initial}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#2b99a8;border-color:#2b99a8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #2b99a880}.btn-outline-warning{color:#ffc200;border-color:#ffc200}.btn-outline-warning:hover{color:#212529;background-color:#ffc200;border-color:#ffc200}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem #ffc20080}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc200;background-color:initial}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc200;border-color:#ffc200}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #ffc20080}.btn-outline-danger{color:#ef5c55;border-color:#ef5c55}.btn-outline-danger:hover{color:#fff;background-color:#ef5c55;border-color:#ef5c55}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem #ef5c5580}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#ef5c55;background-color:initial}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#ef5c55;border-color:#ef5c55}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #ef5c5580}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem #f8f9fa80}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:initial}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #f8f9fa80}.btn-outline-dark{color:#777;border-color:#777}.btn-outline-dark:hover{color:#fff;background-color:#777;border-color:#777}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem #77777780}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#777;background-color:initial}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#777;border-color:#777}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #77777780}.btn-outline-accent{color:#ef5c55;border-color:#ef5c55}.btn-outline-accent:hover{color:#fff;background-color:#ef5c55;border-color:#ef5c55}.btn-outline-accent.focus,.btn-outline-accent:focus{box-shadow:0 0 0 .2rem #ef5c5580}.btn-outline-accent.disabled,.btn-outline-accent:disabled{color:#ef5c55;background-color:initial}.btn-outline-accent:not(:disabled):not(.disabled).active,.btn-outline-accent:not(:disabled):not(.disabled):active,.show>.btn-outline-accent.dropdown-toggle{color:#fff;background-color:#ef5c55;border-color:#ef5c55}.btn-outline-accent:not(:disabled):not(.disabled).active:focus,.btn-outline-accent:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-accent.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #ef5c5580}.btn-outline-warning-dark{color:#fd7e14;border-color:#fd7e14}.btn-outline-warning-dark:hover{color:#212529;background-color:#fd7e14;border-color:#fd7e14}.btn-outline-warning-dark.focus,.btn-outline-warning-dark:focus{box-shadow:0 0 0 .2rem #fd7e1480}.btn-outline-warning-dark.disabled,.btn-outline-warning-dark:disabled{color:#fd7e14;background-color:initial}.btn-outline-warning-dark:not(:disabled):not(.disabled).active,.btn-outline-warning-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-warning-dark.dropdown-toggle{color:#212529;background-color:#fd7e14;border-color:#fd7e14}.btn-outline-warning-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-warning-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #fd7e1480}.btn-link{font-weight:400;color:#2b99a8;text-decoration:none}.btn-link:hover{color:#1b626b}.btn-link.focus,.btn-link:focus,.btn-link:hover{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion: reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid #0000;border-bottom:0;border-left:.3em solid #0000}.dropdown-toggle:empty:after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid #00000026;border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width: 576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width: 768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width: 992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width: 1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}@media (min-width: 1450px){.dropdown-menu-2xl-left{right:auto;left:0}.dropdown-menu-2xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid #0000;border-bottom:.3em solid;border-left:.3em solid #0000}.dropup .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid #0000;border-right:0;border-bottom:.3em solid #0000;border-left:.3em solid}.dropright .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-toggle:after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";display:none}.dropleft .dropdown-toggle:before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid #0000;border-right:.3em solid;border-bottom:.3em solid #0000}.dropleft .dropdown-toggle:empty:after{margin-left:0}.dropleft .dropdown-toggle:before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:initial;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#e9ecef}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#2b99a8}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:initial}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split:after,.dropright .dropdown-toggle-split:after,.dropup .dropdown-toggle-split:after{margin-left:0}.dropleft .dropdown-toggle-split:before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.cd-form-control,.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.cd-form-control+.cd-form-control,.input-group>.cd-form-control+.custom-file,.input-group>.cd-form-control+.custom-select,.input-group>.cd-form-control+.form-control,.input-group>.custom-file+.cd-form-control,.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.cd-form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.cd-form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.cd-form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.cd-form-control:focus,.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.cd-form-control:not(:first-child),.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:flex;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label:after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group.has-validation>.cd-form-control:nth-last-child(n+3),.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label,.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label:after,.input-group.has-validation>.custom-select:nth-last-child(n+3),.input-group.has-validation>.form-control:nth-last-child(n+3),.input-group:not(.has-validation)>.cd-form-control:not(:last-child),.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label,.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label:after,.input-group:not(.has-validation)>.custom-select:not(:last-child),.input-group:not(.has-validation)>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-append,.input-group-prepend{display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.cd-form-control:not(textarea),.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.cd-form-control,.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.cd-form-control:not(textarea),.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.cd-form-control,.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem;-webkit-print-color-adjust:exact;color-adjust:exact}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label:before{color:#fff;border-color:#2b99a8;background-color:#2b99a8}.custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem #2b99a840}.custom-control-input:focus:not(:checked)~.custom-control-label:before{border-color:#76d0dc}.custom-control-input:not(:disabled):active~.custom-control-label:before{color:#fff;background-color:#9fdee6;border-color:#9fdee6}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label:before,.custom-control-input[disabled]~.custom-control-label:before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label:before{pointer-events:none;background-color:#fff;border:1px solid #adb5bd}.custom-control-label:after,.custom-control-label:before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:""}.custom-control-label:after{background:50%/50% 50% no-repeat}.custom-checkbox .custom-control-label:before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label:before{border-color:#2b99a8;background-color:#2b99a8}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label:after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label:before,.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label:before{background-color:#2b99a880}.custom-radio .custom-control-label:before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label:before{background-color:#2b99a880}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label:before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label:after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion: reduce){.custom-switch .custom-control-label:after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label:after{background-color:#fff;transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label:before{background-color:#2b99a880}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat;border:1px solid #ced4da;border-radius:.25rem;appearance:none}.custom-select:focus{border-color:#76d0dc;outline:0;box-shadow:0 0 0 .2rem #2b99a840}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:#0000;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{display:inline-block;margin-bottom:0}.custom-file,.custom-file-input{position:relative;width:100%;height:calc(1.5em + .75rem + 2px)}.custom-file-input{z-index:2;margin:0;overflow:hidden;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#76d0dc;box-shadow:0 0 0 .2rem #2b99a840}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label:after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]:after{content:attr(data-browse)}.custom-file-label{left:0;z-index:1;height:calc(1.5em + .75rem + 2px);overflow:hidden;font-weight:400;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label,.custom-file-label:after{position:absolute;top:0;right:0;padding:.375rem .75rem;line-height:1.5;color:#495057}.custom-file-label:after{bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:initial;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem #2b99a840}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem #2b99a840}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem #2b99a840}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#2b99a8;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#9fdee6}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:#0000;cursor:pointer;background-color:#dee2e6;border-color:#0000;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#2b99a8;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#9fdee6}.custom-range::-moz-range-track{width:100%;height:.5rem;color:#0000;cursor:pointer;background-color:#dee2e6;border-color:#0000;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#2b99a8;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#9fdee6}.custom-range::-ms-track{width:100%;height:.5rem;color:#0000;cursor:pointer;background-color:initial;border-color:#0000;border-width:.5rem}.custom-range::-ms-fill-lower,.custom-range::-ms-fill-upper{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label:before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion: reduce){.custom-control-label:before,.custom-file-label,.custom-select{transition:none}}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;border:1px solid #0000;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:initial;border-color:#0000}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#2b99a8}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;padding:.5rem 1rem}.navbar,.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:initial;border:1px solid #0000;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:50%/100% 100% no-repeat}.navbar-nav-scroll{max-height:75vh;overflow-y:auto}@media (max-width: 575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width: 576px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{flex-wrap:nowrap}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width: 767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width: 768px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{flex-wrap:nowrap}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width: 991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width: 992px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{flex-wrap:nowrap}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width: 1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width: 1200px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{flex-wrap:nowrap}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}@media (max-width: 1449.98px){.navbar-expand-2xl>.container,.navbar-expand-2xl>.container-fluid,.navbar-expand-2xl>.container-lg,.navbar-expand-2xl>.container-md,.navbar-expand-2xl>.container-sm,.navbar-expand-2xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width: 1450px){.navbar-expand-2xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-2xl .navbar-nav{flex-direction:row}.navbar-expand-2xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-2xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-2xl>.container,.navbar-expand-2xl>.container-fluid,.navbar-expand-2xl>.container-lg,.navbar-expand-2xl>.container-md,.navbar-expand-2xl>.container-sm,.navbar-expand-2xl>.container-xl{flex-wrap:nowrap}.navbar-expand-2xl .navbar-nav-scroll{overflow:visible}.navbar-expand-2xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-2xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{flex-wrap:nowrap}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand,.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:#000000e6}.navbar-light .navbar-nav .nav-link{color:#00000080}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:#000000b3}.navbar-light .navbar-nav .nav-link.disabled{color:#0000004d}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:#000000e6}.navbar-light .navbar-toggler{color:#00000080;border-color:#0000001a}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:#00000080}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:#000000e6}.navbar-dark .navbar-brand,.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:#ffffff80}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:#ffffffbf}.navbar-dark .navbar-nav .nav-link.disabled{color:#ffffff40}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:#ffffff80;border-color:#ffffff1a}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:#ffffff80}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card,pre:not(cd-api-docs *){position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:initial;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr,pre:not(cd-api-docs *)>hr{margin-right:0;margin-left:0}.card>.list-group,pre:not(cd-api-docs *)>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child,pre:not(cd-api-docs *)>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child,pre:not(cd-api-docs *)>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer,pre:not(cd-api-docs *)>.card-header+.list-group,pre:not(cd-api-docs *)>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem}.card-subtitle,.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:#f8f9fa;border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.75rem 1.25rem;background-color:#f8f9fa;border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-bottom:-.75rem;border-bottom:0}.card-header-pills,.card-header-tabs{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card,.card-deck pre:not(cd-api-docs *){margin-bottom:15px}@media (min-width: 576px){.card-deck{display:flex;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card,.card-deck pre:not(cd-api-docs *){flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card,.card-group>pre:not(cd-api-docs *){margin-bottom:15px}@media (min-width: 576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card,.card-group>pre:not(cd-api-docs *){flex:1 0 0%;margin-bottom:0}.card-group>.card+.card,.card-group>.card+pre:not(cd-api-docs *),.card-group>pre:not(cd-api-docs *)+.card,.card-group>pre:not(cd-api-docs *)+pre:not(cd-api-docs *){margin-left:0;border-left:0}.card-group>.card:not(:last-child),.card-group>pre:not(:last-child):not(cd-api-docs *){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top,.card-group>pre:not(:last-child):not(cd-api-docs *) .card-header,.card-group>pre:not(:last-child):not(cd-api-docs *) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom,.card-group>pre:not(:last-child):not(cd-api-docs *) .card-footer,.card-group>pre:not(:last-child):not(cd-api-docs *) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child),.card-group>pre:not(:first-child):not(cd-api-docs *){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top,.card-group>pre:not(:first-child):not(cd-api-docs *) .card-header,.card-group>pre:not(:first-child):not(cd-api-docs *) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom,.card-group>pre:not(:first-child):not(cd-api-docs *) .card-footer,.card-group>pre:not(:first-child):not(cd-api-docs *) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card,.card-columns pre:not(cd-api-docs *){margin-bottom:.75rem}@media (min-width: 576px){.card-columns{column-count:3;grid-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card,.card-columns pre:not(cd-api-docs *){display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card,.accordion>pre:not(cd-api-docs *){overflow:hidden}.accordion>.card:not(:last-of-type),.accordion>pre:not(:last-of-type):not(cd-api-docs *){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type),.accordion>pre:not(:first-of-type):not(cd-api-docs *){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header,.accordion>pre:not(cd-api-docs *)>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:flex;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item:before{float:left;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover:before{text-decoration:underline;text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination,cd-table .cd-datatable .datatable-footer .datatable-pager ul{display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link,cd-table .cd-datatable .datatable-footer .datatable-pager ul li a{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#2b99a8;background-color:#fff;border:1px solid #dee2e6}.page-link:hover,cd-table .cd-datatable .datatable-footer .datatable-pager ul li a:hover{z-index:2;color:#1b626b;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus,cd-table .cd-datatable .datatable-footer .datatable-pager ul li a:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem #2b99a840}.page-item:first-child .page-link,.page-item:first-child cd-table .cd-datatable .datatable-footer .datatable-pager ul li a,cd-table .cd-datatable .datatable-footer .datatable-pager ul li .page-item:first-child a,cd-table .cd-datatable .datatable-footer .datatable-pager ul li:first-child .page-link,cd-table .cd-datatable .datatable-footer .datatable-pager ul li:first-child a{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link,.page-item:last-child cd-table .cd-datatable .datatable-footer .datatable-pager ul li a,cd-table .cd-datatable .datatable-footer .datatable-pager ul li .page-item:last-child a,cd-table .cd-datatable .datatable-footer .datatable-pager ul li:last-child .page-link,cd-table .cd-datatable .datatable-footer .datatable-pager ul li:last-child a{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link,.page-item.active cd-table .cd-datatable .datatable-footer .datatable-pager ul li a,cd-table .cd-datatable .datatable-footer .datatable-pager ul li .page-item.active a,cd-table .cd-datatable .datatable-footer .datatable-pager ul li.active .page-link,cd-table .cd-datatable .datatable-footer .datatable-pager ul li.active a{z-index:3;color:#fff;background-color:#2b99a8;border-color:#2b99a8}.page-item.disabled .page-link,.page-item.disabled cd-table .cd-datatable .datatable-footer .datatable-pager ul li a,cd-table .cd-datatable .datatable-footer .datatable-pager ul li .page-item.disabled a,cd-table .cd-datatable .datatable-footer .datatable-pager ul li.disabled .page-link,cd-table .cd-datatable .datatable-footer .datatable-pager ul li.disabled a{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link,.pagination-lg cd-table .cd-datatable .datatable-footer .datatable-pager ul li a,cd-table .cd-datatable .datatable-footer .datatable-pager ul li .pagination-lg a{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link,.pagination-lg .page-item:first-child cd-table .cd-datatable .datatable-footer .datatable-pager ul li a,.pagination-lg cd-table .cd-datatable .datatable-footer .datatable-pager ul li:first-child .page-link,.pagination-lg cd-table .cd-datatable .datatable-footer .datatable-pager ul li:first-child a,cd-table .cd-datatable .datatable-footer .datatable-pager ul .pagination-lg li:first-child .page-link,cd-table .cd-datatable .datatable-footer .datatable-pager ul .pagination-lg li:first-child a,cd-table .cd-datatable .datatable-footer .datatable-pager ul li .pagination-lg .page-item:first-child a{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link,.pagination-lg .page-item:last-child cd-table .cd-datatable .datatable-footer .datatable-pager ul li a,.pagination-lg cd-table .cd-datatable .datatable-footer .datatable-pager ul li:last-child .page-link,.pagination-lg cd-table .cd-datatable .datatable-footer .datatable-pager ul li:last-child a,cd-table .cd-datatable .datatable-footer .datatable-pager ul .pagination-lg li:last-child .page-link,cd-table .cd-datatable .datatable-footer .datatable-pager ul .pagination-lg li:last-child a,cd-table .cd-datatable .datatable-footer .datatable-pager ul li .pagination-lg .page-item:last-child a{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link,.pagination-sm cd-table .cd-datatable .datatable-footer .datatable-pager ul li a,cd-table .cd-datatable .datatable-footer .datatable-pager ul li .pagination-sm a{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link,.pagination-sm .page-item:first-child cd-table .cd-datatable .datatable-footer .datatable-pager ul li a,.pagination-sm cd-table .cd-datatable .datatable-footer .datatable-pager ul li:first-child .page-link,.pagination-sm cd-table .cd-datatable .datatable-footer .datatable-pager ul li:first-child a,cd-table .cd-datatable .datatable-footer .datatable-pager ul .pagination-sm li:first-child .page-link,cd-table .cd-datatable .datatable-footer .datatable-pager ul .pagination-sm li:first-child a,cd-table .cd-datatable .datatable-footer .datatable-pager ul li .pagination-sm .page-item:first-child a{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link,.pagination-sm .page-item:last-child cd-table .cd-datatable .datatable-footer .datatable-pager ul li a,.pagination-sm cd-table .cd-datatable .datatable-footer .datatable-pager ul li:last-child .page-link,.pagination-sm cd-table .cd-datatable .datatable-footer .datatable-pager ul li:last-child a,cd-table .cd-datatable .datatable-footer .datatable-pager ul .pagination-sm li:last-child .page-link,cd-table .cd-datatable .datatable-footer .datatable-pager ul .pagination-sm li:last-child a,cd-table .cd-datatable .datatable-footer .datatable-pager ul li .pagination-sm .page-item:last-child a{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:1rem;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:initial;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion: reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#2b99a8}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#21747f}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem #2b99a880}.badge-secondary{color:#fff;background-color:#374249}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#21282c}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem #37424980}.badge-success{color:#fff;background-color:#0b0}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#080}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem #00bb0080}.badge-info{color:#fff;background-color:#2b99a8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#21747f}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem #2b99a880}.badge-warning{color:#212529;background-color:#ffc200}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#cc9b00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem #ffc20080}.badge-danger{color:#fff;background-color:#ef5c55}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#eb2f26}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem #ef5c5580}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem #f8f9fa80}.badge-dark{color:#fff;background-color:#777}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#5e5e5e}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem #77777780}.badge-accent{color:#fff;background-color:#ef5c55}a.badge-accent:focus,a.badge-accent:hover{color:#fff;background-color:#eb2f26}a.badge-accent.focus,a.badge-accent:focus{outline:0;box-shadow:0 0 0 .2rem #ef5c5580}.badge-warning-dark{color:#212529;background-color:#fd7e14}a.badge-warning-dark:focus,a.badge-warning-dark:hover{color:#212529;background-color:#dc6502}a.badge-warning-dark.focus,a.badge-warning-dark:focus{outline:0;box-shadow:0 0 0 .2rem #fd7e1480}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width: 576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid #0000;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#165057;background-color:#d5ebee;border-color:#c4e2e7}.alert-primary hr{border-top-color:#b2d9e0}.alert-primary .alert-link{color:#0c2b2e}.alert-secondary{color:#1d2226;background-color:#d7d9db;border-color:#c7cacc}.alert-secondary hr{border-top-color:#babdc0}.alert-secondary .alert-link{color:#070809}.alert-success{color:#006100;background-color:#ccf1cc;border-color:#b8ecb8}.alert-success hr{border-top-color:#a4e7a4}.alert-success .alert-link{color:#002e00}.alert-info{color:#165057;background-color:#d5ebee;border-color:#c4e2e7}.alert-info hr{border-top-color:#b2d9e0}.alert-info .alert-link{color:#0c2b2e}.alert-warning{color:#856500;background-color:#fff3cc;border-color:#ffeeb8}.alert-warning hr{border-top-color:#ffe89f}.alert-warning .alert-link{color:#523e00}.alert-danger{color:#7c302c;background-color:#fcdedd;border-color:#fbd1cf}.alert-danger hr{border-top-color:#f9bab7}.alert-danger .alert-link{color:#56211f}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#3e3e3e;background-color:#e4e4e4;border-color:#d9d9d9}.alert-dark hr{border-top-color:#ccc}.alert-dark .alert-link{color:#252525}.alert-accent{color:#7c302c;background-color:#fcdedd;border-color:#fbd1cf}.alert-accent hr{border-top-color:#f9bab7}.alert-accent .alert-link{color:#56211f}.alert-warning-dark{color:#84420a;background-color:#ffe5d0;border-color:#fedbbd}.alert-warning-dark hr{border-top-color:#fecda4}.alert-warning-dark .alert-link{color:#552a06}@keyframes progress-bar-stripes{0%{background-position:1rem 0}to{background-position:0 0}}.progress{height:1rem;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress,.progress-bar{display:flex;overflow:hidden}.progress-bar{flex-direction:column;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#2b99a8;transition:width .6s ease}@media (prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000);background-size:1rem 1rem}.progress-bar-animated{animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.media{display:flex;align-items:flex-start}.media-body{flex:1}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#2b99a8;border-color:#2b99a8}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width: 576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1450px){.list-group-horizontal-2xl{flex-direction:row}.list-group-horizontal-2xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-2xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-2xl>.list-group-item.active{margin-top:0}.list-group-horizontal-2xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-2xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#165057;background-color:#c4e2e7}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#165057;background-color:#b2d9e0}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#165057;border-color:#165057}.list-group-item-secondary{color:#1d2226;background-color:#c7cacc}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#1d2226;background-color:#babdc0}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#1d2226;border-color:#1d2226}.list-group-item-success{color:#006100;background-color:#b8ecb8}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#006100;background-color:#a4e7a4}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#006100;border-color:#006100}.list-group-item-info{color:#165057;background-color:#c4e2e7}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#165057;background-color:#b2d9e0}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#165057;border-color:#165057}.list-group-item-warning{color:#856500;background-color:#ffeeb8}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856500;background-color:#ffe89f}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856500;border-color:#856500}.list-group-item-danger{color:#7c302c;background-color:#fbd1cf}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#7c302c;background-color:#f9bab7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#7c302c;border-color:#7c302c}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#3e3e3e;background-color:#d9d9d9}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#3e3e3e;background-color:#ccc}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#3e3e3e;border-color:#3e3e3e}.list-group-item-accent{color:#7c302c;background-color:#fbd1cf}.list-group-item-accent.list-group-item-action:focus,.list-group-item-accent.list-group-item-action:hover{color:#7c302c;background-color:#f9bab7}.list-group-item-accent.list-group-item-action.active{color:#fff;background-color:#7c302c;border-color:#7c302c}.list-group-item-warning-dark{color:#84420a;background-color:#fedbbd}.list-group-item-warning-dark.list-group-item-action:focus,.list-group-item-warning-dark.list-group-item-action:hover{color:#84420a;background-color:#fecda4}.list-group-item-warning-dark.list-group-item-action.active{color:#fff;background-color:#84420a;border-color:#84420a}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:initial;border:0}a.close.disabled{pointer-events:none}.toast{flex-basis:350px;max-width:350px;font-size:.875rem;background-color:#ffffffd9;background-clip:padding-box;border:1px solid #0000001a;box-shadow:0 .25rem .75rem #0000001a;opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:flex;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:#ffffffd9;background-clip:padding-box;border-bottom:1px solid #0000000d;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translateY(-50px)}@media (prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered:before{display:block;height:calc(100vh - 1rem);height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable:before{content:none}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid #0003;border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered:before{height:calc(100vh - 3.5rem);height:min-content}.modal-sm{max-width:300px}}@media (min-width: 992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width: 1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:Helvetica Neue,Helvetica,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow:before{position:absolute;content:"";border-color:#0000;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow:before,.bs-tooltip-top .arrow:before{top:0;border-width:.4rem .4rem 0;border-top-color:#212529}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow:before,.bs-tooltip-right .arrow:before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#212529}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow:before,.bs-tooltip-bottom .arrow:before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#212529}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow:before,.bs-tooltip-left .arrow:before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#212529}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#212529;border-radius:.25rem}.popover{top:0;left:0;z-index:1060;max-width:350px;font-family:Helvetica Neue,Helvetica,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:1rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid #0003;border-radius:.3rem}.popover,.popover .arrow{position:absolute;display:block}.popover .arrow{width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow:after,.popover .arrow:before{position:absolute;display:block;content:"";border-color:#0000;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow:before,.bs-popover-top>.arrow:before{bottom:0;border-width:.5rem .5rem 0;border-top-color:#00000040}.bs-popover-auto[x-placement^=top]>.arrow:after,.bs-popover-top>.arrow:after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow:before,.bs-popover-right>.arrow:before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:#00000040}.bs-popover-auto[x-placement^=right]>.arrow:after,.bs-popover-right>.arrow:after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow:before,.bs-popover-bottom>.arrow:before{top:0;border-width:0 .5rem .5rem;border-bottom-color:#00000040}.bs-popover-auto[x-placement^=bottom]>.arrow:after,.bs-popover-bottom>.arrow:after{top:1px;border-width:0 .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header:before,.bs-popover-bottom .popover-header:before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow:before,.bs-popover-left>.arrow:before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:#00000040}.bs-popover-auto[x-placement^=left]>.arrow:after,.bs-popover-left>.arrow:after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner:after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion: reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion: reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:none;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion: reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:50%/100% 100% no-repeat}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:flex;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:initial;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid #0000;border-bottom:10px solid #0000;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion: reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@keyframes spinner-border{to{transform:rotate(1turn)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid;border-right:.25em solid #0000;border-radius:50%;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentColor;border-radius:50%;opacity:0;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{animation-duration:1.5s}}.align-baseline{vertical-align:initial!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#2b99a8!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#21747f!important}.bg-secondary{background-color:#374249!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#21282c!important}.bg-success{background-color:#0b0!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#080!important}.bg-info{background-color:#2b99a8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#21747f!important}.bg-warning{background-color:#ffc200!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#cc9b00!important}.bg-danger{background-color:#ef5c55!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#eb2f26!important}.bg-light,pre:not(cd-api-docs *){background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#777!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#5e5e5e!important}.bg-accent{background-color:#ef5c55!important}a.bg-accent:focus,a.bg-accent:hover,button.bg-accent:focus,button.bg-accent:hover{background-color:#eb2f26!important}.bg-warning-dark{background-color:#fd7e14!important}a.bg-warning-dark:focus,a.bg-warning-dark:hover,button.bg-warning-dark:focus,button.bg-warning-dark:hover{background-color:#dc6502!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:initial!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom,.cd-header,legend{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#2b99a8!important}.border-secondary{border-color:#374249!important}.border-success{border-color:#0b0!important}.border-info{border-color:#2b99a8!important}.border-warning{border-color:#ffc200!important}.border-danger{border-color:#ef5c55!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#777!important}.border-accent{border-color:#ef5c55!important}.border-warning-dark{border-color:#fd7e14!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important}.rounded-right,.rounded-top{border-top-right-radius:.25rem!important}.rounded-bottom,.rounded-right{border-bottom-right-radius:.25rem!important}.rounded-bottom,.rounded-left{border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix:after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex,cd-health cd-info-card{display:flex!important}.d-inline-flex{display:inline-flex!important}@media (min-width: 576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}}@media (min-width: 768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}}@media (min-width: 992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}}@media (min-width: 1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}}@media (min-width: 1450px){.d-2xl-none{display:none!important}.d-2xl-inline{display:inline!important}.d-2xl-inline-block{display:inline-block!important}.d-2xl-block{display:block!important}.d-2xl-table{display:table!important}.d-2xl-table-row{display:table-row!important}.d-2xl-table-cell{display:table-cell!important}.d-2xl-flex{display:flex!important}.d-2xl-inline-flex{display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive:before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9:before{padding-top:42.85714286%}.embed-responsive-16by9:before{padding-top:56.25%}.embed-responsive-4by3:before{padding-top:75%}.embed-responsive-1by1:before{padding-top:100%}.flex-row{flex-direction:row!important}.flex-column,cd-health cd-info-card{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex:1 1 auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}@media (min-width: 576px){.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}}@media (min-width: 768px){.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}}@media (min-width: 992px){.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}}@media (min-width: 1200px){.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}}@media (min-width: 1450px){.flex-2xl-row{flex-direction:row!important}.flex-2xl-column{flex-direction:column!important}.flex-2xl-row-reverse{flex-direction:row-reverse!important}.flex-2xl-column-reverse{flex-direction:column-reverse!important}.flex-2xl-wrap{flex-wrap:wrap!important}.flex-2xl-nowrap{flex-wrap:nowrap!important}.flex-2xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-2xl-fill{flex:1 1 auto!important}.flex-2xl-grow-0{flex-grow:0!important}.flex-2xl-grow-1{flex-grow:1!important}.flex-2xl-shrink-0{flex-shrink:0!important}.flex-2xl-shrink-1{flex-shrink:1!important}.justify-content-2xl-start{justify-content:flex-start!important}.justify-content-2xl-end{justify-content:flex-end!important}.justify-content-2xl-center{justify-content:center!important}.justify-content-2xl-between{justify-content:space-between!important}.justify-content-2xl-around{justify-content:space-around!important}.align-items-2xl-start{align-items:flex-start!important}.align-items-2xl-end{align-items:flex-end!important}.align-items-2xl-center{align-items:center!important}.align-items-2xl-baseline{align-items:baseline!important}.align-items-2xl-stretch{align-items:stretch!important}.align-content-2xl-start{align-content:flex-start!important}.align-content-2xl-end{align-content:flex-end!important}.align-content-2xl-center{align-content:center!important}.align-content-2xl-between{align-content:space-between!important}.align-content-2xl-around{align-content:space-around!important}.align-content-2xl-stretch{align-content:stretch!important}.align-self-2xl-auto{align-self:auto!important}.align-self-2xl-start{align-self:flex-start!important}.align-self-2xl-end{align-self:flex-end!important}.align-self-2xl-center{align-self:center!important}.align-self-2xl-baseline{align-self:baseline!important}.align-self-2xl-stretch{align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width: 576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width: 768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width: 992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width: 1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}@media (min-width: 1450px){.float-2xl-left{float:left!important}.float-2xl-right{float:right!important}.float-2xl-none{float:none!important}}.user-select-all{user-select:all!important}.user-select-auto{user-select:auto!important}.user-select-none{user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:sticky!important}.fixed-top{top:0}.fixed-bottom,.fixed-top{position:fixed;right:0;left:0;z-index:1030}.fixed-bottom{bottom:0}@supports (position: sticky){.sticky-top{position:sticky;top:0;z-index:1020}}.sr-only{white-space:nowrap}.sr-only-focusable:active,.sr-only-focusable:focus{white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem #00000026!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.btn-toolbar cd-table-actions.btn-group,.mr-2,.mx-2,cd-logs label{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3,cd-logs .form-inline>.form-group{margin-right:1rem!important}.mb-3,.my-3,cd-logs .form-inline>.form-group{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.cd-header,.mt-4,.my-4,legend{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.cd-header,.mb-4,.my-4,cd-health cd-info-card,legend{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.cd-header,.pb-1,.py-1,legend{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2,cd-table .cd-datatable .datatable-footer,pre:not(cd-api-docs *){padding:.5rem!important}.pt-2,.py-2,cd-info-card .card .card-body .card-text,cd-info-card pre:not(cd-api-docs *) .card-body .card-text{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2,cd-info-card .card,cd-info-card pre:not(cd-api-docs *){padding-bottom:.5rem!important}.pl-2,.px-2,cd-info-card .card .card-body .card-title,cd-info-card pre:not(cd-api-docs *) .card-body .card-title{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width: 576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width: 768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width: 992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width: 1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}@media (min-width: 1450px){.m-2xl-0{margin:0!important}.mt-2xl-0,.my-2xl-0{margin-top:0!important}.mr-2xl-0,.mx-2xl-0{margin-right:0!important}.mb-2xl-0,.my-2xl-0{margin-bottom:0!important}.ml-2xl-0,.mx-2xl-0{margin-left:0!important}.m-2xl-1{margin:.25rem!important}.mt-2xl-1,.my-2xl-1{margin-top:.25rem!important}.mr-2xl-1,.mx-2xl-1{margin-right:.25rem!important}.mb-2xl-1,.my-2xl-1{margin-bottom:.25rem!important}.ml-2xl-1,.mx-2xl-1{margin-left:.25rem!important}.m-2xl-2{margin:.5rem!important}.mt-2xl-2,.my-2xl-2{margin-top:.5rem!important}.mr-2xl-2,.mx-2xl-2{margin-right:.5rem!important}.mb-2xl-2,.my-2xl-2{margin-bottom:.5rem!important}.ml-2xl-2,.mx-2xl-2{margin-left:.5rem!important}.m-2xl-3{margin:1rem!important}.mt-2xl-3,.my-2xl-3{margin-top:1rem!important}.mr-2xl-3,.mx-2xl-3{margin-right:1rem!important}.mb-2xl-3,.my-2xl-3{margin-bottom:1rem!important}.ml-2xl-3,.mx-2xl-3{margin-left:1rem!important}.m-2xl-4{margin:1.5rem!important}.mt-2xl-4,.my-2xl-4{margin-top:1.5rem!important}.mr-2xl-4,.mx-2xl-4{margin-right:1.5rem!important}.mb-2xl-4,.my-2xl-4{margin-bottom:1.5rem!important}.ml-2xl-4,.mx-2xl-4{margin-left:1.5rem!important}.m-2xl-5{margin:3rem!important}.mt-2xl-5,.my-2xl-5{margin-top:3rem!important}.mr-2xl-5,.mx-2xl-5{margin-right:3rem!important}.mb-2xl-5,.my-2xl-5{margin-bottom:3rem!important}.ml-2xl-5,.mx-2xl-5{margin-left:3rem!important}.p-2xl-0{padding:0!important}.pt-2xl-0,.py-2xl-0{padding-top:0!important}.pr-2xl-0,.px-2xl-0{padding-right:0!important}.pb-2xl-0,.py-2xl-0{padding-bottom:0!important}.pl-2xl-0,.px-2xl-0{padding-left:0!important}.p-2xl-1{padding:.25rem!important}.pt-2xl-1,.py-2xl-1{padding-top:.25rem!important}.pr-2xl-1,.px-2xl-1{padding-right:.25rem!important}.pb-2xl-1,.py-2xl-1{padding-bottom:.25rem!important}.pl-2xl-1,.px-2xl-1{padding-left:.25rem!important}.p-2xl-2{padding:.5rem!important}.pt-2xl-2,.py-2xl-2{padding-top:.5rem!important}.pr-2xl-2,.px-2xl-2{padding-right:.5rem!important}.pb-2xl-2,.py-2xl-2{padding-bottom:.5rem!important}.pl-2xl-2,.px-2xl-2{padding-left:.5rem!important}.p-2xl-3{padding:1rem!important}.pt-2xl-3,.py-2xl-3{padding-top:1rem!important}.pr-2xl-3,.px-2xl-3{padding-right:1rem!important}.pb-2xl-3,.py-2xl-3{padding-bottom:1rem!important}.pl-2xl-3,.px-2xl-3{padding-left:1rem!important}.p-2xl-4{padding:1.5rem!important}.pt-2xl-4,.py-2xl-4{padding-top:1.5rem!important}.pr-2xl-4,.px-2xl-4{padding-right:1.5rem!important}.pb-2xl-4,.py-2xl-4{padding-bottom:1.5rem!important}.pl-2xl-4,.px-2xl-4{padding-left:1.5rem!important}.p-2xl-5{padding:3rem!important}.pt-2xl-5,.py-2xl-5{padding-top:3rem!important}.pr-2xl-5,.px-2xl-5{padding-right:3rem!important}.pb-2xl-5,.py-2xl-5{padding-bottom:3rem!important}.pl-2xl-5,.px-2xl-5{padding-left:3rem!important}.m-2xl-n1{margin:-.25rem!important}.mt-2xl-n1,.my-2xl-n1{margin-top:-.25rem!important}.mr-2xl-n1,.mx-2xl-n1{margin-right:-.25rem!important}.mb-2xl-n1,.my-2xl-n1{margin-bottom:-.25rem!important}.ml-2xl-n1,.mx-2xl-n1{margin-left:-.25rem!important}.m-2xl-n2{margin:-.5rem!important}.mt-2xl-n2,.my-2xl-n2{margin-top:-.5rem!important}.mr-2xl-n2,.mx-2xl-n2{margin-right:-.5rem!important}.mb-2xl-n2,.my-2xl-n2{margin-bottom:-.5rem!important}.ml-2xl-n2,.mx-2xl-n2{margin-left:-.5rem!important}.m-2xl-n3{margin:-1rem!important}.mt-2xl-n3,.my-2xl-n3{margin-top:-1rem!important}.mr-2xl-n3,.mx-2xl-n3{margin-right:-1rem!important}.mb-2xl-n3,.my-2xl-n3{margin-bottom:-1rem!important}.ml-2xl-n3,.mx-2xl-n3{margin-left:-1rem!important}.m-2xl-n4{margin:-1.5rem!important}.mt-2xl-n4,.my-2xl-n4{margin-top:-1.5rem!important}.mr-2xl-n4,.mx-2xl-n4{margin-right:-1.5rem!important}.mb-2xl-n4,.my-2xl-n4{margin-bottom:-1.5rem!important}.ml-2xl-n4,.mx-2xl-n4{margin-left:-1.5rem!important}.m-2xl-n5{margin:-3rem!important}.mt-2xl-n5,.my-2xl-n5{margin-top:-3rem!important}.mr-2xl-n5,.mx-2xl-n5{margin-right:-3rem!important}.mb-2xl-n5,.my-2xl-n5{margin-bottom:-3rem!important}.ml-2xl-n5,.mx-2xl-n5{margin-left:-3rem!important}.m-2xl-auto{margin:auto!important}.mt-2xl-auto,.my-2xl-auto{margin-top:auto!important}.mr-2xl-auto,.mx-2xl-auto{margin-right:auto!important}.mb-2xl-auto,.my-2xl-auto{margin-bottom:auto!important}.ml-2xl-auto,.mx-2xl-auto{margin-left:auto!important}}.stretched-link:after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:#0000}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width: 576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width: 768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width: 992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width: 1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width: 1450px){.text-2xl-left{text-align:left!important}.text-2xl-right{text-align:right!important}.text-2xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold,cd-about dt{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#2b99a8!important}a.text-primary:focus,a.text-primary:hover{color:#1b626b!important}.text-secondary{color:#374249!important}a.text-secondary:focus,a.text-secondary:hover{color:#161b1d!important}.text-success{color:#0b0!important}a.text-success:focus,a.text-success:hover{color:#006f00!important}.text-info{color:#2b99a8!important}a.text-info:focus,a.text-info:hover{color:#1b626b!important}.text-warning{color:#ffc200!important}a.text-warning:focus,a.text-warning:hover{color:#b38800!important}.text-danger{color:#ef5c55!important}a.text-danger:focus,a.text-danger:hover{color:#e21f15!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#777!important}a.text-dark:focus,a.text-dark:hover{color:#515151!important}.text-accent{color:#ef5c55!important}a.text-accent:focus,a.text-accent:hover{color:#e21f15!important}.text-warning-dark{color:#fd7e14!important}a.text-warning-dark:focus,a.text-warning-dark:hover{color:#c35a02!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:#00000080!important}.text-white-50{color:#ffffff80!important}.text-hide{font:0/0 a;color:#0000;text-shadow:none;background-color:initial;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,:after,:before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]:after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd}blockquote,img,pre,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}.container,body{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}
+/*!
+Fork Awesome 1.1.7
+License - https://forkaweso.me/Fork-Awesome/license
+
+Copyright 2018 Dave Gandy & Fork Awesome
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */@font-face{font-family:ForkAwesome;src:url(forkawesome-webfont.e182ad6df04f9177b326.eot?v=1.1.7);src:url(forkawesome-webfont.e182ad6df04f9177b326.eot?#iefix&v=1.1.7) format("embedded-opentype"),url(forkawesome-webfont.7c20758e3e7c7dff7c8d.woff2?v=1.1.7) format("woff2"),url(forkawesome-webfont.2dfb5f36fc148e26e398.woff?v=1.1.7) format("woff"),url(forkawesome-webfont.ee4d8bfd0af89fc714a2.ttf?v=1.1.7) format("truetype"),url(forkawesome-webfont.86541105409e56d17291.svg?v=1.1.7#forkawesomeregular) format("svg");font-weight:400;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 ForkAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa,.fa-fw{width:1.2857142857em;text-align:center}.fa-ul{padding-left:0;margin-left:2.1428571429em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.1428571429em;width:2.1428571429em;top:.1428571429em;text-align:center}.fa-li.fa-lg{left:-1.8571428571em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{animation:fa-spin 2s linear infinite}.fa-pulse{animation:fa-spin 1s steps(8) infinite}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before,.fa-sync:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before,.fa-video:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before{content:""}.fa-check-circle:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell-o:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-globe-e:before{content:""}.fa-globe-w:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-community:before,.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus-g:before,.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before,.fa-utensils:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before,.fa-pound:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before,.fa-sort-alpha-down:before{content:""}.fa-sort-alpha-desc:before,.fa-sort-alpha-up:before{content:""}.fa-sort-amount-asc:before,.fa-sort-amount-down:before{content:""}.fa-sort-amount-desc:before,.fa-sort-amount-up:before{content:""}.fa-sort-numeric-asc:before,.fa-sort-numeric-down:before{content:""}.fa-sort-numeric-desc:before,.fa-sort-numeric-up:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before,.fa-utensil-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before,.fa-heading:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before,.fa-closed-captioning:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before,.fa-gem:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-medium-square:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo-v:before,.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-phone-volume:before,.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.fa-mastodon:before{content:""}.fa-mastodon-alt:before{content:""}.fa-fork-awesome:before,.fa-fork-circle:before{content:""}.fa-peertube:before{content:""}.fa-diaspora:before{content:""}.fa-friendica:before{content:""}.fa-gnu-social:before{content:""}.fa-liberapay-square:before{content:""}.fa-liberapay:before{content:""}.fa-scuttlebutt:before,.fa-ssb:before{content:""}.fa-hubzilla:before{content:""}.fa-social-home:before{content:""}.fa-artstation:before{content:""}.fa-discord:before{content:""}.fa-discord-alt:before{content:""}.fa-patreon:before{content:""}.fa-snowdrift:before{content:""}.fa-activitypub:before{content:""}.fa-ethereum:before{content:""}.fa-keybase:before{content:""}.fa-shaarli:before{content:""}.fa-shaarli-o:before{content:""}.fa-cut-key:before,.fa-key-modern:before{content:""}.fa-xmpp:before{content:""}.fa-archive-org:before{content:""}.fa-freedombox:before{content:""}.fa-facebook-messenger:before{content:""}.fa-debian:before{content:""}.fa-mastodon-square:before{content:""}.fa-tipeee:before{content:""}.fa-react:before{content:""}.fa-dogmazic:before{content:""}.fa-zotero:before{content:""}.fa-nodejs:before{content:""}.fa-nextcloud:before{content:""}.fa-nextcloud-square:before{content:""}.fa-hackaday:before{content:""}.fa-laravel:before{content:""}.fa-signalapp:before{content:""}.fa-gnupg:before{content:""}.fa-php:before{content:""}.fa-ffmpeg:before{content:""}.fa-joplin:before{content:""}.fa-syncthing:before{content:""}.fa-inkscape:before{content:""}.fa-matrix-org:before{content:""}.fa-pixelfed:before{content:""}.fa-bootstrap:before{content:""}.fa-dev-to:before{content:""}.fa-hashnode:before{content:""}.fa-jirafeau:before{content:""}.fa-emby:before{content:""}.fa-wikidata:before{content:""}.fa-gimp:before{content:""}.fa-c:before{content:""}.fa-digitalocean:before{content:""}.fa-att:before{content:""}.fa-gitea:before{content:""}.fa-file-epub:before{content:""}.fa-python:before{content:""}.fa-archlinux:before{content:""}.fa-pleroma:before{content:""}.fa-unsplash:before{content:""}.fa-hackster:before{content:""}.fa-spell-check:before{content:""}.fa-moon:before{content:""}.fa-sun:before{content:""}.fa-f-droid:before{content:""}.fa-biometric:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.info-card-popover-cluster-status{max-height:20vh;max-width:23vw}.info-card-popover-cluster-status .popover-body{font-size:1rem;max-height:19vh;max-width:100%;overflow:auto}@media (max-width: calc(1200px - 1px)){.info-card-popover-cluster-status{max-width:31vw}}@media (max-width: calc(992px - 1px)){.info-card-popover-cluster-status{max-width:46vw}}@media (max-width: calc(768px - 1px)){.info-card-popover-cluster-status{max-width:83vw}}.info-card-content-clickable{border:1px solid #e9ecef;border-radius:3px;cursor:pointer;padding:7px}.info-card-content-clickable:hover{background-color:#e9ecef;border-color:#ced4da}html{background-color:#fff}body,html{font-size:12px;height:100%;width:100%}option{font-style:normal;font-weight:400}mark{background-color:#ffc200;padding:0}.full-height{height:100vh}.full-width{width:100vw}.vertical-align{align-items:center;display:flex}.horizontal-align{display:flex;justify-content:center}.loading:not(cd-api-docs *){left:50%;position:absolute;top:50%}.margin-right-md{margin-right:15px}.no-border{border:0;box-shadow:0 0 0!important}.italic{font-style:italic}.bold{font-weight:700}.text-right{text-align:right}.text-monospace{font-family:monospace}.text-pre-wrap{white-space:pre-wrap}.text-pre{white-space:pre}.border-danger{border-left:4px solid #ef5c55}.border-info{border-left:4px solid #2b99a8}.border-success{border-left:4px solid #0b0}.vertical-line{border-left:1px solid #ced4da}.accordion .card,.accordion pre:not(cd-api-docs *){border:0}.accordion .card-header{border:0;border-bottom:3px solid #fff;padding-left:0}.accordion .card-header .btn.focus,.accordion .card-header .btn:focus{box-shadow:none}.accordion .card-header button.dropdown-toggle{position:relative}.accordion .card-header button.dropdown-toggle:after{border:0;content:"";font-family:ForkAwesome;font-size:1rem;position:absolute;right:20px;transition:transform .3s ease-in-out}.accordion .card-header button.dropdown-toggle[aria-expanded=true]:after{transform:rotate(90deg)}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:initial}.custom-control-input.is-valid:checked~.custom-control-label:before,.was-validated .custom-control-input:valid:checked~.custom-control-label:before{background-color:#2b99a8;border-color:#2b99a8}.custom-control-input.is-valid~.custom-control-label:before,.was-validated .custom-control-input:valid~.custom-control-label:before{border-color:#adb5bd}.custom-control-input.is-valid:focus~.custom-control-label:before,.was-validated .custom-control-input:valid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem #2b99a840}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label:before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label:before{border-color:#76d0dc}.btn-light{background-color:#fff;border-color:#ced4da!important}.btn-light:hover{background-color:#dee2e6;border-color:#6c757d!important}.btn-light:disabled{background-color:#e9ecef;border-color:#ced4da!important}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:0}.btn.disabled{border:0;box-shadow:none}.btn-primary .badge{background-color:#e9ecef;color:#2b99a8}.btn-group>.btn>i.fa,.cd-datatable-actions button.btn i.fa{margin-right:5px}.card-footer button.btn:not(:first-child){margin-left:5px}.dropdown-menu{min-width:50px;z-index:999999}.dropdown-menu button.dropdown-item:focus{outline:none}.dropdown-menu>li>a{cursor:pointer}.dropdown-menu>li>a>i.fa{margin-right:5px}.dropdown-menu>.active>a{background-color:#2b99a8;color:#e9ecef}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#21747f}.dataTables_wrapper .dropdown-menu>li.dropdown-divider{cursor:auto}.required:after{color:#ef5c55;content:"*";font-size:1.167rem;padding-left:4px}.form-footer{display:flex;width:100%}.cd-form-control,.form-control{display:table-cell}.cd-form-control:focus,.form-control:focus{border-color:#2b99a8cc;box-shadow:0 0 3px 2px #2b99a880;outline:0}.custom-checkbox{padding-top:7px}.custom-radio{padding-top:5px}cd-modal .modal{background-color:#0006;display:block}cd-modal .modal-dialog{max-width:70vh}.invalid-feedback{display:block}.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{padding:0 30px}.ceph-icon{background:url(Ceph_Logo.487a0001b327fa7f5232.svg)}.prometheus-icon{background:url(prometheus_logo.8b3183e5a2db0e87bb2b.svg)}.custom-icon{background-clip:padding-box;background-repeat:no-repeat;background-size:contain;margin-right:8px;padding:10px}.nav-tabs{margin-bottom:1rem}#toast-container{margin-top:2vw}@media (max-width: 1600px){#toast-container{margin-top:2.5vw}}@media (max-width: calc(992px - 1px)){#toast-container{margin-top:9vw}}@media (max-width: 900px){#toast-container{margin-top:10vw}}@media (max-width: 319px){#toast-container{margin-top:11vw}}@media (max-width: 260px){#toast-container{margin-top:14vw}}.toast-message>ul{margin:0;padding-left:1rem}.noscript{padding-top:5em}@media (min-width: 576px){.cd-col-form-label,.col-form-label{text-align:right}}.cd-col-form-label,.col-form-label{font-weight:700}.password-strength-level{flex:100%;margin-top:2px}.password-strength-level .ok,.password-strength-level .strong,.password-strength-level .very-strong,.password-strength-level .weak{border-radius:.25rem;height:13px}.password-strength-level .weak{background:#ef5c55;width:25%}.password-strength-level .ok{background:#ffc200;width:50%}.password-strength-level .strong{background:#0b0;width:75%}.password-strength-level .very-strong{background:#006f00;width:100%}.badge-background-gray,.badge-hdd{background-color:#6c757d;color:#fff}.badge-background-primary,.badge-ssd{background-color:#2b99a8;color:#fff}.badge-tab{background-color:#e9ecef;color:#495057}tree-root tree-viewport{min-height:1em}tags-input .tags{border:1px solid #ced4da;border-radius:4px;box-shadow:inset 0 1px 1px #00000017}.card-header{font-size:1.3em}.card-body h2:first-child{margin-top:0}.disabled{pointer-events:none}.clickable,a{cursor:pointer} \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/html-linter.config.json b/src/pybind/mgr/dashboard/frontend/html-linter.config.json
new file mode 100644
index 000000000..bf91475d8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/html-linter.config.json
@@ -0,0 +1,12 @@
+{
+ "files": ["src/**/*.html"],
+ "indentation": {
+ "char": "space",
+ "number": 2
+ },
+ "attributes": {
+ "quotes": "double",
+ "whitespace": 0,
+ "vertical-align": true
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/i18n.config.json b/src/pybind/mgr/dashboard/frontend/i18n.config.json
new file mode 100644
index 000000000..f5ba06d47
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/i18n.config.json
@@ -0,0 +1,12 @@
+{
+ "sourceDirectory": "src/locale",
+ "targetDirectory": "src/locale",
+ "sourceFile": "messages.xlf",
+ "languages": "cs,de-DE,es-ES,fr-FR,id-ID,it-IT,ja-JP,ko-KR,pl-PL,pt-BR,zh-CN,zh-TW",
+ "organization": "ceph",
+ "project": "ceph-dashboard",
+ "resource": "Pacific:pacific",
+ "removeUnusedIds": true,
+ "automate": true,
+ "quiet": false
+}
diff --git a/src/pybind/mgr/dashboard/frontend/ngcc.config.js b/src/pybind/mgr/dashboard/frontend/ngcc.config.js
new file mode 100644
index 000000000..9c190711f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/ngcc.config.js
@@ -0,0 +1,10 @@
+module.exports = {
+ packages: {
+ 'simplebar-angular': {
+ ignorableDeepImportMatchers: [/simplebar-core\.esm/]
+ },
+ '@locl/cli': {
+ ignorableDeepImportMatchers: [/@angular\/localize/, /@angular\/compiler-cli/]
+ }
+ }
+};
diff --git a/src/pybind/mgr/dashboard/frontend/package-lock.json b/src/pybind/mgr/dashboard/frontend/package-lock.json
new file mode 100644
index 000000000..f84e0560e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/package-lock.json
@@ -0,0 +1,28313 @@
+{
+ "name": "ceph-dashboard",
+ "version": "0.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@aduh95/viz.js": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/@aduh95/viz.js/-/viz.js-3.7.0.tgz",
+ "integrity": "sha512-20Pk2Z98fbPLkECcrZSJszKos/OgtvJJR3NcbVfgCJ6EQjDNzW2P1BKqImOz3tJ952dvO2DWEhcLhQ1Wz1e9ng==",
+ "dev": true
+ },
+ "@ampproject/remapping": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-1.0.1.tgz",
+ "integrity": "sha512-Ta9bMA3EtUHDaZJXqUoT5cn/EecwOp+SXpKJqxDbDuMbLvEMu6YTyDDuvTWeStODfdmXyfMo7LymQyPkN3BicA==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/resolve-uri": "1.0.0",
+ "sourcemap-codec": "1.4.8"
+ },
+ "dependencies": {
+ "@jridgewell/resolve-uri": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-1.0.0.tgz",
+ "integrity": "sha512-9oLAnygRMi8Q5QkYEU4XWK04B+nuoXoxjRvRxgjuChkLZFBja0YPSgdZ7dZtwhncLBcQe/I/E+fLuk5qxcYVJA==",
+ "dev": true
+ }
+ }
+ },
+ "@angular-devkit/architect": {
+ "version": "0.1202.13",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1202.13.tgz",
+ "integrity": "sha512-LXgiidXwBgyWPqqWK4xR1/kCPQTMTzG5w+s7+LvENUZwbcdl6CKrOMjfgjo6WPr6yeq+WWQvPCD4pZ6nXRTm7A==",
+ "dev": true,
+ "requires": {
+ "@angular-devkit/core": "12.2.13",
+ "rxjs": "6.6.7"
+ },
+ "dependencies": {
+ "rxjs": {
+ "version": "6.6.7",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+ "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ }
+ }
+ },
+ "@angular-devkit/build-angular": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-12.2.13.tgz",
+ "integrity": "sha512-iJ1P/RZ1hk2n/HtEqB5ohXvHa+Hf0BXShYskSGrn6/klcTb0eJTCREsFxHk7mNEmRIGPWkjbLAslqpPgwiagXg==",
+ "dev": true,
+ "requires": {
+ "@ampproject/remapping": "1.0.1",
+ "@angular-devkit/architect": "0.1202.13",
+ "@angular-devkit/build-optimizer": "0.1202.13",
+ "@angular-devkit/build-webpack": "0.1202.13",
+ "@angular-devkit/core": "12.2.13",
+ "@babel/core": "7.14.8",
+ "@babel/generator": "7.14.8",
+ "@babel/helper-annotate-as-pure": "7.14.5",
+ "@babel/plugin-proposal-async-generator-functions": "7.14.7",
+ "@babel/plugin-transform-async-to-generator": "7.14.5",
+ "@babel/plugin-transform-runtime": "7.14.5",
+ "@babel/preset-env": "7.14.8",
+ "@babel/runtime": "7.14.8",
+ "@babel/template": "7.14.5",
+ "@discoveryjs/json-ext": "0.5.3",
+ "@jsdevtools/coverage-istanbul-loader": "3.0.5",
+ "@ngtools/webpack": "12.2.13",
+ "ansi-colors": "4.1.1",
+ "babel-loader": "8.2.2",
+ "browserslist": "^4.9.1",
+ "cacache": "15.2.0",
+ "caniuse-lite": "^1.0.30001032",
+ "circular-dependency-plugin": "5.2.2",
+ "copy-webpack-plugin": "9.0.1",
+ "core-js": "3.16.0",
+ "critters": "0.0.12",
+ "css-loader": "6.2.0",
+ "css-minimizer-webpack-plugin": "3.0.2",
+ "esbuild": "0.13.8",
+ "esbuild-wasm": "0.13.8",
+ "find-cache-dir": "3.3.1",
+ "glob": "7.1.7",
+ "https-proxy-agent": "5.0.0",
+ "inquirer": "8.1.2",
+ "karma-source-map-support": "1.4.0",
+ "less": "4.1.1",
+ "less-loader": "10.0.1",
+ "license-webpack-plugin": "2.3.20",
+ "loader-utils": "2.0.0",
+ "mini-css-extract-plugin": "2.4.2",
+ "minimatch": "3.0.4",
+ "open": "8.2.1",
+ "ora": "5.4.1",
+ "parse5-html-rewriting-stream": "6.0.1",
+ "piscina": "3.1.0",
+ "postcss": "8.3.6",
+ "postcss-import": "14.0.2",
+ "postcss-loader": "6.1.1",
+ "postcss-preset-env": "6.7.0",
+ "regenerator-runtime": "0.13.9",
+ "resolve-url-loader": "4.0.0",
+ "rxjs": "6.6.7",
+ "sass": "1.36.0",
+ "sass-loader": "12.1.0",
+ "semver": "7.3.5",
+ "source-map-loader": "3.0.0",
+ "source-map-support": "0.5.19",
+ "style-loader": "3.2.1",
+ "stylus": "0.54.8",
+ "stylus-loader": "6.1.0",
+ "terser": "5.7.1",
+ "terser-webpack-plugin": "5.1.4",
+ "text-table": "0.2.0",
+ "tree-kill": "1.2.2",
+ "tslib": "2.3.0",
+ "webpack": "5.50.0",
+ "webpack-dev-middleware": "5.0.0",
+ "webpack-dev-server": "3.11.2",
+ "webpack-merge": "5.8.0",
+ "webpack-subresource-integrity": "1.5.2"
+ },
+ "dependencies": {
+ "@babel/core": {
+ "version": "7.14.8",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.8.tgz",
+ "integrity": "sha512-/AtaeEhT6ErpDhInbXmjHcUQXH0L0TEgscfcxk1qbOvLuKCa5aZT0SOOtDKFY96/CLROwbLSKyFor6idgNaU4Q==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.14.8",
+ "@babel/helper-compilation-targets": "^7.14.5",
+ "@babel/helper-module-transforms": "^7.14.8",
+ "@babel/helpers": "^7.14.8",
+ "@babel/parser": "^7.14.8",
+ "@babel/template": "^7.14.5",
+ "@babel/traverse": "^7.14.8",
+ "@babel/types": "^7.14.8",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.1.2",
+ "semver": "^6.3.0",
+ "source-map": "^0.5.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/generator": {
+ "version": "7.14.8",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.8.tgz",
+ "integrity": "sha512-cYDUpvIzhBVnMzRoY1fkSEhK/HmwEVwlyULYgn/tMQYd6Obag3ylCjONle3gdErfXBW61SVTlR9QR7uWlgeIkg==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.14.8",
+ "jsesc": "^2.5.1",
+ "source-map": "^0.5.0"
+ }
+ },
+ "@babel/runtime": {
+ "version": "7.14.8",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
+ "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
+ "dev": true,
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "@babel/template": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ }
+ },
+ "core-js": {
+ "version": "3.16.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.16.0.tgz",
+ "integrity": "sha512-5+5VxRFmSf97nM8Jr2wzOwLqRo6zphH2aX+7KsAUONObyzakDNq2G/bgbhinxB4PoV9L3aXQYhiDKyIKWd2c8g==",
+ "dev": true
+ },
+ "esbuild": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.13.8.tgz",
+ "integrity": "sha512-A4af7G7YZLfG5OnARJRMtlpEsCkq/zHZQXewgPA864l9D6VjjbH1SuFYK/OSV6BtHwDGkdwyRrX0qQFLnMfUcw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "esbuild-android-arm64": "0.13.8",
+ "esbuild-darwin-64": "0.13.8",
+ "esbuild-darwin-arm64": "0.13.8",
+ "esbuild-freebsd-64": "0.13.8",
+ "esbuild-freebsd-arm64": "0.13.8",
+ "esbuild-linux-32": "0.13.8",
+ "esbuild-linux-64": "0.13.8",
+ "esbuild-linux-arm": "0.13.8",
+ "esbuild-linux-arm64": "0.13.8",
+ "esbuild-linux-mips64le": "0.13.8",
+ "esbuild-linux-ppc64le": "0.13.8",
+ "esbuild-netbsd-64": "0.13.8",
+ "esbuild-openbsd-64": "0.13.8",
+ "esbuild-sunos-64": "0.13.8",
+ "esbuild-windows-32": "0.13.8",
+ "esbuild-windows-64": "0.13.8",
+ "esbuild-windows-arm64": "0.13.8"
+ }
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "rxjs": {
+ "version": "6.6.7",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+ "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ }
+ }
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "tslib": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
+ "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
+ "dev": true
+ }
+ }
+ },
+ "@angular-devkit/build-optimizer": {
+ "version": "0.1202.13",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.1202.13.tgz",
+ "integrity": "sha512-XX6rX5+mAl+MiIJDvi5N5mBLWOoskhMJ5r/G1PEqv0CMMJSSw60zUTndjxfq/nrX0PtsV3j/aqHN4Sj0w/gumg==",
+ "dev": true,
+ "requires": {
+ "source-map": "0.7.3",
+ "tslib": "2.3.0",
+ "typescript": "4.3.5"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+ "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+ "dev": true
+ },
+ "tslib": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
+ "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
+ "dev": true
+ }
+ }
+ },
+ "@angular-devkit/build-webpack": {
+ "version": "0.1202.13",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1202.13.tgz",
+ "integrity": "sha512-KafzGyHuU2gBKaSICfMTFP2niTYZ/46DKU94TQ0lCILdJZsj0NE5M/288LSCbYgu2c7srJKz+Rvb+JcYGxIZ1g==",
+ "dev": true,
+ "requires": {
+ "@angular-devkit/architect": "0.1202.13",
+ "rxjs": "6.6.7"
+ },
+ "dependencies": {
+ "rxjs": {
+ "version": "6.6.7",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+ "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ }
+ }
+ },
+ "@angular-devkit/core": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.2.13.tgz",
+ "integrity": "sha512-9csMF0p+lTvlWnutxxTZ/+pDRMIbXk/TV4MGLbcqUPPfeG3dCRwErns73xLuMTwp9qO/KCLkFqNaM6cGOoqsDA==",
+ "dev": true,
+ "requires": {
+ "ajv": "8.6.2",
+ "ajv-formats": "2.1.0",
+ "fast-json-stable-stringify": "2.1.0",
+ "magic-string": "0.25.7",
+ "rxjs": "6.6.7",
+ "source-map": "0.7.3"
+ },
+ "dependencies": {
+ "rxjs": {
+ "version": "6.6.7",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+ "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "source-map": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+ "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+ "dev": true
+ },
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ }
+ }
+ },
+ "@angular-devkit/schematics": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-12.2.13.tgz",
+ "integrity": "sha512-LQTv72R5Ma1uowMEeii2wIoDWI4bYQyZvunqPy9jRveBTjli2yVwwcOziGCVyttwlYs46bSdxThgeEvVIako2w==",
+ "dev": true,
+ "requires": {
+ "@angular-devkit/core": "12.2.13",
+ "ora": "5.4.1",
+ "rxjs": "6.6.7"
+ },
+ "dependencies": {
+ "rxjs": {
+ "version": "6.6.7",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+ "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ }
+ }
+ },
+ "@angular/animations": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-12.2.13.tgz",
+ "integrity": "sha512-qpdmvu+nxsKnimJ3Hc1joNuzK7xXYyE+VtNMk4K77Ao/9+5C/juGMce85DhqZCcu1xraZ3YYIrzYmL/GgdUK4g==",
+ "requires": {
+ "tslib": "^2.2.0"
+ }
+ },
+ "@angular/cli": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-12.2.13.tgz",
+ "integrity": "sha512-Yz6MuwdxxP6U2i8iRuCSNZeJxlLDPshT/joymCsFdjwSMGEH9Kk9DdvAfFYfzdHGdHbGrDdASJ4G+uALyNSLxw==",
+ "dev": true,
+ "requires": {
+ "@angular-devkit/architect": "0.1202.13",
+ "@angular-devkit/core": "12.2.13",
+ "@angular-devkit/schematics": "12.2.13",
+ "@schematics/angular": "12.2.13",
+ "@yarnpkg/lockfile": "1.1.0",
+ "ansi-colors": "4.1.1",
+ "debug": "4.3.2",
+ "ini": "2.0.0",
+ "inquirer": "8.1.2",
+ "jsonc-parser": "3.0.0",
+ "npm-package-arg": "8.1.5",
+ "npm-pick-manifest": "6.1.1",
+ "open": "8.2.1",
+ "ora": "5.4.1",
+ "pacote": "11.3.5",
+ "resolve": "1.20.0",
+ "semver": "7.3.5",
+ "symbol-observable": "4.0.0",
+ "uuid": "8.3.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "resolve": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
+ "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.2.0",
+ "path-parse": "^1.0.6"
+ }
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "@angular/common": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/common/-/common-12.2.13.tgz",
+ "integrity": "sha512-I1t/jl9ojCwTJKT7PKHnk23D+vMHTHS/9qZ2nndCjzGusMK8029nn8l3tHAkwefvxZWSaLAk1MgsVcP+rHQNsQ==",
+ "requires": {
+ "tslib": "^2.2.0"
+ }
+ },
+ "@angular/compiler": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-12.2.13.tgz",
+ "integrity": "sha512-L0saTTJJtxldjhaGIL6b1BCfodPOEz4Wrev3pEUK5UcODooj5HLiE/aO6jiNb8M4XTbdqByKyqvZyWzGHeexVQ==",
+ "requires": {
+ "tslib": "^2.2.0"
+ }
+ },
+ "@angular/compiler-cli": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-12.2.13.tgz",
+ "integrity": "sha512-qmnmihl3SCRooj/mCsNIZLtnQ6qbx1/L6aMIEQosPvQhMeGMt8GCYvQPE8IZ+sahv7fih95HCWNa9TeLpOylug==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.8.6",
+ "@babel/types": "^7.8.6",
+ "canonical-path": "1.0.0",
+ "chokidar": "^3.0.0",
+ "convert-source-map": "^1.5.1",
+ "dependency-graph": "^0.11.0",
+ "magic-string": "^0.25.0",
+ "minimist": "^1.2.0",
+ "reflect-metadata": "^0.1.2",
+ "semver": "^7.0.0",
+ "source-map": "^0.6.1",
+ "sourcemap-codec": "^1.4.8",
+ "tslib": "^2.2.0",
+ "yargs": "^17.0.0"
+ },
+ "dependencies": {
+ "@ampproject/remapping": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
+ "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/gen-mapping": "^0.1.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@babel/core": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.0.tgz",
+ "integrity": "sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==",
+ "dev": true,
+ "requires": {
+ "@ampproject/remapping": "^2.1.0",
+ "@babel/code-frame": "^7.18.6",
+ "@babel/generator": "^7.19.0",
+ "@babel/helper-compilation-targets": "^7.19.0",
+ "@babel/helper-module-transforms": "^7.19.0",
+ "@babel/helpers": "^7.19.0",
+ "@babel/parser": "^7.19.0",
+ "@babel/template": "^7.18.10",
+ "@babel/traverse": "^7.19.0",
+ "@babel/types": "^7.19.0",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.1",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "@jridgewell/gen-mapping": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
+ "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.0",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "@angular/core": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/core/-/core-12.2.13.tgz",
+ "integrity": "sha512-tZ5nAnmOi418JDaJIFiiP9z2JrluMJZvUvXO4QDUs52BXaL2yuP7MJ2LczWOVJXrBLZXeZGfjDjZmaFPA24grg==",
+ "requires": {
+ "tslib": "^2.2.0"
+ }
+ },
+ "@angular/forms": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-12.2.13.tgz",
+ "integrity": "sha512-wa7I5R8sck2q+VWNL262GJTVxtpEHMys8Bt6oE+lyHB5zlZAgOXwAb8GE4XVwuc+BZU1Gvrocn21P/8KvDY1uw==",
+ "requires": {
+ "tslib": "^2.2.0"
+ }
+ },
+ "@angular/language-service": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-12.2.13.tgz",
+ "integrity": "sha512-jb9s3IJuWNKTRcM90NOwvMfiy85nnKfTxxLVn8/QFMO6+Ps/hsVZNp+W/TmAEDvCkon+9q0O4hwa4MY1m/Dlkw==",
+ "dev": true
+ },
+ "@angular/localize": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-12.2.13.tgz",
+ "integrity": "sha512-mAGs86JaWaoHN/+Mmvq1QppiTbIT1FWC5cUe0dnpGStfoKqiULPSjiHTzlfJw/eUZUMOMD7C8kjbbhv3jjLTIQ==",
+ "requires": {
+ "@babel/core": "7.8.3",
+ "glob": "7.1.7",
+ "yargs": "^17.0.0"
+ }
+ },
+ "@angular/platform-browser": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-12.2.13.tgz",
+ "integrity": "sha512-Ua8m2GtG2msqz/Mr/MK7s8RXud554x8cup2THVAwetyTaY5th/1LOZX0hhDIhfsxBCLHnC53LRhMbSsI0cikOg==",
+ "requires": {
+ "tslib": "^2.2.0"
+ }
+ },
+ "@angular/platform-browser-dynamic": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-12.2.13.tgz",
+ "integrity": "sha512-a7y7R3vOXhMAk9uQWK5/23DefahuF0UYJSFM/wKeVo5zR+qOCVCTfafkJMcWbuZWTrSDbVafJ1xbcWnu3+TkCg==",
+ "requires": {
+ "tslib": "^2.2.0"
+ }
+ },
+ "@angular/router": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/router/-/router-12.2.13.tgz",
+ "integrity": "sha512-HZL/Pzp6I7fQiMLrzfEzhnqhgNcGcFjBgMMOoLp5IA1IV26rp1NU6zYJzPrXtopBx7XLl8BECehAwFqrJsu/PQ==",
+ "requires": {
+ "tslib": "^2.2.0"
+ }
+ },
+ "@applitools/dom-capture": {
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/@applitools/dom-capture/-/dom-capture-11.0.1.tgz",
+ "integrity": "sha512-6W9qbm8Hvn2jzy0Y7LfVc4sOOHza8C8MvLFI/q60bjyti1lpaddZaePkdE+UJi/6cGkDaCQNjOJTLJAm2xvW8g==",
+ "dev": true,
+ "requires": {
+ "@applitools/dom-shared": "1.0.5",
+ "@applitools/functional-commons": "1.6.0"
+ },
+ "dependencies": {
+ "@applitools/dom-shared": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@applitools/dom-shared/-/dom-shared-1.0.5.tgz",
+ "integrity": "sha512-O2zgnnqVi3/Atq7EQjURLa73XNaDFJCj8wHht6WQtxIv1EWYnPutNTmnJSKwK7FnbJAg65OVjZylcz4EezyYZA==",
+ "dev": true
+ }
+ }
+ },
+ "@applitools/dom-shared": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@applitools/dom-shared/-/dom-shared-1.0.6.tgz",
+ "integrity": "sha512-GnMhI0aOea+WLSFQmlFqs0pFemT4JtdB0CBwNdxdS19t+X4FL4uKthkMU1A2e7JmxIhe0nn6iJchGWzlNsXyQQ==",
+ "dev": true
+ },
+ "@applitools/dom-snapshot": {
+ "version": "4.5.8",
+ "resolved": "https://registry.npmjs.org/@applitools/dom-snapshot/-/dom-snapshot-4.5.8.tgz",
+ "integrity": "sha512-Fp52Wqnto9UqDltB9SVbcIvTqDXF0l78uAlZh0ddDbPY8Kcq7eT6YsfQjzyl3cO9uZW/c75OFEHVzUrLJkn6jA==",
+ "dev": true,
+ "requires": {
+ "@applitools/dom-shared": "1.0.6",
+ "@applitools/functional-commons": "1.6.0",
+ "css-tree": "1.0.0-alpha.39",
+ "pako": "1.0.11"
+ },
+ "dependencies": {
+ "css-tree": {
+ "version": "1.0.0-alpha.39",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz",
+ "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==",
+ "dev": true,
+ "requires": {
+ "mdn-data": "2.0.6",
+ "source-map": "^0.6.1"
+ }
+ },
+ "mdn-data": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz",
+ "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "@applitools/driver": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@applitools/driver/-/driver-1.2.4.tgz",
+ "integrity": "sha512-lbISIrocCEL28sFN31uU6vhWUJkbCLzfdH7YSYruM+wsjmJkW/WB2jAPlfRCOcWQObxpnTWPGVokGjnh4cIIzQ==",
+ "dev": true,
+ "requires": {
+ "@applitools/snippets": "2.1.7",
+ "@applitools/types": "1.0.14",
+ "@applitools/utils": "1.2.3"
+ }
+ },
+ "@applitools/eyes-cypress": {
+ "version": "3.22.5",
+ "resolved": "https://registry.npmjs.org/@applitools/eyes-cypress/-/eyes-cypress-3.22.5.tgz",
+ "integrity": "sha512-UKTmfI87spyTMvL4G3q8I6yYP9UoJKLgF347Qdbjkg3MzFo20oVAgKchuZZc+RnG2vzPn59gD13RA3JvJKJfOA==",
+ "dev": true,
+ "requires": {
+ "@applitools/dom-snapshot": "4.5.8",
+ "@applitools/functional-commons": "1.6.0",
+ "@applitools/visual-grid-client": "15.8.31",
+ "body-parser": "1.19.0",
+ "chalk": "3.0.0",
+ "cors": "2.8.5",
+ "express": "4.17.1",
+ "lodash.flatten": "4.4.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
+ "dev": true
+ },
+ "body-parser": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+ "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+ "dev": true,
+ "requires": {
+ "bytes": "3.1.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "on-finished": "~2.3.0",
+ "qs": "6.7.0",
+ "raw-body": "2.4.0",
+ "type-is": "~1.6.17"
+ }
+ },
+ "bytes": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+ "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "content-disposition": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+ "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.2"
+ }
+ },
+ "cookie": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+ "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
+ "dev": true
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==",
+ "dev": true
+ },
+ "express": {
+ "version": "4.17.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+ "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+ "dev": true,
+ "requires": {
+ "accepts": "~1.3.7",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.19.0",
+ "content-disposition": "0.5.3",
+ "content-type": "~1.0.4",
+ "cookie": "0.4.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "~1.1.2",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.5",
+ "qs": "6.7.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.1.2",
+ "send": "0.17.1",
+ "serve-static": "1.14.1",
+ "setprototypeof": "1.1.1",
+ "statuses": "~1.5.0",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ }
+ },
+ "finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "http-errors": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+ "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+ "dev": true,
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.1",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.0"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
+ "dev": true,
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+ "dev": true
+ },
+ "raw-body": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+ "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+ "dev": true,
+ "requires": {
+ "bytes": "3.1.0",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ }
+ },
+ "send": {
+ "version": "0.17.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+ "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.7.2",
+ "mime": "1.6.0",
+ "ms": "2.1.1",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.1",
+ "statuses": "~1.5.0"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+ "dev": true
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+ "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+ "dev": true,
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.17.1"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
+ "dev": true
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "toidentifier": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
+ "dev": true
+ }
+ }
+ },
+ "@applitools/eyes-sdk-core": {
+ "version": "12.23.12",
+ "resolved": "https://registry.npmjs.org/@applitools/eyes-sdk-core/-/eyes-sdk-core-12.23.12.tgz",
+ "integrity": "sha512-nVDWYe1VvUpCQrvjUgDASIDDgHMtIjxXrI52Tvdov1ya/jhyNn6vMYHW9ZgSmjwdrYAoq+p7B90qIdy/HEV5DA==",
+ "dev": true,
+ "requires": {
+ "@applitools/dom-capture": "11.0.1",
+ "@applitools/dom-snapshot": "4.5.8",
+ "@applitools/driver": "1.2.4",
+ "@applitools/isomorphic-fetch": "3.0.0",
+ "@applitools/logger": "1.0.4",
+ "@applitools/screenshoter": "3.2.4",
+ "@applitools/snippets": "2.1.7",
+ "@applitools/types": "1.0.14",
+ "@applitools/utils": "1.2.3",
+ "axios": "0.21.4",
+ "chalk": "3.0.0",
+ "cosmiconfig": "6.0.0",
+ "dateformat": "3.0.3",
+ "debug": "4.2.0",
+ "deepmerge": "4.2.2",
+ "stack-trace": "0.0.10",
+ "tunnel": "0.0.6"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "cosmiconfig": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
+ "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
+ "dev": true,
+ "requires": {
+ "@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"
+ }
+ },
+ "debug": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
+ "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@applitools/functional-commons": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@applitools/functional-commons/-/functional-commons-1.6.0.tgz",
+ "integrity": "sha512-fwiF0CbeYHDEOTD/NKaFgaI8LvRcGYG2GaJJiRwcedKko16sQ8F3TK5wXfj2Ytjf+8gjwHwsEEX550z3yvDWxA==",
+ "dev": true
+ },
+ "@applitools/http-commons": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/@applitools/http-commons/-/http-commons-2.4.3.tgz",
+ "integrity": "sha512-MBhrHcjDxhkyiw9bRlwe6uhjYg7IsNrsAbDf3w8wfB6iFrCABxsTnPKbnLoT4pyf//s2NFJqFUmcJpwJeEjJmw==",
+ "dev": true,
+ "requires": {
+ "@applitools/functional-commons": "^1.5.5",
+ "@applitools/monitoring-commons": "^1.0.19",
+ "agentkeepalive": "^4.1.0",
+ "debug": "^4.1.1",
+ "lodash.merge": "^4.6.2",
+ "node-fetch": "^2.6.0"
+ }
+ },
+ "@applitools/isomorphic-fetch": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@applitools/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz",
+ "integrity": "sha512-7rutaN/2M5wYjOIOTKS/Zuc1Na90fJNEAqvo/jCxt7nSD1kYscHV3aCk9t7RD59gmzLMvUTIxFbjl4RUMV8qfg==",
+ "dev": true,
+ "requires": {
+ "node-fetch": "^2.3.0",
+ "whatwg-fetch": ">=0.10.0"
+ }
+ },
+ "@applitools/jsdom": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@applitools/jsdom/-/jsdom-1.0.3.tgz",
+ "integrity": "sha512-Iy/Sw7GCzbVYdhg/yveTnss6mNma1Gr+MtYQhcd4ahG7aDyiHXYAAx8XSqO56dozaRz5trJVjQ4K8vf7NS+R+A==",
+ "dev": true,
+ "requires": {
+ "abab": "^2.0.0",
+ "acorn": "^7.4.1",
+ "acorn-globals": "^4.3.2",
+ "array-equal": "^1.0.0",
+ "cssom": "^0.4.1",
+ "cssstyle": "^2.0.0",
+ "data-urls": "^1.1.0",
+ "domexception": "^1.0.1",
+ "escodegen": "^1.11.1",
+ "html-encoding-sniffer": "^1.0.2",
+ "nwsapi": "^2.2.0",
+ "parse5": "5.1.0",
+ "pn": "^1.1.0",
+ "request": "^2.88.0",
+ "request-promise-native": "^1.0.7",
+ "saxes": "^3.1.9",
+ "symbol-tree": "^3.2.2",
+ "tough-cookie": "^3.0.1",
+ "w3c-hr-time": "^1.0.1",
+ "w3c-xmlserializer": "^1.1.2",
+ "webidl-conversions": "^4.0.2",
+ "whatwg-encoding": "^1.0.5",
+ "whatwg-mimetype": "^2.3.0",
+ "whatwg-url": "^7.0.0",
+ "ws": "^7.0.0",
+ "xml-name-validator": "^3.0.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true
+ },
+ "parse5": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
+ "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==",
+ "dev": true
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ },
+ "tough-cookie": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
+ "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
+ "dev": true,
+ "requires": {
+ "ip-regex": "^2.1.0",
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
+ }
+ },
+ "tr46": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+ "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "webidl-conversions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+ "dev": true
+ },
+ "whatwg-url": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+ "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+ "dev": true,
+ "requires": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
+ }
+ },
+ "ws": {
+ "version": "7.5.9",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
+ "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
+ "dev": true
+ }
+ }
+ },
+ "@applitools/logger": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@applitools/logger/-/logger-1.0.4.tgz",
+ "integrity": "sha512-GQ/OdEVUY4fnkNLXVswSxaBncIfQqsfy+H1JyI85XGTjWIH4LqV/GQqnaiet2o4SHabGe8vHs0eyoWyT0WgAnQ==",
+ "dev": true,
+ "requires": {
+ "@applitools/utils": "1.2.3",
+ "chalk": "3.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@applitools/monitoring-commons": {
+ "version": "1.0.19",
+ "resolved": "https://registry.npmjs.org/@applitools/monitoring-commons/-/monitoring-commons-1.0.19.tgz",
+ "integrity": "sha512-rzEOvGoiEF4KnK0PJ9I0btdwnaNlIPLYhjF1vTEG15PoucbbKpix9fYusxWlDG7kMiZya8ZycVPc0woVlNaHRQ==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.0"
+ }
+ },
+ "@applitools/screenshoter": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@applitools/screenshoter/-/screenshoter-3.2.4.tgz",
+ "integrity": "sha512-v1lhUVMZYvjP2aFm2XTZmschRaPv0xJiVmi4tc7aWcWk4Gu4LgrmcV0yI6QqPkl5fGuK/VwvRBg9tyvX1eWZhA==",
+ "dev": true,
+ "requires": {
+ "@applitools/snippets": "2.1.7",
+ "@applitools/utils": "1.2.3",
+ "png-async": "0.9.4"
+ }
+ },
+ "@applitools/snippets": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@applitools/snippets/-/snippets-2.1.7.tgz",
+ "integrity": "sha512-Tr4Gj7Qov/oPy+8WI4oVmmubxqpOzr8P3Wjzpl6rA57xKLg6/TiIg5oZNb4+jEmO2ShjNYLaEwRWHl7kPgb4fw==",
+ "dev": true
+ },
+ "@applitools/types": {
+ "version": "1.0.14",
+ "resolved": "https://registry.npmjs.org/@applitools/types/-/types-1.0.14.tgz",
+ "integrity": "sha512-Exfi8EOGGBwpRpaLizXmsUXInXGXNU26qup7AjLJSJLYETwn3Q3W+0aLHBUbdFA87w9fPCQjXJuZxJgqsNpVig==",
+ "dev": true
+ },
+ "@applitools/utils": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@applitools/utils/-/utils-1.2.3.tgz",
+ "integrity": "sha512-MZXsrzeHTvjFLzpfyKRDUmZWzNxH3gWd3reqYf+1kYimALKB3CO82VDNmkaGJykrRbxEP03Yqha7fHJj9eKslQ==",
+ "dev": true
+ },
+ "@applitools/visual-grid-client": {
+ "version": "15.8.31",
+ "resolved": "https://registry.npmjs.org/@applitools/visual-grid-client/-/visual-grid-client-15.8.31.tgz",
+ "integrity": "sha512-DPkZ5ynlPcBKx8XMXGOtKjaxJkJs11Ui2SPRPwzGD4Soilq/ijcOfBbNBx89KC7TkntOVlInD/rZBIAfoElO/Q==",
+ "dev": true,
+ "requires": {
+ "@applitools/eyes-sdk-core": "12.23.12",
+ "@applitools/functional-commons": "1.6.0",
+ "@applitools/http-commons": "2.4.3",
+ "@applitools/isomorphic-fetch": "3.0.0",
+ "@applitools/jsdom": "1.0.3",
+ "abort-controller": "3.0.0",
+ "chalk": "3.0.0",
+ "he": "1.2.0",
+ "lodash.mapvalues": "4.6.0",
+ "mime-types": "2.1.27",
+ "mkdirp": "0.5.5",
+ "postcss-value-parser": "4.1.0",
+ "throat": "5.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "mime-db": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
+ "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.27",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
+ "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.44.0"
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.5"
+ }
+ },
+ "postcss-value-parser": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz",
+ "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@assemblyscript/loader": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.10.1.tgz",
+ "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==",
+ "dev": true
+ },
+ "@babel/code-frame": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+ "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+ "requires": {
+ "@babel/highlight": "^7.18.6"
+ }
+ },
+ "@babel/compat-data": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.0.tgz",
+ "integrity": "sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw==",
+ "dev": true
+ },
+ "@babel/core": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.3.tgz",
+ "integrity": "sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA==",
+ "requires": {
+ "@babel/code-frame": "^7.8.3",
+ "@babel/generator": "^7.8.3",
+ "@babel/helpers": "^7.8.3",
+ "@babel/parser": "^7.8.3",
+ "@babel/template": "^7.8.3",
+ "@babel/traverse": "^7.8.3",
+ "@babel/types": "^7.8.3",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.1",
+ "json5": "^2.1.0",
+ "lodash": "^4.17.13",
+ "resolve": "^1.3.2",
+ "semver": "^5.4.1",
+ "source-map": "^0.5.0"
+ }
+ },
+ "@babel/generator": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.0.tgz",
+ "integrity": "sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==",
+ "requires": {
+ "@babel/types": "^7.19.0",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "jsesc": "^2.5.1"
+ }
+ },
+ "@babel/helper-annotate-as-pure": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz",
+ "integrity": "sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.14.5"
+ }
+ },
+ "@babel/helper-builder-binary-assignment-operator-visitor": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz",
+ "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-explode-assignable-expression": "^7.18.6",
+ "@babel/types": "^7.18.9"
+ }
+ },
+ "@babel/helper-compilation-targets": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.0.tgz",
+ "integrity": "sha512-Ai5bNWXIvwDvWM7njqsG3feMlL9hCVQsPYXodsZyLwshYkZVJt59Gftau4VrE8S9IT9asd2uSP1hG6wCNw+sXA==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.19.0",
+ "@babel/helper-validator-option": "^7.18.6",
+ "browserslist": "^4.20.2",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/helper-create-class-features-plugin": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz",
+ "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.18.6",
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-function-name": "^7.19.0",
+ "@babel/helper-member-expression-to-functions": "^7.18.9",
+ "@babel/helper-optimise-call-expression": "^7.18.6",
+ "@babel/helper-replace-supers": "^7.18.9",
+ "@babel/helper-split-export-declaration": "^7.18.6"
+ },
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz",
+ "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ }
+ }
+ },
+ "@babel/helper-create-regexp-features-plugin": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz",
+ "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.18.6",
+ "regexpu-core": "^5.1.0"
+ },
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz",
+ "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ }
+ }
+ },
+ "@babel/helper-define-polyfill-provider": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.4.tgz",
+ "integrity": "sha512-OrpPZ97s+aPi6h2n1OXzdhVis1SGSsMU2aMHgLcOKfsp4/v1NWpx3CWT3lBj5eeBq9cDkPkh+YCfdF7O12uNDQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-compilation-targets": "^7.13.0",
+ "@babel/helper-module-imports": "^7.12.13",
+ "@babel/helper-plugin-utils": "^7.13.0",
+ "@babel/traverse": "^7.13.0",
+ "debug": "^4.1.1",
+ "lodash.debounce": "^4.0.8",
+ "resolve": "^1.14.2",
+ "semver": "^6.1.2"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/helper-environment-visitor": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
+ "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg=="
+ },
+ "@babel/helper-explode-assignable-expression": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz",
+ "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ },
+ "@babel/helper-function-name": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
+ "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
+ "requires": {
+ "@babel/template": "^7.18.10",
+ "@babel/types": "^7.19.0"
+ }
+ },
+ "@babel/helper-hoist-variables": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
+ "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ },
+ "@babel/helper-member-expression-to-functions": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz",
+ "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.9"
+ }
+ },
+ "@babel/helper-module-imports": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz",
+ "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ },
+ "@babel/helper-module-transforms": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz",
+ "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-module-imports": "^7.18.6",
+ "@babel/helper-simple-access": "^7.18.6",
+ "@babel/helper-split-export-declaration": "^7.18.6",
+ "@babel/helper-validator-identifier": "^7.18.6",
+ "@babel/template": "^7.18.10",
+ "@babel/traverse": "^7.19.0",
+ "@babel/types": "^7.19.0"
+ }
+ },
+ "@babel/helper-optimise-call-expression": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz",
+ "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ },
+ "@babel/helper-plugin-utils": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz",
+ "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==",
+ "dev": true
+ },
+ "@babel/helper-remap-async-to-generator": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz",
+ "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.18.6",
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-wrap-function": "^7.18.9",
+ "@babel/types": "^7.18.9"
+ },
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz",
+ "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ }
+ }
+ },
+ "@babel/helper-replace-supers": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz",
+ "integrity": "sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-member-expression-to-functions": "^7.18.9",
+ "@babel/helper-optimise-call-expression": "^7.18.6",
+ "@babel/traverse": "^7.18.9",
+ "@babel/types": "^7.18.9"
+ }
+ },
+ "@babel/helper-simple-access": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz",
+ "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ },
+ "@babel/helper-skip-transparent-expression-wrappers": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz",
+ "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.9"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
+ "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ },
+ "@babel/helper-string-parser": {
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz",
+ "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw=="
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz",
+ "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g=="
+ },
+ "@babel/helper-validator-option": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz",
+ "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==",
+ "dev": true
+ },
+ "@babel/helper-wrap-function": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz",
+ "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-function-name": "^7.19.0",
+ "@babel/template": "^7.18.10",
+ "@babel/traverse": "^7.19.0",
+ "@babel/types": "^7.19.0"
+ }
+ },
+ "@babel/helpers": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz",
+ "integrity": "sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==",
+ "requires": {
+ "@babel/template": "^7.18.10",
+ "@babel/traverse": "^7.19.0",
+ "@babel/types": "^7.19.0"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+ "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.18.6",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.0.tgz",
+ "integrity": "sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw=="
+ },
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz",
+ "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz",
+ "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9",
+ "@babel/plugin-proposal-optional-chaining": "^7.18.9"
+ }
+ },
+ "@babel/plugin-proposal-async-generator-functions": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.7.tgz",
+ "integrity": "sha512-RK8Wj7lXLY3bqei69/cc25gwS5puEc3dknoFPFbqfy3XxYQBQFvu4ioWpafMBAB+L9NyptQK4nMOa5Xz16og8Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-remap-async-to-generator": "^7.14.5",
+ "@babel/plugin-syntax-async-generators": "^7.8.4"
+ }
+ },
+ "@babel/plugin-proposal-class-properties": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz",
+ "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-class-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-proposal-class-static-block": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz",
+ "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-class-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5"
+ }
+ },
+ "@babel/plugin-proposal-dynamic-import": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz",
+ "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3"
+ }
+ },
+ "@babel/plugin-proposal-export-namespace-from": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz",
+ "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.9",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+ }
+ },
+ "@babel/plugin-proposal-json-strings": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz",
+ "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/plugin-syntax-json-strings": "^7.8.3"
+ }
+ },
+ "@babel/plugin-proposal-logical-assignment-operators": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz",
+ "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.9",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+ }
+ },
+ "@babel/plugin-proposal-nullish-coalescing-operator": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz",
+ "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
+ }
+ },
+ "@babel/plugin-proposal-numeric-separator": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz",
+ "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+ }
+ },
+ "@babel/plugin-proposal-object-rest-spread": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz",
+ "integrity": "sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.18.8",
+ "@babel/helper-compilation-targets": "^7.18.9",
+ "@babel/helper-plugin-utils": "^7.18.9",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-transform-parameters": "^7.18.8"
+ }
+ },
+ "@babel/plugin-proposal-optional-catch-binding": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz",
+ "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
+ }
+ },
+ "@babel/plugin-proposal-optional-chaining": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz",
+ "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+ }
+ },
+ "@babel/plugin-proposal-private-methods": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz",
+ "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-class-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-proposal-private-property-in-object": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz",
+ "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.18.6",
+ "@babel/helper-create-class-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
+ },
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz",
+ "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ }
+ }
+ },
+ "@babel/plugin-proposal-unicode-property-regex": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz",
+ "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-bigint": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+ "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ }
+ },
+ "@babel/plugin-syntax-class-static-block": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
+ "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ }
+ },
+ "@babel/plugin-syntax-dynamic-import": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+ "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-export-namespace-from": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
+ "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.3"
+ }
+ },
+ "@babel/plugin-syntax-import-assertions": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz",
+ "integrity": "sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-jsx": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz",
+ "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-private-property-in-object": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
+ "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ }
+ },
+ "@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ }
+ },
+ "@babel/plugin-transform-arrow-functions": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz",
+ "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-async-to-generator": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz",
+ "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-remap-async-to-generator": "^7.14.5"
+ }
+ },
+ "@babel/plugin-transform-block-scoped-functions": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz",
+ "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-block-scoping": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz",
+ "integrity": "sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.9"
+ }
+ },
+ "@babel/plugin-transform-classes": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz",
+ "integrity": "sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.18.6",
+ "@babel/helper-compilation-targets": "^7.19.0",
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-function-name": "^7.19.0",
+ "@babel/helper-optimise-call-expression": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.19.0",
+ "@babel/helper-replace-supers": "^7.18.9",
+ "@babel/helper-split-export-declaration": "^7.18.6",
+ "globals": "^11.1.0"
+ },
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz",
+ "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ }
+ }
+ },
+ "@babel/plugin-transform-computed-properties": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz",
+ "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.9"
+ }
+ },
+ "@babel/plugin-transform-destructuring": {
+ "version": "7.18.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz",
+ "integrity": "sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.9"
+ }
+ },
+ "@babel/plugin-transform-dotall-regex": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz",
+ "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-duplicate-keys": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz",
+ "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.9"
+ }
+ },
+ "@babel/plugin-transform-exponentiation-operator": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz",
+ "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-for-of": {
+ "version": "7.18.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz",
+ "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-function-name": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz",
+ "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-compilation-targets": "^7.18.9",
+ "@babel/helper-function-name": "^7.18.9",
+ "@babel/helper-plugin-utils": "^7.18.9"
+ }
+ },
+ "@babel/plugin-transform-literals": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz",
+ "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.9"
+ }
+ },
+ "@babel/plugin-transform-member-expression-literals": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz",
+ "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-modules-amd": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz",
+ "integrity": "sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-transforms": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ }
+ },
+ "@babel/plugin-transform-modules-commonjs": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz",
+ "integrity": "sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-transforms": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/helper-simple-access": "^7.18.6",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ }
+ },
+ "@babel/plugin-transform-modules-systemjs": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz",
+ "integrity": "sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-hoist-variables": "^7.18.6",
+ "@babel/helper-module-transforms": "^7.19.0",
+ "@babel/helper-plugin-utils": "^7.19.0",
+ "@babel/helper-validator-identifier": "^7.18.6",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ }
+ },
+ "@babel/plugin-transform-modules-umd": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz",
+ "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-transforms": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-named-capturing-groups-regex": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.0.tgz",
+ "integrity": "sha512-HDSuqOQzkU//kfGdiHBt71/hkDTApw4U/cMVgKgX7PqfB3LOaK+2GtCEsBu1dL9CkswDm0Gwehht1dCr421ULQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-regexp-features-plugin": "^7.19.0",
+ "@babel/helper-plugin-utils": "^7.19.0"
+ }
+ },
+ "@babel/plugin-transform-new-target": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz",
+ "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-object-super": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz",
+ "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/helper-replace-supers": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-parameters": {
+ "version": "7.18.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz",
+ "integrity": "sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-property-literals": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz",
+ "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-react-display-name": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz",
+ "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-react-jsx": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz",
+ "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.18.6",
+ "@babel/helper-module-imports": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.19.0",
+ "@babel/plugin-syntax-jsx": "^7.18.6",
+ "@babel/types": "^7.19.0"
+ },
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz",
+ "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ }
+ }
+ },
+ "@babel/plugin-transform-react-jsx-development": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz",
+ "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==",
+ "dev": true,
+ "requires": {
+ "@babel/plugin-transform-react-jsx": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-react-pure-annotations": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz",
+ "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz",
+ "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ }
+ }
+ },
+ "@babel/plugin-transform-regenerator": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz",
+ "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "regenerator-transform": "^0.15.0"
+ }
+ },
+ "@babel/plugin-transform-reserved-words": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz",
+ "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-runtime": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.14.5.tgz",
+ "integrity": "sha512-fPMBhh1AV8ZyneiCIA+wYYUH1arzlXR1UMcApjvchDhfKxhy2r2lReJv8uHEyihi4IFIGlr1Pdx7S5fkESDQsg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "babel-plugin-polyfill-corejs2": "^0.2.2",
+ "babel-plugin-polyfill-corejs3": "^0.2.2",
+ "babel-plugin-polyfill-regenerator": "^0.2.2",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/plugin-transform-shorthand-properties": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz",
+ "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-spread": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz",
+ "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.19.0",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9"
+ }
+ },
+ "@babel/plugin-transform-sticky-regex": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz",
+ "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-template-literals": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz",
+ "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.9"
+ }
+ },
+ "@babel/plugin-transform-typeof-symbol": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz",
+ "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.9"
+ }
+ },
+ "@babel/plugin-transform-unicode-escapes": {
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz",
+ "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.9"
+ }
+ },
+ "@babel/plugin-transform-unicode-regex": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz",
+ "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/preset-env": {
+ "version": "7.14.8",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.8.tgz",
+ "integrity": "sha512-a9aOppDU93oArQ51H+B8M1vH+tayZbuBqzjOhntGetZVa+4tTu5jp+XTwqHGG2lxslqomPYVSjIxQkFwXzgnxg==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.14.7",
+ "@babel/helper-compilation-targets": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-validator-option": "^7.14.5",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.14.5",
+ "@babel/plugin-proposal-async-generator-functions": "^7.14.7",
+ "@babel/plugin-proposal-class-properties": "^7.14.5",
+ "@babel/plugin-proposal-class-static-block": "^7.14.5",
+ "@babel/plugin-proposal-dynamic-import": "^7.14.5",
+ "@babel/plugin-proposal-export-namespace-from": "^7.14.5",
+ "@babel/plugin-proposal-json-strings": "^7.14.5",
+ "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5",
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5",
+ "@babel/plugin-proposal-numeric-separator": "^7.14.5",
+ "@babel/plugin-proposal-object-rest-spread": "^7.14.7",
+ "@babel/plugin-proposal-optional-catch-binding": "^7.14.5",
+ "@babel/plugin-proposal-optional-chaining": "^7.14.5",
+ "@babel/plugin-proposal-private-methods": "^7.14.5",
+ "@babel/plugin-proposal-private-property-in-object": "^7.14.5",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.14.5",
+ "@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-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-transform-arrow-functions": "^7.14.5",
+ "@babel/plugin-transform-async-to-generator": "^7.14.5",
+ "@babel/plugin-transform-block-scoped-functions": "^7.14.5",
+ "@babel/plugin-transform-block-scoping": "^7.14.5",
+ "@babel/plugin-transform-classes": "^7.14.5",
+ "@babel/plugin-transform-computed-properties": "^7.14.5",
+ "@babel/plugin-transform-destructuring": "^7.14.7",
+ "@babel/plugin-transform-dotall-regex": "^7.14.5",
+ "@babel/plugin-transform-duplicate-keys": "^7.14.5",
+ "@babel/plugin-transform-exponentiation-operator": "^7.14.5",
+ "@babel/plugin-transform-for-of": "^7.14.5",
+ "@babel/plugin-transform-function-name": "^7.14.5",
+ "@babel/plugin-transform-literals": "^7.14.5",
+ "@babel/plugin-transform-member-expression-literals": "^7.14.5",
+ "@babel/plugin-transform-modules-amd": "^7.14.5",
+ "@babel/plugin-transform-modules-commonjs": "^7.14.5",
+ "@babel/plugin-transform-modules-systemjs": "^7.14.5",
+ "@babel/plugin-transform-modules-umd": "^7.14.5",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.7",
+ "@babel/plugin-transform-new-target": "^7.14.5",
+ "@babel/plugin-transform-object-super": "^7.14.5",
+ "@babel/plugin-transform-parameters": "^7.14.5",
+ "@babel/plugin-transform-property-literals": "^7.14.5",
+ "@babel/plugin-transform-regenerator": "^7.14.5",
+ "@babel/plugin-transform-reserved-words": "^7.14.5",
+ "@babel/plugin-transform-shorthand-properties": "^7.14.5",
+ "@babel/plugin-transform-spread": "^7.14.6",
+ "@babel/plugin-transform-sticky-regex": "^7.14.5",
+ "@babel/plugin-transform-template-literals": "^7.14.5",
+ "@babel/plugin-transform-typeof-symbol": "^7.14.5",
+ "@babel/plugin-transform-unicode-escapes": "^7.14.5",
+ "@babel/plugin-transform-unicode-regex": "^7.14.5",
+ "@babel/preset-modules": "^0.1.4",
+ "@babel/types": "^7.14.8",
+ "babel-plugin-polyfill-corejs2": "^0.2.2",
+ "babel-plugin-polyfill-corejs3": "^0.2.2",
+ "babel-plugin-polyfill-regenerator": "^0.2.2",
+ "core-js-compat": "^3.15.0",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/preset-modules": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz",
+ "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
+ "@babel/plugin-transform-dotall-regex": "^7.4.4",
+ "@babel/types": "^7.4.4",
+ "esutils": "^2.0.2"
+ }
+ },
+ "@babel/preset-react": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz",
+ "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/helper-validator-option": "^7.18.6",
+ "@babel/plugin-transform-react-display-name": "^7.18.6",
+ "@babel/plugin-transform-react-jsx": "^7.18.6",
+ "@babel/plugin-transform-react-jsx-development": "^7.18.6",
+ "@babel/plugin-transform-react-pure-annotations": "^7.18.6"
+ }
+ },
+ "@babel/runtime": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz",
+ "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==",
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "@babel/runtime-corejs3": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.19.0.tgz",
+ "integrity": "sha512-JyXXoCu1N8GLuKc2ii8y5RGma5FMpFeO2nAQIe0Yzrbq+rQnN+sFj47auLblR5ka6aHNGPDgv8G/iI2Grb0ldQ==",
+ "requires": {
+ "core-js-pure": "^3.20.2",
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "@babel/template": {
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
+ "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==",
+ "requires": {
+ "@babel/code-frame": "^7.18.6",
+ "@babel/parser": "^7.18.10",
+ "@babel/types": "^7.18.10"
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.0.tgz",
+ "integrity": "sha512-4pKpFRDh+utd2mbRC8JLnlsMUii3PMHjpL6a0SZ4NMZy7YFP9aXORxEhdMVOc9CpWtDF09IkciQLEhK7Ml7gRA==",
+ "requires": {
+ "@babel/code-frame": "^7.18.6",
+ "@babel/generator": "^7.19.0",
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-function-name": "^7.19.0",
+ "@babel/helper-hoist-variables": "^7.18.6",
+ "@babel/helper-split-export-declaration": "^7.18.6",
+ "@babel/parser": "^7.19.0",
+ "@babel/types": "^7.19.0",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ }
+ },
+ "@babel/types": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.0.tgz",
+ "integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==",
+ "requires": {
+ "@babel/helper-string-parser": "^7.18.10",
+ "@babel/helper-validator-identifier": "^7.18.6",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true
+ },
+ "@braintree/sanitize-url": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.0.tgz",
+ "integrity": "sha512-mgmE7XBYY/21erpzhexk4Cj1cyTQ9LzvnTxtzM17BJ7ERMNE6W72mQRo0I1Ud8eFJ+RVVIcBNhLFZ3GX4XFz5w=="
+ },
+ "@circlon/angular-tree-component": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/@circlon/angular-tree-component/-/angular-tree-component-10.0.0.tgz",
+ "integrity": "sha512-3dRWLbOdMfIuvZjX6AMHmvzPtqhNFECMWMpNVXrZfZtTAa0n+Y4lxbuLST85q5QiedBZuC720p/7kkZ78PJ+iw==",
+ "requires": {
+ "lodash-es": "^4.17.15",
+ "mobx": "~4.14.1",
+ "tslib": "^2.0.0"
+ }
+ },
+ "@cnakazawa/watch": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz",
+ "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==",
+ "dev": true,
+ "requires": {
+ "exec-sh": "^0.3.2",
+ "minimist": "^1.2.0"
+ }
+ },
+ "@colors/colors": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
+ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
+ "dev": true,
+ "optional": true
+ },
+ "@compodoc/compodoc": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/@compodoc/compodoc/-/compodoc-1.1.15.tgz",
+ "integrity": "sha512-ek38uUSFR4SfH4ueJbV9zPn5bxaA21uSRPeeG2YQ602S0DgYl5QhJlXM2DlvZIqZ3Fuz0p1sd/v0f0ZnNrCDzA==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.15.5",
+ "@babel/preset-env": "^7.15.5",
+ "@compodoc/live-server": "^1.2.2",
+ "@compodoc/ngd-transformer": "^2.1.0",
+ "chalk": "^4.1.2",
+ "cheerio": "^1.0.0-rc.10",
+ "chokidar": "^3.5.2",
+ "colors": "^1.4.0",
+ "commander": "^8.2.0",
+ "cosmiconfig": "^7.0.1",
+ "decache": "^4.6.0",
+ "fancy-log": "^1.3.3",
+ "findit2": "^2.2.3",
+ "fs-extra": "^10.0.0",
+ "glob": "^7.1.7",
+ "handlebars": "^4.7.7",
+ "html-entities": "^2.3.2",
+ "i18next": "^20.6.1",
+ "inside": "^1.0.0",
+ "json5": "^2.2.0",
+ "lodash": "^4.17.21",
+ "loglevel": "^1.7.1",
+ "loglevel-plugin-prefix": "^0.8.4",
+ "lunr": "^2.3.9",
+ "marked": "^3.0.4",
+ "minimist": "^1.2.5",
+ "opencollective-postinstall": "^2.0.3",
+ "os-name": "4.0.1",
+ "pdfmake": "^0.2.2",
+ "semver": "^7.3.5",
+ "traverse": "^0.6.6",
+ "ts-morph": "^12.0.0",
+ "uuid": "^8.3.2"
+ },
+ "dependencies": {
+ "@ampproject/remapping": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
+ "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/gen-mapping": "^0.1.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@babel/core": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.0.tgz",
+ "integrity": "sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==",
+ "dev": true,
+ "requires": {
+ "@ampproject/remapping": "^2.1.0",
+ "@babel/code-frame": "^7.18.6",
+ "@babel/generator": "^7.19.0",
+ "@babel/helper-compilation-targets": "^7.19.0",
+ "@babel/helper-module-transforms": "^7.19.0",
+ "@babel/helpers": "^7.19.0",
+ "@babel/parser": "^7.19.0",
+ "@babel/template": "^7.18.10",
+ "@babel/traverse": "^7.19.0",
+ "@babel/types": "^7.19.0",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.1",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/helper-define-polyfill-provider": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.2.tgz",
+ "integrity": "sha512-r9QJJ+uDWrd+94BSPcP6/de67ygLtvVy6cK4luE6MOuDsZIdoaPBnfSpbO/+LTifjPckbKXRuI9BB/Z2/y3iTg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-compilation-targets": "^7.17.7",
+ "@babel/helper-plugin-utils": "^7.16.7",
+ "debug": "^4.1.1",
+ "lodash.debounce": "^4.0.8",
+ "resolve": "^1.14.2",
+ "semver": "^6.1.2"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/plugin-proposal-async-generator-functions": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.0.tgz",
+ "integrity": "sha512-nhEByMUTx3uZueJ/QkJuSlCfN4FGg+xy+vRsfGQGzSauq5ks2Deid2+05Q3KhfaUjvec1IGhw/Zm3cFm8JigTQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-plugin-utils": "^7.19.0",
+ "@babel/helper-remap-async-to-generator": "^7.18.9",
+ "@babel/plugin-syntax-async-generators": "^7.8.4"
+ }
+ },
+ "@babel/plugin-transform-async-to-generator": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz",
+ "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/helper-remap-async-to-generator": "^7.18.6"
+ }
+ },
+ "@babel/preset-env": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.0.tgz",
+ "integrity": "sha512-1YUju1TAFuzjIQqNM9WsF4U6VbD/8t3wEAlw3LFYuuEr+ywqLRcSXxFKz4DCEj+sN94l/XTDiUXYRrsvMpz9WQ==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.19.0",
+ "@babel/helper-compilation-targets": "^7.19.0",
+ "@babel/helper-plugin-utils": "^7.19.0",
+ "@babel/helper-validator-option": "^7.18.6",
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9",
+ "@babel/plugin-proposal-async-generator-functions": "^7.19.0",
+ "@babel/plugin-proposal-class-properties": "^7.18.6",
+ "@babel/plugin-proposal-class-static-block": "^7.18.6",
+ "@babel/plugin-proposal-dynamic-import": "^7.18.6",
+ "@babel/plugin-proposal-export-namespace-from": "^7.18.9",
+ "@babel/plugin-proposal-json-strings": "^7.18.6",
+ "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9",
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
+ "@babel/plugin-proposal-numeric-separator": "^7.18.6",
+ "@babel/plugin-proposal-object-rest-spread": "^7.18.9",
+ "@babel/plugin-proposal-optional-catch-binding": "^7.18.6",
+ "@babel/plugin-proposal-optional-chaining": "^7.18.9",
+ "@babel/plugin-proposal-private-methods": "^7.18.6",
+ "@babel/plugin-proposal-private-property-in-object": "^7.18.6",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.18.6",
+ "@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.18.6",
+ "@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-transform-arrow-functions": "^7.18.6",
+ "@babel/plugin-transform-async-to-generator": "^7.18.6",
+ "@babel/plugin-transform-block-scoped-functions": "^7.18.6",
+ "@babel/plugin-transform-block-scoping": "^7.18.9",
+ "@babel/plugin-transform-classes": "^7.19.0",
+ "@babel/plugin-transform-computed-properties": "^7.18.9",
+ "@babel/plugin-transform-destructuring": "^7.18.13",
+ "@babel/plugin-transform-dotall-regex": "^7.18.6",
+ "@babel/plugin-transform-duplicate-keys": "^7.18.9",
+ "@babel/plugin-transform-exponentiation-operator": "^7.18.6",
+ "@babel/plugin-transform-for-of": "^7.18.8",
+ "@babel/plugin-transform-function-name": "^7.18.9",
+ "@babel/plugin-transform-literals": "^7.18.9",
+ "@babel/plugin-transform-member-expression-literals": "^7.18.6",
+ "@babel/plugin-transform-modules-amd": "^7.18.6",
+ "@babel/plugin-transform-modules-commonjs": "^7.18.6",
+ "@babel/plugin-transform-modules-systemjs": "^7.19.0",
+ "@babel/plugin-transform-modules-umd": "^7.18.6",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.0",
+ "@babel/plugin-transform-new-target": "^7.18.6",
+ "@babel/plugin-transform-object-super": "^7.18.6",
+ "@babel/plugin-transform-parameters": "^7.18.8",
+ "@babel/plugin-transform-property-literals": "^7.18.6",
+ "@babel/plugin-transform-regenerator": "^7.18.6",
+ "@babel/plugin-transform-reserved-words": "^7.18.6",
+ "@babel/plugin-transform-shorthand-properties": "^7.18.6",
+ "@babel/plugin-transform-spread": "^7.19.0",
+ "@babel/plugin-transform-sticky-regex": "^7.18.6",
+ "@babel/plugin-transform-template-literals": "^7.18.9",
+ "@babel/plugin-transform-typeof-symbol": "^7.18.9",
+ "@babel/plugin-transform-unicode-escapes": "^7.18.10",
+ "@babel/plugin-transform-unicode-regex": "^7.18.6",
+ "@babel/preset-modules": "^0.1.5",
+ "@babel/types": "^7.19.0",
+ "babel-plugin-polyfill-corejs2": "^0.3.2",
+ "babel-plugin-polyfill-corejs3": "^0.5.3",
+ "babel-plugin-polyfill-regenerator": "^0.4.0",
+ "core-js-compat": "^3.22.1",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "@jridgewell/gen-mapping": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
+ "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.0",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "babel-plugin-polyfill-corejs2": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.2.tgz",
+ "integrity": "sha512-LPnodUl3lS0/4wN3Rb+m+UK8s7lj2jcLRrjho4gLw+OJs+I4bvGXshINesY5xx/apM+biTnQ9reDI8yj+0M5+Q==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.17.7",
+ "@babel/helper-define-polyfill-provider": "^0.3.2",
+ "semver": "^6.1.1"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "babel-plugin-polyfill-corejs3": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz",
+ "integrity": "sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-define-polyfill-provider": "^0.3.2",
+ "core-js-compat": "^3.21.0"
+ }
+ },
+ "babel-plugin-polyfill-regenerator": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.0.tgz",
+ "integrity": "sha512-RW1cnryiADFeHmfLS+WW/G431p1PsW5qdRdz0SDRi7TKcUgc7Oh/uXkT7MZ/+tGsT1BkczEAmD5XjUyJ5SWDTw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-define-polyfill-provider": "^0.3.2"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "commander": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+ "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "html-entities": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz",
+ "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==",
+ "dev": true
+ },
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@compodoc/live-server": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@compodoc/live-server/-/live-server-1.2.3.tgz",
+ "integrity": "sha512-hDmntVCyjjaxuJzPzBx68orNZ7TW4BtHWMnXlIVn5dqhK7vuFF/11hspO1cMmc+2QTYgqde1TBcb3127S7Zrow==",
+ "dev": true,
+ "requires": {
+ "chokidar": "^3.5.2",
+ "colors": "1.4.0",
+ "connect": "^3.7.0",
+ "cors": "^2.8.5",
+ "event-stream": "4.0.1",
+ "faye-websocket": "0.11.x",
+ "http-auth": "4.1.9",
+ "http-auth-connect": "^1.0.5",
+ "morgan": "^1.10.0",
+ "object-assign": "^4.1.1",
+ "open": "8.4.0",
+ "proxy-middleware": "^0.15.0",
+ "send": "^0.18.0",
+ "serve-index": "^1.9.1"
+ },
+ "dependencies": {
+ "cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "dev": true,
+ "requires": {
+ "object-assign": "^4",
+ "vary": "^1"
+ }
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ }
+ }
+ },
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "dev": true
+ },
+ "open": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz",
+ "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==",
+ "dev": true,
+ "requires": {
+ "define-lazy-prop": "^2.0.0",
+ "is-docker": "^2.1.1",
+ "is-wsl": "^2.2.0"
+ }
+ },
+ "send": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
+ "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ }
+ }
+ },
+ "@compodoc/ngd-core": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@compodoc/ngd-core/-/ngd-core-2.1.0.tgz",
+ "integrity": "sha512-nyBH7J7SJJ2AV6OeZhJ02kRtVB7ALnZJKgShjoL9CNmOFEj8AkdhP9qTBIgjaDrbsW5pF4nx32KQL2fT7RFnqw==",
+ "dev": true,
+ "requires": {
+ "ansi-colors": "^4.1.1",
+ "fancy-log": "^1.3.3",
+ "typescript": "^4.0.3"
+ }
+ },
+ "@compodoc/ngd-transformer": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@compodoc/ngd-transformer/-/ngd-transformer-2.1.0.tgz",
+ "integrity": "sha512-Jo4VCMzIUtgIAdRmhHhOoRRE01gCjc5CyrUERRx0VgEzkkCm1Wmu/XHSsQP6tSpCYHBjERghqaDqH5DabkR2oQ==",
+ "dev": true,
+ "requires": {
+ "@aduh95/viz.js": "^3.1.0",
+ "@compodoc/ngd-core": "~2.1.0",
+ "dot": "^1.1.3",
+ "fs-extra": "^9.0.1"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+ "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+ "dev": true,
+ "requires": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ }
+ }
+ }
+ },
+ "@csstools/convert-colors": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz",
+ "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==",
+ "dev": true
+ },
+ "@cypress/browserify-preprocessor": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@cypress/browserify-preprocessor/-/browserify-preprocessor-3.0.2.tgz",
+ "integrity": "sha512-y6mlFR+IR2cqcm3HabSp7AEcX9QfF1EUL4eOaw/7xexdhmdQU8ez6piyRopZQob4BK8oKTsc9PkupsU2rzjqMA==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.16.0",
+ "@babel/plugin-proposal-class-properties": "^7.16.0",
+ "@babel/plugin-proposal-object-rest-spread": "^7.16.0",
+ "@babel/plugin-transform-runtime": "^7.16.0",
+ "@babel/preset-env": "^7.16.0",
+ "@babel/preset-react": "^7.16.0",
+ "@babel/runtime": "^7.16.0",
+ "babel-plugin-add-module-exports": "^1.0.4",
+ "babelify": "^10.0.0",
+ "bluebird": "^3.7.2",
+ "browserify": "^16.2.3",
+ "coffeeify": "^3.0.1",
+ "coffeescript": "^1.12.7",
+ "debug": "^4.3.2",
+ "fs-extra": "^9.0.0",
+ "lodash.clonedeep": "^4.5.0",
+ "through2": "^2.0.0",
+ "watchify": "^4.0.0"
+ },
+ "dependencies": {
+ "@ampproject/remapping": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
+ "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/gen-mapping": "^0.1.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@babel/core": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.0.tgz",
+ "integrity": "sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==",
+ "dev": true,
+ "requires": {
+ "@ampproject/remapping": "^2.1.0",
+ "@babel/code-frame": "^7.18.6",
+ "@babel/generator": "^7.19.0",
+ "@babel/helper-compilation-targets": "^7.19.0",
+ "@babel/helper-module-transforms": "^7.19.0",
+ "@babel/helpers": "^7.19.0",
+ "@babel/parser": "^7.19.0",
+ "@babel/template": "^7.18.10",
+ "@babel/traverse": "^7.19.0",
+ "@babel/types": "^7.19.0",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.1",
+ "semver": "^6.3.0"
+ }
+ },
+ "@babel/helper-define-polyfill-provider": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.2.tgz",
+ "integrity": "sha512-r9QJJ+uDWrd+94BSPcP6/de67ygLtvVy6cK4luE6MOuDsZIdoaPBnfSpbO/+LTifjPckbKXRuI9BB/Z2/y3iTg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-compilation-targets": "^7.17.7",
+ "@babel/helper-plugin-utils": "^7.16.7",
+ "debug": "^4.1.1",
+ "lodash.debounce": "^4.0.8",
+ "resolve": "^1.14.2",
+ "semver": "^6.1.2"
+ }
+ },
+ "@babel/plugin-proposal-async-generator-functions": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.0.tgz",
+ "integrity": "sha512-nhEByMUTx3uZueJ/QkJuSlCfN4FGg+xy+vRsfGQGzSauq5ks2Deid2+05Q3KhfaUjvec1IGhw/Zm3cFm8JigTQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-plugin-utils": "^7.19.0",
+ "@babel/helper-remap-async-to-generator": "^7.18.9",
+ "@babel/plugin-syntax-async-generators": "^7.8.4"
+ }
+ },
+ "@babel/plugin-transform-async-to-generator": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz",
+ "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/helper-remap-async-to-generator": "^7.18.6"
+ }
+ },
+ "@babel/plugin-transform-runtime": {
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.10.tgz",
+ "integrity": "sha512-q5mMeYAdfEbpBAgzl7tBre/la3LeCxmDO1+wMXRdPWbcoMjR3GiXlCLk7JBZVVye0bqTGNMbt0yYVXX1B1jEWQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.9",
+ "babel-plugin-polyfill-corejs2": "^0.3.2",
+ "babel-plugin-polyfill-corejs3": "^0.5.3",
+ "babel-plugin-polyfill-regenerator": "^0.4.0",
+ "semver": "^6.3.0"
+ }
+ },
+ "@babel/preset-env": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.0.tgz",
+ "integrity": "sha512-1YUju1TAFuzjIQqNM9WsF4U6VbD/8t3wEAlw3LFYuuEr+ywqLRcSXxFKz4DCEj+sN94l/XTDiUXYRrsvMpz9WQ==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.19.0",
+ "@babel/helper-compilation-targets": "^7.19.0",
+ "@babel/helper-plugin-utils": "^7.19.0",
+ "@babel/helper-validator-option": "^7.18.6",
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9",
+ "@babel/plugin-proposal-async-generator-functions": "^7.19.0",
+ "@babel/plugin-proposal-class-properties": "^7.18.6",
+ "@babel/plugin-proposal-class-static-block": "^7.18.6",
+ "@babel/plugin-proposal-dynamic-import": "^7.18.6",
+ "@babel/plugin-proposal-export-namespace-from": "^7.18.9",
+ "@babel/plugin-proposal-json-strings": "^7.18.6",
+ "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9",
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
+ "@babel/plugin-proposal-numeric-separator": "^7.18.6",
+ "@babel/plugin-proposal-object-rest-spread": "^7.18.9",
+ "@babel/plugin-proposal-optional-catch-binding": "^7.18.6",
+ "@babel/plugin-proposal-optional-chaining": "^7.18.9",
+ "@babel/plugin-proposal-private-methods": "^7.18.6",
+ "@babel/plugin-proposal-private-property-in-object": "^7.18.6",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.18.6",
+ "@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.18.6",
+ "@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-transform-arrow-functions": "^7.18.6",
+ "@babel/plugin-transform-async-to-generator": "^7.18.6",
+ "@babel/plugin-transform-block-scoped-functions": "^7.18.6",
+ "@babel/plugin-transform-block-scoping": "^7.18.9",
+ "@babel/plugin-transform-classes": "^7.19.0",
+ "@babel/plugin-transform-computed-properties": "^7.18.9",
+ "@babel/plugin-transform-destructuring": "^7.18.13",
+ "@babel/plugin-transform-dotall-regex": "^7.18.6",
+ "@babel/plugin-transform-duplicate-keys": "^7.18.9",
+ "@babel/plugin-transform-exponentiation-operator": "^7.18.6",
+ "@babel/plugin-transform-for-of": "^7.18.8",
+ "@babel/plugin-transform-function-name": "^7.18.9",
+ "@babel/plugin-transform-literals": "^7.18.9",
+ "@babel/plugin-transform-member-expression-literals": "^7.18.6",
+ "@babel/plugin-transform-modules-amd": "^7.18.6",
+ "@babel/plugin-transform-modules-commonjs": "^7.18.6",
+ "@babel/plugin-transform-modules-systemjs": "^7.19.0",
+ "@babel/plugin-transform-modules-umd": "^7.18.6",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.0",
+ "@babel/plugin-transform-new-target": "^7.18.6",
+ "@babel/plugin-transform-object-super": "^7.18.6",
+ "@babel/plugin-transform-parameters": "^7.18.8",
+ "@babel/plugin-transform-property-literals": "^7.18.6",
+ "@babel/plugin-transform-regenerator": "^7.18.6",
+ "@babel/plugin-transform-reserved-words": "^7.18.6",
+ "@babel/plugin-transform-shorthand-properties": "^7.18.6",
+ "@babel/plugin-transform-spread": "^7.19.0",
+ "@babel/plugin-transform-sticky-regex": "^7.18.6",
+ "@babel/plugin-transform-template-literals": "^7.18.9",
+ "@babel/plugin-transform-typeof-symbol": "^7.18.9",
+ "@babel/plugin-transform-unicode-escapes": "^7.18.10",
+ "@babel/plugin-transform-unicode-regex": "^7.18.6",
+ "@babel/preset-modules": "^0.1.5",
+ "@babel/types": "^7.19.0",
+ "babel-plugin-polyfill-corejs2": "^0.3.2",
+ "babel-plugin-polyfill-corejs3": "^0.5.3",
+ "babel-plugin-polyfill-regenerator": "^0.4.0",
+ "core-js-compat": "^3.22.1",
+ "semver": "^6.3.0"
+ }
+ },
+ "@jridgewell/gen-mapping": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
+ "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.0",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "babel-plugin-polyfill-corejs2": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.2.tgz",
+ "integrity": "sha512-LPnodUl3lS0/4wN3Rb+m+UK8s7lj2jcLRrjho4gLw+OJs+I4bvGXshINesY5xx/apM+biTnQ9reDI8yj+0M5+Q==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.17.7",
+ "@babel/helper-define-polyfill-provider": "^0.3.2",
+ "semver": "^6.1.1"
+ }
+ },
+ "babel-plugin-polyfill-corejs3": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz",
+ "integrity": "sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-define-polyfill-provider": "^0.3.2",
+ "core-js-compat": "^3.21.0"
+ }
+ },
+ "babel-plugin-polyfill-regenerator": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.0.tgz",
+ "integrity": "sha512-RW1cnryiADFeHmfLS+WW/G431p1PsW5qdRdz0SDRi7TKcUgc7Oh/uXkT7MZ/+tGsT1BkczEAmD5XjUyJ5SWDTw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-define-polyfill-provider": "^0.3.2"
+ }
+ },
+ "fs-extra": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+ "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+ "dev": true,
+ "requires": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "@cypress/request": {
+ "version": "2.88.10",
+ "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.10.tgz",
+ "integrity": "sha512-Zp7F+R93N0yZyG34GutyTNr+okam7s/Fzc1+i3kcqOP8vk6OuajuE9qZJ6Rs+10/1JFtXFYMdyarnU1rZuJesg==",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "http-signature": "~1.3.6",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.5.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^8.3.2"
+ },
+ "dependencies": {
+ "http-signature": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz",
+ "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^2.0.2",
+ "sshpk": "^1.14.1"
+ }
+ },
+ "jsprim": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz",
+ "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.4.0",
+ "verror": "1.10.0"
+ }
+ },
+ "qs": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
+ "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
+ "dev": true
+ }
+ }
+ },
+ "@cypress/webpack-preprocessor": {
+ "version": "5.11.0",
+ "resolved": "https://registry.npmjs.org/@cypress/webpack-preprocessor/-/webpack-preprocessor-5.11.0.tgz",
+ "integrity": "sha512-0VMEodVAOkYYhCGKQ2wilI28RtISc3rCre9wlFhishwtnT0B1onJJ8fwhWmcT3Y2/K88WP+cyVO2ZaQPcsEFQg==",
+ "dev": true,
+ "requires": {
+ "bluebird": "3.7.1",
+ "debug": "^4.3.2",
+ "lodash": "^4.17.20"
+ },
+ "dependencies": {
+ "bluebird": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz",
+ "integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==",
+ "dev": true
+ }
+ }
+ },
+ "@cypress/xvfb": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz",
+ "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==",
+ "dev": true,
+ "requires": {
+ "debug": "^3.1.0",
+ "lodash.once": "^4.1.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "@discoveryjs/json-ext": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz",
+ "integrity": "sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==",
+ "dev": true
+ },
+ "@foliojs-fork/fontkit": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/@foliojs-fork/fontkit/-/fontkit-1.9.1.tgz",
+ "integrity": "sha512-U589voc2/ROnvx1CyH9aNzOQWJp127JGU1QAylXGQ7LoEAF6hMmahZLQ4eqAcgHUw+uyW4PjtCItq9qudPkK3A==",
+ "dev": true,
+ "requires": {
+ "@foliojs-fork/restructure": "^2.0.2",
+ "brfs": "^2.0.0",
+ "brotli": "^1.2.0",
+ "browserify-optional": "^1.0.1",
+ "clone": "^1.0.4",
+ "deep-equal": "^1.0.0",
+ "dfa": "^1.2.0",
+ "tiny-inflate": "^1.0.2",
+ "unicode-properties": "^1.2.2",
+ "unicode-trie": "^2.0.0"
+ }
+ },
+ "@foliojs-fork/linebreak": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@foliojs-fork/linebreak/-/linebreak-1.1.1.tgz",
+ "integrity": "sha512-pgY/+53GqGQI+mvDiyprvPWgkTlVBS8cxqee03ejm6gKAQNsR1tCYCIvN9FHy7otZajzMqCgPOgC4cHdt4JPig==",
+ "dev": true,
+ "requires": {
+ "base64-js": "1.3.1",
+ "brfs": "^2.0.2",
+ "unicode-trie": "^2.0.0"
+ },
+ "dependencies": {
+ "base64-js": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
+ "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
+ "dev": true
+ }
+ }
+ },
+ "@foliojs-fork/pdfkit": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@foliojs-fork/pdfkit/-/pdfkit-0.13.0.tgz",
+ "integrity": "sha512-YXeG1fml9k97YNC9K8e292Pj2JzGt9uOIiBFuQFxHsdQ45BlxW+JU3RQK6JAvXU7kjhjP8rCcYvpk36JLD33sQ==",
+ "dev": true,
+ "requires": {
+ "@foliojs-fork/fontkit": "^1.9.1",
+ "@foliojs-fork/linebreak": "^1.1.1",
+ "crypto-js": "^4.0.0",
+ "png-js": "^1.0.0"
+ }
+ },
+ "@foliojs-fork/restructure": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@foliojs-fork/restructure/-/restructure-2.0.2.tgz",
+ "integrity": "sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA==",
+ "dev": true
+ },
+ "@grafana/e2e": {
+ "version": "8.4.5",
+ "resolved": "https://registry.npmjs.org/@grafana/e2e/-/e2e-8.4.5.tgz",
+ "integrity": "sha512-3UTxH0CdXqQkuuW4UvNG60R7yQGgD/27VWqVks5+nEuo+DxWrAgzHbxdvks8C1Hm/EUUhmwj5GkaU/9AN74pWQ==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "7.16.7",
+ "@babel/preset-env": "7.16.7",
+ "@cypress/webpack-preprocessor": "5.11.0",
+ "@grafana/e2e-selectors": "8.4.5",
+ "@grafana/tsconfig": "^1.0.0-rc1",
+ "@mochajs/json-file-reporter": "^1.2.0",
+ "babel-loader": "8.2.3",
+ "blink-diff": "1.0.13",
+ "chrome-remote-interface": "0.31.1",
+ "commander": "8.3.0",
+ "cypress": "9.3.1",
+ "cypress-file-upload": "5.0.8",
+ "devtools-protocol": "0.0.927104",
+ "execa": "5.1.1",
+ "lodash": "4.17.21",
+ "mocha": "9.2.0",
+ "resolve-as-bin": "2.1.0",
+ "rimraf": "3.0.2",
+ "tracelib": "1.0.1",
+ "ts-loader": "6.2.1",
+ "tslib": "2.3.1",
+ "typescript": "4.4.4",
+ "uuid": "8.3.2",
+ "yaml": "^1.8.3"
+ },
+ "dependencies": {
+ "@babel/core": {
+ "version": "7.16.7",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.7.tgz",
+ "integrity": "sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.16.7",
+ "@babel/generator": "^7.16.7",
+ "@babel/helper-compilation-targets": "^7.16.7",
+ "@babel/helper-module-transforms": "^7.16.7",
+ "@babel/helpers": "^7.16.7",
+ "@babel/parser": "^7.16.7",
+ "@babel/template": "^7.16.7",
+ "@babel/traverse": "^7.16.7",
+ "@babel/types": "^7.16.7",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.1.2",
+ "semver": "^6.3.0",
+ "source-map": "^0.5.0"
+ }
+ },
+ "@babel/helper-define-polyfill-provider": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.2.tgz",
+ "integrity": "sha512-r9QJJ+uDWrd+94BSPcP6/de67ygLtvVy6cK4luE6MOuDsZIdoaPBnfSpbO/+LTifjPckbKXRuI9BB/Z2/y3iTg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-compilation-targets": "^7.17.7",
+ "@babel/helper-plugin-utils": "^7.16.7",
+ "debug": "^4.1.1",
+ "lodash.debounce": "^4.0.8",
+ "resolve": "^1.14.2",
+ "semver": "^6.1.2"
+ }
+ },
+ "@babel/plugin-proposal-async-generator-functions": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.0.tgz",
+ "integrity": "sha512-nhEByMUTx3uZueJ/QkJuSlCfN4FGg+xy+vRsfGQGzSauq5ks2Deid2+05Q3KhfaUjvec1IGhw/Zm3cFm8JigTQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-plugin-utils": "^7.19.0",
+ "@babel/helper-remap-async-to-generator": "^7.18.9",
+ "@babel/plugin-syntax-async-generators": "^7.8.4"
+ }
+ },
+ "@babel/plugin-transform-async-to-generator": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz",
+ "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/helper-remap-async-to-generator": "^7.18.6"
+ }
+ },
+ "@babel/preset-env": {
+ "version": "7.16.7",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.7.tgz",
+ "integrity": "sha512-urX3Cee4aOZbRWOSa3mKPk0aqDikfILuo+C7qq7HY0InylGNZ1fekq9jmlr3pLWwZHF4yD7heQooc2Pow2KMyQ==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.16.4",
+ "@babel/helper-compilation-targets": "^7.16.7",
+ "@babel/helper-plugin-utils": "^7.16.7",
+ "@babel/helper-validator-option": "^7.16.7",
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.7",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.7",
+ "@babel/plugin-proposal-async-generator-functions": "^7.16.7",
+ "@babel/plugin-proposal-class-properties": "^7.16.7",
+ "@babel/plugin-proposal-class-static-block": "^7.16.7",
+ "@babel/plugin-proposal-dynamic-import": "^7.16.7",
+ "@babel/plugin-proposal-export-namespace-from": "^7.16.7",
+ "@babel/plugin-proposal-json-strings": "^7.16.7",
+ "@babel/plugin-proposal-logical-assignment-operators": "^7.16.7",
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7",
+ "@babel/plugin-proposal-numeric-separator": "^7.16.7",
+ "@babel/plugin-proposal-object-rest-spread": "^7.16.7",
+ "@babel/plugin-proposal-optional-catch-binding": "^7.16.7",
+ "@babel/plugin-proposal-optional-chaining": "^7.16.7",
+ "@babel/plugin-proposal-private-methods": "^7.16.7",
+ "@babel/plugin-proposal-private-property-in-object": "^7.16.7",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.16.7",
+ "@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-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-transform-arrow-functions": "^7.16.7",
+ "@babel/plugin-transform-async-to-generator": "^7.16.7",
+ "@babel/plugin-transform-block-scoped-functions": "^7.16.7",
+ "@babel/plugin-transform-block-scoping": "^7.16.7",
+ "@babel/plugin-transform-classes": "^7.16.7",
+ "@babel/plugin-transform-computed-properties": "^7.16.7",
+ "@babel/plugin-transform-destructuring": "^7.16.7",
+ "@babel/plugin-transform-dotall-regex": "^7.16.7",
+ "@babel/plugin-transform-duplicate-keys": "^7.16.7",
+ "@babel/plugin-transform-exponentiation-operator": "^7.16.7",
+ "@babel/plugin-transform-for-of": "^7.16.7",
+ "@babel/plugin-transform-function-name": "^7.16.7",
+ "@babel/plugin-transform-literals": "^7.16.7",
+ "@babel/plugin-transform-member-expression-literals": "^7.16.7",
+ "@babel/plugin-transform-modules-amd": "^7.16.7",
+ "@babel/plugin-transform-modules-commonjs": "^7.16.7",
+ "@babel/plugin-transform-modules-systemjs": "^7.16.7",
+ "@babel/plugin-transform-modules-umd": "^7.16.7",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.7",
+ "@babel/plugin-transform-new-target": "^7.16.7",
+ "@babel/plugin-transform-object-super": "^7.16.7",
+ "@babel/plugin-transform-parameters": "^7.16.7",
+ "@babel/plugin-transform-property-literals": "^7.16.7",
+ "@babel/plugin-transform-regenerator": "^7.16.7",
+ "@babel/plugin-transform-reserved-words": "^7.16.7",
+ "@babel/plugin-transform-shorthand-properties": "^7.16.7",
+ "@babel/plugin-transform-spread": "^7.16.7",
+ "@babel/plugin-transform-sticky-regex": "^7.16.7",
+ "@babel/plugin-transform-template-literals": "^7.16.7",
+ "@babel/plugin-transform-typeof-symbol": "^7.16.7",
+ "@babel/plugin-transform-unicode-escapes": "^7.16.7",
+ "@babel/plugin-transform-unicode-regex": "^7.16.7",
+ "@babel/preset-modules": "^0.1.5",
+ "@babel/types": "^7.16.7",
+ "babel-plugin-polyfill-corejs2": "^0.3.0",
+ "babel-plugin-polyfill-corejs3": "^0.4.0",
+ "babel-plugin-polyfill-regenerator": "^0.3.0",
+ "core-js-compat": "^3.19.1",
+ "semver": "^6.3.0"
+ }
+ },
+ "@types/node": {
+ "version": "14.18.28",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.28.tgz",
+ "integrity": "sha512-CK2fnrQlIgKlCV3N2kM+Gznb5USlwA1KFX3rJVHmgVk6NJxFPuQ86pAcvKnu37IA4BGlSRz7sEE1lHL1aLZ/eQ==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "babel-loader": {
+ "version": "8.2.3",
+ "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.3.tgz",
+ "integrity": "sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw==",
+ "dev": true,
+ "requires": {
+ "find-cache-dir": "^3.3.1",
+ "loader-utils": "^1.4.0",
+ "make-dir": "^3.1.0",
+ "schema-utils": "^2.6.5"
+ }
+ },
+ "babel-plugin-polyfill-corejs2": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.2.tgz",
+ "integrity": "sha512-LPnodUl3lS0/4wN3Rb+m+UK8s7lj2jcLRrjho4gLw+OJs+I4bvGXshINesY5xx/apM+biTnQ9reDI8yj+0M5+Q==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.17.7",
+ "@babel/helper-define-polyfill-provider": "^0.3.2",
+ "semver": "^6.1.1"
+ }
+ },
+ "babel-plugin-polyfill-corejs3": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz",
+ "integrity": "sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-define-polyfill-provider": "^0.3.0",
+ "core-js-compat": "^3.18.0"
+ }
+ },
+ "babel-plugin-polyfill-regenerator": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz",
+ "integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-define-polyfill-provider": "^0.3.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "commander": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+ "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "cypress": {
+ "version": "9.3.1",
+ "resolved": "https://registry.npmjs.org/cypress/-/cypress-9.3.1.tgz",
+ "integrity": "sha512-BODdPesxX6bkVUnH8BVsV8I/jn57zQtO1FEOUTiuG2us3kslW7g0tcuwiny7CKCmJUZz8S/D587ppC+s58a+5Q==",
+ "dev": true,
+ "requires": {
+ "@cypress/request": "^2.88.10",
+ "@cypress/xvfb": "^1.2.4",
+ "@types/node": "^14.14.31",
+ "@types/sinonjs__fake-timers": "8.1.1",
+ "@types/sizzle": "^2.3.2",
+ "arch": "^2.2.0",
+ "blob-util": "^2.0.2",
+ "bluebird": "^3.7.2",
+ "buffer": "^5.6.0",
+ "cachedir": "^2.3.0",
+ "chalk": "^4.1.0",
+ "check-more-types": "^2.24.0",
+ "cli-cursor": "^3.1.0",
+ "cli-table3": "~0.6.1",
+ "commander": "^5.1.0",
+ "common-tags": "^1.8.0",
+ "dayjs": "^1.10.4",
+ "debug": "^4.3.2",
+ "enquirer": "^2.3.6",
+ "eventemitter2": "^6.4.3",
+ "execa": "4.1.0",
+ "executable": "^4.1.1",
+ "extract-zip": "2.0.1",
+ "figures": "^3.2.0",
+ "fs-extra": "^9.1.0",
+ "getos": "^3.2.1",
+ "is-ci": "^3.0.0",
+ "is-installed-globally": "~0.4.0",
+ "lazy-ass": "^1.6.0",
+ "listr2": "^3.8.3",
+ "lodash": "^4.17.21",
+ "log-symbols": "^4.0.0",
+ "minimist": "^1.2.5",
+ "ospath": "^1.2.2",
+ "pretty-bytes": "^5.6.0",
+ "proxy-from-env": "1.0.0",
+ "request-progress": "^3.0.0",
+ "supports-color": "^8.1.1",
+ "tmp": "~0.2.1",
+ "untildify": "^4.0.0",
+ "url": "^0.11.0",
+ "yauzl": "^2.10.0"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
+ "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
+ "dev": true
+ },
+ "execa": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
+ "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.0",
+ "get-stream": "^5.0.0",
+ "human-signals": "^1.1.1",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.0",
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2",
+ "strip-final-newline": "^2.0.0"
+ }
+ }
+ }
+ },
+ "execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
+ "requires": {
+ "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"
+ },
+ "dependencies": {
+ "get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true
+ },
+ "human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true
+ }
+ }
+ },
+ "fs-extra": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+ "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+ "dev": true,
+ "requires": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true
+ },
+ "loader-utils": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+ "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+ "dev": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^1.0.1"
+ },
+ "dependencies": {
+ "json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ }
+ }
+ },
+ "npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.0.0"
+ }
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "tmp": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
+ "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
+ "dev": true,
+ "requires": {
+ "rimraf": "^3.0.0"
+ }
+ },
+ "typescript": {
+ "version": "4.4.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz",
+ "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==",
+ "dev": true
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "@grafana/e2e-selectors": {
+ "version": "8.4.5",
+ "resolved": "https://registry.npmjs.org/@grafana/e2e-selectors/-/e2e-selectors-8.4.5.tgz",
+ "integrity": "sha512-sfdafy76s5nCtrkyCMv8v2QMJTsypWFad5BHF4zL4nHbYEhhpZPbky13RufiqBImFeIWLM9Zmz7LDFFJVBhFtA==",
+ "dev": true,
+ "requires": {
+ "@grafana/tsconfig": "^1.0.0-rc1",
+ "tslib": "2.3.1",
+ "typescript": "4.4.4"
+ },
+ "dependencies": {
+ "typescript": {
+ "version": "4.4.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz",
+ "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==",
+ "dev": true
+ }
+ }
+ },
+ "@grafana/tsconfig": {
+ "version": "1.0.0-rc1",
+ "resolved": "https://registry.npmjs.org/@grafana/tsconfig/-/tsconfig-1.0.0-rc1.tgz",
+ "integrity": "sha512-nucKPGyzlSKYSiJk5RA8GzMdVWhdYNdF+Hh65AXxjD9PlY69JKr5wANj8bVdQboag6dgg0BFKqgKPyY+YtV4Iw==",
+ "dev": true
+ },
+ "@hapi/hoek": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
+ "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==",
+ "dev": true
+ },
+ "@hapi/topo": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
+ "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
+ "dev": true,
+ "requires": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
+ },
+ "dependencies": {
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true
+ }
+ }
+ },
+ "@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true
+ },
+ "@jest/console": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz",
+ "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "jest-message-util": "^26.6.2",
+ "jest-util": "^26.6.2",
+ "slash": "^3.0.0"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@jest/core": {
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz",
+ "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^26.6.2",
+ "@jest/reporters": "^26.6.2",
+ "@jest/test-result": "^26.6.2",
+ "@jest/transform": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.4",
+ "jest-changed-files": "^26.6.2",
+ "jest-config": "^26.6.3",
+ "jest-haste-map": "^26.6.2",
+ "jest-message-util": "^26.6.2",
+ "jest-regex-util": "^26.0.0",
+ "jest-resolve": "^26.6.2",
+ "jest-resolve-dependencies": "^26.6.3",
+ "jest-runner": "^26.6.3",
+ "jest-runtime": "^26.6.3",
+ "jest-snapshot": "^26.6.2",
+ "jest-util": "^26.6.2",
+ "jest-validate": "^26.6.2",
+ "jest-watcher": "^26.6.2",
+ "micromatch": "^4.0.2",
+ "p-each-series": "^2.1.0",
+ "rimraf": "^3.0.0",
+ "slash": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@jest/environment": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz",
+ "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==",
+ "dev": true,
+ "requires": {
+ "@jest/fake-timers": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
+ "jest-mock": "^26.6.2"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@jest/fake-timers": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz",
+ "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "@sinonjs/fake-timers": "^6.0.1",
+ "@types/node": "*",
+ "jest-message-util": "^26.6.2",
+ "jest-mock": "^26.6.2",
+ "jest-util": "^26.6.2"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@jest/globals": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz",
+ "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "expect": "^26.6.2"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@jest/reporters": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz",
+ "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==",
+ "dev": true,
+ "requires": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@jest/console": "^26.6.2",
+ "@jest/test-result": "^26.6.2",
+ "@jest/transform": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "chalk": "^4.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "exit": "^0.1.2",
+ "glob": "^7.1.2",
+ "graceful-fs": "^4.2.4",
+ "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-instrument": "^4.0.3",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-lib-source-maps": "^4.0.0",
+ "istanbul-reports": "^3.0.2",
+ "jest-haste-map": "^26.6.2",
+ "jest-resolve": "^26.6.2",
+ "jest-util": "^26.6.2",
+ "jest-worker": "^26.6.2",
+ "node-notifier": "^8.0.0",
+ "slash": "^3.0.0",
+ "source-map": "^0.6.0",
+ "string-length": "^4.0.1",
+ "terminal-link": "^2.0.0",
+ "v8-to-istanbul": "^7.0.0"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "jest-worker": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
+ "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^7.0.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@jest/source-map": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz",
+ "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0",
+ "graceful-fs": "^4.2.4",
+ "source-map": "^0.6.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "@jest/test-result": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz",
+ "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "collect-v8-coverage": "^1.0.0"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@jest/test-sequencer": {
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz",
+ "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==",
+ "dev": true,
+ "requires": {
+ "@jest/test-result": "^26.6.2",
+ "graceful-fs": "^4.2.4",
+ "jest-haste-map": "^26.6.2",
+ "jest-runner": "^26.6.3",
+ "jest-runtime": "^26.6.3"
+ }
+ },
+ "@jest/transform": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz",
+ "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.1.0",
+ "@jest/types": "^26.6.2",
+ "babel-plugin-istanbul": "^6.0.0",
+ "chalk": "^4.0.0",
+ "convert-source-map": "^1.4.0",
+ "fast-json-stable-stringify": "^2.0.0",
+ "graceful-fs": "^4.2.4",
+ "jest-haste-map": "^26.6.2",
+ "jest-regex-util": "^26.0.0",
+ "jest-util": "^26.6.2",
+ "micromatch": "^4.0.2",
+ "pirates": "^4.0.1",
+ "slash": "^3.0.0",
+ "source-map": "^0.6.1",
+ "write-file-atomic": "^3.0.0"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@jest/types": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz",
+ "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^1.1.1",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@jridgewell/gen-mapping": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+ "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+ "requires": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w=="
+ },
+ "@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw=="
+ },
+ "@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
+ },
+ "@jridgewell/trace-mapping": {
+ "version": "0.3.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz",
+ "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==",
+ "requires": {
+ "@jridgewell/resolve-uri": "^3.0.3",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "@jsdevtools/coverage-istanbul-loader": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@jsdevtools/coverage-istanbul-loader/-/coverage-istanbul-loader-3.0.5.tgz",
+ "integrity": "sha512-EUCPEkaRPvmHjWAAZkWMT7JDzpw7FKB00WTISaiXsbNOd5hCHg77XLA8sLYLFDo1zepYLo2w7GstN8YBqRXZfA==",
+ "dev": true,
+ "requires": {
+ "convert-source-map": "^1.7.0",
+ "istanbul-lib-instrument": "^4.0.3",
+ "loader-utils": "^2.0.0",
+ "merge-source-map": "^1.1.0",
+ "schema-utils": "^2.7.0"
+ }
+ },
+ "@juggle/resize-observer": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz",
+ "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA=="
+ },
+ "@mochajs/json-file-reporter": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@mochajs/json-file-reporter/-/json-file-reporter-1.3.0.tgz",
+ "integrity": "sha512-evIxpeP8EOixo/T2xh5xYEIzwbEHk8YNJfRUm1KeTs8F3bMjgNn2580Ogze9yisXNlTxu88JiJJYzXjjg5NdLA==",
+ "dev": true
+ },
+ "@ng-bootstrap/ng-bootstrap": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-10.0.0.tgz",
+ "integrity": "sha512-Sz+QaxjuyJYJ+zyUbf0TevgcgVesCPQiiFiggEzxKjzY5R+Hvq3YgryLdXf2r/ryePL+C3FXCcmmKpTM5bfczQ==",
+ "requires": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "@ngtools/webpack": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-12.2.13.tgz",
+ "integrity": "sha512-krAwMyRqOaC1S0+IxAFid9F6A6ABip2DJ0tgCx26X+1Vw/d1GKtV9ZqDJFizMf5k1ywl9aBlhOazWpq5d6i+gw==",
+ "dev": true
+ },
+ "@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true
+ },
+ "@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ }
+ },
+ "@npmcli/git": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.1.0.tgz",
+ "integrity": "sha512-/hBFX/QG1b+N7PZBFs0bi+evgRZcK9nWBxQKZkGoXUT5hJSwl5c4d7y8/hm+NQZRPhQ67RzFaj5UM9YeyKoryw==",
+ "dev": true,
+ "requires": {
+ "@npmcli/promise-spawn": "^1.3.2",
+ "lru-cache": "^6.0.0",
+ "mkdirp": "^1.0.4",
+ "npm-pick-manifest": "^6.1.1",
+ "promise-inflight": "^1.0.1",
+ "promise-retry": "^2.0.1",
+ "semver": "^7.3.5",
+ "which": "^2.0.2"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "@npmcli/installed-package-contents": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz",
+ "integrity": "sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==",
+ "dev": true,
+ "requires": {
+ "npm-bundled": "^1.1.1",
+ "npm-normalize-package-bin": "^1.0.1"
+ }
+ },
+ "@npmcli/move-file": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
+ "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
+ "dev": true,
+ "requires": {
+ "mkdirp": "^1.0.4",
+ "rimraf": "^3.0.2"
+ }
+ },
+ "@npmcli/node-gyp": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-1.0.3.tgz",
+ "integrity": "sha512-fnkhw+fmX65kiLqk6E3BFLXNC26rUhK90zVwe2yncPliVT/Qos3xjhTLE59Df8KnPlcwIERXKVlU1bXoUQ+liA==",
+ "dev": true
+ },
+ "@npmcli/promise-spawn": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz",
+ "integrity": "sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg==",
+ "dev": true,
+ "requires": {
+ "infer-owner": "^1.0.4"
+ }
+ },
+ "@npmcli/run-script": {
+ "version": "1.8.6",
+ "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-1.8.6.tgz",
+ "integrity": "sha512-e42bVZnC6VluBZBAFEr3YrdqSspG3bgilyg4nSLBJ7TRGNCzxHa92XAHxQBLYg0BmgwO4b2mf3h/l5EkEWRn3g==",
+ "dev": true,
+ "requires": {
+ "@npmcli/node-gyp": "^1.0.2",
+ "@npmcli/promise-spawn": "^1.3.2",
+ "node-gyp": "^7.1.0",
+ "read-package-json-fast": "^2.0.1"
+ }
+ },
+ "@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
+ "dev": true
+ },
+ "@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
+ "dev": true
+ },
+ "@protobufjs/codegen": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+ "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
+ "dev": true
+ },
+ "@protobufjs/eventemitter": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+ "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
+ "dev": true
+ },
+ "@protobufjs/fetch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+ "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+ "dev": true,
+ "requires": {
+ "@protobufjs/aspromise": "^1.1.1",
+ "@protobufjs/inquire": "^1.1.0"
+ }
+ },
+ "@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
+ "dev": true
+ },
+ "@protobufjs/inquire": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+ "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
+ "dev": true
+ },
+ "@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
+ "dev": true
+ },
+ "@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
+ "dev": true
+ },
+ "@protobufjs/utf8": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
+ "dev": true
+ },
+ "@schematics/angular": {
+ "version": "12.2.13",
+ "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-12.2.13.tgz",
+ "integrity": "sha512-TrigQ9TCmAedf1J5PSSSfTC+sScYrITeAUN8a9rlkjZNvff8hHVyQaiZmhqL+egKQL828mhkqpnFUDd4QsPBIw==",
+ "dev": true,
+ "requires": {
+ "@angular-devkit/core": "12.2.13",
+ "@angular-devkit/schematics": "12.2.13",
+ "jsonc-parser": "3.0.0"
+ }
+ },
+ "@sideway/address": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
+ "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==",
+ "dev": true,
+ "requires": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "@sideway/formula": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz",
+ "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==",
+ "dev": true
+ },
+ "@sideway/pinpoint": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
+ "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
+ "dev": true
+ },
+ "@sinonjs/commons": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
+ "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==",
+ "dev": true,
+ "requires": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "@sinonjs/fake-timers": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz",
+ "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.7.0"
+ }
+ },
+ "@stylelint/postcss-css-in-js": {
+ "version": "0.37.3",
+ "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.3.tgz",
+ "integrity": "sha512-scLk3cSH1H9KggSniseb2KNAU5D9FWc3H7BxCSAIdtU9OWIyw0zkEZ9qEKHryRM+SExYXRKNb7tOOVNAsQ3iwg==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.17.9"
+ },
+ "dependencies": {
+ "@ampproject/remapping": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
+ "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/gen-mapping": "^0.1.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@babel/core": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.0.tgz",
+ "integrity": "sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==",
+ "dev": true,
+ "requires": {
+ "@ampproject/remapping": "^2.1.0",
+ "@babel/code-frame": "^7.18.6",
+ "@babel/generator": "^7.19.0",
+ "@babel/helper-compilation-targets": "^7.19.0",
+ "@babel/helper-module-transforms": "^7.19.0",
+ "@babel/helpers": "^7.19.0",
+ "@babel/parser": "^7.19.0",
+ "@babel/template": "^7.18.10",
+ "@babel/traverse": "^7.19.0",
+ "@babel/types": "^7.19.0",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.1",
+ "semver": "^6.3.0"
+ }
+ },
+ "@jridgewell/gen-mapping": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
+ "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.0",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "@stylelint/postcss-markdown": {
+ "version": "0.36.2",
+ "resolved": "https://registry.npmjs.org/@stylelint/postcss-markdown/-/postcss-markdown-0.36.2.tgz",
+ "integrity": "sha512-2kGbqUVJUGE8dM+bMzXG/PYUWKkjLIkRLWNh39OaADkiabDRdw8ATFCgbMz5xdIcvwspPAluSL7uY+ZiTWdWmQ==",
+ "dev": true,
+ "requires": {
+ "remark": "^13.0.0",
+ "unist-util-find-all-after": "^3.0.2"
+ }
+ },
+ "@swimlane/ngx-datatable": {
+ "version": "18.0.0",
+ "resolved": "https://registry.npmjs.org/@swimlane/ngx-datatable/-/ngx-datatable-18.0.0.tgz",
+ "integrity": "sha512-secqjzlLpGJqoXjcoCoTf8ClnVlZAENJcXvuBfseGenOD+evGNXc4UTZhwCPDUBlJ4xnMZHUWK6IVk5sXe+WlQ==",
+ "requires": {
+ "tslib": "^2.0.0"
+ }
+ },
+ "@tootallnate/once": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
+ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
+ "dev": true
+ },
+ "@trysound/sax": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
+ "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
+ "dev": true
+ },
+ "@ts-morph/common": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.11.1.tgz",
+ "integrity": "sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==",
+ "dev": true,
+ "requires": {
+ "fast-glob": "^3.2.7",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^1.0.4",
+ "path-browserify": "^1.0.1"
+ }
+ },
+ "@types/babel__core": {
+ "version": "7.1.19",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz",
+ "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "@types/babel__generator": {
+ "version": "7.6.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz",
+ "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "@types/babel__template": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz",
+ "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "@types/babel__traverse": {
+ "version": "7.18.1",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.1.tgz",
+ "integrity": "sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.3.0"
+ }
+ },
+ "@types/brace-expansion": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@types/brace-expansion/-/brace-expansion-1.1.0.tgz",
+ "integrity": "sha512-SaU/Kgp6z40CiF9JxlsrSrBEa+8YIry9IiCPhhYSNekeEhIAkY7iyu9aZ+5dSQIdo7mf86MUVvxWYm5GAzB/0g==",
+ "dev": true
+ },
+ "@types/chart.js": {
+ "version": "2.9.37",
+ "resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.37.tgz",
+ "integrity": "sha512-9bosRfHhkXxKYfrw94EmyDQcdjMaQPkU1fH2tDxu8DWXxf1mjzWQAV4laJF51ZbC2ycYwNDvIm1rGez8Bug0vg==",
+ "requires": {
+ "moment": "^2.10.2"
+ }
+ },
+ "@types/cypress-cucumber-preprocessor": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@types/cypress-cucumber-preprocessor/-/cypress-cucumber-preprocessor-4.0.1.tgz",
+ "integrity": "sha512-sK2/uU5CtmJ51zo0JF2Lc4iSw9Fy3xn9ewfewuooV5Qmeb5O+brAHuoXKMV7UWwRbBmd+txhAXAJoi4S5QLDRQ==",
+ "dev": true
+ },
+ "@types/eslint": {
+ "version": "8.4.6",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz",
+ "integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==",
+ "dev": true,
+ "requires": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
+ }
+ },
+ "@types/eslint-scope": {
+ "version": "3.7.4",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz",
+ "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==",
+ "dev": true,
+ "requires": {
+ "@types/eslint": "*",
+ "@types/estree": "*"
+ }
+ },
+ "@types/estree": {
+ "version": "0.0.50",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz",
+ "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==",
+ "dev": true
+ },
+ "@types/file-saver": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.1.tgz",
+ "integrity": "sha512-g1QUuhYVVAamfCifK7oB7G3aIl4BbOyzDOqVyUfEr4tfBKrXfeH+M+Tg7HKCXSrbzxYdhyCP7z9WbKo0R2hBCw=="
+ },
+ "@types/glob": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
+ "dev": true,
+ "requires": {
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/graceful-fs": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz",
+ "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/hast": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
+ "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==",
+ "requires": {
+ "@types/unist": "*"
+ }
+ },
+ "@types/hoist-non-react-statics": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
+ "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
+ "requires": {
+ "@types/react": "*",
+ "hoist-non-react-statics": "^3.3.0"
+ }
+ },
+ "@types/istanbul-lib-coverage": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
+ "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
+ "dev": true
+ },
+ "@types/istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz",
+ "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "*",
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "@types/jest": {
+ "version": "26.0.14",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.14.tgz",
+ "integrity": "sha512-Hz5q8Vu0D288x3iWXePSn53W7hAjP0H7EQ6QvDO9c7t46mR0lNOLlfuwQ+JkVxuhygHzlzPX+0jKdA3ZgSh+Vg==",
+ "dev": true,
+ "requires": {
+ "jest-diff": "^25.2.1",
+ "pretty-format": "^25.2.1"
+ }
+ },
+ "@types/json-schema": {
+ "version": "7.0.11",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
+ "dev": true
+ },
+ "@types/lodash": {
+ "version": "4.14.161",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.161.tgz",
+ "integrity": "sha512-EP6O3Jkr7bXvZZSZYlsgt5DIjiGr0dXP1/jVEwVLTFgg0d+3lWVQkRavYVQszV7dYUwvg0B8R0MBDpcmXg7XIA==",
+ "dev": true
+ },
+ "@types/long": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
+ "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==",
+ "dev": true
+ },
+ "@types/mdast": {
+ "version": "3.0.10",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz",
+ "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "*"
+ }
+ },
+ "@types/minimatch": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
+ "dev": true
+ },
+ "@types/minimist": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
+ "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==",
+ "dev": true
+ },
+ "@types/node": {
+ "version": "12.12.62",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.62.tgz",
+ "integrity": "sha512-qAfo81CsD7yQIM9mVyh6B/U47li5g7cfpVQEDMfQeF8pSZVwzbhwU3crc0qG4DmpsebpJPR49AKOExQyJ05Cpg==",
+ "dev": true
+ },
+ "@types/normalize-package-data": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
+ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
+ "dev": true
+ },
+ "@types/parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
+ "dev": true
+ },
+ "@types/prettier": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz",
+ "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==",
+ "dev": true
+ },
+ "@types/prop-types": {
+ "version": "15.7.5",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
+ "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
+ },
+ "@types/react": {
+ "version": "18.0.18",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.18.tgz",
+ "integrity": "sha512-6hI08umYs6NaiHFEEGioXnxJ+oEhY3eRz8VCUaudZmGdtvPviCJB8mgaMxaDWAdPSYd4eFavrPk2QIolwbLYrg==",
+ "requires": {
+ "@types/prop-types": "*",
+ "@types/scheduler": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "@types/react-redux": {
+ "version": "7.1.24",
+ "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.24.tgz",
+ "integrity": "sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ==",
+ "requires": {
+ "@types/hoist-non-react-statics": "^3.3.0",
+ "@types/react": "*",
+ "hoist-non-react-statics": "^3.3.0",
+ "redux": "^4.0.0"
+ }
+ },
+ "@types/scheduler": {
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
+ "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
+ },
+ "@types/simplebar": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/@types/simplebar/-/simplebar-5.1.1.tgz",
+ "integrity": "sha512-nC9iBQ4dfvvzJ3iAbL1qCfwjUyaF8EO56l/ApcRXUFK2zLOb8GDXC55V08JZvpzkUxGHtWVunp17KKH/3/KFJA==",
+ "dev": true
+ },
+ "@types/sinonjs__fake-timers": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz",
+ "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==",
+ "dev": true
+ },
+ "@types/sizzle": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz",
+ "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==",
+ "dev": true
+ },
+ "@types/source-list-map": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
+ "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==",
+ "dev": true
+ },
+ "@types/stack-utils": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
+ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
+ "dev": true
+ },
+ "@types/swagger-ui": {
+ "version": "3.52.0",
+ "resolved": "https://registry.npmjs.org/@types/swagger-ui/-/swagger-ui-3.52.0.tgz",
+ "integrity": "sha512-SlufixEmh+8CLHNgTfAfCT1icNOF7bXboWabhHr1+hIolqlvfwYJGe7HgRcpI3ChE7HWASmEKLkMu34rxseJjQ==",
+ "dev": true
+ },
+ "@types/unist": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
+ "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
+ },
+ "@types/uuid": {
+ "version": "3.4.10",
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.10.tgz",
+ "integrity": "sha512-BgeaZuElf7DEYZhWYDTc/XcLZXdVgFkVSTa13BqKvbnmUrxr3TJFKofUxCtDO9UQOdhnV+HPOESdHiHKZOJV1A==",
+ "dev": true
+ },
+ "@types/webpack-sources": {
+ "version": "0.1.9",
+ "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.9.tgz",
+ "integrity": "sha512-bvzMnzqoK16PQIC8AYHNdW45eREJQMd6WG/msQWX5V2+vZmODCOPb4TJcbgRljTZZTwTM4wUMcsI8FftNA7new==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "@types/source-list-map": "*",
+ "source-map": "^0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "@types/yargs": {
+ "version": "15.0.14",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz",
+ "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==",
+ "dev": true,
+ "requires": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "@types/yargs-parser": {
+ "version": "21.0.0",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
+ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
+ "dev": true
+ },
+ "@types/yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@ungap/promise-all-settled": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
+ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
+ "dev": true
+ },
+ "@webassemblyjs/ast": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
+ "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/helper-numbers": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1"
+ }
+ },
+ "@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
+ "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-api-error": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
+ "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-buffer": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
+ "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-numbers": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
+ "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/floating-point-hex-parser": "1.11.1",
+ "@webassemblyjs/helper-api-error": "1.11.1",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
+ "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-wasm-section": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
+ "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1"
+ }
+ },
+ "@webassemblyjs/ieee754": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
+ "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
+ "dev": true,
+ "requires": {
+ "@xtuc/ieee754": "^1.2.0"
+ }
+ },
+ "@webassemblyjs/leb128": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
+ "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
+ "dev": true,
+ "requires": {
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "@webassemblyjs/utf8": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
+ "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
+ "dev": true
+ },
+ "@webassemblyjs/wasm-edit": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
+ "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/helper-wasm-section": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1",
+ "@webassemblyjs/wasm-opt": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1",
+ "@webassemblyjs/wast-printer": "1.11.1"
+ }
+ },
+ "@webassemblyjs/wasm-gen": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
+ "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/ieee754": "1.11.1",
+ "@webassemblyjs/leb128": "1.11.1",
+ "@webassemblyjs/utf8": "1.11.1"
+ }
+ },
+ "@webassemblyjs/wasm-opt": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
+ "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1"
+ }
+ },
+ "@webassemblyjs/wasm-parser": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
+ "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-api-error": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/ieee754": "1.11.1",
+ "@webassemblyjs/leb128": "1.11.1",
+ "@webassemblyjs/utf8": "1.11.1"
+ }
+ },
+ "@webassemblyjs/wast-printer": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
+ "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "@xtuc/ieee754": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+ "dev": true
+ },
+ "@xtuc/long": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+ "dev": true
+ },
+ "@yarnpkg/lockfile": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
+ "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
+ "dev": true
+ },
+ "JSONStream": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
+ "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
+ "dev": true,
+ "requires": {
+ "jsonparse": "^1.2.0",
+ "through": ">=2.2.7 <3"
+ }
+ },
+ "abab": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
+ "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==",
+ "dev": true
+ },
+ "abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "dev": true
+ },
+ "abort-controller": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
+ "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+ "dev": true,
+ "requires": {
+ "event-target-shim": "^5.0.0"
+ }
+ },
+ "accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "dev": true,
+ "requires": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ }
+ },
+ "acorn": {
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+ "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
+ "dev": true
+ },
+ "acorn-globals": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz",
+ "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==",
+ "dev": true,
+ "requires": {
+ "acorn": "^6.0.1",
+ "acorn-walk": "^6.0.1"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
+ "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
+ "dev": true
+ }
+ }
+ },
+ "acorn-import-assertions": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
+ "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
+ "dev": true
+ },
+ "acorn-node": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz",
+ "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==",
+ "dev": true,
+ "requires": {
+ "acorn": "^7.0.0",
+ "acorn-walk": "^7.0.0",
+ "xtend": "^4.0.2"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true
+ },
+ "acorn-walk": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+ "dev": true
+ }
+ }
+ },
+ "acorn-walk": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz",
+ "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
+ "dev": true
+ },
+ "adjust-sourcemap-loader": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz",
+ "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==",
+ "dev": true,
+ "requires": {
+ "loader-utils": "^2.0.0",
+ "regex-parser": "^2.2.11"
+ }
+ },
+ "agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "dev": true,
+ "requires": {
+ "debug": "4"
+ }
+ },
+ "agentkeepalive": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz",
+ "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.0",
+ "depd": "^1.1.2",
+ "humanize-ms": "^1.2.1"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
+ "dev": true
+ }
+ }
+ },
+ "aggregate-error": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+ "dev": true,
+ "requires": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ }
+ },
+ "ajv": {
+ "version": "8.6.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz",
+ "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ajv-errors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
+ "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
+ "dev": true
+ },
+ "ajv-formats": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.0.tgz",
+ "integrity": "sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q==",
+ "dev": true,
+ "requires": {
+ "ajv": "^8.0.0"
+ }
+ },
+ "ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "dev": true
+ },
+ "amdefine": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+ "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==",
+ "dev": true,
+ "optional": true
+ },
+ "ansi-colors": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+ "dev": true
+ },
+ "ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.21.3"
+ },
+ "dependencies": {
+ "type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "dev": true
+ }
+ }
+ },
+ "ansi-gray": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
+ "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==",
+ "dev": true,
+ "requires": {
+ "ansi-wrap": "0.1.0"
+ }
+ },
+ "ansi-html": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
+ "integrity": "sha512-JoAxEa1DfP9m2xfB/y2r/aKcwXNlltr4+0QSBC4TrLfcxyvepX2Pv0t/xpgGV5bGsDzCYV8SzjWgyCW0T9yYbA==",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "ansi-wrap": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
+ "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==",
+ "dev": true
+ },
+ "any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "dev": true
+ },
+ "anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "apache-crypt": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/apache-crypt/-/apache-crypt-1.2.5.tgz",
+ "integrity": "sha512-ICnYQH+DFVmw+S4Q0QY2XRXD8Ne8ewh8HgbuFH4K7022zCxgHM0Hz1xkRnUlEfAXNbwp1Cnhbedu60USIfDxvg==",
+ "dev": true,
+ "requires": {
+ "unix-crypt-td-js": "^1.1.4"
+ }
+ },
+ "apache-md5": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.7.tgz",
+ "integrity": "sha512-JtHjzZmJxtzfTSjsCyHgPR155HBe5WGyUyHTaEkfy46qhwCFKx1Epm6nAxgUG3WfUZP1dWhGqj9Z2NOBeZ+uBw==",
+ "dev": true
+ },
+ "app-root-path": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz",
+ "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==",
+ "dev": true
+ },
+ "aproba": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+ "dev": true
+ },
+ "arch": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz",
+ "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==",
+ "dev": true
+ },
+ "are-we-there-yet": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz",
+ "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==",
+ "dev": true,
+ "requires": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.6"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true
+ },
+ "argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+ },
+ "aria-query": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz",
+ "integrity": "sha512-majUxHgLehQTeSA+hClx+DY09OVUqG3GtezWkF1krgLGNdlDu9l9V8DaqNMWbq4Eddc8wsyDA0hpDUtnYxQEXw==",
+ "dev": true,
+ "requires": {
+ "ast-types-flow": "0.0.7",
+ "commander": "^2.11.0"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ }
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==",
+ "dev": true
+ },
+ "arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+ "dev": true
+ },
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==",
+ "dev": true
+ },
+ "array-differ": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
+ "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
+ "dev": true
+ },
+ "array-each": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
+ "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==",
+ "dev": true
+ },
+ "array-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
+ "integrity": "sha512-H3LU5RLiSsGXPhN+Nipar0iR0IofH+8r89G2y1tBKxQ/agagKyAjhkAFDRBfodP2caPrNKHpAWNIM/c9yeL7uA==",
+ "dev": true
+ },
+ "array-flatten": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
+ "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
+ "dev": true
+ },
+ "array-from": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz",
+ "integrity": "sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==",
+ "dev": true
+ },
+ "array-slice": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
+ "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
+ "dev": true
+ },
+ "array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==",
+ "dev": true
+ },
+ "arrify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
+ "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
+ "dev": true
+ },
+ "asap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz",
+ "integrity": "sha512-Ej9qjcXY+8Tuy1cNqiwNMwFRXOy9UwgTeMA8LxreodygIPV48lx8PU1ecFxb5ZeU1DpMKxiq6vGLTxcitWZPbA==",
+ "dev": true
+ },
+ "asn1": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
+ "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "asn1.js": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
+ "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "safer-buffer": "^2.1.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+ "dev": true
+ }
+ }
+ },
+ "assert": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz",
+ "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
+ "dev": true,
+ "requires": {
+ "object-assign": "^4.1.1",
+ "util": "0.10.3"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+ "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==",
+ "dev": true
+ },
+ "util": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+ "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.1"
+ }
+ }
+ }
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
+ "dev": true
+ },
+ "assertion-error": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+ "dev": true
+ },
+ "assertion-error-formatter": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/assertion-error-formatter/-/assertion-error-formatter-2.0.1.tgz",
+ "integrity": "sha512-cjC3jUCh9spkroKue5PDSKH5RFQ/KNuZJhk3GwHYmB/8qqETxLOmMdLH+ohi/VukNzxDlMvIe7zScvLoOdhb6Q==",
+ "dev": true,
+ "requires": {
+ "diff": "^3.0.0",
+ "pad-right": "^0.2.2",
+ "repeat-string": "^1.6.1"
+ },
+ "dependencies": {
+ "diff": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+ "dev": true
+ }
+ }
+ },
+ "assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==",
+ "dev": true
+ },
+ "ast-transform": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/ast-transform/-/ast-transform-0.0.0.tgz",
+ "integrity": "sha512-e/JfLiSoakfmL4wmTGPjv0HpTICVmxwXgYOB8x+mzozHL8v+dSfCbrJ8J8hJ0YBP0XcYu1aLZ6b/3TnxNK3P2A==",
+ "dev": true,
+ "requires": {
+ "escodegen": "~1.2.0",
+ "esprima": "~1.0.4",
+ "through": "~2.3.4"
+ },
+ "dependencies": {
+ "escodegen": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.2.0.tgz",
+ "integrity": "sha512-yLy3Cc+zAC0WSmoT2fig3J87TpQ8UaZGx8ahCAs9FL8qNbyV7CVyPKS74DG4bsHiL5ew9sxdYx131OkBQMFnvA==",
+ "dev": true,
+ "requires": {
+ "esprima": "~1.0.4",
+ "estraverse": "~1.5.0",
+ "esutils": "~1.0.0",
+ "source-map": "~0.1.30"
+ }
+ },
+ "esprima": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
+ "integrity": "sha512-rp5dMKN8zEs9dfi9g0X1ClLmV//WRyk/R15mppFNICIFRG5P92VP7Z04p8pk++gABo9W2tY+kHyu6P1mEHgmTA==",
+ "dev": true
+ },
+ "estraverse": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.5.1.tgz",
+ "integrity": "sha512-FpCjJDfmo3vsc/1zKSeqR5k42tcIhxFIlvq+h9j0fO2q/h2uLKyweq7rYJ+0CoVvrGQOxIS5wyBrW/+vF58BUQ==",
+ "dev": true
+ },
+ "esutils": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.0.0.tgz",
+ "integrity": "sha512-x/iYH53X3quDwfHRz4y8rn4XcEwwCJeWsul9pF1zldMbGtgOtMNBEOuYWwB1EQlK2LRa1fev3YAgym/RElp5Cg==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.1.43",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
+ "integrity": "sha512-VtCvB9SIQhk3aF6h+N85EaqIaBFIAfZ9Cu+NJHHVvc8BbEcnvDcFw6sqQ2dQrT6SlOrZq3tIvyD9+EGq/lJryQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "amdefine": ">=0.0.4"
+ }
+ }
+ }
+ },
+ "ast-types": {
+ "version": "0.7.8",
+ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.7.8.tgz",
+ "integrity": "sha512-RIOpVnVlltB6PcBJ5BMLx+H+6JJ/zjDGU0t7f0L6c2M1dqcK92VQopLBlPQ9R80AVXelfqYgjcPLtHtDbNFg0Q==",
+ "dev": true
+ },
+ "ast-types-flow": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
+ "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==",
+ "dev": true
+ },
+ "astral-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+ "dev": true
+ },
+ "async": {
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
+ "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "async-each": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
+ "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
+ "dev": true
+ },
+ "async-limiter": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+ "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
+ "dev": true
+ },
+ "async-mutex": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.2.4.tgz",
+ "integrity": "sha512-fcQKOXUKMQc57JlmjBCHtkKNrfGpHyR7vu18RfuLfeTAf4hK9PgOadPR5cDrBQ682zasrLUhJFe7EKAHJOduDg==",
+ "requires": {
+ "tslib": "^2.0.0"
+ }
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "dev": true
+ },
+ "at-least-node": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+ "dev": true
+ },
+ "atob": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+ "dev": true
+ },
+ "autolinker": {
+ "version": "3.16.2",
+ "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-3.16.2.tgz",
+ "integrity": "sha512-JiYl7j2Z19F9NdTmirENSUUIIL/9MytEWtmzhfmsKPCp9E+G35Y0UNCMoM9tFigxT59qSc8Ml2dlZXOCVTYwuA==",
+ "requires": {
+ "tslib": "^2.3.0"
+ }
+ },
+ "autoprefixer": {
+ "version": "9.8.8",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz",
+ "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.12.0",
+ "caniuse-lite": "^1.0.30001109",
+ "normalize-range": "^0.1.2",
+ "num2fraction": "^1.2.2",
+ "picocolors": "^0.2.1",
+ "postcss": "^7.0.32",
+ "postcss-value-parser": "^4.1.0"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "available-typed-arrays": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
+ "dev": true
+ },
+ "aws4": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
+ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
+ "dev": true
+ },
+ "axios": {
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
+ "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
+ "dev": true,
+ "requires": {
+ "follow-redirects": "^1.14.0"
+ }
+ },
+ "axobject-query": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz",
+ "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==",
+ "dev": true,
+ "requires": {
+ "ast-types-flow": "0.0.7"
+ }
+ },
+ "babel-jest": {
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz",
+ "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==",
+ "dev": true,
+ "requires": {
+ "@jest/transform": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/babel__core": "^7.1.7",
+ "babel-plugin-istanbul": "^6.0.0",
+ "babel-preset-jest": "^26.6.2",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.4",
+ "slash": "^3.0.0"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "babel-loader": {
+ "version": "8.2.2",
+ "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz",
+ "integrity": "sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g==",
+ "dev": true,
+ "requires": {
+ "find-cache-dir": "^3.3.1",
+ "loader-utils": "^1.4.0",
+ "make-dir": "^3.1.0",
+ "schema-utils": "^2.6.5"
+ },
+ "dependencies": {
+ "json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ },
+ "loader-utils": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+ "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+ "dev": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^1.0.1"
+ }
+ }
+ }
+ },
+ "babel-plugin-add-module-exports": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-1.0.4.tgz",
+ "integrity": "sha512-g+8yxHUZ60RcyaUpfNzy56OtWW+x9cyEe9j+CranqLiqbju2yf/Cy6ZtYK40EZxtrdHllzlVZgLmcOUCTlJ7Jg==",
+ "dev": true
+ },
+ "babel-plugin-dynamic-import-node": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
+ "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==",
+ "dev": true,
+ "requires": {
+ "object.assign": "^4.1.0"
+ }
+ },
+ "babel-plugin-istanbul": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
+ "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-instrument": "^5.0.4",
+ "test-exclude": "^6.0.0"
+ },
+ "dependencies": {
+ "@ampproject/remapping": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
+ "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/gen-mapping": "^0.1.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@babel/core": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.0.tgz",
+ "integrity": "sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==",
+ "dev": true,
+ "requires": {
+ "@ampproject/remapping": "^2.1.0",
+ "@babel/code-frame": "^7.18.6",
+ "@babel/generator": "^7.19.0",
+ "@babel/helper-compilation-targets": "^7.19.0",
+ "@babel/helper-module-transforms": "^7.19.0",
+ "@babel/helpers": "^7.19.0",
+ "@babel/parser": "^7.19.0",
+ "@babel/template": "^7.18.10",
+ "@babel/traverse": "^7.19.0",
+ "@babel/types": "^7.19.0",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.1",
+ "semver": "^6.3.0"
+ }
+ },
+ "@jridgewell/gen-mapping": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
+ "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.0",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "istanbul-lib-instrument": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz",
+ "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.12.3",
+ "@babel/parser": "^7.14.7",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-coverage": "^3.2.0",
+ "semver": "^6.3.0"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "babel-plugin-jest-hoist": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz",
+ "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.3.3",
+ "@babel/types": "^7.3.3",
+ "@types/babel__core": "^7.0.0",
+ "@types/babel__traverse": "^7.0.6"
+ }
+ },
+ "babel-plugin-polyfill-corejs2": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.3.tgz",
+ "integrity": "sha512-NDZ0auNRzmAfE1oDDPW2JhzIMXUk+FFe2ICejmt5T4ocKgiQx3e0VCRx9NCAidcMtL2RUZaWtXnmjTCkx0tcbA==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.13.11",
+ "@babel/helper-define-polyfill-provider": "^0.2.4",
+ "semver": "^6.1.1"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "babel-plugin-polyfill-corejs3": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.5.tgz",
+ "integrity": "sha512-ninF5MQNwAX9Z7c9ED+H2pGt1mXdP4TqzlHKyPIYmJIYz0N+++uwdM7RnJukklhzJ54Q84vA4ZJkgs7lu5vqcw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-define-polyfill-provider": "^0.2.2",
+ "core-js-compat": "^3.16.2"
+ }
+ },
+ "babel-plugin-polyfill-regenerator": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.3.tgz",
+ "integrity": "sha512-JVE78oRZPKFIeUqFGrSORNzQnrDwZR16oiWeGM8ZyjBn2XAT5OjP+wXx5ESuo33nUsFUEJYjtklnsKbxW5L+7g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-define-polyfill-provider": "^0.2.4"
+ }
+ },
+ "babel-preset-current-node-syntax": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz",
+ "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==",
+ "dev": true,
+ "requires": {
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-bigint": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.8.3",
+ "@babel/plugin-syntax-import-meta": "^7.8.3",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.8.3",
+ "@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-top-level-await": "^7.8.3"
+ }
+ },
+ "babel-preset-jest": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz",
+ "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==",
+ "dev": true,
+ "requires": {
+ "babel-plugin-jest-hoist": "^26.6.2",
+ "babel-preset-current-node-syntax": "^1.0.0"
+ }
+ },
+ "babel-runtime": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+ "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==",
+ "dev": true,
+ "requires": {
+ "core-js": "^2.4.0",
+ "regenerator-runtime": "^0.11.0"
+ },
+ "dependencies": {
+ "core-js": {
+ "version": "2.6.12",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
+ "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
+ "dev": true
+ },
+ "regenerator-runtime": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+ "dev": true
+ }
+ }
+ },
+ "babelify": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/babelify/-/babelify-10.0.0.tgz",
+ "integrity": "sha512-X40FaxyH7t3X+JFAKvb1H9wooWKLRCi8pg3m8poqtdZaIng+bjzp9RvKQCvRjF9isHiPkXspbbXT/zwXLtwgwg==",
+ "dev": true
+ },
+ "bail": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz",
+ "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "dev": true,
+ "requires": {
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
+ },
+ "basic-auth": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
+ "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.2"
+ }
+ },
+ "batch": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
+ "dev": true
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
+ "dev": true,
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "bcryptjs": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
+ "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==",
+ "dev": true
+ },
+ "becke-ch--regex--s0-0-v1--base--pl--lib": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/becke-ch--regex--s0-0-v1--base--pl--lib/-/becke-ch--regex--s0-0-v1--base--pl--lib-1.4.0.tgz",
+ "integrity": "sha512-FnWonOyaw7Vivg5nIkrUll9HSS5TjFbyuURAiDssuL6VxrBe3ERzudRxOcWRhZYlP89UArMDikz7SapRPQpmZQ==",
+ "dev": true
+ },
+ "big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+ "dev": true
+ },
+ "binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true
+ },
+ "bl": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "blink-diff": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/blink-diff/-/blink-diff-1.0.13.tgz",
+ "integrity": "sha512-2hIEnGq8wruXfje9GvDV41VXo+4YdjrjL5ZMlVJT3Wi5k1jjz20fCTlVejSXoERirhEVsFYz9NmgdUYgQ41Giw==",
+ "dev": true,
+ "requires": {
+ "pngjs-image": "~0.11.5",
+ "preceptor-core": "~0.10.0",
+ "promise": "6.0.0"
+ }
+ },
+ "blob-util": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz",
+ "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==",
+ "dev": true
+ },
+ "bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+ "dev": true
+ },
+ "bn.js": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
+ "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==",
+ "dev": true
+ },
+ "body-parser": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
+ "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
+ "dev": true,
+ "requires": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.4",
+ "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.10.3",
+ "raw-body": "2.5.1",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ },
+ "dependencies": {
+ "bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.10.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
+ "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
+ "dev": true,
+ "requires": {
+ "side-channel": "^1.0.4"
+ }
+ }
+ }
+ },
+ "bonjour": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
+ "integrity": "sha512-RaVTblr+OnEli0r/ud8InrU7D+G0y6aJhlxaLa6Pwty4+xoxboF1BsUI45tujvRpbj9dQVoglChqonGAsjEBYg==",
+ "dev": true,
+ "requires": {
+ "array-flatten": "^2.1.0",
+ "deep-equal": "^1.0.1",
+ "dns-equal": "^1.0.0",
+ "dns-txt": "^2.0.2",
+ "multicast-dns": "^6.0.1",
+ "multicast-dns-service-types": "^1.1.0"
+ }
+ },
+ "boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true
+ },
+ "bootstrap": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.1.tgz",
+ "integrity": "sha512-0dj+VgI9Ecom+rvvpNZ4MUZJz8dcX7WCX+eTID9+/8HgOkv3dsRzi8BGeZJCQU6flWQVYxwTQnEZFrmJSEO7og=="
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "brfs": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brfs/-/brfs-2.0.2.tgz",
+ "integrity": "sha512-IrFjVtwu4eTJZyu8w/V2gxU7iLTtcHih67sgEdzrhjLBMHp2uYefUBfdM4k2UvcuWMgV7PQDZHSLeNWnLFKWVQ==",
+ "dev": true,
+ "requires": {
+ "quote-stream": "^1.0.1",
+ "resolve": "^1.1.5",
+ "static-module": "^3.0.2",
+ "through2": "^2.0.0"
+ }
+ },
+ "brorand": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+ "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==",
+ "dev": true
+ },
+ "brotli": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz",
+ "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.1.2"
+ }
+ },
+ "browser-pack": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz",
+ "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "combine-source-map": "~0.8.0",
+ "defined": "^1.0.0",
+ "safe-buffer": "^5.1.1",
+ "through2": "^2.0.0",
+ "umd": "^3.0.0"
+ }
+ },
+ "browser-process-hrtime": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
+ "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==",
+ "dev": true
+ },
+ "browser-resolve": {
+ "version": "1.11.3",
+ "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz",
+ "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==",
+ "dev": true,
+ "requires": {
+ "resolve": "1.1.7"
+ },
+ "dependencies": {
+ "resolve": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==",
+ "dev": true
+ }
+ }
+ },
+ "browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+ "dev": true
+ },
+ "browserify": {
+ "version": "16.5.2",
+ "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.5.2.tgz",
+ "integrity": "sha512-TkOR1cQGdmXU9zW4YukWzWVSJwrxmNdADFbqbE3HFgQWe5wqZmOawqZ7J/8MPCwk/W8yY7Y0h+7mOtcZxLP23g==",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "assert": "^1.4.0",
+ "browser-pack": "^6.0.1",
+ "browser-resolve": "^2.0.0",
+ "browserify-zlib": "~0.2.0",
+ "buffer": "~5.2.1",
+ "cached-path-relative": "^1.0.0",
+ "concat-stream": "^1.6.0",
+ "console-browserify": "^1.1.0",
+ "constants-browserify": "~1.0.0",
+ "crypto-browserify": "^3.0.0",
+ "defined": "^1.0.0",
+ "deps-sort": "^2.0.0",
+ "domain-browser": "^1.2.0",
+ "duplexer2": "~0.1.2",
+ "events": "^2.0.0",
+ "glob": "^7.1.0",
+ "has": "^1.0.0",
+ "htmlescape": "^1.1.0",
+ "https-browserify": "^1.0.0",
+ "inherits": "~2.0.1",
+ "insert-module-globals": "^7.0.0",
+ "labeled-stream-splicer": "^2.0.0",
+ "mkdirp-classic": "^0.5.2",
+ "module-deps": "^6.2.3",
+ "os-browserify": "~0.3.0",
+ "parents": "^1.0.1",
+ "path-browserify": "~0.0.0",
+ "process": "~0.11.0",
+ "punycode": "^1.3.2",
+ "querystring-es3": "~0.2.0",
+ "read-only-stream": "^2.0.0",
+ "readable-stream": "^2.0.2",
+ "resolve": "^1.1.4",
+ "shasum": "^1.0.0",
+ "shell-quote": "^1.6.1",
+ "stream-browserify": "^2.0.0",
+ "stream-http": "^3.0.0",
+ "string_decoder": "^1.1.1",
+ "subarg": "^1.0.0",
+ "syntax-error": "^1.1.1",
+ "through2": "^2.0.0",
+ "timers-browserify": "^1.0.1",
+ "tty-browserify": "0.0.1",
+ "url": "~0.11.0",
+ "util": "~0.10.1",
+ "vm-browserify": "^1.0.0",
+ "xtend": "^4.0.0"
+ },
+ "dependencies": {
+ "browser-resolve": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz",
+ "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==",
+ "dev": true,
+ "requires": {
+ "resolve": "^1.17.0"
+ }
+ },
+ "buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
+ "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "events": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz",
+ "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==",
+ "dev": true
+ },
+ "path-browserify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
+ "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "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"
+ },
+ "dependencies": {
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ }
+ }
+ },
+ "browserify-aes": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+ "dev": true,
+ "requires": {
+ "buffer-xor": "^1.0.3",
+ "cipher-base": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.3",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "browserify-cipher": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+ "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+ "dev": true,
+ "requires": {
+ "browserify-aes": "^1.0.4",
+ "browserify-des": "^1.0.0",
+ "evp_bytestokey": "^1.0.0"
+ }
+ },
+ "browserify-des": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+ "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "des.js": "^1.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "browserify-optional": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-optional/-/browserify-optional-1.0.1.tgz",
+ "integrity": "sha512-VrhjbZ+Ba5mDiSYEuPelekQMfTbhcA2DhLk2VQWqdcCROWeFqlTcXZ7yfRkXCIl8E+g4gINJYJiRB7WEtfomAQ==",
+ "dev": true,
+ "requires": {
+ "ast-transform": "0.0.0",
+ "ast-types": "^0.7.0",
+ "browser-resolve": "^1.8.1"
+ }
+ },
+ "browserify-rsa": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz",
+ "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^5.0.0",
+ "randombytes": "^2.0.1"
+ }
+ },
+ "browserify-sign": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
+ "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^5.1.1",
+ "browserify-rsa": "^4.0.1",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "elliptic": "^6.5.3",
+ "inherits": "^2.0.4",
+ "parse-asn1": "^5.1.5",
+ "readable-stream": "^3.6.0",
+ "safe-buffer": "^5.2.0"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ }
+ }
+ },
+ "browserify-zlib": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+ "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+ "dev": true,
+ "requires": {
+ "pako": "~1.0.5"
+ }
+ },
+ "browserslist": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz",
+ "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==",
+ "dev": true,
+ "requires": {
+ "caniuse-lite": "^1.0.30001370",
+ "electron-to-chromium": "^1.4.202",
+ "node-releases": "^2.0.6",
+ "update-browserslist-db": "^1.0.5"
+ }
+ },
+ "bs-logger": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
+ "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
+ "dev": true,
+ "requires": {
+ "fast-json-stable-stringify": "2.x"
+ }
+ },
+ "bser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "dev": true,
+ "requires": {
+ "node-int64": "^0.4.0"
+ }
+ },
+ "buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+ "dev": true
+ },
+ "buffer-equal": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz",
+ "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==",
+ "dev": true
+ },
+ "buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true
+ },
+ "buffer-indexof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
+ "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==",
+ "dev": true
+ },
+ "buffer-xor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+ "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==",
+ "dev": true
+ },
+ "builtin-modules": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==",
+ "dev": true
+ },
+ "builtin-status-codes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+ "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==",
+ "dev": true
+ },
+ "builtins": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz",
+ "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==",
+ "dev": true
+ },
+ "bulk-require": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/bulk-require/-/bulk-require-1.0.1.tgz",
+ "integrity": "sha512-BLU9AMnm1FMr68fR0sYvOkMew4x2ZJ8YztshITlGArl6aLtfAazOWiFj/bwJJixRO8C0wXx9PnRNRWeoR03e8Q==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.1"
+ }
+ },
+ "bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==",
+ "dev": true
+ },
+ "cacache": {
+ "version": "15.2.0",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.2.0.tgz",
+ "integrity": "sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw==",
+ "dev": true,
+ "requires": {
+ "@npmcli/move-file": "^1.0.1",
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "glob": "^7.1.4",
+ "infer-owner": "^1.0.4",
+ "lru-cache": "^6.0.0",
+ "minipass": "^3.1.1",
+ "minipass-collect": "^1.0.2",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.2",
+ "mkdirp": "^1.0.3",
+ "p-map": "^4.0.0",
+ "promise-inflight": "^1.0.1",
+ "rimraf": "^3.0.2",
+ "ssri": "^8.0.1",
+ "tar": "^6.0.2",
+ "unique-filename": "^1.1.1"
+ }
+ },
+ "cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "dev": true,
+ "requires": {
+ "collection-visit": "^1.0.0",
+ "component-emitter": "^1.2.1",
+ "get-value": "^2.0.6",
+ "has-value": "^1.0.0",
+ "isobject": "^3.0.1",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ }
+ },
+ "cached-path-relative": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.1.0.tgz",
+ "integrity": "sha512-WF0LihfemtesFcJgO7xfOoOcnWzY/QHR4qeDqV44jPU3HTI54+LnfXK3SA27AVVGCdZFgjjFFaqUA9Jx7dMJZA==",
+ "dev": true
+ },
+ "cachedir": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz",
+ "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==",
+ "dev": true
+ },
+ "call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ }
+ },
+ "callsite": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
+ "integrity": "sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==",
+ "dev": true
+ },
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "camelcase-keys": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz",
+ "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.3.1",
+ "map-obj": "^4.0.0",
+ "quick-lru": "^4.0.1"
+ }
+ },
+ "can-use-dom": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/can-use-dom/-/can-use-dom-0.1.0.tgz",
+ "integrity": "sha512-ceOhN1DL7Y4O6M0j9ICgmTYziV89WMd96SvSl0REd8PMgrY0B/WBOPoed5S1KUmJqXgUXh8gzSe6E3ae27upsQ=="
+ },
+ "caniuse-api": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
+ "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.0.0",
+ "caniuse-lite": "^1.0.0",
+ "lodash.memoize": "^4.1.2",
+ "lodash.uniq": "^4.5.0"
+ }
+ },
+ "caniuse-lite": {
+ "version": "1.0.30001393",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001393.tgz",
+ "integrity": "sha512-N/od11RX+Gsk+1qY/jbPa0R6zJupEa0lxeBG598EbrtblxVCTJsQwbRBm6+V+rxpc5lHKdsXb9RY83cZIPLseA==",
+ "dev": true
+ },
+ "canonical-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/canonical-path/-/canonical-path-1.0.0.tgz",
+ "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==",
+ "dev": true
+ },
+ "capture-exit": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
+ "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==",
+ "dev": true,
+ "requires": {
+ "rsvp": "^4.8.4"
+ }
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==",
+ "dev": true
+ },
+ "chai": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz",
+ "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==",
+ "dev": true,
+ "requires": {
+ "assertion-error": "^1.1.0",
+ "check-error": "^1.0.2",
+ "deep-eql": "^3.0.1",
+ "get-func-name": "^2.0.0",
+ "loupe": "^2.3.1",
+ "pathval": "^1.1.1",
+ "type-detect": "^4.0.5"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "char-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "dev": true
+ },
+ "character-entities": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
+ "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw=="
+ },
+ "character-entities-legacy": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
+ "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA=="
+ },
+ "character-reference-invalid": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
+ "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg=="
+ },
+ "chardet": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+ "dev": true
+ },
+ "charenc": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
+ "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==",
+ "dev": true
+ },
+ "chart.js": {
+ "version": "2.9.4",
+ "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz",
+ "integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==",
+ "requires": {
+ "chartjs-color": "^2.1.0",
+ "moment": "^2.10.2"
+ }
+ },
+ "chartjs-color": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz",
+ "integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==",
+ "requires": {
+ "chartjs-color-string": "^0.6.0",
+ "color-convert": "^1.9.3"
+ }
+ },
+ "chartjs-color-string": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz",
+ "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==",
+ "requires": {
+ "color-name": "^1.0.0"
+ }
+ },
+ "check-error": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+ "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==",
+ "dev": true
+ },
+ "check-more-types": {
+ "version": "2.24.0",
+ "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz",
+ "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==",
+ "dev": true
+ },
+ "cheerio": {
+ "version": "1.0.0-rc.12",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
+ "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
+ "dev": true,
+ "requires": {
+ "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"
+ },
+ "dependencies": {
+ "dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ }
+ },
+ "domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^2.3.0"
+ }
+ },
+ "domutils": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
+ "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
+ "dev": true,
+ "requires": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.1"
+ }
+ },
+ "entities": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
+ "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
+ "dev": true
+ },
+ "parse5": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.1.tgz",
+ "integrity": "sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==",
+ "dev": true,
+ "requires": {
+ "entities": "^4.4.0"
+ }
+ },
+ "parse5-htmlparser2-tree-adapter": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
+ "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
+ "dev": true,
+ "requires": {
+ "domhandler": "^5.0.2",
+ "parse5": "^7.0.0"
+ }
+ }
+ }
+ },
+ "cheerio-select": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+ "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
+ "dev": true,
+ "requires": {
+ "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"
+ },
+ "dependencies": {
+ "css-select": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
+ "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+ "dev": true,
+ "requires": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.1.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "nth-check": "^2.0.1"
+ }
+ },
+ "dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ }
+ },
+ "domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^2.3.0"
+ }
+ },
+ "domutils": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
+ "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
+ "dev": true,
+ "requires": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.1"
+ }
+ },
+ "entities": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
+ "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
+ "dev": true
+ }
+ }
+ },
+ "chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
+ "requires": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "fsevents": "~2.3.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"
+ },
+ "dependencies": {
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ }
+ }
+ },
+ "chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "dev": true
+ },
+ "chrome-remote-interface": {
+ "version": "0.31.1",
+ "resolved": "https://registry.npmjs.org/chrome-remote-interface/-/chrome-remote-interface-0.31.1.tgz",
+ "integrity": "sha512-cvNTnXfx4kYCaeh2sEKrdlqZsYRleACPL47O8LrrjihVfBQbfPmf03vVqSSm7SIeqyo2P77ZXovrBAs4D/nopQ==",
+ "dev": true,
+ "requires": {
+ "commander": "2.11.x",
+ "ws": "^7.2.0"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
+ "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
+ "dev": true
+ },
+ "ws": {
+ "version": "7.5.9",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
+ "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
+ "dev": true
+ }
+ }
+ },
+ "chrome-trace-event": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
+ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
+ "dev": true
+ },
+ "ci-info": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz",
+ "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==",
+ "dev": true
+ },
+ "cipher-base": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "circular-dependency-plugin": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz",
+ "integrity": "sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ==",
+ "dev": true
+ },
+ "cjs-module-lexer": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz",
+ "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==",
+ "dev": true
+ },
+ "cjson": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cjson/-/cjson-0.5.0.tgz",
+ "integrity": "sha512-D3CKJU9YnZNyerUQ1IzNUvMnToP3MGC2XbIAPi/7yqunJJW3rBwCVapousoFtaR9IbejeEM0KIshxC1n4HQcXw==",
+ "dev": true,
+ "requires": {
+ "json-parse-helpfulerror": "^1.0.3"
+ }
+ },
+ "class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ }
+ }
+ },
+ "classnames": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
+ "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
+ },
+ "clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "dev": true
+ },
+ "cli-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^3.1.0"
+ }
+ },
+ "cli-spinners": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz",
+ "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==",
+ "dev": true
+ },
+ "cli-table": {
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.11.tgz",
+ "integrity": "sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==",
+ "dev": true,
+ "requires": {
+ "colors": "1.0.3"
+ },
+ "dependencies": {
+ "colors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
+ "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==",
+ "dev": true
+ }
+ }
+ },
+ "cli-table3": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz",
+ "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==",
+ "dev": true,
+ "requires": {
+ "@colors/colors": "1.5.0",
+ "string-width": "^4.2.0"
+ }
+ },
+ "cli-truncate": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
+ "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
+ "dev": true,
+ "requires": {
+ "slice-ansi": "^3.0.0",
+ "string-width": "^4.2.0"
+ }
+ },
+ "cli-width": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
+ "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
+ "dev": true
+ },
+ "cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+ "dev": true
+ },
+ "clone-deep": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
+ "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4",
+ "kind-of": "^6.0.2",
+ "shallow-clone": "^3.0.0"
+ },
+ "dependencies": {
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ }
+ }
+ },
+ "clone-regexp": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz",
+ "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==",
+ "dev": true,
+ "requires": {
+ "is-regexp": "^2.0.0"
+ }
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
+ "dev": true
+ },
+ "code-block-writer": {
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-10.1.1.tgz",
+ "integrity": "sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==",
+ "dev": true
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==",
+ "dev": true
+ },
+ "codelyzer": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-6.0.2.tgz",
+ "integrity": "sha512-v3+E0Ucu2xWJMOJ2fA/q9pDT/hlxHftHGPUay1/1cTgyPV5JTHFdO9hqo837Sx2s9vKBMTt5gO+lhF95PO6J+g==",
+ "dev": true,
+ "requires": {
+ "@angular/compiler": "9.0.0",
+ "@angular/core": "9.0.0",
+ "app-root-path": "^3.0.0",
+ "aria-query": "^3.0.0",
+ "axobject-query": "2.0.2",
+ "css-selector-tokenizer": "^0.7.1",
+ "cssauron": "^1.4.0",
+ "damerau-levenshtein": "^1.0.4",
+ "rxjs": "^6.5.3",
+ "semver-dsl": "^1.0.1",
+ "source-map": "^0.5.7",
+ "sprintf-js": "^1.1.2",
+ "tslib": "^1.10.0",
+ "zone.js": "~0.10.3"
+ },
+ "dependencies": {
+ "@angular/compiler": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.0.0.tgz",
+ "integrity": "sha512-ctjwuntPfZZT2mNj2NDIVu51t9cvbhl/16epc5xEwyzyDt76pX9UgwvY+MbXrf/C/FWwdtmNtfP698BKI+9leQ==",
+ "dev": true
+ },
+ "@angular/core": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/@angular/core/-/core-9.0.0.tgz",
+ "integrity": "sha512-6Pxgsrf0qF9iFFqmIcWmjJGkkCaCm6V5QNnxMy2KloO3SDq6QuMVRbN9RtC8Urmo25LP+eZ6ZgYqFYpdD8Hd9w==",
+ "dev": true
+ },
+ "sprintf-js": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
+ "dev": true
+ },
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ }
+ }
+ },
+ "coffeeify": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/coffeeify/-/coffeeify-3.0.1.tgz",
+ "integrity": "sha512-Qjnr7UX6ldK1PHV7wCnv7AuCd4q19KTUtwJnu/6JRJB4rfm12zvcXtKdacUoePOKr1I4ka/ydKiwWpNAdsQb0g==",
+ "dev": true,
+ "requires": {
+ "convert-source-map": "^1.3.0",
+ "through2": "^2.0.0"
+ }
+ },
+ "coffeescript": {
+ "version": "1.12.7",
+ "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.12.7.tgz",
+ "integrity": "sha512-pLXHFxQMPklVoEekowk8b3erNynC+DVJzChxS/LCBBgR6/8AJkHivkm//zbowcfc7BTCAjryuhx6gPqPRfsFoA==",
+ "dev": true
+ },
+ "collect-v8-coverage": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz",
+ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==",
+ "dev": true
+ },
+ "collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==",
+ "dev": true,
+ "requires": {
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+ },
+ "color-support": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+ "dev": true
+ },
+ "colord": {
+ "version": "2.9.3",
+ "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
+ "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
+ "dev": true
+ },
+ "colorette": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz",
+ "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==",
+ "dev": true
+ },
+ "colors": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+ "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
+ "dev": true
+ },
+ "combine-source-map": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz",
+ "integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==",
+ "dev": true,
+ "requires": {
+ "convert-source-map": "~1.1.0",
+ "inline-source-map": "~0.6.0",
+ "lodash.memoize": "~3.0.3",
+ "source-map": "~0.5.3"
+ },
+ "dependencies": {
+ "convert-source-map": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
+ "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==",
+ "dev": true
+ },
+ "lodash.memoize": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz",
+ "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==",
+ "dev": true
+ }
+ }
+ },
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "comma-separated-tokens": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz",
+ "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw=="
+ },
+ "commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+ "dev": true
+ },
+ "common-tags": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
+ "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
+ "dev": true
+ },
+ "commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
+ "dev": true
+ },
+ "component-emitter": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
+ "dev": true
+ },
+ "compressible": {
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
+ "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
+ "dev": true,
+ "requires": {
+ "mime-db": ">= 1.43.0 < 2"
+ }
+ },
+ "compression": {
+ "version": "1.7.4",
+ "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
+ "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
+ "dev": true,
+ "requires": {
+ "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"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ }
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+ },
+ "concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "connect": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
+ "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "finalhandler": "1.1.2",
+ "parseurl": "~1.3.3",
+ "utils-merge": "1.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
+ "dev": true,
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+ "dev": true
+ }
+ }
+ },
+ "connect-history-api-fallback": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
+ "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
+ "dev": true
+ },
+ "console-browserify": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
+ "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==",
+ "dev": true
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
+ "dev": true
+ },
+ "constants-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+ "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==",
+ "dev": true
+ },
+ "content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.2.1"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ }
+ }
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "dev": true
+ },
+ "convert-source-map": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
+ "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==",
+ "requires": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "cookie": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+ "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
+ "dev": true
+ },
+ "copy-anything": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz",
+ "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==",
+ "dev": true,
+ "requires": {
+ "is-what": "^3.14.1"
+ }
+ },
+ "copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==",
+ "dev": true
+ },
+ "copy-to-clipboard": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.2.tgz",
+ "integrity": "sha512-Vme1Z6RUDzrb6xAI7EZlVZ5uvOk2F//GaxKUxajDqm9LhOVM1inxNAD2vy+UZDYsd0uyA9s7b3/FVZPSxqrCfg==",
+ "requires": {
+ "toggle-selection": "^1.0.6"
+ }
+ },
+ "copy-webpack-plugin": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-9.0.1.tgz",
+ "integrity": "sha512-14gHKKdYIxF84jCEgPgYXCPpldbwpxxLbCmA7LReY7gvbaT555DgeBWBgBZM116tv/fO6RRJrsivBqRyRlukhw==",
+ "dev": true,
+ "requires": {
+ "fast-glob": "^3.2.5",
+ "glob-parent": "^6.0.0",
+ "globby": "^11.0.3",
+ "normalize-path": "^3.0.0",
+ "p-limit": "^3.1.0",
+ "schema-utils": "^3.0.0",
+ "serialize-javascript": "^6.0.0"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "requires": {
+ "yocto-queue": "^0.1.0"
+ }
+ },
+ "schema-utils": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+ "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ }
+ }
+ }
+ },
+ "core-js": {
+ "version": "3.25.1",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.1.tgz",
+ "integrity": "sha512-sr0FY4lnO1hkQ4gLDr24K0DGnweGO1QwSj5BpfQjpSJPdqWalja4cTps29Y/PJVG/P7FYlPDkH3hO+Tr0CvDgQ=="
+ },
+ "core-js-compat": {
+ "version": "3.25.1",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.1.tgz",
+ "integrity": "sha512-pOHS7O0i8Qt4zlPW/eIFjwp+NrTPx+wTL0ctgI2fHn31sZOq89rDsmtc/A2vAX7r6shl+bmVI+678He46jgBlw==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.21.3"
+ }
+ },
+ "core-js-pure": {
+ "version": "3.25.1",
+ "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.25.1.tgz",
+ "integrity": "sha512-7Fr74bliUDdeJCBMxkkIuQ4xfxn/SwrVg+HkJUAoNEXVqYLv55l6Af0dJ5Lq2YBUW9yKqSkLXaS5SYPK6MGa/A=="
+ },
+ "core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "dev": true
+ },
+ "cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "dev": true,
+ "requires": {
+ "object-assign": "^4",
+ "vary": "^1"
+ }
+ },
+ "cosmiconfig": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz",
+ "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==",
+ "dev": true,
+ "requires": {
+ "@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"
+ }
+ },
+ "create-ecdh": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
+ "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "elliptic": "^6.5.3"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+ "dev": true
+ }
+ }
+ },
+ "create-hash": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "inherits": "^2.0.1",
+ "md5.js": "^1.3.4",
+ "ripemd160": "^2.0.1",
+ "sha.js": "^2.4.0"
+ }
+ },
+ "create-hmac": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.3",
+ "create-hash": "^1.1.0",
+ "inherits": "^2.0.1",
+ "ripemd160": "^2.0.0",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "critters": {
+ "version": "0.0.12",
+ "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.12.tgz",
+ "integrity": "sha512-ujxKtKc/mWpjrOKeaACTaQ1aP0O31M0ZPWhfl85jZF1smPU4Ivb9va5Ox2poif4zVJQQo0LCFlzGtEZAsCAPcw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.1.0",
+ "css-select": "^4.1.3",
+ "parse5": "^6.0.1",
+ "parse5-htmlparser2-tree-adapter": "^6.0.1",
+ "postcss": "^8.3.7",
+ "pretty-bytes": "^5.3.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "8.4.16",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz",
+ "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==",
+ "dev": true,
+ "requires": {
+ "nanoid": "^3.3.4",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "cross-fetch": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
+ "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
+ "requires": {
+ "node-fetch": "2.6.7"
+ }
+ },
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "crypt": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
+ "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==",
+ "dev": true
+ },
+ "crypto-browserify": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+ "dev": true,
+ "requires": {
+ "browserify-cipher": "^1.0.0",
+ "browserify-sign": "^4.0.0",
+ "create-ecdh": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "create-hmac": "^1.1.0",
+ "diffie-hellman": "^5.0.0",
+ "inherits": "^2.0.1",
+ "pbkdf2": "^3.0.3",
+ "public-encrypt": "^4.0.0",
+ "randombytes": "^2.0.0",
+ "randomfill": "^1.0.3"
+ }
+ },
+ "crypto-js": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz",
+ "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==",
+ "dev": true
+ },
+ "css": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
+ "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "source-map": "^0.6.1",
+ "source-map-resolve": "^0.5.2",
+ "urix": "^0.1.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "css-blank-pseudo": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz",
+ "integrity": "sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.5"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "css-declaration-sorter": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz",
+ "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==",
+ "dev": true
+ },
+ "css-has-pseudo": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz",
+ "integrity": "sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.6",
+ "postcss-selector-parser": "^5.0.0-rc.4"
+ },
+ "dependencies": {
+ "cssesc": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
+ "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
+ "dev": true
+ },
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "postcss-selector-parser": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
+ "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
+ "dev": true,
+ "requires": {
+ "cssesc": "^2.0.0",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "css-loader": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.2.0.tgz",
+ "integrity": "sha512-/rvHfYRjIpymZblf49w8jYcRo2y9gj6rV8UroHGmBxKrIyGLokpycyKzp9OkitvqT29ZSpzJ0Ic7SpnJX3sC8g==",
+ "dev": true,
+ "requires": {
+ "icss-utils": "^5.1.0",
+ "postcss": "^8.2.15",
+ "postcss-modules-extract-imports": "^3.0.0",
+ "postcss-modules-local-by-default": "^4.0.0",
+ "postcss-modules-scope": "^3.0.0",
+ "postcss-modules-values": "^4.0.0",
+ "postcss-value-parser": "^4.1.0",
+ "semver": "^7.3.5"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "css-minimizer-webpack-plugin": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.0.2.tgz",
+ "integrity": "sha512-B3I5e17RwvKPJwsxjjWcdgpU/zqylzK1bPVghcmpFHRL48DXiBgrtqz1BJsn68+t/zzaLp9kYAaEDvQ7GyanFQ==",
+ "dev": true,
+ "requires": {
+ "cssnano": "^5.0.6",
+ "jest-worker": "^27.0.2",
+ "p-limit": "^3.0.2",
+ "postcss": "^8.3.5",
+ "schema-utils": "^3.0.0",
+ "serialize-javascript": "^6.0.0",
+ "source-map": "^0.6.1"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "requires": {
+ "yocto-queue": "^0.1.0"
+ }
+ },
+ "schema-utils": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+ "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "css-parse": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz",
+ "integrity": "sha512-UNIFik2RgSbiTwIW1IsFwXWn6vs+bYdq83LKTSOsx7NJR7WII9dxewkHLltfTLVppoUApHV0118a4RZRI9FLwA==",
+ "dev": true,
+ "requires": {
+ "css": "^2.0.0"
+ }
+ },
+ "css-prefers-color-scheme": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz",
+ "integrity": "sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.5"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "css-select": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
+ "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
+ "dev": true,
+ "requires": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.0.1",
+ "domhandler": "^4.3.1",
+ "domutils": "^2.8.0",
+ "nth-check": "^2.0.1"
+ }
+ },
+ "css-selector-tokenizer": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz",
+ "integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==",
+ "dev": true,
+ "requires": {
+ "cssesc": "^3.0.0",
+ "fastparse": "^1.1.2"
+ }
+ },
+ "css-tree": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
+ "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
+ "dev": true,
+ "requires": {
+ "mdn-data": "2.0.14",
+ "source-map": "^0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "css-what": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+ "dev": true
+ },
+ "css.escape": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
+ "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg=="
+ },
+ "cssauron": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz",
+ "integrity": "sha512-Ht70DcFBh+/ekjVrYS2PlDMdSQEl3OFNmjK6lcn49HptBgilXf/Zwg4uFh9Xn0pX3Q8YOkSjIFOfK2osvdqpBw==",
+ "dev": true,
+ "requires": {
+ "through": "X.X.X"
+ }
+ },
+ "cssdb": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz",
+ "integrity": "sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==",
+ "dev": true
+ },
+ "cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true
+ },
+ "cssfontparser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz",
+ "integrity": "sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg==",
+ "dev": true
+ },
+ "cssnano": {
+ "version": "5.1.13",
+ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.13.tgz",
+ "integrity": "sha512-S2SL2ekdEz6w6a2epXn4CmMKU4K3KpcyXLKfAYc9UQQqJRkD/2eLUG0vJ3Db/9OvO5GuAdgXw3pFbR6abqghDQ==",
+ "dev": true,
+ "requires": {
+ "cssnano-preset-default": "^5.2.12",
+ "lilconfig": "^2.0.3",
+ "yaml": "^1.10.2"
+ }
+ },
+ "cssnano-preset-default": {
+ "version": "5.2.12",
+ "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.12.tgz",
+ "integrity": "sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew==",
+ "dev": true,
+ "requires": {
+ "css-declaration-sorter": "^6.3.0",
+ "cssnano-utils": "^3.1.0",
+ "postcss-calc": "^8.2.3",
+ "postcss-colormin": "^5.3.0",
+ "postcss-convert-values": "^5.1.2",
+ "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.6",
+ "postcss-merge-rules": "^5.1.2",
+ "postcss-minify-font-values": "^5.1.0",
+ "postcss-minify-gradients": "^5.1.1",
+ "postcss-minify-params": "^5.1.3",
+ "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.0",
+ "postcss-normalize-url": "^5.1.0",
+ "postcss-normalize-whitespace": "^5.1.1",
+ "postcss-ordered-values": "^5.1.3",
+ "postcss-reduce-initial": "^5.1.0",
+ "postcss-reduce-transforms": "^5.1.0",
+ "postcss-svgo": "^5.1.0",
+ "postcss-unique-selectors": "^5.1.1"
+ }
+ },
+ "cssnano-utils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz",
+ "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==",
+ "dev": true
+ },
+ "csso": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz",
+ "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==",
+ "dev": true,
+ "requires": {
+ "css-tree": "^1.1.2"
+ }
+ },
+ "cssom": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
+ "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==",
+ "dev": true
+ },
+ "cssstyle": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
+ "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+ "dev": true,
+ "requires": {
+ "cssom": "~0.3.6"
+ },
+ "dependencies": {
+ "cssom": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+ "dev": true
+ }
+ }
+ },
+ "csstype": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz",
+ "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA=="
+ },
+ "cucumber": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/cucumber/-/cucumber-4.2.1.tgz",
+ "integrity": "sha512-3gQ0Vv4kSHsvXEFC6b1c+TfLRDzWD1/kU7e5vm8Kh8j35b95k6favan9/4ixcBNqd7UsU1T6FYcawC87+DlNKw==",
+ "dev": true,
+ "requires": {
+ "assertion-error-formatter": "^2.0.1",
+ "babel-runtime": "^6.11.6",
+ "bluebird": "^3.4.1",
+ "cli-table": "^0.3.1",
+ "colors": "^1.1.2",
+ "commander": "^2.9.0",
+ "cucumber-expressions": "^5.0.13",
+ "cucumber-tag-expressions": "^1.1.1",
+ "duration": "^0.2.0",
+ "escape-string-regexp": "^1.0.5",
+ "figures": "2.0.0",
+ "gherkin": "^5.0.0",
+ "glob": "^7.0.0",
+ "indent-string": "^3.1.0",
+ "is-generator": "^1.0.2",
+ "is-stream": "^1.1.0",
+ "knuth-shuffle-seeded": "^1.0.6",
+ "lodash": "^4.17.4",
+ "mz": "^2.4.0",
+ "progress": "^2.0.0",
+ "resolve": "^1.3.3",
+ "serialize-error": "^2.1.0",
+ "stack-chain": "^2.0.0",
+ "stacktrace-js": "^2.0.0",
+ "string-argv": "0.0.2",
+ "title-case": "^2.1.1",
+ "util-arity": "^1.0.2",
+ "verror": "^1.9.0"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "cucumber-expressions": {
+ "version": "5.0.18",
+ "resolved": "https://registry.npmjs.org/cucumber-expressions/-/cucumber-expressions-5.0.18.tgz",
+ "integrity": "sha512-cj9UKCEvsB7bN97THmowcZt8I3rYFbTAFBNeDpKmWW3vr43CLZeWBmbk7NlHijndLwPJ7+uiF72xWrRU+RLyZA==",
+ "dev": true,
+ "requires": {
+ "becke-ch--regex--s0-0-v1--base--pl--lib": "^1.2.0"
+ }
+ },
+ "figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "indent-string": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
+ "integrity": "sha512-BYqTHXTGUIvg7t1r4sJNKcbDZkL92nkXA8YtRpbjFHRHGDL/NtUeiBJMeE60kIFN/Mg8ESaWQvftaYMGJzQZCQ==",
+ "dev": true
+ },
+ "serialize-error": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz",
+ "integrity": "sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==",
+ "dev": true
+ }
+ }
+ },
+ "cucumber-expressions": {
+ "version": "6.6.2",
+ "resolved": "https://registry.npmjs.org/cucumber-expressions/-/cucumber-expressions-6.6.2.tgz",
+ "integrity": "sha512-WcFSVBiWNLJbIcAAC3t/ACU46vaOKfe1UIF5H3qveoq+Y4XQm9j3YwHurQNufRKBBg8nCnpU7Ttsx7egjS3hwA==",
+ "dev": true,
+ "requires": {
+ "becke-ch--regex--s0-0-v1--base--pl--lib": "^1.2.0"
+ }
+ },
+ "cucumber-messages": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/cucumber-messages/-/cucumber-messages-8.0.0.tgz",
+ "integrity": "sha512-lUnWRMjwA9+KhDec/5xRZV3Du67ISumHnVLywWQXyvzmc4P+Eqx8CoeQrBQoau3Pw1hs4kJLTDyV85hFBF00SQ==",
+ "dev": true,
+ "requires": {
+ "@types/uuid": "^3.4.6",
+ "protobufjs": "^6.8.8",
+ "uuid": "^3.3.3"
+ },
+ "dependencies": {
+ "uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+ "dev": true
+ }
+ }
+ },
+ "cucumber-tag-expressions": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/cucumber-tag-expressions/-/cucumber-tag-expressions-1.1.1.tgz",
+ "integrity": "sha512-V9jv81sR/HaJ87FoidrvHkviXId7KmBcUi7aQPfi+W3nRO30N6GqH6lcp8K+nyiT1DgemRJBPDDeBMS93xJqMQ==",
+ "dev": true
+ },
+ "cypress": {
+ "version": "9.7.0",
+ "resolved": "https://registry.npmjs.org/cypress/-/cypress-9.7.0.tgz",
+ "integrity": "sha512-+1EE1nuuuwIt/N1KXRR2iWHU+OiIt7H28jJDyyI4tiUftId/DrXYEwoDa5+kH2pki1zxnA0r6HrUGHV5eLbF5Q==",
+ "dev": true,
+ "requires": {
+ "@cypress/request": "^2.88.10",
+ "@cypress/xvfb": "^1.2.4",
+ "@types/node": "^14.14.31",
+ "@types/sinonjs__fake-timers": "8.1.1",
+ "@types/sizzle": "^2.3.2",
+ "arch": "^2.2.0",
+ "blob-util": "^2.0.2",
+ "bluebird": "^3.7.2",
+ "buffer": "^5.6.0",
+ "cachedir": "^2.3.0",
+ "chalk": "^4.1.0",
+ "check-more-types": "^2.24.0",
+ "cli-cursor": "^3.1.0",
+ "cli-table3": "~0.6.1",
+ "commander": "^5.1.0",
+ "common-tags": "^1.8.0",
+ "dayjs": "^1.10.4",
+ "debug": "^4.3.2",
+ "enquirer": "^2.3.6",
+ "eventemitter2": "^6.4.3",
+ "execa": "4.1.0",
+ "executable": "^4.1.1",
+ "extract-zip": "2.0.1",
+ "figures": "^3.2.0",
+ "fs-extra": "^9.1.0",
+ "getos": "^3.2.1",
+ "is-ci": "^3.0.0",
+ "is-installed-globally": "~0.4.0",
+ "lazy-ass": "^1.6.0",
+ "listr2": "^3.8.3",
+ "lodash": "^4.17.21",
+ "log-symbols": "^4.0.0",
+ "minimist": "^1.2.6",
+ "ospath": "^1.2.2",
+ "pretty-bytes": "^5.6.0",
+ "proxy-from-env": "1.0.0",
+ "request-progress": "^3.0.0",
+ "semver": "^7.3.2",
+ "supports-color": "^8.1.1",
+ "tmp": "~0.2.1",
+ "untildify": "^4.0.0",
+ "yauzl": "^2.10.0"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "14.18.28",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.28.tgz",
+ "integrity": "sha512-CK2fnrQlIgKlCV3N2kM+Gznb5USlwA1KFX3rJVHmgVk6NJxFPuQ86pAcvKnu37IA4BGlSRz7sEE1lHL1aLZ/eQ==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "commander": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
+ "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "execa": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
+ "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.0",
+ "get-stream": "^5.0.0",
+ "human-signals": "^1.1.1",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.0",
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2",
+ "strip-final-newline": "^2.0.0"
+ }
+ },
+ "fs-extra": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+ "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+ "dev": true,
+ "requires": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true
+ },
+ "npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.0.0"
+ }
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "tmp": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
+ "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
+ "dev": true,
+ "requires": {
+ "rimraf": "^3.0.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "cypress-cucumber-preprocessor": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/cypress-cucumber-preprocessor/-/cypress-cucumber-preprocessor-4.3.1.tgz",
+ "integrity": "sha512-BKUYXqoTeKzkPXohEczDtpAwRCY0ZPtIpfRwJut16yNLqdXQMV+aItwanxe3cbJTFlwg562NAjL4LMdiOhkAjg==",
+ "dev": true,
+ "requires": {
+ "@cypress/browserify-preprocessor": "^3.0.2",
+ "chai": "^4.2.0",
+ "chokidar": "3.5.2",
+ "cosmiconfig": "^4.0.0",
+ "cucumber": "^4.2.1",
+ "cucumber-expressions": "^6.0.1",
+ "cucumber-tag-expressions": "^1.1.1",
+ "dargs": "^7.0.0",
+ "debug": "^3.0.1",
+ "gherkin": "^5.1.0",
+ "glob": "^7.1.2",
+ "js-string-escape": "^1.0.1",
+ "minimist": "^1.2.5",
+ "through": "^2.3.8"
+ },
+ "dependencies": {
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "chokidar": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
+ "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
+ "dev": true,
+ "requires": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "fsevents": "~2.3.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"
+ }
+ },
+ "cosmiconfig": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz",
+ "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==",
+ "dev": true,
+ "requires": {
+ "is-directory": "^0.3.1",
+ "js-yaml": "^3.9.0",
+ "parse-json": "^4.0.0",
+ "require-from-string": "^2.0.1"
+ }
+ },
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ }
+ }
+ },
+ "cypress-file-upload": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/cypress-file-upload/-/cypress-file-upload-5.0.8.tgz",
+ "integrity": "sha512-+8VzNabRk3zG6x8f8BWArF/xA/W0VK4IZNx3MV0jFWrJS/qKn8eHfa5nU73P9fOQAgwHFJx7zjg4lwOnljMO8g==",
+ "dev": true
+ },
+ "cypress-iframe": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cypress-iframe/-/cypress-iframe-1.0.1.tgz",
+ "integrity": "sha512-Ne+xkZmWMhfq3x6wbfzK/SzsVTCrJru3R3cLXsoSAZyfUtJDamXyaIieHXeea3pQDXF4wE2w4iUuvCYHhoD31g==",
+ "dev": true
+ },
+ "cypress-multi-reporters": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/cypress-multi-reporters/-/cypress-multi-reporters-1.5.0.tgz",
+ "integrity": "sha512-6rJ1rk1RpjZwTeydCDc8r3iOmWj2ZEYo++oDTJHNEu7eetb3W1cYDNo5CdxF/r0bo7TLQsOEpBHOCYBZfPVt/g==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "lodash": "^4.17.15"
+ }
+ },
+ "d": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+ "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+ "dev": true,
+ "requires": {
+ "es5-ext": "^0.10.50",
+ "type": "^1.0.1"
+ }
+ },
+ "damerau-levenshtein": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
+ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==",
+ "dev": true
+ },
+ "dargs": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz",
+ "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==",
+ "dev": true
+ },
+ "dash-ast": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-2.0.1.tgz",
+ "integrity": "sha512-5TXltWJGc+RdnabUGzhRae1TRq6m4gr+3K2wQX0is5/F2yS6MJXJvLyI3ErAnsAXuJoGqvfVD5icRgim07DrxQ==",
+ "dev": true
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "data-urls": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz",
+ "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
+ "dev": true,
+ "requires": {
+ "abab": "^2.0.0",
+ "whatwg-mimetype": "^2.2.0",
+ "whatwg-url": "^7.0.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ },
+ "tr46": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+ "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "webidl-conversions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+ "dev": true
+ },
+ "whatwg-url": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+ "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+ "dev": true,
+ "requires": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
+ }
+ }
+ }
+ },
+ "date-format": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/date-format/-/date-format-0.0.0.tgz",
+ "integrity": "sha512-kAmAdtsjW5nQ02FERwI1bP4xe6HQBPwy5kpAF4CRSLOMUs/vgMIEEwpy6JqUs7NitTyhZiImxwAjgPpnteycHg==",
+ "dev": true
+ },
+ "dateformat": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
+ "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==",
+ "dev": true
+ },
+ "dayjs": {
+ "version": "1.11.5",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.5.tgz",
+ "integrity": "sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA==",
+ "dev": true
+ },
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "decache": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/decache/-/decache-4.6.1.tgz",
+ "integrity": "sha512-ohApBM8u9ygepJCjgBrEZSSxPjc0T/PJkD+uNyxXPkqudyUpdXpwJYp0VISm2WrPVzASU6DZyIi6BWdyw7uJ2Q==",
+ "dev": true,
+ "requires": {
+ "callsite": "^1.0.0"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
+ "dev": true
+ },
+ "decamelize-keys": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz",
+ "integrity": "sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==",
+ "dev": true,
+ "requires": {
+ "decamelize": "^1.1.0",
+ "map-obj": "^1.0.0"
+ },
+ "dependencies": {
+ "map-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+ "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
+ "dev": true
+ }
+ }
+ },
+ "decimal.js": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz",
+ "integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==",
+ "dev": true
+ },
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==",
+ "dev": true
+ },
+ "deep-eql": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
+ "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+ "dev": true,
+ "requires": {
+ "type-detect": "^4.0.0"
+ }
+ },
+ "deep-equal": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
+ "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
+ "dev": true,
+ "requires": {
+ "is-arguments": "^1.0.4",
+ "is-date-object": "^1.0.1",
+ "is-regex": "^1.0.4",
+ "object-is": "^1.0.1",
+ "object-keys": "^1.1.1",
+ "regexp.prototype.flags": "^1.2.0"
+ }
+ },
+ "deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
+ },
+ "deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true
+ },
+ "deepmerge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
+ },
+ "default-gateway": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz",
+ "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==",
+ "dev": true,
+ "requires": {
+ "execa": "^1.0.0",
+ "ip-regex": "^2.1.0"
+ }
+ },
+ "defaults": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
+ "integrity": "sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==",
+ "dev": true,
+ "requires": {
+ "clone": "^1.0.2"
+ }
+ },
+ "define-lazy-prop": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
+ "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
+ "dev": true
+ },
+ "define-properties": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
+ "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
+ "dev": true,
+ "requires": {
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ }
+ },
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "dependencies": {
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "defined": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
+ "integrity": "sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==",
+ "dev": true
+ },
+ "del": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz",
+ "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==",
+ "dev": true,
+ "requires": {
+ "@types/glob": "^7.1.1",
+ "globby": "^6.1.0",
+ "is-path-cwd": "^2.0.0",
+ "is-path-in-cwd": "^2.0.0",
+ "p-map": "^2.0.0",
+ "pify": "^4.0.1",
+ "rimraf": "^2.6.3"
+ },
+ "dependencies": {
+ "array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==",
+ "dev": true,
+ "requires": {
+ "array-uniq": "^1.0.1"
+ }
+ },
+ "globby": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+ "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==",
+ "dev": true,
+ "requires": {
+ "array-union": "^1.0.1",
+ "glob": "^7.0.3",
+ "object-assign": "^4.0.1",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "dev": true
+ }
+ }
+ },
+ "p-map": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
+ "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "dev": true
+ },
+ "delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
+ "dev": true
+ },
+ "depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "dev": true
+ },
+ "dependency-graph": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz",
+ "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==",
+ "dev": true
+ },
+ "deps-sort": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz",
+ "integrity": "sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "shasum-object": "^1.0.0",
+ "subarg": "^1.0.0",
+ "through2": "^2.0.0"
+ }
+ },
+ "des.js": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
+ "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "dev": true
+ },
+ "detect-browser": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.2.0.tgz",
+ "integrity": "sha512-tr7XntDAu50BVENgQfajMLzacmSe34D+qZc4zjnniz0ZVuw/TZcLcyxHQjYpJTM36sGEkZZlYLnIM1hH7alTMA=="
+ },
+ "detect-file": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+ "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
+ "dev": true
+ },
+ "detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "dev": true
+ },
+ "detect-node": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
+ "dev": true
+ },
+ "detective": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz",
+ "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==",
+ "dev": true,
+ "requires": {
+ "acorn-node": "^1.8.2",
+ "defined": "^1.0.0",
+ "minimist": "^1.2.6"
+ }
+ },
+ "devtools-protocol": {
+ "version": "0.0.927104",
+ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.927104.tgz",
+ "integrity": "sha512-5jfffjSuTOv0Lz53wTNNTcCUV8rv7d82AhYcapj28bC2B5tDxEZzVb7k51cNxZP2KHw24QE+sW7ZuSeD9NfMpA==",
+ "dev": true
+ },
+ "dfa": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz",
+ "integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==",
+ "dev": true
+ },
+ "diff": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
+ "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
+ "dev": true
+ },
+ "diff-sequences": {
+ "version": "25.2.6",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz",
+ "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==",
+ "dev": true
+ },
+ "diffie-hellman": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+ "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "miller-rabin": "^4.0.0",
+ "randombytes": "^2.0.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+ "dev": true
+ }
+ }
+ },
+ "dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "requires": {
+ "path-type": "^4.0.0"
+ }
+ },
+ "dns-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
+ "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==",
+ "dev": true
+ },
+ "dns-packet": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz",
+ "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==",
+ "dev": true,
+ "requires": {
+ "ip": "^1.1.0",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "dns-txt": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
+ "integrity": "sha512-Ix5PrWjphuSoUXV/Zv5gaFHjnaJtb02F2+Si3Ht9dyJ87+Z/lMmy+dpNHtTGraNK958ndXq2i+GLkWsWHcKaBQ==",
+ "dev": true,
+ "requires": {
+ "buffer-indexof": "^1.0.0"
+ }
+ },
+ "dom-serializer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
+ "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.2.0",
+ "entities": "^2.0.0"
+ }
+ },
+ "domain-browser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+ "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
+ "dev": true
+ },
+ "domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true
+ },
+ "domexception": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
+ "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
+ "dev": true,
+ "requires": {
+ "webidl-conversions": "^4.0.2"
+ },
+ "dependencies": {
+ "webidl-conversions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+ "dev": true
+ }
+ }
+ },
+ "domhandler": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
+ "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^2.2.0"
+ }
+ },
+ "dompurify": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.3.tgz",
+ "integrity": "sha512-dqnqRkPMAjOZE0FogZ+ceJNM2dZ3V/yNOuFB7+39qpO93hHhfRpHw3heYQC7DPK9FqbQTfBKUJhiSfz4MvXYwg=="
+ },
+ "domutils": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
+ "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+ "dev": true,
+ "requires": {
+ "dom-serializer": "^1.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.2.0"
+ }
+ },
+ "dot": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/dot/-/dot-1.1.3.tgz",
+ "integrity": "sha512-/nt74Rm+PcfnirXGEdhZleTwGC2LMnuKTeeTIlI82xb5loBBoXNYzr2ezCroPSMtilK8EZIfcNZwOcHN+ib1Lg==",
+ "dev": true
+ },
+ "drange": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/drange/-/drange-1.1.1.tgz",
+ "integrity": "sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA=="
+ },
+ "duplexer": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
+ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
+ "dev": true
+ },
+ "duplexer2": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+ "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.2"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "duration": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/duration/-/duration-0.2.2.tgz",
+ "integrity": "sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg==",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.46"
+ }
+ },
+ "ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
+ "dev": true,
+ "requires": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "dev": true
+ },
+ "electron-to-chromium": {
+ "version": "1.4.246",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.246.tgz",
+ "integrity": "sha512-/wFCHUE+Hocqr/LlVGsuKLIw4P2lBWwFIDcNMDpJGzyIysQV4aycpoOitAs32FT94EHKnNqDR/CVZJFbXEufJA==",
+ "dev": true
+ },
+ "elliptic": {
+ "version": "6.5.4",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
+ "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.11.9",
+ "brorand": "^1.1.0",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.1",
+ "inherits": "^2.0.4",
+ "minimalistic-assert": "^1.0.1",
+ "minimalistic-crypto-utils": "^1.0.1"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+ "dev": true
+ }
+ }
+ },
+ "emittery": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz",
+ "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "emojis-list": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+ "dev": true
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "dev": true
+ },
+ "encoding": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+ "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "iconv-lite": "^0.6.2"
+ },
+ "dependencies": {
+ "iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ }
+ }
+ }
+ },
+ "end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "enhanced-resolve": {
+ "version": "5.10.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz",
+ "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ }
+ },
+ "enquirer": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+ "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+ "dev": true,
+ "requires": {
+ "ansi-colors": "^4.1.1"
+ }
+ },
+ "entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "dev": true
+ },
+ "env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "dev": true
+ },
+ "err-code": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
+ "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
+ "dev": true
+ },
+ "errno": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
+ "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
+ "dev": true,
+ "requires": {
+ "prr": "~1.0.1"
+ }
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "error-stack-parser": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz",
+ "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==",
+ "dev": true,
+ "requires": {
+ "stackframe": "^1.3.4"
+ }
+ },
+ "es-abstract": {
+ "version": "1.20.2",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.2.tgz",
+ "integrity": "sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "function.prototype.name": "^1.1.5",
+ "get-intrinsic": "^1.1.2",
+ "get-symbol-description": "^1.0.0",
+ "has": "^1.0.3",
+ "has-property-descriptors": "^1.0.0",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.3",
+ "is-callable": "^1.2.4",
+ "is-negative-zero": "^2.0.2",
+ "is-regex": "^1.1.4",
+ "is-shared-array-buffer": "^1.0.2",
+ "is-string": "^1.0.7",
+ "is-weakref": "^1.0.2",
+ "object-inspect": "^1.12.2",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.4",
+ "regexp.prototype.flags": "^1.4.3",
+ "string.prototype.trimend": "^1.0.5",
+ "string.prototype.trimstart": "^1.0.5",
+ "unbox-primitive": "^1.0.2"
+ }
+ },
+ "es-module-lexer": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz",
+ "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==",
+ "dev": true
+ },
+ "es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
+ "es5-ext": {
+ "version": "0.10.62",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz",
+ "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==",
+ "dev": true,
+ "requires": {
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.3",
+ "next-tick": "^1.1.0"
+ }
+ },
+ "es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "es6-map": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
+ "integrity": "sha512-mz3UqCh0uPCIqsw1SSAkB/p0rOzF/M0V++vyN7JqlPtSW/VsYgQBvVvqMLmfBuyMzTpLnNqi6JmcSizs4jy19A==",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14",
+ "es6-iterator": "~2.0.1",
+ "es6-set": "~0.1.5",
+ "es6-symbol": "~3.1.1",
+ "event-emitter": "~0.3.5"
+ }
+ },
+ "es6-set": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.6.tgz",
+ "integrity": "sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw==",
+ "dev": true,
+ "requires": {
+ "d": "^1.0.1",
+ "es5-ext": "^0.10.62",
+ "es6-iterator": "~2.0.3",
+ "es6-symbol": "^3.1.3",
+ "event-emitter": "^0.3.5",
+ "type": "^2.7.2"
+ },
+ "dependencies": {
+ "type": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
+ "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==",
+ "dev": true
+ }
+ }
+ },
+ "es6-symbol": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+ "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+ "dev": true,
+ "requires": {
+ "d": "^1.0.1",
+ "ext": "^1.1.2"
+ }
+ },
+ "esbuild-android-arm64": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.13.8.tgz",
+ "integrity": "sha512-AilbChndywpk7CdKkNSZ9klxl+9MboLctXd9LwLo3b0dawmOF/i/t2U5d8LM6SbT1Xw36F8yngSUPrd8yPs2RA==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-darwin-64": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.13.8.tgz",
+ "integrity": "sha512-b6sdiT84zV5LVaoF+UoMVGJzR/iE2vNUfUDfFQGrm4LBwM/PWXweKpuu6RD9mcyCq18cLxkP6w/LD/w9DtX3ng==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-darwin-arm64": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.8.tgz",
+ "integrity": "sha512-R8YuPiiJayuJJRUBG4H0VwkEKo6AvhJs2m7Tl0JaIer3u1FHHXwGhMxjJDmK+kXwTFPriSysPvcobXC/UrrZCQ==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-freebsd-64": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.8.tgz",
+ "integrity": "sha512-zBn6urrn8FnKC+YSgDxdof9jhPCeU8kR/qaamlV4gI8R3KUaUK162WYM7UyFVAlj9N0MyD3AtB+hltzu4cysTw==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-freebsd-arm64": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.8.tgz",
+ "integrity": "sha512-pWW2slN7lGlkx0MOEBoUGwRX5UgSCLq3dy2c8RIOpiHtA87xAUpDBvZK10MykbT+aMfXc0NI2lu1X+6kI34xng==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-linux-32": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.13.8.tgz",
+ "integrity": "sha512-T0I0ueeKVO/Is0CAeSEOG9s2jeNNb8jrrMwG9QBIm3UU18MRB60ERgkS2uV3fZ1vP2F8i3Z2e3Zju4lg9dhVmw==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-linux-64": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.8.tgz",
+ "integrity": "sha512-Bm8SYmFtvfDCIu9sjKppFXzRXn2BVpuCinU1ChTuMtdKI/7aPpXIrkqBNOgPTOQO9AylJJc1Zw6EvtKORhn64w==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-linux-arm": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.13.8.tgz",
+ "integrity": "sha512-4/HfcC40LJ4GPyboHA+db0jpFarTB628D1ifU+/5bunIgY+t6mHkJWyxWxAAE8wl/ZIuRYB9RJFdYpu1AXGPdg==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-linux-arm64": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.8.tgz",
+ "integrity": "sha512-X4pWZ+SL+FJ09chWFgRNO3F+YtvAQRcWh0uxKqZSWKiWodAB20flsW/OWFYLXBKiVCTeoGMvENZS/GeVac7+tQ==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-linux-mips64le": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.8.tgz",
+ "integrity": "sha512-o7e0D+sqHKT31v+mwFircJFjwSKVd2nbkHEn4l9xQ1hLR+Bv8rnt3HqlblY3+sBdlrOTGSwz0ReROlKUMJyldA==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-linux-ppc64le": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.8.tgz",
+ "integrity": "sha512-eZSQ0ERsWkukJp2px/UWJHVNuy0lMoz/HZcRWAbB6reoaBw7S9vMzYNUnflfL3XA6WDs+dZn3ekHE4Y2uWLGig==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-netbsd-64": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.13.8.tgz",
+ "integrity": "sha512-gZX4kP7gVvOrvX0ZwgHmbuHczQUwqYppxqtoyC7VNd80t5nBHOFXVhWo2Ad/Lms0E8b+wwgI/WjZFTCpUHOg9Q==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-openbsd-64": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.8.tgz",
+ "integrity": "sha512-afzza308X4WmcebexbTzAgfEWt9MUkdTvwIa8xOu4CM2qGbl2LanqEl8/LUs8jh6Gqw6WsicEK52GPrS9wvkcw==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-sunos-64": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.13.8.tgz",
+ "integrity": "sha512-mWPZibmBbuMKD+LDN23LGcOZ2EawMYBONMXXHmbuxeT0XxCNwadbCVwUQ/2p5Dp5Kvf6mhrlIffcnWOiCBpiVw==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-wasm": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.13.8.tgz",
+ "integrity": "sha512-UbD+3nloiSpJWXTCInZQrqPe8Y+RLfDkY/5kEHiXsw/lmaEvibe69qTzQu16m5R9je/0bF7VYQ5jaEOq0z9lLA==",
+ "dev": true
+ },
+ "esbuild-windows-32": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.13.8.tgz",
+ "integrity": "sha512-QsZ1HnWIcnIEApETZWw8HlOhDSWqdZX2SylU7IzGxOYyVcX7QI06ety/aDcn437mwyO7Ph4RrbhB+2ntM8kX8A==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-windows-64": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.13.8.tgz",
+ "integrity": "sha512-76Fb57B9eE/JmJi1QmUW0tRLQZfGo0it+JeYoCDTSlbTn7LV44ecOHIMJSSgZADUtRMWT9z0Kz186bnaB3amSg==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-windows-arm64": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.8.tgz",
+ "integrity": "sha512-HW6Mtq5eTudllxY2YgT62MrVcn7oq2o8TAoAvDUhyiEmRmDY8tPwAhb1vxw5/cdkbukM3KdMYtksnUhF/ekWeg==",
+ "dev": true,
+ "optional": true
+ },
+ "escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
+ },
+ "escodegen": {
+ "version": "1.14.3",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
+ "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
+ "dev": true,
+ "requires": {
+ "esprima": "^4.0.1",
+ "estraverse": "^4.2.0",
+ "esutils": "^2.0.2",
+ "optionator": "^0.8.1",
+ "source-map": "~0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.2.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true
+ }
+ }
+ },
+ "estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true
+ },
+ "estree-is-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/estree-is-function/-/estree-is-function-1.0.0.tgz",
+ "integrity": "sha512-nSCWn1jkSq2QAtkaVLJZY2ezwcFO161HVc174zL1KPW3RJ+O6C3eJb8Nx7OXzvhoEv+nLgSR1g71oWUHUDTrJA==",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true
+ },
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "dev": true
+ },
+ "event-emitter": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+ "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14"
+ }
+ },
+ "event-stream": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz",
+ "integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==",
+ "dev": true,
+ "requires": {
+ "duplexer": "^0.1.1",
+ "from": "^0.1.7",
+ "map-stream": "0.0.7",
+ "pause-stream": "^0.0.11",
+ "split": "^1.0.1",
+ "stream-combiner": "^0.2.2",
+ "through": "^2.3.8"
+ }
+ },
+ "event-target-shim": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
+ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
+ "dev": true
+ },
+ "eventemitter-asyncresource": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz",
+ "integrity": "sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==",
+ "dev": true
+ },
+ "eventemitter2": {
+ "version": "6.4.8",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.8.tgz",
+ "integrity": "sha512-pAJurPyD+Nj/pfz8m0usKF1RW0E9gfY4Dfdem2l6jZbqcZlK8SP93qUMCv9V9FgOn+GSZEW6qeaglpf/vQ9D5A==",
+ "dev": true
+ },
+ "eventemitter3": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+ "dev": true
+ },
+ "events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "dev": true
+ },
+ "eventsource": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz",
+ "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==",
+ "dev": true
+ },
+ "evp_bytestokey": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+ "dev": true,
+ "requires": {
+ "md5.js": "^1.3.4",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "exec-sh": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz",
+ "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==",
+ "dev": true
+ },
+ "execa": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ }
+ },
+ "execall": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz",
+ "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==",
+ "dev": true,
+ "requires": {
+ "clone-regexp": "^2.1.0"
+ }
+ },
+ "executable": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz",
+ "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==",
+ "dev": true,
+ "requires": {
+ "pify": "^2.2.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "dev": true
+ }
+ }
+ },
+ "exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
+ "dev": true
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ }
+ }
+ },
+ "expand-tilde": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+ "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
+ "dev": true,
+ "requires": {
+ "homedir-polyfill": "^1.0.1"
+ }
+ },
+ "expect": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz",
+ "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "ansi-styles": "^4.0.0",
+ "jest-get-type": "^26.3.0",
+ "jest-matcher-utils": "^26.6.2",
+ "jest-message-util": "^26.6.2",
+ "jest-regex-util": "^26.0.0"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "jest-get-type": {
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
+ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "express": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz",
+ "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==",
+ "dev": true,
+ "requires": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.20.0",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.5.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.10.3",
+ "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"
+ },
+ "dependencies": {
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.10.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
+ "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
+ "dev": true,
+ "requires": {
+ "side-channel": "^1.0.4"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ }
+ }
+ },
+ "ext": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
+ "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
+ "dev": true,
+ "requires": {
+ "type": "^2.7.2"
+ },
+ "dependencies": {
+ "type": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
+ "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==",
+ "dev": true
+ }
+ }
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "dev": true
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ },
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ }
+ }
+ },
+ "external-editor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+ "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+ "dev": true,
+ "requires": {
+ "chardet": "^0.7.0",
+ "iconv-lite": "^0.4.24",
+ "tmp": "^0.0.33"
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "extract-zip": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
+ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
+ "dev": true,
+ "requires": {
+ "@types/yauzl": "^2.9.1",
+ "debug": "^4.1.1",
+ "get-stream": "^5.1.0",
+ "yauzl": "^2.10.0"
+ },
+ "dependencies": {
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ }
+ }
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
+ "dev": true
+ },
+ "fancy-log": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz",
+ "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==",
+ "dev": true,
+ "requires": {
+ "ansi-gray": "^0.1.1",
+ "color-support": "^1.1.3",
+ "parse-node-version": "^1.0.0",
+ "time-stamp": "^1.0.0"
+ }
+ },
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "fast-glob": {
+ "version": "3.2.11",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
+ "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
+ "dev": true,
+ "requires": {
+ "@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"
+ },
+ "dependencies": {
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ }
+ }
+ },
+ "fast-json-patch": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz",
+ "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ=="
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true
+ },
+ "fast-safe-stringify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
+ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
+ "dev": true
+ },
+ "fastest-levenshtein": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+ "dev": true
+ },
+ "fastparse": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
+ "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
+ "dev": true
+ },
+ "fastq": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
+ "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
+ "dev": true,
+ "requires": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "fault": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz",
+ "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==",
+ "requires": {
+ "format": "^0.2.0"
+ }
+ },
+ "faye-websocket": {
+ "version": "0.11.4",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
+ "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
+ "dev": true,
+ "requires": {
+ "websocket-driver": ">=0.5.1"
+ }
+ },
+ "fb-watchman": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
+ "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==",
+ "dev": true,
+ "requires": {
+ "bser": "2.1.1"
+ }
+ },
+ "fd-slicer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+ "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
+ "dev": true,
+ "requires": {
+ "pend": "~1.2.0"
+ }
+ },
+ "figures": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
+ "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^3.0.4"
+ }
+ },
+ "file-saver": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.2.tgz",
+ "integrity": "sha512-Wz3c3XQ5xroCxd1G8b7yL0Ehkf0TC9oYC6buPFkNnU9EnaPlifeAFCyCh+iewXTyFRcg0a6j3J7FmJsIhlhBdw=="
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "finalhandler": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
+ "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
+ "dev": true,
+ "requires": {
+ "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"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ }
+ }
+ },
+ "find-cache-dir": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
+ "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
+ "dev": true,
+ "requires": {
+ "commondir": "^1.0.1",
+ "make-dir": "^3.0.2",
+ "pkg-dir": "^4.1.0"
+ }
+ },
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "findit2": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz",
+ "integrity": "sha512-lg/Moejf4qXovVutL0Lz4IsaPoNYMuxt4PA0nGqFxnJ1CTTGGlEO2wKgoDpwknhvZ8k4Q2F+eesgkLbG2Mxfog==",
+ "dev": true
+ },
+ "findup-sync": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
+ "integrity": "sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g==",
+ "dev": true,
+ "requires": {
+ "detect-file": "^1.0.0",
+ "is-glob": "^3.1.0",
+ "micromatch": "^3.0.4",
+ "resolve-dir": "^1.0.1"
+ },
+ "dependencies": {
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ }
+ }
+ }
+ },
+ "fined": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz",
+ "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "^2.0.2",
+ "is-plain-object": "^2.0.3",
+ "object.defaults": "^1.1.0",
+ "object.pick": "^1.2.0",
+ "parse-filepath": "^1.0.1"
+ },
+ "dependencies": {
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ }
+ }
+ },
+ "flagged-respawn": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
+ "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==",
+ "dev": true
+ },
+ "flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "dev": true
+ },
+ "flat-cache": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
+ "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+ "dev": true,
+ "requires": {
+ "flatted": "^3.1.0",
+ "rimraf": "^3.0.2"
+ }
+ },
+ "flatted": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
+ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
+ "dev": true
+ },
+ "flatten": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz",
+ "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==",
+ "dev": true
+ },
+ "follow-redirects": {
+ "version": "1.15.1",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
+ "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
+ "dev": true
+ },
+ "for-each": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+ "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==",
+ "dev": true
+ },
+ "for-own": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+ "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==",
+ "dev": true,
+ "requires": {
+ "for-in": "^1.0.1"
+ }
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
+ "dev": true
+ },
+ "fork-awesome": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/fork-awesome/-/fork-awesome-1.1.7.tgz",
+ "integrity": "sha512-IHI7XCSXrKfUIWslse8c/PaaVDT1oBaYge+ju40ihL2ooiQeBpTr4wvIXhgTd2NuhntlvX+M5jYHAPTzNlmv0g=="
+ },
+ "form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "form-data-encoder": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz",
+ "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A=="
+ },
+ "format": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
+ "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww=="
+ },
+ "formdata-node": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz",
+ "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==",
+ "requires": {
+ "node-domexception": "1.0.0",
+ "web-streams-polyfill": "4.0.0-beta.3"
+ }
+ },
+ "forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "dev": true
+ },
+ "fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==",
+ "dev": true,
+ "requires": {
+ "map-cache": "^0.2.2"
+ }
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "dev": true
+ },
+ "from": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
+ "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==",
+ "dev": true
+ },
+ "fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ }
+ },
+ "fs-minipass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "fs-monkey": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz",
+ "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==",
+ "dev": true
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
+ },
+ "fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "optional": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "function.prototype.name": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
+ "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.19.0",
+ "functions-have-names": "^1.2.2"
+ }
+ },
+ "functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true
+ },
+ "gauge": {
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+ "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==",
+ "dev": true,
+ "requires": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==",
+ "dev": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ }
+ }
+ },
+ "gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="
+ },
+ "get-assigned-identifiers": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz",
+ "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==",
+ "dev": true
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
+ },
+ "get-func-name": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+ "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==",
+ "dev": true
+ },
+ "get-intrinsic": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
+ "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.3"
+ }
+ },
+ "get-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "dev": true
+ },
+ "get-stdin": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
+ "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
+ "dev": true
+ },
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "get-symbol-description": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
+ "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.1"
+ }
+ },
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==",
+ "dev": true
+ },
+ "getos": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz",
+ "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==",
+ "dev": true,
+ "requires": {
+ "async": "^3.2.0"
+ },
+ "dependencies": {
+ "async": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
+ "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==",
+ "dev": true
+ }
+ }
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "gherkin": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/gherkin/-/gherkin-5.1.0.tgz",
+ "integrity": "sha512-axTCsxH0m0cixijLvo7s9591h5pMb8ifQxFDun5FnfFhVsUhxgdnH0H7TSK7q8I4ASUU18DJ/tmlnMegMuLUUQ==",
+ "dev": true
+ },
+ "gherkin-lint": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/gherkin-lint/-/gherkin-lint-4.2.2.tgz",
+ "integrity": "sha512-+vu0wbrwxaaEdrheU9pH2MYR6zk38u2IkrCIg6IETUw1lkrNVAfIfOCihwrrL2NTJv5Iia/C7hZEBNwjGSkL2Q==",
+ "dev": true,
+ "requires": {
+ "commander": "5.0.0",
+ "core-js": "3.6.4",
+ "gherkin": "9.0.0",
+ "glob": "7.1.6",
+ "lodash": "4.17.21",
+ "strip-json-comments": "3.0.1",
+ "xml-js": "^1.6.11"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-5.0.0.tgz",
+ "integrity": "sha512-JrDGPAKjMGSP1G0DUoaceEJ3DZgAfr/q6X7FVk4+U5KxUSKviYGM2k6zWkfyyBHy5rAtzgYJFa1ro2O9PtoxwQ==",
+ "dev": true
+ },
+ "core-js": {
+ "version": "3.6.4",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz",
+ "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==",
+ "dev": true
+ },
+ "gherkin": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/gherkin/-/gherkin-9.0.0.tgz",
+ "integrity": "sha512-6xoAepoxo5vhkBXjB4RCfVnSKHu5z9SqXIQVUyj+Jw8BQX8odATlee5otXgdN8llZvyvHokuvNiBeB3naEnnIQ==",
+ "dev": true,
+ "requires": {
+ "commander": "^4.0.1",
+ "cucumber-messages": "8.0.0",
+ "source-map-support": "^0.5.16"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true
+ }
+ }
+ },
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "strip-json-comments": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
+ "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
+ "dev": true
+ }
+ }
+ },
+ "glob": {
+ "version": "7.1.7",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+ "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.3"
+ }
+ },
+ "glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "dev": true
+ },
+ "global-dirs": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz",
+ "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==",
+ "dev": true,
+ "requires": {
+ "ini": "2.0.0"
+ }
+ },
+ "global-modules": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
+ "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+ "dev": true,
+ "requires": {
+ "global-prefix": "^1.0.1",
+ "is-windows": "^1.0.1",
+ "resolve-dir": "^1.0.0"
+ }
+ },
+ "global-prefix": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+ "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "^2.0.2",
+ "homedir-polyfill": "^1.0.1",
+ "ini": "^1.3.4",
+ "is-windows": "^1.0.1",
+ "which": "^1.2.14"
+ },
+ "dependencies": {
+ "ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true
+ }
+ }
+ },
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
+ },
+ "globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "globjoin": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz",
+ "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==",
+ "dev": true
+ },
+ "gonzales-pe": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz",
+ "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.5"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "dev": true
+ },
+ "growl": {
+ "version": "1.10.5",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+ "dev": true
+ },
+ "growly": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
+ "integrity": "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==",
+ "dev": true,
+ "optional": true
+ },
+ "handle-thing": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
+ "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==",
+ "dev": true
+ },
+ "handlebars": {
+ "version": "4.7.7",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
+ "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.5",
+ "neo-async": "^2.6.0",
+ "source-map": "^0.6.1",
+ "uglify-js": "^3.1.4",
+ "wordwrap": "^1.0.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==",
+ "dev": true
+ },
+ "har-validator": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+ "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.12.3",
+ "har-schema": "^2.0.0"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ }
+ }
+ },
+ "hard-rejection": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
+ "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
+ "dev": true
+ },
+ "harmony-reflect": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz",
+ "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==",
+ "dev": true
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-bigints": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
+ },
+ "has-property-descriptors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+ "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+ "dev": true,
+ "requires": {
+ "get-intrinsic": "^1.1.1"
+ }
+ },
+ "has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
+ },
+ "has-tostringtag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+ "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.2"
+ }
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
+ "dev": true
+ },
+ "has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.6",
+ "has-values": "^1.0.0",
+ "isobject": "^3.0.0"
+ }
+ },
+ "has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "kind-of": "^4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "hash-base": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
+ "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.6.0",
+ "safe-buffer": "^5.2.0"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ }
+ }
+ },
+ "hash.js": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+ "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.1"
+ }
+ },
+ "hast-util-parse-selector": {
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
+ "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ=="
+ },
+ "hastscript": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz",
+ "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==",
+ "requires": {
+ "@types/hast": "^2.0.0",
+ "comma-separated-tokens": "^1.0.0",
+ "hast-util-parse-selector": "^2.0.0",
+ "property-information": "^5.0.0",
+ "space-separated-tokens": "^1.0.0"
+ }
+ },
+ "hdr-histogram-js": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/hdr-histogram-js/-/hdr-histogram-js-2.0.3.tgz",
+ "integrity": "sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g==",
+ "dev": true,
+ "requires": {
+ "@assemblyscript/loader": "^0.10.1",
+ "base64-js": "^1.2.0",
+ "pako": "^1.0.3"
+ }
+ },
+ "hdr-histogram-percentiles-obj": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/hdr-histogram-percentiles-obj/-/hdr-histogram-percentiles-obj-3.0.0.tgz",
+ "integrity": "sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw==",
+ "dev": true
+ },
+ "he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true
+ },
+ "highlight.js": {
+ "version": "10.7.3",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
+ "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="
+ },
+ "hmac-drbg": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+ "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==",
+ "dev": true,
+ "requires": {
+ "hash.js": "^1.0.3",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "requires": {
+ "react-is": "^16.7.0"
+ }
+ },
+ "homedir-polyfill": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+ "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+ "dev": true,
+ "requires": {
+ "parse-passwd": "^1.0.0"
+ }
+ },
+ "hosted-git-info": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+ "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "hpack.js": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
+ "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "obuf": "^1.0.0",
+ "readable-stream": "^2.0.1",
+ "wbuf": "^1.1.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "html-encoding-sniffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
+ "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
+ "dev": true,
+ "requires": {
+ "whatwg-encoding": "^1.0.1"
+ }
+ },
+ "html-entities": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz",
+ "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==",
+ "dev": true
+ },
+ "html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
+ "html-linter": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/html-linter/-/html-linter-1.1.1.tgz",
+ "integrity": "sha512-DJfLevdq+YmY4R7yMdD0zaCAJOvWihg+eCe5o/jeTw86grvgmvSCIwBv1mDi+UdeJP9mDoi5rB6KtcFOn8StrA==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "commander": "^2.12.2",
+ "glob": "^7.1.2"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ }
+ }
+ },
+ "html-tags": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz",
+ "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==",
+ "dev": true
+ },
+ "htmlescape": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz",
+ "integrity": "sha512-eVcrzgbR4tim7c7soKQKtxa/kQM4TzjnlU83rcZ9bHU6t31ehfV7SktN6McWgwPWg+JYMA/O3qpGxBvFq1z2Jg==",
+ "dev": true
+ },
+ "htmllint": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/htmllint/-/htmllint-0.7.3.tgz",
+ "integrity": "sha512-h8wfCu0CC0FVo18Jkygv7xqj0fa23Xlv4QsR2n34LDr8eqpf4glfbNg1HTbiCqpT3ONioMOfk8EkFUbZgrO1KA==",
+ "dev": true,
+ "requires": {
+ "bulk-require": "^1.0.1",
+ "htmlparser2": "^3.10.0",
+ "lodash": "^4.17.11",
+ "promise": "^8.0.2"
+ },
+ "dependencies": {
+ "asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
+ "dev": true
+ },
+ "dom-serializer": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
+ "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^2.0.1",
+ "entities": "^2.0.0"
+ },
+ "dependencies": {
+ "domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true
+ },
+ "entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "dev": true
+ }
+ }
+ },
+ "domelementtype": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+ "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
+ "dev": true
+ },
+ "domhandler": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
+ "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1"
+ }
+ },
+ "domutils": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
+ "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
+ "dev": true,
+ "requires": {
+ "dom-serializer": "0",
+ "domelementtype": "1"
+ }
+ },
+ "entities": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+ "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
+ "dev": true
+ },
+ "htmlparser2": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
+ "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^1.3.1",
+ "domhandler": "^2.3.0",
+ "domutils": "^1.5.1",
+ "entities": "^1.1.1",
+ "inherits": "^2.0.1",
+ "readable-stream": "^3.1.1"
+ }
+ },
+ "promise": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-8.2.0.tgz",
+ "integrity": "sha512-+CMAlLHqwRYwBMXKCP+o8ns7DN+xHDUiI+0nArsiJ9y+kJVPLFxEaSw6Ha9s9H0tftxg2Yzl25wqj9G7m5wLZg==",
+ "dev": true,
+ "requires": {
+ "asap": "~2.0.6"
+ }
+ }
+ }
+ },
+ "htmllint-cli": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/htmllint-cli/-/htmllint-cli-0.0.7.tgz",
+ "integrity": "sha512-JREMzimj1HGrOUcA/FMMweLpHD5YRD1E5RnzXa4dj5m1zQ+6YYLklAGdaTar+qAGaj1Jasb3mGhH6FuKuLGWAQ==",
+ "dev": true,
+ "requires": {
+ "bluebird": "^3.5.1",
+ "chalk": "^2.4.0",
+ "cjson": "^0.5.0",
+ "glob": "^7.1.2",
+ "htmllint": "^0.7.2",
+ "liftoff": "^2.5.0",
+ "semver": "^5.5.0",
+ "yargs": "^11.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
+ "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==",
+ "dev": true
+ },
+ "cliui": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
+ "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^2.1.1",
+ "strip-ansi": "^4.0.0",
+ "wrap-ansi": "^2.0.0"
+ }
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^2.0.0"
+ }
+ },
+ "get-caller-file": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
+ "dev": true
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "requires": {
+ "p-try": "^1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^1.1.0"
+ }
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+ "dev": true
+ },
+ "require-main-filename": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==",
+ "dev": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ }
+ }
+ },
+ "y18n": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
+ "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "11.1.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.1.tgz",
+ "integrity": "sha512-PRU7gJrJaXv3q3yQZ/+/X6KBswZiaQ+zOmdprZcouPYtQgvNU35i+68M4b1ZHLZtYFT5QObFLV+ZkmJYcwKdiw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^4.0.0",
+ "decamelize": "^1.1.1",
+ "find-up": "^2.1.0",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^3.1.0",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^2.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^9.0.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz",
+ "integrity": "sha512-CswCfdOgCr4MMsT1GzbEJ7Z2uYudWyrGX8Bgh/0eyCzj/DXWdKq6a/ADufkzI1WAOIW6jYaXJvRyLhDO0kfqBw==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^4.1.0"
+ }
+ }
+ }
+ },
+ "htmlparser2": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
+ "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "entities": "^4.3.0"
+ },
+ "dependencies": {
+ "dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ }
+ },
+ "domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^2.3.0"
+ }
+ },
+ "domutils": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
+ "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
+ "dev": true,
+ "requires": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.1"
+ }
+ },
+ "entities": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
+ "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
+ "dev": true
+ }
+ }
+ },
+ "http-auth": {
+ "version": "4.1.9",
+ "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-4.1.9.tgz",
+ "integrity": "sha512-kvPYxNGc9EKGTXvOMnTBQw2RZfuiSihK/mLw/a4pbtRueTE45S55Lw/3k5CktIf7Ak0veMKEIteDj4YkNmCzmQ==",
+ "dev": true,
+ "requires": {
+ "apache-crypt": "^1.1.2",
+ "apache-md5": "^1.0.6",
+ "bcryptjs": "^2.4.3",
+ "uuid": "^8.3.2"
+ }
+ },
+ "http-auth-connect": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/http-auth-connect/-/http-auth-connect-1.0.5.tgz",
+ "integrity": "sha512-zykAOKpVAXyzhOLm6+xyB/RtRcfN3uDfH4Al73DIfeSb6B7nr0WToLI6UyyM6ohtcLmbBPksWXzVbEDStz8ObQ==",
+ "dev": true
+ },
+ "http-cache-semantics": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+ "dev": true
+ },
+ "http-deceiver": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
+ "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==",
+ "dev": true
+ },
+ "http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "dev": true,
+ "requires": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ }
+ },
+ "http-parser-js": {
+ "version": "0.5.8",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz",
+ "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==",
+ "dev": true
+ },
+ "http-proxy": {
+ "version": "1.18.1",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
+ "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+ "dev": true,
+ "requires": {
+ "eventemitter3": "^4.0.0",
+ "follow-redirects": "^1.0.0",
+ "requires-port": "^1.0.0"
+ }
+ },
+ "http-proxy-agent": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
+ "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+ "dev": true,
+ "requires": {
+ "@tootallnate/once": "1",
+ "agent-base": "6",
+ "debug": "4"
+ }
+ },
+ "http-proxy-middleware": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz",
+ "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
+ "dev": true,
+ "requires": {
+ "http-proxy": "^1.17.0",
+ "is-glob": "^4.0.0",
+ "lodash": "^4.17.11",
+ "micromatch": "^3.1.10"
+ },
+ "dependencies": {
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ }
+ }
+ }
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "https-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+ "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==",
+ "dev": true
+ },
+ "https-proxy-agent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
+ "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
+ "dev": true,
+ "requires": {
+ "agent-base": "6",
+ "debug": "4"
+ }
+ },
+ "human-signals": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
+ "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
+ "dev": true
+ },
+ "humanize-ms": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
+ "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.0.0"
+ }
+ },
+ "i18next": {
+ "version": "20.6.1",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-20.6.1.tgz",
+ "integrity": "sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A==",
+ "dev": true,
+ "requires": {
+ "@babel/runtime": "^7.12.0"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "icss-utils": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
+ "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
+ "dev": true
+ },
+ "identity-obj-proxy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz",
+ "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==",
+ "dev": true,
+ "requires": {
+ "harmony-reflect": "^1.4.6"
+ }
+ },
+ "ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
+ },
+ "ignore": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
+ "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+ "dev": true
+ },
+ "ignore-walk": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz",
+ "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==",
+ "dev": true,
+ "requires": {
+ "minimatch": "^3.0.4"
+ }
+ },
+ "image-size": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
+ "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==",
+ "dev": true,
+ "optional": true
+ },
+ "immutable": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz",
+ "integrity": "sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg=="
+ },
+ "import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "requires": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ }
+ },
+ "import-lazy": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
+ "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
+ "dev": true
+ },
+ "import-local": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
+ "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==",
+ "dev": true,
+ "requires": {
+ "pkg-dir": "^3.0.0",
+ "resolve-cwd": "^2.0.0"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+ "dev": true
+ },
+ "pkg-dir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+ "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+ "dev": true,
+ "requires": {
+ "find-up": "^3.0.0"
+ }
+ }
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true
+ },
+ "indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true
+ },
+ "indexes-of": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
+ "integrity": "sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==",
+ "dev": true
+ },
+ "infer-owner": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
+ "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "ini": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz",
+ "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
+ "dev": true
+ },
+ "inline-source-map": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz",
+ "integrity": "sha512-0mVWSSbNDvedDWIN4wxLsdPM4a7cIPcpyMxj3QZ406QRwQ6ePGB1YIHxVPjqpcUGbWQ5C+nHTwGNWAGvt7ggVA==",
+ "dev": true,
+ "requires": {
+ "source-map": "~0.5.3"
+ }
+ },
+ "inquirer": {
+ "version": "8.1.2",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.1.2.tgz",
+ "integrity": "sha512-DHLKJwLPNgkfwNmsuEUKSejJFbkv0FMO9SMiQbjI3n5NQuCrSIBqP66ggqyz2a6t2qEolKrMjhQ3+W/xXgUQ+Q==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.1.1",
+ "cli-cursor": "^3.1.0",
+ "cli-width": "^3.0.0",
+ "external-editor": "^3.0.3",
+ "figures": "^3.0.0",
+ "lodash": "^4.17.21",
+ "mute-stream": "0.0.8",
+ "ora": "^5.3.0",
+ "run-async": "^2.4.0",
+ "rxjs": "^7.2.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0",
+ "through": "^2.3.6"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "rxjs": {
+ "version": "7.5.6",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz",
+ "integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==",
+ "dev": true,
+ "requires": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "insert-module-globals": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.1.tgz",
+ "integrity": "sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg==",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "acorn-node": "^1.5.2",
+ "combine-source-map": "^0.8.0",
+ "concat-stream": "^1.6.1",
+ "is-buffer": "^1.1.0",
+ "path-is-absolute": "^1.0.1",
+ "process": "~0.11.0",
+ "through2": "^2.0.0",
+ "undeclared-identifiers": "^1.1.2",
+ "xtend": "^4.0.0"
+ }
+ },
+ "inside": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/inside/-/inside-1.0.0.tgz",
+ "integrity": "sha512-tvFwvS4g7q6iDot/4FjtWFHwwpv6TVvEumbTdLQilk1F07ojakbXPQcvf3kMAlyNDpzKRzn+d33O3RuXODuxZQ==",
+ "dev": true
+ },
+ "internal-ip": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz",
+ "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==",
+ "dev": true,
+ "requires": {
+ "default-gateway": "^4.2.0",
+ "ipaddr.js": "^1.9.0"
+ }
+ },
+ "internal-slot": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
+ "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
+ "dev": true,
+ "requires": {
+ "get-intrinsic": "^1.1.0",
+ "has": "^1.0.3",
+ "side-channel": "^1.0.4"
+ }
+ },
+ "invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "requires": {
+ "loose-envify": "^1.0.0"
+ }
+ },
+ "invert-kv": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
+ "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
+ "dev": true
+ },
+ "ip": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
+ "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==",
+ "dev": true
+ },
+ "ip-regex": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
+ "integrity": "sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==",
+ "dev": true
+ },
+ "ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "dev": true
+ },
+ "is-absolute": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
+ "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
+ "dev": true,
+ "requires": {
+ "is-relative": "^1.0.0",
+ "is-windows": "^1.0.1"
+ }
+ },
+ "is-absolute-url": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz",
+ "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==",
+ "dev": true
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-alphabetical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
+ "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg=="
+ },
+ "is-alphanumerical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
+ "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
+ "requires": {
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0"
+ }
+ },
+ "is-arguments": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
+ "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true
+ },
+ "is-bigint": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+ "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "dev": true,
+ "requires": {
+ "has-bigints": "^1.0.1"
+ }
+ },
+ "is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^2.0.0"
+ }
+ },
+ "is-boolean-object": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+ "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "is-callable": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
+ "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==",
+ "dev": true
+ },
+ "is-ci": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
+ "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^3.2.0"
+ }
+ },
+ "is-core-module": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
+ "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-date-object": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+ "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "dev": true,
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-decimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
+ "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw=="
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "is-directory": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+ "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==",
+ "dev": true
+ },
+ "is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "dev": true
+ },
+ "is-dom": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-dom/-/is-dom-1.1.0.tgz",
+ "integrity": "sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ==",
+ "requires": {
+ "is-object": "^1.0.1",
+ "is-window": "^1.0.2"
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+ "dev": true
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
+ },
+ "is-generator": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-generator/-/is-generator-1.0.3.tgz",
+ "integrity": "sha512-G56jBpbJeg7ds83HW1LuShNs8J73Fv3CPz/bmROHOHlnKkN8sWb9ujiagjmxxMUywftgq48HlBZELKKqFLk0oA==",
+ "dev": true
+ },
+ "is-generator-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+ "dev": true
+ },
+ "is-generator-function": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
+ "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
+ "dev": true,
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-hexadecimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
+ "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw=="
+ },
+ "is-installed-globally": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz",
+ "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==",
+ "dev": true,
+ "requires": {
+ "global-dirs": "^3.0.0",
+ "is-path-inside": "^3.0.2"
+ },
+ "dependencies": {
+ "is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true
+ }
+ }
+ },
+ "is-interactive": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
+ "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
+ "dev": true
+ },
+ "is-lambda": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
+ "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
+ "dev": true
+ },
+ "is-negative-zero": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
+ "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "is-number-object": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+ "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+ "dev": true,
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-object": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz",
+ "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA=="
+ },
+ "is-path-cwd": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
+ "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
+ "dev": true
+ },
+ "is-path-in-cwd": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz",
+ "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==",
+ "dev": true,
+ "requires": {
+ "is-path-inside": "^2.1.0"
+ }
+ },
+ "is-path-inside": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz",
+ "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==",
+ "dev": true,
+ "requires": {
+ "path-is-inside": "^1.0.2"
+ }
+ },
+ "is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "dev": true
+ },
+ "is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
+ },
+ "is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
+ "dev": true
+ },
+ "is-regex": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+ "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-regexp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz",
+ "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==",
+ "dev": true
+ },
+ "is-relative": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
+ "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+ "dev": true,
+ "requires": {
+ "is-unc-path": "^1.0.0"
+ }
+ },
+ "is-shared-array-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
+ "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2"
+ }
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
+ "dev": true
+ },
+ "is-string": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+ "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "dev": true,
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-symbol": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+ "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.2"
+ }
+ },
+ "is-typed-array": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz",
+ "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==",
+ "dev": true,
+ "requires": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "es-abstract": "^1.20.0",
+ "for-each": "^0.3.3",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
+ "dev": true
+ },
+ "is-unc-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
+ "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+ "dev": true,
+ "requires": {
+ "unc-path-regex": "^0.1.2"
+ }
+ },
+ "is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "dev": true
+ },
+ "is-weakref": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+ "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2"
+ }
+ },
+ "is-what": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz",
+ "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==",
+ "dev": true
+ },
+ "is-window": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-window/-/is-window-1.0.2.tgz",
+ "integrity": "sha512-uj00kdXyZb9t9RcAUAwMZAnkBUwdYGhYlt7djMXhfyhUCzwNba50tIiBKR7q0l7tdoBtFVw/3JmLY6fI3rmZmg=="
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true
+ },
+ "is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "requires": {
+ "is-docker": "^2.0.0"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+ "dev": true
+ },
+ "isomorphic-form-data": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isomorphic-form-data/-/isomorphic-form-data-2.0.0.tgz",
+ "integrity": "sha512-TYgVnXWeESVmQSg4GLVbalmQ+B4NPi/H4eWxqALKj63KsUrcu301YDjBqaOw3h+cbak7Na4Xyps3BiptHtxTfg==",
+ "dev": true,
+ "requires": {
+ "form-data": "^2.3.2"
+ }
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==",
+ "dev": true
+ },
+ "istanbul-lib-coverage": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
+ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
+ "dev": true
+ },
+ "istanbul-lib-instrument": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
+ "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.7.5",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-coverage": "^3.0.0",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
+ "dev": true,
+ "requires": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^3.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "istanbul-lib-source-maps": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
+ "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0",
+ "source-map": "^0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "istanbul-reports": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz",
+ "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==",
+ "dev": true,
+ "requires": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ }
+ },
+ "jest": {
+ "version": "26.5.2",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-26.5.2.tgz",
+ "integrity": "sha512-4HFabJVwsgDwul/7rhXJ3yFAF/aUkVIXiJWmgFxb+WMdZG39fVvOwYAs8/3r4AlFPc4m/n5sTMtuMbOL3kNtrQ==",
+ "dev": true,
+ "requires": {
+ "@jest/core": "^26.5.2",
+ "import-local": "^3.0.2",
+ "jest-cli": "^26.5.2"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "cliui": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+ "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^6.2.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "import-local": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+ "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
+ "dev": true,
+ "requires": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ }
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "jest-cli": {
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz",
+ "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==",
+ "dev": true,
+ "requires": {
+ "@jest/core": "^26.6.3",
+ "@jest/test-result": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "chalk": "^4.0.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.4",
+ "import-local": "^3.0.2",
+ "is-ci": "^2.0.0",
+ "jest-config": "^26.6.3",
+ "jest-util": "^26.6.2",
+ "jest-validate": "^26.6.2",
+ "prompts": "^2.0.1",
+ "yargs": "^15.4.1"
+ }
+ },
+ "resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "requires": {
+ "resolve-from": "^5.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "y18n": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "15.4.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
+ "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "dev": true,
+ "requires": {
+ "cliui": "^6.0.0",
+ "decamelize": "^1.2.0",
+ "find-up": "^4.1.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^4.2.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^18.1.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "18.1.3",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+ "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ }
+ }
+ },
+ "jest-canvas-mock": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/jest-canvas-mock/-/jest-canvas-mock-2.3.0.tgz",
+ "integrity": "sha512-3TMyR66VG2MzAW8Negzec03bbcIjVJMfGNvKzrEnbws1CYKqMNkvIJ8LbkoGYfp42tKqDmhIpQq3v+MNLW2A2w==",
+ "dev": true,
+ "requires": {
+ "cssfontparser": "^1.2.1",
+ "moo-color": "^1.0.2"
+ }
+ },
+ "jest-changed-files": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz",
+ "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "execa": "^4.0.0",
+ "throat": "^5.0.0"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "execa": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
+ "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.0",
+ "get-stream": "^5.0.0",
+ "human-signals": "^1.1.1",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.0",
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2",
+ "strip-final-newline": "^2.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true
+ },
+ "npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.0.0"
+ }
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "jest-config": {
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz",
+ "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.1.0",
+ "@jest/test-sequencer": "^26.6.3",
+ "@jest/types": "^26.6.2",
+ "babel-jest": "^26.6.3",
+ "chalk": "^4.0.0",
+ "deepmerge": "^4.2.2",
+ "glob": "^7.1.1",
+ "graceful-fs": "^4.2.4",
+ "jest-environment-jsdom": "^26.6.2",
+ "jest-environment-node": "^26.6.2",
+ "jest-get-type": "^26.3.0",
+ "jest-jasmine2": "^26.6.3",
+ "jest-regex-util": "^26.0.0",
+ "jest-resolve": "^26.6.2",
+ "jest-util": "^26.6.2",
+ "jest-validate": "^26.6.2",
+ "micromatch": "^4.0.2",
+ "pretty-format": "^26.6.2"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "jest-get-type": {
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
+ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
+ "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^4.0.0",
+ "react-is": "^17.0.1"
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-diff": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz",
+ "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==",
+ "dev": true,
+ "requires": {
+ "chalk": "^3.0.0",
+ "diff-sequences": "^25.2.6",
+ "jest-get-type": "^25.2.6",
+ "pretty-format": "^25.5.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-docblock": {
+ "version": "26.0.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz",
+ "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==",
+ "dev": true,
+ "requires": {
+ "detect-newline": "^3.0.0"
+ }
+ },
+ "jest-each": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz",
+ "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^26.3.0",
+ "jest-util": "^26.6.2",
+ "pretty-format": "^26.6.2"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "jest-get-type": {
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
+ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
+ "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^4.0.0",
+ "react-is": "^17.0.1"
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-environment-jsdom": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz",
+ "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^26.6.2",
+ "@jest/fake-timers": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
+ "jest-mock": "^26.6.2",
+ "jest-util": "^26.6.2",
+ "jsdom": "^16.4.0"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-environment-node": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz",
+ "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^26.6.2",
+ "@jest/fake-timers": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
+ "jest-mock": "^26.6.2",
+ "jest-util": "^26.6.2"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-get-type": {
+ "version": "25.2.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz",
+ "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==",
+ "dev": true
+ },
+ "jest-haste-map": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz",
+ "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "@types/graceful-fs": "^4.1.2",
+ "@types/node": "*",
+ "anymatch": "^3.0.3",
+ "fb-watchman": "^2.0.0",
+ "fsevents": "^2.1.2",
+ "graceful-fs": "^4.2.4",
+ "jest-regex-util": "^26.0.0",
+ "jest-serializer": "^26.6.2",
+ "jest-util": "^26.6.2",
+ "jest-worker": "^26.6.2",
+ "micromatch": "^4.0.2",
+ "sane": "^4.0.3",
+ "walker": "^1.0.7"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "jest-worker": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
+ "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^7.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-jasmine2": {
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz",
+ "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==",
+ "dev": true,
+ "requires": {
+ "@babel/traverse": "^7.1.0",
+ "@jest/environment": "^26.6.2",
+ "@jest/source-map": "^26.6.2",
+ "@jest/test-result": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "co": "^4.6.0",
+ "expect": "^26.6.2",
+ "is-generator-fn": "^2.0.0",
+ "jest-each": "^26.6.2",
+ "jest-matcher-utils": "^26.6.2",
+ "jest-message-util": "^26.6.2",
+ "jest-runtime": "^26.6.3",
+ "jest-snapshot": "^26.6.2",
+ "jest-util": "^26.6.2",
+ "pretty-format": "^26.6.2",
+ "throat": "^5.0.0"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
+ "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^4.0.0",
+ "react-is": "^17.0.1"
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-leak-detector": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz",
+ "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==",
+ "dev": true,
+ "requires": {
+ "jest-get-type": "^26.3.0",
+ "pretty-format": "^26.6.2"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "jest-get-type": {
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
+ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
+ "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^4.0.0",
+ "react-is": "^17.0.1"
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-matcher-utils": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz",
+ "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0",
+ "jest-diff": "^26.6.2",
+ "jest-get-type": "^26.3.0",
+ "pretty-format": "^26.6.2"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "diff-sequences": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz",
+ "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "jest-diff": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz",
+ "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^26.6.2",
+ "jest-get-type": "^26.3.0",
+ "pretty-format": "^26.6.2"
+ }
+ },
+ "jest-get-type": {
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
+ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
+ "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^4.0.0",
+ "react-is": "^17.0.1"
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-message-util": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz",
+ "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "@jest/types": "^26.6.2",
+ "@types/stack-utils": "^2.0.0",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.4",
+ "micromatch": "^4.0.2",
+ "pretty-format": "^26.6.2",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.2"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
+ "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^4.0.0",
+ "react-is": "^17.0.1"
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-mock": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz",
+ "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "@types/node": "*"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-pnp-resolver": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz",
+ "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==",
+ "dev": true
+ },
+ "jest-preset-angular": {
+ "version": "8.3.1",
+ "resolved": "https://registry.npmjs.org/jest-preset-angular/-/jest-preset-angular-8.3.1.tgz",
+ "integrity": "sha512-WhQm+0tXzikkvIF35XErV87DqYbieZI0R0MIGgn7VE/DDhdbXFDmYQxFZ7w4qcA0cGLLvSMTBbIsUtHeE/rFxQ==",
+ "dev": true,
+ "requires": {
+ "pretty-format": "26.x",
+ "ts-jest": "26.x"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
+ "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^4.0.0",
+ "react-is": "^17.0.1"
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-regex-util": {
+ "version": "26.0.0",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz",
+ "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==",
+ "dev": true
+ },
+ "jest-resolve": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz",
+ "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.4",
+ "jest-pnp-resolver": "^1.2.2",
+ "jest-util": "^26.6.2",
+ "read-pkg-up": "^7.0.1",
+ "resolve": "^1.18.1",
+ "slash": "^3.0.0"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-resolve-dependencies": {
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz",
+ "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "jest-regex-util": "^26.0.0",
+ "jest-snapshot": "^26.6.2"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-runner": {
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz",
+ "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^26.6.2",
+ "@jest/environment": "^26.6.2",
+ "@jest/test-result": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "emittery": "^0.7.1",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.4",
+ "jest-config": "^26.6.3",
+ "jest-docblock": "^26.0.0",
+ "jest-haste-map": "^26.6.2",
+ "jest-leak-detector": "^26.6.2",
+ "jest-message-util": "^26.6.2",
+ "jest-resolve": "^26.6.2",
+ "jest-runtime": "^26.6.3",
+ "jest-util": "^26.6.2",
+ "jest-worker": "^26.6.2",
+ "source-map-support": "^0.5.6",
+ "throat": "^5.0.0"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "jest-worker": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
+ "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^7.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-runtime": {
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz",
+ "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^26.6.2",
+ "@jest/environment": "^26.6.2",
+ "@jest/fake-timers": "^26.6.2",
+ "@jest/globals": "^26.6.2",
+ "@jest/source-map": "^26.6.2",
+ "@jest/test-result": "^26.6.2",
+ "@jest/transform": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0",
+ "cjs-module-lexer": "^0.6.0",
+ "collect-v8-coverage": "^1.0.0",
+ "exit": "^0.1.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.4",
+ "jest-config": "^26.6.3",
+ "jest-haste-map": "^26.6.2",
+ "jest-message-util": "^26.6.2",
+ "jest-mock": "^26.6.2",
+ "jest-regex-util": "^26.0.0",
+ "jest-resolve": "^26.6.2",
+ "jest-snapshot": "^26.6.2",
+ "jest-util": "^26.6.2",
+ "jest-validate": "^26.6.2",
+ "slash": "^3.0.0",
+ "strip-bom": "^4.0.0",
+ "yargs": "^15.4.1"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "cliui": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+ "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^6.2.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "y18n": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "15.4.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
+ "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "dev": true,
+ "requires": {
+ "cliui": "^6.0.0",
+ "decamelize": "^1.2.0",
+ "find-up": "^4.1.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^4.2.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^18.1.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "18.1.3",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+ "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ }
+ }
+ },
+ "jest-serializer": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz",
+ "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "graceful-fs": "^4.2.4"
+ }
+ },
+ "jest-silent-reporter": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/jest-silent-reporter/-/jest-silent-reporter-0.2.1.tgz",
+ "integrity": "sha512-nEO3oOFHtEXFjlRCbJOlvEWA7ZHyyyvMsU4WHuAhinYBOI4PiX1EIbsZfQZ/cxHcYliHBU9zY8bPxMPdBGksYw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.3.1",
+ "jest-util": "^24.0.0"
+ },
+ "dependencies": {
+ "@jest/console": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz",
+ "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==",
+ "dev": true,
+ "requires": {
+ "@jest/source-map": "^24.9.0",
+ "chalk": "^2.0.1",
+ "slash": "^2.0.0"
+ }
+ },
+ "@jest/fake-timers": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz",
+ "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^24.9.0",
+ "jest-message-util": "^24.9.0",
+ "jest-mock": "^24.9.0"
+ }
+ },
+ "@jest/source-map": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz",
+ "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0",
+ "graceful-fs": "^4.1.15",
+ "source-map": "^0.6.0"
+ }
+ },
+ "@jest/test-result": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz",
+ "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "@types/istanbul-lib-coverage": "^2.0.0"
+ }
+ },
+ "@jest/types": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz",
+ "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^1.1.1",
+ "@types/yargs": "^13.0.0"
+ }
+ },
+ "@types/stack-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
+ "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
+ "dev": true
+ },
+ "@types/yargs": {
+ "version": "13.0.12",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz",
+ "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==",
+ "dev": true,
+ "requires": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "jest-message-util": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz",
+ "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "@jest/test-result": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "@types/stack-utils": "^1.0.1",
+ "chalk": "^2.0.1",
+ "micromatch": "^3.1.10",
+ "slash": "^2.0.0",
+ "stack-utils": "^1.0.1"
+ }
+ },
+ "jest-mock": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz",
+ "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^24.9.0"
+ }
+ },
+ "jest-util": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz",
+ "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^24.9.0",
+ "@jest/fake-timers": "^24.9.0",
+ "@jest/source-map": "^24.9.0",
+ "@jest/test-result": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "callsites": "^3.0.0",
+ "chalk": "^2.0.1",
+ "graceful-fs": "^4.1.15",
+ "is-ci": "^2.0.0",
+ "mkdirp": "^0.5.1",
+ "slash": "^2.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.6"
+ }
+ },
+ "slash": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+ "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "stack-utils": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz",
+ "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^2.0.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ }
+ }
+ }
+ },
+ "jest-snapshot": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz",
+ "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.0.0",
+ "@jest/types": "^26.6.2",
+ "@types/babel__traverse": "^7.0.4",
+ "@types/prettier": "^2.0.0",
+ "chalk": "^4.0.0",
+ "expect": "^26.6.2",
+ "graceful-fs": "^4.2.4",
+ "jest-diff": "^26.6.2",
+ "jest-get-type": "^26.3.0",
+ "jest-haste-map": "^26.6.2",
+ "jest-matcher-utils": "^26.6.2",
+ "jest-message-util": "^26.6.2",
+ "jest-resolve": "^26.6.2",
+ "natural-compare": "^1.4.0",
+ "pretty-format": "^26.6.2",
+ "semver": "^7.3.2"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "diff-sequences": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz",
+ "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "jest-diff": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz",
+ "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^26.6.2",
+ "jest-get-type": "^26.3.0",
+ "pretty-format": "^26.6.2"
+ }
+ },
+ "jest-get-type": {
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
+ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
+ "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^4.0.0",
+ "react-is": "^17.0.1"
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-util": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz",
+ "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.4",
+ "is-ci": "^2.0.0",
+ "micromatch": "^4.0.2"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-validate": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz",
+ "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "camelcase": "^6.0.0",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^26.3.0",
+ "leven": "^3.1.0",
+ "pretty-format": "^26.6.2"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "jest-get-type": {
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
+ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
+ "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^26.6.2",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^4.0.0",
+ "react-is": "^17.0.1"
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-watcher": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz",
+ "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==",
+ "dev": true,
+ "requires": {
+ "@jest/test-result": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "jest-util": "^26.6.2",
+ "string-length": "^4.0.1"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-worker": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
+ "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jju": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
+ "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==",
+ "dev": true
+ },
+ "joi": {
+ "version": "17.6.0",
+ "resolved": "https://registry.npmjs.org/joi/-/joi-17.6.0.tgz",
+ "integrity": "sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw==",
+ "dev": true,
+ "requires": {
+ "@hapi/hoek": "^9.0.0",
+ "@hapi/topo": "^5.0.0",
+ "@sideway/address": "^4.1.3",
+ "@sideway/formula": "^3.0.0",
+ "@sideway/pinpoint": "^2.0.0"
+ }
+ },
+ "js-file-download": {
+ "version": "0.4.12",
+ "resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.12.tgz",
+ "integrity": "sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg=="
+ },
+ "js-string-escape": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
+ "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==",
+ "dev": true
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "requires": {
+ "argparse": "^2.0.1"
+ }
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
+ "dev": true
+ },
+ "jsdom": {
+ "version": "16.7.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz",
+ "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==",
+ "dev": true,
+ "requires": {
+ "abab": "^2.0.5",
+ "acorn": "^8.2.4",
+ "acorn-globals": "^6.0.0",
+ "cssom": "^0.4.4",
+ "cssstyle": "^2.3.0",
+ "data-urls": "^2.0.0",
+ "decimal.js": "^10.2.1",
+ "domexception": "^2.0.1",
+ "escodegen": "^2.0.0",
+ "form-data": "^3.0.0",
+ "html-encoding-sniffer": "^2.0.1",
+ "http-proxy-agent": "^4.0.1",
+ "https-proxy-agent": "^5.0.0",
+ "is-potential-custom-element-name": "^1.0.1",
+ "nwsapi": "^2.2.0",
+ "parse5": "6.0.1",
+ "saxes": "^5.0.1",
+ "symbol-tree": "^3.2.4",
+ "tough-cookie": "^4.0.0",
+ "w3c-hr-time": "^1.0.2",
+ "w3c-xmlserializer": "^2.0.0",
+ "webidl-conversions": "^6.1.0",
+ "whatwg-encoding": "^1.0.5",
+ "whatwg-mimetype": "^2.3.0",
+ "whatwg-url": "^8.5.0",
+ "ws": "^7.4.6",
+ "xml-name-validator": "^3.0.0"
+ },
+ "dependencies": {
+ "acorn-globals": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz",
+ "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==",
+ "dev": true,
+ "requires": {
+ "acorn": "^7.1.1",
+ "acorn-walk": "^7.1.1"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true
+ }
+ }
+ },
+ "acorn-walk": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+ "dev": true
+ },
+ "data-urls": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz",
+ "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==",
+ "dev": true,
+ "requires": {
+ "abab": "^2.0.3",
+ "whatwg-mimetype": "^2.3.0",
+ "whatwg-url": "^8.0.0"
+ }
+ },
+ "domexception": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz",
+ "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==",
+ "dev": true,
+ "requires": {
+ "webidl-conversions": "^5.0.0"
+ },
+ "dependencies": {
+ "webidl-conversions": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz",
+ "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==",
+ "dev": true
+ }
+ }
+ },
+ "escodegen": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz",
+ "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==",
+ "dev": true,
+ "requires": {
+ "esprima": "^4.0.1",
+ "estraverse": "^5.2.0",
+ "esutils": "^2.0.2",
+ "optionator": "^0.8.1",
+ "source-map": "~0.6.1"
+ }
+ },
+ "estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true
+ },
+ "form-data": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
+ "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "html-encoding-sniffer": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
+ "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==",
+ "dev": true,
+ "requires": {
+ "whatwg-encoding": "^1.0.5"
+ }
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ },
+ "saxes": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
+ "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
+ "dev": true,
+ "requires": {
+ "xmlchars": "^2.2.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "optional": true
+ },
+ "tough-cookie": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz",
+ "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==",
+ "dev": true,
+ "requires": {
+ "psl": "^1.1.33",
+ "punycode": "^2.1.1",
+ "universalify": "^0.2.0",
+ "url-parse": "^1.5.3"
+ }
+ },
+ "tr46": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
+ "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.1"
+ }
+ },
+ "universalify": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
+ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
+ "dev": true
+ },
+ "w3c-xmlserializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
+ "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==",
+ "dev": true,
+ "requires": {
+ "xml-name-validator": "^3.0.0"
+ }
+ },
+ "webidl-conversions": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
+ "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==",
+ "dev": true
+ },
+ "whatwg-url": {
+ "version": "8.7.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz",
+ "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.7.0",
+ "tr46": "^2.1.0",
+ "webidl-conversions": "^6.1.0"
+ }
+ },
+ "ws": {
+ "version": "7.5.9",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
+ "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
+ "dev": true
+ }
+ }
+ },
+ "jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
+ },
+ "json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true
+ },
+ "json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
+ },
+ "json-parse-helpfulerror": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz",
+ "integrity": "sha512-XgP0FGR77+QhUxjXkwOMkC94k3WtqEBfcnjWqhRd82qTat4SWKRE+9kUnynz/shm3I4ea2+qISvTIeGTNU7kJg==",
+ "dev": true,
+ "requires": {
+ "jju": "^1.1.0"
+ }
+ },
+ "json-schema": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
+ "dev": true
+ },
+ "json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true
+ },
+ "json-stable-stringify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz",
+ "integrity": "sha512-nKtD/Qxm7tWdZqJoldEC7fF0S41v0mWbeaXG3637stOWfyGxTgWTYE2wtfKmjzpvxv2MA2xzxsXOIiwUpkX6Qw==",
+ "dev": true,
+ "requires": {
+ "jsonify": "~0.0.0"
+ }
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
+ "dev": true
+ },
+ "json5": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
+ "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA=="
+ },
+ "jsonc-parser": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
+ "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==",
+ "dev": true
+ },
+ "jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6",
+ "universalify": "^2.0.0"
+ }
+ },
+ "jsonify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+ "integrity": "sha512-trvBk1ki43VZptdBI5rIlG4YOzyeH/WefQt5rj1grasPn4iiZWKet8nkgc4GlsAylaztn0qZfUYOiTsASJFdNA==",
+ "dev": true
+ },
+ "jsonparse": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
+ "dev": true
+ },
+ "jsprim": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
+ "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.4.0",
+ "verror": "1.10.0"
+ }
+ },
+ "karma-source-map-support": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz",
+ "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==",
+ "dev": true,
+ "requires": {
+ "source-map-support": "^0.5.5"
+ }
+ },
+ "killable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
+ "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ },
+ "kleur": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+ "dev": true
+ },
+ "klona": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz",
+ "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==",
+ "dev": true
+ },
+ "known-css-properties": {
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.21.0.tgz",
+ "integrity": "sha512-sZLUnTqimCkvkgRS+kbPlYW5o8q5w1cu+uIisKpEWkj31I8mx8kNG162DwRav8Zirkva6N5uoFsm9kzK4mUXjw==",
+ "dev": true
+ },
+ "knuth-shuffle-seeded": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/knuth-shuffle-seeded/-/knuth-shuffle-seeded-1.0.6.tgz",
+ "integrity": "sha512-9pFH0SplrfyKyojCLxZfMcvkhf5hH0d+UwR9nTVJ/DDQJGuzcXjTwB7TP7sDfehSudlGGaOLblmEWqv04ERVWg==",
+ "dev": true,
+ "requires": {
+ "seed-random": "~2.2.0"
+ }
+ },
+ "labeled-stream-splicer": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz",
+ "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "stream-splicer": "^2.0.0"
+ }
+ },
+ "lazy-ass": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz",
+ "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==",
+ "dev": true
+ },
+ "lcid": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
+ "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
+ "dev": true,
+ "requires": {
+ "invert-kv": "^2.0.0"
+ }
+ },
+ "less": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/less/-/less-4.1.1.tgz",
+ "integrity": "sha512-w09o8tZFPThBscl5d0Ggp3RcrKIouBoQscnOMgFH3n5V3kN/CXGHNfCkRPtxJk6nKryDXaV9aHLK55RXuH4sAw==",
+ "dev": true,
+ "requires": {
+ "copy-anything": "^2.0.1",
+ "errno": "^0.1.1",
+ "graceful-fs": "^4.1.2",
+ "image-size": "~0.5.0",
+ "make-dir": "^2.1.0",
+ "mime": "^1.4.1",
+ "needle": "^2.5.2",
+ "parse-node-version": "^1.0.1",
+ "source-map": "~0.6.0",
+ "tslib": "^1.10.0"
+ },
+ "dependencies": {
+ "make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "optional": true
+ },
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ }
+ }
+ },
+ "less-loader": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-10.0.1.tgz",
+ "integrity": "sha512-Crln//HpW9M5CbtdfWm3IO66Cvx1WhZQvNybXgfB2dD/6Sav9ppw+IWqs/FQKPBFO4B6X0X28Z0WNznshgwUzA==",
+ "dev": true,
+ "requires": {
+ "klona": "^2.0.4"
+ }
+ },
+ "leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ }
+ },
+ "license-webpack-plugin": {
+ "version": "2.3.20",
+ "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-2.3.20.tgz",
+ "integrity": "sha512-AHVueg9clOKACSHkhmEI+PCC9x8+qsQVuKECZD3ETxETK5h/PCv5/MUzyG1gm8OMcip/s1tcNxqo9Qb7WhjGsg==",
+ "dev": true,
+ "requires": {
+ "@types/webpack-sources": "^0.1.5",
+ "webpack-sources": "^1.2.0"
+ }
+ },
+ "liftoff": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz",
+ "integrity": "sha512-01zfGFqfORP1CGmZZP2Zn51zsqz4RltDi0RDOhbGoLYdUT5Lw+I2gX6QdwXhPITF6hPOHEOp+At6/L24hIg9WQ==",
+ "dev": true,
+ "requires": {
+ "extend": "^3.0.0",
+ "findup-sync": "^2.0.0",
+ "fined": "^1.0.1",
+ "flagged-respawn": "^1.0.0",
+ "is-plain-object": "^2.0.4",
+ "object.map": "^1.0.0",
+ "rechoir": "^0.6.2",
+ "resolve": "^1.1.7"
+ },
+ "dependencies": {
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ }
+ }
+ },
+ "lilconfig": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz",
+ "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==",
+ "dev": true
+ },
+ "lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true
+ },
+ "listr2": {
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz",
+ "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==",
+ "dev": true,
+ "requires": {
+ "cli-truncate": "^2.1.0",
+ "colorette": "^2.0.16",
+ "log-update": "^4.0.0",
+ "p-map": "^4.0.0",
+ "rfdc": "^1.3.0",
+ "rxjs": "^7.5.1",
+ "through": "^2.3.8",
+ "wrap-ansi": "^7.0.0"
+ },
+ "dependencies": {
+ "colorette": {
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz",
+ "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==",
+ "dev": true
+ },
+ "rxjs": {
+ "version": "7.5.6",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz",
+ "integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==",
+ "dev": true,
+ "requires": {
+ "tslib": "^2.1.0"
+ }
+ }
+ }
+ },
+ "load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ },
+ "dependencies": {
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "dev": true
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true
+ }
+ }
+ },
+ "loader-runner": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
+ "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
+ "dev": true
+ },
+ "loader-utils": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
+ "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
+ "dev": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ }
+ },
+ "locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
+ "lodash-es": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+ "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+ },
+ "lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
+ "dev": true
+ },
+ "lodash.debounce": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
+ },
+ "lodash.flatten": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
+ "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==",
+ "dev": true
+ },
+ "lodash.mapvalues": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz",
+ "integrity": "sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ==",
+ "dev": true
+ },
+ "lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag=="
+ },
+ "lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true
+ },
+ "lodash.once": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
+ "dev": true
+ },
+ "lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==",
+ "dev": true
+ },
+ "lodash.throttle": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
+ "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
+ },
+ "lodash.truncate": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
+ "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
+ "dev": true
+ },
+ "lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
+ "dev": true
+ },
+ "log-symbols": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "log-update": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz",
+ "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^4.3.0",
+ "cli-cursor": "^3.1.0",
+ "slice-ansi": "^4.0.0",
+ "wrap-ansi": "^6.2.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+ "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ }
+ }
+ },
+ "log4js": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/log4js/-/log4js-1.1.1.tgz",
+ "integrity": "sha512-lYb14ZSs1M/CUFuvy7Zk3VZLDtqrqOaVql9CE0tv8g6/qE1Gfq97XKdltBsjSxxvcJ+t8fAXOnvFxSsms7gGVg==",
+ "dev": true,
+ "requires": {
+ "debug": "^2.2.0",
+ "semver": "^5.3.0",
+ "streamroller": "^0.4.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ }
+ }
+ },
+ "loglevel": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz",
+ "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==",
+ "dev": true
+ },
+ "loglevel-plugin-prefix": {
+ "version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz",
+ "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==",
+ "dev": true
+ },
+ "long": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
+ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==",
+ "dev": true
+ },
+ "longest-streak": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz",
+ "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==",
+ "dev": true
+ },
+ "loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "requires": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ }
+ },
+ "loupe": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz",
+ "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==",
+ "dev": true,
+ "requires": {
+ "get-func-name": "^2.0.0"
+ }
+ },
+ "lower-case": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
+ "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==",
+ "dev": true
+ },
+ "lowlight": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz",
+ "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==",
+ "requires": {
+ "fault": "^1.0.0",
+ "highlight.js": "~10.7.0"
+ }
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "lunr": {
+ "version": "2.3.9",
+ "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
+ "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
+ "dev": true
+ },
+ "macos-release": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.0.tgz",
+ "integrity": "sha512-EIgv+QZ9r+814gjJj0Bt5vSLJLzswGmSUbUpbi9AIr/fsN2IWFBl2NucV9PAiek+U1STK468tEkxmVYUtuAN3g==",
+ "dev": true
+ },
+ "magic-string": {
+ "version": "0.25.7",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
+ "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
+ "dev": true,
+ "requires": {
+ "sourcemap-codec": "^1.4.4"
+ }
+ },
+ "make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "requires": {
+ "semver": "^6.0.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true
+ },
+ "make-fetch-happen": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
+ "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
+ "dev": true,
+ "requires": {
+ "agentkeepalive": "^4.1.3",
+ "cacache": "^15.2.0",
+ "http-cache-semantics": "^4.1.0",
+ "http-proxy-agent": "^4.0.1",
+ "https-proxy-agent": "^5.0.0",
+ "is-lambda": "^1.0.1",
+ "lru-cache": "^6.0.0",
+ "minipass": "^3.1.3",
+ "minipass-collect": "^1.0.2",
+ "minipass-fetch": "^1.3.2",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "negotiator": "^0.6.2",
+ "promise-retry": "^2.0.1",
+ "socks-proxy-agent": "^6.0.0",
+ "ssri": "^8.0.0"
+ }
+ },
+ "make-iterator": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
+ "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.2"
+ }
+ },
+ "makeerror": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
+ "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
+ "dev": true,
+ "requires": {
+ "tmpl": "1.0.5"
+ }
+ },
+ "map-age-cleaner": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
+ "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
+ "dev": true,
+ "requires": {
+ "p-defer": "^1.0.0"
+ }
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==",
+ "dev": true
+ },
+ "map-obj": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
+ "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
+ "dev": true
+ },
+ "map-stream": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz",
+ "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==",
+ "dev": true
+ },
+ "map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==",
+ "dev": true,
+ "requires": {
+ "object-visit": "^1.0.0"
+ }
+ },
+ "marked": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-3.0.8.tgz",
+ "integrity": "sha512-0gVrAjo5m0VZSJb4rpL59K1unJAMb/hm8HRXqasD8VeC8m91ytDPMritgFSlKonfdt+rRYYpP/JfLxgIX8yoSw==",
+ "dev": true
+ },
+ "mathml-tag-names": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz",
+ "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==",
+ "dev": true
+ },
+ "md5": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
+ "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
+ "dev": true,
+ "requires": {
+ "charenc": "0.0.2",
+ "crypt": "0.0.2",
+ "is-buffer": "~1.1.6"
+ }
+ },
+ "md5.js": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+ "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+ "dev": true,
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "mdast-util-from-markdown": {
+ "version": "0.8.5",
+ "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz",
+ "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==",
+ "dev": true,
+ "requires": {
+ "@types/mdast": "^3.0.0",
+ "mdast-util-to-string": "^2.0.0",
+ "micromark": "~2.11.0",
+ "parse-entities": "^2.0.0",
+ "unist-util-stringify-position": "^2.0.0"
+ }
+ },
+ "mdast-util-to-markdown": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz",
+ "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "longest-streak": "^2.0.0",
+ "mdast-util-to-string": "^2.0.0",
+ "parse-entities": "^2.0.0",
+ "repeat-string": "^1.0.0",
+ "zwitch": "^1.0.0"
+ }
+ },
+ "mdast-util-to-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz",
+ "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==",
+ "dev": true
+ },
+ "mdn-data": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
+ "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
+ "dev": true
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "dev": true
+ },
+ "mem": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/mem/-/mem-8.1.1.tgz",
+ "integrity": "sha512-qFCFUDs7U3b8mBDPyz5EToEKoAkgCzqquIgi9nkkR9bixxOVOre+09lbuH7+9Kn2NFpm56M3GUWVbU2hQgdACA==",
+ "dev": true,
+ "requires": {
+ "map-age-cleaner": "^0.1.3",
+ "mimic-fn": "^3.1.0"
+ },
+ "dependencies": {
+ "mimic-fn": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz",
+ "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==",
+ "dev": true
+ }
+ }
+ },
+ "memfs": {
+ "version": "3.4.7",
+ "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.7.tgz",
+ "integrity": "sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw==",
+ "dev": true,
+ "requires": {
+ "fs-monkey": "^1.0.3"
+ }
+ },
+ "memory-fs": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
+ "integrity": "sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==",
+ "dev": true,
+ "requires": {
+ "errno": "^0.1.3",
+ "readable-stream": "^2.0.1"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "memorystream": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
+ "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==",
+ "dev": true
+ },
+ "meow": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz",
+ "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==",
+ "dev": true,
+ "requires": {
+ "@types/minimist": "^1.2.0",
+ "camelcase-keys": "^6.2.2",
+ "decamelize": "^1.2.0",
+ "decamelize-keys": "^1.1.0",
+ "hard-rejection": "^2.1.0",
+ "minimist-options": "4.1.0",
+ "normalize-package-data": "^3.0.0",
+ "read-pkg-up": "^7.0.1",
+ "redent": "^3.0.0",
+ "trim-newlines": "^3.0.0",
+ "type-fest": "^0.18.0",
+ "yargs-parser": "^20.2.3"
+ },
+ "dependencies": {
+ "normalize-package-data": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
+ "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^4.0.1",
+ "is-core-module": "^2.5.0",
+ "semver": "^7.3.4",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "type-fest": {
+ "version": "0.18.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
+ "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
+ "dev": true
+ },
+ "yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "dev": true
+ }
+ }
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==",
+ "dev": true
+ },
+ "merge-source-map": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz",
+ "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==",
+ "dev": true,
+ "requires": {
+ "source-map": "^0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "dev": true
+ },
+ "micromark": {
+ "version": "2.11.4",
+ "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz",
+ "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.0.0",
+ "parse-entities": "^2.0.0"
+ }
+ },
+ "micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ }
+ },
+ "miller-rabin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.0.0",
+ "brorand": "^1.0.1"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+ "dev": true
+ }
+ }
+ },
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "dev": true
+ },
+ "mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.52.0"
+ }
+ },
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ },
+ "min-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
+ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
+ "dev": true
+ },
+ "mini-css-extract-plugin": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.4.2.tgz",
+ "integrity": "sha512-ZmqShkn79D36uerdED+9qdo1ZYG8C1YsWvXu0UMJxurZnSdgz7gQKO2EGv8T55MhDqG3DYmGtizZNpM/UbTlcA==",
+ "dev": true,
+ "requires": {
+ "schema-utils": "^3.1.0"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "schema-utils": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+ "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ }
+ }
+ }
+ },
+ "minimalistic-assert": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+ "dev": true
+ },
+ "minimalistic-crypto-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+ "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
+ "dev": true
+ },
+ "minimist-options": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
+ "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
+ "dev": true,
+ "requires": {
+ "arrify": "^1.0.1",
+ "is-plain-obj": "^1.1.0",
+ "kind-of": "^6.0.3"
+ },
+ "dependencies": {
+ "arrify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+ "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
+ "dev": true
+ },
+ "is-plain-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+ "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
+ "dev": true
+ }
+ }
+ },
+ "minipass": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz",
+ "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "minipass-collect": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
+ "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "minipass-fetch": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
+ "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
+ "dev": true,
+ "requires": {
+ "encoding": "^0.1.12",
+ "minipass": "^3.1.0",
+ "minipass-sized": "^1.0.3",
+ "minizlib": "^2.0.0"
+ }
+ },
+ "minipass-flush": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+ "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "minipass-json-stream": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz",
+ "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==",
+ "dev": true,
+ "requires": {
+ "jsonparse": "^1.3.1",
+ "minipass": "^3.0.0"
+ }
+ },
+ "minipass-pipeline": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
+ "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "minipass-sized": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
+ "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ }
+ },
+ "mixin-deep": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+ "dev": true,
+ "requires": {
+ "for-in": "^1.0.2",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ },
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "dev": true
+ },
+ "mkdirp-classic": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
+ "dev": true
+ },
+ "mobx": {
+ "version": "4.14.1",
+ "resolved": "https://registry.npmjs.org/mobx/-/mobx-4.14.1.tgz",
+ "integrity": "sha512-Oyg7Sr7r78b+QPYLufJyUmxTWcqeQ96S1nmtyur3QL8SeI6e0TqcKKcxbG+sVJLWANhHQkBW/mDmgG5DDC4fdw=="
+ },
+ "mocha": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.0.tgz",
+ "integrity": "sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q==",
+ "dev": true,
+ "requires": {
+ "@ungap/promise-all-settled": "1.1.2",
+ "ansi-colors": "4.1.1",
+ "browser-stdout": "1.3.1",
+ "chokidar": "3.5.3",
+ "debug": "4.3.3",
+ "diff": "5.0.0",
+ "escape-string-regexp": "4.0.0",
+ "find-up": "5.0.0",
+ "glob": "7.2.0",
+ "growl": "1.10.5",
+ "he": "1.2.0",
+ "js-yaml": "4.1.0",
+ "log-symbols": "4.1.0",
+ "minimatch": "3.0.4",
+ "ms": "2.1.3",
+ "nanoid": "3.2.0",
+ "serialize-javascript": "6.0.0",
+ "strip-json-comments": "3.1.1",
+ "supports-color": "8.1.1",
+ "which": "2.0.2",
+ "workerpool": "6.2.0",
+ "yargs": "16.2.0",
+ "yargs-parser": "20.2.4",
+ "yargs-unparser": "2.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
+ "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true
+ },
+ "find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "glob": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^5.0.0"
+ }
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ },
+ "nanoid": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
+ "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "requires": {
+ "yocto-queue": "^0.1.0"
+ }
+ },
+ "p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^3.0.2"
+ }
+ },
+ "supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "20.2.4",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+ "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+ "dev": true
+ }
+ }
+ },
+ "mocha-junit-reporter": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-2.0.2.tgz",
+ "integrity": "sha512-vYwWq5hh3v1lG0gdQCBxwNipBfvDiAM1PHroQRNp96+2l72e9wEUTw+mzoK+O0SudgfQ7WvTQZ9Nh3qkAYAjfg==",
+ "dev": true,
+ "requires": {
+ "debug": "^2.2.0",
+ "md5": "^2.1.0",
+ "mkdirp": "~0.5.1",
+ "strip-ansi": "^6.0.1",
+ "xml": "^1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.6"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ }
+ }
+ },
+ "module-deps": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.3.tgz",
+ "integrity": "sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "browser-resolve": "^2.0.0",
+ "cached-path-relative": "^1.0.2",
+ "concat-stream": "~1.6.0",
+ "defined": "^1.0.0",
+ "detective": "^5.2.0",
+ "duplexer2": "^0.1.2",
+ "inherits": "^2.0.1",
+ "parents": "^1.0.0",
+ "readable-stream": "^2.0.2",
+ "resolve": "^1.4.0",
+ "stream-combiner2": "^1.1.1",
+ "subarg": "^1.0.0",
+ "through2": "^2.0.0",
+ "xtend": "^4.0.0"
+ },
+ "dependencies": {
+ "browser-resolve": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz",
+ "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==",
+ "dev": true,
+ "requires": {
+ "resolve": "^1.17.0"
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "moment": {
+ "version": "2.29.3",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.3.tgz",
+ "integrity": "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw=="
+ },
+ "moo-color": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/moo-color/-/moo-color-1.0.3.tgz",
+ "integrity": "sha512-i/+ZKXMDf6aqYtBhuOcej71YSlbjT3wCO/4H1j8rPvxDJEifdwgg5MaFyu6iYAT8GBZJg2z0dkgK4YMzvURALQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "^1.1.4"
+ },
+ "dependencies": {
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ }
+ }
+ },
+ "morgan": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
+ "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==",
+ "dev": true,
+ "requires": {
+ "basic-auth": "~2.0.1",
+ "debug": "2.6.9",
+ "depd": "~2.0.0",
+ "on-finished": "~2.3.0",
+ "on-headers": "~1.0.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
+ "dev": true,
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ }
+ }
+ },
+ "mri": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
+ "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "multicast-dns": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
+ "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
+ "dev": true,
+ "requires": {
+ "dns-packet": "^1.3.1",
+ "thunky": "^1.0.2"
+ }
+ },
+ "multicast-dns-service-types": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
+ "integrity": "sha512-cnAsSVxIDsYt0v7HmC0hWZFwwXSh+E6PgCrREDuN/EsjgLwA5XRmlMHhSiDPrt6HxY1gTivEa/Zh7GtODoLevQ==",
+ "dev": true
+ },
+ "multimatch": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz",
+ "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==",
+ "dev": true,
+ "requires": {
+ "@types/minimatch": "^3.0.3",
+ "array-differ": "^3.0.0",
+ "array-union": "^2.1.0",
+ "arrify": "^2.0.1",
+ "minimatch": "^3.0.4"
+ },
+ "dependencies": {
+ "@types/minimatch": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
+ "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
+ "dev": true
+ }
+ }
+ },
+ "mute-stream": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+ "dev": true
+ },
+ "mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "dev": true,
+ "requires": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "nanoid": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
+ "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
+ "dev": true
+ },
+ "nanomatch": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "fragment-cache": "^0.2.1",
+ "is-windows": "^1.0.2",
+ "kind-of": "^6.0.2",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ }
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true
+ },
+ "needle": {
+ "version": "2.9.1",
+ "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz",
+ "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "debug": "^3.2.6",
+ "iconv-lite": "^0.4.4",
+ "sax": "^1.2.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "dev": true
+ },
+ "neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true
+ },
+ "next-tick": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
+ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==",
+ "dev": true
+ },
+ "ng-block-ui": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/ng-block-ui/-/ng-block-ui-3.0.2.tgz",
+ "integrity": "sha512-EP3IXP8WSoKQOAwunf/v77aydcBCSLkEm5K8duRMSXFsnrcTdNqUiaLDKCf9U3COHY52IVBJcLb9PGhMBCWVSA==",
+ "requires": {
+ "tslib": "^1.10.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
+ "ng-bullet": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/ng-bullet/-/ng-bullet-1.0.3.tgz",
+ "integrity": "sha512-qacsE/w/pLlBxebort1rkrE2B4Vc3idutcpe7tYiHVarz0V6Q5SN8E3d6NUp4UFBMOucpHlCpaASp7qEOsxM1Q==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ }
+ }
+ },
+ "ng-click-outside": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/ng-click-outside/-/ng-click-outside-7.0.0.tgz",
+ "integrity": "sha512-5QgqABb8ULqQtHNvCNXnBlzjKfILXrdZkq/xcnGL1aM1EmrY7xlUQQ/WLYnxno0gw/QQwCE5tH7sFfFUhIn8CA=="
+ },
+ "ng-mocks": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/ng-mocks/-/ng-mocks-10.2.0.tgz",
+ "integrity": "sha512-aEbNKbXYXNFRH1iedokACPBnZpiWrpG09Szkcc3RpcFa1gb46wwWBQUlgNxuc52MX/RZurVLpdn38nkKh3iSKA==",
+ "dev": true
+ },
+ "ng2-charts": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/ng2-charts/-/ng2-charts-2.4.2.tgz",
+ "integrity": "sha512-mY3C2uKCaApHCQizS2YxEOqQ7sSZZLxdV6N1uM9u/VvUgVtYvlPtdcXbKpN52ak93ZE22I73DiLWVDnDNG4/AQ==",
+ "requires": {
+ "@types/chart.js": "^2.9.24",
+ "lodash-es": "^4.17.15",
+ "tslib": "^2.0.0"
+ }
+ },
+ "ngx-pipe-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/ngx-pipe-function/-/ngx-pipe-function-1.0.0.tgz",
+ "integrity": "sha512-AFWZ3icsq+0/nxFZtqRGZ03nRFoHcxVkZNGIi4ZQbdl5QLP3FmNTHGMmigohSeCV785l3YmPDUEx+6qwdGynMw==",
+ "requires": {
+ "tslib": "^1.9.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
+ "ngx-toastr": {
+ "version": "14.1.4",
+ "resolved": "https://registry.npmjs.org/ngx-toastr/-/ngx-toastr-14.1.4.tgz",
+ "integrity": "sha512-t1/9r+pOXm65LIl0gevvFat6XIl0g3tMA8UOArFjI4ta/nGwDe/14J/f4cZvOBDcomedvjvGAWi+d/2URdSTBg==",
+ "requires": {
+ "tslib": "^2.2.0"
+ }
+ },
+ "nice-napi": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
+ "integrity": "sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "node-addon-api": "^3.0.0",
+ "node-gyp-build": "^4.2.2"
+ }
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "no-case": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
+ "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==",
+ "dev": true,
+ "requires": {
+ "lower-case": "^1.1.1"
+ }
+ },
+ "node-addon-api": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz",
+ "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==",
+ "dev": true,
+ "optional": true
+ },
+ "node-domexception": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
+ "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="
+ },
+ "node-fetch": {
+ "version": "2.6.7",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
+ "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+ "requires": {
+ "whatwg-url": "^5.0.0"
+ }
+ },
+ "node-forge": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
+ "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==",
+ "dev": true
+ },
+ "node-gyp": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz",
+ "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==",
+ "dev": true,
+ "requires": {
+ "env-paths": "^2.2.0",
+ "glob": "^7.1.4",
+ "graceful-fs": "^4.2.3",
+ "nopt": "^5.0.0",
+ "npmlog": "^4.1.2",
+ "request": "^2.88.2",
+ "rimraf": "^3.0.2",
+ "semver": "^7.3.2",
+ "tar": "^6.0.2",
+ "which": "^2.0.2"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "node-gyp-build": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz",
+ "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==",
+ "dev": true,
+ "optional": true
+ },
+ "node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
+ "dev": true
+ },
+ "node-notifier": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz",
+ "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "growly": "^1.3.0",
+ "is-wsl": "^2.2.0",
+ "semver": "^7.3.2",
+ "shellwords": "^0.1.1",
+ "uuid": "^8.3.0",
+ "which": "^2.0.2"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "node-releases": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz",
+ "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==",
+ "dev": true
+ },
+ "nopt": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
+ "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
+ "dev": true,
+ "requires": {
+ "abbrev": "1"
+ }
+ },
+ "normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ },
+ "dependencies": {
+ "hosted-git-info": {
+ "version": "2.8.9",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+ "dev": true
+ }
+ }
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+ "dev": true
+ },
+ "normalize-selector": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz",
+ "integrity": "sha512-dxvWdI8gw6eAvk9BlPffgEoGfM7AdijoCwOEJge3e3ulT2XLgmU7KvvxprOaCu05Q1uGRHmOhHe1r6emZoKyFw==",
+ "dev": true
+ },
+ "normalize-url": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
+ "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
+ "dev": true
+ },
+ "npm-bundled": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz",
+ "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==",
+ "dev": true,
+ "requires": {
+ "npm-normalize-package-bin": "^1.0.1"
+ }
+ },
+ "npm-install-checks": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-4.0.0.tgz",
+ "integrity": "sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w==",
+ "dev": true,
+ "requires": {
+ "semver": "^7.1.1"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "npm-normalize-package-bin": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz",
+ "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==",
+ "dev": true
+ },
+ "npm-package-arg": {
+ "version": "8.1.5",
+ "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.1.5.tgz",
+ "integrity": "sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^4.0.1",
+ "semver": "^7.3.4",
+ "validate-npm-package-name": "^3.0.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "npm-packlist": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-2.2.2.tgz",
+ "integrity": "sha512-Jt01acDvJRhJGthnUJVF/w6gumWOZxO7IkpY/lsX9//zqQgnF7OJaxgQXcerd4uQOLu7W5bkb4mChL9mdfm+Zg==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.6",
+ "ignore-walk": "^3.0.3",
+ "npm-bundled": "^1.1.1",
+ "npm-normalize-package-bin": "^1.0.1"
+ }
+ },
+ "npm-pick-manifest": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz",
+ "integrity": "sha512-dBsdBtORT84S8V8UTad1WlUyKIY9iMsAmqxHbLdeEeBNMLQDlDWWra3wYUx9EBEIiG/YwAy0XyNHDd2goAsfuA==",
+ "dev": true,
+ "requires": {
+ "npm-install-checks": "^4.0.0",
+ "npm-normalize-package-bin": "^1.0.1",
+ "npm-package-arg": "^8.1.2",
+ "semver": "^7.3.4"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "npm-registry-fetch": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-11.0.0.tgz",
+ "integrity": "sha512-jmlgSxoDNuhAtxUIG6pVwwtz840i994dL14FoNVZisrmZW5kWd63IUTNv1m/hyRSGSqWjCUp/YZlS1BJyNp9XA==",
+ "dev": true,
+ "requires": {
+ "make-fetch-happen": "^9.0.1",
+ "minipass": "^3.1.3",
+ "minipass-fetch": "^1.3.0",
+ "minipass-json-stream": "^1.0.1",
+ "minizlib": "^2.0.0",
+ "npm-package-arg": "^8.0.0"
+ }
+ },
+ "npm-run-all": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz",
+ "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "chalk": "^2.4.1",
+ "cross-spawn": "^6.0.5",
+ "memorystream": "^0.3.1",
+ "minimatch": "^3.0.4",
+ "pidtree": "^0.3.0",
+ "read-pkg": "^3.0.0",
+ "shell-quote": "^1.6.1",
+ "string.prototype.padend": "^3.0.0"
+ },
+ "dependencies": {
+ "path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "requires": {
+ "pify": "^3.0.0"
+ }
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "dev": true
+ },
+ "read-pkg": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+ "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^4.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^3.0.0"
+ }
+ }
+ }
+ },
+ "npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
+ "dev": true,
+ "requires": {
+ "path-key": "^2.0.0"
+ }
+ },
+ "npmlog": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+ "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+ "dev": true,
+ "requires": {
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.7.3",
+ "set-blocking": "~2.0.0"
+ }
+ },
+ "nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "requires": {
+ "boolbase": "^1.0.0"
+ }
+ },
+ "num2fraction": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
+ "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==",
+ "dev": true
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==",
+ "dev": true
+ },
+ "nwsapi": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz",
+ "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
+ },
+ "object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==",
+ "dev": true,
+ "requires": {
+ "copy-descriptor": "^0.1.0",
+ "define-property": "^0.2.5",
+ "kind-of": "^3.0.3"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "object-inspect": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+ "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ=="
+ },
+ "object-is": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
+ "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ }
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true
+ },
+ "object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.0"
+ }
+ },
+ "object.assign": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
+ "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "has-symbols": "^1.0.3",
+ "object-keys": "^1.1.1"
+ }
+ },
+ "object.defaults": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
+ "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==",
+ "dev": true,
+ "requires": {
+ "array-each": "^1.0.1",
+ "array-slice": "^1.0.0",
+ "for-own": "^1.0.0",
+ "isobject": "^3.0.0"
+ }
+ },
+ "object.map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
+ "integrity": "sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==",
+ "dev": true,
+ "requires": {
+ "for-own": "^1.0.0",
+ "make-iterator": "^1.0.0"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "obuf": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
+ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
+ "dev": true
+ },
+ "on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "dev": true,
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "on-headers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
+ "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
+ "dev": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^2.1.0"
+ }
+ },
+ "open": {
+ "version": "8.2.1",
+ "resolved": "https://registry.npmjs.org/open/-/open-8.2.1.tgz",
+ "integrity": "sha512-rXILpcQlkF/QuFez2BJDf3GsqpjGKbkUUToAIGo9A0Q6ZkoSGogZJulrUdwRkrAsoQvoZsrjCYt8+zblOk7JQQ==",
+ "dev": true,
+ "requires": {
+ "define-lazy-prop": "^2.0.0",
+ "is-docker": "^2.1.1",
+ "is-wsl": "^2.2.0"
+ }
+ },
+ "opencollective-postinstall": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
+ "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
+ "dev": true
+ },
+ "opn": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
+ "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==",
+ "dev": true,
+ "requires": {
+ "is-wsl": "^1.1.0"
+ },
+ "dependencies": {
+ "is-wsl": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+ "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==",
+ "dev": true
+ }
+ }
+ },
+ "optionator": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+ "dev": true,
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.6",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "word-wrap": "~1.2.3"
+ }
+ },
+ "ora": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
+ "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
+ "dev": true,
+ "requires": {
+ "bl": "^4.1.0",
+ "chalk": "^4.1.0",
+ "cli-cursor": "^3.1.0",
+ "cli-spinners": "^2.5.0",
+ "is-interactive": "^1.0.0",
+ "is-unicode-supported": "^0.1.0",
+ "log-symbols": "^4.1.0",
+ "strip-ansi": "^6.0.0",
+ "wcwidth": "^1.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "os-browserify": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+ "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==",
+ "dev": true
+ },
+ "os-locale": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
+ "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
+ "dev": true,
+ "requires": {
+ "execa": "^1.0.0",
+ "lcid": "^2.0.0",
+ "mem": "^4.0.0"
+ },
+ "dependencies": {
+ "mem": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz",
+ "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
+ "dev": true,
+ "requires": {
+ "map-age-cleaner": "^0.1.1",
+ "mimic-fn": "^2.0.0",
+ "p-is-promise": "^2.0.0"
+ }
+ }
+ }
+ },
+ "os-name": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/os-name/-/os-name-4.0.1.tgz",
+ "integrity": "sha512-xl9MAoU97MH1Xt5K9ERft2YfCAoaO6msy1OBA0ozxEC0x0TmIoE6K3QvgJMMZA9yKGLmHXNY/YZoDbiGDj4zYw==",
+ "dev": true,
+ "requires": {
+ "macos-release": "^2.5.0",
+ "windows-release": "^4.0.0"
+ }
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
+ "dev": true
+ },
+ "ospath": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz",
+ "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==",
+ "dev": true
+ },
+ "outpipe": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/outpipe/-/outpipe-1.1.1.tgz",
+ "integrity": "sha512-BnNY/RwnDrkmQdUa9U+OfN/Y7AWmKuUPCCd+hbRclZnnANvYpO72zp/a6Q4n829hPbdqEac31XCcsvlEvb+rtA==",
+ "dev": true,
+ "requires": {
+ "shell-quote": "^1.4.2"
+ }
+ },
+ "p-defer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
+ "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==",
+ "dev": true
+ },
+ "p-each-series": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz",
+ "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==",
+ "dev": true
+ },
+ "p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
+ "dev": true
+ },
+ "p-is-promise": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz",
+ "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.2.0"
+ }
+ },
+ "p-map": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+ "dev": true,
+ "requires": {
+ "aggregate-error": "^3.0.0"
+ }
+ },
+ "p-retry": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz",
+ "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==",
+ "dev": true,
+ "requires": {
+ "retry": "^0.12.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "pacote": {
+ "version": "11.3.5",
+ "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.3.5.tgz",
+ "integrity": "sha512-fT375Yczn4zi+6Hkk2TBe1x1sP8FgFsEIZ2/iWaXY2r/NkhDJfxbcn5paz1+RTFCyNf+dPnaoBDJoAxXSU8Bkg==",
+ "dev": true,
+ "requires": {
+ "@npmcli/git": "^2.1.0",
+ "@npmcli/installed-package-contents": "^1.0.6",
+ "@npmcli/promise-spawn": "^1.2.0",
+ "@npmcli/run-script": "^1.8.2",
+ "cacache": "^15.0.5",
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.1.0",
+ "infer-owner": "^1.0.4",
+ "minipass": "^3.1.3",
+ "mkdirp": "^1.0.3",
+ "npm-package-arg": "^8.0.1",
+ "npm-packlist": "^2.1.4",
+ "npm-pick-manifest": "^6.0.0",
+ "npm-registry-fetch": "^11.0.0",
+ "promise-retry": "^2.0.1",
+ "read-package-json-fast": "^2.0.1",
+ "rimraf": "^3.0.2",
+ "ssri": "^8.0.1",
+ "tar": "^6.1.0"
+ }
+ },
+ "pad-right": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/pad-right/-/pad-right-0.2.2.tgz",
+ "integrity": "sha512-4cy8M95ioIGolCoMmm2cMntGR1lPLEbOMzOKu8bzjuJP6JpzEMQcDHmh7hHLYGgob+nKe1YHFMaG4V59HQa89g==",
+ "dev": true,
+ "requires": {
+ "repeat-string": "^1.5.2"
+ }
+ },
+ "pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+ "dev": true
+ },
+ "parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0"
+ }
+ },
+ "parents": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz",
+ "integrity": "sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==",
+ "dev": true,
+ "requires": {
+ "path-platform": "~0.11.15"
+ }
+ },
+ "parse-asn1": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
+ "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
+ "dev": true,
+ "requires": {
+ "asn1.js": "^5.2.0",
+ "browserify-aes": "^1.0.0",
+ "evp_bytestokey": "^1.0.0",
+ "pbkdf2": "^3.0.3",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "parse-entities": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
+ "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
+ "requires": {
+ "character-entities": "^1.0.0",
+ "character-entities-legacy": "^1.0.0",
+ "character-reference-invalid": "^1.0.0",
+ "is-alphanumerical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-hexadecimal": "^1.0.0"
+ }
+ },
+ "parse-filepath": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
+ "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==",
+ "dev": true,
+ "requires": {
+ "is-absolute": "^1.0.0",
+ "map-cache": "^0.2.0",
+ "path-root": "^0.1.1"
+ }
+ },
+ "parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "requires": {
+ "@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-node-version": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
+ "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
+ "dev": true
+ },
+ "parse-passwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
+ "dev": true
+ },
+ "parse5": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
+ "dev": true
+ },
+ "parse5-html-rewriting-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-6.0.1.tgz",
+ "integrity": "sha512-vwLQzynJVEfUlURxgnf51yAJDQTtVpNyGD8tKi2Za7m+akukNHxCcUQMAa/mUGLhCeicFdpy7Tlvj8ZNKadprg==",
+ "dev": true,
+ "requires": {
+ "parse5": "^6.0.1",
+ "parse5-sax-parser": "^6.0.1"
+ }
+ },
+ "parse5-htmlparser2-tree-adapter": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
+ "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+ "dev": true,
+ "requires": {
+ "parse5": "^6.0.1"
+ }
+ },
+ "parse5-sax-parser": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-6.0.1.tgz",
+ "integrity": "sha512-kXX+5S81lgESA0LsDuGjAlBybImAChYRMT+/uKCEXFBFOeEhS52qUCydGhU3qLRD8D9DVjaUo821WK7DM4iCeg==",
+ "dev": true,
+ "requires": {
+ "parse5": "^6.0.1"
+ }
+ },
+ "parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "dev": true
+ },
+ "pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==",
+ "dev": true
+ },
+ "path-browserify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
+ "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+ "dev": true
+ },
+ "path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==",
+ "dev": true
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+ },
+ "path-platform": {
+ "version": "0.11.15",
+ "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz",
+ "integrity": "sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==",
+ "dev": true
+ },
+ "path-root": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
+ "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==",
+ "dev": true,
+ "requires": {
+ "path-root-regex": "^0.1.0"
+ }
+ },
+ "path-root-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
+ "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==",
+ "dev": true
+ },
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==",
+ "dev": true
+ },
+ "path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true
+ },
+ "pathval": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
+ "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
+ "dev": true
+ },
+ "pause-stream": {
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
+ "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==",
+ "dev": true,
+ "requires": {
+ "through": "~2.3"
+ }
+ },
+ "pbkdf2": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
+ "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
+ "dev": true,
+ "requires": {
+ "create-hash": "^1.1.2",
+ "create-hmac": "^1.1.4",
+ "ripemd160": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "pdfmake": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/pdfmake/-/pdfmake-0.2.5.tgz",
+ "integrity": "sha512-NlayjehMtuZEdw2Lyipf/MxOCR2vATZQ7jn8cH0/dHwsNb+mqof9/6SW4jZT5p+So4qz+0mD21KG81+dDQSEhA==",
+ "dev": true,
+ "requires": {
+ "@foliojs-fork/linebreak": "^1.1.1",
+ "@foliojs-fork/pdfkit": "^0.13.0",
+ "iconv-lite": "^0.6.3",
+ "xmldoc": "^1.1.2"
+ },
+ "dependencies": {
+ "iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ }
+ }
+ }
+ },
+ "pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
+ "dev": true
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==",
+ "dev": true
+ },
+ "picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true
+ },
+ "pidtree": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz",
+ "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==",
+ "dev": true
+ },
+ "pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "dev": true
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==",
+ "dev": true
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==",
+ "dev": true,
+ "requires": {
+ "pinkie": "^2.0.0"
+ }
+ },
+ "pirates": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
+ "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
+ "dev": true
+ },
+ "piscina": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/piscina/-/piscina-3.1.0.tgz",
+ "integrity": "sha512-KTW4sjsCD34MHrUbx9eAAbuUSpVj407hQSgk/6Epkg0pbRBmv4a3UX7Sr8wxm9xYqQLnsN4mFOjqGDzHAdgKQg==",
+ "dev": true,
+ "requires": {
+ "eventemitter-asyncresource": "^1.0.0",
+ "hdr-histogram-js": "^2.0.1",
+ "hdr-histogram-percentiles-obj": "^3.0.0",
+ "nice-napi": "^1.0.2"
+ }
+ },
+ "pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "requires": {
+ "find-up": "^4.0.0"
+ }
+ },
+ "pn": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
+ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
+ "dev": true
+ },
+ "png-async": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/png-async/-/png-async-0.9.4.tgz",
+ "integrity": "sha512-B//AXX9TkneKfgtOpT1mdUnnhk2BImGD+a98vImsMU8uo1dBeHyW/kM2erWZ/CsYteTPU/xKG+t6T62heHkC3A==",
+ "dev": true
+ },
+ "png-js": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/png-js/-/png-js-1.0.0.tgz",
+ "integrity": "sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g==",
+ "dev": true
+ },
+ "pngjs": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-2.3.1.tgz",
+ "integrity": "sha512-ITNPqvx+SSssNFOgHQzGG87HrqQ0g2nMSHc1jjU5Piq9xJEJ40fiFEPz0S5HSSXxBHrTnhaBHIayTO5aRfk2vw==",
+ "dev": true
+ },
+ "pngjs-image": {
+ "version": "0.11.7",
+ "resolved": "https://registry.npmjs.org/pngjs-image/-/pngjs-image-0.11.7.tgz",
+ "integrity": "sha512-JRyrmT+HXa1/gvdHpebus8TGqKa8WRgcsHz/DDalxRsMhvu6AOA99/enBFjZIPvmXVAzwKR051s80TuE1IiCpg==",
+ "dev": true,
+ "requires": {
+ "iconv-lite": "^0.4.8",
+ "pako": "^0.2.6",
+ "pngjs": "2.3.1",
+ "request": "^2.55.0",
+ "stream-buffers": "1.0.1",
+ "underscore": "1.7.0"
+ },
+ "dependencies": {
+ "pako": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
+ "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==",
+ "dev": true
+ }
+ }
+ },
+ "portfinder": {
+ "version": "1.0.32",
+ "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
+ "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==",
+ "dev": true,
+ "requires": {
+ "async": "^2.6.4",
+ "debug": "^3.2.7",
+ "mkdirp": "^0.5.6"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.6"
+ }
+ }
+ }
+ },
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "8.3.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.6.tgz",
+ "integrity": "sha512-wG1cc/JhRgdqB6WHEuyLTedf3KIRuD0hG6ldkFEZNCjRxiC+3i6kkWUUbiJQayP28iwG35cEmAbe98585BYV0A==",
+ "dev": true,
+ "requires": {
+ "colorette": "^1.2.2",
+ "nanoid": "^3.1.23",
+ "source-map-js": "^0.6.2"
+ },
+ "dependencies": {
+ "source-map-js": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz",
+ "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-attribute-case-insensitive": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz",
+ "integrity": "sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2",
+ "postcss-selector-parser": "^6.0.2"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-calc": {
+ "version": "8.2.4",
+ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz",
+ "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==",
+ "dev": true,
+ "requires": {
+ "postcss-selector-parser": "^6.0.9",
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "postcss-color-functional-notation": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz",
+ "integrity": "sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2",
+ "postcss-values-parser": "^2.0.0"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-color-gray": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz",
+ "integrity": "sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==",
+ "dev": true,
+ "requires": {
+ "@csstools/convert-colors": "^1.4.0",
+ "postcss": "^7.0.5",
+ "postcss-values-parser": "^2.0.0"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-color-hex-alpha": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz",
+ "integrity": "sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.14",
+ "postcss-values-parser": "^2.0.1"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-color-mod-function": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz",
+ "integrity": "sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==",
+ "dev": true,
+ "requires": {
+ "@csstools/convert-colors": "^1.4.0",
+ "postcss": "^7.0.2",
+ "postcss-values-parser": "^2.0.0"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-color-rebeccapurple": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz",
+ "integrity": "sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2",
+ "postcss-values-parser": "^2.0.0"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-colormin": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz",
+ "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.16.6",
+ "caniuse-api": "^3.0.0",
+ "colord": "^2.9.1",
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "postcss-convert-values": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz",
+ "integrity": "sha512-c6Hzc4GAv95B7suy4udszX9Zy4ETyMCgFPUDtWjdFTKH1SE9eFY/jEpHSwTH1QPuwxHpWslhckUQWbNRM4ho5g==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.20.3",
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "postcss-custom-media": {
+ "version": "7.0.8",
+ "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz",
+ "integrity": "sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.14"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-custom-properties": {
+ "version": "8.0.11",
+ "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz",
+ "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.17",
+ "postcss-values-parser": "^2.0.1"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-custom-selectors": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz",
+ "integrity": "sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2",
+ "postcss-selector-parser": "^5.0.0-rc.3"
+ },
+ "dependencies": {
+ "cssesc": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
+ "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
+ "dev": true
+ },
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "postcss-selector-parser": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
+ "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
+ "dev": true,
+ "requires": {
+ "cssesc": "^2.0.0",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-dir-pseudo-class": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz",
+ "integrity": "sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2",
+ "postcss-selector-parser": "^5.0.0-rc.3"
+ },
+ "dependencies": {
+ "cssesc": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
+ "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
+ "dev": true
+ },
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "postcss-selector-parser": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
+ "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
+ "dev": true,
+ "requires": {
+ "cssesc": "^2.0.0",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-discard-comments": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz",
+ "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==",
+ "dev": true
+ },
+ "postcss-discard-duplicates": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz",
+ "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==",
+ "dev": true
+ },
+ "postcss-discard-empty": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz",
+ "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==",
+ "dev": true
+ },
+ "postcss-discard-overridden": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz",
+ "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==",
+ "dev": true
+ },
+ "postcss-double-position-gradients": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz",
+ "integrity": "sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.5",
+ "postcss-values-parser": "^2.0.0"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-env-function": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-2.0.2.tgz",
+ "integrity": "sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2",
+ "postcss-values-parser": "^2.0.0"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-focus-visible": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz",
+ "integrity": "sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-focus-within": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz",
+ "integrity": "sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-font-variant": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz",
+ "integrity": "sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-gap-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz",
+ "integrity": "sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-html": {
+ "version": "0.36.0",
+ "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz",
+ "integrity": "sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==",
+ "dev": true,
+ "requires": {
+ "htmlparser2": "^3.10.0"
+ },
+ "dependencies": {
+ "dom-serializer": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
+ "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^2.0.1",
+ "entities": "^2.0.0"
+ },
+ "dependencies": {
+ "domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true
+ },
+ "entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "dev": true
+ }
+ }
+ },
+ "domelementtype": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+ "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
+ "dev": true
+ },
+ "domhandler": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
+ "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1"
+ }
+ },
+ "domutils": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
+ "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
+ "dev": true,
+ "requires": {
+ "dom-serializer": "0",
+ "domelementtype": "1"
+ }
+ },
+ "entities": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+ "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
+ "dev": true
+ },
+ "htmlparser2": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
+ "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^1.3.1",
+ "domhandler": "^2.3.0",
+ "domutils": "^1.5.1",
+ "entities": "^1.1.1",
+ "inherits": "^2.0.1",
+ "readable-stream": "^3.1.1"
+ }
+ }
+ }
+ },
+ "postcss-image-set-function": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz",
+ "integrity": "sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2",
+ "postcss-values-parser": "^2.0.0"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-import": {
+ "version": "14.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.0.2.tgz",
+ "integrity": "sha512-BJ2pVK4KhUyMcqjuKs9RijV5tatNzNa73e/32aBVE/ejYPe37iH+6vAu9WvqUkB5OAYgLHzbSvzHnorybJCm9g==",
+ "dev": true,
+ "requires": {
+ "postcss-value-parser": "^4.0.0",
+ "read-cache": "^1.0.0",
+ "resolve": "^1.1.7"
+ }
+ },
+ "postcss-initial": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.4.tgz",
+ "integrity": "sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-lab-function": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz",
+ "integrity": "sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==",
+ "dev": true,
+ "requires": {
+ "@csstools/convert-colors": "^1.4.0",
+ "postcss": "^7.0.2",
+ "postcss-values-parser": "^2.0.0"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-less": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz",
+ "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.14"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-loader": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.1.1.tgz",
+ "integrity": "sha512-lBmJMvRh1D40dqpWKr9Rpygwxn8M74U9uaCSeYGNKLGInbk9mXBt1ultHf2dH9Ghk6Ue4UXlXWwGMH9QdUJ5ug==",
+ "dev": true,
+ "requires": {
+ "cosmiconfig": "^7.0.0",
+ "klona": "^2.0.4",
+ "semver": "^7.3.5"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "postcss-logical": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-3.0.0.tgz",
+ "integrity": "sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-media-minmax": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz",
+ "integrity": "sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-media-query-parser": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz",
+ "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==",
+ "dev": true
+ },
+ "postcss-merge-longhand": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.6.tgz",
+ "integrity": "sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw==",
+ "dev": true,
+ "requires": {
+ "postcss-value-parser": "^4.2.0",
+ "stylehacks": "^5.1.0"
+ }
+ },
+ "postcss-merge-rules": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.2.tgz",
+ "integrity": "sha512-zKMUlnw+zYCWoPN6yhPjtcEdlJaMUZ0WyVcxTAmw3lkkN/NDMRkOkiuctQEoWAOvH7twaxUUdvBWl0d4+hifRQ==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.16.6",
+ "caniuse-api": "^3.0.0",
+ "cssnano-utils": "^3.1.0",
+ "postcss-selector-parser": "^6.0.5"
+ }
+ },
+ "postcss-minify-font-values": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz",
+ "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==",
+ "dev": true,
+ "requires": {
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "postcss-minify-gradients": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz",
+ "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==",
+ "dev": true,
+ "requires": {
+ "colord": "^2.9.1",
+ "cssnano-utils": "^3.1.0",
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "postcss-minify-params": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.3.tgz",
+ "integrity": "sha512-bkzpWcjykkqIujNL+EVEPOlLYi/eZ050oImVtHU7b4lFS82jPnsCb44gvC6pxaNt38Els3jWYDHTjHKf0koTgg==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.16.6",
+ "cssnano-utils": "^3.1.0",
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "postcss-minify-selectors": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz",
+ "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==",
+ "dev": true,
+ "requires": {
+ "postcss-selector-parser": "^6.0.5"
+ }
+ },
+ "postcss-modules-extract-imports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
+ "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
+ "dev": true
+ },
+ "postcss-modules-local-by-default": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz",
+ "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==",
+ "dev": true,
+ "requires": {
+ "icss-utils": "^5.0.0",
+ "postcss-selector-parser": "^6.0.2",
+ "postcss-value-parser": "^4.1.0"
+ }
+ },
+ "postcss-modules-scope": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz",
+ "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==",
+ "dev": true,
+ "requires": {
+ "postcss-selector-parser": "^6.0.4"
+ }
+ },
+ "postcss-modules-values": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
+ "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
+ "dev": true,
+ "requires": {
+ "icss-utils": "^5.0.0"
+ }
+ },
+ "postcss-nesting": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz",
+ "integrity": "sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-normalize-charset": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz",
+ "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==",
+ "dev": true
+ },
+ "postcss-normalize-display-values": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz",
+ "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==",
+ "dev": true,
+ "requires": {
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "postcss-normalize-positions": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz",
+ "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==",
+ "dev": true,
+ "requires": {
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "postcss-normalize-repeat-style": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz",
+ "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==",
+ "dev": true,
+ "requires": {
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "postcss-normalize-string": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz",
+ "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==",
+ "dev": true,
+ "requires": {
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "postcss-normalize-timing-functions": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz",
+ "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==",
+ "dev": true,
+ "requires": {
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "postcss-normalize-unicode": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz",
+ "integrity": "sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.16.6",
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "postcss-normalize-url": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz",
+ "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==",
+ "dev": true,
+ "requires": {
+ "normalize-url": "^6.0.1",
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "postcss-normalize-whitespace": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz",
+ "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==",
+ "dev": true,
+ "requires": {
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "postcss-ordered-values": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz",
+ "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==",
+ "dev": true,
+ "requires": {
+ "cssnano-utils": "^3.1.0",
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "postcss-overflow-shorthand": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz",
+ "integrity": "sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-page-break": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-2.0.0.tgz",
+ "integrity": "sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-place": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-4.0.1.tgz",
+ "integrity": "sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2",
+ "postcss-values-parser": "^2.0.0"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-preset-env": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz",
+ "integrity": "sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg==",
+ "dev": true,
+ "requires": {
+ "autoprefixer": "^9.6.1",
+ "browserslist": "^4.6.4",
+ "caniuse-lite": "^1.0.30000981",
+ "css-blank-pseudo": "^0.1.4",
+ "css-has-pseudo": "^0.10.0",
+ "css-prefers-color-scheme": "^3.1.1",
+ "cssdb": "^4.4.0",
+ "postcss": "^7.0.17",
+ "postcss-attribute-case-insensitive": "^4.0.1",
+ "postcss-color-functional-notation": "^2.0.1",
+ "postcss-color-gray": "^5.0.0",
+ "postcss-color-hex-alpha": "^5.0.3",
+ "postcss-color-mod-function": "^3.0.3",
+ "postcss-color-rebeccapurple": "^4.0.1",
+ "postcss-custom-media": "^7.0.8",
+ "postcss-custom-properties": "^8.0.11",
+ "postcss-custom-selectors": "^5.1.2",
+ "postcss-dir-pseudo-class": "^5.0.0",
+ "postcss-double-position-gradients": "^1.0.0",
+ "postcss-env-function": "^2.0.2",
+ "postcss-focus-visible": "^4.0.0",
+ "postcss-focus-within": "^3.0.0",
+ "postcss-font-variant": "^4.0.0",
+ "postcss-gap-properties": "^2.0.0",
+ "postcss-image-set-function": "^3.0.1",
+ "postcss-initial": "^3.0.0",
+ "postcss-lab-function": "^2.0.1",
+ "postcss-logical": "^3.0.0",
+ "postcss-media-minmax": "^4.0.0",
+ "postcss-nesting": "^7.0.0",
+ "postcss-overflow-shorthand": "^2.0.0",
+ "postcss-page-break": "^2.0.0",
+ "postcss-place": "^4.0.1",
+ "postcss-pseudo-class-any-link": "^6.0.0",
+ "postcss-replace-overflow-wrap": "^3.0.0",
+ "postcss-selector-matches": "^4.0.0",
+ "postcss-selector-not": "^4.0.0"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-pseudo-class-any-link": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz",
+ "integrity": "sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2",
+ "postcss-selector-parser": "^5.0.0-rc.3"
+ },
+ "dependencies": {
+ "cssesc": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
+ "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
+ "dev": true
+ },
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "postcss-selector-parser": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
+ "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
+ "dev": true,
+ "requires": {
+ "cssesc": "^2.0.0",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-reduce-initial": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz",
+ "integrity": "sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.16.6",
+ "caniuse-api": "^3.0.0"
+ }
+ },
+ "postcss-reduce-transforms": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz",
+ "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==",
+ "dev": true,
+ "requires": {
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "postcss-replace-overflow-wrap": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz",
+ "integrity": "sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-resolve-nested-selector": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz",
+ "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==",
+ "dev": true
+ },
+ "postcss-safe-parser": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz",
+ "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.26"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-sass": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.4.4.tgz",
+ "integrity": "sha512-BYxnVYx4mQooOhr+zer0qWbSPYnarAy8ZT7hAQtbxtgVf8gy+LSLT/hHGe35h14/pZDTw1DsxdbrwxBN++H+fg==",
+ "dev": true,
+ "requires": {
+ "gonzales-pe": "^4.3.0",
+ "postcss": "^7.0.21"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-scss": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz",
+ "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.6"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-selector-matches": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz",
+ "integrity": "sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "postcss": "^7.0.2"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-selector-not": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz",
+ "integrity": "sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "postcss": "^7.0.2"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-selector-parser": {
+ "version": "6.0.10",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
+ "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
+ "dev": true,
+ "requires": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ }
+ },
+ "postcss-sorting": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-5.0.1.tgz",
+ "integrity": "sha512-Y9fUFkIhfrm6i0Ta3n+89j56EFqaNRdUKqXyRp6kvTcSXnmgEjaVowCXH+JBe9+YKWqd4nc28r2sgwnzJalccA==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.14",
+ "postcss": "^7.0.17"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-svgo": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz",
+ "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==",
+ "dev": true,
+ "requires": {
+ "postcss-value-parser": "^4.2.0",
+ "svgo": "^2.7.0"
+ }
+ },
+ "postcss-syntax": {
+ "version": "0.36.2",
+ "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz",
+ "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==",
+ "dev": true
+ },
+ "postcss-unique-selectors": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz",
+ "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==",
+ "dev": true,
+ "requires": {
+ "postcss-selector-parser": "^6.0.5"
+ }
+ },
+ "postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "dev": true
+ },
+ "postcss-values-parser": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz",
+ "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==",
+ "dev": true,
+ "requires": {
+ "flatten": "^1.0.2",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ },
+ "preceptor-core": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/preceptor-core/-/preceptor-core-0.10.1.tgz",
+ "integrity": "sha512-WLDk+UowEESixvlhiamGOj/iqWrp8IWeCCHvBZrLh0g4/A1Fa77fDQWqQUd5S5rScT+9u49aDfa45xYRkxqmiA==",
+ "dev": true,
+ "requires": {
+ "log4js": "1.1.1",
+ "underscore": "1.7.0"
+ }
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==",
+ "dev": true
+ },
+ "prettier": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz",
+ "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==",
+ "dev": true
+ },
+ "pretty-bytes": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
+ "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz",
+ "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^4.0.0",
+ "react-is": "^16.12.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ }
+ }
+ },
+ "pretty-quick": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.0.2.tgz",
+ "integrity": "sha512-4rWOs/Ifdkg7G/YX7Xbco4jZkuXPx445KdhuMI6REnl3nXRDb9+zysb29c76R59jsJzcnkcpAaGi8D/RjAVfSQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^3.0.0",
+ "execa": "^4.0.0",
+ "find-up": "^4.1.0",
+ "ignore": "^5.1.4",
+ "mri": "^1.1.5",
+ "multimatch": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "execa": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
+ "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.0",
+ "get-stream": "^5.0.0",
+ "human-signals": "^1.1.1",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.0",
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2",
+ "strip-final-newline": "^2.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true
+ },
+ "npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.0.0"
+ }
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "prismjs": {
+ "version": "1.29.0",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
+ "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q=="
+ },
+ "process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
+ "dev": true
+ },
+ "process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true
+ },
+ "progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true
+ },
+ "promise": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-6.0.0.tgz",
+ "integrity": "sha512-PjIqIEWR8EWwP5ml3Wf5KWIP3sIdXAew9vQ6vLOLV+z4LMa/8ZQyLd7sTWe2r8OuA8A9jsIYptDfbEn/L36ogw==",
+ "dev": true,
+ "requires": {
+ "asap": "~1.0.0"
+ }
+ },
+ "promise-inflight": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+ "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
+ "dev": true
+ },
+ "promise-retry": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
+ "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
+ "dev": true,
+ "requires": {
+ "err-code": "^2.0.2",
+ "retry": "^0.12.0"
+ }
+ },
+ "prompts": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
+ "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
+ "dev": true,
+ "requires": {
+ "kleur": "^3.0.3",
+ "sisteransi": "^1.0.5"
+ }
+ },
+ "prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "requires": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "property-information": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz",
+ "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==",
+ "requires": {
+ "xtend": "^4.0.0"
+ }
+ },
+ "protobufjs": {
+ "version": "6.11.3",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz",
+ "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==",
+ "dev": true,
+ "requires": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.4",
+ "@protobufjs/eventemitter": "^1.1.0",
+ "@protobufjs/fetch": "^1.1.0",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/inquire": "^1.1.0",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.0",
+ "@types/long": "^4.0.1",
+ "@types/node": ">=13.7.0",
+ "long": "^4.0.0"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "18.7.16",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.16.tgz",
+ "integrity": "sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg==",
+ "dev": true
+ }
+ }
+ },
+ "proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "dev": true,
+ "requires": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ }
+ },
+ "proxy-from-env": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
+ "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==",
+ "dev": true
+ },
+ "proxy-middleware": {
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz",
+ "integrity": "sha512-EGCG8SeoIRVMhsqHQUdDigB2i7qU7fCsWASwn54+nPutYO8n4q6EiwMzyfWlC+dzRFExP+kvcnDFdBDHoZBU7Q==",
+ "dev": true
+ },
+ "prr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+ "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
+ "dev": true
+ },
+ "ps-tree": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz",
+ "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==",
+ "dev": true,
+ "requires": {
+ "event-stream": "=3.3.4"
+ },
+ "dependencies": {
+ "event-stream": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
+ "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==",
+ "dev": true,
+ "requires": {
+ "duplexer": "~0.1.1",
+ "from": "~0",
+ "map-stream": "~0.1.0",
+ "pause-stream": "0.0.11",
+ "split": "0.3",
+ "stream-combiner": "~0.0.4",
+ "through": "~2.3.1"
+ }
+ },
+ "map-stream": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
+ "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==",
+ "dev": true
+ },
+ "split": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
+ "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==",
+ "dev": true,
+ "requires": {
+ "through": "2"
+ }
+ },
+ "stream-combiner": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
+ "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==",
+ "dev": true,
+ "requires": {
+ "duplexer": "~0.1.1"
+ }
+ }
+ }
+ },
+ "psl": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
+ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
+ "dev": true
+ },
+ "public-encrypt": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+ "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "parse-asn1": "^5.0.0",
+ "randombytes": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+ "dev": true
+ }
+ }
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "punycode": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+ "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw=="
+ },
+ "qs": {
+ "version": "6.11.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
+ "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+ "requires": {
+ "side-channel": "^1.0.4"
+ }
+ },
+ "querystring": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+ "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g=="
+ },
+ "querystring-es3": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+ "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==",
+ "dev": true
+ },
+ "querystringify": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
+ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
+ },
+ "queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true
+ },
+ "quick-lru": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
+ "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==",
+ "dev": true
+ },
+ "quote-stream": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/quote-stream/-/quote-stream-1.0.2.tgz",
+ "integrity": "sha512-kKr2uQ2AokadPjvTyKJQad9xELbZwYzWlNfI3Uz2j/ib5u6H9lDP7fUUR//rMycd0gv4Z5P1qXMfXR8YpIxrjQ==",
+ "dev": true,
+ "requires": {
+ "buffer-equal": "0.0.1",
+ "minimist": "^1.1.3",
+ "through2": "^2.0.0"
+ }
+ },
+ "randexp": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz",
+ "integrity": "sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==",
+ "requires": {
+ "drange": "^1.0.2",
+ "ret": "^0.2.0"
+ }
+ },
+ "randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "requires": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "randomfill": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.0.5",
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "dev": true
+ },
+ "raw-body": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
+ "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+ "dev": true,
+ "requires": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "dependencies": {
+ "bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "dev": true
+ }
+ }
+ },
+ "react": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
+ "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==",
+ "requires": {
+ "loose-envify": "^1.1.0",
+ "object-assign": "^4.1.1"
+ }
+ },
+ "react-copy-to-clipboard": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.4.tgz",
+ "integrity": "sha512-IeVAiNVKjSPeGax/Gmkqfa/+PuMTBhutEvFUaMQLwE2tS0EXrAdgOpWDX26bWTXF3HrioorR7lr08NqeYUWQCQ==",
+ "requires": {
+ "copy-to-clipboard": "^3",
+ "prop-types": "^15.5.8"
+ }
+ },
+ "react-debounce-input": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/react-debounce-input/-/react-debounce-input-3.2.4.tgz",
+ "integrity": "sha512-fX70bNj0fLEYO2Zcvuh7eh9wOUQ29GIx6r8IxIJlc0i0mpUH++9ax0BhfAYfzndADli3RAMROrZQ014J01owrg==",
+ "requires": {
+ "lodash.debounce": "^4",
+ "prop-types": "^15.7.2"
+ }
+ },
+ "react-dom": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
+ "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==",
+ "requires": {
+ "loose-envify": "^1.1.0",
+ "object-assign": "^4.1.1",
+ "scheduler": "^0.20.2"
+ }
+ },
+ "react-immutable-proptypes": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz",
+ "integrity": "sha512-Vf4gBsePlwdGvSZoLSBfd4HAP93HDauMY4fDjXhreg/vg6F3Fj/MXDNyTbltPC/xZKmZc+cjLu3598DdYK6sgQ==",
+ "requires": {
+ "invariant": "^2.2.2"
+ }
+ },
+ "react-immutable-pure-component": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/react-immutable-pure-component/-/react-immutable-pure-component-2.2.2.tgz",
+ "integrity": "sha512-vkgoMJUDqHZfXXnjVlG3keCxSO/U6WeDQ5/Sl0GK2cH8TOxEzQ5jXqDXHEL/jqk6fsNxV05oH5kD7VNMUE2k+A=="
+ },
+ "react-inspector": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-5.1.1.tgz",
+ "integrity": "sha512-GURDaYzoLbW8pMGXwYPDBIv6nqei4kK7LPRZ9q9HCZF54wqXz/dnylBp/kfE9XmekBhHvLDdcYeyIwSrvtOiWg==",
+ "requires": {
+ "@babel/runtime": "^7.0.0",
+ "is-dom": "^1.0.0",
+ "prop-types": "^15.0.0"
+ }
+ },
+ "react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
+ "react-redux": {
+ "version": "7.2.8",
+ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.8.tgz",
+ "integrity": "sha512-6+uDjhs3PSIclqoCk0kd6iX74gzrGc3W5zcAjbrFgEdIjRSQObdIwfx80unTkVUYvbQ95Y8Av3OvFHq1w5EOUw==",
+ "requires": {
+ "@babel/runtime": "^7.15.4",
+ "@types/react-redux": "^7.1.20",
+ "hoist-non-react-statics": "^3.3.2",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.7.2",
+ "react-is": "^17.0.2"
+ },
+ "dependencies": {
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
+ }
+ }
+ },
+ "react-syntax-highlighter": {
+ "version": "15.5.0",
+ "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz",
+ "integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "highlight.js": "^10.4.1",
+ "lowlight": "^1.17.0",
+ "prismjs": "^1.27.0",
+ "refractor": "^3.6.0"
+ }
+ },
+ "read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
+ "dev": true,
+ "requires": {
+ "pify": "^2.3.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "dev": true
+ }
+ }
+ },
+ "read-only-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz",
+ "integrity": "sha512-3ALe0bjBVZtkdWKIcThYpQCLbBMd/+Tbh2CDSrAIDO3UsZ4Xs+tnyjv2MjCOMMgBG+AsUOeuP1cgtY1INISc8w==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.2"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "read-package-json-fast": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz",
+ "integrity": "sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ==",
+ "dev": true,
+ "requires": {
+ "json-parse-even-better-errors": "^2.3.0",
+ "npm-normalize-package-bin": "^1.0.1"
+ }
+ },
+ "read-pkg": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
+ "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
+ "dev": true,
+ "requires": {
+ "@types/normalize-package-data": "^2.4.0",
+ "normalize-package-data": "^2.5.0",
+ "parse-json": "^5.0.0",
+ "type-fest": "^0.6.0"
+ },
+ "dependencies": {
+ "type-fest": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
+ "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
+ "dev": true
+ }
+ }
+ },
+ "read-pkg-up": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
+ "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
+ "dev": true,
+ "requires": {
+ "find-up": "^4.1.0",
+ "read-pkg": "^5.2.0",
+ "type-fest": "^0.8.1"
+ },
+ "dependencies": {
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+ "dev": true
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "requires": {
+ "picomatch": "^2.2.1"
+ }
+ },
+ "rechoir": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+ "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
+ "dev": true,
+ "requires": {
+ "resolve": "^1.1.6"
+ }
+ },
+ "redent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
+ "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
+ "dev": true,
+ "requires": {
+ "indent-string": "^4.0.0",
+ "strip-indent": "^3.0.0"
+ }
+ },
+ "redux": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz",
+ "integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==",
+ "requires": {
+ "@babel/runtime": "^7.9.2"
+ }
+ },
+ "redux-immutable": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/redux-immutable/-/redux-immutable-4.0.0.tgz",
+ "integrity": "sha512-SchSn/DWfGb3oAejd+1hhHx01xUoxY+V7TeK0BKqpkLKiQPVFf7DYzEaKmrEVxsWxielKfSK9/Xq66YyxgR1cg=="
+ },
+ "reflect-metadata": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
+ "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==",
+ "dev": true
+ },
+ "refractor": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz",
+ "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==",
+ "requires": {
+ "hastscript": "^6.0.0",
+ "parse-entities": "^2.0.0",
+ "prismjs": "~1.27.0"
+ },
+ "dependencies": {
+ "prismjs": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
+ "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA=="
+ }
+ }
+ },
+ "regenerate": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
+ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
+ "dev": true
+ },
+ "regenerate-unicode-properties": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz",
+ "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==",
+ "dev": true,
+ "requires": {
+ "regenerate": "^1.4.2"
+ }
+ },
+ "regenerator-runtime": {
+ "version": "0.13.9",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
+ "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
+ },
+ "regenerator-transform": {
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz",
+ "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==",
+ "dev": true,
+ "requires": {
+ "@babel/runtime": "^7.8.4"
+ }
+ },
+ "regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.2",
+ "safe-regex": "^1.1.0"
+ }
+ },
+ "regex-parser": {
+ "version": "2.2.11",
+ "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz",
+ "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==",
+ "dev": true
+ },
+ "regexp.prototype.flags": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
+ "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "functions-have-names": "^1.2.2"
+ }
+ },
+ "regexpu-core": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.1.0.tgz",
+ "integrity": "sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA==",
+ "dev": true,
+ "requires": {
+ "regenerate": "^1.4.2",
+ "regenerate-unicode-properties": "^10.0.1",
+ "regjsgen": "^0.6.0",
+ "regjsparser": "^0.8.2",
+ "unicode-match-property-ecmascript": "^2.0.0",
+ "unicode-match-property-value-ecmascript": "^2.0.0"
+ }
+ },
+ "regjsgen": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz",
+ "integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==",
+ "dev": true
+ },
+ "regjsparser": {
+ "version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz",
+ "integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==",
+ "dev": true,
+ "requires": {
+ "jsesc": "~0.5.0"
+ },
+ "dependencies": {
+ "jsesc": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
+ "dev": true
+ }
+ }
+ },
+ "remark": {
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz",
+ "integrity": "sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==",
+ "dev": true,
+ "requires": {
+ "remark-parse": "^9.0.0",
+ "remark-stringify": "^9.0.0",
+ "unified": "^9.1.0"
+ }
+ },
+ "remark-parse": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz",
+ "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==",
+ "dev": true,
+ "requires": {
+ "mdast-util-from-markdown": "^0.8.0"
+ }
+ },
+ "remark-stringify": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz",
+ "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==",
+ "dev": true,
+ "requires": {
+ "mdast-util-to-markdown": "^0.6.0"
+ }
+ },
+ "remarkable": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-2.0.1.tgz",
+ "integrity": "sha512-YJyMcOH5lrR+kZdmB0aJJ4+93bEojRZ1HGDn9Eagu6ibg7aVZhc3OWbbShRid+Q5eAfsEqWxpe+g5W5nYNfNiA==",
+ "requires": {
+ "argparse": "^1.0.10",
+ "autolinker": "^3.11.0"
+ },
+ "dependencies": {
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ }
+ }
+ },
+ "remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==",
+ "dev": true
+ },
+ "repeat-element": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz",
+ "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==",
+ "dev": true
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w=="
+ },
+ "request": {
+ "version": "2.88.2",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+ "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.3",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.5.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ },
+ "dependencies": {
+ "qs": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
+ "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
+ "dev": true
+ },
+ "uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+ "dev": true
+ }
+ }
+ },
+ "request-progress": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz",
+ "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==",
+ "dev": true,
+ "requires": {
+ "throttleit": "^1.0.0"
+ }
+ },
+ "request-promise-core": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
+ "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.19"
+ }
+ },
+ "request-promise-native": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
+ "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
+ "dev": true,
+ "requires": {
+ "request-promise-core": "1.1.4",
+ "stealthy-require": "^1.1.1",
+ "tough-cookie": "^2.3.3"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
+ },
+ "require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true
+ },
+ "require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+ "dev": true
+ },
+ "requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
+ },
+ "reselect": {
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.6.tgz",
+ "integrity": "sha512-ZovIuXqto7elwnxyXbBtCPo9YFEr3uJqj2rRbcOOog1bmu2Ag85M4hixSwFWyaBMKXNgvPaJ9OSu9SkBPIeJHQ=="
+ },
+ "resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "requires": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
+ },
+ "resolve-as-bin": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/resolve-as-bin/-/resolve-as-bin-2.1.0.tgz",
+ "integrity": "sha512-ileUuPIOP+xj+GS/d/EbB2XqRA8T2IeZTFkMggNIW2Mo72VyBMbq+HvIAxdW0ED9D44aEzJwHvUtbMm2PJT5Kw==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^6.0.5"
+ }
+ },
+ "resolve-cwd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
+ "integrity": "sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg==",
+ "dev": true,
+ "requires": {
+ "resolve-from": "^3.0.0"
+ },
+ "dependencies": {
+ "resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==",
+ "dev": true
+ }
+ }
+ },
+ "resolve-dir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
+ "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "^2.0.0",
+ "global-modules": "^1.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true
+ },
+ "resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==",
+ "dev": true
+ },
+ "resolve-url-loader": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz",
+ "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==",
+ "dev": true,
+ "requires": {
+ "adjust-sourcemap-loader": "^4.0.0",
+ "convert-source-map": "^1.7.0",
+ "loader-utils": "^2.0.0",
+ "postcss": "^7.0.35",
+ "source-map": "0.6.1"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "dev": true,
+ "requires": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "ret": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz",
+ "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ=="
+ },
+ "retry": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
+ "dev": true
+ },
+ "reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true
+ },
+ "rfdc": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
+ "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "ripemd160": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+ "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+ "dev": true,
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1"
+ }
+ },
+ "rsvp": {
+ "version": "4.8.5",
+ "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz",
+ "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==",
+ "dev": true
+ },
+ "run-async": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
+ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
+ "dev": true
+ },
+ "run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "requires": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "rxjs": {
+ "version": "6.6.3",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz",
+ "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==",
+ "requires": {
+ "tslib": "^1.9.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==",
+ "dev": true,
+ "requires": {
+ "ret": "~0.1.10"
+ },
+ "dependencies": {
+ "ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "dev": true
+ }
+ }
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
+ "sane": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz",
+ "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==",
+ "dev": true,
+ "requires": {
+ "@cnakazawa/watch": "^1.0.3",
+ "anymatch": "^2.0.0",
+ "capture-exit": "^2.0.0",
+ "exec-sh": "^0.3.2",
+ "execa": "^1.0.0",
+ "fb-watchman": "^2.0.0",
+ "micromatch": "^3.1.4",
+ "minimist": "^1.1.1",
+ "walker": "~1.0.5"
+ },
+ "dependencies": {
+ "anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "dev": true,
+ "requires": {
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
+ }
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==",
+ "dev": true,
+ "requires": {
+ "remove-trailing-separator": "^1.0.1"
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ }
+ }
+ }
+ },
+ "sass": {
+ "version": "1.36.0",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.36.0.tgz",
+ "integrity": "sha512-fQzEjipfOv5kh930nu3Imzq3ie/sGDc/4KtQMJlt7RRdrkQSfe37Bwi/Rf/gfuYHsIuE1fIlDMvpyMcEwjnPvg==",
+ "dev": true,
+ "requires": {
+ "chokidar": ">=3.0.0 <4.0.0"
+ }
+ },
+ "sass-loader": {
+ "version": "12.1.0",
+ "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.1.0.tgz",
+ "integrity": "sha512-FVJZ9kxVRYNZTIe2xhw93n3xJNYZADr+q69/s98l9nTCrWASo+DR2Ot0s5xTKQDDEosUkatsGeHxcH4QBp5bSg==",
+ "dev": true,
+ "requires": {
+ "klona": "^2.0.4",
+ "neo-async": "^2.6.2"
+ }
+ },
+ "sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+ "dev": true
+ },
+ "saxes": {
+ "version": "3.1.11",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz",
+ "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==",
+ "dev": true,
+ "requires": {
+ "xmlchars": "^2.1.1"
+ }
+ },
+ "scheduler": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
+ "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
+ "requires": {
+ "loose-envify": "^1.1.0",
+ "object-assign": "^4.1.1"
+ }
+ },
+ "schema-utils": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
+ "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.5",
+ "ajv": "^6.12.4",
+ "ajv-keywords": "^3.5.2"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ }
+ }
+ },
+ "scope-analyzer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/scope-analyzer/-/scope-analyzer-2.1.2.tgz",
+ "integrity": "sha512-5cfCmsTYV/wPaRIItNxatw02ua/MThdIUNnUOCYp+3LSEJvnG804ANw2VLaavNILIfWXF1D1G2KNANkBBvInwQ==",
+ "dev": true,
+ "requires": {
+ "array-from": "^2.1.1",
+ "dash-ast": "^2.0.1",
+ "es6-map": "^0.1.5",
+ "es6-set": "^0.1.5",
+ "es6-symbol": "^3.1.1",
+ "estree-is-function": "^1.0.0",
+ "get-assigned-identifiers": "^1.1.0"
+ }
+ },
+ "seed-random": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/seed-random/-/seed-random-2.2.0.tgz",
+ "integrity": "sha512-34EQV6AAHQGhoc0tn/96a9Fsi6v2xdqe/dMUwljGRaFOzR3EgRmECvD0O8vi8X+/uQ50LGHfkNu/Eue5TPKZkQ==",
+ "dev": true
+ },
+ "select-hose": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
+ "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==",
+ "dev": true
+ },
+ "selfsigned": {
+ "version": "1.10.14",
+ "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.14.tgz",
+ "integrity": "sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA==",
+ "dev": true,
+ "requires": {
+ "node-forge": "^0.10.0"
+ }
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+ },
+ "semver-dsl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz",
+ "integrity": "sha512-e8BOaTo007E3dMuQQTnPdalbKTABKNS7UxoBIDnwOqRa+QwMrCPjynB8zAlPF6xlqUfdLPPLIJ13hJNmhtq8Ng==",
+ "dev": true,
+ "requires": {
+ "semver": "^5.3.0"
+ }
+ },
+ "send": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
+ "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+ "dev": true,
+ "requires": {
+ "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"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ }
+ }
+ },
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ }
+ }
+ },
+ "serialize-error": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz",
+ "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==",
+ "requires": {
+ "type-fest": "^0.20.2"
+ }
+ },
+ "serialize-javascript": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
+ "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "serve-index": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+ "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==",
+ "dev": true,
+ "requires": {
+ "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"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
+ "dev": true
+ },
+ "http-errors": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==",
+ "dev": true,
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.0",
+ "statuses": ">= 1.4.0 < 2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ },
+ "setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+ "dev": true
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+ "dev": true
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
+ "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
+ "dev": true,
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.18.0"
+ }
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
+ "dev": true
+ },
+ "set-value": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+ "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.3",
+ "split-string": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ }
+ }
+ },
+ "setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "dev": true
+ },
+ "sha.js": {
+ "version": "2.4.11",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "shallow-clone": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
+ "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.2"
+ }
+ },
+ "shallow-copy": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz",
+ "integrity": "sha512-b6i4ZpVuUxB9h5gfCxPiusKYkqTMOjEbBs4wMaFbkfia4yFv92UKZ6Df8WXcKbn08JNL/abvg3FnMAOfakDvUw==",
+ "dev": true
+ },
+ "shasum": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz",
+ "integrity": "sha512-UTzHm/+AzKfO9RgPgRpDIuMSNie1ubXRaljjlhFMNGYoG7z+rm9AHLPMf70R7887xboDH9Q+5YQbWKObFHEAtw==",
+ "dev": true,
+ "requires": {
+ "json-stable-stringify": "~0.0.0",
+ "sha.js": "~2.4.4"
+ }
+ },
+ "shasum-object": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shasum-object/-/shasum-object-1.0.0.tgz",
+ "integrity": "sha512-Iqo5rp/3xVi6M4YheapzZhhGPVs0yZwHj7wvwQ1B9z8H6zk+FEnI7y3Teq7qwnekfEhu8WmG2z0z4iWZaxLWVg==",
+ "dev": true,
+ "requires": {
+ "fast-safe-stringify": "^2.0.7"
+ }
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
+ "dev": true
+ },
+ "shell-quote": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz",
+ "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==",
+ "dev": true
+ },
+ "shellwords": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
+ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
+ "dev": true,
+ "optional": true
+ },
+ "side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "requires": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ }
+ },
+ "signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
+ },
+ "simple-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+ "dev": true
+ },
+ "simplebar": {
+ "version": "5.3.8",
+ "resolved": "https://registry.npmjs.org/simplebar/-/simplebar-5.3.8.tgz",
+ "integrity": "sha512-LOHjyOcihx++zFN+vuktoZBGpCarFCtHIVDWXOf2VELbGDknq3Hw/sddafRp1aCg123VNkHWOFHUDHYEXAtufQ==",
+ "requires": {
+ "@juggle/resize-observer": "^3.3.1",
+ "can-use-dom": "^0.1.0",
+ "core-js": "^3.0.1",
+ "lodash.debounce": "^4.0.8",
+ "lodash.memoize": "^4.1.2",
+ "lodash.throttle": "^4.1.1"
+ }
+ },
+ "simplebar-angular": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/simplebar-angular/-/simplebar-angular-2.3.6.tgz",
+ "integrity": "sha512-chSUdCYCLOdajbCA73oL/OU+H/YFNGGdAYkcYx76YDY81C3sj3vMePjuW8cPgZZHwSCGI+opcl6xoBsCK56fJA==",
+ "requires": {
+ "simplebar": "^5.3.6",
+ "tslib": "^1.9.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
+ "sisteransi": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+ "dev": true
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
+ "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ }
+ }
+ },
+ "smart-buffer": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
+ "dev": true
+ },
+ "snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "dev": true,
+ "requires": {
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ }
+ }
+ },
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "dev": true,
+ "requires": {
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.0",
+ "snapdragon-util": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.2.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "sockjs": {
+ "version": "0.3.24",
+ "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
+ "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==",
+ "dev": true,
+ "requires": {
+ "faye-websocket": "^0.11.3",
+ "uuid": "^8.3.2",
+ "websocket-driver": "^0.7.4"
+ }
+ },
+ "sockjs-client": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.6.1.tgz",
+ "integrity": "sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw==",
+ "dev": true,
+ "requires": {
+ "debug": "^3.2.7",
+ "eventsource": "^2.0.2",
+ "faye-websocket": "^0.11.4",
+ "inherits": "^2.0.4",
+ "url-parse": "^1.5.10"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "socks": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.0.tgz",
+ "integrity": "sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==",
+ "dev": true,
+ "requires": {
+ "ip": "^2.0.0",
+ "smart-buffer": "^4.2.0"
+ },
+ "dependencies": {
+ "ip": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
+ "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==",
+ "dev": true
+ }
+ }
+ },
+ "socks-proxy-agent": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz",
+ "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
+ "dev": true,
+ "requires": {
+ "agent-base": "^6.0.2",
+ "debug": "^4.3.3",
+ "socks": "^2.6.2"
+ }
+ },
+ "source-list-map": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
+ "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="
+ },
+ "source-map-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "dev": true
+ },
+ "source-map-loader": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.0.tgz",
+ "integrity": "sha512-GKGWqWvYr04M7tn8dryIWvb0s8YM41z82iQv01yBtIylgxax0CwvSy6gc2Y02iuXwEfGWRlMicH0nvms9UZphw==",
+ "dev": true,
+ "requires": {
+ "abab": "^2.0.5",
+ "iconv-lite": "^0.6.2",
+ "source-map-js": "^0.6.2"
+ },
+ "dependencies": {
+ "iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ }
+ },
+ "source-map-js": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz",
+ "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==",
+ "dev": true
+ }
+ }
+ },
+ "source-map-resolve": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+ "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+ "dev": true,
+ "requires": {
+ "atob": "^2.1.2",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ }
+ },
+ "source-map-support": {
+ "version": "0.5.19",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+ "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "source-map-url": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz",
+ "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
+ "dev": true
+ },
+ "sourcemap-codec": {
+ "version": "1.4.8",
+ "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
+ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
+ "dev": true
+ },
+ "space-separated-tokens": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz",
+ "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA=="
+ },
+ "spdx-correct": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
+ "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+ "dev": true,
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+ "dev": true
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.12",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz",
+ "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==",
+ "dev": true
+ },
+ "spdy": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
+ "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.0",
+ "handle-thing": "^2.0.0",
+ "http-deceiver": "^1.2.7",
+ "select-hose": "^2.0.0",
+ "spdy-transport": "^3.0.0"
+ }
+ },
+ "spdy-transport": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz",
+ "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "specificity": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz",
+ "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==",
+ "dev": true
+ },
+ "split": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
+ "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
+ "dev": true,
+ "requires": {
+ "through": "2"
+ }
+ },
+ "split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.0"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="
+ },
+ "sshpk": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
+ "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
+ "dev": true,
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ }
+ },
+ "ssri": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
+ "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.1.1"
+ }
+ },
+ "stable": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
+ "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
+ "dev": true
+ },
+ "stack-chain": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-2.0.0.tgz",
+ "integrity": "sha512-GGrHXePi305aW7XQweYZZwiRwR7Js3MWoK/EHzzB9ROdc75nCnjSJVi21rdAGxFl+yCx2L2qdfl5y7NO4lTyqg==",
+ "dev": true
+ },
+ "stack-generator": {
+ "version": "2.0.10",
+ "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz",
+ "integrity": "sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==",
+ "dev": true,
+ "requires": {
+ "stackframe": "^1.3.4"
+ }
+ },
+ "stack-trace": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+ "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==",
+ "dev": true
+ },
+ "stack-utils": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz",
+ "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^2.0.0"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true
+ }
+ }
+ },
+ "stackframe": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz",
+ "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
+ "dev": true
+ },
+ "stacktrace-gps": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-3.1.2.tgz",
+ "integrity": "sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==",
+ "dev": true,
+ "requires": {
+ "source-map": "0.5.6",
+ "stackframe": "^1.3.4"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
+ "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==",
+ "dev": true
+ }
+ }
+ },
+ "stacktrace-js": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.2.tgz",
+ "integrity": "sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==",
+ "dev": true,
+ "requires": {
+ "error-stack-parser": "^2.0.6",
+ "stack-generator": "^2.0.5",
+ "stacktrace-gps": "^3.0.4"
+ }
+ },
+ "start-server-and-test": {
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.12.1.tgz",
+ "integrity": "sha512-qGQ2HQiF2yDIfyaHsXkHfoE5UOl4zJUbJ/gx2xOkfX7iPMXW9qHmoFyaMfIDJVLNkxCK7RxSrvWEI9hNVKQluw==",
+ "dev": true,
+ "requires": {
+ "bluebird": "3.7.2",
+ "check-more-types": "2.24.0",
+ "debug": "4.3.1",
+ "execa": "3.4.0",
+ "lazy-ass": "1.6.0",
+ "ps-tree": "1.2.0",
+ "wait-on": "5.3.0"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "execa": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz",
+ "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.0",
+ "get-stream": "^5.0.0",
+ "human-signals": "^1.1.1",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.0",
+ "onetime": "^5.1.0",
+ "p-finally": "^2.0.0",
+ "signal-exit": "^3.0.2",
+ "strip-final-newline": "^2.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true
+ },
+ "npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.0.0"
+ }
+ },
+ "p-finally": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz",
+ "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==",
+ "dev": true
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "static-eval": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.0.tgz",
+ "integrity": "sha512-agtxZ/kWSsCkI5E4QifRwsaPs0P0JmZV6dkLz6ILYfFYQGn+5plctanRN+IC8dJRiFkyXHrwEE3W9Wmx67uDbw==",
+ "dev": true,
+ "requires": {
+ "escodegen": "^1.11.1"
+ }
+ },
+ "static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==",
+ "dev": true,
+ "requires": {
+ "define-property": "^0.2.5",
+ "object-copy": "^0.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ }
+ }
+ },
+ "static-module": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/static-module/-/static-module-3.0.4.tgz",
+ "integrity": "sha512-gb0v0rrgpBkifXCa3yZXxqVmXDVE+ETXj6YlC/jt5VzOnGXR2C15+++eXuMDUYsePnbhf+lwW0pE1UXyOLtGCw==",
+ "dev": true,
+ "requires": {
+ "acorn-node": "^1.3.0",
+ "concat-stream": "~1.6.0",
+ "convert-source-map": "^1.5.1",
+ "duplexer2": "~0.1.4",
+ "escodegen": "^1.11.1",
+ "has": "^1.0.1",
+ "magic-string": "0.25.1",
+ "merge-source-map": "1.0.4",
+ "object-inspect": "^1.6.0",
+ "readable-stream": "~2.3.3",
+ "scope-analyzer": "^2.0.1",
+ "shallow-copy": "~0.0.1",
+ "static-eval": "^2.0.5",
+ "through2": "~2.0.3"
+ },
+ "dependencies": {
+ "magic-string": {
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.1.tgz",
+ "integrity": "sha512-sCuTz6pYom8Rlt4ISPFn6wuFodbKMIHUMv4Qko9P17dpxb7s52KJTmRuZZqHdGmLCK9AOcDare039nRIcfdkEg==",
+ "dev": true,
+ "requires": {
+ "sourcemap-codec": "^1.4.1"
+ }
+ },
+ "merge-source-map": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz",
+ "integrity": "sha512-PGSmS0kfnTnMJCzJ16BLLCEe6oeYCamKFFdQKshi4BmM6FUwipjVOcBFGxqtQtirtAG4iZvHlqST9CpZKqlRjA==",
+ "dev": true,
+ "requires": {
+ "source-map": "^0.5.6"
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "dev": true
+ },
+ "stealthy-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+ "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==",
+ "dev": true
+ },
+ "stream-browserify": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
+ "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
+ "dev": true,
+ "requires": {
+ "inherits": "~2.0.1",
+ "readable-stream": "^2.0.2"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "stream-buffers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-1.0.1.tgz",
+ "integrity": "sha512-t+8bSU8qPq7NnWHWAvikjcZf+biErLZzD15RroYft1IKQwYbkRyiwppT7kNqwdtYLS59YPxc4sTSvwbLSMaodw==",
+ "dev": true
+ },
+ "stream-combiner": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz",
+ "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==",
+ "dev": true,
+ "requires": {
+ "duplexer": "~0.1.1",
+ "through": "~2.3.4"
+ }
+ },
+ "stream-combiner2": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz",
+ "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==",
+ "dev": true,
+ "requires": {
+ "duplexer2": "~0.1.0",
+ "readable-stream": "^2.0.2"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "stream-http": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz",
+ "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==",
+ "dev": true,
+ "requires": {
+ "builtin-status-codes": "^3.0.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.6.0",
+ "xtend": "^4.0.2"
+ }
+ },
+ "stream-splicer": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz",
+ "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.2"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "streamroller": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.4.1.tgz",
+ "integrity": "sha512-w0GGkMlWOiIBIYTmOWHTWKy9Y5hKxGKpQ5WpiHqwhvoSoMHXNTITrk6ZsR3fdgz3Bi/c+CXVHwmfPUQFkEPL+A==",
+ "dev": true,
+ "requires": {
+ "date-format": "^0.0.0",
+ "debug": "^0.7.2",
+ "mkdirp": "^0.5.1",
+ "readable-stream": "^1.1.7"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz",
+ "integrity": "sha512-EohAb3+DSHSGx8carOSKJe8G0ayV5/i609OD0J2orCkuyae7SyZSz2aoLmQF2s0Pj5gITDebwPH7GFBlqOUQ1Q==",
+ "dev": true
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.6"
+ }
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
+ "dev": true
+ }
+ }
+ },
+ "string-argv": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.0.2.tgz",
+ "integrity": "sha512-p6/Mqq0utTQWUeGMi/m0uBtlLZEwXSY3+mXzeRRqw7fz5ezUb28Wr0R99NlfbWaMmL/jCyT9be4jpn7Yz8IO8w==",
+ "dev": true
+ },
+ "string-length": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
+ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
+ "dev": true,
+ "requires": {
+ "char-regex": "^1.0.2",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ }
+ },
+ "string.prototype.padend": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz",
+ "integrity": "sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.19.1"
+ }
+ },
+ "string.prototype.trimend": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz",
+ "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.19.5"
+ }
+ },
+ "string.prototype.trimstart": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz",
+ "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.19.5"
+ }
+ },
+ "string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.2.0"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ }
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "requires": {
+ "ansi-regex": "^5.0.1"
+ }
+ },
+ "strip-bom": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+ "dev": true
+ },
+ "strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==",
+ "dev": true
+ },
+ "strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true
+ },
+ "strip-indent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
+ "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
+ "dev": true,
+ "requires": {
+ "min-indent": "^1.0.0"
+ }
+ },
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true
+ },
+ "style-loader": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.2.1.tgz",
+ "integrity": "sha512-1k9ZosJCRFaRbY6hH49JFlRB0fVSbmnyq1iTPjNxUmGVjBNEmwrrHPenhlp+Lgo51BojHSf6pl2FcqYaN3PfVg==",
+ "dev": true
+ },
+ "style-search": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz",
+ "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==",
+ "dev": true
+ },
+ "stylehacks": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz",
+ "integrity": "sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.16.6",
+ "postcss-selector-parser": "^6.0.4"
+ }
+ },
+ "stylelint": {
+ "version": "13.13.1",
+ "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.13.1.tgz",
+ "integrity": "sha512-Mv+BQr5XTUrKqAXmpqm6Ddli6Ief+AiPZkRsIrAoUKFuq/ElkUh9ZMYxXD0iQNZ5ADghZKLOWz1h7hTClB7zgQ==",
+ "dev": true,
+ "requires": {
+ "@stylelint/postcss-css-in-js": "^0.37.2",
+ "@stylelint/postcss-markdown": "^0.36.2",
+ "autoprefixer": "^9.8.6",
+ "balanced-match": "^2.0.0",
+ "chalk": "^4.1.1",
+ "cosmiconfig": "^7.0.0",
+ "debug": "^4.3.1",
+ "execall": "^2.0.0",
+ "fast-glob": "^3.2.5",
+ "fastest-levenshtein": "^1.0.12",
+ "file-entry-cache": "^6.0.1",
+ "get-stdin": "^8.0.0",
+ "global-modules": "^2.0.0",
+ "globby": "^11.0.3",
+ "globjoin": "^0.1.4",
+ "html-tags": "^3.1.0",
+ "ignore": "^5.1.8",
+ "import-lazy": "^4.0.0",
+ "imurmurhash": "^0.1.4",
+ "known-css-properties": "^0.21.0",
+ "lodash": "^4.17.21",
+ "log-symbols": "^4.1.0",
+ "mathml-tag-names": "^2.1.3",
+ "meow": "^9.0.0",
+ "micromatch": "^4.0.4",
+ "normalize-selector": "^0.2.0",
+ "postcss": "^7.0.35",
+ "postcss-html": "^0.36.0",
+ "postcss-less": "^3.1.4",
+ "postcss-media-query-parser": "^0.2.3",
+ "postcss-resolve-nested-selector": "^0.1.1",
+ "postcss-safe-parser": "^4.0.2",
+ "postcss-sass": "^0.4.4",
+ "postcss-scss": "^2.1.1",
+ "postcss-selector-parser": "^6.0.5",
+ "postcss-syntax": "^0.36.2",
+ "postcss-value-parser": "^4.1.0",
+ "resolve-from": "^5.0.0",
+ "slash": "^3.0.0",
+ "specificity": "^0.4.1",
+ "string-width": "^4.2.2",
+ "strip-ansi": "^6.0.0",
+ "style-search": "^0.1.0",
+ "sugarss": "^2.0.0",
+ "svg-tags": "^1.0.0",
+ "table": "^6.6.0",
+ "v8-compile-cache": "^2.3.0",
+ "write-file-atomic": "^3.0.3"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "balanced-match": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz",
+ "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "global-modules": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
+ "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
+ "dev": true,
+ "requires": {
+ "global-prefix": "^3.0.0"
+ }
+ },
+ "global-prefix": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
+ "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
+ "dev": true,
+ "requires": {
+ "ini": "^1.3.5",
+ "kind-of": "^6.0.2",
+ "which": "^1.3.1"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true
+ },
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "stylelint-config-sass-guidelines": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/stylelint-config-sass-guidelines/-/stylelint-config-sass-guidelines-7.1.0.tgz",
+ "integrity": "sha512-WvC9nRdlYknftPcUaJCajrPYKg6d2CKffrr7BPPkN/i/Mt8Qsm1hNQ9lqC1sKoCIKdH051SCEZi10qwFLgDbbg==",
+ "dev": true,
+ "requires": {
+ "stylelint-order": "^4.0.0",
+ "stylelint-scss": "^3.18.0"
+ }
+ },
+ "stylelint-declaration-use-variable": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/stylelint-declaration-use-variable/-/stylelint-declaration-use-variable-1.7.3.tgz",
+ "integrity": "sha512-6aH9aJcjT4QAzwgqcE+0td507lqBeSZGWbRf8nX7VJRNm8SQT//b2uoshQ4sNxKfJBH3S8RUWeVP37DgCjzZmQ==",
+ "dev": true
+ },
+ "stylelint-order": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-4.1.0.tgz",
+ "integrity": "sha512-sVTikaDvMqg2aJjh4r48jsdfmqLT+nqB1MOsaBnvM3OwLx4S+WXcsxsgk5w18h/OZoxZCxuyXMh61iBHcj9Qiw==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.15",
+ "postcss": "^7.0.31",
+ "postcss-sorting": "^5.0.1"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "stylelint-scss": {
+ "version": "3.21.0",
+ "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-3.21.0.tgz",
+ "integrity": "sha512-CMI2wSHL+XVlNExpauy/+DbUcB/oUZLARDtMIXkpV/5yd8nthzylYd1cdHeDMJVBXeYHldsnebUX6MoV5zPW4A==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.15",
+ "postcss-media-query-parser": "^0.2.3",
+ "postcss-resolve-nested-selector": "^0.1.1",
+ "postcss-selector-parser": "^6.0.2",
+ "postcss-value-parser": "^4.1.0"
+ }
+ },
+ "stylus": {
+ "version": "0.54.8",
+ "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.8.tgz",
+ "integrity": "sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg==",
+ "dev": true,
+ "requires": {
+ "css-parse": "~2.0.0",
+ "debug": "~3.1.0",
+ "glob": "^7.1.6",
+ "mkdirp": "~1.0.4",
+ "safer-buffer": "^2.1.2",
+ "sax": "~1.2.4",
+ "semver": "^6.3.0",
+ "source-map": "^0.7.3"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+ "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
+ "dev": true
+ }
+ }
+ },
+ "stylus-loader": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-6.1.0.tgz",
+ "integrity": "sha512-qKO34QCsOtSJrXxQQmXsPeaVHh6hMumBAFIoJTcsSr2VzrA6o/CW9HCGR8spCjzJhN8oKQHdj/Ytx0wwXyElkw==",
+ "dev": true,
+ "requires": {
+ "fast-glob": "^3.2.5",
+ "klona": "^2.0.4",
+ "normalize-path": "^3.0.0"
+ }
+ },
+ "subarg": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
+ "integrity": "sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.1.0"
+ }
+ },
+ "sugarss": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz",
+ "integrity": "sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2"
+ },
+ "dependencies": {
+ "picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "supports-hyperlinks": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz",
+ "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0",
+ "supports-color": "^7.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
+ },
+ "svg-tags": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
+ "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
+ "dev": true
+ },
+ "svgo": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz",
+ "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==",
+ "dev": true,
+ "requires": {
+ "@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"
+ }
+ },
+ "swagger-client": {
+ "version": "3.18.5",
+ "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.18.5.tgz",
+ "integrity": "sha512-c0txGDtfQTJnaIBaEKCwtRNcUaaAfj+RXI4QVV9p3WW+AUCQqp4naCjaDNNsOfMkE4ySyhnblbL+jGqAVC7snw==",
+ "requires": {
+ "@babel/runtime-corejs3": "^7.11.2",
+ "cookie": "~0.5.0",
+ "cross-fetch": "^3.1.5",
+ "deepmerge": "~4.2.2",
+ "fast-json-patch": "^3.0.0-1",
+ "form-data-encoder": "^1.4.3",
+ "formdata-node": "^4.0.0",
+ "is-plain-object": "^5.0.0",
+ "js-yaml": "^4.1.0",
+ "lodash": "^4.17.21",
+ "qs": "^6.10.2",
+ "traverse": "~0.6.6",
+ "url": "~0.11.0"
+ }
+ },
+ "swagger-ui": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/swagger-ui/-/swagger-ui-4.12.0.tgz",
+ "integrity": "sha512-ffNcDTQFWu5dEzJywQ4QEcgQZlBaHaeYCjifuWePds8anzqCZXVpeJSD7RCirUs+8D051YevRSu3ZjqNUNyvrQ==",
+ "requires": {
+ "@babel/runtime-corejs3": "^7.16.8",
+ "@braintree/sanitize-url": "=6.0.0",
+ "base64-js": "^1.5.1",
+ "classnames": "^2.3.1",
+ "css.escape": "1.5.1",
+ "deep-extend": "0.6.0",
+ "dompurify": "=2.3.3",
+ "ieee754": "^1.2.1",
+ "immutable": "^3.x.x",
+ "js-file-download": "^0.4.12",
+ "js-yaml": "=4.1.0",
+ "lodash": "^4.17.21",
+ "prop-types": "^15.8.1",
+ "randexp": "^0.5.3",
+ "randombytes": "^2.1.0",
+ "react": "=17.0.2",
+ "react-copy-to-clipboard": "5.0.4",
+ "react-debounce-input": "=3.2.4",
+ "react-dom": "=17.0.2",
+ "react-immutable-proptypes": "2.2.0",
+ "react-immutable-pure-component": "^2.2.0",
+ "react-inspector": "^5.1.1",
+ "react-redux": "^7.2.4",
+ "react-syntax-highlighter": "^15.4.5",
+ "redux": "^4.1.2",
+ "redux-immutable": "^4.0.0",
+ "remarkable": "^2.0.1",
+ "reselect": "^4.1.5",
+ "serialize-error": "^8.1.0",
+ "sha.js": "^2.4.11",
+ "swagger-client": "^3.18.5",
+ "url-parse": "^1.5.8",
+ "xml": "=1.0.1",
+ "xml-but-prettier": "^1.0.1",
+ "zenscroll": "^4.0.2"
+ }
+ },
+ "symbol-observable": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz",
+ "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==",
+ "dev": true
+ },
+ "symbol-tree": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+ "dev": true
+ },
+ "syntax-error": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz",
+ "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==",
+ "dev": true,
+ "requires": {
+ "acorn-node": "^1.2.0"
+ }
+ },
+ "table": {
+ "version": "6.8.0",
+ "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz",
+ "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==",
+ "dev": true,
+ "requires": {
+ "ajv": "^8.0.1",
+ "lodash.truncate": "^4.4.2",
+ "slice-ansi": "^4.0.0",
+ "string-width": "^4.2.3",
+ "strip-ansi": "^6.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+ "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
+ }
+ }
+ }
+ },
+ "tapable": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+ "dev": true
+ },
+ "tar": {
+ "version": "6.1.11",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
+ "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
+ "dev": true,
+ "requires": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^3.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ }
+ },
+ "terminal-link": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
+ "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^4.2.1",
+ "supports-hyperlinks": "^2.0.0"
+ }
+ },
+ "terser": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz",
+ "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==",
+ "dev": true,
+ "requires": {
+ "commander": "^2.20.0",
+ "source-map": "~0.7.2",
+ "source-map-support": "~0.5.19"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+ "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
+ "dev": true
+ }
+ }
+ },
+ "terser-webpack-plugin": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz",
+ "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==",
+ "dev": true,
+ "requires": {
+ "jest-worker": "^27.0.2",
+ "p-limit": "^3.1.0",
+ "schema-utils": "^3.0.0",
+ "serialize-javascript": "^6.0.0",
+ "source-map": "^0.6.1",
+ "terser": "^5.7.0"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "requires": {
+ "yocto-queue": "^0.1.0"
+ }
+ },
+ "schema-utils": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+ "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "requires": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ }
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+ "dev": true
+ },
+ "thenify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "dev": true,
+ "requires": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+ "dev": true,
+ "requires": {
+ "thenify": ">= 3.1.0 < 4"
+ }
+ },
+ "throat": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz",
+ "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==",
+ "dev": true
+ },
+ "throttleit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
+ "integrity": "sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==",
+ "dev": true
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "dev": true
+ },
+ "through2": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "thunky": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
+ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
+ "dev": true
+ },
+ "time-stamp": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz",
+ "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==",
+ "dev": true
+ },
+ "timers-browserify": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz",
+ "integrity": "sha512-PIxwAupJZiYU4JmVZYwXp9FKsHMXb5h0ZEFyuXTAn8WLHOlcij+FEcbrvDsom1o5dr1YggEtFbECvGCW2sT53Q==",
+ "dev": true,
+ "requires": {
+ "process": "~0.11.0"
+ }
+ },
+ "tiny-inflate": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
+ "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==",
+ "dev": true
+ },
+ "title-case": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz",
+ "integrity": "sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==",
+ "dev": true,
+ "requires": {
+ "no-case": "^2.2.0",
+ "upper-case": "^1.0.3"
+ }
+ },
+ "tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "dev": true,
+ "requires": {
+ "os-tmpdir": "~1.0.2"
+ }
+ },
+ "tmpl": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
+ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
+ "dev": true
+ },
+ "to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog=="
+ },
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "dev": true,
+ "requires": {
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
+ "toggle-selection": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
+ "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
+ },
+ "toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "dev": true
+ },
+ "tough-cookie": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+ "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+ "dev": true,
+ "requires": {
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ }
+ }
+ },
+ "tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ },
+ "tracelib": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tracelib/-/tracelib-1.0.1.tgz",
+ "integrity": "sha512-T2Vkpa/7Vdm3sV8nXRn8vZ0tnq6wlnO4Zx7Pux+JA1W6DMlg5EtbNcPZu/L7XRTPc9S0eAKhEFR4p/u0GcsDpQ==",
+ "dev": true
+ },
+ "transifex-i18ntool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/transifex-i18ntool/-/transifex-i18ntool-1.1.0.tgz",
+ "integrity": "sha512-W1FIGosZJ3cxbYk238QgsJvKPq12dPDIMn3rg37ZHNtoNAGrUAV6wKp+YSFwnMcqk3igZcAEPlLW1jFjBFC95Q==",
+ "dev": true,
+ "requires": {
+ "colors": "^1.0.3",
+ "minimist": "^1.2.0",
+ "prompts": "^2.0.4",
+ "request": "^2.88.0",
+ "request-promise-native": "^1.0.7",
+ "xliff": "^4.2.0"
+ }
+ },
+ "traverse": {
+ "version": "0.6.6",
+ "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz",
+ "integrity": "sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw=="
+ },
+ "tree-kill": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
+ "dev": true
+ },
+ "trim-newlines": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
+ "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==",
+ "dev": true
+ },
+ "trough": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz",
+ "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==",
+ "dev": true
+ },
+ "ts-jest": {
+ "version": "26.5.6",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.6.tgz",
+ "integrity": "sha512-rua+rCP8DxpA8b4DQD/6X2HQS8Zy/xzViVYfEs2OQu68tkCuKLV0Md8pmX55+W24uRIyAsf/BajRfxOs+R2MKA==",
+ "dev": true,
+ "requires": {
+ "bs-logger": "0.x",
+ "buffer-from": "1.x",
+ "fast-json-stable-stringify": "2.x",
+ "jest-util": "^26.1.0",
+ "json5": "2.x",
+ "lodash": "4.x",
+ "make-error": "1.x",
+ "mkdirp": "1.x",
+ "semver": "7.x",
+ "yargs-parser": "20.x"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "dev": true
+ }
+ }
+ },
+ "ts-loader": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.1.tgz",
+ "integrity": "sha512-Dd9FekWuABGgjE1g0TlQJ+4dFUfYGbYcs52/HQObE0ZmUNjQlmLAS7xXsSzy23AMaMwipsx5sNHvoEpT2CZq1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.3.0",
+ "enhanced-resolve": "^4.0.0",
+ "loader-utils": "^1.0.2",
+ "micromatch": "^4.0.0",
+ "semver": "^6.0.0"
+ },
+ "dependencies": {
+ "enhanced-resolve": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz",
+ "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "memory-fs": "^0.5.0",
+ "tapable": "^1.0.0"
+ }
+ },
+ "json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ },
+ "loader-utils": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+ "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+ "dev": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^1.0.1"
+ }
+ },
+ "memory-fs": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
+ "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==",
+ "dev": true,
+ "requires": {
+ "errno": "^0.1.3",
+ "readable-stream": "^2.0.1"
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "tapable": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
+ "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
+ "dev": true
+ }
+ }
+ },
+ "ts-morph": {
+ "version": "12.2.0",
+ "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-12.2.0.tgz",
+ "integrity": "sha512-WHXLtFDcIRwoqaiu0elAoZ/AmI+SwwDafnPKjgJmdwJ2gRVO0jMKBt88rV2liT/c6MTsXyuWbGFiHe9MRddWJw==",
+ "dev": true,
+ "requires": {
+ "@ts-morph/common": "~0.11.1",
+ "code-block-writer": "^10.1.1"
+ }
+ },
+ "ts-node": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz",
+ "integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==",
+ "dev": true,
+ "requires": {
+ "arg": "^4.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "source-map-support": "^0.5.17",
+ "yn": "3.1.1"
+ },
+ "dependencies": {
+ "diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true
+ }
+ }
+ },
+ "tslib": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
+ },
+ "tslint": {
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz",
+ "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "builtin-modules": "^1.1.1",
+ "chalk": "^2.3.0",
+ "commander": "^2.12.1",
+ "diff": "^4.0.1",
+ "glob": "^7.1.1",
+ "js-yaml": "^3.13.1",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.3",
+ "resolve": "^1.3.2",
+ "semver": "^5.3.0",
+ "tslib": "^1.13.0",
+ "tsutils": "^2.29.0"
+ },
+ "dependencies": {
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.6"
+ }
+ },
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ }
+ }
+ },
+ "tsutils": {
+ "version": "2.29.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
+ "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.8.1"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ }
+ }
+ },
+ "tty-browserify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz",
+ "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==",
+ "dev": true
+ },
+ "tunnel": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
+ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
+ "dev": true
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
+ "dev": true
+ },
+ "type": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
+ "dev": true
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2"
+ }
+ },
+ "type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true
+ },
+ "type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="
+ },
+ "type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "dev": true,
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ }
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
+ "dev": true
+ },
+ "typedarray-to-buffer": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+ "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+ "dev": true,
+ "requires": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
+ "typescript": {
+ "version": "4.3.5",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
+ "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
+ "dev": true
+ },
+ "uglify-js": {
+ "version": "3.17.0",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.0.tgz",
+ "integrity": "sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg==",
+ "dev": true,
+ "optional": true
+ },
+ "umd": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz",
+ "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==",
+ "dev": true
+ },
+ "unbox-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+ "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.0.3",
+ "which-boxed-primitive": "^1.0.2"
+ }
+ },
+ "unc-path-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+ "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==",
+ "dev": true
+ },
+ "undeclared-identifiers": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz",
+ "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==",
+ "dev": true,
+ "requires": {
+ "acorn-node": "^1.3.0",
+ "dash-ast": "^1.0.0",
+ "get-assigned-identifiers": "^1.2.0",
+ "simple-concat": "^1.0.0",
+ "xtend": "^4.0.1"
+ },
+ "dependencies": {
+ "dash-ast": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz",
+ "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==",
+ "dev": true
+ }
+ }
+ },
+ "underscore": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz",
+ "integrity": "sha512-cp0oQQyZhUM1kpJDLdGO1jPZHgS/MpzoWYfe9+CM2h/QGDZlqwT2T3YGukuBdaNJ/CAPoeyAZRRHz8JFo176vA==",
+ "dev": true
+ },
+ "unicode-canonical-property-names-ecmascript": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
+ "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==",
+ "dev": true
+ },
+ "unicode-match-property-ecmascript": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
+ "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
+ "dev": true,
+ "requires": {
+ "unicode-canonical-property-names-ecmascript": "^2.0.0",
+ "unicode-property-aliases-ecmascript": "^2.0.0"
+ }
+ },
+ "unicode-match-property-value-ecmascript": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz",
+ "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==",
+ "dev": true
+ },
+ "unicode-properties": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz",
+ "integrity": "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.3.0",
+ "unicode-trie": "^2.0.0"
+ }
+ },
+ "unicode-property-aliases-ecmascript": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz",
+ "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==",
+ "dev": true
+ },
+ "unicode-trie": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz",
+ "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==",
+ "dev": true,
+ "requires": {
+ "pako": "^0.2.5",
+ "tiny-inflate": "^1.0.0"
+ },
+ "dependencies": {
+ "pako": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
+ "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==",
+ "dev": true
+ }
+ }
+ },
+ "unified": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz",
+ "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==",
+ "dev": true,
+ "requires": {
+ "bail": "^1.0.0",
+ "extend": "^3.0.0",
+ "is-buffer": "^2.0.0",
+ "is-plain-obj": "^2.0.0",
+ "trough": "^1.0.0",
+ "vfile": "^4.0.0"
+ },
+ "dependencies": {
+ "is-buffer": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+ "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
+ "dev": true
+ }
+ }
+ },
+ "union-value": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+ "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "get-value": "^2.0.6",
+ "is-extendable": "^0.1.1",
+ "set-value": "^2.0.1"
+ }
+ },
+ "uniq": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+ "integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==",
+ "dev": true
+ },
+ "unique-filename": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+ "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
+ "dev": true,
+ "requires": {
+ "unique-slug": "^2.0.0"
+ }
+ },
+ "unique-slug": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
+ "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
+ "dev": true,
+ "requires": {
+ "imurmurhash": "^0.1.4"
+ }
+ },
+ "unist-util-find-all-after": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-3.0.2.tgz",
+ "integrity": "sha512-xaTC/AGZ0rIM2gM28YVRAFPIZpzbpDtU3dRmp7EXlNVA8ziQc4hY3H7BHXM1J49nEmiqc3svnqMReW+PGqbZKQ==",
+ "dev": true,
+ "requires": {
+ "unist-util-is": "^4.0.0"
+ }
+ },
+ "unist-util-is": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz",
+ "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==",
+ "dev": true
+ },
+ "unist-util-stringify-position": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
+ "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.2"
+ }
+ },
+ "universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+ "dev": true
+ },
+ "unix-crypt-td-js": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz",
+ "integrity": "sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==",
+ "dev": true
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "dev": true
+ },
+ "unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==",
+ "dev": true,
+ "requires": {
+ "has-value": "^0.3.1",
+ "isobject": "^3.0.0"
+ },
+ "dependencies": {
+ "has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.3",
+ "has-values": "^0.1.4",
+ "isobject": "^2.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==",
+ "dev": true
+ }
+ }
+ },
+ "untildify": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
+ "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
+ "dev": true
+ },
+ "upath": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
+ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
+ "dev": true
+ },
+ "update-browserslist-db": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.7.tgz",
+ "integrity": "sha512-iN/XYesmZ2RmmWAiI4Z5rq0YqSiv0brj9Ce9CfhNE4xIW2h+MFxcgkxIzZ+ShkFPUkjU3gQ+3oypadD3RAMtrg==",
+ "dev": true,
+ "requires": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ }
+ },
+ "upper-case": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
+ "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==",
+ "dev": true
+ },
+ "uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ }
+ }
+ },
+ "urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==",
+ "dev": true
+ },
+ "url": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+ "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==",
+ "requires": {
+ "punycode": "1.3.2",
+ "querystring": "0.2.0"
+ }
+ },
+ "url-parse": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
+ "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
+ "requires": {
+ "querystringify": "^2.1.1",
+ "requires-port": "^1.0.0"
+ }
+ },
+ "use": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+ "dev": true
+ },
+ "util": {
+ "version": "0.10.4",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
+ "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
+ "dev": true
+ }
+ }
+ },
+ "util-arity": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/util-arity/-/util-arity-1.1.0.tgz",
+ "integrity": "sha512-kkyIsXKwemfSy8ZEoaIz06ApApnWsk5hQO0vLjZS6UkBiGiW++Jsyb8vSBoc0WKlffGoGs5yYy/j5pp8zckrFA==",
+ "dev": true
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "dev": true
+ },
+ "uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true
+ },
+ "v8-compile-cache": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
+ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
+ "dev": true
+ },
+ "v8-to-istanbul": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz",
+ "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^1.6.0",
+ "source-map": "^0.7.3"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+ "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
+ "dev": true
+ }
+ }
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "requires": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "validate-npm-package-name": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz",
+ "integrity": "sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==",
+ "dev": true,
+ "requires": {
+ "builtins": "^1.0.3"
+ }
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "dev": true
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ },
+ "dependencies": {
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
+ "dev": true
+ }
+ }
+ },
+ "vfile": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz",
+ "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "is-buffer": "^2.0.0",
+ "unist-util-stringify-position": "^2.0.0",
+ "vfile-message": "^2.0.0"
+ },
+ "dependencies": {
+ "is-buffer": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+ "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
+ "dev": true
+ }
+ }
+ },
+ "vfile-message": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz",
+ "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "unist-util-stringify-position": "^2.0.0"
+ }
+ },
+ "vm-browserify": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
+ "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
+ "dev": true
+ },
+ "w3c-hr-time": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
+ "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
+ "dev": true,
+ "requires": {
+ "browser-process-hrtime": "^1.0.0"
+ }
+ },
+ "w3c-xmlserializer": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz",
+ "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==",
+ "dev": true,
+ "requires": {
+ "domexception": "^1.0.1",
+ "webidl-conversions": "^4.0.2",
+ "xml-name-validator": "^3.0.0"
+ },
+ "dependencies": {
+ "webidl-conversions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+ "dev": true
+ }
+ }
+ },
+ "wait-on": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-5.3.0.tgz",
+ "integrity": "sha512-DwrHrnTK+/0QFaB9a8Ol5Lna3k7WvUR4jzSKmz0YaPBpuN2sACyiPVKVfj6ejnjcajAcvn3wlbTyMIn9AZouOg==",
+ "dev": true,
+ "requires": {
+ "axios": "^0.21.1",
+ "joi": "^17.3.0",
+ "lodash": "^4.17.21",
+ "minimist": "^1.2.5",
+ "rxjs": "^6.6.3"
+ }
+ },
+ "walker": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
+ "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
+ "dev": true,
+ "requires": {
+ "makeerror": "1.0.12"
+ }
+ },
+ "watchify": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/watchify/-/watchify-4.0.0.tgz",
+ "integrity": "sha512-2Z04dxwoOeNxa11qzWumBTgSAohTC0+ScuY7XMenPnH+W2lhTcpEOJP4g2EIG/SWeLadPk47x++Yh+8BqPM/lA==",
+ "dev": true,
+ "requires": {
+ "anymatch": "^3.1.0",
+ "browserify": "^17.0.0",
+ "chokidar": "^3.4.0",
+ "defined": "^1.0.0",
+ "outpipe": "^1.1.0",
+ "through2": "^4.0.2",
+ "xtend": "^4.0.2"
+ },
+ "dependencies": {
+ "browser-resolve": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz",
+ "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==",
+ "dev": true,
+ "requires": {
+ "resolve": "^1.17.0"
+ }
+ },
+ "browserify": {
+ "version": "17.0.0",
+ "resolved": "https://registry.npmjs.org/browserify/-/browserify-17.0.0.tgz",
+ "integrity": "sha512-SaHqzhku9v/j6XsQMRxPyBrSP3gnwmE27gLJYZgMT2GeK3J0+0toN+MnuNYDfHwVGQfLiMZ7KSNSIXHemy905w==",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "assert": "^1.4.0",
+ "browser-pack": "^6.0.1",
+ "browser-resolve": "^2.0.0",
+ "browserify-zlib": "~0.2.0",
+ "buffer": "~5.2.1",
+ "cached-path-relative": "^1.0.0",
+ "concat-stream": "^1.6.0",
+ "console-browserify": "^1.1.0",
+ "constants-browserify": "~1.0.0",
+ "crypto-browserify": "^3.0.0",
+ "defined": "^1.0.0",
+ "deps-sort": "^2.0.1",
+ "domain-browser": "^1.2.0",
+ "duplexer2": "~0.1.2",
+ "events": "^3.0.0",
+ "glob": "^7.1.0",
+ "has": "^1.0.0",
+ "htmlescape": "^1.1.0",
+ "https-browserify": "^1.0.0",
+ "inherits": "~2.0.1",
+ "insert-module-globals": "^7.2.1",
+ "labeled-stream-splicer": "^2.0.0",
+ "mkdirp-classic": "^0.5.2",
+ "module-deps": "^6.2.3",
+ "os-browserify": "~0.3.0",
+ "parents": "^1.0.1",
+ "path-browserify": "^1.0.0",
+ "process": "~0.11.0",
+ "punycode": "^1.3.2",
+ "querystring-es3": "~0.2.0",
+ "read-only-stream": "^2.0.0",
+ "readable-stream": "^2.0.2",
+ "resolve": "^1.1.4",
+ "shasum-object": "^1.0.0",
+ "shell-quote": "^1.6.1",
+ "stream-browserify": "^3.0.0",
+ "stream-http": "^3.0.0",
+ "string_decoder": "^1.1.1",
+ "subarg": "^1.0.0",
+ "syntax-error": "^1.1.1",
+ "through2": "^2.0.0",
+ "timers-browserify": "^1.0.1",
+ "tty-browserify": "0.0.1",
+ "url": "~0.11.0",
+ "util": "~0.12.0",
+ "vm-browserify": "^1.0.0",
+ "xtend": "^4.0.0"
+ },
+ "dependencies": {
+ "through2": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ }
+ }
+ }
+ },
+ "buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
+ "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "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"
+ },
+ "dependencies": {
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "stream-browserify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz",
+ "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==",
+ "dev": true,
+ "requires": {
+ "inherits": "~2.0.4",
+ "readable-stream": "^3.5.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
+ }
+ },
+ "through2": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz",
+ "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "3"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
+ }
+ },
+ "util": {
+ "version": "0.12.4",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz",
+ "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "is-arguments": "^1.0.4",
+ "is-generator-function": "^1.0.7",
+ "is-typed-array": "^1.1.3",
+ "safe-buffer": "^5.1.2",
+ "which-typed-array": "^1.1.2"
+ }
+ }
+ }
+ },
+ "watchpack": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
+ "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+ "dev": true,
+ "requires": {
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
+ }
+ },
+ "wbuf": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
+ "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
+ "dev": true,
+ "requires": {
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "wcwidth": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+ "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
+ "dev": true,
+ "requires": {
+ "defaults": "^1.0.3"
+ }
+ },
+ "web-streams-polyfill": {
+ "version": "4.0.0-beta.3",
+ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz",
+ "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug=="
+ },
+ "webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ },
+ "webpack": {
+ "version": "5.50.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.50.0.tgz",
+ "integrity": "sha512-hqxI7t/KVygs0WRv/kTgUW8Kl3YC81uyWQSo/7WUs5LsuRw0htH/fCwbVBGCuiX/t4s7qzjXFcf41O8Reiypag==",
+ "dev": true,
+ "requires": {
+ "@types/eslint-scope": "^3.7.0",
+ "@types/estree": "^0.0.50",
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/wasm-edit": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1",
+ "acorn": "^8.4.1",
+ "acorn-import-assertions": "^1.7.6",
+ "browserslist": "^4.14.5",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^5.8.0",
+ "es-module-lexer": "^0.7.1",
+ "eslint-scope": "5.1.1",
+ "events": "^3.2.0",
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.2.4",
+ "json-parse-better-errors": "^1.0.2",
+ "loader-runner": "^4.2.0",
+ "mime-types": "^2.1.27",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^3.1.0",
+ "tapable": "^2.1.1",
+ "terser-webpack-plugin": "^5.1.3",
+ "watchpack": "^2.2.0",
+ "webpack-sources": "^3.2.0"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "schema-utils": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+ "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ }
+ },
+ "webpack-sources": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
+ "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+ "dev": true
+ }
+ }
+ },
+ "webpack-dev-middleware": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.0.0.tgz",
+ "integrity": "sha512-9zng2Z60pm6A98YoRcA0wSxw1EYn7B7y5owX/Tckyt9KGyULTkLtiavjaXlWqOMkM0YtqGgL3PvMOFgyFLq8vw==",
+ "dev": true,
+ "requires": {
+ "colorette": "^1.2.2",
+ "mem": "^8.1.1",
+ "memfs": "^3.2.2",
+ "mime-types": "^2.1.31",
+ "range-parser": "^1.2.1",
+ "schema-utils": "^3.0.0"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "schema-utils": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+ "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ }
+ }
+ }
+ },
+ "webpack-dev-server": {
+ "version": "3.11.2",
+ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz",
+ "integrity": "sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ==",
+ "dev": true,
+ "requires": {
+ "ansi-html": "0.0.7",
+ "bonjour": "^3.5.0",
+ "chokidar": "^2.1.8",
+ "compression": "^1.7.4",
+ "connect-history-api-fallback": "^1.6.0",
+ "debug": "^4.1.1",
+ "del": "^4.1.1",
+ "express": "^4.17.1",
+ "html-entities": "^1.3.1",
+ "http-proxy-middleware": "0.19.1",
+ "import-local": "^2.0.0",
+ "internal-ip": "^4.3.0",
+ "ip": "^1.1.5",
+ "is-absolute-url": "^3.0.3",
+ "killable": "^1.0.1",
+ "loglevel": "^1.6.8",
+ "opn": "^5.5.0",
+ "p-retry": "^3.0.1",
+ "portfinder": "^1.0.26",
+ "schema-utils": "^1.0.0",
+ "selfsigned": "^1.10.8",
+ "semver": "^6.3.0",
+ "serve-index": "^1.9.1",
+ "sockjs": "^0.3.21",
+ "sockjs-client": "^1.5.0",
+ "spdy": "^4.0.2",
+ "strip-ansi": "^3.0.1",
+ "supports-color": "^6.1.0",
+ "url": "^0.11.0",
+ "webpack-dev-middleware": "^3.7.2",
+ "webpack-log": "^2.0.0",
+ "ws": "^6.2.1",
+ "yargs": "^13.3.2"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
+ "dev": true
+ },
+ "anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "dev": true,
+ "requires": {
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
+ },
+ "dependencies": {
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==",
+ "dev": true,
+ "requires": {
+ "remove-trailing-separator": "^1.0.1"
+ }
+ }
+ }
+ },
+ "binary-extensions": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
+ "dev": true
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "chokidar": {
+ "version": "2.1.8",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
+ "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
+ "dev": true,
+ "requires": {
+ "anymatch": "^2.0.0",
+ "async-each": "^1.0.1",
+ "braces": "^2.3.2",
+ "fsevents": "^1.2.7",
+ "glob-parent": "^3.1.0",
+ "inherits": "^2.0.3",
+ "is-binary-path": "^1.0.0",
+ "is-glob": "^4.0.0",
+ "normalize-path": "^3.0.0",
+ "path-is-absolute": "^1.0.0",
+ "readdirp": "^2.2.1",
+ "upath": "^1.1.1"
+ }
+ },
+ "cliui": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+ "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+ "dev": true,
+ "requires": {
+ "string-width": "^3.1.0",
+ "strip-ansi": "^5.2.0",
+ "wrap-ansi": "^5.1.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+ "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "fsevents": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
+ "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
+ "dev": true,
+ "optional": true
+ },
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ },
+ "is-binary-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^1.0.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "mime": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
+ "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.6"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "readdirp": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.11",
+ "micromatch": "^3.1.10",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "schema-utils": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.1.0",
+ "ajv-errors": "^1.0.0",
+ "ajv-keywords": "^3.1.0"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+ "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ }
+ },
+ "webpack-dev-middleware": {
+ "version": "3.7.3",
+ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz",
+ "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==",
+ "dev": true,
+ "requires": {
+ "memory-fs": "^0.4.1",
+ "mime": "^2.4.4",
+ "mkdirp": "^0.5.1",
+ "range-parser": "^1.2.1",
+ "webpack-log": "^2.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+ "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "string-width": "^3.0.0",
+ "strip-ansi": "^5.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+ "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "y18n": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "13.3.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+ "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^5.0.0",
+ "find-up": "^3.0.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^3.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^13.1.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "13.1.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+ "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ }
+ }
+ },
+ "webpack-log": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",
+ "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==",
+ "dev": true,
+ "requires": {
+ "ansi-colors": "^3.0.0",
+ "uuid": "^3.3.2"
+ },
+ "dependencies": {
+ "ansi-colors": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
+ "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==",
+ "dev": true
+ },
+ "uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+ "dev": true
+ }
+ }
+ },
+ "webpack-merge": {
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz",
+ "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==",
+ "dev": true,
+ "requires": {
+ "clone-deep": "^4.0.1",
+ "wildcard": "^2.0.0"
+ }
+ },
+ "webpack-sources": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
+ "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
+ "dev": true,
+ "requires": {
+ "source-list-map": "^2.0.0",
+ "source-map": "~0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "webpack-subresource-integrity": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.5.2.tgz",
+ "integrity": "sha512-GBWYBoyalbo5YClwWop9qe6Zclp8CIXYGIz12OPclJhIrSplDxs1Ls1JDMH8xBPPrg1T6ISaTW9Y6zOrwEiAzw==",
+ "dev": true,
+ "requires": {
+ "webpack-sources": "^1.3.0"
+ }
+ },
+ "websocket-driver": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
+ "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
+ "dev": true,
+ "requires": {
+ "http-parser-js": ">=0.5.1",
+ "safe-buffer": ">=5.1.0",
+ "websocket-extensions": ">=0.1.1"
+ }
+ },
+ "websocket-extensions": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
+ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
+ "dev": true
+ },
+ "whatwg-encoding": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
+ "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
+ "dev": true,
+ "requires": {
+ "iconv-lite": "0.4.24"
+ }
+ },
+ "whatwg-fetch": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz",
+ "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==",
+ "dev": true
+ },
+ "whatwg-mimetype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
+ "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==",
+ "dev": true
+ },
+ "whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "requires": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "which-boxed-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+ "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+ "dev": true,
+ "requires": {
+ "is-bigint": "^1.0.1",
+ "is-boolean-object": "^1.1.0",
+ "is-number-object": "^1.0.4",
+ "is-string": "^1.0.5",
+ "is-symbol": "^1.0.3"
+ }
+ },
+ "which-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+ "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==",
+ "dev": true
+ },
+ "which-typed-array": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz",
+ "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==",
+ "dev": true,
+ "requires": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "es-abstract": "^1.20.0",
+ "for-each": "^0.3.3",
+ "has-tostringtag": "^1.0.0",
+ "is-typed-array": "^1.1.9"
+ }
+ },
+ "wide-align": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
+ "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.2 || 2 || 3 || 4"
+ }
+ },
+ "wildcard": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz",
+ "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
+ "dev": true
+ },
+ "windows-release": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-4.0.0.tgz",
+ "integrity": "sha512-OxmV4wzDKB1x7AZaZgXMVsdJ1qER1ed83ZrTYd5Bwq2HfJVg3DJS8nqlAG4sMoJ7mu8cuRmLEYyU13BKwctRAg==",
+ "dev": true,
+ "requires": {
+ "execa": "^4.0.2"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "execa": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
+ "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.0",
+ "get-stream": "^5.0.0",
+ "human-signals": "^1.1.1",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.0",
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2",
+ "strip-final-newline": "^2.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true
+ },
+ "npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.0.0"
+ }
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true
+ },
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
+ "dev": true
+ },
+ "workerpool": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
+ "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
+ "dev": true
+ },
+ "wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ }
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+ },
+ "write-file-atomic": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
+ "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
+ "dev": true,
+ "requires": {
+ "imurmurhash": "^0.1.4",
+ "is-typedarray": "^1.0.0",
+ "signal-exit": "^3.0.2",
+ "typedarray-to-buffer": "^3.1.5"
+ }
+ },
+ "ws": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
+ "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
+ "dev": true,
+ "requires": {
+ "async-limiter": "~1.0.0"
+ }
+ },
+ "xliff": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/xliff/-/xliff-4.4.0.tgz",
+ "integrity": "sha512-SVzjB3hTHJ/CbsIJtbQg2BAxhvVJqbZ3OluMS7u6JnCbf0/twuj2KASghYHiKHz2sJqZo42dGjydp0URKmWWoA==",
+ "dev": true,
+ "requires": {
+ "xml-js": "1.6.11"
+ }
+ },
+ "xml": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
+ "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw=="
+ },
+ "xml-but-prettier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/xml-but-prettier/-/xml-but-prettier-1.0.1.tgz",
+ "integrity": "sha512-C2CJaadHrZTqESlH03WOyw0oZTtoy2uEg6dSDF6YRg+9GnYNub53RRemLpnvtbHDFelxMx4LajiFsYeR6XJHgQ==",
+ "requires": {
+ "repeat-string": "^1.5.2"
+ }
+ },
+ "xml-js": {
+ "version": "1.6.11",
+ "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz",
+ "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==",
+ "dev": true,
+ "requires": {
+ "sax": "^1.2.4"
+ }
+ },
+ "xml-name-validator": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
+ "dev": true
+ },
+ "xmlchars": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+ "dev": true
+ },
+ "xmldoc": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.2.0.tgz",
+ "integrity": "sha512-2eN8QhjBsMW2uVj7JHLHkMytpvGHLHxKXBy4J3fAT/HujsEtM6yU84iGjpESYGHg6XwK0Vu4l+KgqQ2dv2cCqg==",
+ "dev": true,
+ "requires": {
+ "sax": "^1.2.4"
+ }
+ },
+ "xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
+ },
+ "y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "17.5.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
+ "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
+ "requires": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.0.0"
+ }
+ },
+ "yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="
+ },
+ "yargs-unparser": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
+ "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^6.0.0",
+ "decamelize": "^4.0.0",
+ "flat": "^5.0.2",
+ "is-plain-obj": "^2.1.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true
+ },
+ "decamelize": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
+ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
+ "dev": true
+ }
+ }
+ },
+ "yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+ "dev": true,
+ "requires": {
+ "buffer-crc32": "~0.2.3",
+ "fd-slicer": "~1.1.0"
+ }
+ },
+ "yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true
+ },
+ "yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true
+ },
+ "zenscroll": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/zenscroll/-/zenscroll-4.0.2.tgz",
+ "integrity": "sha512-jEA1znR7b4C/NnaycInCU6h/d15ZzCd1jmsruqOKnZP6WXQSMH3W2GL+OXbkruslU4h+Tzuos0HdswzRUk/Vgg=="
+ },
+ "zone.js": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz",
+ "integrity": "sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg==",
+ "dev": true
+ },
+ "zwitch": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz",
+ "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==",
+ "dev": true
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/package.json b/src/pybind/mgr/dashboard/frontend/package.json
new file mode 100644
index 000000000..722baa8dc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/package.json
@@ -0,0 +1,157 @@
+{
+ "name": "ceph-dashboard",
+ "version": "0.0.0",
+ "license": "MIT",
+ "config": {
+ "locale": "en-US"
+ },
+ "scripts": {
+ "ng": "ng",
+ "start": "npm run env_build && ng serve --host 0.0.0.0 --ssl",
+ "build": "npm run env_build && ng build --configuration=$npm_package_config_locale",
+ "build:localize": "node cd --env --pre && ng build --localize",
+ "postbuild:localize": "node cd --res",
+ "env_build": "node cd --env",
+ "i18n": "npm run i18n:extract && npm run i18n:push && npm run i18n:pull && npm run i18n:merge",
+ "i18n:extract": "ng extract-i18n --output-path src/locale --progress=false",
+ "i18n:push": "npx i18ntool push -c i18n.config.json",
+ "i18n:pull": "npx i18ntool pull -c i18n.config.json",
+ "i18n:merge": "npx i18ntool merge -c i18n.config.json",
+ "i18n:token": "npx i18ntool config token",
+ "test": "jest --watch",
+ "test:ci": "jest --clearCache && JEST_SILENT_REPORTER_DOTS=true jest --coverage --reporters jest-silent-reporter",
+ "pree2e": "rm -f cypress/reports/results-*.xml || true",
+ "e2e": "start-test 4200 'cypress open'",
+ "pree2e:ci": "npm run pree2e",
+ "e2e:ci": "start-test 4200 'cypress run -b chrome --headless'",
+ "lint:tslint": "ng lint",
+ "lint:gherkin": "gherkin-lint -c .gherkin-lintrc cypress/integration",
+ "lint:prettier": "prettier --list-different \"{src,cypress}/**/*.{ts,scss}\"",
+ "lint:html": "htmllint src/app/**/*.html && html-linter --config html-linter.config.json",
+ "prelint:tsc": "npm run postinstall",
+ "lint:tsc": "tsc -p tsconfig.app.json --noEmit && tsc -p tsconfig.spec.json --noEmit && tsc -p cypress/tsconfig.json --noEmit",
+ "lint:scss": "stylelint '**/*.scss'",
+ "lint": "run-p -csl --aggregate-output lint:*",
+ "fix:prettier": "prettier --write \"{src,cypress}/**/*.{ts,scss}\"",
+ "fix:tslint": "npm run lint:tslint -- --fix",
+ "fix:scss": "stylelint '**/*.scss' --fix",
+ "fixmod": "pretty-quick --pattern \"{src,cypress}/**/*.{ts,scss}\" --branch HEAD",
+ "fix": "run-p -csl --aggregate-output fix:*",
+ "compodoc": "compodoc",
+ "doc-build": "compodoc -p tsconfig.app.json",
+ "doc-serve": "compodoc --port 8444 -s tsconfig.app.json",
+ "postinstall": "ngcc --properties es2015 browser module main --async false --first-only --tsconfig 'tsconfig.app.json'"
+ },
+ "private": true,
+ "jest": {
+ "moduleNameMapper": {
+ "\\.scss$": "identity-obj-proxy",
+ "~/(.*)$": "<rootDir>/src/$1"
+ },
+ "preset": "jest-preset-angular",
+ "setupFilesAfterEnv": [
+ "<rootDir>/src/setupJest.ts"
+ ],
+ "transformIgnorePatterns": [
+ "node_modules/(?!@ngrx|@progress|simplebar|lodash-es|react-syntax-highlighter|swagger-client)"
+ ],
+ "transform": {
+ "^.+\\.(ts|html)$": "ts-jest",
+ "^.+\\.(js)$": "babel-jest"
+ },
+ "setupFiles": [
+ "jest-canvas-mock"
+ ],
+ "coverageReporters": [
+ "cobertura",
+ "html"
+ ],
+ "modulePathIgnorePatterns": [
+ "<rootDir>/coverage/"
+ ],
+ "testMatch": [
+ "**/*.spec.ts"
+ ],
+ "testURL": "http://localhost/"
+ },
+ "dependencies": {
+ "@angular/animations": "12.2.13",
+ "@angular/common": "12.2.13",
+ "@angular/compiler": "12.2.13",
+ "@angular/core": "12.2.13",
+ "@angular/forms": "12.2.13",
+ "@angular/localize": "12.2.13",
+ "@angular/platform-browser": "12.2.13",
+ "@angular/platform-browser-dynamic": "12.2.13",
+ "@angular/router": "12.2.13",
+ "@circlon/angular-tree-component": "10.0.0",
+ "@ng-bootstrap/ng-bootstrap": "10.0.0",
+ "@swimlane/ngx-datatable": "18.0.0",
+ "@types/file-saver": "2.0.1",
+ "async-mutex": "0.2.4",
+ "bootstrap": "4.6.1",
+ "chart.js": "2.9.4",
+ "detect-browser": "5.2.0",
+ "file-saver": "2.0.2",
+ "fork-awesome": "1.1.7",
+ "lodash": "4.17.21",
+ "moment": "2.29.3",
+ "ng-block-ui": "3.0.2",
+ "ng-click-outside": "7.0.0",
+ "ng2-charts": "2.4.2",
+ "ngx-pipe-function": "1.0.0",
+ "ngx-toastr": "14.1.4",
+ "rxjs": "6.6.3",
+ "simplebar-angular": "2.3.6",
+ "swagger-ui": "4.12.0",
+ "tslib": "2.3.1"
+ },
+ "devDependencies": {
+ "@angular-devkit/build-angular": "12.2.13",
+ "@angular/cli": "12.2.13",
+ "@angular/compiler-cli": "12.2.13",
+ "@angular/language-service": "12.2.13",
+ "@applitools/eyes-cypress": "3.22.5",
+ "@compodoc/compodoc": "1.1.15",
+ "@cypress/browserify-preprocessor": "3.0.2",
+ "@grafana/e2e": "8.4.5",
+ "@types/brace-expansion": "1.1.0",
+ "@types/cypress-cucumber-preprocessor": "4.0.1",
+ "@types/jest": "26.0.14",
+ "@types/lodash": "4.14.161",
+ "@types/node": "12.12.62",
+ "@types/simplebar": "5.1.1",
+ "@types/swagger-ui": "3.52.0",
+ "codelyzer": "6.0.2",
+ "cypress": "9.7.0",
+ "cypress-cucumber-preprocessor": "4.3.1",
+ "cypress-iframe": "1.0.1",
+ "cypress-multi-reporters": "1.5.0",
+ "gherkin-lint": "4.2.2",
+ "html-linter": "1.1.1",
+ "htmllint-cli": "0.0.7",
+ "identity-obj-proxy": "3.0.0",
+ "isomorphic-form-data": "2.0.0",
+ "jest": "26.5.2",
+ "jest-canvas-mock": "2.3.0",
+ "jest-preset-angular": "8.3.1",
+ "jest-silent-reporter": "0.2.1",
+ "mocha-junit-reporter": "2.0.2",
+ "ng-bullet": "1.0.3",
+ "ng-mocks": "10.2.0",
+ "npm-run-all": "4.1.5",
+ "prettier": "2.1.2",
+ "pretty-quick": "3.0.2",
+ "start-server-and-test": "1.12.1",
+ "stylelint": "13.13.1",
+ "stylelint-config-sass-guidelines": "7.1.0",
+ "stylelint-declaration-use-variable": "1.7.3",
+ "transifex-i18ntool": "1.1.0",
+ "ts-node": "9.0.0",
+ "tslint": "6.1.3",
+ "typescript": "4.3.5"
+ },
+ "cypress-cucumber-preprocessor": {
+ "nonGlobalStepDefinitions": true
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/proxy.conf.json.sample b/src/pybind/mgr/dashboard/frontend/proxy.conf.json.sample
new file mode 100644
index 000000000..6a71a26bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/proxy.conf.json.sample
@@ -0,0 +1,12 @@
+{
+ "/api/": {
+ "target": "https://localhost:8443",
+ "secure": false,
+ "logLevel": "debug"
+ },
+ "/ui-api/": {
+ "target": "https://localhost:8443",
+ "secure": false,
+ "logLevel": "debug"
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/app-routing.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/app-routing.module.ts
new file mode 100644
index 000000000..4a490728b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/app-routing.module.ts
@@ -0,0 +1,392 @@
+import { Injectable, NgModule } from '@angular/core';
+import { ActivatedRouteSnapshot, PreloadAllModules, RouterModule, Routes } from '@angular/router';
+
+import _ from 'lodash';
+
+import { CephfsListComponent } from './ceph/cephfs/cephfs-list/cephfs-list.component';
+import { ConfigurationFormComponent } from './ceph/cluster/configuration/configuration-form/configuration-form.component';
+import { ConfigurationComponent } from './ceph/cluster/configuration/configuration.component';
+import { CreateClusterComponent } from './ceph/cluster/create-cluster/create-cluster.component';
+import { CrushmapComponent } from './ceph/cluster/crushmap/crushmap.component';
+import { HostFormComponent } from './ceph/cluster/hosts/host-form/host-form.component';
+import { HostsComponent } from './ceph/cluster/hosts/hosts.component';
+import { InventoryComponent } from './ceph/cluster/inventory/inventory.component';
+import { LogsComponent } from './ceph/cluster/logs/logs.component';
+import { MgrModuleFormComponent } from './ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component';
+import { MgrModuleListComponent } from './ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component';
+import { MonitorComponent } from './ceph/cluster/monitor/monitor.component';
+import { OsdFormComponent } from './ceph/cluster/osd/osd-form/osd-form.component';
+import { OsdListComponent } from './ceph/cluster/osd/osd-list/osd-list.component';
+import { ActiveAlertListComponent } from './ceph/cluster/prometheus/active-alert-list/active-alert-list.component';
+import { RulesListComponent } from './ceph/cluster/prometheus/rules-list/rules-list.component';
+import { SilenceFormComponent } from './ceph/cluster/prometheus/silence-form/silence-form.component';
+import { SilenceListComponent } from './ceph/cluster/prometheus/silence-list/silence-list.component';
+import { ServiceFormComponent } from './ceph/cluster/services/service-form/service-form.component';
+import { ServicesComponent } from './ceph/cluster/services/services.component';
+import { TelemetryComponent } from './ceph/cluster/telemetry/telemetry.component';
+import { DashboardComponent } from './ceph/dashboard/dashboard/dashboard.component';
+import { NfsFormComponent } from './ceph/nfs/nfs-form/nfs-form.component';
+import { NfsListComponent } from './ceph/nfs/nfs-list/nfs-list.component';
+import { PerformanceCounterComponent } from './ceph/performance-counter/performance-counter/performance-counter.component';
+import { LoginPasswordFormComponent } from './core/auth/login-password-form/login-password-form.component';
+import { LoginComponent } from './core/auth/login/login.component';
+import { UserPasswordFormComponent } from './core/auth/user-password-form/user-password-form.component';
+import { ErrorComponent } from './core/error/error.component';
+import { BlankLayoutComponent } from './core/layouts/blank-layout/blank-layout.component';
+import { LoginLayoutComponent } from './core/layouts/login-layout/login-layout.component';
+import { WorkbenchLayoutComponent } from './core/layouts/workbench-layout/workbench-layout.component';
+import { ApiDocsComponent } from './core/navigation/api-docs/api-docs.component';
+import { ActionLabels, URLVerbs } from './shared/constants/app.constants';
+import { BreadcrumbsResolver, IBreadcrumb } from './shared/models/breadcrumbs';
+import { AuthGuardService } from './shared/services/auth-guard.service';
+import { ChangePasswordGuardService } from './shared/services/change-password-guard.service';
+import { FeatureTogglesGuardService } from './shared/services/feature-toggles-guard.service';
+import { ModuleStatusGuardService } from './shared/services/module-status-guard.service';
+import { NoSsoGuardService } from './shared/services/no-sso-guard.service';
+
+@Injectable()
+export class PerformanceCounterBreadcrumbsResolver extends BreadcrumbsResolver {
+ resolve(route: ActivatedRouteSnapshot) {
+ const result: IBreadcrumb[] = [];
+
+ const fromPath = route.queryParams.fromLink || null;
+ let fromText = '';
+ switch (fromPath) {
+ case '/monitor':
+ fromText = 'Monitors';
+ break;
+ case '/hosts':
+ fromText = 'Hosts';
+ break;
+ }
+ result.push({ text: 'Cluster', path: null });
+ result.push({ text: fromText, path: fromPath });
+ result.push({ text: 'Performance Counters', path: '' });
+
+ return result;
+ }
+}
+
+@Injectable()
+export class StartCaseBreadcrumbsResolver extends BreadcrumbsResolver {
+ resolve(route: ActivatedRouteSnapshot) {
+ const path = route.params.name;
+ const text = _.startCase(path);
+ return [{ text: `${text}/Edit`, path: path }];
+ }
+}
+
+const routes: Routes = [
+ // Dashboard
+ { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
+ { path: 'api-docs', component: ApiDocsComponent },
+ {
+ path: '',
+ component: WorkbenchLayoutComponent,
+ canActivate: [AuthGuardService, ChangePasswordGuardService],
+ canActivateChild: [AuthGuardService, ChangePasswordGuardService],
+ children: [
+ { path: 'dashboard', component: DashboardComponent },
+ { path: 'error', component: ErrorComponent },
+
+ // Cluster
+ {
+ path: 'expand-cluster',
+ component: CreateClusterComponent,
+ canActivate: [ModuleStatusGuardService],
+ data: {
+ moduleStatusGuardConfig: {
+ uiApiPath: 'orchestrator',
+ redirectTo: 'dashboard',
+ backend: 'cephadm'
+ },
+ breadcrumbs: 'Expand Cluster'
+ }
+ },
+ {
+ path: 'hosts',
+ component: HostsComponent,
+ data: { breadcrumbs: 'Cluster/Hosts' },
+ children: [
+ {
+ path: URLVerbs.ADD,
+ component: HostFormComponent,
+ outlet: 'modal'
+ }
+ ]
+ },
+ {
+ path: 'monitor',
+ component: MonitorComponent,
+ data: { breadcrumbs: 'Cluster/Monitors' }
+ },
+ {
+ path: 'services',
+ component: ServicesComponent,
+ canActivate: [ModuleStatusGuardService],
+ data: {
+ moduleStatusGuardConfig: {
+ uiApiPath: 'orchestrator',
+ redirectTo: 'error',
+ section: 'orch',
+ section_info: 'Orchestrator',
+ header: 'Orchestrator is not available'
+ },
+ breadcrumbs: 'Cluster/Services'
+ },
+ children: [
+ {
+ path: URLVerbs.CREATE,
+ component: ServiceFormComponent,
+ outlet: 'modal'
+ },
+ {
+ path: `${URLVerbs.EDIT}/:type/:name`,
+ component: ServiceFormComponent,
+ outlet: 'modal'
+ }
+ ]
+ },
+ {
+ path: 'inventory',
+ canActivate: [ModuleStatusGuardService],
+ component: InventoryComponent,
+ data: {
+ moduleStatusGuardConfig: {
+ uiApiPath: 'orchestrator',
+ redirectTo: 'error',
+ section: 'orch',
+ section_info: 'Orchestrator',
+ header: 'Orchestrator is not available'
+ },
+ breadcrumbs: 'Cluster/Physical Disks'
+ }
+ },
+ {
+ path: 'osd',
+ data: { breadcrumbs: 'Cluster/OSDs' },
+ children: [
+ { path: '', component: OsdListComponent },
+ {
+ path: URLVerbs.CREATE,
+ component: OsdFormComponent,
+ data: { breadcrumbs: ActionLabels.CREATE }
+ }
+ ]
+ },
+ {
+ path: 'configuration',
+ data: { breadcrumbs: 'Cluster/Configuration' },
+ children: [
+ { path: '', component: ConfigurationComponent },
+ {
+ path: 'edit/:name',
+ component: ConfigurationFormComponent,
+ data: { breadcrumbs: ActionLabels.EDIT }
+ }
+ ]
+ },
+ {
+ path: 'crush-map',
+ component: CrushmapComponent,
+ data: { breadcrumbs: 'Cluster/CRUSH map' }
+ },
+ {
+ path: 'logs',
+ component: LogsComponent,
+ data: { breadcrumbs: 'Cluster/Logs' }
+ },
+ {
+ path: 'telemetry',
+ component: TelemetryComponent,
+ data: { breadcrumbs: 'Telemetry configuration' }
+ },
+ {
+ path: 'monitoring',
+ data: { breadcrumbs: 'Cluster/Monitoring' },
+ children: [
+ { path: '', redirectTo: 'active-alerts', pathMatch: 'full' },
+ {
+ path: 'active-alerts',
+ data: { breadcrumbs: 'Active Alerts' },
+ component: ActiveAlertListComponent
+ },
+ {
+ path: 'alerts',
+ data: { breadcrumbs: 'Alerts' },
+ component: RulesListComponent
+ },
+ {
+ path: 'silences',
+ data: { breadcrumbs: 'Silences' },
+ children: [
+ {
+ path: '',
+ component: SilenceListComponent
+ },
+ {
+ path: URLVerbs.CREATE,
+ component: SilenceFormComponent,
+ data: { breadcrumbs: `${ActionLabels.CREATE} Silence` }
+ },
+ {
+ path: `${URLVerbs.CREATE}/:id`,
+ component: SilenceFormComponent,
+ data: { breadcrumbs: ActionLabels.CREATE }
+ },
+ {
+ path: `${URLVerbs.EDIT}/:id`,
+ component: SilenceFormComponent,
+ data: { breadcrumbs: ActionLabels.EDIT }
+ },
+ {
+ path: `${URLVerbs.RECREATE}/:id`,
+ component: SilenceFormComponent,
+ data: { breadcrumbs: ActionLabels.RECREATE }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ path: 'perf_counters/:type/:id',
+ component: PerformanceCounterComponent,
+ data: {
+ breadcrumbs: PerformanceCounterBreadcrumbsResolver
+ }
+ },
+ // Mgr modules
+ {
+ path: 'mgr-modules',
+ data: { breadcrumbs: 'Cluster/Manager Modules' },
+ children: [
+ {
+ path: '',
+ component: MgrModuleListComponent
+ },
+ {
+ path: 'edit/:name',
+ component: MgrModuleFormComponent,
+ data: {
+ breadcrumbs: StartCaseBreadcrumbsResolver
+ }
+ }
+ ]
+ },
+ // Pools
+ {
+ path: 'pool',
+ data: { breadcrumbs: 'Pools' },
+ loadChildren: () => import('./ceph/pool/pool.module').then((m) => m.RoutedPoolModule)
+ },
+ // Block
+ {
+ path: 'block',
+ data: { breadcrumbs: true, text: 'Block', path: null },
+ loadChildren: () => import('./ceph/block/block.module').then((m) => m.RoutedBlockModule)
+ },
+ // File Systems
+ {
+ path: 'cephfs',
+ component: CephfsListComponent,
+ canActivate: [FeatureTogglesGuardService],
+ data: { breadcrumbs: 'File Systems' }
+ },
+ // Object Gateway
+ {
+ path: 'rgw',
+ canActivateChild: [FeatureTogglesGuardService, ModuleStatusGuardService],
+ data: {
+ moduleStatusGuardConfig: {
+ uiApiPath: 'rgw',
+ redirectTo: 'error',
+ section: 'rgw',
+ section_info: 'Object Gateway',
+ header: 'The Object Gateway Service is not configured'
+ },
+ breadcrumbs: true,
+ text: 'Object Gateway',
+ path: null
+ },
+ loadChildren: () => import('./ceph/rgw/rgw.module').then((m) => m.RoutedRgwModule)
+ },
+ // User/Role Management
+ {
+ path: 'user-management',
+ data: { breadcrumbs: 'User management', path: null },
+ loadChildren: () => import('./core/auth/auth.module').then((m) => m.RoutedAuthModule)
+ },
+ // User Profile
+ {
+ path: 'user-profile',
+ data: { breadcrumbs: 'User profile', path: null },
+ children: [
+ {
+ path: URLVerbs.EDIT,
+ component: UserPasswordFormComponent,
+ canActivate: [NoSsoGuardService],
+ data: { breadcrumbs: ActionLabels.EDIT }
+ }
+ ]
+ },
+ // NFS
+ {
+ path: 'nfs',
+ canActivateChild: [FeatureTogglesGuardService, ModuleStatusGuardService],
+ data: {
+ moduleStatusGuardConfig: {
+ uiApiPath: 'nfs-ganesha',
+ redirectTo: 'error',
+ section: 'nfs-ganesha',
+ section_info: 'NFS GANESHA',
+ header: 'NFS-Ganesha is not configured'
+ },
+ breadcrumbs: 'NFS'
+ },
+ children: [
+ { path: '', component: NfsListComponent },
+ {
+ path: URLVerbs.CREATE,
+ component: NfsFormComponent,
+ data: { breadcrumbs: ActionLabels.CREATE }
+ },
+ {
+ path: `${URLVerbs.EDIT}/:cluster_id/:export_id`,
+ component: NfsFormComponent,
+ data: { breadcrumbs: ActionLabels.EDIT }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ path: '',
+ component: LoginLayoutComponent,
+ children: [
+ { path: 'login', component: LoginComponent },
+ {
+ path: 'login-change-password',
+ component: LoginPasswordFormComponent,
+ canActivate: [NoSsoGuardService]
+ }
+ ]
+ },
+ {
+ path: '',
+ component: BlankLayoutComponent,
+ children: [{ path: '**', redirectTo: '/error' }]
+ }
+];
+
+@NgModule({
+ imports: [
+ RouterModule.forRoot(routes, {
+ useHash: true,
+ preloadingStrategy: PreloadAllModules,
+ relativeLinkResolution: 'legacy'
+ })
+ ],
+ exports: [RouterModule],
+ providers: [StartCaseBreadcrumbsResolver, PerformanceCounterBreadcrumbsResolver]
+})
+export class AppRoutingModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/app.component.html b/src/pybind/mgr/dashboard/frontend/src/app/app.component.html
new file mode 100644
index 000000000..0680b43f9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/app.component.html
@@ -0,0 +1 @@
+<router-outlet></router-outlet>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/app.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/app.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/app.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/app.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/app.component.spec.ts
new file mode 100644
index 000000000..71643d37c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/app.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { AppComponent } from './app.component';
+
+describe('AppComponent', () => {
+ let component: AppComponent;
+ let fixture: ComponentFixture<AppComponent>;
+
+ configureTestBed({
+ declarations: [AppComponent],
+ imports: [RouterTestingModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AppComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/app.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/app.component.ts
new file mode 100644
index 000000000..5f483cc94
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/app.component.ts
@@ -0,0 +1,18 @@
+import { Component } from '@angular/core';
+
+import { NgbPopoverConfig, NgbTooltipConfig } from '@ng-bootstrap/ng-bootstrap';
+
+@Component({
+ selector: 'cd-root',
+ templateUrl: './app.component.html',
+ styleUrls: ['./app.component.scss']
+})
+export class AppComponent {
+ constructor(popoverConfig: NgbPopoverConfig, tooltipConfig: NgbTooltipConfig) {
+ popoverConfig.autoClose = 'outside';
+ popoverConfig.container = 'body';
+ popoverConfig.placement = 'bottom';
+
+ tooltipConfig.container = 'body';
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/app.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/app.module.ts
new file mode 100644
index 000000000..970f3a112
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/app.module.ts
@@ -0,0 +1,51 @@
+import { APP_BASE_HREF } from '@angular/common';
+import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
+import { ErrorHandler, NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+import { ToastrModule } from 'ngx-toastr';
+
+import { AppRoutingModule } from './app-routing.module';
+import { AppComponent } from './app.component';
+import { CephModule } from './ceph/ceph.module';
+import { CoreModule } from './core/core.module';
+import { ApiInterceptorService } from './shared/services/api-interceptor.service';
+import { JsErrorHandler } from './shared/services/js-error-handler.service';
+import { SharedModule } from './shared/shared.module';
+
+@NgModule({
+ declarations: [AppComponent],
+ imports: [
+ HttpClientModule,
+ BrowserModule,
+ BrowserAnimationsModule,
+ ToastrModule.forRoot({
+ positionClass: 'toast-top-right',
+ preventDuplicates: true,
+ enableHtml: true
+ }),
+ AppRoutingModule,
+ CoreModule,
+ SharedModule,
+ CephModule
+ ],
+ exports: [SharedModule],
+ providers: [
+ {
+ provide: ErrorHandler,
+ useClass: JsErrorHandler
+ },
+ {
+ provide: HTTP_INTERCEPTORS,
+ useClass: ApiInterceptorService,
+ multi: true
+ },
+ {
+ provide: APP_BASE_HREF,
+ useValue: '/' + (window.location.pathname.split('/', 1)[1] || '')
+ }
+ ],
+ bootstrap: [AppComponent]
+})
+export class AppModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts
new file mode 100644
index 000000000..8a13f1c69
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts
@@ -0,0 +1,205 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { RouterModule, Routes } from '@angular/router';
+
+import { TreeModule } from '@circlon/angular-tree-component';
+import { NgbNavModule, NgbPopoverModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgxPipeFunctionModule } from 'ngx-pipe-function';
+
+import { ActionLabels, URLVerbs } from '~/app/shared/constants/app.constants';
+import { FeatureTogglesGuardService } from '~/app/shared/services/feature-toggles-guard.service';
+import { ModuleStatusGuardService } from '~/app/shared/services/module-status-guard.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { IscsiSettingComponent } from './iscsi-setting/iscsi-setting.component';
+import { IscsiTabsComponent } from './iscsi-tabs/iscsi-tabs.component';
+import { IscsiTargetDetailsComponent } from './iscsi-target-details/iscsi-target-details.component';
+import { IscsiTargetDiscoveryModalComponent } from './iscsi-target-discovery-modal/iscsi-target-discovery-modal.component';
+import { IscsiTargetFormComponent } from './iscsi-target-form/iscsi-target-form.component';
+import { IscsiTargetImageSettingsModalComponent } from './iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component';
+import { IscsiTargetIqnSettingsModalComponent } from './iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component';
+import { IscsiTargetListComponent } from './iscsi-target-list/iscsi-target-list.component';
+import { IscsiComponent } from './iscsi/iscsi.component';
+import { MirroringModule } from './mirroring/mirroring.module';
+import { OverviewComponent as RbdMirroringComponent } from './mirroring/overview/overview.component';
+import { PoolEditModeModalComponent } from './mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component';
+import { RbdConfigurationFormComponent } from './rbd-configuration-form/rbd-configuration-form.component';
+import { RbdConfigurationListComponent } from './rbd-configuration-list/rbd-configuration-list.component';
+import { RbdDetailsComponent } from './rbd-details/rbd-details.component';
+import { RbdFormComponent } from './rbd-form/rbd-form.component';
+import { RbdListComponent } from './rbd-list/rbd-list.component';
+import { RbdNamespaceFormModalComponent } from './rbd-namespace-form/rbd-namespace-form-modal.component';
+import { RbdNamespaceListComponent } from './rbd-namespace-list/rbd-namespace-list.component';
+import { RbdPerformanceComponent } from './rbd-performance/rbd-performance.component';
+import { RbdSnapshotFormModalComponent } from './rbd-snapshot-form/rbd-snapshot-form-modal.component';
+import { RbdSnapshotListComponent } from './rbd-snapshot-list/rbd-snapshot-list.component';
+import { RbdTabsComponent } from './rbd-tabs/rbd-tabs.component';
+import { RbdTrashListComponent } from './rbd-trash-list/rbd-trash-list.component';
+import { RbdTrashMoveModalComponent } from './rbd-trash-move-modal/rbd-trash-move-modal.component';
+import { RbdTrashPurgeModalComponent } from './rbd-trash-purge-modal/rbd-trash-purge-modal.component';
+import { RbdTrashRestoreModalComponent } from './rbd-trash-restore-modal/rbd-trash-restore-modal.component';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ MirroringModule,
+ FormsModule,
+ ReactiveFormsModule,
+ NgbNavModule,
+ NgbPopoverModule,
+ NgbTooltipModule,
+ NgxPipeFunctionModule,
+ SharedModule,
+ RouterModule,
+ TreeModule
+ ],
+ declarations: [
+ RbdListComponent,
+ IscsiComponent,
+ IscsiSettingComponent,
+ IscsiTabsComponent,
+ IscsiTargetListComponent,
+ RbdDetailsComponent,
+ RbdFormComponent,
+ RbdNamespaceFormModalComponent,
+ RbdNamespaceListComponent,
+ RbdSnapshotListComponent,
+ RbdSnapshotFormModalComponent,
+ RbdTrashListComponent,
+ RbdTrashMoveModalComponent,
+ RbdTrashRestoreModalComponent,
+ RbdTrashPurgeModalComponent,
+ IscsiTargetDetailsComponent,
+ IscsiTargetFormComponent,
+ IscsiTargetImageSettingsModalComponent,
+ IscsiTargetIqnSettingsModalComponent,
+ IscsiTargetDiscoveryModalComponent,
+ RbdConfigurationListComponent,
+ RbdConfigurationFormComponent,
+ RbdTabsComponent,
+ RbdPerformanceComponent
+ ],
+ exports: [RbdConfigurationListComponent, RbdConfigurationFormComponent]
+})
+export class BlockModule {}
+
+/* The following breakdown is needed to allow importing block.module without
+ the routes (e.g.: this module is imported by pool.module for RBD QoS
+ components)
+*/
+const routes: Routes = [
+ { path: '', redirectTo: 'rbd', pathMatch: 'full' },
+ {
+ path: 'rbd',
+ canActivate: [FeatureTogglesGuardService, ModuleStatusGuardService],
+ data: {
+ moduleStatusGuardConfig: {
+ uiApiPath: 'block/rbd',
+ redirectTo: 'error',
+ header: 'No RBD pools available',
+ button_name: 'Create RBD pool',
+ button_route: '/pool/create'
+ },
+ breadcrumbs: 'Images'
+ },
+ children: [
+ { path: '', component: RbdListComponent },
+ {
+ path: 'namespaces',
+ component: RbdNamespaceListComponent,
+ data: { breadcrumbs: 'Namespaces' }
+ },
+ {
+ path: 'trash',
+ component: RbdTrashListComponent,
+ data: { breadcrumbs: 'Trash' }
+ },
+ {
+ path: 'performance',
+ component: RbdPerformanceComponent,
+ data: { breadcrumbs: 'Overall Performance' }
+ },
+ {
+ path: URLVerbs.CREATE,
+ component: RbdFormComponent,
+ data: { breadcrumbs: ActionLabels.CREATE }
+ },
+ {
+ path: `${URLVerbs.EDIT}/:image_spec`,
+ component: RbdFormComponent,
+ data: { breadcrumbs: ActionLabels.EDIT }
+ },
+ {
+ path: `${URLVerbs.CLONE}/:image_spec/:snap`,
+ component: RbdFormComponent,
+ data: { breadcrumbs: ActionLabels.CLONE }
+ },
+ {
+ path: `${URLVerbs.COPY}/:image_spec`,
+ component: RbdFormComponent,
+ data: { breadcrumbs: ActionLabels.COPY }
+ },
+ {
+ path: `${URLVerbs.COPY}/:image_spec/:snap`,
+ component: RbdFormComponent,
+ data: { breadcrumbs: ActionLabels.COPY }
+ }
+ ]
+ },
+ {
+ path: 'mirroring',
+ component: RbdMirroringComponent,
+ canActivate: [FeatureTogglesGuardService, ModuleStatusGuardService],
+ data: {
+ moduleStatusGuardConfig: {
+ uiApiPath: 'block/mirroring',
+ redirectTo: 'error',
+ header: $localize`RBD mirroring is not configured`,
+ button_name: $localize`Configure RBD Mirroring`,
+ button_title: $localize`This will create rbd-mirror service and a replicated RBD pool`,
+ component: 'RBD Mirroring',
+ uiConfig: true
+ },
+ breadcrumbs: 'Mirroring'
+ },
+ children: [
+ {
+ path: `${URLVerbs.EDIT}/:pool_name`,
+ component: PoolEditModeModalComponent,
+ outlet: 'modal'
+ }
+ ]
+ },
+ // iSCSI
+ {
+ path: 'iscsi',
+ canActivate: [FeatureTogglesGuardService],
+ data: { breadcrumbs: 'iSCSI' },
+ children: [
+ { path: '', redirectTo: 'overview', pathMatch: 'full' },
+ { path: 'overview', component: IscsiComponent, data: { breadcrumbs: 'Overview' } },
+ {
+ path: 'targets',
+ data: { breadcrumbs: 'Targets' },
+ children: [
+ { path: '', component: IscsiTargetListComponent },
+ {
+ path: URLVerbs.CREATE,
+ component: IscsiTargetFormComponent,
+ data: { breadcrumbs: ActionLabels.CREATE }
+ },
+ {
+ path: `${URLVerbs.EDIT}/:target_iqn`,
+ component: IscsiTargetFormComponent,
+ data: { breadcrumbs: ActionLabels.EDIT }
+ }
+ ]
+ }
+ ]
+ }
+];
+
+@NgModule({
+ imports: [BlockModule, RouterModule.forChild(routes)]
+})
+export class RoutedBlockModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.html
new file mode 100644
index 000000000..b19941ae0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.html
@@ -0,0 +1,57 @@
+<div class="form-group"
+ [formGroup]="settingsForm">
+ <label class="col-form-label"
+ for="{{ setting }}">{{ setting }}</label>
+ <select id="{{ setting }}"
+ name="{{ setting }}"
+ *ngIf="limits['type'] === 'enum'"
+ class="form-control"
+ [formControlName]="setting">
+ <option [ngValue]="null"></option>
+ <option *ngFor="let opt of limits['values']"
+ [ngValue]="opt">{{ opt }}</option>
+ </select>
+
+ <span *ngIf="limits['type'] !== 'enum'">
+ <input type="number"
+ *ngIf="limits['type'] === 'int'"
+ class="form-control"
+ [formControlName]="setting">
+
+ <input type="text"
+ *ngIf="limits['type'] === 'str'"
+ class="form-control"
+ [formControlName]="setting">
+
+ <ng-container *ngIf="limits['type'] === 'bool'">
+ <br>
+ <div class="custom-control custom-radio custom-control-inline">
+ <input type="radio"
+ [id]="setting + 'True'"
+ [value]="true"
+ [formControlName]="setting"
+ class="custom-control-input">
+ <label class="custom-control-label"
+ [for]="setting + 'True'">Yes</label>
+ </div>
+ <div class="custom-control custom-radio custom-control-inline">
+ <input type="radio"
+ [id]="setting + 'False'"
+ [value]="false"
+ class="custom-control-input"
+ [formControlName]="setting">
+ <label class="custom-control-label"
+ [for]="setting + 'False'">No</label>
+ </div>
+ </ng-container>
+ </span>
+
+ <span class="invalid-feedback"
+ *ngIf="settingsForm.showError(setting, formDir, 'min')">
+ <ng-container i18n>Must be greater than or equal to {{ limits['min'] }}.</ng-container>
+ </span>
+ <span class="invalid-feedback"
+ *ngIf="settingsForm.showError(setting, formDir, 'max')">
+ <ng-container i18n>Must be less than or equal to {{ limits['max'] }}.</ng-container>
+ </span>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.spec.ts
new file mode 100644
index 000000000..19aee4df3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.spec.ts
@@ -0,0 +1,37 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormControl, NgForm, ReactiveFormsModule } from '@angular/forms';
+
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { IscsiSettingComponent } from './iscsi-setting.component';
+
+describe('IscsiSettingComponent', () => {
+ let component: IscsiSettingComponent;
+ let fixture: ComponentFixture<IscsiSettingComponent>;
+
+ configureTestBed({
+ imports: [SharedModule, ReactiveFormsModule],
+ declarations: [IscsiSettingComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(IscsiSettingComponent);
+ component = fixture.componentInstance;
+ component.settingsForm = new CdFormGroup({
+ max_data_area_mb: new FormControl()
+ });
+ component.formDir = new NgForm([], []);
+ component.setting = 'max_data_area_mb';
+ component.limits = {
+ type: 'int',
+ min: 1,
+ max: 2048
+ };
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.ts
new file mode 100644
index 000000000..fbbd28b20
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.ts
@@ -0,0 +1,31 @@
+import { Component, Input, OnInit } from '@angular/core';
+import { NgForm, ValidatorFn, Validators } from '@angular/forms';
+
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+
+@Component({
+ selector: 'cd-iscsi-setting',
+ templateUrl: './iscsi-setting.component.html',
+ styleUrls: ['./iscsi-setting.component.scss']
+})
+export class IscsiSettingComponent implements OnInit {
+ @Input()
+ settingsForm: CdFormGroup;
+ @Input()
+ formDir: NgForm;
+ @Input()
+ setting: string;
+ @Input()
+ limits: object;
+
+ ngOnInit() {
+ const validators: ValidatorFn[] = [];
+ if ('min' in this.limits) {
+ validators.push(Validators.min(this.limits['min']));
+ }
+ if ('max' in this.limits) {
+ validators.push(Validators.max(this.limits['max']));
+ }
+ this.settingsForm.get(this.setting).setValidators(validators);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html
new file mode 100644
index 000000000..3d328cb6b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html
@@ -0,0 +1,14 @@
+<ul ngbNav
+ #nav="ngbNav"
+ [activeId]="router.url"
+ (navChange)="router.navigate([$event.nextId])"
+ class="nav-tabs">
+ <li ngbNavItem="/block/iscsi/overview">
+ <a ngbNavLink
+ i18n>Overview</a>
+ </li>
+ <li ngbNavItem="/block/iscsi/targets">
+ <a ngbNavLink
+ i18n>Targets</a>
+ </li>
+</ul>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.spec.ts
new file mode 100644
index 000000000..9bdddf78d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.spec.ts
@@ -0,0 +1,28 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { IscsiTabsComponent } from './iscsi-tabs.component';
+
+describe('IscsiTabsComponent', () => {
+ let component: IscsiTabsComponent;
+ let fixture: ComponentFixture<IscsiTabsComponent>;
+
+ configureTestBed({
+ imports: [SharedModule, RouterTestingModule, NgbNavModule],
+ declarations: [IscsiTabsComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(IscsiTabsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.ts
new file mode 100644
index 000000000..d4d21361b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.ts
@@ -0,0 +1,11 @@
+import { Component } from '@angular/core';
+import { Router } from '@angular/router';
+
+@Component({
+ selector: 'cd-iscsi-tabs',
+ templateUrl: './iscsi-tabs.component.html',
+ styleUrls: ['./iscsi-tabs.component.scss']
+})
+export class IscsiTabsComponent {
+ constructor(public router: Router) {}
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html
new file mode 100644
index 000000000..29d91ef47
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html
@@ -0,0 +1,41 @@
+<div class="row">
+ <div class="col-6">
+ <legend i18n>iSCSI Topology</legend>
+
+ <tree-root #tree
+ [nodes]="nodes"
+ [options]="treeOptions"
+ (updateData)="onUpdateData()">
+ <ng-template #treeNodeTemplate
+ let-node
+ let-index="index">
+ <i [class]="node.data.cdIcon"></i>
+ <span>{{ node.data.name }}</span>
+ &nbsp;
+ <span class="badge"
+ [ngClass]="{'badge-success': ['logged_in'].includes(node.data.status), 'badge-danger': ['logged_out'].includes(node.data.status)}">
+ {{ node.data.status }}
+ </span>
+ </ng-template>
+ </tree-root>
+ </div>
+
+ <div class="col-6 metadata"
+ *ngIf="data">
+ <legend>{{ title }}</legend>
+
+ <cd-table #detailTable
+ [data]="data"
+ columnMode="flex"
+ [columns]="columns"
+ [limit]="0">
+ </cd-table>
+ </div>
+</div>
+
+<ng-template #highlightTpl
+ let-row="row"
+ let-value="value">
+ <span *ngIf="row.default === undefined || row.default === row.current">{{ value }}</span>
+ <strong *ngIf="row.default !== undefined && row.default !== row.current">{{ value }}</strong>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.spec.ts
new file mode 100644
index 000000000..d95ed76e5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.spec.ts
@@ -0,0 +1,207 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+import { TreeModel, TreeModule } from '@circlon/angular-tree-component';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { IscsiTargetDetailsComponent } from './iscsi-target-details.component';
+
+describe('IscsiTargetDetailsComponent', () => {
+ let component: IscsiTargetDetailsComponent;
+ let fixture: ComponentFixture<IscsiTargetDetailsComponent>;
+
+ configureTestBed({
+ declarations: [IscsiTargetDetailsComponent],
+ imports: [BrowserAnimationsModule, TreeModule, SharedModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(IscsiTargetDetailsComponent);
+ component = fixture.componentInstance;
+
+ component.settings = {
+ config: { minimum_gateways: 2 },
+ disk_default_controls: {
+ 'backstore:1': {
+ hw_max_sectors: 1024,
+ max_data_area_mb: 8
+ },
+ 'backstore:2': {
+ hw_max_sectors: 1024,
+ max_data_area_mb: 8
+ }
+ },
+ target_default_controls: {
+ cmdsn_depth: 128,
+ dataout_timeout: 20
+ },
+ backstores: ['backstore:1', 'backstore:2'],
+ default_backstore: 'backstore:1'
+ };
+ component.selection = undefined;
+ component.selection = {
+ target_iqn: 'iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw',
+ portals: [{ host: 'node1', ip: '192.168.100.201' }],
+ disks: [
+ {
+ pool: 'rbd',
+ image: 'disk_1',
+ backstore: 'backstore:1',
+ controls: { hw_max_sectors: 1 }
+ }
+ ],
+ clients: [
+ {
+ client_iqn: 'iqn.1994-05.com.redhat:rh7-client',
+ luns: [{ pool: 'rbd', image: 'disk_1' }],
+ auth: {
+ user: 'myiscsiusername'
+ },
+ info: {
+ alias: 'myhost',
+ ip_address: ['192.168.200.1'],
+ state: { LOGGED_IN: ['node1'] }
+ }
+ }
+ ],
+ groups: [],
+ target_controls: { dataout_timeout: 2 }
+ };
+
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should empty data and generateTree when ngOnChanges is called', () => {
+ const tempData = [{ current: 'baz', default: 'bar', displayName: 'foo' }];
+ component.data = tempData;
+ fixture.detectChanges();
+
+ expect(component.data).toEqual(tempData);
+ expect(component.metadata).toEqual({});
+ expect(component.nodes).toEqual([]);
+
+ component.ngOnChanges();
+
+ expect(component.data).toBeUndefined();
+ expect(component.metadata).toEqual({
+ 'client_iqn.1994-05.com.redhat:rh7-client': {
+ user: 'myiscsiusername',
+ alias: 'myhost',
+ ip_address: ['192.168.200.1'],
+ logged_in: ['node1']
+ },
+ disk_rbd_disk_1: { backstore: 'backstore:1', controls: { hw_max_sectors: 1 } },
+ root: { dataout_timeout: 2 }
+ });
+ expect(component.nodes).toEqual([
+ {
+ cdIcon: 'fa fa-lg fa fa-bullseye',
+ cdId: 'root',
+ children: [
+ {
+ cdIcon: 'fa fa-lg fa fa-hdd-o',
+ children: [
+ {
+ cdIcon: 'fa fa-hdd-o',
+ cdId: 'disk_rbd_disk_1',
+ name: 'rbd/disk_1'
+ }
+ ],
+ isExpanded: true,
+ name: 'Disks'
+ },
+ {
+ cdIcon: 'fa fa-lg fa fa-server',
+ children: [
+ {
+ cdIcon: 'fa fa-server',
+ name: 'node1:192.168.100.201'
+ }
+ ],
+ isExpanded: true,
+ name: 'Portals'
+ },
+ {
+ cdIcon: 'fa fa-lg fa fa-user',
+ children: [
+ {
+ cdIcon: 'fa fa-user',
+ cdId: 'client_iqn.1994-05.com.redhat:rh7-client',
+ children: [
+ {
+ cdIcon: 'fa fa-hdd-o',
+ cdId: 'disk_rbd_disk_1',
+ name: 'rbd/disk_1'
+ }
+ ],
+ name: 'iqn.1994-05.com.redhat:rh7-client',
+ status: 'logged_in'
+ }
+ ],
+ isExpanded: true,
+ name: 'Initiators'
+ },
+ {
+ cdIcon: 'fa fa-lg fa fa-users',
+ children: [],
+ isExpanded: true,
+ name: 'Groups'
+ }
+ ],
+ isExpanded: true,
+ name: 'iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw'
+ }
+ ]);
+ });
+
+ describe('should update data when onNodeSelected is called', () => {
+ let tree: TreeModel;
+
+ beforeEach(() => {
+ component.ngOnChanges();
+ tree = component.tree.treeModel;
+ fixture.detectChanges();
+ });
+
+ it('with target selected', () => {
+ const node = tree.getNodeBy({ data: { cdId: 'root' } });
+ component.onNodeSelected(tree, node);
+ expect(component.data).toEqual([
+ { current: 128, default: 128, displayName: 'cmdsn_depth' },
+ { current: 2, default: 20, displayName: 'dataout_timeout' }
+ ]);
+ });
+
+ it('with disk selected', () => {
+ const node = tree.getNodeBy({ data: { cdId: 'disk_rbd_disk_1' } });
+ component.onNodeSelected(tree, node);
+ expect(component.data).toEqual([
+ { current: 1, default: 1024, displayName: 'hw_max_sectors' },
+ { current: 8, default: 8, displayName: 'max_data_area_mb' },
+ { current: 'backstore:1', default: 'backstore:1', displayName: 'backstore' }
+ ]);
+ });
+
+ it('with initiator selected', () => {
+ const node = tree.getNodeBy({ data: { cdId: 'client_iqn.1994-05.com.redhat:rh7-client' } });
+ component.onNodeSelected(tree, node);
+ expect(component.data).toEqual([
+ { current: 'myiscsiusername', default: undefined, displayName: 'user' },
+ { current: 'myhost', default: undefined, displayName: 'alias' },
+ { current: ['192.168.200.1'], default: undefined, displayName: 'ip_address' },
+ { current: ['node1'], default: undefined, displayName: 'logged_in' }
+ ]);
+ });
+
+ it('with any other selected', () => {
+ const node = tree.getNodeBy({ data: { name: 'Disks' } });
+ component.onNodeSelected(tree, node);
+ expect(component.data).toBeUndefined();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts
new file mode 100644
index 000000000..3840bb3fb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts
@@ -0,0 +1,346 @@
+import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import {
+ ITreeOptions,
+ TreeComponent,
+ TreeModel,
+ TreeNode,
+ TREE_ACTIONS
+} from '@circlon/angular-tree-component';
+import _ from 'lodash';
+
+import { TableComponent } from '~/app/shared/datatable/table/table.component';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { BooleanTextPipe } from '~/app/shared/pipes/boolean-text.pipe';
+import { IscsiBackstorePipe } from '~/app/shared/pipes/iscsi-backstore.pipe';
+
+@Component({
+ selector: 'cd-iscsi-target-details',
+ templateUrl: './iscsi-target-details.component.html',
+ styleUrls: ['./iscsi-target-details.component.scss']
+})
+export class IscsiTargetDetailsComponent implements OnChanges, OnInit {
+ @Input()
+ selection: any;
+ @Input()
+ settings: any;
+ @Input()
+ cephIscsiConfigVersion: number;
+
+ @ViewChild('highlightTpl', { static: true })
+ highlightTpl: TemplateRef<any>;
+
+ private detailTable: TableComponent;
+ @ViewChild('detailTable')
+ set content(content: TableComponent) {
+ this.detailTable = content;
+ if (content) {
+ content.updateColumns();
+ }
+ }
+
+ @ViewChild('tree') tree: TreeComponent;
+
+ icons = Icons;
+ columns: CdTableColumn[];
+ data: any;
+ metadata: any = {};
+ selectedItem: any;
+ title: string;
+
+ nodes: any[] = [];
+ treeOptions: ITreeOptions = {
+ useVirtualScroll: true,
+ actionMapping: {
+ mouse: {
+ click: this.onNodeSelected.bind(this)
+ }
+ }
+ };
+
+ constructor(
+ private iscsiBackstorePipe: IscsiBackstorePipe,
+ private booleanTextPipe: BooleanTextPipe
+ ) {}
+
+ ngOnInit() {
+ this.columns = [
+ {
+ prop: 'displayName',
+ name: $localize`Name`,
+ flexGrow: 1,
+ cellTemplate: this.highlightTpl
+ },
+ {
+ prop: 'current',
+ name: $localize`Current`,
+ flexGrow: 1,
+ cellTemplate: this.highlightTpl
+ },
+ {
+ prop: 'default',
+ name: $localize`Default`,
+ flexGrow: 1,
+ cellTemplate: this.highlightTpl
+ }
+ ];
+ }
+
+ ngOnChanges() {
+ if (this.selection) {
+ this.selectedItem = this.selection;
+ this.generateTree();
+ }
+
+ this.data = undefined;
+ }
+
+ private generateTree() {
+ const target_meta = _.cloneDeep(this.selectedItem.target_controls);
+ // Target level authentication was introduced in ceph-iscsi config v11
+ if (this.cephIscsiConfigVersion > 10) {
+ _.extend(target_meta, _.cloneDeep(this.selectedItem.auth));
+ }
+ this.metadata = { root: target_meta };
+ const cssClasses = {
+ target: {
+ expanded: _.join(
+ this.selectedItem.cdExecuting
+ ? [Icons.large, Icons.spinner, Icons.spin]
+ : [Icons.large, Icons.bullseye],
+ ' '
+ )
+ },
+ initiators: {
+ expanded: _.join([Icons.large, Icons.user], ' '),
+ leaf: _.join([Icons.user], ' ')
+ },
+ groups: {
+ expanded: _.join([Icons.large, Icons.users], ' '),
+ leaf: _.join([Icons.users], ' ')
+ },
+ disks: {
+ expanded: _.join([Icons.large, Icons.disk], ' '),
+ leaf: _.join([Icons.disk], ' ')
+ },
+ portals: {
+ expanded: _.join([Icons.large, Icons.server], ' '),
+ leaf: _.join([Icons.server], ' ')
+ }
+ };
+
+ const disks: any[] = [];
+ _.forEach(this.selectedItem.disks, (disk) => {
+ const cdId = 'disk_' + disk.pool + '_' + disk.image;
+ this.metadata[cdId] = {
+ controls: disk.controls,
+ backstore: disk.backstore
+ };
+ ['wwn', 'lun'].forEach((k) => {
+ if (k in disk) {
+ this.metadata[cdId][k] = disk[k];
+ }
+ });
+ disks.push({
+ name: `${disk.pool}/${disk.image}`,
+ cdId: cdId,
+ cdIcon: cssClasses.disks.leaf
+ });
+ });
+
+ const portals: any[] = [];
+ _.forEach(this.selectedItem.portals, (portal) => {
+ portals.push({
+ name: `${portal.host}:${portal.ip}`,
+ cdIcon: cssClasses.portals.leaf
+ });
+ });
+
+ const clients: any[] = [];
+ _.forEach(this.selectedItem.clients, (client) => {
+ const client_metadata = _.cloneDeep(client.auth);
+ if (client.info) {
+ _.extend(client_metadata, client.info);
+ delete client_metadata['state'];
+ _.forEach(Object.keys(client.info.state), (state) => {
+ client_metadata[state.toLowerCase()] = client.info.state[state];
+ });
+ }
+ this.metadata['client_' + client.client_iqn] = client_metadata;
+
+ const luns: any[] = [];
+ client.luns.forEach((lun: Record<string, any>) => {
+ luns.push({
+ name: `${lun.pool}/${lun.image}`,
+ cdId: 'disk_' + lun.pool + '_' + lun.image,
+ cdIcon: cssClasses.disks.leaf
+ });
+ });
+
+ let status = '';
+ if (client.info) {
+ status = Object.keys(client.info.state).includes('LOGGED_IN') ? 'logged_in' : 'logged_out';
+ }
+ clients.push({
+ name: client.client_iqn,
+ status: status,
+ cdId: 'client_' + client.client_iqn,
+ children: luns,
+ cdIcon: cssClasses.initiators.leaf
+ });
+ });
+
+ const groups: any[] = [];
+ _.forEach(this.selectedItem.groups, (group) => {
+ const luns: any[] = [];
+ group.disks.forEach((disk: Record<string, any>) => {
+ luns.push({
+ name: `${disk.pool}/${disk.image}`,
+ cdId: 'disk_' + disk.pool + '_' + disk.image,
+ cdIcon: cssClasses.disks.leaf
+ });
+ });
+
+ const initiators: any[] = [];
+ group.members.forEach((member: string) => {
+ initiators.push({
+ name: member,
+ cdId: 'client_' + member
+ });
+ });
+
+ groups.push({
+ name: group.group_id,
+ cdIcon: cssClasses.groups.leaf,
+ children: [
+ {
+ name: 'Disks',
+ children: luns,
+ cdIcon: cssClasses.disks.expanded
+ },
+ {
+ name: 'Initiators',
+ children: initiators,
+ cdIcon: cssClasses.initiators.expanded
+ }
+ ]
+ });
+ });
+
+ this.nodes = [
+ {
+ name: this.selectedItem.target_iqn,
+ cdId: 'root',
+ isExpanded: true,
+ cdIcon: cssClasses.target.expanded,
+ children: [
+ {
+ name: 'Disks',
+ isExpanded: true,
+ children: disks,
+ cdIcon: cssClasses.disks.expanded
+ },
+ {
+ name: 'Portals',
+ isExpanded: true,
+ children: portals,
+ cdIcon: cssClasses.portals.expanded
+ },
+ {
+ name: 'Initiators',
+ isExpanded: true,
+ children: clients,
+ cdIcon: cssClasses.initiators.expanded
+ },
+ {
+ name: 'Groups',
+ isExpanded: true,
+ children: groups,
+ cdIcon: cssClasses.groups.expanded
+ }
+ ]
+ }
+ ];
+ }
+
+ private format(value: any) {
+ if (typeof value === 'boolean') {
+ return this.booleanTextPipe.transform(value);
+ }
+ return value;
+ }
+
+ onNodeSelected(tree: TreeModel, node: TreeNode) {
+ TREE_ACTIONS.ACTIVATE(tree, node, true);
+ if (node.data.cdId) {
+ this.title = node.data.name;
+ const tempData = this.metadata[node.data.cdId] || {};
+
+ if (node.data.cdId === 'root') {
+ this.detailTable?.toggleColumn({ prop: 'default', isHidden: true });
+ this.data = _.map(this.settings.target_default_controls, (value, key) => {
+ value = this.format(value);
+ return {
+ displayName: key,
+ default: value,
+ current: !_.isUndefined(tempData[key]) ? this.format(tempData[key]) : value
+ };
+ });
+ // Target level authentication was introduced in ceph-iscsi config v11
+ if (this.cephIscsiConfigVersion > 10) {
+ ['user', 'password', 'mutual_user', 'mutual_password'].forEach((key) => {
+ this.data.push({
+ displayName: key,
+ default: null,
+ current: tempData[key]
+ });
+ });
+ }
+ } else if (node.data.cdId.toString().startsWith('disk_')) {
+ this.detailTable?.toggleColumn({ prop: 'default', isHidden: true });
+ this.data = _.map(this.settings.disk_default_controls[tempData.backstore], (value, key) => {
+ value = this.format(value);
+ return {
+ displayName: key,
+ default: value,
+ current: !_.isUndefined(tempData.controls[key])
+ ? this.format(tempData.controls[key])
+ : value
+ };
+ });
+ this.data.push({
+ displayName: 'backstore',
+ default: this.iscsiBackstorePipe.transform(this.settings.default_backstore),
+ current: this.iscsiBackstorePipe.transform(tempData.backstore)
+ });
+ ['wwn', 'lun'].forEach((k) => {
+ if (k in tempData) {
+ this.data.push({
+ displayName: k,
+ default: undefined,
+ current: tempData[k]
+ });
+ }
+ });
+ } else {
+ this.detailTable?.toggleColumn({ prop: 'default', isHidden: false });
+ this.data = _.map(tempData, (value, key) => {
+ return {
+ displayName: key,
+ default: undefined,
+ current: this.format(value)
+ };
+ });
+ }
+ } else {
+ this.data = undefined;
+ }
+
+ this.detailTable?.updateColumns();
+ }
+
+ onUpdateData() {
+ this.tree.treeModel.expandAll();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html
new file mode 100644
index 000000000..d84ea787f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html
@@ -0,0 +1,132 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container class="modal-title"
+ i18n>Discovery Authentication</ng-container>
+
+ <ng-container class="modal-content">
+ <form name="discoveryForm"
+ #formDir="ngForm"
+ [formGroup]="discoveryForm"
+ novalidate>
+ <div class="modal-body">
+ <!-- User -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="user"
+ i18n>User</label>
+ <div class="cd-col-form-input">
+ <input id="user"
+ class="form-control"
+ formControlName="user"
+ type="text"
+ autocomplete="off">
+ <span class="invalid-feedback"
+ *ngIf="discoveryForm.showError('user', formDir, 'required')"
+ i18n>This field is required.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="discoveryForm.showError('user', formDir, 'pattern')"
+ i18n>User names must have a length of 8 to 64 characters and can contain
+ alphanumeric characters, '.', '@', '-', '_' or ':'.</span>
+ </div>
+ </div>
+
+ <!-- Password -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="password"
+ i18n>Password</label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input id="password"
+ class="form-control"
+ formControlName="password"
+ type="password"
+ autocomplete="new-password">
+
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="password">
+ </button>
+ <cd-copy-2-clipboard-button source="password">
+ </cd-copy-2-clipboard-button>
+ </span>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="discoveryForm.showError('password', formDir, 'required')"
+ i18n>This field is required.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="discoveryForm.showError('password', formDir, 'pattern')"
+ i18n>Passwords must have a length of 12 to 16 characters and can contain
+ alphanumeric characters, '@', '-', '_' or '/'.</span>
+ </div>
+ </div>
+
+ <!-- mutual_user -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="mutual_user">
+ <ng-container i18n>Mutual User</ng-container>
+ </label>
+ <div class="cd-col-form-input">
+ <input id="mutual_user"
+ class="form-control"
+ formControlName="mutual_user"
+ type="text"
+ autocomplete="off">
+
+ <span class="invalid-feedback"
+ *ngIf="discoveryForm.showError('mutual_user', formDir, 'required')"
+ i18n>This field is required.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="discoveryForm.showError('mutual_user', formDir, 'pattern')"
+ i18n>User names must have a length of 8 to 64 characters and can contain
+ alphanumeric characters, '.', '@', '-', '_' or ':'.</span>
+ </div>
+ </div>
+
+ <!-- mutual_password -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="mutual_password"
+ i18n>Mutual Password</label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input id="mutual_password"
+ class="form-control"
+ formControlName="mutual_password"
+ type="password"
+ autocomplete="new-password">
+
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="mutual_password">
+ </button>
+ <cd-copy-2-clipboard-button source="mutual_password">
+ </cd-copy-2-clipboard-button>
+ </span>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="discoveryForm.showError('mutual_password', formDir, 'required')"
+ i18n>This field is required.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="discoveryForm.showError('mutual_password', formDir, 'pattern')"
+ i18n>Passwords must have a length of 12 to 16 characters and can contain
+ alphanumeric characters, '@', '-', '_' or '/'.</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="submitAction()"
+ [form]="discoveryForm"
+ [showSubmit]="hasPermission"
+ [submitText]="actionLabels.SUBMIT"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.spec.ts
new file mode 100644
index 000000000..0f540f18e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.spec.ts
@@ -0,0 +1,133 @@
+import {
+ HttpClientTestingModule,
+ HttpTestingController,
+ TestRequest
+} from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { By } from '@angular/platform-browser';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+
+import { Permission } from '~/app/shared/models/permissions';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, FormHelper, IscsiHelper } from '~/testing/unit-test-helper';
+import { IscsiTargetDiscoveryModalComponent } from './iscsi-target-discovery-modal.component';
+
+describe('IscsiTargetDiscoveryModalComponent', () => {
+ let component: IscsiTargetDiscoveryModalComponent;
+ let fixture: ComponentFixture<IscsiTargetDiscoveryModalComponent>;
+ let httpTesting: HttpTestingController;
+ let req: TestRequest;
+
+ const elem = (css: string) => fixture.debugElement.query(By.css(css));
+ const elemDisabled = (css: string) => elem(css).nativeElement.disabled;
+
+ configureTestBed({
+ declarations: [IscsiTargetDiscoveryModalComponent],
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ SharedModule,
+ ToastrModule.forRoot(),
+ RouterTestingModule
+ ],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(IscsiTargetDiscoveryModalComponent);
+ component = fixture.componentInstance;
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ describe('with update permissions', () => {
+ beforeEach(() => {
+ component.permission = new Permission(['update']);
+ fixture.detectChanges();
+ req = httpTesting.expectOne('api/iscsi/discoveryauth');
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should create form', () => {
+ expect(component.discoveryForm.value).toEqual({
+ user: '',
+ password: '',
+ mutual_user: '',
+ mutual_password: ''
+ });
+ });
+
+ it('should patch form', () => {
+ req.flush({
+ user: 'foo',
+ password: 'bar',
+ mutual_user: 'mutual_foo',
+ mutual_password: 'mutual_bar'
+ });
+ expect(component.discoveryForm.value).toEqual({
+ user: 'foo',
+ password: 'bar',
+ mutual_user: 'mutual_foo',
+ mutual_password: 'mutual_bar'
+ });
+ });
+
+ it('should submit new values', () => {
+ component.discoveryForm.patchValue({
+ user: 'new_user',
+ password: 'new_pass',
+ mutual_user: 'mutual_new_user',
+ mutual_password: 'mutual_new_pass'
+ });
+ component.submitAction();
+
+ const submit_req = httpTesting.expectOne('api/iscsi/discoveryauth');
+ expect(submit_req.request.method).toBe('PUT');
+ expect(submit_req.request.body).toEqual({
+ user: 'new_user',
+ password: 'new_pass',
+ mutual_user: 'mutual_new_user',
+ mutual_password: 'mutual_new_pass'
+ });
+ });
+
+ it('should enable form if user has update permission', () => {
+ expect(elemDisabled('input#user')).toBeFalsy();
+ expect(elemDisabled('input#password')).toBeFalsy();
+ expect(elemDisabled('input#mutual_user')).toBeFalsy();
+ expect(elemDisabled('input#mutual_password')).toBeFalsy();
+ expect(elem('cd-submit-button')).toBeDefined();
+ });
+ });
+
+ it('should disabled form if user does not have update permission', () => {
+ component.permission = new Permission(['read', 'create', 'delete']);
+ fixture.detectChanges();
+ req = httpTesting.expectOne('api/iscsi/discoveryauth');
+
+ expect(elemDisabled('input#user')).toBeTruthy();
+ expect(elemDisabled('input#password')).toBeTruthy();
+ expect(elemDisabled('input#mutual_user')).toBeTruthy();
+ expect(elemDisabled('input#mutual_password')).toBeTruthy();
+ expect(elem('cd-submit-button')).toBeNull();
+ });
+
+ it('should validate authentication', () => {
+ component.permission = new Permission(['read', 'create', 'update', 'delete']);
+ fixture.detectChanges();
+ const control = component.discoveryForm;
+ const formHelper = new FormHelper(control);
+ formHelper.expectValid(control);
+
+ IscsiHelper.validateUser(formHelper, 'user');
+ IscsiHelper.validatePassword(formHelper, 'password');
+ IscsiHelper.validateUser(formHelper, 'mutual_user');
+ IscsiHelper.validatePassword(formHelper, 'mutual_password');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts
new file mode 100644
index 000000000..68958cfaa
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts
@@ -0,0 +1,123 @@
+import { Component, OnInit } from '@angular/core';
+import { FormControl, Validators } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+import { IscsiService } from '~/app/shared/api/iscsi.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+
+@Component({
+ selector: 'cd-iscsi-target-discovery-modal',
+ templateUrl: './iscsi-target-discovery-modal.component.html',
+ styleUrls: ['./iscsi-target-discovery-modal.component.scss']
+})
+export class IscsiTargetDiscoveryModalComponent implements OnInit {
+ discoveryForm: CdFormGroup;
+ permission: Permission;
+ hasPermission: boolean;
+
+ USER_REGEX = /^[\w\.:@_-]{8,64}$/;
+ PASSWORD_REGEX = /^[\w@\-_\/]{12,16}$/;
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n,
+ private iscsiService: IscsiService,
+ private notificationService: NotificationService
+ ) {
+ this.permission = this.authStorageService.getPermissions().iscsi;
+ }
+
+ ngOnInit() {
+ this.hasPermission = this.permission.update;
+ this.createForm();
+ this.iscsiService.getDiscovery().subscribe((auth) => {
+ this.discoveryForm.patchValue(auth);
+ });
+ }
+
+ createForm() {
+ this.discoveryForm = new CdFormGroup({
+ user: new FormControl({ value: '', disabled: !this.hasPermission }),
+ password: new FormControl({ value: '', disabled: !this.hasPermission }),
+ mutual_user: new FormControl({ value: '', disabled: !this.hasPermission }),
+ mutual_password: new FormControl({ value: '', disabled: !this.hasPermission })
+ });
+
+ CdValidators.validateIf(
+ this.discoveryForm.get('user'),
+ () =>
+ this.discoveryForm.getValue('password') ||
+ this.discoveryForm.getValue('mutual_user') ||
+ this.discoveryForm.getValue('mutual_password'),
+ [Validators.required],
+ [Validators.pattern(this.USER_REGEX)],
+ [
+ this.discoveryForm.get('password'),
+ this.discoveryForm.get('mutual_user'),
+ this.discoveryForm.get('mutual_password')
+ ]
+ );
+
+ CdValidators.validateIf(
+ this.discoveryForm.get('password'),
+ () =>
+ this.discoveryForm.getValue('user') ||
+ this.discoveryForm.getValue('mutual_user') ||
+ this.discoveryForm.getValue('mutual_password'),
+ [Validators.required],
+ [Validators.pattern(this.PASSWORD_REGEX)],
+ [
+ this.discoveryForm.get('user'),
+ this.discoveryForm.get('mutual_user'),
+ this.discoveryForm.get('mutual_password')
+ ]
+ );
+
+ CdValidators.validateIf(
+ this.discoveryForm.get('mutual_user'),
+ () => this.discoveryForm.getValue('mutual_password'),
+ [Validators.required],
+ [Validators.pattern(this.USER_REGEX)],
+ [
+ this.discoveryForm.get('user'),
+ this.discoveryForm.get('password'),
+ this.discoveryForm.get('mutual_password')
+ ]
+ );
+
+ CdValidators.validateIf(
+ this.discoveryForm.get('mutual_password'),
+ () => this.discoveryForm.getValue('mutual_user'),
+ [Validators.required],
+ [Validators.pattern(this.PASSWORD_REGEX)],
+ [
+ this.discoveryForm.get('user'),
+ this.discoveryForm.get('password'),
+ this.discoveryForm.get('mutual_user')
+ ]
+ );
+ }
+
+ submitAction() {
+ this.iscsiService.updateDiscovery(this.discoveryForm.value).subscribe(
+ () => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Updated discovery authentication`
+ );
+ this.activeModal.close();
+ },
+ () => {
+ this.discoveryForm.setErrors({ cdSubmitButton: true });
+ }
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html
new file mode 100644
index 000000000..852866a86
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html
@@ -0,0 +1,692 @@
+<div class="cd-col-form"
+ *cdFormLoading="loading">
+ <form name="targetForm"
+ #formDir="ngForm"
+ [formGroup]="targetForm"
+ novalidate>
+ <div class="card">
+ <div i18n="form title"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
+
+ <div class="card-body">
+ <!-- Target IQN -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="target_iqn"
+ i18n>Target IQN</label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input class="form-control"
+ type="text"
+ id="target_iqn"
+ name="target_iqn"
+ formControlName="target_iqn"
+ cdTrim />
+ <span class="input-group-append">
+ <button class="btn btn-light"
+ id="ecp-info-button"
+ type="button"
+ (click)="targetSettingsModal()">
+ <i [ngClass]="[icons.deepCheck]"
+ aria-hidden="true"></i>
+ </button>
+ </span>
+ </div>
+
+ <span class="invalid-feedback"
+ *ngIf="targetForm.showError('target_iqn', formDir, 'required')"
+ i18n>This field is required.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="targetForm.showError('target_iqn', formDir, 'pattern')"
+ i18n>IQN has wrong pattern.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="targetForm.showError('target_iqn', formDir, 'iqn')">
+ <ng-container i18n>An IQN has the following notation
+ 'iqn.$year-$month.$reversedAddress:$definedName'</ng-container>
+ <br>
+ <ng-container i18n>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</ng-container>
+ <br>
+ <a target="_blank"
+ href="https://en.wikipedia.org/wiki/ISCSI#Addressing"
+ i18n>More information</a>
+ </span>
+
+ <span class="form-text text-muted"
+ *ngIf="hasAdvancedSettings(targetForm.getValue('target_controls'))"
+ i18n>This target has modified advanced settings.</span>
+ <hr />
+ </div>
+ </div>
+
+ <!-- Portals -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="portals"
+ i18n>Portals</label>
+ <div class="cd-col-form-input">
+
+ <ng-container *ngFor="let portal of portals.value; let i = index">
+ <div class="input-group cd-mb">
+ <input class="cd-form-control"
+ type="text"
+ [value]="portal"
+ disabled />
+ <span class="input-group-append">
+ <button class="btn btn-light"
+ type="button"
+ (click)="removePortal(i, portal)">
+ <i [ngClass]="[icons.destroy]"
+ aria-hidden="true"></i>
+ </button>
+ </span>
+ </div>
+ </ng-container>
+
+ <div class="row">
+ <div class="col-md-12">
+ <cd-select [data]="portals.value"
+ [options]="portalsSelections"
+ [messages]="messages.portals"
+ (selection)="onPortalSelection($event)"
+ elemClass="btn btn-light float-right">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>Add portal</ng-container>
+ </cd-select>
+ </div>
+ </div>
+
+ <input class="form-control"
+ type="hidden"
+ id="portals"
+ name="portals"
+ formControlName="portals" />
+
+ <span class="invalid-feedback"
+ *ngIf="targetForm.showError('portals', formDir, 'minGateways')"
+ i18n>At least {{ minimum_gateways }} gateways are required.</span>
+
+ <hr />
+ </div>
+ </div>
+
+ <!-- Images -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="disks"
+ i18n>Images</label>
+ <div class="cd-col-form-input">
+ <ng-container *ngFor="let image of targetForm.getValue('disks'); let i = index">
+ <div class="input-group cd-mb">
+ <input class="cd-form-control"
+ type="text"
+ [value]="image"
+ disabled />
+ <span class="input-group-append">
+ <div class="input-group-text"
+ *ngIf="api_version >= 1">lun: {{ imagesSettings[image]['lun'] }}</div>
+ <button class="btn btn-light"
+ type="button"
+ (click)="imageSettingsModal(image)">
+ <i [ngClass]="[icons.deepCheck]"
+ aria-hidden="true"></i>
+ </button>
+ <button class="btn btn-light"
+ type="button"
+ (click)="removeImage(i, image)">
+ <i [ngClass]="[icons.destroy]"
+ aria-hidden="true"></i>
+ </button>
+ </span>
+
+ </div>
+
+ <span class="form-text text-muted">
+ <ng-container *ngIf="backstores.length > 1"
+ i18n>Backstore: {{ imagesSettings[image].backstore | iscsiBackstore }}.&nbsp;</ng-container>
+
+ <ng-container *ngIf="hasAdvancedSettings(imagesSettings[image][imagesSettings[image].backstore])"
+ i18n>This image has modified settings.</ng-container>
+ </span>
+ </ng-container>
+
+ <input class="form-control"
+ type="hidden"
+ id="disks"
+ name="disks"
+ formControlName="disks" />
+
+ <span class="invalid-feedback"
+ *ngIf="targetForm.showError('disks', formDir, 'dupLunId')"
+ i18n>Duplicated LUN numbers.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="targetForm.showError('disks', formDir, 'dupWwn')"
+ i18n>Duplicated WWN.</span>
+
+ <div class="row">
+ <div class="col-md-12">
+ <cd-select [data]="disks.value"
+ [options]="imagesSelections"
+ [messages]="messages.images"
+ (selection)="onImageSelection($event)"
+ elemClass="btn btn-light float-right">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>Add image</ng-container>
+ </cd-select>
+ </div>
+ </div>
+
+ <hr />
+ </div>
+ </div>
+
+ <!-- acl_enabled -->
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ formControlName="acl_enabled"
+ name="acl_enabled"
+ id="acl_enabled">
+ <label for="acl_enabled"
+ class="custom-control-label"
+ i18n>ACL authentication</label>
+ </div>
+
+ <hr />
+ </div>
+ </div>
+
+ <!-- Target level authentication was introduced in ceph-iscsi config v11 -->
+ <div formGroupName="auth"
+ *ngIf="cephIscsiConfigVersion > 10 && !targetForm.getValue('acl_enabled')">
+
+ <!-- Target user -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="target_user">
+ <ng-container i18n>User</ng-container>
+ </label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ autocomplete="off"
+ id="target_user"
+ name="target_user"
+ formControlName="user" />
+
+ <span class="invalid-feedback"
+ *ngIf="targetForm.showError('user', formDir, 'required')"
+ i18n>This field is required.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="targetForm.showError('user', formDir, 'pattern')"
+ i18n>User names must have a length of 8 to 64 characters and can contain
+ alphanumeric characters, '.', '@', '-', '_' or ':'.</span>
+ </div>
+ </div>
+
+ <!-- Target password -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="target_password">
+ <ng-container i18n>Password</ng-container>
+ </label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input class="form-control"
+ type="password"
+ autocomplete="new-password"
+ id="target_password"
+ name="target_password"
+ formControlName="password" />
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="target_password">
+ </button>
+ <cd-copy-2-clipboard-button source="target_password">
+ </cd-copy-2-clipboard-button>
+ </span>
+ </div>
+
+ <span class="invalid-feedback"
+ *ngIf="targetForm.showError('password', formDir, 'required')"
+ i18n>This field is required.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="targetForm.showError('password', formDir, 'pattern')"
+ i18n>Passwords must have a length of 12 to 16 characters and can contain
+ alphanumeric characters, '@', '-', '_' or '/'.</span>
+ </div>
+ </div>
+
+ <!-- Target mutual_user -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="target_mutual_user">
+ <ng-container i18n>Mutual User</ng-container>
+ </label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ autocomplete="off"
+ id="target_mutual_user"
+ name="target_mutual_user"
+ formControlName="mutual_user" />
+
+ <span class="invalid-feedback"
+ *ngIf="targetForm.showError('mutual_user', formDir, 'required')"
+ i18n>This field is required.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="targetForm.showError('mutual_user', formDir, 'pattern')"
+ i18n>User names must have a length of 8 to 64 characters and can contain
+ alphanumeric characters, '.', '@', '-', '_' or ':'.</span>
+ </div>
+ </div>
+
+ <!-- Target mutual_password -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="target_mutual_password">
+ <ng-container i18n>Mutual Password</ng-container>
+ </label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input class="form-control"
+ type="password"
+ autocomplete="new-password"
+ id="target_mutual_password"
+ name="target_mutual_password"
+ formControlName="mutual_password" />
+
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="target_mutual_password">
+ </button>
+ <cd-copy-2-clipboard-button source="target_mutual_password">
+ </cd-copy-2-clipboard-button>
+ </span>
+ </div>
+
+ <span class="invalid-feedback"
+ *ngIf="targetForm.showError('mutual_password', formDir, 'required')"
+ i18n>This field is required.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="targetForm.showError('mutual_password', formDir, 'pattern')"
+ i18n>Passwords must have a length of 12 to 16 characters and can contain
+ alphanumeric characters, '@', '-', '_' or '/'.</span>
+ </div>
+ </div>
+
+ </div>
+
+ <!-- Initiators -->
+ <div class="form-group row"
+ *ngIf="targetForm.getValue('acl_enabled')">
+ <label class="cd-col-form-label"
+ for="initiators"
+ i18n>Initiators</label>
+ <div class="cd-col-form-input"
+ formArrayName="initiators">
+ <div class="card mb-2"
+ *ngFor="let initiator of initiators.controls; let ii = index"
+ [formGroup]="initiator">
+ <div class="card-header">
+ <ng-container i18n>Initiator</ng-container>: {{ initiator.getValue('client_iqn') }}
+ <button type="button"
+ class="close"
+ (click)="removeInitiator(ii)">
+ <i [ngClass]="[icons.destroy]"></i>
+ </button>
+ </div>
+ <div class="card-body">
+ <!-- Initiator: Name -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="client_iqn"
+ i18n>Client IQN</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ formControlName="client_iqn"
+ cdTrim
+ (blur)="updatedInitiatorSelector()">
+
+ <span class="invalid-feedback"
+ *ngIf="initiator.showError('client_iqn', formDir, 'notUnique')"
+ i18n>Initiator IQN needs to be unique.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="initiator.showError('client_iqn', formDir, 'required')"
+ i18n>This field is required.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="initiator.showError('client_iqn', formDir, 'pattern')"
+ i18n>IQN has wrong pattern.</span>
+ </div>
+ </div>
+
+ <ng-container formGroupName="auth">
+ <!-- Initiator: User -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="user"
+ i18n>User</label>
+ <div class="cd-col-form-input">
+ <input [id]="'user' + ii"
+ class="form-control"
+ formControlName="user"
+ autocomplete="off"
+ type="text">
+ <span class="invalid-feedback"
+ *ngIf="initiator.showError('user', formDir, 'required')"
+ i18n>This field is required.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="initiator.showError('user', formDir, 'pattern')"
+ i18n>User names must have a length of 8 to 64 characters and can contain
+ alphanumeric characters, '.', '@', '-', '_' or ':'.</span>
+ </div>
+ </div>
+
+ <!-- Initiator: Password -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="password"
+ i18n>Password</label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input [id]="'password' + ii"
+ class="form-control"
+ formControlName="password"
+ autocomplete="new-password"
+ type="password">
+
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ [cdPasswordButton]="'password' + ii">
+ </button>
+ <cd-copy-2-clipboard-button [source]="'password' + ii">
+ </cd-copy-2-clipboard-button>
+ </span>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="initiator.showError('password', formDir, 'required')"
+ i18n>This field is required.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="initiator.showError('password', formDir, 'pattern')"
+ i18n>Passwords must have a length of 12 to 16 characters and can contain
+ alphanumeric characters, '@', '-', '_' or '/'.</span>
+ </div>
+ </div>
+
+
+ <!-- Initiator: mutual_user -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="mutual_user">
+ <ng-container i18n>Mutual User</ng-container>
+ </label>
+ <div class="cd-col-form-input">
+ <input [id]="'mutual_user' + ii"
+ class="form-control"
+ formControlName="mutual_user"
+ autocomplete="off"
+ type="text">
+
+ <span class="invalid-feedback"
+ *ngIf="initiator.showError('mutual_user', formDir, 'required')"
+ i18n>This field is required.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="initiator.showError('mutual_user', formDir, 'pattern')"
+ i18n>User names must have a length of 8 to 64 characters and can contain
+ alphanumeric characters, '.', '@', '-', '_' or ':'.</span>
+ </div>
+ </div>
+
+ <!-- Initiator: mutual_password -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="mutual_password"
+ i18n>Mutual Password</label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input [id]="'mutual_password' + ii"
+ class="form-control"
+ formControlName="mutual_password"
+ autocomplete="new-password"
+ type="password">
+
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ [cdPasswordButton]="'mutual_password' + ii">
+ </button>
+ <cd-copy-2-clipboard-button [source]="'mutual_password' + ii">
+ </cd-copy-2-clipboard-button>
+ </span>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="initiator.showError('mutual_password', formDir, 'required')"
+ i18n>This field is required.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="initiator.showError('mutual_password', formDir, 'pattern')"
+ i18n>Passwords must have a length of 12 to 16 characters and can contain
+ alphanumeric characters, '@', '-', '_' or '/'.</span>
+ </div>
+ </div>
+ </ng-container>
+
+ <!-- Initiator: Images -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="luns"
+ i18n>Images</label>
+ <div class="cd-col-form-input">
+ <ng-container *ngFor="let image of initiator.getValue('luns'); let li = index">
+ <div class="input-group cd-mb">
+ <input class="cd-form-control"
+ type="text"
+ [value]="image"
+ disabled />
+ <span class="input-group-append">
+ <button class="btn btn-light"
+ type="button"
+ (click)="removeInitiatorImage(initiator, li, ii, image)">
+ <i [ngClass]="[icons.destroy]"
+ aria-hidden="true"></i>
+ </button>
+ </span>
+ </div>
+ </ng-container>
+
+ <span *ngIf="initiator.getValue('cdIsInGroup')"
+ i18n>Initiator belongs to a group. Images will be configure in the group.</span>
+
+ <div class="row"
+ *ngIf="!initiator.getValue('cdIsInGroup')">
+ <div class="col-md-12">
+ <cd-select [data]="initiator.getValue('luns')"
+ [options]="imagesInitiatorSelections[ii]"
+ [messages]="messages.initiatorImage"
+ elemClass="btn btn-light float-right">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>Add image</ng-container>
+ </cd-select>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-12">
+ <span class="form-text text-muted"
+ *ngIf="initiators.controls.length === 0"
+ i18n>No items added.</span>
+
+ <button (click)="addInitiator(); false"
+ class="btn btn-light float-right">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>Add initiator</ng-container>
+ </button>
+ </div>
+ </div>
+
+ <hr />
+ </div>
+ </div>
+
+ <!-- Groups -->
+ <div class="form-group row"
+ *ngIf="targetForm.getValue('acl_enabled')">
+ <label class="cd-col-form-label"
+ for="initiators"
+ i18n>Groups</label>
+ <div class="cd-col-form-input"
+ formArrayName="groups">
+ <div class="card mb-2"
+ *ngFor="let group of groups.controls; let gi = index"
+ [formGroup]="group">
+ <div class="card-header">
+ <ng-container i18n>Group</ng-container>: {{ group.getValue('group_id') }}
+ <button type="button"
+ class="close"
+ (click)="removeGroup(gi)">
+ <i [ngClass]="[icons.destroy]"></i>
+ </button>
+ </div>
+ <div class="card-body">
+ <!-- Group: group_id -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="group_id"
+ i18n>Name</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ formControlName="group_id">
+ </div>
+ </div>
+
+ <!-- Group: members -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="members">
+ <ng-container i18n>Initiators</ng-container>
+ </label>
+ <div class="cd-col-form-input">
+ <ng-container *ngFor="let member of group.getValue('members'); let i = index">
+ <div class="input-group cd-mb">
+ <input class="cd-form-control"
+ type="text"
+ [value]="member"
+ disabled />
+ <span class="input-group-append">
+ <button class="btn btn-light"
+ type="button"
+ (click)="removeGroupInitiator(group, i, gi)">
+ <i [ngClass]="[icons.destroy]"
+ aria-hidden="true"></i>
+ </button>
+ </span>
+ </div>
+ </ng-container>
+
+ <div class="row">
+ <div class="col-md-12">
+ <cd-select [data]="group.getValue('members')"
+ [options]="groupMembersSelections[gi]"
+ [messages]="messages.groupInitiator"
+ (selection)="onGroupMemberSelection($event, gi)"
+ elemClass="btn btn-light float-right">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>Add initiator</ng-container>
+ </cd-select>
+ </div>
+ </div>
+
+ <hr />
+ </div>
+ </div>
+
+ <!-- Group: disks -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="disks">
+ <ng-container i18n>Images</ng-container>
+ </label>
+ <div class="cd-col-form-input">
+ <ng-container *ngFor="let disk of group.getValue('disks'); let i = index">
+ <div class="input-group cd-mb">
+ <input class="cd-form-control"
+ type="text"
+ [value]="disk"
+ disabled />
+ <span class="input-group-append">
+ <button class="btn btn-light"
+ type="button"
+ (click)="removeGroupDisk(group, i, gi)">
+ <i [ngClass]="[icons.destroy]"
+ aria-hidden="true"></i>
+ </button>
+ </span>
+ </div>
+ </ng-container>
+
+ <div class="row">
+ <div class="col-md-12">
+ <cd-select [data]="group.getValue('disks')"
+ [options]="groupDiskSelections[gi]"
+ [messages]="messages.initiatorImage"
+ elemClass="btn btn-light float-right">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>Add image</ng-container>
+ </cd-select>
+ </div>
+ </div>
+
+ <hr />
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-12">
+ <span class="form-text text-muted"
+ *ngIf="groups.controls.length === 0"
+ i18n>No items added.</span>
+
+ <button (click)="addGroup(); false"
+ class="btn btn-light float-right">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>Add group</ng-container>
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ <div class="card-footer">
+ <cd-form-button-panel (submitActionEvent)="submit()"
+ [form]="targetForm"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
+ wrappingClass="text-right"></cd-form-button-panel>
+ </div>
+ </div>
+ </form>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.scss
new file mode 100644
index 000000000..cebcc8877
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.scss
@@ -0,0 +1,3 @@
+.cd-mb {
+ margin-bottom: 10px;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.spec.ts
new file mode 100644
index 000000000..e993468c8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.spec.ts
@@ -0,0 +1,593 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { ActivatedRoute } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+
+import { LoadingPanelComponent } from '~/app/shared/components/loading-panel/loading-panel.component';
+import { SelectOption } from '~/app/shared/components/select/select-option.model';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { SharedModule } from '~/app/shared/shared.module';
+import { ActivatedRouteStub } from '~/testing/activated-route-stub';
+import { configureTestBed, FormHelper, IscsiHelper } from '~/testing/unit-test-helper';
+import { IscsiTargetFormComponent } from './iscsi-target-form.component';
+
+describe('IscsiTargetFormComponent', () => {
+ let component: IscsiTargetFormComponent;
+ let fixture: ComponentFixture<IscsiTargetFormComponent>;
+ let httpTesting: HttpTestingController;
+ let activatedRoute: ActivatedRouteStub;
+
+ const SETTINGS = {
+ config: { minimum_gateways: 2 },
+ disk_default_controls: {
+ 'backstore:1': {
+ hw_max_sectors: 1024,
+ osd_op_timeout: 30
+ },
+ 'backstore:2': {
+ qfull_timeout: 5
+ }
+ },
+ target_default_controls: {
+ cmdsn_depth: 128,
+ dataout_timeout: 20,
+ immediate_data: true
+ },
+ required_rbd_features: {
+ 'backstore:1': 0,
+ 'backstore:2': 0
+ },
+ unsupported_rbd_features: {
+ 'backstore:1': 0,
+ 'backstore:2': 0
+ },
+ backstores: ['backstore:1', 'backstore:2'],
+ default_backstore: 'backstore:1',
+ api_version: 1
+ };
+
+ const LIST_TARGET: any[] = [
+ {
+ target_iqn: 'iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw',
+ portals: [{ host: 'node1', ip: '192.168.100.201' }],
+ disks: [
+ {
+ pool: 'rbd',
+ image: 'disk_1',
+ controls: {},
+ backstore: 'backstore:1',
+ wwn: '64af6678-9694-4367-bacc-f8eb0baa'
+ }
+ ],
+ clients: [
+ {
+ client_iqn: 'iqn.1994-05.com.redhat:rh7-client',
+ luns: [{ pool: 'rbd', image: 'disk_1', lun: 0 }],
+ auth: {
+ user: 'myiscsiusername',
+ password: 'myiscsipassword',
+ mutual_user: null,
+ mutual_password: null
+ }
+ }
+ ],
+ groups: [],
+ target_controls: {}
+ }
+ ];
+
+ const PORTALS = [
+ { name: 'node1', ip_addresses: ['192.168.100.201', '10.0.2.15'] },
+ { name: 'node2', ip_addresses: ['192.168.100.202'] }
+ ];
+
+ const VERSION = {
+ ceph_iscsi_config_version: 11
+ };
+
+ const RBD_LIST: any[] = [
+ { value: [], pool_name: 'ganesha' },
+ {
+ value: [
+ {
+ size: 96636764160,
+ obj_size: 4194304,
+ num_objs: 23040,
+ order: 22,
+ block_name_prefix: 'rbd_data.148162fb31a8',
+ name: 'disk_1',
+ id: '148162fb31a8',
+ pool_name: 'rbd',
+ features: 61,
+ features_name: ['deep-flatten', 'exclusive-lock', 'fast-diff', 'layering', 'object-map'],
+ timestamp: '2019-01-18T10:44:26Z',
+ stripe_count: 1,
+ stripe_unit: 4194304,
+ data_pool: null,
+ parent: null,
+ snapshots: [],
+ total_disk_usage: 0,
+ disk_usage: 0
+ },
+ {
+ size: 119185342464,
+ obj_size: 4194304,
+ num_objs: 28416,
+ order: 22,
+ block_name_prefix: 'rbd_data.14b292cee6cb',
+ name: 'disk_2',
+ id: '14b292cee6cb',
+ pool_name: 'rbd',
+ features: 61,
+ features_name: ['deep-flatten', 'exclusive-lock', 'fast-diff', 'layering', 'object-map'],
+ timestamp: '2019-01-18T10:45:56Z',
+ stripe_count: 1,
+ stripe_unit: 4194304,
+ data_pool: null,
+ parent: null,
+ snapshots: [],
+ total_disk_usage: 0,
+ disk_usage: 0
+ }
+ ],
+ pool_name: 'rbd'
+ }
+ ];
+
+ configureTestBed(
+ {
+ declarations: [IscsiTargetFormComponent],
+ imports: [
+ SharedModule,
+ ReactiveFormsModule,
+ HttpClientTestingModule,
+ RouterTestingModule,
+ ToastrModule.forRoot()
+ ],
+ providers: [
+ {
+ provide: ActivatedRoute,
+ useValue: new ActivatedRouteStub({ target_iqn: undefined })
+ }
+ ]
+ },
+ [LoadingPanelComponent]
+ );
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(IscsiTargetFormComponent);
+ component = fixture.componentInstance;
+ httpTesting = TestBed.inject(HttpTestingController);
+ activatedRoute = <ActivatedRouteStub>TestBed.inject(ActivatedRoute);
+ fixture.detectChanges();
+
+ httpTesting.expectOne('ui-api/iscsi/settings').flush(SETTINGS);
+ httpTesting.expectOne('ui-api/iscsi/portals').flush(PORTALS);
+ httpTesting.expectOne('ui-api/iscsi/version').flush(VERSION);
+ httpTesting.expectOne('api/block/image?offset=0&limit=-1&search=&sort=+name').flush(RBD_LIST);
+ httpTesting.expectOne('api/iscsi/target').flush(LIST_TARGET);
+ httpTesting.verify();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should only show images not used in other targets', () => {
+ expect(component.imagesAll).toEqual([RBD_LIST[1]['value'][1]]);
+ expect(component.imagesSelections).toEqual([
+ { description: '', name: 'rbd/disk_2', selected: false, enabled: true }
+ ]);
+ });
+
+ it('should generate portals selectOptions', () => {
+ expect(component.portalsSelections).toEqual([
+ { description: '', name: 'node1:192.168.100.201', selected: false, enabled: true },
+ { description: '', name: 'node1:10.0.2.15', selected: false, enabled: true },
+ { description: '', name: 'node2:192.168.100.202', selected: false, enabled: true }
+ ]);
+ });
+
+ it('should create the form', () => {
+ expect(component.targetForm.value).toEqual({
+ disks: [],
+ groups: [],
+ initiators: [],
+ acl_enabled: false,
+ auth: {
+ password: '',
+ user: '',
+ mutual_password: '',
+ mutual_user: ''
+ },
+ portals: [],
+ target_controls: {},
+ target_iqn: component.targetForm.value.target_iqn
+ });
+ });
+
+ it('should prepare data when selecting an image', () => {
+ expect(component.imagesSettings).toEqual({});
+ component.onImageSelection({ option: { name: 'rbd/disk_2', selected: true } });
+ expect(component.imagesSettings).toEqual({
+ 'rbd/disk_2': {
+ lun: 0,
+ backstore: 'backstore:1',
+ 'backstore:1': {}
+ }
+ });
+ });
+
+ it('should clean data when removing an image', () => {
+ component.onImageSelection({ option: { name: 'rbd/disk_2', selected: true } });
+ component.addGroup();
+ component.groups.controls[0].patchValue({
+ group_id: 'foo',
+ disks: ['rbd/disk_2']
+ });
+
+ expect(component.groups.controls[0].value).toEqual({
+ disks: ['rbd/disk_2'],
+ group_id: 'foo',
+ members: []
+ });
+
+ component.onImageSelection({ option: { name: 'rbd/disk_2', selected: false } });
+
+ expect(component.groups.controls[0].value).toEqual({ disks: [], group_id: 'foo', members: [] });
+ expect(component.imagesSettings).toEqual({
+ 'rbd/disk_2': {
+ lun: 0,
+ backstore: 'backstore:1',
+ 'backstore:1': {}
+ }
+ });
+ });
+
+ it('should validate authentication', () => {
+ const control = component.targetForm;
+ const formHelper = new FormHelper(control as CdFormGroup);
+ formHelper.expectValid('auth');
+ validateAuth(formHelper);
+ });
+
+ describe('should test initiators', () => {
+ beforeEach(() => {
+ component.onImageSelection({ option: { name: 'rbd/disk_2', selected: true } });
+ component.targetForm.patchValue({ disks: ['rbd/disk_2'], acl_enabled: true });
+ component.addGroup().patchValue({ name: 'group_1' });
+ component.addGroup().patchValue({ name: 'group_2' });
+
+ component.addInitiator();
+ component.initiators.controls[0].patchValue({
+ client_iqn: 'iqn.initiator'
+ });
+ component.updatedInitiatorSelector();
+ });
+
+ it('should prepare data when creating an initiator', () => {
+ expect(component.initiators.controls.length).toBe(1);
+ expect(component.initiators.controls[0].value).toEqual({
+ auth: { mutual_password: '', mutual_user: '', password: '', user: '' },
+ cdIsInGroup: false,
+ client_iqn: 'iqn.initiator',
+ luns: []
+ });
+ expect(component.imagesInitiatorSelections).toEqual([
+ [{ description: '', name: 'rbd/disk_2', selected: false, enabled: true }]
+ ]);
+ expect(component.groupMembersSelections).toEqual([
+ [{ description: '', name: 'iqn.initiator', selected: false, enabled: true }],
+ [{ description: '', name: 'iqn.initiator', selected: false, enabled: true }]
+ ]);
+ });
+
+ it('should update data when changing an initiator name', () => {
+ expect(component.groupMembersSelections).toEqual([
+ [{ description: '', name: 'iqn.initiator', selected: false, enabled: true }],
+ [{ description: '', name: 'iqn.initiator', selected: false, enabled: true }]
+ ]);
+
+ component.initiators.controls[0].patchValue({
+ client_iqn: 'iqn.initiator_new'
+ });
+ component.updatedInitiatorSelector();
+
+ expect(component.groupMembersSelections).toEqual([
+ [{ description: '', name: 'iqn.initiator_new', selected: false, enabled: true }],
+ [{ description: '', name: 'iqn.initiator_new', selected: false, enabled: true }]
+ ]);
+ });
+
+ it('should clean data when removing an initiator', () => {
+ component.groups.controls[0].patchValue({
+ group_id: 'foo',
+ members: ['iqn.initiator']
+ });
+
+ expect(component.groups.controls[0].value).toEqual({
+ disks: [],
+ group_id: 'foo',
+ members: ['iqn.initiator']
+ });
+
+ component.removeInitiator(0);
+
+ expect(component.groups.controls[0].value).toEqual({
+ disks: [],
+ group_id: 'foo',
+ members: []
+ });
+ expect(component.groupMembersSelections).toEqual([[], []]);
+ expect(component.imagesInitiatorSelections).toEqual([]);
+ });
+
+ it('should remove images in the initiator when added in a group', () => {
+ component.initiators.controls[0].patchValue({
+ luns: ['rbd/disk_2']
+ });
+ component.imagesInitiatorSelections[0] = [
+ {
+ description: '',
+ enabled: true,
+ name: 'rbd/disk_2',
+ selected: true
+ }
+ ];
+ expect(component.initiators.controls[0].value).toEqual({
+ auth: { mutual_password: '', mutual_user: '', password: '', user: '' },
+ cdIsInGroup: false,
+ client_iqn: 'iqn.initiator',
+ luns: ['rbd/disk_2']
+ });
+
+ component.groups.controls[0].patchValue({
+ group_id: 'foo',
+ members: ['iqn.initiator']
+ });
+ component.onGroupMemberSelection(
+ {
+ option: {
+ name: 'iqn.initiator',
+ selected: true
+ }
+ },
+ 0
+ );
+
+ expect(component.initiators.controls[0].value).toEqual({
+ auth: { mutual_password: '', mutual_user: '', password: '', user: '' },
+ cdIsInGroup: true,
+ client_iqn: 'iqn.initiator',
+ luns: []
+ });
+ expect(component.imagesInitiatorSelections[0]).toEqual([
+ {
+ description: '',
+ enabled: true,
+ name: 'rbd/disk_2',
+ selected: false
+ }
+ ]);
+ });
+
+ it('should disabled the initiator when selected', () => {
+ expect(component.groupMembersSelections).toEqual([
+ [{ description: '', enabled: true, name: 'iqn.initiator', selected: false }],
+ [{ description: '', enabled: true, name: 'iqn.initiator', selected: false }]
+ ]);
+
+ component.groupMembersSelections[0][0].selected = true;
+ component.onGroupMemberSelection({ option: { name: 'iqn.initiator', selected: true } }, 0);
+
+ expect(component.groupMembersSelections).toEqual([
+ [{ description: '', enabled: false, name: 'iqn.initiator', selected: true }],
+ [{ description: '', enabled: false, name: 'iqn.initiator', selected: false }]
+ ]);
+ });
+
+ describe('should remove from group', () => {
+ beforeEach(() => {
+ component.onGroupMemberSelection(
+ { option: new SelectOption(true, 'iqn.initiator', '') },
+ 0
+ );
+ component.groupDiskSelections[0][0].selected = true;
+ component.groups.controls[0].patchValue({
+ disks: ['rbd/disk_2'],
+ members: ['iqn.initiator']
+ });
+
+ expect(component.initiators.value[0].luns).toEqual([]);
+ expect(component.imagesInitiatorSelections[0]).toEqual([
+ { description: '', enabled: true, name: 'rbd/disk_2', selected: false }
+ ]);
+ expect(component.initiators.value[0].cdIsInGroup).toBe(true);
+ });
+
+ it('should update initiator images when deselecting', () => {
+ component.onGroupMemberSelection(
+ { option: new SelectOption(false, 'iqn.initiator', '') },
+ 0
+ );
+
+ expect(component.initiators.value[0].luns).toEqual(['rbd/disk_2']);
+ expect(component.imagesInitiatorSelections[0]).toEqual([
+ { description: '', enabled: true, name: 'rbd/disk_2', selected: true }
+ ]);
+ expect(component.initiators.value[0].cdIsInGroup).toBe(false);
+ });
+
+ it('should update initiator when removing', () => {
+ component.removeGroupInitiator(component.groups.controls[0] as CdFormGroup, 0, 0);
+
+ expect(component.initiators.value[0].luns).toEqual(['rbd/disk_2']);
+ expect(component.imagesInitiatorSelections[0]).toEqual([
+ { description: '', enabled: true, name: 'rbd/disk_2', selected: true }
+ ]);
+ expect(component.initiators.value[0].cdIsInGroup).toBe(false);
+ });
+ });
+
+ it('should validate authentication', () => {
+ const control = component.initiators.controls[0];
+ const formHelper = new FormHelper(control as CdFormGroup);
+ formHelper.expectValid(control);
+ validateAuth(formHelper);
+ });
+ });
+
+ describe('should submit request', () => {
+ beforeEach(() => {
+ component.onImageSelection({ option: { name: 'rbd/disk_2', selected: true } });
+ component.targetForm.patchValue({ disks: ['rbd/disk_2'], acl_enabled: true });
+ component.portals.setValue(['node1:192.168.100.201', 'node2:192.168.100.202']);
+ component.addInitiator().patchValue({
+ client_iqn: 'iqn.initiator'
+ });
+ component.addGroup().patchValue({
+ group_id: 'foo',
+ members: ['iqn.initiator'],
+ disks: ['rbd/disk_2']
+ });
+ });
+
+ it('should call update', () => {
+ activatedRoute.setParams({ target_iqn: 'iqn.iscsi' });
+ component.isEdit = true;
+ component.target_iqn = 'iqn.iscsi';
+
+ component.submit();
+
+ const req = httpTesting.expectOne('api/iscsi/target/iqn.iscsi');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({
+ clients: [
+ {
+ auth: { mutual_password: '', mutual_user: '', password: '', user: '' },
+ client_iqn: 'iqn.initiator',
+ luns: []
+ }
+ ],
+ disks: [
+ {
+ backstore: 'backstore:1',
+ controls: {},
+ image: 'disk_2',
+ pool: 'rbd',
+ lun: 0,
+ wwn: undefined
+ }
+ ],
+ groups: [
+ { disks: [{ image: 'disk_2', pool: 'rbd' }], group_id: 'foo', members: ['iqn.initiator'] }
+ ],
+ new_target_iqn: component.targetForm.value.target_iqn,
+ portals: [
+ { host: 'node1', ip: '192.168.100.201' },
+ { host: 'node2', ip: '192.168.100.202' }
+ ],
+ target_controls: {},
+ target_iqn: component.target_iqn,
+ acl_enabled: true,
+ auth: {
+ password: '',
+ user: '',
+ mutual_password: '',
+ mutual_user: ''
+ }
+ });
+ });
+
+ it('should call create', () => {
+ component.submit();
+
+ const req = httpTesting.expectOne('api/iscsi/target');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual({
+ clients: [
+ {
+ auth: { mutual_password: '', mutual_user: '', password: '', user: '' },
+ client_iqn: 'iqn.initiator',
+ luns: []
+ }
+ ],
+ disks: [
+ {
+ backstore: 'backstore:1',
+ controls: {},
+ image: 'disk_2',
+ pool: 'rbd',
+ lun: 0,
+ wwn: undefined
+ }
+ ],
+ groups: [
+ {
+ disks: [{ image: 'disk_2', pool: 'rbd' }],
+ group_id: 'foo',
+ members: ['iqn.initiator']
+ }
+ ],
+ portals: [
+ { host: 'node1', ip: '192.168.100.201' },
+ { host: 'node2', ip: '192.168.100.202' }
+ ],
+ target_controls: {},
+ target_iqn: component.targetForm.value.target_iqn,
+ acl_enabled: true,
+ auth: {
+ password: '',
+ user: '',
+ mutual_password: '',
+ mutual_user: ''
+ }
+ });
+ });
+
+ it('should call create with acl_enabled disabled', () => {
+ component.targetForm.patchValue({ acl_enabled: false });
+ component.submit();
+
+ const req = httpTesting.expectOne('api/iscsi/target');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual({
+ clients: [],
+ disks: [
+ {
+ backstore: 'backstore:1',
+ controls: {},
+ image: 'disk_2',
+ pool: 'rbd',
+ lun: 0,
+ wwn: undefined
+ }
+ ],
+ groups: [],
+ acl_enabled: false,
+ auth: {
+ password: '',
+ user: '',
+ mutual_password: '',
+ mutual_user: ''
+ },
+ portals: [
+ { host: 'node1', ip: '192.168.100.201' },
+ { host: 'node2', ip: '192.168.100.202' }
+ ],
+ target_controls: {},
+ target_iqn: component.targetForm.value.target_iqn
+ });
+ });
+ });
+
+ function validateAuth(formHelper: FormHelper) {
+ IscsiHelper.validateUser(formHelper, 'auth.user');
+ IscsiHelper.validatePassword(formHelper, 'auth.password');
+ IscsiHelper.validateUser(formHelper, 'auth.mutual_user');
+ IscsiHelper.validatePassword(formHelper, 'auth.mutual_password');
+ }
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts
new file mode 100644
index 000000000..6704b41e6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts
@@ -0,0 +1,822 @@
+import { Component, OnInit } from '@angular/core';
+import { FormArray, FormControl, Validators } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { forkJoin } from 'rxjs';
+
+import { IscsiService } from '~/app/shared/api/iscsi.service';
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { SelectMessages } from '~/app/shared/components/select/select-messages.model';
+import { SelectOption } from '~/app/shared/components/select/select-option.model';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdForm } from '~/app/shared/forms/cd-form';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { IscsiTargetImageSettingsModalComponent } from '../iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component';
+import { IscsiTargetIqnSettingsModalComponent } from '../iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component';
+
+@Component({
+ selector: 'cd-iscsi-target-form',
+ templateUrl: './iscsi-target-form.component.html',
+ styleUrls: ['./iscsi-target-form.component.scss']
+})
+export class IscsiTargetFormComponent extends CdForm implements OnInit {
+ cephIscsiConfigVersion: number;
+ targetForm: CdFormGroup;
+ modalRef: NgbModalRef;
+ api_version = 0;
+ minimum_gateways = 1;
+ target_default_controls: any;
+ target_controls_limits: any;
+ disk_default_controls: any;
+ disk_controls_limits: any;
+ backstores: string[];
+ default_backstore: string;
+ unsupported_rbd_features: any;
+ required_rbd_features: any;
+
+ icons = Icons;
+
+ isEdit = false;
+ target_iqn: string;
+
+ imagesAll: any[];
+ imagesSelections: SelectOption[];
+ portalsSelections: SelectOption[] = [];
+
+ imagesInitiatorSelections: SelectOption[][] = [];
+ groupDiskSelections: SelectOption[][] = [];
+ groupMembersSelections: SelectOption[][] = [];
+
+ imagesSettings: any = {};
+ messages = {
+ portals: new SelectMessages({ noOptions: $localize`There are no portals available.` }),
+ images: new SelectMessages({ noOptions: $localize`There are no images available.` }),
+ initiatorImage: new SelectMessages({
+ noOptions: $localize`There are no images available. Please make sure you add an image to the target.`
+ }),
+ groupInitiator: new SelectMessages({
+ noOptions: $localize`There are no initiators available. Please make sure you add an initiator to the target.`
+ })
+ };
+
+ IQN_REGEX = /^iqn\.(19|20)\d\d-(0[1-9]|1[0-2])\.\D{2,3}(\.[A-Za-z0-9-]+)+(:[A-Za-z0-9-\.]+)*$/;
+ USER_REGEX = /^[\w\.:@_-]{8,64}$/;
+ PASSWORD_REGEX = /^[\w@\-_\/]{12,16}$/;
+ action: string;
+ resource: string;
+
+ constructor(
+ private iscsiService: IscsiService,
+ private modalService: ModalService,
+ private rbdService: RbdService,
+ private router: Router,
+ private route: ActivatedRoute,
+ private taskWrapper: TaskWrapperService,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ super();
+ this.resource = $localize`target`;
+ }
+
+ ngOnInit() {
+ const rbdListContext = new CdTableFetchDataContext(() => undefined);
+ /* limit -1 to specify all images */
+ rbdListContext.pageInfo.limit = -1;
+ const promises: any[] = [
+ this.iscsiService.listTargets(),
+ /* tslint:disable:no-empty */
+ this.rbdService.list(rbdListContext.toParams()),
+ this.iscsiService.portals(),
+ this.iscsiService.settings(),
+ this.iscsiService.version()
+ ];
+
+ if (this.router.url.startsWith('/block/iscsi/targets/edit')) {
+ this.isEdit = true;
+ this.route.params.subscribe((params: { target_iqn: string }) => {
+ this.target_iqn = decodeURIComponent(params.target_iqn);
+ promises.push(this.iscsiService.getTarget(this.target_iqn));
+ });
+ }
+ this.action = this.isEdit ? this.actionLabels.EDIT : this.actionLabels.CREATE;
+
+ forkJoin(promises).subscribe((data: any[]) => {
+ // iscsiService.listTargets
+ const usedImages = _(data[0])
+ .filter((target) => target.target_iqn !== this.target_iqn)
+ .flatMap((target) => target.disks)
+ .map((image) => `${image.pool}/${image.image}`)
+ .value();
+
+ // iscsiService.settings()
+ if ('api_version' in data[3]) {
+ this.api_version = data[3].api_version;
+ }
+ this.minimum_gateways = data[3].config.minimum_gateways;
+ this.target_default_controls = data[3].target_default_controls;
+ this.target_controls_limits = data[3].target_controls_limits;
+ this.disk_default_controls = data[3].disk_default_controls;
+ this.disk_controls_limits = data[3].disk_controls_limits;
+ this.backstores = data[3].backstores;
+ this.default_backstore = data[3].default_backstore;
+ this.unsupported_rbd_features = data[3].unsupported_rbd_features;
+ this.required_rbd_features = data[3].required_rbd_features;
+
+ // rbdService.list()
+ this.imagesAll = _(data[1])
+ .flatMap((pool) => pool.value)
+ .filter((image) => {
+ // Namespaces are not supported by ceph-iscsi
+ if (image.namespace) {
+ return false;
+ }
+ const imageId = `${image.pool_name}/${image.name}`;
+ if (usedImages.indexOf(imageId) !== -1) {
+ return false;
+ }
+ const validBackstores = this.getValidBackstores(image);
+ if (validBackstores.length === 0) {
+ return false;
+ }
+ return true;
+ })
+ .value();
+
+ this.imagesSelections = this.imagesAll.map(
+ (image) => new SelectOption(false, `${image.pool_name}/${image.name}`, '')
+ );
+
+ // iscsiService.portals()
+ const portals: SelectOption[] = [];
+ data[2].forEach((portal: Record<string, any>) => {
+ portal.ip_addresses.forEach((ip: string) => {
+ portals.push(new SelectOption(false, portal.name + ':' + ip, ''));
+ });
+ });
+ this.portalsSelections = [...portals];
+
+ // iscsiService.version()
+ this.cephIscsiConfigVersion = data[4]['ceph_iscsi_config_version'];
+
+ this.createForm();
+
+ // iscsiService.getTarget()
+ if (data[5]) {
+ this.resolveModel(data[5]);
+ }
+
+ this.loadingReady();
+ });
+ }
+
+ createForm() {
+ this.targetForm = new CdFormGroup({
+ target_iqn: new FormControl('iqn.2001-07.com.ceph:' + Date.now(), {
+ validators: [Validators.required, Validators.pattern(this.IQN_REGEX)]
+ }),
+ target_controls: new FormControl({}),
+ portals: new FormControl([], {
+ validators: [
+ CdValidators.custom('minGateways', (value: any[]) => {
+ const gateways = _.uniq(value.map((elem) => elem.split(':')[0]));
+ return gateways.length < Math.max(1, this.minimum_gateways);
+ })
+ ]
+ }),
+ disks: new FormControl([], {
+ validators: [
+ CdValidators.custom('dupLunId', (value: any[]) => {
+ const lunIds = this.getLunIds(value);
+ return lunIds.length !== _.uniq(lunIds).length;
+ }),
+ CdValidators.custom('dupWwn', (value: any[]) => {
+ const wwns = this.getWwns(value);
+ return wwns.length !== _.uniq(wwns).length;
+ })
+ ]
+ }),
+ initiators: new FormArray([]),
+ groups: new FormArray([]),
+ acl_enabled: new FormControl(false)
+ });
+ // Target level authentication was introduced in ceph-iscsi config v11
+ if (this.cephIscsiConfigVersion > 10) {
+ const authFormGroup = new CdFormGroup({
+ user: new FormControl(''),
+ password: new FormControl(''),
+ mutual_user: new FormControl(''),
+ mutual_password: new FormControl('')
+ });
+ this.setAuthValidator(authFormGroup);
+ this.targetForm.addControl('auth', authFormGroup);
+ }
+ }
+
+ resolveModel(res: Record<string, any>) {
+ this.targetForm.patchValue({
+ target_iqn: res.target_iqn,
+ target_controls: res.target_controls,
+ acl_enabled: res.acl_enabled
+ });
+ // Target level authentication was introduced in ceph-iscsi config v11
+ if (this.cephIscsiConfigVersion > 10) {
+ this.targetForm.patchValue({
+ auth: res.auth
+ });
+ }
+ const portals: any[] = [];
+ _.forEach(res.portals, (portal) => {
+ const id = `${portal.host}:${portal.ip}`;
+ portals.push(id);
+ });
+ this.targetForm.patchValue({
+ portals: portals
+ });
+
+ const disks: any[] = [];
+ _.forEach(res.disks, (disk) => {
+ const id = `${disk.pool}/${disk.image}`;
+ disks.push(id);
+ this.imagesSettings[id] = {
+ backstore: disk.backstore
+ };
+ this.imagesSettings[id][disk.backstore] = disk.controls;
+ if ('lun' in disk) {
+ this.imagesSettings[id]['lun'] = disk.lun;
+ }
+ if ('wwn' in disk) {
+ this.imagesSettings[id]['wwn'] = disk.wwn;
+ }
+
+ this.onImageSelection({ option: { name: id, selected: true } });
+ });
+ this.targetForm.patchValue({
+ disks: disks
+ });
+
+ _.forEach(res.clients, (client) => {
+ const initiator = this.addInitiator();
+ client.luns = _.map(client.luns, (lun) => `${lun.pool}/${lun.image}`);
+ initiator.patchValue(client);
+ // updatedInitiatorSelector()
+ });
+
+ (res.groups as any[]).forEach((group: any, group_index: number) => {
+ const fg = this.addGroup();
+ group.disks = _.map(group.disks, (disk) => `${disk.pool}/${disk.image}`);
+ fg.patchValue(group);
+ _.forEach(group.members, (member) => {
+ this.onGroupMemberSelection({ option: new SelectOption(true, member, '') }, group_index);
+ });
+ });
+ }
+
+ hasAdvancedSettings(settings: any) {
+ return Object.values(settings).length > 0;
+ }
+
+ // Portals
+ get portals() {
+ return this.targetForm.get('portals') as FormControl;
+ }
+
+ onPortalSelection() {
+ this.portals.setValue(this.portals.value);
+ }
+
+ removePortal(index: number, portal: string) {
+ this.portalsSelections.forEach((value) => {
+ if (value.name === portal) {
+ value.selected = false;
+ }
+ });
+
+ this.portals.value.splice(index, 1);
+ this.portals.setValue(this.portals.value);
+ return false;
+ }
+
+ // Images
+ get disks() {
+ return this.targetForm.get('disks') as FormControl;
+ }
+
+ removeImage(index: number, image: string) {
+ this.imagesSelections.forEach((value) => {
+ if (value.name === image) {
+ value.selected = false;
+ }
+ });
+ this.disks.value.splice(index, 1);
+ this.removeImageRefs(image);
+ this.targetForm.get('disks').updateValueAndValidity({ emitEvent: false });
+ return false;
+ }
+
+ removeImageRefs(name: string) {
+ this.initiators.controls.forEach((element) => {
+ const newImages = element.value.luns.filter((item: string) => item !== name);
+ element.get('luns').setValue(newImages);
+ });
+
+ this.groups.controls.forEach((element) => {
+ const newDisks = element.value.disks.filter((item: string) => item !== name);
+ element.get('disks').setValue(newDisks);
+ });
+
+ _.forEach(this.imagesInitiatorSelections, (selections, i) => {
+ this.imagesInitiatorSelections[i] = selections.filter((item: any) => item.name !== name);
+ });
+ _.forEach(this.groupDiskSelections, (selections, i) => {
+ this.groupDiskSelections[i] = selections.filter((item: any) => item.name !== name);
+ });
+ }
+
+ getDefaultBackstore(imageId: string) {
+ let result = this.default_backstore;
+ const image = this.getImageById(imageId);
+ if (!this.validFeatures(image, this.default_backstore)) {
+ this.backstores.forEach((backstore) => {
+ if (backstore !== this.default_backstore) {
+ if (this.validFeatures(image, backstore)) {
+ result = backstore;
+ }
+ }
+ });
+ }
+ return result;
+ }
+
+ isLunIdInUse(lunId: string, imageId: string) {
+ const images = this.disks.value.filter((currentImageId: string) => currentImageId !== imageId);
+ return this.getLunIds(images).includes(lunId);
+ }
+
+ getLunIds(images: object) {
+ return _.map(images, (image) => this.imagesSettings[image]['lun']);
+ }
+
+ nextLunId(imageId: string) {
+ const images = this.disks.value.filter((currentImageId: string) => currentImageId !== imageId);
+ const lunIdsInUse = this.getLunIds(images);
+ let lunIdCandidate = 0;
+ while (lunIdsInUse.includes(lunIdCandidate)) {
+ lunIdCandidate++;
+ }
+ return lunIdCandidate;
+ }
+
+ getWwns(images: object) {
+ const wwns = _.map(images, (image) => this.imagesSettings[image]['wwn']);
+ return wwns.filter((wwn) => _.isString(wwn) && wwn !== '');
+ }
+
+ onImageSelection($event: any) {
+ const option = $event.option;
+
+ if (option.selected) {
+ if (!this.imagesSettings[option.name]) {
+ const defaultBackstore = this.getDefaultBackstore(option.name);
+ this.imagesSettings[option.name] = {
+ backstore: defaultBackstore,
+ lun: this.nextLunId(option.name)
+ };
+ this.imagesSettings[option.name][defaultBackstore] = {};
+ } else if (this.isLunIdInUse(this.imagesSettings[option.name]['lun'], option.name)) {
+ // If the lun id is now in use, we have to generate a new one
+ this.imagesSettings[option.name]['lun'] = this.nextLunId(option.name);
+ }
+
+ _.forEach(this.imagesInitiatorSelections, (selections, i) => {
+ selections.push(new SelectOption(false, option.name, ''));
+ this.imagesInitiatorSelections[i] = [...selections];
+ });
+
+ _.forEach(this.groupDiskSelections, (selections, i) => {
+ selections.push(new SelectOption(false, option.name, ''));
+ this.groupDiskSelections[i] = [...selections];
+ });
+ } else {
+ this.removeImageRefs(option.name);
+ }
+ this.targetForm.get('disks').updateValueAndValidity({ emitEvent: false });
+ }
+
+ // Initiators
+ get initiators() {
+ return this.targetForm.get('initiators') as FormArray;
+ }
+
+ addInitiator() {
+ const fg = new CdFormGroup({
+ client_iqn: new FormControl('', {
+ validators: [
+ Validators.required,
+ CdValidators.custom('notUnique', (client_iqn: string) => {
+ const flattened = this.initiators.controls.reduce(function (accumulator, currentValue) {
+ return accumulator.concat(currentValue.value.client_iqn);
+ }, []);
+
+ return flattened.indexOf(client_iqn) !== flattened.lastIndexOf(client_iqn);
+ }),
+ Validators.pattern(this.IQN_REGEX)
+ ]
+ }),
+ auth: new CdFormGroup({
+ user: new FormControl(''),
+ password: new FormControl(''),
+ mutual_user: new FormControl(''),
+ mutual_password: new FormControl('')
+ }),
+ luns: new FormControl([]),
+ cdIsInGroup: new FormControl(false)
+ });
+
+ this.setAuthValidator(fg);
+
+ this.initiators.push(fg);
+
+ _.forEach(this.groupMembersSelections, (selections, i) => {
+ selections.push(new SelectOption(false, '', ''));
+ this.groupMembersSelections[i] = [...selections];
+ });
+
+ const disks = _.map(
+ this.targetForm.getValue('disks'),
+ (disk) => new SelectOption(false, disk, '')
+ );
+ this.imagesInitiatorSelections.push(disks);
+
+ return fg;
+ }
+
+ setAuthValidator(fg: CdFormGroup) {
+ CdValidators.validateIf(
+ fg.get('user'),
+ () => fg.getValue('password') || fg.getValue('mutual_user') || fg.getValue('mutual_password'),
+ [Validators.required],
+ [Validators.pattern(this.USER_REGEX)],
+ [fg.get('password'), fg.get('mutual_user'), fg.get('mutual_password')]
+ );
+
+ CdValidators.validateIf(
+ fg.get('password'),
+ () => fg.getValue('user') || fg.getValue('mutual_user') || fg.getValue('mutual_password'),
+ [Validators.required],
+ [Validators.pattern(this.PASSWORD_REGEX)],
+ [fg.get('user'), fg.get('mutual_user'), fg.get('mutual_password')]
+ );
+
+ CdValidators.validateIf(
+ fg.get('mutual_user'),
+ () => fg.getValue('mutual_password'),
+ [Validators.required],
+ [Validators.pattern(this.USER_REGEX)],
+ [fg.get('user'), fg.get('password'), fg.get('mutual_password')]
+ );
+
+ CdValidators.validateIf(
+ fg.get('mutual_password'),
+ () => fg.getValue('mutual_user'),
+ [Validators.required],
+ [Validators.pattern(this.PASSWORD_REGEX)],
+ [fg.get('user'), fg.get('password'), fg.get('mutual_user')]
+ );
+ }
+
+ removeInitiator(index: number) {
+ const removed = this.initiators.value[index];
+
+ this.initiators.removeAt(index);
+
+ _.forEach(this.groupMembersSelections, (selections, i) => {
+ selections.splice(index, 1);
+ this.groupMembersSelections[i] = [...selections];
+ });
+
+ this.groups.controls.forEach((element) => {
+ const newMembers = element.value.members.filter(
+ (item: string) => item !== removed.client_iqn
+ );
+ element.get('members').setValue(newMembers);
+ });
+
+ this.imagesInitiatorSelections.splice(index, 1);
+ }
+
+ updatedInitiatorSelector() {
+ // Validate all client_iqn
+ this.initiators.controls.forEach((control) => {
+ control.get('client_iqn').updateValueAndValidity({ emitEvent: false });
+ });
+
+ // Update Group Initiator Selector
+ _.forEach(this.groupMembersSelections, (group, group_index) => {
+ _.forEach(group, (elem, index) => {
+ const oldName = elem.name;
+ elem.name = this.initiators.controls[index].value.client_iqn;
+
+ this.groups.controls.forEach((element) => {
+ const members = element.value.members;
+ const i = members.indexOf(oldName);
+
+ if (i !== -1) {
+ members[i] = elem.name;
+ }
+ element.get('members').setValue(members);
+ });
+ });
+ this.groupMembersSelections[group_index] = [...this.groupMembersSelections[group_index]];
+ });
+ }
+
+ removeInitiatorImage(initiator: any, lun_index: number, initiator_index: number, image: string) {
+ const luns = initiator.getValue('luns');
+ luns.splice(lun_index, 1);
+ initiator.patchValue({ luns: luns });
+
+ this.imagesInitiatorSelections[initiator_index].forEach((value: Record<string, any>) => {
+ if (value.name === image) {
+ value.selected = false;
+ }
+ });
+
+ return false;
+ }
+
+ // Groups
+ get groups() {
+ return this.targetForm.get('groups') as FormArray;
+ }
+
+ addGroup() {
+ const fg = new CdFormGroup({
+ group_id: new FormControl('', { validators: [Validators.required] }),
+ members: new FormControl([]),
+ disks: new FormControl([])
+ });
+
+ this.groups.push(fg);
+
+ const disks = _.map(
+ this.targetForm.getValue('disks'),
+ (disk) => new SelectOption(false, disk, '')
+ );
+ this.groupDiskSelections.push(disks);
+
+ const initiators = _.map(
+ this.initiators.value,
+ (initiator) => new SelectOption(false, initiator.client_iqn, '', !initiator.cdIsInGroup)
+ );
+ this.groupMembersSelections.push(initiators);
+
+ return fg;
+ }
+
+ removeGroup(index: number) {
+ // Remove group and disk selections
+ this.groups.removeAt(index);
+
+ // Free initiator from group
+ const selectedMembers = this.groupMembersSelections[index].filter((value) => value.selected);
+ selectedMembers.forEach((selection) => {
+ selection.selected = false;
+ this.onGroupMemberSelection({ option: selection }, index);
+ });
+
+ this.groupMembersSelections.splice(index, 1);
+ this.groupDiskSelections.splice(index, 1);
+ }
+
+ onGroupMemberSelection($event: any, group_index: number) {
+ const option = $event.option;
+
+ let luns: string[] = [];
+ if (!option.selected) {
+ const selectedDisks = this.groupDiskSelections[group_index].filter((value) => value.selected);
+ luns = selectedDisks.map((value) => value.name);
+ }
+
+ this.initiators.controls.forEach((element, index) => {
+ if (element.value.client_iqn === option.name) {
+ element.patchValue({ luns: luns });
+ element.get('cdIsInGroup').setValue(option.selected);
+
+ // Members can only be at one group at a time, so when a member is selected
+ // in one group we need to disable its selection in other groups
+ _.forEach(this.groupMembersSelections, (group) => {
+ group[index].enabled = !option.selected;
+ });
+
+ this.imagesInitiatorSelections[index].forEach((image) => {
+ image.selected = luns.includes(image.name);
+ });
+ }
+ });
+ }
+
+ removeGroupInitiator(group: CdFormGroup, member_index: number, group_index: number) {
+ const name = group.getValue('members')[member_index];
+ group.getValue('members').splice(member_index, 1);
+
+ this.onGroupMemberSelection({ option: new SelectOption(false, name, '') }, group_index);
+ }
+
+ removeGroupDisk(group: CdFormGroup, disk_index: number, group_index: number) {
+ const name = group.getValue('disks')[disk_index];
+ group.getValue('disks').splice(disk_index, 1);
+
+ this.groupDiskSelections[group_index].forEach((value) => {
+ if (value.name === name) {
+ value.selected = false;
+ }
+ });
+ this.groupDiskSelections[group_index] = [...this.groupDiskSelections[group_index]];
+ }
+
+ submit() {
+ const formValue = _.cloneDeep(this.targetForm.value);
+
+ const request: Record<string, any> = {
+ target_iqn: this.targetForm.getValue('target_iqn'),
+ target_controls: this.targetForm.getValue('target_controls'),
+ acl_enabled: this.targetForm.getValue('acl_enabled'),
+ portals: [],
+ disks: [],
+ clients: [],
+ groups: []
+ };
+
+ // Target level authentication was introduced in ceph-iscsi config v11
+ if (this.cephIscsiConfigVersion > 10) {
+ const targetAuth: CdFormGroup = this.targetForm.get('auth') as CdFormGroup;
+ if (!targetAuth.getValue('user')) {
+ targetAuth.get('user').setValue('');
+ }
+ if (!targetAuth.getValue('password')) {
+ targetAuth.get('password').setValue('');
+ }
+ if (!targetAuth.getValue('mutual_user')) {
+ targetAuth.get('mutual_user').setValue('');
+ }
+ if (!targetAuth.getValue('mutual_password')) {
+ targetAuth.get('mutual_password').setValue('');
+ }
+ const acl_enabled = this.targetForm.getValue('acl_enabled');
+ request['auth'] = {
+ user: acl_enabled ? '' : targetAuth.getValue('user'),
+ password: acl_enabled ? '' : targetAuth.getValue('password'),
+ mutual_user: acl_enabled ? '' : targetAuth.getValue('mutual_user'),
+ mutual_password: acl_enabled ? '' : targetAuth.getValue('mutual_password')
+ };
+ }
+
+ // Disks
+ formValue.disks.forEach((disk: string) => {
+ const imageSplit = disk.split('/');
+ const backstore = this.imagesSettings[disk].backstore;
+ request.disks.push({
+ pool: imageSplit[0],
+ image: imageSplit[1],
+ backstore: backstore,
+ controls: this.imagesSettings[disk][backstore],
+ lun: this.imagesSettings[disk]['lun'],
+ wwn: this.imagesSettings[disk]['wwn']
+ });
+ });
+
+ // Portals
+ formValue.portals.forEach((portal: string) => {
+ const index = portal.indexOf(':');
+ request.portals.push({
+ host: portal.substring(0, index),
+ ip: portal.substring(index + 1)
+ });
+ });
+
+ // Clients
+ if (request.acl_enabled) {
+ formValue.initiators.forEach((initiator: Record<string, any>) => {
+ if (!initiator.auth.user) {
+ initiator.auth.user = '';
+ }
+ if (!initiator.auth.password) {
+ initiator.auth.password = '';
+ }
+ if (!initiator.auth.mutual_user) {
+ initiator.auth.mutual_user = '';
+ }
+ if (!initiator.auth.mutual_password) {
+ initiator.auth.mutual_password = '';
+ }
+ delete initiator.cdIsInGroup;
+
+ const newLuns: any[] = [];
+ initiator.luns.forEach((lun: string) => {
+ const imageSplit = lun.split('/');
+ newLuns.push({
+ pool: imageSplit[0],
+ image: imageSplit[1]
+ });
+ });
+
+ initiator.luns = newLuns;
+ });
+ request.clients = formValue.initiators;
+ }
+
+ // Groups
+ if (request.acl_enabled) {
+ formValue.groups.forEach((group: Record<string, any>) => {
+ const newDisks: any[] = [];
+ group.disks.forEach((disk: string) => {
+ const imageSplit = disk.split('/');
+ newDisks.push({
+ pool: imageSplit[0],
+ image: imageSplit[1]
+ });
+ });
+
+ group.disks = newDisks;
+ });
+ request.groups = formValue.groups;
+ }
+
+ let wrapTask;
+ if (this.isEdit) {
+ request['new_target_iqn'] = request.target_iqn;
+ request.target_iqn = this.target_iqn;
+ wrapTask = this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('iscsi/target/edit', {
+ target_iqn: request.target_iqn
+ }),
+ call: this.iscsiService.updateTarget(this.target_iqn, request)
+ });
+ } else {
+ wrapTask = this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('iscsi/target/create', {
+ target_iqn: request.target_iqn
+ }),
+ call: this.iscsiService.createTarget(request)
+ });
+ }
+
+ wrapTask.subscribe({
+ error: () => {
+ this.targetForm.setErrors({ cdSubmitButton: true });
+ },
+ complete: () => this.router.navigate(['/block/iscsi/targets'])
+ });
+ }
+
+ targetSettingsModal() {
+ const initialState = {
+ target_controls: this.targetForm.get('target_controls'),
+ target_default_controls: this.target_default_controls,
+ target_controls_limits: this.target_controls_limits
+ };
+
+ this.modalRef = this.modalService.show(IscsiTargetIqnSettingsModalComponent, initialState);
+ }
+
+ imageSettingsModal(image: string) {
+ const initialState = {
+ imagesSettings: this.imagesSettings,
+ image: image,
+ api_version: this.api_version,
+ disk_default_controls: this.disk_default_controls,
+ disk_controls_limits: this.disk_controls_limits,
+ backstores: this.getValidBackstores(this.getImageById(image)),
+ control: this.targetForm.get('disks')
+ };
+
+ this.modalRef = this.modalService.show(IscsiTargetImageSettingsModalComponent, initialState);
+ }
+
+ validFeatures(image: Record<string, any>, backstore: string) {
+ const imageFeatures = image.features;
+ const requiredFeatures = this.required_rbd_features[backstore];
+ const unsupportedFeatures = this.unsupported_rbd_features[backstore];
+ // tslint:disable-next-line:no-bitwise
+ const validRequiredFeatures = (imageFeatures & requiredFeatures) === requiredFeatures;
+ // tslint:disable-next-line:no-bitwise
+ const validSupportedFeatures = (imageFeatures & unsupportedFeatures) === 0;
+ return validRequiredFeatures && validSupportedFeatures;
+ }
+
+ getImageById(imageId: string) {
+ return this.imagesAll.find((image) => imageId === `${image.pool_name}/${image.name}`);
+ }
+
+ getValidBackstores(image: object) {
+ return this.backstores.filter((backstore) => this.validFeatures(image, backstore));
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html
new file mode 100644
index 000000000..2452b0bc5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html
@@ -0,0 +1,92 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container class="modal-title">
+ <ng-container i18n>Configure</ng-container>&nbsp;
+ <small>{{ image }}</small>
+ </ng-container>
+
+ <ng-container class="modal-content">
+ <form name="settingsForm"
+ class="form"
+ #formDir="ngForm"
+ [formGroup]="settingsForm"
+ novalidate>
+ <div class="modal-body">
+ <p class="alert-warning"
+ i18n>Changing these parameters from their default values is usually not necessary.</p>
+
+ <span *ngIf="api_version >= 1">
+ <legend class="cd-header"
+ i18n>Identifier</legend>
+ <!-- LUN -->
+ <div class="form-group row">
+ <div class="col-sm-12">
+ <label class="col-form-label required"
+ for="lun"
+ i18n>lun</label>
+ <input type="number"
+ class="form-control"
+ id="lun"
+ name="lun"
+ formControlName="lun">
+ <span class="invalid-feedback"
+ *ngIf="settingsForm.showError('lun', formDir, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+ <!-- WWN -->
+ <div class="form-group row">
+ <div class="col-sm-12">
+ <label class="col-form-label"
+ for="wwn"
+ i18n>wwn</label>
+ <input type="text"
+ class="form-control"
+ id="wwn"
+ name="wwn"
+ formControlName="wwn">
+ </div>
+ </div>
+ </span>
+
+ <legend class="cd-header"
+ i18n>Settings</legend>
+
+ <!-- BACKSTORE -->
+ <div class="form-group row">
+ <div class="col-sm-12">
+ <label class="col-form-label"
+ i18n>Backstore</label>
+ <select id="backstore"
+ name="backstore"
+ class="form-control"
+ formControlName="backstore">
+ <option *ngFor="let bs of backstores"
+ [value]="bs">{{ bs | iscsiBackstore }}</option>
+ </select>
+ </div>
+ </div>
+
+ <!-- CONTROLS -->
+ <ng-container *ngFor="let bs of backstores">
+ <ng-container *ngIf="settingsForm.value['backstore'] === bs">
+ <div class="form-group row"
+ *ngFor="let setting of disk_default_controls[bs] | keyvalue">
+ <div class="col-sm-12">
+ <cd-iscsi-setting [settingsForm]="settingsForm"
+ [formDir]="formDir"
+ [setting]="setting.key"
+ [limits]="getDiskControlLimits(bs, setting.key)"></cd-iscsi-setting>
+ </div>
+ </div>
+ </ng-container>
+ </ng-container>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="save()"
+ [form]="settingsForm"
+ [submitText]="actionLabels.UPDATE"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.spec.ts
new file mode 100644
index 000000000..cb37b2ffe
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.spec.ts
@@ -0,0 +1,98 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormControl, ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { IscsiSettingComponent } from '../iscsi-setting/iscsi-setting.component';
+import { IscsiTargetImageSettingsModalComponent } from './iscsi-target-image-settings-modal.component';
+
+describe('IscsiTargetImageSettingsModalComponent', () => {
+ let component: IscsiTargetImageSettingsModalComponent;
+ let fixture: ComponentFixture<IscsiTargetImageSettingsModalComponent>;
+
+ configureTestBed({
+ declarations: [IscsiTargetImageSettingsModalComponent, IscsiSettingComponent],
+ imports: [SharedModule, ReactiveFormsModule, HttpClientTestingModule, RouterTestingModule],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(IscsiTargetImageSettingsModalComponent);
+ component = fixture.componentInstance;
+
+ component.imagesSettings = { 'rbd/disk_1': { backstore: 'backstore:1', 'backstore:1': {} } };
+ component.image = 'rbd/disk_1';
+ component.disk_default_controls = {
+ 'backstore:1': {
+ foo: 1,
+ bar: 2
+ },
+ 'backstore:2': {
+ baz: 3
+ }
+ };
+ component.disk_controls_limits = {
+ 'backstore:1': {
+ foo: {
+ min: 1,
+ max: 512,
+ type: 'int'
+ },
+ bar: {
+ min: 1,
+ max: 512,
+ type: 'int'
+ }
+ },
+ 'backstore:2': {
+ baz: {
+ min: 1,
+ max: 512,
+ type: 'int'
+ }
+ }
+ };
+ component.backstores = ['backstore:1', 'backstore:2'];
+ component.control = new FormControl();
+
+ component.ngOnInit();
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should fill the form', () => {
+ expect(component.settingsForm.value).toEqual({
+ lun: null,
+ wwn: null,
+ backstore: 'backstore:1',
+ foo: null,
+ bar: null,
+ baz: null
+ });
+ });
+
+ it('should save changes to imagesSettings', () => {
+ component.settingsForm.controls['foo'].setValue(1234);
+ expect(component.imagesSettings).toEqual({
+ 'rbd/disk_1': { backstore: 'backstore:1', 'backstore:1': {} }
+ });
+ component.save();
+ expect(component.imagesSettings).toEqual({
+ 'rbd/disk_1': {
+ lun: null,
+ wwn: null,
+ backstore: 'backstore:1',
+ 'backstore:1': {
+ foo: 1234
+ }
+ }
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.ts
new file mode 100644
index 000000000..e9c9c7d90
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.ts
@@ -0,0 +1,87 @@
+import { Component, OnInit } from '@angular/core';
+import { AbstractControl, FormControl } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+
+import { IscsiService } from '~/app/shared/api/iscsi.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+
+@Component({
+ selector: 'cd-iscsi-target-image-settings-modal',
+ templateUrl: './iscsi-target-image-settings-modal.component.html',
+ styleUrls: ['./iscsi-target-image-settings-modal.component.scss']
+})
+export class IscsiTargetImageSettingsModalComponent implements OnInit {
+ image: string;
+ imagesSettings: any;
+ api_version: number;
+ disk_default_controls: any;
+ disk_controls_limits: any;
+ backstores: any;
+ control: AbstractControl;
+
+ settingsForm: CdFormGroup;
+
+ constructor(
+ public activeModal: NgbActiveModal,
+ public iscsiService: IscsiService,
+ public actionLabels: ActionLabelsI18n
+ ) {}
+
+ ngOnInit() {
+ const fg: Record<string, FormControl> = {
+ backstore: new FormControl(this.imagesSettings[this.image]['backstore']),
+ lun: new FormControl(this.imagesSettings[this.image]['lun']),
+ wwn: new FormControl(this.imagesSettings[this.image]['wwn'])
+ };
+ _.forEach(this.backstores, (backstore) => {
+ const model = this.imagesSettings[this.image][backstore] || {};
+ _.forIn(this.disk_default_controls[backstore], (_value, key) => {
+ fg[key] = new FormControl(model[key]);
+ });
+ });
+
+ this.settingsForm = new CdFormGroup(fg);
+ }
+
+ getDiskControlLimits(backstore: string, setting: string) {
+ if (this.disk_controls_limits) {
+ return this.disk_controls_limits[backstore][setting];
+ }
+ // backward compatibility
+ return { type: 'int' };
+ }
+
+ save() {
+ const backstore = this.settingsForm.controls['backstore'].value;
+ const lun = this.settingsForm.controls['lun'].value;
+ const wwn = this.settingsForm.controls['wwn'].value;
+ const settings = {};
+ _.forIn(this.settingsForm.controls, (control, key) => {
+ if (
+ !(control.value === '' || control.value === null) &&
+ key in this.disk_default_controls[this.settingsForm.value['backstore']]
+ ) {
+ settings[key] = control.value;
+ // If one setting belongs to multiple backstores, we have to update it in all backstores
+ _.forEach(this.backstores, (currentBackstore) => {
+ if (currentBackstore !== backstore) {
+ const model = this.imagesSettings[this.image][currentBackstore] || {};
+ if (key in model) {
+ this.imagesSettings[this.image][currentBackstore][key] = control.value;
+ }
+ }
+ });
+ }
+ });
+ this.imagesSettings[this.image]['backstore'] = backstore;
+ this.imagesSettings[this.image]['lun'] = lun;
+ this.imagesSettings[this.image]['wwn'] = wwn;
+ this.imagesSettings[this.image][backstore] = settings;
+ this.imagesSettings = { ...this.imagesSettings };
+ this.control.updateValueAndValidity({ emitEvent: false });
+ this.activeModal.close();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html
new file mode 100644
index 000000000..a5d1269f6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html
@@ -0,0 +1,32 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container class="modal-title"
+ i18n>Advanced Settings</ng-container>
+
+ <ng-container class="modal-content">
+ <form name="settingsForm"
+ #formDir="ngForm"
+ [formGroup]="settingsForm"
+ novalidate>
+ <div class="modal-body">
+ <p class="alert-warning"
+ i18n>Changing these parameters from their default values is usually not necessary.</p>
+
+ <div class="form-group row"
+ *ngFor="let setting of settingsForm.controls | keyvalue">
+ <div class="col-sm-12">
+ <cd-iscsi-setting [settingsForm]="settingsForm"
+ [formDir]="formDir"
+ [setting]="setting.key"
+ [limits]="getTargetControlLimits(setting.key)"></cd-iscsi-setting>
+ </div>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="save()"
+ [form]="settingsForm"
+ [submitText]="actionLabels.UPDATE"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.spec.ts
new file mode 100644
index 000000000..dda1be3c1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.spec.ts
@@ -0,0 +1,71 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormControl, ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { IscsiSettingComponent } from '../iscsi-setting/iscsi-setting.component';
+import { IscsiTargetIqnSettingsModalComponent } from './iscsi-target-iqn-settings-modal.component';
+
+describe('IscsiTargetIqnSettingsModalComponent', () => {
+ let component: IscsiTargetIqnSettingsModalComponent;
+ let fixture: ComponentFixture<IscsiTargetIqnSettingsModalComponent>;
+
+ configureTestBed({
+ declarations: [IscsiTargetIqnSettingsModalComponent, IscsiSettingComponent],
+ imports: [SharedModule, ReactiveFormsModule, HttpClientTestingModule, RouterTestingModule],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(IscsiTargetIqnSettingsModalComponent);
+ component = fixture.componentInstance;
+ component.target_controls = new FormControl({});
+ component.target_default_controls = {
+ cmdsn_depth: 1,
+ dataout_timeout: 2,
+ first_burst_length: true
+ };
+ component.target_controls_limits = {
+ cmdsn_depth: {
+ min: 1,
+ max: 512,
+ type: 'int'
+ },
+ dataout_timeout: {
+ min: 2,
+ max: 60,
+ type: 'int'
+ },
+ first_burst_length: {
+ max: 16777215,
+ min: 512,
+ type: 'int'
+ }
+ };
+ component.ngOnInit();
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should fill the settingsForm', () => {
+ expect(component.settingsForm.value).toEqual({
+ cmdsn_depth: null,
+ dataout_timeout: null,
+ first_burst_length: null
+ });
+ });
+
+ it('should save changes to target_controls', () => {
+ component.settingsForm.patchValue({ dataout_timeout: 1234 });
+ expect(component.target_controls.value).toEqual({});
+ component.save();
+ expect(component.target_controls.value).toEqual({ dataout_timeout: 1234 });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.ts
new file mode 100644
index 000000000..36fdb9026
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.ts
@@ -0,0 +1,60 @@
+import { Component, OnInit } from '@angular/core';
+import { FormControl } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+
+import { IscsiService } from '~/app/shared/api/iscsi.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+
+@Component({
+ selector: 'cd-iscsi-target-iqn-settings-modal',
+ templateUrl: './iscsi-target-iqn-settings-modal.component.html',
+ styleUrls: ['./iscsi-target-iqn-settings-modal.component.scss']
+})
+export class IscsiTargetIqnSettingsModalComponent implements OnInit {
+ target_controls: FormControl;
+ target_default_controls: any;
+ target_controls_limits: any;
+
+ settingsForm: CdFormGroup;
+
+ constructor(
+ public activeModal: NgbActiveModal,
+ public iscsiService: IscsiService,
+ public actionLabels: ActionLabelsI18n
+ ) {}
+
+ ngOnInit() {
+ const fg: Record<string, FormControl> = {};
+ _.forIn(this.target_default_controls, (_value, key) => {
+ fg[key] = new FormControl(this.target_controls.value[key]);
+ });
+
+ this.settingsForm = new CdFormGroup(fg);
+ }
+
+ save() {
+ const settings = {};
+ _.forIn(this.settingsForm.controls, (control, key) => {
+ if (!(control.value === '' || control.value === null)) {
+ settings[key] = control.value;
+ }
+ });
+
+ this.target_controls.setValue(settings);
+ this.activeModal.close();
+ }
+
+ getTargetControlLimits(setting: string) {
+ if (this.target_controls_limits) {
+ return this.target_controls_limits[setting];
+ }
+ // backward compatibility
+ if (['Yes', 'No'].includes(this.target_default_controls[setting])) {
+ return { type: 'bool' };
+ }
+ return { type: 'int' };
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html
new file mode 100644
index 000000000..f6ac54538
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html
@@ -0,0 +1,53 @@
+<cd-iscsi-tabs></cd-iscsi-tabs>
+
+<cd-alert-panel type="info"
+ *ngIf="available === false"
+ title="iSCSI Targets not available"
+ i18n-title>
+ <ng-container i18n>Please consult the <cd-doc section="iscsi"></cd-doc> on
+ how to configure and enable the iSCSI Targets management functionality.</ng-container>
+
+ <ng-container *ngIf="status">
+ <br>
+ <span i18n>Available information:</span>
+ <pre>{{ status }}</pre>
+ </ng-container>
+</cd-alert-panel>
+
+<cd-table #table
+ *ngIf="available === true"
+ [data]="targets"
+ columnMode="flex"
+ [columns]="columns"
+ identifier="target_iqn"
+ forceIdentifier="true"
+ selectionType="single"
+ [hasDetails]="true"
+ [autoReload]="false"
+ [status]="tableStatus"
+ (fetchData)="getTargets()"
+ (setExpandedRow)="setExpandedRow($event)"
+ (updateSelection)="updateSelection($event)">
+ <div class="table-actions btn-toolbar">
+ <cd-table-actions class="btn-group"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+
+ <button class="btn btn-light"
+ type="button"
+ (click)="configureDiscoveryAuth()">
+ <i [ngClass]="[icons.key]"
+ aria-hidden="true">
+ </i>
+ <ng-container i18n>Discovery authentication</ng-container>
+ </button>
+ </div>
+
+ <cd-iscsi-target-details cdTableDetail
+ *ngIf="expandedRow"
+ [cephIscsiConfigVersion]="cephIscsiConfigVersion"
+ [selection]="expandedRow"
+ [settings]="settings"></cd-iscsi-target-details>
+</cd-table>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.spec.ts
new file mode 100644
index 000000000..51998cf0b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.spec.ts
@@ -0,0 +1,309 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { TreeModule } from '@circlon/angular-tree-component';
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { BehaviorSubject, of } from 'rxjs';
+
+import { IscsiService } from '~/app/shared/api/iscsi.service';
+import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { ExecutingTask } from '~/app/shared/models/executing-task';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { TaskListService } from '~/app/shared/services/task-list.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, expectItemTasks, PermissionHelper } from '~/testing/unit-test-helper';
+import { IscsiTabsComponent } from '../iscsi-tabs/iscsi-tabs.component';
+import { IscsiTargetDetailsComponent } from '../iscsi-target-details/iscsi-target-details.component';
+import { IscsiTargetListComponent } from './iscsi-target-list.component';
+
+describe('IscsiTargetListComponent', () => {
+ let component: IscsiTargetListComponent;
+ let fixture: ComponentFixture<IscsiTargetListComponent>;
+ let summaryService: SummaryService;
+ let iscsiService: IscsiService;
+
+ const refresh = (data: any) => {
+ summaryService['summaryDataSource'].next(data);
+ };
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ HttpClientTestingModule,
+ RouterTestingModule,
+ SharedModule,
+ TreeModule,
+ ToastrModule.forRoot(),
+ NgbNavModule
+ ],
+ declarations: [IscsiTargetListComponent, IscsiTabsComponent, IscsiTargetDetailsComponent],
+ providers: [TaskListService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(IscsiTargetListComponent);
+ component = fixture.componentInstance;
+ summaryService = TestBed.inject(SummaryService);
+ iscsiService = TestBed.inject(IscsiService);
+
+ // this is needed because summaryService isn't being reset after each test.
+ summaryService['summaryDataSource'] = new BehaviorSubject(null);
+ summaryService['summaryData$'] = summaryService['summaryDataSource'].asObservable();
+
+ spyOn(iscsiService, 'status').and.returnValue(of({ available: true }));
+ spyOn(iscsiService, 'version').and.returnValue(of({ ceph_iscsi_config_version: 11 }));
+ spyOn(component, 'setTableRefreshTimeout').and.stub();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('after ngOnInit', () => {
+ beforeEach(() => {
+ spyOn(iscsiService, 'listTargets').and.callThrough();
+ fixture.detectChanges();
+ });
+
+ it('should load targets on init', () => {
+ refresh({});
+ expect(iscsiService.status).toHaveBeenCalled();
+ expect(iscsiService.listTargets).toHaveBeenCalled();
+ });
+
+ it('should not load targets on init because no data', () => {
+ refresh(undefined);
+ expect(iscsiService.listTargets).not.toHaveBeenCalled();
+ });
+
+ it('should call error function on init when summary service fails', () => {
+ spyOn(component.table, 'reset');
+ summaryService['summaryDataSource'].error(undefined);
+ expect(component.table.reset).toHaveBeenCalled();
+ });
+
+ it('should call settings on the getTargets methods', () => {
+ spyOn(iscsiService, 'settings').and.callThrough();
+ component.getTargets();
+ expect(iscsiService.settings).toHaveBeenCalled();
+ });
+ });
+
+ describe('handling of executing tasks', () => {
+ let targets: any[];
+
+ const addTarget = (name: string) => {
+ const model: any = {
+ target_iqn: name,
+ portals: [{ host: 'node1', ip: '192.168.100.201' }],
+ disks: [{ pool: 'rbd', image: 'disk_1', controls: {} }],
+ clients: [
+ {
+ client_iqn: 'iqn.1994-05.com.redhat:rh7-client',
+ luns: [{ pool: 'rbd', image: 'disk_1' }],
+ auth: {
+ user: 'myiscsiusername',
+ password: 'myiscsipassword',
+ mutual_user: null,
+ mutual_password: null
+ }
+ }
+ ],
+ groups: [],
+ target_controls: {}
+ };
+ targets.push(model);
+ };
+
+ const addTask = (name: string, target_iqn: string) => {
+ const task = new ExecutingTask();
+ task.name = name;
+ switch (task.name) {
+ case 'iscsi/target/create':
+ task.metadata = {
+ target_iqn: target_iqn
+ };
+ break;
+ case 'iscsi/target/delete':
+ task.metadata = {
+ target_iqn: target_iqn
+ };
+ break;
+ default:
+ task.metadata = {
+ target_iqn: target_iqn
+ };
+ break;
+ }
+ summaryService.addRunningTask(task);
+ };
+
+ beforeEach(() => {
+ targets = [];
+ addTarget('iqn.a');
+ addTarget('iqn.b');
+ addTarget('iqn.c');
+
+ component.targets = targets;
+ refresh({ executing_tasks: [], finished_tasks: [] });
+ spyOn(iscsiService, 'listTargets').and.callFake(() => of(targets));
+ fixture.detectChanges();
+ });
+
+ it('should gets all targets without tasks', () => {
+ expect(component.targets.length).toBe(3);
+ expect(component.targets.every((target) => !target.cdExecuting)).toBeTruthy();
+ });
+
+ it('should add a new target from a task', () => {
+ addTask('iscsi/target/create', 'iqn.d');
+ expect(component.targets.length).toBe(4);
+ expectItemTasks(component.targets[0], undefined);
+ expectItemTasks(component.targets[1], undefined);
+ expectItemTasks(component.targets[2], undefined);
+ expectItemTasks(component.targets[3], 'Creating');
+ });
+
+ it('should show when an existing target is being modified', () => {
+ addTask('iscsi/target/delete', 'iqn.b');
+ expect(component.targets.length).toBe(3);
+ expectItemTasks(component.targets[1], 'Deleting');
+ });
+ });
+
+ describe('handling of actions', () => {
+ beforeEach(() => {
+ fixture.detectChanges();
+ });
+
+ let action: CdTableAction;
+
+ const getAction = (name: string): CdTableAction => {
+ return component.tableActions.find((tableAction) => tableAction.name === name);
+ };
+
+ describe('edit', () => {
+ beforeEach(() => {
+ action = getAction('Edit');
+ });
+
+ it('should be disabled if no gateways', () => {
+ component.selection.selected = [
+ {
+ id: '-1'
+ }
+ ];
+ expect(action.disable(undefined)).toBe('Unavailable gateway(s)');
+ });
+
+ it('should be enabled if active sessions', () => {
+ component.selection.selected = [
+ {
+ id: '-1',
+ info: {
+ num_sessions: 1
+ }
+ }
+ ];
+ expect(action.disable(undefined)).toBeFalsy();
+ });
+
+ it('should be enabled if no active sessions', () => {
+ component.selection.selected = [
+ {
+ id: '-1',
+ info: {
+ num_sessions: 0
+ }
+ }
+ ];
+ expect(action.disable(undefined)).toBeFalsy();
+ });
+ });
+
+ describe('delete', () => {
+ beforeEach(() => {
+ action = getAction('Delete');
+ });
+
+ it('should be disabled if no gateways', () => {
+ component.selection.selected = [
+ {
+ id: '-1'
+ }
+ ];
+ expect(action.disable(undefined)).toBe('Unavailable gateway(s)');
+ });
+
+ it('should be disabled if active sessions', () => {
+ component.selection.selected = [
+ {
+ id: '-1',
+ info: {
+ num_sessions: 1
+ }
+ }
+ ];
+ expect(action.disable(undefined)).toBe('Target has active sessions');
+ });
+
+ it('should be enabled if no active sessions', () => {
+ component.selection.selected = [
+ {
+ id: '-1',
+ info: {
+ num_sessions: 0
+ }
+ }
+ ];
+ expect(action.disable(undefined)).toBeFalsy();
+ });
+ });
+ });
+
+ it('should test all TableActions combinations', () => {
+ const permissionHelper: PermissionHelper = new PermissionHelper(component.permission);
+ const tableActions: TableActionsComponent = permissionHelper.setPermissionsAndGetActions(
+ component.tableActions
+ );
+
+ expect(tableActions).toEqual({
+ 'create,update,delete': {
+ actions: ['Create', 'Edit', 'Delete'],
+ primary: { multiple: 'Create', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,update': {
+ actions: ['Create', 'Edit'],
+ primary: { multiple: 'Create', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,delete': {
+ actions: ['Create', 'Delete'],
+ primary: { multiple: 'Create', executing: 'Delete', single: 'Delete', no: 'Create' }
+ },
+ create: {
+ actions: ['Create'],
+ primary: { multiple: 'Create', executing: 'Create', single: 'Create', no: 'Create' }
+ },
+ 'update,delete': {
+ actions: ['Edit', 'Delete'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ update: {
+ actions: ['Edit'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ delete: {
+ actions: ['Delete'],
+ primary: { multiple: 'Delete', executing: 'Delete', single: 'Delete', no: 'Delete' }
+ },
+ 'no-permissions': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ }
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts
new file mode 100644
index 000000000..d0eed6a72
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts
@@ -0,0 +1,242 @@
+import { Component, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { Subscription } from 'rxjs';
+
+import { IscsiService } from '~/app/shared/api/iscsi.service';
+import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { TableComponent } from '~/app/shared/datatable/table/table.component';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { Permission } from '~/app/shared/models/permissions';
+import { Task } from '~/app/shared/models/task';
+import { JoinPipe } from '~/app/shared/pipes/join.pipe';
+import { NotAvailablePipe } from '~/app/shared/pipes/not-available.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { TaskListService } from '~/app/shared/services/task-list.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { IscsiTargetDiscoveryModalComponent } from '../iscsi-target-discovery-modal/iscsi-target-discovery-modal.component';
+
+@Component({
+ selector: 'cd-iscsi-target-list',
+ templateUrl: './iscsi-target-list.component.html',
+ styleUrls: ['./iscsi-target-list.component.scss'],
+ providers: [TaskListService]
+})
+export class IscsiTargetListComponent extends ListWithDetails implements OnInit, OnDestroy {
+ @ViewChild(TableComponent)
+ table: TableComponent;
+
+ available: boolean = undefined;
+ columns: CdTableColumn[];
+ modalRef: NgbModalRef;
+ permission: Permission;
+ selection = new CdTableSelection();
+ cephIscsiConfigVersion: number;
+ settings: any;
+ status: string;
+ summaryDataSubscription: Subscription;
+ tableActions: CdTableAction[];
+ targets: any[] = [];
+ icons = Icons;
+
+ builders = {
+ 'iscsi/target/create': (metadata: object) => {
+ return {
+ target_iqn: metadata['target_iqn']
+ };
+ }
+ };
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private iscsiService: IscsiService,
+ private joinPipe: JoinPipe,
+ private taskListService: TaskListService,
+ private notAvailablePipe: NotAvailablePipe,
+ private modalService: ModalService,
+ private taskWrapper: TaskWrapperService,
+ public actionLabels: ActionLabelsI18n,
+ protected ngZone: NgZone
+ ) {
+ super(ngZone);
+ this.permission = this.authStorageService.getPermissions().iscsi;
+
+ this.tableActions = [
+ {
+ permission: 'create',
+ icon: Icons.add,
+ routerLink: () => '/block/iscsi/targets/create',
+ name: this.actionLabels.CREATE
+ },
+ {
+ permission: 'update',
+ icon: Icons.edit,
+ routerLink: () => `/block/iscsi/targets/edit/${this.selection.first().target_iqn}`,
+ name: this.actionLabels.EDIT,
+ disable: () => this.getEditDisableDesc()
+ },
+ {
+ permission: 'delete',
+ icon: Icons.destroy,
+ click: () => this.deleteIscsiTargetModal(),
+ name: this.actionLabels.DELETE,
+ disable: () => this.getDeleteDisableDesc()
+ }
+ ];
+ }
+
+ ngOnInit() {
+ this.columns = [
+ {
+ name: $localize`Target`,
+ prop: 'target_iqn',
+ flexGrow: 2,
+ cellTransformation: CellTemplate.executing
+ },
+ {
+ name: $localize`Portals`,
+ prop: 'cdPortals',
+ pipe: this.joinPipe,
+ flexGrow: 2
+ },
+ {
+ name: $localize`Images`,
+ prop: 'cdImages',
+ pipe: this.joinPipe,
+ flexGrow: 2
+ },
+ {
+ name: $localize`# Sessions`,
+ prop: 'info.num_sessions',
+ pipe: this.notAvailablePipe,
+ flexGrow: 1
+ }
+ ];
+
+ this.iscsiService.status().subscribe((result: any) => {
+ this.available = result.available;
+
+ if (!result.available) {
+ this.status = result.message;
+ }
+ });
+ }
+
+ getTargets() {
+ if (this.available) {
+ this.setTableRefreshTimeout();
+ this.iscsiService.version().subscribe((res: any) => {
+ this.cephIscsiConfigVersion = res['ceph_iscsi_config_version'];
+ });
+ this.taskListService.init(
+ () => this.iscsiService.listTargets(),
+ (resp) => this.prepareResponse(resp),
+ (targets) => (this.targets = targets),
+ () => this.onFetchError(),
+ this.taskFilter,
+ this.itemFilter,
+ this.builders
+ );
+
+ this.iscsiService.settings().subscribe((settings: any) => {
+ this.settings = settings;
+ });
+ }
+ }
+
+ ngOnDestroy() {
+ if (this.summaryDataSubscription) {
+ this.summaryDataSubscription.unsubscribe();
+ }
+ }
+
+ getEditDisableDesc(): string | boolean {
+ const first = this.selection.first();
+
+ if (first && first?.cdExecuting) {
+ return first.cdExecuting;
+ }
+
+ if (first && _.isUndefined(first?.['info'])) {
+ return $localize`Unavailable gateway(s)`;
+ }
+
+ return !first;
+ }
+
+ getDeleteDisableDesc(): string | boolean {
+ const first = this.selection.first();
+
+ if (first?.cdExecuting) {
+ return first.cdExecuting;
+ }
+
+ if (first && _.isUndefined(first?.['info'])) {
+ return $localize`Unavailable gateway(s)`;
+ }
+
+ if (first && first?.['info']?.['num_sessions']) {
+ return $localize`Target has active sessions`;
+ }
+
+ return !first;
+ }
+
+ prepareResponse(resp: any): any[] {
+ resp.forEach((element: Record<string, any>) => {
+ element.cdPortals = element.portals.map(
+ (portal: Record<string, any>) => `${portal.host}:${portal.ip}`
+ );
+ element.cdImages = element.disks.map(
+ (disk: Record<string, any>) => `${disk.pool}/${disk.image}`
+ );
+ });
+
+ return resp;
+ }
+
+ onFetchError() {
+ this.table.reset(); // Disable loading indicator.
+ }
+
+ itemFilter(entry: Record<string, any>, task: Task) {
+ return entry.target_iqn === task.metadata['target_iqn'];
+ }
+
+ taskFilter(task: Task) {
+ return ['iscsi/target/create', 'iscsi/target/edit', 'iscsi/target/delete'].includes(task.name);
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ deleteIscsiTargetModal() {
+ const target_iqn = this.selection.first().target_iqn;
+
+ this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: $localize`iSCSI target`,
+ itemNames: [target_iqn],
+ submitActionObservable: () =>
+ this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('iscsi/target/delete', {
+ target_iqn: target_iqn
+ }),
+ call: this.iscsiService.deleteTarget(target_iqn)
+ })
+ });
+ }
+
+ configureDiscoveryAuth() {
+ this.modalService.show(IscsiTargetDiscoveryModalComponent);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.html
new file mode 100644
index 000000000..eccb79514
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.html
@@ -0,0 +1,49 @@
+<cd-iscsi-tabs></cd-iscsi-tabs>
+
+<legend i18n>Gateways</legend>
+<cd-table [data]="gateways"
+ (fetchData)="refresh()"
+ [columns]="gatewaysColumns">
+</cd-table>
+
+<legend i18n>Images</legend>
+<cd-table [data]="images"
+ [columns]="imagesColumns">
+</cd-table>
+
+<ng-template #iscsiSparklineTpl
+ let-row="row"
+ let-value="value">
+ <span *ngIf="row.backstore === 'user:rbd'">
+ <cd-sparkline [data]="value"
+ [isBinary]="row.cdIsBinary"></cd-sparkline>
+ </span>
+ <span *ngIf="row.backstore !== 'user:rbd'"
+ class="text-muted">
+ n/a
+ </span>
+</ng-template>
+
+<ng-template #iscsiPerSecondTpl
+ let-row="row"
+ let-value="value">
+ <span *ngIf="row.backstore === 'user:rbd'">
+ {{ value }} /s
+ </span>
+ <span *ngIf="row.backstore !== 'user:rbd'"
+ class="text-muted">
+ n/a
+ </span>
+</ng-template>
+
+<ng-template #iscsiRelativeDateTpl
+ let-row="row"
+ let-value="value">
+ <span *ngIf="row.backstore === 'user:rbd'">
+ {{ value | relativeDate | notAvailable }}
+ </span>
+ <span *ngIf="row.backstore !== 'user:rbd'"
+ class="text-muted">
+ n/a
+ </span>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.spec.ts
new file mode 100644
index 000000000..9e99bf9e6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.spec.ts
@@ -0,0 +1,83 @@
+import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+import { of } from 'rxjs';
+
+import { IscsiService } from '~/app/shared/api/iscsi.service';
+import { CephShortVersionPipe } from '~/app/shared/pipes/ceph-short-version.pipe';
+import { DimlessPipe } from '~/app/shared/pipes/dimless.pipe';
+import { IscsiBackstorePipe } from '~/app/shared/pipes/iscsi-backstore.pipe';
+import { FormatterService } from '~/app/shared/services/formatter.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { IscsiComponent } from './iscsi.component';
+
+describe('IscsiComponent', () => {
+ let component: IscsiComponent;
+ let fixture: ComponentFixture<IscsiComponent>;
+ let iscsiService: IscsiService;
+ let tcmuiscsiData: Record<string, any>;
+
+ const fakeService = {
+ overview: () => {
+ return new Promise(function () {
+ return;
+ });
+ }
+ };
+
+ configureTestBed({
+ imports: [BrowserAnimationsModule, SharedModule],
+ declarations: [IscsiComponent],
+ schemas: [NO_ERRORS_SCHEMA],
+ providers: [
+ CephShortVersionPipe,
+ DimlessPipe,
+ FormatterService,
+ IscsiBackstorePipe,
+ { provide: IscsiService, useValue: fakeService }
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(IscsiComponent);
+ component = fixture.componentInstance;
+ iscsiService = TestBed.inject(IscsiService);
+ fixture.detectChanges();
+ tcmuiscsiData = {
+ images: []
+ };
+ spyOn(iscsiService, 'overview').and.callFake(() => of(tcmuiscsiData));
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should refresh without stats available', () => {
+ tcmuiscsiData.images.push({});
+ component.refresh();
+ expect(component.images[0].cdIsBinary).toBe(true);
+ });
+
+ it('should refresh with stats', () => {
+ tcmuiscsiData.images.push({
+ stats_history: {
+ rd_bytes: [
+ [1540551220, 0.0],
+ [1540551225, 0.0],
+ [1540551230, 0.0]
+ ],
+ wr_bytes: [
+ [1540551220, 0.0],
+ [1540551225, 0.0],
+ [1540551230, 0.0]
+ ]
+ }
+ });
+ component.refresh();
+ expect(component.images[0].stats_history).toEqual({ rd_bytes: [0, 0, 0], wr_bytes: [0, 0, 0] });
+ expect(component.images[0].cdIsBinary).toBe(true);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.ts
new file mode 100644
index 000000000..89e4d7f34
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.ts
@@ -0,0 +1,117 @@
+import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import { IscsiService } from '~/app/shared/api/iscsi.service';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { DimlessPipe } from '~/app/shared/pipes/dimless.pipe';
+import { IscsiBackstorePipe } from '~/app/shared/pipes/iscsi-backstore.pipe';
+
+@Component({
+ selector: 'cd-iscsi',
+ templateUrl: './iscsi.component.html',
+ styleUrls: ['./iscsi.component.scss']
+})
+export class IscsiComponent implements OnInit {
+ @ViewChild('iscsiSparklineTpl', { static: true })
+ iscsiSparklineTpl: TemplateRef<any>;
+ @ViewChild('iscsiPerSecondTpl', { static: true })
+ iscsiPerSecondTpl: TemplateRef<any>;
+ @ViewChild('iscsiRelativeDateTpl', { static: true })
+ iscsiRelativeDateTpl: TemplateRef<any>;
+
+ gateways: any[] = [];
+ gatewaysColumns: any;
+ images: any[] = [];
+ imagesColumns: any;
+
+ constructor(
+ private iscsiService: IscsiService,
+ private dimlessPipe: DimlessPipe,
+ private iscsiBackstorePipe: IscsiBackstorePipe
+ ) {}
+
+ ngOnInit() {
+ this.gatewaysColumns = [
+ {
+ name: $localize`Name`,
+ prop: 'name'
+ },
+ {
+ name: $localize`State`,
+ prop: 'state',
+ flexGrow: 1,
+ cellTransformation: CellTemplate.badge,
+ customTemplateConfig: {
+ map: {
+ up: { class: 'badge-success' },
+ down: { class: 'badge-danger' }
+ }
+ }
+ },
+ {
+ name: $localize`# Targets`,
+ prop: 'num_targets'
+ },
+ {
+ name: $localize`# Sessions`,
+ prop: 'num_sessions'
+ }
+ ];
+ this.imagesColumns = [
+ {
+ name: $localize`Pool`,
+ prop: 'pool'
+ },
+ {
+ name: $localize`Image`,
+ prop: 'image'
+ },
+ {
+ name: $localize`Backstore`,
+ prop: 'backstore',
+ pipe: this.iscsiBackstorePipe
+ },
+ {
+ name: $localize`Read Bytes`,
+ prop: 'stats_history.rd_bytes',
+ cellTemplate: this.iscsiSparklineTpl
+ },
+ {
+ name: $localize`Write Bytes`,
+ prop: 'stats_history.wr_bytes',
+ cellTemplate: this.iscsiSparklineTpl
+ },
+ {
+ name: $localize`Read Ops`,
+ prop: 'stats.rd',
+ pipe: this.dimlessPipe,
+ cellTemplate: this.iscsiPerSecondTpl
+ },
+ {
+ name: $localize`Write Ops`,
+ prop: 'stats.wr',
+ pipe: this.dimlessPipe,
+ cellTemplate: this.iscsiPerSecondTpl
+ },
+ {
+ name: $localize`A/O Since`,
+ prop: 'optimized_since',
+ cellTemplate: this.iscsiRelativeDateTpl
+ }
+ ];
+ }
+
+ refresh() {
+ this.iscsiService.overview().subscribe((overview: object) => {
+ this.gateways = overview['gateways'];
+ this.images = overview['images'];
+ this.images.map((image) => {
+ if (image.stats_history) {
+ image.stats_history.rd_bytes = image.stats_history.rd_bytes.map((i: any) => i[1]);
+ image.stats_history.wr_bytes = image.stats_history.wr_bytes.map((i: any) => i[1]);
+ }
+ image.cdIsBinary = true;
+ return image;
+ });
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html
new file mode 100755
index 000000000..a31ab933c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html
@@ -0,0 +1,87 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container i18n
+ class="modal-title">Create Bootstrap Token</ng-container>
+
+ <ng-container class="modal-content">
+ <form name="createBootstrapForm"
+ class="form"
+ #formDir="ngForm"
+ [formGroup]="createBootstrapForm"
+ novalidate>
+ <div class="modal-body">
+ <p>
+ <ng-container i18n>To create a bootstrap token which can be imported
+ by a peer site cluster, provide the local site's name, select
+ which pools will have mirroring enabled, and click&nbsp;
+ <kbd>Generate</kbd>.</ng-container>
+ </p>
+
+ <div class="form-group">
+ <label class="col-form-label required"
+ for="siteName"
+ i18n>Site Name</label>
+ <input class="form-control"
+ type="text"
+ placeholder="Name..."
+ i18n-placeholder
+ id="siteName"
+ name="siteName"
+ formControlName="siteName"
+ autofocus>
+ <span *ngIf="createBootstrapForm.showError('siteName', formDir, 'required')"
+ class="invalid-feedback"
+ i18n>This field is required.</span>
+ </div>
+
+ <div class="form-group"
+ formGroupName="pools">
+ <label class="col-form-label required"
+ for="pools"
+ i18n>Pools</label>
+ <div class="custom-control custom-checkbox"
+ *ngFor="let pool of pools">
+ <input type="checkbox"
+ class="custom-control-input"
+ id="{{ pool.name }}"
+ name="{{ pool.name }}"
+ formControlName="{{ pool.name }}">
+ <label class="custom-control-label"
+ for="{{ pool.name }}">{{ pool.name }}</label>
+ </div>
+ <span *ngIf="createBootstrapForm.showError('pools', formDir, 'requirePool')"
+ class="invalid-feedback"
+ i18n>At least one pool is required.</span>
+ </div>
+
+ <cd-submit-button class="mb-4 float-right"
+ i18n
+ [form]="createBootstrapForm"
+ (submitAction)="generate()">Generate</cd-submit-button>
+
+ <div class="form-group">
+ <label class="col-form-label"
+ for="token">
+ <span i18n>Token</span>
+ </label>
+ <textarea class="form-control resize-vertical"
+ placeholder="Generated token..."
+ i18n-placeholder
+ id="token"
+ formControlName="token"
+ readonly>
+ </textarea>
+ </div>
+ <cd-copy-2-clipboard-button class="float-right"
+ source="token">
+ </cd-copy-2-clipboard-button>
+ </div>
+
+ <div class="modal-footer">
+ <cd-back-button (backAction)="activeModal.close()"
+ name="Close"
+ i18n-name>
+ </cd-back-button>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.scss
new file mode 100644
index 000000000..8dc4d1c73
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.scss
@@ -0,0 +1,3 @@
+.form-group.ng-invalid .invalid-feedback {
+ display: block;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.spec.ts
new file mode 100644
index 000000000..f8f634476
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.spec.ts
@@ -0,0 +1,113 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
+import { BootstrapCreateModalComponent } from './bootstrap-create-modal.component';
+
+describe('BootstrapCreateModalComponent', () => {
+ let component: BootstrapCreateModalComponent;
+ let fixture: ComponentFixture<BootstrapCreateModalComponent>;
+ let notificationService: NotificationService;
+ let rbdMirroringService: RbdMirroringService;
+ let formHelper: FormHelper;
+
+ configureTestBed({
+ declarations: [BootstrapCreateModalComponent],
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ RouterTestingModule,
+ SharedModule,
+ ToastrModule.forRoot()
+ ],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(BootstrapCreateModalComponent);
+ component = fixture.componentInstance;
+ component.siteName = 'site-A';
+
+ notificationService = TestBed.inject(NotificationService);
+ spyOn(notificationService, 'show').and.stub();
+
+ rbdMirroringService = TestBed.inject(RbdMirroringService);
+
+ formHelper = new FormHelper(component.createBootstrapForm);
+
+ spyOn(rbdMirroringService, 'getSiteName').and.callFake(() => of({ site_name: 'site-A' }));
+ spyOn(rbdMirroringService, 'subscribeSummary').and.callFake((call) =>
+ of({
+ content_data: {
+ pools: [
+ { name: 'pool1', mirror_mode: 'disabled' },
+ { name: 'pool2', mirror_mode: 'disabled' },
+ { name: 'pool3', mirror_mode: 'disabled' }
+ ]
+ }
+ }).subscribe(call)
+ );
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('generate token', () => {
+ beforeEach(() => {
+ spyOn(rbdMirroringService, 'refresh').and.stub();
+ spyOn(component.activeModal, 'close').and.callThrough();
+ fixture.detectChanges();
+ });
+
+ afterEach(() => {
+ expect(rbdMirroringService.getSiteName).toHaveBeenCalledTimes(1);
+ expect(rbdMirroringService.subscribeSummary).toHaveBeenCalledTimes(1);
+ expect(rbdMirroringService.refresh).toHaveBeenCalledTimes(1);
+ });
+
+ it('should generate a bootstrap token', () => {
+ spyOn(rbdMirroringService, 'setSiteName').and.callFake(() => of({ site_name: 'new-site-A' }));
+ spyOn(rbdMirroringService, 'updatePool').and.callFake(() => of({}));
+ spyOn(rbdMirroringService, 'createBootstrapToken').and.callFake(() => of({ token: 'token' }));
+
+ component.createBootstrapForm.patchValue({
+ siteName: 'new-site-A',
+ pools: { pool1: true, pool3: true }
+ });
+ component.generate();
+ expect(rbdMirroringService.setSiteName).toHaveBeenCalledWith('new-site-A');
+ expect(rbdMirroringService.updatePool).toHaveBeenCalledWith('pool1', {
+ mirror_mode: 'image'
+ });
+ expect(rbdMirroringService.updatePool).toHaveBeenCalledWith('pool3', {
+ mirror_mode: 'image'
+ });
+ expect(rbdMirroringService.createBootstrapToken).toHaveBeenCalledWith('pool3');
+ expect(component.createBootstrapForm.getValue('token')).toBe('token');
+ });
+ });
+
+ describe('form validation', () => {
+ beforeEach(() => {
+ fixture.detectChanges();
+ });
+
+ it('should require a site name', () => {
+ formHelper.expectErrorChange('siteName', '', 'required');
+ });
+
+ it('should require at least one pool', () => {
+ formHelper.expectError(component.createBootstrapForm.get('pools'), 'requirePool');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.ts
new file mode 100644
index 000000000..380b636c3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.ts
@@ -0,0 +1,153 @@
+import { Component, OnDestroy, OnInit } from '@angular/core';
+import { FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { concat, forkJoin, Subscription } from 'rxjs';
+import { last, tap } from 'rxjs/operators';
+
+import { Pool } from '~/app/ceph/pool/pool';
+import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+
+@Component({
+ selector: 'cd-bootstrap-create-modal',
+ templateUrl: './bootstrap-create-modal.component.html',
+ styleUrls: ['./bootstrap-create-modal.component.scss']
+})
+export class BootstrapCreateModalComponent implements OnDestroy, OnInit {
+ siteName: string;
+ pools: any[] = [];
+ token: string;
+
+ subs: Subscription;
+
+ createBootstrapForm: CdFormGroup;
+
+ constructor(
+ public activeModal: NgbActiveModal,
+ private rbdMirroringService: RbdMirroringService,
+ private taskWrapper: TaskWrapperService
+ ) {
+ this.createForm();
+ }
+
+ createForm() {
+ this.createBootstrapForm = new CdFormGroup({
+ siteName: new FormControl('', {
+ validators: [Validators.required]
+ }),
+ pools: new FormGroup(
+ {},
+ {
+ validators: [this.validatePools()]
+ }
+ ),
+ token: new FormControl('', {})
+ });
+ }
+
+ ngOnInit() {
+ this.createBootstrapForm.get('siteName').setValue(this.siteName);
+ this.rbdMirroringService.getSiteName().subscribe((response: any) => {
+ this.createBootstrapForm.get('siteName').setValue(response.site_name);
+ });
+
+ this.subs = this.rbdMirroringService.subscribeSummary((data) => {
+ const pools = data.content_data.pools;
+ this.pools = pools.reduce((acc: any[], pool: Pool) => {
+ acc.push({
+ name: pool['name'],
+ mirror_mode: pool['mirror_mode']
+ });
+ return acc;
+ }, []);
+
+ const poolsControl = this.createBootstrapForm.get('pools') as FormGroup;
+ _.each(this.pools, (pool) => {
+ const poolName = pool['name'];
+ const mirroring_disabled = pool['mirror_mode'] === 'disabled';
+ const control = poolsControl.controls[poolName];
+ if (control) {
+ if (mirroring_disabled && control.disabled) {
+ control.enable();
+ } else if (!mirroring_disabled && control.enabled) {
+ control.disable();
+ control.setValue(true);
+ }
+ } else {
+ poolsControl.addControl(
+ poolName,
+ new FormControl({ value: !mirroring_disabled, disabled: !mirroring_disabled })
+ );
+ }
+ });
+ });
+ }
+
+ ngOnDestroy() {
+ if (this.subs) {
+ this.subs.unsubscribe();
+ }
+ }
+
+ validatePools(): ValidatorFn {
+ return (poolsControl: FormGroup): { [key: string]: any } => {
+ let checkedCount = 0;
+ _.each(poolsControl.controls, (control) => {
+ if (control.value === true) {
+ ++checkedCount;
+ }
+ });
+
+ if (checkedCount > 0) {
+ return null;
+ }
+
+ return { requirePool: true };
+ };
+ }
+
+ generate() {
+ this.createBootstrapForm.get('token').setValue('');
+
+ let bootstrapPoolName = '';
+ const poolNames: string[] = [];
+ const poolsControl = this.createBootstrapForm.get('pools') as FormGroup;
+ _.each(poolsControl.controls, (control, poolName) => {
+ if (control.value === true) {
+ bootstrapPoolName = poolName;
+ if (!control.disabled) {
+ poolNames.push(poolName);
+ }
+ }
+ });
+
+ const poolModeRequest = {
+ mirror_mode: 'image'
+ };
+
+ const apiActionsObs = concat(
+ this.rbdMirroringService.setSiteName(this.createBootstrapForm.getValue('siteName')),
+ forkJoin(
+ poolNames.map((poolName) => this.rbdMirroringService.updatePool(poolName, poolModeRequest))
+ ),
+ this.rbdMirroringService
+ .createBootstrapToken(bootstrapPoolName)
+ .pipe(tap((data: any) => this.createBootstrapForm.get('token').setValue(data['token'])))
+ ).pipe(last());
+
+ const finishHandler = () => {
+ this.rbdMirroringService.refresh();
+ this.createBootstrapForm.setErrors({ cdSubmitButton: true });
+ };
+
+ const taskObs = this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('rbd/mirroring/bootstrap/create', {}),
+ call: apiActionsObs
+ });
+ taskObs.subscribe({ error: finishHandler, complete: finishHandler });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html
new file mode 100644
index 000000000..23372d383
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html
@@ -0,0 +1,96 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container i18n
+ class="modal-title">Import Bootstrap Token</ng-container>
+
+ <ng-container class="modal-content">
+ <form name="importBootstrapForm"
+ class="form"
+ #formDir="ngForm"
+ [formGroup]="importBootstrapForm"
+ novalidate>
+ <div class="modal-body">
+ <p>
+ <ng-container i18n>To import a bootstrap token which was created
+ by a peer site cluster, provide the local site's name, select
+ which pools will have mirroring enabled, provide the generated
+ token, and click&nbsp;<kbd>Import</kbd>.</ng-container>
+ </p>
+
+ <div class="form-group">
+ <label class="col-form-label required"
+ for="siteName"
+ i18n>Site Name</label>
+ <input class="form-control"
+ type="text"
+ placeholder="Name..."
+ i18n-placeholder
+ id="siteName"
+ name="siteName"
+ formControlName="siteName"
+ autofocus>
+ <span *ngIf="importBootstrapForm.showError('siteName', formDir, 'required')"
+ class="invalid-feedback"
+ i18n>This field is required.</span>
+ </div>
+
+ <div class="form-group">
+ <label class="col-form-label"
+ for="direction">
+ <span i18n>Direction</span>
+ </label>
+ <select id="direction"
+ name="direction"
+ class="form-control"
+ formControlName="direction">
+ <option *ngFor="let direction of directions"
+ [value]="direction.key">{{ direction.desc }}</option>
+ </select>
+ </div>
+
+ <div class="form-group"
+ formGroupName="pools">
+ <label class="col-form-label required"
+ for="pools"
+ i18n>Pools</label>
+ <div class="custom-control custom-checkbox"
+ *ngFor="let pool of pools">
+ <input type="checkbox"
+ class="custom-control-input"
+ id="{{ pool.name }}"
+ name="{{ pool.name }}"
+ formControlName="{{ pool.name }}">
+ <label class="custom-control-label"
+ for="{{ pool.name }}">{{ pool.name }}</label>
+ </div>
+ <span *ngIf="importBootstrapForm.showError('pools', formDir, 'requirePool')"
+ class="invalid-feedback"
+ i18n>At least one pool is required.</span>
+ </div>
+
+ <div class="form-group">
+ <label class="col-form-label required"
+ for="token"
+ i18n>Token</label>
+ <textarea class="form-control resize-vertical"
+ placeholder="Generated token..."
+ i18n-placeholder
+ id="token"
+ formControlName="token">
+ </textarea>
+ <span *ngIf="importBootstrapForm.showError('token', formDir, 'required')"
+ class="invalid-feedback"
+ i18n>This field is required.</span>
+ <span *ngIf="importBootstrapForm.showError('token', formDir, 'invalidToken')"
+ class="invalid-feedback"
+ i18n>The token is invalid.</span>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="import()"
+ [form]="importBootstrapForm"
+ [submitText]="actionLabels.SUBMIT"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.spec.ts
new file mode 100644
index 000000000..93c1405df
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.spec.ts
@@ -0,0 +1,131 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
+import { BootstrapImportModalComponent } from './bootstrap-import-modal.component';
+
+describe('BootstrapImportModalComponent', () => {
+ let component: BootstrapImportModalComponent;
+ let fixture: ComponentFixture<BootstrapImportModalComponent>;
+ let notificationService: NotificationService;
+ let rbdMirroringService: RbdMirroringService;
+ let formHelper: FormHelper;
+
+ configureTestBed({
+ declarations: [BootstrapImportModalComponent],
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ RouterTestingModule,
+ SharedModule,
+ ToastrModule.forRoot()
+ ],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(BootstrapImportModalComponent);
+ component = fixture.componentInstance;
+ component.siteName = 'site-A';
+
+ notificationService = TestBed.inject(NotificationService);
+ spyOn(notificationService, 'show').and.stub();
+
+ rbdMirroringService = TestBed.inject(RbdMirroringService);
+
+ formHelper = new FormHelper(component.importBootstrapForm);
+
+ spyOn(rbdMirroringService, 'getSiteName').and.callFake(() => of({ site_name: 'site-A' }));
+ spyOn(rbdMirroringService, 'subscribeSummary').and.callFake((call) =>
+ of({
+ content_data: {
+ pools: [
+ { name: 'pool1', mirror_mode: 'disabled' },
+ { name: 'pool2', mirror_mode: 'disabled' },
+ { name: 'pool3', mirror_mode: 'disabled' }
+ ]
+ }
+ }).subscribe(call)
+ );
+ });
+
+ it('should import', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('import token', () => {
+ beforeEach(() => {
+ spyOn(rbdMirroringService, 'refresh').and.stub();
+ spyOn(component.activeModal, 'close').and.callThrough();
+ fixture.detectChanges();
+ });
+
+ afterEach(() => {
+ expect(rbdMirroringService.getSiteName).toHaveBeenCalledTimes(1);
+ expect(rbdMirroringService.subscribeSummary).toHaveBeenCalledTimes(1);
+ expect(rbdMirroringService.refresh).toHaveBeenCalledTimes(1);
+ });
+
+ it('should generate a bootstrap token', () => {
+ spyOn(rbdMirroringService, 'setSiteName').and.callFake(() => of({ site_name: 'new-site-A' }));
+ spyOn(rbdMirroringService, 'updatePool').and.callFake(() => of({}));
+ spyOn(rbdMirroringService, 'importBootstrapToken').and.callFake(() => of({ token: 'token' }));
+
+ component.importBootstrapForm.patchValue({
+ siteName: 'new-site-A',
+ pools: { pool1: true, pool3: true },
+ token: 'e30='
+ });
+ component.import();
+ expect(rbdMirroringService.setSiteName).toHaveBeenCalledWith('new-site-A');
+ expect(rbdMirroringService.updatePool).toHaveBeenCalledWith('pool1', {
+ mirror_mode: 'image'
+ });
+ expect(rbdMirroringService.updatePool).toHaveBeenCalledWith('pool3', {
+ mirror_mode: 'image'
+ });
+ expect(rbdMirroringService.importBootstrapToken).toHaveBeenCalledWith(
+ 'pool1',
+ 'rx-tx',
+ 'e30='
+ );
+ expect(rbdMirroringService.importBootstrapToken).toHaveBeenCalledWith(
+ 'pool3',
+ 'rx-tx',
+ 'e30='
+ );
+ });
+ });
+
+ describe('form validation', () => {
+ beforeEach(() => {
+ fixture.detectChanges();
+ });
+
+ it('should require a site name', () => {
+ formHelper.expectErrorChange('siteName', '', 'required');
+ });
+
+ it('should require at least one pool', () => {
+ formHelper.expectError(component.importBootstrapForm.get('pools'), 'requirePool');
+ });
+
+ it('should require a token', () => {
+ formHelper.expectErrorChange('token', '', 'required');
+ });
+
+ it('should verify token is base64-encoded JSON', () => {
+ formHelper.expectErrorChange('token', 'VEVTVA==', 'invalidToken');
+ formHelper.expectErrorChange('token', 'e2RmYXNqZGZrbH0=', 'invalidToken');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.ts
new file mode 100644
index 000000000..d79096f6b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.ts
@@ -0,0 +1,187 @@
+import { Component, OnDestroy, OnInit } from '@angular/core';
+import { FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { concat, forkJoin, Observable, Subscription } from 'rxjs';
+import { last } from 'rxjs/operators';
+
+import { Pool } from '~/app/ceph/pool/pool';
+import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+
+@Component({
+ selector: 'cd-bootstrap-import-modal',
+ templateUrl: './bootstrap-import-modal.component.html',
+ styleUrls: ['./bootstrap-import-modal.component.scss']
+})
+export class BootstrapImportModalComponent implements OnInit, OnDestroy {
+ siteName: string;
+ pools: any[] = [];
+ token: string;
+
+ subs: Subscription;
+
+ importBootstrapForm: CdFormGroup;
+
+ directions: Array<any> = [
+ { key: 'rx-tx', desc: 'Bidirectional' },
+ { key: 'rx', desc: 'Unidirectional (receive-only)' }
+ ];
+
+ constructor(
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n,
+ private rbdMirroringService: RbdMirroringService,
+ private taskWrapper: TaskWrapperService
+ ) {
+ this.createForm();
+ }
+
+ createForm() {
+ this.importBootstrapForm = new CdFormGroup({
+ siteName: new FormControl('', {
+ validators: [Validators.required]
+ }),
+ direction: new FormControl('rx-tx', {}),
+ pools: new FormGroup(
+ {},
+ {
+ validators: [this.validatePools()]
+ }
+ ),
+ token: new FormControl('', {
+ validators: [Validators.required, this.validateToken()]
+ })
+ });
+ }
+
+ ngOnInit() {
+ this.rbdMirroringService.getSiteName().subscribe((response: any) => {
+ this.importBootstrapForm.get('siteName').setValue(response.site_name);
+ });
+
+ this.subs = this.rbdMirroringService.subscribeSummary((data) => {
+ const pools = data.content_data.pools;
+ this.pools = pools.reduce((acc: any[], pool: Pool) => {
+ acc.push({
+ name: pool['name'],
+ mirror_mode: pool['mirror_mode']
+ });
+ return acc;
+ }, []);
+
+ const poolsControl = this.importBootstrapForm.get('pools') as FormGroup;
+ _.each(this.pools, (pool) => {
+ const poolName = pool['name'];
+ const mirroring_disabled = pool['mirror_mode'] === 'disabled';
+ const control = poolsControl.controls[poolName];
+ if (control) {
+ if (mirroring_disabled && control.disabled) {
+ control.enable();
+ } else if (!mirroring_disabled && control.enabled) {
+ control.disable();
+ control.setValue(true);
+ }
+ } else {
+ poolsControl.addControl(
+ poolName,
+ new FormControl({ value: !mirroring_disabled, disabled: !mirroring_disabled })
+ );
+ }
+ });
+ });
+ }
+
+ ngOnDestroy() {
+ if (this.subs) {
+ this.subs.unsubscribe();
+ }
+ }
+
+ validatePools(): ValidatorFn {
+ return (poolsControl: FormGroup): { [key: string]: any } => {
+ let checkedCount = 0;
+ _.each(poolsControl.controls, (control) => {
+ if (control.value === true) {
+ ++checkedCount;
+ }
+ });
+
+ if (checkedCount > 0) {
+ return null;
+ }
+
+ return { requirePool: true };
+ };
+ }
+
+ validateToken(): ValidatorFn {
+ return (token: FormControl): { [key: string]: any } => {
+ try {
+ if (JSON.parse(atob(token.value))) {
+ return null;
+ }
+ } catch (error) {}
+ return { invalidToken: true };
+ };
+ }
+
+ import() {
+ const bootstrapPoolNames: string[] = [];
+ const poolNames: string[] = [];
+ const poolsControl = this.importBootstrapForm.get('pools') as FormGroup;
+ _.each(poolsControl.controls, (control, poolName) => {
+ if (control.value === true) {
+ bootstrapPoolNames.push(poolName);
+ if (!control.disabled) {
+ poolNames.push(poolName);
+ }
+ }
+ });
+
+ const poolModeRequest = {
+ mirror_mode: 'image'
+ };
+
+ let apiActionsObs: Observable<any> = concat(
+ this.rbdMirroringService.setSiteName(this.importBootstrapForm.getValue('siteName')),
+ forkJoin(
+ poolNames.map((poolName) => this.rbdMirroringService.updatePool(poolName, poolModeRequest))
+ )
+ );
+
+ apiActionsObs = bootstrapPoolNames
+ .reduce((obs, poolName) => {
+ return concat(
+ obs,
+ this.rbdMirroringService.importBootstrapToken(
+ poolName,
+ this.importBootstrapForm.getValue('direction'),
+ this.importBootstrapForm.getValue('token')
+ )
+ );
+ }, apiActionsObs)
+ .pipe(last());
+
+ const finishHandler = () => {
+ this.rbdMirroringService.refresh();
+ this.importBootstrapForm.setErrors({ cdSubmitButton: true });
+ };
+
+ const taskObs = this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('rbd/mirroring/bootstrap/import', {}),
+ call: apiActionsObs
+ });
+ taskObs.subscribe({
+ error: finishHandler,
+ complete: () => {
+ finishHandler();
+ this.activeModal.close();
+ }
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.html
new file mode 100644
index 000000000..c7c3bab87
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.html
@@ -0,0 +1,13 @@
+<cd-table [data]="data"
+ columnMode="flex"
+ [columns]="columns"
+ [autoReload]="-1"
+ (fetchData)="refresh()"
+ [status]="tableStatus">
+</cd-table>
+
+<ng-template #healthTmpl
+ let-row="row"
+ let-value="value">
+ <span [ngClass]="row.health_color | mirrorHealthColor">{{ value }}</span>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.spec.ts
new file mode 100644
index 000000000..12e3d82b5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.spec.ts
@@ -0,0 +1,28 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { MirrorHealthColorPipe } from '../mirror-health-color.pipe';
+import { DaemonListComponent } from './daemon-list.component';
+
+describe('DaemonListComponent', () => {
+ let component: DaemonListComponent;
+ let fixture: ComponentFixture<DaemonListComponent>;
+
+ configureTestBed({
+ declarations: [DaemonListComponent, MirrorHealthColorPipe],
+ imports: [BrowserAnimationsModule, SharedModule, HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DaemonListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts
new file mode 100644
index 000000000..d55197003
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts
@@ -0,0 +1,62 @@
+import { Component, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import { Subscription } from 'rxjs';
+
+import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
+import { TableStatusViewCache } from '~/app/shared/classes/table-status-view-cache';
+import { CephShortVersionPipe } from '~/app/shared/pipes/ceph-short-version.pipe';
+
+@Component({
+ selector: 'cd-mirroring-daemons',
+ templateUrl: './daemon-list.component.html',
+ styleUrls: ['./daemon-list.component.scss']
+})
+export class DaemonListComponent implements OnInit, OnDestroy {
+ @ViewChild('healthTmpl', { static: true })
+ healthTmpl: TemplateRef<any>;
+
+ subs: Subscription;
+
+ data: [];
+ columns: {};
+
+ tableStatus = new TableStatusViewCache();
+
+ constructor(
+ private rbdMirroringService: RbdMirroringService,
+ private cephShortVersionPipe: CephShortVersionPipe
+ ) {}
+
+ ngOnInit() {
+ this.columns = [
+ { prop: 'instance_id', name: $localize`Instance`, flexGrow: 2 },
+ { prop: 'id', name: $localize`ID`, flexGrow: 2 },
+ { prop: 'server_hostname', name: $localize`Hostname`, flexGrow: 2 },
+ {
+ prop: 'version',
+ name: $localize`Version`,
+ pipe: this.cephShortVersionPipe,
+ flexGrow: 2
+ },
+ {
+ prop: 'health',
+ name: $localize`Health`,
+ cellTemplate: this.healthTmpl,
+ flexGrow: 1
+ }
+ ];
+
+ this.subs = this.rbdMirroringService.subscribeSummary((data) => {
+ this.data = data.content_data.daemons;
+ this.tableStatus = new TableStatusViewCache(data.status);
+ });
+ }
+
+ ngOnDestroy(): void {
+ this.subs.unsubscribe();
+ }
+
+ refresh() {
+ this.rbdMirroringService.refresh();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.html
new file mode 100644
index 000000000..d4972a41c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.html
@@ -0,0 +1,63 @@
+<ul ngbNav
+ #nav="ngbNav"
+ class="nav-tabs"
+ cdStatefulTab="image-list">
+ <li ngbNavItem="issues">
+ <a ngbNavLink
+ i18n>Issues ({{ image_error.data.length }})</a>
+ <ng-template ngbNavContent>
+ <cd-table [data]="image_error.data"
+ columnMode="flex"
+ [columns]="image_error.columns"
+ [autoReload]="-1"
+ (fetchData)="refresh()"
+ [status]="tableStatus">
+ </cd-table>
+ </ng-template>
+ </li>
+ <li ngbNavItem="syncing">
+ <a ngbNavLink
+ i18n>Syncing ({{ image_syncing.data.length }})</a>
+ <ng-template ngbNavContent>
+ <cd-table [data]="image_syncing.data"
+ columnMode="flex"
+ [columns]="image_syncing.columns"
+ [autoReload]="-1"
+ (fetchData)="refresh()"
+ [status]="tableStatus">
+ </cd-table>
+ </ng-template>
+ </li>
+ <li ngbNavItem="ready">
+ <a ngbNavLink
+ i18n>Ready ({{ image_ready.data.length }})</a>
+ <ng-template ngbNavContent>
+ <cd-table [data]="image_ready.data"
+ columnMode="flex"
+ [columns]="image_ready.columns"
+ [autoReload]="-1"
+ (fetchData)="refresh()"
+ [status]="tableStatus">
+ </cd-table>
+ </ng-template>
+ </li>
+</ul>
+
+<div [ngbNavOutlet]="nav"></div>
+
+<ng-template #stateTmpl
+ let-row="row"
+ let-value="value">
+ <span [ngClass]="row.state_color | mirrorHealthColor">{{ value }}</span>
+</ng-template>
+
+<ng-template #progressTmpl
+ let-row="row"
+ let-value="value">
+ <div *ngIf="row.state === 'Replaying'">
+ </div>
+ <ngb-progressbar *ngIf="row.state === 'Syncing'"
+ type="info"
+ [value]="value"
+ [showValue]="true"></ngb-progressbar>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.spec.ts
new file mode 100644
index 000000000..b2cc12687
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.spec.ts
@@ -0,0 +1,36 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+import { NgbNavModule, NgbProgressbarModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { MirrorHealthColorPipe } from '../mirror-health-color.pipe';
+import { ImageListComponent } from './image-list.component';
+
+describe('ImageListComponent', () => {
+ let component: ImageListComponent;
+ let fixture: ComponentFixture<ImageListComponent>;
+
+ configureTestBed({
+ declarations: [ImageListComponent, MirrorHealthColorPipe],
+ imports: [
+ BrowserAnimationsModule,
+ SharedModule,
+ NgbNavModule,
+ NgbProgressbarModule,
+ HttpClientTestingModule
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ImageListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.ts
new file mode 100644
index 000000000..4966cc0af
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.ts
@@ -0,0 +1,99 @@
+import { Component, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import { Subscription } from 'rxjs';
+
+import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
+import { TableStatusViewCache } from '~/app/shared/classes/table-status-view-cache';
+
+@Component({
+ selector: 'cd-mirroring-images',
+ templateUrl: './image-list.component.html',
+ styleUrls: ['./image-list.component.scss']
+})
+export class ImageListComponent implements OnInit, OnDestroy {
+ @ViewChild('stateTmpl', { static: true })
+ stateTmpl: TemplateRef<any>;
+ @ViewChild('syncTmpl', { static: true })
+ syncTmpl: TemplateRef<any>;
+ @ViewChild('progressTmpl', { static: true })
+ progressTmpl: TemplateRef<any>;
+
+ subs: Subscription;
+
+ image_error: Record<string, any> = {
+ data: [],
+ columns: {}
+ };
+ image_syncing: Record<string, any> = {
+ data: [],
+ columns: {}
+ };
+ image_ready: Record<string, any> = {
+ data: [],
+ columns: {}
+ };
+
+ tableStatus = new TableStatusViewCache();
+
+ constructor(private rbdMirroringService: RbdMirroringService) {}
+
+ ngOnInit() {
+ this.image_error.columns = [
+ { prop: 'pool_name', name: $localize`Pool`, flexGrow: 2 },
+ { prop: 'name', name: $localize`Image`, flexGrow: 2 },
+ {
+ prop: 'state',
+ name: $localize`State`,
+ cellTemplate: this.stateTmpl,
+ flexGrow: 1
+ },
+ { prop: 'description', name: $localize`Issue`, flexGrow: 4 }
+ ];
+
+ this.image_syncing.columns = [
+ { prop: 'pool_name', name: $localize`Pool`, flexGrow: 2 },
+ { prop: 'name', name: $localize`Image`, flexGrow: 2 },
+ {
+ prop: 'state',
+ name: $localize`State`,
+ cellTemplate: this.stateTmpl,
+ flexGrow: 1
+ },
+ {
+ prop: 'progress',
+ name: $localize`Progress`,
+ cellTemplate: this.progressTmpl,
+ flexGrow: 2
+ },
+ { prop: 'bytes_per_second', name: $localize`Bytes per second`, flexGrow: 2 },
+ { prop: 'entries_behind_primary', name: $localize`Entries behind primary`, flexGrow: 2 }
+ ];
+
+ this.image_ready.columns = [
+ { prop: 'pool_name', name: $localize`Pool`, flexGrow: 2 },
+ { prop: 'name', name: $localize`Image`, flexGrow: 2 },
+ {
+ prop: 'state',
+ name: $localize`State`,
+ cellTemplate: this.stateTmpl,
+ flexGrow: 1
+ },
+ { prop: 'description', name: $localize`Description`, flexGrow: 4 }
+ ];
+
+ this.subs = this.rbdMirroringService.subscribeSummary((data) => {
+ this.image_error.data = data.content_data.image_error;
+ this.image_syncing.data = data.content_data.image_syncing;
+ this.image_ready.data = data.content_data.image_ready;
+ this.tableStatus = new TableStatusViewCache(data.status);
+ });
+ }
+
+ ngOnDestroy(): void {
+ this.subs.unsubscribe();
+ }
+
+ refresh() {
+ this.rbdMirroringService.refresh();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirror-health-color.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirror-health-color.pipe.spec.ts
new file mode 100644
index 000000000..52ff84be1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirror-health-color.pipe.spec.ts
@@ -0,0 +1,25 @@
+import { MirrorHealthColorPipe } from './mirror-health-color.pipe';
+
+describe('MirrorHealthColorPipe', () => {
+ const pipe = new MirrorHealthColorPipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms "warning"', () => {
+ expect(pipe.transform('warning')).toBe('badge badge-warning');
+ });
+
+ it('transforms "error"', () => {
+ expect(pipe.transform('error')).toBe('badge badge-danger');
+ });
+
+ it('transforms "success"', () => {
+ expect(pipe.transform('success')).toBe('badge badge-success');
+ });
+
+ it('transforms others', () => {
+ expect(pipe.transform('abc')).toBe('badge badge-info');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirror-health-color.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirror-health-color.pipe.ts
new file mode 100644
index 000000000..3c25d715e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirror-health-color.pipe.ts
@@ -0,0 +1,17 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'mirrorHealthColor'
+})
+export class MirrorHealthColorPipe implements PipeTransform {
+ transform(value: any): any {
+ if (value === 'warning') {
+ return 'badge badge-warning';
+ } else if (value === 'error') {
+ return 'badge badge-danger';
+ } else if (value === 'success') {
+ return 'badge badge-success';
+ }
+ return 'badge badge-info';
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirroring.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirroring.module.ts
new file mode 100644
index 000000000..dfebe934f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirroring.module.ts
@@ -0,0 +1,42 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { RouterModule } from '@angular/router';
+
+import { NgbNavModule, NgbProgressbarModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { BootstrapCreateModalComponent } from './bootstrap-create-modal/bootstrap-create-modal.component';
+import { BootstrapImportModalComponent } from './bootstrap-import-modal/bootstrap-import-modal.component';
+import { DaemonListComponent } from './daemon-list/daemon-list.component';
+import { ImageListComponent } from './image-list/image-list.component';
+import { MirrorHealthColorPipe } from './mirror-health-color.pipe';
+import { OverviewComponent } from './overview/overview.component';
+import { PoolEditModeModalComponent } from './pool-edit-mode-modal/pool-edit-mode-modal.component';
+import { PoolEditPeerModalComponent } from './pool-edit-peer-modal/pool-edit-peer-modal.component';
+import { PoolListComponent } from './pool-list/pool-list.component';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ SharedModule,
+ NgbNavModule,
+ RouterModule,
+ FormsModule,
+ ReactiveFormsModule,
+ NgbProgressbarModule
+ ],
+ declarations: [
+ BootstrapCreateModalComponent,
+ BootstrapImportModalComponent,
+ DaemonListComponent,
+ ImageListComponent,
+ OverviewComponent,
+ PoolEditModeModalComponent,
+ PoolEditPeerModalComponent,
+ PoolListComponent,
+ MirrorHealthColorPipe
+ ],
+ exports: [OverviewComponent]
+})
+export class MirroringModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.html
new file mode 100644
index 000000000..9cdfab939
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.html
@@ -0,0 +1,66 @@
+<div class="row">
+ <div class="col-md-12">
+ <form name="rbdmirroringForm"
+ #formDir="ngForm"
+ [formGroup]="rbdmirroringForm"
+ novalidate>
+
+ <div class="d-flex flex-row">
+ <label class="col-form-label"
+ for="siteName"
+ i18n>Site Name</label>
+
+ <div class="col-md-4 input-group mb-3 mr-auto">
+ <input type="text"
+ class="form-control"
+ id="siteName"
+ name="siteName"
+ formControlName="siteName"
+ [attr.disabled]="!editing ? true : null">
+ <div class="input-group-append">
+ <button class="btn btn-light"
+ id="editSiteName"
+ (click)="updateSiteName()">
+ <i [ngClass]="icons.edit"
+ *ngIf="!editing"></i>
+ <i [ngClass]="icons.check"
+ *ngIf="editing"></i>
+ </button>
+ <cd-copy-2-clipboard-button [source]="siteName"
+ [byId]="false">
+ </cd-copy-2-clipboard-button>
+ </div>
+ </div>
+ <cd-table-actions class="table-actions"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ </div>
+ </form>
+ </div>
+</div>
+
+<div class="row">
+ <div class="col-sm-6">
+ <legend i18n>Daemons</legend>
+
+ <cd-mirroring-daemons>
+ </cd-mirroring-daemons>
+ </div>
+
+ <div class="col-sm-6">
+ <legend i18n>Pools</legend>
+
+ <cd-mirroring-pools>
+ </cd-mirroring-pools>
+ </div>
+</div>
+
+<div class="row">
+ <div class="col-md-12">
+ <legend i18n>Images</legend>
+ <cd-mirroring-images>
+ </cd-mirroring-images>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.spec.ts
new file mode 100644
index 000000000..d771c2f70
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.spec.ts
@@ -0,0 +1,79 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule, NgbProgressbarModule } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { DaemonListComponent } from '../daemon-list/daemon-list.component';
+import { ImageListComponent } from '../image-list/image-list.component';
+import { MirrorHealthColorPipe } from '../mirror-health-color.pipe';
+import { PoolListComponent } from '../pool-list/pool-list.component';
+import { OverviewComponent } from './overview.component';
+
+describe('OverviewComponent', () => {
+ let component: OverviewComponent;
+ let fixture: ComponentFixture<OverviewComponent>;
+ let rbdMirroringService: RbdMirroringService;
+
+ configureTestBed({
+ declarations: [
+ DaemonListComponent,
+ ImageListComponent,
+ MirrorHealthColorPipe,
+ OverviewComponent,
+ PoolListComponent
+ ],
+ imports: [
+ BrowserAnimationsModule,
+ SharedModule,
+ NgbNavModule,
+ NgbProgressbarModule,
+ HttpClientTestingModule,
+ RouterTestingModule,
+ ReactiveFormsModule,
+ ToastrModule.forRoot()
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OverviewComponent);
+ component = fixture.componentInstance;
+ rbdMirroringService = TestBed.inject(RbdMirroringService);
+ component.siteName = 'site-A';
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('edit site name', () => {
+ beforeEach(() => {
+ spyOn(rbdMirroringService, 'getSiteName').and.callFake(() => of({ site_name: 'site-A' }));
+ spyOn(rbdMirroringService, 'refresh').and.stub();
+ fixture.detectChanges();
+ });
+
+ afterEach(() => {
+ expect(rbdMirroringService.refresh).toHaveBeenCalledTimes(1);
+ });
+
+ it('should call setSiteName', () => {
+ component.editing = true;
+ spyOn(rbdMirroringService, 'setSiteName').and.callFake(() => of({ site_name: 'new-site-A' }));
+
+ component.rbdmirroringForm.patchValue({
+ siteName: 'new-site-A'
+ });
+ component.updateSiteName();
+ expect(rbdMirroringService.setSiteName).toHaveBeenCalledWith('new-site-A');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.ts
new file mode 100644
index 000000000..3ee1fa813
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.ts
@@ -0,0 +1,122 @@
+import { Component, OnDestroy, OnInit } from '@angular/core';
+import { FormControl } from '@angular/forms';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { Subscription } from 'rxjs';
+
+import { Pool } from '~/app/ceph/pool/pool';
+import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { ViewCacheStatus } from '~/app/shared/enum/view-cache-status.enum';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { BootstrapCreateModalComponent } from '../bootstrap-create-modal/bootstrap-create-modal.component';
+import { BootstrapImportModalComponent } from '../bootstrap-import-modal/bootstrap-import-modal.component';
+
+@Component({
+ selector: 'cd-mirroring',
+ templateUrl: './overview.component.html',
+ styleUrls: ['./overview.component.scss']
+})
+export class OverviewComponent implements OnInit, OnDestroy {
+ rbdmirroringForm: CdFormGroup;
+ permission: Permission;
+ tableActions: CdTableAction[];
+ selection = new CdTableSelection();
+ modalRef: NgbModalRef;
+ peersExist = true;
+ siteName: any;
+ status: ViewCacheStatus;
+ private subs = new Subscription();
+ editing = false;
+
+ icons = Icons;
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private rbdMirroringService: RbdMirroringService,
+ private modalService: ModalService,
+ private taskWrapper: TaskWrapperService
+ ) {
+ this.permission = this.authStorageService.getPermissions().rbdMirroring;
+
+ const createBootstrapAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.upload,
+ click: () => this.createBootstrapModal(),
+ name: $localize`Create Bootstrap Token`,
+ canBePrimary: () => true,
+ disable: () => false
+ };
+ const importBootstrapAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.download,
+ click: () => this.importBootstrapModal(),
+ name: $localize`Import Bootstrap Token`,
+ disable: () => this.peersExist
+ };
+ this.tableActions = [createBootstrapAction, importBootstrapAction];
+ }
+
+ ngOnInit() {
+ this.createForm();
+ this.subs.add(this.rbdMirroringService.startPolling());
+ this.subs.add(
+ this.rbdMirroringService.subscribeSummary((data) => {
+ this.status = data.content_data.status;
+
+ this.peersExist = !!data.content_data.pools.find((o: Pool) => o['peer_uuids'].length > 0);
+ })
+ );
+ this.rbdMirroringService.getSiteName().subscribe((response: any) => {
+ this.siteName = response.site_name;
+ this.rbdmirroringForm.get('siteName').setValue(this.siteName);
+ });
+ }
+
+ private createForm() {
+ this.rbdmirroringForm = new CdFormGroup({
+ siteName: new FormControl({ value: '', disabled: true })
+ });
+ }
+
+ ngOnDestroy(): void {
+ this.subs.unsubscribe();
+ }
+
+ updateSiteName() {
+ if (this.editing) {
+ const action = this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('rbd/mirroring/site_name/edit', {}),
+ call: this.rbdMirroringService.setSiteName(this.rbdmirroringForm.getValue('siteName'))
+ });
+
+ action.subscribe({
+ complete: () => {
+ this.rbdMirroringService.refresh();
+ }
+ });
+ }
+ this.editing = !this.editing;
+ }
+
+ createBootstrapModal() {
+ const initialState = {
+ siteName: this.siteName
+ };
+ this.modalRef = this.modalService.show(BootstrapCreateModalComponent, initialState);
+ }
+
+ importBootstrapModal() {
+ const initialState = {
+ siteName: this.siteName
+ };
+ this.modalRef = this.modalService.show(BootstrapImportModalComponent, initialState);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html
new file mode 100644
index 000000000..00fe92b32
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html
@@ -0,0 +1,44 @@
+<cd-modal [modalRef]="activeModal"
+ pageURL="mirroring">
+ <ng-container i18n
+ class="modal-title">Edit pool mirror mode</ng-container>
+
+ <ng-container class="modal-content">
+ <form name="editModeForm"
+ class="form"
+ #formDir="ngForm"
+ [formGroup]="editModeForm"
+ novalidate>
+ <div class="modal-body">
+ <p>
+ <ng-container i18n>To edit the mirror mode for pool&nbsp;
+ <kbd>{{ poolName }}</kbd>, select a new mode from the list and click&nbsp;
+ <kbd>Update</kbd>.</ng-container>
+ </p>
+
+ <div class="form-group">
+ <label class="col-form-label"
+ for="mirrorMode">
+ <span i18n>Mode</span>
+ </label>
+ <select id="mirrorMode"
+ name="mirrorMode"
+ class="form-control"
+ formControlName="mirrorMode">
+ <option *ngFor="let mirrorMode of mirrorModes"
+ [value]="mirrorMode.id">{{ mirrorMode.name }}</option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="editModeForm.showError('mirrorMode', formDir, 'cannotDisable')"
+ i18n>Peer clusters must be removed prior to disabling mirror.</span>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="update()"
+ [form]="editModeForm"
+ [submitText]="actionLabels.UPDATE"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.spec.ts
new file mode 100644
index 000000000..11ba12334
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.spec.ts
@@ -0,0 +1,86 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { ActivatedRoute } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { ActivatedRouteStub } from '~/testing/activated-route-stub';
+import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
+import { PoolEditModeModalComponent } from './pool-edit-mode-modal.component';
+
+describe('PoolEditModeModalComponent', () => {
+ let component: PoolEditModeModalComponent;
+ let fixture: ComponentFixture<PoolEditModeModalComponent>;
+ let notificationService: NotificationService;
+ let rbdMirroringService: RbdMirroringService;
+ let formHelper: FormHelper;
+ let activatedRoute: ActivatedRouteStub;
+
+ configureTestBed({
+ declarations: [PoolEditModeModalComponent],
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ RouterTestingModule,
+ SharedModule,
+ ToastrModule.forRoot()
+ ],
+ providers: [
+ NgbActiveModal,
+ {
+ provide: ActivatedRoute,
+ useValue: new ActivatedRouteStub({ pool_name: 'somePool' })
+ }
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(PoolEditModeModalComponent);
+ component = fixture.componentInstance;
+ component.poolName = 'somePool';
+
+ notificationService = TestBed.inject(NotificationService);
+ spyOn(notificationService, 'show').and.stub();
+
+ rbdMirroringService = TestBed.inject(RbdMirroringService);
+ activatedRoute = <ActivatedRouteStub>TestBed.inject(ActivatedRoute);
+
+ formHelper = new FormHelper(component.editModeForm);
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('update pool mode', () => {
+ beforeEach(() => {
+ spyOn(component.activeModal, 'close').and.callThrough();
+ });
+
+ it('should call updatePool', () => {
+ activatedRoute.setParams({ pool_name: 'somePool' });
+ spyOn(rbdMirroringService, 'updatePool').and.callFake(() => of(''));
+
+ component.editModeForm.patchValue({ mirrorMode: 'disabled' });
+ component.update();
+ expect(rbdMirroringService.updatePool).toHaveBeenCalledWith('somePool', {
+ mirror_mode: 'disabled'
+ });
+ });
+ });
+
+ describe('form validation', () => {
+ it('should prevent disabling mirroring if peers exist', () => {
+ component.peerExists = true;
+ formHelper.expectErrorChange('mirrorMode', 'disabled', 'cannotDisable');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts
new file mode 100644
index 000000000..ef30c888c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts
@@ -0,0 +1,111 @@
+import { Location } from '@angular/common';
+import { Component, OnDestroy, OnInit } from '@angular/core';
+import { AbstractControl, FormControl, Validators } from '@angular/forms';
+import { ActivatedRoute } from '@angular/router';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { Subscription } from 'rxjs';
+
+import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { PoolEditModeResponseModel } from './pool-edit-mode-response.model';
+
+@Component({
+ selector: 'cd-pool-edit-mode-modal',
+ templateUrl: './pool-edit-mode-modal.component.html',
+ styleUrls: ['./pool-edit-mode-modal.component.scss']
+})
+export class PoolEditModeModalComponent implements OnInit, OnDestroy {
+ poolName: string;
+
+ subs: Subscription;
+
+ editModeForm: CdFormGroup;
+ bsConfig = {
+ containerClass: 'theme-default'
+ };
+ pattern: string;
+
+ response: PoolEditModeResponseModel;
+ peerExists = false;
+
+ mirrorModes: Array<{ id: string; name: string }> = [
+ { id: 'disabled', name: $localize`Disabled` },
+ { id: 'pool', name: $localize`Pool` },
+ { id: 'image', name: $localize`Image` }
+ ];
+
+ constructor(
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n,
+ private rbdMirroringService: RbdMirroringService,
+ private taskWrapper: TaskWrapperService,
+ private route: ActivatedRoute,
+ private location: Location
+ ) {
+ this.createForm();
+ }
+
+ createForm() {
+ this.editModeForm = new CdFormGroup({
+ mirrorMode: new FormControl('', {
+ validators: [Validators.required, this.validateMode.bind(this)]
+ })
+ });
+ }
+
+ ngOnInit() {
+ this.route.params.subscribe((params: { pool_name: string }) => {
+ this.poolName = params.pool_name;
+ });
+ this.pattern = `${this.poolName}`;
+ this.rbdMirroringService.getPool(this.poolName).subscribe((resp: PoolEditModeResponseModel) => {
+ this.setResponse(resp);
+ });
+
+ this.subs = this.rbdMirroringService.subscribeSummary((data) => {
+ this.peerExists = false;
+ const poolData = data.content_data.pools;
+ const pool = poolData.find((o: any) => this.poolName === o['name']);
+ this.peerExists = pool && pool['peer_uuids'].length;
+ });
+ }
+
+ ngOnDestroy(): void {
+ this.subs.unsubscribe();
+ }
+
+ validateMode(control: AbstractControl) {
+ if (control.value === 'disabled' && this.peerExists) {
+ return { cannotDisable: { value: control.value } };
+ }
+ return null;
+ }
+
+ setResponse(response: PoolEditModeResponseModel) {
+ this.editModeForm.get('mirrorMode').setValue(response.mirror_mode);
+ }
+
+ update() {
+ const request = new PoolEditModeResponseModel();
+ request.mirror_mode = this.editModeForm.getValue('mirrorMode');
+
+ const action = this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('rbd/mirroring/pool/edit', {
+ pool_name: this.poolName
+ }),
+ call: this.rbdMirroringService.updatePool(this.poolName, request)
+ });
+
+ action.subscribe({
+ error: () => this.editModeForm.setErrors({ cdSubmitButton: true }),
+ complete: () => {
+ this.rbdMirroringService.refresh();
+ this.location.back();
+ }
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-response.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-response.model.ts
new file mode 100644
index 000000000..ba8bc677c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-response.model.ts
@@ -0,0 +1,3 @@
+export class PoolEditModeResponseModel {
+ mirror_mode: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html
new file mode 100644
index 000000000..97774ebe3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html
@@ -0,0 +1,100 @@
+<cd-modal [modalRef]="activeModal">
+ <span class="modal-title"
+ i18n>{mode, select, edit {Edit} other {Add}} pool mirror peer</span>
+
+ <ng-container class="modal-content">
+ <form name="editPeerForm"
+ class="form"
+ #formDir="ngForm"
+ [formGroup]="editPeerForm"
+ novalidate>
+ <div class="modal-body">
+ <p>
+ <span i18n>{mode, select, edit {Edit} other {Add}} the pool
+ mirror peer attributes for pool <kbd>{{ poolName }}</kbd> and click
+ <kbd>Submit</kbd>.</span>
+ </p>
+
+ <div class="form-group">
+ <label class="col-form-label required"
+ for="clusterName"
+ i18n>Cluster Name</label>
+ <input class="form-control"
+ type="text"
+ placeholder="Name..."
+ i18n-placeholder
+ id="clusterName"
+ name="clusterName"
+ formControlName="clusterName"
+ autofocus>
+ <span class="invalid-feedback"
+ *ngIf="editPeerForm.showError('clusterName', formDir, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="editPeerForm.showError('clusterName', formDir, 'invalidClusterName')"
+ i18n>The cluster name is not valid.</span>
+ </div>
+
+ <div class="form-group">
+ <label class="col-form-label required"
+ for="clientID"
+ i18n>CephX ID</label>
+ <input class="form-control"
+ type="text"
+ placeholder="CephX ID..."
+ i18n-placeholder
+ id="clientID"
+ name="clientID"
+ formControlName="clientID">
+ <span class="invalid-feedback"
+ *ngIf="editPeerForm.showError('clientID', formDir, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="editPeerForm.showError('clientID', formDir, 'invalidClientID')"
+ i18n>The CephX ID is not valid.</span>
+ </div>
+
+ <div class="form-group">
+ <label class="col-form-label"
+ for="monAddr">
+ <span i18n>Monitor Addresses</span>
+ </label>
+ <input class="form-control"
+ type="text"
+ placeholder="Comma-delimited addresses..."
+ i18n-placeholder
+ id="monAddr"
+ name="monAddr"
+ formControlName="monAddr">
+ <span class="invalid-feedback"
+ *ngIf="editPeerForm.showError('monAddr', formDir, 'invalidMonAddr')"
+ i18n>The monitory address is not valid.</span>
+ </div>
+
+ <div class="form-group">
+ <label class="col-form-label"
+ for="key">
+ <span i18n>CephX Key</span>
+ </label>
+ <input class="form-control"
+ type="text"
+ placeholder="Base64-encoded key..."
+ i18n-placeholder
+ id="key"
+ name="key"
+ formControlName="key">
+ <span class="invalid-feedback"
+ *ngIf="editPeerForm.showError('key', formDir, 'invalidKey')"
+ i18n>CephX key must be base64 encoded.</span>
+ </div>
+
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="update()"
+ [form]="editPeerForm"
+ [submitText]="actionLabels.SUBMIT"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.spec.ts
new file mode 100644
index 000000000..96efaa539
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.spec.ts
@@ -0,0 +1,148 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
+import { PoolEditPeerModalComponent } from './pool-edit-peer-modal.component';
+import { PoolEditPeerResponseModel } from './pool-edit-peer-response.model';
+
+describe('PoolEditPeerModalComponent', () => {
+ let component: PoolEditPeerModalComponent;
+ let fixture: ComponentFixture<PoolEditPeerModalComponent>;
+ let notificationService: NotificationService;
+ let rbdMirroringService: RbdMirroringService;
+ let formHelper: FormHelper;
+
+ configureTestBed({
+ declarations: [PoolEditPeerModalComponent],
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ RouterTestingModule,
+ SharedModule,
+ ToastrModule.forRoot()
+ ],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(PoolEditPeerModalComponent);
+ component = fixture.componentInstance;
+ component.mode = 'add';
+ component.poolName = 'somePool';
+
+ notificationService = TestBed.inject(NotificationService);
+ spyOn(notificationService, 'show').and.stub();
+
+ rbdMirroringService = TestBed.inject(RbdMirroringService);
+
+ formHelper = new FormHelper(component.editPeerForm);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('add pool peer', () => {
+ beforeEach(() => {
+ component.mode = 'add';
+ component.peerUUID = undefined;
+ spyOn(rbdMirroringService, 'refresh').and.stub();
+ spyOn(component.activeModal, 'close').and.callThrough();
+ fixture.detectChanges();
+ });
+
+ afterEach(() => {
+ expect(rbdMirroringService.refresh).toHaveBeenCalledTimes(1);
+ expect(component.activeModal.close).toHaveBeenCalledTimes(1);
+ });
+
+ it('should call addPeer', () => {
+ spyOn(rbdMirroringService, 'addPeer').and.callFake(() => of(''));
+
+ component.editPeerForm.patchValue({
+ clusterName: 'cluster',
+ clientID: 'id',
+ monAddr: 'mon_host',
+ key: 'dGVzdA=='
+ });
+
+ component.update();
+ expect(rbdMirroringService.addPeer).toHaveBeenCalledWith('somePool', {
+ cluster_name: 'cluster',
+ client_id: 'id',
+ mon_host: 'mon_host',
+ key: 'dGVzdA=='
+ });
+ });
+ });
+
+ describe('edit pool peer', () => {
+ beforeEach(() => {
+ component.mode = 'edit';
+ component.peerUUID = 'somePeer';
+
+ const response = new PoolEditPeerResponseModel();
+ response.uuid = 'somePeer';
+ response.cluster_name = 'cluster';
+ response.client_id = 'id';
+ response.mon_host = '1.2.3.4:1234';
+ response.key = 'dGVzdA==';
+
+ spyOn(rbdMirroringService, 'getPeer').and.callFake(() => of(response));
+ spyOn(rbdMirroringService, 'refresh').and.stub();
+ spyOn(component.activeModal, 'close').and.callThrough();
+ fixture.detectChanges();
+ });
+
+ afterEach(() => {
+ expect(rbdMirroringService.getPeer).toHaveBeenCalledWith('somePool', 'somePeer');
+ expect(rbdMirroringService.refresh).toHaveBeenCalledTimes(1);
+ expect(component.activeModal.close).toHaveBeenCalledTimes(1);
+ });
+
+ it('should call updatePeer', () => {
+ spyOn(rbdMirroringService, 'updatePeer').and.callFake(() => of(''));
+
+ component.update();
+ expect(rbdMirroringService.updatePeer).toHaveBeenCalledWith('somePool', 'somePeer', {
+ cluster_name: 'cluster',
+ client_id: 'id',
+ mon_host: '1.2.3.4:1234',
+ key: 'dGVzdA=='
+ });
+ });
+ });
+
+ describe('form validation', () => {
+ beforeEach(() => {
+ fixture.detectChanges();
+ });
+
+ it('should validate cluster name', () => {
+ formHelper.expectErrorChange('clusterName', '', 'required');
+ formHelper.expectErrorChange('clusterName', ' ', 'invalidClusterName');
+ });
+
+ it('should validate client ID', () => {
+ formHelper.expectErrorChange('clientID', '', 'required');
+ formHelper.expectErrorChange('clientID', 'client.id', 'invalidClientID');
+ });
+
+ it('should validate monitor address', () => {
+ formHelper.expectErrorChange('monAddr', '@', 'invalidMonAddr');
+ });
+
+ it('should validate key', () => {
+ formHelper.expectErrorChange('key', '(', 'invalidKey');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.ts
new file mode 100644
index 000000000..6569c3b24
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.ts
@@ -0,0 +1,141 @@
+import { Component, OnInit } from '@angular/core';
+import { AbstractControl, FormControl, Validators } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { PoolEditPeerResponseModel } from './pool-edit-peer-response.model';
+
+@Component({
+ selector: 'cd-pool-edit-peer-modal',
+ templateUrl: './pool-edit-peer-modal.component.html',
+ styleUrls: ['./pool-edit-peer-modal.component.scss']
+})
+export class PoolEditPeerModalComponent implements OnInit {
+ mode: string;
+ poolName: string;
+ peerUUID: string;
+
+ editPeerForm: CdFormGroup;
+ bsConfig = {
+ containerClass: 'theme-default'
+ };
+ pattern: string;
+
+ response: PoolEditPeerResponseModel;
+
+ constructor(
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n,
+ private rbdMirroringService: RbdMirroringService,
+ private taskWrapper: TaskWrapperService
+ ) {
+ this.createForm();
+ }
+
+ createForm() {
+ this.editPeerForm = new CdFormGroup({
+ clusterName: new FormControl('', {
+ validators: [Validators.required, this.validateClusterName]
+ }),
+ clientID: new FormControl('', {
+ validators: [Validators.required, this.validateClientID]
+ }),
+ monAddr: new FormControl('', {
+ validators: [this.validateMonAddr]
+ }),
+ key: new FormControl('', {
+ validators: [this.validateKey]
+ })
+ });
+ }
+
+ ngOnInit() {
+ this.pattern = `${this.poolName}/${this.peerUUID}`;
+ if (this.mode === 'edit') {
+ this.rbdMirroringService
+ .getPeer(this.poolName, this.peerUUID)
+ .subscribe((resp: PoolEditPeerResponseModel) => {
+ this.setResponse(resp);
+ });
+ }
+ }
+
+ validateClusterName(control: AbstractControl) {
+ if (!control.value.match(/^[\w\-_]*$/)) {
+ return { invalidClusterName: { value: control.value } };
+ }
+
+ return undefined;
+ }
+
+ validateClientID(control: AbstractControl) {
+ if (!control.value.match(/^(?!client\.)[\w\-_.]*$/)) {
+ return { invalidClientID: { value: control.value } };
+ }
+
+ return undefined;
+ }
+
+ validateMonAddr(control: AbstractControl) {
+ if (!control.value.match(/^[,; ]*([\w.\-_\[\]]+(:[\d]+)?[,; ]*)*$/)) {
+ return { invalidMonAddr: { value: control.value } };
+ }
+
+ return undefined;
+ }
+
+ validateKey(control: AbstractControl) {
+ try {
+ if (control.value === '' || !!atob(control.value)) {
+ return null;
+ }
+ } catch (error) {}
+ return { invalidKey: { value: control.value } };
+ }
+
+ setResponse(response: PoolEditPeerResponseModel) {
+ this.response = response;
+ this.editPeerForm.get('clusterName').setValue(response.cluster_name);
+ this.editPeerForm.get('clientID').setValue(response.client_id);
+ this.editPeerForm.get('monAddr').setValue(response.mon_host);
+ this.editPeerForm.get('key').setValue(response.key);
+ }
+
+ update() {
+ const request = new PoolEditPeerResponseModel();
+ request.cluster_name = this.editPeerForm.getValue('clusterName');
+ request.client_id = this.editPeerForm.getValue('clientID');
+ request.mon_host = this.editPeerForm.getValue('monAddr');
+ request.key = this.editPeerForm.getValue('key');
+
+ let action;
+ if (this.mode === 'edit') {
+ action = this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('rbd/mirroring/peer/edit', {
+ pool_name: this.poolName
+ }),
+ call: this.rbdMirroringService.updatePeer(this.poolName, this.peerUUID, request)
+ });
+ } else {
+ action = this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('rbd/mirroring/peer/add', {
+ pool_name: this.poolName
+ }),
+ call: this.rbdMirroringService.addPeer(this.poolName, request)
+ });
+ }
+
+ action.subscribe({
+ error: () => this.editPeerForm.setErrors({ cdSubmitButton: true }),
+ complete: () => {
+ this.rbdMirroringService.refresh();
+ this.activeModal.close();
+ }
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-response.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-response.model.ts
new file mode 100644
index 000000000..fb9c67fcb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-response.model.ts
@@ -0,0 +1,7 @@
+export class PoolEditPeerResponseModel {
+ cluster_name: string;
+ client_id: string;
+ mon_host: string;
+ key: string;
+ uuid: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.html
new file mode 100644
index 000000000..1e4e72df1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.html
@@ -0,0 +1,23 @@
+<cd-table [data]="data"
+ columnMode="flex"
+ [columns]="columns"
+ identifier="name"
+ forceIdentifier="true"
+ [autoReload]="-1"
+ (fetchData)="refresh()"
+ selectionType="single"
+ (updateSelection)="updateSelection($event)"
+ [status]="tableStatus">
+ <cd-table-actions class="table-actions"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+</cd-table>
+
+<ng-template #healthTmpl
+ let-row="row"
+ let-value="value">
+ <span [ngClass]="row.health_color | mirrorHealthColor">{{ value }}</span>
+</ng-template>
+<router-outlet name="modal"></router-outlet>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.spec.ts
new file mode 100644
index 000000000..bb5865039
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.spec.ts
@@ -0,0 +1,37 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { MirrorHealthColorPipe } from '../mirror-health-color.pipe';
+import { PoolListComponent } from './pool-list.component';
+
+describe('PoolListComponent', () => {
+ let component: PoolListComponent;
+ let fixture: ComponentFixture<PoolListComponent>;
+
+ configureTestBed({
+ declarations: [PoolListComponent, MirrorHealthColorPipe],
+ imports: [
+ BrowserAnimationsModule,
+ SharedModule,
+ HttpClientTestingModule,
+ RouterTestingModule,
+ ToastrModule.forRoot()
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(PoolListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.ts
new file mode 100644
index 000000000..a5e1c9e4b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.ts
@@ -0,0 +1,174 @@
+import { Component, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
+import { Router } from '@angular/router';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { Observable, Subscriber, Subscription } from 'rxjs';
+
+import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
+import { TableStatusViewCache } from '~/app/shared/classes/table-status-view-cache';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { URLVerbs } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { PoolEditPeerModalComponent } from '../pool-edit-peer-modal/pool-edit-peer-modal.component';
+
+const BASE_URL = '/block/mirroring';
+@Component({
+ selector: 'cd-mirroring-pools',
+ templateUrl: './pool-list.component.html',
+ styleUrls: ['./pool-list.component.scss']
+})
+export class PoolListComponent implements OnInit, OnDestroy {
+ @ViewChild('healthTmpl', { static: true })
+ healthTmpl: TemplateRef<any>;
+
+ subs: Subscription;
+
+ permission: Permission;
+ tableActions: CdTableAction[];
+ selection = new CdTableSelection();
+
+ modalRef: NgbModalRef;
+
+ data: [];
+ columns: {};
+
+ tableStatus = new TableStatusViewCache();
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private rbdMirroringService: RbdMirroringService,
+ private modalService: ModalService,
+ private taskWrapper: TaskWrapperService,
+ private router: Router
+ ) {
+ this.data = [];
+ this.permission = this.authStorageService.getPermissions().rbdMirroring;
+
+ const editModeAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.edit,
+ click: () => this.editModeModal(),
+ name: $localize`Edit Mode`,
+ canBePrimary: () => true
+ };
+ const addPeerAction: CdTableAction = {
+ permission: 'create',
+ icon: Icons.add,
+ name: $localize`Add Peer`,
+ click: () => this.editPeersModal('add'),
+ disable: () => !this.selection.first() || this.selection.first().mirror_mode === 'disabled',
+ visible: () => !this.getPeerUUID(),
+ canBePrimary: () => false
+ };
+ const editPeerAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.exchange,
+ name: $localize`Edit Peer`,
+ click: () => this.editPeersModal('edit'),
+ visible: () => !!this.getPeerUUID()
+ };
+ const deletePeerAction: CdTableAction = {
+ permission: 'delete',
+ icon: Icons.destroy,
+ name: $localize`Delete Peer`,
+ click: () => this.deletePeersModal(),
+ visible: () => !!this.getPeerUUID()
+ };
+ this.tableActions = [editModeAction, addPeerAction, editPeerAction, deletePeerAction];
+ }
+
+ ngOnInit() {
+ this.columns = [
+ { prop: 'name', name: $localize`Name`, flexGrow: 2 },
+ { prop: 'mirror_mode', name: $localize`Mode`, flexGrow: 2 },
+ { prop: 'leader_id', name: $localize`Leader`, flexGrow: 2 },
+ { prop: 'image_local_count', name: $localize`# Local`, flexGrow: 2 },
+ { prop: 'image_remote_count', name: $localize`# Remote`, flexGrow: 2 },
+ {
+ prop: 'health',
+ name: $localize`Health`,
+ cellTemplate: this.healthTmpl,
+ flexGrow: 1
+ }
+ ];
+
+ this.subs = this.rbdMirroringService.subscribeSummary((data) => {
+ this.data = data.content_data.pools;
+ this.tableStatus = new TableStatusViewCache(data.status);
+ });
+ }
+
+ ngOnDestroy(): void {
+ this.subs.unsubscribe();
+ }
+
+ refresh() {
+ this.rbdMirroringService.refresh();
+ }
+
+ editModeModal() {
+ this.router.navigate([
+ BASE_URL,
+ { outlets: { modal: [URLVerbs.EDIT, this.selection.first().name] } }
+ ]);
+ }
+
+ editPeersModal(mode: string) {
+ const initialState = {
+ poolName: this.selection.first().name,
+ mode: mode
+ };
+ if (mode === 'edit') {
+ initialState['peerUUID'] = this.getPeerUUID();
+ }
+ this.modalRef = this.modalService.show(PoolEditPeerModalComponent, initialState);
+ }
+
+ deletePeersModal() {
+ const poolName = this.selection.first().name;
+ const peerUUID = this.getPeerUUID();
+
+ this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: $localize`mirror peer`,
+ itemNames: [`${poolName} (${peerUUID})`],
+ submitActionObservable: () =>
+ new Observable((observer: Subscriber<any>) => {
+ this.taskWrapper
+ .wrapTaskAroundCall({
+ task: new FinishedTask('rbd/mirroring/peer/delete', {
+ pool_name: poolName
+ }),
+ call: this.rbdMirroringService.deletePeer(poolName, peerUUID)
+ })
+ .subscribe({
+ error: (resp) => observer.error(resp),
+ complete: () => {
+ this.rbdMirroringService.refresh();
+ observer.complete();
+ }
+ });
+ })
+ });
+ }
+
+ getPeerUUID(): any {
+ const selection = this.selection.first();
+ const pool = this.data.find((o) => selection && selection.name === o['name']);
+ if (pool && pool['peer_uuids']) {
+ return pool['peer_uuids'][0];
+ }
+
+ return undefined;
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html
new file mode 100644
index 000000000..130aa3286
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html
@@ -0,0 +1,74 @@
+<fieldset #cfgFormGroup
+ [formGroup]="form.get('configuration')">
+ <legend i18n>RBD Configuration</legend>
+
+ <div *ngFor="let section of rbdConfigurationService.sections"
+ class="col-12">
+ <h4 class="cd-header">
+ <span (click)="toggleSectionVisibility(section.class)"
+ class="collapsible">
+ {{ section.heading }} <i [ngClass]="!sectionVisibility[section.class] ? icons.addCircle : icons.minusCircle"
+ aria-hidden="true"></i>
+ </span>
+ </h4>
+ <div class="{{ section.class }}"
+ [hidden]="!sectionVisibility[section.class]">
+ <div class="form-group row"
+ *ngFor="let option of section.options">
+ <label class="cd-col-form-label"
+ [for]="option.name">{{ option.displayName }}<cd-helper>{{ option.description }}</cd-helper></label>
+
+ <div class="cd-col-form-input {{ section.heading }}">
+ <div class="input-group">
+ <ng-container [ngSwitch]="option.type">
+ <ng-container *ngSwitchCase="configurationType.milliseconds">
+ <input [id]="option.name"
+ [name]="option.name"
+ [formControlName]="option.name"
+ type="text"
+ class="form-control"
+ [ngDataReady]="ngDataReady"
+ cdMilliseconds>
+ </ng-container>
+ <ng-container *ngSwitchCase="configurationType.bps">
+ <input [id]="option.name"
+ [name]="option.name"
+ [formControlName]="option.name"
+ type="text"
+ class="form-control"
+ defaultUnit="b"
+ [ngDataReady]="ngDataReady"
+ cdDimlessBinaryPerSecond>
+ </ng-container>
+ <ng-container *ngSwitchCase="configurationType.iops">
+ <input [id]="option.name"
+ [name]="option.name"
+ [formControlName]="option.name"
+ type="text"
+ class="form-control"
+ [ngDataReady]="ngDataReady"
+ cdIops>
+ </ng-container>
+ </ng-container>
+ <span class="input-group-append">
+ <button class="btn btn-light"
+ type="button"
+ data-toggle="button"
+ [ngClass]="{'active': isDisabled(option.name)}"
+ title="Remove the local configuration value. The parent configuration value will be inherited and used instead."
+ i18n-title
+ (click)="reset(option.name)">
+ <i [ngClass]="[icons.erase]"
+ aria-hidden="true"></i>
+ </button>
+ </span>
+ </div>
+ <span i18n
+ class="invalid-feedback"
+ *ngIf="form.showError('configuration.' + option.name, cfgFormGroup, 'min')">The minimum value is 0</span>
+ </div>
+ </div>
+ </div>
+ </div>
+
+</fieldset>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.scss
new file mode 100644
index 000000000..ba6460c32
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.scss
@@ -0,0 +1,4 @@
+.collapsible {
+ cursor: pointer;
+ user-select: none;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.spec.ts
new file mode 100644
index 000000000..833a649da
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.spec.ts
@@ -0,0 +1,294 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { By } from '@angular/platform-browser';
+
+import { ReplaySubject } from 'rxjs';
+
+import { DirectivesModule } from '~/app/shared/directives/directives.module';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { RbdConfigurationSourceField } from '~/app/shared/models/configuration';
+import { DimlessBinaryPerSecondPipe } from '~/app/shared/pipes/dimless-binary-per-second.pipe';
+import { FormatterService } from '~/app/shared/services/formatter.service';
+import { RbdConfigurationService } from '~/app/shared/services/rbd-configuration.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
+import { RbdConfigurationFormComponent } from './rbd-configuration-form.component';
+
+describe('RbdConfigurationFormComponent', () => {
+ let component: RbdConfigurationFormComponent;
+ let fixture: ComponentFixture<RbdConfigurationFormComponent>;
+ let sections: any[];
+ let fh: FormHelper;
+
+ configureTestBed({
+ imports: [ReactiveFormsModule, DirectivesModule, SharedModule],
+ declarations: [RbdConfigurationFormComponent],
+ providers: [RbdConfigurationService, FormatterService, DimlessBinaryPerSecondPipe]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RbdConfigurationFormComponent);
+ component = fixture.componentInstance;
+ component.form = new CdFormGroup({}, null);
+ fh = new FormHelper(component.form);
+ fixture.detectChanges();
+ sections = TestBed.inject(RbdConfigurationService).sections;
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should create all form fields mentioned in RbdConfiguration::OPTIONS', () => {
+ /* Test form creation on a TypeScript level */
+ const actual = Object.keys((component.form.get('configuration') as CdFormGroup).controls);
+ const expected = sections
+ .map((section) => section.options)
+ .reduce((a, b) => a.concat(b))
+ .map((option: Record<string, any>) => option.name);
+ expect(actual).toEqual(expected);
+
+ /* Test form creation on a template level */
+ const controlDebugElements = fixture.debugElement.queryAll(By.css('input.form-control'));
+ expect(controlDebugElements.length).toBe(expected.length);
+ controlDebugElements.forEach((element) => expect(element.nativeElement).toBeTruthy());
+ });
+
+ it('should only contain values of changed controls if submitted', () => {
+ let values = {};
+ component.changes.subscribe((getDirtyValues: Function) => {
+ values = getDirtyValues();
+ });
+ fh.setValue('configuration.rbd_qos_bps_limit', 0, true);
+ fixture.detectChanges();
+
+ expect(values).toEqual({ rbd_qos_bps_limit: 0 });
+ });
+
+ describe('test loading of initial data for editing', () => {
+ beforeEach(() => {
+ component.initializeData = new ReplaySubject<any>(1);
+ fixture.detectChanges();
+ component.ngOnInit();
+ });
+
+ it('should return dirty values without any units', () => {
+ let dirtyValues = {};
+ component.changes.subscribe((getDirtyValues: Function) => {
+ dirtyValues = getDirtyValues();
+ });
+
+ fh.setValue('configuration.rbd_qos_bps_limit', 55, true);
+ fh.setValue('configuration.rbd_qos_iops_limit', 22, true);
+
+ expect(dirtyValues['rbd_qos_bps_limit']).toBe(55);
+ expect(dirtyValues['rbd_qos_iops_limit']).toBe(22);
+ });
+
+ it('should load initial data into forms', () => {
+ component.initializeData.next({
+ initialData: [
+ {
+ name: 'rbd_qos_bps_limit',
+ value: 55,
+ source: 1
+ }
+ ],
+ sourceType: RbdConfigurationSourceField.pool
+ });
+
+ expect(component.form.getValue('configuration.rbd_qos_bps_limit')).toEqual('55 B/s');
+ });
+
+ it('should not load initial data if the source is not the pool itself', () => {
+ component.initializeData.next({
+ initialData: [
+ {
+ name: 'rbd_qos_bps_limit',
+ value: 55,
+ source: RbdConfigurationSourceField.image
+ },
+ {
+ name: 'rbd_qos_iops_limit',
+ value: 22,
+ source: RbdConfigurationSourceField.global
+ }
+ ],
+ sourceType: RbdConfigurationSourceField.pool
+ });
+
+ expect(component.form.getValue('configuration.rbd_qos_iops_limit')).toEqual('0 IOPS');
+ expect(component.form.getValue('configuration.rbd_qos_bps_limit')).toEqual('0 B/s');
+ });
+
+ it('should not load initial data if the source is not the image itself', () => {
+ component.initializeData.next({
+ initialData: [
+ {
+ name: 'rbd_qos_bps_limit',
+ value: 55,
+ source: RbdConfigurationSourceField.pool
+ },
+ {
+ name: 'rbd_qos_iops_limit',
+ value: 22,
+ source: RbdConfigurationSourceField.global
+ }
+ ],
+ sourceType: RbdConfigurationSourceField.image
+ });
+
+ expect(component.form.getValue('configuration.rbd_qos_iops_limit')).toEqual('0 IOPS');
+ expect(component.form.getValue('configuration.rbd_qos_bps_limit')).toEqual('0 B/s');
+ });
+
+ it('should always have formatted results', () => {
+ component.initializeData.next({
+ initialData: [
+ {
+ name: 'rbd_qos_bps_limit',
+ value: 55,
+ source: RbdConfigurationSourceField.image
+ },
+ {
+ name: 'rbd_qos_iops_limit',
+ value: 22,
+ source: RbdConfigurationSourceField.image
+ },
+ {
+ name: 'rbd_qos_read_bps_limit',
+ value: null, // incorrect type
+ source: RbdConfigurationSourceField.image
+ },
+ {
+ name: 'rbd_qos_read_bps_limit',
+ value: undefined, // incorrect type
+ source: RbdConfigurationSourceField.image
+ }
+ ],
+ sourceType: RbdConfigurationSourceField.image
+ });
+
+ expect(component.form.getValue('configuration.rbd_qos_iops_limit')).toEqual('22 IOPS');
+ expect(component.form.getValue('configuration.rbd_qos_bps_limit')).toEqual('55 B/s');
+ expect(component.form.getValue('configuration.rbd_qos_read_bps_limit')).toEqual('0 B/s');
+ expect(component.form.getValue('configuration.rbd_qos_read_bps_limit')).toEqual('0 B/s');
+ });
+ });
+
+ it('should reset the corresponding form field correctly', () => {
+ const fieldName = 'rbd_qos_bps_limit';
+ const getValue = () => component.form.get(`configuration.${fieldName}`).value;
+
+ // Initialization
+ fh.setValue(`configuration.${fieldName}`, 418, true);
+ expect(getValue()).toBe(418);
+
+ // Reset
+ component.reset(fieldName);
+ expect(getValue()).toBe(null);
+
+ // Restore
+ component.reset(fieldName);
+ expect(getValue()).toBe(418);
+
+ // Reset
+ component.reset(fieldName);
+ expect(getValue()).toBe(null);
+
+ // Restore
+ component.reset(fieldName);
+ expect(getValue()).toBe(418);
+ });
+
+ describe('should verify that getDirtyValues() returns correctly', () => {
+ let data: any;
+
+ beforeEach(() => {
+ component.initializeData = new ReplaySubject<any>(1);
+ fixture.detectChanges();
+ component.ngOnInit();
+ data = {
+ initialData: [
+ {
+ name: 'rbd_qos_bps_limit',
+ value: 0,
+ source: RbdConfigurationSourceField.image
+ },
+ {
+ name: 'rbd_qos_iops_limit',
+ value: 0,
+ source: RbdConfigurationSourceField.image
+ },
+ {
+ name: 'rbd_qos_read_bps_limit',
+ value: 0,
+ source: RbdConfigurationSourceField.image
+ },
+ {
+ name: 'rbd_qos_read_iops_limit',
+ value: 0,
+ source: RbdConfigurationSourceField.image
+ },
+ {
+ name: 'rbd_qos_read_iops_burst',
+ value: 0,
+ source: RbdConfigurationSourceField.image
+ },
+ {
+ name: 'rbd_qos_write_bps_burst',
+ value: undefined,
+ source: RbdConfigurationSourceField.global
+ },
+ {
+ name: 'rbd_qos_write_iops_burst',
+ value: null,
+ source: RbdConfigurationSourceField.global
+ }
+ ],
+ sourceType: RbdConfigurationSourceField.image
+ };
+ component.initializeData.next(data);
+ });
+
+ it('should return an empty object', () => {
+ expect(component.getDirtyValues()).toEqual({});
+ expect(component.getDirtyValues(true, RbdConfigurationSourceField.image)).toEqual({});
+ });
+
+ it('should return dirty values', () => {
+ component.form.get('configuration.rbd_qos_write_bps_burst').markAsDirty();
+ expect(component.getDirtyValues()).toEqual({ rbd_qos_write_bps_burst: 0 });
+
+ component.form.get('configuration.rbd_qos_write_iops_burst').markAsDirty();
+ expect(component.getDirtyValues()).toEqual({
+ rbd_qos_write_iops_burst: 0,
+ rbd_qos_write_bps_burst: 0
+ });
+ });
+
+ it('should also return all local values if they do not contain their initial values', () => {
+ // Change value for all options
+ data.initialData = data.initialData.map((o: Record<string, any>) => {
+ o.value = 22;
+ return o;
+ });
+
+ // Mark some dirty
+ ['rbd_qos_read_iops_limit', 'rbd_qos_write_bps_burst'].forEach((option) => {
+ component.form.get(`configuration.${option}`).markAsDirty();
+ });
+
+ expect(component.getDirtyValues(true, RbdConfigurationSourceField.image)).toEqual({
+ rbd_qos_read_iops_limit: 0,
+ rbd_qos_write_bps_burst: 0
+ });
+ });
+
+ it('should throw an error if used incorrectly', () => {
+ expect(() => component.getDirtyValues(true)).toThrowError(
+ /^ProgrammingError: If local values shall be included/
+ );
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.ts
new file mode 100644
index 000000000..3ced71f02
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.ts
@@ -0,0 +1,166 @@
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { FormControl, Validators } from '@angular/forms';
+
+import _ from 'lodash';
+import { ReplaySubject } from 'rxjs';
+
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import {
+ RbdConfigurationEntry,
+ RbdConfigurationSourceField,
+ RbdConfigurationType
+} from '~/app/shared/models/configuration';
+import { FormatterService } from '~/app/shared/services/formatter.service';
+import { RbdConfigurationService } from '~/app/shared/services/rbd-configuration.service';
+
+@Component({
+ selector: 'cd-rbd-configuration-form',
+ templateUrl: './rbd-configuration-form.component.html',
+ styleUrls: ['./rbd-configuration-form.component.scss']
+})
+export class RbdConfigurationFormComponent implements OnInit {
+ @Input()
+ form: CdFormGroup;
+ @Input()
+ initializeData = new ReplaySubject<{
+ initialData: RbdConfigurationEntry[];
+ sourceType: RbdConfigurationSourceField;
+ }>(1);
+ @Output()
+ changes = new EventEmitter<any>();
+
+ icons = Icons;
+
+ ngDataReady = new EventEmitter<any>();
+ initialData: RbdConfigurationEntry[];
+ configurationType = RbdConfigurationType;
+ sectionVisibility: { [key: string]: boolean } = {};
+
+ constructor(
+ public formatterService: FormatterService,
+ public rbdConfigurationService: RbdConfigurationService
+ ) {}
+
+ ngOnInit() {
+ const configFormGroup = this.createConfigurationFormGroup();
+ this.form.addControl('configuration', configFormGroup);
+
+ // Listen to changes and emit the values to the parent component
+ configFormGroup.valueChanges.subscribe(() => {
+ this.changes.emit(this.getDirtyValues.bind(this));
+ });
+
+ if (this.initializeData) {
+ this.initializeData.subscribe((data: Record<string, any>) => {
+ this.initialData = data.initialData;
+ const dataType = data.sourceType;
+ this.rbdConfigurationService.getWritableOptionFields().forEach((option) => {
+ const optionData = data.initialData
+ .filter((entry: Record<string, any>) => entry.name === option.name)
+ .pop();
+ if (optionData && optionData['source'] === dataType) {
+ this.form.get(`configuration.${option.name}`).setValue(optionData['value']);
+ }
+ });
+ this.ngDataReady.emit();
+ });
+ }
+
+ this.rbdConfigurationService
+ .getWritableSections()
+ .forEach((section) => (this.sectionVisibility[section.class] = false));
+ }
+
+ getDirtyValues(includeLocalValues = false, localFieldType?: RbdConfigurationSourceField) {
+ if (includeLocalValues && !localFieldType) {
+ const msg =
+ 'ProgrammingError: If local values shall be included, a proper localFieldType argument has to be provided, too';
+ throw new Error(msg);
+ }
+ const result = {};
+
+ this.rbdConfigurationService.getWritableOptionFields().forEach((config) => {
+ const control: any = this.form.get('configuration').get(config.name);
+ const dirty = control.dirty;
+
+ if (this.initialData && this.initialData[config.name] === control.value) {
+ return; // Skip controls with initial data loaded
+ }
+
+ if (dirty || (includeLocalValues && control['source'] === localFieldType)) {
+ if (control.value === null) {
+ result[config.name] = control.value;
+ } else if (config.type === RbdConfigurationType.bps) {
+ result[config.name] = this.formatterService.toBytes(control.value);
+ } else if (config.type === RbdConfigurationType.milliseconds) {
+ result[config.name] = this.formatterService.toMilliseconds(control.value);
+ } else if (config.type === RbdConfigurationType.iops) {
+ result[config.name] = this.formatterService.toIops(control.value);
+ } else {
+ result[config.name] = control.value;
+ }
+ }
+ });
+
+ return result;
+ }
+
+ /**
+ * Dynamically create form controls.
+ */
+ private createConfigurationFormGroup() {
+ const configFormGroup = new CdFormGroup({});
+
+ this.rbdConfigurationService.getWritableOptionFields().forEach((c) => {
+ let control: FormControl;
+ if (
+ c.type === RbdConfigurationType.milliseconds ||
+ c.type === RbdConfigurationType.iops ||
+ c.type === RbdConfigurationType.bps
+ ) {
+ let initialValue = 0;
+ _.forEach(this.initialData, (configList) => {
+ if (configList['name'] === c.name) {
+ initialValue = configList['value'];
+ }
+ });
+ control = new FormControl(initialValue, Validators.min(0));
+ } else {
+ throw new Error(
+ `Type ${c.type} is unknown, you may need to add it to RbdConfiguration class`
+ );
+ }
+ configFormGroup.addControl(c.name, control);
+ });
+
+ return configFormGroup;
+ }
+
+ /**
+ * Reset the value. The inherited value will be used instead.
+ */
+ reset(optionName: string) {
+ const formControl: any = this.form.get('configuration').get(optionName);
+ if (formControl.disabled) {
+ formControl.setValue(formControl['previousValue'] || 0);
+ formControl.enable();
+ if (!formControl['previousValue']) {
+ formControl.markAsPristine();
+ }
+ } else {
+ formControl['previousValue'] = formControl.value;
+ formControl.setValue(null);
+ formControl.markAsDirty();
+ formControl.disable();
+ }
+ }
+
+ isDisabled(optionName: string) {
+ return this.form.get('configuration').get(optionName).disabled;
+ }
+
+ toggleSectionVisibility(className: string) {
+ this.sectionVisibility[className] = !this.sectionVisibility[className];
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html
new file mode 100644
index 000000000..6c3e8c027
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html
@@ -0,0 +1,29 @@
+<cd-table #poolConfTable
+ [data]="data"
+ [columns]="poolConfigurationColumns"
+ identifier="name">
+</cd-table>
+
+<ng-template #configurationSourceTpl
+ let-value="value">
+
+ <div [ngSwitch]="value">
+ <span *ngSwitchCase="'global'"
+ i18n>Global</span>
+ <strong *ngSwitchCase="'image'"
+ i18n>Image</strong>
+ <strong *ngSwitchCase="'pool'"
+ i18n>Pool</strong>
+ </div>
+</ng-template>
+
+<ng-template #configurationValueTpl
+ let-row="row"
+ let-value="value">
+ <div [ngSwitch]="row.type">
+ <span *ngSwitchCase="typeField.bps">{{ value | dimlessBinaryPerSecond }}</span>
+ <span *ngSwitchCase="typeField.milliseconds">{{ value | milliseconds }}</span>
+ <span *ngSwitchCase="typeField.iops">{{ value | iops }}</span>
+ <span *ngSwitchDefault>{{ value }}</span>
+ </div>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.spec.ts
new file mode 100644
index 000000000..f54ad0272
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.spec.ts
@@ -0,0 +1,99 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule } from '@angular/forms';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbDropdownModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgxDatatableModule } from '@swimlane/ngx-datatable';
+import { ChartsModule } from 'ng2-charts';
+
+import { ComponentsModule } from '~/app/shared/components/components.module';
+import { RbdConfigurationEntry } from '~/app/shared/models/configuration';
+import { FormatterService } from '~/app/shared/services/formatter.service';
+import { RbdConfigurationService } from '~/app/shared/services/rbd-configuration.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RbdConfigurationListComponent } from './rbd-configuration-list.component';
+
+describe('RbdConfigurationListComponent', () => {
+ let component: RbdConfigurationListComponent;
+ let fixture: ComponentFixture<RbdConfigurationListComponent>;
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ FormsModule,
+ NgxDatatableModule,
+ RouterTestingModule,
+ ComponentsModule,
+ NgbDropdownModule,
+ ChartsModule,
+ SharedModule,
+ NgbTooltipModule
+ ],
+ declarations: [RbdConfigurationListComponent],
+ providers: [FormatterService, RbdConfigurationService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RbdConfigurationListComponent);
+ component = fixture.componentInstance;
+ component.data = [];
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('filters options out which are not defined in RbdConfigurationService', () => {
+ const fakeOption = { name: 'foo', source: 0, value: '50' } as RbdConfigurationEntry;
+ const realOption = {
+ name: 'rbd_qos_read_iops_burst',
+ source: 0,
+ value: '50'
+ } as RbdConfigurationEntry;
+
+ component.data = [fakeOption, realOption];
+ component.ngOnChanges();
+
+ expect(component.data.length).toBe(1);
+ expect(component.data.pop()).toBe(realOption);
+ });
+
+ it('should filter the source column by its piped value', () => {
+ const poolConfTable = component.poolConfTable;
+ poolConfTable.data = [
+ {
+ name: 'rbd_qos_read_iops_burst',
+ source: 0,
+ value: '50'
+ },
+ {
+ name: 'rbd_qos_read_iops_limit',
+ source: 1,
+ value: '50'
+ },
+ {
+ name: 'rbd_qos_write_iops_limit',
+ source: 0,
+ value: '100'
+ },
+ {
+ name: 'rbd_qos_write_iops_burst',
+ source: 2,
+ value: '100'
+ }
+ ];
+ const filter = (keyword: string) => {
+ poolConfTable.search = keyword;
+ poolConfTable.updateFilter();
+ return poolConfTable.rows;
+ };
+ expect(filter('').length).toBe(4);
+ expect(filter('source:global').length).toBe(2);
+ expect(filter('source:pool').length).toBe(1);
+ expect(filter('source:image').length).toBe(1);
+ expect(filter('source:zero').length).toBe(0);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts
new file mode 100644
index 000000000..84fa02ff9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts
@@ -0,0 +1,65 @@
+import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import { TableComponent } from '~/app/shared/datatable/table/table.component';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import {
+ RbdConfigurationEntry,
+ RbdConfigurationSourceField,
+ RbdConfigurationType
+} from '~/app/shared/models/configuration';
+import { RbdConfigurationSourcePipe } from '~/app/shared/pipes/rbd-configuration-source.pipe';
+import { FormatterService } from '~/app/shared/services/formatter.service';
+import { RbdConfigurationService } from '~/app/shared/services/rbd-configuration.service';
+
+@Component({
+ selector: 'cd-rbd-configuration-table',
+ templateUrl: './rbd-configuration-list.component.html',
+ styleUrls: ['./rbd-configuration-list.component.scss']
+})
+export class RbdConfigurationListComponent implements OnInit, OnChanges {
+ @Input()
+ data: RbdConfigurationEntry[];
+ poolConfigurationColumns: CdTableColumn[];
+ @ViewChild('configurationSourceTpl', { static: true })
+ configurationSourceTpl: TemplateRef<any>;
+ @ViewChild('configurationValueTpl', { static: true })
+ configurationValueTpl: TemplateRef<any>;
+ @ViewChild('poolConfTable', { static: true })
+ poolConfTable: TableComponent;
+
+ readonly sourceField = RbdConfigurationSourceField;
+ readonly typeField = RbdConfigurationType;
+
+ constructor(
+ public formatterService: FormatterService,
+ private rbdConfigurationService: RbdConfigurationService
+ ) {}
+
+ ngOnInit() {
+ this.poolConfigurationColumns = [
+ { prop: 'displayName', name: $localize`Name` },
+ { prop: 'description', name: $localize`Description` },
+ { prop: 'name', name: $localize`Key` },
+ {
+ prop: 'source',
+ name: $localize`Source`,
+ cellTemplate: this.configurationSourceTpl,
+ pipe: new RbdConfigurationSourcePipe()
+ },
+ { prop: 'value', name: $localize`Value`, cellTemplate: this.configurationValueTpl }
+ ];
+ }
+
+ ngOnChanges(): void {
+ if (!this.data) {
+ return;
+ }
+ // Filter settings out which are not listed in RbdConfigurationService
+ this.data = this.data.filter((row) =>
+ this.rbdConfigurationService
+ .getOptionFields()
+ .map((o) => o.name)
+ .includes(row.name)
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html
new file mode 100644
index 000000000..ab9454cbc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html
@@ -0,0 +1,180 @@
+<ng-template #usageNotAvailableTooltipTpl>
+ <ng-container i18n>Only available for RBD images with <strong>fast-diff</strong> enabled</ng-container>
+</ng-template>
+
+<ng-container *ngIf="selection && selection.source !== 'REMOVING'">
+ <ul ngbNav
+ #nav="ngbNav"
+ class="nav-tabs"
+ cdStatefulTab="rbd-details">
+ <li ngbNavItem="details">
+ <a ngbNavLink
+ i18n>Details</a>
+ <ng-template ngbNavContent>
+ <table class="table table-striped table-bordered">
+ <tbody>
+ <tr>
+ <td i18n
+ class="bold w-25">Name</td>
+ <td class="w-75">{{ selection.name }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Pool</td>
+ <td>{{ selection.pool_name }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Data Pool</td>
+ <td>{{ selection.data_pool | empty }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Created</td>
+ <td>{{ selection.timestamp | cdDate }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Size</td>
+ <td>{{ selection.size | dimlessBinary }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Objects</td>
+ <td>{{ selection.num_objs | dimless }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Object size</td>
+ <td>{{ selection.obj_size | dimlessBinary }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Features</td>
+ <td>
+ <span *ngFor="let feature of selection.features_name">
+ <span class="badge badge-dark mr-2">{{ feature }}</span>
+ </span>
+ </td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Provisioned</td>
+ <td>
+ <span *ngIf="selection.features_name?.indexOf('fast-diff') === -1">
+ <span class="form-text text-muted"
+ [ngbTooltip]="usageNotAvailableTooltipTpl"
+ placement="top"
+ i18n>N/A</span>
+ </span>
+ <span *ngIf="selection.features_name?.indexOf('fast-diff') !== -1">
+ {{ selection.disk_usage | dimlessBinary }}
+ </span>
+ </td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Total provisioned</td>
+ <td>
+ <span *ngIf="selection.features_name?.indexOf('fast-diff') === -1">
+ <span class="form-text text-muted"
+ [ngbTooltip]="usageNotAvailableTooltipTpl"
+ placement="top"
+ i18n>N/A</span>
+ </span>
+ <span *ngIf="selection.features_name?.indexOf('fast-diff') !== -1">
+ {{ selection.total_disk_usage | dimlessBinary }}
+ </span>
+ </td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Striping unit</td>
+ <td>{{ selection.stripe_unit | dimlessBinary }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Striping count</td>
+ <td>{{ selection.stripe_count }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Parent</td>
+ <td>
+ <span *ngIf="selection.parent">{{ selection.parent.pool_name }}<span
+ *ngIf="selection.parent.pool_namespace">/{{ selection.parent.pool_namespace }}</span>/{{ selection.parent.image_name }}@{{ selection.parent.snap_name }}</span>
+ <span *ngIf="!selection.parent">-</span>
+ </td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Block name prefix</td>
+ <td>{{ selection.block_name_prefix }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Order</td>
+ <td>{{ selection.order }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Format Version</td>
+ <td>{{ selection.image_format }}</td>
+ </tr>
+ </tbody>
+ </table>
+ </ng-template>
+ </li>
+ <li ngbNavItem="snapshots">
+ <a ngbNavLink
+ i18n>Snapshots</a>
+ <ng-template ngbNavContent>
+ <cd-rbd-snapshot-list [snapshots]="selection.snapshots"
+ [featuresName]="selection.features_name"
+ [poolName]="selection.pool_name"
+ [namespace]="selection.namespace"
+ [mirroring]="selection.mirror_mode"
+ [rbdName]="selection.name"></cd-rbd-snapshot-list>
+ </ng-template>
+ </li>
+ <li ngbNavItem="configuration">
+ <a ngbNavLink
+ i18n>Configuration</a>
+ <ng-template ngbNavContent>
+ <cd-rbd-configuration-table [data]="selection['configuration']"></cd-rbd-configuration-table>
+ </ng-template>
+ </li>
+
+ <li ngbNavItem="performance">
+ <a ngbNavLink
+ i18n>Performance</a>
+ <ng-template ngbNavContent>
+ <cd-grafana [grafanaPath]="rbdDashboardUrl"
+ uid="YhCYGcuZz"
+ grafanaStyle="one">
+ </cd-grafana>
+ </ng-template>
+ </li>
+ </ul>
+
+ <div [ngbNavOutlet]="nav"></div>
+</ng-container>
+<ng-container *ngIf="selection && selection.source === 'REMOVING'">
+ <cd-alert-panel type="warning"
+ i18n>Information can not be displayed for RBD in status 'Removing'.</cd-alert-panel>
+</ng-container>
+
+<ng-template #poolConfigurationSourceTpl
+ let-row="row"
+ let-value="value">
+ <ng-container *ngIf="+value; else global">
+ <strong i18n
+ i18n-ngbTooltip
+ ngbTooltip="This setting overrides the global value">Image</strong>
+ </ng-container>
+ <ng-template #global>
+ <span i18n
+ i18n-ngbTooltip
+ ngbTooltip="This is the global value. No value for this option has been set for this image.">Global</span>
+ </ng-template>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.spec.ts
new file mode 100644
index 000000000..757976546
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.spec.ts
@@ -0,0 +1,30 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RbdConfigurationListComponent } from '../rbd-configuration-list/rbd-configuration-list.component';
+import { RbdSnapshotListComponent } from '../rbd-snapshot-list/rbd-snapshot-list.component';
+import { RbdDetailsComponent } from './rbd-details.component';
+
+describe('RbdDetailsComponent', () => {
+ let component: RbdDetailsComponent;
+ let fixture: ComponentFixture<RbdDetailsComponent>;
+
+ configureTestBed({
+ declarations: [RbdDetailsComponent, RbdSnapshotListComponent, RbdConfigurationListComponent],
+ imports: [SharedModule, NgbTooltipModule, RouterTestingModule, NgbNavModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RbdDetailsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.ts
new file mode 100644
index 000000000..ee06198d1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.ts
@@ -0,0 +1,31 @@
+import { Component, Input, OnChanges, TemplateRef, ViewChild } from '@angular/core';
+
+import { NgbNav } from '@ng-bootstrap/ng-bootstrap';
+
+import { RbdFormModel } from '../rbd-form/rbd-form.model';
+
+@Component({
+ selector: 'cd-rbd-details',
+ templateUrl: './rbd-details.component.html',
+ styleUrls: ['./rbd-details.component.scss']
+})
+export class RbdDetailsComponent implements OnChanges {
+ @Input()
+ selection: RbdFormModel;
+ @Input()
+ images: any;
+
+ @ViewChild('poolConfigurationSourceTpl', { static: true })
+ poolConfigurationSourceTpl: TemplateRef<any>;
+
+ @ViewChild(NgbNav, { static: true })
+ nav: NgbNav;
+
+ rbdDashboardUrl: string;
+
+ ngOnChanges() {
+ if (this.selection) {
+ this.rbdDashboardUrl = `rbd-details?var-Pool=${this.selection['pool_name']}&var-Image=${this.selection['name']}`;
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-feature.interface.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-feature.interface.ts
new file mode 100644
index 000000000..c12975f05
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-feature.interface.ts
@@ -0,0 +1,9 @@
+export interface RbdImageFeature {
+ desc: string;
+ allowEnable: boolean;
+ allowDisable: boolean;
+ requires?: string;
+ interlockedWith?: string;
+ key?: string;
+ initDisabled?: boolean;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-clone-request.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-clone-request.model.ts
new file mode 100644
index 000000000..fa190c0d5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-clone-request.model.ts
@@ -0,0 +1,13 @@
+import { RbdConfigurationEntry } from '~/app/shared/models/configuration';
+
+export class RbdFormCloneRequestModel {
+ child_pool_name: string;
+ child_namespace: string;
+ child_image_name: string;
+ obj_size: number;
+ features: Array<string> = [];
+ stripe_unit: number;
+ stripe_count: number;
+ data_pool: string;
+ configuration?: RbdConfigurationEntry[];
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-copy-request.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-copy-request.model.ts
new file mode 100644
index 000000000..af86234af
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-copy-request.model.ts
@@ -0,0 +1,14 @@
+import { RbdConfigurationEntry } from '~/app/shared/models/configuration';
+
+export class RbdFormCopyRequestModel {
+ dest_pool_name: string;
+ dest_namespace: string;
+ dest_image_name: string;
+ snapshot_name: string;
+ obj_size: number;
+ features: Array<string> = [];
+ stripe_unit: number;
+ stripe_count: number;
+ data_pool: string;
+ configuration: RbdConfigurationEntry[];
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-create-request.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-create-request.model.ts
new file mode 100644
index 000000000..2a2366f7c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-create-request.model.ts
@@ -0,0 +1,5 @@
+import { RbdFormModel } from './rbd-form.model';
+
+export class RbdFormCreateRequestModel extends RbdFormModel {
+ features: Array<string> = [];
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-edit-request.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-edit-request.model.ts
new file mode 100644
index 000000000..8b994d958
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-edit-request.model.ts
@@ -0,0 +1,14 @@
+import { RbdConfigurationEntry } from '~/app/shared/models/configuration';
+
+export class RbdFormEditRequestModel {
+ name: string;
+ size: number;
+ features: Array<string> = [];
+ configuration: RbdConfigurationEntry[];
+
+ enable_mirror?: boolean;
+ mirror_mode?: string;
+ primary?: boolean;
+ schedule_interval: string;
+ remove_scheduling? = false;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-mode.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-mode.enum.ts
new file mode 100644
index 000000000..3db18a1d6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-mode.enum.ts
@@ -0,0 +1,5 @@
+export enum RbdFormMode {
+ editing = 'editing',
+ cloning = 'cloning',
+ copying = 'copying'
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-response.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-response.model.ts
new file mode 100644
index 000000000..7468e3a2b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-response.model.ts
@@ -0,0 +1,7 @@
+import { RbdFormModel } from './rbd-form.model';
+import { RbdParentModel } from './rbd-parent.model';
+
+export class RbdFormResponseModel extends RbdFormModel {
+ features_name: string[];
+ parent: RbdParentModel;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.html
new file mode 100644
index 000000000..38f204762
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.html
@@ -0,0 +1,395 @@
+<div class="cd-col-form"
+ *cdFormLoading="loading">
+ <form name="rbdForm"
+ #formDir="ngForm"
+ [formGroup]="rbdForm"
+ novalidate>
+ <div class="card">
+ <div i18n="form title"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
+ <div class="card-body">
+
+ <!-- Parent -->
+ <div class="form-group row"
+ *ngIf="rbdForm.getValue('parent')">
+ <label i18n
+ class="cd-col-form-label"
+ for="name">{{ action | titlecase }} from</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ id="parent"
+ name="parent"
+ formControlName="parent">
+ <hr>
+ </div>
+ </div>
+
+ <!-- Name -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="name"
+ i18n>Name</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ placeholder="Name..."
+ id="name"
+ name="name"
+ formControlName="name"
+ autofocus>
+ <span class="invalid-feedback"
+ *ngIf="rbdForm.showError('name', formDir, 'required')">
+ <ng-container i18n>This field is required.</ng-container>
+ </span>
+ <span class="invalid-feedback"
+ *ngIf="rbdForm.showError('name', formDir, 'pattern')">
+ <ng-container i18n>'/' and '@' are not allowed.</ng-container>
+ </span>
+ </div>
+ </div>
+
+ <!-- Pool -->
+ <div class="form-group row"
+ (change)="onPoolChange($event.target.value)">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': mode !== 'editing'}"
+ for="pool"
+ i18n>Pool</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ placeholder="Pool name..."
+ id="pool"
+ name="pool"
+ formControlName="pool"
+ *ngIf="mode === 'editing' || !poolPermission.read">
+ <select id="pool"
+ name="pool"
+ class="form-control"
+ formControlName="pool"
+ *ngIf="mode !== 'editing' && poolPermission.read"
+ (change)="setPoolMirrorMode()">
+ <option *ngIf="pools === null"
+ [ngValue]="null"
+ i18n>Loading...</option>
+ <option *ngIf="pools !== null && pools.length === 0"
+ [ngValue]="null"
+ i18n>-- No rbd pools available --</option>
+ <option *ngIf="pools !== null && pools.length > 0"
+ [ngValue]="null"
+ i18n>-- Select a pool --</option>
+ <option *ngFor="let pool of pools"
+ [value]="pool.pool_name">{{ pool.pool_name }}</option>
+ </select>
+ <span *ngIf="rbdForm.showError('pool', formDir, 'required')"
+ class="invalid-feedback"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Namespace -->
+ <div class="form-group row"
+ *ngIf="mode !== 'editing' && rbdForm.getValue('pool') && namespaces === null">
+ <div class="cd-col-form-offset">
+ <i [ngClass]="[icons.spinner, icons.spin]"></i>
+ </div>
+ </div>
+ <div class="form-group row"
+ *ngIf="(mode === 'editing' && rbdForm.getValue('namespace')) || mode !== 'editing' && (namespaces && namespaces.length > 0 || !poolPermission.read)">
+ <label class="cd-col-form-label"
+ for="pool">
+ Namespace
+ </label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ placeholder="Namespace..."
+ id="namespace"
+ name="namespace"
+ formControlName="namespace"
+ *ngIf="mode === 'editing' || !poolPermission.read">
+ <select id="namespace"
+ name="namespace"
+ class="form-control"
+ formControlName="namespace"
+ *ngIf="mode !== 'editing' && poolPermission.read">
+ <option *ngIf="pools === null"
+ [ngValue]="null"
+ i18n>Loading...</option>
+ <option *ngIf="pools !== null && pools.length === 0"
+ [ngValue]="null"
+ i18n>-- No namespaces available --</option>
+ <option *ngIf="pools !== null && pools.length > 0"
+ [ngValue]="null"
+ i18n>-- Select a namespace --</option>
+ <option *ngFor="let namespace of namespaces"
+ [value]="namespace">{{ namespace }}</option>
+ </select>
+ </div>
+ </div>
+
+ <!-- Use a dedicated pool -->
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ id="useDataPool"
+ name="useDataPool"
+ formControlName="useDataPool"
+ (change)="onUseDataPoolChange()">
+ <label class="custom-control-label"
+ for="useDataPool"
+ i18n>Use a dedicated data pool</label>
+ <cd-helper *ngIf="allDataPools.length <= 1">
+ <span i18n>You need more than one pool with the rbd application label use to use a dedicated data pool.</span>
+ </cd-helper>
+ </div>
+ </div>
+ </div>
+
+ <!-- Data Pool -->
+ <div class="form-group row"
+ *ngIf="rbdForm.getValue('useDataPool')">
+ <label class="cd-col-form-label"
+ for="dataPool">
+ <span [ngClass]="{'required': mode !== 'editing'}"
+ i18n>Data pool</span>
+ <cd-helper i18n-html
+ html="Dedicated pool that stores the object-data of the RBD.">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ placeholder="Data pool name..."
+ id="dataPool"
+ name="dataPool"
+ formControlName="dataPool"
+ *ngIf="mode === 'editing' || !poolPermission.read">
+ <select id="dataPool"
+ name="dataPool"
+ class="form-control"
+ formControlName="dataPool"
+ (change)="onDataPoolChange($event.target.value)"
+ *ngIf="mode !== 'editing' && poolPermission.read">
+ <option *ngIf="dataPools === null"
+ [ngValue]="null"
+ i18n>Loading...</option>
+ <option *ngIf="dataPools !== null && dataPools.length === 0"
+ [ngValue]="null"
+ i18n>-- No data pools available --</option>
+ <option *ngIf="dataPools !== null && dataPools.length > 0"
+ [ngValue]="null">-- Select a data pool --
+ </option>
+ <option *ngFor="let dataPool of dataPools"
+ [value]="dataPool.pool_name">{{ dataPool.pool_name }}</option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="rbdForm.showError('dataPool', formDir, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Size -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="size"
+ i18n>Size</label>
+ <div class="cd-col-form-input">
+ <input id="size"
+ name="size"
+ class="form-control"
+ type="text"
+ formControlName="size"
+ i18n-placeholder
+ placeholder="e.g., 10GiB"
+ defaultUnit="GiB"
+ cdDimlessBinary>
+ <span class="invalid-feedback"
+ *ngIf="rbdForm.showError('size', formDir, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="rbdForm.showError('size', formDir, 'invalidSizeObject')"
+ i18n>You have to increase the size.</span>
+ </div>
+ </div>
+
+ <!-- Features -->
+ <div class="form-group row"
+ formGroupName="features">
+ <label i18n
+ class="cd-col-form-label"
+ for="features">Features</label>
+ <div class="cd-col-form-input">
+ <div class="custom-control custom-checkbox"
+ *ngFor="let feature of featuresList">
+ <input type="checkbox"
+ class="custom-control-input"
+ id="{{ feature.key }}"
+ name="{{ feature.key }}"
+ formControlName="{{ feature.key }}">
+ <label class="custom-control-label"
+ for="{{ feature.key }}">{{ feature.desc }}</label>
+ <cd-helper *ngIf="feature.helperHtml"
+ html="{{ feature.helperHtml }}">
+ </cd-helper>
+ </div>
+ </div>
+ </div>
+
+ <!-- Mirroring -->
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ id="mirroring"
+ name="mirroring"
+ (change)="setMirrorMode()"
+ formControlName="mirroring">
+ <label class="custom-control-label"
+ for="mirroring">Mirroring</label>
+ <cd-helper *ngIf="mirroring === false && this.currentPoolName">
+ <span i18n>You need to enable a <b>mirror mode</b> in the selected pool. Please <a [routerLink]="['/block/mirroring', {outlets: {modal: ['edit', currentPoolName]}}]">click here to select a mode and enable it in this pool.</a></span>
+ </cd-helper>
+ </div>
+ <div *ngIf="mirroring">
+ <div class="custom-control custom-radio ml-2"
+ *ngFor="let option of mirroringOptions">
+ <input type="radio"
+ class="custom-control-input"
+ [id]="option"
+ [value]="option"
+ name="mirroringMode"
+ (change)="setExclusiveLock()"
+ formControlName="mirroringMode"
+ [attr.disabled]="(poolMirrorMode === 'pool' && option === 'snapshot') ? true : null">
+ <label class="custom-control-label"
+ [for]="option">{{ option | titlecase }}</label>
+ <cd-helper *ngIf="poolMirrorMode === 'pool' && option === 'snapshot'">
+ <span i18n>You need to enable <b>image mirror mode</b> in the selected pool. Please <a [routerLink]="['/block/mirroring', {outlets: {modal: ['edit', currentPoolName]}}]">click here to select a mode and enable it in this pool.</a></span>
+ </cd-helper>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group row"
+ *ngIf="rbdForm.getValue('mirroringMode') === 'snapshot' && mirroring">
+ <label class="cd-col-form-label"
+ i18n>Schedule Interval
+ <cd-helper i18n-html
+ html="Create Mirror-Snapshots automatically on a periodic basis. The interval can be specified in days, hours, or minutes using d, h, m suffix respectively.">
+ </cd-helper></label>
+ <div class="cd-col-form-input">
+ <input id="schedule"
+ name="schedule"
+ class="form-control"
+ type="text"
+ formControlName="schedule"
+ i18n-placeholder
+ placeholder="e.g., 12h or 1d or 10m"
+ [attr.disabled]="(mode === rbdFormMode.editing) ? true : null">
+ </div>
+ </div>
+
+ <!-- Advanced -->
+ <div class="row">
+ <div class="col-sm-12">
+ <a class="float-right margin-right-md"
+ (click)="advancedEnabled = true; false"
+ *ngIf="!advancedEnabled"
+ href=""
+ i18n>Advanced...</a>
+ </div>
+ </div>
+
+ <div [hidden]="!advancedEnabled">
+
+ <legend class="cd-header"
+ i18n>Advanced</legend>
+
+ <div class="col-md-12">
+ <h4 class="cd-header"
+ i18n>Striping</h4>
+
+ <!-- Object Size -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="size">Object size<cd-helper>Objects in the Ceph Storage Cluster have a maximum configurable size (e.g., 2MB, 4MB, etc.). The object size should be large enough to accommodate many stripe units, and should be a multiple of the stripe unit.</cd-helper></label>
+ <div class="cd-col-form-input">
+ <select id="obj_size"
+ name="obj_size"
+ class="form-control"
+ formControlName="obj_size">
+ <option *ngFor="let objectSize of objectSizes"
+ [value]="objectSize">{{ objectSize }}</option>
+ </select>
+ </div>
+ </div>
+
+ <!-- stripingUnit -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': rbdForm.getValue('stripingCount')}"
+ for="stripingUnit"
+ i18n>Stripe unit<cd-helper>Stripes have a configurable unit size (e.g., 64kb). The Ceph Client divides the data it will write to objects into equally sized stripe units, except for the last stripe unit. A stripe width, should be a fraction of the Object Size so that an object may contain many stripe units.</cd-helper></label>
+ <div class="cd-col-form-input">
+ <select id="stripingUnit"
+ name="stripingUnit"
+ class="form-control"
+ formControlName="stripingUnit">
+ <option i18n
+ [ngValue]="null">-- Select stripe unit --</option>
+ <option *ngFor="let objectSize of objectSizes"
+ [value]="objectSize">{{ objectSize }}</option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="rbdForm.showError('stripingUnit', formDir, 'required')"
+ i18n>This field is required because stripe count is defined!</span>
+ <span class="invalid-feedback"
+ *ngIf="rbdForm.showError('stripingUnit', formDir, 'invalidStripingUnit')"
+ i18n>Stripe unit is greater than object size.</span>
+ </div>
+ </div>
+
+ <!-- Stripe Count -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': rbdForm.getValue('stripingUnit')}"
+ for="stripingCount"
+ i18n>Stripe count<cd-helper>The Ceph Client writes a sequence of stripe units over a series of objects determined by the stripe count. The series of objects is called an object set. After the Ceph Client writes to the last object in the object set, it returns to the first object in the object set.</cd-helper></label>
+ <div class="cd-col-form-input">
+ <input id="stripingCount"
+ name="stripingCount"
+ formControlName="stripingCount"
+ class="form-control"
+ type="number">
+ <span class="invalid-feedback"
+ *ngIf="rbdForm.showError('stripingCount', formDir, 'required')"
+ i18n>This field is required because stripe unit is defined!</span>
+ <span class="invalid-feedback"
+ *ngIf="rbdForm.showError('stripingCount', formDir, 'min')"
+ i18n>Stripe count must be greater than 0.</span>
+ </div>
+ </div>
+ </div>
+
+ <cd-rbd-configuration-form [form]="rbdForm"
+ [initializeData]="initializeConfigData"
+ (changes)="getDirtyConfigurationValues = $event"></cd-rbd-configuration-form>
+ </div>
+
+ </div>
+ <div class="card-footer">
+ <cd-form-button-panel (submitActionEvent)="submit()"
+ [form]="formDir"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
+ wrappingClass="text-right"></cd-form-button-panel>
+ </div>
+ </div>
+ </form>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.spec.ts
new file mode 100644
index 000000000..7f7815c00
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.spec.ts
@@ -0,0 +1,480 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { By } from '@angular/platform-browser';
+import { ActivatedRoute, Router } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+import { NEVER, of } from 'rxjs';
+import { delay } from 'rxjs/operators';
+
+import { Pool } from '~/app/ceph/pool/pool';
+import { PoolService } from '~/app/shared/api/pool.service';
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { ImageSpec } from '~/app/shared/models/image-spec';
+import { SharedModule } from '~/app/shared/shared.module';
+import { ActivatedRouteStub } from '~/testing/activated-route-stub';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RbdConfigurationFormComponent } from '../rbd-configuration-form/rbd-configuration-form.component';
+import { RbdImageFeature } from './rbd-feature.interface';
+import { RbdFormMode } from './rbd-form-mode.enum';
+import { RbdFormResponseModel } from './rbd-form-response.model';
+import { RbdFormComponent } from './rbd-form.component';
+
+describe('RbdFormComponent', () => {
+ const urlPrefix = {
+ create: '/block/rbd/create',
+ edit: '/block/rbd/edit',
+ clone: '/block/rbd/clone',
+ copy: '/block/rbd/copy'
+ };
+ let component: RbdFormComponent;
+ let fixture: ComponentFixture<RbdFormComponent>;
+ let activatedRoute: ActivatedRouteStub;
+ const mock: { rbd: RbdFormResponseModel; pools: Pool[]; defaultFeatures: string[] } = {
+ rbd: {} as RbdFormResponseModel,
+ pools: [],
+ defaultFeatures: []
+ };
+
+ const setRouterUrl = (
+ action: 'create' | 'edit' | 'clone' | 'copy',
+ poolName?: string,
+ imageName?: string
+ ) => {
+ component['routerUrl'] = [urlPrefix[action], poolName, imageName].filter((x) => x).join('/');
+ };
+
+ const queryNativeElement = (cssSelector: string) =>
+ fixture.debugElement.query(By.css(cssSelector)).nativeElement;
+
+ configureTestBed({
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ RouterTestingModule,
+ ToastrModule.forRoot(),
+ SharedModule
+ ],
+ declarations: [RbdFormComponent, RbdConfigurationFormComponent],
+ providers: [
+ {
+ provide: ActivatedRoute,
+ useValue: new ActivatedRouteStub({ pool: 'foo', name: 'bar', snap: undefined })
+ },
+ RbdService
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RbdFormComponent);
+ component = fixture.componentInstance;
+ activatedRoute = <ActivatedRouteStub>TestBed.inject(ActivatedRoute);
+
+ component.loadingReady();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('create/edit/clone/copy image', () => {
+ let createAction: jasmine.Spy;
+ let editAction: jasmine.Spy;
+ let cloneAction: jasmine.Spy;
+ let copyAction: jasmine.Spy;
+ let rbdServiceGetSpy: jasmine.Spy;
+ let routerNavigate: jasmine.Spy;
+
+ const DELAY = 100;
+
+ const getPool = (
+ pool_name: string,
+ type: 'replicated' | 'erasure',
+ flags_names: string,
+ application_metadata: string[]
+ ): Pool =>
+ ({
+ pool_name,
+ flags_names,
+ application_metadata,
+ type
+ } as Pool);
+
+ beforeEach(() => {
+ createAction = spyOn(component, 'createAction').and.returnValue(of(null));
+ editAction = spyOn(component, 'editAction');
+ editAction.and.returnValue(of(null));
+ cloneAction = spyOn(component, 'cloneAction').and.returnValue(of(null));
+ copyAction = spyOn(component, 'copyAction').and.returnValue(of(null));
+ spyOn(component, 'setResponse').and.stub();
+ routerNavigate = spyOn(TestBed.inject(Router), 'navigate').and.stub();
+ mock.pools = [
+ getPool('one', 'replicated', '', []),
+ getPool('two', 'replicated', '', ['rbd']),
+ getPool('three', 'replicated', '', ['rbd']),
+ getPool('four', 'erasure', '', ['rbd']),
+ getPool('four', 'erasure', 'ec_overwrites', ['rbd'])
+ ];
+ spyOn(TestBed.inject(PoolService), 'list').and.callFake(() => of(mock.pools));
+ rbdServiceGetSpy = spyOn(TestBed.inject(RbdService), 'get');
+ mock.rbd = ({ pool_name: 'foo', pool_image: 'bar' } as any) as RbdFormResponseModel;
+ rbdServiceGetSpy.and.returnValue(of(mock.rbd));
+ component.mode = undefined;
+ });
+
+ it('should create image', () => {
+ component.ngOnInit();
+ component.submit();
+
+ expect(createAction).toHaveBeenCalledTimes(1);
+ expect(editAction).toHaveBeenCalledTimes(0);
+ expect(cloneAction).toHaveBeenCalledTimes(0);
+ expect(copyAction).toHaveBeenCalledTimes(0);
+ expect(routerNavigate).toHaveBeenCalledTimes(1);
+ });
+
+ it('should unsubscribe right after image data is received', () => {
+ setRouterUrl('edit', 'foo', 'bar');
+ rbdServiceGetSpy.and.returnValue(of(mock.rbd));
+ editAction.and.returnValue(NEVER);
+ expect(component['rbdImage'].observers.length).toEqual(0);
+ component.ngOnInit(); // Subscribes to image once during init
+ component.submit();
+ expect(component['rbdImage'].observers.length).toEqual(1);
+ expect(createAction).toHaveBeenCalledTimes(0);
+ expect(editAction).toHaveBeenCalledTimes(1);
+ expect(cloneAction).toHaveBeenCalledTimes(0);
+ expect(copyAction).toHaveBeenCalledTimes(0);
+ expect(routerNavigate).toHaveBeenCalledTimes(0);
+ });
+
+ it('should not edit image if no image data is received', fakeAsync(() => {
+ setRouterUrl('edit', 'foo', 'bar');
+ rbdServiceGetSpy.and.returnValue(of(mock.rbd).pipe(delay(DELAY)));
+ component.ngOnInit();
+ component.submit();
+
+ expect(createAction).toHaveBeenCalledTimes(0);
+ expect(editAction).toHaveBeenCalledTimes(0);
+ expect(cloneAction).toHaveBeenCalledTimes(0);
+ expect(copyAction).toHaveBeenCalledTimes(0);
+ expect(routerNavigate).toHaveBeenCalledTimes(0);
+
+ tick(DELAY);
+ }));
+
+ describe('disable data pools', () => {
+ beforeEach(() => {
+ component.ngOnInit();
+ });
+
+ it('should be enabled with more than 1 pool', () => {
+ component['handleExternalData'](mock);
+ expect(component.allDataPools.length).toBe(3);
+ expect(component.rbdForm.get('useDataPool').disabled).toBe(false);
+
+ mock.pools.pop();
+ component['handleExternalData'](mock);
+ expect(component.allDataPools.length).toBe(2);
+ expect(component.rbdForm.get('useDataPool').disabled).toBe(false);
+ });
+
+ it('should be disabled with 1 pool', () => {
+ mock.pools = [mock.pools[0]];
+ component['handleExternalData'](mock);
+ expect(component.rbdForm.get('useDataPool').disabled).toBe(true);
+ });
+
+ // Reason for 2 tests - useDataPool is not re-enabled anywhere else
+ it('should be disabled without any pool', () => {
+ mock.pools = [];
+ component['handleExternalData'](mock);
+ expect(component.rbdForm.get('useDataPool').disabled).toBe(true);
+ });
+ });
+
+ it('should edit image after image data is received', () => {
+ setRouterUrl('edit', 'foo', 'bar');
+ component.ngOnInit();
+ component.submit();
+
+ expect(createAction).toHaveBeenCalledTimes(0);
+ expect(editAction).toHaveBeenCalledTimes(1);
+ expect(cloneAction).toHaveBeenCalledTimes(0);
+ expect(copyAction).toHaveBeenCalledTimes(0);
+ expect(routerNavigate).toHaveBeenCalledTimes(1);
+ });
+
+ it('should not clone image if no image data is received', fakeAsync(() => {
+ setRouterUrl('clone', 'foo', 'bar');
+ rbdServiceGetSpy.and.returnValue(of(mock.rbd).pipe(delay(DELAY)));
+ component.ngOnInit();
+ component.submit();
+
+ expect(createAction).toHaveBeenCalledTimes(0);
+ expect(editAction).toHaveBeenCalledTimes(0);
+ expect(cloneAction).toHaveBeenCalledTimes(0);
+ expect(copyAction).toHaveBeenCalledTimes(0);
+ expect(routerNavigate).toHaveBeenCalledTimes(0);
+
+ tick(DELAY);
+ }));
+
+ it('should clone image after image data is received', () => {
+ setRouterUrl('clone', 'foo', 'bar');
+ component.ngOnInit();
+ component.submit();
+
+ expect(createAction).toHaveBeenCalledTimes(0);
+ expect(editAction).toHaveBeenCalledTimes(0);
+ expect(cloneAction).toHaveBeenCalledTimes(1);
+ expect(copyAction).toHaveBeenCalledTimes(0);
+ expect(routerNavigate).toHaveBeenCalledTimes(1);
+ });
+
+ it('should not copy image if no image data is received', fakeAsync(() => {
+ setRouterUrl('copy', 'foo', 'bar');
+ rbdServiceGetSpy.and.returnValue(of(mock.rbd).pipe(delay(DELAY)));
+ component.ngOnInit();
+ component.submit();
+
+ expect(createAction).toHaveBeenCalledTimes(0);
+ expect(editAction).toHaveBeenCalledTimes(0);
+ expect(cloneAction).toHaveBeenCalledTimes(0);
+ expect(copyAction).toHaveBeenCalledTimes(0);
+ expect(routerNavigate).toHaveBeenCalledTimes(0);
+
+ tick(DELAY);
+ }));
+
+ it('should copy image after image data is received', () => {
+ setRouterUrl('copy', 'foo', 'bar');
+ component.ngOnInit();
+ component.submit();
+
+ expect(createAction).toHaveBeenCalledTimes(0);
+ expect(editAction).toHaveBeenCalledTimes(0);
+ expect(cloneAction).toHaveBeenCalledTimes(0);
+ expect(copyAction).toHaveBeenCalledTimes(1);
+ expect(routerNavigate).toHaveBeenCalledTimes(1);
+ });
+ });
+
+ describe('should test decodeURIComponent of params', () => {
+ let rbdService: RbdService;
+
+ beforeEach(() => {
+ rbdService = TestBed.inject(RbdService);
+ component.mode = RbdFormMode.editing;
+ fixture.detectChanges();
+ spyOn(rbdService, 'get').and.callThrough();
+ });
+
+ it('with namespace', () => {
+ activatedRoute.setParams({ image_spec: 'foo%2Fbar%2Fbaz' });
+
+ expect(rbdService.get).toHaveBeenCalledWith(new ImageSpec('foo', 'bar', 'baz'));
+ });
+
+ it('without snapName', () => {
+ activatedRoute.setParams({ image_spec: 'foo%2Fbar', snap: undefined });
+
+ expect(rbdService.get).toHaveBeenCalledWith(new ImageSpec('foo', null, 'bar'));
+ expect(component.snapName).toBeUndefined();
+ });
+
+ it('with snapName', () => {
+ activatedRoute.setParams({ image_spec: 'foo%2Fbar', snap: 'baz%2Fbaz' });
+
+ expect(rbdService.get).toHaveBeenCalledWith(new ImageSpec('foo', null, 'bar'));
+ expect(component.snapName).toBe('baz/baz');
+ });
+ });
+
+ describe('test image configuration component', () => {
+ it('is visible', () => {
+ fixture.detectChanges();
+ expect(
+ fixture.debugElement.query(By.css('cd-rbd-configuration-form')).nativeElement.parentElement
+ .hidden
+ ).toBe(true);
+ });
+ });
+
+ describe('tests for feature flags', () => {
+ let deepFlatten: any, layering: any, exclusiveLock: any, objectMap: any, fastDiff: any;
+ const defaultFeatures = [
+ // Supposed to be enabled by default
+ 'deep-flatten',
+ 'exclusive-lock',
+ 'fast-diff',
+ 'layering',
+ 'object-map'
+ ];
+ const allFeatureNames = [
+ 'deep-flatten',
+ 'layering',
+ 'exclusive-lock',
+ 'object-map',
+ 'fast-diff'
+ ];
+ const setFeatures = (features: Record<string, RbdImageFeature>) => {
+ component.features = features;
+ component.featuresList = component.objToArray(features);
+ component.createForm();
+ };
+ const getFeatureNativeElements = () => allFeatureNames.map((f) => queryNativeElement(`#${f}`));
+
+ it('should convert feature flags correctly in the constructor', () => {
+ setFeatures({
+ one: { desc: 'one', allowEnable: true, allowDisable: true },
+ two: { desc: 'two', allowEnable: true, allowDisable: true },
+ three: { desc: 'three', allowEnable: true, allowDisable: true }
+ });
+ expect(component.featuresList).toEqual([
+ { desc: 'one', key: 'one', allowDisable: true, allowEnable: true },
+ { desc: 'two', key: 'two', allowDisable: true, allowEnable: true },
+ { desc: 'three', key: 'three', allowDisable: true, allowEnable: true }
+ ]);
+ });
+
+ describe('test edit form flags', () => {
+ const prepare = (pool: string, image: string, enabledFeatures: string[]): void => {
+ const rbdService = TestBed.inject(RbdService);
+ spyOn(rbdService, 'get').and.returnValue(
+ of({
+ name: image,
+ pool_name: pool,
+ features_name: enabledFeatures
+ })
+ );
+ spyOn(rbdService, 'defaultFeatures').and.returnValue(of(defaultFeatures));
+ setRouterUrl('edit', pool, image);
+ fixture.detectChanges();
+ [deepFlatten, layering, exclusiveLock, objectMap, fastDiff] = getFeatureNativeElements();
+ };
+
+ it('should have the interlock feature for flags disabled, if one feature is not set', () => {
+ prepare('rbd', 'foobar', ['deep-flatten', 'exclusive-lock', 'layering', 'object-map']);
+
+ expect(objectMap.disabled).toBe(false);
+ expect(fastDiff.disabled).toBe(false);
+
+ expect(objectMap.checked).toBe(true);
+ expect(fastDiff.checked).toBe(false);
+
+ fastDiff.click();
+ fastDiff.click();
+
+ expect(objectMap.checked).toBe(true); // Shall not be disabled by `fast-diff`!
+ });
+
+ it('should not disable object-map when fast-diff is unchecked', () => {
+ prepare('rbd', 'foobar', ['deep-flatten', 'exclusive-lock', 'layering', 'object-map']);
+
+ fastDiff.click();
+ fastDiff.click();
+
+ expect(objectMap.checked).toBe(true); // Shall not be disabled by `fast-diff`!
+ });
+
+ it('should not enable fast-diff when object-map is checked', () => {
+ prepare('rbd', 'foobar', ['deep-flatten', 'exclusive-lock', 'layering', 'object-map']);
+
+ objectMap.click();
+ objectMap.click();
+
+ expect(fastDiff.checked).toBe(false); // Shall not be disabled by `fast-diff`!
+ });
+ });
+
+ describe('test create form flags', () => {
+ beforeEach(() => {
+ const rbdService = TestBed.inject(RbdService);
+ spyOn(rbdService, 'defaultFeatures').and.returnValue(of(defaultFeatures));
+ setRouterUrl('create');
+ fixture.detectChanges();
+ [deepFlatten, layering, exclusiveLock, objectMap, fastDiff] = getFeatureNativeElements();
+ });
+
+ it('should initialize the checkboxes correctly', () => {
+ expect(deepFlatten.disabled).toBe(false);
+ expect(layering.disabled).toBe(false);
+ expect(exclusiveLock.disabled).toBe(false);
+ expect(objectMap.disabled).toBe(false);
+ expect(fastDiff.disabled).toBe(false);
+
+ expect(deepFlatten.checked).toBe(true);
+ expect(layering.checked).toBe(true);
+ expect(exclusiveLock.checked).toBe(true);
+ expect(objectMap.checked).toBe(true);
+ expect(fastDiff.checked).toBe(true);
+ });
+
+ it('should disable features if their requirements are not met (exclusive-lock)', () => {
+ exclusiveLock.click(); // unchecks exclusive-lock
+ expect(objectMap.disabled).toBe(true);
+ expect(fastDiff.disabled).toBe(true);
+ });
+
+ it('should disable features if their requirements are not met (object-map)', () => {
+ objectMap.click(); // unchecks object-map
+ expect(fastDiff.disabled).toBe(true);
+ });
+ });
+
+ describe('test mirroring options', () => {
+ beforeEach(() => {
+ component.ngOnInit();
+ fixture.detectChanges();
+ const mirroring = fixture.debugElement.query(By.css('#mirroring')).nativeElement;
+ mirroring.click();
+ fixture.detectChanges();
+ });
+
+ it('should verify two mirroring options are shown', () => {
+ const journal = fixture.debugElement.query(By.css('#journal')).nativeElement;
+ const snapshot = fixture.debugElement.query(By.css('#snapshot')).nativeElement;
+ expect(journal).not.toBeNull();
+ expect(snapshot).not.toBeNull();
+ });
+
+ it('should verify only snapshot is disabled for pools that are in pool mirror mode', () => {
+ component.poolMirrorMode = 'pool';
+ fixture.detectChanges();
+ const journal = fixture.debugElement.query(By.css('#journal')).nativeElement;
+ const snapshot = fixture.debugElement.query(By.css('#snapshot')).nativeElement;
+ expect(journal.disabled).toBe(false);
+ expect(snapshot.disabled).toBe(true);
+ });
+
+ it('should set and disable exclusive-lock only for the journal mode', () => {
+ component.poolMirrorMode = 'pool';
+ fixture.detectChanges();
+ const exclusiveLocks = fixture.debugElement.query(By.css('#exclusive-lock')).nativeElement;
+ expect(exclusiveLocks.checked).toBe(true);
+ expect(exclusiveLocks.disabled).toBe(true);
+ });
+
+ it('should have journaling feature for journaling mirror mode on createRequest', () => {
+ component.mirroring = true;
+ fixture.detectChanges();
+ const journal = fixture.debugElement.query(By.css('#journal')).nativeElement;
+ expect(journal.checked).toBe(true);
+ const request = component.createRequest();
+ expect(request.features).toContain('journaling');
+ });
+
+ it('should have journaling feature for journaling mirror mode on editRequest', () => {
+ component.mirroring = true;
+ fixture.detectChanges();
+ const journal = fixture.debugElement.query(By.css('#journal')).nativeElement;
+ expect(journal.checked).toBe(true);
+ const request = component.editRequest();
+ expect(request.features).toContain('journaling');
+ });
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts
new file mode 100644
index 000000000..f6c6af579
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts
@@ -0,0 +1,815 @@
+import { Component, OnInit } from '@angular/core';
+import { FormControl, ValidatorFn, Validators } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+
+import _ from 'lodash';
+import { forkJoin, Observable, ReplaySubject } from 'rxjs';
+import { first, switchMap } from 'rxjs/operators';
+
+import { Pool } from '~/app/ceph/pool/pool';
+import { PoolService } from '~/app/shared/api/pool.service';
+import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdForm } from '~/app/shared/forms/cd-form';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import {
+ RbdConfigurationEntry,
+ RbdConfigurationSourceField
+} from '~/app/shared/models/configuration';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { ImageSpec } from '~/app/shared/models/image-spec';
+import { Permission } from '~/app/shared/models/permissions';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { FormatterService } from '~/app/shared/services/formatter.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { RBDImageFormat, RbdModel } from '../rbd-list/rbd-model';
+import { RbdImageFeature } from './rbd-feature.interface';
+import { RbdFormCloneRequestModel } from './rbd-form-clone-request.model';
+import { RbdFormCopyRequestModel } from './rbd-form-copy-request.model';
+import { RbdFormCreateRequestModel } from './rbd-form-create-request.model';
+import { RbdFormEditRequestModel } from './rbd-form-edit-request.model';
+import { RbdFormMode } from './rbd-form-mode.enum';
+import { RbdFormResponseModel } from './rbd-form-response.model';
+
+class ExternalData {
+ rbd: RbdFormResponseModel;
+ defaultFeatures: string[];
+ pools: Pool[];
+}
+
+@Component({
+ selector: 'cd-rbd-form',
+ templateUrl: './rbd-form.component.html',
+ styleUrls: ['./rbd-form.component.scss']
+})
+export class RbdFormComponent extends CdForm implements OnInit {
+ poolPermission: Permission;
+ rbdForm: CdFormGroup;
+ getDirtyConfigurationValues: (
+ includeLocalField?: boolean,
+ localField?: RbdConfigurationSourceField
+ ) => RbdConfigurationEntry[];
+
+ namespaces: Array<string> = [];
+ namespacesByPoolCache = {};
+ pools: Array<Pool> = null;
+ allPools: Array<Pool> = null;
+ dataPools: Array<Pool> = null;
+ allDataPools: Array<Pool> = [];
+ features: { [key: string]: RbdImageFeature };
+ featuresList: RbdImageFeature[] = [];
+ initializeConfigData = new ReplaySubject<{
+ initialData: RbdConfigurationEntry[];
+ sourceType: RbdConfigurationSourceField;
+ }>(1);
+
+ pool: string;
+
+ advancedEnabled = false;
+
+ public rbdFormMode = RbdFormMode;
+ mode: RbdFormMode;
+
+ response: RbdFormResponseModel;
+ snapName: string;
+
+ defaultObjectSize = '4 MiB';
+
+ mirroringOptions = ['journal', 'snapshot'];
+ poolMirrorMode: string;
+ mirroring = false;
+ currentPoolName = '';
+
+ objectSizes: Array<string> = [
+ '4 KiB',
+ '8 KiB',
+ '16 KiB',
+ '32 KiB',
+ '64 KiB',
+ '128 KiB',
+ '256 KiB',
+ '512 KiB',
+ '1 MiB',
+ '2 MiB',
+ '4 MiB',
+ '8 MiB',
+ '16 MiB',
+ '32 MiB'
+ ];
+
+ defaultStripingUnit = '4 MiB';
+
+ defaultStripingCount = 1;
+
+ action: string;
+ resource: string;
+ private rbdImage = new ReplaySubject(1);
+ private routerUrl: string;
+
+ icons = Icons;
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private route: ActivatedRoute,
+ private poolService: PoolService,
+ private rbdService: RbdService,
+ private formatter: FormatterService,
+ private taskWrapper: TaskWrapperService,
+ private dimlessBinaryPipe: DimlessBinaryPipe,
+ public actionLabels: ActionLabelsI18n,
+ private router: Router,
+ private rbdMirroringService: RbdMirroringService
+ ) {
+ super();
+ this.routerUrl = this.router.url;
+ this.poolPermission = this.authStorageService.getPermissions().pool;
+ this.resource = $localize`RBD`;
+ this.features = {
+ 'deep-flatten': {
+ desc: $localize`Deep flatten`,
+ requires: null,
+ allowEnable: false,
+ allowDisable: true
+ },
+ layering: {
+ desc: $localize`Layering`,
+ requires: null,
+ allowEnable: false,
+ allowDisable: false
+ },
+ 'exclusive-lock': {
+ desc: $localize`Exclusive lock`,
+ requires: null,
+ allowEnable: true,
+ allowDisable: true
+ },
+ 'object-map': {
+ desc: $localize`Object map (requires exclusive-lock)`,
+ requires: 'exclusive-lock',
+ allowEnable: true,
+ allowDisable: true,
+ initDisabled: true
+ },
+ 'fast-diff': {
+ desc: $localize`Fast diff (interlocked with object-map)`,
+ requires: 'object-map',
+ allowEnable: true,
+ allowDisable: true,
+ interlockedWith: 'object-map',
+ initDisabled: true
+ }
+ };
+ this.featuresList = this.objToArray(this.features);
+ this.createForm();
+ }
+
+ objToArray(obj: { [key: string]: any }) {
+ return _.map(obj, (o, key) => Object.assign(o, { key: key }));
+ }
+
+ createForm() {
+ this.rbdForm = new CdFormGroup(
+ {
+ parent: new FormControl(''),
+ name: new FormControl('', {
+ validators: [Validators.required, Validators.pattern(/^[^@/]+?$/)]
+ }),
+ pool: new FormControl(null, {
+ validators: [Validators.required]
+ }),
+ namespace: new FormControl(null),
+ useDataPool: new FormControl(false),
+ dataPool: new FormControl(null),
+ size: new FormControl(null, {
+ updateOn: 'blur'
+ }),
+ obj_size: new FormControl(this.defaultObjectSize),
+ features: new CdFormGroup(
+ this.featuresList.reduce((acc: object, e) => {
+ acc[e.key] = new FormControl({ value: false, disabled: !!e.initDisabled });
+ return acc;
+ }, {})
+ ),
+ mirroring: new FormControl(false),
+ schedule: new FormControl('', {
+ validators: [Validators.pattern(/^([0-9]+)d|([0-9]+)h|([0-9]+)m$/)] // check schedule interval to be in format - 1d or 1h or 1m
+ }),
+ mirroringMode: new FormControl(this.mirroringOptions[0]),
+ stripingUnit: new FormControl(this.defaultStripingUnit),
+ stripingCount: new FormControl(this.defaultStripingCount, {
+ updateOn: 'blur'
+ })
+ },
+ this.validateRbdForm(this.formatter)
+ );
+ }
+
+ disableForEdit() {
+ this.rbdForm.get('parent').disable();
+ this.rbdForm.get('pool').disable();
+ this.rbdForm.get('namespace').disable();
+ this.rbdForm.get('useDataPool').disable();
+ this.rbdForm.get('dataPool').disable();
+ this.rbdForm.get('obj_size').disable();
+ this.rbdForm.get('stripingUnit').disable();
+ this.rbdForm.get('stripingCount').disable();
+
+ /* RBD Image Format v1 */
+ this.rbdImage.subscribe((image: RbdModel) => {
+ if (image.image_format === RBDImageFormat.V1) {
+ this.rbdForm.get('deep-flatten').disable();
+ this.rbdForm.get('layering').disable();
+ this.rbdForm.get('exclusive-lock').disable();
+ }
+ });
+ }
+
+ disableForClone() {
+ this.rbdForm.get('parent').disable();
+ this.rbdForm.get('size').disable();
+ }
+
+ disableForCopy() {
+ this.rbdForm.get('parent').disable();
+ this.rbdForm.get('size').disable();
+ }
+
+ ngOnInit() {
+ this.prepareFormForAction();
+ this.gatherNeededData().subscribe(this.handleExternalData.bind(this));
+ }
+
+ setExclusiveLock() {
+ if (this.mirroring && this.rbdForm.get('mirroringMode').value === 'journal') {
+ this.rbdForm.get('exclusive-lock').setValue(true);
+ this.rbdForm.get('exclusive-lock').disable();
+ } else {
+ this.rbdForm.get('exclusive-lock').enable();
+ if (this.poolMirrorMode === 'pool') {
+ this.rbdForm.get('mirroringMode').setValue(this.mirroringOptions[0]);
+ }
+ }
+ }
+
+ setMirrorMode() {
+ this.mirroring = !this.mirroring;
+ this.setExclusiveLock();
+ }
+
+ setPoolMirrorMode() {
+ this.currentPoolName =
+ this.mode === this.rbdFormMode.editing
+ ? this.response?.pool_name
+ : this.rbdForm.getValue('pool');
+ if (this.currentPoolName) {
+ this.rbdMirroringService.refresh();
+ this.rbdMirroringService.subscribeSummary((data) => {
+ const pool = data.content_data.pools.find((o: any) => o.name === this.currentPoolName);
+ this.poolMirrorMode = pool.mirror_mode;
+
+ if (pool.mirror_mode === 'disabled') {
+ this.mirroring = false;
+ this.rbdForm.get('mirroring').setValue(this.mirroring);
+ this.rbdForm.get('mirroring').disable();
+ } else if (this.mode !== this.rbdFormMode.editing) {
+ this.rbdForm.get('mirroring').enable();
+ this.mirroring = true;
+ this.rbdForm.get('mirroring').setValue(this.mirroring);
+ }
+ });
+ }
+ this.setExclusiveLock();
+ }
+
+ private prepareFormForAction() {
+ const url = this.routerUrl;
+ if (url.startsWith('/block/rbd/edit')) {
+ this.mode = this.rbdFormMode.editing;
+ this.action = this.actionLabels.EDIT;
+ this.disableForEdit();
+ } else if (url.startsWith('/block/rbd/clone')) {
+ this.mode = this.rbdFormMode.cloning;
+ this.disableForClone();
+ this.action = this.actionLabels.CLONE;
+ } else if (url.startsWith('/block/rbd/copy')) {
+ this.mode = this.rbdFormMode.copying;
+ this.action = this.actionLabels.COPY;
+ this.disableForCopy();
+ } else {
+ this.action = this.actionLabels.CREATE;
+ }
+ _.each(this.features, (feature) => {
+ this.rbdForm
+ .get('features')
+ .get(feature.key)
+ .valueChanges.subscribe((value) => this.featureFormUpdate(feature.key, value));
+ });
+ }
+
+ private gatherNeededData(): Observable<object> {
+ const promises = {};
+ if (this.mode) {
+ // Mode is not set for creation
+ this.route.params.subscribe((params: { image_spec: string; snap: string }) => {
+ const imageSpec = ImageSpec.fromString(decodeURIComponent(params.image_spec));
+ if (params.snap) {
+ this.snapName = decodeURIComponent(params.snap);
+ }
+ promises['rbd'] = this.rbdService.get(imageSpec);
+ });
+ } else {
+ // New image
+ promises['defaultFeatures'] = this.rbdService.defaultFeatures();
+ }
+ if (this.mode !== this.rbdFormMode.editing && this.poolPermission.read) {
+ promises['pools'] = this.poolService.list([
+ 'pool_name',
+ 'type',
+ 'flags_names',
+ 'application_metadata'
+ ]);
+ }
+ return forkJoin(promises);
+ }
+
+ private handleExternalData(data: ExternalData) {
+ this.handlePoolData(data.pools);
+ this.setPoolMirrorMode();
+
+ if (data.defaultFeatures) {
+ // Fetched only during creation
+ this.setFeatures(data.defaultFeatures);
+ }
+
+ if (data.rbd) {
+ // Not fetched for creation
+ const resp = data.rbd;
+ this.setResponse(resp, this.snapName);
+ this.rbdImage.next(resp);
+ }
+
+ this.loadingReady();
+ }
+
+ private handlePoolData(data: Pool[]) {
+ if (!data) {
+ // Not fetched while editing
+ return;
+ }
+ const pools: Pool[] = [];
+ const dataPools = [];
+ for (const pool of data) {
+ if (this.rbdService.isRBDPool(pool)) {
+ if (pool.type === 'replicated') {
+ pools.push(pool);
+ dataPools.push(pool);
+ } else if (pool.type === 'erasure' && pool.flags_names.indexOf('ec_overwrites') !== -1) {
+ dataPools.push(pool);
+ }
+ }
+ }
+ this.pools = pools;
+ this.allPools = pools;
+ this.dataPools = dataPools;
+ this.allDataPools = dataPools;
+ if (this.pools.length === 1) {
+ const poolName = this.pools[0].pool_name;
+ this.rbdForm.get('pool').setValue(poolName);
+ this.onPoolChange(poolName);
+ }
+ if (this.allDataPools.length <= 1) {
+ this.rbdForm.get('useDataPool').disable();
+ }
+ }
+
+ onPoolChange(selectedPoolName: string) {
+ const dataPoolControl = this.rbdForm.get('dataPool');
+ if (dataPoolControl.value === selectedPoolName) {
+ dataPoolControl.setValue(null);
+ }
+ this.dataPools = this.allDataPools
+ ? this.allDataPools.filter((dataPool: any) => {
+ return dataPool.pool_name !== selectedPoolName;
+ })
+ : [];
+ this.namespaces = null;
+ if (selectedPoolName in this.namespacesByPoolCache) {
+ this.namespaces = this.namespacesByPoolCache[selectedPoolName];
+ } else {
+ this.rbdService.listNamespaces(selectedPoolName).subscribe((namespaces: any[]) => {
+ namespaces = namespaces.map((namespace) => namespace.namespace);
+ this.namespacesByPoolCache[selectedPoolName] = namespaces;
+ this.namespaces = namespaces;
+ });
+ }
+ this.rbdForm.get('namespace').setValue(null);
+ }
+
+ onUseDataPoolChange() {
+ if (!this.rbdForm.getValue('useDataPool')) {
+ this.rbdForm.get('dataPool').setValue(null);
+ this.onDataPoolChange(null);
+ }
+ }
+
+ onDataPoolChange(selectedDataPoolName: string) {
+ const newPools = this.allPools.filter((pool: Pool) => {
+ return pool.pool_name !== selectedDataPoolName;
+ });
+ if (this.rbdForm.getValue('pool') === selectedDataPoolName) {
+ this.rbdForm.get('pool').setValue(null);
+ }
+ this.pools = newPools;
+ }
+
+ validateRbdForm(formatter: FormatterService): ValidatorFn {
+ return (formGroup: CdFormGroup) => {
+ // Data Pool
+ const useDataPoolControl = formGroup.get('useDataPool');
+ const dataPoolControl = formGroup.get('dataPool');
+ let dataPoolControlErrors = null;
+ if (useDataPoolControl.value && dataPoolControl.value == null) {
+ dataPoolControlErrors = { required: true };
+ }
+ dataPoolControl.setErrors(dataPoolControlErrors);
+ // Size
+ const sizeControl = formGroup.get('size');
+ const objectSizeControl = formGroup.get('obj_size');
+ const objectSizeInBytes = formatter.toBytes(
+ objectSizeControl.value != null ? objectSizeControl.value : this.defaultObjectSize
+ );
+ const stripingCountControl = formGroup.get('stripingCount');
+ const stripingCount =
+ stripingCountControl.value != null ? stripingCountControl.value : this.defaultStripingCount;
+ let sizeControlErrors = null;
+ if (sizeControl.value === null) {
+ sizeControlErrors = { required: true };
+ } else {
+ const sizeInBytes = formatter.toBytes(sizeControl.value);
+ if (stripingCount * objectSizeInBytes > sizeInBytes) {
+ sizeControlErrors = { invalidSizeObject: true };
+ }
+ }
+ sizeControl.setErrors(sizeControlErrors);
+ // Striping Unit
+ const stripingUnitControl = formGroup.get('stripingUnit');
+ let stripingUnitControlErrors = null;
+ if (stripingUnitControl.value === null && stripingCountControl.value !== null) {
+ stripingUnitControlErrors = { required: true };
+ } else if (stripingUnitControl.value !== null) {
+ const stripingUnitInBytes = formatter.toBytes(stripingUnitControl.value);
+ if (stripingUnitInBytes > objectSizeInBytes) {
+ stripingUnitControlErrors = { invalidStripingUnit: true };
+ }
+ }
+ stripingUnitControl.setErrors(stripingUnitControlErrors);
+ // Striping Count
+ let stripingCountControlErrors = null;
+ if (stripingCountControl.value === null && stripingUnitControl.value !== null) {
+ stripingCountControlErrors = { required: true };
+ } else if (stripingCount < 1) {
+ stripingCountControlErrors = { min: true };
+ }
+ stripingCountControl.setErrors(stripingCountControlErrors);
+ return null;
+ };
+ }
+
+ deepBoxCheck(key: string, checked: boolean) {
+ const childFeatures = this.getDependentChildFeatures(key);
+ childFeatures.forEach((feature) => {
+ const featureControl = this.rbdForm.get(feature.key);
+ if (checked) {
+ featureControl.enable({ emitEvent: false });
+ } else {
+ featureControl.disable({ emitEvent: false });
+ featureControl.setValue(false, { emitEvent: false });
+ this.deepBoxCheck(feature.key, checked);
+ }
+
+ const featureFormGroup = this.rbdForm.get('features');
+ if (this.mode === this.rbdFormMode.editing && featureFormGroup.get(feature.key).enabled) {
+ if (this.response.features_name.indexOf(feature.key) !== -1 && !feature.allowDisable) {
+ featureFormGroup.get(feature.key).disable();
+ } else if (
+ this.response.features_name.indexOf(feature.key) === -1 &&
+ !feature.allowEnable
+ ) {
+ featureFormGroup.get(feature.key).disable();
+ }
+ }
+ });
+ }
+
+ protected getDependentChildFeatures(featureKey: string) {
+ return _.filter(this.features, (f) => f.requires === featureKey) || [];
+ }
+
+ interlockCheck(key: string, checked: boolean) {
+ // Adds a compatibility layer for Ceph cluster where the feature interlock of features hasn't
+ // been implemented yet. It disables the feature interlock for images which only have one of
+ // both interlocked features (at the time of this writing: object-map and fast-diff) enabled.
+ const feature = this.featuresList.find((f) => f.key === key);
+ if (this.response) {
+ // Ignore `create` page
+ const hasInterlockedFeature = feature.interlockedWith != null;
+ const dependentInterlockedFeature = this.featuresList.find(
+ (f) => f.interlockedWith === feature.key
+ );
+ const isOriginFeatureEnabled = !!this.response.features_name.find((e) => e === feature.key); // in this case: fast-diff
+ if (hasInterlockedFeature) {
+ const isLinkedEnabled = !!this.response.features_name.find(
+ (e) => e === feature.interlockedWith
+ ); // depends: object-map
+ if (isOriginFeatureEnabled !== isLinkedEnabled) {
+ return; // Ignore incompatible setting because it's from a previous cluster version
+ }
+ } else if (dependentInterlockedFeature) {
+ const isOtherInterlockedFeatureEnabled = !!this.response.features_name.find(
+ (e) => e === dependentInterlockedFeature.key
+ );
+ if (isOtherInterlockedFeatureEnabled !== isOriginFeatureEnabled) {
+ return; // Ignore incompatible setting because it's from a previous cluster version
+ }
+ }
+ }
+
+ if (checked) {
+ _.filter(this.features, (f) => f.interlockedWith === key).forEach((f) =>
+ this.rbdForm.get(f.key).setValue(true, { emitEvent: false })
+ );
+ } else {
+ if (feature.interlockedWith) {
+ // Don't skip emitting the event here, as it prevents `fast-diff` from
+ // becoming disabled when manually unchecked. This is because it
+ // triggers an update on `object-map` and if `object-map` doesn't emit,
+ // `fast-diff` will not be automatically disabled.
+ this.rbdForm.get('features').get(feature.interlockedWith).setValue(false);
+ }
+ }
+ }
+
+ featureFormUpdate(key: string, checked: boolean) {
+ if (checked) {
+ const required = this.features[key].requires;
+ if (required && !this.rbdForm.getValue(required)) {
+ this.rbdForm.get(`features.${key}`).setValue(false);
+ return;
+ }
+ }
+ this.deepBoxCheck(key, checked);
+ this.interlockCheck(key, checked);
+ }
+
+ setFeatures(features: Array<string>) {
+ const featuresControl = this.rbdForm.get('features');
+ _.forIn(this.features, (feature) => {
+ if (features.indexOf(feature.key) !== -1) {
+ featuresControl.get(feature.key).setValue(true);
+ }
+ this.featureFormUpdate(feature.key, featuresControl.get(feature.key).value);
+ });
+ }
+
+ setResponse(response: RbdFormResponseModel, snapName: string) {
+ this.response = response;
+ const imageSpec = new ImageSpec(
+ response.pool_name,
+ response.namespace,
+ response.name
+ ).toString();
+ if (this.mode === this.rbdFormMode.cloning) {
+ this.rbdForm.get('parent').setValue(`${imageSpec}@${snapName}`);
+ } else if (this.mode === this.rbdFormMode.copying) {
+ if (snapName) {
+ this.rbdForm.get('parent').setValue(`${imageSpec}@${snapName}`);
+ } else {
+ this.rbdForm.get('parent').setValue(`${imageSpec}`);
+ }
+ } else if (response.parent) {
+ const parent = response.parent;
+ this.rbdForm
+ .get('parent')
+ .setValue(`${parent.pool_name}/${parent.image_name}@${parent.snap_name}`);
+ }
+ if (this.mode === this.rbdFormMode.editing) {
+ this.rbdForm.get('name').setValue(response.name);
+ if (response?.mirror_mode === 'snapshot' || response.features_name.includes('journaling')) {
+ this.mirroring = true;
+ this.rbdForm.get('mirroring').setValue(this.mirroring);
+ this.rbdForm.get('mirroringMode').setValue(response?.mirror_mode);
+ this.rbdForm.get('schedule').setValue(response?.schedule_interval);
+ } else {
+ this.mirroring = false;
+ this.rbdForm.get('mirroring').setValue(this.mirroring);
+ }
+ this.setPoolMirrorMode();
+ }
+ this.rbdForm.get('pool').setValue(response.pool_name);
+ this.onPoolChange(response.pool_name);
+ this.rbdForm.get('namespace').setValue(response.namespace);
+ if (response.data_pool) {
+ this.rbdForm.get('useDataPool').setValue(true);
+ this.rbdForm.get('dataPool').setValue(response.data_pool);
+ }
+ this.rbdForm.get('size').setValue(this.dimlessBinaryPipe.transform(response.size));
+ this.rbdForm.get('obj_size').setValue(this.dimlessBinaryPipe.transform(response.obj_size));
+ this.setFeatures(response.features_name);
+ this.rbdForm
+ .get('stripingUnit')
+ .setValue(this.dimlessBinaryPipe.transform(response.stripe_unit));
+ this.rbdForm.get('stripingCount').setValue(response.stripe_count);
+ /* Configuration */
+ this.initializeConfigData.next({
+ initialData: this.response.configuration,
+ sourceType: RbdConfigurationSourceField.image
+ });
+ }
+
+ createRequest() {
+ const request = new RbdFormCreateRequestModel();
+ request.pool_name = this.rbdForm.getValue('pool');
+ request.namespace = this.rbdForm.getValue('namespace');
+ request.name = this.rbdForm.getValue('name');
+ request.schedule_interval = this.rbdForm.getValue('schedule');
+ request.size = this.formatter.toBytes(this.rbdForm.getValue('size'));
+ if (this.poolMirrorMode === 'image') {
+ request.mirror_mode = this.rbdForm.getValue('mirroringMode');
+ }
+ this.addObjectSizeAndStripingToRequest(request);
+ request.configuration = this.getDirtyConfigurationValues();
+ return request;
+ }
+
+ private addObjectSizeAndStripingToRequest(
+ request: RbdFormCreateRequestModel | RbdFormCloneRequestModel | RbdFormCopyRequestModel
+ ) {
+ request.obj_size = this.formatter.toBytes(this.rbdForm.getValue('obj_size'));
+ _.forIn(this.features, (feature) => {
+ if (this.rbdForm.getValue(feature.key)) {
+ request.features.push(feature.key);
+ }
+ });
+
+ if (this.mirroring && this.rbdForm.getValue('mirroringMode') === 'journal') {
+ request.features.push('journaling');
+ }
+
+ /* Striping */
+ request.stripe_unit = this.formatter.toBytes(this.rbdForm.getValue('stripingUnit'));
+ request.stripe_count = this.rbdForm.getValue('stripingCount');
+ request.data_pool = this.rbdForm.getValue('dataPool');
+ }
+
+ createAction(): Observable<any> {
+ const request = this.createRequest();
+ return this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('rbd/create', {
+ pool_name: request.pool_name,
+ namespace: request.namespace,
+ image_name: request.name,
+ schedule_interval: request.schedule_interval,
+ start_time: request.start_time
+ }),
+ call: this.rbdService.create(request)
+ });
+ }
+
+ editRequest() {
+ const request = new RbdFormEditRequestModel();
+ request.name = this.rbdForm.getValue('name');
+ request.schedule_interval = this.rbdForm.getValue('schedule');
+ request.name = this.rbdForm.getValue('name');
+ request.size = this.formatter.toBytes(this.rbdForm.getValue('size'));
+ _.forIn(this.features, (feature) => {
+ if (this.rbdForm.getValue(feature.key)) {
+ request.features.push(feature.key);
+ }
+ });
+ request.enable_mirror = this.rbdForm.getValue('mirroring');
+ if (request.enable_mirror) {
+ if (this.rbdForm.getValue('mirroringMode') === 'journal') {
+ request.features.push('journaling');
+ }
+ if (this.poolMirrorMode === 'image') {
+ request.mirror_mode = this.rbdForm.getValue('mirroringMode');
+ }
+ } else {
+ const index = request.features.indexOf('journaling', 0);
+ if (index > -1) {
+ request.features.splice(index, 1);
+ }
+ }
+ request.configuration = this.getDirtyConfigurationValues();
+ return request;
+ }
+
+ cloneRequest(): RbdFormCloneRequestModel {
+ const request = new RbdFormCloneRequestModel();
+ request.child_pool_name = this.rbdForm.getValue('pool');
+ request.child_namespace = this.rbdForm.getValue('namespace');
+ request.child_image_name = this.rbdForm.getValue('name');
+ this.addObjectSizeAndStripingToRequest(request);
+ request.configuration = this.getDirtyConfigurationValues(
+ true,
+ RbdConfigurationSourceField.image
+ );
+ return request;
+ }
+
+ editAction(): Observable<any> {
+ const imageSpec = new ImageSpec(
+ this.response.pool_name,
+ this.response.namespace,
+ this.response.name
+ );
+ return this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('rbd/edit', {
+ image_spec: imageSpec.toString()
+ }),
+ call: this.rbdService.update(imageSpec, this.editRequest())
+ });
+ }
+
+ cloneAction(): Observable<any> {
+ const request = this.cloneRequest();
+ const imageSpec = new ImageSpec(
+ this.response.pool_name,
+ this.response.namespace,
+ this.response.name
+ );
+ return this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('rbd/clone', {
+ parent_image_spec: imageSpec.toString(),
+ parent_snap_name: this.snapName,
+ child_pool_name: request.child_pool_name,
+ child_namespace: request.child_namespace,
+ child_image_name: request.child_image_name
+ }),
+ call: this.rbdService.cloneSnapshot(imageSpec, this.snapName, request)
+ });
+ }
+
+ copyRequest(): RbdFormCopyRequestModel {
+ const request = new RbdFormCopyRequestModel();
+ if (this.snapName) {
+ request.snapshot_name = this.snapName;
+ }
+ request.dest_pool_name = this.rbdForm.getValue('pool');
+ request.dest_namespace = this.rbdForm.getValue('namespace');
+ request.dest_image_name = this.rbdForm.getValue('name');
+ this.addObjectSizeAndStripingToRequest(request);
+ request.configuration = this.getDirtyConfigurationValues(
+ true,
+ RbdConfigurationSourceField.image
+ );
+ return request;
+ }
+
+ copyAction(): Observable<any> {
+ const request = this.copyRequest();
+ const imageSpec = new ImageSpec(
+ this.response.pool_name,
+ this.response.namespace,
+ this.response.name
+ );
+ return this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('rbd/copy', {
+ src_image_spec: imageSpec.toString(),
+ dest_pool_name: request.dest_pool_name,
+ dest_namespace: request.dest_namespace,
+ dest_image_name: request.dest_image_name
+ }),
+ call: this.rbdService.copy(imageSpec, request)
+ });
+ }
+
+ submit() {
+ if (!this.mode) {
+ this.rbdImage.next('create');
+ }
+ this.rbdImage
+ .pipe(
+ first(),
+ switchMap(() => {
+ if (this.mode === this.rbdFormMode.editing) {
+ return this.editAction();
+ } else if (this.mode === this.rbdFormMode.cloning) {
+ return this.cloneAction();
+ } else if (this.mode === this.rbdFormMode.copying) {
+ return this.copyAction();
+ } else {
+ return this.createAction();
+ }
+ })
+ )
+ .subscribe(
+ () => undefined,
+ () => this.rbdForm.setErrors({ cdSubmitButton: true }),
+ () => this.router.navigate(['/block/rbd'])
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.model.ts
new file mode 100644
index 000000000..262d79c95
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.model.ts
@@ -0,0 +1,26 @@
+import { RbdConfigurationEntry } from '~/app/shared/models/configuration';
+
+export class RbdFormModel {
+ name: string;
+ pool_name: string;
+ namespace: string;
+ data_pool: string;
+ size: number;
+
+ /* Striping */
+ obj_size: number;
+ stripe_unit: number;
+ stripe_count: number;
+
+ /* Configuration */
+ configuration: RbdConfigurationEntry[];
+
+ /* Deletion process */
+ source?: string;
+
+ enable_mirror?: boolean;
+ mirror_mode?: string;
+
+ schedule_interval: string;
+ start_time: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-parent.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-parent.model.ts
new file mode 100644
index 000000000..000717b0a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-parent.model.ts
@@ -0,0 +1,6 @@
+export class RbdParentModel {
+ image_name: string;
+ pool_name: string;
+ pool_namespace: string;
+ snap_name: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.html
new file mode 100644
index 000000000..712d771c5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.html
@@ -0,0 +1,128 @@
+<cd-rbd-tabs></cd-rbd-tabs>
+
+<cd-table #table
+ [data]="images"
+ columnMode="flex"
+ [columns]="columns"
+ identifier="unique_id"
+ [searchableObjects]="true"
+ [serverSide]="true"
+ [count]="count"
+ forceIdentifier="true"
+ selectionType="single"
+ [hasDetails]="true"
+ [status]="tableStatus"
+ [maxLimit]="25"
+ [autoReload]="-1"
+ (fetchData)="taskListService.fetch($event)"
+ (setExpandedRow)="setExpandedRow($event)"
+ (updateSelection)="updateSelection($event)">
+ <cd-table-actions class="table-actions"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ <cd-rbd-details cdTableDetail
+ [selection]="expandedRow">
+ </cd-rbd-details>
+</cd-table>
+
+<ng-template #scheduleStatus>
+ <div i18n
+ [innerHtml]="'Only available for RBD images with <strong>fast-diff</strong> enabled'"></div>
+</ng-template>
+
+<ng-template #provisionedNotAvailableTooltipTpl
+ let-row="row">
+ <span *ngIf="row.disk_usage === null && !row.features_name.includes('fast-diff'); else provisioned"
+ [ngbTooltip]="usageNotAvailableTooltipTpl"
+ placement="top"
+ i18n>N/A</span>
+ <ng-template #provisioned
+ i18n>{{row.disk_usage | dimlessBinary}}</ng-template>
+</ng-template>
+
+<ng-template #totalProvisionedNotAvailableTooltipTpl
+ let-row="row">
+ <span *ngIf="row.total_disk_usage === null && !row.features_name.includes('fast-diff'); else totalProvisioned"
+ [ngbTooltip]="usageNotAvailableTooltipTpl"
+ placement="top"
+ i18n>N/A</span>
+ <ng-template #totalProvisioned
+ i18n>{{row.total_disk_usage | dimlessBinary}}</ng-template>
+</ng-template>
+
+<ng-template #parentTpl
+ let-value="value">
+ <span *ngIf="value">{{ value.pool_name }}<span
+ *ngIf="value.pool_namespace">/{{ value.pool_namespace }}</span>/{{ value.image_name }}@{{ value.snap_name }}</span>
+ <span *ngIf="!value">-</span>
+</ng-template>
+
+<ng-template #mirroringTpl
+ let-value="value"
+ let-row="row">
+ <span *ngIf="value.length === 3; else probb"
+ class="badge badge-info">{{ value[0] }}</span>&nbsp;
+ <span *ngIf="value.length === 3"
+ class="badge badge-info"
+ [ngbTooltip]="'Next scheduled snapshot on' + ' ' + (value[2] | cdDate)">{{ value[1] }}</span>
+ <span *ngIf="row.primary === true"
+ class="badge badge-info"
+ i18n>primary</span>
+ <span *ngIf="row.primary === false"
+ class="badge badge-info"
+ i18n>secondary</span>
+ <ng-template #probb>
+ <span class="badge badge-info">{{ value }}</span>
+ </ng-template>
+</ng-template>
+
+<ng-template #flattenTpl
+ let-value>
+ You are about to flatten
+ <strong>{{ value.child }}</strong>.
+ <br>
+ <br> All blocks will be copied from parent
+ <strong>{{ value.parent }}</strong> to child
+ <strong>{{ value.child }}</strong>.
+</ng-template>
+
+<ng-template #deleteTpl
+ let-hasSnapshots="hasSnapshots"
+ let-snapshots="snapshots">
+ <div class="alert alert-warning"
+ *ngIf="hasSnapshots"
+ role="alert">
+ <span i18n>Deleting this image will also delete all its snapshots.</span>
+ <br>
+ <ng-container *ngIf="snapshots.length > 0">
+ <span i18n>The following snapshots are currently protected and will be removed:</span>
+ <ul>
+ <li *ngFor="let snapshot of snapshots">{{ snapshot }}</li>
+ </ul>
+ </ng-container>
+ </div>
+</ng-template>
+
+<ng-template #removingStatTpl
+ let-column="column"
+ let-value="value"
+ let-row="row">
+
+ <i [ngClass]="[icons.spinner, icons.spin]"
+ *ngIf="row.cdExecuting"></i>
+ <span [ngClass]="column?.customTemplateConfig?.valueClass">
+ {{ value }}
+ </span>
+ <span *ngIf="row.cdExecuting"
+ [ngClass]="column?.customTemplateConfig?.executingClass ?
+ column.customTemplateConfig.executingClass :
+ 'text-muted italic'">
+ ({{ row.cdExecuting }})
+ </span>
+ <i *ngIf="row.source && row.source === 'REMOVING'"
+ i18n-title
+ title="RBD in status 'Removing'"
+ class="{{ icons.warning }} warn"></i>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.scss
new file mode 100644
index 000000000..4cfa4e8da
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.scss
@@ -0,0 +1,5 @@
+@use './src/styles/vendor/variables' as vv;
+
+.warn {
+ color: vv.$warning;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.spec.ts
new file mode 100644
index 000000000..fa7a772f0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.spec.ts
@@ -0,0 +1,438 @@
+import { HttpHeaders } from '@angular/common/http';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { BehaviorSubject, of } from 'rxjs';
+
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
+import { ExecutingTask } from '~/app/shared/models/executing-task';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { TaskListService } from '~/app/shared/services/task-list.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, expectItemTasks, PermissionHelper } from '~/testing/unit-test-helper';
+import { RbdConfigurationListComponent } from '../rbd-configuration-list/rbd-configuration-list.component';
+import { RbdDetailsComponent } from '../rbd-details/rbd-details.component';
+import { RbdSnapshotListComponent } from '../rbd-snapshot-list/rbd-snapshot-list.component';
+import { RbdTabsComponent } from '../rbd-tabs/rbd-tabs.component';
+import { RbdListComponent } from './rbd-list.component';
+import { RbdModel } from './rbd-model';
+
+describe('RbdListComponent', () => {
+ let fixture: ComponentFixture<RbdListComponent>;
+ let component: RbdListComponent;
+ let summaryService: SummaryService;
+ let rbdService: RbdService;
+ let headers: HttpHeaders;
+
+ const refresh = (data: any) => {
+ summaryService['summaryDataSource'].next(data);
+ };
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ SharedModule,
+ NgbNavModule,
+ NgbTooltipModule,
+ ToastrModule.forRoot(),
+ RouterTestingModule,
+ HttpClientTestingModule
+ ],
+ declarations: [
+ RbdListComponent,
+ RbdDetailsComponent,
+ RbdSnapshotListComponent,
+ RbdConfigurationListComponent,
+ RbdTabsComponent
+ ],
+ providers: [TaskListService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RbdListComponent);
+ component = fixture.componentInstance;
+ summaryService = TestBed.inject(SummaryService);
+ rbdService = TestBed.inject(RbdService);
+ headers = new HttpHeaders().set('X-Total-Count', '10');
+
+ // this is needed because summaryService isn't being reset after each test.
+ summaryService['summaryDataSource'] = new BehaviorSubject(null);
+ summaryService['summaryData$'] = summaryService['summaryDataSource'].asObservable();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('after ngOnInit', () => {
+ beforeEach(() => {
+ fixture.detectChanges();
+ spyOn(rbdService, 'list').and.callThrough();
+ });
+
+ it('should load images on init', () => {
+ refresh({});
+ expect(rbdService.list).toHaveBeenCalled();
+ });
+
+ it('should not load images on init because no data', () => {
+ refresh(undefined);
+ expect(rbdService.list).not.toHaveBeenCalled();
+ });
+
+ it('should call error function on init when summary service fails', () => {
+ spyOn(component.table, 'reset');
+ summaryService['summaryDataSource'].error(undefined);
+ expect(component.table.reset).toHaveBeenCalled();
+ });
+ });
+
+ describe('handling of provisioned columns', () => {
+ let rbdServiceListSpy: jasmine.Spy;
+
+ const images = [
+ {
+ name: 'img1',
+ pool_name: 'rbd',
+ features_name: ['layering', 'exclusive-lock'],
+ disk_usage: null,
+ total_disk_usage: null
+ },
+ {
+ name: 'img2',
+ pool_name: 'rbd',
+ features_name: ['layering', 'exclusive-lock', 'object-map', 'fast-diff'],
+ disk_usage: 1024,
+ total_disk_usage: 1024
+ }
+ ];
+
+ beforeEach(() => {
+ component.images = images;
+ refresh({ executing_tasks: [], finished_tasks: [] });
+ rbdServiceListSpy = spyOn(rbdService, 'list');
+ });
+
+ it('should display N/A for Provisioned & Total Provisioned columns if disk usage is null', () => {
+ rbdServiceListSpy.and.callFake(() =>
+ of([{ pool_name: 'rbd', value: images, headers: headers }])
+ );
+ fixture.detectChanges();
+ const spanWithoutFastDiff = fixture.debugElement.nativeElement.querySelectorAll(
+ '.datatable-body-cell-label span'
+ );
+ // check image with disk usage = null & fast-diff disabled
+ expect(spanWithoutFastDiff[6].textContent).toBe('N/A');
+
+ images[0]['features_name'] = ['layering', 'exclusive-lock', 'object-map', 'fast-diff'];
+ component.images = images;
+ refresh({ executing_tasks: [], finished_tasks: [] });
+
+ rbdServiceListSpy.and.callFake(() =>
+ of([{ pool_name: 'rbd', value: images, headers: headers }])
+ );
+ fixture.detectChanges();
+
+ const spanWithFastDiff = fixture.debugElement.nativeElement.querySelectorAll(
+ '.datatable-body-cell-label span'
+ );
+ // check image with disk usage = null & fast-diff changed to enabled
+ expect(spanWithFastDiff[6].textContent).toBe('-');
+ });
+ });
+
+ describe('handling of deletion', () => {
+ beforeEach(() => {
+ fixture.detectChanges();
+ });
+
+ it('should check if there are no snapshots', () => {
+ component.selection.add({
+ id: '-1',
+ name: 'rbd1',
+ pool_name: 'rbd'
+ });
+ expect(component.hasSnapshots()).toBeFalsy();
+ });
+
+ it('should check if there are snapshots', () => {
+ component.selection.add({
+ id: '-1',
+ name: 'rbd1',
+ pool_name: 'rbd',
+ snapshots: [{}, {}]
+ });
+ expect(component.hasSnapshots()).toBeTruthy();
+ });
+
+ it('should get delete disable description', () => {
+ component.selection.add({
+ id: '-1',
+ name: 'rbd1',
+ pool_name: 'rbd',
+ snapshots: [
+ {
+ children: [{}]
+ }
+ ]
+ });
+ expect(component.getDeleteDisableDesc(component.selection)).toBe(
+ 'This RBD has cloned snapshots. Please delete related RBDs before deleting this RBD.'
+ );
+ });
+
+ it('should list all protected snapshots', () => {
+ component.selection.add({
+ id: '-1',
+ name: 'rbd1',
+ pool_name: 'rbd',
+ snapshots: [
+ {
+ name: 'snap1',
+ is_protected: false
+ },
+ {
+ name: 'snap2',
+ is_protected: true
+ }
+ ]
+ });
+
+ expect(component.listProtectedSnapshots()).toEqual(['snap2']);
+ });
+ });
+
+ describe('handling of executing tasks', () => {
+ let images: RbdModel[];
+
+ const addImage = (name: string) => {
+ const model = new RbdModel();
+ model.id = '-1';
+ model.name = name;
+ model.pool_name = 'rbd';
+ images.push(model);
+ };
+
+ const addTask = (name: string, image_name: string) => {
+ const task = new ExecutingTask();
+ task.name = name;
+ switch (task.name) {
+ case 'rbd/copy':
+ task.metadata = {
+ dest_pool_name: 'rbd',
+ dest_namespace: null,
+ dest_image_name: 'd'
+ };
+ break;
+ case 'rbd/clone':
+ task.metadata = {
+ child_pool_name: 'rbd',
+ child_namespace: null,
+ child_image_name: 'd'
+ };
+ break;
+ case 'rbd/create':
+ task.metadata = {
+ pool_name: 'rbd',
+ namespace: null,
+ image_name: image_name
+ };
+ break;
+ default:
+ task.metadata = {
+ image_spec: `rbd/${image_name}`
+ };
+ break;
+ }
+ summaryService.addRunningTask(task);
+ };
+
+ beforeEach(() => {
+ images = [];
+ addImage('a');
+ addImage('b');
+ addImage('c');
+ component.images = images;
+ refresh({ executing_tasks: [], finished_tasks: [] });
+ spyOn(rbdService, 'list').and.callFake(() =>
+ of([{ pool_name: 'rbd', value: images, headers: headers }])
+ );
+ fixture.detectChanges();
+ });
+
+ it('should gets all images without tasks', () => {
+ expect(component.images.length).toBe(3);
+ expect(component.images.every((image: any) => !image.cdExecuting)).toBeTruthy();
+ });
+
+ it('should add a new image from a task', () => {
+ addTask('rbd/create', 'd');
+ expect(component.images.length).toBe(4);
+ expectItemTasks(component.images[0], undefined);
+ expectItemTasks(component.images[1], undefined);
+ expectItemTasks(component.images[2], undefined);
+ expectItemTasks(component.images[3], 'Creating');
+ });
+
+ it('should show when a image is being cloned', () => {
+ addTask('rbd/clone', 'd');
+ expect(component.images.length).toBe(4);
+ expectItemTasks(component.images[0], undefined);
+ expectItemTasks(component.images[1], undefined);
+ expectItemTasks(component.images[2], undefined);
+ expectItemTasks(component.images[3], 'Cloning');
+ });
+
+ it('should show when a image is being copied', () => {
+ addTask('rbd/copy', 'd');
+ expect(component.images.length).toBe(4);
+ expectItemTasks(component.images[0], undefined);
+ expectItemTasks(component.images[1], undefined);
+ expectItemTasks(component.images[2], undefined);
+ expectItemTasks(component.images[3], 'Copying');
+ });
+
+ it('should show when an existing image is being modified', () => {
+ addTask('rbd/edit', 'a');
+ expectItemTasks(component.images[0], 'Updating');
+ addTask('rbd/delete', 'b');
+ expectItemTasks(component.images[1], 'Deleting');
+ addTask('rbd/flatten', 'c');
+ expectItemTasks(component.images[2], 'Flattening');
+ expect(component.images.length).toBe(3);
+ });
+ });
+
+ it('should test all TableActions combinations', () => {
+ const permissionHelper: PermissionHelper = new PermissionHelper(component.permission);
+ const tableActions: TableActionsComponent = permissionHelper.setPermissionsAndGetActions(
+ component.tableActions
+ );
+
+ expect(tableActions).toEqual({
+ 'create,update,delete': {
+ actions: [
+ 'Create',
+ 'Edit',
+ 'Copy',
+ 'Flatten',
+ 'Resync',
+ 'Delete',
+ 'Move to Trash',
+ 'Remove Scheduling',
+ 'Promote',
+ 'Demote'
+ ],
+ primary: { multiple: 'Create', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,update': {
+ actions: [
+ 'Create',
+ 'Edit',
+ 'Copy',
+ 'Flatten',
+ 'Resync',
+ 'Remove Scheduling',
+ 'Promote',
+ 'Demote'
+ ],
+ primary: { multiple: 'Create', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,delete': {
+ actions: ['Create', 'Copy', 'Delete', 'Move to Trash'],
+ primary: { multiple: 'Create', executing: 'Copy', single: 'Copy', no: 'Create' }
+ },
+ create: {
+ actions: ['Create', 'Copy'],
+ primary: { multiple: 'Create', executing: 'Copy', single: 'Copy', no: 'Create' }
+ },
+ 'update,delete': {
+ actions: [
+ 'Edit',
+ 'Flatten',
+ 'Resync',
+ 'Delete',
+ 'Move to Trash',
+ 'Remove Scheduling',
+ 'Promote',
+ 'Demote'
+ ],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ update: {
+ actions: ['Edit', 'Flatten', 'Resync', 'Remove Scheduling', 'Promote', 'Demote'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ delete: {
+ actions: ['Delete', 'Move to Trash'],
+ primary: { multiple: 'Delete', executing: 'Delete', single: 'Delete', no: 'Delete' }
+ },
+ 'no-permissions': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ }
+ });
+ });
+
+ const getActionDisable = (name: string) =>
+ component.tableActions.find((o) => o.name === name).disable;
+
+ const testActions = (selection: any, expected: { [action: string]: string | boolean }) => {
+ expect(getActionDisable('Edit')(selection)).toBe(expected.edit || false);
+ expect(getActionDisable('Delete')(selection)).toBe(expected.delete || false);
+ expect(getActionDisable('Copy')(selection)).toBe(expected.copy || false);
+ expect(getActionDisable('Flatten')(selection)).toBeTruthy();
+ expect(getActionDisable('Move to Trash')(selection)).toBe(expected.moveTrash || false);
+ };
+
+ it('should test TableActions with valid/invalid image name', () => {
+ component.selection.selected = [
+ {
+ name: 'foobar',
+ pool_name: 'rbd',
+ snapshots: []
+ }
+ ];
+ testActions(component.selection, {});
+
+ component.selection.selected = [
+ {
+ name: 'foo/bar',
+ pool_name: 'rbd',
+ snapshots: []
+ }
+ ];
+ const message = `This RBD image has an invalid name and can't be managed by ceph.`;
+ const expected = {
+ edit: message,
+ delete: message,
+ copy: message,
+ moveTrash: message
+ };
+ testActions(component.selection, expected);
+ });
+
+ it('should disable edit, copy, flatten and move action if RBD is in status `Removing`', () => {
+ component.selection.selected = [
+ {
+ name: 'foobar',
+ pool_name: 'rbd',
+ snapshots: [],
+ source: 'REMOVING'
+ }
+ ];
+
+ const message = `Action not possible for an RBD in status 'Removing'`;
+ const expected = {
+ edit: message,
+ copy: message,
+ moveTrash: message
+ };
+ testActions(component.selection, expected);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.ts
new file mode 100644
index 000000000..a24e59f82
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.ts
@@ -0,0 +1,629 @@
+import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { Observable, Subscriber } from 'rxjs';
+
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
+import { TableStatus } from '~/app/shared/classes/table-status';
+import { ConfirmationModalComponent } from '~/app/shared/components/confirmation-modal/confirmation-modal.component';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { TableComponent } from '~/app/shared/datatable/table/table.component';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { ImageSpec } from '~/app/shared/models/image-spec';
+import { Permission } from '~/app/shared/models/permissions';
+import { Task } from '~/app/shared/models/task';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { DimlessPipe } from '~/app/shared/pipes/dimless.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { CdTableServerSideService } from '~/app/shared/services/cd-table-server-side.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { TaskListService } from '~/app/shared/services/task-list.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { URLBuilderService } from '~/app/shared/services/url-builder.service';
+import { RbdFormEditRequestModel } from '../rbd-form/rbd-form-edit-request.model';
+import { RbdParentModel } from '../rbd-form/rbd-parent.model';
+import { RbdTrashMoveModalComponent } from '../rbd-trash-move-modal/rbd-trash-move-modal.component';
+import { RBDImageFormat, RbdModel } from './rbd-model';
+
+const BASE_URL = 'block/rbd';
+
+@Component({
+ selector: 'cd-rbd-list',
+ templateUrl: './rbd-list.component.html',
+ styleUrls: ['./rbd-list.component.scss'],
+ providers: [
+ TaskListService,
+ { provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }
+ ]
+})
+export class RbdListComponent extends ListWithDetails implements OnInit {
+ @ViewChild(TableComponent, { static: true })
+ table: TableComponent;
+ @ViewChild('usageTpl')
+ usageTpl: TemplateRef<any>;
+ @ViewChild('parentTpl', { static: true })
+ parentTpl: TemplateRef<any>;
+ @ViewChild('nameTpl')
+ nameTpl: TemplateRef<any>;
+ @ViewChild('mirroringTpl', { static: true })
+ mirroringTpl: TemplateRef<any>;
+ @ViewChild('flattenTpl', { static: true })
+ flattenTpl: TemplateRef<any>;
+ @ViewChild('deleteTpl', { static: true })
+ deleteTpl: TemplateRef<any>;
+ @ViewChild('removingStatTpl', { static: true })
+ removingStatTpl: TemplateRef<any>;
+ @ViewChild('provisionedNotAvailableTooltipTpl', { static: true })
+ provisionedNotAvailableTooltipTpl: TemplateRef<any>;
+ @ViewChild('totalProvisionedNotAvailableTooltipTpl', { static: true })
+ totalProvisionedNotAvailableTooltipTpl: TemplateRef<any>;
+
+ permission: Permission;
+ tableActions: CdTableAction[];
+ images: any;
+ columns: CdTableColumn[];
+ retries: number;
+ tableStatus = new TableStatus('light');
+ selection = new CdTableSelection();
+ icons = Icons;
+ count = 0;
+ private tableContext: CdTableFetchDataContext = null;
+ modalRef: NgbModalRef;
+
+ builders = {
+ 'rbd/create': (metadata: object) =>
+ this.createRbdFromTask(metadata['pool_name'], metadata['namespace'], metadata['image_name']),
+ 'rbd/delete': (metadata: object) => this.createRbdFromTaskImageSpec(metadata['image_spec']),
+ 'rbd/clone': (metadata: object) =>
+ this.createRbdFromTask(
+ metadata['child_pool_name'],
+ metadata['child_namespace'],
+ metadata['child_image_name']
+ ),
+ 'rbd/copy': (metadata: object) =>
+ this.createRbdFromTask(
+ metadata['dest_pool_name'],
+ metadata['dest_namespace'],
+ metadata['dest_image_name']
+ )
+ };
+ remove_scheduling: boolean;
+
+ private createRbdFromTaskImageSpec(imageSpecStr: string): RbdModel {
+ const imageSpec = ImageSpec.fromString(imageSpecStr);
+ return this.createRbdFromTask(imageSpec.poolName, imageSpec.namespace, imageSpec.imageName);
+ }
+
+ private createRbdFromTask(pool: string, namespace: string, name: string): RbdModel {
+ const model = new RbdModel();
+ model.id = '-1';
+ model.unique_id = '-1';
+ model.name = name;
+ model.namespace = namespace;
+ model.pool_name = pool;
+ model.image_format = RBDImageFormat.V2;
+ return model;
+ }
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private rbdService: RbdService,
+ private dimlessBinaryPipe: DimlessBinaryPipe,
+ private dimlessPipe: DimlessPipe,
+ private modalService: ModalService,
+ private taskWrapper: TaskWrapperService,
+ public taskListService: TaskListService,
+ private urlBuilder: URLBuilderService,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ super();
+ this.permission = this.authStorageService.getPermissions().rbdImage;
+ const getImageUri = () =>
+ this.selection.first() &&
+ new ImageSpec(
+ this.selection.first().pool_name,
+ this.selection.first().namespace,
+ this.selection.first().name
+ ).toStringEncoded();
+ const addAction: CdTableAction = {
+ permission: 'create',
+ icon: Icons.add,
+ routerLink: () => this.urlBuilder.getCreate(),
+ canBePrimary: (selection: CdTableSelection) => !selection.hasSingleSelection,
+ name: this.actionLabels.CREATE
+ };
+ const editAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.edit,
+ routerLink: () => this.urlBuilder.getEdit(getImageUri()),
+ name: this.actionLabels.EDIT,
+ disable: (selection: CdTableSelection) =>
+ this.getRemovingStatusDesc(selection) || this.getInvalidNameDisable(selection)
+ };
+ const deleteAction: CdTableAction = {
+ permission: 'delete',
+ icon: Icons.destroy,
+ click: () => this.deleteRbdModal(),
+ name: this.actionLabels.DELETE,
+ disable: (selection: CdTableSelection) => this.getDeleteDisableDesc(selection)
+ };
+ const resyncAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.refresh,
+ click: () => this.resyncRbdModal(),
+ name: this.actionLabels.RESYNC,
+ disable: (selection: CdTableSelection) => this.getResyncDisableDesc(selection)
+ };
+ const copyAction: CdTableAction = {
+ permission: 'create',
+ canBePrimary: (selection: CdTableSelection) => selection.hasSingleSelection,
+ disable: (selection: CdTableSelection) =>
+ this.getRemovingStatusDesc(selection) ||
+ this.getInvalidNameDisable(selection) ||
+ !!selection.first().cdExecuting,
+ icon: Icons.copy,
+ routerLink: () => `/block/rbd/copy/${getImageUri()}`,
+ name: this.actionLabels.COPY
+ };
+ const flattenAction: CdTableAction = {
+ permission: 'update',
+ disable: (selection: CdTableSelection) =>
+ this.getRemovingStatusDesc(selection) ||
+ this.getInvalidNameDisable(selection) ||
+ selection.first().cdExecuting ||
+ !selection.first().parent,
+ icon: Icons.flatten,
+ click: () => this.flattenRbdModal(),
+ name: this.actionLabels.FLATTEN
+ };
+ const moveAction: CdTableAction = {
+ permission: 'delete',
+ icon: Icons.trash,
+ click: () => this.trashRbdModal(),
+ name: this.actionLabels.TRASH,
+ disable: (selection: CdTableSelection) =>
+ this.getRemovingStatusDesc(selection) ||
+ this.getInvalidNameDisable(selection) ||
+ selection.first().image_format === RBDImageFormat.V1
+ };
+ const removeSchedulingAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.edit,
+ click: () => this.removeSchedulingModal(),
+ name: this.actionLabels.REMOVE_SCHEDULING,
+ disable: (selection: CdTableSelection) =>
+ this.getRemovingStatusDesc(selection) ||
+ this.getInvalidNameDisable(selection) ||
+ selection.first().schedule_info === undefined
+ };
+ const promoteAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.edit,
+ click: () => this.actionPrimary(true),
+ name: this.actionLabels.PROMOTE,
+ visible: () => this.selection.first() != null && !this.selection.first().primary
+ };
+ const demoteAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.edit,
+ click: () => this.actionPrimary(false),
+ name: this.actionLabels.DEMOTE,
+ visible: () => this.selection.first() != null && this.selection.first().primary
+ };
+ this.tableActions = [
+ addAction,
+ editAction,
+ copyAction,
+ flattenAction,
+ resyncAction,
+ deleteAction,
+ moveAction,
+ removeSchedulingAction,
+ promoteAction,
+ demoteAction
+ ];
+ }
+
+ ngOnInit() {
+ this.columns = [
+ {
+ name: $localize`Name`,
+ prop: 'name',
+ flexGrow: 2,
+ cellTemplate: this.removingStatTpl
+ },
+ {
+ name: $localize`Pool`,
+ prop: 'pool_name',
+ flexGrow: 2
+ },
+ {
+ name: $localize`Namespace`,
+ prop: 'namespace',
+ flexGrow: 2
+ },
+ {
+ name: $localize`Size`,
+ prop: 'size',
+ flexGrow: 1,
+ cellClass: 'text-right',
+ sortable: false,
+ pipe: this.dimlessBinaryPipe
+ },
+ {
+ name: $localize`Objects`,
+ prop: 'num_objs',
+ flexGrow: 1,
+ cellClass: 'text-right',
+ sortable: false,
+ pipe: this.dimlessPipe
+ },
+ {
+ name: $localize`Object size`,
+ prop: 'obj_size',
+ flexGrow: 1,
+ cellClass: 'text-right',
+ sortable: false,
+ pipe: this.dimlessBinaryPipe
+ },
+ {
+ name: $localize`Provisioned`,
+ prop: 'disk_usage',
+ cellClass: 'text-center',
+ flexGrow: 1,
+ pipe: this.dimlessBinaryPipe,
+ sortable: false,
+ cellTemplate: this.provisionedNotAvailableTooltipTpl
+ },
+ {
+ name: $localize`Total provisioned`,
+ prop: 'total_disk_usage',
+ cellClass: 'text-center',
+ flexGrow: 1,
+ pipe: this.dimlessBinaryPipe,
+ sortable: false,
+ cellTemplate: this.totalProvisionedNotAvailableTooltipTpl
+ },
+ {
+ name: $localize`Parent`,
+ prop: 'parent',
+ flexGrow: 2,
+ sortable: false,
+ cellTemplate: this.parentTpl
+ },
+ {
+ name: $localize`Mirroring`,
+ prop: 'mirror_mode',
+ flexGrow: 3,
+ sortable: false,
+ cellTemplate: this.mirroringTpl
+ }
+ ];
+
+ const itemFilter = (entry: Record<string, any>, task: Task) => {
+ let taskImageSpec: string;
+ switch (task.name) {
+ case 'rbd/copy':
+ taskImageSpec = new ImageSpec(
+ task.metadata['dest_pool_name'],
+ task.metadata['dest_namespace'],
+ task.metadata['dest_image_name']
+ ).toString();
+ break;
+ case 'rbd/clone':
+ taskImageSpec = new ImageSpec(
+ task.metadata['child_pool_name'],
+ task.metadata['child_namespace'],
+ task.metadata['child_image_name']
+ ).toString();
+ break;
+ case 'rbd/create':
+ taskImageSpec = new ImageSpec(
+ task.metadata['pool_name'],
+ task.metadata['namespace'],
+ task.metadata['image_name']
+ ).toString();
+ break;
+ default:
+ taskImageSpec = task.metadata['image_spec'];
+ break;
+ }
+ return (
+ taskImageSpec === new ImageSpec(entry.pool_name, entry.namespace, entry.name).toString()
+ );
+ };
+
+ const taskFilter = (task: Task) => {
+ return [
+ 'rbd/clone',
+ 'rbd/copy',
+ 'rbd/create',
+ 'rbd/delete',
+ 'rbd/edit',
+ 'rbd/flatten',
+ 'rbd/trash/move'
+ ].includes(task.name);
+ };
+
+ this.taskListService.init(
+ (context) => this.getRbdImages(context),
+ (resp) => this.prepareResponse(resp),
+ (images) => (this.images = images),
+ () => this.onFetchError(),
+ taskFilter,
+ itemFilter,
+ this.builders
+ );
+ }
+
+ onFetchError() {
+ this.table.reset(); // Disable loading indicator.
+ this.tableStatus = new TableStatus('danger');
+ }
+
+ getRbdImages(context: CdTableFetchDataContext) {
+ if (context !== null) {
+ this.tableContext = context;
+ }
+ if (this.tableContext == null) {
+ this.tableContext = new CdTableFetchDataContext(() => undefined);
+ }
+ return this.rbdService.list(this.tableContext?.toParams());
+ }
+
+ prepareResponse(resp: any[]): any[] {
+ let images: any[] = [];
+
+ resp.forEach((pool) => {
+ images = images.concat(pool.value);
+ });
+
+ images.forEach((image) => {
+ if (image.schedule_info !== undefined) {
+ let scheduling: any[] = [];
+ const scheduleStatus = 'scheduled';
+ let nextSnapshotDate = +new Date(image.schedule_info.schedule_time);
+ const offset = new Date().getTimezoneOffset();
+ nextSnapshotDate = nextSnapshotDate + Math.abs(offset) * 60000;
+ scheduling.push(image.mirror_mode, scheduleStatus, nextSnapshotDate);
+ image.mirror_mode = scheduling;
+ scheduling = [];
+ }
+ });
+
+ if (images.length > 0) {
+ this.count = CdTableServerSideService.getCount(resp[0]);
+ } else {
+ this.count = 0;
+ }
+ return images;
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ deleteRbdModal() {
+ const poolName = this.selection.first().pool_name;
+ const namespace = this.selection.first().namespace;
+ const imageName = this.selection.first().name;
+ const imageSpec = new ImageSpec(poolName, namespace, imageName);
+
+ this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: 'RBD',
+ itemNames: [imageSpec],
+ bodyTemplate: this.deleteTpl,
+ bodyContext: {
+ hasSnapshots: this.hasSnapshots(),
+ snapshots: this.listProtectedSnapshots()
+ },
+ submitActionObservable: () =>
+ this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('rbd/delete', {
+ image_spec: imageSpec.toString()
+ }),
+ call: this.rbdService.delete(imageSpec)
+ })
+ });
+ }
+
+ resyncRbdModal() {
+ const poolName = this.selection.first().pool_name;
+ const namespace = this.selection.first().namespace;
+ const imageName = this.selection.first().name;
+ const imageSpec = new ImageSpec(poolName, namespace, imageName);
+
+ this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: 'RBD',
+ itemNames: [imageSpec],
+ actionDescription: 'resync',
+ submitActionObservable: () =>
+ this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('rbd/edit', {
+ image_spec: imageSpec.toString()
+ }),
+ call: this.rbdService.update(imageSpec, { resync: true })
+ })
+ });
+ }
+
+ trashRbdModal() {
+ const initialState = {
+ poolName: this.selection.first().pool_name,
+ namespace: this.selection.first().namespace,
+ imageName: this.selection.first().name,
+ hasSnapshots: this.hasSnapshots()
+ };
+ this.modalRef = this.modalService.show(RbdTrashMoveModalComponent, initialState);
+ }
+
+ flattenRbd(imageSpec: ImageSpec) {
+ this.taskWrapper
+ .wrapTaskAroundCall({
+ task: new FinishedTask('rbd/flatten', {
+ image_spec: imageSpec.toString()
+ }),
+ call: this.rbdService.flatten(imageSpec)
+ })
+ .subscribe({
+ complete: () => {
+ this.modalRef.close();
+ }
+ });
+ }
+
+ flattenRbdModal() {
+ const poolName = this.selection.first().pool_name;
+ const namespace = this.selection.first().namespace;
+ const imageName = this.selection.first().name;
+ const parent: RbdParentModel = this.selection.first().parent;
+ const parentImageSpec = new ImageSpec(
+ parent.pool_name,
+ parent.pool_namespace,
+ parent.image_name
+ );
+ const childImageSpec = new ImageSpec(poolName, namespace, imageName);
+
+ const initialState = {
+ titleText: 'RBD flatten',
+ buttonText: 'Flatten',
+ bodyTpl: this.flattenTpl,
+ bodyData: {
+ parent: `${parentImageSpec}@${parent.snap_name}`,
+ child: childImageSpec.toString()
+ },
+ onSubmit: () => {
+ this.flattenRbd(childImageSpec);
+ }
+ };
+
+ this.modalRef = this.modalService.show(ConfirmationModalComponent, initialState);
+ }
+
+ editRequest() {
+ const request = new RbdFormEditRequestModel();
+ request.remove_scheduling = !request.remove_scheduling;
+ return request;
+ }
+
+ removeSchedulingModal() {
+ const imageName = this.selection.first().name;
+
+ const imageSpec = new ImageSpec(
+ this.selection.first().pool_name,
+ this.selection.first().namespace,
+ this.selection.first().name
+ );
+
+ this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ actionDescription: 'remove scheduling on',
+ itemDescription: $localize`image`,
+ itemNames: [`${imageName}`],
+ submitActionObservable: () =>
+ new Observable((observer: Subscriber<any>) => {
+ this.taskWrapper
+ .wrapTaskAroundCall({
+ task: new FinishedTask('rbd/edit', {
+ image_spec: imageSpec.toString()
+ }),
+ call: this.rbdService.update(imageSpec, this.editRequest())
+ })
+ .subscribe({
+ error: (resp) => observer.error(resp),
+ complete: () => {
+ this.modalRef.close();
+ }
+ });
+ })
+ });
+ }
+
+ actionPrimary(primary: boolean) {
+ const request = new RbdFormEditRequestModel();
+ request.primary = primary;
+ request.features = null;
+ const imageSpec = new ImageSpec(
+ this.selection.first().pool_name,
+ this.selection.first().namespace,
+ this.selection.first().name
+ );
+ this.taskWrapper
+ .wrapTaskAroundCall({
+ task: new FinishedTask('rbd/edit', {
+ image_spec: imageSpec.toString()
+ }),
+ call: this.rbdService.update(imageSpec, request)
+ })
+ .subscribe();
+ }
+
+ hasSnapshots() {
+ const snapshots = this.selection.first()['snapshots'] || [];
+ return snapshots.length > 0;
+ }
+
+ hasClonedSnapshots(image: object) {
+ const snapshots = image['snapshots'] || [];
+ return snapshots.some((snap: object) => snap['children'] && snap['children'].length > 0);
+ }
+
+ listProtectedSnapshots() {
+ const first = this.selection.first();
+ const snapshots = first['snapshots'];
+ return snapshots.reduce((accumulator: string[], snap: object) => {
+ if (snap['is_protected']) {
+ accumulator.push(snap['name']);
+ }
+ return accumulator;
+ }, []);
+ }
+
+ getDeleteDisableDesc(selection: CdTableSelection): string | boolean {
+ const first = selection.first();
+
+ if (first && this.hasClonedSnapshots(first)) {
+ return $localize`This RBD has cloned snapshots. Please delete related RBDs before deleting this RBD.`;
+ }
+
+ return this.getInvalidNameDisable(selection) || this.hasClonedSnapshots(selection.first());
+ }
+
+ getResyncDisableDesc(selection: CdTableSelection): string | boolean {
+ const first = selection.first();
+
+ if (first && this.imageIsPrimary(first)) {
+ return $localize`Primary RBD images cannot be resynced`;
+ }
+
+ return this.getInvalidNameDisable(selection);
+ }
+
+ imageIsPrimary(image: object) {
+ return image['primary'];
+ }
+ getInvalidNameDisable(selection: CdTableSelection): string | boolean {
+ const first = selection.first();
+
+ if (first?.name?.match(/[@/]/)) {
+ return $localize`This RBD image has an invalid name and can't be managed by ceph.`;
+ }
+
+ return !selection.first() || !selection.hasSingleSelection;
+ }
+
+ getRemovingStatusDesc(selection: CdTableSelection): string | boolean {
+ const first = selection.first();
+ if (first?.source === 'REMOVING') {
+ return $localize`Action not possible for an RBD in status 'Removing'`;
+ }
+ return false;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-model.ts
new file mode 100644
index 000000000..0a265dea8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-model.ts
@@ -0,0 +1,15 @@
+export class RbdModel {
+ id: string;
+ unique_id: string;
+ name: string;
+ pool_name: string;
+ namespace: string;
+ image_format: RBDImageFormat;
+
+ cdExecuting: string;
+}
+
+export enum RBDImageFormat {
+ V1 = 1,
+ V2 = 2
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html
new file mode 100644
index 000000000..9d76cba09
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html
@@ -0,0 +1,79 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container class="modal-title"
+ i18n>Create Namespace</ng-container>
+
+ <ng-container class="modal-content">
+ <form name="namespaceForm"
+ #formDir="ngForm"
+ [formGroup]="namespaceForm"
+ novalidate>
+ <div class="modal-body">
+
+ <!-- Pool -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="pool"
+ i18n>Pool</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ placeholder="Pool name..."
+ id="pool"
+ name="pool"
+ formControlName="pool"
+ *ngIf="!poolPermission.read">
+ <select id="pool"
+ name="pool"
+ class="form-control"
+ formControlName="pool"
+ *ngIf="poolPermission.read">
+ <option *ngIf="pools === null"
+ [ngValue]="null"
+ i18n>Loading...</option>
+ <option *ngIf="pools !== null && pools.length === 0"
+ [ngValue]="null"
+ i18n>-- No rbd pools available --</option>
+ <option *ngIf="pools !== null && pools.length > 0"
+ [ngValue]="null"
+ i18n>-- Select a pool --</option>
+ <option *ngFor="let pool of pools"
+ [value]="pool.pool_name">{{ pool.pool_name }}</option>
+ </select>
+ <span *ngIf="namespaceForm.showError('pool', formDir, 'required')"
+ class="invalid-feedback"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Name -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="namespace"
+ i18n>Name</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ placeholder="Namespace name..."
+ id="namespace"
+ name="namespace"
+ formControlName="namespace"
+ autofocus>
+ <span class="invalid-feedback"
+ *ngIf="namespaceForm.showError('namespace', formDir, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="namespaceForm.showError('namespace', formDir, 'namespaceExists')"
+ i18n>Namespace already exists.</span>
+ </div>
+ </div>
+
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="submit()"
+ [form]="namespaceForm"
+ [submitText]="actionLabels.CREATE"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.spec.ts
new file mode 100644
index 000000000..8300fc655
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.spec.ts
@@ -0,0 +1,39 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+
+import { ComponentsModule } from '~/app/shared/components/components.module';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RbdNamespaceFormModalComponent } from './rbd-namespace-form-modal.component';
+
+describe('RbdNamespaceFormModalComponent', () => {
+ let component: RbdNamespaceFormModalComponent;
+ let fixture: ComponentFixture<RbdNamespaceFormModalComponent>;
+
+ configureTestBed({
+ imports: [
+ ReactiveFormsModule,
+ ComponentsModule,
+ HttpClientTestingModule,
+ ToastrModule.forRoot(),
+ RouterTestingModule
+ ],
+ declarations: [RbdNamespaceFormModalComponent],
+ providers: [NgbActiveModal, AuthStorageService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RbdNamespaceFormModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts
new file mode 100644
index 000000000..bad32c3c5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts
@@ -0,0 +1,144 @@
+import { Component, OnInit } from '@angular/core';
+import {
+ AbstractControl,
+ AsyncValidatorFn,
+ FormControl,
+ ValidationErrors,
+ ValidatorFn
+} from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { Subject } from 'rxjs';
+
+import { Pool } from '~/app/ceph/pool/pool';
+import { PoolService } from '~/app/shared/api/pool.service';
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+
+@Component({
+ selector: 'cd-rbd-namespace-form-modal',
+ templateUrl: './rbd-namespace-form-modal.component.html',
+ styleUrls: ['./rbd-namespace-form-modal.component.scss']
+})
+export class RbdNamespaceFormModalComponent implements OnInit {
+ poolPermission: Permission;
+ pools: Array<Pool> = null;
+ pool: string;
+ namespace: string;
+
+ namespaceForm: CdFormGroup;
+
+ editing = false;
+
+ public onSubmit: Subject<void>;
+
+ constructor(
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n,
+ private authStorageService: AuthStorageService,
+ private notificationService: NotificationService,
+ private poolService: PoolService,
+ private rbdService: RbdService
+ ) {
+ this.poolPermission = this.authStorageService.getPermissions().pool;
+ this.createForm();
+ }
+
+ createForm() {
+ this.namespaceForm = new CdFormGroup(
+ {
+ pool: new FormControl(''),
+ namespace: new FormControl('')
+ },
+ this.validator(),
+ this.asyncValidator()
+ );
+ }
+
+ validator(): ValidatorFn {
+ return (control: AbstractControl) => {
+ const poolCtrl = control.get('pool');
+ const namespaceCtrl = control.get('namespace');
+ let poolErrors = null;
+ if (!poolCtrl.value) {
+ poolErrors = { required: true };
+ }
+ poolCtrl.setErrors(poolErrors);
+ let namespaceErrors = null;
+ if (!namespaceCtrl.value) {
+ namespaceErrors = { required: true };
+ }
+ namespaceCtrl.setErrors(namespaceErrors);
+ return null;
+ };
+ }
+
+ asyncValidator(): AsyncValidatorFn {
+ return (control: AbstractControl): Promise<ValidationErrors | null> => {
+ return new Promise((resolve) => {
+ const poolCtrl = control.get('pool');
+ const namespaceCtrl = control.get('namespace');
+ this.rbdService.listNamespaces(poolCtrl.value).subscribe((namespaces: any[]) => {
+ if (namespaces.some((ns) => ns.namespace === namespaceCtrl.value)) {
+ const error = { namespaceExists: true };
+ namespaceCtrl.setErrors(error);
+ resolve(error);
+ } else {
+ resolve(null);
+ }
+ });
+ });
+ };
+ }
+
+ ngOnInit() {
+ this.onSubmit = new Subject();
+
+ if (this.poolPermission.read) {
+ this.poolService.list(['pool_name', 'type', 'application_metadata']).then((resp) => {
+ const pools: Pool[] = [];
+ for (const pool of resp) {
+ if (this.rbdService.isRBDPool(pool) && pool.type === 'replicated') {
+ pools.push(pool);
+ }
+ }
+ this.pools = pools;
+ if (this.pools.length === 1) {
+ const poolName = this.pools[0]['pool_name'];
+ this.namespaceForm.get('pool').setValue(poolName);
+ }
+ });
+ }
+ }
+
+ submit() {
+ const pool = this.namespaceForm.getValue('pool');
+ const namespace = this.namespaceForm.getValue('namespace');
+ const finishedTask = new FinishedTask();
+ finishedTask.name = 'rbd/namespace/create';
+ finishedTask.metadata = {
+ pool: pool,
+ namespace: namespace
+ };
+ this.rbdService
+ .createNamespace(pool, namespace)
+ .toPromise()
+ .then(() => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Created namespace '${pool}/${namespace}'`
+ );
+ this.activeModal.close();
+ this.onSubmit.next();
+ })
+ .catch(() => {
+ this.namespaceForm.setErrors({ cdSubmitButton: true });
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.html
new file mode 100644
index 000000000..46e27179e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.html
@@ -0,0 +1,18 @@
+<cd-rbd-tabs></cd-rbd-tabs>
+
+<cd-table [data]="namespaces"
+ (fetchData)="refresh()"
+ columnMode="flex"
+ [columns]="columns"
+ identifier="id"
+ forceIdentifier="true"
+ selectionType="single"
+ (updateSelection)="updateSelection($event)">
+ <div class="table-actions btn-toolbar">
+ <cd-table-actions class="btn-group"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ </div>
+</cd-table>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.spec.ts
new file mode 100644
index 000000000..85f8d3f81
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.spec.ts
@@ -0,0 +1,41 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+
+import { TaskListService } from '~/app/shared/services/task-list.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RbdTabsComponent } from '../rbd-tabs/rbd-tabs.component';
+import { RbdNamespaceListComponent } from './rbd-namespace-list.component';
+
+describe('RbdNamespaceListComponent', () => {
+ let component: RbdNamespaceListComponent;
+ let fixture: ComponentFixture<RbdNamespaceListComponent>;
+
+ configureTestBed({
+ declarations: [RbdNamespaceListComponent, RbdTabsComponent],
+ imports: [
+ BrowserAnimationsModule,
+ SharedModule,
+ HttpClientTestingModule,
+ RouterTestingModule,
+ ToastrModule.forRoot(),
+ NgbNavModule
+ ],
+ providers: [TaskListService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RbdNamespaceListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts
new file mode 100644
index 000000000..4617e13e4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts
@@ -0,0 +1,157 @@
+import { Component, OnInit } from '@angular/core';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { forkJoin, Observable } from 'rxjs';
+
+import { PoolService } from '~/app/shared/api/pool.service';
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { TaskListService } from '~/app/shared/services/task-list.service';
+import { RbdNamespaceFormModalComponent } from '../rbd-namespace-form/rbd-namespace-form-modal.component';
+
+@Component({
+ selector: 'cd-rbd-namespace-list',
+ templateUrl: './rbd-namespace-list.component.html',
+ styleUrls: ['./rbd-namespace-list.component.scss'],
+ providers: [TaskListService]
+})
+export class RbdNamespaceListComponent implements OnInit {
+ columns: CdTableColumn[];
+ namespaces: any;
+ modalRef: NgbModalRef;
+ permission: Permission;
+ selection = new CdTableSelection();
+ tableActions: CdTableAction[];
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private rbdService: RbdService,
+ private poolService: PoolService,
+ private modalService: ModalService,
+ private notificationService: NotificationService,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ this.permission = this.authStorageService.getPermissions().rbdImage;
+ const createAction: CdTableAction = {
+ permission: 'create',
+ icon: Icons.add,
+ click: () => this.createModal(),
+ name: this.actionLabels.CREATE
+ };
+ const deleteAction: CdTableAction = {
+ permission: 'delete',
+ icon: Icons.destroy,
+ click: () => this.deleteModal(),
+ name: this.actionLabels.DELETE,
+ disable: () => this.getDeleteDisableDesc()
+ };
+ this.tableActions = [createAction, deleteAction];
+ }
+
+ ngOnInit() {
+ this.columns = [
+ {
+ name: $localize`Namespace`,
+ prop: 'namespace',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Pool`,
+ prop: 'pool',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Total images`,
+ prop: 'num_images',
+ flexGrow: 1
+ }
+ ];
+ this.refresh();
+ }
+
+ refresh() {
+ this.poolService.list(['pool_name', 'type', 'application_metadata']).then((pools: any) => {
+ pools = pools.filter(
+ (pool: any) => this.rbdService.isRBDPool(pool) && pool.type === 'replicated'
+ );
+ const promisses: Observable<any>[] = [];
+ pools.forEach((pool: any) => {
+ promisses.push(this.rbdService.listNamespaces(pool['pool_name']));
+ });
+ if (promisses.length > 0) {
+ forkJoin(promisses).subscribe((data: Array<Array<string>>) => {
+ const result: any[] = [];
+ for (let i = 0; i < data.length; i++) {
+ const namespaces = data[i];
+ const pool_name = pools[i]['pool_name'];
+ namespaces.forEach((namespace: any) => {
+ result.push({
+ id: `${pool_name}/${namespace.namespace}`,
+ pool: pool_name,
+ namespace: namespace.namespace,
+ num_images: namespace.num_images
+ });
+ });
+ }
+ this.namespaces = result;
+ });
+ } else {
+ this.namespaces = [];
+ }
+ });
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ createModal() {
+ this.modalRef = this.modalService.show(RbdNamespaceFormModalComponent);
+ this.modalRef.componentInstance.onSubmit.subscribe(() => {
+ this.refresh();
+ });
+ }
+
+ deleteModal() {
+ const pool = this.selection.first().pool;
+ const namespace = this.selection.first().namespace;
+ this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: 'Namespace',
+ itemNames: [`${pool}/${namespace}`],
+ submitAction: () =>
+ this.rbdService.deleteNamespace(pool, namespace).subscribe(
+ () => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Deleted namespace '${pool}/${namespace}'`
+ );
+ this.modalRef.close();
+ this.refresh();
+ },
+ () => {
+ this.modalRef.componentInstance.stopLoadingSpinner();
+ }
+ )
+ });
+ }
+
+ getDeleteDisableDesc(): string | boolean {
+ const first = this.selection.first();
+
+ if (first?.num_images > 0) {
+ return $localize`Namespace contains images`;
+ }
+
+ return !this.selection?.first();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.html
new file mode 100644
index 000000000..002c8e57c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.html
@@ -0,0 +1,6 @@
+<cd-rbd-tabs></cd-rbd-tabs>
+
+<cd-grafana [grafanaPath]="'rbd-overview?'"
+ uid="41FrpeUiz"
+ grafanaStyle="two">
+</cd-grafana>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.spec.ts
new file mode 100644
index 000000000..d778d2552
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.spec.ts
@@ -0,0 +1,30 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RbdTabsComponent } from '../rbd-tabs/rbd-tabs.component';
+import { RbdPerformanceComponent } from './rbd-performance.component';
+
+describe('RbdPerformanceComponent', () => {
+ let component: RbdPerformanceComponent;
+ let fixture: ComponentFixture<RbdPerformanceComponent>;
+
+ configureTestBed({
+ imports: [HttpClientTestingModule, RouterTestingModule, SharedModule, NgbNavModule],
+ declarations: [RbdPerformanceComponent, RbdTabsComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RbdPerformanceComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.ts
new file mode 100644
index 000000000..76750a8ce
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.ts
@@ -0,0 +1,8 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'cd-rbd-performance',
+ templateUrl: './rbd-performance.component.html',
+ styleUrls: ['./rbd-performance.component.scss']
+})
+export class RbdPerformanceComponent {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html
new file mode 100644
index 000000000..598e3fd38
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html
@@ -0,0 +1,41 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container i18n="form title"
+ class="modal-title">{{ action | titlecase }} {{ resource | upperFirst }}</ng-container>
+
+ <ng-container class="modal-content">
+ <form name="snapshotForm"
+ #formDir="ngForm"
+ [formGroup]="snapshotForm"
+ novalidate>
+ <div class="modal-body">
+ <!-- Name -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="snapshotName"
+ i18n>Name</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ placeholder="Snapshot name..."
+ id="snapshotName"
+ name="snapshotName"
+ [attr.disabled]="(mirroring === 'snapshot') ? true : null"
+ formControlName="snapshotName"
+ autofocus>
+ <span class="invalid-feedback"
+ *ngIf="snapshotForm.showError('snapshotName', formDir, 'required')"
+ i18n>This field is required.</span><br><br>
+ <span *ngIf="mirroring === 'snapshot'"
+ i18n>Snapshot mode is enabled on image <b>{{ imageName }}</b>: snapshot names are auto generated</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="submit()"
+ [form]="snapshotForm"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.spec.ts
new file mode 100644
index 000000000..b6681ec51
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.spec.ts
@@ -0,0 +1,62 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+
+import { ComponentsModule } from '~/app/shared/components/components.module';
+import { PipesModule } from '~/app/shared/pipes/pipes.module';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RbdSnapshotFormModalComponent } from './rbd-snapshot-form-modal.component';
+
+describe('RbdSnapshotFormModalComponent', () => {
+ let component: RbdSnapshotFormModalComponent;
+ let fixture: ComponentFixture<RbdSnapshotFormModalComponent>;
+
+ configureTestBed({
+ imports: [
+ ReactiveFormsModule,
+ ComponentsModule,
+ PipesModule,
+ HttpClientTestingModule,
+ ToastrModule.forRoot(),
+ RouterTestingModule
+ ],
+ declarations: [RbdSnapshotFormModalComponent],
+ providers: [NgbActiveModal, AuthStorageService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RbdSnapshotFormModalComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should show "Create" text', () => {
+ fixture.detectChanges();
+
+ const header = fixture.debugElement.nativeElement.querySelector('h4');
+ expect(header.textContent).toBe('Create RBD Snapshot');
+
+ const button = fixture.debugElement.nativeElement.querySelector('cd-submit-button');
+ expect(button.textContent).toBe('Create RBD Snapshot');
+ });
+
+ it('should show "Rename" text', () => {
+ component.setEditing();
+
+ fixture.detectChanges();
+
+ const header = fixture.debugElement.nativeElement.querySelector('h4');
+ expect(header.textContent).toBe('Rename RBD Snapshot');
+
+ const button = fixture.debugElement.nativeElement.querySelector('cd-submit-button');
+ expect(button.textContent).toBe('Rename RBD Snapshot');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts
new file mode 100644
index 000000000..d5861163f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts
@@ -0,0 +1,137 @@
+import { Component } from '@angular/core';
+import { FormControl, Validators } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { Subject } from 'rxjs';
+
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { ImageSpec } from '~/app/shared/models/image-spec';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { TaskManagerService } from '~/app/shared/services/task-manager.service';
+
+@Component({
+ selector: 'cd-rbd-snapshot-form-modal',
+ templateUrl: './rbd-snapshot-form-modal.component.html',
+ styleUrls: ['./rbd-snapshot-form-modal.component.scss']
+})
+export class RbdSnapshotFormModalComponent {
+ poolName: string;
+ namespace: string;
+ imageName: string;
+ snapName: string;
+ mirroring: string;
+
+ snapshotForm: CdFormGroup;
+
+ editing = false;
+ action: string;
+ resource: string;
+
+ public onSubmit: Subject<string> = new Subject();
+
+ constructor(
+ public activeModal: NgbActiveModal,
+ private rbdService: RbdService,
+ private taskManagerService: TaskManagerService,
+ private notificationService: NotificationService,
+ private actionLabels: ActionLabelsI18n
+ ) {
+ this.action = this.actionLabels.CREATE;
+ this.resource = $localize`RBD Snapshot`;
+ this.createForm();
+ }
+
+ createForm() {
+ this.snapshotForm = new CdFormGroup({
+ snapshotName: new FormControl('', {
+ validators: [Validators.required]
+ })
+ });
+ }
+
+ setSnapName(snapName: string) {
+ this.snapName = snapName;
+ if (this.mirroring !== 'snapshot') {
+ this.snapshotForm.get('snapshotName').setValue(snapName);
+ } else {
+ this.snapshotForm.get('snapshotName').clearValidators();
+ }
+ }
+
+ /**
+ * Set the 'editing' flag. If set to TRUE, the modal dialog is in
+ * 'Edit' mode, otherwise in 'Create' mode.
+ * @param {boolean} editing
+ */
+ setEditing(editing: boolean = true) {
+ this.editing = editing;
+ this.action = this.editing ? this.actionLabels.RENAME : this.actionLabels.CREATE;
+ }
+
+ editAction() {
+ const snapshotName = this.snapshotForm.getValue('snapshotName');
+ const imageSpec = new ImageSpec(this.poolName, this.namespace, this.imageName);
+ const finishedTask = new FinishedTask();
+ finishedTask.name = 'rbd/snap/edit';
+ finishedTask.metadata = {
+ image_spec: imageSpec.toString(),
+ snapshot_name: snapshotName
+ };
+ this.rbdService
+ .renameSnapshot(imageSpec, this.snapName, snapshotName)
+ .toPromise()
+ .then(() => {
+ this.taskManagerService.subscribe(
+ finishedTask.name,
+ finishedTask.metadata,
+ (asyncFinishedTask: FinishedTask) => {
+ this.notificationService.notifyTask(asyncFinishedTask);
+ }
+ );
+ this.activeModal.close();
+ this.onSubmit.next(this.snapName);
+ })
+ .catch(() => {
+ this.snapshotForm.setErrors({ cdSubmitButton: true });
+ });
+ }
+
+ createAction() {
+ const snapshotName = this.snapshotForm.getValue('snapshotName');
+ const imageSpec = new ImageSpec(this.poolName, this.namespace, this.imageName);
+ const finishedTask = new FinishedTask();
+ finishedTask.name = 'rbd/snap/create';
+ finishedTask.metadata = {
+ image_spec: imageSpec.toString(),
+ snapshot_name: snapshotName
+ };
+ this.rbdService
+ .createSnapshot(imageSpec, snapshotName)
+ .toPromise()
+ .then(() => {
+ this.taskManagerService.subscribe(
+ finishedTask.name,
+ finishedTask.metadata,
+ (asyncFinishedTask: FinishedTask) => {
+ this.notificationService.notifyTask(asyncFinishedTask);
+ }
+ );
+ this.activeModal.close();
+ this.onSubmit.next(snapshotName);
+ })
+ .catch(() => {
+ this.snapshotForm.setErrors({ cdSubmitButton: true });
+ });
+ }
+
+ submit() {
+ if (this.editing) {
+ this.editAction();
+ } else {
+ this.createAction();
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts
new file mode 100644
index 000000000..cc0d61f91
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts
@@ -0,0 +1,131 @@
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+
+export class RbdSnapshotActionsModel {
+ create: CdTableAction;
+ rename: CdTableAction;
+ protect: CdTableAction;
+ unprotect: CdTableAction;
+ clone: CdTableAction;
+ copy: CdTableAction;
+ rollback: CdTableAction;
+ deleteSnap: CdTableAction;
+ ordering: CdTableAction[];
+
+ cloneFormatVersion = 1;
+
+ constructor(
+ actionLabels: ActionLabelsI18n,
+ public featuresName: string[],
+ rbdService: RbdService
+ ) {
+ rbdService.cloneFormatVersion().subscribe((version: number) => {
+ this.cloneFormatVersion = version;
+ });
+
+ this.create = {
+ permission: 'create',
+ icon: Icons.add,
+ name: actionLabels.CREATE
+ };
+ this.rename = {
+ permission: 'update',
+ icon: Icons.edit,
+ name: actionLabels.RENAME,
+ disable: (selection: CdTableSelection) => this.disableForMirrorSnapshot(selection)
+ };
+ this.protect = {
+ permission: 'update',
+ icon: Icons.lock,
+ visible: (selection: CdTableSelection) =>
+ selection.hasSingleSelection && !selection.first().is_protected,
+ name: actionLabels.PROTECT,
+ disable: (selection: CdTableSelection) => this.disableForMirrorSnapshot(selection)
+ };
+ this.unprotect = {
+ permission: 'update',
+ icon: Icons.unlock,
+ visible: (selection: CdTableSelection) =>
+ selection.hasSingleSelection && selection.first().is_protected,
+ name: actionLabels.UNPROTECT,
+ disable: (selection: CdTableSelection) => this.disableForMirrorSnapshot(selection)
+ };
+ this.clone = {
+ permission: 'create',
+ canBePrimary: (selection: CdTableSelection) => selection.hasSingleSelection,
+ disable: (selection: CdTableSelection) =>
+ this.getCloneDisableDesc(selection, this.featuresName) ||
+ this.disableForMirrorSnapshot(selection),
+ icon: Icons.clone,
+ name: actionLabels.CLONE
+ };
+ this.copy = {
+ permission: 'create',
+ canBePrimary: (selection: CdTableSelection) => selection.hasSingleSelection,
+ disable: (selection: CdTableSelection) =>
+ !selection.hasSingleSelection ||
+ selection.first().cdExecuting ||
+ this.disableForMirrorSnapshot(selection),
+ icon: Icons.copy,
+ name: actionLabels.COPY
+ };
+ this.rollback = {
+ permission: 'update',
+ icon: Icons.undo,
+ name: actionLabels.ROLLBACK,
+ disable: (selection: CdTableSelection) => this.disableForMirrorSnapshot(selection)
+ };
+ this.deleteSnap = {
+ permission: 'delete',
+ icon: Icons.destroy,
+ disable: (selection: CdTableSelection) => {
+ const first = selection.first();
+ return (
+ !selection.hasSingleSelection ||
+ first.cdExecuting ||
+ first.is_protected ||
+ this.disableForMirrorSnapshot(selection)
+ );
+ },
+ name: actionLabels.DELETE
+ };
+
+ this.ordering = [
+ this.create,
+ this.rename,
+ this.protect,
+ this.unprotect,
+ this.clone,
+ this.copy,
+ this.rollback,
+ this.deleteSnap
+ ];
+ }
+
+ getCloneDisableDesc(selection: CdTableSelection, featuresName: string[]): boolean | string {
+ if (selection.hasSingleSelection && !selection.first().cdExecuting) {
+ if (!featuresName?.includes('layering')) {
+ return $localize`Parent image must support Layering`;
+ }
+
+ if (this.cloneFormatVersion === 1 && !selection.first().is_protected) {
+ return $localize`Snapshot must be protected in order to clone.`;
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ disableForMirrorSnapshot(selection: CdTableSelection) {
+ return (
+ selection.hasSingleSelection &&
+ selection.first().mirror_mode === 'snapshot' &&
+ selection.first().name.includes('.mirror.')
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html
new file mode 100644
index 000000000..90fbf5384
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html
@@ -0,0 +1,17 @@
+<cd-table [data]="data"
+ columnMode="flex"
+ selectionType="single"
+ (updateSelection)="updateSelection($event)"
+ [columns]="columns">
+ <cd-table-actions class="table-actions"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+</cd-table>
+
+<ng-template #rollbackTpl
+ let-value>
+ <ng-container i18n>You are about to rollback</ng-container>
+ <strong> {{ value.snapName }}</strong>.
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.spec.ts
new file mode 100644
index 000000000..ca72007ee
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.spec.ts
@@ -0,0 +1,305 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbModalModule, NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { MockComponent } from 'ng-mocks';
+import { ToastrModule } from 'ngx-toastr';
+import { Subject, throwError as observableThrowError } from 'rxjs';
+
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { ComponentsModule } from '~/app/shared/components/components.module';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { DataTableModule } from '~/app/shared/datatable/datatable.module';
+import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { ExecutingTask } from '~/app/shared/models/executing-task';
+import { Permissions } from '~/app/shared/models/permissions';
+import { PipesModule } from '~/app/shared/pipes/pipes.module';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { TaskListService } from '~/app/shared/services/task-list.service';
+import { configureTestBed, expectItemTasks, PermissionHelper } from '~/testing/unit-test-helper';
+import { RbdSnapshotFormModalComponent } from '../rbd-snapshot-form/rbd-snapshot-form-modal.component';
+import { RbdTabsComponent } from '../rbd-tabs/rbd-tabs.component';
+import { RbdSnapshotActionsModel } from './rbd-snapshot-actions.model';
+import { RbdSnapshotListComponent } from './rbd-snapshot-list.component';
+import { RbdSnapshotModel } from './rbd-snapshot.model';
+
+describe('RbdSnapshotListComponent', () => {
+ let component: RbdSnapshotListComponent;
+ let fixture: ComponentFixture<RbdSnapshotListComponent>;
+ let summaryService: SummaryService;
+
+ const fakeAuthStorageService = {
+ isLoggedIn: () => {
+ return true;
+ },
+ getPermissions: () => {
+ return new Permissions({ 'rbd-image': ['read', 'update', 'create', 'delete'] });
+ }
+ };
+
+ configureTestBed(
+ {
+ declarations: [
+ RbdSnapshotListComponent,
+ RbdTabsComponent,
+ MockComponent(RbdSnapshotFormModalComponent)
+ ],
+ imports: [
+ BrowserAnimationsModule,
+ ComponentsModule,
+ DataTableModule,
+ HttpClientTestingModule,
+ PipesModule,
+ RouterTestingModule,
+ NgbNavModule,
+ ToastrModule.forRoot(),
+ NgbModalModule
+ ],
+ providers: [
+ { provide: AuthStorageService, useValue: fakeAuthStorageService },
+ TaskListService
+ ]
+ },
+ [CriticalConfirmationModalComponent]
+ );
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RbdSnapshotListComponent);
+ component = fixture.componentInstance;
+ component.ngOnChanges();
+ summaryService = TestBed.inject(SummaryService);
+ });
+
+ it('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+
+ describe('api delete request', () => {
+ let called: boolean;
+ let rbdService: RbdService;
+ let notificationService: NotificationService;
+ let authStorageService: AuthStorageService;
+
+ beforeEach(() => {
+ fixture.detectChanges();
+ const modalService = TestBed.inject(ModalService);
+ const actionLabelsI18n = TestBed.inject(ActionLabelsI18n);
+ called = false;
+ rbdService = new RbdService(null, null);
+ notificationService = new NotificationService(null, null, null);
+ authStorageService = new AuthStorageService();
+ authStorageService.set('user', { 'rbd-image': ['create', 'read', 'update', 'delete'] });
+ component = new RbdSnapshotListComponent(
+ authStorageService,
+ modalService,
+ null,
+ null,
+ rbdService,
+ null,
+ notificationService,
+ null,
+ null,
+ actionLabelsI18n,
+ null
+ );
+ spyOn(rbdService, 'deleteSnapshot').and.returnValue(observableThrowError({ status: 500 }));
+ spyOn(notificationService, 'notifyTask').and.stub();
+ });
+
+ it('should call stopLoadingSpinner if the request fails', fakeAsync(() => {
+ component.updateSelection(new CdTableSelection([{ name: 'someName' }]));
+ expect(called).toBe(false);
+ component.deleteSnapshotModal();
+ spyOn(component.modalRef.componentInstance, 'stopLoadingSpinner').and.callFake(() => {
+ called = true;
+ });
+ component.modalRef.componentInstance.submitAction();
+ tick(500);
+ expect(called).toBe(true);
+ }));
+ });
+
+ describe('handling of executing tasks', () => {
+ let snapshots: RbdSnapshotModel[];
+
+ const addSnapshot = (name: string) => {
+ const model = new RbdSnapshotModel();
+ model.id = 1;
+ model.name = name;
+ snapshots.push(model);
+ };
+
+ const addTask = (task_name: string, snapshot_name: string) => {
+ const task = new ExecutingTask();
+ task.name = task_name;
+ task.metadata = {
+ image_spec: 'rbd/foo',
+ snapshot_name: snapshot_name
+ };
+ summaryService.addRunningTask(task);
+ };
+
+ const refresh = (data: any) => {
+ summaryService['summaryDataSource'].next(data);
+ };
+
+ beforeEach(() => {
+ fixture.detectChanges();
+ snapshots = [];
+ addSnapshot('a');
+ addSnapshot('b');
+ addSnapshot('c');
+ component.snapshots = snapshots;
+ component.poolName = 'rbd';
+ component.rbdName = 'foo';
+ refresh({ executing_tasks: [], finished_tasks: [] });
+ component.ngOnChanges();
+ fixture.detectChanges();
+ });
+
+ it('should gets all snapshots without tasks', () => {
+ expect(component.snapshots.length).toBe(3);
+ expect(component.snapshots.every((image) => !image.cdExecuting)).toBeTruthy();
+ });
+
+ it('should add a new image from a task', () => {
+ addTask('rbd/snap/create', 'd');
+ expect(component.snapshots.length).toBe(4);
+ expectItemTasks(component.snapshots[0], undefined);
+ expectItemTasks(component.snapshots[1], undefined);
+ expectItemTasks(component.snapshots[2], undefined);
+ expectItemTasks(component.snapshots[3], 'Creating');
+ });
+
+ it('should show when an existing image is being modified', () => {
+ addTask('rbd/snap/edit', 'a');
+ addTask('rbd/snap/delete', 'b');
+ addTask('rbd/snap/rollback', 'c');
+ expect(component.snapshots.length).toBe(3);
+ expectItemTasks(component.snapshots[0], 'Updating');
+ expectItemTasks(component.snapshots[1], 'Deleting');
+ expectItemTasks(component.snapshots[2], 'Rolling back');
+ });
+ });
+
+ describe('snapshot modal dialog', () => {
+ beforeEach(() => {
+ component.poolName = 'pool01';
+ component.rbdName = 'image01';
+ spyOn(TestBed.inject(ModalService), 'show').and.callFake(() => {
+ const ref: any = {};
+ ref.componentInstance = new RbdSnapshotFormModalComponent(
+ null,
+ null,
+ null,
+ null,
+ TestBed.inject(ActionLabelsI18n)
+ );
+ ref.componentInstance.onSubmit = new Subject();
+ return ref;
+ });
+ });
+
+ it('should display old snapshot name', () => {
+ component.selection.selected = [{ name: 'oldname' }];
+ component.openEditSnapshotModal();
+ expect(component.modalRef.componentInstance.snapName).toBe('oldname');
+ expect(component.modalRef.componentInstance.editing).toBeTruthy();
+ });
+
+ it('should display suggested snapshot name', () => {
+ component.openCreateSnapshotModal();
+ expect(component.modalRef.componentInstance.snapName).toMatch(
+ RegExp(`^${component.rbdName}_[\\d-]+T[\\d.:]+[\\+-][\\d:]+$`)
+ );
+ });
+ });
+
+ it('should test all TableActions combinations', () => {
+ component.ngOnInit();
+ const permissionHelper: PermissionHelper = new PermissionHelper(component.permission);
+ const tableActions: TableActionsComponent = permissionHelper.setPermissionsAndGetActions(
+ component.tableActions
+ );
+
+ expect(tableActions).toEqual({
+ 'create,update,delete': {
+ actions: [
+ 'Create',
+ 'Rename',
+ 'Protect',
+ 'Unprotect',
+ 'Clone',
+ 'Copy',
+ 'Rollback',
+ 'Delete'
+ ],
+ primary: { multiple: 'Create', executing: 'Rename', single: 'Rename', no: 'Create' }
+ },
+ 'create,update': {
+ actions: ['Create', 'Rename', 'Protect', 'Unprotect', 'Clone', 'Copy', 'Rollback'],
+ primary: { multiple: 'Create', executing: 'Rename', single: 'Rename', no: 'Create' }
+ },
+ 'create,delete': {
+ actions: ['Create', 'Clone', 'Copy', 'Delete'],
+ primary: { multiple: 'Create', executing: 'Clone', single: 'Clone', no: 'Create' }
+ },
+ create: {
+ actions: ['Create', 'Clone', 'Copy'],
+ primary: { multiple: 'Create', executing: 'Clone', single: 'Clone', no: 'Create' }
+ },
+ 'update,delete': {
+ actions: ['Rename', 'Protect', 'Unprotect', 'Rollback', 'Delete'],
+ primary: { multiple: 'Rename', executing: 'Rename', single: 'Rename', no: 'Rename' }
+ },
+ update: {
+ actions: ['Rename', 'Protect', 'Unprotect', 'Rollback'],
+ primary: { multiple: 'Rename', executing: 'Rename', single: 'Rename', no: 'Rename' }
+ },
+ delete: {
+ actions: ['Delete'],
+ primary: { multiple: 'Delete', executing: 'Delete', single: 'Delete', no: 'Delete' }
+ },
+ 'no-permissions': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ }
+ });
+ });
+
+ describe('clone button disable state', () => {
+ let actions: RbdSnapshotActionsModel;
+
+ beforeEach(() => {
+ fixture.detectChanges();
+ const rbdService = TestBed.inject(RbdService);
+ const actionLabelsI18n = TestBed.inject(ActionLabelsI18n);
+ actions = new RbdSnapshotActionsModel(actionLabelsI18n, [], rbdService);
+ });
+
+ it('should be disabled with version 1 and protected false', () => {
+ const selection = new CdTableSelection([{ name: 'someName', is_protected: false }]);
+ const disableDesc = actions.getCloneDisableDesc(selection, ['layering']);
+ expect(disableDesc).toBe('Snapshot must be protected in order to clone.');
+ });
+
+ it.each([
+ [1, true],
+ [2, true],
+ [2, false]
+ ])('should be enabled with version %d and protected %s', (version, is_protected) => {
+ actions.cloneFormatVersion = version;
+ const selection = new CdTableSelection([{ name: 'someName', is_protected: is_protected }]);
+ const disableDesc = actions.getCloneDisableDesc(selection, ['layering']);
+ expect(disableDesc).toBe(false);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts
new file mode 100644
index 000000000..df66b0e88
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts
@@ -0,0 +1,336 @@
+import {
+ ChangeDetectionStrategy,
+ ChangeDetectorRef,
+ Component,
+ Input,
+ OnChanges,
+ OnInit,
+ TemplateRef,
+ ViewChild
+} from '@angular/core';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import moment from 'moment';
+import { of } from 'rxjs';
+
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { CdHelperClass } from '~/app/shared/classes/cd-helper.class';
+import { ConfirmationModalComponent } from '~/app/shared/components/confirmation-modal/confirmation-modal.component';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { ExecutingTask } from '~/app/shared/models/executing-task';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { ImageSpec } from '~/app/shared/models/image-spec';
+import { Permission } from '~/app/shared/models/permissions';
+import { Task } from '~/app/shared/models/task';
+import { CdDatePipe } from '~/app/shared/pipes/cd-date.pipe';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { TaskListService } from '~/app/shared/services/task-list.service';
+import { TaskManagerService } from '~/app/shared/services/task-manager.service';
+import { RbdSnapshotFormModalComponent } from '../rbd-snapshot-form/rbd-snapshot-form-modal.component';
+import { RbdSnapshotActionsModel } from './rbd-snapshot-actions.model';
+import { RbdSnapshotModel } from './rbd-snapshot.model';
+
+@Component({
+ selector: 'cd-rbd-snapshot-list',
+ templateUrl: './rbd-snapshot-list.component.html',
+ styleUrls: ['./rbd-snapshot-list.component.scss'],
+ providers: [TaskListService],
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class RbdSnapshotListComponent implements OnInit, OnChanges {
+ @Input()
+ snapshots: RbdSnapshotModel[] = [];
+ @Input()
+ featuresName: string[];
+ @Input()
+ poolName: string;
+ @Input()
+ namespace: string;
+ @Input()
+ mirroring: string;
+ @Input()
+ rbdName: string;
+ @ViewChild('nameTpl')
+ nameTpl: TemplateRef<any>;
+ @ViewChild('rollbackTpl', { static: true })
+ rollbackTpl: TemplateRef<any>;
+
+ permission: Permission;
+ selection = new CdTableSelection();
+ tableActions: CdTableAction[];
+ rbdTableActions: RbdSnapshotActionsModel;
+ imageSpec: ImageSpec;
+
+ data: RbdSnapshotModel[];
+
+ columns: CdTableColumn[];
+
+ modalRef: NgbModalRef;
+
+ builders = {
+ 'rbd/snap/create': (metadata: any) => {
+ const model = new RbdSnapshotModel();
+ model.name = metadata['snapshot_name'];
+ return model;
+ }
+ };
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private modalService: ModalService,
+ private dimlessBinaryPipe: DimlessBinaryPipe,
+ private cdDatePipe: CdDatePipe,
+ private rbdService: RbdService,
+ private taskManagerService: TaskManagerService,
+ private notificationService: NotificationService,
+ private summaryService: SummaryService,
+ private taskListService: TaskListService,
+ private actionLabels: ActionLabelsI18n,
+ private cdr: ChangeDetectorRef
+ ) {
+ this.permission = this.authStorageService.getPermissions().rbdImage;
+ }
+
+ ngOnInit() {
+ this.columns = [
+ {
+ name: $localize`Name`,
+ prop: 'name',
+ cellTransformation: CellTemplate.executing,
+ flexGrow: 2
+ },
+ {
+ name: $localize`Size`,
+ prop: 'size',
+ flexGrow: 1,
+ cellClass: 'text-right',
+ pipe: this.dimlessBinaryPipe
+ },
+ {
+ name: $localize`Provisioned`,
+ prop: 'disk_usage',
+ flexGrow: 1,
+ cellClass: 'text-right',
+ pipe: this.dimlessBinaryPipe
+ },
+ {
+ name: $localize`State`,
+ prop: 'is_protected',
+ flexGrow: 1,
+ cellTransformation: CellTemplate.badge,
+ customTemplateConfig: {
+ map: {
+ true: { value: $localize`PROTECTED`, class: 'badge-success' },
+ false: { value: $localize`UNPROTECTED`, class: 'badge-info' }
+ }
+ }
+ },
+ {
+ name: $localize`Created`,
+ prop: 'timestamp',
+ flexGrow: 1,
+ pipe: this.cdDatePipe
+ }
+ ];
+
+ this.imageSpec = new ImageSpec(this.poolName, this.namespace, this.rbdName);
+ this.rbdTableActions = new RbdSnapshotActionsModel(
+ this.actionLabels,
+ this.featuresName,
+ this.rbdService
+ );
+ this.rbdTableActions.create.click = () => this.openCreateSnapshotModal();
+ this.rbdTableActions.rename.click = () => this.openEditSnapshotModal();
+ this.rbdTableActions.protect.click = () => this.toggleProtection();
+ this.rbdTableActions.unprotect.click = () => this.toggleProtection();
+ const getImageUri = () =>
+ this.selection.first() &&
+ `${this.imageSpec.toStringEncoded()}/${encodeURIComponent(this.selection.first().name)}`;
+ this.rbdTableActions.clone.routerLink = () => `/block/rbd/clone/${getImageUri()}`;
+ this.rbdTableActions.copy.routerLink = () => `/block/rbd/copy/${getImageUri()}`;
+ this.rbdTableActions.rollback.click = () => this.rollbackModal();
+ this.rbdTableActions.deleteSnap.click = () => this.deleteSnapshotModal();
+
+ this.tableActions = this.rbdTableActions.ordering;
+
+ const itemFilter = (entry: any, task: Task) => {
+ return entry.name === task.metadata['snapshot_name'];
+ };
+
+ const taskFilter = (task: Task) => {
+ return (
+ ['rbd/snap/create', 'rbd/snap/delete', 'rbd/snap/edit', 'rbd/snap/rollback'].includes(
+ task.name
+ ) && this.imageSpec.toString() === task.metadata['image_spec']
+ );
+ };
+
+ this.taskListService.init(
+ () => of(this.snapshots),
+ null,
+ (items) => {
+ const hasChanges = CdHelperClass.updateChanged(this, {
+ data: items
+ });
+ if (hasChanges) {
+ this.cdr.detectChanges();
+ this.data = [...this.data];
+ }
+ },
+ () => {
+ const hasChanges = CdHelperClass.updateChanged(this, {
+ data: this.snapshots
+ });
+ if (hasChanges) {
+ this.cdr.detectChanges();
+ this.data = [...this.data];
+ }
+ },
+ taskFilter,
+ itemFilter,
+ this.builders
+ );
+ }
+
+ ngOnChanges() {
+ if (this.columns) {
+ this.imageSpec = new ImageSpec(this.poolName, this.namespace, this.rbdName);
+ if (this.rbdTableActions) {
+ this.rbdTableActions.featuresName = this.featuresName;
+ }
+ this.taskListService.fetch();
+ }
+ }
+
+ private openSnapshotModal(taskName: string, snapName: string = null) {
+ const modalVariables = {
+ mirroring: this.mirroring
+ };
+ this.modalRef = this.modalService.show(RbdSnapshotFormModalComponent, modalVariables);
+ this.modalRef.componentInstance.poolName = this.poolName;
+ this.modalRef.componentInstance.imageName = this.rbdName;
+ this.modalRef.componentInstance.namespace = this.namespace;
+ if (snapName) {
+ this.modalRef.componentInstance.setEditing();
+ } else {
+ // Auto-create a name for the snapshot: <image_name>_<timestamp_ISO_8601>
+ // https://en.wikipedia.org/wiki/ISO_8601
+ snapName = `${this.rbdName}_${moment().toISOString(true)}`;
+ }
+ this.modalRef.componentInstance.setSnapName(snapName);
+ this.modalRef.componentInstance.onSubmit.subscribe((snapshotName: string) => {
+ const executingTask = new ExecutingTask();
+ executingTask.name = taskName;
+ executingTask.metadata = {
+ image_spec: this.imageSpec.toString(),
+ snapshot_name: snapshotName
+ };
+ this.summaryService.addRunningTask(executingTask);
+ });
+ }
+
+ openCreateSnapshotModal() {
+ this.openSnapshotModal('rbd/snap/create');
+ }
+
+ openEditSnapshotModal() {
+ this.openSnapshotModal('rbd/snap/edit', this.selection.first().name);
+ }
+
+ toggleProtection() {
+ const snapshotName = this.selection.first().name;
+ const isProtected = this.selection.first().is_protected;
+ const finishedTask = new FinishedTask();
+ finishedTask.name = 'rbd/snap/edit';
+ const imageSpec = new ImageSpec(this.poolName, this.namespace, this.rbdName);
+ finishedTask.metadata = {
+ image_spec: imageSpec.toString(),
+ snapshot_name: snapshotName
+ };
+ this.rbdService
+ .protectSnapshot(imageSpec, snapshotName, !isProtected)
+ .toPromise()
+ .then(() => {
+ const executingTask = new ExecutingTask();
+ executingTask.name = finishedTask.name;
+ executingTask.metadata = finishedTask.metadata;
+ this.summaryService.addRunningTask(executingTask);
+ this.taskManagerService.subscribe(
+ finishedTask.name,
+ finishedTask.metadata,
+ (asyncFinishedTask: FinishedTask) => {
+ this.notificationService.notifyTask(asyncFinishedTask);
+ }
+ );
+ });
+ }
+
+ _asyncTask(task: string, taskName: string, snapshotName: string) {
+ const finishedTask = new FinishedTask();
+ finishedTask.name = taskName;
+ finishedTask.metadata = {
+ image_spec: new ImageSpec(this.poolName, this.namespace, this.rbdName).toString(),
+ snapshot_name: snapshotName
+ };
+ const imageSpec = new ImageSpec(this.poolName, this.namespace, this.rbdName);
+ this.rbdService[task](imageSpec, snapshotName)
+ .toPromise()
+ .then(() => {
+ const executingTask = new ExecutingTask();
+ executingTask.name = finishedTask.name;
+ executingTask.metadata = finishedTask.metadata;
+ this.summaryService.addRunningTask(executingTask);
+ this.modalRef.close();
+ this.taskManagerService.subscribe(
+ executingTask.name,
+ executingTask.metadata,
+ (asyncFinishedTask: FinishedTask) => {
+ this.notificationService.notifyTask(asyncFinishedTask);
+ }
+ );
+ })
+ .catch(() => {
+ this.modalRef.componentInstance.stopLoadingSpinner();
+ });
+ }
+
+ rollbackModal() {
+ const snapshotName = this.selection.selected[0].name;
+ const imageSpec = new ImageSpec(this.poolName, this.namespace, this.rbdName).toString();
+ const initialState = {
+ titleText: $localize`RBD snapshot rollback`,
+ buttonText: $localize`Rollback`,
+ bodyTpl: this.rollbackTpl,
+ bodyData: {
+ snapName: `${imageSpec}@${snapshotName}`
+ },
+ onSubmit: () => {
+ this._asyncTask('rollbackSnapshot', 'rbd/snap/rollback', snapshotName);
+ }
+ };
+
+ this.modalRef = this.modalService.show(ConfirmationModalComponent, initialState);
+ }
+
+ deleteSnapshotModal() {
+ const snapshotName = this.selection.selected[0].name;
+ this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: $localize`RBD snapshot`,
+ itemNames: [snapshotName],
+ submitAction: () => this._asyncTask('deleteSnapshot', 'rbd/snap/delete', snapshotName)
+ });
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot.model.ts
new file mode 100644
index 000000000..06fd28783
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot.model.ts
@@ -0,0 +1,9 @@
+export class RbdSnapshotModel {
+ id: number;
+ name: string;
+ size: number;
+ timestamp: string;
+ is_protected: boolean;
+
+ cdExecuting: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.html
new file mode 100644
index 000000000..657568c22
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.html
@@ -0,0 +1,23 @@
+<ul ngbNav
+ #nav="ngbNav"
+ [activeId]="router.url"
+ (navChange)="router.navigate([$event.nextId])"
+ class="nav-tabs">
+ <li ngbNavItem="/block/rbd">
+ <a ngbNavLink
+ i18n>Images</a>
+ </li>
+ <li ngbNavItem="/block/rbd/namespaces">
+ <a ngbNavLink
+ i18n>Namespaces</a>
+ </li>
+ <li ngbNavItem="/block/rbd/trash">
+ <a ngbNavLink
+ i18n>Trash</a>
+ </li>
+ <li ngbNavItem="/block/rbd/performance"
+ *ngIf="grafanaPermission.read">
+ <a ngbNavLink
+ i18n>Overall Performance</a>
+ </li>
+</ul>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.spec.ts
new file mode 100644
index 000000000..73a9490d7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.spec.ts
@@ -0,0 +1,27 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RbdTabsComponent } from './rbd-tabs.component';
+
+describe('RbdTabsComponent', () => {
+ let component: RbdTabsComponent;
+ let fixture: ComponentFixture<RbdTabsComponent>;
+
+ configureTestBed({
+ imports: [RouterTestingModule, NgbNavModule],
+ declarations: [RbdTabsComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RbdTabsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.ts
new file mode 100644
index 000000000..056cb1764
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.ts
@@ -0,0 +1,19 @@
+import { Component } from '@angular/core';
+import { Router } from '@angular/router';
+
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+
+@Component({
+ selector: 'cd-rbd-tabs',
+ templateUrl: './rbd-tabs.component.html',
+ styleUrls: ['./rbd-tabs.component.scss']
+})
+export class RbdTabsComponent {
+ grafanaPermission: Permission;
+ url: string;
+
+ constructor(private authStorageService: AuthStorageService, public router: Router) {
+ this.grafanaPermission = this.authStorageService.getPermissions().grafana;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html
new file mode 100644
index 000000000..044a1e9ac
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html
@@ -0,0 +1,52 @@
+<cd-rbd-tabs></cd-rbd-tabs>
+
+<cd-table [data]="images"
+ columnMode="flex"
+ [columns]="columns"
+ identifier="id"
+ forceIdentifier="true"
+ selectionType="single"
+ [status]="tableStatus"
+ [autoReload]="-1"
+ (fetchData)="taskListService.fetch()"
+ (updateSelection)="updateSelection($event)">
+ <div class="table-actions btn-toolbar">
+ <cd-table-actions class="btn-group"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ <button class="btn btn-light"
+ type="button"
+ (click)="purgeModal()"
+ [disabled]="disablePurgeBtn"
+ *ngIf="permission.delete">
+ <i [ngClass]="[icons.destroy]"
+ aria-hidden="true"></i>
+ <ng-container i18n>Purge Trash</ng-container>
+ </button>
+ </div>
+</cd-table>
+
+<ng-template #expiresTpl
+ let-row="row"
+ let-value="value">
+ <ng-container *ngIf="row.cdIsExpired"
+ i18n>Expired at</ng-container>
+
+ <ng-container *ngIf="!row.cdIsExpired"
+ i18n>Protected until</ng-container>
+
+ {{ value | cdDate }}
+</ng-template>
+
+<ng-template #deleteTpl
+ let-expiresAt="expiresAt"
+ let-isExpired="isExpired">
+ <p class="text-danger"
+ *ngIf="!isExpired">
+ <strong>
+ <ng-container i18n>This image is protected until {{ expiresAt | cdDate }}.</ng-container>
+ </strong>
+ </p>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.spec.ts
new file mode 100644
index 000000000..17d8eed0f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.spec.ts
@@ -0,0 +1,172 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import moment from 'moment';
+import { NgxPipeFunctionModule } from 'ngx-pipe-function';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { ExecutingTask } from '~/app/shared/models/executing-task';
+import { Summary } from '~/app/shared/models/summary.model';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { TaskListService } from '~/app/shared/services/task-list.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, expectItemTasks } from '~/testing/unit-test-helper';
+import { RbdTabsComponent } from '../rbd-tabs/rbd-tabs.component';
+import { RbdTrashListComponent } from './rbd-trash-list.component';
+
+describe('RbdTrashListComponent', () => {
+ let component: RbdTrashListComponent;
+ let fixture: ComponentFixture<RbdTrashListComponent>;
+ let summaryService: SummaryService;
+ let rbdService: RbdService;
+
+ configureTestBed({
+ declarations: [RbdTrashListComponent, RbdTabsComponent],
+ imports: [
+ BrowserAnimationsModule,
+ HttpClientTestingModule,
+ RouterTestingModule,
+ SharedModule,
+ NgbNavModule,
+ NgxPipeFunctionModule,
+ ToastrModule.forRoot()
+ ],
+ providers: [TaskListService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RbdTrashListComponent);
+ component = fixture.componentInstance;
+ summaryService = TestBed.inject(SummaryService);
+ rbdService = TestBed.inject(RbdService);
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should load trash images when summary is trigged', () => {
+ spyOn(rbdService, 'listTrash').and.callThrough();
+
+ summaryService['summaryDataSource'].next(new Summary());
+ expect(rbdService.listTrash).toHaveBeenCalled();
+ });
+
+ it('should call updateSelection', () => {
+ expect(component.selection.hasSelection).toBeFalsy();
+ component.updateSelection(new CdTableSelection(['foo']));
+ expect(component.selection.hasSelection).toBeTruthy();
+ });
+
+ describe('handling of executing tasks', () => {
+ let images: any[];
+
+ const addImage = (id: string) => {
+ images.push({
+ id: id,
+ pool_name: 'pl'
+ });
+ };
+
+ const addTask = (name: string, image_id: string) => {
+ const task = new ExecutingTask();
+ task.name = name;
+ task.metadata = {
+ image_id_spec: `pl/${image_id}`
+ };
+ summaryService.addRunningTask(task);
+ };
+
+ beforeEach(() => {
+ images = [];
+ addImage('1');
+ addImage('2');
+ component.images = images;
+ summaryService['summaryDataSource'].next(new Summary());
+ spyOn(rbdService, 'listTrash').and.callFake(() =>
+ of([{ pool_name: 'rbd', status: 1, value: images }])
+ );
+ fixture.detectChanges();
+ });
+
+ it('should gets all images without tasks', () => {
+ expect(component.images.length).toBe(2);
+ expect(
+ component.images.every((image: Record<string, any>) => !image.cdExecuting)
+ ).toBeTruthy();
+ });
+
+ it('should show when an existing image is being modified', () => {
+ addTask('rbd/trash/remove', '1');
+ addTask('rbd/trash/restore', '2');
+ expect(component.images.length).toBe(2);
+ expectItemTasks(component.images[0], 'Deleting');
+ expectItemTasks(component.images[1], 'Restoring');
+ });
+ });
+
+ describe('display purge button', () => {
+ let images: any[];
+ const addImage = (id: string) => {
+ images.push({
+ id: id,
+ pool_name: 'pl',
+ deferment_end_time: moment()
+ });
+ };
+
+ beforeEach(() => {
+ summaryService['summaryDataSource'].next(new Summary());
+ spyOn(rbdService, 'listTrash').and.callFake(() => {
+ of([{ pool_name: 'rbd', status: 1, value: images }]);
+ });
+ fixture.detectChanges();
+ });
+
+ it('should show button disabled when no image is in trash', () => {
+ expect(component.disablePurgeBtn).toBeTruthy();
+ });
+
+ it('should show button enabled when an existing image is in trash', () => {
+ images = [];
+ addImage('1');
+ const payload = [{ pool_name: 'rbd', status: 1, value: images }];
+ component.prepareResponse(payload);
+ expect(component.disablePurgeBtn).toBeFalsy();
+ });
+
+ it('should show button with delete permission', () => {
+ component.permission = {
+ read: true,
+ create: true,
+ delete: true,
+ update: true
+ };
+ fixture.detectChanges();
+
+ const purge = fixture.debugElement.query(By.css('.table-actions button .fa-times'));
+ expect(purge).not.toBeNull();
+ });
+
+ it('should remove button without delete permission', () => {
+ component.permission = {
+ read: true,
+ create: true,
+ delete: false,
+ update: true
+ };
+ fixture.detectChanges();
+
+ const purge = fixture.debugElement.query(By.css('.table-actions button .fa-times'));
+ expect(purge).toBeNull();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts
new file mode 100644
index 000000000..43fe42b99
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts
@@ -0,0 +1,225 @@
+import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import moment from 'moment';
+
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { TableStatusViewCache } from '~/app/shared/classes/table-status-view-cache';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { TableComponent } from '~/app/shared/datatable/table/table.component';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { ViewCacheStatus } from '~/app/shared/enum/view-cache-status.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { ExecutingTask } from '~/app/shared/models/executing-task';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { ImageSpec } from '~/app/shared/models/image-spec';
+import { Permission } from '~/app/shared/models/permissions';
+import { Task } from '~/app/shared/models/task';
+import { CdDatePipe } from '~/app/shared/pipes/cd-date.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { TaskListService } from '~/app/shared/services/task-list.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { RbdTrashPurgeModalComponent } from '../rbd-trash-purge-modal/rbd-trash-purge-modal.component';
+import { RbdTrashRestoreModalComponent } from '../rbd-trash-restore-modal/rbd-trash-restore-modal.component';
+
+@Component({
+ selector: 'cd-rbd-trash-list',
+ templateUrl: './rbd-trash-list.component.html',
+ styleUrls: ['./rbd-trash-list.component.scss'],
+ providers: [TaskListService]
+})
+export class RbdTrashListComponent implements OnInit {
+ @ViewChild(TableComponent, { static: true })
+ table: TableComponent;
+ @ViewChild('expiresTpl', { static: true })
+ expiresTpl: TemplateRef<any>;
+ @ViewChild('deleteTpl', { static: true })
+ deleteTpl: TemplateRef<any>;
+
+ icons = Icons;
+
+ columns: CdTableColumn[];
+ executingTasks: ExecutingTask[] = [];
+ images: any;
+ modalRef: NgbModalRef;
+ permission: Permission;
+ retries: number;
+ selection = new CdTableSelection();
+ tableActions: CdTableAction[];
+ tableStatus = new TableStatusViewCache();
+ disablePurgeBtn = true;
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private rbdService: RbdService,
+ private modalService: ModalService,
+ private cdDatePipe: CdDatePipe,
+ public taskListService: TaskListService,
+ private taskWrapper: TaskWrapperService,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ this.permission = this.authStorageService.getPermissions().rbdImage;
+ const restoreAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.undo,
+ click: () => this.restoreModal(),
+ name: this.actionLabels.RESTORE
+ };
+ const deleteAction: CdTableAction = {
+ permission: 'delete',
+ icon: Icons.destroy,
+ click: () => this.deleteModal(),
+ name: this.actionLabels.DELETE
+ };
+ this.tableActions = [restoreAction, deleteAction];
+ }
+
+ ngOnInit() {
+ this.columns = [
+ {
+ name: $localize`ID`,
+ prop: 'id',
+ flexGrow: 1,
+ cellTransformation: CellTemplate.executing
+ },
+ {
+ name: $localize`Name`,
+ prop: 'name',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Pool`,
+ prop: 'pool_name',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Namespace`,
+ prop: 'namespace',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Status`,
+ prop: 'deferment_end_time',
+ flexGrow: 1,
+ cellTemplate: this.expiresTpl
+ },
+ {
+ name: $localize`Deleted At`,
+ prop: 'deletion_time',
+ flexGrow: 1,
+ pipe: this.cdDatePipe
+ }
+ ];
+
+ const itemFilter = (entry: any, task: Task) => {
+ const imageSpec = new ImageSpec(entry.pool_name, entry.namespace, entry.id);
+ return imageSpec.toString() === task.metadata['image_id_spec'];
+ };
+
+ const taskFilter = (task: Task) => {
+ return ['rbd/trash/remove', 'rbd/trash/restore'].includes(task.name);
+ };
+
+ this.taskListService.init(
+ () => this.rbdService.listTrash(),
+ (resp) => this.prepareResponse(resp),
+ (images) => (this.images = images),
+ () => this.onFetchError(),
+ taskFilter,
+ itemFilter,
+ undefined
+ );
+ }
+
+ prepareResponse(resp: any[]): any[] {
+ let images: any[] = [];
+ const viewCacheStatusMap = {};
+
+ resp.forEach((pool: Record<string, any>) => {
+ if (_.isUndefined(viewCacheStatusMap[pool.status])) {
+ viewCacheStatusMap[pool.status] = [];
+ }
+ viewCacheStatusMap[pool.status].push(pool.pool_name);
+ images = images.concat(pool.value);
+ this.disablePurgeBtn = !images.length;
+ });
+
+ let status: number;
+ if (viewCacheStatusMap[3]) {
+ status = 3;
+ } else if (viewCacheStatusMap[1]) {
+ status = 1;
+ } else if (viewCacheStatusMap[2]) {
+ status = 2;
+ }
+
+ if (status) {
+ const statusFor =
+ (viewCacheStatusMap[status].length > 1 ? 'pools ' : 'pool ') +
+ viewCacheStatusMap[status].join();
+
+ this.tableStatus = new TableStatusViewCache(status, statusFor);
+ } else {
+ this.tableStatus = new TableStatusViewCache();
+ }
+
+ images.forEach((image) => {
+ image.cdIsExpired = moment().isAfter(image.deferment_end_time);
+ });
+
+ return images;
+ }
+
+ onFetchError() {
+ this.table.reset(); // Disable loading indicator.
+ this.tableStatus = new TableStatusViewCache(ViewCacheStatus.ValueException);
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ restoreModal() {
+ const initialState = {
+ poolName: this.selection.first().pool_name,
+ namespace: this.selection.first().namespace,
+ imageName: this.selection.first().name,
+ imageId: this.selection.first().id
+ };
+
+ this.modalRef = this.modalService.show(RbdTrashRestoreModalComponent, initialState);
+ }
+
+ deleteModal() {
+ const poolName = this.selection.first().pool_name;
+ const namespace = this.selection.first().namespace;
+ const imageId = this.selection.first().id;
+ const expiresAt = this.selection.first().deferment_end_time;
+ const isExpired = moment().isAfter(expiresAt);
+ const imageIdSpec = new ImageSpec(poolName, namespace, imageId);
+
+ this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: 'RBD',
+ itemNames: [imageIdSpec],
+ bodyTemplate: this.deleteTpl,
+ bodyContext: { expiresAt, isExpired },
+ submitActionObservable: () =>
+ this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('rbd/trash/remove', {
+ image_id_spec: imageIdSpec.toString()
+ }),
+ call: this.rbdService.removeTrash(imageIdSpec, true)
+ })
+ });
+ }
+
+ purgeModal() {
+ this.modalService.show(RbdTrashPurgeModalComponent);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html
new file mode 100644
index 000000000..00c3f9265
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html
@@ -0,0 +1,57 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container i18n
+ class="modal-title">Move an image to trash</ng-container>
+
+ <ng-container class="modal-content">
+ <form name="moveForm"
+ class="form"
+ #formDir="ngForm"
+ [formGroup]="moveForm"
+ novalidate>
+ <div class="modal-body">
+ <div class="alert alert-warning"
+ *ngIf="hasSnapshots"
+ role="alert">
+ <span i18n>This image contains snapshot(s), which will prevent it
+ from being removed after moved to trash.</span>
+ </div>
+
+ <p i18n>To move <kbd>{{ imageSpecStr }}</kbd> to trash,
+ click <kbd>Move</kbd>. Optionally, you can pick an expiration date.</p>
+
+ <div class="form-group">
+ <label class="col-form-label"
+ for="expiresAt"
+ i18n>Protection expires at</label>
+ <input type="text"
+ placeholder="NOT PROTECTED"
+ i18n-placeholder
+ class="form-control"
+ formControlName="expiresAt"
+ [ngbPopover]="popContent"
+ triggers="manual"
+ #p="ngbPopover"
+ (click)="p.open()"
+ (keypress)="p.close()">
+
+ <span class="invalid-feedback"
+ *ngIf="moveForm.showError('expiresAt', formDir, 'format')"
+ i18n>Wrong date format. Please use "YYYY-MM-DD HH:mm:ss".</span>
+ <span class="invalid-feedback"
+ *ngIf="moveForm.showError('expiresAt', formDir, 'expired')"
+ i18n>Protection has already expired. Please pick a future date or leave it empty.</span>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="moveImage()"
+ [form]="moveForm"
+ [submitText]="actionLabels.MOVE"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
+
+<ng-template #popContent>
+ <cd-date-time-picker [control]="moveForm.get('expiresAt')"></cd-date-time-picker>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.spec.ts
new file mode 100644
index 000000000..0381046b7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.spec.ts
@@ -0,0 +1,94 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap';
+import moment from 'moment';
+import { ToastrModule } from 'ngx-toastr';
+
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RbdTrashMoveModalComponent } from './rbd-trash-move-modal.component';
+
+describe('RbdTrashMoveModalComponent', () => {
+ let component: RbdTrashMoveModalComponent;
+ let fixture: ComponentFixture<RbdTrashMoveModalComponent>;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ imports: [
+ ReactiveFormsModule,
+ HttpClientTestingModule,
+ RouterTestingModule,
+ SharedModule,
+ ToastrModule.forRoot(),
+ NgbPopoverModule
+ ],
+ declarations: [RbdTrashMoveModalComponent],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RbdTrashMoveModalComponent);
+ component = fixture.componentInstance;
+ httpTesting = TestBed.inject(HttpTestingController);
+
+ component.poolName = 'foo';
+ component.imageName = 'bar';
+
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ expect(component.moveForm).toBeDefined();
+ });
+
+ it('should finish running ngOnInit', () => {
+ expect(component.pattern).toEqual('foo/bar');
+ });
+
+ describe('should call moveImage', () => {
+ let notificationService: NotificationService;
+
+ beforeEach(() => {
+ notificationService = TestBed.inject(NotificationService);
+ spyOn(notificationService, 'show').and.stub();
+ spyOn(component.activeModal, 'close').and.callThrough();
+ });
+
+ afterEach(() => {
+ expect(notificationService.show).toHaveBeenCalledTimes(1);
+ expect(component.activeModal.close).toHaveBeenCalledTimes(1);
+ });
+
+ it('with normal delay', () => {
+ component.moveImage();
+ const req = httpTesting.expectOne('api/block/image/foo%2Fbar/move_trash');
+ req.flush(null);
+ expect(req.request.body).toEqual({ delay: 0 });
+ });
+
+ it('with delay < 0', () => {
+ const oldDate = moment().subtract(24, 'hour').toDate();
+ component.moveForm.patchValue({ expiresAt: oldDate });
+
+ component.moveImage();
+ const req = httpTesting.expectOne('api/block/image/foo%2Fbar/move_trash');
+ req.flush(null);
+ expect(req.request.body).toEqual({ delay: 0 });
+ });
+
+ it('with delay < 0', () => {
+ const oldDate = moment().add(24, 'hour').toISOString();
+ component.moveForm.patchValue({ expiresAt: oldDate });
+
+ component.moveImage();
+ const req = httpTesting.expectOne('api/block/image/foo%2Fbar/move_trash');
+ req.flush(null);
+ expect(req.request.body.delay).toBeGreaterThan(76390);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.ts
new file mode 100644
index 000000000..ccf381f9c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.ts
@@ -0,0 +1,94 @@
+import { Component, OnInit } from '@angular/core';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import moment from 'moment';
+
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { ExecutingTask } from '~/app/shared/models/executing-task';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { ImageSpec } from '~/app/shared/models/image-spec';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+
+@Component({
+ selector: 'cd-rbd-trash-move-modal',
+ templateUrl: './rbd-trash-move-modal.component.html',
+ styleUrls: ['./rbd-trash-move-modal.component.scss']
+})
+export class RbdTrashMoveModalComponent implements OnInit {
+ // initial state
+ poolName: string;
+ namespace: string;
+ imageName: string;
+ hasSnapshots: boolean;
+
+ imageSpec: ImageSpec;
+ imageSpecStr: string;
+ executingTasks: ExecutingTask[];
+
+ moveForm: CdFormGroup;
+ pattern: string;
+
+ constructor(
+ private rbdService: RbdService,
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n,
+ private fb: CdFormBuilder,
+ private taskWrapper: TaskWrapperService
+ ) {
+ this.createForm();
+ }
+
+ createForm() {
+ this.moveForm = this.fb.group({
+ expiresAt: [
+ '',
+ [
+ CdValidators.custom('format', (expiresAt: string) => {
+ const result = expiresAt === '' || moment(expiresAt, 'YYYY-MM-DD HH:mm:ss').isValid();
+ return !result;
+ }),
+ CdValidators.custom('expired', (expiresAt: string) => {
+ const result = moment().isAfter(expiresAt);
+ return result;
+ })
+ ]
+ ]
+ });
+ }
+
+ ngOnInit() {
+ this.imageSpec = new ImageSpec(this.poolName, this.namespace, this.imageName);
+ this.imageSpecStr = this.imageSpec.toString();
+ this.pattern = `${this.poolName}/${this.imageName}`;
+ }
+
+ moveImage() {
+ let delay = 0;
+ const expiresAt = this.moveForm.getValue('expiresAt');
+
+ if (expiresAt) {
+ delay = moment(expiresAt, 'YYYY-MM-DD HH:mm:ss').diff(moment(), 'seconds', true);
+ }
+
+ if (delay < 0) {
+ delay = 0;
+ }
+
+ this.taskWrapper
+ .wrapTaskAroundCall({
+ task: new FinishedTask('rbd/trash/move', {
+ image_spec: this.imageSpecStr
+ }),
+ call: this.rbdService.moveTrash(this.imageSpec, delay)
+ })
+ .subscribe({
+ complete: () => {
+ this.activeModal.close();
+ }
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html
new file mode 100644
index 000000000..7c761f8f4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html
@@ -0,0 +1,46 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container i18n
+ class="modal-title">Purge Trash</ng-container>
+
+ <ng-container class="modal-content">
+ <form name="purgeForm"
+ class="form"
+ #formDir="ngForm"
+ [formGroup]="purgeForm"
+ novalidate>
+ <div class="modal-body">
+ <p i18n>To purge, select&nbsp;
+ <kbd>All</kbd>&nbsp;
+ or one pool and click&nbsp;
+ <kbd>Purge</kbd>.&nbsp;</p>
+
+ <div class="form-group">
+ <label class="col-form-label mx-auto"
+ i18n>Pool:</label>
+ <input class="form-control"
+ type="text"
+ placeholder="Pool name..."
+ i18n-placeholder
+ formControlName="poolName"
+ *ngIf="!poolPermission.read">
+ <select id="poolName"
+ name="poolName"
+ class="form-control"
+ formControlName="poolName"
+ *ngIf="poolPermission.read">
+ <option value=""
+ i18n>All</option>
+ <option *ngFor="let pool of pools"
+ [value]="pool">{{ pool }}</option>
+ </select>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="purge()"
+ [form]="purgeForm"
+ [submitText]="actionLabels.PURGE"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.spec.ts
new file mode 100644
index 000000000..7f1708fff
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.spec.ts
@@ -0,0 +1,105 @@
+import {
+ HttpClientTestingModule,
+ HttpTestingController,
+ TestRequest
+} from '@angular/common/http/testing';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+
+import { Permission } from '~/app/shared/models/permissions';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RbdTrashPurgeModalComponent } from './rbd-trash-purge-modal.component';
+
+describe('RbdTrashPurgeModalComponent', () => {
+ let component: RbdTrashPurgeModalComponent;
+ let fixture: ComponentFixture<RbdTrashPurgeModalComponent>;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ SharedModule,
+ ToastrModule.forRoot(),
+ RouterTestingModule
+ ],
+ declarations: [RbdTrashPurgeModalComponent],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RbdTrashPurgeModalComponent);
+ httpTesting = TestBed.inject(HttpTestingController);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+
+ it('should finish ngOnInit', fakeAsync(() => {
+ component.poolPermission = new Permission(['read', 'create', 'update', 'delete']);
+ fixture.detectChanges();
+ const req = httpTesting.expectOne('api/pool?attrs=pool_name,application_metadata');
+ req.flush([
+ {
+ application_metadata: ['foo'],
+ pool_name: 'bar'
+ },
+ {
+ application_metadata: ['rbd'],
+ pool_name: 'baz'
+ }
+ ]);
+ tick();
+ expect(component.pools).toEqual(['baz']);
+ expect(component.purgeForm).toBeTruthy();
+ }));
+
+ it('should call ngOnInit without pool permissions', () => {
+ component.poolPermission = new Permission([]);
+ component.ngOnInit();
+ httpTesting.verify();
+ });
+
+ describe('should call purge', () => {
+ let notificationService: NotificationService;
+ let activeModal: NgbActiveModal;
+ let req: TestRequest;
+
+ beforeEach(() => {
+ fixture.detectChanges();
+ notificationService = TestBed.inject(NotificationService);
+ activeModal = TestBed.inject(NgbActiveModal);
+
+ component.purgeForm.patchValue({ poolName: 'foo' });
+
+ spyOn(activeModal, 'close').and.stub();
+ spyOn(component.purgeForm, 'setErrors').and.stub();
+ spyOn(notificationService, 'show').and.stub();
+
+ component.purge();
+
+ req = httpTesting.expectOne('api/block/image/trash/purge/?pool_name=foo');
+ });
+
+ it('with success', () => {
+ req.flush(null);
+ expect(component.purgeForm.setErrors).toHaveBeenCalledTimes(0);
+ expect(component.activeModal.close).toHaveBeenCalledTimes(1);
+ });
+
+ it('with failure', () => {
+ req.flush(null, { status: 500, statusText: 'failure' });
+ expect(component.purgeForm.setErrors).toHaveBeenCalledTimes(1);
+ expect(component.activeModal.close).toHaveBeenCalledTimes(0);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.ts
new file mode 100644
index 000000000..e4df25d15
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.ts
@@ -0,0 +1,74 @@
+import { Component, OnInit } from '@angular/core';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+import { Pool } from '~/app/ceph/pool/pool';
+import { PoolService } from '~/app/shared/api/pool.service';
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+
+@Component({
+ selector: 'cd-rbd-trash-purge-modal',
+ templateUrl: './rbd-trash-purge-modal.component.html',
+ styleUrls: ['./rbd-trash-purge-modal.component.scss']
+})
+export class RbdTrashPurgeModalComponent implements OnInit {
+ poolPermission: Permission;
+ purgeForm: CdFormGroup;
+ pools: any[];
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private rbdService: RbdService,
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n,
+ private fb: CdFormBuilder,
+ private poolService: PoolService,
+ private taskWrapper: TaskWrapperService
+ ) {
+ this.poolPermission = this.authStorageService.getPermissions().pool;
+ }
+
+ createForm() {
+ this.purgeForm = this.fb.group({
+ poolName: ''
+ });
+ }
+
+ ngOnInit() {
+ if (this.poolPermission.read) {
+ this.poolService.list(['pool_name', 'application_metadata']).then((resp) => {
+ this.pools = resp
+ .filter((pool: Pool) => pool.application_metadata.includes('rbd'))
+ .map((pool: Pool) => pool.pool_name);
+ });
+ }
+
+ this.createForm();
+ }
+
+ purge() {
+ const poolName = this.purgeForm.getValue('poolName') || '';
+ this.taskWrapper
+ .wrapTaskAroundCall({
+ task: new FinishedTask('rbd/trash/purge', {
+ pool_name: poolName
+ }),
+ call: this.rbdService.purgeTrash(poolName)
+ })
+ .subscribe({
+ error: () => {
+ this.purgeForm.setErrors({ cdSubmitButton: true });
+ },
+ complete: () => {
+ this.activeModal.close();
+ }
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html
new file mode 100644
index 000000000..2cc3e08df
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html
@@ -0,0 +1,41 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container i18n
+ class="modal-title">Restore Image</ng-container>
+
+ <ng-container class="modal-content">
+ <form name="restoreForm"
+ class="form"
+ #formDir="ngForm"
+ [formGroup]="restoreForm"
+ novalidate>
+ <div class="modal-body">
+ <p i18n>To restore&nbsp;
+ <kbd>{{ imageSpec }}@{{ imageId }}</kbd>,&nbsp;
+ type the image's new name and click&nbsp;
+ <kbd>Restore</kbd>.</p>
+
+ <div class="form-group">
+ <label class="col-form-label"
+ for="name"
+ i18n>New Name</label>
+ <input type="text"
+ class="form-control"
+ name="name"
+ id="name"
+ autocomplete="off"
+ formControlName="name"
+ autofocus>
+ <span class="invalid-feedback"
+ *ngIf="restoreForm.showError('name', formDir, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="restore()"
+ [form]="restoreForm"
+ [submitText]="actionLabels.RESTORE"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.spec.ts
new file mode 100644
index 000000000..7eb963a6e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.spec.ts
@@ -0,0 +1,81 @@
+import {
+ HttpClientTestingModule,
+ HttpTestingController,
+ TestRequest
+} from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RbdTrashRestoreModalComponent } from './rbd-trash-restore-modal.component';
+
+describe('RbdTrashRestoreModalComponent', () => {
+ let component: RbdTrashRestoreModalComponent;
+ let fixture: ComponentFixture<RbdTrashRestoreModalComponent>;
+
+ configureTestBed({
+ declarations: [RbdTrashRestoreModalComponent],
+ imports: [
+ ReactiveFormsModule,
+ HttpClientTestingModule,
+ ToastrModule.forRoot(),
+ SharedModule,
+ RouterTestingModule
+ ],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RbdTrashRestoreModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('should call restore', () => {
+ let httpTesting: HttpTestingController;
+ let notificationService: NotificationService;
+ let activeModal: NgbActiveModal;
+ let req: TestRequest;
+
+ beforeEach(() => {
+ httpTesting = TestBed.inject(HttpTestingController);
+ notificationService = TestBed.inject(NotificationService);
+ activeModal = TestBed.inject(NgbActiveModal);
+
+ component.poolName = 'foo';
+ component.imageName = 'bar';
+ component.imageId = '113cb6963793';
+ component.ngOnInit();
+
+ spyOn(activeModal, 'close').and.stub();
+ spyOn(component.restoreForm, 'setErrors').and.stub();
+ spyOn(notificationService, 'show').and.stub();
+
+ component.restore();
+
+ req = httpTesting.expectOne('api/block/image/trash/foo%2F113cb6963793/restore');
+ });
+
+ it('with success', () => {
+ req.flush(null);
+ expect(component.restoreForm.setErrors).toHaveBeenCalledTimes(0);
+ expect(component.activeModal.close).toHaveBeenCalledTimes(1);
+ });
+
+ it('with failure', () => {
+ req.flush(null, { status: 500, statusText: 'failure' });
+ expect(component.restoreForm.setErrors).toHaveBeenCalledTimes(1);
+ expect(component.activeModal.close).toHaveBeenCalledTimes(0);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.ts
new file mode 100644
index 000000000..860d66cc0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.ts
@@ -0,0 +1,65 @@
+import { Component, OnInit } from '@angular/core';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { ExecutingTask } from '~/app/shared/models/executing-task';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { ImageSpec } from '~/app/shared/models/image-spec';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+
+@Component({
+ selector: 'cd-rbd-trash-restore-modal',
+ templateUrl: './rbd-trash-restore-modal.component.html',
+ styleUrls: ['./rbd-trash-restore-modal.component.scss']
+})
+export class RbdTrashRestoreModalComponent implements OnInit {
+ poolName: string;
+ namespace: string;
+ imageName: string;
+ imageSpec: string;
+ imageId: string;
+ executingTasks: ExecutingTask[];
+
+ restoreForm: CdFormGroup;
+
+ constructor(
+ private rbdService: RbdService,
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n,
+ private fb: CdFormBuilder,
+ private taskWrapper: TaskWrapperService
+ ) {}
+
+ ngOnInit() {
+ this.imageSpec = new ImageSpec(this.poolName, this.namespace, this.imageName).toString();
+ this.restoreForm = this.fb.group({
+ name: this.imageName
+ });
+ }
+
+ restore() {
+ const name = this.restoreForm.getValue('name');
+ const imageSpec = new ImageSpec(this.poolName, this.namespace, this.imageId);
+
+ this.taskWrapper
+ .wrapTaskAroundCall({
+ task: new FinishedTask('rbd/trash/restore', {
+ image_id_spec: imageSpec.toString(),
+ new_image_name: name
+ }),
+ call: this.rbdService.restoreTrash(imageSpec, name)
+ })
+ .subscribe({
+ error: () => {
+ this.restoreForm.setErrors({ cdSubmitButton: true });
+ },
+ complete: () => {
+ this.activeModal.close();
+ }
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/ceph.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/ceph.module.ts
new file mode 100644
index 000000000..47772304b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/ceph.module.ts
@@ -0,0 +1,23 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+
+import { SharedModule } from '../shared/shared.module';
+import { CephfsModule } from './cephfs/cephfs.module';
+import { ClusterModule } from './cluster/cluster.module';
+import { DashboardModule } from './dashboard/dashboard.module';
+import { NfsModule } from './nfs/nfs.module';
+import { PerformanceCounterModule } from './performance-counter/performance-counter.module';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ ClusterModule,
+ DashboardModule,
+ PerformanceCounterModule,
+ CephfsModule,
+ NfsModule,
+ SharedModule
+ ],
+ declarations: []
+})
+export class CephModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.html
new file mode 100644
index 000000000..b81bc20ba
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.html
@@ -0,0 +1,12 @@
+<div class="chart-container">
+ <canvas baseChart
+ #chartCanvas
+ [datasets]="chart.datasets"
+ [options]="chart.options"
+ [chartType]="chart.chartType">
+ </canvas>
+ <div class="chartjs-tooltip"
+ #chartTooltip>
+ <table></table>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.scss
new file mode 100644
index 000000000..f90af6f5a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.scss
@@ -0,0 +1,8 @@
+@use './src/styles/chart-tooltip';
+
+.chart-container {
+ height: 500px;
+ margin-bottom: 20px;
+ position: relative;
+ width: 100%;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.spec.ts
new file mode 100644
index 000000000..4ba20fa89
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.spec.ts
@@ -0,0 +1,81 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ChartsModule } from 'ng2-charts';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { CephfsChartComponent } from './cephfs-chart.component';
+
+describe('CephfsChartComponent', () => {
+ let component: CephfsChartComponent;
+ let fixture: ComponentFixture<CephfsChartComponent>;
+
+ const counter = [
+ [0, 15],
+ [5, 15],
+ [10, 25],
+ [15, 50]
+ ];
+
+ configureTestBed({
+ imports: [ChartsModule],
+ declarations: [CephfsChartComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CephfsChartComponent);
+ component = fixture.componentInstance;
+ component.mdsCounter = {
+ 'mds_server.handle_client_request': counter,
+ 'mds_mem.ino': counter,
+ name: 'a'
+ };
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('completed the chart', () => {
+ const lhs = component.chart.datasets[0].data;
+ expect(lhs.length).toBe(3);
+ expect(lhs).toEqual([
+ {
+ x: 5000,
+ y: 15
+ },
+ {
+ x: 10000,
+ y: 25
+ },
+ {
+ x: 15000,
+ y: 50
+ }
+ ]);
+
+ const rhs = component.chart.datasets[1].data;
+ expect(rhs.length).toBe(3);
+ expect(rhs).toEqual([
+ {
+ x: 5000,
+ y: 0
+ },
+ {
+ x: 10000,
+ y: 10
+ },
+ {
+ x: 15000,
+ y: 25
+ }
+ ]);
+ });
+
+ it('should force angular to update the chart datasets array in order to update the graph', () => {
+ const oldDatasets = component.chart.datasets;
+ component.ngOnChanges();
+ expect(oldDatasets).toEqual(component.chart.datasets);
+ expect(oldDatasets).not.toBe(component.chart.datasets);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.ts
new file mode 100644
index 000000000..7f3c9437d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.ts
@@ -0,0 +1,196 @@
+import { Component, ElementRef, Input, OnChanges, OnInit, ViewChild } from '@angular/core';
+
+import { ChartDataSets, ChartOptions, ChartPoint, ChartType } from 'chart.js';
+import _ from 'lodash';
+import moment from 'moment';
+
+import { ChartTooltip } from '~/app/shared/models/chart-tooltip';
+
+@Component({
+ selector: 'cd-cephfs-chart',
+ templateUrl: './cephfs-chart.component.html',
+ styleUrls: ['./cephfs-chart.component.scss']
+})
+export class CephfsChartComponent implements OnChanges, OnInit {
+ @ViewChild('chartCanvas', { static: true })
+ chartCanvas: ElementRef;
+ @ViewChild('chartTooltip', { static: true })
+ chartTooltip: ElementRef;
+
+ @Input()
+ mdsCounter: any;
+
+ lhsCounter = 'mds_mem.ino';
+ rhsCounter = 'mds_server.handle_client_request';
+
+ chart: {
+ datasets: ChartDataSets[];
+ options: ChartOptions;
+ chartType: ChartType;
+ } = {
+ datasets: [
+ {
+ label: this.lhsCounter,
+ yAxisID: 'LHS',
+ data: [],
+ lineTension: 0.1
+ },
+ {
+ label: this.rhsCounter,
+ yAxisID: 'RHS',
+ data: [],
+ lineTension: 0.1
+ }
+ ],
+ options: {
+ title: {
+ text: '',
+ display: true
+ },
+ responsive: true,
+ maintainAspectRatio: false,
+ legend: {
+ position: 'top'
+ },
+ scales: {
+ xAxes: [
+ {
+ position: 'top',
+ type: 'time',
+ time: {
+ displayFormats: {
+ quarter: 'MMM YYYY'
+ }
+ },
+ ticks: {
+ maxRotation: 0
+ }
+ }
+ ],
+ yAxes: [
+ {
+ id: 'LHS',
+ type: 'linear',
+ position: 'left'
+ },
+ {
+ id: 'RHS',
+ type: 'linear',
+ position: 'right'
+ }
+ ]
+ },
+ tooltips: {
+ enabled: false,
+ mode: 'index',
+ intersect: false,
+ position: 'nearest',
+ callbacks: {
+ // Pick the Unix timestamp of the first tooltip item.
+ title: (tooltipItems, data): string => {
+ let ts = 0;
+ if (tooltipItems.length > 0) {
+ const item = tooltipItems[0];
+ const point = data.datasets[item.datasetIndex].data[item.index] as ChartPoint;
+ ts = point.x as number;
+ }
+ return ts.toString();
+ }
+ }
+ }
+ },
+ chartType: 'line'
+ };
+
+ ngOnInit() {
+ if (_.isUndefined(this.mdsCounter)) {
+ return;
+ }
+ this.setChartTooltip();
+ this.updateChart();
+ }
+
+ ngOnChanges() {
+ if (_.isUndefined(this.mdsCounter)) {
+ return;
+ }
+ this.updateChart();
+ }
+
+ private setChartTooltip() {
+ const chartTooltip = new ChartTooltip(
+ this.chartCanvas,
+ this.chartTooltip,
+ (tooltip: any) => tooltip.caretX + 'px',
+ (tooltip: any) => tooltip.caretY - tooltip.height - 23 + 'px'
+ );
+ chartTooltip.getTitle = (ts) => moment(ts, 'x').format('LTS');
+ chartTooltip.checkOffset = true;
+ const chartOptions: ChartOptions = {
+ title: {
+ text: this.mdsCounter.name
+ },
+ tooltips: {
+ custom: (tooltip) => chartTooltip.customTooltips(tooltip)
+ }
+ };
+ _.merge(this.chart, { options: chartOptions });
+ }
+
+ private updateChart() {
+ const chartDataSets: ChartDataSets[] = [
+ {
+ data: this.convertTimeSeries(this.mdsCounter[this.lhsCounter])
+ },
+ {
+ data: this.deltaTimeSeries(this.mdsCounter[this.rhsCounter])
+ }
+ ];
+ _.merge(this.chart, {
+ datasets: chartDataSets
+ });
+ this.chart.datasets = [...this.chart.datasets]; // Force angular to update
+ }
+
+ /**
+ * Convert ceph-mgr's time series format (list of 2-tuples
+ * with seconds-since-epoch timestamps) into what chart.js
+ * can handle (list of objects with millisecs-since-epoch
+ * timestamps)
+ */
+ private convertTimeSeries(sourceSeries: any) {
+ const data: any[] = [];
+ _.each(sourceSeries, (dp) => {
+ data.push({
+ x: dp[0] * 1000,
+ y: dp[1]
+ });
+ });
+
+ /**
+ * MDS performance counters chart is expecting the same number of items
+ * from each data series. Since in deltaTimeSeries we are ignoring the first
+ * element, we will do the same here.
+ */
+ data.shift();
+
+ return data;
+ }
+
+ private deltaTimeSeries(sourceSeries: any) {
+ let i;
+ let prev = sourceSeries[0];
+ const result = [];
+ for (i = 1; i < sourceSeries.length; i++) {
+ const cur = sourceSeries[i];
+
+ result.push({
+ x: cur[0] * 1000,
+ y: cur[1] - prev[1]
+ });
+
+ prev = cur;
+ }
+ return result;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.html
new file mode 100644
index 000000000..cb1ee364c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.html
@@ -0,0 +1,13 @@
+<cd-table [data]="clients.data"
+ [columns]="columns"
+ [status]="clients.status"
+ [autoReload]="-1"
+ (fetchData)="triggerApiUpdate.emit()"
+ selectionType="single"
+ (updateSelection)="updateSelection($event)">
+ <cd-table-actions class="table-actions"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+</cd-table>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.spec.ts
new file mode 100644
index 000000000..f7a7f64bf
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.spec.ts
@@ -0,0 +1,83 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+import { ToastrModule } from 'ngx-toastr';
+
+import { TableStatusViewCache } from '~/app/shared/classes/table-status-view-cache';
+import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
+import { ViewCacheStatus } from '~/app/shared/enum/view-cache-status.enum';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, PermissionHelper } from '~/testing/unit-test-helper';
+import { CephfsClientsComponent } from './cephfs-clients.component';
+
+describe('CephfsClientsComponent', () => {
+ let component: CephfsClientsComponent;
+ let fixture: ComponentFixture<CephfsClientsComponent>;
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ ToastrModule.forRoot(),
+ SharedModule,
+ HttpClientTestingModule
+ ],
+ declarations: [CephfsClientsComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CephfsClientsComponent);
+ component = fixture.componentInstance;
+ component.clients = {
+ status: new TableStatusViewCache(ViewCacheStatus.ValueOk),
+ data: [{}, {}, {}, {}]
+ };
+ });
+
+ it('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+
+ it('should test all TableActions combinations', () => {
+ const permissionHelper: PermissionHelper = new PermissionHelper(component.permission);
+ const tableActions: TableActionsComponent = permissionHelper.setPermissionsAndGetActions(
+ component.tableActions
+ );
+
+ expect(tableActions).toEqual({
+ 'create,update,delete': {
+ actions: ['Evict'],
+ primary: { multiple: 'Evict', executing: 'Evict', single: 'Evict', no: 'Evict' }
+ },
+ 'create,update': {
+ actions: ['Evict'],
+ primary: { multiple: 'Evict', executing: 'Evict', single: 'Evict', no: 'Evict' }
+ },
+ 'create,delete': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ },
+ create: {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ },
+ 'update,delete': {
+ actions: ['Evict'],
+ primary: { multiple: 'Evict', executing: 'Evict', single: 'Evict', no: 'Evict' }
+ },
+ update: {
+ actions: ['Evict'],
+ primary: { multiple: 'Evict', executing: 'Evict', single: 'Evict', no: 'Evict' }
+ },
+ delete: {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ },
+ 'no-permissions': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ }
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts
new file mode 100644
index 000000000..fb43cca4b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts
@@ -0,0 +1,102 @@
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+
+import { CephfsService } from '~/app/shared/api/cephfs.service';
+import { TableStatusViewCache } from '~/app/shared/classes/table-status-view-cache';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+
+@Component({
+ selector: 'cd-cephfs-clients',
+ templateUrl: './cephfs-clients.component.html',
+ styleUrls: ['./cephfs-clients.component.scss']
+})
+export class CephfsClientsComponent implements OnInit {
+ @Input()
+ id: number;
+
+ @Input()
+ clients: {
+ data: any[];
+ status: TableStatusViewCache;
+ };
+
+ @Output()
+ triggerApiUpdate = new EventEmitter();
+
+ columns: CdTableColumn[];
+
+ permission: Permission;
+ tableActions: CdTableAction[];
+ modalRef: NgbModalRef;
+
+ selection = new CdTableSelection();
+
+ constructor(
+ private cephfsService: CephfsService,
+ private modalService: ModalService,
+ private notificationService: NotificationService,
+ private authStorageService: AuthStorageService,
+ private actionLabels: ActionLabelsI18n
+ ) {
+ this.permission = this.authStorageService.getPermissions().cephfs;
+ const evictAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.signOut,
+ click: () => this.evictClientModal(),
+ name: this.actionLabels.EVICT
+ };
+ this.tableActions = [evictAction];
+ }
+
+ ngOnInit() {
+ this.columns = [
+ { prop: 'id', name: $localize`id` },
+ { prop: 'type', name: $localize`type` },
+ { prop: 'state', name: $localize`state` },
+ { prop: 'version', name: $localize`version` },
+ { prop: 'hostname', name: $localize`Host` },
+ { prop: 'root', name: $localize`root` }
+ ];
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ evictClient(clientId: number) {
+ this.cephfsService.evictClient(this.id, clientId).subscribe(
+ () => {
+ this.triggerApiUpdate.emit();
+ this.modalRef.close();
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Evicted client '${clientId}'`
+ );
+ },
+ () => {
+ this.modalRef.componentInstance.stopLoadingSpinner();
+ }
+ );
+ }
+
+ evictClientModal() {
+ const clientId = this.selection.first().id;
+ this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: 'client',
+ itemNames: [clientId],
+ actionDescription: 'evict',
+ submitAction: () => this.evictClient(clientId)
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html
new file mode 100644
index 000000000..c1d33d8e0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html
@@ -0,0 +1,42 @@
+<div class="row">
+ <div class="col-sm-6">
+ <legend i18n>Ranks</legend>
+ <cd-table [data]="data.ranks"
+ [columns]="columns.ranks"
+ [toolHeader]="false">
+ </cd-table>
+
+ <legend i18n>Standbys</legend>
+ <cd-table-key-value [data]="standbys">
+ </cd-table-key-value>
+ </div>
+
+ <div class="col-sm-6">
+ <legend i18n>Pools</legend>
+ <cd-table [data]="data.pools"
+ [columns]="columns.pools"
+ [toolHeader]="false">
+ </cd-table>
+ </div>
+</div>
+
+<legend i18n>MDS performance counters</legend>
+<div class="row"
+ *ngFor="let mdsCounter of objectValues(data.mdsCounters); trackBy: trackByFn">
+ <div class="col-md-12">
+ <cd-cephfs-chart [mdsCounter]="mdsCounter"></cd-cephfs-chart>
+ </div>
+</div>
+
+<!-- templates -->
+<ng-template #poolUsageTpl
+ let-row="row">
+ <cd-usage-bar [total]="row.size"
+ [used]="row.used"></cd-usage-bar>
+</ng-template>
+
+<ng-template #activityTmpl
+ let-row="row"
+ let-value="value">
+ {{ row.state === 'standby-replay' ? 'Evts' : 'Reqs' }}: {{ value | dimless }} /s
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.scss
new file mode 100644
index 000000000..d2b859af0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.scss
@@ -0,0 +1,3 @@
+.progress {
+ margin-bottom: 0;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.spec.ts
new file mode 100644
index 000000000..b62fce9d9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.spec.ts
@@ -0,0 +1,55 @@
+import { Component, Input } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { CephfsDetailComponent } from './cephfs-detail.component';
+
+@Component({ selector: 'cd-cephfs-chart', template: '' })
+class CephfsChartStubComponent {
+ @Input()
+ mdsCounter: any;
+}
+
+describe('CephfsDetailComponent', () => {
+ let component: CephfsDetailComponent;
+ let fixture: ComponentFixture<CephfsDetailComponent>;
+
+ const updateDetails = (
+ standbys: string,
+ pools: any[],
+ ranks: any[],
+ mdsCounters: object,
+ name: string
+ ) => {
+ component.data = {
+ standbys,
+ pools,
+ ranks,
+ mdsCounters,
+ name
+ };
+ fixture.detectChanges();
+ };
+
+ configureTestBed({
+ imports: [SharedModule],
+ declarations: [CephfsDetailComponent, CephfsChartStubComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CephfsDetailComponent);
+ component = fixture.componentInstance;
+ updateDetails('b', [], [], { a: { name: 'a', x: [0], y: [0, 1] } }, 'someFs');
+ fixture.detectChanges();
+ component.ngOnChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('prepares standby on change', () => {
+ expect(component.standbys).toEqual([{ key: 'Standby daemons', value: 'b' }]);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts
new file mode 100644
index 000000000..87985a049
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts
@@ -0,0 +1,91 @@
+import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { DimlessPipe } from '~/app/shared/pipes/dimless.pipe';
+
+@Component({
+ selector: 'cd-cephfs-detail',
+ templateUrl: './cephfs-detail.component.html',
+ styleUrls: ['./cephfs-detail.component.scss']
+})
+export class CephfsDetailComponent implements OnChanges, OnInit {
+ @ViewChild('poolUsageTpl', { static: true })
+ poolUsageTpl: TemplateRef<any>;
+ @ViewChild('activityTmpl', { static: true })
+ activityTmpl: TemplateRef<any>;
+
+ @Input()
+ data: {
+ standbys: string;
+ pools: any[];
+ ranks: any[];
+ mdsCounters: object;
+ name: string;
+ };
+
+ columns: {
+ ranks: CdTableColumn[];
+ pools: CdTableColumn[];
+ };
+ standbys: any[] = [];
+
+ objectValues = Object.values;
+
+ constructor(private dimlessBinary: DimlessBinaryPipe, private dimless: DimlessPipe) {}
+
+ ngOnChanges() {
+ this.setStandbys();
+ }
+
+ private setStandbys() {
+ this.standbys = [
+ {
+ key: $localize`Standby daemons`,
+ value: this.data.standbys
+ }
+ ];
+ }
+
+ ngOnInit() {
+ this.columns = {
+ ranks: [
+ { prop: 'rank', name: $localize`Rank` },
+ { prop: 'state', name: $localize`State` },
+ { prop: 'mds', name: $localize`Daemon` },
+ { prop: 'activity', name: $localize`Activity`, cellTemplate: this.activityTmpl },
+ { prop: 'dns', name: $localize`Dentries`, pipe: this.dimless },
+ { prop: 'inos', name: $localize`Inodes`, pipe: this.dimless },
+ { prop: 'dirs', name: $localize`Dirs`, pipe: this.dimless },
+ { prop: 'caps', name: $localize`Caps`, pipe: this.dimless }
+ ],
+ pools: [
+ { prop: 'pool', name: $localize`Pool` },
+ { prop: 'type', name: $localize`Type` },
+ { prop: 'size', name: $localize`Size`, pipe: this.dimlessBinary },
+ {
+ name: $localize`Usage`,
+ cellTemplate: this.poolUsageTpl,
+ comparator: (_valueA: any, _valueB: any, rowA: any, rowB: any) => {
+ const valA = rowA.used / rowA.avail;
+ const valB = rowB.used / rowB.avail;
+
+ if (valA === valB) {
+ return 0;
+ }
+
+ if (valA > valB) {
+ return 1;
+ } else {
+ return -1;
+ }
+ }
+ } as CdTableColumn
+ ]
+ };
+ }
+
+ trackByFn(_index: any, item: any) {
+ return item.name;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html
new file mode 100644
index 000000000..1d4b2ece8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html
@@ -0,0 +1,75 @@
+<div class="row">
+ <div class="col-sm-4 pr-0">
+ <div class="card">
+ <div class="card-header">
+ <button type="button"
+ [class.disabled]="loadingIndicator"
+ class="btn btn-light pull-right"
+ (click)="refreshAllDirectories()">
+ <i [ngClass]="[icons.large, icons.refresh]"
+ [class.fa-spin]="loadingIndicator"></i>
+ </button>
+ </div>
+ <div class="card-body">
+ <tree-root *ngIf="nodes"
+ [nodes]="nodes"
+ [options]="treeOptions">
+ <ng-template #loadingTemplate>
+ <i [ngClass]="[icons.spinner, icons.spin]"></i>
+ </ng-template>
+ </tree-root>
+ </div>
+ </div>
+ </div>
+ <!-- Selection details -->
+ <div class="col-sm-8 metadata"
+ *ngIf="selectedDir">
+ <div class="card">
+ <div class="card-header">
+ {{ selectedDir.path }}
+ </div>
+ <div class="card-body">
+ <ng-container *ngIf="selectedDir.path !== '/'">
+ <legend i18n>Quotas</legend>
+ <cd-table [data]="settings"
+ [columns]="quota.columns"
+ [limit]="0"
+ [footer]="false"
+ selectionType="single"
+ (updateSelection)="quota.updateSelection($event)"
+ [onlyActionHeader]="true"
+ identifier="quotaKey"
+ [forceIdentifier]="true"
+ [toolHeader]="false">
+ <cd-table-actions class="only-table-actions"
+ [permission]="permission"
+ [selection]="quota.selection"
+ [tableActions]="quota.tableActions">
+ </cd-table-actions>
+ </cd-table>
+ </ng-container>
+
+ <legend i18n>Snapshots</legend>
+ <cd-table [data]="selectedDir.snapshots"
+ [columns]="snapshot.columns"
+ identifier="name"
+ forceIdentifier="true"
+ selectionType="multiClick"
+ (updateSelection)="snapshot.updateSelection($event)">
+ <cd-table-actions class="table-actions"
+ [permission]="permission"
+ [selection]="snapshot.selection"
+ [tableActions]="snapshot.tableActions">
+ </cd-table-actions>
+ </cd-table>
+ </div>
+ </div>
+ </div>
+</div>
+
+<ng-template #origin
+ let-row="row"
+ let-value="value">
+ <span class="quota-origin"
+ (click)="selectOrigin(value)">{{value}}</span>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.scss
new file mode 100644
index 000000000..3334f0618
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.scss
@@ -0,0 +1,17 @@
+@use './src/styles/vendor/variables' as vv;
+
+// Angular2-Tree Component
+::ng-deep cd-cephfs-directories tree-root {
+ .tree-children {
+ overflow: inherit;
+ }
+}
+
+.quota-origin {
+ color: vv.$primary;
+ cursor: pointer;
+
+ &:hover {
+ color: vv.$gray-900;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.spec.ts
new file mode 100644
index 000000000..3a43ac5c7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.spec.ts
@@ -0,0 +1,1111 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { Type } from '@angular/core';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { Validators } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { TreeComponent, TreeModule, TREE_ACTIONS } from '@circlon/angular-tree-component';
+import { NgbActiveModal, NgbModalModule, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { Observable, of } from 'rxjs';
+
+import { CephfsService } from '~/app/shared/api/cephfs.service';
+import { ConfirmationModalComponent } from '~/app/shared/components/confirmation-modal/confirmation-modal.component';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { FormModalComponent } from '~/app/shared/components/form-modal/form-modal.component';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import {
+ CephfsDir,
+ CephfsQuotas,
+ CephfsSnapshot
+} from '~/app/shared/models/cephfs-directory-models';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, modalServiceShow, PermissionHelper } from '~/testing/unit-test-helper';
+import { CephfsDirectoriesComponent } from './cephfs-directories.component';
+
+describe('CephfsDirectoriesComponent', () => {
+ let component: CephfsDirectoriesComponent;
+ let fixture: ComponentFixture<CephfsDirectoriesComponent>;
+ let cephfsService: CephfsService;
+ let noAsyncUpdate: boolean;
+ let lsDirSpy: jasmine.Spy;
+ let modalShowSpy: jasmine.Spy;
+ let notificationShowSpy: jasmine.Spy;
+ let minValidator: jasmine.Spy;
+ let maxValidator: jasmine.Spy;
+ let minBinaryValidator: jasmine.Spy;
+ let maxBinaryValidator: jasmine.Spy;
+ let modal: NgbModalRef;
+
+ // Get's private attributes or functions
+ const get = {
+ nodeIds: (): { [path: string]: CephfsDir } => component['nodeIds'],
+ dirs: (): CephfsDir[] => component['dirs'],
+ requestedPaths: (): string[] => component['requestedPaths']
+ };
+
+ // Object contains mock data that will be reset before each test.
+ let mockData: {
+ nodes: any;
+ parent: any;
+ createdSnaps: CephfsSnapshot[] | any[];
+ deletedSnaps: CephfsSnapshot[] | any[];
+ updatedQuotas: { [path: string]: CephfsQuotas };
+ createdDirs: CephfsDir[];
+ };
+
+ // Object contains mock functions
+ const mockLib = {
+ quotas: (max_bytes: number, max_files: number): CephfsQuotas => ({ max_bytes, max_files }),
+ snapshots: (dirPath: string, howMany: number): CephfsSnapshot[] => {
+ const name = 'someSnapshot';
+ const snapshots = [];
+ const oneDay = 3600 * 24 * 1000;
+ for (let i = 0; i < howMany; i++) {
+ const snapName = `${name}${i + 1}`;
+ const path = `${dirPath}/.snap/${snapName}`;
+ const created = new Date(+new Date() - oneDay * i).toString();
+ snapshots.push({ name: snapName, path, created });
+ }
+ return snapshots;
+ },
+ dir: (parentPath: string, name: string, modifier: number): CephfsDir => {
+ const dirPath = `${parentPath === '/' ? '' : parentPath}/${name}`;
+ let snapshots = mockLib.snapshots(parentPath, modifier);
+ const extraSnapshots = mockData.createdSnaps.filter((s) => s.path === dirPath);
+ if (extraSnapshots.length > 0) {
+ snapshots = snapshots.concat(extraSnapshots);
+ }
+ const deletedSnapshots = mockData.deletedSnaps
+ .filter((s) => s.path === dirPath)
+ .map((s) => s.name);
+ if (deletedSnapshots.length > 0) {
+ snapshots = snapshots.filter((s) => !deletedSnapshots.includes(s.name));
+ }
+ return {
+ name,
+ path: dirPath,
+ parent: parentPath,
+ quotas: Object.assign(
+ mockLib.quotas(1024 * modifier, 10 * modifier),
+ mockData.updatedQuotas[dirPath] || {}
+ ),
+ snapshots: snapshots
+ };
+ },
+ // Only used inside other mocks
+ lsSingleDir: (path = ''): CephfsDir[] => {
+ const customDirs = mockData.createdDirs.filter((d) => d.parent === path);
+ const isCustomDir = mockData.createdDirs.some((d) => d.path === path);
+ if (isCustomDir || path.includes('b')) {
+ // 'b' has no sub directories
+ return customDirs;
+ }
+ return customDirs.concat([
+ // Directories are not sorted!
+ mockLib.dir(path, 'c', 3),
+ mockLib.dir(path, 'a', 1),
+ mockLib.dir(path, 'b', 2)
+ ]);
+ },
+ lsDir: (_id: number, path = ''): Observable<CephfsDir[]> => {
+ // will return 2 levels deep
+ let data = mockLib.lsSingleDir(path);
+ const paths = data.map((dir) => dir.path);
+ paths.forEach((pathL2) => {
+ data = data.concat(mockLib.lsSingleDir(pathL2));
+ });
+ if (path === '' || path === '/') {
+ // Adds root directory on ls of '/' to the directories list.
+ const root = mockLib.dir(path, '/', 1);
+ root.path = '/';
+ root.parent = undefined;
+ root.quotas = undefined;
+ data = [root].concat(data);
+ }
+ return of(data);
+ },
+ mkSnapshot: (_id: any, path: string, name: string): Observable<string> => {
+ mockData.createdSnaps.push({
+ name,
+ path,
+ created: new Date().toString()
+ });
+ return of(name);
+ },
+ rmSnapshot: (_id: any, path: string, name: string): Observable<string> => {
+ mockData.deletedSnaps.push({
+ name,
+ path,
+ created: new Date().toString()
+ });
+ return of(name);
+ },
+ updateQuota: (_id: any, path: string, updated: CephfsQuotas): Observable<string> => {
+ mockData.updatedQuotas[path] = Object.assign(mockData.updatedQuotas[path] || {}, updated);
+ return of('Response');
+ },
+ modalShow: (comp: Type<any>, init: any): any => {
+ modal = modalServiceShow(comp, init);
+ return modal;
+ },
+ getNodeById: (path: string) => {
+ return mockLib.useNode(path);
+ },
+ updateNodes: (path: string) => {
+ const p: Promise<any[]> = component.treeOptions.getChildren({ id: path });
+ return noAsyncUpdate ? () => p : mockLib.asyncNodeUpdate(p);
+ },
+ asyncNodeUpdate: fakeAsync((p: Promise<any[]>) => {
+ p.then((nodes) => {
+ mockData.nodes = mockData.nodes.concat(nodes);
+ });
+ tick();
+ }),
+ changeId: (id: number) => {
+ // For some reason this spy has to be renewed after usage
+ spyOn(global, 'setTimeout').and.callFake((fn) => fn());
+ component.id = id;
+ component.ngOnChanges();
+ mockData.nodes = component.nodes.concat(mockData.nodes);
+ },
+ selectNode: (path: string) => {
+ component.treeOptions.actionMapping.mouse.click(undefined, mockLib.useNode(path), undefined);
+ },
+ // Creates TreeNode with parents until root
+ useNode: (path: string): { id: string; parent: any; data: any; loadNodeChildren: Function } => {
+ const parentPath = path.split('/');
+ parentPath.pop();
+ const parentIsRoot = parentPath.length === 1;
+ const parent = parentIsRoot ? { id: '/' } : mockLib.useNode(parentPath.join('/'));
+ return {
+ id: path,
+ parent,
+ data: {},
+ loadNodeChildren: () => mockLib.updateNodes(path)
+ };
+ },
+ treeActions: {
+ toggleActive: (_a: any, node: any, _b: any) => {
+ return mockLib.updateNodes(node.id);
+ }
+ },
+ mkDir: (path: string, name: string, maxFiles: number, maxBytes: number) => {
+ const dir = mockLib.dir(path, name, 3);
+ dir.quotas.max_bytes = maxBytes * 1024;
+ dir.quotas.max_files = maxFiles;
+ mockData.createdDirs.push(dir);
+ // Below is needed for quota tests only where 4 dirs are mocked
+ get.nodeIds()[dir.path] = dir;
+ mockData.nodes.push({ id: dir.path });
+ },
+ createSnapshotThroughModal: (name: string) => {
+ component.createSnapshot();
+ modal.componentInstance.onSubmitForm({ name });
+ },
+ deleteSnapshotsThroughModal: (snapshots: CephfsSnapshot[]) => {
+ component.snapshot.selection.selected = snapshots;
+ component.deleteSnapshotModal();
+ modal.componentInstance.callSubmitAction();
+ },
+ updateQuotaThroughModal: (attribute: string, value: number) => {
+ component.quota.selection.selected = component.settings.filter(
+ (q) => q.quotaKey === attribute
+ );
+ component.updateQuotaModal();
+ modal.componentInstance.onSubmitForm({ [attribute]: value });
+ },
+ unsetQuotaThroughModal: (attribute: string) => {
+ component.quota.selection.selected = component.settings.filter(
+ (q) => q.quotaKey === attribute
+ );
+ component.unsetQuotaModal();
+ modal.componentInstance.onSubmit();
+ },
+ setFourQuotaDirs: (quotas: number[][]) => {
+ expect(quotas.length).toBe(4); // Make sure this function is used correctly
+ let path = '';
+ quotas.forEach((quota, index) => {
+ index += 1;
+ mockLib.mkDir(path === '' ? '/' : path, index.toString(), quota[0], quota[1]);
+ path += '/' + index;
+ });
+ mockData.parent = {
+ value: '3',
+ id: '/1/2/3',
+ parent: {
+ value: '2',
+ id: '/1/2',
+ parent: {
+ value: '1',
+ id: '/1',
+ parent: { value: '/', id: '/' }
+ }
+ }
+ };
+ mockLib.selectNode('/1/2/3/4');
+ }
+ };
+
+ // Expects that are used frequently
+ const assert = {
+ dirLength: (n: number) => expect(get.dirs().length).toBe(n),
+ nodeLength: (n: number) => expect(mockData.nodes.length).toBe(n),
+ lsDirCalledTimes: (n: number) => expect(lsDirSpy).toHaveBeenCalledTimes(n),
+ lsDirHasBeenCalledWith: (id: number, paths: string[]) => {
+ paths.forEach((path) => expect(lsDirSpy).toHaveBeenCalledWith(id, path));
+ assert.lsDirCalledTimes(paths.length);
+ },
+ requestedPaths: (expected: string[]) => expect(get.requestedPaths()).toEqual(expected),
+ snapshotsByName: (snaps: string[]) =>
+ expect(component.selectedDir.snapshots.map((s) => s.name)).toEqual(snaps),
+ dirQuotas: (bytes: number, files: number) => {
+ expect(component.selectedDir.quotas).toEqual({ max_bytes: bytes, max_files: files });
+ },
+ noQuota: (key: 'bytes' | 'files') => {
+ assert.quotaRow(key, '', 0, '');
+ },
+ quotaIsNotInherited: (key: 'bytes' | 'files', shownValue: any, nextMaximum: number) => {
+ const dir = component.selectedDir;
+ const path = dir.path;
+ assert.quotaRow(key, shownValue, nextMaximum, path);
+ },
+ quotaIsInherited: (key: 'bytes' | 'files', shownValue: any, path: string) => {
+ const isBytes = key === 'bytes';
+ const nextMaximum = get.nodeIds()[path].quotas[isBytes ? 'max_bytes' : 'max_files'];
+ assert.quotaRow(key, shownValue, nextMaximum, path);
+ },
+ quotaRow: (
+ key: 'bytes' | 'files',
+ shownValue: number | string,
+ nextTreeMaximum: number,
+ originPath: string
+ ) => {
+ const isBytes = key === 'bytes';
+ expect(component.settings[isBytes ? 1 : 0]).toEqual({
+ row: {
+ name: `Max ${isBytes ? 'size' : key}`,
+ value: shownValue,
+ originPath
+ },
+ quotaKey: `max_${key}`,
+ dirValue: expect.any(Number),
+ nextTreeMaximum: {
+ value: nextTreeMaximum,
+ path: expect.any(String)
+ }
+ });
+ },
+ quotaUnsetModalTexts: (titleText: string, message: string, notificationMsg: string) => {
+ expect(modalShowSpy).toHaveBeenCalledWith(
+ ConfirmationModalComponent,
+ expect.objectContaining({
+ titleText,
+ description: message,
+ buttonText: 'Unset'
+ })
+ );
+ expect(notificationShowSpy).toHaveBeenCalledWith(NotificationType.success, notificationMsg);
+ },
+ quotaUpdateModalTexts: (titleText: string, message: string, notificationMsg: string) => {
+ expect(modalShowSpy).toHaveBeenCalledWith(
+ FormModalComponent,
+ expect.objectContaining({
+ titleText,
+ message,
+ submitButtonText: 'Save'
+ })
+ );
+ expect(notificationShowSpy).toHaveBeenCalledWith(NotificationType.success, notificationMsg);
+ },
+ quotaUpdateModalField: (
+ type: string,
+ label: string,
+ key: string,
+ value: number,
+ max: number,
+ errors?: { [key: string]: string }
+ ) => {
+ expect(modalShowSpy).toHaveBeenCalledWith(
+ FormModalComponent,
+ expect.objectContaining({
+ fields: [
+ {
+ type,
+ label,
+ errors,
+ name: key,
+ value,
+ validators: expect.anything(),
+ required: true
+ }
+ ]
+ })
+ );
+ if (type === 'binary') {
+ expect(minBinaryValidator).toHaveBeenCalledWith(0);
+ expect(maxBinaryValidator).toHaveBeenCalledWith(max);
+ } else {
+ expect(minValidator).toHaveBeenCalledWith(0);
+ expect(maxValidator).toHaveBeenCalledWith(max);
+ }
+ }
+ };
+
+ configureTestBed(
+ {
+ imports: [
+ HttpClientTestingModule,
+ SharedModule,
+ RouterTestingModule,
+ TreeModule,
+ ToastrModule.forRoot(),
+ NgbModalModule
+ ],
+ declarations: [CephfsDirectoriesComponent],
+ providers: [NgbActiveModal]
+ },
+ [CriticalConfirmationModalComponent, FormModalComponent, ConfirmationModalComponent]
+ );
+
+ beforeEach(() => {
+ noAsyncUpdate = false;
+ mockData = {
+ nodes: [],
+ parent: undefined,
+ createdSnaps: [],
+ deletedSnaps: [],
+ createdDirs: [],
+ updatedQuotas: {}
+ };
+
+ cephfsService = TestBed.inject(CephfsService);
+ lsDirSpy = spyOn(cephfsService, 'lsDir').and.callFake(mockLib.lsDir);
+ spyOn(cephfsService, 'mkSnapshot').and.callFake(mockLib.mkSnapshot);
+ spyOn(cephfsService, 'rmSnapshot').and.callFake(mockLib.rmSnapshot);
+ spyOn(cephfsService, 'quota').and.callFake(mockLib.updateQuota);
+
+ modalShowSpy = spyOn(TestBed.inject(ModalService), 'show').and.callFake(mockLib.modalShow);
+ notificationShowSpy = spyOn(TestBed.inject(NotificationService), 'show').and.stub();
+
+ fixture = TestBed.createComponent(CephfsDirectoriesComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+
+ spyOn(TREE_ACTIONS, 'TOGGLE_ACTIVE').and.callFake(mockLib.treeActions.toggleActive);
+
+ component.treeComponent = {
+ sizeChanged: () => null,
+ treeModel: { getNodeById: mockLib.getNodeById, update: () => null }
+ } as TreeComponent;
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('mock self test', () => {
+ it('tests snapshots mock', () => {
+ expect(mockLib.snapshots('/a', 1).map((s) => ({ name: s.name, path: s.path }))).toEqual([
+ {
+ name: 'someSnapshot1',
+ path: '/a/.snap/someSnapshot1'
+ }
+ ]);
+ expect(mockLib.snapshots('/a/b', 3).map((s) => ({ name: s.name, path: s.path }))).toEqual([
+ {
+ name: 'someSnapshot1',
+ path: '/a/b/.snap/someSnapshot1'
+ },
+ {
+ name: 'someSnapshot2',
+ path: '/a/b/.snap/someSnapshot2'
+ },
+ {
+ name: 'someSnapshot3',
+ path: '/a/b/.snap/someSnapshot3'
+ }
+ ]);
+ });
+
+ it('tests dir mock', () => {
+ const path = '/a/b/c';
+ mockData.createdSnaps = [
+ { path, name: 's1' },
+ { path, name: 's2' }
+ ];
+ mockData.deletedSnaps = [
+ { path, name: 'someSnapshot2' },
+ { path, name: 's2' }
+ ];
+ const dir = mockLib.dir('/a/b', 'c', 2);
+ expect(dir.path).toBe('/a/b/c');
+ expect(dir.parent).toBe('/a/b');
+ expect(dir.quotas).toEqual({ max_bytes: 2048, max_files: 20 });
+ expect(dir.snapshots.map((s) => s.name)).toEqual(['someSnapshot1', 's1']);
+ });
+
+ it('tests lsdir mock', () => {
+ let dirs: CephfsDir[] = [];
+ mockLib.lsDir(2, '/a').subscribe((x) => (dirs = x));
+ expect(dirs.map((d) => d.path)).toEqual([
+ '/a/c',
+ '/a/a',
+ '/a/b',
+ '/a/c/c',
+ '/a/c/a',
+ '/a/c/b',
+ '/a/a/c',
+ '/a/a/a',
+ '/a/a/b'
+ ]);
+ });
+
+ describe('test quota update mock', () => {
+ const PATH = '/a';
+ const ID = 2;
+
+ const updateQuota = (quotas: CephfsQuotas) => mockLib.updateQuota(ID, PATH, quotas);
+
+ const expectMockUpdate = (max_bytes?: number, max_files?: number) =>
+ expect(mockData.updatedQuotas[PATH]).toEqual({
+ max_bytes,
+ max_files
+ });
+
+ const expectLsUpdate = (max_bytes?: number, max_files?: number) => {
+ let dir: CephfsDir;
+ mockLib.lsDir(ID, '/').subscribe((dirs) => (dir = dirs.find((d) => d.path === PATH)));
+ expect(dir.quotas).toEqual({
+ max_bytes,
+ max_files
+ });
+ };
+
+ it('tests to set quotas', () => {
+ expectLsUpdate(1024, 10);
+
+ updateQuota({ max_bytes: 512 });
+ expectMockUpdate(512);
+ expectLsUpdate(512, 10);
+
+ updateQuota({ max_files: 100 });
+ expectMockUpdate(512, 100);
+ expectLsUpdate(512, 100);
+ });
+
+ it('tests to unset quotas', () => {
+ updateQuota({ max_files: 0 });
+ expectMockUpdate(undefined, 0);
+ expectLsUpdate(1024, 0);
+
+ updateQuota({ max_bytes: 0 });
+ expectMockUpdate(0, 0);
+ expectLsUpdate(0, 0);
+ });
+ });
+ });
+
+ it('calls lsDir only if an id exits', () => {
+ assert.lsDirCalledTimes(0);
+
+ mockLib.changeId(1);
+ assert.lsDirCalledTimes(1);
+ expect(lsDirSpy).toHaveBeenCalledWith(1, '/');
+
+ mockLib.changeId(2);
+ assert.lsDirCalledTimes(2);
+ expect(lsDirSpy).toHaveBeenCalledWith(2, '/');
+ });
+
+ describe('listing sub directories', () => {
+ beforeEach(() => {
+ mockLib.changeId(1);
+ /**
+ * Tree looks like this:
+ * v /
+ * > a
+ * * b
+ * > c
+ * */
+ });
+
+ it('expands first level', () => {
+ // Tree will only show '*' if nor 'loadChildren' or 'children' are defined
+ expect(
+ mockData.nodes.map((node: any) => ({
+ [node.id]: node.hasChildren || node.isExpanded || Boolean(node.children)
+ }))
+ ).toEqual([{ '/': true }, { '/a': true }, { '/b': false }, { '/c': true }]);
+ });
+
+ it('resets all dynamic content on id change', () => {
+ mockLib.selectNode('/a');
+ /**
+ * Tree looks like this:
+ * v /
+ * v a <- Selected
+ * > a
+ * * b
+ * > c
+ * * b
+ * > c
+ * */
+ assert.requestedPaths(['/', '/a']);
+ assert.nodeLength(7);
+ assert.dirLength(16);
+ expect(component.selectedDir).toBeDefined();
+
+ mockLib.changeId(undefined);
+ assert.dirLength(0);
+ assert.requestedPaths([]);
+ expect(component.selectedDir).not.toBeDefined();
+ });
+
+ it('should select a node and show the directory contents', () => {
+ mockLib.selectNode('/a');
+ const dir = get.dirs().find((d) => d.path === '/a');
+ expect(component.selectedDir).toEqual(dir);
+ assert.quotaIsNotInherited('files', 10, 0);
+ assert.quotaIsNotInherited('bytes', '1 KiB', 0);
+ });
+
+ it('should extend the list by subdirectories when expanding', () => {
+ mockLib.selectNode('/a');
+ mockLib.selectNode('/a/c');
+ /**
+ * Tree looks like this:
+ * v /
+ * v a
+ * > a
+ * * b
+ * v c <- Selected
+ * > a
+ * * b
+ * > c
+ * * b
+ * > c
+ * */
+ assert.lsDirCalledTimes(3);
+ assert.requestedPaths(['/', '/a', '/a/c']);
+ assert.dirLength(22);
+ assert.nodeLength(10);
+ });
+
+ it('should update the tree after each selection', () => {
+ const spy = spyOn(component.treeComponent, 'sizeChanged').and.callThrough();
+ expect(spy).toHaveBeenCalledTimes(0);
+ mockLib.selectNode('/a');
+ expect(spy).toHaveBeenCalledTimes(1);
+ mockLib.selectNode('/a/c');
+ expect(spy).toHaveBeenCalledTimes(2);
+ });
+
+ it('should select parent by path', () => {
+ mockLib.selectNode('/a');
+ mockLib.selectNode('/a/c');
+ mockLib.selectNode('/a/c/a');
+ component.selectOrigin('/a');
+ expect(component.selectedDir.path).toBe('/a');
+ });
+
+ it('should refresh directories with no sub directories as they could have some now', () => {
+ mockLib.selectNode('/b');
+ /**
+ * Tree looks like this:
+ * v /
+ * > a
+ * * b <- Selected
+ * > c
+ * */
+ assert.lsDirCalledTimes(2);
+ assert.requestedPaths(['/', '/b']);
+ assert.nodeLength(4);
+ });
+
+ describe('used quotas', () => {
+ it('should use no quota if none is set', () => {
+ mockLib.setFourQuotaDirs([
+ [0, 0],
+ [0, 0],
+ [0, 0],
+ [0, 0]
+ ]);
+ assert.noQuota('files');
+ assert.noQuota('bytes');
+ assert.dirQuotas(0, 0);
+ });
+
+ it('should use quota from upper parents', () => {
+ mockLib.setFourQuotaDirs([
+ [100, 0],
+ [0, 8],
+ [0, 0],
+ [0, 0]
+ ]);
+ assert.quotaIsInherited('files', 100, '/1');
+ assert.quotaIsInherited('bytes', '8 KiB', '/1/2');
+ assert.dirQuotas(0, 0);
+ });
+
+ it('should use quota from the parent with the lowest value (deep inheritance)', () => {
+ mockLib.setFourQuotaDirs([
+ [200, 1],
+ [100, 4],
+ [400, 3],
+ [300, 2]
+ ]);
+ assert.quotaIsInherited('files', 100, '/1/2');
+ assert.quotaIsInherited('bytes', '1 KiB', '/1');
+ assert.dirQuotas(2048, 300);
+ });
+
+ it('should use current value', () => {
+ mockLib.setFourQuotaDirs([
+ [200, 2],
+ [300, 4],
+ [400, 3],
+ [100, 1]
+ ]);
+ assert.quotaIsNotInherited('files', 100, 200);
+ assert.quotaIsNotInherited('bytes', '1 KiB', 2048);
+ assert.dirQuotas(1024, 100);
+ });
+ });
+ });
+
+ describe('snapshots', () => {
+ beforeEach(() => {
+ mockLib.changeId(1);
+ mockLib.selectNode('/a');
+ });
+
+ it('should create a snapshot', () => {
+ mockLib.createSnapshotThroughModal('newSnap');
+ expect(cephfsService.mkSnapshot).toHaveBeenCalledWith(1, '/a', 'newSnap');
+ assert.snapshotsByName(['someSnapshot1', 'newSnap']);
+ });
+
+ it('should delete a snapshot', () => {
+ mockLib.createSnapshotThroughModal('deleteMe');
+ mockLib.deleteSnapshotsThroughModal([component.selectedDir.snapshots[1]]);
+ assert.snapshotsByName(['someSnapshot1']);
+ });
+
+ it('should delete all snapshots', () => {
+ mockLib.createSnapshotThroughModal('deleteAll');
+ mockLib.deleteSnapshotsThroughModal(component.selectedDir.snapshots);
+ assert.snapshotsByName([]);
+ });
+ });
+
+ it('should test all snapshot table actions combinations', () => {
+ const permissionHelper: PermissionHelper = new PermissionHelper(component.permission);
+ const tableActions = permissionHelper.setPermissionsAndGetActions(
+ component.snapshot.tableActions
+ );
+
+ expect(tableActions).toEqual({
+ 'create,update,delete': {
+ actions: ['Create', 'Delete'],
+ primary: { multiple: 'Delete', executing: 'Delete', single: 'Delete', no: 'Create' }
+ },
+ 'create,update': {
+ actions: ['Create'],
+ primary: { multiple: 'Create', executing: 'Create', single: 'Create', no: 'Create' }
+ },
+ 'create,delete': {
+ actions: ['Create', 'Delete'],
+ primary: { multiple: 'Delete', executing: 'Delete', single: 'Delete', no: 'Create' }
+ },
+ create: {
+ actions: ['Create'],
+ primary: { multiple: 'Create', executing: 'Create', single: 'Create', no: 'Create' }
+ },
+ 'update,delete': {
+ actions: ['Delete'],
+ primary: { multiple: 'Delete', executing: 'Delete', single: 'Delete', no: 'Delete' }
+ },
+ update: {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ },
+ delete: {
+ actions: ['Delete'],
+ primary: { multiple: 'Delete', executing: 'Delete', single: 'Delete', no: 'Delete' }
+ },
+ 'no-permissions': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ }
+ });
+ });
+
+ describe('quotas', () => {
+ beforeEach(() => {
+ // Spies
+ minValidator = spyOn(Validators, 'min').and.callThrough();
+ maxValidator = spyOn(Validators, 'max').and.callThrough();
+ minBinaryValidator = spyOn(CdValidators, 'binaryMin').and.callThrough();
+ maxBinaryValidator = spyOn(CdValidators, 'binaryMax').and.callThrough();
+ // Select /a/c/b
+ mockLib.changeId(1);
+ mockLib.selectNode('/a');
+ mockLib.selectNode('/a/c');
+ mockLib.selectNode('/a/c/b');
+ // Quotas after selection
+ assert.quotaIsInherited('files', 10, '/a');
+ assert.quotaIsInherited('bytes', '1 KiB', '/a');
+ assert.dirQuotas(2048, 20);
+ });
+
+ describe('update modal', () => {
+ describe('max_files', () => {
+ beforeEach(() => {
+ mockLib.updateQuotaThroughModal('max_files', 5);
+ });
+
+ it('should update max_files correctly', () => {
+ expect(cephfsService.quota).toHaveBeenCalledWith(1, '/a/c/b', { max_files: 5 });
+ assert.quotaIsNotInherited('files', 5, 10);
+ });
+
+ it('uses the correct form field', () => {
+ assert.quotaUpdateModalField('number', 'Max files', 'max_files', 20, 10, {
+ min: 'Value has to be at least 0 or more',
+ max: 'Value has to be at most 10 or less'
+ });
+ });
+
+ it('shows the right texts', () => {
+ assert.quotaUpdateModalTexts(
+ `Update CephFS files quota for '/a/c/b'`,
+ `The inherited files quota 10 from '/a' is the maximum value to be used.`,
+ `Updated CephFS files quota for '/a/c/b'`
+ );
+ });
+ });
+
+ describe('max_bytes', () => {
+ beforeEach(() => {
+ mockLib.updateQuotaThroughModal('max_bytes', 512);
+ });
+
+ it('should update max_files correctly', () => {
+ expect(cephfsService.quota).toHaveBeenCalledWith(1, '/a/c/b', { max_bytes: 512 });
+ assert.quotaIsNotInherited('bytes', '512 B', 1024);
+ });
+
+ it('uses the correct form field', () => {
+ mockLib.updateQuotaThroughModal('max_bytes', 512);
+ assert.quotaUpdateModalField('binary', 'Max size', 'max_bytes', 2048, 1024);
+ });
+
+ it('shows the right texts', () => {
+ assert.quotaUpdateModalTexts(
+ `Update CephFS size quota for '/a/c/b'`,
+ `The inherited size quota 1 KiB from '/a' is the maximum value to be used.`,
+ `Updated CephFS size quota for '/a/c/b'`
+ );
+ });
+ });
+
+ describe('action behaviour', () => {
+ it('opens with next maximum as maximum if directory holds the current maximum', () => {
+ mockLib.updateQuotaThroughModal('max_bytes', 512);
+ mockLib.updateQuotaThroughModal('max_bytes', 888);
+ assert.quotaUpdateModalField('binary', 'Max size', 'max_bytes', 512, 1024);
+ });
+
+ it(`uses 'Set' action instead of 'Update' if the quota is not set (0)`, () => {
+ mockLib.updateQuotaThroughModal('max_bytes', 0);
+ mockLib.updateQuotaThroughModal('max_bytes', 200);
+ assert.quotaUpdateModalTexts(
+ `Set CephFS size quota for '/a/c/b'`,
+ `The inherited size quota 1 KiB from '/a' is the maximum value to be used.`,
+ `Set CephFS size quota for '/a/c/b'`
+ );
+ });
+ });
+ });
+
+ describe('unset modal', () => {
+ describe('max_files', () => {
+ beforeEach(() => {
+ mockLib.updateQuotaThroughModal('max_files', 5); // Sets usable quota
+ mockLib.unsetQuotaThroughModal('max_files');
+ });
+
+ it('should unset max_files correctly', () => {
+ expect(cephfsService.quota).toHaveBeenCalledWith(1, '/a/c/b', { max_files: 0 });
+ assert.dirQuotas(2048, 0);
+ });
+
+ it('shows the right texts', () => {
+ assert.quotaUnsetModalTexts(
+ `Unset CephFS files quota for '/a/c/b'`,
+ `Unset files quota 5 from '/a/c/b' in order to inherit files quota 10 from '/a'.`,
+ `Unset CephFS files quota for '/a/c/b'`
+ );
+ });
+ });
+
+ describe('max_bytes', () => {
+ beforeEach(() => {
+ mockLib.updateQuotaThroughModal('max_bytes', 512); // Sets usable quota
+ mockLib.unsetQuotaThroughModal('max_bytes');
+ });
+
+ it('should unset max_files correctly', () => {
+ expect(cephfsService.quota).toHaveBeenCalledWith(1, '/a/c/b', { max_bytes: 0 });
+ assert.dirQuotas(0, 20);
+ });
+
+ it('shows the right texts', () => {
+ assert.quotaUnsetModalTexts(
+ `Unset CephFS size quota for '/a/c/b'`,
+ `Unset size quota 512 B from '/a/c/b' in order to inherit size quota 1 KiB from '/a'.`,
+ `Unset CephFS size quota for '/a/c/b'`
+ );
+ });
+ });
+
+ describe('action behaviour', () => {
+ it('uses different Text if no quota is inherited', () => {
+ mockLib.selectNode('/a');
+ mockLib.unsetQuotaThroughModal('max_bytes');
+ assert.quotaUnsetModalTexts(
+ `Unset CephFS size quota for '/a'`,
+ `Unset size quota 1 KiB from '/a' in order to have no quota on the directory.`,
+ `Unset CephFS size quota for '/a'`
+ );
+ });
+
+ it('uses different Text if quota is already inherited', () => {
+ mockLib.unsetQuotaThroughModal('max_bytes');
+ assert.quotaUnsetModalTexts(
+ `Unset CephFS size quota for '/a/c/b'`,
+ `Unset size quota 2 KiB from '/a/c/b' which isn't used because of the inheritance ` +
+ `of size quota 1 KiB from '/a'.`,
+ `Unset CephFS size quota for '/a/c/b'`
+ );
+ });
+ });
+ });
+ });
+
+ describe('table actions', () => {
+ let actions: CdTableAction[];
+
+ const empty = (): CdTableSelection => new CdTableSelection();
+
+ const select = (value: number): CdTableSelection => {
+ const selection = new CdTableSelection();
+ selection.selected = [{ dirValue: value }];
+ return selection;
+ };
+
+ beforeEach(() => {
+ actions = component.quota.tableActions;
+ });
+
+ it(`shows 'Set' for empty and not set quotas`, () => {
+ const isSetVisible = actions[0].visible;
+ expect(isSetVisible(empty())).toBe(true);
+ expect(isSetVisible(select(0))).toBe(true);
+ expect(isSetVisible(select(1))).toBe(false);
+ });
+
+ it(`shows 'Update' for set quotas only`, () => {
+ const isUpdateVisible = actions[1].visible;
+ expect(isUpdateVisible(empty())).toBeFalsy();
+ expect(isUpdateVisible(select(0))).toBe(false);
+ expect(isUpdateVisible(select(1))).toBe(true);
+ });
+
+ it(`only enables 'Unset' for set quotas only`, () => {
+ const isUnsetDisabled = actions[2].disable;
+ expect(isUnsetDisabled(empty())).toBe(true);
+ expect(isUnsetDisabled(select(0))).toBe(true);
+ expect(isUnsetDisabled(select(1))).toBe(false);
+ });
+
+ it('should test all quota table actions permission combinations', () => {
+ const permissionHelper: PermissionHelper = new PermissionHelper(component.permission, {
+ single: { dirValue: 0 },
+ multiple: [{ dirValue: 0 }, {}]
+ });
+ const tableActions = permissionHelper.setPermissionsAndGetActions(
+ component.quota.tableActions
+ );
+
+ expect(tableActions).toEqual({
+ 'create,update,delete': {
+ actions: ['Set', 'Update', 'Unset'],
+ primary: { multiple: 'Set', executing: 'Set', single: 'Set', no: 'Set' }
+ },
+ 'create,update': {
+ actions: ['Set', 'Update', 'Unset'],
+ primary: { multiple: 'Set', executing: 'Set', single: 'Set', no: 'Set' }
+ },
+ 'create,delete': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ },
+ create: {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ },
+ 'update,delete': {
+ actions: ['Set', 'Update', 'Unset'],
+ primary: { multiple: 'Set', executing: 'Set', single: 'Set', no: 'Set' }
+ },
+ update: {
+ actions: ['Set', 'Update', 'Unset'],
+ primary: { multiple: 'Set', executing: 'Set', single: 'Set', no: 'Set' }
+ },
+ delete: {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ },
+ 'no-permissions': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ }
+ });
+ });
+ });
+
+ describe('reload all', () => {
+ const calledPaths = ['/', '/a', '/a/c', '/a/c/a', '/a/c/a/b'];
+
+ const dirsByPath = (): string[] => get.dirs().map((d) => d.path);
+
+ beforeEach(() => {
+ mockLib.changeId(1);
+ mockLib.selectNode('/a');
+ mockLib.selectNode('/a/c');
+ mockLib.selectNode('/a/c/a');
+ mockLib.selectNode('/a/c/a/b');
+ });
+
+ it('should reload all requested paths', () => {
+ assert.lsDirHasBeenCalledWith(1, calledPaths);
+ lsDirSpy.calls.reset();
+ assert.lsDirHasBeenCalledWith(1, []);
+ component.refreshAllDirectories();
+ assert.lsDirHasBeenCalledWith(1, calledPaths);
+ });
+
+ it('should reload all requested paths if not selected anything', () => {
+ lsDirSpy.calls.reset();
+ mockLib.changeId(2);
+ assert.lsDirHasBeenCalledWith(2, ['/']);
+ lsDirSpy.calls.reset();
+ component.refreshAllDirectories();
+ assert.lsDirHasBeenCalledWith(2, ['/']);
+ });
+
+ it('should add new directories', () => {
+ // Create two new directories in preparation
+ const dirsBeforeRefresh = dirsByPath();
+ expect(dirsBeforeRefresh.includes('/a/c/has_dir_now')).toBe(false);
+ mockLib.mkDir('/a/c', 'has_dir_now', 0, 0);
+ mockLib.mkDir('/a/c/a/b', 'has_dir_now_too', 0, 0);
+ // Now the new directories will be fetched
+ component.refreshAllDirectories();
+ const dirsAfterRefresh = dirsByPath();
+ expect(dirsAfterRefresh.length - dirsBeforeRefresh.length).toBe(2);
+ expect(dirsAfterRefresh.includes('/a/c/has_dir_now')).toBe(true);
+ expect(dirsAfterRefresh.includes('/a/c/a/b/has_dir_now_too')).toBe(true);
+ });
+
+ it('should remove deleted directories', () => {
+ // Create one new directory and refresh in order to have it added to the directories list
+ mockLib.mkDir('/a/c', 'will_be_removed_shortly', 0, 0);
+ component.refreshAllDirectories();
+ const dirsBeforeRefresh = dirsByPath();
+ expect(dirsBeforeRefresh.includes('/a/c/will_be_removed_shortly')).toBe(true);
+ mockData.createdDirs = []; // Mocks the deletion of the directory
+ // Now the deleted directory will be missing on refresh
+ component.refreshAllDirectories();
+ const dirsAfterRefresh = dirsByPath();
+ expect(dirsAfterRefresh.length - dirsBeforeRefresh.length).toBe(-1);
+ expect(dirsAfterRefresh.includes('/a/c/will_be_removed_shortly')).toBe(false);
+ });
+
+ describe('loading indicator', () => {
+ beforeEach(() => {
+ noAsyncUpdate = true;
+ });
+
+ it('should have set loading indicator to false after refreshing all dirs', fakeAsync(() => {
+ component.refreshAllDirectories();
+ expect(component.loadingIndicator).toBe(true);
+ tick(3000); // To resolve all promises
+ expect(component.loadingIndicator).toBe(false);
+ }));
+
+ it('should only update the tree once and not on every call', fakeAsync(() => {
+ const spy = spyOn(component.treeComponent, 'sizeChanged').and.callThrough();
+ component.refreshAllDirectories();
+ expect(spy).toHaveBeenCalledTimes(0);
+ tick(3000); // To resolve all promises
+ // Called during the interval and at the end of timeout
+ expect(spy).toHaveBeenCalledTimes(2);
+ }));
+
+ it('should have set all loaded dirs as attribute names of "indicators"', () => {
+ noAsyncUpdate = false;
+ component.refreshAllDirectories();
+ expect(Object.keys(component.loading).sort()).toEqual(calledPaths);
+ });
+
+ it('should set an indicator to true during load', () => {
+ lsDirSpy.and.callFake(() => new Observable((): null => null));
+ component.refreshAllDirectories();
+ expect(Object.values(component.loading).every((b) => b)).toBe(true);
+ expect(component.loadingIndicator).toBe(true);
+ });
+ });
+ describe('disable create snapshot', () => {
+ let actions: CdTableAction[];
+ beforeEach(() => {
+ actions = component.snapshot.tableActions;
+ mockLib.mkDir('/', 'volumes', 2, 2);
+ mockLib.mkDir('/volumes', 'group1', 2, 2);
+ mockLib.mkDir('/volumes/group1', 'subvol', 2, 2);
+ mockLib.mkDir('/volumes/group1/subvol', 'subfile', 2, 2);
+ });
+
+ const empty = (): CdTableSelection => new CdTableSelection();
+
+ it('should return a descriptive message to explain why it is disabled', () => {
+ const path = '/volumes/group1/subvol/subfile';
+ const res = 'Cannot create snapshots for files/folders in the subvolume subvol';
+ mockLib.selectNode(path);
+ expect(actions[0].disable(empty())).toContain(res);
+ });
+
+ it('should return false if it is not a subvolume node', () => {
+ const testCases = [
+ '/volumes/group1/subvol',
+ '/volumes/group1',
+ '/volumes',
+ '/',
+ '/a',
+ '/a/b'
+ ];
+ testCases.forEach((testCase) => {
+ mockLib.selectNode(testCase);
+ expect(actions[0].disable(empty())).toBeFalsy();
+ });
+ });
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts
new file mode 100644
index 000000000..4ae8a159a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts
@@ -0,0 +1,733 @@
+import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
+import { AbstractControl, Validators } from '@angular/forms';
+
+import {
+ ITreeOptions,
+ TreeComponent,
+ TreeModel,
+ TreeNode,
+ TREE_ACTIONS
+} from '@circlon/angular-tree-component';
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import moment from 'moment';
+
+import { CephfsService } from '~/app/shared/api/cephfs.service';
+import { ConfirmationModalComponent } from '~/app/shared/components/confirmation-modal/confirmation-modal.component';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { FormModalComponent } from '~/app/shared/components/form-modal/form-modal.component';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { CdFormModalFieldConfig } from '~/app/shared/models/cd-form-modal-field-config';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import {
+ CephfsDir,
+ CephfsQuotas,
+ CephfsSnapshot
+} from '~/app/shared/models/cephfs-directory-models';
+import { Permission } from '~/app/shared/models/permissions';
+import { CdDatePipe } from '~/app/shared/pipes/cd-date.pipe';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+
+class QuotaSetting {
+ row: {
+ // Used in quota table
+ name: string;
+ value: number | string;
+ originPath: string;
+ };
+ quotaKey: string;
+ dirValue: number;
+ nextTreeMaximum: {
+ value: number;
+ path: string;
+ };
+}
+
+@Component({
+ selector: 'cd-cephfs-directories',
+ templateUrl: './cephfs-directories.component.html',
+ styleUrls: ['./cephfs-directories.component.scss']
+})
+export class CephfsDirectoriesComponent implements OnInit, OnChanges {
+ @ViewChild(TreeComponent)
+ treeComponent: TreeComponent;
+ @ViewChild('origin', { static: true })
+ originTmpl: TemplateRef<any>;
+
+ @Input()
+ id: number;
+
+ private modalRef: NgbModalRef;
+ private dirs: CephfsDir[];
+ private nodeIds: { [path: string]: CephfsDir };
+ private requestedPaths: string[];
+ private loadingTimeout: any;
+
+ icons = Icons;
+ loadingIndicator = false;
+ loading = {};
+ treeOptions: ITreeOptions = {
+ useVirtualScroll: true,
+ getChildren: (node: TreeNode): Promise<any[]> => {
+ return this.updateDirectory(node.id);
+ },
+ actionMapping: {
+ mouse: {
+ click: this.selectAndShowNode.bind(this),
+ expanderClick: this.selectAndShowNode.bind(this)
+ }
+ }
+ };
+
+ permission: Permission;
+ selectedDir: CephfsDir;
+ settings: QuotaSetting[];
+ quota: {
+ columns: CdTableColumn[];
+ selection: CdTableSelection;
+ tableActions: CdTableAction[];
+ updateSelection: Function;
+ };
+ snapshot: {
+ columns: CdTableColumn[];
+ selection: CdTableSelection;
+ tableActions: CdTableAction[];
+ updateSelection: Function;
+ };
+ nodes: any[];
+ alreadyExists: boolean;
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private modalService: ModalService,
+ private cephfsService: CephfsService,
+ private cdDatePipe: CdDatePipe,
+ private actionLabels: ActionLabelsI18n,
+ private notificationService: NotificationService,
+ private dimlessBinaryPipe: DimlessBinaryPipe
+ ) {}
+
+ private selectAndShowNode(tree: TreeModel, node: TreeNode, $event: any) {
+ TREE_ACTIONS.TOGGLE_EXPANDED(tree, node, $event);
+ this.selectNode(node);
+ }
+
+ private selectNode(node: TreeNode) {
+ TREE_ACTIONS.TOGGLE_ACTIVE(undefined, node, undefined);
+ this.selectedDir = this.getDirectory(node);
+ if (node.id === '/') {
+ return;
+ }
+ this.setSettings(node);
+ }
+
+ ngOnInit() {
+ this.permission = this.authStorageService.getPermissions().cephfs;
+ this.setUpQuotaTable();
+ this.setUpSnapshotTable();
+ }
+
+ private setUpQuotaTable() {
+ this.quota = {
+ columns: [
+ {
+ prop: 'row.name',
+ name: $localize`Name`,
+ flexGrow: 1
+ },
+ {
+ prop: 'row.value',
+ name: $localize`Value`,
+ sortable: false,
+ flexGrow: 1
+ },
+ {
+ prop: 'row.originPath',
+ name: $localize`Origin`,
+ sortable: false,
+ cellTemplate: this.originTmpl,
+ flexGrow: 1
+ }
+ ],
+ selection: new CdTableSelection(),
+ updateSelection: (selection: CdTableSelection) => {
+ this.quota.selection = selection;
+ },
+ tableActions: [
+ {
+ name: this.actionLabels.SET,
+ icon: Icons.edit,
+ permission: 'update',
+ visible: (selection) =>
+ !selection.hasSelection || (selection.first() && selection.first().dirValue === 0),
+ click: () => this.updateQuotaModal()
+ },
+ {
+ name: this.actionLabels.UPDATE,
+ icon: Icons.edit,
+ permission: 'update',
+ visible: (selection) => selection.first() && selection.first().dirValue > 0,
+ click: () => this.updateQuotaModal()
+ },
+ {
+ name: this.actionLabels.UNSET,
+ icon: Icons.destroy,
+ permission: 'update',
+ disable: (selection) =>
+ !selection.hasSelection || (selection.first() && selection.first().dirValue === 0),
+ click: () => this.unsetQuotaModal()
+ }
+ ]
+ };
+ }
+
+ private setUpSnapshotTable() {
+ this.snapshot = {
+ columns: [
+ {
+ prop: 'name',
+ name: $localize`Name`,
+ flexGrow: 1
+ },
+ {
+ prop: 'path',
+ name: $localize`Path`,
+ isHidden: true,
+ flexGrow: 2
+ },
+ {
+ prop: 'created',
+ name: $localize`Created`,
+ flexGrow: 1,
+ pipe: this.cdDatePipe
+ }
+ ],
+ selection: new CdTableSelection(),
+ updateSelection: (selection: CdTableSelection) => {
+ this.snapshot.selection = selection;
+ },
+ tableActions: [
+ {
+ name: this.actionLabels.CREATE,
+ icon: Icons.add,
+ permission: 'create',
+ canBePrimary: (selection) => !selection.hasSelection,
+ click: () => this.createSnapshot(),
+ disable: () => this.disableCreateSnapshot()
+ },
+ {
+ name: this.actionLabels.DELETE,
+ icon: Icons.destroy,
+ permission: 'delete',
+ click: () => this.deleteSnapshotModal(),
+ canBePrimary: (selection) => selection.hasSelection,
+ disable: (selection) => !selection.hasSelection
+ }
+ ]
+ };
+ }
+
+ private disableCreateSnapshot(): string | boolean {
+ const folders = this.selectedDir.path.split('/').slice(1);
+ // With deph of 4 or more we have the subvolume files/folders for which we cannot create
+ // a snapshot. Somehow, you can create a snapshot of the subvolume but not its files.
+ if (folders.length >= 4 && folders[0] === 'volumes') {
+ return $localize`Cannot create snapshots for files/folders in the subvolume ${folders[2]}`;
+ }
+ return false;
+ }
+
+ ngOnChanges() {
+ this.selectedDir = undefined;
+ this.dirs = [];
+ this.requestedPaths = [];
+ this.nodeIds = {};
+ if (this.id) {
+ this.setRootNode();
+ this.firstCall();
+ }
+ }
+
+ private setRootNode() {
+ this.nodes = [
+ {
+ name: '/',
+ id: '/',
+ isExpanded: true
+ }
+ ];
+ }
+
+ private firstCall() {
+ const path = '/';
+ setTimeout(() => {
+ this.getNode(path).loadNodeChildren();
+ }, 10);
+ }
+
+ updateDirectory(path: string): Promise<any[]> {
+ this.unsetLoadingIndicator();
+ if (!this.requestedPaths.includes(path)) {
+ this.requestedPaths.push(path);
+ } else if (this.loading[path] === true) {
+ return undefined; // Path is currently fetched.
+ }
+ return new Promise((resolve) => {
+ this.setLoadingIndicator(path, true);
+ this.cephfsService.lsDir(this.id, path).subscribe((dirs) => {
+ this.updateTreeStructure(dirs);
+ this.updateQuotaTable();
+ this.updateTree();
+ resolve(this.getChildren(path));
+ this.setLoadingIndicator(path, false);
+ });
+ });
+ }
+
+ private setLoadingIndicator(path: string, loading: boolean) {
+ this.loading[path] = loading;
+ this.unsetLoadingIndicator();
+ }
+
+ private getSubDirectories(path: string, tree: CephfsDir[] = this.dirs): CephfsDir[] {
+ return tree.filter((d) => d.parent === path);
+ }
+
+ private getChildren(path: string): any[] {
+ const subTree = this.getSubTree(path);
+ return _.sortBy(this.getSubDirectories(path), 'path').map((dir) =>
+ this.createNode(dir, subTree)
+ );
+ }
+
+ private createNode(dir: CephfsDir, subTree?: CephfsDir[]): any {
+ this.nodeIds[dir.path] = dir;
+ if (!subTree) {
+ this.getSubTree(dir.parent);
+ }
+ return {
+ name: dir.name,
+ id: dir.path,
+ hasChildren: this.getSubDirectories(dir.path, subTree).length > 0
+ };
+ }
+
+ private getSubTree(path: string): CephfsDir[] {
+ return this.dirs.filter((d) => d.parent && d.parent.startsWith(path));
+ }
+
+ private setSettings(node: TreeNode) {
+ const readable = (value: number, fn?: (arg0: number) => number | string): number | string =>
+ value ? (fn ? fn(value) : value) : '';
+
+ this.settings = [
+ this.getQuota(node, 'max_files', readable),
+ this.getQuota(node, 'max_bytes', (value) =>
+ readable(value, (v) => this.dimlessBinaryPipe.transform(v))
+ )
+ ];
+ }
+
+ private getQuota(
+ tree: TreeNode,
+ quotaKey: string,
+ valueConvertFn: (number: number) => number | string
+ ): QuotaSetting {
+ // Get current maximum
+ const currentPath = tree.id;
+ tree = this.getOrigin(tree, quotaKey);
+ const dir = this.getDirectory(tree);
+ const value = dir.quotas[quotaKey];
+ // Get next tree maximum
+ // => The value that isn't changeable through a change of the current directories quota value
+ let nextMaxValue = value;
+ let nextMaxPath = dir.path;
+ if (tree.id === currentPath) {
+ if (tree.parent.id === '/') {
+ // The value will never inherit any other value, so it has no maximum.
+ nextMaxValue = 0;
+ } else {
+ const nextMaxDir = this.getDirectory(this.getOrigin(tree.parent, quotaKey));
+ nextMaxValue = nextMaxDir.quotas[quotaKey];
+ nextMaxPath = nextMaxDir.path;
+ }
+ }
+ return {
+ row: {
+ name: quotaKey === 'max_bytes' ? $localize`Max size` : $localize`Max files`,
+ value: valueConvertFn(value),
+ originPath: value ? dir.path : ''
+ },
+ quotaKey,
+ dirValue: this.nodeIds[currentPath].quotas[quotaKey],
+ nextTreeMaximum: {
+ value: nextMaxValue,
+ path: nextMaxValue ? nextMaxPath : ''
+ }
+ };
+ }
+
+ /**
+ * Get the node where the quota limit originates from in the current node
+ *
+ * Example as it's a recursive method:
+ *
+ * | Path + Value | Call depth | useOrigin? | Output |
+ * |:-------------:|:----------:|:---------------------:|:------:|
+ * | /a/b/c/d (15) | 1st | 2nd (5) < 15 => false | /a/b |
+ * | /a/b/c (20) | 2nd | 3rd (5) < 20 => false | /a/b |
+ * | /a/b (5) | 3rd | 4th (10) < 5 => true | /a/b |
+ * | /a (10) | 4th | 10 => true | /a |
+ *
+ */
+ private getOrigin(tree: TreeNode, quotaSetting: string): TreeNode {
+ if (tree.parent && tree.parent.id !== '/') {
+ const current = this.getQuotaFromTree(tree, quotaSetting);
+
+ // Get the next used quota and node above the current one (until it hits the root directory)
+ const originTree = this.getOrigin(tree.parent, quotaSetting);
+ const inherited = this.getQuotaFromTree(originTree, quotaSetting);
+
+ // Select if the current quota is in use or the above
+ const useOrigin = current === 0 || (inherited !== 0 && inherited < current);
+ return useOrigin ? originTree : tree;
+ }
+ return tree;
+ }
+
+ private getQuotaFromTree(tree: TreeNode, quotaSetting: string): number {
+ return this.getDirectory(tree).quotas[quotaSetting];
+ }
+
+ private getDirectory(node: TreeNode): CephfsDir {
+ const path = node.id as string;
+ return this.nodeIds[path];
+ }
+
+ selectOrigin(path: string) {
+ this.selectNode(this.getNode(path));
+ }
+
+ private getNode(path: string): TreeNode {
+ return this.treeComponent.treeModel.getNodeById(path);
+ }
+
+ updateQuotaModal() {
+ const path = this.selectedDir.path;
+ const selection: QuotaSetting = this.quota.selection.first();
+ const nextMax = selection.nextTreeMaximum;
+ const key = selection.quotaKey;
+ const value = selection.dirValue;
+ this.modalService.show(FormModalComponent, {
+ titleText: this.getModalQuotaTitle(
+ value === 0 ? this.actionLabels.SET : this.actionLabels.UPDATE,
+ path
+ ),
+ message: nextMax.value
+ ? $localize`The inherited ${this.getQuotaValueFromPathMsg(
+ nextMax.value,
+ nextMax.path
+ )} is the maximum value to be used.`
+ : undefined,
+ fields: [this.getQuotaFormField(selection.row.name, key, value, nextMax.value)],
+ submitButtonText: $localize`Save`,
+ onSubmit: (values: CephfsQuotas) => this.updateQuota(values)
+ });
+ }
+
+ private getModalQuotaTitle(action: string, path: string): string {
+ return $localize`${action} CephFS ${this.getQuotaName()} quota for '${path}'`;
+ }
+
+ private getQuotaName(): string {
+ return this.isBytesQuotaSelected() ? $localize`size` : $localize`files`;
+ }
+
+ private isBytesQuotaSelected(): boolean {
+ return this.quota.selection.first().quotaKey === 'max_bytes';
+ }
+
+ private getQuotaValueFromPathMsg(value: number, path: string): string {
+ value = this.isBytesQuotaSelected() ? this.dimlessBinaryPipe.transform(value) : value;
+
+ return $localize`${this.getQuotaName()} quota ${value} from '${path}'`;
+ }
+
+ private getQuotaFormField(
+ label: string,
+ name: string,
+ value: number,
+ maxValue: number
+ ): CdFormModalFieldConfig {
+ const isBinary = name === 'max_bytes';
+ const formValidators = [isBinary ? CdValidators.binaryMin(0) : Validators.min(0)];
+ if (maxValue) {
+ formValidators.push(isBinary ? CdValidators.binaryMax(maxValue) : Validators.max(maxValue));
+ }
+ const field: CdFormModalFieldConfig = {
+ type: isBinary ? 'binary' : 'number',
+ label,
+ name,
+ value,
+ validators: formValidators,
+ required: true
+ };
+ if (!isBinary) {
+ field.errors = {
+ min: $localize`Value has to be at least 0 or more`,
+ max: $localize`Value has to be at most ${maxValue} or less`
+ };
+ }
+ return field;
+ }
+
+ private updateQuota(values: CephfsQuotas, onSuccess?: Function) {
+ const path = this.selectedDir.path;
+ const key = this.quota.selection.first().quotaKey;
+ const action =
+ this.selectedDir.quotas[key] === 0
+ ? this.actionLabels.SET
+ : values[key] === 0
+ ? this.actionLabels.UNSET
+ : $localize`Updated`;
+ this.cephfsService.quota(this.id, path, values).subscribe(() => {
+ if (onSuccess) {
+ onSuccess();
+ }
+ this.notificationService.show(
+ NotificationType.success,
+ this.getModalQuotaTitle(action, path)
+ );
+ this.forceDirRefresh();
+ });
+ }
+
+ unsetQuotaModal() {
+ const path = this.selectedDir.path;
+ const selection: QuotaSetting = this.quota.selection.first();
+ const key = selection.quotaKey;
+ const nextMax = selection.nextTreeMaximum;
+ const dirValue = selection.dirValue;
+
+ const quotaValue = this.getQuotaValueFromPathMsg(nextMax.value, nextMax.path);
+ const conclusion =
+ nextMax.value > 0
+ ? nextMax.value > dirValue
+ ? $localize`in order to inherit ${quotaValue}`
+ : $localize`which isn't used because of the inheritance of ${quotaValue}`
+ : $localize`in order to have no quota on the directory`;
+
+ this.modalRef = this.modalService.show(ConfirmationModalComponent, {
+ titleText: this.getModalQuotaTitle(this.actionLabels.UNSET, path),
+ buttonText: this.actionLabels.UNSET,
+ description: $localize`${this.actionLabels.UNSET} ${this.getQuotaValueFromPathMsg(
+ dirValue,
+ path
+ )} ${conclusion}.`,
+ onSubmit: () => this.updateQuota({ [key]: 0 }, () => this.modalRef.close())
+ });
+ }
+
+ createSnapshot() {
+ // Create a snapshot. Auto-generate a snapshot name by default.
+ const path = this.selectedDir.path;
+ this.modalService.show(FormModalComponent, {
+ titleText: $localize`Create Snapshot`,
+ message: $localize`Please enter the name of the snapshot.`,
+ fields: [
+ {
+ type: 'text',
+ name: 'name',
+ value: `${moment().toISOString(true)}`,
+ required: true,
+ validators: [this.validateValue.bind(this)]
+ }
+ ],
+ submitButtonText: $localize`Create Snapshot`,
+ onSubmit: (values: CephfsSnapshot) => {
+ if (!this.alreadyExists) {
+ this.cephfsService.mkSnapshot(this.id, path, values.name).subscribe((name) => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Created snapshot '${name}' for '${path}'`
+ );
+ this.forceDirRefresh();
+ });
+ } else {
+ this.notificationService.show(
+ NotificationType.error,
+ $localize`Snapshot name '${values.name}' is already in use. Please use another name.`
+ );
+ }
+ }
+ });
+ }
+
+ validateValue(control: AbstractControl) {
+ this.alreadyExists = this.selectedDir.snapshots.some((s) => s.name === control.value);
+ }
+
+ /**
+ * Forces an update of the current selected directory
+ *
+ * As all nodes point by their path on an directory object, the easiest way is to update
+ * the objects by merge with their latest change.
+ */
+ private forceDirRefresh(path?: string) {
+ if (!path) {
+ const dir = this.selectedDir;
+ if (!dir) {
+ throw new Error('This function can only be called without path if an selection was made');
+ }
+ // Parent has to be called in order to update the object referring
+ // to the current selected directory
+ path = dir.parent ? dir.parent : dir.path;
+ }
+ const node = this.getNode(path);
+ node.loadNodeChildren();
+ }
+
+ private updateTreeStructure(dirs: CephfsDir[]) {
+ const getChildrenAndPaths = (
+ directories: CephfsDir[],
+ parent: string
+ ): { children: CephfsDir[]; paths: string[] } => {
+ const children = directories.filter((d) => d.parent === parent);
+ const paths = children.map((d) => d.path);
+ return { children, paths };
+ };
+
+ const parents = _.uniq(dirs.map((d) => d.parent).sort());
+ parents.forEach((p) => {
+ const received = getChildrenAndPaths(dirs, p);
+ const cached = getChildrenAndPaths(this.dirs, p);
+
+ cached.children.forEach((d) => {
+ if (!received.paths.includes(d.path)) {
+ this.removeOldDirectory(d);
+ }
+ });
+ received.children.forEach((d) => {
+ if (cached.paths.includes(d.path)) {
+ this.updateExistingDirectory(cached.children, d);
+ } else {
+ this.addNewDirectory(d);
+ }
+ });
+ });
+ }
+
+ private removeOldDirectory(rmDir: CephfsDir) {
+ const path = rmDir.path;
+ // Remove directory from local variables
+ _.remove(this.dirs, (d) => d.path === path);
+ delete this.nodeIds[path];
+ this.updateDirectoriesParentNode(rmDir);
+ }
+
+ private updateDirectoriesParentNode(dir: CephfsDir) {
+ const parent = dir.parent;
+ if (!parent) {
+ return;
+ }
+ const node = this.getNode(parent);
+ if (!node) {
+ // Node will not be found for new sub sub directories - this is the intended behaviour
+ return;
+ }
+ const children = this.getChildren(parent);
+ node.data.children = children;
+ node.data.hasChildren = children.length > 0;
+ this.treeComponent.treeModel.update();
+ }
+
+ private addNewDirectory(newDir: CephfsDir) {
+ this.dirs.push(newDir);
+ this.nodeIds[newDir.path] = newDir;
+ this.updateDirectoriesParentNode(newDir);
+ }
+
+ private updateExistingDirectory(source: CephfsDir[], updatedDir: CephfsDir) {
+ const currentDirObject = source.find((sub) => sub.path === updatedDir.path);
+ Object.assign(currentDirObject, updatedDir);
+ }
+
+ private updateQuotaTable() {
+ const node = this.selectedDir ? this.getNode(this.selectedDir.path) : undefined;
+ if (node && node.id !== '/') {
+ this.setSettings(node);
+ }
+ }
+
+ private updateTree(force: boolean = false) {
+ if (this.loadingIndicator && !force) {
+ // In order to make the page scrollable during load, the render cycle for each node
+ // is omitted and only be called if all updates were loaded.
+ return;
+ }
+ this.treeComponent.treeModel.update();
+ this.nodes = [...this.nodes];
+ this.treeComponent.sizeChanged();
+ }
+
+ deleteSnapshotModal() {
+ this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: $localize`CephFs Snapshot`,
+ itemNames: this.snapshot.selection.selected.map((snapshot: CephfsSnapshot) => snapshot.name),
+ submitAction: () => this.deleteSnapshot()
+ });
+ }
+
+ deleteSnapshot() {
+ const path = this.selectedDir.path;
+ this.snapshot.selection.selected.forEach((snapshot: CephfsSnapshot) => {
+ const name = snapshot.name;
+ this.cephfsService.rmSnapshot(this.id, path, name).subscribe(() => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Deleted snapshot '${name}' for '${path}'`
+ );
+ });
+ });
+ this.modalRef.close();
+ this.forceDirRefresh();
+ }
+
+ refreshAllDirectories() {
+ // In order to make the page scrollable during load, the render cycle for each node
+ // is omitted and only be called if all updates were loaded.
+ this.loadingIndicator = true;
+ this.requestedPaths.map((path) => this.forceDirRefresh(path));
+ const interval = setInterval(() => {
+ this.updateTree(true);
+ if (!this.loadingIndicator) {
+ clearInterval(interval);
+ }
+ }, 3000);
+ }
+
+ unsetLoadingIndicator() {
+ if (!this.loadingIndicator) {
+ return;
+ }
+ clearTimeout(this.loadingTimeout);
+ this.loadingTimeout = setTimeout(() => {
+ const loading = Object.values(this.loading).some((l) => l);
+ if (loading) {
+ return this.unsetLoadingIndicator();
+ }
+ this.loadingIndicator = false;
+ this.updateTree();
+ // The problem is that we can't subscribe to an useful updated tree event and the time
+ // between fetching all calls and rebuilding the tree can take some time
+ }, 3000);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.html
new file mode 100644
index 000000000..05960e87f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.html
@@ -0,0 +1,14 @@
+<cd-table [data]="filesystems"
+ columnMode="flex"
+ [columns]="columns"
+ (fetchData)="loadFilesystems($event)"
+ identifier="id"
+ forceIdentifier="true"
+ selectionType="single"
+ [hasDetails]="true"
+ (setExpandedRow)="setExpandedRow($event)"
+ (updateSelection)="updateSelection($event)">
+ <cd-cephfs-tabs cdTableDetail
+ [selection]="expandedRow">
+ </cd-cephfs-tabs>
+</cd-table>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.spec.ts
new file mode 100644
index 000000000..793651081
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.spec.ts
@@ -0,0 +1,35 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { Component, Input } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { CephfsListComponent } from './cephfs-list.component';
+
+@Component({ selector: 'cd-cephfs-tabs', template: '' })
+class CephfsTabsStubComponent {
+ @Input()
+ selection: CdTableSelection;
+}
+
+describe('CephfsListComponent', () => {
+ let component: CephfsListComponent;
+ let fixture: ComponentFixture<CephfsListComponent>;
+
+ configureTestBed({
+ imports: [BrowserAnimationsModule, SharedModule, HttpClientTestingModule],
+ declarations: [CephfsListComponent, CephfsTabsStubComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CephfsListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts
new file mode 100644
index 000000000..8d19d394c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts
@@ -0,0 +1,61 @@
+import { Component, OnInit } from '@angular/core';
+
+import { CephfsService } from '~/app/shared/api/cephfs.service';
+import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { CdDatePipe } from '~/app/shared/pipes/cd-date.pipe';
+
+@Component({
+ selector: 'cd-cephfs-list',
+ templateUrl: './cephfs-list.component.html',
+ styleUrls: ['./cephfs-list.component.scss']
+})
+export class CephfsListComponent extends ListWithDetails implements OnInit {
+ columns: CdTableColumn[];
+ filesystems: any = [];
+ selection = new CdTableSelection();
+
+ constructor(private cephfsService: CephfsService, private cdDatePipe: CdDatePipe) {
+ super();
+ }
+
+ ngOnInit() {
+ this.columns = [
+ {
+ name: $localize`Name`,
+ prop: 'mdsmap.fs_name',
+ flexGrow: 2
+ },
+ {
+ name: $localize`Created`,
+ prop: 'mdsmap.created',
+ flexGrow: 2,
+ pipe: this.cdDatePipe
+ },
+ {
+ name: $localize`Enabled`,
+ prop: 'mdsmap.enabled',
+ flexGrow: 1,
+ cellTransformation: CellTemplate.checkIcon
+ }
+ ];
+ }
+
+ loadFilesystems(context: CdTableFetchDataContext) {
+ this.cephfsService.list().subscribe(
+ (resp: any[]) => {
+ this.filesystems = resp;
+ },
+ () => {
+ context.error();
+ }
+ );
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html
new file mode 100644
index 000000000..7a222a100
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html
@@ -0,0 +1,47 @@
+<ng-container *ngIf="selection">
+ <ul ngbNav
+ #nav="ngbNav"
+ (navChange)="softRefresh()"
+ class="nav-tabs"
+ cdStatefulTab="cephfs-tabs">
+ <li ngbNavItem="details">
+ <a ngbNavLink
+ i18n>Details</a>
+ <ng-template ngbNavContent>
+ <cd-cephfs-detail [data]="details">
+ </cd-cephfs-detail>
+ </ng-template>
+ </li>
+ <li ngbNavItem="clients">
+ <a ngbNavLink>
+ <ng-container i18n>Clients</ng-container>
+ <span class="badge badge-pill badge-tab ml-1">{{ clients.data.length }}</span>
+ </a>
+ <ng-template ngbNavContent>
+ <cd-cephfs-clients [id]="id"
+ [clients]="clients"
+ (triggerApiUpdate)="refresh()">
+ </cd-cephfs-clients>
+ </ng-template>
+ </li>
+ <li ngbNavItem="directories">
+ <a ngbNavLink
+ i18n>Directories</a>
+ <ng-template ngbNavContent>
+ <cd-cephfs-directories [id]="id"></cd-cephfs-directories>
+ </ng-template>
+ </li>
+ <li ngbNavItem="performance-details">
+ <a ngbNavLink
+ i18n>Performance Details</a>
+ <ng-template ngbNavContent>
+ <cd-grafana [grafanaPath]="'mds-performance?var-mds_servers=mds.' + grafanaId"
+ uid="tbO9LAiZz"
+ grafanaStyle="one">
+ </cd-grafana>
+ </ng-template>
+ </li>
+ </ul>
+
+ <div [ngbNavOutlet]="nav"></div>
+</ng-container>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.spec.ts
new file mode 100644
index 000000000..6a8a3991b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.spec.ts
@@ -0,0 +1,215 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { Component, Input } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { TreeModule } from '@circlon/angular-tree-component';
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { CephfsService } from '~/app/shared/api/cephfs.service';
+import { TableStatusViewCache } from '~/app/shared/classes/table-status-view-cache';
+import { ViewCacheStatus } from '~/app/shared/enum/view-cache-status.enum';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { CephfsClientsComponent } from '../cephfs-clients/cephfs-clients.component';
+import { CephfsDetailComponent } from '../cephfs-detail/cephfs-detail.component';
+import { CephfsDirectoriesComponent } from '../cephfs-directories/cephfs-directories.component';
+import { CephfsTabsComponent } from './cephfs-tabs.component';
+
+describe('CephfsTabsComponent', () => {
+ let component: CephfsTabsComponent;
+ let fixture: ComponentFixture<CephfsTabsComponent>;
+ let service: CephfsService;
+ let data: {
+ standbys: string;
+ pools: any[];
+ ranks: any[];
+ mdsCounters: object;
+ name: string;
+ clients: { status: ViewCacheStatus; data: any[] };
+ };
+
+ let old: any;
+ const getReload: any = () => component['reloadSubscriber'];
+ const setReload = (sth?: any) => (component['reloadSubscriber'] = sth);
+ const mockRunOutside = () => {
+ component['subscribeInterval'] = () => {
+ // It's mocked because the rxjs timer subscription isn't called through the use of 'tick'.
+ setReload({
+ unsubscribed: false,
+ unsubscribe: () => {
+ old = getReload();
+ getReload().unsubscribed = true;
+ setReload();
+ }
+ });
+ component.refresh();
+ };
+ };
+
+ const setSelection = (selection: any) => {
+ component.selection = selection;
+ component.ngOnChanges();
+ };
+
+ const selectFs = (id: number, name: string) => {
+ setSelection({
+ id,
+ mdsmap: {
+ info: {
+ something: {
+ name
+ }
+ }
+ }
+ });
+ };
+
+ const updateData = () => {
+ component['data'] = _.cloneDeep(data);
+ component.softRefresh();
+ };
+
+ @Component({ selector: 'cd-cephfs-chart', template: '' })
+ class CephfsChartStubComponent {
+ @Input()
+ mdsCounter: any;
+ }
+
+ configureTestBed({
+ imports: [
+ SharedModule,
+ NgbNavModule,
+ HttpClientTestingModule,
+ TreeModule,
+ ToastrModule.forRoot()
+ ],
+ declarations: [
+ CephfsTabsComponent,
+ CephfsChartStubComponent,
+ CephfsDetailComponent,
+ CephfsDirectoriesComponent,
+ CephfsClientsComponent
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CephfsTabsComponent);
+ component = fixture.componentInstance;
+ component.selection = undefined;
+ data = {
+ standbys: 'b',
+ pools: [{}, {}],
+ ranks: [{}, {}, {}],
+ mdsCounters: { a: { name: 'a', x: [], y: [] } },
+ name: 'someFs',
+ clients: {
+ status: ViewCacheStatus.ValueOk,
+ data: [{}, {}, {}, {}]
+ }
+ };
+ service = TestBed.inject(CephfsService);
+ spyOn(service, 'getTabs').and.callFake(() => of(data));
+
+ fixture.detectChanges();
+ mockRunOutside();
+ setReload(); // Clears rxjs timer subscription
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should resist invalid mds info', () => {
+ setSelection({
+ id: 3,
+ mdsmap: {
+ info: {}
+ }
+ });
+ expect(component.grafanaId).toBe(undefined);
+ });
+
+ it('should find out the grafana id', () => {
+ selectFs(2, 'otherMds');
+ expect(component.grafanaId).toBe('otherMds');
+ });
+
+ it('should set default values on id change before api request', () => {
+ const defaultDetails: Record<string, any> = {
+ standbys: '',
+ pools: [],
+ ranks: [],
+ mdsCounters: {},
+ name: ''
+ };
+ const defaultClients: Record<string, any> = {
+ data: [],
+ status: new TableStatusViewCache(ViewCacheStatus.ValueNone)
+ };
+ component['subscribeInterval'] = () => undefined;
+ updateData();
+ expect(component.clients).not.toEqual(defaultClients);
+ expect(component.details).not.toEqual(defaultDetails);
+ selectFs(2, 'otherMds');
+ expect(component.clients).toEqual(defaultClients);
+ expect(component.details).toEqual(defaultDetails);
+ });
+
+ it('should force data updates on tab change without api requests', () => {
+ const oldClients = component.clients;
+ const oldDetails = component.details;
+ updateData();
+ expect(service.getTabs).toHaveBeenCalledTimes(0);
+ expect(component.details).not.toBe(oldDetails);
+ expect(component.clients).not.toBe(oldClients);
+ });
+
+ describe('handling of id change', () => {
+ beforeEach(() => {
+ setReload(); // Clears rxjs timer subscription
+ selectFs(2, 'otherMds');
+ old = getReload(); // Gets current subscription
+ });
+
+ it('should have called getDetails once', () => {
+ expect(component.details.pools.length).toBe(2);
+ expect(service.getTabs).toHaveBeenCalledTimes(1);
+ });
+
+ it('should not subscribe to an new interval for the same selection', () => {
+ expect(component.id).toBe(2);
+ expect(component.grafanaId).toBe('otherMds');
+ selectFs(2, 'otherMds');
+ expect(component.id).toBe(2);
+ expect(component.grafanaId).toBe('otherMds');
+ expect(getReload()).toBe(old);
+ });
+
+ it('should subscribe to an new interval', () => {
+ selectFs(3, 'anotherMds');
+ expect(getReload()).not.toBe(old); // Holds an new object
+ });
+
+ it('should unsubscribe the old interval if it exists', () => {
+ selectFs(3, 'anotherMds');
+ expect(old.unsubscribed).toBe(true);
+ });
+
+ it('should not unsubscribe if no interval exists', () => {
+ expect(() => component.ngOnDestroy()).not.toThrow();
+ });
+
+ it('should request the details of the new id', () => {
+ expect(service.getTabs).toHaveBeenCalledWith(2);
+ });
+
+ it('should should unsubscribe on deselect', () => {
+ setSelection(undefined);
+ expect(old.unsubscribed).toBe(true);
+ expect(getReload()).toBe(undefined); // Cleared timer subscription
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.ts
new file mode 100644
index 000000000..404ec20aa
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.ts
@@ -0,0 +1,130 @@
+import { Component, Input, NgZone, OnChanges, OnDestroy } from '@angular/core';
+
+import _ from 'lodash';
+import { Subscription, timer } from 'rxjs';
+
+import { CephfsService } from '~/app/shared/api/cephfs.service';
+import { TableStatusViewCache } from '~/app/shared/classes/table-status-view-cache';
+import { ViewCacheStatus } from '~/app/shared/enum/view-cache-status.enum';
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+
+@Component({
+ selector: 'cd-cephfs-tabs',
+ templateUrl: './cephfs-tabs.component.html',
+ styleUrls: ['./cephfs-tabs.component.scss']
+})
+export class CephfsTabsComponent implements OnChanges, OnDestroy {
+ @Input()
+ selection: any;
+
+ // Grafana tab
+ grafanaId: any;
+ grafanaPermission: Permission;
+
+ // Client tab
+ id: number;
+ clients: Record<string, any> = {
+ data: [],
+ status: new TableStatusViewCache(ViewCacheStatus.ValueNone)
+ };
+
+ // Details tab
+ details: Record<string, any> = {
+ standbys: '',
+ pools: [],
+ ranks: [],
+ mdsCounters: {},
+ name: ''
+ };
+
+ private data: any;
+ private reloadSubscriber: Subscription;
+
+ constructor(
+ private ngZone: NgZone,
+ private authStorageService: AuthStorageService,
+ private cephfsService: CephfsService
+ ) {
+ this.grafanaPermission = this.authStorageService.getPermissions().grafana;
+ }
+
+ ngOnChanges() {
+ if (!this.selection) {
+ this.unsubscribeInterval();
+ return;
+ }
+ if (this.selection.id !== this.id) {
+ this.setupSelected(this.selection.id, this.selection.mdsmap.info);
+ }
+ }
+
+ private setupSelected(id: number, mdsInfo: any) {
+ this.id = id;
+ const firstMds: any = _.first(Object.values(mdsInfo));
+ this.grafanaId = firstMds && firstMds['name'];
+ this.details = {
+ standbys: '',
+ pools: [],
+ ranks: [],
+ mdsCounters: {},
+ name: ''
+ };
+ this.clients = {
+ data: [],
+ status: new TableStatusViewCache(ViewCacheStatus.ValueNone)
+ };
+ this.updateInterval();
+ }
+
+ private updateInterval() {
+ this.unsubscribeInterval();
+ this.subscribeInterval();
+ }
+
+ private unsubscribeInterval() {
+ if (this.reloadSubscriber) {
+ this.reloadSubscriber.unsubscribe();
+ }
+ }
+
+ private subscribeInterval() {
+ this.ngZone.runOutsideAngular(
+ () =>
+ (this.reloadSubscriber = timer(0, 5000).subscribe(() =>
+ this.ngZone.run(() => this.refresh())
+ ))
+ );
+ }
+
+ refresh() {
+ this.cephfsService.getTabs(this.id).subscribe(
+ (data: any) => {
+ this.data = data;
+ this.softRefresh();
+ },
+ () => {
+ this.clients.status = new TableStatusViewCache(ViewCacheStatus.ValueException);
+ }
+ );
+ }
+
+ softRefresh() {
+ const data = _.cloneDeep(this.data); // Forces update of tab tables on tab switch
+ // Clients tab
+ this.clients = data.clients;
+ this.clients.status = new TableStatusViewCache(this.clients.status);
+ // Details tab
+ this.details = {
+ standbys: data.standbys,
+ pools: data.pools,
+ ranks: data.ranks,
+ mdsCounters: data.mds_counters,
+ name: data.name
+ };
+ }
+
+ ngOnDestroy() {
+ this.unsubscribeInterval();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs.module.ts
new file mode 100644
index 000000000..41b58a0a3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs.module.ts
@@ -0,0 +1,28 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+
+import { TreeModule } from '@circlon/angular-tree-component';
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { ChartsModule } from 'ng2-charts';
+
+import { AppRoutingModule } from '~/app/app-routing.module';
+import { SharedModule } from '~/app/shared/shared.module';
+import { CephfsChartComponent } from './cephfs-chart/cephfs-chart.component';
+import { CephfsClientsComponent } from './cephfs-clients/cephfs-clients.component';
+import { CephfsDetailComponent } from './cephfs-detail/cephfs-detail.component';
+import { CephfsDirectoriesComponent } from './cephfs-directories/cephfs-directories.component';
+import { CephfsListComponent } from './cephfs-list/cephfs-list.component';
+import { CephfsTabsComponent } from './cephfs-tabs/cephfs-tabs.component';
+
+@NgModule({
+ imports: [CommonModule, SharedModule, AppRoutingModule, ChartsModule, TreeModule, NgbNavModule],
+ declarations: [
+ CephfsDetailComponent,
+ CephfsClientsComponent,
+ CephfsChartComponent,
+ CephfsListComponent,
+ CephfsTabsComponent,
+ CephfsDirectoriesComponent
+ ]
+})
+export class CephfsModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/cluster.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/cluster.module.ts
new file mode 100644
index 000000000..610bb79ba
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/cluster.module.ts
@@ -0,0 +1,123 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { RouterModule } from '@angular/router';
+
+import { TreeModule } from '@circlon/angular-tree-component';
+import {
+ NgbActiveModal,
+ NgbDatepickerModule,
+ NgbDropdownModule,
+ NgbNavModule,
+ NgbPopoverModule,
+ NgbTimepickerModule,
+ NgbTooltipModule,
+ NgbTypeaheadModule
+} from '@ng-bootstrap/ng-bootstrap';
+import { NgxPipeFunctionModule } from 'ngx-pipe-function';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { PerformanceCounterModule } from '../performance-counter/performance-counter.module';
+import { CephSharedModule } from '../shared/ceph-shared.module';
+import { ConfigurationDetailsComponent } from './configuration/configuration-details/configuration-details.component';
+import { ConfigurationFormComponent } from './configuration/configuration-form/configuration-form.component';
+import { ConfigurationComponent } from './configuration/configuration.component';
+import { CreateClusterReviewComponent } from './create-cluster/create-cluster-review.component';
+import { CreateClusterComponent } from './create-cluster/create-cluster.component';
+import { CrushmapComponent } from './crushmap/crushmap.component';
+import { HostDetailsComponent } from './hosts/host-details/host-details.component';
+import { HostFormComponent } from './hosts/host-form/host-form.component';
+import { HostsComponent } from './hosts/hosts.component';
+import { InventoryDevicesComponent } from './inventory/inventory-devices/inventory-devices.component';
+import { InventoryComponent } from './inventory/inventory.component';
+import { LogsComponent } from './logs/logs.component';
+import { MgrModulesModule } from './mgr-modules/mgr-modules.module';
+import { MonitorComponent } from './monitor/monitor.component';
+import { OsdCreationPreviewModalComponent } from './osd/osd-creation-preview-modal/osd-creation-preview-modal.component';
+import { OsdDetailsComponent } from './osd/osd-details/osd-details.component';
+import { OsdDevicesSelectionGroupsComponent } from './osd/osd-devices-selection-groups/osd-devices-selection-groups.component';
+import { OsdDevicesSelectionModalComponent } from './osd/osd-devices-selection-modal/osd-devices-selection-modal.component';
+import { OsdFlagsIndivModalComponent } from './osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component';
+import { OsdFlagsModalComponent } from './osd/osd-flags-modal/osd-flags-modal.component';
+import { OsdFormComponent } from './osd/osd-form/osd-form.component';
+import { OsdListComponent } from './osd/osd-list/osd-list.component';
+import { OsdPgScrubModalComponent } from './osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component';
+import { OsdRecvSpeedModalComponent } from './osd/osd-recv-speed-modal/osd-recv-speed-modal.component';
+import { OsdReweightModalComponent } from './osd/osd-reweight-modal/osd-reweight-modal.component';
+import { OsdScrubModalComponent } from './osd/osd-scrub-modal/osd-scrub-modal.component';
+import { ActiveAlertListComponent } from './prometheus/active-alert-list/active-alert-list.component';
+import { PrometheusTabsComponent } from './prometheus/prometheus-tabs/prometheus-tabs.component';
+import { RulesListComponent } from './prometheus/rules-list/rules-list.component';
+import { SilenceFormComponent } from './prometheus/silence-form/silence-form.component';
+import { SilenceListComponent } from './prometheus/silence-list/silence-list.component';
+import { SilenceMatcherModalComponent } from './prometheus/silence-matcher-modal/silence-matcher-modal.component';
+import { PlacementPipe } from './services/placement.pipe';
+import { ServiceDaemonListComponent } from './services/service-daemon-list/service-daemon-list.component';
+import { ServiceDetailsComponent } from './services/service-details/service-details.component';
+import { ServiceFormComponent } from './services/service-form/service-form.component';
+import { ServicesComponent } from './services/services.component';
+import { TelemetryComponent } from './telemetry/telemetry.component';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ PerformanceCounterModule,
+ NgbNavModule,
+ SharedModule,
+ RouterModule,
+ FormsModule,
+ ReactiveFormsModule,
+ NgbTooltipModule,
+ MgrModulesModule,
+ NgbTypeaheadModule,
+ NgbTimepickerModule,
+ TreeModule,
+ CephSharedModule,
+ NgbDatepickerModule,
+ NgbPopoverModule,
+ NgbDropdownModule,
+ NgxPipeFunctionModule
+ ],
+ declarations: [
+ HostsComponent,
+ MonitorComponent,
+ ConfigurationComponent,
+ OsdListComponent,
+ OsdDetailsComponent,
+ OsdScrubModalComponent,
+ OsdFlagsModalComponent,
+ HostDetailsComponent,
+ ConfigurationDetailsComponent,
+ ConfigurationFormComponent,
+ OsdReweightModalComponent,
+ CrushmapComponent,
+ LogsComponent,
+ OsdRecvSpeedModalComponent,
+ OsdPgScrubModalComponent,
+ OsdRecvSpeedModalComponent,
+ SilenceFormComponent,
+ SilenceListComponent,
+ SilenceMatcherModalComponent,
+ ServicesComponent,
+ InventoryComponent,
+ HostFormComponent,
+ OsdFormComponent,
+ OsdDevicesSelectionModalComponent,
+ InventoryDevicesComponent,
+ OsdDevicesSelectionGroupsComponent,
+ OsdCreationPreviewModalComponent,
+ RulesListComponent,
+ ActiveAlertListComponent,
+ ServiceDetailsComponent,
+ ServiceDaemonListComponent,
+ TelemetryComponent,
+ PrometheusTabsComponent,
+ ServiceFormComponent,
+ OsdFlagsIndivModalComponent,
+ PlacementPipe,
+ CreateClusterComponent,
+ CreateClusterReviewComponent
+ ],
+ providers: [NgbActiveModal]
+})
+export class ClusterModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html
new file mode 100755
index 000000000..8debf9dc6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html
@@ -0,0 +1,105 @@
+<ng-container *ngIf="selection">
+ <table class="table table-striped table-bordered">
+ <tbody>
+ <tr>
+ <td i18n
+ class="bold w-25">Name</td>
+ <td class="w-75">{{ selection.name }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Description</td>
+ <td>{{ selection.desc }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Long description</td>
+ <td>{{ selection.long_desc }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Current values</td>
+ <td>
+ <span *ngFor="let conf of selection.value; last as isLast">
+ {{ conf.section }}: {{ conf.value }}{{ !isLast ? "," : "" }}<br />
+ </span>
+ </td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Default</td>
+ <td>{{ selection.default }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Daemon default</td>
+ <td>{{ selection.daemon_default }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Type</td>
+ <td>{{ selection.type }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Min</td>
+ <td>{{ selection.min }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Max</td>
+ <td>{{ selection.max }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Flags</td>
+ <td>
+ <span *ngFor="let flag of selection.flags">
+ <span title="{{ flags[flag] }}">
+ <span class="badge badge-dark mr-2">{{ flag | uppercase }}</span>
+ </span>
+ </span>
+ </td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Services</td>
+ <td>
+ <span *ngFor="let service of selection.services">
+ <span class="badge badge-dark mr-2">{{ service }}</span>
+ </span>
+ </td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Source</td>
+ <td>{{ selection.source }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Level</td>
+ <td>{{ selection.level }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Can be updated at runtime (editable)</td>
+ <td>{{ selection.can_update_at_runtime | booleanText }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Tags</td>
+ <td>{{ selection.tags }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Enum values</td>
+ <td>{{ selection.enum_values }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">See also</td>
+ <td>{{ selection.see_also }}</td>
+ </tr>
+ </tbody>
+ </table>
+</ng-container>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.scss
new file mode 100755
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.spec.ts
new file mode 100755
index 000000000..4902602a8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.spec.ts
@@ -0,0 +1,26 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DataTableModule } from '~/app/shared/datatable/datatable.module';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { ConfigurationDetailsComponent } from './configuration-details.component';
+
+describe('ConfigurationDetailsComponent', () => {
+ let component: ConfigurationDetailsComponent;
+ let fixture: ComponentFixture<ConfigurationDetailsComponent>;
+
+ configureTestBed({
+ declarations: [ConfigurationDetailsComponent],
+ imports: [DataTableModule, SharedModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ConfigurationDetailsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts
new file mode 100755
index 000000000..0d4b67d43
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts
@@ -0,0 +1,29 @@
+import { Component, Input, OnChanges } from '@angular/core';
+
+import _ from 'lodash';
+
+@Component({
+ selector: 'cd-configuration-details',
+ templateUrl: './configuration-details.component.html',
+ styleUrls: ['./configuration-details.component.scss']
+})
+export class ConfigurationDetailsComponent implements OnChanges {
+ @Input()
+ selection: any;
+ flags = {
+ runtime: $localize`The value can be updated at runtime.`,
+ no_mon_update: $localize`Daemons/clients do not pull this value from the
+ monitor config database. We disallow setting this option via 'ceph config
+ set ...'. This option should be configured via ceph.conf or via the
+ command line.`,
+ startup: $localize`Option takes effect only during daemon startup.`,
+ cluster_create: $localize`Option only affects cluster creation.`,
+ create: $localize`Option only affects daemon creation.`
+ };
+
+ ngOnChanges() {
+ if (this.selection) {
+ this.selection.services = _.split(this.selection.services, ',');
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form-create-request.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form-create-request.model.ts
new file mode 100644
index 000000000..bca65a887
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form-create-request.model.ts
@@ -0,0 +1,4 @@
+export class ConfigFormCreateRequestModel {
+ name: string;
+ value: Array<any> = [];
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html
new file mode 100644
index 000000000..72c717942
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html
@@ -0,0 +1,160 @@
+<div class="cd-col-form"
+ *cdFormLoading="loading">
+ <form name="configForm"
+ #formDir="ngForm"
+ [formGroup]="configForm"
+ novalidate>
+ <div class="card">
+ <div class="card-header">
+ <ng-container i18>Edit</ng-container> {{ configForm.getValue('name') }}
+ </div>
+
+ <div class="card-body">
+ <!-- Name -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label">Name</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ id="name"
+ formControlName="name"
+ readonly>
+ </div>
+ </div>
+
+ <!-- Description -->
+ <div class="form-group row"
+ *ngIf="configForm.getValue('desc')">
+ <label i18n
+ class="cd-col-form-label">Description</label>
+ <div class="cd-col-form-input">
+ <textarea class="form-control resize-vertical"
+ id="desc"
+ formControlName="desc"
+ readonly>
+ </textarea>
+ </div>
+ </div>
+
+ <!-- Long description -->
+ <div class="form-group row"
+ *ngIf="configForm.getValue('long_desc')">
+ <label i18n
+ class="cd-col-form-label">Long description</label>
+ <div class="cd-col-form-input">
+ <textarea class="form-control resize-vertical"
+ id="long_desc"
+ formControlName="long_desc"
+ readonly>
+ </textarea>
+ </div>
+ </div>
+
+ <!-- Default -->
+ <div class="form-group row"
+ *ngIf="configForm.getValue('default') !== ''">
+ <label i18n
+ class="cd-col-form-label">Default</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ id="default"
+ formControlName="default"
+ readonly>
+ </div>
+ </div>
+
+ <!-- Daemon default -->
+ <div class="form-group row"
+ *ngIf="configForm.getValue('daemon_default') !== ''">
+ <label i18n
+ class="cd-col-form-label">Daemon default</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ id="daemon_default"
+ formControlName="daemon_default"
+ readonly>
+ </div>
+ </div>
+
+ <!-- Services -->
+ <div class="form-group row"
+ *ngIf="configForm.getValue('services').length > 0">
+ <label i18n
+ class="cd-col-form-label">Services</label>
+ <div class="cd-col-form-input">
+ <span *ngFor="let service of configForm.getValue('services')"
+ class="form-component-badge">
+ <span class="badge badge-dark">{{ service }}</span>
+ </span>
+ </div>
+ </div>
+
+ <!-- Values -->
+ <div formGroupName="values">
+ <h3 i18n
+ class="cd-header">Values</h3>
+ <ng-container *ngFor="let section of availSections">
+ <div class="form-group row"
+ *ngIf="type === 'bool'">
+ <label class="cd-col-form-label"
+ [for]="section">{{ section }}
+ </label>
+ <div class="cd-col-form-input">
+ <select id="pool"
+ name="pool"
+ class="form-control"
+ [formControlName]="section">
+ <option [ngValue]="null"
+ i18n>-- Default --</option>
+ <option [ngValue]="true"
+ i18n>true</option>
+ <option [ngValue]="false"
+ i18n>false</option>
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group row"
+ *ngIf="type !== 'bool'">
+ <label class="cd-col-form-label"
+ [for]="section">{{ section }}
+ </label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ [type]="inputType"
+ [id]="section"
+ [placeholder]="humanReadableType"
+ [formControlName]="section"
+ [step]="getStep(type, this.configForm.getValue(section))">
+ <span class="invalid-feedback"
+ *ngIf="configForm.showError(section, formDir, 'pattern')">
+ {{ patternHelpText }}
+ </span>
+ <span class="invalid-feedback"
+ *ngIf="configForm.showError(section, formDir, 'invalidUuid')">
+ {{ patternHelpText }}
+ </span>
+ <span class="invalid-feedback"
+ *ngIf="configForm.showError(section, formDir, 'max')"
+ i18n>The entered value is too high! It must not be greater than {{ maxValue }}.</span>
+ <span class="invalid-feedback"
+ *ngIf="configForm.showError(section, formDir, 'min')"
+ i18n>The entered value is too low! It must not be lower than {{ minValue }}.</span>
+ </div>
+ </div>
+ </ng-container>
+ </div>
+ </div>
+ <!-- Footer -->
+ <div class="card-footer">
+ <cd-form-button-panel (submitActionEvent)="submit()"
+ [form]="configForm"
+ [submitText]="actionLabels.UPDATE"
+ wrappingClass="text-right"></cd-form-button-panel>
+ </div>
+ </div>
+ </form>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.scss
new file mode 100644
index 000000000..ed2945d1d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.scss
@@ -0,0 +1,12 @@
+.form-component-badge {
+ display: block;
+ height: 34px;
+
+ span {
+ margin-top: 7px;
+ }
+}
+
+.resize-vertical {
+ resize: vertical;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.spec.ts
new file mode 100644
index 000000000..23fab84cc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.spec.ts
@@ -0,0 +1,106 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { ActivatedRoute } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+
+import { ConfigFormModel } from '~/app/shared/components/config-option/config-option.model';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { ConfigurationFormComponent } from './configuration-form.component';
+
+describe('ConfigurationFormComponent', () => {
+ let component: ConfigurationFormComponent;
+ let fixture: ComponentFixture<ConfigurationFormComponent>;
+
+ configureTestBed({
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ RouterTestingModule,
+ ToastrModule.forRoot(),
+ SharedModule
+ ],
+ declarations: [ConfigurationFormComponent],
+ providers: [
+ {
+ provide: ActivatedRoute
+ }
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ConfigurationFormComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('getValidators', () => {
+ it('should return a validator for types float, addr and uuid', () => {
+ const types = ['float', 'addr', 'uuid'];
+
+ types.forEach((valType) => {
+ const configOption = new ConfigFormModel();
+ configOption.type = valType;
+
+ const ret = component.getValidators(configOption);
+ expect(ret).toBeTruthy();
+ expect(ret.length).toBe(1);
+ });
+ });
+
+ it('should not return a validator for types str and bool', () => {
+ const types = ['str', 'bool'];
+
+ types.forEach((valType) => {
+ const configOption = new ConfigFormModel();
+ configOption.type = valType;
+
+ const ret = component.getValidators(configOption);
+ expect(ret).toBeUndefined();
+ });
+ });
+
+ it('should return a pattern and a min validator', () => {
+ const configOption = new ConfigFormModel();
+ configOption.type = 'int';
+ configOption.min = 2;
+
+ const ret = component.getValidators(configOption);
+ expect(ret).toBeTruthy();
+ expect(ret.length).toBe(2);
+ expect(component.minValue).toBe(2);
+ expect(component.maxValue).toBeUndefined();
+ });
+
+ it('should return a pattern and a max validator', () => {
+ const configOption = new ConfigFormModel();
+ configOption.type = 'int';
+ configOption.max = 5;
+
+ const ret = component.getValidators(configOption);
+ expect(ret).toBeTruthy();
+ expect(ret.length).toBe(2);
+ expect(component.minValue).toBeUndefined();
+ expect(component.maxValue).toBe(5);
+ });
+
+ it('should return multiple validators', () => {
+ const configOption = new ConfigFormModel();
+ configOption.type = 'float';
+ configOption.max = 5.2;
+ configOption.min = 1.5;
+
+ const ret = component.getValidators(configOption);
+ expect(ret).toBeTruthy();
+ expect(ret.length).toBe(3);
+ expect(component.minValue).toBe(1.5);
+ expect(component.maxValue).toBe(5.2);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts
new file mode 100644
index 000000000..18099109d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts
@@ -0,0 +1,172 @@
+import { Component, OnInit } from '@angular/core';
+import { FormControl, FormGroup, ValidatorFn } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+
+import _ from 'lodash';
+
+import { ConfigurationService } from '~/app/shared/api/configuration.service';
+import { ConfigFormModel } from '~/app/shared/components/config-option/config-option.model';
+import { ConfigOptionTypes } from '~/app/shared/components/config-option/config-option.types';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdForm } from '~/app/shared/forms/cd-form';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { ConfigFormCreateRequestModel } from './configuration-form-create-request.model';
+
+@Component({
+ selector: 'cd-configuration-form',
+ templateUrl: './configuration-form.component.html',
+ styleUrls: ['./configuration-form.component.scss']
+})
+export class ConfigurationFormComponent extends CdForm implements OnInit {
+ configForm: CdFormGroup;
+ response: ConfigFormModel;
+ type: string;
+ inputType: string;
+ humanReadableType: string;
+ minValue: number;
+ maxValue: number;
+ patternHelpText: string;
+ availSections = ['global', 'mon', 'mgr', 'osd', 'mds', 'client'];
+
+ constructor(
+ public actionLabels: ActionLabelsI18n,
+ private route: ActivatedRoute,
+ private router: Router,
+ private configService: ConfigurationService,
+ private notificationService: NotificationService
+ ) {
+ super();
+ this.createForm();
+ }
+
+ createForm() {
+ const formControls = {
+ name: new FormControl({ value: null }),
+ desc: new FormControl({ value: null }),
+ long_desc: new FormControl({ value: null }),
+ values: new FormGroup({}),
+ default: new FormControl({ value: null }),
+ daemon_default: new FormControl({ value: null }),
+ services: new FormControl([])
+ };
+
+ this.availSections.forEach((section) => {
+ formControls.values.addControl(section, new FormControl(null));
+ });
+
+ this.configForm = new CdFormGroup(formControls);
+ }
+
+ ngOnInit() {
+ this.route.params.subscribe((params: { name: string }) => {
+ const configName = params.name;
+ this.configService.get(configName).subscribe((resp: ConfigFormModel) => {
+ this.setResponse(resp);
+ this.loadingReady();
+ });
+ });
+ }
+
+ getValidators(configOption: any): ValidatorFn[] {
+ const typeValidators = ConfigOptionTypes.getTypeValidators(configOption);
+ if (typeValidators) {
+ this.patternHelpText = typeValidators.patternHelpText;
+
+ if ('max' in typeValidators && typeValidators.max !== '') {
+ this.maxValue = typeValidators.max;
+ }
+
+ if ('min' in typeValidators && typeValidators.min !== '') {
+ this.minValue = typeValidators.min;
+ }
+
+ return typeValidators.validators;
+ }
+
+ return undefined;
+ }
+
+ getStep(type: string, value: number): number | undefined {
+ return ConfigOptionTypes.getTypeStep(type, value);
+ }
+
+ setResponse(response: ConfigFormModel) {
+ this.response = response;
+ const validators = this.getValidators(response);
+
+ this.configForm.get('name').setValue(response.name);
+ this.configForm.get('desc').setValue(response.desc);
+ this.configForm.get('long_desc').setValue(response.long_desc);
+ this.configForm.get('default').setValue(response.default);
+ this.configForm.get('daemon_default').setValue(response.daemon_default);
+ this.configForm.get('services').setValue(response.services);
+
+ if (this.response.value) {
+ this.response.value.forEach((value) => {
+ // Check value type. If it's a boolean value we need to convert it because otherwise we
+ // would use the string representation. That would cause issues for e.g. checkboxes.
+ let sectionValue = null;
+ if (value.value === 'true') {
+ sectionValue = true;
+ } else if (value.value === 'false') {
+ sectionValue = false;
+ } else {
+ sectionValue = value.value;
+ }
+ this.configForm.get('values').get(value.section).setValue(sectionValue);
+ });
+ }
+
+ this.availSections.forEach((section) => {
+ this.configForm.get('values').get(section).setValidators(validators);
+ });
+
+ const currentType = ConfigOptionTypes.getType(response.type);
+ this.type = currentType.name;
+ this.inputType = currentType.inputType;
+ this.humanReadableType = currentType.humanReadable;
+ }
+
+ createRequest(): ConfigFormCreateRequestModel | null {
+ const values: any[] = [];
+
+ this.availSections.forEach((section) => {
+ const sectionValue = this.configForm.getValue(section);
+ if (sectionValue !== null && sectionValue !== '') {
+ values.push({ section: section, value: sectionValue });
+ }
+ });
+
+ if (!_.isEqual(this.response.value, values)) {
+ const request = new ConfigFormCreateRequestModel();
+ request.name = this.configForm.getValue('name');
+ request.value = values;
+ return request;
+ }
+
+ return null;
+ }
+
+ submit() {
+ const request = this.createRequest();
+
+ if (request) {
+ this.configService.create(request).subscribe(
+ () => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Updated config option ${request.name}`
+ );
+ this.router.navigate(['/configuration']);
+ },
+ () => {
+ this.configForm.setErrors({ cdSubmitButton: true });
+ }
+ );
+ }
+
+ this.router.navigate(['/configuration']);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.html
new file mode 100644
index 000000000..a1eb64963
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.html
@@ -0,0 +1,26 @@
+<cd-table [data]="data"
+ (fetchData)="getConfigurationList($event)"
+ [columns]="columns"
+ [extraFilterableColumns]="filters"
+ selectionType="single"
+ [hasDetails]="true"
+ (setExpandedRow)="setExpandedRow($event)"
+ (updateSelection)="updateSelection($event)">
+ <cd-table-actions class="table-actions"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ <cd-configuration-details cdTableDetail
+ [selection]="expandedRow">
+ </cd-configuration-details>
+</cd-table>
+
+<ng-template #confValTpl
+ let-value="value">
+ <span *ngIf="value">
+ <span *ngFor="let conf of value; last as isLast">
+ {{ conf.section }}: {{ conf.value }}{{ !isLast ? "," : "" }}<br />
+ </span>
+ </span>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.scss
new file mode 100644
index 000000000..33f2ebaa2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.scss
@@ -0,0 +1,16 @@
+.filter {
+ padding-right: 8px;
+}
+
+.fa-stack {
+ font-size: 0.79rem;
+
+ .fa-stack-1x {
+ margin-left: 8px;
+ margin-top: 5px;
+ }
+}
+
+::ng-deep cd-configuration datatable-body-cell.wrap {
+ word-break: break-all;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.spec.ts
new file mode 100644
index 000000000..56e374cef
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.spec.ts
@@ -0,0 +1,46 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule } from '@angular/forms';
+import { By } from '@angular/platform-browser';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { ConfigurationDetailsComponent } from './configuration-details/configuration-details.component';
+import { ConfigurationComponent } from './configuration.component';
+
+describe('ConfigurationComponent', () => {
+ let component: ConfigurationComponent;
+ let fixture: ComponentFixture<ConfigurationComponent>;
+
+ configureTestBed({
+ declarations: [ConfigurationComponent, ConfigurationDetailsComponent],
+ imports: [
+ BrowserAnimationsModule,
+ SharedModule,
+ FormsModule,
+ NgbNavModule,
+ HttpClientTestingModule,
+ RouterTestingModule
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ConfigurationComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should check header text', () => {
+ expect(fixture.debugElement.query(By.css('.datatable-header')).nativeElement.textContent).toBe(
+ ['Name', 'Description', 'Current value', 'Default', 'Editable'].join('')
+ );
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.ts
new file mode 100644
index 000000000..a57603d4c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.ts
@@ -0,0 +1,149 @@
+import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import { ConfigurationService } from '~/app/shared/api/configuration.service';
+import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+
+@Component({
+ selector: 'cd-configuration',
+ templateUrl: './configuration.component.html',
+ styleUrls: ['./configuration.component.scss']
+})
+export class ConfigurationComponent extends ListWithDetails implements OnInit {
+ permission: Permission;
+ tableActions: CdTableAction[];
+ data: any[] = [];
+ icons = Icons;
+ columns: CdTableColumn[];
+ selection = new CdTableSelection();
+ filters: CdTableColumn[] = [
+ {
+ name: $localize`Level`,
+ prop: 'level',
+ filterOptions: ['basic', 'advanced', 'dev'],
+ filterInitValue: 'basic',
+ filterPredicate: (row, value) => {
+ enum Level {
+ basic = 0,
+ advanced = 1,
+ dev = 2
+ }
+
+ const levelVal = Level[value];
+
+ return Level[row.level] <= levelVal;
+ }
+ },
+ {
+ name: $localize`Service`,
+ prop: 'services',
+ filterOptions: ['mon', 'mgr', 'osd', 'mds', 'common', 'mds_client', 'rgw'],
+ filterPredicate: (row, value) => {
+ return row.services.includes(value);
+ }
+ },
+ {
+ name: $localize`Source`,
+ prop: 'source',
+ filterOptions: ['mon'],
+ filterPredicate: (row, value) => {
+ if (!row.hasOwnProperty('source')) {
+ return false;
+ }
+ return row.source.includes(value);
+ }
+ },
+ {
+ name: $localize`Modified`,
+ prop: 'modified',
+ filterOptions: ['yes', 'no'],
+ filterPredicate: (row, value) => {
+ if (value === 'yes' && row.hasOwnProperty('value')) {
+ return true;
+ }
+
+ if (value === 'no' && !row.hasOwnProperty('value')) {
+ return true;
+ }
+
+ return false;
+ }
+ }
+ ];
+
+ @ViewChild('confValTpl', { static: true })
+ public confValTpl: TemplateRef<any>;
+ @ViewChild('confFlagTpl')
+ public confFlagTpl: TemplateRef<any>;
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private configurationService: ConfigurationService,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ super();
+ this.permission = this.authStorageService.getPermissions().configOpt;
+ const getConfigOptUri = () =>
+ this.selection.first() && `${encodeURIComponent(this.selection.first().name)}`;
+ const editAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.edit,
+ routerLink: () => `/configuration/edit/${getConfigOptUri()}`,
+ name: this.actionLabels.EDIT,
+ disable: () => !this.isEditable(this.selection)
+ };
+ this.tableActions = [editAction];
+ }
+
+ ngOnInit() {
+ this.columns = [
+ { canAutoResize: true, prop: 'name', name: $localize`Name` },
+ { prop: 'desc', name: $localize`Description`, cellClass: 'wrap' },
+ {
+ prop: 'value',
+ name: $localize`Current value`,
+ cellClass: 'wrap',
+ cellTemplate: this.confValTpl
+ },
+ { prop: 'default', name: $localize`Default`, cellClass: 'wrap' },
+ {
+ prop: 'can_update_at_runtime',
+ name: $localize`Editable`,
+ cellTransformation: CellTemplate.checkIcon,
+ flexGrow: 0.4,
+ cellClass: 'text-center'
+ }
+ ];
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ getConfigurationList(context: CdTableFetchDataContext) {
+ this.configurationService.getConfigData().subscribe(
+ (data: any) => {
+ this.data = data;
+ },
+ () => {
+ context.error();
+ }
+ );
+ }
+
+ isEditable(selection: CdTableSelection): boolean {
+ if (selection.selected.length !== 1) {
+ return false;
+ }
+
+ return selection.selected[0].can_update_at_runtime;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.html
new file mode 100644
index 000000000..7fbc67185
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.html
@@ -0,0 +1,54 @@
+<div class="row">
+ <div class="col-lg-3">
+ <fieldset>
+ <legend class="cd-header"
+ i18n>Cluster Resources</legend>
+ <table class="table table-striped">
+ <tr>
+ <td i18n
+ class="bold">Hosts</td>
+ <td>{{ hostsCount }}</td>
+ </tr>
+ <tr>
+ <td>
+ <dl>
+ <dt>
+ <p i18n>Storage Capacity</p>
+ </dt>
+ <dd>
+ <p i18n>Number of devices</p>
+ </dd>
+ <dd>
+ <p i18n>Raw capacity</p>
+ </dd>
+ </dl>
+ </td>
+ <td class="pt-5"><p>{{ totalDevices }}</p><p>
+ {{ totalCapacity | dimlessBinary }}</p></td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">CPUs</td>
+ <td>{{ totalCPUs }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Memory</td>
+ <td>{{ totalMemory }}</td>
+ </tr>
+ </table>
+ </fieldset>
+ </div>
+
+<div class="col-lg-9">
+ <legend i18n
+ class="cd-header">Host Details</legend>
+ <cd-hosts [hiddenColumns]="['services', 'status']"
+ [hideToolHeader]="true"
+ [hideTitle]="true"
+ [hideSubmitBtn]="true"
+ [hasTableDetails]="false"
+ [showGeneralActionsOnly]="true">
+ </cd-hosts>
+</div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.scss
new file mode 100644
index 000000000..beecca096
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.scss
@@ -0,0 +1,5 @@
+cd-hosts {
+ ::ng-deep .nav {
+ display: none;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.spec.ts
new file mode 100644
index 000000000..94d3dd9d6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.spec.ts
@@ -0,0 +1,29 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import _ from 'lodash';
+import { ToastrModule } from 'ngx-toastr';
+
+import { CephModule } from '~/app/ceph/ceph.module';
+import { CoreModule } from '~/app/core/core.module';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { CreateClusterReviewComponent } from './create-cluster-review.component';
+
+describe('CreateClusterReviewComponent', () => {
+ let component: CreateClusterReviewComponent;
+ let fixture: ComponentFixture<CreateClusterReviewComponent>;
+
+ configureTestBed({
+ imports: [HttpClientTestingModule, SharedModule, ToastrModule.forRoot(), CephModule, CoreModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CreateClusterReviewComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.ts
new file mode 100644
index 000000000..4490b4e44
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.ts
@@ -0,0 +1,72 @@
+import { Component, OnInit } from '@angular/core';
+
+import _ from 'lodash';
+
+import { CephServiceService } from '~/app/shared/api/ceph-service.service';
+import { HostService } from '~/app/shared/api/host.service';
+import { OsdService } from '~/app/shared/api/osd.service';
+import { CephServiceSpec } from '~/app/shared/models/service.interface';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { WizardStepsService } from '~/app/shared/services/wizard-steps.service';
+
+@Component({
+ selector: 'cd-create-cluster-review',
+ templateUrl: './create-cluster-review.component.html',
+ styleUrls: ['./create-cluster-review.component.scss']
+})
+export class CreateClusterReviewComponent implements OnInit {
+ hosts: object[] = [];
+ hostsCount: number;
+ totalDevices: number;
+ totalCapacity = 0;
+ services: Array<CephServiceSpec> = [];
+ totalCPUs = 0;
+ totalMemory = 0;
+
+ constructor(
+ public wizardStepsService: WizardStepsService,
+ public cephServiceService: CephServiceService,
+ private dimlessBinary: DimlessBinaryPipe,
+ public hostService: HostService,
+ private osdService: OsdService
+ ) {}
+
+ ngOnInit() {
+ let dataDevices = 0;
+ let dataDeviceCapacity = 0;
+ let walDevices = 0;
+ let walDeviceCapacity = 0;
+ let dbDevices = 0;
+ let dbDeviceCapacity = 0;
+
+ this.hostService.list('true').subscribe((resp: object[]) => {
+ this.hosts = resp;
+ this.hostsCount = this.hosts.length;
+ _.forEach(this.hosts, (hostKey) => {
+ this.totalCPUs = this.totalCPUs + hostKey['cpu_count'];
+ // convert to bytes
+ this.totalMemory = this.totalMemory + hostKey['memory_total_kb'] * 1024;
+ });
+ this.totalMemory = this.dimlessBinary.transform(this.totalMemory);
+ });
+
+ if (this.osdService.osdDevices['data']) {
+ dataDevices = this.osdService.osdDevices['data']?.length;
+ dataDeviceCapacity = this.osdService.osdDevices['data']['capacity'];
+ }
+
+ if (this.osdService.osdDevices['wal']) {
+ walDevices = this.osdService.osdDevices['wal']?.length;
+ walDeviceCapacity = this.osdService.osdDevices['wal']['capacity'];
+ }
+
+ if (this.osdService.osdDevices['db']) {
+ dbDevices = this.osdService.osdDevices['db']?.length;
+ dbDeviceCapacity = this.osdService.osdDevices['db']['capacity'];
+ }
+
+ this.totalDevices = dataDevices + walDevices + dbDevices;
+ this.osdService.osdDevices['totalDevices'] = this.totalDevices;
+ this.totalCapacity = dataDeviceCapacity + walDeviceCapacity + dbDeviceCapacity;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.html
new file mode 100644
index 000000000..d7ab567cf
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.html
@@ -0,0 +1,98 @@
+<div class="container h-75"
+ *ngIf="!startClusterCreation">
+ <div class="row h-100 justify-content-center align-items-center">
+ <div class="blank-page">
+ <!-- htmllint img-req-src="false" -->
+ <img [src]="projectConstants.cephLogo"
+ alt="Ceph"
+ class="img-fluid mx-auto d-block">
+ <h3 class="text-center m-2"
+ i18n>Welcome to {{ projectConstants.projectName }}</h3>
+
+ <div class="m-4">
+ <h4 class="text-center"
+ i18n>Please expand your cluster first</h4>
+ <div class="offset-md-2">
+ <button class="btn btn-accent m-2"
+ name="expand-cluster"
+ (click)="createCluster()"
+ aria-label="Expand Cluster"
+ i18n>Expand Cluster</button>
+ <button class="btn btn-light"
+ name="skip-cluster-creation"
+ aria-label="Skip"
+ (click)="skipClusterCreation()"
+ i18n>Skip</button>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
+<div class="card"
+ *ngIf="startClusterCreation">
+ <div class="card-header"
+ i18n>Expand Cluster</div>
+ <div class="container-fluid">
+ <cd-wizard [stepsTitle]="stepTitles"></cd-wizard>
+ <div class="card-body vertical-line">
+ <ng-container [ngSwitch]="currentStep?.stepIndex">
+ <div *ngSwitchCase="'1'"
+ class="ml-5">
+ <h4 class="title"
+ i18n>Add Hosts</h4>
+ <br>
+ <cd-hosts [hiddenColumns]="['services']"
+ [hideTitle]="true"
+ [hideSubmitBtn]="true"
+ [hasTableDetails]="false"
+ [showGeneralActionsOnly]="true"></cd-hosts>
+ </div>
+ <div *ngSwitchCase="'2'"
+ class="ml-5">
+ <h4 class="title"
+ i18n>Create OSDs</h4>
+ <div class="alignForm">
+ <cd-osd-form [hideTitle]="true"
+ [hideSubmitBtn]="true"
+ (emitDriveGroup)="setDriveGroup($event)"
+ (emitDeploymentOption)="setDeploymentOptions($event)"
+ (emitMode)="setDeploymentMode($event)"></cd-osd-form>
+ </div>
+ </div>
+ <div *ngSwitchCase="'3'"
+ class="ml-5">
+ <h4 class="title"
+ i18n>Create Services</h4>
+ <br>
+ <cd-services [hasDetails]="false"
+ [hiddenServices]="['mon', 'mgr', 'crash', 'agent']"
+ [hiddenColumns]="['status.running', 'status.size', 'status.last_refresh']"
+ [routedModal]="false"></cd-services>
+ </div>
+ <div *ngSwitchCase="'4'"
+ class="ml-5">
+ <cd-create-cluster-review></cd-create-cluster-review>
+ </div>
+ </ng-container>
+ </div>
+ </div>
+ <div class="card-footer">
+ <button class="btn btn-accent m-2 float-right"
+ (click)="onNextStep()"
+ aria-label="Next"
+ i18n>{{ showSubmitButtonLabel() }}</button>
+ <cd-back-button class="m-2 float-right"
+ aria-label="Close"
+ (backAction)="onPreviousStep()"
+ [name]="showCancelButtonLabel()"></cd-back-button>
+ </div>
+</div>
+
+<ng-template #skipConfirmTpl>
+ <span i18n>You are about to skip the cluster expansion process.
+ You’ll need to <strong>navigate through the menu to add hosts and services.</strong></span>
+
+ <div class="mt-4"
+ i18n>Are you sure you want to continue?</div>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.scss
new file mode 100644
index 000000000..313f3193b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.scss
@@ -0,0 +1,22 @@
+.container-fluid {
+ align-items: flex-start;
+ display: flex;
+ padding-left: 0;
+ width: 100%;
+}
+
+cd-hosts {
+ ::ng-deep .nav {
+ display: none;
+ }
+}
+
+cd-osd-form {
+ ::ng-deep .card {
+ border: 0;
+ }
+
+ ::ng-deep .accordion {
+ margin-left: -1.5rem;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.spec.ts
new file mode 100644
index 000000000..0563c4a80
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.spec.ts
@@ -0,0 +1,154 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+
+import { CephModule } from '~/app/ceph/ceph.module';
+import { CoreModule } from '~/app/core/core.module';
+import { HostService } from '~/app/shared/api/host.service';
+import { OsdService } from '~/app/shared/api/osd.service';
+import { ConfirmationModalComponent } from '~/app/shared/components/confirmation-modal/confirmation-modal.component';
+import { LoadingPanelComponent } from '~/app/shared/components/loading-panel/loading-panel.component';
+import { AppConstants } from '~/app/shared/constants/app.constants';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { WizardStepsService } from '~/app/shared/services/wizard-steps.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { CreateClusterComponent } from './create-cluster.component';
+
+describe('CreateClusterComponent', () => {
+ let component: CreateClusterComponent;
+ let fixture: ComponentFixture<CreateClusterComponent>;
+ let wizardStepService: WizardStepsService;
+ let hostService: HostService;
+ let osdService: OsdService;
+ let modalServiceShowSpy: jasmine.Spy;
+ const projectConstants: typeof AppConstants = AppConstants;
+
+ configureTestBed(
+ {
+ imports: [
+ HttpClientTestingModule,
+ RouterTestingModule,
+ ToastrModule.forRoot(),
+ SharedModule,
+ CoreModule,
+ CephModule
+ ]
+ },
+ [LoadingPanelComponent]
+ );
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CreateClusterComponent);
+ component = fixture.componentInstance;
+ wizardStepService = TestBed.inject(WizardStepsService);
+ hostService = TestBed.inject(HostService);
+ osdService = TestBed.inject(OsdService);
+ modalServiceShowSpy = spyOn(TestBed.inject(ModalService), 'show').and.returnValue({
+ // mock the close function, it might be called if there are async tests.
+ close: jest.fn()
+ });
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should have project name as heading in welcome screen', () => {
+ const heading = fixture.debugElement.query(By.css('h3')).nativeElement;
+ expect(heading.innerHTML).toBe(`Welcome to ${projectConstants.projectName}`);
+ });
+
+ it('should show confirmation modal when cluster creation is skipped', () => {
+ component.skipClusterCreation();
+ expect(modalServiceShowSpy.calls.any()).toBeTruthy();
+ expect(modalServiceShowSpy.calls.first().args[0]).toBe(ConfirmationModalComponent);
+ });
+
+ it('should show the wizard when cluster creation is started', () => {
+ component.createCluster();
+ fixture.detectChanges();
+ const nativeEl = fixture.debugElement.nativeElement;
+ expect(nativeEl.querySelector('cd-wizard')).not.toBe(null);
+ });
+
+ it('should have title Add Hosts', () => {
+ component.createCluster();
+ fixture.detectChanges();
+ const heading = fixture.debugElement.query(By.css('.title')).nativeElement;
+ expect(heading.innerHTML).toBe('Add Hosts');
+ });
+
+ it('should show the host list when cluster creation as first step', () => {
+ component.createCluster();
+ fixture.detectChanges();
+ const nativeEl = fixture.debugElement.nativeElement;
+ expect(nativeEl.querySelector('cd-hosts')).not.toBe(null);
+ });
+
+ it('should move to next step and show the second page', () => {
+ const wizardStepServiceSpy = spyOn(wizardStepService, 'moveToNextStep').and.callThrough();
+ component.createCluster();
+ fixture.detectChanges();
+ component.onNextStep();
+ fixture.detectChanges();
+ expect(wizardStepServiceSpy).toHaveBeenCalledTimes(1);
+ });
+
+ it('should show the button labels correctly', () => {
+ component.createCluster();
+ fixture.detectChanges();
+ let submitBtnLabel = component.showSubmitButtonLabel();
+ expect(submitBtnLabel).toEqual('Next');
+ let cancelBtnLabel = component.showCancelButtonLabel();
+ expect(cancelBtnLabel).toEqual('Cancel');
+
+ component.onNextStep();
+ fixture.detectChanges();
+ submitBtnLabel = component.showSubmitButtonLabel();
+ expect(submitBtnLabel).toEqual('Next');
+ cancelBtnLabel = component.showCancelButtonLabel();
+ expect(cancelBtnLabel).toEqual('Back');
+
+ component.onNextStep();
+ fixture.detectChanges();
+ submitBtnLabel = component.showSubmitButtonLabel();
+ expect(submitBtnLabel).toEqual('Next');
+ cancelBtnLabel = component.showCancelButtonLabel();
+ expect(cancelBtnLabel).toEqual('Back');
+
+ // Last page of the wizard
+ component.onNextStep();
+ fixture.detectChanges();
+ submitBtnLabel = component.showSubmitButtonLabel();
+ expect(submitBtnLabel).toEqual('Expand Cluster');
+ cancelBtnLabel = component.showCancelButtonLabel();
+ expect(cancelBtnLabel).toEqual('Back');
+ });
+
+ it('should ensure osd creation did not happen when no devices are selected', () => {
+ component.simpleDeployment = false;
+ const osdServiceSpy = spyOn(osdService, 'create').and.callThrough();
+ component.onSubmit();
+ fixture.detectChanges();
+ expect(osdServiceSpy).toBeCalledTimes(0);
+ });
+
+ it('should ensure osd creation did happen when devices are selected', () => {
+ const osdServiceSpy = spyOn(osdService, 'create').and.callThrough();
+ osdService.osdDevices['totalDevices'] = 1;
+ component.onSubmit();
+ fixture.detectChanges();
+ expect(osdServiceSpy).toBeCalledTimes(1);
+ });
+
+ it('should ensure host list call happened', () => {
+ const hostServiceSpy = spyOn(hostService, 'list').and.callThrough();
+ component.onSubmit();
+ expect(hostServiceSpy).toHaveBeenCalledTimes(1);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.ts
new file mode 100644
index 000000000..02333c39b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.ts
@@ -0,0 +1,231 @@
+import {
+ Component,
+ EventEmitter,
+ OnDestroy,
+ OnInit,
+ Output,
+ TemplateRef,
+ ViewChild
+} from '@angular/core';
+import { Router } from '@angular/router';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { forkJoin, Subscription } from 'rxjs';
+import { finalize } from 'rxjs/operators';
+
+import { ClusterService } from '~/app/shared/api/cluster.service';
+import { HostService } from '~/app/shared/api/host.service';
+import { OsdService } from '~/app/shared/api/osd.service';
+import { ConfirmationModalComponent } from '~/app/shared/components/confirmation-modal/confirmation-modal.component';
+import { ActionLabelsI18n, AppConstants, URLVerbs } from '~/app/shared/constants/app.constants';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { DeploymentOptions } from '~/app/shared/models/osd-deployment-options';
+import { Permissions } from '~/app/shared/models/permissions';
+import { WizardStepModel } from '~/app/shared/models/wizard-steps';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { WizardStepsService } from '~/app/shared/services/wizard-steps.service';
+import { DriveGroup } from '../osd/osd-form/drive-group.model';
+
+@Component({
+ selector: 'cd-create-cluster',
+ templateUrl: './create-cluster.component.html',
+ styleUrls: ['./create-cluster.component.scss']
+})
+export class CreateClusterComponent implements OnInit, OnDestroy {
+ @ViewChild('skipConfirmTpl', { static: true })
+ skipConfirmTpl: TemplateRef<any>;
+ currentStep: WizardStepModel;
+ currentStepSub: Subscription;
+ permissions: Permissions;
+ projectConstants: typeof AppConstants = AppConstants;
+ stepTitles = ['Add Hosts', 'Create OSDs', 'Create Services', 'Review'];
+ startClusterCreation = false;
+ observables: any = [];
+ modalRef: NgbModalRef;
+ driveGroup = new DriveGroup();
+ driveGroups: Object[] = [];
+ deploymentOption: DeploymentOptions;
+ selectedOption = {};
+ simpleDeployment = true;
+
+ @Output()
+ submitAction = new EventEmitter();
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private wizardStepsService: WizardStepsService,
+ private router: Router,
+ private hostService: HostService,
+ private notificationService: NotificationService,
+ private actionLabels: ActionLabelsI18n,
+ private clusterService: ClusterService,
+ private modalService: ModalService,
+ private taskWrapper: TaskWrapperService,
+ private osdService: OsdService
+ ) {
+ this.permissions = this.authStorageService.getPermissions();
+ this.currentStepSub = this.wizardStepsService
+ .getCurrentStep()
+ .subscribe((step: WizardStepModel) => {
+ this.currentStep = step;
+ });
+ this.currentStep.stepIndex = 1;
+ }
+
+ ngOnInit(): void {
+ this.osdService.getDeploymentOptions().subscribe((options) => {
+ this.deploymentOption = options;
+ this.selectedOption = { option: options.recommended_option };
+ });
+ }
+
+ createCluster() {
+ this.startClusterCreation = true;
+ }
+
+ skipClusterCreation() {
+ const modalVariables = {
+ titleText: $localize`Warning`,
+ buttonText: $localize`Continue`,
+ warning: true,
+ bodyTpl: this.skipConfirmTpl,
+ showSubmit: true,
+ onSubmit: () => {
+ this.clusterService.updateStatus('POST_INSTALLED').subscribe({
+ error: () => this.modalRef.close(),
+ complete: () => {
+ this.notificationService.show(
+ NotificationType.info,
+ $localize`Cluster expansion skipped by user`
+ );
+ this.router.navigate(['/dashboard']);
+ this.modalRef.close();
+ }
+ });
+ }
+ };
+ this.modalRef = this.modalService.show(ConfirmationModalComponent, modalVariables);
+ }
+
+ onSubmit() {
+ this.hostService.list('false').subscribe((hosts) => {
+ hosts.forEach((host) => {
+ const index = host['labels'].indexOf('_no_schedule', 0);
+ if (index > -1) {
+ host['labels'].splice(index, 1);
+ this.observables.push(this.hostService.update(host['hostname'], true, host['labels']));
+ }
+ });
+ forkJoin(this.observables)
+ .pipe(
+ finalize(() =>
+ this.clusterService.updateStatus('POST_INSTALLED').subscribe(() => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Cluster expansion was successful`
+ );
+ this.router.navigate(['/dashboard']);
+ })
+ )
+ )
+ .subscribe({
+ error: (error) => error.preventDefault()
+ });
+ });
+
+ if (this.driveGroup) {
+ const user = this.authStorageService.getUsername();
+ this.driveGroup.setName(`dashboard-${user}-${_.now()}`);
+ this.driveGroups.push(this.driveGroup.spec);
+ }
+
+ if (this.simpleDeployment) {
+ const title = this.deploymentOption?.options[this.selectedOption['option']].title;
+ const trackingId = $localize`${title} deployment`;
+ this.taskWrapper
+ .wrapTaskAroundCall({
+ task: new FinishedTask('osd/' + URLVerbs.CREATE, {
+ tracking_id: trackingId
+ }),
+ call: this.osdService.create([this.selectedOption], trackingId, 'predefined')
+ })
+ .subscribe({
+ error: (error) => error.preventDefault(),
+ complete: () => {
+ this.submitAction.emit();
+ }
+ });
+ } else {
+ if (this.osdService.osdDevices['totalDevices'] > 0) {
+ this.driveGroup.setFeature('encrypted', this.selectedOption['encrypted']);
+ const trackingId = _.join(_.map(this.driveGroups, 'service_id'), ', ');
+ this.taskWrapper
+ .wrapTaskAroundCall({
+ task: new FinishedTask('osd/' + URLVerbs.CREATE, {
+ tracking_id: trackingId
+ }),
+ call: this.osdService.create(this.driveGroups, trackingId)
+ })
+ .subscribe({
+ error: (error) => error.preventDefault(),
+ complete: () => {
+ this.submitAction.emit();
+ this.osdService.osdDevices = [];
+ }
+ });
+ }
+ }
+ }
+
+ setDriveGroup(driveGroup: DriveGroup) {
+ this.driveGroup = driveGroup;
+ }
+
+ setDeploymentOptions(option: object) {
+ this.selectedOption = option;
+ }
+
+ setDeploymentMode(mode: boolean) {
+ this.simpleDeployment = mode;
+ }
+
+ onNextStep() {
+ if (!this.wizardStepsService.isLastStep()) {
+ this.wizardStepsService.getCurrentStep().subscribe((step: WizardStepModel) => {
+ this.currentStep = step;
+ });
+ this.wizardStepsService.moveToNextStep();
+ } else {
+ this.onSubmit();
+ }
+ }
+
+ onPreviousStep() {
+ if (!this.wizardStepsService.isFirstStep()) {
+ this.wizardStepsService.moveToPreviousStep();
+ } else {
+ this.router.navigate(['/dashboard']);
+ }
+ }
+
+ showSubmitButtonLabel() {
+ return !this.wizardStepsService.isLastStep()
+ ? this.actionLabels.NEXT
+ : $localize`Expand Cluster`;
+ }
+
+ showCancelButtonLabel() {
+ return !this.wizardStepsService.isFirstStep()
+ ? this.actionLabels.BACK
+ : this.actionLabels.CANCEL;
+ }
+
+ ngOnDestroy(): void {
+ this.currentStepSub.unsubscribe();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.html
new file mode 100644
index 000000000..e01d3480e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.html
@@ -0,0 +1,39 @@
+<div class="row">
+ <div class="col-sm-12 col-lg-12">
+ <div class="card">
+ <div class="card-header"
+ i18n>CRUSH map viewer</div>
+ <div class="card-body">
+ <div class="row">
+ <div class="col-sm-6 col-lg-6 tree-container">
+ <i *ngIf="loadingIndicator"
+ [ngClass]="[icons.large, icons.spinner, icons.spin]"></i>
+
+ <tree-root #tree
+ [nodes]="nodes"
+ [options]="treeOptions"
+ (updateData)="onUpdateData()">
+ <ng-template #treeNodeTemplate
+ let-node>
+ <span *ngIf="node.data.status"
+ class="badge"
+ [ngClass]="{'badge-success': ['in', 'up'].includes(node.data.status), 'badge-danger': ['down', 'out', 'destroyed'].includes(node.data.status)}">
+ {{ node.data.status }}
+ </span>
+ <span>&nbsp;</span>
+ <span class="node-name"
+ [ngClass]="{'type-osd': node.data.type === 'osd'}"
+ [innerHTML]="node.data.name"></span>
+ </ng-template>
+ </tree-root>
+ </div>
+ <div class="col-sm-6 col-lg-6 metadata"
+ *ngIf="metadata">
+ <legend>{{ metadataTitle }}</legend>
+ <cd-table-key-value [data]="metadata"></cd-table-key-value>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.scss
new file mode 100644
index 000000000..e581024fd
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.scss
@@ -0,0 +1,3 @@
+.tree-container {
+ height: calc(100vh - 200px);
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.spec.ts
new file mode 100644
index 000000000..2fc0c141e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.spec.ts
@@ -0,0 +1,137 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { DebugElement } from '@angular/core';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+
+import { TreeModule } from '@circlon/angular-tree-component';
+import { of } from 'rxjs';
+
+import { CrushRuleService } from '~/app/shared/api/crush-rule.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { CrushmapComponent } from './crushmap.component';
+
+describe('CrushmapComponent', () => {
+ let component: CrushmapComponent;
+ let fixture: ComponentFixture<CrushmapComponent>;
+ let debugElement: DebugElement;
+ let crushRuleService: CrushRuleService;
+ let crushRuleServiceInfoSpy: jasmine.Spy;
+ configureTestBed({
+ imports: [HttpClientTestingModule, TreeModule, SharedModule],
+ declarations: [CrushmapComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CrushmapComponent);
+ component = fixture.componentInstance;
+ debugElement = fixture.debugElement;
+ crushRuleService = TestBed.inject(CrushRuleService);
+ crushRuleServiceInfoSpy = spyOn(crushRuleService, 'getInfo');
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should display right title', () => {
+ const span = debugElement.nativeElement.querySelector('.card-header');
+ expect(span.textContent).toBe('CRUSH map viewer');
+ });
+
+ it('should display "No nodes!" if ceph tree nodes is empty array', fakeAsync(() => {
+ crushRuleServiceInfoSpy.and.returnValue(of({ nodes: [] }));
+ fixture.detectChanges();
+ tick(5000);
+ expect(crushRuleService.getInfo).toHaveBeenCalled();
+ expect(component.nodes[0].name).toEqual('No nodes!');
+ component.ngOnDestroy();
+ }));
+
+ it('should have two root nodes', fakeAsync(() => {
+ crushRuleServiceInfoSpy.and.returnValue(
+ of({
+ nodes: [
+ { children: [-2], type: 'root', name: 'default', id: -1 },
+ { children: [1, 0, 2], type: 'host', name: 'my-host', id: -2 },
+ { status: 'up', type: 'osd', name: 'osd.0', id: 0 },
+ { status: 'down', type: 'osd', name: 'osd.1', id: 1 },
+ { status: 'up', type: 'osd', name: 'osd.2', id: 2 },
+ { children: [-4], type: 'datacenter', name: 'site1', id: -3 },
+ { children: [4], type: 'host', name: 'my-host-2', id: -4 },
+ { status: 'up', type: 'osd', name: 'osd.0-2', id: 4 }
+ ],
+ roots: [-1, -3, -6]
+ })
+ );
+ fixture.detectChanges();
+ tick(10000);
+ expect(crushRuleService.getInfo).toHaveBeenCalled();
+ expect(component.nodes).toEqual([
+ {
+ cdId: -3,
+ children: [
+ {
+ children: [
+ {
+ id: component.nodes[0].children[0].children[0].id,
+ cdId: 4,
+ status: 'up',
+ type: 'osd',
+ name: 'osd.0-2 (osd)'
+ }
+ ],
+ id: component.nodes[0].children[0].id,
+ cdId: -4,
+ status: undefined,
+ type: 'host',
+ name: 'my-host-2 (host)'
+ }
+ ],
+ id: component.nodes[0].id,
+ status: undefined,
+ type: 'datacenter',
+ name: 'site1 (datacenter)'
+ },
+ {
+ children: [
+ {
+ children: [
+ {
+ id: component.nodes[1].children[0].children[0].id,
+ cdId: 0,
+ status: 'up',
+ type: 'osd',
+ name: 'osd.0 (osd)'
+ },
+ {
+ id: component.nodes[1].children[0].children[1].id,
+ cdId: 1,
+ status: 'down',
+ type: 'osd',
+ name: 'osd.1 (osd)'
+ },
+ {
+ id: component.nodes[1].children[0].children[2].id,
+ cdId: 2,
+ status: 'up',
+ type: 'osd',
+ name: 'osd.2 (osd)'
+ }
+ ],
+ id: component.nodes[1].children[0].id,
+ cdId: -2,
+ status: undefined,
+ type: 'host',
+ name: 'my-host (host)'
+ }
+ ],
+ id: component.nodes[1].id,
+ cdId: -1,
+ status: undefined,
+ type: 'root',
+ name: 'default (root)'
+ }
+ ]);
+ component.ngOnDestroy();
+ }));
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.ts
new file mode 100644
index 000000000..e3a9ce578
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.ts
@@ -0,0 +1,122 @@
+import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
+
+import {
+ ITreeOptions,
+ TreeComponent,
+ TreeModel,
+ TreeNode,
+ TREE_ACTIONS
+} from '@circlon/angular-tree-component';
+import { Observable, Subscription } from 'rxjs';
+
+import { CrushRuleService } from '~/app/shared/api/crush-rule.service';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { TimerService } from '~/app/shared/services/timer.service';
+
+@Component({
+ selector: 'cd-crushmap',
+ templateUrl: './crushmap.component.html',
+ styleUrls: ['./crushmap.component.scss']
+})
+export class CrushmapComponent implements OnDestroy, OnInit {
+ private sub = new Subscription();
+
+ @ViewChild('tree') tree: TreeComponent;
+
+ icons = Icons;
+ loadingIndicator = true;
+ nodes: any[] = [];
+ treeOptions: ITreeOptions = {
+ useVirtualScroll: true,
+ nodeHeight: 22,
+ actionMapping: {
+ mouse: {
+ click: this.onNodeSelected.bind(this)
+ }
+ }
+ };
+
+ metadata: any;
+ metadataTitle: string;
+ metadataKeyMap: { [key: number]: any } = {};
+ data$: Observable<object>;
+
+ constructor(private crushRuleService: CrushRuleService, private timerService: TimerService) {}
+
+ ngOnInit() {
+ this.sub = this.timerService
+ .get(() => this.crushRuleService.getInfo(), 5000)
+ .subscribe((data: any) => {
+ this.loadingIndicator = false;
+ this.nodes = this.abstractTreeData(data);
+ });
+ }
+
+ ngOnDestroy() {
+ this.sub.unsubscribe();
+ }
+
+ private abstractTreeData(data: any): any[] {
+ const nodes = data.nodes || [];
+ const rootNodes = data.roots || [];
+ const treeNodeMap: { [key: number]: any } = {};
+
+ if (0 === nodes.length) {
+ return [
+ {
+ name: 'No nodes!'
+ }
+ ];
+ }
+
+ const roots: any[] = [];
+ nodes.reverse().forEach((node: any) => {
+ if (rootNodes.includes(node.id)) {
+ roots.push(node.id);
+ }
+ treeNodeMap[node.id] = this.generateTreeLeaf(node, treeNodeMap);
+ });
+
+ const children = roots.map((id) => {
+ return treeNodeMap[id];
+ });
+
+ return children;
+ }
+
+ private generateTreeLeaf(node: any, treeNodeMap: any) {
+ const cdId = node.id;
+ this.metadataKeyMap[cdId] = node;
+
+ const name: string = node.name + ' (' + node.type + ')';
+ const status: string = node.status;
+
+ const children: any[] = [];
+ const resultNode = { name, status, cdId, type: node.type };
+ if (node.children) {
+ node.children.sort().forEach((childId: any) => {
+ children.push(treeNodeMap[childId]);
+ });
+
+ resultNode['children'] = children;
+ }
+
+ return resultNode;
+ }
+
+ onNodeSelected(tree: TreeModel, node: TreeNode) {
+ TREE_ACTIONS.ACTIVATE(tree, node, true);
+ if (node.data.cdId !== undefined) {
+ const { name, type, status, ...remain } = this.metadataKeyMap[node.data.cdId];
+ this.metadata = remain;
+ this.metadataTitle = name + ' (' + type + ')';
+ } else {
+ delete this.metadata;
+ delete this.metadataTitle;
+ }
+ }
+
+ onUpdateData() {
+ this.tree.treeModel.expandAll();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/fixtures/host_list_response.json b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/fixtures/host_list_response.json
new file mode 100644
index 000000000..838819790
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/fixtures/host_list_response.json
@@ -0,0 +1,32 @@
+[
+ {
+ "hostname": "ceph-master",
+ "services": [
+ { "type": "mds", "id": "a" },
+ { "type": "mds", "id": "b" },
+ { "type": "mds", "id": "c" },
+ { "type": "mgr", "id": "x" },
+ { "type": "mon", "id": "a" },
+ { "type": "mon", "id": "b" },
+ { "type": "mon", "id": "c" },
+ { "type": "osd", "id": "0" },
+ { "type": "osd", "id": "1" },
+ { "type": "osd", "id": "2" }
+ ],
+ "ceph_version": "ceph version Development (no_version) pacific (dev)",
+ "addr": "",
+ "labels": [],
+ "service_type": "",
+ "sources": { "ceph": true, "orchestrator": false },
+ "status": ""
+ },
+ {
+ "ceph_version": "",
+ "services": [],
+ "sources": { "ceph": false, "orchestrator": true },
+ "hostname": "mgr0",
+ "addr": "mgr0",
+ "labels": [],
+ "status": ""
+ }
+]
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.html
new file mode 100644
index 000000000..a138768c3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.html
@@ -0,0 +1,59 @@
+<ng-container *ngIf="selection">
+ <ul ngbNav
+ #nav="ngbNav"
+ class="nav-tabs"
+ cdStatefulTab="host-details">
+ <li ngbNavItem="devices">
+ <a ngbNavLink
+ i18n>Devices</a>
+ <ng-template ngbNavContent>
+ <cd-device-list [hostname]="selection['hostname']"></cd-device-list>
+ </ng-template>
+ </li>
+ <li ngbNavItem="inventory"
+ *ngIf="permissions.hosts.read">
+ <a ngbNavLink
+ i18n>Physical Disks</a>
+ <ng-template ngbNavContent>
+ <cd-inventory [hostname]="selectedHostname"></cd-inventory>
+ </ng-template>
+ </li>
+ <li ngbNavItem="daemons"
+ *ngIf="permissions.hosts.read">
+ <a ngbNavLink
+ i18n>Daemons</a>
+ <ng-template ngbNavContent>
+ <cd-service-daemon-list [hostname]="selectedHostname"
+ flag="hostDetails"
+ [hiddenColumns]="['hostname']">
+ </cd-service-daemon-list>
+ </ng-template>
+ </li>
+ <li ngbNavItem="performance-details"
+ *ngIf="permissions.grafana.read">
+ <a ngbNavLink
+ i18n>Performance Details</a>
+ <ng-template ngbNavContent>
+ <cd-grafana [grafanaPath]="'host-details?var-ceph_hosts=' + selectedHostname"
+ uid="rtOg0AiWz"
+ grafanaStyle="four">
+ </cd-grafana>
+ </ng-template>
+ </li>
+ <li ngbNavItem="device-health">
+ <a ngbNavLink
+ i18n>Device health</a>
+ <ng-template ngbNavContent>
+ <cd-smart-list *ngIf="selectedHostname; else noHostname"
+ [hostname]="selectedHostname"></cd-smart-list>
+ </ng-template>
+ </li>
+ </ul>
+
+ <div [ngbNavOutlet]="nav"></div>
+</ng-container>
+
+<ng-template #noHostname>
+ <cd-alert-panel type="error"
+ i18n>No hostname found.</cd-alert-panel>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.spec.ts
new file mode 100644
index 000000000..8d632cc2b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.spec.ts
@@ -0,0 +1,68 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+
+import { CephModule } from '~/app/ceph/ceph.module';
+import { CephSharedModule } from '~/app/ceph/shared/ceph-shared.module';
+import { CoreModule } from '~/app/core/core.module';
+import { Permissions } from '~/app/shared/models/permissions';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, TabHelper } from '~/testing/unit-test-helper';
+import { HostDetailsComponent } from './host-details.component';
+
+describe('HostDetailsComponent', () => {
+ let component: HostDetailsComponent;
+ let fixture: ComponentFixture<HostDetailsComponent>;
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ HttpClientTestingModule,
+ RouterTestingModule,
+ CephModule,
+ CoreModule,
+ CephSharedModule,
+ SharedModule,
+ ToastrModule.forRoot()
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(HostDetailsComponent);
+ component = fixture.componentInstance;
+ component.selection = undefined;
+ component.permissions = new Permissions({
+ hosts: ['read'],
+ grafana: ['read']
+ });
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('Host details tabset', () => {
+ beforeEach(() => {
+ component.selection = { hostname: 'localhost' };
+ fixture.detectChanges();
+ });
+
+ it('should recognize a tabset child', () => {
+ const tabsetChild = TabHelper.getNgbNav(fixture);
+ expect(tabsetChild).toBeDefined();
+ });
+
+ it('should show tabs', () => {
+ expect(TabHelper.getTextContents(fixture)).toEqual([
+ 'Devices',
+ 'Physical Disks',
+ 'Daemons',
+ 'Performance Details',
+ 'Device health'
+ ]);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.ts
new file mode 100644
index 000000000..bc66bdaab
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.ts
@@ -0,0 +1,20 @@
+import { Component, Input } from '@angular/core';
+
+import { Permissions } from '~/app/shared/models/permissions';
+
+@Component({
+ selector: 'cd-host-details',
+ templateUrl: './host-details.component.html',
+ styleUrls: ['./host-details.component.scss']
+})
+export class HostDetailsComponent {
+ @Input()
+ permissions: Permissions;
+
+ @Input()
+ selection: any;
+
+ get selectedHostname(): string {
+ return this.selection !== undefined ? this.selection['hostname'] : null;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.html
new file mode 100644
index 000000000..66fe42f7f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.html
@@ -0,0 +1,107 @@
+<cd-modal [pageURL]="pageURL"
+ [modalRef]="activeModal">
+ <span class="modal-title"
+ i18n>{{ action | titlecase }} {{ resource | upperFirst }}</span>
+
+ <ng-container class="modal-content">
+
+ <div *cdFormLoading="loading">
+ <form name="hostForm"
+ #formDir="ngForm"
+ [formGroup]="hostForm"
+ novalidate>
+
+ <div class="modal-body">
+
+ <!-- Hostname -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="hostname">
+ <ng-container i18n>Hostname</ng-container>
+ <cd-helper>
+ <p i18n>To add multiple hosts at once, you can enter:</p>
+ <ul>
+ <li i18n>a comma-separated list of hostnames <samp>(e.g.: example-01,example-02,example-03)</samp>,</li>
+ <li i18n>a range expression <samp>(e.g.: example-[01-03].ceph)</samp>,</li>
+ <li i18n>a comma separated range expression <samp>(e.g.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)</samp></li>
+ </ul>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ placeholder="mon-123"
+ id="hostname"
+ name="hostname"
+ formControlName="hostname"
+ autofocus
+ (keyup)="checkHostNameValue()">
+ <span class="invalid-feedback"
+ *ngIf="hostForm.showError('hostname', formDir, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="hostForm.showError('hostname', formDir, 'uniqueName')"
+ i18n>The chosen hostname is already in use.</span>
+ </div>
+ </div>
+
+ <!-- Address -->
+ <div class="form-group row"
+ *ngIf="!hostPattern">
+ <label class="cd-col-form-label"
+ for="addr"
+ i18n>Network address</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ placeholder="192.168.0.1"
+ id="addr"
+ name="addr"
+ formControlName="addr">
+ <span class="invalid-feedback"
+ *ngIf="hostForm.showError('addr', formDir, 'pattern')"
+ i18n>The value is not a valid IP address.</span>
+ </div>
+ </div>
+
+ <!-- Labels -->
+ <div class="form-group row">
+ <label i18n
+ for="labels"
+ class="cd-col-form-label">Labels</label>
+ <div class="cd-col-form-input">
+ <cd-select-badges id="labels"
+ [data]="hostForm.controls.labels.value"
+ [options]="labelsOption"
+ [customBadges]="true"
+ [messages]="messages">
+ </cd-select-badges>
+ </div>
+ </div>
+
+ <!-- Maintenance Mode -->
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="maintenance"
+ type="checkbox"
+ formControlName="maintenance">
+ <label class="custom-control-label"
+ for="maintenance"
+ i18n>Maintenance Mode</label>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="submit()"
+ [form]="hostForm"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
+ wrappingClass="text-right"></cd-form-button-panel>
+ </div>
+ </form>
+ </div>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.spec.ts
new file mode 100644
index 000000000..ed85d96cb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.spec.ts
@@ -0,0 +1,168 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+
+import { LoadingPanelComponent } from '~/app/shared/components/loading-panel/loading-panel.component';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
+import { HostFormComponent } from './host-form.component';
+
+describe('HostFormComponent', () => {
+ let component: HostFormComponent;
+ let fixture: ComponentFixture<HostFormComponent>;
+ let formHelper: FormHelper;
+
+ configureTestBed(
+ {
+ imports: [
+ SharedModule,
+ HttpClientTestingModule,
+ RouterTestingModule,
+ ReactiveFormsModule,
+ ToastrModule.forRoot()
+ ],
+ declarations: [HostFormComponent],
+ providers: [NgbActiveModal]
+ },
+ [LoadingPanelComponent]
+ );
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(HostFormComponent);
+ component = fixture.componentInstance;
+ component.ngOnInit();
+ formHelper = new FormHelper(component.hostForm);
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should open the form in a modal', () => {
+ const nativeEl = fixture.debugElement.nativeElement;
+ expect(nativeEl.querySelector('cd-modal')).not.toBe(null);
+ });
+
+ it('should validate the network address is valid', fakeAsync(() => {
+ formHelper.setValue('addr', '115.42.150.37', true);
+ tick();
+ formHelper.expectValid('addr');
+ }));
+
+ it('should show error if network address is invalid', fakeAsync(() => {
+ formHelper.setValue('addr', '666.10.10.20', true);
+ tick();
+ formHelper.expectError('addr', 'pattern');
+ }));
+
+ it('should submit the network address', () => {
+ component.hostForm.get('addr').setValue('127.0.0.1');
+ fixture.detectChanges();
+ component.submit();
+ expect(component.addr).toBe('127.0.0.1');
+ });
+
+ it('should validate the labels are added', () => {
+ const labels = ['label1', 'label2'];
+ component.hostForm.get('labels').patchValue(labels);
+ fixture.detectChanges();
+ component.submit();
+ expect(component.allLabels).toBe(labels);
+ });
+
+ it('should select maintenance mode', () => {
+ component.hostForm.get('maintenance').setValue(true);
+ fixture.detectChanges();
+ component.submit();
+ expect(component.status).toBe('maintenance');
+ });
+
+ it('should expand the hostname correctly', () => {
+ component.hostForm.get('hostname').setValue('ceph-node-00.cephlab.com');
+ fixture.detectChanges();
+ component.submit();
+ expect(component.hostnameArray).toStrictEqual(['ceph-node-00.cephlab.com']);
+
+ component.hostnameArray = [];
+
+ component.hostForm.get('hostname').setValue('ceph-node-[00-10].cephlab.com');
+ fixture.detectChanges();
+ component.submit();
+ expect(component.hostnameArray).toStrictEqual([
+ 'ceph-node-00.cephlab.com',
+ 'ceph-node-01.cephlab.com',
+ 'ceph-node-02.cephlab.com',
+ 'ceph-node-03.cephlab.com',
+ 'ceph-node-04.cephlab.com',
+ 'ceph-node-05.cephlab.com',
+ 'ceph-node-06.cephlab.com',
+ 'ceph-node-07.cephlab.com',
+ 'ceph-node-08.cephlab.com',
+ 'ceph-node-09.cephlab.com',
+ 'ceph-node-10.cephlab.com'
+ ]);
+
+ component.hostnameArray = [];
+
+ component.hostForm.get('hostname').setValue('ceph-node-00.cephlab.com,ceph-node-1.cephlab.com');
+ fixture.detectChanges();
+ component.submit();
+ expect(component.hostnameArray).toStrictEqual([
+ 'ceph-node-00.cephlab.com',
+ 'ceph-node-1.cephlab.com'
+ ]);
+
+ component.hostnameArray = [];
+
+ component.hostForm
+ .get('hostname')
+ .setValue('ceph-mon-[01-05].lab.com,ceph-osd-[1-4].lab.com,ceph-rgw-[001-006].lab.com');
+ fixture.detectChanges();
+ component.submit();
+ expect(component.hostnameArray).toStrictEqual([
+ 'ceph-mon-01.lab.com',
+ 'ceph-mon-02.lab.com',
+ 'ceph-mon-03.lab.com',
+ 'ceph-mon-04.lab.com',
+ 'ceph-mon-05.lab.com',
+ 'ceph-osd-1.lab.com',
+ 'ceph-osd-2.lab.com',
+ 'ceph-osd-3.lab.com',
+ 'ceph-osd-4.lab.com',
+ 'ceph-rgw-001.lab.com',
+ 'ceph-rgw-002.lab.com',
+ 'ceph-rgw-003.lab.com',
+ 'ceph-rgw-004.lab.com',
+ 'ceph-rgw-005.lab.com',
+ 'ceph-rgw-006.lab.com'
+ ]);
+
+ component.hostnameArray = [];
+
+ component.hostForm
+ .get('hostname')
+ .setValue('ceph-(mon-[00-04],osd-[001-005],rgw-[1-3]).lab.com');
+ fixture.detectChanges();
+ component.submit();
+ expect(component.hostnameArray).toStrictEqual([
+ 'ceph-mon-00.lab.com',
+ 'ceph-mon-01.lab.com',
+ 'ceph-mon-02.lab.com',
+ 'ceph-mon-03.lab.com',
+ 'ceph-mon-04.lab.com',
+ 'ceph-osd-001.lab.com',
+ 'ceph-osd-002.lab.com',
+ 'ceph-osd-003.lab.com',
+ 'ceph-osd-004.lab.com',
+ 'ceph-osd-005.lab.com',
+ 'ceph-rgw-1.lab.com',
+ 'ceph-rgw-2.lab.com',
+ 'ceph-rgw-3.lab.com'
+ ]);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.ts
new file mode 100644
index 000000000..6bfb79d67
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.ts
@@ -0,0 +1,171 @@
+import { Component, OnInit } from '@angular/core';
+import { FormControl, Validators } from '@angular/forms';
+import { Router } from '@angular/router';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import expand from 'brace-expansion';
+
+import { HostService } from '~/app/shared/api/host.service';
+import { SelectMessages } from '~/app/shared/components/select/select-messages.model';
+import { SelectOption } from '~/app/shared/components/select/select-option.model';
+import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
+import { CdForm } from '~/app/shared/forms/cd-form';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+
+@Component({
+ selector: 'cd-host-form',
+ templateUrl: './host-form.component.html',
+ styleUrls: ['./host-form.component.scss']
+})
+export class HostFormComponent extends CdForm implements OnInit {
+ hostForm: CdFormGroup;
+ action: string;
+ resource: string;
+ hostnames: string[];
+ hostnameArray: string[] = [];
+ addr: string;
+ status: string;
+ allLabels: string[];
+ pageURL: string;
+ hostPattern = false;
+ labelsOption: Array<SelectOption> = [];
+
+ messages = new SelectMessages({
+ empty: $localize`There are no labels.`,
+ filter: $localize`Filter or add labels`,
+ add: $localize`Add label`
+ });
+
+ constructor(
+ private router: Router,
+ private actionLabels: ActionLabelsI18n,
+ private hostService: HostService,
+ private taskWrapper: TaskWrapperService,
+ public activeModal: NgbActiveModal
+ ) {
+ super();
+ this.resource = $localize`host`;
+ this.action = this.actionLabels.ADD;
+ }
+
+ ngOnInit() {
+ if (this.router.url.includes('hosts')) {
+ this.pageURL = 'hosts';
+ }
+ this.createForm();
+ this.hostService.list('false').subscribe((resp: any[]) => {
+ this.hostnames = resp.map((host) => {
+ return host['hostname'];
+ });
+ this.loadingReady();
+ });
+
+ this.hostService.getLabels().subscribe((resp: string[]) => {
+ const uniqueLabels = new Set(resp.concat(this.hostService.predefinedLabels));
+ this.labelsOption = Array.from(uniqueLabels).map((label) => {
+ return { enabled: true, name: label, selected: false, description: null };
+ });
+ });
+ }
+
+ // check if hostname is a single value or pattern to hide network address field
+ checkHostNameValue() {
+ const hostNames = this.hostForm.get('hostname').value;
+ hostNames.match(/[()\[\]{},]/g) ? (this.hostPattern = true) : (this.hostPattern = false);
+ }
+
+ private createForm() {
+ this.hostForm = new CdFormGroup({
+ hostname: new FormControl('', {
+ validators: [
+ Validators.required,
+ CdValidators.custom('uniqueName', (hostname: string) => {
+ return this.hostnames && this.hostnames.indexOf(hostname) !== -1;
+ })
+ ]
+ }),
+ addr: new FormControl('', {
+ validators: [CdValidators.ip()]
+ }),
+ labels: new FormControl([]),
+ maintenance: new FormControl({ value: false, disabled: this.pageURL !== 'hosts' })
+ });
+ }
+
+ private isCommaSeparatedPattern(hostname: string) {
+ // eg. ceph-node-01.cephlab.com,ceph-node-02.cephlab.com
+ return hostname.includes(',');
+ }
+
+ private isRangeTypePattern(hostname: string) {
+ // check if it is a range expression or comma separated range expression
+ // eg. ceph-mon-[01-05].lab.com,ceph-osd-[02-08].lab.com,ceph-rgw-[01-09]
+ return hostname.includes('[') && hostname.includes(']') && !hostname.match(/(?![^(]*\)),/g);
+ }
+
+ private replaceBraces(hostname: string) {
+ // pattern to replace range [0-5] to [0..5](valid expression for brace expansion)
+ // replace any kind of brackets with curly braces
+ return hostname
+ .replace(/(\d)\s*-\s*(\d)/g, '$1..$2')
+ .replace(/\(/g, '{')
+ .replace(/\)/g, '}')
+ .replace(/\[/g, '{')
+ .replace(/]/g, '}');
+ }
+
+ // expand hostnames in case hostname is a pattern
+ private checkHostNamePattern(hostname: string) {
+ if (this.isRangeTypePattern(hostname)) {
+ const hostnameRange = this.replaceBraces(hostname);
+ this.hostnameArray = expand(hostnameRange);
+ } else if (this.isCommaSeparatedPattern(hostname)) {
+ let hostArray = [];
+ hostArray = hostname.split(',');
+ hostArray.forEach((host: string) => {
+ if (this.isRangeTypePattern(host)) {
+ const hostnameRange = this.replaceBraces(host);
+ this.hostnameArray = this.hostnameArray.concat(expand(hostnameRange));
+ } else {
+ this.hostnameArray.push(host);
+ }
+ });
+ } else {
+ // single hostname
+ this.hostnameArray.push(hostname);
+ }
+ }
+
+ submit() {
+ const hostname = this.hostForm.get('hostname').value;
+ this.checkHostNamePattern(hostname);
+ this.addr = this.hostForm.get('addr').value;
+ this.status = this.hostForm.get('maintenance').value ? 'maintenance' : '';
+ this.allLabels = this.hostForm.get('labels').value;
+ if (this.pageURL !== 'hosts' && !this.allLabels.includes('_no_schedule')) {
+ this.allLabels.push('_no_schedule');
+ }
+ this.hostnameArray.forEach((hostName: string) => {
+ this.taskWrapper
+ .wrapTaskAroundCall({
+ task: new FinishedTask('host/' + URLVerbs.ADD, {
+ hostname: hostName
+ }),
+ call: this.hostService.create(hostName, this.addr, this.allLabels, this.status)
+ })
+ .subscribe({
+ error: () => {
+ this.hostForm.setErrors({ cdSubmitButton: true });
+ },
+ complete: () => {
+ this.pageURL === 'hosts'
+ ? this.router.navigate([this.pageURL, { outlets: { modal: null } }])
+ : this.activeModal.close();
+ }
+ });
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.html
new file mode 100644
index 000000000..b41ecfa86
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.html
@@ -0,0 +1,77 @@
+<ul ngbNav
+ #nav="ngbNav"
+ class="nav-tabs">
+ <li ngbNavItem>
+ <a ngbNavLink
+ i18n>Hosts List</a>
+ <ng-template ngbNavContent>
+ <cd-table #table
+ [data]="hosts"
+ [columns]="columns"
+ columnMode="flex"
+ (fetchData)="getHosts($event)"
+ selectionType="single"
+ [hasDetails]="hasTableDetails"
+ (setExpandedRow)="setExpandedRow($event)"
+ (updateSelection)="updateSelection($event)"
+ [toolHeader]="!hideToolHeader">
+ <div class="table-actions btn-toolbar">
+ <cd-table-actions [permission]="permissions.hosts"
+ [selection]="selection"
+ class="btn-group"
+ id="host-actions"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ </div>
+ <cd-host-details cdTableDetail
+ [permissions]="permissions"
+ [selection]="expandedRow">
+ </cd-host-details>
+ </cd-table>
+ </ng-template>
+ </li>
+ <li ngbNavItem
+ *ngIf="permissions.grafana.read">
+ <a ngbNavLink
+ i18n>Overall Performance</a>
+ <ng-template ngbNavContent>
+ <cd-grafana [grafanaPath]="'host-overview?'"
+ uid="y0KGL0iZz"
+ grafanaStyle="two">
+ </cd-grafana>
+ </ng-template>
+ </li>
+</ul>
+
+<div [ngbNavOutlet]="nav"></div>
+
+<ng-template #servicesTpl
+ let-value="value">
+ <span *ngFor="let instance of value; last as isLast">
+ <span class="badge badge-background-primary" >{{ instance }}</span>
+ <ng-container *ngIf="!isLast">&nbsp;</ng-container>
+ </span>
+</ng-template>
+
+<ng-template #maintenanceConfirmTpl>
+ <div *ngFor="let msg of errorMessage; let last=last">
+ <ul *ngIf="!last || errorMessage.length == '1'">
+ <li i18n>{{ msg }}</li>
+ </ul>
+ </div>
+ <ng-container i18n
+ *ngIf="showSubmit">Are you sure you want to continue?</ng-container>
+</ng-template>
+
+<ng-template #orchTmpl>
+ <span i18n
+ i18n-ngbTooltip
+ ngbTooltip="Data will be available only if Orchestrator is available.">N/A</span>
+</ng-template>
+
+<ng-template #flashTmpl>
+ <span i18n
+ i18n-ngbTooltip
+ ngbTooltip="SSD, NVMEs">Flash</span>
+</ng-template>
+<router-outlet name="modal"></router-outlet>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.spec.ts
new file mode 100644
index 000000000..5fce54fbb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.spec.ts
@@ -0,0 +1,419 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { CephModule } from '~/app/ceph/ceph.module';
+import { CephSharedModule } from '~/app/ceph/shared/ceph-shared.module';
+import { CoreModule } from '~/app/core/core.module';
+import { HostService } from '~/app/shared/api/host.service';
+import { OrchestratorService } from '~/app/shared/api/orchestrator.service';
+import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { OrchestratorFeature } from '~/app/shared/models/orchestrator.enum';
+import { Permissions } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import {
+ configureTestBed,
+ OrchestratorHelper,
+ TableActionHelper
+} from '~/testing/unit-test-helper';
+import { HostsComponent } from './hosts.component';
+
+class MockShowForceMaintenanceModal {
+ showModal = false;
+ showModalDialog(msg: string) {
+ if (
+ msg.includes('WARNING') &&
+ !msg.includes('It is NOT safe to stop') &&
+ !msg.includes('ALERT') &&
+ !msg.includes('unsafe to stop')
+ ) {
+ this.showModal = true;
+ }
+ }
+}
+
+describe('HostsComponent', () => {
+ let component: HostsComponent;
+ let fixture: ComponentFixture<HostsComponent>;
+ let hostListSpy: jasmine.Spy;
+ let orchService: OrchestratorService;
+ let showForceMaintenanceModal: MockShowForceMaintenanceModal;
+
+ const fakeAuthStorageService = {
+ getPermissions: () => {
+ return new Permissions({ hosts: ['read', 'update', 'create', 'delete'] });
+ }
+ };
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ CephSharedModule,
+ SharedModule,
+ HttpClientTestingModule,
+ RouterTestingModule,
+ ToastrModule.forRoot(),
+ CephModule,
+ CoreModule
+ ],
+ providers: [
+ { provide: AuthStorageService, useValue: fakeAuthStorageService },
+ TableActionsComponent
+ ]
+ });
+
+ beforeEach(() => {
+ showForceMaintenanceModal = new MockShowForceMaintenanceModal();
+ fixture = TestBed.createComponent(HostsComponent);
+ component = fixture.componentInstance;
+ hostListSpy = spyOn(TestBed.inject(HostService), 'list');
+ orchService = TestBed.inject(OrchestratorService);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should render hosts list even with not permission mapped services', () => {
+ const hostname = 'ceph.dev';
+ const payload = [
+ {
+ services: [
+ {
+ type: 'osd',
+ id: '0'
+ },
+ {
+ type: 'rgw',
+ id: 'rgw'
+ },
+ {
+ type: 'notPermissionMappedService',
+ id: '1'
+ }
+ ],
+ hostname: hostname,
+ labels: ['foo', 'bar']
+ }
+ ];
+
+ OrchestratorHelper.mockStatus(false);
+ hostListSpy.and.callFake(() => of(payload));
+ fixture.detectChanges();
+
+ component.getHosts(new CdTableFetchDataContext(() => undefined));
+ fixture.detectChanges();
+
+ const spans = fixture.debugElement.nativeElement.querySelectorAll(
+ '.datatable-body-cell-label span'
+ );
+ expect(spans[0].textContent).toBe(hostname);
+ });
+
+ it('should show the exact count of the repeating daemons', () => {
+ const hostname = 'ceph.dev';
+ const payload = [
+ {
+ services: [
+ {
+ type: 'mgr',
+ id: 'x'
+ },
+ {
+ type: 'mgr',
+ id: 'y'
+ },
+ {
+ type: 'osd',
+ id: '0'
+ },
+ {
+ type: 'osd',
+ id: '1'
+ },
+ {
+ type: 'osd',
+ id: '2'
+ },
+ {
+ type: 'rgw',
+ id: 'rgw'
+ }
+ ],
+ hostname: hostname,
+ labels: ['foo', 'bar']
+ }
+ ];
+
+ OrchestratorHelper.mockStatus(false);
+ hostListSpy.and.callFake(() => of(payload));
+ fixture.detectChanges();
+
+ component.getHosts(new CdTableFetchDataContext(() => undefined));
+ fixture.detectChanges();
+
+ const spans = fixture.debugElement.nativeElement.querySelectorAll(
+ '.datatable-body-cell-label span span.badge.badge-background-primary'
+ );
+ expect(spans[0].textContent).toContain('mgr: 2');
+ expect(spans[1].textContent).toContain('osd: 3');
+ expect(spans[2].textContent).toContain('rgw: 1');
+ });
+
+ it('should test if host facts are tranformed correctly if orch available', () => {
+ const features = [OrchestratorFeature.HOST_FACTS];
+ const payload = [
+ {
+ hostname: 'host_test',
+ services: [
+ {
+ type: 'osd',
+ id: '0'
+ }
+ ],
+ cpu_count: 2,
+ cpu_cores: 1,
+ memory_total_kb: 1024,
+ hdd_count: 4,
+ hdd_capacity_bytes: 1024,
+ flash_count: 4,
+ flash_capacity_bytes: 1024,
+ nic_count: 1
+ }
+ ];
+ OrchestratorHelper.mockStatus(true, features);
+ hostListSpy.and.callFake(() => of(payload));
+ fixture.detectChanges();
+
+ component.getHosts(new CdTableFetchDataContext(() => undefined));
+ expect(hostListSpy).toHaveBeenCalled();
+ expect(component.hosts[0]['cpu_count']).toEqual(2);
+ expect(component.hosts[0]['memory_total_bytes']).toEqual(1048576);
+ expect(component.hosts[0]['raw_capacity']).toEqual(2048);
+ expect(component.hosts[0]['hdd_count']).toEqual(4);
+ expect(component.hosts[0]['flash_count']).toEqual(4);
+ expect(component.hosts[0]['cpu_cores']).toEqual(1);
+ expect(component.hosts[0]['nic_count']).toEqual(1);
+ });
+
+ it('should test if host facts are unavailable if no orch available', () => {
+ const payload = [
+ {
+ hostname: 'host_test',
+ services: [
+ {
+ type: 'osd',
+ id: '0'
+ }
+ ]
+ }
+ ];
+ OrchestratorHelper.mockStatus(false);
+ hostListSpy.and.callFake(() => of(payload));
+ fixture.detectChanges();
+
+ component.getHosts(new CdTableFetchDataContext(() => undefined));
+ fixture.detectChanges();
+
+ const spans = fixture.debugElement.nativeElement.querySelectorAll(
+ '.datatable-body-cell-label span'
+ );
+ expect(spans[7].textContent).toBe('N/A');
+ });
+
+ it('should test if host facts are unavailable if get_fatcs orch feature is not available', () => {
+ const payload = [
+ {
+ hostname: 'host_test',
+ services: [
+ {
+ type: 'osd',
+ id: '0'
+ }
+ ]
+ }
+ ];
+ OrchestratorHelper.mockStatus(true);
+ hostListSpy.and.callFake(() => of(payload));
+ fixture.detectChanges();
+
+ component.getHosts(new CdTableFetchDataContext(() => undefined));
+ fixture.detectChanges();
+
+ const spans = fixture.debugElement.nativeElement.querySelectorAll(
+ '.datatable-body-cell-label span'
+ );
+ expect(spans[7].textContent).toBe('N/A');
+ });
+
+ it('should show force maintenance modal when it is safe to stop host', () => {
+ const errorMsg = `WARNING: Stopping 1 out of 1 daemons in Grafana service.
+ Service will not be operational with no daemons left. At
+ least 1 daemon must be running to guarantee service.`;
+ showForceMaintenanceModal.showModalDialog(errorMsg);
+ expect(showForceMaintenanceModal.showModal).toBeTruthy();
+ });
+
+ it('should not show force maintenance modal when error is an ALERT', () => {
+ const errorMsg = `ALERT: Cannot stop active Mgr daemon, Please switch active Mgrs
+ with 'ceph mgr fail ceph-node-00'`;
+ showForceMaintenanceModal.showModalDialog(errorMsg);
+ expect(showForceMaintenanceModal.showModal).toBeFalsy();
+ });
+
+ it('should not show force maintenance modal when it is not safe to stop host', () => {
+ const errorMsg = `WARNING: Stopping 1 out of 1 daemons in Grafana service.
+ Service will not be operational with no daemons left. At
+ least 1 daemon must be running to guarantee service.
+ It is NOT safe to stop ['mon.ceph-node-00']: not enough
+ monitors would be available (ceph-node-02) after stopping mons`;
+ showForceMaintenanceModal.showModalDialog(errorMsg);
+ expect(showForceMaintenanceModal.showModal).toBeFalsy();
+ });
+
+ it('should not show force maintenance modal when it is unsafe to stop host', () => {
+ const errorMsg = 'unsafe to stop osd.0 because of some unknown reason';
+ showForceMaintenanceModal.showModalDialog(errorMsg);
+ expect(showForceMaintenanceModal.showModal).toBeFalsy();
+ });
+
+ describe('table actions', () => {
+ const fakeHosts = require('./fixtures/host_list_response.json');
+
+ beforeEach(() => {
+ hostListSpy.and.callFake(() => of(fakeHosts));
+ });
+
+ const testTableActions = async (
+ orch: boolean,
+ features: OrchestratorFeature[],
+ tests: { selectRow?: number; expectResults: any }[]
+ ) => {
+ OrchestratorHelper.mockStatus(orch, features);
+ fixture.detectChanges();
+ await fixture.whenStable();
+
+ for (const test of tests) {
+ if (test.selectRow) {
+ component.selection = new CdTableSelection();
+ component.selection.selected = [test.selectRow];
+ }
+ await TableActionHelper.verifyTableActions(
+ fixture,
+ component.tableActions,
+ test.expectResults
+ );
+ }
+ };
+
+ it('should have correct states when Orchestrator is enabled', async () => {
+ const tests = [
+ {
+ expectResults: {
+ Add: { disabled: false, disableDesc: '' },
+ Edit: { disabled: true, disableDesc: '' },
+ Remove: { disabled: true, disableDesc: '' }
+ }
+ },
+ {
+ selectRow: fakeHosts[0], // non-orchestrator host
+ expectResults: {
+ Add: { disabled: false, disableDesc: '' },
+ Edit: { disabled: true, disableDesc: component.messages.nonOrchHost },
+ Remove: { disabled: true, disableDesc: component.messages.nonOrchHost }
+ }
+ },
+ {
+ selectRow: fakeHosts[1], // orchestrator host
+ expectResults: {
+ Add: { disabled: false, disableDesc: '' },
+ Edit: { disabled: false, disableDesc: '' },
+ Remove: { disabled: false, disableDesc: '' }
+ }
+ }
+ ];
+
+ const features = [
+ OrchestratorFeature.HOST_ADD,
+ OrchestratorFeature.HOST_LABEL_ADD,
+ OrchestratorFeature.HOST_REMOVE,
+ OrchestratorFeature.HOST_LABEL_REMOVE,
+ OrchestratorFeature.HOST_DRAIN
+ ];
+ await testTableActions(true, features, tests);
+ });
+
+ it('should have correct states when Orchestrator is disabled', async () => {
+ const resultNoOrchestrator = {
+ disabled: true,
+ disableDesc: orchService.disableMessages.noOrchestrator
+ };
+ const tests = [
+ {
+ expectResults: {
+ Add: resultNoOrchestrator,
+ Edit: { disabled: true, disableDesc: '' },
+ Remove: { disabled: true, disableDesc: '' }
+ }
+ },
+ {
+ selectRow: fakeHosts[0], // non-orchestrator host
+ expectResults: {
+ Add: resultNoOrchestrator,
+ Edit: { disabled: true, disableDesc: component.messages.nonOrchHost },
+ Remove: { disabled: true, disableDesc: component.messages.nonOrchHost }
+ }
+ },
+ {
+ selectRow: fakeHosts[1], // orchestrator host
+ expectResults: {
+ Add: resultNoOrchestrator,
+ Edit: resultNoOrchestrator,
+ Remove: resultNoOrchestrator
+ }
+ }
+ ];
+ await testTableActions(false, [], tests);
+ });
+
+ it('should have correct states when Orchestrator features are missing', async () => {
+ const resultMissingFeatures = {
+ disabled: true,
+ disableDesc: orchService.disableMessages.missingFeature
+ };
+ const tests = [
+ {
+ expectResults: {
+ Add: resultMissingFeatures,
+ Edit: { disabled: true, disableDesc: '' },
+ Remove: { disabled: true, disableDesc: '' }
+ }
+ },
+ {
+ selectRow: fakeHosts[0], // non-orchestrator host
+ expectResults: {
+ Add: resultMissingFeatures,
+ Edit: { disabled: true, disableDesc: component.messages.nonOrchHost },
+ Remove: { disabled: true, disableDesc: component.messages.nonOrchHost }
+ }
+ },
+ {
+ selectRow: fakeHosts[1], // orchestrator host
+ expectResults: {
+ Add: resultMissingFeatures,
+ Edit: resultMissingFeatures,
+ Remove: resultMissingFeatures
+ }
+ }
+ ];
+ await testTableActions(true, [], tests);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts
new file mode 100644
index 000000000..4f2279bcf
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts
@@ -0,0 +1,535 @@
+import { Component, Input, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
+import { Router } from '@angular/router';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { Observable, Subscription } from 'rxjs';
+import { map, mergeMap } from 'rxjs/operators';
+
+import { HostService } from '~/app/shared/api/host.service';
+import { OrchestratorService } from '~/app/shared/api/orchestrator.service';
+import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
+import { ConfirmationModalComponent } from '~/app/shared/components/confirmation-modal/confirmation-modal.component';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { FormModalComponent } from '~/app/shared/components/form-modal/form-modal.component';
+import { SelectMessages } from '~/app/shared/components/select/select-messages.model';
+import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
+import { TableComponent } from '~/app/shared/datatable/table/table.component';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { Daemon } from '~/app/shared/models/daemon.interface';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { OrchestratorFeature } from '~/app/shared/models/orchestrator.enum';
+import { OrchestratorStatus } from '~/app/shared/models/orchestrator.interface';
+import { Permissions } from '~/app/shared/models/permissions';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { URLBuilderService } from '~/app/shared/services/url-builder.service';
+import { HostFormComponent } from './host-form/host-form.component';
+
+const BASE_URL = 'hosts';
+
+@Component({
+ selector: 'cd-hosts',
+ templateUrl: './hosts.component.html',
+ styleUrls: ['./hosts.component.scss'],
+ providers: [{ provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }]
+})
+export class HostsComponent extends ListWithDetails implements OnDestroy, OnInit {
+ private sub = new Subscription();
+
+ @ViewChild(TableComponent)
+ table: TableComponent;
+ @ViewChild('servicesTpl', { static: true })
+ public servicesTpl: TemplateRef<any>;
+ @ViewChild('maintenanceConfirmTpl', { static: true })
+ maintenanceConfirmTpl: TemplateRef<any>;
+ @ViewChild('orchTmpl', { static: true })
+ orchTmpl: TemplateRef<any>;
+ @ViewChild('flashTmpl', { static: true })
+ flashTmpl: TemplateRef<any>;
+
+ @Input()
+ hiddenColumns: string[] = [];
+
+ @Input()
+ hideTitle = false;
+
+ @Input()
+ hideSubmitBtn = false;
+
+ @Input()
+ hasTableDetails = true;
+
+ @Input()
+ hideToolHeader = false;
+
+ @Input()
+ showGeneralActionsOnly = false;
+
+ permissions: Permissions;
+ columns: Array<CdTableColumn> = [];
+ hosts: Array<object> = [];
+ isLoadingHosts = false;
+ cdParams = { fromLink: '/hosts' };
+ tableActions: CdTableAction[];
+ selection = new CdTableSelection();
+ modalRef: NgbModalRef;
+ isExecuting = false;
+ errorMessage: string;
+ enableMaintenanceBtn: boolean;
+ enableDrainBtn: boolean;
+ bsModalRef: NgbModalRef;
+
+ icons = Icons;
+
+ messages = {
+ nonOrchHost: $localize`The feature is disabled because the selected host is not managed by Orchestrator.`
+ };
+
+ orchStatus: OrchestratorStatus;
+ actionOrchFeatures = {
+ add: [OrchestratorFeature.HOST_ADD],
+ edit: [OrchestratorFeature.HOST_LABEL_ADD, OrchestratorFeature.HOST_LABEL_REMOVE],
+ remove: [OrchestratorFeature.HOST_REMOVE],
+ maintenance: [
+ OrchestratorFeature.HOST_MAINTENANCE_ENTER,
+ OrchestratorFeature.HOST_MAINTENANCE_EXIT
+ ],
+ drain: [OrchestratorFeature.HOST_DRAIN]
+ };
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private dimlessBinary: DimlessBinaryPipe,
+ private hostService: HostService,
+ private actionLabels: ActionLabelsI18n,
+ private modalService: ModalService,
+ private taskWrapper: TaskWrapperService,
+ private router: Router,
+ private notificationService: NotificationService,
+ private orchService: OrchestratorService
+ ) {
+ super();
+ this.permissions = this.authStorageService.getPermissions();
+ this.tableActions = [
+ {
+ name: this.actionLabels.ADD,
+ permission: 'create',
+ icon: Icons.add,
+ click: () =>
+ this.router.url.includes('/hosts')
+ ? this.router.navigate([BASE_URL, { outlets: { modal: [URLVerbs.ADD] } }])
+ : (this.bsModalRef = this.modalService.show(HostFormComponent)),
+ disable: (selection: CdTableSelection) => this.getDisable('add', selection)
+ },
+ {
+ name: this.actionLabels.EDIT,
+ permission: 'update',
+ icon: Icons.edit,
+ click: () => this.editAction(),
+ disable: (selection: CdTableSelection) => this.getDisable('edit', selection)
+ },
+ {
+ name: this.actionLabels.START_DRAIN,
+ permission: 'update',
+ icon: Icons.exit,
+ click: () => this.hostDrain(),
+ disable: (selection: CdTableSelection) =>
+ this.getDisable('drain', selection) || !this.enableDrainBtn,
+ visible: () => !this.showGeneralActionsOnly && this.enableDrainBtn
+ },
+ {
+ name: this.actionLabels.STOP_DRAIN,
+ permission: 'update',
+ icon: Icons.exit,
+ click: () => this.hostDrain(true),
+ disable: (selection: CdTableSelection) =>
+ this.getDisable('drain', selection) || this.enableDrainBtn,
+ visible: () => !this.showGeneralActionsOnly && !this.enableDrainBtn
+ },
+ {
+ name: this.actionLabels.REMOVE,
+ permission: 'delete',
+ icon: Icons.destroy,
+ click: () => this.deleteAction(),
+ disable: (selection: CdTableSelection) => this.getDisable('remove', selection)
+ },
+ {
+ name: this.actionLabels.ENTER_MAINTENANCE,
+ permission: 'update',
+ icon: Icons.enter,
+ click: () => this.hostMaintenance(),
+ disable: (selection: CdTableSelection) =>
+ this.getDisable('maintenance', selection) ||
+ this.isExecuting ||
+ this.enableMaintenanceBtn,
+ visible: () => !this.showGeneralActionsOnly && !this.enableMaintenanceBtn
+ },
+ {
+ name: this.actionLabels.EXIT_MAINTENANCE,
+ permission: 'update',
+ icon: Icons.exit,
+ click: () => this.hostMaintenance(),
+ disable: (selection: CdTableSelection) =>
+ this.getDisable('maintenance', selection) ||
+ this.isExecuting ||
+ !this.enableMaintenanceBtn,
+ visible: () => !this.showGeneralActionsOnly && this.enableMaintenanceBtn
+ }
+ ];
+ }
+
+ ngOnInit() {
+ this.columns = [
+ {
+ name: $localize`Hostname`,
+ prop: 'hostname',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Service Instances`,
+ prop: 'service_instances',
+ flexGrow: 1,
+ cellTemplate: this.servicesTpl
+ },
+ {
+ name: $localize`Labels`,
+ prop: 'labels',
+ flexGrow: 1,
+ cellTransformation: CellTemplate.badge,
+ customTemplateConfig: {
+ class: 'badge-dark'
+ }
+ },
+ {
+ name: $localize`Status`,
+ prop: 'status',
+ flexGrow: 1,
+ cellTransformation: CellTemplate.badge,
+ customTemplateConfig: {
+ map: {
+ maintenance: { class: 'badge-warning' }
+ }
+ }
+ },
+ {
+ name: $localize`Model`,
+ prop: 'model',
+ flexGrow: 1
+ },
+ {
+ name: $localize`CPUs`,
+ prop: 'cpu_count',
+ flexGrow: 0.3
+ },
+ {
+ name: $localize`Cores`,
+ prop: 'cpu_cores',
+ flexGrow: 0.3
+ },
+ {
+ name: $localize`Total Memory`,
+ prop: 'memory_total_bytes',
+ pipe: this.dimlessBinary,
+ flexGrow: 0.4
+ },
+ {
+ name: $localize`Raw Capacity`,
+ prop: 'raw_capacity',
+ pipe: this.dimlessBinary,
+ flexGrow: 0.5
+ },
+ {
+ name: $localize`HDDs`,
+ prop: 'hdd_count',
+ flexGrow: 0.3
+ },
+ {
+ name: $localize`Flash`,
+ prop: 'flash_count',
+ headerTemplate: this.flashTmpl,
+ flexGrow: 0.3
+ },
+ {
+ name: $localize`NICs`,
+ prop: 'nic_count',
+ flexGrow: 0.3
+ }
+ ];
+
+ this.columns = this.columns.filter((col: any) => {
+ return !this.hiddenColumns.includes(col.prop);
+ });
+ }
+
+ ngOnDestroy() {
+ this.sub.unsubscribe();
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ this.enableMaintenanceBtn = false;
+ this.enableDrainBtn = false;
+ if (this.selection.hasSelection) {
+ if (this.selection.first().status === 'maintenance') {
+ this.enableMaintenanceBtn = true;
+ }
+
+ if (!this.selection.first().labels.includes('_no_schedule')) {
+ this.enableDrainBtn = true;
+ }
+ }
+ }
+
+ editAction() {
+ this.hostService.getLabels().subscribe((resp: string[]) => {
+ const host = this.selection.first();
+ const labels = new Set(resp.concat(this.hostService.predefinedLabels));
+ const allLabels = Array.from(labels).map((label) => {
+ return { enabled: true, name: label };
+ });
+ this.modalService.show(FormModalComponent, {
+ titleText: $localize`Edit Host: ${host.hostname}`,
+ fields: [
+ {
+ type: 'select-badges',
+ name: 'labels',
+ value: host['labels'],
+ label: $localize`Labels`,
+ typeConfig: {
+ customBadges: true,
+ options: allLabels,
+ messages: new SelectMessages({
+ empty: $localize`There are no labels.`,
+ filter: $localize`Filter or add labels`,
+ add: $localize`Add label`
+ })
+ }
+ }
+ ],
+ submitButtonText: $localize`Edit Host`,
+ onSubmit: (values: any) => {
+ this.hostService.update(host['hostname'], true, values.labels).subscribe(() => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Updated Host "${host.hostname}"`
+ );
+ // Reload the data table content.
+ this.table.refreshBtn();
+ });
+ }
+ });
+ });
+ }
+
+ hostMaintenance() {
+ this.isExecuting = true;
+ const host = this.selection.first();
+ if (host['status'] !== 'maintenance') {
+ this.hostService.update(host['hostname'], false, [], true).subscribe(
+ () => {
+ this.isExecuting = false;
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`"${host.hostname}" moved to maintenance`
+ );
+ this.table.refreshBtn();
+ },
+ (error) => {
+ this.isExecuting = false;
+ this.errorMessage = error.error['detail'].split(/\n/);
+ error.preventDefault();
+ if (
+ error.error['detail'].includes('WARNING') &&
+ !error.error['detail'].includes('It is NOT safe to stop') &&
+ !error.error['detail'].includes('ALERT') &&
+ !error.error['detail'].includes('unsafe to stop')
+ ) {
+ const modalVariables = {
+ titleText: $localize`Warning`,
+ buttonText: $localize`Continue`,
+ warning: true,
+ bodyTpl: this.maintenanceConfirmTpl,
+ showSubmit: true,
+ onSubmit: () => {
+ this.hostService.update(host['hostname'], false, [], true, true).subscribe(
+ () => {
+ this.modalRef.close();
+ },
+ () => this.modalRef.close()
+ );
+ }
+ };
+ this.modalRef = this.modalService.show(ConfirmationModalComponent, modalVariables);
+ } else {
+ this.notificationService.show(
+ NotificationType.error,
+ $localize`"${host.hostname}" cannot be put into maintenance`,
+ $localize`${error.error['detail']}`
+ );
+ }
+ }
+ );
+ } else {
+ this.hostService.update(host['hostname'], false, [], true).subscribe(() => {
+ this.isExecuting = false;
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`"${host.hostname}" has exited maintenance`
+ );
+ this.table.refreshBtn();
+ });
+ }
+ }
+
+ hostDrain(stop = false) {
+ const host = this.selection.first();
+ if (stop) {
+ const index = host['labels'].indexOf('_no_schedule', 0);
+ host['labels'].splice(index, 1);
+ this.hostService.update(host['hostname'], true, host['labels']).subscribe(() => {
+ this.notificationService.show(
+ NotificationType.info,
+ $localize`"${host['hostname']}" stopped draining`
+ );
+ this.table.refreshBtn();
+ });
+ } else {
+ this.hostService.update(host['hostname'], false, [], false, false, true).subscribe(() => {
+ this.notificationService.show(
+ NotificationType.info,
+ $localize`"${host['hostname']}" started draining`
+ );
+ this.table.refreshBtn();
+ });
+ }
+ }
+
+ getDisable(
+ action: 'add' | 'edit' | 'remove' | 'maintenance' | 'drain',
+ selection: CdTableSelection
+ ): boolean | string {
+ if (
+ action === 'remove' ||
+ action === 'edit' ||
+ action === 'maintenance' ||
+ action === 'drain'
+ ) {
+ if (!selection?.hasSingleSelection) {
+ return true;
+ }
+ if (!_.every(selection.selected, 'sources.orchestrator')) {
+ return this.messages.nonOrchHost;
+ }
+ }
+ return this.orchService.getTableActionDisableDesc(
+ this.orchStatus,
+ this.actionOrchFeatures[action]
+ );
+ }
+
+ deleteAction() {
+ const hostname = this.selection.first().hostname;
+ this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: 'Host',
+ itemNames: [hostname],
+ actionDescription: 'remove',
+ submitActionObservable: () =>
+ this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('host/remove', { hostname: hostname }),
+ call: this.hostService.delete(hostname)
+ })
+ });
+ }
+
+ checkHostsFactsAvailable() {
+ const orchFeatures = this.orchStatus.features;
+ if (!_.isEmpty(orchFeatures)) {
+ if (orchFeatures.get_facts.available) {
+ return true;
+ }
+ return false;
+ }
+ return false;
+ }
+
+ transformHostsData() {
+ if (this.checkHostsFactsAvailable()) {
+ _.forEach(this.hosts, (hostKey) => {
+ hostKey['memory_total_bytes'] = hostKey['memory_total_kb'] * 1024;
+ hostKey['raw_capacity'] = hostKey['hdd_capacity_bytes'] + hostKey['flash_capacity_bytes'];
+ });
+ } else {
+ // mark host facts columns unavailable
+ for (let column = 4; column < this.columns.length; column++) {
+ this.columns[column]['cellTemplate'] = this.orchTmpl;
+ }
+ }
+ }
+
+ getHosts(context: CdTableFetchDataContext) {
+ if (this.isLoadingHosts) {
+ return;
+ }
+ this.isLoadingHosts = true;
+ this.sub = this.orchService
+ .status()
+ .pipe(
+ mergeMap((orchStatus) => {
+ this.orchStatus = orchStatus;
+ const factsAvailable = this.checkHostsFactsAvailable();
+ return this.hostService.list(`${factsAvailable}`);
+ }),
+ map((hostList: object[]) =>
+ hostList.map((host) => {
+ const counts = {};
+ host['service_instances'] = new Set<string>();
+ if (this.orchStatus?.available) {
+ let daemons: Daemon[] = [];
+ let observable: Observable<Daemon[]>;
+ observable = this.hostService.getDaemons(host['hostname']);
+ observable.subscribe((dmns: Daemon[]) => {
+ daemons = dmns;
+ daemons.forEach((daemon: any) => {
+ counts[daemon.daemon_type] = (counts[daemon.daemon_type] || 0) + 1;
+ });
+ daemons.map((daemon: any) => {
+ host['service_instances'].add(
+ `${daemon.daemon_type}: ${counts[daemon.daemon_type]}`
+ );
+ });
+ });
+ } else {
+ host['services'].forEach((service: any) => {
+ counts[service.type] = (counts[service.type] || 0) + 1;
+ });
+ host['services'].map((service: any) => {
+ host['service_instances'].add(`${service.type}: ${counts[service.type]}`);
+ });
+ }
+ return host;
+ })
+ )
+ )
+ .subscribe(
+ (hostList) => {
+ this.hosts = hostList;
+ this.transformHostsData();
+ this.isLoadingHosts = false;
+ },
+ () => {
+ this.isLoadingHosts = false;
+ context.error();
+ }
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/fixtures/inventory_list_response.json b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/fixtures/inventory_list_response.json
new file mode 100644
index 000000000..8a6986a35
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/fixtures/inventory_list_response.json
@@ -0,0 +1,324 @@
+[
+ {
+ "name": "mgr0",
+ "addr": "mgr0",
+ "devices": [
+ {
+ "rejected_reasons": [],
+ "available": true,
+ "path": "/dev/sda",
+ "sys_api": {
+ "removable": "0",
+ "ro": "0",
+ "vendor": "ATA",
+ "model": "QEMU HARDDISK",
+ "rev": "2.5+",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "support_discard": "512",
+ "rotational": "0",
+ "nr_requests": "64",
+ "scheduler_mode": "mq-deadline",
+ "partitions": {},
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 10737418240.0,
+ "human_readable_size": "10.00 GB",
+ "path": "/dev/sda",
+ "locked": 0
+ },
+ "lvs": [],
+ "human_readable_type": "ssd",
+ "device_id": "QEMU_HARDDISK_mgr0-1-ssd",
+ "osd_ids": []
+ },
+ {
+ "rejected_reasons": [],
+ "available": true,
+ "path": "/dev/sdb",
+ "sys_api": {
+ "removable": "0",
+ "ro": "0",
+ "vendor": "ATA",
+ "model": "QEMU HARDDISK",
+ "rev": "2.5+",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "support_discard": "512",
+ "rotational": "0",
+ "nr_requests": "64",
+ "scheduler_mode": "mq-deadline",
+ "partitions": {},
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 10737418240.0,
+ "human_readable_size": "10.00 GB",
+ "path": "/dev/sdb",
+ "locked": 0
+ },
+ "lvs": [],
+ "human_readable_type": "ssd",
+ "device_id": "QEMU_HARDDISK_mgr0-2-ssd",
+ "osd_ids": []
+ },
+ {
+ "rejected_reasons": [],
+ "available": true,
+ "path": "/dev/sdc",
+ "sys_api": {
+ "removable": "0",
+ "ro": "0",
+ "vendor": "ATA",
+ "model": "QEMU HARDDISK",
+ "rev": "2.5+",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "support_discard": "512",
+ "rotational": "1",
+ "nr_requests": "64",
+ "scheduler_mode": "mq-deadline",
+ "partitions": {},
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 21474836480.0,
+ "human_readable_size": "20.00 GB",
+ "path": "/dev/sdc",
+ "locked": 0
+ },
+ "lvs": [],
+ "human_readable_type": "hdd",
+ "device_id": "QEMU_HARDDISK_mgr0-3-hdd",
+ "osd_ids": []
+ },
+ {
+ "rejected_reasons": [],
+ "available": true,
+ "path": "/dev/sdd",
+ "sys_api": {
+ "removable": "0",
+ "ro": "0",
+ "vendor": "ATA",
+ "model": "QEMU HARDDISK",
+ "rev": "2.5+",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "support_discard": "512",
+ "rotational": "1",
+ "nr_requests": "64",
+ "scheduler_mode": "mq-deadline",
+ "partitions": {},
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 21474836480.0,
+ "human_readable_size": "20.00 GB",
+ "path": "/dev/sdd",
+ "locked": 0
+ },
+ "lvs": [],
+ "human_readable_type": "hdd",
+ "device_id": "QEMU_HARDDISK_mgr0-4-hdd",
+ "osd_ids": []
+ },
+ {
+ "rejected_reasons": ["locked"],
+ "available": false,
+ "path": "/dev/vda",
+ "sys_api": {
+ "removable": "0",
+ "ro": "0",
+ "vendor": "0x1af4",
+ "model": "",
+ "rev": "",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "support_discard": "0",
+ "rotational": "1",
+ "nr_requests": "256",
+ "scheduler_mode": "mq-deadline",
+ "partitions": {
+ "vda1": {
+ "start": "2048",
+ "sectors": "20969472",
+ "sectorsize": 512,
+ "size": 10736369664.0,
+ "human_readable_size": "10.00 GB",
+ "holders": []
+ }
+ },
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 11811160064.0,
+ "human_readable_size": "11.00 GB",
+ "path": "/dev/vda",
+ "locked": 1
+ },
+ "lvs": [],
+ "human_readable_type": "hdd",
+ "device_id": "",
+ "osd_ids": []
+ }
+ ],
+ "labels": []
+ },
+ {
+ "name": "osd0",
+ "addr": "osd0",
+ "devices": [
+ {
+ "rejected_reasons": [],
+ "available": true,
+ "path": "/dev/sda",
+ "sys_api": {
+ "removable": "0",
+ "ro": "0",
+ "vendor": "ATA",
+ "model": "QEMU HARDDISK",
+ "rev": "2.5+",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "support_discard": "512",
+ "rotational": "0",
+ "nr_requests": "64",
+ "scheduler_mode": "mq-deadline",
+ "partitions": {},
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 10737418240.0,
+ "human_readable_size": "10.00 GB",
+ "path": "/dev/sda",
+ "locked": 0
+ },
+ "lvs": [],
+ "human_readable_type": "ssd",
+ "device_id": "QEMU_HARDDISK_osd0-1-ssd",
+ "osd_ids": []
+ },
+ {
+ "rejected_reasons": [],
+ "available": true,
+ "path": "/dev/sdb",
+ "sys_api": {
+ "removable": "0",
+ "ro": "0",
+ "vendor": "ATA",
+ "model": "QEMU HARDDISK",
+ "rev": "2.5+",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "support_discard": "512",
+ "rotational": "0",
+ "nr_requests": "64",
+ "scheduler_mode": "mq-deadline",
+ "partitions": {},
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 10737418240.0,
+ "human_readable_size": "10.00 GB",
+ "path": "/dev/sdb",
+ "locked": 0
+ },
+ "lvs": [],
+ "human_readable_type": "ssd",
+ "device_id": "QEMU_HARDDISK_osd0-2-ssd",
+ "osd_ids": []
+ },
+ {
+ "rejected_reasons": [],
+ "available": true,
+ "path": "/dev/sdc",
+ "sys_api": {
+ "removable": "0",
+ "ro": "0",
+ "vendor": "ATA",
+ "model": "QEMU HARDDISK",
+ "rev": "2.5+",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "support_discard": "512",
+ "rotational": "1",
+ "nr_requests": "64",
+ "scheduler_mode": "mq-deadline",
+ "partitions": {},
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 21474836480.0,
+ "human_readable_size": "20.00 GB",
+ "path": "/dev/sdc",
+ "locked": 0
+ },
+ "lvs": [],
+ "human_readable_type": "hdd",
+ "device_id": "QEMU_HARDDISK_osd0-3-hdd",
+ "osd_ids": []
+ },
+ {
+ "rejected_reasons": [],
+ "available": true,
+ "path": "/dev/sdd",
+ "sys_api": {
+ "removable": "0",
+ "ro": "0",
+ "vendor": "ATA",
+ "model": "QEMU HARDDISK",
+ "rev": "2.5+",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "support_discard": "512",
+ "rotational": "1",
+ "nr_requests": "64",
+ "scheduler_mode": "mq-deadline",
+ "partitions": {},
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 21474836480.0,
+ "human_readable_size": "20.00 GB",
+ "path": "/dev/sdd",
+ "locked": 0
+ },
+ "lvs": [],
+ "human_readable_type": "hdd",
+ "device_id": "QEMU_HARDDISK_osd0-4-hdd",
+ "osd_ids": []
+ },
+ {
+ "rejected_reasons": ["locked"],
+ "available": false,
+ "path": "/dev/vda",
+ "sys_api": {
+ "removable": "0",
+ "ro": "0",
+ "vendor": "0x1af4",
+ "model": "",
+ "rev": "",
+ "sas_address": "",
+ "sas_device_handle": "",
+ "support_discard": "0",
+ "rotational": "1",
+ "nr_requests": "256",
+ "scheduler_mode": "mq-deadline",
+ "partitions": {
+ "vda1": {
+ "start": "2048",
+ "sectors": "20969472",
+ "sectorsize": 512,
+ "size": 10736369664.0,
+ "human_readable_size": "10.00 GB",
+ "holders": []
+ }
+ },
+ "sectors": 0,
+ "sectorsize": "512",
+ "size": 11811160064.0,
+ "human_readable_size": "11.00 GB",
+ "path": "/dev/vda",
+ "locked": 1
+ },
+ "lvs": [],
+ "human_readable_type": "hdd",
+ "device_id": "",
+ "osd_ids": []
+ }
+ ],
+ "labels": []
+ }
+]
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-device.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-device.model.ts
new file mode 100644
index 000000000..4af9137de
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-device.model.ts
@@ -0,0 +1,20 @@
+export class SysAPI {
+ vendor: string;
+ model: string;
+ size: number;
+ rotational: string;
+ human_readable_size: string;
+}
+
+export class InventoryDevice {
+ hostname: string;
+ uid: string;
+
+ path: string;
+ sys_api: SysAPI;
+ available: boolean;
+ rejected_reasons: string[];
+ device_id: string;
+ human_readable_type: string;
+ osd_ids: number[];
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.html
new file mode 100644
index 000000000..54cee708d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.html
@@ -0,0 +1,16 @@
+<cd-table [data]="devices"
+ [columns]="columns"
+ identifier="uid"
+ [forceIdentifier]="true"
+ [selectionType]="selectionType"
+ columnMode="flex"
+ (fetchData)="getDevices()"
+ [searchField]="false"
+ (updateSelection)="updateSelection($event)"
+ (columnFiltersChanged)="onColumnFiltersChanged($event)">
+ <cd-table-actions class="table-actions"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+</cd-table>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.scss
new file mode 100644
index 000000000..e2eb0350c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.scss
@@ -0,0 +1,12 @@
+.filter {
+ padding-right: 8px;
+}
+
+.fa-stack {
+ font-size: 0.79rem;
+
+ .fa-stack-1x {
+ margin-left: 8px;
+ margin-top: 5px;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.spec.ts
new file mode 100644
index 000000000..29a3ece96
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.spec.ts
@@ -0,0 +1,194 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule } from '@angular/forms';
+import { By } from '@angular/platform-browser';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+
+import { HostService } from '~/app/shared/api/host.service';
+import { OrchestratorService } from '~/app/shared/api/orchestrator.service';
+import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { OrchestratorFeature } from '~/app/shared/models/orchestrator.enum';
+import { OrchestratorStatus } from '~/app/shared/models/orchestrator.interface';
+import { Permissions } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { InventoryDevicesComponent } from './inventory-devices.component';
+
+describe('InventoryDevicesComponent', () => {
+ let component: InventoryDevicesComponent;
+ let fixture: ComponentFixture<InventoryDevicesComponent>;
+ let orchService: OrchestratorService;
+ let hostService: HostService;
+
+ const fakeAuthStorageService = {
+ getPermissions: () => {
+ return new Permissions({ osd: ['read', 'update', 'create', 'delete'] });
+ }
+ };
+
+ const mockOrchStatus = (available: boolean, features?: OrchestratorFeature[]) => {
+ const orchStatus: OrchestratorStatus = { available: available, message: '', features: {} };
+ if (features) {
+ features.forEach((feature: OrchestratorFeature) => {
+ orchStatus.features[feature] = { available: true };
+ });
+ }
+ component.orchStatus = orchStatus;
+ };
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ FormsModule,
+ HttpClientTestingModule,
+ SharedModule,
+ RouterTestingModule,
+ ToastrModule.forRoot()
+ ],
+ providers: [
+ { provide: AuthStorageService, useValue: fakeAuthStorageService },
+ TableActionsComponent
+ ],
+ declarations: [InventoryDevicesComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(InventoryDevicesComponent);
+ component = fixture.componentInstance;
+ hostService = TestBed.inject(HostService);
+ orchService = TestBed.inject(OrchestratorService);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should have columns that are sortable', () => {
+ expect(component.columns.every((column) => Boolean(column.prop))).toBeTruthy();
+ });
+
+ it('should call inventoryDataList only when showOnlyAvailableData is true', () => {
+ const hostServiceSpy = spyOn(hostService, 'inventoryDeviceList').and.callThrough();
+ component.getDevices();
+ expect(hostServiceSpy).toBeCalledTimes(0);
+ component.showAvailDeviceOnly = true;
+ component.getDevices();
+ expect(hostServiceSpy).toBeCalledTimes(1);
+ });
+
+ describe('table actions', () => {
+ const fakeDevices = require('./fixtures/inventory_list_response.json');
+
+ beforeEach(() => {
+ component.devices = fakeDevices;
+ component.selectionType = 'single';
+ fixture.detectChanges();
+ });
+
+ const verifyTableActions = async (
+ tableActions: CdTableAction[],
+ expectResult: {
+ [action: string]: { disabled: boolean; disableDesc: string };
+ }
+ ) => {
+ fixture.detectChanges();
+ await fixture.whenStable();
+ const tableActionElement = fixture.debugElement.query(By.directive(TableActionsComponent));
+ // There is actually only one action for now
+ const actions = {};
+ tableActions.forEach((action) => {
+ const actionElement = tableActionElement.query(By.css('button'));
+ actions[action.name] = {
+ disabled: actionElement.classes.disabled,
+ disableDesc: actionElement.properties.title
+ };
+ });
+ expect(actions).toEqual(expectResult);
+ };
+
+ const testTableActions = async (
+ orch: boolean,
+ features: OrchestratorFeature[],
+ tests: { selectRow?: number; expectResults: any }[]
+ ) => {
+ mockOrchStatus(orch, features);
+ fixture.detectChanges();
+ await fixture.whenStable();
+
+ for (const test of tests) {
+ if (test.selectRow) {
+ component.selection = new CdTableSelection();
+ component.selection.selected = [test.selectRow];
+ }
+ await verifyTableActions(component.tableActions, test.expectResults);
+ }
+ };
+
+ it('should have correct states when Orchestrator is enabled', async () => {
+ const tests = [
+ {
+ expectResults: {
+ Identify: { disabled: true, disableDesc: '' }
+ }
+ },
+ {
+ selectRow: fakeDevices[0],
+ expectResults: {
+ Identify: { disabled: false, disableDesc: '' }
+ }
+ }
+ ];
+
+ const features = [OrchestratorFeature.DEVICE_BLINK_LIGHT];
+ await testTableActions(true, features, tests);
+ });
+
+ it('should have correct states when Orchestrator is disabled', async () => {
+ const resultNoOrchestrator = {
+ disabled: true,
+ disableDesc: orchService.disableMessages.noOrchestrator
+ };
+ const tests = [
+ {
+ expectResults: {
+ Identify: { disabled: true, disableDesc: '' }
+ }
+ },
+ {
+ selectRow: fakeDevices[0],
+ expectResults: {
+ Identify: resultNoOrchestrator
+ }
+ }
+ ];
+ await testTableActions(false, [], tests);
+ });
+
+ it('should have correct states when Orchestrator features are missing', async () => {
+ const resultMissingFeatures = {
+ disabled: true,
+ disableDesc: orchService.disableMessages.missingFeature
+ };
+ const expectResults = [
+ {
+ expectResults: {
+ Identify: { disabled: true, disableDesc: '' }
+ }
+ },
+ {
+ selectRow: fakeDevices[0],
+ expectResults: {
+ Identify: resultMissingFeatures
+ }
+ }
+ ];
+ await testTableActions(true, [], expectResults);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts
new file mode 100644
index 000000000..e0d82cb19
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts
@@ -0,0 +1,254 @@
+import {
+ Component,
+ EventEmitter,
+ Input,
+ OnDestroy,
+ OnInit,
+ Output,
+ ViewChild
+} from '@angular/core';
+
+import _ from 'lodash';
+import { Subscription } from 'rxjs';
+
+import { HostService } from '~/app/shared/api/host.service';
+import { OrchestratorService } from '~/app/shared/api/orchestrator.service';
+import { FormModalComponent } from '~/app/shared/components/form-modal/form-modal.component';
+import { TableComponent } from '~/app/shared/datatable/table/table.component';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableColumnFiltersChange } from '~/app/shared/models/cd-table-column-filters-change';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { OrchestratorFeature } from '~/app/shared/models/orchestrator.enum';
+import { OrchestratorStatus } from '~/app/shared/models/orchestrator.interface';
+import { Permission } from '~/app/shared/models/permissions';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { InventoryDevice } from './inventory-device.model';
+
+@Component({
+ selector: 'cd-inventory-devices',
+ templateUrl: './inventory-devices.component.html',
+ styleUrls: ['./inventory-devices.component.scss']
+})
+export class InventoryDevicesComponent implements OnInit, OnDestroy {
+ @ViewChild(TableComponent, { static: true })
+ table: TableComponent;
+
+ // Devices
+ @Input() devices: InventoryDevice[] = [];
+
+ @Input() showAvailDeviceOnly = false;
+ // Do not display these columns
+ @Input() hiddenColumns: string[] = [];
+
+ // Show filters for these columns, specify empty array to disable
+ @Input() filterColumns = [
+ 'hostname',
+ 'human_readable_type',
+ 'available',
+ 'sys_api.vendor',
+ 'sys_api.model',
+ 'sys_api.size'
+ ];
+
+ // Device table row selection type
+ @Input() selectionType: string = undefined;
+
+ @Output() filterChange = new EventEmitter<CdTableColumnFiltersChange>();
+
+ @Output() fetchInventory = new EventEmitter();
+
+ icons = Icons;
+ columns: Array<CdTableColumn> = [];
+ selection: CdTableSelection = new CdTableSelection();
+ permission: Permission;
+ tableActions: CdTableAction[];
+ fetchInventorySub: Subscription;
+
+ @Input() orchStatus: OrchestratorStatus = undefined;
+
+ actionOrchFeatures = {
+ identify: [OrchestratorFeature.DEVICE_BLINK_LIGHT]
+ };
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private dimlessBinary: DimlessBinaryPipe,
+ private modalService: ModalService,
+ private notificationService: NotificationService,
+ private orchService: OrchestratorService,
+ private hostService: HostService
+ ) {}
+
+ ngOnInit() {
+ this.permission = this.authStorageService.getPermissions().osd;
+ this.tableActions = [
+ {
+ permission: 'update',
+ icon: Icons.show,
+ click: () => this.identifyDevice(),
+ name: $localize`Identify`,
+ disable: (selection: CdTableSelection) => this.getDisable('identify', selection),
+ canBePrimary: (selection: CdTableSelection) => !selection.hasSingleSelection,
+ visible: () => _.isString(this.selectionType)
+ }
+ ];
+ const columns = [
+ {
+ name: $localize`Hostname`,
+ prop: 'hostname',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Device path`,
+ prop: 'path',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Type`,
+ prop: 'human_readable_type',
+ flexGrow: 1,
+ cellTransformation: CellTemplate.badge,
+ customTemplateConfig: {
+ map: {
+ hdd: { value: 'HDD', class: 'badge-hdd' },
+ ssd: { value: 'SSD', class: 'badge-ssd' }
+ }
+ }
+ },
+ {
+ name: $localize`Available`,
+ prop: 'available',
+ flexGrow: 1,
+ cellClass: 'text-center',
+ cellTransformation: CellTemplate.checkIcon
+ },
+ {
+ name: $localize`Vendor`,
+ prop: 'sys_api.vendor',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Model`,
+ prop: 'sys_api.model',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Size`,
+ prop: 'sys_api.size',
+ flexGrow: 1,
+ pipe: this.dimlessBinary
+ },
+ {
+ name: $localize`OSDs`,
+ prop: 'osd_ids',
+ flexGrow: 1,
+ cellTransformation: CellTemplate.badge,
+ customTemplateConfig: {
+ class: 'badge-dark',
+ prefix: 'osd.'
+ }
+ }
+ ];
+
+ this.columns = columns.filter((col: any) => {
+ return !this.hiddenColumns.includes(col.prop);
+ });
+
+ // init column filters
+ _.forEach(this.filterColumns, (prop) => {
+ const col = _.find(this.columns, { prop: prop });
+ if (col) {
+ col.filterable = true;
+ }
+ });
+
+ if (this.fetchInventory.observers.length > 0) {
+ this.fetchInventorySub = this.table.fetchData.subscribe(() => {
+ this.fetchInventory.emit();
+ });
+ }
+ }
+
+ getDevices() {
+ if (this.showAvailDeviceOnly) {
+ this.hostService.inventoryDeviceList().subscribe(
+ (devices: InventoryDevice[]) => {
+ this.devices = _.filter(devices, 'available');
+ this.devices = [...this.devices];
+ },
+ () => {
+ this.devices = [];
+ }
+ );
+ } else {
+ this.devices = [...this.devices];
+ }
+ }
+
+ ngOnDestroy() {
+ if (this.fetchInventorySub) {
+ this.fetchInventorySub.unsubscribe();
+ }
+ }
+
+ onColumnFiltersChanged(event: CdTableColumnFiltersChange) {
+ this.filterChange.emit(event);
+ }
+
+ getDisable(action: 'identify', selection: CdTableSelection): boolean | string {
+ if (!selection.hasSingleSelection) {
+ return true;
+ }
+ return this.orchService.getTableActionDisableDesc(
+ this.orchStatus,
+ this.actionOrchFeatures[action]
+ );
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ identifyDevice() {
+ const selected = this.selection.first();
+ const hostname = selected.hostname;
+ const device = selected.path || selected.device_id;
+ this.modalService.show(FormModalComponent, {
+ titleText: $localize`Identify device ${device}`,
+ message: $localize`Please enter the duration how long to blink the LED.`,
+ fields: [
+ {
+ type: 'select',
+ name: 'duration',
+ value: 300,
+ required: true,
+ typeConfig: {
+ options: [
+ { text: $localize`1 minute`, value: 60 },
+ { text: $localize`2 minutes`, value: 120 },
+ { text: $localize`5 minutes`, value: 300 },
+ { text: $localize`10 minutes`, value: 600 },
+ { text: $localize`15 minutes`, value: 900 }
+ ]
+ }
+ }
+ ],
+ submitButtonText: $localize`Execute`,
+ onSubmit: (values: any) => {
+ this.hostService.identifyDevice(hostname, device, values.duration).subscribe(() => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Identifying '${device}' started on host '${hostname}'`
+ );
+ });
+ }
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-host.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-host.model.ts
new file mode 100644
index 000000000..22400113a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-host.model.ts
@@ -0,0 +1,6 @@
+import { InventoryDevice } from './inventory-devices/inventory-device.model';
+
+export class InventoryHost {
+ name: string;
+ devices: InventoryDevice[];
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.html
new file mode 100644
index 000000000..6ba0b7002
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.html
@@ -0,0 +1,14 @@
+<cd-orchestrator-doc-panel *ngIf="showDocPanel"></cd-orchestrator-doc-panel>
+<ng-container *ngIf="orchStatus?.available">
+ <legend i18n>Physical Disks</legend>
+ <div class="row">
+ <div class="col-md-12">
+ <cd-inventory-devices [devices]="devices"
+ [hiddenColumns]="hostname === undefined ? [] : ['hostname']"
+ selectionType="single"
+ (fetchInventory)="refresh()"
+ [orchStatus]="orchStatus">
+ </cd-inventory-devices>
+ </div>
+ </div>
+</ng-container>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.spec.ts
new file mode 100644
index 000000000..dd60f7959
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.spec.ts
@@ -0,0 +1,67 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule } from '@angular/forms';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { HostService } from '~/app/shared/api/host.service';
+import { OrchestratorService } from '~/app/shared/api/orchestrator.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { InventoryDevicesComponent } from './inventory-devices/inventory-devices.component';
+import { InventoryComponent } from './inventory.component';
+
+describe('InventoryComponent', () => {
+ let component: InventoryComponent;
+ let fixture: ComponentFixture<InventoryComponent>;
+ let orchService: OrchestratorService;
+ let hostService: HostService;
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ FormsModule,
+ SharedModule,
+ HttpClientTestingModule,
+ RouterTestingModule,
+ ToastrModule.forRoot()
+ ],
+ declarations: [InventoryComponent, InventoryDevicesComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(InventoryComponent);
+ component = fixture.componentInstance;
+ orchService = TestBed.inject(OrchestratorService);
+ hostService = TestBed.inject(HostService);
+ spyOn(orchService, 'status').and.returnValue(of({ available: true }));
+ spyOn(hostService, 'inventoryDeviceList').and.callThrough();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should not display doc panel if orchestrator is available', () => {
+ expect(component.showDocPanel).toBeFalsy();
+ });
+
+ describe('after ngOnInit', () => {
+ it('should load devices', () => {
+ fixture.detectChanges();
+ component.refresh(); // click refresh button
+ expect(hostService.inventoryDeviceList).toHaveBeenNthCalledWith(1, undefined, false);
+
+ const newHost = 'host0';
+ component.hostname = newHost;
+ fixture.detectChanges();
+ component.ngOnChanges();
+ expect(hostService.inventoryDeviceList).toHaveBeenNthCalledWith(2, newHost, false);
+ component.refresh(); // click refresh button
+ expect(hostService.inventoryDeviceList).toHaveBeenNthCalledWith(3, newHost, true);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.ts
new file mode 100644
index 000000000..a60f5d698
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.ts
@@ -0,0 +1,90 @@
+import { Component, Input, NgZone, OnChanges, OnDestroy, OnInit } from '@angular/core';
+
+import { Subscription, timer as observableTimer } from 'rxjs';
+
+import { HostService } from '~/app/shared/api/host.service';
+import { OrchestratorService } from '~/app/shared/api/orchestrator.service';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { OrchestratorStatus } from '~/app/shared/models/orchestrator.interface';
+import { InventoryDevice } from './inventory-devices/inventory-device.model';
+
+@Component({
+ selector: 'cd-inventory',
+ templateUrl: './inventory.component.html',
+ styleUrls: ['./inventory.component.scss']
+})
+export class InventoryComponent implements OnChanges, OnInit, OnDestroy {
+ // Display inventory page only for this hostname, ignore to display all.
+ @Input() hostname?: string;
+
+ private reloadSubscriber: Subscription;
+ private reloadInterval = 5000;
+ private firstRefresh = true;
+
+ icons = Icons;
+
+ orchStatus: OrchestratorStatus;
+ showDocPanel = false;
+
+ devices: Array<InventoryDevice> = [];
+
+ constructor(
+ private orchService: OrchestratorService,
+ private hostService: HostService,
+ private ngZone: NgZone
+ ) {}
+
+ ngOnInit() {
+ this.orchService.status().subscribe((status) => {
+ this.orchStatus = status;
+ this.showDocPanel = !status.available;
+ if (status.available) {
+ // Create a timer to get cached inventory from the orchestrator.
+ // Do not ask the orchestrator frequently to refresh its cache data because it's expensive.
+ this.ngZone.runOutsideAngular(() => {
+ // start after first pass because the embedded table calls refresh at init.
+ this.reloadSubscriber = observableTimer(
+ this.reloadInterval,
+ this.reloadInterval
+ ).subscribe(() => {
+ this.ngZone.run(() => {
+ this.getInventory(false);
+ });
+ });
+ });
+ }
+ });
+ }
+
+ ngOnDestroy() {
+ this.reloadSubscriber?.unsubscribe();
+ }
+
+ ngOnChanges() {
+ if (this.orchStatus?.available) {
+ this.devices = [];
+ this.getInventory(false);
+ }
+ }
+
+ getInventory(refresh: boolean) {
+ if (this.hostname === '') {
+ return;
+ }
+ this.hostService.inventoryDeviceList(this.hostname, refresh).subscribe(
+ (devices: InventoryDevice[]) => {
+ this.devices = devices;
+ },
+ () => {
+ this.devices = [];
+ }
+ );
+ }
+
+ refresh() {
+ // Make the first reload (triggered by table) use cached data, and
+ // the remaining reloads (triggered by users) ask orchestrator to refresh inventory.
+ this.getInventory(!this.firstRefresh);
+ this.firstRefresh = false;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.html
new file mode 100644
index 000000000..dd55a678f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.html
@@ -0,0 +1,159 @@
+<div *ngIf="contentData">
+ <ng-container *ngTemplateOutlet="logFiltersTpl"></ng-container>
+
+ <ul ngbNav
+ #nav="ngbNav"
+ class="nav-tabs"
+ cdStatefulTab="logs">
+ <li ngbNavItem="cluster-logs">
+ <a ngbNavLink
+ i18n>Cluster Logs</a>
+ <ng-template ngbNavContent>
+ <div class="card bg-light mb-3"
+ *ngIf="clog">
+ <div class="btn-group"
+ role="group"
+ *ngIf="clog.length">
+ <cd-download-button [objectItem]="clog"
+ [textItem]="clogText"
+ fileName="cluster_log">
+ </cd-download-button>
+ <cd-copy-2-clipboard-button
+ [source]="clogText"
+ [byId]="false">
+ </cd-copy-2-clipboard-button>
+ </div>
+ <div class="card-body">
+ <p *ngFor="let line of clog">
+ <span class="timestamp">{{ line.stamp | cdDate }}</span>
+ <span class="priority {{ line.priority | logPriority }}">{{ line.priority }}</span>
+ <span class="message"
+ [innerHTML]="line.message | searchHighlight: search"></span>
+ </p>
+
+ <ng-container *ngIf="clog.length != 0 else noEntriesTpl"></ng-container>
+ </div>
+ </div>
+ </ng-template>
+ </li>
+ <li ngbNavItem="audit-logs">
+ <a ngbNavLink
+ i18n>Audit Logs</a>
+ <ng-template ngbNavContent>
+ <div class="card bg-light mb-3"
+ *ngIf="audit_log">
+ <div class="btn-group"
+ role="group"
+ *ngIf="audit_log.length">
+ <cd-download-button [objectItem]="audit_log"
+ [textItem]="auditLogText"
+ fileName="audit_log">
+ </cd-download-button>
+ <cd-copy-2-clipboard-button
+ [source]="auditLogText"
+ [byId]="false">
+ </cd-copy-2-clipboard-button>
+ </div>
+ <div class="card-body">
+ <p *ngFor="let line of audit_log">
+ <span class="timestamp">{{ line.stamp | cdDate }}</span>
+ <span class="priority {{ line.priority | logPriority }}">{{ line.priority }}</span>
+ <span class="message"
+ [innerHTML]="line.message | searchHighlight: search"></span>
+ </p>
+
+ <ng-container *ngIf="audit_log.length != 0 else noEntriesTpl"></ng-container>
+ </div>
+ </div>
+ </ng-template>
+ </li>
+ </ul>
+
+ <div [ngbNavOutlet]="nav"></div>
+</div>
+
+<ng-template #logFiltersTpl>
+ <div class="form-inline">
+ <div class="form-group">
+ <label for="logs-priority"
+ i18n>Priority:</label>
+ <select id="logs-priority"
+ class="form-control"
+ [(ngModel)]="priority"
+ (ngModelChange)="filterLogs()">
+ <option *ngFor="let prio of priorities"
+ [value]="prio.value">{{ prio.name }}</option>
+ </select>
+ </div>
+
+ <div class="form-group">
+ <label for="logs-keyword"
+ i18n>Keyword:</label>
+ <div class="input-group">
+ <div class="input-group-prepend">
+ <span class="input-group-text">
+ <i [ngClass]="[icons.search]"></i>
+ </span>
+ </div>
+
+ <input class="form-control"
+ id="logs-keyword"
+ type="text"
+ [(ngModel)]="search"
+ (keyup)="filterLogs()">
+
+ <div class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ (click)="clearSearchKey()">
+ <i class="icon-prepend {{ icons.destroy }}"></i>
+ </button>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="logs-date"
+ i18n>Date:</label>
+ <div class="input-group">
+ <input class="form-control"
+ id="logs-date"
+ placeholder="YYYY-MM-DD"
+ ngbDatepicker
+ [maxDate]="maxDate"
+ #d="ngbDatepicker"
+ (click)="d.open()"
+ [(ngModel)]="selectedDate"
+ (ngModelChange)="filterLogs()">
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ (click)="clearDate()">
+ <i class="icon-prepend {{ icons.destroy }}"></i>
+ </button>
+ </span>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label i18n>Time range:</label>
+ <ngb-timepicker [spinners]="false"
+ [(ngModel)]="startTime"
+ (ngModelChange)="filterLogs()"></ngb-timepicker>
+
+ <span>&nbsp;&mdash;&nbsp;</span>
+
+ <ngb-timepicker [spinners]="false"
+ [(ngModel)]="endTime"
+ (ngModelChange)="filterLogs()"></ngb-timepicker>
+ </div>
+ </div>
+</ng-template>
+
+<ng-template #noEntriesTpl>
+ <span i18n>No log entries found. Please try to select different filter options.</span>
+ <span>&nbsp;</span>
+ <a href="#"
+ (click)="resetFilter()"
+ i18n>Reset filter.</a>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.scss
new file mode 100644
index 000000000..54ab44250
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.scss
@@ -0,0 +1,54 @@
+@use './src/styles/vendor/variables' as vv;
+
+p {
+ font-family: monospace;
+}
+
+.card {
+ .btn-group {
+ margin-top: -45px;
+ position: absolute;
+ right: 0;
+ }
+
+ div p {
+ display: flex;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .timestamp {
+ flex-shrink: 0;
+ font-weight: bold;
+ }
+
+ .priority {
+ margin-left: 0.5rem;
+ }
+
+ .message {
+ margin-left: 1rem;
+ }
+
+ .err {
+ color: vv.$danger;
+ }
+
+ .warn {
+ color: vv.$warning;
+ }
+
+ .info {
+ color: vv.$info;
+ }
+
+ .debug {
+ color: vv.$gray-700;
+ }
+}
+
+::ng-deep cd-logs ngb-timepicker input.ngb-tp-input {
+ width: 3.5rem !important;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.spec.ts
new file mode 100644
index 000000000..69c6051d2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.spec.ts
@@ -0,0 +1,169 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule } from '@angular/forms';
+
+import { NgbDatepickerModule, NgbNavModule, NgbTimepickerModule } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { LogsService } from '~/app/shared/api/logs.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { LogsComponent } from './logs.component';
+
+describe('LogsComponent', () => {
+ let component: LogsComponent;
+ let fixture: ComponentFixture<LogsComponent>;
+ let logsService: LogsService;
+ let logsServiceSpy: jasmine.Spy;
+
+ configureTestBed({
+ imports: [
+ HttpClientTestingModule,
+ NgbNavModule,
+ SharedModule,
+ FormsModule,
+ NgbDatepickerModule,
+ NgbTimepickerModule,
+ ToastrModule.forRoot()
+ ],
+ declarations: [LogsComponent]
+ });
+
+ beforeEach(() => {
+ logsService = TestBed.inject(LogsService);
+ logsServiceSpy = spyOn(logsService, 'getLogs');
+ logsServiceSpy.and.returnValue(of(null));
+ fixture = TestBed.createComponent(LogsComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('abstractFilters', () => {
+ it('after initialized', () => {
+ const filters = component.abstractFilters();
+ expect(filters.priority).toBe('All');
+ expect(filters.key).toBe('');
+ expect(filters.yearMonthDay).toBe('');
+ expect(filters.sTime).toBe(0);
+ expect(filters.eTime).toBe(1439);
+ });
+ it('change date', () => {
+ component.selectedDate = { year: 2019, month: 1, day: 1 };
+ component.startTime = { hour: 1, minute: 10 };
+ component.endTime = { hour: 12, minute: 10 };
+ const filters = component.abstractFilters();
+ expect(filters.yearMonthDay).toBe('2019-01-01');
+ expect(filters.sTime).toBe(70);
+ expect(filters.eTime).toBe(730);
+ });
+ });
+
+ describe('filterLogs', () => {
+ const contentData: Record<string, any> = {
+ clog: [
+ {
+ name: 'priority',
+ stamp: '2019-02-21 09:39:49.572801',
+ message: 'Manager daemon localhost is now available',
+ priority: '[ERR]'
+ },
+ {
+ name: 'search',
+ stamp: '2019-02-21 09:39:49.572801',
+ message: 'Activating manager daemon localhost',
+ priority: '[INF]'
+ },
+ {
+ name: 'date',
+ stamp: '2019-01-21 09:39:49.572801',
+ message: 'Manager daemon localhost is now available',
+ priority: '[INF]'
+ },
+ {
+ name: 'time',
+ stamp: '2019-02-21 01:39:49.572801',
+ message: 'Manager daemon localhost is now available',
+ priority: '[INF]'
+ }
+ ],
+ audit_log: []
+ };
+ const resetFilter = () => {
+ component.selectedDate = null;
+ component.priority = 'All';
+ component.search = '';
+ component.startTime = { hour: 0, minute: 0 };
+ component.endTime = { hour: 23, minute: 59 };
+ };
+ beforeEach(() => {
+ component.contentData = contentData;
+ });
+
+ it('show all log', () => {
+ component.filterLogs();
+ expect(component.clog.length).toBe(4);
+ });
+
+ it('filter by search key', () => {
+ resetFilter();
+ component.search = 'Activating';
+ component.filterLogs();
+ expect(component.clog.length).toBe(1);
+ expect(component.clog[0].name).toBe('search');
+ });
+
+ it('filter by date', () => {
+ resetFilter();
+ component.selectedDate = { year: 2019, month: 1, day: 21 };
+ component.filterLogs();
+ expect(component.clog.length).toBe(1);
+ expect(component.clog[0].name).toBe('date');
+ });
+
+ it('filter by priority', () => {
+ resetFilter();
+ component.priority = '[ERR]';
+ component.filterLogs();
+ expect(component.clog.length).toBe(1);
+ expect(component.clog[0].name).toBe('priority');
+ });
+
+ it('filter by time range', () => {
+ resetFilter();
+ component.startTime = { hour: 1, minute: 0 };
+ component.endTime = { hour: 2, minute: 0 };
+ component.filterLogs();
+ expect(component.clog.length).toBe(1);
+ expect(component.clog[0].name).toBe('time');
+ });
+ });
+
+ describe('convert logs to text', () => {
+ it('convert cluster & audit logs to text', () => {
+ const logsPayload = {
+ clog: [
+ {
+ name: 'priority',
+ stamp: '2019-02-21 09:39:49.572801',
+ message: 'Manager daemon localhost is now available',
+ priority: '[ERR]'
+ }
+ ],
+ audit_log: [
+ {
+ stamp: '2020-12-22T11:18:13.896920+0000',
+ priority: '[INF]'
+ }
+ ]
+ };
+ logsServiceSpy.and.returnValue(of(logsPayload));
+ fixture.detectChanges();
+ expect(component.clogText).toContain(logsPayload.clog[0].message);
+ expect(component.auditLogText).toContain(logsPayload.audit_log[0].priority);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.ts
new file mode 100644
index 000000000..420da4958
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.ts
@@ -0,0 +1,157 @@
+import { DatePipe } from '@angular/common';
+import { Component, NgZone, OnDestroy, OnInit } from '@angular/core';
+
+import { NgbDateStruct } from '@ng-bootstrap/ng-bootstrap';
+
+import { LogsService } from '~/app/shared/api/logs.service';
+import { Icons } from '~/app/shared/enum/icons.enum';
+
+@Component({
+ selector: 'cd-logs',
+ templateUrl: './logs.component.html',
+ styleUrls: ['./logs.component.scss']
+})
+export class LogsComponent implements OnInit, OnDestroy {
+ contentData: any;
+ clog: Array<any>;
+ audit_log: Array<any>;
+ icons = Icons;
+ clogText: string;
+ auditLogText: string;
+
+ interval: number;
+ priorities: Array<{ name: string; value: string }> = [
+ { name: 'Debug', value: '[DBG]' },
+ { name: 'Info', value: '[INF]' },
+ { name: 'Warning', value: '[WRN]' },
+ { name: 'Error', value: '[ERR]' },
+ { name: 'All', value: 'All' }
+ ];
+ priority = 'All';
+ search = '';
+ selectedDate: NgbDateStruct;
+ startTime = { hour: 0, minute: 0 };
+ endTime = { hour: 23, minute: 59 };
+ maxDate = {
+ year: new Date().getFullYear(),
+ month: new Date().getMonth() + 1,
+ day: new Date().getDate()
+ };
+
+ constructor(
+ private logsService: LogsService,
+ private datePipe: DatePipe,
+ private ngZone: NgZone
+ ) {}
+
+ ngOnInit() {
+ this.getInfo();
+ this.ngZone.runOutsideAngular(() => {
+ this.interval = window.setInterval(() => {
+ this.ngZone.run(() => {
+ this.getInfo();
+ });
+ }, 5000);
+ });
+ }
+
+ ngOnDestroy() {
+ clearInterval(this.interval);
+ }
+
+ getInfo() {
+ this.logsService.getLogs().subscribe((data: any) => {
+ this.contentData = data;
+ this.clogText = this.logToText(this.contentData.clog);
+ this.auditLogText = this.logToText(this.contentData.audit_log);
+ this.filterLogs();
+ });
+ }
+
+ abstractFilters(): any {
+ const priority = this.priority;
+ const key = this.search.toLowerCase();
+ let yearMonthDay: string;
+ if (this.selectedDate) {
+ const m = this.selectedDate.month;
+ const d = this.selectedDate.day;
+
+ const year = this.selectedDate.year;
+ const month = m <= 9 ? `0${m}` : `${m}`;
+ const day = d <= 9 ? `0${d}` : `${d}`;
+ yearMonthDay = `${year}-${month}-${day}`;
+ } else {
+ yearMonthDay = '';
+ }
+
+ const sHour = this.startTime?.hour ?? 0;
+ const sMinutes = this.startTime?.minute ?? 0;
+ const sTime = sHour * 60 + sMinutes;
+
+ const eHour = this.endTime?.hour ?? 23;
+ const eMinutes = this.endTime?.minute ?? 59;
+ const eTime = eHour * 60 + eMinutes;
+
+ return { priority, key, yearMonthDay, sTime, eTime };
+ }
+
+ filterExecutor(logs: Array<any>, filters: any): Array<any> {
+ return logs.filter((line) => {
+ const localDate = this.datePipe.transform(line.stamp, 'mediumTime');
+ const hour = parseInt(localDate.split(':')[0], 10);
+ const minutes = parseInt(localDate.split(':')[1], 10);
+ let prio: string, y_m_d: string, timeSpan: number;
+
+ prio = filters.priority === 'All' ? line.priority : filters.priority;
+ y_m_d = filters.yearMonthDay ? filters.yearMonthDay : line.stamp;
+ timeSpan = hour * 60 + minutes;
+ return (
+ line.priority === prio &&
+ line.message.toLowerCase().indexOf(filters.key) !== -1 &&
+ line.stamp.indexOf(y_m_d) !== -1 &&
+ timeSpan >= filters.sTime &&
+ timeSpan <= filters.eTime
+ );
+ });
+ }
+
+ filterLogs() {
+ const filters = this.abstractFilters();
+ this.clog = this.filterExecutor(this.contentData.clog, filters);
+ this.audit_log = this.filterExecutor(this.contentData.audit_log, filters);
+ }
+
+ clearSearchKey() {
+ this.search = '';
+ this.filterLogs();
+ }
+ clearDate() {
+ this.selectedDate = null;
+ this.filterLogs();
+ }
+ resetFilter() {
+ this.priority = 'All';
+ this.search = '';
+ this.selectedDate = null;
+ this.startTime = { hour: 0, minute: 0 };
+ this.endTime = { hour: 23, minute: 59 };
+ this.filterLogs();
+
+ return false;
+ }
+
+ logToText(log: object) {
+ let logText = '';
+ for (const line of Object.keys(log)) {
+ logText =
+ logText +
+ this.datePipe.transform(log[line].stamp, 'medium') +
+ '\t' +
+ log[line].priority +
+ '\t' +
+ log[line].message +
+ '\n';
+ }
+ return logText;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.html
new file mode 100644
index 000000000..29cae36ba
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.html
@@ -0,0 +1,4 @@
+<ng-container *ngIf="selection">
+ <cd-table-key-value [data]="module_config">
+ </cd-table-key-value>
+</ng-container>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.spec.ts
new file mode 100644
index 000000000..4b3ea971b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.spec.ts
@@ -0,0 +1,27 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { MgrModuleDetailsComponent } from './mgr-module-details.component';
+
+describe('MgrModuleDetailsComponent', () => {
+ let component: MgrModuleDetailsComponent;
+ let fixture: ComponentFixture<MgrModuleDetailsComponent>;
+
+ configureTestBed({
+ declarations: [MgrModuleDetailsComponent],
+ imports: [HttpClientTestingModule, SharedModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(MgrModuleDetailsComponent);
+ component = fixture.componentInstance;
+ component.selection = undefined;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.ts
new file mode 100644
index 000000000..5a08ebedd
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.ts
@@ -0,0 +1,25 @@
+import { Component, Input, OnChanges } from '@angular/core';
+
+import { MgrModuleService } from '~/app/shared/api/mgr-module.service';
+
+@Component({
+ selector: 'cd-mgr-module-details',
+ templateUrl: './mgr-module-details.component.html',
+ styleUrls: ['./mgr-module-details.component.scss']
+})
+export class MgrModuleDetailsComponent implements OnChanges {
+ module_config: any;
+
+ @Input()
+ selection: any;
+
+ constructor(private mgrModuleService: MgrModuleService) {}
+
+ ngOnChanges() {
+ if (this.selection) {
+ this.mgrModuleService.getConfig(this.selection.name).subscribe((resp: any) => {
+ this.module_config = resp;
+ });
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html
new file mode 100644
index 000000000..b952ce8d8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html
@@ -0,0 +1,110 @@
+<div class="cd-col-form"
+ *cdFormLoading="loading">
+ <form name="mgrModuleForm"
+ #frm="ngForm"
+ [formGroup]="mgrModuleForm"
+ novalidate>
+ <div class="card">
+ <div class="card-header"
+ i18n>Edit Manager module</div>
+ <div class="card-body">
+ <div class="form-group row"
+ *ngFor="let moduleOption of moduleOptions | keyvalue">
+
+ <!-- Field label -->
+ <label class="cd-col-form-label"
+ for="{{ moduleOption.value.name }}">
+ {{ moduleOption.value.name }}
+ <cd-helper *ngIf="moduleOption.value.long_desc || moduleOption.value.desc">
+ {{ moduleOption.value.long_desc || moduleOption.value.desc | upperFirst }}
+ </cd-helper>
+ </label>
+
+ <!-- Field control -->
+ <!-- bool -->
+ <div class="cd-col-form-input"
+ *ngIf="moduleOption.value.type === 'bool'">
+ <div class="custom-control custom-checkbox">
+ <input id="{{ moduleOption.value.name }}"
+ type="checkbox"
+ class="custom-control-input"
+ formControlName="{{ moduleOption.value.name }}">
+ <label class="custom-control-label"
+ for="{{ moduleOption.value.name }}"></label>
+ </div>
+ </div>
+
+ <!-- addr|str|uuid -->
+ <div class="cd-col-form-input"
+ *ngIf="['addr', 'str', 'uuid'].includes(moduleOption.value.type)">
+ <input id="{{ moduleOption.value.name }}"
+ class="form-control"
+ type="text"
+ formControlName="{{ moduleOption.value.name }}"
+ *ngIf="moduleOption.value.enum_allowed.length === 0">
+ <select id="{{ moduleOption.value.name }}"
+ class="form-control"
+ formControlName="{{ moduleOption.value.name }}"
+ *ngIf="moduleOption.value.enum_allowed.length > 0">
+ <option *ngFor="let value of moduleOption.value.enum_allowed"
+ [ngValue]="value">
+ {{ value }}
+ </option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="mgrModuleForm.showError(moduleOption.value.name, frm, 'invalidUuid')"
+ i18n>The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</span>
+ <span class="invalid-feedback"
+ *ngIf="mgrModuleForm.showError(moduleOption.value.name, frm, 'pattern')"
+ i18n>The entered value needs to be a valid IP address.</span>
+ </div>
+
+ <!-- uint|int|size|secs -->
+ <div class="cd-col-form-input"
+ *ngIf="['uint', 'int', 'size', 'secs'].includes(moduleOption.value.type)">
+ <input id="{{ moduleOption.value.name }}"
+ class="form-control"
+ type="number"
+ formControlName="{{ moduleOption.value.name }}"
+ min="{{ moduleOption.value.min }}"
+ max="{{ moduleOption.value.max }}">
+ <span class="invalid-feedback"
+ *ngIf="mgrModuleForm.showError(moduleOption.value.name, frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="mgrModuleForm.showError(moduleOption.value.name, frm, 'max')"
+ i18n>The entered value is too high! It must be lower or equal to {{ moduleOption.value.max }}.</span>
+ <span class="invalid-feedback"
+ *ngIf="mgrModuleForm.showError(moduleOption.value.name, frm, 'min')"
+ i18n>The entered value is too low! It must be greater or equal to {{ moduleOption.value.min }}.</span>
+ <span class="invalid-feedback"
+ *ngIf="mgrModuleForm.showError(moduleOption.value.name, frm, 'pattern')"
+ i18n>The entered value needs to be a number.</span>
+ </div>
+
+ <!-- float -->
+ <div class="cd-col-form-input"
+ *ngIf="moduleOption.value.type === 'float'">
+ <input id="{{ moduleOption.value.name }}"
+ class="form-control"
+ type="number"
+ formControlName="{{ moduleOption.value.name }}">
+ <span class="invalid-feedback"
+ *ngIf="mgrModuleForm.showError(moduleOption.value.name, frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="mgrModuleForm.showError(moduleOption.value.name, frm, 'pattern')"
+ i18n>The entered value needs to be a number or decimal.</span>
+ </div>
+
+ </div>
+ </div>
+ <div class="card-footer">
+ <cd-form-button-panel (submitActionEvent)="onSubmit()"
+ [form]="mgrModuleForm"
+ [submitText]="actionLabels.UPDATE"
+ wrappingClass="text-right"></cd-form-button-panel>
+ </div>
+ </div>
+ </form>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.spec.ts
new file mode 100644
index 000000000..f8c139bc9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.spec.ts
@@ -0,0 +1,80 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+
+import { LoadingPanelComponent } from '~/app/shared/components/loading-panel/loading-panel.component';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { MgrModuleFormComponent } from './mgr-module-form.component';
+
+describe('MgrModuleFormComponent', () => {
+ let component: MgrModuleFormComponent;
+ let fixture: ComponentFixture<MgrModuleFormComponent>;
+
+ configureTestBed(
+ {
+ declarations: [MgrModuleFormComponent],
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ RouterTestingModule,
+ SharedModule,
+ ToastrModule.forRoot()
+ ]
+ },
+ [LoadingPanelComponent]
+ );
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(MgrModuleFormComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('getValidators', () => {
+ it('should return ip validator for type addr', () => {
+ const result = component.getValidators({ type: 'addr' });
+ expect(result.length).toBe(1);
+ });
+
+ it('should return required validator for types uint, int, size, secs', () => {
+ const types = ['uint', 'int', 'size', 'secs'];
+ types.forEach((type) => {
+ const result = component.getValidators({ type: type });
+ expect(result.length).toBe(1);
+ });
+ });
+
+ it('should return required, decimalNumber validators for type float', () => {
+ const result = component.getValidators({ type: 'float' });
+ expect(result.length).toBe(2);
+ });
+
+ it('should return uuid validator for type uuid', () => {
+ const result = component.getValidators({ type: 'uuid' });
+ expect(result.length).toBe(1);
+ });
+
+ it('should return no validator for type str', () => {
+ const result = component.getValidators({ type: 'str' });
+ expect(result.length).toBe(0);
+ });
+
+ it('should return min validator for type str', () => {
+ const result = component.getValidators({ type: 'str', min: 1 });
+ expect(result.length).toBe(1);
+ });
+
+ it('should return min, max validators for type str', () => {
+ const result = component.getValidators({ type: 'str', min: 1, max: 127 });
+ expect(result.length).toBe(2);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts
new file mode 100644
index 000000000..ef44df970
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts
@@ -0,0 +1,135 @@
+import { Component, OnInit } from '@angular/core';
+import { ValidatorFn, Validators } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+
+import _ from 'lodash';
+import { forkJoin as observableForkJoin } from 'rxjs';
+
+import { MgrModuleService } from '~/app/shared/api/mgr-module.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdForm } from '~/app/shared/forms/cd-form';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { NotificationService } from '~/app/shared/services/notification.service';
+
+@Component({
+ selector: 'cd-mgr-module-form',
+ templateUrl: './mgr-module-form.component.html',
+ styleUrls: ['./mgr-module-form.component.scss']
+})
+export class MgrModuleFormComponent extends CdForm implements OnInit {
+ mgrModuleForm: CdFormGroup;
+ moduleName = '';
+ moduleOptions: any[] = [];
+
+ constructor(
+ public actionLabels: ActionLabelsI18n,
+ private route: ActivatedRoute,
+ private router: Router,
+ private formBuilder: CdFormBuilder,
+ private mgrModuleService: MgrModuleService,
+ private notificationService: NotificationService
+ ) {
+ super();
+ }
+
+ ngOnInit() {
+ this.route.params.subscribe((params: { name: string }) => {
+ this.moduleName = decodeURIComponent(params.name);
+ const observables = [
+ this.mgrModuleService.getOptions(this.moduleName),
+ this.mgrModuleService.getConfig(this.moduleName)
+ ];
+ observableForkJoin(observables).subscribe(
+ (resp: object) => {
+ this.moduleOptions = resp[0];
+ // Create the form dynamically.
+ this.createForm();
+ // Set the form field values.
+ this.mgrModuleForm.setValue(resp[1]);
+ this.loadingReady();
+ },
+ (_error) => {
+ this.loadingError();
+ }
+ );
+ });
+ }
+
+ getValidators(moduleOption: any): ValidatorFn[] {
+ const result = [];
+ switch (moduleOption.type) {
+ case 'addr':
+ result.push(CdValidators.ip());
+ break;
+ case 'uint':
+ case 'int':
+ case 'size':
+ case 'secs':
+ result.push(Validators.required);
+ break;
+ case 'str':
+ if (_.isNumber(moduleOption.min)) {
+ result.push(Validators.minLength(moduleOption.min));
+ }
+ if (_.isNumber(moduleOption.max)) {
+ result.push(Validators.maxLength(moduleOption.max));
+ }
+ break;
+ case 'float':
+ result.push(Validators.required);
+ result.push(CdValidators.decimalNumber());
+ break;
+ case 'uuid':
+ result.push(CdValidators.uuid());
+ break;
+ }
+ return result;
+ }
+
+ createForm() {
+ const controlsConfig = {};
+ _.forEach(this.moduleOptions, (moduleOption) => {
+ controlsConfig[moduleOption.name] = [
+ moduleOption.default_value,
+ this.getValidators(moduleOption)
+ ];
+ });
+ this.mgrModuleForm = this.formBuilder.group(controlsConfig);
+ }
+
+ goToListView() {
+ this.router.navigate(['/mgr-modules']);
+ }
+
+ onSubmit() {
+ // Exit immediately if the form isn't dirty.
+ if (this.mgrModuleForm.pristine) {
+ this.goToListView();
+ return;
+ }
+ const config = {};
+ _.forEach(this.moduleOptions, (moduleOption) => {
+ const control = this.mgrModuleForm.get(moduleOption.name);
+ // Append the option only if the value has been modified.
+ if (control.dirty && control.valid) {
+ config[moduleOption.name] = control.value;
+ }
+ });
+ this.mgrModuleService.updateConfig(this.moduleName, config).subscribe(
+ () => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Updated options for module '${this.moduleName}'.`
+ );
+ this.goToListView();
+ },
+ () => {
+ // Reset the 'Submit' button.
+ this.mgrModuleForm.setErrors({ cdSubmitButton: true });
+ }
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.html
new file mode 100644
index 000000000..29b287de8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.html
@@ -0,0 +1,20 @@
+<cd-table #table
+ [autoReload]="false"
+ [data]="modules"
+ [columns]="columns"
+ columnMode="flex"
+ selectionType="single"
+ [hasDetails]="true"
+ (setExpandedRow)="setExpandedRow($event)"
+ (updateSelection)="updateSelection($event)"
+ identifier="module"
+ (fetchData)="getModuleList($event)">
+ <cd-table-actions class="table-actions"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ <cd-mgr-module-details cdTableDetail
+ [selection]="expandedRow">
+ </cd-mgr-module-details>
+</cd-table>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.spec.ts
new file mode 100644
index 000000000..9a0d87d50
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.spec.ts
@@ -0,0 +1,155 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { of as observableOf, throwError as observableThrowError } from 'rxjs';
+
+import { MgrModuleService } from '~/app/shared/api/mgr-module.service';
+import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, PermissionHelper } from '~/testing/unit-test-helper';
+import { MgrModuleDetailsComponent } from '../mgr-module-details/mgr-module-details.component';
+import { MgrModuleListComponent } from './mgr-module-list.component';
+
+describe('MgrModuleListComponent', () => {
+ let component: MgrModuleListComponent;
+ let fixture: ComponentFixture<MgrModuleListComponent>;
+ let mgrModuleService: MgrModuleService;
+ let notificationService: NotificationService;
+
+ configureTestBed({
+ declarations: [MgrModuleListComponent, MgrModuleDetailsComponent],
+ imports: [
+ BrowserAnimationsModule,
+ RouterTestingModule,
+ SharedModule,
+ HttpClientTestingModule,
+ NgbNavModule,
+ ToastrModule.forRoot()
+ ],
+ providers: [MgrModuleService, NotificationService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(MgrModuleListComponent);
+ component = fixture.componentInstance;
+ mgrModuleService = TestBed.inject(MgrModuleService);
+ notificationService = TestBed.inject(NotificationService);
+ });
+
+ it('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+
+ it('should test all TableActions combinations', () => {
+ const permissionHelper: PermissionHelper = new PermissionHelper(component.permission);
+ const tableActions: TableActionsComponent = permissionHelper.setPermissionsAndGetActions(
+ component.tableActions
+ );
+
+ expect(tableActions).toEqual({
+ 'create,update,delete': {
+ actions: ['Edit', 'Enable', 'Disable'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ 'create,update': {
+ actions: ['Edit', 'Enable', 'Disable'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ 'create,delete': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ },
+ create: { actions: [], primary: { multiple: '', executing: '', single: '', no: '' } },
+ 'update,delete': {
+ actions: ['Edit', 'Enable', 'Disable'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ update: {
+ actions: ['Edit', 'Enable', 'Disable'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ delete: { actions: [], primary: { multiple: '', executing: '', single: '', no: '' } },
+ 'no-permissions': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ }
+ });
+ });
+
+ describe('should update module state', () => {
+ beforeEach(() => {
+ component.selection = new CdTableSelection();
+ spyOn(notificationService, 'suspendToasties');
+ spyOn(component.blockUI, 'start');
+ spyOn(component.blockUI, 'stop');
+ spyOn(component.table, 'refreshBtn');
+ });
+
+ it('should enable module', fakeAsync(() => {
+ spyOn(mgrModuleService, 'enable').and.returnValue(observableThrowError('y'));
+ spyOn(mgrModuleService, 'list').and.returnValues(observableThrowError('z'), observableOf([]));
+ component.selection.add({
+ name: 'foo',
+ enabled: false,
+ always_on: false
+ });
+ component.updateModuleState();
+ tick(2000);
+ tick(2000);
+ expect(mgrModuleService.enable).toHaveBeenCalledWith('foo');
+ expect(mgrModuleService.list).toHaveBeenCalledTimes(2);
+ expect(notificationService.suspendToasties).toHaveBeenCalledTimes(2);
+ expect(component.blockUI.start).toHaveBeenCalled();
+ expect(component.blockUI.stop).toHaveBeenCalled();
+ expect(component.table.refreshBtn).toHaveBeenCalled();
+ }));
+
+ it('should disable module', fakeAsync(() => {
+ spyOn(mgrModuleService, 'disable').and.returnValue(observableThrowError('x'));
+ spyOn(mgrModuleService, 'list').and.returnValue(observableOf([]));
+ component.selection.add({
+ name: 'bar',
+ enabled: true,
+ always_on: false
+ });
+ component.updateModuleState();
+ tick(2000);
+ expect(mgrModuleService.disable).toHaveBeenCalledWith('bar');
+ expect(mgrModuleService.list).toHaveBeenCalledTimes(1);
+ expect(notificationService.suspendToasties).toHaveBeenCalledTimes(2);
+ expect(component.blockUI.start).toHaveBeenCalled();
+ expect(component.blockUI.stop).toHaveBeenCalled();
+ expect(component.table.refreshBtn).toHaveBeenCalled();
+ }));
+
+ it.only('should not disable module without selecting one', () => {
+ expect(component.getTableActionDisabledDesc()).toBeTruthy();
+ });
+
+ it('should not disable dashboard module', () => {
+ component.selection.selected = [
+ {
+ name: 'dashboard'
+ }
+ ];
+ expect(component.getTableActionDisabledDesc()).toBeTruthy();
+ });
+
+ it('should not disable an always-on module', () => {
+ component.selection.selected = [
+ {
+ name: 'bar',
+ always_on: true
+ }
+ ];
+ expect(component.getTableActionDisabledDesc()).toBe('This Manager module is always on.');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts
new file mode 100644
index 000000000..915e54923
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts
@@ -0,0 +1,198 @@
+import { Component, ViewChild } from '@angular/core';
+
+import { BlockUI, NgBlockUI } from 'ng-block-ui';
+import { timer as observableTimer } from 'rxjs';
+
+import { MgrModuleService } from '~/app/shared/api/mgr-module.service';
+import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
+import { TableComponent } from '~/app/shared/datatable/table/table.component';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+
+@Component({
+ selector: 'cd-mgr-module-list',
+ templateUrl: './mgr-module-list.component.html',
+ styleUrls: ['./mgr-module-list.component.scss']
+})
+export class MgrModuleListComponent extends ListWithDetails {
+ @ViewChild(TableComponent, { static: true })
+ table: TableComponent;
+ @BlockUI()
+ blockUI: NgBlockUI;
+
+ permission: Permission;
+ tableActions: CdTableAction[];
+ columns: CdTableColumn[] = [];
+ modules: object[] = [];
+ selection: CdTableSelection = new CdTableSelection();
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private mgrModuleService: MgrModuleService,
+ private notificationService: NotificationService
+ ) {
+ super();
+ this.permission = this.authStorageService.getPermissions().configOpt;
+ this.columns = [
+ {
+ name: $localize`Name`,
+ prop: 'name',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Enabled`,
+ prop: 'enabled',
+ flexGrow: 1,
+ cellClass: 'text-center',
+ cellTransformation: CellTemplate.checkIcon
+ },
+ {
+ name: $localize`Always-On`,
+ prop: 'always_on',
+ flexGrow: 1,
+ cellClass: 'text-center',
+ cellTransformation: CellTemplate.checkIcon
+ }
+ ];
+ const getModuleUri = () =>
+ this.selection.first() && encodeURIComponent(this.selection.first().name);
+ this.tableActions = [
+ {
+ name: $localize`Edit`,
+ permission: 'update',
+ disable: () => {
+ if (!this.selection.hasSelection) {
+ return true;
+ }
+ // Disable the 'edit' button when the module has no options.
+ return Object.values(this.selection.first().options).length === 0;
+ },
+ routerLink: () => `/mgr-modules/edit/${getModuleUri()}`,
+ icon: Icons.edit
+ },
+ {
+ name: $localize`Enable`,
+ permission: 'update',
+ click: () => this.updateModuleState(),
+ disable: () => this.isTableActionDisabled('enabled'),
+ icon: Icons.start
+ },
+ {
+ name: $localize`Disable`,
+ permission: 'update',
+ click: () => this.updateModuleState(),
+ disable: () => this.getTableActionDisabledDesc(),
+ icon: Icons.stop
+ }
+ ];
+ }
+
+ getModuleList(context: CdTableFetchDataContext) {
+ this.mgrModuleService.list().subscribe(
+ (resp: object[]) => {
+ this.modules = resp;
+ },
+ () => {
+ context.error();
+ }
+ );
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ /**
+ * Check if the table action is disabled.
+ * @param state The expected module state, e.g. ``enabled`` or ``disabled``.
+ * @returns If the specified state is validated to true or no selection is
+ * done, then ``true`` is returned, otherwise ``false``.
+ */
+ isTableActionDisabled(state: 'enabled' | 'disabled') {
+ if (!this.selection.hasSelection) {
+ return true;
+ }
+ const selected = this.selection.first();
+ // Make sure the user can't modify the run state of the 'Dashboard' module.
+ // This check is only done in the UI because the REST API should still be
+ // able to do so.
+ if (selected.name === 'dashboard') {
+ return true;
+ }
+ // Always-on modules can't be disabled.
+ if (selected.always_on) {
+ return true;
+ }
+ switch (state) {
+ case 'enabled':
+ return selected.enabled;
+ case 'disabled':
+ return !selected.enabled;
+ }
+ }
+
+ getTableActionDisabledDesc(): string | boolean {
+ if (this.selection.first()?.always_on) {
+ return $localize`This Manager module is always on.`;
+ }
+
+ return this.isTableActionDisabled('disabled');
+ }
+
+ /**
+ * Update the Ceph Mgr module state to enabled or disabled.
+ */
+ updateModuleState() {
+ if (!this.selection.hasSelection) {
+ return;
+ }
+
+ let $obs;
+ const fnWaitUntilReconnected = () => {
+ observableTimer(2000).subscribe(() => {
+ // Trigger an API request to check if the connection is
+ // re-established.
+ this.mgrModuleService.list().subscribe(
+ () => {
+ // Resume showing the notification toasties.
+ this.notificationService.suspendToasties(false);
+ // Unblock the whole UI.
+ this.blockUI.stop();
+ // Reload the data table content.
+ this.table.refreshBtn();
+ },
+ () => {
+ fnWaitUntilReconnected();
+ }
+ );
+ });
+ };
+
+ // Note, the Ceph Mgr is always restarted when a module
+ // is enabled/disabled.
+ const module = this.selection.first();
+ if (module.enabled) {
+ $obs = this.mgrModuleService.disable(module.name);
+ } else {
+ $obs = this.mgrModuleService.enable(module.name);
+ }
+ $obs.subscribe(
+ () => undefined,
+ () => {
+ // Suspend showing the notification toasties.
+ this.notificationService.suspendToasties(true);
+ // Block the whole UI to prevent user interactions until
+ // the connection to the backend is reestablished
+ this.blockUI.start($localize`Reconnecting, please wait ...`);
+ fnWaitUntilReconnected();
+ }
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-modules.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-modules.module.ts
new file mode 100644
index 000000000..9921db6d7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-modules.module.ts
@@ -0,0 +1,17 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { ReactiveFormsModule } from '@angular/forms';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { AppRoutingModule } from '~/app/app-routing.module';
+import { SharedModule } from '~/app/shared/shared.module';
+import { MgrModuleDetailsComponent } from './mgr-module-details/mgr-module-details.component';
+import { MgrModuleFormComponent } from './mgr-module-form/mgr-module-form.component';
+import { MgrModuleListComponent } from './mgr-module-list/mgr-module-list.component';
+
+@NgModule({
+ imports: [AppRoutingModule, CommonModule, ReactiveFormsModule, SharedModule, NgbNavModule],
+ declarations: [MgrModuleListComponent, MgrModuleFormComponent, MgrModuleDetailsComponent]
+})
+export class MgrModulesModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.html
new file mode 100644
index 000000000..ca9ac8221
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.html
@@ -0,0 +1,61 @@
+<div class="row">
+ <div class="col-lg-4">
+ <fieldset>
+ <legend class="cd-header"
+ i18n>Status</legend>
+ <table class="table table-striped"
+ *ngIf="mon_status">
+ <tr>
+ <td i18n
+ class="bold">Cluster ID</td>
+ <td>{{ mon_status.monmap.fsid }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">monmap modified</td>
+ <td>{{ mon_status.monmap.modified | relativeDate }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">monmap epoch</td>
+ <td>{{ mon_status.monmap.epoch }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">quorum con</td>
+ <td>{{ mon_status.features.quorum_con }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">quorum mon</td>
+ <td>{{ mon_status.features.quorum_mon }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">required con</td>
+ <td>{{ mon_status.features.required_con }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">required mon</td>
+ <td>{{ mon_status.features.required_mon }}</td>
+ </tr>
+ </table>
+ </fieldset>
+ </div>
+
+ <div class="col-lg-8">
+ <legend i18n
+ class="in-quorum cd-header">In Quorum</legend>
+ <cd-table [data]="inQuorum.data"
+ [columns]="inQuorum.columns">
+ </cd-table>
+
+ <legend i18n
+ class="in-quorum cd-header">Not In Quorum</legend>
+ <cd-table [data]="notInQuorum.data"
+ (fetchData)="refresh()"
+ [columns]="notInQuorum.columns">
+ </cd-table>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.spec.ts
new file mode 100644
index 000000000..53673c7f4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.spec.ts
@@ -0,0 +1,105 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { of } from 'rxjs';
+
+import { MonitorService } from '~/app/shared/api/monitor.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { MonitorComponent } from './monitor.component';
+
+describe('MonitorComponent', () => {
+ let component: MonitorComponent;
+ let fixture: ComponentFixture<MonitorComponent>;
+ let getMonitorSpy: jasmine.Spy;
+
+ configureTestBed({
+ imports: [HttpClientTestingModule, SharedModule],
+ declarations: [MonitorComponent],
+ schemas: [NO_ERRORS_SCHEMA],
+ providers: [MonitorService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(MonitorComponent);
+ component = fixture.componentInstance;
+ const getMonitorPayload: Record<string, any> = {
+ in_quorum: [
+ {
+ stats: { num_sessions: [[1, 5]] }
+ },
+ {
+ stats: {
+ num_sessions: [
+ [1, 1],
+ [2, 10],
+ [3, 1]
+ ]
+ }
+ },
+ {
+ stats: {
+ num_sessions: [
+ [1, 0],
+ [2, 3]
+ ]
+ }
+ },
+ {
+ stats: {
+ num_sessions: [
+ [1, 2],
+ [2, 1],
+ [3, 7],
+ [4, 5]
+ ]
+ }
+ }
+ ],
+ mon_status: null,
+ out_quorum: []
+ };
+ getMonitorSpy = spyOn(TestBed.inject(MonitorService), 'getMonitor').and.returnValue(
+ of(getMonitorPayload)
+ );
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should sort by open sessions column correctly', () => {
+ component.refresh();
+
+ expect(getMonitorSpy).toHaveBeenCalled();
+
+ expect(component.inQuorum.columns[3].comparator(undefined, undefined)).toBe(0);
+ expect(component.inQuorum.columns[3].comparator(null, null)).toBe(0);
+ expect(component.inQuorum.columns[3].comparator([], [])).toBe(0);
+ expect(
+ component.inQuorum.columns[3].comparator(
+ component.inQuorum.data[0].cdOpenSessions,
+ component.inQuorum.data[3].cdOpenSessions
+ )
+ ).toBe(0);
+ expect(
+ component.inQuorum.columns[3].comparator(
+ component.inQuorum.data[0].cdOpenSessions,
+ component.inQuorum.data[1].cdOpenSessions
+ )
+ ).toBe(1);
+ expect(
+ component.inQuorum.columns[3].comparator(
+ component.inQuorum.data[1].cdOpenSessions,
+ component.inQuorum.data[0].cdOpenSessions
+ )
+ ).toBe(-1);
+ expect(
+ component.inQuorum.columns[3].comparator(
+ component.inQuorum.data[2].cdOpenSessions,
+ component.inQuorum.data[1].cdOpenSessions
+ )
+ ).toBe(1);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.ts
new file mode 100644
index 000000000..5ba17e6c5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.ts
@@ -0,0 +1,74 @@
+import { Component } from '@angular/core';
+
+import _ from 'lodash';
+
+import { MonitorService } from '~/app/shared/api/monitor.service';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+
+@Component({
+ selector: 'cd-monitor',
+ templateUrl: './monitor.component.html',
+ styleUrls: ['./monitor.component.scss']
+})
+export class MonitorComponent {
+ mon_status: any;
+ inQuorum: any;
+ notInQuorum: any;
+
+ interval: any;
+
+ constructor(private monitorService: MonitorService) {
+ this.inQuorum = {
+ columns: [
+ { prop: 'name', name: $localize`Name`, cellTransformation: CellTemplate.routerLink },
+ { prop: 'rank', name: $localize`Rank` },
+ { prop: 'public_addr', name: $localize`Public Address` },
+ {
+ prop: 'cdOpenSessions',
+ name: $localize`Open Sessions`,
+ cellTransformation: CellTemplate.sparkline,
+ comparator: (dataA: any, dataB: any) => {
+ // We get the last value of time series to compare:
+ const lastValueA = _.last(dataA);
+ const lastValueB = _.last(dataB);
+
+ if (!lastValueA || !lastValueB || lastValueA === lastValueB) {
+ return 0;
+ }
+
+ return lastValueA > lastValueB ? 1 : -1;
+ }
+ }
+ ]
+ };
+
+ this.notInQuorum = {
+ columns: [
+ { prop: 'name', name: $localize`Name`, cellTransformation: CellTemplate.routerLink },
+ { prop: 'rank', name: $localize`Rank` },
+ { prop: 'public_addr', name: $localize`Public Address` }
+ ]
+ };
+ }
+
+ refresh() {
+ this.monitorService.getMonitor().subscribe((data: any) => {
+ data.in_quorum.map((row: any) => {
+ row.cdOpenSessions = row.stats.num_sessions.map((i: string) => i[1]);
+ row.cdLink = '/perf_counters/mon/' + row.name;
+ row.cdParams = { fromLink: '/monitor' };
+ return row;
+ });
+
+ data.out_quorum.map((row: any) => {
+ row.cdLink = '/perf_counters/mon/' + row.name;
+ row.cdParams = { fromLink: '/monitor' };
+ return row;
+ });
+
+ this.inQuorum.data = [...data.in_quorum];
+ this.notInQuorum.data = [...data.out_quorum];
+ this.mon_status = data.mon_status;
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html
new file mode 100644
index 000000000..9b442dbc7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html
@@ -0,0 +1,20 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container class="modal-title"
+ i18n>OSD creation preview</ng-container>
+
+ <ng-container class="modal-content">
+ <form #frm="ngForm"
+ [formGroup]="formGroup"
+ novalidate>
+ <div class="modal-body">
+ <h4 i18n>DriveGroups</h4>
+ <pre>{{ driveGroups | json}}</pre>
+ </div>
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="onSubmit()"
+ [form]="formGroup"
+ [submitText]="action | titlecase"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.spec.ts
new file mode 100644
index 000000000..cc2db7411
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.spec.ts
@@ -0,0 +1,38 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { OsdCreationPreviewModalComponent } from './osd-creation-preview-modal.component';
+
+describe('OsdCreationPreviewModalComponent', () => {
+ let component: OsdCreationPreviewModalComponent;
+ let fixture: ComponentFixture<OsdCreationPreviewModalComponent>;
+
+ configureTestBed({
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ SharedModule,
+ RouterTestingModule,
+ ToastrModule.forRoot()
+ ],
+ providers: [NgbActiveModal],
+ declarations: [OsdCreationPreviewModalComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OsdCreationPreviewModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.ts
new file mode 100644
index 000000000..3e1b0f067
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.ts
@@ -0,0 +1,62 @@
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+
+import { OsdService } from '~/app/shared/api/osd.service';
+import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+
+@Component({
+ selector: 'cd-osd-creation-preview-modal',
+ templateUrl: './osd-creation-preview-modal.component.html',
+ styleUrls: ['./osd-creation-preview-modal.component.scss']
+})
+export class OsdCreationPreviewModalComponent {
+ @Input()
+ driveGroups: Object[] = [];
+
+ @Output()
+ submitAction = new EventEmitter();
+
+ action: string;
+ formGroup: CdFormGroup;
+
+ constructor(
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n,
+ private formBuilder: CdFormBuilder,
+ private osdService: OsdService,
+ private taskWrapper: TaskWrapperService
+ ) {
+ this.action = actionLabels.CREATE;
+ this.createForm();
+ }
+
+ createForm() {
+ this.formGroup = this.formBuilder.group({});
+ }
+
+ onSubmit() {
+ const trackingId = _.join(_.map(this.driveGroups, 'service_id'), ', ');
+ this.taskWrapper
+ .wrapTaskAroundCall({
+ task: new FinishedTask('osd/' + URLVerbs.CREATE, {
+ tracking_id: trackingId
+ }),
+ call: this.osdService.create(this.driveGroups, trackingId)
+ })
+ .subscribe({
+ error: () => {
+ this.formGroup.setErrors({ cdSubmitButton: true });
+ },
+ complete: () => {
+ this.submitAction.emit();
+ this.activeModal.close();
+ }
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.html
new file mode 100644
index 000000000..bd85e2255
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.html
@@ -0,0 +1,67 @@
+<ng-container *ngIf="selection">
+ <ul ngbNav
+ #nav="ngbNav"
+ id="tabset-osd-details"
+ class="nav-tabs"
+ cdStatefulTab="osd-details">
+ <li ngbNavItem="devices">
+ <a ngbNavLink
+ i18n>Devices</a>
+ <ng-template ngbNavContent>
+ <cd-device-list [osdId]="osd?.id"></cd-device-list>
+ </ng-template>
+ </li>
+ <li ngbNavItem="attributes">
+ <a ngbNavLink
+ i18n>Attributes (OSD map)</a>
+ <ng-template ngbNavContent>
+ <cd-table-key-value [data]="osd?.details?.osd_map">
+ </cd-table-key-value>
+ </ng-template>
+ </li>
+ <li ngbNavItem="metadata">
+ <a ngbNavLink
+ i18n>Metadata</a>
+ <ng-template ngbNavContent>
+ <cd-table-key-value *ngIf="osd?.details?.osd_metadata; else noMetaData"
+ (fetchData)="refresh()"
+ [data]="osd?.details?.osd_metadata">
+ </cd-table-key-value>
+ <ng-template #noMetaData>
+ <cd-alert-panel type="warning"
+ i18n>Metadata not available</cd-alert-panel>
+ </ng-template>
+ </ng-template>
+ </li>
+ <li ngbNavItem="device-health">
+ <a ngbNavLink
+ i18n>Device health</a>
+ <ng-template ngbNavContent>
+ <cd-smart-list [osdId]="osd?.id"></cd-smart-list>
+ </ng-template>
+ </li>
+ <li ngbNavItem="performance-counter">
+ <a ngbNavLink
+ i18n>Performance counter</a>
+ <ng-template ngbNavContent>
+ <cd-table-performance-counter *ngIf="osd?.details"
+ serviceType="osd"
+ [serviceId]="osd?.id">
+ </cd-table-performance-counter>
+ </ng-template>
+ </li>
+ <li ngbNavItem="performance-details"
+ *ngIf="grafanaPermission.read">
+ <a ngbNavLink
+ i18n>Performance Details</a>
+ <ng-template ngbNavContent>
+ <cd-grafana [grafanaPath]="'osd-device-details?var-osd=osd.' + osd['id']"
+ uid="CrAHE0iZz"
+ grafanaStyle="three">
+ </cd-grafana>
+ </ng-template>
+ </li>
+ </ul>
+
+ <div [ngbNavOutlet]="nav"></div>
+</ng-container>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.spec.ts
new file mode 100644
index 000000000..ebb1ef044
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.spec.ts
@@ -0,0 +1,31 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { TablePerformanceCounterComponent } from '~/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component';
+import { CephSharedModule } from '~/app/ceph/shared/ceph-shared.module';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { OsdDetailsComponent } from './osd-details.component';
+
+describe('OsdDetailsComponent', () => {
+ let component: OsdDetailsComponent;
+ let fixture: ComponentFixture<OsdDetailsComponent>;
+
+ configureTestBed({
+ imports: [HttpClientTestingModule, NgbNavModule, SharedModule, CephSharedModule],
+ declarations: [OsdDetailsComponent, TablePerformanceCounterComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OsdDetailsComponent);
+ component = fixture.componentInstance;
+ component.selection = undefined;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.ts
new file mode 100644
index 000000000..5e52880f0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.ts
@@ -0,0 +1,44 @@
+import { Component, Input, OnChanges } from '@angular/core';
+
+import _ from 'lodash';
+
+import { OsdService } from '~/app/shared/api/osd.service';
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+
+@Component({
+ selector: 'cd-osd-details',
+ templateUrl: './osd-details.component.html',
+ styleUrls: ['./osd-details.component.scss']
+})
+export class OsdDetailsComponent implements OnChanges {
+ @Input()
+ selection: any;
+
+ osd: {
+ id?: number;
+ details?: any;
+ tree?: any;
+ };
+ grafanaPermission: Permission;
+
+ constructor(private osdService: OsdService, private authStorageService: AuthStorageService) {
+ this.grafanaPermission = this.authStorageService.getPermissions().grafana;
+ }
+
+ ngOnChanges() {
+ if (this.osd?.id !== this.selection?.id) {
+ this.osd = this.selection;
+ }
+
+ if (_.isNumber(this.osd?.id)) {
+ this.refresh();
+ }
+ }
+
+ refresh() {
+ this.osdService.getDetails(this.osd.id).subscribe((data) => {
+ this.osd.details = data;
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/devices-selection-change-event.interface.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/devices-selection-change-event.interface.ts
new file mode 100644
index 000000000..0467f14f6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/devices-selection-change-event.interface.ts
@@ -0,0 +1,5 @@
+import { CdTableColumnFiltersChange } from '~/app/shared/models/cd-table-column-filters-change';
+
+export interface DevicesSelectionChangeEvent extends CdTableColumnFiltersChange {
+ type: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/devices-selection-clear-event.interface.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/devices-selection-clear-event.interface.ts
new file mode 100644
index 000000000..4e7a2ff54
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/devices-selection-clear-event.interface.ts
@@ -0,0 +1,6 @@
+import { InventoryDevice } from '~/app/ceph/cluster/inventory/inventory-devices/inventory-device.model';
+
+export interface DevicesSelectionClearEvent {
+ type: string;
+ clearedDevices: InventoryDevice[];
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html
new file mode 100644
index 000000000..8b1f59eac
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html
@@ -0,0 +1,51 @@
+<!-- button -->
+<div class="form-group row">
+ <label class="cd-col-form-label"
+ for="createDeleteButton">
+ <ng-container i18n>{{ name }} devices</ng-container>
+ <cd-helper>
+ <span i18n
+ *ngIf="type === 'data'">The primary storage devices. These devices contain all OSD data.</span>
+ <span i18n
+ *ngIf="type === 'wal'">Write-Ahead-Log devices. These devices are used for BlueStore’s internal journal. It is only useful to use a WAL device if the device is faster than the primary device (e.g. NVME devices or SSDs). If there is only a small amount of fast storage available (e.g., less than a gigabyte), we recommend using it as a WAL device.</span>
+ <span i18n
+ *ngIf="type === 'db'">DB devices can be used for storing BlueStore’s internal metadata. It is only helpful to provision a DB device if it is faster than the primary device (e.g. NVME devices or SSD).</span>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <ng-container *ngIf="devices.length === 0; else blockClearDevices">
+ <button type="button"
+ class="btn btn-light"
+ (click)="showSelectionModal()"
+ data-toggle="tooltip"
+ [title]="addButtonTooltip"
+ [disabled]="availDevices.length === 0 || !canSelect || expansionCanSelect">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>Add</ng-container>
+ </button>
+ </ng-container>
+ <ng-template #blockClearDevices>
+ <div class="pb-2 my-2 border-bottom">
+ <span *ngFor="let filter of appliedFilters">
+ <span class="badge badge-dark mr-2">{{ filter.name }}: {{ filter.value.formatted }}</span>
+ </span>
+ <a class="tc_clearSelections"
+ href=""
+ (click)="clearDevices(); false">
+ <i [ngClass]="[icons.clearFilters]"></i>
+ <ng-container i18n>Clear</ng-container>
+ </a>
+ </div>
+ <div>
+ <cd-inventory-devices [devices]="devices"
+ [hiddenColumns]="['available', 'osd_ids']"
+ [filterColumns]="[]">
+ </cd-inventory-devices>
+ </div>
+ <div *ngIf="type === 'data'"
+ class="float-right">
+ <span i18n>Raw capacity: {{ capacity | dimlessBinary }}</span>
+ </div>
+ </ng-template>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.scss
new file mode 100644
index 000000000..3fb8f6b38
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.scss
@@ -0,0 +1,3 @@
+.tc_clearSelections {
+ text-decoration: none;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.spec.ts
new file mode 100644
index 000000000..dea6746cf
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.spec.ts
@@ -0,0 +1,125 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule } from '@angular/forms';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+
+import { InventoryDevice } from '~/app/ceph/cluster/inventory/inventory-devices/inventory-device.model';
+import { InventoryDevicesComponent } from '~/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, FixtureHelper, Mocks } from '~/testing/unit-test-helper';
+import { OsdDevicesSelectionGroupsComponent } from './osd-devices-selection-groups.component';
+
+describe('OsdDevicesSelectionGroupsComponent', () => {
+ let component: OsdDevicesSelectionGroupsComponent;
+ let fixture: ComponentFixture<OsdDevicesSelectionGroupsComponent>;
+ let fixtureHelper: FixtureHelper;
+ const devices: InventoryDevice[] = [Mocks.getInventoryDevice('node0', '1')];
+
+ const buttonSelector = '.cd-col-form-input button';
+ const getButton = () => {
+ const debugElement = fixtureHelper.getElementByCss(buttonSelector);
+ return debugElement.nativeElement;
+ };
+ const clearTextSelector = '.tc_clearSelections';
+ const getClearText = () => {
+ const debugElement = fixtureHelper.getElementByCss(clearTextSelector);
+ return debugElement.nativeElement;
+ };
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ FormsModule,
+ HttpClientTestingModule,
+ SharedModule,
+ ToastrModule.forRoot(),
+ RouterTestingModule
+ ],
+ declarations: [OsdDevicesSelectionGroupsComponent, InventoryDevicesComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OsdDevicesSelectionGroupsComponent);
+ fixtureHelper = new FixtureHelper(fixture);
+ component = fixture.componentInstance;
+ component.canSelect = true;
+ });
+
+ describe('without available devices', () => {
+ beforeEach(() => {
+ component.availDevices = [];
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should display Add button in disabled state', () => {
+ const button = getButton();
+ expect(button).toBeTruthy();
+ expect(button.disabled).toBe(true);
+ expect(button.textContent).toBe('Add');
+ });
+
+ it('should not display devices table', () => {
+ fixtureHelper.expectElementVisible('cd-inventory-devices', false);
+ });
+ });
+
+ describe('without devices selected', () => {
+ beforeEach(() => {
+ component.availDevices = devices;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should display Add button in enabled state', () => {
+ const button = getButton();
+ expect(button).toBeTruthy();
+ expect(button.disabled).toBe(false);
+ expect(button.textContent).toBe('Add');
+ });
+
+ it('should not display devices table', () => {
+ fixtureHelper.expectElementVisible('cd-inventory-devices', false);
+ });
+ });
+
+ describe('with devices selected', () => {
+ beforeEach(() => {
+ component.isOsdPage = true;
+ component.availDevices = [];
+ component.devices = devices;
+ component.ngOnInit();
+ fixture.detectChanges();
+ });
+
+ it('should display clear link', () => {
+ const text = getClearText();
+ expect(text).toBeTruthy();
+ expect(text.textContent).toBe('Clear');
+ });
+
+ it('should display devices table', () => {
+ fixtureHelper.expectElementVisible('cd-inventory-devices', true);
+ });
+
+ it('should clear devices by clicking Clear link', () => {
+ spyOn(component.cleared, 'emit');
+ fixtureHelper.clickElement(clearTextSelector);
+ fixtureHelper.expectElementVisible('cd-inventory-devices', false);
+ const event: Record<string, any> = {
+ type: undefined,
+ clearedDevices: devices
+ };
+ expect(component.cleared.emit).toHaveBeenCalledWith(event);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts
new file mode 100644
index 000000000..cff0cbc05
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts
@@ -0,0 +1,135 @@
+import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
+import { Router } from '@angular/router';
+
+import _ from 'lodash';
+
+import { InventoryDevice } from '~/app/ceph/cluster/inventory/inventory-devices/inventory-device.model';
+import { OsdService } from '~/app/shared/api/osd.service';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdTableColumnFiltersChange } from '~/app/shared/models/cd-table-column-filters-change';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { OsdDevicesSelectionModalComponent } from '../osd-devices-selection-modal/osd-devices-selection-modal.component';
+import { DevicesSelectionChangeEvent } from './devices-selection-change-event.interface';
+import { DevicesSelectionClearEvent } from './devices-selection-clear-event.interface';
+
+@Component({
+ selector: 'cd-osd-devices-selection-groups',
+ templateUrl: './osd-devices-selection-groups.component.html',
+ styleUrls: ['./osd-devices-selection-groups.component.scss']
+})
+export class OsdDevicesSelectionGroupsComponent implements OnInit, OnChanges {
+ // data, wal, db
+ @Input() type: string;
+
+ // Data, WAL, DB
+ @Input() name: string;
+
+ @Input() hostname: string;
+
+ @Input() availDevices: InventoryDevice[];
+
+ @Input() canSelect: boolean;
+
+ @Output()
+ selected = new EventEmitter<DevicesSelectionChangeEvent>();
+
+ @Output()
+ cleared = new EventEmitter<DevicesSelectionClearEvent>();
+
+ icons = Icons;
+ devices: InventoryDevice[] = [];
+ capacity = 0;
+ appliedFilters = new Array();
+ expansionCanSelect = false;
+ isOsdPage: boolean;
+
+ addButtonTooltip: String;
+ tooltips = {
+ noAvailDevices: $localize`No available devices`,
+ addPrimaryFirst: $localize`Please add primary devices first`,
+ addByFilters: $localize`Add devices by using filters`
+ };
+
+ constructor(
+ private modalService: ModalService,
+ public osdService: OsdService,
+ private router: Router
+ ) {
+ this.isOsdPage = this.router.url.includes('/osd');
+ }
+
+ ngOnInit() {
+ if (!this.isOsdPage) {
+ this.osdService?.osdDevices[this.type]
+ ? (this.devices = this.osdService.osdDevices[this.type])
+ : (this.devices = []);
+ this.capacity = _.sumBy(this.devices, 'sys_api.size');
+ this.osdService?.osdDevices
+ ? (this.expansionCanSelect = this.osdService?.osdDevices['disableSelect'])
+ : (this.expansionCanSelect = false);
+ }
+ this.updateAddButtonTooltip();
+ }
+
+ ngOnChanges() {
+ this.updateAddButtonTooltip();
+ }
+
+ showSelectionModal() {
+ let filterColumns = ['human_readable_type', 'sys_api.vendor', 'sys_api.model', 'sys_api.size'];
+ if (this.type === 'data') {
+ filterColumns = ['hostname', ...filterColumns];
+ }
+ const initialState = {
+ hostname: this.hostname,
+ deviceType: this.name,
+ devices: this.availDevices,
+ filterColumns: filterColumns
+ };
+ const modalRef = this.modalService.show(OsdDevicesSelectionModalComponent, initialState, {
+ size: 'xl'
+ });
+ modalRef.componentInstance.submitAction.subscribe((result: CdTableColumnFiltersChange) => {
+ this.devices = result.data;
+ this.capacity = _.sumBy(this.devices, 'sys_api.size');
+ this.appliedFilters = result.filters;
+ const event = _.assign({ type: this.type }, result);
+ if (!this.isOsdPage) {
+ this.osdService.osdDevices[this.type] = this.devices;
+ this.osdService.osdDevices['disableSelect'] =
+ this.canSelect || this.devices.length === this.availDevices.length;
+ this.osdService.osdDevices[this.type]['capacity'] = this.capacity;
+ }
+ this.selected.emit(event);
+ });
+ }
+
+ private updateAddButtonTooltip() {
+ if (this.type === 'data' && this.availDevices.length === 0) {
+ this.addButtonTooltip = this.tooltips.noAvailDevices;
+ } else {
+ if (!this.canSelect) {
+ // No primary devices added yet.
+ this.addButtonTooltip = this.tooltips.addPrimaryFirst;
+ } else if (this.availDevices.length === 0) {
+ this.addButtonTooltip = this.tooltips.noAvailDevices;
+ } else {
+ this.addButtonTooltip = this.tooltips.addByFilters;
+ }
+ }
+ }
+
+ clearDevices() {
+ if (!this.isOsdPage) {
+ this.expansionCanSelect = false;
+ this.osdService.osdDevices['disableSelect'] = false;
+ this.osdService.osdDevices = [];
+ }
+ const event = {
+ type: this.type,
+ clearedDevices: [...this.devices]
+ };
+ this.devices = [];
+ this.cleared.emit(event);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html
new file mode 100644
index 000000000..3e53d5c41
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html
@@ -0,0 +1,42 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container class="modal-title"
+ i18n>{{ deviceType }} devices</ng-container>
+
+ <ng-container class="modal-content">
+ <form #frm="ngForm"
+ [formGroup]="formGroup"
+ novalidate>
+ <div class="modal-body">
+ <cd-alert-panel *ngIf="!canSubmit"
+ type="warning"
+ size="slim"
+ [showTitle]="false">
+ <ng-container i18n>At least one of these filters must be applied in order to proceed:</ng-container>
+ <span *ngFor="let filter of requiredFilters"
+ class="badge badge-dark ml-2">
+ {{ filter }}
+ </span>
+ </cd-alert-panel>
+ <cd-inventory-devices #inventoryDevices
+ [devices]="devices"
+ [filterColumns]="filterColumns"
+ [showAvailDeviceOnly]="true"
+ [hiddenColumns]="['available', 'osd_ids']"
+ (filterChange)="onFilterChange($event)">
+ </cd-inventory-devices>
+ <div *ngIf="canSubmit">
+ <p class="text-center">
+ <span i18n>Number of devices: {{ filteredDevices.length }}. Raw capacity:
+ {{ capacity | dimlessBinary }}.</span>
+ </p>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="onSubmit()"
+ [form]="formGroup"
+ [disabled]="!canSubmit || filteredDevices.length === 0"
+ [submitText]="action | titlecase"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.spec.ts
new file mode 100644
index 000000000..60ef65d05
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.spec.ts
@@ -0,0 +1,109 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+
+import { InventoryDevice } from '~/app/ceph/cluster/inventory/inventory-devices/inventory-device.model';
+import { InventoryDevicesComponent } from '~/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component';
+import { CdTableColumnFiltersChange } from '~/app/shared/models/cd-table-column-filters-change';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, Mocks } from '~/testing/unit-test-helper';
+import { OsdDevicesSelectionModalComponent } from './osd-devices-selection-modal.component';
+
+describe('OsdDevicesSelectionModalComponent', () => {
+ let component: OsdDevicesSelectionModalComponent;
+ let fixture: ComponentFixture<OsdDevicesSelectionModalComponent>;
+ let timeoutFn: Function;
+
+ const devices: InventoryDevice[] = [Mocks.getInventoryDevice('node0', '1')];
+
+ const expectSubmitButton = (enabled: boolean) => {
+ const nativeElement = fixture.debugElement.nativeElement;
+ const button = nativeElement.querySelector('.modal-footer .tc_submitButton');
+ expect(button.disabled).toBe(!enabled);
+ };
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ FormsModule,
+ HttpClientTestingModule,
+ SharedModule,
+ ReactiveFormsModule,
+ RouterTestingModule,
+ ToastrModule.forRoot()
+ ],
+ providers: [NgbActiveModal],
+ declarations: [OsdDevicesSelectionModalComponent, InventoryDevicesComponent]
+ });
+
+ beforeEach(() => {
+ spyOn(window, 'setTimeout').and.callFake((fn) => (timeoutFn = fn));
+
+ fixture = TestBed.createComponent(OsdDevicesSelectionModalComponent);
+ component = fixture.componentInstance;
+ component.devices = devices;
+
+ // Mocks InventoryDeviceComponent
+ component.inventoryDevices = {
+ columns: [
+ { name: 'Device path', prop: 'path' },
+ {
+ name: 'Type',
+ prop: 'human_readable_type'
+ },
+ {
+ name: 'Available',
+ prop: 'available'
+ }
+ ]
+ } as InventoryDevicesComponent;
+ // Mocks the update from the above component
+ component.filterColumns = ['path', 'human_readable_type'];
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should disable submit button initially', () => {
+ expectSubmitButton(false);
+ });
+
+ it(
+ 'should update requiredFilters after ngAfterViewInit is called to prevent ' +
+ 'ExpressionChangedAfterItHasBeenCheckedError',
+ () => {
+ expect(component.requiredFilters).toEqual([]);
+ timeoutFn();
+ expect(component.requiredFilters).toEqual(['Device path', 'Type']);
+ }
+ );
+
+ it('should enable submit button after filtering some devices', () => {
+ const event: CdTableColumnFiltersChange = {
+ filters: [
+ {
+ name: 'hostname',
+ prop: 'hostname',
+ value: { raw: 'node0', formatted: 'node0' }
+ },
+ {
+ name: 'size',
+ prop: 'size',
+ value: { raw: '1024', formatted: '1KiB' }
+ }
+ ],
+ data: devices,
+ dataOut: []
+ };
+ component.onFilterChange(event);
+ fixture.detectChanges();
+ expectSubmitButton(true);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.ts
new file mode 100644
index 000000000..edfe9d6a7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.ts
@@ -0,0 +1,92 @@
+import { AfterViewInit, Component, EventEmitter, Output, ViewChild } from '@angular/core';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { TableColumnProp } from '@swimlane/ngx-datatable';
+import _ from 'lodash';
+
+import { InventoryDevice } from '~/app/ceph/cluster/inventory/inventory-devices/inventory-device.model';
+import { InventoryDevicesComponent } from '~/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdTableColumnFiltersChange } from '~/app/shared/models/cd-table-column-filters-change';
+import { WizardStepsService } from '~/app/shared/services/wizard-steps.service';
+
+@Component({
+ selector: 'cd-osd-devices-selection-modal',
+ templateUrl: './osd-devices-selection-modal.component.html',
+ styleUrls: ['./osd-devices-selection-modal.component.scss']
+})
+export class OsdDevicesSelectionModalComponent implements AfterViewInit {
+ @ViewChild('inventoryDevices')
+ inventoryDevices: InventoryDevicesComponent;
+
+ @Output()
+ submitAction = new EventEmitter<CdTableColumnFiltersChange>();
+
+ icons = Icons;
+ filterColumns: TableColumnProp[] = [];
+
+ hostname: string;
+ deviceType: string;
+ formGroup: CdFormGroup;
+ action: string;
+
+ devices: InventoryDevice[] = [];
+ filteredDevices: InventoryDevice[] = [];
+ capacity = 0;
+ event: CdTableColumnFiltersChange;
+ canSubmit = false;
+ requiredFilters: string[] = [];
+
+ constructor(
+ private formBuilder: CdFormBuilder,
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n,
+ public wizardStepService: WizardStepsService
+ ) {
+ this.action = actionLabels.ADD;
+ this.createForm();
+ }
+
+ ngAfterViewInit() {
+ // At least one filter other than hostname is required
+ // Extract the name from table columns for i18n strings
+ const cols = _.filter(this.inventoryDevices.columns, (col) => {
+ return this.filterColumns.includes(col.prop) && col.prop !== 'hostname';
+ });
+ // Fixes 'ExpressionChangedAfterItHasBeenCheckedError'
+ setTimeout(() => {
+ this.requiredFilters = _.map(cols, 'name');
+ }, 0);
+ }
+
+ createForm() {
+ this.formGroup = this.formBuilder.group({});
+ }
+
+ onFilterChange(event: CdTableColumnFiltersChange) {
+ this.capacity = 0;
+ this.canSubmit = false;
+ if (_.isEmpty(event.filters)) {
+ // filters are cleared
+ this.filteredDevices = [];
+ this.event = undefined;
+ } else {
+ // at least one filter is required (except hostname)
+ const filters = event.filters.filter((filter) => {
+ return filter.prop !== 'hostname';
+ });
+ this.canSubmit = !_.isEmpty(filters);
+ this.filteredDevices = event.data;
+ this.capacity = _.sumBy(this.filteredDevices, 'sys_api.size');
+ this.event = event;
+ }
+ }
+
+ onSubmit() {
+ this.submitAction.emit(this.event);
+ this.activeModal.close();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html
new file mode 100644
index 000000000..f8a10ff24
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html
@@ -0,0 +1,48 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container class="modal-title"
+ i18n>Individual OSD Flags</ng-container>
+
+ <ng-container class="modal-content">
+ <form name="osdFlagsForm"
+ #formDir="ngForm"
+ [formGroup]="osdFlagsForm"
+ novalidate>
+ <div class="modal-body osd-modal">
+ <div class="custom-control custom-checkbox"
+ *ngFor="let flag of flags; let last = last">
+ <input class="custom-control-input"
+ type="checkbox"
+ [checked]="flag.value"
+ [indeterminate]="flag.indeterminate"
+ (change)="changeValue(flag)"
+ [name]="flag.code"
+ [id]="flag.code">
+ <label class="custom-control-label"
+ [for]="flag.code"
+ ng-class="['tc_' + key]">
+ <strong>{{ flag.name }}</strong>
+ <span class="badge badge-hdd ml-2"
+ [ngbTooltip]="clusterWideTooltip"
+ *ngIf="flag.clusterWide"
+ i18n>Cluster-wide</span>
+ <br>
+ <span class="form-text text-muted">{{ flag.description }}</span>
+ </label>
+ <hr class="m-1"
+ *ngIf="!last">
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button type="button"
+ class="btn btn-light"
+ (click)="resetSelection()"
+ i18n>Restore previous selection</button>
+ <cd-form-button-panel (submitActionEvent)="submitAction()"
+ [form]="osdFlagsForm"
+ [showSubmit]="permissions.osd.update"
+ [submitText]="actionLabels.UPDATE"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.spec.ts
new file mode 100644
index 000000000..93c9e9adc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.spec.ts
@@ -0,0 +1,353 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { of as observableOf } from 'rxjs';
+
+import { OsdService } from '~/app/shared/api/osd.service';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { Flag } from '~/app/shared/models/flag';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { OsdFlagsIndivModalComponent } from './osd-flags-indiv-modal.component';
+
+describe('OsdFlagsIndivModalComponent', () => {
+ let component: OsdFlagsIndivModalComponent;
+ let fixture: ComponentFixture<OsdFlagsIndivModalComponent>;
+ let httpTesting: HttpTestingController;
+ let osdService: OsdService;
+
+ configureTestBed({
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ SharedModule,
+ ToastrModule.forRoot(),
+ NgbTooltipModule,
+ RouterTestingModule
+ ],
+ declarations: [OsdFlagsIndivModalComponent],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ httpTesting = TestBed.inject(HttpTestingController);
+ fixture = TestBed.createComponent(OsdFlagsIndivModalComponent);
+ component = fixture.componentInstance;
+ osdService = TestBed.inject(OsdService);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('getActivatedIndivFlags', () => {
+ function checkFlagsCount(
+ counts: { [key: string]: number },
+ expected: { [key: string]: number }
+ ) {
+ Object.entries(expected).forEach(([expectedKey, expectedValue]) => {
+ expect(counts[expectedKey]).toBe(expectedValue);
+ });
+ }
+
+ it('should count correctly if no flag has been set', () => {
+ component.selected = generateSelected();
+ const countedFlags = component.getActivatedIndivFlags();
+ checkFlagsCount(countedFlags, { noup: 0, nodown: 0, noin: 0, noout: 0 });
+ });
+
+ it('should count correctly if some of the flags have been set', () => {
+ component.selected = generateSelected([['noin'], ['noin', 'noout'], ['nodown']]);
+ const countedFlags = component.getActivatedIndivFlags();
+ checkFlagsCount(countedFlags, { noup: 0, nodown: 1, noin: 2, noout: 1 });
+ });
+ });
+
+ describe('changeValue', () => {
+ it('should change value correctly and set indeterminate to false', () => {
+ const testFlag = component.flags[0];
+ const value = testFlag.value;
+ component.changeValue(testFlag);
+ expect(testFlag.value).toBe(!value);
+ expect(testFlag.indeterminate).toBeFalsy();
+ });
+ });
+
+ describe('resetSelection', () => {
+ it('should set a new flags object by deep cloning the initial selection', () => {
+ component.resetSelection();
+ expect(component.flags === component.initialSelection).toBeFalsy();
+ });
+ });
+
+ describe('OSD single-select', () => {
+ beforeEach(() => {
+ component.selected = [{ osd: 0 }];
+ });
+
+ describe('ngOnInit', () => {
+ it('should clone flags as initial selection', () => {
+ expect(component.flags === component.initialSelection).toBeFalsy();
+ });
+
+ it('should initialize form correctly if no individual and global flags are set', () => {
+ component.selected[0]['state'] = ['exists', 'up'];
+ spyOn(osdService, 'getFlags').and.callFake(() => observableOf([]));
+ fixture.detectChanges();
+ checkFlags(component.flags);
+ });
+
+ it('should initialize form correctly if individual but no global flags are set', () => {
+ component.selected[0]['state'] = ['exists', 'noout', 'up'];
+ spyOn(osdService, 'getFlags').and.callFake(() => observableOf([]));
+ fixture.detectChanges();
+ const expected = {
+ noout: { value: true, clusterWide: false, indeterminate: false }
+ };
+ checkFlags(component.flags, expected);
+ });
+
+ it('should initialize form correctly if multiple individual but no global flags are set', () => {
+ component.selected[0]['state'] = ['exists', 'noin', 'noout', 'up'];
+ spyOn(osdService, 'getFlags').and.callFake(() => observableOf([]));
+ fixture.detectChanges();
+ const expected = {
+ noout: { value: true, clusterWide: false, indeterminate: false },
+ noin: { value: true, clusterWide: false, indeterminate: false }
+ };
+ checkFlags(component.flags, expected);
+ });
+
+ it('should initialize form correctly if no individual but global flags are set', () => {
+ component.selected[0]['state'] = ['exists', 'up'];
+ spyOn(osdService, 'getFlags').and.callFake(() => observableOf(['noout']));
+ fixture.detectChanges();
+ const expected = {
+ noout: { value: false, clusterWide: true, indeterminate: false }
+ };
+ checkFlags(component.flags, expected);
+ });
+ });
+
+ describe('submitAction', () => {
+ let notificationType: NotificationType;
+ let notificationService: NotificationService;
+ let bsModalRef: NgbActiveModal;
+ let flags: object;
+
+ beforeEach(() => {
+ notificationService = TestBed.inject(NotificationService);
+ spyOn(notificationService, 'show').and.callFake((type) => {
+ notificationType = type;
+ });
+ bsModalRef = TestBed.inject(NgbActiveModal);
+ spyOn(bsModalRef, 'close').and.callThrough();
+ flags = {
+ nodown: false,
+ noin: false,
+ noout: false,
+ noup: false
+ };
+ });
+
+ it('should submit an activated flag', () => {
+ const code = component.flags[0].code;
+ component.flags[0].value = true;
+ component.submitAction();
+ flags[code] = true;
+
+ const req = httpTesting.expectOne('api/osd/flags/individual');
+ req.flush({ flags, ids: [0] });
+ expect(req.request.body).toEqual({ flags, ids: [0] });
+ expect(notificationType).toBe(NotificationType.success);
+ expect(component.activeModal.close).toHaveBeenCalledTimes(1);
+ });
+
+ it('should submit multiple flags', () => {
+ const codes = [component.flags[0].code, component.flags[1].code];
+ component.flags[0].value = true;
+ component.flags[1].value = true;
+ component.submitAction();
+ flags[codes[0]] = true;
+ flags[codes[1]] = true;
+
+ const req = httpTesting.expectOne('api/osd/flags/individual');
+ req.flush({ flags, ids: [0] });
+ expect(req.request.body).toEqual({ flags, ids: [0] });
+ expect(notificationType).toBe(NotificationType.success);
+ expect(component.activeModal.close).toHaveBeenCalledTimes(1);
+ });
+
+ it('should hide modal if request fails', () => {
+ component.flags = [];
+ component.submitAction();
+ const req = httpTesting.expectOne('api/osd/flags/individual');
+ req.flush([], { status: 500, statusText: 'failure' });
+ expect(notificationService.show).toHaveBeenCalledTimes(0);
+ expect(component.activeModal.close).toHaveBeenCalledTimes(1);
+ });
+ });
+ });
+
+ describe('OSD multi-select', () => {
+ describe('ngOnInit', () => {
+ it('should initialize form correctly if same individual and no global flags are set', () => {
+ component.selected = generateSelected([['noin'], ['noin'], ['noin']]);
+ spyOn(osdService, 'getFlags').and.callFake(() => observableOf([]));
+ fixture.detectChanges();
+ const expected = {
+ noin: { value: true, clusterWide: false, indeterminate: false }
+ };
+ checkFlags(component.flags, expected);
+ });
+
+ it('should initialize form correctly if different individual and no global flags are set', () => {
+ component.selected = generateSelected([['noin'], ['noout'], ['noin']]);
+ spyOn(osdService, 'getFlags').and.callFake(() => observableOf([]));
+ fixture.detectChanges();
+ const expected = {
+ noin: { value: false, clusterWide: false, indeterminate: true },
+ noout: { value: false, clusterWide: false, indeterminate: true }
+ };
+ checkFlags(component.flags, expected);
+ });
+
+ it('should initialize form correctly if different and same individual and no global flags are set', () => {
+ component.selected = generateSelected([
+ ['noin', 'nodown'],
+ ['noout', 'nodown'],
+ ['noin', 'nodown']
+ ]);
+ spyOn(osdService, 'getFlags').and.callFake(() => observableOf([]));
+ fixture.detectChanges();
+ const expected = {
+ noin: { value: false, clusterWide: false, indeterminate: true },
+ noout: { value: false, clusterWide: false, indeterminate: true },
+ nodown: { value: true, clusterWide: false, indeterminate: false }
+ };
+ checkFlags(component.flags, expected);
+ });
+
+ it('should initialize form correctly if a flag is set for all OSDs individually and globally', () => {
+ component.selected = generateSelected([
+ ['noin', 'nodown'],
+ ['noout', 'nodown'],
+ ['noin', 'nodown']
+ ]);
+ spyOn(osdService, 'getFlags').and.callFake(() => observableOf(['noout']));
+ fixture.detectChanges();
+ const expected = {
+ noin: { value: false, clusterWide: false, indeterminate: true },
+ noout: { value: false, clusterWide: true, indeterminate: true },
+ nodown: { value: true, clusterWide: false, indeterminate: false }
+ };
+ checkFlags(component.flags, expected);
+ });
+
+ it('should initialize form correctly if different individual and global flags are set', () => {
+ component.selected = generateSelected([
+ ['noin', 'nodown', 'noout'],
+ ['noout', 'nodown'],
+ ['noin', 'nodown', 'noout']
+ ]);
+ spyOn(osdService, 'getFlags').and.callFake(() => observableOf(['noout']));
+ fixture.detectChanges();
+ const expected = {
+ noin: { value: false, clusterWide: false, indeterminate: true },
+ noout: { value: true, clusterWide: true, indeterminate: false },
+ nodown: { value: true, clusterWide: false, indeterminate: false }
+ };
+ checkFlags(component.flags, expected);
+ });
+ });
+
+ describe('submitAction', () => {
+ let notificationType: NotificationType;
+ let notificationService: NotificationService;
+ let bsModalRef: NgbActiveModal;
+ let flags: object;
+
+ beforeEach(() => {
+ notificationService = TestBed.inject(NotificationService);
+ spyOn(notificationService, 'show').and.callFake((type) => {
+ notificationType = type;
+ });
+ bsModalRef = TestBed.inject(NgbActiveModal);
+ spyOn(bsModalRef, 'close').and.callThrough();
+ flags = {
+ nodown: false,
+ noin: false,
+ noout: false,
+ noup: false
+ };
+ });
+
+ it('should submit an activated flag for multiple OSDs', () => {
+ component.selected = generateSelected();
+ const code = component.flags[0].code;
+ const submittedIds = [0, 1, 2];
+ component.flags[0].value = true;
+ component.submitAction();
+ flags[code] = true;
+
+ const req = httpTesting.expectOne('api/osd/flags/individual');
+ req.flush({ flags, ids: submittedIds });
+ expect(req.request.body).toEqual({ flags, ids: submittedIds });
+ expect(notificationType).toBe(NotificationType.success);
+ expect(component.activeModal.close).toHaveBeenCalledTimes(1);
+ });
+
+ it('should submit multiple flags for multiple OSDs', () => {
+ component.selected = generateSelected();
+ const codes = [component.flags[0].code, component.flags[1].code];
+ const submittedIds = [0, 1, 2];
+ component.flags[0].value = true;
+ component.flags[1].value = true;
+ component.submitAction();
+ flags[codes[0]] = true;
+ flags[codes[1]] = true;
+
+ const req = httpTesting.expectOne('api/osd/flags/individual');
+ req.flush({ flags, ids: submittedIds });
+ expect(req.request.body).toEqual({ flags, ids: submittedIds });
+ expect(notificationType).toBe(NotificationType.success);
+ expect(component.activeModal.close).toHaveBeenCalledTimes(1);
+ });
+ });
+ });
+
+ function checkFlags(flags: Flag[], expected: object = {}) {
+ flags.forEach((flag) => {
+ let value = false;
+ let clusterWide = false;
+ let indeterminate = false;
+ if (Object.keys(expected).includes(flag.code)) {
+ value = expected[flag.code]['value'];
+ clusterWide = expected[flag.code]['clusterWide'];
+ indeterminate = expected[flag.code]['indeterminate'];
+ }
+ expect(flag.value).toBe(value);
+ expect(flag.clusterWide).toBe(clusterWide);
+ expect(flag.indeterminate).toBe(indeterminate);
+ });
+ }
+
+ function generateSelected(flags: string[][] = []) {
+ const defaultFlags = ['exists', 'up'];
+ const osds = [];
+ const count = flags.length || 3;
+ for (let i = 0; i < count; i++) {
+ const osd = {
+ osd: i,
+ state: defaultFlags.concat(flags[i]) || defaultFlags
+ };
+ osds.push(osd);
+ }
+ return osds;
+ }
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts
new file mode 100644
index 000000000..e9e0b876f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts
@@ -0,0 +1,134 @@
+import { Component, OnInit } from '@angular/core';
+import { FormGroup } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+
+import { OsdService } from '~/app/shared/api/osd.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { Flag } from '~/app/shared/models/flag';
+import { Permissions } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+
+@Component({
+ selector: 'cd-osd-flags-indiv-modal',
+ templateUrl: './osd-flags-indiv-modal.component.html',
+ styleUrls: ['./osd-flags-indiv-modal.component.scss']
+})
+export class OsdFlagsIndivModalComponent implements OnInit {
+ permissions: Permissions;
+ selected: object[];
+ initialSelection: Flag[] = [];
+ osdFlagsForm = new FormGroup({});
+ flags: Flag[] = [
+ {
+ code: 'noup',
+ name: $localize`No Up`,
+ description: $localize`OSDs are not allowed to start`,
+ value: false,
+ clusterWide: false,
+ indeterminate: false
+ },
+ {
+ code: 'nodown',
+ name: $localize`No Down`,
+ description: $localize`OSD failure reports are being ignored, such that the monitors will not mark OSDs down`,
+ value: false,
+ clusterWide: false,
+ indeterminate: false
+ },
+ {
+ code: 'noin',
+ name: $localize`No In`,
+ description: $localize`OSDs that were previously marked out will not be marked back in when they start`,
+ value: false,
+ clusterWide: false,
+ indeterminate: false
+ },
+ {
+ code: 'noout',
+ name: $localize`No Out`,
+ description: $localize`OSDs will not automatically be marked out after the configured interval`,
+ value: false,
+ clusterWide: false,
+ indeterminate: false
+ }
+ ];
+ clusterWideTooltip: string = $localize`The flag has been enabled for the entire cluster.`;
+
+ constructor(
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n,
+ private authStorageService: AuthStorageService,
+ private osdService: OsdService,
+ private notificationService: NotificationService
+ ) {
+ this.permissions = this.authStorageService.getPermissions();
+ }
+
+ ngOnInit() {
+ const osdCount = this.selected.length;
+ this.osdService.getFlags().subscribe((clusterWideFlags: string[]) => {
+ const activatedIndivFlags = this.getActivatedIndivFlags();
+ this.flags.forEach((flag) => {
+ const flagCount = activatedIndivFlags[flag.code];
+ if (clusterWideFlags.includes(flag.code)) {
+ flag.clusterWide = true;
+ }
+
+ if (flagCount === osdCount) {
+ flag.value = true;
+ } else if (flagCount > 0) {
+ flag.indeterminate = true;
+ }
+ });
+ this.initialSelection = _.cloneDeep(this.flags);
+ });
+ }
+
+ getActivatedIndivFlags(): { [flag: string]: number } {
+ const flagsCount = {};
+ this.flags.forEach((flag) => {
+ flagsCount[flag.code] = 0;
+ });
+
+ [].concat(...this.selected.map((osd) => osd['state'])).map((activatedFlag) => {
+ if (Object.keys(flagsCount).includes(activatedFlag)) {
+ flagsCount[activatedFlag] = flagsCount[activatedFlag] + 1;
+ }
+ });
+ return flagsCount;
+ }
+
+ changeValue(flag: Flag) {
+ flag.value = !flag.value;
+ flag.indeterminate = false;
+ }
+
+ resetSelection() {
+ this.flags = _.cloneDeep(this.initialSelection);
+ }
+
+ submitAction() {
+ const activeFlags = {};
+ this.flags.forEach((flag) => {
+ if (flag.indeterminate) {
+ activeFlags[flag.code] = null;
+ } else {
+ activeFlags[flag.code] = flag.value;
+ }
+ });
+ const selectedIds = this.selected.map((selection) => selection['osd']);
+ this.osdService.updateIndividualFlags(activeFlags, selectedIds).subscribe(
+ () => {
+ this.notificationService.show(NotificationType.success, $localize`Updated OSD Flags`);
+ this.activeModal.close();
+ },
+ () => {
+ this.activeModal.close();
+ }
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html
new file mode 100644
index 000000000..2ae6460fb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html
@@ -0,0 +1,41 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container class="modal-title"
+ i18n>Cluster-wide OSD Flags</ng-container>
+
+ <ng-container class="modal-content">
+ <form name="osdFlagsForm"
+ #formDir="ngForm"
+ [formGroup]="osdFlagsForm"
+ novalidate
+ cdFormScope="osd">
+ <div class="modal-body osd-modal">
+ <div class="custom-control custom-checkbox"
+ *ngFor="let flag of flags; let last = last">
+ <input class="custom-control-input"
+ type="checkbox"
+ [checked]="flag.value"
+ (change)="flag.value = !flag.value"
+ [name]="flag.code"
+ [id]="flag.code"
+ [disabled]="flag.disabled">
+ <label class="custom-control-label"
+ [for]="flag.code"
+ ng-class="['tc_' + key]">
+ <strong>{{ flag.name }}</strong>
+ <br>
+ <span class="form-text text-muted">{{ flag.description }}</span>
+ </label>
+ <hr class="m-1"
+ *ngIf="!last">
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="submitAction()"
+ [form]="osdFlagsForm"
+ [showSubmit]="permissions.osd.update"
+ [submitText]="actionLabels.UPDATE"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.spec.ts
new file mode 100644
index 000000000..b6bea06f9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.spec.ts
@@ -0,0 +1,99 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { ToastrModule } from 'ngx-toastr';
+
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { OsdFlagsModalComponent } from './osd-flags-modal.component';
+
+function getFlagsArray(component: OsdFlagsModalComponent) {
+ const allFlags = _.cloneDeep(component.allFlags);
+ allFlags['purged_snapdirs'].value = true;
+ allFlags['pause'].value = true;
+ return _.toArray(allFlags);
+}
+
+describe('OsdFlagsModalComponent', () => {
+ let component: OsdFlagsModalComponent;
+ let fixture: ComponentFixture<OsdFlagsModalComponent>;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ imports: [
+ ReactiveFormsModule,
+ SharedModule,
+ HttpClientTestingModule,
+ RouterTestingModule,
+ ToastrModule.forRoot()
+ ],
+ declarations: [OsdFlagsModalComponent],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ httpTesting = TestBed.inject(HttpTestingController);
+ fixture = TestBed.createComponent(OsdFlagsModalComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should finish running ngOnInit', () => {
+ fixture.detectChanges();
+
+ const flags = getFlagsArray(component);
+
+ const req = httpTesting.expectOne('api/osd/flags');
+ req.flush(['purged_snapdirs', 'pause', 'foo']);
+
+ expect(component.flags).toEqual(flags);
+ expect(component.unknownFlags).toEqual(['foo']);
+ });
+
+ describe('test submitAction', function () {
+ let notificationType: NotificationType;
+ let notificationService: NotificationService;
+ let bsModalRef: NgbActiveModal;
+
+ beforeEach(() => {
+ notificationService = TestBed.inject(NotificationService);
+ spyOn(notificationService, 'show').and.callFake((type) => {
+ notificationType = type;
+ });
+
+ bsModalRef = TestBed.inject(NgbActiveModal);
+ spyOn(bsModalRef, 'close').and.callThrough();
+ component.unknownFlags = ['foo'];
+ });
+
+ it('should run submitAction', () => {
+ component.flags = getFlagsArray(component);
+ component.submitAction();
+ const req = httpTesting.expectOne('api/osd/flags');
+ req.flush(['purged_snapdirs', 'pause', 'foo']);
+ expect(req.request.body).toEqual({ flags: ['pause', 'purged_snapdirs', 'foo'] });
+
+ expect(notificationType).toBe(NotificationType.success);
+ expect(component.activeModal.close).toHaveBeenCalledTimes(1);
+ });
+
+ it('should hide modal if request fails', () => {
+ component.flags = [];
+ component.submitAction();
+ const req = httpTesting.expectOne('api/osd/flags');
+ req.flush([], { status: 500, statusText: 'failure' });
+
+ expect(notificationService.show).toHaveBeenCalledTimes(0);
+ expect(component.activeModal.close).toHaveBeenCalledTimes(1);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts
new file mode 100644
index 000000000..640719382
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts
@@ -0,0 +1,156 @@
+import { Component, OnInit } from '@angular/core';
+import { FormGroup } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+
+import { OsdService } from '~/app/shared/api/osd.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { Permissions } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+
+@Component({
+ selector: 'cd-osd-flags-modal',
+ templateUrl: './osd-flags-modal.component.html',
+ styleUrls: ['./osd-flags-modal.component.scss']
+})
+export class OsdFlagsModalComponent implements OnInit {
+ permissions: Permissions;
+
+ osdFlagsForm = new FormGroup({});
+
+ allFlags = {
+ noin: {
+ code: 'noin',
+ name: $localize`No In`,
+ value: false,
+ description: $localize`OSDs that were previously marked out will not be marked back in when they start`
+ },
+ noout: {
+ code: 'noout',
+ name: $localize`No Out`,
+ value: false,
+ description: $localize`OSDs will not automatically be marked out after the configured interval`
+ },
+ noup: {
+ code: 'noup',
+ name: $localize`No Up`,
+ value: false,
+ description: $localize`OSDs are not allowed to start`
+ },
+ nodown: {
+ code: 'nodown',
+ name: $localize`No Down`,
+ value: false,
+ description: $localize`OSD failure reports are being ignored, such that the monitors will not mark OSDs down`
+ },
+ pause: {
+ code: 'pause',
+ name: $localize`Pause`,
+ value: false,
+ description: $localize`Pauses reads and writes`
+ },
+ noscrub: {
+ code: 'noscrub',
+ name: $localize`No Scrub`,
+ value: false,
+ description: $localize`Scrubbing is disabled`
+ },
+ 'nodeep-scrub': {
+ code: 'nodeep-scrub',
+ name: $localize`No Deep Scrub`,
+ value: false,
+ description: $localize`Deep Scrubbing is disabled`
+ },
+ nobackfill: {
+ code: 'nobackfill',
+ name: $localize`No Backfill`,
+ value: false,
+ description: $localize`Backfilling of PGs is suspended`
+ },
+ norebalance: {
+ code: 'norebalance',
+ name: $localize`No Rebalance`,
+ value: false,
+ description: $localize`OSD will choose not to backfill unless PG is also degraded`
+ },
+ norecover: {
+ code: 'norecover',
+ name: $localize`No Recover`,
+ value: false,
+ description: $localize`Recovery of PGs is suspended`
+ },
+ sortbitwise: {
+ code: 'sortbitwise',
+ name: $localize`Bitwise Sort`,
+ value: false,
+ description: $localize`Use bitwise sort`,
+ disabled: true
+ },
+ purged_snapdirs: {
+ code: 'purged_snapdirs',
+ name: $localize`Purged Snapdirs`,
+ value: false,
+ description: $localize`OSDs have converted snapsets`,
+ disabled: true
+ },
+ recovery_deletes: {
+ code: 'recovery_deletes',
+ name: $localize`Recovery Deletes`,
+ value: false,
+ description: $localize`Deletes performed during recovery instead of peering`,
+ disabled: true
+ },
+ pglog_hardlimit: {
+ code: 'pglog_hardlimit',
+ name: $localize`PG Log Hard Limit`,
+ value: false,
+ description: $localize`Puts a hard limit on pg log length`,
+ disabled: true
+ }
+ };
+ flags: any[];
+ unknownFlags: string[] = [];
+
+ constructor(
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n,
+ private authStorageService: AuthStorageService,
+ private osdService: OsdService,
+ private notificationService: NotificationService
+ ) {
+ this.permissions = this.authStorageService.getPermissions();
+ }
+
+ ngOnInit() {
+ this.osdService.getFlags().subscribe((res: string[]) => {
+ res.forEach((value) => {
+ if (this.allFlags[value]) {
+ this.allFlags[value].value = true;
+ } else {
+ this.unknownFlags.push(value);
+ }
+ });
+ this.flags = _.toArray(this.allFlags);
+ });
+ }
+
+ submitAction() {
+ const newFlags = this.flags
+ .filter((flag) => flag.value)
+ .map((flag) => flag.code)
+ .concat(this.unknownFlags);
+
+ this.osdService.updateFlags(newFlags).subscribe(
+ () => {
+ this.notificationService.show(NotificationType.success, $localize`Updated OSD Flags`);
+ this.activeModal.close();
+ },
+ () => {
+ this.activeModal.close();
+ }
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/drive-group.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/drive-group.model.ts
new file mode 100644
index 000000000..841e947b8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/drive-group.model.ts
@@ -0,0 +1,97 @@
+import _ from 'lodash';
+
+import { CdTableColumnFiltersChange } from '~/app/shared/models/cd-table-column-filters-change';
+import { FormatterService } from '~/app/shared/services/formatter.service';
+
+export class DriveGroup {
+ spec: Object;
+
+ // Map from filter column prop to device selection attribute name
+ private deviceSelectionAttrs: {
+ [key: string]: {
+ name: string;
+ formatter?: Function;
+ };
+ };
+
+ private formatterService: FormatterService;
+
+ constructor() {
+ this.reset();
+ this.formatterService = new FormatterService();
+ this.deviceSelectionAttrs = {
+ 'sys_api.vendor': {
+ name: 'vendor'
+ },
+ 'sys_api.model': {
+ name: 'model'
+ },
+ device_id: {
+ name: 'device_id'
+ },
+ human_readable_type: {
+ name: 'rotational',
+ formatter: (value: string) => {
+ return value.toLowerCase() === 'hdd';
+ }
+ },
+ 'sys_api.size': {
+ name: 'size',
+ formatter: (value: string) => {
+ return this.formatterService
+ .format_number(value, 1024, ['B', 'KB', 'MB', 'GB', 'TB', 'PB'])
+ .replace(' ', '');
+ }
+ }
+ };
+ }
+
+ reset() {
+ this.spec = {
+ service_type: 'osd',
+ service_id: `dashboard-${_.now()}`
+ };
+ }
+
+ setName(name: string) {
+ this.spec['service_id'] = name;
+ }
+
+ setHostPattern(pattern: string) {
+ this.spec['host_pattern'] = pattern;
+ }
+
+ setDeviceSelection(type: string, appliedFilters: CdTableColumnFiltersChange['filters']) {
+ const key = `${type}_devices`;
+ this.spec[key] = {};
+ appliedFilters.forEach((filter) => {
+ const attr = this.deviceSelectionAttrs[filter.prop];
+ if (attr) {
+ const name = attr.name;
+ this.spec[key][name] = attr.formatter ? attr.formatter(filter.value.raw) : filter.value.raw;
+ }
+ });
+ }
+
+ clearDeviceSelection(type: string) {
+ const key = `${type}_devices`;
+ delete this.spec[key];
+ }
+
+ setSlots(type: string, slots: number) {
+ const key = `${type}_slots`;
+ if (slots === 0) {
+ delete this.spec[key];
+ } else {
+ this.spec[key] = slots;
+ }
+ }
+
+ setFeature(feature: string, enabled: boolean) {
+ if (enabled) {
+ this.spec[feature] = true;
+ } else {
+ delete this.spec[feature];
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-feature.interface.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-feature.interface.ts
new file mode 100644
index 000000000..8c9dc452e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-feature.interface.ts
@@ -0,0 +1,4 @@
+export interface OsdFeature {
+ desc: string;
+ key?: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.html
new file mode 100644
index 000000000..d4b6d9fae
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.html
@@ -0,0 +1,213 @@
+<cd-orchestrator-doc-panel *ngIf="!hasOrchestrator"></cd-orchestrator-doc-panel>
+
+<div class="card"
+ *cdFormLoading="loading">
+ <div i18n="form title|Example: Create Pool@@formTitle"
+ class="card-header"
+ *ngIf="!hideTitle">{{ action | titlecase }} {{ resource | upperFirst }}</div>
+ <div class="card-body ml-2">
+ <form name="form"
+ #formDir="ngForm"
+ [formGroup]="form"
+ novalidate>
+ <div class="accordion">
+ <div class="card">
+ <div class="card-header">
+ <h2 class="mb-0">
+ <button class="btn btn-link btn-block text-left dropdown-toggle"
+ data-toggle="collapse"
+ aria-label="toggle deployment options"
+ [attr.aria-expanded]="simpleDeployment"
+ (click)="emitDeploymentMode()"
+ i18n>Deployment Options</button>
+ </h2>
+ </div>
+ </div>
+ <div class="collapse"
+ [ngClass]="{show: simpleDeployment}">
+ <div class="card-body d-flex flex-column">
+ <div class="pt-3 pb-3"
+ *ngFor="let optionName of optionNames">
+ <div class="custom-control custom-radio custom-control-inline">
+ <input class="custom-control-input"
+ type="radio"
+ name="deploymentOption"
+ [id]="optionName"
+ [value]="optionName"
+ formControlName="deploymentOption"
+ (change)="emitDeploymentSelection()"
+ [attr.disabled]="!deploymentOptions?.options[optionName].available ? true : null">
+ <label class="custom-control-label"
+ [id]="'label_' + optionName"
+ [for]="optionName"
+ i18n>{{ deploymentOptions?.options[optionName].title }}
+ {{ deploymentOptions.recommended_option === optionName ? "(Recommended)" : "" }}
+ <cd-helper>
+ <span>{{ deploymentOptions?.options[optionName].desc }}</span>
+ </cd-helper>
+ </label>
+ </div>
+ </div>
+ <!-- @TODO: Visualize the storage used on a chart -->
+ <!-- <div class="pie-chart">
+ <h4 class="text-center">Selected Capacity</h4>
+ <h5 class="margin text-center">10 Hosts | 30 NVMes </h5>
+ <div class="char-i-contain">
+ <cd-health-pie [data]="data"
+ [config]="rawCapacityChartConfig"
+ [isBytesData]="true"
+ (prepareFn)="prepareRawUsage($event[0], $event[1])">
+ </cd-health-pie>
+ </div>
+ </div> -->
+ </div>
+ </div>
+ <div class="card">
+ <div class="card-header">
+ <h2 class="mb-0">
+ <button class="btn btn-link btn-block text-left dropdown-toggle"
+ data-toggle="collapse"
+ aria-label="toggle advanced mode"
+ [attr.aria-expanded]="!simpleDeployment"
+ (click)="emitDeploymentMode()"
+ i18n>Advanced Mode</button>
+ </h2>
+ </div>
+ </div>
+ <div class="collapse"
+ [ngClass]="{show: !simpleDeployment}">
+ <div class="card-body">
+ <div class="card-body">
+ <fieldset>
+ <cd-osd-devices-selection-groups #dataDeviceSelectionGroups
+ name="Primary"
+ type="data"
+ [availDevices]="availDevices"
+ [canSelect]="availDevices.length !== 0"
+ (selected)="onDevicesSelected($event)"
+ (cleared)="onDevicesCleared($event)">
+ </cd-osd-devices-selection-groups>
+ </fieldset>
+
+ <!-- Shared devices -->
+ <fieldset>
+ <legend i18n>Shared devices</legend>
+
+ <!-- WAL devices button and table -->
+ <cd-osd-devices-selection-groups #walDeviceSelectionGroups
+ name="WAL"
+ type="wal"
+ [availDevices]="availDevices"
+ [canSelect]="dataDeviceSelectionGroups.devices.length !== 0"
+ (selected)="onDevicesSelected($event)"
+ (cleared)="onDevicesCleared($event)">
+ </cd-osd-devices-selection-groups>
+
+ <!-- WAL slots -->
+ <div class="form-group row"
+ *ngIf="walDeviceSelectionGroups.devices.length !== 0">
+ <label class="cd-col-form-label"
+ for="walSlots">
+ <ng-container i18n>WAL slots</ng-container>
+ <cd-helper>
+ <span i18n>How many OSDs per WAL device.</span>
+ <br>
+ <span i18n>Specify 0 to let Orchestrator backend decide it.</span>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ id="walSlots"
+ name="walSlots"
+ type="number"
+ min="0"
+ formControlName="walSlots">
+ <span class="invalid-feedback"
+ *ngIf="form.showError('walSlots', formDir, 'min')"
+ i18n>Value should be greater than or equal to 0</span>
+ </div>
+ </div>
+
+ <!-- DB devices button and table -->
+ <cd-osd-devices-selection-groups #dbDeviceSelectionGroups
+ name="DB"
+ type="db"
+ [availDevices]="availDevices"
+ [canSelect]="dataDeviceSelectionGroups.devices.length !== 0"
+ (selected)="onDevicesSelected($event)"
+ (cleared)="onDevicesCleared($event)">
+ </cd-osd-devices-selection-groups>
+
+ <!-- DB slots -->
+ <div class="form-group row"
+ *ngIf="dbDeviceSelectionGroups.devices.length !== 0">
+ <label class="cd-col-form-label"
+ for="dbSlots">
+ <ng-container i18n>DB slots</ng-container>
+ <cd-helper>
+ <span i18n>How many OSDs per DB device.</span>
+ <br>
+ <span i18n>Specify 0 to let Orchestrator backend decide it.</span>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ id="dbSlots"
+ name="dbSlots"
+ type="number"
+ min="0"
+ formControlName="dbSlots">
+ <span class="invalid-feedback"
+ *ngIf="form.showError('dbSlots', formDir, 'min')"
+ i18n>Value should be greater than or equal to 0</span>
+ </div>
+ </div>
+ </fieldset>
+ </div>
+ </div>
+ </div>
+
+ <!-- Features -->
+ <div class="card">
+ <div class="card-header">
+ <h2 class="mb-0">
+ <button class="btn btn-link btn-block text-left dropdown-toggle"
+ data-toggle="collapse"
+ aria-label="features"
+ aria-expanded="true"
+ i18n>Features</button>
+ </h2>
+ </div>
+ </div>
+ <div class="collapse show">
+ <div class="card-body d-flex flex-column">
+ <div class="pt-3 pb-3"
+ formGroupName="features">
+ <div class="custom-control custom-checkbox"
+ *ngFor="let feature of featureList">
+ <input type="checkbox"
+ class="custom-control-input"
+ id="{{ feature.key }}"
+ name="{{ feature.key }}"
+ formControlName="{{ feature.key }}"
+ (change)="emitDeploymentSelection()">
+ <label class="custom-control-label"
+ for="{{ feature.key }}">{{ feature.desc }}</label>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </form>
+ </div>
+
+ <div class="card-footer"
+ *ngIf="!hideSubmitBtn">
+ <cd-form-button-panel #previewButtonPanel
+ (submitActionEvent)="submit()"
+ [form]="form"
+ [disabled]="dataDeviceSelectionGroups.devices.length === 0 && !simpleDeployment"
+ [submitText]="simpleDeployment ? 'Create OSDs' : actionLabels.PREVIEW"
+ wrappingClass="text-right"></cd-form-button-panel>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.spec.ts
new file mode 100644
index 000000000..725fc953f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.spec.ts
@@ -0,0 +1,309 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+import { BehaviorSubject, of } from 'rxjs';
+
+import { InventoryDevice } from '~/app/ceph/cluster/inventory/inventory-devices/inventory-device.model';
+import { InventoryDevicesComponent } from '~/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component';
+import { DashboardModule } from '~/app/ceph/dashboard/dashboard.module';
+import { HostService } from '~/app/shared/api/host.service';
+import { OrchestratorService } from '~/app/shared/api/orchestrator.service';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import {
+ DeploymentOptions,
+ OsdDeploymentOptions
+} from '~/app/shared/models/osd-deployment-options';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, FixtureHelper, FormHelper } from '~/testing/unit-test-helper';
+import { DevicesSelectionChangeEvent } from '../osd-devices-selection-groups/devices-selection-change-event.interface';
+import { DevicesSelectionClearEvent } from '../osd-devices-selection-groups/devices-selection-clear-event.interface';
+import { OsdDevicesSelectionGroupsComponent } from '../osd-devices-selection-groups/osd-devices-selection-groups.component';
+import { OsdFormComponent } from './osd-form.component';
+
+describe('OsdFormComponent', () => {
+ let form: CdFormGroup;
+ let component: OsdFormComponent;
+ let formHelper: FormHelper;
+ let fixture: ComponentFixture<OsdFormComponent>;
+ let fixtureHelper: FixtureHelper;
+ let orchService: OrchestratorService;
+ let hostService: HostService;
+ let summaryService: SummaryService;
+ const devices: InventoryDevice[] = [
+ {
+ hostname: 'node0',
+ uid: '1',
+
+ path: '/dev/sda',
+ sys_api: {
+ vendor: 'VENDOR',
+ model: 'MODEL',
+ size: 1024,
+ rotational: 'false',
+ human_readable_size: '1 KB'
+ },
+ available: true,
+ rejected_reasons: [''],
+ device_id: 'VENDOR-MODEL-ID',
+ human_readable_type: 'nvme/ssd',
+ osd_ids: []
+ }
+ ];
+
+ const deploymentOptions: DeploymentOptions = {
+ options: {
+ cost_capacity: {
+ name: OsdDeploymentOptions.COST_CAPACITY,
+ available: true,
+ capacity: 0,
+ used: 0,
+ hdd_used: 0,
+ ssd_used: 0,
+ nvme_used: 0,
+ title: 'Cost/Capacity-optimized',
+ desc: 'All the available HDDs are selected'
+ },
+ throughput_optimized: {
+ name: OsdDeploymentOptions.THROUGHPUT,
+ available: false,
+ capacity: 0,
+ used: 0,
+ hdd_used: 0,
+ ssd_used: 0,
+ nvme_used: 0,
+ title: 'Throughput-optimized',
+ desc: 'HDDs/SSDs are selected for data devices and SSDs/NVMes for DB/WAL devices'
+ },
+ iops_optimized: {
+ name: OsdDeploymentOptions.IOPS,
+ available: false,
+ capacity: 0,
+ used: 0,
+ hdd_used: 0,
+ ssd_used: 0,
+ nvme_used: 0,
+ title: 'IOPS-optimized',
+ desc: 'All the available NVMes are selected'
+ }
+ },
+ recommended_option: OsdDeploymentOptions.COST_CAPACITY
+ };
+
+ const expectPreviewButton = (enabled: boolean) => {
+ const debugElement = fixtureHelper.getElementByCss('.tc_submitButton');
+ expect(debugElement.nativeElement.disabled).toBe(!enabled);
+ };
+
+ const selectDevices = (type: string) => {
+ const event: DevicesSelectionChangeEvent = {
+ type: type,
+ filters: [],
+ data: devices,
+ dataOut: []
+ };
+ component.onDevicesSelected(event);
+ if (type === 'data') {
+ component.dataDeviceSelectionGroups.devices = devices;
+ } else if (type === 'wal') {
+ component.walDeviceSelectionGroups.devices = devices;
+ } else if (type === 'db') {
+ component.dbDeviceSelectionGroups.devices = devices;
+ }
+ fixture.detectChanges();
+ };
+
+ const clearDevices = (type: string) => {
+ const event: DevicesSelectionClearEvent = {
+ type: type,
+ clearedDevices: []
+ };
+ component.onDevicesCleared(event);
+ fixture.detectChanges();
+ };
+
+ const features = ['encrypted'];
+ const checkFeatures = (enabled: boolean) => {
+ for (const feature of features) {
+ const element = fixtureHelper.getElementByCss(`#${feature}`).nativeElement;
+ expect(element.disabled).toBe(!enabled);
+ expect(element.checked).toBe(false);
+ }
+ };
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ HttpClientTestingModule,
+ FormsModule,
+ SharedModule,
+ RouterTestingModule,
+ ReactiveFormsModule,
+ ToastrModule.forRoot(),
+ DashboardModule
+ ],
+ declarations: [OsdFormComponent, OsdDevicesSelectionGroupsComponent, InventoryDevicesComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OsdFormComponent);
+ fixtureHelper = new FixtureHelper(fixture);
+ component = fixture.componentInstance;
+ form = component.form;
+ formHelper = new FormHelper(form);
+ orchService = TestBed.inject(OrchestratorService);
+ hostService = TestBed.inject(HostService);
+ summaryService = TestBed.inject(SummaryService);
+ summaryService['summaryDataSource'] = new BehaviorSubject(null);
+ summaryService['summaryData$'] = summaryService['summaryDataSource'].asObservable();
+ summaryService['summaryDataSource'].next({ version: 'master' });
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('without orchestrator', () => {
+ beforeEach(() => {
+ spyOn(orchService, 'status').and.returnValue(of({ available: false }));
+ spyOn(hostService, 'inventoryDeviceList').and.callThrough();
+ fixture.detectChanges();
+ });
+
+ it('should display info panel to document', () => {
+ fixtureHelper.expectElementVisible('cd-alert-panel', true);
+ fixtureHelper.expectElementVisible('.col-sm-10 form', false);
+ });
+
+ it('should not call inventoryDeviceList', () => {
+ expect(hostService.inventoryDeviceList).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('with orchestrator', () => {
+ beforeEach(() => {
+ component.simpleDeployment = false;
+ spyOn(orchService, 'status').and.returnValue(of({ available: true }));
+ spyOn(hostService, 'inventoryDeviceList').and.returnValue(of([]));
+ component.deploymentOptions = deploymentOptions;
+ fixture.detectChanges();
+ });
+
+ it('should display the accordion', () => {
+ fixtureHelper.expectElementVisible('.card-body .accordion', true);
+ });
+
+ it('should display the three deployment scenarios', () => {
+ fixtureHelper.expectElementVisible('#cost_capacity', true);
+ fixtureHelper.expectElementVisible('#throughput_optimized', true);
+ fixtureHelper.expectElementVisible('#iops_optimized', true);
+ });
+
+ it('should only disable the options that are not available', () => {
+ let radioBtn = fixtureHelper.getElementByCss('#throughput_optimized').nativeElement;
+ expect(radioBtn.disabled).toBeTruthy();
+ radioBtn = fixtureHelper.getElementByCss('#iops_optimized').nativeElement;
+ expect(radioBtn.disabled).toBeTruthy();
+
+ // Make the throughput_optimized option available and verify the option is not disabled
+ deploymentOptions.options['throughput_optimized'].available = true;
+ fixture.detectChanges();
+ radioBtn = fixtureHelper.getElementByCss('#throughput_optimized').nativeElement;
+ expect(radioBtn.disabled).toBeFalsy();
+ });
+
+ it('should be a Recommended option only when it is recommended by backend', () => {
+ const label = fixtureHelper.getElementByCss('#label_cost_capacity').nativeElement;
+ const throughputLabel = fixtureHelper.getElementByCss('#label_throughput_optimized')
+ .nativeElement;
+
+ expect(label.innerHTML).toContain('Recommended');
+ expect(throughputLabel.innerHTML).not.toContain('Recommended');
+
+ deploymentOptions.recommended_option = OsdDeploymentOptions.THROUGHPUT;
+ fixture.detectChanges();
+ expect(throughputLabel.innerHTML).toContain('Recommended');
+ expect(label.innerHTML).not.toContain('Recommended');
+ });
+
+ it('should display form', () => {
+ fixtureHelper.expectElementVisible('cd-alert-panel', false);
+ fixtureHelper.expectElementVisible('.card-body form', true);
+ });
+
+ describe('without data devices selected', () => {
+ it('should disable preview button', () => {
+ expectPreviewButton(false);
+ });
+
+ it('should not display shared devices slots', () => {
+ fixtureHelper.expectElementVisible('#walSlots', false);
+ fixtureHelper.expectElementVisible('#dbSlots', false);
+ });
+
+ it('should disable the checkboxes', () => {
+ checkFeatures(false);
+ });
+ });
+
+ describe('with data devices selected', () => {
+ beforeEach(() => {
+ selectDevices('data');
+ });
+
+ it('should enable preview button', () => {
+ expectPreviewButton(true);
+ });
+
+ it('should not display shared devices slots', () => {
+ fixtureHelper.expectElementVisible('#walSlots', false);
+ fixtureHelper.expectElementVisible('#dbSlots', false);
+ });
+
+ it('should enable the checkboxes', () => {
+ checkFeatures(true);
+ });
+
+ it('should disable the checkboxes after clearing data devices', () => {
+ clearDevices('data');
+ checkFeatures(false);
+ });
+
+ describe('with shared devices selected', () => {
+ beforeEach(() => {
+ selectDevices('wal');
+ selectDevices('db');
+ });
+
+ it('should display slots', () => {
+ fixtureHelper.expectElementVisible('#walSlots', true);
+ fixtureHelper.expectElementVisible('#dbSlots', true);
+ });
+
+ it('validate slots', () => {
+ for (const control of ['walSlots', 'dbSlots']) {
+ formHelper.expectValid(control);
+ formHelper.expectValidChange(control, 1);
+ formHelper.expectErrorChange(control, -1, 'min');
+ }
+ });
+
+ describe('test clearing data devices', () => {
+ beforeEach(() => {
+ clearDevices('data');
+ });
+
+ it('should not display shared devices slots and should disable checkboxes', () => {
+ fixtureHelper.expectElementVisible('#walSlots', false);
+ fixtureHelper.expectElementVisible('#dbSlots', false);
+ checkFeatures(false);
+ });
+ });
+ });
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.ts
new file mode 100644
index 000000000..c2384425e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.ts
@@ -0,0 +1,285 @@
+import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
+import { FormControl } from '@angular/forms';
+import { Router } from '@angular/router';
+
+import _ from 'lodash';
+
+import { InventoryDevice } from '~/app/ceph/cluster/inventory/inventory-devices/inventory-device.model';
+import { HostService } from '~/app/shared/api/host.service';
+import { OrchestratorService } from '~/app/shared/api/orchestrator.service';
+import { OsdService } from '~/app/shared/api/osd.service';
+import { FormButtonPanelComponent } from '~/app/shared/components/form-button-panel/form-button-panel.component';
+import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdForm } from '~/app/shared/forms/cd-form';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import {
+ DeploymentOptions,
+ OsdDeploymentOptions
+} from '~/app/shared/models/osd-deployment-options';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { OsdCreationPreviewModalComponent } from '../osd-creation-preview-modal/osd-creation-preview-modal.component';
+import { DevicesSelectionChangeEvent } from '../osd-devices-selection-groups/devices-selection-change-event.interface';
+import { DevicesSelectionClearEvent } from '../osd-devices-selection-groups/devices-selection-clear-event.interface';
+import { OsdDevicesSelectionGroupsComponent } from '../osd-devices-selection-groups/osd-devices-selection-groups.component';
+import { DriveGroup } from './drive-group.model';
+import { OsdFeature } from './osd-feature.interface';
+
+@Component({
+ selector: 'cd-osd-form',
+ templateUrl: './osd-form.component.html',
+ styleUrls: ['./osd-form.component.scss']
+})
+export class OsdFormComponent extends CdForm implements OnInit {
+ @ViewChild('dataDeviceSelectionGroups')
+ dataDeviceSelectionGroups: OsdDevicesSelectionGroupsComponent;
+
+ @ViewChild('walDeviceSelectionGroups')
+ walDeviceSelectionGroups: OsdDevicesSelectionGroupsComponent;
+
+ @ViewChild('dbDeviceSelectionGroups')
+ dbDeviceSelectionGroups: OsdDevicesSelectionGroupsComponent;
+
+ @ViewChild('previewButtonPanel')
+ previewButtonPanel: FormButtonPanelComponent;
+
+ @Input()
+ hideTitle = false;
+
+ @Input()
+ hideSubmitBtn = false;
+
+ @Output() emitDriveGroup: EventEmitter<DriveGroup> = new EventEmitter();
+
+ @Output() emitDeploymentOption: EventEmitter<object> = new EventEmitter();
+
+ @Output() emitMode: EventEmitter<boolean> = new EventEmitter();
+
+ icons = Icons;
+
+ form: CdFormGroup;
+ columns: Array<CdTableColumn> = [];
+
+ allDevices: InventoryDevice[] = [];
+
+ availDevices: InventoryDevice[] = [];
+ dataDeviceFilters: any[] = [];
+ dbDeviceFilters: any[] = [];
+ walDeviceFilters: any[] = [];
+ hostname = '';
+ driveGroup = new DriveGroup();
+
+ action: string;
+ resource: string;
+
+ features: { [key: string]: OsdFeature };
+ featureList: OsdFeature[] = [];
+
+ hasOrchestrator = true;
+
+ simpleDeployment = true;
+
+ deploymentOptions: DeploymentOptions;
+ optionNames = Object.values(OsdDeploymentOptions);
+
+ constructor(
+ public actionLabels: ActionLabelsI18n,
+ private authStorageService: AuthStorageService,
+ private orchService: OrchestratorService,
+ private hostService: HostService,
+ private router: Router,
+ private modalService: ModalService,
+ private osdService: OsdService,
+ private taskWrapper: TaskWrapperService
+ ) {
+ super();
+ this.resource = $localize`OSDs`;
+ this.action = this.actionLabels.CREATE;
+ this.features = {
+ encrypted: {
+ key: 'encrypted',
+ desc: $localize`Encryption`
+ }
+ };
+ this.featureList = _.map(this.features, (o, key) => Object.assign(o, { key: key }));
+ this.createForm();
+ }
+
+ ngOnInit() {
+ this.orchService.status().subscribe((status) => {
+ this.hasOrchestrator = status.available;
+ if (status.available) {
+ this.getDataDevices();
+ } else {
+ this.loadingNone();
+ }
+ });
+
+ this.osdService.getDeploymentOptions().subscribe((options) => {
+ this.deploymentOptions = options;
+ this.form.get('deploymentOption').setValue(this.deploymentOptions?.recommended_option);
+
+ if (this.deploymentOptions?.recommended_option) {
+ this.enableFeatures();
+ }
+ });
+ this.form.get('walSlots').valueChanges.subscribe((value) => this.setSlots('wal', value));
+ this.form.get('dbSlots').valueChanges.subscribe((value) => this.setSlots('db', value));
+ _.each(this.features, (feature) => {
+ this.form
+ .get('features')
+ .get(feature.key)
+ .valueChanges.subscribe((value) => this.featureFormUpdate(feature.key, value));
+ });
+ }
+
+ createForm() {
+ this.form = new CdFormGroup({
+ walSlots: new FormControl(0),
+ dbSlots: new FormControl(0),
+ features: new CdFormGroup(
+ this.featureList.reduce((acc: object, e) => {
+ // disable initially because no data devices are selected
+ acc[e.key] = new FormControl({ value: false, disabled: true });
+ return acc;
+ }, {})
+ ),
+ deploymentOption: new FormControl(0)
+ });
+ }
+
+ getDataDevices() {
+ this.hostService.inventoryDeviceList().subscribe(
+ (devices: InventoryDevice[]) => {
+ this.allDevices = _.filter(devices, 'available');
+ this.availDevices = [...this.allDevices];
+ this.loadingReady();
+ },
+ () => {
+ this.allDevices = [];
+ this.availDevices = [];
+ this.loadingError();
+ }
+ );
+ }
+
+ setSlots(type: string, slots: number) {
+ if (typeof slots !== 'number') {
+ return;
+ }
+ if (slots >= 0) {
+ this.driveGroup.setSlots(type, slots);
+ }
+ }
+
+ featureFormUpdate(key: string, checked: boolean) {
+ this.driveGroup.setFeature(key, checked);
+ }
+
+ enableFeatures() {
+ this.featureList.forEach((feature) => {
+ this.form.get(feature.key).enable({ emitEvent: false });
+ });
+ }
+
+ disableFeatures() {
+ this.featureList.forEach((feature) => {
+ const control = this.form.get(feature.key);
+ control.disable({ emitEvent: false });
+ control.setValue(false, { emitEvent: false });
+ });
+ }
+
+ onDevicesSelected(event: DevicesSelectionChangeEvent) {
+ this.availDevices = event.dataOut;
+
+ if (event.type === 'data') {
+ // If user selects data devices for a single host, make only remaining devices on
+ // that host as available.
+ const hostnameFilter = _.find(event.filters, { prop: 'hostname' });
+ if (hostnameFilter) {
+ this.hostname = hostnameFilter.value.raw;
+ this.availDevices = event.dataOut.filter((device: InventoryDevice) => {
+ return device.hostname === this.hostname;
+ });
+ this.driveGroup.setHostPattern(this.hostname);
+ } else {
+ this.driveGroup.setHostPattern('*');
+ }
+ this.enableFeatures();
+ }
+ this.driveGroup.setDeviceSelection(event.type, event.filters);
+
+ this.emitDriveGroup.emit(this.driveGroup);
+ }
+
+ onDevicesCleared(event: DevicesSelectionClearEvent) {
+ if (event.type === 'data') {
+ this.availDevices = [...this.allDevices];
+ this.walDeviceSelectionGroups.devices = [];
+ this.dbDeviceSelectionGroups.devices = [];
+ this.disableFeatures();
+ this.driveGroup.reset();
+ this.form.get('walSlots').setValue(0, { emitEvent: false });
+ this.form.get('dbSlots').setValue(0, { emitEvent: false });
+ } else {
+ this.availDevices = [...this.availDevices, ...event.clearedDevices];
+ this.driveGroup.clearDeviceSelection(event.type);
+ const slotControlName = `${event.type}Slots`;
+ this.form.get(slotControlName).setValue(0, { emitEvent: false });
+ }
+ }
+
+ emitDeploymentSelection() {
+ const option = this.form.get('deploymentOption').value;
+ const encrypted = this.form.get('encrypted').value;
+ this.emitDeploymentOption.emit({ option: option, encrypted: encrypted });
+ }
+
+ emitDeploymentMode() {
+ this.simpleDeployment = !this.simpleDeployment;
+ if (!this.simpleDeployment && this.dataDeviceSelectionGroups.devices.length === 0) {
+ this.disableFeatures();
+ } else {
+ this.enableFeatures();
+ }
+ this.emitMode.emit(this.simpleDeployment);
+ }
+
+ submit() {
+ if (this.simpleDeployment) {
+ const option = this.form.get('deploymentOption').value;
+ const encrypted = this.form.get('encrypted').value;
+ const deploymentSpec = { option: option, encrypted: encrypted };
+ const title = this.deploymentOptions.options[deploymentSpec.option].title;
+ const trackingId = `${title} deployment`;
+ this.taskWrapper
+ .wrapTaskAroundCall({
+ task: new FinishedTask('osd/' + URLVerbs.CREATE, {
+ tracking_id: trackingId
+ }),
+ call: this.osdService.create([deploymentSpec], trackingId, 'predefined')
+ })
+ .subscribe({
+ complete: () => {
+ this.router.navigate(['/osd']);
+ }
+ });
+ } else {
+ // use user name and timestamp for drive group name
+ const user = this.authStorageService.getUsername();
+ this.driveGroup.setName(`dashboard-${user}-${_.now()}`);
+ const modalRef = this.modalService.show(OsdCreationPreviewModalComponent, {
+ driveGroups: [this.driveGroup.spec]
+ });
+ modalRef.componentInstance.submitAction.subscribe(() => {
+ this.router.navigate(['/osd']);
+ });
+ this.previewButtonPanel.submitButton.loading = false;
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/fixtures/osd_list_response.json b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/fixtures/osd_list_response.json
new file mode 100644
index 000000000..2de532703
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/fixtures/osd_list_response.json
@@ -0,0 +1,605 @@
+[
+ {
+ "osd": 0,
+ "up": 1,
+ "in": 1,
+ "weight": 1.0,
+ "primary_affinity": 1.0,
+ "last_clean_begin": 0,
+ "last_clean_end": 0,
+ "up_from": 8,
+ "up_thru": 143,
+ "down_at": 0,
+ "lost_at": 0,
+ "public_addrs": {
+ "addrvec": [
+ { "type": "v2", "nonce": 9066, "addr": "192.168.2.106:6802" },
+ { "type": "v1", "nonce": 9066, "addr": "192.168.2.106:6803" }
+ ]
+ },
+ "cluster_addrs": {
+ "addrvec": [
+ { "type": "v2", "nonce": 9066, "addr": "192.168.2.106:6804" },
+ { "type": "v1", "nonce": 9066, "addr": "192.168.2.106:6805" }
+ ]
+ },
+ "heartbeat_back_addrs": {
+ "addrvec": [
+ { "type": "v2", "nonce": 9066, "addr": "192.168.2.106:6808" },
+ { "type": "v1", "nonce": 9066, "addr": "192.168.2.106:6809" }
+ ]
+ },
+ "heartbeat_front_addrs": {
+ "addrvec": [
+ { "type": "v2", "nonce": 9066, "addr": "192.168.2.106:6806" },
+ { "type": "v1", "nonce": 9066, "addr": "192.168.2.106:6807" }
+ ]
+ },
+ "state": ["exists", "up"],
+ "uuid": "7fd350c1-ff37-4b89-b4a7-774219e78cbb",
+ "public_addr": "192.168.2.106:6803/9066",
+ "cluster_addr": "192.168.2.106:6805/9066",
+ "heartbeat_back_addr": "192.168.2.106:6809/9066",
+ "heartbeat_front_addr": "192.168.2.106:6807/9066",
+ "id": 0,
+ "osd_stats": {
+ "osd": 0,
+ "up_from": 8,
+ "seq": 34359740004,
+ "num_pgs": 201,
+ "num_osds": 1,
+ "num_per_pool_osds": 1,
+ "num_per_pool_omap_osds": 1,
+ "kb": 105906168,
+ "kb_used": 2099028,
+ "kb_used_data": 1876,
+ "kb_used_omap": 0,
+ "kb_used_meta": 1048576,
+ "kb_avail": 103807140,
+ "statfs": {
+ "total": 108447916032,
+ "available": 106298511360,
+ "internally_reserved": 1073741824,
+ "allocated": 1921024,
+ "data_stored": 748530,
+ "data_compressed": 0,
+ "data_compressed_allocated": 0,
+ "data_compressed_original": 0,
+ "omap_allocated": 0,
+ "internal_metadata": 1073741824
+ },
+ "hb_peers": [1, 2],
+ "snap_trim_queue_len": 0,
+ "num_snap_trimming": 0,
+ "num_shards_repaired": 0,
+ "op_queue_age_hist": { "histogram": [], "upper_bound": 1 },
+ "perf_stat": {
+ "commit_latency_ms": 0.0,
+ "apply_latency_ms": 0.0,
+ "commit_latency_ns": 0,
+ "apply_latency_ns": 0
+ },
+ "alerts": []
+ },
+ "tree": {
+ "id": 0,
+ "device_class": "ssd",
+ "type": "osd",
+ "type_id": 0,
+ "crush_weight": 0.0985870361328125,
+ "depth": 2,
+ "pool_weights": {},
+ "exists": 1,
+ "status": "up",
+ "reweight": 1.0,
+ "primary_affinity": 1.0,
+ "name": "osd.0"
+ },
+ "host": {
+ "id": -3,
+ "name": "ceph-master",
+ "type": "host",
+ "type_id": 1,
+ "pool_weights": {},
+ "children": [2, 1, 0]
+ },
+ "stats": {
+ "op_w": 0.0,
+ "op_in_bytes": 0.0,
+ "op_r": 0.0,
+ "op_out_bytes": 0.0,
+ "numpg": 201,
+ "stat_bytes": 108447916032,
+ "stat_bytes_used": 2149404672
+ },
+ "stats_history": {
+ "op_w": [
+ [1594973071.815675, 0.0],
+ [1594973076.8181818, 0.0],
+ [1594973081.8206801, 0.0],
+ [1594973086.8231986, 0.0],
+ [1594973091.8258255, 0.0],
+ [1594973096.8285067, 0.0],
+ [1594973101.830774, 0.0],
+ [1594973106.8332067, 0.0],
+ [1594973111.8377645, 0.0],
+ [1594973116.8413265, 0.0],
+ [1594973121.8436713, 0.0],
+ [1594973126.846079, 0.0],
+ [1594973131.8485043, 0.0],
+ [1594973136.8509178, 0.0],
+ [1594973141.8532503, 0.0],
+ [1594973146.8557014, 0.0],
+ [1594973151.857818, 0.0],
+ [1594973156.8602881, 0.0],
+ [1594973161.862781, 0.0]
+ ],
+ "op_in_bytes": [
+ [1594973071.815675, 0.0],
+ [1594973076.8181818, 0.0],
+ [1594973081.8206801, 0.0],
+ [1594973086.8231986, 0.0],
+ [1594973091.8258255, 0.0],
+ [1594973096.8285067, 0.0],
+ [1594973101.830774, 0.0],
+ [1594973106.8332067, 0.0],
+ [1594973111.8377645, 0.0],
+ [1594973116.8413265, 0.0],
+ [1594973121.8436713, 0.0],
+ [1594973126.846079, 0.0],
+ [1594973131.8485043, 0.0],
+ [1594973136.8509178, 0.0],
+ [1594973141.8532503, 0.0],
+ [1594973146.8557014, 0.0],
+ [1594973151.857818, 0.0],
+ [1594973156.8602881, 0.0],
+ [1594973161.862781, 0.0]
+ ],
+ "op_r": [
+ [1594973071.815675, 0.0],
+ [1594973076.8181818, 0.0],
+ [1594973081.8206801, 0.0],
+ [1594973086.8231986, 0.0],
+ [1594973091.8258255, 0.0],
+ [1594973096.8285067, 0.0],
+ [1594973101.830774, 0.0],
+ [1594973106.8332067, 0.0],
+ [1594973111.8377645, 0.0],
+ [1594973116.8413265, 0.0],
+ [1594973121.8436713, 0.0],
+ [1594973126.846079, 0.0],
+ [1594973131.8485043, 0.0],
+ [1594973136.8509178, 0.0],
+ [1594973141.8532503, 0.0],
+ [1594973146.8557014, 0.0],
+ [1594973151.857818, 0.0],
+ [1594973156.8602881, 0.0],
+ [1594973161.862781, 0.0]
+ ],
+ "op_out_bytes": [
+ [1594973071.815675, 0.0],
+ [1594973076.8181818, 0.0],
+ [1594973081.8206801, 0.0],
+ [1594973086.8231986, 0.0],
+ [1594973091.8258255, 0.0],
+ [1594973096.8285067, 0.0],
+ [1594973101.830774, 0.0],
+ [1594973106.8332067, 0.0],
+ [1594973111.8377645, 0.0],
+ [1594973116.8413265, 0.0],
+ [1594973121.8436713, 0.0],
+ [1594973126.846079, 0.0],
+ [1594973131.8485043, 0.0],
+ [1594973136.8509178, 0.0],
+ [1594973141.8532503, 0.0],
+ [1594973146.8557014, 0.0],
+ [1594973151.857818, 0.0],
+ [1594973156.8602881, 0.0],
+ [1594973161.862781, 0.0]
+ ]
+ },
+ "operational_status": "working"
+ },
+ {
+ "osd": 1,
+ "up": 1,
+ "in": 1,
+ "weight": 1.0,
+ "primary_affinity": 1.0,
+ "last_clean_begin": 0,
+ "last_clean_end": 0,
+ "up_from": 13,
+ "up_thru": 143,
+ "down_at": 0,
+ "lost_at": 0,
+ "public_addrs": {
+ "addrvec": [
+ { "type": "v2", "nonce": 10136, "addr": "192.168.2.106:6810" },
+ { "type": "v1", "nonce": 10136, "addr": "192.168.2.106:6811" }
+ ]
+ },
+ "cluster_addrs": {
+ "addrvec": [
+ { "type": "v2", "nonce": 10136, "addr": "192.168.2.106:6812" },
+ { "type": "v1", "nonce": 10136, "addr": "192.168.2.106:6813" }
+ ]
+ },
+ "heartbeat_back_addrs": {
+ "addrvec": [
+ { "type": "v2", "nonce": 10136, "addr": "192.168.2.106:6816" },
+ { "type": "v1", "nonce": 10136, "addr": "192.168.2.106:6817" }
+ ]
+ },
+ "heartbeat_front_addrs": {
+ "addrvec": [
+ { "type": "v2", "nonce": 10136, "addr": "192.168.2.106:6814" },
+ { "type": "v1", "nonce": 10136, "addr": "192.168.2.106:6815" }
+ ]
+ },
+ "state": ["exists", "up"],
+ "uuid": "b57436ab-31cf-43ab-ae04-2b1ead69d155",
+ "public_addr": "192.168.2.106:6811/10136",
+ "cluster_addr": "192.168.2.106:6813/10136",
+ "heartbeat_back_addr": "192.168.2.106:6817/10136",
+ "heartbeat_front_addr": "192.168.2.106:6815/10136",
+ "id": 1,
+ "osd_stats": {
+ "osd": 1,
+ "up_from": 13,
+ "seq": 55834576483,
+ "num_pgs": 201,
+ "num_osds": 1,
+ "num_per_pool_osds": 1,
+ "num_per_pool_omap_osds": 1,
+ "kb": 105906168,
+ "kb_used": 2099028,
+ "kb_used_data": 1876,
+ "kb_used_omap": 0,
+ "kb_used_meta": 1048576,
+ "kb_avail": 103807140,
+ "statfs": {
+ "total": 108447916032,
+ "available": 106298511360,
+ "internally_reserved": 1073741824,
+ "allocated": 1921024,
+ "data_stored": 748530,
+ "data_compressed": 0,
+ "data_compressed_allocated": 0,
+ "data_compressed_original": 0,
+ "omap_allocated": 0,
+ "internal_metadata": 1073741824
+ },
+ "hb_peers": [0, 2],
+ "snap_trim_queue_len": 0,
+ "num_snap_trimming": 0,
+ "num_shards_repaired": 0,
+ "op_queue_age_hist": { "histogram": [], "upper_bound": 1 },
+ "perf_stat": {
+ "commit_latency_ms": 0.0,
+ "apply_latency_ms": 0.0,
+ "commit_latency_ns": 0,
+ "apply_latency_ns": 0
+ },
+ "alerts": []
+ },
+ "tree": {
+ "id": 1,
+ "device_class": "ssd",
+ "type": "osd",
+ "type_id": 0,
+ "crush_weight": 0.0985870361328125,
+ "depth": 2,
+ "pool_weights": {},
+ "exists": 1,
+ "status": "up",
+ "reweight": 1.0,
+ "primary_affinity": 1.0,
+ "name": "osd.1"
+ },
+ "host": {
+ "id": -3,
+ "name": "ceph-master",
+ "type": "host",
+ "type_id": 1,
+ "pool_weights": {},
+ "children": [2, 1, 0]
+ },
+ "stats": {
+ "op_w": 0.0,
+ "op_in_bytes": 0.0,
+ "op_r": 0.0,
+ "op_out_bytes": 0.0,
+ "numpg": 201,
+ "stat_bytes": 108447916032,
+ "stat_bytes_used": 2149404672
+ },
+ "stats_history": {
+ "op_w": [
+ [1594973072.2473748, 0.0],
+ [1594973077.249638, 0.0],
+ [1594973082.252127, 0.0],
+ [1594973087.2545457, 0.0],
+ [1594973092.2568345, 0.0],
+ [1594973097.2593641, 0.0],
+ [1594973102.2615848, 0.0],
+ [1594973107.263888, 0.0],
+ [1594973112.2665699, 0.0],
+ [1594973117.2689157, 0.0],
+ [1594973122.2711878, 0.0],
+ [1594973127.2736654, 0.0],
+ [1594973132.2760675, 0.0],
+ [1594973137.2787013, 0.0],
+ [1594973142.2811794, 0.0],
+ [1594973147.2834256, 0.0],
+ [1594973152.2856195, 0.0],
+ [1594973157.288044, 0.0],
+ [1594973162.2904015, 0.0]
+ ],
+ "op_in_bytes": [
+ [1594973072.2473748, 0.0],
+ [1594973077.249638, 0.0],
+ [1594973082.252127, 0.0],
+ [1594973087.2545457, 0.0],
+ [1594973092.2568345, 0.0],
+ [1594973097.2593641, 0.0],
+ [1594973102.2615848, 0.0],
+ [1594973107.263888, 0.0],
+ [1594973112.2665699, 0.0],
+ [1594973117.2689157, 0.0],
+ [1594973122.2711878, 0.0],
+ [1594973127.2736654, 0.0],
+ [1594973132.2760675, 0.0],
+ [1594973137.2787013, 0.0],
+ [1594973142.2811794, 0.0],
+ [1594973147.2834256, 0.0],
+ [1594973152.2856195, 0.0],
+ [1594973157.288044, 0.0],
+ [1594973162.2904015, 0.0]
+ ],
+ "op_r": [
+ [1594973072.2473748, 0.0],
+ [1594973077.249638, 0.0],
+ [1594973082.252127, 0.0],
+ [1594973087.2545457, 0.0],
+ [1594973092.2568345, 0.0],
+ [1594973097.2593641, 0.0],
+ [1594973102.2615848, 0.0],
+ [1594973107.263888, 0.0],
+ [1594973112.2665699, 0.0],
+ [1594973117.2689157, 0.0],
+ [1594973122.2711878, 0.0],
+ [1594973127.2736654, 0.0],
+ [1594973132.2760675, 0.0],
+ [1594973137.2787013, 0.0],
+ [1594973142.2811794, 0.0],
+ [1594973147.2834256, 0.0],
+ [1594973152.2856195, 0.0],
+ [1594973157.288044, 0.0],
+ [1594973162.2904015, 0.0]
+ ],
+ "op_out_bytes": [
+ [1594973072.2473748, 0.0],
+ [1594973077.249638, 0.0],
+ [1594973082.252127, 0.0],
+ [1594973087.2545457, 0.0],
+ [1594973092.2568345, 0.0],
+ [1594973097.2593641, 0.0],
+ [1594973102.2615848, 0.0],
+ [1594973107.263888, 0.0],
+ [1594973112.2665699, 0.0],
+ [1594973117.2689157, 0.0],
+ [1594973122.2711878, 0.0],
+ [1594973127.2736654, 0.0],
+ [1594973132.2760675, 0.0],
+ [1594973137.2787013, 0.0],
+ [1594973142.2811794, 0.0],
+ [1594973147.2834256, 0.0],
+ [1594973152.2856195, 0.0],
+ [1594973157.288044, 0.0],
+ [1594973162.2904015, 0.0]
+ ]
+ },
+ "operational_status": "unmanaged"
+ },
+ {
+ "osd": 2,
+ "up": 1,
+ "in": 1,
+ "weight": 1.0,
+ "primary_affinity": 1.0,
+ "last_clean_begin": 0,
+ "last_clean_end": 0,
+ "up_from": 17,
+ "up_thru": 143,
+ "down_at": 0,
+ "lost_at": 0,
+ "public_addrs": {
+ "addrvec": [
+ { "type": "v2", "nonce": 11208, "addr": "192.168.2.106:6818" },
+ { "type": "v1", "nonce": 11208, "addr": "192.168.2.106:6819" }
+ ]
+ },
+ "cluster_addrs": {
+ "addrvec": [
+ { "type": "v2", "nonce": 11208, "addr": "192.168.2.106:6820" },
+ { "type": "v1", "nonce": 11208, "addr": "192.168.2.106:6821" }
+ ]
+ },
+ "heartbeat_back_addrs": {
+ "addrvec": [
+ { "type": "v2", "nonce": 11208, "addr": "192.168.2.106:6824" },
+ { "type": "v1", "nonce": 11208, "addr": "192.168.2.106:6825" }
+ ]
+ },
+ "heartbeat_front_addrs": {
+ "addrvec": [
+ { "type": "v2", "nonce": 11208, "addr": "192.168.2.106:6822" },
+ { "type": "v1", "nonce": 11208, "addr": "192.168.2.106:6823" }
+ ]
+ },
+ "state": ["exists", "up"],
+ "uuid": "6e6b88e3-67aa-4ea0-aac0-cbfe89a0f652",
+ "public_addr": "192.168.2.106:6819/11208",
+ "cluster_addr": "192.168.2.106:6821/11208",
+ "heartbeat_back_addr": "192.168.2.106:6825/11208",
+ "heartbeat_front_addr": "192.168.2.106:6823/11208",
+ "id": 2,
+ "osd_stats": {
+ "osd": 2,
+ "up_from": 17,
+ "seq": 73014445666,
+ "num_pgs": 201,
+ "num_osds": 1,
+ "num_per_pool_osds": 1,
+ "num_per_pool_omap_osds": 1,
+ "kb": 105906168,
+ "kb_used": 2099028,
+ "kb_used_data": 1876,
+ "kb_used_omap": 0,
+ "kb_used_meta": 1048576,
+ "kb_avail": 103807140,
+ "statfs": {
+ "total": 108447916032,
+ "available": 106298511360,
+ "internally_reserved": 1073741824,
+ "allocated": 1921024,
+ "data_stored": 748530,
+ "data_compressed": 0,
+ "data_compressed_allocated": 0,
+ "data_compressed_original": 0,
+ "omap_allocated": 0,
+ "internal_metadata": 1073741824
+ },
+ "hb_peers": [0, 1],
+ "snap_trim_queue_len": 0,
+ "num_snap_trimming": 0,
+ "num_shards_repaired": 0,
+ "op_queue_age_hist": { "histogram": [], "upper_bound": 1 },
+ "perf_stat": {
+ "commit_latency_ms": 0.0,
+ "apply_latency_ms": 0.0,
+ "commit_latency_ns": 0,
+ "apply_latency_ns": 0
+ },
+ "alerts": []
+ },
+ "tree": {
+ "id": 2,
+ "device_class": "ssd",
+ "type": "osd",
+ "type_id": 0,
+ "crush_weight": 0.0985870361328125,
+ "depth": 2,
+ "pool_weights": {},
+ "exists": 1,
+ "status": "up",
+ "reweight": 1.0,
+ "primary_affinity": 1.0,
+ "name": "osd.2"
+ },
+ "host": {
+ "id": -3,
+ "name": "ceph-master",
+ "type": "host",
+ "type_id": 1,
+ "pool_weights": {},
+ "children": [2, 1, 0]
+ },
+ "stats": {
+ "op_w": 0.0,
+ "op_in_bytes": 0.0,
+ "op_r": 0.0,
+ "op_out_bytes": 0.0,
+ "numpg": 201,
+ "stat_bytes": 108447916032,
+ "stat_bytes_used": 2149404672
+ },
+ "stats_history": {
+ "op_w": [
+ [1594973071.7967167, 0.0],
+ [1594973076.7992308, 0.0],
+ [1594973081.8016157, 0.0],
+ [1594973086.8038485, 0.0],
+ [1594973091.806146, 0.0],
+ [1594973096.8079553, 0.0],
+ [1594973101.8099923, 0.0],
+ [1594973106.8122191, 0.0],
+ [1594973111.814509, 0.0],
+ [1594973116.8168204, 0.0],
+ [1594973121.8191206, 0.0],
+ [1594973126.8215034, 0.0],
+ [1594973131.8238406, 0.0],
+ [1594973136.8261213, 0.0],
+ [1594973141.8283849, 0.0],
+ [1594973146.8305933, 0.0],
+ [1594973151.8342226, 0.0],
+ [1594973156.837437, 0.0],
+ [1594973161.8397536, 0.0]
+ ],
+ "op_in_bytes": [
+ [1594973071.7967167, 0.0],
+ [1594973076.7992308, 0.0],
+ [1594973081.8016157, 0.0],
+ [1594973086.8038485, 0.0],
+ [1594973091.806146, 0.0],
+ [1594973096.8079553, 0.0],
+ [1594973101.8099923, 0.0],
+ [1594973106.8122191, 0.0],
+ [1594973111.814509, 0.0],
+ [1594973116.8168204, 0.0],
+ [1594973121.8191206, 0.0],
+ [1594973126.8215034, 0.0],
+ [1594973131.8238406, 0.0],
+ [1594973136.8261213, 0.0],
+ [1594973141.8283849, 0.0],
+ [1594973146.8305933, 0.0],
+ [1594973151.8342226, 0.0],
+ [1594973156.837437, 0.0],
+ [1594973161.8397536, 0.0]
+ ],
+ "op_r": [
+ [1594973071.7967167, 0.0],
+ [1594973076.7992308, 0.0],
+ [1594973081.8016157, 0.0],
+ [1594973086.8038485, 0.0],
+ [1594973091.806146, 0.0],
+ [1594973096.8079553, 0.0],
+ [1594973101.8099923, 0.0],
+ [1594973106.8122191, 0.0],
+ [1594973111.814509, 0.0],
+ [1594973116.8168204, 0.0],
+ [1594973121.8191206, 0.0],
+ [1594973126.8215034, 0.0],
+ [1594973131.8238406, 0.0],
+ [1594973136.8261213, 0.0],
+ [1594973141.8283849, 0.0],
+ [1594973146.8305933, 0.0],
+ [1594973151.8342226, 0.0],
+ [1594973156.837437, 0.0],
+ [1594973161.8397536, 0.0]
+ ],
+ "op_out_bytes": [
+ [1594973071.7967167, 0.0],
+ [1594973076.7992308, 0.0],
+ [1594973081.8016157, 0.0],
+ [1594973086.8038485, 0.0],
+ [1594973091.806146, 0.0],
+ [1594973096.8079553, 0.0],
+ [1594973101.8099923, 0.0],
+ [1594973106.8122191, 0.0],
+ [1594973111.814509, 0.0],
+ [1594973116.8168204, 0.0],
+ [1594973121.8191206, 0.0],
+ [1594973126.8215034, 0.0],
+ [1594973131.8238406, 0.0],
+ [1594973136.8261213, 0.0],
+ [1594973141.8283849, 0.0],
+ [1594973146.8305933, 0.0],
+ [1594973151.8342226, 0.0],
+ [1594973156.837437, 0.0],
+ [1594973161.8397536, 0.0]
+ ]
+ },
+ "operational_status": "deleting"
+ }
+]
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.html
new file mode 100644
index 000000000..c1c1894d7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.html
@@ -0,0 +1,150 @@
+<ul ngbNav
+ #nav="ngbNav"
+ class="nav-tabs">
+ <li ngbNavItem>
+ <a ngbNavLink
+ i18n>OSDs List</a>
+ <ng-template ngbNavContent>
+ <cd-table [data]="osds"
+ (fetchData)="getOsdList()"
+ [columns]="columns"
+ selectionType="multiClick"
+ [hasDetails]="true"
+ (setExpandedRow)="setExpandedRow($event)"
+ (updateSelection)="updateSelection($event)"
+ [updateSelectionOnRefresh]="'never'">
+
+ <div class="table-actions btn-toolbar">
+ <cd-table-actions [permission]="permissions.osd"
+ [selection]="selection"
+ class="btn-group"
+ id="osd-actions"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ <cd-table-actions [permission]="{read: true}"
+ [selection]="selection"
+ dropDownOnly="Cluster-wide configuration"
+ btnColor="light"
+ class="btn-group"
+ id="cluster-wide-actions"
+ [tableActions]="clusterWideActions">
+ </cd-table-actions>
+ </div>
+
+ <cd-osd-details cdTableDetail
+ [selection]="expandedRow">
+ </cd-osd-details>
+ </cd-table>
+ </ng-template>
+ </li>
+
+ <li ngbNavItem
+ *ngIf="permissions.grafana.read">
+ <a ngbNavLink
+ i18n>Overall Performance</a>
+ <ng-template ngbNavContent>
+ <cd-grafana [grafanaPath]="'osd-overview?'"
+ uid="lo02I1Aiz"
+ grafanaStyle="four">
+ </cd-grafana>
+ </ng-template>
+ </li>
+</ul>
+
+<div [ngbNavOutlet]="nav"></div>
+
+<ng-template #markOsdConfirmationTpl
+ let-markActionDescription="markActionDescription"
+ let-osdIds="osdIds">
+ <ng-container i18n><strong>OSD(s) {{ osdIds | join }}</strong> will be marked
+ <strong>{{ markActionDescription }}</strong> if you proceed.</ng-container>
+</ng-template>
+
+<ng-template #criticalConfirmationTpl
+ let-safeToPerform="safeToPerform"
+ let-message="message"
+ let-active="active"
+ let-missingStats="missingStats"
+ let-storedPgs="storedPgs"
+ let-actionDescription="actionDescription"
+ let-osdIds="osdIds">
+ <div *ngIf="!safeToPerform"
+ class="danger mb-3">
+ <cd-alert-panel type="warning">
+ <span i18n>
+ The {selection.hasSingleSelection, select, true {OSD is} other {OSDs are}} not safe to be
+ {{ actionDescription }}!
+ </span>
+ <br>
+ <ul class="mb-0 pl-4">
+ <li *ngIf="active.length > 0"
+ i18n>
+ {selection.hasSingleSelection, select, true {} other {{{ active | join }} : }}
+ Some PGs are currently mapped to
+ {active.length === 1, select, true {it} other {them}}.
+ </li>
+ <li *ngIf="missingStats.length > 0"
+ i18n>
+ {selection.hasSingleSelection, select, true {} other {{{ missingStats | join }} : }}
+ There are no reported stats and not all PGs are active and clean.
+ </li>
+ <li *ngIf="storedPgs.length > 0"
+ i18n>
+ {selection.hasSingleSelection, select, true {OSD} other {{{ storedPgs | join }} : OSDs }}
+ still store some PG data and not all PGs are active and clean.
+ </li>
+ <li *ngIf="message">
+ {{ message }}
+ </li>
+ </ul>
+ </cd-alert-panel>
+ </div>
+ <div *ngIf="safeToPerform"
+ class="danger mb-3">
+ <cd-alert-panel type="info">
+ <span i18n>
+ The {selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}
+ safe to destroy without reducing data durability.
+ </span>
+ </cd-alert-panel>
+ </div>
+ <ng-container i18n><strong>OSD {{ osdIds | join }}</strong> will be
+ <strong>{{ actionDescription }}</strong> if you proceed.</ng-container>
+</ng-template>
+
+<ng-template #flagsTpl
+ let-row="row">
+ <span *ngFor="let flag of row.cdClusterFlags;"
+ class="badge badge-hdd mr-1">{{ flag }}</span>
+ <span *ngFor="let flag of row.cdIndivFlags;"
+ class="badge badge-info mr-1">{{ flag }}</span>
+</ng-template>
+
+<ng-template #osdUsageTpl
+ let-row="row">
+ <cd-usage-bar [total]="row.stats.stat_bytes"
+ [used]="row.stats.stat_bytes_used"
+ [warningThreshold]="osdSettings.nearfull_ratio"
+ [errorThreshold]="osdSettings.full_ratio">
+ </cd-usage-bar>
+</ng-template>
+
+<ng-template #deleteOsdExtraTpl
+ let-form="form">
+ <ng-container [formGroup]="form">
+ <ng-container formGroupName="child">
+ <div class="form-group">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ name="preserve"
+ id="preserve"
+ formControlName="preserve">
+ <label class="custom-control-label"
+ for="preserve"
+ i18n>Preserve OSD ID(s) for replacement.</label>
+ </div>
+ </div>
+ </ng-container>
+ </ng-container>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.spec.ts
new file mode 100644
index 000000000..d6f865471
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.spec.ts
@@ -0,0 +1,641 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { By } from '@angular/platform-browser';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { ToastrModule } from 'ngx-toastr';
+import { EMPTY, of } from 'rxjs';
+
+import { CephModule } from '~/app/ceph/ceph.module';
+import { PerformanceCounterModule } from '~/app/ceph/performance-counter/performance-counter.module';
+import { CoreModule } from '~/app/core/core.module';
+import { OrchestratorService } from '~/app/shared/api/orchestrator.service';
+import { OsdService } from '~/app/shared/api/osd.service';
+import { ConfirmationModalComponent } from '~/app/shared/components/confirmation-modal/confirmation-modal.component';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { FormModalComponent } from '~/app/shared/components/form-modal/form-modal.component';
+import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { OrchestratorFeature } from '~/app/shared/models/orchestrator.enum';
+import { Permissions } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import {
+ configureTestBed,
+ OrchestratorHelper,
+ PermissionHelper,
+ TableActionHelper
+} from '~/testing/unit-test-helper';
+import { OsdReweightModalComponent } from '../osd-reweight-modal/osd-reweight-modal.component';
+import { OsdListComponent } from './osd-list.component';
+
+describe('OsdListComponent', () => {
+ let component: OsdListComponent;
+ let fixture: ComponentFixture<OsdListComponent>;
+ let modalServiceShowSpy: jasmine.Spy;
+ let osdService: OsdService;
+ let orchService: OrchestratorService;
+
+ const fakeAuthStorageService = {
+ getPermissions: () => {
+ return new Permissions({
+ 'config-opt': ['read', 'update', 'create', 'delete'],
+ osd: ['read', 'update', 'create', 'delete']
+ });
+ }
+ };
+
+ const getTableAction = (name: string) =>
+ component.tableActions.find((action) => action.name === name);
+
+ const setFakeSelection = () => {
+ // Default data and selection
+ const selection = [{ id: 1, tree: { device_class: 'ssd' } }];
+ const data = [{ id: 1, tree: { device_class: 'ssd' } }];
+
+ // Table data and selection
+ component.selection = new CdTableSelection();
+ component.selection.selected = selection;
+ component.osds = data;
+ component.permissions = fakeAuthStorageService.getPermissions();
+ };
+
+ const openActionModal = (actionName: string) => {
+ setFakeSelection();
+ getTableAction(actionName).click();
+ };
+
+ /**
+ * The following modals are called after the information about their
+ * safety to destroy/remove/mark them lost has been retrieved, hence
+ * we will have to fake its request to be able to open those modals.
+ */
+ const mockSafeToDestroy = () => {
+ spyOn(TestBed.inject(OsdService), 'safeToDestroy').and.callFake(() =>
+ of({ is_safe_to_destroy: true })
+ );
+ };
+
+ const mockSafeToDelete = () => {
+ spyOn(TestBed.inject(OsdService), 'safeToDelete').and.callFake(() =>
+ of({ is_safe_to_delete: true })
+ );
+ };
+
+ const mockOrch = () => {
+ const features = [OrchestratorFeature.OSD_CREATE, OrchestratorFeature.OSD_DELETE];
+ OrchestratorHelper.mockStatus(true, features);
+ };
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ HttpClientTestingModule,
+ PerformanceCounterModule,
+ ToastrModule.forRoot(),
+ CephModule,
+ ReactiveFormsModule,
+ NgbDropdownModule,
+ RouterTestingModule,
+ CoreModule,
+ RouterTestingModule
+ ],
+ providers: [
+ { provide: AuthStorageService, useValue: fakeAuthStorageService },
+ TableActionsComponent,
+ ModalService
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OsdListComponent);
+ component = fixture.componentInstance;
+ osdService = TestBed.inject(OsdService);
+ modalServiceShowSpy = spyOn(TestBed.inject(ModalService), 'show').and.returnValue({
+ // mock the close function, it might be called if there are async tests.
+ close: jest.fn()
+ });
+ orchService = TestBed.inject(OrchestratorService);
+ });
+
+ it('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+
+ it('should have columns that are sortable', () => {
+ fixture.detectChanges();
+ expect(
+ component.columns
+ .filter((column) => !(column.prop === undefined))
+ .every((column) => Boolean(column.prop))
+ ).toBeTruthy();
+ });
+
+ describe('getOsdList', () => {
+ let osds: any[];
+ let flagsSpy: jasmine.Spy;
+
+ const createOsd = (n: number) =>
+ <Record<string, any>>{
+ in: 'in',
+ up: 'up',
+ tree: {
+ device_class: 'ssd'
+ },
+ stats_history: {
+ op_out_bytes: [
+ [n, n],
+ [n * 2, n * 2]
+ ],
+ op_in_bytes: [
+ [n * 3, n * 3],
+ [n * 4, n * 4]
+ ]
+ },
+ stats: {
+ stat_bytes_used: n * n,
+ stat_bytes: n * n * n
+ },
+ state: []
+ };
+
+ const expectAttributeOnEveryOsd = (attr: string) =>
+ expect(component.osds.every((osd) => Boolean(_.get(osd, attr)))).toBeTruthy();
+
+ beforeEach(() => {
+ spyOn(osdService, 'getList').and.callFake(() => of(osds));
+ flagsSpy = spyOn(osdService, 'getFlags').and.callFake(() => of([]));
+ osds = [createOsd(1), createOsd(2), createOsd(3)];
+ component.getOsdList();
+ });
+
+ it('should replace "this.osds" with new data', () => {
+ expect(component.osds.length).toBe(3);
+ expect(osdService.getList).toHaveBeenCalledTimes(1);
+
+ osds = [createOsd(4)];
+ component.getOsdList();
+ expect(component.osds.length).toBe(1);
+ expect(osdService.getList).toHaveBeenCalledTimes(2);
+ });
+
+ it('should have custom attribute "collectedStates"', () => {
+ expectAttributeOnEveryOsd('collectedStates');
+ expect(component.osds[0].collectedStates).toEqual(['in', 'up']);
+ });
+
+ it('should have "destroyed" state in "collectedStates"', () => {
+ osds[0].state.push('destroyed');
+ osds[0].up = 0;
+ component.getOsdList();
+
+ expectAttributeOnEveryOsd('collectedStates');
+ expect(component.osds[0].collectedStates).toEqual(['in', 'destroyed']);
+ });
+
+ it('should have custom attribute "stats_history.out_bytes"', () => {
+ expectAttributeOnEveryOsd('stats_history.out_bytes');
+ expect(component.osds[0].stats_history.out_bytes).toEqual([1, 2]);
+ });
+
+ it('should have custom attribute "stats_history.in_bytes"', () => {
+ expectAttributeOnEveryOsd('stats_history.in_bytes');
+ expect(component.osds[0].stats_history.in_bytes).toEqual([3, 4]);
+ });
+
+ it('should have custom attribute "stats.usage"', () => {
+ expectAttributeOnEveryOsd('stats.usage');
+ expect(component.osds[0].stats.usage).toBe(1);
+ expect(component.osds[1].stats.usage).toBe(0.5);
+ expect(component.osds[2].stats.usage).toBe(3 / 9);
+ });
+
+ it('should have custom attribute "cdIsBinary" to be true', () => {
+ expectAttributeOnEveryOsd('cdIsBinary');
+ expect(component.osds[0].cdIsBinary).toBe(true);
+ });
+
+ it('should return valid individual flags only', () => {
+ const osd1 = createOsd(1);
+ const osd2 = createOsd(2);
+ osd1.state = ['noup', 'exists', 'up'];
+ osd2.state = ['noup', 'exists', 'up', 'noin'];
+ osds = [osd1, osd2];
+ component.getOsdList();
+
+ expect(component.osds[0].cdIndivFlags).toStrictEqual(['noup']);
+ expect(component.osds[1].cdIndivFlags).toStrictEqual(['noup', 'noin']);
+ });
+
+ it('should not fail on empty individual flags list', () => {
+ expect(component.osds[0].cdIndivFlags).toStrictEqual([]);
+ });
+
+ it('should not return disabled cluster-wide flags', () => {
+ flagsSpy.and.callFake(() => of(['noout', 'nodown', 'sortbitwise']));
+ component.getOsdList();
+ expect(component.osds[0].cdClusterFlags).toStrictEqual(['noout', 'nodown']);
+
+ flagsSpy.and.callFake(() => of(['noout', 'purged_snapdirs', 'nodown']));
+ component.getOsdList();
+ expect(component.osds[0].cdClusterFlags).toStrictEqual(['noout', 'nodown']);
+
+ flagsSpy.and.callFake(() => of(['recovery_deletes', 'noout', 'pglog_hardlimit', 'nodown']));
+ component.getOsdList();
+ expect(component.osds[0].cdClusterFlags).toStrictEqual(['noout', 'nodown']);
+ });
+
+ it('should not fail on empty cluster-wide flags list', () => {
+ flagsSpy.and.callFake(() => of([]));
+ component.getOsdList();
+ expect(component.osds[0].cdClusterFlags).toStrictEqual([]);
+ });
+
+ it('should have custom attribute "cdExecuting"', () => {
+ osds[1].operational_status = 'unmanaged';
+ osds[2].operational_status = 'deleting';
+ component.getOsdList();
+ expect(component.osds[0].cdExecuting).toBeUndefined();
+ expect(component.osds[1].cdExecuting).toBeUndefined();
+ expect(component.osds[2].cdExecuting).toBe('deleting');
+ });
+ });
+
+ describe('show osd actions as defined', () => {
+ const getOsdActions = () => {
+ fixture.detectChanges();
+ return fixture.debugElement.query(By.css('#cluster-wide-actions')).componentInstance
+ .dropDownActions;
+ };
+
+ it('shows osd actions after osd-actions', () => {
+ fixture.detectChanges();
+ expect(fixture.debugElement.query(By.css('#cluster-wide-actions'))).toBe(
+ fixture.debugElement.queryAll(By.directive(TableActionsComponent))[1]
+ );
+ });
+
+ it('shows both osd actions', () => {
+ const osdActions = getOsdActions();
+ expect(osdActions).toEqual(component.clusterWideActions);
+ expect(osdActions.length).toBe(3);
+ });
+
+ it('shows only "Flags" action', () => {
+ component.permissions.configOpt.read = false;
+ const osdActions = getOsdActions();
+ expect(osdActions[0].name).toBe('Flags');
+ expect(osdActions.length).toBe(1);
+ });
+
+ it('shows only "Recovery Priority" action', () => {
+ component.permissions.osd.read = false;
+ const osdActions = getOsdActions();
+ expect(osdActions[0].name).toBe('Recovery Priority');
+ expect(osdActions[1].name).toBe('PG scrub');
+ expect(osdActions.length).toBe(2);
+ });
+
+ it('shows no osd actions', () => {
+ component.permissions.configOpt.read = false;
+ component.permissions.osd.read = false;
+ const osdActions = getOsdActions();
+ expect(osdActions).toEqual([]);
+ });
+ });
+
+ it('should test all TableActions combinations', () => {
+ const permissionHelper: PermissionHelper = new PermissionHelper(component.permissions.osd);
+ const tableActions: TableActionsComponent = permissionHelper.setPermissionsAndGetActions(
+ component.tableActions
+ );
+
+ expect(tableActions).toEqual({
+ 'create,update,delete': {
+ actions: [
+ 'Create',
+ 'Edit',
+ 'Flags',
+ 'Scrub',
+ 'Deep Scrub',
+ 'Reweight',
+ 'Mark Out',
+ 'Mark In',
+ 'Mark Down',
+ 'Mark Lost',
+ 'Purge',
+ 'Destroy',
+ 'Delete'
+ ],
+ primary: { multiple: 'Scrub', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,update': {
+ actions: [
+ 'Create',
+ 'Edit',
+ 'Flags',
+ 'Scrub',
+ 'Deep Scrub',
+ 'Reweight',
+ 'Mark Out',
+ 'Mark In',
+ 'Mark Down'
+ ],
+ primary: { multiple: 'Scrub', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,delete': {
+ actions: ['Create', 'Mark Lost', 'Purge', 'Destroy', 'Delete'],
+ primary: {
+ multiple: 'Create',
+ executing: 'Mark Lost',
+ single: 'Mark Lost',
+ no: 'Create'
+ }
+ },
+ create: {
+ actions: ['Create'],
+ primary: { multiple: 'Create', executing: 'Create', single: 'Create', no: 'Create' }
+ },
+ 'update,delete': {
+ actions: [
+ 'Edit',
+ 'Flags',
+ 'Scrub',
+ 'Deep Scrub',
+ 'Reweight',
+ 'Mark Out',
+ 'Mark In',
+ 'Mark Down',
+ 'Mark Lost',
+ 'Purge',
+ 'Destroy',
+ 'Delete'
+ ],
+ primary: { multiple: 'Scrub', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ update: {
+ actions: [
+ 'Edit',
+ 'Flags',
+ 'Scrub',
+ 'Deep Scrub',
+ 'Reweight',
+ 'Mark Out',
+ 'Mark In',
+ 'Mark Down'
+ ],
+ primary: { multiple: 'Scrub', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ delete: {
+ actions: ['Mark Lost', 'Purge', 'Destroy', 'Delete'],
+ primary: {
+ multiple: 'Mark Lost',
+ executing: 'Mark Lost',
+ single: 'Mark Lost',
+ no: 'Mark Lost'
+ }
+ },
+ 'no-permissions': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ }
+ });
+ });
+
+ describe('test table actions in submenu', () => {
+ beforeEach(() => {
+ fixture.detectChanges();
+ });
+
+ beforeEach(fakeAsync(() => {
+ // The menu needs a click to render the dropdown!
+ const dropDownToggle = fixture.debugElement.query(By.css('.dropdown-toggle'));
+ dropDownToggle.triggerEventHandler('click', null);
+ tick();
+ fixture.detectChanges();
+ }));
+
+ it('has all menu entries disabled except create', () => {
+ const tableActionElement = fixture.debugElement.query(By.directive(TableActionsComponent));
+ const toClassName = TestBed.inject(TableActionsComponent).toClassName;
+ const getActionClasses = (action: CdTableAction) =>
+ tableActionElement.query(By.css(`[ngbDropdownItem].${toClassName(action)}`)).classes;
+
+ component.tableActions.forEach((action) => {
+ if (action.name === 'Create') {
+ return;
+ }
+ expect(getActionClasses(action).disabled).toBe(true);
+ });
+ });
+ });
+
+ describe('tests if all modals are opened correctly', () => {
+ /**
+ * Helper function to check if a function opens a modal
+ *
+ * @param modalClass - The expected class of the modal
+ */
+ const expectOpensModal = (actionName: string, modalClass: any): void => {
+ openActionModal(actionName);
+
+ // @TODO: check why tsc is complaining when passing 'expectationFailOutput' param.
+ expect(modalServiceShowSpy.calls.any()).toBeTruthy();
+ expect(modalServiceShowSpy.calls.first().args[0]).toBe(modalClass);
+
+ modalServiceShowSpy.calls.reset();
+ };
+
+ it('opens the reweight modal', () => {
+ expectOpensModal('Reweight', OsdReweightModalComponent);
+ });
+
+ it('opens the form modal', () => {
+ expectOpensModal('Edit', FormModalComponent);
+ });
+
+ it('opens all confirmation modals', () => {
+ const modalClass = ConfirmationModalComponent;
+ expectOpensModal('Mark Out', modalClass);
+ expectOpensModal('Mark In', modalClass);
+ expectOpensModal('Mark Down', modalClass);
+ });
+
+ it('opens all critical confirmation modals', () => {
+ const modalClass = CriticalConfirmationModalComponent;
+ mockSafeToDestroy();
+ expectOpensModal('Mark Lost', modalClass);
+ expectOpensModal('Purge', modalClass);
+ expectOpensModal('Destroy', modalClass);
+ mockOrch();
+ mockSafeToDelete();
+ expectOpensModal('Delete', modalClass);
+ });
+ });
+
+ describe('tests if the correct methods are called on confirmation', () => {
+ const expectOsdServiceMethodCalled = (
+ actionName: string,
+ osdServiceMethodName:
+ | 'markOut'
+ | 'markIn'
+ | 'markDown'
+ | 'markLost'
+ | 'purge'
+ | 'destroy'
+ | 'delete'
+ ): void => {
+ const osdServiceSpy = spyOn(osdService, osdServiceMethodName).and.callFake(() => EMPTY);
+ openActionModal(actionName);
+ const initialState = modalServiceShowSpy.calls.first().args[1];
+ const submit = initialState.onSubmit || initialState.submitAction;
+ submit.call(component);
+
+ expect(osdServiceSpy.calls.count()).toBe(1);
+ expect(osdServiceSpy.calls.first().args[0]).toBe(1);
+
+ // Reset spies to be able to recreate them
+ osdServiceSpy.calls.reset();
+ modalServiceShowSpy.calls.reset();
+ };
+
+ it('calls the corresponding service methods in confirmation modals', () => {
+ expectOsdServiceMethodCalled('Mark Out', 'markOut');
+ expectOsdServiceMethodCalled('Mark In', 'markIn');
+ expectOsdServiceMethodCalled('Mark Down', 'markDown');
+ });
+
+ it('calls the corresponding service methods in critical confirmation modals', () => {
+ mockSafeToDestroy();
+ expectOsdServiceMethodCalled('Mark Lost', 'markLost');
+ expectOsdServiceMethodCalled('Purge', 'purge');
+ expectOsdServiceMethodCalled('Destroy', 'destroy');
+ mockOrch();
+ mockSafeToDelete();
+ expectOsdServiceMethodCalled('Delete', 'delete');
+ });
+ });
+
+ describe('table actions', () => {
+ const fakeOsds = require('./fixtures/osd_list_response.json');
+
+ beforeEach(() => {
+ component.permissions = fakeAuthStorageService.getPermissions();
+ spyOn(osdService, 'getList').and.callFake(() => of(fakeOsds));
+ spyOn(osdService, 'getFlags').and.callFake(() => of([]));
+ });
+
+ const testTableActions = async (
+ orch: boolean,
+ features: OrchestratorFeature[],
+ tests: { selectRow?: number; expectResults: any }[]
+ ) => {
+ OrchestratorHelper.mockStatus(orch, features);
+ fixture.detectChanges();
+ await fixture.whenStable();
+
+ for (const test of tests) {
+ if (test.selectRow) {
+ component.selection = new CdTableSelection();
+ component.selection.selected = [test.selectRow];
+ }
+ await TableActionHelper.verifyTableActions(
+ fixture,
+ component.tableActions,
+ test.expectResults
+ );
+ }
+ };
+
+ it('should have correct states when Orchestrator is enabled', async () => {
+ const tests = [
+ {
+ expectResults: {
+ Create: { disabled: false, disableDesc: '' },
+ Delete: { disabled: true, disableDesc: '' }
+ }
+ },
+ {
+ selectRow: fakeOsds[0],
+ expectResults: {
+ Create: { disabled: false, disableDesc: '' },
+ Delete: { disabled: false, disableDesc: '' }
+ }
+ },
+ {
+ selectRow: fakeOsds[1], // Select a row that is not managed.
+ expectResults: {
+ Create: { disabled: false, disableDesc: '' },
+ Delete: { disabled: true, disableDesc: '' }
+ }
+ },
+ {
+ selectRow: fakeOsds[2], // Select a row that is being deleted.
+ expectResults: {
+ Create: { disabled: false, disableDesc: '' },
+ Delete: { disabled: true, disableDesc: '' }
+ }
+ }
+ ];
+
+ const features = [
+ OrchestratorFeature.OSD_CREATE,
+ OrchestratorFeature.OSD_DELETE,
+ OrchestratorFeature.OSD_GET_REMOVE_STATUS
+ ];
+ await testTableActions(true, features, tests);
+ });
+
+ it('should have correct states when Orchestrator is disabled', async () => {
+ const resultNoOrchestrator = {
+ disabled: true,
+ disableDesc: orchService.disableMessages.noOrchestrator
+ };
+ const tests = [
+ {
+ expectResults: {
+ Create: resultNoOrchestrator,
+ Delete: { disabled: true, disableDesc: '' }
+ }
+ },
+ {
+ selectRow: fakeOsds[0],
+ expectResults: {
+ Create: resultNoOrchestrator,
+ Delete: resultNoOrchestrator
+ }
+ }
+ ];
+ await testTableActions(false, [], tests);
+ });
+
+ it('should have correct states when Orchestrator features are missing', async () => {
+ const resultMissingFeatures = {
+ disabled: true,
+ disableDesc: orchService.disableMessages.missingFeature
+ };
+ const tests = [
+ {
+ expectResults: {
+ Create: resultMissingFeatures,
+ Delete: { disabled: true, disableDesc: '' }
+ }
+ },
+ {
+ selectRow: fakeOsds[0],
+ expectResults: {
+ Create: resultMissingFeatures,
+ Delete: resultMissingFeatures
+ }
+ }
+ ];
+ await testTableActions(true, [], tests);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.ts
new file mode 100644
index 000000000..ec8268d8b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.ts
@@ -0,0 +1,624 @@
+import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
+import { FormControl } from '@angular/forms';
+import { Router } from '@angular/router';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { forkJoin as observableForkJoin, Observable } from 'rxjs';
+import { take } from 'rxjs/operators';
+
+import { OrchestratorService } from '~/app/shared/api/orchestrator.service';
+import { OsdService } from '~/app/shared/api/osd.service';
+import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
+import { ConfirmationModalComponent } from '~/app/shared/components/confirmation-modal/confirmation-modal.component';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { FormModalComponent } from '~/app/shared/components/form-modal/form-modal.component';
+import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { OrchestratorFeature } from '~/app/shared/models/orchestrator.enum';
+import { OrchestratorStatus } from '~/app/shared/models/orchestrator.interface';
+import { OsdSettings } from '~/app/shared/models/osd-settings';
+import { Permissions } from '~/app/shared/models/permissions';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { URLBuilderService } from '~/app/shared/services/url-builder.service';
+import { OsdFlagsIndivModalComponent } from '../osd-flags-indiv-modal/osd-flags-indiv-modal.component';
+import { OsdFlagsModalComponent } from '../osd-flags-modal/osd-flags-modal.component';
+import { OsdPgScrubModalComponent } from '../osd-pg-scrub-modal/osd-pg-scrub-modal.component';
+import { OsdRecvSpeedModalComponent } from '../osd-recv-speed-modal/osd-recv-speed-modal.component';
+import { OsdReweightModalComponent } from '../osd-reweight-modal/osd-reweight-modal.component';
+import { OsdScrubModalComponent } from '../osd-scrub-modal/osd-scrub-modal.component';
+
+const BASE_URL = 'osd';
+
+@Component({
+ selector: 'cd-osd-list',
+ templateUrl: './osd-list.component.html',
+ styleUrls: ['./osd-list.component.scss'],
+ providers: [{ provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }]
+})
+export class OsdListComponent extends ListWithDetails implements OnInit {
+ @ViewChild('osdUsageTpl', { static: true })
+ osdUsageTpl: TemplateRef<any>;
+ @ViewChild('markOsdConfirmationTpl', { static: true })
+ markOsdConfirmationTpl: TemplateRef<any>;
+ @ViewChild('criticalConfirmationTpl', { static: true })
+ criticalConfirmationTpl: TemplateRef<any>;
+ @ViewChild('reweightBodyTpl')
+ reweightBodyTpl: TemplateRef<any>;
+ @ViewChild('safeToDestroyBodyTpl')
+ safeToDestroyBodyTpl: TemplateRef<any>;
+ @ViewChild('deleteOsdExtraTpl')
+ deleteOsdExtraTpl: TemplateRef<any>;
+ @ViewChild('flagsTpl', { static: true })
+ flagsTpl: TemplateRef<any>;
+
+ permissions: Permissions;
+ tableActions: CdTableAction[];
+ bsModalRef: NgbModalRef;
+ columns: CdTableColumn[];
+ clusterWideActions: CdTableAction[];
+ icons = Icons;
+ osdSettings = new OsdSettings();
+
+ selection = new CdTableSelection();
+ osds: any[] = [];
+ disabledFlags: string[] = [
+ 'sortbitwise',
+ 'purged_snapdirs',
+ 'recovery_deletes',
+ 'pglog_hardlimit'
+ ];
+ indivFlagNames: string[] = ['noup', 'nodown', 'noin', 'noout'];
+
+ orchStatus: OrchestratorStatus;
+ actionOrchFeatures = {
+ create: [OrchestratorFeature.OSD_CREATE],
+ delete: [OrchestratorFeature.OSD_DELETE]
+ };
+
+ protected static collectStates(osd: any) {
+ const states = [osd['in'] ? 'in' : 'out'];
+ if (osd['up']) {
+ states.push('up');
+ } else if (osd.state.includes('destroyed')) {
+ states.push('destroyed');
+ } else {
+ states.push('down');
+ }
+ return states;
+ }
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private osdService: OsdService,
+ private dimlessBinaryPipe: DimlessBinaryPipe,
+ private modalService: ModalService,
+ private urlBuilder: URLBuilderService,
+ private router: Router,
+ private taskWrapper: TaskWrapperService,
+ public actionLabels: ActionLabelsI18n,
+ public notificationService: NotificationService,
+ private orchService: OrchestratorService
+ ) {
+ super();
+ this.permissions = this.authStorageService.getPermissions();
+ this.tableActions = [
+ {
+ name: this.actionLabels.CREATE,
+ permission: 'create',
+ icon: Icons.add,
+ click: () => this.router.navigate([this.urlBuilder.getCreate()]),
+ disable: (selection: CdTableSelection) => this.getDisable('create', selection),
+ canBePrimary: (selection: CdTableSelection) => !selection.hasSelection
+ },
+ {
+ name: this.actionLabels.EDIT,
+ permission: 'update',
+ icon: Icons.edit,
+ click: () => this.editAction()
+ },
+ {
+ name: this.actionLabels.FLAGS,
+ permission: 'update',
+ icon: Icons.flag,
+ click: () => this.configureFlagsIndivAction(),
+ disable: () => !this.hasOsdSelected
+ },
+ {
+ name: this.actionLabels.SCRUB,
+ permission: 'update',
+ icon: Icons.analyse,
+ click: () => this.scrubAction(false),
+ disable: () => !this.hasOsdSelected,
+ canBePrimary: (selection: CdTableSelection) => selection.hasSelection
+ },
+ {
+ name: this.actionLabels.DEEP_SCRUB,
+ permission: 'update',
+ icon: Icons.deepCheck,
+ click: () => this.scrubAction(true),
+ disable: () => !this.hasOsdSelected
+ },
+ {
+ name: this.actionLabels.REWEIGHT,
+ permission: 'update',
+ click: () => this.reweight(),
+ disable: () => !this.hasOsdSelected || !this.selection.hasSingleSelection,
+ icon: Icons.reweight
+ },
+ {
+ name: this.actionLabels.MARK_OUT,
+ permission: 'update',
+ click: () => this.showConfirmationModal($localize`out`, this.osdService.markOut),
+ disable: () => this.isNotSelectedOrInState('out'),
+ icon: Icons.left
+ },
+ {
+ name: this.actionLabels.MARK_IN,
+ permission: 'update',
+ click: () => this.showConfirmationModal($localize`in`, this.osdService.markIn),
+ disable: () => this.isNotSelectedOrInState('in'),
+ icon: Icons.right
+ },
+ {
+ name: this.actionLabels.MARK_DOWN,
+ permission: 'update',
+ click: () => this.showConfirmationModal($localize`down`, this.osdService.markDown),
+ disable: () => this.isNotSelectedOrInState('down'),
+ icon: Icons.down
+ },
+ {
+ name: this.actionLabels.MARK_LOST,
+ permission: 'delete',
+ click: () =>
+ this.showCriticalConfirmationModal(
+ $localize`Mark`,
+ $localize`OSD lost`,
+ $localize`marked lost`,
+ (ids: number[]) => {
+ return this.osdService.safeToDestroy(JSON.stringify(ids));
+ },
+ 'is_safe_to_destroy',
+ this.osdService.markLost
+ ),
+ disable: () => this.isNotSelectedOrInState('up'),
+ icon: Icons.flatten
+ },
+ {
+ name: this.actionLabels.PURGE,
+ permission: 'delete',
+ click: () =>
+ this.showCriticalConfirmationModal(
+ $localize`Purge`,
+ $localize`OSD`,
+ $localize`purged`,
+ (ids: number[]) => {
+ return this.osdService.safeToDestroy(JSON.stringify(ids));
+ },
+ 'is_safe_to_destroy',
+ (id: number) => {
+ this.selection = new CdTableSelection();
+ return this.osdService.purge(id);
+ }
+ ),
+ disable: () => this.isNotSelectedOrInState('up'),
+ icon: Icons.erase
+ },
+ {
+ name: this.actionLabels.DESTROY,
+ permission: 'delete',
+ click: () =>
+ this.showCriticalConfirmationModal(
+ $localize`destroy`,
+ $localize`OSD`,
+ $localize`destroyed`,
+ (ids: number[]) => {
+ return this.osdService.safeToDestroy(JSON.stringify(ids));
+ },
+ 'is_safe_to_destroy',
+ (id: number) => {
+ this.selection = new CdTableSelection();
+ return this.osdService.destroy(id);
+ }
+ ),
+ disable: () => this.isNotSelectedOrInState('up'),
+ icon: Icons.destroyCircle
+ },
+ {
+ name: this.actionLabels.DELETE,
+ permission: 'delete',
+ click: () => this.delete(),
+ disable: (selection: CdTableSelection) => this.getDisable('delete', selection),
+ icon: Icons.destroy
+ }
+ ];
+ }
+
+ ngOnInit() {
+ this.clusterWideActions = [
+ {
+ name: $localize`Flags`,
+ icon: Icons.flag,
+ click: () => this.configureFlagsAction(),
+ permission: 'read',
+ visible: () => this.permissions.osd.read
+ },
+ {
+ name: $localize`Recovery Priority`,
+ icon: Icons.deepCheck,
+ click: () => this.configureQosParamsAction(),
+ permission: 'read',
+ visible: () => this.permissions.configOpt.read
+ },
+ {
+ name: $localize`PG scrub`,
+ icon: Icons.analyse,
+ click: () => this.configurePgScrubAction(),
+ permission: 'read',
+ visible: () => this.permissions.configOpt.read
+ }
+ ];
+ this.columns = [
+ {
+ prop: 'id',
+ name: $localize`ID`,
+ flexGrow: 1,
+ cellTransformation: CellTemplate.executing,
+ customTemplateConfig: {
+ valueClass: 'bold'
+ }
+ },
+ { prop: 'host.name', name: $localize`Host` },
+ {
+ prop: 'collectedStates',
+ name: $localize`Status`,
+ flexGrow: 1,
+ cellTransformation: CellTemplate.badge,
+ customTemplateConfig: {
+ map: {
+ in: { class: 'badge-success' },
+ up: { class: 'badge-success' },
+ down: { class: 'badge-danger' },
+ out: { class: 'badge-danger' },
+ destroyed: { class: 'badge-danger' }
+ }
+ }
+ },
+ {
+ prop: 'tree.device_class',
+ name: $localize`Device class`,
+ flexGrow: 1.2,
+ cellTransformation: CellTemplate.badge,
+ customTemplateConfig: {
+ map: {
+ hdd: { class: 'badge-hdd' },
+ ssd: { class: 'badge-ssd' }
+ }
+ }
+ },
+ {
+ prop: 'stats.numpg',
+ name: $localize`PGs`,
+ flexGrow: 1
+ },
+ {
+ prop: 'stats.stat_bytes',
+ name: $localize`Size`,
+ flexGrow: 1,
+ pipe: this.dimlessBinaryPipe
+ },
+ {
+ prop: 'state',
+ name: $localize`Flags`,
+ cellTemplate: this.flagsTpl
+ },
+ { prop: 'stats.usage', name: $localize`Usage`, cellTemplate: this.osdUsageTpl },
+ {
+ prop: 'stats_history.out_bytes',
+ name: $localize`Read bytes`,
+ cellTransformation: CellTemplate.sparkline
+ },
+ {
+ prop: 'stats_history.in_bytes',
+ name: $localize`Write bytes`,
+ cellTransformation: CellTemplate.sparkline
+ },
+ {
+ prop: 'stats.op_r',
+ name: $localize`Read ops`,
+ cellTransformation: CellTemplate.perSecond
+ },
+ {
+ prop: 'stats.op_w',
+ name: $localize`Write ops`,
+ cellTransformation: CellTemplate.perSecond
+ }
+ ];
+
+ this.orchService.status().subscribe((status: OrchestratorStatus) => (this.orchStatus = status));
+
+ this.osdService
+ .getOsdSettings()
+ .pipe(take(1))
+ .subscribe((data: any) => {
+ this.osdSettings = data;
+ });
+ }
+
+ getDisable(action: 'create' | 'delete', selection: CdTableSelection): boolean | string {
+ if (action === 'delete') {
+ if (!selection.hasSelection) {
+ return true;
+ } else {
+ // Disable delete action if any selected OSDs are under deleting or unmanaged.
+ const deletingOSDs = _.some(this.getSelectedOsds(), (osd) => {
+ const status = _.get(osd, 'operational_status');
+ return status === 'deleting' || status === 'unmanaged';
+ });
+ if (deletingOSDs) {
+ return true;
+ }
+ }
+ }
+ return this.orchService.getTableActionDisableDesc(
+ this.orchStatus,
+ this.actionOrchFeatures[action]
+ );
+ }
+
+ /**
+ * Only returns valid IDs, e.g. if an OSD is falsely still selected after being deleted, it won't
+ * get returned.
+ */
+ getSelectedOsdIds(): number[] {
+ const osdIds = this.osds.map((osd) => osd.id);
+ return this.selection.selected
+ .map((row) => row.id)
+ .filter((id) => osdIds.includes(id))
+ .sort();
+ }
+
+ getSelectedOsds(): any[] {
+ return this.osds.filter(
+ (osd) => !_.isUndefined(osd) && this.getSelectedOsdIds().includes(osd.id)
+ );
+ }
+
+ get hasOsdSelected(): boolean {
+ return this.getSelectedOsdIds().length > 0;
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ /**
+ * Returns true if no rows are selected or if *any* of the selected rows are in the given
+ * state. Useful for deactivating the corresponding menu entry.
+ */
+ isNotSelectedOrInState(state: 'in' | 'up' | 'down' | 'out'): boolean {
+ const selectedOsds = this.getSelectedOsds();
+ if (selectedOsds.length === 0) {
+ return true;
+ }
+ switch (state) {
+ case 'in':
+ return selectedOsds.some((osd) => osd.in === 1);
+ case 'out':
+ return selectedOsds.some((osd) => osd.in !== 1);
+ case 'down':
+ return selectedOsds.some((osd) => osd.up !== 1);
+ case 'up':
+ return selectedOsds.some((osd) => osd.up === 1);
+ }
+ }
+
+ getOsdList() {
+ const observables = [this.osdService.getList(), this.osdService.getFlags()];
+ observableForkJoin(observables).subscribe((resp: [any[], string[]]) => {
+ this.osds = resp[0].map((osd) => {
+ osd.collectedStates = OsdListComponent.collectStates(osd);
+ osd.stats_history.out_bytes = osd.stats_history.op_out_bytes.map((i: string) => i[1]);
+ osd.stats_history.in_bytes = osd.stats_history.op_in_bytes.map((i: string) => i[1]);
+ osd.stats.usage = osd.stats.stat_bytes_used / osd.stats.stat_bytes;
+ osd.cdIsBinary = true;
+ osd.cdIndivFlags = osd.state.filter((f: string) => this.indivFlagNames.includes(f));
+ osd.cdClusterFlags = resp[1].filter((f: string) => !this.disabledFlags.includes(f));
+ const deploy_state = _.get(osd, 'operational_status', 'unmanaged');
+ if (deploy_state !== 'unmanaged' && deploy_state !== 'working') {
+ osd.cdExecuting = deploy_state;
+ }
+ return osd;
+ });
+ });
+ }
+
+ editAction() {
+ const selectedOsd = _.filter(this.osds, ['id', this.selection.first().id]).pop();
+
+ this.modalService.show(FormModalComponent, {
+ titleText: $localize`Edit OSD: ${selectedOsd.id}`,
+ fields: [
+ {
+ type: 'text',
+ name: 'deviceClass',
+ value: selectedOsd.tree.device_class,
+ label: $localize`Device class`,
+ required: true
+ }
+ ],
+ submitButtonText: $localize`Edit OSD`,
+ onSubmit: (values: any) => {
+ this.osdService.update(selectedOsd.id, values.deviceClass).subscribe(() => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Updated OSD '${selectedOsd.id}'`
+ );
+ this.getOsdList();
+ });
+ }
+ });
+ }
+
+ scrubAction(deep: boolean) {
+ if (!this.hasOsdSelected) {
+ return;
+ }
+
+ const initialState = {
+ selected: this.getSelectedOsdIds(),
+ deep: deep
+ };
+
+ this.bsModalRef = this.modalService.show(OsdScrubModalComponent, initialState);
+ }
+
+ configureFlagsAction() {
+ this.bsModalRef = this.modalService.show(OsdFlagsModalComponent);
+ }
+
+ configureFlagsIndivAction() {
+ const initialState = {
+ selected: this.getSelectedOsds()
+ };
+ this.bsModalRef = this.modalService.show(OsdFlagsIndivModalComponent, initialState);
+ }
+
+ showConfirmationModal(markAction: string, onSubmit: (id: number) => Observable<any>) {
+ const osdIds = this.getSelectedOsdIds();
+ this.bsModalRef = this.modalService.show(ConfirmationModalComponent, {
+ titleText: $localize`Mark OSD ${markAction}`,
+ buttonText: $localize`Mark ${markAction}`,
+ bodyTpl: this.markOsdConfirmationTpl,
+ bodyContext: {
+ markActionDescription: markAction,
+ osdIds
+ },
+ onSubmit: () => {
+ observableForkJoin(
+ this.getSelectedOsdIds().map((osd: any) => onSubmit.call(this.osdService, osd))
+ ).subscribe(() => this.bsModalRef.close());
+ }
+ });
+ }
+
+ reweight() {
+ const selectedOsd = this.osds.filter((o) => o.id === this.selection.first().id).pop();
+ this.bsModalRef = this.modalService.show(OsdReweightModalComponent, {
+ currentWeight: selectedOsd.weight,
+ osdId: selectedOsd.id
+ });
+ }
+
+ delete() {
+ const deleteFormGroup = new CdFormGroup({
+ preserve: new FormControl(false)
+ });
+
+ this.showCriticalConfirmationModal(
+ $localize`delete`,
+ $localize`OSD`,
+ $localize`deleted`,
+ (ids: number[]) => {
+ return this.osdService.safeToDelete(JSON.stringify(ids));
+ },
+ 'is_safe_to_delete',
+ (id: number) => {
+ this.selection = new CdTableSelection();
+ return this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('osd/' + URLVerbs.DELETE, {
+ svc_id: id
+ }),
+ call: this.osdService.delete(id, deleteFormGroup.value.preserve, true)
+ });
+ },
+ true,
+ deleteFormGroup,
+ this.deleteOsdExtraTpl
+ );
+ }
+
+ /**
+ * Perform check first and display a critical confirmation modal.
+ * @param {string} actionDescription name of the action.
+ * @param {string} itemDescription the item's name that the action operates on.
+ * @param {string} templateItemDescription the action name to be displayed in modal template.
+ * @param {Function} check the function is called to check if the action is safe.
+ * @param {string} checkKey the safe indicator's key in the check response.
+ * @param {Function} action the action function.
+ * @param {boolean} taskWrapped if true, hide confirmation modal after action
+ * @param {CdFormGroup} childFormGroup additional child form group to be passed to confirmation modal
+ * @param {TemplateRef<any>} childFormGroupTemplate template for additional child form group
+ */
+ showCriticalConfirmationModal(
+ actionDescription: string,
+ itemDescription: string,
+ templateItemDescription: string,
+ check: (ids: number[]) => Observable<any>,
+ checkKey: string,
+ action: (id: number | number[]) => Observable<any>,
+ taskWrapped: boolean = false,
+ childFormGroup?: CdFormGroup,
+ childFormGroupTemplate?: TemplateRef<any>
+ ): void {
+ check(this.getSelectedOsdIds()).subscribe((result) => {
+ const modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ actionDescription: actionDescription,
+ itemDescription: itemDescription,
+ bodyTemplate: this.criticalConfirmationTpl,
+ bodyContext: {
+ safeToPerform: result[checkKey],
+ message: result.message,
+ active: result.active,
+ missingStats: result.missing_stats,
+ storedPgs: result.stored_pgs,
+ actionDescription: templateItemDescription,
+ osdIds: this.getSelectedOsdIds()
+ },
+ childFormGroup: childFormGroup,
+ childFormGroupTemplate: childFormGroupTemplate,
+ submitAction: () => {
+ const observable = observableForkJoin(
+ this.getSelectedOsdIds().map((osd: any) => action.call(this.osdService, osd))
+ );
+ if (taskWrapped) {
+ observable.subscribe({
+ error: () => {
+ this.getOsdList();
+ modalRef.close();
+ },
+ complete: () => modalRef.close()
+ });
+ } else {
+ observable.subscribe(
+ () => {
+ this.getOsdList();
+ modalRef.close();
+ },
+ () => modalRef.close()
+ );
+ }
+ }
+ });
+ });
+ }
+
+ configureQosParamsAction() {
+ this.bsModalRef = this.modalService.show(OsdRecvSpeedModalComponent);
+ }
+
+ configurePgScrubAction() {
+ this.bsModalRef = this.modalService.show(OsdPgScrubModalComponent, undefined, { size: 'lg' });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html
new file mode 100644
index 000000000..fa2636722
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html
@@ -0,0 +1,45 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container i18n="form title"
+ class="modal-title">{{ action | titlecase }} {{ resource | upperFirst }}</ng-container>
+
+ <ng-container class="modal-content">
+ <form #formDir="ngForm"
+ [formGroup]="osdPgScrubForm"
+ novalidate
+ cdFormScope="osd">
+ <div class="modal-body osd-modal">
+ <!-- Basic -->
+ <cd-config-option [optionNames]="basicOptions"
+ [optionsForm]="osdPgScrubForm"
+ [optionsFormDir]="formDir"
+ [optionsFormGroupName]="'basicFormGroup'"
+ #basicOptionsValues></cd-config-option>
+ <!-- Advanced -->
+ <div class="row">
+ <div class="col-sm-12">
+ <a class="pull-right margin-right-md"
+ (click)="advancedEnabled = true"
+ *ngIf="!advancedEnabled"
+ i18n>Advanced...</a>
+ </div>
+ </div>
+ <div *ngIf="advancedEnabled">
+ <h3 class="page-header"
+ i18n>Advanced configuration options</h3>
+ <cd-config-option [optionNames]="advancedOptions"
+ [optionsForm]="osdPgScrubForm"
+ [optionsFormDir]="formDir"
+ [optionsFormGroupName]="'advancedFormGroup'"
+ #advancedOptionsValues></cd-config-option>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="submitAction()"
+ [form]="osdPgScrubForm"
+ [showSubmit]="permissions.configOpt.update"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)">
+ </cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.spec.ts
new file mode 100644
index 000000000..dc5fc1644
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.spec.ts
@@ -0,0 +1,64 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { Router } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { of as observableOf } from 'rxjs';
+
+import { ConfigurationService } from '~/app/shared/api/configuration.service';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { OsdPgScrubModalComponent } from './osd-pg-scrub-modal.component';
+
+describe('OsdPgScrubModalComponent', () => {
+ let component: OsdPgScrubModalComponent;
+ let fixture: ComponentFixture<OsdPgScrubModalComponent>;
+ let configurationService: ConfigurationService;
+
+ configureTestBed({
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ RouterTestingModule,
+ SharedModule,
+ ToastrModule.forRoot()
+ ],
+ declarations: [OsdPgScrubModalComponent],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OsdPgScrubModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ configurationService = TestBed.inject(ConfigurationService);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('submitAction', () => {
+ let notificationService: NotificationService;
+
+ beforeEach(() => {
+ spyOn(TestBed.inject(Router), 'navigate').and.stub();
+ notificationService = TestBed.inject(NotificationService);
+ spyOn(notificationService, 'show');
+ });
+
+ it('test create success notification', () => {
+ spyOn(configurationService, 'bulkCreate').and.returnValue(observableOf([]));
+ component.submitAction();
+ expect(notificationService.show).toHaveBeenCalledWith(
+ NotificationType.success,
+ 'Updated PG scrub options'
+ );
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts
new file mode 100644
index 000000000..7e76c99c5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts
@@ -0,0 +1,68 @@
+import { Component, ViewChild } from '@angular/core';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { forkJoin as observableForkJoin } from 'rxjs';
+
+import { ConfigOptionComponent } from '~/app/shared/components/config-option/config-option.component';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { Permissions } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { OsdPgScrubModalOptions } from './osd-pg-scrub-modal.options';
+
+@Component({
+ selector: 'cd-osd-pg-scrub-modal',
+ templateUrl: './osd-pg-scrub-modal.component.html',
+ styleUrls: ['./osd-pg-scrub-modal.component.scss']
+})
+export class OsdPgScrubModalComponent {
+ osdPgScrubForm: CdFormGroup;
+ action: string;
+ resource: string;
+ permissions: Permissions;
+
+ @ViewChild('basicOptionsValues', { static: true })
+ basicOptionsValues: ConfigOptionComponent;
+ basicOptions: Array<string> = OsdPgScrubModalOptions.basicOptions;
+
+ @ViewChild('advancedOptionsValues')
+ advancedOptionsValues: ConfigOptionComponent;
+ advancedOptions: Array<string> = OsdPgScrubModalOptions.advancedOptions;
+
+ advancedEnabled = false;
+
+ constructor(
+ public activeModal: NgbActiveModal,
+ private authStorageService: AuthStorageService,
+ private notificationService: NotificationService,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ this.osdPgScrubForm = new CdFormGroup({});
+ this.resource = $localize`PG scrub options`;
+ this.action = this.actionLabels.EDIT;
+ this.permissions = this.authStorageService.getPermissions();
+ }
+
+ submitAction() {
+ const observables = [this.basicOptionsValues.saveValues()];
+
+ if (this.advancedOptionsValues) {
+ observables.push(this.advancedOptionsValues.saveValues());
+ }
+
+ observableForkJoin(observables).subscribe(
+ () => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Updated PG scrub options`
+ );
+ this.activeModal.close();
+ },
+ () => {
+ this.activeModal.close();
+ }
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.options.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.options.ts
new file mode 100644
index 000000000..424fbc479
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.options.ts
@@ -0,0 +1,36 @@
+export class OsdPgScrubModalOptions {
+ public static basicOptions: Array<string> = [
+ 'osd_scrub_during_recovery',
+ 'osd_scrub_begin_hour',
+ 'osd_scrub_end_hour',
+ 'osd_scrub_begin_week_day',
+ 'osd_scrub_end_week_day',
+ 'osd_scrub_min_interval',
+ 'osd_scrub_max_interval',
+ 'osd_deep_scrub_interval',
+ 'osd_scrub_auto_repair',
+ 'osd_max_scrubs',
+ 'osd_scrub_priority',
+ 'osd_scrub_sleep'
+ ];
+
+ public static advancedOptions: Array<string> = [
+ 'osd_scrub_auto_repair_num_errors',
+ 'osd_debug_deep_scrub_sleep',
+ 'osd_deep_scrub_keys',
+ 'osd_deep_scrub_large_omap_object_key_threshold',
+ 'osd_deep_scrub_large_omap_object_value_sum_threshold',
+ 'osd_deep_scrub_randomize_ratio',
+ 'osd_deep_scrub_stride',
+ 'osd_deep_scrub_update_digest_min_age',
+ 'osd_requested_scrub_priority',
+ 'osd_scrub_backoff_ratio',
+ 'osd_scrub_chunk_max',
+ 'osd_scrub_chunk_min',
+ 'osd_scrub_cost',
+ 'osd_scrub_interval_randomize_ratio',
+ 'osd_scrub_invalid_stats',
+ 'osd_scrub_load_threshold',
+ 'osd_scrub_max_preemptions'
+ ];
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html
new file mode 100755
index 000000000..eb54c82f5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html
@@ -0,0 +1,92 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container class="modal-title"
+ i18n>OSD Recovery Priority</ng-container>
+
+ <ng-container class="modal-content">
+ <form #formDir="ngForm"
+ [formGroup]="osdRecvSpeedForm"
+ novalidate
+ cdFormScope="osd">
+ <div class="modal-body">
+ <!-- Priority -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="priority"
+ i18n>Priority</label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ formControlName="priority"
+ id="priority"
+ (change)="onPriorityChange($event.target.value)">
+ <option *ngFor="let priority of priorities"
+ [value]="priority.name">
+ {{ priority.text }}
+ </option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="osdRecvSpeedForm.showError('priority', formDir, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Customize priority -->
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input formControlName="customizePriority"
+ class="custom-control-input"
+ id="customizePriority"
+ name="customizePriority"
+ type="checkbox"
+ (change)="onCustomizePriorityChange()">
+ <label class="custom-control-label"
+ for="customizePriority"
+ i18n>Customize priority values</label>
+ </div>
+ </div>
+ </div>
+
+ <!-- Priority values -->
+ <div class="form-group row"
+ *ngFor="let attr of priorityAttrs | keyvalue">
+ <label class="cd-col-form-label"
+ [for]="attr.key">
+ <span [ngClass]="{'required': osdRecvSpeedForm.getValue('customizePriority')}">
+ {{ attr.value.text }}
+ </span>
+ <cd-helper *ngIf="attr.value.desc">{{ attr.value.desc }}</cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="number"
+ [id]="attr.key"
+ [formControlName]="attr.key"
+ [readonly]="!osdRecvSpeedForm.getValue('customizePriority')">
+ <span class="invalid-feedback"
+ *ngIf="osdRecvSpeedForm.getValue('customizePriority') &&
+ osdRecvSpeedForm.showError(attr.key, formDir, 'required')"
+ i18n>This field is required!</span>
+ <span class="invalid-feedback"
+ *ngIf="osdRecvSpeedForm.getValue('customizePriority') &&
+ osdRecvSpeedForm.showError(attr.key, formDir, 'pattern')"
+ i18n>{{ attr.value.patternHelpText }}</span>
+ <span class="invalid-feedback"
+ *ngIf="osdRecvSpeedForm.getValue('customizePriority') &&
+ osdRecvSpeedForm.showError(attr.key, formDir, 'max')"
+ i18n>The entered value is too high! It must not be greater than {{ attr.value.maxValue }}.</span>
+ <span class="invalid-feedback"
+ *ngIf="osdRecvSpeedForm.getValue('customizePriority') &&
+ osdRecvSpeedForm.showError(attr.key, formDir, 'min')"
+ i18n>The entered value is too low! It must not be lower than {{ attr.value.minValue }}.</span>
+ </div>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="submitAction()"
+ [form]="osdRecvSpeedForm"
+ [submitText]="actionLabels.UPDATE"
+ [showSubmit]="permissions.configOpt.update"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.scss
new file mode 100755
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts
new file mode 100755
index 000000000..f8b72940b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts
@@ -0,0 +1,317 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { ToastrModule } from 'ngx-toastr';
+import { of as observableOf } from 'rxjs';
+
+import { ConfigurationService } from '~/app/shared/api/configuration.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { OsdRecvSpeedModalComponent } from './osd-recv-speed-modal.component';
+
+describe('OsdRecvSpeedModalComponent', () => {
+ let component: OsdRecvSpeedModalComponent;
+ let fixture: ComponentFixture<OsdRecvSpeedModalComponent>;
+ let configurationService: ConfigurationService;
+
+ configureTestBed({
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ RouterTestingModule,
+ SharedModule,
+ ToastrModule.forRoot()
+ ],
+ declarations: [OsdRecvSpeedModalComponent],
+ providers: [NgbActiveModal]
+ });
+
+ let configOptions: any[] = [];
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OsdRecvSpeedModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ configurationService = TestBed.inject(ConfigurationService);
+ configOptions = [
+ {
+ name: 'osd_max_backfills',
+ desc: '',
+ type: 'uint',
+ default: 1
+ },
+ {
+ name: 'osd_recovery_max_active',
+ desc: '',
+ type: 'uint',
+ default: 3
+ },
+ {
+ name: 'osd_recovery_max_single_start',
+ desc: '',
+ type: 'uint',
+ default: 1
+ },
+ {
+ name: 'osd_recovery_sleep',
+ desc: 'Time in seconds to sleep before next recovery or backfill op',
+ type: 'float',
+ default: 0
+ }
+ ];
+ spyOn(configurationService, 'filter').and.returnValue(observableOf(configOptions));
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('ngOnInit', () => {
+ let setPriority: jasmine.Spy;
+ let setValidators: jasmine.Spy;
+
+ beforeEach(() => {
+ setPriority = spyOn(component, 'setPriority').and.callThrough();
+ setValidators = spyOn(component, 'setValidators').and.callThrough();
+ component.ngOnInit();
+ });
+
+ it('should call setValidators', () => {
+ expect(setValidators).toHaveBeenCalled();
+ });
+
+ it('should get and set priority correctly', () => {
+ const defaultPriority = _.find(component.priorities, (p) => {
+ return _.isEqual(p.name, 'default');
+ });
+ expect(setPriority).toHaveBeenCalledWith(defaultPriority);
+ });
+
+ it('should set descriptions correctly', () => {
+ expect(component.priorityAttrs['osd_max_backfills'].desc).toBe('');
+ expect(component.priorityAttrs['osd_recovery_max_active'].desc).toBe('');
+ expect(component.priorityAttrs['osd_recovery_max_single_start'].desc).toBe('');
+ expect(component.priorityAttrs['osd_recovery_sleep'].desc).toBe(
+ 'Time in seconds to sleep before next recovery or backfill op'
+ );
+ });
+ });
+
+ describe('setPriority', () => {
+ it('should prepare the form for a custom priority', () => {
+ const customPriority = {
+ name: 'custom',
+ text: 'Custom',
+ values: {
+ osd_max_backfills: 1,
+ osd_recovery_max_active: 4,
+ osd_recovery_max_single_start: 1,
+ osd_recovery_sleep: 1
+ }
+ };
+
+ component.setPriority(customPriority);
+
+ const customInPriorities = _.find(component.priorities, (p) => {
+ return p.name === 'custom';
+ });
+
+ expect(customInPriorities).not.toBeNull();
+ expect(component.osdRecvSpeedForm.getValue('priority')).toBe('custom');
+ expect(component.osdRecvSpeedForm.getValue('osd_max_backfills')).toBe(1);
+ expect(component.osdRecvSpeedForm.getValue('osd_recovery_max_active')).toBe(4);
+ expect(component.osdRecvSpeedForm.getValue('osd_recovery_max_single_start')).toBe(1);
+ expect(component.osdRecvSpeedForm.getValue('osd_recovery_sleep')).toBe(1);
+ });
+
+ it('should prepare the form for a none custom priority', () => {
+ const lowPriority = {
+ name: 'low',
+ text: 'Low',
+ values: {
+ osd_max_backfills: 1,
+ osd_recovery_max_active: 1,
+ osd_recovery_max_single_start: 1,
+ osd_recovery_sleep: 0.5
+ }
+ };
+
+ component.setPriority(lowPriority);
+
+ const customInPriorities = _.find(component.priorities, (p) => {
+ return p.name === 'custom';
+ });
+
+ expect(customInPriorities).toBeUndefined();
+ expect(component.osdRecvSpeedForm.getValue('priority')).toBe('low');
+ expect(component.osdRecvSpeedForm.getValue('osd_max_backfills')).toBe(1);
+ expect(component.osdRecvSpeedForm.getValue('osd_recovery_max_active')).toBe(1);
+ expect(component.osdRecvSpeedForm.getValue('osd_recovery_max_single_start')).toBe(1);
+ expect(component.osdRecvSpeedForm.getValue('osd_recovery_sleep')).toBe(0.5);
+ });
+ });
+
+ describe('detectPriority', () => {
+ const configOptionsLow = {
+ osd_max_backfills: 1,
+ osd_recovery_max_active: 1,
+ osd_recovery_max_single_start: 1,
+ osd_recovery_sleep: 0.5
+ };
+
+ const configOptionsDefault = {
+ osd_max_backfills: 1,
+ osd_recovery_max_active: 3,
+ osd_recovery_max_single_start: 1,
+ osd_recovery_sleep: 0
+ };
+
+ const configOptionsHigh = {
+ osd_max_backfills: 4,
+ osd_recovery_max_active: 4,
+ osd_recovery_max_single_start: 4,
+ osd_recovery_sleep: 0
+ };
+
+ const configOptionsCustom = {
+ osd_max_backfills: 1,
+ osd_recovery_max_active: 2,
+ osd_recovery_max_single_start: 1,
+ osd_recovery_sleep: 0
+ };
+
+ const configOptionsIncomplete = {
+ osd_max_backfills: 1,
+ osd_recovery_max_single_start: 1,
+ osd_recovery_sleep: 0
+ };
+
+ it('should return priority "low" if the config option values have been set accordingly', () => {
+ component.detectPriority(configOptionsLow, (priority: Record<string, any>) => {
+ expect(priority.name).toBe('low');
+ });
+ expect(component.osdRecvSpeedForm.getValue('customizePriority')).toBeFalsy();
+ });
+
+ it('should return priority "default" if the config option values have been set accordingly', () => {
+ component.detectPriority(configOptionsDefault, (priority: Record<string, any>) => {
+ expect(priority.name).toBe('default');
+ });
+ expect(component.osdRecvSpeedForm.getValue('customizePriority')).toBeFalsy();
+ });
+
+ it('should return priority "high" if the config option values have been set accordingly', () => {
+ component.detectPriority(configOptionsHigh, (priority: Record<string, any>) => {
+ expect(priority.name).toBe('high');
+ });
+ expect(component.osdRecvSpeedForm.getValue('customizePriority')).toBeFalsy();
+ });
+
+ it('should return priority "custom" if the config option values do not match any priority', () => {
+ component.detectPriority(configOptionsCustom, (priority: Record<string, any>) => {
+ expect(priority.name).toBe('custom');
+ });
+ expect(component.osdRecvSpeedForm.getValue('customizePriority')).toBeTruthy();
+ });
+
+ it('should return no priority if the config option values are incomplete', () => {
+ component.detectPriority(configOptionsIncomplete, (priority: Record<string, any>) => {
+ expect(priority.name).toBeNull();
+ });
+ expect(component.osdRecvSpeedForm.getValue('customizePriority')).toBeFalsy();
+ });
+ });
+
+ describe('getCurrentValues', () => {
+ it('should return default values if no value has been set by the user', () => {
+ const currentValues = component.getCurrentValues(configOptions);
+ configOptions.forEach((configOption) => {
+ const configOptionValue = currentValues.values[configOption.name];
+ expect(configOptionValue).toBe(configOption.default);
+ });
+ });
+
+ it('should return the values set by the user if they exist', () => {
+ configOptions.forEach((configOption) => {
+ configOption['value'] = [{ section: 'osd', value: 7 }];
+ });
+
+ const currentValues = component.getCurrentValues(configOptions);
+ Object.values(currentValues.values).forEach((configValue) => {
+ expect(configValue).toBe(7);
+ });
+ });
+
+ it('should return the default value if one is missing', () => {
+ for (let i = 1; i < configOptions.length; i++) {
+ configOptions[i]['value'] = [{ section: 'osd', value: 7 }];
+ }
+
+ const currentValues = component.getCurrentValues(configOptions);
+ Object.entries(currentValues.values).forEach(([configName, configValue]) => {
+ if (configName === 'osd_max_backfills') {
+ expect(configValue).toBe(1);
+ } else {
+ expect(configValue).toBe(7);
+ }
+ });
+ });
+
+ it('should return nothing if neither value nor default value is given', () => {
+ configOptions[0].default = null;
+ const currentValues = component.getCurrentValues(configOptions);
+ expect(currentValues.values).not.toContain('osd_max_backfills');
+ });
+ });
+
+ describe('setDescription', () => {
+ it('should set the description if one is given', () => {
+ component.setDescription(configOptions);
+ Object.keys(component.priorityAttrs).forEach((configOptionName) => {
+ if (configOptionName === 'osd_recovery_sleep') {
+ expect(component.priorityAttrs[configOptionName].desc).toBe(
+ 'Time in seconds to sleep before next recovery or backfill op'
+ );
+ } else {
+ expect(component.priorityAttrs[configOptionName].desc).toBe('');
+ }
+ });
+ });
+ });
+
+ describe('setValidators', () => {
+ it('should set needed validators for config option', () => {
+ component.setValidators(configOptions);
+ configOptions.forEach((configOption) => {
+ const control = component.osdRecvSpeedForm.controls[configOption.name];
+
+ if (configOption.type === 'float') {
+ expect(component.priorityAttrs[configOption.name].patternHelpText).toBe(
+ 'The entered value needs to be a number or decimal.'
+ );
+ } else {
+ expect(component.priorityAttrs[configOption.name].minValue).toBe(0);
+ expect(component.priorityAttrs[configOption.name].patternHelpText).toBe(
+ 'The entered value needs to be an unsigned number.'
+ );
+
+ control.setValue(-1);
+ expect(control.hasError('min')).toBeTruthy();
+ }
+
+ control.setValue(null);
+ expect(control.hasError('required')).toBeTruthy();
+ control.setValue('E');
+ expect(control.hasError('pattern')).toBeTruthy();
+ control.setValue(3);
+ expect(control.hasError('required')).toBeFalsy();
+ expect(control.hasError('min')).toBeFalsy();
+ expect(control.hasError('pattern')).toBeFalsy();
+ });
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts
new file mode 100755
index 000000000..6546e0865
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts
@@ -0,0 +1,238 @@
+import { Component, OnInit } from '@angular/core';
+import { FormControl, Validators } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+
+import { ConfigurationService } from '~/app/shared/api/configuration.service';
+import { OsdService } from '~/app/shared/api/osd.service';
+import { ConfigOptionTypes } from '~/app/shared/components/config-option/config-option.types';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { Permissions } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+
+@Component({
+ selector: 'cd-osd-recv-speed-modal',
+ templateUrl: './osd-recv-speed-modal.component.html',
+ styleUrls: ['./osd-recv-speed-modal.component.scss']
+})
+export class OsdRecvSpeedModalComponent implements OnInit {
+ osdRecvSpeedForm: CdFormGroup;
+ permissions: Permissions;
+
+ priorities: any[] = [];
+ priorityAttrs = {};
+
+ constructor(
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n,
+ private authStorageService: AuthStorageService,
+ private configService: ConfigurationService,
+ private notificationService: NotificationService,
+ private osdService: OsdService
+ ) {
+ this.permissions = this.authStorageService.getPermissions();
+ this.priorities = this.osdService.osdRecvSpeedModalPriorities.KNOWN_PRIORITIES;
+ this.osdRecvSpeedForm = new CdFormGroup({
+ priority: new FormControl(null, { validators: [Validators.required] }),
+ customizePriority: new FormControl(false)
+ });
+ this.priorityAttrs = {
+ osd_max_backfills: {
+ text: $localize`Max Backfills`,
+ desc: '',
+ patternHelpText: '',
+ maxValue: undefined,
+ minValue: undefined
+ },
+ osd_recovery_max_active: {
+ text: $localize`Recovery Max Active`,
+ desc: '',
+ patternHelpText: '',
+ maxValue: undefined,
+ minValue: undefined
+ },
+ osd_recovery_max_single_start: {
+ text: $localize`Recovery Max Single Start`,
+ desc: '',
+ patternHelpText: '',
+ maxValue: undefined,
+ minValue: undefined
+ },
+ osd_recovery_sleep: {
+ text: $localize`Recovery Sleep`,
+ desc: '',
+ patternHelpText: '',
+ maxValue: undefined,
+ minValue: undefined
+ }
+ };
+
+ Object.keys(this.priorityAttrs).forEach((configOptionName) => {
+ this.osdRecvSpeedForm.addControl(
+ configOptionName,
+ new FormControl(null, { validators: [Validators.required] })
+ );
+ });
+ }
+
+ ngOnInit() {
+ this.configService.filter(Object.keys(this.priorityAttrs)).subscribe((data: any) => {
+ const config_option_values = this.getCurrentValues(data);
+ this.detectPriority(config_option_values.values, (priority: any) => {
+ this.setPriority(priority);
+ });
+ this.setDescription(config_option_values.configOptions);
+ this.setValidators(config_option_values.configOptions);
+ });
+ }
+
+ detectPriority(configOptionValues: any, callbackFn: Function) {
+ const priority = _.find(this.priorities, (p) => {
+ return _.isEqual(p.values, configOptionValues);
+ });
+
+ this.osdRecvSpeedForm.controls.customizePriority.setValue(false);
+
+ if (priority) {
+ return callbackFn(priority);
+ }
+
+ if (Object.entries(configOptionValues).length === 4) {
+ this.osdRecvSpeedForm.controls.customizePriority.setValue(true);
+ return callbackFn(
+ Object({ name: 'custom', text: $localize`Custom`, values: configOptionValues })
+ );
+ }
+
+ return callbackFn(this.priorities[0]);
+ }
+
+ getCurrentValues(configOptions: any) {
+ const currentValues: Record<string, any> = { values: {}, configOptions: [] };
+ configOptions.forEach((configOption: any) => {
+ currentValues.configOptions.push(configOption);
+
+ if ('value' in configOption) {
+ configOption.value.forEach((value: any) => {
+ if (value.section === 'osd') {
+ currentValues.values[configOption.name] = Number(value.value);
+ }
+ });
+ } else if ('default' in configOption && configOption.default !== null) {
+ currentValues.values[configOption.name] = Number(configOption.default);
+ }
+ });
+ return currentValues;
+ }
+
+ setDescription(configOptions: Array<any>) {
+ configOptions.forEach((configOption) => {
+ if (configOption.desc !== '') {
+ this.priorityAttrs[configOption.name].desc = configOption.desc;
+ }
+ });
+ }
+
+ setPriority(priority: any) {
+ const customPriority = _.find(this.priorities, (p) => {
+ return p.name === 'custom';
+ });
+
+ if (priority.name === 'custom') {
+ if (!customPriority) {
+ this.priorities.push(priority);
+ }
+ } else {
+ if (customPriority) {
+ this.priorities.splice(this.priorities.indexOf(customPriority), 1);
+ }
+ }
+
+ this.osdRecvSpeedForm.controls.priority.setValue(priority.name);
+ Object.entries(priority.values).forEach(([name, value]) => {
+ this.osdRecvSpeedForm.controls[name].setValue(value);
+ });
+ }
+
+ setValidators(configOptions: Array<any>) {
+ configOptions.forEach((configOption) => {
+ const typeValidators = ConfigOptionTypes.getTypeValidators(configOption);
+ if (typeValidators) {
+ typeValidators.validators.push(Validators.required);
+
+ if ('max' in typeValidators && typeValidators.max !== '') {
+ this.priorityAttrs[configOption.name].maxValue = typeValidators.max;
+ }
+
+ if ('min' in typeValidators && typeValidators.min !== '') {
+ this.priorityAttrs[configOption.name].minValue = typeValidators.min;
+ }
+
+ this.priorityAttrs[configOption.name].patternHelpText = typeValidators.patternHelpText;
+ this.osdRecvSpeedForm.controls[configOption.name].setValidators(typeValidators.validators);
+ } else {
+ this.osdRecvSpeedForm.controls[configOption.name].setValidators(Validators.required);
+ }
+ });
+ }
+
+ onCustomizePriorityChange() {
+ const values = {};
+ Object.keys(this.priorityAttrs).forEach((configOptionName) => {
+ values[configOptionName] = this.osdRecvSpeedForm.getValue(configOptionName);
+ });
+
+ if (this.osdRecvSpeedForm.getValue('customizePriority')) {
+ const customPriority = {
+ name: 'custom',
+ text: $localize`Custom`,
+ values: values
+ };
+ this.setPriority(customPriority);
+ } else {
+ this.detectPriority(values, (priority: any) => {
+ this.setPriority(priority);
+ });
+ }
+ }
+
+ onPriorityChange(selectedPriorityName: string) {
+ const selectedPriority =
+ _.find(this.priorities, (p) => {
+ return p.name === selectedPriorityName;
+ }) || this.priorities[0];
+ // Uncheck the 'Customize priority values' checkbox.
+ this.osdRecvSpeedForm.get('customizePriority').setValue(false);
+ // Set the priority profile values.
+ this.setPriority(selectedPriority);
+ }
+
+ submitAction() {
+ const options = {};
+ Object.keys(this.priorityAttrs).forEach((configOptionName) => {
+ options[configOptionName] = {
+ section: 'osd',
+ value: this.osdRecvSpeedForm.getValue(configOptionName)
+ };
+ });
+
+ this.configService.bulkCreate({ options: options }).subscribe(
+ () => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Updated OSD recovery speed priority '${this.osdRecvSpeedForm.getValue(
+ 'priority'
+ )}'`
+ );
+ this.activeModal.close();
+ },
+ () => {
+ this.activeModal.close();
+ }
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html
new file mode 100644
index 000000000..e5aa22311
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html
@@ -0,0 +1,38 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container class="modal-title"
+ i18n>Reweight OSD: {{ osdId }}</ng-container>
+
+ <ng-container class="modal-content">
+ <form [formGroup]="reweightForm">
+ <div class="modal-body">
+ <div class="row">
+ <label for="weight"
+ class="cd-col-form-label">Weight</label>
+ <div class="cd-col-form-input">
+ <input id="weight"
+ class="form-control"
+ type="number"
+ step="0.1"
+ formControlName="weight"
+ min="0"
+ max="1"
+ [value]="currentWeight">
+ <span class="invalid-feedback"
+ *ngIf="weight.errors">
+ <span *ngIf="weight.errors?.required"
+ i18n>This field is required.</span>
+ <span *ngIf="weight.errors?.max || weight.errors?.min"
+ i18n>The value needs to be between 0 and 1.</span>
+ </span>
+ </div>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="reweight()"
+ [form]="reweightForm"
+ [submitText]="actionLabels.REWEIGHT"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.spec.ts
new file mode 100644
index 000000000..41e05021e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.spec.ts
@@ -0,0 +1,56 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { of } from 'rxjs';
+
+import { OsdService } from '~/app/shared/api/osd.service';
+import { BackButtonComponent } from '~/app/shared/components/back-button/back-button.component';
+import { ModalComponent } from '~/app/shared/components/modal/modal.component';
+import { SubmitButtonComponent } from '~/app/shared/components/submit-button/submit-button.component';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { OsdReweightModalComponent } from './osd-reweight-modal.component';
+
+describe('OsdReweightModalComponent', () => {
+ let component: OsdReweightModalComponent;
+ let fixture: ComponentFixture<OsdReweightModalComponent>;
+
+ configureTestBed({
+ imports: [ReactiveFormsModule, HttpClientTestingModule, RouterTestingModule],
+ declarations: [
+ OsdReweightModalComponent,
+ ModalComponent,
+ SubmitButtonComponent,
+ BackButtonComponent
+ ],
+ schemas: [NO_ERRORS_SCHEMA],
+ providers: [OsdService, NgbActiveModal, CdFormBuilder]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OsdReweightModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call OsdService::reweight() on submit', () => {
+ component.osdId = 1;
+ component.reweightForm.get('weight').setValue(0.5);
+
+ const osdServiceSpy = spyOn(TestBed.inject(OsdService), 'reweight').and.callFake(() =>
+ of(true)
+ );
+ component.reweight();
+
+ expect(osdServiceSpy.calls.count()).toBe(1);
+ expect(osdServiceSpy.calls.first().args).toEqual([1, 0.5]);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.ts
new file mode 100644
index 000000000..acbdb2d8f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.ts
@@ -0,0 +1,43 @@
+import { Component, OnInit } from '@angular/core';
+import { Validators } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+import { OsdService } from '~/app/shared/api/osd.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+
+@Component({
+ selector: 'cd-osd-reweight-modal',
+ templateUrl: './osd-reweight-modal.component.html',
+ styleUrls: ['./osd-reweight-modal.component.scss']
+})
+export class OsdReweightModalComponent implements OnInit {
+ currentWeight = 1;
+ osdId: number;
+ reweightForm: CdFormGroup;
+
+ constructor(
+ public actionLabels: ActionLabelsI18n,
+ public activeModal: NgbActiveModal,
+ private osdService: OsdService,
+ private fb: CdFormBuilder
+ ) {}
+
+ get weight() {
+ return this.reweightForm.get('weight');
+ }
+
+ ngOnInit() {
+ this.reweightForm = this.fb.group({
+ weight: this.fb.control(this.currentWeight, [Validators.required])
+ });
+ }
+
+ reweight() {
+ this.osdService
+ .reweight(this.osdId, this.reweightForm.value.weight)
+ .subscribe(() => this.activeModal.close());
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html
new file mode 100644
index 000000000..568c700fa
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html
@@ -0,0 +1,22 @@
+<cd-modal [modalRef]="activeModal">
+ <span class="modal-title"
+ i18n>OSDs {deep, select, true {Deep } other {}}Scrub</span>
+
+ <ng-container class="modal-content">
+ <form name="scrubForm"
+ #formDir="ngForm"
+ [formGroup]="scrubForm"
+ novalidate>
+ <div class="modal-body">
+ <p i18n>You are about to apply a {deep, select, true {deep } other {}}scrub to
+ the OSD(s): <strong>{{ selected | join }}</strong>.</p>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="scrub()"
+ [form]="scrubForm"
+ [submitText]="actionLabels.UPDATE"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.spec.ts
new file mode 100644
index 000000000..c65dad0de
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.spec.ts
@@ -0,0 +1,50 @@
+import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+import { OsdService } from '~/app/shared/api/osd.service';
+import { JoinPipe } from '~/app/shared/pipes/join.pipe';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { OsdScrubModalComponent } from './osd-scrub-modal.component';
+
+describe('OsdScrubModalComponent', () => {
+ let component: OsdScrubModalComponent;
+ let fixture: ComponentFixture<OsdScrubModalComponent>;
+
+ const fakeService = {
+ list: () => {
+ return new Promise(() => undefined);
+ },
+ scrub: () => {
+ return new Promise(() => undefined);
+ },
+ scrub_many: () => {
+ return new Promise(() => undefined);
+ }
+ };
+
+ configureTestBed({
+ imports: [ReactiveFormsModule],
+ declarations: [OsdScrubModalComponent, JoinPipe],
+ schemas: [NO_ERRORS_SCHEMA],
+ providers: [
+ NgbActiveModal,
+ JoinPipe,
+ { provide: OsdService, useValue: fakeService },
+ { provide: NotificationService, useValue: fakeService }
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OsdScrubModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts
new file mode 100644
index 000000000..b2f636708
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts
@@ -0,0 +1,52 @@
+import { Component, OnInit } from '@angular/core';
+import { FormGroup } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { forkJoin } from 'rxjs';
+
+import { OsdService } from '~/app/shared/api/osd.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { JoinPipe } from '~/app/shared/pipes/join.pipe';
+import { NotificationService } from '~/app/shared/services/notification.service';
+
+@Component({
+ selector: 'cd-osd-scrub-modal',
+ templateUrl: './osd-scrub-modal.component.html',
+ styleUrls: ['./osd-scrub-modal.component.scss']
+})
+export class OsdScrubModalComponent implements OnInit {
+ deep: boolean;
+ scrubForm: FormGroup;
+ selected: any[] = [];
+
+ constructor(
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n,
+ private osdService: OsdService,
+ private notificationService: NotificationService,
+ private joinPipe: JoinPipe
+ ) {}
+
+ ngOnInit() {
+ this.scrubForm = new FormGroup({});
+ }
+
+ scrub() {
+ forkJoin(this.selected.map((id: any) => this.osdService.scrub(id, this.deep))).subscribe(
+ () => {
+ const operation = this.deep ? 'Deep scrub' : 'Scrub';
+
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`${operation} was initialized in the following OSD(s): ${this.joinPipe.transform(
+ this.selected
+ )}`
+ );
+
+ this.activeModal.close();
+ },
+ () => this.activeModal.close()
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html
new file mode 100644
index 000000000..278bc4ddc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html
@@ -0,0 +1,41 @@
+<cd-prometheus-tabs></cd-prometheus-tabs>
+
+<cd-alert-panel *ngIf="!isAlertmanagerConfigured"
+ type="info"
+ i18n>To see all active Prometheus alerts, please provide
+ the URL to the API of Prometheus' Alertmanager as described
+ in the <cd-doc section="prometheus"></cd-doc>.</cd-alert-panel>
+
+<cd-table *ngIf="isAlertmanagerConfigured"
+ [data]="prometheusAlertService.alerts"
+ [columns]="columns"
+ identifier="fingerprint"
+ [forceIdentifier]="true"
+ [customCss]="customCss"
+ selectionType="single"
+ [hasDetails]="true"
+ (setExpandedRow)="setExpandedRow($event)"
+ (updateSelection)="updateSelection($event)">
+ <cd-table-actions class="table-actions"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+
+ <cd-table-key-value cdTableDetail
+ *ngIf="expandedRow"
+ [renderObjects]="true"
+ [hideEmpty]="true"
+ [appendParentKey]="false"
+ [data]="expandedRow"
+ [customCss]="customCss"
+ [autoReload]="false">
+ </cd-table-key-value>
+</cd-table>
+
+<ng-template #externalLinkTpl
+ let-row="row"
+ let-value="value">
+ <a [href]="value"
+ target="_blank"><i [ngClass]="[icons.lineChart]"></i> Source</a>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.spec.ts
new file mode 100644
index 000000000..7b10c20aa
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.spec.ts
@@ -0,0 +1,103 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+
+import { CephModule } from '~/app/ceph/ceph.module';
+import { ClusterModule } from '~/app/ceph/cluster/cluster.module';
+import { DashboardModule } from '~/app/ceph/dashboard/dashboard.module';
+import { CoreModule } from '~/app/core/core.module';
+import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, PermissionHelper } from '~/testing/unit-test-helper';
+import { ActiveAlertListComponent } from './active-alert-list.component';
+
+describe('ActiveAlertListComponent', () => {
+ let component: ActiveAlertListComponent;
+ let fixture: ComponentFixture<ActiveAlertListComponent>;
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ HttpClientTestingModule,
+ NgbNavModule,
+ RouterTestingModule,
+ ToastrModule.forRoot(),
+ SharedModule,
+ ClusterModule,
+ DashboardModule,
+ CephModule,
+ CoreModule
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ActiveAlertListComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+
+ it('should test all TableActions combinations', () => {
+ component.ngOnInit();
+ const permissionHelper: PermissionHelper = new PermissionHelper(component.permission);
+ const tableActions: TableActionsComponent = permissionHelper.setPermissionsAndGetActions(
+ component.tableActions
+ );
+
+ expect(tableActions).toEqual({
+ 'create,update,delete': {
+ actions: ['Create Silence'],
+ primary: {
+ multiple: 'Create Silence',
+ executing: 'Create Silence',
+ single: 'Create Silence',
+ no: 'Create Silence'
+ }
+ },
+ 'create,update': {
+ actions: ['Create Silence'],
+ primary: {
+ multiple: 'Create Silence',
+ executing: 'Create Silence',
+ single: 'Create Silence',
+ no: 'Create Silence'
+ }
+ },
+ 'create,delete': {
+ actions: ['Create Silence'],
+ primary: {
+ multiple: 'Create Silence',
+ executing: 'Create Silence',
+ single: 'Create Silence',
+ no: 'Create Silence'
+ }
+ },
+ create: {
+ actions: ['Create Silence'],
+ primary: {
+ multiple: 'Create Silence',
+ executing: 'Create Silence',
+ single: 'Create Silence',
+ no: 'Create Silence'
+ }
+ },
+ 'update,delete': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ },
+ update: { actions: [], primary: { multiple: '', executing: '', single: '', no: '' } },
+ delete: { actions: [], primary: { multiple: '', executing: '', single: '', no: '' } },
+ 'no-permissions': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ }
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts
new file mode 100644
index 000000000..83888a555
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts
@@ -0,0 +1,101 @@
+import { Component, Inject, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import { PrometheusService } from '~/app/shared/api/prometheus.service';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { Permission } from '~/app/shared/models/permissions';
+import { CdDatePipe } from '~/app/shared/pipes/cd-date.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { PrometheusAlertService } from '~/app/shared/services/prometheus-alert.service';
+import { URLBuilderService } from '~/app/shared/services/url-builder.service';
+import { PrometheusListHelper } from '../prometheus-list-helper';
+
+const BASE_URL = 'silences'; // as only silence actions can be used
+
+@Component({
+ selector: 'cd-active-alert-list',
+ providers: [{ provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }],
+ templateUrl: './active-alert-list.component.html',
+ styleUrls: ['./active-alert-list.component.scss']
+})
+export class ActiveAlertListComponent extends PrometheusListHelper implements OnInit {
+ @ViewChild('externalLinkTpl', { static: true })
+ externalLinkTpl: TemplateRef<any>;
+ columns: CdTableColumn[];
+ tableActions: CdTableAction[];
+ permission: Permission;
+ selection = new CdTableSelection();
+ icons = Icons;
+ customCss = {
+ 'badge badge-danger': 'active',
+ 'badge badge-warning': 'unprocessed',
+ 'badge badge-info': 'suppressed'
+ };
+
+ constructor(
+ // NotificationsComponent will refresh all alerts every 5s (No need to do it here as well)
+ private authStorageService: AuthStorageService,
+ public prometheusAlertService: PrometheusAlertService,
+ private urlBuilder: URLBuilderService,
+ private cdDatePipe: CdDatePipe,
+ @Inject(PrometheusService) prometheusService: PrometheusService
+ ) {
+ super(prometheusService);
+ this.permission = this.authStorageService.getPermissions().prometheus;
+ this.tableActions = [
+ {
+ permission: 'create',
+ canBePrimary: (selection: CdTableSelection) => selection.hasSingleSelection,
+ disable: (selection: CdTableSelection) =>
+ !selection.hasSingleSelection || selection.first().cdExecuting,
+ icon: Icons.add,
+ routerLink: () =>
+ '/monitoring' + this.urlBuilder.getCreateFrom(this.selection.first().fingerprint),
+ name: $localize`Create Silence`
+ }
+ ];
+ }
+
+ ngOnInit() {
+ super.ngOnInit();
+ this.columns = [
+ {
+ name: $localize`Name`,
+ prop: 'labels.alertname',
+ flexGrow: 2
+ },
+ {
+ name: $localize`Job`,
+ prop: 'labels.job',
+ flexGrow: 2
+ },
+ {
+ name: $localize`Severity`,
+ prop: 'labels.severity'
+ },
+ {
+ name: $localize`State`,
+ prop: 'status.state',
+ cellTransformation: CellTemplate.classAdding
+ },
+ {
+ name: $localize`Started`,
+ prop: 'startsAt',
+ pipe: this.cdDatePipe
+ },
+ {
+ name: $localize`URL`,
+ prop: 'generatorURL',
+ sortable: false,
+ cellTemplate: this.externalLinkTpl
+ }
+ ];
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-list-helper.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-list-helper.ts
new file mode 100644
index 000000000..c1a594908
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-list-helper.ts
@@ -0,0 +1,24 @@
+import { Directive, OnInit } from '@angular/core';
+
+import { PrometheusService } from '~/app/shared/api/prometheus.service';
+import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
+
+@Directive()
+// tslint:disable-next-line: directive-class-suffix
+export class PrometheusListHelper extends ListWithDetails implements OnInit {
+ public isPrometheusConfigured = false;
+ public isAlertmanagerConfigured = false;
+
+ constructor(protected prometheusService: PrometheusService) {
+ super();
+ }
+
+ ngOnInit() {
+ this.prometheusService.ifAlertmanagerConfigured(() => {
+ this.isAlertmanagerConfigured = true;
+ });
+ this.prometheusService.ifPrometheusConfigured(() => {
+ this.isPrometheusConfigured = true;
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html
new file mode 100644
index 000000000..fd3967ce6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html
@@ -0,0 +1,18 @@
+<ul ngbNav
+ #nav="ngbNav"
+ [activeId]="router.url"
+ (navChange)="router.navigate([$event.nextId])"
+ class="nav-tabs">
+ <li ngbNavItem="/monitoring/active-alerts">
+ <a ngbNavLink
+ i18n>Active Alerts</a>
+ </li>
+ <li ngbNavItem="/monitoring/alerts">
+ <a ngbNavLink
+ i18n>Alerts</a>
+ </li>
+ <li ngbNavItem="/monitoring/silences">
+ <a ngbNavLink
+ i18n>Silences</a>
+ </li>
+</ul>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.spec.ts
new file mode 100644
index 000000000..675063413
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.spec.ts
@@ -0,0 +1,27 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { PrometheusTabsComponent } from './prometheus-tabs.component';
+
+describe('PrometheusTabsComponent', () => {
+ let component: PrometheusTabsComponent;
+ let fixture: ComponentFixture<PrometheusTabsComponent>;
+
+ configureTestBed({
+ imports: [RouterTestingModule, NgbNavModule],
+ declarations: [PrometheusTabsComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(PrometheusTabsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.ts
new file mode 100644
index 000000000..4011770d4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.ts
@@ -0,0 +1,11 @@
+import { Component } from '@angular/core';
+import { Router } from '@angular/router';
+
+@Component({
+ selector: 'cd-prometheus-tabs',
+ templateUrl: './prometheus-tabs.component.html',
+ styleUrls: ['./prometheus-tabs.component.scss']
+})
+export class PrometheusTabsComponent {
+ constructor(public router: Router) {}
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html
new file mode 100644
index 000000000..4ae7e8a31
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html
@@ -0,0 +1,22 @@
+<cd-prometheus-tabs></cd-prometheus-tabs>
+
+<cd-alert-panel *ngIf="!isPrometheusConfigured"
+ type="info"
+ i18n>To see all configured Prometheus alerts, please
+ provide the URL to the API of Prometheus as described in
+ the <cd-doc section="prometheus"></cd-doc>.</cd-alert-panel>
+
+<cd-table *ngIf="isPrometheusConfigured"
+ [data]="prometheusAlertService.rules"
+ [columns]="columns"
+ [selectionType]="'single'"
+ [hasDetails]="true"
+ (setExpandedRow)="setExpandedRow($event)"
+ (updateSelection)="updateSelection($event)">
+ <cd-table-key-value cdTableDetail
+ *ngIf="expandedRow"
+ [data]="expandedRow"
+ [renderObjects]="true"
+ [hideKeys]="hideKeys">
+ </cd-table-key-value>
+</cd-table>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.spec.ts
new file mode 100644
index 000000000..ada139e6d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.spec.ts
@@ -0,0 +1,40 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+
+import { PrometheusService } from '~/app/shared/api/prometheus.service';
+import { SettingsService } from '~/app/shared/api/settings.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { PrometheusTabsComponent } from '../prometheus-tabs/prometheus-tabs.component';
+import { RulesListComponent } from './rules-list.component';
+
+describe('RulesListComponent', () => {
+ let component: RulesListComponent;
+ let fixture: ComponentFixture<RulesListComponent>;
+
+ configureTestBed({
+ declarations: [RulesListComponent, PrometheusTabsComponent],
+ imports: [
+ HttpClientTestingModule,
+ SharedModule,
+ NgbNavModule,
+ RouterTestingModule,
+ ToastrModule.forRoot()
+ ],
+ providers: [PrometheusService, SettingsService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RulesListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts
new file mode 100644
index 000000000..325520d11
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts
@@ -0,0 +1,44 @@
+import { Component, Inject, OnInit } from '@angular/core';
+
+import { PrometheusService } from '~/app/shared/api/prometheus.service';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { PrometheusRule } from '~/app/shared/models/prometheus-alerts';
+import { DurationPipe } from '~/app/shared/pipes/duration.pipe';
+import { PrometheusAlertService } from '~/app/shared/services/prometheus-alert.service';
+import { PrometheusListHelper } from '../prometheus-list-helper';
+
+@Component({
+ selector: 'cd-rules-list',
+ templateUrl: './rules-list.component.html',
+ styleUrls: ['./rules-list.component.scss']
+})
+export class RulesListComponent extends PrometheusListHelper implements OnInit {
+ columns: CdTableColumn[];
+ expandedRow: PrometheusRule;
+
+ /**
+ * Hide active alerts in details of alerting rules as they are already shown
+ * in the 'active alerts' table. Also hide the 'type' column as the type is
+ * always supposed to be 'alerting'.
+ */
+ hideKeys = ['alerts', 'type'];
+
+ constructor(
+ public prometheusAlertService: PrometheusAlertService,
+ @Inject(PrometheusService) prometheusService: PrometheusService
+ ) {
+ super(prometheusService);
+ }
+
+ ngOnInit() {
+ super.ngOnInit();
+ this.columns = [
+ { prop: 'name', name: $localize`Name` },
+ { prop: 'labels.severity', name: $localize`Severity` },
+ { prop: 'group', name: $localize`Group` },
+ { prop: 'duration', name: $localize`Duration`, pipe: new DurationPipe() },
+ { prop: 'query', name: $localize`Query`, isHidden: true },
+ { prop: 'annotations.description', name: $localize`Description` }
+ ];
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html
new file mode 100644
index 000000000..02f04a06a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html
@@ -0,0 +1,224 @@
+<ng-template #matcherTpl
+ let-matcher="matcher"
+ let-index="index">
+ <div class="input-group my-2">
+ <ng-container *ngFor="let config of matcherConfig">
+ <div class="input-group-prepend">
+ <span class="input-group-text"
+ [ngbTooltip]="config.tooltip">
+ <i [ngClass]="[config.icon]"></i>
+ </span>
+ </div>
+
+ <ng-container *ngIf="config.attribute !== 'isRegex'">
+ <input type="text"
+ id="matcher-{{config.attribute}}-{{index}}"
+ class="form-control"
+ [value]="matcher[config.attribute]"
+ disabled
+ readonly>
+ </ng-container>
+
+ <ng-container *ngIf="config.attribute === 'isRegex'">
+ <div class="input-group-append">
+ <div class="input-group-text">
+ <input type="checkbox"
+ id="matcher-{{config.attribute}}-{{index}}"
+ [checked]="matcher[config.attribute]"
+ disabled
+ readonly>
+ </div>
+ </div>
+ </ng-container>
+ </ng-container>
+
+ <!-- Matcher actions -->
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ id="matcher-edit-{{index}}"
+ i18n-ngbTooltip
+ ngbTooltip="Edit"
+ (click)="showMatcherModal(index)">
+ <i [ngClass]="[icons.edit]"></i>
+ </button>
+ <button type="button"
+ class="btn btn-light"
+ id="matcher-delete-{{index}}"
+ i18n-ngbTooltip
+ ngbTooltip="Delete"
+ (click)="deleteMatcher(index)">
+ <i [ngClass]="[icons.trash]"></i>
+ </button>
+ </span>
+ </div>
+ <span class="help-block"></span>
+</ng-template>
+
+<div class="cd-col-form">
+ <form #formDir="ngForm"
+ [formGroup]="form"
+ class="form"
+ name="form"
+ novalidate>
+ <div class="card">
+ <div class="card-header">
+ <span i18n>{{ action | titlecase }} {{ resource | upperFirst }}</span>
+ <cd-helper *ngIf="edit"
+ i18n>Editing a silence will expire the old silence and recreate it as a new silence</cd-helper>
+ </div>
+
+ <!-- Creator -->
+ <div class="card-body">
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="created-by"
+ i18n>Creator</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ formControlName="createdBy"
+ id="created-by"
+ name="created-by"
+ type="text">
+ <span *ngIf="form.showError('createdBy', formDir, 'required')"
+ class="invalid-feedback"
+ i18n>This field is required!</span>
+ </div>
+ </div>
+
+ <!-- Comment -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="comment"
+ i18n>Comment</label>
+ <div class="cd-col-form-input">
+ <textarea class="form-control"
+ formControlName="comment"
+ id="comment"
+ name="comment"
+ type="text">
+ </textarea>
+ <span *ngIf="form.showError('comment', formDir, 'required')"
+ class="invalid-feedback"
+ i18n>This field is required!</span>
+ </div>
+ </div>
+
+ <!-- Start time -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="starts-at">
+ <span class="required"
+ i18n>Start time</span>
+ <cd-helper i18n>If the start time lies in the past the creation time will be used</cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ formControlName="startsAt"
+ [ngbPopover]="popStart"
+ triggers="manual"
+ #ps="ngbPopover"
+ (click)="ps.open()"
+ (keypress)="ps.close()">
+ <span *ngIf="form.showError('startsAt', formDir, 'required')"
+ class="invalid-feedback"
+ i18n>This field is required!</span>
+ </div>
+ </div>
+
+ <!-- Duration -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="duration"
+ i18n>Duration</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ formControlName="duration"
+ id="duration"
+ name="duration"
+ type="text">
+ <span *ngIf="form.showError('duration', formDir, 'required')"
+ class="invalid-feedback"
+ i18n>This field is required!</span>
+ </div>
+ </div>
+
+ <!-- End time -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="ends-at"
+ i18n>End time</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ formControlName="endsAt"
+ [ngbPopover]="popEnd"
+ triggers="manual"
+ #pe="ngbPopover"
+ (click)="pe.open()"
+ (keypress)="pe.close()">
+ <span *ngIf="form.showError('endsAt', formDir, 'required')"
+ class="invalid-feedback"
+ i18n>This field is required!</span>
+ </div>
+ </div>
+
+ <!-- Matchers -->
+ <fieldset>
+ <legend class="required"
+ i18n>Matchers</legend>
+
+ <div class="cd-col-form-offset">
+ <h5 *ngIf="matchers.length === 0"
+ [ngClass]="{'text-warning': !formDir.submitted, 'text-danger': formDir.submitted}">
+ <strong i18n>A silence requires at least one matcher</strong>
+ </h5>
+
+ <span *ngFor="let matcher of matchers; let i=index;">
+ <ng-container *ngTemplateOutlet="matcherTpl; context:{index: i, matcher: matcher}"></ng-container>
+ </span>
+
+ <div class="row">
+ <div class="col-12">
+ <button type="button"
+ id="add-matcher"
+ class="btn btn-light float-right my-3"
+ [ngClass]="{'btn-warning': formDir.submitted && matchers.length === 0 }"
+ (click)="showMatcherModal()">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>Add matcher</ng-container>
+ </button>
+ </div>
+ </div>
+ </div>
+
+ <div *ngIf="matchers.length && matcherMatch"
+ class="cd-col-form-offset {{matcherMatch.cssClass}}"
+ id="match-state">
+ <span class="text-muted {{matcherMatch.cssClass}}">
+ {{ matcherMatch.status }}
+ </span>
+ </div>
+ </fieldset>
+ </div>
+
+ <div class="card-footer">
+ <div class="text-right">
+ <cd-form-button-panel (submitActionEvent)="submit()"
+ [form]="form"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>
+ </div>
+ </div>
+ </div>
+ </form>
+</div>
+
+<ng-template #popStart>
+ <cd-date-time-picker [control]="form.get('startsAt')"
+ [hasSeconds]="false"></cd-date-time-picker>
+</ng-template>
+
+
+<ng-template #popEnd>
+ <cd-date-time-picker [control]="form.get('endsAt')"
+ [hasSeconds]="false"></cd-date-time-picker>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.scss
new file mode 100644
index 000000000..fb52450d4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.scss
@@ -0,0 +1,3 @@
+textarea {
+ resize: vertical;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.spec.ts
new file mode 100644
index 000000000..418983150
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.spec.ts
@@ -0,0 +1,598 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { ActivatedRoute, Router, Routes } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbPopoverModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import moment from 'moment';
+import { ToastrModule } from 'ngx-toastr';
+import { of, throwError } from 'rxjs';
+
+import { DashboardNotFoundError } from '~/app/core/error/error';
+import { ErrorComponent } from '~/app/core/error/error.component';
+import { PrometheusService } from '~/app/shared/api/prometheus.service';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { AlertmanagerSilence } from '~/app/shared/models/alertmanager-silence';
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import {
+ configureTestBed,
+ FixtureHelper,
+ FormHelper,
+ PrometheusHelper
+} from '~/testing/unit-test-helper';
+import { SilenceFormComponent } from './silence-form.component';
+
+describe('SilenceFormComponent', () => {
+ // SilenceFormComponent specific
+ let component: SilenceFormComponent;
+ let fixture: ComponentFixture<SilenceFormComponent>;
+ let form: CdFormGroup;
+ // Spied on
+ let prometheusService: PrometheusService;
+ let authStorageService: AuthStorageService;
+ let notificationService: NotificationService;
+ let router: Router;
+ // Spies
+ let rulesSpy: jasmine.Spy;
+ let ifPrometheusSpy: jasmine.Spy;
+ // Helper
+ let prometheus: PrometheusHelper;
+ let formHelper: FormHelper;
+ let fixtureH: FixtureHelper;
+ let params: Record<string, any>;
+ // Date mocking related
+ const baseTime = '2022-02-22 00:00';
+ const beginningDate = '2022-02-22T00:00:12.35';
+ let prometheusPermissions: Permission;
+
+ const routes: Routes = [{ path: '404', component: ErrorComponent }];
+ configureTestBed({
+ declarations: [ErrorComponent, SilenceFormComponent],
+ imports: [
+ HttpClientTestingModule,
+ RouterTestingModule.withRoutes(routes),
+ SharedModule,
+ ToastrModule.forRoot(),
+ NgbTooltipModule,
+ NgbPopoverModule,
+ ReactiveFormsModule
+ ],
+ providers: [
+ {
+ provide: ActivatedRoute,
+ useValue: { params: { subscribe: (fn: Function) => fn(params) } }
+ }
+ ]
+ });
+
+ const createMatcher = (name: string, value: any, isRegex: boolean) => ({ name, value, isRegex });
+
+ const addMatcher = (name: string, value: any, isRegex: boolean) =>
+ component['setMatcher'](createMatcher(name, value, isRegex));
+
+ const callInit = () =>
+ fixture.ngZone.run(() => {
+ component['init']();
+ });
+
+ const changeAction = (action: string) => {
+ const modes = {
+ add: '/monitoring/silences/add',
+ alertAdd: '/monitoring/silences/add/alert0',
+ recreate: '/monitoring/silences/recreate/someExpiredId',
+ edit: '/monitoring/silences/edit/someNotExpiredId'
+ };
+ Object.defineProperty(router, 'url', { value: modes[action] });
+ callInit();
+ };
+
+ beforeEach(() => {
+ params = {};
+ spyOn(Date, 'now').and.returnValue(new Date(beginningDate));
+
+ prometheus = new PrometheusHelper();
+ prometheusService = TestBed.inject(PrometheusService);
+ spyOn(prometheusService, 'getAlerts').and.callFake(() => {
+ const name = _.split(router.url, '/').pop();
+ return of([prometheus.createAlert(name)]);
+ });
+ ifPrometheusSpy = spyOn(prometheusService, 'ifPrometheusConfigured').and.callFake((fn) => fn());
+ rulesSpy = spyOn(prometheusService, 'getRules').and.callFake(() =>
+ of({
+ groups: [
+ {
+ file: '',
+ interval: 0,
+ name: '',
+ rules: [
+ prometheus.createRule('alert0', 'someSeverity', [prometheus.createAlert('alert0')]),
+ prometheus.createRule('alert1', 'someSeverity', []),
+ prometheus.createRule('alert2', 'someOtherSeverity', [
+ prometheus.createAlert('alert2')
+ ])
+ ]
+ }
+ ]
+ })
+ );
+
+ router = TestBed.inject(Router);
+
+ notificationService = TestBed.inject(NotificationService);
+ spyOn(notificationService, 'show').and.stub();
+
+ authStorageService = TestBed.inject(AuthStorageService);
+ spyOn(authStorageService, 'getUsername').and.returnValue('someUser');
+
+ spyOn(authStorageService, 'getPermissions').and.callFake(() => ({
+ prometheus: prometheusPermissions
+ }));
+ prometheusPermissions = new Permission(['update', 'delete', 'read', 'create']);
+ fixture = TestBed.createComponent(SilenceFormComponent);
+ fixtureH = new FixtureHelper(fixture);
+ component = fixture.componentInstance;
+ form = component.form;
+ formHelper = new FormHelper(form);
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ expect(_.isArray(component.rules)).toBeTruthy();
+ });
+
+ it('should have set the logged in user name as creator', () => {
+ expect(component.form.getValue('createdBy')).toBe('someUser');
+ });
+
+ it('should call disablePrometheusConfig on error calling getRules', () => {
+ spyOn(prometheusService, 'disablePrometheusConfig');
+ rulesSpy.and.callFake(() => throwError({}));
+ callInit();
+ expect(component.rules).toEqual([]);
+ expect(prometheusService.disablePrometheusConfig).toHaveBeenCalled();
+ });
+
+ it('should remind user if prometheus is not set when it is not configured', () => {
+ ifPrometheusSpy.and.callFake((_x: any, fn: Function) => fn());
+ callInit();
+ expect(component.rules).toEqual([]);
+ expect(notificationService.show).toHaveBeenCalledWith(
+ NotificationType.info,
+ 'Please add your Prometheus host to the dashboard configuration and refresh the page',
+ undefined,
+ undefined,
+ 'Prometheus'
+ );
+ });
+
+ describe('throw error for not allowed users', () => {
+ let navigateSpy: jasmine.Spy;
+
+ const expectError = (action: string, redirected: boolean) => {
+ Object.defineProperty(router, 'url', { value: action });
+ if (redirected) {
+ expect(() => callInit()).toThrowError(DashboardNotFoundError);
+ } else {
+ expect(() => callInit()).not.toThrowError();
+ }
+ navigateSpy.calls.reset();
+ };
+
+ beforeEach(() => {
+ navigateSpy = spyOn(router, 'navigate').and.stub();
+ });
+
+ it('should throw error if not allowed', () => {
+ prometheusPermissions = new Permission(['delete', 'read']);
+ expectError('add', true);
+ expectError('alertAdd', true);
+ });
+
+ it('should throw error if user does not have minimum permissions to create silences', () => {
+ prometheusPermissions = new Permission(['update', 'delete', 'read']);
+ expectError('add', true);
+ prometheusPermissions = new Permission(['update', 'delete', 'create']);
+ expectError('recreate', true);
+ });
+
+ it('should throw error if user does not have minimum permissions to update silences', () => {
+ prometheusPermissions = new Permission(['delete', 'read']);
+ expectError('edit', true);
+ prometheusPermissions = new Permission(['create', 'delete', 'update']);
+ expectError('edit', true);
+ });
+
+ it('does not throw error if user has minimum permissions to create silences', () => {
+ prometheusPermissions = new Permission(['create', 'read']);
+ expectError('add', false);
+ expectError('alertAdd', false);
+ expectError('recreate', false);
+ });
+
+ it('does not throw error if user has minimum permissions to update silences', () => {
+ prometheusPermissions = new Permission(['read', 'create']);
+ expectError('edit', false);
+ });
+ });
+
+ describe('choose the right action', () => {
+ const expectMode = (routerMode: string, edit: boolean, recreate: boolean, action: string) => {
+ changeAction(routerMode);
+ expect(component.recreate).toBe(recreate);
+ expect(component.edit).toBe(edit);
+ expect(component.action).toBe(action);
+ };
+
+ beforeEach(() => {
+ spyOn(prometheusService, 'getSilences').and.callFake(() => {
+ const id = _.split(router.url, '/').pop();
+ return of([prometheus.createSilence(id)]);
+ });
+ });
+
+ it('should have no special action activate by default', () => {
+ expectMode('add', false, false, 'Create');
+ expect(prometheusService.getSilences).not.toHaveBeenCalled();
+ expect(component.form.value).toEqual({
+ comment: null,
+ createdBy: 'someUser',
+ duration: '2h',
+ startsAt: baseTime,
+ endsAt: '2022-02-22 02:00'
+ });
+ });
+
+ it('should be in edit action if route includes edit', () => {
+ params = { id: 'someNotExpiredId' };
+ expectMode('edit', true, false, 'Edit');
+ expect(prometheusService.getSilences).toHaveBeenCalled();
+ expect(component.form.value).toEqual({
+ comment: `A comment for ${params.id}`,
+ createdBy: `Creator of ${params.id}`,
+ duration: '1d',
+ startsAt: '2022-02-22 22:22',
+ endsAt: '2022-02-23 22:22'
+ });
+ expect(component.matchers).toEqual([createMatcher('job', 'someJob', true)]);
+ });
+
+ it('should be in recreation action if route includes recreate', () => {
+ params = { id: 'someExpiredId' };
+ expectMode('recreate', false, true, 'Recreate');
+ expect(prometheusService.getSilences).toHaveBeenCalled();
+ expect(component.form.value).toEqual({
+ comment: `A comment for ${params.id}`,
+ createdBy: `Creator of ${params.id}`,
+ duration: '2h',
+ startsAt: baseTime,
+ endsAt: '2022-02-22 02:00'
+ });
+ expect(component.matchers).toEqual([createMatcher('job', 'someJob', true)]);
+ });
+
+ it('adds matchers based on the label object of the alert with the given id', () => {
+ params = { id: 'alert0' };
+ expectMode('alertAdd', false, false, 'Create');
+ expect(prometheusService.getSilences).not.toHaveBeenCalled();
+ expect(prometheusService.getAlerts).toHaveBeenCalled();
+ expect(component.matchers).toEqual([
+ createMatcher('alertname', 'alert0', false),
+ createMatcher('instance', 'someInstance', false),
+ createMatcher('job', 'someJob', false),
+ createMatcher('severity', 'someSeverity', false)
+ ]);
+ expect(component.matcherMatch).toEqual({
+ cssClass: 'has-success',
+ status: 'Matches 1 rule with 1 active alert.'
+ });
+ });
+ });
+
+ describe('time', () => {
+ const changeEndDate = (text: string) => component.form.patchValue({ endsAt: text });
+ const changeStartDate = (text: string) => component.form.patchValue({ startsAt: text });
+
+ it('have all dates set at beginning', () => {
+ expect(form.getValue('startsAt')).toEqual(baseTime);
+ expect(form.getValue('duration')).toBe('2h');
+ expect(form.getValue('endsAt')).toEqual('2022-02-22 02:00');
+ });
+
+ describe('on start date change', () => {
+ it('changes end date on start date change if it exceeds it', fakeAsync(() => {
+ changeStartDate('2022-02-28 04:05');
+ expect(form.getValue('duration')).toEqual('2h');
+ expect(form.getValue('endsAt')).toEqual('2022-02-28 06:05');
+
+ changeStartDate('2022-12-31 22:00');
+ expect(form.getValue('duration')).toEqual('2h');
+ expect(form.getValue('endsAt')).toEqual('2023-01-01 00:00');
+ }));
+
+ it('changes duration if start date does not exceed end date ', fakeAsync(() => {
+ changeStartDate('2022-02-22 00:45');
+ expect(form.getValue('duration')).toEqual('1h 15m');
+ expect(form.getValue('endsAt')).toEqual('2022-02-22 02:00');
+ }));
+
+ it('should raise invalid start date error', fakeAsync(() => {
+ changeStartDate('No valid date');
+ formHelper.expectError('startsAt', 'format');
+ expect(form.getValue('startsAt').toString()).toBe('No valid date');
+ expect(form.getValue('endsAt')).toEqual('2022-02-22 02:00');
+ }));
+ });
+
+ describe('on duration change', () => {
+ it('changes end date if duration is changed', () => {
+ formHelper.setValue('duration', '15m');
+ expect(form.getValue('endsAt')).toEqual('2022-02-22 00:15');
+ formHelper.setValue('duration', '5d 23h');
+ expect(form.getValue('endsAt')).toEqual('2022-02-27 23:00');
+ });
+ });
+
+ describe('on end date change', () => {
+ it('changes duration on end date change if it exceeds start date', fakeAsync(() => {
+ changeEndDate('2022-02-28 04:05');
+ expect(form.getValue('duration')).toEqual('6d 4h 5m');
+ expect(form.getValue('startsAt')).toEqual(baseTime);
+ }));
+
+ it('changes start date if end date happens before it', fakeAsync(() => {
+ changeEndDate('2022-02-21 02:00');
+ expect(form.getValue('duration')).toEqual('2h');
+ expect(form.getValue('startsAt')).toEqual('2022-02-21 00:00');
+ }));
+
+ it('should raise invalid end date error', fakeAsync(() => {
+ changeEndDate('No valid date');
+ formHelper.expectError('endsAt', 'format');
+ expect(form.getValue('endsAt').toString()).toBe('No valid date');
+ expect(form.getValue('startsAt')).toEqual(baseTime);
+ }));
+ });
+ });
+
+ it('should have a creator field', () => {
+ formHelper.expectValid('createdBy');
+ formHelper.expectErrorChange('createdBy', '', 'required');
+ formHelper.expectValidChange('createdBy', 'Mighty FSM');
+ });
+
+ it('should have a comment field', () => {
+ formHelper.expectError('comment', 'required');
+ formHelper.expectValidChange('comment', 'A pretty long comment');
+ });
+
+ it('should be a valid form if all inputs are filled and at least one matcher was added', () => {
+ expect(form.valid).toBeFalsy();
+ formHelper.expectValidChange('createdBy', 'Mighty FSM');
+ formHelper.expectValidChange('comment', 'A pretty long comment');
+ addMatcher('job', 'someJob', false);
+ expect(form.valid).toBeTruthy();
+ });
+
+ describe('matchers', () => {
+ const expectMatch = (helpText: string) => {
+ expect(fixtureH.getText('#match-state')).toBe(helpText);
+ };
+
+ it('should show the add matcher button', () => {
+ fixtureH.expectElementVisible('#add-matcher', true);
+ fixtureH.expectIdElementsVisible(
+ [
+ 'matcher-name-0',
+ 'matcher-value-0',
+ 'matcher-isRegex-0',
+ 'matcher-edit-0',
+ 'matcher-delete-0'
+ ],
+ false
+ );
+ expectMatch(null);
+ });
+
+ it('should show added matcher', () => {
+ addMatcher('job', 'someJob', true);
+ fixtureH.expectIdElementsVisible(
+ [
+ 'matcher-name-0',
+ 'matcher-value-0',
+ 'matcher-isRegex-0',
+ 'matcher-edit-0',
+ 'matcher-delete-0'
+ ],
+ true
+ );
+ expectMatch(null);
+ });
+
+ it('should show multiple matchers', () => {
+ addMatcher('severity', 'someSeverity', false);
+ addMatcher('alertname', 'alert0', false);
+ fixtureH.expectIdElementsVisible(
+ [
+ 'matcher-name-0',
+ 'matcher-value-0',
+ 'matcher-isRegex-0',
+ 'matcher-edit-0',
+ 'matcher-delete-0',
+ 'matcher-name-1',
+ 'matcher-value-1',
+ 'matcher-isRegex-1',
+ 'matcher-edit-1',
+ 'matcher-delete-1'
+ ],
+ true
+ );
+ expectMatch('Matches 1 rule with 1 active alert.');
+ });
+
+ it('should show the right matcher values', () => {
+ addMatcher('alertname', 'alert.*', true);
+ addMatcher('job', 'someJob', false);
+ fixture.detectChanges();
+ fixtureH.expectFormFieldToBe('#matcher-name-0', 'alertname');
+ fixtureH.expectFormFieldToBe('#matcher-value-0', 'alert.*');
+ fixtureH.expectFormFieldToBe('#matcher-isRegex-0', 'true');
+ fixtureH.expectFormFieldToBe('#matcher-isRegex-1', 'false');
+ expectMatch(null);
+ });
+
+ it('should be able to edit a matcher', () => {
+ addMatcher('alertname', 'alert.*', true);
+ expectMatch(null);
+
+ const modalService = TestBed.inject(ModalService);
+ spyOn(modalService, 'show').and.callFake(() => {
+ return {
+ componentInstance: {
+ preFillControls: (matcher: any) => {
+ expect(matcher).toBe(component.matchers[0]);
+ },
+ submitAction: of({ name: 'alertname', value: 'alert0', isRegex: false })
+ }
+ };
+ });
+ fixtureH.clickElement('#matcher-edit-0');
+
+ fixtureH.expectFormFieldToBe('#matcher-name-0', 'alertname');
+ fixtureH.expectFormFieldToBe('#matcher-value-0', 'alert0');
+ fixtureH.expectFormFieldToBe('#matcher-isRegex-0', 'false');
+ expectMatch('Matches 1 rule with 1 active alert.');
+ });
+
+ it('should be able to remove a matcher', () => {
+ addMatcher('alertname', 'alert0', false);
+ expectMatch('Matches 1 rule with 1 active alert.');
+ fixtureH.clickElement('#matcher-delete-0');
+ expect(component.matchers).toEqual([]);
+ fixtureH.expectIdElementsVisible(
+ ['matcher-name-0', 'matcher-value-0', 'matcher-isRegex-0'],
+ false
+ );
+ expectMatch(null);
+ });
+
+ it('should be able to remove a matcher and update the matcher text', () => {
+ addMatcher('alertname', 'alert0', false);
+ addMatcher('alertname', 'alert1', false);
+ expectMatch('Your matcher seems to match no currently defined rule or active alert.');
+ fixtureH.clickElement('#matcher-delete-1');
+ expectMatch('Matches 1 rule with 1 active alert.');
+ });
+
+ it('should show form as invalid if no matcher is set', () => {
+ expect(form.errors).toEqual({ matcherRequired: true });
+ });
+
+ it('should show form as valid if matcher was added', () => {
+ addMatcher('some name', 'some value', true);
+ expect(form.errors).toEqual(null);
+ });
+ });
+
+ describe('submit tests', () => {
+ const endsAt = '2022-02-22 02:00';
+ let silence: AlertmanagerSilence;
+ const silenceId = '50M3-10N6-1D';
+
+ const expectSuccessNotification = (titleStartsWith: string) =>
+ expect(notificationService.show).toHaveBeenCalledWith(
+ NotificationType.success,
+ `${titleStartsWith} silence ${silenceId}`,
+ undefined,
+ undefined,
+ 'Prometheus'
+ );
+
+ const fillAndSubmit = () => {
+ ['createdBy', 'comment'].forEach((attr) => {
+ formHelper.setValue(attr, silence[attr]);
+ });
+ silence.matchers.forEach((matcher) =>
+ addMatcher(matcher.name, matcher.value, matcher.isRegex)
+ );
+ component.submit();
+ };
+
+ beforeEach(() => {
+ spyOn(prometheusService, 'setSilence').and.callFake(() => of({ body: { silenceId } }));
+ spyOn(router, 'navigate').and.stub();
+ silence = {
+ createdBy: 'some creator',
+ comment: 'some comment',
+ startsAt: moment(baseTime).toISOString(),
+ endsAt: moment(endsAt).toISOString(),
+ matchers: [
+ {
+ name: 'some attribute name',
+ value: 'some value',
+ isRegex: false
+ },
+ {
+ name: 'job',
+ value: 'node-exporter',
+ isRegex: false
+ },
+ {
+ name: 'instance',
+ value: 'localhost:9100',
+ isRegex: false
+ },
+ {
+ name: 'alertname',
+ value: 'load_0',
+ isRegex: false
+ }
+ ]
+ };
+ });
+
+ // it('should not create a silence if the form is invalid', () => {
+ // component.submit();
+ // expect(notificationService.show).not.toHaveBeenCalled();
+ // expect(form.valid).toBeFalsy();
+ // expect(prometheusService.setSilence).not.toHaveBeenCalledWith(silence);
+ // expect(router.navigate).not.toHaveBeenCalled();
+ // });
+
+ // it('should route back to previous tab on success', () => {
+ // fillAndSubmit();
+ // expect(form.valid).toBeTruthy();
+ // expect(router.navigate).toHaveBeenCalledWith(['/monitoring'], { fragment: 'silences' });
+ // });
+
+ it('should create a silence', () => {
+ fillAndSubmit();
+ expect(prometheusService.setSilence).toHaveBeenCalledWith(silence);
+ expectSuccessNotification('Created');
+ });
+
+ it('should recreate a silence', () => {
+ component.recreate = true;
+ component.id = 'recreateId';
+ fillAndSubmit();
+ expect(prometheusService.setSilence).toHaveBeenCalledWith(silence);
+ expectSuccessNotification('Recreated');
+ });
+
+ it('should edit a silence', () => {
+ component.edit = true;
+ component.id = 'editId';
+ silence.id = component.id;
+ fillAndSubmit();
+ expect(prometheusService.setSilence).toHaveBeenCalledWith(silence);
+ expectSuccessNotification('Edited');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts
new file mode 100644
index 000000000..b698e4958
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts
@@ -0,0 +1,340 @@
+import { Component } from '@angular/core';
+import { Validators } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+
+import _ from 'lodash';
+import moment from 'moment';
+
+import { DashboardNotFoundError } from '~/app/core/error/error';
+import { PrometheusService } from '~/app/shared/api/prometheus.service';
+import { ActionLabelsI18n, SucceededActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import {
+ AlertmanagerSilence,
+ AlertmanagerSilenceMatcher,
+ AlertmanagerSilenceMatcherMatch
+} from '~/app/shared/models/alertmanager-silence';
+import { Permission } from '~/app/shared/models/permissions';
+import { AlertmanagerAlert, PrometheusRule } from '~/app/shared/models/prometheus-alerts';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { PrometheusSilenceMatcherService } from '~/app/shared/services/prometheus-silence-matcher.service';
+import { TimeDiffService } from '~/app/shared/services/time-diff.service';
+import { SilenceMatcherModalComponent } from '../silence-matcher-modal/silence-matcher-modal.component';
+
+@Component({
+ selector: 'cd-prometheus-form',
+ templateUrl: './silence-form.component.html',
+ styleUrls: ['./silence-form.component.scss']
+})
+export class SilenceFormComponent {
+ icons = Icons;
+ permission: Permission;
+ form: CdFormGroup;
+ rules: PrometheusRule[];
+
+ recreate = false;
+ edit = false;
+ id: string;
+
+ action: string;
+ resource = $localize`silence`;
+
+ matchers: AlertmanagerSilenceMatcher[] = [];
+ matcherMatch: AlertmanagerSilenceMatcherMatch = undefined;
+ matcherConfig = [
+ {
+ tooltip: $localize`Attribute name`,
+ icon: this.icons.paragraph,
+ attribute: 'name'
+ },
+ {
+ tooltip: $localize`Value`,
+ icon: this.icons.terminal,
+ attribute: 'value'
+ },
+ {
+ tooltip: $localize`Regular expression`,
+ icon: this.icons.magic,
+ attribute: 'isRegex'
+ }
+ ];
+
+ datetimeFormat = 'YYYY-MM-DD HH:mm';
+
+ constructor(
+ private router: Router,
+ private authStorageService: AuthStorageService,
+ private formBuilder: CdFormBuilder,
+ private prometheusService: PrometheusService,
+ private notificationService: NotificationService,
+ private route: ActivatedRoute,
+ private timeDiff: TimeDiffService,
+ private modalService: ModalService,
+ private silenceMatcher: PrometheusSilenceMatcherService,
+ private actionLabels: ActionLabelsI18n,
+ private succeededLabels: SucceededActionLabelsI18n
+ ) {
+ this.init();
+ }
+
+ private init() {
+ this.chooseMode();
+ this.authenticate();
+ this.createForm();
+ this.setupDates();
+ this.getData();
+ }
+
+ private chooseMode() {
+ this.edit = this.router.url.startsWith('/monitoring/silences/edit');
+ this.recreate = this.router.url.startsWith('/monitoring/silences/recreate');
+ if (this.edit) {
+ this.action = this.actionLabels.EDIT;
+ } else if (this.recreate) {
+ this.action = this.actionLabels.RECREATE;
+ } else {
+ this.action = this.actionLabels.CREATE;
+ }
+ }
+
+ private authenticate() {
+ this.permission = this.authStorageService.getPermissions().prometheus;
+ const allowed =
+ this.permission.read && (this.edit ? this.permission.update : this.permission.create);
+ if (!allowed) {
+ throw new DashboardNotFoundError();
+ }
+ }
+
+ private createForm() {
+ const formatValidator = CdValidators.custom('format', (expiresAt: string) => {
+ const result = expiresAt === '' || moment(expiresAt, this.datetimeFormat).isValid();
+ return !result;
+ });
+ this.form = this.formBuilder.group(
+ {
+ startsAt: ['', [Validators.required, formatValidator]],
+ duration: ['2h', [Validators.min(1)]],
+ endsAt: ['', [Validators.required, formatValidator]],
+ createdBy: [this.authStorageService.getUsername(), [Validators.required]],
+ comment: [null, [Validators.required]]
+ },
+ {
+ validators: CdValidators.custom('matcherRequired', () => this.matchers.length === 0)
+ }
+ );
+ }
+
+ private setupDates() {
+ const now = moment().format(this.datetimeFormat);
+ this.form.silentSet('startsAt', now);
+ this.updateDate();
+ this.subscribeDateChanges();
+ }
+
+ private updateDate(updateStartDate?: boolean) {
+ const date = moment(
+ this.form.getValue(updateStartDate ? 'endsAt' : 'startsAt'),
+ this.datetimeFormat
+ ).toDate();
+ const next = this.timeDiff.calculateDate(date, this.form.getValue('duration'), updateStartDate);
+ if (next) {
+ const nextDate = moment(next).format(this.datetimeFormat);
+ this.form.silentSet(updateStartDate ? 'startsAt' : 'endsAt', nextDate);
+ }
+ }
+
+ private subscribeDateChanges() {
+ this.form.get('startsAt').valueChanges.subscribe(() => {
+ this.onDateChange();
+ });
+ this.form.get('duration').valueChanges.subscribe(() => {
+ this.updateDate();
+ });
+ this.form.get('endsAt').valueChanges.subscribe(() => {
+ this.onDateChange(true);
+ });
+ }
+
+ private onDateChange(updateStartDate?: boolean) {
+ const startsAt = moment(this.form.getValue('startsAt'), this.datetimeFormat);
+ const endsAt = moment(this.form.getValue('endsAt'), this.datetimeFormat);
+ if (startsAt.isBefore(endsAt)) {
+ this.updateDuration();
+ } else {
+ this.updateDate(updateStartDate);
+ }
+ }
+
+ private updateDuration() {
+ const startsAt = moment(this.form.getValue('startsAt'), this.datetimeFormat).toDate();
+ const endsAt = moment(this.form.getValue('endsAt'), this.datetimeFormat).toDate();
+ this.form.silentSet('duration', this.timeDiff.calculateDuration(startsAt, endsAt));
+ }
+
+ private getData() {
+ this.getRules();
+ this.getModeSpecificData();
+ }
+
+ private getRules() {
+ this.prometheusService.ifPrometheusConfigured(
+ () =>
+ this.prometheusService.getRules().subscribe(
+ (groups) => {
+ this.rules = groups['groups'].reduce(
+ (acc, group) => _.concat<PrometheusRule>(acc, group.rules),
+ []
+ );
+ },
+ () => {
+ this.prometheusService.disablePrometheusConfig();
+ this.rules = [];
+ }
+ ),
+ () => {
+ this.rules = [];
+ this.notificationService.show(
+ NotificationType.info,
+ $localize`Please add your Prometheus host to the dashboard configuration and refresh the page`,
+ undefined,
+ undefined,
+ 'Prometheus'
+ );
+ }
+ );
+ }
+
+ private getModeSpecificData() {
+ this.route.params.subscribe((params: { id: string }) => {
+ if (!params.id) {
+ return;
+ }
+ if (this.edit || this.recreate) {
+ this.prometheusService.getSilences().subscribe((silences) => {
+ const silence = _.find(silences, ['id', params.id]);
+ if (!_.isUndefined(silence)) {
+ this.fillFormWithSilence(silence);
+ }
+ });
+ } else {
+ this.prometheusService.getAlerts().subscribe((alerts) => {
+ const alert = _.find(alerts, ['fingerprint', params.id]);
+ if (!_.isUndefined(alert)) {
+ this.fillFormByAlert(alert);
+ }
+ });
+ }
+ });
+ }
+
+ private fillFormWithSilence(silence: AlertmanagerSilence) {
+ this.id = silence.id;
+ if (this.edit) {
+ ['startsAt', 'endsAt'].forEach((attr) =>
+ this.form.silentSet(attr, moment(silence[attr]).format(this.datetimeFormat))
+ );
+ this.updateDuration();
+ }
+ ['createdBy', 'comment'].forEach((attr) => this.form.silentSet(attr, silence[attr]));
+ this.matchers = silence.matchers;
+ this.validateMatchers();
+ }
+
+ private validateMatchers() {
+ if (!this.rules) {
+ window.setTimeout(() => this.validateMatchers(), 100);
+ return;
+ }
+ this.matcherMatch = this.silenceMatcher.multiMatch(this.matchers, this.rules);
+ this.form.markAsDirty();
+ this.form.updateValueAndValidity();
+ }
+
+ private fillFormByAlert(alert: AlertmanagerAlert) {
+ const labels = alert.labels;
+ Object.keys(labels).forEach((key) =>
+ this.setMatcher({
+ name: key,
+ value: labels[key],
+ isRegex: false
+ })
+ );
+ }
+
+ private setMatcher(matcher: AlertmanagerSilenceMatcher, index?: number) {
+ if (_.isNumber(index)) {
+ this.matchers[index] = matcher;
+ } else {
+ this.matchers.push(matcher);
+ }
+ this.validateMatchers();
+ }
+
+ showMatcherModal(index?: number) {
+ const modalRef = this.modalService.show(SilenceMatcherModalComponent);
+ const modalComponent = modalRef.componentInstance as SilenceMatcherModalComponent;
+ modalComponent.rules = this.rules;
+ if (_.isNumber(index)) {
+ modalComponent.editMode = true;
+ modalComponent.preFillControls(this.matchers[index]);
+ }
+ modalComponent.submitAction.subscribe((matcher: AlertmanagerSilenceMatcher) => {
+ this.setMatcher(matcher, index);
+ });
+ }
+
+ deleteMatcher(index: number) {
+ this.matchers.splice(index, 1);
+ this.validateMatchers();
+ }
+
+ submit() {
+ if (this.form.invalid) {
+ return;
+ }
+ this.prometheusService.setSilence(this.getSubmitData()).subscribe(
+ (resp) => {
+ this.router.navigate(['/monitoring/silences']);
+ this.notificationService.show(
+ NotificationType.success,
+ this.getNotificationTile(resp.body['silenceId']),
+ undefined,
+ undefined,
+ 'Prometheus'
+ );
+ },
+ () => this.form.setErrors({ cdSubmitButton: true })
+ );
+ }
+
+ private getSubmitData(): AlertmanagerSilence {
+ const payload = this.form.value;
+ delete payload.duration;
+ payload.startsAt = moment(payload.startsAt, this.datetimeFormat).toISOString();
+ payload.endsAt = moment(payload.endsAt, this.datetimeFormat).toISOString();
+ payload.matchers = this.matchers;
+ if (this.edit) {
+ payload.id = this.id;
+ }
+ return payload;
+ }
+
+ private getNotificationTile(id: string) {
+ let action;
+ if (this.edit) {
+ action = this.succeededLabels.EDITED;
+ } else if (this.recreate) {
+ action = this.succeededLabels.RECREATED;
+ } else {
+ action = this.succeededLabels.CREATED;
+ }
+ return `${action} ${this.resource} ${id}`;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html
new file mode 100644
index 000000000..2997ff373
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html
@@ -0,0 +1,34 @@
+<cd-prometheus-tabs></cd-prometheus-tabs>
+
+<cd-alert-panel *ngIf="!isAlertmanagerConfigured"
+ type="info"
+ i18n>To enable Silences, please provide the URL to
+ the API of the Prometheus' Alertmanager as described in the
+ <cd-doc section="prometheus"></cd-doc>.</cd-alert-panel>
+
+<cd-table *ngIf="isAlertmanagerConfigured"
+ [data]="silences"
+ [columns]="columns"
+ [forceIdentifier]="true"
+ [customCss]="customCss"
+ [sorts]="sorts"
+ selectionType="single"
+ [hasDetails]="true"
+ (setExpandedRow)="setExpandedRow($event)"
+ (fetchData)="refresh()"
+ (updateSelection)="updateSelection($event)">
+ <cd-table-actions class="table-actions"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ <cd-table-key-value cdTableDetail
+ *ngIf="expandedRow"
+ [renderObjects]="true"
+ [hideEmpty]="true"
+ [appendParentKey]="false"
+ [data]="expandedRow"
+ [customCss]="customCss"
+ [autoReload]="false">
+ </cd-table-key-value>
+</cd-table>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.spec.ts
new file mode 100644
index 000000000..cc4b76c32
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.spec.ts
@@ -0,0 +1,140 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { PrometheusService } from '~/app/shared/api/prometheus.service';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, PermissionHelper } from '~/testing/unit-test-helper';
+import { PrometheusTabsComponent } from '../prometheus-tabs/prometheus-tabs.component';
+import { SilenceListComponent } from './silence-list.component';
+
+describe('SilenceListComponent', () => {
+ let component: SilenceListComponent;
+ let fixture: ComponentFixture<SilenceListComponent>;
+ let prometheusService: PrometheusService;
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ SharedModule,
+ ToastrModule.forRoot(),
+ RouterTestingModule,
+ HttpClientTestingModule,
+ NgbNavModule
+ ],
+ declarations: [SilenceListComponent, PrometheusTabsComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(SilenceListComponent);
+ component = fixture.componentInstance;
+ prometheusService = TestBed.inject(PrometheusService);
+ });
+
+ it('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+
+ it('should test all TableActions combinations', () => {
+ const permissionHelper: PermissionHelper = new PermissionHelper(component.permission);
+ const tableActions: TableActionsComponent = permissionHelper.setPermissionsAndGetActions(
+ component.tableActions
+ );
+
+ expect(tableActions).toEqual({
+ 'create,update,delete': {
+ actions: ['Create', 'Recreate', 'Edit', 'Expire'],
+ primary: { multiple: 'Create', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,update': {
+ actions: ['Create', 'Recreate', 'Edit'],
+ primary: { multiple: 'Create', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,delete': {
+ actions: ['Create', 'Recreate', 'Expire'],
+ primary: { multiple: 'Create', executing: 'Expire', single: 'Expire', no: 'Create' }
+ },
+ create: {
+ actions: ['Create', 'Recreate'],
+ primary: { multiple: 'Create', executing: 'Create', single: 'Create', no: 'Create' }
+ },
+ 'update,delete': {
+ actions: ['Edit', 'Expire'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ update: {
+ actions: ['Edit'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ delete: {
+ actions: ['Expire'],
+ primary: { multiple: 'Expire', executing: 'Expire', single: 'Expire', no: 'Expire' }
+ },
+ 'no-permissions': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ }
+ });
+ });
+
+ describe('expire silence', () => {
+ const setSelectedSilence = (silenceName: string) =>
+ (component.selection.selected = [{ id: silenceName }]);
+
+ const expireSilence = () => {
+ component.expireSilence();
+ const deletion: CriticalConfirmationModalComponent = component.modalRef.componentInstance;
+ // deletion.modalRef = new BsModalRef();
+ deletion.ngOnInit();
+ deletion.callSubmitAction();
+ };
+
+ const expectSilenceToExpire = (silenceId: string) => {
+ setSelectedSilence(silenceId);
+ expireSilence();
+ expect(prometheusService.expireSilence).toHaveBeenCalledWith(silenceId);
+ };
+
+ beforeEach(() => {
+ const mockObservable = () => of([]);
+ spyOn(component, 'refresh').and.callFake(mockObservable);
+ spyOn(prometheusService, 'expireSilence').and.callFake(mockObservable);
+ spyOn(TestBed.inject(ModalService), 'show').and.callFake((deletionClass, config) => {
+ return {
+ componentInstance: Object.assign(new deletionClass(), config)
+ };
+ });
+ });
+
+ it('should expire a silence', () => {
+ const notificationService = TestBed.inject(NotificationService);
+ spyOn(notificationService, 'show').and.stub();
+ expectSilenceToExpire('someSilenceId');
+ expect(notificationService.show).toHaveBeenCalledWith(
+ NotificationType.success,
+ 'Expired Silence someSilenceId',
+ undefined,
+ undefined,
+ 'Prometheus'
+ );
+ });
+
+ it('should refresh after expiring a silence', () => {
+ expectSilenceToExpire('someId');
+ expect(component.refresh).toHaveBeenCalledTimes(1);
+ expectSilenceToExpire('someOtherId');
+ expect(component.refresh).toHaveBeenCalledTimes(2);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts
new file mode 100644
index 000000000..c351a64e5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts
@@ -0,0 +1,191 @@
+import { Component, Inject } from '@angular/core';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { SortDirection, SortPropDir } from '@swimlane/ngx-datatable';
+import { Observable, Subscriber } from 'rxjs';
+
+import { PrometheusService } from '~/app/shared/api/prometheus.service';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { ActionLabelsI18n, SucceededActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { AlertmanagerSilence } from '~/app/shared/models/alertmanager-silence';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { Permission } from '~/app/shared/models/permissions';
+import { CdDatePipe } from '~/app/shared/pipes/cd-date.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { URLBuilderService } from '~/app/shared/services/url-builder.service';
+import { PrometheusListHelper } from '../prometheus-list-helper';
+
+const BASE_URL = 'monitoring/silences';
+
+@Component({
+ providers: [{ provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }],
+ selector: 'cd-silences-list',
+ templateUrl: './silence-list.component.html',
+ styleUrls: ['./silence-list.component.scss']
+})
+export class SilenceListComponent extends PrometheusListHelper {
+ silences: AlertmanagerSilence[] = [];
+ columns: CdTableColumn[];
+ tableActions: CdTableAction[];
+ permission: Permission;
+ selection = new CdTableSelection();
+ modalRef: NgbModalRef;
+ customCss = {
+ 'badge badge-danger': 'active',
+ 'badge badge-warning': 'pending',
+ 'badge badge-default': 'expired'
+ };
+ sorts: SortPropDir[] = [{ prop: 'endsAt', dir: SortDirection.desc }];
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private cdDatePipe: CdDatePipe,
+ private modalService: ModalService,
+ private notificationService: NotificationService,
+ private urlBuilder: URLBuilderService,
+ private actionLabels: ActionLabelsI18n,
+ private succeededLabels: SucceededActionLabelsI18n,
+ @Inject(PrometheusService) prometheusService: PrometheusService
+ ) {
+ super(prometheusService);
+ this.permission = this.authStorageService.getPermissions().prometheus;
+ const selectionExpired = (selection: CdTableSelection) =>
+ selection.first() && selection.first().status && selection.first().status.state === 'expired';
+ this.tableActions = [
+ {
+ permission: 'create',
+ icon: Icons.add,
+ routerLink: () => this.urlBuilder.getCreate(),
+ canBePrimary: (selection: CdTableSelection) => !selection.hasSingleSelection,
+ name: this.actionLabels.CREATE
+ },
+ {
+ permission: 'create',
+ canBePrimary: (selection: CdTableSelection) =>
+ selection.hasSingleSelection && selectionExpired(selection),
+ disable: (selection: CdTableSelection) =>
+ !selection.hasSingleSelection ||
+ selection.first().cdExecuting ||
+ (selection.first().cdExecuting && selectionExpired(selection)) ||
+ !selectionExpired(selection),
+ icon: Icons.copy,
+ routerLink: () => this.urlBuilder.getRecreate(this.selection.first().id),
+ name: this.actionLabels.RECREATE
+ },
+ {
+ permission: 'update',
+ icon: Icons.edit,
+ canBePrimary: (selection: CdTableSelection) =>
+ selection.hasSingleSelection && !selectionExpired(selection),
+ disable: (selection: CdTableSelection) =>
+ !selection.hasSingleSelection ||
+ selection.first().cdExecuting ||
+ (selection.first().cdExecuting && !selectionExpired(selection)) ||
+ selectionExpired(selection),
+ routerLink: () => this.urlBuilder.getEdit(this.selection.first().id),
+ name: this.actionLabels.EDIT
+ },
+ {
+ permission: 'delete',
+ icon: Icons.trash,
+ canBePrimary: (selection: CdTableSelection) =>
+ selection.hasSingleSelection && !selectionExpired(selection),
+ disable: (selection: CdTableSelection) =>
+ !selection.hasSingleSelection ||
+ selection.first().cdExecuting ||
+ selectionExpired(selection),
+ click: () => this.expireSilence(),
+ name: this.actionLabels.EXPIRE
+ }
+ ];
+ this.columns = [
+ {
+ name: $localize`ID`,
+ prop: 'id',
+ flexGrow: 3
+ },
+ {
+ name: $localize`Created by`,
+ prop: 'createdBy',
+ flexGrow: 2
+ },
+ {
+ name: $localize`Started`,
+ prop: 'startsAt',
+ pipe: this.cdDatePipe
+ },
+ {
+ name: $localize`Updated`,
+ prop: 'updatedAt',
+ pipe: this.cdDatePipe
+ },
+ {
+ name: $localize`Ends`,
+ prop: 'endsAt',
+ pipe: this.cdDatePipe
+ },
+ {
+ name: $localize`Status`,
+ prop: 'status.state',
+ cellTransformation: CellTemplate.classAdding
+ }
+ ];
+ }
+
+ refresh() {
+ this.prometheusService.ifAlertmanagerConfigured(() => {
+ this.prometheusService.getSilences().subscribe(
+ (silences) => {
+ this.silences = silences;
+ },
+ () => {
+ this.prometheusService.disableAlertmanagerConfig();
+ }
+ );
+ });
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ expireSilence() {
+ const id = this.selection.first().id;
+ const i18nSilence = $localize`Silence`;
+ const applicationName = 'Prometheus';
+ this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: i18nSilence,
+ itemNames: [id],
+ actionDescription: this.actionLabels.EXPIRE,
+ submitActionObservable: () =>
+ new Observable((observer: Subscriber<any>) => {
+ this.prometheusService.expireSilence(id).subscribe(
+ () => {
+ this.notificationService.show(
+ NotificationType.success,
+ `${this.succeededLabels.EXPIRED} ${i18nSilence} ${id}`,
+ undefined,
+ undefined,
+ applicationName
+ );
+ },
+ (resp) => {
+ resp['application'] = applicationName;
+ observer.error(resp);
+ },
+ () => {
+ observer.complete();
+ this.refresh();
+ }
+ );
+ })
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html
new file mode 100644
index 000000000..db89adc53
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html
@@ -0,0 +1,85 @@
+<cd-modal [modalRef]="activeModal">
+ <span class="modal-title"
+ i18n>{editMode, select, true {Edit} other {Add}} Matcher</span>
+
+ <ng-container class="modal-content">
+ <form class="form"
+ #formDir="ngForm"
+ [formGroup]="form"
+ novalidate>
+ <div class="modal-body">
+ <!-- Name -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="name"
+ i18n>Name</label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ id="name"
+ formControlName="name"
+ name="name">
+ <option [ngValue]="null"
+ i18n>-- Select an attribute to match against --</option>
+ <option *ngFor="let attribute of nameAttributes"
+ [value]="attribute">
+ {{ attribute }}
+ </option>
+ </select>
+ <span class="help-block"
+ *ngIf="form.showError('name', formDir, 'required')"
+ i18n>This field is required!</span>
+ </div>
+ </div>
+
+ <!-- Value -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="value"
+ i18n>Value</label>
+ <div class="cd-col-form-input">
+ <input id="value"
+ (focus)="valueFocus.next($any($event).target.value)"
+ (click)="valueClick.next($any($event).target.value)"
+ container="body"
+ class="form-control"
+ type="text"
+ [ngbTypeahead]="search"
+ formControlName="value">
+ <span *ngIf="form.showError('value', formDir, 'required')"
+ class="help-block"
+ i18n>This field is required!</span>
+ </div>
+ <div *ngIf="form.getValue('value') && !form.getValue('isRegex') && matcherMatch"
+ class="cd-col-form-offset {{matcherMatch.cssClass}}"
+ id="match-state">
+ <span class="text-muted {{matcherMatch.cssClass}}">
+ {{matcherMatch.status}}
+ </span>
+ </div>
+ </div>
+
+ <!-- isRegex -->
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ formControlName="isRegex"
+ name="is-regex"
+ id="is-regex">
+ <label for="is-regex"
+ class="custom-control-label"
+ i18n>Use regular expression</label>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="onSubmit()"
+ [form]="form"
+ [submitText]="getMode()"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.spec.ts
new file mode 100644
index 000000000..c9bfce9c1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.spec.ts
@@ -0,0 +1,209 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { of } from 'rxjs';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import {
+ configureTestBed,
+ FixtureHelper,
+ FormHelper,
+ PrometheusHelper
+} from '~/testing/unit-test-helper';
+import { SilenceMatcherModalComponent } from './silence-matcher-modal.component';
+
+describe('SilenceMatcherModalComponent', () => {
+ let component: SilenceMatcherModalComponent;
+ let fixture: ComponentFixture<SilenceMatcherModalComponent>;
+
+ let formH: FormHelper;
+ let fixtureH: FixtureHelper;
+ let prometheus: PrometheusHelper;
+
+ configureTestBed({
+ declarations: [SilenceMatcherModalComponent],
+ imports: [
+ HttpClientTestingModule,
+ SharedModule,
+ NgbTypeaheadModule,
+ RouterTestingModule,
+ ReactiveFormsModule
+ ],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(SilenceMatcherModalComponent);
+ component = fixture.componentInstance;
+
+ fixtureH = new FixtureHelper(fixture);
+ formH = new FormHelper(component.form);
+ prometheus = new PrometheusHelper();
+
+ component.rules = [
+ prometheus.createRule('alert0', 'someSeverity', [prometheus.createAlert('alert0')]),
+ prometheus.createRule('alert1', 'someSeverity', [])
+ ];
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should have a name field', () => {
+ formH.expectError('name', 'required');
+ formH.expectValidChange('name', 'alertname');
+ });
+
+ it('should only allow a specific set of name attributes', () => {
+ expect(component.nameAttributes).toEqual(['alertname', 'instance', 'job', 'severity']);
+ });
+
+ it('should autocomplete a list based on the set name', () => {
+ const expectations = {
+ alertname: ['alert0', 'alert1'],
+ instance: ['someInstance'],
+ job: ['someJob'],
+ severity: ['someSeverity']
+ };
+ Object.keys(expectations).forEach((key) => {
+ formH.setValue('name', key);
+ expect(component.possibleValues).toEqual(expectations[key]);
+ });
+ });
+
+ describe('test rule matching', () => {
+ const expectMatch = (name: string, value: string, helpText: string) => {
+ component.preFillControls({
+ name: name,
+ value: value,
+ isRegex: false
+ });
+ expect(fixtureH.getText('#match-state')).toBe(helpText);
+ };
+
+ it('should match no rule and no alert', () => {
+ expectMatch(
+ 'alertname',
+ 'alert',
+ 'Your matcher seems to match no currently defined rule or active alert.'
+ );
+ });
+
+ it('should match a rule with no alert', () => {
+ expectMatch('alertname', 'alert1', 'Matches 1 rule with no active alerts.');
+ });
+
+ it('should match a rule and an alert', () => {
+ expectMatch('alertname', 'alert0', 'Matches 1 rule with 1 active alert.');
+ });
+
+ it('should match multiple rules and an alert', () => {
+ expectMatch('severity', 'someSeverity', 'Matches 2 rules with 1 active alert.');
+ });
+
+ it('should match multiple rules and multiple alerts', () => {
+ component.rules[1].alerts.push(null);
+ expectMatch('severity', 'someSeverity', 'Matches 2 rules with 2 active alerts.');
+ });
+
+ it('should not show match-state if regex is checked', () => {
+ fixtureH.expectElementVisible('#match-state', false);
+ formH.setValue('name', 'severity');
+ formH.setValue('value', 'someSeverity');
+ fixtureH.expectElementVisible('#match-state', true);
+ formH.setValue('isRegex', true);
+ fixtureH.expectElementVisible('#match-state', false);
+ });
+ });
+
+ it('should only enable value field if name was set', () => {
+ const value = component.form.get('value');
+ expect(value.disabled).toBeTruthy();
+ formH.setValue('name', component.nameAttributes[0]);
+ expect(value.enabled).toBeTruthy();
+ formH.setValue('name', null);
+ expect(value.disabled).toBeTruthy();
+ });
+
+ it('should have a value field', () => {
+ formH.setValue('name', component.nameAttributes[0]);
+ formH.expectError('value', 'required');
+ formH.expectValidChange('value', 'alert0');
+ });
+
+ it('should test preFillControls', () => {
+ const controlValues = {
+ name: 'alertname',
+ value: 'alert0',
+ isRegex: false
+ };
+ component.preFillControls(controlValues);
+ expect(component.form.value).toEqual(controlValues);
+ });
+
+ it('should test submit', (done) => {
+ const controlValues = {
+ name: 'alertname',
+ value: 'alert0',
+ isRegex: false
+ };
+ component.preFillControls(controlValues);
+ component.submitAction.subscribe((resp: object) => {
+ expect(resp).toEqual(controlValues);
+ done();
+ });
+ component.onSubmit();
+ });
+
+ describe('typeahead', () => {
+ let equality: { [key: string]: boolean };
+ let expectations: { [key: string]: string[] };
+
+ const search = (s: string) => {
+ Object.keys(expectations).forEach((key) => {
+ formH.setValue('name', key);
+ component.search(of(s)).subscribe((result) => {
+ // Expect won't fail the test inside subscribe
+ equality[key] = _.isEqual(result, expectations[key]);
+ });
+ expect(equality[key]).toBeTruthy();
+ });
+ };
+
+ beforeEach(() => {
+ equality = {
+ alertname: false,
+ instance: false,
+ job: false,
+ severity: false
+ };
+ expectations = {
+ alertname: ['alert0', 'alert1'],
+ instance: ['someInstance'],
+ job: ['someJob'],
+ severity: ['someSeverity']
+ };
+ });
+
+ it('should show all values on name switch', () => {
+ search('');
+ });
+
+ it('should search for "some"', () => {
+ expectations['alertname'] = [];
+ search('some');
+ });
+
+ it('should search for "er"', () => {
+ expectations['instance'] = [];
+ expectations['job'] = [];
+ search('er');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.ts
new file mode 100644
index 000000000..bdd616ce9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.ts
@@ -0,0 +1,107 @@
+import { Component, EventEmitter, Output, ViewChild } from '@angular/core';
+import { FormControl, Validators } from '@angular/forms';
+
+import { NgbActiveModal, NgbTypeahead } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { merge, Observable, Subject } from 'rxjs';
+import { debounceTime, distinctUntilChanged, filter, map } from 'rxjs/operators';
+
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import {
+ AlertmanagerSilenceMatcher,
+ AlertmanagerSilenceMatcherMatch
+} from '~/app/shared/models/alertmanager-silence';
+import { PrometheusRule } from '~/app/shared/models/prometheus-alerts';
+import { PrometheusSilenceMatcherService } from '~/app/shared/services/prometheus-silence-matcher.service';
+
+@Component({
+ selector: 'cd-silence-matcher-modal',
+ templateUrl: './silence-matcher-modal.component.html',
+ styleUrls: ['./silence-matcher-modal.component.scss']
+})
+export class SilenceMatcherModalComponent {
+ @ViewChild(NgbTypeahead, { static: true })
+ typeahead: NgbTypeahead;
+ @Output()
+ submitAction = new EventEmitter();
+
+ form: CdFormGroup;
+ editMode = false;
+ rules: PrometheusRule[];
+ nameAttributes = ['alertname', 'instance', 'job', 'severity'];
+ possibleValues: string[] = [];
+ matcherMatch: AlertmanagerSilenceMatcherMatch = undefined;
+
+ // For typeahead usage
+ valueClick = new Subject<string>();
+ valueFocus = new Subject<string>();
+ search = (text$: Observable<string>) => {
+ return merge(
+ text$.pipe(debounceTime(200), distinctUntilChanged()),
+ this.valueFocus,
+ this.valueClick.pipe(filter(() => !this.typeahead.isPopupOpen()))
+ ).pipe(
+ map((term) =>
+ (term === ''
+ ? this.possibleValues
+ : this.possibleValues.filter((v) => v.toLowerCase().indexOf(term.toLowerCase()) > -1)
+ ).slice(0, 10)
+ )
+ );
+ };
+
+ constructor(
+ private formBuilder: CdFormBuilder,
+ private silenceMatcher: PrometheusSilenceMatcherService,
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ this.createForm();
+ this.subscribeToChanges();
+ }
+
+ private createForm() {
+ this.form = this.formBuilder.group({
+ name: [null, [Validators.required]],
+ value: [{ value: '', disabled: true }, [Validators.required]],
+ isRegex: new FormControl(false)
+ });
+ }
+
+ private subscribeToChanges() {
+ this.form.get('name').valueChanges.subscribe((name) => {
+ if (name === null) {
+ this.form.get('value').disable();
+ return;
+ }
+ this.setPossibleValues(name);
+ this.form.get('value').enable();
+ });
+ this.form.get('value').valueChanges.subscribe((value) => {
+ const values = this.form.value;
+ values.value = value; // Isn't the current value at this stage
+ this.matcherMatch = this.silenceMatcher.singleMatch(values, this.rules);
+ });
+ }
+
+ private setPossibleValues(name: string) {
+ this.possibleValues = _.sortedUniq(
+ this.rules.map((r) => _.get(r, this.silenceMatcher.getAttributePath(name))).filter((x) => x)
+ );
+ }
+
+ getMode() {
+ return this.editMode ? this.actionLabels.EDIT : this.actionLabels.ADD;
+ }
+
+ preFillControls(matcher: AlertmanagerSilenceMatcher) {
+ this.form.setValue(matcher);
+ }
+
+ onSubmit() {
+ this.submitAction.emit(this.form.value);
+ this.activeModal.close();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/placement.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/placement.pipe.spec.ts
new file mode 100644
index 000000000..588744aa6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/placement.pipe.spec.ts
@@ -0,0 +1,78 @@
+import { PlacementPipe } from './placement.pipe';
+
+describe('PlacementPipe', () => {
+ const pipe = new PlacementPipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms to no spec', () => {
+ expect(pipe.transform(undefined)).toBe('no spec');
+ });
+
+ it('transforms to unmanaged', () => {
+ expect(pipe.transform({ unmanaged: true })).toBe('unmanaged');
+ });
+
+ it('transforms placement (1)', () => {
+ expect(
+ pipe.transform({
+ placement: {
+ hosts: ['mon0']
+ }
+ })
+ ).toBe('mon0');
+ });
+
+ it('transforms placement (2)', () => {
+ expect(
+ pipe.transform({
+ placement: {
+ hosts: ['mon0', 'mgr0']
+ }
+ })
+ ).toBe('mon0;mgr0');
+ });
+
+ it('transforms placement (3)', () => {
+ expect(
+ pipe.transform({
+ placement: {
+ count: 1
+ }
+ })
+ ).toBe('count:1');
+ });
+
+ it('transforms placement (4)', () => {
+ expect(
+ pipe.transform({
+ placement: {
+ label: 'foo'
+ }
+ })
+ ).toBe('label:foo');
+ });
+
+ it('transforms placement (5)', () => {
+ expect(
+ pipe.transform({
+ placement: {
+ host_pattern: 'abc.ceph.xyz.com'
+ }
+ })
+ ).toBe('abc.ceph.xyz.com');
+ });
+
+ it('transforms placement (6)', () => {
+ expect(
+ pipe.transform({
+ placement: {
+ count: 2,
+ hosts: ['mon0', 'mgr0']
+ }
+ })
+ ).toBe('mon0;mgr0;count:2');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/placement.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/placement.pipe.ts
new file mode 100644
index 000000000..5aee65890
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/placement.pipe.ts
@@ -0,0 +1,41 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import _ from 'lodash';
+
+@Pipe({
+ name: 'placement'
+})
+export class PlacementPipe implements PipeTransform {
+ /**
+ * Convert the placement configuration into human readable form.
+ * The output is equal to the column 'PLACEMENT' in 'ceph orch ls'.
+ * @param serviceSpec The service specification to process.
+ * @return The placement configuration as human readable string.
+ */
+ transform(serviceSpec: object | undefined): string {
+ if (_.isUndefined(serviceSpec)) {
+ return $localize`no spec`;
+ }
+ if (_.get(serviceSpec, 'unmanaged', false)) {
+ return $localize`unmanaged`;
+ }
+ const kv: Array<any> = [];
+ const hosts: Array<string> = _.get(serviceSpec, 'placement.hosts');
+ const count: number = _.get(serviceSpec, 'placement.count');
+ const label: string = _.get(serviceSpec, 'placement.label');
+ const hostPattern: string = _.get(serviceSpec, 'placement.host_pattern');
+ if (_.isArray(hosts)) {
+ kv.push(...hosts);
+ }
+ if (_.isNumber(count)) {
+ kv.push($localize`count:${count}`);
+ }
+ if (_.isString(label)) {
+ kv.push($localize`label:${label}`);
+ }
+ if (_.isString(hostPattern)) {
+ kv.push(hostPattern);
+ }
+ return kv.join(';');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html
new file mode 100644
index 000000000..fc076a185
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html
@@ -0,0 +1,102 @@
+<cd-orchestrator-doc-panel *ngIf="showDocPanel"></cd-orchestrator-doc-panel>
+
+<div *ngIf="flag === 'hostDetails'; else serviceDetailsTpl">
+ <ng-container *ngTemplateOutlet="serviceDaemonDetailsTpl"></ng-container>
+</div>
+
+<ng-template #serviceDetailsTpl>
+ <ng-container>
+ <ul ngbNav
+ #nav="ngbNav"
+ class="nav-tabs"
+ cdStatefulTab="service-details">
+ <li ngbNavItem="details">
+ <a ngbNavLink
+ i18n>Details</a>
+ <ng-template ngbNavContent>
+ <ng-container *ngTemplateOutlet="serviceDaemonDetailsTpl"></ng-container>
+ </ng-template>
+ </li>
+ <li ngbNavItem="service_events">
+ <a ngbNavLink
+ i18n>Service Events</a>
+ <ng-template ngbNavContent>
+ <cd-table *ngIf="hasOrchestrator"
+ #serviceTable
+ [data]="services"
+ [columns]="serviceColumns"
+ columnMode="flex"
+ (fetchData)="getServices($event)">
+ </cd-table>
+ </ng-template>
+ </li>
+ </ul>
+ <div [ngbNavOutlet]="nav"></div>
+ </ng-container>
+</ng-template>
+
+<ng-template #statusTpl
+ let-row="row">
+ <span class="badge"
+ [ngClass]="row | pipeFunction:getStatusClass">
+ {{ row.status_desc }}
+ </span>
+</ng-template>
+
+<ng-template #listTpl
+ let-events="value">
+ <ul class="list-group list-group-flush"
+ *ngIf="events?.length else noEventsAvailable">
+ <li class="list-group-item"
+ *ngFor="let event of events; trackBy:trackByFn">
+ <b>{{ event.created | relativeDate }} - </b>
+ <span class="badge badge-info">{{ event.subject }}</span><br>
+ <span *ngIf="event.level === 'INFO'">
+ <i [ngClass]="[icons.infoCircle]"
+ aria-hidden="true"></i>
+ </span>
+ <span *ngIf="event.level === 'ERROR'">
+ <i [ngClass]="[icons.warning]"
+ aria-hidden="true"></i>
+ </span>
+ {{ event.message }}
+ </li>
+ </ul>
+ <ng-template #noEventsAvailable>
+ <div *ngIf="events?.length === 0"
+ class="list-group-item">
+ <span>No data available</span>
+ </div>
+ </ng-template>
+</ng-template>
+
+<ng-template #serviceDaemonDetailsTpl>
+ <cd-table *ngIf="hasOrchestrator"
+ #daemonsTable
+ [data]="daemons"
+ selectionType="single"
+ [columns]="columns"
+ columnMode="flex"
+ identifier="daemon_name"
+ (fetchData)="getDaemons($event)"
+ (updateSelection)="updateSelection($event)">
+ <cd-table-actions id="service-daemon-list-actions"
+ class="table-actions"
+ [selection]="selection"
+ [permission]="permissions.hosts"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ </cd-table>
+</ng-template>
+
+<ng-template #cpuTpl
+ let-row="row">
+ <cd-usage-bar [total]="total"
+ [calculatePerc]="false"
+ [used]="row.cpu_percentage"
+ [isBinary]="false"
+ [warningThreshold]="warningThreshold"
+ [errorThreshold]="errorThreshold">
+ </cd-usage-bar>
+</ng-template>
+
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.scss
new file mode 100644
index 000000000..a0d91c704
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.scss
@@ -0,0 +1,14 @@
+@use './src/styles/vendor/variables' as vv;
+
+.fa-info-circle {
+ color: vv.$info;
+}
+
+.fa-exclamation-triangle {
+ color: vv.$danger;
+}
+
+.list-group-item {
+ background-color: transparent;
+ border-width: 0;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.spec.ts
new file mode 100644
index 000000000..31739a7c2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.spec.ts
@@ -0,0 +1,253 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import _ from 'lodash';
+import { NgxPipeFunctionModule } from 'ngx-pipe-function';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { CephModule } from '~/app/ceph/ceph.module';
+import { CoreModule } from '~/app/core/core.module';
+import { CephServiceService } from '~/app/shared/api/ceph-service.service';
+import { HostService } from '~/app/shared/api/host.service';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { ServiceDaemonListComponent } from './service-daemon-list.component';
+
+describe('ServiceDaemonListComponent', () => {
+ let component: ServiceDaemonListComponent;
+ let fixture: ComponentFixture<ServiceDaemonListComponent>;
+
+ const daemons = [
+ {
+ hostname: 'osd0',
+ container_id: '003c10beafc8c27b635bcdfed1ed832e4c1005be89bb1bb05ad4cc6c2b98e41b',
+ container_image_id: 'e70344c77bcbf3ee389b9bf5128f635cf95f3d59e005c5d8e67fc19bcc74ed23',
+ container_image_name: 'docker.io/ceph/daemon-base:latest-master-devel',
+ daemon_id: '3',
+ daemon_type: 'osd',
+ daemon_name: 'osd.3',
+ version: '15.1.0-1174-g16a11f7',
+ memory_usage: '17.7',
+ cpu_percentage: '3.54%',
+ status: 1,
+ status_desc: 'running',
+ last_refresh: '2020-02-25T04:33:26.465699',
+ events: [
+ { created: '2020-02-24T04:33:26.465699' },
+ { created: '2020-02-25T04:33:26.465699' },
+ { created: '2020-02-26T04:33:26.465699' }
+ ]
+ },
+ {
+ hostname: 'osd0',
+ container_id: 'baeec41a01374b3ed41016d542d19aef4a70d69c27274f271e26381a0cc58e7a',
+ container_image_id: 'e70344c77bcbf3ee389b9bf5128f635cf95f3d59e005c5d8e67fc19bcc74ed23',
+ container_image_name: 'docker.io/ceph/daemon-base:latest-master-devel',
+ daemon_id: '4',
+ daemon_type: 'osd',
+ daemon_name: 'osd.4',
+ version: '15.1.0-1174-g16a11f7',
+ memory_usage: '17.7',
+ cpu_percentage: '3.54%',
+ status: 1,
+ status_desc: 'running',
+ last_refresh: '2020-02-25T04:33:26.465822',
+ events: []
+ },
+ {
+ hostname: 'osd0',
+ container_id: '8483de277e365bea4365cee9e1f26606be85c471e4da5d51f57e4b85a42c616e',
+ container_image_id: 'e70344c77bcbf3ee389b9bf5128f635cf95f3d59e005c5d8e67fc19bcc74ed23',
+ container_image_name: 'docker.io/ceph/daemon-base:latest-master-devel',
+ daemon_id: '5',
+ daemon_type: 'osd',
+ daemon_name: 'osd.5',
+ version: '15.1.0-1174-g16a11f7',
+ memory_usage: '17.7',
+ cpu_percentage: '3.54%',
+ status: 1,
+ status_desc: 'running',
+ last_refresh: '2020-02-25T04:33:26.465886',
+ events: []
+ },
+ {
+ hostname: 'mon0',
+ container_id: '6ca0574f47e300a6979eaf4e7c283a8c4325c2235ae60358482fc4cd58844a21',
+ container_image_id: 'e70344c77bcbf3ee389b9bf5128f635cf95f3d59e005c5d8e67fc19bcc74ed23',
+ container_image_name: 'docker.io/ceph/daemon-base:latest-master-devel',
+ daemon_id: 'a',
+ daemon_name: 'mon.a',
+ daemon_type: 'mon',
+ version: '15.1.0-1174-g16a11f7',
+ memory_usage: '17.7',
+ cpu_percentage: '3.54%',
+ status: 1,
+ status_desc: 'running',
+ last_refresh: '2020-02-25T04:33:26.465886',
+ events: []
+ }
+ ];
+
+ const services = [
+ {
+ service_type: 'osd',
+ service_name: 'osd',
+ status: {
+ container_image_id: 'e70344c77bcbf3ee389b9bf5128f635cf95f3d59e005c5d8e67fc19bcc74ed23',
+ container_image_name: 'docker.io/ceph/daemon-base:latest-master-devel',
+ size: 3,
+ running: 3,
+ last_refresh: '2020-02-25T04:33:26.465699'
+ },
+ events: '2021-03-22T07:34:48.582163Z service:osd [INFO] "service was created"'
+ },
+ {
+ service_type: 'crash',
+ service_name: 'crash',
+ status: {
+ container_image_id: 'e70344c77bcbf3ee389b9bf5128f635cf95f3d59e005c5d8e67fc19bcc74ed23',
+ container_image_name: 'docker.io/ceph/daemon-base:latest-master-devel',
+ size: 1,
+ running: 1,
+ last_refresh: '2020-02-25T04:33:26.465766'
+ },
+ events: '2021-03-22T07:34:48.582163Z service:osd [INFO] "service was created"'
+ }
+ ];
+
+ const getDaemonsByHostname = (hostname?: string) => {
+ return hostname ? _.filter(daemons, { hostname: hostname }) : daemons;
+ };
+
+ const getDaemonsByServiceName = (serviceName?: string) => {
+ return serviceName ? _.filter(daemons, { daemon_type: serviceName }) : daemons;
+ };
+
+ configureTestBed({
+ imports: [
+ HttpClientTestingModule,
+ CephModule,
+ CoreModule,
+ NgxPipeFunctionModule,
+ SharedModule,
+ ToastrModule.forRoot()
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ServiceDaemonListComponent);
+ component = fixture.componentInstance;
+ const hostService = TestBed.inject(HostService);
+ const cephServiceService = TestBed.inject(CephServiceService);
+ spyOn(hostService, 'getDaemons').and.callFake(() =>
+ of(getDaemonsByHostname(component.hostname))
+ );
+ spyOn(cephServiceService, 'getDaemons').and.callFake(() =>
+ of(getDaemonsByServiceName(component.serviceName))
+ );
+ spyOn(cephServiceService, 'list').and.returnValue(of(services));
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should list daemons by host', () => {
+ component.hostname = 'mon0';
+ component.getDaemons(new CdTableFetchDataContext(() => undefined));
+ expect(component.daemons.length).toBe(1);
+ });
+
+ it('should list daemons by service', () => {
+ component.serviceName = 'osd';
+ component.getDaemons(new CdTableFetchDataContext(() => undefined));
+ expect(component.daemons.length).toBe(3);
+ });
+
+ it('should list services', () => {
+ component.getServices(new CdTableFetchDataContext(() => undefined));
+ expect(component.services.length).toBe(2);
+ });
+
+ it('should not display doc panel if orchestrator is available', () => {
+ expect(component.showDocPanel).toBeFalsy();
+ });
+
+ it('should call daemon action', () => {
+ const daemon = daemons[0];
+ component.selection.selected = [daemon];
+ component['daemonService'].action = jest.fn(() => of());
+ for (const action of ['start', 'stop', 'restart', 'redeploy']) {
+ component.daemonAction(action);
+ expect(component['daemonService'].action).toHaveBeenCalledWith(daemon.daemon_name, action);
+ }
+ });
+
+ it('should disable daemon actions', () => {
+ const daemon = {
+ daemon_type: 'osd',
+ status_desc: 'running'
+ };
+
+ const states = {
+ start: true,
+ stop: false,
+ restart: false,
+ redeploy: false
+ };
+ const expectBool = (toExpect: boolean, arg: boolean) => {
+ if (toExpect === true) {
+ expect(arg).toBeTruthy();
+ } else {
+ expect(arg).toBeFalsy();
+ }
+ };
+
+ component.selection.selected = [daemon];
+ for (const action of ['start', 'stop', 'restart', 'redeploy']) {
+ expectBool(states[action], component.actionDisabled(action));
+ }
+
+ daemon.status_desc = 'stopped';
+ states.start = false;
+ states.stop = true;
+ component.selection.selected = [daemon];
+ for (const action of ['start', 'stop', 'restart', 'redeploy']) {
+ expectBool(states[action], component.actionDisabled(action));
+ }
+ });
+
+ it('should disable daemon actions in mgr and mon daemon', () => {
+ const daemon = {
+ daemon_type: 'mgr',
+ status_desc: 'running'
+ };
+ for (const action of ['start', 'stop', 'restart', 'redeploy']) {
+ expect(component.actionDisabled(action)).toBeTruthy();
+ }
+ daemon.daemon_type = 'mon';
+ for (const action of ['start', 'stop', 'restart', 'redeploy']) {
+ expect(component.actionDisabled(action)).toBeTruthy();
+ }
+ });
+
+ it('should disable daemon actions if no selection', () => {
+ component.selection.selected = [];
+ for (const action of ['start', 'stop', 'restart', 'redeploy']) {
+ expect(component.actionDisabled(action)).toBeTruthy();
+ }
+ });
+
+ it('should sort daemons events', () => {
+ component.sortDaemonEvents();
+ const daemon = daemons[0];
+ for (let i = 1; i < daemon.events.length; i++) {
+ const t1 = new Date(daemon.events[i - 1].created).getTime();
+ const t2 = new Date(daemon.events[i].created).getTime();
+ expect(t1 >= t2).toBeTruthy();
+ }
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts
new file mode 100644
index 000000000..d1c2f9cc3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts
@@ -0,0 +1,347 @@
+import {
+ AfterViewInit,
+ Component,
+ Input,
+ OnChanges,
+ OnDestroy,
+ OnInit,
+ QueryList,
+ TemplateRef,
+ ViewChild,
+ ViewChildren
+} from '@angular/core';
+
+import _ from 'lodash';
+import { Observable, Subscription } from 'rxjs';
+import { take } from 'rxjs/operators';
+
+import { CephServiceService } from '~/app/shared/api/ceph-service.service';
+import { DaemonService } from '~/app/shared/api/daemon.service';
+import { HostService } from '~/app/shared/api/host.service';
+import { OrchestratorService } from '~/app/shared/api/orchestrator.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { TableComponent } from '~/app/shared/datatable/table/table.component';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { Daemon } from '~/app/shared/models/daemon.interface';
+import { Permissions } from '~/app/shared/models/permissions';
+import { CephServiceSpec } from '~/app/shared/models/service.interface';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { RelativeDatePipe } from '~/app/shared/pipes/relative-date.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+
+@Component({
+ selector: 'cd-service-daemon-list',
+ templateUrl: './service-daemon-list.component.html',
+ styleUrls: ['./service-daemon-list.component.scss']
+})
+export class ServiceDaemonListComponent implements OnInit, OnChanges, AfterViewInit, OnDestroy {
+ @ViewChild('statusTpl', { static: true })
+ statusTpl: TemplateRef<any>;
+
+ @ViewChild('listTpl', { static: true })
+ listTpl: TemplateRef<any>;
+
+ @ViewChild('cpuTpl', { static: true })
+ cpuTpl: TemplateRef<any>;
+
+ @ViewChildren('daemonsTable')
+ daemonsTableTpls: QueryList<TemplateRef<TableComponent>>;
+
+ @Input()
+ serviceName?: string;
+
+ @Input()
+ hostname?: string;
+
+ @Input()
+ hiddenColumns: string[] = [];
+
+ @Input()
+ flag?: string;
+
+ total = 100;
+
+ warningThreshold = 0.8;
+
+ errorThreshold = 0.9;
+
+ icons = Icons;
+
+ daemons: Daemon[] = [];
+ services: Array<CephServiceSpec> = [];
+ columns: CdTableColumn[] = [];
+ serviceColumns: CdTableColumn[] = [];
+ tableActions: CdTableAction[];
+ selection = new CdTableSelection();
+ permissions: Permissions;
+
+ hasOrchestrator = false;
+ showDocPanel = false;
+
+ private daemonsTable: TableComponent;
+ private daemonsTableTplsSub: Subscription;
+ private serviceSub: Subscription;
+
+ constructor(
+ private hostService: HostService,
+ private cephServiceService: CephServiceService,
+ private orchService: OrchestratorService,
+ private relativeDatePipe: RelativeDatePipe,
+ private dimlessBinary: DimlessBinaryPipe,
+ public actionLabels: ActionLabelsI18n,
+ private authStorageService: AuthStorageService,
+ private daemonService: DaemonService,
+ private notificationService: NotificationService
+ ) {}
+
+ ngOnInit() {
+ this.permissions = this.authStorageService.getPermissions();
+ this.tableActions = [
+ {
+ permission: 'update',
+ icon: Icons.start,
+ click: () => this.daemonAction('start'),
+ name: this.actionLabels.START,
+ disable: () => this.actionDisabled('start')
+ },
+ {
+ permission: 'update',
+ icon: Icons.stop,
+ click: () => this.daemonAction('stop'),
+ name: this.actionLabels.STOP,
+ disable: () => this.actionDisabled('stop')
+ },
+ {
+ permission: 'update',
+ icon: Icons.restart,
+ click: () => this.daemonAction('restart'),
+ name: this.actionLabels.RESTART,
+ disable: () => this.actionDisabled('restart')
+ },
+ {
+ permission: 'update',
+ icon: Icons.deploy,
+ click: () => this.daemonAction('redeploy'),
+ name: this.actionLabels.REDEPLOY,
+ disable: () => this.actionDisabled('redeploy')
+ }
+ ];
+ this.columns = [
+ {
+ name: $localize`Hostname`,
+ prop: 'hostname',
+ flexGrow: 2,
+ filterable: true
+ },
+ {
+ name: $localize`Daemon name`,
+ prop: 'daemon_name',
+ flexGrow: 1,
+ filterable: true
+ },
+ {
+ name: $localize`Version`,
+ prop: 'version',
+ flexGrow: 1,
+ filterable: true
+ },
+ {
+ name: $localize`Status`,
+ prop: 'status_desc',
+ flexGrow: 1,
+ filterable: true,
+ cellTemplate: this.statusTpl
+ },
+ {
+ name: $localize`Last Refreshed`,
+ prop: 'last_refresh',
+ pipe: this.relativeDatePipe,
+ flexGrow: 1
+ },
+ {
+ name: $localize`CPU Usage`,
+ prop: 'cpu_percentage',
+ flexGrow: 1,
+ cellTemplate: this.cpuTpl
+ },
+ {
+ name: $localize`Memory Usage`,
+ prop: 'memory_usage',
+ flexGrow: 1,
+ pipe: this.dimlessBinary,
+ cellClass: 'text-right'
+ },
+ {
+ name: $localize`Daemon Events`,
+ prop: 'events',
+ flexGrow: 2,
+ cellTemplate: this.listTpl
+ }
+ ];
+
+ this.serviceColumns = [
+ {
+ name: $localize`Service Name`,
+ prop: 'service_name',
+ flexGrow: 2,
+ filterable: true
+ },
+ {
+ name: $localize`Service Type`,
+ prop: 'service_type',
+ flexGrow: 1,
+ filterable: true
+ },
+ {
+ name: $localize`Service Events`,
+ prop: 'events',
+ flexGrow: 5,
+ cellTemplate: this.listTpl
+ }
+ ];
+
+ this.orchService.status().subscribe((data: { available: boolean }) => {
+ this.hasOrchestrator = data.available;
+ this.showDocPanel = !data.available;
+ });
+
+ this.columns = this.columns.filter((col: any) => {
+ return !this.hiddenColumns.includes(col.prop);
+ });
+ }
+
+ ngOnChanges() {
+ if (!_.isUndefined(this.daemonsTable)) {
+ this.daemonsTable.reloadData();
+ }
+ }
+
+ ngAfterViewInit() {
+ this.daemonsTableTplsSub = this.daemonsTableTpls.changes.subscribe(
+ (tableRefs: QueryList<TableComponent>) => {
+ this.daemonsTable = tableRefs.first;
+ }
+ );
+ }
+
+ ngOnDestroy() {
+ if (this.daemonsTableTplsSub) {
+ this.daemonsTableTplsSub.unsubscribe();
+ }
+ if (this.serviceSub) {
+ this.serviceSub.unsubscribe();
+ }
+ }
+
+ getStatusClass(row: Daemon): string {
+ return _.get(
+ {
+ '-1': 'badge-danger',
+ '0': 'badge-warning',
+ '1': 'badge-success'
+ },
+ row.status,
+ 'badge-dark'
+ );
+ }
+
+ getDaemons(context: CdTableFetchDataContext) {
+ let observable: Observable<Daemon[]>;
+ if (this.hostname) {
+ observable = this.hostService.getDaemons(this.hostname);
+ } else if (this.serviceName) {
+ observable = this.cephServiceService.getDaemons(this.serviceName);
+ } else {
+ this.daemons = [];
+ return;
+ }
+ observable.subscribe(
+ (daemons: Daemon[]) => {
+ this.daemons = daemons;
+ this.sortDaemonEvents();
+ },
+ () => {
+ this.daemons = [];
+ context.error();
+ }
+ );
+ }
+
+ sortDaemonEvents() {
+ this.daemons.forEach((daemon: any) => {
+ daemon.events?.sort((event1: any, event2: any) => {
+ return new Date(event2.created).getTime() - new Date(event1.created).getTime();
+ });
+ });
+ }
+ getServices(context: CdTableFetchDataContext) {
+ this.serviceSub = this.cephServiceService.list(this.serviceName).subscribe(
+ (services: CephServiceSpec[]) => {
+ this.services = services;
+ },
+ () => {
+ this.services = [];
+ context.error();
+ }
+ );
+ }
+
+ trackByFn(_index: any, item: any) {
+ return item.created;
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ daemonAction(actionType: string) {
+ this.daemonService
+ .action(this.selection.first()?.daemon_name, actionType)
+ .pipe(take(1))
+ .subscribe({
+ next: (resp) => {
+ this.notificationService.show(
+ NotificationType.success,
+ `Daemon ${actionType} scheduled`,
+ resp.body.toString()
+ );
+ },
+ error: (resp) => {
+ this.notificationService.show(
+ NotificationType.error,
+ 'Daemon action failed',
+ resp.body.toString()
+ );
+ }
+ });
+ }
+
+ actionDisabled(actionType: string) {
+ if (this.selection?.hasSelection) {
+ const daemon = this.selection.selected[0];
+ if (daemon.daemon_type === 'mon' || daemon.daemon_type === 'mgr') {
+ return true; // don't allow actions on mon and mgr, dashboard requires them.
+ }
+ switch (actionType) {
+ case 'start':
+ if (daemon.status_desc === 'running') {
+ return true;
+ }
+ break;
+ case 'stop':
+ if (daemon.status_desc === 'stopped') {
+ return true;
+ }
+ break;
+ }
+ return false;
+ }
+ return true; // if no selection then disable everything
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-details/service-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-details/service-details.component.html
new file mode 100644
index 000000000..704f0f98e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-details/service-details.component.html
@@ -0,0 +1,4 @@
+<ng-container *ngIf="selection">
+ <cd-service-daemon-list [serviceName]="selection['service_name']">
+ </cd-service-daemon-list>
+</ng-container>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-details/service-details.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-details/service-details.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-details/service-details.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-details/service-details.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-details/service-details.component.spec.ts
new file mode 100644
index 000000000..109ef039f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-details/service-details.component.spec.ts
@@ -0,0 +1,43 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgxPipeFunctionModule } from 'ngx-pipe-function';
+import { ToastrModule } from 'ngx-toastr';
+
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { ServiceDaemonListComponent } from '../service-daemon-list/service-daemon-list.component';
+import { ServiceDetailsComponent } from './service-details.component';
+
+describe('ServiceDetailsComponent', () => {
+ let component: ServiceDetailsComponent;
+ let fixture: ComponentFixture<ServiceDetailsComponent>;
+
+ configureTestBed({
+ imports: [
+ HttpClientTestingModule,
+ RouterTestingModule,
+ SharedModule,
+ NgbNavModule,
+ NgxPipeFunctionModule,
+ ToastrModule.forRoot()
+ ],
+ declarations: [ServiceDetailsComponent, ServiceDaemonListComponent],
+ providers: [{ provide: SummaryService, useValue: { subscribeOnce: jest.fn() } }]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ServiceDetailsComponent);
+ component = fixture.componentInstance;
+ component.selection = new CdTableSelection();
+ });
+
+ it('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-details/service-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-details/service-details.component.ts
new file mode 100644
index 000000000..0aed38e67
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-details/service-details.component.ts
@@ -0,0 +1,17 @@
+import { Component, Input } from '@angular/core';
+
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { Permissions } from '~/app/shared/models/permissions';
+
+@Component({
+ selector: 'cd-service-details',
+ templateUrl: './service-details.component.html',
+ styleUrls: ['./service-details.component.scss']
+})
+export class ServiceDetailsComponent {
+ @Input()
+ permissions: Permissions;
+
+ @Input()
+ selection: CdTableSelection;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.html
new file mode 100644
index 000000000..dcd898d88
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.html
@@ -0,0 +1,696 @@
+<cd-modal [pageURL]="pageURL"
+ [modalRef]="activeModal">
+ <span class="modal-title"
+ i18n>{{ action | titlecase }} {{ resource | upperFirst }}</span>
+ <ng-container class="modal-content">
+ <form #frm="ngForm"
+ [formGroup]="serviceForm"
+ novalidate>
+ <div class="modal-body">
+
+ <!-- Service type -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="service_type"
+ i18n>Type</label>
+ <div class="cd-col-form-input">
+ <select id="service_type"
+ name="service_type"
+ class="form-control"
+ formControlName="service_type"
+ (change)="getServiceIds($event.target.value)">
+ <option i18n
+ [ngValue]="null">-- Select a service type --</option>
+ <option *ngFor="let serviceType of serviceTypes"
+ [value]="serviceType">
+ {{ serviceType }}
+ </option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('service_type', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- backend_service -->
+ <div *ngIf="serviceForm.controls.service_type.value === 'ingress'"
+ class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
+ for="backend_service">Backend Service</label>
+ <div class="cd-col-form-input">
+ <select id="backend_service"
+ name="backend_service"
+ class="form-control"
+ formControlName="backend_service"
+ (change)="prePopulateId()">
+ <option *ngIf="services === null"
+ [ngValue]="null"
+ i18n>Loading...</option>
+ <option *ngIf="services !== null && services.length === 0"
+ [ngValue]="null"
+ i18n>-- No service available --</option>
+ <option *ngIf="services !== null && services.length > 0"
+ [ngValue]="null"
+ i18n>-- Select an existing service --</option>
+ <option *ngFor="let service of services"
+ [value]="service.service_name">{{ service.service_name }}</option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('backend_service', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Service id -->
+ <div class="form-group row"
+ *ngIf="serviceForm.controls.service_type.value !== 'snmp-gateway'">
+ <label i18n
+ class="cd-col-form-label"
+ [ngClass]="{'required': ['mds', 'rgw', 'nfs', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)}"
+ for="service_id">Id</label>
+ <div class="cd-col-form-input">
+ <input id="service_id"
+ class="form-control"
+ type="text"
+ formControlName="service_id">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('service_id', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('service_id', frm, 'uniqueName')"
+ i18n>This service id is already in use.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('service_id', frm, 'rgwPattern')"
+ i18n>The value does not match the pattern <strong>&lt;service_id&gt;[.&lt;realm_name&gt;.&lt;zone_name&gt;]</strong>.</span>
+ </div>
+ </div>
+
+ <!-- unmanaged -->
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="unmanaged"
+ type="checkbox"
+ formControlName="unmanaged">
+ <label class="custom-control-label"
+ for="unmanaged"
+ i18n>Unmanaged</label>
+ </div>
+ </div>
+ </div>
+
+ <!-- Placement -->
+ <div *ngIf="!serviceForm.controls.unmanaged.value"
+ class="form-group row">
+ <label class="cd-col-form-label"
+ for="placement"
+ i18n>Placement</label>
+ <div class="cd-col-form-input">
+ <select id="placement"
+ class="form-control"
+ formControlName="placement">
+ <option i18n
+ value="hosts">Hosts</option>
+ <option i18n
+ value="label">Label</option>
+ </select>
+ </div>
+ </div>
+
+ <!-- Label -->
+ <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'label'"
+ class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="label">Label</label>
+ <div class="cd-col-form-input">
+ <input id="label"
+ class="form-control"
+ type="text"
+ formControlName="label"
+ [ngbTypeahead]="searchLabels"
+ (focus)="labelFocus.next($any($event).target.value)"
+ (click)="labelClick.next($any($event).target.value)">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('label', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Hosts -->
+ <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'hosts'"
+ class="form-group row">
+ <label class="cd-col-form-label"
+ for="hosts"
+ i18n>Hosts</label>
+ <div class="cd-col-form-input">
+ <cd-select-badges id="hosts"
+ [data]="serviceForm.controls.hosts.value"
+ [options]="hosts.options"
+ [messages]="hosts.messages">
+ </cd-select-badges>
+ </div>
+ </div>
+
+ <!-- count -->
+ <div *ngIf="!serviceForm.controls.unmanaged.value"
+ class="form-group row">
+ <label class="cd-col-form-label"
+ for="count">
+ <span i18n>Count</span>
+ <cd-helper i18n>Only that number of daemons will be created.</cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input id="count"
+ class="form-control"
+ type="number"
+ formControlName="count"
+ min="1">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('count', frm, 'min')"
+ i18n>The value must be at least 1.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('count', frm, 'pattern')"
+ i18n>The entered value needs to be a number.</span>
+ </div>
+ </div>
+
+ <!-- RGW -->
+ <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'rgw'">
+ <!-- rgw_frontend_port -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="rgw_frontend_port">Port</label>
+ <div class="cd-col-form-input">
+ <input id="rgw_frontend_port"
+ class="form-control"
+ type="number"
+ formControlName="rgw_frontend_port"
+ min="1"
+ max="65535">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'pattern')"
+ i18n>The entered value needs to be a number.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'min')"
+ i18n>The value must be at least 1.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'max')"
+ i18n>The value cannot exceed 65535.</span>
+ </div>
+ </div>
+ </ng-container>
+
+ <!-- iSCSI -->
+ <!-- pool -->
+ <div class="form-group row"
+ *ngIf="serviceForm.controls.service_type.value === 'iscsi'">
+ <label i18n
+ class="cd-col-form-label required"
+ for="pool">Pool</label>
+ <div class="cd-col-form-input">
+ <select id="pool"
+ name="pool"
+ class="form-control"
+ formControlName="pool">
+ <option *ngIf="pools === null"
+ [ngValue]="null"
+ i18n>Loading...</option>
+ <option *ngIf="pools && pools.length === 0"
+ [ngValue]="null"
+ i18n>-- No pools available --</option>
+ <option *ngIf="pools && pools.length > 0"
+ [ngValue]="null"
+ i18n>-- Select a pool --</option>
+ <option *ngFor="let pool of pools"
+ [value]="pool.pool_name">{{ pool.pool_name }}</option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('pool', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- fields in iSCSI which are hidden when unmanaged is true -->
+ <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'iscsi'">
+ <!-- trusted_ip_list -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="trusted_ip_list">
+ <span i18n>Trusted IPs</span>
+ <cd-helper>
+ <span i18n>Comma separated list of IP addresses.</span>
+ <br>
+ <span i18n>Please add the <b>Ceph Manager</b> IP addresses here, otherwise the iSCSI gateways can't be reached.</span>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input id="trusted_ip_list"
+ class="form-control"
+ type="text"
+ formControlName="trusted_ip_list">
+ </div>
+ </div>
+
+ <!-- api_port -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="api_port">Port</label>
+ <div class="cd-col-form-input">
+ <input id="api_port"
+ class="form-control"
+ type="number"
+ formControlName="api_port"
+ min="1"
+ max="65535">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('api_port', frm, 'pattern')"
+ i18n>The entered value needs to be a number.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('api_port', frm, 'min')"
+ i18n>The value must be at least 1.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('api_port', frm, 'max')"
+ i18n>The value cannot exceed 65535.</span>
+ </div>
+ </div>
+
+ <!-- api_user -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
+ for="api_user">User</label>
+ <div class="cd-col-form-input">
+ <input id="api_user"
+ class="form-control"
+ type="text"
+ formControlName="api_user">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('api_user', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- api_password -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
+ for="api_password">Password</label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input id="api_password"
+ class="form-control"
+ type="password"
+ autocomplete="new-password"
+ formControlName="api_password">
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="api_password">
+ </button>
+ <cd-copy-2-clipboard-button source="api_password">
+ </cd-copy-2-clipboard-button>
+ </span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('api_password', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+ </div>
+ </ng-container>
+
+ <!-- Ingress -->
+ <ng-container *ngIf="serviceForm.controls.service_type.value === 'ingress'">
+ <!-- virtual_ip -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
+ for="virtual_ip">
+ <span i18n>Virtual IP</span>
+ <cd-helper>
+ <span i18n>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</span>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input id="virtual_ip"
+ class="form-control"
+ type="text"
+ formControlName="virtual_ip">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('virtual_ip', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- frontend_port -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
+ for="frontend_port">
+ <span i18n>Frontend Port</span>
+ <cd-helper>
+ <span i18n>The port used to access the ingress service.</span>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input id="frontend_port"
+ class="form-control"
+ type="number"
+ formControlName="frontend_port"
+ min="1"
+ max="65535">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('frontend_port', frm, 'pattern')"
+ i18n>The entered value needs to be a number.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('frontend_port', frm, 'min')"
+ i18n>The value must be at least 1.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('frontend_port', frm, 'max')"
+ i18n>The value cannot exceed 65535.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('frontend_port', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- monitor_port -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
+ for="monitor_port">
+ <span i18n>Monitor Port</span>
+ <cd-helper>
+ <span i18n>The port used by haproxy for load balancer status.</span>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input id="monitor_port"
+ class="form-control"
+ type="number"
+ formControlName="monitor_port"
+ min="1"
+ max="65535">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('monitor_port', frm, 'pattern')"
+ i18n>The entered value needs to be a number.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('monitor_port', frm, 'min')"
+ i18n>The value must be at least 1.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('monitor_port', frm, 'max')"
+ i18n>The value cannot exceed 65535.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('monitor_port', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+ <!-- virtual_interface_networks -->
+ <div class="form-group row"
+ *ngIf="!serviceForm.controls.unmanaged.value">
+ <label class="cd-col-form-label"
+ for="virtual_interface_networks">
+ <span i18n>CIDR Networks</span>
+ <cd-helper>
+ <span i18n>A list of networks to identify which network interface to use for the virtual IP address.</span>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input id="virtual_interface_networks"
+ class="form-control"
+ type="text"
+ formControlName="virtual_interface_networks">
+ </div>
+ </div>
+ </ng-container>
+
+ <!-- SNMP-Gateway -->
+ <ng-container *ngIf="serviceForm.controls.service_type.value === 'snmp-gateway'">
+ <!-- snmp-version -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="snmp_version"
+ i18n>Version</label>
+ <div class="cd-col-form-input">
+ <select id="snmp_version"
+ name="snmp_version"
+ class="form-control"
+ formControlName="snmp_version"
+ (change)="clearValidations()">
+ <option i18n
+ [ngValue]="null">-- Select SNMP version --</option>
+ <option *ngFor="let snmpVersion of ['V2c', 'V3']"
+ [value]="snmpVersion">{{ snmpVersion }}</option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('snmp_version', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+ <!-- Destination -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="snmp_destination">
+ <span i18n>Destination</span>
+ <cd-helper>
+ <span i18n>Must be of the format hostname:port.</span>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input id="snmp_destination"
+ class="form-control"
+ type="text"
+ formControlName="snmp_destination">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('snmp_destination', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('snmp_destination', frm, 'snmpDestinationPattern')"
+ i18n>The value does not match the pattern: <strong>hostname:port</strong></span>
+ </div>
+ </div>
+ <!-- Engine id for snmp V3 -->
+ <div class="form-group row"
+ *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
+ <label class="cd-col-form-label required"
+ for="engine_id">
+ <span i18n>Engine Id</span>
+ <cd-helper>
+ <span i18n>Unique identifier for the device (in hex).</span>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input id="engine_id"
+ class="form-control"
+ type="text"
+ formControlName="engine_id">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('engine_id', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('engine_id', frm, 'snmpEngineIdPattern')"
+ i18n>The value does not match the pattern: <strong>Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64.</strong></span>
+ </div>
+ </div>
+ <!-- Auth protocol for snmp V3 -->
+ <div class="form-group row"
+ *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
+ <label class="cd-col-form-label required"
+ for="auth_protocol"
+ i18n>Auth Protocol</label>
+ <div class="cd-col-form-input">
+ <select id="auth_protocol"
+ name="auth_protocol"
+ class="form-control"
+ formControlName="auth_protocol">
+ <option i18n
+ [ngValue]="null">-- Select auth protocol --</option>
+ <option *ngFor="let authProtocol of ['SHA', 'MD5']"
+ [value]="authProtocol">
+ {{ authProtocol }}
+ </option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('auth_protocol', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+ <!-- Privacy protocol for snmp V3 -->
+ <div class="form-group row"
+ *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
+ <label class="cd-col-form-label"
+ for="privacy_protocol"
+ i18n>Privacy Protocol</label>
+ <div class="cd-col-form-input">
+ <select id="privacy_protocol"
+ name="privacy_protocol"
+ class="form-control"
+ formControlName="privacy_protocol">
+ <option i18n
+ [ngValue]="null">-- Select privacy protocol --</option>
+ <option *ngFor="let privacyProtocol of ['DES', 'AES']"
+ [value]="privacyProtocol">
+ {{ privacyProtocol }}
+ </option>
+ </select>
+ </div>
+ </div>
+ <!-- Credentials -->
+ <fieldset>
+ <legend i18n>Credentials</legend>
+ <!-- snmp v2c snmp_community -->
+ <div class="form-group row"
+ *ngIf="serviceForm.controls.snmp_version.value === 'V2c'">
+ <label class="cd-col-form-label required"
+ for="snmp_community">
+ <span i18n>SNMP Community</span>
+ </label>
+ <div class="cd-col-form-input">
+ <input id="snmp_community"
+ class="form-control"
+ type="text"
+ formControlName="snmp_community">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('snmp_community', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+ <!-- snmp v3 auth username -->
+ <div class="form-group row"
+ *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
+ <label class="cd-col-form-label required"
+ for="snmp_v3_auth_username">
+ <span i18n>Username</span>
+ </label>
+ <div class="cd-col-form-input">
+ <input id="snmp_v3_auth_username"
+ class="form-control"
+ type="text"
+ formControlName="snmp_v3_auth_username">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('snmp_v3_auth_username', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+ <!-- snmp v3 auth password -->
+ <div class="form-group row"
+ *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
+ <label class="cd-col-form-label required"
+ for="snmp_v3_auth_password">
+ <span i18n>Password</span>
+ </label>
+ <div class="cd-col-form-input">
+ <input id="snmp_v3_auth_password"
+ class="form-control"
+ type="password"
+ formControlName="snmp_v3_auth_password">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('snmp_v3_auth_password', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+ <!-- snmp v3 priv password -->
+ <div class="form-group row"
+ *ngIf="serviceForm.controls.snmp_version.value === 'V3' && serviceForm.controls.privacy_protocol.value !== null && serviceForm.controls.privacy_protocol.value !== undefined">
+ <label class="cd-col-form-label required"
+ for="snmp_v3_priv_password">
+ <span i18n>Encryption</span>
+ </label>
+ <div class="cd-col-form-input">
+ <input id="snmp_v3_priv_password"
+ class="form-control"
+ type="password"
+ formControlName="snmp_v3_priv_password">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('snmp_v3_priv_password', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+ </fieldset>
+ </ng-container>
+ <!-- RGW, Ingress & iSCSI -->
+ <ng-container *ngIf="!serviceForm.controls.unmanaged.value && ['rgw', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)">
+ <!-- ssl -->
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="ssl"
+ type="checkbox"
+ formControlName="ssl">
+ <label class="custom-control-label"
+ for="ssl"
+ i18n>SSL</label>
+ </div>
+ </div>
+ </div>
+
+ <!-- ssl_cert -->
+ <div *ngIf="serviceForm.controls.ssl.value"
+ class="form-group row">
+ <label class="cd-col-form-label"
+ for="ssl_cert">
+ <span i18n>Certificate</span>
+ <cd-helper i18n>The SSL certificate in PEM format.</cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <textarea id="ssl_cert"
+ class="form-control resize-vertical text-monospace text-pre"
+ formControlName="ssl_cert"
+ rows="5">
+ </textarea>
+ <input type="file"
+ (change)="fileUpload($event.target.files, 'ssl_cert')">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('ssl_cert', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('ssl_cert', frm, 'pattern')"
+ i18n>Invalid SSL certificate.</span>
+ </div>
+ </div>
+
+ <!-- ssl_key -->
+ <div *ngIf="serviceForm.controls.ssl.value && !(['rgw', 'ingress'].includes(serviceForm.controls.service_type.value))"
+ class="form-group row">
+ <label class="cd-col-form-label"
+ for="ssl_key">
+ <span i18n>Private key</span>
+ <cd-helper i18n>The SSL private key in PEM format.</cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <textarea id="ssl_key"
+ class="form-control resize-vertical text-monospace text-pre"
+ formControlName="ssl_key"
+ rows="5">
+ </textarea>
+ <input type="file"
+ (change)="fileUpload($event.target.files,'ssl_key')">
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('ssl_key', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="serviceForm.showError('ssl_key', frm, 'pattern')"
+ i18n>Invalid SSL private key.</span>
+ </div>
+ </div>
+ </ng-container>
+ </div>
+
+ <div class="modal-footer">
+ <div class="text-right">
+ <cd-form-button-panel (submitActionEvent)="onSubmit()"
+ [form]="serviceForm"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>
+ </div>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.spec.ts
new file mode 100644
index 000000000..082fe9162
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.spec.ts
@@ -0,0 +1,550 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { By } from '@angular/platform-browser';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { ToastrModule } from 'ngx-toastr';
+
+import { CephServiceService } from '~/app/shared/api/ceph-service.service';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
+import { ServiceFormComponent } from './service-form.component';
+
+describe('ServiceFormComponent', () => {
+ let component: ServiceFormComponent;
+ let fixture: ComponentFixture<ServiceFormComponent>;
+ let cephServiceService: CephServiceService;
+ let form: CdFormGroup;
+ let formHelper: FormHelper;
+
+ configureTestBed({
+ declarations: [ServiceFormComponent],
+ providers: [NgbActiveModal],
+ imports: [
+ HttpClientTestingModule,
+ NgbTypeaheadModule,
+ ReactiveFormsModule,
+ RouterTestingModule,
+ SharedModule,
+ ToastrModule.forRoot()
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ServiceFormComponent);
+ component = fixture.componentInstance;
+ component.ngOnInit();
+ form = component.serviceForm;
+ formHelper = new FormHelper(form);
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('should test form', () => {
+ beforeEach(() => {
+ cephServiceService = TestBed.inject(CephServiceService);
+ spyOn(cephServiceService, 'create').and.stub();
+ });
+
+ it('should test placement (host)', () => {
+ formHelper.setValue('service_type', 'crash');
+ formHelper.setValue('placement', 'hosts');
+ formHelper.setValue('hosts', ['mgr0', 'mon0', 'osd0']);
+ formHelper.setValue('count', 2);
+ component.onSubmit();
+ expect(cephServiceService.create).toHaveBeenCalledWith({
+ service_type: 'crash',
+ placement: {
+ hosts: ['mgr0', 'mon0', 'osd0'],
+ count: 2
+ },
+ unmanaged: false
+ });
+ });
+
+ it('should test placement (label)', () => {
+ formHelper.setValue('service_type', 'mgr');
+ formHelper.setValue('placement', 'label');
+ formHelper.setValue('label', 'foo');
+ component.onSubmit();
+ expect(cephServiceService.create).toHaveBeenCalledWith({
+ service_type: 'mgr',
+ placement: {
+ label: 'foo'
+ },
+ unmanaged: false
+ });
+ });
+
+ it('should submit valid count', () => {
+ formHelper.setValue('count', 1);
+ component.onSubmit();
+ formHelper.expectValid('count');
+ });
+
+ it('should submit invalid count (1)', () => {
+ formHelper.setValue('count', 0);
+ component.onSubmit();
+ formHelper.expectError('count', 'min');
+ });
+
+ it('should submit invalid count (2)', () => {
+ formHelper.setValue('count', 'abc');
+ component.onSubmit();
+ formHelper.expectError('count', 'pattern');
+ });
+
+ it('should test unmanaged', () => {
+ formHelper.setValue('service_type', 'mgr');
+ formHelper.setValue('service_id', 'svc');
+ formHelper.setValue('placement', 'label');
+ formHelper.setValue('label', 'bar');
+ formHelper.setValue('unmanaged', true);
+ component.onSubmit();
+ expect(cephServiceService.create).toHaveBeenCalledWith({
+ service_type: 'mgr',
+ service_id: 'svc',
+ placement: {},
+ unmanaged: true
+ });
+ });
+
+ it('should test various services', () => {
+ _.forEach(
+ [
+ 'alertmanager',
+ 'crash',
+ 'grafana',
+ 'mds',
+ 'mgr',
+ 'mon',
+ 'node-exporter',
+ 'prometheus',
+ 'rbd-mirror'
+ ],
+ (serviceType) => {
+ formHelper.setValue('service_type', serviceType);
+ component.onSubmit();
+ expect(cephServiceService.create).toHaveBeenCalledWith({
+ service_type: serviceType,
+ placement: {},
+ unmanaged: false
+ });
+ }
+ );
+ });
+
+ describe('should test service nfs', () => {
+ beforeEach(() => {
+ formHelper.setValue('service_type', 'nfs');
+ });
+
+ it('should submit nfs', () => {
+ component.onSubmit();
+ expect(cephServiceService.create).toHaveBeenCalledWith({
+ service_type: 'nfs',
+ placement: {},
+ unmanaged: false
+ });
+ });
+ });
+
+ describe('should test service rgw', () => {
+ beforeEach(() => {
+ formHelper.setValue('service_type', 'rgw');
+ formHelper.setValue('service_id', 'svc');
+ });
+
+ it('should test rgw valid service id', () => {
+ formHelper.setValue('service_id', 'svc.realm.zone');
+ formHelper.expectValid('service_id');
+ formHelper.setValue('service_id', 'svc');
+ formHelper.expectValid('service_id');
+ });
+
+ it('should test rgw invalid service id', () => {
+ formHelper.setValue('service_id', '.');
+ formHelper.expectError('service_id', 'rgwPattern');
+ formHelper.setValue('service_id', 'svc.');
+ formHelper.expectError('service_id', 'rgwPattern');
+ formHelper.setValue('service_id', 'svc.realm');
+ formHelper.expectError('service_id', 'rgwPattern');
+ formHelper.setValue('service_id', 'svc.realm.');
+ formHelper.expectError('service_id', 'rgwPattern');
+ formHelper.setValue('service_id', '.svc.realm');
+ formHelper.expectError('service_id', 'rgwPattern');
+ formHelper.setValue('service_id', 'svc.realm.zone.');
+ formHelper.expectError('service_id', 'rgwPattern');
+ });
+
+ it('should submit rgw with realm and zone', () => {
+ formHelper.setValue('service_id', 'svc.my-realm.my-zone');
+ component.onSubmit();
+ expect(cephServiceService.create).toHaveBeenCalledWith({
+ service_type: 'rgw',
+ service_id: 'svc',
+ rgw_realm: 'my-realm',
+ rgw_zone: 'my-zone',
+ placement: {},
+ unmanaged: false,
+ ssl: false
+ });
+ });
+
+ it('should submit rgw with port and ssl enabled', () => {
+ formHelper.setValue('rgw_frontend_port', 1234);
+ formHelper.setValue('ssl', true);
+ component.onSubmit();
+ expect(cephServiceService.create).toHaveBeenCalledWith({
+ service_type: 'rgw',
+ service_id: 'svc',
+ placement: {},
+ unmanaged: false,
+ rgw_frontend_port: 1234,
+ rgw_frontend_ssl_certificate: '',
+ ssl: true
+ });
+ });
+
+ it('should submit valid rgw port (1)', () => {
+ formHelper.setValue('rgw_frontend_port', 1);
+ component.onSubmit();
+ formHelper.expectValid('rgw_frontend_port');
+ });
+
+ it('should submit valid rgw port (2)', () => {
+ formHelper.setValue('rgw_frontend_port', 65535);
+ component.onSubmit();
+ formHelper.expectValid('rgw_frontend_port');
+ });
+
+ it('should submit invalid rgw port (1)', () => {
+ formHelper.setValue('rgw_frontend_port', 0);
+ fixture.detectChanges();
+ formHelper.expectError('rgw_frontend_port', 'min');
+ });
+
+ it('should submit invalid rgw port (2)', () => {
+ formHelper.setValue('rgw_frontend_port', 65536);
+ fixture.detectChanges();
+ formHelper.expectError('rgw_frontend_port', 'max');
+ });
+
+ it('should submit invalid rgw port (3)', () => {
+ formHelper.setValue('rgw_frontend_port', 'abc');
+ component.onSubmit();
+ formHelper.expectError('rgw_frontend_port', 'pattern');
+ });
+
+ it('should submit rgw w/o port', () => {
+ formHelper.setValue('ssl', false);
+ component.onSubmit();
+ expect(cephServiceService.create).toHaveBeenCalledWith({
+ service_type: 'rgw',
+ service_id: 'svc',
+ placement: {},
+ unmanaged: false,
+ ssl: false
+ });
+ });
+
+ it('should not show private key field', () => {
+ formHelper.setValue('ssl', true);
+ fixture.detectChanges();
+ const ssl_key = fixture.debugElement.query(By.css('#ssl_key'));
+ expect(ssl_key).toBeNull();
+ });
+
+ it('should test .pem file', () => {
+ const pemCert = `
+-----BEGIN CERTIFICATE-----
+iJ5IbgzlKPssdYwuAEI3yPZxX/g5vKBrgcyD3LttLL/DlElq/1xCnwVrv7WROSNu
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+mn/S7BNBEC7AGe5ajmN+8hBTGdACUXe8rwMNrtTy/MwBZ0VpJsAAjJh+aptZh5yB
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
+-----END RSA PRIVATE KEY-----`;
+ formHelper.setValue('ssl', true);
+ formHelper.setValue('ssl_cert', pemCert);
+ fixture.detectChanges();
+ formHelper.expectValid('ssl_cert');
+ });
+ });
+
+ describe('should test service iscsi', () => {
+ beforeEach(() => {
+ formHelper.setValue('service_type', 'iscsi');
+ formHelper.setValue('pool', 'xyz');
+ formHelper.setValue('api_user', 'user');
+ formHelper.setValue('api_password', 'password');
+ formHelper.setValue('ssl', false);
+ });
+
+ it('should submit iscsi', () => {
+ component.onSubmit();
+ expect(cephServiceService.create).toHaveBeenCalledWith({
+ service_type: 'iscsi',
+ placement: {},
+ unmanaged: false,
+ pool: 'xyz',
+ api_user: 'user',
+ api_password: 'password',
+ api_secure: false
+ });
+ });
+
+ it('should submit iscsi with trusted ips', () => {
+ formHelper.setValue('ssl', true);
+ formHelper.setValue('trusted_ip_list', ' 172.16.0.5, 192.1.1.10 ');
+ component.onSubmit();
+ expect(cephServiceService.create).toHaveBeenCalledWith({
+ service_type: 'iscsi',
+ placement: {},
+ unmanaged: false,
+ pool: 'xyz',
+ api_user: 'user',
+ api_password: 'password',
+ api_secure: true,
+ ssl_cert: '',
+ ssl_key: '',
+ trusted_ip_list: '172.16.0.5, 192.1.1.10'
+ });
+ });
+
+ it('should submit iscsi with port', () => {
+ formHelper.setValue('api_port', 456);
+ component.onSubmit();
+ expect(cephServiceService.create).toHaveBeenCalledWith({
+ service_type: 'iscsi',
+ placement: {},
+ unmanaged: false,
+ pool: 'xyz',
+ api_user: 'user',
+ api_password: 'password',
+ api_secure: false,
+ api_port: 456
+ });
+ });
+
+ it('should submit valid iscsi port (1)', () => {
+ formHelper.setValue('api_port', 1);
+ component.onSubmit();
+ formHelper.expectValid('api_port');
+ });
+
+ it('should submit valid iscsi port (2)', () => {
+ formHelper.setValue('api_port', 65535);
+ component.onSubmit();
+ formHelper.expectValid('api_port');
+ });
+
+ it('should submit invalid iscsi port (1)', () => {
+ formHelper.setValue('api_port', 0);
+ fixture.detectChanges();
+ formHelper.expectError('api_port', 'min');
+ });
+
+ it('should submit invalid iscsi port (2)', () => {
+ formHelper.setValue('api_port', 65536);
+ fixture.detectChanges();
+ formHelper.expectError('api_port', 'max');
+ });
+
+ it('should submit invalid iscsi port (3)', () => {
+ formHelper.setValue('api_port', 'abc');
+ component.onSubmit();
+ formHelper.expectError('api_port', 'pattern');
+ });
+
+ it('should throw error when there is no pool', () => {
+ formHelper.expectErrorChange('pool', '', 'required');
+ });
+ });
+
+ describe('should test service ingress', () => {
+ beforeEach(() => {
+ formHelper.setValue('service_type', 'ingress');
+ formHelper.setValue('backend_service', 'rgw.foo');
+ formHelper.setValue('virtual_ip', '192.168.20.1/24');
+ formHelper.setValue('ssl', false);
+ });
+
+ it('should submit ingress', () => {
+ component.onSubmit();
+ expect(cephServiceService.create).toHaveBeenCalledWith({
+ service_type: 'ingress',
+ placement: {},
+ unmanaged: false,
+ backend_service: 'rgw.foo',
+ service_id: 'rgw.foo',
+ virtual_ip: '192.168.20.1/24',
+ virtual_interface_networks: null,
+ ssl: false
+ });
+ });
+
+ it('should pre-populate the service id', () => {
+ component.prePopulateId();
+ const prePopulatedID = component.serviceForm.getValue('service_id');
+ expect(prePopulatedID).toBe('rgw.foo');
+ });
+
+ it('should submit valid frontend and monitor port', () => {
+ // min value
+ formHelper.setValue('frontend_port', 1);
+ formHelper.setValue('monitor_port', 1);
+ fixture.detectChanges();
+ formHelper.expectValid('frontend_port');
+ formHelper.expectValid('monitor_port');
+
+ // max value
+ formHelper.setValue('frontend_port', 65535);
+ formHelper.setValue('monitor_port', 65535);
+ fixture.detectChanges();
+ formHelper.expectValid('frontend_port');
+ formHelper.expectValid('monitor_port');
+ });
+
+ it('should submit invalid frontend and monitor port', () => {
+ // min
+ formHelper.setValue('frontend_port', 0);
+ formHelper.setValue('monitor_port', 0);
+ fixture.detectChanges();
+ formHelper.expectError('frontend_port', 'min');
+ formHelper.expectError('monitor_port', 'min');
+
+ // max
+ formHelper.setValue('frontend_port', 65536);
+ formHelper.setValue('monitor_port', 65536);
+ fixture.detectChanges();
+ formHelper.expectError('frontend_port', 'max');
+ formHelper.expectError('monitor_port', 'max');
+
+ // pattern
+ formHelper.setValue('frontend_port', 'abc');
+ formHelper.setValue('monitor_port', 'abc');
+ component.onSubmit();
+ formHelper.expectError('frontend_port', 'pattern');
+ formHelper.expectError('monitor_port', 'pattern');
+ });
+
+ it('should not show private key field with ssl enabled', () => {
+ formHelper.setValue('ssl', true);
+ fixture.detectChanges();
+ const ssl_key = fixture.debugElement.query(By.css('#ssl_key'));
+ expect(ssl_key).toBeNull();
+ });
+
+ it('should test .pem file with ssl enabled', () => {
+ const pemCert = `
+-----BEGIN CERTIFICATE-----
+iJ5IbgzlKPssdYwuAEI3yPZxX/g5vKBrgcyD3LttLL/DlElq/1xCnwVrv7WROSNu
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+mn/S7BNBEC7AGe5ajmN+8hBTGdACUXe8rwMNrtTy/MwBZ0VpJsAAjJh+aptZh5yB
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
+-----END RSA PRIVATE KEY-----`;
+ formHelper.setValue('ssl', true);
+ formHelper.setValue('ssl_cert', pemCert);
+ fixture.detectChanges();
+ formHelper.expectValid('ssl_cert');
+ });
+ });
+
+ describe('should test service snmp-gateway', () => {
+ beforeEach(() => {
+ formHelper.setValue('service_type', 'snmp-gateway');
+ formHelper.setValue('snmp_destination', '192.168.20.1:8443');
+ });
+
+ it('should test snmp-gateway service with V2c', () => {
+ formHelper.setValue('snmp_version', 'V2c');
+ formHelper.setValue('snmp_community', 'public');
+ component.onSubmit();
+ expect(cephServiceService.create).toHaveBeenCalledWith({
+ service_type: 'snmp-gateway',
+ placement: {},
+ unmanaged: false,
+ snmp_version: 'V2c',
+ snmp_destination: '192.168.20.1:8443',
+ credentials: {
+ snmp_community: 'public'
+ }
+ });
+ });
+
+ it('should test snmp-gateway service with V3', () => {
+ formHelper.setValue('snmp_version', 'V3');
+ formHelper.setValue('engine_id', '800C53F00000');
+ formHelper.setValue('auth_protocol', 'SHA');
+ formHelper.setValue('privacy_protocol', 'DES');
+ formHelper.setValue('snmp_v3_auth_username', 'testuser');
+ formHelper.setValue('snmp_v3_auth_password', 'testpass');
+ formHelper.setValue('snmp_v3_priv_password', 'testencrypt');
+ component.onSubmit();
+ expect(cephServiceService.create).toHaveBeenCalledWith({
+ service_type: 'snmp-gateway',
+ placement: {},
+ unmanaged: false,
+ snmp_version: 'V3',
+ snmp_destination: '192.168.20.1:8443',
+ engine_id: '800C53F00000',
+ auth_protocol: 'SHA',
+ privacy_protocol: 'DES',
+ credentials: {
+ snmp_v3_auth_username: 'testuser',
+ snmp_v3_auth_password: 'testpass',
+ snmp_v3_priv_password: 'testencrypt'
+ }
+ });
+ });
+
+ it('should submit invalid snmp destination', () => {
+ formHelper.setValue('snmp_version', 'V2c');
+ formHelper.setValue('snmp_destination', '192.168.20.1');
+ formHelper.setValue('snmp_community', 'public');
+ formHelper.expectError('snmp_destination', 'snmpDestinationPattern');
+ });
+
+ it('should submit invalid snmp engine id', () => {
+ formHelper.setValue('snmp_version', 'V3');
+ formHelper.setValue('snmp_destination', '192.168.20.1');
+ formHelper.setValue('engine_id', 'AABBCCDDE');
+ formHelper.setValue('auth_protocol', 'SHA');
+ formHelper.setValue('privacy_protocol', 'DES');
+ formHelper.setValue('snmp_v3_auth_username', 'testuser');
+ formHelper.setValue('snmp_v3_auth_password', 'testpass');
+
+ formHelper.expectError('engine_id', 'snmpEngineIdPattern');
+ });
+ });
+
+ describe('check edit fields', () => {
+ beforeEach(() => {
+ component.editing = true;
+ });
+
+ it('should check whether edit field is correctly loaded', () => {
+ const cephServiceSpy = spyOn(cephServiceService, 'list').and.callThrough();
+ component.ngOnInit();
+ expect(cephServiceSpy).toBeCalledTimes(2);
+ expect(component.action).toBe('Edit');
+ const serviceType = fixture.debugElement.query(By.css('#service_type')).nativeElement;
+ const serviceId = fixture.debugElement.query(By.css('#service_id')).nativeElement;
+ expect(serviceType.disabled).toBeTruthy();
+ expect(serviceId.disabled).toBeTruthy();
+ });
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts
new file mode 100644
index 000000000..4cab78437
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts
@@ -0,0 +1,678 @@
+import { Component, Input, OnInit, ViewChild } from '@angular/core';
+import { AbstractControl, Validators } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+
+import { NgbActiveModal, NgbTypeahead } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { merge, Observable, Subject } from 'rxjs';
+import { debounceTime, distinctUntilChanged, filter, map } from 'rxjs/operators';
+
+import { CephServiceService } from '~/app/shared/api/ceph-service.service';
+import { HostService } from '~/app/shared/api/host.service';
+import { PoolService } from '~/app/shared/api/pool.service';
+import { SelectMessages } from '~/app/shared/components/select/select-messages.model';
+import { SelectOption } from '~/app/shared/components/select/select-option.model';
+import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
+import { CdForm } from '~/app/shared/forms/cd-form';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { CephServiceSpec } from '~/app/shared/models/service.interface';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+
+@Component({
+ selector: 'cd-service-form',
+ templateUrl: './service-form.component.html',
+ styleUrls: ['./service-form.component.scss']
+})
+export class ServiceFormComponent extends CdForm implements OnInit {
+ readonly RGW_SVC_ID_PATTERN = /^([^.]+)(\.([^.]+)\.([^.]+))?$/;
+ readonly SNMP_DESTINATION_PATTERN = /^[^\:]+:[0-9]/;
+ readonly SNMP_ENGINE_ID_PATTERN = /^[0-9A-Fa-f]{10,64}/g;
+ readonly INGRESS_SUPPORTED_SERVICE_TYPES = ['rgw', 'nfs'];
+ @ViewChild(NgbTypeahead, { static: false })
+ typeahead: NgbTypeahead;
+
+ @Input() hiddenServices: string[] = [];
+
+ @Input() editing = false;
+
+ @Input() serviceName: string;
+
+ @Input() serviceType: string;
+
+ serviceForm: CdFormGroup;
+ action: string;
+ resource: string;
+ serviceTypes: string[] = [];
+ serviceIds: string[] = [];
+ hosts: any;
+ labels: string[];
+ labelClick = new Subject<string>();
+ labelFocus = new Subject<string>();
+ pools: Array<object>;
+ services: Array<CephServiceSpec> = [];
+ pageURL: string;
+ serviceList: CephServiceSpec[];
+
+ constructor(
+ public actionLabels: ActionLabelsI18n,
+ private cephServiceService: CephServiceService,
+ private formBuilder: CdFormBuilder,
+ private hostService: HostService,
+ private poolService: PoolService,
+ private router: Router,
+ private taskWrapperService: TaskWrapperService,
+ private route: ActivatedRoute,
+ public activeModal: NgbActiveModal
+ ) {
+ super();
+ this.resource = $localize`service`;
+ this.hosts = {
+ options: [],
+ messages: new SelectMessages({
+ empty: $localize`There are no hosts.`,
+ filter: $localize`Filter hosts`
+ })
+ };
+ this.createForm();
+ }
+
+ createForm() {
+ this.serviceForm = this.formBuilder.group({
+ // Global
+ service_type: [null, [Validators.required]],
+ service_id: [
+ null,
+ [
+ CdValidators.requiredIf({
+ service_type: 'mds'
+ }),
+ CdValidators.requiredIf({
+ service_type: 'nfs'
+ }),
+ CdValidators.requiredIf({
+ service_type: 'iscsi'
+ }),
+ CdValidators.requiredIf({
+ service_type: 'ingress'
+ }),
+ CdValidators.composeIf(
+ {
+ service_type: 'rgw'
+ },
+ [
+ Validators.required,
+ CdValidators.custom('rgwPattern', (value: string) => {
+ if (_.isEmpty(value)) {
+ return false;
+ }
+ return !this.RGW_SVC_ID_PATTERN.test(value);
+ })
+ ]
+ ),
+ CdValidators.custom('uniqueName', (service_id: string) => {
+ return this.serviceIds && this.serviceIds.includes(service_id);
+ })
+ ]
+ ],
+ placement: ['hosts'],
+ label: [
+ null,
+ [
+ CdValidators.requiredIf({
+ placement: 'label',
+ unmanaged: false
+ })
+ ]
+ ],
+ hosts: [[]],
+ count: [null, [CdValidators.number(false)]],
+ unmanaged: [false],
+ // iSCSI
+ pool: [
+ null,
+ [
+ CdValidators.requiredIf({
+ service_type: 'iscsi'
+ })
+ ]
+ ],
+ // RGW
+ rgw_frontend_port: [null, [CdValidators.number(false)]],
+ // iSCSI
+ trusted_ip_list: [null],
+ api_port: [null, [CdValidators.number(false)]],
+ api_user: [
+ null,
+ [
+ CdValidators.requiredIf({
+ service_type: 'iscsi',
+ unmanaged: false
+ })
+ ]
+ ],
+ api_password: [
+ null,
+ [
+ CdValidators.requiredIf({
+ service_type: 'iscsi',
+ unmanaged: false
+ })
+ ]
+ ],
+ // Ingress
+ backend_service: [
+ null,
+ [
+ CdValidators.requiredIf({
+ service_type: 'ingress'
+ })
+ ]
+ ],
+ virtual_ip: [
+ null,
+ [
+ CdValidators.requiredIf({
+ service_type: 'ingress'
+ })
+ ]
+ ],
+ frontend_port: [
+ null,
+ [
+ CdValidators.number(false),
+ CdValidators.requiredIf({
+ service_type: 'ingress'
+ })
+ ]
+ ],
+ monitor_port: [
+ null,
+ [
+ CdValidators.number(false),
+ CdValidators.requiredIf({
+ service_type: 'ingress'
+ })
+ ]
+ ],
+ virtual_interface_networks: [null],
+ // RGW, Ingress & iSCSI
+ ssl: [false],
+ ssl_cert: [
+ '',
+ [
+ CdValidators.composeIf(
+ {
+ service_type: 'rgw',
+ unmanaged: false,
+ ssl: true
+ },
+ [Validators.required, CdValidators.pemCert()]
+ ),
+ CdValidators.composeIf(
+ {
+ service_type: 'iscsi',
+ unmanaged: false,
+ ssl: true
+ },
+ [Validators.required, CdValidators.sslCert()]
+ ),
+ CdValidators.composeIf(
+ {
+ service_type: 'ingress',
+ unmanaged: false,
+ ssl: true
+ },
+ [Validators.required, CdValidators.pemCert()]
+ )
+ ]
+ ],
+ ssl_key: [
+ '',
+ [
+ CdValidators.composeIf(
+ {
+ service_type: 'iscsi',
+ unmanaged: false,
+ ssl: true
+ },
+ [Validators.required, CdValidators.sslPrivKey()]
+ )
+ ]
+ ],
+ // snmp-gateway
+ snmp_version: [
+ null,
+ [
+ CdValidators.requiredIf({
+ service_type: 'snmp-gateway'
+ })
+ ]
+ ],
+ snmp_destination: [
+ null,
+ {
+ validators: [
+ CdValidators.requiredIf({
+ service_type: 'snmp-gateway'
+ }),
+ CdValidators.custom('snmpDestinationPattern', (value: string) => {
+ if (_.isEmpty(value)) {
+ return false;
+ }
+ return !this.SNMP_DESTINATION_PATTERN.test(value);
+ })
+ ]
+ }
+ ],
+ engine_id: [
+ null,
+ [
+ CdValidators.requiredIf({
+ service_type: 'snmp-gateway'
+ }),
+ CdValidators.custom('snmpEngineIdPattern', (value: string) => {
+ if (_.isEmpty(value)) {
+ return false;
+ }
+ return !this.SNMP_ENGINE_ID_PATTERN.test(value);
+ })
+ ]
+ ],
+ auth_protocol: [
+ 'SHA',
+ [
+ CdValidators.requiredIf({
+ service_type: 'snmp-gateway'
+ })
+ ]
+ ],
+ privacy_protocol: [null],
+ snmp_community: [
+ null,
+ [
+ CdValidators.requiredIf({
+ snmp_version: 'V2c'
+ })
+ ]
+ ],
+ snmp_v3_auth_username: [
+ null,
+ [
+ CdValidators.requiredIf({
+ service_type: 'snmp-gateway'
+ })
+ ]
+ ],
+ snmp_v3_auth_password: [
+ null,
+ [
+ CdValidators.requiredIf({
+ service_type: 'snmp-gateway'
+ })
+ ]
+ ],
+ snmp_v3_priv_password: [
+ null,
+ [
+ CdValidators.requiredIf({
+ privacy_protocol: { op: '!empty' }
+ })
+ ]
+ ]
+ });
+ }
+
+ ngOnInit(): void {
+ this.action = this.actionLabels.CREATE;
+ if (this.router.url.includes('services/(modal:create')) {
+ this.pageURL = 'services';
+ } else if (this.router.url.includes('services/(modal:edit')) {
+ this.editing = true;
+ this.pageURL = 'services';
+ this.route.params.subscribe((params: { type: string; name: string }) => {
+ this.serviceName = params.name;
+ this.serviceType = params.type;
+ });
+ }
+
+ this.cephServiceService.list().subscribe((services: CephServiceSpec[]) => {
+ this.serviceList = services;
+ this.services = services.filter((service: any) =>
+ this.INGRESS_SUPPORTED_SERVICE_TYPES.includes(service.service_type)
+ );
+ });
+
+ this.cephServiceService.getKnownTypes().subscribe((resp: Array<string>) => {
+ // Remove service types:
+ // osd - This is deployed a different way.
+ // container - This should only be used in the CLI.
+ this.hiddenServices.push('osd', 'container');
+
+ this.serviceTypes = _.difference(resp, this.hiddenServices).sort();
+ });
+ this.hostService.list('false').subscribe((resp: object[]) => {
+ const options: SelectOption[] = [];
+ _.forEach(resp, (host: object) => {
+ if (_.get(host, 'sources.orchestrator', false)) {
+ const option = new SelectOption(false, _.get(host, 'hostname'), '');
+ options.push(option);
+ }
+ });
+ this.hosts.options = [...options];
+ });
+ this.hostService.getLabels().subscribe((resp: string[]) => {
+ this.labels = resp;
+ });
+ this.poolService.getList().subscribe((resp: Array<object>) => {
+ this.pools = resp;
+ });
+
+ if (this.editing) {
+ this.action = this.actionLabels.EDIT;
+ this.disableForEditing(this.serviceType);
+ this.cephServiceService.list(this.serviceName).subscribe((response: CephServiceSpec[]) => {
+ const formKeys = ['service_type', 'service_id', 'unmanaged'];
+ formKeys.forEach((keys) => {
+ this.serviceForm.get(keys).setValue(response[0][keys]);
+ });
+ if (!response[0]['unmanaged']) {
+ const placementKey = Object.keys(response[0]['placement'])[0];
+ let placementValue: string;
+ ['hosts', 'label'].indexOf(placementKey) >= 0
+ ? (placementValue = placementKey)
+ : (placementValue = 'hosts');
+ this.serviceForm.get('placement').setValue(placementValue);
+ this.serviceForm.get('count').setValue(response[0]['placement']['count']);
+ if (response[0]?.placement[placementValue]) {
+ this.serviceForm.get(placementValue).setValue(response[0]?.placement[placementValue]);
+ }
+ }
+ switch (this.serviceType) {
+ case 'iscsi':
+ const specKeys = ['pool', 'api_password', 'api_user', 'trusted_ip_list', 'api_port'];
+ specKeys.forEach((key) => {
+ this.serviceForm.get(key).setValue(response[0].spec[key]);
+ });
+ this.serviceForm.get('ssl').setValue(response[0].spec?.api_secure);
+ if (response[0].spec?.api_secure) {
+ this.serviceForm.get('ssl_cert').setValue(response[0].spec?.ssl_cert);
+ this.serviceForm.get('ssl_key').setValue(response[0].spec?.ssl_key);
+ }
+ break;
+ case 'rgw':
+ this.serviceForm.get('rgw_frontend_port').setValue(response[0].spec?.rgw_frontend_port);
+ this.serviceForm.get('ssl').setValue(response[0].spec?.ssl);
+ if (response[0].spec?.ssl) {
+ this.serviceForm
+ .get('ssl_cert')
+ .setValue(response[0].spec?.rgw_frontend_ssl_certificate);
+ }
+ break;
+ case 'ingress':
+ const ingressSpecKeys = [
+ 'backend_service',
+ 'virtual_ip',
+ 'frontend_port',
+ 'monitor_port',
+ 'virtual_interface_networks',
+ 'ssl'
+ ];
+ ingressSpecKeys.forEach((key) => {
+ this.serviceForm.get(key).setValue(response[0].spec[key]);
+ });
+ if (response[0].spec?.ssl) {
+ this.serviceForm.get('ssl_cert').setValue(response[0].spec?.ssl_cert);
+ this.serviceForm.get('ssl_key').setValue(response[0].spec?.ssl_key);
+ }
+ break;
+ case 'snmp-gateway':
+ const snmpCommonSpecKeys = ['snmp_version', 'snmp_destination'];
+ snmpCommonSpecKeys.forEach((key) => {
+ this.serviceForm.get(key).setValue(response[0].spec[key]);
+ });
+ if (this.serviceForm.getValue('snmp_version') === 'V3') {
+ const snmpV3SpecKeys = [
+ 'engine_id',
+ 'auth_protocol',
+ 'privacy_protocol',
+ 'snmp_v3_auth_username',
+ 'snmp_v3_auth_password',
+ 'snmp_v3_priv_password'
+ ];
+ snmpV3SpecKeys.forEach((key) => {
+ if (key !== null) {
+ if (
+ key === 'snmp_v3_auth_username' ||
+ key === 'snmp_v3_auth_password' ||
+ key === 'snmp_v3_priv_password'
+ ) {
+ this.serviceForm.get(key).setValue(response[0].spec['credentials'][key]);
+ } else {
+ this.serviceForm.get(key).setValue(response[0].spec[key]);
+ }
+ }
+ });
+ } else {
+ this.serviceForm
+ .get('snmp_community')
+ .setValue(response[0].spec['credentials']['snmp_community']);
+ }
+ break;
+ }
+ });
+ }
+ }
+
+ getServiceIds(selectedServiceType: string) {
+ this.serviceIds = this.serviceList
+ .filter((service) => service['service_type'] === selectedServiceType)
+ .map((service) => service['service_id']);
+ }
+
+ disableForEditing(serviceType: string) {
+ const disableForEditKeys = ['service_type', 'service_id'];
+ disableForEditKeys.forEach((key) => {
+ this.serviceForm.get(key).disable();
+ });
+ switch (serviceType) {
+ case 'ingress':
+ this.serviceForm.get('backend_service').disable();
+ }
+ }
+
+ searchLabels = (text$: Observable<string>) => {
+ return merge(
+ text$.pipe(debounceTime(200), distinctUntilChanged()),
+ this.labelFocus,
+ this.labelClick.pipe(filter(() => !this.typeahead.isPopupOpen()))
+ ).pipe(
+ map((value) =>
+ this.labels
+ .filter((label: string) => label.toLowerCase().indexOf(value.toLowerCase()) > -1)
+ .slice(0, 10)
+ )
+ );
+ };
+
+ fileUpload(files: FileList, controlName: string) {
+ const file: File = files[0];
+ const reader = new FileReader();
+ reader.addEventListener('load', (event: ProgressEvent<FileReader>) => {
+ const control: AbstractControl = this.serviceForm.get(controlName);
+ control.setValue(event.target.result);
+ control.markAsDirty();
+ control.markAsTouched();
+ control.updateValueAndValidity();
+ });
+ reader.readAsText(file, 'utf8');
+ }
+
+ prePopulateId() {
+ const control: AbstractControl = this.serviceForm.get('service_id');
+ const backendService = this.serviceForm.getValue('backend_service');
+ // Set Id as read-only
+ control.reset({ value: backendService, disabled: true });
+ }
+
+ onSubmit() {
+ const self = this;
+ const values: object = this.serviceForm.getRawValue();
+ const serviceType: string = values['service_type'];
+ let taskUrl = `service/${URLVerbs.CREATE}`;
+ if (this.editing) {
+ taskUrl = `service/${URLVerbs.EDIT}`;
+ }
+ const serviceSpec: object = {
+ service_type: serviceType,
+ placement: {},
+ unmanaged: values['unmanaged']
+ };
+ let svcId: string;
+ if (serviceType === 'rgw') {
+ const svcIdMatch = values['service_id'].match(this.RGW_SVC_ID_PATTERN);
+ svcId = svcIdMatch[1];
+ if (svcIdMatch[3]) {
+ serviceSpec['rgw_realm'] = svcIdMatch[3];
+ serviceSpec['rgw_zone'] = svcIdMatch[4];
+ }
+ } else {
+ svcId = values['service_id'];
+ }
+ const serviceId: string = svcId;
+ let serviceName: string = serviceType;
+ if (_.isString(serviceId) && !_.isEmpty(serviceId)) {
+ serviceName = `${serviceType}.${serviceId}`;
+ serviceSpec['service_id'] = serviceId;
+ }
+
+ // These services has some fields to be
+ // filled out even if unmanaged is true
+ switch (serviceType) {
+ case 'ingress':
+ serviceSpec['backend_service'] = values['backend_service'];
+ serviceSpec['service_id'] = values['backend_service'];
+ if (_.isNumber(values['frontend_port']) && values['frontend_port'] > 0) {
+ serviceSpec['frontend_port'] = values['frontend_port'];
+ }
+ if (_.isString(values['virtual_ip']) && !_.isEmpty(values['virtual_ip'])) {
+ serviceSpec['virtual_ip'] = values['virtual_ip'].trim();
+ }
+ if (_.isNumber(values['monitor_port']) && values['monitor_port'] > 0) {
+ serviceSpec['monitor_port'] = values['monitor_port'];
+ }
+ break;
+
+ case 'iscsi':
+ serviceSpec['pool'] = values['pool'];
+ break;
+
+ case 'snmp-gateway':
+ serviceSpec['credentials'] = {};
+ serviceSpec['snmp_version'] = values['snmp_version'];
+ serviceSpec['snmp_destination'] = values['snmp_destination'];
+ if (values['snmp_version'] === 'V3') {
+ serviceSpec['engine_id'] = values['engine_id'];
+ serviceSpec['auth_protocol'] = values['auth_protocol'];
+ serviceSpec['credentials']['snmp_v3_auth_username'] = values['snmp_v3_auth_username'];
+ serviceSpec['credentials']['snmp_v3_auth_password'] = values['snmp_v3_auth_password'];
+ if (values['privacy_protocol'] !== null) {
+ serviceSpec['privacy_protocol'] = values['privacy_protocol'];
+ serviceSpec['credentials']['snmp_v3_priv_password'] = values['snmp_v3_priv_password'];
+ }
+ } else {
+ serviceSpec['credentials']['snmp_community'] = values['snmp_community'];
+ }
+ break;
+ }
+
+ if (!values['unmanaged']) {
+ switch (values['placement']) {
+ case 'hosts':
+ if (values['hosts'].length > 0) {
+ serviceSpec['placement']['hosts'] = values['hosts'];
+ }
+ break;
+ case 'label':
+ serviceSpec['placement']['label'] = values['label'];
+ break;
+ }
+ if (_.isNumber(values['count']) && values['count'] > 0) {
+ serviceSpec['placement']['count'] = values['count'];
+ }
+ switch (serviceType) {
+ case 'rgw':
+ if (_.isNumber(values['rgw_frontend_port']) && values['rgw_frontend_port'] > 0) {
+ serviceSpec['rgw_frontend_port'] = values['rgw_frontend_port'];
+ }
+ serviceSpec['ssl'] = values['ssl'];
+ if (values['ssl']) {
+ serviceSpec['rgw_frontend_ssl_certificate'] = values['ssl_cert']?.trim();
+ }
+ break;
+ case 'iscsi':
+ if (_.isString(values['trusted_ip_list']) && !_.isEmpty(values['trusted_ip_list'])) {
+ serviceSpec['trusted_ip_list'] = values['trusted_ip_list'].trim();
+ }
+ if (_.isNumber(values['api_port']) && values['api_port'] > 0) {
+ serviceSpec['api_port'] = values['api_port'];
+ }
+ serviceSpec['api_user'] = values['api_user'];
+ serviceSpec['api_password'] = values['api_password'];
+ serviceSpec['api_secure'] = values['ssl'];
+ if (values['ssl']) {
+ serviceSpec['ssl_cert'] = values['ssl_cert']?.trim();
+ serviceSpec['ssl_key'] = values['ssl_key']?.trim();
+ }
+ break;
+ case 'ingress':
+ serviceSpec['ssl'] = values['ssl'];
+ if (values['ssl']) {
+ serviceSpec['ssl_cert'] = values['ssl_cert']?.trim();
+ serviceSpec['ssl_key'] = values['ssl_key']?.trim();
+ }
+ serviceSpec['virtual_interface_networks'] = values['virtual_interface_networks'];
+ break;
+ }
+ }
+
+ this.taskWrapperService
+ .wrapTaskAroundCall({
+ task: new FinishedTask(taskUrl, {
+ service_name: serviceName
+ }),
+ call: this.editing
+ ? this.cephServiceService.update(serviceSpec)
+ : this.cephServiceService.create(serviceSpec)
+ })
+ .subscribe({
+ error() {
+ self.serviceForm.setErrors({ cdSubmitButton: true });
+ },
+ complete: () => {
+ this.pageURL === 'services'
+ ? this.router.navigate([this.pageURL, { outlets: { modal: null } }])
+ : this.activeModal.close();
+ }
+ });
+ }
+
+ clearValidations() {
+ const snmpVersion = this.serviceForm.getValue('snmp_version');
+ const privacyProtocol = this.serviceForm.getValue('privacy_protocol');
+ if (snmpVersion === 'V3') {
+ this.serviceForm.get('snmp_community').clearValidators();
+ } else {
+ this.serviceForm.get('engine_id').clearValidators();
+ this.serviceForm.get('auth_protocol').clearValidators();
+ this.serviceForm.get('privacy_protocol').clearValidators();
+ this.serviceForm.get('snmp_v3_auth_username').clearValidators();
+ this.serviceForm.get('snmp_v3_auth_password').clearValidators();
+ }
+ if (privacyProtocol === null) {
+ this.serviceForm.get('snmp_v3_priv_password').clearValidators();
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.html
new file mode 100644
index 000000000..36ab431fc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.html
@@ -0,0 +1,25 @@
+<cd-orchestrator-doc-panel *ngIf="showDocPanel"></cd-orchestrator-doc-panel>
+<ng-container *ngIf="orchStatus?.available">
+ <cd-table [data]="services"
+ [columns]="columns"
+ identifier="service_name"
+ forceIdentifier="true"
+ columnMode="flex"
+ selectionType="single"
+ [autoReload]="5000"
+ (fetchData)="getServices($event)"
+ [hasDetails]="hasDetails"
+ (setExpandedRow)="setExpandedRow($event)"
+ (updateSelection)="updateSelection($event)">
+ <cd-table-actions class="table-actions"
+ [permission]="permissions.hosts"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ <cd-service-details cdTableDetail
+ [permissions]="permissions"
+ [selection]="expandedRow">
+ </cd-service-details>
+ </cd-table>
+</ng-container>
+<router-outlet name="modal"></router-outlet>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.spec.ts
new file mode 100644
index 000000000..69d28e705
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.spec.ts
@@ -0,0 +1,97 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { CephModule } from '~/app/ceph/ceph.module';
+import { CoreModule } from '~/app/core/core.module';
+import { CephServiceService } from '~/app/shared/api/ceph-service.service';
+import { OrchestratorService } from '~/app/shared/api/orchestrator.service';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { Permissions } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { ServicesComponent } from './services.component';
+
+describe('ServicesComponent', () => {
+ let component: ServicesComponent;
+ let fixture: ComponentFixture<ServicesComponent>;
+
+ const fakeAuthStorageService = {
+ getPermissions: () => {
+ return new Permissions({ hosts: ['read'] });
+ }
+ };
+
+ const services = [
+ {
+ service_type: 'osd',
+ service_name: 'osd',
+ status: {
+ size: 3,
+ running: 3,
+ last_refresh: '2020-02-25T04:33:26.465699'
+ }
+ },
+ {
+ service_type: 'crash',
+ service_name: 'crash',
+ status: {
+ size: 1,
+ running: 1,
+ last_refresh: '2020-02-25T04:33:26.465766'
+ }
+ }
+ ];
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ CephModule,
+ CoreModule,
+ SharedModule,
+ HttpClientTestingModule,
+ RouterTestingModule,
+ ToastrModule.forRoot()
+ ],
+ providers: [{ provide: AuthStorageService, useValue: fakeAuthStorageService }]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ServicesComponent);
+ component = fixture.componentInstance;
+ const orchService = TestBed.inject(OrchestratorService);
+ const cephServiceService = TestBed.inject(CephServiceService);
+ spyOn(orchService, 'status').and.returnValue(of({ available: true }));
+ spyOn(cephServiceService, 'list').and.returnValue(of(services));
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should have columns that are sortable', () => {
+ expect(
+ component.columns
+ // Filter the 'Expand/Collapse Row' column.
+ .filter((column) => !(column.cellClass === 'cd-datatable-expand-collapse'))
+ // Filter the 'Placement' column.
+ .filter((column) => !(column.prop === ''))
+ .every((column) => Boolean(column.prop))
+ ).toBeTruthy();
+ });
+
+ it('should return all services', () => {
+ component.getServices(new CdTableFetchDataContext(() => undefined));
+ expect(component.services.length).toBe(2);
+ });
+
+ it('should not display doc panel if orchestrator is available', () => {
+ expect(component.showDocPanel).toBeFalsy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.ts
new file mode 100644
index 000000000..318a54a6e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.ts
@@ -0,0 +1,259 @@
+import { Component, Input, OnChanges, OnInit, ViewChild } from '@angular/core';
+import { Router } from '@angular/router';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { delay } from 'rxjs/operators';
+
+import { CephServiceService } from '~/app/shared/api/ceph-service.service';
+import { OrchestratorService } from '~/app/shared/api/orchestrator.service';
+import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
+import { TableComponent } from '~/app/shared/datatable/table/table.component';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { OrchestratorFeature } from '~/app/shared/models/orchestrator.enum';
+import { OrchestratorStatus } from '~/app/shared/models/orchestrator.interface';
+import { Permissions } from '~/app/shared/models/permissions';
+import { CephServiceSpec } from '~/app/shared/models/service.interface';
+import { RelativeDatePipe } from '~/app/shared/pipes/relative-date.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { URLBuilderService } from '~/app/shared/services/url-builder.service';
+import { PlacementPipe } from './placement.pipe';
+import { ServiceFormComponent } from './service-form/service-form.component';
+
+const BASE_URL = 'services';
+
+@Component({
+ selector: 'cd-services',
+ templateUrl: './services.component.html',
+ styleUrls: ['./services.component.scss'],
+ providers: [{ provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }]
+})
+export class ServicesComponent extends ListWithDetails implements OnChanges, OnInit {
+ @ViewChild(TableComponent, { static: true })
+ table: TableComponent;
+
+ @Input() hostname: string;
+
+ // Do not display these columns
+ @Input() hiddenColumns: string[] = [];
+
+ @Input() hiddenServices: string[] = [];
+
+ @Input() hasDetails = true;
+
+ @Input() routedModal = true;
+
+ permissions: Permissions;
+ tableActions: CdTableAction[];
+ showDocPanel = false;
+ bsModalRef: NgbModalRef;
+
+ orchStatus: OrchestratorStatus;
+ actionOrchFeatures = {
+ create: [OrchestratorFeature.SERVICE_CREATE],
+ update: [OrchestratorFeature.SERVICE_EDIT],
+ delete: [OrchestratorFeature.SERVICE_DELETE]
+ };
+
+ columns: Array<CdTableColumn> = [];
+ services: Array<CephServiceSpec> = [];
+ isLoadingServices = false;
+ selection: CdTableSelection = new CdTableSelection();
+
+ constructor(
+ private actionLabels: ActionLabelsI18n,
+ private authStorageService: AuthStorageService,
+ private modalService: ModalService,
+ private orchService: OrchestratorService,
+ private cephServiceService: CephServiceService,
+ private relativeDatePipe: RelativeDatePipe,
+ private taskWrapperService: TaskWrapperService,
+ private router: Router
+ ) {
+ super();
+ this.permissions = this.authStorageService.getPermissions();
+ this.tableActions = [
+ {
+ permission: 'create',
+ icon: Icons.add,
+ click: () => this.openModal(),
+ name: this.actionLabels.CREATE,
+ canBePrimary: (selection: CdTableSelection) => !selection.hasSelection,
+ disable: (selection: CdTableSelection) => this.getDisable('create', selection)
+ },
+ {
+ permission: 'update',
+ icon: Icons.edit,
+ click: () => this.openModal(true),
+ name: this.actionLabels.EDIT,
+ disable: (selection: CdTableSelection) => this.getDisable('update', selection)
+ },
+ {
+ permission: 'delete',
+ icon: Icons.destroy,
+ click: () => this.deleteAction(),
+ name: this.actionLabels.DELETE,
+ disable: (selection: CdTableSelection) => this.getDisable('delete', selection)
+ }
+ ];
+ }
+
+ openModal(edit = false) {
+ if (this.routedModal) {
+ edit
+ ? this.router.navigate([
+ BASE_URL,
+ {
+ outlets: {
+ modal: [
+ URLVerbs.EDIT,
+ this.selection.first().service_type,
+ this.selection.first().service_name
+ ]
+ }
+ }
+ ])
+ : this.router.navigate([BASE_URL, { outlets: { modal: [URLVerbs.CREATE] } }]);
+ } else {
+ let initialState = {};
+ edit
+ ? (initialState = {
+ serviceName: this.selection.first()?.service_name,
+ serviceType: this.selection?.first()?.service_type,
+ hiddenServices: this.hiddenServices,
+ editing: edit
+ })
+ : (initialState = {
+ hiddenServices: this.hiddenServices,
+ editing: edit
+ });
+ this.bsModalRef = this.modalService.show(ServiceFormComponent, initialState, { size: 'lg' });
+ }
+ }
+
+ ngOnInit() {
+ const columns = [
+ {
+ name: $localize`Service`,
+ prop: 'service_name',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Placement`,
+ prop: '',
+ pipe: new PlacementPipe(),
+ flexGrow: 2
+ },
+ {
+ name: $localize`Running`,
+ prop: 'status.running',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Size`,
+ prop: 'status.size',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Last Refreshed`,
+ prop: 'status.last_refresh',
+ pipe: this.relativeDatePipe,
+ flexGrow: 1
+ }
+ ];
+
+ this.columns = columns.filter((col: any) => {
+ return !this.hiddenColumns.includes(col.prop);
+ });
+
+ this.orchService.status().subscribe((status: OrchestratorStatus) => {
+ this.orchStatus = status;
+ this.showDocPanel = !status.available;
+ });
+ }
+
+ ngOnChanges() {
+ if (this.orchStatus?.available) {
+ this.services = [];
+ this.table.reloadData();
+ }
+ }
+
+ getDisable(
+ action: 'create' | 'update' | 'delete',
+ selection: CdTableSelection
+ ): boolean | string {
+ if (action === 'delete') {
+ if (!selection?.hasSingleSelection) {
+ return true;
+ }
+ }
+ if (action === 'update') {
+ const disableEditServices = ['osd', 'container'];
+ if (disableEditServices.indexOf(this.selection.first()?.service_type) >= 0) {
+ return true;
+ }
+ }
+ return this.orchService.getTableActionDisableDesc(
+ this.orchStatus,
+ this.actionOrchFeatures[action]
+ );
+ }
+
+ getServices(context: CdTableFetchDataContext) {
+ if (this.isLoadingServices) {
+ return;
+ }
+ this.isLoadingServices = true;
+ this.cephServiceService.list().subscribe(
+ (services: CephServiceSpec[]) => {
+ this.services = services;
+ this.services = this.services.filter((col: any) => {
+ return !this.hiddenServices.includes(col.service_name);
+ });
+ this.isLoadingServices = false;
+ },
+ () => {
+ this.isLoadingServices = false;
+ this.services = [];
+ context.error();
+ }
+ );
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ deleteAction() {
+ const service = this.selection.first();
+ this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: $localize`Service`,
+ itemNames: [service.service_name],
+ actionDescription: 'delete',
+ submitActionObservable: () =>
+ this.taskWrapperService
+ .wrapTaskAroundCall({
+ task: new FinishedTask(`service/${URLVerbs.DELETE}`, {
+ service_name: service.service_name
+ }),
+ call: this.cephServiceService.delete(service.service_name)
+ })
+ .pipe(
+ // Delay closing the dialog, otherwise the datatable still
+ // shows the deleted service after an auto-reload.
+ // Showing the dialog while delaying is done to increase
+ // the user experience.
+ delay(5000)
+ )
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.html
new file mode 100644
index 000000000..134871469
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.html
@@ -0,0 +1,322 @@
+<div class="cd-col-form"
+ *cdFormLoading="loading">
+ <ng-container [ngSwitch]="step">
+ <!-- Configuration step -->
+ <div *ngSwitchCase="1">
+ <form name="form"
+ #formDir="ngForm"
+ [formGroup]="configForm"
+ novalidate>
+ <div class="card">
+ <div class="card-header"
+ i18n>Step {{ step }} of 2: Telemetry report configuration</div>
+ <div class="card-body">
+ <p i18n>The telemetry module sends anonymous data about this Ceph cluster back to the Ceph developers
+ to help understand how Ceph is used and what problems users may be experiencing.<br/>
+ This data is visualized on <a href="https://telemetry-public.ceph.com/">public dashboards</a>
+ that allow the community to quickly see summary statistics on how many clusters are reporting,
+ their total capacity and OSD count, and version distribution trends.<br/><br/>
+ The data being reported does <b>not</b> contain any sensitive data like pool names, object names, object contents,
+ hostnames, or device serial numbers. It contains counters and statistics on how the cluster has been
+ deployed, the version of Ceph, the distribution of the hosts and other parameters which help the project
+ to gain a better understanding of the way Ceph is used. The data is sent secured to {{ sendToUrl }} and
+ {{ sendToDeviceUrl }} (device report).</p>
+ <div *ngIf="moduleEnabled">
+ The plugin is already <b>enabled</b>. Click <b>Deactivate</b> to disable it.&nbsp;
+ <button type="button"
+ class="btn btn-light"
+ (click)="disableModule('The Telemetry module has been disabled successfully.')"
+ i18n>Deactivate</button>
+ </div>
+ <legend i18n>Channels</legend>
+ <p i18n>The telemetry report is broken down into several "channels", each with a different type of information that can
+ be configured below.</p>
+
+ <!-- Channel basic -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="channel_basic">
+ <ng-container i18n>Basic</ng-container>
+ <cd-helper>
+ <ng-container i18n>Includes basic information about the cluster:</ng-container>
+ <ul>
+ <li i18n>Capacity of the cluster</li>
+ <li i18n>Number of monitors, managers, OSDs, MDSs, object gateways, or other daemons</li>
+ <li i18n>Software version currently being used</li>
+ <li i18n>Number and types of RADOS pools and CephFS file systems</li>
+ <li i18n>Names of configuration options that have been changed from their default (but not their values)</li>
+ </ul>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ id="channel_basic"
+ formControlName="channel_basic">
+ <label class="custom-control-label"
+ for="channel_basic"></label>
+ </div>
+ </div>
+ </div>
+
+ <!-- Channel crash -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="channel_crash">
+ <ng-container i18n>Crash</ng-container>
+ <cd-helper>
+ <ng-container i18n>Includes information about daemon crashes:</ng-container>
+ <ul>
+ <li i18n>Type of daemon</li>
+ <li i18n>Version of the daemon</li>
+ <li i18n>Operating system (OS distribution, kernel version)</li>
+ <li i18n>Stack trace identifying where in the Ceph code the crash occurred</li>
+ </ul>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ id="channel_crash"
+ formControlName="channel_crash">
+ <label class="custom-control-label"
+ for="channel_crash"></label>
+ </div>
+ </div>
+ </div>
+
+ <!-- Channel device -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="channel_device">
+ <ng-container i18n>Device</ng-container>
+ <cd-helper i18n-html
+ html="Includes information about device metrics like anonymized SMART metrics.">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ id="channel_device"
+ formControlName="channel_device">
+ <label class="custom-control-label"
+ for="channel_device"></label>
+ </div>
+ </div>
+ </div>
+
+ <!-- Channel ident -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="channel_ident">
+ <ng-container i18n>Ident</ng-container>
+ <cd-helper>
+ <ng-container i18n>Includes user-provided identifying information about the cluster:</ng-container>
+ <ul>
+ <li>Cluster description</li>
+ <li>Contact email address</li>
+ </ul>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ id="channel_ident"
+ formControlName="channel_ident"
+ (click)="toggleIdent()">
+ <label class="custom-control-label"
+ for="channel_ident"></label>
+ </div>
+ </div>
+ </div>
+ <ng-container *ngIf="showContactInfo">
+ <legend>
+ <ng-container i18n>Contact Information</ng-container>
+ <cd-helper i18n>Submitting any contact information is completely optional and disabled by default.</cd-helper>
+ </legend>
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="contact"
+ i18n>Contact</label>
+ <div class="cd-col-form-input">
+ <input id="contact"
+ class="form-control"
+ type="text"
+ formControlName="contact"
+ placeholder="Example User <user@example.com>">
+ </div>
+ </div>
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="description"
+ i18n>Description</label>
+ <div class="cd-col-form-input">
+ <input id="description"
+ class="form-control"
+ type="text"
+ formControlName="description"
+ placeholder="My first Ceph cluster"
+ i18n-placeholder>
+ </div>
+ </div>
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="organization"
+ i18n>Organization</label>
+ <div class="cd-col-form-input">
+ <input id="organization"
+ class="form-control"
+ type="text"
+ formControlName="organization"
+ placeholder="Organization name"
+ i18n-placeholder>
+ </div>
+ </div>
+ </ng-container>
+ <legend i18n>Advanced Settings</legend>
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="interval">
+ <ng-container i18n>Interval</ng-container>
+ <cd-helper i18n>The module compiles and sends a new report every 24 hours by default. You can
+ adjust this interval by setting a different number of hours.</cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input id="interval"
+ class="form-control"
+ type="number"
+ formControlName="interval"
+ min="8">
+ <span class="invalid-feedback"
+ *ngIf="configForm.showError('interval', formDir, 'min')"
+ i18n>The entered value is too low! It must be greater or equal to 8.</span>
+ </div>
+ </div>
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="proxy">
+ <ng-container i18n>Proxy</ng-container>
+ <cd-helper>
+ <p i18n>If the cluster cannot directly connect to the configured telemetry endpoint
+ (default telemetry.ceph.com), you can configure a HTTP/HTTPS proxy server by e.g. adding
+ https://10.0.0.1:8080</p>
+ <p i18n>You can also include a user:pass if needed e.g. https://ceph:telemetry@10.0.0.1:8080</p>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input id="proxy"
+ class="form-control"
+ type="text"
+ formControlName="proxy"
+ placeholder="https://10.0.0.1:8080">
+ </div>
+ </div>
+ <br />
+ <p i18n><b>Note:</b> By clicking 'Next' you will first see a preview of the report content before you
+ can activate the automatic submission of your data.</p>
+ </div>
+ <div class="card-footer">
+ <div class="button-group text-right">
+ <button type="button"
+ class="btn btn-light"
+ (click)="next()">
+ <ng-container>{{ actionLabels.NEXT }}</ng-container>
+ </button>
+ </div>
+ </div>
+ </div>
+ </form>
+ </div>
+
+ <!-- Preview step -->
+ <div *ngSwitchCase="2">
+ <form name="previewForm"
+ #frm="ngForm"
+ [formGroup]="previewForm"
+ novalidate>
+ <div class="card">
+ <div class="card-header"
+ i18n>Step {{ step }} of 2: Telemetry report preview</div>
+ <div class="card-body">
+ <!-- Telemetry report ID -->
+ <div class="form-group row">
+ <label i18n
+ for="reportId"
+ class="cd-col-form-label">Report ID
+ <cd-helper i18n-html
+ html="A randomized UUID to identify a particular cluster over the course of several telemetry reports.">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ id="reportId"
+ formControlName="reportId"
+ readonly>
+ </div>
+ </div>
+
+ <!-- Telemetry report -->
+ <div class="form-group row">
+ <label i18n
+ for="report"
+ class="cd-col-form-label">Report preview
+ <cd-helper i18n-html
+ html="The actual telemetry data that will be submitted.">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <textarea class="form-control"
+ id="report"
+ formControlName="report"
+ rows="15"
+ readonly></textarea>
+ </div>
+ </div>
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="btn-group"
+ role="group">
+ <cd-download-button [objectItem]="report"
+ fileName="telemetry_report">
+ </cd-download-button>
+ <cd-copy-2-clipboard-button source="report">
+ </cd-copy-2-clipboard-button>
+ </div>
+ </div>
+ </div>
+
+ <!-- License agreement -->
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ id="licenseAgrmt"
+ name="licenseAgrmt"
+ formControlName="licenseAgrmt">
+ <label class="custom-control-label"
+ for="licenseAgrmt"
+ i18n>I agree to my telemetry data being submitted under the <a href="https://cdla.io/sharing-1-0/">Community Data License Agreement - Sharing - Version 1.0</a></label>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="card-footer">
+ <div class="button-group text-right">
+ <cd-form-button-panel (submitActionEvent)="onSubmit()"
+ (backActionEvent)="back()"
+ [form]="previewForm"
+ [submitText]="actionLabels.UPDATE"
+ [cancelText]="actionLabels.BACK"></cd-form-button-panel>
+ </div>
+ </div>
+ </div>
+ </form>
+ </div>
+ </ng-container>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.spec.ts
new file mode 100644
index 000000000..248881649
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.spec.ts
@@ -0,0 +1,188 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { Router } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import _ from 'lodash';
+import { ToastrModule } from 'ngx-toastr';
+import { of as observableOf } from 'rxjs';
+
+import { MgrModuleService } from '~/app/shared/api/mgr-module.service';
+import { DownloadButtonComponent } from '~/app/shared/components/download-button/download-button.component';
+import { LoadingPanelComponent } from '~/app/shared/components/loading-panel/loading-panel.component';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { TelemetryComponent } from './telemetry.component';
+
+describe('TelemetryComponent', () => {
+ let component: TelemetryComponent;
+ let fixture: ComponentFixture<TelemetryComponent>;
+ let mgrModuleService: MgrModuleService;
+ let options: any;
+ let configs: any;
+ let httpTesting: HttpTestingController;
+ let router: Router;
+
+ const optionsNames = [
+ 'channel_basic',
+ 'channel_crash',
+ 'channel_device',
+ 'channel_ident',
+ 'contact',
+ 'description',
+ 'device_url',
+ 'enabled',
+ 'interval',
+ 'last_opt_revision',
+ 'leaderboard',
+ 'log_level',
+ 'log_to_cluster',
+ 'log_to_cluster_level',
+ 'log_to_file',
+ 'organization',
+ 'proxy',
+ 'url'
+ ];
+
+ configureTestBed(
+ {
+ declarations: [TelemetryComponent],
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ RouterTestingModule,
+ SharedModule,
+ ToastrModule.forRoot()
+ ]
+ },
+ [LoadingPanelComponent, DownloadButtonComponent]
+ );
+
+ describe('configForm', () => {
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TelemetryComponent);
+ component = fixture.componentInstance;
+ mgrModuleService = TestBed.inject(MgrModuleService);
+ options = {};
+ configs = {};
+ optionsNames.forEach((name) => (options[name] = { name }));
+ optionsNames.forEach((name) => (configs[name] = true));
+ spyOn(mgrModuleService, 'getOptions').and.callFake(() => observableOf(options));
+ spyOn(mgrModuleService, 'getConfig').and.callFake(() => observableOf(configs));
+ fixture.detectChanges();
+ httpTesting = TestBed.inject(HttpTestingController);
+ router = TestBed.inject(Router);
+ spyOn(router, 'navigate');
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should show/hide ident fields on checking/unchecking', () => {
+ const getContactField = () =>
+ fixture.debugElement.nativeElement.querySelector('input[id=contact]');
+ const getDescriptionField = () =>
+ fixture.debugElement.nativeElement.querySelector('input[id=description]');
+ const checkVisibility = () => {
+ if (component.showContactInfo) {
+ expect(getContactField()).toBeTruthy();
+ expect(getDescriptionField()).toBeTruthy();
+ } else {
+ expect(getContactField()).toBeFalsy();
+ expect(getDescriptionField()).toBeFalsy();
+ }
+ };
+
+ // Initial check.
+ checkVisibility();
+
+ // toggle fields.
+ component.toggleIdent();
+ fixture.detectChanges();
+ checkVisibility();
+
+ // toggle fields again.
+ component.toggleIdent();
+ fixture.detectChanges();
+ checkVisibility();
+ });
+
+ it('should set module enability to true correctly', () => {
+ expect(component.moduleEnabled).toBeTruthy();
+ });
+
+ it('should set module enability to false correctly', () => {
+ configs['enabled'] = false;
+ component.ngOnInit();
+ expect(component.moduleEnabled).toBeFalsy();
+ });
+
+ it('should filter options list correctly', () => {
+ _.forEach(Object.keys(component.options), (option) => {
+ expect(component.requiredFields).toContain(option);
+ });
+ });
+
+ it('should disable the Telemetry module', () => {
+ const message = 'Module disabled message.';
+ const followUpFunc = function () {
+ return 'followUp';
+ };
+ component.disableModule(message, followUpFunc);
+ const req = httpTesting.expectOne('api/telemetry');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({
+ enable: false
+ });
+ req.flush({});
+ });
+
+ it('should disable the Telemetry module with default parameters', () => {
+ component.disableModule();
+ const req = httpTesting.expectOne('api/telemetry');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({
+ enable: false
+ });
+ req.flush({});
+ expect(router.navigate).toHaveBeenCalledWith(['']);
+ });
+ });
+
+ describe('previewForm', () => {
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TelemetryComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ httpTesting = TestBed.inject(HttpTestingController);
+ router = TestBed.inject(Router);
+ spyOn(router, 'navigate');
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should submit', () => {
+ component.onSubmit();
+ const req1 = httpTesting.expectOne('api/telemetry');
+ expect(req1.request.method).toBe('PUT');
+ expect(req1.request.body).toEqual({
+ enable: true,
+ license_name: 'sharing-1-0'
+ });
+ req1.flush({});
+ const req2 = httpTesting.expectOne({
+ url: 'api/mgr/module/telemetry',
+ method: 'PUT'
+ });
+ expect(req2.request.body).toEqual({
+ config: {}
+ });
+ req2.flush({});
+ expect(router.url).toBe('/');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.ts
new file mode 100644
index 000000000..c2f4523dc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.ts
@@ -0,0 +1,244 @@
+import { Component, OnInit } from '@angular/core';
+import { ValidatorFn, Validators } from '@angular/forms';
+import { Router } from '@angular/router';
+
+import _ from 'lodash';
+import { forkJoin as observableForkJoin } from 'rxjs';
+
+import { MgrModuleService } from '~/app/shared/api/mgr-module.service';
+import { TelemetryService } from '~/app/shared/api/telemetry.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdForm } from '~/app/shared/forms/cd-form';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { TelemetryNotificationService } from '~/app/shared/services/telemetry-notification.service';
+
+@Component({
+ selector: 'cd-telemetry',
+ templateUrl: './telemetry.component.html',
+ styleUrls: ['./telemetry.component.scss']
+})
+export class TelemetryComponent extends CdForm implements OnInit {
+ configForm: CdFormGroup;
+ licenseAgrmt = false;
+ moduleEnabled: boolean;
+ options: Object = {};
+ newConfig: Object = {};
+ configResp: object = {};
+ previewForm: CdFormGroup;
+ requiredFields = [
+ 'channel_basic',
+ 'channel_crash',
+ 'channel_device',
+ 'channel_ident',
+ 'interval',
+ 'proxy',
+ 'contact',
+ 'description',
+ 'organization'
+ ];
+ contactInfofields = ['contact', 'description', 'organization'];
+ report: object = undefined;
+ reportId: number = undefined;
+ sendToUrl = '';
+ sendToDeviceUrl = '';
+ step = 1;
+ showContactInfo: boolean;
+
+ constructor(
+ public actionLabels: ActionLabelsI18n,
+ private formBuilder: CdFormBuilder,
+ private mgrModuleService: MgrModuleService,
+ private notificationService: NotificationService,
+ private router: Router,
+ private telemetryService: TelemetryService,
+ private telemetryNotificationService: TelemetryNotificationService
+ ) {
+ super();
+ }
+
+ ngOnInit() {
+ const observables = [
+ this.mgrModuleService.getOptions('telemetry'),
+ this.mgrModuleService.getConfig('telemetry')
+ ];
+ observableForkJoin(observables).subscribe(
+ (resp: object) => {
+ const configResp = resp[1];
+ this.moduleEnabled = configResp['enabled'];
+ this.sendToUrl = configResp['url'];
+ this.sendToDeviceUrl = configResp['device_url'];
+ this.showContactInfo = configResp['channel_ident'];
+ this.options = _.pick(resp[0], this.requiredFields);
+ this.configResp = _.pick(configResp, this.requiredFields);
+ this.createConfigForm();
+ this.configForm.setValue(this.configResp);
+ this.loadingReady();
+ },
+ (_error) => {
+ this.loadingError();
+ }
+ );
+ }
+
+ private createConfigForm() {
+ const controlsConfig = {};
+ _.forEach(Object.values(this.options), (option) => {
+ controlsConfig[option.name] = [option.default_value, this.getValidators(option)];
+ });
+ this.configForm = this.formBuilder.group(controlsConfig);
+ }
+
+ private createPreviewForm() {
+ const controls = {
+ report: JSON.stringify(this.report, null, 2),
+ reportId: this.reportId,
+ licenseAgrmt: [this.licenseAgrmt, Validators.requiredTrue]
+ };
+ this.previewForm = this.formBuilder.group(controls);
+ }
+
+ private getValidators(option: any): ValidatorFn[] {
+ const result = [];
+ switch (option.type) {
+ case 'int':
+ result.push(Validators.required);
+ break;
+ case 'str':
+ if (_.isNumber(option.min)) {
+ result.push(Validators.minLength(option.min));
+ }
+ if (_.isNumber(option.max)) {
+ result.push(Validators.maxLength(option.max));
+ }
+ break;
+ }
+ return result;
+ }
+
+ private updateReportFromConfig(updatedConfig: Object = {}) {
+ // update channels
+ const availableChannels: string[] = this.report['report']['channels_available'];
+ const updatedChannels = [];
+ for (const channel of availableChannels) {
+ const key = `channel_${channel}`;
+ if (updatedConfig[key]) {
+ updatedChannels.push(channel);
+ }
+ }
+ this.report['report']['channels'] = updatedChannels;
+ // update contactInfo
+ for (const contactInfofield of this.contactInfofields) {
+ this.report['report'][contactInfofield] = updatedConfig[contactInfofield];
+ }
+ }
+
+ private getReport() {
+ this.loadingStart();
+
+ this.telemetryService.getReport().subscribe(
+ (resp: object) => {
+ this.report = resp;
+ this.reportId = resp['report']['report_id'];
+ this.updateReportFromConfig(this.newConfig);
+ this.createPreviewForm();
+ this.loadingReady();
+ this.step++;
+ },
+ (_error) => {
+ this.loadingError();
+ }
+ );
+ }
+
+ toggleIdent() {
+ this.showContactInfo = !this.showContactInfo;
+ }
+
+ buildReport() {
+ this.newConfig = {};
+ for (const option of Object.values(this.options)) {
+ const control = this.configForm.get(option.name);
+ // Append the option only if they are valid
+ if (control.valid) {
+ this.newConfig[option.name] = control.value;
+ } else {
+ this.configForm.setErrors({ cdSubmitButton: true });
+ return;
+ }
+ }
+ // reset contact info field if ident channel is off
+ if (!this.newConfig['channel_ident']) {
+ for (const contactInfofield of this.contactInfofields) {
+ this.newConfig[contactInfofield] = '';
+ }
+ }
+ this.getReport();
+ }
+
+ disableModule(message: string = null, followUpFunc: Function = null) {
+ this.telemetryService.enable(false).subscribe(() => {
+ this.telemetryNotificationService.setVisibility(true);
+ if (message) {
+ this.notificationService.show(NotificationType.success, message);
+ }
+ if (followUpFunc) {
+ followUpFunc();
+ } else {
+ this.router.navigate(['']);
+ }
+ });
+ }
+
+ next() {
+ this.buildReport();
+ }
+
+ back() {
+ this.step--;
+ }
+
+ getChangedConfig() {
+ const updatedConfig = {};
+ _.forEach(this.requiredFields, (configField) => {
+ if (!_.isEqual(this.configResp[configField], this.newConfig[configField])) {
+ updatedConfig[configField] = this.newConfig[configField];
+ }
+ });
+ return updatedConfig;
+ }
+
+ onSubmit() {
+ const updatedConfig = this.getChangedConfig();
+ const observables = [
+ this.telemetryService.enable(),
+ this.mgrModuleService.updateConfig('telemetry', updatedConfig)
+ ];
+
+ observableForkJoin(observables).subscribe(
+ () => {
+ this.telemetryNotificationService.setVisibility(false);
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`The Telemetry module has been configured and activated successfully.`
+ );
+ },
+ () => {
+ this.telemetryNotificationService.setVisibility(false);
+ this.notificationService.show(
+ NotificationType.error,
+ $localize`An Error occurred while updating the Telemetry module configuration.\
+ Please Try again`
+ );
+ // Reset the 'Update' button.
+ this.previewForm.setErrors({ cdSubmitButton: true });
+ },
+ () => {
+ this.newConfig = {};
+ this.router.navigate(['']);
+ }
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard.module.ts
new file mode 100644
index 000000000..1205de94d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard.module.ts
@@ -0,0 +1,43 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { RouterModule } from '@angular/router';
+
+import { NgbNavModule, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap';
+import { ChartsModule } from 'ng2-charts';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { CephSharedModule } from '../shared/ceph-shared.module';
+import { DashboardComponent } from './dashboard/dashboard.component';
+import { HealthPieComponent } from './health-pie/health-pie.component';
+import { HealthComponent } from './health/health.component';
+import { InfoCardComponent } from './info-card/info-card.component';
+import { InfoGroupComponent } from './info-group/info-group.component';
+import { MdsSummaryPipe } from './mds-summary.pipe';
+import { MgrSummaryPipe } from './mgr-summary.pipe';
+import { MonSummaryPipe } from './mon-summary.pipe';
+import { OsdSummaryPipe } from './osd-summary.pipe';
+
+@NgModule({
+ imports: [
+ CephSharedModule,
+ CommonModule,
+ NgbNavModule,
+ SharedModule,
+ ChartsModule,
+ RouterModule,
+ NgbPopoverModule
+ ],
+
+ declarations: [
+ HealthComponent,
+ DashboardComponent,
+ MonSummaryPipe,
+ OsdSummaryPipe,
+ MgrSummaryPipe,
+ MdsSummaryPipe,
+ HealthPieComponent,
+ InfoCardComponent,
+ InfoGroupComponent
+ ]
+})
+export class DashboardModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.html
new file mode 100644
index 000000000..2d03ea3e6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.html
@@ -0,0 +1,28 @@
+<div>
+ <cd-refresh-selector></cd-refresh-selector>
+
+ <ng-container *ngIf="hasGrafana">
+ <ul ngbNav
+ #nav="ngbNav"
+ class="nav-tabs">
+ <li ngbNavItem>
+ <a ngbNavLink
+ i18n>Health</a>
+ <ng-template ngbNavContent>
+ <cd-health></cd-health>
+ </ng-template>
+ </li>
+ <li ngbNavItem>
+ <a ngbNavLink
+ i18n>Statistics</a>
+ <ng-template ngbNavContent>
+ </ng-template>
+ </li>
+
+ </ul>
+
+ <div [ngbNavOutlet]="nav"></div>
+ </ng-container>
+
+ <cd-health *ngIf="!hasGrafana"></cd-health>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.scss
new file mode 100644
index 000000000..04eee2d6f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.scss
@@ -0,0 +1,3 @@
+div {
+ padding-top: 20px;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.spec.ts
new file mode 100644
index 000000000..7bc4980bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.spec.ts
@@ -0,0 +1,28 @@
+import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { DashboardComponent } from './dashboard.component';
+
+describe('DashboardComponent', () => {
+ let component: DashboardComponent;
+ let fixture: ComponentFixture<DashboardComponent>;
+
+ configureTestBed({
+ imports: [NgbNavModule],
+ declarations: [DashboardComponent],
+ schemas: [NO_ERRORS_SCHEMA]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DashboardComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.ts
new file mode 100644
index 000000000..354e38903
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.ts
@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'cd-dashboard',
+ templateUrl: './dashboard.component.html',
+ styleUrls: ['./dashboard.component.scss']
+})
+export class DashboardComponent {
+ hasGrafana = false; // TODO: Temporary var, remove when grafana is implemented
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.html
new file mode 100644
index 000000000..ba8176bea
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.html
@@ -0,0 +1,16 @@
+<div class="chart-container">
+ <canvas baseChart
+ #chartCanvas
+ [datasets]="chartConfig.dataset"
+ [chartType]="chartConfig.chartType"
+ [options]="chartConfig.options"
+ [labels]="chartConfig.labels"
+ [colors]="chartConfig.colors"
+ [plugins]="doughnutChartPlugins"
+ class="chart-canvas">
+ </canvas>
+ <div class="chartjs-tooltip"
+ #chartTooltip>
+ <table></table>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.scss
new file mode 100644
index 000000000..64e7a9822
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.scss
@@ -0,0 +1,22 @@
+@use './src/styles/chart-tooltip';
+
+$canvas-width: 100%;
+$canvas-height: 100%;
+
+.chart-container {
+ height: $canvas-height;
+ margin-left: auto;
+ margin-right: auto;
+ position: unset;
+ width: $canvas-width;
+}
+
+.chart-canvas {
+ height: $canvas-height;
+ margin-left: auto;
+ margin-right: auto;
+ max-height: $canvas-height;
+ max-width: $canvas-width;
+ position: unset;
+ width: $canvas-width;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.spec.ts
new file mode 100644
index 000000000..b87f4bfb5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.spec.ts
@@ -0,0 +1,75 @@
+import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CssHelper } from '~/app/shared/classes/css-helper';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { DimlessPipe } from '~/app/shared/pipes/dimless.pipe';
+import { FormatterService } from '~/app/shared/services/formatter.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { HealthPieComponent } from './health-pie.component';
+
+describe('HealthPieComponent', () => {
+ let component: HealthPieComponent;
+ let fixture: ComponentFixture<HealthPieComponent>;
+
+ configureTestBed({
+ schemas: [NO_ERRORS_SCHEMA],
+ declarations: [HealthPieComponent],
+ providers: [DimlessBinaryPipe, DimlessPipe, FormatterService, CssHelper]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(HealthPieComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('Add slice border if there is more than one slice with numeric non zero value', () => {
+ component.chartConfig.dataset[0].data = [48, 0, 1, 0];
+ component.ngOnChanges();
+
+ expect(component.chartConfig.dataset[0].borderWidth).toEqual(1);
+ });
+
+ it('Remove slice border if there is only one slice with numeric non zero value', () => {
+ component.chartConfig.dataset[0].data = [48, 0, undefined, 0];
+ component.ngOnChanges();
+
+ expect(component.chartConfig.dataset[0].borderWidth).toEqual(0);
+ });
+
+ it('Remove slice border if there is no slice with numeric non zero value', () => {
+ component.chartConfig.dataset[0].data = [undefined, 0];
+ component.ngOnChanges();
+
+ expect(component.chartConfig.dataset[0].borderWidth).toEqual(0);
+ });
+
+ it('should not hide any slice if there is no user click on legend item', () => {
+ const initialData = [8, 15];
+ component.chartConfig.dataset[0].data = initialData;
+ component.ngOnChanges();
+
+ expect(component.chartConfig.dataset[0].data).toEqual(initialData);
+ });
+
+ describe('tooltip body', () => {
+ const tooltipBody = ['text: 10000'];
+
+ it('should return amount converted to appropriate units', () => {
+ component.isBytesData = false;
+ expect(component['getChartTooltipBody'](tooltipBody)).toEqual('text: 10 k');
+
+ component.isBytesData = true;
+ expect(component['getChartTooltipBody'](tooltipBody)).toEqual('text: 9.8 KiB');
+ });
+
+ it('should not return amount when showing label as tooltip', () => {
+ component.showLabelAsTooltip = true;
+ expect(component['getChartTooltipBody'](tooltipBody)).toEqual('text');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.ts
new file mode 100644
index 000000000..fc119b6e2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.ts
@@ -0,0 +1,198 @@
+import {
+ Component,
+ ElementRef,
+ EventEmitter,
+ Input,
+ OnChanges,
+ OnInit,
+ Output,
+ ViewChild
+} from '@angular/core';
+
+import * as Chart from 'chart.js';
+import _ from 'lodash';
+import { PluginServiceGlobalRegistrationAndOptions } from 'ng2-charts';
+
+import { CssHelper } from '~/app/shared/classes/css-helper';
+import { ChartTooltip } from '~/app/shared/models/chart-tooltip';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { DimlessPipe } from '~/app/shared/pipes/dimless.pipe';
+
+@Component({
+ selector: 'cd-health-pie',
+ templateUrl: './health-pie.component.html',
+ styleUrls: ['./health-pie.component.scss']
+})
+export class HealthPieComponent implements OnChanges, OnInit {
+ @ViewChild('chartCanvas', { static: true })
+ chartCanvasRef: ElementRef;
+ @ViewChild('chartTooltip', { static: true })
+ chartTooltipRef: ElementRef;
+
+ @Input()
+ data: any;
+ @Input()
+ config = {};
+ @Input()
+ isBytesData = false;
+ @Input()
+ tooltipFn: any;
+ @Input()
+ showLabelAsTooltip = false;
+ @Output()
+ prepareFn = new EventEmitter();
+
+ chartConfig: any = {
+ chartType: 'doughnut',
+ dataset: [
+ {
+ label: null,
+ borderWidth: 0
+ }
+ ],
+ colors: [
+ {
+ backgroundColor: [
+ this.cssHelper.propertyValue('chart-color-green'),
+ this.cssHelper.propertyValue('chart-color-yellow'),
+ this.cssHelper.propertyValue('chart-color-orange'),
+ this.cssHelper.propertyValue('chart-color-red'),
+ this.cssHelper.propertyValue('chart-color-blue')
+ ]
+ }
+ ],
+ options: {
+ cutoutPercentage: 90,
+ events: ['click', 'mouseout', 'touchstart'],
+ legend: {
+ display: true,
+ position: 'right',
+ labels: {
+ boxWidth: 10,
+ usePointStyle: false
+ }
+ },
+ plugins: {
+ center_text: true
+ },
+ tooltips: {
+ enabled: true,
+ displayColors: false,
+ backgroundColor: this.cssHelper.propertyValue('chart-color-tooltip-background'),
+ cornerRadius: 0,
+ bodyFontSize: 14,
+ bodyFontStyle: '600',
+ position: 'nearest',
+ xPadding: 12,
+ yPadding: 12,
+ callbacks: {
+ label: (item: Record<string, any>, data: Record<string, any>) => {
+ let text = data.labels[item.index];
+ if (!text.includes('%')) {
+ text = `${text} (${data.datasets[item.datasetIndex].data[item.index]}%)`;
+ }
+ return text;
+ }
+ }
+ },
+ title: {
+ display: false
+ }
+ }
+ };
+
+ public doughnutChartPlugins: PluginServiceGlobalRegistrationAndOptions[] = [
+ {
+ id: 'center_text',
+ beforeDraw(chart: Chart) {
+ const cssHelper = new CssHelper();
+ const defaultFontFamily = 'Helvetica Neue, Helvetica, Arial, sans-serif';
+ Chart.defaults.global.defaultFontFamily = defaultFontFamily;
+ const ctx = chart.ctx;
+ if (!chart.options.plugins.center_text || !chart.data.datasets[0].label) {
+ return;
+ }
+
+ ctx.save();
+ const label = chart.data.datasets[0].label.split('\n');
+
+ const centerX = (chart.chartArea.left + chart.chartArea.right) / 2;
+ const centerY = (chart.chartArea.top + chart.chartArea.bottom) / 2;
+ ctx.textAlign = 'center';
+ ctx.textBaseline = 'middle';
+
+ ctx.font = `24px ${defaultFontFamily}`;
+ ctx.fillStyle = cssHelper.propertyValue('chart-color-center-text');
+ ctx.fillText(label[0], centerX, centerY - 10);
+
+ if (label.length > 1) {
+ ctx.font = `14px ${defaultFontFamily}`;
+ ctx.fillStyle = cssHelper.propertyValue('chart-color-center-text-description');
+ ctx.fillText(label[1], centerX, centerY + 10);
+ }
+ ctx.restore();
+ }
+ }
+ ];
+
+ constructor(
+ private dimlessBinary: DimlessBinaryPipe,
+ private dimless: DimlessPipe,
+ private cssHelper: CssHelper
+ ) {}
+
+ ngOnInit() {
+ const getStyleTop = (tooltip: any, positionY: number) => {
+ return positionY + tooltip.caretY - tooltip.height - 10 + 'px';
+ };
+
+ const getStyleLeft = (tooltip: any, positionX: number) => {
+ return positionX + tooltip.caretX + 'px';
+ };
+
+ const chartTooltip = new ChartTooltip(
+ this.chartCanvasRef,
+ this.chartTooltipRef,
+ getStyleLeft,
+ getStyleTop
+ );
+
+ chartTooltip.getBody = (body: any) => {
+ return this.getChartTooltipBody(body);
+ };
+
+ _.merge(this.chartConfig, this.config);
+
+ this.prepareFn.emit([this.chartConfig, this.data]);
+ }
+
+ ngOnChanges() {
+ this.prepareFn.emit([this.chartConfig, this.data]);
+ this.setChartSliceBorderWidth();
+ }
+
+ private getChartTooltipBody(body: string[]) {
+ const bodySplit = body[0].split(': ');
+
+ if (this.showLabelAsTooltip) {
+ return bodySplit[0];
+ }
+
+ bodySplit[1] = this.isBytesData
+ ? this.dimlessBinary.transform(bodySplit[1])
+ : this.dimless.transform(bodySplit[1]);
+
+ return bodySplit.join(': ');
+ }
+
+ private setChartSliceBorderWidth() {
+ let nonZeroValueSlices = 0;
+ _.forEach(this.chartConfig.dataset[0].data, function (slice) {
+ if (slice > 0) {
+ nonZeroValueSlices += 1;
+ }
+ });
+
+ this.chartConfig.dataset[0].borderWidth = nonZeroValueSlices > 1 ? 1 : 0;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html
new file mode 100644
index 000000000..71aac66d9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html
@@ -0,0 +1,237 @@
+<div *ngIf="healthData && enabledFeature$ | async as enabledFeature"
+ class="container-fluid">
+ <cd-info-group groupTitle="Status"
+ i18n-groupTitle
+ *ngIf="healthData.health?.status
+ || healthData.mon_status
+ || healthData.osd_map
+ || healthData.mgr_map
+ || healthData.hosts != null
+ || healthData.rgw != null
+ || healthData.fs_map
+ || healthData.iscsi_daemons != null">
+
+ <cd-info-card cardTitle="Cluster Status"
+ i18n-cardTitle
+ class="cd-status-card"
+ contentClass="content-highlight"
+ *ngIf="healthData.health?.status">
+ <ng-container *ngIf="healthData.health?.checks?.length > 0">
+ <ng-template #healthChecks>
+ <ng-container *ngTemplateOutlet="logsLink"></ng-container>
+ <ul>
+ <li *ngFor="let check of healthData.health.checks">
+ <span [ngStyle]="check.severity | healthColor">{{ check.type }}</span>: {{ check.summary.message }}
+ </li>
+ </ul>
+ </ng-template>
+ <div class="info-card-content-clickable"
+ [ngStyle]="healthData.health.status | healthColor"
+ [ngbPopover]="healthChecks"
+ popoverClass="info-card-popover-cluster-status">
+ {{ healthData.health.status }} <i *ngIf="healthData.health?.status != 'HEALTH_OK'"
+ class="fa fa-exclamation-triangle"></i>
+ </div>
+ </ng-container>
+ <ng-container *ngIf="!healthData.health?.checks?.length">
+ <div [ngStyle]="healthData.health.status | healthColor">
+ {{ healthData.health.status }}
+ </div>
+ </ng-container>
+ </cd-info-card>
+
+ <cd-info-card cardTitle="Hosts"
+ i18n-cardTitle
+ link="/hosts"
+ class="cd-status-card"
+ contentClass="content-highlight"
+ *ngIf="healthData.hosts != null">
+ {{ healthData.hosts }} total
+ </cd-info-card>
+
+ <cd-info-card cardTitle="Monitors"
+ i18n-cardTitle
+ link="/monitor"
+ class="cd-status-card"
+ contentClass="content-highlight"
+ *ngIf="healthData.mon_status">
+ {{ healthData.mon_status | monSummary }}
+ </cd-info-card>
+
+ <cd-info-card cardTitle="OSDs"
+ i18n-cardTitle
+ link="/osd"
+ class="cd-status-card"
+ *ngIf="(healthData.osd_map | osdSummary) as transformedResult"
+ contentClass="content-highlight">
+ <span *ngFor="let result of transformedResult"
+ [ngClass]="result.class">
+ {{ result.content }}
+ </span>
+ </cd-info-card>
+
+ <cd-info-card cardTitle="Managers"
+ i18n-cardTitle
+ class="cd-status-card"
+ contentClass="content-highlight"
+ *ngIf="healthData.mgr_map">
+ <span *ngFor="let result of (healthData.mgr_map | mgrSummary)"
+ [ngClass]="result.class"
+ [title]="result.titleText != null ? result.titleText : ''">
+ {{ result.content }}
+ </span>
+ </cd-info-card>
+
+ <cd-info-card cardTitle="Object Gateways"
+ i18n-cardTitle
+ link="/rgw/daemon"
+ class="cd-status-card"
+ contentClass="content-highlight"
+ *ngIf="enabledFeature.rgw && healthData.rgw != null">
+ {{ healthData.rgw }} total
+ </cd-info-card>
+
+ <cd-info-card cardTitle="Metadata Servers"
+ i18n-cardTitle
+ class="cd-status-card"
+ *ngIf="(enabledFeature.cephfs && healthData.fs_map | mdsSummary) as transformedResult"
+ [contentClass]="(transformedResult.length > 1 ? 'text-area-size-2' : '') + ' content-highlight'">
+ <!-- TODO: check text-area-size-2 -->
+ <span *ngFor="let result of transformedResult"
+ [ngClass]="result.class"
+ [title]="result.titleText != null ? result.titleText : ''">
+ {{ result.content }}
+ </span>
+ </cd-info-card>
+
+ <cd-info-card cardTitle="iSCSI Gateways"
+ i18n-cardTitle
+ link="/block/iscsi"
+ class="cd-status-card"
+ contentClass="content-highlight"
+ *ngIf="enabledFeature.iscsi && healthData.iscsi_daemons != null">
+ {{ healthData.iscsi_daemons.up + healthData.iscsi_daemons.down }} total
+ <span class="card-text-line-break"></span>
+ {{ healthData.iscsi_daemons.up }} up,
+ <span [ngClass]="{'card-text-error': healthData.iscsi_daemons.down > 0}">{{ healthData.iscsi_daemons.down }}
+ down</span>
+ </cd-info-card>
+ </cd-info-group>
+
+ <cd-info-group groupTitle="Capacity"
+ i18n-groupTitle
+ *ngIf="healthData.pools
+ || healthData.df
+ || healthData.pg_info">
+ <cd-info-card cardTitle="Raw Capacity"
+ i18n-cardTitle
+ class="cd-capacity-card cd-chart-card"
+ contentClass="content-chart"
+ *ngIf="healthData.df">
+ <cd-health-pie [data]="healthData"
+ [config]="rawCapacityChartConfig"
+ [isBytesData]="true"
+ (prepareFn)="prepareRawUsage($event[0], $event[1])">
+ </cd-health-pie>
+ </cd-info-card>
+
+ <cd-info-card cardTitle="Objects"
+ i18n-cardTitle
+ class="cd-capacity-card cd-chart-card"
+ contentClass="content-chart"
+ *ngIf="healthData.pg_info?.object_stats?.num_objects != null">
+ <cd-health-pie [data]="healthData"
+ (prepareFn)="prepareObjects($event[0], $event[1])">
+ </cd-health-pie>
+ </cd-info-card>
+
+ <cd-info-card cardTitle="PG Status"
+ i18n-cardTitle
+ class="cd-capacity-card cd-chart-card"
+ contentClass="content-chart"
+ *ngIf="healthData.pg_info">
+ <ng-template #pgStatus>
+ <ng-container *ngTemplateOutlet="logsLink"></ng-container>
+ <ul>
+ <li *ngFor="let pgStatesText of healthData.pg_info.statuses | keyvalue">
+ {{ pgStatesText.key }}: {{ pgStatesText.value }}
+ </li>
+ </ul>
+ </ng-template>
+ <div class="pg-status-popover-wrapper">
+ <div [ngbPopover]="pgStatus">
+ <cd-health-pie [data]="healthData"
+ [config]="pgStatusChartConfig"
+ (prepareFn)="preparePgStatus($event[0], $event[1])">
+ </cd-health-pie>
+ </div>
+ </div>
+ </cd-info-card>
+
+ <cd-info-card cardTitle="Pools"
+ i18n-cardTitle
+ link="/pool"
+ class="cd-capacity-card"
+ contentClass="content-highlight"
+ *ngIf="healthData.pools">
+ {{ healthData.pools.length }}
+ </cd-info-card>
+
+ <cd-info-card cardTitle="PGs per OSD"
+ i18n-cardTitle
+ class="cd-capacity-card"
+ contentClass="content-highlight"
+ *ngIf="healthData.pg_info">
+ {{ healthData.pg_info.pgs_per_osd | dimless }}
+ </cd-info-card>
+ </cd-info-group>
+
+ <cd-info-group groupTitle="Performance"
+ i18n-groupTitle
+ *ngIf="healthData.client_perf || healthData.scrub_status">
+ <cd-info-card cardTitle="Client Read/Write"
+ i18n-cardTitle
+ class="cd-performance-card cd-chart-card"
+ contentClass="content-chart"
+ *ngIf="healthData.client_perf">
+ <cd-health-pie [data]="healthData"
+ [config]="clientStatsConfig"
+ (prepareFn)="prepareReadWriteRatio($event[0], $event[1])">
+ </cd-health-pie>
+ </cd-info-card>
+
+ <cd-info-card cardTitle="Client Throughput"
+ i18n-cardTitle
+ class="cd-performance-card cd-chart-card"
+ contentClass="content-chart"
+ *ngIf="healthData.client_perf">
+ <cd-health-pie [data]="healthData"
+ [config]="clientStatsConfig"
+ (prepareFn)="prepareClientThroughput($event[0], $event[1])">
+ </cd-health-pie>
+ </cd-info-card>
+
+ <cd-info-card cardTitle="Recovery Throughput"
+ i18n-cardTitle
+ class="cd-performance-card"
+ contentClass="content-highlight"
+ *ngIf="healthData.client_perf">
+ {{ (healthData.client_perf.recovering_bytes_per_sec | dimlessBinary) + '/s' }}
+ </cd-info-card>
+
+ <cd-info-card cardTitle="Scrubbing"
+ i18n-cardTitle
+ class="cd-performance-card"
+ contentClass="content-highlight"
+ *ngIf="healthData.scrub_status">
+ {{ healthData.scrub_status }}
+ </cd-info-card>
+ </cd-info-group>
+
+ <ng-template #logsLink>
+ <ng-container *ngIf="permissions.log.read">
+ <p class="logs-link"
+ i18n><i [ngClass]="[icons.infoCircle]"></i> See <a routerLink="/logs">Logs</a> for more details.</p>
+ </ng-container>
+ </ng-template>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.scss
new file mode 100644
index 000000000..1294f5922
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.scss
@@ -0,0 +1,41 @@
+@use './src/styles/vendor/variables' as vv;
+
+cd-info-card {
+ padding: 0 0.5vw;
+}
+
+::ng-deep cd-health .pg-status-popover-wrapper {
+ position: relative;
+
+ .popover {
+ max-height: 20vh;
+ max-width: unset !important;
+ min-width: unset !important;
+ position: absolute;
+ width: 116%;
+
+ .popover-body {
+ font-size: 1rem;
+ max-height: 19vh;
+ max-width: 100%;
+ }
+ }
+}
+
+.logs-link {
+ text-align: center;
+}
+
+.card-text-error {
+ color: vv.$chart-danger;
+ display: inline;
+}
+
+.card-text-line-break::after {
+ content: '\A';
+ white-space: pre;
+}
+
+.popover-info:hover {
+ cursor: pointer;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.spec.ts
new file mode 100644
index 000000000..cedcd06b6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.spec.ts
@@ -0,0 +1,348 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+
+import _ from 'lodash';
+import { of } from 'rxjs';
+
+import { PgCategoryService } from '~/app/ceph/shared/pg-category.service';
+import { HealthService } from '~/app/shared/api/health.service';
+import { CssHelper } from '~/app/shared/classes/css-helper';
+import { Permissions } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { FeatureTogglesService } from '~/app/shared/services/feature-toggles.service';
+import { RefreshIntervalService } from '~/app/shared/services/refresh-interval.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { HealthPieComponent } from '../health-pie/health-pie.component';
+import { MdsSummaryPipe } from '../mds-summary.pipe';
+import { MgrSummaryPipe } from '../mgr-summary.pipe';
+import { MonSummaryPipe } from '../mon-summary.pipe';
+import { OsdSummaryPipe } from '../osd-summary.pipe';
+import { HealthComponent } from './health.component';
+
+describe('HealthComponent', () => {
+ let component: HealthComponent;
+ let fixture: ComponentFixture<HealthComponent>;
+ let getHealthSpy: jasmine.Spy;
+ const healthPayload: Record<string, any> = {
+ health: { status: 'HEALTH_OK' },
+ mon_status: { monmap: { mons: [] }, quorum: [] },
+ osd_map: { osds: [] },
+ mgr_map: { standbys: [] },
+ hosts: 0,
+ rgw: 0,
+ fs_map: { filesystems: [], standbys: [] },
+ iscsi_daemons: 0,
+ client_perf: {},
+ scrub_status: 'Inactive',
+ pools: [],
+ df: { stats: {} },
+ pg_info: { object_stats: { num_objects: 0 } }
+ };
+ const fakeAuthStorageService = {
+ getPermissions: () => {
+ return new Permissions({ log: ['read'] });
+ }
+ };
+ let fakeFeatureTogglesService: jasmine.Spy;
+
+ configureTestBed({
+ imports: [SharedModule, HttpClientTestingModule],
+ declarations: [
+ HealthComponent,
+ HealthPieComponent,
+ MonSummaryPipe,
+ OsdSummaryPipe,
+ MdsSummaryPipe,
+ MgrSummaryPipe
+ ],
+ schemas: [NO_ERRORS_SCHEMA],
+ providers: [
+ { provide: AuthStorageService, useValue: fakeAuthStorageService },
+ PgCategoryService,
+ RefreshIntervalService,
+ CssHelper
+ ]
+ });
+
+ beforeEach(() => {
+ fakeFeatureTogglesService = spyOn(TestBed.inject(FeatureTogglesService), 'get').and.returnValue(
+ of({
+ rbd: true,
+ mirroring: true,
+ iscsi: true,
+ cephfs: true,
+ rgw: true
+ })
+ );
+ fixture = TestBed.createComponent(HealthComponent);
+ component = fixture.componentInstance;
+ getHealthSpy = spyOn(TestBed.inject(HealthService), 'getMinimalHealth');
+ getHealthSpy.and.returnValue(of(healthPayload));
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should render all info groups and all info cards', () => {
+ fixture.detectChanges();
+
+ const infoGroups = fixture.debugElement.nativeElement.querySelectorAll('cd-info-group');
+ expect(infoGroups.length).toBe(3);
+
+ const infoCards = fixture.debugElement.nativeElement.querySelectorAll('cd-info-card');
+ expect(infoCards.length).toBe(17);
+ });
+
+ describe('features disabled', () => {
+ beforeEach(() => {
+ fakeFeatureTogglesService.and.returnValue(
+ of({
+ rbd: false,
+ mirroring: false,
+ iscsi: false,
+ cephfs: false,
+ rgw: false
+ })
+ );
+ fixture = TestBed.createComponent(HealthComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should not render cards related to disabled features', () => {
+ fixture.detectChanges();
+
+ const infoGroups = fixture.debugElement.nativeElement.querySelectorAll('cd-info-group');
+ expect(infoGroups.length).toBe(3);
+
+ const infoCards = fixture.debugElement.nativeElement.querySelectorAll('cd-info-card');
+ expect(infoCards.length).toBe(14);
+ });
+ });
+
+ it('should render all except "Status" group and cards', () => {
+ const payload = _.cloneDeep(healthPayload);
+ payload.health.status = '';
+ payload.mon_status = null;
+ payload.osd_map = null;
+ payload.mgr_map = null;
+ payload.hosts = null;
+ payload.rgw = null;
+ payload.fs_map = null;
+ payload.iscsi_daemons = null;
+
+ getHealthSpy.and.returnValue(of(payload));
+ fixture.detectChanges();
+
+ const infoGroups = fixture.debugElement.nativeElement.querySelectorAll('cd-info-group');
+ expect(infoGroups.length).toBe(2);
+
+ const infoCards = fixture.debugElement.nativeElement.querySelectorAll('cd-info-card');
+ expect(infoCards.length).toBe(9);
+ });
+
+ it('should render all except "Performance" group and cards', () => {
+ const payload = _.cloneDeep(healthPayload);
+ payload.scrub_status = '';
+ payload.client_perf = null;
+
+ getHealthSpy.and.returnValue(of(payload));
+ fixture.detectChanges();
+
+ const infoGroups = fixture.debugElement.nativeElement.querySelectorAll('cd-info-group');
+ expect(infoGroups.length).toBe(2);
+
+ const infoCards = fixture.debugElement.nativeElement.querySelectorAll('cd-info-card');
+ expect(infoCards.length).toBe(13);
+ });
+
+ it('should render all except "Capacity" group and cards', () => {
+ const payload = _.cloneDeep(healthPayload);
+ payload.pools = null;
+ payload.df = null;
+ payload.pg_info = null;
+
+ getHealthSpy.and.returnValue(of(payload));
+ fixture.detectChanges();
+
+ const infoGroups = fixture.debugElement.nativeElement.querySelectorAll('cd-info-group');
+ expect(infoGroups.length).toBe(2);
+
+ const infoCards = fixture.debugElement.nativeElement.querySelectorAll('cd-info-card');
+ expect(infoCards.length).toBe(12);
+ });
+
+ it('should render all groups and 1 card per group', () => {
+ const payload: Record<string, any> = { hosts: 0, scrub_status: 'Inactive', pools: [] };
+
+ getHealthSpy.and.returnValue(of(payload));
+ fixture.detectChanges();
+
+ const infoGroups = fixture.debugElement.nativeElement.querySelectorAll('cd-info-group');
+ expect(infoGroups.length).toBe(3);
+
+ _.each(infoGroups, (infoGroup) => {
+ expect(infoGroup.querySelectorAll('cd-info-card').length).toBe(1);
+ });
+ });
+
+ it('should render "Cluster Status" card text that is not clickable', () => {
+ fixture.detectChanges();
+
+ const clusterStatusCard = fixture.debugElement.query(
+ By.css('cd-info-card[cardTitle="Cluster Status"]')
+ );
+ const clickableContent = clusterStatusCard.query(By.css('.info-card-content-clickable'));
+ expect(clickableContent).toBeNull();
+ expect(clusterStatusCard.nativeElement.textContent).toEqual(` ${healthPayload.health.status} `);
+ });
+
+ it('should render "Cluster Status" card text that is clickable (popover)', () => {
+ const payload = _.cloneDeep(healthPayload);
+ payload.health['status'] = 'HEALTH_WARN';
+ payload.health['checks'] = [
+ { severity: 'HEALTH_WARN', type: 'WRN', summary: { message: 'fake warning' } }
+ ];
+
+ getHealthSpy.and.returnValue(of(payload));
+ fixture.detectChanges();
+
+ expect(component.permissions.log.read).toBeTruthy();
+
+ const clusterStatusCard = fixture.debugElement.query(
+ By.css('cd-info-card[cardTitle="Cluster Status"]')
+ );
+ const clickableContent = clusterStatusCard.query(By.css('.info-card-content-clickable'));
+ expect(clickableContent.nativeElement.textContent).toEqual(` ${payload.health.status} `);
+ });
+
+ it('event binding "prepareReadWriteRatio" is called', () => {
+ const prepareReadWriteRatio = spyOn(component, 'prepareReadWriteRatio').and.callThrough();
+
+ const payload = _.cloneDeep(healthPayload);
+ payload.client_perf['read_op_per_sec'] = 1;
+ payload.client_perf['write_op_per_sec'] = 3;
+ getHealthSpy.and.returnValue(of(payload));
+ fixture.detectChanges();
+
+ expect(prepareReadWriteRatio).toHaveBeenCalled();
+ expect(prepareReadWriteRatio.calls.mostRecent().args[0].dataset[0].data).toEqual([25, 75]);
+ });
+
+ it('event binding "prepareRawUsage" is called', () => {
+ const prepareRawUsage = spyOn(component, 'prepareRawUsage');
+
+ fixture.detectChanges();
+
+ expect(prepareRawUsage).toHaveBeenCalled();
+ });
+
+ it('event binding "preparePgStatus" is called', () => {
+ const preparePgStatus = spyOn(component, 'preparePgStatus');
+
+ fixture.detectChanges();
+
+ expect(preparePgStatus).toHaveBeenCalled();
+ });
+
+ it('event binding "prepareObjects" is called', () => {
+ const prepareObjects = spyOn(component, 'prepareObjects');
+
+ fixture.detectChanges();
+
+ expect(prepareObjects).toHaveBeenCalled();
+ });
+
+ describe('preparePgStatus', () => {
+ const expectedChart = (data: number[], label: string = null) => ({
+ labels: [
+ `Clean: ${component['dimless'].transform(data[0])}`,
+ `Working: ${component['dimless'].transform(data[1])}`,
+ `Warning: ${component['dimless'].transform(data[2])}`,
+ `Unknown: ${component['dimless'].transform(data[3])}`
+ ],
+ options: {},
+ dataset: [
+ {
+ data: data.map((i) =>
+ component['calcPercentage'](
+ i,
+ data.reduce((j, k) => j + k)
+ )
+ ),
+ label: label
+ }
+ ]
+ });
+
+ it('gets no data', () => {
+ const chart = { dataset: [{}], options: {} };
+ component.preparePgStatus(chart, {
+ pg_info: {}
+ });
+ expect(chart).toEqual(expectedChart([0, 0, 0, 0], '0\nPGs'));
+ });
+
+ it('gets data from all categories', () => {
+ const chart = { dataset: [{}], options: {} };
+ component.preparePgStatus(chart, {
+ pg_info: {
+ statuses: {
+ 'clean+active+scrubbing+nonMappedState': 4,
+ 'clean+active+scrubbing': 2,
+ 'clean+active': 1,
+ 'clean+active+scrubbing+down': 3
+ }
+ }
+ });
+ expect(chart).toEqual(expectedChart([1, 2, 3, 4], '10\nPGs'));
+ });
+ });
+
+ describe('isClientReadWriteChartShowable', () => {
+ beforeEach(() => {
+ component.healthData = healthPayload;
+ });
+
+ it('returns false', () => {
+ component.healthData['client_perf'] = {};
+
+ expect(component.isClientReadWriteChartShowable()).toBeFalsy();
+ });
+
+ it('returns false', () => {
+ component.healthData['client_perf'] = { read_op_per_sec: undefined, write_op_per_sec: 0 };
+
+ expect(component.isClientReadWriteChartShowable()).toBeFalsy();
+ });
+
+ it('returns true', () => {
+ component.healthData['client_perf'] = { read_op_per_sec: 1, write_op_per_sec: undefined };
+
+ expect(component.isClientReadWriteChartShowable()).toBeTruthy();
+ });
+
+ it('returns true', () => {
+ component.healthData['client_perf'] = { read_op_per_sec: 2, write_op_per_sec: 3 };
+
+ expect(component.isClientReadWriteChartShowable()).toBeTruthy();
+ });
+ });
+
+ describe('calcPercentage', () => {
+ it('returns correct value', () => {
+ expect(component['calcPercentage'](1, undefined)).toEqual(0);
+ expect(component['calcPercentage'](1, null)).toEqual(0);
+ expect(component['calcPercentage'](1, 0)).toEqual(0);
+ expect(component['calcPercentage'](undefined, 1)).toEqual(0);
+ expect(component['calcPercentage'](null, 1)).toEqual(0);
+ expect(component['calcPercentage'](0, 1)).toEqual(0);
+ expect(component['calcPercentage'](1, 100000)).toEqual(0.01);
+ expect(component['calcPercentage'](2.346, 10)).toEqual(23.46);
+ expect(component['calcPercentage'](2.56, 10)).toEqual(25.6);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.ts
new file mode 100644
index 000000000..4d1dac769
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.ts
@@ -0,0 +1,278 @@
+import { Component, OnDestroy, OnInit } from '@angular/core';
+
+import _ from 'lodash';
+import { Subscription } from 'rxjs';
+import { take } from 'rxjs/operators';
+
+import { PgCategoryService } from '~/app/ceph/shared/pg-category.service';
+import { HealthService } from '~/app/shared/api/health.service';
+import { OsdService } from '~/app/shared/api/osd.service';
+import { CssHelper } from '~/app/shared/classes/css-helper';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { OsdSettings } from '~/app/shared/models/osd-settings';
+import { Permissions } from '~/app/shared/models/permissions';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { DimlessPipe } from '~/app/shared/pipes/dimless.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import {
+ FeatureTogglesMap$,
+ FeatureTogglesService
+} from '~/app/shared/services/feature-toggles.service';
+import { RefreshIntervalService } from '~/app/shared/services/refresh-interval.service';
+
+@Component({
+ selector: 'cd-health',
+ templateUrl: './health.component.html',
+ styleUrls: ['./health.component.scss']
+})
+export class HealthComponent implements OnInit, OnDestroy {
+ healthData: any;
+ osdSettings = new OsdSettings();
+ interval = new Subscription();
+ permissions: Permissions;
+ enabledFeature$: FeatureTogglesMap$;
+ icons = Icons;
+ color: string;
+
+ clientStatsConfig = {
+ colors: [
+ {
+ backgroundColor: [
+ this.cssHelper.propertyValue('chart-color-cyan'),
+ this.cssHelper.propertyValue('chart-color-purple')
+ ]
+ }
+ ]
+ };
+
+ rawCapacityChartConfig = {
+ colors: [
+ {
+ backgroundColor: [
+ this.cssHelper.propertyValue('chart-color-blue'),
+ this.cssHelper.propertyValue('chart-color-gray')
+ ]
+ }
+ ]
+ };
+
+ pgStatusChartConfig = {
+ options: {
+ events: ['']
+ }
+ };
+
+ constructor(
+ private healthService: HealthService,
+ private osdService: OsdService,
+ private authStorageService: AuthStorageService,
+ private pgCategoryService: PgCategoryService,
+ private featureToggles: FeatureTogglesService,
+ private refreshIntervalService: RefreshIntervalService,
+ private dimlessBinary: DimlessBinaryPipe,
+ private dimless: DimlessPipe,
+ private cssHelper: CssHelper
+ ) {
+ this.permissions = this.authStorageService.getPermissions();
+ this.enabledFeature$ = this.featureToggles.get();
+ }
+
+ ngOnInit() {
+ this.interval = this.refreshIntervalService.intervalData$.subscribe(() => {
+ this.getHealth();
+ });
+
+ this.osdService
+ .getOsdSettings()
+ .pipe(take(1))
+ .subscribe((data: any) => {
+ this.osdSettings = data;
+ });
+ }
+
+ ngOnDestroy() {
+ this.interval.unsubscribe();
+ }
+
+ getHealth() {
+ this.healthService.getMinimalHealth().subscribe((data: any) => {
+ this.healthData = data;
+ });
+ }
+
+ prepareReadWriteRatio(chart: Record<string, any>) {
+ const ratioLabels = [];
+ const ratioData = [];
+
+ const total =
+ this.healthData.client_perf.write_op_per_sec + this.healthData.client_perf.read_op_per_sec;
+
+ ratioLabels.push(
+ `${$localize`Reads`}: ${this.dimless.transform(
+ this.healthData.client_perf.read_op_per_sec
+ )} ${$localize`/s`}`
+ );
+ ratioData.push(this.calcPercentage(this.healthData.client_perf.read_op_per_sec, total));
+ ratioLabels.push(
+ `${$localize`Writes`}: ${this.dimless.transform(
+ this.healthData.client_perf.write_op_per_sec
+ )} ${$localize`/s`}`
+ );
+ ratioData.push(this.calcPercentage(this.healthData.client_perf.write_op_per_sec, total));
+
+ chart.labels = ratioLabels;
+ chart.dataset[0].data = ratioData;
+ chart.dataset[0].label = `${this.dimless.transform(total)}\n${$localize`IOPS`}`;
+ }
+
+ prepareClientThroughput(chart: Record<string, any>) {
+ const ratioLabels = [];
+ const ratioData = [];
+
+ const total =
+ this.healthData.client_perf.read_bytes_sec + this.healthData.client_perf.write_bytes_sec;
+
+ ratioLabels.push(
+ `${$localize`Reads`}: ${this.dimlessBinary.transform(
+ this.healthData.client_perf.read_bytes_sec
+ )}${$localize`/s`}`
+ );
+ ratioData.push(this.calcPercentage(this.healthData.client_perf.read_bytes_sec, total));
+ ratioLabels.push(
+ `${$localize`Writes`}: ${this.dimlessBinary.transform(
+ this.healthData.client_perf.write_bytes_sec
+ )}${$localize`/s`}`
+ );
+ ratioData.push(this.calcPercentage(this.healthData.client_perf.write_bytes_sec, total));
+
+ chart.labels = ratioLabels;
+ chart.dataset[0].data = ratioData;
+ chart.dataset[0].label = `${this.dimlessBinary
+ .transform(total)
+ .replace(' ', '\n')}${$localize`/s`}`;
+ }
+
+ prepareRawUsage(chart: Record<string, any>, data: Record<string, any>) {
+ const percentAvailable = this.calcPercentage(
+ data.df.stats.total_bytes - data.df.stats.total_used_raw_bytes,
+ data.df.stats.total_bytes
+ );
+ const percentUsed = this.calcPercentage(
+ data.df.stats.total_used_raw_bytes,
+ data.df.stats.total_bytes
+ );
+
+ if (percentUsed / 100 >= this.osdSettings.nearfull_ratio) {
+ this.color = 'chart-color-red';
+ } else if (percentUsed / 100 >= this.osdSettings.full_ratio) {
+ this.color = 'chart-color-yellow';
+ } else {
+ this.color = 'chart-color-blue';
+ }
+ this.rawCapacityChartConfig.colors[0].backgroundColor[0] = this.cssHelper.propertyValue(
+ this.color
+ );
+
+ chart.dataset[0].data = [percentUsed, percentAvailable];
+
+ chart.labels = [
+ `${$localize`Used`}: ${this.dimlessBinary.transform(data.df.stats.total_used_raw_bytes)}`,
+ `${$localize`Avail.`}: ${this.dimlessBinary.transform(
+ data.df.stats.total_bytes - data.df.stats.total_used_raw_bytes
+ )}`
+ ];
+
+ chart.dataset[0].label = `${percentUsed}%\nof ${this.dimlessBinary.transform(
+ data.df.stats.total_bytes
+ )}`;
+ }
+
+ preparePgStatus(chart: Record<string, any>, data: Record<string, any>) {
+ const categoryPgAmount: Record<string, number> = {};
+ let totalPgs = 0;
+
+ _.forEach(data.pg_info.statuses, (pgAmount, pgStatesText) => {
+ const categoryType = this.pgCategoryService.getTypeByStates(pgStatesText);
+
+ if (_.isUndefined(categoryPgAmount[categoryType])) {
+ categoryPgAmount[categoryType] = 0;
+ }
+ categoryPgAmount[categoryType] += pgAmount;
+ totalPgs += pgAmount;
+ });
+
+ for (const categoryType of this.pgCategoryService.getAllTypes()) {
+ if (_.isUndefined(categoryPgAmount[categoryType])) {
+ categoryPgAmount[categoryType] = 0;
+ }
+ }
+
+ chart.dataset[0].data = this.pgCategoryService
+ .getAllTypes()
+ .map((categoryType) => this.calcPercentage(categoryPgAmount[categoryType], totalPgs));
+
+ chart.labels = [
+ `${$localize`Clean`}: ${this.dimless.transform(categoryPgAmount['clean'])}`,
+ `${$localize`Working`}: ${this.dimless.transform(categoryPgAmount['working'])}`,
+ `${$localize`Warning`}: ${this.dimless.transform(categoryPgAmount['warning'])}`,
+ `${$localize`Unknown`}: ${this.dimless.transform(categoryPgAmount['unknown'])}`
+ ];
+
+ chart.dataset[0].label = `${totalPgs}\n${$localize`PGs`}`;
+ }
+
+ prepareObjects(chart: Record<string, any>, data: Record<string, any>) {
+ const objectCopies = data.pg_info.object_stats.num_object_copies;
+ const healthy =
+ objectCopies -
+ data.pg_info.object_stats.num_objects_misplaced -
+ data.pg_info.object_stats.num_objects_degraded -
+ data.pg_info.object_stats.num_objects_unfound;
+ const healthyPercentage = this.calcPercentage(healthy, objectCopies);
+ const misplacedPercentage = this.calcPercentage(
+ data.pg_info.object_stats.num_objects_misplaced,
+ objectCopies
+ );
+ const degradedPercentage = this.calcPercentage(
+ data.pg_info.object_stats.num_objects_degraded,
+ objectCopies
+ );
+ const unfoundPercentage = this.calcPercentage(
+ data.pg_info.object_stats.num_objects_unfound,
+ objectCopies
+ );
+
+ chart.labels = [
+ `${$localize`Healthy`}: ${healthyPercentage}%`,
+ `${$localize`Misplaced`}: ${misplacedPercentage}%`,
+ `${$localize`Degraded`}: ${degradedPercentage}%`,
+ `${$localize`Unfound`}: ${unfoundPercentage}%`
+ ];
+
+ chart.dataset[0].data = [
+ healthyPercentage,
+ misplacedPercentage,
+ degradedPercentage,
+ unfoundPercentage
+ ];
+
+ chart.dataset[0].label = `${this.dimless.transform(
+ data.pg_info.object_stats.num_objects
+ )}\n${$localize`objects`}`;
+ }
+
+ isClientReadWriteChartShowable() {
+ const readOps = this.healthData.client_perf.read_op_per_sec || 0;
+ const writeOps = this.healthData.client_perf.write_op_per_sec || 0;
+
+ return readOps + writeOps > 0;
+ }
+
+ private calcPercentage(dividend: number, divisor: number) {
+ if (!_.isNumber(dividend) || !_.isNumber(divisor) || divisor === 0) {
+ return 0;
+ }
+
+ return Math.ceil((dividend / divisor) * 100 * 100) / 100;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card-popover.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card-popover.scss
new file mode 100644
index 000000000..43cbe18ff
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card-popover.scss
@@ -0,0 +1,42 @@
+@use './src/styles/vendor/variables' as vv;
+
+.info-card-popover-cluster-status {
+ max-height: 20vh;
+ max-width: 23vw;
+
+ .popover-body {
+ font-size: 1rem;
+ max-height: 19vh;
+ max-width: 100%;
+ overflow: auto;
+ }
+}
+
+@media (max-width: vv.$screen-lg-max) {
+ .info-card-popover-cluster-status {
+ max-width: 31vw;
+ }
+}
+
+@media (max-width: vv.$screen-md-max) {
+ .info-card-popover-cluster-status {
+ max-width: 46vw;
+ }
+}
+@media (max-width: vv.$screen-sm-max) {
+ .info-card-popover-cluster-status {
+ max-width: 83vw;
+ }
+}
+
+.info-card-content-clickable {
+ border: 1px solid vv.$gray-200;
+ border-radius: 3px;
+ cursor: pointer;
+ padding: 7px;
+}
+
+.info-card-content-clickable:hover {
+ background-color: vv.$gray-200;
+ border-color: vv.$gray-400;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.html
new file mode 100644
index 000000000..ef0328502
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.html
@@ -0,0 +1,18 @@
+<div class="card shadow-sm"
+ [ngClass]="cardClass">
+ <div class="card-body d-flex align-items-center justify-content-center">
+ <h4 class="card-title m-4">
+ <a *ngIf="link; else noLinkTitle"
+ [routerLink]="link">{{ cardTitle }}</a>
+
+ <ng-template #noLinkTitle>
+ {{ cardTitle }}
+ </ng-template>
+ </h4>
+
+ <div class="card-text text-center"
+ [ngClass]="contentClass">
+ <ng-content></ng-content>
+ </div>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss
new file mode 100644
index 000000000..897d09a9a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss
@@ -0,0 +1,40 @@
+@use './src/styles/vendor/variables' as vv;
+@use './src/styles/defaults/mixins';
+
+$card-font-min-width: 320px;
+$card-font-max-width: 2048px;
+$card-font-min-size: 12px;
+$card-font-max-size: 21px;
+
+.card {
+ @include mixins.fluid-font-size(
+ $card-font-min-width,
+ $card-font-max-width,
+ $card-font-min-size,
+ $card-font-max-size
+ );
+ border: 0.5px solid vv.$gray-300;
+ border-radius: 3px;
+ height: 100%;
+
+ .card-body {
+ padding-top: 40px !important;
+
+ .card-title {
+ left: -0.6rem;
+ position: absolute;
+ top: -0.3rem;
+ }
+ }
+}
+
+.no-center {
+ left: unset;
+ position: unset;
+ top: unset;
+ transform: unset;
+}
+
+.content-highlight {
+ font-weight: bold;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.spec.ts
new file mode 100644
index 000000000..bde9a9a00
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.spec.ts
@@ -0,0 +1,65 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { InfoCardComponent } from './info-card.component';
+
+describe('InfoCardComponent', () => {
+ let component: InfoCardComponent;
+ let fixture: ComponentFixture<InfoCardComponent>;
+
+ configureTestBed({
+ imports: [RouterTestingModule],
+ declarations: [InfoCardComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(InfoCardComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('Setting cardTitle makes title visible', () => {
+ const cardTitle = 'Card Title';
+ component.cardTitle = cardTitle;
+ fixture.detectChanges();
+ const titleDiv = fixture.debugElement.nativeElement.querySelector('.card-title');
+
+ expect(titleDiv.textContent).toContain(cardTitle);
+ });
+
+ it('Setting link makes anchor visible', () => {
+ const cardTitle = 'Card Title';
+ const link = '/dashboard';
+ component.cardTitle = cardTitle;
+ component.link = link;
+ fixture.detectChanges();
+ const anchor = fixture.debugElement.nativeElement
+ .querySelector('.card-title')
+ .querySelector('a');
+
+ expect(anchor.textContent).toContain(cardTitle);
+ expect(anchor.href).toBe(`http://localhost${link}`);
+ });
+
+ it('Setting cardClass makes class set', () => {
+ const cardClass = 'my-css-card-class';
+ component.cardClass = cardClass;
+ fixture.detectChanges();
+ const card = fixture.debugElement.nativeElement.querySelector(`.card.${cardClass}`);
+
+ expect(card).toBeTruthy();
+ });
+
+ it('Setting contentClass makes class set', () => {
+ const contentClass = 'my-css-content-class';
+ component.contentClass = contentClass;
+ fixture.detectChanges();
+ const card = fixture.debugElement.nativeElement.querySelector(`.card-body .${contentClass}`);
+
+ expect(card).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.ts
new file mode 100644
index 000000000..fdcbe2ece
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.ts
@@ -0,0 +1,17 @@
+import { Component, Input } from '@angular/core';
+
+@Component({
+ selector: 'cd-info-card',
+ templateUrl: './info-card.component.html',
+ styleUrls: ['./info-card.component.scss']
+})
+export class InfoCardComponent {
+ @Input()
+ cardTitle: string;
+ @Input()
+ link: string;
+ @Input()
+ cardClass = '';
+ @Input()
+ contentClass: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.html
new file mode 100644
index 000000000..722824a8f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.html
@@ -0,0 +1,26 @@
+<div class="row">
+ <div class="info-group-title"
+ [ngbPopover]="popInfoTemplate"
+ #popInfo="ngbPopover"
+ triggers="">
+ <span>{{ groupTitle }}</span>
+ <button type="button"
+ class="popover-icon btn btn-link p-0"
+ (click)="popInfo.toggle()">
+ <i [ngClass]="[icons.infoCircle, icons.large]"></i>
+ </button>
+ </div>
+</div>
+
+<div class="row">
+ <ng-content></ng-content>
+</div>
+
+<ng-template #popInfoTemplate>
+ <div class="text-center"
+ i18n>For an overview of {{ groupTitle|lowercase }} widgets click
+ <cd-doc section="dashboard-landing-page-{{ groupTitle|lowercase }}"
+ docText="here"
+ i18n-docText></cd-doc>
+ </div>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.scss
new file mode 100644
index 000000000..52bcddb96
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.scss
@@ -0,0 +1,8 @@
+.info-group-title {
+ font-size: 1.75rem;
+ margin: 0 0 0.5vw 0.5vw;
+}
+
+.popover-icon:focus {
+ box-shadow: none;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.spec.ts
new file mode 100644
index 000000000..73ed55a8f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.spec.ts
@@ -0,0 +1,35 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { InfoGroupComponent } from './info-group.component';
+
+describe('InfoGroupComponent', () => {
+ let component: InfoGroupComponent;
+ let fixture: ComponentFixture<InfoGroupComponent>;
+
+ configureTestBed({
+ imports: [NgbPopoverModule, SharedModule],
+ declarations: [InfoGroupComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(InfoGroupComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('Setting groupTitle makes title visible', () => {
+ const groupTitle = 'Group Title';
+ component.groupTitle = groupTitle;
+ fixture.detectChanges();
+ const titleDiv = fixture.debugElement.nativeElement.querySelector('.info-group-title');
+
+ expect(titleDiv.textContent).toContain(groupTitle);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.ts
new file mode 100644
index 000000000..167db9e2f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.ts
@@ -0,0 +1,14 @@
+import { Component, Input } from '@angular/core';
+
+import { Icons } from '~/app/shared/enum/icons.enum';
+
+@Component({
+ selector: 'cd-info-group',
+ templateUrl: './info-group.component.html',
+ styleUrls: ['./info-group.component.scss']
+})
+export class InfoGroupComponent {
+ icons = Icons;
+ @Input()
+ groupTitle: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-summary.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-summary.pipe.spec.ts
new file mode 100644
index 000000000..c62b35c54
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-summary.pipe.spec.ts
@@ -0,0 +1,72 @@
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { MdsSummaryPipe } from './mds-summary.pipe';
+
+describe('MdsSummaryPipe', () => {
+ let pipe: MdsSummaryPipe;
+
+ configureTestBed({
+ providers: [MdsSummaryPipe]
+ });
+
+ beforeEach(() => {
+ pipe = TestBed.inject(MdsSummaryPipe);
+ });
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms with 0 active and 2 standy', () => {
+ const payload = {
+ standbys: [{ name: 'a' }],
+ filesystems: [{ mdsmap: { info: [{ state: 'up:standby-replay' }] } }]
+ };
+ const expected = [
+ { class: 'popover-info', content: '0 active', titleText: '1 standbyReplay' },
+ { class: 'card-text-line-break', content: '', titleText: '' },
+ { class: 'popover-info', content: '2 standby', titleText: 'standby daemons: a' }
+ ];
+
+ expect(pipe.transform(payload)).toEqual(expected);
+ });
+
+ it('transforms with 1 active and 1 standy', () => {
+ const payload = {
+ standbys: [{ name: 'b' }],
+ filesystems: [{ mdsmap: { info: [{ state: 'up:active', name: 'a' }] } }]
+ };
+ const expected = [
+ { class: 'popover-info', content: '1 active', titleText: 'active daemon: a' },
+ { class: 'card-text-line-break', content: '', titleText: '' },
+ { class: 'popover-info', content: '1 standby', titleText: 'standby daemons: b' }
+ ];
+ expect(pipe.transform(payload)).toEqual(expected);
+ });
+
+ it('transforms with 0 filesystems', () => {
+ const payload: Record<string, any> = {
+ standbys: [0],
+ filesystems: []
+ };
+ const expected = [{ class: 'popover-info', content: 'no filesystems', titleText: '' }];
+
+ expect(pipe.transform(payload)).toEqual(expected);
+ });
+
+ it('transforms without filesystem', () => {
+ const payload = { standbys: [{ name: 'a' }] };
+ const expected = [
+ { class: 'popover-info', content: '1 up', titleText: '' },
+ { class: 'card-text-line-break', content: '', titleText: '' },
+ { class: 'popover-info', content: 'no filesystems', titleText: 'standby daemons: a' }
+ ];
+
+ expect(pipe.transform(payload)).toEqual(expected);
+ });
+
+ it('transforms without value', () => {
+ expect(pipe.transform(undefined)).toBe('');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-summary.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-summary.pipe.ts
new file mode 100644
index 000000000..9cc72ac96
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-summary.pipe.ts
@@ -0,0 +1,78 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import _ from 'lodash';
+
+@Pipe({
+ name: 'mdsSummary'
+})
+export class MdsSummaryPipe implements PipeTransform {
+ transform(value: any): any {
+ if (!value) {
+ return '';
+ }
+
+ let contentLine1 = '';
+ let contentLine2 = '';
+ let standbys = 0;
+ let active = 0;
+ let standbyReplay = 0;
+ _.each(value.standbys, () => {
+ standbys += 1;
+ });
+
+ if (value.standbys && !value.filesystems) {
+ contentLine1 = `${standbys} ${$localize`up`}`;
+ contentLine2 = $localize`no filesystems`;
+ } else if (value.filesystems.length === 0) {
+ contentLine1 = $localize`no filesystems`;
+ } else {
+ _.each(value.filesystems, (fs) => {
+ _.each(fs.mdsmap.info, (mds) => {
+ if (mds.state === 'up:standby-replay') {
+ standbyReplay += 1;
+ } else {
+ active += 1;
+ }
+ });
+ });
+
+ contentLine1 = `${active} ${$localize`active`}`;
+ contentLine2 = `${standbys + standbyReplay} ${$localize`standby`}`;
+ }
+ const standbyHoverText = value.standbys.map((s: any): string => s.name).join(', ');
+ const standbyTitleText = !standbyHoverText
+ ? ''
+ : `${$localize`standby daemons`}: ${standbyHoverText}`;
+ const fsLength = value.filesystems ? value.filesystems.length : 0;
+ const infoObject = fsLength > 0 ? value.filesystems[0].mdsmap.info : {};
+ const activeHoverText = Object.values(infoObject)
+ .map((info: any): string => info.name)
+ .join(', ');
+ let activeTitleText = !activeHoverText ? '' : `${$localize`active daemon`}: ${activeHoverText}`;
+ // There is always one standbyreplay to replace active daemon, if active one is down
+ if (!active && fsLength > 0) {
+ activeTitleText = `${standbyReplay} ${$localize`standbyReplay`}`;
+ }
+ const mgrSummary = [
+ {
+ content: contentLine1,
+ class: 'popover-info',
+ titleText: activeTitleText
+ }
+ ];
+ if (contentLine2) {
+ mgrSummary.push({
+ content: '',
+ class: 'card-text-line-break',
+ titleText: ''
+ });
+ mgrSummary.push({
+ content: contentLine2,
+ class: 'popover-info',
+ titleText: standbyTitleText
+ });
+ }
+
+ return mgrSummary;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-summary.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-summary.pipe.spec.ts
new file mode 100644
index 000000000..8bc275380
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-summary.pipe.spec.ts
@@ -0,0 +1,52 @@
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { MgrSummaryPipe } from './mgr-summary.pipe';
+
+describe('MgrSummaryPipe', () => {
+ let pipe: MgrSummaryPipe;
+
+ configureTestBed({
+ providers: [MgrSummaryPipe]
+ });
+
+ beforeEach(() => {
+ pipe = TestBed.inject(MgrSummaryPipe);
+ });
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms without value', () => {
+ expect(pipe.transform(undefined)).toBe('');
+ });
+
+ it('transforms with active_name undefined', () => {
+ const payload: Record<string, any> = {
+ active_name: undefined,
+ standbys: []
+ };
+ const expected = [
+ { class: 'popover-info', content: 'n/a active', titleText: '' },
+ { class: 'card-text-line-break', content: '', titleText: '' },
+ { class: 'popover-info', content: '0 standby', titleText: '' }
+ ];
+
+ expect(pipe.transform(payload)).toEqual(expected);
+ });
+
+ it('transforms with 1 active and 2 standbys', () => {
+ const payload = {
+ active_name: 'x',
+ standbys: [{ name: 'y' }, { name: 'z' }]
+ };
+ const expected = [
+ { class: 'popover-info', content: '1 active', titleText: 'active daemon: x' },
+ { class: 'card-text-line-break', content: '', titleText: '' },
+ { class: 'popover-info', content: '2 standby', titleText: 'standby daemons: y, z' }
+ ];
+
+ expect(pipe.transform(payload)).toEqual(expected);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-summary.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-summary.pipe.ts
new file mode 100644
index 000000000..ffdee7300
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-summary.pipe.ts
@@ -0,0 +1,48 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import _ from 'lodash';
+
+@Pipe({
+ name: 'mgrSummary'
+})
+export class MgrSummaryPipe implements PipeTransform {
+ transform(value: any): any {
+ if (!value) {
+ return '';
+ }
+
+ let activeCount = $localize`n/a`;
+ const activeTitleText = _.isUndefined(value.active_name)
+ ? ''
+ : `${$localize`active daemon`}: ${value.active_name}`;
+ // There is always one standbyreplay to replace active daemon, if active one is down
+ if (activeTitleText.length > 0) {
+ activeCount = '1';
+ }
+ const standbyHoverText = value.standbys.map((s: any): string => s.name).join(', ');
+ const standbyTitleText = !standbyHoverText
+ ? ''
+ : `${$localize`standby daemons`}: ${standbyHoverText}`;
+ const standbyCount = value.standbys.length;
+ const mgrSummary = [
+ {
+ content: `${activeCount} ${$localize`active`}`,
+ class: 'popover-info',
+ titleText: activeTitleText
+ }
+ ];
+
+ mgrSummary.push({
+ content: '',
+ class: 'card-text-line-break',
+ titleText: ''
+ });
+ mgrSummary.push({
+ content: `${standbyCount} ${$localize`standby`}`,
+ class: 'popover-info',
+ titleText: standbyTitleText
+ });
+
+ return mgrSummary;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.spec.ts
new file mode 100644
index 000000000..b8a083a32
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.spec.ts
@@ -0,0 +1,40 @@
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { MonSummaryPipe } from './mon-summary.pipe';
+
+describe('MonSummaryPipe', () => {
+ let pipe: MonSummaryPipe;
+
+ configureTestBed({
+ providers: [MonSummaryPipe]
+ });
+
+ beforeEach(() => {
+ pipe = TestBed.inject(MonSummaryPipe);
+ });
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms without value', () => {
+ expect(pipe.transform(undefined)).toBe('');
+ });
+
+ it('transforms with 3 mons in quorum', () => {
+ const value = {
+ monmap: { mons: [0, 1, 2] },
+ quorum: [0, 1, 2]
+ };
+ expect(pipe.transform(value)).toBe('3 (quorum 0, 1, 2)');
+ });
+
+ it('transforms with 2/3 mons in quorum', () => {
+ const value = {
+ monmap: { mons: [0, 1, 2] },
+ quorum: [0, 1]
+ };
+ expect(pipe.transform(value)).toBe('3 (quorum 0, 1)');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.ts
new file mode 100644
index 000000000..399045d5d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.ts
@@ -0,0 +1,17 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'monSummary'
+})
+export class MonSummaryPipe implements PipeTransform {
+ transform(value: any): any {
+ if (!value) {
+ return '';
+ }
+
+ const result = $localize`${value.monmap.mons.length.toString()} (quorum \
+${value.quorum.join(', ')})`;
+
+ return result;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-summary.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-summary.pipe.spec.ts
new file mode 100644
index 000000000..22f5eeff3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-summary.pipe.spec.ts
@@ -0,0 +1,193 @@
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { OsdSummaryPipe } from './osd-summary.pipe';
+
+describe('OsdSummaryPipe', () => {
+ let pipe: OsdSummaryPipe;
+
+ configureTestBed({
+ providers: [OsdSummaryPipe]
+ });
+
+ beforeEach(() => {
+ pipe = TestBed.inject(OsdSummaryPipe);
+ });
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms without value', () => {
+ expect(pipe.transform(undefined)).toBe('');
+ });
+
+ it('transforms having 3 osd with 3 up, 3 in, 0 down, 0 out', () => {
+ const value = {
+ osds: [
+ { up: 1, in: 1, state: ['up', 'exists'] },
+ { up: 1, in: 1, state: ['up', 'exists'] },
+ { up: 1, in: 1, state: ['up', 'exists'] }
+ ]
+ };
+ expect(pipe.transform(value)).toEqual([
+ {
+ content: '3 total',
+ class: ''
+ },
+ {
+ content: '',
+ class: 'card-text-line-break'
+ },
+ {
+ content: '3 up, 3 in',
+ class: ''
+ }
+ ]);
+ });
+
+ it('transforms having 3 osd with 2 up, 1 in, 1 down, 2 out', () => {
+ const value = {
+ osds: [
+ { up: 1, in: 1, state: ['up', 'exists'] },
+ { up: 1, in: 0, state: ['up', 'exists'] },
+ { up: 0, in: 0, state: ['exists'] }
+ ]
+ };
+ expect(pipe.transform(value)).toEqual([
+ {
+ content: '3 total',
+ class: ''
+ },
+ {
+ content: '',
+ class: 'card-text-line-break'
+ },
+ {
+ content: '2 up, 1 in',
+ class: ''
+ },
+ {
+ content: '',
+ class: 'card-text-line-break'
+ },
+ {
+ content: '1 down, 2 out',
+ class: 'card-text-error'
+ }
+ ]);
+ });
+
+ it('transforms having 3 osd with 2 up, 3 in, 1 full, 1 nearfull, 1 down, 0 out', () => {
+ const value = {
+ osds: [
+ { up: 1, in: 1, state: ['up', 'nearfull'] },
+ { up: 1, in: 1, state: ['up', 'exists'] },
+ { up: 0, in: 1, state: ['full'] }
+ ]
+ };
+ expect(pipe.transform(value)).toEqual([
+ {
+ content: '3 total',
+ class: ''
+ },
+ {
+ content: '',
+ class: 'card-text-line-break'
+ },
+ {
+ content: '2 up, 3 in',
+ class: ''
+ },
+ {
+ content: '',
+ class: 'card-text-line-break'
+ },
+ {
+ content: '1 down',
+ class: 'card-text-error'
+ },
+ {
+ content: '',
+ class: 'card-text-line-break'
+ },
+ {
+ content: '1 near full',
+ class: 'card-text-error'
+ },
+ {
+ content: '',
+ class: 'card-text-line-break'
+ },
+ {
+ content: '1 full',
+ class: 'card-text-error'
+ }
+ ]);
+ });
+
+ it('transforms having 3 osd with 3 up, 2 in, 0 down, 1 out', () => {
+ const value = {
+ osds: [
+ { up: 1, in: 1, state: ['up', 'exists'] },
+ { up: 1, in: 1, state: ['up', 'exists'] },
+ { up: 1, in: 0, state: ['up', 'exists'] }
+ ]
+ };
+ expect(pipe.transform(value)).toEqual([
+ {
+ content: '3 total',
+ class: ''
+ },
+ {
+ content: '',
+ class: 'card-text-line-break'
+ },
+ {
+ content: '3 up, 2 in',
+ class: ''
+ },
+ {
+ content: '',
+ class: 'card-text-line-break'
+ },
+ {
+ content: '1 out',
+ class: 'card-text-error'
+ }
+ ]);
+ });
+
+ it('transforms having 4 osd with 3 up, 2 in, 1 down, another 2 out', () => {
+ const value = {
+ osds: [
+ { up: 1, in: 1, state: ['up', 'exists'] },
+ { up: 1, in: 0, state: ['up', 'exists'] },
+ { up: 1, in: 0, state: ['up', 'exists'] },
+ { up: 0, in: 1, state: ['exists'] }
+ ]
+ };
+ expect(pipe.transform(value)).toEqual([
+ {
+ content: '4 total',
+ class: ''
+ },
+ {
+ content: '',
+ class: 'card-text-line-break'
+ },
+ {
+ content: '3 up, 2 in',
+ class: ''
+ },
+ {
+ content: '',
+ class: 'card-text-line-break'
+ },
+ {
+ content: '1 down, 2 out',
+ class: 'card-text-error'
+ }
+ ]);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-summary.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-summary.pipe.ts
new file mode 100644
index 000000000..46d2eda6b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-summary.pipe.ts
@@ -0,0 +1,91 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import _ from 'lodash';
+
+@Pipe({
+ name: 'osdSummary'
+})
+export class OsdSummaryPipe implements PipeTransform {
+ transform(value: any): any {
+ if (!value) {
+ return '';
+ }
+
+ let inCount = 0;
+ let upCount = 0;
+ let nearFullCount = 0;
+ let fullCount = 0;
+ _.each(value.osds, (osd) => {
+ if (osd.in) {
+ inCount++;
+ }
+ if (osd.up) {
+ upCount++;
+ }
+ if (osd.state.includes('nearfull')) {
+ nearFullCount++;
+ }
+ if (osd.state.includes('full')) {
+ fullCount++;
+ }
+ });
+
+ const osdSummary = [
+ {
+ content: `${value.osds.length} ${$localize`total`}`,
+ class: ''
+ }
+ ];
+ osdSummary.push({
+ content: '',
+ class: 'card-text-line-break'
+ });
+ osdSummary.push({
+ content: `${upCount} ${$localize`up`}, ${inCount} ${$localize`in`}`,
+ class: ''
+ });
+
+ const downCount = value.osds.length - upCount;
+ const outCount = value.osds.length - inCount;
+ if (downCount > 0 || outCount > 0) {
+ osdSummary.push({
+ content: '',
+ class: 'card-text-line-break'
+ });
+
+ const downText = downCount > 0 ? `${downCount} ${$localize`down`}` : '';
+ const separator = downCount > 0 && outCount > 0 ? ', ' : '';
+ const outText = outCount > 0 ? `${outCount} ${$localize`out`}` : '';
+ osdSummary.push({
+ content: `${downText}${separator}${outText}`,
+ class: 'card-text-error'
+ });
+ }
+
+ if (nearFullCount > 0) {
+ osdSummary.push(
+ {
+ content: '',
+ class: 'card-text-line-break'
+ },
+ {
+ content: `${nearFullCount} ${$localize`near full`}`,
+ class: 'card-text-error'
+ },
+ {
+ content: '',
+ class: 'card-text-line-break'
+ }
+ );
+ }
+
+ if (fullCount > 0) {
+ osdSummary.push({
+ content: `${fullCount} ${$localize`full`}`,
+ class: 'card-text-error'
+ });
+ }
+
+ return osdSummary;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/models/nfs.fsal.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/models/nfs.fsal.ts
new file mode 100644
index 000000000..f204ac6d8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/models/nfs.fsal.ts
@@ -0,0 +1,5 @@
+export interface NfsFSAbstractionLayer {
+ value: string;
+ descr: string;
+ disabled: boolean;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.html
new file mode 100644
index 000000000..2a8b9453f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.html
@@ -0,0 +1,32 @@
+<ng-container *ngIf="selection">
+ <ul ngbNav
+ #nav="ngbNav"
+ class="nav-tabs"
+ cdStatefulTab="nfs-details">
+ <li ngbNavItem="details">
+ <a ngbNavLink
+ i18n>Details</a>
+ <ng-template ngbNavContent>
+ <cd-table-key-value [data]="data">
+ </cd-table-key-value>
+ </ng-template>
+ </li>
+ <li ngbNavItem="clients">
+ <a ngbNavLink
+ i18n>Clients ({{ clients.length }})</a>
+ <ng-template ngbNavContent>
+
+ <cd-table #table
+ [data]="clients"
+ columnMode="flex"
+ [columns]="clientsColumns"
+ identifier="addresses"
+ forceIdentifier="true"
+ selectionType="">
+ </cd-table>
+ </ng-template>
+ </li>
+ </ul>
+
+ <div [ngbNavOutlet]="nav"></div>
+</ng-container>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.spec.ts
new file mode 100644
index 000000000..fcf530539
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.spec.ts
@@ -0,0 +1,102 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { NfsDetailsComponent } from './nfs-details.component';
+
+describe('NfsDetailsComponent', () => {
+ let component: NfsDetailsComponent;
+ let fixture: ComponentFixture<NfsDetailsComponent>;
+
+ const elem = (css: string) => fixture.debugElement.query(By.css(css));
+
+ configureTestBed({
+ declarations: [NfsDetailsComponent],
+ imports: [BrowserAnimationsModule, SharedModule, HttpClientTestingModule, NgbNavModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(NfsDetailsComponent);
+ component = fixture.componentInstance;
+
+ component.selection = {
+ export_id: 1,
+ path: '/qwe',
+ fsal: { name: 'CEPH', user_id: 'fs', fs_name: 1 },
+ cluster_id: 'cluster1',
+ pseudo: '/qwe',
+ access_type: 'RW',
+ squash: 'no_root_squash',
+ protocols: [4],
+ transports: ['TCP', 'UDP'],
+ clients: [
+ {
+ addresses: ['192.168.0.10', '192.168.1.0/8'],
+ access_type: 'RW',
+ squash: 'root_id_squash'
+ }
+ ]
+ };
+ component.ngOnChanges();
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component.data).toBeTruthy();
+ });
+
+ it('should prepare data', () => {
+ expect(component.data).toEqual({
+ 'Access Type': 'RW',
+ 'CephFS Filesystem': 1,
+ 'CephFS User': 'fs',
+ Cluster: 'cluster1',
+ 'NFS Protocol': ['NFSv4'],
+ Path: '/qwe',
+ Pseudo: '/qwe',
+ 'Security Label': undefined,
+ Squash: 'no_root_squash',
+ 'Storage Backend': 'CephFS',
+ Transport: ['TCP', 'UDP']
+ });
+ });
+
+ it('should prepare data if RGW', () => {
+ const newData = _.assignIn(component.selection, {
+ fsal: {
+ name: 'RGW',
+ user_id: 'user-id'
+ }
+ });
+ component.selection = newData;
+ component.ngOnChanges();
+ expect(component.data).toEqual({
+ 'Access Type': 'RW',
+ Cluster: 'cluster1',
+ 'NFS Protocol': ['NFSv4'],
+ 'Object Gateway User': 'user-id',
+ Path: '/qwe',
+ Pseudo: '/qwe',
+ Squash: 'no_root_squash',
+ 'Storage Backend': 'Object Gateway',
+ Transport: ['TCP', 'UDP']
+ });
+ });
+
+ it('should have 1 client', () => {
+ expect(elem('ul.nav-tabs li:nth-of-type(2) a').nativeElement.textContent).toBe('Clients (1)');
+ expect(component.clients).toEqual([
+ {
+ access_type: 'RW',
+ addresses: ['192.168.0.10', '192.168.1.0/8'],
+ squash: 'root_id_squash'
+ }
+ ]);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.ts
new file mode 100644
index 000000000..5a84bd52e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.ts
@@ -0,0 +1,68 @@
+import { Component, Input, OnChanges } from '@angular/core';
+
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+
+@Component({
+ selector: 'cd-nfs-details',
+ templateUrl: './nfs-details.component.html',
+ styleUrls: ['./nfs-details.component.scss']
+})
+export class NfsDetailsComponent implements OnChanges {
+ @Input()
+ selection: any;
+
+ selectedItem: any;
+ data: any;
+
+ clientsColumns: CdTableColumn[];
+ clients: any[] = [];
+
+ constructor() {
+ this.clientsColumns = [
+ {
+ name: $localize`Addresses`,
+ prop: 'addresses',
+ flexGrow: 2
+ },
+ {
+ name: $localize`Access Type`,
+ prop: 'access_type',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Squash`,
+ prop: 'squash',
+ flexGrow: 1
+ }
+ ];
+ }
+
+ ngOnChanges() {
+ if (this.selection) {
+ this.selectedItem = this.selection;
+
+ this.clients = this.selectedItem.clients;
+
+ this.data = {};
+ this.data[$localize`Cluster`] = this.selectedItem.cluster_id;
+ this.data[$localize`NFS Protocol`] = this.selectedItem.protocols.map(
+ (protocol: string) => 'NFSv' + protocol
+ );
+ this.data[$localize`Pseudo`] = this.selectedItem.pseudo;
+ this.data[$localize`Access Type`] = this.selectedItem.access_type;
+ this.data[$localize`Squash`] = this.selectedItem.squash;
+ this.data[$localize`Transport`] = this.selectedItem.transports;
+ this.data[$localize`Path`] = this.selectedItem.path;
+
+ if (this.selectedItem.fsal.name === 'CEPH') {
+ this.data[$localize`Storage Backend`] = $localize`CephFS`;
+ this.data[$localize`CephFS User`] = this.selectedItem.fsal.user_id;
+ this.data[$localize`CephFS Filesystem`] = this.selectedItem.fsal.fs_name;
+ this.data[$localize`Security Label`] = this.selectedItem.fsal.sec_label_xattr;
+ } else {
+ this.data[$localize`Storage Backend`] = $localize`Object Gateway`;
+ this.data[$localize`Object Gateway User`] = this.selectedItem.fsal.user_id;
+ }
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html
new file mode 100644
index 000000000..117ad371d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html
@@ -0,0 +1,109 @@
+<div class="form-group row">
+ <label class="cd-col-form-label"
+ i18n>Clients</label>
+
+ <div class="cd-col-form-input"
+ [formGroup]="form"
+ #formDir="ngForm">
+ <span *ngIf="form.get('clients').value.length === 0"
+ class="no-border text-muted">
+ <span class="form-text text-muted"
+ i18n>Any client can access</span>
+ </span>
+
+ <ng-container formArrayName="clients">
+ <div *ngFor="let item of clientsFormArray.controls; let index = index; trackBy: trackByFn">
+ <div class="card"
+ [formGroup]="item">
+ <div class="card-header">
+ {{ (index + 1) | ordinal }}
+ <span class="float-right clickable"
+ name="remove_client"
+ (click)="removeClient(index)"
+ ngbTooltip="Remove">&times;</span>
+ </div>
+
+ <div class="card-body">
+ <!-- Addresses -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label required"
+ for="addresses">Addresses</label>
+ <div class="cd-col-form-input">
+ <input type="text"
+ class="form-control"
+ name="addresses"
+ id="addresses"
+ formControlName="addresses"
+ placeholder="192.168.0.10, 192.168.1.0/8">
+ <span class="invalid-feedback">
+ <span *ngIf="showError(index, 'addresses', formDir, 'required')"
+ i18n>This field is required.</span>
+
+ <span *ngIf="showError(index, 'addresses', formDir, 'pattern')">
+ <ng-container i18n>Must contain one or more comma-separated values</ng-container>
+ <br>
+ <ng-container i18n>For example:</ng-container> 192.168.0.10, 192.168.1.0/8
+ </span>
+ </span>
+ </div>
+ </div>
+
+ <!-- Access Type-->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="access_type">Access Type</label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ name="access_type"
+ id="access_type"
+ formControlName="access_type">
+ <option value="">{{ getNoAccessTypeDescr() }}</option>
+ <option *ngFor="let item of nfsAccessType"
+ [value]="item.value">{{ item.value }}</option>
+ </select>
+ <span class="form-text text-muted"
+ *ngIf="getValue(index, 'access_type')">
+ {{ getAccessTypeHelp(index) }}
+ </span>
+ </div>
+ </div>
+
+ <!-- Squash -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="squash">
+ <span i18n>Squash</span>
+ <ng-container *ngTemplateOutlet="squashHelperTpl"></ng-container>
+ </label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ name="squash"
+ id="squash"
+ formControlName="squash">
+ <option value="">{{ getNoSquashDescr() }}</option>
+ <option *ngFor="let squash of nfsSquash"
+ [value]="squash">{{ squash }}</option>
+ </select>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </ng-container>
+
+ <div class="row">
+ <div class="col-12">
+ <div class="float-right">
+ <button class="btn btn-light "
+ (click)="addClient()"
+ name="add_client">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>Add clients</ng-container>
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.spec.ts
new file mode 100644
index 000000000..70d885d84
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.spec.ts
@@ -0,0 +1,71 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormControl, ReactiveFormsModule } from '@angular/forms';
+
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { NfsFormClientComponent } from './nfs-form-client.component';
+
+describe('NfsFormClientComponent', () => {
+ let component: NfsFormClientComponent;
+ let fixture: ComponentFixture<NfsFormClientComponent>;
+
+ configureTestBed({
+ declarations: [NfsFormClientComponent],
+ imports: [ReactiveFormsModule, SharedModule, HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(NfsFormClientComponent);
+ const formBuilder = TestBed.inject(CdFormBuilder);
+ component = fixture.componentInstance;
+
+ component.form = new CdFormGroup({
+ access_type: new FormControl(''),
+ clients: formBuilder.array([]),
+ squash: new FormControl('')
+ });
+
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should add a client', () => {
+ expect(component.form.getValue('clients')).toEqual([]);
+ component.addClient();
+ expect(component.form.getValue('clients')).toEqual([
+ { access_type: '', addresses: '', squash: '' }
+ ]);
+ });
+
+ it('should return form access_type', () => {
+ expect(component.getNoAccessTypeDescr()).toBe('-- Select the access type --');
+
+ component.form.patchValue({ access_type: 'RW' });
+ expect(component.getNoAccessTypeDescr()).toBe('RW (inherited from global config)');
+ });
+
+ it('should return form squash', () => {
+ expect(component.getNoSquashDescr()).toBe(
+ '-- Select what kind of user id squashing is performed --'
+ );
+
+ component.form.patchValue({ squash: 'root_id_squash' });
+ expect(component.getNoSquashDescr()).toBe('root_id_squash (inherited from global config)');
+ });
+
+ it('should remove client', () => {
+ component.addClient();
+ expect(component.form.getValue('clients')).toEqual([
+ { access_type: '', addresses: '', squash: '' }
+ ]);
+
+ component.removeClient(0);
+ expect(component.form.getValue('clients')).toEqual([]);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts
new file mode 100644
index 000000000..15e7d7d5c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts
@@ -0,0 +1,95 @@
+import { Component, ContentChild, Input, OnInit, TemplateRef } from '@angular/core';
+import { FormArray, FormControl, NgForm, Validators } from '@angular/forms';
+
+import _ from 'lodash';
+
+import { NfsService } from '~/app/shared/api/nfs.service';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+
+@Component({
+ selector: 'cd-nfs-form-client',
+ templateUrl: './nfs-form-client.component.html',
+ styleUrls: ['./nfs-form-client.component.scss']
+})
+export class NfsFormClientComponent implements OnInit {
+ @Input()
+ form: CdFormGroup;
+
+ @Input()
+ clients: any[];
+
+ @ContentChild('squashHelper', { static: true }) squashHelperTpl: TemplateRef<any>;
+
+ nfsSquash: any[] = Object.keys(this.nfsService.nfsSquash);
+ nfsAccessType: any[] = this.nfsService.nfsAccessType;
+ icons = Icons;
+ clientsFormArray: FormArray;
+
+ constructor(private nfsService: NfsService) {}
+
+ ngOnInit() {
+ _.forEach(this.clients, (client) => {
+ const fg = this.addClient();
+ fg.patchValue(client);
+ });
+ this.clientsFormArray = this.form.get('clients') as FormArray;
+ }
+
+ getNoAccessTypeDescr() {
+ if (this.form.getValue('access_type')) {
+ return `${this.form.getValue('access_type')} ${$localize`(inherited from global config)`}`;
+ }
+ return $localize`-- Select the access type --`;
+ }
+
+ getAccessTypeHelp(index: number) {
+ const accessTypeItem = this.nfsAccessType.find((currentAccessTypeItem) => {
+ return this.getValue(index, 'access_type') === currentAccessTypeItem.value;
+ });
+ return _.isObjectLike(accessTypeItem) ? accessTypeItem.help : '';
+ }
+
+ getNoSquashDescr() {
+ if (this.form.getValue('squash')) {
+ return `${this.form.getValue('squash')} (${$localize`inherited from global config`})`;
+ }
+ return $localize`-- Select what kind of user id squashing is performed --`;
+ }
+
+ addClient() {
+ this.clientsFormArray = this.form.get('clients') as FormArray;
+
+ const REGEX_IP = `(([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\.([0-9]{1,3})([/](\\d|[1-2]\\d|3[0-2]))?)`;
+ const REGEX_LIST_IP = `${REGEX_IP}([ ,]{1,2}${REGEX_IP})*`;
+ const fg = new CdFormGroup({
+ addresses: new FormControl('', {
+ validators: [Validators.required, Validators.pattern(REGEX_LIST_IP)]
+ }),
+ access_type: new FormControl(''),
+ squash: new FormControl('')
+ });
+
+ this.clientsFormArray.push(fg);
+ return fg;
+ }
+
+ removeClient(index: number) {
+ this.clientsFormArray = this.form.get('clients') as FormArray;
+ this.clientsFormArray.removeAt(index);
+ }
+
+ showError(index: number, control: string, formDir: NgForm, x: string) {
+ return (<any>this.form.controls.clients).controls[index].showError(control, formDir, x);
+ }
+
+ getValue(index: number, control: string) {
+ this.clientsFormArray = this.form.get('clients') as FormArray;
+ const client = this.clientsFormArray.at(index) as CdFormGroup;
+ return client.getValue(control);
+ }
+
+ trackByFn(index: number) {
+ return index;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html
new file mode 100644
index 000000000..7313ea69b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html
@@ -0,0 +1,400 @@
+<div class="cd-col-form"
+ *cdFormLoading="loading">
+ <form name="nfsForm"
+ #formDir="ngForm"
+ [formGroup]="nfsForm"
+ novalidate>
+ <div class="card">
+ <div i18n="form title"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
+
+ <div class="card-body">
+ <!-- cluster_id -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="cluster_id">
+ <span class="required"
+ i18n>Cluster</span>
+ <cd-helper>
+ <p i18n>This is the ID of an NFS Service.</p>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ formControlName="cluster_id"
+ name="cluster_id"
+ id="cluster_id">
+ <option *ngIf="allClusters === null"
+ value=""
+ i18n>Loading...</option>
+ <option *ngIf="allClusters !== null && allClusters.length === 0"
+ value=""
+ i18n>-- No cluster available --</option>
+ <option *ngIf="allClusters !== null && allClusters.length > 0"
+ value=""
+ i18n>-- Select the cluster --</option>
+ <option *ngFor="let cluster of allClusters"
+ [value]="cluster.cluster_id">{{ cluster.cluster_id }}</option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="nfsForm.showError('cluster_id', formDir, 'required') || allClusters?.length === 0"
+ i18n>This field is required.
+ To create a new NFS cluster, <a [routerLink]="['/services', {outlets: {modal: ['create']}}]"
+ class="btn-link">add a new NFS Service</a>.</span>
+ </div>
+ </div>
+
+ <!-- FSAL -->
+ <div formGroupName="fsal">
+ <!-- Name -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="name"
+ i18n>Storage Backend</label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ formControlName="name"
+ name="name"
+ id="name"
+ (change)="fsalChangeHandler()">
+ <option *ngIf="allFsals === null"
+ value=""
+ i18n>Loading...</option>
+ <option *ngIf="allFsals !== null && allFsals.length === 0"
+ value=""
+ i18n>-- No data pools available --</option>
+ <option *ngIf="allFsals !== null && allFsals.length > 0"
+ value=""
+ i18n>-- Select the storage backend --</option>
+ <option *ngFor="let fsal of allFsals"
+ [value]="fsal.value"
+ [disabled]="fsal.disabled">{{ fsal.descr }}</option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="nfsForm.showError('name', formDir, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="fsalAvailabilityError"
+ i18n>{{ fsalAvailabilityError }}</span>
+ </div>
+ </div>
+
+ <!-- CephFS Volume -->
+ <div class="form-group row"
+ *ngIf="nfsForm.getValue('name') === 'CEPH'">
+ <label class="cd-col-form-label required"
+ for="fs_name"
+ i18n>Volume</label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ formControlName="fs_name"
+ name="fs_name"
+ id="fs_name"
+ (change)="pathChangeHandler()">
+ <option *ngIf="allFsNames === null"
+ value=""
+ i18n>Loading...</option>
+ <option *ngIf="allFsNames !== null && allFsNames.length === 0"
+ value=""
+ i18n>-- No CephFS filesystem available --</option>
+ <option *ngIf="allFsNames !== null && allFsNames.length > 0"
+ value=""
+ i18n>-- Select the CephFS filesystem --</option>
+ <option *ngFor="let filesystem of allFsNames"
+ [value]="filesystem.name">{{ filesystem.name }}</option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="nfsForm.showError('fs_name', formDir, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+ </div>
+
+ <!-- Security Label -->
+ <div class="form-group row"
+ *ngIf="nfsForm.getValue('name') === 'CEPH'">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': nfsForm.getValue('security_label')}"
+ for="security_label"
+ i18n>Security Label</label>
+
+ <div class="cd-col-form-input">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ formControlName="security_label"
+ name="security_label"
+ id="security_label">
+ <label for="security_label"
+ class="custom-control-label"
+ i18n>Enable security label</label>
+ </div>
+
+ <br>
+
+ <input type="text"
+ *ngIf="nfsForm.getValue('security_label')"
+ class="form-control"
+ name="sec_label_xattr"
+ id="sec_label_xattr"
+ formControlName="sec_label_xattr">
+
+ <span class="invalid-feedback"
+ *ngIf="nfsForm.showError('sec_label_xattr', formDir, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Path -->
+ <div class="form-group row"
+ *ngIf="nfsForm.getValue('name') === 'CEPH'">
+ <label class="cd-col-form-label"
+ for="path">
+ <span class="required"
+ i18n>CephFS Path</span>
+ <cd-helper>
+ <p i18n>A path in a CephFS file system.</p>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input type="text"
+ class="form-control"
+ name="path"
+ id="path"
+ data-testid="fs_path"
+ formControlName="path"
+ [ngbTypeahead]="pathDataSource"
+ (selectItem)="pathChangeHandler()"
+ (blur)="pathChangeHandler()">
+ <span class="invalid-feedback"
+ *ngIf="nfsForm.showError('path', formDir, 'required')"
+ i18n>This field is required.</span>
+
+ <span class="invalid-feedback"
+ *ngIf="nfsForm.showError('path', formDir, 'pattern')"
+ i18n>Path need to start with a '/' and can be followed by a word</span>
+ <span class="invalid-feedback"
+ *ngIf="nfsForm.showError('path', formDir, 'pathNameNotAllowed')"
+ i18n>The path does not exist in the selected volume.</span>
+ </div>
+ </div>
+
+ <!-- Bucket -->
+ <div class="form-group row"
+ *ngIf="nfsForm.getValue('name') === 'RGW'">
+ <label class="cd-col-form-label"
+ for="path">
+ <span class="required"
+ i18n>Bucket</span>
+ </label>
+ <div class="cd-col-form-input">
+ <input type="text"
+ class="form-control"
+ name="path"
+ id="path"
+ data-testid="rgw_path"
+ formControlName="path"
+ [ngbTypeahead]="bucketDataSource">
+
+ <span class="invalid-feedback"
+ *ngIf="nfsForm.showError('path', formDir, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="nfsForm.showError('path', formDir, 'bucketNameNotAllowed')"
+ i18n>The bucket does not exist or is not in the default realm (if multiple realms are configured).
+ To continue, <a routerLink="/rgw/bucket/create"
+ class="btn-link">create a new bucket</a>.</span>
+ </div>
+ </div>
+
+ <!-- NFS Protocol -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="protocols"
+ i18n>NFS Protocol</label>
+ <div class="cd-col-form-input">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ formControlName="protocolNfsv4"
+ name="protocolNfsv4"
+ id="protocolNfsv4"
+ disabled>
+ <label i18n
+ class="custom-control-label"
+ for="protocolNfsv4">NFSv4</label>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="nfsForm.showError('protocolNfsv4', formDir, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Pseudo -->
+ <div class="form-group row"
+ *ngIf="nfsForm.getValue('protocolNfsv4')">
+ <label class="cd-col-form-label"
+ for="pseudo">
+ <span class="required"
+ i18n>Pseudo</span>
+ <cd-helper>
+ <p i18n>The position that this <strong>NFS v4</strong> export occupies
+ in the <strong>Pseudo FS</strong> (it must be unique).</p>
+ <p i18n>By using different Pseudo options, the same Path may be exported multiple times.</p>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input type="text"
+ class="form-control"
+ name="pseudo"
+ id="pseudo"
+ formControlName="pseudo">
+ <span class="invalid-feedback"
+ *ngIf="nfsForm.showError('pseudo', formDir, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="nfsForm.showError('pseudo', formDir, 'pseudoAlreadyExists')"
+ i18n>The pseudo is already in use by another export.</span>
+ <span class="invalid-feedback"
+ *ngIf="nfsForm.showError('pseudo', formDir, 'pattern')"
+ i18n>Pseudo needs to start with a '/' and can't contain any of the following: &gt;, &lt;, |, &, ( or ).</span>
+ </div>
+ </div>
+
+ <!-- Access Type -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="access_type"
+ i18n>Access Type</label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ formControlName="access_type"
+ name="access_type"
+ id="access_type"
+ (change)="accessTypeChangeHandler()">
+ <option *ngIf="nfsAccessType === null"
+ value=""
+ i18n>Loading...</option>
+ <option *ngIf="nfsAccessType !== null && nfsAccessType.length === 0"
+ value=""
+ i18n>-- No access type available --</option>
+ <option *ngFor="let accessType of nfsAccessType"
+ [value]="accessType.value">{{ accessType.value }}</option>
+ </select>
+ <span class="form-text text-muted"
+ *ngIf="nfsForm.getValue('access_type')">
+ {{ getAccessTypeHelp(nfsForm.getValue('access_type')) }}
+ </span>
+ <span class="form-text text-warning"
+ *ngIf="nfsForm.getValue('access_type') === 'RW' && nfsForm.getValue('name') === 'RGW'"
+ i18n>The Object Gateway NFS backend has a number of
+ limitations which will seriously affect applications writing to
+ the share. Please consult the <cd-doc section="rgw-nfs"></cd-doc>
+ for details before enabling write access.</span>
+ <span class="invalid-feedback"
+ *ngIf="nfsForm.showError('access_type', formDir, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Squash -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="squash">
+ <span i18n>Squash</span>
+ <ng-container *ngTemplateOutlet="squashHelper"></ng-container>
+ </label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ name="squash"
+ formControlName="squash"
+ id="squash">
+ <option *ngIf="nfsSquash === null"
+ value=""
+ i18n>Loading...</option>
+ <option *ngIf="nfsSquash !== null && nfsSquash.length === 0"
+ value=""
+ i18n>-- No squash available --</option>
+ <option *ngFor="let squash of nfsSquash"
+ [value]="squash">{{ squash }}</option>
+
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="nfsForm.showError('squash', formDir,'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Transport Protocol -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="transports"
+ i18n>Transport Protocol</label>
+ <div class="cd-col-form-input">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ formControlName="transportUDP"
+ name="transportUDP"
+ id="transportUDP">
+ <label for="transportUDP"
+ class="custom-control-label"
+ i18n>UDP</label>
+ </div>
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ formControlName="transportTCP"
+ name="transportTCP"
+ id="transportTCP">
+ <label for="transportTCP"
+ class="custom-control-label"
+ i18n>TCP</label>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="nfsForm.showError('transportUDP', formDir, 'required') ||
+ nfsForm.showError('transportTCP', formDir, 'required')"
+ i18n>This field is required.</span>
+ <hr>
+ </div>
+ </div>
+
+ <!-- Clients -->
+ <cd-nfs-form-client [form]="nfsForm"
+ [clients]="clients"
+ #nfsClients>
+ <ng-template #squashHelper>
+ <cd-helper>
+ <ul class="squash-helper">
+ <li>
+ <span class="squash-helper-item-value">no_root_squash: </span>
+ <span i18n>No user id squashing is performed.</span>
+ </li>
+ <li>
+ <span class="squash-helper-item-value">root_id_squash: </span>
+ <span i18n>uid 0 and gid 0 are squashed to the Anonymous_Uid and Anonymous_Gid gid 0 in alt_groups lists is also squashed.</span>
+ </li>
+ <li>
+ <span class="squash-helper-item-value">root_squash: </span>
+ <span i18n>uid 0 and gid of any value are squashed to the Anonymous_Uid and Anonymous_Gid alt_groups lists is discarded.</span>
+ </li>
+ <li>
+ <span class="squash-helper-item-value">all_squash: </span>
+ <span i18n>All users are squashed.</span>
+ </li>
+ </ul>
+ </cd-helper>
+ </ng-template>
+ </cd-nfs-form-client>
+
+ </div>
+
+ <div class="card-footer">
+ <cd-form-button-panel (submitActionEvent)="submitAction()"
+ [form]="nfsForm"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
+ wrappingClass="text-right"></cd-form-button-panel>
+ </div>
+ </div>
+ </form>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.scss
new file mode 100644
index 000000000..4d892a120
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.scss
@@ -0,0 +1,11 @@
+.cd-mb {
+ margin-bottom: 10px;
+}
+
+.squash-helper {
+ padding-left: 1rem;
+}
+
+.squash-helper-item-value {
+ font-weight: bold;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.spec.ts
new file mode 100644
index 000000000..62efec423
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.spec.ts
@@ -0,0 +1,238 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { ActivatedRoute } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { Observable, of } from 'rxjs';
+
+import { NfsFormClientComponent } from '~/app/ceph/nfs/nfs-form-client/nfs-form-client.component';
+import { NfsFormComponent } from '~/app/ceph/nfs/nfs-form/nfs-form.component';
+import { Directory } from '~/app/shared/api/nfs.service';
+import { LoadingPanelComponent } from '~/app/shared/components/loading-panel/loading-panel.component';
+import { SharedModule } from '~/app/shared/shared.module';
+import { ActivatedRouteStub } from '~/testing/activated-route-stub';
+import { configureTestBed, RgwHelper } from '~/testing/unit-test-helper';
+
+describe('NfsFormComponent', () => {
+ let component: NfsFormComponent;
+ let fixture: ComponentFixture<NfsFormComponent>;
+ let httpTesting: HttpTestingController;
+ let activatedRoute: ActivatedRouteStub;
+
+ configureTestBed(
+ {
+ declarations: [NfsFormComponent, NfsFormClientComponent],
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ RouterTestingModule,
+ SharedModule,
+ ToastrModule.forRoot(),
+ NgbTypeaheadModule
+ ],
+ providers: [
+ {
+ provide: ActivatedRoute,
+ useValue: new ActivatedRouteStub({ cluster_id: 'mynfs', export_id: '1' })
+ }
+ ]
+ },
+ [LoadingPanelComponent]
+ );
+
+ const matchSquash = (backendSquashValue: string, uiSquashValue: string) => {
+ component.ngOnInit();
+ httpTesting.expectOne('ui-api/nfs-ganesha/fsals').flush(['CEPH', 'RGW']);
+ httpTesting.expectOne('ui-api/nfs-ganesha/cephfs/filesystems').flush([{ id: 1, name: 'a' }]);
+ httpTesting.expectOne('api/nfs-ganesha/cluster').flush(['mynfs']);
+ httpTesting.expectOne('api/nfs-ganesha/export/mynfs/1').flush({
+ fsal: {
+ name: 'RGW'
+ },
+ export_id: 1,
+ transports: ['TCP', 'UDP'],
+ protocols: [4],
+ clients: [],
+ squash: backendSquashValue
+ });
+ httpTesting.verify();
+ expect(component.nfsForm.value).toMatchObject({
+ squash: uiSquashValue
+ });
+ };
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(NfsFormComponent);
+ component = fixture.componentInstance;
+ httpTesting = TestBed.inject(HttpTestingController);
+ activatedRoute = <ActivatedRouteStub>TestBed.inject(ActivatedRoute);
+ RgwHelper.selectDaemon();
+ fixture.detectChanges();
+
+ httpTesting.expectOne('ui-api/nfs-ganesha/fsals').flush(['CEPH', 'RGW']);
+ httpTesting.expectOne('ui-api/nfs-ganesha/cephfs/filesystems').flush([{ id: 1, name: 'a' }]);
+ httpTesting.expectOne('api/nfs-ganesha/cluster').flush(['mynfs']);
+ httpTesting.verify();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should process all data', () => {
+ expect(component.allFsals).toEqual([
+ { descr: 'CephFS', value: 'CEPH', disabled: false },
+ { descr: 'Object Gateway', value: 'RGW', disabled: false }
+ ]);
+ expect(component.allFsNames).toEqual([{ id: 1, name: 'a' }]);
+ expect(component.allClusters).toEqual([{ cluster_id: 'mynfs' }]);
+ });
+
+ it('should create the form', () => {
+ expect(component.nfsForm.value).toEqual({
+ access_type: 'RW',
+ clients: [],
+ cluster_id: 'mynfs',
+ fsal: { fs_name: 'a', name: 'CEPH' },
+ path: '/',
+ protocolNfsv4: true,
+ pseudo: '',
+ sec_label_xattr: 'security.selinux',
+ security_label: false,
+ squash: 'no_root_squash',
+ transportTCP: true,
+ transportUDP: true
+ });
+ expect(component.nfsForm.get('cluster_id').disabled).toBeFalsy();
+ });
+
+ it('should prepare data when selecting an cluster', () => {
+ component.nfsForm.patchValue({ cluster_id: 'cluster1' });
+
+ component.nfsForm.patchValue({ cluster_id: 'cluster2' });
+ });
+
+ it('should not allow changing cluster in edit mode', () => {
+ component.isEdit = true;
+ component.ngOnInit();
+ expect(component.nfsForm.get('cluster_id').disabled).toBeTruthy();
+ });
+
+ it('should mark NFSv4 protocol as enabled always', () => {
+ expect(component.nfsForm.get('protocolNfsv4')).toBeTruthy();
+ });
+
+ it('should match backend squash values with ui values', () => {
+ component.isEdit = true;
+ matchSquash('none', 'no_root_squash');
+ matchSquash('all', 'all_squash');
+ matchSquash('rootid', 'root_id_squash');
+ matchSquash('root', 'root_squash');
+ });
+
+ describe('should submit request', () => {
+ beforeEach(() => {
+ component.nfsForm.patchValue({
+ access_type: 'RW',
+ clients: [],
+ cluster_id: 'cluster1',
+ fsal: { name: 'CEPH', fs_name: 1 },
+ path: '/foo',
+ protocolNfsv4: true,
+ pseudo: '/baz',
+ squash: 'no_root_squash',
+ transportTCP: true,
+ transportUDP: true
+ });
+ });
+
+ it('should call update', () => {
+ activatedRoute.setParams({ cluster_id: 'cluster1', export_id: '1' });
+ component.isEdit = true;
+ component.cluster_id = 'cluster1';
+ component.export_id = '1';
+ component.nfsForm.patchValue({ export_id: 1 });
+ component.submitAction();
+
+ const req = httpTesting.expectOne('api/nfs-ganesha/export/cluster1/1');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({
+ access_type: 'RW',
+ clients: [],
+ cluster_id: 'cluster1',
+ export_id: 1,
+ fsal: { fs_name: 1, name: 'CEPH', sec_label_xattr: null },
+ path: '/foo',
+ protocols: [4],
+ pseudo: '/baz',
+ security_label: false,
+ squash: 'no_root_squash',
+ transports: ['TCP', 'UDP']
+ });
+ });
+
+ it('should call create', () => {
+ activatedRoute.setParams({ cluster_id: undefined, export_id: undefined });
+ component.submitAction();
+
+ const req = httpTesting.expectOne('api/nfs-ganesha/export');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual({
+ access_type: 'RW',
+ clients: [],
+ cluster_id: 'cluster1',
+ fsal: {
+ fs_name: 1,
+ name: 'CEPH',
+ sec_label_xattr: null
+ },
+ path: '/foo',
+ protocols: [4],
+ pseudo: '/baz',
+ security_label: false,
+ squash: 'no_root_squash',
+ transports: ['TCP', 'UDP']
+ });
+ });
+ });
+
+ describe('pathExistence', () => {
+ beforeEach(() => {
+ component['nfsService']['lsDir'] = jest.fn(
+ (): Observable<Directory> => of({ paths: ['/path1'] })
+ );
+ component.nfsForm.get('name').setValue('CEPH');
+ component.setPathValidation();
+ });
+
+ const testValidator = (pathName: string, valid: boolean, expectedError?: string) => {
+ const path = component.nfsForm.get('path');
+ path.setValue(pathName);
+ path.markAsDirty();
+ path.updateValueAndValidity();
+
+ if (valid) {
+ expect(path.errors).toBe(null);
+ } else {
+ expect(path.hasError(expectedError)).toBeTruthy();
+ }
+ };
+
+ it('path cannot be empty', () => {
+ testValidator('', false, 'required');
+ });
+
+ it('path that does not exist should be invalid', () => {
+ testValidator('/path2', false, 'pathNameNotAllowed');
+ expect(component['nfsService']['lsDir']).toHaveBeenCalledTimes(1);
+ });
+
+ it('path that exists should be valid', () => {
+ testValidator('/path1', true);
+ expect(component['nfsService']['lsDir']).toHaveBeenCalledTimes(1);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts
new file mode 100644
index 000000000..595b3b7fe
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts
@@ -0,0 +1,535 @@
+import { ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core';
+import {
+ AbstractControl,
+ AsyncValidatorFn,
+ FormControl,
+ ValidationErrors,
+ Validators
+} from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+
+import _ from 'lodash';
+import { forkJoin, Observable, of } from 'rxjs';
+import { catchError, debounceTime, distinctUntilChanged, map, mergeMap } from 'rxjs/operators';
+
+import { NfsFSAbstractionLayer } from '~/app/ceph/nfs/models/nfs.fsal';
+import { Directory, NfsService } from '~/app/shared/api/nfs.service';
+import { RgwBucketService } from '~/app/shared/api/rgw-bucket.service';
+import { RgwSiteService } from '~/app/shared/api/rgw-site.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdForm } from '~/app/shared/forms/cd-form';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { Permission } from '~/app/shared/models/permissions';
+import { CdHttpErrorResponse } from '~/app/shared/services/api-interceptor.service';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { NfsFormClientComponent } from '../nfs-form-client/nfs-form-client.component';
+
+@Component({
+ selector: 'cd-nfs-form',
+ templateUrl: './nfs-form.component.html',
+ styleUrls: ['./nfs-form.component.scss']
+})
+export class NfsFormComponent extends CdForm implements OnInit {
+ @ViewChild('nfsClients', { static: true })
+ nfsClients: NfsFormClientComponent;
+
+ clients: any[] = [];
+
+ permission: Permission;
+ nfsForm: CdFormGroup;
+ isEdit = false;
+
+ cluster_id: string = null;
+ export_id: string = null;
+
+ allClusters: { cluster_id: string }[] = null;
+ icons = Icons;
+
+ allFsals: any[] = [];
+ allFsNames: any[] = null;
+ fsalAvailabilityError: string = null;
+
+ defaultAccessType = { RGW: 'RO' };
+ nfsAccessType: any[] = this.nfsService.nfsAccessType;
+ nfsSquash: any[] = Object.keys(this.nfsService.nfsSquash);
+
+ action: string;
+ resource: string;
+
+ pathDataSource = (text$: Observable<string>) => {
+ return text$.pipe(
+ debounceTime(200),
+ distinctUntilChanged(),
+ mergeMap((token: string) => this.getPathTypeahead(token)),
+ map((val: string[]) => val)
+ );
+ };
+
+ bucketDataSource = (text$: Observable<string>) => {
+ return text$.pipe(
+ debounceTime(200),
+ distinctUntilChanged(),
+ mergeMap((token: string) => this.getBucketTypeahead(token))
+ );
+ };
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private nfsService: NfsService,
+ private route: ActivatedRoute,
+ private router: Router,
+ private rgwBucketService: RgwBucketService,
+ private rgwSiteService: RgwSiteService,
+ private formBuilder: CdFormBuilder,
+ private taskWrapper: TaskWrapperService,
+ private cdRef: ChangeDetectorRef,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ super();
+ this.permission = this.authStorageService.getPermissions().pool;
+ this.resource = $localize`NFS export`;
+ this.createForm();
+ }
+
+ ngOnInit() {
+ const promises: Observable<any>[] = [
+ this.nfsService.listClusters(),
+ this.nfsService.fsals(),
+ this.nfsService.filesystems()
+ ];
+
+ if (this.router.url.startsWith('/nfs/edit')) {
+ this.isEdit = true;
+ }
+
+ if (this.isEdit) {
+ this.action = this.actionLabels.EDIT;
+ this.route.params.subscribe((params: { cluster_id: string; export_id: string }) => {
+ this.cluster_id = decodeURIComponent(params.cluster_id);
+ this.export_id = decodeURIComponent(params.export_id);
+ promises.push(this.nfsService.get(this.cluster_id, this.export_id));
+
+ this.getData(promises);
+ });
+ this.nfsForm.get('cluster_id').disable();
+ } else {
+ this.action = this.actionLabels.CREATE;
+ this.getData(promises);
+ }
+ }
+
+ getData(promises: Observable<any>[]) {
+ forkJoin(promises).subscribe((data: any[]) => {
+ this.resolveClusters(data[0]);
+ this.resolveFsals(data[1]);
+ this.resolveFilesystems(data[2]);
+ if (data[3]) {
+ this.resolveModel(data[3]);
+ }
+
+ this.loadingReady();
+ });
+ }
+
+ createForm() {
+ this.nfsForm = new CdFormGroup({
+ cluster_id: new FormControl('', {
+ validators: [Validators.required]
+ }),
+ fsal: new CdFormGroup({
+ name: new FormControl('', {
+ validators: [Validators.required]
+ }),
+ fs_name: new FormControl('', {
+ validators: [
+ CdValidators.requiredIf({
+ name: 'CEPH'
+ })
+ ]
+ })
+ }),
+ path: new FormControl('/'),
+ protocolNfsv4: new FormControl(true),
+ pseudo: new FormControl('', {
+ validators: [
+ CdValidators.requiredIf({ protocolNfsv4: true }),
+ Validators.pattern('^/[^><|&()]*$')
+ ]
+ }),
+ access_type: new FormControl('RW'),
+ squash: new FormControl(this.nfsSquash[0]),
+ transportUDP: new FormControl(true, {
+ validators: [
+ CdValidators.requiredIf({ transportTCP: false }, (value: boolean) => {
+ return !value;
+ })
+ ]
+ }),
+ transportTCP: new FormControl(true, {
+ validators: [
+ CdValidators.requiredIf({ transportUDP: false }, (value: boolean) => {
+ return !value;
+ })
+ ]
+ }),
+ clients: this.formBuilder.array([]),
+ security_label: new FormControl(false),
+ sec_label_xattr: new FormControl(
+ 'security.selinux',
+ CdValidators.requiredIf({ security_label: true, 'fsal.name': 'CEPH' })
+ )
+ });
+ }
+
+ resolveModel(res: any) {
+ if (res.fsal.name === 'CEPH') {
+ res.sec_label_xattr = res.fsal.sec_label_xattr;
+ }
+
+ res.protocolNfsv4 = res.protocols.indexOf(4) !== -1;
+ delete res.protocols;
+
+ res.transportTCP = res.transports.indexOf('TCP') !== -1;
+ res.transportUDP = res.transports.indexOf('UDP') !== -1;
+ delete res.transports;
+
+ Object.entries(this.nfsService.nfsSquash).forEach(([key, value]) => {
+ if (value.includes(res.squash)) {
+ res.squash = key;
+ }
+ });
+
+ res.clients.forEach((client: any) => {
+ let addressStr = '';
+ client.addresses.forEach((address: string) => {
+ addressStr += address + ', ';
+ });
+ if (addressStr.length >= 2) {
+ addressStr = addressStr.substring(0, addressStr.length - 2);
+ }
+ client.addresses = addressStr;
+ });
+
+ this.nfsForm.patchValue(res);
+ this.setPathValidation();
+ this.clients = res.clients;
+ }
+
+ resolveClusters(clusters: string[]) {
+ this.allClusters = [];
+ for (const cluster of clusters) {
+ this.allClusters.push({ cluster_id: cluster });
+ }
+ if (!this.isEdit && this.allClusters.length > 0) {
+ this.nfsForm.get('cluster_id').setValue(this.allClusters[0].cluster_id);
+ }
+ }
+
+ resolveFsals(res: string[]) {
+ res.forEach((fsal) => {
+ const fsalItem = this.nfsService.nfsFsal.find((currentFsalItem) => {
+ return fsal === currentFsalItem.value;
+ });
+
+ if (_.isObjectLike(fsalItem)) {
+ this.allFsals.push(fsalItem);
+ }
+ });
+ if (!this.isEdit && this.allFsals.length > 0) {
+ this.nfsForm.patchValue({
+ fsal: {
+ name: this.allFsals[0].value
+ }
+ });
+ }
+ }
+
+ resolveFilesystems(filesystems: any[]) {
+ this.allFsNames = filesystems;
+ if (!this.isEdit && filesystems.length > 0) {
+ this.nfsForm.patchValue({
+ fsal: {
+ fs_name: filesystems[0].name
+ }
+ });
+ }
+ }
+
+ fsalChangeHandler() {
+ this.setPathValidation();
+ const fsalValue = this.nfsForm.getValue('name');
+ const checkAvailability =
+ fsalValue === 'RGW'
+ ? this.rgwSiteService.get('realms').pipe(
+ mergeMap((realms: string[]) =>
+ realms.length === 0
+ ? of(true)
+ : this.rgwSiteService.isDefaultRealm().pipe(
+ mergeMap((isDefaultRealm) => {
+ if (!isDefaultRealm) {
+ throw new Error('Selected realm is not the default.');
+ }
+ return of(true);
+ })
+ )
+ )
+ )
+ : this.nfsService.filesystems();
+
+ checkAvailability.subscribe({
+ next: () => {
+ this.setFsalAvailability(fsalValue, true);
+ if (!this.isEdit) {
+ this.nfsForm.patchValue({
+ path: fsalValue === 'RGW' ? '' : '/',
+ pseudo: this.generatePseudo(),
+ access_type: this.updateAccessType()
+ });
+ }
+
+ this.cdRef.detectChanges();
+ },
+ error: (error) => {
+ this.setFsalAvailability(fsalValue, false, error);
+ this.nfsForm.get('name').setValue('');
+ }
+ });
+ }
+
+ private setFsalAvailability(fsalValue: string, available: boolean, errorMessage: string = '') {
+ this.allFsals = this.allFsals.map((fsalItem: NfsFSAbstractionLayer) => {
+ if (fsalItem.value === fsalValue) {
+ fsalItem.disabled = !available;
+
+ this.fsalAvailabilityError = fsalItem.disabled
+ ? $localize`${fsalItem.descr} backend is not available. ${errorMessage}`
+ : null;
+ }
+ return fsalItem;
+ });
+ }
+
+ accessTypeChangeHandler() {
+ const name = this.nfsForm.getValue('name');
+ const accessType = this.nfsForm.getValue('access_type');
+ this.defaultAccessType[name] = accessType;
+ }
+
+ setPathValidation() {
+ const path = this.nfsForm.get('path');
+ path.setValidators([Validators.required]);
+ if (this.nfsForm.getValue('name') === 'RGW') {
+ path.setAsyncValidators([CdValidators.bucketExistence(true, this.rgwBucketService)]);
+ } else {
+ path.setAsyncValidators([this.pathExistence(true)]);
+ }
+
+ if (this.isEdit) {
+ path.markAsDirty();
+ }
+ }
+
+ getAccessTypeHelp(accessType: string) {
+ const accessTypeItem = this.nfsAccessType.find((currentAccessTypeItem) => {
+ if (accessType === currentAccessTypeItem.value) {
+ return currentAccessTypeItem;
+ }
+ });
+ return _.isObjectLike(accessTypeItem) ? accessTypeItem.help : '';
+ }
+
+ getId() {
+ if (
+ _.isString(this.nfsForm.getValue('cluster_id')) &&
+ _.isString(this.nfsForm.getValue('path'))
+ ) {
+ return this.nfsForm.getValue('cluster_id') + ':' + this.nfsForm.getValue('path');
+ }
+ return '';
+ }
+
+ private getPathTypeahead(path: any) {
+ if (!_.isString(path) || path === '/') {
+ return of([]);
+ }
+
+ const fsName = this.nfsForm.getValue('fsal').fs_name;
+ return this.nfsService.lsDir(fsName, path).pipe(
+ map((result: Directory) =>
+ result.paths.filter((dirName: string) => dirName.toLowerCase().includes(path)).slice(0, 15)
+ ),
+ catchError(() => of([$localize`Error while retrieving paths.`]))
+ );
+ }
+
+ pathChangeHandler() {
+ if (!this.isEdit) {
+ this.nfsForm.patchValue({
+ pseudo: this.generatePseudo()
+ });
+ }
+ }
+
+ private getBucketTypeahead(path: string): Observable<any> {
+ if (_.isString(path) && path !== '/' && path !== '') {
+ return this.rgwBucketService.list().pipe(
+ map((bucketList) =>
+ bucketList
+ .filter((bucketName: string) => bucketName.toLowerCase().includes(path))
+ .slice(0, 15)
+ ),
+ catchError(() => of([$localize`Error while retrieving bucket names.`]))
+ );
+ } else {
+ return of([]);
+ }
+ }
+
+ private generatePseudo() {
+ let newPseudo = this.nfsForm.getValue('pseudo');
+ if (this.nfsForm.get('pseudo') && !this.nfsForm.get('pseudo').dirty) {
+ newPseudo = undefined;
+ if (this.nfsForm.getValue('fsal') === 'CEPH') {
+ newPseudo = '/cephfs';
+ if (_.isString(this.nfsForm.getValue('path'))) {
+ newPseudo += this.nfsForm.getValue('path');
+ }
+ }
+ }
+ return newPseudo;
+ }
+
+ private updateAccessType() {
+ const name = this.nfsForm.getValue('name');
+ let accessType = this.defaultAccessType[name];
+
+ if (!accessType) {
+ accessType = 'RW';
+ }
+
+ return accessType;
+ }
+
+ submitAction() {
+ let action: Observable<any>;
+ const requestModel = this.buildRequest();
+
+ if (this.isEdit) {
+ action = this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('nfs/edit', {
+ cluster_id: this.cluster_id,
+ export_id: _.parseInt(this.export_id)
+ }),
+ call: this.nfsService.update(this.cluster_id, _.parseInt(this.export_id), requestModel)
+ });
+ } else {
+ // Create
+ action = this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('nfs/create', {
+ path: requestModel.path,
+ fsal: requestModel.fsal,
+ cluster_id: requestModel.cluster_id
+ }),
+ call: this.nfsService.create(requestModel)
+ });
+ }
+
+ action.subscribe({
+ error: (errorResponse: CdHttpErrorResponse) => this.setFormErrors(errorResponse),
+ complete: () => this.router.navigate(['/nfs'])
+ });
+ }
+
+ private setFormErrors(errorResponse: CdHttpErrorResponse) {
+ if (
+ errorResponse.error.detail &&
+ errorResponse.error.detail
+ .toString()
+ .includes(`Pseudo ${this.nfsForm.getValue('pseudo')} is already in use`)
+ ) {
+ this.nfsForm.get('pseudo').setErrors({ pseudoAlreadyExists: true });
+ }
+ this.nfsForm.setErrors({ cdSubmitButton: true });
+ }
+
+ private buildRequest() {
+ const requestModel: any = _.cloneDeep(this.nfsForm.value);
+
+ if (this.isEdit) {
+ requestModel.export_id = _.parseInt(this.export_id);
+ }
+
+ if (requestModel.fsal.name === 'RGW') {
+ delete requestModel.fsal.fs_name;
+ }
+
+ requestModel.protocols = [];
+ if (requestModel.protocolNfsv4) {
+ requestModel.protocols.push(4);
+ } else {
+ requestModel.pseudo = null;
+ }
+ delete requestModel.protocolNfsv4;
+
+ requestModel.transports = [];
+ if (requestModel.transportTCP) {
+ requestModel.transports.push('TCP');
+ }
+ delete requestModel.transportTCP;
+ if (requestModel.transportUDP) {
+ requestModel.transports.push('UDP');
+ }
+ delete requestModel.transportUDP;
+
+ requestModel.clients.forEach((client: any) => {
+ if (_.isString(client.addresses)) {
+ client.addresses = _(client.addresses)
+ .split(/[ ,]+/)
+ .uniq()
+ .filter((address) => address !== '')
+ .value();
+ } else {
+ client.addresses = [];
+ }
+
+ if (!client.squash) {
+ client.squash = requestModel.squash;
+ }
+
+ if (!client.access_type) {
+ client.access_type = requestModel.access_type;
+ }
+ });
+
+ if (requestModel.security_label === false || requestModel.fsal.name === 'RGW') {
+ requestModel.fsal.sec_label_xattr = null;
+ } else {
+ requestModel.fsal.sec_label_xattr = requestModel.sec_label_xattr;
+ }
+ delete requestModel.sec_label_xattr;
+
+ return requestModel;
+ }
+
+ private pathExistence(requiredExistenceResult: boolean): AsyncValidatorFn {
+ return (control: AbstractControl): Observable<ValidationErrors | null> => {
+ if (control.pristine || !control.value) {
+ return of({ required: true });
+ }
+ const fsName = this.nfsForm.getValue('fsal').fs_name;
+ return this.nfsService.lsDir(fsName, control.value).pipe(
+ map((directory: Directory) =>
+ directory.paths.includes(control.value) === requiredExistenceResult
+ ? null
+ : { pathNameNotAllowed: true }
+ ),
+ catchError(() => of({ pathNameNotAllowed: true }))
+ );
+ };
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.html
new file mode 100644
index 000000000..79304265e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.html
@@ -0,0 +1,30 @@
+<cd-table #table
+ [data]="exports"
+ columnMode="flex"
+ [columns]="columns"
+ identifier="id"
+ forceIdentifier="true"
+ selectionType="single"
+ [hasDetails]="true"
+ (setExpandedRow)="setExpandedRow($event)"
+ (updateSelection)="updateSelection($event)">
+ <div class="table-actions btn-toolbar">
+ <cd-table-actions class="btn-group"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ </div>
+
+ <cd-nfs-details cdTableDetail
+ [selection]="expandedRow">
+ </cd-nfs-details>
+</cd-table>
+
+<ng-template #nfsFsal
+ let-value="value">
+ <ng-container *ngIf="value.name==='CEPH'"
+ i18n>CephFS</ng-container>
+ <ng-container *ngIf="value.name==='RGW'"
+ i18n>Object Gateway</ng-container>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.spec.ts
new file mode 100644
index 000000000..5e43cdd65
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.spec.ts
@@ -0,0 +1,195 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { NfsService } from '~/app/shared/api/nfs.service';
+import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
+import { ExecutingTask } from '~/app/shared/models/executing-task';
+import { Summary } from '~/app/shared/models/summary.model';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { TaskListService } from '~/app/shared/services/task-list.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, expectItemTasks, PermissionHelper } from '~/testing/unit-test-helper';
+import { NfsDetailsComponent } from '../nfs-details/nfs-details.component';
+import { NfsListComponent } from './nfs-list.component';
+
+describe('NfsListComponent', () => {
+ let component: NfsListComponent;
+ let fixture: ComponentFixture<NfsListComponent>;
+ let summaryService: SummaryService;
+ let nfsService: NfsService;
+ let httpTesting: HttpTestingController;
+
+ const refresh = (data: Summary) => {
+ summaryService['summaryDataSource'].next(data);
+ };
+
+ configureTestBed({
+ declarations: [NfsListComponent, NfsDetailsComponent],
+ imports: [
+ BrowserAnimationsModule,
+ HttpClientTestingModule,
+ RouterTestingModule,
+ SharedModule,
+ NgbNavModule,
+ ToastrModule.forRoot()
+ ],
+ providers: [TaskListService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(NfsListComponent);
+ component = fixture.componentInstance;
+ summaryService = TestBed.inject(SummaryService);
+ nfsService = TestBed.inject(NfsService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('after ngOnInit', () => {
+ beforeEach(() => {
+ fixture.detectChanges();
+ spyOn(nfsService, 'list').and.callThrough();
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should load exports on init', () => {
+ refresh(new Summary());
+ httpTesting.expectOne('api/nfs-ganesha/export');
+ expect(nfsService.list).toHaveBeenCalled();
+ });
+
+ it('should not load images on init because no data', () => {
+ refresh(undefined);
+ expect(nfsService.list).not.toHaveBeenCalled();
+ });
+
+ it('should call error function on init when summary service fails', () => {
+ spyOn(component.table, 'reset');
+ summaryService['summaryDataSource'].error(undefined);
+ expect(component.table.reset).toHaveBeenCalled();
+ });
+ });
+
+ describe('handling of executing tasks', () => {
+ let exports: any[];
+
+ const addExport = (export_id: string) => {
+ const model = {
+ export_id: export_id,
+ path: 'path_' + export_id,
+ fsal: 'fsal_' + export_id,
+ cluster_id: 'cluster_' + export_id
+ };
+ exports.push(model);
+ };
+
+ const addTask = (name: string, export_id: string) => {
+ const task = new ExecutingTask();
+ task.name = name;
+ switch (task.name) {
+ case 'nfs/create':
+ task.metadata = {
+ path: 'path_' + export_id,
+ fsal: 'fsal_' + export_id,
+ cluster_id: 'cluster_' + export_id
+ };
+ break;
+ default:
+ task.metadata = {
+ cluster_id: 'cluster_' + export_id,
+ export_id: export_id
+ };
+ break;
+ }
+ summaryService.addRunningTask(task);
+ };
+
+ beforeEach(() => {
+ exports = [];
+ addExport('a');
+ addExport('b');
+ addExport('c');
+ component.exports = exports;
+ refresh(new Summary());
+ spyOn(nfsService, 'list').and.callFake(() => of(exports));
+ fixture.detectChanges();
+ });
+
+ it('should gets all exports without tasks', () => {
+ expect(component.exports.length).toBe(3);
+ expect(component.exports.every((expo) => !expo.cdExecuting)).toBeTruthy();
+ });
+
+ it('should add a new export from a task', fakeAsync(() => {
+ addTask('nfs/create', 'd');
+ tick();
+ expect(component.exports.length).toBe(4);
+ expectItemTasks(component.exports[0], undefined);
+ expectItemTasks(component.exports[1], undefined);
+ expectItemTasks(component.exports[2], undefined);
+ expectItemTasks(component.exports[3], 'Creating');
+ }));
+
+ it('should show when an existing export is being modified', () => {
+ addTask('nfs/edit', 'a');
+ addTask('nfs/delete', 'b');
+ expect(component.exports.length).toBe(3);
+ expectItemTasks(component.exports[0], 'Updating');
+ expectItemTasks(component.exports[1], 'Deleting');
+ });
+ });
+
+ it('should test all TableActions combinations', () => {
+ const permissionHelper: PermissionHelper = new PermissionHelper(component.permission);
+ const tableActions: TableActionsComponent = permissionHelper.setPermissionsAndGetActions(
+ component.tableActions
+ );
+
+ expect(tableActions).toEqual({
+ 'create,update,delete': {
+ actions: ['Create', 'Edit', 'Delete'],
+ primary: { multiple: 'Create', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,update': {
+ actions: ['Create', 'Edit'],
+ primary: { multiple: 'Create', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,delete': {
+ actions: ['Create', 'Delete'],
+ primary: { multiple: 'Create', executing: 'Delete', single: 'Delete', no: 'Create' }
+ },
+ create: {
+ actions: ['Create'],
+ primary: { multiple: 'Create', executing: 'Create', single: 'Create', no: 'Create' }
+ },
+ 'update,delete': {
+ actions: ['Edit', 'Delete'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ update: {
+ actions: ['Edit'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ delete: {
+ actions: ['Delete'],
+ primary: { multiple: 'Delete', executing: 'Delete', single: 'Delete', no: 'Delete' }
+ },
+ 'no-permissions': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ }
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.ts
new file mode 100644
index 000000000..d5d0c2639
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.ts
@@ -0,0 +1,199 @@
+import { Component, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { Subscription } from 'rxjs';
+
+import { NfsService } from '~/app/shared/api/nfs.service';
+import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { TableComponent } from '~/app/shared/datatable/table/table.component';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { ViewCacheStatus } from '~/app/shared/enum/view-cache-status.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { Permission } from '~/app/shared/models/permissions';
+import { Task } from '~/app/shared/models/task';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { TaskListService } from '~/app/shared/services/task-list.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+
+@Component({
+ selector: 'cd-nfs-list',
+ templateUrl: './nfs-list.component.html',
+ styleUrls: ['./nfs-list.component.scss'],
+ providers: [TaskListService]
+})
+export class NfsListComponent extends ListWithDetails implements OnInit, OnDestroy {
+ @ViewChild('nfsState')
+ nfsState: TemplateRef<any>;
+ @ViewChild('nfsFsal', { static: true })
+ nfsFsal: TemplateRef<any>;
+
+ @ViewChild('table', { static: true })
+ table: TableComponent;
+
+ columns: CdTableColumn[];
+ permission: Permission;
+ selection = new CdTableSelection();
+ summaryDataSubscription: Subscription;
+ viewCacheStatus: any;
+ exports: any[];
+ tableActions: CdTableAction[];
+ isDefaultCluster = false;
+
+ modalRef: NgbModalRef;
+
+ builders = {
+ 'nfs/create': (metadata: any) => {
+ return {
+ path: metadata['path'],
+ cluster_id: metadata['cluster_id'],
+ fsal: metadata['fsal']
+ };
+ }
+ };
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private modalService: ModalService,
+ private nfsService: NfsService,
+ private taskListService: TaskListService,
+ private taskWrapper: TaskWrapperService,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ super();
+ this.permission = this.authStorageService.getPermissions().nfs;
+ const getNfsUri = () =>
+ this.selection.first() &&
+ `${encodeURI(this.selection.first().cluster_id)}/${encodeURI(
+ this.selection.first().export_id
+ )}`;
+
+ const createAction: CdTableAction = {
+ permission: 'create',
+ icon: Icons.add,
+ routerLink: () => '/nfs/create',
+ canBePrimary: (selection: CdTableSelection) => !selection.hasSingleSelection,
+ name: this.actionLabels.CREATE
+ };
+
+ const editAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.edit,
+ routerLink: () => `/nfs/edit/${getNfsUri()}`,
+ name: this.actionLabels.EDIT
+ };
+
+ const deleteAction: CdTableAction = {
+ permission: 'delete',
+ icon: Icons.destroy,
+ click: () => this.deleteNfsModal(),
+ name: this.actionLabels.DELETE
+ };
+
+ this.tableActions = [createAction, editAction, deleteAction];
+ }
+
+ ngOnInit() {
+ this.columns = [
+ {
+ name: $localize`Path`,
+ prop: 'path',
+ flexGrow: 2,
+ cellTransformation: CellTemplate.executing
+ },
+ {
+ name: $localize`Pseudo`,
+ prop: 'pseudo',
+ flexGrow: 2
+ },
+ {
+ name: $localize`Cluster`,
+ prop: 'cluster_id',
+ flexGrow: 2
+ },
+ {
+ name: $localize`Storage Backend`,
+ prop: 'fsal',
+ flexGrow: 2,
+ cellTemplate: this.nfsFsal
+ },
+ {
+ name: $localize`Access Type`,
+ prop: 'access_type',
+ flexGrow: 2
+ }
+ ];
+
+ this.taskListService.init(
+ () => this.nfsService.list(),
+ (resp) => this.prepareResponse(resp),
+ (exports) => (this.exports = exports),
+ () => this.onFetchError(),
+ this.taskFilter,
+ this.itemFilter,
+ this.builders
+ );
+ }
+
+ ngOnDestroy() {
+ if (this.summaryDataSubscription) {
+ this.summaryDataSubscription.unsubscribe();
+ }
+ }
+
+ prepareResponse(resp: any): any[] {
+ let result: any[] = [];
+ resp.forEach((nfs: any) => {
+ nfs.id = `${nfs.cluster_id}:${nfs.export_id}`;
+ nfs.state = 'LOADING';
+ result = result.concat(nfs);
+ });
+
+ return result;
+ }
+
+ onFetchError() {
+ this.table.reset(); // Disable loading indicator.
+ this.viewCacheStatus = { status: ViewCacheStatus.ValueException };
+ }
+
+ itemFilter(entry: any, task: Task) {
+ return (
+ entry.cluster_id === task.metadata['cluster_id'] &&
+ entry.export_id === task.metadata['export_id']
+ );
+ }
+
+ taskFilter(task: Task) {
+ return ['nfs/create', 'nfs/delete', 'nfs/edit'].includes(task.name);
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ deleteNfsModal() {
+ const cluster_id = this.selection.first().cluster_id;
+ const export_id = this.selection.first().export_id;
+
+ this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: $localize`NFS export`,
+ itemNames: [`${cluster_id}:${export_id}`],
+ submitActionObservable: () =>
+ this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask('nfs/delete', {
+ cluster_id: cluster_id,
+ export_id: export_id
+ }),
+ call: this.nfsService.delete(cluster_id, export_id)
+ })
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs.module.ts
new file mode 100644
index 000000000..4205eb63b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs.module.ts
@@ -0,0 +1,26 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterModule } from '@angular/router';
+
+import { NgbNavModule, NgbTooltipModule, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { NfsDetailsComponent } from './nfs-details/nfs-details.component';
+import { NfsFormClientComponent } from './nfs-form-client/nfs-form-client.component';
+import { NfsFormComponent } from './nfs-form/nfs-form.component';
+import { NfsListComponent } from './nfs-list/nfs-list.component';
+
+@NgModule({
+ imports: [
+ ReactiveFormsModule,
+ RouterModule,
+ SharedModule,
+ NgbNavModule,
+ CommonModule,
+ NgbTypeaheadModule,
+ NgbTooltipModule
+ ],
+ declarations: [NfsListComponent, NfsDetailsComponent, NfsFormComponent, NfsFormClientComponent]
+})
+export class NfsModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter.module.ts
new file mode 100644
index 000000000..9beb53011
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter.module.ts
@@ -0,0 +1,14 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { RouterModule } from '@angular/router';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { PerformanceCounterComponent } from './performance-counter/performance-counter.component';
+import { TablePerformanceCounterComponent } from './table-performance-counter/table-performance-counter.component';
+
+@NgModule({
+ imports: [CommonModule, SharedModule, RouterModule],
+ declarations: [TablePerformanceCounterComponent, PerformanceCounterComponent],
+ exports: [TablePerformanceCounterComponent]
+})
+export class PerformanceCounterModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.html
new file mode 100644
index 000000000..988a8a252
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.html
@@ -0,0 +1,4 @@
+<legend>{{ serviceType }}.{{ serviceId }}</legend>
+<cd-table-performance-counter [serviceType]="serviceType"
+ [serviceId]="serviceId">
+</cd-table-performance-counter>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.spec.ts
new file mode 100644
index 000000000..5d2da8164
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.spec.ts
@@ -0,0 +1,29 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { TablePerformanceCounterComponent } from '../table-performance-counter/table-performance-counter.component';
+import { PerformanceCounterComponent } from './performance-counter.component';
+
+describe('PerformanceCounterComponent', () => {
+ let component: PerformanceCounterComponent;
+ let fixture: ComponentFixture<PerformanceCounterComponent>;
+
+ configureTestBed({
+ declarations: [PerformanceCounterComponent, TablePerformanceCounterComponent],
+ imports: [RouterTestingModule, SharedModule, HttpClientTestingModule, BrowserAnimationsModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(PerformanceCounterComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.ts
new file mode 100644
index 000000000..9321e0e9a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.ts
@@ -0,0 +1,25 @@
+import { Component } from '@angular/core';
+import { ActivatedRoute } from '@angular/router';
+
+@Component({
+ selector: 'cd-performance-counter',
+ templateUrl: './performance-counter.component.html',
+ styleUrls: ['./performance-counter.component.scss']
+})
+export class PerformanceCounterComponent {
+ static defaultFromLink = '/hosts';
+
+ serviceId: string;
+ serviceType: string;
+ fromLink: string;
+
+ constructor(private route: ActivatedRoute) {
+ this.route.queryParams.subscribe((params: { fromLink: string }) => {
+ this.fromLink = params.fromLink || PerformanceCounterComponent.defaultFromLink;
+ });
+ this.route.params.subscribe((params: { type: string; id: string }) => {
+ this.serviceId = decodeURIComponent(params.id);
+ this.serviceType = params.type;
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html
new file mode 100644
index 000000000..17c757356
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html
@@ -0,0 +1,15 @@
+<cd-table *ngIf="counters; else warning"
+ [data]="counters"
+ [columns]="columns"
+ columnMode="flex"
+ [autoSave]="false"
+ (fetchData)="getCounters($event)">
+ <ng-template #valueTpl
+ let-row="row">
+ {{ row.value | dimless }} {{ row.unit }}
+ </ng-template>
+</cd-table>
+<ng-template #warning>
+ <cd-alert-panel type="warning"
+ i18n>Performance counters not available</cd-alert-panel>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.spec.ts
new file mode 100644
index 000000000..fd8264405
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.spec.ts
@@ -0,0 +1,62 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AppModule } from '~/app/app.module';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { TablePerformanceCounterComponent } from './table-performance-counter.component';
+
+describe('TablePerformanceCounterComponent', () => {
+ let component: TablePerformanceCounterComponent;
+ let fixture: ComponentFixture<TablePerformanceCounterComponent>;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ imports: [AppModule, HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TablePerformanceCounterComponent);
+ component = fixture.componentInstance;
+ httpTesting = TestBed.inject(HttpTestingController);
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ expect(component.counters).toEqual([]);
+ });
+
+ it('should have columns that are sortable', () => {
+ expect(component.columns.every((column) => Boolean(column.prop))).toBeTruthy();
+ });
+
+ describe('Error handling', () => {
+ const context = new CdTableFetchDataContext(() => undefined);
+
+ beforeEach(() => {
+ spyOn(context, 'error');
+ component.serviceType = 'osd';
+ component.serviceId = '3';
+ component.getCounters(context);
+ });
+
+ it('should display 404 warning', () => {
+ httpTesting
+ .expectOne('api/perf_counters/osd/3')
+ .error(new ErrorEvent('osd.3 not found'), { status: 404 });
+ httpTesting.verify();
+ expect(component.counters).toBeNull();
+ expect(context.error).not.toHaveBeenCalled();
+ });
+
+ it('should call error function of context', () => {
+ httpTesting
+ .expectOne('api/perf_counters/osd/3')
+ .error(new ErrorEvent('Unknown error'), { status: 500 });
+ httpTesting.verify();
+ expect(component.counters).toEqual([]);
+ expect(context.error).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts
new file mode 100644
index 000000000..e2e0194de
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts
@@ -0,0 +1,72 @@
+import { Component, Input, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import { PerformanceCounterService } from '~/app/shared/api/performance-counter.service';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+
+/**
+ * Display the specified performance counters in a datatable.
+ */
+@Component({
+ selector: 'cd-table-performance-counter',
+ templateUrl: './table-performance-counter.component.html',
+ styleUrls: ['./table-performance-counter.component.scss']
+})
+export class TablePerformanceCounterComponent implements OnInit {
+ columns: Array<CdTableColumn> = [];
+ counters: Array<object> = [];
+
+ @ViewChild('valueTpl')
+ public valueTpl: TemplateRef<any>;
+
+ /**
+ * The service type, e.g. 'rgw', 'mds', 'mon', 'osd', ...
+ */
+ @Input()
+ serviceType: string;
+
+ /**
+ * The service identifier.
+ */
+ @Input()
+ serviceId: string;
+
+ constructor(private performanceCounterService: PerformanceCounterService) {}
+
+ ngOnInit() {
+ this.columns = [
+ {
+ name: $localize`Name`,
+ prop: 'name',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Description`,
+ prop: 'description',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Value`,
+ prop: 'value',
+ cellTemplate: this.valueTpl,
+ flexGrow: 1
+ }
+ ];
+ }
+
+ getCounters(context: CdTableFetchDataContext) {
+ this.performanceCounterService.get(this.serviceType, this.serviceId).subscribe(
+ (resp: object[]) => {
+ this.counters = resp;
+ },
+ (error) => {
+ if (error.status === 404) {
+ error.preventDefault();
+ this.counters = null;
+ } else {
+ context.error();
+ }
+ }
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html
new file mode 100644
index 000000000..e5906dc4b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html
@@ -0,0 +1,123 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container i18n="form title"
+ class="modal-title">{{ action | titlecase }} {{ resource | upperFirst }}</ng-container>
+
+ <ng-container class="modal-content">
+ <form #frm="ngForm"
+ [formGroup]="form"
+ novalidate>
+ <div class="modal-body">
+ <div class="form-group row">
+ <label for="name"
+ class="cd-col-form-label">
+ <ng-container i18n>Name</ng-container>
+ <span class="required"></span>
+ </label>
+ <div class="cd-col-form-input">
+ <input type="text"
+ id="name"
+ name="name"
+ class="form-control"
+ placeholder="Name..."
+ formControlName="name"
+ autofocus>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('name', frm, 'required')"
+ i18n>This field is required!</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('name', frm, 'pattern')"
+ i18n>The name can only consist of alphanumeric characters, dashes and underscores.</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('name', frm, 'uniqueName')"
+ i18n>The chosen erasure code profile name is already in use.</span>
+ </div>
+ </div>
+
+ <!-- Root -->
+ <div class="form-group row">
+ <label for="root"
+ class="cd-col-form-label">
+ <ng-container i18n>Root</ng-container>
+ <cd-helper [html]="tooltips.root">
+ </cd-helper>
+ <span class="required"></span>
+ </label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ id="root"
+ name="root"
+ formControlName="root">
+ <option *ngIf="!buckets"
+ ngValue=""
+ i18n>Loading...</option>
+ <option *ngFor="let bucket of buckets"
+ [ngValue]="bucket">
+ {{ bucket.name }}
+ </option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('root', frm, 'required')"
+ i18n>This field is required!</span>
+ </div>
+ </div>
+
+ <!-- Failure Domain Type -->
+ <div class="form-group row">
+ <label for="failure_domain"
+ class="cd-col-form-label">
+ <ng-container i18n>Failure domain type</ng-container>
+ <cd-helper [html]="tooltips.failure_domain">
+ </cd-helper>
+ <span class="required"></span>
+ </label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ id="failure_domain"
+ name="failure_domain"
+ formControlName="failure_domain">
+ <option *ngIf="!failureDomains"
+ ngValue=""
+ i18n>Loading...</option>
+ <option *ngFor="let domain of failureDomainKeys"
+ [ngValue]="domain">
+ {{ domain }} ( {{failureDomains[domain].length}} )
+ </option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('failure_domain', frm, 'required')"
+ i18n>This field is required!</span>
+ </div>
+ </div>
+
+ <!-- Class -->
+ <div class="form-group row">
+ <label for="device_class"
+ class="cd-col-form-label">
+ <ng-container i18n>Device class</ng-container>
+ <cd-helper [html]="tooltips.device_class">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ id="device_class"
+ name="device_class"
+ formControlName="device_class">
+ <option ngValue=""
+ i18n>Let Ceph decide</option>
+ <option *ngFor="let deviceClass of devices"
+ [ngValue]="deviceClass">
+ {{ deviceClass }}
+ </option>
+ </select>
+ </div>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="onSubmit()"
+ [form]="form"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.spec.ts
new file mode 100644
index 000000000..2b8c9e5cf
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.spec.ts
@@ -0,0 +1,210 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { CrushRuleService } from '~/app/shared/api/crush-rule.service';
+import { CrushNode } from '~/app/shared/models/crush-node';
+import { CrushRuleConfig } from '~/app/shared/models/crush-rule';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { configureTestBed, FixtureHelper, FormHelper, Mocks } from '~/testing/unit-test-helper';
+import { PoolModule } from '../pool.module';
+import { CrushRuleFormModalComponent } from './crush-rule-form-modal.component';
+
+describe('CrushRuleFormComponent', () => {
+ let component: CrushRuleFormModalComponent;
+ let crushRuleService: CrushRuleService;
+ let fixture: ComponentFixture<CrushRuleFormModalComponent>;
+ let formHelper: FormHelper;
+ let fixtureHelper: FixtureHelper;
+ let data: { names: string[]; nodes: CrushNode[] };
+
+ // Object contains functions to get something
+ const get = {
+ nodeByName: (name: string): CrushNode => data.nodes.find((node) => node.name === name),
+ nodesByNames: (names: string[]): CrushNode[] => names.map(get.nodeByName)
+ };
+
+ // Expects that are used frequently
+ const assert = {
+ failureDomains: (nodes: CrushNode[], types: string[]) => {
+ const expectation = {};
+ types.forEach((type) => (expectation[type] = nodes.filter((node) => node.type === type)));
+ const keys = component.failureDomainKeys;
+ expect(keys).toEqual(types);
+ keys.forEach((key) => {
+ expect(component.failureDomains[key].length).toBe(expectation[key].length);
+ });
+ },
+ formFieldValues: (root: CrushNode, failureDomain: string, device: string) => {
+ expect(component.form.value).toEqual({
+ name: '',
+ root,
+ failure_domain: failureDomain,
+ device_class: device
+ });
+ },
+ valuesOnRootChange: (
+ rootName: string,
+ expectedFailureDomain: string,
+ expectedDevice: string
+ ) => {
+ const node = get.nodeByName(rootName);
+ formHelper.setValue('root', node);
+ assert.formFieldValues(node, expectedFailureDomain, expectedDevice);
+ },
+ creation: (rule: CrushRuleConfig) => {
+ formHelper.setValue('name', rule.name);
+ fixture.detectChanges();
+ component.onSubmit();
+ expect(crushRuleService.create).toHaveBeenCalledWith(rule);
+ }
+ };
+
+ configureTestBed({
+ imports: [HttpClientTestingModule, RouterTestingModule, ToastrModule.forRoot(), PoolModule],
+ providers: [CrushRuleService, NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CrushRuleFormModalComponent);
+ fixtureHelper = new FixtureHelper(fixture);
+ component = fixture.componentInstance;
+ formHelper = new FormHelper(component.form);
+ crushRuleService = TestBed.inject(CrushRuleService);
+ data = {
+ names: ['rule1', 'rule2'],
+ /**
+ * Create the following test crush map:
+ * > default
+ * --> ssd-host
+ * ----> 3x osd with ssd
+ * --> mix-host
+ * ----> hdd-rack
+ * ------> 2x osd-rack with hdd
+ * ----> ssd-rack
+ * ------> 2x osd-rack with ssd
+ */
+ nodes: Mocks.getCrushMap()
+ };
+ spyOn(crushRuleService, 'getInfo').and.callFake(() => of(data));
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('calls listing to get rules on ngInit', () => {
+ expect(crushRuleService.getInfo).toHaveBeenCalled();
+ expect(component.names.length).toBe(2);
+ expect(component.buckets.length).toBe(5);
+ });
+
+ describe('lists', () => {
+ afterEach(() => {
+ // The available buckets should not change
+ expect(component.buckets).toEqual(
+ get.nodesByNames(['default', 'hdd-rack', 'mix-host', 'ssd-host', 'ssd-rack'])
+ );
+ });
+
+ it('has the following lists after init', () => {
+ assert.failureDomains(data.nodes, ['host', 'osd', 'osd-rack', 'rack']); // Not root as root only exist once
+ expect(component.devices).toEqual(['hdd', 'ssd']);
+ });
+
+ it('has the following lists after selection of ssd-host', () => {
+ formHelper.setValue('root', get.nodeByName('ssd-host'));
+ assert.failureDomains(get.nodesByNames(['osd.0', 'osd.1', 'osd.2']), ['osd']); // Not host as it only exist once
+ expect(component.devices).toEqual(['ssd']);
+ });
+
+ it('has the following lists after selection of mix-host', () => {
+ formHelper.setValue('root', get.nodeByName('mix-host'));
+ expect(component.devices).toEqual(['hdd', 'ssd']);
+ assert.failureDomains(
+ get.nodesByNames(['hdd-rack', 'ssd-rack', 'osd2.0', 'osd2.1', 'osd2.0', 'osd2.1']),
+ ['osd-rack', 'rack']
+ );
+ });
+ });
+
+ describe('selection', () => {
+ it('selects the first root after init automatically', () => {
+ assert.formFieldValues(get.nodeByName('default'), 'osd-rack', '');
+ });
+
+ it('should select all values automatically by selecting "ssd-host" as root', () => {
+ assert.valuesOnRootChange('ssd-host', 'osd', 'ssd');
+ });
+
+ it('selects automatically the most common failure domain', () => {
+ // Select mix-host as mix-host has multiple failure domains (osd-rack and rack)
+ assert.valuesOnRootChange('mix-host', 'osd-rack', '');
+ });
+
+ it('should override automatic selections', () => {
+ assert.formFieldValues(get.nodeByName('default'), 'osd-rack', '');
+ assert.valuesOnRootChange('ssd-host', 'osd', 'ssd');
+ assert.valuesOnRootChange('mix-host', 'osd-rack', '');
+ });
+
+ it('should not override manual selections if possible', () => {
+ formHelper.setValue('failure_domain', 'rack', true);
+ formHelper.setValue('device_class', 'ssd', true);
+ assert.valuesOnRootChange('mix-host', 'rack', 'ssd');
+ });
+
+ it('should preselect device by domain selection', () => {
+ formHelper.setValue('failure_domain', 'osd', true);
+ assert.formFieldValues(get.nodeByName('default'), 'osd', 'ssd');
+ });
+ });
+
+ describe('form validation', () => {
+ it(`isn't valid if name is not set`, () => {
+ expect(component.form.invalid).toBeTruthy();
+ formHelper.setValue('name', 'someProfileName');
+ expect(component.form.valid).toBeTruthy();
+ });
+
+ it('sets name invalid', () => {
+ component.names = ['awesomeProfileName'];
+ formHelper.expectErrorChange('name', 'awesomeProfileName', 'uniqueName');
+ formHelper.expectErrorChange('name', 'some invalid text', 'pattern');
+ formHelper.expectErrorChange('name', null, 'required');
+ });
+
+ it(`should show all default form controls`, () => {
+ // name
+ // root (preselected(first root))
+ // failure_domain (preselected=type that is most common)
+ // device_class (preselected=any if multiple or some type if only one device type)
+ fixtureHelper.expectIdElementsVisible(
+ ['name', 'root', 'failure_domain', 'device_class'],
+ true
+ );
+ });
+ });
+
+ describe('submission', () => {
+ beforeEach(() => {
+ const taskWrapper = TestBed.inject(TaskWrapperService);
+ spyOn(taskWrapper, 'wrapTaskAroundCall').and.callThrough();
+ spyOn(crushRuleService, 'create').and.stub();
+ });
+
+ it('creates a rule with only required fields', () => {
+ assert.creation(Mocks.getCrushRuleConfig('default-rule', 'default', 'osd-rack'));
+ });
+
+ it('creates a rule with all fields', () => {
+ assert.valuesOnRootChange('ssd-host', 'osd', 'ssd');
+ assert.creation(Mocks.getCrushRuleConfig('ssd-host-rule', 'ssd-host', 'osd', 'ssd'));
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts
new file mode 100644
index 000000000..308b09d72
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts
@@ -0,0 +1,108 @@
+import { Component, EventEmitter, OnInit, Output } from '@angular/core';
+import { Validators } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+
+import { CrushRuleService } from '~/app/shared/api/crush-rule.service';
+import { CrushNodeSelectionClass } from '~/app/shared/classes/crush.node.selection.class';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { CrushNode } from '~/app/shared/models/crush-node';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+
+@Component({
+ selector: 'cd-crush-rule-form-modal',
+ templateUrl: './crush-rule-form-modal.component.html',
+ styleUrls: ['./crush-rule-form-modal.component.scss']
+})
+export class CrushRuleFormModalComponent extends CrushNodeSelectionClass implements OnInit {
+ @Output()
+ submitAction = new EventEmitter();
+
+ tooltips = this.crushRuleService.formTooltips;
+
+ form: CdFormGroup;
+ names: string[];
+ action: string;
+ resource: string;
+
+ constructor(
+ private formBuilder: CdFormBuilder,
+ public activeModal: NgbActiveModal,
+ private taskWrapper: TaskWrapperService,
+ private crushRuleService: CrushRuleService,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ super();
+ this.action = this.actionLabels.CREATE;
+ this.resource = $localize`Crush Rule`;
+ this.createForm();
+ }
+
+ createForm() {
+ this.form = this.formBuilder.group({
+ // name: string
+ name: [
+ '',
+ [
+ Validators.required,
+ Validators.pattern('[A-Za-z0-9_-]+'),
+ CdValidators.custom(
+ 'uniqueName',
+ (value: any) => this.names && this.names.indexOf(value) !== -1
+ )
+ ]
+ ],
+ // root: CrushNode
+ root: null, // Replaced with first root
+ // failure_domain: string
+ failure_domain: '', // Replaced with most common type
+ // device_class: string
+ device_class: '' // Replaced with device type if only one exists beneath domain
+ });
+ }
+
+ ngOnInit() {
+ this.crushRuleService
+ .getInfo()
+ .subscribe(({ names, nodes }: { names: string[]; nodes: CrushNode[] }) => {
+ this.initCrushNodeSelection(
+ nodes,
+ this.form.get('root'),
+ this.form.get('failure_domain'),
+ this.form.get('device_class')
+ );
+ this.names = names;
+ });
+ }
+
+ onSubmit() {
+ if (this.form.invalid) {
+ this.form.setErrors({ cdSubmitButton: true });
+ return;
+ }
+ const rule = _.cloneDeep(this.form.value);
+ rule.root = rule.root.name;
+ if (rule.device_class === '') {
+ delete rule.device_class;
+ }
+ this.taskWrapper
+ .wrapTaskAroundCall({
+ task: new FinishedTask('crushRule/create', rule),
+ call: this.crushRuleService.create(rule)
+ })
+ .subscribe({
+ error: () => {
+ this.form.setErrors({ cdSubmitButton: true });
+ },
+ complete: () => {
+ this.activeModal.close();
+ this.submitAction.emit(rule);
+ }
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html
new file mode 100644
index 000000000..b4b9cd193
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html
@@ -0,0 +1,420 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container i18n="form title"
+ class="modal-title">{{ action | titlecase }} {{ resource | upperFirst }}</ng-container>
+
+ <ng-container class="modal-content">
+ <form #frm="ngForm"
+ [formGroup]="form"
+ novalidate>
+ <div class="modal-body">
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="name"
+ i18n>Name</label>
+ <div class="cd-col-form-input">
+ <input type="text"
+ id="name"
+ name="name"
+ class="form-control"
+ placeholder="Name..."
+ formControlName="name"
+ autofocus>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('name', frm, 'required')"
+ i18n>This field is required!</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('name', frm, 'pattern')"
+ i18n>The name can only consist of alphanumeric characters, dashes and underscores.</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('name', frm, 'uniqueName')"
+ i18n>The chosen erasure code profile name is already in use.</span>
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label for="plugin"
+ class="cd-col-form-label">
+ <span class="required"
+ i18n>Plugin</span>
+ <cd-helper [html]="tooltips.plugins[plugin].description">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ id="plugin"
+ name="plugin"
+ formControlName="plugin">
+ <option *ngIf="!plugins"
+ ngValue=""
+ i18n>Loading...</option>
+ <option *ngFor="let plugin of plugins"
+ [ngValue]="plugin">
+ {{ plugin }}
+ </option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('name', frm, 'required')"
+ i18n>This field is required!</span>
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label for="k"
+ class="cd-col-form-label">
+ <span class="required"
+ i18n>Data chunks (k)</span>
+ <cd-helper [html]="tooltips.k">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input type="number"
+ id="k"
+ name="k"
+ class="form-control"
+ ng-model="$ctrl.erasureCodeProfile.k"
+ placeholder="Data chunks..."
+ formControlName="k"
+ min="2">
+ <span class="invalid-feedback"
+ *ngIf="form.showError('k', frm, 'required')"
+ i18n>This field is required!</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('k', frm, 'min')"
+ i18n>Must be equal to or greater than 2.</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('k', frm, 'max')"
+ i18n>Chunks (k+m) have exceeded the available OSDs of {{deviceCount}}.</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('k', frm, 'unequal')"
+ i18n>For an equal distribution k has to be a multiple of (k+m)/l.</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('k', frm, 'kLowerM')"
+ i18n>K has to be equal to or greater than m in order to recover data correctly through c.</span>
+ <span *ngIf="plugin === 'lrc'"
+ class="form-text text-muted"
+ i18n>Distribution factor: {{lrcMultiK}}</span>
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label for="m"
+ class="cd-col-form-label">
+ <span class="required"
+ i18n>Coding chunks (m)</span>
+ <cd-helper [html]="tooltips.m">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input type="number"
+ id="m"
+ name="m"
+ class="form-control"
+ placeholder="Coding chunks..."
+ formControlName="m"
+ min="1">
+ <span class="invalid-feedback"
+ *ngIf="form.showError('m', frm, 'required')"
+ i18n>This field is required!</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('m', frm, 'min')"
+ i18n>Must be equal to or greater than 1.</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('m', frm, 'max')"
+ i18n>Chunks (k+m) have exceeded the available OSDs of {{deviceCount}}.</span>
+ </div>
+ </div>
+
+ <div class="form-group row"
+ *ngIf="plugin === 'shec'">
+ <label for="c"
+ class="cd-col-form-label">
+ <span class="required"
+ i18n>Durability estimator (c)</span>
+ <cd-helper [html]="tooltips.plugins.shec.c">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input type="number"
+ id="c"
+ name="c"
+ class="form-control"
+ placeholder="Coding chunks..."
+ formControlName="c"
+ min="1">
+ <span class="invalid-feedback"
+ *ngIf="form.showError('c', frm, 'min')"
+ i18n>Must be equal to or greater than 1.</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('c', frm, 'cGreaterM')"
+ i18n>C has to be equal to or lower than m as m defines the amount of chunks that can be used.</span>
+ </div>
+ </div>
+
+ <div class="form-group row"
+ *ngIf="plugin === 'clay'">
+ <label for="d"
+ class="cd-col-form-label">
+ <span class="required"
+ i18n>Helper chunks (d)</span>
+ <cd-helper [html]="tooltips.plugins.clay.d">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input type="number"
+ id="d"
+ name="d"
+ class="form-control"
+ placeholder="Helper chunks..."
+ formControlName="d">
+ <span class="input-group-append">
+ <button class="btn btn-light"
+ id="d-calc-btn"
+ ngbTooltip="Set d manually or use the plugin's default calculation that maximizes d."
+ i18n-ngbTooltip
+ type="button"
+ (click)="toggleDCalc()">
+ <i [ngClass]="dCalc ? icons.unlock : icons.lock"
+ aria-hidden="true"></i>
+ </button>
+ </span>
+ </div>
+ <span class="form-text text-muted"
+ *ngIf="dCalc"
+ i18n>D is automatically updated on k and m changes</span>
+ <ng-container
+ *ngIf="!dCalc">
+ <span class="form-text text-muted"
+ *ngIf="getDMin() < getDMax()"
+ i18n>D can be set from {{getDMin()}} to {{getDMax()}}</span>
+ <span class="form-text text-muted"
+ *ngIf="getDMin() === getDMax()"
+ i18n>D can only be set to {{getDMax()}}</span>
+ </ng-container>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('d', frm, 'dMin')"
+ i18n>D has to be greater than k ({{getDMin()}}).</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('d', frm, 'dMax')"
+ i18n>D has to be lower than k + m ({{getDMax()}}).</span>
+ </div>
+ </div>
+
+ <div class="form-group row"
+ *ngIf="plugin === PLUGIN.LRC">
+ <label class="cd-col-form-label"
+ for="l">
+ <span class="required"
+ i18n>Locality (l)</span>
+ <cd-helper [html]="tooltips.plugins.lrc.l">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input type="number"
+ id="l"
+ name="l"
+ class="form-control"
+ placeholder="Coding chunks..."
+ formControlName="l"
+ min="1">
+ <span class="invalid-feedback"
+ *ngIf="form.showError('l', frm, 'required')"
+ i18n>This field is required!</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('l', frm, 'min')"
+ i18n>Must be equal to or greater than 1.</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('l', frm, 'unequal')"
+ i18n>Can't split up chunks (k+m) correctly with the current locality.</span>
+ <span class="form-text text-muted"
+ i18n>Locality groups: {{lrcGroups}}</span>
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label for="crushFailureDomain"
+ class="cd-col-form-label">
+ <ng-container i18n>Crush failure domain</ng-container>
+ <cd-helper [html]="tooltips.crushFailureDomain">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ id="crushFailureDomain"
+ name="crushFailureDomain"
+ formControlName="crushFailureDomain">
+ <option *ngIf="!failureDomains"
+ ngValue=""
+ i18n>Loading...</option>
+ <option *ngFor="let domain of failureDomainKeys"
+ [ngValue]="domain">
+ {{ domain }} ( {{failureDomains[domain].length}} )
+ </option>
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group row"
+ *ngIf="plugin === PLUGIN.LRC">
+ <label for="crushLocality"
+ class="cd-col-form-label">
+ <ng-container i18n>Crush Locality</ng-container>
+ <cd-helper [html]="tooltips.plugins.lrc.crushLocality">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ id="crushLocality"
+ name="crushLocality"
+ formControlName="crushLocality">
+ <option *ngIf="!failureDomains"
+ ngValue=""
+ i18n>Loading...</option>
+ <option *ngIf="failureDomainKeys.length > 0"
+ ngValue=""
+ i18n>None</option>
+ <option *ngFor="let domain of failureDomainKeys"
+ [ngValue]="domain">
+ {{ domain }} ( {{failureDomains[domain].length}} )
+ </option>
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group row"
+ *ngIf="PLUGIN.CLAY === plugin">
+ <label for="scalar_mds"
+ class="cd-col-form-label">
+ <ng-container i18n>Scalar mds</ng-container>
+ <cd-helper [html]="tooltips.plugins.clay.scalar_mds">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ id="scalar_mds"
+ name="scalar_mds"
+ formControlName="scalar_mds">
+ <option *ngFor="let plugin of [PLUGIN.JERASURE, PLUGIN.ISA, PLUGIN.SHEC]"
+ [ngValue]="plugin">
+ {{ plugin }}
+ </option>
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group row"
+ *ngIf="[PLUGIN.JERASURE, PLUGIN.ISA, PLUGIN.CLAY].includes(plugin)">
+ <label for="technique"
+ class="cd-col-form-label">
+ <ng-container i18n>Technique</ng-container>
+ <cd-helper [html]="tooltips.plugins[plugin].technique">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ id="technique"
+ name="technique"
+ formControlName="technique">
+ <option *ngFor="let technique of techniques"
+ [ngValue]="technique">
+ {{ technique }}
+ </option>
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group row"
+ *ngIf="plugin === PLUGIN.JERASURE">
+ <label for="packetSize"
+ class="cd-col-form-label">
+ <ng-container i18n>Packetsize</ng-container>
+ <cd-helper [html]="tooltips.plugins.jerasure.packetSize">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input type="number"
+ id="packetSize"
+ name="packetSize"
+ class="form-control"
+ placeholder="Packetsize..."
+ formControlName="packetSize"
+ min="1">
+ <span class="invalid-feedback"
+ *ngIf="form.showError('packetSize', frm, 'min')"
+ i18n>Must be equal to or greater than 1.</span>
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label for="crushRoot"
+ class="cd-col-form-label">
+ <ng-container i18n>Crush root</ng-container>
+ <cd-helper [html]="tooltips.crushRoot">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ id="crushRoot"
+ name="crushRoot"
+ formControlName="crushRoot">
+ <option *ngIf="!buckets"
+ ngValue=""
+ i18n>Loading...</option>
+ <option *ngFor="let bucket of buckets"
+ [ngValue]="bucket">
+ {{ bucket.name }}
+ </option>
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label for="crushDeviceClass"
+ class="cd-col-form-label">
+ <ng-container i18n>Crush device class</ng-container>
+ <cd-helper [html]="tooltips.crushDeviceClass">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ id="crushDeviceClass"
+ name="crushDeviceClass"
+ formControlName="crushDeviceClass">
+ <option ngValue=""
+ i18n>Let Ceph decide</option>
+ <option *ngFor="let deviceClass of devices"
+ [ngValue]="deviceClass">
+ {{ deviceClass }}
+ </option>
+ </select>
+ <span class="form-text text-muted"
+ i18n>Available OSDs: {{deviceCount}}</span>
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label for="directory"
+ class="cd-col-form-label">
+ <ng-container i18n>Directory</ng-container>
+ <cd-helper [html]="tooltips.directory">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input type="text"
+ id="directory"
+ name="directory"
+ class="form-control"
+ placeholder="Path..."
+ formControlName="directory">
+ </div>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="onSubmit()"
+ [form]="form"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.spec.ts
new file mode 100644
index 000000000..7d0331dfe
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.spec.ts
@@ -0,0 +1,688 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { ErasureCodeProfileService } from '~/app/shared/api/erasure-code-profile.service';
+import { CrushNode } from '~/app/shared/models/crush-node';
+import { ErasureCodeProfile } from '~/app/shared/models/erasure-code-profile';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { configureTestBed, FixtureHelper, FormHelper, Mocks } from '~/testing/unit-test-helper';
+import { PoolModule } from '../pool.module';
+import { ErasureCodeProfileFormModalComponent } from './erasure-code-profile-form-modal.component';
+
+describe('ErasureCodeProfileFormModalComponent', () => {
+ let component: ErasureCodeProfileFormModalComponent;
+ let ecpService: ErasureCodeProfileService;
+ let fixture: ComponentFixture<ErasureCodeProfileFormModalComponent>;
+ let formHelper: FormHelper;
+ let fixtureHelper: FixtureHelper;
+ let data: { plugins: string[]; names: string[]; nodes: CrushNode[] };
+
+ const expectTechnique = (current: string) =>
+ expect(component.form.getValue('technique')).toBe(current);
+
+ const expectTechniques = (techniques: string[], current: string) => {
+ expect(component.techniques).toEqual(techniques);
+ expectTechnique(current);
+ };
+
+ const expectRequiredControls = (controlNames: string[]) => {
+ controlNames.forEach((name) => {
+ const value = component.form.getValue(name);
+ formHelper.expectValid(name);
+ formHelper.expectErrorChange(name, null, 'required');
+ // This way other fields won't fail through getting invalid.
+ formHelper.expectValidChange(name, value);
+ });
+ fixtureHelper.expectIdElementsVisible(controlNames, true);
+ };
+
+ configureTestBed({
+ imports: [HttpClientTestingModule, RouterTestingModule, ToastrModule.forRoot(), PoolModule],
+ providers: [ErasureCodeProfileService, NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ErasureCodeProfileFormModalComponent);
+ fixtureHelper = new FixtureHelper(fixture);
+ component = fixture.componentInstance;
+ formHelper = new FormHelper(component.form);
+ ecpService = TestBed.inject(ErasureCodeProfileService);
+ data = {
+ plugins: ['isa', 'jerasure', 'shec', 'lrc'],
+ names: ['ecp1', 'ecp2'],
+ /**
+ * Create the following test crush map:
+ * > default
+ * --> ssd-host
+ * ----> 3x osd with ssd
+ * --> mix-host
+ * ----> hdd-rack
+ * ------> 5x osd-rack with hdd
+ * ----> ssd-rack
+ * ------> 5x osd-rack with ssd
+ */
+ nodes: [
+ // Root node
+ Mocks.getCrushNode('default', -1, 'root', 11, [-2, -3]),
+ // SSD host
+ Mocks.getCrushNode('ssd-host', -2, 'host', 1, [1, 0, 2]),
+ Mocks.getCrushNode('osd.0', 0, 'osd', 0, undefined, 'ssd'),
+ Mocks.getCrushNode('osd.1', 1, 'osd', 0, undefined, 'ssd'),
+ Mocks.getCrushNode('osd.2', 2, 'osd', 0, undefined, 'ssd'),
+ // SSD and HDD mixed devices host
+ Mocks.getCrushNode('mix-host', -3, 'host', 1, [-4, -5]),
+ // HDD rack
+ Mocks.getCrushNode('hdd-rack', -4, 'rack', 3, [3, 4, 5, 6, 7]),
+ Mocks.getCrushNode('osd2.0', 3, 'osd-rack', 0, undefined, 'hdd'),
+ Mocks.getCrushNode('osd2.1', 4, 'osd-rack', 0, undefined, 'hdd'),
+ Mocks.getCrushNode('osd2.2', 5, 'osd-rack', 0, undefined, 'hdd'),
+ Mocks.getCrushNode('osd2.3', 6, 'osd-rack', 0, undefined, 'hdd'),
+ Mocks.getCrushNode('osd2.4', 7, 'osd-rack', 0, undefined, 'hdd'),
+ // SSD rack
+ Mocks.getCrushNode('ssd-rack', -5, 'rack', 3, [8, 9, 10, 11, 12]),
+ Mocks.getCrushNode('osd3.0', 8, 'osd-rack', 0, undefined, 'ssd'),
+ Mocks.getCrushNode('osd3.1', 9, 'osd-rack', 0, undefined, 'ssd'),
+ Mocks.getCrushNode('osd3.2', 10, 'osd-rack', 0, undefined, 'ssd'),
+ Mocks.getCrushNode('osd3.3', 11, 'osd-rack', 0, undefined, 'ssd'),
+ Mocks.getCrushNode('osd3.4', 12, 'osd-rack', 0, undefined, 'ssd')
+ ]
+ };
+ spyOn(ecpService, 'getInfo').and.callFake(() => of(data));
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('calls listing to get ecps on ngInit', () => {
+ expect(ecpService.getInfo).toHaveBeenCalled();
+ expect(component.names.length).toBe(2);
+ });
+
+ describe('form validation', () => {
+ it(`isn't valid if name is not set`, () => {
+ expect(component.form.invalid).toBeTruthy();
+ formHelper.setValue('name', 'someProfileName');
+ expect(component.form.valid).toBeTruthy();
+ });
+
+ it('sets name invalid', () => {
+ component.names = ['awesomeProfileName'];
+ formHelper.expectErrorChange('name', 'awesomeProfileName', 'uniqueName');
+ formHelper.expectErrorChange('name', 'some invalid text', 'pattern');
+ formHelper.expectErrorChange('name', null, 'required');
+ });
+
+ it('sets k to min error', () => {
+ formHelper.expectErrorChange('k', 1, 'min');
+ });
+
+ it('sets m to min error', () => {
+ formHelper.expectErrorChange('m', 0, 'min');
+ });
+
+ it(`should show all default form controls`, () => {
+ const showDefaults = (plugin: string) => {
+ formHelper.setValue('plugin', plugin);
+ fixtureHelper.expectIdElementsVisible(
+ [
+ 'name',
+ 'plugin',
+ 'k',
+ 'm',
+ 'crushFailureDomain',
+ 'crushRoot',
+ 'crushDeviceClass',
+ 'directory'
+ ],
+ true
+ );
+ };
+ showDefaults('jerasure');
+ showDefaults('shec');
+ showDefaults('lrc');
+ showDefaults('isa');
+ });
+
+ it('should change technique to default if not available in other plugin', () => {
+ expectTechnique('reed_sol_van');
+ formHelper.setValue('technique', 'blaum_roth');
+ expectTechnique('blaum_roth');
+ formHelper.setValue('plugin', 'isa');
+ expectTechnique('reed_sol_van');
+ formHelper.setValue('plugin', 'clay');
+ formHelper.expectValidChange('scalar_mds', 'shec');
+ expectTechnique('single');
+ });
+
+ describe(`for 'jerasure' plugin (default)`, () => {
+ it(`requires 'm' and 'k'`, () => {
+ expectRequiredControls(['k', 'm']);
+ });
+
+ it(`should show 'packetSize' and 'technique'`, () => {
+ fixtureHelper.expectIdElementsVisible(['packetSize', 'technique'], true);
+ });
+
+ it('should show available techniques', () => {
+ expectTechniques(
+ [
+ 'reed_sol_van',
+ 'reed_sol_r6_op',
+ 'cauchy_orig',
+ 'cauchy_good',
+ 'liberation',
+ 'blaum_roth',
+ 'liber8tion'
+ ],
+ 'reed_sol_van'
+ );
+ });
+
+ it(`should not show any other plugin specific form control`, () => {
+ fixtureHelper.expectIdElementsVisible(
+ ['c', 'l', 'crushLocality', 'd', 'scalar_mds'],
+ false
+ );
+ });
+
+ it('should not allow "k" to be changed more than possible', () => {
+ formHelper.expectErrorChange('k', 10, 'max');
+ });
+
+ it('should not allow "m" to be changed more than possible', () => {
+ formHelper.expectErrorChange('m', 10, 'max');
+ });
+ });
+
+ describe(`for 'isa' plugin`, () => {
+ beforeEach(() => {
+ formHelper.setValue('plugin', 'isa');
+ });
+
+ it(`does require 'm' and 'k'`, () => {
+ expectRequiredControls(['k', 'm']);
+ });
+
+ it(`should show 'technique'`, () => {
+ fixtureHelper.expectIdElementsVisible(['technique'], true);
+ });
+
+ it('should show available techniques', () => {
+ expectTechniques(['reed_sol_van', 'cauchy'], 'reed_sol_van');
+ });
+
+ it(`should not show any other plugin specific form control`, () => {
+ fixtureHelper.expectIdElementsVisible(
+ ['c', 'l', 'crushLocality', 'packetSize', 'd', 'scalar_mds'],
+ false
+ );
+ });
+
+ it('should not allow "k" to be changed more than possible', () => {
+ formHelper.expectErrorChange('k', 10, 'max');
+ });
+
+ it('should not allow "m" to be changed more than possible', () => {
+ formHelper.expectErrorChange('m', 10, 'max');
+ });
+ });
+
+ describe(`for 'lrc' plugin`, () => {
+ beforeEach(() => {
+ formHelper.setValue('plugin', 'lrc');
+ formHelper.expectValid('k');
+ formHelper.expectValid('l');
+ formHelper.expectValid('m');
+ });
+
+ it(`requires 'm', 'l' and 'k'`, () => {
+ expectRequiredControls(['k', 'm', 'l']);
+ });
+
+ it(`should show 'l' and 'crushLocality'`, () => {
+ fixtureHelper.expectIdElementsVisible(['l', 'crushLocality'], true);
+ });
+
+ it(`should not show any other plugin specific form control`, () => {
+ fixtureHelper.expectIdElementsVisible(
+ ['c', 'packetSize', 'technique', 'd', 'scalar_mds'],
+ false
+ );
+ });
+
+ it('should not allow "k" to be changed more than possible', () => {
+ formHelper.expectErrorChange('k', 10, 'max');
+ });
+
+ it('should not allow "m" to be changed more than possible', () => {
+ formHelper.expectErrorChange('m', 10, 'max');
+ });
+
+ it('should not allow "l" to be changed so that (k+m) is not a multiple of "l"', () => {
+ formHelper.expectErrorChange('l', 4, 'unequal');
+ });
+
+ it('should update validity of k and l on m change', () => {
+ formHelper.expectValidChange('m', 3);
+ formHelper.expectError('k', 'unequal');
+ formHelper.expectError('l', 'unequal');
+ });
+
+ describe('lrc calculation', () => {
+ const expectCorrectCalculation = (
+ k: number,
+ m: number,
+ l: number,
+ failedControl: string[] = []
+ ) => {
+ formHelper.setValue('k', k);
+ formHelper.setValue('m', m);
+ formHelper.setValue('l', l);
+ ['k', 'l'].forEach((name) => {
+ if (failedControl.includes(name)) {
+ formHelper.expectError(name, 'unequal');
+ } else {
+ formHelper.expectValid(name);
+ }
+ });
+ };
+
+ const tests = {
+ kFails: [
+ [2, 1, 1],
+ [2, 2, 1],
+ [3, 1, 1],
+ [3, 2, 1],
+ [3, 1, 2],
+ [3, 3, 1],
+ [3, 3, 3],
+ [4, 1, 1],
+ [4, 2, 1],
+ [4, 2, 2],
+ [4, 3, 1],
+ [4, 4, 1]
+ ],
+ lFails: [
+ [2, 1, 2],
+ [3, 2, 2],
+ [3, 1, 3],
+ [3, 2, 3],
+ [4, 1, 2],
+ [4, 3, 2],
+ [4, 3, 3],
+ [4, 1, 3],
+ [4, 4, 3],
+ [4, 1, 4],
+ [4, 2, 4],
+ [4, 3, 4]
+ ],
+ success: [
+ [2, 2, 2],
+ [2, 2, 4],
+ [3, 3, 2],
+ [3, 3, 6],
+ [4, 2, 3],
+ [4, 2, 6],
+ [4, 4, 2],
+ [4, 4, 8],
+ [4, 4, 4]
+ ]
+ };
+
+ it('tests all cases where k fails', () => {
+ tests.kFails.forEach((testCase) => {
+ expectCorrectCalculation(testCase[0], testCase[1], testCase[2], ['k']);
+ });
+ });
+
+ it('tests all cases where l fails', () => {
+ tests.lFails.forEach((testCase) => {
+ expectCorrectCalculation(testCase[0], testCase[1], testCase[2], ['k', 'l']);
+ });
+ });
+
+ it('tests all cases where everything is valid', () => {
+ tests.success.forEach((testCase) => {
+ expectCorrectCalculation(testCase[0], testCase[1], testCase[2]);
+ });
+ });
+ });
+ });
+
+ describe(`for 'shec' plugin`, () => {
+ beforeEach(() => {
+ formHelper.setValue('plugin', 'shec');
+ formHelper.expectValid('c');
+ formHelper.expectValid('m');
+ formHelper.expectValid('k');
+ });
+
+ it(`does require 'm', 'c' and 'k'`, () => {
+ expectRequiredControls(['k', 'm', 'c']);
+ });
+
+ it(`should not show any other plugin specific form control`, () => {
+ fixtureHelper.expectIdElementsVisible(
+ ['l', 'crushLocality', 'packetSize', 'technique', 'd', 'scalar_mds'],
+ false
+ );
+ });
+
+ it('should make sure that k has to be equal or greater than m', () => {
+ formHelper.expectValidChange('k', 3);
+ formHelper.expectErrorChange('k', 2, 'kLowerM');
+ });
+
+ it('should make sure that c has to be equal or less than m', () => {
+ formHelper.expectValidChange('c', 3);
+ formHelper.expectErrorChange('c', 4, 'cGreaterM');
+ });
+
+ it('should update validity of k and c on m change', () => {
+ formHelper.expectValidChange('m', 5);
+ formHelper.expectError('k', 'kLowerM');
+ formHelper.expectValid('c');
+
+ formHelper.expectValidChange('m', 1);
+ formHelper.expectError('c', 'cGreaterM');
+ formHelper.expectValid('k');
+ });
+ });
+
+ describe(`for 'clay' plugin`, () => {
+ beforeEach(() => {
+ formHelper.setValue('plugin', 'clay');
+ // Through this change d has a valid range from 4 to 7
+ formHelper.expectValidChange('k', 3);
+ formHelper.expectValidChange('m', 5);
+ });
+
+ it(`does require 'm', 'c', 'd', 'scalar_mds' and 'k'`, () => {
+ fixtureHelper.clickElement('#d-calc-btn');
+ expectRequiredControls(['k', 'm', 'd', 'scalar_mds']);
+ });
+
+ it(`should not show any other plugin specific form control`, () => {
+ fixtureHelper.expectIdElementsVisible(['l', 'crushLocality', 'packetSize', 'c'], false);
+ });
+
+ it('should show default values for d and scalar_mds', () => {
+ expect(component.form.getValue('d')).toBe(7); // (k+m-1)
+ expect(component.form.getValue('scalar_mds')).toBe('jerasure');
+ });
+
+ it('should auto change d if auto calculation is enabled (default)', () => {
+ formHelper.expectValidChange('k', 4);
+ expect(component.form.getValue('d')).toBe(8);
+ });
+
+ it('should have specific techniques for scalar_mds jerasure', () => {
+ expectTechniques(
+ ['reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig', 'cauchy_good', 'liber8tion'],
+ 'reed_sol_van'
+ );
+ });
+
+ it('should have specific techniques for scalar_mds isa', () => {
+ formHelper.expectValidChange('scalar_mds', 'isa');
+ expectTechniques(['reed_sol_van', 'cauchy'], 'reed_sol_van');
+ });
+
+ it('should have specific techniques for scalar_mds shec', () => {
+ formHelper.expectValidChange('scalar_mds', 'shec');
+ expectTechniques(['single', 'multiple'], 'single');
+ });
+
+ describe('Validity of d', () => {
+ beforeEach(() => {
+ // Don't automatically change d - the only way to get d invalid
+ fixtureHelper.clickElement('#d-calc-btn');
+ });
+
+ it('should not automatically change d if k or m have been changed', () => {
+ formHelper.expectValidChange('m', 4);
+ formHelper.expectValidChange('k', 5);
+ expect(component.form.getValue('d')).toBe(7);
+ });
+
+ it('should trigger dMin through change of d', () => {
+ formHelper.expectErrorChange('d', 3, 'dMin');
+ });
+
+ it('should trigger dMax through change of d', () => {
+ formHelper.expectErrorChange('d', 8, 'dMax');
+ });
+
+ it('should trigger dMin through change of k and m', () => {
+ formHelper.expectValidChange('m', 2);
+ formHelper.expectValidChange('k', 7);
+ formHelper.expectError('d', 'dMin');
+ });
+
+ it('should trigger dMax through change of m', () => {
+ formHelper.expectValidChange('m', 3);
+ formHelper.expectError('d', 'dMax');
+ });
+
+ it('should remove dMax through change of k', () => {
+ formHelper.expectValidChange('m', 3);
+ formHelper.expectError('d', 'dMax');
+ formHelper.expectValidChange('k', 5);
+ formHelper.expectValid('d');
+ });
+ });
+ });
+ });
+
+ describe('submission', () => {
+ let ecp: ErasureCodeProfile;
+ let submittedEcp: ErasureCodeProfile;
+
+ const testCreation = () => {
+ fixture.detectChanges();
+ component.onSubmit();
+ expect(ecpService.create).toHaveBeenCalledWith(submittedEcp);
+ };
+
+ const ecpChange = (attribute: string, value: string | number) => {
+ ecp[attribute] = value;
+ submittedEcp[attribute] = value;
+ };
+
+ beforeEach(() => {
+ ecp = new ErasureCodeProfile();
+ submittedEcp = new ErasureCodeProfile();
+ submittedEcp['crush-root'] = 'default';
+ submittedEcp['crush-failure-domain'] = 'osd-rack';
+ submittedEcp['packetsize'] = 2048;
+ submittedEcp['technique'] = 'reed_sol_van';
+
+ const taskWrapper = TestBed.inject(TaskWrapperService);
+ spyOn(taskWrapper, 'wrapTaskAroundCall').and.callThrough();
+ spyOn(ecpService, 'create').and.stub();
+ });
+
+ describe(`'jerasure' usage`, () => {
+ beforeEach(() => {
+ submittedEcp['plugin'] = 'jerasure';
+ ecpChange('name', 'jerasureProfile');
+ submittedEcp.k = 4;
+ submittedEcp.m = 2;
+ });
+
+ it('should be able to create a profile with only required fields', () => {
+ formHelper.setMultipleValues(ecp, true);
+ testCreation();
+ });
+
+ it(`does not create with missing 'k' or invalid form`, () => {
+ ecpChange('k', 0);
+ formHelper.setMultipleValues(ecp, true);
+ component.onSubmit();
+ expect(ecpService.create).not.toHaveBeenCalled();
+ });
+
+ it('should be able to create a profile with m, k, name, directory and packetSize', () => {
+ ecpChange('m', 3);
+ ecpChange('directory', '/different/ecp/path');
+ formHelper.setMultipleValues(ecp, true);
+ formHelper.setValue('packetSize', 8192, true);
+ ecpChange('packetsize', 8192);
+ testCreation();
+ });
+
+ it('should not send the profile with unsupported fields', () => {
+ formHelper.setMultipleValues(ecp, true);
+ formHelper.setValue('crushLocality', 'osd', true);
+ testCreation();
+ });
+ });
+
+ describe(`'isa' usage`, () => {
+ beforeEach(() => {
+ ecpChange('name', 'isaProfile');
+ ecpChange('plugin', 'isa');
+ submittedEcp.k = 7;
+ submittedEcp.m = 3;
+ delete submittedEcp.packetsize;
+ });
+
+ it('should be able to create a profile with only plugin and name', () => {
+ formHelper.setMultipleValues(ecp, true);
+ testCreation();
+ });
+
+ it('should send profile with plugin, name, failure domain and technique only', () => {
+ ecpChange('technique', 'cauchy');
+ formHelper.setMultipleValues(ecp, true);
+ formHelper.setValue('crushFailureDomain', 'osd', true);
+ submittedEcp['crush-failure-domain'] = 'osd';
+ submittedEcp['crush-device-class'] = 'ssd';
+ testCreation();
+ });
+
+ it('should not send the profile with unsupported fields', () => {
+ formHelper.setMultipleValues(ecp, true);
+ formHelper.setValue('packetSize', 'osd', true);
+ testCreation();
+ });
+ });
+
+ describe(`'lrc' usage`, () => {
+ beforeEach(() => {
+ ecpChange('name', 'lrcProfile');
+ ecpChange('plugin', 'lrc');
+ submittedEcp.k = 4;
+ submittedEcp.m = 2;
+ submittedEcp.l = 3;
+ delete submittedEcp.packetsize;
+ delete submittedEcp.technique;
+ });
+
+ it('should be able to create a profile with only required fields', () => {
+ formHelper.setMultipleValues(ecp, true);
+ testCreation();
+ });
+
+ it('should send profile with all required fields and crush root and locality', () => {
+ ecpChange('l', '6');
+ formHelper.setMultipleValues(ecp, true);
+ formHelper.setValue('crushRoot', component.buckets[2], true);
+ submittedEcp['crush-root'] = 'mix-host';
+ formHelper.setValue('crushLocality', 'osd-rack', true);
+ submittedEcp['crush-locality'] = 'osd-rack';
+ testCreation();
+ });
+
+ it('should not send the profile with unsupported fields', () => {
+ formHelper.setMultipleValues(ecp, true);
+ formHelper.setValue('c', 4, true);
+ testCreation();
+ });
+ });
+
+ describe(`'shec' usage`, () => {
+ beforeEach(() => {
+ ecpChange('name', 'shecProfile');
+ ecpChange('plugin', 'shec');
+ submittedEcp.k = 4;
+ submittedEcp.m = 3;
+ submittedEcp.c = 2;
+ delete submittedEcp.packetsize;
+ delete submittedEcp.technique;
+ });
+
+ it('should be able to create a profile with only plugin and name', () => {
+ formHelper.setMultipleValues(ecp, true);
+ testCreation();
+ });
+
+ it('should send profile with plugin, name, c and crush device class only', () => {
+ ecpChange('c', '3');
+ formHelper.setMultipleValues(ecp, true);
+ formHelper.setValue('crushDeviceClass', 'ssd', true);
+ submittedEcp['crush-device-class'] = 'ssd';
+ testCreation();
+ });
+
+ it('should not send the profile with unsupported fields', () => {
+ formHelper.setMultipleValues(ecp, true);
+ formHelper.setValue('l', 8, true);
+ testCreation();
+ });
+ });
+
+ describe(`'clay' usage`, () => {
+ beforeEach(() => {
+ ecpChange('name', 'clayProfile');
+ ecpChange('plugin', 'clay');
+ // Setting expectations
+ submittedEcp.k = 4;
+ submittedEcp.m = 2;
+ submittedEcp.d = 5;
+ submittedEcp.scalar_mds = 'jerasure';
+ delete submittedEcp.packetsize;
+ });
+
+ it('should be able to create a profile with only plugin and name', () => {
+ formHelper.setMultipleValues(ecp, true);
+ testCreation();
+ });
+
+ it('should send profile with a changed d', () => {
+ formHelper.setMultipleValues(ecp, true);
+ ecpChange('d', '5');
+ submittedEcp.d = 5;
+ testCreation();
+ });
+
+ it('should send profile with a changed k which automatically changes d', () => {
+ ecpChange('k', 5);
+ formHelper.setMultipleValues(ecp, true);
+ submittedEcp.d = 6;
+ testCreation();
+ });
+
+ it('should send profile with a changed sclara_mds', () => {
+ ecpChange('scalar_mds', 'shec');
+ formHelper.setMultipleValues(ecp, true);
+ submittedEcp.scalar_mds = 'shec';
+ submittedEcp.technique = 'single';
+ testCreation();
+ });
+
+ it('should not send the profile with unsupported fields', () => {
+ formHelper.setMultipleValues(ecp, true);
+ formHelper.setValue('l', 8, true);
+ testCreation();
+ });
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts
new file mode 100644
index 000000000..01f7dcb1e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts
@@ -0,0 +1,459 @@
+import { Component, EventEmitter, OnInit, Output } from '@angular/core';
+import { Validators } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+import { ErasureCodeProfileService } from '~/app/shared/api/erasure-code-profile.service';
+import { CrushNodeSelectionClass } from '~/app/shared/classes/crush.node.selection.class';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { CrushNode } from '~/app/shared/models/crush-node';
+import { ErasureCodeProfile } from '~/app/shared/models/erasure-code-profile';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+
+@Component({
+ selector: 'cd-erasure-code-profile-form-modal',
+ templateUrl: './erasure-code-profile-form-modal.component.html',
+ styleUrls: ['./erasure-code-profile-form-modal.component.scss']
+})
+export class ErasureCodeProfileFormModalComponent
+ extends CrushNodeSelectionClass
+ implements OnInit {
+ @Output()
+ submitAction = new EventEmitter();
+
+ tooltips = this.ecpService.formTooltips;
+ PLUGIN = {
+ LRC: 'lrc', // Locally Repairable Erasure Code
+ SHEC: 'shec', // Shingled Erasure Code
+ CLAY: 'clay', // Coupled LAYer
+ JERASURE: 'jerasure', // default
+ ISA: 'isa' // Intel Storage Acceleration
+ };
+ plugin = this.PLUGIN.JERASURE;
+ icons = Icons;
+
+ form: CdFormGroup;
+ plugins: string[];
+ names: string[];
+ techniques: string[];
+ action: string;
+ resource: string;
+ dCalc: boolean;
+ lrcGroups: number;
+ lrcMultiK: number;
+
+ constructor(
+ private formBuilder: CdFormBuilder,
+ public activeModal: NgbActiveModal,
+ private taskWrapper: TaskWrapperService,
+ private ecpService: ErasureCodeProfileService,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ super();
+ this.action = this.actionLabels.CREATE;
+ this.resource = $localize`EC Profile`;
+ this.createForm();
+ this.setJerasureDefaults();
+ }
+
+ createForm() {
+ this.form = this.formBuilder.group({
+ name: [
+ null,
+ [
+ Validators.required,
+ Validators.pattern('[A-Za-z0-9_-]+'),
+ CdValidators.custom(
+ 'uniqueName',
+ (value: string) => this.names && this.names.indexOf(value) !== -1
+ )
+ ]
+ ],
+ plugin: [this.PLUGIN.JERASURE, [Validators.required]],
+ k: [
+ 4, // Will be overwritten with plugin defaults
+ [
+ Validators.required,
+ CdValidators.custom('max', () => this.baseValueValidation(true)),
+ CdValidators.custom('unequal', (v: number) => this.lrcDataValidation(v)),
+ CdValidators.custom('kLowerM', (v: number) => this.shecDataValidation(v))
+ ]
+ ],
+ m: [
+ 2, // Will be overwritten with plugin defaults
+ [Validators.required, CdValidators.custom('max', () => this.baseValueValidation())]
+ ],
+ crushFailureDomain: '', // Will be preselected
+ crushRoot: null, // Will be preselected
+ crushDeviceClass: '', // Will be preselected
+ directory: '',
+ // Only for 'jerasure', 'clay' and 'isa' use
+ technique: 'reed_sol_van',
+ // Only for 'jerasure' use
+ packetSize: [2048],
+ // Only for 'lrc' use
+ l: [
+ 3, // Will be overwritten with plugin defaults
+ [
+ Validators.required,
+ CdValidators.custom('unequal', (v: number) => this.lrcLocalityValidation(v))
+ ]
+ ],
+ crushLocality: '', // set to none at the end (same list as for failure domains)
+ // Only for 'shec' use
+ c: [
+ 2, // Will be overwritten with plugin defaults
+ [
+ Validators.required,
+ CdValidators.custom('cGreaterM', (v: number) => this.shecDurabilityValidation(v))
+ ]
+ ],
+ // Only for 'clay' use
+ d: [
+ 5, // Will be overwritten with plugin defaults (k+m-1) = k+1 <= d <= k+m-1
+ [
+ Validators.required,
+ CdValidators.custom('dMin', (v: number) => this.dMinValidation(v)),
+ CdValidators.custom('dMax', (v: number) => this.dMaxValidation(v))
+ ]
+ ],
+ scalar_mds: [this.PLUGIN.JERASURE, [Validators.required]] // jerasure or isa or shec
+ });
+ this.toggleDCalc();
+ this.form.get('k').valueChanges.subscribe(() => this.updateValidityOnChange(['m', 'l', 'd']));
+ this.form
+ .get('m')
+ .valueChanges.subscribe(() => this.updateValidityOnChange(['k', 'l', 'c', 'd']));
+ this.form.get('l').valueChanges.subscribe(() => this.updateValidityOnChange(['k', 'm']));
+ this.form.get('plugin').valueChanges.subscribe((plugin) => this.onPluginChange(plugin));
+ this.form.get('scalar_mds').valueChanges.subscribe(() => this.setClayDefaultsForScalar());
+ }
+
+ private baseValueValidation(dataChunk: boolean = false): boolean {
+ return this.validValidation(() => {
+ return (
+ this.getKMSum() > this.deviceCount &&
+ this.form.getValue('k') > this.form.getValue('m') === dataChunk
+ );
+ });
+ }
+
+ private validValidation(fn: () => boolean, plugin?: string): boolean {
+ if (!this.form || plugin ? this.plugin !== plugin : false) {
+ return false;
+ }
+ return fn();
+ }
+
+ private getKMSum(): number {
+ return this.form.getValue('k') + this.form.getValue('m');
+ }
+
+ private lrcDataValidation(k: number): boolean {
+ return this.validValidation(() => {
+ const m = this.form.getValue('m');
+ const l = this.form.getValue('l');
+ const km = k + m;
+ this.lrcMultiK = k / (km / l);
+ return k % (km / l) !== 0;
+ }, 'lrc');
+ }
+
+ private shecDataValidation(k: number): boolean {
+ return this.validValidation(() => {
+ const m = this.form.getValue('m');
+ return m > k;
+ }, 'shec');
+ }
+
+ private lrcLocalityValidation(l: number) {
+ return this.validValidation(() => {
+ const value = this.getKMSum();
+ this.lrcGroups = l > 0 ? value / l : 0;
+ return l > 0 && value % l !== 0;
+ }, 'lrc');
+ }
+
+ private shecDurabilityValidation(c: number): boolean {
+ return this.validValidation(() => {
+ const m = this.form.getValue('m');
+ return c > m;
+ }, 'shec');
+ }
+
+ private dMinValidation(d: number): boolean {
+ return this.validValidation(() => this.getDMin() > d, 'clay');
+ }
+
+ getDMin(): number {
+ return this.form.getValue('k') + 1;
+ }
+
+ private dMaxValidation(d: number): boolean {
+ return this.validValidation(() => d > this.getDMax(), 'clay');
+ }
+
+ getDMax(): number {
+ const m = this.form.getValue('m');
+ const k = this.form.getValue('k');
+ return k + m - 1;
+ }
+
+ toggleDCalc() {
+ this.dCalc = !this.dCalc;
+ this.form.get('d')[this.dCalc ? 'disable' : 'enable']();
+ this.calculateD();
+ }
+
+ private calculateD() {
+ if (this.plugin !== this.PLUGIN.CLAY || !this.dCalc) {
+ return;
+ }
+ this.form.silentSet('d', this.getDMax());
+ }
+
+ private updateValidityOnChange(names: string[]) {
+ names.forEach((name) => {
+ if (name === 'd') {
+ this.calculateD();
+ }
+ this.form.get(name).updateValueAndValidity({ emitEvent: false });
+ });
+ }
+
+ private onPluginChange(plugin: string) {
+ this.plugin = plugin;
+ if (plugin === this.PLUGIN.JERASURE) {
+ this.setJerasureDefaults();
+ } else if (plugin === this.PLUGIN.LRC) {
+ this.setLrcDefaults();
+ } else if (plugin === this.PLUGIN.ISA) {
+ this.setIsaDefaults();
+ } else if (plugin === this.PLUGIN.SHEC) {
+ this.setShecDefaults();
+ } else if (plugin === this.PLUGIN.CLAY) {
+ this.setClayDefaults();
+ }
+ this.updateValidityOnChange(['m']); // Triggers k, m, c, d and l
+ }
+
+ private setJerasureDefaults() {
+ this.techniques = [
+ 'reed_sol_van',
+ 'reed_sol_r6_op',
+ 'cauchy_orig',
+ 'cauchy_good',
+ 'liberation',
+ 'blaum_roth',
+ 'liber8tion'
+ ];
+ this.setDefaults({
+ k: 4,
+ m: 2,
+ technique: 'reed_sol_van'
+ });
+ }
+
+ private setLrcDefaults() {
+ this.setDefaults({
+ k: 4,
+ m: 2,
+ l: 3
+ });
+ }
+
+ private setIsaDefaults() {
+ /**
+ * Actually k and m are not required - but they will be set to the default values in case
+ * if they are not set, therefore it's fine to mark them as required in order to get
+ * strange values that weren't set.
+ */
+ this.techniques = ['reed_sol_van', 'cauchy'];
+ this.setDefaults({
+ k: 7,
+ m: 3,
+ technique: 'reed_sol_van'
+ });
+ }
+
+ private setShecDefaults() {
+ /**
+ * Actually k, c and m are not required - but they will be set to the default values in case
+ * if they are not set, therefore it's fine to mark them as required in order to get
+ * strange values that weren't set.
+ */
+ this.setDefaults({
+ k: 4,
+ m: 3,
+ c: 2
+ });
+ }
+
+ private setClayDefaults() {
+ /**
+ * Actually d and scalar_mds are not required - but they will be set to show the default values
+ * in case if they are not set, therefore it's fine to mark them as required in order to not get
+ * strange values that weren't set.
+ *
+ * As d would be set to the value k+m-1 for the greatest savings, the form will
+ * automatically update d if the automatic calculation is activated (default).
+ */
+ this.setDefaults({
+ k: 4,
+ m: 2,
+ // d: 5, <- Will be automatically update to 5
+ scalar_mds: this.PLUGIN.JERASURE
+ });
+ this.setClayDefaultsForScalar();
+ }
+
+ private setClayDefaultsForScalar() {
+ const plugin = this.form.getValue('scalar_mds');
+ let defaultTechnique = 'reed_sol_van';
+ if (plugin === this.PLUGIN.JERASURE) {
+ this.techniques = [
+ 'reed_sol_van',
+ 'reed_sol_r6_op',
+ 'cauchy_orig',
+ 'cauchy_good',
+ 'liber8tion'
+ ];
+ } else if (plugin === this.PLUGIN.ISA) {
+ this.techniques = ['reed_sol_van', 'cauchy'];
+ } else {
+ // this.PLUGIN.SHEC
+ defaultTechnique = 'single';
+ this.techniques = ['single', 'multiple'];
+ }
+ this.setDefaults({ technique: defaultTechnique });
+ }
+
+ private setDefaults(defaults: object) {
+ Object.keys(defaults).forEach((controlName) => {
+ const control = this.form.get(controlName);
+ const value = control.value;
+ /**
+ * As k, m, c and l are now set touched and dirty on the beginning, plugin change will
+ * overwrite their values as we can't determine if the user has changed anything.
+ * k and m can have two default values where as l and c can only have one,
+ * so there is no need to overwrite them.
+ */
+ const overwrite =
+ control.pristine ||
+ (controlName === 'technique' && !this.techniques.includes(value)) ||
+ (controlName === 'k' && [4, 7].includes(value)) ||
+ (controlName === 'm' && [2, 3].includes(value));
+ if (overwrite) {
+ control.setValue(defaults[controlName]); // also validates new value
+ } else {
+ control.updateValueAndValidity();
+ }
+ });
+ }
+
+ ngOnInit() {
+ this.ecpService
+ .getInfo()
+ .subscribe(
+ ({
+ plugins,
+ names,
+ directory,
+ nodes
+ }: {
+ plugins: string[];
+ names: string[];
+ directory: string;
+ nodes: CrushNode[];
+ }) => {
+ this.initCrushNodeSelection(
+ nodes,
+ this.form.get('crushRoot'),
+ this.form.get('crushFailureDomain'),
+ this.form.get('crushDeviceClass')
+ );
+ this.plugins = plugins;
+ this.names = names;
+ this.form.silentSet('directory', directory);
+ this.preValidateNumericInputFields();
+ }
+ );
+ }
+
+ /**
+ * This allows k, m, l and c to be validated instantly on change, before the
+ * fields got changed before by the user.
+ */
+ private preValidateNumericInputFields() {
+ const kml = ['k', 'm', 'l', 'c', 'd'].map((name) => this.form.get(name));
+ kml.forEach((control) => {
+ control.markAsTouched();
+ control.markAsDirty();
+ });
+ kml[1].updateValueAndValidity(); // Update validity of k, m, c, d and l
+ }
+
+ onSubmit() {
+ if (this.form.invalid) {
+ this.form.setErrors({ cdSubmitButton: true });
+ return;
+ }
+ const profile = this.createJson();
+ this.taskWrapper
+ .wrapTaskAroundCall({
+ task: new FinishedTask('ecp/create', { name: profile.name }),
+ call: this.ecpService.create(profile)
+ })
+ .subscribe({
+ error: () => {
+ this.form.setErrors({ cdSubmitButton: true });
+ },
+ complete: () => {
+ this.activeModal.close();
+ this.submitAction.emit(profile);
+ }
+ });
+ }
+
+ private createJson() {
+ const pluginControls = {
+ technique: [this.PLUGIN.ISA, this.PLUGIN.JERASURE, this.PLUGIN.CLAY],
+ packetSize: [this.PLUGIN.JERASURE],
+ l: [this.PLUGIN.LRC],
+ crushLocality: [this.PLUGIN.LRC],
+ c: [this.PLUGIN.SHEC],
+ d: [this.PLUGIN.CLAY],
+ scalar_mds: [this.PLUGIN.CLAY]
+ };
+ const ecp = new ErasureCodeProfile();
+ const plugin = this.form.getValue('plugin');
+ Object.keys(this.form.controls)
+ .filter((name) => {
+ const pluginControl = pluginControls[name];
+ const value = this.form.getValue(name);
+ const usable = (pluginControl && pluginControl.includes(plugin)) || !pluginControl;
+ return usable && value && value !== '';
+ })
+ .forEach((name) => {
+ this.extendJson(name, ecp);
+ });
+ return ecp;
+ }
+
+ private extendJson(name: string, ecp: ErasureCodeProfile) {
+ const differentApiAttributes = {
+ crushFailureDomain: 'crush-failure-domain',
+ crushRoot: 'crush-root',
+ crushDeviceClass: 'crush-device-class',
+ packetSize: 'packetsize',
+ crushLocality: 'crush-locality'
+ };
+ const value = this.form.getValue(name);
+ ecp[differentApiAttributes[name] || name] = name === 'crushRoot' ? value.name : value;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.html
new file mode 100644
index 000000000..1b0cd563c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.html
@@ -0,0 +1,51 @@
+<ng-container *ngIf="selection"
+ cdTableDetail>
+ <ul ngbNav
+ #nav="ngbNav"
+ class="nav-tabs"
+ cdStatefulTab="pool-details">
+ <li ngbNavItem="details">
+ <a ngbNavLink
+ i18n>Details</a>
+ <ng-template ngbNavContent>
+ <cd-table-key-value [renderObjects]="true"
+ [data]="poolDetails"
+ [autoReload]="false">
+ </cd-table-key-value>
+ </ng-template>
+ </li>
+ <li ngbNavItem="performance-details"
+ *ngIf="permissions.grafana.read">
+ <a ngbNavLink
+ i18n>Performance Details</a>
+ <ng-template ngbNavContent>
+ <cd-grafana grafanaPath="ceph-pool-detail?var-pool_name={{selection.pool_name}}"
+ uid="-xyV8KCiz"
+ grafanaStyle="three">
+ </cd-grafana>
+ </ng-template>
+ </li>
+ <li ngbNavItem="configuration"
+ *ngIf="selection.type === 'replicated'">
+ <a ngbNavLink
+ i18n>Configuration</a>
+ <ng-template ngbNavContent>
+ <cd-rbd-configuration-table [data]="selectedPoolConfiguration"></cd-rbd-configuration-table>
+ </ng-template>
+ </li>
+ <li ngbNavItem="cache-tiers-details"
+ *ngIf="selection['tiers']?.length > 0">
+ <a ngbNavLink
+ i18n>Cache Tiers Details</a>
+ <ng-template ngbNavContent>
+ <cd-table [data]="cacheTiers"
+ [columns]="cacheTierColumns"
+ [autoSave]="false"
+ columnMode="flex">
+ </cd-table>
+ </ng-template>
+ </li>
+ </ul>
+
+ <div [ngbNavOutlet]="nav"></div>
+</ng-container>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.spec.ts
new file mode 100644
index 000000000..f30f954b5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.spec.ts
@@ -0,0 +1,171 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ChangeDetectorRef } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { RbdConfigurationListComponent } from '~/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component';
+import { Permissions } from '~/app/shared/models/permissions';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, Mocks, TabHelper } from '~/testing/unit-test-helper';
+import { PoolDetailsComponent } from './pool-details.component';
+
+describe('PoolDetailsComponent', () => {
+ let poolDetailsComponent: PoolDetailsComponent;
+ let fixture: ComponentFixture<PoolDetailsComponent>;
+
+ // Needed because of ChangeDetectionStrategy.OnPush
+ // https://github.com/angular/angular/issues/12313#issuecomment-444623173
+ let changeDetector: ChangeDetectorRef;
+ const detectChanges = () => {
+ poolDetailsComponent.ngOnChanges();
+ changeDetector.detectChanges(); // won't call ngOnChanges on it's own but updates fixture
+ };
+
+ const updatePoolSelection = (selection: any) => {
+ poolDetailsComponent.selection = selection;
+ detectChanges();
+ };
+
+ const currentPoolUpdate = () => {
+ updatePoolSelection(poolDetailsComponent.selection);
+ };
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ NgbNavModule,
+ SharedModule,
+ HttpClientTestingModule,
+ RouterTestingModule
+ ],
+ declarations: [PoolDetailsComponent, RbdConfigurationListComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(PoolDetailsComponent);
+ // Needed because of ChangeDetectionStrategy.OnPush
+ // https://github.com/angular/angular/issues/12313#issuecomment-444623173
+ changeDetector = fixture.componentRef.injector.get(ChangeDetectorRef);
+ poolDetailsComponent = fixture.componentInstance;
+ poolDetailsComponent.selection = undefined;
+ poolDetailsComponent.permissions = new Permissions({
+ grafana: ['read']
+ });
+ updatePoolSelection({ tiers: [0], pool: 0, pool_name: 'micro_pool' });
+ });
+
+ it('should create', () => {
+ expect(poolDetailsComponent).toBeTruthy();
+ });
+
+ describe('Pool details tabset', () => {
+ it('should recognize a tabset child', () => {
+ detectChanges();
+ const ngbNav = TabHelper.getNgbNav(fixture);
+ expect(ngbNav).toBeDefined();
+ });
+
+ it('should not change the tabs active status when selection is the same as before', () => {
+ const tabs = TabHelper.getNgbNavItems(fixture);
+ expect(tabs[0].active).toBeTruthy();
+ currentPoolUpdate();
+ expect(tabs[0].active).toBeTruthy();
+
+ const ngbNav = TabHelper.getNgbNav(fixture);
+ ngbNav.select(tabs[1].id);
+ expect(tabs[1].active).toBeTruthy();
+ currentPoolUpdate();
+ expect(tabs[1].active).toBeTruthy();
+ });
+
+ it('should filter out cdExecuting, cdIsBinary and all stats', () => {
+ updatePoolSelection({
+ prop1: 1,
+ cdIsBinary: true,
+ prop2: 2,
+ cdExecuting: true,
+ prop3: 3,
+ stats: { anyStat: 3, otherStat: [1, 2, 3] }
+ });
+ const expectedPool = { prop1: 1, prop2: 2, prop3: 3 };
+ expect(poolDetailsComponent.poolDetails).toEqual(expectedPool);
+ });
+
+ describe('Updates of shown data', () => {
+ const expectedChange = (
+ expected: {
+ selectedPoolConfiguration?: object;
+ poolDetails?: object;
+ },
+ newSelection: object,
+ doesNotEqualOld = true
+ ) => {
+ const getData = () => {
+ const data = {};
+ Object.keys(expected).forEach((key) => (data[key] = poolDetailsComponent[key]));
+ return data;
+ };
+ const oldData = getData();
+ updatePoolSelection(newSelection);
+ const newData = getData();
+ if (doesNotEqualOld) {
+ expect(expected).not.toEqual(oldData);
+ } else {
+ expect(expected).toEqual(oldData);
+ }
+ expect(expected).toEqual(newData);
+ };
+
+ it('should update shown data on change', () => {
+ expectedChange(
+ {
+ poolDetails: {
+ pg_num: 256,
+ pg_num_target: 256,
+ pg_placement_num: 256,
+ pg_placement_num_target: 256,
+ pool: 2,
+ pool_name: 'somePool',
+ type: 'replicated',
+ size: 3
+ }
+ },
+ Mocks.getPool('somePool', 2)
+ );
+ });
+
+ it('should not update shown data if no detail has changed on pool refresh', () => {
+ expectedChange(
+ {
+ poolDetails: {
+ pool: 0,
+ pool_name: 'micro_pool',
+ tiers: [0]
+ }
+ },
+ poolDetailsComponent.selection,
+ false
+ );
+ });
+
+ it('should show "Cache Tiers Details" tab if selected pool has "tiers"', () => {
+ const tabsItem = TabHelper.getNgbNavItems(fixture);
+ const tabsText = TabHelper.getTextContents(fixture);
+ expect(poolDetailsComponent.selection['tiers'].length).toBe(1);
+ expect(tabsItem.length).toBe(3);
+ expect(tabsText[2]).toBe('Cache Tiers Details');
+ expect(tabsItem[0].active).toBeTruthy();
+ });
+
+ it('should not show "Cache Tiers Details" tab if selected pool has no "tiers"', () => {
+ updatePoolSelection({ tiers: [] });
+ const tabs = TabHelper.getNgbNavItems(fixture);
+ expect(tabs.length).toEqual(2);
+ expect(tabs[0].active).toBeTruthy();
+ });
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.ts
new file mode 100644
index 000000000..21f3ae971
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.ts
@@ -0,0 +1,80 @@
+import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';
+
+import _ from 'lodash';
+
+import { PoolService } from '~/app/shared/api/pool.service';
+import { CdHelperClass } from '~/app/shared/classes/cd-helper.class';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { RbdConfigurationEntry } from '~/app/shared/models/configuration';
+import { Permissions } from '~/app/shared/models/permissions';
+
+@Component({
+ selector: 'cd-pool-details',
+ templateUrl: './pool-details.component.html',
+ styleUrls: ['./pool-details.component.scss'],
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class PoolDetailsComponent implements OnChanges {
+ @Input()
+ cacheTiers: any[];
+ @Input()
+ permissions: Permissions;
+ @Input()
+ selection: any;
+
+ cacheTierColumns: Array<CdTableColumn> = [];
+ // 'stats' won't be shown as the pure stat numbers won't tell the user much,
+ // if they are not converted or used in a chart (like the ones available in the pool listing)
+ omittedPoolAttributes = ['cdExecuting', 'cdIsBinary', 'stats'];
+
+ poolDetails: object;
+ selectedPoolConfiguration: RbdConfigurationEntry[];
+
+ constructor(private poolService: PoolService) {
+ this.cacheTierColumns = [
+ {
+ prop: 'pool_name',
+ name: $localize`Name`,
+ flexGrow: 3
+ },
+ {
+ prop: 'cache_mode',
+ name: $localize`Cache Mode`,
+ flexGrow: 2
+ },
+ {
+ prop: 'cache_min_evict_age',
+ name: $localize`Min Evict Age`,
+ flexGrow: 2
+ },
+ {
+ prop: 'cache_min_flush_age',
+ name: $localize`Min Flush Age`,
+ flexGrow: 2
+ },
+ {
+ prop: 'target_max_bytes',
+ name: $localize`Target Max Bytes`,
+ flexGrow: 2
+ },
+ {
+ prop: 'target_max_objects',
+ name: $localize`Target Max Objects`,
+ flexGrow: 2
+ }
+ ];
+ }
+
+ ngOnChanges() {
+ if (this.selection) {
+ this.poolService
+ .getConfiguration(this.selection.pool_name)
+ .subscribe((poolConf: RbdConfigurationEntry[]) => {
+ CdHelperClass.updateChanged(this, { selectedPoolConfiguration: poolConf });
+ });
+ CdHelperClass.updateChanged(this, {
+ poolDetails: _.omit(this.selection, this.omittedPoolAttributes)
+ });
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form-data.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form-data.ts
new file mode 100644
index 000000000..2c5dc57eb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form-data.ts
@@ -0,0 +1,37 @@
+import { Validators } from '@angular/forms';
+
+import { SelectMessages } from '~/app/shared/components/select/select-messages.model';
+import { Pool } from '../pool';
+
+export class PoolFormData {
+ poolTypes: string[];
+ erasureInfo = false;
+ crushInfo = false;
+ applications: any;
+
+ constructor() {
+ this.poolTypes = ['erasure', 'replicated'];
+ this.applications = {
+ selected: [],
+ default: ['cephfs', 'rbd', 'rgw'],
+ available: [], // Filled during runtime
+ validators: [Validators.pattern('[A-Za-z0-9_]+'), Validators.maxLength(128)],
+ messages: new SelectMessages({
+ empty: $localize`No applications added`,
+ selectionLimit: {
+ text: $localize`Applications limit reached`,
+ tooltip: $localize`A pool can only have up to four applications definitions.`
+ },
+ customValidations: {
+ pattern: $localize`Allowed characters '_a-zA-Z0-9'`,
+ maxlength: $localize`Maximum length is 128 characters`
+ },
+ filter: $localize`Filter or add applications'`,
+ add: $localize`Add application`
+ })
+ };
+ }
+
+ pgs = 1;
+ pool: Pool; // Only available during edit mode
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.html
new file mode 100644
index 000000000..07a26f9eb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.html
@@ -0,0 +1,609 @@
+<div class="cd-col-form"
+ *cdFormLoading="loading">
+ <form name="form"
+ #formDir="ngForm"
+ [formGroup]="form"
+ novalidate>
+ <div class="card">
+ <div i18n="form title|Example: Create Pool@@formTitle"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
+
+ <div class="card-body">
+ <!-- Name -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="name"
+ i18n>Name</label>
+ <div class="cd-col-form-input">
+ <input id="name"
+ name="name"
+ type="text"
+ class="form-control"
+ placeholder="Name..."
+ i18n-placeholder
+ formControlName="name"
+ autofocus>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('name', formDir, 'required')"
+ i18n>This field is required!</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('name', formDir, 'uniqueName')"
+ i18n>The chosen Ceph pool name is already in use.</span>
+ <span *ngIf="form.showError('name', formDir, 'rbdPool')"
+ class="invalid-feedback"
+ i18n>It's not possible to create an RBD pool with '/' in the name.
+ Please change the name or remove 'rbd' from the applications list.</span>
+ <span *ngIf="form.showError('name', formDir, 'pattern')"
+ class="invalid-feedback"
+ i18n>Pool name can only contain letters, numbers, '.', '-', '_' or '/'.</span>
+ </div>
+ </div>
+
+ <!-- Pool type selection -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="poolType"
+ i18n>Pool type</label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ id="poolType"
+ formControlName="poolType"
+ name="poolType">
+ <option ngValue=""
+ i18n>-- Select a pool type --</option>
+ <option *ngFor="let poolType of data.poolTypes"
+ [value]="poolType">
+ {{ poolType }}
+ </option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('poolType', formDir, 'required')"
+ i18n>This field is required!</span>
+ </div>
+ </div>
+
+ <div *ngIf="isReplicated || isErasure">
+ <!-- PG Autoscale Mode -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="pgAutoscaleMode">PG Autoscale</label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ id="pgAutoscaleMode"
+ name="pgAutoscaleMode"
+ formControlName="pgAutoscaleMode">
+ <option *ngFor="let mode of pgAutoscaleModes"
+ [value]="mode">
+ {{ mode }}
+ </option>
+ </select>
+ </div>
+ </div>
+
+ <!-- Pg number -->
+ <div class="form-group row"
+ *ngIf="form.getValue('pgAutoscaleMode') !== 'on'">
+ <label class="cd-col-form-label required"
+ for="pgNum"
+ i18n>Placement groups</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ id="pgNum"
+ name="pgNum"
+ formControlName="pgNum"
+ min="1"
+ type="number"
+ (focus)="externalPgChange = false"
+ (blur)="alignPgs()"
+ required>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('pgNum', formDir, 'required')"
+ i18n>This field is required!</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('pgNum', formDir, 'min')"
+ i18n>At least one placement group is needed!</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('pgNum', formDir, '34')"
+ i18n>Your cluster can't handle this many PGs. Please recalculate the PG amount needed.</span>
+ <span class="form-text text-muted">
+ <cd-doc section="pgs"
+ docText="Calculation help"
+ i18n-docText></cd-doc>
+ </span>
+ <span class="form-text text-muted"
+ *ngIf="externalPgChange"
+ i18n>The current PGs settings were calculated for you, you
+ should make sure the values suit your needs before submit.</span>
+ </div>
+ </div>
+
+ <!-- Replica Size -->
+ <div class="form-group row"
+ *ngIf="isReplicated">
+ <label class="cd-col-form-label required"
+ for="size"
+ i18n>Replicated size</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ id="size"
+ [max]="getMaxSize()"
+ [min]="getMinSize()"
+ name="size"
+ type="number"
+ formControlName="size">
+ <span class="invalid-feedback"
+ *ngIf="form.showError('size', formDir)">
+ <ul class="list-inline">
+ <li i18n>Minimum: {{ getMinSize() }}</li>
+ <li i18n>Maximum: {{ getMaxSize() }}</li>
+ </ul>
+ </span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('size', formDir)"
+ i18n>The size specified is out of range. A value from
+ {{ getMinSize() }} to {{ getMaxSize() }} is usable.</span>
+ <span class="text-warning-dark"
+ *ngIf="form.getValue('size') === 1"
+ i18n>A size of 1 will not create a replication of the
+ object. The 'Replicated size' includes the object itself.</span>
+ </div>
+ </div>
+
+ <!-- Flags -->
+ <div class="form-group row"
+ *ngIf="info.is_all_bluestore && isErasure">
+ <label i18n
+ class="cd-col-form-label">Flags</label>
+ <div class="cd-col-form-input">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ id="ec-overwrites"
+ formControlName="ecOverwrites">
+ <label class="custom-control-label"
+ for="ec-overwrites"
+ i18n>EC Overwrites</label>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ <!-- Applications -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="applications">Applications</label>
+ <div class="cd-col-form-input">
+ <cd-select-badges id="applications"
+ [customBadges]="true"
+ [customBadgeValidators]="data.applications.validators"
+ [messages]="data.applications.messages"
+ [data]="data.applications.selected"
+ [options]="data.applications.available"
+ [selectionLimit]="4"
+ (selection)="appSelection()">
+ </cd-select-badges>
+ </div>
+ </div>
+
+ <!-- CRUSH -->
+ <div *ngIf="isErasure || isReplicated">
+
+ <legend i18n>CRUSH</legend>
+
+ <!-- Erasure Profile select -->
+ <div class="form-group row"
+ *ngIf="isErasure">
+ <label i18n
+ class="cd-col-form-label"
+ for="erasureProfile">Erasure code profile</label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <select class="form-control"
+ id="erasureProfile"
+ name="erasureProfile"
+ formControlName="erasureProfile">
+ <option *ngIf="!ecProfiles"
+ ngValue=""
+ i18n>Loading...</option>
+ <option *ngIf="ecProfiles && ecProfiles.length === 0"
+ [ngValue]="null"
+ i18n>-- No erasure code profile available --</option>
+ <option *ngIf="ecProfiles && ecProfiles.length > 0"
+ [ngValue]="null"
+ i18n>-- Select an erasure code profile --</option>
+ <option *ngFor="let ecp of ecProfiles"
+ [ngValue]="ecp">
+ {{ ecp.name }}
+ </option>
+ </select>
+ <span class="input-group-append">
+ <button class="btn btn-light"
+ [ngClass]="{'active': data.erasureInfo}"
+ id="ecp-info-button"
+ type="button"
+ (click)="data.erasureInfo = !data.erasureInfo">
+ <i [ngClass]="[icons.questionCircle]"
+ aria-hidden="true"></i>
+ </button>
+ <button class="btn btn-light"
+ type="button"
+ *ngIf="!editing"
+ (click)="addErasureCodeProfile()">
+ <i [ngClass]="[icons.add]"
+ aria-hidden="true"></i>
+ </button>
+ <button class="btn btn-light"
+ type="button"
+ *ngIf="!editing"
+ ngbTooltip="This profile can't be deleted as it is in use."
+ i18n-ngbTooltip
+ triggers="manual"
+ #ecpDeletionBtn="ngbTooltip"
+ (click)="deleteErasureCodeProfile()">
+ <i [ngClass]="[icons.trash]"
+ aria-hidden="true"></i>
+ </button>
+ </span>
+ </div>
+ <span class="form-text text-muted"
+ id="ecp-info-block"
+ *ngIf="data.erasureInfo && form.getValue('erasureProfile')">
+ <ul ngbNav
+ #ecpInfoTabs="ngbNav"
+ class="nav-tabs">
+ <li ngbNavItem="ecp-info">
+ <a ngbNavLink
+ i18n>Profile</a>
+ <ng-template ngbNavContent>
+ <cd-table-key-value [renderObjects]="true"
+ [hideKeys]="['name']"
+ [data]="form.getValue('erasureProfile')"
+ [autoReload]="false">
+ </cd-table-key-value>
+ </ng-template>
+ </li>
+ <li ngbNavItem="used-by-pools">
+ <a ngbNavLink
+ i18n>Used by pools</a>
+ <ng-template ngbNavContent>
+ <ng-template #ecpIsNotUsed>
+ <span i18n>Profile is not in use.</span>
+ </ng-template>
+ <ul *ngIf="ecpUsage; else ecpIsNotUsed">
+ <li *ngFor="let pool of ecpUsage">
+ {{ pool }}
+ </li>
+ </ul>
+ </ng-template>
+ </li>
+ </ul>
+
+ <div [ngbNavOutlet]="ecpInfoTabs"></div>
+ </span>
+ </div>
+ </div>
+
+ <!-- Crush ruleset selection -->
+ <div class="form-group row"
+ *ngIf="isErasure && !editing">
+ <label class="cd-col-form-label"
+ for="crushRule"
+ i18n>Crush ruleset</label>
+ <div class="cd-col-form-input">
+ <span class="form-text text-muted"
+ i18n>A new crush ruleset will be implicitly created.</span>
+ </div>
+ </div>
+ <div class="form-group row"
+ *ngIf="isReplicated || editing">
+ <label class="cd-col-form-label"
+ for="crushRule"
+ i18n>Crush ruleset</label>
+ <div class="cd-col-form-input">
+ <ng-template #noRules>
+ <span class="form-text text-muted">
+ <span i18n>There are no rules.</span>&nbsp;
+ </span>
+ </ng-template>
+ <div *ngIf="current.rules.length > 0; else noRules">
+ <div class="input-group">
+ <select class="form-control"
+ id="crushRule"
+ formControlName="crushRule"
+ name="crushSet">
+ <option [ngValue]="null"
+ i18n>-- Select a crush rule --</option>
+ <option *ngFor="let rule of current.rules"
+ [ngValue]="rule">
+ {{ rule.rule_name }}
+ </option>
+ </select>
+ <span class="input-group-append">
+ <button class="btn btn-light"
+ [ngClass]="{'active': data.crushInfo}"
+ id="crush-info-button"
+ type="button"
+ ngbTooltip="Placement and
+ replication strategies or distribution policies that allow to
+ specify how CRUSH places data replicas."
+ i18n-ngbTooltip
+ (click)="data.crushInfo = !data.crushInfo">
+ <i [ngClass]="[icons.questionCircle]"
+ aria-hidden="true"></i>
+ </button>
+ <button class="btn btn-light"
+ type="button"
+ *ngIf="isReplicated && !editing"
+ (click)="addCrushRule()">
+ <i [ngClass]="[icons.add]"
+ aria-hidden="true"></i>
+ </button>
+ <button class="btn btn-light"
+ *ngIf="isReplicated && !editing"
+ type="button"
+ ngbTooltip="This rule can't be deleted as it is in use."
+ i18n-ngbTooltip
+ triggers="manual"
+ #crushDeletionBtn="ngbTooltip"
+ (click)="deleteCrushRule()">
+ <i [ngClass]="[icons.trash]"
+ aria-hidden="true"></i>
+ </button>
+ </span>
+ </div>
+
+ <div class="form-text text-muted"
+ id="crush-info-block"
+ *ngIf="data.crushInfo && form.getValue('crushRule')">
+ <ul ngbNav
+ #crushInfoTabs="ngbNav"
+ class="nav-tabs">
+ <li ngbNavItem="crush-rule-info">
+ <a ngbNavLink
+ i18n>Crush rule</a>
+ <ng-template ngbNavContent>
+ <cd-table-key-value [renderObjects]="false"
+ [hideKeys]="['steps', 'ruleset', 'type', 'rule_name']"
+ [data]="form.getValue('crushRule')"
+ [autoReload]="false">
+ </cd-table-key-value>
+ </ng-template>
+ </li>
+ <li ngbNavItem="crush-rule-steps">
+ <a ngbNavLink
+ i18n>Crush steps</a>
+ <ng-template ngbNavContent>
+ <ol>
+ <li *ngFor="let step of form.get('crushRule').value.steps">
+ {{ describeCrushStep(step) }}
+ </li>
+ </ol>
+ </ng-template>
+ </li>
+ <li ngbNavItem="used-by-pools">
+ <a ngbNavLink
+ i18n>Used by pools</a>
+ <ng-template ngbNavContent>
+
+ <ng-template #ruleIsNotUsed>
+ <span i18n>Rule is not in use.</span>
+ </ng-template>
+ <ul *ngIf="crushUsage; else ruleIsNotUsed">
+ <li *ngFor="let pool of crushUsage">
+ {{ pool }}
+ </li>
+ </ul>
+ </ng-template>
+ </li>
+ </ul>
+
+ <div [ngbNavOutlet]="crushInfoTabs"></div>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('crushRule', formDir, 'required')"
+ i18n>This field is required!</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('crushRule', formDir, 'tooFewOsds')"
+ i18n>The rule can't be used in the current cluster as it has
+ too few OSDs to meet the minimum required OSD by this rule.</span>
+ </div>
+ </div>
+ </div>
+
+ </div>
+
+ <!-- Compression -->
+ <div *ngIf="info.is_all_bluestore"
+ formGroupName="compression">
+ <legend i18n>Compression</legend>
+
+ <!-- Compression Mode -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="mode">Mode</label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ id="mode"
+ name="mode"
+ formControlName="mode">
+ <option *ngFor="let mode of info.compression_modes"
+ [value]="mode">
+ {{ mode }}
+ </option>
+ </select>
+ </div>
+ </div>
+ <div *ngIf="hasCompressionEnabled()">
+ <!-- Compression algorithm selection -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="algorithm">Algorithm</label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ id="algorithm"
+ name="algorithm"
+ formControlName="algorithm">
+ <option *ngIf="!info.compression_algorithms"
+ ngValue=""
+ i18n>Loading...</option>
+ <option *ngIf="info.compression_algorithms && info.compression_algorithms.length === 0"
+ i18n
+ ngValue="">-- No erasure compression algorithm available --</option>
+ <option *ngFor="let algorithm of info.compression_algorithms"
+ [value]="algorithm">
+ {{ algorithm }}
+ </option>
+ </select>
+ </div>
+ </div>
+
+ <!-- Compression min blob size -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="minBlobSize">Minimum blob size</label>
+ <div class="cd-col-form-input">
+ <input id="minBlobSize"
+ name="minBlobSize"
+ formControlName="minBlobSize"
+ type="text"
+ min="0"
+ class="form-control"
+ i18n-placeholder
+ placeholder="e.g., 128KiB"
+ defaultUnit="KiB"
+ cdDimlessBinary>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('minBlobSize', formDir, 'min')"
+ i18n>Value should be greater than 0</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('minBlobSize', formDir, 'maximum')"
+ i18n>Value should be less than the maximum blob size</span>
+ </div>
+ </div>
+
+ <!-- Compression max blob size -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="maxBlobSize">Maximum blob size</label>
+ <div class="cd-col-form-input">
+ <input id="maxBlobSize"
+ type="text"
+ min="0"
+ formControlName="maxBlobSize"
+ class="form-control"
+ i18n-placeholder
+ placeholder="e.g., 512KiB"
+ defaultUnit="KiB"
+ cdDimlessBinary>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('maxBlobSize', formDir, 'min')"
+ i18n>Value should be greater than 0</span>
+ <span class="invalid-feedback"
+ *ngIf="form.showError('maxBlobSize', formDir, 'minimum')"
+ i18n>Value should be greater than the minimum blob size</span>
+ </div>
+ </div>
+
+ <!-- Compression ratio -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="ratio">Ratio</label>
+ <div class="cd-col-form-input">
+ <input id="ratio"
+ name="ratio"
+ formControlName="ratio"
+ type="number"
+ min="0"
+ max="1"
+ step="0.1"
+ class="form-control"
+ i18n-placeholder
+ placeholder="Compression ratio">
+ <span class="invalid-feedback"
+ *ngIf="form.showError('ratio', formDir, 'min') || form.showError('ratio', formDir, 'max')"
+ i18n>Value should be between 0.0 and 1.0</span>
+ </div>
+ </div>
+
+ </div>
+ </div>
+
+ <!-- Quotas -->
+ <div>
+ <legend i18n>Quotas</legend>
+
+ <!-- Max Bytes -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="max_bytes">
+ <ng-container i18n>Max bytes</ng-container>
+ <cd-helper>
+ <span i18n>Leave it blank or specify 0 to disable this quota.</span>
+ <br>
+ <span i18n>A valid quota should be greater than 0.</span>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ id="max_bytes"
+ name="max_bytes"
+ type="text"
+ formControlName="max_bytes"
+ i18n-placeholder
+ placeholder="e.g., 10GiB"
+ defaultUnit="GiB"
+ cdDimlessBinary>
+ </div>
+ </div>
+
+ <!-- Max Objects -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="max_objects">
+ <ng-container i18n>Max objects</ng-container>
+ <cd-helper>
+ <span i18n>Leave it blank or specify 0 to disable this quota.</span>
+ <br>
+ <span i18n>A valid quota should be greater than 0.</span>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ id="max_objects"
+ min="0"
+ name="max_objects"
+ type="number"
+ formControlName="max_objects">
+ <span class="invalid-feedback"
+ *ngIf="form.showError('max_objects', formDir, 'min')"
+ i18n>The value should be greater or equal to 0</span>
+ </div>
+ </div>
+ </div>
+
+ <!-- Pool configuration -->
+ <div [hidden]="isErasure || data.applications.selected.indexOf('rbd') === -1">
+ <cd-rbd-configuration-form [form]="form"
+ [initializeData]="initializeConfigData"
+ (changes)="currentConfigurationValues = $event()">
+ </cd-rbd-configuration-form>
+ </div>
+ </div>
+ <div class="card-footer">
+ <cd-form-button-panel (submitActionEvent)="submit()"
+ [form]="form"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
+ wrappingClass="text-right"></cd-form-button-panel>
+ </div>
+
+ </div>
+
+ </form>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.spec.ts
new file mode 100644
index 000000000..1d58a1778
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.spec.ts
@@ -0,0 +1,1466 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { AbstractControl } from '@angular/forms';
+import { By } from '@angular/platform-browser';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { ActivatedRoute, Router, Routes } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import {
+ NgbActiveModal,
+ NgbModalModule,
+ NgbModalRef,
+ NgbNavModule
+} from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { DashboardNotFoundError } from '~/app/core/error/error';
+import { ErrorComponent } from '~/app/core/error/error.component';
+import { CrushRuleService } from '~/app/shared/api/crush-rule.service';
+import { ErasureCodeProfileService } from '~/app/shared/api/erasure-code-profile.service';
+import { PoolService } from '~/app/shared/api/pool.service';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { SelectBadgesComponent } from '~/app/shared/components/select-badges/select-badges.component';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { ErasureCodeProfile } from '~/app/shared/models/erasure-code-profile';
+import { Permission } from '~/app/shared/models/permissions';
+import { PoolFormInfo } from '~/app/shared/models/pool-form-info';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import {
+ configureTestBed,
+ FixtureHelper,
+ FormHelper,
+ Mocks,
+ modalServiceShow
+} from '~/testing/unit-test-helper';
+import { Pool } from '../pool';
+import { PoolModule } from '../pool.module';
+import { PoolFormComponent } from './pool-form.component';
+
+describe('PoolFormComponent', () => {
+ let OSDS = 15;
+ let formHelper: FormHelper;
+ let fixtureHelper: FixtureHelper;
+ let component: PoolFormComponent;
+ let fixture: ComponentFixture<PoolFormComponent>;
+ let poolService: PoolService;
+ let form: CdFormGroup;
+ let router: Router;
+ let ecpService: ErasureCodeProfileService;
+ let crushRuleService: CrushRuleService;
+ let poolPermissions: Permission;
+ let authStorageService: AuthStorageService;
+
+ const setPgNum = (pgs: number): AbstractControl => {
+ const control = formHelper.setValue('pgNum', pgs);
+ fixture.debugElement.query(By.css('#pgNum')).nativeElement.dispatchEvent(new Event('blur'));
+ return control;
+ };
+
+ const testPgUpdate = (pgs: number, jump: number, returnValue: number) => {
+ if (pgs) {
+ setPgNum(pgs);
+ }
+ if (jump) {
+ setPgNum(form.getValue('pgNum') + jump);
+ }
+ expect(form.getValue('pgNum')).toBe(returnValue);
+ };
+
+ const expectValidSubmit = (
+ pool: any,
+ taskName = 'pool/create',
+ poolServiceMethod: 'create' | 'update' = 'create'
+ ) => {
+ spyOn(poolService, poolServiceMethod).and.stub();
+ const taskWrapper = TestBed.inject(TaskWrapperService);
+ spyOn(taskWrapper, 'wrapTaskAroundCall').and.callThrough();
+ component.submit();
+ expect(poolService[poolServiceMethod]).toHaveBeenCalledWith(pool);
+ expect(taskWrapper.wrapTaskAroundCall).toHaveBeenCalledWith({
+ task: {
+ name: taskName,
+ metadata: {
+ pool_name: pool.pool
+ }
+ },
+ call: undefined // because of stub
+ });
+ };
+
+ let infoReturn: PoolFormInfo;
+ const setInfo = () => {
+ const ecp1 = new ErasureCodeProfile();
+ ecp1.name = 'ecp1';
+ infoReturn = {
+ pool_names: ['someExistingPoolName'],
+ osd_count: OSDS,
+ is_all_bluestore: true,
+ bluestore_compression_algorithm: 'snappy',
+ compression_algorithms: ['snappy'],
+ compression_modes: ['none', 'passive'],
+ crush_rules_replicated: [
+ Mocks.getCrushRule({ id: 0, min: 2, max: 4, name: 'rep1', type: 'replicated' }),
+ Mocks.getCrushRule({ id: 1, min: 3, max: 18, name: 'rep2', type: 'replicated' }),
+ Mocks.getCrushRule({ id: 2, min: 1, max: 9, name: 'used_rule', type: 'replicated' })
+ ],
+ crush_rules_erasure: [
+ Mocks.getCrushRule({ id: 3, min: 1, max: 1, name: 'ecp1', type: 'erasure' })
+ ],
+ erasure_code_profiles: [ecp1],
+ pg_autoscale_default_mode: 'off',
+ pg_autoscale_modes: ['off', 'warn', 'on'],
+ used_rules: {
+ used_rule: ['some.pool.uses.it']
+ },
+ used_profiles: {
+ ecp1: ['some.other.pool.uses.it']
+ },
+ nodes: Mocks.generateSimpleCrushMap(3, 5)
+ };
+ };
+
+ const setUpPoolComponent = () => {
+ fixture = TestBed.createComponent(PoolFormComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+
+ fixtureHelper = new FixtureHelper(fixture);
+ form = component.form;
+ formHelper = new FormHelper(form);
+ };
+
+ const routes: Routes = [{ path: '404', component: ErrorComponent }];
+
+ configureTestBed(
+ {
+ declarations: [ErrorComponent],
+ imports: [
+ BrowserAnimationsModule,
+ HttpClientTestingModule,
+ RouterTestingModule.withRoutes(routes),
+ ToastrModule.forRoot(),
+ NgbNavModule,
+ PoolModule,
+ SharedModule,
+ NgbModalModule
+ ],
+ providers: [
+ ErasureCodeProfileService,
+ NgbActiveModal,
+ SelectBadgesComponent,
+ { provide: ActivatedRoute, useValue: { params: of({ name: 'somePoolName' }) } }
+ ]
+ },
+ [CriticalConfirmationModalComponent]
+ );
+
+ let navigationSpy: jasmine.Spy;
+
+ beforeEach(() => {
+ poolService = TestBed.inject(PoolService);
+ setInfo();
+ spyOn(poolService, 'getInfo').and.callFake(() => of(infoReturn));
+
+ ecpService = TestBed.inject(ErasureCodeProfileService);
+ crushRuleService = TestBed.inject(CrushRuleService);
+
+ router = TestBed.inject(Router);
+ navigationSpy = spyOn(router, 'navigate').and.stub();
+ authStorageService = TestBed.inject(AuthStorageService);
+ spyOn(authStorageService, 'getPermissions').and.callFake(() => ({
+ pool: poolPermissions
+ }));
+ poolPermissions = new Permission(['update', 'delete', 'read', 'create']);
+ setUpPoolComponent();
+
+ component.loadingReady();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('throws error for not allowed users', () => {
+ const expectError = (redirected: boolean) => {
+ navigationSpy.calls.reset();
+ if (redirected) {
+ expect(() => component.authenticate()).toThrowError(DashboardNotFoundError);
+ } else {
+ expect(() => component.authenticate()).not.toThrowError();
+ }
+ };
+
+ beforeEach(() => {
+ poolPermissions = new Permission(['delete']);
+ });
+
+ it('navigates to Dashboard if not allowed', () => {
+ expect(() => component.authenticate()).toThrowError(DashboardNotFoundError);
+ });
+
+ it('throws error if user is not allowed', () => {
+ expectError(true);
+ poolPermissions.read = true;
+ expectError(true);
+ poolPermissions.delete = true;
+ expectError(true);
+ poolPermissions.update = true;
+ expectError(true);
+ component.editing = true;
+ poolPermissions.update = false;
+ poolPermissions.create = true;
+ expectError(true);
+ });
+
+ it('does not throw error for users with right permissions', () => {
+ poolPermissions.read = true;
+ poolPermissions.create = true;
+ expectError(false);
+ component.editing = true;
+ poolPermissions.update = true;
+ expectError(false);
+ poolPermissions.create = false;
+ expectError(false);
+ });
+ });
+
+ describe('pool form validation', () => {
+ beforeEach(() => {
+ fixture.detectChanges();
+ });
+
+ it('is invalid at the beginning all sub forms are valid', () => {
+ expect(form.valid).toBeFalsy();
+ ['name', 'poolType', 'pgNum'].forEach((name) => formHelper.expectError(name, 'required'));
+ ['size', 'crushRule', 'erasureProfile', 'ecOverwrites'].forEach((name) =>
+ formHelper.expectValid(name)
+ );
+ expect(component.form.get('compression').valid).toBeTruthy();
+ });
+
+ it('validates name', () => {
+ expect(component.editing).toBeFalsy();
+ formHelper.expectError('name', 'required');
+ formHelper.expectValidChange('name', 'some-name');
+ formHelper.expectValidChange('name', 'name/with/slash');
+ formHelper.expectErrorChange('name', 'someExistingPoolName', 'uniqueName');
+ formHelper.expectErrorChange('name', 'wrong format with spaces', 'pattern');
+ });
+
+ it('should validate with dots in pool name', () => {
+ formHelper.expectValidChange('name', 'pool.default.bar', true);
+ });
+
+ it('validates poolType', () => {
+ formHelper.expectError('poolType', 'required');
+ formHelper.expectValidChange('poolType', 'erasure');
+ formHelper.expectValidChange('poolType', 'replicated');
+ });
+
+ it('validates that pgNum is required creation mode', () => {
+ formHelper.expectError(form.get('pgNum'), 'required');
+ });
+
+ it('validates pgNum in edit mode', () => {
+ component.data.pool = new Pool('test');
+ component.data.pool.pg_num = 16;
+ component.editing = true;
+ component.ngOnInit(); // Switches form into edit mode
+ formHelper.setValue('poolType', 'erasure');
+ fixture.detectChanges();
+ formHelper.expectValid(setPgNum(8));
+ });
+
+ it('is valid if pgNum, poolType and name are valid', () => {
+ formHelper.setValue('name', 'some-name');
+ formHelper.setValue('poolType', 'erasure');
+ fixture.detectChanges();
+ setPgNum(1);
+ expect(form.valid).toBeTruthy();
+ });
+
+ it('validates crushRule with multiple crush rules', () => {
+ formHelper.expectValidChange('poolType', 'replicated');
+ form.get('crushRule').updateValueAndValidity();
+ formHelper.expectError('crushRule', 'required'); // As multiple rules exist
+ formHelper.expectErrorChange('crushRule', { min_size: 20 }, 'tooFewOsds');
+ });
+
+ it('validates crushRule with no crush rules', () => {
+ infoReturn.crush_rules_replicated = [];
+ setUpPoolComponent();
+ formHelper.expectValidChange('poolType', 'replicated');
+ formHelper.expectValid('crushRule');
+ });
+
+ it('validates size', () => {
+ component.info.nodes = Mocks.getCrushMap();
+ formHelper.setValue('poolType', 'replicated');
+ formHelper.expectValid('size');
+ formHelper.setValue('crushRule', Mocks.getCrushRule({ min: 2, max: 6 })); // 3 OSDs usable
+ formHelper.expectErrorChange('size', 1, 'min');
+ formHelper.expectErrorChange('size', 4, 'max'); // More than usable
+ formHelper.expectValidChange('size', 3);
+
+ formHelper.setValue(
+ 'crushRule',
+ Mocks.getCrushRule({ min: 1, max: 2, failureDomain: 'osd-rack' }) // 4 OSDs usable
+ );
+ formHelper.expectErrorChange('size', 4, 'max'); // More than rule allows
+ formHelper.expectValidChange('size', 2);
+ });
+
+ it('validates if warning is displayed when size is 1', () => {
+ formHelper.setValue('poolType', 'replicated');
+ formHelper.expectValid('size');
+
+ formHelper.setValue('size', 1, true);
+ expect(fixtureHelper.getElementByCss('#size ~ .text-warning-dark')).toBeTruthy();
+
+ formHelper.setValue('size', 2, true);
+ expect(fixtureHelper.getElementByCss('#size ~ .text-warning-dark')).toBeFalsy();
+ });
+
+ it('validates compression mode default value', () => {
+ expect(form.getValue('mode')).toBe('none');
+ });
+
+ it('validate quotas', () => {
+ formHelper.expectValid('max_bytes');
+ formHelper.expectValid('max_objects');
+ formHelper.expectValidChange('max_bytes', '10 Gib');
+ formHelper.expectValidChange('max_bytes', '');
+ formHelper.expectValidChange('max_objects', '');
+ formHelper.expectErrorChange('max_objects', -1, 'min');
+ });
+
+ describe('compression form', () => {
+ beforeEach(() => {
+ formHelper.setValue('poolType', 'replicated');
+ formHelper.setValue('mode', 'passive');
+ });
+
+ it('is valid', () => {
+ expect(component.form.get('compression').valid).toBeTruthy();
+ });
+
+ it('validates minBlobSize to be only valid between 0 and maxBlobSize', () => {
+ formHelper.expectErrorChange('minBlobSize', -1, 'min');
+ formHelper.expectValidChange('minBlobSize', 0);
+ formHelper.setValue('maxBlobSize', '2 KiB');
+ formHelper.expectErrorChange('minBlobSize', '3 KiB', 'maximum');
+ formHelper.expectValidChange('minBlobSize', '1.9 KiB');
+ });
+
+ it('validates minBlobSize converts numbers', () => {
+ const control = formHelper.setValue('minBlobSize', '1');
+ fixture.detectChanges();
+ formHelper.expectValid(control);
+ expect(control.value).toBe('1 KiB');
+ });
+
+ it('validates maxBlobSize to be only valid bigger than minBlobSize', () => {
+ formHelper.expectErrorChange('maxBlobSize', -1, 'min');
+ formHelper.setValue('minBlobSize', '1 KiB');
+ formHelper.expectErrorChange('maxBlobSize', '0.5 KiB', 'minimum');
+ formHelper.expectValidChange('maxBlobSize', '1.5 KiB');
+ });
+
+ it('s valid to only use one blob size', () => {
+ formHelper.expectValid(formHelper.setValue('minBlobSize', '1 KiB'));
+ formHelper.expectValid(formHelper.setValue('maxBlobSize', ''));
+ formHelper.expectValid(formHelper.setValue('minBlobSize', ''));
+ formHelper.expectValid(formHelper.setValue('maxBlobSize', '1 KiB'));
+ });
+
+ it('dismisses any size error if one of the blob sizes is changed into a valid state', () => {
+ const min = formHelper.setValue('minBlobSize', '10 KiB');
+ const max = formHelper.setValue('maxBlobSize', '1 KiB');
+ fixture.detectChanges();
+ max.setValue('');
+ formHelper.expectValid(min);
+ formHelper.expectValid(max);
+ max.setValue('1 KiB');
+ fixture.detectChanges();
+ min.setValue('0.5 KiB');
+ formHelper.expectValid(min);
+ formHelper.expectValid(max);
+ });
+
+ it('validates maxBlobSize converts numbers', () => {
+ const control = formHelper.setValue('maxBlobSize', '2');
+ fixture.detectChanges();
+ expect(control.value).toBe('2 KiB');
+ });
+
+ it('validates that odd size validator works as expected', () => {
+ const odd = (min: string, max: string) => component['oddBlobSize'](min, max);
+ expect(odd('10', '8')).toBe(true);
+ expect(odd('8', '-')).toBe(false);
+ expect(odd('8', '10')).toBe(false);
+ expect(odd(null, '8')).toBe(false);
+ expect(odd('10', '')).toBe(false);
+ expect(odd('10', null)).toBe(false);
+ expect(odd(null, null)).toBe(false);
+ });
+
+ it('validates ratio to be only valid between 0 and 1', () => {
+ formHelper.expectValid('ratio');
+ formHelper.expectErrorChange('ratio', -0.1, 'min');
+ formHelper.expectValidChange('ratio', 0);
+ formHelper.expectValidChange('ratio', 1);
+ formHelper.expectErrorChange('ratio', 1.1, 'max');
+ });
+ });
+
+ it('validates application metadata name', () => {
+ formHelper.setValue('poolType', 'replicated');
+ fixture.detectChanges();
+ const selectBadges = fixture.debugElement.query(By.directive(SelectBadgesComponent))
+ .componentInstance;
+ const control = selectBadges.cdSelect.filter;
+ formHelper.expectValid(control);
+ control.setValue('?');
+ formHelper.expectError(control, 'pattern');
+ control.setValue('Ab3_');
+ formHelper.expectValid(control);
+ control.setValue('a'.repeat(129));
+ formHelper.expectError(control, 'maxlength');
+ });
+ });
+
+ describe('pool type changes', () => {
+ beforeEach(() => {
+ component.ngOnInit();
+ });
+
+ it('should have a default replicated size of 3', () => {
+ formHelper.setValue('poolType', 'replicated');
+ expect(form.getValue('size')).toBe(3);
+ });
+
+ describe('replicatedRuleChange', () => {
+ beforeEach(() => {
+ formHelper.setValue('poolType', 'replicated');
+ formHelper.setValue('size', 99);
+ });
+
+ it('should not set size if a replicated pool is not set', () => {
+ formHelper.setValue('poolType', 'erasure');
+ expect(form.getValue('size')).toBe(99);
+ formHelper.setValue('crushRule', component.info.crush_rules_replicated[1]);
+ expect(form.getValue('size')).toBe(99);
+ });
+
+ it('should set size to maximum if size exceeds maximum', () => {
+ formHelper.setValue('crushRule', component.info.crush_rules_replicated[0]);
+ expect(form.getValue('size')).toBe(4);
+ });
+
+ it('should set size to minimum if size is lower than minimum', () => {
+ formHelper.setValue('size', -1);
+ formHelper.setValue('crushRule', component.info.crush_rules_replicated[0]);
+ expect(form.getValue('size')).toBe(2);
+ });
+ });
+
+ describe('rulesChange', () => {
+ it('has no effect if info is not there', () => {
+ delete component.info;
+ formHelper.setValue('poolType', 'replicated');
+ expect(component.current.rules).toEqual([]);
+ });
+
+ it('has no effect if pool type is not set', () => {
+ component['poolTypeChange']('');
+ expect(component.current.rules).toEqual([]);
+ });
+
+ it('shows all replicated rules when pool type is "replicated"', () => {
+ formHelper.setValue('poolType', 'replicated');
+ expect(component.current.rules).toEqual(component.info.crush_rules_replicated);
+ expect(component.current.rules.length).toBe(3);
+ });
+
+ it('shows all erasure code rules when pool type is "erasure"', () => {
+ formHelper.setValue('poolType', 'erasure');
+ expect(component.current.rules).toEqual(component.info.crush_rules_erasure);
+ expect(component.current.rules.length).toBe(1);
+ });
+
+ it('disables rule field if only one rule exists which is used in the disabled field', () => {
+ infoReturn.crush_rules_replicated = [
+ Mocks.getCrushRule({ id: 0, min: 2, max: 4, name: 'rep1', type: 'replicated' })
+ ];
+ setUpPoolComponent();
+ formHelper.setValue('poolType', 'replicated');
+ const control = form.get('crushRule');
+ expect(control.value).toEqual(component.info.crush_rules_replicated[0]);
+ expect(control.disabled).toBe(true);
+ });
+
+ it('does not select the first rule if more than one exist', () => {
+ formHelper.setValue('poolType', 'replicated');
+ const control = form.get('crushRule');
+ expect(control.value).toEqual(null);
+ expect(control.disabled).toBe(false);
+ });
+
+ it('changing between both pool types will not forget the crush rule selection', () => {
+ formHelper.setValue('poolType', 'replicated');
+ const control = form.get('crushRule');
+ const currentRule = component.info.crush_rules_replicated[0];
+ control.setValue(currentRule);
+ formHelper.setValue('poolType', 'erasure');
+ formHelper.setValue('poolType', 'replicated');
+ expect(control.value).toEqual(currentRule);
+ });
+ });
+ });
+
+ describe('getMaxSize and getMinSize', () => {
+ const setCrushRule = ({ min, max }: { min?: number; max?: number }) => {
+ formHelper.setValue('crushRule', Mocks.getCrushRule({ min, max }));
+ };
+
+ it('returns 0 if osd count is 0', () => {
+ component.info.osd_count = 0;
+ expect(component.getMinSize()).toBe(0);
+ expect(component.getMaxSize()).toBe(0);
+ });
+
+ it('returns 0 if info is not there', () => {
+ delete component.info;
+ expect(component.getMinSize()).toBe(0);
+ expect(component.getMaxSize()).toBe(0);
+ });
+
+ it('returns minimum and maximum of rule', () => {
+ setCrushRule({ min: 2, max: 6 });
+ expect(component.getMinSize()).toBe(2);
+ expect(component.getMaxSize()).toBe(6);
+ });
+
+ it('returns 1 as minimum and 3 as maximum if no crush rule is available', () => {
+ expect(component.getMinSize()).toBe(1);
+ expect(component.getMaxSize()).toBe(3);
+ });
+
+ it('returns the osd count as maximum if the rule maximum exceeds it', () => {
+ setCrushRule({ max: 100 });
+ expect(component.getMaxSize()).toBe(15);
+ });
+
+ it('should return the osd count as minimum if its lower the the rule minimum', () => {
+ setCrushRule({ min: 20 });
+ expect(component.getMinSize()).toBe(20);
+ const control = form.get('crushRule');
+ expect(control.invalid).toBe(true);
+ formHelper.expectError(control, 'tooFewOsds');
+ });
+
+ it('should get the right maximum if the device type is defined', () => {
+ formHelper.setValue(
+ 'crushRule',
+ Mocks.getCrushRule({ min: 1, max: 5, itemName: 'default~ssd' })
+ );
+ expect(form.getValue('crushRule').usable_size).toBe(5);
+ });
+ });
+
+ describe('application metadata', () => {
+ let selectBadges: SelectBadgesComponent;
+
+ const testAddApp = (app?: string, result?: string[]) => {
+ selectBadges.cdSelect.filter.setValue(app);
+ selectBadges.cdSelect.updateFilter();
+ selectBadges.cdSelect.selectOption();
+ expect(component.data.applications.selected).toEqual(result);
+ };
+
+ const testRemoveApp = (app: string, result: string[]) => {
+ selectBadges.cdSelect.removeItem(app);
+ expect(component.data.applications.selected).toEqual(result);
+ };
+
+ const setCurrentApps = (apps: string[]) => {
+ component.data.applications.selected = apps;
+ fixture.detectChanges();
+ selectBadges.cdSelect.ngOnInit();
+ return apps;
+ };
+
+ beforeEach(() => {
+ formHelper.setValue('poolType', 'replicated');
+ fixture.detectChanges();
+ selectBadges = fixture.debugElement.query(By.directive(SelectBadgesComponent))
+ .componentInstance;
+ });
+
+ it('adds all predefined and a custom applications to the application metadata array', () => {
+ testAddApp('g', ['rgw']);
+ testAddApp('b', ['rbd', 'rgw']);
+ testAddApp('c', ['cephfs', 'rbd', 'rgw']);
+ testAddApp('ownApp', ['cephfs', 'ownApp', 'rbd', 'rgw']);
+ });
+
+ it('only allows 4 apps to be added to the array', () => {
+ const apps = setCurrentApps(['d', 'c', 'b', 'a']);
+ testAddApp('e', apps);
+ });
+
+ it('can remove apps', () => {
+ setCurrentApps(['a', 'b', 'c', 'd']);
+ testRemoveApp('c', ['a', 'b', 'd']);
+ testRemoveApp('a', ['b', 'd']);
+ testRemoveApp('d', ['b']);
+ testRemoveApp('b', []);
+ });
+
+ it('does not remove any app that is not in the array', () => {
+ const apps = ['a', 'b', 'c', 'd'];
+ setCurrentApps(apps);
+ testRemoveApp('e', apps);
+ testRemoveApp('0', apps);
+ });
+ });
+
+ describe('pg number changes', () => {
+ beforeEach(() => {
+ formHelper.setValue('crushRule', {
+ min_size: 1,
+ max_size: 20
+ });
+ formHelper.setValue('poolType', 'erasure');
+ fixture.detectChanges();
+ setPgNum(256);
+ });
+
+ it('updates by value', () => {
+ testPgUpdate(10, undefined, 8);
+ testPgUpdate(22, undefined, 16);
+ testPgUpdate(26, undefined, 32);
+ testPgUpdate(200, undefined, 256);
+ testPgUpdate(300, undefined, 256);
+ testPgUpdate(350, undefined, 256);
+ });
+
+ it('updates by jump -> a magnitude of the power of 2', () => {
+ testPgUpdate(undefined, 1, 512);
+ testPgUpdate(undefined, -1, 256);
+ });
+
+ it('returns 1 as minimum for false numbers', () => {
+ testPgUpdate(-26, undefined, 1);
+ testPgUpdate(0, undefined, 1);
+ testPgUpdate(0, -1, 1);
+ testPgUpdate(undefined, -20, 1);
+ });
+
+ it('changes the value and than jumps', () => {
+ testPgUpdate(230, 1, 512);
+ testPgUpdate(3500, -1, 2048);
+ });
+
+ describe('pg power jump', () => {
+ it('should jump correctly at the beginning', () => {
+ testPgUpdate(1, -1, 1);
+ testPgUpdate(1, 1, 2);
+ testPgUpdate(2, -1, 1);
+ testPgUpdate(2, 1, 4);
+ testPgUpdate(4, -1, 2);
+ testPgUpdate(4, 1, 8);
+ testPgUpdate(4, 1, 8);
+ });
+
+ it('increments pg power if difference to the current number is 1', () => {
+ testPgUpdate(undefined, 1, 512);
+ testPgUpdate(undefined, 1, 1024);
+ testPgUpdate(undefined, 1, 2048);
+ testPgUpdate(undefined, 1, 4096);
+ });
+
+ it('decrements pg power if difference to the current number is -1', () => {
+ testPgUpdate(undefined, -1, 128);
+ testPgUpdate(undefined, -1, 64);
+ testPgUpdate(undefined, -1, 32);
+ testPgUpdate(undefined, -1, 16);
+ testPgUpdate(undefined, -1, 8);
+ });
+ });
+
+ describe('pgCalc', () => {
+ const PGS = 1;
+ OSDS = 8;
+
+ const getValidCase = () => ({
+ type: 'replicated',
+ osds: OSDS,
+ size: 4,
+ ecp: {
+ k: 2,
+ m: 2
+ },
+ expected: 256
+ });
+
+ const testPgCalc = ({ type, osds, size, ecp, expected }: Record<string, any>) => {
+ component.info.osd_count = osds;
+ formHelper.setValue('poolType', type);
+ if (type === 'replicated') {
+ formHelper.setValue('size', size);
+ } else {
+ formHelper.setValue('erasureProfile', ecp);
+ }
+ expect(form.getValue('pgNum')).toBe(expected);
+ expect(component.externalPgChange).toBe(PGS !== expected);
+ };
+
+ beforeEach(() => {
+ setPgNum(PGS);
+ });
+
+ it('does not change anything if type is not valid', () => {
+ const test = getValidCase();
+ test.type = '';
+ test.expected = PGS;
+ testPgCalc(test);
+ });
+
+ it('does not change anything if ecp is not valid', () => {
+ const test = getValidCase();
+ test.expected = PGS;
+ test.type = 'erasure';
+ test.ecp = null;
+ testPgCalc(test);
+ });
+
+ it('calculates some replicated values', () => {
+ const test = getValidCase();
+ testPgCalc(test);
+ test.osds = 16;
+ test.expected = 512;
+ testPgCalc(test);
+ test.osds = 8;
+ test.size = 8;
+ test.expected = 128;
+ testPgCalc(test);
+ });
+
+ it('calculates erasure code values even if selection is disabled', () => {
+ component['initEcp']([{ k: 2, m: 2, name: 'bla', plugin: '', technique: '' }]);
+ const test = getValidCase();
+ test.type = 'erasure';
+ testPgCalc(test);
+ expect(form.get('erasureProfile').disabled).toBeTruthy();
+ });
+
+ it('calculates some erasure code values', () => {
+ const test = getValidCase();
+ test.type = 'erasure';
+ testPgCalc(test);
+ test.osds = 16;
+ test.ecp.m = 5;
+ test.expected = 256;
+ testPgCalc(test);
+ test.ecp.k = 5;
+ test.expected = 128;
+ testPgCalc(test);
+ });
+
+ it('should not change a manual set pg number', () => {
+ form.get('pgNum').markAsDirty();
+ const test = getValidCase();
+ test.expected = PGS;
+ testPgCalc(test);
+ });
+ });
+ });
+
+ describe('crushRule', () => {
+ const selectRuleByIndex = (n: number) => {
+ formHelper.setValue('crushRule', component.info.crush_rules_replicated[n]);
+ };
+
+ beforeEach(() => {
+ formHelper.setValue('poolType', 'replicated');
+ selectRuleByIndex(0);
+ fixture.detectChanges();
+ });
+
+ it('should select the newly created rule', () => {
+ expect(form.getValue('crushRule').rule_name).toBe('rep1');
+ const name = 'awesomeRule';
+ spyOn(TestBed.inject(ModalService), 'show').and.callFake(() => {
+ return {
+ componentInstance: {
+ submitAction: of({ name })
+ }
+ };
+ });
+ infoReturn.crush_rules_replicated.push(Mocks.getCrushRule({ id: 8, name }));
+ component.addCrushRule();
+ expect(form.getValue('crushRule').rule_name).toBe(name);
+ });
+
+ it('should not show info per default', () => {
+ fixtureHelper.expectElementVisible('#crushRule', true);
+ fixtureHelper.expectElementVisible('#crush-info-block', false);
+ });
+
+ it('should show info if the info button is clicked', () => {
+ const infoButton = fixture.debugElement.query(By.css('#crush-info-button'));
+ infoButton.triggerEventHandler('click', null);
+ expect(component.data.crushInfo).toBeTruthy();
+ fixture.detectChanges();
+ expect(infoButton.classes['active']).toBeTruthy();
+ fixtureHelper.expectIdElementsVisible(['crushRule', 'crush-info-block'], true);
+ });
+
+ it('should know which rules are in use', () => {
+ selectRuleByIndex(2);
+ expect(component.crushUsage).toEqual(['some.pool.uses.it']);
+ });
+
+ describe('crush rule deletion', () => {
+ let taskWrapper: TaskWrapperService;
+ let deletion: CriticalConfirmationModalComponent;
+ let deleteSpy: jasmine.Spy;
+ let modalSpy: jasmine.Spy;
+
+ const callDeletion = () => {
+ component.deleteCrushRule();
+ deletion.submitActionObservable();
+ };
+
+ const callDeletionWithRuleByIndex = (index: number) => {
+ deleteSpy.calls.reset();
+ selectRuleByIndex(index);
+ callDeletion();
+ };
+
+ const expectSuccessfulDeletion = (name: string) => {
+ expect(crushRuleService.delete).toHaveBeenCalledWith(name);
+ expect(taskWrapper.wrapTaskAroundCall).toHaveBeenCalledWith(
+ expect.objectContaining({
+ task: {
+ name: 'crushRule/delete',
+ metadata: {
+ name: name
+ }
+ }
+ })
+ );
+ };
+
+ beforeEach(() => {
+ modalSpy = spyOn(TestBed.inject(ModalService), 'show').and.callFake(
+ (deletionClass: any, initialState: any) => {
+ deletion = Object.assign(new deletionClass(), initialState);
+ return {
+ componentInstance: deletion
+ };
+ }
+ );
+ deleteSpy = spyOn(crushRuleService, 'delete').and.callFake((name: string) => {
+ const rules = infoReturn.crush_rules_replicated;
+ const index = _.findIndex(rules, (rule) => rule.rule_name === name);
+ rules.splice(index, 1);
+ return of(undefined);
+ });
+ taskWrapper = TestBed.inject(TaskWrapperService);
+ spyOn(taskWrapper, 'wrapTaskAroundCall').and.callThrough();
+ });
+
+ describe('with unused rule', () => {
+ beforeEach(() => {
+ callDeletionWithRuleByIndex(0);
+ });
+
+ it('should have called delete', () => {
+ expectSuccessfulDeletion('rep1');
+ });
+
+ it('should not open the tooltip nor the crush info', () => {
+ expect(component.crushDeletionBtn.isOpen()).toBe(false);
+ expect(component.data.crushInfo).toBe(false);
+ });
+
+ it('should reload the rules after deletion', () => {
+ const expected = infoReturn.crush_rules_replicated;
+ const currentRules = component.current.rules;
+ expect(currentRules.length).toBe(expected.length);
+ expect(currentRules).toEqual(expected);
+ });
+ });
+
+ describe('rule in use', () => {
+ beforeEach(() => {
+ spyOn(global, 'setTimeout').and.callFake((fn: Function) => fn());
+ deleteSpy.calls.reset();
+ selectRuleByIndex(2);
+ component.deleteCrushRule();
+ });
+
+ it('should not have called delete and opened the tooltip', () => {
+ expect(crushRuleService.delete).not.toHaveBeenCalled();
+ expect(component.crushDeletionBtn.isOpen()).toBe(true);
+ expect(component.data.crushInfo).toBe(true);
+ });
+
+ it('should hide the tooltip when clicking on delete again', () => {
+ component.deleteCrushRule();
+ expect(component.crushDeletionBtn.isOpen()).toBe(false);
+ });
+
+ it('should hide the tooltip when clicking on add', () => {
+ modalSpy.and.callFake((): any => ({
+ componentInstance: {
+ submitAction: of('someRule')
+ }
+ }));
+ component.addCrushRule();
+ expect(component.crushDeletionBtn.isOpen()).toBe(false);
+ });
+
+ it('should hide the tooltip when changing the crush rule', () => {
+ selectRuleByIndex(0);
+ expect(component.crushDeletionBtn.isOpen()).toBe(false);
+ });
+ });
+ });
+ });
+
+ describe('erasure code profile', () => {
+ const setSelectedEcp = (name: string) => {
+ formHelper.setValue('erasureProfile', { name: name });
+ };
+
+ beforeEach(() => {
+ formHelper.setValue('poolType', 'erasure');
+ fixture.detectChanges();
+ });
+
+ it('should not show info per default', () => {
+ fixtureHelper.expectElementVisible('#erasureProfile', true);
+ fixtureHelper.expectElementVisible('#ecp-info-block', false);
+ });
+
+ it('should show info if the info button is clicked', () => {
+ const infoButton = fixture.debugElement.query(By.css('#ecp-info-button'));
+ infoButton.triggerEventHandler('click', null);
+ expect(component.data.erasureInfo).toBeTruthy();
+ fixture.detectChanges();
+ expect(infoButton.classes['active']).toBeTruthy();
+ fixtureHelper.expectIdElementsVisible(['erasureProfile', 'ecp-info-block'], true);
+ });
+
+ it('should select the newly created profile', () => {
+ spyOn(ecpService, 'list').and.callFake(() => of(infoReturn.erasure_code_profiles));
+ expect(form.getValue('erasureProfile').name).toBe('ecp1');
+ const name = 'awesomeProfile';
+ spyOn(TestBed.inject(ModalService), 'show').and.callFake(() => {
+ return {
+ componentInstance: {
+ submitAction: of({ name })
+ }
+ };
+ });
+ const ecp2 = new ErasureCodeProfile();
+ ecp2.name = name;
+ infoReturn.erasure_code_profiles.push(ecp2);
+ component.addErasureCodeProfile();
+ expect(form.getValue('erasureProfile').name).toBe(name);
+ });
+
+ describe('ecp deletion', () => {
+ let taskWrapper: TaskWrapperService;
+ let deletion: CriticalConfirmationModalComponent;
+ let deleteSpy: jasmine.Spy;
+ let modalSpy: jasmine.Spy;
+ let modal: NgbModalRef;
+
+ const callEcpDeletion = () => {
+ component.deleteErasureCodeProfile();
+ modal.componentInstance.callSubmitAction();
+ };
+
+ const expectSuccessfulEcpDeletion = (name: string) => {
+ setSelectedEcp(name);
+ callEcpDeletion();
+ expect(ecpService.delete).toHaveBeenCalledWith(name);
+ expect(taskWrapper.wrapTaskAroundCall).toHaveBeenCalledWith(
+ expect.objectContaining({
+ task: {
+ name: 'ecp/delete',
+ metadata: {
+ name: name
+ }
+ }
+ })
+ );
+ };
+
+ beforeEach(() => {
+ deletion = undefined;
+ modalSpy = spyOn(TestBed.inject(ModalService), 'show').and.callFake(
+ (comp: any, init: any) => {
+ modal = modalServiceShow(comp, init);
+ return modal;
+ }
+ );
+ deleteSpy = spyOn(ecpService, 'delete').and.callFake((name: string) => {
+ const profiles = infoReturn.erasure_code_profiles;
+ const index = _.findIndex(profiles, (profile) => profile.name === name);
+ profiles.splice(index, 1);
+ return of({ status: 202 });
+ });
+ taskWrapper = TestBed.inject(TaskWrapperService);
+ spyOn(taskWrapper, 'wrapTaskAroundCall').and.callThrough();
+
+ const ecp2 = new ErasureCodeProfile();
+ ecp2.name = 'someEcpName';
+ infoReturn.erasure_code_profiles.push(ecp2);
+
+ const ecp3 = new ErasureCodeProfile();
+ ecp3.name = 'aDifferentEcpName';
+ infoReturn.erasure_code_profiles.push(ecp3);
+ });
+
+ it('should delete two different erasure code profiles', () => {
+ expectSuccessfulEcpDeletion('someEcpName');
+ expectSuccessfulEcpDeletion('aDifferentEcpName');
+ });
+
+ describe('with unused profile', () => {
+ beforeEach(() => {
+ expectSuccessfulEcpDeletion('someEcpName');
+ });
+
+ it('should not open the tooltip nor the crush info', () => {
+ expect(component.ecpDeletionBtn.isOpen()).toBe(false);
+ expect(component.data.erasureInfo).toBe(false);
+ });
+
+ it('should reload the rules after deletion', () => {
+ const expected = infoReturn.erasure_code_profiles;
+ const currentProfiles = component.info.erasure_code_profiles;
+ expect(currentProfiles.length).toBe(expected.length);
+ expect(currentProfiles).toEqual(expected);
+ });
+ });
+
+ describe('rule in use', () => {
+ beforeEach(() => {
+ spyOn(global, 'setTimeout').and.callFake((fn: Function) => fn());
+ deleteSpy.calls.reset();
+ setSelectedEcp('ecp1');
+ component.deleteErasureCodeProfile();
+ });
+
+ it('should not open the modal', () => {
+ expect(deletion).toBe(undefined);
+ });
+
+ it('should not have called delete and opened the tooltip', () => {
+ expect(ecpService.delete).not.toHaveBeenCalled();
+ expect(component.ecpDeletionBtn.isOpen()).toBe(true);
+ expect(component.data.erasureInfo).toBe(true);
+ });
+
+ it('should hide the tooltip when clicking on delete again', () => {
+ component.deleteErasureCodeProfile();
+ expect(component.ecpDeletionBtn.isOpen()).toBe(false);
+ });
+
+ it('should hide the tooltip when clicking on add', () => {
+ modalSpy.and.callFake((): any => ({
+ componentInstance: {
+ submitAction: of('someProfile')
+ }
+ }));
+ component.addErasureCodeProfile();
+ expect(component.ecpDeletionBtn.isOpen()).toBe(false);
+ });
+
+ it('should hide the tooltip when changing the crush rule', () => {
+ setSelectedEcp('someEcpName');
+ expect(component.ecpDeletionBtn.isOpen()).toBe(false);
+ });
+ });
+ });
+ });
+
+ describe('submit - create', () => {
+ const setMultipleValues = (settings: object) => {
+ Object.keys(settings).forEach((name) => {
+ formHelper.setValue(name, settings[name]);
+ });
+ };
+
+ describe('erasure coded pool', () => {
+ const expectEcSubmit = (o: any) =>
+ expectValidSubmit(
+ Object.assign(
+ {
+ pool: 'ecPool',
+ pool_type: 'erasure',
+ pg_autoscale_mode: 'off',
+ erasure_code_profile: 'ecp1',
+ pg_num: 4
+ },
+ o
+ )
+ );
+
+ beforeEach(() => {
+ setMultipleValues({
+ name: 'ecPool',
+ poolType: 'erasure',
+ pgNum: 4
+ });
+ });
+
+ it('minimum requirements without ECP to create ec pool', () => {
+ // Mock that no ec profiles exist
+ infoReturn.erasure_code_profiles = [];
+ setUpPoolComponent();
+ setMultipleValues({
+ name: 'minECPool',
+ poolType: 'erasure',
+ pgNum: 4
+ });
+ expectValidSubmit({
+ pool: 'minECPool',
+ pool_type: 'erasure',
+ pg_autoscale_mode: 'off',
+ pg_num: 4
+ });
+ });
+
+ it('creates ec pool with erasure coded profile', () => {
+ const ecp = { name: 'ecpMinimalMock' };
+ setMultipleValues({
+ erasureProfile: ecp
+ });
+ expectEcSubmit({
+ erasure_code_profile: ecp.name
+ });
+ });
+
+ it('creates ec pool with ec_overwrite flag', () => {
+ setMultipleValues({
+ ecOverwrites: true
+ });
+ expectEcSubmit({
+ flags: ['ec_overwrites']
+ });
+ });
+
+ it('should ignore replicated set settings for ec pools', () => {
+ setMultipleValues({
+ size: 2 // will be ignored
+ });
+ expectEcSubmit({});
+ });
+
+ it('creates a pool with compression', () => {
+ setMultipleValues({
+ mode: 'passive',
+ algorithm: 'lz4',
+ minBlobSize: '4 K',
+ maxBlobSize: '4 M',
+ ratio: 0.7
+ });
+ expectEcSubmit({
+ compression_mode: 'passive',
+ compression_algorithm: 'lz4',
+ compression_min_blob_size: 4096,
+ compression_max_blob_size: 4194304,
+ compression_required_ratio: 0.7
+ });
+ });
+
+ it('creates a pool with application metadata', () => {
+ component.data.applications.selected = ['cephfs', 'rgw'];
+ expectEcSubmit({
+ application_metadata: ['cephfs', 'rgw']
+ });
+ });
+ });
+
+ describe('with replicated pool', () => {
+ const expectReplicatedSubmit = (o: any) =>
+ expectValidSubmit(
+ Object.assign(
+ {
+ pool: 'repPool',
+ pool_type: 'replicated',
+ pg_autoscale_mode: 'off',
+ pg_num: 16,
+ rule_name: 'rep1',
+ size: 3
+ },
+ o
+ )
+ );
+ beforeEach(() => {
+ setMultipleValues({
+ name: 'repPool',
+ poolType: 'replicated',
+ crushRule: infoReturn.crush_rules_replicated[0],
+ size: 3,
+ pgNum: 16
+ });
+ });
+
+ it('uses the minimum requirements for replicated pools', () => {
+ // Mock that no replicated rules exist
+ infoReturn.crush_rules_replicated = [];
+ setUpPoolComponent();
+
+ setMultipleValues({
+ name: 'minRepPool',
+ poolType: 'replicated',
+ size: 2,
+ pgNum: 32
+ });
+ expectValidSubmit({
+ pool: 'minRepPool',
+ pool_type: 'replicated',
+ pg_num: 32,
+ pg_autoscale_mode: 'off',
+ size: 2
+ });
+ });
+
+ it('ignores erasure only set settings for replicated pools', () => {
+ setMultipleValues({
+ erasureProfile: { name: 'ecpMinimalMock' }, // Will be ignored
+ ecOverwrites: true // Will be ignored
+ });
+ /**
+ * As pgCalc is triggered through profile changes, which is normally not possible,
+ * if type `replicated` is set, pgNum will be set to 256 with the current rule for
+ * a replicated pool.
+ */
+ expectReplicatedSubmit({
+ pg_num: 256
+ });
+ });
+
+ it('creates a pool with quotas', () => {
+ setMultipleValues({
+ max_bytes: 1024 * 1024,
+ max_objects: 3000
+ });
+ expectReplicatedSubmit({
+ quota_max_bytes: 1024 * 1024,
+ quota_max_objects: 3000
+ });
+ });
+
+ it('creates a pool with rbd qos settings', () => {
+ component.currentConfigurationValues = {
+ rbd_qos_bps_limit: 55
+ };
+ expectReplicatedSubmit({
+ configuration: {
+ rbd_qos_bps_limit: 55
+ }
+ });
+ });
+ });
+ });
+
+ describe('edit mode', () => {
+ const setUrl = (url: string) => {
+ Object.defineProperty(router, 'url', { value: url });
+ setUpPoolComponent(); // Renew of component needed because the constructor has to be called
+ };
+
+ let pool: Pool;
+ beforeEach(() => {
+ pool = new Pool('somePoolName');
+ pool.type = 'replicated';
+ pool.size = 3;
+ pool.crush_rule = 'rep1';
+ pool.pg_num = 32;
+ pool.options = {};
+ pool.options.compression_mode = 'passive';
+ pool.options.compression_algorithm = 'lz4';
+ pool.options.compression_min_blob_size = 1024 * 512;
+ pool.options.compression_max_blob_size = 1024 * 1024;
+ pool.options.compression_required_ratio = 0.8;
+ pool.flags_names = 'someFlag1,someFlag2';
+ pool.application_metadata = ['rbd', 'ownApp'];
+ pool.quota_max_bytes = 1024 * 1024 * 1024;
+ pool.quota_max_objects = 3000;
+
+ Mocks.getCrushRule({ name: 'someRule' });
+ spyOn(poolService, 'get').and.callFake(() => of(pool));
+ });
+
+ it('is not in edit mode if edit is not included in url', () => {
+ setUrl('/pool/add');
+ expect(component.editing).toBeFalsy();
+ });
+
+ it('is in edit mode if edit is included in url', () => {
+ setUrl('/pool/edit/somePoolName');
+ expect(component.editing).toBeTruthy();
+ });
+
+ describe('after ngOnInit', () => {
+ beforeEach(() => {
+ setUrl('/pool/edit/somePoolName');
+ fixture.detectChanges();
+ });
+
+ it('disabled inputs', () => {
+ fixture.detectChanges();
+ const disabled = ['poolType', 'crushRule', 'size', 'erasureProfile', 'ecOverwrites'];
+ disabled.forEach((controlName) => {
+ return expect(form.get(controlName).disabled).toBeTruthy();
+ });
+ const enabled = [
+ 'name',
+ 'pgNum',
+ 'mode',
+ 'algorithm',
+ 'minBlobSize',
+ 'maxBlobSize',
+ 'ratio',
+ 'max_bytes',
+ 'max_objects'
+ ];
+ enabled.forEach((controlName) => {
+ return expect(form.get(controlName).enabled).toBeTruthy();
+ });
+ });
+
+ it('should include the custom app as valid option', () => {
+ expect(
+ component.data.applications.available.map((app: Record<string, any>) => app.name)
+ ).toEqual(['cephfs', 'ownApp', 'rbd', 'rgw']);
+ });
+
+ it('set all control values to the given pool', () => {
+ expect(form.getValue('name')).toBe(pool.pool_name);
+ expect(form.getValue('poolType')).toBe(pool.type);
+ expect(form.getValue('crushRule')).toEqual(component.info.crush_rules_replicated[0]);
+ expect(form.getValue('size')).toBe(pool.size);
+ expect(form.getValue('pgNum')).toBe(pool.pg_num);
+ expect(form.getValue('mode')).toBe(pool.options.compression_mode);
+ expect(form.getValue('algorithm')).toBe(pool.options.compression_algorithm);
+ expect(form.getValue('minBlobSize')).toBe('512 KiB');
+ expect(form.getValue('maxBlobSize')).toBe('1 MiB');
+ expect(form.getValue('ratio')).toBe(pool.options.compression_required_ratio);
+ expect(form.getValue('max_bytes')).toBe('1 GiB');
+ expect(form.getValue('max_objects')).toBe(pool.quota_max_objects);
+ });
+
+ it('updates pgs on every change', () => {
+ testPgUpdate(undefined, -1, 16);
+ testPgUpdate(undefined, -1, 8);
+ });
+
+ it('is possible to use less or more pgs than before', () => {
+ formHelper.expectValid(setPgNum(64));
+ formHelper.expectValid(setPgNum(4));
+ });
+
+ describe('submit', () => {
+ const markControlAsPreviouslySet = (controlName: string) =>
+ form.get(controlName).markAsPristine();
+
+ beforeEach(() => {
+ [
+ 'algorithm',
+ 'maxBlobSize',
+ 'minBlobSize',
+ 'mode',
+ 'pgNum',
+ 'ratio',
+ 'name'
+ ].forEach((name) => markControlAsPreviouslySet(name));
+ fixture.detectChanges();
+ });
+
+ it(`always provides the application metadata array with submit even if it's empty`, () => {
+ expect(form.get('mode').dirty).toBe(false);
+ component.data.applications.selected = [];
+ expectValidSubmit(
+ {
+ application_metadata: [],
+ pool: 'somePoolName'
+ },
+ 'pool/edit',
+ 'update'
+ );
+ });
+
+ it(`will always provide reset value for compression options`, () => {
+ formHelper.setValue('minBlobSize', '').markAsDirty();
+ formHelper.setValue('maxBlobSize', '').markAsDirty();
+ formHelper.setValue('ratio', '').markAsDirty();
+ expectValidSubmit(
+ {
+ application_metadata: ['ownApp', 'rbd'],
+ compression_max_blob_size: 0,
+ compression_min_blob_size: 0,
+ compression_required_ratio: 0,
+ pool: 'somePoolName'
+ },
+ 'pool/edit',
+ 'update'
+ );
+ });
+
+ it(`will unset mode not used anymore`, () => {
+ formHelper.setValue('mode', 'none').markAsDirty();
+ expectValidSubmit(
+ {
+ application_metadata: ['ownApp', 'rbd'],
+ compression_mode: 'unset',
+ pool: 'somePoolName'
+ },
+ 'pool/edit',
+ 'update'
+ );
+ });
+ });
+ });
+ });
+
+ describe('test pool configuration component', () => {
+ it('is visible for replicated pools with rbd application', () => {
+ const poolType = component.form.get('poolType');
+ poolType.markAsDirty();
+ poolType.setValue('replicated');
+ component.data.applications.selected = ['rbd'];
+ fixture.detectChanges();
+ expect(
+ fixture.debugElement.query(By.css('cd-rbd-configuration-form')).nativeElement.parentElement
+ .hidden
+ ).toBe(false);
+ });
+
+ it('is invisible for erasure coded pools', () => {
+ const poolType = component.form.get('poolType');
+ poolType.markAsDirty();
+ poolType.setValue('erasure');
+ fixture.detectChanges();
+ expect(
+ fixture.debugElement.query(By.css('cd-rbd-configuration-form')).nativeElement.parentElement
+ .hidden
+ ).toBe(true);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.ts
new file mode 100644
index 000000000..4778562cb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.ts
@@ -0,0 +1,919 @@
+import { Component, OnInit, Type, ViewChild } from '@angular/core';
+import { FormControl, Validators } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+
+import { NgbNav, NgbTooltip } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { Observable, ReplaySubject, Subscription } from 'rxjs';
+
+import { DashboardNotFoundError } from '~/app/core/error/error';
+import { CrushRuleService } from '~/app/shared/api/crush-rule.service';
+import { ErasureCodeProfileService } from '~/app/shared/api/erasure-code-profile.service';
+import { PoolService } from '~/app/shared/api/pool.service';
+import { CrushNodeSelectionClass } from '~/app/shared/classes/crush.node.selection.class';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { SelectOption } from '~/app/shared/components/select/select-option.model';
+import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdForm } from '~/app/shared/forms/cd-form';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import {
+ RbdConfigurationEntry,
+ RbdConfigurationSourceField
+} from '~/app/shared/models/configuration';
+import { CrushRule } from '~/app/shared/models/crush-rule';
+import { CrushStep } from '~/app/shared/models/crush-step';
+import { ErasureCodeProfile } from '~/app/shared/models/erasure-code-profile';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { Permission } from '~/app/shared/models/permissions';
+import { PoolFormInfo } from '~/app/shared/models/pool-form-info';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { FormatterService } from '~/app/shared/services/formatter.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { CrushRuleFormModalComponent } from '../crush-rule-form-modal/crush-rule-form-modal.component';
+import { ErasureCodeProfileFormModalComponent } from '../erasure-code-profile-form/erasure-code-profile-form-modal.component';
+import { Pool } from '../pool';
+import { PoolFormData } from './pool-form-data';
+
+interface FormFieldDescription {
+ externalFieldName: string;
+ formControlName: string;
+ attr?: string;
+ replaceFn?: Function;
+ editable?: boolean;
+ resetValue?: any;
+}
+
+@Component({
+ selector: 'cd-pool-form',
+ templateUrl: './pool-form.component.html',
+ styleUrls: ['./pool-form.component.scss']
+})
+export class PoolFormComponent extends CdForm implements OnInit {
+ @ViewChild('crushInfoTabs') crushInfoTabs: NgbNav;
+ @ViewChild('crushDeletionBtn') crushDeletionBtn: NgbTooltip;
+ @ViewChild('ecpInfoTabs') ecpInfoTabs: NgbNav;
+ @ViewChild('ecpDeletionBtn') ecpDeletionBtn: NgbTooltip;
+
+ permission: Permission;
+ form: CdFormGroup;
+ ecProfiles: ErasureCodeProfile[];
+ info: PoolFormInfo;
+ routeParamsSubscribe: any;
+ editing = false;
+ isReplicated = false;
+ isErasure = false;
+ data = new PoolFormData();
+ externalPgChange = false;
+ current: Record<string, any> = {
+ rules: []
+ };
+ initializeConfigData = new ReplaySubject<{
+ initialData: RbdConfigurationEntry[];
+ sourceType: RbdConfigurationSourceField;
+ }>(1);
+ currentConfigurationValues: { [configKey: string]: any } = {};
+ action: string;
+ resource: string;
+ icons = Icons;
+ pgAutoscaleModes: string[];
+ crushUsage: string[] = undefined; // Will only be set if a rule is used by some pool
+ ecpUsage: string[] = undefined; // Will only be set if a rule is used by some pool
+
+ private modalSubscription: Subscription;
+
+ constructor(
+ private dimlessBinaryPipe: DimlessBinaryPipe,
+ private route: ActivatedRoute,
+ private router: Router,
+ private modalService: ModalService,
+ private poolService: PoolService,
+ private authStorageService: AuthStorageService,
+ private formatter: FormatterService,
+ private taskWrapper: TaskWrapperService,
+ private ecpService: ErasureCodeProfileService,
+ private crushRuleService: CrushRuleService,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ super();
+ this.editing = this.router.url.startsWith(`/pool/${URLVerbs.EDIT}`);
+ this.action = this.editing ? this.actionLabels.EDIT : this.actionLabels.CREATE;
+ this.resource = $localize`pool`;
+ this.authenticate();
+ this.createForm();
+ }
+
+ authenticate() {
+ this.permission = this.authStorageService.getPermissions().pool;
+ if (
+ !this.permission.read ||
+ (!this.permission.update && this.editing) ||
+ (!this.permission.create && !this.editing)
+ ) {
+ throw new DashboardNotFoundError();
+ }
+ }
+
+ private createForm() {
+ const compressionForm = new CdFormGroup({
+ mode: new FormControl('none'),
+ algorithm: new FormControl(''),
+ minBlobSize: new FormControl('', {
+ updateOn: 'blur'
+ }),
+ maxBlobSize: new FormControl('', {
+ updateOn: 'blur'
+ }),
+ ratio: new FormControl('', {
+ updateOn: 'blur'
+ })
+ });
+
+ this.form = new CdFormGroup(
+ {
+ name: new FormControl('', {
+ validators: [
+ Validators.pattern(/^[.A-Za-z0-9_/-]+$/),
+ Validators.required,
+ CdValidators.custom('rbdPool', () => {
+ return (
+ this.form &&
+ this.form.getValue('name').includes('/') &&
+ this.data &&
+ this.data.applications.selected.indexOf('rbd') !== -1
+ );
+ })
+ ]
+ }),
+ poolType: new FormControl('', {
+ validators: [Validators.required]
+ }),
+ crushRule: new FormControl(null, {
+ validators: [
+ CdValidators.custom(
+ 'tooFewOsds',
+ (rule: any) => this.info && rule && this.info.osd_count < rule.min_size
+ ),
+ CdValidators.custom(
+ 'required',
+ (rule: CrushRule) =>
+ this.isReplicated && this.info.crush_rules_replicated.length > 0 && !rule
+ )
+ ]
+ }),
+ size: new FormControl('', {
+ updateOn: 'blur'
+ }),
+ erasureProfile: new FormControl(null),
+ pgNum: new FormControl('', {
+ validators: [Validators.required]
+ }),
+ pgAutoscaleMode: new FormControl(null),
+ ecOverwrites: new FormControl(false),
+ compression: compressionForm,
+ max_bytes: new FormControl(''),
+ max_objects: new FormControl(0)
+ },
+ [CdValidators.custom('form', (): null => null)]
+ );
+ }
+
+ ngOnInit() {
+ this.poolService.getInfo().subscribe((info: PoolFormInfo) => {
+ this.initInfo(info);
+ if (this.editing) {
+ this.initEditMode();
+ } else {
+ this.setAvailableApps();
+ this.loadingReady();
+ }
+ this.listenToChanges();
+ this.setComplexValidators();
+ });
+ }
+
+ private initInfo(info: PoolFormInfo) {
+ this.pgAutoscaleModes = info.pg_autoscale_modes;
+ this.form.silentSet('pgAutoscaleMode', info.pg_autoscale_default_mode);
+ this.form.silentSet('algorithm', info.bluestore_compression_algorithm);
+ this.info = info;
+ this.initEcp(info.erasure_code_profiles);
+ }
+
+ private initEcp(ecProfiles: ErasureCodeProfile[]) {
+ this.setListControlStatus('erasureProfile', ecProfiles);
+ this.ecProfiles = ecProfiles;
+ }
+
+ /**
+ * Used to update the crush rule or erasure code profile listings.
+ *
+ * If only one rule or profile exists it will be selected.
+ * If nothing exists null will be selected.
+ * If more than one rule or profile exists the listing will be enabled,
+ * otherwise disabled.
+ */
+ private setListControlStatus(controlName: string, arr: any[]) {
+ const control = this.form.get(controlName);
+ const value = control.value;
+ if (arr.length === 1 && (!value || !_.isEqual(value, arr[0]))) {
+ control.setValue(arr[0]);
+ } else if (arr.length === 0 && value) {
+ control.setValue(null);
+ }
+ if (arr.length <= 1) {
+ if (control.enabled) {
+ control.disable();
+ }
+ } else if (control.disabled) {
+ control.enable();
+ }
+ }
+
+ private initEditMode() {
+ this.disableForEdit();
+ this.routeParamsSubscribe = this.route.params.subscribe((param: { name: string }) =>
+ this.poolService.get(param.name).subscribe((pool: Pool) => {
+ this.data.pool = pool;
+ this.initEditFormData(pool);
+ this.loadingReady();
+ })
+ );
+ }
+
+ private disableForEdit() {
+ ['poolType', 'crushRule', 'size', 'erasureProfile', 'ecOverwrites'].forEach((controlName) =>
+ this.form.get(controlName).disable()
+ );
+ }
+
+ private initEditFormData(pool: Pool) {
+ this.initializeConfigData.next({
+ initialData: pool.configuration,
+ sourceType: RbdConfigurationSourceField.pool
+ });
+ this.poolTypeChange(pool.type);
+ const rules = this.info.crush_rules_replicated.concat(this.info.crush_rules_erasure);
+ const dataMap = {
+ name: pool.pool_name,
+ poolType: pool.type,
+ crushRule: rules.find((rule: CrushRule) => rule.rule_name === pool.crush_rule),
+ size: pool.size,
+ erasureProfile: this.ecProfiles.find((ecp) => ecp.name === pool.erasure_code_profile),
+ pgAutoscaleMode: pool.pg_autoscale_mode,
+ pgNum: pool.pg_num,
+ ecOverwrites: pool.flags_names.includes('ec_overwrites'),
+ mode: pool.options.compression_mode,
+ algorithm: pool.options.compression_algorithm,
+ minBlobSize: this.dimlessBinaryPipe.transform(pool.options.compression_min_blob_size),
+ maxBlobSize: this.dimlessBinaryPipe.transform(pool.options.compression_max_blob_size),
+ ratio: pool.options.compression_required_ratio,
+ max_bytes: this.dimlessBinaryPipe.transform(pool.quota_max_bytes),
+ max_objects: pool.quota_max_objects
+ };
+ Object.keys(dataMap).forEach((controlName: string) => {
+ const value = dataMap[controlName];
+ if (!_.isUndefined(value) && value !== '') {
+ this.form.silentSet(controlName, value);
+ }
+ });
+ this.data.pgs = this.form.getValue('pgNum');
+ this.setAvailableApps(this.data.applications.default.concat(pool.application_metadata));
+ this.data.applications.selected = pool.application_metadata;
+ }
+
+ private setAvailableApps(apps: string[] = this.data.applications.default) {
+ this.data.applications.available = _.uniq(apps.sort()).map(
+ (x: string) => new SelectOption(false, x, '')
+ );
+ }
+
+ private listenToChanges() {
+ this.listenToChangesDuringAddEdit();
+ if (!this.editing) {
+ this.listenToChangesDuringAdd();
+ }
+ }
+
+ private listenToChangesDuringAddEdit() {
+ this.form.get('pgNum').valueChanges.subscribe((pgs) => {
+ const change = pgs - this.data.pgs;
+ if (Math.abs(change) !== 1 || pgs === 2) {
+ this.data.pgs = pgs;
+ return;
+ }
+ this.doPgPowerJump(change as 1 | -1);
+ });
+ }
+
+ private doPgPowerJump(jump: 1 | -1) {
+ const power = this.calculatePgPower() + jump;
+ this.setPgs(jump === -1 ? Math.round(power) : Math.floor(power));
+ }
+
+ private calculatePgPower(pgs = this.form.getValue('pgNum')): number {
+ return Math.log(pgs) / Math.log(2);
+ }
+
+ private setPgs(power: number) {
+ const pgs = Math.pow(2, power < 0 ? 0 : power); // Set size the nearest accurate size.
+ this.data.pgs = pgs;
+ this.form.silentSet('pgNum', pgs);
+ }
+
+ private listenToChangesDuringAdd() {
+ this.form.get('poolType').valueChanges.subscribe((poolType) => {
+ this.poolTypeChange(poolType);
+ });
+ this.form.get('crushRule').valueChanges.subscribe((rule) => {
+ // The crush rule can only be changed if type 'replicated' is set.
+ if (this.crushDeletionBtn && this.crushDeletionBtn.isOpen()) {
+ this.crushDeletionBtn.close();
+ }
+ if (!rule) {
+ return;
+ }
+ this.setCorrectMaxSize(rule);
+ this.crushRuleIsUsedBy(rule.rule_name);
+ this.replicatedRuleChange();
+ this.pgCalc();
+ });
+ this.form.get('size').valueChanges.subscribe(() => {
+ // The size can only be changed if type 'replicated' is set.
+ this.pgCalc();
+ });
+ this.form.get('erasureProfile').valueChanges.subscribe((profile) => {
+ // The ec profile can only be changed if type 'erasure' is set.
+ if (this.ecpDeletionBtn && this.ecpDeletionBtn.isOpen()) {
+ this.ecpDeletionBtn.close();
+ }
+ if (!profile) {
+ return;
+ }
+ this.ecpIsUsedBy(profile.name);
+ this.pgCalc();
+ });
+ this.form.get('mode').valueChanges.subscribe(() => {
+ ['minBlobSize', 'maxBlobSize', 'ratio'].forEach((name) => {
+ this.form.get(name).updateValueAndValidity({ emitEvent: false });
+ });
+ });
+ this.form.get('minBlobSize').valueChanges.subscribe(() => {
+ this.form.get('maxBlobSize').updateValueAndValidity({ emitEvent: false });
+ });
+ this.form.get('maxBlobSize').valueChanges.subscribe(() => {
+ this.form.get('minBlobSize').updateValueAndValidity({ emitEvent: false });
+ });
+ }
+
+ private poolTypeChange(poolType: string) {
+ if (poolType === 'replicated') {
+ this.setTypeBooleans(true, false);
+ } else if (poolType === 'erasure') {
+ this.setTypeBooleans(false, true);
+ } else {
+ this.setTypeBooleans(false, false);
+ }
+ if (!poolType || !this.info) {
+ this.current.rules = [];
+ return;
+ }
+ const rules = this.info['crush_rules_' + poolType] || [];
+ this.current.rules = rules;
+ if (this.editing) {
+ return;
+ }
+ if (this.isReplicated) {
+ this.setListControlStatus('crushRule', rules);
+ }
+ this.replicatedRuleChange();
+ this.pgCalc();
+ }
+
+ private setTypeBooleans(replicated: boolean, erasure: boolean) {
+ this.isReplicated = replicated;
+ this.isErasure = erasure;
+ }
+
+ private replicatedRuleChange() {
+ if (!this.isReplicated) {
+ return;
+ }
+ const control = this.form.get('size');
+ let size = this.form.getValue('size') || 3;
+ const min = this.getMinSize();
+ const max = this.getMaxSize();
+ if (size < min) {
+ size = min;
+ } else if (size > max) {
+ size = max;
+ }
+ if (size !== control.value) {
+ this.form.silentSet('size', size);
+ }
+ }
+
+ getMinSize(): number {
+ if (!this.info || this.info.osd_count < 1) {
+ return 0;
+ }
+ const rule = this.form.getValue('crushRule');
+ if (rule) {
+ return rule.min_size;
+ }
+ return 1;
+ }
+
+ getMaxSize(): number {
+ const rule = this.form.getValue('crushRule');
+ if (!this.info) {
+ return 0;
+ }
+ if (!rule) {
+ const osds = this.info.osd_count;
+ const defaultSize = 3;
+ return Math.min(osds, defaultSize);
+ }
+ return rule.usable_size;
+ }
+
+ private pgCalc() {
+ const poolType = this.form.getValue('poolType');
+ if (!this.info || this.form.get('pgNum').dirty || !poolType) {
+ return;
+ }
+ const pgMax = this.info.osd_count * 100;
+ const pgs = this.isReplicated ? this.replicatedPgCalc(pgMax) : this.erasurePgCalc(pgMax);
+ if (!pgs) {
+ return;
+ }
+ const oldValue = this.data.pgs;
+ this.alignPgs(pgs);
+ const newValue = this.data.pgs;
+ if (!this.externalPgChange) {
+ this.externalPgChange = oldValue !== newValue;
+ }
+ }
+
+ private setCorrectMaxSize(rule: CrushRule = this.form.getValue('crushRule')) {
+ if (!rule) {
+ return;
+ }
+ const domains = CrushNodeSelectionClass.searchFailureDomains(
+ this.info.nodes,
+ rule.steps[0].item_name
+ );
+ const currentDomain = domains[rule.steps[1].type];
+ const usable = currentDomain ? currentDomain.length : rule.max_size;
+ rule.usable_size = Math.min(usable, rule.max_size);
+ }
+
+ private replicatedPgCalc(pgs: number): number {
+ const sizeControl = this.form.get('size');
+ const size = sizeControl.value;
+ return sizeControl.valid && size > 0 ? pgs / size : 0;
+ }
+
+ private erasurePgCalc(pgs: number): number {
+ const ecpControl = this.form.get('erasureProfile');
+ const ecp = ecpControl.value;
+ return (ecpControl.valid || ecpControl.disabled) && ecp ? pgs / (ecp.k + ecp.m) : 0;
+ }
+
+ alignPgs(pgs = this.form.getValue('pgNum')) {
+ this.setPgs(Math.round(this.calculatePgPower(pgs < 1 ? 1 : pgs)));
+ }
+
+ private setComplexValidators() {
+ if (this.editing) {
+ this.form
+ .get('name')
+ .setValidators([
+ this.form.get('name').validator,
+ CdValidators.custom(
+ 'uniqueName',
+ (name: string) =>
+ this.data.pool &&
+ this.info &&
+ this.info.pool_names.indexOf(name) !== -1 &&
+ this.info.pool_names.indexOf(name) !==
+ this.info.pool_names.indexOf(this.data.pool.pool_name)
+ )
+ ]);
+ } else {
+ CdValidators.validateIf(this.form.get('size'), () => this.isReplicated, [
+ CdValidators.custom(
+ 'min',
+ (value: number) => this.form.getValue('size') && value < this.getMinSize()
+ ),
+ CdValidators.custom(
+ 'max',
+ (value: number) => this.form.getValue('size') && this.getMaxSize() < value
+ )
+ ]);
+ this.form
+ .get('name')
+ .setValidators([
+ this.form.get('name').validator,
+ CdValidators.custom(
+ 'uniqueName',
+ (name: string) => this.info && this.info.pool_names.indexOf(name) !== -1
+ )
+ ]);
+ }
+ this.setCompressionValidators();
+ }
+
+ private setCompressionValidators() {
+ CdValidators.validateIf(this.form.get('minBlobSize'), () => this.hasCompressionEnabled(), [
+ Validators.min(0),
+ CdValidators.custom('maximum', (size: string) =>
+ this.oddBlobSize(size, this.form.getValue('maxBlobSize'))
+ )
+ ]);
+ CdValidators.validateIf(this.form.get('maxBlobSize'), () => this.hasCompressionEnabled(), [
+ Validators.min(0),
+ CdValidators.custom('minimum', (size: string) =>
+ this.oddBlobSize(this.form.getValue('minBlobSize'), size)
+ )
+ ]);
+ CdValidators.validateIf(this.form.get('ratio'), () => this.hasCompressionEnabled(), [
+ Validators.min(0),
+ Validators.max(1)
+ ]);
+ }
+
+ private oddBlobSize(minimum: string, maximum: string) {
+ const min = this.formatter.toBytes(minimum);
+ const max = this.formatter.toBytes(maximum);
+ return Boolean(min && max && min >= max);
+ }
+
+ hasCompressionEnabled() {
+ return this.form.getValue('mode') && this.form.get('mode').value.toLowerCase() !== 'none';
+ }
+
+ describeCrushStep(step: CrushStep) {
+ return [
+ step.op.replace('_', ' '),
+ step.item_name || '',
+ step.type ? step.num + ' type ' + step.type : ''
+ ].join(' ');
+ }
+
+ addErasureCodeProfile() {
+ this.addModal(ErasureCodeProfileFormModalComponent, (name) => this.reloadECPs(name));
+ }
+
+ private addModal(modalComponent: Type<any>, reload: (name: string) => void) {
+ this.hideOpenTooltips();
+ const modalRef = this.modalService.show(modalComponent);
+ modalRef.componentInstance.submitAction.subscribe((item: any) => {
+ reload(item.name);
+ });
+ }
+
+ private hideOpenTooltips() {
+ const hideTooltip = (btn: NgbTooltip) => btn && btn.isOpen() && btn.close();
+ hideTooltip(this.ecpDeletionBtn);
+ hideTooltip(this.crushDeletionBtn);
+ }
+
+ private reloadECPs(profileName?: string) {
+ this.reloadList({
+ newItemName: profileName,
+ getInfo: () => this.ecpService.list(),
+ initInfo: (profiles) => this.initEcp(profiles),
+ findNewItem: () => this.ecProfiles.find((p) => p.name === profileName),
+ controlName: 'erasureProfile'
+ });
+ }
+
+ private reloadList({
+ newItemName,
+ getInfo,
+ initInfo,
+ findNewItem,
+ controlName
+ }: {
+ newItemName: string;
+ getInfo: () => Observable<any>;
+ initInfo: (items: any) => void;
+ findNewItem: () => any;
+ controlName: string;
+ }) {
+ if (this.modalSubscription) {
+ this.modalSubscription.unsubscribe();
+ }
+ getInfo().subscribe((items: any) => {
+ initInfo(items);
+ if (!newItemName) {
+ return;
+ }
+ const item = findNewItem();
+ if (item) {
+ this.form.get(controlName).setValue(item);
+ }
+ });
+ }
+
+ deleteErasureCodeProfile() {
+ this.deletionModal({
+ value: this.form.getValue('erasureProfile'),
+ usage: this.ecpUsage,
+ deletionBtn: this.ecpDeletionBtn,
+ dataName: 'erasureInfo',
+ getTabs: () => this.ecpInfoTabs,
+ tabPosition: 'used-by-pools',
+ nameAttribute: 'name',
+ itemDescription: $localize`erasure code profile`,
+ reloadFn: () => this.reloadECPs(),
+ deleteFn: (name) => this.ecpService.delete(name),
+ taskName: 'ecp/delete'
+ });
+ }
+
+ private deletionModal({
+ value,
+ usage,
+ deletionBtn,
+ dataName,
+ getTabs,
+ tabPosition,
+ nameAttribute,
+ itemDescription,
+ reloadFn,
+ deleteFn,
+ taskName
+ }: {
+ value: any;
+ usage: string[];
+ deletionBtn: NgbTooltip;
+ dataName: string;
+ getTabs: () => NgbNav;
+ tabPosition: string;
+ nameAttribute: string;
+ itemDescription: string;
+ reloadFn: Function;
+ deleteFn: (name: string) => Observable<any>;
+ taskName: string;
+ }) {
+ if (!value) {
+ return;
+ }
+ if (usage) {
+ deletionBtn.animation = false;
+ deletionBtn.toggle();
+ this.data[dataName] = true;
+ setTimeout(() => {
+ const tabs = getTabs();
+ if (tabs) {
+ tabs.select(tabPosition);
+ }
+ }, 50);
+ return;
+ }
+ const name = value[nameAttribute];
+ this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription,
+ itemNames: [name],
+ submitActionObservable: () => {
+ const deletion = deleteFn(name);
+ deletion.subscribe(() => reloadFn());
+ return this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask(taskName, { name: name }),
+ call: deletion
+ });
+ }
+ });
+ }
+
+ addCrushRule() {
+ this.addModal(CrushRuleFormModalComponent, (name) => this.reloadCrushRules(name));
+ }
+
+ private reloadCrushRules(ruleName?: string) {
+ this.reloadList({
+ newItemName: ruleName,
+ getInfo: () => this.poolService.getInfo(),
+ initInfo: (info) => {
+ this.initInfo(info);
+ this.poolTypeChange('replicated');
+ },
+ findNewItem: () =>
+ this.info.crush_rules_replicated.find((rule) => rule.rule_name === ruleName),
+ controlName: 'crushRule'
+ });
+ }
+
+ deleteCrushRule() {
+ this.deletionModal({
+ value: this.form.getValue('crushRule'),
+ usage: this.crushUsage,
+ deletionBtn: this.crushDeletionBtn,
+ dataName: 'crushInfo',
+ getTabs: () => this.crushInfoTabs,
+ tabPosition: 'used-by-pools',
+ nameAttribute: 'rule_name',
+ itemDescription: $localize`crush rule`,
+ reloadFn: () => this.reloadCrushRules(),
+ deleteFn: (name) => this.crushRuleService.delete(name),
+ taskName: 'crushRule/delete'
+ });
+ }
+
+ crushRuleIsUsedBy(ruleName: string) {
+ this.crushUsage = ruleName ? this.info.used_rules[ruleName] : undefined;
+ }
+
+ ecpIsUsedBy(profileName: string) {
+ this.ecpUsage = profileName ? this.info.used_profiles[profileName] : undefined;
+ }
+
+ submit() {
+ if (this.form.invalid) {
+ this.form.setErrors({ cdSubmitButton: true });
+ return;
+ }
+
+ const pool = { pool: this.form.getValue('name') };
+
+ this.assignFormFields(pool, [
+ { externalFieldName: 'pool_type', formControlName: 'poolType' },
+ {
+ externalFieldName: 'pg_autoscale_mode',
+ formControlName: 'pgAutoscaleMode',
+ editable: true
+ },
+ {
+ externalFieldName: 'pg_num',
+ formControlName: 'pgNum',
+ replaceFn: (value: number) => (this.form.getValue('pgAutoscaleMode') === 'on' ? 1 : value),
+ editable: true
+ },
+ this.isReplicated
+ ? { externalFieldName: 'size', formControlName: 'size' }
+ : {
+ externalFieldName: 'erasure_code_profile',
+ formControlName: 'erasureProfile',
+ attr: 'name'
+ },
+ {
+ externalFieldName: 'rule_name',
+ formControlName: 'crushRule',
+ replaceFn: (value: CrushRule) => (this.isReplicated ? value && value.rule_name : undefined)
+ },
+ {
+ externalFieldName: 'quota_max_bytes',
+ formControlName: 'max_bytes',
+ replaceFn: this.formatter.toBytes,
+ editable: true,
+ resetValue: this.editing ? 0 : undefined
+ },
+ {
+ externalFieldName: 'quota_max_objects',
+ formControlName: 'max_objects',
+ editable: true,
+ resetValue: this.editing ? 0 : undefined
+ }
+ ]);
+
+ if (this.info.is_all_bluestore) {
+ this.assignFormField(pool, {
+ externalFieldName: 'flags',
+ formControlName: 'ecOverwrites',
+ replaceFn: () => (this.isErasure ? ['ec_overwrites'] : undefined)
+ });
+
+ if (this.form.getValue('mode') !== 'none') {
+ this.assignFormFields(pool, [
+ {
+ externalFieldName: 'compression_mode',
+ formControlName: 'mode',
+ editable: true,
+ replaceFn: (value: boolean) => this.hasCompressionEnabled() && value
+ },
+ {
+ externalFieldName: 'compression_algorithm',
+ formControlName: 'algorithm',
+ editable: true
+ },
+ {
+ externalFieldName: 'compression_min_blob_size',
+ formControlName: 'minBlobSize',
+ replaceFn: this.formatter.toBytes,
+ editable: true,
+ resetValue: 0
+ },
+ {
+ externalFieldName: 'compression_max_blob_size',
+ formControlName: 'maxBlobSize',
+ replaceFn: this.formatter.toBytes,
+ editable: true,
+ resetValue: 0
+ },
+ {
+ externalFieldName: 'compression_required_ratio',
+ formControlName: 'ratio',
+ editable: true,
+ resetValue: 0
+ }
+ ]);
+ } else if (this.editing) {
+ this.assignFormFields(pool, [
+ {
+ externalFieldName: 'compression_mode',
+ formControlName: 'mode',
+ editable: true,
+ replaceFn: () => 'unset' // Is used if no compression is set
+ },
+ {
+ externalFieldName: 'srcpool',
+ formControlName: 'name',
+ editable: true,
+ replaceFn: () => this.data.pool.pool_name
+ }
+ ]);
+ }
+ }
+
+ const apps = this.data.applications.selected;
+ if (apps.length > 0 || this.editing) {
+ pool['application_metadata'] = apps;
+ }
+
+ // Only collect configuration data for replicated pools, as QoS cannot be configured on EC
+ // pools. EC data pools inherit their settings from the corresponding replicated metadata pool.
+ if (this.isReplicated && !_.isEmpty(this.currentConfigurationValues)) {
+ pool['configuration'] = this.currentConfigurationValues;
+ }
+
+ this.triggerApiTask(pool);
+ }
+
+ /**
+ * Retrieves the values for the given form field descriptions and assigns the values to the given
+ * object. This method differentiates between `add` and `edit` mode and acts differently on one or
+ * the other.
+ */
+ private assignFormFields(pool: object, formFieldDescription: FormFieldDescription[]): void {
+ formFieldDescription.forEach((item) => this.assignFormField(pool, item));
+ }
+
+ /**
+ * Retrieves the value for the given form field description and assigns the values to the given
+ * object. This method differentiates between `add` and `edit` mode and acts differently on one or
+ * the other.
+ */
+ private assignFormField(
+ pool: object,
+ {
+ externalFieldName,
+ formControlName,
+ attr,
+ replaceFn,
+ editable,
+ resetValue
+ }: FormFieldDescription
+ ): void {
+ if (this.editing && (!editable || this.form.get(formControlName).pristine)) {
+ return;
+ }
+ const value = this.form.getValue(formControlName);
+ let apiValue = replaceFn ? replaceFn(value) : attr ? _.get(value, attr) : value;
+ if (!value || !apiValue) {
+ if (editable && !_.isUndefined(resetValue)) {
+ apiValue = resetValue;
+ } else {
+ return;
+ }
+ }
+ pool[externalFieldName] = apiValue;
+ }
+
+ private triggerApiTask(pool: Record<string, any>) {
+ this.taskWrapper
+ .wrapTaskAroundCall({
+ task: new FinishedTask('pool/' + (this.editing ? URLVerbs.EDIT : URLVerbs.CREATE), {
+ pool_name: pool.hasOwnProperty('srcpool') ? pool.srcpool : pool.pool
+ }),
+ call: this.poolService[this.editing ? URLVerbs.UPDATE : URLVerbs.CREATE](pool)
+ })
+ .subscribe({
+ error: (resp) => {
+ if (_.isObject(resp.error) && resp.error.code === '34') {
+ this.form.get('pgNum').setErrors({ '34': true });
+ }
+ this.form.setErrors({ cdSubmitButton: true });
+ },
+ complete: () => this.router.navigate(['/pool'])
+ });
+ }
+
+ appSelection() {
+ this.form.get('name').updateValueAndValidity({ emitEvent: false, onlySelf: true });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.html
new file mode 100644
index 000000000..2d3ee6976
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.html
@@ -0,0 +1,57 @@
+<ul ngbNav
+ #nav="ngbNav"
+ class="nav-tabs">
+ <li ngbNavItem>
+ <a ngbNavLink
+ i18n>Pools List</a>
+ <ng-template ngbNavContent>
+ <cd-table #table
+ id="pool-list"
+ [data]="pools"
+ [columns]="columns"
+ selectionType="single"
+ [hasDetails]="true"
+ [status]="tableStatus"
+ [autoReload]="-1"
+ (fetchData)="taskListService.fetch()"
+ (setExpandedRow)="setExpandedRow($event)"
+ (updateSelection)="updateSelection($event)">
+ <cd-table-actions id="pool-list-actions"
+ class="table-actions"
+ [permission]="permissions.pool"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ <cd-pool-details cdTableDetail
+ id="pool-list-details"
+ [selection]="expandedRow"
+ [permissions]="permissions"
+ [cacheTiers]="cacheTiers">
+ </cd-pool-details>
+ </cd-table>
+ </ng-template>
+ </li>
+
+ <li ngbNavItem
+ *ngIf="permissions.grafana.read">
+ <a ngbNavLink
+ i18n>Overall Performance</a>
+ <ng-template ngbNavContent>
+ <cd-grafana [grafanaPath]="'ceph-pools-overview?'"
+ uid="z99hzWtmk"
+ grafanaStyle="two">
+ </cd-grafana>
+ </ng-template>
+ </li>
+</ul>
+
+<div [ngbNavOutlet]="nav"></div>
+
+<ng-template #poolUsageTpl
+ let-row="row">
+ <cd-usage-bar *ngIf="row.stats?.avail_raw?.latest"
+ [total]="row.stats.bytes_used.latest + row.stats.avail_raw.latest"
+ [used]="row.stats.bytes_used.latest"
+ decimals="2">
+ </cd-usage-bar>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.scss
new file mode 100644
index 000000000..709e8aeb2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.scss
@@ -0,0 +1,19 @@
+@use './src/styles/vendor/variables' as vv;
+
+::ng-deep cd-pool-list {
+ .pg-clean {
+ color: vv.$success;
+ }
+
+ .pg-working {
+ color: vv.$primary;
+ }
+
+ .pg-warning {
+ color: vv.$warning;
+ }
+
+ .pg-unknown {
+ color: vv.$danger;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.spec.ts
new file mode 100644
index 000000000..8a8af7b73
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.spec.ts
@@ -0,0 +1,518 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { RbdConfigurationListComponent } from '~/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component';
+import { PgCategoryService } from '~/app/ceph/shared/pg-category.service';
+import { ConfigurationService } from '~/app/shared/api/configuration.service';
+import { ErasureCodeProfileService } from '~/app/shared/api/erasure-code-profile.service';
+import { PoolService } from '~/app/shared/api/pool.service';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { ErasureCodeProfile } from '~/app/shared/models/erasure-code-profile';
+import { ExecutingTask } from '~/app/shared/models/executing-task';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, expectItemTasks, Mocks } from '~/testing/unit-test-helper';
+import { Pool } from '../pool';
+import { PoolDetailsComponent } from '../pool-details/pool-details.component';
+import { PoolListComponent } from './pool-list.component';
+
+describe('PoolListComponent', () => {
+ let component: PoolListComponent;
+ let fixture: ComponentFixture<PoolListComponent>;
+ let poolService: PoolService;
+ let getECPList: jasmine.Spy;
+
+ const getPoolList = (): Pool[] => {
+ return [Mocks.getPool('a', 0), Mocks.getPool('b', 1), Mocks.getPool('c', 2)];
+ };
+ const getECPProfiles = (): ErasureCodeProfile[] => {
+ const ecpProfile = new ErasureCodeProfile();
+ ecpProfile.name = 'default';
+ ecpProfile.k = 2;
+ ecpProfile.m = 1;
+
+ return [ecpProfile];
+ };
+
+ configureTestBed({
+ declarations: [PoolListComponent, PoolDetailsComponent, RbdConfigurationListComponent],
+ imports: [
+ BrowserAnimationsModule,
+ SharedModule,
+ ToastrModule.forRoot(),
+ RouterTestingModule,
+ NgbNavModule,
+ HttpClientTestingModule
+ ],
+ providers: [PgCategoryService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(PoolListComponent);
+ component = fixture.componentInstance;
+ component.permissions.pool.read = true;
+ poolService = TestBed.inject(PoolService);
+ spyOn(poolService, 'getList').and.callFake(() => of(getPoolList()));
+ getECPList = spyOn(TestBed.inject(ErasureCodeProfileService), 'list');
+ getECPList.and.returnValue(of(getECPProfiles()));
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should have columns that are sortable', () => {
+ expect(
+ component.columns
+ .filter((column) => !(column.prop === undefined))
+ .every((column) => Boolean(column.prop))
+ ).toBeTruthy();
+ });
+
+ describe('monAllowPoolDelete', () => {
+ let configOptRead: boolean;
+ let configurationService: ConfigurationService;
+
+ beforeEach(() => {
+ configOptRead = true;
+ spyOn(TestBed.inject(AuthStorageService), 'getPermissions').and.callFake(() => ({
+ configOpt: { read: configOptRead }
+ }));
+ configurationService = TestBed.inject(ConfigurationService);
+ });
+
+ it('should set value correctly if mon_allow_pool_delete flag is set to true', () => {
+ const configOption = {
+ name: 'mon_allow_pool_delete',
+ value: [
+ {
+ section: 'mon',
+ value: 'true'
+ }
+ ]
+ };
+ spyOn(configurationService, 'get').and.returnValue(of(configOption));
+ fixture = TestBed.createComponent(PoolListComponent);
+ component = fixture.componentInstance;
+ expect(component.monAllowPoolDelete).toBe(true);
+ });
+
+ it('should set value correctly if mon_allow_pool_delete flag is set to false', () => {
+ const configOption = {
+ name: 'mon_allow_pool_delete',
+ value: [
+ {
+ section: 'mon',
+ value: 'false'
+ }
+ ]
+ };
+ spyOn(configurationService, 'get').and.returnValue(of(configOption));
+ fixture = TestBed.createComponent(PoolListComponent);
+ component = fixture.componentInstance;
+ expect(component.monAllowPoolDelete).toBe(false);
+ });
+
+ it('should set value correctly if mon_allow_pool_delete flag is not set', () => {
+ const configOption = {
+ name: 'mon_allow_pool_delete'
+ };
+ spyOn(configurationService, 'get').and.returnValue(of(configOption));
+ fixture = TestBed.createComponent(PoolListComponent);
+ component = fixture.componentInstance;
+ expect(component.monAllowPoolDelete).toBe(false);
+ });
+
+ it('should set value correctly w/o config-opt read privileges', () => {
+ configOptRead = false;
+ fixture = TestBed.createComponent(PoolListComponent);
+ component = fixture.componentInstance;
+ expect(component.monAllowPoolDelete).toBe(false);
+ });
+ });
+
+ describe('pool deletion', () => {
+ let taskWrapper: TaskWrapperService;
+ let modalRef: any;
+
+ const setSelectedPool = (poolName: string) =>
+ (component.selection.selected = [{ pool_name: poolName }]);
+
+ const callDeletion = () => {
+ component.deletePoolModal();
+ expect(modalRef).toBeTruthy();
+ const deletion: CriticalConfirmationModalComponent = modalRef && modalRef.componentInstance;
+ deletion.submitActionObservable();
+ };
+
+ const testPoolDeletion = (poolName: string) => {
+ setSelectedPool(poolName);
+ callDeletion();
+ expect(poolService.delete).toHaveBeenCalledWith(poolName);
+ expect(taskWrapper.wrapTaskAroundCall).toHaveBeenCalledWith({
+ task: {
+ name: 'pool/delete',
+ metadata: {
+ pool_name: poolName
+ }
+ },
+ call: undefined // because of stub
+ });
+ };
+
+ beforeEach(() => {
+ spyOn(TestBed.inject(ModalService), 'show').and.callFake((deletionClass, initialState) => {
+ modalRef = {
+ componentInstance: Object.assign(new deletionClass(), initialState)
+ };
+ return modalRef;
+ });
+ spyOn(poolService, 'delete').and.stub();
+ taskWrapper = TestBed.inject(TaskWrapperService);
+ spyOn(taskWrapper, 'wrapTaskAroundCall').and.callThrough();
+ });
+
+ it('should pool deletion with two different pools', () => {
+ testPoolDeletion('somePoolName');
+ testPoolDeletion('aDifferentPoolName');
+ });
+ });
+
+ describe('handling of executing tasks', () => {
+ let summaryService: SummaryService;
+
+ const addTask = (name: string, pool: string) => {
+ const task = new ExecutingTask();
+ task.name = name;
+ task.metadata = { pool_name: pool };
+ summaryService.addRunningTask(task);
+ };
+
+ beforeEach(() => {
+ summaryService = TestBed.inject(SummaryService);
+ summaryService['summaryDataSource'].next({
+ executing_tasks: [],
+ finished_tasks: []
+ });
+ });
+
+ it('gets all pools without executing pools', () => {
+ expect(component.pools.length).toBe(3);
+ expect(component.pools.every((pool) => !pool.executingTasks)).toBeTruthy();
+ });
+
+ it('gets a pool from a task during creation', () => {
+ addTask('pool/create', 'd');
+ expect(component.pools.length).toBe(4);
+ expectItemTasks(component.pools[3], 'Creating');
+ });
+
+ it('gets all pools with one executing pools', () => {
+ addTask('pool/create', 'a');
+ expect(component.pools.length).toBe(3);
+ expectItemTasks(component.pools[0], 'Creating');
+ expect(component.pools[1].cdExecuting).toBeFalsy();
+ expect(component.pools[2].cdExecuting).toBeFalsy();
+ });
+
+ it('gets all pools with multiple executing pools', () => {
+ addTask('pool/create', 'a');
+ addTask('pool/edit', 'a');
+ addTask('pool/delete', 'a');
+ addTask('pool/edit', 'b');
+ addTask('pool/delete', 'b');
+ addTask('pool/delete', 'c');
+ expect(component.pools.length).toBe(3);
+ expectItemTasks(component.pools[0], 'Creating..., Updating..., Deleting');
+ expectItemTasks(component.pools[1], 'Updating..., Deleting');
+ expectItemTasks(component.pools[2], 'Deleting');
+ });
+
+ it('gets all pools with multiple executing tasks (not only pool tasks)', () => {
+ addTask('rbd/create', 'a');
+ addTask('rbd/edit', 'a');
+ addTask('pool/delete', 'a');
+ addTask('pool/edit', 'b');
+ addTask('rbd/delete', 'b');
+ addTask('rbd/delete', 'c');
+ expect(component.pools.length).toBe(3);
+ expectItemTasks(component.pools[0], 'Deleting');
+ expectItemTasks(component.pools[1], 'Updating');
+ expect(component.pools[2].cdExecuting).toBeFalsy();
+ });
+ });
+
+ describe('getPgStatusCellClass', () => {
+ const testMethod = (value: string, expected: string) =>
+ expect(component.getPgStatusCellClass('', '', value)).toEqual({
+ 'text-right': true,
+ [expected]: true
+ });
+
+ it('pg-clean', () => {
+ testMethod('8 active+clean', 'pg-clean');
+ });
+
+ it('pg-working', () => {
+ testMethod(' 8 active+clean+scrubbing+deep, 255 active+clean ', 'pg-working');
+ });
+
+ it('pg-warning', () => {
+ testMethod('8 active+clean+scrubbing+down', 'pg-warning');
+ testMethod('8 active+clean+scrubbing+down+nonMappedState', 'pg-warning');
+ });
+
+ it('pg-unknown', () => {
+ testMethod('8 active+clean+scrubbing+nonMappedState', 'pg-unknown');
+ testMethod('8 ', 'pg-unknown');
+ testMethod('', 'pg-unknown');
+ });
+ });
+
+ describe('custom row comparators', () => {
+ const expectCorrectComparator = (statsAttribute: string) => {
+ const mockPool = (v: number) => ({ stats: { [statsAttribute]: { latest: v } } });
+ const columnDefinition = _.find(
+ component.columns,
+ (column) => column.prop === `stats.${statsAttribute}.rates`
+ );
+ expect(columnDefinition.comparator(undefined, undefined, mockPool(2), mockPool(1))).toBe(1);
+ expect(columnDefinition.comparator(undefined, undefined, mockPool(1), mockPool(2))).toBe(-1);
+ };
+
+ it('compares read bytes correctly', () => {
+ expectCorrectComparator('rd_bytes');
+ });
+
+ it('compares write bytes correctly', () => {
+ expectCorrectComparator('wr_bytes');
+ });
+ });
+
+ describe('transformPoolsData', () => {
+ let pool: Pool;
+
+ const getPoolData = (o: object) => [
+ _.merge(
+ _.merge(Mocks.getPool('a', 0), {
+ cdIsBinary: true,
+ pg_status: '',
+ stats: {
+ bytes_used: { latest: 0, rate: 0, rates: [] },
+ max_avail: { latest: 0, rate: 0, rates: [] },
+ avail_raw: { latest: 0, rate: 0, rates: [] },
+ percent_used: { latest: 0, rate: 0, rates: [] },
+ rd: { latest: 0, rate: 0, rates: [] },
+ rd_bytes: { latest: 0, rate: 0, rates: [] },
+ wr: { latest: 0, rate: 0, rates: [] },
+ wr_bytes: { latest: 0, rate: 0, rates: [] }
+ },
+ usage: 0,
+ data_protection: 'replica: ×3'
+ }),
+ o
+ )
+ ];
+
+ beforeEach(() => {
+ pool = Mocks.getPool('a', 0);
+ });
+
+ it('transforms replicated pools data correctly', () => {
+ pool = _.merge(pool, {
+ stats: {
+ bytes_used: { latest: 5, rate: 0, rates: [] },
+ avail_raw: { latest: 15, rate: 0, rates: [] },
+ percent_used: { latest: 0.25, rate: 0, rates: [] },
+ rd_bytes: {
+ latest: 6,
+ rate: 4,
+ rates: [
+ [0, 2],
+ [1, 6]
+ ]
+ }
+ },
+ pg_status: { 'active+clean': 8, down: 2 }
+ });
+ expect(component.transformPoolsData([pool])).toEqual(
+ getPoolData({
+ pg_status: '8 active+clean, 2 down',
+ stats: {
+ bytes_used: { latest: 5, rate: 0, rates: [] },
+ avail_raw: { latest: 15, rate: 0, rates: [] },
+ percent_used: { latest: 0.25, rate: 0, rates: [] },
+ rd_bytes: { latest: 6, rate: 4, rates: [2, 6] }
+ },
+ usage: 0.25,
+ data_protection: 'replica: ×3'
+ })
+ );
+ });
+
+ it('transforms erasure pools data correctly', () => {
+ pool.type = 'erasure';
+ pool.erasure_code_profile = 'default';
+ component.ecProfileList = getECPProfiles();
+
+ expect(component.transformPoolsData([pool])).toEqual(
+ getPoolData({
+ type: 'erasure',
+ erasure_code_profile: 'default',
+ data_protection: 'EC: 2+1'
+ })
+ );
+ });
+
+ it('transforms pools data correctly if stats are missing', () => {
+ expect(component.transformPoolsData([pool])).toEqual(getPoolData({}));
+ });
+
+ it('transforms empty pools data correctly', () => {
+ expect(component.transformPoolsData(undefined)).toEqual(undefined);
+ expect(component.transformPoolsData([])).toEqual([]);
+ });
+
+ it('shows not marked pools in progress if pg_num does not match pg_num_target', () => {
+ const pools = [
+ _.merge(pool, {
+ pg_num: 32,
+ pg_num_target: 16,
+ pg_placement_num: 32,
+ pg_placement_num_target: 16
+ })
+ ];
+ expect(component.transformPoolsData(pools)).toEqual(
+ getPoolData({
+ cdExecuting: 'Updating',
+ pg_num: 32,
+ pg_num_target: 16,
+ pg_placement_num: 32,
+ pg_placement_num_target: 16,
+ data_protection: 'replica: ×3'
+ })
+ );
+ });
+
+ it('shows marked pools in progress as defined by task', () => {
+ const pools = [
+ _.merge(pool, {
+ pg_num: 32,
+ pg_num_target: 16,
+ pg_placement_num: 32,
+ pg_placement_num_target: 16,
+ cdExecuting: 'Updating... 50%'
+ })
+ ];
+ expect(component.transformPoolsData(pools)).toEqual(
+ getPoolData({
+ cdExecuting: 'Updating... 50%',
+ pg_num: 32,
+ pg_num_target: 16,
+ pg_placement_num: 32,
+ pg_placement_num_target: 16,
+ data_protection: 'replica: ×3'
+ })
+ );
+ });
+ });
+
+ describe('transformPgStatus', () => {
+ it('returns status groups correctly', () => {
+ const pgStatus = { 'active+clean': 8 };
+ const expected = '8 active+clean';
+
+ expect(component.transformPgStatus(pgStatus)).toEqual(expected);
+ });
+
+ it('returns separated status groups', () => {
+ const pgStatus = { 'active+clean': 8, down: 2 };
+ const expected = '8 active+clean, 2 down';
+
+ expect(component.transformPgStatus(pgStatus)).toEqual(expected);
+ });
+
+ it('returns separated statuses correctly', () => {
+ const pgStatus = { active: 8, down: 2 };
+ const expected = '8 active, 2 down';
+
+ expect(component.transformPgStatus(pgStatus)).toEqual(expected);
+ });
+
+ it('returns empty string', () => {
+ const pgStatus: any = undefined;
+ const expected = '';
+
+ expect(component.transformPgStatus(pgStatus)).toEqual(expected);
+ });
+ });
+
+ describe('getSelectionTiers', () => {
+ const setSelectionTiers = (tiers: number[]) => {
+ component.expandedRow = { tiers };
+ component.getSelectionTiers();
+ };
+
+ beforeEach(() => {
+ component.pools = getPoolList();
+ });
+
+ it('should select multiple existing cache tiers', () => {
+ setSelectionTiers([0, 1, 2]);
+ expect(component.cacheTiers).toEqual(getPoolList());
+ });
+
+ it('should select correct existing cache tier', () => {
+ setSelectionTiers([0]);
+ expect(component.cacheTiers).toEqual([Mocks.getPool('a', 0)]);
+ });
+
+ it('should not select cache tier if id is invalid', () => {
+ setSelectionTiers([-1]);
+ expect(component.cacheTiers).toEqual([]);
+ });
+
+ it('should not select cache tier if empty', () => {
+ setSelectionTiers([]);
+ expect(component.cacheTiers).toEqual([]);
+ });
+
+ it('should be able to selected one pool with multiple tiers, than with a single tier, than with no tiers', () => {
+ setSelectionTiers([0, 1, 2]);
+ expect(component.cacheTiers).toEqual(getPoolList());
+ setSelectionTiers([0]);
+ expect(component.cacheTiers).toEqual([Mocks.getPool('a', 0)]);
+ setSelectionTiers([]);
+ expect(component.cacheTiers).toEqual([]);
+ });
+ });
+
+ describe('getDisableDesc', () => {
+ beforeEach(() => {
+ component.selection.selected = [{ pool_name: 'foo' }];
+ });
+
+ it('should return message if mon_allow_pool_delete flag is set to false', () => {
+ component.monAllowPoolDelete = false;
+ expect(component.getDisableDesc()).toBe(
+ 'Pool deletion is disabled by the mon_allow_pool_delete configuration setting.'
+ );
+ });
+
+ it('should return false if mon_allow_pool_delete flag is set to true', () => {
+ component.monAllowPoolDelete = true;
+ expect(component.getDisableDesc()).toBeFalsy();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.ts
new file mode 100644
index 000000000..ba2d9cbe5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.ts
@@ -0,0 +1,332 @@
+import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import _ from 'lodash';
+import { mergeMap } from 'rxjs/operators';
+
+import { PgCategoryService } from '~/app/ceph/shared/pg-category.service';
+import { ConfigurationService } from '~/app/shared/api/configuration.service';
+import { ErasureCodeProfileService } from '~/app/shared/api/erasure-code-profile.service';
+import { PoolService } from '~/app/shared/api/pool.service';
+import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
+import { TableStatusViewCache } from '~/app/shared/classes/table-status-view-cache';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
+import { TableComponent } from '~/app/shared/datatable/table/table.component';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { ViewCacheStatus } from '~/app/shared/enum/view-cache-status.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { ErasureCodeProfile } from '~/app/shared/models/erasure-code-profile';
+import { ExecutingTask } from '~/app/shared/models/executing-task';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { Permissions } from '~/app/shared/models/permissions';
+import { DimlessPipe } from '~/app/shared/pipes/dimless.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { TaskListService } from '~/app/shared/services/task-list.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
+import { URLBuilderService } from '~/app/shared/services/url-builder.service';
+import { Pool } from '../pool';
+import { PoolStat, PoolStats } from '../pool-stat';
+
+const BASE_URL = 'pool';
+
+@Component({
+ selector: 'cd-pool-list',
+ templateUrl: './pool-list.component.html',
+ providers: [
+ TaskListService,
+ { provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }
+ ],
+ styleUrls: ['./pool-list.component.scss']
+})
+export class PoolListComponent extends ListWithDetails implements OnInit {
+ @ViewChild(TableComponent)
+ table: TableComponent;
+ @ViewChild('poolUsageTpl', { static: true })
+ poolUsageTpl: TemplateRef<any>;
+
+ @ViewChild('poolConfigurationSourceTpl')
+ poolConfigurationSourceTpl: TemplateRef<any>;
+
+ pools: Pool[];
+ columns: CdTableColumn[];
+ selection = new CdTableSelection();
+ executingTasks: ExecutingTask[] = [];
+ permissions: Permissions;
+ tableActions: CdTableAction[];
+ tableStatus = new TableStatusViewCache();
+ cacheTiers: any[] = [];
+ monAllowPoolDelete = false;
+ ecProfileList: ErasureCodeProfile[];
+
+ constructor(
+ private poolService: PoolService,
+ private taskWrapper: TaskWrapperService,
+ private ecpService: ErasureCodeProfileService,
+ private authStorageService: AuthStorageService,
+ public taskListService: TaskListService,
+ private modalService: ModalService,
+ private pgCategoryService: PgCategoryService,
+ private dimlessPipe: DimlessPipe,
+ private urlBuilder: URLBuilderService,
+ private configurationService: ConfigurationService,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ super();
+ this.permissions = this.authStorageService.getPermissions();
+ this.tableActions = [
+ {
+ permission: 'create',
+ icon: Icons.add,
+ routerLink: () => this.urlBuilder.getCreate(),
+ name: this.actionLabels.CREATE
+ },
+ {
+ permission: 'update',
+ icon: Icons.edit,
+ routerLink: () =>
+ this.urlBuilder.getEdit(encodeURIComponent(this.selection.first().pool_name)),
+ name: this.actionLabels.EDIT
+ },
+ {
+ permission: 'delete',
+ icon: Icons.destroy,
+ click: () => this.deletePoolModal(),
+ name: this.actionLabels.DELETE,
+ disable: this.getDisableDesc.bind(this)
+ }
+ ];
+
+ // Note, we need read permissions to get the 'mon_allow_pool_delete'
+ // configuration option.
+ if (this.permissions.configOpt.read) {
+ this.configurationService.get('mon_allow_pool_delete').subscribe((data: any) => {
+ if (_.has(data, 'value')) {
+ const monSection = _.find(data.value, (v) => {
+ return v.section === 'mon';
+ }) || { value: false };
+ this.monAllowPoolDelete = monSection.value === 'true' ? true : false;
+ }
+ });
+ }
+ }
+
+ ngOnInit() {
+ const compare = (prop: string, pool1: Pool, pool2: Pool) =>
+ _.get(pool1, prop) > _.get(pool2, prop) ? 1 : -1;
+ this.columns = [
+ {
+ prop: 'pool_name',
+ name: $localize`Name`,
+ flexGrow: 4,
+ cellTransformation: CellTemplate.executing
+ },
+ {
+ prop: 'data_protection',
+ name: $localize`Data Protection`,
+ cellTransformation: CellTemplate.badge,
+ customTemplateConfig: {
+ class: 'badge-background-gray'
+ },
+ flexGrow: 1.3
+ },
+ {
+ prop: 'application_metadata',
+ name: $localize`Applications`,
+ cellTransformation: CellTemplate.badge,
+ customTemplateConfig: {
+ class: 'badge-background-primary'
+ },
+ flexGrow: 1.5
+ },
+ {
+ prop: 'pg_status',
+ name: $localize`PG Status`,
+ flexGrow: 1.2,
+ cellClass: ({ row, column, value }): any => {
+ return this.getPgStatusCellClass(row, column, value);
+ }
+ },
+ {
+ prop: 'crush_rule',
+ name: $localize`Crush Ruleset`,
+ isHidden: true,
+ flexGrow: 2
+ },
+ {
+ name: $localize`Usage`,
+ prop: 'usage',
+ cellTemplate: this.poolUsageTpl,
+ flexGrow: 1.2
+ },
+ {
+ prop: 'stats.rd_bytes.rates',
+ name: $localize`Read bytes`,
+ comparator: (_valueA: any, _valueB: any, rowA: Pool, rowB: Pool) =>
+ compare('stats.rd_bytes.latest', rowA, rowB),
+ cellTransformation: CellTemplate.sparkline,
+ flexGrow: 1.5
+ },
+ {
+ prop: 'stats.wr_bytes.rates',
+ name: $localize`Write bytes`,
+ comparator: (_valueA: any, _valueB: any, rowA: Pool, rowB: Pool) =>
+ compare('stats.wr_bytes.latest', rowA, rowB),
+ cellTransformation: CellTemplate.sparkline,
+ flexGrow: 1.5
+ },
+ {
+ prop: 'stats.rd.rate',
+ name: $localize`Read ops`,
+ flexGrow: 1,
+ pipe: this.dimlessPipe,
+ cellTransformation: CellTemplate.perSecond
+ },
+ {
+ prop: 'stats.wr.rate',
+ name: $localize`Write ops`,
+ flexGrow: 1,
+ pipe: this.dimlessPipe,
+ cellTransformation: CellTemplate.perSecond
+ }
+ ];
+
+ this.taskListService.init(
+ () =>
+ this.ecpService.list().pipe(
+ mergeMap((ecProfileList: ErasureCodeProfile[]) => {
+ this.ecProfileList = ecProfileList;
+ return this.poolService.getList();
+ })
+ ),
+ undefined,
+ (pools) => {
+ this.pools = this.transformPoolsData(pools);
+ this.tableStatus = new TableStatusViewCache();
+ },
+ () => {
+ this.table.reset(); // Disable loading indicator.
+ this.tableStatus = new TableStatusViewCache(ViewCacheStatus.ValueException);
+ },
+ (task) => task.name.startsWith(`${BASE_URL}/`),
+ (pool, task) => task.metadata['pool_name'] === pool.pool_name,
+ { default: (metadata: any) => new Pool(metadata['pool_name']) }
+ );
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ deletePoolModal() {
+ const name = this.selection.first().pool_name;
+ this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: 'Pool',
+ itemNames: [name],
+ submitActionObservable: () =>
+ this.taskWrapper.wrapTaskAroundCall({
+ task: new FinishedTask(`${BASE_URL}/${URLVerbs.DELETE}`, { pool_name: name }),
+ call: this.poolService.delete(name)
+ })
+ });
+ }
+
+ getPgStatusCellClass(_row: any, _column: any, value: string): object {
+ return {
+ 'text-right': true,
+ [`pg-${this.pgCategoryService.getTypeByStates(value)}`]: true
+ };
+ }
+
+ getErasureCodeProfile(erasureCodeProfile: string) {
+ let ecpInfo = '';
+ _.forEach(this.ecProfileList, (ecpKey) => {
+ if (ecpKey['name'] === erasureCodeProfile) {
+ ecpInfo = `EC: ${ecpKey['k']}+${ecpKey['m']}`;
+ }
+ });
+ return ecpInfo;
+ }
+
+ transformPoolsData(pools: any) {
+ const requiredStats = [
+ 'bytes_used',
+ 'max_avail',
+ 'avail_raw',
+ 'percent_used',
+ 'rd_bytes',
+ 'wr_bytes',
+ 'rd',
+ 'wr'
+ ];
+ const emptyStat: PoolStat = { latest: 0, rate: 0, rates: [] };
+
+ _.forEach(pools, (pool: Pool) => {
+ pool['pg_status'] = this.transformPgStatus(pool['pg_status']);
+ const stats: PoolStats = {};
+ _.forEach(requiredStats, (stat) => {
+ stats[stat] = pool.stats && pool.stats[stat] ? pool.stats[stat] : emptyStat;
+ });
+ pool['stats'] = stats;
+ pool['usage'] = stats.percent_used.latest;
+
+ if (
+ !pool.cdExecuting &&
+ pool.pg_num + pool.pg_placement_num !== pool.pg_num_target + pool.pg_placement_num_target
+ ) {
+ pool['cdExecuting'] = 'Updating';
+ }
+
+ ['rd_bytes', 'wr_bytes'].forEach((stat) => {
+ pool.stats[stat].rates = pool.stats[stat].rates.map((point: any) => point[1]);
+ });
+ pool.cdIsBinary = true;
+
+ if (pool['type'] === 'erasure') {
+ const erasureCodeProfile = pool['erasure_code_profile'];
+ pool['data_protection'] = this.getErasureCodeProfile(erasureCodeProfile);
+ }
+ if (pool['type'] === 'replicated') {
+ pool['data_protection'] = `replica: ×${pool['size']}`;
+ }
+ });
+
+ return pools;
+ }
+
+ transformPgStatus(pgStatus: any): string {
+ const strings: string[] = [];
+ _.forEach(pgStatus, (count, state) => {
+ strings.push(`${count} ${state}`);
+ });
+
+ return strings.join(', ');
+ }
+
+ getSelectionTiers() {
+ if (typeof this.expandedRow !== 'undefined') {
+ const cacheTierIds = this.expandedRow['tiers'];
+ this.cacheTiers = this.pools.filter((pool) => cacheTierIds.includes(pool.pool));
+ }
+ }
+
+ getDisableDesc(): boolean | string {
+ if (this.selection?.hasSelection) {
+ if (!this.monAllowPoolDelete) {
+ return $localize`Pool deletion is disabled by the mon_allow_pool_delete configuration setting.`;
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ setExpandedRow(expandedRow: any) {
+ super.setExpandedRow(expandedRow);
+ this.getSelectionTiers();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-stat.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-stat.ts
new file mode 100644
index 000000000..9820be94a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-stat.ts
@@ -0,0 +1,16 @@
+export class PoolStat {
+ latest: number;
+ rate: number;
+ rates: number[];
+}
+
+export class PoolStats {
+ bytes_used?: PoolStat;
+ max_avail?: PoolStat;
+ avail_raw?: PoolStat;
+ percent_used?: PoolStat;
+ rd_bytes?: PoolStat;
+ wr_bytes?: PoolStat;
+ rd?: PoolStat;
+ wr?: PoolStat;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool.module.ts
new file mode 100644
index 000000000..3f01b9fd9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool.module.ts
@@ -0,0 +1,57 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterModule, Routes } from '@angular/router';
+
+import { NgbNavModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { ActionLabels, URLVerbs } from '~/app/shared/constants/app.constants';
+import { SharedModule } from '~/app/shared/shared.module';
+import { BlockModule } from '../block/block.module';
+import { CephSharedModule } from '../shared/ceph-shared.module';
+import { CrushRuleFormModalComponent } from './crush-rule-form-modal/crush-rule-form-modal.component';
+import { ErasureCodeProfileFormModalComponent } from './erasure-code-profile-form/erasure-code-profile-form-modal.component';
+import { PoolDetailsComponent } from './pool-details/pool-details.component';
+import { PoolFormComponent } from './pool-form/pool-form.component';
+import { PoolListComponent } from './pool-list/pool-list.component';
+
+@NgModule({
+ imports: [
+ CephSharedModule,
+ CommonModule,
+ NgbNavModule,
+ SharedModule,
+ RouterModule,
+ ReactiveFormsModule,
+ NgbTooltipModule,
+ BlockModule
+ ],
+ exports: [PoolListComponent, PoolFormComponent],
+ declarations: [
+ PoolListComponent,
+ PoolFormComponent,
+ ErasureCodeProfileFormModalComponent,
+ CrushRuleFormModalComponent,
+ PoolDetailsComponent
+ ]
+})
+export class PoolModule {}
+
+const routes: Routes = [
+ { path: '', component: PoolListComponent },
+ {
+ path: URLVerbs.CREATE,
+ component: PoolFormComponent,
+ data: { breadcrumbs: ActionLabels.CREATE }
+ },
+ {
+ path: `${URLVerbs.EDIT}/:name`,
+ component: PoolFormComponent,
+ data: { breadcrumbs: ActionLabels.EDIT }
+ }
+];
+
+@NgModule({
+ imports: [PoolModule, RouterModule.forChild(routes)]
+})
+export class RoutedPoolModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool.ts
new file mode 100644
index 000000000..55c70c6f5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool.ts
@@ -0,0 +1,73 @@
+import { ExecutingTask } from '~/app/shared/models/executing-task';
+import { PoolStats } from './pool-stat';
+
+export class Pool {
+ cache_target_full_ratio_micro: number;
+ fast_read: boolean;
+ stripe_width: number;
+ flags_names: string;
+ tier_of: number;
+ hit_set_grade_decay_rate: number;
+ use_gmt_hitset: boolean;
+ last_force_op_resend_preluminous: string;
+ quota_max_bytes: number;
+ erasure_code_profile: string;
+ expected_num_objects: number;
+ size: number;
+ snap_seq: number;
+ auid: number;
+ cache_min_flush_age: number;
+ hit_set_period: number;
+ min_read_recency_for_promote: number;
+ target_max_objects: number;
+ pg_num: number;
+ pg_num_target: number;
+ pg_num_pending: number;
+ pg_placement_num: number;
+ pg_placement_num_target: number;
+ pg_autoscale_mode: string;
+ pg_status: string;
+ type: string;
+ pool_name: string;
+ cache_min_evict_age: number;
+ cache_mode: string;
+ min_size: number;
+ cache_target_dirty_high_ratio_micro: number;
+ object_hash: number;
+ application_metadata: string[];
+ write_tier: number;
+ cache_target_dirty_ratio_micro: number;
+ pool: number;
+ removed_snaps: string;
+ cdExecuting?: string;
+ executingTasks?: ExecutingTask[];
+ crush_rule: string;
+ tiers: any[];
+ hit_set_params: {
+ type: string;
+ };
+ last_force_op_resend: string;
+ pool_snaps: any[];
+ quota_max_objects: number;
+ options: {
+ compression_algorithm?: string;
+ compression_max_blob_size?: number;
+ compression_min_blob_size?: number;
+ compression_mode?: string;
+ compression_required_ratio?: number;
+ };
+ hit_set_count: number;
+ flags: number;
+ target_max_bytes: number;
+ hit_set_search_last_n: number;
+ last_change: string;
+ min_write_recency_for_promote: number;
+ read_tier: number;
+ stats?: PoolStats;
+ cdIsBinary?: boolean;
+ configuration: { source: number; name: string; value: string }[];
+
+ constructor(name: string) {
+ this.pool_name = name;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-bucket-mfa-delete.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-bucket-mfa-delete.ts
new file mode 100644
index 000000000..531094087
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-bucket-mfa-delete.ts
@@ -0,0 +1,4 @@
+export enum RgwBucketMfaDelete {
+ ENABLED = 'Enabled',
+ DISABLED = 'Disabled'
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-bucket-versioning.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-bucket-versioning.ts
new file mode 100644
index 000000000..51048c65e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-bucket-versioning.ts
@@ -0,0 +1,4 @@
+export enum RgwBucketVersioning {
+ ENABLED = 'Enabled',
+ SUSPENDED = 'Suspended'
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-daemon.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-daemon.ts
new file mode 100644
index 000000000..445f2a5ac
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-daemon.ts
@@ -0,0 +1,10 @@
+export class RgwDaemon {
+ id: string;
+ service_map_id: string;
+ version: string;
+ server_hostname: string;
+ realm_name: string;
+ zonegroup_name: string;
+ zone_name: string;
+ default: boolean;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-capabilities.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-capabilities.ts
new file mode 100644
index 000000000..dac6986c7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-capabilities.ts
@@ -0,0 +1,15 @@
+export enum RgwUserAvailableCapability {
+ USERS = 'users',
+ BUCKETS = 'buckets',
+ METADATA = 'metadata',
+ USAGE = 'usage',
+ ZONE = 'zone'
+}
+
+export class RgwUserCapabilities {
+ static readonly capabilities = RgwUserAvailableCapability;
+
+ static getAll(): string[] {
+ return Object.values(RgwUserCapabilities.capabilities);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-capability.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-capability.ts
new file mode 100644
index 000000000..ee10088c0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-capability.ts
@@ -0,0 +1,4 @@
+export class RgwUserCapability {
+ type: string;
+ perm: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-s3-key.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-s3-key.ts
new file mode 100644
index 000000000..bcb953106
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-s3-key.ts
@@ -0,0 +1,6 @@
+export class RgwUserS3Key {
+ user: string;
+ generate_key?: boolean;
+ access_key: string;
+ secret_key: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-subuser.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-subuser.ts
new file mode 100644
index 000000000..788b6a291
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-subuser.ts
@@ -0,0 +1,6 @@
+export class RgwUserSubuser {
+ id: string;
+ permissions: string;
+ generate_secret?: boolean;
+ secret_key?: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-swift-key.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-swift-key.ts
new file mode 100644
index 000000000..26abd2a99
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-swift-key.ts
@@ -0,0 +1,4 @@
+export class RgwUserSwiftKey {
+ user: string;
+ secret_key: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html
new file mode 100644
index 000000000..bf4bdcb08
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html
@@ -0,0 +1,127 @@
+<ng-container *ngIf="selection">
+ <table class="table table-striped table-bordered">
+ <tbody>
+ <tr>
+ <td i18n
+ class="bold w-25">Name</td>
+ <td class="w-75">{{ selection.bid }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">ID</td>
+ <td>{{ selection.id }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Owner</td>
+ <td>{{ selection.owner }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Index type</td>
+ <td>{{ selection.index_type }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Placement rule</td>
+ <td>{{ selection.placement_rule }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Marker</td>
+ <td>{{ selection.marker }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Maximum marker</td>
+ <td>{{ selection.max_marker }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Version</td>
+ <td>{{ selection.ver }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Master version</td>
+ <td>{{ selection.master_ver }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Modification time</td>
+ <td>{{ selection.mtime | cdDate }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Zonegroup</td>
+ <td>{{ selection.zonegroup }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Versioning</td>
+ <td>{{ selection.versioning }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">MFA Delete</td>
+ <td>{{ selection.mfa_delete }}</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <!-- Bucket quota -->
+ <div *ngIf="selection.bucket_quota">
+ <legend i18n>Bucket quota</legend>
+ <table class="table table-striped table-bordered">
+ <tbody>
+ <tr>
+ <td i18n
+ class="bold w-25">Enabled</td>
+ <td class="w-75">{{ selection.bucket_quota.enabled | booleanText }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Maximum size</td>
+ <td *ngIf="selection.bucket_quota.max_size <= -1"
+ i18n>Unlimited</td>
+ <td *ngIf="selection.bucket_quota.max_size > -1">
+ {{ selection.bucket_quota.max_size | dimless }}
+ </td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Maximum objects</td>
+ <td *ngIf="selection.bucket_quota.max_objects <= -1"
+ i18n>Unlimited</td>
+ <td *ngIf="selection.bucket_quota.max_objects > -1">
+ {{ selection.bucket_quota.max_objects }}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <!-- Locking -->
+ <legend i18n>Locking</legend>
+ <table class="table table-striped table-bordered">
+ <tbody>
+ <tr>
+ <td i18n
+ class="bold w-25">Enabled</td>
+ <td class="w-75">{{ selection.lock_enabled | booleanText }}</td>
+ </tr>
+ <ng-container *ngIf="selection.lock_enabled">
+ <tr>
+ <td i18n
+ class="bold">Mode</td>
+ <td>{{ selection.lock_mode }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Days</td>
+ <td>{{ selection.lock_retention_period_days }}</td>
+ </tr>
+ </ng-container>
+ </tbody>
+ </table>
+</ng-container>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.scss
new file mode 100644
index 000000000..d293c9d98
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.scss
@@ -0,0 +1,7 @@
+table {
+ table-layout: fixed;
+}
+
+table td {
+ word-wrap: break-word;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.spec.ts
new file mode 100644
index 000000000..ca6e09f0c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.spec.ts
@@ -0,0 +1,42 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { of } from 'rxjs';
+
+import { RgwBucketService } from '~/app/shared/api/rgw-bucket.service';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RgwBucketDetailsComponent } from './rgw-bucket-details.component';
+
+describe('RgwBucketDetailsComponent', () => {
+ let component: RgwBucketDetailsComponent;
+ let fixture: ComponentFixture<RgwBucketDetailsComponent>;
+ let rgwBucketService: RgwBucketService;
+ let rgwBucketServiceGetSpy: jasmine.Spy;
+
+ configureTestBed({
+ declarations: [RgwBucketDetailsComponent],
+ imports: [SharedModule, HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ rgwBucketService = TestBed.inject(RgwBucketService);
+ rgwBucketServiceGetSpy = spyOn(rgwBucketService, 'get');
+ rgwBucketServiceGetSpy.and.returnValue(of(null));
+ fixture = TestBed.createComponent(RgwBucketDetailsComponent);
+ component = fixture.componentInstance;
+ component.selection = new CdTableSelection();
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should retrieve bucket full info', () => {
+ component.selection = { bid: 'bucket' };
+ component.ngOnChanges();
+ expect(rgwBucketServiceGetSpy).toHaveBeenCalled();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.ts
new file mode 100644
index 000000000..f9a351367
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.ts
@@ -0,0 +1,24 @@
+import { Component, Input, OnChanges } from '@angular/core';
+
+import { RgwBucketService } from '~/app/shared/api/rgw-bucket.service';
+
+@Component({
+ selector: 'cd-rgw-bucket-details',
+ templateUrl: './rgw-bucket-details.component.html',
+ styleUrls: ['./rgw-bucket-details.component.scss']
+})
+export class RgwBucketDetailsComponent implements OnChanges {
+ @Input()
+ selection: any;
+
+ constructor(private rgwBucketService: RgwBucketService) {}
+
+ ngOnChanges() {
+ if (this.selection) {
+ this.rgwBucketService.get(this.selection.bid).subscribe((bucket: object) => {
+ bucket['lock_retention_period_days'] = this.rgwBucketService.getLockDays(bucket);
+ this.selection = bucket;
+ });
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html
new file mode 100644
index 000000000..bad80a7f3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html
@@ -0,0 +1,291 @@
+<div class="cd-col-form"
+ *cdFormLoading="loading">
+ <form name="bucketForm"
+ #frm="ngForm"
+ [formGroup]="bucketForm"
+ novalidate>
+ <div class="card">
+ <div i18n="form title"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
+
+ <div class="card-body">
+ <!-- Id -->
+ <div class="form-group row"
+ *ngIf="editing">
+ <label i18n
+ class="cd-col-form-label"
+ for="id">Id</label>
+ <div class="cd-col-form-input">
+ <input id="id"
+ name="id"
+ class="form-control"
+ type="text"
+ formControlName="id"
+ readonly>
+ </div>
+ </div>
+
+ <!-- Name -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ [ngClass]="{required: !editing}"
+ for="bid"
+ i18n>Name</label>
+ <div class="cd-col-form-input">
+ <input id="bid"
+ name="bid"
+ class="form-control"
+ type="text"
+ i18n-placeholder
+ placeholder="Name..."
+ formControlName="bid"
+ [readonly]="editing"
+ [autofocus]="!editing">
+ <span class="invalid-feedback"
+ *ngIf="bucketForm.showError('bid', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="bucketForm.showError('bid', frm, 'bucketNameInvalid')"
+ i18n>Bucket names can only contain lowercase letters, numbers, periods and hyphens.</span>
+ <span class="invalid-feedback"
+ *ngIf="bucketForm.showError('bid', frm, 'bucketNameNotAllowed')"
+ i18n>The chosen name is already in use.</span>
+ <span class="invalid-feedback"
+ *ngIf="bucketForm.showError('bid', frm, 'containsUpperCase')"
+ i18n>Bucket names must not contain uppercase characters or underscores.</span>
+ <span class="invalid-feedback"
+ *ngIf="bucketForm.showError('bid', frm, 'lowerCaseOrNumber')"
+ i18n>Each label must start and end with a lowercase letter or a number.</span>
+ <span class="invalid-feedback"
+ *ngIf="bucketForm.showError('bid', frm, 'ipAddress')"
+ i18n>Bucket names cannot be formatted as IP address.</span>
+ <span class="invalid-feedback"
+ *ngIf="bucketForm.showError('bid', frm, 'onlyLowerCaseAndNumbers')"
+ i18n>Bucket labels cannot be empty and can only contain lowercase letters, numbers and hyphens.</span>
+ <span class="invalid-feedback"
+ *ngIf="bucketForm.showError('bid', frm, 'shouldBeInRange')"
+ i18n>Bucket names must be 3 to 63 characters long.</span>
+ </div>
+ </div>
+
+ <!-- Owner -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="owner"
+ i18n>Owner</label>
+ <div class="cd-col-form-input">
+ <select id="owner"
+ name="owner"
+ class="form-control"
+ formControlName="owner"
+ [autofocus]="editing">
+ <option i18n
+ *ngIf="owners === null"
+ [ngValue]="null">Loading...</option>
+ <option i18n
+ *ngIf="owners !== null"
+ [ngValue]="null">-- Select a user --</option>
+ <option *ngFor="let owner of owners"
+ [value]="owner">{{ owner }}</option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="bucketForm.showError('owner', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Placement target -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ [ngClass]="{required: !editing}"
+ for="placement-target"
+ i18n>Placement target</label>
+ <div class="cd-col-form-input">
+ <ng-template #placementTargetSelect>
+ <select id="placement-target"
+ name="placement-target"
+ formControlName="placement-target"
+ class="form-control">
+ <option i18n
+ *ngIf="placementTargets === null"
+ [ngValue]="null">Loading...</option>
+ <option i18n
+ *ngIf="placementTargets !== null"
+ [ngValue]="null">-- Select a placement target --</option>
+ <option *ngFor="let placementTarget of placementTargets"
+ [value]="placementTarget.name">{{ placementTarget.description }}</option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="bucketForm.showError('placement-target', frm, 'required')"
+ i18n>This field is required.</span>
+ </ng-template>
+ <ng-container *ngIf="editing; else placementTargetSelect">
+ <input id="placement-target"
+ name="placement-target"
+ formControlName="placement-target"
+ class="form-control"
+ type="text"
+ readonly>
+ </ng-container>
+ </div>
+ </div>
+
+ <!-- Versioning -->
+ <fieldset *ngIf="editing">
+ <legend class="cd-header"
+ i18n>Versioning</legend>
+
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ id="versioning"
+ name="versioning"
+ formControlName="versioning"
+ (change)="setMfaDeleteValidators()">
+ <label class="custom-control-label"
+ for="versioning"
+ i18n>Enabled</label>
+ <cd-helper>
+ <span i18n>Enables versioning for the objects in the bucket.</span>
+ </cd-helper>
+ </div>
+ </div>
+ </div>
+ </fieldset>
+
+ <!-- Multi-Factor Authentication -->
+ <fieldset *ngIf="editing">
+ <!-- MFA Delete -->
+ <legend class="cd-header"
+ i18n>Multi-Factor Authentication</legend>
+
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ id="mfa-delete"
+ name="mfa-delete"
+ formControlName="mfa-delete"
+ (change)="setMfaDeleteValidators()">
+ <label class="custom-control-label"
+ for="mfa-delete"
+ i18n>Delete enabled</label>
+ <cd-helper>
+ <span i18n>Enables MFA (multi-factor authentication) Delete, which requires additional authentication for changing the bucket versioning state.</span>
+ </cd-helper>
+ </div>
+ </div>
+ </div>
+ <div *ngIf="areMfaCredentialsRequired()"
+ class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="mfa-token-serial">Token Serial Number</label>
+ <div class="cd-col-form-input">
+ <input type="text"
+ id="mfa-token-serial"
+ name="mfa-token-serial"
+ formControlName="mfa-token-serial"
+ class="form-control">
+ <span class="invalid-feedback"
+ *ngIf="bucketForm.showError('mfa-token-serial', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+ <div *ngIf="areMfaCredentialsRequired()"
+ class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="mfa-token-pin">Token PIN</label>
+ <div class="cd-col-form-input">
+ <input type="text"
+ id="mfa-token-pin"
+ name="mfa-token-pin"
+ formControlName="mfa-token-pin"
+ class="form-control">
+ <span class="invalid-feedback"
+ *ngIf="bucketForm.showError('mfa-token-pin', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+ </fieldset>
+
+ <!-- Locking -->
+ <fieldset>
+ <legend class="cd-header"
+ i18n>Locking</legend>
+
+ <!-- Locking enabled -->
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="lock_enabled"
+ formControlName="lock_enabled"
+ type="checkbox">
+ <label class="custom-control-label"
+ for="lock_enabled"
+ i18n>Enabled</label>
+ <cd-helper>
+ <span i18n>Enables locking for the objects in the bucket. Locking can only be enabled while creating a bucket.</span>
+ </cd-helper>
+ </div>
+ </div>
+ </div>
+
+ <!-- Locking mode -->
+ <div *ngIf="bucketForm.getValue('lock_enabled')"
+ class="form-group row">
+ <label class="cd-col-form-label"
+ for="lock_mode"
+ i18n>Mode</label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ formControlName="lock_mode"
+ name="lock_mode"
+ id="lock_mode">
+ <option i18n
+ value="COMPLIANCE">Compliance</option>
+ <option i18n
+ value="GOVERNANCE">Governance</option>
+ </select>
+ </div>
+ </div>
+
+ <!-- Retention period (days) -->
+ <div *ngIf="bucketForm.getValue('lock_enabled')"
+ class="form-group row">
+ <label class="cd-col-form-label"
+ for="lock_retention_period_days">
+ <ng-container i18n>Days</ng-container>
+ <cd-helper i18n>The number of days that you want to specify for the default retention period that will be applied to new objects placed in this bucket.</cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="number"
+ id="lock_retention_period_days"
+ formControlName="lock_retention_period_days"
+ min="0">
+ <span class="invalid-feedback"
+ *ngIf="bucketForm.showError('lock_retention_period_days', frm, 'pattern')"
+ i18n>The entered value must be a positive integer.</span>
+ <span class="invalid-feedback"
+ *ngIf="bucketForm.showError('lock_retention_period_days', frm, 'lockDays')"
+ i18n>Retention Days must be a positive integer.</span>
+ </div>
+ </div>
+ </fieldset>
+
+ </div>
+ <div class="card-footer">
+ <cd-form-button-panel (submitActionEvent)="submit()"
+ [form]="bucketForm"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
+ wrappingClass="text-right"></cd-form-button-panel>
+ </div>
+ </div>
+ </form>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.spec.ts
new file mode 100644
index 000000000..704d79184
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.spec.ts
@@ -0,0 +1,300 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { Router } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import _ from 'lodash';
+import { ToastrModule } from 'ngx-toastr';
+import { of as observableOf } from 'rxjs';
+
+import { RgwBucketService } from '~/app/shared/api/rgw-bucket.service';
+import { RgwSiteService } from '~/app/shared/api/rgw-site.service';
+import { RgwUserService } from '~/app/shared/api/rgw-user.service';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
+import { RgwBucketMfaDelete } from '../models/rgw-bucket-mfa-delete';
+import { RgwBucketVersioning } from '../models/rgw-bucket-versioning';
+import { RgwBucketFormComponent } from './rgw-bucket-form.component';
+
+describe('RgwBucketFormComponent', () => {
+ let component: RgwBucketFormComponent;
+ let fixture: ComponentFixture<RgwBucketFormComponent>;
+ let rgwBucketService: RgwBucketService;
+ let getPlacementTargetsSpy: jasmine.Spy;
+ let rgwBucketServiceGetSpy: jasmine.Spy;
+ let enumerateSpy: jasmine.Spy;
+ let formHelper: FormHelper;
+
+ configureTestBed({
+ declarations: [RgwBucketFormComponent],
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ RouterTestingModule,
+ SharedModule,
+ ToastrModule.forRoot()
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RgwBucketFormComponent);
+ component = fixture.componentInstance;
+ rgwBucketService = TestBed.inject(RgwBucketService);
+ rgwBucketServiceGetSpy = spyOn(rgwBucketService, 'get');
+ getPlacementTargetsSpy = spyOn(TestBed.inject(RgwSiteService), 'get');
+ enumerateSpy = spyOn(TestBed.inject(RgwUserService), 'enumerate');
+ formHelper = new FormHelper(component.bucketForm);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('bucketNameValidator', () => {
+ it('should validate empty name', fakeAsync(() => {
+ formHelper.expectErrorChange('bid', '', 'required', true);
+ }));
+ });
+
+ describe('zonegroup and placement targets', () => {
+ it('should get zonegroup and placement targets', () => {
+ const payload: Record<string, any> = {
+ zonegroup: 'default',
+ placement_targets: [
+ {
+ name: 'default-placement',
+ data_pool: 'default.rgw.buckets.data'
+ },
+ {
+ name: 'placement-target2',
+ data_pool: 'placement-target2.rgw.buckets.data'
+ }
+ ]
+ };
+ getPlacementTargetsSpy.and.returnValue(observableOf(payload));
+ enumerateSpy.and.returnValue(observableOf([]));
+ fixture.detectChanges();
+
+ expect(component.zonegroup).toBe(payload.zonegroup);
+ const placementTargets = [];
+ for (const placementTarget of payload['placement_targets']) {
+ placementTarget[
+ 'description'
+ ] = `${placementTarget['name']} (pool: ${placementTarget['data_pool']})`;
+ placementTargets.push(placementTarget);
+ }
+ expect(component.placementTargets).toEqual(placementTargets);
+ });
+ });
+
+ describe('submit form', () => {
+ let notificationService: NotificationService;
+
+ beforeEach(() => {
+ spyOn(TestBed.inject(Router), 'navigate').and.stub();
+ notificationService = TestBed.inject(NotificationService);
+ spyOn(notificationService, 'show');
+ });
+
+ it('should validate name', () => {
+ component.editing = false;
+ component.createForm();
+ const control = component.bucketForm.get('bid');
+ expect(_.isFunction(control.asyncValidator)).toBeTruthy();
+ });
+
+ it('should not validate name', () => {
+ component.editing = true;
+ component.createForm();
+ const control = component.bucketForm.get('bid');
+ expect(control.asyncValidator).toBeNull();
+ });
+
+ it('tests create success notification', () => {
+ spyOn(rgwBucketService, 'create').and.returnValue(observableOf([]));
+ component.editing = false;
+ component.bucketForm.markAsDirty();
+ component.submit();
+ expect(notificationService.show).toHaveBeenCalledWith(
+ NotificationType.success,
+ `Created Object Gateway bucket 'null'`
+ );
+ });
+
+ it('tests update success notification', () => {
+ spyOn(rgwBucketService, 'update').and.returnValue(observableOf([]));
+ component.editing = true;
+ component.bucketForm.markAsDirty();
+ component.submit();
+ expect(notificationService.show).toHaveBeenCalledWith(
+ NotificationType.success,
+ `Updated Object Gateway bucket 'null'.`
+ );
+ });
+ });
+
+ describe('mfa credentials', () => {
+ const checkMfaCredentialsVisibility = (
+ fakeResponse: object,
+ versioningChecked: boolean,
+ mfaDeleteChecked: boolean,
+ expectedVisibility: boolean
+ ) => {
+ component['route'].params = observableOf({ bid: 'bid' });
+ component.editing = true;
+ rgwBucketServiceGetSpy.and.returnValue(observableOf(fakeResponse));
+ enumerateSpy.and.returnValue(observableOf([]));
+ component.ngOnInit();
+ component.bucketForm.patchValue({
+ versioning: versioningChecked,
+ 'mfa-delete': mfaDeleteChecked
+ });
+ fixture.detectChanges();
+
+ const mfaTokenSerial = fixture.debugElement.nativeElement.querySelector('#mfa-token-serial');
+ const mfaTokenPin = fixture.debugElement.nativeElement.querySelector('#mfa-token-pin');
+ if (expectedVisibility) {
+ expect(mfaTokenSerial).toBeTruthy();
+ expect(mfaTokenPin).toBeTruthy();
+ } else {
+ expect(mfaTokenSerial).toBeFalsy();
+ expect(mfaTokenPin).toBeFalsy();
+ }
+ };
+
+ it('inputs should be visible when required', () => {
+ checkMfaCredentialsVisibility(
+ {
+ versioning: RgwBucketVersioning.SUSPENDED,
+ mfa_delete: RgwBucketMfaDelete.DISABLED
+ },
+ false,
+ false,
+ false
+ );
+ checkMfaCredentialsVisibility(
+ {
+ versioning: RgwBucketVersioning.SUSPENDED,
+ mfa_delete: RgwBucketMfaDelete.DISABLED
+ },
+ true,
+ false,
+ false
+ );
+ checkMfaCredentialsVisibility(
+ {
+ versioning: RgwBucketVersioning.ENABLED,
+ mfa_delete: RgwBucketMfaDelete.DISABLED
+ },
+ false,
+ false,
+ false
+ );
+ checkMfaCredentialsVisibility(
+ {
+ versioning: RgwBucketVersioning.ENABLED,
+ mfa_delete: RgwBucketMfaDelete.ENABLED
+ },
+ true,
+ true,
+ false
+ );
+ checkMfaCredentialsVisibility(
+ {
+ versioning: RgwBucketVersioning.SUSPENDED,
+ mfa_delete: RgwBucketMfaDelete.DISABLED
+ },
+ false,
+ true,
+ true
+ );
+ checkMfaCredentialsVisibility(
+ {
+ versioning: RgwBucketVersioning.SUSPENDED,
+ mfa_delete: RgwBucketMfaDelete.ENABLED
+ },
+ false,
+ false,
+ true
+ );
+ checkMfaCredentialsVisibility(
+ {
+ versioning: RgwBucketVersioning.SUSPENDED,
+ mfa_delete: RgwBucketMfaDelete.ENABLED
+ },
+ true,
+ true,
+ true
+ );
+ checkMfaCredentialsVisibility(
+ {
+ versioning: RgwBucketVersioning.ENABLED,
+ mfa_delete: RgwBucketMfaDelete.ENABLED
+ },
+ false,
+ true,
+ true
+ );
+ });
+ });
+
+ describe('object locking', () => {
+ const expectPatternLockError = (value: string) => {
+ formHelper.setValue('lock_enabled', true, true);
+ formHelper.setValue('lock_retention_period_days', value);
+ formHelper.expectError('lock_retention_period_days', 'pattern');
+ };
+
+ const expectValidLockInputs = (enabled: boolean, mode: string, days: string) => {
+ formHelper.setValue('lock_enabled', enabled);
+ formHelper.setValue('lock_mode', mode);
+ formHelper.setValue('lock_retention_period_days', days);
+ ['lock_enabled', 'lock_mode', 'lock_retention_period_days'].forEach((name) => {
+ const control = component.bucketForm.get(name);
+ expect(control.valid).toBeTruthy();
+ expect(control.errors).toBeNull();
+ });
+ };
+
+ it('should check lock enabled checkbox [mode=create]', () => {
+ component.createForm();
+ const control = component.bucketForm.get('lock_enabled');
+ expect(control.disabled).toBeFalsy();
+ });
+
+ it('should check lock enabled checkbox [mode=edit]', () => {
+ component.editing = true;
+ component.createForm();
+ const control = component.bucketForm.get('lock_enabled');
+ expect(control.disabled).toBeTruthy();
+ });
+
+ it('should have the "lockDays" error', () => {
+ formHelper.setValue('lock_enabled', true);
+ const control = component.bucketForm.get('lock_retention_period_days');
+ control.updateValueAndValidity();
+ expect(control.value).toBe(0);
+ expect(control.invalid).toBeTruthy();
+ formHelper.expectError(control, 'lockDays');
+ });
+
+ it('should have the "pattern" error [1]', () => {
+ expectPatternLockError('-1');
+ });
+
+ it('should have the "pattern" error [2]', () => {
+ expectPatternLockError('1.2');
+ });
+
+ it('should have valid values [1]', () => {
+ expectValidLockInputs(true, 'Governance', '1');
+ });
+
+ it('should have valid values [2]', () => {
+ expectValidLockInputs(false, 'Compliance', '2');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts
new file mode 100644
index 000000000..1d5aede39
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts
@@ -0,0 +1,264 @@
+import { Component, OnInit } from '@angular/core';
+import { Validators } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+
+import _ from 'lodash';
+import { forkJoin } from 'rxjs';
+
+import { RgwBucketService } from '~/app/shared/api/rgw-bucket.service';
+import { RgwSiteService } from '~/app/shared/api/rgw-site.service';
+import { RgwUserService } from '~/app/shared/api/rgw-user.service';
+import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdForm } from '~/app/shared/forms/cd-form';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { RgwBucketMfaDelete } from '../models/rgw-bucket-mfa-delete';
+import { RgwBucketVersioning } from '../models/rgw-bucket-versioning';
+
+@Component({
+ selector: 'cd-rgw-bucket-form',
+ templateUrl: './rgw-bucket-form.component.html',
+ styleUrls: ['./rgw-bucket-form.component.scss']
+})
+export class RgwBucketFormComponent extends CdForm implements OnInit {
+ bucketForm: CdFormGroup;
+ editing = false;
+ owners: string[] = null;
+ action: string;
+ resource: string;
+ zonegroup: string;
+ placementTargets: object[] = [];
+ isVersioningAlreadyEnabled = false;
+ isMfaDeleteAlreadyEnabled = false;
+ icons = Icons;
+
+ get isVersioningEnabled(): boolean {
+ return this.bucketForm.getValue('versioning');
+ }
+ get isMfaDeleteEnabled(): boolean {
+ return this.bucketForm.getValue('mfa-delete');
+ }
+
+ constructor(
+ private route: ActivatedRoute,
+ private router: Router,
+ private formBuilder: CdFormBuilder,
+ private rgwBucketService: RgwBucketService,
+ private rgwSiteService: RgwSiteService,
+ private rgwUserService: RgwUserService,
+ private notificationService: NotificationService,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ super();
+ this.editing = this.router.url.startsWith(`/rgw/bucket/${URLVerbs.EDIT}`);
+ this.action = this.editing ? this.actionLabels.EDIT : this.actionLabels.CREATE;
+ this.resource = $localize`bucket`;
+ this.createForm();
+ }
+
+ createForm() {
+ const self = this;
+ const lockDaysValidator = CdValidators.custom('lockDays', () => {
+ if (!self.bucketForm || !_.get(self.bucketForm.getRawValue(), 'lock_enabled')) {
+ return false;
+ }
+ const lockDays = Number(self.bucketForm.getValue('lock_retention_period_days'));
+ return !Number.isInteger(lockDays) || lockDays === 0;
+ });
+ this.bucketForm = this.formBuilder.group({
+ id: [null],
+ bid: [
+ null,
+ [Validators.required],
+ this.editing
+ ? []
+ : [CdValidators.bucketName(), CdValidators.bucketExistence(false, this.rgwBucketService)]
+ ],
+ owner: [null, [Validators.required]],
+ 'placement-target': [null, this.editing ? [] : [Validators.required]],
+ versioning: [null],
+ 'mfa-delete': [null],
+ 'mfa-token-serial': [''],
+ 'mfa-token-pin': [''],
+ lock_enabled: [{ value: false, disabled: this.editing }],
+ lock_mode: ['COMPLIANCE'],
+ lock_retention_period_days: [0, [CdValidators.number(false), lockDaysValidator]]
+ });
+ }
+
+ ngOnInit() {
+ const promises = {
+ owners: this.rgwUserService.enumerate()
+ };
+
+ if (!this.editing) {
+ promises['getPlacementTargets'] = this.rgwSiteService.get('placement-targets');
+ }
+
+ // Process route parameters.
+ this.route.params.subscribe((params: { bid: string }) => {
+ if (params.hasOwnProperty('bid')) {
+ const bid = decodeURIComponent(params.bid);
+ promises['getBid'] = this.rgwBucketService.get(bid);
+ }
+
+ forkJoin(promises).subscribe((data: any) => {
+ // Get the list of possible owners.
+ this.owners = (<string[]>data.owners).sort();
+
+ // Get placement targets:
+ if (data['getPlacementTargets']) {
+ const placementTargets = data['getPlacementTargets'];
+ this.zonegroup = placementTargets['zonegroup'];
+ _.forEach(placementTargets['placement_targets'], (placementTarget) => {
+ placementTarget['description'] = `${placementTarget['name']} (${$localize`pool`}: ${
+ placementTarget['data_pool']
+ })`;
+ this.placementTargets.push(placementTarget);
+ });
+
+ // If there is only 1 placement target, select it by default:
+ if (this.placementTargets.length === 1) {
+ this.bucketForm.get('placement-target').setValue(this.placementTargets[0]['name']);
+ }
+ }
+
+ if (data['getBid']) {
+ const bidResp = data['getBid'];
+ // Get the default values (incl. the values from disabled fields).
+ const defaults = _.clone(this.bucketForm.getRawValue());
+
+ // Get the values displayed in the form. We need to do that to
+ // extract those key/value pairs from the response data, otherwise
+ // the Angular react framework will throw an error if there is no
+ // field for a given key.
+ let value: object = _.pick(bidResp, _.keys(defaults));
+ value['lock_retention_period_days'] = this.rgwBucketService.getLockDays(bidResp);
+ value['placement-target'] = bidResp['placement_rule'];
+ value['versioning'] = bidResp['versioning'] === RgwBucketVersioning.ENABLED;
+ value['mfa-delete'] = bidResp['mfa_delete'] === RgwBucketMfaDelete.ENABLED;
+
+ // Append default values.
+ value = _.merge(defaults, value);
+
+ // Update the form.
+ this.bucketForm.setValue(value);
+ if (this.editing) {
+ this.isVersioningAlreadyEnabled = this.isVersioningEnabled;
+ this.isMfaDeleteAlreadyEnabled = this.isMfaDeleteEnabled;
+ this.setMfaDeleteValidators();
+ if (value['lock_enabled']) {
+ this.bucketForm.controls['versioning'].disable();
+ }
+ }
+ }
+
+ this.loadingReady();
+ });
+ });
+ }
+
+ goToListView() {
+ this.router.navigate(['/rgw/bucket']);
+ }
+
+ submit() {
+ // Exit immediately if the form isn't dirty.
+ if (this.bucketForm.pristine) {
+ this.goToListView();
+ return;
+ }
+ const values = this.bucketForm.value;
+ if (this.editing) {
+ // Edit
+ const versioning = this.getVersioningStatus();
+ const mfaDelete = this.getMfaDeleteStatus();
+ this.rgwBucketService
+ .update(
+ values['bid'],
+ values['id'],
+ values['owner'],
+ versioning,
+ mfaDelete,
+ values['mfa-token-serial'],
+ values['mfa-token-pin'],
+ values['lock_mode'],
+ values['lock_retention_period_days']
+ )
+ .subscribe(
+ () => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Updated Object Gateway bucket '${values.bid}'.`
+ );
+ this.goToListView();
+ },
+ () => {
+ // Reset the 'Submit' button.
+ this.bucketForm.setErrors({ cdSubmitButton: true });
+ }
+ );
+ } else {
+ // Add
+ this.rgwBucketService
+ .create(
+ values['bid'],
+ values['owner'],
+ this.zonegroup,
+ values['placement-target'],
+ values['lock_enabled'],
+ values['lock_mode'],
+ values['lock_retention_period_days']
+ )
+ .subscribe(
+ () => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Created Object Gateway bucket '${values.bid}'`
+ );
+ this.goToListView();
+ },
+ () => {
+ // Reset the 'Submit' button.
+ this.bucketForm.setErrors({ cdSubmitButton: true });
+ }
+ );
+ }
+ }
+
+ areMfaCredentialsRequired() {
+ return (
+ this.isMfaDeleteEnabled !== this.isMfaDeleteAlreadyEnabled ||
+ (this.isMfaDeleteAlreadyEnabled &&
+ this.isVersioningEnabled !== this.isVersioningAlreadyEnabled)
+ );
+ }
+
+ setMfaDeleteValidators() {
+ const mfaTokenSerialControl = this.bucketForm.get('mfa-token-serial');
+ const mfaTokenPinControl = this.bucketForm.get('mfa-token-pin');
+
+ if (this.areMfaCredentialsRequired()) {
+ mfaTokenSerialControl.setValidators(Validators.required);
+ mfaTokenPinControl.setValidators(Validators.required);
+ } else {
+ mfaTokenSerialControl.setValidators(null);
+ mfaTokenPinControl.setValidators(null);
+ }
+
+ mfaTokenSerialControl.updateValueAndValidity();
+ mfaTokenPinControl.updateValueAndValidity();
+ }
+
+ getVersioningStatus() {
+ return this.isVersioningEnabled ? RgwBucketVersioning.ENABLED : RgwBucketVersioning.SUSPENDED;
+ }
+
+ getMfaDeleteStatus() {
+ return this.isMfaDeleteEnabled ? RgwBucketMfaDelete.ENABLED : RgwBucketMfaDelete.DISABLED;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html
new file mode 100644
index 000000000..b5e75841a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html
@@ -0,0 +1,44 @@
+<cd-table #table
+ [autoReload]="false"
+ [data]="buckets"
+ [columns]="columns"
+ columnMode="flex"
+ selectionType="multiClick"
+ [hasDetails]="true"
+ (setExpandedRow)="setExpandedRow($event)"
+ (updateSelection)="updateSelection($event)"
+ identifier="bid"
+ (fetchData)="getBucketList($event)"
+ [status]="tableStatus">
+ <cd-table-actions class="table-actions"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ <cd-rgw-bucket-details cdTableDetail
+ [selection]="expandedRow">
+ </cd-rgw-bucket-details>
+</cd-table>
+
+<ng-template #bucketSizeTpl
+ let-row="row">
+ <cd-usage-bar *ngIf="row.bucket_quota.max_size > 0 && row.bucket_quota.enabled; else noSizeQuota"
+ [total]="row.bucket_quota.max_size"
+ [used]="row.bucket_size">
+ </cd-usage-bar>
+
+ <ng-template #noSizeQuota
+ i18n>No Limit</ng-template>
+</ng-template>
+
+<ng-template #bucketObjectTpl
+ let-row="row">
+ <cd-usage-bar *ngIf="row.bucket_quota.max_objects > 0 && row.bucket_quota.enabled; else noObjectQuota"
+ [total]="row.bucket_quota.max_objects"
+ [used]="row.num_objects"
+ [isBinary]="false">
+ </cd-usage-bar>
+
+ <ng-template #noObjectQuota
+ i18n>No Limit</ng-template>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.spec.ts
new file mode 100644
index 000000000..ff0705793
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.spec.ts
@@ -0,0 +1,178 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { of } from 'rxjs';
+
+import { RgwBucketService } from '~/app/shared/api/rgw-bucket.service';
+import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, PermissionHelper } from '~/testing/unit-test-helper';
+import { RgwBucketDetailsComponent } from '../rgw-bucket-details/rgw-bucket-details.component';
+import { RgwBucketListComponent } from './rgw-bucket-list.component';
+
+describe('RgwBucketListComponent', () => {
+ let component: RgwBucketListComponent;
+ let fixture: ComponentFixture<RgwBucketListComponent>;
+ let rgwBucketService: RgwBucketService;
+ let rgwBucketServiceListSpy: jasmine.Spy;
+
+ configureTestBed({
+ declarations: [RgwBucketListComponent, RgwBucketDetailsComponent],
+ imports: [
+ BrowserAnimationsModule,
+ RouterTestingModule,
+ SharedModule,
+ NgbNavModule,
+ HttpClientTestingModule
+ ]
+ });
+
+ beforeEach(() => {
+ rgwBucketService = TestBed.inject(RgwBucketService);
+ rgwBucketServiceListSpy = spyOn(rgwBucketService, 'list');
+ rgwBucketServiceListSpy.and.returnValue(of([]));
+ fixture = TestBed.createComponent(RgwBucketListComponent);
+ component = fixture.componentInstance;
+ spyOn(component, 'setTableRefreshTimeout').and.stub();
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ expect(rgwBucketServiceListSpy).toHaveBeenCalledTimes(1);
+ });
+
+ it('should test all TableActions combinations', () => {
+ const permissionHelper: PermissionHelper = new PermissionHelper(component.permission);
+ const tableActions: TableActionsComponent = permissionHelper.setPermissionsAndGetActions(
+ component.tableActions
+ );
+
+ expect(tableActions).toEqual({
+ 'create,update,delete': {
+ actions: ['Create', 'Edit', 'Delete'],
+ primary: { multiple: 'Delete', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,update': {
+ actions: ['Create', 'Edit'],
+ primary: { multiple: 'Create', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,delete': {
+ actions: ['Create', 'Delete'],
+ primary: { multiple: 'Delete', executing: 'Create', single: 'Create', no: 'Create' }
+ },
+ create: {
+ actions: ['Create'],
+ primary: { multiple: 'Create', executing: 'Create', single: 'Create', no: 'Create' }
+ },
+ 'update,delete': {
+ actions: ['Edit', 'Delete'],
+ primary: { multiple: 'Delete', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ update: {
+ actions: ['Edit'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ delete: {
+ actions: ['Delete'],
+ primary: { multiple: 'Delete', executing: 'Delete', single: 'Delete', no: 'Delete' }
+ },
+ 'no-permissions': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ }
+ });
+ });
+
+ it('should test if bucket data is tranformed correctly', () => {
+ rgwBucketServiceListSpy.and.returnValue(
+ of([
+ {
+ bucket: 'bucket',
+ owner: 'testid',
+ usage: {
+ 'rgw.main': {
+ size_actual: 4,
+ num_objects: 2
+ },
+ 'rgw.none': {
+ size_actual: 6,
+ num_objects: 6
+ }
+ },
+ bucket_quota: {
+ max_size: 20,
+ max_objects: 10,
+ enabled: true
+ }
+ }
+ ])
+ );
+ component.getBucketList(null);
+ expect(rgwBucketServiceListSpy).toHaveBeenCalledTimes(2);
+ expect(component.buckets).toEqual([
+ {
+ bucket: 'bucket',
+ owner: 'testid',
+ usage: {
+ 'rgw.main': { size_actual: 4, num_objects: 2 },
+ 'rgw.none': { size_actual: 6, num_objects: 6 }
+ },
+ bucket_quota: {
+ max_size: 20,
+ max_objects: 10,
+ enabled: true
+ },
+ bucket_size: 4,
+ num_objects: 2,
+ size_usage: 0.2,
+ object_usage: 0.2
+ }
+ ]);
+ });
+
+ it('should usage bars only if quota enabled', () => {
+ rgwBucketServiceListSpy.and.returnValue(
+ of([
+ {
+ bucket: 'bucket',
+ owner: 'testid',
+ bucket_quota: {
+ max_size: 1024,
+ max_objects: 10,
+ enabled: true
+ }
+ }
+ ])
+ );
+ component.getBucketList(null);
+ expect(rgwBucketServiceListSpy).toHaveBeenCalledTimes(2);
+ fixture.detectChanges();
+ const usageBars = fixture.debugElement.nativeElement.querySelectorAll('cd-usage-bar');
+ expect(usageBars.length).toBe(2);
+ });
+
+ it('should not show any usage bars if quota disabled', () => {
+ rgwBucketServiceListSpy.and.returnValue(
+ of([
+ {
+ bucket: 'bucket',
+ owner: 'testid',
+ bucket_quota: {
+ max_size: 1024,
+ max_objects: 10,
+ enabled: false
+ }
+ }
+ ])
+ );
+ component.getBucketList(null);
+ expect(rgwBucketServiceListSpy).toHaveBeenCalledTimes(2);
+ fixture.detectChanges();
+ const usageBars = fixture.debugElement.nativeElement.querySelectorAll('cd-usage-bar');
+ expect(usageBars.length).toBe(0);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts
new file mode 100644
index 000000000..479da864a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts
@@ -0,0 +1,188 @@
+import { Component, NgZone, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import _ from 'lodash';
+import { forkJoin as observableForkJoin, Observable, Subscriber } from 'rxjs';
+
+import { RgwBucketService } from '~/app/shared/api/rgw-bucket.service';
+import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { TableComponent } from '~/app/shared/datatable/table/table.component';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { Permission } from '~/app/shared/models/permissions';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { DimlessPipe } from '~/app/shared/pipes/dimless.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { URLBuilderService } from '~/app/shared/services/url-builder.service';
+
+const BASE_URL = 'rgw/bucket';
+
+@Component({
+ selector: 'cd-rgw-bucket-list',
+ templateUrl: './rgw-bucket-list.component.html',
+ styleUrls: ['./rgw-bucket-list.component.scss'],
+ providers: [{ provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }]
+})
+export class RgwBucketListComponent extends ListWithDetails implements OnInit {
+ @ViewChild(TableComponent, { static: true })
+ table: TableComponent;
+ @ViewChild('bucketSizeTpl', { static: true })
+ bucketSizeTpl: TemplateRef<any>;
+ @ViewChild('bucketObjectTpl', { static: true })
+ bucketObjectTpl: TemplateRef<any>;
+
+ permission: Permission;
+ tableActions: CdTableAction[];
+ columns: CdTableColumn[] = [];
+ buckets: object[] = [];
+ selection: CdTableSelection = new CdTableSelection();
+ staleTimeout: number;
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private dimlessBinaryPipe: DimlessBinaryPipe,
+ private dimlessPipe: DimlessPipe,
+ private rgwBucketService: RgwBucketService,
+ private modalService: ModalService,
+ private urlBuilder: URLBuilderService,
+ public actionLabels: ActionLabelsI18n,
+ protected ngZone: NgZone
+ ) {
+ super(ngZone);
+ }
+
+ ngOnInit() {
+ this.permission = this.authStorageService.getPermissions().rgw;
+ this.columns = [
+ {
+ name: $localize`Name`,
+ prop: 'bid',
+ flexGrow: 2
+ },
+ {
+ name: $localize`Owner`,
+ prop: 'owner',
+ flexGrow: 2.5
+ },
+ {
+ name: $localize`Used Capacity`,
+ prop: 'bucket_size',
+ flexGrow: 0.6,
+ pipe: this.dimlessBinaryPipe
+ },
+ {
+ name: $localize`Capacity Limit %`,
+ prop: 'size_usage',
+ cellTemplate: this.bucketSizeTpl,
+ flexGrow: 0.8
+ },
+ {
+ name: $localize`Objects`,
+ prop: 'num_objects',
+ flexGrow: 0.6,
+ pipe: this.dimlessPipe
+ },
+ {
+ name: $localize`Object Limit %`,
+ prop: 'object_usage',
+ cellTemplate: this.bucketObjectTpl,
+ flexGrow: 0.8
+ }
+ ];
+ const getBucketUri = () =>
+ this.selection.first() && `${encodeURIComponent(this.selection.first().bid)}`;
+ const addAction: CdTableAction = {
+ permission: 'create',
+ icon: Icons.add,
+ routerLink: () => this.urlBuilder.getCreate(),
+ name: this.actionLabels.CREATE,
+ canBePrimary: (selection: CdTableSelection) => !selection.hasSelection
+ };
+ const editAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.edit,
+ routerLink: () => this.urlBuilder.getEdit(getBucketUri()),
+ name: this.actionLabels.EDIT
+ };
+ const deleteAction: CdTableAction = {
+ permission: 'delete',
+ icon: Icons.destroy,
+ click: () => this.deleteAction(),
+ disable: () => !this.selection.hasSelection,
+ name: this.actionLabels.DELETE,
+ canBePrimary: (selection: CdTableSelection) => selection.hasMultiSelection
+ };
+ this.tableActions = [addAction, editAction, deleteAction];
+ this.setTableRefreshTimeout();
+ }
+
+ transformBucketData() {
+ _.forEach(this.buckets, (bucketKey) => {
+ const maxBucketSize = bucketKey['bucket_quota']['max_size'];
+ const maxBucketObjects = bucketKey['bucket_quota']['max_objects'];
+ bucketKey['bucket_size'] = 0;
+ bucketKey['num_objects'] = 0;
+ if (!_.isEmpty(bucketKey['usage'])) {
+ bucketKey['bucket_size'] = bucketKey['usage']['rgw.main']['size_actual'];
+ bucketKey['num_objects'] = bucketKey['usage']['rgw.main']['num_objects'];
+ }
+ bucketKey['size_usage'] =
+ maxBucketSize > 0 ? bucketKey['bucket_size'] / maxBucketSize : undefined;
+ bucketKey['object_usage'] =
+ maxBucketObjects > 0 ? bucketKey['num_objects'] / maxBucketObjects : undefined;
+ });
+ }
+
+ getBucketList(context: CdTableFetchDataContext) {
+ this.setTableRefreshTimeout();
+ this.rgwBucketService.list(true).subscribe(
+ (resp: object[]) => {
+ this.buckets = resp;
+ this.transformBucketData();
+ },
+ () => {
+ context.error();
+ }
+ );
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ deleteAction() {
+ this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: this.selection.hasSingleSelection ? $localize`bucket` : $localize`buckets`,
+ itemNames: this.selection.selected.map((bucket: any) => bucket['bid']),
+ submitActionObservable: () => {
+ return new Observable((observer: Subscriber<any>) => {
+ // Delete all selected data table rows.
+ observableForkJoin(
+ this.selection.selected.map((bucket: any) => {
+ return this.rgwBucketService.delete(bucket.bid);
+ })
+ ).subscribe({
+ error: (error) => {
+ // Forward the error to the observer.
+ observer.error(error);
+ // Reload the data table content because some deletions might
+ // have been executed successfully in the meanwhile.
+ this.table.refreshBtn();
+ },
+ complete: () => {
+ // Notify the observer that we are done.
+ observer.complete();
+ // Reload the data table content.
+ this.table.refreshBtn();
+ }
+ });
+ });
+ }
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html
new file mode 100644
index 000000000..e53eaa8f7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html
@@ -0,0 +1,38 @@
+<ng-container *ngIf="selection">
+ <ul ngbNav
+ #nav="ngbNav"
+ class="nav-tabs"
+ cdStatefulTab="rgw-daemon-details">
+ <li ngbNavItem="details">
+ <a ngbNavLink
+ i18n>Details</a>
+ <ng-template ngbNavContent>
+ <cd-table-key-value [data]="metadata"
+ (fetchData)="getMetaData()">
+ </cd-table-key-value>
+ </ng-template>
+ </li>
+ <li ngbNavItem="performance-counters">
+ <a ngbNavLink
+ i18n>Performance Counters</a>
+ <ng-template ngbNavContent>
+ <cd-table-performance-counter serviceType="rgw"
+ [serviceId]="serviceMapId">
+ </cd-table-performance-counter>
+ </ng-template>
+ </li>
+ <li ngbNavItem="performance-details"
+ *ngIf="grafanaPermission.read">
+ <a ngbNavLink
+ i18n>Performance Details</a>
+ <ng-template ngbNavContent>
+ <cd-grafana [grafanaPath]="'rgw-instance-detail?var-rgw_servers=rgw.' + this.serviceId"
+ uid="x5ARzZtmk"
+ grafanaStyle="one">
+ </cd-grafana>
+ </ng-template>
+ </li>
+ </ul>
+
+ <div [ngbNavOutlet]="nav"></div>
+</ng-container>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.spec.ts
new file mode 100644
index 000000000..40ea5a043
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.spec.ts
@@ -0,0 +1,42 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { PerformanceCounterModule } from '~/app/ceph/performance-counter/performance-counter.module';
+import { RgwDaemon } from '~/app/ceph/rgw/models/rgw-daemon';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RgwDaemonDetailsComponent } from './rgw-daemon-details.component';
+
+describe('RgwDaemonDetailsComponent', () => {
+ let component: RgwDaemonDetailsComponent;
+ let fixture: ComponentFixture<RgwDaemonDetailsComponent>;
+
+ configureTestBed({
+ declarations: [RgwDaemonDetailsComponent],
+ imports: [SharedModule, PerformanceCounterModule, HttpClientTestingModule, NgbNavModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RgwDaemonDetailsComponent);
+ component = fixture.componentInstance;
+ component.selection = undefined;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should set service id and service map id on changes', () => {
+ const daemon = new RgwDaemon();
+ daemon.id = 'daemon1';
+ daemon.service_map_id = '4832';
+ component.selection = daemon;
+ component.ngOnChanges();
+
+ expect(component.serviceId).toBe(daemon.id);
+ expect(component.serviceMapId).toBe(daemon.service_map_id);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.ts
new file mode 100644
index 000000000..38a309e0a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.ts
@@ -0,0 +1,46 @@
+import { Component, Input, OnChanges } from '@angular/core';
+
+import _ from 'lodash';
+
+import { RgwDaemon } from '~/app/ceph/rgw/models/rgw-daemon';
+import { RgwDaemonService } from '~/app/shared/api/rgw-daemon.service';
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+
+@Component({
+ selector: 'cd-rgw-daemon-details',
+ templateUrl: './rgw-daemon-details.component.html',
+ styleUrls: ['./rgw-daemon-details.component.scss']
+})
+export class RgwDaemonDetailsComponent implements OnChanges {
+ metadata: any;
+ serviceId = '';
+ serviceMapId = '';
+ grafanaPermission: Permission;
+
+ @Input()
+ selection: RgwDaemon;
+
+ constructor(
+ private rgwDaemonService: RgwDaemonService,
+ private authStorageService: AuthStorageService
+ ) {
+ this.grafanaPermission = this.authStorageService.getPermissions().grafana;
+ }
+
+ ngOnChanges() {
+ if (this.selection) {
+ this.serviceId = this.selection.id;
+ this.serviceMapId = this.selection.service_map_id;
+ }
+ }
+
+ getMetaData() {
+ if (_.isEmpty(this.serviceId)) {
+ return;
+ }
+ this.rgwDaemonService.get(this.serviceId).subscribe((resp: any) => {
+ this.metadata = resp['rgw_metadata'];
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html
new file mode 100644
index 000000000..38683a6f6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html
@@ -0,0 +1,46 @@
+<ul ngbNav
+ #nav="ngbNav"
+ class="nav-tabs">
+ <li ngbNavItem>
+ <a ngbNavLink
+ i18n>Daemons List</a>
+ <ng-template ngbNavContent>
+ <cd-table [data]="daemons"
+ [columns]="columns"
+ columnMode="flex"
+ [hasDetails]="true"
+ (setExpandedRow)="setExpandedRow($event)"
+ (fetchData)="getDaemonList($event)">
+ <cd-rgw-daemon-details cdTableDetail
+ [selection]="expandedRow">
+ </cd-rgw-daemon-details>
+ </cd-table>
+ </ng-template>
+ </li>
+
+ <li ngbNavItem
+ *ngIf="grafanaPermission.read">
+ <a ngbNavLink
+ i18n>Overall Performance</a>
+ <ng-template ngbNavContent>
+ <cd-grafana [grafanaPath]="'rgw-overview?'"
+ uid="WAkugZpiz"
+ grafanaStyle="two">
+ </cd-grafana>
+ </ng-template>
+ </li>
+
+ <li ngbNavItem
+ *ngIf="grafanaPermission.read && isMultiSite">
+ <a ngbNavLink
+ i18n>Sync Performance</a>
+ <ng-template ngbNavContent>
+ <cd-grafana [grafanaPath]="'radosgw-sync-overview?'"
+ uid="rgw-sync-overview"
+ grafanaStyle="two">
+ </cd-grafana>
+ </ng-template>
+ </li>
+</ul>
+
+<div [ngbNavOutlet]="nav"></div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.spec.ts
new file mode 100644
index 000000000..ecf0bedf9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.spec.ts
@@ -0,0 +1,106 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { of } from 'rxjs';
+
+import { PerformanceCounterModule } from '~/app/ceph/performance-counter/performance-counter.module';
+import { RgwDaemon } from '~/app/ceph/rgw/models/rgw-daemon';
+import { RgwDaemonService } from '~/app/shared/api/rgw-daemon.service';
+import { RgwSiteService } from '~/app/shared/api/rgw-site.service';
+import { Permissions } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, TabHelper } from '~/testing/unit-test-helper';
+import { RgwDaemonDetailsComponent } from '../rgw-daemon-details/rgw-daemon-details.component';
+import { RgwDaemonListComponent } from './rgw-daemon-list.component';
+
+describe('RgwDaemonListComponent', () => {
+ let component: RgwDaemonListComponent;
+ let fixture: ComponentFixture<RgwDaemonListComponent>;
+ let getPermissionsSpy: jasmine.Spy;
+ let getRealmsSpy: jasmine.Spy;
+ let listDaemonsSpy: jest.SpyInstance;
+ const permissions = new Permissions({ grafana: ['read'] });
+ const daemon: RgwDaemon = {
+ id: '8000',
+ service_map_id: '4803',
+ version: 'ceph version',
+ server_hostname: 'ceph',
+ realm_name: 'realm1',
+ zonegroup_name: 'zg1-realm1',
+ zone_name: 'zone1-zg1-realm1',
+ default: true
+ };
+
+ const expectTabsAndHeading = (length: number, heading: string) => {
+ const tabs = TabHelper.getTextContents(fixture);
+ expect(tabs.length).toEqual(length);
+ expect(tabs[length - 1]).toEqual(heading);
+ };
+
+ configureTestBed({
+ declarations: [RgwDaemonListComponent, RgwDaemonDetailsComponent],
+ imports: [
+ BrowserAnimationsModule,
+ HttpClientTestingModule,
+ NgbNavModule,
+ PerformanceCounterModule,
+ SharedModule,
+ RouterTestingModule
+ ]
+ });
+
+ beforeEach(() => {
+ getPermissionsSpy = spyOn(TestBed.inject(AuthStorageService), 'getPermissions');
+ getPermissionsSpy.and.returnValue(new Permissions({}));
+ getRealmsSpy = spyOn(TestBed.inject(RgwSiteService), 'get');
+ getRealmsSpy.and.returnValue(of([]));
+ listDaemonsSpy = jest
+ .spyOn(TestBed.inject(RgwDaemonService), 'list')
+ .mockReturnValue(of([daemon]));
+ fixture = TestBed.createComponent(RgwDaemonListComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+
+ it('should show a row with daemon info', fakeAsync(() => {
+ fixture.detectChanges();
+ tick();
+ expect(listDaemonsSpy).toHaveBeenCalledTimes(1);
+ expect(component.daemons).toEqual([daemon]);
+ expect(fixture.debugElement.query(By.css('cd-table')).nativeElement.textContent).toContain(
+ 'total 1'
+ );
+
+ fixture.destroy();
+ }));
+
+ it('should only show Daemons List tab', () => {
+ fixture.detectChanges();
+
+ expectTabsAndHeading(1, 'Daemons List');
+ });
+
+ it('should show Overall Performance tab', () => {
+ getPermissionsSpy.and.returnValue(permissions);
+ fixture.detectChanges();
+
+ expectTabsAndHeading(2, 'Overall Performance');
+ });
+
+ it('should show Sync Performance tab', () => {
+ getPermissionsSpy.and.returnValue(permissions);
+ getRealmsSpy.and.returnValue(of(['realm1']));
+ fixture.detectChanges();
+
+ expectTabsAndHeading(3, 'Sync Performance');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts
new file mode 100644
index 000000000..c620843fb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts
@@ -0,0 +1,82 @@
+import { Component, OnInit } from '@angular/core';
+
+import { RgwDaemon } from '~/app/ceph/rgw/models/rgw-daemon';
+import { RgwDaemonService } from '~/app/shared/api/rgw-daemon.service';
+import { RgwSiteService } from '~/app/shared/api/rgw-site.service';
+import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { Permission } from '~/app/shared/models/permissions';
+import { CephShortVersionPipe } from '~/app/shared/pipes/ceph-short-version.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+
+@Component({
+ selector: 'cd-rgw-daemon-list',
+ templateUrl: './rgw-daemon-list.component.html',
+ styleUrls: ['./rgw-daemon-list.component.scss']
+})
+export class RgwDaemonListComponent extends ListWithDetails implements OnInit {
+ columns: CdTableColumn[] = [];
+ daemons: RgwDaemon[] = [];
+ grafanaPermission: Permission;
+ isMultiSite: boolean;
+
+ constructor(
+ private rgwDaemonService: RgwDaemonService,
+ private authStorageService: AuthStorageService,
+ private cephShortVersionPipe: CephShortVersionPipe,
+ private rgwSiteService: RgwSiteService
+ ) {
+ super();
+ }
+
+ ngOnInit(): void {
+ this.grafanaPermission = this.authStorageService.getPermissions().grafana;
+ this.columns = [
+ {
+ name: $localize`ID`,
+ prop: 'id',
+ flexGrow: 2
+ },
+ {
+ name: $localize`Hostname`,
+ prop: 'server_hostname',
+ flexGrow: 2
+ },
+ {
+ name: $localize`Zone`,
+ prop: 'zone_name',
+ flexGrow: 2
+ },
+ {
+ name: $localize`Zone Group`,
+ prop: 'zonegroup_name',
+ flexGrow: 2
+ },
+ {
+ name: $localize`Realm`,
+ prop: 'realm_name',
+ flexGrow: 2
+ },
+ {
+ name: $localize`Version`,
+ prop: 'version',
+ flexGrow: 1,
+ pipe: this.cephShortVersionPipe
+ }
+ ];
+ this.rgwSiteService
+ .get('realms')
+ .subscribe((realms: string[]) => (this.isMultiSite = realms.length > 0));
+ }
+
+ getDaemonList(context: CdTableFetchDataContext) {
+ this.rgwDaemonService.list().subscribe(this.updateDaemons, () => {
+ context.error();
+ });
+ }
+
+ private updateDaemons = (daemons: RgwDaemon[]) => {
+ this.daemons = daemons;
+ };
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html
new file mode 100644
index 000000000..8276e01e7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html
@@ -0,0 +1,70 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container i18n="form title"
+ class="modal-title">{{ action | titlecase }} {{ resource | upperFirst }}</ng-container>
+
+ <ng-container class="modal-content">
+ <form #frm="ngForm"
+ [formGroup]="formGroup"
+ novalidate>
+ <div class="modal-body">
+ <!-- Type -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': !editing}"
+ for="type"
+ i18n>Type</label>
+ <div class="cd-col-form-input">
+ <input id="type"
+ class="form-control"
+ type="text"
+ *ngIf="editing"
+ [readonly]="true"
+ formControlName="type">
+ <select id="type"
+ class="form-control"
+ formControlName="type"
+ *ngIf="!editing"
+ autofocus>
+ <option i18n
+ *ngIf="types !== null"
+ [ngValue]="null">-- Select a type --</option>
+ <option *ngFor="let type of types"
+ [value]="type">{{ type }}</option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="formGroup.showError('type', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Permission -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="perm"
+ i18n>Permission</label>
+ <div class="cd-col-form-input">
+ <select id="perm"
+ class="form-control"
+ formControlName="perm">
+ <option i18n
+ [ngValue]="null">-- Select a permission --</option>
+ <option *ngFor="let perm of ['read', 'write', '*']"
+ [value]="perm">
+ {{ perm }}
+ </option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="formGroup.showError('perm', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="onSubmit()"
+ [form]="formGroup"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.spec.ts
new file mode 100644
index 000000000..e270fb254
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.spec.ts
@@ -0,0 +1,30 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RgwUserCapabilityModalComponent } from './rgw-user-capability-modal.component';
+
+describe('RgwUserCapabilityModalComponent', () => {
+ let component: RgwUserCapabilityModalComponent;
+ let fixture: ComponentFixture<RgwUserCapabilityModalComponent>;
+
+ configureTestBed({
+ declarations: [RgwUserCapabilityModalComponent],
+ imports: [ReactiveFormsModule, SharedModule, RouterTestingModule],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RgwUserCapabilityModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts
new file mode 100644
index 000000000..3a3c9ac46
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts
@@ -0,0 +1,92 @@
+import { Component, EventEmitter, Output } from '@angular/core';
+import { Validators } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { RgwUserCapabilities } from '../models/rgw-user-capabilities';
+import { RgwUserCapability } from '../models/rgw-user-capability';
+
+@Component({
+ selector: 'cd-rgw-user-capability-modal',
+ templateUrl: './rgw-user-capability-modal.component.html',
+ styleUrls: ['./rgw-user-capability-modal.component.scss']
+})
+export class RgwUserCapabilityModalComponent {
+ /**
+ * The event that is triggered when the 'Add' or 'Update' button
+ * has been pressed.
+ */
+ @Output()
+ submitAction = new EventEmitter();
+
+ formGroup: CdFormGroup;
+ editing = true;
+ types: string[] = [];
+ resource: string;
+ action: string;
+
+ constructor(
+ private formBuilder: CdFormBuilder,
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ this.resource = $localize`capability`;
+ this.createForm();
+ }
+
+ createForm() {
+ this.formGroup = this.formBuilder.group({
+ type: [null, [Validators.required]],
+ perm: [null, [Validators.required]]
+ });
+ }
+
+ /**
+ * Set the 'editing' flag. If set to TRUE, the modal dialog is in 'Edit' mode,
+ * otherwise in 'Add' mode. According to the mode the dialog and its controls
+ * behave different.
+ * @param {boolean} viewing
+ */
+ setEditing(editing: boolean = true) {
+ this.editing = editing;
+ this.action = this.editing ? this.actionLabels.EDIT : this.actionLabels.ADD;
+ }
+
+ /**
+ * Set the values displayed in the dialog.
+ */
+ setValues(type: string, perm: string) {
+ this.formGroup.setValue({
+ type: type,
+ perm: perm
+ });
+ }
+
+ /**
+ * Set the current capabilities of the user.
+ */
+ setCapabilities(capabilities: RgwUserCapability[]) {
+ // Parse the configured capabilities to get a list of types that
+ // should be displayed.
+ const usedTypes: string[] = [];
+ capabilities.forEach((capability) => {
+ usedTypes.push(capability.type);
+ });
+ this.types = [];
+ RgwUserCapabilities.getAll().forEach((type) => {
+ if (_.indexOf(usedTypes, type) === -1) {
+ this.types.push(type);
+ }
+ });
+ }
+
+ onSubmit() {
+ const capability: RgwUserCapability = this.formGroup.value;
+ this.submitAction.emit(capability);
+ this.activeModal.close();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html
new file mode 100644
index 000000000..2283f4c54
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html
@@ -0,0 +1,178 @@
+<ng-container *ngIf="selection">
+ <ul ngbNav
+ #nav="ngbNav"
+ class="nav-tabs"
+ cdStatefulTab="rgw-user-details">
+ <li ngbNavItem="details">
+ <a ngbNavLink
+ i18n>Details</a>
+ <ng-template ngbNavContent>
+ <div *ngIf="user">
+ <table class="table table-striped table-bordered">
+ <tbody>
+ <tr>
+ <td i18n
+ class="bold w-25">Tenant</td>
+ <td class="w-75">{{ user.tenant }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold w-25">User ID</td>
+ <td class="w-75">{{ user.user_id }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold w-25">Username</td>
+ <td class="w-75">{{ user.uid }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Full name</td>
+ <td>{{ user.display_name }}</td>
+ </tr>
+ <tr *ngIf="user.email?.length">
+ <td i18n
+ class="bold">Email address</td>
+ <td>{{ user.email }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Suspended</td>
+ <td>{{ user.suspended | booleanText }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">System</td>
+ <td>{{ user.system === 'true' | booleanText }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Maximum buckets</td>
+ <td>{{ user.max_buckets | map:maxBucketsMap }}</td>
+ </tr>
+ <tr *ngIf="user.subusers && user.subusers.length">
+ <td i18n
+ class="bold">Subusers</td>
+ <td>
+ <div *ngFor="let subuser of user.subusers">
+ {{ subuser.id }} ({{ subuser.permissions }})
+ </div>
+ </td>
+ </tr>
+ <tr *ngIf="user.caps && user.caps.length">
+ <td i18n
+ class="bold">Capabilities</td>
+ <td>
+ <div *ngFor="let cap of user.caps">
+ {{ cap.type }} ({{ cap.perm }})
+ </div>
+ </td>
+ </tr>
+ <tr *ngIf="user.mfa_ids?.length">
+ <td i18n
+ class="bold">MFAs(Id)</td>
+ <td>{{ user.mfa_ids | join}}</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <!-- User quota -->
+ <div *ngIf="user.user_quota">
+ <legend i18n>User quota</legend>
+ <table class="table table-striped table-bordered">
+ <tbody>
+ <tr>
+ <td i18n
+ class="bold w-25">Enabled</td>
+ <td class="w-75">{{ user.user_quota.enabled | booleanText }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Maximum size</td>
+ <td *ngIf="!user.user_quota.enabled">-</td>
+ <td *ngIf="user.user_quota.enabled && user.user_quota.max_size <= -1"
+ i18n>Unlimited</td>
+ <td *ngIf="user.user_quota.enabled && user.user_quota.max_size > -1">
+ {{ user.user_quota.max_size | dimlessBinary }}
+ </td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Maximum objects</td>
+ <td *ngIf="!user.user_quota.enabled">-</td>
+ <td *ngIf="user.user_quota.enabled && user.user_quota.max_objects <= -1"
+ i18n>Unlimited</td>
+ <td *ngIf="user.user_quota.enabled && user.user_quota.max_objects > -1">
+ {{ user.user_quota.max_objects }}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <!-- Bucket quota -->
+ <div *ngIf="user.bucket_quota">
+ <legend i18n>Bucket quota</legend>
+ <table class="table table-striped table-bordered">
+ <tbody>
+ <tr>
+ <td i18n
+ class="bold w-25">Enabled</td>
+ <td class="w-75">{{ user.bucket_quota.enabled | booleanText }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Maximum size</td>
+ <td *ngIf="!user.bucket_quota.enabled">-</td>
+ <td *ngIf="user.bucket_quota.enabled && user.bucket_quota.max_size <= -1"
+ i18n>Unlimited</td>
+ <td *ngIf="user.bucket_quota.enabled && user.bucket_quota.max_size > -1">
+ {{ user.bucket_quota.max_size | dimlessBinary }}
+ </td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">Maximum objects</td>
+ <td *ngIf="!user.bucket_quota.enabled">-</td>
+ <td *ngIf="user.bucket_quota.enabled && user.bucket_quota.max_objects <= -1"
+ i18n>Unlimited</td>
+ <td *ngIf="user.bucket_quota.enabled && user.bucket_quota.max_objects > -1">
+ {{ user.bucket_quota.max_objects }}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </ng-template>
+ </li>
+ <li ngbNavItem="keys"
+ *ngIf="keys.length">
+ <a ngbNavLink
+ i18n>Keys</a>
+ <ng-template ngbNavContent>
+ <cd-table [data]="keys"
+ [columns]="keysColumns"
+ columnMode="flex"
+ selectionType="multi"
+ forceIdentifier="true"
+ (updateSelection)="updateKeysSelection($event)">
+ <div class="table-actions">
+ <div class="btn-group"
+ dropdown>
+ <button type="button"
+ class="btn btn-accent"
+ [disabled]="!keysSelection.hasSingleSelection"
+ (click)="showKeyModal()">
+ <i [ngClass]="[icons.show]"></i>
+ <ng-container i18n>Show</ng-container>
+ </button>
+ </div>
+ </div>
+ </cd-table>
+ </ng-template>
+ </li>
+ </ul>
+
+ <div [ngbNavOutlet]="nav"></div>
+</ng-container>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.spec.ts
new file mode 100644
index 000000000..62519cdf4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.spec.ts
@@ -0,0 +1,94 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, TabHelper } from '~/testing/unit-test-helper';
+import { RgwUserS3Key } from '../models/rgw-user-s3-key';
+import { RgwUserDetailsComponent } from './rgw-user-details.component';
+
+describe('RgwUserDetailsComponent', () => {
+ let component: RgwUserDetailsComponent;
+ let fixture: ComponentFixture<RgwUserDetailsComponent>;
+
+ configureTestBed({
+ declarations: [RgwUserDetailsComponent],
+ imports: [BrowserAnimationsModule, HttpClientTestingModule, SharedModule, NgbNavModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RgwUserDetailsComponent);
+ component = fixture.componentInstance;
+ component.selection = {};
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+
+ const tabs = TabHelper.getTextContents(fixture);
+ expect(tabs).toContain('Details');
+ expect(tabs).not.toContain('Keys');
+ });
+
+ it('should show "Details" tab', () => {
+ component.selection = { uid: 'myUsername' };
+ fixture.detectChanges();
+
+ const tabs = TabHelper.getTextContents(fixture);
+ expect(tabs).toContain('Details');
+ expect(tabs).not.toContain('Keys');
+ });
+
+ it('should show "Keys" tab', () => {
+ const s3Key = new RgwUserS3Key();
+ component.selection = { keys: [s3Key] };
+ component.ngOnChanges();
+ fixture.detectChanges();
+
+ const tabs = TabHelper.getTextContents(fixture);
+ expect(tabs).toContain('Details');
+ expect(tabs).toContain('Keys');
+ });
+
+ it('should show correct "System" info', () => {
+ component.selection = { uid: '', email: '', system: 'true', keys: [], swift_keys: [] };
+
+ component.ngOnChanges();
+ fixture.detectChanges();
+
+ const detailsTab = fixture.debugElement.nativeElement.querySelectorAll(
+ '.table.table-striped.table-bordered tr td'
+ );
+ expect(detailsTab[10].textContent).toEqual('System');
+ expect(detailsTab[11].textContent).toEqual('Yes');
+
+ component.selection.system = 'false';
+ component.ngOnChanges();
+ fixture.detectChanges();
+
+ expect(detailsTab[11].textContent).toEqual('No');
+ });
+
+ it('should show mfa ids only if length > 0', () => {
+ component.selection = {
+ uid: 'dashboard',
+ email: '',
+ system: 'true',
+ keys: [],
+ swift_keys: [],
+ mfa_ids: ['testMFA1', 'testMFA2']
+ };
+
+ component.ngOnChanges();
+ fixture.detectChanges();
+
+ const detailsTab = fixture.debugElement.nativeElement.querySelectorAll(
+ '.table.table-striped.table-bordered tr td'
+ );
+ expect(detailsTab[14].textContent).toEqual('MFAs(Id)');
+ expect(detailsTab[15].textContent).toEqual('testMFA1, testMFA2');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts
new file mode 100644
index 000000000..2c4a92612
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts
@@ -0,0 +1,120 @@
+import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import _ from 'lodash';
+
+import { RgwUserService } from '~/app/shared/api/rgw-user.service';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { RgwUserS3Key } from '../models/rgw-user-s3-key';
+import { RgwUserSwiftKey } from '../models/rgw-user-swift-key';
+import { RgwUserS3KeyModalComponent } from '../rgw-user-s3-key-modal/rgw-user-s3-key-modal.component';
+import { RgwUserSwiftKeyModalComponent } from '../rgw-user-swift-key-modal/rgw-user-swift-key-modal.component';
+
+@Component({
+ selector: 'cd-rgw-user-details',
+ templateUrl: './rgw-user-details.component.html',
+ styleUrls: ['./rgw-user-details.component.scss']
+})
+export class RgwUserDetailsComponent implements OnChanges, OnInit {
+ @ViewChild('accessKeyTpl')
+ public accessKeyTpl: TemplateRef<any>;
+ @ViewChild('secretKeyTpl')
+ public secretKeyTpl: TemplateRef<any>;
+
+ @Input()
+ selection: any;
+
+ // Details tab
+ user: any;
+ maxBucketsMap: {};
+
+ // Keys tab
+ keys: any = [];
+ keysColumns: CdTableColumn[] = [];
+ keysSelection: CdTableSelection = new CdTableSelection();
+
+ icons = Icons;
+
+ constructor(private rgwUserService: RgwUserService, private modalService: ModalService) {}
+
+ ngOnInit() {
+ this.keysColumns = [
+ {
+ name: $localize`Username`,
+ prop: 'username',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Type`,
+ prop: 'type',
+ flexGrow: 1
+ }
+ ];
+ this.maxBucketsMap = {
+ '-1': $localize`Disabled`,
+ 0: $localize`Unlimited`
+ };
+ }
+
+ ngOnChanges() {
+ if (this.selection) {
+ this.user = this.selection;
+
+ // Sort subusers and capabilities.
+ this.user.subusers = _.sortBy(this.user.subusers, 'id');
+ this.user.caps = _.sortBy(this.user.caps, 'type');
+
+ // Load the user/bucket quota of the selected user.
+ this.rgwUserService.getQuota(this.user.uid).subscribe((resp: object) => {
+ _.extend(this.user, resp);
+ });
+
+ // Process the keys.
+ this.keys = [];
+ if (this.user.keys) {
+ this.user.keys.forEach((key: RgwUserS3Key) => {
+ this.keys.push({
+ id: this.keys.length + 1, // Create an unique identifier
+ type: 'S3',
+ username: key.user,
+ ref: key
+ });
+ });
+ }
+ if (this.user.swift_keys) {
+ this.user.swift_keys.forEach((key: RgwUserSwiftKey) => {
+ this.keys.push({
+ id: this.keys.length + 1, // Create an unique identifier
+ type: 'Swift',
+ username: key.user,
+ ref: key
+ });
+ });
+ }
+
+ this.keys = _.sortBy(this.keys, 'user');
+ }
+ }
+
+ updateKeysSelection(selection: CdTableSelection) {
+ this.keysSelection = selection;
+ }
+
+ showKeyModal() {
+ const key = this.keysSelection.first();
+ const modalRef = this.modalService.show(
+ key.type === 'S3' ? RgwUserS3KeyModalComponent : RgwUserSwiftKeyModalComponent
+ );
+ switch (key.type) {
+ case 'S3':
+ modalRef.componentInstance.setViewing();
+ modalRef.componentInstance.setValues(key.ref.user, key.ref.access_key, key.ref.secret_key);
+ break;
+ case 'Swift':
+ modalRef.componentInstance.setValues(key.ref.user, key.ref.secret_key);
+ break;
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html
new file mode 100644
index 000000000..4a28c3e57
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html
@@ -0,0 +1,668 @@
+<div class="cd-col-form"
+ *cdFormLoading="loading">
+ <form #frm="ngForm"
+ [formGroup]="userForm"
+ novalidate>
+ <div class="card">
+ <div i18n="form title"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
+
+ <div class="card-body">
+ <!-- User ID -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': !editing}"
+ for="user_id"
+ i18n>User ID</label>
+ <div class="cd-col-form-input">
+ <input id="user_id"
+ class="form-control"
+ type="text"
+ formControlName="user_id"
+ [readonly]="editing">
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('user_id', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('user_id', frm, 'pattern')"
+ i18n>The value is not valid.</span>
+ <span class="invalid-feedback"
+ *ngIf="!userForm.getValue('show_tenant') && userForm.showError('user_id', frm, 'notUnique')"
+ i18n>The chosen user ID is already in use.</span>
+ </div>
+ </div>
+
+ <!-- Show Tenant -->
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="show_tenant"
+ type="checkbox"
+ (click)="updateFieldsWhenTenanted()"
+ formControlName="show_tenant"
+ [readonly]="true">
+ <label class="custom-control-label"
+ for="show_tenant"
+ i18n>Show Tenant</label>
+ </div>
+ </div>
+ </div>
+
+ <!-- Tenant -->
+ <div class="form-group row"
+ *ngIf="userForm.getValue('show_tenant')">
+ <label class="cd-col-form-label"
+ for="tenant"
+ i18n>Tenant</label>
+ <div class="cd-col-form-input">
+ <input id="tenant"
+ class="form-control"
+ type="text"
+ formControlName="tenant"
+ [readonly]="editing"
+ autofocus>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('tenant', frm, 'pattern')"
+ i18n>The value is not valid.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('tenant', frm, 'notUnique')"
+ i18n>The chosen user ID exists in this tenant.</span>
+ </div>
+ </div>
+
+ <!-- Full name -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': !editing}"
+ for="display_name"
+ i18n>Full name</label>
+ <div class="cd-col-form-input">
+ <input id="display_name"
+ class="form-control"
+ type="text"
+ formControlName="display_name">
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('display_name', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Email address -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="email"
+ i18n>Email address</label>
+ <div class="cd-col-form-input">
+ <input id="email"
+ class="form-control"
+ type="text"
+ formControlName="email">
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('email', frm, 'email')"
+ i18n>This is not a valid email address.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('email', frm, 'notUnique')"
+ i18n>The chosen email address is already in use.</span>
+ </div>
+ </div>
+
+ <!-- Max. buckets -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="max_buckets_mode"
+ i18n>Max. buckets</label>
+ <div class="cd-col-form-input">
+ <select class="form-control"
+ formControlName="max_buckets_mode"
+ name="max_buckets_mode"
+ id="max_buckets_mode"
+ (change)="onMaxBucketsModeChange($event.target.value)">
+ <option i18n
+ value="-1">Disabled</option>
+ <option i18n
+ value="0">Unlimited</option>
+ <option i18n
+ value="1">Custom</option>
+ </select>
+ </div>
+ </div>
+ <div *ngIf="1 == userForm.get('max_buckets_mode').value"
+ class="form-group row">
+ <label class="cd-col-form-label"></label>
+ <div class="cd-col-form-input">
+ <input id="max_buckets"
+ class="form-control"
+ type="number"
+ formControlName="max_buckets"
+ min="1">
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('max_buckets', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('max_buckets', frm, 'min')"
+ i18n>The entered value must be >= 1.</span>
+ </div>
+ </div>
+
+ <!-- Suspended -->
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="suspended"
+ type="checkbox"
+ formControlName="suspended">
+ <label class="custom-control-label"
+ for="suspended"
+ i18n>Suspended</label>
+ </div>
+ </div>
+ </div>
+
+ <!-- S3 key -->
+ <fieldset *ngIf="!editing">
+ <legend i18n>S3 key</legend>
+
+ <!-- Auto-generate key -->
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="generate_key"
+ type="checkbox"
+ formControlName="generate_key">
+ <label class="custom-control-label"
+ for="generate_key"
+ i18n>Auto-generate key</label>
+ </div>
+ </div>
+ </div>
+
+ <!-- Access key -->
+ <div class="form-group row"
+ *ngIf="!editing && !userForm.getValue('generate_key')">
+ <label class="cd-col-form-label required"
+ for="access_key"
+ i18n>Access key</label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input id="access_key"
+ class="form-control"
+ type="password"
+ formControlName="access_key">
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="access_key">
+ </button>
+ <cd-copy-2-clipboard-button source="access_key">
+ </cd-copy-2-clipboard-button>
+ </span>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('access_key', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Secret key -->
+ <div class="form-group row"
+ *ngIf="!editing && !userForm.getValue('generate_key')">
+ <label class="cd-col-form-label required"
+ for="secret_key"
+ i18n>Secret key</label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input id="secret_key"
+ class="form-control"
+ type="password"
+ formControlName="secret_key">
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="secret_key">
+ </button>
+ <cd-copy-2-clipboard-button source="secret_key">
+ </cd-copy-2-clipboard-button>
+ </span>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('secret_key', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+ </fieldset>
+
+ <!-- Subusers -->
+ <fieldset *ngIf="editing">
+ <legend i18n>Subusers</legend>
+ <div class="row">
+ <div class="cd-col-form-offset">
+ <span *ngIf="subusers.length === 0"
+ class="no-border">
+ <span class="form-text text-muted"
+ i18n>There are no subusers.</span>
+ </span>
+
+ <span *ngFor="let subuser of subusers; let i=index;">
+ <div class="input-group">
+ <div class="input-group-prepend">
+ <span class="input-group-text">
+ <i class="{{ icons.user }}"></i>
+ </span>
+ </div>
+ <input type="text"
+ class="cd-form-control"
+ value="{{ subuser.id }}"
+ readonly>
+ <div class="input-group-prepend border-left-0 border-right-0">
+ <span class="input-group-text">
+ <i class="{{ icons.share }}"></i>
+ </span>
+ </div>
+ <input type="text"
+ class="cd-form-control"
+ value="{{ ('full-control' === subuser.permissions) ? 'full' : subuser.permissions }}"
+ readonly>
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light tc_showSubuserButton"
+ i18n-ngbTooltip
+ ngbTooltip="Edit"
+ (click)="showSubuserModal(i)">
+ <i [ngClass]="[icons.edit]"></i>
+ </button>
+ <button type="button"
+ class="btn btn-light tc_deleteSubuserButton"
+ i18n-ngbTooltip
+ ngbTooltip="Delete"
+ (click)="deleteSubuser(i)">
+ <i [ngClass]="[icons.destroy]"></i>
+ </button>
+ </span>
+ </div>
+ <span class="form-text text-muted"></span>
+ </span>
+
+ <div class="row">
+ <div class="col-12">
+ <button type="button"
+ class="btn btn-light float-right tc_addSubuserButton"
+ (click)="showSubuserModal()">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>{{ actionLabels.CREATE | titlecase }}
+ {{ subuserLabel | upperFirst }}</ng-container>
+ </button>
+ </div>
+ </div>
+ <span class="help-block"></span>
+ </div>
+ </div>
+ </fieldset>
+
+ <!-- Keys -->
+ <fieldset *ngIf="editing">
+ <legend i18n>Keys</legend>
+
+ <!-- S3 keys -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ i18n>S3</label>
+ <div class="cd-col-form-input">
+ <span *ngIf="s3Keys.length === 0"
+ class="no-border">
+ <span class="form-text text-muted"
+ i18n>There are no keys.</span>
+ </span>
+
+ <span *ngFor="let key of s3Keys; let i=index;">
+ <div class="input-group">
+ <div class="input-group-prepend">
+ <div class="input-group-text">
+ <i class="{{ icons.key }}"></i>
+ </div>
+ </div>
+ <input type="text"
+ class="cd-form-control"
+ value="{{ key.user }}"
+ readonly>
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light tc_showS3KeyButton"
+ i18n-ngbTooltip
+ ngbTooltip="Show"
+ (click)="showS3KeyModal(i)">
+ <i [ngClass]="[icons.show]"></i>
+ </button>
+ <button type="button"
+ class="btn btn-light tc_deleteS3KeyButton"
+ i18n-ngbTooltip
+ ngbTooltip="Delete"
+ (click)="deleteS3Key(i)">
+ <i [ngClass]="[icons.destroy]"></i>
+ </button>
+ </span>
+ </div>
+ <span class="form-text text-muted"></span>
+ </span>
+
+ <div class="row">
+ <div class="col-12">
+ <button type="button"
+ class="btn btn-light float-right tc_addS3KeyButton"
+ (click)="showS3KeyModal()">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>{{ actionLabels.CREATE | titlecase }}
+ {{ s3keyLabel | upperFirst }}</ng-container>
+ </button>
+ </div>
+ </div>
+
+ <span class="help-block"></span>
+ </div>
+
+ <hr>
+ </div>
+
+ <!-- Swift keys -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ i18n>Swift</label>
+
+ <div class="cd-col-form-input">
+ <span *ngIf="swiftKeys.length === 0"
+ class="no-border">
+ <span class="form-text text-muted"
+ i18n>There are no keys.</span>
+ </span>
+
+ <span *ngFor="let key of swiftKeys; let i=index;">
+ <div class="input-group">
+ <div class="input-group-prepend">
+ <span class="input-group-text">
+ <i class="{{ icons.key }}"></i>
+ </span>
+ </div>
+ <input type="text"
+ class="cd-form-control"
+ value="{{ key.user }}"
+ readonly>
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light tc_showSwiftKeyButton"
+ i18n-ngbTooltip
+ ngbTooltip="Show"
+ (click)="showSwiftKeyModal(i)">
+ <i [ngClass]="[icons.show]"></i>
+ </button>
+ </span>
+ </div>
+ <span class="form-text text-muted"></span>
+ </span>
+ </div>
+ </div>
+ </fieldset>
+
+ <!-- Capabilities -->
+ <fieldset *ngIf="editing">
+ <legend i18n>Capabilities</legend>
+
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <span *ngIf="capabilities.length === 0"
+ class="no-border">
+ <span class="form-text text-muted"
+ i18n>There are no capabilities.</span>
+ </span>
+
+ <span *ngFor="let cap of capabilities; let i=index;">
+ <div class="input-group">
+ <span class="input-group-prepend">
+ <div class="input-group-text">
+ <i class="{{ icons.share }}"></i>
+ </div>
+ </span>
+ <input type="text"
+ class="cd-form-control"
+ value="{{ cap.type }}:{{ cap.perm }}"
+ readonly>
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light tc_editCapButton"
+ i18n-ngbTooltip
+ ngbTooltip="Edit"
+ (click)="showCapabilityModal(i)">
+ <i [ngClass]="[icons.edit]"></i>
+ </button>
+ <button type="button"
+ class="btn btn-light tc_deleteCapButton"
+ i18n-ngbTooltip
+ ngbTooltip="Delete"
+ (click)="deleteCapability(i)">
+ <i [ngClass]="[icons.destroy]"></i>
+ </button>
+ </span>
+ </div>
+ <span class="form-text text-muted"></span>
+ </span>
+
+ <div class="row">
+ <div class="col-12">
+ <button type="button"
+ class="btn btn-light float-right tc_addCapButton"
+ [disabled]="capabilities | pipeFunction:hasAllCapabilities"
+ i18n-ngbTooltip
+ ngbTooltip="All capabilities are already added."
+ [disableTooltip]="!(capabilities | pipeFunction:hasAllCapabilities)"
+ triggers="pointerenter:pointerleave"
+ (click)="showCapabilityModal()">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>{{ actionLabels.ADD | titlecase }}
+ {{ capabilityLabel | upperFirst }}</ng-container>
+ </button>
+ </div>
+ </div>
+ <span class="help-block"></span>
+ </div>
+ </div>
+ </fieldset>
+
+ <!-- User quota -->
+ <fieldset>
+ <legend i18n>User quota</legend>
+
+ <!-- Enabled -->
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="user_quota_enabled"
+ type="checkbox"
+ formControlName="user_quota_enabled">
+ <label class="custom-control-label"
+ for="user_quota_enabled"
+ i18n>Enabled</label>
+ </div>
+ </div>
+ </div>
+
+ <!-- Unlimited size -->
+ <div class="form-group row"
+ *ngIf="userForm.controls.user_quota_enabled.value">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="user_quota_max_size_unlimited"
+ type="checkbox"
+ formControlName="user_quota_max_size_unlimited">
+ <label class="custom-control-label"
+ for="user_quota_max_size_unlimited"
+ i18n>Unlimited size</label>
+ </div>
+ </div>
+ </div>
+
+ <!-- Maximum size -->
+ <div class="form-group row"
+ *ngIf="userForm.controls.user_quota_enabled.value && !userForm.getValue('user_quota_max_size_unlimited')">
+ <label class="cd-col-form-label required"
+ for="user_quota_max_size"
+ i18n>Max. size</label>
+ <div class="cd-col-form-input">
+ <input id="user_quota_max_size"
+ class="form-control"
+ type="text"
+ formControlName="user_quota_max_size"
+ cdDimlessBinary>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('user_quota_max_size', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('user_quota_max_size', frm, 'quotaMaxSize')"
+ i18n>The value is not valid.</span>
+ </div>
+ </div>
+
+ <!-- Unlimited objects -->
+ <div class="form-group row"
+ *ngIf="userForm.controls.user_quota_enabled.value">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="user_quota_max_objects_unlimited"
+ type="checkbox"
+ formControlName="user_quota_max_objects_unlimited">
+ <label class="custom-control-label"
+ for="user_quota_max_objects_unlimited"
+ i18n>Unlimited objects</label>
+ </div>
+ </div>
+ </div>
+
+ <!-- Maximum objects -->
+ <div class="form-group row"
+ *ngIf="userForm.controls.user_quota_enabled.value && !userForm.getValue('user_quota_max_objects_unlimited')">
+ <label class="cd-col-form-label required"
+ for="user_quota_max_objects"
+ i18n>Max. objects</label>
+ <div class="cd-col-form-input">
+ <input id="user_quota_max_objects"
+ class="form-control"
+ type="number"
+ formControlName="user_quota_max_objects"
+ min="0">
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('user_quota_max_objects', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('user_quota_max_objects', frm, 'min')"
+ i18n>The entered value must be >= 0.</span>
+ </div>
+ </div>
+ </fieldset>
+
+ <!-- Bucket quota -->
+ <fieldset>
+ <legend i18n>Bucket quota</legend>
+
+ <!-- Enabled -->
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="bucket_quota_enabled"
+ type="checkbox"
+ formControlName="bucket_quota_enabled">
+ <label class="custom-control-label"
+ for="bucket_quota_enabled"
+ i18n>Enabled</label>
+ </div>
+ </div>
+ </div>
+
+ <!-- Unlimited size -->
+ <div class="form-group row"
+ *ngIf="userForm.controls.bucket_quota_enabled.value">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="bucket_quota_max_size_unlimited"
+ type="checkbox"
+ formControlName="bucket_quota_max_size_unlimited">
+ <label class="custom-control-label"
+ for="bucket_quota_max_size_unlimited"
+ i18n>Unlimited size</label>
+ </div>
+ </div>
+ </div>
+
+ <!-- Maximum size -->
+ <div class="form-group row"
+ *ngIf="userForm.controls.bucket_quota_enabled.value && !userForm.getValue('bucket_quota_max_size_unlimited')">
+ <label class="cd-col-form-label required"
+ for="bucket_quota_max_size"
+ i18n>Max. size</label>
+ <div class="cd-col-form-input">
+ <input id="bucket_quota_max_size"
+ class="form-control"
+ type="text"
+ formControlName="bucket_quota_max_size"
+ cdDimlessBinary>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('bucket_quota_max_size', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('bucket_quota_max_size', frm, 'quotaMaxSize')"
+ i18n>The value is not valid.</span>
+ </div>
+ </div>
+
+ <!-- Unlimited objects -->
+ <div class="form-group row"
+ *ngIf="userForm.controls.bucket_quota_enabled.value">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="bucket_quota_max_objects_unlimited"
+ type="checkbox"
+ formControlName="bucket_quota_max_objects_unlimited">
+ <label class="custom-control-label"
+ for="bucket_quota_max_objects_unlimited"
+ i18n>Unlimited objects</label>
+ </div>
+ </div>
+ </div>
+
+ <!-- Maximum objects -->
+ <div class="form-group row"
+ *ngIf="userForm.controls.bucket_quota_enabled.value && !userForm.getValue('bucket_quota_max_objects_unlimited')">
+ <label class="cd-col-form-label required"
+ for="bucket_quota_max_objects"
+ i18n>Max. objects</label>
+ <div class="cd-col-form-input">
+ <input id="bucket_quota_max_objects"
+ class="form-control"
+ type="number"
+ formControlName="bucket_quota_max_objects"
+ min="0">
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('bucket_quota_max_objects', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('bucket_quota_max_objects', frm, 'min')"
+ i18n>The entered value must be >= 0.</span>
+ </div>
+ </div>
+ </fieldset>
+ </div>
+
+ <div class="card-footer">
+ <cd-form-button-panel (submitActionEvent)="onSubmit()"
+ [form]="userForm"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
+ wrappingClass="text-right"></cd-form-button-panel>
+ </div>
+ </div>
+ </form>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.spec.ts
new file mode 100644
index 000000000..15665d53b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.spec.ts
@@ -0,0 +1,339 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { FormControl, ReactiveFormsModule } from '@angular/forms';
+import { Router } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgxPipeFunctionModule } from 'ngx-pipe-function';
+import { ToastrModule } from 'ngx-toastr';
+import { of as observableOf, throwError } from 'rxjs';
+
+import { RgwUserService } from '~/app/shared/api/rgw-user.service';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
+import { RgwUserCapabilities } from '../models/rgw-user-capabilities';
+import { RgwUserCapability } from '../models/rgw-user-capability';
+import { RgwUserS3Key } from '../models/rgw-user-s3-key';
+import { RgwUserFormComponent } from './rgw-user-form.component';
+
+describe('RgwUserFormComponent', () => {
+ let component: RgwUserFormComponent;
+ let fixture: ComponentFixture<RgwUserFormComponent>;
+ let rgwUserService: RgwUserService;
+ let formHelper: FormHelper;
+
+ configureTestBed({
+ declarations: [RgwUserFormComponent],
+ imports: [
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ RouterTestingModule,
+ SharedModule,
+ ToastrModule.forRoot(),
+ NgbTooltipModule,
+ NgxPipeFunctionModule
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RgwUserFormComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ rgwUserService = TestBed.inject(RgwUserService);
+ formHelper = new FormHelper(component.userForm);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('s3 key management', () => {
+ beforeEach(() => {
+ spyOn(rgwUserService, 'addS3Key').and.stub();
+ });
+
+ it('should not update key', () => {
+ component.setS3Key(new RgwUserS3Key(), 3);
+ expect(component.s3Keys.length).toBe(0);
+ expect(rgwUserService.addS3Key).not.toHaveBeenCalled();
+ });
+
+ it('should set user defined key', () => {
+ const key = new RgwUserS3Key();
+ key.user = 'test1:subuser2';
+ key.access_key = 'my-access-key';
+ key.secret_key = 'my-secret-key';
+ component.setS3Key(key);
+ expect(component.s3Keys.length).toBe(1);
+ expect(component.s3Keys[0].user).toBe('test1:subuser2');
+ expect(rgwUserService.addS3Key).toHaveBeenCalledWith('test1', {
+ subuser: 'subuser2',
+ generate_key: 'false',
+ access_key: 'my-access-key',
+ secret_key: 'my-secret-key'
+ });
+ });
+
+ it('should set params for auto-generating key', () => {
+ const key = new RgwUserS3Key();
+ key.user = 'test1:subuser2';
+ key.generate_key = true;
+ key.access_key = 'my-access-key';
+ key.secret_key = 'my-secret-key';
+ component.setS3Key(key);
+ expect(component.s3Keys.length).toBe(1);
+ expect(component.s3Keys[0].user).toBe('test1:subuser2');
+ expect(rgwUserService.addS3Key).toHaveBeenCalledWith('test1', {
+ subuser: 'subuser2',
+ generate_key: 'true'
+ });
+ });
+
+ it('should set key w/o subuser', () => {
+ const key = new RgwUserS3Key();
+ key.user = 'test1';
+ component.setS3Key(key);
+ expect(component.s3Keys.length).toBe(1);
+ expect(component.s3Keys[0].user).toBe('test1');
+ expect(rgwUserService.addS3Key).toHaveBeenCalledWith('test1', {
+ subuser: '',
+ generate_key: 'false',
+ access_key: undefined,
+ secret_key: undefined
+ });
+ });
+ });
+
+ describe('quotaMaxSizeValidator', () => {
+ it('should validate max size (1)', () => {
+ const resp = component.quotaMaxSizeValidator(new FormControl(''));
+ expect(resp).toBe(null);
+ });
+
+ it('should validate max size (2)', () => {
+ const resp = component.quotaMaxSizeValidator(new FormControl('xxxx'));
+ expect(resp.quotaMaxSize).toBeTruthy();
+ });
+
+ it('should validate max size (3)', () => {
+ const resp = component.quotaMaxSizeValidator(new FormControl('1023'));
+ expect(resp.quotaMaxSize).toBeTruthy();
+ });
+
+ it('should validate max size (4)', () => {
+ const resp = component.quotaMaxSizeValidator(new FormControl('1024'));
+ expect(resp).toBe(null);
+ });
+
+ it('should validate max size (5)', () => {
+ const resp = component.quotaMaxSizeValidator(new FormControl('1M'));
+ expect(resp).toBe(null);
+ });
+
+ it('should validate max size (6)', () => {
+ const resp = component.quotaMaxSizeValidator(new FormControl('1024 gib'));
+ expect(resp).toBe(null);
+ });
+
+ it('should validate max size (7)', () => {
+ const resp = component.quotaMaxSizeValidator(new FormControl('10 X'));
+ expect(resp.quotaMaxSize).toBeTruthy();
+ });
+
+ it('should validate max size (8)', () => {
+ const resp = component.quotaMaxSizeValidator(new FormControl('1.085 GiB'));
+ expect(resp).toBe(null);
+ });
+
+ it('should validate max size (9)', () => {
+ const resp = component.quotaMaxSizeValidator(new FormControl('1,085 GiB'));
+ expect(resp.quotaMaxSize).toBeTruthy();
+ });
+ });
+
+ describe('username validation', () => {
+ it('should validate that username is required', () => {
+ formHelper.expectErrorChange('user_id', '', 'required', true);
+ });
+
+ it('should validate that username is valid', fakeAsync(() => {
+ spyOn(rgwUserService, 'get').and.returnValue(throwError('foo'));
+ formHelper.setValue('user_id', 'ab', true);
+ tick();
+ formHelper.expectValid('user_id');
+ }));
+
+ it('should validate that username is invalid', fakeAsync(() => {
+ spyOn(rgwUserService, 'get').and.returnValue(observableOf({}));
+ formHelper.setValue('user_id', 'abc', true);
+ tick();
+ formHelper.expectError('user_id', 'notUnique');
+ }));
+ });
+
+ describe('max buckets', () => {
+ it('disable creation (create)', () => {
+ spyOn(rgwUserService, 'create');
+ formHelper.setValue('max_buckets_mode', -1, true);
+ component.onSubmit();
+ expect(rgwUserService.create).toHaveBeenCalledWith({
+ access_key: '',
+ display_name: null,
+ email: '',
+ generate_key: true,
+ max_buckets: -1,
+ secret_key: '',
+ suspended: false,
+ uid: null
+ });
+ });
+
+ it('disable creation (edit)', () => {
+ spyOn(rgwUserService, 'update');
+ component.editing = true;
+ formHelper.setValue('max_buckets_mode', -1, true);
+ component.onSubmit();
+ expect(rgwUserService.update).toHaveBeenCalledWith(null, {
+ display_name: null,
+ email: null,
+ max_buckets: -1,
+ suspended: false
+ });
+ });
+
+ it('unlimited buckets (create)', () => {
+ spyOn(rgwUserService, 'create');
+ formHelper.setValue('max_buckets_mode', 0, true);
+ component.onSubmit();
+ expect(rgwUserService.create).toHaveBeenCalledWith({
+ access_key: '',
+ display_name: null,
+ email: '',
+ generate_key: true,
+ max_buckets: 0,
+ secret_key: '',
+ suspended: false,
+ uid: null
+ });
+ });
+
+ it('unlimited buckets (edit)', () => {
+ spyOn(rgwUserService, 'update');
+ component.editing = true;
+ formHelper.setValue('max_buckets_mode', 0, true);
+ component.onSubmit();
+ expect(rgwUserService.update).toHaveBeenCalledWith(null, {
+ display_name: null,
+ email: null,
+ max_buckets: 0,
+ suspended: false
+ });
+ });
+
+ it('custom (create)', () => {
+ spyOn(rgwUserService, 'create');
+ formHelper.setValue('max_buckets_mode', 1, true);
+ formHelper.setValue('max_buckets', 100, true);
+ component.onSubmit();
+ expect(rgwUserService.create).toHaveBeenCalledWith({
+ access_key: '',
+ display_name: null,
+ email: '',
+ generate_key: true,
+ max_buckets: 100,
+ secret_key: '',
+ suspended: false,
+ uid: null
+ });
+ });
+
+ it('custom (edit)', () => {
+ spyOn(rgwUserService, 'update');
+ component.editing = true;
+ formHelper.setValue('max_buckets_mode', 1, true);
+ formHelper.setValue('max_buckets', 100, true);
+ component.onSubmit();
+ expect(rgwUserService.update).toHaveBeenCalledWith(null, {
+ display_name: null,
+ email: null,
+ max_buckets: 100,
+ suspended: false
+ });
+ });
+ });
+
+ describe('submit form', () => {
+ let notificationService: NotificationService;
+
+ beforeEach(() => {
+ spyOn(TestBed.inject(Router), 'navigate').and.stub();
+ notificationService = TestBed.inject(NotificationService);
+ spyOn(notificationService, 'show');
+ });
+
+ it('should be able to clear the mail field on update', () => {
+ spyOn(rgwUserService, 'update');
+ component.editing = true;
+ formHelper.setValue('email', '', true);
+ component.onSubmit();
+ expect(rgwUserService.update).toHaveBeenCalledWith(null, {
+ display_name: null,
+ email: '',
+ max_buckets: 1000,
+ suspended: false
+ });
+ });
+
+ it('tests create success notification', () => {
+ spyOn(rgwUserService, 'create').and.returnValue(observableOf([]));
+ component.editing = false;
+ formHelper.setValue('suspended', true, true);
+ component.onSubmit();
+ expect(notificationService.show).toHaveBeenCalledWith(
+ NotificationType.success,
+ `Created Object Gateway user 'null'`
+ );
+ });
+
+ it('tests update success notification', () => {
+ spyOn(rgwUserService, 'update').and.returnValue(observableOf([]));
+ component.editing = true;
+ formHelper.setValue('suspended', true, true);
+ component.onSubmit();
+ expect(notificationService.show).toHaveBeenCalledWith(
+ NotificationType.success,
+ `Updated Object Gateway user 'null'`
+ );
+ });
+ });
+
+ describe('RgwUserCapabilities', () => {
+ it('capability button disabled when all capabilities are added', () => {
+ component.editing = true;
+ for (const capabilityType of RgwUserCapabilities.getAll()) {
+ const capability = new RgwUserCapability();
+ capability.type = capabilityType;
+ capability.perm = 'read';
+ component.setCapability(capability);
+ }
+
+ fixture.detectChanges();
+
+ expect(component.hasAllCapabilities(component.capabilities)).toBeTruthy();
+ const capabilityButton = fixture.debugElement.nativeElement.querySelector('.tc_addCapButton');
+ expect(capabilityButton.disabled).toBeTruthy();
+ });
+
+ it('capability button not disabled when not all capabilities are added', () => {
+ component.editing = true;
+
+ fixture.detectChanges();
+
+ const capabilityButton = fixture.debugElement.nativeElement.querySelector('.tc_addCapButton');
+ expect(capabilityButton.disabled).toBeFalsy();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts
new file mode 100644
index 000000000..5ab333771
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts
@@ -0,0 +1,756 @@
+import { Component, OnInit } from '@angular/core';
+import { AbstractControl, ValidationErrors, Validators } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+
+import _ from 'lodash';
+import { concat as observableConcat, forkJoin as observableForkJoin, Observable } from 'rxjs';
+
+import { RgwUserService } from '~/app/shared/api/rgw-user.service';
+import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdForm } from '~/app/shared/forms/cd-form';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators, isEmptyInputValue } from '~/app/shared/forms/cd-validators';
+import { FormatterService } from '~/app/shared/services/formatter.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { RgwUserCapabilities } from '../models/rgw-user-capabilities';
+import { RgwUserCapability } from '../models/rgw-user-capability';
+import { RgwUserS3Key } from '../models/rgw-user-s3-key';
+import { RgwUserSubuser } from '../models/rgw-user-subuser';
+import { RgwUserSwiftKey } from '../models/rgw-user-swift-key';
+import { RgwUserCapabilityModalComponent } from '../rgw-user-capability-modal/rgw-user-capability-modal.component';
+import { RgwUserS3KeyModalComponent } from '../rgw-user-s3-key-modal/rgw-user-s3-key-modal.component';
+import { RgwUserSubuserModalComponent } from '../rgw-user-subuser-modal/rgw-user-subuser-modal.component';
+import { RgwUserSwiftKeyModalComponent } from '../rgw-user-swift-key-modal/rgw-user-swift-key-modal.component';
+
+@Component({
+ selector: 'cd-rgw-user-form',
+ templateUrl: './rgw-user-form.component.html',
+ styleUrls: ['./rgw-user-form.component.scss']
+})
+export class RgwUserFormComponent extends CdForm implements OnInit {
+ userForm: CdFormGroup;
+ editing = false;
+ submitObservables: Observable<Object>[] = [];
+ icons = Icons;
+ subusers: RgwUserSubuser[] = [];
+ s3Keys: RgwUserS3Key[] = [];
+ swiftKeys: RgwUserSwiftKey[] = [];
+ capabilities: RgwUserCapability[] = [];
+
+ action: string;
+ resource: string;
+ subuserLabel: string;
+ s3keyLabel: string;
+ capabilityLabel: string;
+ usernameExists: boolean;
+ showTenant = false;
+ previousTenant: string = null;
+
+ constructor(
+ private formBuilder: CdFormBuilder,
+ private route: ActivatedRoute,
+ private router: Router,
+ private rgwUserService: RgwUserService,
+ private modalService: ModalService,
+ private notificationService: NotificationService,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ super();
+ this.resource = $localize`user`;
+ this.subuserLabel = $localize`subuser`;
+ this.s3keyLabel = $localize`S3 Key`;
+ this.capabilityLabel = $localize`capability`;
+ this.editing = this.router.url.startsWith(`/rgw/user/${URLVerbs.EDIT}`);
+ this.action = this.editing ? this.actionLabels.EDIT : this.actionLabels.CREATE;
+ this.createForm();
+ }
+
+ createForm() {
+ this.userForm = this.formBuilder.group({
+ // General
+ user_id: [
+ null,
+ [Validators.required, Validators.pattern(/^[a-zA-Z0-9!@#%^&*()_-]+$/)],
+ this.editing
+ ? []
+ : [
+ CdValidators.unique(this.rgwUserService.exists, this.rgwUserService, () =>
+ this.userForm.getValue('tenant')
+ )
+ ]
+ ],
+ show_tenant: [this.editing],
+ tenant: [
+ null,
+ [Validators.pattern(/^[a-zA-Z0-9!@#%^&*()_-]+$/)],
+ this.editing
+ ? []
+ : [
+ CdValidators.unique(
+ this.rgwUserService.exists,
+ this.rgwUserService,
+ () => this.userForm.getValue('user_id'),
+ true
+ )
+ ]
+ ],
+ display_name: [null, [Validators.required]],
+ email: [
+ null,
+ [CdValidators.email],
+ [CdValidators.unique(this.rgwUserService.emailExists, this.rgwUserService)]
+ ],
+ max_buckets_mode: [1],
+ max_buckets: [
+ 1000,
+ [CdValidators.requiredIf({ max_buckets_mode: '1' }), CdValidators.number(false)]
+ ],
+ suspended: [false],
+ // S3 key
+ generate_key: [true],
+ access_key: [null, [CdValidators.requiredIf({ generate_key: false })]],
+ secret_key: [null, [CdValidators.requiredIf({ generate_key: false })]],
+ // User quota
+ user_quota_enabled: [false],
+ user_quota_max_size_unlimited: [true],
+ user_quota_max_size: [
+ null,
+ [
+ CdValidators.composeIf(
+ {
+ user_quota_enabled: true,
+ user_quota_max_size_unlimited: false
+ },
+ [Validators.required, this.quotaMaxSizeValidator]
+ )
+ ]
+ ],
+ user_quota_max_objects_unlimited: [true],
+ user_quota_max_objects: [
+ null,
+ [
+ CdValidators.requiredIf({
+ user_quota_enabled: true,
+ user_quota_max_objects_unlimited: false
+ })
+ ]
+ ],
+ // Bucket quota
+ bucket_quota_enabled: [false],
+ bucket_quota_max_size_unlimited: [true],
+ bucket_quota_max_size: [
+ null,
+ [
+ CdValidators.composeIf(
+ {
+ bucket_quota_enabled: true,
+ bucket_quota_max_size_unlimited: false
+ },
+ [Validators.required, this.quotaMaxSizeValidator]
+ )
+ ]
+ ],
+ bucket_quota_max_objects_unlimited: [true],
+ bucket_quota_max_objects: [
+ null,
+ [
+ CdValidators.requiredIf({
+ bucket_quota_enabled: true,
+ bucket_quota_max_objects_unlimited: false
+ })
+ ]
+ ]
+ });
+ }
+
+ ngOnInit() {
+ // Process route parameters.
+ this.route.params.subscribe((params: { uid: string }) => {
+ if (!params.hasOwnProperty('uid')) {
+ this.loadingReady();
+ return;
+ }
+ const uid = decodeURIComponent(params.uid);
+ // Load the user and quota information.
+ const observables = [];
+ observables.push(this.rgwUserService.get(uid));
+ observables.push(this.rgwUserService.getQuota(uid));
+ observableForkJoin(observables).subscribe(
+ (resp: any[]) => {
+ // Get the default values.
+ const defaults = _.clone(this.userForm.value);
+ // Extract the values displayed in the form.
+ let value = _.pick(resp[0], _.keys(this.userForm.value));
+ // Map the max. buckets values.
+ switch (value['max_buckets']) {
+ case -1:
+ value['max_buckets_mode'] = -1;
+ value['max_buckets'] = '';
+ break;
+ case 0:
+ value['max_buckets_mode'] = 0;
+ value['max_buckets'] = '';
+ break;
+ default:
+ value['max_buckets_mode'] = 1;
+ break;
+ }
+ // Map the quota values.
+ ['user', 'bucket'].forEach((type) => {
+ const quota = resp[1][type + '_quota'];
+ value[type + '_quota_enabled'] = quota.enabled;
+ if (quota.max_size < 0) {
+ value[type + '_quota_max_size_unlimited'] = true;
+ value[type + '_quota_max_size'] = null;
+ } else {
+ value[type + '_quota_max_size_unlimited'] = false;
+ value[type + '_quota_max_size'] = `${quota.max_size} B`;
+ }
+ if (quota.max_objects < 0) {
+ value[type + '_quota_max_objects_unlimited'] = true;
+ value[type + '_quota_max_objects'] = null;
+ } else {
+ value[type + '_quota_max_objects_unlimited'] = false;
+ value[type + '_quota_max_objects'] = quota.max_objects;
+ }
+ });
+ // Merge with default values.
+ value = _.merge(defaults, value);
+ // Update the form.
+ this.userForm.setValue(value);
+
+ // Get the sub users.
+ this.subusers = resp[0].subusers;
+
+ // Get the keys.
+ this.s3Keys = resp[0].keys;
+ this.swiftKeys = resp[0].swift_keys;
+
+ // Process the capabilities.
+ const mapPerm = { 'read, write': '*' };
+ resp[0].caps.forEach((cap: any) => {
+ if (cap.perm in mapPerm) {
+ cap.perm = mapPerm[cap.perm];
+ }
+ });
+ this.capabilities = resp[0].caps;
+
+ this.loadingReady();
+ },
+ () => {
+ this.loadingError();
+ }
+ );
+ });
+ }
+
+ goToListView() {
+ this.router.navigate(['/rgw/user']);
+ }
+
+ onSubmit() {
+ let notificationTitle: string;
+ // Exit immediately if the form isn't dirty.
+ if (this.userForm.pristine) {
+ this.goToListView();
+ return;
+ }
+ const uid = this.getUID();
+ if (this.editing) {
+ // Edit
+ if (this._isGeneralDirty()) {
+ const args = this._getUpdateArgs();
+ this.submitObservables.push(this.rgwUserService.update(uid, args));
+ }
+ notificationTitle = $localize`Updated Object Gateway user '${uid}'`;
+ } else {
+ // Add
+ const args = this._getCreateArgs();
+ this.submitObservables.push(this.rgwUserService.create(args));
+ notificationTitle = $localize`Created Object Gateway user '${uid}'`;
+ }
+ // Check if user quota has been modified.
+ if (this._isUserQuotaDirty()) {
+ const userQuotaArgs = this._getUserQuotaArgs();
+ this.submitObservables.push(this.rgwUserService.updateQuota(uid, userQuotaArgs));
+ }
+ // Check if bucket quota has been modified.
+ if (this._isBucketQuotaDirty()) {
+ const bucketQuotaArgs = this._getBucketQuotaArgs();
+ this.submitObservables.push(this.rgwUserService.updateQuota(uid, bucketQuotaArgs));
+ }
+ // Finally execute all observables one by one in serial.
+ observableConcat(...this.submitObservables).subscribe({
+ error: () => {
+ // Reset the 'Submit' button.
+ this.userForm.setErrors({ cdSubmitButton: true });
+ },
+ complete: () => {
+ this.notificationService.show(NotificationType.success, notificationTitle);
+ this.goToListView();
+ }
+ });
+ }
+
+ updateFieldsWhenTenanted() {
+ this.showTenant = this.userForm.getValue('show_tenant');
+ if (!this.showTenant) {
+ this.userForm.get('user_id').markAsUntouched();
+ this.userForm.get('tenant').patchValue(this.previousTenant);
+ } else {
+ this.userForm.get('user_id').markAsTouched();
+ this.previousTenant = this.userForm.get('tenant').value;
+ this.userForm.get('tenant').patchValue(null);
+ }
+ }
+
+ getUID(): string {
+ let uid = this.userForm.getValue('user_id');
+ const tenant = this.userForm?.getValue('tenant');
+ if (tenant && tenant.length > 0) {
+ uid = `${this.userForm.getValue('tenant')}$${uid}`;
+ }
+ return uid;
+ }
+
+ /**
+ * Validate the quota maximum size, e.g. 1096, 1K, 30M or 1.9MiB.
+ */
+ quotaMaxSizeValidator(control: AbstractControl): ValidationErrors | null {
+ if (isEmptyInputValue(control.value)) {
+ return null;
+ }
+ const m = RegExp('^(\\d+(\\.\\d+)?)\\s*(B|K(B|iB)?|M(B|iB)?|G(B|iB)?|T(B|iB)?)?$', 'i').exec(
+ control.value
+ );
+ if (m === null) {
+ return { quotaMaxSize: true };
+ }
+ const bytes = new FormatterService().toBytes(control.value);
+ return bytes < 1024 ? { quotaMaxSize: true } : null;
+ }
+
+ /**
+ * Add/Update a subuser.
+ */
+ setSubuser(subuser: RgwUserSubuser, index?: number) {
+ const mapPermissions: Record<string, string> = {
+ 'full-control': 'full',
+ 'read-write': 'readwrite'
+ };
+ const uid = this.getUID();
+ const args = {
+ subuser: subuser.id,
+ access:
+ subuser.permissions in mapPermissions
+ ? mapPermissions[subuser.permissions]
+ : subuser.permissions,
+ key_type: 'swift',
+ secret_key: subuser.secret_key,
+ generate_secret: subuser.generate_secret ? 'true' : 'false'
+ };
+ this.submitObservables.push(this.rgwUserService.createSubuser(uid, args));
+ if (_.isNumber(index)) {
+ // Modify
+ // Create an observable to modify the subuser when the form is submitted.
+ this.subusers[index] = subuser;
+ } else {
+ // Add
+ // Create an observable to add the subuser when the form is submitted.
+ this.subusers.push(subuser);
+ // Add a Swift key. If the secret key is auto-generated, then visualize
+ // this to the user by displaying a notification instead of the key.
+ this.swiftKeys.push({
+ user: subuser.id,
+ secret_key: subuser.generate_secret ? 'Apply your changes first...' : subuser.secret_key
+ });
+ }
+ // Mark the form as dirty to be able to submit it.
+ this.userForm.markAsDirty();
+ }
+
+ /**
+ * Delete a subuser.
+ * @param {number} index The subuser to delete.
+ */
+ deleteSubuser(index: number) {
+ const subuser = this.subusers[index];
+ // Create an observable to delete the subuser when the form is submitted.
+ this.submitObservables.push(this.rgwUserService.deleteSubuser(this.getUID(), subuser.id));
+ // Remove the associated S3 keys.
+ this.s3Keys = this.s3Keys.filter((key) => {
+ return key.user !== subuser.id;
+ });
+ // Remove the associated Swift keys.
+ this.swiftKeys = this.swiftKeys.filter((key) => {
+ return key.user !== subuser.id;
+ });
+ // Remove the subuser to update the UI.
+ this.subusers.splice(index, 1);
+ // Mark the form as dirty to be able to submit it.
+ this.userForm.markAsDirty();
+ }
+
+ /**
+ * Add/Update a capability.
+ */
+ setCapability(cap: RgwUserCapability, index?: number) {
+ const uid = this.getUID();
+ if (_.isNumber(index)) {
+ // Modify
+ const oldCap = this.capabilities[index];
+ // Note, the RadosGW Admin OPS API does not support the modification of
+ // user capabilities. Because of that it is necessary to delete it and
+ // then to re-add the capability with its new value/permission.
+ this.submitObservables.push(
+ this.rgwUserService.deleteCapability(uid, oldCap.type, oldCap.perm)
+ );
+ this.submitObservables.push(this.rgwUserService.addCapability(uid, cap.type, cap.perm));
+ this.capabilities[index] = cap;
+ } else {
+ // Add
+ // Create an observable to add the capability when the form is submitted.
+ this.submitObservables.push(this.rgwUserService.addCapability(uid, cap.type, cap.perm));
+ this.capabilities = [...this.capabilities, cap]; // Notify Angular CD
+ }
+ // Mark the form as dirty to be able to submit it.
+ this.userForm.markAsDirty();
+ }
+
+ /**
+ * Delete the given capability:
+ * - Delete it from the local array to update the UI
+ * - Create an observable that will be executed on form submit
+ * @param {number} index The capability to delete.
+ */
+ deleteCapability(index: number) {
+ const cap = this.capabilities[index];
+ // Create an observable to delete the capability when the form is submitted.
+ this.submitObservables.push(
+ this.rgwUserService.deleteCapability(this.getUID(), cap.type, cap.perm)
+ );
+ // Remove the capability to update the UI.
+ this.capabilities.splice(index, 1);
+ this.capabilities = [...this.capabilities]; // Notify Angular CD
+ // Mark the form as dirty to be able to submit it.
+ this.userForm.markAsDirty();
+ }
+
+ hasAllCapabilities(capabilities: RgwUserCapability[]) {
+ return !_.difference(RgwUserCapabilities.getAll(), _.map(capabilities, 'type')).length;
+ }
+
+ /**
+ * Add/Update a S3 key.
+ */
+ setS3Key(key: RgwUserS3Key, index?: number) {
+ if (_.isNumber(index)) {
+ // Modify
+ // Nothing to do here at the moment.
+ } else {
+ // Add
+ // Split the key's user name into its user and subuser parts.
+ const userMatches = key.user.match(/([^:]+)(:(.+))?/);
+ // Create an observable to add the S3 key when the form is submitted.
+ const uid = userMatches[1];
+ const args = {
+ subuser: userMatches[2] ? userMatches[3] : '',
+ generate_key: key.generate_key ? 'true' : 'false'
+ };
+ if (args['generate_key'] === 'false') {
+ if (!_.isNil(key.access_key)) {
+ args['access_key'] = key.access_key;
+ }
+ if (!_.isNil(key.secret_key)) {
+ args['secret_key'] = key.secret_key;
+ }
+ }
+ this.submitObservables.push(this.rgwUserService.addS3Key(uid, args));
+ // If the access and the secret key are auto-generated, then visualize
+ // this to the user by displaying a notification instead of the key.
+ this.s3Keys.push({
+ user: key.user,
+ access_key: key.generate_key ? 'Apply your changes first...' : key.access_key,
+ secret_key: key.generate_key ? 'Apply your changes first...' : key.secret_key
+ });
+ }
+ // Mark the form as dirty to be able to submit it.
+ this.userForm.markAsDirty();
+ }
+
+ /**
+ * Delete a S3 key.
+ * @param {number} index The S3 key to delete.
+ */
+ deleteS3Key(index: number) {
+ const key = this.s3Keys[index];
+ // Create an observable to delete the S3 key when the form is submitted.
+ this.submitObservables.push(this.rgwUserService.deleteS3Key(this.getUID(), key.access_key));
+ // Remove the S3 key to update the UI.
+ this.s3Keys.splice(index, 1);
+ // Mark the form as dirty to be able to submit it.
+ this.userForm.markAsDirty();
+ }
+
+ /**
+ * Show the specified subuser in a modal dialog.
+ * @param {number | undefined} index The subuser to show.
+ */
+ showSubuserModal(index?: number) {
+ const uid = this.getUID();
+ const modalRef = this.modalService.show(RgwUserSubuserModalComponent);
+ if (_.isNumber(index)) {
+ // Edit
+ const subuser = this.subusers[index];
+ modalRef.componentInstance.setEditing();
+ modalRef.componentInstance.setValues(uid, subuser.id, subuser.permissions);
+ } else {
+ // Add
+ modalRef.componentInstance.setEditing(false);
+ modalRef.componentInstance.setValues(uid);
+ modalRef.componentInstance.setSubusers(this.subusers);
+ }
+ modalRef.componentInstance.submitAction.subscribe((subuser: RgwUserSubuser) => {
+ this.setSubuser(subuser, index);
+ });
+ }
+
+ /**
+ * Show the specified S3 key in a modal dialog.
+ * @param {number | undefined} index The S3 key to show.
+ */
+ showS3KeyModal(index?: number) {
+ const modalRef = this.modalService.show(RgwUserS3KeyModalComponent);
+ if (_.isNumber(index)) {
+ // View
+ const key = this.s3Keys[index];
+ modalRef.componentInstance.setViewing();
+ modalRef.componentInstance.setValues(key.user, key.access_key, key.secret_key);
+ } else {
+ // Add
+ const candidates = this._getS3KeyUserCandidates();
+ modalRef.componentInstance.setViewing(false);
+ modalRef.componentInstance.setUserCandidates(candidates);
+ modalRef.componentInstance.submitAction.subscribe((key: RgwUserS3Key) => {
+ this.setS3Key(key);
+ });
+ }
+ }
+
+ /**
+ * Show the specified Swift key in a modal dialog.
+ * @param {number} index The Swift key to show.
+ */
+ showSwiftKeyModal(index: number) {
+ const modalRef = this.modalService.show(RgwUserSwiftKeyModalComponent);
+ const key = this.swiftKeys[index];
+ modalRef.componentInstance.setValues(key.user, key.secret_key);
+ }
+
+ /**
+ * Show the specified capability in a modal dialog.
+ * @param {number | undefined} index The S3 key to show.
+ */
+ showCapabilityModal(index?: number) {
+ const modalRef = this.modalService.show(RgwUserCapabilityModalComponent);
+ if (_.isNumber(index)) {
+ // Edit
+ const cap = this.capabilities[index];
+ modalRef.componentInstance.setEditing();
+ modalRef.componentInstance.setValues(cap.type, cap.perm);
+ } else {
+ // Add
+ modalRef.componentInstance.setEditing(false);
+ modalRef.componentInstance.setCapabilities(this.capabilities);
+ }
+ modalRef.componentInstance.submitAction.subscribe((cap: RgwUserCapability) => {
+ this.setCapability(cap, index);
+ });
+ }
+
+ /**
+ * Check if the general user settings (display name, email, ...) have been modified.
+ * @return {Boolean} Returns TRUE if the general user settings have been modified.
+ */
+ private _isGeneralDirty(): boolean {
+ return ['display_name', 'email', 'max_buckets_mode', 'max_buckets', 'suspended'].some(
+ (path) => {
+ return this.userForm.get(path).dirty;
+ }
+ );
+ }
+
+ /**
+ * Check if the user quota has been modified.
+ * @return {Boolean} Returns TRUE if the user quota has been modified.
+ */
+ private _isUserQuotaDirty(): boolean {
+ return [
+ 'user_quota_enabled',
+ 'user_quota_max_size_unlimited',
+ 'user_quota_max_size',
+ 'user_quota_max_objects_unlimited',
+ 'user_quota_max_objects'
+ ].some((path) => {
+ return this.userForm.get(path).dirty;
+ });
+ }
+
+ /**
+ * Check if the bucket quota has been modified.
+ * @return {Boolean} Returns TRUE if the bucket quota has been modified.
+ */
+ private _isBucketQuotaDirty(): boolean {
+ return [
+ 'bucket_quota_enabled',
+ 'bucket_quota_max_size_unlimited',
+ 'bucket_quota_max_size',
+ 'bucket_quota_max_objects_unlimited',
+ 'bucket_quota_max_objects'
+ ].some((path) => {
+ return this.userForm.get(path).dirty;
+ });
+ }
+
+ /**
+ * Helper function to get the arguments of the API request when a new
+ * user is created.
+ */
+ private _getCreateArgs() {
+ const result = {
+ uid: this.getUID(),
+ display_name: this.userForm.getValue('display_name'),
+ suspended: this.userForm.getValue('suspended'),
+ email: '',
+ max_buckets: this.userForm.getValue('max_buckets'),
+ generate_key: this.userForm.getValue('generate_key'),
+ access_key: '',
+ secret_key: ''
+ };
+ const email = this.userForm.getValue('email');
+ if (_.isString(email) && email.length > 0) {
+ _.merge(result, { email: email });
+ }
+ const generateKey = this.userForm.getValue('generate_key');
+ if (!generateKey) {
+ _.merge(result, {
+ generate_key: false,
+ access_key: this.userForm.getValue('access_key'),
+ secret_key: this.userForm.getValue('secret_key')
+ });
+ }
+ const maxBucketsMode = parseInt(this.userForm.getValue('max_buckets_mode'), 10);
+ if (_.includes([-1, 0], maxBucketsMode)) {
+ // -1 => Disable bucket creation.
+ // 0 => Unlimited bucket creation.
+ _.merge(result, { max_buckets: maxBucketsMode });
+ }
+ return result;
+ }
+
+ /**
+ * Helper function to get the arguments for the API request when the user
+ * configuration has been modified.
+ */
+ private _getUpdateArgs() {
+ const result: Record<string, any> = {};
+ const keys = ['display_name', 'email', 'max_buckets', 'suspended'];
+ for (const key of keys) {
+ result[key] = this.userForm.getValue(key);
+ }
+ const maxBucketsMode = parseInt(this.userForm.getValue('max_buckets_mode'), 10);
+ if (_.includes([-1, 0], maxBucketsMode)) {
+ // -1 => Disable bucket creation.
+ // 0 => Unlimited bucket creation.
+ result['max_buckets'] = maxBucketsMode;
+ }
+ return result;
+ }
+
+ /**
+ * Helper function to get the arguments for the API request when the user
+ * quota configuration has been modified.
+ */
+ private _getUserQuotaArgs(): Record<string, any> {
+ const result = {
+ quota_type: 'user',
+ enabled: this.userForm.getValue('user_quota_enabled'),
+ max_size_kb: -1,
+ max_objects: -1
+ };
+ if (!this.userForm.getValue('user_quota_max_size_unlimited')) {
+ // Convert the given value to bytes.
+ const bytes = new FormatterService().toBytes(this.userForm.getValue('user_quota_max_size'));
+ // Finally convert the value to KiB.
+ result['max_size_kb'] = (bytes / 1024).toFixed(0) as any;
+ }
+ if (!this.userForm.getValue('user_quota_max_objects_unlimited')) {
+ result['max_objects'] = this.userForm.getValue('user_quota_max_objects');
+ }
+ return result;
+ }
+
+ /**
+ * Helper function to get the arguments for the API request when the bucket
+ * quota configuration has been modified.
+ */
+ private _getBucketQuotaArgs(): Record<string, any> {
+ const result = {
+ quota_type: 'bucket',
+ enabled: this.userForm.getValue('bucket_quota_enabled'),
+ max_size_kb: -1,
+ max_objects: -1
+ };
+ if (!this.userForm.getValue('bucket_quota_max_size_unlimited')) {
+ // Convert the given value to bytes.
+ const bytes = new FormatterService().toBytes(this.userForm.getValue('bucket_quota_max_size'));
+ // Finally convert the value to KiB.
+ result['max_size_kb'] = (bytes / 1024).toFixed(0) as any;
+ }
+ if (!this.userForm.getValue('bucket_quota_max_objects_unlimited')) {
+ result['max_objects'] = this.userForm.getValue('bucket_quota_max_objects');
+ }
+ return result;
+ }
+
+ /**
+ * Helper method to get the user candidates for S3 keys.
+ * @returns {Array} Returns a list of user identifiers.
+ */
+ private _getS3KeyUserCandidates() {
+ let result = [];
+ // Add the current user id.
+ const uid = this.getUID();
+ if (_.isString(uid) && !_.isEmpty(uid)) {
+ result.push(uid);
+ }
+ // Append the subusers.
+ this.subusers.forEach((subUser) => {
+ result.push(subUser.id);
+ });
+ // Note that it's possible to create multiple S3 key pairs for a user,
+ // thus we append already configured users, too.
+ this.s3Keys.forEach((key) => {
+ result.push(key.user);
+ });
+ result = _.uniq(result);
+ return result;
+ }
+
+ onMaxBucketsModeChange(mode: string) {
+ if (mode === '1') {
+ // If 'Custom' mode is selected, then ensure that the form field
+ // 'Max. buckets' contains a valid value. Set it to default if
+ // necessary.
+ if (!this.userForm.get('max_buckets').valid) {
+ this.userForm.patchValue({
+ max_buckets: 1000
+ });
+ }
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html
new file mode 100644
index 000000000..6c6d7677e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html
@@ -0,0 +1,44 @@
+<cd-table #table
+ [autoReload]="false"
+ [data]="users"
+ [columns]="columns"
+ columnMode="flex"
+ selectionType="multiClick"
+ [hasDetails]="true"
+ (setExpandedRow)="setExpandedRow($event)"
+ (updateSelection)="updateSelection($event)"
+ identifier="uid"
+ (fetchData)="getUserList($event)"
+ [status]="tableStatus">
+ <cd-table-actions class="table-actions"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ <cd-rgw-user-details cdTableDetail
+ [selection]="expandedRow">
+ </cd-rgw-user-details>
+</cd-table>
+
+<ng-template #userSizeTpl
+ let-row="row">
+ <cd-usage-bar *ngIf="row.user_quota.max_size > 0 && row.user_quota.enabled; else noSizeQuota"
+ [total]="row.user_quota.max_size"
+ [used]="row.stats.size_actual">
+ </cd-usage-bar>
+
+ <ng-template #noSizeQuota
+ i18n>No Limit</ng-template>
+</ng-template>
+
+<ng-template #userObjectTpl
+ let-row="row">
+ <cd-usage-bar *ngIf="row.user_quota.max_objects > 0 && row.user_quota.enabled; else noObjectQuota"
+ [total]="row.user_quota.max_objects"
+ [used]="row.stats.num_objects"
+ [isBinary]="false">
+ </cd-usage-bar>
+
+ <ng-template #noObjectQuota
+ i18n>No Limit</ng-template>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.spec.ts
new file mode 100644
index 000000000..2f886ccf5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.spec.ts
@@ -0,0 +1,166 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { of } from 'rxjs';
+
+import { RgwUserService } from '~/app/shared/api/rgw-user.service';
+import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, PermissionHelper } from '~/testing/unit-test-helper';
+import { RgwUserListComponent } from './rgw-user-list.component';
+
+describe('RgwUserListComponent', () => {
+ let component: RgwUserListComponent;
+ let fixture: ComponentFixture<RgwUserListComponent>;
+ let rgwUserService: RgwUserService;
+ let rgwUserServiceListSpy: jasmine.Spy;
+
+ configureTestBed({
+ declarations: [RgwUserListComponent],
+ imports: [BrowserAnimationsModule, RouterTestingModule, HttpClientTestingModule, SharedModule],
+ schemas: [NO_ERRORS_SCHEMA]
+ });
+
+ beforeEach(() => {
+ rgwUserService = TestBed.inject(RgwUserService);
+ rgwUserServiceListSpy = spyOn(rgwUserService, 'list');
+ rgwUserServiceListSpy.and.returnValue(of([]));
+ fixture = TestBed.createComponent(RgwUserListComponent);
+ component = fixture.componentInstance;
+ spyOn(component, 'setTableRefreshTimeout').and.stub();
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ expect(rgwUserServiceListSpy).toHaveBeenCalledTimes(1);
+ });
+
+ it('should test all TableActions combinations', () => {
+ const permissionHelper: PermissionHelper = new PermissionHelper(component.permission);
+ const tableActions: TableActionsComponent = permissionHelper.setPermissionsAndGetActions(
+ component.tableActions
+ );
+
+ expect(tableActions).toEqual({
+ 'create,update,delete': {
+ actions: ['Create', 'Edit', 'Delete'],
+ primary: { multiple: 'Delete', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,update': {
+ actions: ['Create', 'Edit'],
+ primary: { multiple: 'Create', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,delete': {
+ actions: ['Create', 'Delete'],
+ primary: { multiple: 'Delete', executing: 'Create', single: 'Create', no: 'Create' }
+ },
+ create: {
+ actions: ['Create'],
+ primary: { multiple: 'Create', executing: 'Create', single: 'Create', no: 'Create' }
+ },
+ 'update,delete': {
+ actions: ['Edit', 'Delete'],
+ primary: { multiple: 'Delete', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ update: {
+ actions: ['Edit'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ delete: {
+ actions: ['Delete'],
+ primary: { multiple: 'Delete', executing: 'Delete', single: 'Delete', no: 'Delete' }
+ },
+ 'no-permissions': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ }
+ });
+ });
+
+ it('should test if rgw-user data is tranformed correctly', () => {
+ rgwUserServiceListSpy.and.returnValue(
+ of([
+ {
+ user_id: 'testid',
+ stats: {
+ size_actual: 6,
+ num_objects: 6
+ },
+ user_quota: {
+ max_size: 20,
+ max_objects: 10,
+ enabled: true
+ }
+ }
+ ])
+ );
+ component.getUserList(null);
+ expect(rgwUserServiceListSpy).toHaveBeenCalledTimes(2);
+ expect(component.users).toEqual([
+ {
+ user_id: 'testid',
+ stats: {
+ size_actual: 6,
+ num_objects: 6
+ },
+ user_quota: {
+ max_size: 20,
+ max_objects: 10,
+ enabled: true
+ }
+ }
+ ]);
+ });
+
+ it('should usage bars only if quota enabled', () => {
+ rgwUserServiceListSpy.and.returnValue(
+ of([
+ {
+ user_id: 'testid',
+ stats: {
+ size_actual: 6,
+ num_objects: 6
+ },
+ user_quota: {
+ max_size: 1024,
+ max_objects: 10,
+ enabled: true
+ }
+ }
+ ])
+ );
+ component.getUserList(null);
+ expect(rgwUserServiceListSpy).toHaveBeenCalledTimes(2);
+ fixture.detectChanges();
+ const usageBars = fixture.debugElement.nativeElement.querySelectorAll('cd-usage-bar');
+ expect(usageBars.length).toBe(2);
+ });
+
+ it('should not show any usage bars if quota disabled', () => {
+ rgwUserServiceListSpy.and.returnValue(
+ of([
+ {
+ user_id: 'testid',
+ stats: {
+ size_actual: 6,
+ num_objects: 6
+ },
+ user_quota: {
+ max_size: 1024,
+ max_objects: 10,
+ enabled: false
+ }
+ }
+ ])
+ );
+ component.getUserList(null);
+ expect(rgwUserServiceListSpy).toHaveBeenCalledTimes(2);
+ fixture.detectChanges();
+ const usageBars = fixture.debugElement.nativeElement.querySelectorAll('cd-usage-bar');
+ expect(usageBars.length).toBe(0);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts
new file mode 100644
index 000000000..34cccb940
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts
@@ -0,0 +1,180 @@
+import { Component, NgZone, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import { forkJoin as observableForkJoin, Observable, Subscriber } from 'rxjs';
+
+import { RgwUserService } from '~/app/shared/api/rgw-user.service';
+import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { TableComponent } from '~/app/shared/datatable/table/table.component';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { URLBuilderService } from '~/app/shared/services/url-builder.service';
+
+const BASE_URL = 'rgw/user';
+
+@Component({
+ selector: 'cd-rgw-user-list',
+ templateUrl: './rgw-user-list.component.html',
+ styleUrls: ['./rgw-user-list.component.scss'],
+ providers: [{ provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }]
+})
+export class RgwUserListComponent extends ListWithDetails implements OnInit {
+ @ViewChild(TableComponent, { static: true })
+ table: TableComponent;
+ @ViewChild('userSizeTpl', { static: true })
+ userSizeTpl: TemplateRef<any>;
+ @ViewChild('userObjectTpl', { static: true })
+ userObjectTpl: TemplateRef<any>;
+ permission: Permission;
+ tableActions: CdTableAction[];
+ columns: CdTableColumn[] = [];
+ users: object[] = [];
+ selection: CdTableSelection = new CdTableSelection();
+ staleTimeout: number;
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private rgwUserService: RgwUserService,
+ private modalService: ModalService,
+ private urlBuilder: URLBuilderService,
+ public actionLabels: ActionLabelsI18n,
+ protected ngZone: NgZone
+ ) {
+ super(ngZone);
+ }
+
+ ngOnInit() {
+ this.permission = this.authStorageService.getPermissions().rgw;
+ this.columns = [
+ {
+ name: $localize`Username`,
+ prop: 'uid',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Tenant`,
+ prop: 'tenant',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Full name`,
+ prop: 'display_name',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Email address`,
+ prop: 'email',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Suspended`,
+ prop: 'suspended',
+ flexGrow: 1,
+ cellClass: 'text-center',
+ cellTransformation: CellTemplate.checkIcon
+ },
+ {
+ name: $localize`Max. buckets`,
+ prop: 'max_buckets',
+ flexGrow: 1,
+ cellTransformation: CellTemplate.map,
+ customTemplateConfig: {
+ '-1': $localize`Disabled`,
+ 0: $localize`Unlimited`
+ }
+ },
+ {
+ name: $localize`Capacity Limit %`,
+ prop: 'size_usage',
+ cellTemplate: this.userSizeTpl,
+ flexGrow: 0.8
+ },
+ {
+ name: $localize`Object Limit %`,
+ prop: 'object_usage',
+ cellTemplate: this.userObjectTpl,
+ flexGrow: 0.8
+ }
+ ];
+ const getUserUri = () =>
+ this.selection.first() && `${encodeURIComponent(this.selection.first().uid)}`;
+ const addAction: CdTableAction = {
+ permission: 'create',
+ icon: Icons.add,
+ routerLink: () => this.urlBuilder.getCreate(),
+ name: this.actionLabels.CREATE,
+ canBePrimary: (selection: CdTableSelection) => !selection.hasSelection
+ };
+ const editAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.edit,
+ routerLink: () => this.urlBuilder.getEdit(getUserUri()),
+ name: this.actionLabels.EDIT
+ };
+ const deleteAction: CdTableAction = {
+ permission: 'delete',
+ icon: Icons.destroy,
+ click: () => this.deleteAction(),
+ disable: () => !this.selection.hasSelection,
+ name: this.actionLabels.DELETE,
+ canBePrimary: (selection: CdTableSelection) => selection.hasMultiSelection
+ };
+ this.tableActions = [addAction, editAction, deleteAction];
+ this.setTableRefreshTimeout();
+ }
+
+ getUserList(context: CdTableFetchDataContext) {
+ this.setTableRefreshTimeout();
+ this.rgwUserService.list().subscribe(
+ (resp: object[]) => {
+ this.users = resp;
+ },
+ () => {
+ context.error();
+ }
+ );
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ deleteAction() {
+ this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: this.selection.hasSingleSelection ? $localize`user` : $localize`users`,
+ itemNames: this.selection.selected.map((user: any) => user['uid']),
+ submitActionObservable: (): Observable<any> => {
+ return new Observable((observer: Subscriber<any>) => {
+ // Delete all selected data table rows.
+ observableForkJoin(
+ this.selection.selected.map((user: any) => {
+ return this.rgwUserService.delete(user.uid);
+ })
+ ).subscribe({
+ error: (error) => {
+ // Forward the error to the observer.
+ observer.error(error);
+ // Reload the data table content because some deletions might
+ // have been executed successfully in the meanwhile.
+ this.table.refreshBtn();
+ },
+ complete: () => {
+ // Notify the observer that we are done.
+ observer.complete();
+ // Reload the data table content.
+ this.table.refreshBtn();
+ }
+ });
+ });
+ }
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html
new file mode 100644
index 000000000..6ec8978af
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html
@@ -0,0 +1,125 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container i18n="form title"
+ class="modal-title">{{ action | titlecase }} {{ resource | upperFirst }}</ng-container>
+
+ <ng-container class="modal-content">
+ <form #frm="ngForm"
+ [formGroup]="formGroup"
+ novalidate>
+ <div class="modal-body">
+
+ <!-- Username -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': !viewing}"
+ for="user"
+ i18n>Username</label>
+ <div class="cd-col-form-input">
+ <input id="user"
+ class="form-control"
+ type="text"
+ *ngIf="viewing"
+ [readonly]="true"
+ formControlName="user">
+ <select id="user"
+ class="form-control"
+ formControlName="user"
+ *ngIf="!viewing"
+ autofocus>
+ <option i18n
+ *ngIf="userCandidates !== null"
+ [ngValue]="null">-- Select a username --</option>
+ <option *ngFor="let userCandidate of userCandidates"
+ [value]="userCandidate">{{ userCandidate }}</option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="formGroup.showError('user', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Auto-generate key -->
+ <div class="form-group row"
+ *ngIf="!viewing">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="generate_key"
+ type="checkbox"
+ formControlName="generate_key">
+ <label class="custom-control-label"
+ for="generate_key"
+ i18n>Auto-generate key</label>
+ </div>
+ </div>
+ </div>
+
+ <!-- Access key -->
+ <div class="form-group row"
+ *ngIf="!formGroup.getValue('generate_key')">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': !viewing}"
+ for="access_key"
+ i18n>Access key</label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input id="access_key"
+ class="form-control"
+ type="password"
+ [readonly]="viewing"
+ formControlName="access_key">
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="access_key">
+ </button>
+ <cd-copy-2-clipboard-button source="access_key">
+ </cd-copy-2-clipboard-button>
+ </span>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="formGroup.showError('access_key', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Secret key -->
+ <div class="form-group row"
+ *ngIf="!formGroup.getValue('generate_key')">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': !viewing}"
+ for="secret_key"
+ i18n>Secret key</label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input id="secret_key"
+ class="form-control"
+ type="password"
+ [readonly]="viewing"
+ formControlName="secret_key">
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="secret_key">
+ </button>
+ <cd-copy-2-clipboard-button source="secret_key">
+ </cd-copy-2-clipboard-button>
+ </span>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="formGroup.showError('secret_key', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ </div>
+
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="onSubmit()"
+ [form]="formGroup"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
+ [showSubmit]="!viewing"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.spec.ts
new file mode 100644
index 000000000..b6152c59f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.spec.ts
@@ -0,0 +1,30 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RgwUserS3KeyModalComponent } from './rgw-user-s3-key-modal.component';
+
+describe('RgwUserS3KeyModalComponent', () => {
+ let component: RgwUserS3KeyModalComponent;
+ let fixture: ComponentFixture<RgwUserS3KeyModalComponent>;
+
+ configureTestBed({
+ declarations: [RgwUserS3KeyModalComponent],
+ imports: [ReactiveFormsModule, SharedModule, RouterTestingModule],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RgwUserS3KeyModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts
new file mode 100644
index 000000000..23566e87c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts
@@ -0,0 +1,84 @@
+import { Component, EventEmitter, Output } from '@angular/core';
+import { Validators } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { RgwUserS3Key } from '../models/rgw-user-s3-key';
+
+@Component({
+ selector: 'cd-rgw-user-s3-key-modal',
+ templateUrl: './rgw-user-s3-key-modal.component.html',
+ styleUrls: ['./rgw-user-s3-key-modal.component.scss']
+})
+export class RgwUserS3KeyModalComponent {
+ /**
+ * The event that is triggered when the 'Add' button as been pressed.
+ */
+ @Output()
+ submitAction = new EventEmitter();
+
+ formGroup: CdFormGroup;
+ viewing = true;
+ userCandidates: string[] = [];
+ resource: string;
+ action: string;
+
+ constructor(
+ private formBuilder: CdFormBuilder,
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ this.resource = $localize`S3 Key`;
+ this.createForm();
+ }
+
+ createForm() {
+ this.formGroup = this.formBuilder.group({
+ user: [null, [Validators.required]],
+ generate_key: [true],
+ access_key: [null, [CdValidators.requiredIf({ generate_key: false })]],
+ secret_key: [null, [CdValidators.requiredIf({ generate_key: false })]]
+ });
+ }
+
+ /**
+ * Set the 'viewing' flag. If set to TRUE, the modal dialog is in 'View' mode,
+ * otherwise in 'Add' mode. According to the mode the dialog and its controls
+ * behave different.
+ * @param {boolean} viewing
+ */
+ setViewing(viewing: boolean = true) {
+ this.viewing = viewing;
+ this.action = this.viewing ? this.actionLabels.SHOW : this.actionLabels.CREATE;
+ }
+
+ /**
+ * Set the values displayed in the dialog.
+ */
+ setValues(user: string, access_key: string, secret_key: string) {
+ this.formGroup.setValue({
+ user: user,
+ generate_key: _.isEmpty(access_key),
+ access_key: access_key,
+ secret_key: secret_key
+ });
+ }
+
+ /**
+ * Set the user candidates displayed in the 'Username' dropdown box.
+ */
+ setUserCandidates(candidates: string[]) {
+ this.userCandidates = candidates;
+ }
+
+ onSubmit() {
+ const key: RgwUserS3Key = this.formGroup.value;
+ this.submitAction.emit(key);
+ this.activeModal.close();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html
new file mode 100644
index 000000000..4fb03f019
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html
@@ -0,0 +1,128 @@
+<cd-modal [modalRef]="bsModalRef">
+ <ng-container i18n="form title"
+ class="modal-title">{{ action | titlecase }} {{ resource | upperFirst }}</ng-container>
+ <ng-container class="modal-content">
+ <form #frm="ngForm"
+ [formGroup]="formGroup"
+ novalidate>
+ <div class="modal-body">
+
+ <!-- Username -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="uid"
+ i18n>Username</label>
+ <div class="cd-col-form-input">
+ <input id="uid"
+ class="form-control"
+ type="text"
+ formControlName="uid"
+ [readonly]="true">
+ </div>
+ </div>
+
+ <!-- Subuser -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': !editing}"
+ for="subuid"
+ i18n>Subuser</label>
+ <div class="cd-col-form-input">
+ <input id="subuid"
+ class="form-control"
+ type="text"
+ formControlName="subuid"
+ [readonly]="editing"
+ autofocus>
+ <span class="invalid-feedback"
+ *ngIf="formGroup.showError('subuid', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="formGroup.showError('subuid', frm, 'subuserIdExists')"
+ i18n>The chosen subuser ID is already in use.</span>
+ </div>
+ </div>
+
+ <!-- Permission -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="perm"
+ i18n>Permission</label>
+ <div class="cd-col-form-input">
+ <select id="perm"
+ class="form-control"
+ formControlName="perm">
+ <option i18n
+ [ngValue]="null">-- Select a permission --</option>
+ <option *ngFor="let perm of ['read', 'write']"
+ [value]="perm">
+ {{ perm }}
+ </option>
+ <option i18n
+ value="read-write">read, write</option>
+ <option i18n
+ value="full-control">full</option>
+ </select>
+ <span class="invalid-feedback"
+ *ngIf="formGroup.showError('perm', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Swift key -->
+ <fieldset *ngIf="!editing">
+ <legend i18n>Swift key</legend>
+
+ <!-- Auto-generate key -->
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="generate_secret"
+ type="checkbox"
+ formControlName="generate_secret">
+ <label class="custom-control-label"
+ for="generate_secret"
+ i18n>Auto-generate secret</label>
+ </div>
+ </div>
+ </div>
+
+ <!-- Secret key -->
+ <div class="form-group row"
+ *ngIf="!editing && !formGroup.getValue('generate_secret')">
+ <label class="cd-col-form-label required"
+ for="secret_key"
+ i18n>Secret key</label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input id="secret_key"
+ class="form-control"
+ type="password"
+ formControlName="secret_key">
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="secret_key">
+ </button>
+ <cd-copy-2-clipboard-button source="secret_key">
+ </cd-copy-2-clipboard-button>
+ </span>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="formGroup.showError('secret_key', frm, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ </fieldset>
+
+ </div>
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="onSubmit()"
+ [form]="formGroup"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.spec.ts
new file mode 100644
index 000000000..d4843aa9d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.spec.ts
@@ -0,0 +1,71 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormControl, ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RgwUserSubuserModalComponent } from './rgw-user-subuser-modal.component';
+
+describe('RgwUserSubuserModalComponent', () => {
+ let component: RgwUserSubuserModalComponent;
+ let fixture: ComponentFixture<RgwUserSubuserModalComponent>;
+
+ configureTestBed({
+ declarations: [RgwUserSubuserModalComponent],
+ imports: [ReactiveFormsModule, SharedModule, RouterTestingModule],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RgwUserSubuserModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('subuserValidator', () => {
+ beforeEach(() => {
+ component.editing = false;
+ component.subusers = [
+ { id: 'Edith', permissions: 'full-control' },
+ { id: 'Edith:images', permissions: 'read-write' }
+ ];
+ });
+
+ it('should validate subuser (1/5)', () => {
+ component.editing = true;
+ const validatorFn = component.subuserValidator();
+ const resp = validatorFn(new FormControl());
+ expect(resp).toBe(null);
+ });
+
+ it('should validate subuser (2/5)', () => {
+ const validatorFn = component.subuserValidator();
+ const resp = validatorFn(new FormControl(''));
+ expect(resp).toBe(null);
+ });
+
+ it('should validate subuser (3/5)', () => {
+ const validatorFn = component.subuserValidator();
+ const resp = validatorFn(new FormControl('Melissa'));
+ expect(resp).toBe(null);
+ });
+
+ it('should validate subuser (4/5)', () => {
+ const validatorFn = component.subuserValidator();
+ const resp = validatorFn(new FormControl('Edith'));
+ expect(resp.subuserIdExists).toBeTruthy();
+ });
+
+ it('should validate subuser (5/5)', () => {
+ const validatorFn = component.subuserValidator();
+ const resp = validatorFn(new FormControl('images'));
+ expect(resp.subuserIdExists).toBeTruthy();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts
new file mode 100644
index 000000000..32aef91fe
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts
@@ -0,0 +1,130 @@
+import { Component, EventEmitter, Output } from '@angular/core';
+import { AbstractControl, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators, isEmptyInputValue } from '~/app/shared/forms/cd-validators';
+import { RgwUserSubuser } from '../models/rgw-user-subuser';
+
+@Component({
+ selector: 'cd-rgw-user-subuser-modal',
+ templateUrl: './rgw-user-subuser-modal.component.html',
+ styleUrls: ['./rgw-user-subuser-modal.component.scss']
+})
+export class RgwUserSubuserModalComponent {
+ /**
+ * The event that is triggered when the 'Add' or 'Update' button
+ * has been pressed.
+ */
+ @Output()
+ submitAction = new EventEmitter();
+
+ formGroup: CdFormGroup;
+ editing = true;
+ subusers: RgwUserSubuser[] = [];
+ resource: string;
+ action: string;
+
+ constructor(
+ private formBuilder: CdFormBuilder,
+ public bsModalRef: NgbActiveModal,
+ private actionLabels: ActionLabelsI18n
+ ) {
+ this.resource = $localize`Subuser`;
+ this.createForm();
+ }
+
+ createForm() {
+ this.formGroup = this.formBuilder.group({
+ uid: [null],
+ subuid: [null, [Validators.required, this.subuserValidator()]],
+ perm: [null, [Validators.required]],
+ // Swift key
+ generate_secret: [true],
+ secret_key: [null, [CdValidators.requiredIf({ generate_secret: false })]]
+ });
+ }
+
+ /**
+ * Validates whether the subuser already exists.
+ */
+ subuserValidator(): ValidatorFn {
+ const self = this;
+ return (control: AbstractControl): ValidationErrors | null => {
+ if (self.editing) {
+ return null;
+ }
+ if (isEmptyInputValue(control.value)) {
+ return null;
+ }
+ const found = self.subusers.some((subuser) => {
+ return _.isEqual(self.getSubuserName(subuser.id), control.value);
+ });
+ return found ? { subuserIdExists: true } : null;
+ };
+ }
+
+ /**
+ * Get the subuser name.
+ * Examples:
+ * 'johndoe' => 'johndoe'
+ * 'janedoe:xyz' => 'xyz'
+ * @param {string} value The value to process.
+ * @returns {string} Returns the user ID.
+ */
+ private getSubuserName(value: string) {
+ if (_.isEmpty(value)) {
+ return value;
+ }
+ const matches = value.match(/([^:]+)(:(.+))?/);
+ return _.isUndefined(matches[3]) ? matches[1] : matches[3];
+ }
+
+ /**
+ * Set the 'editing' flag. If set to TRUE, the modal dialog is in 'Edit' mode,
+ * otherwise in 'Add' mode. According to the mode the dialog and its controls
+ * behave different.
+ * @param {boolean} viewing
+ */
+ setEditing(editing: boolean = true) {
+ this.editing = editing;
+ this.action = this.editing ? this.actionLabels.EDIT : this.actionLabels.CREATE;
+ }
+
+ /**
+ * Set the values displayed in the dialog.
+ */
+ setValues(uid: string, subuser: string = '', permissions: string = '') {
+ this.formGroup.setValue({
+ uid: uid,
+ subuid: this.getSubuserName(subuser),
+ perm: permissions,
+ generate_secret: true,
+ secret_key: null
+ });
+ }
+
+ /**
+ * Set the current capabilities of the user.
+ */
+ setSubusers(subusers: RgwUserSubuser[]) {
+ this.subusers = subusers;
+ }
+
+ onSubmit() {
+ // Get the values from the form and create an object that is sent
+ // by the triggered submit action event.
+ const values = this.formGroup.value;
+ const subuser = new RgwUserSubuser();
+ subuser.id = `${values.uid}:${values.subuid}`;
+ subuser.permissions = values.perm;
+ subuser.generate_secret = values.generate_secret;
+ subuser.secret_key = values.secret_key;
+ this.submitAction.emit(subuser);
+ this.bsModalRef.close();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html
new file mode 100644
index 000000000..00f3cf0f2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html
@@ -0,0 +1,54 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container i18n="form title"
+ class="modal-title">{{ action | titlecase }} {{ resource | upperFirst }}</ng-container>
+
+ <ng-container class="modal-content">
+ <div class="modal-body">
+ <form novalidate>
+ <!-- Username -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="user"
+ i18n>Username</label>
+ <div class="cd-col-form-input">
+ <input id="user"
+ name="user"
+ class="form-control"
+ type="text"
+ [readonly]="true"
+ [(ngModel)]="user">
+ </div>
+ </div>
+
+ <!-- Secret key -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="secret_key"
+ i18n>Secret key</label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input id="secret_key"
+ name="secret_key"
+ class="form-control"
+ type="password"
+ [(ngModel)]="secret_key"
+ [readonly]="true">
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="secret_key">
+ </button>
+ <cd-copy-2-clipboard-button source="secret_key">
+ </cd-copy-2-clipboard-button>
+ </span>
+ </div>
+ </div>
+ </div>
+ </form>
+ </div>
+
+ <div class="modal-footer">
+ <cd-back-button (backAction)="activeModal.close()"></cd-back-button>
+ </div>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.spec.ts
new file mode 100644
index 000000000..f7ecf3290
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.spec.ts
@@ -0,0 +1,31 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RgwUserSwiftKeyModalComponent } from './rgw-user-swift-key-modal.component';
+
+describe('RgwUserSwiftKeyModalComponent', () => {
+ let component: RgwUserSwiftKeyModalComponent;
+ let fixture: ComponentFixture<RgwUserSwiftKeyModalComponent>;
+
+ configureTestBed({
+ declarations: [RgwUserSwiftKeyModalComponent],
+ imports: [ToastrModule.forRoot(), FormsModule, SharedModule, RouterTestingModule],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RgwUserSwiftKeyModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts
new file mode 100644
index 000000000..7bd63bcc0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts
@@ -0,0 +1,30 @@
+import { Component } from '@angular/core';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+
+@Component({
+ selector: 'cd-rgw-user-swift-key-modal',
+ templateUrl: './rgw-user-swift-key-modal.component.html',
+ styleUrls: ['./rgw-user-swift-key-modal.component.scss']
+})
+export class RgwUserSwiftKeyModalComponent {
+ user: string;
+ secret_key: string;
+ resource: string;
+ action: string;
+
+ constructor(public activeModal: NgbActiveModal, public actionLabels: ActionLabelsI18n) {
+ this.resource = $localize`Swift Key`;
+ this.action = this.actionLabels.SHOW;
+ }
+
+ /**
+ * Set the values displayed in the dialog.
+ */
+ setValues(user: string, secret_key: string) {
+ this.user = user;
+ this.secret_key = secret_key;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw.module.ts
new file mode 100644
index 000000000..4abcd6979
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw.module.ts
@@ -0,0 +1,108 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { RouterModule, Routes } from '@angular/router';
+
+import { NgbNavModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgxPipeFunctionModule } from 'ngx-pipe-function';
+
+import { ActionLabels, URLVerbs } from '~/app/shared/constants/app.constants';
+import { SharedModule } from '~/app/shared/shared.module';
+import { PerformanceCounterModule } from '../performance-counter/performance-counter.module';
+import { RgwBucketDetailsComponent } from './rgw-bucket-details/rgw-bucket-details.component';
+import { RgwBucketFormComponent } from './rgw-bucket-form/rgw-bucket-form.component';
+import { RgwBucketListComponent } from './rgw-bucket-list/rgw-bucket-list.component';
+import { RgwDaemonDetailsComponent } from './rgw-daemon-details/rgw-daemon-details.component';
+import { RgwDaemonListComponent } from './rgw-daemon-list/rgw-daemon-list.component';
+import { RgwUserCapabilityModalComponent } from './rgw-user-capability-modal/rgw-user-capability-modal.component';
+import { RgwUserDetailsComponent } from './rgw-user-details/rgw-user-details.component';
+import { RgwUserFormComponent } from './rgw-user-form/rgw-user-form.component';
+import { RgwUserListComponent } from './rgw-user-list/rgw-user-list.component';
+import { RgwUserS3KeyModalComponent } from './rgw-user-s3-key-modal/rgw-user-s3-key-modal.component';
+import { RgwUserSubuserModalComponent } from './rgw-user-subuser-modal/rgw-user-subuser-modal.component';
+import { RgwUserSwiftKeyModalComponent } from './rgw-user-swift-key-modal/rgw-user-swift-key-modal.component';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ SharedModule,
+ FormsModule,
+ ReactiveFormsModule,
+ PerformanceCounterModule,
+ NgbNavModule,
+ RouterModule,
+ NgbTooltipModule,
+ NgxPipeFunctionModule
+ ],
+ exports: [
+ RgwDaemonListComponent,
+ RgwDaemonDetailsComponent,
+ RgwBucketFormComponent,
+ RgwBucketListComponent,
+ RgwBucketDetailsComponent,
+ RgwUserListComponent,
+ RgwUserDetailsComponent
+ ],
+ declarations: [
+ RgwDaemonListComponent,
+ RgwDaemonDetailsComponent,
+ RgwBucketFormComponent,
+ RgwBucketListComponent,
+ RgwBucketDetailsComponent,
+ RgwUserListComponent,
+ RgwUserDetailsComponent,
+ RgwBucketFormComponent,
+ RgwUserFormComponent,
+ RgwUserSwiftKeyModalComponent,
+ RgwUserS3KeyModalComponent,
+ RgwUserCapabilityModalComponent,
+ RgwUserSubuserModalComponent
+ ]
+})
+export class RgwModule {}
+
+const routes: Routes = [
+ {
+ path: '' // Required for a clean reload on daemon selection.
+ },
+ { path: 'daemon', component: RgwDaemonListComponent, data: { breadcrumbs: 'Daemons' } },
+ {
+ path: 'user',
+ data: { breadcrumbs: 'Users' },
+ children: [
+ { path: '', component: RgwUserListComponent },
+ {
+ path: URLVerbs.CREATE,
+ component: RgwUserFormComponent,
+ data: { breadcrumbs: ActionLabels.CREATE }
+ },
+ {
+ path: `${URLVerbs.EDIT}/:uid`,
+ component: RgwUserFormComponent,
+ data: { breadcrumbs: ActionLabels.EDIT }
+ }
+ ]
+ },
+ {
+ path: 'bucket',
+ data: { breadcrumbs: 'Buckets' },
+ children: [
+ { path: '', component: RgwBucketListComponent },
+ {
+ path: URLVerbs.CREATE,
+ component: RgwBucketFormComponent,
+ data: { breadcrumbs: ActionLabels.CREATE }
+ },
+ {
+ path: `${URLVerbs.EDIT}/:bid`,
+ component: RgwBucketFormComponent,
+ data: { breadcrumbs: ActionLabels.EDIT }
+ }
+ ]
+ }
+];
+
+@NgModule({
+ imports: [RgwModule, RouterModule.forChild(routes)]
+})
+export class RoutedRgwModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/ceph-shared.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/ceph-shared.module.ts
new file mode 100644
index 000000000..9e9f2917a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/ceph-shared.module.ts
@@ -0,0 +1,17 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgxPipeFunctionModule } from 'ngx-pipe-function';
+
+import { DataTableModule } from '~/app/shared/datatable/datatable.module';
+import { SharedModule } from '~/app/shared/shared.module';
+import { DeviceListComponent } from './device-list/device-list.component';
+import { SmartListComponent } from './smart-list/smart-list.component';
+
+@NgModule({
+ imports: [CommonModule, DataTableModule, SharedModule, NgbNavModule, NgxPipeFunctionModule],
+ exports: [DeviceListComponent, SmartListComponent],
+ declarations: [DeviceListComponent, SmartListComponent]
+})
+export class CephSharedModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/device-list/device-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/device-list/device-list.component.html
new file mode 100644
index 000000000..56fbb965a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/device-list/device-list.component.html
@@ -0,0 +1,26 @@
+<cd-table *ngIf="hostname || osdId !== null"
+ [data]="devices"
+ [columns]="columns"></cd-table>
+
+<cd-alert-panel type="warning"
+ *ngIf="hostname === '' && osdId === null"
+ i18n>Neither hostname nor OSD ID given</cd-alert-panel>
+
+<ng-template #deviceLocation
+ let-value="value">
+ <span *ngFor="let location of value">{{location.dev}}</span>
+</ng-template>
+
+<ng-template #lifeExpectancy
+ let-value="value">
+ <span *ngIf="!value.life_expectancy_enabled"
+ i18n>{{ "" | notAvailable }}</span>
+ <span *ngIf="value.min && !value.max">&gt; {{value.min | i18nPlural: translationMapping}}</span>
+ <span *ngIf="value.max && !value.min">&lt; {{value.max | i18nPlural: translationMapping}}</span>
+ <span *ngIf="value.max && value.min">{{value.min}} to {{value.max | i18nPlural: translationMapping}}</span>
+</ng-template>
+
+<ng-template #lifeExpectancyTimestamp
+ let-value="value">
+ {{value}}
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/device-list/device-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/device-list/device-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/device-list/device-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/device-list/device-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/device-list/device-list.component.spec.ts
new file mode 100644
index 000000000..718d04727
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/device-list/device-list.component.spec.ts
@@ -0,0 +1,26 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { DeviceListComponent } from './device-list.component';
+
+describe('DeviceListComponent', () => {
+ let component: DeviceListComponent;
+ let fixture: ComponentFixture<DeviceListComponent>;
+
+ configureTestBed({
+ declarations: [DeviceListComponent],
+ imports: [SharedModule, HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DeviceListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/device-list/device-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/device-list/device-list.component.ts
new file mode 100644
index 000000000..5503d1319
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/device-list/device-list.component.ts
@@ -0,0 +1,84 @@
+import { DatePipe } from '@angular/common';
+import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import { HostService } from '~/app/shared/api/host.service';
+import { OsdService } from '~/app/shared/api/osd.service';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdDevice } from '~/app/shared/models/devices';
+
+@Component({
+ selector: 'cd-device-list',
+ templateUrl: './device-list.component.html',
+ styleUrls: ['./device-list.component.scss']
+})
+export class DeviceListComponent implements OnChanges, OnInit {
+ @Input()
+ hostname = '';
+ @Input()
+ osdId: number = null;
+
+ @ViewChild('deviceLocation', { static: true })
+ locationTemplate: TemplateRef<any>;
+ @ViewChild('lifeExpectancy', { static: true })
+ lifeExpectancyTemplate: TemplateRef<any>;
+ @ViewChild('lifeExpectancyTimestamp', { static: true })
+ lifeExpectancyTimestampTemplate: TemplateRef<any>;
+
+ devices: CdDevice[] = null;
+ columns: CdTableColumn[] = [];
+ translationMapping = {
+ '=1': '# week',
+ other: '# weeks'
+ };
+
+ constructor(
+ private hostService: HostService,
+ private datePipe: DatePipe,
+ private osdService: OsdService
+ ) {}
+
+ ngOnInit() {
+ this.columns = [
+ { prop: 'devid', name: $localize`Device ID`, minWidth: 200 },
+ {
+ prop: 'state',
+ name: $localize`State of Health`,
+ flexGrow: 1,
+ cellTransformation: CellTemplate.badge,
+ customTemplateConfig: {
+ map: {
+ good: { value: $localize`Good`, class: 'badge-success' },
+ warning: { value: $localize`Warning`, class: 'badge-warning' },
+ bad: { value: $localize`Bad`, class: 'badge-danger' },
+ stale: { value: $localize`Stale`, class: 'badge-info' },
+ unknown: { value: $localize`Unknown`, class: 'badge-dark' }
+ }
+ }
+ },
+ {
+ prop: 'life_expectancy_weeks',
+ name: $localize`Life Expectancy`,
+ cellTemplate: this.lifeExpectancyTemplate
+ },
+ {
+ prop: 'life_expectancy_stamp',
+ name: $localize`Prediction Creation Date`,
+ cellTemplate: this.lifeExpectancyTimestampTemplate,
+ pipe: this.datePipe,
+ isHidden: true
+ },
+ { prop: 'location', name: $localize`Device Name`, cellTemplate: this.locationTemplate },
+ { prop: 'readableDaemons', name: $localize`Daemons` }
+ ];
+ }
+
+ ngOnChanges() {
+ const updateDevicesFn = (devices: CdDevice[]) => (this.devices = devices);
+ if (this.hostname) {
+ this.hostService.getDevices(this.hostname).subscribe(updateDevicesFn);
+ } else if (this.osdId !== null) {
+ this.osdService.getDevices(this.osdId).subscribe(updateDevicesFn);
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/pg-category.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/pg-category.model.ts
new file mode 100644
index 000000000..12fda7784
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/pg-category.model.ts
@@ -0,0 +1,71 @@
+export class PgCategory {
+ static readonly CATEGORY_CLEAN = 'clean';
+ static readonly CATEGORY_WORKING = 'working';
+ static readonly CATEGORY_WARNING = 'warning';
+ static readonly CATEGORY_UNKNOWN = 'unknown';
+ static readonly VALID_CATEGORIES = [
+ PgCategory.CATEGORY_CLEAN,
+ PgCategory.CATEGORY_WORKING,
+ PgCategory.CATEGORY_WARNING,
+ PgCategory.CATEGORY_UNKNOWN
+ ];
+
+ states: string[];
+
+ constructor(public type: string) {
+ if (!this.isValidType()) {
+ throw new Error('Wrong placement group category type');
+ }
+
+ this.setTypeStates();
+ }
+
+ private isValidType() {
+ return PgCategory.VALID_CATEGORIES.includes(this.type);
+ }
+
+ private setTypeStates() {
+ switch (this.type) {
+ case PgCategory.CATEGORY_CLEAN:
+ this.states = ['active', 'clean'];
+ break;
+ case PgCategory.CATEGORY_WORKING:
+ this.states = [
+ 'activating',
+ 'backfill_wait',
+ 'backfilling',
+ 'creating',
+ 'deep',
+ 'degraded',
+ 'forced_backfill',
+ 'forced_recovery',
+ 'peering',
+ 'peered',
+ 'recovering',
+ 'recovery_wait',
+ 'repair',
+ 'scrubbing',
+ 'snaptrim',
+ 'snaptrim_wait'
+ ];
+ break;
+ case PgCategory.CATEGORY_WARNING:
+ this.states = [
+ 'backfill_toofull',
+ 'backfill_unfound',
+ 'down',
+ 'incomplete',
+ 'inconsistent',
+ 'recovery_toofull',
+ 'recovery_unfound',
+ 'remapped',
+ 'snaptrim_error',
+ 'stale',
+ 'undersized'
+ ];
+ break;
+ default:
+ this.states = [];
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/pg-category.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/pg-category.service.spec.ts
new file mode 100644
index 000000000..2b3e2975c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/pg-category.service.spec.ts
@@ -0,0 +1,56 @@
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { PgCategory } from './pg-category.model';
+import { PgCategoryService } from './pg-category.service';
+
+describe('PgCategoryService', () => {
+ let service: PgCategoryService;
+
+ configureTestBed({
+ providers: [PgCategoryService]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(PgCategoryService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('returns all category types', () => {
+ const categoryTypes = service.getAllTypes();
+
+ expect(categoryTypes).toEqual(PgCategory.VALID_CATEGORIES);
+ });
+
+ describe('getTypeByStates', () => {
+ const testMethod = (value: string, expected: string) =>
+ expect(service.getTypeByStates(value)).toEqual(expected);
+
+ it(PgCategory.CATEGORY_CLEAN, () => {
+ testMethod('clean', PgCategory.CATEGORY_CLEAN);
+ });
+
+ it(PgCategory.CATEGORY_WORKING, () => {
+ testMethod('clean+scrubbing', PgCategory.CATEGORY_WORKING);
+ testMethod('active+clean+snaptrim_wait', PgCategory.CATEGORY_WORKING);
+ testMethod(
+ ' 8 active+clean+scrubbing+deep, 255 active+clean ',
+ PgCategory.CATEGORY_WORKING
+ );
+ });
+
+ it(PgCategory.CATEGORY_WARNING, () => {
+ testMethod('clean+scrubbing+down', PgCategory.CATEGORY_WARNING);
+ testMethod('clean+scrubbing+down+nonMappedState', PgCategory.CATEGORY_WARNING);
+ });
+
+ it(PgCategory.CATEGORY_UNKNOWN, () => {
+ testMethod('clean+scrubbing+nonMappedState', PgCategory.CATEGORY_UNKNOWN);
+ testMethod('nonMappedState', PgCategory.CATEGORY_UNKNOWN);
+ testMethod('', PgCategory.CATEGORY_UNKNOWN);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/pg-category.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/pg-category.service.ts
new file mode 100644
index 000000000..ae178ded2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/pg-category.service.ts
@@ -0,0 +1,63 @@
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+
+import { CephSharedModule } from './ceph-shared.module';
+import { PgCategory } from './pg-category.model';
+
+@Injectable({
+ providedIn: CephSharedModule
+})
+export class PgCategoryService {
+ private categories: object;
+
+ constructor() {
+ this.categories = this.createCategories();
+ }
+
+ getAllTypes() {
+ return PgCategory.VALID_CATEGORIES;
+ }
+
+ getTypeByStates(pgStatesText: string): string {
+ const pgStates = this.getPgStatesFromText(pgStatesText);
+
+ if (pgStates.length === 0) {
+ return PgCategory.CATEGORY_UNKNOWN;
+ }
+
+ const intersections = _.zipObject(
+ PgCategory.VALID_CATEGORIES,
+ PgCategory.VALID_CATEGORIES.map(
+ (category) => _.intersection(this.categories[category].states, pgStates).length
+ )
+ );
+
+ if (intersections[PgCategory.CATEGORY_WARNING] > 0) {
+ return PgCategory.CATEGORY_WARNING;
+ }
+
+ const pgWorkingStates = intersections[PgCategory.CATEGORY_WORKING];
+ if (pgStates.length > intersections[PgCategory.CATEGORY_CLEAN] + pgWorkingStates) {
+ return PgCategory.CATEGORY_UNKNOWN;
+ }
+
+ return pgWorkingStates ? PgCategory.CATEGORY_WORKING : PgCategory.CATEGORY_CLEAN;
+ }
+
+ private createCategories() {
+ return _.zipObject(
+ PgCategory.VALID_CATEGORIES,
+ PgCategory.VALID_CATEGORIES.map((category) => new PgCategory(category))
+ );
+ }
+
+ private getPgStatesFromText(pgStatesText: string) {
+ const pgStates = pgStatesText
+ .replace(/[^a-z_]+/g, ' ')
+ .trim()
+ .split(' ');
+
+ return _.uniq(pgStates);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/fixtures/smart_data_version_1_0_ata_response.json b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/fixtures/smart_data_version_1_0_ata_response.json
new file mode 100644
index 000000000..514c2966c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/fixtures/smart_data_version_1_0_ata_response.json
@@ -0,0 +1,570 @@
+{
+ "WDC_WD1003FBYX-01Y7B1_WD-WCAW11111111": {
+ "ata_sct_capabilities": {
+ "data_table_supported": true,
+ "error_recovery_control_supported": true,
+ "feature_control_supported": true,
+ "value": 12351
+ },
+ "ata_smart_attributes": {
+ "revision": 16,
+ "table": [
+ {
+ "flags": {
+ "auto_keep": true,
+ "error_rate": true,
+ "event_count": false,
+ "performance": true,
+ "prefailure": true,
+ "string": "POSR-K ",
+ "updated_online": true,
+ "value": 47
+ },
+ "id": 1,
+ "name": "Raw_Read_Error_Rate",
+ "raw": {
+ "string": "1",
+ "value": 1
+ },
+ "thresh": 51,
+ "value": 200,
+ "when_failed": "",
+ "worst": 200
+ },
+ {
+ "flags": {
+ "auto_keep": true,
+ "error_rate": false,
+ "event_count": false,
+ "performance": true,
+ "prefailure": true,
+ "string": "POS--K ",
+ "updated_online": true,
+ "value": 39
+ },
+ "id": 3,
+ "name": "Spin_Up_Time",
+ "raw": {
+ "string": "4250",
+ "value": 4250
+ },
+ "thresh": 21,
+ "value": 175,
+ "when_failed": "",
+ "worst": 172
+ },
+ {
+ "flags": {
+ "auto_keep": true,
+ "error_rate": false,
+ "event_count": true,
+ "performance": false,
+ "prefailure": false,
+ "string": "-O--CK ",
+ "updated_online": true,
+ "value": 50
+ },
+ "id": 4,
+ "name": "Start_Stop_Count",
+ "raw": {
+ "string": "1657",
+ "value": 1657
+ },
+ "thresh": 0,
+ "value": 99,
+ "when_failed": "",
+ "worst": 99
+ },
+ {
+ "flags": {
+ "auto_keep": true,
+ "error_rate": false,
+ "event_count": true,
+ "performance": false,
+ "prefailure": true,
+ "string": "PO--CK ",
+ "updated_online": true,
+ "value": 51
+ },
+ "id": 5,
+ "name": "Reallocated_Sector_Ct",
+ "raw": {
+ "string": "0",
+ "value": 0
+ },
+ "thresh": 140,
+ "value": 200,
+ "when_failed": "",
+ "worst": 200
+ },
+ {
+ "flags": {
+ "auto_keep": true,
+ "error_rate": true,
+ "event_count": false,
+ "performance": true,
+ "prefailure": false,
+ "string": "-OSR-K ",
+ "updated_online": true,
+ "value": 46
+ },
+ "id": 7,
+ "name": "Seek_Error_Rate",
+ "raw": {
+ "string": "0",
+ "value": 0
+ },
+ "thresh": 0,
+ "value": 200,
+ "when_failed": "",
+ "worst": 200
+ },
+ {
+ "flags": {
+ "auto_keep": true,
+ "error_rate": false,
+ "event_count": true,
+ "performance": false,
+ "prefailure": false,
+ "string": "-O--CK ",
+ "updated_online": true,
+ "value": 50
+ },
+ "id": 9,
+ "name": "Power_On_Hours",
+ "raw": {
+ "string": "15807",
+ "value": 15807
+ },
+ "thresh": 0,
+ "value": 79,
+ "when_failed": "",
+ "worst": 79
+ },
+ {
+ "flags": {
+ "auto_keep": true,
+ "error_rate": false,
+ "event_count": true,
+ "performance": false,
+ "prefailure": false,
+ "string": "-O--CK ",
+ "updated_online": true,
+ "value": 50
+ },
+ "id": 10,
+ "name": "Spin_Retry_Count",
+ "raw": {
+ "string": "0",
+ "value": 0
+ },
+ "thresh": 0,
+ "value": 100,
+ "when_failed": "",
+ "worst": 100
+ },
+ {
+ "flags": {
+ "auto_keep": true,
+ "error_rate": false,
+ "event_count": true,
+ "performance": false,
+ "prefailure": false,
+ "string": "-O--CK ",
+ "updated_online": true,
+ "value": 50
+ },
+ "id": 11,
+ "name": "Calibration_Retry_Count",
+ "raw": {
+ "string": "0",
+ "value": 0
+ },
+ "thresh": 0,
+ "value": 100,
+ "when_failed": "",
+ "worst": 100
+ },
+ {
+ "flags": {
+ "auto_keep": true,
+ "error_rate": false,
+ "event_count": true,
+ "performance": false,
+ "prefailure": false,
+ "string": "-O--CK ",
+ "updated_online": true,
+ "value": 50
+ },
+ "id": 12,
+ "name": "Power_Cycle_Count",
+ "raw": {
+ "string": "1370",
+ "value": 1370
+ },
+ "thresh": 0,
+ "value": 99,
+ "when_failed": "",
+ "worst": 99
+ },
+ {
+ "flags": {
+ "auto_keep": true,
+ "error_rate": false,
+ "event_count": true,
+ "performance": false,
+ "prefailure": false,
+ "string": "-O--CK ",
+ "updated_online": true,
+ "value": 50
+ },
+ "id": 192,
+ "name": "Power-Off_Retract_Count",
+ "raw": {
+ "string": "111",
+ "value": 111
+ },
+ "thresh": 0,
+ "value": 200,
+ "when_failed": "",
+ "worst": 200
+ },
+ {
+ "flags": {
+ "auto_keep": true,
+ "error_rate": false,
+ "event_count": true,
+ "performance": false,
+ "prefailure": false,
+ "string": "-O--CK ",
+ "updated_online": true,
+ "value": 50
+ },
+ "id": 193,
+ "name": "Load_Cycle_Count",
+ "raw": {
+ "string": "1545",
+ "value": 1545
+ },
+ "thresh": 0,
+ "value": 200,
+ "when_failed": "",
+ "worst": 200
+ },
+ {
+ "flags": {
+ "auto_keep": true,
+ "error_rate": false,
+ "event_count": false,
+ "performance": false,
+ "prefailure": false,
+ "string": "-O---K ",
+ "updated_online": true,
+ "value": 34
+ },
+ "id": 194,
+ "name": "Temperature_Celsius",
+ "raw": {
+ "string": "47",
+ "value": 47
+ },
+ "thresh": 0,
+ "value": 100,
+ "when_failed": "",
+ "worst": 89
+ },
+ {
+ "flags": {
+ "auto_keep": true,
+ "error_rate": false,
+ "event_count": true,
+ "performance": false,
+ "prefailure": false,
+ "string": "-O--CK ",
+ "updated_online": true,
+ "value": 50
+ },
+ "id": 196,
+ "name": "Reallocated_Event_Count",
+ "raw": {
+ "string": "0",
+ "value": 0
+ },
+ "thresh": 0,
+ "value": 200,
+ "when_failed": "",
+ "worst": 200
+ },
+ {
+ "flags": {
+ "auto_keep": true,
+ "error_rate": false,
+ "event_count": true,
+ "performance": false,
+ "prefailure": false,
+ "string": "-O--CK ",
+ "updated_online": true,
+ "value": 50
+ },
+ "id": 197,
+ "name": "Current_Pending_Sector",
+ "raw": {
+ "string": "0",
+ "value": 0
+ },
+ "thresh": 0,
+ "value": 200,
+ "when_failed": "",
+ "worst": 200
+ },
+ {
+ "flags": {
+ "auto_keep": true,
+ "error_rate": false,
+ "event_count": true,
+ "performance": false,
+ "prefailure": false,
+ "string": "----CK ",
+ "updated_online": false,
+ "value": 48
+ },
+ "id": 198,
+ "name": "Offline_Uncorrectable",
+ "raw": {
+ "string": "0",
+ "value": 0
+ },
+ "thresh": 0,
+ "value": 200,
+ "when_failed": "",
+ "worst": 200
+ },
+ {
+ "flags": {
+ "auto_keep": true,
+ "error_rate": false,
+ "event_count": true,
+ "performance": false,
+ "prefailure": false,
+ "string": "-O--CK ",
+ "updated_online": true,
+ "value": 50
+ },
+ "id": 199,
+ "name": "UDMA_CRC_Error_Count",
+ "raw": {
+ "string": "0",
+ "value": 0
+ },
+ "thresh": 0,
+ "value": 200,
+ "when_failed": "",
+ "worst": 200
+ },
+ {
+ "flags": {
+ "auto_keep": false,
+ "error_rate": true,
+ "event_count": false,
+ "performance": false,
+ "prefailure": false,
+ "string": "---R-- ",
+ "updated_online": false,
+ "value": 8
+ },
+ "id": 200,
+ "name": "Multi_Zone_Error_Rate",
+ "raw": {
+ "string": "0",
+ "value": 0
+ },
+ "thresh": 0,
+ "value": 200,
+ "when_failed": "",
+ "worst": 200
+ }
+ ]
+ },
+ "ata_smart_data": {
+ "capabilities": {
+ "attribute_autosave_enabled": true,
+ "conveyance_self_test_supported": true,
+ "error_logging_supported": true,
+ "exec_offline_immediate_supported": true,
+ "gp_logging_supported": true,
+ "offline_is_aborted_upon_new_cmd": false,
+ "offline_surface_scan_supported": true,
+ "selective_self_test_supported": true,
+ "self_tests_supported": true,
+ "values": [
+ 123,
+ 3
+ ]
+ },
+ "offline_data_collection": {
+ "completion_seconds": 16500,
+ "status": {
+ "string": "was suspended by an interrupting command from host",
+ "value": 132
+ }
+ },
+ "self_test": {
+ "polling_minutes": {
+ "conveyance": 5,
+ "extended": 162,
+ "short": 2
+ },
+ "status": {
+ "passed": true,
+ "string": "completed without error",
+ "value": 0
+ }
+ }
+ },
+ "ata_smart_error_log": {
+ "summary": {
+ "count": 0,
+ "revision": 1
+ }
+ },
+ "ata_smart_selective_self_test_log": {
+ "flags": {
+ "remainder_scan_enabled": false,
+ "value": 0
+ },
+ "power_up_scan_resume_minutes": 0,
+ "revision": 1,
+ "table": [
+ {
+ "lba_max": 0,
+ "lba_min": 0,
+ "status": {
+ "string": "Not_testing",
+ "value": 0
+ }
+ },
+ {
+ "lba_max": 0,
+ "lba_min": 0,
+ "status": {
+ "string": "Not_testing",
+ "value": 0
+ }
+ },
+ {
+ "lba_max": 0,
+ "lba_min": 0,
+ "status": {
+ "string": "Not_testing",
+ "value": 0
+ }
+ },
+ {
+ "lba_max": 0,
+ "lba_min": 0,
+ "status": {
+ "string": "Not_testing",
+ "value": 0
+ }
+ },
+ {
+ "lba_max": 0,
+ "lba_min": 0,
+ "status": {
+ "string": "Not_testing",
+ "value": 0
+ }
+ }
+ ]
+ },
+ "ata_smart_self_test_log": {
+ "standard": {
+ "count": 0,
+ "revision": 1
+ }
+ },
+ "ata_version": {
+ "major_value": 510,
+ "minor_value": 0,
+ "string": "ATA8-ACS (minor revision not indicated)"
+ },
+ "device": {
+ "info_name": "/dev/sde [SAT]",
+ "name": "/dev/sde",
+ "protocol": "ATA",
+ "type": "sat"
+ },
+ "firmware_version": "01.01V02",
+ "in_smartctl_database": true,
+ "interface_speed": {
+ "current": {
+ "bits_per_unit": 100000000,
+ "sata_value": 2,
+ "string": "3.0 Gb/s",
+ "units_per_second": 30
+ },
+ "max": {
+ "bits_per_unit": 100000000,
+ "sata_value": 6,
+ "string": "3.0 Gb/s",
+ "units_per_second": 30
+ }
+ },
+ "json_format_version": [
+ 1,
+ 0
+ ],
+ "local_time": {
+ "asctime": "Mon Sep 2 12:39:01 2019 UTC",
+ "time_t": 1567427941
+ },
+ "logical_block_size": 512,
+ "model_family": "Western Digital RE4",
+ "model_name": "WDC WD1003FBYX-01Y7B1",
+ "nvme_smart_health_information_add_log_error": "nvme returned an error: sudo: exit status: 1",
+ "nvme_smart_health_information_add_log_error_code": -22,
+ "nvme_vendor": "wdc_wd1003fbyx-01y7b1",
+ "physical_block_size": 512,
+ "power_cycle_count": 1370,
+ "power_on_time": {
+ "hours": 15807
+ },
+ "rotation_rate": 7200,
+ "sata_version": {
+ "string": "SATA 3.0",
+ "value": 63
+ },
+ "serial_number": "WD-WCAW11111111",
+ "smart_status": {
+ "passed": true
+ },
+ "smartctl": {
+ "argv": [
+ "smartctl",
+ "-a",
+ "/dev/sde",
+ "--json"
+ ],
+ "build_info": "(SUSE RPM)",
+ "exit_status": 0,
+ "platform_info": "x86_64-linux-5.0.0-25-generic",
+ "svn_revision": "4917",
+ "version": [
+ 7,
+ 0
+ ]
+ },
+ "temperature": {
+ "current": 47
+ },
+ "user_capacity": {
+ "blocks": 1953525168,
+ "bytes": 1000204886016
+ },
+ "wwn": {
+ "id": 11601695629,
+ "naa": 5,
+ "oui": 5358
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/fixtures/smart_data_version_1_0_nvme_response.json b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/fixtures/smart_data_version_1_0_nvme_response.json
new file mode 100644
index 000000000..fce50658a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/fixtures/smart_data_version_1_0_nvme_response.json
@@ -0,0 +1,134 @@
+{
+ "Samsung_SSD_970_EVO_Plus_1TB_S4EXXXXXXXXXXXX": {
+ "device": {
+ "info_name": "/dev/nvme0n1",
+ "name": "/dev/nvme0n1",
+ "protocol": "NVMe",
+ "type": "nvme"
+ },
+ "firmware_version": "1B2QEXM7",
+ "json_format_version": [1, 0],
+ "local_time": { "asctime": "Thu Oct 24 10:17:06 2019 CEST", "time_t": 1571905026 },
+ "logical_block_size": 512,
+ "model_name": "Samsung SSD 970 EVO Plus 1TB",
+ "nvme_controller_id": 4,
+ "nvme_ieee_oui_identifier": 9528,
+ "nvme_namespaces": [
+ {
+ "capacity": { "blocks": 1953525168, "bytes": 1000204886016 },
+ "eui64": { "ext_id": 367510189547, "oui": 9528 },
+ "formatted_lba_size": 512,
+ "id": 1,
+ "size": { "blocks": 1953525168, "bytes": 1000204886016 },
+ "utilization": { "blocks": 102347056, "bytes": 52401692672 }
+ }
+ ],
+ "nvme_number_of_namespaces": 1,
+ "nvme_pci_vendor": { "id": 5197, "subsystem_id": 5197 },
+ "nvme_smart_health_information_add_log_error": "nvme returned an error: sudo: exit status: 231",
+ "nvme_smart_health_information_add_log_error_code": -22,
+ "nvme_smart_health_information_log": {
+ "available_spare": 100,
+ "available_spare_threshold": 10,
+ "controller_busy_time": 29,
+ "critical_comp_time": 0,
+ "critical_warning": 0,
+ "data_units_read": 28800,
+ "data_units_written": 558814,
+ "host_reads": 480163,
+ "host_writes": 2340561,
+ "media_errors": 0,
+ "num_err_log_entries": 2,
+ "percentage_used": 0,
+ "power_cycles": 4,
+ "power_on_hours": 13,
+ "temperature": 42,
+ "temperature_sensors": [42, 46],
+ "unsafe_shutdowns": 2,
+ "warning_temp_time": 0
+ },
+ "nvme_total_capacity": 1000204886016,
+ "nvme_unallocated_capacity": 0,
+ "nvme_vendor": "samsung",
+ "power_cycle_count": 4,
+ "power_on_time": { "hours": 13 },
+ "serial_number": "S4EXXXXXXXXXXXX",
+ "smart_status": { "nvme": { "value": 0 }, "passed": true },
+ "smartctl": {
+ "argv": ["smartctl", "-a", "--json=o", "/dev/nvme0n1"],
+ "build_info": "(local build)",
+ "exit_status": 0,
+ "output": [
+ "smartctl 7.0 2018-12-30 r4883 [x86_64-linux-5.0.0-32-generic] (local build)",
+ "Copyright (C) 2002-18, Bruce Allen, Christian Franke, www.smartmontools.org",
+ "",
+ "=== START OF INFORMATION SECTION ===",
+ "Model Number: Samsung SSD 970 EVO Plus 1TB",
+ "Serial Number: S4EXXXXXXXXXXXX",
+ "Firmware Version: 1B2QEXM7",
+ "PCI Vendor/Subsystem ID: 0x144d",
+ "IEEE OUI Identifier: 0x002538",
+ "Total NVM Capacity: 1.000.204.886.016 [1,00 TB]",
+ "Unallocated NVM Capacity: 0",
+ "Controller ID: 4",
+ "Number of Namespaces: 1",
+ "Namespace 1 Size/Capacity: 1.000.204.886.016 [1,00 TB]",
+ "Namespace 1 Utilization: 52.401.692.672 [52,4 GB]",
+ "Namespace 1 Formatted LBA Size: 512",
+ "Namespace 1 IEEE EUI-64: 002538 55915075eb",
+ "Local Time is: Thu Oct 24 10:17:06 2019 CEST",
+ "Firmware Updates (0x16): 3 Slots, no Reset required",
+ "Optional Admin Commands (0x0017): Security Format Frmw_DL Self_Test",
+ "Optional NVM Commands (0x005f): Comp Wr_Unc DS_Mngmt Wr_Zero Sav/Sel_Feat Timestmp",
+ "Maximum Data Transfer Size: 512 Pages",
+ "Warning Comp. Temp. Threshold: 85 Celsius",
+ "Critical Comp. Temp. Threshold: 85 Celsius",
+ "",
+ "Supported Power States",
+ "St Op Max Active Idle RL RT WL WT Ent_Lat Ex_Lat",
+ " 0 + 7.80W - - 0 0 0 0 0 0",
+ " 1 + 6.00W - - 1 1 1 1 0 0",
+ " 2 + 3.40W - - 2 2 2 2 0 0",
+ " 3 - 0.0700W - - 3 3 3 3 210 1200",
+ " 4 - 0.0100W - - 4 4 4 4 2000 8000",
+ "",
+ "Supported LBA Sizes (NSID 0x1)",
+ "Id Fmt Data Metadt Rel_Perf",
+ " 0 + 512 0 0",
+ "",
+ "=== START OF SMART DATA SECTION ===",
+ "SMART overall-health self-assessment test result: PASSED",
+ "",
+ "SMART/Health Information (NVMe Log 0x02)",
+ "Critical Warning: 0x00",
+ "Temperature: 42 Celsius",
+ "Available Spare: 100%",
+ "Available Spare Threshold: 10%",
+ "Percentage Used: 0%",
+ "Data Units Read: 28.800 [14,7 GB]",
+ "Data Units Written: 558.814 [286 GB]",
+ "Host Read Commands: 480.163",
+ "Host Write Commands: 2.340.561",
+ "Controller Busy Time: 29",
+ "Power Cycles: 4",
+ "Power On Hours: 13",
+ "Unsafe Shutdowns: 2",
+ "Media and Data Integrity Errors: 0",
+ "Error Information Log Entries: 2",
+ "Warning Comp. Temperature Time: 0",
+ "Critical Comp. Temperature Time: 0",
+ "Temperature Sensor 1: 42 Celsius",
+ "Temperature Sensor 2: 46 Celsius",
+ "",
+ "Error Information (NVMe Log 0x01, max 64 entries)",
+ "No Errors Logged",
+ ""
+ ],
+ "platform_info": "x86_64-linux-5.0.0-32-generic",
+ "svn_revision": "4883",
+ "version": [7, 0]
+ },
+ "temperature": { "current": 42 },
+ "user_capacity": { "blocks": 1953525168, "bytes": 1000204886016 }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/fixtures/smart_data_version_1_0_scsi_response.json b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/fixtures/smart_data_version_1_0_scsi_response.json
new file mode 100644
index 000000000..dfbe580c7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/fixtures/smart_data_version_1_0_scsi_response.json
@@ -0,0 +1,208 @@
+{
+ "WDC_WUH721818AL5204_012345689": {
+ "device": {
+ "info_name": "/dev/sdf",
+ "name": "/dev/sdf",
+ "protocol": "SCSI",
+ "type": "scsi"
+ },
+ "device_type": {
+ "name": "disk",
+ "scsi_value": 0
+ },
+ "form_factor": {
+ "name": "3.5 inches",
+ "scsi_value": 2
+ },
+ "json_format_version": [
+ 1,
+ 0
+ ],
+ "local_time": {
+ "asctime": "Sun May 8 14:21:11 2022 UTC",
+ "time_t": 1652019671
+ },
+ "logical_block_size": 512,
+ "model_name": "WDC WUH721818AL5204",
+ "nvme_smart_health_information_add_log_error": "nvme returned an error: sudo: exit status: 231",
+ "nvme_smart_health_information_add_log_error_code": -22,
+ "nvme_vendor": "wdc",
+ "physical_block_size": 4096,
+ "power_on_time": {
+ "hours": 1719,
+ "minutes": 55
+ },
+ "product": "WUH721818AL5204",
+ "revision": "C232",
+ "rotation_rate": 7200,
+ "scsi_error_counter_log": {
+ "read": {
+ "correction_algorithm_invocations": 1001,
+ "errors_corrected_by_eccdelayed": 0,
+ "errors_corrected_by_eccfast": 0,
+ "errors_corrected_by_rereads_rewrites": 0,
+ "gigabytes_processed": "8519.006",
+ "total_errors_corrected": 0,
+ "total_uncorrected_errors": 0
+ },
+ "verify": {
+ "correction_algorithm_invocations": 261,
+ "errors_corrected_by_eccdelayed": 0,
+ "errors_corrected_by_eccfast": 0,
+ "errors_corrected_by_rereads_rewrites": 0,
+ "gigabytes_processed": "0.000",
+ "total_errors_corrected": 0,
+ "total_uncorrected_errors": 0
+ },
+ "write": {
+ "correction_algorithm_invocations": 25720,
+ "errors_corrected_by_eccdelayed": 0,
+ "errors_corrected_by_eccfast": 0,
+ "errors_corrected_by_rereads_rewrites": 0,
+ "gigabytes_processed": "146241.629",
+ "total_errors_corrected": 0,
+ "total_uncorrected_errors": 0
+ }
+ },
+ "scsi_grown_defect_list": 0,
+ "scsi_version": "SPC-5",
+ "serial_number": "0123456789",
+ "smart_status": {
+ "passed": true
+ },
+ "smartctl": {
+ "argv": [
+ "smartctl",
+ "-x",
+ "--json=o",
+ "/dev/sdf"
+ ],
+ "build_info": "(local build)",
+ "exit_status": 0,
+ "output": [
+ "smartctl 7.1 2020-04-05 r5049 [x86_64-linux-4.18.0-348.2.1.el8_5.x86_64] (local build)",
+ "Copyright (C) 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org",
+ "",
+ "=== START OF INFORMATION SECTION ===",
+ "Vendor: WDC",
+ "Product: WUH721818AL5204",
+ "Revision: C232",
+ "Compliance: SPC-5",
+ "User Capacity: 18,000,207,937,536 bytes [18.0 TB]",
+ "Logical block size: 512 bytes",
+ "Physical block size: 4096 bytes",
+ "LU is fully provisioned",
+ "Rotation Rate: 7200 rpm",
+ "Form Factor: 3.5 inches",
+ "Logical Unit id: 0xffffffffffffffffffffffff",
+ "Serial number: 0123456789",
+ "Device type: disk",
+ "Transport protocol: SAS (SPL-3)",
+ "Local Time is: Sun May 8 14:21:11 2022 UTC",
+ "SMART support is: Available - device has SMART capability.",
+ "SMART support is: Enabled",
+ "Temperature Warning: Enabled",
+ "Read Cache is: Enabled",
+ "Writeback Cache is: Enabled",
+ "",
+ "=== START OF READ SMART DATA SECTION ===",
+ "SMART Health Status: OK",
+ "",
+ "Grown defects during certification <not available>",
+ "Total blocks reassigned during format <not available>",
+ "Total new blocks reassigned <not available>",
+ "Power on minutes since format <not available>",
+ "Current Drive Temperature: 38 C",
+ "Drive Trip Temperature: 85 C",
+ "",
+ "Manufactured in week 43 of year 2021",
+ "Specified cycle count over device lifetime: 50000",
+ "Accumulated start-stop cycles: 9",
+ "Specified load-unload count over device lifetime: 600000",
+ "Accumulated load-unload cycles: 74",
+ "Elements in grown defect list: 0",
+ "",
+ "Error counter log:",
+ " Errors Corrected by Total Correction Gigabytes Total",
+ " ECC rereads/ errors algorithm processed uncorrected",
+ " fast | delayed rewrites corrected invocations [10^9 bytes] errors",
+ "read: 0 0 0 0 1001 8519.006 0",
+ "write: 0 0 0 0 25720 146241.629 0",
+ "verify: 0 0 0 0 261 0.000 0",
+ "",
+ "Non-medium error count: 0",
+ "",
+ "No Self-tests have been logged",
+ "",
+ "Background scan results log",
+ " Status: waiting until BMS interval timer expires",
+ " Accumulated power on time, hours:minutes 1719:55 [103195 minutes]",
+ " Number of background scans performed: 5, scan progress: 0.00%",
+ " Number of background medium scans performed: 5",
+ "",
+ "Protocol Specific port log page for SAS SSP",
+ "relative target port id = 1",
+ " generation code = 3",
+ " number of phys = 1",
+ " phy identifier = 0",
+ " attached device type: expander device",
+ " attached reason: loss of dword synchronization",
+ " reason: unknown",
+ " negotiated logical link rate: phy enabled; 12 Gbps",
+ " attached initiator port: ssp=0 stp=0 smp=1",
+ " attached target port: ssp=0 stp=0 smp=1",
+ " SAS address = 0xffffffffffffffffffffffff",
+ " attached SAS address = 0xffffffffffffffffffffffff",
+ " attached phy identifier = 0",
+ " Invalid DWORD count = 0",
+ " Running disparity error count = 0",
+ " Loss of DWORD synchronization = 0",
+ " Phy reset problem = 0",
+ " Phy event descriptors:",
+ " Invalid word count: 0",
+ " Running disparity error count: 0",
+ " Loss of dword synchronization count: 0",
+ " Phy reset problem count: 0",
+ "relative target port id = 2",
+ " generation code = 3",
+ " number of phys = 1",
+ " phy identifier = 1",
+ " attached device type: expander device",
+ " attached reason: power on",
+ " reason: unknown",
+ " negotiated logical link rate: phy enabled; 12 Gbps",
+ " attached initiator port: ssp=0 stp=0 smp=1",
+ " attached target port: ssp=0 stp=0 smp=1",
+ " SAS address = 0xffffffffffffffffffffffff",
+ " attached SAS address = 0xffffffffffffffffffffffff",
+ " attached phy identifier = 0",
+ " Invalid DWORD count = 0",
+ " Running disparity error count = 0",
+ " Loss of DWORD synchronization = 0",
+ " Phy reset problem = 0",
+ " Phy event descriptors:",
+ " Invalid word count: 0",
+ " Running disparity error count: 0",
+ " Loss of dword synchronization count: 0",
+ " Phy reset problem count: 0",
+ ""
+ ],
+ "platform_info": "x86_64-linux-4.18.0-348.2.1.el8_5.x86_64",
+ "svn_revision": "5049",
+ "version": [
+ 7,
+ 1
+ ]
+ },
+ "temperature": {
+ "current": 38,
+ "drive_trip": 85
+ },
+ "user_capacity": {
+ "blocks": 35156656128,
+ "bytes": 18000207937536
+ },
+ "vendor": "WDC"
+ }
+ }
+ \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.html
new file mode 100644
index 000000000..805d7558e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.html
@@ -0,0 +1,110 @@
+<ng-container *ngIf="!loading; else isLoading">
+ <cd-alert-panel *ngIf="error"
+ type="error"
+ i18n>Failed to retrieve SMART data.</cd-alert-panel>
+ <cd-alert-panel *ngIf="incompatible"
+ type="warning"
+ i18n>The data received has the JSON format version 2.x and is currently incompatible with the
+ dashboard.</cd-alert-panel>
+
+ <ng-container *ngIf="!error && !incompatible">
+ <cd-alert-panel *ngIf="data | pipeFunction:isEmpty"
+ type="info"
+ i18n>No SMART data available.</cd-alert-panel>
+
+ <ng-container *ngIf="!(data | pipeFunction:isEmpty)">
+ <ul ngbNav
+ #nav="ngbNav"
+ class="nav-tabs">
+ <li ngbNavItem
+ *ngFor="let device of data | keyvalue">
+ <a ngbNavLink>{{ device.value.device }} ({{ device.value.identifier }})</a>
+ <ng-template ngbNavContent>
+ <ng-container *ngIf="device.value.error; else noError">
+ <cd-alert-panel id="alert-error"
+ type="warning">{{ device.value.userMessage }}</cd-alert-panel>
+ </ng-container>
+
+ <ng-template #noError>
+ <cd-alert-panel *ngIf="device.value.info?.smart_status | pipeFunction:isEmpty; else hasSmartStatus"
+ id="alert-self-test-unknown"
+ size="slim"
+ type="warning"
+ i18n-title
+ title="SMART overall-health self-assessment test result"
+ i18n>unknown</cd-alert-panel>
+ <ng-template #hasSmartStatus>
+ <!-- HDD/NVMe self test -->
+ <ng-container *ngIf="device.value.info.smart_status.passed; else selfTestFailed">
+ <cd-alert-panel id="alert-self-test-passed"
+ size="slim"
+ type="info"
+ i18n-title
+ title="SMART overall-health self-assessment test result"
+ i18n>passed</cd-alert-panel>
+ </ng-container>
+ <ng-template #selfTestFailed>
+ <cd-alert-panel id="alert-self-test-failed"
+ size="slim"
+ type="warning"
+ i18n-title
+ title="SMART overall-health self-assessment test result"
+ i18n>failed</cd-alert-panel>
+ </ng-template>
+ </ng-template>
+ </ng-template>
+
+ <ng-container *ngIf="!(device.value.info | pipeFunction:isEmpty) || !(device.value.smart | pipeFunction:isEmpty)">
+ <ul ngbNav
+ #innerNav="ngbNav"
+ class="nav-tabs">
+ <li [ngbNavItem]="1">
+ <a ngbNavLink
+ i18n>Device Information</a>
+ <ng-template ngbNavContent>
+ <cd-table-key-value *ngIf="!(device.value.info | pipeFunction:isEmpty)"
+ [renderObjects]="true"
+ [data]="device.value.info"></cd-table-key-value>
+ <cd-alert-panel *ngIf="device.value.info | pipeFunction:isEmpty"
+ id="alert-device-info-unavailable"
+ type="info"
+ i18n>No device information available for this device.</cd-alert-panel>
+ </ng-template>
+ </li>
+ <li [ngbNavItem]="2">
+ <a ngbNavLink
+ i18n>SMART</a>
+ <ng-template ngbNavContent>
+ <cd-table *ngIf="device.value.smart?.attributes"
+ [data]="device.value.smart.attributes.table"
+ updateSelectionOnRefresh="never"
+ [columns]="smartDataColumns"></cd-table>
+ <cd-table-key-value *ngIf="device.value.smart?.scsi_error_counter_log"
+ [renderObjects]="true"
+ [data]="device.value.smart"
+ updateSelectionOnRefresh="never"></cd-table-key-value>
+ <cd-table-key-value *ngIf="device.value.smart?.nvmeData"
+ [renderObjects]="true"
+ [data]="device.value.smart.nvmeData"
+ updateSelectionOnRefresh="never"></cd-table-key-value>
+ <cd-alert-panel *ngIf="!device.value.smart?.attributes && !device.value.smart?.nvmeData && !device.value.smart?.scsi_error_counter_log"
+ id="alert-device-smart-data-unavailable"
+ type="info"
+ i18n>No SMART data available for this device.</cd-alert-panel>
+ </ng-template>
+ </li>
+ </ul>
+
+ <div [ngbNavOutlet]="innerNav"></div>
+ </ng-container>
+ </ng-template>
+ </li>
+ </ul>
+
+ <div [ngbNavOutlet]="nav"></div>
+ </ng-container>
+ </ng-container>
+</ng-container>
+<ng-template #isLoading>
+ <cd-loading-panel i18n>SMART data is loading.</cd-loading-panel>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.spec.ts
new file mode 100644
index 000000000..54c436ca6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.spec.ts
@@ -0,0 +1,264 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { SimpleChange, SimpleChanges } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { NgxPipeFunctionModule } from 'ngx-pipe-function';
+import { of } from 'rxjs';
+
+import { OsdService } from '~/app/shared/api/osd.service';
+import {
+ AtaSmartDataV1,
+ IscsiSmartDataV1,
+ NvmeSmartDataV1,
+ SmartDataResult
+} from '~/app/shared/models/smart';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { SmartListComponent } from './smart-list.component';
+
+describe('OsdSmartListComponent', () => {
+ let component: SmartListComponent;
+ let fixture: ComponentFixture<SmartListComponent>;
+ let osdService: OsdService;
+
+ const SMART_DATA_ATA_VERSION_1_0: AtaSmartDataV1 = require('./fixtures/smart_data_version_1_0_ata_response.json');
+ const SMART_DATA_NVME_VERSION_1_0: NvmeSmartDataV1 = require('./fixtures/smart_data_version_1_0_nvme_response.json');
+ const SMART_DATA_SCSI_VERSION_1_0: IscsiSmartDataV1 = require('./fixtures/smart_data_version_1_0_scsi_response.json');
+
+ /**
+ * Sets attributes for _all_ returned devices according to the given path. The syntax is the same
+ * as used in lodash.set().
+ *
+ * @example
+ * patchData('json_format_version', [2, 0]) // sets the value of `json_format_version` to [2, 0]
+ * // for all devices
+ *
+ * patchData('json_format_version[0]', 2) // same result
+ *
+ * @param path The path to the attribute
+ * @param newValue The new value
+ */
+ const patchData = (path: string, newValue: any): any => {
+ return _.reduce(
+ _.cloneDeep(SMART_DATA_ATA_VERSION_1_0),
+ (result: object, dataObj, deviceId) => {
+ result[deviceId] = _.set<any>(dataObj, path, newValue);
+ return result;
+ },
+ {}
+ );
+ };
+
+ /**
+ * Initializes the component after it spied upon the `getSmartData()` method
+ * of `OsdService`. Determines which data is returned.
+ */
+ const initializeComponentWithData = (
+ dataType: 'hdd_v1' | 'nvme_v1' | 'hdd_v1_scsi',
+ patch: { [path: string]: any } = null,
+ simpleChanges?: SimpleChanges
+ ) => {
+ let data: AtaSmartDataV1 | NvmeSmartDataV1 | IscsiSmartDataV1;
+ switch (dataType) {
+ case 'hdd_v1':
+ data = SMART_DATA_ATA_VERSION_1_0;
+ break;
+ case 'nvme_v1':
+ data = SMART_DATA_NVME_VERSION_1_0;
+ break;
+ case 'hdd_v1_scsi':
+ data = SMART_DATA_SCSI_VERSION_1_0;
+ break;
+ }
+
+ if (_.isObject(patch)) {
+ _.each(patch, (replacement, path) => {
+ data = patchData(path, replacement);
+ });
+ }
+
+ spyOn(osdService, 'getSmartData').and.callFake(() => of(data));
+ component.ngOnInit();
+ const changes: SimpleChanges = simpleChanges || {
+ osdId: new SimpleChange(null, 0, true)
+ };
+ component.ngOnChanges(changes);
+ };
+
+ /**
+ * Verify an alert panel and its attributes.
+ *
+ * @param selector The CSS selector for the alert panel.
+ * @param panelTitle The title should be displayed.
+ * @param panelType Alert level of panel. Can be in `warning` or `info`.
+ * @param panelSize Pass `slim` for slim alert panel.
+ */
+ const verifyAlertPanel = (
+ selector: string,
+ panelTitle: string,
+ panelType: 'warning' | 'info',
+ panelSize?: 'slim'
+ ) => {
+ const alertPanel = fixture.debugElement.query(By.css(selector));
+ expect(component.incompatible).toBe(false);
+ expect(component.loading).toBe(false);
+
+ expect(alertPanel.attributes.type).toBe(panelType);
+ if (panelSize === 'slim') {
+ expect(alertPanel.attributes.title).toBe(panelTitle);
+ expect(alertPanel.attributes.size).toBe(panelSize);
+ } else {
+ const panelText = alertPanel.query(By.css('.alert-panel-text'));
+ expect(panelText.nativeElement.textContent).toBe(panelTitle);
+ }
+ };
+
+ configureTestBed({
+ declarations: [SmartListComponent],
+ imports: [
+ BrowserAnimationsModule,
+ SharedModule,
+ HttpClientTestingModule,
+ NgbNavModule,
+ NgxPipeFunctionModule
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(SmartListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+
+ osdService = TestBed.inject(OsdService);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('tests ATA version 1.x', () => {
+ beforeEach(() => initializeComponentWithData('hdd_v1'));
+
+ it('should return with proper keys', () => {
+ _.each(component.data, (smartData, _deviceId) => {
+ expect(_.keys(smartData)).toEqual(['info', 'smart', 'device', 'identifier']);
+ });
+ });
+
+ it('should not contain excluded keys in `info`', () => {
+ const excludes = [
+ 'ata_smart_attributes',
+ 'ata_smart_selective_self_test_log',
+ 'ata_smart_data'
+ ];
+ _.each(component.data, (smartData: SmartDataResult, _deviceId) => {
+ _.each(excludes, (exclude) => expect(smartData.info[exclude]).toBeUndefined());
+ });
+ });
+ });
+
+ describe('tests NVMe version 1.x', () => {
+ beforeEach(() => initializeComponentWithData('nvme_v1'));
+
+ it('should return with proper keys', () => {
+ _.each(component.data, (smartData, _deviceId) => {
+ expect(_.keys(smartData)).toEqual(['info', 'smart', 'device', 'identifier']);
+ });
+ });
+
+ it('should not contain excluded keys in `info`', () => {
+ const excludes = ['nvme_smart_health_information_log'];
+ _.each(component.data, (smartData: SmartDataResult, _deviceId) => {
+ _.each(excludes, (exclude) => expect(smartData.info[exclude]).toBeUndefined());
+ });
+ });
+ });
+
+ describe('tests SCSI version 1.x', () => {
+ beforeEach(() => initializeComponentWithData('hdd_v1_scsi'));
+
+ it('should return with proper keys', () => {
+ _.each(component.data, (smartData, _deviceId) => {
+ expect(_.keys(smartData)).toEqual(['info', 'smart', 'device', 'identifier']);
+ });
+ });
+
+ it('should not contain excluded keys in `info`', () => {
+ const excludes = ['scsi_error_counter_log', 'scsi_grown_defect_list'];
+ _.each(component.data, (smartData: SmartDataResult, _deviceId) => {
+ _.each(excludes, (exclude) => expect(smartData.info[exclude]).toBeUndefined());
+ });
+ });
+ });
+
+ it('should not work for version 2.x', () => {
+ initializeComponentWithData('nvme_v1', { json_format_version: [2, 0] });
+ expect(component.data).toEqual({});
+ expect(component.incompatible).toBeTruthy();
+ });
+
+ it('should display info panel for passed self test', () => {
+ initializeComponentWithData('hdd_v1');
+ fixture.detectChanges();
+ verifyAlertPanel(
+ 'cd-alert-panel#alert-self-test-passed',
+ 'SMART overall-health self-assessment test result',
+ 'info',
+ 'slim'
+ );
+ });
+
+ it('should display warning panel for failed self test', () => {
+ initializeComponentWithData('hdd_v1', { 'smart_status.passed': false });
+ fixture.detectChanges();
+ verifyAlertPanel(
+ 'cd-alert-panel#alert-self-test-failed',
+ 'SMART overall-health self-assessment test result',
+ 'warning',
+ 'slim'
+ );
+ });
+
+ it('should display warning panel for unknown self test', () => {
+ initializeComponentWithData('hdd_v1', { smart_status: undefined });
+ fixture.detectChanges();
+ verifyAlertPanel(
+ 'cd-alert-panel#alert-self-test-unknown',
+ 'SMART overall-health self-assessment test result',
+ 'warning',
+ 'slim'
+ );
+ });
+
+ it('should display info panel for empty device info', () => {
+ initializeComponentWithData('hdd_v1');
+ const deviceId: string = _.keys(component.data)[0];
+ component.data[deviceId]['info'] = {};
+ fixture.detectChanges();
+ component.nav.select(1);
+ fixture.detectChanges();
+ verifyAlertPanel(
+ 'cd-alert-panel#alert-device-info-unavailable',
+ 'No device information available for this device.',
+ 'info'
+ );
+ });
+
+ it('should display info panel for empty SMART data', () => {
+ initializeComponentWithData('hdd_v1');
+ const deviceId: string = _.keys(component.data)[0];
+ component.data[deviceId]['smart'] = {};
+ fixture.detectChanges();
+ component.nav.select(2);
+ fixture.detectChanges();
+ verifyAlertPanel(
+ 'cd-alert-panel#alert-device-smart-data-unavailable',
+ 'No SMART data available for this device.',
+ 'info'
+ );
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.ts
new file mode 100644
index 000000000..abfdcfe5b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.ts
@@ -0,0 +1,212 @@
+import { Component, Input, OnChanges, OnInit, SimpleChanges, ViewChild } from '@angular/core';
+
+import { NgbNav } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+
+import { HostService } from '~/app/shared/api/host.service';
+import { OsdService } from '~/app/shared/api/osd.service';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import {
+ AtaSmartDataV1,
+ IscsiSmartDataV1,
+ NvmeSmartDataV1,
+ SmartDataResult,
+ SmartError,
+ SmartErrorResult
+} from '~/app/shared/models/smart';
+
+@Component({
+ selector: 'cd-smart-list',
+ templateUrl: './smart-list.component.html',
+ styleUrls: ['./smart-list.component.scss']
+})
+export class SmartListComponent implements OnInit, OnChanges {
+ @ViewChild('innerNav')
+ nav: NgbNav;
+
+ @Input()
+ osdId: number = null;
+ @Input()
+ hostname: string = null;
+
+ loading = false;
+ incompatible = false;
+ error = false;
+
+ data: { [deviceId: string]: SmartDataResult | SmartErrorResult } = {};
+
+ smartDataColumns: CdTableColumn[];
+ scsiSmartDataColumns: CdTableColumn[];
+
+ isEmpty = _.isEmpty;
+
+ constructor(private osdService: OsdService, private hostService: HostService) {}
+
+ isSmartError(data: any): data is SmartError {
+ return _.get(data, 'error') !== undefined;
+ }
+
+ isNvmeSmartData(data: any): data is NvmeSmartDataV1 {
+ return _.get(data, 'device.protocol', '').toLowerCase() === 'nvme';
+ }
+
+ isAtaSmartData(data: any): data is AtaSmartDataV1 {
+ return _.get(data, 'device.protocol', '').toLowerCase() === 'ata';
+ }
+
+ isIscsiSmartData(data: any): data is IscsiSmartDataV1 {
+ return _.get(data, 'device.protocol', '').toLowerCase() === 'scsi';
+ }
+
+ private fetchData(data: any) {
+ const result: { [deviceId: string]: SmartDataResult | SmartErrorResult } = {};
+ _.each(data, (smartData, deviceId) => {
+ if (this.isSmartError(smartData)) {
+ let userMessage = '';
+ if (smartData.smartctl_error_code === -22) {
+ userMessage = $localize`Smartctl has received an unknown argument \
+(error code ${smartData.smartctl_error_code}). \
+You may be using an incompatible version of smartmontools. Version >= 7.0 of \
+smartmontools is required to successfully retrieve data.`;
+ } else {
+ userMessage = $localize`An error with error code ${smartData.smartctl_error_code} occurred.`;
+ }
+ const _result: SmartErrorResult = {
+ error: smartData.error,
+ smartctl_error_code: smartData.smartctl_error_code,
+ smartctl_output: smartData.smartctl_output,
+ userMessage: userMessage,
+ device: smartData.dev,
+ identifier: smartData.nvme_vendor
+ };
+ result[deviceId] = _result;
+ return;
+ }
+ // Prepare S.M.A.R.T data
+ if (smartData.json_format_version[0] === 1) {
+ // Version 1.x
+ if (this.isAtaSmartData(smartData)) {
+ result[deviceId] = this.extractAtaData(smartData);
+ } else if (this.isIscsiSmartData(smartData)) {
+ result[deviceId] = this.extractIscsiData(smartData);
+ } else if (this.isNvmeSmartData(smartData)) {
+ result[deviceId] = this.extractNvmeData(smartData);
+ }
+ return;
+ } else {
+ this.incompatible = true;
+ }
+ });
+ this.data = result;
+ this.loading = false;
+ }
+
+ private extractNvmeData(smartData: NvmeSmartDataV1): SmartDataResult {
+ const info = _.omitBy(smartData, (_value: string, key: string) =>
+ ['nvme_smart_health_information_log'].includes(key)
+ );
+ return {
+ info: info,
+ smart: {
+ nvmeData: smartData.nvme_smart_health_information_log
+ },
+ device: smartData.device.name,
+ identifier: smartData.serial_number
+ };
+ }
+
+ private extractIscsiData(smartData: IscsiSmartDataV1): SmartDataResult {
+ const info = _.omitBy(smartData, (_value: string, key: string) =>
+ ['scsi_error_counter_log', 'scsi_grown_defect_list'].includes(key)
+ );
+ return {
+ info: info,
+ smart: {
+ scsi_error_counter_log: smartData.scsi_error_counter_log,
+ scsi_grown_defect_list: smartData.scsi_grown_defect_list
+ },
+ device: info.device.name,
+ identifier: info.serial_number
+ };
+ }
+
+ private extractAtaData(smartData: AtaSmartDataV1): SmartDataResult {
+ const info = _.omitBy(smartData, (_value: string, key: string) =>
+ ['ata_smart_attributes', 'ata_smart_selective_self_test_log', 'ata_smart_data'].includes(key)
+ );
+ return {
+ info: info,
+ smart: {
+ attributes: smartData.ata_smart_attributes,
+ data: smartData.ata_smart_data
+ },
+ device: info.device.name,
+ identifier: info.serial_number
+ };
+ }
+
+ private updateData() {
+ this.loading = true;
+
+ if (this.osdId !== null) {
+ this.osdService.getSmartData(this.osdId).subscribe({
+ next: this.fetchData.bind(this),
+ error: (error) => {
+ error.preventDefault();
+ this.error = error;
+ this.loading = false;
+ }
+ });
+ } else if (this.hostname !== null) {
+ this.hostService.getSmartData(this.hostname).subscribe({
+ next: this.fetchData.bind(this),
+ error: (error) => {
+ error.preventDefault();
+ this.error = error;
+ this.loading = false;
+ }
+ });
+ }
+ }
+
+ ngOnInit() {
+ this.smartDataColumns = [
+ { prop: 'id', name: $localize`ID` },
+ { prop: 'name', name: $localize`Name` },
+ { prop: 'raw.value', name: $localize`Raw` },
+ { prop: 'thresh', name: $localize`Threshold` },
+ { prop: 'value', name: $localize`Value` },
+ { prop: 'when_failed', name: $localize`When Failed` },
+ { prop: 'worst', name: $localize`Worst` }
+ ];
+
+ this.scsiSmartDataColumns = [
+ {
+ prop: 'correction_algorithm_invocations',
+ name: $localize`Correction Algorithm Invocations`
+ },
+ {
+ prop: 'errors_corrected_by_eccdelayed',
+ name: $localize`Errors Corrected by ECC (Delayed)`
+ },
+ { prop: 'errors_corrected_by_eccfast', name: $localize`Errors Corrected by ECC (Fast)` },
+ {
+ prop: 'errors_corrected_by_rereads_rewrites',
+ name: $localize`Errors Corrected by Rereads/Rewrites`
+ },
+ { prop: 'gigabytes_processed', name: $localize`Gigabyes Processed` },
+ { prop: 'total_errors_corrected', name: $localize`Total Errors Corrected` },
+ { prop: 'total_uncorrected_errors', name: $localize`Total Errors Uncorrected` }
+ ];
+ }
+
+ ngOnChanges(changes: SimpleChanges): void {
+ this.data = {}; // Clear previous data
+ if (changes.osdId) {
+ this.osdId = changes.osdId.currentValue;
+ } else if (changes.hostname) {
+ this.hostname = changes.hostname.currentValue;
+ }
+ this.updateData();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/auth.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/auth.module.ts
new file mode 100644
index 000000000..74583431c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/auth.module.ts
@@ -0,0 +1,87 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { RouterModule, Routes } from '@angular/router';
+
+import { NgbNavModule, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgxPipeFunctionModule } from 'ngx-pipe-function';
+
+import { ActionLabels, URLVerbs } from '~/app/shared/constants/app.constants';
+import { SharedModule } from '~/app/shared/shared.module';
+import { LoginPasswordFormComponent } from './login-password-form/login-password-form.component';
+import { LoginComponent } from './login/login.component';
+import { RoleDetailsComponent } from './role-details/role-details.component';
+import { RoleFormComponent } from './role-form/role-form.component';
+import { RoleListComponent } from './role-list/role-list.component';
+import { UserFormComponent } from './user-form/user-form.component';
+import { UserListComponent } from './user-list/user-list.component';
+import { UserPasswordFormComponent } from './user-password-form/user-password-form.component';
+import { UserTabsComponent } from './user-tabs/user-tabs.component';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ FormsModule,
+ ReactiveFormsModule,
+ SharedModule,
+ NgbNavModule,
+ NgbPopoverModule,
+ NgxPipeFunctionModule,
+ RouterModule
+ ],
+ declarations: [
+ LoginComponent,
+ LoginPasswordFormComponent,
+ RoleDetailsComponent,
+ RoleFormComponent,
+ RoleListComponent,
+ UserTabsComponent,
+ UserListComponent,
+ UserFormComponent,
+ UserPasswordFormComponent
+ ]
+})
+export class AuthModule {}
+
+const routes: Routes = [
+ { path: '', redirectTo: 'users', pathMatch: 'full' },
+ {
+ path: 'users',
+ data: { breadcrumbs: 'Users' },
+ children: [
+ { path: '', component: UserListComponent },
+ {
+ path: URLVerbs.CREATE,
+ component: UserFormComponent,
+ data: { breadcrumbs: ActionLabels.CREATE }
+ },
+ {
+ path: `${URLVerbs.EDIT}/:username`,
+ component: UserFormComponent,
+ data: { breadcrumbs: ActionLabels.EDIT }
+ }
+ ]
+ },
+ {
+ path: 'roles',
+ data: { breadcrumbs: 'Roles' },
+ children: [
+ { path: '', component: RoleListComponent },
+ {
+ path: URLVerbs.CREATE,
+ component: RoleFormComponent,
+ data: { breadcrumbs: ActionLabels.CREATE }
+ },
+ {
+ path: `${URLVerbs.EDIT}/:name`,
+ component: RoleFormComponent,
+ data: { breadcrumbs: ActionLabels.EDIT }
+ }
+ ]
+ }
+];
+
+@NgModule({
+ imports: [AuthModule, RouterModule.forChild(routes)]
+})
+export class RoutedAuthModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.html
new file mode 100755
index 000000000..2dc30df52
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.html
@@ -0,0 +1,95 @@
+<div>
+ <h2 i18n>Please set a new password.</h2>
+ <h4 i18n>You will be redirected to the login page afterwards.</h4>
+ <form #frm="ngForm"
+ [formGroup]="userForm"
+ novalidate>
+
+ <!-- Old password -->
+ <div class="form-group has-feedback">
+ <div class="input-group">
+ <input class="form-control"
+ type="password"
+ placeholder="Old password..."
+ id="oldpassword"
+ formControlName="oldpassword"
+ autocomplete="new-password"
+ autofocus>
+ <span class="input-group-append">
+ <button class="btn btn-outline-light btn-password"
+ cdPasswordButton="oldpassword">
+ </button>
+ </span>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('oldpassword', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('oldpassword', frm, 'notmatch')"
+ i18n>The old and new passwords must be different.</span>
+ </div>
+
+ <!-- New password -->
+ <div class="form-group has-feedback">
+ <div class="input-group">
+ <input class="form-control"
+ type="password"
+ placeholder="New password..."
+ id="newpassword"
+ autocomplete="new-password"
+ formControlName="newpassword">
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-outline-light btn-password"
+ cdPasswordButton="newpassword">
+ </button>
+ </span>
+ </div>
+ <div class="password-strength-level">
+ <div class="{{ passwordStrengthLevelClass }}"
+ data-toggle="tooltip"
+ title="{{ passwordValuation }}">
+ </div>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('newpassword', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('newpassword', frm, 'notmatch')"
+ i18n>The old and new passwords must be different.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('newpassword', frm, 'passwordPolicy')">
+ {{ passwordValuation }}
+ </span>
+ </div>
+
+ <!-- Confirm new password -->
+ <div class="form-group has-feedback">
+ <div class="input-group">
+ <input class="form-control"
+ type="password"
+ autocomplete="new-password"
+ placeholder="Confirm new password..."
+ id="confirmnewpassword"
+ formControlName="confirmnewpassword">
+ <span class="input-group-append">
+ <button class="btn btn-outline-light btn-password"
+ cdPasswordButton="confirmnewpassword">
+ </button>
+ </span>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('confirmnewpassword', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('confirmnewpassword', frm, 'match')"
+ i18n>Password confirmation doesn't match the new password.</span>
+ </div>
+ <cd-form-button-panel (submitActionEvent)="onSubmit()"
+ (backActionEvent)="onCancel()"
+ [form]="userForm"
+ [disabled]="userForm.invalid"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
+ wrappingClass="text-right"></cd-form-button-panel>
+ </form>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.scss
new file mode 100755
index 000000000..15addd1e8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.scss
@@ -0,0 +1,68 @@
+@use 'sass:map';
+@use './src/styles/vendor/variables' as vv;
+
+$dark-secondary: darken(vv.$secondary, 4%);
+
+::ng-deep cd-login-password-form {
+ h4 {
+ margin: 0 0 30px;
+ }
+
+ .form-group {
+ background-color: $dark-secondary;
+ border-left: 4px solid vv.$white;
+
+ &:focus-within {
+ border-left: 4px solid map.get(vv.$theme-colors, 'accent');
+ }
+ }
+
+ .btn-password,
+ .btn-password:focus,
+ .form-control,
+ .form-control:focus {
+ background-color: $dark-secondary;
+ border: 0;
+ box-shadow: none;
+ color: vv.$body-color-bright;
+ filter: none;
+ outline: none;
+ }
+
+ .form-control::placeholder {
+ color: vv.$gray-600;
+ }
+
+ .btn-password:focus {
+ outline-color: vv.$primary;
+ }
+
+ button.btn:not(:first-child) {
+ margin-left: 5px;
+ }
+}
+
+// This will override the colors applied by chrome
+@keyframes autofill {
+ to {
+ background-color: $dark-secondary;
+ color: vv.$body-color-bright;
+ }
+}
+
+input:-webkit-autofill {
+ animation-fill-mode: both;
+ animation-name: autofill;
+ border-radius: 0;
+ box-shadow: 0 0 0 1000px $dark-secondary inset;
+ -webkit-text-fill-color: vv.$body-color-bright;
+ transition-property: none;
+}
+
+.invalid-feedback {
+ padding-left: 9px;
+}
+
+.is-invalid.cd-form-control {
+ border-color: transparent;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.spec.ts
new file mode 100755
index 000000000..062d076e4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.spec.ts
@@ -0,0 +1,77 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { Router } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+
+import { AuthService } from '~/app/shared/api/auth.service';
+import { ComponentsModule } from '~/app/shared/components/components.module';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
+import { LoginPasswordFormComponent } from './login-password-form.component';
+
+describe('LoginPasswordFormComponent', () => {
+ let component: LoginPasswordFormComponent;
+ let fixture: ComponentFixture<LoginPasswordFormComponent>;
+ let form: CdFormGroup;
+ let formHelper: FormHelper;
+ let httpTesting: HttpTestingController;
+ let router: Router;
+ let authStorageService: AuthStorageService;
+ let authService: AuthService;
+
+ configureTestBed({
+ imports: [
+ HttpClientTestingModule,
+ RouterTestingModule,
+ ReactiveFormsModule,
+ ComponentsModule,
+ ToastrModule.forRoot(),
+ SharedModule
+ ],
+ declarations: [LoginPasswordFormComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(LoginPasswordFormComponent);
+ component = fixture.componentInstance;
+ httpTesting = TestBed.inject(HttpTestingController);
+ router = TestBed.inject(Router);
+ authStorageService = TestBed.inject(AuthStorageService);
+ authService = TestBed.inject(AuthService);
+ spyOn(router, 'navigate');
+ fixture.detectChanges();
+ form = component.userForm;
+ formHelper = new FormHelper(form);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should submit', () => {
+ spyOn(component, 'onPasswordChange').and.callThrough();
+ spyOn(authService, 'logout');
+ spyOn(authStorageService, 'getUsername').and.returnValue('test1');
+ formHelper.setMultipleValues({
+ oldpassword: 'foo',
+ newpassword: 'bar'
+ });
+ formHelper.setValue('confirmnewpassword', 'bar', true);
+ component.onSubmit();
+ const request = httpTesting.expectOne('api/user/test1/change_password');
+ request.flush({});
+ expect(component.onPasswordChange).toHaveBeenCalled();
+ expect(authService.logout).toHaveBeenCalled();
+ });
+
+ it('should cancel', () => {
+ spyOn(authService, 'logout');
+ component.onCancel();
+ expect(authService.logout).toHaveBeenCalled();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.ts
new file mode 100755
index 000000000..0e72cca35
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.ts
@@ -0,0 +1,51 @@
+import { Component } from '@angular/core';
+import { Router } from '@angular/router';
+
+import { AuthService } from '~/app/shared/api/auth.service';
+import { UserService } from '~/app/shared/api/user.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { PasswordPolicyService } from '~/app/shared/services/password-policy.service';
+import { UserPasswordFormComponent } from '../user-password-form/user-password-form.component';
+
+@Component({
+ selector: 'cd-login-password-form',
+ templateUrl: './login-password-form.component.html',
+ styleUrls: ['./login-password-form.component.scss']
+})
+export class LoginPasswordFormComponent extends UserPasswordFormComponent {
+ constructor(
+ public actionLabels: ActionLabelsI18n,
+ public notificationService: NotificationService,
+ public userService: UserService,
+ public authStorageService: AuthStorageService,
+ public formBuilder: CdFormBuilder,
+ public router: Router,
+ public passwordPolicyService: PasswordPolicyService,
+ public authService: AuthService
+ ) {
+ super(
+ actionLabels,
+ notificationService,
+ userService,
+ authStorageService,
+ formBuilder,
+ router,
+ passwordPolicyService
+ );
+ }
+
+ onPasswordChange() {
+ // Logout here because changing the password will change the
+ // session token which will finally lead to a 401 when calling
+ // the REST API the next time. The API HTTP interceptor will
+ // then also redirect to the login page immediately.
+ this.authService.logout();
+ }
+
+ onCancel() {
+ this.authService.logout();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.html
new file mode 100644
index 000000000..8565c3615
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.html
@@ -0,0 +1,64 @@
+<div class="container"
+ *ngIf="isLoginActive">
+ <form name="loginForm"
+ (ngSubmit)="login()"
+ #loginForm="ngForm"
+ novalidate>
+
+ <!-- Username -->
+ <div class="form-group has-feedback d-flex flex-column py-3">
+ <label class="placeholder pl-4"
+ for="username"
+ i18n>Username</label>
+ <input id="username"
+ name="username"
+ [(ngModel)]="model.username"
+ #username="ngModel"
+ type="text"
+ [attr.aria-invalid]="username.invalid"
+ aria-labelledby="username"
+ class="form-control pl-4"
+ required
+ autofocus>
+ <div class="invalid-feedback pl-4"
+ *ngIf="(loginForm.submitted || username.dirty) && username.invalid"
+ i18n>Username is required</div>
+ </div>
+
+ <!-- Password -->
+ <div class="form-group has-feedback"
+ id="password-div">
+ <div class="input-group d-flex flex-nowrap">
+ <div class="d-flex flex-column flex-grow-1 py-3">
+ <label class="placeholder pl-4"
+ for="password"
+ i18n>Password</label>
+ <input id="password"
+ name="password"
+ [(ngModel)]="model.password"
+ #password="ngModel"
+ type="password"
+ [attr.aria-invalid]="password.invalid"
+ aria-labelledby="password"
+ class="form-control pl-4"
+ required>
+ <div class="invalid-feedback pl-4"
+ *ngIf="(loginForm.submitted || password.dirty) && password.invalid"
+ i18n>Password is required</div>
+ </div>
+ <span class="form-group-append">
+ <button type="button"
+ class="btn btn-outline-light btn-password h-100 px-4"
+ cdPasswordButton="password">
+ </button>
+ </span>
+ </div>
+ </div>
+
+ <input type="submit"
+ class="btn btn-accent px-5 py-2"
+ [disabled]="loginForm.invalid"
+ value="Log in"
+ i18n-value>
+ </form>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.scss
new file mode 100644
index 000000000..0fdc3c6ba
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.scss
@@ -0,0 +1,54 @@
+@use 'sass:map';
+@use './src/styles/vendor/variables' as vv;
+
+$dark-secondary: darken(vv.$secondary, 4%);
+
+::ng-deep cd-login {
+ .form-group {
+ background-color: $dark-secondary;
+ border-left: 4px solid vv.$white;
+ height: auto;
+ margin-bottom: 2rem;
+
+ &:focus-within {
+ border-left: 4px solid map.get(vv.$theme-colors, 'accent');
+ }
+ }
+
+ .btn-password,
+ .btn-password:focus,
+ .form-control,
+ .form-control:focus {
+ background-color: $dark-secondary;
+ border: 0;
+ box-shadow: none;
+ color: vv.$body-color-bright;
+ filter: none;
+ outline: none;
+ }
+
+ .placeholder {
+ color: vv.$gray-600;
+ }
+
+ .btn-password:focus {
+ outline-color: vv.$primary;
+ }
+}
+
+// This will override the colors applied by chrome
+@keyframes autofill {
+ to {
+ background-color: $dark-secondary;
+ color: vv.$body-color-bright;
+ }
+}
+
+input:-webkit-autofill {
+ animation-fill-mode: both;
+ animation-name: autofill;
+ border-radius: 0;
+ box-shadow: 0 0 0 1000px $dark-secondary inset;
+ -webkit-text-fill-color: vv.$body-color-bright;
+ transition-property: none;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.spec.ts
new file mode 100644
index 000000000..fc02e9bde
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.spec.ts
@@ -0,0 +1,58 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { Router } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { of } from 'rxjs';
+
+import { AuthService } from '~/app/shared/api/auth.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { AuthModule } from '../auth.module';
+import { LoginComponent } from './login.component';
+
+describe('LoginComponent', () => {
+ let component: LoginComponent;
+ let fixture: ComponentFixture<LoginComponent>;
+ let routerNavigateSpy: jasmine.Spy;
+ let authServiceLoginSpy: jasmine.Spy;
+
+ configureTestBed({
+ imports: [RouterTestingModule, HttpClientTestingModule, AuthModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(LoginComponent);
+ component = fixture.componentInstance;
+ routerNavigateSpy = spyOn(TestBed.inject(Router), 'navigate');
+ routerNavigateSpy.and.returnValue(true);
+ authServiceLoginSpy = spyOn(TestBed.inject(AuthService), 'login');
+ authServiceLoginSpy.and.returnValue(of(null));
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should ensure no modal dialogs are opened', () => {
+ component['modalService']['modalsCount'] = 2;
+ component.ngOnInit();
+ expect(component['modalService'].hasOpenModals()).toBeFalsy();
+ });
+
+ it('should not show create cluster wizard if cluster creation was successful', () => {
+ component.postInstalled = true;
+ component.login();
+
+ expect(routerNavigateSpy).toHaveBeenCalledTimes(1);
+ expect(routerNavigateSpy).toHaveBeenCalledWith(['/']);
+ });
+
+ it('should show create cluster wizard if cluster creation was failed', () => {
+ component.postInstalled = false;
+ component.login();
+
+ expect(routerNavigateSpy).toHaveBeenCalledTimes(1);
+ expect(routerNavigateSpy).toHaveBeenCalledWith(['/expand-cluster']);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.ts
new file mode 100644
index 000000000..a98548f94
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.ts
@@ -0,0 +1,76 @@
+import { Component, OnInit } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+
+import _ from 'lodash';
+
+import { AuthService } from '~/app/shared/api/auth.service';
+import { Credentials } from '~/app/shared/models/credentials';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+
+@Component({
+ selector: 'cd-login',
+ templateUrl: './login.component.html',
+ styleUrls: ['./login.component.scss']
+})
+export class LoginComponent implements OnInit {
+ model = new Credentials();
+ isLoginActive = false;
+ returnUrl: string;
+ postInstalled = false;
+
+ constructor(
+ private authService: AuthService,
+ private authStorageService: AuthStorageService,
+ private modalService: ModalService,
+ private route: ActivatedRoute,
+ private router: Router
+ ) {}
+
+ ngOnInit() {
+ if (this.authStorageService.isLoggedIn()) {
+ this.router.navigate(['']);
+ } else {
+ // Make sure all open modal dialogs are closed. This might be
+ // necessary when the logged in user is redirected to the login
+ // page after a 401.
+ this.modalService.dismissAll();
+
+ let token: string = null;
+ if (window.location.hash.indexOf('access_token=') !== -1) {
+ token = window.location.hash.split('access_token=')[1];
+ const uri = window.location.toString();
+ window.history.replaceState({}, document.title, uri.split('?')[0]);
+ }
+ this.authService.check(token).subscribe((login: any) => {
+ if (login.login_url) {
+ this.postInstalled = login.cluster_status === 'POST_INSTALLED';
+ if (login.login_url === '#/login') {
+ this.isLoginActive = true;
+ } else {
+ window.location.replace(login.login_url);
+ }
+ } else {
+ this.authStorageService.set(
+ login.username,
+ login.permissions,
+ login.sso,
+ login.pwdExpirationDate
+ );
+ this.router.navigate(['']);
+ }
+ });
+ }
+ }
+
+ login() {
+ this.authService.login(this.model).subscribe(() => {
+ const urlPath = this.postInstalled ? '/' : '/expand-cluster';
+ let url = _.get(this.route.snapshot.queryParams, 'returnUrl', urlPath);
+ if (!this.postInstalled && this.route.snapshot.queryParams['returnUrl'] === '/dashboard') {
+ url = '/expand-cluster';
+ }
+ this.router.navigate([url]);
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.html
new file mode 100644
index 000000000..ca4b6781b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.html
@@ -0,0 +1,11 @@
+<ng-container *ngIf="selection">
+ <cd-table [data]="scopes_permissions"
+ [columns]="columns"
+ columnMode="flex"
+ [toolHeader]="false"
+ [autoReload]="false"
+ [autoSave]="false"
+ [footer]="false"
+ [limit]="0">
+ </cd-table>
+</ng-container>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.scss
new file mode 100644
index 000000000..2ec160998
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.scss
@@ -0,0 +1,9 @@
+@use './src/styles/vendor/variables' as vv;
+
+.fa {
+ font-size: large;
+
+ &.fa-square-o {
+ color: vv.$gray-400;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.spec.ts
new file mode 100644
index 000000000..b62cd32eb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.spec.ts
@@ -0,0 +1,67 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RoleDetailsComponent } from './role-details.component';
+
+describe('RoleDetailsComponent', () => {
+ let component: RoleDetailsComponent;
+ let fixture: ComponentFixture<RoleDetailsComponent>;
+
+ configureTestBed({
+ imports: [SharedModule, RouterTestingModule, HttpClientTestingModule, NgbNavModule],
+ declarations: [RoleDetailsComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RoleDetailsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should create scopes permissions [1/2]', () => {
+ component.scopes = ['log', 'rgw'];
+ component.selection = {
+ description: 'RGW Manager',
+ name: 'rgw-manager',
+ scopes_permissions: {
+ rgw: ['read', 'create', 'update', 'delete']
+ },
+ system: true
+ };
+ expect(component.scopes_permissions.length).toBe(0);
+ component.ngOnChanges();
+ expect(component.scopes_permissions).toEqual([
+ { scope: 'log', read: false, create: false, update: false, delete: false },
+ { scope: 'rgw', read: true, create: true, update: true, delete: true }
+ ]);
+ });
+
+ it('should create scopes permissions [2/2]', () => {
+ component.scopes = ['cephfs', 'log', 'rgw'];
+ component.selection = {
+ description: 'Test',
+ name: 'test',
+ scopes_permissions: {
+ log: ['read', 'update'],
+ rgw: ['read', 'create', 'update']
+ },
+ system: false
+ };
+ expect(component.scopes_permissions.length).toBe(0);
+ component.ngOnChanges();
+ expect(component.scopes_permissions).toEqual([
+ { scope: 'cephfs', read: false, create: false, update: false, delete: false },
+ { scope: 'log', read: true, create: false, update: true, delete: false },
+ { scope: 'rgw', read: true, create: true, update: true, delete: false }
+ ]);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.ts
new file mode 100644
index 000000000..244a7861b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.ts
@@ -0,0 +1,79 @@
+import { Component, Input, OnChanges, OnInit } from '@angular/core';
+
+import _ from 'lodash';
+
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+
+@Component({
+ selector: 'cd-role-details',
+ templateUrl: './role-details.component.html',
+ styleUrls: ['./role-details.component.scss']
+})
+export class RoleDetailsComponent implements OnChanges, OnInit {
+ @Input()
+ selection: any;
+ @Input()
+ scopes: Array<string>;
+ selectedItem: any;
+
+ columns: CdTableColumn[];
+ scopes_permissions: Array<any> = [];
+
+ ngOnInit() {
+ this.columns = [
+ {
+ prop: 'scope',
+ name: $localize`Scope`,
+ flexGrow: 2
+ },
+ {
+ prop: 'read',
+ name: $localize`Read`,
+ flexGrow: 1,
+ cellClass: 'text-center',
+ cellTransformation: CellTemplate.checkIcon
+ },
+ {
+ prop: 'create',
+ name: $localize`Create`,
+ flexGrow: 1,
+ cellClass: 'text-center',
+ cellTransformation: CellTemplate.checkIcon
+ },
+ {
+ prop: 'update',
+ name: $localize`Update`,
+ flexGrow: 1,
+ cellClass: 'text-center',
+ cellTransformation: CellTemplate.checkIcon
+ },
+ {
+ prop: 'delete',
+ name: $localize`Delete`,
+ flexGrow: 1,
+ cellClass: 'text-center',
+ cellTransformation: CellTemplate.checkIcon
+ }
+ ];
+ }
+
+ ngOnChanges() {
+ if (this.selection) {
+ this.selectedItem = this.selection;
+ // Build the scopes/permissions data used by the data table.
+ const scopes_permissions: any[] = [];
+ _.each(this.scopes, (scope) => {
+ const scope_permission: any = { read: false, create: false, update: false, delete: false };
+ scope_permission['scope'] = scope;
+ if (scope in this.selectedItem['scopes_permissions']) {
+ _.each(this.selectedItem['scopes_permissions'][scope], (permission) => {
+ scope_permission[permission] = true;
+ });
+ }
+ scopes_permissions.push(scope_permission);
+ });
+ this.scopes_permissions = scopes_permissions;
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form-mode.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form-mode.enum.ts
new file mode 100644
index 000000000..4f0a6f11f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form-mode.enum.ts
@@ -0,0 +1,3 @@
+export enum RoleFormMode {
+ editing = 'editing'
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.html
new file mode 100644
index 000000000..08904c1c2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.html
@@ -0,0 +1,121 @@
+<div class="cd-col-form"
+ *cdFormLoading="loading">
+ <form name="roleForm"
+ #formDir="ngForm"
+ [formGroup]="roleForm"
+ novalidate>
+ <div class="card">
+ <div i18n="form title"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
+ <div class="card-body">
+
+ <!-- Name -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': mode !== roleFormMode.editing}"
+ for="name"
+ i18n>Name</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ i18n-placeholder
+ placeholder="Name..."
+ id="name"
+ name="name"
+ formControlName="name"
+ autofocus>
+ <span class="invalid-feedback"
+ *ngIf="roleForm.showError('name', formDir, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="roleForm.showError('name', formDir, 'notUnique')"
+ i18n>The chosen name is already in use.</span>
+ </div>
+ </div>
+
+ <!-- Description -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="description">Description</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ i18n-placeholder
+ placeholder="Description..."
+ id="description"
+ name="description"
+ formControlName="description">
+ </div>
+ </div>
+
+ <!-- Permissions -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label">Permissions</label>
+ <div class="cd-col-form-input">
+ <cd-table [data]="scopes_permissions"
+ [columns]="columns"
+ columnMode="flex"
+ [toolHeader]="false"
+ [autoReload]="false"
+ [autoSave]="false"
+ [footer]="false"
+ [limit]="0">
+ </cd-table>
+ </div>
+ </div>
+
+ </div>
+ <div class="card-footer">
+ <cd-form-button-panel (submitActionEvent)="submit()"
+ [form]="roleForm"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
+ wrappingClass="text-right"></cd-form-button-panel>
+ </div>
+ </div>
+ </form>
+</div>
+
+<ng-template #cellScopeCheckboxTpl
+ let-column="column"
+ let-row="row"
+ let-value="value">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="scope_{{ row.scope }}"
+ type="checkbox"
+ [checked]="isRowChecked(row.scope)"
+ (change)="onClickCellCheckbox(row.scope, column.prop, $event)">
+ <label class="datatable-permissions-scope-cell-label custom-control-label"
+ for="scope_{{ row.scope }}">{{ value }}</label>
+ </div>
+</ng-template>
+
+<ng-template #cellPermissionCheckboxTpl
+ let-column="column"
+ let-row="row"
+ let-value="value">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ type="checkbox"
+ [checked]="value"
+ [id]="row.scope + '-' + column.prop"
+ (change)="onClickCellCheckbox(row.scope, column.prop, $event)">
+ <label class="custom-control-label"
+ [for]="row.scope + '-' + column.prop"></label>
+ </div>
+</ng-template>
+
+<ng-template #headerPermissionCheckboxTpl
+ let-column="column">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="header_{{ column.prop }}"
+ type="checkbox"
+ [checked]="isHeaderChecked(column.prop)"
+ (change)="onClickHeaderCheckbox(column.prop, $event)">
+ <label class="datatable-permissions-header-cell-label custom-control-label"
+ for="header_{{ column.prop }}">{{ column.name }}</label>
+ </div>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.scss
new file mode 100644
index 000000000..3caafa2ee
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.scss
@@ -0,0 +1,4 @@
+.datatable-permissions-header-cell-label,
+.datatable-permissions-scope-cell-label {
+ font-weight: bold;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.spec.ts
new file mode 100644
index 000000000..7552f594b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.spec.ts
@@ -0,0 +1,222 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { Component } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { Router, Routes } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { RoleService } from '~/app/shared/api/role.service';
+import { ScopeService } from '~/app/shared/api/scope.service';
+import { LoadingPanelComponent } from '~/app/shared/components/loading-panel/loading-panel.component';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
+import { RoleFormComponent } from './role-form.component';
+import { RoleFormModel } from './role-form.model';
+
+describe('RoleFormComponent', () => {
+ let component: RoleFormComponent;
+ let form: CdFormGroup;
+ let fixture: ComponentFixture<RoleFormComponent>;
+ let httpTesting: HttpTestingController;
+ let roleService: RoleService;
+ let router: Router;
+ const setUrl = (url: string) => Object.defineProperty(router, 'url', { value: url });
+
+ @Component({ selector: 'cd-fake', template: '' })
+ class FakeComponent {}
+
+ const routes: Routes = [{ path: 'roles', component: FakeComponent }];
+
+ configureTestBed(
+ {
+ imports: [
+ RouterTestingModule.withRoutes(routes),
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ ToastrModule.forRoot(),
+ SharedModule
+ ],
+ declarations: [RoleFormComponent, FakeComponent]
+ },
+ [LoadingPanelComponent]
+ );
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RoleFormComponent);
+ component = fixture.componentInstance;
+ form = component.roleForm;
+ httpTesting = TestBed.inject(HttpTestingController);
+ roleService = TestBed.inject(RoleService);
+ router = TestBed.inject(Router);
+ spyOn(router, 'navigate');
+ fixture.detectChanges();
+ const notify = TestBed.inject(NotificationService);
+ spyOn(notify, 'show');
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ expect(form).toBeTruthy();
+ });
+
+ describe('create mode', () => {
+ let formHelper: FormHelper;
+
+ beforeEach(() => {
+ setUrl('/user-management/roles/add');
+ component.ngOnInit();
+ formHelper = new FormHelper(form);
+ });
+
+ it('should not disable fields', () => {
+ ['name', 'description', 'scopes_permissions'].forEach((key) =>
+ expect(form.get(key).disabled).toBeFalsy()
+ );
+ });
+
+ it('should validate name required', () => {
+ formHelper.expectErrorChange('name', '', 'required');
+ });
+
+ it('should set mode', () => {
+ expect(component.mode).toBeUndefined();
+ });
+
+ it('should submit', () => {
+ const role: RoleFormModel = {
+ name: 'role1',
+ description: 'Role 1',
+ scopes_permissions: { osd: ['read'] }
+ };
+ formHelper.setMultipleValues(role);
+ component.submit();
+ const roleReq = httpTesting.expectOne('api/role');
+ expect(roleReq.request.method).toBe('POST');
+ expect(roleReq.request.body).toEqual(role);
+ roleReq.flush({});
+ expect(router.navigate).toHaveBeenCalledWith(['/user-management/roles']);
+ });
+
+ it('should check all perms for a scope', () => {
+ formHelper.setValue('scopes_permissions', { cephfs: ['read'] });
+ component.onClickCellCheckbox('grafana', 'scope');
+ const scopes_permissions = form.getValue('scopes_permissions');
+ expect(Object.keys(scopes_permissions)).toContain('grafana');
+ expect(scopes_permissions['grafana']).toEqual(['create', 'delete', 'read', 'update']);
+ });
+
+ it('should uncheck all perms for a scope', () => {
+ formHelper.setValue('scopes_permissions', { cephfs: ['read', 'create', 'update', 'delete'] });
+ component.onClickCellCheckbox('cephfs', 'scope');
+ const scopes_permissions = form.getValue('scopes_permissions');
+ expect(Object.keys(scopes_permissions)).not.toContain('cephfs');
+ });
+
+ it('should uncheck all scopes and perms', () => {
+ component.scopes = ['cephfs', 'grafana'];
+ formHelper.setValue('scopes_permissions', {
+ cephfs: ['read', 'delete'],
+ grafana: ['update']
+ });
+ component.onClickHeaderCheckbox('scope', ({
+ target: { checked: false }
+ } as unknown) as Event);
+ const scopes_permissions = form.getValue('scopes_permissions');
+ expect(scopes_permissions).toEqual({});
+ });
+
+ it('should check all scopes and perms', () => {
+ component.scopes = ['cephfs', 'grafana'];
+ formHelper.setValue('scopes_permissions', {
+ cephfs: ['create', 'update'],
+ grafana: ['delete']
+ });
+ component.onClickHeaderCheckbox('scope', ({ target: { checked: true } } as unknown) as Event);
+ const scopes_permissions = form.getValue('scopes_permissions');
+ const keys = Object.keys(scopes_permissions);
+ expect(keys).toEqual(['cephfs', 'grafana']);
+ keys.forEach((key) => {
+ expect(scopes_permissions[key].sort()).toEqual(['create', 'delete', 'read', 'update']);
+ });
+ });
+
+ it('should check if column is checked', () => {
+ component.scopes_permissions = [
+ { scope: 'a', read: true, create: true, update: true, delete: true },
+ { scope: 'b', read: false, create: true, update: false, delete: true }
+ ];
+ expect(component.isRowChecked('a')).toBeTruthy();
+ expect(component.isRowChecked('b')).toBeFalsy();
+ expect(component.isRowChecked('c')).toBeFalsy();
+ });
+
+ it('should check if header is checked', () => {
+ component.scopes_permissions = [
+ { scope: 'a', read: true, create: true, update: false, delete: true },
+ { scope: 'b', read: false, create: true, update: false, delete: true }
+ ];
+ expect(component.isHeaderChecked('read')).toBeFalsy();
+ expect(component.isHeaderChecked('create')).toBeTruthy();
+ expect(component.isHeaderChecked('update')).toBeFalsy();
+ });
+ });
+
+ describe('edit mode', () => {
+ const role: RoleFormModel = {
+ name: 'role1',
+ description: 'Role 1',
+ scopes_permissions: { osd: ['read', 'create'] }
+ };
+ const scopes = ['osd', 'user'];
+ beforeEach(() => {
+ spyOn(roleService, 'get').and.callFake(() => of(role));
+ spyOn(TestBed.inject(ScopeService), 'list').and.callFake(() => of(scopes));
+ setUrl('/user-management/roles/edit/role1');
+ component.ngOnInit();
+ const reqScopes = httpTesting.expectOne('ui-api/scope');
+ expect(reqScopes.request.method).toBe('GET');
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should disable fields if editing', () => {
+ expect(form.get('name').disabled).toBeTruthy();
+ ['description', 'scopes_permissions'].forEach((key) =>
+ expect(form.get(key).disabled).toBeFalsy()
+ );
+ });
+
+ it('should set control values', () => {
+ ['name', 'description', 'scopes_permissions'].forEach((key) =>
+ expect(form.getValue(key)).toBe(role[key])
+ );
+ });
+
+ it('should set mode', () => {
+ expect(component.mode).toBe('editing');
+ });
+
+ it('should submit', () => {
+ component.onClickCellCheckbox('osd', 'update');
+ component.onClickCellCheckbox('osd', 'create');
+ component.onClickCellCheckbox('user', 'read');
+ component.submit();
+ const roleReq = httpTesting.expectOne(`api/role/${role.name}`);
+ expect(roleReq.request.method).toBe('PUT');
+ expect(roleReq.request.body).toEqual({
+ name: 'role1',
+ description: 'Role 1',
+ scopes_permissions: { osd: ['read', 'update'], user: ['read'] }
+ });
+ roleReq.flush({});
+ expect(router.navigate).toHaveBeenCalledWith(['/user-management/roles']);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.ts
new file mode 100644
index 000000000..21dff1c85
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.ts
@@ -0,0 +1,315 @@
+import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
+import { FormControl, Validators } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+
+import _ from 'lodash';
+import { forkJoin as observableForkJoin } from 'rxjs';
+
+import { RoleService } from '~/app/shared/api/role.service';
+import { ScopeService } from '~/app/shared/api/scope.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdForm } from '~/app/shared/forms/cd-form';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { RoleFormMode } from './role-form-mode.enum';
+import { RoleFormModel } from './role-form.model';
+
+@Component({
+ selector: 'cd-role-form',
+ templateUrl: './role-form.component.html',
+ styleUrls: ['./role-form.component.scss']
+})
+export class RoleFormComponent extends CdForm implements OnInit {
+ @ViewChild('headerPermissionCheckboxTpl', { static: true })
+ headerPermissionCheckboxTpl: TemplateRef<any>;
+ @ViewChild('cellScopeCheckboxTpl', { static: true })
+ cellScopeCheckboxTpl: TemplateRef<any>;
+ @ViewChild('cellPermissionCheckboxTpl', { static: true })
+ cellPermissionCheckboxTpl: TemplateRef<any>;
+
+ roleForm: CdFormGroup;
+ response: RoleFormModel;
+
+ columns: CdTableColumn[];
+ scopes: Array<string> = [];
+ scopes_permissions: Array<any> = [];
+
+ roleFormMode = RoleFormMode;
+ mode: RoleFormMode;
+
+ action: string;
+ resource: string;
+
+ constructor(
+ private route: ActivatedRoute,
+ private router: Router,
+ private roleService: RoleService,
+ private scopeService: ScopeService,
+ private notificationService: NotificationService,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ super();
+ this.resource = $localize`role`;
+ this.createForm();
+ this.listenToChanges();
+ }
+
+ createForm() {
+ this.roleForm = new CdFormGroup({
+ name: new FormControl('', {
+ validators: [Validators.required],
+ asyncValidators: [CdValidators.unique(this.roleService.exists, this.roleService)]
+ }),
+ description: new FormControl(''),
+ scopes_permissions: new FormControl({})
+ });
+ }
+
+ ngOnInit() {
+ this.columns = [
+ {
+ prop: 'scope',
+ name: $localize`All`,
+ flexGrow: 2,
+ cellTemplate: this.cellScopeCheckboxTpl,
+ headerTemplate: this.headerPermissionCheckboxTpl
+ },
+ {
+ prop: 'read',
+ name: $localize`Read`,
+ flexGrow: 1,
+ cellClass: 'text-center',
+ cellTemplate: this.cellPermissionCheckboxTpl,
+ headerTemplate: this.headerPermissionCheckboxTpl
+ },
+ {
+ prop: 'create',
+ name: $localize`Create`,
+ flexGrow: 1,
+ cellClass: 'text-center',
+ cellTemplate: this.cellPermissionCheckboxTpl,
+ headerTemplate: this.headerPermissionCheckboxTpl
+ },
+ {
+ prop: 'update',
+ name: $localize`Update`,
+ flexGrow: 1,
+ cellClass: 'text-center',
+ cellTemplate: this.cellPermissionCheckboxTpl,
+ headerTemplate: this.headerPermissionCheckboxTpl
+ },
+ {
+ prop: 'delete',
+ name: $localize`Delete`,
+ flexGrow: 1,
+ cellClass: 'text-center',
+ cellTemplate: this.cellPermissionCheckboxTpl,
+ headerTemplate: this.headerPermissionCheckboxTpl
+ }
+ ];
+ if (this.router.url.startsWith('/user-management/roles/edit')) {
+ this.mode = this.roleFormMode.editing;
+ this.action = this.actionLabels.EDIT;
+ } else {
+ this.action = this.actionLabels.CREATE;
+ }
+ if (this.mode === this.roleFormMode.editing) {
+ this.initEdit();
+ } else {
+ this.initCreate();
+ }
+ }
+
+ initCreate() {
+ // Load the scopes and initialize the default scopes/permissions data.
+ this.scopeService.list().subscribe((scopes: Array<string>) => {
+ this.scopes = scopes;
+ this.roleForm.get('scopes_permissions').setValue({});
+
+ this.loadingReady();
+ });
+ }
+
+ initEdit() {
+ // Disable the 'Name' input field.
+ this.roleForm.get('name').disable();
+ // Load the scopes and the role data.
+ this.route.params.subscribe((params: { name: string }) => {
+ const observables = [];
+ observables.push(this.scopeService.list());
+ observables.push(this.roleService.get(params.name));
+ observableForkJoin(observables).subscribe((resp: any[]) => {
+ this.scopes = resp[0];
+ ['name', 'description', 'scopes_permissions'].forEach((key) =>
+ this.roleForm.get(key).setValue(resp[1][key])
+ );
+
+ this.loadingReady();
+ });
+ });
+ }
+
+ listenToChanges() {
+ // Create/Update the data which is used by the data table to display the
+ // scopes/permissions every time the form field value has been changed.
+ this.roleForm.get('scopes_permissions').valueChanges.subscribe((value) => {
+ const scopes_permissions: any[] = [];
+ _.each(this.scopes, (scope) => {
+ // Set the defaults values.
+ const scope_permission: any = { read: false, create: false, update: false, delete: false };
+ scope_permission['scope'] = scope;
+ // Apply settings from the given value if they exist.
+ if (scope in value) {
+ _.each(value[scope], (permission) => {
+ scope_permission[permission] = true;
+ });
+ }
+ scopes_permissions.push(scope_permission);
+ });
+ this.scopes_permissions = scopes_permissions;
+ });
+ }
+
+ /**
+ * Checks if the specified row checkbox needs to be rendered as checked.
+ * @param {string} scope The scope to be checked, e.g. 'cephfs', 'grafana',
+ * 'osd', 'pool' ...
+ * @return Returns true if all permissions (read, create, update, delete)
+ * are checked for the specified scope, otherwise false.
+ */
+ isRowChecked(scope: string) {
+ const scope_permission = _.find(this.scopes_permissions, (o) => {
+ return o['scope'] === scope;
+ });
+ if (_.isUndefined(scope_permission)) {
+ return false;
+ }
+ return (
+ scope_permission['read'] &&
+ scope_permission['create'] &&
+ scope_permission['update'] &&
+ scope_permission['delete']
+ );
+ }
+
+ /**
+ * Checks if the specified header checkbox needs to be rendered as checked.
+ * @param {string} property The property/permission (read, create,
+ * update, delete) to be checked. If 'scope' is given, all permissions
+ * are checked.
+ * @return Returns true if specified property/permission is selected
+ * for all scopes, otherwise false.
+ */
+ isHeaderChecked(property: string) {
+ let permissions = [property];
+ if ('scope' === property) {
+ permissions = ['read', 'create', 'update', 'delete'];
+ }
+ return permissions.every((permission) => {
+ return this.scopes_permissions.every((scope_permission) => {
+ return scope_permission[permission];
+ });
+ });
+ }
+
+ onClickCellCheckbox(scope: string, property: string, event: any = null) {
+ // Use a copy of the form field data to do not trigger the redrawing of the
+ // data table with every change.
+ const scopes_permissions = _.cloneDeep(this.roleForm.getValue('scopes_permissions'));
+ let permissions = [property];
+ if ('scope' === property) {
+ permissions = ['read', 'create', 'update', 'delete'];
+ }
+ if (!(scope in scopes_permissions)) {
+ scopes_permissions[scope] = [];
+ }
+ // Add or remove the given permission(s) depending on the click event or if no
+ // click event is given then add/remove them if they are absent/exist.
+ if (
+ (event && event.target['checked']) ||
+ !_.isEqual(permissions.sort(), _.intersection(scopes_permissions[scope], permissions).sort())
+ ) {
+ scopes_permissions[scope] = _.union(scopes_permissions[scope], permissions);
+ } else {
+ scopes_permissions[scope] = _.difference(scopes_permissions[scope], permissions);
+ if (_.isEmpty(scopes_permissions[scope])) {
+ _.unset(scopes_permissions, scope);
+ }
+ }
+ this.roleForm.get('scopes_permissions').setValue(scopes_permissions);
+ }
+
+ onClickHeaderCheckbox(property: 'scope' | 'read' | 'create' | 'update' | 'delete', event: any) {
+ // Use a copy of the form field data to do not trigger the redrawing of the
+ // data table with every change.
+ const scopes_permissions = _.cloneDeep(this.roleForm.getValue('scopes_permissions'));
+ let permissions = [property];
+ if ('scope' === property) {
+ permissions = ['read', 'create', 'update', 'delete'];
+ }
+ _.each(permissions, (permission) => {
+ _.each(this.scopes, (scope) => {
+ if (event.target['checked']) {
+ scopes_permissions[scope] = _.union(scopes_permissions[scope], [permission]);
+ } else {
+ scopes_permissions[scope] = _.difference(scopes_permissions[scope], [permission]);
+ if (_.isEmpty(scopes_permissions[scope])) {
+ _.unset(scopes_permissions, scope);
+ }
+ }
+ });
+ });
+ this.roleForm.get('scopes_permissions').setValue(scopes_permissions);
+ }
+
+ getRequest(): RoleFormModel {
+ const roleFormModel = new RoleFormModel();
+ ['name', 'description', 'scopes_permissions'].forEach(
+ (key) => (roleFormModel[key] = this.roleForm.get(key).value)
+ );
+ return roleFormModel;
+ }
+
+ createAction() {
+ const roleFormModel = this.getRequest();
+ this.roleService.create(roleFormModel).subscribe(
+ () => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Created role '${roleFormModel.name}'`
+ );
+ this.router.navigate(['/user-management/roles']);
+ },
+ () => {
+ this.roleForm.setErrors({ cdSubmitButton: true });
+ }
+ );
+ }
+
+ editAction() {
+ const roleFormModel = this.getRequest();
+ this.roleService.update(roleFormModel).subscribe(
+ () => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Updated role '${roleFormModel.name}'`
+ );
+ this.router.navigate(['/user-management/roles']);
+ },
+ () => {
+ this.roleForm.setErrors({ cdSubmitButton: true });
+ }
+ );
+ }
+
+ submit() {
+ if (this.mode === this.roleFormMode.editing) {
+ this.editAction();
+ } else {
+ this.createAction();
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.model.ts
new file mode 100644
index 000000000..74a7323be
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.model.ts
@@ -0,0 +1,5 @@
+export class RoleFormModel {
+ name: string;
+ description: string;
+ scopes_permissions: any;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.html
new file mode 100644
index 000000000..6b8a5d73e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.html
@@ -0,0 +1,21 @@
+<cd-user-tabs></cd-user-tabs>
+
+<cd-table [data]="roles"
+ columnMode="flex"
+ [columns]="columns"
+ identifier="name"
+ selectionType="single"
+ [hasDetails]="true"
+ (setExpandedRow)="setExpandedRow($event)"
+ (fetchData)="getRoles()"
+ (updateSelection)="updateSelection($event)">
+ <cd-table-actions class="table-actions"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ <cd-role-details cdTableDetail
+ [selection]="expandedRow"
+ [scopes]="scopes">
+ </cd-role-details>
+</cd-table>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.spec.ts
new file mode 100644
index 000000000..373e37b9d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.spec.ts
@@ -0,0 +1,83 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+
+import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, PermissionHelper } from '~/testing/unit-test-helper';
+import { RoleDetailsComponent } from '../role-details/role-details.component';
+import { UserTabsComponent } from '../user-tabs/user-tabs.component';
+import { RoleListComponent } from './role-list.component';
+
+describe('RoleListComponent', () => {
+ let component: RoleListComponent;
+ let fixture: ComponentFixture<RoleListComponent>;
+
+ configureTestBed({
+ declarations: [RoleListComponent, RoleDetailsComponent, UserTabsComponent],
+ imports: [
+ BrowserAnimationsModule,
+ SharedModule,
+ ToastrModule.forRoot(),
+ NgbNavModule,
+ RouterTestingModule,
+ HttpClientTestingModule
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RoleListComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+
+ it('should test all TableActions combinations', () => {
+ const permissionHelper: PermissionHelper = new PermissionHelper(component.permission);
+ const tableActions: TableActionsComponent = permissionHelper.setPermissionsAndGetActions(
+ component.tableActions
+ );
+
+ expect(tableActions).toEqual({
+ 'create,update,delete': {
+ actions: ['Create', 'Clone', 'Edit', 'Delete'],
+ primary: { multiple: 'Create', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,update': {
+ actions: ['Create', 'Clone', 'Edit'],
+ primary: { multiple: 'Create', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,delete': {
+ actions: ['Create', 'Clone', 'Delete'],
+ primary: { multiple: 'Create', executing: 'Delete', single: 'Delete', no: 'Create' }
+ },
+ create: {
+ actions: ['Create', 'Clone'],
+ primary: { multiple: 'Create', executing: 'Create', single: 'Create', no: 'Create' }
+ },
+ 'update,delete': {
+ actions: ['Edit', 'Delete'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ update: {
+ actions: ['Edit'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ delete: {
+ actions: ['Delete'],
+ primary: { multiple: 'Delete', executing: 'Delete', single: 'Delete', no: 'Delete' }
+ },
+ 'no-permissions': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ }
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.ts
new file mode 100644
index 000000000..83dcd69fa
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.ts
@@ -0,0 +1,169 @@
+import { Component, OnInit } from '@angular/core';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { forkJoin } from 'rxjs';
+
+import { RoleService } from '~/app/shared/api/role.service';
+import { ScopeService } from '~/app/shared/api/scope.service';
+import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { FormModalComponent } from '~/app/shared/components/form-modal/form-modal.component';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { Permission } from '~/app/shared/models/permissions';
+import { EmptyPipe } from '~/app/shared/pipes/empty.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { URLBuilderService } from '~/app/shared/services/url-builder.service';
+
+const BASE_URL = 'user-management/roles';
+
+@Component({
+ selector: 'cd-role-list',
+ templateUrl: './role-list.component.html',
+ styleUrls: ['./role-list.component.scss'],
+ providers: [{ provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }]
+})
+export class RoleListComponent extends ListWithDetails implements OnInit {
+ permission: Permission;
+ tableActions: CdTableAction[];
+ columns: CdTableColumn[];
+ roles: Array<any>;
+ scopes: Array<string>;
+ selection = new CdTableSelection();
+
+ modalRef: NgbModalRef;
+
+ constructor(
+ private roleService: RoleService,
+ private scopeService: ScopeService,
+ private emptyPipe: EmptyPipe,
+ private authStorageService: AuthStorageService,
+ private modalService: ModalService,
+ private notificationService: NotificationService,
+ private urlBuilder: URLBuilderService,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ super();
+ this.permission = this.authStorageService.getPermissions().user;
+ const addAction: CdTableAction = {
+ permission: 'create',
+ icon: Icons.add,
+ routerLink: () => this.urlBuilder.getCreate(),
+ name: this.actionLabels.CREATE
+ };
+ const cloneAction: CdTableAction = {
+ permission: 'create',
+ icon: Icons.clone,
+ name: this.actionLabels.CLONE,
+ disable: () => !this.selection.hasSingleSelection,
+ click: () => this.cloneRole()
+ };
+ const editAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.edit,
+ disable: () => !this.selection.hasSingleSelection || this.selection.first().system,
+ routerLink: () =>
+ this.selection.first() && this.urlBuilder.getEdit(this.selection.first().name),
+ name: this.actionLabels.EDIT
+ };
+ const deleteAction: CdTableAction = {
+ permission: 'delete',
+ icon: Icons.destroy,
+ disable: () => !this.selection.hasSingleSelection || this.selection.first().system,
+ click: () => this.deleteRoleModal(),
+ name: this.actionLabels.DELETE
+ };
+ this.tableActions = [addAction, cloneAction, editAction, deleteAction];
+ }
+
+ ngOnInit() {
+ this.columns = [
+ {
+ name: $localize`Name`,
+ prop: 'name',
+ flexGrow: 3
+ },
+ {
+ name: $localize`Description`,
+ prop: 'description',
+ flexGrow: 5,
+ pipe: this.emptyPipe
+ },
+ {
+ name: $localize`System Role`,
+ prop: 'system',
+ cellClass: 'text-center',
+ flexGrow: 1,
+ cellTransformation: CellTemplate.checkIcon
+ }
+ ];
+ }
+
+ getRoles() {
+ forkJoin([this.roleService.list(), this.scopeService.list()]).subscribe(
+ (data: [Array<any>, Array<string>]) => {
+ this.roles = data[0];
+ this.scopes = data[1];
+ }
+ );
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ deleteRole(role: string) {
+ this.roleService.delete(role).subscribe(
+ () => {
+ this.getRoles();
+ this.modalRef.close();
+ this.notificationService.show(NotificationType.success, $localize`Deleted role '${role}'`);
+ },
+ () => {
+ this.modalRef.componentInstance.stopLoadingSpinner();
+ }
+ );
+ }
+
+ deleteRoleModal() {
+ const name = this.selection.first().name;
+ this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: 'Role',
+ itemNames: [name],
+ submitAction: () => this.deleteRole(name)
+ });
+ }
+
+ cloneRole() {
+ const name = this.selection.first().name;
+ this.modalRef = this.modalService.show(FormModalComponent, {
+ fields: [
+ {
+ type: 'text',
+ name: 'newName',
+ value: `${name}_clone`,
+ label: $localize`New name`,
+ required: true
+ }
+ ],
+ titleText: $localize`Clone Role`,
+ submitButtonText: $localize`Clone Role`,
+ onSubmit: (values: object) => {
+ this.roleService.clone(name, values['newName']).subscribe(() => {
+ this.getRoles();
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Cloned role '${values['newName']}' from '${name}'`
+ );
+ });
+ }
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form-mode.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form-mode.enum.ts
new file mode 100644
index 000000000..8cae7d15f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form-mode.enum.ts
@@ -0,0 +1,3 @@
+export enum UserFormMode {
+ editing = 'editing'
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form-role.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form-role.model.ts
new file mode 100644
index 000000000..2d323b04e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form-role.model.ts
@@ -0,0 +1,14 @@
+import { SelectOption } from '~/app/shared/components/select/select-option.model';
+
+export class UserFormRoleModel implements SelectOption {
+ name: string;
+ description: string;
+ selected = false;
+ scopes_permissions: object;
+ enabled = true;
+
+ constructor(name: string, description: string) {
+ this.name = name;
+ this.description = description;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.html
new file mode 100644
index 000000000..df97face8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.html
@@ -0,0 +1,263 @@
+<div class="cd-col-form"
+ *cdFormLoading="loading">
+ <form name="userForm"
+ #formDir="ngForm"
+ [formGroup]="userForm"
+ novalidate>
+ <div class="card">
+ <div i18n="form title"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
+ <div class="card-body">
+
+ <!-- Username -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': mode !== userFormMode.editing}"
+ for="username"
+ i18n>Username</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ placeholder="Username..."
+ id="username"
+ name="username"
+ formControlName="username"
+ autocomplete="off"
+ autofocus>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('username', formDir, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('username', formDir, 'notUnique')"
+ i18n>The username already exists.</span>
+ </div>
+ </div>
+
+ <!-- Password -->
+ <div class="form-group row"
+ *ngIf="!authStorageService.isSSO()">
+ <label class="cd-col-form-label"
+ for="password">
+ <ng-container i18n>Password</ng-container>
+ <cd-helper *ngIf="passwordPolicyHelpText.length > 0"
+ class="text-pre-wrap"
+ html="{{ passwordPolicyHelpText }}">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input class="form-control"
+ type="password"
+ placeholder="Password..."
+ id="password"
+ name="password"
+ autocomplete="new-password"
+ formControlName="password">
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="password">
+ </button>
+ </span>
+ </div>
+ <div class="password-strength-level">
+ <div class="{{ passwordStrengthLevelClass }}"
+ data-toggle="tooltip"
+ title="{{ passwordValuation }}">
+ </div>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('password', formDir, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('password', formDir, 'passwordPolicy')">
+ {{ passwordValuation }}
+ </span>
+ </div>
+ </div>
+
+ <!-- Confirm password -->
+ <div class="form-group row"
+ *ngIf="!authStorageService.isSSO()">
+ <label i18n
+ class="cd-col-form-label"
+ for="confirmpassword">Confirm password</label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input class="form-control"
+ type="password"
+ placeholder="Confirm password..."
+ id="confirmpassword"
+ name="confirmpassword"
+ autocomplete="new-password"
+ formControlName="confirmpassword">
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="confirmpassword">
+ </button>
+ </span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('confirmpassword', formDir, 'match')"
+ i18n>Password confirmation doesn't match the password.</span>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('confirmpassword', formDir, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+
+ <!-- Password expiration date -->
+ <div class="form-group row"
+ *ngIf="!authStorageService.isSSO()">
+ <label class="cd-col-form-label"
+ [ngClass]="{'required': pwdExpirationSettings.pwdExpirationSpan > 0}"
+ for="pwdExpirationDate">
+ <ng-container i18n>Password expiration date</ng-container>
+ <cd-helper class="text-pre-wrap"
+ *ngIf="pwdExpirationSettings.pwdExpirationSpan == 0">
+ <p>
+ The Dashboard setting defining the expiration interval of
+ passwords is currently set to <strong>0</strong>. This means
+ if a date is set, the user password will only expire once.
+ </p>
+ <p>
+ Consider configuring the Dashboard setting
+ <a routerLink="/mgr-modules/edit/dashboard"
+ class="alert-link">USER_PWD_EXPIRATION_SPAN</a>
+ in order to let passwords expire periodically.
+ </p>
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input class="form-control"
+ i18n-placeholder
+ placeholder="Password expiration date..."
+ id="pwdExpirationDate"
+ name="pwdExpirationDate"
+ formControlName="pwdExpirationDate"
+ [ngbPopover]="popContent"
+ triggers="manual"
+ #p="ngbPopover"
+ (click)="p.open()"
+ (keypress)="p.close()">
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ (click)="clearExpirationDate()">
+ <i class="icon-prepend {{ icons.destroy }}"></i>
+ </button>
+ </span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('pwdExpirationDate', formDir, 'required')"
+ i18n>This field is required.</span>
+ </div>
+ </div>
+ </div>
+
+ <!-- Name -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="name">Full name</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="text"
+ placeholder="Full name..."
+ id="name"
+ name="name"
+ formControlName="name">
+ </div>
+ </div>
+
+ <!-- Email -->
+ <div class="form-group row">
+ <label i18n
+ class="cd-col-form-label"
+ for="email">Email</label>
+ <div class="cd-col-form-input">
+ <input class="form-control"
+ type="email"
+ placeholder="Email..."
+ id="email"
+ name="email"
+ formControlName="email">
+
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('email', formDir, 'email')"
+ i18n>Invalid email.</span>
+ </div>
+ </div>
+
+ <!-- Roles -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ i18n>Roles</label>
+ <div class="cd-col-form-input">
+ <span class="no-border full-height"
+ *ngIf="allRoles">
+ <cd-select-badges [data]="userForm.controls.roles.value"
+ [options]="allRoles"
+ [messages]="messages"></cd-select-badges>
+ </span>
+ </div>
+ </div>
+
+ <!-- Enabled -->
+ <div class="form-group row"
+ *ngIf="!isCurrentUser()">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ id="enabled"
+ name="enabled"
+ formControlName="enabled">
+ <label class="custom-control-label"
+ for="enabled"
+ i18n>Enabled</label>
+ </div>
+ </div>
+ </div>
+
+ <!-- Force change password -->
+ <div class="form-group row"
+ *ngIf="!isCurrentUser() && !authStorageService.isSSO()">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ id="pwdUpdateRequired"
+ name="pwdUpdateRequired"
+ formControlName="pwdUpdateRequired">
+ <label class="custom-control-label"
+ for="pwdUpdateRequired"
+ i18n>User must change password at next logon</label>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ <div class="card-footer">
+ <cd-form-button-panel (submitActionEvent)="submit()"
+ [form]="userForm"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
+ wrappingClass="text-right"></cd-form-button-panel>
+ </div>
+ </div>
+ </form>
+</div>
+
+<ng-template #removeSelfUserReadUpdatePermissionTpl>
+ <p><strong i18n>You are about to remove "user read / update" permissions from your own user.</strong></p>
+ <br>
+ <p i18n>If you continue, you will no longer be able to add or remove roles from any user.</p>
+
+ <ng-container i18n>Are you sure you want to continue?</ng-container>
+</ng-template>
+
+<ng-template #popContent>
+ <cd-date-time-picker [control]="userForm.get('pwdExpirationDate')"
+ [hasTime]="false"></cd-date-time-picker>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.spec.ts
new file mode 100644
index 000000000..4f95ac1e2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.spec.ts
@@ -0,0 +1,258 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { Component } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { Router, Routes } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { RoleService } from '~/app/shared/api/role.service';
+import { SettingsService } from '~/app/shared/api/settings.service';
+import { UserService } from '~/app/shared/api/user.service';
+import { ComponentsModule } from '~/app/shared/components/components.module';
+import { LoadingPanelComponent } from '~/app/shared/components/loading-panel/loading-panel.component';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { PasswordPolicyService } from '~/app/shared/services/password-policy.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
+import { UserFormComponent } from './user-form.component';
+import { UserFormModel } from './user-form.model';
+
+describe('UserFormComponent', () => {
+ let component: UserFormComponent;
+ let form: CdFormGroup;
+ let fixture: ComponentFixture<UserFormComponent>;
+ let httpTesting: HttpTestingController;
+ let userService: UserService;
+ let modalService: ModalService;
+ let router: Router;
+ let formHelper: FormHelper;
+
+ const setUrl = (url: string) => Object.defineProperty(router, 'url', { value: url });
+
+ @Component({ selector: 'cd-fake', template: '' })
+ class FakeComponent {}
+
+ const routes: Routes = [
+ { path: 'login', component: FakeComponent },
+ { path: 'users', component: FakeComponent }
+ ];
+
+ configureTestBed(
+ {
+ imports: [
+ RouterTestingModule.withRoutes(routes),
+ HttpClientTestingModule,
+ ReactiveFormsModule,
+ ComponentsModule,
+ ToastrModule.forRoot(),
+ SharedModule,
+ NgbPopoverModule
+ ],
+ declarations: [UserFormComponent, FakeComponent]
+ },
+ [LoadingPanelComponent]
+ );
+
+ beforeEach(() => {
+ spyOn(TestBed.inject(PasswordPolicyService), 'getHelpText').and.callFake(() => of(''));
+ fixture = TestBed.createComponent(UserFormComponent);
+ component = fixture.componentInstance;
+ form = component.userForm;
+ httpTesting = TestBed.inject(HttpTestingController);
+ userService = TestBed.inject(UserService);
+ modalService = TestBed.inject(ModalService);
+ router = TestBed.inject(Router);
+ spyOn(router, 'navigate');
+ fixture.detectChanges();
+ const notify = TestBed.inject(NotificationService);
+ spyOn(notify, 'show');
+ formHelper = new FormHelper(form);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ expect(form).toBeTruthy();
+ });
+
+ describe('create mode', () => {
+ beforeEach(() => {
+ setUrl('/user-management/users/add');
+ component.ngOnInit();
+ });
+
+ it('should not disable fields', () => {
+ [
+ 'username',
+ 'name',
+ 'password',
+ 'confirmpassword',
+ 'email',
+ 'roles',
+ 'pwdExpirationDate'
+ ].forEach((key) => expect(form.get(key).disabled).toBeFalsy());
+ });
+
+ it('should validate username required', () => {
+ formHelper.expectErrorChange('username', '', 'required');
+ formHelper.expectValidChange('username', 'user1');
+ });
+
+ it('should validate password match', () => {
+ formHelper.setValue('password', 'aaa');
+ formHelper.expectErrorChange('confirmpassword', 'bbb', 'match');
+ formHelper.expectValidChange('confirmpassword', 'aaa');
+ });
+
+ it('should validate email', () => {
+ formHelper.expectErrorChange('email', 'aaa', 'email');
+ });
+
+ it('should set mode', () => {
+ expect(component.mode).toBeUndefined();
+ });
+
+ it('should submit', () => {
+ const user: UserFormModel = {
+ username: 'user0',
+ password: 'pass0',
+ name: 'User 0',
+ email: 'user0@email.com',
+ roles: ['administrator'],
+ enabled: true,
+ pwdExpirationDate: undefined,
+ pwdUpdateRequired: true
+ };
+ formHelper.setMultipleValues(user);
+ formHelper.setValue('confirmpassword', user.password);
+ component.submit();
+ const userReq = httpTesting.expectOne('api/user');
+ expect(userReq.request.method).toBe('POST');
+ expect(userReq.request.body).toEqual(user);
+ userReq.flush({});
+ expect(router.navigate).toHaveBeenCalledWith(['/user-management/users']);
+ });
+ });
+
+ describe('edit mode', () => {
+ const user: UserFormModel = {
+ username: 'user1',
+ password: undefined,
+ name: 'User 1',
+ email: 'user1@email.com',
+ roles: ['administrator'],
+ enabled: true,
+ pwdExpirationDate: undefined,
+ pwdUpdateRequired: true
+ };
+ const roles = [
+ {
+ name: 'administrator',
+ description: 'Administrator',
+ scopes_permissions: {
+ user: ['create', 'delete', 'read', 'update']
+ }
+ },
+ {
+ name: 'read-only',
+ description: 'Read-Only',
+ scopes_permissions: {
+ user: ['read']
+ }
+ },
+ {
+ name: 'user-manager',
+ description: 'User Manager',
+ scopes_permissions: {
+ user: ['create', 'delete', 'read', 'update']
+ }
+ }
+ ];
+
+ beforeEach(() => {
+ spyOn(userService, 'get').and.callFake(() => of(user));
+ spyOn(TestBed.inject(RoleService), 'list').and.callFake(() => of(roles));
+ setUrl('/user-management/users/edit/user1');
+ spyOn(TestBed.inject(SettingsService), 'getStandardSettings').and.callFake(() =>
+ of({
+ user_pwd_expiration_warning_1: 10,
+ user_pwd_expiration_warning_2: 5,
+ user_pwd_expiration_span: 90
+ })
+ );
+ component.ngOnInit();
+ const req = httpTesting.expectOne('api/role');
+ expect(req.request.method).toBe('GET');
+ req.flush(roles);
+ httpTesting.expectOne('ui-api/standard_settings');
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should disable fields if editing', () => {
+ expect(form.get('username').disabled).toBeTruthy();
+ ['name', 'password', 'confirmpassword', 'email', 'roles'].forEach((key) =>
+ expect(form.get(key).disabled).toBeFalsy()
+ );
+ });
+
+ it('should set control values', () => {
+ ['username', 'name', 'email', 'roles'].forEach((key) =>
+ expect(form.getValue(key)).toBe(user[key])
+ );
+ ['password', 'confirmpassword'].forEach((key) => expect(form.getValue(key)).toBeFalsy());
+ });
+
+ it('should set mode', () => {
+ expect(component.mode).toBe('editing');
+ });
+
+ it('should alert if user is removing needed role permission', () => {
+ spyOn(TestBed.inject(AuthStorageService), 'getUsername').and.callFake(() => user.username);
+ let modalBodyTpl = null;
+ spyOn(modalService, 'show').and.callFake((_content, initialState) => {
+ modalBodyTpl = initialState.bodyTpl;
+ });
+ formHelper.setValue('roles', ['read-only']);
+ component.submit();
+ expect(modalBodyTpl).toEqual(component.removeSelfUserReadUpdatePermissionTpl);
+ });
+
+ it('should logout if current user roles have been changed', () => {
+ spyOn(TestBed.inject(AuthStorageService), 'getUsername').and.callFake(() => user.username);
+ formHelper.setValue('roles', ['user-manager']);
+ component.submit();
+ const userReq = httpTesting.expectOne(`api/user/${user.username}`);
+ expect(userReq.request.method).toBe('PUT');
+ userReq.flush({});
+ const authReq = httpTesting.expectOne('api/auth/logout');
+ expect(authReq.request.method).toBe('POST');
+ });
+
+ it('should submit', () => {
+ spyOn(TestBed.inject(AuthStorageService), 'getUsername').and.callFake(() => user.username);
+ component.submit();
+ const userReq = httpTesting.expectOne(`api/user/${user.username}`);
+ expect(userReq.request.method).toBe('PUT');
+ expect(userReq.request.body).toEqual({
+ username: 'user1',
+ password: '',
+ pwdUpdateRequired: true,
+ name: 'User 1',
+ email: 'user1@email.com',
+ roles: ['administrator'],
+ enabled: true
+ });
+ userReq.flush({});
+ expect(router.navigate).toHaveBeenCalledWith(['/user-management/users']);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.ts
new file mode 100644
index 000000000..1a0ddf35c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.ts
@@ -0,0 +1,305 @@
+import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
+import { Validators } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import moment from 'moment';
+import { forkJoin as observableForkJoin } from 'rxjs';
+
+import { AuthService } from '~/app/shared/api/auth.service';
+import { RoleService } from '~/app/shared/api/role.service';
+import { SettingsService } from '~/app/shared/api/settings.service';
+import { UserService } from '~/app/shared/api/user.service';
+import { ConfirmationModalComponent } from '~/app/shared/components/confirmation-modal/confirmation-modal.component';
+import { SelectMessages } from '~/app/shared/components/select/select-messages.model';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdForm } from '~/app/shared/forms/cd-form';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { CdPwdExpirationSettings } from '~/app/shared/models/cd-pwd-expiration-settings';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { PasswordPolicyService } from '~/app/shared/services/password-policy.service';
+import { UserFormMode } from './user-form-mode.enum';
+import { UserFormRoleModel } from './user-form-role.model';
+import { UserFormModel } from './user-form.model';
+
+@Component({
+ selector: 'cd-user-form',
+ templateUrl: './user-form.component.html',
+ styleUrls: ['./user-form.component.scss']
+})
+export class UserFormComponent extends CdForm implements OnInit {
+ @ViewChild('removeSelfUserReadUpdatePermissionTpl', { static: true })
+ removeSelfUserReadUpdatePermissionTpl: TemplateRef<any>;
+
+ modalRef: NgbModalRef;
+
+ userForm: CdFormGroup;
+ response: UserFormModel;
+
+ userFormMode = UserFormMode;
+ mode: UserFormMode;
+ allRoles: Array<UserFormRoleModel>;
+ messages = new SelectMessages({ empty: $localize`There are no roles.` });
+ action: string;
+ resource: string;
+ passwordPolicyHelpText = '';
+ passwordStrengthLevelClass: string;
+ passwordValuation: string;
+ icons = Icons;
+ pwdExpirationSettings: CdPwdExpirationSettings;
+ pwdExpirationFormat = 'YYYY-MM-DD';
+
+ constructor(
+ private authService: AuthService,
+ private authStorageService: AuthStorageService,
+ private route: ActivatedRoute,
+ public router: Router,
+ private modalService: ModalService,
+ private roleService: RoleService,
+ private userService: UserService,
+ private notificationService: NotificationService,
+ public actionLabels: ActionLabelsI18n,
+ private passwordPolicyService: PasswordPolicyService,
+ private formBuilder: CdFormBuilder,
+ private settingsService: SettingsService
+ ) {
+ super();
+ this.resource = $localize`user`;
+ this.createForm();
+ this.messages = new SelectMessages({ empty: $localize`There are no roles.` });
+ }
+
+ createForm() {
+ this.passwordPolicyService.getHelpText().subscribe((helpText: string) => {
+ this.passwordPolicyHelpText = helpText;
+ });
+ this.userForm = this.formBuilder.group(
+ {
+ username: [
+ '',
+ [Validators.required],
+ [CdValidators.unique(this.userService.validateUserName, this.userService)]
+ ],
+ name: [''],
+ password: [
+ '',
+ [],
+ [
+ CdValidators.passwordPolicy(
+ this.userService,
+ () => this.userForm.getValue('username'),
+ (_valid: boolean, credits: number, valuation: string) => {
+ this.passwordStrengthLevelClass = this.passwordPolicyService.mapCreditsToCssClass(
+ credits
+ );
+ this.passwordValuation = _.defaultTo(valuation, '');
+ }
+ )
+ ]
+ ],
+ confirmpassword: [''],
+ pwdExpirationDate: [undefined],
+ email: ['', [CdValidators.email]],
+ roles: [[]],
+ enabled: [true, [Validators.required]],
+ pwdUpdateRequired: [true]
+ },
+ {
+ validators: [CdValidators.match('password', 'confirmpassword')]
+ }
+ );
+ }
+
+ ngOnInit() {
+ if (this.router.url.startsWith('/user-management/users/edit')) {
+ this.mode = this.userFormMode.editing;
+ this.action = this.actionLabels.EDIT;
+ } else {
+ this.action = this.actionLabels.CREATE;
+ }
+
+ const observables = [this.roleService.list(), this.settingsService.getStandardSettings()];
+ observableForkJoin(observables).subscribe(
+ (result: [UserFormRoleModel[], CdPwdExpirationSettings]) => {
+ this.allRoles = _.map(result[0], (role) => {
+ role.enabled = true;
+ return role;
+ });
+ this.pwdExpirationSettings = new CdPwdExpirationSettings(result[1]);
+
+ if (this.mode === this.userFormMode.editing) {
+ this.initEdit();
+ } else {
+ if (this.pwdExpirationSettings.pwdExpirationSpan > 0) {
+ const pwdExpirationDateField = this.userForm.get('pwdExpirationDate');
+ const expirationDate = moment();
+ expirationDate.add(this.pwdExpirationSettings.pwdExpirationSpan, 'day');
+ pwdExpirationDateField.setValue(expirationDate.format(this.pwdExpirationFormat));
+ pwdExpirationDateField.setValidators([Validators.required]);
+ }
+
+ this.loadingReady();
+ }
+ }
+ );
+ }
+
+ initEdit() {
+ this.disableForEdit();
+ this.route.params.subscribe((params: { username: string }) => {
+ const username = params.username;
+ this.userService.get(username).subscribe((userFormModel: UserFormModel) => {
+ this.response = _.cloneDeep(userFormModel);
+ this.setResponse(userFormModel);
+
+ this.loadingReady();
+ });
+ });
+ }
+
+ disableForEdit() {
+ this.userForm.get('username').disable();
+ }
+
+ setResponse(response: UserFormModel) {
+ ['username', 'name', 'email', 'roles', 'enabled', 'pwdUpdateRequired'].forEach((key) =>
+ this.userForm.get(key).setValue(response[key])
+ );
+ const expirationDate = response['pwdExpirationDate'];
+ if (expirationDate) {
+ this.userForm
+ .get('pwdExpirationDate')
+ .setValue(moment(expirationDate * 1000).format(this.pwdExpirationFormat));
+ }
+ }
+
+ getRequest(): UserFormModel {
+ const userFormModel = new UserFormModel();
+ ['username', 'password', 'name', 'email', 'roles', 'enabled', 'pwdUpdateRequired'].forEach(
+ (key) => (userFormModel[key] = this.userForm.get(key).value)
+ );
+ const expirationDate = this.userForm.get('pwdExpirationDate').value;
+ if (expirationDate) {
+ const mom = moment(expirationDate, this.pwdExpirationFormat);
+ if (
+ this.mode !== this.userFormMode.editing ||
+ this.response.pwdExpirationDate !== mom.unix()
+ ) {
+ mom.set({ hour: 23, minute: 59, second: 59 });
+ }
+ userFormModel['pwdExpirationDate'] = mom.unix();
+ }
+ return userFormModel;
+ }
+
+ createAction() {
+ const userFormModel = this.getRequest();
+ this.userService.create(userFormModel).subscribe(
+ () => {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Created user '${userFormModel.username}'`
+ );
+ this.router.navigate(['/user-management/users']);
+ },
+ () => {
+ this.userForm.setErrors({ cdSubmitButton: true });
+ }
+ );
+ }
+
+ editAction() {
+ if (this.isUserRemovingNeededRolePermissions()) {
+ const initialState = {
+ titleText: $localize`Update user`,
+ buttonText: $localize`Continue`,
+ bodyTpl: this.removeSelfUserReadUpdatePermissionTpl,
+ onSubmit: () => {
+ this.modalRef.close();
+ this.doEditAction();
+ },
+ onCancel: () => {
+ this.userForm.setErrors({ cdSubmitButton: true });
+ this.userForm.get('roles').reset(this.userForm.get('roles').value);
+ }
+ };
+ this.modalRef = this.modalService.show(ConfirmationModalComponent, initialState);
+ } else {
+ this.doEditAction();
+ }
+ }
+
+ public isCurrentUser(): boolean {
+ return this.authStorageService.getUsername() === this.userForm.getValue('username');
+ }
+
+ private isUserChangingRoles(): boolean {
+ const isCurrentUser = this.isCurrentUser();
+ return (
+ isCurrentUser &&
+ this.response &&
+ !_.isEqual(this.response.roles, this.userForm.getValue('roles'))
+ );
+ }
+
+ private isUserRemovingNeededRolePermissions(): boolean {
+ const isCurrentUser = this.isCurrentUser();
+ return isCurrentUser && !this.hasUserReadUpdatePermissions(this.userForm.getValue('roles'));
+ }
+
+ private hasUserReadUpdatePermissions(roles: Array<string> = []) {
+ for (const role of this.allRoles) {
+ if (roles.indexOf(role.name) !== -1 && role.scopes_permissions['user']) {
+ const userPermissions = role.scopes_permissions['user'];
+ return ['read', 'update'].every((permission) => {
+ return userPermissions.indexOf(permission) !== -1;
+ });
+ }
+ }
+ return false;
+ }
+
+ private doEditAction() {
+ const userFormModel = this.getRequest();
+ this.userService.update(userFormModel).subscribe(
+ () => {
+ if (this.isUserChangingRoles()) {
+ this.authService.logout(() => {
+ this.notificationService.show(
+ NotificationType.info,
+ $localize`You were automatically logged out because your roles have been changed.`
+ );
+ });
+ } else {
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Updated user '${userFormModel.username}'`
+ );
+ this.router.navigate(['/user-management/users']);
+ }
+ },
+ () => {
+ this.userForm.setErrors({ cdSubmitButton: true });
+ }
+ );
+ }
+
+ clearExpirationDate() {
+ this.userForm.get('pwdExpirationDate').setValue(undefined);
+ }
+
+ submit() {
+ if (this.mode === this.userFormMode.editing) {
+ this.editAction();
+ } else {
+ this.createAction();
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.model.ts
new file mode 100644
index 000000000..2dc88ab5a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.model.ts
@@ -0,0 +1,10 @@
+export class UserFormModel {
+ username: string;
+ password: string;
+ pwdExpirationDate: number;
+ name: string;
+ email: string;
+ roles: Array<string>;
+ enabled: boolean;
+ pwdUpdateRequired: boolean;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.html
new file mode 100644
index 000000000..89ed21be8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.html
@@ -0,0 +1,22 @@
+<cd-user-tabs></cd-user-tabs>
+
+<cd-table [data]="users"
+ columnMode="flex"
+ [columns]="columns"
+ identifier="username"
+ selectionType="single"
+ (fetchData)="getUsers()"
+ (updateSelection)="updateSelection($event)">
+ <cd-table-actions class="table-actions"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+</cd-table>
+
+<ng-template #userRolesTpl
+ let-value="value">
+ <span *ngFor="let role of value; last as isLast">
+ {{ role }}{{ !isLast ? ", " : "" }}
+ </span>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.spec.ts
new file mode 100644
index 000000000..a1b9cfd14
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.spec.ts
@@ -0,0 +1,82 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+
+import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, PermissionHelper } from '~/testing/unit-test-helper';
+import { UserTabsComponent } from '../user-tabs/user-tabs.component';
+import { UserListComponent } from './user-list.component';
+
+describe('UserListComponent', () => {
+ let component: UserListComponent;
+ let fixture: ComponentFixture<UserListComponent>;
+
+ configureTestBed({
+ imports: [
+ BrowserAnimationsModule,
+ SharedModule,
+ ToastrModule.forRoot(),
+ NgbNavModule,
+ RouterTestingModule,
+ HttpClientTestingModule
+ ],
+ declarations: [UserListComponent, UserTabsComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(UserListComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+
+ it('should test all TableActions combinations', () => {
+ const permissionHelper: PermissionHelper = new PermissionHelper(component.permission);
+ const tableActions: TableActionsComponent = permissionHelper.setPermissionsAndGetActions(
+ component.tableActions
+ );
+
+ expect(tableActions).toEqual({
+ 'create,update,delete': {
+ actions: ['Create', 'Edit', 'Delete'],
+ primary: { multiple: 'Create', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,update': {
+ actions: ['Create', 'Edit'],
+ primary: { multiple: 'Create', executing: 'Edit', single: 'Edit', no: 'Create' }
+ },
+ 'create,delete': {
+ actions: ['Create', 'Delete'],
+ primary: { multiple: 'Create', executing: 'Delete', single: 'Delete', no: 'Create' }
+ },
+ create: {
+ actions: ['Create'],
+ primary: { multiple: 'Create', executing: 'Create', single: 'Create', no: 'Create' }
+ },
+ 'update,delete': {
+ actions: ['Edit', 'Delete'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ update: {
+ actions: ['Edit'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ delete: {
+ actions: ['Delete'],
+ primary: { multiple: 'Delete', executing: 'Delete', single: 'Delete', no: 'Delete' }
+ },
+ 'no-permissions': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ }
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.ts
new file mode 100644
index 000000000..09c0d82fc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.ts
@@ -0,0 +1,164 @@
+import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+
+import { UserService } from '~/app/shared/api/user.service';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { Permission } from '~/app/shared/models/permissions';
+import { CdDatePipe } from '~/app/shared/pipes/cd-date.pipe';
+import { EmptyPipe } from '~/app/shared/pipes/empty.pipe';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { URLBuilderService } from '~/app/shared/services/url-builder.service';
+
+const BASE_URL = 'user-management/users';
+
+@Component({
+ selector: 'cd-user-list',
+ templateUrl: './user-list.component.html',
+ styleUrls: ['./user-list.component.scss'],
+ providers: [{ provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }]
+})
+export class UserListComponent implements OnInit {
+ @ViewChild('userRolesTpl', { static: true })
+ userRolesTpl: TemplateRef<any>;
+
+ permission: Permission;
+ tableActions: CdTableAction[];
+ columns: CdTableColumn[];
+ users: Array<any>;
+ selection = new CdTableSelection();
+
+ modalRef: NgbModalRef;
+
+ constructor(
+ private userService: UserService,
+ private emptyPipe: EmptyPipe,
+ private modalService: ModalService,
+ private notificationService: NotificationService,
+ private authStorageService: AuthStorageService,
+ private urlBuilder: URLBuilderService,
+ private cdDatePipe: CdDatePipe,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ this.permission = this.authStorageService.getPermissions().user;
+ const addAction: CdTableAction = {
+ permission: 'create',
+ icon: Icons.add,
+ routerLink: () => this.urlBuilder.getCreate(),
+ name: this.actionLabels.CREATE
+ };
+ const editAction: CdTableAction = {
+ permission: 'update',
+ icon: Icons.edit,
+ routerLink: () =>
+ this.selection.first() && this.urlBuilder.getEdit(this.selection.first().username),
+ name: this.actionLabels.EDIT
+ };
+ const deleteAction: CdTableAction = {
+ permission: 'delete',
+ icon: Icons.destroy,
+ click: () => this.deleteUserModal(),
+ name: this.actionLabels.DELETE
+ };
+ this.tableActions = [addAction, editAction, deleteAction];
+ }
+
+ ngOnInit() {
+ this.columns = [
+ {
+ name: $localize`Username`,
+ prop: 'username',
+ flexGrow: 1
+ },
+ {
+ name: $localize`Name`,
+ prop: 'name',
+ flexGrow: 1,
+ pipe: this.emptyPipe
+ },
+ {
+ name: $localize`Email`,
+ prop: 'email',
+ flexGrow: 1,
+ pipe: this.emptyPipe
+ },
+ {
+ name: $localize`Roles`,
+ prop: 'roles',
+ flexGrow: 1,
+ cellTemplate: this.userRolesTpl
+ },
+ {
+ name: $localize`Enabled`,
+ prop: 'enabled',
+ flexGrow: 1,
+ cellTransformation: CellTemplate.checkIcon
+ },
+ {
+ name: $localize`Password expiration date`,
+ prop: 'pwdExpirationDate',
+ flexGrow: 1,
+ pipe: this.cdDatePipe
+ }
+ ];
+ }
+
+ getUsers() {
+ this.userService.list().subscribe((users: Array<any>) => {
+ users.forEach((user) => {
+ if (user['pwdExpirationDate'] && user['pwdExpirationDate'] > 0) {
+ user['pwdExpirationDate'] = user['pwdExpirationDate'] * 1000;
+ }
+ });
+ this.users = users;
+ });
+ }
+
+ updateSelection(selection: CdTableSelection) {
+ this.selection = selection;
+ }
+
+ deleteUser(username: string) {
+ this.userService.delete(username).subscribe(
+ () => {
+ this.getUsers();
+ this.modalRef.close();
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Deleted user '${username}'`
+ );
+ },
+ () => {
+ this.modalRef.componentInstance.stopLoadingSpinner();
+ }
+ );
+ }
+
+ deleteUserModal() {
+ const sessionUsername = this.authStorageService.getUsername();
+ const username = this.selection.first().username;
+ if (sessionUsername === username) {
+ this.notificationService.show(
+ NotificationType.error,
+ $localize`Failed to delete user '${username}'`,
+ $localize`You are currently logged in as '${username}'.`
+ );
+ return;
+ }
+
+ this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ itemDescription: 'User',
+ itemNames: [username],
+ submitAction: () => this.deleteUser(username)
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-password-form/user-password-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-password-form/user-password-form.component.html
new file mode 100644
index 000000000..83eb40944
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-password-form/user-password-form.component.html
@@ -0,0 +1,121 @@
+<div class="cd-col-form">
+ <form #frm="ngForm"
+ [formGroup]="userForm"
+ novalidate>
+ <div class="card">
+ <div i18n="form title"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
+
+ <div class="card-body">
+ <!-- Old password -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="oldpassword"
+ i18n>Old password</label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input class="form-control"
+ type="password"
+ placeholder="Old password..."
+ id="oldpassword"
+ formControlName="oldpassword"
+ autocomplete="new-password"
+ autofocus>
+ <span class="input-group-append">
+ <button class="btn btn-light"
+ cdPasswordButton="oldpassword">
+ </button>
+ </span>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('oldpassword', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('oldpassword', frm, 'notmatch')"
+ i18n>The old and new passwords must be different.</span>
+ </div>
+ </div>
+
+ <!-- New password -->
+ <div class="form-group row">
+ <label class="cd-col-form-label"
+ for="newpassword">
+ <span class="required"
+ i18n>New password</span>
+ <cd-helper *ngIf="passwordPolicyHelpText.length > 0"
+ class="text-pre-wrap"
+ html="{{ passwordPolicyHelpText }}">
+ </cd-helper>
+ </label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input class="form-control"
+ type="password"
+ placeholder="Password..."
+ id="newpassword"
+ autocomplete="new-password"
+ formControlName="newpassword">
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="newpassword">
+ </button>
+ </span>
+ </div>
+ <div class="password-strength-level">
+ <div class="{{ passwordStrengthLevelClass }}"
+ data-toggle="tooltip"
+ title="{{ passwordValuation }}">
+ </div>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('newpassword', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('newpassword', frm, 'notmatch')"
+ i18n>The old and new passwords must be different.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('newpassword', frm, 'passwordPolicy')">
+ {{ passwordValuation }}
+ </span>
+ </div>
+ </div>
+
+ <!-- Confirm new password -->
+ <div class="form-group row">
+ <label class="cd-col-form-label required"
+ for="confirmnewpassword"
+ i18n>Confirm new password</label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input class="form-control"
+ type="password"
+ autocomplete="new-password"
+ placeholder="Confirm new password..."
+ id="confirmnewpassword"
+ formControlName="confirmnewpassword">
+ <span class="input-group-append">
+ <button class="btn btn-light"
+ cdPasswordButton="confirmnewpassword">
+ </button>
+ </span>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('confirmnewpassword', frm, 'required')"
+ i18n>This field is required.</span>
+ <span class="invalid-feedback"
+ *ngIf="userForm.showError('confirmnewpassword', frm, 'match')"
+ i18n>Password confirmation doesn't match the new password.</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="card-footer">
+ <cd-form-button-panel (submitActionEvent)="onSubmit()"
+ [form]="userForm"
+ [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
+ wrappingClass="text-right"></cd-form-button-panel>
+ </div>
+ </div>
+ </form>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-password-form/user-password-form.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-password-form/user-password-form.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-password-form/user-password-form.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-password-form/user-password-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-password-form/user-password-form.component.spec.ts
new file mode 100644
index 000000000..b1df8cf42
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-password-form/user-password-form.component.spec.ts
@@ -0,0 +1,83 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { Router } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+
+import { ComponentsModule } from '~/app/shared/components/components.module';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
+import { UserPasswordFormComponent } from './user-password-form.component';
+
+describe('UserPasswordFormComponent', () => {
+ let component: UserPasswordFormComponent;
+ let fixture: ComponentFixture<UserPasswordFormComponent>;
+ let form: CdFormGroup;
+ let formHelper: FormHelper;
+ let httpTesting: HttpTestingController;
+ let router: Router;
+ let authStorageService: AuthStorageService;
+
+ configureTestBed({
+ imports: [
+ HttpClientTestingModule,
+ RouterTestingModule,
+ ReactiveFormsModule,
+ ComponentsModule,
+ ToastrModule.forRoot(),
+ SharedModule
+ ],
+ declarations: [UserPasswordFormComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(UserPasswordFormComponent);
+ component = fixture.componentInstance;
+ form = component.userForm;
+ httpTesting = TestBed.inject(HttpTestingController);
+ router = TestBed.inject(Router);
+ authStorageService = TestBed.inject(AuthStorageService);
+ spyOn(router, 'navigate');
+ fixture.detectChanges();
+ formHelper = new FormHelper(form);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should validate old password required', () => {
+ formHelper.expectErrorChange('oldpassword', '', 'required');
+ formHelper.expectValidChange('oldpassword', 'foo');
+ });
+
+ it('should validate password match', () => {
+ formHelper.setValue('newpassword', 'aaa');
+ formHelper.expectErrorChange('confirmnewpassword', 'bbb', 'match');
+ formHelper.expectValidChange('confirmnewpassword', 'aaa');
+ });
+
+ it('should submit', () => {
+ spyOn(component, 'onPasswordChange').and.callThrough();
+ spyOn(authStorageService, 'getUsername').and.returnValue('xyz');
+ formHelper.setMultipleValues({
+ oldpassword: 'foo',
+ newpassword: 'bar'
+ });
+ formHelper.setValue('confirmnewpassword', 'bar', true);
+ component.onSubmit();
+ const request = httpTesting.expectOne('api/user/xyz/change_password');
+ expect(request.request.method).toBe('POST');
+ expect(request.request.body).toEqual({
+ old_password: 'foo',
+ new_password: 'bar'
+ });
+ request.flush({});
+ expect(component.onPasswordChange).toHaveBeenCalled();
+ expect(router.navigate).toHaveBeenCalledWith(['/login']);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-password-form/user-password-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-password-form/user-password-form.component.ts
new file mode 100644
index 000000000..dffb927ac
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-password-form/user-password-form.component.ts
@@ -0,0 +1,119 @@
+import { Component } from '@angular/core';
+import { Validators } from '@angular/forms';
+import { Router } from '@angular/router';
+
+import _ from 'lodash';
+
+import { UserService } from '~/app/shared/api/user.service';
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { PasswordPolicyService } from '~/app/shared/services/password-policy.service';
+
+@Component({
+ selector: 'cd-user-password-form',
+ templateUrl: './user-password-form.component.html',
+ styleUrls: ['./user-password-form.component.scss']
+})
+export class UserPasswordFormComponent {
+ userForm: CdFormGroup;
+ action: string;
+ resource: string;
+ passwordPolicyHelpText = '';
+ passwordStrengthLevelClass: string;
+ passwordValuation: string;
+ icons = Icons;
+
+ constructor(
+ public actionLabels: ActionLabelsI18n,
+ public notificationService: NotificationService,
+ public userService: UserService,
+ public authStorageService: AuthStorageService,
+ public formBuilder: CdFormBuilder,
+ public router: Router,
+ public passwordPolicyService: PasswordPolicyService
+ ) {
+ this.action = this.actionLabels.CHANGE;
+ this.resource = $localize`password`;
+ this.createForm();
+ }
+
+ createForm() {
+ this.passwordPolicyService.getHelpText().subscribe((helpText: string) => {
+ this.passwordPolicyHelpText = helpText;
+ });
+ this.userForm = this.formBuilder.group(
+ {
+ oldpassword: [
+ null,
+ [
+ Validators.required,
+ CdValidators.custom('notmatch', () => {
+ return (
+ this.userForm &&
+ this.userForm.getValue('newpassword') === this.userForm.getValue('oldpassword')
+ );
+ })
+ ]
+ ],
+ newpassword: [
+ null,
+ [
+ Validators.required,
+ CdValidators.custom('notmatch', () => {
+ return (
+ this.userForm &&
+ this.userForm.getValue('oldpassword') === this.userForm.getValue('newpassword')
+ );
+ })
+ ],
+ [
+ CdValidators.passwordPolicy(
+ this.userService,
+ () => this.authStorageService.getUsername(),
+ (_valid: boolean, credits: number, valuation: string) => {
+ this.passwordStrengthLevelClass = this.passwordPolicyService.mapCreditsToCssClass(
+ credits
+ );
+ this.passwordValuation = _.defaultTo(valuation, '');
+ }
+ )
+ ]
+ ],
+ confirmnewpassword: [null, [Validators.required]]
+ },
+ {
+ validators: [CdValidators.match('newpassword', 'confirmnewpassword')]
+ }
+ );
+ }
+
+ onSubmit() {
+ if (this.userForm.pristine) {
+ return;
+ }
+ const username = this.authStorageService.getUsername();
+ const oldPassword = this.userForm.getValue('oldpassword');
+ const newPassword = this.userForm.getValue('newpassword');
+ this.userService.changePassword(username, oldPassword, newPassword).subscribe(
+ () => this.onPasswordChange(),
+ () => {
+ this.userForm.setErrors({ cdSubmitButton: true });
+ }
+ );
+ }
+
+ /**
+ * The function that is called after the password has been changed.
+ * Override this in derived classes to change the behaviour.
+ */
+ onPasswordChange() {
+ this.notificationService.show(NotificationType.success, $localize`Updated user password"`);
+ this.router.navigate(['/login']);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.html
new file mode 100644
index 000000000..3c102cf66
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.html
@@ -0,0 +1,14 @@
+<ul ngbNav
+ #nav="ngbNav"
+ [activeId]="router.url"
+ (navChange)="router.navigate([$event.nextId])"
+ class="nav-tabs">
+ <li ngbNavItem="/user-management/users">
+ <a ngbNavLink
+ i18n>Users</a>
+ </li>
+ <li ngbNavItem="/user-management/roles">
+ <a ngbNavLink
+ i18n>Roles</a>
+ </li>
+</ul>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.spec.ts
new file mode 100644
index 000000000..f9b8081db
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.spec.ts
@@ -0,0 +1,29 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { UserTabsComponent } from './user-tabs.component';
+
+describe('UserTabsComponent', () => {
+ let component: UserTabsComponent;
+ let fixture: ComponentFixture<UserTabsComponent>;
+
+ configureTestBed({
+ imports: [SharedModule, RouterTestingModule, HttpClientTestingModule, NgbNavModule],
+ declarations: [UserTabsComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(UserTabsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.ts
new file mode 100644
index 000000000..06626ec3e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.ts
@@ -0,0 +1,13 @@
+import { Component } from '@angular/core';
+import { Router } from '@angular/router';
+
+@Component({
+ selector: 'cd-user-tabs',
+ templateUrl: './user-tabs.component.html',
+ styleUrls: ['./user-tabs.component.scss']
+})
+export class UserTabsComponent {
+ url: string;
+
+ constructor(public router: Router) {}
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/context/context.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/context/context.component.html
new file mode 100644
index 000000000..63af29e13
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/context/context.component.html
@@ -0,0 +1,27 @@
+<ng-container *ngIf="{ ftMap: featureToggleMap$ | async, daemons: rgwDaemonService.daemons$ | async, selectedDaemon: rgwDaemonService.selectedDaemon$ | async } as data">
+ <ng-container *ngIf="data.ftMap && data.ftMap.rgw && permissions.rgw.read && isRgwRoute && data.daemons.length > 1">
+ <div class="cd-context-bar pt-3 pb-3">
+ <span class="mr-1"
+ i18n>Selected Object Gateway:</span>
+ <div ngbDropdown
+ placement="bottom-left"
+ class="d-inline-block ml-2">
+ <button ngbDropdownToggle
+ class="btn btn-outline-info ctx-bar-selected-rgw-daemon"
+ i18n-title
+ title="Select Object Gateway">
+ {{ data.selectedDaemon.id }} ( {{ data.selectedDaemon.zonegroup_name }} )
+ </button>
+ <div ngbDropdownMenu>
+ <ng-container *ngFor="let daemon of data.daemons">
+ <button ngbDropdownItem
+ class="ctx-bar-available-rgw-daemon"
+ (click)="onDaemonSelection(daemon)">
+ {{ daemon.id }} ( {{ daemon.zonegroup_name }} )
+ </button>
+ </ng-container>
+ </div>
+ </div>
+ </div>
+ </ng-container>
+</ng-container>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/context/context.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/context/context.component.scss
new file mode 100644
index 000000000..0cd44f150
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/context/context.component.scss
@@ -0,0 +1,5 @@
+@use './src/styles/vendor/variables' as vv;
+
+.cd-context-bar {
+ border-bottom: 1px solid vv.$gray-300;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/context/context.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/context/context.component.spec.ts
new file mode 100644
index 000000000..9512e3183
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/context/context.component.spec.ts
@@ -0,0 +1,100 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { Router } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { of } from 'rxjs';
+
+import { Permissions } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import {
+ FeatureTogglesMap,
+ FeatureTogglesService
+} from '~/app/shared/services/feature-toggles.service';
+import { configureTestBed, RgwHelper } from '~/testing/unit-test-helper';
+import { ContextComponent } from './context.component';
+
+describe('ContextComponent', () => {
+ let component: ContextComponent;
+ let fixture: ComponentFixture<ContextComponent>;
+ let router: Router;
+ let routerNavigateByUrlSpy: jasmine.Spy;
+ let routerNavigateSpy: jasmine.Spy;
+ let getPermissionsSpy: jasmine.Spy;
+ let getFeatureTogglesSpy: jasmine.Spy;
+ let ftMap: FeatureTogglesMap;
+ let httpTesting: HttpTestingController;
+
+ const daemonList = RgwHelper.getDaemonList();
+
+ configureTestBed({
+ declarations: [ContextComponent],
+ imports: [HttpClientTestingModule, RouterTestingModule]
+ });
+
+ beforeEach(() => {
+ httpTesting = TestBed.inject(HttpTestingController);
+ router = TestBed.inject(Router);
+ routerNavigateByUrlSpy = spyOn(router, 'navigateByUrl');
+ routerNavigateByUrlSpy.and.returnValue(Promise.resolve(undefined));
+ routerNavigateSpy = spyOn(router, 'navigate');
+ getPermissionsSpy = spyOn(TestBed.inject(AuthStorageService), 'getPermissions');
+ getPermissionsSpy.and.returnValue(
+ new Permissions({ rgw: ['read', 'update', 'create', 'delete'] })
+ );
+ getFeatureTogglesSpy = spyOn(TestBed.inject(FeatureTogglesService), 'get');
+ ftMap = new FeatureTogglesMap();
+ ftMap.rgw = true;
+ getFeatureTogglesSpy.and.returnValue(of(ftMap));
+ fixture = TestBed.createComponent(ContextComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should not show any info if not in RGW route', () => {
+ component.isRgwRoute = false;
+ expect(fixture.debugElement.nativeElement.textContent).toEqual('');
+ });
+
+ it('should select the default daemon', fakeAsync(() => {
+ component.isRgwRoute = true;
+ fixture.detectChanges();
+ tick();
+ const req = httpTesting.expectOne('api/rgw/daemon');
+ req.flush(daemonList);
+ fixture.detectChanges();
+ const selectedDaemon = fixture.debugElement.nativeElement.querySelector(
+ '.ctx-bar-selected-rgw-daemon'
+ );
+ expect(selectedDaemon.textContent).toEqual(' daemon2 ( zonegroup2 ) ');
+
+ const availableDaemons = fixture.debugElement.nativeElement.querySelectorAll(
+ '.ctx-bar-available-rgw-daemon'
+ );
+ expect(availableDaemons.length).toEqual(daemonList.length);
+ expect(availableDaemons[0].textContent).toEqual(' daemon1 ( zonegroup1 ) ');
+ component.ngOnDestroy();
+ }));
+
+ it('should select the chosen daemon', fakeAsync(() => {
+ component.isRgwRoute = true;
+ fixture.detectChanges();
+ tick();
+ const req = httpTesting.expectOne('api/rgw/daemon');
+ req.flush(daemonList);
+ fixture.detectChanges();
+ component.onDaemonSelection(daemonList[2]);
+ expect(routerNavigateByUrlSpy).toHaveBeenCalledTimes(1);
+ fixture.detectChanges();
+ tick();
+ expect(routerNavigateSpy).toHaveBeenCalledTimes(1);
+ const selectedDaemon = fixture.debugElement.nativeElement.querySelector(
+ '.ctx-bar-selected-rgw-daemon'
+ );
+ expect(selectedDaemon.textContent).toEqual(' daemon3 ( zonegroup3 ) ');
+ component.ngOnDestroy();
+ }));
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/context/context.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/context/context.component.ts
new file mode 100644
index 000000000..8de611307
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/context/context.component.ts
@@ -0,0 +1,70 @@
+import { Component, OnDestroy, OnInit } from '@angular/core';
+import { Event, NavigationEnd, Router } from '@angular/router';
+
+import { NEVER, Subscription } from 'rxjs';
+import { filter } from 'rxjs/operators';
+
+import { RgwDaemon } from '~/app/ceph/rgw/models/rgw-daemon';
+import { RgwDaemonService } from '~/app/shared/api/rgw-daemon.service';
+import { Permissions } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import {
+ FeatureTogglesMap$,
+ FeatureTogglesService
+} from '~/app/shared/services/feature-toggles.service';
+import { TimerService } from '~/app/shared/services/timer.service';
+
+@Component({
+ selector: 'cd-context',
+ templateUrl: './context.component.html',
+ styleUrls: ['./context.component.scss']
+})
+export class ContextComponent implements OnInit, OnDestroy {
+ readonly REFRESH_INTERVAL = 5000;
+ private subs = new Subscription();
+ private rgwUrlPrefix = '/rgw';
+ permissions: Permissions;
+ featureToggleMap$: FeatureTogglesMap$;
+ isRgwRoute = document.location.href.includes(this.rgwUrlPrefix);
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private featureToggles: FeatureTogglesService,
+ private router: Router,
+ private timerService: TimerService,
+ public rgwDaemonService: RgwDaemonService
+ ) {}
+
+ ngOnInit() {
+ this.permissions = this.authStorageService.getPermissions();
+ this.featureToggleMap$ = this.featureToggles.get();
+ // Check if route belongs to RGW:
+ this.subs.add(
+ this.router.events
+ .pipe(filter((event: Event) => event instanceof NavigationEnd))
+ .subscribe(() => (this.isRgwRoute = this.router.url.startsWith(this.rgwUrlPrefix)))
+ );
+ // Set daemon list polling only when in RGW route:
+ this.subs.add(
+ this.timerService
+ .get(() => (this.isRgwRoute ? this.rgwDaemonService.list() : NEVER), this.REFRESH_INTERVAL)
+ .subscribe()
+ );
+ }
+
+ ngOnDestroy() {
+ this.subs.unsubscribe();
+ }
+
+ onDaemonSelection(daemon: RgwDaemon) {
+ this.rgwDaemonService.selectDaemon(daemon);
+ this.reloadData();
+ }
+
+ private reloadData() {
+ const currentUrl = this.router.url;
+ this.router.navigateByUrl(this.rgwUrlPrefix, { skipLocationChange: true }).finally(() => {
+ this.router.navigate([currentUrl]);
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/core.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/core.module.ts
new file mode 100644
index 000000000..005c82778
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/core.module.ts
@@ -0,0 +1,34 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { RouterModule } from '@angular/router';
+
+import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
+import { BlockUIModule } from 'ng-block-ui';
+
+import { ContextComponent } from '~/app/core/context/context.component';
+import { SharedModule } from '~/app/shared/shared.module';
+import { ErrorComponent } from './error/error.component';
+import { BlankLayoutComponent } from './layouts/blank-layout/blank-layout.component';
+import { LoginLayoutComponent } from './layouts/login-layout/login-layout.component';
+import { WorkbenchLayoutComponent } from './layouts/workbench-layout/workbench-layout.component';
+import { NavigationModule } from './navigation/navigation.module';
+
+@NgModule({
+ imports: [
+ BlockUIModule.forRoot(),
+ CommonModule,
+ NavigationModule,
+ NgbDropdownModule,
+ RouterModule,
+ SharedModule
+ ],
+ exports: [NavigationModule],
+ declarations: [
+ ContextComponent,
+ WorkbenchLayoutComponent,
+ BlankLayoutComponent,
+ LoginLayoutComponent,
+ ErrorComponent
+ ]
+})
+export class CoreModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.html
new file mode 100644
index 000000000..164c181da
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.html
@@ -0,0 +1,63 @@
+<head>
+ <title>Error Page</title>
+ <base target="_blank">
+</head>
+<div class="container h-75">
+ <div class="row h-100 justify-content-center align-items-center">
+ <div class="blank-page">
+ <div *ngIf="header && message; else elseBlock">
+ <i [ngClass]="icon"
+ class="mx-auto d-block"></i>
+
+ <div class="mt-4 text-center">
+ <h3><b>{{ header }}</b></h3>
+ <h4 class="mt-3"
+ *ngIf="header !== message">{{ message }}</h4>
+ <h4 *ngIf="section"
+ i18n>Please consult the <a href="{{ docUrl }}">documentation</a> on how to configure and enable
+ the {{ sectionInfo }} management functionality.
+ </h4>
+ </div>
+ </div>
+
+ <div class="mt-4">
+ <div class="text-center"
+ *ngIf="(buttonName && buttonRoute) || uiConfig; else dashboardButton">
+ <button class="btn btn-primary"
+ [routerLink]="buttonRoute"
+ *ngIf="!uiConfig; else configureButtonTpl"
+ i18n>{{ buttonName }}</button>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
+<ng-template #configureButtonTpl>
+ <button class="btn btn-primary"
+ (click)="doConfigure()"
+ [attr.title]="buttonTitle"
+ *ngIf="uiConfig"
+ i18n>{{ buttonName }}</button>
+</ng-template>
+
+
+<ng-template #elseBlock>
+ <i class="fa fa-exclamation-triangle mx-auto d-block text-danger"></i>
+
+ <div class="mt-4 text-center">
+ <h3 i18n><b>Page not Found</b></h3>
+
+ <h4 class="mt-4"
+ i18n>Sorry, we couldn’t find what you were looking for.
+ The page you requested may have been changed or moved.</h4>
+ </div>
+</ng-template>
+
+<ng-template #dashboardButton>
+ <div class="mt-4 text-center">
+ <button class="btn btn-primary"
+ [routerLink]="'/dashboard'"
+ i18n>Go To Dashboard</button>
+ </div>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.scss
new file mode 100644
index 000000000..feb4e0f95
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.scss
@@ -0,0 +1,18 @@
+@use './src/styles/vendor/variables' as vv;
+
+h4 {
+ color: vv.$gray-700;
+}
+
+i {
+ font-size: 6em;
+ margin-top: 120px;
+}
+
+.fa-lock {
+ color: vv.$danger;
+}
+
+.fa-wrench {
+ color: vv.$info;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.spec.ts
new file mode 100644
index 000000000..5763d4d97
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.spec.ts
@@ -0,0 +1,49 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { ErrorComponent } from './error.component';
+
+describe('ErrorComponent', () => {
+ let component: ErrorComponent;
+ let fixture: ComponentFixture<ErrorComponent>;
+
+ configureTestBed({
+ declarations: [ErrorComponent],
+ imports: [HttpClientTestingModule, RouterTestingModule, SharedModule, ToastrModule.forRoot()]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ErrorComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should show error message and header', () => {
+ window.history.pushState({ message: 'Access Forbidden', header: 'User Denied' }, 'Errors');
+ component.fetchData();
+ fixture.detectChanges();
+ const header = fixture.debugElement.nativeElement.querySelector('h3');
+ expect(header.innerHTML).toContain('User Denied');
+ const message = fixture.debugElement.nativeElement.querySelector('h4');
+ expect(message.innerHTML).toContain('Access Forbidden');
+ });
+
+ it('should show 404 Page not Found if message and header are blank', () => {
+ window.history.pushState({ message: '', header: '' }, 'Errors');
+ component.fetchData();
+ fixture.detectChanges();
+ const header = fixture.debugElement.nativeElement.querySelector('h3');
+ expect(header.innerHTML).toContain('Page not Found');
+ const message = fixture.debugElement.nativeElement.querySelector('h4');
+ expect(message.innerHTML).toContain('Sorry, we couldn’t find what you were looking for.');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.ts
new file mode 100644
index 000000000..d26bc6db4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.ts
@@ -0,0 +1,96 @@
+import { HttpClient } from '@angular/common/http';
+import { Component, HostListener, OnDestroy, OnInit } from '@angular/core';
+import { NavigationEnd, Router, RouterEvent } from '@angular/router';
+
+import { Subscription } from 'rxjs';
+import { filter } from 'rxjs/operators';
+
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { DocService } from '~/app/shared/services/doc.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+
+@Component({
+ selector: 'cd-error',
+ templateUrl: './error.component.html',
+ styleUrls: ['./error.component.scss']
+})
+export class ErrorComponent implements OnDestroy, OnInit {
+ header: string;
+ message: string;
+ section: string;
+ sectionInfo: string;
+ icon: string;
+ docUrl: string;
+ source: string;
+ routerSubscription: Subscription;
+ uiConfig: string;
+ uiApiPath: string;
+ buttonRoute: string;
+ buttonName: string;
+ buttonTitle: string;
+ component: string;
+
+ constructor(
+ private router: Router,
+ private docService: DocService,
+ private http: HttpClient,
+ private notificationService: NotificationService
+ ) {}
+
+ ngOnInit() {
+ this.fetchData();
+ this.routerSubscription = this.router.events
+ .pipe(filter((event: RouterEvent) => event instanceof NavigationEnd))
+ .subscribe(() => {
+ this.fetchData();
+ });
+ }
+
+ doConfigure() {
+ this.http.post(`ui-api/${this.uiApiPath}/configure`, {}).subscribe({
+ next: () => {
+ this.notificationService.show(NotificationType.info, `Configuring ${this.component}`);
+ },
+ error: (error: any) => {
+ this.notificationService.show(NotificationType.error, error);
+ },
+ complete: () => {
+ setTimeout(() => {
+ this.router.navigate([this.uiApiPath]);
+ this.notificationService.show(NotificationType.success, `Configured ${this.component}`);
+ }, 3000);
+ }
+ });
+ }
+
+ @HostListener('window:beforeunload', ['$event']) unloadHandler(event: Event) {
+ event.returnValue = false;
+ }
+
+ fetchData() {
+ try {
+ this.router.onSameUrlNavigation = 'reload';
+ this.message = history.state.message;
+ this.header = history.state.header;
+ this.section = history.state.section;
+ this.sectionInfo = history.state.section_info;
+ this.icon = history.state.icon;
+ this.source = history.state.source;
+ this.uiConfig = history.state.uiConfig;
+ this.uiApiPath = history.state.uiApiPath;
+ this.buttonRoute = history.state.button_route;
+ this.buttonName = history.state.button_name;
+ this.buttonTitle = history.state.button_title;
+ this.component = history.state.component;
+ this.docUrl = this.docService.urlGenerator(this.section);
+ } catch (error) {
+ this.router.navigate(['/error']);
+ }
+ }
+
+ ngOnDestroy() {
+ if (this.routerSubscription) {
+ this.routerSubscription.unsubscribe();
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.ts
new file mode 100644
index 000000000..0270a4587
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.ts
@@ -0,0 +1,27 @@
+import { Icons } from '~/app/shared/enum/icons.enum';
+
+export class DashboardError extends Error {
+ header: string;
+ message: string;
+ icon: string;
+}
+
+export class DashboardNotFoundError extends DashboardError {
+ header = $localize`Page Not Found`;
+ message = $localize`Sorry, we couldn’t find what you were looking for.
+ The page you requested may have been changed or moved.`;
+ icon = Icons.warning;
+}
+
+export class DashboardForbiddenError extends DashboardError {
+ header = $localize`Access Denied`;
+ message = $localize`Sorry, you don’t have permission to view this page or resource.`;
+ icon = Icons.lock;
+}
+
+export class DashboardUserDeniedError extends DashboardError {
+ header = $localize`User Denied`;
+ message = $localize`Sorry, the user does not exist in Ceph.
+ You'll be logged out from the Identity Provider when you retry logging in.`;
+ icon = Icons.warning;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/blank-layout/blank-layout.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/blank-layout/blank-layout.component.html
new file mode 100644
index 000000000..0680b43f9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/blank-layout/blank-layout.component.html
@@ -0,0 +1 @@
+<router-outlet></router-outlet>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/blank-layout/blank-layout.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/blank-layout/blank-layout.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/blank-layout/blank-layout.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/blank-layout/blank-layout.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/blank-layout/blank-layout.component.spec.ts
new file mode 100644
index 000000000..faee6aa9b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/blank-layout/blank-layout.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { BlankLayoutComponent } from './blank-layout.component';
+
+describe('DefaultLayoutComponent', () => {
+ let component: BlankLayoutComponent;
+ let fixture: ComponentFixture<BlankLayoutComponent>;
+
+ configureTestBed({
+ declarations: [BlankLayoutComponent],
+ imports: [RouterTestingModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(BlankLayoutComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/blank-layout/blank-layout.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/blank-layout/blank-layout.component.ts
new file mode 100644
index 000000000..761bb3b87
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/blank-layout/blank-layout.component.ts
@@ -0,0 +1,8 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'cd-blank-layout',
+ templateUrl: './blank-layout.component.html',
+ styleUrls: ['./blank-layout.component.scss']
+})
+export class BlankLayoutComponent {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.html
new file mode 100644
index 000000000..1222fcc2a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.html
@@ -0,0 +1,34 @@
+<main class="login full-height">
+ <header>
+ <nav class="navbar p-4">
+ <a class="navbar-brand"></a>
+ <div class="form-inline">
+ <cd-language-selector></cd-language-selector>
+ </div>
+ </nav>
+ </header>
+ <section>
+ <div class="container">
+ <div class="row full-height">
+ <div class="col-sm-12 col-md-6 d-sm-block login-form">
+ <router-outlet></router-outlet>
+ </div>
+ <div class="col-sm-12 col-md-6 d-sm-block branding-info">
+ <img src="assets/Ceph_Ceph_Logo_with_text_white.svg"
+ alt="Ceph"
+ class="img-fluid pb-3">
+ <ul class="list-inline">
+ <li class="list-inline-item p-3"
+ *ngFor="let docItem of docItems">
+ <cd-doc section="{{ docItem.section }}"
+ docText="{{ docItem.text }}"
+ noSubscribe="true"
+ i18n-docText></cd-doc>
+ </li>
+ </ul>
+ <cd-custom-login-banner></cd-custom-login-banner>
+ </div>
+ </div>
+ </div>
+ </section>
+</main>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.scss
new file mode 100644
index 000000000..d5c9f73ec
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.scss
@@ -0,0 +1,61 @@
+@use './src/styles/vendor/variables' as vv;
+
+::ng-deep cd-login-layout .login {
+ background-color: vv.$secondary;
+ background-image: url('../../../../assets/ceph_background.gif');
+ background-position: right bottom;
+ background-repeat: no-repeat;
+ color: vv.$body-color-bright;
+
+ header {
+ position: absolute;
+ width: 100vw;
+
+ .navbar {
+ .dropdown-menu {
+ margin-top: 0.2rem;
+
+ li a {
+ &:hover {
+ background-color: vv.$primary;
+ }
+ }
+ }
+ }
+ }
+
+ section {
+ display: inline-flex;
+ min-height: 100vh;
+ width: 100vw;
+ }
+
+ .list-inline {
+ margin-bottom: 0;
+ margin-left: 20%;
+ }
+
+ a {
+ color: vv.$fg-color-over-dark-bg;
+
+ &:hover {
+ color: vv.$fg-hover-color-over-dark-bg;
+ }
+ }
+
+ @media screen and (min-width: vv.$screen-sm-min) {
+ .login-form,
+ .branding-info {
+ padding-top: 30vh;
+ }
+ }
+ @media screen and (max-width: vv.$screen-sm-max) {
+ .login-form {
+ padding-top: 10vh;
+ }
+
+ .branding-info {
+ padding-top: 0;
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.spec.ts
new file mode 100644
index 000000000..b57e9a36e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.spec.ts
@@ -0,0 +1,28 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { LoginLayoutComponent } from './login-layout.component';
+
+describe('LoginLayoutComponent', () => {
+ let component: LoginLayoutComponent;
+ let fixture: ComponentFixture<LoginLayoutComponent>;
+
+ configureTestBed({
+ declarations: [LoginLayoutComponent],
+ imports: [BrowserAnimationsModule, HttpClientTestingModule, RouterTestingModule, SharedModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(LoginLayoutComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.ts
new file mode 100644
index 000000000..69d591cd1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.ts
@@ -0,0 +1,14 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'cd-login-layout',
+ templateUrl: './login-layout.component.html',
+ styleUrls: ['./login-layout.component.scss']
+})
+export class LoginLayoutComponent {
+ docItems: any[] = [
+ { section: 'help', text: $localize`Help` },
+ { section: 'security', text: $localize`Security` },
+ { section: 'trademarks', text: $localize`Trademarks` }
+ ];
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.html
new file mode 100644
index 000000000..3979ad7a4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.html
@@ -0,0 +1,10 @@
+<block-ui>
+ <cd-navigation>
+ <div class="container-fluid h-100"
+ [ngClass]="{'dashboard':isDashboardPage()} ">
+ <cd-context></cd-context>
+ <cd-breadcrumbs></cd-breadcrumbs>
+ <router-outlet></router-outlet>
+ </div>
+ </cd-navigation>
+</block-ui>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.scss
new file mode 100644
index 000000000..7ec90d43e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.scss
@@ -0,0 +1,12 @@
+@use './src/styles/vendor/variables' as vv;
+
+.dashboard {
+ background-color: vv.$body-bg-alt;
+ margin: 0;
+ padding: 0;
+}
+
+.container-fluid {
+ overflow: auto;
+ position: absolute;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.spec.ts
new file mode 100644
index 000000000..faf8c9cdf
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.spec.ts
@@ -0,0 +1,35 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { CssHelper } from '~/app/shared/classes/css-helper';
+import { PipesModule } from '~/app/shared/pipes/pipes.module';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { WorkbenchLayoutComponent } from './workbench-layout.component';
+
+describe('WorkbenchLayoutComponent', () => {
+ let component: WorkbenchLayoutComponent;
+ let fixture: ComponentFixture<WorkbenchLayoutComponent>;
+
+ configureTestBed({
+ imports: [RouterTestingModule, ToastrModule.forRoot(), PipesModule, HttpClientTestingModule],
+ declarations: [WorkbenchLayoutComponent],
+ schemas: [NO_ERRORS_SCHEMA],
+ providers: [AuthStorageService, CssHelper, RbdService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(WorkbenchLayoutComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.ts
new file mode 100644
index 000000000..f2070be5f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.ts
@@ -0,0 +1,39 @@
+import { Component, OnDestroy, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
+
+import { Subscription } from 'rxjs';
+
+import { FaviconService } from '~/app/shared/services/favicon.service';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { TaskManagerService } from '~/app/shared/services/task-manager.service';
+
+@Component({
+ selector: 'cd-workbench-layout',
+ templateUrl: './workbench-layout.component.html',
+ styleUrls: ['./workbench-layout.component.scss'],
+ providers: [FaviconService]
+})
+export class WorkbenchLayoutComponent implements OnInit, OnDestroy {
+ private subs = new Subscription();
+
+ constructor(
+ private router: Router,
+ private summaryService: SummaryService,
+ private taskManagerService: TaskManagerService,
+ private faviconService: FaviconService
+ ) {}
+
+ ngOnInit() {
+ this.subs.add(this.summaryService.startPolling());
+ this.subs.add(this.taskManagerService.init(this.summaryService));
+ this.faviconService.init();
+ }
+
+ ngOnDestroy() {
+ this.subs.unsubscribe();
+ }
+
+ isDashboardPage() {
+ return this.router.url === '/dashboard';
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.html
new file mode 100644
index 000000000..fdf4d95cf
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.html
@@ -0,0 +1,47 @@
+<div class="about-container">
+ <div class="modal-header">
+ <button type="button"
+ class="close float-right"
+ aria-label="Close"
+ (click)="activeModal.close()">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ </div>
+ <div class="modal-body">
+ <img src="assets/Ceph_Ceph_Logo_with_text_red_white.svg"
+ class="ceph-logo"
+ alt="{{ projectConstants.organization }}">
+ <h3>
+ <strong>{{ projectConstants.projectName }}</strong>
+ </h3>
+ <div class="product-versions">
+ <strong>Version</strong>
+ <br>
+ {{ versionNumber }}
+ {{ versionHash }}
+ <br>
+ {{ versionName }}
+ </div>
+ <br>
+ <dl>
+ <dt>Ceph Manager</dt>
+ <dd>{{ hostAddr }}</dd>
+ <dt>User</dt>
+ <dd>{{ modalVariables.user }}</dd>
+ <dt>User Role</dt>
+ <dd>{{ modalVariables.role }}</dd>
+ <dt>Browser</dt>
+ <dd>{{ modalVariables.browserName }}</dd>
+ <dt>Browser Version</dt>
+ <dd>{{ modalVariables.browserVersion }}</dd>
+ <dt>Browser OS</dt>
+ <dd>{{ modalVariables.browserOS }}</dd>
+ </dl>
+ </div>
+ <div class="modal-footer">
+ <div class="text-left">
+ {{ projectConstants.copyright }}
+ {{ projectConstants.license }}
+ </div>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.scss
new file mode 100644
index 000000000..78c7fe550
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.scss
@@ -0,0 +1,43 @@
+@use './src/styles/vendor/variables' as vv;
+
+.about-container {
+ background-color: vv.$secondary;
+ background-image: url('../../../../assets/ceph_background.gif');
+ background-position: right bottom;
+ background-repeat: no-repeat;
+ color: vv.$white;
+ text-shadow: 1px 1px vv.$secondary;
+}
+
+.product-versions {
+ margin-top: 30px;
+}
+
+.product-versions strong {
+ margin-right: 10px;
+}
+
+.modal-header {
+ border-bottom: 0;
+}
+
+.modal-header .close {
+ color: vv.$white;
+ font-size: 2em;
+}
+
+.modal-body {
+ padding-left: 80px;
+ padding-right: 80px;
+}
+
+.ceph-logo {
+ margin-bottom: 30px;
+ width: 25%;
+}
+
+.modal-footer {
+ border-top: 0;
+ display: block;
+ padding: 15px 80px 35px;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.spec.ts
new file mode 100644
index 000000000..74ca78434
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.spec.ts
@@ -0,0 +1,60 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { BehaviorSubject } from 'rxjs';
+
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { environment } from '~/environments/environment';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { AboutComponent } from './about.component';
+
+export class SummaryServiceMock {
+ summaryDataSource = new BehaviorSubject({
+ version:
+ 'ceph version 14.0.0-855-gb8193bb4cd ' +
+ '(b8193bb4cda16ccc5b028c3e1df62bc72350a15d) nautilus (dev)',
+ mgr_host: 'http://localhost:11000/'
+ });
+ summaryData$ = this.summaryDataSource.asObservable();
+
+ subscribe(call: any) {
+ return this.summaryData$.subscribe(call);
+ }
+}
+
+describe('AboutComponent', () => {
+ let component: AboutComponent;
+ let fixture: ComponentFixture<AboutComponent>;
+
+ configureTestBed({
+ imports: [SharedModule, HttpClientTestingModule],
+ declarations: [AboutComponent],
+ providers: [NgbActiveModal, { provide: SummaryService, useClass: SummaryServiceMock }]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AboutComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should parse version', () => {
+ expect(component.versionNumber).toBe('14.0.0-855-gb8193bb4cd');
+ expect(component.versionHash).toBe('(b8193bb4cda16ccc5b028c3e1df62bc72350a15d)');
+ expect(component.versionName).toBe('nautilus (dev)');
+ });
+
+ it('should get host', () => {
+ expect(component.hostAddr).toBe('localhost:11000');
+ });
+
+ it('should display copyright', () => {
+ expect(component.projectConstants.copyright).toContain(environment.year);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.ts
new file mode 100644
index 000000000..64b26bfc6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.ts
@@ -0,0 +1,70 @@
+import { Component, OnDestroy, OnInit } from '@angular/core';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { detect } from 'detect-browser';
+import { Subscription } from 'rxjs';
+
+import { UserService } from '~/app/shared/api/user.service';
+import { AppConstants } from '~/app/shared/constants/app.constants';
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { SummaryService } from '~/app/shared/services/summary.service';
+
+@Component({
+ selector: 'cd-about',
+ templateUrl: './about.component.html',
+ styleUrls: ['./about.component.scss']
+})
+export class AboutComponent implements OnInit, OnDestroy {
+ modalVariables: any;
+ versionNumber: string;
+ versionHash: string;
+ versionName: string;
+ subs: Subscription;
+ userPermission: Permission;
+ projectConstants: typeof AppConstants;
+ hostAddr: string;
+ copyright: string;
+
+ constructor(
+ public activeModal: NgbActiveModal,
+ private summaryService: SummaryService,
+ private userService: UserService,
+ private authStorageService: AuthStorageService
+ ) {
+ this.userPermission = this.authStorageService.getPermissions().user;
+ }
+
+ ngOnInit() {
+ this.projectConstants = AppConstants;
+ this.hostAddr = window.location.hostname;
+ this.modalVariables = this.setVariables();
+ this.subs = this.summaryService.subscribe((summary) => {
+ const version = summary.version.replace('ceph version ', '').split(' ');
+ this.hostAddr = summary.mgr_host.replace(/(^\w+:|^)\/\//, '').replace(/\/$/, '');
+ this.versionNumber = version[0];
+ this.versionHash = version[1];
+ this.versionName = version.slice(2, version.length).join(' ');
+ });
+ }
+
+ ngOnDestroy(): void {
+ this.subs.unsubscribe();
+ }
+
+ setVariables() {
+ const project = {} as any;
+ project.user = localStorage.getItem('dashboard_username');
+ project.role = 'user';
+ if (this.userPermission.read) {
+ this.userService.get(project.user).subscribe((data: any) => {
+ project.role = data.roles;
+ });
+ }
+ const browser = detect();
+ project.browserName = browser && browser.name ? browser.name : 'Not detected';
+ project.browserVersion = browser && browser.version ? browser.version : 'Not detected';
+ project.browserOS = browser && browser.os ? browser.os : 'Not detected';
+ return project;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.html
new file mode 100644
index 000000000..fa4b38d16
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.html
@@ -0,0 +1,22 @@
+<div ngbDropdown
+ placement="bottom-right"
+ *ngIf="userPermission.read">
+ <a ngbDropdownToggle
+ class="dropdown-toggle"
+ i18n-title
+ title="Dashboard Settings">
+ <i [ngClass]="[icons.deepCheck]"></i>
+ <span i18n
+ class="d-md-none">Dashboard Settings</span>
+ </a>
+ <div ngbDropdownMenu>
+ <button ngbDropdownItem
+ *ngIf="userPermission.read"
+ routerLink="/user-management"
+ i18n>User management</button>
+ <button ngbDropdownItem
+ *ngIf="configOptPermission.read"
+ routerLink="/telemetry"
+ i18n>Telemetry configuration</button>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.spec.ts
new file mode 100644
index 000000000..29392785b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { AdministrationComponent } from './administration.component';
+
+describe('AdministrationComponent', () => {
+ let component: AdministrationComponent;
+ let fixture: ComponentFixture<AdministrationComponent>;
+
+ configureTestBed({
+ imports: [SharedModule],
+ declarations: [AdministrationComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AdministrationComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.ts
new file mode 100644
index 000000000..60cd17ec6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.ts
@@ -0,0 +1,22 @@
+import { Component } from '@angular/core';
+
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { Permission } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+
+@Component({
+ selector: 'cd-administration',
+ templateUrl: './administration.component.html',
+ styleUrls: ['./administration.component.scss']
+})
+export class AdministrationComponent {
+ userPermission: Permission;
+ configOptPermission: Permission;
+ icons = Icons;
+
+ constructor(private authStorageService: AuthStorageService) {
+ const permissions = this.authStorageService.getPermissions();
+ this.userPermission = permissions.user;
+ this.configOptPermission = permissions.configOpt;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/api-docs/api-docs.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/api-docs/api-docs.component.html
new file mode 100644
index 000000000..2dd0ff424
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/api-docs/api-docs.component.html
@@ -0,0 +1,3 @@
+
+<div id="swagger-ui"
+ class="apiDocs"></div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/api-docs/api-docs.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/api-docs/api-docs.component.scss
new file mode 100644
index 000000000..889286488
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/api-docs/api-docs.component.scss
@@ -0,0 +1,7 @@
+@use './src/styles/vendor/variables' as vv;
+
+.apiDocs {
+ background: vv.$gray-100;
+ font-size: 18px !important;
+ margin-top: -48px !important;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/api-docs/api-docs.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/api-docs/api-docs.component.ts
new file mode 100644
index 000000000..7d9ea86eb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/api-docs/api-docs.component.ts
@@ -0,0 +1,18 @@
+import { Component, OnInit } from '@angular/core';
+
+import SwaggerUI from 'swagger-ui';
+
+@Component({
+ selector: 'cd-api-docs',
+ templateUrl: './api-docs.component.html',
+ styleUrls: ['./api-docs.component.scss']
+})
+export class ApiDocsComponent implements OnInit {
+ ngOnInit(): void {
+ SwaggerUI({
+ url: window.location.origin + '/docs/openapi.json',
+ dom_id: '#swagger-ui',
+ layout: 'BaseLayout'
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.html
new file mode 100644
index 000000000..05232b7fa
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.html
@@ -0,0 +1,11 @@
+<ol *ngIf="crumbs.length"
+ class="breadcrumb">
+ <li *ngFor="let crumb of crumbs; let last = last"
+ [ngClass]="{ 'active': last && finished }"
+ class="breadcrumb-item">
+ <a *ngIf="!last && crumb.path !== null"
+ [routerLink]="crumb.path"
+ preserveFragment>{{ crumb.text }}</a>
+ <span *ngIf="last || crumb.path === null">{{ crumb.text }}</span>
+ </li>
+</ol>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.scss
new file mode 100644
index 000000000..733f7e677
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.scss
@@ -0,0 +1,12 @@
+.breadcrumb {
+ background-color: transparent;
+ border-radius: 0;
+ margin-top: 8px;
+ padding: 8px 0;
+}
+
+.breadcrumb > li + li::before {
+ content: '\f101';
+ font-family: 'ForkAwesome';
+ padding: 0 5px 0 7px;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.spec.ts
new file mode 100644
index 000000000..b6551f780
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.spec.ts
@@ -0,0 +1,131 @@
+import { CommonModule } from '@angular/common';
+import { Component } from '@angular/core';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { Router, Routes } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { PerformanceCounterBreadcrumbsResolver } from '~/app/app-routing.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { BreadcrumbsComponent } from './breadcrumbs.component';
+
+describe('BreadcrumbsComponent', () => {
+ let component: BreadcrumbsComponent;
+ let fixture: ComponentFixture<BreadcrumbsComponent>;
+ let router: Router;
+
+ @Component({ selector: 'cd-fake', template: '' })
+ class FakeComponent {}
+
+ const routes: Routes = [
+ {
+ path: 'hosts',
+ component: FakeComponent,
+ data: { breadcrumbs: 'Cluster/Hosts' }
+ },
+ {
+ path: 'perf_counters',
+ component: FakeComponent,
+ data: {
+ breadcrumbs: PerformanceCounterBreadcrumbsResolver
+ }
+ },
+ {
+ path: 'block',
+ data: { breadcrumbs: true, text: 'Block', path: null },
+ children: [
+ {
+ path: 'rbd',
+ data: { breadcrumbs: 'Images' },
+ children: [
+ { path: '', component: FakeComponent },
+ { path: 'add', component: FakeComponent, data: { breadcrumbs: 'Add' } }
+ ]
+ }
+ ]
+ }
+ ];
+
+ configureTestBed({
+ declarations: [BreadcrumbsComponent, FakeComponent],
+ imports: [CommonModule, RouterTestingModule.withRoutes(routes)],
+ providers: [PerformanceCounterBreadcrumbsResolver]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(BreadcrumbsComponent);
+ router = TestBed.inject(Router);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ expect(component.crumbs).toEqual([]);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ expect(component.subscription).toBeDefined();
+ });
+
+ it('should run postProcess and split the breadcrumbs when navigating to hosts', fakeAsync(() => {
+ fixture.ngZone.run(() => {
+ router.navigateByUrl('/hosts');
+ });
+ tick();
+ expect(component.crumbs).toEqual([
+ { path: null, text: 'Cluster' },
+ { path: '/hosts', text: 'Hosts' }
+ ]);
+ }));
+
+ it('should display empty breadcrumb when navigating to perf_counters from unknown path', fakeAsync(() => {
+ fixture.ngZone.run(() => {
+ router.navigateByUrl('/perf_counters');
+ });
+ tick();
+ expect(component.crumbs).toEqual([
+ { path: null, text: 'Cluster' },
+ { path: null, text: '' },
+ { path: '', text: 'Performance Counters' }
+ ]);
+ }));
+
+ it('should display Monitor breadcrumb when navigating to perf_counters from Monitors', fakeAsync(() => {
+ fixture.ngZone.run(() => {
+ router.navigate(['/perf_counters'], { queryParams: { fromLink: '/monitor' } });
+ });
+ tick();
+ expect(component.crumbs).toEqual([
+ { path: null, text: 'Cluster' },
+ { path: '/monitor', text: 'Monitors' },
+ { path: '', text: 'Performance Counters' }
+ ]);
+ }));
+
+ it('should display Hosts breadcrumb when navigating to perf_counters from Hosts', fakeAsync(() => {
+ fixture.ngZone.run(() => {
+ router.navigate(['/perf_counters'], { queryParams: { fromLink: '/hosts' } });
+ });
+ tick();
+ expect(component.crumbs).toEqual([
+ { path: null, text: 'Cluster' },
+ { path: '/hosts', text: 'Hosts' },
+ { path: '', text: 'Performance Counters' }
+ ]);
+ }));
+
+ it('should show all 3 breadcrumbs when navigating to RBD Add', fakeAsync(() => {
+ fixture.ngZone.run(() => {
+ router.navigateByUrl('/block/rbd/add');
+ });
+ tick();
+ expect(component.crumbs).toEqual([
+ { path: null, text: 'Block' },
+ { path: '/block/rbd', text: 'Images' },
+ { path: '/block/rbd/add', text: 'Add' }
+ ]);
+ }));
+
+ it('should unsubscribe on ngOnDestroy', () => {
+ expect(component.subscription.closed).toBeFalsy();
+ component.ngOnDestroy();
+ expect(component.subscription.closed).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.ts
new file mode 100644
index 000000000..d933081ab
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.ts
@@ -0,0 +1,141 @@
+/*
+The MIT License
+
+Copyright (c) 2017 (null) McNull https://github.com/McNull
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+ */
+
+import { Component, Injector, OnDestroy } from '@angular/core';
+import { ActivatedRouteSnapshot, NavigationEnd, NavigationStart, Router } from '@angular/router';
+
+import { concat, from, Observable, of, Subscription } from 'rxjs';
+import { distinct, filter, first, mergeMap, toArray } from 'rxjs/operators';
+
+import { BreadcrumbsResolver, IBreadcrumb } from '~/app/shared/models/breadcrumbs';
+
+@Component({
+ selector: 'cd-breadcrumbs',
+ templateUrl: './breadcrumbs.component.html',
+ styleUrls: ['./breadcrumbs.component.scss']
+})
+export class BreadcrumbsComponent implements OnDestroy {
+ crumbs: IBreadcrumb[] = [];
+ /**
+ * Useful for e2e tests.
+ * This allow us to mark the breadcrumb as pending during the navigation from
+ * one page to another.
+ * This resolves the problem of validating the breadcrumb of a new page and
+ * still get the value from the previous
+ */
+ finished = false;
+ subscription: Subscription;
+ private defaultResolver = new BreadcrumbsResolver();
+
+ constructor(private router: Router, private injector: Injector) {
+ this.subscription = this.router.events
+ .pipe(filter((x) => x instanceof NavigationStart))
+ .subscribe(() => {
+ this.finished = false;
+ });
+
+ this.subscription = this.router.events
+ .pipe(filter((x) => x instanceof NavigationEnd))
+ .subscribe(() => {
+ const currentRoot = router.routerState.snapshot.root;
+
+ this._resolveCrumbs(currentRoot)
+ .pipe(
+ mergeMap((x) => x),
+ distinct((x) => x.text),
+ toArray(),
+ mergeMap((x) => {
+ const y = this.postProcess(x);
+ return this.wrapIntoObservable<IBreadcrumb[]>(y).pipe(first());
+ })
+ )
+ .subscribe((x) => {
+ this.finished = true;
+ this.crumbs = x;
+ });
+ });
+ }
+
+ ngOnDestroy(): void {
+ this.subscription.unsubscribe();
+ }
+
+ private _resolveCrumbs(route: ActivatedRouteSnapshot): Observable<IBreadcrumb[]> {
+ let crumbs$: Observable<IBreadcrumb[]>;
+
+ const data = route.routeConfig && route.routeConfig.data;
+
+ if (data && data.breadcrumbs) {
+ let resolver: BreadcrumbsResolver;
+
+ if (data.breadcrumbs.prototype instanceof BreadcrumbsResolver) {
+ resolver = this.injector.get<BreadcrumbsResolver>(data.breadcrumbs);
+ } else {
+ resolver = this.defaultResolver;
+ }
+
+ const result = resolver.resolve(route);
+ crumbs$ = this.wrapIntoObservable<IBreadcrumb[]>(result).pipe(first());
+ } else {
+ crumbs$ = of([]);
+ }
+
+ if (route.firstChild) {
+ crumbs$ = concat<IBreadcrumb[]>(crumbs$, this._resolveCrumbs(route.firstChild));
+ }
+
+ return crumbs$;
+ }
+
+ postProcess(breadcrumbs: IBreadcrumb[]) {
+ const result: IBreadcrumb[] = [];
+ breadcrumbs.forEach((element) => {
+ const split = element.text.split('/');
+ if (split.length > 1) {
+ element.text = split[split.length - 1];
+ for (let i = 0; i < split.length - 1; i++) {
+ result.push({ text: split[i], path: null });
+ }
+ }
+ result.push(element);
+ });
+ return result;
+ }
+
+ isPromise(value: any): boolean {
+ return value && typeof value.then === 'function';
+ }
+
+ wrapIntoObservable<T>(value: T | Promise<T> | Observable<T>): Observable<T> {
+ if (value instanceof Observable) {
+ return value;
+ }
+
+ if (this.isPromise(value)) {
+ return from(Promise.resolve(value));
+ }
+
+ return of(value as T);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.html
new file mode 100644
index 000000000..274ec71df
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.html
@@ -0,0 +1,25 @@
+<div ngbDropdown
+ placement="bottom-right">
+ <a ngbDropdownToggle
+ i18n-title
+ title="Help">
+ <i [ngClass]="[icons.questionCircle]"></i>
+ <span i18n
+ class="d-md-none">Help</span>
+ </a>
+ <div ngbDropdownMenu>
+ <a ngbDropdownItem
+ [ngClass]="{'disabled': !docsUrl}"
+ class="text-capitalize"
+ href="{{ docsUrl }}"
+ target="_blank"
+ i18n>documentation</a>
+ <a ngbDropdownItem
+ routerLink="/api-docs"
+ target="_blank"
+ i18n>API</a>
+ <button ngbDropdownItem
+ (click)="openAboutModal()"
+ i18n>About</button>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.spec.ts
new file mode 100644
index 000000000..1c9e0a5f7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.spec.ts
@@ -0,0 +1,27 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { DashboardHelpComponent } from './dashboard-help.component';
+
+describe('DashboardHelpComponent', () => {
+ let component: DashboardHelpComponent;
+ let fixture: ComponentFixture<DashboardHelpComponent>;
+
+ configureTestBed({
+ imports: [HttpClientTestingModule, SharedModule, RouterTestingModule],
+ declarations: [DashboardHelpComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DashboardHelpComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.ts
new file mode 100644
index 000000000..910a61333
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.ts
@@ -0,0 +1,31 @@
+import { Component, OnInit } from '@angular/core';
+
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { DocService } from '~/app/shared/services/doc.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { AboutComponent } from '../about/about.component';
+
+@Component({
+ selector: 'cd-dashboard-help',
+ templateUrl: './dashboard-help.component.html',
+ styleUrls: ['./dashboard-help.component.scss']
+})
+export class DashboardHelpComponent implements OnInit {
+ docsUrl: string;
+ modalRef: NgbModalRef;
+ icons = Icons;
+
+ constructor(private modalService: ModalService, private docService: DocService) {}
+
+ ngOnInit() {
+ this.docService.subscribeOnce('dashboard', (url: string) => {
+ this.docsUrl = url;
+ });
+ }
+
+ openAboutModal() {
+ this.modalRef = this.modalService.show(AboutComponent, null, { size: 'lg' });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.html
new file mode 100644
index 000000000..bf0f22fbb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.html
@@ -0,0 +1,27 @@
+<div ngbDropdown
+ placement="bottom-right">
+ <a ngbDropdownToggle
+ i18n-title
+ title="Logged in user">
+ <i [ngClass]="[icons.user]"></i>
+ <span i18n
+ class="d-md-none">Logged in user</span>
+ </a>
+ <div ngbDropdownMenu>
+ <button ngbDropdownItem
+ disabled
+ i18n>Signed in as <strong>{{ username }}</strong></button>
+ <li class="dropdown-divider"></li>
+ <button ngbDropdownItem
+ *ngIf="!sso"
+ routerLink="/user-profile/edit">
+ <i [ngClass]="[icons.lock]"></i>
+ <span i18n>Change password</span>
+ </button>
+ <button ngbDropdownItem
+ (click)="logout()">
+ <i [ngClass]="[icons.signOut]"></i>
+ <span i18n>Sign out</span>
+ </button>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.spec.ts
new file mode 100644
index 000000000..23f2f97ca
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.spec.ts
@@ -0,0 +1,27 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { IdentityComponent } from './identity.component';
+
+describe('IdentityComponent', () => {
+ let component: IdentityComponent;
+ let fixture: ComponentFixture<IdentityComponent>;
+
+ configureTestBed({
+ imports: [HttpClientTestingModule, SharedModule, RouterTestingModule],
+ declarations: [IdentityComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(IdentityComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.ts
new file mode 100644
index 000000000..c1d33b938
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.ts
@@ -0,0 +1,27 @@
+import { Component, OnInit } from '@angular/core';
+
+import { AuthService } from '~/app/shared/api/auth.service';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+
+@Component({
+ selector: 'cd-identity',
+ templateUrl: './identity.component.html',
+ styleUrls: ['./identity.component.scss']
+})
+export class IdentityComponent implements OnInit {
+ sso: boolean;
+ username: string;
+ icons = Icons;
+
+ constructor(private authStorageService: AuthStorageService, private authService: AuthService) {}
+
+ ngOnInit() {
+ this.username = this.authStorageService.getUsername();
+ this.sso = this.authStorageService.isSSO();
+ }
+
+ logout() {
+ this.authService.logout();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation.module.ts
new file mode 100644
index 000000000..c8d2a9d9c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation.module.ts
@@ -0,0 +1,43 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { RouterModule } from '@angular/router';
+
+import { NgbCollapseModule, NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
+import { SimplebarAngularModule } from 'simplebar-angular';
+
+import { AppRoutingModule } from '~/app/app-routing.module';
+import { SharedModule } from '~/app/shared/shared.module';
+import { AuthModule } from '../auth/auth.module';
+import { AboutComponent } from './about/about.component';
+import { AdministrationComponent } from './administration/administration.component';
+import { ApiDocsComponent } from './api-docs/api-docs.component';
+import { BreadcrumbsComponent } from './breadcrumbs/breadcrumbs.component';
+import { DashboardHelpComponent } from './dashboard-help/dashboard-help.component';
+import { IdentityComponent } from './identity/identity.component';
+import { NavigationComponent } from './navigation/navigation.component';
+import { NotificationsComponent } from './notifications/notifications.component';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ AuthModule,
+ NgbCollapseModule,
+ NgbDropdownModule,
+ AppRoutingModule,
+ SharedModule,
+ SimplebarAngularModule,
+ RouterModule
+ ],
+ declarations: [
+ AboutComponent,
+ ApiDocsComponent,
+ BreadcrumbsComponent,
+ NavigationComponent,
+ NotificationsComponent,
+ DashboardHelpComponent,
+ AdministrationComponent,
+ IdentityComponent
+ ],
+ exports: [NavigationComponent, BreadcrumbsComponent]
+})
+export class NavigationModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.html
new file mode 100644
index 000000000..bdb35a610
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.html
@@ -0,0 +1,272 @@
+<div class="cd-navbar-main">
+ <cd-pwd-expiration-notification></cd-pwd-expiration-notification>
+ <cd-telemetry-notification></cd-telemetry-notification>
+ <cd-motd></cd-motd>
+ <cd-notifications-sidebar></cd-notifications-sidebar>
+ <div class="cd-navbar-top">
+ <nav class="navbar navbar-expand-md navbar-dark cd-navbar-brand">
+ <button class="btn btn-link py-0"
+ (click)="showMenuSidebar = !showMenuSidebar"
+ aria-label="toggle sidebar visibility">
+ <i class="fa fa-bars fa-2x"
+ aria-hidden="true"></i>
+ </button>
+
+ <a class="navbar-brand ml-2"
+ href="#">
+ <img src="assets/Ceph_Ceph_Logo_with_text_white.svg"
+ alt="Ceph" />
+ </a>
+
+ <button type="button"
+ class="navbar-toggler"
+ (click)="toggleRightSidebar()">
+ <span i18n
+ class="sr-only">Toggle navigation</span>
+ <span class="">
+ <i class="fa fa-navicon fa-lg"></i>
+ </span>
+ </button>
+
+ <div class="collapse navbar-collapse"
+ [ngClass]="{'show': rightSidebarOpen}">
+ <ul class="nav navbar-nav cd-navbar-utility my-2 my-md-0">
+ <ng-container *ngTemplateOutlet="cd_utilities"> </ng-container>
+ </ul>
+ </div>
+ </nav>
+ </div>
+
+ <div class="wrapper">
+ <!-- Content -->
+ <nav id="sidebar"
+ [ngClass]="{'active': !showMenuSidebar}">
+ <ngx-simplebar [options]="simplebar">
+ <ul class="list-unstyled components cd-navbar-primary">
+ <ng-container *ngTemplateOutlet="cd_menu"> </ng-container>
+ </ul>
+ </ngx-simplebar>
+ </nav>
+
+ <!-- Page Content -->
+ <div id="content"
+ [ngClass]="{'active': !showMenuSidebar}">
+ <ng-content></ng-content>
+ </div>
+ </div>
+
+ <ng-template #cd_utilities>
+ <li class="nav-item">
+ <cd-language-selector class="cd-navbar"></cd-language-selector>
+ </li>
+ <li class="nav-item">
+ <cd-notifications class="cd-navbar"
+ (click)="toggleRightSidebar()"></cd-notifications>
+ </li>
+ <li class="nav-item">
+ <cd-dashboard-help class="cd-navbar"></cd-dashboard-help>
+ </li>
+ <li class="nav-item">
+ <cd-administration class="cd-navbar"></cd-administration>
+ </li>
+ <li class="nav-item">
+ <cd-identity class="cd-navbar"></cd-identity>
+ </li>
+ </ng-template>
+
+ <ng-template #cd_menu>
+ <ng-container *ngIf="enabledFeature$ | async as enabledFeature">
+ <!-- Dashboard -->
+ <li routerLinkActive="active"
+ class="nav-item tc_menuitem_dashboard">
+ <a routerLink="/dashboard"
+ class="nav-link">
+ <span i18n>Dashboard</span>&nbsp;
+ <i [ngClass]="[icons.health]"
+ [ngStyle]="summaryData?.health_status | healthColor"></i>
+ </a>
+ </li>
+
+ <!-- Cluster -->
+ <li routerLinkActive="active"
+ class="nav-item tc_menuitem_cluster"
+ *ngIf="permissions.hosts.read || permissions.monitor.read ||
+ permissions.osd.read || permissions.configOpt.read ||
+ permissions.log.read || permissions.prometheus.read">
+ <a (click)="toggleSubMenu('cluster')"
+ class="nav-link dropdown-toggle"
+ [attr.aria-expanded]="displayedSubMenu == 'cluster'"
+ aria-controls="collapseBasic">
+ <ng-container i18n>Cluster</ng-container>
+ </a>
+ <ul class="list-unstyled"
+ [ngbCollapse]="displayedSubMenu !== 'cluster'">
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_hosts"
+ *ngIf="permissions.hosts.read">
+ <a i18n
+ routerLink="/hosts">Hosts</a>
+ </li>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_cluster_inventory"
+ *ngIf="permissions.hosts.read">
+ <a i18n
+ routerLink="/inventory">Physical Disks</a>
+ </li>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_cluster_monitor"
+ *ngIf="permissions.monitor.read">
+ <a i18n
+ routerLink="/monitor/">Monitors</a>
+ </li>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_cluster_services"
+ *ngIf="permissions.hosts.read">
+ <a i18n
+ routerLink="/services/">Services</a>
+ </li>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_osds"
+ *ngIf="permissions.osd.read">
+ <a i18n
+ routerLink="/osd">OSDs</a>
+ </li>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_configuration"
+ *ngIf="permissions.configOpt.read">
+ <a i18n
+ routerLink="/configuration">Configuration</a>
+ </li>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_crush"
+ *ngIf="permissions.osd.read">
+ <a i18n
+ routerLink="/crush-map">CRUSH map</a>
+ </li>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_modules"
+ *ngIf="permissions.configOpt.read">
+ <a i18n
+ routerLink="/mgr-modules">Manager Modules</a>
+ </li>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_log"
+ *ngIf="permissions.log.read">
+ <a i18n
+ routerLink="/logs">Logs</a>
+ </li>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_monitoring"
+ *ngIf="permissions.prometheus.read">
+ <a routerLink="/monitoring">
+ <ng-container i18n>Monitoring</ng-container>
+ <small *ngIf="prometheusAlertService.activeAlerts > 0"
+ class="badge badge-danger">{{ prometheusAlertService.activeAlerts }}</small>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <!-- Pools -->
+ <li routerLinkActive="active"
+ class="nav-item tc_menuitem_pool"
+ *ngIf="permissions.pool.read">
+ <a class="nav-link"
+ i18n
+ routerLink="/pool">Pools</a>
+ </li>
+
+ <!-- Block -->
+ <li routerLinkActive="active"
+ class="nav-item tc_menuitem_block"
+ *ngIf="(permissions.rbdImage.read || permissions.rbdMirroring.read || permissions.iscsi.read) &&
+ (enabledFeature.rbd || enabledFeature.mirroring || enabledFeature.iscsi)">
+ <a class="nav-link dropdown-toggle"
+ (click)="toggleSubMenu('block')"
+ [attr.aria-expanded]="displayedSubMenu == 'block'"
+ aria-controls="collapseBasic"
+ [ngStyle]="blockHealthColor()">
+ <ng-container i18n>Block</ng-container>
+ </a>
+
+ <ul class="list-unstyled"
+ [ngbCollapse]="displayedSubMenu !== 'block'">
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_block_images"
+ *ngIf="permissions.rbdImage.read && enabledFeature.rbd">
+ <a i18n
+ routerLink="/block/rbd">Images</a>
+ </li>
+
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_block_mirroring"
+ *ngIf="permissions.rbdMirroring.read && enabledFeature.mirroring">
+ <a routerLink="/block/mirroring">
+ <ng-container i18n>Mirroring</ng-container>
+ <small *ngIf="summaryData?.rbd_mirroring?.warnings !== 0"
+ class="badge badge-warning">{{ summaryData?.rbd_mirroring?.warnings }}</small>
+ <small *ngIf="summaryData?.rbd_mirroring?.errors !== 0"
+ class="badge badge-danger">{{ summaryData?.rbd_mirroring?.errors }}</small>
+ </a>
+ </li>
+
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_block_iscsi"
+ *ngIf="permissions.iscsi.read && enabledFeature.iscsi">
+ <a i18n
+ routerLink="/block/iscsi">iSCSI</a>
+ </li>
+ </ul>
+ </li>
+
+ <!-- NFS -->
+ <li routerLinkActive="active"
+ class="nav-item tc_menuitem_nfs"
+ *ngIf="permissions.nfs.read && enabledFeature.nfs">
+ <a i18n
+ class="nav-link"
+ routerLink="/nfs">NFS</a>
+ </li>
+
+ <!-- Filesystem -->
+ <li routerLinkActive="active"
+ class="nav-item tc_menuitem_cephfs"
+ *ngIf="permissions.cephfs.read && enabledFeature.cephfs">
+ <a i18n
+ class="nav-link"
+ routerLink="/cephfs">File Systems</a>
+ </li>
+
+ <!-- Object Gateway -->
+ <li routerLinkActive="active"
+ class="nav-item tc_menuitem_rgw"
+ *ngIf="permissions.rgw.read && enabledFeature.rgw">
+ <a class="nav-link dropdown-toggle"
+ (click)="toggleSubMenu('rgw')"
+ [attr.aria-expanded]="displayedSubMenu == 'rgw'"
+ aria-controls="collapseBasic">
+ <ng-container i18n>Object Gateway</ng-container>
+ </a>
+ <ul class="list-unstyled"
+ [ngbCollapse]="displayedSubMenu !== 'rgw'">
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_rgw_daemons">
+ <a i18n
+ routerLink="/rgw/daemon">Daemons</a>
+ </li>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_rgw_users">
+ <a i18n
+ routerLink="/rgw/user">Users</a>
+ </li>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_rgw_buckets">
+ <a i18n
+ routerLink="/rgw/bucket">Buckets</a>
+ </li>
+ </ul>
+ </li>
+ </ng-container>
+ </ng-template>
+
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.scss
new file mode 100644
index 000000000..f0ce4cd92
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.scss
@@ -0,0 +1,263 @@
+@use './src/styles/vendor/variables' as vv;
+
+/* --------------------------------------------------
+ MAIN NAVBAR STYLE
+--------------------------------------------------- */
+
+.cd-navbar-main {
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+ height: 100%;
+}
+
+/* ---------------------------------------------------
+ NAVBAR STYLE
+--------------------------------------------------- */
+
+::ng-deep cd-navigation .cd-navbar-top {
+ .cd-navbar-brand {
+ background: vv.$secondary;
+ border-top: 4px solid vv.$primary;
+
+ .navbar-brand,
+ .navbar-brand:hover {
+ color: vv.$gray-200;
+ height: auto;
+ padding: 0;
+ }
+
+ .navbar-brand > img {
+ height: 25px;
+ }
+
+ .navbar-toggler {
+ border: 0;
+
+ &:focus,
+ &:hover {
+ outline: 0;
+ }
+
+ .fa-navicon {
+ color: vv.$gray-200;
+ }
+ }
+
+ .navbar-collapse {
+ padding: 0;
+ }
+
+ .cd-navbar-utility > .active > a {
+ background-color: vv.$primary;
+ color: vv.$gray-200;
+ }
+
+ .cd-navbar-utility > li > .open > a,
+ .cd-navbar-utility > li > .open > a:focus,
+ .cd-navbar-utility > li > .open > a:hover {
+ background-color: transparent;
+ border-color: transparent;
+ color: vv.$gray-200;
+ }
+ }
+
+ .navbar-nav > li > .cd-navbar > [ngbDropdown] > a,
+ .navbar-nav > li > .cd-navbar > a,
+ .navbar-nav > li > a {
+ color: vv.$gray-200;
+ display: block;
+ line-height: 1;
+ padding: 13.5px 18px !important;
+ position: relative;
+ text-decoration: none;
+ }
+
+ .navbar-nav .nav-link,
+ .navbar-nav .nav-link:hover {
+ color: vv.$gray-200;
+ }
+
+ .navbar-nav > li > .cd-navbar > [ngbDropdown] > a:hover,
+ .navbar-nav > li > .cd-navbar > [ngbDropdown].open > a,
+ .navbar-nav > li > .cd-navbar > a:hover,
+ .navbar-nav > li > a:hover,
+ .navbar-nav > li:hover {
+ background-color: vv.$primary;
+ }
+
+ .navbar-nav > .open > .cd-navbar > [ngbDropdown] > a,
+ .navbar-nav > .open > .cd-navbar > [ngbDropdown] > a:hover,
+ .navbar-nav > .open > .cd-navbar > a,
+ .navbar-nav > .open > .cd-navbar > a:focus,
+ .navbar-nav > .open > .cd-navbar > a:hover,
+ .navbar-nav > .open > .cd-navbar > li > a:focus,
+ .navbar-nav > .open > a,
+ .navbar-nav > .open > a:focus,
+ .navbar-nav > .open > a:hover {
+ background-color: transparent;
+ border-color: transparent;
+ color: vv.$gray-200;
+ }
+
+ @media (min-width: vv.$screen-md-min) {
+ .cd-navbar-utility {
+ border-bottom: 0;
+ font-size: 1.1rem;
+ position: absolute;
+ right: 0;
+ top: 0;
+ }
+ }
+
+ @media (max-width: vv.$screen-sm-max) {
+ .navbar-nav {
+ margin: 0;
+
+ .fa {
+ margin-right: 0.5em;
+ }
+
+ .open .dropdown-menu {
+ background-color: vv.$primary;
+ border: 0;
+ padding-bottom: 0;
+ padding-top: 0;
+ }
+
+ .open .dropdown-menu > li > a {
+ color: vv.$gray-200;
+ padding: 5px 15px 5px 35px;
+ }
+
+ .open .dropdown-menu > .active > a {
+ background-color: vv.$primary;
+ }
+ }
+
+ .navbar-nav > li > a:hover {
+ background-color: vv.$primary;
+ }
+ }
+}
+
+/* ---------------------------------------------------
+ SIDEBAR STYLE
+--------------------------------------------------- */
+
+$sidebar-width: 200px;
+
+.cd-navbar-primary .active > a,
+.cd-navbar-primary > .active > a:focus,
+.cd-navbar-primary > .active > a:hover {
+ background-color: vv.$primary !important;
+ border: 0 !important;
+ color: vv.$gray-200 !important;
+}
+
+.wrapper {
+ display: flex;
+ height: 100%;
+ width: 100%;
+
+ #sidebar {
+ background: vv.$secondary;
+ bottom: 0;
+ color: vv.$white;
+ height: auto;
+ left: 0;
+ overflow-y: auto;
+ position: relative;
+ transition: all 0.3s;
+ width: $sidebar-width;
+ z-index: 999;
+
+ &.active {
+ margin-left: -$sidebar-width;
+ }
+
+ ul {
+ &.component {
+ margin: 0;
+ padding: 20px 0;
+ }
+
+ p {
+ color: vv.$white;
+ padding: 10px;
+ }
+
+ li a {
+ color: vv.$white;
+ display: block;
+ font-size: 1.1em;
+ padding: 10px;
+ padding-left: 27px;
+
+ text-decoration: none;
+
+ &:hover {
+ background: vv.$primary;
+ color: vv.$white;
+ }
+
+ > .badge {
+ margin-left: 5px;
+ }
+ }
+
+ li.active > a,
+ li > a a[aria-expanded='true'] {
+ color: vv.$white;
+ }
+ }
+ }
+
+ a.dropdown-toggle {
+ position: relative;
+
+ &::after {
+ border: 0;
+ content: '\f054';
+ font-family: 'ForkAwesome';
+ font-size: 1rem;
+ position: absolute;
+ right: 20px;
+ transition: transform 0.3s ease-in-out;
+ }
+
+ &[aria-expanded='true']::after {
+ transform: rotate(90deg);
+ }
+ }
+
+ ul ul a {
+ background: lighten(vv.$secondary, 10);
+ font-size: 0.9em !important;
+ padding-left: 40px !important;
+ }
+
+ .cd-navbar-primary a:focus {
+ outline: none;
+ }
+
+ ngx-simplebar {
+ height: 100%;
+ }
+}
+
+/* ---------------------------------------------------
+ CONTENT STYLE
+--------------------------------------------------- */
+
+#content {
+ bottom: 0;
+ position: relative;
+ right: 0;
+ transition: all 0.3s;
+ width: calc(100% - #{$sidebar-width});
+
+ &.active {
+ width: 100vw;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.spec.ts
new file mode 100644
index 000000000..241910f2b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.spec.ts
@@ -0,0 +1,237 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+
+import { MockModule } from 'ng-mocks';
+import { of } from 'rxjs';
+
+import { Permission, Permissions } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import {
+ Features,
+ FeatureTogglesMap,
+ FeatureTogglesService
+} from '~/app/shared/services/feature-toggles.service';
+import { PrometheusAlertService } from '~/app/shared/services/prometheus-alert.service';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { NavigationModule } from '../navigation.module';
+import { NavigationComponent } from './navigation.component';
+
+function everythingPermittedExcept(disabledPermissions: string[] = []): any {
+ const permissions: Permissions = new Permissions({});
+ Object.keys(permissions).forEach(
+ (key) => (permissions[key] = new Permission(disabledPermissions.includes(key) ? [] : ['read']))
+ );
+ return permissions;
+}
+
+function onlyPermitted(enabledPermissions: string[] = []): any {
+ const permissions: Permissions = new Permissions({});
+ enabledPermissions.forEach((key) => (permissions[key] = new Permission(['read'])));
+ return permissions;
+}
+
+function everythingEnabledExcept(features: Features[] = []): FeatureTogglesMap {
+ const featureTogglesMap: FeatureTogglesMap = new FeatureTogglesMap();
+ features.forEach((key) => (featureTogglesMap[key] = false));
+ return featureTogglesMap;
+}
+
+function onlyEnabled(features: Features[] = []): FeatureTogglesMap {
+ const featureTogglesMap: FeatureTogglesMap = new FeatureTogglesMap();
+ Object.keys(featureTogglesMap).forEach(
+ (key) => (featureTogglesMap[key] = features.includes(<Features>key))
+ );
+ return featureTogglesMap;
+}
+
+describe('NavigationComponent', () => {
+ let component: NavigationComponent;
+ let fixture: ComponentFixture<NavigationComponent>;
+
+ configureTestBed({
+ declarations: [NavigationComponent],
+ imports: [HttpClientTestingModule, MockModule(NavigationModule)],
+ providers: [
+ {
+ provide: AuthStorageService,
+ useValue: {
+ getPermissions: jest.fn(),
+ isPwdDisplayed$: { subscribe: jest.fn() },
+ telemetryNotification$: { subscribe: jest.fn() }
+ }
+ },
+ { provide: SummaryService, useValue: { subscribe: jest.fn() } },
+ { provide: FeatureTogglesService, useValue: { get: jest.fn() } },
+ { provide: PrometheusAlertService, useValue: { alerts: [] } }
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(NavigationComponent);
+ component = fixture.componentInstance;
+ });
+
+ describe('Test Permissions', () => {
+ const testCases: [string[], string[]][] = [
+ [
+ ['hosts'],
+ [
+ '.tc_submenuitem_hosts',
+ '.tc_submenuitem_cluster_inventory',
+ '.tc_submenuitem_cluster_services'
+ ]
+ ],
+ [['monitor'], ['.tc_submenuitem_cluster_monitor']],
+ [['osd'], ['.tc_submenuitem_osds', '.tc_submenuitem_crush']],
+ [['configOpt'], ['.tc_submenuitem_configuration', '.tc_submenuitem_modules']],
+ [['log'], ['.tc_submenuitem_log']],
+ [['prometheus'], ['.tc_submenuitem_monitoring']],
+ [['pool'], ['.tc_menuitem_pool']],
+ [['rbdImage'], ['.tc_submenuitem_block_images']],
+ [['rbdMirroring'], ['.tc_submenuitem_block_mirroring']],
+ [['iscsi'], ['.tc_submenuitem_block_iscsi']],
+ [['rbdImage', 'rbdMirroring', 'iscsi'], ['.tc_menuitem_block']],
+ [['nfs'], ['.tc_menuitem_nfs']],
+ [['cephfs'], ['.tc_menuitem_cephfs']],
+ [
+ ['rgw'],
+ [
+ '.tc_menuitem_rgw',
+ '.tc_submenuitem_rgw_daemons',
+ '.tc_submenuitem_rgw_buckets',
+ '.tc_submenuitem_rgw_users'
+ ]
+ ]
+ ];
+
+ for (const [disabledPermissions, selectors] of testCases) {
+ it(`When disabled permissions: ${JSON.stringify(
+ disabledPermissions
+ )} => hidden: "${selectors}"`, () => {
+ component.permissions = everythingPermittedExcept(disabledPermissions);
+ component.enabledFeature$ = of(everythingEnabledExcept());
+
+ fixture.detectChanges();
+ for (const selector of selectors) {
+ expect(fixture.debugElement.query(By.css(selector))).toBeFalsy();
+ }
+ });
+ }
+
+ for (const [enabledPermissions, selectors] of testCases) {
+ it(`When enabled permissions: ${JSON.stringify(
+ enabledPermissions
+ )} => visible: "${selectors}"`, () => {
+ component.permissions = onlyPermitted(enabledPermissions);
+ component.enabledFeature$ = of(everythingEnabledExcept());
+
+ fixture.detectChanges();
+ for (const selector of selectors) {
+ expect(fixture.debugElement.query(By.css(selector))).toBeTruthy();
+ }
+ });
+ }
+ });
+
+ describe('Test FeatureToggles', () => {
+ const testCases: [Features[], string[]][] = [
+ [['rbd'], ['.tc_submenuitem_block_images']],
+ [['mirroring'], ['.tc_submenuitem_block_mirroring']],
+ [['iscsi'], ['.tc_submenuitem_block_iscsi']],
+ [['rbd', 'mirroring', 'iscsi'], ['.tc_menuitem_block']],
+ [['nfs'], ['.tc_menuitem_nfs']],
+ [['cephfs'], ['.tc_menuitem_cephfs']],
+ [
+ ['rgw'],
+ [
+ '.tc_menuitem_rgw',
+ '.tc_submenuitem_rgw_daemons',
+ '.tc_submenuitem_rgw_buckets',
+ '.tc_submenuitem_rgw_users'
+ ]
+ ]
+ ];
+
+ for (const [disabledFeatures, selectors] of testCases) {
+ it(`When disabled features: ${JSON.stringify(
+ disabledFeatures
+ )} => hidden: "${selectors}"`, () => {
+ component.enabledFeature$ = of(everythingEnabledExcept(disabledFeatures));
+ component.permissions = everythingPermittedExcept();
+
+ fixture.detectChanges();
+ for (const selector of selectors) {
+ expect(fixture.debugElement.query(By.css(selector))).toBeFalsy();
+ }
+ });
+ }
+
+ for (const [enabledFeatures, selectors] of testCases) {
+ it(`When enabled features: ${JSON.stringify(
+ enabledFeatures
+ )} => visible: "${selectors}"`, () => {
+ component.enabledFeature$ = of(onlyEnabled(enabledFeatures));
+ component.permissions = everythingPermittedExcept();
+
+ fixture.detectChanges();
+ for (const selector of selectors) {
+ expect(fixture.debugElement.query(By.css(selector))).toBeTruthy();
+ }
+ });
+ }
+ });
+
+ describe('showTopNotification', () => {
+ const notification1 = 'notificationName1';
+ const notification2 = 'notificationName2';
+
+ beforeEach(() => {
+ component.notifications = [];
+ });
+
+ it('should show notification', () => {
+ component.showTopNotification(notification1, true);
+ expect(component.notifications.includes(notification1)).toBeTruthy();
+ expect(component.notifications.length).toBe(1);
+ });
+
+ it('should not add a second notification if it is already shown', () => {
+ component.showTopNotification(notification1, true);
+ component.showTopNotification(notification1, true);
+ expect(component.notifications.includes(notification1)).toBeTruthy();
+ expect(component.notifications.length).toBe(1);
+ });
+
+ it('should add a second notification if the first one is different', () => {
+ component.showTopNotification(notification1, true);
+ component.showTopNotification(notification2, true);
+ expect(component.notifications.includes(notification1)).toBeTruthy();
+ expect(component.notifications.includes(notification2)).toBeTruthy();
+ expect(component.notifications.length).toBe(2);
+ });
+
+ it('should hide an active notification', () => {
+ component.showTopNotification(notification1, true);
+ expect(component.notifications.includes(notification1)).toBeTruthy();
+ expect(component.notifications.length).toBe(1);
+ component.showTopNotification(notification1, false);
+ expect(component.notifications.length).toBe(0);
+ });
+
+ it('should not fail if it tries to hide an inactive notification', () => {
+ expect(() => component.showTopNotification(notification1, false)).not.toThrow();
+ expect(component.notifications.length).toBe(0);
+ });
+
+ it('should keep other notifications if it hides one', () => {
+ component.showTopNotification(notification1, true);
+ component.showTopNotification(notification2, true);
+ expect(component.notifications.length).toBe(2);
+ component.showTopNotification(notification2, false);
+ expect(component.notifications.length).toBe(1);
+ expect(component.notifications.includes(notification1)).toBeTruthy();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.ts
new file mode 100644
index 000000000..512feecef
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.ts
@@ -0,0 +1,123 @@
+import { Component, HostBinding, OnDestroy, OnInit } from '@angular/core';
+
+import * as _ from 'lodash';
+import { Subscription } from 'rxjs';
+
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { Permissions } from '~/app/shared/models/permissions';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import {
+ FeatureTogglesMap$,
+ FeatureTogglesService
+} from '~/app/shared/services/feature-toggles.service';
+import { MotdNotificationService } from '~/app/shared/services/motd-notification.service';
+import { PrometheusAlertService } from '~/app/shared/services/prometheus-alert.service';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { TelemetryNotificationService } from '~/app/shared/services/telemetry-notification.service';
+
+@Component({
+ selector: 'cd-navigation',
+ templateUrl: './navigation.component.html',
+ styleUrls: ['./navigation.component.scss']
+})
+export class NavigationComponent implements OnInit, OnDestroy {
+ notifications: string[] = [];
+ @HostBinding('class') get class(): string {
+ return 'top-notification-' + this.notifications.length;
+ }
+
+ permissions: Permissions;
+ enabledFeature$: FeatureTogglesMap$;
+ summaryData: any;
+ icons = Icons;
+
+ rightSidebarOpen = false; // rightSidebar only opens when width is less than 768px
+ showMenuSidebar = true;
+ displayedSubMenu = '';
+
+ simplebar = {
+ autoHide: false
+ };
+ private subs = new Subscription();
+
+ constructor(
+ private authStorageService: AuthStorageService,
+ private summaryService: SummaryService,
+ private featureToggles: FeatureTogglesService,
+ private telemetryNotificationService: TelemetryNotificationService,
+ public prometheusAlertService: PrometheusAlertService,
+ private motdNotificationService: MotdNotificationService
+ ) {
+ this.permissions = this.authStorageService.getPermissions();
+ this.enabledFeature$ = this.featureToggles.get();
+ }
+
+ ngOnInit() {
+ this.subs.add(
+ this.summaryService.subscribe((summary) => {
+ this.summaryData = summary;
+ })
+ );
+ /*
+ Note: If you're going to add more top notifications please do not forget to increase
+ the number of generated css-classes in section topNotification settings in the scss
+ file.
+ */
+ this.subs.add(
+ this.authStorageService.isPwdDisplayed$.subscribe((isDisplayed) => {
+ this.showTopNotification('isPwdDisplayed', isDisplayed);
+ })
+ );
+ this.subs.add(
+ this.telemetryNotificationService.update.subscribe((visible: boolean) => {
+ this.showTopNotification('telemetryNotificationEnabled', visible);
+ })
+ );
+ this.subs.add(
+ this.motdNotificationService.motd$.subscribe((motd: any) => {
+ this.showTopNotification('motdNotificationEnabled', _.isPlainObject(motd));
+ })
+ );
+ }
+
+ ngOnDestroy(): void {
+ this.subs.unsubscribe();
+ }
+
+ blockHealthColor() {
+ if (this.summaryData && this.summaryData.rbd_mirroring) {
+ if (this.summaryData.rbd_mirroring.errors > 0) {
+ return { color: '#d9534f' };
+ } else if (this.summaryData.rbd_mirroring.warnings > 0) {
+ return { color: '#f0ad4e' };
+ }
+ }
+
+ return undefined;
+ }
+
+ toggleSubMenu(menu: string) {
+ if (this.displayedSubMenu === menu) {
+ this.displayedSubMenu = '';
+ } else {
+ this.displayedSubMenu = menu;
+ }
+ }
+
+ toggleRightSidebar() {
+ this.rightSidebarOpen = !this.rightSidebarOpen;
+ }
+
+ showTopNotification(name: string, isDisplayed: boolean) {
+ if (isDisplayed) {
+ if (!this.notifications.includes(name)) {
+ this.notifications.push(name);
+ }
+ } else {
+ const index = this.notifications.indexOf(name);
+ if (index >= 0) {
+ this.notifications.splice(index, 1);
+ }
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.html
new file mode 100644
index 000000000..f5eae4f89
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.html
@@ -0,0 +1,11 @@
+<a i18n-title
+ title="Tasks and Notifications"
+ [ngClass]="{ 'running': hasRunningTasks }"
+ (click)="toggleSidebar()">
+ <i [ngClass]="[icons.bell]"></i>
+ <span class="dot"
+ *ngIf="hasNotifications">
+ </span>
+ <span class="d-md-none"
+ i18n>Tasks and Notifications</span>
+</a>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.scss
new file mode 100644
index 000000000..5729f7625
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.scss
@@ -0,0 +1,27 @@
+@use './src/styles/vendor/variables' as vv;
+
+.running i {
+ color: vv.$primary;
+}
+
+.running:hover i {
+ color: vv.$white;
+}
+
+a {
+ .dot {
+ background-color: vv.$primary;
+ border: 2px solid vv.$secondary;
+ border-radius: 50%;
+ height: 11px;
+ position: absolute;
+ right: 17px;
+ top: 10px;
+ width: 10px;
+ }
+
+ &:hover .dot {
+ background-color: vv.$white;
+ border-color: vv.$primary;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.spec.ts
new file mode 100644
index 000000000..8fea818cf
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.spec.ts
@@ -0,0 +1,58 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+
+import { CdNotification, CdNotificationConfig } from '~/app/shared/models/cd-notification';
+import { ExecutingTask } from '~/app/shared/models/executing-task';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { NotificationsComponent } from './notifications.component';
+
+describe('NotificationsComponent', () => {
+ let component: NotificationsComponent;
+ let fixture: ComponentFixture<NotificationsComponent>;
+ let summaryService: SummaryService;
+ let notificationService: NotificationService;
+
+ configureTestBed({
+ imports: [HttpClientTestingModule, SharedModule, ToastrModule.forRoot(), RouterTestingModule],
+ declarations: [NotificationsComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(NotificationsComponent);
+ component = fixture.componentInstance;
+ summaryService = TestBed.inject(SummaryService);
+ notificationService = TestBed.inject(NotificationService);
+
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should subscribe and check if there are running tasks', () => {
+ expect(component.hasRunningTasks).toBeFalsy();
+
+ const task = new ExecutingTask('task', { name: 'name' });
+ summaryService['summaryDataSource'].next({ executing_tasks: [task] });
+
+ expect(component.hasRunningTasks).toBeTruthy();
+ });
+
+ it('should create a dot if there are running notifications', () => {
+ const notification = new CdNotification(new CdNotificationConfig());
+ const recent = notificationService['dataSource'].getValue();
+ recent.push(notification);
+ notificationService['dataSource'].next(recent);
+ expect(component.hasNotifications).toBeTruthy();
+ fixture.detectChanges();
+ const dot = fixture.debugElement.nativeElement.querySelector('.dot');
+ expect(dot).not.toBe('');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.ts
new file mode 100644
index 000000000..89c6c4037
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.ts
@@ -0,0 +1,47 @@
+import { Component, OnDestroy, OnInit } from '@angular/core';
+
+import { Subscription } from 'rxjs';
+
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdNotification } from '~/app/shared/models/cd-notification';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { SummaryService } from '~/app/shared/services/summary.service';
+
+@Component({
+ selector: 'cd-notifications',
+ templateUrl: './notifications.component.html',
+ styleUrls: ['./notifications.component.scss']
+})
+export class NotificationsComponent implements OnInit, OnDestroy {
+ icons = Icons;
+ hasRunningTasks = false;
+ hasNotifications = false;
+ private subs = new Subscription();
+
+ constructor(
+ public notificationService: NotificationService,
+ private summaryService: SummaryService
+ ) {}
+
+ ngOnInit() {
+ this.subs.add(
+ this.summaryService.subscribe((summary) => {
+ this.hasRunningTasks = summary.executing_tasks.length > 0;
+ })
+ );
+
+ this.subs.add(
+ this.notificationService.data$.subscribe((notifications: CdNotification[]) => {
+ this.hasNotifications = notifications.length > 0;
+ })
+ );
+ }
+
+ ngOnDestroy(): void {
+ this.subs.unsubscribe();
+ }
+
+ toggleSidebar() {
+ this.notificationService.toggleSidebar();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/api-client.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/api-client.spec.ts
new file mode 100644
index 000000000..0d521a889
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/api-client.spec.ts
@@ -0,0 +1,11 @@
+import { ApiClient } from '~/app/shared/api/api-client';
+
+class MockApiClient extends ApiClient {}
+
+describe('ApiClient', () => {
+ const service = new MockApiClient();
+
+ it('should get the version header value', () => {
+ expect(service.getVersionHeaderValue(1, 2)).toBe('application/vnd.ceph.api.v1.2+json');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/api-client.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/api-client.ts
new file mode 100644
index 000000000..06583eb10
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/api-client.ts
@@ -0,0 +1,5 @@
+export abstract class ApiClient {
+ getVersionHeaderValue(major: number, minor: number) {
+ return `application/vnd.ceph.api.v${major}.${minor}+json`;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/auth.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/auth.service.spec.ts
new file mode 100644
index 000000000..c32f0ea05
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/auth.service.spec.ts
@@ -0,0 +1,57 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { Router, Routes } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { AuthStorageService } from '../services/auth-storage.service';
+import { AuthService } from './auth.service';
+
+describe('AuthService', () => {
+ let service: AuthService;
+ let httpTesting: HttpTestingController;
+
+ const routes: Routes = [{ path: 'login', children: [] }];
+
+ configureTestBed({
+ providers: [AuthService, AuthStorageService],
+ imports: [HttpClientTestingModule, RouterTestingModule.withRoutes(routes)]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(AuthService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should login and save the user', fakeAsync(() => {
+ const fakeCredentials = { username: 'foo', password: 'bar' };
+ const fakeResponse = { username: 'foo' };
+ service.login(fakeCredentials).subscribe();
+ const req = httpTesting.expectOne('api/auth');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual(fakeCredentials);
+ req.flush(fakeResponse);
+ tick();
+ expect(localStorage.getItem('dashboard_username')).toBe('foo');
+ }));
+
+ it('should logout and remove the user', () => {
+ const router = TestBed.inject(Router);
+ spyOn(router, 'navigate').and.stub();
+
+ service.logout();
+ const req = httpTesting.expectOne('api/auth/logout');
+ expect(req.request.method).toBe('POST');
+ req.flush({ redirect_url: '#/login' });
+ expect(localStorage.getItem('dashboard_username')).toBe(null);
+ expect(router.navigate).toBeCalledTimes(1);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/auth.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/auth.service.ts
new file mode 100644
index 000000000..8a2917992
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/auth.service.ts
@@ -0,0 +1,53 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+
+import * as _ from 'lodash';
+import { Observable } from 'rxjs';
+import { tap } from 'rxjs/operators';
+
+import { Credentials } from '../models/credentials';
+import { LoginResponse } from '../models/login-response';
+import { AuthStorageService } from '../services/auth-storage.service';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class AuthService {
+ constructor(
+ private authStorageService: AuthStorageService,
+ private http: HttpClient,
+ private router: Router,
+ private route: ActivatedRoute
+ ) {}
+
+ check(token: string) {
+ return this.http.post('api/auth/check', { token: token });
+ }
+
+ login(credentials: Credentials): Observable<LoginResponse> {
+ return this.http.post('api/auth', credentials).pipe(
+ tap((resp: LoginResponse) => {
+ this.authStorageService.set(
+ resp.username,
+ resp.permissions,
+ resp.sso,
+ resp.pwdExpirationDate,
+ resp.pwdUpdateRequired
+ );
+ })
+ );
+ }
+
+ logout(callback: Function = null) {
+ return this.http.post('api/auth/logout', null).subscribe((resp: any) => {
+ this.authStorageService.remove();
+ const url = _.get(this.route.snapshot.queryParams, 'returnUrl', '/login');
+ this.router.navigate([url], { skipLocationChange: true });
+ if (callback) {
+ callback();
+ }
+ window.location.replace(resp.redirect_url);
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/ceph-service.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/ceph-service.service.ts
new file mode 100644
index 000000000..c62dfea7c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/ceph-service.service.ts
@@ -0,0 +1,63 @@
+import { HttpClient, HttpParams } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { Observable } from 'rxjs';
+
+import { Daemon } from '../models/daemon.interface';
+import { CephServiceSpec } from '../models/service.interface';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class CephServiceService {
+ private url = 'api/service';
+
+ constructor(private http: HttpClient) {}
+
+ list(serviceName?: string): Observable<CephServiceSpec[]> {
+ const options = serviceName
+ ? { params: new HttpParams().set('service_name', serviceName) }
+ : {};
+ return this.http.get<CephServiceSpec[]>(this.url, options);
+ }
+
+ getDaemons(serviceName?: string): Observable<Daemon[]> {
+ return this.http.get<Daemon[]>(`${this.url}/${serviceName}/daemons`);
+ }
+
+ create(serviceSpec: { [key: string]: any }) {
+ const serviceName = serviceSpec['service_id']
+ ? `${serviceSpec['service_type']}.${serviceSpec['service_id']}`
+ : serviceSpec['service_type'];
+ return this.http.post(
+ this.url,
+ {
+ service_name: serviceName,
+ service_spec: serviceSpec
+ },
+ { observe: 'response' }
+ );
+ }
+
+ update(serviceSpec: { [key: string]: any }) {
+ const serviceName = serviceSpec['service_id']
+ ? `${serviceSpec['service_type']}.${serviceSpec['service_id']}`
+ : serviceSpec['service_type'];
+ return this.http.put(
+ `${this.url}/${serviceName}`,
+ {
+ service_name: serviceName,
+ service_spec: serviceSpec
+ },
+ { observe: 'response' }
+ );
+ }
+
+ delete(serviceName: string) {
+ return this.http.delete(`${this.url}/${serviceName}`, { observe: 'response' });
+ }
+
+ getKnownTypes(): Observable<string[]> {
+ return this.http.get<string[]>(`${this.url}/known_types`);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/cephfs.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/cephfs.service.spec.ts
new file mode 100644
index 000000000..58395cd67
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/cephfs.service.spec.ts
@@ -0,0 +1,98 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { CephfsService } from './cephfs.service';
+
+describe('CephfsService', () => {
+ let service: CephfsService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ imports: [HttpClientTestingModule],
+ providers: [CephfsService]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(CephfsService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call list', () => {
+ service.list().subscribe();
+ const req = httpTesting.expectOne('api/cephfs');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call getCephfs', () => {
+ service.getCephfs(1).subscribe();
+ const req = httpTesting.expectOne('api/cephfs/1');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call getClients', () => {
+ service.getClients(1).subscribe();
+ const req = httpTesting.expectOne('api/cephfs/1/clients');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call getTabs', () => {
+ service.getTabs(2).subscribe();
+ const req = httpTesting.expectOne('ui-api/cephfs/2/tabs');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call getMdsCounters', () => {
+ service.getMdsCounters('1').subscribe();
+ const req = httpTesting.expectOne('api/cephfs/1/mds_counters');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call lsDir', () => {
+ service.lsDir(1).subscribe();
+ const req = httpTesting.expectOne('ui-api/cephfs/1/ls_dir?depth=2');
+ expect(req.request.method).toBe('GET');
+ service.lsDir(2, '/some/path').subscribe();
+ httpTesting.expectOne('ui-api/cephfs/2/ls_dir?depth=2&path=%252Fsome%252Fpath');
+ });
+
+ it('should call mkSnapshot', () => {
+ service.mkSnapshot(3, '/some/path').subscribe();
+ const req = httpTesting.expectOne('api/cephfs/3/snapshot?path=%252Fsome%252Fpath');
+ expect(req.request.method).toBe('POST');
+
+ service.mkSnapshot(4, '/some/other/path', 'snap').subscribe();
+ httpTesting.expectOne('api/cephfs/4/snapshot?path=%252Fsome%252Fother%252Fpath&name=snap');
+ });
+
+ it('should call rmSnapshot', () => {
+ service.rmSnapshot(1, '/some/path', 'snap').subscribe();
+ const req = httpTesting.expectOne('api/cephfs/1/snapshot?path=%252Fsome%252Fpath&name=snap');
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call updateQuota', () => {
+ service.quota(1, '/some/path', { max_bytes: 1024 }).subscribe();
+ let req = httpTesting.expectOne('api/cephfs/1/quota?path=%252Fsome%252Fpath');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({ max_bytes: 1024 });
+
+ service.quota(1, '/some/path', { max_files: 10 }).subscribe();
+ req = httpTesting.expectOne('api/cephfs/1/quota?path=%252Fsome%252Fpath');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({ max_files: 10 });
+
+ service.quota(1, '/some/path', { max_bytes: 1024, max_files: 10 }).subscribe();
+ req = httpTesting.expectOne('api/cephfs/1/quota?path=%252Fsome%252Fpath');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({ max_bytes: 1024, max_files: 10 });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/cephfs.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/cephfs.service.ts
new file mode 100644
index 000000000..02f31ca7b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/cephfs.service.ts
@@ -0,0 +1,76 @@
+import { HttpClient, HttpParams } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+import { Observable } from 'rxjs';
+
+import { cdEncode } from '../decorators/cd-encode';
+import { CephfsDir, CephfsQuotas } from '../models/cephfs-directory-models';
+
+@cdEncode
+@Injectable({
+ providedIn: 'root'
+})
+export class CephfsService {
+ baseURL = 'api/cephfs';
+ baseUiURL = 'ui-api/cephfs';
+
+ constructor(private http: HttpClient) {}
+
+ list() {
+ return this.http.get(`${this.baseURL}`);
+ }
+
+ lsDir(id: number, path?: string): Observable<CephfsDir[]> {
+ let apiPath = `${this.baseUiURL}/${id}/ls_dir?depth=2`;
+ if (path) {
+ apiPath += `&path=${encodeURIComponent(path)}`;
+ }
+ return this.http.get<CephfsDir[]>(apiPath);
+ }
+
+ getCephfs(id: number) {
+ return this.http.get(`${this.baseURL}/${id}`);
+ }
+
+ getTabs(id: number) {
+ return this.http.get(`ui-api/cephfs/${id}/tabs`);
+ }
+
+ getClients(id: number) {
+ return this.http.get(`${this.baseURL}/${id}/clients`);
+ }
+
+ evictClient(fsId: number, clientId: number) {
+ return this.http.delete(`${this.baseURL}/${fsId}/client/${clientId}`);
+ }
+
+ getMdsCounters(id: string) {
+ return this.http.get(`${this.baseURL}/${id}/mds_counters`);
+ }
+
+ mkSnapshot(id: number, path: string, name?: string) {
+ let params = new HttpParams();
+ params = params.append('path', path);
+ if (!_.isUndefined(name)) {
+ params = params.append('name', name);
+ }
+ return this.http.post(`${this.baseURL}/${id}/snapshot`, null, { params });
+ }
+
+ rmSnapshot(id: number, path: string, name: string) {
+ let params = new HttpParams();
+ params = params.append('path', path);
+ params = params.append('name', name);
+ return this.http.delete(`${this.baseURL}/${id}/snapshot`, { params });
+ }
+
+ quota(id: number, path: string, quotas: CephfsQuotas) {
+ let params = new HttpParams();
+ params = params.append('path', path);
+ return this.http.put(`${this.baseURL}/${id}/quota`, quotas, {
+ observe: 'response',
+ params
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/cluster.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/cluster.service.spec.ts
new file mode 100644
index 000000000..758f670ee
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/cluster.service.spec.ts
@@ -0,0 +1,42 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { fakeAsync, TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { ClusterService } from './cluster.service';
+
+describe('ClusterService', () => {
+ let service: ClusterService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ imports: [HttpClientTestingModule],
+ providers: [ClusterService]
+ });
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(ClusterService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call getStatus', () => {
+ service.getStatus().subscribe();
+ const req = httpTesting.expectOne('api/cluster');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should update cluster status', fakeAsync(() => {
+ service.updateStatus('fakeStatus').subscribe();
+ const req = httpTesting.expectOne('api/cluster');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({ status: 'fakeStatus' });
+ }));
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/cluster.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/cluster.service.ts
new file mode 100644
index 000000000..6b435d6ff
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/cluster.service.ts
@@ -0,0 +1,27 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { Observable } from 'rxjs';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class ClusterService {
+ baseURL = 'api/cluster';
+
+ constructor(private http: HttpClient) {}
+
+ getStatus(): Observable<string> {
+ return this.http.get<string>(`${this.baseURL}`, {
+ headers: { Accept: 'application/vnd.ceph.api.v0.1+json' }
+ });
+ }
+
+ updateStatus(status: string) {
+ return this.http.put(
+ `${this.baseURL}`,
+ { status: status },
+ { headers: { Accept: 'application/vnd.ceph.api.v0.1+json' } }
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/configuration.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/configuration.service.spec.ts
new file mode 100644
index 000000000..da05957a4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/configuration.service.spec.ts
@@ -0,0 +1,99 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { ConfigFormCreateRequestModel } from '~/app/ceph/cluster/configuration/configuration-form/configuration-form-create-request.model';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { ConfigurationService } from './configuration.service';
+
+describe('ConfigurationService', () => {
+ let service: ConfigurationService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [ConfigurationService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(ConfigurationService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call getConfigData', () => {
+ service.getConfigData().subscribe();
+ const req = httpTesting.expectOne('api/cluster_conf/');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call get', () => {
+ service.get('configOption').subscribe();
+ const req = httpTesting.expectOne('api/cluster_conf/configOption');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call create', () => {
+ const configOption = new ConfigFormCreateRequestModel();
+ configOption.name = 'Test option';
+ configOption.value = [
+ { section: 'section1', value: 'value1' },
+ { section: 'section2', value: 'value2' }
+ ];
+ service.create(configOption).subscribe();
+ const req = httpTesting.expectOne('api/cluster_conf/');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual(configOption);
+ });
+
+ it('should call bulkCreate', () => {
+ const configOptions = {
+ configOption1: { section: 'section', value: 'value' },
+ configOption2: { section: 'section', value: 'value' }
+ };
+ service.bulkCreate(configOptions).subscribe();
+ const req = httpTesting.expectOne('api/cluster_conf/');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual(configOptions);
+ });
+
+ it('should call filter', () => {
+ const configOptions = ['configOption1', 'configOption2', 'configOption3'];
+ service.filter(configOptions).subscribe();
+ const req = httpTesting.expectOne(
+ 'api/cluster_conf/filter?names=configOption1,configOption2,configOption3'
+ );
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call delete', () => {
+ service.delete('testOption', 'testSection').subscribe();
+ const reg = httpTesting.expectOne('api/cluster_conf/testOption?section=testSection');
+ expect(reg.request.method).toBe('DELETE');
+ });
+
+ it('should get value', () => {
+ const config = {
+ default: 'a',
+ value: [
+ { section: 'global', value: 'b' },
+ { section: 'mon', value: 'c' },
+ { section: 'mon.1', value: 'd' },
+ { section: 'mds', value: 'e' }
+ ]
+ };
+ expect(service.getValue(config, 'mon.1')).toBe('d');
+ expect(service.getValue(config, 'mon')).toBe('c');
+ expect(service.getValue(config, 'mds.1')).toBe('e');
+ expect(service.getValue(config, 'mds')).toBe('e');
+ expect(service.getValue(config, 'osd')).toBe('b');
+ config.value = [];
+ expect(service.getValue(config, 'osd')).toBe('a');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/configuration.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/configuration.service.ts
new file mode 100644
index 000000000..5bad098c9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/configuration.service.ts
@@ -0,0 +1,59 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { ConfigFormCreateRequestModel } from '~/app/ceph/cluster/configuration/configuration-form/configuration-form-create-request.model';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class ConfigurationService {
+ constructor(private http: HttpClient) {}
+
+ private findValue(config: any, section: string) {
+ if (!config.value) {
+ return undefined;
+ }
+ return config.value.find((v: any) => v.section === section);
+ }
+
+ getValue(config: any, section: string) {
+ let val = this.findValue(config, section);
+ if (!val) {
+ const indexOfDot = section.indexOf('.');
+ if (indexOfDot !== -1) {
+ val = this.findValue(config, section.substring(0, indexOfDot));
+ }
+ }
+ if (!val) {
+ val = this.findValue(config, 'global');
+ }
+ if (val) {
+ return val.value;
+ }
+ return config.default;
+ }
+
+ getConfigData() {
+ return this.http.get('api/cluster_conf/');
+ }
+
+ get(configOption: string) {
+ return this.http.get(`api/cluster_conf/${configOption}`);
+ }
+
+ filter(configOptionNames: Array<string>) {
+ return this.http.get(`api/cluster_conf/filter?names=${configOptionNames.join(',')}`);
+ }
+
+ create(configOption: ConfigFormCreateRequestModel) {
+ return this.http.post('api/cluster_conf/', configOption);
+ }
+
+ delete(configOption: string, section: string) {
+ return this.http.delete(`api/cluster_conf/${configOption}?section=${section}`);
+ }
+
+ bulkCreate(configOptions: object) {
+ return this.http.put('api/cluster_conf/', configOptions);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/crush-rule.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/crush-rule.service.spec.ts
new file mode 100644
index 000000000..1142e5368
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/crush-rule.service.spec.ts
@@ -0,0 +1,47 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { CrushRuleService } from './crush-rule.service';
+
+describe('CrushRuleService', () => {
+ let service: CrushRuleService;
+ let httpTesting: HttpTestingController;
+ const apiPath = 'api/crush_rule';
+
+ configureTestBed({
+ imports: [HttpClientTestingModule],
+ providers: [CrushRuleService]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(CrushRuleService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call create', () => {
+ service.create({ root: 'default', name: 'someRule', failure_domain: 'osd' }).subscribe();
+ const req = httpTesting.expectOne(apiPath);
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call delete', () => {
+ service.delete('test').subscribe();
+ const req = httpTesting.expectOne(`${apiPath}/test`);
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call getInfo', () => {
+ service.getInfo().subscribe();
+ const req = httpTesting.expectOne(`ui-${apiPath}/info`);
+ expect(req.request.method).toBe('GET');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/crush-rule.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/crush-rule.service.ts
new file mode 100644
index 000000000..e4e7bb605
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/crush-rule.service.ts
@@ -0,0 +1,32 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { CrushRuleConfig } from '../models/crush-rule';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class CrushRuleService {
+ apiPath = 'api/crush_rule';
+
+ formTooltips = {
+ // Copied from /doc/rados/operations/crush-map.rst
+ root: $localize`The name of the node under which data should be placed.`,
+ failure_domain: $localize`The type of CRUSH nodes across which we should separate replicas.`,
+ device_class: $localize`The device class data should be placed on.`
+ };
+
+ constructor(private http: HttpClient) {}
+
+ create(rule: CrushRuleConfig) {
+ return this.http.post(this.apiPath, rule, { observe: 'response' });
+ }
+
+ delete(name: string) {
+ return this.http.delete(`${this.apiPath}/${name}`, { observe: 'response' });
+ }
+
+ getInfo() {
+ return this.http.get(`ui-${this.apiPath}/info`);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/custom-login-banner.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/custom-login-banner.service.spec.ts
new file mode 100644
index 000000000..d1db441c7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/custom-login-banner.service.spec.ts
@@ -0,0 +1,35 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { CustomLoginBannerService } from './custom-login-banner.service';
+
+describe('CustomLoginBannerService', () => {
+ let service: CustomLoginBannerService;
+ let httpTesting: HttpTestingController;
+ const baseUiURL = 'ui-api/login/custom_banner';
+
+ configureTestBed({
+ providers: [CustomLoginBannerService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(CustomLoginBannerService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call getBannerText', () => {
+ service.getBannerText().subscribe();
+ const req = httpTesting.expectOne(baseUiURL);
+ expect(req.request.method).toBe('GET');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/custom-login-banner.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/custom-login-banner.service.ts
new file mode 100644
index 000000000..7c499eb13
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/custom-login-banner.service.ts
@@ -0,0 +1,15 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class CustomLoginBannerService {
+ baseUiURL = 'ui-api/login/custom_banner';
+
+ constructor(private http: HttpClient) {}
+
+ getBannerText() {
+ return this.http.get<string>(this.baseUiURL);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/daemon.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/daemon.service.spec.ts
new file mode 100644
index 000000000..787e5db7c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/daemon.service.spec.ts
@@ -0,0 +1,39 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { DaemonService } from './daemon.service';
+
+describe('DaemonService', () => {
+ let service: DaemonService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [DaemonService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(DaemonService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call action', () => {
+ const put_data: any = {
+ action: 'start',
+ container_image: null
+ };
+ service.action('osd.1', 'start').subscribe();
+ const req = httpTesting.expectOne('api/daemon/osd.1');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual(put_data);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/daemon.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/daemon.service.ts
new file mode 100644
index 000000000..a66ed7edb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/daemon.service.ts
@@ -0,0 +1,28 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { cdEncode } from '~/app/shared/decorators/cd-encode';
+
+@cdEncode
+@Injectable({
+ providedIn: 'root'
+})
+export class DaemonService {
+ private url = 'api/daemon';
+
+ constructor(private http: HttpClient) {}
+
+ action(daemonName: string, actionType: string) {
+ return this.http.put(
+ `${this.url}/${daemonName}`,
+ {
+ action: actionType,
+ container_image: null
+ },
+ {
+ headers: { Accept: 'application/vnd.ceph.api.v0.1+json' },
+ observe: 'response'
+ }
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/erasure-code-profile.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/erasure-code-profile.service.spec.ts
new file mode 100644
index 000000000..caf3da0c6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/erasure-code-profile.service.spec.ts
@@ -0,0 +1,55 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { ErasureCodeProfile } from '../models/erasure-code-profile';
+import { ErasureCodeProfileService } from './erasure-code-profile.service';
+
+describe('ErasureCodeProfileService', () => {
+ let service: ErasureCodeProfileService;
+ let httpTesting: HttpTestingController;
+ const apiPath = 'api/erasure_code_profile';
+ const testProfile: ErasureCodeProfile = { name: 'test', plugin: 'jerasure', k: 2, m: 1 };
+
+ configureTestBed({
+ imports: [HttpClientTestingModule],
+ providers: [ErasureCodeProfileService]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(ErasureCodeProfileService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call list', () => {
+ service.list().subscribe();
+ const req = httpTesting.expectOne(apiPath);
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call create', () => {
+ service.create(testProfile).subscribe();
+ const req = httpTesting.expectOne(apiPath);
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call delete', () => {
+ service.delete('test').subscribe();
+ const req = httpTesting.expectOne(`${apiPath}/test`);
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call getInfo', () => {
+ service.getInfo().subscribe();
+ const req = httpTesting.expectOne(`ui-${apiPath}/info`);
+ expect(req.request.method).toBe('GET');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/erasure-code-profile.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/erasure-code-profile.service.ts
new file mode 100644
index 000000000..d2bd131a4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/erasure-code-profile.service.ts
@@ -0,0 +1,110 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { Observable } from 'rxjs';
+
+import { ErasureCodeProfile } from '../models/erasure-code-profile';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class ErasureCodeProfileService {
+ apiPath = 'api/erasure_code_profile';
+
+ formTooltips = {
+ // Copied from /doc/rados/operations/erasure-code.*.rst
+ k: $localize`Each object is split in data-chunks parts, each stored on a different OSD.`,
+
+ m: $localize`Compute coding chunks for each object and store them on different OSDs.
+ The number of coding chunks is also the number of OSDs that can be down without losing data.`,
+
+ plugins: {
+ jerasure: {
+ description: $localize`The jerasure plugin is the most generic and flexible plugin,
+ it is also the default for Ceph erasure coded pools.`,
+ technique: $localize`The more flexible technique is reed_sol_van : it is enough to set k
+ and m. The cauchy_good technique can be faster but you need to chose the packetsize
+ carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents
+ in the sense that they can only be configured with m=2.`,
+ packetSize: $localize`The encoding will be done on packets of bytes size at a time.
+ Choosing the right packet size is difficult.
+ The jerasure documentation contains extensive information on this topic.`
+ },
+ lrc: {
+ description: $localize`With the jerasure plugin, when an erasure coded object is stored on
+ multiple OSDs, recovering from the loss of one OSD requires reading from all the others.
+ For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading
+ from the eleven others to repair.
+
+ The lrc erasure code plugin creates local parity chunks to be able to recover using
+ less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create
+ an additional parity chunk for every four OSDs. When a single OSD is lost, it can be
+ recovered with only four OSDs instead of eleven.`,
+ l: $localize`Group the coding and data chunks into sets of size locality. For instance,
+ for k=4 and m=2, when locality=3 two groups of three are created. Each set can
+ be recovered without reading chunks from another set.`,
+ crushLocality: $localize`The type of the crush bucket in which each set of chunks defined
+ by l will be stored. For instance, if it is set to rack, each group of l chunks will be
+ placed in a different rack. It is used to create a CRUSH rule step such as step choose
+ rack. If it is not set, no such grouping is done.`
+ },
+ isa: {
+ description: $localize`The isa plugin encapsulates the ISA library. It only runs on Intel processors.`,
+ technique: $localize`The ISA plugin comes in two Reed Solomon forms.
+ If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.`
+ },
+ shec: {
+ description: $localize`The shec plugin encapsulates the multiple SHEC library.
+ It allows ceph to recover data more efficiently than Reed Solomon codes.`,
+ c: $localize`The number of parity chunks each of which includes each data chunk in its
+ calculation range. The number is used as a durability estimator. For instance, if c=2,
+ 2 OSDs can be down without losing data.`
+ },
+ clay: {
+ description: $localize`CLAY (short for coupled-layer) codes are erasure codes designed to
+ bring about significant savings in terms of network bandwidth and disk IO when a failed
+ node/OSD/rack is being repaired.`,
+ d: $localize`Number of OSDs requested to send data during recovery of a single chunk.
+ d needs to be chosen such that k+1 <= d <= k+m-1. The larger the d, the better
+ the savings.`,
+ scalar_mds: $localize`scalar_mds specifies the plugin that is used as a building block
+ in the layered construction. It can be one of jerasure, isa, shec.`,
+ technique: $localize`technique specifies the technique that will be picked
+ within the 'scalar_mds' plugin specified. Supported techniques
+ are 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good', 'liber8tion' for jerasure, 'reed_sol_van',
+ 'cauchy' for isa and 'single', 'multiple' for shec.`
+ }
+ },
+
+ crushRoot: $localize`The name of the crush bucket used for the first step of the CRUSH rule.
+ For instance step take default.`,
+
+ crushFailureDomain: $localize`Ensure that no two chunks are in a bucket with the same failure
+ domain. For instance, if the failure domain is host no two chunks will be stored on the same
+ host. It is used to create a CRUSH rule step such as step chooseleaf host.`,
+
+ crushDeviceClass: $localize`Restrict placement to devices of a specific class
+ (e.g., ssd or hdd), using the crush device class names in the CRUSH map.`,
+
+ directory: $localize`Set the directory name from which the erasure code plugin is loaded.`
+ };
+
+ constructor(private http: HttpClient) {}
+
+ list(): Observable<ErasureCodeProfile[]> {
+ return this.http.get<ErasureCodeProfile[]>(this.apiPath);
+ }
+
+ create(ecp: ErasureCodeProfile) {
+ return this.http.post(this.apiPath, ecp, { observe: 'response' });
+ }
+
+ delete(name: string) {
+ return this.http.delete(`${this.apiPath}/${name}`, { observe: 'response' });
+ }
+
+ getInfo() {
+ return this.http.get(`ui-${this.apiPath}/info`);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/health.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/health.service.spec.ts
new file mode 100644
index 000000000..84eeac0f3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/health.service.spec.ts
@@ -0,0 +1,40 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { HealthService } from './health.service';
+
+describe('HealthService', () => {
+ let service: HealthService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [HealthService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(HealthService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call getFullHealth', () => {
+ service.getFullHealth().subscribe();
+ const req = httpTesting.expectOne('api/health/full');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call getMinimalHealth', () => {
+ service.getMinimalHealth().subscribe();
+ const req = httpTesting.expectOne('api/health/minimal');
+ expect(req.request.method).toBe('GET');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/health.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/health.service.ts
new file mode 100644
index 000000000..a8f7c467a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/health.service.ts
@@ -0,0 +1,17 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class HealthService {
+ constructor(private http: HttpClient) {}
+
+ getFullHealth() {
+ return this.http.get('api/health/full');
+ }
+
+ getMinimalHealth() {
+ return this.http.get('api/health/minimal');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/host.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/host.service.spec.ts
new file mode 100644
index 000000000..e4b6476f2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/host.service.spec.ts
@@ -0,0 +1,91 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { HostService } from './host.service';
+
+describe('HostService', () => {
+ let service: HostService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [HostService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(HostService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call list', fakeAsync(() => {
+ let result;
+ service.list('true').subscribe((resp) => (result = resp));
+ const req = httpTesting.expectOne('api/host?facts=true');
+ expect(req.request.method).toBe('GET');
+ req.flush(['foo', 'bar']);
+ tick();
+ expect(result).toEqual(['foo', 'bar']);
+ }));
+
+ it('should make a GET request on the devices endpoint when requesting devices', () => {
+ const hostname = 'hostname';
+ service.getDevices(hostname).subscribe();
+ const req = httpTesting.expectOne(`api/host/${hostname}/devices`);
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should update host', fakeAsync(() => {
+ service.update('mon0', true, ['foo', 'bar'], true, false).subscribe();
+ const req = httpTesting.expectOne('api/host/mon0');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({
+ force: false,
+ labels: ['foo', 'bar'],
+ maintenance: true,
+ update_labels: true,
+ drain: false
+ });
+ }));
+
+ it('should test host drain call', fakeAsync(() => {
+ service.update('host0', false, null, false, false, true).subscribe();
+ const req = httpTesting.expectOne('api/host/host0');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({
+ force: false,
+ labels: null,
+ maintenance: false,
+ update_labels: false,
+ drain: true
+ });
+ }));
+
+ it('should call getInventory', () => {
+ service.getInventory('host-0').subscribe();
+ let req = httpTesting.expectOne('api/host/host-0/inventory');
+ expect(req.request.method).toBe('GET');
+
+ service.getInventory('host-0', true).subscribe();
+ req = httpTesting.expectOne('api/host/host-0/inventory?refresh=true');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call inventoryList', () => {
+ service.inventoryList().subscribe();
+ let req = httpTesting.expectOne('ui-api/host/inventory');
+ expect(req.request.method).toBe('GET');
+
+ service.inventoryList(true).subscribe();
+ req = httpTesting.expectOne('ui-api/host/inventory?refresh=true');
+ expect(req.request.method).toBe('GET');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/host.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/host.service.ts
new file mode 100644
index 000000000..d13f41527
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/host.service.ts
@@ -0,0 +1,154 @@
+import { HttpClient, HttpParams } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+import { Observable, of as observableOf } from 'rxjs';
+import { map, mergeMap, toArray } from 'rxjs/operators';
+
+import { InventoryDevice } from '~/app/ceph/cluster/inventory/inventory-devices/inventory-device.model';
+import { InventoryHost } from '~/app/ceph/cluster/inventory/inventory-host.model';
+import { ApiClient } from '~/app/shared/api/api-client';
+import { CdHelperClass } from '~/app/shared/classes/cd-helper.class';
+import { Daemon } from '../models/daemon.interface';
+import { CdDevice } from '../models/devices';
+import { SmartDataResponseV1 } from '../models/smart';
+import { DeviceService } from '../services/device.service';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class HostService extends ApiClient {
+ baseURL = 'api/host';
+ baseUIURL = 'ui-api/host';
+
+ predefinedLabels = ['mon', 'mgr', 'osd', 'mds', 'rgw', 'nfs', 'iscsi', 'rbd', 'grafana'];
+
+ constructor(private http: HttpClient, private deviceService: DeviceService) {
+ super();
+ }
+
+ list(facts: string): Observable<object[]> {
+ return this.http.get<object[]>(this.baseURL, {
+ headers: { Accept: 'application/vnd.ceph.api.v1.1+json' },
+ params: { facts: facts }
+ });
+ }
+
+ create(hostname: string, addr: string, labels: string[], status: string) {
+ return this.http.post(
+ this.baseURL,
+ { hostname: hostname, addr: addr, labels: labels, status: status },
+ { observe: 'response', headers: { Accept: CdHelperClass.cdVersionHeader('0', '1') } }
+ );
+ }
+
+ delete(hostname: string) {
+ return this.http.delete(`${this.baseURL}/${hostname}`, { observe: 'response' });
+ }
+
+ getDevices(hostname: string): Observable<CdDevice[]> {
+ return this.http
+ .get<CdDevice[]>(`${this.baseURL}/${hostname}/devices`)
+ .pipe(map((devices) => devices.map((device) => this.deviceService.prepareDevice(device))));
+ }
+
+ getSmartData(hostname: string) {
+ return this.http.get<SmartDataResponseV1>(`${this.baseURL}/${hostname}/smart`);
+ }
+
+ getDaemons(hostname: string): Observable<Daemon[]> {
+ return this.http.get<Daemon[]>(`${this.baseURL}/${hostname}/daemons`);
+ }
+
+ getLabels(): Observable<string[]> {
+ return this.http.get<string[]>(`${this.baseUIURL}/labels`);
+ }
+
+ update(
+ hostname: string,
+ updateLabels = false,
+ labels: string[] = [],
+ maintenance = false,
+ force = false,
+ drain = false
+ ) {
+ return this.http.put(
+ `${this.baseURL}/${hostname}`,
+ {
+ update_labels: updateLabels,
+ labels: labels,
+ maintenance: maintenance,
+ force: force,
+ drain: drain
+ },
+ { headers: { Accept: this.getVersionHeaderValue(0, 1) } }
+ );
+ }
+
+ identifyDevice(hostname: string, device: string, duration: number) {
+ return this.http.post(`${this.baseURL}/${hostname}/identify_device`, {
+ device,
+ duration
+ });
+ }
+
+ private getInventoryParams(refresh?: boolean): HttpParams {
+ let params = new HttpParams();
+ if (refresh) {
+ params = params.append('refresh', _.toString(refresh));
+ }
+ return params;
+ }
+
+ /**
+ * Get inventory of a host.
+ *
+ * @param hostname the host query.
+ * @param refresh true to ask the Orchestrator to refresh inventory.
+ */
+ getInventory(hostname: string, refresh?: boolean): Observable<InventoryHost> {
+ const params = this.getInventoryParams(refresh);
+ return this.http.get<InventoryHost>(`${this.baseURL}/${hostname}/inventory`, {
+ params: params
+ });
+ }
+
+ /**
+ * Get inventories of all hosts.
+ *
+ * @param refresh true to ask the Orchestrator to refresh inventory.
+ */
+ inventoryList(refresh?: boolean): Observable<InventoryHost[]> {
+ const params = this.getInventoryParams(refresh);
+ return this.http.get<InventoryHost[]>(`${this.baseUIURL}/inventory`, { params: params });
+ }
+
+ /**
+ * Get device list via host inventories.
+ *
+ * @param hostname the host to query. undefined for all hosts.
+ * @param refresh true to ask the Orchestrator to refresh inventory.
+ */
+ inventoryDeviceList(hostname?: string, refresh?: boolean): Observable<InventoryDevice[]> {
+ let observable;
+ if (hostname) {
+ observable = this.getInventory(hostname, refresh).pipe(toArray());
+ } else {
+ observable = this.inventoryList(refresh);
+ }
+ return observable.pipe(
+ mergeMap((hosts: InventoryHost[]) => {
+ const devices = _.flatMap(hosts, (host) => {
+ return host.devices.map((device) => {
+ device.hostname = host.name;
+ device.uid = device.device_id
+ ? `${device.device_id}-${device.hostname}-${device.path}`
+ : `${device.hostname}-${device.path}`;
+ return device;
+ });
+ });
+ return observableOf(devices);
+ })
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/iscsi.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/iscsi.service.spec.ts
new file mode 100644
index 000000000..fcb1804a6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/iscsi.service.spec.ts
@@ -0,0 +1,97 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { IscsiService } from './iscsi.service';
+
+describe('IscsiService', () => {
+ let service: IscsiService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [IscsiService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(IscsiService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call listTargets', () => {
+ service.listTargets().subscribe();
+ const req = httpTesting.expectOne('api/iscsi/target');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call getTarget', () => {
+ service.getTarget('iqn.foo').subscribe();
+ const req = httpTesting.expectOne('api/iscsi/target/iqn.foo');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call status', () => {
+ service.status().subscribe();
+ const req = httpTesting.expectOne('ui-api/iscsi/status');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call settings', () => {
+ service.settings().subscribe();
+ const req = httpTesting.expectOne('ui-api/iscsi/settings');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call portals', () => {
+ service.portals().subscribe();
+ const req = httpTesting.expectOne('ui-api/iscsi/portals');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call createTarget', () => {
+ service.createTarget({ target_iqn: 'foo' }).subscribe();
+ const req = httpTesting.expectOne('api/iscsi/target');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual({ target_iqn: 'foo' });
+ });
+
+ it('should call updateTarget', () => {
+ service.updateTarget('iqn.foo', { target_iqn: 'foo' }).subscribe();
+ const req = httpTesting.expectOne('api/iscsi/target/iqn.foo');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({ target_iqn: 'foo' });
+ });
+
+ it('should call deleteTarget', () => {
+ service.deleteTarget('target_iqn').subscribe();
+ const req = httpTesting.expectOne('api/iscsi/target/target_iqn');
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call getDiscovery', () => {
+ service.getDiscovery().subscribe();
+ const req = httpTesting.expectOne('api/iscsi/discoveryauth');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call updateDiscovery', () => {
+ service
+ .updateDiscovery({
+ user: 'foo',
+ password: 'bar',
+ mutual_user: 'mutual_foo',
+ mutual_password: 'mutual_bar'
+ })
+ .subscribe();
+ const req = httpTesting.expectOne('api/iscsi/discoveryauth');
+ expect(req.request.method).toBe('PUT');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/iscsi.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/iscsi.service.ts
new file mode 100644
index 000000000..9ef0310c7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/iscsi.service.ts
@@ -0,0 +1,60 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { cdEncode } from '../decorators/cd-encode';
+
+@cdEncode
+@Injectable({
+ providedIn: 'root'
+})
+export class IscsiService {
+ constructor(private http: HttpClient) {}
+
+ listTargets() {
+ return this.http.get(`api/iscsi/target`);
+ }
+
+ getTarget(target_iqn: string) {
+ return this.http.get(`api/iscsi/target/${target_iqn}`);
+ }
+
+ updateTarget(target_iqn: string, target: any) {
+ return this.http.put(`api/iscsi/target/${target_iqn}`, target, { observe: 'response' });
+ }
+
+ status() {
+ return this.http.get(`ui-api/iscsi/status`);
+ }
+
+ settings() {
+ return this.http.get(`ui-api/iscsi/settings`);
+ }
+
+ version() {
+ return this.http.get(`ui-api/iscsi/version`);
+ }
+
+ portals() {
+ return this.http.get(`ui-api/iscsi/portals`);
+ }
+
+ createTarget(target: any) {
+ return this.http.post(`api/iscsi/target`, target, { observe: 'response' });
+ }
+
+ deleteTarget(target_iqn: string) {
+ return this.http.delete(`api/iscsi/target/${target_iqn}`, { observe: 'response' });
+ }
+
+ getDiscovery() {
+ return this.http.get(`api/iscsi/discoveryauth`);
+ }
+
+ updateDiscovery(auth: any) {
+ return this.http.put(`api/iscsi/discoveryauth`, auth);
+ }
+
+ overview() {
+ return this.http.get(`ui-api/iscsi/overview`);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/logging.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/logging.service.spec.ts
new file mode 100644
index 000000000..6458827f0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/logging.service.spec.ts
@@ -0,0 +1,39 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { LoggingService } from './logging.service';
+
+describe('LoggingService', () => {
+ let service: LoggingService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [LoggingService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(LoggingService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call jsError', () => {
+ service.jsError('foo', 'bar', 'baz').subscribe();
+ const req = httpTesting.expectOne('ui-api/logging/js-error');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual({
+ url: 'foo',
+ message: 'bar',
+ stack: 'baz'
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/logging.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/logging.service.ts
new file mode 100644
index 000000000..85846946b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/logging.service.ts
@@ -0,0 +1,18 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class LoggingService {
+ constructor(private http: HttpClient) {}
+
+ jsError(url: string, message: string, stack: any) {
+ const request = {
+ url: url,
+ message: message,
+ stack: stack
+ };
+ return this.http.post('ui-api/logging/js-error', request);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/logs.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/logs.service.spec.ts
new file mode 100644
index 000000000..82c12dad8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/logs.service.spec.ts
@@ -0,0 +1,34 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { LogsService } from './logs.service';
+
+describe('LogsService', () => {
+ let service: LogsService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [LogsService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(LogsService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call getLogs', () => {
+ service.getLogs().subscribe();
+ const req = httpTesting.expectOne('api/logs/all');
+ expect(req.request.method).toBe('GET');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/logs.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/logs.service.ts
new file mode 100644
index 000000000..252769dbd
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/logs.service.ts
@@ -0,0 +1,17 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class LogsService {
+ constructor(private http: HttpClient) {}
+
+ getLogs() {
+ return this.http.get('api/logs/all');
+ }
+
+ validateDashboardUrl(uid: string) {
+ return this.http.get(`api/grafana/validation/${uid}`);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/mgr-module.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/mgr-module.service.spec.ts
new file mode 100644
index 000000000..77e6fb221
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/mgr-module.service.spec.ts
@@ -0,0 +1,66 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { MgrModuleService } from './mgr-module.service';
+
+describe('MgrModuleService', () => {
+ let service: MgrModuleService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ imports: [HttpClientTestingModule],
+ providers: [MgrModuleService]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(MgrModuleService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call list', () => {
+ service.list().subscribe();
+ const req = httpTesting.expectOne('api/mgr/module');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call getConfig', () => {
+ service.getConfig('foo').subscribe();
+ const req = httpTesting.expectOne('api/mgr/module/foo');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call updateConfig', () => {
+ const config = { foo: 'bar' };
+ service.updateConfig('xyz', config).subscribe();
+ const req = httpTesting.expectOne('api/mgr/module/xyz');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body.config).toEqual(config);
+ });
+
+ it('should call enable', () => {
+ service.enable('foo').subscribe();
+ const req = httpTesting.expectOne('api/mgr/module/foo/enable');
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call disable', () => {
+ service.disable('bar').subscribe();
+ const req = httpTesting.expectOne('api/mgr/module/bar/disable');
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call getOptions', () => {
+ service.getOptions('foo').subscribe();
+ const req = httpTesting.expectOne('api/mgr/module/foo/options');
+ expect(req.request.method).toBe('GET');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/mgr-module.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/mgr-module.service.ts
new file mode 100644
index 000000000..3942a1a44
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/mgr-module.service.ts
@@ -0,0 +1,65 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { Observable } from 'rxjs';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class MgrModuleService {
+ private url = 'api/mgr/module';
+
+ constructor(private http: HttpClient) {}
+
+ /**
+ * Get the list of Ceph Mgr modules and their state (enabled/disabled).
+ * @return {Observable<Object[]>}
+ */
+ list(): Observable<Object[]> {
+ return this.http.get<Object[]>(`${this.url}`);
+ }
+
+ /**
+ * Get the Ceph Mgr module configuration.
+ * @param {string} module The name of the mgr module.
+ * @return {Observable<Object>}
+ */
+ getConfig(module: string): Observable<Object> {
+ return this.http.get(`${this.url}/${module}`);
+ }
+
+ /**
+ * Update the Ceph Mgr module configuration.
+ * @param {string} module The name of the mgr module.
+ * @param {object} config The configuration.
+ * @return {Observable<Object>}
+ */
+ updateConfig(module: string, config: object): Observable<Object> {
+ return this.http.put(`${this.url}/${module}`, { config: config });
+ }
+
+ /**
+ * Enable the Ceph Mgr module.
+ * @param {string} module The name of the mgr module.
+ */
+ enable(module: string) {
+ return this.http.post(`${this.url}/${module}/enable`, null);
+ }
+
+ /**
+ * Disable the Ceph Mgr module.
+ * @param {string} module The name of the mgr module.
+ */
+ disable(module: string) {
+ return this.http.post(`${this.url}/${module}/disable`, null);
+ }
+
+ /**
+ * Get the Ceph Mgr module options.
+ * @param {string} module The name of the mgr module.
+ * @return {Observable<Object>}
+ */
+ getOptions(module: string): Observable<Object> {
+ return this.http.get(`${this.url}/${module}/options`);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/monitor.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/monitor.service.spec.ts
new file mode 100644
index 000000000..29396866d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/monitor.service.spec.ts
@@ -0,0 +1,34 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { MonitorService } from './monitor.service';
+
+describe('MonitorService', () => {
+ let service: MonitorService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [MonitorService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(MonitorService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call getMonitor', () => {
+ service.getMonitor().subscribe();
+ const req = httpTesting.expectOne('api/monitor');
+ expect(req.request.method).toBe('GET');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/monitor.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/monitor.service.ts
new file mode 100644
index 000000000..42ca9a7af
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/monitor.service.ts
@@ -0,0 +1,13 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class MonitorService {
+ constructor(private http: HttpClient) {}
+
+ getMonitor() {
+ return this.http.get('api/monitor');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/motd.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/motd.service.spec.ts
new file mode 100644
index 000000000..e186e8423
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/motd.service.spec.ts
@@ -0,0 +1,34 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { MotdService } from '~/app/shared/api/motd.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+
+describe('MotdService', () => {
+ let service: MotdService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ imports: [HttpClientTestingModule],
+ providers: [MotdService]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(MotdService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should get MOTD', () => {
+ service.get().subscribe();
+ const req = httpTesting.expectOne('ui-api/motd');
+ expect(req.request.method).toBe('GET');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/motd.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/motd.service.ts
new file mode 100644
index 000000000..dd17b2e04
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/motd.service.ts
@@ -0,0 +1,25 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { Observable } from 'rxjs';
+
+export interface Motd {
+ message: string;
+ md5: string;
+ severity: 'info' | 'warning' | 'danger';
+ // The expiration date in ISO 8601. Does not expire if empty.
+ expires: string;
+}
+
+@Injectable({
+ providedIn: 'root'
+})
+export class MotdService {
+ private url = 'ui-api/motd';
+
+ constructor(private http: HttpClient) {}
+
+ get(): Observable<Motd | null> {
+ return this.http.get<Motd | null>(this.url);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/nfs.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/nfs.service.spec.ts
new file mode 100644
index 000000000..139fa490b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/nfs.service.spec.ts
@@ -0,0 +1,74 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { NfsService } from './nfs.service';
+
+describe('NfsService', () => {
+ let service: NfsService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [NfsService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(NfsService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call list', () => {
+ service.list().subscribe();
+ const req = httpTesting.expectOne('api/nfs-ganesha/export');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call get', () => {
+ service.get('cluster_id', 'export_id').subscribe();
+ const req = httpTesting.expectOne('api/nfs-ganesha/export/cluster_id/export_id');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call create', () => {
+ service.create('foo').subscribe();
+ const req = httpTesting.expectOne('api/nfs-ganesha/export');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual('foo');
+ });
+
+ it('should call update', () => {
+ service.update('cluster_id', 1, 'foo').subscribe();
+ const req = httpTesting.expectOne('api/nfs-ganesha/export/cluster_id/1');
+ expect(req.request.body).toEqual('foo');
+ expect(req.request.method).toBe('PUT');
+ });
+
+ it('should call delete', () => {
+ service.delete('hostName', 'exportId').subscribe();
+ const req = httpTesting.expectOne('api/nfs-ganesha/export/hostName/exportId');
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call lsDir', () => {
+ service.lsDir('a', 'foo_dir').subscribe();
+ const req = httpTesting.expectOne('ui-api/nfs-ganesha/lsdir/a?root_dir=foo_dir');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should not call lsDir if volume is not provided', fakeAsync(() => {
+ service.lsDir('', 'foo_dir').subscribe({
+ error: (error: string) => expect(error).toEqual('Please specify a filesystem volume.')
+ });
+ tick();
+ httpTesting.expectNone('ui-api/nfs-ganesha/lsdir/?root_dir=foo_dir');
+ }));
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/nfs.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/nfs.service.ts
new file mode 100644
index 000000000..9b4e4a0a2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/nfs.service.ts
@@ -0,0 +1,108 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { Observable, throwError } from 'rxjs';
+
+import { NfsFSAbstractionLayer } from '~/app/ceph/nfs/models/nfs.fsal';
+import { ApiClient } from '~/app/shared/api/api-client';
+
+export interface Directory {
+ paths: string[];
+}
+
+@Injectable({
+ providedIn: 'root'
+})
+export class NfsService extends ApiClient {
+ apiPath = 'api/nfs-ganesha';
+ uiApiPath = 'ui-api/nfs-ganesha';
+
+ nfsAccessType = [
+ {
+ value: 'RW',
+ help: $localize`Allows all operations`
+ },
+ {
+ value: 'RO',
+ help: $localize`Allows only operations that do not modify the server`
+ },
+ {
+ value: 'NONE',
+ help: $localize`Allows no access at all`
+ }
+ ];
+
+ nfsFsal: NfsFSAbstractionLayer[] = [
+ {
+ value: 'CEPH',
+ descr: $localize`CephFS`,
+ disabled: false
+ },
+ {
+ value: 'RGW',
+ descr: $localize`Object Gateway`,
+ disabled: false
+ }
+ ];
+
+ nfsSquash = {
+ no_root_squash: ['no_root_squash', 'noidsquash', 'none'],
+ root_id_squash: ['root_id_squash', 'rootidsquash', 'rootid'],
+ root_squash: ['root_squash', 'rootsquash', 'root'],
+ all_squash: ['all_squash', 'allsquash', 'all', 'allanonymous', 'all_anonymous']
+ };
+
+ constructor(private http: HttpClient) {
+ super();
+ }
+
+ list() {
+ return this.http.get(`${this.apiPath}/export`);
+ }
+
+ get(clusterId: string, exportId: string) {
+ return this.http.get(`${this.apiPath}/export/${clusterId}/${exportId}`);
+ }
+
+ create(nfs: any) {
+ return this.http.post(`${this.apiPath}/export`, nfs, {
+ headers: { Accept: this.getVersionHeaderValue(2, 0) },
+ observe: 'response'
+ });
+ }
+
+ update(clusterId: string, id: number, nfs: any) {
+ return this.http.put(`${this.apiPath}/export/${clusterId}/${id}`, nfs, {
+ headers: { Accept: this.getVersionHeaderValue(2, 0) },
+ observe: 'response'
+ });
+ }
+
+ delete(clusterId: string, exportId: string) {
+ return this.http.delete(`${this.apiPath}/export/${clusterId}/${exportId}`, {
+ headers: { Accept: this.getVersionHeaderValue(2, 0) },
+ observe: 'response'
+ });
+ }
+
+ listClusters() {
+ return this.http.get(`${this.apiPath}/cluster`, {
+ headers: { Accept: this.getVersionHeaderValue(0, 1) }
+ });
+ }
+
+ lsDir(fs_name: string, root_dir: string): Observable<Directory> {
+ if (!fs_name) {
+ return throwError($localize`Please specify a filesystem volume.`);
+ }
+ return this.http.get<Directory>(`${this.uiApiPath}/lsdir/${fs_name}?root_dir=${root_dir}`);
+ }
+
+ fsals() {
+ return this.http.get(`${this.uiApiPath}/fsals`);
+ }
+
+ filesystems() {
+ return this.http.get(`${this.uiApiPath}/cephfs/filesystems`);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/orchestrator.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/orchestrator.service.spec.ts
new file mode 100644
index 000000000..c49cb8b0d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/orchestrator.service.spec.ts
@@ -0,0 +1,35 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { OrchestratorService } from './orchestrator.service';
+
+describe('OrchestratorService', () => {
+ let service: OrchestratorService;
+ let httpTesting: HttpTestingController;
+ const uiApiPath = 'ui-api/orchestrator';
+
+ configureTestBed({
+ providers: [OrchestratorService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(OrchestratorService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call status', () => {
+ service.status().subscribe();
+ const req = httpTesting.expectOne(`${uiApiPath}/status`);
+ expect(req.request.method).toBe('GET');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/orchestrator.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/orchestrator.service.ts
new file mode 100644
index 000000000..a6e33e834
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/orchestrator.service.ts
@@ -0,0 +1,46 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+import { Observable } from 'rxjs';
+
+import { OrchestratorFeature } from '../models/orchestrator.enum';
+import { OrchestratorStatus } from '../models/orchestrator.interface';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class OrchestratorService {
+ private url = 'ui-api/orchestrator';
+
+ disableMessages = {
+ noOrchestrator: $localize`The feature is disabled because Orchestrator is not available.`,
+ missingFeature: $localize`The Orchestrator backend doesn't support this feature.`
+ };
+
+ constructor(private http: HttpClient) {}
+
+ status(): Observable<OrchestratorStatus> {
+ return this.http.get<OrchestratorStatus>(`${this.url}/status`);
+ }
+
+ hasFeature(status: OrchestratorStatus, features: OrchestratorFeature[]): boolean {
+ return _.every(features, (feature) => _.get(status.features, `${feature}.available`));
+ }
+
+ getTableActionDisableDesc(
+ status: OrchestratorStatus,
+ features: OrchestratorFeature[]
+ ): boolean | string {
+ if (!status) {
+ return false;
+ }
+ if (!status.available) {
+ return this.disableMessages.noOrchestrator;
+ }
+ if (!this.hasFeature(status, features)) {
+ return this.disableMessages.missingFeature;
+ }
+ return false;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/osd.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/osd.service.spec.ts
new file mode 100644
index 000000000..d1f999779
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/osd.service.spec.ts
@@ -0,0 +1,183 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { OsdService } from './osd.service';
+
+describe('OsdService', () => {
+ let service: OsdService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [OsdService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(OsdService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call create', () => {
+ const trackingId = 'all_hdd, host1_ssd';
+ const post_data = {
+ method: 'drive_groups',
+ data: [
+ {
+ service_name: 'osd',
+ service_id: 'all_hdd',
+ host_pattern: '*',
+ data_devices: {
+ rotational: true
+ }
+ },
+ {
+ service_name: 'osd',
+ service_id: 'host1_ssd',
+ host_pattern: 'host1',
+ data_devices: {
+ rotational: false
+ }
+ }
+ ],
+ tracking_id: trackingId
+ };
+ service.create(post_data.data, trackingId).subscribe();
+ const req = httpTesting.expectOne('api/osd');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual(post_data);
+ });
+
+ it('should call delete', () => {
+ const id = 1;
+ service.delete(id, true, true).subscribe();
+ const req = httpTesting.expectOne(`api/osd/${id}?preserve_id=true&force=true`);
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call getList', () => {
+ service.getList().subscribe();
+ const req = httpTesting.expectOne('api/osd');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call getDetails', () => {
+ service.getDetails(1).subscribe();
+ const req = httpTesting.expectOne('api/osd/1');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call scrub, with deep=true', () => {
+ service.scrub('foo', true).subscribe();
+ const req = httpTesting.expectOne('api/osd/foo/scrub?deep=true');
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call scrub, with deep=false', () => {
+ service.scrub('foo', false).subscribe();
+ const req = httpTesting.expectOne('api/osd/foo/scrub?deep=false');
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call getFlags', () => {
+ service.getFlags().subscribe();
+ const req = httpTesting.expectOne('api/osd/flags');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call updateFlags', () => {
+ service.updateFlags(['foo']).subscribe();
+ const req = httpTesting.expectOne('api/osd/flags');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({ flags: ['foo'] });
+ });
+
+ it('should call updateIndividualFlags to update individual flags', () => {
+ const flags = { noin: true, noout: true };
+ const ids = [0, 1];
+ service.updateIndividualFlags(flags, ids).subscribe();
+ const req = httpTesting.expectOne('api/osd/flags/individual');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({ flags: flags, ids: ids });
+ });
+
+ it('should mark the OSD out', () => {
+ service.markOut(1).subscribe();
+ const req = httpTesting.expectOne('api/osd/1/mark');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({ action: 'out' });
+ });
+
+ it('should mark the OSD in', () => {
+ service.markIn(1).subscribe();
+ const req = httpTesting.expectOne('api/osd/1/mark');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({ action: 'in' });
+ });
+
+ it('should mark the OSD down', () => {
+ service.markDown(1).subscribe();
+ const req = httpTesting.expectOne('api/osd/1/mark');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({ action: 'down' });
+ });
+
+ it('should reweight an OSD', () => {
+ service.reweight(1, 0.5).subscribe();
+ const req = httpTesting.expectOne('api/osd/1/reweight');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual({ weight: 0.5 });
+ });
+
+ it('should update OSD', () => {
+ service.update(1, 'hdd').subscribe();
+ const req = httpTesting.expectOne('api/osd/1');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({ device_class: 'hdd' });
+ });
+
+ it('should mark an OSD lost', () => {
+ service.markLost(1).subscribe();
+ const req = httpTesting.expectOne('api/osd/1/mark');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({ action: 'lost' });
+ });
+
+ it('should purge an OSD', () => {
+ service.purge(1).subscribe();
+ const req = httpTesting.expectOne('api/osd/1/purge');
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should destroy an OSD', () => {
+ service.destroy(1).subscribe();
+ const req = httpTesting.expectOne('api/osd/1/destroy');
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should return if it is safe to destroy an OSD', () => {
+ service.safeToDestroy('[0,1]').subscribe();
+ const req = httpTesting.expectOne('api/osd/safe_to_destroy?ids=[0,1]');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call the devices endpoint to retrieve smart data', () => {
+ service.getDevices(1).subscribe();
+ const req = httpTesting.expectOne('api/osd/1/devices');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call getDeploymentOptions', () => {
+ service.getDeploymentOptions().subscribe();
+ const req = httpTesting.expectOne('ui-api/osd/deployment_options');
+ expect(req.request.method).toBe('GET');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/osd.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/osd.service.ts
new file mode 100644
index 000000000..34461bf63
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/osd.service.ts
@@ -0,0 +1,190 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+import { Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
+
+import { CdDevice } from '../models/devices';
+import { InventoryDeviceType } from '../models/inventory-device-type.model';
+import { DeploymentOptions } from '../models/osd-deployment-options';
+import { OsdSettings } from '../models/osd-settings';
+import { SmartDataResponseV1 } from '../models/smart';
+import { DeviceService } from '../services/device.service';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class OsdService {
+ private path = 'api/osd';
+ private uiPath = 'ui-api/osd';
+
+ osdDevices: InventoryDeviceType[] = [];
+
+ osdRecvSpeedModalPriorities = {
+ KNOWN_PRIORITIES: [
+ {
+ name: null,
+ text: $localize`-- Select the priority --`,
+ values: {
+ osd_max_backfills: null,
+ osd_recovery_max_active: null,
+ osd_recovery_max_single_start: null,
+ osd_recovery_sleep: null
+ }
+ },
+ {
+ name: 'low',
+ text: $localize`Low`,
+ values: {
+ osd_max_backfills: 1,
+ osd_recovery_max_active: 1,
+ osd_recovery_max_single_start: 1,
+ osd_recovery_sleep: 0.5
+ }
+ },
+ {
+ name: 'default',
+ text: $localize`Default`,
+ values: {
+ osd_max_backfills: 1,
+ osd_recovery_max_active: 3,
+ osd_recovery_max_single_start: 1,
+ osd_recovery_sleep: 0
+ }
+ },
+ {
+ name: 'high',
+ text: $localize`High`,
+ values: {
+ osd_max_backfills: 4,
+ osd_recovery_max_active: 4,
+ osd_recovery_max_single_start: 4,
+ osd_recovery_sleep: 0
+ }
+ }
+ ]
+ };
+
+ constructor(private http: HttpClient, private deviceService: DeviceService) {}
+
+ create(driveGroups: Object[], trackingId: string, method = 'drive_groups') {
+ const request = {
+ method: method,
+ data: driveGroups,
+ tracking_id: trackingId
+ };
+ return this.http.post(this.path, request, { observe: 'response' });
+ }
+
+ getList() {
+ return this.http.get(`${this.path}`);
+ }
+
+ getOsdSettings(): Observable<OsdSettings> {
+ return this.http.get<OsdSettings>(`${this.path}/settings`, {
+ headers: { Accept: 'application/vnd.ceph.api.v0.1+json' }
+ });
+ }
+
+ getDetails(id: number) {
+ interface OsdData {
+ osd_map: { [key: string]: any };
+ osd_metadata: { [key: string]: any };
+ smart: { [device_identifier: string]: any };
+ }
+ return this.http.get<OsdData>(`${this.path}/${id}`);
+ }
+
+ /**
+ * @param id OSD ID
+ */
+ getSmartData(id: number) {
+ return this.http.get<SmartDataResponseV1>(`${this.path}/${id}/smart`);
+ }
+
+ scrub(id: string, deep: boolean) {
+ return this.http.post(`${this.path}/${id}/scrub?deep=${deep}`, null);
+ }
+
+ getDeploymentOptions() {
+ return this.http.get<DeploymentOptions>(`${this.uiPath}/deployment_options`);
+ }
+
+ getFlags() {
+ return this.http.get(`${this.path}/flags`);
+ }
+
+ updateFlags(flags: string[]) {
+ return this.http.put(`${this.path}/flags`, { flags: flags });
+ }
+
+ updateIndividualFlags(flags: { [flag: string]: boolean }, ids: number[]) {
+ return this.http.put(`${this.path}/flags/individual`, { flags: flags, ids: ids });
+ }
+
+ markOut(id: number) {
+ return this.http.put(`${this.path}/${id}/mark`, { action: 'out' });
+ }
+
+ markIn(id: number) {
+ return this.http.put(`${this.path}/${id}/mark`, { action: 'in' });
+ }
+
+ markDown(id: number) {
+ return this.http.put(`${this.path}/${id}/mark`, { action: 'down' });
+ }
+
+ reweight(id: number, weight: number) {
+ return this.http.post(`${this.path}/${id}/reweight`, { weight: weight });
+ }
+
+ update(id: number, deviceClass: string) {
+ return this.http.put(`${this.path}/${id}`, { device_class: deviceClass });
+ }
+
+ markLost(id: number) {
+ return this.http.put(`${this.path}/${id}/mark`, { action: 'lost' });
+ }
+
+ purge(id: number) {
+ return this.http.post(`${this.path}/${id}/purge`, null);
+ }
+
+ destroy(id: number) {
+ return this.http.post(`${this.path}/${id}/destroy`, null);
+ }
+
+ delete(id: number, preserveId?: boolean, force?: boolean) {
+ const params = {
+ preserve_id: preserveId ? 'true' : 'false',
+ force: force ? 'true' : 'false'
+ };
+ return this.http.delete(`${this.path}/${id}`, { observe: 'response', params: params });
+ }
+
+ safeToDestroy(ids: string) {
+ interface SafeToDestroyResponse {
+ active: number[];
+ missing_stats: number[];
+ stored_pgs: number[];
+ is_safe_to_destroy: boolean;
+ message?: string;
+ }
+ return this.http.get<SafeToDestroyResponse>(`${this.path}/safe_to_destroy?ids=${ids}`);
+ }
+
+ safeToDelete(ids: string) {
+ interface SafeToDeleteResponse {
+ is_safe_to_delete: boolean;
+ message?: string;
+ }
+ return this.http.get<SafeToDeleteResponse>(`${this.path}/safe_to_delete?svc_ids=${ids}`);
+ }
+
+ getDevices(osdId: number) {
+ return this.http
+ .get<CdDevice[]>(`${this.path}/${osdId}/devices`)
+ .pipe(map((devices) => devices.map((device) => this.deviceService.prepareDevice(device))));
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/performance-counter.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/performance-counter.service.spec.ts
new file mode 100644
index 000000000..12b13787b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/performance-counter.service.spec.ts
@@ -0,0 +1,45 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { PerformanceCounterService } from './performance-counter.service';
+
+describe('PerformanceCounterService', () => {
+ let service: PerformanceCounterService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [PerformanceCounterService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(PerformanceCounterService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call list', () => {
+ service.list().subscribe();
+ const req = httpTesting.expectOne('api/perf_counters');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call get', () => {
+ let result;
+ service.get('foo', '1').subscribe((resp) => {
+ result = resp;
+ });
+ const req = httpTesting.expectOne('api/perf_counters/foo/1');
+ expect(req.request.method).toBe('GET');
+ req.flush({ counters: [{ foo: 'bar' }] });
+ expect(result).toEqual([{ foo: 'bar' }]);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/performance-counter.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/performance-counter.service.ts
new file mode 100644
index 000000000..36be6f383
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/performance-counter.service.ts
@@ -0,0 +1,29 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { of as observableOf } from 'rxjs';
+import { mergeMap } from 'rxjs/operators';
+
+import { cdEncode } from '../decorators/cd-encode';
+
+@cdEncode
+@Injectable({
+ providedIn: 'root'
+})
+export class PerformanceCounterService {
+ private url = 'api/perf_counters';
+
+ constructor(private http: HttpClient) {}
+
+ list() {
+ return this.http.get(this.url);
+ }
+
+ get(service_type: string, service_id: string) {
+ return this.http.get(`${this.url}/${service_type}/${service_id}`).pipe(
+ mergeMap((resp: any) => {
+ return observableOf(resp['counters']);
+ })
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/pool.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/pool.service.spec.ts
new file mode 100644
index 000000000..292da3c21
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/pool.service.spec.ts
@@ -0,0 +1,123 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RbdConfigurationSourceField } from '../models/configuration';
+import { RbdConfigurationService } from '../services/rbd-configuration.service';
+import { PoolService } from './pool.service';
+
+describe('PoolService', () => {
+ let service: PoolService;
+ let httpTesting: HttpTestingController;
+ const apiPath = 'api/pool';
+
+ configureTestBed({
+ providers: [PoolService, RbdConfigurationService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(PoolService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call getList', () => {
+ service.getList().subscribe();
+ const req = httpTesting.expectOne(`${apiPath}?stats=true`);
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call getInfo', () => {
+ service.getInfo().subscribe();
+ const req = httpTesting.expectOne(`ui-${apiPath}/info`);
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call create', () => {
+ const pool = { pool: 'somePool' };
+ service.create(pool).subscribe();
+ const req = httpTesting.expectOne(apiPath);
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual(pool);
+ });
+
+ it('should call update', () => {
+ service.update({ pool: 'somePool', application_metadata: [] }).subscribe();
+ const req = httpTesting.expectOne(`${apiPath}/somePool`);
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({ application_metadata: [] });
+ });
+
+ it('should call delete', () => {
+ service.delete('somePool').subscribe();
+ const req = httpTesting.expectOne(`${apiPath}/somePool`);
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call list without parameter', fakeAsync(() => {
+ let result;
+ service.list().then((resp) => (result = resp));
+ const req = httpTesting.expectOne(`${apiPath}?attrs=`);
+ expect(req.request.method).toBe('GET');
+ req.flush(['foo', 'bar']);
+ tick();
+ expect(result).toEqual(['foo', 'bar']);
+ }));
+
+ it('should call list with a list', fakeAsync(() => {
+ let result;
+ service.list(['foo']).then((resp) => (result = resp));
+ const req = httpTesting.expectOne(`${apiPath}?attrs=foo`);
+ expect(req.request.method).toBe('GET');
+ req.flush(['foo', 'bar']);
+ tick();
+ expect(result).toEqual(['foo', 'bar']);
+ }));
+
+ it('should test injection of data from getConfiguration()', fakeAsync(() => {
+ const pool = 'foo';
+ let value;
+ service.getConfiguration(pool).subscribe((next) => (value = next));
+ const req = httpTesting.expectOne(`${apiPath}/${pool}/configuration`);
+ expect(req.request.method).toBe('GET');
+ req.flush([
+ {
+ name: 'rbd_qos_bps_limit',
+ value: '60',
+ source: RbdConfigurationSourceField.global
+ },
+ {
+ name: 'rbd_qos_iops_limit',
+ value: '0',
+ source: RbdConfigurationSourceField.global
+ }
+ ]);
+ tick();
+ expect(value).toEqual([
+ {
+ description: 'The desired limit of IO bytes per second.',
+ displayName: 'BPS Limit',
+ name: 'rbd_qos_bps_limit',
+ source: RbdConfigurationSourceField.global,
+ type: 0,
+ value: '60'
+ },
+ {
+ description: 'The desired limit of IO operations per second.',
+ displayName: 'IOPS Limit',
+ name: 'rbd_qos_iops_limit',
+ source: RbdConfigurationSourceField.global,
+ type: 1,
+ value: '0'
+ }
+ ]);
+ }));
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/pool.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/pool.service.ts
new file mode 100644
index 000000000..78d5819ec
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/pool.service.ts
@@ -0,0 +1,74 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
+
+import { cdEncode } from '../decorators/cd-encode';
+import { RbdConfigurationEntry } from '../models/configuration';
+import { RbdConfigurationService } from '../services/rbd-configuration.service';
+
+@cdEncode
+@Injectable({
+ providedIn: 'root'
+})
+export class PoolService {
+ apiPath = 'api/pool';
+
+ constructor(private http: HttpClient, private rbdConfigurationService: RbdConfigurationService) {}
+
+ create(pool: any) {
+ return this.http.post(this.apiPath, pool, { observe: 'response' });
+ }
+
+ update(pool: any) {
+ let name: string;
+ if (pool.hasOwnProperty('srcpool')) {
+ name = pool.srcpool;
+ delete pool.srcpool;
+ } else {
+ name = pool.pool;
+ delete pool.pool;
+ }
+ return this.http.put(`${this.apiPath}/${encodeURIComponent(name)}`, pool, {
+ observe: 'response'
+ });
+ }
+
+ delete(name: string) {
+ return this.http.delete(`${this.apiPath}/${name}`, { observe: 'response' });
+ }
+
+ get(poolName: string) {
+ return this.http.get(`${this.apiPath}/${poolName}`);
+ }
+
+ getList() {
+ return this.http.get(`${this.apiPath}?stats=true`);
+ }
+
+ getConfiguration(poolName: string): Observable<RbdConfigurationEntry[]> {
+ return this.http.get<RbdConfigurationEntry[]>(`${this.apiPath}/${poolName}/configuration`).pipe(
+ // Add static data maintained in RbdConfigurationService
+ map((values) =>
+ values.map((entry) =>
+ Object.assign(entry, this.rbdConfigurationService.getOptionByName(entry.name))
+ )
+ )
+ );
+ }
+
+ getInfo() {
+ return this.http.get(`ui-${this.apiPath}/info`);
+ }
+
+ list(attrs: string[] = []) {
+ const attrsStr = attrs.join(',');
+ return this.http
+ .get(`${this.apiPath}?attrs=${attrsStr}`)
+ .toPromise()
+ .then((resp: any) => {
+ return resp;
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/prometheus.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/prometheus.service.spec.ts
new file mode 100644
index 000000000..c42f6e7ac
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/prometheus.service.spec.ts
@@ -0,0 +1,247 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { AlertmanagerNotification } from '../models/prometheus-alerts';
+import { PrometheusService } from './prometheus.service';
+import { SettingsService } from './settings.service';
+
+describe('PrometheusService', () => {
+ let service: PrometheusService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [PrometheusService, SettingsService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(PrometheusService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should get alerts', () => {
+ service.getAlerts().subscribe();
+ const req = httpTesting.expectOne('api/prometheus');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should get silences', () => {
+ service.getSilences().subscribe();
+ const req = httpTesting.expectOne('api/prometheus/silences');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should set a silence', () => {
+ const silence = {
+ id: 'someId',
+ matchers: [
+ {
+ name: 'getZero',
+ value: 0,
+ isRegex: false
+ }
+ ],
+ startsAt: '2019-01-25T14:32:46.646300974Z',
+ endsAt: '2019-01-25T18:32:46.646300974Z',
+ createdBy: 'someCreator',
+ comment: 'for testing purpose'
+ };
+ service.setSilence(silence).subscribe();
+ const req = httpTesting.expectOne('api/prometheus/silence');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual(silence);
+ });
+
+ it('should expire a silence', () => {
+ service.expireSilence('someId').subscribe();
+ const req = httpTesting.expectOne('api/prometheus/silence/someId');
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call getNotificationSince without a notification', () => {
+ service.getNotifications().subscribe();
+ const req = httpTesting.expectOne('api/prometheus/notifications?from=last');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call getNotificationSince with notification', () => {
+ service.getNotifications({ id: '42' } as AlertmanagerNotification).subscribe();
+ const req = httpTesting.expectOne('api/prometheus/notifications?from=42');
+ expect(req.request.method).toBe('GET');
+ });
+
+ describe('test getRules()', () => {
+ let data: {}; // Subset of PrometheusRuleGroup to keep the tests concise.
+
+ beforeEach(() => {
+ data = {
+ groups: [
+ {
+ name: 'test',
+ rules: [
+ {
+ name: 'load_0',
+ type: 'alerting'
+ },
+ {
+ name: 'load_1',
+ type: 'alerting'
+ },
+ {
+ name: 'load_2',
+ type: 'alerting'
+ }
+ ]
+ },
+ {
+ name: 'recording_rule',
+ rules: [
+ {
+ name: 'node_memory_MemUsed_percent',
+ type: 'recording'
+ }
+ ]
+ }
+ ]
+ };
+ });
+
+ it('should get rules without applying filters', () => {
+ service.getRules().subscribe((rules) => {
+ expect(rules).toEqual(data);
+ });
+
+ const req = httpTesting.expectOne('api/prometheus/rules');
+ expect(req.request.method).toBe('GET');
+ req.flush(data);
+ });
+
+ it('should get rewrite rules only', () => {
+ service.getRules('rewrites').subscribe((rules) => {
+ expect(rules).toEqual({
+ groups: [
+ { name: 'test', rules: [] },
+ { name: 'recording_rule', rules: [] }
+ ]
+ });
+ });
+
+ const req = httpTesting.expectOne('api/prometheus/rules');
+ expect(req.request.method).toBe('GET');
+ req.flush(data);
+ });
+
+ it('should get alerting rules only', () => {
+ service.getRules('alerting').subscribe((rules) => {
+ expect(rules).toEqual({
+ groups: [
+ {
+ name: 'test',
+ rules: [
+ { name: 'load_0', type: 'alerting' },
+ { name: 'load_1', type: 'alerting' },
+ { name: 'load_2', type: 'alerting' }
+ ]
+ },
+ { name: 'recording_rule', rules: [] }
+ ]
+ });
+ });
+
+ const req = httpTesting.expectOne('api/prometheus/rules');
+ expect(req.request.method).toBe('GET');
+ req.flush(data);
+ });
+ });
+
+ describe('ifAlertmanagerConfigured', () => {
+ let x: any;
+ let host: string;
+
+ const receiveConfig = () => {
+ const req = httpTesting.expectOne('api/settings/alertmanager-api-host');
+ expect(req.request.method).toBe('GET');
+ req.flush({ value: host });
+ };
+
+ beforeEach(() => {
+ x = false;
+ TestBed.inject(SettingsService)['settings'] = {};
+ service.ifAlertmanagerConfigured(
+ (v) => (x = v),
+ () => (x = [])
+ );
+ host = 'http://localhost:9093';
+ });
+
+ it('changes x in a valid case', () => {
+ expect(x).toBe(false);
+ receiveConfig();
+ expect(x).toBe(host);
+ });
+
+ it('does changes x an empty array in a invalid case', () => {
+ host = '';
+ receiveConfig();
+ expect(x).toEqual([]);
+ });
+
+ it('disables the set setting', () => {
+ receiveConfig();
+ service.disableAlertmanagerConfig();
+ x = false;
+ service.ifAlertmanagerConfigured((v) => (x = v));
+ expect(x).toBe(false);
+ });
+ });
+
+ describe('ifPrometheusConfigured', () => {
+ let x: any;
+ let host: string;
+
+ const receiveConfig = () => {
+ const req = httpTesting.expectOne('api/settings/prometheus-api-host');
+ expect(req.request.method).toBe('GET');
+ req.flush({ value: host });
+ };
+
+ beforeEach(() => {
+ x = false;
+ TestBed.inject(SettingsService)['settings'] = {};
+ service.ifPrometheusConfigured(
+ (v) => (x = v),
+ () => (x = [])
+ );
+ host = 'http://localhost:9090';
+ });
+
+ it('changes x in a valid case', () => {
+ expect(x).toBe(false);
+ receiveConfig();
+ expect(x).toBe(host);
+ });
+
+ it('does changes x an empty array in a invalid case', () => {
+ host = '';
+ receiveConfig();
+ expect(x).toEqual([]);
+ });
+
+ it('disables the set setting', () => {
+ receiveConfig();
+ service.disablePrometheusConfig();
+ x = false;
+ service.ifPrometheusConfigured((v) => (x = v));
+ expect(x).toBe(false);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/prometheus.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/prometheus.service.ts
new file mode 100644
index 000000000..581917219
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/prometheus.service.ts
@@ -0,0 +1,82 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
+
+import { AlertmanagerSilence } from '../models/alertmanager-silence';
+import {
+ AlertmanagerAlert,
+ AlertmanagerNotification,
+ PrometheusRuleGroup
+} from '../models/prometheus-alerts';
+import { SettingsService } from './settings.service';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class PrometheusService {
+ private baseURL = 'api/prometheus';
+ private settingsKey = {
+ alertmanager: 'api/settings/alertmanager-api-host',
+ prometheus: 'api/settings/prometheus-api-host'
+ };
+
+ constructor(private http: HttpClient, private settingsService: SettingsService) {}
+
+ ifAlertmanagerConfigured(fn: (value?: string) => void, elseFn?: () => void): void {
+ this.settingsService.ifSettingConfigured(this.settingsKey.alertmanager, fn, elseFn);
+ }
+
+ disableAlertmanagerConfig(): void {
+ this.settingsService.disableSetting(this.settingsKey.alertmanager);
+ }
+
+ ifPrometheusConfigured(fn: (value?: string) => void, elseFn?: () => void): void {
+ this.settingsService.ifSettingConfigured(this.settingsKey.prometheus, fn, elseFn);
+ }
+
+ disablePrometheusConfig(): void {
+ this.settingsService.disableSetting(this.settingsKey.prometheus);
+ }
+
+ getAlerts(params = {}): Observable<AlertmanagerAlert[]> {
+ return this.http.get<AlertmanagerAlert[]>(this.baseURL, { params });
+ }
+
+ getSilences(params = {}): Observable<AlertmanagerSilence[]> {
+ return this.http.get<AlertmanagerSilence[]>(`${this.baseURL}/silences`, { params });
+ }
+
+ getRules(
+ type: 'all' | 'alerting' | 'rewrites' = 'all'
+ ): Observable<{ groups: PrometheusRuleGroup[] }> {
+ return this.http.get<{ groups: PrometheusRuleGroup[] }>(`${this.baseURL}/rules`).pipe(
+ map((rules) => {
+ if (['alerting', 'rewrites'].includes(type)) {
+ rules.groups.map((group) => {
+ group.rules = group.rules.filter((rule) => rule.type === type);
+ });
+ }
+ return rules;
+ })
+ );
+ }
+
+ setSilence(silence: AlertmanagerSilence) {
+ return this.http.post<object>(`${this.baseURL}/silence`, silence, { observe: 'response' });
+ }
+
+ expireSilence(silenceId: string) {
+ return this.http.delete(`${this.baseURL}/silence/${silenceId}`, { observe: 'response' });
+ }
+
+ getNotifications(
+ notification?: AlertmanagerNotification
+ ): Observable<AlertmanagerNotification[]> {
+ const url = `${this.baseURL}/notifications?from=${
+ notification && notification.id ? notification.id : 'last'
+ }`;
+ return this.http.get<AlertmanagerNotification[]>(url);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd-mirroring.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd-mirroring.service.spec.ts
new file mode 100644
index 000000000..3f883d91f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd-mirroring.service.spec.ts
@@ -0,0 +1,164 @@
+import { HttpRequest } from '@angular/common/http';
+import {
+ HttpClientTestingModule,
+ HttpTestingController,
+ TestRequest
+} from '@angular/common/http/testing';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RbdMirroringService } from './rbd-mirroring.service';
+
+describe('RbdMirroringService', () => {
+ let service: RbdMirroringService;
+ let httpTesting: HttpTestingController;
+ let getMirroringSummaryCalls: () => TestRequest[];
+ let flushCalls: (call: TestRequest) => void;
+
+ const summary: Record<string, any> = {
+ status: 0,
+ content_data: {
+ daemons: [],
+ pools: [],
+ image_error: [],
+ image_syncing: [],
+ image_ready: []
+ },
+ executing_tasks: [{}]
+ };
+
+ configureTestBed({
+ providers: [RbdMirroringService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(RbdMirroringService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ getMirroringSummaryCalls = () => {
+ return httpTesting.match((request: HttpRequest<any>) => {
+ return request.url.match(/api\/block\/mirroring\/summary/) && request.method === 'GET';
+ });
+ };
+ flushCalls = (call: TestRequest) => {
+ if (!call.cancelled) {
+ call.flush(summary);
+ }
+ };
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should periodically poll summary', fakeAsync(() => {
+ const subs = service.startPolling();
+ tick();
+ const calledWith: any[] = [];
+ service.subscribeSummary((data) => {
+ calledWith.push(data);
+ });
+ tick(service.REFRESH_INTERVAL * 2);
+ const calls = getMirroringSummaryCalls();
+
+ expect(calls.length).toEqual(3);
+ calls.forEach((call: TestRequest) => flushCalls(call));
+ expect(calledWith).toEqual([summary]);
+
+ subs.unsubscribe();
+ }));
+
+ it('should get pool config', () => {
+ service.getPool('poolName').subscribe();
+
+ const req = httpTesting.expectOne('api/block/mirroring/pool/poolName');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should update pool config', () => {
+ const request = {
+ mirror_mode: 'pool'
+ };
+ service.updatePool('poolName', request).subscribe();
+
+ const req = httpTesting.expectOne('api/block/mirroring/pool/poolName');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual(request);
+ });
+
+ it('should get site name', () => {
+ service.getSiteName().subscribe();
+
+ const req = httpTesting.expectOne('api/block/mirroring/site_name');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should set site name', () => {
+ service.setSiteName('site-a').subscribe();
+
+ const req = httpTesting.expectOne('api/block/mirroring/site_name');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual({ site_name: 'site-a' });
+ });
+
+ it('should create bootstrap token', () => {
+ service.createBootstrapToken('poolName').subscribe();
+
+ const req = httpTesting.expectOne('api/block/mirroring/pool/poolName/bootstrap/token');
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should import bootstrap token', () => {
+ service.importBootstrapToken('poolName', 'rx', 'token-1234').subscribe();
+
+ const req = httpTesting.expectOne('api/block/mirroring/pool/poolName/bootstrap/peer');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual({
+ direction: 'rx',
+ token: 'token-1234'
+ });
+ });
+
+ it('should get peer config', () => {
+ service.getPeer('poolName', 'peerUUID').subscribe();
+
+ const req = httpTesting.expectOne('api/block/mirroring/pool/poolName/peer/peerUUID');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should add peer config', () => {
+ const request = {
+ cluster_name: 'remote',
+ client_id: 'admin',
+ mon_host: 'localhost',
+ key: '1234'
+ };
+ service.addPeer('poolName', request).subscribe();
+
+ const req = httpTesting.expectOne('api/block/mirroring/pool/poolName/peer');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual(request);
+ });
+
+ it('should update peer config', () => {
+ const request = {
+ cluster_name: 'remote'
+ };
+ service.updatePeer('poolName', 'peerUUID', request).subscribe();
+
+ const req = httpTesting.expectOne('api/block/mirroring/pool/poolName/peer/peerUUID');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body).toEqual(request);
+ });
+
+ it('should delete peer config', () => {
+ service.deletePeer('poolName', 'peerUUID').subscribe();
+
+ const req = httpTesting.expectOne('api/block/mirroring/pool/poolName/peer/peerUUID');
+ expect(req.request.method).toBe('DELETE');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd-mirroring.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd-mirroring.service.ts
new file mode 100644
index 000000000..4958382e2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd-mirroring.service.ts
@@ -0,0 +1,114 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { BehaviorSubject, Observable, Subscription } from 'rxjs';
+import { filter } from 'rxjs/operators';
+
+import { cdEncode, cdEncodeNot } from '../decorators/cd-encode';
+import { MirroringSummary } from '../models/mirroring-summary';
+import { TimerService } from '../services/timer.service';
+
+@cdEncode
+@Injectable({
+ providedIn: 'root'
+})
+export class RbdMirroringService {
+ readonly REFRESH_INTERVAL = 30000;
+ // Observable sources
+ private summaryDataSource = new BehaviorSubject<MirroringSummary>(null);
+ // Observable streams
+ summaryData$ = this.summaryDataSource.asObservable();
+
+ constructor(private http: HttpClient, private timerService: TimerService) {}
+
+ startPolling(): Subscription {
+ return this.timerService
+ .get(() => this.retrieveSummaryObservable(), this.REFRESH_INTERVAL)
+ .subscribe(this.retrieveSummaryObserver());
+ }
+
+ refresh(): Subscription {
+ return this.retrieveSummaryObservable().subscribe(this.retrieveSummaryObserver());
+ }
+
+ private retrieveSummaryObservable(): Observable<MirroringSummary> {
+ return this.http.get('api/block/mirroring/summary');
+ }
+
+ private retrieveSummaryObserver(): (data: MirroringSummary) => void {
+ return (data: any) => {
+ this.summaryDataSource.next(data);
+ };
+ }
+
+ /**
+ * Subscribes to the summaryData,
+ * which is updated periodically or when a new task is created.
+ */
+ subscribeSummary(
+ next: (summary: MirroringSummary) => void,
+ error?: (error: any) => void
+ ): Subscription {
+ return this.summaryData$.pipe(filter((value) => !!value)).subscribe(next, error);
+ }
+
+ getPool(poolName: string) {
+ return this.http.get(`api/block/mirroring/pool/${poolName}`);
+ }
+
+ updatePool(poolName: string, request: any) {
+ return this.http.put(`api/block/mirroring/pool/${poolName}`, request, { observe: 'response' });
+ }
+
+ getSiteName() {
+ return this.http.get(`api/block/mirroring/site_name`);
+ }
+
+ setSiteName(@cdEncodeNot siteName: string) {
+ return this.http.put(
+ `api/block/mirroring/site_name`,
+ { site_name: siteName },
+ { observe: 'response' }
+ );
+ }
+
+ createBootstrapToken(poolName: string) {
+ return this.http.post(`api/block/mirroring/pool/${poolName}/bootstrap/token`, {});
+ }
+
+ importBootstrapToken(
+ poolName: string,
+ @cdEncodeNot direction: string,
+ @cdEncodeNot token: string
+ ) {
+ const request = {
+ direction: direction,
+ token: token
+ };
+ return this.http.post(`api/block/mirroring/pool/${poolName}/bootstrap/peer`, request, {
+ observe: 'response'
+ });
+ }
+
+ getPeer(poolName: string, peerUUID: string) {
+ return this.http.get(`api/block/mirroring/pool/${poolName}/peer/${peerUUID}`);
+ }
+
+ addPeer(poolName: string, request: any) {
+ return this.http.post(`api/block/mirroring/pool/${poolName}/peer`, request, {
+ observe: 'response'
+ });
+ }
+
+ updatePeer(poolName: string, peerUUID: string, request: any) {
+ return this.http.put(`api/block/mirroring/pool/${poolName}/peer/${peerUUID}`, request, {
+ observe: 'response'
+ });
+ }
+
+ deletePeer(poolName: string, peerUUID: string) {
+ return this.http.delete(`api/block/mirroring/pool/${poolName}/peer/${peerUUID}`, {
+ observe: 'response'
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.model.ts
new file mode 100644
index 000000000..d14b2bc40
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.model.ts
@@ -0,0 +1,30 @@
+import { RbdConfigurationEntry } from '../models/configuration';
+
+export interface RbdPool {
+ pool_name: string;
+ status: number;
+ value: RbdImage[];
+ headers: any;
+}
+
+export interface RbdImage {
+ disk_usage: number;
+ stripe_unit: number;
+ name: string;
+ parent: any;
+ pool_name: string;
+ num_objs: number;
+ block_name_prefix: string;
+ snapshots: any[];
+ obj_size: number;
+ data_pool: string;
+ total_disk_usage: number;
+ features: number;
+ configuration: RbdConfigurationEntry[];
+ timestamp: string;
+ id: string;
+ features_name: string[];
+ stripe_count: number;
+ order: number;
+ size: number;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.spec.ts
new file mode 100644
index 000000000..84abf6d34
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.spec.ts
@@ -0,0 +1,181 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { ImageSpec } from '../models/image-spec';
+import { RbdConfigurationService } from '../services/rbd-configuration.service';
+import { RbdService } from './rbd.service';
+
+describe('RbdService', () => {
+ let service: RbdService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [RbdService, RbdConfigurationService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(RbdService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call create', () => {
+ service.create('foo').subscribe();
+ const req = httpTesting.expectOne('api/block/image');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual('foo');
+ });
+
+ it('should call delete', () => {
+ service.delete(new ImageSpec('poolName', null, 'rbdName')).subscribe();
+ const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName');
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call update', () => {
+ service.update(new ImageSpec('poolName', null, 'rbdName'), 'foo').subscribe();
+ const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName');
+ expect(req.request.body).toEqual('foo');
+ expect(req.request.method).toBe('PUT');
+ });
+
+ it('should call get', () => {
+ service.get(new ImageSpec('poolName', null, 'rbdName')).subscribe();
+ const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call list', () => {
+ /* tslint:disable:no-empty */
+ const context = new CdTableFetchDataContext(() => {});
+ service.list(context.toParams()).subscribe();
+ const req = httpTesting.expectOne('api/block/image?offset=0&limit=10&search=&sort=+name');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call copy', () => {
+ service.copy(new ImageSpec('poolName', null, 'rbdName'), 'foo').subscribe();
+ const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName/copy');
+ expect(req.request.body).toEqual('foo');
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call flatten', () => {
+ service.flatten(new ImageSpec('poolName', null, 'rbdName')).subscribe();
+ const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName/flatten');
+ expect(req.request.body).toEqual(null);
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call defaultFeatures', () => {
+ service.defaultFeatures().subscribe();
+ const req = httpTesting.expectOne('api/block/image/default_features');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call cloneFormatVersion', () => {
+ service.cloneFormatVersion().subscribe();
+ const req = httpTesting.expectOne('api/block/image/clone_format_version');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call createSnapshot', () => {
+ service.createSnapshot(new ImageSpec('poolName', null, 'rbdName'), 'snapshotName').subscribe();
+ const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName/snap');
+ expect(req.request.body).toEqual({
+ snapshot_name: 'snapshotName'
+ });
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call renameSnapshot', () => {
+ service
+ .renameSnapshot(new ImageSpec('poolName', null, 'rbdName'), 'snapshotName', 'foo')
+ .subscribe();
+ const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName/snap/snapshotName');
+ expect(req.request.body).toEqual({
+ new_snap_name: 'foo'
+ });
+ expect(req.request.method).toBe('PUT');
+ });
+
+ it('should call protectSnapshot', () => {
+ service
+ .protectSnapshot(new ImageSpec('poolName', null, 'rbdName'), 'snapshotName', true)
+ .subscribe();
+ const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName/snap/snapshotName');
+ expect(req.request.body).toEqual({
+ is_protected: true
+ });
+ expect(req.request.method).toBe('PUT');
+ });
+
+ it('should call rollbackSnapshot', () => {
+ service
+ .rollbackSnapshot(new ImageSpec('poolName', null, 'rbdName'), 'snapshotName')
+ .subscribe();
+ const req = httpTesting.expectOne(
+ 'api/block/image/poolName%2FrbdName/snap/snapshotName/rollback'
+ );
+ expect(req.request.body).toEqual(null);
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call cloneSnapshot', () => {
+ service
+ .cloneSnapshot(new ImageSpec('poolName', null, 'rbdName'), 'snapshotName', null)
+ .subscribe();
+ const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName/snap/snapshotName/clone');
+ expect(req.request.body).toEqual(null);
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call deleteSnapshot', () => {
+ service.deleteSnapshot(new ImageSpec('poolName', null, 'rbdName'), 'snapshotName').subscribe();
+ const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName/snap/snapshotName');
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call moveTrash', () => {
+ service.moveTrash(new ImageSpec('poolName', null, 'rbdName'), 1).subscribe();
+ const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName/move_trash');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual({ delay: 1 });
+ });
+
+ describe('should compose image spec', () => {
+ it('with namespace', () => {
+ expect(new ImageSpec('mypool', 'myns', 'myimage').toString()).toBe('mypool/myns/myimage');
+ });
+
+ it('without namespace', () => {
+ expect(new ImageSpec('mypool', null, 'myimage').toString()).toBe('mypool/myimage');
+ });
+ });
+
+ describe('should parse image spec', () => {
+ it('with namespace', () => {
+ const imageSpec = ImageSpec.fromString('mypool/myns/myimage');
+ expect(imageSpec.poolName).toBe('mypool');
+ expect(imageSpec.namespace).toBe('myns');
+ expect(imageSpec.imageName).toBe('myimage');
+ });
+
+ it('without namespace', () => {
+ const imageSpec = ImageSpec.fromString('mypool/myimage');
+ expect(imageSpec.poolName).toBe('mypool');
+ expect(imageSpec.namespace).toBeNull();
+ expect(imageSpec.imageName).toBe('myimage');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.ts
new file mode 100644
index 000000000..555f0db0f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.ts
@@ -0,0 +1,198 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+import { map } from 'rxjs/operators';
+
+import { ApiClient } from '~/app/shared/api/api-client';
+import { cdEncode, cdEncodeNot } from '../decorators/cd-encode';
+import { ImageSpec } from '../models/image-spec';
+import { RbdConfigurationService } from '../services/rbd-configuration.service';
+import { RbdPool } from './rbd.model';
+
+@cdEncode
+@Injectable({
+ providedIn: 'root'
+})
+export class RbdService extends ApiClient {
+ constructor(private http: HttpClient, private rbdConfigurationService: RbdConfigurationService) {
+ super();
+ }
+
+ isRBDPool(pool: any) {
+ return _.indexOf(pool.application_metadata, 'rbd') !== -1 && !pool.pool_name.includes('/');
+ }
+
+ create(rbd: any) {
+ return this.http.post('api/block/image', rbd, { observe: 'response' });
+ }
+
+ delete(imageSpec: ImageSpec) {
+ return this.http.delete(`api/block/image/${imageSpec.toStringEncoded()}`, {
+ observe: 'response'
+ });
+ }
+
+ update(imageSpec: ImageSpec, rbd: any) {
+ return this.http.put(`api/block/image/${imageSpec.toStringEncoded()}`, rbd, {
+ observe: 'response'
+ });
+ }
+
+ get(imageSpec: ImageSpec) {
+ return this.http.get(`api/block/image/${imageSpec.toStringEncoded()}`);
+ }
+
+ list(params: any) {
+ return this.http
+ .get<RbdPool[]>('api/block/image', {
+ params: params,
+ headers: { Accept: this.getVersionHeaderValue(2, 0) },
+ observe: 'response'
+ })
+ .pipe(
+ map((response: any) => {
+ return response['body'].map((pool: any) => {
+ pool.value.map((image: any) => {
+ if (!image.configuration) {
+ return image;
+ }
+ image.configuration.map((option: any) =>
+ Object.assign(option, this.rbdConfigurationService.getOptionByName(option.name))
+ );
+ return image;
+ });
+ pool['headers'] = response.headers;
+ return pool;
+ });
+ })
+ );
+ }
+
+ copy(imageSpec: ImageSpec, rbd: any) {
+ return this.http.post(`api/block/image/${imageSpec.toStringEncoded()}/copy`, rbd, {
+ observe: 'response'
+ });
+ }
+
+ flatten(imageSpec: ImageSpec) {
+ return this.http.post(`api/block/image/${imageSpec.toStringEncoded()}/flatten`, null, {
+ observe: 'response'
+ });
+ }
+
+ defaultFeatures() {
+ return this.http.get('api/block/image/default_features');
+ }
+
+ cloneFormatVersion() {
+ return this.http.get<number>('api/block/image/clone_format_version');
+ }
+
+ createSnapshot(imageSpec: ImageSpec, @cdEncodeNot snapshotName: string) {
+ const request = {
+ snapshot_name: snapshotName
+ };
+ return this.http.post(`api/block/image/${imageSpec.toStringEncoded()}/snap`, request, {
+ observe: 'response'
+ });
+ }
+
+ renameSnapshot(imageSpec: ImageSpec, snapshotName: string, @cdEncodeNot newSnapshotName: string) {
+ const request = {
+ new_snap_name: newSnapshotName
+ };
+ return this.http.put(
+ `api/block/image/${imageSpec.toStringEncoded()}/snap/${snapshotName}`,
+ request,
+ {
+ observe: 'response'
+ }
+ );
+ }
+
+ protectSnapshot(imageSpec: ImageSpec, snapshotName: string, @cdEncodeNot isProtected: boolean) {
+ const request = {
+ is_protected: isProtected
+ };
+ return this.http.put(
+ `api/block/image/${imageSpec.toStringEncoded()}/snap/${snapshotName}`,
+ request,
+ {
+ observe: 'response'
+ }
+ );
+ }
+
+ rollbackSnapshot(imageSpec: ImageSpec, snapshotName: string) {
+ return this.http.post(
+ `api/block/image/${imageSpec.toStringEncoded()}/snap/${snapshotName}/rollback`,
+ null,
+ { observe: 'response' }
+ );
+ }
+
+ cloneSnapshot(imageSpec: ImageSpec, snapshotName: string, request: any) {
+ return this.http.post(
+ `api/block/image/${imageSpec.toStringEncoded()}/snap/${snapshotName}/clone`,
+ request,
+ { observe: 'response' }
+ );
+ }
+
+ deleteSnapshot(imageSpec: ImageSpec, snapshotName: string) {
+ return this.http.delete(`api/block/image/${imageSpec.toStringEncoded()}/snap/${snapshotName}`, {
+ observe: 'response'
+ });
+ }
+
+ listTrash() {
+ return this.http.get(`api/block/image/trash/`);
+ }
+
+ createNamespace(pool: string, namespace: string) {
+ const request = {
+ namespace: namespace
+ };
+ return this.http.post(`api/block/pool/${pool}/namespace`, request, { observe: 'response' });
+ }
+
+ listNamespaces(pool: string) {
+ return this.http.get(`api/block/pool/${pool}/namespace/`);
+ }
+
+ deleteNamespace(pool: string, namespace: string) {
+ return this.http.delete(`api/block/pool/${pool}/namespace/${namespace}`, {
+ observe: 'response'
+ });
+ }
+
+ moveTrash(imageSpec: ImageSpec, delay: number) {
+ return this.http.post(
+ `api/block/image/${imageSpec.toStringEncoded()}/move_trash`,
+ { delay: delay },
+ { observe: 'response' }
+ );
+ }
+
+ purgeTrash(poolName: string) {
+ return this.http.post(`api/block/image/trash/purge/?pool_name=${poolName}`, null, {
+ observe: 'response'
+ });
+ }
+
+ restoreTrash(imageSpec: ImageSpec, @cdEncodeNot newImageName: string) {
+ return this.http.post(
+ `api/block/image/trash/${imageSpec.toStringEncoded()}/restore`,
+ { new_image_name: newImageName },
+ { observe: 'response' }
+ );
+ }
+
+ removeTrash(imageSpec: ImageSpec, force = false) {
+ return this.http.delete(
+ `api/block/image/trash/${imageSpec.toStringEncoded()}/?force=${force}`,
+ { observe: 'response' }
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-bucket.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-bucket.service.spec.ts
new file mode 100644
index 000000000..b22b67e34
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-bucket.service.spec.ts
@@ -0,0 +1,102 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed, RgwHelper } from '~/testing/unit-test-helper';
+import { RgwBucketService } from './rgw-bucket.service';
+
+describe('RgwBucketService', () => {
+ let service: RgwBucketService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [RgwBucketService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(RgwBucketService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ RgwHelper.selectDaemon();
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call list', () => {
+ service.list().subscribe();
+ const req = httpTesting.expectOne(`api/rgw/bucket?${RgwHelper.DAEMON_QUERY_PARAM}&stats=false`);
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call list with stats and user id', () => {
+ service.list(true, 'test-name').subscribe();
+ const req = httpTesting.expectOne(
+ `api/rgw/bucket?${RgwHelper.DAEMON_QUERY_PARAM}&stats=true&uid=test-name`
+ );
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call get', () => {
+ service.get('foo').subscribe();
+ const req = httpTesting.expectOne(`api/rgw/bucket/foo?${RgwHelper.DAEMON_QUERY_PARAM}`);
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call create', () => {
+ service
+ .create('foo', 'bar', 'default', 'default-placement', false, 'COMPLIANCE', '5')
+ .subscribe();
+ const req = httpTesting.expectOne(
+ `api/rgw/bucket?bucket=foo&uid=bar&zonegroup=default&placement_target=default-placement&lock_enabled=false&lock_mode=COMPLIANCE&lock_retention_period_days=5&${RgwHelper.DAEMON_QUERY_PARAM}`
+ );
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call update', () => {
+ service
+ .update('foo', 'bar', 'baz', 'Enabled', 'Enabled', '1', '223344', 'GOVERNANCE', '10')
+ .subscribe();
+ const req = httpTesting.expectOne(
+ `api/rgw/bucket/foo?${RgwHelper.DAEMON_QUERY_PARAM}&bucket_id=bar&uid=baz&versioning_state=Enabled&mfa_delete=Enabled&mfa_token_serial=1&mfa_token_pin=223344&lock_mode=GOVERNANCE&lock_retention_period_days=10`
+ );
+ expect(req.request.method).toBe('PUT');
+ });
+
+ it('should call delete, with purgeObjects = true', () => {
+ service.delete('foo').subscribe();
+ const req = httpTesting.expectOne(
+ `api/rgw/bucket/foo?${RgwHelper.DAEMON_QUERY_PARAM}&purge_objects=true`
+ );
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call delete, with purgeObjects = false', () => {
+ service.delete('foo', false).subscribe();
+ const req = httpTesting.expectOne(
+ `api/rgw/bucket/foo?${RgwHelper.DAEMON_QUERY_PARAM}&purge_objects=false`
+ );
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call exists', () => {
+ let result;
+ service.exists('foo').subscribe((resp) => {
+ result = resp;
+ });
+ const req = httpTesting.expectOne(`api/rgw/bucket/foo?${RgwHelper.DAEMON_QUERY_PARAM}`);
+ expect(req.request.method).toBe('GET');
+ req.flush(['foo', 'bar']);
+ expect(result).toBe(true);
+ });
+
+ it('should convert lock retention period to days', () => {
+ expect(service.getLockDays({ lock_retention_period_years: 1000 })).toBe(365242);
+ expect(service.getLockDays({ lock_retention_period_days: 5 })).toBe(5);
+ expect(service.getLockDays({})).toBe(0);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-bucket.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-bucket.service.ts
new file mode 100644
index 000000000..fc88bfa71
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-bucket.service.ts
@@ -0,0 +1,128 @@
+import { HttpClient, HttpParams } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+import { of as observableOf } from 'rxjs';
+import { catchError, mapTo } from 'rxjs/operators';
+
+import { ApiClient } from '~/app/shared/api/api-client';
+import { RgwDaemonService } from '~/app/shared/api/rgw-daemon.service';
+import { cdEncode } from '~/app/shared/decorators/cd-encode';
+
+@cdEncode
+@Injectable({
+ providedIn: 'root'
+})
+export class RgwBucketService extends ApiClient {
+ private url = 'api/rgw/bucket';
+
+ constructor(private http: HttpClient, private rgwDaemonService: RgwDaemonService) {
+ super();
+ }
+
+ /**
+ * Get the list of buckets.
+ * @return Observable<Object[]>
+ */
+ list(stats: boolean = false, uid: string = '') {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ params = params.append('stats', stats.toString());
+ if (uid) {
+ params = params.append('uid', uid);
+ }
+ return this.http.get(this.url, {
+ headers: { Accept: this.getVersionHeaderValue(1, 1) },
+ params: params
+ });
+ });
+ }
+
+ get(bucket: string) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ return this.http.get(`${this.url}/${bucket}`, { params: params });
+ });
+ }
+
+ create(
+ bucket: string,
+ uid: string,
+ zonegroup: string,
+ placementTarget: string,
+ lockEnabled: boolean,
+ lock_mode: 'GOVERNANCE' | 'COMPLIANCE',
+ lock_retention_period_days: string
+ ) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ return this.http.post(this.url, null, {
+ params: new HttpParams({
+ fromObject: {
+ bucket,
+ uid,
+ zonegroup,
+ placement_target: placementTarget,
+ lock_enabled: String(lockEnabled),
+ lock_mode,
+ lock_retention_period_days,
+ daemon_name: params.get('daemon_name')
+ }
+ })
+ });
+ });
+ }
+
+ update(
+ bucket: string,
+ bucketId: string,
+ uid: string,
+ versioningState: string,
+ mfaDelete: string,
+ mfaTokenSerial: string,
+ mfaTokenPin: string,
+ lockMode: 'GOVERNANCE' | 'COMPLIANCE',
+ lockRetentionPeriodDays: string
+ ) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ params = params.append('bucket_id', bucketId);
+ params = params.append('uid', uid);
+ params = params.append('versioning_state', versioningState);
+ params = params.append('mfa_delete', mfaDelete);
+ params = params.append('mfa_token_serial', mfaTokenSerial);
+ params = params.append('mfa_token_pin', mfaTokenPin);
+ params = params.append('lock_mode', lockMode);
+ params = params.append('lock_retention_period_days', lockRetentionPeriodDays);
+ return this.http.put(`${this.url}/${bucket}`, null, { params: params });
+ });
+ }
+
+ delete(bucket: string, purgeObjects = true) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ params = params.append('purge_objects', purgeObjects ? 'true' : 'false');
+ return this.http.delete(`${this.url}/${bucket}`, { params: params });
+ });
+ }
+
+ /**
+ * Check if the specified bucket exists.
+ * @param {string} bucket The bucket name to check.
+ * @return Observable<boolean>
+ */
+ exists(bucket: string) {
+ return this.get(bucket).pipe(
+ mapTo(true),
+ catchError((error: Event) => {
+ if (_.isFunction(error.preventDefault)) {
+ error.preventDefault();
+ }
+ return observableOf(false);
+ })
+ );
+ }
+
+ getLockDays(bucketData: object): number {
+ if (bucketData['lock_retention_period_years'] > 0) {
+ return Math.floor(bucketData['lock_retention_period_years'] * 365.242);
+ }
+
+ return bucketData['lock_retention_period_days'] || 0;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-daemon.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-daemon.service.spec.ts
new file mode 100644
index 000000000..d669ddefc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-daemon.service.spec.ts
@@ -0,0 +1,90 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+
+import { of } from 'rxjs';
+
+import { RgwDaemon } from '~/app/ceph/rgw/models/rgw-daemon';
+import { configureTestBed, RgwHelper } from '~/testing/unit-test-helper';
+import { RgwDaemonService } from './rgw-daemon.service';
+
+describe('RgwDaemonService', () => {
+ let service: RgwDaemonService;
+ let httpTesting: HttpTestingController;
+ let selectDaemonSpy: jasmine.Spy;
+
+ const daemonList: Array<RgwDaemon> = RgwHelper.getDaemonList();
+ const retrieveDaemonList = (reqDaemonList: RgwDaemon[], daemon: RgwDaemon) => {
+ service
+ .request((params) => of(params))
+ .subscribe((params) => expect(params.get('daemon_name')).toBe(daemon.id));
+ const listReq = httpTesting.expectOne('api/rgw/daemon');
+ listReq.flush(reqDaemonList);
+ tick();
+ expect(service['selectedDaemon'].getValue()).toEqual(daemon);
+ };
+
+ configureTestBed({
+ providers: [RgwDaemonService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(RgwDaemonService);
+ selectDaemonSpy = spyOn(service, 'selectDaemon').and.callThrough();
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should get daemon list', () => {
+ service.list().subscribe();
+ const req = httpTesting.expectOne('api/rgw/daemon');
+ req.flush(daemonList);
+ expect(req.request.method).toBe('GET');
+ expect(service['daemons'].getValue()).toEqual(daemonList);
+ });
+
+ it('should call "get daemon"', () => {
+ service.get('foo').subscribe();
+ const req = httpTesting.expectOne('api/rgw/daemon/foo');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call request and not select any daemon from empty daemon list', fakeAsync(() => {
+ expect(() => retrieveDaemonList([], null)).toThrowError('No RGW daemons found!');
+ expect(selectDaemonSpy).toHaveBeenCalledTimes(0);
+ }));
+
+ it('should call request and select default daemon from daemon list', fakeAsync(() => {
+ retrieveDaemonList(daemonList, daemonList[1]);
+ expect(selectDaemonSpy).toHaveBeenCalledTimes(1);
+ expect(selectDaemonSpy).toHaveBeenCalledWith(daemonList[1]);
+ }));
+
+ it('should call request and select first daemon from daemon list that has no default', fakeAsync(() => {
+ const noDefaultDaemonList = daemonList.map((daemon) => {
+ daemon.default = false;
+ return daemon;
+ });
+ retrieveDaemonList(noDefaultDaemonList, noDefaultDaemonList[0]);
+ expect(selectDaemonSpy).toHaveBeenCalledTimes(1);
+ expect(selectDaemonSpy).toHaveBeenCalledWith(noDefaultDaemonList[0]);
+ }));
+
+ it('should update default daemon if not exist in daemon list', fakeAsync(() => {
+ const tmpDaemonList = [...daemonList];
+ service.selectDaemon(tmpDaemonList[1]); // Select 'default' daemon.
+ tmpDaemonList.splice(1, 1); // Remove 'default' daemon.
+ tmpDaemonList[0].default = true; // Set new 'default' daemon.
+ service.list().subscribe();
+ const testReq = httpTesting.expectOne('api/rgw/daemon');
+ testReq.flush(tmpDaemonList);
+ expect(service['selectedDaemon'].getValue()).toEqual(tmpDaemonList[0]);
+ }));
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-daemon.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-daemon.service.ts
new file mode 100644
index 000000000..5c513c7f1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-daemon.service.ts
@@ -0,0 +1,82 @@
+import { HttpClient, HttpParams } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+import { BehaviorSubject, Observable, of, throwError } from 'rxjs';
+import { mergeMap, take, tap } from 'rxjs/operators';
+
+import { RgwDaemon } from '~/app/ceph/rgw/models/rgw-daemon';
+import { cdEncode } from '~/app/shared/decorators/cd-encode';
+
+@cdEncode
+@Injectable({
+ providedIn: 'root'
+})
+export class RgwDaemonService {
+ private url = 'api/rgw/daemon';
+ private daemons = new BehaviorSubject<RgwDaemon[]>([]);
+ daemons$ = this.daemons.asObservable();
+ private selectedDaemon = new BehaviorSubject<RgwDaemon>(null);
+ selectedDaemon$ = this.selectedDaemon.asObservable();
+
+ constructor(private http: HttpClient) {}
+
+ list(): Observable<RgwDaemon[]> {
+ return this.http.get<RgwDaemon[]>(this.url).pipe(
+ tap((daemons: RgwDaemon[]) => {
+ this.daemons.next(daemons);
+ const selectedDaemon = this.selectedDaemon.getValue();
+ // Set or re-select the default daemon if the current one is not
+ // in the list anymore.
+ if (_.isEmpty(selectedDaemon) || undefined === _.find(daemons, { id: selectedDaemon.id })) {
+ this.selectDefaultDaemon(daemons);
+ }
+ })
+ );
+ }
+
+ get(id: string) {
+ return this.http.get(`${this.url}/${id}`);
+ }
+
+ selectDaemon(daemon: RgwDaemon) {
+ this.selectedDaemon.next(daemon);
+ }
+
+ private selectDefaultDaemon(daemons: RgwDaemon[]): RgwDaemon {
+ if (daemons.length === 0) {
+ return null;
+ }
+
+ for (const daemon of daemons) {
+ if (daemon.default) {
+ this.selectDaemon(daemon);
+ return daemon;
+ }
+ }
+
+ this.selectDaemon(daemons[0]);
+ return daemons[0];
+ }
+
+ request(next: (params: HttpParams) => Observable<any>) {
+ return this.selectedDaemon.pipe(
+ mergeMap((daemon: RgwDaemon) =>
+ // If there is no selected daemon, retrieve daemon list so default daemon will be selected.
+ _.isEmpty(daemon)
+ ? this.list().pipe(
+ mergeMap((daemons) =>
+ _.isEmpty(daemons) ? throwError('No RGW daemons found!') : this.selectedDaemon$
+ )
+ )
+ : of(daemon)
+ ),
+ take(1),
+ mergeMap((daemon: RgwDaemon) => {
+ let params = new HttpParams();
+ params = params.append('daemon_name', daemon.id);
+ return next(params);
+ })
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-site.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-site.service.spec.ts
new file mode 100644
index 000000000..fa769d88b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-site.service.spec.ts
@@ -0,0 +1,43 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed, RgwHelper } from '~/testing/unit-test-helper';
+import { RgwSiteService } from './rgw-site.service';
+
+describe('RgwSiteService', () => {
+ let service: RgwSiteService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [RgwSiteService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(RgwSiteService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ RgwHelper.selectDaemon();
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should contain site endpoint in GET request', () => {
+ service.get().subscribe();
+ const req = httpTesting.expectOne(`${service['url']}?${RgwHelper.DAEMON_QUERY_PARAM}`);
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should add query param in GET request', () => {
+ const query = 'placement-targets';
+ service.get(query).subscribe();
+ httpTesting.expectOne(
+ `${service['url']}?${RgwHelper.DAEMON_QUERY_PARAM}&query=placement-targets`
+ );
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-site.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-site.service.ts
new file mode 100644
index 000000000..49589c83f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-site.service.ts
@@ -0,0 +1,38 @@
+import { HttpClient, HttpParams } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { Observable } from 'rxjs';
+import { map, mergeMap } from 'rxjs/operators';
+
+import { RgwDaemon } from '~/app/ceph/rgw/models/rgw-daemon';
+import { RgwDaemonService } from '~/app/shared/api/rgw-daemon.service';
+import { cdEncode } from '~/app/shared/decorators/cd-encode';
+
+@cdEncode
+@Injectable({
+ providedIn: 'root'
+})
+export class RgwSiteService {
+ private url = 'api/rgw/site';
+
+ constructor(private http: HttpClient, private rgwDaemonService: RgwDaemonService) {}
+
+ get(query?: string) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ if (query) {
+ params = params.append('query', query);
+ }
+ return this.http.get(this.url, { params: params });
+ });
+ }
+
+ isDefaultRealm(): Observable<boolean> {
+ return this.get('default-realm').pipe(
+ mergeMap((defaultRealm: string) =>
+ this.rgwDaemonService.selectedDaemon$.pipe(
+ map((selectedDaemon: RgwDaemon) => selectedDaemon.realm_name === defaultRealm)
+ )
+ )
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-user.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-user.service.spec.ts
new file mode 100644
index 000000000..7884f2385
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-user.service.spec.ts
@@ -0,0 +1,170 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { of as observableOf, throwError } from 'rxjs';
+
+import { configureTestBed, RgwHelper } from '~/testing/unit-test-helper';
+import { RgwUserService } from './rgw-user.service';
+
+describe('RgwUserService', () => {
+ let service: RgwUserService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ imports: [HttpClientTestingModule],
+ providers: [RgwUserService]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(RgwUserService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ RgwHelper.selectDaemon();
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call list with empty result', () => {
+ let result;
+ service.list().subscribe((resp) => {
+ result = resp;
+ });
+ const req = httpTesting.expectOne(`api/rgw/user?${RgwHelper.DAEMON_QUERY_PARAM}`);
+ expect(req.request.method).toBe('GET');
+ req.flush([]);
+ expect(result).toEqual([]);
+ });
+
+ it('should call list with result', () => {
+ let result;
+ service.list().subscribe((resp) => {
+ result = resp;
+ });
+ let req = httpTesting.expectOne(`api/rgw/user?${RgwHelper.DAEMON_QUERY_PARAM}`);
+ expect(req.request.method).toBe('GET');
+ req.flush(['foo', 'bar']);
+
+ req = httpTesting.expectOne(`api/rgw/user/foo?${RgwHelper.DAEMON_QUERY_PARAM}`);
+ expect(req.request.method).toBe('GET');
+ req.flush({ name: 'foo' });
+
+ req = httpTesting.expectOne(`api/rgw/user/bar?${RgwHelper.DAEMON_QUERY_PARAM}`);
+ expect(req.request.method).toBe('GET');
+ req.flush({ name: 'bar' });
+
+ expect(result).toEqual([{ name: 'foo' }, { name: 'bar' }]);
+ });
+
+ it('should call enumerate', () => {
+ service.enumerate().subscribe();
+ const req = httpTesting.expectOne(`api/rgw/user?${RgwHelper.DAEMON_QUERY_PARAM}`);
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call get', () => {
+ service.get('foo').subscribe();
+ const req = httpTesting.expectOne(`api/rgw/user/foo?${RgwHelper.DAEMON_QUERY_PARAM}`);
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call getQuota', () => {
+ service.getQuota('foo').subscribe();
+ const req = httpTesting.expectOne(`api/rgw/user/foo/quota?${RgwHelper.DAEMON_QUERY_PARAM}`);
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call update', () => {
+ service.update('foo', { xxx: 'yyy' }).subscribe();
+ const req = httpTesting.expectOne(`api/rgw/user/foo?${RgwHelper.DAEMON_QUERY_PARAM}&xxx=yyy`);
+ expect(req.request.method).toBe('PUT');
+ });
+
+ it('should call updateQuota', () => {
+ service.updateQuota('foo', { xxx: 'yyy' }).subscribe();
+ const req = httpTesting.expectOne(
+ `api/rgw/user/foo/quota?${RgwHelper.DAEMON_QUERY_PARAM}&xxx=yyy`
+ );
+ expect(req.request.method).toBe('PUT');
+ });
+
+ it('should call create', () => {
+ service.create({ foo: 'bar' }).subscribe();
+ const req = httpTesting.expectOne(`api/rgw/user?${RgwHelper.DAEMON_QUERY_PARAM}&foo=bar`);
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call delete', () => {
+ service.delete('foo').subscribe();
+ const req = httpTesting.expectOne(`api/rgw/user/foo?${RgwHelper.DAEMON_QUERY_PARAM}`);
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call createSubuser', () => {
+ service.createSubuser('foo', { xxx: 'yyy' }).subscribe();
+ const req = httpTesting.expectOne(
+ `api/rgw/user/foo/subuser?${RgwHelper.DAEMON_QUERY_PARAM}&xxx=yyy`
+ );
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call deleteSubuser', () => {
+ service.deleteSubuser('foo', 'bar').subscribe();
+ const req = httpTesting.expectOne(
+ `api/rgw/user/foo/subuser/bar?${RgwHelper.DAEMON_QUERY_PARAM}`
+ );
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call addCapability', () => {
+ service.addCapability('foo', 'bar', 'baz').subscribe();
+ const req = httpTesting.expectOne(
+ `api/rgw/user/foo/capability?${RgwHelper.DAEMON_QUERY_PARAM}&type=bar&perm=baz`
+ );
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call deleteCapability', () => {
+ service.deleteCapability('foo', 'bar', 'baz').subscribe();
+ const req = httpTesting.expectOne(
+ `api/rgw/user/foo/capability?${RgwHelper.DAEMON_QUERY_PARAM}&type=bar&perm=baz`
+ );
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call addS3Key', () => {
+ service.addS3Key('foo', { xxx: 'yyy' }).subscribe();
+ const req = httpTesting.expectOne(
+ `api/rgw/user/foo/key?${RgwHelper.DAEMON_QUERY_PARAM}&key_type=s3&xxx=yyy`
+ );
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call deleteS3Key', () => {
+ service.deleteS3Key('foo', 'bar').subscribe();
+ const req = httpTesting.expectOne(
+ `api/rgw/user/foo/key?${RgwHelper.DAEMON_QUERY_PARAM}&key_type=s3&access_key=bar`
+ );
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call exists with an existent uid', (done) => {
+ spyOn(service, 'get').and.returnValue(observableOf({}));
+ service.exists('foo').subscribe((res) => {
+ expect(res).toBe(true);
+ done();
+ });
+ });
+
+ it('should call exists with a non existent uid', (done) => {
+ spyOn(service, 'get').and.returnValue(throwError('bar'));
+ service.exists('baz').subscribe((res) => {
+ expect(res).toBe(false);
+ done();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-user.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-user.service.ts
new file mode 100644
index 000000000..66167bcab
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-user.service.ts
@@ -0,0 +1,179 @@
+import { HttpClient, HttpParams } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+import { forkJoin as observableForkJoin, Observable, of as observableOf } from 'rxjs';
+import { catchError, mapTo, mergeMap } from 'rxjs/operators';
+
+import { RgwDaemonService } from '~/app/shared/api/rgw-daemon.service';
+import { cdEncode } from '~/app/shared/decorators/cd-encode';
+
+@cdEncode
+@Injectable({
+ providedIn: 'root'
+})
+export class RgwUserService {
+ private url = 'api/rgw/user';
+
+ constructor(private http: HttpClient, private rgwDaemonService: RgwDaemonService) {}
+
+ /**
+ * Get the list of users.
+ * @return {Observable<Object[]>}
+ */
+ list() {
+ return this.enumerate().pipe(
+ mergeMap((uids: string[]) => {
+ if (uids.length > 0) {
+ return observableForkJoin(
+ uids.map((uid: string) => {
+ return this.get(uid);
+ })
+ );
+ }
+ return observableOf([]);
+ })
+ );
+ }
+
+ /**
+ * Get the list of usernames.
+ * @return {Observable<string[]>}
+ */
+ enumerate() {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ return this.http.get(this.url, { params: params });
+ });
+ }
+
+ enumerateEmail() {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ return this.http.get(`${this.url}/get_emails`, { params: params });
+ });
+ }
+
+ get(uid: string) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ return this.http.get(`${this.url}/${uid}`, { params: params });
+ });
+ }
+
+ getQuota(uid: string) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ return this.http.get(`${this.url}/${uid}/quota`, { params: params });
+ });
+ }
+
+ create(args: Record<string, any>) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ _.keys(args).forEach((key) => {
+ params = params.append(key, args[key]);
+ });
+ return this.http.post(this.url, null, { params: params });
+ });
+ }
+
+ update(uid: string, args: Record<string, any>) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ _.keys(args).forEach((key) => {
+ params = params.append(key, args[key]);
+ });
+ return this.http.put(`${this.url}/${uid}`, null, { params: params });
+ });
+ }
+
+ updateQuota(uid: string, args: Record<string, string>) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ _.keys(args).forEach((key) => {
+ params = params.append(key, args[key]);
+ });
+ return this.http.put(`${this.url}/${uid}/quota`, null, { params: params });
+ });
+ }
+
+ delete(uid: string) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ return this.http.delete(`${this.url}/${uid}`, { params: params });
+ });
+ }
+
+ createSubuser(uid: string, args: Record<string, string>) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ _.keys(args).forEach((key) => {
+ params = params.append(key, args[key]);
+ });
+ return this.http.post(`${this.url}/${uid}/subuser`, null, { params: params });
+ });
+ }
+
+ deleteSubuser(uid: string, subuser: string) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ return this.http.delete(`${this.url}/${uid}/subuser/${subuser}`, { params: params });
+ });
+ }
+
+ addCapability(uid: string, type: string, perm: string) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ params = params.append('type', type);
+ params = params.append('perm', perm);
+ return this.http.post(`${this.url}/${uid}/capability`, null, { params: params });
+ });
+ }
+
+ deleteCapability(uid: string, type: string, perm: string) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ params = params.append('type', type);
+ params = params.append('perm', perm);
+ return this.http.delete(`${this.url}/${uid}/capability`, { params: params });
+ });
+ }
+
+ addS3Key(uid: string, args: Record<string, string>) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ params = params.append('key_type', 's3');
+ _.keys(args).forEach((key) => {
+ params = params.append(key, args[key]);
+ });
+ return this.http.post(`${this.url}/${uid}/key`, null, { params: params });
+ });
+ }
+
+ deleteS3Key(uid: string, accessKey: string) {
+ return this.rgwDaemonService.request((params: HttpParams) => {
+ params = params.append('key_type', 's3');
+ params = params.append('access_key', accessKey);
+ return this.http.delete(`${this.url}/${uid}/key`, { params: params });
+ });
+ }
+
+ /**
+ * Check if the specified user ID exists.
+ * @param {string} uid The user ID to check.
+ * @return {Observable<boolean>}
+ */
+ exists(uid: string): Observable<boolean> {
+ return this.get(uid).pipe(
+ mapTo(true),
+ catchError((error: Event) => {
+ if (_.isFunction(error.preventDefault)) {
+ error.preventDefault();
+ }
+ return observableOf(false);
+ })
+ );
+ }
+
+ // Using @cdEncodeNot would be the preferred way here, but this
+ // causes an error: https://tracker.ceph.com/issues/37505
+ // Use decodeURIComponent as workaround.
+ // emailExists(@cdEncodeNot email: string): Observable<boolean> {
+ emailExists(email: string): Observable<boolean> {
+ email = decodeURIComponent(email);
+ return this.enumerateEmail().pipe(
+ mergeMap((resp: any[]) => {
+ const index = _.indexOf(resp, email);
+ return observableOf(-1 !== index);
+ })
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/role.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/role.service.spec.ts
new file mode 100644
index 000000000..c5af5877c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/role.service.spec.ts
@@ -0,0 +1,75 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RoleService } from './role.service';
+
+describe('RoleService', () => {
+ let service: RoleService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [RoleService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(RoleService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call list', () => {
+ service.list().subscribe();
+ const req = httpTesting.expectOne('api/role');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call delete', () => {
+ service.delete('role1').subscribe();
+ const req = httpTesting.expectOne('api/role/role1');
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call get', () => {
+ service.get('role1').subscribe();
+ const req = httpTesting.expectOne('api/role/role1');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call clone', () => {
+ service.clone('foo', 'bar').subscribe();
+ const req = httpTesting.expectOne('api/role/foo/clone');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual({ new_name: 'bar' });
+ });
+
+ it('should check if role name exists', () => {
+ let exists: boolean;
+ service.exists('role1').subscribe((res: boolean) => {
+ exists = res;
+ });
+ const req = httpTesting.expectOne('api/role');
+ expect(req.request.method).toBe('GET');
+ req.flush([{ name: 'role0' }, { name: 'role1' }]);
+ expect(exists).toBeTruthy();
+ });
+
+ it('should check if role name does not exist', () => {
+ let exists: boolean;
+ service.exists('role2').subscribe((res: boolean) => {
+ exists = res;
+ });
+ const req = httpTesting.expectOne('api/role');
+ expect(req.request.method).toBe('GET');
+ req.flush([{ name: 'role0' }, { name: 'role1' }]);
+ expect(exists).toBeFalsy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/role.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/role.service.ts
new file mode 100644
index 000000000..e76846b41
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/role.service.ts
@@ -0,0 +1,49 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { Observable, of as observableOf } from 'rxjs';
+import { mergeMap } from 'rxjs/operators';
+
+import { RoleFormModel } from '~/app/core/auth/role-form/role-form.model';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class RoleService {
+ constructor(private http: HttpClient) {}
+
+ list() {
+ return this.http.get('api/role');
+ }
+
+ delete(name: string) {
+ return this.http.delete(`api/role/${name}`);
+ }
+
+ get(name: string) {
+ return this.http.get(`api/role/${name}`);
+ }
+
+ create(role: RoleFormModel) {
+ return this.http.post(`api/role`, role);
+ }
+
+ clone(name: string, newName: string) {
+ return this.http.post(`api/role/${name}/clone`, { new_name: newName });
+ }
+
+ update(role: RoleFormModel) {
+ return this.http.put(`api/role/${role.name}`, role);
+ }
+
+ exists(name: string): Observable<boolean> {
+ return this.list().pipe(
+ mergeMap((roles: Array<RoleFormModel>) => {
+ const exists = roles.some((currentRole: RoleFormModel) => {
+ return currentRole.name === name;
+ });
+ return observableOf(exists);
+ })
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/scope.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/scope.service.spec.ts
new file mode 100644
index 000000000..811e1924f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/scope.service.spec.ts
@@ -0,0 +1,34 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { ScopeService } from './scope.service';
+
+describe('ScopeService', () => {
+ let service: ScopeService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [ScopeService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(ScopeService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call list', () => {
+ service.list().subscribe();
+ const req = httpTesting.expectOne('ui-api/scope');
+ expect(req.request.method).toBe('GET');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/scope.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/scope.service.ts
new file mode 100644
index 000000000..11e5da80a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/scope.service.ts
@@ -0,0 +1,13 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class ScopeService {
+ constructor(private http: HttpClient) {}
+
+ list() {
+ return this.http.get('ui-api/scope');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/settings.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/settings.service.spec.ts
new file mode 100644
index 000000000..06bd19823
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/settings.service.spec.ts
@@ -0,0 +1,154 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { SettingsService } from './settings.service';
+
+describe('SettingsService', () => {
+ let service: SettingsService;
+ let httpTesting: HttpTestingController;
+
+ const exampleUrl = 'api/settings/something';
+ const exampleValue = 'http://localhost:3000';
+
+ configureTestBed({
+ providers: [SettingsService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(SettingsService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call validateGrafanaDashboardUrl', () => {
+ service.validateGrafanaDashboardUrl('s').subscribe();
+ const req = httpTesting.expectOne('api/grafana/validation/s');
+ expect(req.request.method).toBe('GET');
+ });
+
+ describe('getSettingsValue', () => {
+ const testMethod = (data: object, expected: string) => {
+ expect(service['getSettingsValue'](data)).toBe(expected);
+ };
+
+ it('should explain the logic of the method', () => {
+ expect('' || undefined).toBe(undefined);
+ expect(undefined || '').toBe('');
+ expect('test' || undefined || '').toBe('test');
+ });
+
+ it('should test the method for empty string values', () => {
+ testMethod({}, '');
+ testMethod({ wrongAttribute: 'test' }, '');
+ testMethod({ value: '' }, '');
+ testMethod({ instance: '' }, '');
+ });
+
+ it('should test the method for non empty string values', () => {
+ testMethod({ value: 'test' }, 'test');
+ testMethod({ instance: 'test' }, 'test');
+ });
+ });
+
+ describe('isSettingConfigured', () => {
+ let increment: number;
+
+ const testConfig = (url: string, value: string) => {
+ service.ifSettingConfigured(
+ url,
+ (setValue) => {
+ expect(setValue).toBe(value);
+ increment++;
+ },
+ () => {
+ increment--;
+ }
+ );
+ };
+
+ const expectSettingsApiCall = (url: string, value: object, isSet: string) => {
+ testConfig(url, isSet);
+ const req = httpTesting.expectOne(url);
+ expect(req.request.method).toBe('GET');
+ req.flush(value);
+ tick();
+ expect(increment).toBe(isSet !== '' ? 1 : -1);
+ expect(service['settings'][url]).toBe(isSet);
+ };
+
+ beforeEach(() => {
+ increment = 0;
+ });
+
+ it(`should return true if 'value' does not contain an empty string`, fakeAsync(() => {
+ expectSettingsApiCall(exampleUrl, { value: exampleValue }, exampleValue);
+ }));
+
+ it(`should return false if 'value' does contain an empty string`, fakeAsync(() => {
+ expectSettingsApiCall(exampleUrl, { value: '' }, '');
+ }));
+
+ it(`should return true if 'instance' does not contain an empty string`, fakeAsync(() => {
+ expectSettingsApiCall(exampleUrl, { value: exampleValue }, exampleValue);
+ }));
+
+ it(`should return false if 'instance' does contain an empty string`, fakeAsync(() => {
+ expectSettingsApiCall(exampleUrl, { instance: '' }, '');
+ }));
+
+ it(`should return false if the api object is empty`, fakeAsync(() => {
+ expectSettingsApiCall(exampleUrl, {}, '');
+ }));
+
+ it(`should call the API once even if it is called multiple times`, fakeAsync(() => {
+ expectSettingsApiCall(exampleUrl, { value: exampleValue }, exampleValue);
+ testConfig(exampleUrl, exampleValue);
+ httpTesting.expectNone(exampleUrl);
+ expect(increment).toBe(2);
+ }));
+ });
+
+ it('should disable a set setting', () => {
+ service['settings'] = { [exampleUrl]: exampleValue };
+ service.disableSetting(exampleUrl);
+ expect(service['settings']).toEqual({ [exampleUrl]: '' });
+ });
+
+ it('should return the specified settings (1)', () => {
+ let result;
+ service.getValues('foo,bar').subscribe((resp) => {
+ result = resp;
+ });
+ const req = httpTesting.expectOne('api/settings?names=foo,bar');
+ expect(req.request.method).toBe('GET');
+ req.flush([
+ { name: 'foo', default: '', type: 'str', value: 'test' },
+ { name: 'bar', default: 0, type: 'int', value: 2 }
+ ]);
+ expect(result).toEqual({
+ foo: 'test',
+ bar: 2
+ });
+ });
+
+ it('should return the specified settings (2)', () => {
+ service.getValues(['abc', 'xyz']).subscribe();
+ const req = httpTesting.expectOne('api/settings?names=abc,xyz');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should return standard settings', () => {
+ service.getStandardSettings().subscribe();
+ const req = httpTesting.expectOne('ui-api/standard_settings');
+ expect(req.request.method).toBe('GET');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/settings.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/settings.service.ts
new file mode 100644
index 000000000..1e53fa064
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/settings.service.ts
@@ -0,0 +1,77 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+import { Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
+
+class SettingResponse {
+ name: string;
+ default: any;
+ type: string;
+ value: any;
+}
+
+@Injectable({
+ providedIn: 'root'
+})
+export class SettingsService {
+ constructor(private http: HttpClient) {}
+
+ private settings: { [url: string]: string } = {};
+
+ getValues(names: string | string[]): Observable<{ [key: string]: any }> {
+ if (_.isArray(names)) {
+ names = names.join(',');
+ }
+ return this.http.get(`api/settings?names=${names}`).pipe(
+ map((resp: SettingResponse[]) => {
+ const result = {};
+ _.forEach(resp, (option: SettingResponse) => {
+ _.set(result, option.name, option.value);
+ });
+ return result;
+ })
+ );
+ }
+
+ ifSettingConfigured(url: string, fn: (value?: string) => void, elseFn?: () => void): void {
+ const setting = this.settings[url];
+ if (setting === undefined) {
+ this.http.get(url).subscribe(
+ (data: any) => {
+ this.settings[url] = this.getSettingsValue(data);
+ this.ifSettingConfigured(url, fn, elseFn);
+ },
+ (resp) => {
+ if (resp.status !== 401) {
+ this.settings[url] = '';
+ }
+ }
+ );
+ } else if (setting !== '') {
+ fn(setting);
+ } else {
+ if (elseFn) {
+ elseFn();
+ }
+ }
+ }
+
+ // Easiest way to stop reloading external content that can't be reached
+ disableSetting(url: string) {
+ this.settings[url] = '';
+ }
+
+ private getSettingsValue(data: any): string {
+ return data.value || data.instance || '';
+ }
+
+ validateGrafanaDashboardUrl(uid: string) {
+ return this.http.get(`api/grafana/validation/${uid}`);
+ }
+
+ getStandardSettings(): Observable<{ [key: string]: any }> {
+ return this.http.get('ui-api/standard_settings');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/telemetry.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/telemetry.service.spec.ts
new file mode 100644
index 000000000..a90fcff7a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/telemetry.service.spec.ts
@@ -0,0 +1,58 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { TelemetryService } from './telemetry.service';
+
+describe('TelemetryService', () => {
+ let service: TelemetryService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ imports: [HttpClientTestingModule],
+ providers: [TelemetryService]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(TelemetryService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call getReport', () => {
+ service.getReport().subscribe();
+ const req = httpTesting.expectOne('api/telemetry/report');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call enable to enable module', () => {
+ service.enable(true).subscribe();
+ const req = httpTesting.expectOne('api/telemetry');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body.enable).toBe(true);
+ expect(req.request.body.license_name).toBe('sharing-1-0');
+ });
+
+ it('should call enable to disable module', () => {
+ service.enable(false).subscribe();
+ const req = httpTesting.expectOne('api/telemetry');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body.enable).toBe(false);
+ expect(req.request.body.license_name).toBeUndefined();
+ });
+
+ it('should call enable to enable module by default', () => {
+ service.enable().subscribe();
+ const req = httpTesting.expectOne('api/telemetry');
+ expect(req.request.method).toBe('PUT');
+ expect(req.request.body.enable).toBe(true);
+ expect(req.request.body.license_name).toBe('sharing-1-0');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/telemetry.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/telemetry.service.ts
new file mode 100644
index 000000000..8a175f66d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/telemetry.service.ts
@@ -0,0 +1,23 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class TelemetryService {
+ private url = 'api/telemetry';
+
+ constructor(private http: HttpClient) {}
+
+ getReport() {
+ return this.http.get(`${this.url}/report`);
+ }
+
+ enable(enable: boolean = true) {
+ const body = { enable: enable };
+ if (enable) {
+ body['license_name'] = 'sharing-1-0';
+ }
+ return this.http.put(`${this.url}`, body);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/user.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/user.service.spec.ts
new file mode 100644
index 000000000..ba038a725
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/user.service.spec.ts
@@ -0,0 +1,104 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { UserFormModel } from '~/app/core/auth/user-form/user-form.model';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { UserService } from './user.service';
+
+describe('UserService', () => {
+ let service: UserService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [UserService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(UserService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call create', () => {
+ const user = new UserFormModel();
+ user.username = 'user0';
+ user.password = 'pass0';
+ user.name = 'User 0';
+ user.email = 'user0@email.com';
+ user.roles = ['administrator'];
+ service.create(user).subscribe();
+ const req = httpTesting.expectOne('api/user');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual(user);
+ });
+
+ it('should call delete', () => {
+ service.delete('user0').subscribe();
+ const req = httpTesting.expectOne('api/user/user0');
+ expect(req.request.method).toBe('DELETE');
+ });
+
+ it('should call update', () => {
+ const user = new UserFormModel();
+ user.username = 'user0';
+ user.password = 'pass0';
+ user.name = 'User 0';
+ user.email = 'user0@email.com';
+ user.roles = ['administrator'];
+ service.update(user).subscribe();
+ const req = httpTesting.expectOne('api/user/user0');
+ expect(req.request.body).toEqual(user);
+ expect(req.request.method).toBe('PUT');
+ });
+
+ it('should call get', () => {
+ service.get('user0').subscribe();
+ const req = httpTesting.expectOne('api/user/user0');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call list', () => {
+ service.list().subscribe();
+ const req = httpTesting.expectOne('api/user');
+ expect(req.request.method).toBe('GET');
+ });
+
+ it('should call changePassword', () => {
+ service.changePassword('user0', 'foo', 'bar').subscribe();
+ const req = httpTesting.expectOne('api/user/user0/change_password');
+ expect(req.request.body).toEqual({
+ old_password: 'foo',
+ new_password: 'bar'
+ });
+ expect(req.request.method).toBe('POST');
+ });
+
+ it('should call validatePassword', () => {
+ service.validatePassword('foo').subscribe();
+ const req = httpTesting.expectOne('api/user/validate_password');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual({ password: 'foo', old_password: null, username: null });
+ });
+
+ it('should call validatePassword (incl. name)', () => {
+ service.validatePassword('foo_bar', 'bar').subscribe();
+ const req = httpTesting.expectOne('api/user/validate_password');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual({ password: 'foo_bar', username: 'bar', old_password: null });
+ });
+
+ it('should call validatePassword (incl. old password)', () => {
+ service.validatePassword('foo', null, 'foo').subscribe();
+ const req = httpTesting.expectOne('api/user/validate_password');
+ expect(req.request.method).toBe('POST');
+ expect(req.request.body).toEqual({ password: 'foo', old_password: 'foo', username: null });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/user.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/user.service.ts
new file mode 100644
index 000000000..95c80dd46
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/user.service.ts
@@ -0,0 +1,62 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { Observable, of as observableOf } from 'rxjs';
+import { catchError, mapTo } from 'rxjs/operators';
+
+import { UserFormModel } from '~/app/core/auth/user-form/user-form.model';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class UserService {
+ constructor(private http: HttpClient) {}
+
+ list() {
+ return this.http.get('api/user');
+ }
+
+ delete(username: string) {
+ return this.http.delete(`api/user/${username}`);
+ }
+
+ get(username: string) {
+ return this.http.get(`api/user/${username}`);
+ }
+
+ create(user: UserFormModel) {
+ return this.http.post(`api/user`, user);
+ }
+
+ update(user: UserFormModel) {
+ return this.http.put(`api/user/${user.username}`, user);
+ }
+
+ changePassword(username: string, oldPassword: string, newPassword: string) {
+ // Note, the specified user MUST be logged in to be able to change
+ // the password. The backend ensures that the password of another
+ // user can not be changed, otherwise an error will be thrown.
+ return this.http.post(`api/user/${username}/change_password`, {
+ old_password: oldPassword,
+ new_password: newPassword
+ });
+ }
+
+ validateUserName(user_name: string): Observable<boolean> {
+ return this.get(user_name).pipe(
+ mapTo(true),
+ catchError((error) => {
+ error.preventDefault();
+ return observableOf(false);
+ })
+ );
+ }
+
+ validatePassword(password: string, username: string = null, oldPassword: string = null) {
+ return this.http.post('api/user/validate_password', {
+ password: password,
+ username: username,
+ old_password: oldPassword
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/cd-helper.class.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/cd-helper.class.spec.ts
new file mode 100644
index 000000000..a5a28650d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/cd-helper.class.spec.ts
@@ -0,0 +1,66 @@
+import { CdHelperClass } from './cd-helper.class';
+
+class MockClass {
+ n = 42;
+ o = {
+ x: 'something',
+ y: [1, 2, 3],
+ z: true
+ };
+ b: boolean;
+}
+
+describe('CdHelperClass', () => {
+ describe('updateChanged', () => {
+ let old: MockClass;
+ let used: MockClass;
+ let structure = {
+ n: 42,
+ o: {
+ x: 'something',
+ y: [1, 2, 3],
+ z: true
+ }
+ } as any;
+
+ beforeEach(() => {
+ old = new MockClass();
+ used = new MockClass();
+ structure = {
+ n: 42,
+ o: {
+ x: 'something',
+ y: [1, 2, 3],
+ z: true
+ }
+ };
+ });
+
+ it('should not update anything', () => {
+ CdHelperClass.updateChanged(used, structure);
+ expect(used).toEqual(old);
+ });
+
+ it('should only change n', () => {
+ CdHelperClass.updateChanged(used, { n: 17 });
+ expect(used.n).not.toEqual(old.n);
+ expect(used.n).toBe(17);
+ });
+
+ it('should update o on change of o.y', () => {
+ CdHelperClass.updateChanged(used, structure);
+ structure.o.y.push(4);
+ expect(used.o.y).toEqual(old.o.y);
+ CdHelperClass.updateChanged(used, structure);
+ expect(used.o.y).toEqual([1, 2, 3, 4]);
+ });
+
+ it('should change b, o and n', () => {
+ structure.o.x.toUpperCase();
+ structure.n++;
+ structure.b = true;
+ CdHelperClass.updateChanged(used, structure);
+ expect(used).toEqual(structure);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/cd-helper.class.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/cd-helper.class.ts
new file mode 100644
index 000000000..250573125
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/cd-helper.class.ts
@@ -0,0 +1,28 @@
+import _ from 'lodash';
+
+export class CdHelperClass {
+ /**
+ * Simple way to only update variables if they have really changed and not just the reference
+ *
+ * @param componentThis - In order to update the variables if necessary
+ * @param change - The variable name (attribute of the object) is followed by the current value
+ * it would update even if it equals
+ */
+ static updateChanged(componentThis: any, change: { [publicVarName: string]: any }) {
+ let hasChanges = false;
+
+ Object.keys(change).forEach((publicVarName) => {
+ const data = change[publicVarName];
+ if (!_.isEqual(data, componentThis[publicVarName])) {
+ componentThis[publicVarName] = data;
+ hasChanges = true;
+ }
+ });
+
+ return hasChanges;
+ }
+
+ static cdVersionHeader(major_ver: string, minor_ver: string) {
+ return `application/vnd.ceph.api.v${major_ver}.${minor_ver}+json`;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/crush.node.selection.class.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/crush.node.selection.class.spec.ts
new file mode 100644
index 000000000..e09364015
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/crush.node.selection.class.spec.ts
@@ -0,0 +1,220 @@
+import { FormControl } from '@angular/forms';
+
+import _ from 'lodash';
+
+import { configureTestBed, Mocks } from '~/testing/unit-test-helper';
+import { CrushNode } from '../models/crush-node';
+import { CrushNodeSelectionClass } from './crush.node.selection.class';
+
+describe('CrushNodeSelectionService', () => {
+ const nodes = Mocks.getCrushMap();
+
+ let service: CrushNodeSelectionClass;
+ let controls: {
+ root: FormControl;
+ failure: FormControl;
+ device: FormControl;
+ };
+
+ // Object contains functions to get something
+ const get = {
+ nodeByName: (name: string): CrushNode => nodes.find((node) => node.name === name),
+ nodesByNames: (names: string[]): CrushNode[] => names.map(get.nodeByName)
+ };
+
+ // Expects that are used frequently
+ const assert = {
+ formFieldValues: (root: CrushNode, failureDomain: string, device: string) => {
+ expect(controls.root.value).toEqual(root);
+ expect(controls.failure.value).toBe(failureDomain);
+ expect(controls.device.value).toBe(device);
+ },
+ valuesOnRootChange: (
+ rootName: string,
+ expectedFailureDomain: string,
+ expectedDevice: string
+ ) => {
+ const node = get.nodeByName(rootName);
+ controls.root.setValue(node);
+ assert.formFieldValues(node, expectedFailureDomain, expectedDevice);
+ },
+ failureDomainNodes: (
+ failureDomains: { [failureDomain: string]: CrushNode[] },
+ expected: { [failureDomains: string]: string[] | CrushNode[] }
+ ) => {
+ expect(Object.keys(failureDomains)).toEqual(Object.keys(expected));
+ Object.keys(failureDomains).forEach((key) => {
+ if (_.isString(expected[key][0])) {
+ expect(failureDomains[key]).toEqual(get.nodesByNames(expected[key] as string[]));
+ } else {
+ expect(failureDomains[key]).toEqual(expected[key]);
+ }
+ });
+ }
+ };
+
+ configureTestBed({
+ providers: [CrushNodeSelectionClass]
+ });
+
+ beforeEach(() => {
+ controls = {
+ root: new FormControl(null),
+ failure: new FormControl(''),
+ device: new FormControl('')
+ };
+ // Normally this should be extended by the class using it
+ service = new CrushNodeSelectionClass();
+ // Therefore to get it working correctly use "this" instead of "service"
+ service.initCrushNodeSelection(nodes, controls.root, controls.failure, controls.device);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ expect(nodes.length).toBe(12);
+ });
+
+ describe('lists', () => {
+ afterEach(() => {
+ // The available buckets should not change
+ expect(service.buckets).toEqual(
+ get.nodesByNames(['default', 'hdd-rack', 'mix-host', 'ssd-host', 'ssd-rack'])
+ );
+ });
+
+ it('has the following lists after init', () => {
+ assert.failureDomainNodes(service.failureDomains, {
+ host: ['ssd-host', 'mix-host'],
+ osd: ['osd.1', 'osd.0', 'osd.2'],
+ rack: ['hdd-rack', 'ssd-rack'],
+ 'osd-rack': ['osd2.0', 'osd2.1', 'osd3.0', 'osd3.1']
+ });
+ expect(service.devices).toEqual(['hdd', 'ssd']);
+ });
+
+ it('has the following lists after selection of ssd-host', () => {
+ controls.root.setValue(get.nodeByName('ssd-host'));
+ assert.failureDomainNodes(service.failureDomains, {
+ // Not host as it only exist once
+ osd: ['osd.1', 'osd.0', 'osd.2']
+ });
+ expect(service.devices).toEqual(['ssd']);
+ });
+
+ it('has the following lists after selection of mix-host', () => {
+ controls.root.setValue(get.nodeByName('mix-host'));
+ expect(service.devices).toEqual(['hdd', 'ssd']);
+ assert.failureDomainNodes(service.failureDomains, {
+ rack: ['hdd-rack', 'ssd-rack'],
+ 'osd-rack': ['osd2.0', 'osd2.1', 'osd3.0', 'osd3.1']
+ });
+ });
+ });
+
+ describe('selection', () => {
+ it('selects the first root after init automatically', () => {
+ assert.formFieldValues(get.nodeByName('default'), 'osd-rack', '');
+ });
+
+ it('should select all values automatically by selecting "ssd-host" as root', () => {
+ assert.valuesOnRootChange('ssd-host', 'osd', 'ssd');
+ });
+
+ it('selects automatically the most common failure domain', () => {
+ // Select mix-host as mix-host has multiple failure domains (osd-rack and rack)
+ assert.valuesOnRootChange('mix-host', 'osd-rack', '');
+ });
+
+ it('should override automatic selections', () => {
+ assert.formFieldValues(get.nodeByName('default'), 'osd-rack', '');
+ assert.valuesOnRootChange('ssd-host', 'osd', 'ssd');
+ assert.valuesOnRootChange('mix-host', 'osd-rack', '');
+ });
+
+ it('should not override manual selections if possible', () => {
+ controls.failure.setValue('rack');
+ controls.failure.markAsDirty();
+ controls.device.setValue('ssd');
+ controls.device.markAsDirty();
+ assert.valuesOnRootChange('mix-host', 'rack', 'ssd');
+ });
+
+ it('should preselect device by domain selection', () => {
+ controls.failure.setValue('osd');
+ assert.formFieldValues(get.nodeByName('default'), 'osd', 'ssd');
+ });
+ });
+
+ describe('get available OSDs count', () => {
+ it('should have 4 available OSDs with the default selection', () => {
+ expect(service.deviceCount).toBe(4);
+ });
+
+ it('should reduce available OSDs to 2 if a device type is set', () => {
+ controls.device.setValue('ssd');
+ controls.device.markAsDirty();
+ expect(service.deviceCount).toBe(2);
+ });
+
+ it('should show 3 OSDs when selecting "ssd-host"', () => {
+ assert.valuesOnRootChange('ssd-host', 'osd', 'ssd');
+ expect(service.deviceCount).toBe(3);
+ });
+ });
+
+ describe('search tree', () => {
+ it('returns the following list after searching for mix-host', () => {
+ const subNodes = CrushNodeSelectionClass.search(nodes, 'mix-host');
+ expect(subNodes).toEqual(
+ get.nodesByNames([
+ 'mix-host',
+ 'hdd-rack',
+ 'osd2.0',
+ 'osd2.1',
+ 'ssd-rack',
+ 'osd3.0',
+ 'osd3.1'
+ ])
+ );
+ });
+
+ it('returns the following list after searching for mix-host with SSDs', () => {
+ const subNodes = CrushNodeSelectionClass.search(nodes, 'mix-host~ssd');
+ expect(subNodes.map((n) => n.name)).toEqual(['mix-host', 'ssd-rack', 'osd3.0', 'osd3.1']);
+ });
+
+ it('returns an empty array if node can not be found', () => {
+ expect(CrushNodeSelectionClass.search(nodes, 'not-there')).toEqual([]);
+ });
+
+ it('returns the following list after searching for mix-host failure domains', () => {
+ const subNodes = CrushNodeSelectionClass.search(nodes, 'mix-host');
+ assert.failureDomainNodes(CrushNodeSelectionClass.getFailureDomains(subNodes), {
+ host: ['mix-host'],
+ rack: ['hdd-rack', 'ssd-rack'],
+ 'osd-rack': ['osd2.0', 'osd2.1', 'osd3.0', 'osd3.1']
+ });
+ });
+
+ it('returns the following list after searching for mix-host failure domains for a specific type', () => {
+ const subNodes = CrushNodeSelectionClass.search(nodes, 'mix-host~hdd');
+ const hddHost = _.cloneDeep(get.nodesByNames(['mix-host'])[0]);
+ hddHost.children = [-4];
+ assert.failureDomainNodes(CrushNodeSelectionClass.getFailureDomains(subNodes), {
+ host: [hddHost],
+ rack: ['hdd-rack'],
+ 'osd-rack': ['osd2.0', 'osd2.1']
+ });
+ const ssdHost = _.cloneDeep(get.nodesByNames(['mix-host'])[0]);
+ ssdHost.children = [-5];
+ assert.failureDomainNodes(
+ CrushNodeSelectionClass.searchFailureDomains(nodes, 'mix-host~ssd'),
+ {
+ host: [ssdHost],
+ rack: ['ssd-rack'],
+ 'osd-rack': ['osd3.0', 'osd3.1']
+ }
+ );
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/crush.node.selection.class.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/crush.node.selection.class.ts
new file mode 100644
index 000000000..34cebbcc8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/crush.node.selection.class.ts
@@ -0,0 +1,221 @@
+import { AbstractControl } from '@angular/forms';
+
+import _ from 'lodash';
+
+import { CrushNode } from '../models/crush-node';
+
+export class CrushNodeSelectionClass {
+ private nodes: CrushNode[] = [];
+ private idTree: { [id: number]: CrushNode } = {};
+ private allDevices: string[] = [];
+ private controls: {
+ root: AbstractControl;
+ failure: AbstractControl;
+ device: AbstractControl;
+ };
+
+ buckets: CrushNode[] = [];
+ failureDomains: { [type: string]: CrushNode[] } = {};
+ failureDomainKeys: string[] = [];
+ devices: string[] = [];
+ deviceCount = 0;
+
+ static searchFailureDomains(
+ nodes: CrushNode[],
+ s: string
+ ): { [failureDomain: string]: CrushNode[] } {
+ return this.getFailureDomains(this.search(nodes, s));
+ }
+
+ /**
+ * Filters crush map for a node and it's tree.
+ * The node name as provided in crush rules attribute item_name is supported.
+ * This means that '$name~$deviceType' can be used and will result in a crush map
+ * that only include buckets with the specified device in use as their leaf.
+ */
+ static search(nodes: CrushNode[], s: string): CrushNode[] {
+ const [search, deviceType] = s.split('~'); // Used inside item_name in crush rules
+ const node = nodes.find((n) => ['name', 'id', 'type'].some((attr) => n[attr] === search));
+ if (!node) {
+ return [];
+ }
+ nodes = this.getSubNodes(node, this.createIdTreeFromNodes(nodes));
+ if (deviceType) {
+ nodes = this.filterNodesByDeviceType(nodes, deviceType);
+ }
+ return nodes;
+ }
+
+ static createIdTreeFromNodes(nodes: CrushNode[]): { [id: number]: CrushNode } {
+ const idTree = {};
+ nodes.forEach((node) => {
+ idTree[node.id] = node;
+ });
+ return idTree;
+ }
+
+ static getSubNodes(node: CrushNode, idTree: { [id: number]: CrushNode }): CrushNode[] {
+ let subNodes = [node]; // Includes parent node
+ if (!node.children) {
+ return subNodes;
+ }
+ node.children.forEach((id) => {
+ const childNode = idTree[id];
+ subNodes = subNodes.concat(this.getSubNodes(childNode, idTree));
+ });
+ return subNodes;
+ }
+
+ static filterNodesByDeviceType(nodes: CrushNode[], deviceType: string): any {
+ let doNotInclude = nodes
+ .filter((n) => n.device_class && n.device_class !== deviceType)
+ .map((n) => n.id);
+ let foundNewNode: boolean;
+ let childrenToRemove = doNotInclude;
+
+ // Filters out all unwanted nodes
+ do {
+ foundNewNode = false;
+ nodes = nodes.filter((n) => !doNotInclude.includes(n.id)); // Unwanted nodes
+ // Find nodes where all children were filtered
+ const toRemoveNext: number[] = [];
+ nodes.forEach((n) => {
+ if (n.children && n.children.every((id) => doNotInclude.includes(id))) {
+ toRemoveNext.push(n.id);
+ foundNewNode = true;
+ }
+ });
+ if (foundNewNode) {
+ doNotInclude = toRemoveNext; // Reduces array length
+ childrenToRemove = childrenToRemove.concat(toRemoveNext);
+ }
+ } while (foundNewNode);
+
+ // Removes filtered out children in all left nodes with children
+ nodes = _.cloneDeep(nodes); // Clone objects to not change original objects
+ nodes = nodes.map((n) => {
+ if (!n.children) {
+ return n;
+ }
+ n.children = n.children.filter((id) => !childrenToRemove.includes(id));
+ return n;
+ });
+
+ return nodes;
+ }
+
+ static getFailureDomains(nodes: CrushNode[]): { [failureDomain: string]: CrushNode[] } {
+ const domains = {};
+ nodes.forEach((node) => {
+ const type = node.type;
+ if (!domains[type]) {
+ domains[type] = [];
+ }
+ domains[type].push(node);
+ });
+ return domains;
+ }
+
+ initCrushNodeSelection(
+ nodes: CrushNode[],
+ rootControl: AbstractControl,
+ failureControl: AbstractControl,
+ deviceControl: AbstractControl
+ ) {
+ this.nodes = nodes;
+ this.idTree = CrushNodeSelectionClass.createIdTreeFromNodes(nodes);
+ nodes.forEach((node) => {
+ this.idTree[node.id] = node;
+ });
+ this.buckets = _.sortBy(
+ nodes.filter((n) => n.children),
+ 'name'
+ );
+ this.controls = {
+ root: rootControl,
+ failure: failureControl,
+ device: deviceControl
+ };
+ this.preSelectRoot();
+ this.controls.root.valueChanges.subscribe(() => this.onRootChange());
+ this.controls.failure.valueChanges.subscribe(() => this.onFailureDomainChange());
+ this.controls.device.valueChanges.subscribe(() => this.onDeviceChange());
+ }
+
+ private preSelectRoot() {
+ const rootNode = this.nodes.find((node) => node.type === 'root');
+ this.silentSet(this.controls.root, rootNode);
+ this.onRootChange();
+ }
+
+ private silentSet(control: AbstractControl, value: any) {
+ control.setValue(value, { emitEvent: false });
+ }
+
+ private onRootChange() {
+ const nodes = CrushNodeSelectionClass.getSubNodes(this.controls.root.value, this.idTree);
+ const domains = CrushNodeSelectionClass.getFailureDomains(nodes);
+ Object.keys(domains).forEach((type) => {
+ if (domains[type].length <= 1) {
+ delete domains[type];
+ }
+ });
+ this.failureDomains = domains;
+ this.failureDomainKeys = Object.keys(domains).sort();
+ this.updateFailureDomain();
+ }
+
+ private updateFailureDomain() {
+ let failureDomain = this.getIncludedCustomValue(
+ this.controls.failure,
+ Object.keys(this.failureDomains)
+ );
+ if (failureDomain === '') {
+ failureDomain = this.setMostCommonDomain(this.controls.failure);
+ }
+ this.updateDevices(failureDomain);
+ }
+
+ private getIncludedCustomValue(control: AbstractControl, includedIn: string[]) {
+ return control.dirty && includedIn.includes(control.value) ? control.value : '';
+ }
+
+ private setMostCommonDomain(failureControl: AbstractControl): string {
+ let winner = { n: 0, type: '' };
+ Object.keys(this.failureDomains).forEach((type) => {
+ const n = this.failureDomains[type].length;
+ if (winner.n < n) {
+ winner = { n, type };
+ }
+ });
+ this.silentSet(failureControl, winner.type);
+ return winner.type;
+ }
+
+ private onFailureDomainChange() {
+ this.updateDevices();
+ }
+
+ private updateDevices(failureDomain: string = this.controls.failure.value) {
+ const subNodes = _.flatten(
+ this.failureDomains[failureDomain].map((node) =>
+ CrushNodeSelectionClass.getSubNodes(node, this.idTree)
+ )
+ );
+ this.allDevices = subNodes.filter((n) => n.device_class).map((n) => n.device_class);
+ this.devices = _.uniq(this.allDevices).sort();
+ const device =
+ this.devices.length === 1
+ ? this.devices[0]
+ : this.getIncludedCustomValue(this.controls.device, this.devices);
+ this.silentSet(this.controls.device, device);
+ this.onDeviceChange(device);
+ }
+
+ private onDeviceChange(deviceType: string = this.controls.device.value) {
+ this.deviceCount =
+ deviceType === ''
+ ? this.allDevices.length
+ : this.allDevices.filter((type) => type === deviceType).length;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/css-helper.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/css-helper.ts
new file mode 100644
index 000000000..e5caef761
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/css-helper.ts
@@ -0,0 +1,5 @@
+export class CssHelper {
+ propertyValue(propertyName: string): string {
+ return getComputedStyle(document.body).getPropertyValue(`--${propertyName}`);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/list-with-details.class.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/list-with-details.class.ts
new file mode 100644
index 000000000..2eaeeb35e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/list-with-details.class.ts
@@ -0,0 +1,29 @@
+import { NgZone } from '@angular/core';
+
+import { TableStatus } from './table-status';
+
+export class ListWithDetails {
+ expandedRow: any;
+ staleTimeout: number;
+ tableStatus: TableStatus;
+
+ constructor(protected ngZone?: NgZone) {}
+
+ setExpandedRow(expandedRow: any) {
+ this.expandedRow = expandedRow;
+ }
+
+ setTableRefreshTimeout() {
+ clearTimeout(this.staleTimeout);
+ this.ngZone.runOutsideAngular(() => {
+ this.staleTimeout = window.setTimeout(() => {
+ this.ngZone.run(() => {
+ this.tableStatus = new TableStatus(
+ 'warning',
+ $localize`The user list data might be stale. If needed, you can manually reload it.`
+ );
+ });
+ }, 10000);
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status-view-cache.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status-view-cache.spec.ts
new file mode 100644
index 000000000..cff2ec33a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status-view-cache.spec.ts
@@ -0,0 +1,40 @@
+import { ViewCacheStatus } from '../enum/view-cache-status.enum';
+import { TableStatusViewCache } from './table-status-view-cache';
+
+describe('TableStatusViewCache', () => {
+ it('should create an instance', () => {
+ const ts = new TableStatusViewCache();
+ expect(ts).toBeTruthy();
+ expect(ts).toEqual({ msg: '', type: 'light' });
+ });
+
+ it('should create a ValueStale instance', () => {
+ let ts = new TableStatusViewCache(ViewCacheStatus.ValueStale);
+ expect(ts).toEqual({ type: 'warning', msg: 'Displaying previously cached data.' });
+
+ ts = new TableStatusViewCache(ViewCacheStatus.ValueStale, 'foo bar');
+ expect(ts).toEqual({ type: 'warning', msg: 'Displaying previously cached data for foo bar.' });
+ });
+
+ it('should create a ValueNone instance', () => {
+ let ts = new TableStatusViewCache(ViewCacheStatus.ValueNone);
+ expect(ts).toEqual({ type: 'info', msg: 'Retrieving data. Please wait...' });
+
+ ts = new TableStatusViewCache(ViewCacheStatus.ValueNone, 'foo bar');
+ expect(ts).toEqual({ type: 'info', msg: 'Retrieving data for foo bar. Please wait...' });
+ });
+
+ it('should create a ValueException instance', () => {
+ let ts = new TableStatusViewCache(ViewCacheStatus.ValueException);
+ expect(ts).toEqual({
+ type: 'danger',
+ msg: 'Could not load data. Please check the cluster health.'
+ });
+
+ ts = new TableStatusViewCache(ViewCacheStatus.ValueException, 'foo bar');
+ expect(ts).toEqual({
+ type: 'danger',
+ msg: 'Could not load data for foo bar. Please check the cluster health.'
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status-view-cache.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status-view-cache.ts
new file mode 100644
index 000000000..91c53a0aa
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status-view-cache.ts
@@ -0,0 +1,37 @@
+import { ViewCacheStatus } from '../enum/view-cache-status.enum';
+import { TableStatus } from './table-status';
+
+export class TableStatusViewCache extends TableStatus {
+ constructor(status: ViewCacheStatus = ViewCacheStatus.ValueOk, statusFor: string = '') {
+ super();
+
+ switch (status) {
+ case ViewCacheStatus.ValueOk:
+ this.type = 'light';
+ this.msg = '';
+ break;
+ case ViewCacheStatus.ValueNone:
+ this.type = 'info';
+ this.msg =
+ (statusFor ? $localize`Retrieving data for ${statusFor}.` : $localize`Retrieving data.`) +
+ ' ' +
+ $localize`Please wait...`;
+ break;
+ case ViewCacheStatus.ValueStale:
+ this.type = 'warning';
+ this.msg = statusFor
+ ? $localize`Displaying previously cached data for ${statusFor}.`
+ : $localize`Displaying previously cached data.`;
+ break;
+ case ViewCacheStatus.ValueException:
+ this.type = 'danger';
+ this.msg =
+ (statusFor
+ ? $localize`Could not load data for ${statusFor}.`
+ : $localize`Could not load data.`) +
+ ' ' +
+ $localize`Please check the cluster health.`;
+ break;
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status.spec.ts
new file mode 100644
index 000000000..7fa7ba1a4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status.spec.ts
@@ -0,0 +1,15 @@
+import { TableStatus } from './table-status';
+
+describe('TableStatus', () => {
+ it('should create an instance', () => {
+ const ts = new TableStatus();
+ expect(ts).toBeTruthy();
+ expect(ts).toEqual({ msg: '', type: 'light' });
+ });
+
+ it('should create with parameters', () => {
+ const ts = new TableStatus('danger', 'foo');
+ expect(ts).toBeTruthy();
+ expect(ts).toEqual({ msg: 'foo', type: 'danger' });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status.ts
new file mode 100644
index 000000000..fa9be80fe
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status.ts
@@ -0,0 +1,3 @@
+export class TableStatus {
+ constructor(public type: 'info' | 'warning' | 'danger' | 'light' = 'light', public msg = '') {}
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.html
new file mode 100644
index 000000000..be8096427
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.html
@@ -0,0 +1,42 @@
+<ngb-alert type="{{ bootstrapClass }}"
+ [dismissible]="dismissible"
+ (closed)="onClose()">
+ <table>
+ <ng-container *ngIf="size === 'normal'; else slim">
+ <tr>
+ <td *ngIf="showIcon"
+ rowspan="2"
+ class="alert-panel-icon">
+ <i [ngClass]="[icons.large3x]"
+ class="alert-{{ bootstrapClass }} {{ typeIcon }}"
+ aria-hidden="true"></i>
+ </td>
+ <td *ngIf="showTitle"
+ class="alert-panel-title">{{ title }}</td>
+ </tr>
+ <tr>
+ <td class="alert-panel-text">
+ <ng-container *ngTemplateOutlet="content"></ng-container>
+ </td>
+ </tr>
+ </ng-container>
+ <ng-template #slim>
+ <tr>
+ <td *ngIf="showIcon"
+ class="alert-panel-icon">
+ <i class="alert-{{ bootstrapClass }} {{ typeIcon }}"
+ aria-hidden="true"></i>
+ </td>
+ <td *ngIf="showTitle"
+ class="alert-panel-title">{{ title }}</td>
+ <td class="alert-panel-text">
+ <ng-container *ngTemplateOutlet="content"></ng-container>
+ </td>
+ </tr>
+ </ng-template>
+ </table>
+</ngb-alert>
+
+<ng-template #content>
+ <ng-content></ng-content>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.scss
new file mode 100644
index 000000000..6b89d6d3e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.scss
@@ -0,0 +1,12 @@
+.alert-panel-icon {
+ padding-right: 0.5em;
+ vertical-align: top;
+}
+
+.alert-panel-title {
+ font-weight: bold;
+}
+
+.alert {
+ margin-bottom: 0;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.spec.ts
new file mode 100644
index 000000000..4b1f3f7cc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.spec.ts
@@ -0,0 +1,26 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NgbAlertModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { AlertPanelComponent } from './alert-panel.component';
+
+describe('AlertPanelComponent', () => {
+ let component: AlertPanelComponent;
+ let fixture: ComponentFixture<AlertPanelComponent>;
+
+ configureTestBed({
+ declarations: [AlertPanelComponent],
+ imports: [NgbAlertModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AlertPanelComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.ts
new file mode 100644
index 000000000..51088840e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.ts
@@ -0,0 +1,70 @@
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+
+import { Icons } from '~/app/shared/enum/icons.enum';
+
+@Component({
+ selector: 'cd-alert-panel',
+ templateUrl: './alert-panel.component.html',
+ styleUrls: ['./alert-panel.component.scss']
+})
+export class AlertPanelComponent implements OnInit {
+ @Input()
+ title = '';
+ @Input()
+ bootstrapClass = '';
+ @Input()
+ type: 'warning' | 'error' | 'info' | 'success' | 'danger';
+ @Input()
+ typeIcon: Icons | string;
+ @Input()
+ size: 'slim' | 'normal' = 'normal';
+ @Input()
+ showIcon = true;
+ @Input()
+ showTitle = true;
+ @Input()
+ dismissible = false;
+
+ /**
+ * The event that is triggered when the close button (x) has been
+ * pressed.
+ */
+ @Output()
+ dismissed = new EventEmitter();
+
+ icons = Icons;
+
+ ngOnInit() {
+ switch (this.type) {
+ case 'warning':
+ this.title = this.title || $localize`Warning`;
+ this.typeIcon = this.typeIcon || Icons.warning;
+ this.bootstrapClass = this.bootstrapClass || 'warning';
+ break;
+ case 'error':
+ this.title = this.title || $localize`Error`;
+ this.typeIcon = this.typeIcon || Icons.destroyCircle;
+ this.bootstrapClass = this.bootstrapClass || 'danger';
+ break;
+ case 'info':
+ this.title = this.title || $localize`Information`;
+ this.typeIcon = this.typeIcon || Icons.infoCircle;
+ this.bootstrapClass = this.bootstrapClass || 'info';
+ break;
+ case 'success':
+ this.title = this.title || $localize`Success`;
+ this.typeIcon = this.typeIcon || Icons.check;
+ this.bootstrapClass = this.bootstrapClass || 'success';
+ break;
+ case 'danger':
+ this.title = this.title || $localize`Danger`;
+ this.typeIcon = this.typeIcon || Icons.warning;
+ this.bootstrapClass = this.bootstrapClass || 'danger';
+ break;
+ }
+ }
+
+ onClose(): void {
+ this.dismissed.emit();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.html
new file mode 100644
index 000000000..a9090aaf2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.html
@@ -0,0 +1,5 @@
+<button class="btn btn-light tc_backButton"
+ (click)="back()"
+ type="button">
+ {{ name }}
+</button>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.spec.ts
new file mode 100644
index 000000000..d3120a283
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { BackButtonComponent } from './back-button.component';
+
+describe('BackButtonComponent', () => {
+ let component: BackButtonComponent;
+ let fixture: ComponentFixture<BackButtonComponent>;
+
+ configureTestBed({
+ imports: [RouterTestingModule],
+ declarations: [BackButtonComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(BackButtonComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.ts
new file mode 100644
index 000000000..a578f0394
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.ts
@@ -0,0 +1,24 @@
+import { Location } from '@angular/common';
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+
+@Component({
+ selector: 'cd-back-button',
+ templateUrl: './back-button.component.html',
+ styleUrls: ['./back-button.component.scss']
+})
+export class BackButtonComponent {
+ @Output() backAction = new EventEmitter();
+ @Input() name: string = this.actionLabels.CANCEL;
+
+ constructor(private location: Location, private actionLabels: ActionLabelsI18n) {}
+
+ back() {
+ if (this.backAction.observers.length === 0) {
+ this.location.back();
+ } else {
+ this.backAction.emit();
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts
new file mode 100644
index 000000000..a281bf859
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts
@@ -0,0 +1,132 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { RouterModule } from '@angular/router';
+
+import {
+ NgbAlertModule,
+ NgbDatepickerModule,
+ NgbDropdownModule,
+ NgbPopoverModule,
+ NgbProgressbarModule,
+ NgbTimepickerModule,
+ NgbTooltipModule
+} from '@ng-bootstrap/ng-bootstrap';
+import { ClickOutsideModule } from 'ng-click-outside';
+import { ChartsModule } from 'ng2-charts';
+import { SimplebarAngularModule } from 'simplebar-angular';
+
+import { MotdComponent } from '~/app/shared/components/motd/motd.component';
+import { DirectivesModule } from '../directives/directives.module';
+import { PipesModule } from '../pipes/pipes.module';
+import { AlertPanelComponent } from './alert-panel/alert-panel.component';
+import { BackButtonComponent } from './back-button/back-button.component';
+import { ConfigOptionComponent } from './config-option/config-option.component';
+import { ConfirmationModalComponent } from './confirmation-modal/confirmation-modal.component';
+import { Copy2ClipboardButtonComponent } from './copy2clipboard-button/copy2clipboard-button.component';
+import { CriticalConfirmationModalComponent } from './critical-confirmation-modal/critical-confirmation-modal.component';
+import { CustomLoginBannerComponent } from './custom-login-banner/custom-login-banner.component';
+import { DateTimePickerComponent } from './date-time-picker/date-time-picker.component';
+import { DocComponent } from './doc/doc.component';
+import { DownloadButtonComponent } from './download-button/download-button.component';
+import { FormButtonPanelComponent } from './form-button-panel/form-button-panel.component';
+import { FormModalComponent } from './form-modal/form-modal.component';
+import { GrafanaComponent } from './grafana/grafana.component';
+import { HelperComponent } from './helper/helper.component';
+import { LanguageSelectorComponent } from './language-selector/language-selector.component';
+import { LoadingPanelComponent } from './loading-panel/loading-panel.component';
+import { ModalComponent } from './modal/modal.component';
+import { NotificationsSidebarComponent } from './notifications-sidebar/notifications-sidebar.component';
+import { OrchestratorDocPanelComponent } from './orchestrator-doc-panel/orchestrator-doc-panel.component';
+import { PwdExpirationNotificationComponent } from './pwd-expiration-notification/pwd-expiration-notification.component';
+import { RefreshSelectorComponent } from './refresh-selector/refresh-selector.component';
+import { SelectBadgesComponent } from './select-badges/select-badges.component';
+import { SelectComponent } from './select/select.component';
+import { SparklineComponent } from './sparkline/sparkline.component';
+import { SubmitButtonComponent } from './submit-button/submit-button.component';
+import { TelemetryNotificationComponent } from './telemetry-notification/telemetry-notification.component';
+import { UsageBarComponent } from './usage-bar/usage-bar.component';
+import { WizardComponent } from './wizard/wizard.component';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ FormsModule,
+ ReactiveFormsModule,
+ NgbAlertModule,
+ NgbPopoverModule,
+ NgbProgressbarModule,
+ NgbTooltipModule,
+ ChartsModule,
+ ReactiveFormsModule,
+ PipesModule,
+ DirectivesModule,
+ NgbDropdownModule,
+ ClickOutsideModule,
+ SimplebarAngularModule,
+ RouterModule,
+ NgbDatepickerModule,
+ NgbTimepickerModule
+ ],
+ declarations: [
+ SparklineComponent,
+ HelperComponent,
+ SelectBadgesComponent,
+ SubmitButtonComponent,
+ UsageBarComponent,
+ LoadingPanelComponent,
+ ModalComponent,
+ NotificationsSidebarComponent,
+ CriticalConfirmationModalComponent,
+ ConfirmationModalComponent,
+ LanguageSelectorComponent,
+ GrafanaComponent,
+ SelectComponent,
+ BackButtonComponent,
+ RefreshSelectorComponent,
+ ConfigOptionComponent,
+ AlertPanelComponent,
+ FormModalComponent,
+ PwdExpirationNotificationComponent,
+ TelemetryNotificationComponent,
+ OrchestratorDocPanelComponent,
+ DateTimePickerComponent,
+ DocComponent,
+ Copy2ClipboardButtonComponent,
+ DownloadButtonComponent,
+ FormButtonPanelComponent,
+ MotdComponent,
+ WizardComponent,
+ CustomLoginBannerComponent
+ ],
+ providers: [],
+ exports: [
+ SparklineComponent,
+ HelperComponent,
+ SelectBadgesComponent,
+ SubmitButtonComponent,
+ BackButtonComponent,
+ LoadingPanelComponent,
+ UsageBarComponent,
+ ModalComponent,
+ NotificationsSidebarComponent,
+ LanguageSelectorComponent,
+ GrafanaComponent,
+ SelectComponent,
+ RefreshSelectorComponent,
+ ConfigOptionComponent,
+ AlertPanelComponent,
+ PwdExpirationNotificationComponent,
+ TelemetryNotificationComponent,
+ OrchestratorDocPanelComponent,
+ DateTimePickerComponent,
+ DocComponent,
+ Copy2ClipboardButtonComponent,
+ DownloadButtonComponent,
+ FormButtonPanelComponent,
+ MotdComponent,
+ WizardComponent,
+ CustomLoginBannerComponent
+ ]
+})
+export class ComponentsModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.html
new file mode 100644
index 000000000..0b0f87957
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.html
@@ -0,0 +1,77 @@
+<div [formGroup]="optionsFormGroup">
+ <div *ngFor="let option of options; let last = last">
+ <div class="form-group row pt-2"
+ *ngIf="option.type === 'bool'">
+ <label class="cd-col-form-label"
+ [for]="option.name">
+ <b>{{ option.text }}</b>
+ <br>
+ <span class="text-muted">
+ {{ option.desc }}
+ <cd-helper *ngIf="option.long_desc">
+ {{ option.long_desc }}</cd-helper>
+ </span>
+ </label>
+
+ <div class="cd-col-form-input">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ type="checkbox"
+ [id]="option.name"
+ [formControlName]="option.name">
+ <label class="custom-control-label"
+ [for]="option.name"></label>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group row pt-2"
+ *ngIf="option.type !== 'bool'">
+ <label class="cd-col-form-label"
+ [for]="option.name">{{ option.text }}
+ <br>
+ <span class="text-muted">
+ {{ option.desc }}
+ <cd-helper *ngIf="option.long_desc">
+ {{ option.long_desc }}</cd-helper>
+ </span>
+ </label>
+ <div class="cd-col-form-input">
+ <div class="input-group">
+ <input class="form-control"
+ [type]="option.additionalTypeInfo.inputType"
+ [id]="option.name"
+ [placeholder]="option.additionalTypeInfo.humanReadable"
+ [formControlName]="option.name"
+ [step]="getStep(option.type, optionsForm.getValue(option.name))">
+ <div class="input-group-append"
+ *ngIf="optionsFormShowReset">
+ <button class="btn btn-light"
+ type="button"
+ data-toggle="button"
+ title="Remove the custom configuration value. The default configuration will be inherited and used instead."
+ (click)="resetValue(option.name)"
+ i18n-title>
+ <i [ngClass]="[icons.erase]"
+ aria-hidden="true"></i>
+ </button>
+ </div>
+ </div>
+ <span class="invalid-feedback"
+ *ngIf="optionsForm.showError(option.name, optionsFormDir, 'pattern')">
+ {{ option.additionalTypeInfo.patternHelpText }}</span>
+ <span class="invalid-feedback"
+ *ngIf="optionsForm.showError(option.name, optionsFormDir, 'invalidUuid')">
+ {{ option.additionalTypeInfo.patternHelpText }}</span>
+ <span class="invalid-feedback"
+ *ngIf="optionsForm.showError(option.name, optionsFormDir, 'max')"
+ i18n>The entered value is too high! It must not be greater than {{ option.maxValue }}.</span>
+ <span class="invalid-feedback"
+ *ngIf="optionsForm.showError(option.name, optionsFormDir, 'min')"
+ i18n>The entered value is too low! It must not be lower than {{ option.minValue }}.</span>
+ </div>
+ </div>
+ <hr *ngIf="!last"
+ class="my-2">
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.scss
new file mode 100644
index 000000000..e35c2e37b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.scss
@@ -0,0 +1,10 @@
+.custom-checkbox {
+ label,
+ input {
+ cursor: pointer;
+ }
+}
+
+.col-form-label {
+ text-align: left;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.spec.ts
new file mode 100644
index 000000000..200a27615
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.spec.ts
@@ -0,0 +1,295 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+
+import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { of as observableOf } from 'rxjs';
+
+import { ConfigurationService } from '~/app/shared/api/configuration.service';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { HelperComponent } from '../helper/helper.component';
+import { ConfigOptionComponent } from './config-option.component';
+
+describe('ConfigOptionComponent', () => {
+ let component: ConfigOptionComponent;
+ let fixture: ComponentFixture<ConfigOptionComponent>;
+ let configurationService: ConfigurationService;
+ let oNames: Array<string>;
+
+ configureTestBed({
+ declarations: [ConfigOptionComponent, HelperComponent],
+ imports: [NgbPopoverModule, ReactiveFormsModule, HttpClientTestingModule],
+ providers: [ConfigurationService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ConfigOptionComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ configurationService = TestBed.inject(ConfigurationService);
+
+ const configOptions: Record<string, any> = [
+ {
+ name: 'osd_scrub_auto_repair_num_errors',
+ type: 'uint',
+ level: 'advanced',
+ desc: 'Maximum number of detected errors to automatically repair',
+ long_desc: '',
+ default: 5,
+ daemon_default: '',
+ tags: [],
+ services: [],
+ see_also: ['osd_scrub_auto_repair'],
+ min: '',
+ max: '',
+ can_update_at_runtime: true,
+ flags: []
+ },
+ {
+ name: 'osd_debug_deep_scrub_sleep',
+ type: 'float',
+ level: 'dev',
+ desc:
+ 'Inject an expensive sleep during deep scrub IO to make it easier to induce preemption',
+ long_desc: '',
+ default: 0,
+ daemon_default: '',
+ tags: [],
+ services: [],
+ see_also: [],
+ min: '',
+ max: '',
+ can_update_at_runtime: true,
+ flags: []
+ },
+ {
+ name: 'osd_heartbeat_interval',
+ type: 'int',
+ level: 'advanced',
+ desc: 'Interval (in seconds) between peer pings',
+ long_desc: '',
+ default: 6,
+ daemon_default: '',
+ tags: [],
+ services: [],
+ see_also: [],
+ min: 1,
+ max: 86400,
+ can_update_at_runtime: true,
+ flags: [],
+ value: [
+ {
+ section: 'osd',
+ value: 6
+ }
+ ]
+ },
+ {
+ name: 'bluestore_compression_algorithm',
+ type: 'str',
+ level: 'advanced',
+ desc: 'Default compression algorithm to use when writing object data',
+ long_desc:
+ 'This controls the default compressor to use (if any) if the ' +
+ 'per-pool property is not set. Note that zstd is *not* recommended for ' +
+ 'bluestore due to high CPU overhead when compressing small amounts of data.',
+ default: 'snappy',
+ daemon_default: '',
+ tags: [],
+ services: [],
+ see_also: [],
+ enum_values: ['', 'snappy', 'zlib', 'zstd', 'lz4'],
+ min: '',
+ max: '',
+ can_update_at_runtime: true,
+ flags: ['runtime']
+ },
+ {
+ name: 'rbd_discard_on_zeroed_write_same',
+ type: 'bool',
+ level: 'advanced',
+ desc: 'discard data on zeroed write same instead of writing zero',
+ long_desc: '',
+ default: true,
+ daemon_default: '',
+ tags: [],
+ services: ['rbd'],
+ see_also: [],
+ min: '',
+ max: '',
+ can_update_at_runtime: true,
+ flags: []
+ },
+ {
+ name: 'rbd_journal_max_payload_bytes',
+ type: 'size',
+ level: 'advanced',
+ desc: 'maximum journal payload size before splitting',
+ long_desc: '',
+ daemon_default: '',
+ tags: [],
+ services: ['rbd'],
+ see_also: [],
+ min: '',
+ max: '',
+ can_update_at_runtime: true,
+ flags: [],
+ default: '16384'
+ },
+ {
+ name: 'cluster_addr',
+ type: 'addr',
+ level: 'basic',
+ desc: 'cluster-facing address to bind to',
+ long_desc: '',
+ daemon_default: '',
+ tags: ['network'],
+ services: ['osd'],
+ see_also: [],
+ min: '',
+ max: '',
+ can_update_at_runtime: false,
+ flags: [],
+ default: '-'
+ },
+ {
+ name: 'fsid',
+ type: 'uuid',
+ level: 'basic',
+ desc: 'cluster fsid (uuid)',
+ long_desc: '',
+ daemon_default: '',
+ tags: ['service'],
+ services: ['common'],
+ see_also: [],
+ min: '',
+ max: '',
+ can_update_at_runtime: false,
+ flags: ['no_mon_update'],
+ default: '00000000-0000-0000-0000-000000000000'
+ },
+ {
+ name: 'mgr_tick_period',
+ type: 'secs',
+ level: 'advanced',
+ desc: 'Period in seconds of beacon messages to monitor',
+ long_desc: '',
+ daemon_default: '',
+ tags: [],
+ services: ['mgr'],
+ see_also: [],
+ min: '',
+ max: '',
+ can_update_at_runtime: true,
+ flags: [],
+ default: '2'
+ }
+ ];
+
+ spyOn(configurationService, 'filter').and.returnValue(observableOf(configOptions));
+ oNames = _.map(configOptions, 'name');
+ component.optionNames = oNames;
+ component.optionsForm = new CdFormGroup({});
+ component.optionsFormGroupName = 'testFormGroupName';
+ component.ngOnInit();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('optionNameToText', () => {
+ it('should format config option names correctly', () => {
+ const configOptionNames = {
+ osd_scrub_auto_repair_num_errors: 'Scrub Auto Repair Num Errors',
+ osd_debug_deep_scrub_sleep: 'Debug Deep Scrub Sleep',
+ osd_heartbeat_interval: 'Heartbeat Interval',
+ bluestore_compression_algorithm: 'Bluestore Compression Algorithm',
+ rbd_discard_on_zeroed_write_same: 'Rbd Discard On Zeroed Write Same',
+ rbd_journal_max_payload_bytes: 'Rbd Journal Max Payload Bytes',
+ cluster_addr: 'Cluster Addr',
+ fsid: 'Fsid',
+ mgr_tick_period: 'Tick Period'
+ };
+
+ component.options.forEach((option) => {
+ expect(option.text).toEqual(configOptionNames[option.name]);
+ });
+ });
+ });
+
+ describe('createForm', () => {
+ it('should set the optionsFormGroupName correctly', () => {
+ expect(component.optionsFormGroupName).toEqual('testFormGroupName');
+ });
+
+ it('should create a FormControl for every config option', () => {
+ component.options.forEach((option) => {
+ expect(Object.keys(component.optionsFormGroup.controls)).toContain(option.name);
+ });
+ });
+ });
+
+ describe('loadStorageData', () => {
+ it('should create a list of config options by names', () => {
+ expect(component.options.length).toEqual(9);
+
+ component.options.forEach((option) => {
+ expect(oNames).toContain(option.name);
+ });
+ });
+
+ it('should add all needed attributes to every config option', () => {
+ component.options.forEach((option) => {
+ const optionKeys = Object.keys(option);
+ expect(optionKeys).toContain('text');
+ expect(optionKeys).toContain('additionalTypeInfo');
+ expect(optionKeys).toContain('value');
+
+ if (option.type !== 'bool' && option.type !== 'str') {
+ expect(optionKeys).toContain('patternHelpText');
+ }
+
+ if (option.name === 'osd_heartbeat_interval') {
+ expect(optionKeys).toContain('maxValue');
+ expect(optionKeys).toContain('minValue');
+ }
+ });
+ });
+
+ it('should set minValue and maxValue correctly', () => {
+ component.options.forEach((option) => {
+ if (option.name === 'osd_heartbeat_interval') {
+ expect(option.minValue).toEqual(1);
+ expect(option.maxValue).toEqual(86400);
+ }
+ });
+ });
+
+ it('should set the value attribute correctly', () => {
+ component.options.forEach((option) => {
+ if (option.name === 'osd_heartbeat_interval') {
+ const value = option.value;
+ expect(value).toBeDefined();
+ expect(value).toEqual({ section: 'osd', value: 6 });
+ } else {
+ expect(option.value).toBeUndefined();
+ }
+ });
+ });
+
+ it('should set the FormControl value correctly', () => {
+ component.options.forEach((option) => {
+ const value = component.optionsFormGroup.getValue(option.name);
+ if (option.name === 'osd_heartbeat_interval') {
+ expect(value).toBeDefined();
+ expect(value).toEqual(6);
+ } else {
+ expect(value).toBeNull();
+ }
+ });
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.ts
new file mode 100644
index 000000000..2ac8e569a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.ts
@@ -0,0 +1,120 @@
+import { Component, Input, OnInit } from '@angular/core';
+import { FormControl, NgForm } from '@angular/forms';
+
+import _ from 'lodash';
+
+import { ConfigurationService } from '~/app/shared/api/configuration.service';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { ConfigOptionTypes } from './config-option.types';
+
+@Component({
+ selector: 'cd-config-option',
+ templateUrl: './config-option.component.html',
+ styleUrls: ['./config-option.component.scss']
+})
+export class ConfigOptionComponent implements OnInit {
+ @Input()
+ optionNames: Array<string> = [];
+ @Input()
+ optionsForm: CdFormGroup = new CdFormGroup({});
+ @Input()
+ optionsFormDir: NgForm = new NgForm([], []);
+ @Input()
+ optionsFormGroupName = '';
+ @Input()
+ optionsFormShowReset = true;
+
+ icons = Icons;
+ options: Array<any> = [];
+ optionsFormGroup: CdFormGroup = new CdFormGroup({});
+
+ constructor(private configService: ConfigurationService) {}
+
+ private static optionNameToText(optionName: string): string {
+ const sections = ['mon', 'mgr', 'osd', 'mds', 'client'];
+ return optionName
+ .split('_')
+ .filter((c, index) => index !== 0 || !sections.includes(c))
+ .map((c) => c.charAt(0).toUpperCase() + c.substring(1))
+ .join(' ');
+ }
+
+ ngOnInit() {
+ this.createForm();
+ this.loadStoredData();
+ }
+
+ private createForm() {
+ this.optionsForm.addControl(this.optionsFormGroupName, this.optionsFormGroup);
+ this.optionNames.forEach((optionName) => {
+ this.optionsFormGroup.addControl(optionName, new FormControl(null));
+ });
+ }
+
+ getStep(type: string, value: any): number | undefined {
+ return ConfigOptionTypes.getTypeStep(type, value);
+ }
+
+ private loadStoredData() {
+ this.configService.filter(this.optionNames).subscribe((data: any) => {
+ this.options = data.map((configOption: any) => {
+ const formControl = this.optionsForm.get(configOption.name);
+ const typeValidators = ConfigOptionTypes.getTypeValidators(configOption);
+ configOption.additionalTypeInfo = ConfigOptionTypes.getType(configOption.type);
+
+ // Set general information and value
+ configOption.text = ConfigOptionComponent.optionNameToText(configOption.name);
+ configOption.value = _.find(configOption.value, (p) => {
+ return p.section === 'osd'; // TODO: Can handle any other section
+ });
+ if (configOption.value) {
+ if (configOption.additionalTypeInfo.name === 'bool') {
+ formControl.setValue(configOption.value.value === 'true');
+ } else {
+ formControl.setValue(configOption.value.value);
+ }
+ }
+
+ // Set type information and validators
+ if (typeValidators) {
+ configOption.patternHelpText = typeValidators.patternHelpText;
+ if ('max' in typeValidators && typeValidators.max !== '') {
+ configOption.maxValue = typeValidators.max;
+ }
+ if ('min' in typeValidators && typeValidators.min !== '') {
+ configOption.minValue = typeValidators.min;
+ }
+ formControl.setValidators(typeValidators.validators);
+ }
+
+ return configOption;
+ });
+ });
+ }
+
+ saveValues() {
+ const options = {};
+ this.optionNames.forEach((optionName) => {
+ const optionValue = this.optionsForm.getValue(optionName);
+ if (optionValue !== null && optionValue !== '') {
+ options[optionName] = {
+ section: 'osd', // TODO: Can handle any other section
+ value: optionValue
+ };
+ }
+ });
+
+ return this.configService.bulkCreate({ options: options });
+ }
+
+ resetValue(optionName: string) {
+ this.configService.delete(optionName, 'osd').subscribe(
+ // TODO: Can handle any other section
+ () => {
+ const formControl = this.optionsForm.get(optionName);
+ formControl.reset();
+ }
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.model.ts
new file mode 100644
index 000000000..d3ebc5f37
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.model.ts
@@ -0,0 +1,12 @@
+export class ConfigFormModel {
+ name: string;
+ desc: string;
+ long_desc: string;
+ type: string;
+ value: Array<any>;
+ default: any;
+ daemon_default: any;
+ min: any;
+ max: any;
+ services: Array<string>;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.types.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.types.spec.ts
new file mode 100644
index 000000000..8c34111b9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.types.spec.ts
@@ -0,0 +1,272 @@
+import { ConfigFormModel } from './config-option.model';
+import { ConfigOptionTypes } from './config-option.types';
+
+describe('ConfigOptionTypes', () => {
+ describe('getType', () => {
+ it('should return uint type', () => {
+ const ret = ConfigOptionTypes.getType('uint');
+ expect(ret).toBeTruthy();
+ expect(ret.name).toBe('uint');
+ expect(ret.inputType).toBe('number');
+ expect(ret.humanReadable).toBe('Unsigned integer value');
+ expect(ret.defaultMin).toBe(0);
+ expect(ret.patternHelpText).toBe('The entered value needs to be an unsigned number.');
+ expect(ret.isNumberType).toBe(true);
+ expect(ret.allowsNegative).toBe(false);
+ });
+
+ it('should return int type', () => {
+ const ret = ConfigOptionTypes.getType('int');
+ expect(ret).toBeTruthy();
+ expect(ret.name).toBe('int');
+ expect(ret.inputType).toBe('number');
+ expect(ret.humanReadable).toBe('Integer value');
+ expect(ret.defaultMin).toBeUndefined();
+ expect(ret.patternHelpText).toBe('The entered value needs to be a number.');
+ expect(ret.isNumberType).toBe(true);
+ expect(ret.allowsNegative).toBe(true);
+ });
+
+ it('should return size type', () => {
+ const ret = ConfigOptionTypes.getType('size');
+ expect(ret).toBeTruthy();
+ expect(ret.name).toBe('size');
+ expect(ret.inputType).toBe('number');
+ expect(ret.humanReadable).toBe('Unsigned integer value (>=16bit)');
+ expect(ret.defaultMin).toBe(0);
+ expect(ret.patternHelpText).toBe('The entered value needs to be a unsigned number.');
+ expect(ret.isNumberType).toBe(true);
+ expect(ret.allowsNegative).toBe(false);
+ });
+
+ it('should return secs type', () => {
+ const ret = ConfigOptionTypes.getType('secs');
+ expect(ret).toBeTruthy();
+ expect(ret.name).toBe('secs');
+ expect(ret.inputType).toBe('number');
+ expect(ret.humanReadable).toBe('Number of seconds');
+ expect(ret.defaultMin).toBe(1);
+ expect(ret.patternHelpText).toBe('The entered value needs to be a number >= 1.');
+ expect(ret.isNumberType).toBe(true);
+ expect(ret.allowsNegative).toBe(false);
+ });
+
+ it('should return float type', () => {
+ const ret = ConfigOptionTypes.getType('float');
+ expect(ret).toBeTruthy();
+ expect(ret.name).toBe('float');
+ expect(ret.inputType).toBe('number');
+ expect(ret.humanReadable).toBe('Double value');
+ expect(ret.defaultMin).toBeUndefined();
+ expect(ret.patternHelpText).toBe('The entered value needs to be a number or decimal.');
+ expect(ret.isNumberType).toBe(true);
+ expect(ret.allowsNegative).toBe(true);
+ });
+
+ it('should return str type', () => {
+ const ret = ConfigOptionTypes.getType('str');
+ expect(ret).toBeTruthy();
+ expect(ret.name).toBe('str');
+ expect(ret.inputType).toBe('text');
+ expect(ret.humanReadable).toBe('Text');
+ expect(ret.defaultMin).toBeUndefined();
+ expect(ret.patternHelpText).toBeUndefined();
+ expect(ret.isNumberType).toBe(false);
+ expect(ret.allowsNegative).toBeUndefined();
+ });
+
+ it('should return addr type', () => {
+ const ret = ConfigOptionTypes.getType('addr');
+ expect(ret).toBeTruthy();
+ expect(ret.name).toBe('addr');
+ expect(ret.inputType).toBe('text');
+ expect(ret.humanReadable).toBe('IPv4 or IPv6 address');
+ expect(ret.defaultMin).toBeUndefined();
+ expect(ret.patternHelpText).toBe('The entered value needs to be a valid IP address.');
+ expect(ret.isNumberType).toBe(false);
+ expect(ret.allowsNegative).toBeUndefined();
+ });
+
+ it('should return uuid type', () => {
+ const ret = ConfigOptionTypes.getType('uuid');
+ expect(ret).toBeTruthy();
+ expect(ret.name).toBe('uuid');
+ expect(ret.inputType).toBe('text');
+ expect(ret.humanReadable).toBe('UUID');
+ expect(ret.defaultMin).toBeUndefined();
+ expect(ret.patternHelpText).toBe(
+ 'The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8'
+ );
+ expect(ret.isNumberType).toBe(false);
+ expect(ret.allowsNegative).toBeUndefined();
+ });
+
+ it('should return bool type', () => {
+ const ret = ConfigOptionTypes.getType('bool');
+ expect(ret).toBeTruthy();
+ expect(ret.name).toBe('bool');
+ expect(ret.inputType).toBe('checkbox');
+ expect(ret.humanReadable).toBe('Boolean value');
+ expect(ret.defaultMin).toBeUndefined();
+ expect(ret.patternHelpText).toBeUndefined();
+ expect(ret.isNumberType).toBe(false);
+ expect(ret.allowsNegative).toBeUndefined();
+ });
+
+ it('should throw an error for unknown type', () => {
+ expect(() => ConfigOptionTypes.getType('unknown')).toThrowError(
+ 'Found unknown type "unknown" for config option.'
+ );
+ });
+ });
+
+ describe('getTypeValidators', () => {
+ it('should return two validators for type uint, secs and size', () => {
+ const types = ['uint', 'size', 'secs'];
+
+ types.forEach((valType) => {
+ const configOption = new ConfigFormModel();
+ configOption.type = valType;
+
+ const ret = ConfigOptionTypes.getTypeValidators(configOption);
+ expect(ret).toBeTruthy();
+ expect(ret.validators.length).toBe(2);
+ });
+ });
+
+ it('should return a validator for types float, int, addr and uuid', () => {
+ const types = ['float', 'int', 'addr', 'uuid'];
+
+ types.forEach((valType) => {
+ const configOption = new ConfigFormModel();
+ configOption.type = valType;
+
+ const ret = ConfigOptionTypes.getTypeValidators(configOption);
+ expect(ret).toBeTruthy();
+ expect(ret.validators.length).toBe(1);
+ });
+ });
+
+ it('should return undefined for type bool and str', () => {
+ const types = ['str', 'bool'];
+
+ types.forEach((valType) => {
+ const configOption = new ConfigFormModel();
+ configOption.type = valType;
+
+ const ret = ConfigOptionTypes.getTypeValidators(configOption);
+ expect(ret).toBeUndefined();
+ });
+ });
+
+ it('should return a pattern and a min validator', () => {
+ const configOption = new ConfigFormModel();
+ configOption.type = 'int';
+ configOption.min = 2;
+
+ const ret = ConfigOptionTypes.getTypeValidators(configOption);
+ expect(ret).toBeTruthy();
+ expect(ret.validators.length).toBe(2);
+ expect(ret.min).toBe(2);
+ expect(ret.max).toBeUndefined();
+ });
+
+ it('should return a pattern and a max validator', () => {
+ const configOption = new ConfigFormModel();
+ configOption.type = 'int';
+ configOption.max = 5;
+
+ const ret = ConfigOptionTypes.getTypeValidators(configOption);
+ expect(ret).toBeTruthy();
+ expect(ret.validators.length).toBe(2);
+ expect(ret.min).toBeUndefined();
+ expect(ret.max).toBe(5);
+ });
+
+ it('should return multiple validators', () => {
+ const configOption = new ConfigFormModel();
+ configOption.type = 'float';
+ configOption.max = 5.2;
+ configOption.min = 1.5;
+
+ const ret = ConfigOptionTypes.getTypeValidators(configOption);
+ expect(ret).toBeTruthy();
+ expect(ret.validators.length).toBe(3);
+ expect(ret.min).toBe(1.5);
+ expect(ret.max).toBe(5.2);
+ });
+
+ it(
+ 'should return a pattern help text for type uint, int, size, secs, ' + 'float, addr and uuid',
+ () => {
+ const types = ['uint', 'int', 'size', 'secs', 'float', 'addr', 'uuid'];
+
+ types.forEach((valType) => {
+ const configOption = new ConfigFormModel();
+ configOption.type = valType;
+
+ const ret = ConfigOptionTypes.getTypeValidators(configOption);
+ expect(ret).toBeTruthy();
+ expect(ret.patternHelpText).toBeDefined();
+ });
+ }
+ );
+ });
+
+ describe('getTypeStep', () => {
+ it('should return the correct step for type uint and value 0', () => {
+ const ret = ConfigOptionTypes.getTypeStep('uint', 0);
+ expect(ret).toBe(1);
+ });
+
+ it('should return the correct step for type int and value 1', () => {
+ const ret = ConfigOptionTypes.getTypeStep('int', 1);
+ expect(ret).toBe(1);
+ });
+
+ it('should return the correct step for type int and value null', () => {
+ const ret = ConfigOptionTypes.getTypeStep('int', null);
+ expect(ret).toBe(1);
+ });
+
+ it('should return the correct step for type size and value 2', () => {
+ const ret = ConfigOptionTypes.getTypeStep('size', 2);
+ expect(ret).toBe(1);
+ });
+
+ it('should return the correct step for type secs and value 3', () => {
+ const ret = ConfigOptionTypes.getTypeStep('secs', 3);
+ expect(ret).toBe(1);
+ });
+
+ it('should return the correct step for type float and value 1', () => {
+ const ret = ConfigOptionTypes.getTypeStep('float', 1);
+ expect(ret).toBe(0.1);
+ });
+
+ it('should return the correct step for type float and value 0.1', () => {
+ const ret = ConfigOptionTypes.getTypeStep('float', 0.1);
+ expect(ret).toBe(0.1);
+ });
+
+ it('should return the correct step for type float and value 0.02', () => {
+ const ret = ConfigOptionTypes.getTypeStep('float', 0.02);
+ expect(ret).toBe(0.01);
+ });
+
+ it('should return the correct step for type float and value 0.003', () => {
+ const ret = ConfigOptionTypes.getTypeStep('float', 0.003);
+ expect(ret).toBe(0.001);
+ });
+
+ it('should return the correct step for type float and value null', () => {
+ const ret = ConfigOptionTypes.getTypeStep('float', null);
+ expect(ret).toBe(0.1);
+ });
+
+ it('should return undefined for unknown type', () => {
+ const ret = ConfigOptionTypes.getTypeStep('unknown', 1);
+ expect(ret).toBeUndefined();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.types.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.types.ts
new file mode 100644
index 000000000..33336652c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.types.ts
@@ -0,0 +1,147 @@
+import { Validators } from '@angular/forms';
+
+import _ from 'lodash';
+
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { ConfigFormModel } from './config-option.model';
+
+export class ConfigOptionTypes {
+ // TODO: I18N
+ private static knownTypes: Array<any> = [
+ {
+ name: 'uint',
+ inputType: 'number',
+ humanReadable: 'Unsigned integer value',
+ defaultMin: 0,
+ patternHelpText: 'The entered value needs to be an unsigned number.',
+ isNumberType: true,
+ allowsNegative: false
+ },
+ {
+ name: 'int',
+ inputType: 'number',
+ humanReadable: 'Integer value',
+ patternHelpText: 'The entered value needs to be a number.',
+ isNumberType: true,
+ allowsNegative: true
+ },
+ {
+ name: 'size',
+ inputType: 'number',
+ humanReadable: 'Unsigned integer value (>=16bit)',
+ defaultMin: 0,
+ patternHelpText: 'The entered value needs to be a unsigned number.',
+ isNumberType: true,
+ allowsNegative: false
+ },
+ {
+ name: 'secs',
+ inputType: 'number',
+ humanReadable: 'Number of seconds',
+ defaultMin: 1,
+ patternHelpText: 'The entered value needs to be a number >= 1.',
+ isNumberType: true,
+ allowsNegative: false
+ },
+ {
+ name: 'float',
+ inputType: 'number',
+ humanReadable: 'Double value',
+ patternHelpText: 'The entered value needs to be a number or decimal.',
+ isNumberType: true,
+ allowsNegative: true
+ },
+ { name: 'str', inputType: 'text', humanReadable: 'Text', isNumberType: false },
+ {
+ name: 'addr',
+ inputType: 'text',
+ humanReadable: 'IPv4 or IPv6 address',
+ patternHelpText: 'The entered value needs to be a valid IP address.',
+ isNumberType: false
+ },
+ {
+ name: 'uuid',
+ inputType: 'text',
+ humanReadable: 'UUID',
+ patternHelpText:
+ 'The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8',
+ isNumberType: false
+ },
+ { name: 'bool', inputType: 'checkbox', humanReadable: 'Boolean value', isNumberType: false }
+ ];
+
+ public static getType(type: string): any {
+ const currentType = _.find(this.knownTypes, (t) => {
+ return t.name === type;
+ });
+
+ if (currentType !== undefined) {
+ return currentType;
+ }
+
+ throw new Error('Found unknown type "' + type + '" for config option.');
+ }
+
+ public static getTypeValidators(configOption: ConfigFormModel): any {
+ const typeParams = ConfigOptionTypes.getType(configOption.type);
+
+ if (typeParams.name === 'bool' || typeParams.name === 'str') {
+ return;
+ }
+
+ const typeValidators: Record<string, any> = {
+ validators: [],
+ patternHelpText: typeParams.patternHelpText
+ };
+
+ if (typeParams.isNumberType) {
+ if (configOption.max && configOption.max !== '') {
+ typeValidators['max'] = configOption.max;
+ typeValidators.validators.push(Validators.max(configOption.max));
+ }
+
+ if (configOption.min && configOption.min !== '') {
+ typeValidators['min'] = configOption.min;
+ typeValidators.validators.push(Validators.min(configOption.min));
+ } else if ('defaultMin' in typeParams) {
+ typeValidators['min'] = typeParams.defaultMin;
+ typeValidators.validators.push(Validators.min(typeParams.defaultMin));
+ }
+
+ if (configOption.type === 'float') {
+ typeValidators.validators.push(CdValidators.decimalNumber());
+ } else {
+ typeValidators.validators.push(CdValidators.number(typeParams.allowsNegative));
+ }
+ } else if (configOption.type === 'addr') {
+ typeValidators.validators = [CdValidators.ip()];
+ } else if (configOption.type === 'uuid') {
+ typeValidators.validators = [CdValidators.uuid()];
+ }
+
+ return typeValidators;
+ }
+
+ public static getTypeStep(type: string, value: number): number | undefined {
+ const numberTypes = ['uint', 'int', 'size', 'secs'];
+
+ if (numberTypes.includes(type)) {
+ return 1;
+ }
+
+ if (type === 'float') {
+ if (value !== null) {
+ const stringVal = value.toString();
+ if (stringVal.indexOf('.') !== -1) {
+ // Value type float and contains decimal characters
+ const decimal = value.toString().split('.');
+ return Math.pow(10, -decimal[1].length);
+ }
+ }
+
+ return 0.1;
+ }
+
+ return undefined;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.html
new file mode 100644
index 000000000..294d43f77
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.html
@@ -0,0 +1,27 @@
+<cd-modal (hide)="cancel()">
+ <ng-container class="modal-title">
+ <span class="text-warning"
+ *ngIf="warning">
+ <i class="fa fa-exclamation-triangle fa-1x"></i>
+ </span>{{ titleText }}</ng-container>
+ <ng-container class="modal-content">
+ <form name="confirmationForm"
+ #formDir="ngForm"
+ [formGroup]="confirmationForm"
+ novalidate>
+ <div class="modal-body">
+ <ng-container *ngTemplateOutlet="bodyTpl; context: bodyContext"></ng-container>
+ <p *ngIf="description">
+ {{description}}
+ </p>
+ </div>
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="onSubmit(confirmationForm.value)"
+ (backActionEvent)="boundCancel()"
+ [form]="confirmationForm"
+ [submitText]="buttonText"
+ [showSubmit]="showSubmit"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.spec.ts
new file mode 100644
index 000000000..a76c5d378
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.spec.ts
@@ -0,0 +1,185 @@
+import { Component, NgModule, NO_ERRORS_SCHEMA, TemplateRef, ViewChild } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal, NgbModalModule, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+
+import { ModalService } from '~/app/shared/services/modal.service';
+import { configureTestBed, FixtureHelper } from '~/testing/unit-test-helper';
+import { BackButtonComponent } from '../back-button/back-button.component';
+import { FormButtonPanelComponent } from '../form-button-panel/form-button-panel.component';
+import { ModalComponent } from '../modal/modal.component';
+import { SubmitButtonComponent } from '../submit-button/submit-button.component';
+import { ConfirmationModalComponent } from './confirmation-modal.component';
+
+@NgModule({})
+export class MockModule {}
+
+@Component({
+ template: `<ng-template #fillTpl>Template based description.</ng-template>`
+})
+class MockComponent {
+ @ViewChild('fillTpl', { static: true })
+ fillTpl: TemplateRef<any>;
+ modalRef: NgbModalRef;
+ returnValue: any;
+
+ // Normally private, but public is needed by tests
+ constructor(public modalService: ModalService) {}
+
+ private openModal(extendBaseState = {}) {
+ this.modalRef = this.modalService.show(
+ ConfirmationModalComponent,
+ Object.assign(
+ {
+ titleText: 'Title is a must have',
+ buttonText: 'Action label',
+ bodyTpl: this.fillTpl,
+ description: 'String based description.',
+ onSubmit: () => {
+ this.returnValue = 'The submit action has to hide manually.';
+ }
+ },
+ extendBaseState
+ )
+ );
+ }
+
+ basicModal() {
+ this.openModal();
+ }
+
+ customCancelModal() {
+ this.openModal({
+ onCancel: () => (this.returnValue = 'If you have todo something besides hiding the modal.')
+ });
+ }
+}
+
+describe('ConfirmationModalComponent', () => {
+ let component: ConfirmationModalComponent;
+ let fixture: ComponentFixture<ConfirmationModalComponent>;
+ let mockComponent: MockComponent;
+ let mockFixture: ComponentFixture<MockComponent>;
+ let fh: FixtureHelper;
+
+ const expectReturnValue = (v: string) => expect(mockComponent.returnValue).toBe(v);
+
+ configureTestBed({
+ declarations: [
+ ConfirmationModalComponent,
+ BackButtonComponent,
+ MockComponent,
+ ModalComponent,
+ SubmitButtonComponent,
+ FormButtonPanelComponent
+ ],
+ schemas: [NO_ERRORS_SCHEMA],
+ imports: [ReactiveFormsModule, MockModule, RouterTestingModule, NgbModalModule],
+ providers: [NgbActiveModal, SubmitButtonComponent, FormButtonPanelComponent]
+ });
+
+ beforeEach(() => {
+ fh = new FixtureHelper();
+ mockFixture = TestBed.createComponent(MockComponent);
+ mockComponent = mockFixture.componentInstance;
+ mockFixture.detectChanges();
+
+ spyOn(TestBed.inject(ModalService), 'show').and.callFake((_modalComp, config) => {
+ fixture = TestBed.createComponent(ConfirmationModalComponent);
+ component = fixture.componentInstance;
+ component = Object.assign(component, config);
+ component.activeModal = { close: () => true } as any;
+ spyOn(component.activeModal, 'close').and.callThrough();
+ fh.updateFixture(fixture);
+ });
+ });
+
+ it('should create', () => {
+ mockComponent.basicModal();
+ expect(component).toBeTruthy();
+ });
+
+ describe('Throws errors', () => {
+ const expectError = (config: object, expected: string) => {
+ mockComponent.basicModal();
+ component = Object.assign(component, config);
+ expect(() => component.ngOnInit()).toThrowError(expected);
+ };
+
+ it('has no submit action defined', () => {
+ expectError(
+ {
+ onSubmit: undefined
+ },
+ 'No submit action defined'
+ );
+ });
+
+ it('has no title defined', () => {
+ expectError(
+ {
+ titleText: undefined
+ },
+ 'No title defined'
+ );
+ });
+
+ it('has no action name defined', () => {
+ expectError(
+ {
+ buttonText: undefined
+ },
+ 'No action name defined'
+ );
+ });
+
+ it('has no description defined', () => {
+ expectError(
+ {
+ bodyTpl: undefined,
+ description: undefined
+ },
+ 'No description defined'
+ );
+ });
+ });
+
+ describe('basics', () => {
+ beforeEach(() => {
+ mockComponent.basicModal();
+ spyOn(component, 'onSubmit').and.callThrough();
+ });
+
+ it('should show the correct title', () => {
+ expect(fh.getText('.modal-title')).toBe('Title is a must have');
+ });
+
+ it('should show the correct action name', () => {
+ expect(fh.getText('.tc_submitButton')).toBe('Action label');
+ });
+
+ it('should use the correct submit action', () => {
+ // In order to ignore the `ElementRef` usage of `SubmitButtonComponent`
+ spyOn(fh.getElementByCss('.tc_submitButton').componentInstance, 'focusButton');
+ fh.clickElement('.tc_submitButton');
+ expect(component.onSubmit).toHaveBeenCalledTimes(1);
+ expect(component.activeModal.close).toHaveBeenCalledTimes(0);
+ expectReturnValue('The submit action has to hide manually.');
+ });
+
+ it('should use the default cancel action', () => {
+ fh.clickElement('.tc_backButton');
+ expect(component.onSubmit).toHaveBeenCalledTimes(0);
+ expect(component.activeModal.close).toHaveBeenCalledTimes(1);
+ expectReturnValue(undefined);
+ });
+
+ it('should show the description', () => {
+ expect(fh.getText('.modal-body')).toBe(
+ 'Template based description. String based description.'
+ );
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.ts
new file mode 100644
index 000000000..fe5624981
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.ts
@@ -0,0 +1,65 @@
+import { Component, OnDestroy, OnInit, TemplateRef } from '@angular/core';
+import { FormGroup } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+@Component({
+ selector: 'cd-confirmation-modal',
+ templateUrl: './confirmation-modal.component.html',
+ styleUrls: ['./confirmation-modal.component.scss']
+})
+export class ConfirmationModalComponent implements OnInit, OnDestroy {
+ // Needed
+ buttonText: string;
+ titleText: string;
+ onSubmit: Function;
+
+ // One of them is needed
+ bodyTpl?: TemplateRef<any>;
+ description?: TemplateRef<any>;
+
+ // Optional
+ warning = false;
+ bodyData?: object;
+ onCancel?: Function;
+ bodyContext?: object;
+ showSubmit = true;
+
+ // Component only
+ boundCancel = this.cancel.bind(this);
+ confirmationForm: FormGroup;
+ private canceled = false;
+
+ constructor(public activeModal: NgbActiveModal) {
+ this.confirmationForm = new FormGroup({});
+ }
+
+ ngOnInit() {
+ this.bodyContext = this.bodyContext || {};
+ this.bodyContext['$implicit'] = this.bodyData;
+ if (!this.onSubmit) {
+ throw new Error('No submit action defined');
+ } else if (!this.buttonText) {
+ throw new Error('No action name defined');
+ } else if (!this.titleText) {
+ throw new Error('No title defined');
+ } else if (!this.bodyTpl && !this.description) {
+ throw new Error('No description defined');
+ }
+ }
+
+ ngOnDestroy() {
+ if (this.onCancel && this.canceled) {
+ this.onCancel();
+ }
+ }
+
+ cancel() {
+ this.canceled = true;
+ this.activeModal.close();
+ }
+
+ stopLoadingSpinner() {
+ this.confirmationForm.setErrors({ cdSubmitButton: true });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html
new file mode 100644
index 000000000..25a3f3cfe
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html
@@ -0,0 +1,7 @@
+<button (click)="onClick()"
+ type="button"
+ class="btn btn-light"
+ i18n-title
+ title="Copy to Clipboard">
+ <i [ngClass]="[icons.clipboard]"></i>
+</button>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.spec.ts
new file mode 100644
index 000000000..2842793c6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.spec.ts
@@ -0,0 +1,65 @@
+import { TestBed } from '@angular/core/testing';
+
+import * as BrowserDetect from 'detect-browser';
+import { ToastrService } from 'ngx-toastr';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { Copy2ClipboardButtonComponent } from './copy2clipboard-button.component';
+
+describe('Copy2ClipboardButtonComponent', () => {
+ let component: Copy2ClipboardButtonComponent;
+
+ configureTestBed({
+ providers: [
+ {
+ provide: ToastrService,
+ useValue: {
+ error: () => true,
+ success: () => true
+ }
+ }
+ ]
+ });
+
+ it('should create an instance', () => {
+ component = new Copy2ClipboardButtonComponent(null);
+ expect(component).toBeTruthy();
+ });
+
+ describe('test onClick behaviours', () => {
+ let toastrService: ToastrService;
+ let queryFn: jasmine.Spy;
+ let writeTextFn: jasmine.Spy;
+
+ beforeEach(() => {
+ toastrService = TestBed.inject(ToastrService);
+ component = new Copy2ClipboardButtonComponent(toastrService);
+ spyOn<any>(component, 'getText').and.returnValue('foo');
+ Object.assign(navigator, {
+ permissions: { query: jest.fn() },
+ clipboard: {
+ writeText: jest.fn()
+ }
+ });
+ queryFn = spyOn(navigator.permissions, 'query');
+ });
+
+ it('should not call permissions API', () => {
+ spyOn(BrowserDetect, 'detect').and.returnValue({ name: 'firefox' });
+ writeTextFn = spyOn(navigator.clipboard, 'writeText').and.returnValue(
+ new Promise<void>((resolve, _) => {
+ resolve();
+ })
+ );
+ component.onClick();
+ expect(queryFn).not.toHaveBeenCalled();
+ expect(writeTextFn).toHaveBeenCalledWith('foo');
+ });
+
+ it('should call permissions API', () => {
+ spyOn(BrowserDetect, 'detect').and.returnValue({ name: 'chrome' });
+ component.onClick();
+ expect(queryFn).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.ts
new file mode 100644
index 000000000..2cc656bfc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.ts
@@ -0,0 +1,55 @@
+import { Component, HostListener, Input } from '@angular/core';
+
+import { detect } from 'detect-browser';
+import { ToastrService } from 'ngx-toastr';
+
+import { Icons } from '~/app/shared/enum/icons.enum';
+
+@Component({
+ selector: 'cd-copy-2-clipboard-button',
+ templateUrl: './copy2clipboard-button.component.html',
+ styleUrls: ['./copy2clipboard-button.component.scss']
+})
+export class Copy2ClipboardButtonComponent {
+ @Input()
+ private source: string;
+
+ @Input()
+ byId = true;
+
+ icons = Icons;
+
+ constructor(private toastr: ToastrService) {}
+
+ private getText(): string {
+ const element = document.getElementById(this.source) as HTMLInputElement;
+ return element.value;
+ }
+
+ @HostListener('click')
+ onClick() {
+ try {
+ const browser = detect();
+ const text = this.byId ? this.getText() : this.source;
+ const toastrFn = () => {
+ this.toastr.success('Copied text to the clipboard successfully.');
+ };
+ if (['firefox', 'ie', 'ios', 'safari'].includes(browser.name)) {
+ // Various browsers do not support the `Permissions API`.
+ // https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API#Browser_compatibility
+ navigator.clipboard.writeText(text).then(() => toastrFn());
+ } else {
+ // Checking if we have the clipboard-write permission
+ navigator.permissions
+ .query({ name: 'clipboard-write' as PermissionName })
+ .then((result: any) => {
+ if (result.state === 'granted' || result.state === 'prompt') {
+ navigator.clipboard.writeText(text).then(() => toastrFn());
+ }
+ });
+ }
+ } catch (_) {
+ this.toastr.error('Failed to copy text to the clipboard.');
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html
new file mode 100644
index 000000000..29b669b14
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html
@@ -0,0 +1,55 @@
+<cd-modal #modal
+ [modalRef]="activeModal">
+ <ng-container class="modal-title">
+ <ng-container *ngTemplateOutlet="deletionHeading"></ng-container>
+ </ng-container>
+
+ <ng-container class="modal-content">
+ <form name="deletionForm"
+ #formDir="ngForm"
+ [formGroup]="deletionForm"
+ novalidate>
+ <div class="modal-body">
+ <ng-container *ngTemplateOutlet="bodyTemplate; context: bodyContext"></ng-container>
+ <div class="question">
+ <span *ngIf="itemNames; else noNames">
+ <p *ngIf="itemNames.length === 1; else manyNames"
+ i18n>Are you sure that you want to {{ actionDescription | lowercase }} <strong>{{ itemNames[0] }}</strong>?</p>
+ <ng-template #manyNames>
+ <p i18n>Are you sure that you want to {{ actionDescription | lowercase }} the selected items?</p>
+ <ul>
+ <li *ngFor="let itemName of itemNames"><strong>{{ itemName }}</strong></li>
+ </ul>
+ </ng-template >
+ </span>
+ <ng-template #noNames>
+ <p i18n>Are you sure that you want to {{ actionDescription | lowercase }} the selected {{ itemDescription }}?</p>
+ </ng-template>
+ <ng-container *ngTemplateOutlet="childFormGroupTemplate; context:{form:deletionForm}"></ng-container>
+ <div class="form-group">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ name="confirmation"
+ id="confirmation"
+ formControlName="confirmation"
+ autofocus>
+ <label class="custom-control-label"
+ for="confirmation"
+ i18n>Yes, I am sure.</label>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="callSubmitAction()"
+ [form]="deletionForm"
+ [submitText]="(actionDescription | titlecase) + ' ' + itemDescription"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
+
+<ng-template #deletionHeading>
+ {{ actionDescription | titlecase }} {{ itemDescription }}
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.scss
new file mode 100644
index 000000000..979cb13fe
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.scss
@@ -0,0 +1,11 @@
+.modal-body .question {
+ margin-top: 1em;
+}
+
+.modal-body label {
+ font-weight: bold;
+}
+
+.modal-body .question .form-check {
+ padding-top: 7px;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.spec.ts
new file mode 100644
index 000000000..e501d9f32
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.spec.ts
@@ -0,0 +1,235 @@
+import { Component, NgModule, NO_ERRORS_SCHEMA, TemplateRef, ViewChild } from '@angular/core';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { NgForm, ReactiveFormsModule } from '@angular/forms';
+
+import { NgbActiveModal, NgbModalModule, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { Observable, Subscriber, timer as observableTimer } from 'rxjs';
+
+import { DirectivesModule } from '~/app/shared/directives/directives.module';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { configureTestBed, modalServiceShow } from '~/testing/unit-test-helper';
+import { AlertPanelComponent } from '../alert-panel/alert-panel.component';
+import { LoadingPanelComponent } from '../loading-panel/loading-panel.component';
+import { CriticalConfirmationModalComponent } from './critical-confirmation-modal.component';
+
+@NgModule({})
+export class MockModule {}
+
+@Component({
+ template: `
+ <button type="button" class="btn btn-danger" (click)="openCtrlDriven()">
+ <i class="fa fa-times"></i>Deletion Ctrl-Test
+ <ng-template #ctrlDescription>
+ The spinner is handled by the controller if you have use the modal as ViewChild in order to
+ use it's functions to stop the spinner or close the dialog.
+ </ng-template>
+ </button>
+
+ <button type="button" class="btn btn-danger" (click)="openModalDriven()">
+ <i class="fa fa-times"></i>Deletion Modal-Test
+ <ng-template #modalDescription>
+ The spinner is handled by the modal if your given deletion function returns a Observable.
+ </ng-template>
+ </button>
+ `
+})
+class MockComponent {
+ @ViewChild('ctrlDescription', { static: true })
+ ctrlDescription: TemplateRef<any>;
+ @ViewChild('modalDescription', { static: true })
+ modalDescription: TemplateRef<any>;
+ someData = [1, 2, 3, 4, 5];
+ finished: number[];
+ ctrlRef: NgbModalRef;
+ modalRef: NgbModalRef;
+
+ // Normally private - public was needed for the tests
+ constructor(public modalService: ModalService) {}
+
+ openCtrlDriven() {
+ this.ctrlRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ submitAction: this.fakeDeleteController.bind(this),
+ bodyTemplate: this.ctrlDescription
+ });
+ }
+
+ openModalDriven() {
+ this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+ submitActionObservable: this.fakeDelete(),
+ bodyTemplate: this.modalDescription
+ });
+ }
+
+ finish() {
+ this.finished = [6, 7, 8, 9];
+ }
+
+ fakeDelete() {
+ return (): Observable<any> => {
+ return new Observable((observer: Subscriber<any>) => {
+ observableTimer(100).subscribe(() => {
+ observer.next(this.finish());
+ observer.complete();
+ });
+ });
+ };
+ }
+
+ fakeDeleteController() {
+ observableTimer(100).subscribe(() => {
+ this.finish();
+ this.ctrlRef.close();
+ });
+ }
+}
+
+describe('CriticalConfirmationModalComponent', () => {
+ let mockComponent: MockComponent;
+ let component: CriticalConfirmationModalComponent;
+ let mockFixture: ComponentFixture<MockComponent>;
+
+ configureTestBed(
+ {
+ declarations: [
+ MockComponent,
+ CriticalConfirmationModalComponent,
+ LoadingPanelComponent,
+ AlertPanelComponent
+ ],
+ schemas: [NO_ERRORS_SCHEMA],
+ imports: [ReactiveFormsModule, MockModule, DirectivesModule, NgbModalModule],
+ providers: [NgbActiveModal]
+ },
+ [CriticalConfirmationModalComponent]
+ );
+
+ beforeEach(() => {
+ mockFixture = TestBed.createComponent(MockComponent);
+ mockComponent = mockFixture.componentInstance;
+ spyOn(mockComponent.modalService, 'show').and.callFake((_modalComp, config) => {
+ const data = modalServiceShow(CriticalConfirmationModalComponent, config);
+ component = data.componentInstance;
+ return data;
+ });
+ mockComponent.openCtrlDriven();
+ mockFixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should throw an error if no action is defined', () => {
+ component = Object.assign(component, {
+ submitAction: null,
+ submitActionObservable: null
+ });
+ expect(() => component.ngOnInit()).toThrowError('No submit action defined');
+ });
+
+ it('should test if the ctrl driven mock is set correctly through mock component', () => {
+ expect(component.bodyTemplate).toBeTruthy();
+ expect(component.submitAction).toBeTruthy();
+ expect(component.submitActionObservable).not.toBeTruthy();
+ });
+
+ it('should test if the modal driven mock is set correctly through mock component', () => {
+ mockComponent.openModalDriven();
+ expect(component.bodyTemplate).toBeTruthy();
+ expect(component.submitActionObservable).toBeTruthy();
+ expect(component.submitAction).not.toBeTruthy();
+ });
+
+ describe('component functions', () => {
+ const changeValue = (value: boolean) => {
+ const ctrl = component.deletionForm.get('confirmation');
+ ctrl.setValue(value);
+ ctrl.markAsDirty();
+ ctrl.updateValueAndValidity();
+ mockFixture.detectChanges();
+ };
+
+ it('should test hideModal', () => {
+ expect(component.activeModal).toBeTruthy();
+ expect(component.hideModal).toBeTruthy();
+ spyOn(component.activeModal, 'close').and.callThrough();
+ expect(component.activeModal.close).not.toHaveBeenCalled();
+ component.hideModal();
+ expect(component.activeModal.close).toHaveBeenCalled();
+ });
+
+ describe('validate confirmation', () => {
+ const testValidation = (submitted: boolean, error: string, expected: boolean) => {
+ expect(
+ component.deletionForm.showError('confirmation', <NgForm>{ submitted: submitted }, error)
+ ).toBe(expected);
+ };
+
+ beforeEach(() => {
+ component.deletionForm.reset();
+ });
+
+ it('should test empty values', () => {
+ component.deletionForm.reset();
+ testValidation(false, undefined, false);
+ testValidation(true, 'required', true);
+ component.deletionForm.reset();
+ changeValue(true);
+ changeValue(false);
+ testValidation(true, 'required', true);
+ });
+ });
+
+ describe('deletion call', () => {
+ beforeEach(() => {
+ spyOn(component, 'stopLoadingSpinner').and.callThrough();
+ spyOn(component, 'hideModal').and.callThrough();
+ });
+
+ describe('Controller driven', () => {
+ beforeEach(() => {
+ spyOn(component, 'submitAction').and.callThrough();
+ spyOn(mockComponent.ctrlRef, 'close').and.callThrough();
+ });
+
+ it('should test fake deletion that closes modal', fakeAsync(() => {
+ // Before deletionCall
+ expect(component.submitAction).not.toHaveBeenCalled();
+ // During deletionCall
+ component.callSubmitAction();
+ expect(component.stopLoadingSpinner).not.toHaveBeenCalled();
+ expect(component.hideModal).not.toHaveBeenCalled();
+ expect(mockComponent.ctrlRef.close).not.toHaveBeenCalled();
+ expect(component.submitAction).toHaveBeenCalled();
+ expect(mockComponent.finished).toBe(undefined);
+ // After deletionCall
+ tick(2000);
+ expect(component.hideModal).not.toHaveBeenCalled();
+ expect(mockComponent.ctrlRef.close).toHaveBeenCalled();
+ expect(mockComponent.finished).toEqual([6, 7, 8, 9]);
+ }));
+ });
+
+ describe('Modal driven', () => {
+ beforeEach(() => {
+ mockComponent.openModalDriven();
+ spyOn(component, 'stopLoadingSpinner').and.callThrough();
+ spyOn(component, 'hideModal').and.callThrough();
+ spyOn(mockComponent, 'fakeDelete').and.callThrough();
+ });
+
+ it('should delete and close modal', fakeAsync(() => {
+ // During deletionCall
+ component.callSubmitAction();
+ expect(mockComponent.finished).toBe(undefined);
+ expect(component.hideModal).not.toHaveBeenCalled();
+ // After deletionCall
+ tick(2000);
+ expect(mockComponent.finished).toEqual([6, 7, 8, 9]);
+ expect(component.stopLoadingSpinner).not.toHaveBeenCalled();
+ expect(component.hideModal).toHaveBeenCalled();
+ }));
+ });
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.ts
new file mode 100644
index 000000000..4c634f8ca
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.ts
@@ -0,0 +1,63 @@
+import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
+import { FormControl, Validators } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { Observable } from 'rxjs';
+
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { SubmitButtonComponent } from '../submit-button/submit-button.component';
+
+@Component({
+ selector: 'cd-deletion-modal',
+ templateUrl: './critical-confirmation-modal.component.html',
+ styleUrls: ['./critical-confirmation-modal.component.scss']
+})
+export class CriticalConfirmationModalComponent implements OnInit {
+ @ViewChild(SubmitButtonComponent, { static: true })
+ submitButton: SubmitButtonComponent;
+ bodyTemplate: TemplateRef<any>;
+ bodyContext: object;
+ submitActionObservable: () => Observable<any>;
+ submitAction: Function;
+ deletionForm: CdFormGroup;
+ itemDescription: 'entry';
+ itemNames: string[];
+ actionDescription = 'delete';
+
+ childFormGroup: CdFormGroup;
+ childFormGroupTemplate: TemplateRef<any>;
+
+ constructor(public activeModal: NgbActiveModal) {}
+
+ ngOnInit() {
+ const controls = {
+ confirmation: new FormControl(false, [Validators.requiredTrue])
+ };
+ if (this.childFormGroup) {
+ controls['child'] = this.childFormGroup;
+ }
+ this.deletionForm = new CdFormGroup(controls);
+ if (!(this.submitAction || this.submitActionObservable)) {
+ throw new Error('No submit action defined');
+ }
+ }
+
+ callSubmitAction() {
+ if (this.submitActionObservable) {
+ this.submitActionObservable().subscribe({
+ error: this.stopLoadingSpinner.bind(this),
+ complete: this.hideModal.bind(this)
+ });
+ } else {
+ this.submitAction();
+ }
+ }
+
+ hideModal() {
+ this.activeModal.close();
+ }
+
+ stopLoadingSpinner() {
+ this.deletionForm.setErrors({ cdSubmitButton: true });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/custom-login-banner/custom-login-banner.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/custom-login-banner/custom-login-banner.component.html
new file mode 100644
index 000000000..7bb087c3f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/custom-login-banner/custom-login-banner.component.html
@@ -0,0 +1,2 @@
+<p class="login-text"
+ *ngIf="bannerText$ | async as bannerText">{{ bannerText }}</p>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/custom-login-banner/custom-login-banner.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/custom-login-banner/custom-login-banner.component.scss
new file mode 100644
index 000000000..4721f6531
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/custom-login-banner/custom-login-banner.component.scss
@@ -0,0 +1,5 @@
+.login-text {
+ font-weight: bold;
+ margin: 0;
+ padding: 12px 20% 12px 12px;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/custom-login-banner/custom-login-banner.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/custom-login-banner/custom-login-banner.component.spec.ts
new file mode 100644
index 000000000..6005cbd0b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/custom-login-banner/custom-login-banner.component.spec.ts
@@ -0,0 +1,25 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { CustomLoginBannerComponent } from './custom-login-banner.component';
+
+describe('CustomLoginBannerComponent', () => {
+ let component: CustomLoginBannerComponent;
+ let fixture: ComponentFixture<CustomLoginBannerComponent>;
+
+ configureTestBed({
+ declarations: [CustomLoginBannerComponent],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CustomLoginBannerComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/custom-login-banner/custom-login-banner.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/custom-login-banner/custom-login-banner.component.ts
new file mode 100644
index 000000000..ad0d54688
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/custom-login-banner/custom-login-banner.component.ts
@@ -0,0 +1,20 @@
+import { Component, OnInit } from '@angular/core';
+
+import _ from 'lodash';
+import { Observable } from 'rxjs';
+
+import { CustomLoginBannerService } from '~/app/shared/api/custom-login-banner.service';
+
+@Component({
+ selector: 'cd-custom-login-banner',
+ templateUrl: './custom-login-banner.component.html',
+ styleUrls: ['./custom-login-banner.component.scss']
+})
+export class CustomLoginBannerComponent implements OnInit {
+ bannerText$: Observable<string>;
+ constructor(private customLoginBannerService: CustomLoginBannerService) {}
+
+ ngOnInit(): void {
+ this.bannerText$ = this.customLoginBannerService.getBannerText();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/date-time-picker/date-time-picker.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/date-time-picker/date-time-picker.component.html
new file mode 100644
index 000000000..7f8388f47
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/date-time-picker/date-time-picker.component.html
@@ -0,0 +1,13 @@
+<div class="d-flex justify-content-center">
+ <ngb-datepicker #dp
+ [(ngModel)]="date"
+ [minDate]="minDate"
+ (ngModelChange)="onModelChange()"></ngb-datepicker>
+</div>
+
+<div class="d-flex justify-content-center"
+ *ngIf="hasTime">
+ <ngb-timepicker [seconds]="hasSeconds"
+ [(ngModel)]="time"
+ (ngModelChange)="onModelChange()"></ngb-timepicker>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/date-time-picker/date-time-picker.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/date-time-picker/date-time-picker.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/date-time-picker/date-time-picker.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/date-time-picker/date-time-picker.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/date-time-picker/date-time-picker.component.spec.ts
new file mode 100644
index 000000000..00d09e3b4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/date-time-picker/date-time-picker.component.spec.ts
@@ -0,0 +1,58 @@
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { FormControl, FormsModule } from '@angular/forms';
+
+import { NgbDatepickerModule, NgbTimepickerModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { DateTimePickerComponent } from './date-time-picker.component';
+
+describe('DateTimePickerComponent', () => {
+ let component: DateTimePickerComponent;
+ let fixture: ComponentFixture<DateTimePickerComponent>;
+
+ configureTestBed({
+ declarations: [DateTimePickerComponent],
+ imports: [NgbDatepickerModule, NgbTimepickerModule, FormsModule]
+ });
+
+ beforeEach(() => {
+ spyOn(Date, 'now').and.returnValue(new Date('2022-02-22T00:00:00.00'));
+ fixture = TestBed.createComponent(DateTimePickerComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create with correct datetime', fakeAsync(() => {
+ component.control = new FormControl('2022-02-26 00:00:00');
+ fixture.detectChanges();
+ tick();
+ expect(component).toBeTruthy();
+ expect(component.control.value).toBe('2022-02-26 00:00:00');
+ }));
+
+ it('should update control value if datetime is not valid', fakeAsync(() => {
+ component.control = new FormControl('not valid');
+ fixture.detectChanges();
+ tick();
+ expect(component.control.value).toBe('2022-02-22 00:00:00');
+ }));
+
+ it('should init with only date enabled', () => {
+ component.control = new FormControl();
+ component.hasTime = false;
+ fixture.detectChanges();
+ expect(component.format).toBe('YYYY-MM-DD');
+ });
+
+ it('should init with time enabled', () => {
+ component.control = new FormControl();
+ component.hasSeconds = false;
+ fixture.detectChanges();
+ expect(component.format).toBe('YYYY-MM-DD HH:mm');
+ });
+
+ it('should init with seconds enabled', () => {
+ component.control = new FormControl();
+ fixture.detectChanges();
+ expect(component.format).toBe('YYYY-MM-DD HH:mm:ss');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/date-time-picker/date-time-picker.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/date-time-picker/date-time-picker.component.ts
new file mode 100644
index 000000000..390edbfd8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/date-time-picker/date-time-picker.component.ts
@@ -0,0 +1,67 @@
+import { Component, Input, OnInit } from '@angular/core';
+import { FormControl } from '@angular/forms';
+
+import { NgbCalendar, NgbDateStruct, NgbTimeStruct } from '@ng-bootstrap/ng-bootstrap';
+import moment from 'moment';
+import { Subscription } from 'rxjs';
+
+@Component({
+ selector: 'cd-date-time-picker',
+ templateUrl: './date-time-picker.component.html',
+ styleUrls: ['./date-time-picker.component.scss']
+})
+export class DateTimePickerComponent implements OnInit {
+ @Input()
+ control: FormControl;
+
+ @Input()
+ hasSeconds = true;
+
+ @Input()
+ hasTime = true;
+
+ format: string;
+ minDate: NgbDateStruct;
+ date: NgbDateStruct;
+ time: NgbTimeStruct;
+
+ sub: Subscription;
+
+ constructor(private calendar: NgbCalendar) {}
+
+ ngOnInit() {
+ this.minDate = this.calendar.getToday();
+ if (!this.hasTime) {
+ this.format = 'YYYY-MM-DD';
+ } else if (this.hasSeconds) {
+ this.format = 'YYYY-MM-DD HH:mm:ss';
+ } else {
+ this.format = 'YYYY-MM-DD HH:mm';
+ }
+
+ let mom = moment(this.control?.value, this.format);
+
+ if (!mom.isValid() || mom.isBefore(moment())) {
+ mom = moment();
+ }
+
+ this.date = { year: mom.year(), month: mom.month() + 1, day: mom.date() };
+ this.time = { hour: mom.hour(), minute: mom.minute(), second: mom.second() };
+
+ this.onModelChange();
+ }
+
+ onModelChange() {
+ if (this.date) {
+ const datetime = Object.assign({}, this.date, this.time);
+ datetime.month--;
+ setTimeout(() => {
+ this.control.setValue(moment(datetime).format(this.format));
+ });
+ } else {
+ setTimeout(() => {
+ this.control.setValue('');
+ });
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.html
new file mode 100644
index 000000000..b90fedc0c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.html
@@ -0,0 +1,2 @@
+<a href="{{ docUrl }}"
+ target="_blank">{{ docText }}</a>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.spec.ts
new file mode 100644
index 000000000..3fb31024e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.spec.ts
@@ -0,0 +1,27 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CephReleaseNamePipe } from '~/app/shared/pipes/ceph-release-name.pipe';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { DocComponent } from './doc.component';
+
+describe('DocComponent', () => {
+ let component: DocComponent;
+ let fixture: ComponentFixture<DocComponent>;
+
+ configureTestBed({
+ declarations: [DocComponent],
+ imports: [HttpClientTestingModule],
+ providers: [CephReleaseNamePipe]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DocComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.ts
new file mode 100644
index 000000000..6dffc360b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.ts
@@ -0,0 +1,28 @@
+import { Component, Input, OnInit } from '@angular/core';
+
+import { DocService } from '~/app/shared/services/doc.service';
+
+@Component({
+ selector: 'cd-doc',
+ templateUrl: './doc.component.html',
+ styleUrls: ['./doc.component.scss']
+})
+export class DocComponent implements OnInit {
+ @Input() section: string;
+ @Input() docText = $localize`documentation`;
+ @Input() noSubscribe: boolean;
+
+ docUrl: string;
+
+ constructor(private docService: DocService) {}
+
+ ngOnInit() {
+ if (this.noSubscribe) {
+ this.docUrl = this.docService.urlGenerator(this.section);
+ } else {
+ this.docService.subscribeOnce(this.section, (url: string) => {
+ this.docUrl = url;
+ });
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.html
new file mode 100644
index 000000000..a7e476501
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.html
@@ -0,0 +1,23 @@
+<div ngbDropdown
+ placement="bottom-right">
+ <button type="button"
+ [title]="title"
+ class="btn btn-light dropdown-toggle-split"
+ ngbDropdownToggle>
+ <i [ngClass]="[icons.download]"></i>
+ </button>
+ <div ngbDropdownMenu>
+ <button ngbDropdownItem
+ (click)="download('json')"
+ *ngIf="objectItem">
+ <i [ngClass]="[icons.json]"></i>
+ <span>JSON</span>
+ </button>
+ <button ngbDropdownItem
+ (click)="download()"
+ *ngIf="textItem">
+ <i [ngClass]="[icons.text]"></i>
+ <span>Text</span>
+ </button>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.spec.ts
new file mode 100644
index 000000000..7dbfc2b1c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.spec.ts
@@ -0,0 +1,39 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { TextToDownloadService } from '~/app/shared/services/text-to-download.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { DownloadButtonComponent } from './download-button.component';
+
+describe('DownloadButtonComponent', () => {
+ let component: DownloadButtonComponent;
+ let fixture: ComponentFixture<DownloadButtonComponent>;
+
+ configureTestBed({
+ declarations: [DownloadButtonComponent],
+ providers: [TextToDownloadService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DownloadButtonComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call download function', () => {
+ component.objectItem = {
+ testA: 'testA',
+ testB: 'testB'
+ };
+ const downloadSpy = spyOn(TestBed.inject(TextToDownloadService), 'download');
+ component.fileName = `${'reportText.json'}_${new Date().toLocaleDateString()}`;
+ component.download('json');
+ expect(downloadSpy).toHaveBeenCalledWith(
+ JSON.stringify(component.objectItem, null, 2),
+ `${component.fileName}.json`
+ );
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.ts
new file mode 100644
index 000000000..48fde7921
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.ts
@@ -0,0 +1,31 @@
+import { Component, Input } from '@angular/core';
+
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { TextToDownloadService } from '~/app/shared/services/text-to-download.service';
+
+@Component({
+ selector: 'cd-download-button',
+ templateUrl: './download-button.component.html',
+ styleUrls: ['./download-button.component.scss']
+})
+export class DownloadButtonComponent {
+ @Input() objectItem: object;
+ @Input() textItem: string;
+ @Input() fileName: any;
+ @Input() title = $localize`Download`;
+
+ icons = Icons;
+ constructor(private textToDownloadService: TextToDownloadService) {}
+
+ download(format?: string) {
+ this.fileName = `${this.fileName}_${new Date().toLocaleDateString()}`;
+ if (format === 'json') {
+ this.textToDownloadService.download(
+ JSON.stringify(this.objectItem, null, 2),
+ `${this.fileName}.json`
+ );
+ } else {
+ this.textToDownloadService.download(this.textItem, `${this.fileName}.txt`);
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-button-panel/form-button-panel.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-button-panel/form-button-panel.component.html
new file mode 100644
index 000000000..476ed9609
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-button-panel/form-button-panel.component.html
@@ -0,0 +1,11 @@
+<div [class]="wrappingClass">
+ <cd-back-button class="m-2"
+ (backAction)="backAction()"
+ [name]="cancelText"></cd-back-button>
+ <cd-submit-button *ngIf="showSubmit"
+ (submitAction)="submitAction()"
+ [disabled]="disabled"
+ [form]="form"
+ [ariaLabel]="submitText"
+ data-cy="submitBtn">{{ submitText }}</cd-submit-button>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-button-panel/form-button-panel.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-button-panel/form-button-panel.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-button-panel/form-button-panel.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-button-panel/form-button-panel.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-button-panel/form-button-panel.component.spec.ts
new file mode 100644
index 000000000..b8350485b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-button-panel/form-button-panel.component.spec.ts
@@ -0,0 +1,25 @@
+import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { FormButtonPanelComponent } from './form-button-panel.component';
+
+describe('FormButtonPanelComponent', () => {
+ let component: FormButtonPanelComponent;
+ let fixture: ComponentFixture<FormButtonPanelComponent>;
+
+ configureTestBed({
+ declarations: [FormButtonPanelComponent],
+ schemas: [NO_ERRORS_SCHEMA]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(FormButtonPanelComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-button-panel/form-button-panel.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-button-panel/form-button-panel.component.ts
new file mode 100644
index 000000000..0d48f63c0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-button-panel/form-button-panel.component.ts
@@ -0,0 +1,59 @@
+import { Location } from '@angular/common';
+import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
+import { FormGroup, NgForm } from '@angular/forms';
+
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { SubmitButtonComponent } from '../submit-button/submit-button.component';
+
+@Component({
+ selector: 'cd-form-button-panel',
+ templateUrl: './form-button-panel.component.html',
+ styleUrls: ['./form-button-panel.component.scss']
+})
+export class FormButtonPanelComponent {
+ @ViewChild(SubmitButtonComponent)
+ submitButton: SubmitButtonComponent;
+
+ @Output()
+ submitActionEvent = new EventEmitter();
+ @Output()
+ backActionEvent = new EventEmitter();
+
+ @Input()
+ form: FormGroup | NgForm;
+ @Input()
+ showSubmit = true;
+ @Input()
+ wrappingClass = '';
+ @Input()
+ btnClass = '';
+ @Input()
+ submitText: string = this.actionLabels.CREATE;
+ @Input()
+ cancelText: string = this.actionLabels.CANCEL;
+ @Input()
+ disabled = false;
+
+ constructor(
+ private location: Location,
+ private actionLabels: ActionLabelsI18n,
+ private modalService: ModalService
+ ) {}
+
+ submitAction() {
+ this.submitActionEvent.emit();
+ }
+
+ backAction() {
+ if (this.backActionEvent.observers.length === 0) {
+ if (this.modalService.hasOpenModals()) {
+ this.modalService.dismissAll();
+ } else {
+ this.location.back();
+ }
+ } else {
+ this.backActionEvent.emit();
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.html
new file mode 100755
index 000000000..47fca49c7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.html
@@ -0,0 +1,69 @@
+<cd-modal [modalRef]="activeModal">
+ <ng-container *ngIf="titleText"
+ class="modal-title">
+ {{ titleText }}
+ </ng-container>
+ <ng-container class="modal-content">
+ <form [formGroup]="formGroup"
+ #formDir="ngForm"
+ novalidate>
+ <div class="modal-body">
+ <p *ngIf="message">{{ message }}</p>
+ <ng-container *ngFor="let field of fields">
+ <div class="form-group row cd-{{field.name}}-form-group">
+ <label *ngIf="field.label"
+ class="cd-col-form-label"
+ [ngClass]="{'required': field?.required === true}"
+ [for]="field.name">
+ {{ field.label }}
+ </label>
+ <div [ngClass]="{'cd-col-form-input': field.label, 'col-sm-12': !field.label}">
+ <input *ngIf="['text', 'number'].includes(field.type)"
+ [type]="field.type"
+ class="form-control"
+ [id]="field.name"
+ [name]="field.name"
+ [formControlName]="field.name">
+ <input *ngIf="field.type === 'binary'"
+ type="text"
+ class="form-control"
+ [id]="field.name"
+ [name]="field.name"
+ [formControlName]="field.name"
+ cdDimlessBinary>
+ <select *ngIf="field.type === 'select'"
+ class="form-control"
+ [id]="field.name"
+ [formControlName]="field.name">
+ <option *ngIf="field?.typeConfig?.placeholder"
+ [ngValue]="null">
+ {{ field?.typeConfig?.placeholder }}
+ </option>
+ <option *ngFor="let option of field?.typeConfig?.options"
+ [value]="option.value">
+ {{ option.text }}
+ </option>
+ </select>
+ <cd-select-badges *ngIf="field.type === 'select-badges'"
+ [id]="field.name"
+ [data]="field.value"
+ [customBadges]="field?.typeConfig?.customBadges"
+ [options]="field?.typeConfig?.options"
+ [messages]="field?.typeConfig?.messages">
+ </cd-select-badges>
+ <span *ngIf="formGroup.showError(field.name, formDir)"
+ class="invalid-feedback">
+ {{ getError(field) }}
+ </span>
+ </div>
+ </div>
+ </ng-container>
+ </div>
+ <div class="modal-footer">
+ <cd-form-button-panel (submitActionEvent)="onSubmitForm(formGroup.value)"
+ [form]="formGroup"
+ [submitText]="submitButtonText"></cd-form-button-panel>
+ </div>
+ </form>
+ </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.scss
new file mode 100755
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.spec.ts
new file mode 100755
index 000000000..219c2e79f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.spec.ts
@@ -0,0 +1,149 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule, Validators } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed, FixtureHelper, FormHelper } from '~/testing/unit-test-helper';
+import { FormModalComponent } from './form-modal.component';
+
+describe('InputModalComponent', () => {
+ let component: FormModalComponent;
+ let fixture: ComponentFixture<FormModalComponent>;
+ let fh: FixtureHelper;
+ let formHelper: FormHelper;
+ let submitted: object;
+
+ const initialState = {
+ titleText: 'Some title',
+ message: 'Some description',
+ fields: [
+ {
+ type: 'text',
+ name: 'requiredField',
+ value: 'some-value',
+ required: true
+ },
+ {
+ type: 'number',
+ name: 'optionalField',
+ label: 'Optional',
+ errors: { min: 'Value has to be above zero!' },
+ validators: [Validators.min(0), Validators.max(10)]
+ },
+ {
+ type: 'binary',
+ name: 'dimlessBinary',
+ label: 'Size',
+ value: 2048,
+ validators: [CdValidators.binaryMin(1024), CdValidators.binaryMax(3072)]
+ }
+ ],
+ submitButtonText: 'Submit button name',
+ onSubmit: (values: object) => (submitted = values)
+ };
+
+ configureTestBed({
+ imports: [RouterTestingModule, ReactiveFormsModule, SharedModule],
+ providers: [NgbActiveModal]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(FormModalComponent);
+ component = fixture.componentInstance;
+ Object.assign(component, initialState);
+ fixture.detectChanges();
+ fh = new FixtureHelper(fixture);
+ formHelper = new FormHelper(component.formGroup);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('has the defined title', () => {
+ fh.expectTextToBe('.modal-title', 'Some title');
+ });
+
+ it('has the defined description', () => {
+ fh.expectTextToBe('.modal-body > p', 'Some description');
+ });
+
+ it('should display both inputs', () => {
+ fh.expectElementVisible('#requiredField', true);
+ fh.expectElementVisible('#optionalField', true);
+ });
+
+ it('has one defined label field', () => {
+ fh.expectTextToBe('.cd-col-form-label', 'Optional');
+ });
+
+ it('has a predefined values for requiredField', () => {
+ fh.expectFormFieldToBe('#requiredField', 'some-value');
+ });
+
+ it('gives back all form values on submit', () => {
+ component.onSubmitForm(component.formGroup.value);
+ expect(submitted).toEqual({
+ dimlessBinary: 2048,
+ requiredField: 'some-value',
+ optionalField: null
+ });
+ });
+
+ it('tests required field validation', () => {
+ formHelper.expectErrorChange('requiredField', '', 'required');
+ });
+
+ it('tests required field message', () => {
+ formHelper.setValue('requiredField', '', true);
+ fh.expectTextToBe('.cd-requiredField-form-group .invalid-feedback', 'This field is required.');
+ });
+
+ it('tests custom validator on number field', () => {
+ formHelper.expectErrorChange('optionalField', -1, 'min');
+ formHelper.expectErrorChange('optionalField', 11, 'max');
+ });
+
+ it('tests custom validator error message', () => {
+ formHelper.setValue('optionalField', -1, true);
+ fh.expectTextToBe(
+ '.cd-optionalField-form-group .invalid-feedback',
+ 'Value has to be above zero!'
+ );
+ });
+
+ it('tests default error message', () => {
+ formHelper.setValue('optionalField', 11, true);
+ fh.expectTextToBe('.cd-optionalField-form-group .invalid-feedback', 'An error occurred.');
+ });
+
+ it('tests binary error messages', () => {
+ formHelper.setValue('dimlessBinary', '4 K', true);
+ fh.expectTextToBe(
+ '.cd-dimlessBinary-form-group .invalid-feedback',
+ 'Size has to be at most 3 KiB or less'
+ );
+ formHelper.setValue('dimlessBinary', '0.5 K', true);
+ fh.expectTextToBe(
+ '.cd-dimlessBinary-form-group .invalid-feedback',
+ 'Size has to be at least 1 KiB or more'
+ );
+ });
+
+ it('shows result of dimlessBinary pipe', () => {
+ fh.expectFormFieldToBe('#dimlessBinary', '2 KiB');
+ });
+
+ it('changes dimlessBinary value and the result will still be a number', () => {
+ formHelper.setValue('dimlessBinary', '3 K', true);
+ component.onSubmitForm(component.formGroup.value);
+ expect(submitted).toEqual({
+ dimlessBinary: 3072,
+ requiredField: 'some-value',
+ optionalField: null
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.ts
new file mode 100755
index 000000000..46dd942e9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.ts
@@ -0,0 +1,110 @@
+import { Component, OnInit } from '@angular/core';
+import { FormControl, ValidatorFn, Validators } from '@angular/forms';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdFormModalFieldConfig } from '~/app/shared/models/cd-form-modal-field-config';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { FormatterService } from '~/app/shared/services/formatter.service';
+
+@Component({
+ selector: 'cd-form-modal',
+ templateUrl: './form-modal.component.html',
+ styleUrls: ['./form-modal.component.scss']
+})
+export class FormModalComponent implements OnInit {
+ // Input
+ titleText: string;
+ message: string;
+ fields: CdFormModalFieldConfig[];
+ submitButtonText: string;
+ onSubmit: Function;
+
+ // Internal
+ formGroup: CdFormGroup;
+
+ constructor(
+ public activeModal: NgbActiveModal,
+ private formBuilder: CdFormBuilder,
+ private formatter: FormatterService,
+ private dimlessBinaryPipe: DimlessBinaryPipe
+ ) {}
+
+ ngOnInit() {
+ this.createForm();
+ }
+
+ createForm() {
+ const controlsConfig: Record<string, FormControl> = {};
+ this.fields.forEach((field) => {
+ controlsConfig[field.name] = this.createFormControl(field);
+ });
+ this.formGroup = this.formBuilder.group(controlsConfig);
+ }
+
+ private createFormControl(field: CdFormModalFieldConfig): FormControl {
+ let validators: ValidatorFn[] = [];
+ if (_.isBoolean(field.required) && field.required) {
+ validators.push(Validators.required);
+ }
+ if (field.validators) {
+ validators = validators.concat(field.validators);
+ }
+ return new FormControl(
+ _.defaultTo(
+ field.type === 'binary' ? this.dimlessBinaryPipe.transform(field.value) : field.value,
+ null
+ ),
+ { validators }
+ );
+ }
+
+ getError(field: CdFormModalFieldConfig): string {
+ const formErrors = this.formGroup.get(field.name).errors;
+ const errors = Object.keys(formErrors).map((key) => {
+ return this.getErrorMessage(key, formErrors[key], field.errors);
+ });
+ return errors.join('<br>');
+ }
+
+ private getErrorMessage(
+ error: string,
+ errorContext: any,
+ fieldErrors: { [error: string]: string }
+ ): string {
+ if (fieldErrors) {
+ const customError = fieldErrors[error];
+ if (customError) {
+ return customError;
+ }
+ }
+ if (['binaryMin', 'binaryMax'].includes(error)) {
+ // binaryMin and binaryMax return a function that take I18n to
+ // provide a translated error message.
+ return errorContext();
+ }
+ if (error === 'required') {
+ return $localize`This field is required.`;
+ }
+ return $localize`An error occurred.`;
+ }
+
+ onSubmitForm(values: any) {
+ const binaries = this.fields
+ .filter((field) => field.type === 'binary')
+ .map((field) => field.name);
+ binaries.forEach((key) => {
+ const value = values[key];
+ if (value) {
+ values[key] = this.formatter.toBytes(value);
+ }
+ });
+ this.activeModal.close();
+ if (_.isFunction(this.onSubmit)) {
+ this.onSubmit(values);
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.html
new file mode 100644
index 000000000..8ad98b27f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.html
@@ -0,0 +1,78 @@
+<!-- Embed dashboard -->
+<cd-loading-panel *ngIf="loading && grafanaExist"
+ i18n>Loading panel data...</cd-loading-panel>
+
+<cd-alert-panel type="info"
+ *ngIf="!grafanaExist"
+ i18n>Please consult the <cd-doc section="grafana"></cd-doc> on
+ how to configure and enable the monitoring functionality.</cd-alert-panel>
+
+<cd-alert-panel type="info"
+ *ngIf="!dashboardExist"
+ i18n>Grafana Dashboard doesn't exist. Please refer to
+ <cd-doc section="grafana"></cd-doc> on how to add dashboards to Grafana.</cd-alert-panel>
+
+<ng-container *ngIf="grafanaExist && dashboardExist">
+ <div class="row">
+ <div class="col">
+ <div class="form-inline timepicker">
+ <label for="timepicker"
+ class="ml-1 my-1"
+ i18n>Grafana Time Picker</label>
+
+ <select id="timepicker"
+ name="timepicker"
+ class="custom-select my-1 mx-3"
+ [(ngModel)]="time"
+ (ngModelChange)="onTimepickerChange($event)">
+ <option *ngFor="let key of grafanaTimes"
+ [ngValue]="key.value">{{ key.name }}
+ </option>
+ </select>
+
+ <button class="btn btn-light my-1"
+ i18n-title
+ title="Reset Settings"
+ (click)="reset()">
+ <i [ngClass]="[icons.undo]"></i>
+ </button>
+ <button class="btn btn-light my-1 ml-3"
+ i18n-title
+ title="Show hidden information"
+ (click)="showMessage = !showMessage">
+ <i [ngClass]="[icons.infoCircle, icons.large]"></i>
+ </button>
+ </div>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col my-3"
+ *ngIf="showMessage">
+ <cd-alert-panel type="info"
+ class="mb-3"
+ *ngIf="showMessage"
+ dismissible="true"
+ (dismissed)="showMessage = false"
+ i18n>If no embedded Grafana Dashboard appeared below, please follow <a [href]="grafanaSrc"
+ target="_blank"
+ noopener
+ noreferrer>this link </a> to check if Grafana is reachable and there are no HTTPS certificate issues. You may need to reload this page after accepting any Browser certificate exceptions</cd-alert-panel>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col">
+ <div class="grafana-container">
+ <iframe #iframe
+ id="iframe"
+ [src]="grafanaSrc"
+ class="grafana"
+ [ngClass]="panelStyle"
+ frameborder="0"
+ scrolling="no">
+ </iframe>
+ </div>
+ </div>
+ </div>
+</ng-container>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.scss
new file mode 100644
index 000000000..7b43a460f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.scss
@@ -0,0 +1,33 @@
+.grafana {
+ height: 600px;
+ width: 100%;
+ z-index: 0;
+}
+
+.grafana_one {
+ height: 400px;
+}
+
+.grafana_two {
+ height: 750px;
+}
+
+.grafana_three {
+ height: 900px;
+}
+
+.grafana_four {
+ height: 1160px;
+}
+
+.timepicker {
+ label {
+ font-weight: 700;
+ }
+}
+
+.dropdown-menu {
+ left: auto;
+ right: 20px;
+ top: 20px;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.spec.ts
new file mode 100644
index 000000000..63733fd75
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.spec.ts
@@ -0,0 +1,81 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbAlertModule } from '@ng-bootstrap/ng-bootstrap';
+import { of } from 'rxjs';
+
+import { SettingsService } from '~/app/shared/api/settings.service';
+import { CephReleaseNamePipe } from '~/app/shared/pipes/ceph-release-name.pipe';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { AlertPanelComponent } from '../alert-panel/alert-panel.component';
+import { DocComponent } from '../doc/doc.component';
+import { LoadingPanelComponent } from '../loading-panel/loading-panel.component';
+import { GrafanaComponent } from './grafana.component';
+
+describe('GrafanaComponent', () => {
+ let component: GrafanaComponent;
+ let fixture: ComponentFixture<GrafanaComponent>;
+ const expected_url =
+ 'http:localhost:3000/d/foo/somePath&refresh=2s&var-datasource=Dashboard1&kiosk&from=now-1h&to=now';
+
+ configureTestBed({
+ declarations: [GrafanaComponent, AlertPanelComponent, LoadingPanelComponent, DocComponent],
+ imports: [NgbAlertModule, HttpClientTestingModule, RouterTestingModule, FormsModule],
+ providers: [CephReleaseNamePipe, SettingsService, SummaryService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(GrafanaComponent);
+ component = fixture.componentInstance;
+ component.grafanaPath = 'somePath';
+ component.uid = 'foo';
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should have found out that grafana does not exist', () => {
+ fixture.detectChanges();
+ expect(component.grafanaExist).toBe(false);
+ expect(component.baseUrl).toBe(undefined);
+ expect(component.loading).toBe(true);
+ expect(component.url).toBe(undefined);
+ expect(component.grafanaSrc).toEqual(undefined);
+ });
+
+ describe('with grafana initialized', () => {
+ beforeEach(() => {
+ TestBed.inject(SettingsService)['settings'] = { 'api/grafana/url': 'http:localhost:3000' };
+ fixture.detectChanges();
+ });
+
+ it('should have found out that grafana exists and dashboard exists', () => {
+ expect(component.time).toBe('from=now-1h&to=now');
+ expect(component.grafanaExist).toBe(true);
+ expect(component.baseUrl).toBe('http:localhost:3000/d/');
+ expect(component.loading).toBe(false);
+ expect(component.url).toBe(expected_url);
+ expect(component.grafanaSrc).toEqual({
+ changingThisBreaksApplicationSecurity: expected_url
+ });
+ });
+
+ it('should reset the values', () => {
+ component.reset();
+ expect(component.time).toBe('from=now-1h&to=now');
+ expect(component.url).toBe(expected_url);
+ expect(component.grafanaSrc).toEqual({
+ changingThisBreaksApplicationSecurity: expected_url
+ });
+ });
+
+ it('should have Dashboard', () => {
+ TestBed.inject(SettingsService).validateGrafanaDashboardUrl = () => of({ uid: 200 });
+ expect(component.dashboardExist).toBe(true);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.ts
new file mode 100644
index 000000000..2815160ab
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.ts
@@ -0,0 +1,201 @@
+import { Component, Input, OnChanges, OnInit } from '@angular/core';
+import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
+
+import { SettingsService } from '~/app/shared/api/settings.service';
+import { Icons } from '~/app/shared/enum/icons.enum';
+
+@Component({
+ selector: 'cd-grafana',
+ templateUrl: './grafana.component.html',
+ styleUrls: ['./grafana.component.scss']
+})
+export class GrafanaComponent implements OnInit, OnChanges {
+ grafanaSrc: SafeUrl;
+ url: string;
+ protocol: string;
+ host: string;
+ port: number;
+ baseUrl: any;
+ panelStyle: any;
+ grafanaExist = false;
+ mode = '&kiosk';
+ datasource = 'Dashboard1';
+ loading = true;
+ styles: Record<string, string> = {};
+ dashboardExist = true;
+ showMessage = false;
+ time: string;
+ grafanaTimes: any;
+ icons = Icons;
+ readonly DEFAULT_TIME: string = 'from=now-1h&to=now';
+
+ @Input()
+ grafanaPath: string;
+ @Input()
+ grafanaStyle: string;
+ @Input()
+ uid: string;
+
+ constructor(private sanitizer: DomSanitizer, private settingsService: SettingsService) {
+ this.grafanaTimes = [
+ {
+ name: $localize`Last 5 minutes`,
+ value: 'from=now-5m&to=now'
+ },
+ {
+ name: $localize`Last 15 minutes`,
+ value: 'from=now-15m&to=now'
+ },
+ {
+ name: $localize`Last 30 minutes`,
+ value: 'from=now-30m&to=now'
+ },
+ {
+ name: $localize`Last 1 hour (Default)`,
+ value: 'from=now-1h&to=now'
+ },
+ {
+ name: $localize`Last 3 hours`,
+ value: 'from=now-3h&to=now'
+ },
+ {
+ name: $localize`Last 6 hours`,
+ value: 'from=now-6h&to=now'
+ },
+ {
+ name: $localize`Last 12 hours`,
+ value: 'from=now-12h&to=now'
+ },
+ {
+ name: $localize`Last 24 hours`,
+ value: 'from=now-24h&to=now'
+ },
+ {
+ name: $localize`Yesterday`,
+ value: 'from=now-1d%2Fd&to=now-1d%2Fd'
+ },
+ {
+ name: $localize`Today so far`,
+ value: 'from=now%2Fd&to=now'
+ },
+ {
+ name: $localize`Day before yesterday`,
+ value: 'from=now-2d%2Fd&to=now-2d%2Fd'
+ },
+ {
+ name: $localize`Last 2 days`,
+ value: 'from=now-2d&to=now'
+ },
+ {
+ name: $localize`This day last week`,
+ value: 'from=now-7d%2Fd&to=now-7d%2Fd'
+ },
+ {
+ name: $localize`Previous week`,
+ value: 'from=now-1w%2Fw&to=now-1w%2Fw'
+ },
+ {
+ name: $localize`This week so far`,
+ value: 'from=now%2Fw&to=now'
+ },
+ {
+ name: $localize`Last 7 days`,
+ value: 'from=now-7d&to=now'
+ },
+ {
+ name: $localize`Previous month`,
+ value: 'from=now-1M%2FM&to=now-1M%2FM'
+ },
+ {
+ name: $localize`This month so far`,
+ value: 'from=now%2FM&to=now'
+ },
+ {
+ name: $localize`Last 30 days`,
+ value: 'from=now-30d&to=now'
+ },
+ {
+ name: $localize`Last 90 days`,
+ value: 'from=now-90d&to=now'
+ },
+ {
+ name: $localize`Last 6 months`,
+ value: 'from=now-6M&to=now'
+ },
+ {
+ name: $localize`Last 1 year`,
+ value: 'from=now-1y&to=now'
+ },
+ {
+ name: $localize`Previous year`,
+ value: 'from=now-1y%2Fy&to=now-1y%2Fy'
+ },
+ {
+ name: $localize`This year so far`,
+ value: 'from=now%2Fy&to=now'
+ },
+ {
+ name: $localize`Last 2 years`,
+ value: 'from=now-2y&to=now'
+ },
+ {
+ name: $localize`Last 5 years`,
+ value: 'from=now-5y&to=now'
+ }
+ ];
+ }
+
+ ngOnInit() {
+ this.time = this.DEFAULT_TIME;
+ this.styles = {
+ one: 'grafana_one',
+ two: 'grafana_two',
+ three: 'grafana_three',
+ four: 'grafana_four'
+ };
+
+ this.settingsService.ifSettingConfigured('api/grafana/url', (url) => {
+ this.grafanaExist = true;
+ this.loading = false;
+ this.baseUrl = url + '/d/';
+ this.getFrame();
+ });
+ this.panelStyle = this.styles[this.grafanaStyle];
+ }
+
+ getFrame() {
+ this.settingsService
+ .validateGrafanaDashboardUrl(this.uid)
+ .subscribe((data: any) => (this.dashboardExist = data === 200));
+ this.url =
+ this.baseUrl +
+ this.uid +
+ '/' +
+ this.grafanaPath +
+ '&refresh=2s' +
+ `&var-datasource=${this.datasource}` +
+ this.mode +
+ '&' +
+ this.time;
+ this.grafanaSrc = this.sanitizer.bypassSecurityTrustResourceUrl(this.url);
+ }
+
+ onTimepickerChange() {
+ if (this.grafanaExist) {
+ this.getFrame();
+ }
+ }
+
+ reset() {
+ this.time = this.DEFAULT_TIME;
+ if (this.grafanaExist) {
+ this.getFrame();
+ }
+ }
+
+ ngOnChanges() {
+ if (this.grafanaExist) {
+ this.getFrame();
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.html
new file mode 100644
index 000000000..f7bc12b5b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.html
@@ -0,0 +1,11 @@
+<ng-template #popoverTpl>
+ <div [class]="class"
+ [innerHtml]="html">
+ </div>
+ <ng-content></ng-content>
+</ng-template>
+<i [ngClass]="[icons.questionCircle]"
+ aria-hidden="true"
+ [ngbPopover]="popoverTpl"
+ (click)="$event.preventDefault();">
+</i>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.scss
new file mode 100644
index 000000000..861b607cb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.scss
@@ -0,0 +1,7 @@
+@use './src/styles/vendor/variables' as vv;
+
+i {
+ color: vv.$primary;
+ cursor: pointer;
+ padding-left: 4px;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.spec.ts
new file mode 100644
index 000000000..a7ef4b35e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.spec.ts
@@ -0,0 +1,26 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { HelperComponent } from './helper.component';
+
+describe('HelperComponent', () => {
+ let component: HelperComponent;
+ let fixture: ComponentFixture<HelperComponent>;
+
+ configureTestBed({
+ imports: [NgbPopoverModule],
+ declarations: [HelperComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(HelperComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.ts
new file mode 100644
index 000000000..0028945ba
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.ts
@@ -0,0 +1,18 @@
+import { Component, Input } from '@angular/core';
+
+import { Icons } from '~/app/shared/enum/icons.enum';
+
+@Component({
+ selector: 'cd-helper',
+ templateUrl: './helper.component.html',
+ styleUrls: ['./helper.component.scss']
+})
+export class HelperComponent {
+ @Input()
+ class: string;
+
+ @Input()
+ html: any;
+
+ icons = Icons;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.html
new file mode 100644
index 000000000..2ecbbd7cc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.html
@@ -0,0 +1,17 @@
+<div ngbDropdown
+ display="dynamic"
+ placement="bottom-right">
+ <a ngbDropdownToggle
+ i18n-title
+ title="Select a Language">
+ {{ allLanguages[selectedLanguage] }}
+ </a>
+ <div ngbDropdownMenu>
+ <ng-container *ngFor="let lang of supportedLanguages | keyvalue">
+ <button ngbDropdownItem
+ (click)="changeLanguage(lang.key)">
+ {{ lang.value }}
+ </button>
+ </ng-container>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.spec.ts
new file mode 100644
index 000000000..5c8334e5a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.spec.ts
@@ -0,0 +1,85 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule } from '@angular/forms';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { LanguageSelectorComponent } from './language-selector.component';
+
+describe('LanguageSelectorComponent', () => {
+ let component: LanguageSelectorComponent;
+ let fixture: ComponentFixture<LanguageSelectorComponent>;
+
+ configureTestBed({
+ declarations: [LanguageSelectorComponent],
+ imports: [FormsModule, HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(LanguageSelectorComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ spyOn(component, 'reloadWindow').and.callFake(() => component.ngOnInit());
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should read current language', () => {
+ expect(component.selectedLanguage).toBe('en-US');
+ });
+
+ const expectLanguageChange = (lang: string) => {
+ component.changeLanguage(lang);
+ const cookie = document.cookie.split(';').filter((item) => item.includes(`cd-lang=${lang}`));
+ expect(cookie.length).toBe(1);
+ };
+
+ it('should change to cs', () => {
+ expectLanguageChange('cs');
+ });
+
+ it('should change to de', () => {
+ expectLanguageChange('de');
+ });
+
+ it('should change to es', () => {
+ expectLanguageChange('es');
+ });
+
+ it('should change to fr', () => {
+ expectLanguageChange('fr');
+ });
+
+ it('should change to id', () => {
+ expectLanguageChange('id');
+ });
+
+ it('should change to it', () => {
+ expectLanguageChange('it');
+ });
+
+ it('should change to ja', () => {
+ expectLanguageChange('ja');
+ });
+
+ it('should change to ko', () => {
+ expectLanguageChange('ko');
+ });
+
+ it('should change to pl', () => {
+ expectLanguageChange('pl');
+ });
+
+ it('should change to pt', () => {
+ expectLanguageChange('pt');
+ });
+
+ it('should change to zh-Hans', () => {
+ expectLanguageChange('zh-Hans');
+ });
+
+ it('should change to zh-Hant', () => {
+ expectLanguageChange('zh-Hant');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.ts
new file mode 100644
index 000000000..d747add20
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.ts
@@ -0,0 +1,40 @@
+import { Component, OnInit } from '@angular/core';
+
+import _ from 'lodash';
+
+import { LanguageService } from '~/app/shared/services/language.service';
+import { SupportedLanguages } from './supported-languages.enum';
+
+@Component({
+ selector: 'cd-language-selector',
+ templateUrl: './language-selector.component.html',
+ styleUrls: ['./language-selector.component.scss']
+})
+export class LanguageSelectorComponent implements OnInit {
+ allLanguages = SupportedLanguages;
+ supportedLanguages: Record<string, any> = {};
+ selectedLanguage: string;
+
+ constructor(private languageService: LanguageService) {}
+
+ ngOnInit() {
+ this.selectedLanguage = this.languageService.getLocale();
+
+ this.languageService.getLanguages().subscribe((langs) => {
+ this.supportedLanguages = _.pick(SupportedLanguages, langs) as Object;
+ });
+ }
+
+ /**
+ * Jest is being more restricted regarding spying on the reload method.
+ * This will allow us to spyOn this method instead.
+ */
+ reloadWindow() {
+ window.location.reload();
+ }
+
+ changeLanguage(lang: string) {
+ this.languageService.setLocale(lang);
+ this.reloadWindow();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/supported-languages.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/supported-languages.enum.ts
new file mode 100644
index 000000000..8b573cf64
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/supported-languages.enum.ts
@@ -0,0 +1,17 @@
+// When adding a new supported language make sure to add a test for it in:
+// language-selector.component.spec.ts
+export enum SupportedLanguages {
+ 'cs' = 'Čeština',
+ 'de' = 'Deutsch',
+ 'en-US' = 'English',
+ 'es' = 'Español',
+ 'fr' = 'Français',
+ 'id' = 'Bahasa Indonesia',
+ 'it' = 'Italiano',
+ 'ja' = '日本語',
+ 'ko' = '한국어',
+ 'pl' = 'Polski',
+ 'pt' = 'Português (brasileiro)',
+ 'zh-Hans' = '中文 (简体)',
+ 'zh-Hant' = '中文 (繁體)'
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.html
new file mode 100644
index 000000000..35726cfbd
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.html
@@ -0,0 +1,9 @@
+<ngb-alert type="info"
+ [dismissible]="false">
+ <strong>
+ <i [ngClass]="[icons.spinner, icons.spin]"
+ aria-hidden="true"
+ class="mr-2"></i>
+ </strong>
+ <ng-content></ng-content>
+</ngb-alert>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.spec.ts
new file mode 100644
index 000000000..ffc0aa57b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.spec.ts
@@ -0,0 +1,26 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NgbAlertModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { LoadingPanelComponent } from './loading-panel.component';
+
+describe('LoadingPanelComponent', () => {
+ let component: LoadingPanelComponent;
+ let fixture: ComponentFixture<LoadingPanelComponent>;
+
+ configureTestBed({
+ declarations: [LoadingPanelComponent],
+ imports: [NgbAlertModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(LoadingPanelComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.ts
new file mode 100644
index 000000000..61fd01904
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.ts
@@ -0,0 +1,12 @@
+import { Component } from '@angular/core';
+
+import { Icons } from '~/app/shared/enum/icons.enum';
+
+@Component({
+ selector: 'cd-loading-panel',
+ templateUrl: './loading-panel.component.html',
+ styleUrls: ['./loading-panel.component.scss']
+})
+export class LoadingPanelComponent {
+ icons = Icons;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.html
new file mode 100644
index 000000000..657e0d605
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.html
@@ -0,0 +1,19 @@
+<div [ngClass]="pageURL ? 'modal' : ''">
+ <div [ngClass]="pageURL ? 'modal-dialog' : ''">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h4 class="modal-title float-left">
+ <ng-content select=".modal-title"></ng-content>
+ </h4>
+ <button type="button"
+ class="close float-right"
+ aria-label="Close"
+ (click)="close()">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ </div>
+
+ <ng-content select=".modal-content"></ng-content>
+ </div>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.scss
new file mode 100644
index 000000000..ceeb61427
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.scss
@@ -0,0 +1,23 @@
+@use './src/styles/defaults/mixins';
+
+.modal-header {
+ @include mixins.hf;
+ border-radius: 5px 5px 0 0;
+}
+
+::ng-deep cd-modal {
+ .modal-footer {
+ @include mixins.hf;
+ border-radius: 0 0 5px 5px;
+ }
+
+ .modal-body {
+ max-height: 70vh;
+ overflow-x: hidden;
+ overflow-y: auto;
+ }
+}
+
+button.close {
+ outline: none;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.spec.ts
new file mode 100644
index 000000000..cf08bef10
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.spec.ts
@@ -0,0 +1,54 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { Router } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { ModalComponent } from './modal.component';
+
+describe('ModalComponent', () => {
+ let component: ModalComponent;
+ let fixture: ComponentFixture<ModalComponent>;
+ let routerNavigateSpy: jasmine.Spy;
+
+ configureTestBed({
+ declarations: [ModalComponent],
+ imports: [RouterTestingModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ModalComponent);
+ component = fixture.componentInstance;
+ routerNavigateSpy = spyOn(TestBed.inject(Router), 'navigate');
+ routerNavigateSpy.and.returnValue(true);
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call the hide callback function', () => {
+ spyOn(component.hide, 'emit');
+ const nativeElement = fixture.nativeElement;
+ const button = nativeElement.querySelector('button');
+ button.dispatchEvent(new Event('click'));
+ fixture.detectChanges();
+ expect(component.hide.emit).toHaveBeenCalled();
+ });
+
+ it('should hide the modal', () => {
+ component.modalRef = new NgbActiveModal();
+ spyOn(component.modalRef, 'close');
+ component.close();
+ expect(component.modalRef.close).toHaveBeenCalled();
+ });
+
+ it('should hide the routed modal', () => {
+ component.pageURL = 'hosts';
+ component.close();
+ expect(routerNavigateSpy).toHaveBeenCalledTimes(1);
+ expect(routerNavigateSpy).toHaveBeenCalledWith(['hosts', { outlets: { modal: null } }]);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.ts
new file mode 100644
index 000000000..25e06e62a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.ts
@@ -0,0 +1,31 @@
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { Router } from '@angular/router';
+
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+@Component({
+ selector: 'cd-modal',
+ templateUrl: './modal.component.html',
+ styleUrls: ['./modal.component.scss']
+})
+export class ModalComponent {
+ @Input()
+ modalRef: NgbActiveModal;
+ @Input()
+ pageURL: string;
+
+ /**
+ * Should be a function that is triggered when the modal is hidden.
+ */
+ @Output()
+ hide = new EventEmitter();
+
+ constructor(private router: Router) {}
+
+ close() {
+ this.pageURL
+ ? this.router.navigate([this.pageURL, { outlets: { modal: null } }])
+ : this.modalRef?.close();
+ this.hide.emit();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/motd/motd.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/motd/motd.component.html
new file mode 100644
index 000000000..2fbe5d7f8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/motd/motd.component.html
@@ -0,0 +1,8 @@
+<cd-alert-panel *ngIf="motd"
+ size="slim"
+ [showTitle]="false"
+ [type]="motd.severity"
+ [dismissible]="motd.severity !== 'danger'"
+ (dismissed)="onDismissed()">
+ <span [innerHTML]="motd.message | sanitizeHtml"></span>
+</cd-alert-panel>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/motd/motd.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/motd/motd.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/motd/motd.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/motd/motd.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/motd/motd.component.spec.ts
new file mode 100644
index 000000000..826a8a5d0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/motd/motd.component.spec.ts
@@ -0,0 +1,26 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DashboardModule } from '~/app/ceph/dashboard/dashboard.module';
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { MotdComponent } from './motd.component';
+
+describe('MotdComponent', () => {
+ let component: MotdComponent;
+ let fixture: ComponentFixture<MotdComponent>;
+
+ configureTestBed({
+ imports: [DashboardModule, HttpClientTestingModule, SharedModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(MotdComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/motd/motd.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/motd/motd.component.ts
new file mode 100644
index 000000000..297ef2764
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/motd/motd.component.ts
@@ -0,0 +1,33 @@
+import { Component, OnDestroy, OnInit } from '@angular/core';
+
+import { Subscription } from 'rxjs';
+
+import { Motd } from '~/app/shared/api/motd.service';
+import { MotdNotificationService } from '~/app/shared/services/motd-notification.service';
+
+@Component({
+ selector: 'cd-motd',
+ templateUrl: './motd.component.html',
+ styleUrls: ['./motd.component.scss']
+})
+export class MotdComponent implements OnInit, OnDestroy {
+ motd: Motd | undefined = undefined;
+
+ private subscription: Subscription;
+
+ constructor(private motdNotificationService: MotdNotificationService) {}
+
+ ngOnInit(): void {
+ this.subscription = this.motdNotificationService.motd$.subscribe((motd: Motd | undefined) => {
+ this.motd = motd;
+ });
+ }
+
+ ngOnDestroy(): void {
+ this.subscription.unsubscribe();
+ }
+
+ onDismissed(): void {
+ this.motdNotificationService.hide();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html
new file mode 100644
index 000000000..bba23747b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html
@@ -0,0 +1,131 @@
+<ng-template #tasksTpl>
+ <!-- Executing -->
+ <div *ngFor="let executingTask of executingTasks; trackBy:trackByFn">
+ <div class="card tc_task border-0">
+ <div class="row no-gutters">
+ <div class="col-md-2 text-center">
+ <span [ngClass]="[icons.stack, icons.large2x]"
+ class="text-info">
+ <i [ngClass]="[icons.stack2x, icons.circle]"></i>
+ <i [ngClass]="[icons.stack1x, icons.spinner, icons.spin, icons.inverse]"></i>
+ </span>
+ </div>
+ <div class="col-md-9">
+ <div class="card-body p-1">
+ <h6 class="card-title bold">{{ executingTask.description }}</h6>
+
+ <div class="mb-1">
+ <ngb-progressbar type="info"
+ [value]="executingTask?.progress"
+ [striped]="true"
+ [animated]="true"></ngb-progressbar>
+ </div>
+
+ <p class="card-text text-muted">
+ <small class="date float-left">
+ {{ executingTask.begin_time | cdDate }}
+ </small>
+
+ <span class="float-right">
+ {{ executingTask.progress || 0 }} %
+ </span>
+ </p>
+
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <hr>
+ </div>
+</ng-template>
+
+<ng-template #notificationsTpl>
+ <ng-container *ngIf="notifications.length > 0">
+ <button type="button"
+ class="btn btn-light btn-block"
+ (click)="removeAll(); $event.stopPropagation()">
+ <i [ngClass]="[icons.trash]"
+ aria-hidden="true"></i>
+ &nbsp;
+ <ng-container i18n>Clear notifications</ng-container>
+ </button>
+
+ <hr>
+
+ <div *ngFor="let notification of notifications; let i = index"
+ [ngClass]="notification.borderClass">
+ <div class="card tc_notification border-0">
+ <div class="row no-gutters">
+ <div class="col-md-2 text-center">
+ <span [ngClass]="[icons.stack, icons.large2x, notification.textClass]">
+ <i [ngClass]="[icons.circle, icons.stack2x]"></i>
+ <i [ngClass]="[icons.stack1x, icons.inverse, notification.iconClass]"></i>
+ </span>
+ </div>
+ <div class="col-md-10">
+ <div class="card-body p-1">
+ <button class="btn btn-link float-right mt-0 pt-0"
+ title="Remove notification"
+ i18n-title
+ (click)="remove(i); $event.stopPropagation()">
+ <i [ngClass]="[icons.trash]"></i>
+ </button>
+
+ <h6 class="card-title bold">{{ notification.title }}</h6>
+ <p class="card-text"
+ [innerHtml]="notification.message"></p>
+ <p class="card-text text-muted">
+ <ng-container *ngIf="notification.duration">
+ <small>
+ <ng-container i18n>Duration:</ng-container> {{ notification.duration | duration }}
+ </small>
+ <br>
+ </ng-container>
+ <small class="date"
+ [title]="notification.timestamp | cdDate">{{ notification.timestamp | relativeDate }}</small>
+ <i class="float-right custom-icon"
+ [ngClass]="[notification.applicationClass]"
+ [title]="notification.application"></i>
+ </p>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <hr>
+ </div>
+ </ng-container>
+</ng-template>
+
+<ng-template #emptyTpl>
+ <div *ngIf="notifications.length === 0 && executingTasks.length === 0">
+ <div class="message text-center"
+ i18n>There are no notifications.</div>
+ </div>
+</ng-template>
+
+<div class="card"
+ (clickOutside)="closeSidebar()"
+ [clickOutsideEnabled]="isSidebarOpened">
+ <div class="card-header">
+ <ng-container i18n>Tasks and Notifications</ng-container>
+
+ <button class="close float-right"
+ tabindex="-1"
+ type="button"
+ (click)="closeSidebar()">
+ <span>
+ <i [ngClass]="icons.close"></i>
+ </span>
+ </button>
+ </div>
+
+ <ngx-simplebar [options]="simplebar">
+ <div class="card-body">
+ <ng-container *ngTemplateOutlet="tasksTpl"></ng-container>
+ <ng-container *ngTemplateOutlet="notificationsTpl"></ng-container>
+ <ng-container *ngTemplateOutlet="emptyTpl"></ng-container>
+ </div>
+ </ngx-simplebar>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.scss
new file mode 100644
index 000000000..baa64fa1f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.scss
@@ -0,0 +1,68 @@
+@use './src/styles/vendor/variables' as vv;
+
+:host {
+ bottom: 10px;
+ max-width: 90vw;
+ position: fixed;
+ right: -350px;
+ top: vv.$navbar-height + 10px;
+
+ transition: all 0.6s;
+
+ width: 350px;
+
+ z-index: 9;
+}
+
+:host.active {
+ right: 20px;
+}
+
+.card {
+ height: 100%;
+}
+
+.card-body {
+ padding-left: 0;
+ padding-right: 5px;
+ padding-top: 3px;
+}
+
+ngx-simplebar {
+ height: calc(100% - 42.2px);
+}
+
+.separator {
+ background-color: vv.$gray-200;
+ color: vv.$gray-600;
+ font-size: 1rem;
+ padding: 5px 12px;
+}
+
+.btn-block {
+ width: 98%;
+}
+
+.btn-link .fa-trash-o {
+ color: vv.$black;
+}
+
+table {
+ width: 100%;
+}
+
+.row {
+ margin-left: 0;
+ margin-right: 0;
+ padding-bottom: 1rem;
+ padding-top: 1rem;
+}
+
+hr {
+ margin-bottom: 2px;
+ margin-top: 2px;
+}
+
+.card-text {
+ margin-right: 15px;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.spec.ts
new file mode 100644
index 000000000..596f3c358
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.spec.ts
@@ -0,0 +1,194 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { NoopAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbProgressbarModule } from '@ng-bootstrap/ng-bootstrap';
+import { ClickOutsideModule } from 'ng-click-outside';
+import { ToastrModule } from 'ngx-toastr';
+import { SimplebarAngularModule } from 'simplebar-angular';
+
+import { PrometheusService } from '~/app/shared/api/prometheus.service';
+import { RbdService } from '~/app/shared/api/rbd.service';
+import { SettingsService } from '~/app/shared/api/settings.service';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { ExecutingTask } from '~/app/shared/models/executing-task';
+import { Permissions } from '~/app/shared/models/permissions';
+import { PipesModule } from '~/app/shared/pipes/pipes.module';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { PrometheusAlertService } from '~/app/shared/services/prometheus-alert.service';
+import { PrometheusNotificationService } from '~/app/shared/services/prometheus-notification.service';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { NotificationsSidebarComponent } from './notifications-sidebar.component';
+
+describe('NotificationsSidebarComponent', () => {
+ let component: NotificationsSidebarComponent;
+ let fixture: ComponentFixture<NotificationsSidebarComponent>;
+
+ configureTestBed({
+ imports: [
+ HttpClientTestingModule,
+ PipesModule,
+ NgbProgressbarModule,
+ RouterTestingModule,
+ ToastrModule.forRoot(),
+ NoopAnimationsModule,
+ SimplebarAngularModule,
+ ClickOutsideModule
+ ],
+ declarations: [NotificationsSidebarComponent],
+ providers: [PrometheusService, SettingsService, SummaryService, NotificationService, RbdService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(NotificationsSidebarComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+
+ describe('prometheus alert handling', () => {
+ let prometheusAlertService: PrometheusAlertService;
+ let prometheusNotificationService: PrometheusNotificationService;
+ let prometheusReadPermission: string;
+ let configOptReadPermission: string;
+
+ const expectPrometheusServicesToBeCalledTimes = (n: number) => {
+ expect(prometheusNotificationService.refresh).toHaveBeenCalledTimes(n);
+ expect(prometheusAlertService.refresh).toHaveBeenCalledTimes(n);
+ };
+
+ beforeEach(() => {
+ prometheusReadPermission = 'read';
+ configOptReadPermission = 'read';
+ spyOn(TestBed.inject(AuthStorageService), 'getPermissions').and.callFake(
+ () =>
+ new Permissions({
+ prometheus: [prometheusReadPermission],
+ 'config-opt': [configOptReadPermission]
+ })
+ );
+
+ spyOn(TestBed.inject(PrometheusService), 'ifAlertmanagerConfigured').and.callFake((fn) =>
+ fn()
+ );
+
+ prometheusAlertService = TestBed.inject(PrometheusAlertService);
+ spyOn(prometheusAlertService, 'refresh').and.stub();
+
+ prometheusNotificationService = TestBed.inject(PrometheusNotificationService);
+ spyOn(prometheusNotificationService, 'refresh').and.stub();
+ });
+
+ it('should not refresh prometheus services if not allowed', () => {
+ prometheusReadPermission = '';
+ configOptReadPermission = 'read';
+ fixture.detectChanges();
+
+ expectPrometheusServicesToBeCalledTimes(0);
+
+ prometheusReadPermission = 'read';
+ configOptReadPermission = '';
+ fixture.detectChanges();
+
+ expectPrometheusServicesToBeCalledTimes(0);
+ });
+
+ it('should first refresh prometheus notifications and alerts during init', () => {
+ fixture.detectChanges();
+
+ expect(prometheusAlertService.refresh).toHaveBeenCalledTimes(1);
+ expectPrometheusServicesToBeCalledTimes(1);
+ });
+
+ it('should refresh prometheus services every 5s', fakeAsync(() => {
+ fixture.detectChanges();
+
+ expectPrometheusServicesToBeCalledTimes(1);
+ tick(5000);
+ expectPrometheusServicesToBeCalledTimes(2);
+ tick(15000);
+ expectPrometheusServicesToBeCalledTimes(5);
+ component.ngOnDestroy();
+ }));
+ });
+
+ describe('Running Tasks', () => {
+ let summaryService: SummaryService;
+
+ beforeEach(() => {
+ fixture.detectChanges();
+ summaryService = TestBed.inject(SummaryService);
+
+ spyOn(component, '_handleTasks').and.callThrough();
+ });
+
+ it('should handle executing tasks', () => {
+ const running_tasks = new ExecutingTask('rbd/delete', {
+ image_spec: 'somePool/someImage'
+ });
+
+ summaryService['summaryDataSource'].next({ executing_tasks: [running_tasks] });
+
+ expect(component._handleTasks).toHaveBeenCalled();
+ expect(component.executingTasks.length).toBe(1);
+ expect(component.executingTasks[0].description).toBe(`Deleting RBD 'somePool/someImage'`);
+ });
+ });
+
+ describe('Notifications', () => {
+ it('should fetch latest notifications', fakeAsync(() => {
+ const notificationService: NotificationService = TestBed.inject(NotificationService);
+ fixture.detectChanges();
+
+ expect(component.notifications.length).toBe(0);
+
+ notificationService.show(NotificationType.success, 'Sample title', 'Sample message');
+ tick(6000);
+ expect(component.notifications.length).toBe(1);
+ expect(component.notifications[0].title).toBe('Sample title');
+ }));
+ });
+
+ describe('Sidebar', () => {
+ let notificationService: NotificationService;
+
+ beforeEach(() => {
+ notificationService = TestBed.inject(NotificationService);
+ fixture.detectChanges();
+ });
+
+ it('should always close if sidebarSubject value is true', fakeAsync(() => {
+ // Closed before next value
+ expect(component.isSidebarOpened).toBeFalsy();
+ notificationService.sidebarSubject.next(true);
+ tick();
+ expect(component.isSidebarOpened).toBeFalsy();
+
+ // Opened before next value
+ component.isSidebarOpened = true;
+ expect(component.isSidebarOpened).toBeTruthy();
+ notificationService.sidebarSubject.next(true);
+ tick();
+ expect(component.isSidebarOpened).toBeFalsy();
+ }));
+
+ it('should toggle sidebar visibility if sidebarSubject value is false', () => {
+ // Closed before next value
+ expect(component.isSidebarOpened).toBeFalsy();
+ notificationService.sidebarSubject.next(false);
+ expect(component.isSidebarOpened).toBeTruthy();
+
+ // Opened before next value
+ component.isSidebarOpened = true;
+ expect(component.isSidebarOpened).toBeTruthy();
+ notificationService.sidebarSubject.next(false);
+ expect(component.isSidebarOpened).toBeFalsy();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.ts
new file mode 100644
index 000000000..8c5caf7ff
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.ts
@@ -0,0 +1,167 @@
+import {
+ ChangeDetectionStrategy,
+ ChangeDetectorRef,
+ Component,
+ HostBinding,
+ NgZone,
+ OnDestroy,
+ OnInit
+} from '@angular/core';
+
+import { Mutex } from 'async-mutex';
+import _ from 'lodash';
+import moment from 'moment';
+import { Subscription } from 'rxjs';
+
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdNotification } from '~/app/shared/models/cd-notification';
+import { ExecutingTask } from '~/app/shared/models/executing-task';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { PrometheusAlertService } from '~/app/shared/services/prometheus-alert.service';
+import { PrometheusNotificationService } from '~/app/shared/services/prometheus-notification.service';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { TaskMessageService } from '~/app/shared/services/task-message.service';
+
+@Component({
+ selector: 'cd-notifications-sidebar',
+ templateUrl: './notifications-sidebar.component.html',
+ styleUrls: ['./notifications-sidebar.component.scss'],
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class NotificationsSidebarComponent implements OnInit, OnDestroy {
+ @HostBinding('class.active') isSidebarOpened = false;
+
+ notifications: CdNotification[];
+ private interval: number;
+ private timeout: number;
+
+ executingTasks: ExecutingTask[] = [];
+
+ private subs = new Subscription();
+
+ icons = Icons;
+
+ // Tasks
+ last_task = '';
+ mutex = new Mutex();
+
+ simplebar = {
+ autoHide: false
+ };
+
+ constructor(
+ public notificationService: NotificationService,
+ private summaryService: SummaryService,
+ private taskMessageService: TaskMessageService,
+ private prometheusNotificationService: PrometheusNotificationService,
+ private authStorageService: AuthStorageService,
+ private prometheusAlertService: PrometheusAlertService,
+ private ngZone: NgZone,
+ private cdRef: ChangeDetectorRef
+ ) {
+ this.notifications = [];
+ }
+
+ ngOnDestroy() {
+ window.clearInterval(this.interval);
+ window.clearTimeout(this.timeout);
+ this.subs.unsubscribe();
+ }
+
+ ngOnInit() {
+ this.last_task = window.localStorage.getItem('last_task');
+
+ const permissions = this.authStorageService.getPermissions();
+ if (permissions.prometheus.read && permissions.configOpt.read) {
+ this.triggerPrometheusAlerts();
+ this.ngZone.runOutsideAngular(() => {
+ this.interval = window.setInterval(() => {
+ this.ngZone.run(() => {
+ this.triggerPrometheusAlerts();
+ });
+ }, 5000);
+ });
+ }
+
+ this.subs.add(
+ this.notificationService.data$.subscribe((notifications: CdNotification[]) => {
+ this.notifications = _.orderBy(notifications, ['timestamp'], ['desc']);
+ this.cdRef.detectChanges();
+ })
+ );
+
+ this.subs.add(
+ this.notificationService.sidebarSubject.subscribe((forceClose) => {
+ if (forceClose) {
+ this.isSidebarOpened = false;
+ } else {
+ this.isSidebarOpened = !this.isSidebarOpened;
+ }
+
+ window.clearTimeout(this.timeout);
+ this.timeout = window.setTimeout(() => {
+ this.cdRef.detectChanges();
+ }, 0);
+ })
+ );
+
+ this.subs.add(
+ this.summaryService.subscribe((summary) => {
+ this._handleTasks(summary.executing_tasks);
+
+ this.mutex.acquire().then((release) => {
+ _.filter(
+ summary.finished_tasks,
+ (task: FinishedTask) => !this.last_task || moment(task.end_time).isAfter(this.last_task)
+ ).forEach((task) => {
+ const config = this.notificationService.finishedTaskToNotification(task, task.success);
+ const notification = new CdNotification(config);
+ notification.timestamp = task.end_time;
+ notification.duration = task.duration;
+
+ if (!this.last_task || moment(task.end_time).isAfter(this.last_task)) {
+ this.last_task = task.end_time;
+ window.localStorage.setItem('last_task', this.last_task);
+ }
+
+ this.notificationService.save(notification);
+ });
+
+ this.cdRef.detectChanges();
+
+ release();
+ });
+ })
+ );
+ }
+
+ _handleTasks(executingTasks: ExecutingTask[]) {
+ for (const excutingTask of executingTasks) {
+ excutingTask.description = this.taskMessageService.getRunningTitle(excutingTask);
+ }
+ this.executingTasks = executingTasks;
+ }
+
+ private triggerPrometheusAlerts() {
+ this.prometheusAlertService.refresh();
+ this.prometheusNotificationService.refresh();
+ }
+
+ removeAll() {
+ this.notificationService.removeAll();
+ }
+
+ remove(index: number) {
+ this.notificationService.remove(index);
+ }
+
+ closeSidebar() {
+ this.isSidebarOpened = false;
+ }
+
+ trackByFn(index: number) {
+ return index;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html
new file mode 100644
index 000000000..f33261d80
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html
@@ -0,0 +1,10 @@
+<cd-alert-panel *ngIf="missingFeatures; else elseBlock"
+ type="info"
+ i18n>The feature is not supported in the current Orchestrator.</cd-alert-panel>
+
+<ng-template #elseBlock>
+ <cd-alert-panel type="info"
+ i18n>Orchestrator is not available.
+ Please consult the <cd-doc section="orch"></cd-doc> on how to configure and
+ enable the functionality.</cd-alert-panel>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.spec.ts
new file mode 100644
index 000000000..2a3613474
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.spec.ts
@@ -0,0 +1,29 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { CephReleaseNamePipe } from '~/app/shared/pipes/ceph-release-name.pipe';
+import { SummaryService } from '~/app/shared/services/summary.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { ComponentsModule } from '../components.module';
+import { OrchestratorDocPanelComponent } from './orchestrator-doc-panel.component';
+
+describe('OrchestratorDocPanelComponent', () => {
+ let component: OrchestratorDocPanelComponent;
+ let fixture: ComponentFixture<OrchestratorDocPanelComponent>;
+
+ configureTestBed({
+ imports: [ComponentsModule, HttpClientTestingModule, RouterTestingModule],
+ providers: [CephReleaseNamePipe, SummaryService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OrchestratorDocPanelComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.ts
new file mode 100644
index 000000000..d5bc36ad6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.ts
@@ -0,0 +1,13 @@
+import { Component, Input } from '@angular/core';
+
+import { OrchestratorFeature } from '~/app/shared/models/orchestrator.enum';
+
+@Component({
+ selector: 'cd-orchestrator-doc-panel',
+ templateUrl: './orchestrator-doc-panel.component.html',
+ styleUrls: ['./orchestrator-doc-panel.component.scss']
+})
+export class OrchestratorDocPanelComponent {
+ @Input()
+ missingFeatures: OrchestratorFeature[];
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html
new file mode 100644
index 000000000..b1bc5150a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html
@@ -0,0 +1,16 @@
+<cd-alert-panel class="no-margin-bottom"
+ [type]="alertType"
+ *ngIf="displayNotification"
+ [showTitle]="false"
+ size="slim"
+ [dismissible]="alertType !== 'danger'"
+ (dismissed)="onDismissed()">
+ <div *ngIf="expirationDays === 0"
+ i18n>Your password will expire in <strong>less than 1</strong> day. Click
+ <a routerLink="/user-profile/edit"
+ class="alert-link">here</a> to change it now.</div>
+ <div *ngIf="expirationDays > 0"
+ i18n>Your password will expire in <strong>{{ expirationDays }}</strong> day(s). Click
+ <a routerLink="/user-profile/edit"
+ class="alert-link">here</a> to change it now.</div>
+</cd-alert-panel>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.scss
new file mode 100644
index 000000000..dc5cdeb84
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.scss
@@ -0,0 +1,3 @@
+.no-margin-bottom {
+ margin-bottom: 0;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.spec.ts
new file mode 100644
index 000000000..597f5bab3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.spec.ts
@@ -0,0 +1,107 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { Component } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { Routes } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbAlertModule } from '@ng-bootstrap/ng-bootstrap';
+import { of as observableOf } from 'rxjs';
+
+import { SettingsService } from '~/app/shared/api/settings.service';
+import { AlertPanelComponent } from '~/app/shared/components/alert-panel/alert-panel.component';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { PwdExpirationNotificationComponent } from './pwd-expiration-notification.component';
+
+describe('PwdExpirationNotificationComponent', () => {
+ let component: PwdExpirationNotificationComponent;
+ let fixture: ComponentFixture<PwdExpirationNotificationComponent>;
+ let settingsService: SettingsService;
+ let authStorageService: AuthStorageService;
+
+ @Component({ selector: 'cd-fake', template: '' })
+ class FakeComponent {}
+
+ const routes: Routes = [{ path: 'login', component: FakeComponent }];
+
+ const spyOnDate = (fakeDate: string) => {
+ const dateValue = Date;
+ spyOn(global, 'Date').and.callFake((date) => new dateValue(date ? date : fakeDate));
+ };
+
+ configureTestBed({
+ declarations: [PwdExpirationNotificationComponent, FakeComponent, AlertPanelComponent],
+ imports: [NgbAlertModule, HttpClientTestingModule, RouterTestingModule.withRoutes(routes)],
+ providers: [SettingsService, AuthStorageService]
+ });
+
+ describe('password expiration date has been set', () => {
+ beforeEach(() => {
+ authStorageService = TestBed.inject(AuthStorageService);
+ settingsService = TestBed.inject(SettingsService);
+ spyOn(authStorageService, 'getPwdExpirationDate').and.returnValue(1645488000);
+ spyOn(settingsService, 'getStandardSettings').and.returnValue(
+ observableOf({
+ user_pwd_expiration_warning_1: 10,
+ user_pwd_expiration_warning_2: 5,
+ user_pwd_expiration_span: 90
+ })
+ );
+ fixture = TestBed.createComponent(PwdExpirationNotificationComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ component.ngOnInit();
+ expect(component).toBeTruthy();
+ });
+
+ it('should set warning levels', () => {
+ component.ngOnInit();
+ expect(component.pwdExpirationSettings.pwdExpirationWarning1).toBe(10);
+ expect(component.pwdExpirationSettings.pwdExpirationWarning2).toBe(5);
+ });
+
+ it('should calculate password expiration in days', () => {
+ spyOnDate('2022-02-18T00:00:00.000Z');
+ component.ngOnInit();
+ expect(component['expirationDays']).toBe(4);
+ });
+
+ it('should set alert type warning correctly', () => {
+ spyOnDate('2022-02-14T00:00:00.000Z');
+ component.ngOnInit();
+ expect(component['alertType']).toBe('warning');
+ expect(component.displayNotification).toBeTruthy();
+ });
+
+ it('should set alert type danger correctly', () => {
+ spyOnDate('2022-02-18T00:00:00.000Z');
+ component.ngOnInit();
+ expect(component['alertType']).toBe('danger');
+ expect(component.displayNotification).toBeTruthy();
+ });
+
+ it('should not display if date is far', () => {
+ spyOnDate('2022-01-01T00:00:00.000Z');
+ component.ngOnInit();
+ expect(component.displayNotification).toBeFalsy();
+ });
+ });
+
+ describe('password expiration date has not been set', () => {
+ beforeEach(() => {
+ authStorageService = TestBed.inject(AuthStorageService);
+ spyOn(authStorageService, 'getPwdExpirationDate').and.returnValue(null);
+ fixture = TestBed.createComponent(PwdExpirationNotificationComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should calculate no expirationDays', () => {
+ component.ngOnInit();
+ expect(component['expirationDays']).toBeUndefined();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.ts
new file mode 100644
index 000000000..3dd8b5455
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.ts
@@ -0,0 +1,55 @@
+import { Component, OnDestroy, OnInit } from '@angular/core';
+
+import { SettingsService } from '~/app/shared/api/settings.service';
+import { CdPwdExpirationSettings } from '~/app/shared/models/cd-pwd-expiration-settings';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+
+@Component({
+ selector: 'cd-pwd-expiration-notification',
+ templateUrl: './pwd-expiration-notification.component.html',
+ styleUrls: ['./pwd-expiration-notification.component.scss']
+})
+export class PwdExpirationNotificationComponent implements OnInit, OnDestroy {
+ alertType: string;
+ expirationDays: number;
+ pwdExpirationSettings: CdPwdExpirationSettings;
+ displayNotification = false;
+
+ constructor(
+ private settingsService: SettingsService,
+ private authStorageService: AuthStorageService
+ ) {}
+
+ ngOnInit() {
+ this.settingsService.getStandardSettings().subscribe((pwdExpirationSettings) => {
+ this.pwdExpirationSettings = new CdPwdExpirationSettings(pwdExpirationSettings);
+ const pwdExpirationDate = this.authStorageService.getPwdExpirationDate();
+ if (pwdExpirationDate) {
+ this.expirationDays = this.getExpirationDays(pwdExpirationDate);
+ if (this.expirationDays <= this.pwdExpirationSettings.pwdExpirationWarning2) {
+ this.alertType = 'danger';
+ } else {
+ this.alertType = 'warning';
+ }
+ this.displayNotification =
+ this.expirationDays <= this.pwdExpirationSettings.pwdExpirationWarning1;
+ this.authStorageService.isPwdDisplayedSource.next(this.displayNotification);
+ }
+ });
+ }
+
+ ngOnDestroy() {
+ this.authStorageService.isPwdDisplayedSource.next(false);
+ }
+
+ private getExpirationDays(pwdExpirationDate: number): number {
+ const current = new Date();
+ const expiration = new Date(pwdExpirationDate * 1000);
+ return Math.floor((expiration.valueOf() - current.valueOf()) / (1000 * 3600 * 24));
+ }
+
+ onDismissed(): void {
+ this.authStorageService.isPwdDisplayedSource.next(false);
+ this.displayNotification = false;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.html
new file mode 100644
index 000000000..d33fc9af8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.html
@@ -0,0 +1,19 @@
+<div class="container-fluid">
+ <div class="row">
+ <div class="col d-flex justify-content-end">
+ <form class="form-inline">
+ <label for="refreshInterval"
+ class="col-form-label my-0 mx-2"
+ i18n>Refresh</label>
+ <select id="refreshInterval"
+ name="refreshInterval"
+ class="form-control"
+ (change)="changeRefreshInterval($event.target.value)"
+ [(ngModel)]="selectedInterval">
+ <option *ngFor="let key of intervalKeys"
+ [value]="intervalList[key]">{{ key }}</option>
+ </select>
+ </form>
+ </div>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.spec.ts
new file mode 100644
index 000000000..cb98cadd7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.spec.ts
@@ -0,0 +1,27 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule } from '@angular/forms';
+
+import { RefreshIntervalService } from '~/app/shared/services/refresh-interval.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RefreshSelectorComponent } from './refresh-selector.component';
+
+describe('RefreshSelectorComponent', () => {
+ let component: RefreshSelectorComponent;
+ let fixture: ComponentFixture<RefreshSelectorComponent>;
+
+ configureTestBed({
+ imports: [FormsModule],
+ declarations: [RefreshSelectorComponent],
+ providers: [RefreshIntervalService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RefreshSelectorComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.ts
new file mode 100644
index 000000000..080890e26
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.ts
@@ -0,0 +1,32 @@
+import { Component, OnInit } from '@angular/core';
+
+import { RefreshIntervalService } from '~/app/shared/services/refresh-interval.service';
+
+@Component({
+ selector: 'cd-refresh-selector',
+ templateUrl: './refresh-selector.component.html',
+ styleUrls: ['./refresh-selector.component.scss']
+})
+export class RefreshSelectorComponent implements OnInit {
+ selectedInterval: number;
+ intervalList: { [key: string]: number } = {
+ '5 s': 5000,
+ '10 s': 10000,
+ '15 s': 15000,
+ '30 s': 30000,
+ '1 min': 60000,
+ '3 min': 180000,
+ '5 min': 300000
+ };
+ intervalKeys = Object.keys(this.intervalList);
+
+ constructor(private refreshIntervalService: RefreshIntervalService) {}
+
+ ngOnInit() {
+ this.selectedInterval = this.refreshIntervalService.getRefreshInterval() || 5000;
+ }
+
+ changeRefreshInterval(interval: number) {
+ this.refreshIntervalService.setRefreshInterval(interval);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.html
new file mode 100644
index 000000000..0f23aee87
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.html
@@ -0,0 +1,22 @@
+<cd-select #cdSelect
+ [data]="data"
+ [options]="options"
+ [messages]="messages"
+ [selectionLimit]="selectionLimit"
+ [customBadges]="customBadges"
+ [customBadgeValidators]="customBadgeValidators"
+ elemClass="mr-2 select-menu-edit"
+ (selection)="selection.emit($event)">
+ <i [ngClass]="[icons.edit]"></i>
+</cd-select>
+
+<span *ngFor="let dataItem of data">
+ <span class="badge badge-dark mr-2">
+ <span class="mr-2">{{ dataItem }}</span>
+ <a class="badge-remove"
+ (click)="cdSelect.removeItem(dataItem)">
+ <i [ngClass]="[icons.destroy]"
+ aria-hidden="true"></i>
+ </a>
+ </span>
+</span>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.scss
new file mode 100644
index 000000000..e1271c5e4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.scss
@@ -0,0 +1,9 @@
+@use './src/styles/vendor/variables' as vv;
+
+.badge-remove {
+ color: vv.$white;
+}
+
+i.fa-pencil {
+ font-size: 1.1rem;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.spec.ts
new file mode 100644
index 000000000..ac7323b73
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.spec.ts
@@ -0,0 +1,57 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule, Validators } from '@angular/forms';
+
+import { NgbPopoverModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { SelectMessages } from '../select/select-messages.model';
+import { SelectComponent } from '../select/select.component';
+import { SelectBadgesComponent } from './select-badges.component';
+
+describe('SelectBadgesComponent', () => {
+ let component: SelectBadgesComponent;
+ let fixture: ComponentFixture<SelectBadgesComponent>;
+
+ configureTestBed({
+ declarations: [SelectBadgesComponent, SelectComponent],
+ imports: [NgbPopoverModule, NgbTooltipModule, ReactiveFormsModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(SelectBadgesComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should reflect the attributes into CdSelect', () => {
+ const data = ['a', 'b'];
+ const options = [
+ { name: 'option1', description: '', selected: false, enabled: true },
+ { name: 'option2', description: '', selected: false, enabled: true }
+ ];
+ const messages = new SelectMessages({ empty: 'foo bar' });
+ const selectionLimit = 2;
+ const customBadges = true;
+ const customBadgeValidators = [Validators.required];
+
+ component.data = data;
+ component.options = options;
+ component.messages = messages;
+ component.selectionLimit = selectionLimit;
+ component.customBadges = customBadges;
+ component.customBadgeValidators = customBadgeValidators;
+
+ fixture.detectChanges();
+
+ expect(component.cdSelect.data).toEqual(data);
+ expect(component.cdSelect.options).toEqual(options);
+ expect(component.cdSelect.messages).toEqual(messages);
+ expect(component.cdSelect.selectionLimit).toEqual(selectionLimit);
+ expect(component.cdSelect.customBadges).toEqual(customBadges);
+ expect(component.cdSelect.customBadgeValidators).toEqual(customBadgeValidators);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.ts
new file mode 100644
index 000000000..b44ecd7e4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.ts
@@ -0,0 +1,35 @@
+import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
+import { ValidatorFn } from '@angular/forms';
+
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { SelectMessages } from '../select/select-messages.model';
+import { SelectOption } from '../select/select-option.model';
+import { SelectComponent } from '../select/select.component';
+
+@Component({
+ selector: 'cd-select-badges',
+ templateUrl: './select-badges.component.html',
+ styleUrls: ['./select-badges.component.scss']
+})
+export class SelectBadgesComponent {
+ @Input()
+ data: Array<string> = [];
+ @Input()
+ options: Array<SelectOption> = [];
+ @Input()
+ messages = new SelectMessages({});
+ @Input()
+ selectionLimit: number;
+ @Input()
+ customBadges = false;
+ @Input()
+ customBadgeValidators: ValidatorFn[] = [];
+
+ @Output()
+ selection = new EventEmitter();
+
+ @ViewChild('cdSelect', { static: true })
+ cdSelect: SelectComponent;
+
+ icons = Icons;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select-messages.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select-messages.model.ts
new file mode 100644
index 000000000..7a28ffb5e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select-messages.model.ts
@@ -0,0 +1,23 @@
+import _ from 'lodash';
+
+export class SelectMessages {
+ empty: string;
+ selectionLimit: any;
+ customValidations = {};
+ filter: string;
+ add: string;
+ noOptions: string;
+
+ constructor(messages: {}) {
+ this.empty = $localize`No items selected.`;
+ this.selectionLimit = {
+ tooltip: $localize`Deselect item to select again`,
+ text: $localize`Selection limit reached`
+ };
+ this.filter = $localize`Filter tags`;
+ this.add = $localize`Add badge`; // followed by " '{{filter.value}}'"
+ this.noOptions = $localize`There are no items available.`;
+
+ _.merge(this, messages);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select-option.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select-option.model.ts
new file mode 100644
index 000000000..bbd970c6f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select-option.model.ts
@@ -0,0 +1,13 @@
+export class SelectOption {
+ selected: boolean;
+ name: string;
+ description: string;
+ enabled: boolean;
+
+ constructor(selected: boolean, name: string, description: string, enabled = true) {
+ this.selected = selected;
+ this.name = name;
+ this.description = description;
+ this.enabled = enabled;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.html
new file mode 100644
index 000000000..1533b9439
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.html
@@ -0,0 +1,79 @@
+<ng-template #popTemplate>
+ <form name="form"
+ #formDir="ngForm"
+ [formGroup]="form"
+ novalidate>
+ <div>
+ <input type="text"
+ formControlName="filter"
+ i18n-placeholder
+ [placeholder]="messages.filter"
+ (keyup)="$event.keyCode == 13 ? selectOption() : updateFilter()"
+ class="form-control text-center" />
+ <ng-container *ngFor="let error of Object.keys(messages.customValidations)">
+ <span class="invalid-feedback text-center d-block"
+ *ngIf="form.showError('filter', formDir) && filter.hasError(error)">
+ {{ messages.customValidations[error] }}
+ </span>
+ </ng-container>
+ </div>
+ </form>
+ <div *ngFor="let option of filteredOptions"
+ class="select-menu-item"
+ [ngClass]="{'help-block disabled': (data.length === selectionLimit || !option.enabled) && !option.selected}"
+ (click)="triggerSelection(option)">
+ <div class="select-menu-item-icon">
+ <i [ngClass]="[icons.check]"
+ aria-hidden="true"
+ *ngIf="option.selected"></i>
+ &nbsp;
+ </div>
+ <div class="select-menu-item-content">
+ {{ option.name }}
+ <ng-container *ngIf="option.description">
+ <br>
+ <small class="form-text text-muted">
+ {{ option.description }}&nbsp;
+ </small>
+ </ng-container>
+ </div>
+ </div>
+ <div *ngIf="isCreatable()"
+ class="select-menu-item"
+ (click)="addCustomOption()">
+ <div class="select-menu-item-icon">
+ <i [ngClass]="[icons.tag]"
+ aria-hidden="true"></i>
+ &nbsp;
+ </div>
+ <div class="select-menu-item-content">
+ {{ messages.add }} '{{ filter.value }}'
+ </div>
+ </div>
+ <div class="is-invalid"
+ *ngIf="data.length === selectionLimit">
+ <span class="form-text text-muted text-center text-warning"
+ [ngbTooltip]="messages.selectionLimit.tooltip"
+ *ngIf="data.length === selectionLimit">
+ {{ messages.selectionLimit.text }}
+ </span>
+ </div>
+</ng-template>
+
+<a class="select-menu-edit float-left"
+ [ngClass]="elemClass"
+ [ngbPopover]="popTemplate"
+ data-testid="select-menu-edit"
+ *ngIf="customBadges || options.length > 0">
+ <ng-content></ng-content>
+</a>
+
+<span class="form-text text-muted float-left"
+ *ngIf="data.length === 0 && !(!customBadges && options.length === 0)">
+ {{ messages.empty }}
+</span>
+
+<span class="form-text text-muted float-left"
+ *ngIf="!customBadges && options.length === 0">
+ {{ messages.noOptions }}
+</span>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.scss
new file mode 100644
index 000000000..9a4b45062
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.scss
@@ -0,0 +1,26 @@
+@use './src/styles/vendor/variables' as vv;
+
+.select-menu-item {
+ border-bottom: 1px solid vv.$datatable-divider-color;
+ cursor: pointer;
+ display: block;
+ font-size: 1rem;
+
+ &:hover {
+ background-color: vv.$gray-200;
+ }
+}
+
+.select-menu-item-icon {
+ float: left;
+ padding: 0.5em;
+ width: 3em;
+}
+
+.select-menu-item-content {
+ padding: 0.5em;
+
+ .form-text {
+ display: flex;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.spec.ts
new file mode 100644
index 000000000..c35ec9091
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.spec.ts
@@ -0,0 +1,276 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule, Validators } from '@angular/forms';
+
+import { NgbPopoverModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { SelectOption } from './select-option.model';
+import { SelectComponent } from './select.component';
+
+describe('SelectComponent', () => {
+ let component: SelectComponent;
+ let fixture: ComponentFixture<SelectComponent>;
+
+ const selectOption = (filter: string) => {
+ component.filter.setValue(filter);
+ component.updateFilter();
+ component.selectOption();
+ };
+
+ configureTestBed({
+ declarations: [SelectComponent],
+ imports: [NgbPopoverModule, NgbTooltipModule, ReactiveFormsModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(SelectComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ component.options = [
+ { name: 'option1', description: '', selected: false, enabled: true },
+ { name: 'option2', description: '', selected: false, enabled: true },
+ { name: 'option3', description: '', selected: false, enabled: true }
+ ];
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should add item', () => {
+ component.data = [];
+ component.triggerSelection(component.options[1]);
+ expect(component.data).toEqual(['option2']);
+ });
+
+ it('should update selected', () => {
+ component.data = ['option2'];
+ component.ngOnChanges();
+ expect(component.options[0].selected).toBe(false);
+ expect(component.options[1].selected).toBe(true);
+ });
+
+ it('should remove item', () => {
+ component.options.map((option) => {
+ option.selected = true;
+ return option;
+ });
+ component.data = ['option1', 'option2', 'option3'];
+ component.removeItem('option1');
+ expect(component.data).toEqual(['option2', 'option3']);
+ });
+
+ it('should not remove item that is not selected', () => {
+ component.options[0].selected = true;
+ component.data = ['option1'];
+ component.removeItem('option2');
+ expect(component.data).toEqual(['option1']);
+ });
+
+ describe('filter values', () => {
+ beforeEach(() => {
+ component.ngOnInit();
+ });
+
+ it('shows all options with no value set', () => {
+ expect(component.filteredOptions).toEqual(component.options);
+ });
+
+ it('shows one option that it filtered for', () => {
+ component.filter.setValue('2');
+ component.updateFilter();
+ expect(component.filteredOptions).toEqual([component.options[1]]);
+ });
+
+ it('shows all options after selecting something', () => {
+ component.filter.setValue('2');
+ component.updateFilter();
+ component.selectOption();
+ expect(component.filteredOptions).toEqual(component.options);
+ });
+
+ it('is not able to create by default with no value set', () => {
+ component.updateFilter();
+ expect(component.isCreatable()).toBeFalsy();
+ });
+
+ it('is not able to create by default with a value set', () => {
+ component.filter.setValue('2');
+ component.updateFilter();
+ expect(component.isCreatable()).toBeFalsy();
+ });
+ });
+
+ describe('automatically add selected options if not in options array', () => {
+ beforeEach(() => {
+ component.data = ['option1', 'option4'];
+ expect(component.options.length).toBe(3);
+ });
+
+ const expectedResult = () => {
+ expect(component.options.length).toBe(4);
+ expect(component.options[3]).toEqual(new SelectOption(true, 'option4', ''));
+ };
+
+ it('with no extra settings', () => {
+ component.ngOnInit();
+ expectedResult();
+ });
+
+ it('with custom badges', () => {
+ component.customBadges = true;
+ component.ngOnInit();
+ expectedResult();
+ });
+
+ it('with limit higher than selected', () => {
+ component.selectionLimit = 3;
+ component.ngOnInit();
+ expectedResult();
+ });
+
+ it('with limit equal to selected', () => {
+ component.selectionLimit = 2;
+ component.ngOnInit();
+ expectedResult();
+ });
+
+ it('with limit lower than selected', () => {
+ component.selectionLimit = 1;
+ component.ngOnInit();
+ expectedResult();
+ });
+ });
+
+ describe('sorted array and options', () => {
+ beforeEach(() => {
+ component.customBadges = true;
+ component.customBadgeValidators = [Validators.pattern('[A-Za-z0-9_]+')];
+ component.data = ['c', 'b'];
+ component.options = [new SelectOption(true, 'd', ''), new SelectOption(true, 'a', '')];
+ component.ngOnInit();
+ });
+
+ it('has a sorted selection', () => {
+ expect(component.data).toEqual(['a', 'b', 'c', 'd']);
+ });
+
+ it('has a sorted options', () => {
+ const sortedOptions = [
+ new SelectOption(true, 'a', ''),
+ new SelectOption(true, 'b', ''),
+ new SelectOption(true, 'c', ''),
+ new SelectOption(true, 'd', '')
+ ];
+ expect(component.options).toEqual(sortedOptions);
+ });
+
+ it('has a sorted selection after adding an item', () => {
+ selectOption('block');
+ expect(component.data).toEqual(['a', 'b', 'block', 'c', 'd']);
+ });
+
+ it('has a sorted options after adding an item', () => {
+ selectOption('block');
+ const sortedOptions = [
+ new SelectOption(true, 'a', ''),
+ new SelectOption(true, 'b', ''),
+ new SelectOption(true, 'block', ''),
+ new SelectOption(true, 'c', ''),
+ new SelectOption(true, 'd', '')
+ ];
+ expect(component.options).toEqual(sortedOptions);
+ });
+ });
+
+ describe('with custom options', () => {
+ beforeEach(() => {
+ component.customBadges = true;
+ component.customBadgeValidators = [Validators.pattern('[A-Za-z0-9_]+')];
+ component.ngOnInit();
+ });
+
+ it('is not able to create with no value set', () => {
+ component.updateFilter();
+ expect(component.isCreatable()).toBeFalsy();
+ });
+
+ it('is able to create with a valid value set', () => {
+ component.filter.setValue('2');
+ component.updateFilter();
+ expect(component.isCreatable()).toBeTruthy();
+ });
+
+ it('is not able to create with a value set that already exist', () => {
+ component.filter.setValue('option2');
+ component.updateFilter();
+ expect(component.isCreatable()).toBeFalsy();
+ });
+
+ it('adds custom option', () => {
+ selectOption('customOption');
+ expect(component.options[0]).toEqual({
+ name: 'customOption',
+ description: '',
+ selected: true,
+ enabled: true
+ });
+ expect(component.options.length).toBe(4);
+ expect(component.data).toEqual(['customOption']);
+ });
+
+ it('will not add an option that did not pass the validation', () => {
+ selectOption(' this does not pass ');
+ expect(component.options.length).toBe(3);
+ expect(component.data).toEqual([]);
+ expect(component.filter.invalid).toBeTruthy();
+ });
+
+ it('removes custom item selection by name', () => {
+ selectOption('customOption');
+ component.removeItem('customOption');
+ expect(component.data).toEqual([]);
+ expect(component.options.length).toBe(4);
+ expect(component.options[0]).toEqual({
+ name: 'customOption',
+ description: '',
+ selected: false,
+ enabled: true
+ });
+ });
+
+ it('will not add an option that is already there', () => {
+ selectOption('option2');
+ expect(component.options.length).toBe(3);
+ expect(component.data).toEqual(['option2']);
+ });
+
+ it('will not add an option twice after each other', () => {
+ selectOption('onlyOnce');
+ expect(component.data).toEqual(['onlyOnce']);
+ selectOption('onlyOnce');
+ expect(component.data).toEqual([]);
+ selectOption('onlyOnce');
+ expect(component.data).toEqual(['onlyOnce']);
+ expect(component.options.length).toBe(4);
+ });
+ });
+
+ describe('if the selection limit is reached', function () {
+ beforeEach(() => {
+ component.selectionLimit = 2;
+ component.triggerSelection(component.options[0]);
+ component.triggerSelection(component.options[1]);
+ });
+
+ it('will not select more options', () => {
+ component.triggerSelection(component.options[2]);
+ expect(component.data).toEqual(['option1', 'option2']);
+ });
+
+ it('will unselect options that are selected', () => {
+ component.triggerSelection(component.options[1]);
+ expect(component.data).toEqual(['option1']);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.ts
new file mode 100644
index 000000000..3ff19fe04
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.ts
@@ -0,0 +1,149 @@
+import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
+import { FormControl, ValidatorFn } from '@angular/forms';
+
+import _ from 'lodash';
+
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { SelectMessages } from './select-messages.model';
+import { SelectOption } from './select-option.model';
+
+@Component({
+ selector: 'cd-select',
+ templateUrl: './select.component.html',
+ styleUrls: ['./select.component.scss']
+})
+export class SelectComponent implements OnInit, OnChanges {
+ @Input()
+ elemClass: string;
+ @Input()
+ data: Array<string> = [];
+ @Input()
+ options: Array<SelectOption> = [];
+ @Input()
+ messages = new SelectMessages({});
+ @Input()
+ selectionLimit: number;
+ @Input()
+ customBadges = false;
+ @Input()
+ customBadgeValidators: ValidatorFn[] = [];
+
+ @Output()
+ selection = new EventEmitter();
+
+ form: CdFormGroup;
+ filter: FormControl;
+ Object = Object;
+ filteredOptions: Array<SelectOption> = [];
+ icons = Icons;
+
+ ngOnInit() {
+ this.initFilter();
+ if (this.data.length > 0) {
+ this.initMissingOptions();
+ }
+ this.options = _.sortBy(this.options, ['name']);
+ this.updateOptions();
+ }
+
+ private initFilter() {
+ this.filter = new FormControl('', { validators: this.customBadgeValidators });
+ this.form = new CdFormGroup({ filter: this.filter });
+ this.filteredOptions = [...(this.options || [])];
+ }
+
+ private initMissingOptions() {
+ const options = this.options.map((option) => option.name);
+ const needToCreate = this.data.filter((option) => options.indexOf(option) === -1);
+ needToCreate.forEach((option) => this.addOption(option));
+ this.forceOptionsToReflectData();
+ }
+
+ private addOption(name: string) {
+ this.options.push(new SelectOption(false, name, ''));
+ this.options = _.sortBy(this.options, ['name']);
+ this.triggerSelection(this.options.find((option) => option.name === name));
+ }
+
+ triggerSelection(option: SelectOption) {
+ if (
+ !option ||
+ (this.selectionLimit && !option.selected && this.data.length >= this.selectionLimit)
+ ) {
+ return;
+ }
+ option.selected = !option.selected;
+ this.updateOptions();
+ this.selection.emit({ option: option });
+ }
+
+ private updateOptions() {
+ this.data.splice(0, this.data.length);
+ this.options.forEach((option: SelectOption) => {
+ if (option.selected) {
+ this.data.push(option.name);
+ }
+ });
+ this.updateFilter();
+ }
+
+ updateFilter() {
+ this.filteredOptions = this.options.filter((option) => option.name.includes(this.filter.value));
+ }
+
+ private forceOptionsToReflectData() {
+ this.options.forEach((option) => {
+ if (this.data.indexOf(option.name) !== -1) {
+ option.selected = true;
+ }
+ });
+ }
+
+ ngOnChanges() {
+ if (this.filter) {
+ this.updateFilter();
+ }
+ if (!this.options || !this.data || this.data.length === 0) {
+ return;
+ }
+ this.forceOptionsToReflectData();
+ }
+
+ selectOption() {
+ if (this.filteredOptions.length === 0) {
+ this.addCustomOption();
+ } else {
+ this.triggerSelection(this.filteredOptions[0]);
+ this.resetFilter();
+ }
+ }
+
+ addCustomOption() {
+ if (!this.isCreatable()) {
+ return;
+ }
+ this.addOption(this.filter.value);
+ this.resetFilter();
+ }
+
+ isCreatable() {
+ return (
+ this.customBadges &&
+ this.filter.valid &&
+ this.filter.value.length > 0 &&
+ this.filteredOptions.every((option) => option.name !== this.filter.value)
+ );
+ }
+
+ private resetFilter() {
+ this.filter.setValue('');
+ this.updateFilter();
+ }
+
+ removeItem(item: string) {
+ this.triggerSelection(
+ this.options.find((option: SelectOption) => option.name === item && option.selected)
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.html
new file mode 100644
index 000000000..c823605d1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.html
@@ -0,0 +1,15 @@
+<div class="chart-container"
+ [ngStyle]="style">
+ <canvas baseChart
+ #sparkCanvas
+ [labels]="labels"
+ [datasets]="datasets"
+ [options]="options"
+ [colors]="colors"
+ [chartType]="'line'">
+ </canvas>
+ <div class="chartjs-tooltip"
+ #sparkTooltip>
+ <table></table>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.scss
new file mode 100644
index 000000000..25486150b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.scss
@@ -0,0 +1,5 @@
+@use './src/styles/chart-tooltip';
+
+.chart-container {
+ position: static !important;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.spec.ts
new file mode 100644
index 000000000..b8e731d6e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.spec.ts
@@ -0,0 +1,52 @@
+import { NO_ERRORS_SCHEMA, SimpleChange } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { FormatterService } from '~/app/shared/services/formatter.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { SparklineComponent } from './sparkline.component';
+
+describe('SparklineComponent', () => {
+ let component: SparklineComponent;
+ let fixture: ComponentFixture<SparklineComponent>;
+
+ configureTestBed({
+ declarations: [SparklineComponent],
+ schemas: [NO_ERRORS_SCHEMA],
+ providers: [DimlessBinaryPipe, FormatterService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(SparklineComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ expect(component.options.tooltips.custom).toBeDefined();
+ });
+
+ it('should update', () => {
+ expect(component.datasets).toEqual([{ data: [] }]);
+ expect(component.labels.length).toBe(0);
+
+ component.data = [11, 22, 33];
+ component.ngOnChanges({ data: new SimpleChange(null, component.data, false) });
+
+ expect(component.datasets).toEqual([{ data: [11, 22, 33] }]);
+ expect(component.labels.length).toBe(3);
+ });
+
+ it('should not transform the label, if not isBinary', () => {
+ component.isBinary = false;
+ const result = component.options.tooltips.callbacks.label({ yLabel: 1024 });
+ expect(result).toBe(1024);
+ });
+
+ it('should transform the label, if isBinary', () => {
+ component.isBinary = true;
+ const result = component.options.tooltips.callbacks.label({ yLabel: 1024 });
+ expect(result).toBe('1 KiB');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.ts
new file mode 100644
index 000000000..e2f5af5e0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.ts
@@ -0,0 +1,130 @@
+import {
+ Component,
+ ElementRef,
+ Input,
+ OnChanges,
+ OnInit,
+ SimpleChanges,
+ ViewChild
+} from '@angular/core';
+
+import { ChartTooltip } from '~/app/shared/models/chart-tooltip';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+
+@Component({
+ selector: 'cd-sparkline',
+ templateUrl: './sparkline.component.html',
+ styleUrls: ['./sparkline.component.scss']
+})
+export class SparklineComponent implements OnInit, OnChanges {
+ @ViewChild('sparkCanvas', { static: true })
+ chartCanvasRef: ElementRef;
+ @ViewChild('sparkTooltip', { static: true })
+ chartTooltipRef: ElementRef;
+
+ @Input()
+ data: any;
+ @Input()
+ style = {
+ height: '30px',
+ width: '100px'
+ };
+ @Input()
+ isBinary: boolean;
+
+ public colors: Array<any> = [
+ {
+ backgroundColor: 'rgba(40,140,234,0.2)',
+ borderColor: 'rgba(40,140,234,1)',
+ pointBackgroundColor: 'rgba(40,140,234,1)',
+ pointBorderColor: '#fff',
+ pointHoverBackgroundColor: '#fff',
+ pointHoverBorderColor: 'rgba(40,140,234,0.8)'
+ }
+ ];
+
+ options: Record<string, any> = {
+ animation: {
+ duration: 0
+ },
+ responsive: true,
+ maintainAspectRatio: false,
+ legend: {
+ display: false
+ },
+ elements: {
+ line: {
+ borderWidth: 1
+ }
+ },
+ tooltips: {
+ enabled: false,
+ mode: 'index',
+ intersect: false,
+ custom: undefined,
+ callbacks: {
+ label: (tooltipItem: any) => {
+ if (this.isBinary) {
+ return this.dimlessBinaryPipe.transform(tooltipItem.yLabel);
+ } else {
+ return tooltipItem.yLabel;
+ }
+ },
+ title: () => ''
+ }
+ },
+ scales: {
+ yAxes: [
+ {
+ display: false
+ }
+ ],
+ xAxes: [
+ {
+ display: false
+ }
+ ]
+ }
+ };
+
+ public datasets: Array<any> = [
+ {
+ data: []
+ }
+ ];
+
+ public labels: Array<any> = [];
+
+ constructor(private dimlessBinaryPipe: DimlessBinaryPipe) {}
+
+ ngOnInit() {
+ const getStyleTop = (tooltip: any) => {
+ return tooltip.caretY - tooltip.height - tooltip.yPadding - 5 + 'px';
+ };
+
+ const getStyleLeft = (tooltip: any, positionX: number) => {
+ return positionX + tooltip.caretX + 'px';
+ };
+
+ const chartTooltip = new ChartTooltip(
+ this.chartCanvasRef,
+ this.chartTooltipRef,
+ getStyleLeft,
+ getStyleTop
+ );
+
+ chartTooltip.customColors = {
+ backgroundColor: this.colors[0].pointBackgroundColor,
+ borderColor: this.colors[0].pointBorderColor
+ };
+
+ this.options.tooltips.custom = (tooltip: any) => {
+ chartTooltip.customTooltips(tooltip);
+ };
+ }
+
+ ngOnChanges(changes: SimpleChanges) {
+ this.datasets[0].data = changes['data'].currentValue;
+ this.labels = [...Array(changes['data'].currentValue.length)];
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.html
new file mode 100644
index 000000000..af557a293
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.html
@@ -0,0 +1,11 @@
+<button [type]="type"
+ class="btn btn-accent tc_submitButton"
+ [ngClass]="btnClass"
+ [disabled]="loading || disabled"
+ (click)="submit($event)"
+ [attr.aria-label]="ariaLabel">
+ <ng-content></ng-content>
+ <span *ngIf="loading">
+ <i [ngClass]="[icons.spinner, icons.spin]"></i>
+ </span>
+</button>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.spec.ts
new file mode 100644
index 000000000..a7b7023d0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.spec.ts
@@ -0,0 +1,27 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormGroup } from '@angular/forms';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { SubmitButtonComponent } from './submit-button.component';
+
+describe('SubmitButtonComponent', () => {
+ let component: SubmitButtonComponent;
+ let fixture: ComponentFixture<SubmitButtonComponent>;
+
+ configureTestBed({
+ declarations: [SubmitButtonComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(SubmitButtonComponent);
+ component = fixture.componentInstance;
+
+ component.form = new FormGroup({}, {});
+
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.ts
new file mode 100644
index 000000000..3309f47ed
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.ts
@@ -0,0 +1,99 @@
+import { Component, ElementRef, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { AbstractControl, FormGroup, FormGroupDirective, NgForm } from '@angular/forms';
+
+import _ from 'lodash';
+
+import { Icons } from '~/app/shared/enum/icons.enum';
+
+/**
+ * This component will render a submit button with the given label.
+ *
+ * The button will disabled itself and show a loading icon when the user clicks
+ * it, usually initiating a request to the server, and it will stay in that
+ * state until the request is finished.
+ *
+ * To indicate that the request failed, returning the button to the enable
+ * state, you need to insert an error in the form with the 'cdSubmitButton' key.
+ * p.e.: this.rbdForm.setErrors({'cdSubmitButton': true});
+ *
+ * It will also check if the form is valid, when clicking the button, and will
+ * focus on the first invalid input.
+ *
+ * @export
+ * @class SubmitButtonComponent
+ * @implements {OnInit}
+ */
+@Component({
+ selector: 'cd-submit-button',
+ templateUrl: './submit-button.component.html',
+ styleUrls: ['./submit-button.component.scss']
+})
+export class SubmitButtonComponent implements OnInit {
+ @Input()
+ form: FormGroup | NgForm;
+
+ @Input()
+ type = 'submit';
+
+ @Input()
+ disabled = false;
+
+ // A CSS class string to apply to the button's main element.
+ @Input()
+ btnClass: string;
+
+ @Input()
+ ariaLabel: string;
+
+ @Output()
+ submitAction = new EventEmitter();
+
+ loading = false;
+ icons = Icons;
+
+ constructor(private elRef: ElementRef) {}
+
+ ngOnInit() {
+ this.form.statusChanges.subscribe(() => {
+ if (_.has(this.form.errors, 'cdSubmitButton')) {
+ this.loading = false;
+ _.unset(this.form.errors, 'cdSubmitButton');
+ // Handle Reactive forms.
+ if (this.form instanceof AbstractControl) {
+ (<AbstractControl>this.form).updateValueAndValidity();
+ }
+ }
+ });
+ }
+
+ submit($event: any) {
+ this.focusButton();
+
+ // Special handling for Template driven forms.
+ if (this.form instanceof FormGroupDirective) {
+ (<FormGroupDirective>this.form).onSubmit($event);
+ }
+
+ if (this.form.invalid) {
+ this.focusInvalid();
+ return;
+ }
+
+ this.loading = true;
+ this.submitAction.emit();
+ }
+
+ focusButton() {
+ this.elRef.nativeElement.offsetParent.querySelector(`button[type="${this.type}"]`).focus();
+ }
+
+ focusInvalid() {
+ const target = this.elRef.nativeElement.offsetParent.querySelector(
+ 'input.ng-invalid, select.ng-invalid'
+ );
+
+ if (target) {
+ target.focus();
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.html
new file mode 100644
index 000000000..9af795837
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.html
@@ -0,0 +1,12 @@
+<cd-alert-panel *ngIf="displayNotification"
+ class="no-margin-bottom"
+ [showTitle]="false"
+ size="slim"
+ [type]="notificationSeverity"
+ [dismissible]="notificationSeverity !== 'danger'"
+ (dismissed)="onDismissed()">
+ <div i18n>The Ceph community needs your help to continue improving: please
+ <a routerLink="/telemetry"
+ class="btn activate-button alert-link activate-text">Activate</a> the
+ <a href="https://docs.ceph.com/en/latest/mgr/telemetry/">Telemetry</a> module.</div>
+</cd-alert-panel>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.scss
new file mode 100644
index 000000000..cf8aa33d3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.scss
@@ -0,0 +1,17 @@
+@use './src/styles/vendor/variables' as vv;
+
+.no-margin-bottom {
+ margin-bottom: 0;
+}
+
+.activate-button {
+ background-color: vv.$barley-white;
+ border: vv.$gray-700 solid 0.5px;
+ border-radius: 10%;
+ padding: 0.1rem 0.4rem;
+}
+
+.activate-text {
+ color: vv.$gray-700;
+ font-weight: bold;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.spec.ts
new file mode 100644
index 000000000..e946e79d8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.spec.ts
@@ -0,0 +1,107 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NgbAlertModule } from '@ng-bootstrap/ng-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
+
+import { MgrModuleService } from '~/app/shared/api/mgr-module.service';
+import { UserService } from '~/app/shared/api/user.service';
+import { AlertPanelComponent } from '~/app/shared/components/alert-panel/alert-panel.component';
+import { Permissions } from '~/app/shared/models/permissions';
+import { PipesModule } from '~/app/shared/pipes/pipes.module';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { TelemetryNotificationService } from '~/app/shared/services/telemetry-notification.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { TelemetryNotificationComponent } from './telemetry-notification.component';
+
+describe('TelemetryActivationNotificationComponent', () => {
+ let component: TelemetryNotificationComponent;
+ let fixture: ComponentFixture<TelemetryNotificationComponent>;
+
+ let authStorageService: AuthStorageService;
+ let mgrModuleService: MgrModuleService;
+ let notificationService: NotificationService;
+
+ let isNotificationHiddenSpy: jasmine.Spy;
+ let getPermissionsSpy: jasmine.Spy;
+ let getConfigSpy: jasmine.Spy;
+
+ const configOptPermissions: Permissions = new Permissions({
+ 'config-opt': ['read', 'create', 'update', 'delete']
+ });
+ const noConfigOptPermissions: Permissions = new Permissions({});
+ const telemetryEnabledConfig = {
+ enabled: true
+ };
+ const telemetryDisabledConfig = {
+ enabled: false
+ };
+
+ configureTestBed({
+ declarations: [TelemetryNotificationComponent, AlertPanelComponent],
+ imports: [NgbAlertModule, HttpClientTestingModule, ToastrModule.forRoot(), PipesModule],
+ providers: [MgrModuleService, UserService]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TelemetryNotificationComponent);
+ component = fixture.componentInstance;
+ authStorageService = TestBed.inject(AuthStorageService);
+ mgrModuleService = TestBed.inject(MgrModuleService);
+ notificationService = TestBed.inject(NotificationService);
+
+ isNotificationHiddenSpy = spyOn(component, 'isNotificationHidden').and.returnValue(false);
+ getPermissionsSpy = spyOn(authStorageService, 'getPermissions').and.returnValue(
+ configOptPermissions
+ );
+ getConfigSpy = spyOn(mgrModuleService, 'getConfig').and.returnValue(
+ of(telemetryDisabledConfig)
+ );
+ });
+
+ it('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+
+ it('should not show notification again if the user closed it before', () => {
+ isNotificationHiddenSpy.and.returnValue(true);
+ fixture.detectChanges();
+ expect(component.displayNotification).toBe(false);
+ });
+
+ it('should not show notification for a user without configOpt permissions', () => {
+ getPermissionsSpy.and.returnValue(noConfigOptPermissions);
+ fixture.detectChanges();
+ expect(component.displayNotification).toBe(false);
+ });
+
+ it('should not show notification if the module is enabled already', () => {
+ getConfigSpy.and.returnValue(of(telemetryEnabledConfig));
+ fixture.detectChanges();
+ expect(component.displayNotification).toBe(false);
+ });
+
+ it('should show the notification if all pre-conditions set accordingly', () => {
+ fixture.detectChanges();
+ expect(component.displayNotification).toBe(true);
+ });
+
+ it('should hide the notification if the user closes it', () => {
+ spyOn(notificationService, 'show');
+ fixture.detectChanges();
+ component.onDismissed();
+ expect(notificationService.show).toHaveBeenCalled();
+ expect(localStorage.getItem('telemetry_notification_hidden')).toBe('true');
+ });
+
+ it('should hide the notification if the user logs out', () => {
+ const telemetryNotificationService = TestBed.inject(TelemetryNotificationService);
+ spyOn(telemetryNotificationService, 'setVisibility');
+ fixture.detectChanges();
+ component.ngOnDestroy();
+ expect(telemetryNotificationService.setVisibility).toHaveBeenCalledWith(false);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.ts
new file mode 100644
index 000000000..33174ce11
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.ts
@@ -0,0 +1,62 @@
+import { Component, OnDestroy, OnInit } from '@angular/core';
+
+import _ from 'lodash';
+
+import { MgrModuleService } from '~/app/shared/api/mgr-module.service';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { TelemetryNotificationService } from '~/app/shared/services/telemetry-notification.service';
+
+@Component({
+ selector: 'cd-telemetry-notification',
+ templateUrl: './telemetry-notification.component.html',
+ styleUrls: ['./telemetry-notification.component.scss']
+})
+export class TelemetryNotificationComponent implements OnInit, OnDestroy {
+ displayNotification = false;
+ notificationSeverity = 'warning';
+
+ constructor(
+ private mgrModuleService: MgrModuleService,
+ private authStorageService: AuthStorageService,
+ private notificationService: NotificationService,
+ private telemetryNotificationService: TelemetryNotificationService
+ ) {}
+
+ ngOnInit() {
+ this.telemetryNotificationService.update.subscribe((visible: boolean) => {
+ this.displayNotification = visible;
+ });
+
+ if (!this.isNotificationHidden()) {
+ const configOptPermissions = this.authStorageService.getPermissions().configOpt;
+ if (_.every(Object.values(configOptPermissions))) {
+ this.mgrModuleService.getConfig('telemetry').subscribe((options) => {
+ if (!options['enabled']) {
+ this.telemetryNotificationService.setVisibility(true);
+ }
+ });
+ }
+ }
+ }
+
+ ngOnDestroy() {
+ this.telemetryNotificationService.setVisibility(false);
+ }
+
+ isNotificationHidden(): boolean {
+ return localStorage.getItem('telemetry_notification_hidden') === 'true';
+ }
+
+ onDismissed(): void {
+ this.telemetryNotificationService.setVisibility(false);
+ localStorage.setItem('telemetry_notification_hidden', 'true');
+ this.notificationService.show(
+ NotificationType.success,
+ $localize`Telemetry activation reminder muted`,
+ $localize`You can activate the module on the Telemetry configuration \
+page (<b>Dashboard Settings</b> -> <b>Telemetry configuration</b>) at any time.`
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.html
new file mode 100644
index 000000000..0602a4e59
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.html
@@ -0,0 +1,27 @@
+<ng-template #usageTooltipTpl>
+ <table>
+ <tr>
+ <td class="text-left">Used:&nbsp;</td>
+ <td class="text-right"><strong> {{ isBinary ? (used | dimlessBinary) : (used | dimless) }}</strong></td>
+ </tr>
+ <tr *ngIf="calculatePerc">
+ <td class="text-left">Free:&nbsp;</td>
+ <td class="'text-right"><strong>{{ isBinary ? (total - used | dimlessBinary) : (total - used | dimless) }}</strong></td>
+ </tr>
+ </table>
+</ng-template>
+
+<div class="progress"
+ data-placement="left"
+ [ngbTooltip]="usageTooltipTpl">
+ <div class="progress-bar bg-info"
+ [ngClass]="{'bg-warning': usedPercentage/100 >= warningThreshold, 'bg-danger': usedPercentage/100 >= errorThreshold}"
+ role="progressbar"
+ [style.width]="usedPercentage + '%'">
+ <span>{{ usedPercentage | number: '1.0-' + decimals }}%</span>
+ </div>
+ <div class="progress-bar bg-freespace"
+ role="progressbar"
+ [style.width]="freePercentage + '%'">
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.scss
new file mode 100644
index 000000000..e9d6d2498
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.scss
@@ -0,0 +1,35 @@
+@use './src/styles/vendor/variables' as vv;
+
+.bg-info {
+ background-color: vv.$primary !important;
+}
+
+.bg-warning {
+ background-color: vv.$warning !important;
+}
+
+.bg-danger {
+ background-color: vv.$danger !important;
+}
+
+.bg-freespace {
+ background-color: vv.$gray-400 !important;
+}
+
+.progress {
+ height: 20px;
+ margin-bottom: 0;
+ position: relative;
+
+ div.progress-bar {
+ position: static;
+ }
+
+ span {
+ color: vv.$black;
+ display: block;
+ font-weight: normal;
+ position: absolute;
+ width: 100%;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.spec.ts
new file mode 100644
index 000000000..45e6a06b6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.spec.ts
@@ -0,0 +1,27 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { PipesModule } from '~/app/shared/pipes/pipes.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { UsageBarComponent } from './usage-bar.component';
+
+describe('UsageBarComponent', () => {
+ let component: UsageBarComponent;
+ let fixture: ComponentFixture<UsageBarComponent>;
+
+ configureTestBed({
+ imports: [PipesModule, NgbTooltipModule],
+ declarations: [UsageBarComponent]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(UsageBarComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.ts
new file mode 100644
index 000000000..203f2c9e0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.ts
@@ -0,0 +1,43 @@
+import { Component, Input, OnChanges } from '@angular/core';
+
+import _ from 'lodash';
+
+@Component({
+ selector: 'cd-usage-bar',
+ templateUrl: './usage-bar.component.html',
+ styleUrls: ['./usage-bar.component.scss']
+})
+export class UsageBarComponent implements OnChanges {
+ @Input()
+ total: number;
+ @Input()
+ used: any;
+ @Input()
+ warningThreshold: number;
+ @Input()
+ errorThreshold: number;
+ @Input()
+ isBinary = true;
+ @Input()
+ decimals = 0;
+ @Input()
+ calculatePerc = true;
+
+ usedPercentage: number;
+ freePercentage: number;
+
+ ngOnChanges() {
+ if (this.calculatePerc) {
+ this.usedPercentage = this.total > 0 ? (this.used / this.total) * 100 : 0;
+ this.freePercentage = 100 - this.usedPercentage;
+ } else {
+ if (this.used) {
+ this.used = this.used.slice(0, -1);
+ this.usedPercentage = Number(this.used);
+ this.freePercentage = 100 - this.usedPercentage;
+ } else {
+ this.usedPercentage = 0;
+ }
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/wizard/wizard.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/wizard/wizard.component.html
new file mode 100644
index 000000000..25aa3e1df
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/wizard/wizard.component.html
@@ -0,0 +1,19 @@
+<div class="card-body">
+ <div class="row m-7">
+ <nav class="col">
+ <ul class="nav nav-pills flex-column"
+ *ngFor="let step of steps | async; let i = index;">
+ <li class="nav-item">
+ <a class="nav-link"
+ (click)="onStepClick(step)"
+ [ngClass]="{active: currentStep.stepIndex === step.stepIndex}">
+ <span class="circle-step"
+ [ngClass]="{active: currentStep.stepIndex === step.stepIndex}"
+ i18n>{{ step.stepIndex }}</span>
+ <span i18n>{{ stepsTitle[i] }}</span>
+ </a>
+ </li>
+ </ul>
+ </nav>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/wizard/wizard.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/wizard/wizard.component.scss
new file mode 100644
index 000000000..071b02e4a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/wizard/wizard.component.scss
@@ -0,0 +1,34 @@
+@use './src/styles/vendor/variables' as vv;
+
+::ng-deep cd-wizard {
+ width: 15%;
+}
+
+.card-body {
+ padding-left: 0;
+}
+
+span.circle-step {
+ background: vv.$gray-500;
+ border-radius: 0.8em;
+ color: vv.$white;
+ display: inline-block;
+ font-weight: bold;
+ line-height: 1.6em;
+ margin-right: 5px;
+ text-align: center;
+ width: 1.6em;
+
+ &.active {
+ background-color: vv.$primary;
+ }
+}
+
+.nav-pills .nav-link {
+ background-color: vv.$white;
+ color: vv.$gray-800;
+
+ &.active {
+ color: vv.$primary;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/wizard/wizard.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/wizard/wizard.component.spec.ts
new file mode 100644
index 000000000..b42578fb7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/wizard/wizard.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SharedModule } from '~/app/shared/shared.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { WizardComponent } from './wizard.component';
+
+describe('WizardComponent', () => {
+ let component: WizardComponent;
+ let fixture: ComponentFixture<WizardComponent>;
+
+ configureTestBed({
+ imports: [SharedModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(WizardComponent);
+ component = fixture.componentInstance;
+ component.stepsTitle = ['Add Hosts', 'Review'];
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/wizard/wizard.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/wizard/wizard.component.ts
new file mode 100644
index 000000000..d46aa480e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/wizard/wizard.component.ts
@@ -0,0 +1,39 @@
+import { Component, Input, OnDestroy, OnInit } from '@angular/core';
+
+import * as _ from 'lodash';
+import { Observable, Subscription } from 'rxjs';
+
+import { WizardStepModel } from '~/app/shared/models/wizard-steps';
+import { WizardStepsService } from '~/app/shared/services/wizard-steps.service';
+
+@Component({
+ selector: 'cd-wizard',
+ templateUrl: './wizard.component.html',
+ styleUrls: ['./wizard.component.scss']
+})
+export class WizardComponent implements OnInit, OnDestroy {
+ @Input()
+ stepsTitle: string[];
+
+ steps: Observable<WizardStepModel[]>;
+ currentStep: WizardStepModel;
+ currentStepSub: Subscription;
+
+ constructor(private stepsService: WizardStepsService) {}
+
+ ngOnInit(): void {
+ this.stepsService.setTotalSteps(this.stepsTitle.length);
+ this.steps = this.stepsService.getSteps();
+ this.currentStepSub = this.stepsService.getCurrentStep().subscribe((step: WizardStepModel) => {
+ this.currentStep = step;
+ });
+ }
+
+ onStepClick(step: WizardStepModel) {
+ this.stepsService.setCurrentStep(step);
+ }
+
+ ngOnDestroy(): void {
+ this.currentStepSub.unsubscribe();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/constants/app.constants.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/constants/app.constants.ts
new file mode 100644
index 000000000..4248be8f5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/constants/app.constants.ts
@@ -0,0 +1,305 @@
+import { Injectable } from '@angular/core';
+
+import { environment } from '~/environments/environment';
+
+export class AppConstants {
+ public static readonly organization = 'ceph';
+ public static readonly projectName = 'Ceph Dashboard';
+ public static readonly license = 'Free software (LGPL 2.1).';
+ public static readonly copyright = 'Copyright(c) ' + environment.year + ' Ceph contributors.';
+ public static readonly cephLogo = 'assets/Ceph_Logo.svg';
+}
+
+export enum URLVerbs {
+ /* Create a new item */
+ CREATE = 'create',
+
+ /* Make changes to an existing item */
+ EDIT = 'edit',
+
+ /* Make changes to an existing item */
+ UPDATE = 'update',
+
+ /* Remove an item from a container WITHOUT deleting it */
+ REMOVE = 'remove',
+
+ /* Destroy an existing item */
+ DELETE = 'delete',
+
+ /* Add an existing item to a container */
+ ADD = 'add',
+
+ /* Non-standard verbs */
+ COPY = 'copy',
+ CLONE = 'clone',
+
+ /* Prometheus wording */
+ RECREATE = 'recreate',
+ EXPIRE = 'expire',
+
+ /* Daemons */
+ RESTART = 'Restart'
+}
+
+export enum ActionLabels {
+ /* Create a new item */
+ CREATE = 'Create',
+
+ /* Destroy an existing item */
+ DELETE = 'Delete',
+
+ /* Add an existing item to a container */
+ ADD = 'Add',
+
+ /* Remove an item from a container WITHOUT deleting it */
+ REMOVE = 'Remove',
+
+ /* Make changes to an existing item */
+ EDIT = 'Edit',
+
+ /* */
+ CANCEL = 'Cancel',
+
+ /* Non-standard actions */
+ COPY = 'Copy',
+ CLONE = 'Clone',
+ UPDATE = 'Update',
+ EVICT = 'Evict',
+
+ /* Read-only */
+ SHOW = 'Show',
+
+ /* Prometheus wording */
+ RECREATE = 'Recreate',
+ EXPIRE = 'Expire',
+
+ /* Daemons */
+ START = 'Start',
+ STOP = 'Stop',
+ REDEPLOY = 'Redeploy',
+ RESTART = 'Restart'
+}
+
+@Injectable({
+ providedIn: 'root'
+})
+export class ActionLabelsI18n {
+ /* This service is required as the i18n polyfill does not provide static
+ translation
+ */
+ CREATE: string;
+ DELETE: string;
+ ADD: string;
+ REMOVE: string;
+ EDIT: string;
+ CANCEL: string;
+ PREVIEW: string;
+ MOVE: string;
+ NEXT: string;
+ BACK: string;
+ CHANGE: string;
+ COPY: string;
+ CLONE: string;
+ DEEP_SCRUB: string;
+ DESTROY: string;
+ EVICT: string;
+ EXPIRE: string;
+ FLATTEN: string;
+ MARK_DOWN: string;
+ MARK_IN: string;
+ MARK_LOST: string;
+ MARK_OUT: string;
+ PROTECT: string;
+ PURGE: string;
+ RECREATE: string;
+ RENAME: string;
+ RESTORE: string;
+ REWEIGHT: string;
+ ROLLBACK: string;
+ SCRUB: string;
+ SET: string;
+ SUBMIT: string;
+ SHOW: string;
+ TRASH: string;
+ UNPROTECT: string;
+ UNSET: string;
+ UPDATE: string;
+ FLAGS: string;
+ ENTER_MAINTENANCE: string;
+ EXIT_MAINTENANCE: string;
+ REMOVE_SCHEDULING: string;
+ PROMOTE: string;
+ DEMOTE: string;
+ START_DRAIN: string;
+ STOP_DRAIN: string;
+ START: string;
+ STOP: string;
+ REDEPLOY: string;
+ RESTART: string;
+ RESYNC: string;
+
+ constructor() {
+ /* Create a new item */
+ this.CREATE = $localize`Create`;
+
+ /* Destroy an existing item */
+ this.DELETE = $localize`Delete`;
+
+ /* Add an existing item to a container */
+ this.ADD = $localize`Add`;
+ this.SET = $localize`Set`;
+ this.SUBMIT = $localize`Submit`;
+
+ /* Remove an item from a container WITHOUT deleting it */
+ this.REMOVE = $localize`Remove`;
+ this.UNSET = $localize`Unset`;
+
+ /* Make changes to an existing item */
+ this.EDIT = $localize`Edit`;
+ this.UPDATE = $localize`Update`;
+ this.CANCEL = $localize`Cancel`;
+ this.PREVIEW = $localize`Preview`;
+ this.MOVE = $localize`Move`;
+
+ /* Wizard wording */
+ this.NEXT = $localize`Next`;
+ this.BACK = $localize`Back`;
+
+ /* Non-standard actions */
+ this.CLONE = $localize`Clone`;
+ this.COPY = $localize`Copy`;
+ this.DEEP_SCRUB = $localize`Deep Scrub`;
+ this.DESTROY = $localize`Destroy`;
+ this.EVICT = $localize`Evict`;
+ this.FLATTEN = $localize`Flatten`;
+ this.MARK_DOWN = $localize`Mark Down`;
+ this.MARK_IN = $localize`Mark In`;
+ this.MARK_LOST = $localize`Mark Lost`;
+ this.MARK_OUT = $localize`Mark Out`;
+ this.PROTECT = $localize`Protect`;
+ this.PURGE = $localize`Purge`;
+ this.RENAME = $localize`Rename`;
+ this.RESTORE = $localize`Restore`;
+ this.REWEIGHT = $localize`Reweight`;
+ this.ROLLBACK = $localize`Rollback`;
+ this.SCRUB = $localize`Scrub`;
+ this.SHOW = $localize`Show`;
+ this.TRASH = $localize`Move to Trash`;
+ this.UNPROTECT = $localize`Unprotect`;
+ this.CHANGE = $localize`Change`;
+ this.FLAGS = $localize`Flags`;
+ this.ENTER_MAINTENANCE = $localize`Enter Maintenance`;
+ this.EXIT_MAINTENANCE = $localize`Exit Maintenance`;
+
+ this.START_DRAIN = $localize`Start Drain`;
+ this.STOP_DRAIN = $localize`Stop Drain`;
+ this.RESYNC = $localize`Resync`;
+ /* Prometheus wording */
+ this.RECREATE = $localize`Recreate`;
+ this.EXPIRE = $localize`Expire`;
+
+ this.START = $localize`Start`;
+ this.STOP = $localize`Stop`;
+ this.REDEPLOY = $localize`Redeploy`;
+ this.RESTART = $localize`Restart`;
+
+ this.REMOVE_SCHEDULING = $localize`Remove Scheduling`;
+ this.PROMOTE = $localize`Promote`;
+ this.DEMOTE = $localize`Demote`;
+ }
+}
+
+@Injectable({
+ providedIn: 'root'
+})
+export class SucceededActionLabelsI18n {
+ /* This service is required as the i18n polyfill does not provide static
+ translation
+ */
+ CREATED: string;
+ DELETED: string;
+ ADDED: string;
+ REMOVED: string;
+ EDITED: string;
+ CANCELED: string;
+ PREVIEWED: string;
+ MOVED: string;
+ COPIED: string;
+ CLONED: string;
+ DEEP_SCRUBBED: string;
+ DESTROYED: string;
+ FLATTENED: string;
+ MARKED_DOWN: string;
+ MARKED_IN: string;
+ MARKED_LOST: string;
+ MARKED_OUT: string;
+ PROTECTED: string;
+ PURGED: string;
+ RENAMED: string;
+ RESTORED: string;
+ REWEIGHTED: string;
+ ROLLED_BACK: string;
+ SCRUBBED: string;
+ SHOWED: string;
+ TRASHED: string;
+ UNPROTECTED: string;
+ CHANGE: string;
+ RECREATED: string;
+ EXPIRED: string;
+ MOVE: string;
+ START: string;
+ STOP: string;
+ REDEPLOY: string;
+ RESTART: string;
+
+ constructor() {
+ /* Create a new item */
+ this.CREATED = $localize`Created`;
+
+ /* Destroy an existing item */
+ this.DELETED = $localize`Deleted`;
+
+ /* Add an existing item to a container */
+ this.ADDED = $localize`Added`;
+
+ /* Remove an item from a container WITHOUT deleting it */
+ this.REMOVED = $localize`Removed`;
+
+ /* Make changes to an existing item */
+ this.EDITED = $localize`Edited`;
+ this.CANCELED = $localize`Canceled`;
+ this.PREVIEWED = $localize`Previewed`;
+ this.MOVED = $localize`Moved`;
+
+ /* Non-standard actions */
+ this.CLONED = $localize`Cloned`;
+ this.COPIED = $localize`Copied`;
+ this.DEEP_SCRUBBED = $localize`Deep Scrubbed`;
+ this.DESTROYED = $localize`Destroyed`;
+ this.FLATTENED = $localize`Flattened`;
+ this.MARKED_DOWN = $localize`Marked Down`;
+ this.MARKED_IN = $localize`Marked In`;
+ this.MARKED_LOST = $localize`Marked Lost`;
+ this.MARKED_OUT = $localize`Marked Out`;
+ this.PROTECTED = $localize`Protected`;
+ this.PURGED = $localize`Purged`;
+ this.RENAMED = $localize`Renamed`;
+ this.RESTORED = $localize`Restored`;
+ this.REWEIGHTED = $localize`Reweighted`;
+ this.ROLLED_BACK = $localize`Rolled back`;
+ this.SCRUBBED = $localize`Scrubbed`;
+ this.SHOWED = $localize`Showed`;
+ this.TRASHED = $localize`Moved to Trash`;
+ this.UNPROTECTED = $localize`Unprotected`;
+ this.CHANGE = $localize`Change`;
+
+ /* Prometheus wording */
+ this.RECREATED = $localize`Recreated`;
+ this.EXPIRED = $localize`Expired`;
+
+ this.START = $localize`Start`;
+ this.STOP = $localize`Stop`;
+ this.REDEPLOY = $localize`Redeploy`;
+ this.RESTART = $localize`Restart`;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/datatable.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/datatable.module.ts
new file mode 100644
index 000000000..ede8f2368
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/datatable.module.ts
@@ -0,0 +1,31 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+import { RouterModule } from '@angular/router';
+
+import { NgbDropdownModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgxDatatableModule } from '@swimlane/ngx-datatable';
+import { NgxPipeFunctionModule } from 'ngx-pipe-function';
+
+import { ComponentsModule } from '../components/components.module';
+import { PipesModule } from '../pipes/pipes.module';
+import { TableActionsComponent } from './table-actions/table-actions.component';
+import { TableKeyValueComponent } from './table-key-value/table-key-value.component';
+import { TableComponent } from './table/table.component';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ NgxDatatableModule,
+ NgxPipeFunctionModule,
+ FormsModule,
+ NgbDropdownModule,
+ NgbTooltipModule,
+ PipesModule,
+ ComponentsModule,
+ RouterModule
+ ],
+ declarations: [TableComponent, TableKeyValueComponent, TableActionsComponent],
+ exports: [TableComponent, NgxDatatableModule, TableKeyValueComponent, TableActionsComponent]
+})
+export class DataTableModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.html
new file mode 100644
index 000000000..905aaa96b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.html
@@ -0,0 +1,43 @@
+<div class="btn-group">
+ <ng-container *ngIf="currentAction">
+ <button type="button"
+ title="{{ useDisableDesc(currentAction) }}"
+ class="btn btn-{{btnColor}}"
+ [ngClass]="{'disabled': disableSelectionAction(currentAction)}"
+ (click)="useClickAction(currentAction)"
+ [routerLink]="useRouterLink(currentAction)"
+ [attr.aria-label]="currentAction.name"
+ [preserveFragment]="currentAction.preserveFragment ? '' : null">
+ <i [ngClass]="[currentAction.icon]"></i>
+ <span>{{ currentAction.name }}</span>
+ </button>
+ </ng-container>
+ <div class="btn-group"
+ ngbDropdown
+ role="group"
+ *ngIf="dropDownActions.length > 1"
+ aria-label="Button group with nested dropdown">
+ <button class="btn btn-{{btnColor}} dropdown-toggle-split"
+ ngbDropdownToggle>
+ <ng-container *ngIf="dropDownOnly">{{ dropDownOnly }} </ng-container>
+ <span *ngIf="!dropDownOnly"
+ class="sr-only"></span>
+ </button>
+ <div class="dropdown-menu"
+ ngbDropdownMenu>
+ <ng-container *ngFor="let action of dropDownActions">
+ <button ngbDropdownItem
+ class="{{ toClassName(action) }}"
+ title="{{ useDisableDesc(action) }}"
+ (click)="useClickAction(action)"
+ [routerLink]="useRouterLink(action)"
+ [preserveFragment]="action.preserveFragment ? '' : null"
+ [disabled]="disableSelectionAction(action)"
+ [attr.aria-label]="action.name">
+ <i [ngClass]="[action.icon, 'action-icon']"></i>
+ <span>{{ action.name }}</span>
+ </button>
+ </ng-container>
+ </div>
+ </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.scss
new file mode 100644
index 000000000..f996de727
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.scss
@@ -0,0 +1,8 @@
+button.disabled {
+ cursor: default !important;
+ pointer-events: auto;
+}
+
+.action-icon {
+ padding-right: 1.5rem;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.spec.ts
new file mode 100644
index 000000000..81cc1b972
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.spec.ts
@@ -0,0 +1,213 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgxPipeFunctionModule } from 'ngx-pipe-function';
+
+import { ComponentsModule } from '~/app/shared/components/components.module';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { Permission } from '~/app/shared/models/permissions';
+import { configureTestBed, PermissionHelper } from '~/testing/unit-test-helper';
+import { TableActionsComponent } from './table-actions.component';
+
+describe('TableActionsComponent', () => {
+ let component: TableActionsComponent;
+ let fixture: ComponentFixture<TableActionsComponent>;
+ let addAction: CdTableAction;
+ let editAction: CdTableAction;
+ let protectAction: CdTableAction;
+ let unprotectAction: CdTableAction;
+ let deleteAction: CdTableAction;
+ let copyAction: CdTableAction;
+ let permissionHelper: PermissionHelper;
+
+ configureTestBed({
+ declarations: [TableActionsComponent],
+ imports: [ComponentsModule, NgxPipeFunctionModule, RouterTestingModule]
+ });
+
+ beforeEach(() => {
+ addAction = {
+ permission: 'create',
+ icon: 'fa-plus',
+ canBePrimary: (selection: CdTableSelection) => !selection.hasSelection,
+ name: 'Add'
+ };
+ editAction = {
+ permission: 'update',
+ icon: 'fa-pencil',
+ name: 'Edit'
+ };
+ copyAction = {
+ permission: 'create',
+ icon: 'fa-copy',
+ canBePrimary: (selection: CdTableSelection) => selection.hasSingleSelection,
+ disable: (selection: CdTableSelection) =>
+ !selection.hasSingleSelection || selection.first().cdExecuting,
+ name: 'Copy'
+ };
+ deleteAction = {
+ permission: 'delete',
+ icon: 'fa-times',
+ canBePrimary: (selection: CdTableSelection) => selection.hasSelection,
+ disable: (selection: CdTableSelection) =>
+ !selection.hasSelection || selection.first().cdExecuting,
+ name: 'Delete'
+ };
+ protectAction = {
+ permission: 'update',
+ icon: 'fa-lock',
+ canBePrimary: () => false,
+ visible: (selection: CdTableSelection) => selection.hasSingleSelection,
+ name: 'Protect'
+ };
+ unprotectAction = {
+ permission: 'update',
+ icon: 'fa-unlock',
+ canBePrimary: () => false,
+ visible: (selection: CdTableSelection) => !selection.hasSingleSelection,
+ name: 'Unprotect'
+ };
+ fixture = TestBed.createComponent(TableActionsComponent);
+ component = fixture.componentInstance;
+ component.selection = new CdTableSelection();
+ component.permission = new Permission();
+ component.permission.read = true;
+ component.tableActions = [
+ addAction,
+ editAction,
+ protectAction,
+ unprotectAction,
+ copyAction,
+ deleteAction
+ ];
+ permissionHelper = new PermissionHelper(component.permission);
+ permissionHelper.setPermissionsAndGetActions(component.tableActions);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call ngInit without permissions', () => {
+ component.permission = undefined;
+ component.ngOnInit();
+ expect(component.tableActions).toEqual([]);
+ expect(component.dropDownActions).toEqual([]);
+ });
+
+ describe('useRouterLink', () => {
+ const testLink = '/api/some/link';
+ it('should use a link generated from a function', () => {
+ addAction.routerLink = () => testLink;
+ expect(component.useRouterLink(addAction)).toBe(testLink);
+ });
+
+ it('should use the link as it is because it is a string', () => {
+ addAction.routerLink = testLink;
+ expect(component.useRouterLink(addAction)).toBe(testLink);
+ });
+
+ it('should not return anything because no link is defined', () => {
+ expect(component.useRouterLink(addAction)).toBe(undefined);
+ });
+
+ it('should not return anything because the action is disabled', () => {
+ editAction.routerLink = testLink;
+ expect(component.useRouterLink(editAction)).toBe(undefined);
+ });
+ });
+
+ it('should test all TableActions combinations', () => {
+ const tableActions: TableActionsComponent = permissionHelper.setPermissionsAndGetActions(
+ component.tableActions
+ );
+ expect(tableActions).toEqual({
+ 'create,update,delete': {
+ actions: ['Add', 'Edit', 'Protect', 'Unprotect', 'Copy', 'Delete'],
+ primary: { multiple: 'Delete', executing: 'Edit', single: 'Edit', no: 'Add' }
+ },
+ 'create,update': {
+ actions: ['Add', 'Edit', 'Protect', 'Unprotect', 'Copy'],
+ primary: { multiple: 'Add', executing: 'Edit', single: 'Edit', no: 'Add' }
+ },
+ 'create,delete': {
+ actions: ['Add', 'Copy', 'Delete'],
+ primary: { multiple: 'Delete', executing: 'Copy', single: 'Copy', no: 'Add' }
+ },
+ create: {
+ actions: ['Add', 'Copy'],
+ primary: { multiple: 'Add', executing: 'Copy', single: 'Copy', no: 'Add' }
+ },
+ 'update,delete': {
+ actions: ['Edit', 'Protect', 'Unprotect', 'Delete'],
+ primary: { multiple: 'Delete', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ update: {
+ actions: ['Edit', 'Protect', 'Unprotect'],
+ primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
+ },
+ delete: {
+ actions: ['Delete'],
+ primary: { multiple: 'Delete', executing: 'Delete', single: 'Delete', no: 'Delete' }
+ },
+ 'no-permissions': {
+ actions: [],
+ primary: { multiple: '', executing: '', single: '', no: '' }
+ }
+ });
+ });
+
+ it('should convert any name to a proper CSS class', () => {
+ expect(component.toClassName({ name: 'Create' } as CdTableAction)).toBe('create');
+ expect(component.toClassName({ name: 'Mark x down' } as CdTableAction)).toBe('mark-x-down');
+ expect(component.toClassName({ name: '?Su*per!' } as CdTableAction)).toBe('super');
+ });
+
+ describe('useDisableDesc', () => {
+ it('should return a description if disable method returns a string', () => {
+ const deleteWithDescAction: CdTableAction = {
+ permission: 'delete',
+ icon: 'fa-times',
+ canBePrimary: (selection: CdTableSelection) => selection.hasSelection,
+ disable: () => {
+ return 'Delete action disabled description';
+ },
+ name: 'DeleteDesc'
+ };
+
+ expect(component.useDisableDesc(deleteWithDescAction)).toBe(
+ 'Delete action disabled description'
+ );
+ });
+
+ it('should return no description if disable does not return string', () => {
+ expect(component.useDisableDesc(deleteAction)).toBeUndefined();
+ });
+ });
+
+ describe('useClickAction', () => {
+ const editClickAction: CdTableAction = {
+ permission: 'update',
+ icon: 'fa-pencil',
+ name: 'Edit',
+ click: () => {
+ return 'Edit action click';
+ }
+ };
+
+ it('should call click action if action is not disabled', () => {
+ editClickAction.disable = () => {
+ return false;
+ };
+ expect(component.useClickAction(editClickAction)).toBe('Edit action click');
+ });
+
+ it('should not call click action if action is disabled', () => {
+ editClickAction.disable = () => {
+ return true;
+ };
+ expect(component.useClickAction(editClickAction)).toBeFalsy();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.ts
new file mode 100644
index 000000000..0497f9301
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.ts
@@ -0,0 +1,161 @@
+import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
+
+import _ from 'lodash';
+
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { Permission } from '~/app/shared/models/permissions';
+
+@Component({
+ selector: 'cd-table-actions',
+ templateUrl: './table-actions.component.html',
+ styleUrls: ['./table-actions.component.scss']
+})
+export class TableActionsComponent implements OnChanges, OnInit {
+ @Input()
+ permission: Permission;
+ @Input()
+ selection: CdTableSelection;
+ @Input()
+ tableActions: CdTableAction[];
+ @Input()
+ btnColor = 'accent';
+
+ // Use this if you just want to display a drop down button,
+ // labeled with the given text, with all actions in it.
+ // This disables the main action button.
+ @Input()
+ dropDownOnly?: string;
+
+ currentAction?: CdTableAction;
+ // Array with all visible actions
+ dropDownActions: CdTableAction[] = [];
+
+ icons = Icons;
+
+ ngOnInit() {
+ this.removeActionsWithNoPermissions();
+ this.onSelectionChange();
+ }
+
+ ngOnChanges(changes: SimpleChanges) {
+ if (changes.selection) {
+ this.onSelectionChange();
+ }
+ }
+
+ onSelectionChange(): void {
+ this.updateDropDownActions();
+ this.updateCurrentAction();
+ }
+
+ toClassName(action: CdTableAction): string {
+ return action.name
+ .replace(/ /g, '-')
+ .replace(/[^a-z-]/gi, '')
+ .toLowerCase();
+ }
+
+ /**
+ * Removes all actions from 'tableActions' that need a permission the user doesn't have.
+ */
+ private removeActionsWithNoPermissions() {
+ if (!this.permission) {
+ this.tableActions = [];
+ return;
+ }
+ const permissions = Object.keys(this.permission).filter((key) => this.permission[key]);
+ this.tableActions = this.tableActions.filter((action) =>
+ permissions.includes(action.permission)
+ );
+ }
+
+ private updateDropDownActions(): void {
+ this.dropDownActions = this.tableActions.filter((action) =>
+ action.visible ? action.visible(this.selection) : action
+ );
+ }
+
+ /**
+ * Finds the next action that is used as main action for the button
+ *
+ * The order of the list is crucial to get the right main action.
+ *
+ * Default button conditions of actions:
+ * - 'create' actions can be used with no or multiple selections
+ * - 'update' and 'delete' actions can be used with one selection
+ */
+ private updateCurrentAction(): void {
+ if (this.dropDownOnly) {
+ this.currentAction = undefined;
+ return;
+ }
+ let buttonAction = this.dropDownActions.find((tableAction) => this.showableAction(tableAction));
+ if (!buttonAction && this.dropDownActions.length > 0) {
+ buttonAction = this.dropDownActions[0];
+ }
+ this.currentAction = buttonAction;
+ }
+
+ /**
+ * Determines if action can be used for the button
+ *
+ * @param {CdTableAction} action
+ * @returns {boolean}
+ */
+ private showableAction(action: CdTableAction): boolean {
+ const condition = action.canBePrimary;
+ const singleSelection = this.selection.hasSingleSelection;
+ const defaultCase = action.permission === 'create' ? !singleSelection : singleSelection;
+ return (condition && condition(this.selection)) || (!condition && defaultCase);
+ }
+
+ useRouterLink(action: CdTableAction): string {
+ if (!action.routerLink || this.disableSelectionAction(action)) {
+ return undefined;
+ }
+ return _.isString(action.routerLink) ? action.routerLink : action.routerLink();
+ }
+
+ /**
+ * Determines if an action should be disabled
+ *
+ * Default disable conditions of 'update' and 'delete' actions:
+ * - If no or multiple selections are made
+ * - If one selection is made, but a task is executed on that item
+ *
+ * @param {CdTableAction} action
+ * @returns {Boolean}
+ */
+ disableSelectionAction(action: CdTableAction): Boolean {
+ const disable = action.disable;
+ if (disable) {
+ return Boolean(disable(this.selection));
+ }
+ const permission = action.permission;
+ const selected = this.selection.hasSingleSelection && this.selection.first();
+ return Boolean(
+ ['update', 'delete'].includes(permission) && (!selected || selected.cdExecuting)
+ );
+ }
+
+ useClickAction(action: CdTableAction) {
+ /**
+ * In order to show tooltips for deactivated menu items, the class
+ * 'pointer-events: auto;' has been added to the .scss file which also
+ * re-activates the click-event.
+ * To prevent calling the click-event on deactivated elements we also have
+ * to check here if it's disabled.
+ */
+ return !this.disableSelectionAction(action) && action.click && action.click();
+ }
+
+ useDisableDesc(action: CdTableAction) {
+ if (action.disable) {
+ const result = action.disable(this.selection);
+ return _.isString(result) ? result : undefined;
+ }
+ return undefined;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.html
new file mode 100644
index 000000000..2e2dda4e9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.html
@@ -0,0 +1,12 @@
+<cd-table #table
+ [data]="tableData"
+ [columns]="columns"
+ columnMode="flex"
+ [toolHeader]="false"
+ [autoReload]="autoReload"
+ [customCss]="customCss"
+ [autoSave]="false"
+ [header]="false"
+ [footer]="false"
+ [limit]="0">
+</cd-table>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.scss
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.spec.ts
new file mode 100644
index 000000000..150d44241
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.spec.ts
@@ -0,0 +1,351 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbDropdownModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgxDatatableModule } from '@swimlane/ngx-datatable';
+import { NgxPipeFunctionModule } from 'ngx-pipe-function';
+
+import { ComponentsModule } from '~/app/shared/components/components.module';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdDatePipe } from '~/app/shared/pipes/cd-date.pipe';
+import { PipesModule } from '~/app/shared/pipes/pipes.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { TableComponent } from '../table/table.component';
+import { TableKeyValueComponent } from './table-key-value.component';
+
+describe('TableKeyValueComponent', () => {
+ let component: TableKeyValueComponent;
+ let fixture: ComponentFixture<TableKeyValueComponent>;
+
+ configureTestBed({
+ declarations: [TableComponent, TableKeyValueComponent],
+ imports: [
+ FormsModule,
+ NgxDatatableModule,
+ ComponentsModule,
+ RouterTestingModule,
+ NgbDropdownModule,
+ PipesModule,
+ NgbTooltipModule,
+ NgxPipeFunctionModule
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TableKeyValueComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+
+ it('should make key value object pairs out of arrays with length two', () => {
+ component.data = [
+ ['someKey', 0],
+ ['arrayKey', [1, 2, 3]],
+ [3, 'something']
+ ];
+ component.ngOnInit();
+ const expected: any = [
+ { key: 'arrayKey', value: '1, 2, 3' },
+ { key: 'someKey', value: 0 },
+ { key: 3, value: 'something' }
+ ];
+ expect(component.tableData).toEqual(expected);
+ });
+
+ it('should not show data supposed to be have hidden by key', () => {
+ component.data = [
+ ['a', 1],
+ ['b', 2]
+ ];
+ component.hideKeys = ['a'];
+ component.ngOnInit();
+ expect(component.tableData).toEqual([{ key: 'b', value: 2 }]);
+ });
+
+ it('should remove items with objects as values', () => {
+ component.data = [
+ [3, 'something'],
+ ['will be removed', { a: 3, b: 4, c: 5 }]
+ ];
+ component.ngOnInit();
+ expect(component.tableData).toEqual(<any>[{ key: 3, value: 'something' }]);
+ });
+
+ it('makes key value object pairs out of an object', () => {
+ component.data = { 3: 'something', someKey: 0 };
+ component.ngOnInit();
+ expect(component.tableData).toEqual([
+ { key: '3', value: 'something' },
+ { key: 'someKey', value: 0 }
+ ]);
+ });
+
+ it('does nothing if data does not need to be converted', () => {
+ component.data = [
+ { key: 3, value: 'something' },
+ { key: 'someKey', value: 0 }
+ ];
+ component.ngOnInit();
+ expect(component.tableData).toEqual(component.data);
+ });
+
+ it('throws errors if data cannot be converted', () => {
+ component.data = 38;
+ expect(() => component.ngOnInit()).toThrowError('Wrong data format');
+ component.data = [['someKey', 0, 3]];
+ expect(() => component.ngOnInit()).toThrowError(
+ 'Array contains too many elements (3). Needs to be of type [string, any][]'
+ );
+ });
+
+ it('tests makePairs()', () => {
+ const makePairs = (data: any) => component['makePairs'](data);
+ expect(makePairs([['dash', 'board']])).toEqual([{ key: 'dash', value: 'board' }]);
+ const pair = [
+ { key: 'dash', value: 'board' },
+ { key: 'ceph', value: 'mimic' }
+ ];
+ const pairInverse = [
+ { key: 'ceph', value: 'mimic' },
+ { key: 'dash', value: 'board' }
+ ];
+ expect(makePairs(pair)).toEqual(pairInverse);
+ expect(makePairs({ dash: 'board' })).toEqual([{ key: 'dash', value: 'board' }]);
+ expect(makePairs({ dash: 'board', ceph: 'mimic' })).toEqual(pairInverse);
+ });
+
+ it('tests makePairsFromArray()', () => {
+ const makePairsFromArray = (data: any[]) => component['makePairsFromArray'](data);
+ expect(makePairsFromArray([['dash', 'board']])).toEqual([{ key: 'dash', value: 'board' }]);
+ const pair = [
+ { key: 'dash', value: 'board' },
+ { key: 'ceph', value: 'mimic' }
+ ];
+ expect(makePairsFromArray(pair)).toEqual(pair);
+ });
+
+ it('tests makePairsFromObject()', () => {
+ const makePairsFromObject = (data: object) => component['makePairsFromObject'](data);
+ expect(makePairsFromObject({ dash: 'board' })).toEqual([{ key: 'dash', value: 'board' }]);
+ expect(makePairsFromObject({ dash: 'board', ceph: 'mimic' })).toEqual([
+ { key: 'dash', value: 'board' },
+ { key: 'ceph', value: 'mimic' }
+ ]);
+ });
+
+ describe('tests convertValue()', () => {
+ const convertValue = (data: any) => component['convertValue'](data);
+ const expectConvertValue = (value: any, expectation: any) =>
+ expect(convertValue(value)).toBe(expectation);
+
+ it('should not convert strings', () => {
+ expectConvertValue('something', 'something');
+ });
+
+ it('should not convert integers', () => {
+ expectConvertValue(29, 29);
+ });
+
+ it('should convert arrays with any type to strings', () => {
+ expectConvertValue([1, 2, 3], '1, 2, 3');
+ expectConvertValue([{ sth: 'something' }], '{"sth":"something"}');
+ expectConvertValue([1, 'two', { 3: 'three' }], '1, two, {"3":"three"}');
+ });
+
+ it('should only convert objects if renderObjects is set to true', () => {
+ expect(convertValue({ sth: 'something' })).toBe(null);
+ component.renderObjects = true;
+ expect(convertValue({ sth: 'something' })).toEqual({ sth: 'something' });
+ });
+ });
+
+ describe('automatically pipe UTC dates through cdDate', () => {
+ let datePipe: CdDatePipe;
+
+ beforeEach(() => {
+ datePipe = TestBed.inject(CdDatePipe);
+ spyOn(datePipe, 'transform').and.callThrough();
+ });
+
+ const expectTimeConversion = (date: string) => {
+ component.data = { dateKey: date };
+ component.ngOnInit();
+ expect(datePipe.transform).toHaveBeenCalledWith(date);
+ expect(component.tableData[0].key).not.toBe(date);
+ };
+
+ it('converts some date', () => {
+ expectTimeConversion('2019-04-15 12:26:52.305285');
+ });
+
+ it('converts UTC date', () => {
+ expectTimeConversion('2019-04-16T12:35:46.646300974Z');
+ });
+ });
+
+ describe('render objects', () => {
+ beforeEach(() => {
+ component.data = {
+ options: {
+ numberKey: 38,
+ stringKey: 'somethingElse',
+ objectKey: {
+ sub1: 12,
+ sub2: 34,
+ sub3: 56
+ }
+ },
+ otherOptions: {
+ sub1: {
+ x: 42
+ },
+ sub2: {
+ y: 555
+ }
+ },
+ additionalKeyContainingObject: { type: 'none' },
+ keyWithEmptyObject: {}
+ };
+ component.renderObjects = true;
+ });
+
+ it('with parent key', () => {
+ component.ngOnInit();
+ expect(component.tableData).toEqual([
+ { key: 'additionalKeyContainingObject type', value: 'none' },
+ { key: 'keyWithEmptyObject', value: '' },
+ { key: 'options numberKey', value: 38 },
+ { key: 'options objectKey sub1', value: 12 },
+ { key: 'options objectKey sub2', value: 34 },
+ { key: 'options objectKey sub3', value: 56 },
+ { key: 'options stringKey', value: 'somethingElse' },
+ { key: 'otherOptions sub1 x', value: 42 },
+ { key: 'otherOptions sub2 y', value: 555 }
+ ]);
+ });
+
+ it('without parent key', () => {
+ component.appendParentKey = false;
+ component.ngOnInit();
+ expect(component.tableData).toEqual([
+ { key: 'keyWithEmptyObject', value: '' },
+ { key: 'numberKey', value: 38 },
+ { key: 'stringKey', value: 'somethingElse' },
+ { key: 'sub1', value: 12 },
+ { key: 'sub2', value: 34 },
+ { key: 'sub3', value: 56 },
+ { key: 'type', value: 'none' },
+ { key: 'x', value: 42 },
+ { key: 'y', value: 555 }
+ ]);
+ });
+ });
+
+ describe('subscribe fetchData', () => {
+ it('should not subscribe fetchData of table', () => {
+ component.ngOnInit();
+ expect(component.table.fetchData.observers.length).toBe(0);
+ });
+
+ it('should call fetchData', () => {
+ let called = false;
+ component.fetchData.subscribe(() => {
+ called = true;
+ });
+ component.ngOnInit();
+ expect(component.table.fetchData.observers.length).toBe(1);
+ component.table.fetchData.emit();
+ expect(called).toBeTruthy();
+ });
+ });
+
+ describe('hide empty items', () => {
+ beforeEach(() => {
+ component.data = {
+ booleanFalse: false,
+ booleanTrue: true,
+ string: '',
+ array: [],
+ object: {},
+ emptyObject: {
+ string: '',
+ array: [],
+ object: {}
+ },
+ someNumber: 0,
+ someDifferentNumber: 1,
+ someArray: [0, 1],
+ someString: '0',
+ someObject: {
+ empty: {},
+ something: 0.1
+ }
+ };
+ component.renderObjects = true;
+ });
+
+ it('should show all items as default', () => {
+ expect(component.hideEmpty).toBe(false);
+ component.ngOnInit();
+ expect(component.tableData).toEqual([
+ { key: 'array', value: '' },
+ { key: 'booleanFalse', value: false },
+ { key: 'booleanTrue', value: true },
+ { key: 'emptyObject array', value: '' },
+ { key: 'emptyObject object', value: '' },
+ { key: 'emptyObject string', value: '' },
+ { key: 'object', value: '' },
+ { key: 'someArray', value: '0, 1' },
+ { key: 'someDifferentNumber', value: 1 },
+ { key: 'someNumber', value: 0 },
+ { key: 'someObject empty', value: '' },
+ { key: 'someObject something', value: 0.1 },
+ { key: 'someString', value: '0' },
+ { key: 'string', value: '' }
+ ]);
+ });
+
+ it('should hide all empty items', () => {
+ component.hideEmpty = true;
+ component.ngOnInit();
+ expect(component.tableData).toEqual([
+ { key: 'booleanFalse', value: false },
+ { key: 'booleanTrue', value: true },
+ { key: 'someArray', value: '0, 1' },
+ { key: 'someDifferentNumber', value: 1 },
+ { key: 'someNumber', value: 0 },
+ { key: 'someObject something', value: 0.1 },
+ { key: 'someString', value: '0' }
+ ]);
+ });
+ });
+
+ describe('columns set up', () => {
+ let columns: CdTableColumn[];
+
+ beforeEach(() => {
+ columns = [
+ { prop: 'key', flexGrow: 1, cellTransformation: CellTemplate.bold },
+ { prop: 'value', flexGrow: 3 }
+ ];
+ });
+
+ it('should have the following default column set up', () => {
+ component.ngOnInit();
+ expect(component.columns).toEqual(columns);
+ });
+
+ it('should have the following column set up if customCss is defined', () => {
+ component.customCss = { 'class-name': 42 };
+ component.ngOnInit();
+ columns[1].cellTransformation = CellTemplate.classAdding;
+ expect(component.columns).toEqual(columns);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.ts
new file mode 100644
index 000000000..0f450ce2a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.ts
@@ -0,0 +1,224 @@
+import {
+ Component,
+ EventEmitter,
+ Input,
+ OnChanges,
+ OnInit,
+ Output,
+ ViewChild
+} from '@angular/core';
+
+import _ from 'lodash';
+
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdDatePipe } from '~/app/shared/pipes/cd-date.pipe';
+import { TableComponent } from '../table/table.component';
+
+interface KeyValueItem {
+ key: string;
+ value: any;
+}
+
+/**
+ * Display the given data in a 2 column data table. The left column
+ * shows the 'key' attribute, the right column the 'value' attribute.
+ * The data table has the following characteristics:
+ * - No header and footer is displayed
+ * - The relation of the width for the columns 'key' and 'value' is 1:3
+ * - The 'key' column is displayed in bold text
+ */
+@Component({
+ selector: 'cd-table-key-value',
+ templateUrl: './table-key-value.component.html',
+ styleUrls: ['./table-key-value.component.scss']
+})
+export class TableKeyValueComponent implements OnInit, OnChanges {
+ @ViewChild(TableComponent, { static: true })
+ table: TableComponent;
+
+ @Input()
+ data: any;
+ @Input()
+ autoReload: any = 5000;
+ @Input()
+ renderObjects = false;
+ // Only used if objects are rendered
+ @Input()
+ appendParentKey = true;
+ @Input()
+ hideEmpty = false;
+ @Input()
+ hideKeys: string[] = []; // Keys of pairs not to be displayed
+
+ // If set, the classAddingTpl is used to enable different css for different values
+ @Input()
+ customCss?: { [css: string]: number | string | ((any: any) => boolean) };
+
+ columns: Array<CdTableColumn> = [];
+ tableData: KeyValueItem[];
+
+ /**
+ * The function that will be called to update the input data.
+ */
+ @Output()
+ fetchData = new EventEmitter();
+
+ constructor(private datePipe: CdDatePipe) {}
+
+ ngOnInit() {
+ this.columns = [
+ {
+ prop: 'key',
+ flexGrow: 1,
+ cellTransformation: CellTemplate.bold
+ },
+ {
+ prop: 'value',
+ flexGrow: 3
+ }
+ ];
+ if (this.customCss) {
+ this.columns[1].cellTransformation = CellTemplate.classAdding;
+ }
+ // We need to subscribe the 'fetchData' event here and not in the
+ // HTML template, otherwise the data table will display the loading
+ // indicator infinitely if data is only bound via '[data]="xyz"'.
+ // See for 'loadingIndicator' in 'TableComponent::ngOnInit()'.
+ if (this.fetchData.observers.length > 0) {
+ this.table.fetchData.subscribe(() => {
+ // Forward event triggered by the 'cd-table' data table.
+ this.fetchData.emit();
+ });
+ }
+ this.useData();
+ }
+
+ ngOnChanges() {
+ this.useData();
+ }
+
+ useData() {
+ if (!this.data) {
+ return; // Wait for data
+ }
+ let pairs = this.makePairs(this.data);
+ if (this.hideKeys) {
+ pairs = pairs.filter((pair) => !this.hideKeys.includes(pair.key));
+ }
+ this.tableData = pairs;
+ }
+
+ private makePairs(data: any): KeyValueItem[] {
+ let result: KeyValueItem[] = [];
+ if (!data) {
+ return undefined; // Wait for data
+ } else if (_.isArray(data)) {
+ result = this.makePairsFromArray(data);
+ } else if (_.isObject(data)) {
+ result = this.makePairsFromObject(data);
+ } else {
+ throw new Error('Wrong data format');
+ }
+ result = result
+ .map((item) => {
+ item.value = this.convertValue(item.value);
+ return item;
+ })
+ .filter((i) => i.value !== null);
+ return _.sortBy(this.renderObjects ? this.insertFlattenObjects(result) : result, 'key');
+ }
+
+ private makePairsFromArray(data: any[]): KeyValueItem[] {
+ let temp: any[] = [];
+ const first = data[0];
+ if (_.isArray(first)) {
+ if (first.length === 2) {
+ temp = data.map((a) => ({
+ key: a[0],
+ value: a[1]
+ }));
+ } else {
+ throw new Error(
+ `Array contains too many elements (${first.length}). ` +
+ `Needs to be of type [string, any][]`
+ );
+ }
+ } else if (_.isObject(first)) {
+ if (_.has(first, 'key') && _.has(first, 'value')) {
+ temp = [...data];
+ } else {
+ temp = data.reduce(
+ (previous: any[], item) => previous.concat(this.makePairsFromObject(item)),
+ temp
+ );
+ }
+ }
+ return temp;
+ }
+
+ private makePairsFromObject(data: any): KeyValueItem[] {
+ return Object.keys(data).map((k) => ({
+ key: k,
+ value: data[k]
+ }));
+ }
+
+ private insertFlattenObjects(data: KeyValueItem[]): any[] {
+ return _.flattenDeep(
+ data.map((item) => {
+ const value = item.value;
+ const isObject = _.isObject(value);
+ if (!isObject || _.isEmpty(value)) {
+ if (isObject) {
+ item.value = '';
+ }
+ return item;
+ }
+ return this.splitItemIntoItems(item);
+ })
+ );
+ }
+
+ /**
+ * Split item into items will call _makePairs inside _makePairs (recursion), in oder to split
+ * the object item up into items as planned.
+ */
+ private splitItemIntoItems(data: { key: string; value: object }): KeyValueItem[] {
+ return this.makePairs(data.value).map((item) => {
+ if (this.appendParentKey) {
+ item.key = data.key + ' ' + item.key;
+ }
+ return item;
+ });
+ }
+
+ private convertValue(value: any): KeyValueItem {
+ if (_.isArray(value)) {
+ if (_.isEmpty(value) && this.hideEmpty) {
+ return null;
+ }
+ value = value.map((item) => (_.isObject(item) ? JSON.stringify(item) : item)).join(', ');
+ } else if (_.isObject(value)) {
+ if ((this.hideEmpty && _.isEmpty(value)) || !this.renderObjects) {
+ return null;
+ }
+ } else if (_.isString(value)) {
+ if (value === '' && this.hideEmpty) {
+ return null;
+ }
+ if (this.isDate(value)) {
+ value = this.datePipe.transform(value) || value;
+ }
+ }
+
+ return value;
+ }
+
+ private isDate(s: string) {
+ const sep = '[ -:.TZ]';
+ const n = '\\d{2}' + sep;
+ // year - m - d - h : m : s . someRest Z (if UTC)
+ return s.match(new RegExp('^\\d{4}' + sep + n + n + n + n + n + '\\d*' + 'Z?$'));
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html
new file mode 100644
index 000000000..6212c95c8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html
@@ -0,0 +1,327 @@
+<div class="dataTables_wrapper">
+
+ <div *ngIf="onlyActionHeader"
+ class="dataTables_header clearfix">
+ <div class="cd-datatable-actions">
+ <ng-content select=".only-table-actions"></ng-content>
+ </div>
+ </div>
+ <div class="dataTables_header clearfix"
+ *ngIf="toolHeader">
+ <!-- actions -->
+ <div class="cd-datatable-actions">
+ <ng-content select=".table-actions"></ng-content>
+ </div>
+ <!-- end actions -->
+
+ <!-- column filters -->
+ <div *ngIf="columnFilters.length !== 0"
+ class="btn-group widget-toolbar">
+ <div ngbDropdown
+ placement="bottom-right"
+ class="tc_filter_name">
+ <button ngbDropdownToggle
+ class="btn btn-light">
+ <i [ngClass]="[icons.large, icons.filter]"></i>
+ {{ selectedFilter.column.name }}
+ </button>
+ <div ngbDropdownMenu>
+ <ng-container *ngFor="let filter of columnFilters">
+ <button ngbDropdownItem
+ (click)="onSelectFilter(filter); false">{{ filter.column.name }}</button>
+ </ng-container>
+ </div>
+ </div>
+
+ <div ngbDropdown
+ placement="bottom-right"
+ class="tc_filter_option">
+ <button ngbDropdownToggle
+ class="btn btn-light"
+ [class.disabled]="selectedFilter.options.length === 0">
+ {{ selectedFilter.value ? selectedFilter.value.formatted: 'Any' }}
+ </button>
+ <div ngbDropdownMenu>
+ <ng-container *ngFor="let option of selectedFilter.options">
+ <button ngbDropdownItem
+ (click)="onChangeFilter(selectedFilter, option); false">
+ {{ option.formatted }}
+ <i *ngIf="selectedFilter.value !== undefined && (selectedFilter.value.raw === option.raw)"
+ [ngClass]="[icons.check]"></i>
+ </button>
+ </ng-container>
+ </div>
+ </div>
+ </div>
+ <!-- end column filters -->
+
+ <!-- search -->
+ <div class="input-group search"
+ *ngIf="searchField">
+ <span class="input-group-prepend">
+ <span class="input-group-text">
+ <i [ngClass]="[icons.search]"></i>
+ </span>
+ </span>
+ <input class="form-control"
+ type="text"
+ [(ngModel)]="search"
+ (keyup)="updateFilter()">
+ <div class="input-group-append">
+ <button type="button"
+ class="btn btn-light"
+ (click)="onClearSearch()">
+ <i class="icon-prepend {{ icons.destroy }}"></i>
+ </button>
+ </div>
+ </div>
+ <!-- end search -->
+
+ <!-- pagination limit -->
+ <div class="input-group dataTables_paginate"
+ *ngIf="limit">
+ <input class="form-control"
+ type="number"
+ min="1"
+ max="9999"
+ [value]="userConfig.limit"
+ (click)="setLimit($event)"
+ (keyup)="setLimit($event)"
+ (blur)="setLimit($event)">
+ </div>
+ <!-- end pagination limit-->
+
+ <!-- show hide columns -->
+ <div class="widget-toolbar">
+ <div ngbDropdown
+ autoClose="outside"
+ class="tc_menuitem">
+ <button ngbDropdownToggle
+ class="btn btn-light tc_columnBtn">
+ <i [ngClass]="[icons.large, icons.table]"></i>
+ </button>
+ <div ngbDropdownMenu>
+ <ng-container *ngFor="let column of columns">
+ <button ngbDropdownItem
+ *ngIf="column.name !== ''"
+ (click)="toggleColumn(column); false;">
+ <div class="custom-control custom-checkbox py-0">
+ <input class="custom-control-input"
+ type="checkbox"
+ [name]="column.prop"
+ [id]="column.prop"
+ [checked]="!column.isHidden">
+ <label class="custom-control-label"
+ [for]="column.prop">{{ column.name }}</label>
+ </div>
+ </button>
+ </ng-container>
+ </div>
+ </div>
+ </div>
+ <!-- end show hide columns -->
+
+ <!-- refresh button -->
+ <div class="widget-toolbar tc_refreshBtn"
+ *ngIf="fetchData.observers.length > 0">
+
+ <button type="button"
+ [class]="'btn btn-' + status.type"
+ [ngbTooltip]="status.msg"
+ (click)="refreshBtn()">
+ <i [ngClass]="[icons.large, icons.refresh]"
+ [class.fa-spin]="updating || loadingIndicator"></i>
+ </button>
+ </div>
+ <!-- end refresh button -->
+ </div>
+ <div class="dataTables_header clearfix"
+ *ngIf="toolHeader && columnFiltered">
+ <!-- filter chips for column filters -->
+ <div class="filter-chips">
+ <span *ngFor="let filter of columnFilters">
+ <span *ngIf="filter.value"
+ class="badge badge-info mr-2">
+ <span class="mr-2">{{ filter.column.name }}: {{ filter.value.formatted }}</span>
+ <a class="badge-remove"
+ (click)="onChangeFilter(filter); false">
+ <i [ngClass]="[icons.destroy]"
+ aria-hidden="true"></i>
+ </a>
+ </span>
+ </span>
+ <a class="tc_clearSelections"
+ href=""
+ (click)="onClearFilters(); false">
+ <ng-container i18n>Clear filters</ng-container>
+ </a>
+ </div>
+ <!-- end filter chips for column filters -->
+ </div>
+ <ngx-datatable #table
+ class="bootstrap cd-datatable"
+ [cssClasses]="paginationClasses"
+ [selectionType]="selectionType"
+ [selected]="selection.selected"
+ (select)="onSelect($event)"
+ [sorts]="userConfig.sorts"
+ (sort)="changeSorting($event)"
+ [columns]="tableColumns"
+ [columnMode]="columnMode"
+ [rows]="rows"
+ [rowClass]="getRowClass()"
+ [headerHeight]="header ? 'auto' : 0"
+ [footerHeight]="footer ? 'auto' : 0"
+ [count]="count"
+ [externalPaging]="serverSide"
+ [externalSorting]="serverSide"
+ [limit]="userConfig.limit > 0 ? userConfig.limit : undefined"
+ [offset]="userConfig.offset >= 0 ? userConfig.offset : 0"
+ (page)="changePage($event)"
+ [loadingIndicator]="loadingIndicator"
+ [rowIdentity]="rowIdentity()"
+ [rowHeight]="'auto'">
+
+ <!-- Row Detail Template -->
+ <ngx-datatable-row-detail rowHeight="auto"
+ #detailRow>
+ <ng-template let-row="row"
+ let-expanded="expanded"
+ ngx-datatable-row-detail-template>
+ <!-- Table Details -->
+ <ng-content select="[cdTableDetail]"></ng-content>
+ </ng-template>
+ </ngx-datatable-row-detail>
+
+ <ngx-datatable-footer>
+ <ng-template ngx-datatable-footer-template
+ let-rowCount="rowCount"
+ let-pageSize="pageSize"
+ let-selectedCount="selectedCount"
+ let-curPage="curPage"
+ let-offset="offset"
+ let-isVisible="isVisible">
+ <div class="page-count">
+ <span *ngIf="selectionType">
+ {{ selectedCount }} <ng-container i18n="X selected">selected</ng-container> /
+ </span>
+
+ <!-- rowCount might have different semantics with or without serverSide.
+ We treat serverSide (backend-driven tables) as a specific case.
+ -->
+ <span *ngIf="!serverSide else serverSideTpl">
+ <span *ngIf="rowCount != data?.length">
+ {{ rowCount }} <ng-container i18n="X found">found</ng-container> /
+ </span>
+ {{ data?.length || 0 }} <ng-container i18n="X total">total</ng-container>
+ </span>
+
+ <ng-template #serverSideTpl>
+ {{ data?.length || 0 }} <ng-container i18n="X found">found</ng-container> /
+ {{ rowCount }} <ng-container i18n="X total">total</ng-container>
+ </ng-template>
+ </div>
+ <datatable-pager [pagerLeftArrowIcon]="paginationClasses.pagerPrevious"
+ [pagerRightArrowIcon]="paginationClasses.pagerNext"
+ [pagerPreviousIcon]="paginationClasses.pagerLeftArrow"
+ [pagerNextIcon]="paginationClasses.pagerRightArrow"
+ [page]="curPage"
+ [size]="pageSize"
+ [count]="rowCount"
+ [hidden]="!((rowCount / pageSize) > 1)"
+ (change)="table.onFooterPage($event)">
+ </datatable-pager>
+ </ng-template>
+ </ngx-datatable-footer>
+ </ngx-datatable>
+</div>
+
+<!-- cell templates that can be accessed from outside -->
+<ng-template #tableCellBoldTpl
+ let-value="value">
+ <strong>{{ value }}</strong>
+</ng-template>
+
+<ng-template #sparklineTpl
+ let-row="row"
+ let-value="value">
+ <cd-sparkline [data]="value"
+ [isBinary]="row.cdIsBinary"></cd-sparkline>
+</ng-template>
+
+<ng-template #routerLinkTpl
+ let-row="row"
+ let-value="value">
+ <a [routerLink]="[row.cdLink]"
+ [queryParams]="row.cdParams">{{ value }}</a>
+</ng-template>
+
+<ng-template #checkIconTpl
+ let-value="value">
+ <i [ngClass]="[icons.check]"
+ [hidden]="!(value | boolean)"></i>
+</ng-template>
+
+<ng-template #perSecondTpl
+ let-row="row"
+ let-value="value">
+ {{ value | dimless }} /s
+</ng-template>
+
+<ng-template #executingTpl
+ let-column="column"
+ let-row="row"
+ let-value="value">
+ <i [ngClass]="[icons.spinner, icons.spin]"
+ *ngIf="row.cdExecuting"></i>
+ <span [ngClass]="column?.customTemplateConfig?.valueClass">
+ {{ value }}
+ </span>
+ <span *ngIf="row.cdExecuting"
+ [ngClass]="column?.customTemplateConfig?.executingClass ? column.customTemplateConfig.executingClass : 'text-muted italic'">({{ row.cdExecuting }})</span>
+</ng-template>
+
+<ng-template #classAddingTpl
+ let-value="value">
+ <span class="{{ value | pipeFunction:useCustomClass:this }}">{{ value }}</span>
+</ng-template>
+
+<ng-template #badgeTpl
+ let-column="column"
+ let-value="value">
+ <span *ngFor="let item of (value | array); last as last">
+ <span class="badge"
+ [ngClass]="(column?.customTemplateConfig?.map && column?.customTemplateConfig?.map[item]?.class) ? column.customTemplateConfig.map[item].class : (column?.customTemplateConfig?.class ? column.customTemplateConfig.class : 'badge-primary')"
+ *ngIf="(column?.customTemplateConfig?.map && column?.customTemplateConfig?.map[item]?.value) ? column.customTemplateConfig.map[item].value : column?.customTemplateConfig?.prefix ? column.customTemplateConfig.prefix + item : item">
+ {{ (column?.customTemplateConfig?.map && column?.customTemplateConfig?.map[item]?.value) ? column.customTemplateConfig.map[item].value : column?.customTemplateConfig?.prefix ? column.customTemplateConfig.prefix + item : item }}
+ </span>
+ <span *ngIf="!last">&nbsp;</span>
+ </span>
+</ng-template>
+
+<ng-template #mapTpl
+ let-column="column"
+ let-value="value">
+ <span>{{ value | map:column?.customTemplateConfig }}</span>
+</ng-template>
+
+<ng-template #truncateTpl
+ let-column="column"
+ let-value="value">
+ <span data-toggle="tooltip"
+ [title]="value">{{ value | truncate:column?.customTemplateConfig?.length:column?.customTemplateConfig?.omission }}</span>
+</ng-template>
+
+<ng-template #rowDetailsTpl
+ let-row="row"
+ let-isExpanded="expanded"
+ ngx-datatable-cell-template>
+ <a href="javascript:void(0)"
+ [class.expand-collapse-icon-right]="!isExpanded"
+ [class.expand-collapse-icon-down]="isExpanded"
+ class="expand-collapse-icon tc_expand-collapse"
+ title="Expand/Collapse Row"
+ i18n-title
+ (click)="toggleExpandRow(row, isExpanded, $event)">
+ </a>
+</ng-template>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.scss
new file mode 100644
index 000000000..57b8e48de
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.scss
@@ -0,0 +1,295 @@
+@use './src/styles/vendor/variables' as vv;
+@use './src/styles/defaults/mixins';
+
+@mixin row-details-icon {
+ color: vv.$gray-900;
+ font-family: 'ForkAwesome', sans-serif;
+ font-size: 1rem;
+ line-height: 1;
+}
+
+.dataTables_wrapper {
+ margin-bottom: 25px;
+ // after bootstrap 8.0 the details table started to
+ // have an issue where the columns keep expanding to
+ // infinity.
+ // https://github.com/ceph/ceph/pull/40618#pullrequestreview-629010639
+ // making the max-width to 99.9% solves the issue as a temporary fix
+ // until we get a conclusive fix, this needs to be kept.
+ max-width: 99.9%;
+
+ .separator {
+ border-left: 1px solid vv.$datatable-divider-color;
+ display: inline-block;
+ height: 30px;
+ margin-left: 5px;
+ padding-left: 5px;
+ vertical-align: middle;
+ }
+
+ .widget-toolbar {
+ border-left: 1px solid vv.$datatable-divider-color;
+ float: right;
+ padding: 0 8px;
+
+ .form-check {
+ padding-left: 0;
+ }
+ }
+
+ .dataTables_length > input {
+ line-height: 25px;
+ text-align: right;
+ }
+}
+
+.dataTables_header {
+ background-color: vv.$gray-100;
+ border: 1px solid vv.$gray-400;
+ border-bottom: 0;
+ padding: 5px;
+ position: relative;
+
+ .cd-datatable-actions {
+ float: left;
+ }
+
+ .form-group {
+ padding-left: 8px;
+ }
+
+ .input-group {
+ border-left: 1px solid vv.$datatable-divider-color;
+ float: right;
+ max-width: 250px;
+ padding-left: 8px;
+ padding-right: 8px;
+ width: 40%;
+
+ .form-control {
+ height: 30px;
+ }
+ }
+
+ .input-group.dataTables_paginate {
+ min-width: 85px;
+ padding-right: 8px;
+ width: 8%;
+ }
+
+ .filter-chips {
+ float: right;
+ padding: 0 8px;
+
+ .badge-remove {
+ color: vv.$white;
+ }
+ }
+}
+
+::ng-deep cd-table .cd-datatable {
+ border: 1px solid vv.$gray-400;
+ margin-bottom: 0;
+ max-width: none !important;
+
+ .progress-linear {
+ display: block;
+ height: 5px;
+ margin: 0;
+ padding: 0;
+ position: relative;
+ width: 100%;
+
+ .container {
+ background-color: vv.$primary;
+
+ .bar {
+ background-color: vv.$primary;
+ height: 100%;
+ left: 0;
+ overflow: hidden;
+ position: absolute;
+ width: 100%;
+ }
+
+ .bar::before {
+ animation: progress-loading 3s linear infinite;
+ background-color: vv.$primary;
+ content: '';
+ display: block;
+ height: 100%;
+ left: -200px;
+ position: absolute;
+ width: 200px;
+ }
+ }
+ }
+
+ .datatable-header {
+ background-clip: padding-box;
+ background-color: vv.$gray-100;
+ background-image: linear-gradient(to bottom, vv.$gray-100 0, vv.$gray-200 100%);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffafafa', endColorstr='#ffededed', GradientType=0);
+
+ .sort-asc,
+ .sort-desc {
+ color: vv.$primary;
+ }
+
+ .datatable-header-cell {
+ @include mixins.table-cell;
+
+ font-weight: bold;
+ text-align: left;
+
+ .datatable-header-cell-label {
+ &::after {
+ font-family: ForkAwesome;
+ font-weight: 400;
+ height: 9px;
+ left: 10px;
+ line-height: 12px;
+ position: relative;
+ vertical-align: baseline;
+ width: 12px;
+ }
+ }
+
+ &.sortable {
+ .datatable-header-cell-label::after {
+ content: ' \f0dc';
+ }
+
+ &.sort-active {
+ &.sort-asc .datatable-header-cell-label::after {
+ content: ' \f160';
+ }
+
+ &.sort-desc .datatable-header-cell-label::after {
+ content: ' \f161';
+ }
+ }
+ }
+
+ &:first-child {
+ border-left: 0;
+ }
+ }
+ }
+
+ .datatable-body {
+ margin-bottom: -6px;
+
+ .empty-row {
+ background-color: lighten(vv.$primary, 45%);
+ font-style: italic;
+ font-weight: bold;
+ padding-bottom: 5px;
+ padding-top: 5px;
+ text-align: center;
+ }
+
+ .datatable-body-row {
+ &.clickable:hover .datatable-row-group {
+ background-color: lighten(vv.$primary, 45%);
+ transition-duration: 0.3s;
+ transition-property: background;
+ transition-timing-function: linear;
+ }
+
+ &.datatable-row-even {
+ background-color: vv.$white;
+ }
+
+ &.datatable-row-odd {
+ background-color: vv.$gray-100;
+ }
+
+ &.active,
+ &.active:hover {
+ background-color: lighten(vv.$primary, 35%);
+ }
+
+ .datatable-body-cell {
+ @include mixins.table-cell;
+
+ &:first-child {
+ border-left: 0;
+ }
+
+ .datatable-body-cell-label {
+ display: block;
+ height: 100%;
+ }
+ }
+ }
+
+ .datatable-row-detail {
+ border-bottom: 2px solid vv.$gray-400;
+ overflow-y: visible !important;
+ padding: 20px;
+ }
+
+ .expand-collapse-icon {
+ display: block;
+ height: 100%;
+ text-align: center;
+
+ &:hover {
+ text-decoration: none;
+ }
+ }
+
+ .expand-collapse-icon-right::before {
+ @include row-details-icon;
+ content: '\f105';
+ }
+
+ .expand-collapse-icon-down::before {
+ @include row-details-icon;
+ content: '\f107';
+ }
+ }
+
+ .datatable-footer {
+ .selected-count,
+ .page-count {
+ font-style: italic;
+ min-height: 2rem;
+ padding-left: 0.3rem;
+ padding-top: 0.3rem;
+ }
+ }
+
+ .cd-datatable-checkbox {
+ text-align: center;
+ }
+}
+
+@keyframes progress-loading {
+ from {
+ left: -200px;
+ width: 15%;
+ }
+
+ 50% {
+ width: 30%;
+ }
+
+ 70% {
+ width: 70%;
+ }
+
+ 80% {
+ left: 50%;
+ }
+
+ 95% {
+ left: 120%;
+ }
+
+ to {
+ left: 100%;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.spec.ts
new file mode 100644
index 000000000..f0f649780
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.spec.ts
@@ -0,0 +1,799 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule } from '@angular/forms';
+import { By } from '@angular/platform-browser';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbDropdownModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgxDatatableModule } from '@swimlane/ngx-datatable';
+import _ from 'lodash';
+import { NgxPipeFunctionModule } from 'ngx-pipe-function';
+
+import { ComponentsModule } from '~/app/shared/components/components.module';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { CdTableColumnFilter } from '~/app/shared/models/cd-table-column-filter';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { PipesModule } from '~/app/shared/pipes/pipes.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { TableComponent } from './table.component';
+
+describe('TableComponent', () => {
+ let component: TableComponent;
+ let fixture: ComponentFixture<TableComponent>;
+
+ const createFakeData = (n: number) => {
+ const data = [];
+ for (let i = 0; i < n; i++) {
+ data.push({
+ a: i,
+ b: i * 10,
+ c: !!(i % 2)
+ });
+ }
+ return data;
+ };
+
+ const clearLocalStorage = () => {
+ component.localStorage.clear();
+ };
+
+ configureTestBed({
+ declarations: [TableComponent],
+ imports: [
+ BrowserAnimationsModule,
+ NgxDatatableModule,
+ NgxPipeFunctionModule,
+ FormsModule,
+ ComponentsModule,
+ RouterTestingModule,
+ NgbDropdownModule,
+ PipesModule,
+ NgbTooltipModule
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TableComponent);
+ component = fixture.componentInstance;
+
+ component.data = createFakeData(10);
+ component.localColumns = component.columns = [
+ { prop: 'a', name: 'Index', filterable: true },
+ { prop: 'b', name: 'Index times ten' },
+ { prop: 'c', name: 'Odd?', filterable: true }
+ ];
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should force an identifier', () => {
+ component.identifier = 'x';
+ component.forceIdentifier = true;
+ component.ngOnInit();
+ expect(component.identifier).toBe('x');
+ expect(component.sorts[0].prop).toBe('a');
+ expect(component.sorts).toEqual(component.createSortingDefinition('a'));
+ });
+
+ it('should have rows', () => {
+ component.useData();
+ expect(component.data.length).toBe(10);
+ expect(component.rows.length).toBe(component.data.length);
+ });
+
+ it('should have an int in setLimit parsing a string', () => {
+ expect(component.limit).toBe(10);
+ expect(component.limit).toEqual(jasmine.any(Number));
+
+ const e = { target: { value: '1' } };
+ component.setLimit(e);
+ expect(component.userConfig.limit).toBe(1);
+ expect(component.userConfig.limit).toEqual(jasmine.any(Number));
+ e.target.value = '-20';
+ component.setLimit(e);
+ expect(component.userConfig.limit).toBe(1);
+ });
+
+ it('should prevent propagation of mouseenter event', (done) => {
+ let wasCalled = false;
+ const mouseEvent = new MouseEvent('mouseenter');
+ mouseEvent.stopPropagation = () => {
+ wasCalled = true;
+ };
+ spyOn(component.table.element, 'addEventListener').and.callFake((eventName, fn) => {
+ fn(mouseEvent);
+ expect(eventName).toBe('mouseenter');
+ expect(wasCalled).toBe(true);
+ done();
+ });
+ component.ngOnInit();
+ });
+
+ it('should call updateSelection on init', () => {
+ component.updateSelection.subscribe((selection: CdTableSelection) => {
+ expect(selection.hasSelection).toBeFalsy();
+ expect(selection.hasSingleSelection).toBeFalsy();
+ expect(selection.hasMultiSelection).toBeFalsy();
+ expect(selection.selected.length).toBe(0);
+ });
+ component.ngOnInit();
+ });
+
+ describe('test column filtering', () => {
+ let filterIndex: CdTableColumnFilter;
+ let filterOdd: CdTableColumnFilter;
+ let filterCustom: CdTableColumnFilter;
+
+ const expectColumnFilterCreated = (
+ filter: CdTableColumnFilter,
+ prop: string,
+ options: string[],
+ value?: { raw: string; formatted: string }
+ ) => {
+ expect(filter.column.prop).toBe(prop);
+ expect(_.map(filter.options, 'raw')).toEqual(options);
+ expect(filter.value).toEqual(value);
+ };
+
+ const expectColumnFiltered = (
+ changes: { filter: CdTableColumnFilter; value?: string }[],
+ results: any[],
+ search: string = ''
+ ) => {
+ component.search = search;
+ _.forEach(changes, (change) => {
+ component.onChangeFilter(
+ change.filter,
+ change.value ? { raw: change.value, formatted: change.value } : undefined
+ );
+ });
+ expect(component.rows).toEqual(results);
+ component.onClearSearch();
+ component.onClearFilters();
+ };
+
+ describe('with visible columns', () => {
+ beforeEach(() => {
+ component.initColumnFilters();
+ component.updateColumnFilterOptions();
+ filterIndex = component.columnFilters[0];
+ filterOdd = component.columnFilters[1];
+ });
+
+ it('should have filters initialized', () => {
+ expect(component.columnFilters.length).toBe(2);
+ expectColumnFilterCreated(
+ filterIndex,
+ 'a',
+ _.map(component.data, (row) => _.toString(row.a))
+ );
+ expectColumnFilterCreated(filterOdd, 'c', ['false', 'true']);
+ });
+
+ it('should add filters', () => {
+ // single
+ expectColumnFiltered([{ filter: filterIndex, value: '1' }], [{ a: 1, b: 10, c: true }]);
+
+ // multiple
+ expectColumnFiltered(
+ [
+ { filter: filterOdd, value: 'false' },
+ { filter: filterIndex, value: '2' }
+ ],
+ [{ a: 2, b: 20, c: false }]
+ );
+
+ // Clear should work
+ expect(component.rows).toEqual(component.data);
+ });
+
+ it('should remove filters', () => {
+ // single
+ expectColumnFiltered(
+ [
+ { filter: filterOdd, value: 'true' },
+ { filter: filterIndex, value: '1' },
+ { filter: filterIndex, value: undefined }
+ ],
+ [
+ { a: 1, b: 10, c: true },
+ { a: 3, b: 30, c: true },
+ { a: 5, b: 50, c: true },
+ { a: 7, b: 70, c: true },
+ { a: 9, b: 90, c: true }
+ ]
+ );
+
+ // multiple
+ expectColumnFiltered(
+ [
+ { filter: filterOdd, value: 'true' },
+ { filter: filterIndex, value: '1' },
+ { filter: filterIndex, value: undefined },
+ { filter: filterOdd, value: undefined }
+ ],
+ component.data
+ );
+
+ // a selected filter should be removed if it's selected again
+ expectColumnFiltered(
+ [
+ { filter: filterOdd, value: 'true' },
+ { filter: filterIndex, value: '1' },
+ { filter: filterIndex, value: '1' }
+ ],
+ [
+ { a: 1, b: 10, c: true },
+ { a: 3, b: 30, c: true },
+ { a: 5, b: 50, c: true },
+ { a: 7, b: 70, c: true },
+ { a: 9, b: 90, c: true }
+ ]
+ );
+ });
+
+ it('should search from filtered rows', () => {
+ expectColumnFiltered(
+ [{ filter: filterOdd, value: 'true' }],
+ [{ a: 9, b: 90, c: true }],
+ '9'
+ );
+
+ // Clear should work
+ expect(component.rows).toEqual(component.data);
+ });
+ });
+
+ describe('with custom columns', () => {
+ beforeEach(() => {
+ // create a new additional column in data
+ for (let i = 0; i < component.data.length; i++) {
+ const row = component.data[i];
+ row['d'] = row.a;
+ }
+ // create a custom column filter
+ component.extraFilterableColumns = [
+ {
+ name: 'd less than 5',
+ prop: 'd',
+ filterOptions: ['yes', 'no'],
+ filterInitValue: 'yes',
+ filterPredicate: (row, value) => {
+ if (value === 'yes') {
+ return row.d < 5;
+ } else {
+ return row.d >= 5;
+ }
+ }
+ }
+ ];
+ component.initColumnFilters();
+ component.updateColumnFilterOptions();
+ filterIndex = component.columnFilters[0];
+ filterOdd = component.columnFilters[1];
+ filterCustom = component.columnFilters[2];
+ });
+
+ it('should have filters initialized', () => {
+ expect(component.columnFilters.length).toBe(3);
+ expectColumnFilterCreated(filterCustom, 'd', ['yes', 'no'], {
+ raw: 'yes',
+ formatted: 'yes'
+ });
+ component.useData();
+ expect(component.rows).toEqual(_.slice(component.data, 0, 5));
+ });
+
+ it('should remove filters', () => {
+ expectColumnFiltered([{ filter: filterCustom, value: 'no' }], _.slice(component.data, 5));
+ });
+ });
+ });
+
+ describe('test search', () => {
+ const expectSearch = (keyword: string, expectedResult: object[]) => {
+ component.search = keyword;
+ component.updateFilter();
+ expect(component.rows).toEqual(expectedResult);
+ component.onClearSearch();
+ };
+
+ describe('searchableObjects', () => {
+ const testObject = {
+ obj: {
+ min: 8,
+ max: 123
+ }
+ };
+
+ beforeEach(() => {
+ component.data = [testObject];
+ component.localColumns = [{ prop: 'obj', name: 'Object' }];
+ });
+
+ it('should not search through objects as default case', () => {
+ expect(component.searchableObjects).toBe(false);
+ expectSearch('8', []);
+ });
+
+ it('should search through objects if searchableObjects is set to true', () => {
+ component.searchableObjects = true;
+ expectSearch('28', []);
+ expectSearch('8', [testObject]);
+ expectSearch('123', [testObject]);
+ expectSearch('max', [testObject]);
+ });
+ });
+
+ it('should find a particular number', () => {
+ expectSearch('5', [{ a: 5, b: 50, c: true }]);
+ expectSearch('9', [{ a: 9, b: 90, c: true }]);
+ });
+
+ it('should find boolean values', () => {
+ expectSearch('true', [
+ { a: 1, b: 10, c: true },
+ { a: 3, b: 30, c: true },
+ { a: 5, b: 50, c: true },
+ { a: 7, b: 70, c: true },
+ { a: 9, b: 90, c: true }
+ ]);
+ expectSearch('false', [
+ { a: 0, b: 0, c: false },
+ { a: 2, b: 20, c: false },
+ { a: 4, b: 40, c: false },
+ { a: 6, b: 60, c: false },
+ { a: 8, b: 80, c: false }
+ ]);
+ });
+
+ it('should test search keyword preparation', () => {
+ const prepare = TableComponent.prepareSearch;
+ const expected = ['a', 'b', 'c'];
+ expect(prepare('a b c')).toEqual(expected);
+ expect(prepare('a,, b,, c')).toEqual(expected);
+ expect(prepare('a,,,, b,,, c')).toEqual(expected);
+ expect(prepare('a+b c')).toEqual(['a+b', 'c']);
+ expect(prepare('a,,,+++b,,, c')).toEqual(['a+++b', 'c']);
+ expect(prepare('"a b c" "d e f", "g, h i"')).toEqual(['a+b+c', 'd+e++f', 'g+h+i']);
+ });
+
+ it('should search for multiple values', () => {
+ expectSearch('2 20 false', [{ a: 2, b: 20, c: false }]);
+ expectSearch('false 2', [{ a: 2, b: 20, c: false }]);
+ });
+
+ it('should filter by column', () => {
+ expectSearch('index:5', [{ a: 5, b: 50, c: true }]);
+ expectSearch('times:50', [{ a: 5, b: 50, c: true }]);
+ expectSearch('times:50 index:5', [{ a: 5, b: 50, c: true }]);
+ expectSearch('Odd?:true', [
+ { a: 1, b: 10, c: true },
+ { a: 3, b: 30, c: true },
+ { a: 5, b: 50, c: true },
+ { a: 7, b: 70, c: true },
+ { a: 9, b: 90, c: true }
+ ]);
+ component.data = createFakeData(100);
+ expectSearch('index:1 odd:true times:110', [{ a: 11, b: 110, c: true }]);
+ });
+
+ it('should search through arrays', () => {
+ component.localColumns = [
+ { prop: 'a', name: 'Index' },
+ { prop: 'b', name: 'ArrayColumn' }
+ ];
+
+ component.data = [
+ { a: 1, b: ['foo', 'bar'] },
+ { a: 2, b: ['baz', 'bazinga'] }
+ ];
+ expectSearch('bar', [{ a: 1, b: ['foo', 'bar'] }]);
+ expectSearch('arraycolumn:bar arraycolumn:foo', [{ a: 1, b: ['foo', 'bar'] }]);
+ expectSearch('arraycolumn:baz arraycolumn:inga', [{ a: 2, b: ['baz', 'bazinga'] }]);
+
+ component.data = [
+ { a: 1, b: [1, 2] },
+ { a: 2, b: [3, 4] }
+ ];
+ expectSearch('arraycolumn:1 arraycolumn:2', [{ a: 1, b: [1, 2] }]);
+ });
+
+ it('should search with spaces', () => {
+ const expectedResult = [{ a: 2, b: 20, c: false }];
+ expectSearch(`'Index times ten':20`, expectedResult);
+ expectSearch('index+times+ten:20', expectedResult);
+ });
+
+ it('should filter results although column name is incomplete', () => {
+ component.data = createFakeData(3);
+ expectSearch(`'Index times ten'`, []);
+ expectSearch(`'Ind'`, []);
+ expectSearch(`'Ind:'`, [
+ { a: 0, b: 0, c: false },
+ { a: 1, b: 10, c: true },
+ { a: 2, b: 20, c: false }
+ ]);
+ });
+
+ it('should search if column name is incomplete', () => {
+ const expectedData = [
+ { a: 0, b: 0, c: false },
+ { a: 1, b: 10, c: true },
+ { a: 2, b: 20, c: false }
+ ];
+ component.data = _.clone(expectedData);
+ expectSearch('inde', []);
+ expectSearch('index:', expectedData);
+ expectSearch('index times te', []);
+ });
+
+ it('should restore full table after search', () => {
+ component.useData();
+ expect(component.rows.length).toBe(10);
+ component.search = '3';
+ component.updateFilter();
+ expect(component.rows.length).toBe(1);
+ component.onClearSearch();
+ expect(component.rows.length).toBe(10);
+ });
+
+ it('should work with undefined data', () => {
+ component.data = undefined;
+ component.search = '3';
+ component.updateFilter();
+ expect(component.rows).toBeUndefined();
+ });
+ });
+
+ describe('after ngInit', () => {
+ const toggleColumn = (prop: string, checked: boolean) => {
+ component.toggleColumn({
+ prop: prop,
+ isHidden: checked
+ });
+ };
+
+ const equalStorageConfig = () => {
+ expect(JSON.stringify(component.userConfig)).toBe(
+ component.localStorage.getItem(component.tableName)
+ );
+ };
+
+ beforeEach(() => {
+ component.ngOnInit();
+ });
+
+ it('should have updated the column definitions', () => {
+ expect(component.localColumns[0].flexGrow).toBe(1);
+ expect(component.localColumns[1].flexGrow).toBe(2);
+ expect(component.localColumns[2].flexGrow).toBe(2);
+ expect(component.localColumns[2].resizeable).toBe(false);
+ });
+
+ it('should have table columns', () => {
+ expect(component.tableColumns.length).toBe(3);
+ expect(component.tableColumns).toEqual(component.localColumns);
+ });
+
+ it('should have a unique identifier which it searches for', () => {
+ expect(component.identifier).toBe('a');
+ expect(component.userConfig.sorts[0].prop).toBe('a');
+ expect(component.userConfig.sorts).toEqual(component.createSortingDefinition('a'));
+ equalStorageConfig();
+ });
+
+ it('should remove column "a"', () => {
+ expect(component.userConfig.sorts[0].prop).toBe('a');
+ toggleColumn('a', false);
+ expect(component.userConfig.sorts[0].prop).toBe('b');
+ expect(component.tableColumns.length).toBe(2);
+ equalStorageConfig();
+ });
+
+ it('should not be able to remove all columns', () => {
+ expect(component.userConfig.sorts[0].prop).toBe('a');
+ toggleColumn('a', false);
+ toggleColumn('b', false);
+ toggleColumn('c', false);
+ expect(component.userConfig.sorts[0].prop).toBe('c');
+ expect(component.tableColumns.length).toBe(1);
+ equalStorageConfig();
+ });
+
+ it('should enable column "a" again', () => {
+ expect(component.userConfig.sorts[0].prop).toBe('a');
+ toggleColumn('a', false);
+ toggleColumn('a', true);
+ expect(component.userConfig.sorts[0].prop).toBe('b');
+ expect(component.tableColumns.length).toBe(3);
+ equalStorageConfig();
+ });
+
+ it('should toggle on off columns', () => {
+ for (const column of component.columns) {
+ component.toggleColumn(column);
+ expect(column.isHidden).toBeTruthy();
+ component.toggleColumn(column);
+ expect(column.isHidden).toBeFalsy();
+ }
+ });
+
+ afterEach(() => {
+ clearLocalStorage();
+ });
+ });
+
+ describe('test cell transformations', () => {
+ interface ExecutingTemplateConfig {
+ valueClass?: string;
+ executingClass?: string;
+ }
+
+ const testExecutingTemplate = (templateConfig?: ExecutingTemplateConfig) => {
+ const state = 'updating';
+ const value = component.data[0].a;
+
+ component.autoReload = -1;
+ component.columns[0].cellTransformation = CellTemplate.executing;
+ if (templateConfig) {
+ component.columns[0].customTemplateConfig = templateConfig;
+ }
+ component.data[0].cdExecuting = state;
+ fixture.detectChanges();
+
+ const elements = fixture.debugElement
+ .query(By.css('datatable-body-row datatable-body-cell'))
+ .queryAll(By.css('span'));
+ expect(elements.length).toBe(2);
+
+ // Value
+ const valueElement = elements[0];
+ if (templateConfig?.valueClass) {
+ templateConfig.valueClass.split(' ').forEach((clz) => {
+ expect(valueElement.classes).toHaveProperty(clz);
+ });
+ }
+ expect(valueElement.nativeElement.textContent.trim()).toBe(`${value}`);
+ // Executing state
+ const executingElement = elements[1];
+ if (templateConfig?.executingClass) {
+ templateConfig.executingClass.split(' ').forEach((clz) => {
+ expect(executingElement.classes).toHaveProperty(clz);
+ });
+ }
+ expect(executingElement.nativeElement.textContent.trim()).toBe(`(${state})`);
+ };
+
+ it('should display executing template', () => {
+ testExecutingTemplate();
+ });
+
+ it('should display executing template with custom classes', () => {
+ testExecutingTemplate({ valueClass: 'a b', executingClass: 'c d' });
+ });
+ });
+
+ describe('test unselect functionality of rows', () => {
+ beforeEach(() => {
+ component.autoReload = -1;
+ component.selectionType = 'single';
+ fixture.detectChanges();
+ });
+
+ it('should unselect row on clicking on it again', () => {
+ const rowCellDebugElement = fixture.debugElement.query(By.css('datatable-body-cell'));
+
+ rowCellDebugElement.triggerEventHandler('click', null);
+ expect(component.selection.selected.length).toEqual(1);
+
+ rowCellDebugElement.triggerEventHandler('click', null);
+ expect(component.selection.selected.length).toEqual(0);
+ });
+ });
+
+ describe('reload data', () => {
+ beforeEach(() => {
+ component.ngOnInit();
+ component.data = [];
+ component['updating'] = false;
+ });
+
+ it('should call fetchData callback function', () => {
+ component.fetchData.subscribe((context: any) => {
+ expect(context instanceof CdTableFetchDataContext).toBeTruthy();
+ });
+ component.reloadData();
+ });
+
+ it('should call error function', () => {
+ component.data = createFakeData(5);
+ component.fetchData.subscribe((context: any) => {
+ context.error();
+ expect(component.status.type).toBe('danger');
+ expect(component.data.length).toBe(0);
+ expect(component.loadingIndicator).toBeFalsy();
+ expect(component['updating']).toBeFalsy();
+ });
+ component.reloadData();
+ });
+
+ it('should call error function with custom config', () => {
+ component.data = createFakeData(10);
+ component.fetchData.subscribe((context: any) => {
+ context.errorConfig.resetData = false;
+ context.errorConfig.displayError = false;
+ context.error();
+ expect(component.status.type).toBe('danger');
+ expect(component.data.length).toBe(10);
+ expect(component.loadingIndicator).toBeFalsy();
+ expect(component['updating']).toBeFalsy();
+ });
+ component.reloadData();
+ });
+
+ it('should update selection on refresh - "onChange"', () => {
+ spyOn(component, 'onSelect').and.callThrough();
+ component.data = createFakeData(10);
+ component.selection.selected = [_.clone(component.data[1])];
+ component.updateSelectionOnRefresh = 'onChange';
+ component.updateSelected();
+ expect(component.onSelect).toHaveBeenCalledTimes(0);
+ component.data[1].d = !component.data[1].d;
+ component.updateSelected();
+ expect(component.onSelect).toHaveBeenCalled();
+ });
+
+ it('should update selection on refresh - "always"', () => {
+ spyOn(component, 'onSelect').and.callThrough();
+ component.data = createFakeData(10);
+ component.selection.selected = [_.clone(component.data[1])];
+ component.updateSelectionOnRefresh = 'always';
+ component.updateSelected();
+ expect(component.onSelect).toHaveBeenCalled();
+ component.data[1].d = !component.data[1].d;
+ component.updateSelected();
+ expect(component.onSelect).toHaveBeenCalled();
+ });
+
+ it('should update selection on refresh - "never"', () => {
+ spyOn(component, 'onSelect').and.callThrough();
+ component.data = createFakeData(10);
+ component.selection.selected = [_.clone(component.data[1])];
+ component.updateSelectionOnRefresh = 'never';
+ component.updateSelected();
+ expect(component.onSelect).toHaveBeenCalledTimes(0);
+ component.data[1].d = !component.data[1].d;
+ component.updateSelected();
+ expect(component.onSelect).toHaveBeenCalledTimes(0);
+ });
+
+ afterEach(() => {
+ clearLocalStorage();
+ });
+ });
+
+ describe('useCustomClass', () => {
+ beforeEach(() => {
+ component.customCss = {
+ 'badge badge-danger': 'active',
+ 'secret secret-number': 123.456,
+ btn: (v) => _.isString(v) && v.startsWith('http'),
+ secure: (v) => _.isString(v) && v.startsWith('https')
+ };
+ });
+
+ it('should throw an error if custom classes are not set', () => {
+ component.customCss = undefined;
+ expect(() => component.useCustomClass('active')).toThrowError('Custom classes are not set!');
+ });
+
+ it('should not return any class', () => {
+ ['', 'something', 123, { complex: 1 }, [1, 2, 3]].forEach((value) =>
+ expect(component.useCustomClass(value)).toBe(undefined)
+ );
+ });
+
+ it('should match a string and return the corresponding class', () => {
+ expect(component.useCustomClass('active')).toBe('badge badge-danger');
+ });
+
+ it('should match a number and return the corresponding class', () => {
+ expect(component.useCustomClass(123.456)).toBe('secret secret-number');
+ });
+
+ it('should match against a function and return the corresponding class', () => {
+ expect(component.useCustomClass('http://no.ssl')).toBe('btn');
+ });
+
+ it('should match against multiple functions and return the corresponding classes', () => {
+ expect(component.useCustomClass('https://secure.it')).toBe('btn secure');
+ });
+ });
+
+ describe('test expand and collapse feature', () => {
+ beforeEach(() => {
+ spyOn(component.setExpandedRow, 'emit');
+ component.table = {
+ rowDetail: { collapseAllRows: jest.fn(), toggleExpandRow: jest.fn() }
+ } as any;
+
+ // Setup table
+ component.identifier = 'a';
+ component.data = createFakeData(10);
+
+ // Select item
+ component.expanded = _.clone(component.data[1]);
+ });
+
+ describe('update expanded on refresh', () => {
+ const updateExpendedOnState = (state: 'always' | 'never' | 'onChange') => {
+ component.updateExpandedOnRefresh = state;
+ component.updateExpanded();
+ };
+
+ beforeEach(() => {
+ // Mock change
+ component.data[1].b = 'test';
+ });
+
+ it('refreshes "always"', () => {
+ updateExpendedOnState('always');
+ expect(component.expanded.b).toBe('test');
+ expect(component.setExpandedRow.emit).toHaveBeenCalled();
+ });
+
+ it('refreshes "onChange"', () => {
+ updateExpendedOnState('onChange');
+ expect(component.expanded.b).toBe('test');
+ expect(component.setExpandedRow.emit).toHaveBeenCalled();
+ });
+
+ it('does not refresh "onChange" if data is equal', () => {
+ component.data[1].b = 10; // Reverts change
+ updateExpendedOnState('onChange');
+ expect(component.expanded.b).toBe(10);
+ expect(component.setExpandedRow.emit).not.toHaveBeenCalled();
+ });
+
+ it('"never" refreshes', () => {
+ updateExpendedOnState('never');
+ expect(component.expanded.b).toBe(10);
+ expect(component.setExpandedRow.emit).not.toHaveBeenCalled();
+ });
+ });
+
+ it('should open the table details and close other expanded rows', () => {
+ component.toggleExpandRow(component.expanded, false, new Event('click'));
+ expect(component.expanded).toEqual({ a: 1, b: 10, c: true });
+ expect(component.table.rowDetail.collapseAllRows).toHaveBeenCalled();
+ expect(component.setExpandedRow.emit).toHaveBeenCalledWith(component.expanded);
+ expect(component.table.rowDetail.toggleExpandRow).toHaveBeenCalled();
+ });
+
+ it('should close the current table details expansion', () => {
+ component.toggleExpandRow(component.expanded, true, new Event('click'));
+ expect(component.expanded).toBeUndefined();
+ expect(component.setExpandedRow.emit).toHaveBeenCalledWith(undefined);
+ expect(component.table.rowDetail.toggleExpandRow).toHaveBeenCalled();
+ });
+
+ it('should not select the row when the row is expanded', () => {
+ expect(component.selection.selected).toEqual([]);
+ component.toggleExpandRow(component.data[1], false, new Event('click'));
+ expect(component.selection.selected).toEqual([]);
+ });
+
+ it('should not change selection when expanding different row', () => {
+ expect(component.selection.selected).toEqual([]);
+ expect(component.expanded).toEqual(component.data[1]);
+ component.selection.selected = [component.data[2]];
+ component.toggleExpandRow(component.data[3], false, new Event('click'));
+ expect(component.selection.selected).toEqual([component.data[2]]);
+ expect(component.expanded).toEqual(component.data[3]);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts
new file mode 100644
index 000000000..6a37468c2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts
@@ -0,0 +1,927 @@
+import {
+ AfterContentChecked,
+ ChangeDetectionStrategy,
+ ChangeDetectorRef,
+ Component,
+ EventEmitter,
+ Input,
+ OnChanges,
+ OnDestroy,
+ OnInit,
+ Output,
+ PipeTransform,
+ SimpleChanges,
+ TemplateRef,
+ ViewChild
+} from '@angular/core';
+
+import {
+ DatatableComponent,
+ getterForProp,
+ SortDirection,
+ SortPropDir,
+ TableColumnProp
+} from '@swimlane/ngx-datatable';
+import _ from 'lodash';
+import { Observable, of, Subject, Subscription } from 'rxjs';
+
+import { TableStatus } from '~/app/shared/classes/table-status';
+import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdTableColumn } from '~/app/shared/models/cd-table-column';
+import { CdTableColumnFilter } from '~/app/shared/models/cd-table-column-filter';
+import { CdTableColumnFiltersChange } from '~/app/shared/models/cd-table-column-filters-change';
+import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
+import { PageInfo } from '~/app/shared/models/cd-table-paging';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { CdUserConfig } from '~/app/shared/models/cd-user-config';
+import { TimerService } from '~/app/shared/services/timer.service';
+
+@Component({
+ selector: 'cd-table',
+ templateUrl: './table.component.html',
+ styleUrls: ['./table.component.scss'],
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class TableComponent implements AfterContentChecked, OnInit, OnChanges, OnDestroy {
+ @ViewChild(DatatableComponent, { static: true })
+ table: DatatableComponent;
+ @ViewChild('tableCellBoldTpl', { static: true })
+ tableCellBoldTpl: TemplateRef<any>;
+ @ViewChild('sparklineTpl', { static: true })
+ sparklineTpl: TemplateRef<any>;
+ @ViewChild('routerLinkTpl', { static: true })
+ routerLinkTpl: TemplateRef<any>;
+ @ViewChild('checkIconTpl', { static: true })
+ checkIconTpl: TemplateRef<any>;
+ @ViewChild('perSecondTpl', { static: true })
+ perSecondTpl: TemplateRef<any>;
+ @ViewChild('executingTpl', { static: true })
+ executingTpl: TemplateRef<any>;
+ @ViewChild('classAddingTpl', { static: true })
+ classAddingTpl: TemplateRef<any>;
+ @ViewChild('badgeTpl', { static: true })
+ badgeTpl: TemplateRef<any>;
+ @ViewChild('mapTpl', { static: true })
+ mapTpl: TemplateRef<any>;
+ @ViewChild('truncateTpl', { static: true })
+ truncateTpl: TemplateRef<any>;
+ @ViewChild('rowDetailsTpl', { static: true })
+ rowDetailsTpl: TemplateRef<any>;
+
+ // This is the array with the items to be shown.
+ @Input()
+ data: any[];
+ // Each item -> { prop: 'attribute name', name: 'display name' }
+ @Input()
+ columns: CdTableColumn[];
+ // Each item -> { prop: 'attribute name', dir: 'asc'||'desc'}
+ @Input()
+ sorts?: SortPropDir[];
+ // Method used for setting column widths.
+ @Input()
+ columnMode? = 'flex';
+ // Display only actions in header (make sure to disable toolHeader) and use ".only-table-actions"
+ @Input()
+ onlyActionHeader? = false;
+ // Display the tool header, including reload button, pagination and search fields?
+ @Input()
+ toolHeader? = true;
+ // Display search field inside tool header?
+ @Input()
+ searchField? = true;
+ // Display the table header?
+ @Input()
+ header? = true;
+ // Display the table footer?
+ @Input()
+ footer? = true;
+ // Page size to show. Set to 0 to show unlimited number of rows.
+ @Input()
+ limit? = 10;
+ @Input()
+ maxLimit? = 9999;
+ // Has the row details?
+ @Input()
+ hasDetails = false;
+
+ /**
+ * Auto reload time in ms - per default every 5s
+ * You can set it to 0, undefined or false to disable the auto reload feature in order to
+ * trigger 'fetchData' if the reload button is clicked.
+ * You can set it to a negative number to, on top of disabling the auto reload,
+ * prevent triggering fetchData when initializing the table.
+ */
+ @Input()
+ autoReload = 5000;
+
+ // Which row property is unique for a row. If the identifier is not specified in any
+ // column, then the property name of the first column is used. Defaults to 'id'.
+ @Input()
+ identifier = 'id';
+ // If 'true', then the specified identifier is used anyway, although it is not specified
+ // in any column. Defaults to 'false'.
+ @Input()
+ forceIdentifier = false;
+ // Allows other components to specify which type of selection they want,
+ // e.g. 'single' or 'multi'.
+ @Input()
+ selectionType: string = undefined;
+ // By default selected item details will be updated on table refresh, if data has changed
+ @Input()
+ updateSelectionOnRefresh: 'always' | 'never' | 'onChange' = 'onChange';
+ // By default expanded item details will be updated on table refresh, if data has changed
+ @Input()
+ updateExpandedOnRefresh: 'always' | 'never' | 'onChange' = 'onChange';
+
+ @Input()
+ autoSave = true;
+
+ // Enable this in order to search through the JSON of any used object.
+ @Input()
+ searchableObjects = false;
+
+ // Only needed to set if the classAddingTpl is used
+ @Input()
+ customCss?: { [css: string]: number | string | ((any: any) => boolean) };
+
+ // Columns that aren't displayed but can be used as filters
+ @Input()
+ extraFilterableColumns: CdTableColumn[] = [];
+
+ @Input()
+ status = new TableStatus();
+
+ // Support server-side pagination/sorting/etc.
+ @Input()
+ serverSide = false;
+
+ /*
+ Only required when serverSide is enabled.
+ It should be provided by the server via "X-Total-Count" HTTP Header
+ */
+ @Input()
+ count = 0;
+
+ /**
+ * Should be a function to update the input data if undefined nothing will be triggered
+ *
+ * Sometimes it's useful to only define fetchData once.
+ * Example:
+ * Usage of multiple tables with data which is updated by the same function
+ * What happens:
+ * The function is triggered through one table and all tables will update
+ */
+ @Output()
+ fetchData = new EventEmitter<CdTableFetchDataContext>();
+
+ /**
+ * This should be defined if you need access to the selection object.
+ *
+ * Each time the table selection changes, this will be triggered and
+ * the new selection object will be sent.
+ *
+ * @memberof TableComponent
+ */
+ @Output()
+ updateSelection = new EventEmitter();
+
+ @Output()
+ setExpandedRow = new EventEmitter();
+
+ /**
+ * This should be defined if you need access to the applied column filters.
+ *
+ * Each time the column filters changes, this will be triggered and
+ * the column filters change event will be sent.
+ *
+ * @memberof TableComponent
+ */
+ @Output() columnFiltersChanged = new EventEmitter<CdTableColumnFiltersChange>();
+
+ /**
+ * Use this variable to access the selected row(s).
+ */
+ selection = new CdTableSelection();
+
+ /**
+ * Use this variable to access the expanded row
+ */
+ expanded: any = undefined;
+
+ /**
+ * To prevent making changes to the original columns list, that might change
+ * how the table is renderer a second time, we now clone that list into a
+ * local variable and only use the clone.
+ */
+ localColumns: CdTableColumn[];
+ tableColumns: CdTableColumn[];
+ icons = Icons;
+ cellTemplates: {
+ [key: string]: TemplateRef<any>;
+ } = {};
+ search = '';
+ rows: any[] = [];
+ loadingIndicator = true;
+ paginationClasses = {
+ pagerLeftArrow: Icons.leftArrowDouble,
+ pagerRightArrow: Icons.rightArrowDouble,
+ pagerPrevious: Icons.leftArrow,
+ pagerNext: Icons.rightArrow
+ };
+ userConfig: CdUserConfig = {};
+ tableName: string;
+ localStorage = window.localStorage;
+ private saveSubscriber: Subscription;
+ private reloadSubscriber: Subscription;
+ private updating = false;
+
+ // Internal variable to check if it is necessary to recalculate the
+ // table columns after the browser window has been resized.
+ private currentWidth: number;
+
+ columnFilters: CdTableColumnFilter[] = [];
+ selectedFilter: CdTableColumnFilter;
+ get columnFiltered(): boolean {
+ return _.some(this.columnFilters, (filter) => {
+ return filter.value !== undefined;
+ });
+ }
+
+ constructor(
+ // private ngZone: NgZone,
+ private cdRef: ChangeDetectorRef,
+ private timerService: TimerService
+ ) {}
+
+ static prepareSearch(search: string) {
+ search = search.toLowerCase().replace(/,/g, '');
+ if (search.match(/['"][^'"]+['"]/)) {
+ search = search.replace(/['"][^'"]+['"]/g, (match: string) => {
+ return match.replace(/(['"])([^'"]+)(['"])/g, '$2').replace(/ /g, '+');
+ });
+ }
+ return search.split(' ').filter((word) => word);
+ }
+
+ ngOnInit() {
+ this.localColumns = _.clone(this.columns);
+ // debounce reloadData method so that search doesn't run api requests
+ // for every keystroke
+ if (this.serverSide) {
+ this.reloadData = _.debounce(this.reloadData, 1000);
+ }
+
+ // ngx-datatable triggers calculations each time mouse enters a row,
+ // this will prevent that.
+ this.table.element.addEventListener('mouseenter', (e) => e.stopPropagation());
+ this._addTemplates();
+ if (!this.sorts) {
+ // Check whether the specified identifier exists.
+ const exists = _.findIndex(this.localColumns, ['prop', this.identifier]) !== -1;
+ // Auto-build the sorting configuration. If the specified identifier doesn't exist,
+ // then use the property of the first column.
+ this.sorts = this.createSortingDefinition(
+ exists ? this.identifier : this.localColumns[0].prop + ''
+ );
+ // If the specified identifier doesn't exist and it is not forced to use it anyway,
+ // then use the property of the first column.
+ if (!exists && !this.forceIdentifier) {
+ this.identifier = this.localColumns[0].prop + '';
+ }
+ }
+
+ this.initUserConfig();
+ this.localColumns.forEach((c) => {
+ if (c.cellTransformation) {
+ c.cellTemplate = this.cellTemplates[c.cellTransformation];
+ }
+ if (!c.flexGrow) {
+ c.flexGrow = c.prop + '' === this.identifier ? 1 : 2;
+ }
+ if (!c.resizeable) {
+ c.resizeable = false;
+ }
+ });
+
+ this.initExpandCollapseColumn(); // If rows have details, add a column to expand or collapse the rows
+ this.initCheckboxColumn();
+ this.filterHiddenColumns();
+ this.initColumnFilters();
+ this.updateColumnFilterOptions();
+ // Notify all subscribers to reset their current selection.
+ this.updateSelection.emit(new CdTableSelection());
+ // Load the data table content every N ms or at least once.
+ // Force showing the loading indicator if there are subscribers to the fetchData
+ // event. This is necessary because it has been set to False in useData() when
+ // this method was triggered by ngOnChanges().
+ if (this.fetchData.observers.length > 0) {
+ this.loadingIndicator = true;
+ }
+ if (_.isInteger(this.autoReload) && this.autoReload > 0) {
+ this.reloadSubscriber = this.timerService
+ .get(() => of(0), this.autoReload)
+ .subscribe(() => {
+ this.reloadData();
+ });
+ } else if (!this.autoReload) {
+ this.reloadData();
+ } else {
+ this.useData();
+ }
+
+ if (this.selectionType === 'single') {
+ this.table.selectCheck = this.singleSelectCheck.bind(this);
+ }
+ }
+
+ initUserConfig() {
+ if (this.autoSave) {
+ this.tableName = this._calculateUniqueTableName(this.localColumns);
+ this._loadUserConfig();
+ this._initUserConfigAutoSave();
+ }
+ if (!this.userConfig.limit) {
+ this.userConfig.limit = this.limit;
+ }
+ if (!(this.userConfig.offset >= 0)) {
+ this.userConfig.offset = this.table.offset;
+ }
+ if (!this.userConfig.search) {
+ this.userConfig.search = this.search;
+ }
+ if (!this.userConfig.sorts) {
+ this.userConfig.sorts = this.sorts;
+ }
+ if (!this.userConfig.columns) {
+ this.updateUserColumns();
+ } else {
+ this.userConfig.columns.forEach((col) => {
+ for (let i = 0; i < this.localColumns.length; i++) {
+ if (this.localColumns[i].prop === col.prop) {
+ this.localColumns[i].isHidden = col.isHidden;
+ }
+ }
+ });
+ }
+ }
+
+ _calculateUniqueTableName(columns: any[]) {
+ const stringToNumber = (s: string) => {
+ if (!_.isString(s)) {
+ return 0;
+ }
+ let result = 0;
+ for (let i = 0; i < s.length; i++) {
+ result += s.charCodeAt(i) * i;
+ }
+ return result;
+ };
+ return columns
+ .reduce(
+ (result, value, index) =>
+ (stringToNumber(value.prop) + stringToNumber(value.name)) * (index + 1) + result,
+ 0
+ )
+ .toString();
+ }
+
+ _loadUserConfig() {
+ const loaded = this.localStorage.getItem(this.tableName);
+ if (loaded) {
+ this.userConfig = JSON.parse(loaded);
+ }
+ }
+
+ _initUserConfigAutoSave() {
+ const source: Observable<any> = new Observable(this._initUserConfigProxy.bind(this));
+ this.saveSubscriber = source.subscribe(this._saveUserConfig.bind(this));
+ }
+
+ _initUserConfigProxy(observer: Subject<any>) {
+ this.userConfig = new Proxy(this.userConfig, {
+ set(config, prop: string, value) {
+ config[prop] = value;
+ observer.next(config);
+ return true;
+ }
+ });
+ }
+
+ _saveUserConfig(config: any) {
+ this.localStorage.setItem(this.tableName, JSON.stringify(config));
+ }
+
+ updateUserColumns() {
+ this.userConfig.columns = this.localColumns.map((c) => ({
+ prop: c.prop,
+ name: c.name,
+ isHidden: !!c.isHidden
+ }));
+ }
+
+ /**
+ * Add a column containing a checkbox if selectionType is 'multiClick'.
+ */
+ initCheckboxColumn() {
+ if (this.selectionType === 'multiClick') {
+ this.localColumns.unshift({
+ prop: undefined,
+ resizeable: false,
+ sortable: false,
+ draggable: false,
+ checkboxable: true,
+ canAutoResize: false,
+ cellClass: 'cd-datatable-checkbox',
+ width: 30
+ });
+ }
+ }
+
+ /**
+ * Add a column to expand and collapse the table row if it 'hasDetails'
+ */
+ initExpandCollapseColumn() {
+ if (this.hasDetails) {
+ this.localColumns.unshift({
+ prop: undefined,
+ resizeable: false,
+ sortable: false,
+ draggable: false,
+ isHidden: false,
+ canAutoResize: false,
+ cellClass: 'cd-datatable-expand-collapse',
+ width: 40,
+ cellTemplate: this.rowDetailsTpl
+ });
+ }
+ }
+
+ filterHiddenColumns() {
+ this.tableColumns = this.localColumns.filter((c) => !c.isHidden);
+ }
+
+ initColumnFilters() {
+ let filterableColumns = _.filter(this.localColumns, { filterable: true });
+ filterableColumns = [...filterableColumns, ...this.extraFilterableColumns];
+ this.columnFilters = filterableColumns.map((col: CdTableColumn) => {
+ return {
+ column: col,
+ options: [],
+ value: col.filterInitValue
+ ? this.createColumnFilterOption(col.filterInitValue, col.pipe)
+ : undefined
+ };
+ });
+ this.selectedFilter = _.first(this.columnFilters);
+ }
+
+ private createColumnFilterOption(
+ value: any,
+ pipe?: PipeTransform
+ ): { raw: string; formatted: string } {
+ return {
+ raw: _.toString(value),
+ formatted: pipe ? pipe.transform(value) : _.toString(value)
+ };
+ }
+
+ updateColumnFilterOptions() {
+ // update all possible values in a column
+ this.columnFilters.forEach((filter) => {
+ let values: any[] = [];
+
+ if (_.isUndefined(filter.column.filterOptions)) {
+ // only allow types that can be easily converted into string
+ const pre = _.filter(_.map(this.data, filter.column.prop), (v) => {
+ return (_.isString(v) && v !== '') || _.isBoolean(v) || _.isFinite(v) || _.isDate(v);
+ });
+ values = _.sortedUniq(pre.sort());
+ } else {
+ values = filter.column.filterOptions;
+ }
+
+ const options = values.map((v) => this.createColumnFilterOption(v, filter.column.pipe));
+
+ // In case a previous value is not available anymore
+ if (filter.value && _.isUndefined(_.find(options, { raw: filter.value.raw }))) {
+ filter.value = undefined;
+ }
+
+ filter.options = options;
+ });
+ }
+
+ onSelectFilter(filter: CdTableColumnFilter) {
+ this.selectedFilter = filter;
+ }
+
+ onChangeFilter(filter: CdTableColumnFilter, option?: { raw: string; formatted: string }) {
+ filter.value = _.isEqual(filter.value, option) ? undefined : option;
+ this.updateFilter();
+ }
+
+ doColumnFiltering() {
+ const appliedFilters: CdTableColumnFiltersChange['filters'] = [];
+ let data = [...this.data];
+ let dataOut: any[] = [];
+ this.columnFilters.forEach((filter) => {
+ if (filter.value === undefined) {
+ return;
+ }
+ appliedFilters.push({
+ name: filter.column.name,
+ prop: filter.column.prop,
+ value: filter.value
+ });
+ // Separate data to filtered and filtered-out parts.
+ const parts = _.partition(data, (row) => {
+ // Use getter from ngx-datatable to handle props like 'sys_api.size'
+ const valueGetter = getterForProp(filter.column.prop);
+ const value = valueGetter(row, filter.column.prop);
+ if (_.isUndefined(filter.column.filterPredicate)) {
+ // By default, test string equal
+ return `${value}` === filter.value.raw;
+ } else {
+ // Use custom function to filter
+ return filter.column.filterPredicate(row, filter.value.raw);
+ }
+ });
+ data = parts[0];
+ dataOut = [...dataOut, ...parts[1]];
+ });
+
+ this.columnFiltersChanged.emit({
+ filters: appliedFilters,
+ data: data,
+ dataOut: dataOut
+ });
+
+ // Remove the selection if previously-selected rows are filtered out.
+ _.forEach(this.selection.selected, (selectedItem) => {
+ if (_.find(data, { [this.identifier]: selectedItem[this.identifier] }) === undefined) {
+ this.selection = new CdTableSelection();
+ this.onSelect(this.selection);
+ }
+ });
+ return data;
+ }
+
+ ngOnDestroy() {
+ if (this.reloadSubscriber) {
+ this.reloadSubscriber.unsubscribe();
+ }
+ if (this.saveSubscriber) {
+ this.saveSubscriber.unsubscribe();
+ }
+ }
+
+ ngAfterContentChecked() {
+ // If the data table is not visible, e.g. another tab is active, and the
+ // browser window gets resized, the table and its columns won't get resized
+ // automatically if the tab gets visible again.
+ // https://github.com/swimlane/ngx-datatable/issues/193
+ // https://github.com/swimlane/ngx-datatable/issues/193#issuecomment-329144543
+ if (this.table && this.table.element.clientWidth !== this.currentWidth) {
+ this.currentWidth = this.table.element.clientWidth;
+ // Recalculate the sizes of the grid.
+ this.table.recalculate();
+ // Mark the datatable as changed, Angular's change-detection will
+ // do the rest for us => the grid will be redrawn.
+ // Note, the ChangeDetectorRef variable is private, so we need to
+ // use this workaround to access it and make TypeScript happy.
+ const cdRef = _.get(this.table, 'cd');
+ cdRef.markForCheck();
+ }
+ }
+
+ _addTemplates() {
+ this.cellTemplates.bold = this.tableCellBoldTpl;
+ this.cellTemplates.checkIcon = this.checkIconTpl;
+ this.cellTemplates.sparkline = this.sparklineTpl;
+ this.cellTemplates.routerLink = this.routerLinkTpl;
+ this.cellTemplates.perSecond = this.perSecondTpl;
+ this.cellTemplates.executing = this.executingTpl;
+ this.cellTemplates.classAdding = this.classAddingTpl;
+ this.cellTemplates.badge = this.badgeTpl;
+ this.cellTemplates.map = this.mapTpl;
+ this.cellTemplates.truncate = this.truncateTpl;
+ }
+
+ useCustomClass(value: any): string {
+ if (!this.customCss) {
+ throw new Error('Custom classes are not set!');
+ }
+ const classes = Object.keys(this.customCss);
+ const css = Object.values(this.customCss)
+ .map((v, i) => ((_.isFunction(v) && v(value)) || v === value) && classes[i])
+ .filter((x) => x)
+ .join(' ');
+ return _.isEmpty(css) ? undefined : css;
+ }
+
+ ngOnChanges(changes: SimpleChanges) {
+ if (changes.data && changes.data.currentValue) {
+ this.useData();
+ }
+ }
+
+ setLimit(e: any) {
+ const value = Number(e.target.value);
+ if (value > 0) {
+ if (this.maxLimit && value > this.maxLimit) {
+ this.userConfig.limit = this.maxLimit;
+ // change input field to maxLimit
+ e.srcElement.value = this.maxLimit;
+ } else {
+ this.userConfig.limit = value;
+ }
+ }
+ if (this.serverSide) {
+ this.reloadData();
+ }
+ }
+
+ reloadData() {
+ if (!this.updating) {
+ this.status = new TableStatus();
+ const context = new CdTableFetchDataContext(() => {
+ // Do we have to display the error panel?
+ if (!!context.errorConfig.displayError) {
+ this.status = new TableStatus('danger', $localize`Failed to load data.`);
+ }
+ // Force data table to show no data?
+ if (context.errorConfig.resetData) {
+ this.data = [];
+ }
+ // Stop the loading indicator and reset the data table
+ // to the correct state.
+ this.useData();
+ });
+ context.pageInfo.offset = this.userConfig.offset;
+ context.pageInfo.limit = this.userConfig.limit;
+ context.search = this.userConfig.search;
+ if (this.userConfig.sorts?.length) {
+ const sort = this.userConfig.sorts[0];
+ context.sort = `${sort.dir === 'desc' ? '-' : '+'}${sort.prop}`;
+ }
+ this.fetchData.emit(context);
+ this.updating = true;
+ }
+ }
+
+ refreshBtn() {
+ this.loadingIndicator = true;
+ this.reloadData();
+ }
+
+ changePage(pageInfo: PageInfo) {
+ this.userConfig.offset = pageInfo.offset;
+ this.userConfig.limit = pageInfo.limit;
+ if (this.serverSide) {
+ this.reloadData();
+ }
+ }
+ rowIdentity() {
+ return (row: any) => {
+ const id = row[this.identifier];
+ if (_.isUndefined(id)) {
+ throw new Error(`Wrong identifier "${this.identifier}" -> "${id}"`);
+ }
+ return id;
+ };
+ }
+
+ useData() {
+ if (!this.data) {
+ return; // Wait for data
+ }
+ this.updateColumnFilterOptions();
+ this.updateFilter();
+ this.reset();
+ this.updateSelected();
+ this.updateExpanded();
+ }
+
+ /**
+ * Reset the data table to correct state. This includes:
+ * - Disable loading indicator
+ * - Reset 'Updating' flag
+ */
+ reset() {
+ this.loadingIndicator = false;
+ this.updating = false;
+ }
+
+ /**
+ * After updating the data, we have to update the selected items
+ * because details may have changed,
+ * or some selected items may have been removed.
+ */
+ updateSelected() {
+ if (this.updateSelectionOnRefresh === 'never') {
+ return;
+ }
+ const newSelected = new Set();
+ this.selection.selected.forEach((selectedItem) => {
+ for (const row of this.data) {
+ if (selectedItem[this.identifier] === row[this.identifier]) {
+ newSelected.add(row);
+ }
+ }
+ });
+ const newSelectedArray = Array.from(newSelected.values());
+ if (
+ this.updateSelectionOnRefresh === 'onChange' &&
+ _.isEqual(this.selection.selected, newSelectedArray)
+ ) {
+ return;
+ }
+ this.selection.selected = newSelectedArray;
+ this.onSelect(this.selection);
+ }
+
+ updateExpanded() {
+ if (_.isUndefined(this.expanded) || this.updateExpandedOnRefresh === 'never') {
+ return;
+ }
+
+ const expandedId = this.expanded[this.identifier];
+ const newExpanded = _.find(this.data, (row) => expandedId === row[this.identifier]);
+
+ if (this.updateExpandedOnRefresh === 'onChange' && _.isEqual(this.expanded, newExpanded)) {
+ return;
+ }
+
+ this.expanded = newExpanded;
+ this.setExpandedRow.emit(newExpanded);
+ }
+
+ onSelect($event: any) {
+ // Ensure we do not process DOM 'select' events.
+ // https://github.com/swimlane/ngx-datatable/issues/899
+ if (_.has($event, 'selected')) {
+ this.selection.selected = $event['selected'];
+ }
+ this.updateSelection.emit(_.clone(this.selection));
+ }
+
+ private singleSelectCheck(row: any) {
+ return this.selection.selected.indexOf(row) === -1;
+ }
+
+ toggleColumn(column: CdTableColumn) {
+ const prop: TableColumnProp = column.prop;
+ const hide = !column.isHidden;
+ if (hide && this.tableColumns.length === 1) {
+ column.isHidden = true;
+ return;
+ }
+ _.find(this.localColumns, (c: CdTableColumn) => c.prop === prop).isHidden = hide;
+ this.updateColumns();
+ }
+
+ updateColumns() {
+ this.updateUserColumns();
+ this.filterHiddenColumns();
+ const sortProp = this.userConfig.sorts[0].prop;
+ if (!_.find(this.tableColumns, (c: CdTableColumn) => c.prop === sortProp)) {
+ this.userConfig.sorts = this.createSortingDefinition(this.tableColumns[0].prop);
+ }
+ this.table.recalculate();
+ this.cdRef.detectChanges();
+ }
+
+ createSortingDefinition(prop: TableColumnProp): SortPropDir[] {
+ return [
+ {
+ prop: prop,
+ dir: SortDirection.asc
+ }
+ ];
+ }
+
+ changeSorting({ sorts }: any) {
+ this.userConfig.sorts = sorts;
+ if (this.serverSide) {
+ this.userConfig.offset = 0;
+ this.reloadData();
+ }
+ }
+
+ onClearSearch() {
+ this.search = '';
+ this.updateFilter();
+ }
+
+ onClearFilters() {
+ this.columnFilters.forEach((filter) => {
+ filter.value = undefined;
+ });
+ this.selectedFilter = _.first(this.columnFilters);
+ this.updateFilter();
+ }
+
+ updateFilter() {
+ if (this.serverSide) {
+ if (this.userConfig.search !== this.search) {
+ // if we don't go back to the first page it will try load
+ // a page which could not exists with an especific search
+ this.userConfig.offset = 0;
+ this.userConfig.limit = this.limit;
+ this.userConfig.search = this.search;
+ this.updating = false;
+ this.reloadData();
+ }
+ this.rows = this.data;
+ } else {
+ let rows = this.columnFilters.length !== 0 ? this.doColumnFiltering() : this.data;
+
+ if (this.search.length > 0 && rows) {
+ const columns = this.localColumns.filter(
+ (c) => c.cellTransformation !== CellTemplate.sparkline
+ );
+ // update the rows
+ rows = this.subSearch(rows, TableComponent.prepareSearch(this.search), columns);
+ // Whenever the filter changes, always go back to the first page
+ this.table.offset = 0;
+ }
+
+ this.rows = rows;
+ }
+ }
+
+ subSearch(data: any[], currentSearch: string[], columns: CdTableColumn[]): any[] {
+ if (currentSearch.length === 0 || data.length === 0) {
+ return data;
+ }
+ const searchTerms: string[] = currentSearch.pop().replace(/\+/g, ' ').split(':');
+ const columnsClone = [...columns];
+ if (searchTerms.length === 2) {
+ columns = columnsClone.filter((c) => c.name.toLowerCase().indexOf(searchTerms[0]) !== -1);
+ }
+ data = this.basicDataSearch(_.last(searchTerms), data, columns);
+ // Checks if user searches for column but he is still typing
+ return this.subSearch(data, currentSearch, columnsClone);
+ }
+
+ basicDataSearch(searchTerm: string, rows: any[], columns: CdTableColumn[]) {
+ if (searchTerm.length === 0) {
+ return rows;
+ }
+ return rows.filter((row) => {
+ return (
+ columns.filter((col) => {
+ let cellValue: any = _.get(row, col.prop);
+
+ if (!_.isUndefined(col.pipe)) {
+ cellValue = col.pipe.transform(cellValue);
+ }
+ if (_.isUndefined(cellValue) || _.isNull(cellValue)) {
+ return false;
+ }
+
+ if (_.isArray(cellValue)) {
+ cellValue = cellValue.join(' ');
+ } else if (_.isNumber(cellValue) || _.isBoolean(cellValue)) {
+ cellValue = cellValue.toString();
+ }
+
+ if (_.isObjectLike(cellValue)) {
+ if (this.searchableObjects) {
+ cellValue = JSON.stringify(cellValue);
+ } else {
+ return false;
+ }
+ }
+
+ return cellValue.toLowerCase().indexOf(searchTerm) !== -1;
+ }).length > 0
+ );
+ });
+ }
+
+ getRowClass() {
+ // Return the function used to populate a row's CSS classes.
+ return () => {
+ return {
+ clickable: !_.isUndefined(this.selectionType)
+ };
+ };
+ }
+
+ toggleExpandRow(row: any, isExpanded: boolean, event: any) {
+ event.stopPropagation();
+ if (!isExpanded) {
+ // If current row isn't expanded, collapse others
+ this.expanded = row;
+ this.table.rowDetail.collapseAllRows();
+ this.setExpandedRow.emit(row);
+ } else {
+ // If all rows are closed, emit undefined
+ this.expanded = undefined;
+ this.setExpandedRow.emit(undefined);
+ }
+ this.table.rowDetail.toggleExpandRow(row);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/decorators/cd-encode.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/decorators/cd-encode.spec.ts
new file mode 100644
index 000000000..49b504fd6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/decorators/cd-encode.spec.ts
@@ -0,0 +1,41 @@
+import { cdEncode, cdEncodeNot } from './cd-encode';
+
+describe('cdEncode', () => {
+ @cdEncode
+ class ClassA {
+ x2: string;
+ y2: string;
+
+ methodA(x1: string, @cdEncodeNot y1: string) {
+ this.x2 = x1;
+ this.y2 = y1;
+ }
+ }
+
+ class ClassB {
+ x2: string;
+ y2: string;
+
+ @cdEncode
+ methodB(x1: string, @cdEncodeNot y1: string) {
+ this.x2 = x1;
+ this.y2 = y1;
+ }
+ }
+
+ const word = 'a+b/c-d';
+
+ it('should encode all params of ClassA, with exception of y1', () => {
+ const a = new ClassA();
+ a.methodA(word, word);
+ expect(a.x2).toBe('a%2Bb%2Fc-d');
+ expect(a.y2).toBe(word);
+ });
+
+ it('should encode all params of methodB, with exception of y1', () => {
+ const b = new ClassB();
+ b.methodB(word, word);
+ expect(b.x2).toBe('a%2Bb%2Fc-d');
+ expect(b.y2).toBe(word);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/decorators/cd-encode.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/decorators/cd-encode.ts
new file mode 100644
index 000000000..afff2ec6d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/decorators/cd-encode.ts
@@ -0,0 +1,80 @@
+import _ from 'lodash';
+
+/**
+ * This decorator can be used in a class or method.
+ * It will encode all the string parameters of all the methods of a class
+ * or, if applied on a method, the specified method.
+ *
+ * @export
+ * @param {Function} [target=null]
+ * @returns {*}
+ */
+export function cdEncode(...args: any[]): any {
+ switch (args.length) {
+ case 1:
+ return encodeClass.apply(undefined, args);
+ case 3:
+ return encodeMethod.apply(undefined, args);
+ default:
+ throw new Error();
+ }
+}
+
+/**
+ * This decorator can be used in parameters only.
+ * It will exclude the parameter from being encode.
+ * This should be used in parameters that are going
+ * to be sent in the request's body.
+ *
+ * @export
+ * @param {Object} target
+ * @param {string} propertyKey
+ * @param {number} index
+ */
+export function cdEncodeNot(target: object, propertyKey: string, index: number) {
+ const metadataKey = `__ignore_${propertyKey}`;
+ if (Array.isArray(target[metadataKey])) {
+ target[metadataKey].push(index);
+ } else {
+ target[metadataKey] = [index];
+ }
+}
+
+function encodeClass(target: Function) {
+ for (const propertyName of Object.getOwnPropertyNames(target.prototype)) {
+ const descriptor = Object.getOwnPropertyDescriptor(target.prototype, propertyName);
+
+ const isMethod = descriptor.value instanceof Function;
+ const isConstructor = propertyName === 'constructor';
+ if (!isMethod || isConstructor) {
+ continue;
+ }
+
+ encodeMethod(target.prototype, propertyName, descriptor);
+ Object.defineProperty(target.prototype, propertyName, descriptor);
+ }
+}
+
+function encodeMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
+ if (descriptor === undefined) {
+ descriptor = Object.getOwnPropertyDescriptor(target, propertyKey);
+ }
+ const originalMethod = descriptor.value;
+
+ descriptor.value = function () {
+ const metadataKey = `__ignore_${propertyKey}`;
+ const indices: number[] = target[metadataKey] || [];
+ const args = [];
+
+ for (let i = 0; i < arguments.length; i++) {
+ if (_.isString(arguments[i]) && indices.indexOf(i) === -1) {
+ args[i] = encodeURIComponent(arguments[i]);
+ } else {
+ args[i] = arguments[i];
+ }
+ }
+
+ const result = originalMethod.apply(this, args);
+ return result;
+ };
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/autofocus.directive.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/autofocus.directive.spec.ts
new file mode 100644
index 000000000..9ef2078ec
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/autofocus.directive.spec.ts
@@ -0,0 +1,90 @@
+import { Component } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { AutofocusDirective } from './autofocus.directive';
+
+@Component({
+ template: `
+ <form>
+ <input id="x" type="text" />
+ <input id="y" type="password" autofocus />
+ </form>
+ `
+})
+export class PasswordFormComponent {}
+
+@Component({
+ template: `
+ <form>
+ <input id="x" type="checkbox" [autofocus]="edit" />
+ <input id="y" type="text" />
+ </form>
+ `
+})
+export class CheckboxFormComponent {
+ public edit = true;
+}
+
+@Component({
+ template: `
+ <form>
+ <input id="x" type="text" [autofocus]="foo" />
+ </form>
+ `
+})
+export class TextFormComponent {
+ foo() {
+ return false;
+ }
+}
+
+describe('AutofocusDirective', () => {
+ configureTestBed({
+ declarations: [
+ AutofocusDirective,
+ CheckboxFormComponent,
+ PasswordFormComponent,
+ TextFormComponent
+ ]
+ });
+
+ it('should create an instance', () => {
+ const directive = new AutofocusDirective(null);
+ expect(directive).toBeTruthy();
+ });
+
+ it('should focus the password form field', () => {
+ const fixture: ComponentFixture<PasswordFormComponent> = TestBed.createComponent(
+ PasswordFormComponent
+ );
+ fixture.detectChanges();
+ const focused = fixture.debugElement.query(By.css(':focus'));
+ expect(focused.attributes.id).toBe('y');
+ expect(focused.attributes.type).toBe('password');
+ const element = document.getElementById('y');
+ expect(element === document.activeElement).toBeTruthy();
+ });
+
+ it('should focus the checkbox form field', () => {
+ const fixture: ComponentFixture<CheckboxFormComponent> = TestBed.createComponent(
+ CheckboxFormComponent
+ );
+ fixture.detectChanges();
+ const focused = fixture.debugElement.query(By.css(':focus'));
+ expect(focused.attributes.id).toBe('x');
+ expect(focused.attributes.type).toBe('checkbox');
+ const element = document.getElementById('x');
+ expect(element === document.activeElement).toBeTruthy();
+ });
+
+ it('should not focus the text form field', () => {
+ const fixture: ComponentFixture<TextFormComponent> = TestBed.createComponent(TextFormComponent);
+ fixture.detectChanges();
+ const focused = fixture.debugElement.query(By.css(':focus'));
+ expect(focused).toBeNull();
+ const element = document.getElementById('x');
+ expect(element !== document.activeElement).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/autofocus.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/autofocus.directive.ts
new file mode 100644
index 000000000..dc34b9f3c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/autofocus.directive.ts
@@ -0,0 +1,28 @@
+import { AfterViewInit, Directive, ElementRef, Input } from '@angular/core';
+
+import _ from 'lodash';
+
+@Directive({
+ selector: '[autofocus]' // tslint:disable-line
+})
+export class AutofocusDirective implements AfterViewInit {
+ private focus = true;
+
+ constructor(private elementRef: ElementRef) {}
+
+ ngAfterViewInit() {
+ const el: HTMLInputElement = this.elementRef.nativeElement;
+ if (this.focus && _.isFunction(el.focus)) {
+ el.focus();
+ }
+ }
+
+ @Input()
+ public set autofocus(condition: any) {
+ if (_.isBoolean(condition)) {
+ this.focus = condition;
+ } else if (_.isFunction(condition)) {
+ this.focus = condition();
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.spec.ts
new file mode 100644
index 000000000..858becc45
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.spec.ts
@@ -0,0 +1,12 @@
+import { DimlessBinaryPerSecondDirective } from './dimless-binary-per-second.directive';
+
+export class MockElementRef {
+ nativeElement: {};
+}
+
+describe('DimlessBinaryPerSecondDirective', () => {
+ it('should create an instance', () => {
+ const directive = new DimlessBinaryPerSecondDirective(new MockElementRef(), null, null, null);
+ expect(directive).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.ts
new file mode 100644
index 000000000..a90e2b8f8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.ts
@@ -0,0 +1,132 @@
+import {
+ Directive,
+ ElementRef,
+ EventEmitter,
+ HostListener,
+ Input,
+ OnInit,
+ Output
+} from '@angular/core';
+import { NgControl } from '@angular/forms';
+
+import _ from 'lodash';
+
+import { DimlessBinaryPerSecondPipe } from '../pipes/dimless-binary-per-second.pipe';
+import { FormatterService } from '../services/formatter.service';
+
+@Directive({
+ selector: '[cdDimlessBinaryPerSecond]'
+})
+export class DimlessBinaryPerSecondDirective implements OnInit {
+ @Output()
+ ngModelChange: EventEmitter<any> = new EventEmitter();
+
+ /**
+ * Event emitter for letting this directive know that the data has (asynchronously) been loaded
+ * and the value needs to be adapted by this directive.
+ */
+ @Input()
+ ngDataReady: EventEmitter<any>;
+
+ /**
+ * Minimum size in bytes.
+ * If user enter a value lower than <minBytes>,
+ * the model will automatically be update to <minBytes>.
+ *
+ * If <roundPower> is used, this value should be a power of <roundPower>.
+ *
+ * Example:
+ * Given minBytes=4096 (4KiB), if user type 1KiB, then model will be updated to 4KiB
+ */
+ @Input()
+ minBytes: number;
+
+ /**
+ * Maximum size in bytes.
+ * If user enter a value greater than <maxBytes>,
+ * the model will automatically be update to <maxBytes>.
+ *
+ * If <roundPower> is used, this value should be a power of <roundPower>.
+ *
+ * Example:
+ * Given maxBytes=3145728 (3MiB), if user type 4MiB, then model will be updated to 3MiB
+ */
+ @Input()
+ maxBytes: number;
+
+ /**
+ * Value will be rounded up the nearest power of <roundPower>
+ *
+ * Example:
+ * Given roundPower=2, if user type 7KiB, then model will be updated to 8KiB
+ * Given roundPower=2, if user type 5KiB, then model will be updated to 4KiB
+ */
+ @Input()
+ roundPower: number;
+
+ /**
+ * Default unit that should be used when user do not type a unit.
+ * By default, "MiB" will be used.
+ *
+ * Example:
+ * Given defaultUnit=null, if user type 7, then model will be updated to 7MiB
+ * Given defaultUnit=k, if user type 7, then model will be updated to 7KiB
+ */
+ @Input()
+ defaultUnit: string;
+
+ private el: HTMLInputElement;
+
+ constructor(
+ private elementRef: ElementRef,
+ private control: NgControl,
+ private dimlessBinaryPerSecondPipe: DimlessBinaryPerSecondPipe,
+ private formatter: FormatterService
+ ) {
+ this.el = this.elementRef.nativeElement;
+ }
+
+ ngOnInit() {
+ this.setValue(this.el.value);
+ if (this.ngDataReady) {
+ this.ngDataReady.subscribe(() => this.setValue(this.el.value));
+ }
+ }
+
+ setValue(value: string) {
+ if (/^[\d.]+$/.test(value)) {
+ value += this.defaultUnit || 'm';
+ }
+ const size = this.formatter.toBytes(value, 0);
+ const roundedSize = this.round(size);
+ this.el.value = this.dimlessBinaryPerSecondPipe.transform(roundedSize);
+ if (size !== null) {
+ this.ngModelChange.emit(this.el.value);
+ this.control.control.setValue(this.el.value);
+ } else {
+ this.ngModelChange.emit(null);
+ this.control.control.setValue(null);
+ }
+ }
+
+ round(size: number) {
+ if (size !== null && size !== 0) {
+ if (!_.isUndefined(this.minBytes) && size < this.minBytes) {
+ return this.minBytes;
+ }
+ if (!_.isUndefined(this.maxBytes) && size > this.maxBytes) {
+ return this.maxBytes;
+ }
+ if (!_.isUndefined(this.roundPower)) {
+ const power = Math.round(Math.log(size) / Math.log(this.roundPower));
+ return Math.pow(this.roundPower, power);
+ }
+ }
+ return size;
+ }
+
+ @HostListener('blur', ['$event.target.value'])
+ onBlur(value: string) {
+ this.setValue(value);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary.directive.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary.directive.spec.ts
new file mode 100644
index 000000000..5822e7d97
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary.directive.spec.ts
@@ -0,0 +1,12 @@
+import { DimlessBinaryDirective } from './dimless-binary.directive';
+
+export class MockElementRef {
+ nativeElement: {};
+}
+
+describe('DimlessBinaryDirective', () => {
+ it('should create an instance', () => {
+ const directive = new DimlessBinaryDirective(new MockElementRef(), null, null, null);
+ expect(directive).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary.directive.ts
new file mode 100644
index 000000000..1c27ae1ce
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary.directive.ts
@@ -0,0 +1,122 @@
+import {
+ Directive,
+ ElementRef,
+ EventEmitter,
+ HostListener,
+ Input,
+ OnInit,
+ Output
+} from '@angular/core';
+import { NgControl } from '@angular/forms';
+
+import _ from 'lodash';
+
+import { DimlessBinaryPipe } from '../pipes/dimless-binary.pipe';
+import { FormatterService } from '../services/formatter.service';
+
+@Directive({
+ selector: '[cdDimlessBinary]'
+})
+export class DimlessBinaryDirective implements OnInit {
+ @Output()
+ ngModelChange: EventEmitter<any> = new EventEmitter();
+
+ /**
+ * Minimum size in bytes.
+ * If user enter a value lower than <minBytes>,
+ * the model will automatically be update to <minBytes>.
+ *
+ * If <roundPower> is used, this value should be a power of <roundPower>.
+ *
+ * Example:
+ * Given minBytes=4096 (4KiB), if user type 1KiB, then model will be updated to 4KiB
+ */
+ @Input()
+ minBytes: number;
+
+ /**
+ * Maximum size in bytes.
+ * If user enter a value greater than <maxBytes>,
+ * the model will automatically be update to <maxBytes>.
+ *
+ * If <roundPower> is used, this value should be a power of <roundPower>.
+ *
+ * Example:
+ * Given maxBytes=3145728 (3MiB), if user type 4MiB, then model will be updated to 3MiB
+ */
+ @Input()
+ maxBytes: number;
+
+ /**
+ * Value will be rounded up the nearest power of <roundPower>
+ *
+ * Example:
+ * Given roundPower=2, if user type 7KiB, then model will be updated to 8KiB
+ * Given roundPower=2, if user type 5KiB, then model will be updated to 4KiB
+ */
+ @Input()
+ roundPower: number;
+
+ /**
+ * Default unit that should be used when user do not type a unit.
+ * By default, "MiB" will be used.
+ *
+ * Example:
+ * Given defaultUnit=null, if user type 7, then model will be updated to 7MiB
+ * Given defaultUnit=k, if user type 7, then model will be updated to 7KiB
+ */
+ @Input()
+ defaultUnit: string;
+
+ private el: HTMLInputElement;
+
+ constructor(
+ private elementRef: ElementRef,
+ private control: NgControl,
+ private dimlessBinaryPipe: DimlessBinaryPipe,
+ private formatter: FormatterService
+ ) {
+ this.el = this.elementRef.nativeElement;
+ }
+
+ ngOnInit() {
+ this.setValue(this.el.value);
+ }
+
+ setValue(value: string) {
+ if (/^[\d.]+$/.test(value)) {
+ value += this.defaultUnit || 'm';
+ }
+ const size = this.formatter.toBytes(value);
+ const roundedSize = this.round(size);
+ this.el.value = this.dimlessBinaryPipe.transform(roundedSize);
+ if (size !== null) {
+ this.ngModelChange.emit(this.el.value);
+ this.control.control.setValue(this.el.value);
+ } else {
+ this.ngModelChange.emit(null);
+ this.control.control.setValue(null);
+ }
+ }
+
+ round(size: number) {
+ if (size !== null && size !== 0) {
+ if (!_.isUndefined(this.minBytes) && size < this.minBytes) {
+ return this.minBytes;
+ }
+ if (!_.isUndefined(this.maxBytes) && size > this.maxBytes) {
+ return this.maxBytes;
+ }
+ if (!_.isUndefined(this.roundPower)) {
+ const power = Math.round(Math.log(size) / Math.log(this.roundPower));
+ return Math.pow(this.roundPower, power);
+ }
+ }
+ return size;
+ }
+
+ @HostListener('blur', ['$event.target.value'])
+ onBlur(value: string) {
+ this.setValue(value);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/directives.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/directives.module.ts
new file mode 100644
index 000000000..00e5635d3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/directives.module.ts
@@ -0,0 +1,53 @@
+import { NgModule } from '@angular/core';
+
+import { AutofocusDirective } from './autofocus.directive';
+import { DimlessBinaryPerSecondDirective } from './dimless-binary-per-second.directive';
+import { DimlessBinaryDirective } from './dimless-binary.directive';
+import { FormInputDisableDirective } from './form-input-disable.directive';
+import { FormLoadingDirective } from './form-loading.directive';
+import { FormScopeDirective } from './form-scope.directive';
+import { IopsDirective } from './iops.directive';
+import { MillisecondsDirective } from './milliseconds.directive';
+import { CdFormControlDirective } from './ng-bootstrap-form-validation/cd-form-control.directive';
+import { CdFormGroupDirective } from './ng-bootstrap-form-validation/cd-form-group.directive';
+import { CdFormValidationDirective } from './ng-bootstrap-form-validation/cd-form-validation.directive';
+import { PasswordButtonDirective } from './password-button.directive';
+import { StatefulTabDirective } from './stateful-tab.directive';
+import { TrimDirective } from './trim.directive';
+
+@NgModule({
+ imports: [],
+ declarations: [
+ AutofocusDirective,
+ DimlessBinaryDirective,
+ DimlessBinaryPerSecondDirective,
+ PasswordButtonDirective,
+ TrimDirective,
+ MillisecondsDirective,
+ IopsDirective,
+ FormLoadingDirective,
+ StatefulTabDirective,
+ FormInputDisableDirective,
+ FormScopeDirective,
+ CdFormControlDirective,
+ CdFormGroupDirective,
+ CdFormValidationDirective
+ ],
+ exports: [
+ AutofocusDirective,
+ DimlessBinaryDirective,
+ DimlessBinaryPerSecondDirective,
+ PasswordButtonDirective,
+ TrimDirective,
+ MillisecondsDirective,
+ IopsDirective,
+ FormLoadingDirective,
+ StatefulTabDirective,
+ FormInputDisableDirective,
+ FormScopeDirective,
+ CdFormControlDirective,
+ CdFormGroupDirective,
+ CdFormValidationDirective
+ ]
+})
+export class DirectivesModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.spec.ts
new file mode 100644
index 000000000..a79043b78
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.spec.ts
@@ -0,0 +1,75 @@
+import { Component, DebugElement, Input } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { Permission } from '../models/permissions';
+import { AuthStorageService } from '../services/auth-storage.service';
+import { FormInputDisableDirective } from './form-input-disable.directive';
+import { FormScopeDirective } from './form-scope.directive';
+
+@Component({
+ template: `
+ <form cdFormScope="osd">
+ <input type="checkbox" />
+ </form>
+ `
+})
+export class FormDisableComponent {}
+
+class MockFormScopeDirective {
+ @Input() cdFormScope = 'osd';
+}
+
+describe('FormInputDisableDirective', () => {
+ let fakePermissions: Permission;
+ let authStorageService: AuthStorageService;
+ let directive: FormInputDisableDirective;
+ let fixture: ComponentFixture<FormDisableComponent>;
+ let inputElement: DebugElement;
+ configureTestBed({
+ declarations: [FormScopeDirective, FormInputDisableDirective, FormDisableComponent]
+ });
+
+ beforeEach(() => {
+ directive = new FormInputDisableDirective(
+ new MockFormScopeDirective(),
+ new AuthStorageService(),
+ null
+ );
+
+ fakePermissions = {
+ create: false,
+ update: false,
+ read: false,
+ delete: false
+ };
+ authStorageService = TestBed.inject(AuthStorageService);
+ spyOn(authStorageService, 'getPermissions').and.callFake(() => ({
+ osd: fakePermissions
+ }));
+
+ fixture = TestBed.createComponent(FormDisableComponent);
+ inputElement = fixture.debugElement.query(By.css('input'));
+ });
+
+ afterEach(() => {
+ directive = null;
+ });
+
+ it('should create an instance', () => {
+ expect(directive).toBeTruthy();
+ });
+
+ it('should disable the input if update permission is false', () => {
+ fixture.detectChanges();
+ expect(inputElement.nativeElement.disabled).toBeTruthy();
+ });
+
+ it('should not disable the input if update permission is true', () => {
+ fakePermissions.update = true;
+ fakePermissions.read = false;
+ fixture.detectChanges();
+ expect(inputElement.nativeElement.disabled).toBeFalsy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.ts
new file mode 100644
index 000000000..3e3f83bc5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.ts
@@ -0,0 +1,27 @@
+import { AfterViewInit, Directive, ElementRef, Optional } from '@angular/core';
+
+import { Permissions } from '../models/permissions';
+import { AuthStorageService } from '../services/auth-storage.service';
+import { FormScopeDirective } from './form-scope.directive';
+
+@Directive({
+ selector:
+ 'input:not([cdNoFormInputDisable]), select:not([cdNoFormInputDisable]), button:not([cdNoFormInputDisable]), [cdFormInputDisable]'
+})
+export class FormInputDisableDirective implements AfterViewInit {
+ permissions: Permissions;
+
+ constructor(
+ @Optional() private formScope: FormScopeDirective,
+ private authStorageService: AuthStorageService,
+ private elementRef: ElementRef
+ ) {}
+
+ ngAfterViewInit() {
+ this.permissions = this.authStorageService.getPermissions();
+ const service_name = this.formScope?.cdFormScope;
+ if (service_name && !this.permissions?.[service_name]?.update) {
+ this.elementRef.nativeElement.disabled = true;
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-loading.directive.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-loading.directive.spec.ts
new file mode 100644
index 000000000..8bc3b05a2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-loading.directive.spec.ts
@@ -0,0 +1,89 @@
+import { Component } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+
+import { NgbAlertModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { AlertPanelComponent } from '../components/alert-panel/alert-panel.component';
+import { LoadingPanelComponent } from '../components/loading-panel/loading-panel.component';
+import { CdForm } from '../forms/cd-form';
+import { SharedModule } from '../shared.module';
+import { FormLoadingDirective } from './form-loading.directive';
+
+@Component({ selector: 'cd-test-cmp', template: '<span *cdFormLoading="loading">foo</span>' })
+class TestComponent extends CdForm {
+ constructor() {
+ super();
+ }
+}
+
+describe('FormLoadingDirective', () => {
+ let component: TestComponent;
+ let fixture: ComponentFixture<any>;
+
+ const expectShown = (elem: number, error: number, loading: number) => {
+ expect(fixture.debugElement.queryAll(By.css('span')).length).toEqual(elem);
+ expect(fixture.debugElement.queryAll(By.css('cd-alert-panel')).length).toEqual(error);
+ expect(fixture.debugElement.queryAll(By.css('cd-loading-panel')).length).toEqual(loading);
+ };
+
+ configureTestBed(
+ {
+ declarations: [TestComponent],
+ imports: [SharedModule, NgbAlertModule]
+ },
+ [LoadingPanelComponent, AlertPanelComponent]
+ );
+
+ afterEach(() => {
+ fixture = null;
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TestComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create an instance', () => {
+ const directive = new FormLoadingDirective(null, null, null);
+ expect(directive).toBeTruthy();
+ });
+
+ it('should show loading component by default', () => {
+ expectShown(0, 0, 1);
+
+ const alert = fixture.debugElement.nativeElement.querySelector('cd-loading-panel ngb-alert');
+ expect(alert.textContent).toBe('Loading form data...');
+ });
+
+ it('should show error component when calling loadingError()', () => {
+ component.loadingError();
+ fixture.detectChanges();
+
+ expectShown(0, 1, 0);
+
+ const alert = fixture.debugElement.nativeElement.querySelector(
+ 'cd-alert-panel .alert-panel-text'
+ );
+ expect(alert.textContent).toBe('Form data could not be loaded.');
+ });
+
+ it('should show original component when calling loadingReady()', () => {
+ component.loadingReady();
+ fixture.detectChanges();
+
+ expectShown(1, 0, 0);
+
+ const alert = fixture.debugElement.nativeElement.querySelector('span');
+ expect(alert.textContent).toBe('foo');
+ });
+
+ it('should show nothing when calling loadingNone()', () => {
+ component.loadingNone();
+ fixture.detectChanges();
+
+ expectShown(0, 0, 0);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-loading.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-loading.directive.ts
new file mode 100644
index 000000000..e83614b84
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-loading.directive.ts
@@ -0,0 +1,51 @@
+import {
+ ComponentFactoryResolver,
+ Directive,
+ Input,
+ TemplateRef,
+ ViewContainerRef
+} from '@angular/core';
+
+import { AlertPanelComponent } from '../components/alert-panel/alert-panel.component';
+import { LoadingPanelComponent } from '../components/loading-panel/loading-panel.component';
+import { LoadingStatus } from '../forms/cd-form';
+
+@Directive({
+ selector: '[cdFormLoading]'
+})
+export class FormLoadingDirective {
+ constructor(
+ private templateRef: TemplateRef<any>,
+ private viewContainer: ViewContainerRef,
+ private componentFactoryResolver: ComponentFactoryResolver
+ ) {}
+
+ @Input('cdFormLoading') set cdFormLoading(condition: LoadingStatus) {
+ let factory: any;
+ let content: any;
+
+ this.viewContainer.clear();
+
+ switch (condition) {
+ case LoadingStatus.Loading:
+ factory = this.componentFactoryResolver.resolveComponentFactory(LoadingPanelComponent);
+ content = this.resolveNgContent($localize`Loading form data...`);
+ this.viewContainer.createComponent(factory, null, null, content);
+ break;
+ case LoadingStatus.Ready:
+ this.viewContainer.createEmbeddedView(this.templateRef);
+ break;
+ case LoadingStatus.Error:
+ factory = this.componentFactoryResolver.resolveComponentFactory(AlertPanelComponent);
+ content = this.resolveNgContent($localize`Form data could not be loaded.`);
+ const componentRef = this.viewContainer.createComponent(factory, null, null, content);
+ (<AlertPanelComponent>componentRef.instance).type = 'error';
+ break;
+ }
+ }
+
+ resolveNgContent(content: string) {
+ const element = document.createTextNode(content);
+ return [[element]];
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-scope.directive.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-scope.directive.spec.ts
new file mode 100644
index 000000000..2cf882ece
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-scope.directive.spec.ts
@@ -0,0 +1,8 @@
+import { FormScopeDirective } from './form-scope.directive';
+
+describe('UpdateOnlyDirective', () => {
+ it('should create an instance', () => {
+ const directive = new FormScopeDirective();
+ expect(directive).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-scope.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-scope.directive.ts
new file mode 100644
index 000000000..8ae3f8489
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-scope.directive.ts
@@ -0,0 +1,8 @@
+import { Directive, Input } from '@angular/core';
+
+@Directive({
+ selector: '[cdFormScope]'
+})
+export class FormScopeDirective {
+ @Input() cdFormScope: any;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/iops.directive.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/iops.directive.spec.ts
new file mode 100644
index 000000000..9c1641ded
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/iops.directive.spec.ts
@@ -0,0 +1,8 @@
+import { IopsDirective } from './iops.directive';
+
+describe('IopsDirective', () => {
+ it('should create an instance', () => {
+ const directive = new IopsDirective(null, null);
+ expect(directive).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/iops.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/iops.directive.ts
new file mode 100644
index 000000000..4faf69164
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/iops.directive.ts
@@ -0,0 +1,31 @@
+import { Directive, EventEmitter, HostListener, Input, OnInit } from '@angular/core';
+import { NgControl } from '@angular/forms';
+
+import { FormatterService } from '../services/formatter.service';
+
+@Directive({
+ selector: '[cdIops]'
+})
+export class IopsDirective implements OnInit {
+ @Input()
+ ngDataReady: EventEmitter<any>;
+
+ constructor(private formatter: FormatterService, private ngControl: NgControl) {}
+
+ setValue(value: string): void {
+ const iops = this.formatter.toIops(value);
+ this.ngControl.control.setValue(`${iops} IOPS`);
+ }
+
+ ngOnInit(): void {
+ this.setValue(this.ngControl.value);
+ if (this.ngDataReady) {
+ this.ngDataReady.subscribe(() => this.setValue(this.ngControl.value));
+ }
+ }
+
+ @HostListener('blur', ['$event.target.value'])
+ onUpdate(value: string) {
+ this.setValue(value);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/milliseconds.directive.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/milliseconds.directive.spec.ts
new file mode 100644
index 000000000..503802056
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/milliseconds.directive.spec.ts
@@ -0,0 +1,8 @@
+import { MillisecondsDirective } from './milliseconds.directive';
+
+describe('MillisecondsDirective', () => {
+ it('should create an instance', () => {
+ const directive = new MillisecondsDirective(null, null);
+ expect(directive).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/milliseconds.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/milliseconds.directive.ts
new file mode 100644
index 000000000..d5bb4aff5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/milliseconds.directive.ts
@@ -0,0 +1,31 @@
+import { Directive, EventEmitter, HostListener, Input, OnInit } from '@angular/core';
+import { NgControl } from '@angular/forms';
+
+import { FormatterService } from '../services/formatter.service';
+
+@Directive({
+ selector: '[cdMilliseconds]'
+})
+export class MillisecondsDirective implements OnInit {
+ @Input()
+ ngDataReady: EventEmitter<any>;
+
+ constructor(private control: NgControl, private formatter: FormatterService) {}
+
+ setValue(value: string): void {
+ const ms = this.formatter.toMilliseconds(value);
+ this.control.control.setValue(`${ms} ms`);
+ }
+
+ ngOnInit(): void {
+ this.setValue(this.control.value);
+ if (this.ngDataReady) {
+ this.ngDataReady.subscribe(() => this.setValue(this.control.value));
+ }
+ }
+
+ @HostListener('blur', ['$event.target.value'])
+ onUpdate(value: string) {
+ this.setValue(value);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-control.directive.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-control.directive.spec.ts
new file mode 100644
index 000000000..dd588ae7b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-control.directive.spec.ts
@@ -0,0 +1,37 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2017 Kevin Kipp
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ *
+ * Based on https://github.com/third774/ng-bootstrap-form-validation
+ */
+
+import { NgForm } from '@angular/forms';
+
+import { CdFormControlDirective } from './cd-form-control.directive';
+
+describe('CdFormControlDirective', () => {
+ it('should create an instance', () => {
+ const directive = new CdFormControlDirective(new NgForm([], []));
+ expect(directive).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-control.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-control.directive.ts
new file mode 100644
index 000000000..86afc72a5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-control.directive.ts
@@ -0,0 +1,82 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2017 Kevin Kipp
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ *
+ * Based on https://github.com/third774/ng-bootstrap-form-validation
+ */
+
+import { Directive, Host, HostBinding, Input, Optional, SkipSelf } from '@angular/core';
+import { ControlContainer, FormControl } from '@angular/forms';
+
+export function controlPath(name: string, parent: ControlContainer): string[] {
+ // tslint:disable-next-line:no-non-null-assertion
+ return [...parent.path!, name];
+}
+
+@Directive({
+ // tslint:disable-next-line:directive-selector
+ selector: '.form-control,.form-check-input,.custom-control-input'
+})
+export class CdFormControlDirective {
+ @Input()
+ formControlName: string;
+ @Input()
+ formControl: string;
+
+ @HostBinding('class.is-valid')
+ get validClass() {
+ if (!this.control) {
+ return false;
+ }
+ return this.control.valid && (this.control.touched || this.control.dirty);
+ }
+
+ @HostBinding('class.is-invalid')
+ get invalidClass() {
+ if (!this.control) {
+ return false;
+ }
+ return this.control.invalid && this.control.touched && this.control.dirty;
+ }
+
+ get path() {
+ return controlPath(this.formControlName, this.parent);
+ }
+
+ get control(): FormControl {
+ return this.formDirective && this.formDirective.getControl(this);
+ }
+
+ get formDirective(): any {
+ return this.parent ? this.parent.formDirective : null;
+ }
+
+ constructor(
+ // this value might be null, but we union type it as such until
+ // this issue is resolved: https://github.com/angular/angular/issues/25544
+ @Optional()
+ @Host()
+ @SkipSelf()
+ private parent: ControlContainer
+ ) {}
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-group.directive.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-group.directive.spec.ts
new file mode 100644
index 000000000..40aa251cd
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-group.directive.spec.ts
@@ -0,0 +1,37 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2017 Kevin Kipp
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ *
+ * Based on https://github.com/third774/ng-bootstrap-form-validation
+ */
+
+import { ElementRef } from '@angular/core';
+
+import { CdFormGroupDirective } from './cd-form-group.directive';
+
+describe('CdFormGroupDirective', () => {
+ it('should create an instance', () => {
+ const directive = new CdFormGroupDirective(new ElementRef(null));
+ expect(directive).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-group.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-group.directive.ts
new file mode 100644
index 000000000..5f6b11de1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-group.directive.ts
@@ -0,0 +1,76 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2017 Kevin Kipp
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ *
+ * Based on https://github.com/third774/ng-bootstrap-form-validation
+ */
+
+import {
+ ContentChildren,
+ Directive,
+ ElementRef,
+ HostBinding,
+ Input,
+ QueryList
+} from '@angular/core';
+import { FormControlName } from '@angular/forms';
+
+@Directive({
+ // tslint:disable-next-line:directive-selector
+ selector: '.form-group'
+})
+export class CdFormGroupDirective {
+ @ContentChildren(FormControlName)
+ formControlNames: QueryList<FormControlName>;
+
+ @Input()
+ validationDisabled = false;
+
+ @HostBinding('class.has-error')
+ get hasErrors() {
+ return (
+ this.formControlNames.some((c) => !c.valid && c.dirty && c.touched) &&
+ !this.validationDisabled
+ );
+ }
+
+ @HostBinding('class.has-success')
+ get hasSuccess() {
+ return (
+ !this.formControlNames.some((c) => !c.valid) &&
+ this.formControlNames.some((c) => c.dirty && c.touched) &&
+ !this.validationDisabled
+ );
+ }
+
+ constructor(private elRef: ElementRef) {}
+
+ get label() {
+ const label = this.elRef.nativeElement.querySelector('label');
+ return label && label.textContent ? label.textContent.trim() : 'This field';
+ }
+
+ get isDirtyAndTouched() {
+ return this.formControlNames.some((c) => c.dirty && c.touched);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-validation.directive.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-validation.directive.spec.ts
new file mode 100644
index 000000000..c4b0f424b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-validation.directive.spec.ts
@@ -0,0 +1,35 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2017 Kevin Kipp
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ *
+ * Based on https://github.com/third774/ng-bootstrap-form-validation
+ */
+
+import { CdFormValidationDirective } from './cd-form-validation.directive';
+
+describe('CdFormValidationDirective', () => {
+ it('should create an instance', () => {
+ const directive = new CdFormValidationDirective();
+ expect(directive).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-validation.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-validation.directive.ts
new file mode 100644
index 000000000..a88011d35
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/ng-bootstrap-form-validation/cd-form-validation.directive.ts
@@ -0,0 +1,62 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2017 Kevin Kipp
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ *
+ * Based on https://github.com/third774/ng-bootstrap-form-validation
+ */
+
+import { Directive, EventEmitter, HostListener, Input, Output } from '@angular/core';
+import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms';
+
+@Directive({
+ // tslint:disable-next-line:directive-selector
+ selector: '[formGroup]'
+})
+export class CdFormValidationDirective {
+ @Input()
+ formGroup: FormGroup;
+ @Output()
+ validSubmit = new EventEmitter<any>();
+
+ @HostListener('submit')
+ onSubmit() {
+ this.markAsTouchedAndDirty(this.formGroup);
+ if (this.formGroup.valid) {
+ this.validSubmit.emit(this.formGroup.value);
+ }
+ }
+
+ markAsTouchedAndDirty(control: AbstractControl) {
+ if (control instanceof FormGroup) {
+ Object.keys(control.controls).forEach((key) =>
+ this.markAsTouchedAndDirty(control.controls[key])
+ );
+ } else if (control instanceof FormArray) {
+ control.controls.forEach((c) => this.markAsTouchedAndDirty(c));
+ } else if (control instanceof FormControl && control.enabled) {
+ control.markAsDirty();
+ control.markAsTouched();
+ control.updateValueAndValidity();
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/password-button.directive.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/password-button.directive.spec.ts
new file mode 100644
index 000000000..1fc8f9c7c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/password-button.directive.spec.ts
@@ -0,0 +1,8 @@
+import { PasswordButtonDirective } from './password-button.directive';
+
+describe('PasswordButtonDirective', () => {
+ it('should create an instance', () => {
+ const directive = new PasswordButtonDirective(null, null);
+ expect(directive).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/password-button.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/password-button.directive.ts
new file mode 100644
index 000000000..d9129858a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/password-button.directive.ts
@@ -0,0 +1,45 @@
+import { Directive, ElementRef, HostListener, Input, OnInit, Renderer2 } from '@angular/core';
+
+@Directive({
+ selector: '[cdPasswordButton]'
+})
+export class PasswordButtonDirective implements OnInit {
+ private iElement: HTMLElement;
+
+ @Input()
+ private cdPasswordButton: string;
+
+ constructor(private elementRef: ElementRef, private renderer: Renderer2) {}
+
+ ngOnInit() {
+ this.renderer.setAttribute(this.elementRef.nativeElement, 'tabindex', '-1');
+ this.iElement = this.renderer.createElement('i');
+ this.renderer.addClass(this.iElement, 'fa');
+ this.renderer.appendChild(this.elementRef.nativeElement, this.iElement);
+ this.update();
+ }
+
+ private getInputElement() {
+ return document.getElementById(this.cdPasswordButton) as HTMLInputElement;
+ }
+
+ private update() {
+ const inputElement = this.getInputElement();
+ if (inputElement && inputElement.type === 'text') {
+ this.renderer.removeClass(this.iElement, 'fa-eye');
+ this.renderer.addClass(this.iElement, 'fa-eye-slash');
+ } else {
+ this.renderer.removeClass(this.iElement, 'fa-eye-slash');
+ this.renderer.addClass(this.iElement, 'fa-eye');
+ }
+ }
+
+ @HostListener('click')
+ onClick() {
+ const inputElement = this.getInputElement();
+ // Modify the type of the input field.
+ inputElement.type = inputElement.type === 'password' ? 'text' : 'password';
+ // Update the button icon/tooltip.
+ this.update();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/stateful-tab.directive.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/stateful-tab.directive.spec.ts
new file mode 100644
index 000000000..5cebefbc9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/stateful-tab.directive.spec.ts
@@ -0,0 +1,28 @@
+import { NgbConfig, NgbNav, NgbNavChangeEvent, NgbNavConfig } from '@ng-bootstrap/ng-bootstrap';
+
+import { StatefulTabDirective } from './stateful-tab.directive';
+
+describe('StatefulTabDirective', () => {
+ it('should create an instance', () => {
+ const directive = new StatefulTabDirective(null);
+ expect(directive).toBeTruthy();
+ });
+
+ it('should get and select active tab', () => {
+ const nav = new NgbNav('tablist', new NgbNavConfig(new NgbConfig()), <any>null, null);
+ spyOn(nav, 'select');
+ const directive = new StatefulTabDirective(nav);
+ directive.cdStatefulTab = 'bar';
+ window.localStorage.setItem('tabset_bar', 'foo');
+ directive.ngOnInit();
+ expect(nav.select).toHaveBeenCalledWith('foo');
+ });
+
+ it('should store active tab', () => {
+ const directive = new StatefulTabDirective(null);
+ directive.cdStatefulTab = 'bar';
+ const event: NgbNavChangeEvent<string> = { activeId: '', nextId: 'xyz', preventDefault: null };
+ directive.onNavChange(event);
+ expect(window.localStorage.getItem('tabset_bar')).toBe('xyz');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/stateful-tab.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/stateful-tab.directive.ts
new file mode 100644
index 000000000..cf6f27e95
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/stateful-tab.directive.ts
@@ -0,0 +1,31 @@
+import { Directive, Host, HostListener, Input, OnInit, Optional } from '@angular/core';
+
+import { NgbNav, NgbNavChangeEvent } from '@ng-bootstrap/ng-bootstrap';
+
+@Directive({
+ selector: '[cdStatefulTab]'
+})
+export class StatefulTabDirective implements OnInit {
+ @Input()
+ cdStatefulTab: string;
+
+ private localStorage = window.localStorage;
+
+ constructor(@Optional() @Host() private nav: NgbNav) {}
+
+ ngOnInit() {
+ // Is an activate tab identifier stored in the local storage?
+ const activeId = this.localStorage.getItem(`tabset_${this.cdStatefulTab}`);
+ if (activeId) {
+ this.nav.select(activeId);
+ }
+ }
+
+ @HostListener('navChange', ['$event'])
+ onNavChange(event: NgbNavChangeEvent) {
+ // Store the current active tab identifier in the local storage.
+ if (this.cdStatefulTab && event.nextId) {
+ this.localStorage.setItem(`tabset_${this.cdStatefulTab}`, event.nextId);
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/trim.directive.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/trim.directive.spec.ts
new file mode 100644
index 000000000..daef6b3c8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/trim.directive.spec.ts
@@ -0,0 +1,50 @@
+import { Component } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { By } from '@angular/platform-browser';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { CdFormGroup } from '../forms/cd-form-group';
+import { TrimDirective } from './trim.directive';
+
+@Component({
+ template: `
+ <form [formGroup]="trimForm">
+ <input type="text" formControlName="trimInput" cdTrim />
+ </form>
+ `
+})
+export class TrimComponent {
+ trimForm: CdFormGroup;
+ constructor() {
+ this.trimForm = new CdFormGroup({
+ trimInput: new FormControl()
+ });
+ }
+}
+
+describe('TrimDirective', () => {
+ configureTestBed({
+ imports: [FormsModule, ReactiveFormsModule],
+ declarations: [TrimDirective, TrimComponent]
+ });
+
+ it('should create an instance', () => {
+ const directive = new TrimDirective(null);
+ expect(directive).toBeTruthy();
+ });
+
+ it('should trim', () => {
+ const fixture: ComponentFixture<TrimComponent> = TestBed.createComponent(TrimComponent);
+ const component: TrimComponent = fixture.componentInstance;
+ const inputElement: HTMLInputElement = fixture.debugElement.query(By.css('input'))
+ .nativeElement;
+ fixture.detectChanges();
+
+ inputElement.value = ' a b ';
+ inputElement.dispatchEvent(new Event('input'));
+ const expectedValue = 'a b';
+ expect(inputElement.value).toBe(expectedValue);
+ expect(component.trimForm.getValue('trimInput')).toBe(expectedValue);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/trim.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/trim.directive.ts
new file mode 100644
index 000000000..4b3604e43
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/trim.directive.ts
@@ -0,0 +1,21 @@
+import { Directive, HostListener } from '@angular/core';
+import { NgControl } from '@angular/forms';
+
+import _ from 'lodash';
+
+@Directive({
+ selector: '[cdTrim]'
+})
+export class TrimDirective {
+ constructor(private ngControl: NgControl) {}
+
+ @HostListener('input', ['$event.target.value'])
+ onInput(value: string) {
+ this.setValue(value);
+ }
+
+ setValue(value: string): void {
+ value = _.isString(value) ? value.trim() : value;
+ this.ngControl.control.setValue(value);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/cell-template.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/cell-template.enum.ts
new file mode 100644
index 000000000..73ce1f239
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/cell-template.enum.ts
@@ -0,0 +1,54 @@
+export enum CellTemplate {
+ bold = 'bold',
+ sparkline = 'sparkline',
+ perSecond = 'perSecond',
+ checkIcon = 'checkIcon',
+ routerLink = 'routerLink',
+ // Display the cell with an executing state. The state can be set to the `cdExecuting`
+ // attribute of table rows.
+ // It supports an optional custom configuration:
+ // {
+ // ...
+ // cellTransformation: CellTemplate.executing,
+ // customTemplateConfig: {
+ // valueClass?: string; // Cell value classes.
+ // executingClass?: string; // Executing state classes.
+ // }
+ executing = 'executing',
+ classAdding = 'classAdding',
+ // Display the cell value as a badge. The template
+ // supports an optional custom configuration:
+ // {
+ // ...
+ // cellTransformation: CellTemplate.badge,
+ // customTemplateConfig: {
+ // class?: string; // Additional class name.
+ // prefix?: any; // Prefix of the value to be displayed.
+ // // 'map' and 'prefix' exclude each other.
+ // map?: {
+ // [key: any]: { value: any, class?: string }
+ // }
+ // }
+ // }
+ badge = 'badge',
+ // Maps the value using the given dictionary.
+ // {
+ // ...
+ // cellTransformation: CellTemplate.map,
+ // customTemplateConfig: {
+ // [key: any]: any
+ // }
+ // }
+ map = 'map',
+ // Truncates string if it's longer than the given maximum
+ // string length.
+ // {
+ // ...
+ // cellTransformation: CellTemplate.truncate,
+ // customTemplateConfig: {
+ // length?: number; // Defaults to 30.
+ // omission?: string; // Defaults to empty string.
+ // }
+ // }
+ truncate = 'truncate'
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/components.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/components.enum.ts
new file mode 100644
index 000000000..bf8daafc2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/components.enum.ts
@@ -0,0 +1,9 @@
+export enum Components {
+ auth = 'Login',
+ cephfs = 'CephFS',
+ rbd = 'RBD',
+ pool = 'Pool',
+ osd = 'OSD',
+ role = 'Role',
+ user = 'User'
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/health-color.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/health-color.enum.ts
new file mode 100644
index 000000000..042394225
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/health-color.enum.ts
@@ -0,0 +1,5 @@
+export enum HealthColor {
+ HEALTH_ERR = 'health-color-error',
+ HEALTH_WARN = 'health-color-warning',
+ HEALTH_OK = 'health-color-healthy'
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/icons.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/icons.enum.ts
new file mode 100644
index 000000000..6b65f04e8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/icons.enum.ts
@@ -0,0 +1,84 @@
+export enum Icons {
+ /* Icons for Symbol */
+ add = 'fa fa-plus', // Create, Add
+ addCircle = 'fa fa-plus-circle', // Plus with Circle
+ minusCircle = 'fa fa-minus-circle', // Minus with Circle
+ edit = 'fa fa-pencil', // Edit, Edit Mode, Rename
+ destroy = 'fa fa-times', // Destroy, Remove, Delete
+ destroyCircle = 'fa fa-times-circle', // Destroy, Remove, Delete
+ exchange = 'fa fa-exchange', // Edit-Peer
+ copy = 'fa fa-copy', // Copy
+ clipboard = 'fa fa-clipboard', // Clipboard
+ flatten = 'fa fa-chain-broken', // Flatten, Link broken, Mark Lost
+ trash = 'fa fa-trash-o', // Move to trash
+ lock = 'fa fa-lock', // Protect
+ unlock = 'fa fa-unlock', // Unprotect
+ clone = 'fa fa-clone', // clone
+ undo = 'fa fa-undo', // Rollback, Restore
+ search = 'fa fa-search', // Search
+ start = 'fa fa-play', // Enable
+ stop = 'fa fa-stop', // Disable
+ analyse = 'fa fa-stethoscope', // Scrub
+ deepCheck = 'fa fa-cog', // Deep Scrub, Setting, Configuration
+ reweight = 'fa fa-balance-scale', // Reweight
+ left = 'fa fa-arrow-left', // Mark out
+ right = 'fa fa-arrow-right', // Mark in
+ down = 'fa fa-arrow-down', // Mark Down
+ erase = 'fa fa-eraser', // Purge color: bd.$white;
+
+ user = 'fa fa-user', // User, Initiators
+ users = 'fa fa-users', // Users, Groups
+ share = 'fa fa-share-alt', // share
+ key = 'fa fa-key-modern', // S3 Keys, Swift Keys, Authentication
+ warning = 'fa fa-exclamation-triangle', // Notification warning
+ info = 'fa fa-info', // Notification information
+ infoCircle = 'fa fa-info-circle', // Info on landing page
+ questionCircle = 'fa fa-question-circle-o',
+ check = 'fa fa-check', // Notification check
+ show = 'fa fa-eye', // Show
+ paragraph = 'fa fa-paragraph', // Silence Matcher - Attribute name
+ terminal = 'fa fa-terminal', // Silence Matcher - Value
+ magic = 'fa fa-magic', // Silence Matcher - Regex checkbox
+ hourglass = 'fa fa-hourglass-o', // Task
+ filledHourglass = 'fa fa-hourglass', // Task
+ table = 'fa fa-table', // Table,
+ spinner = 'fa fa-spinner', // spinner, Load
+ refresh = 'fa fa-refresh', // Refresh
+ bullseye = 'fa fa-bullseye', // Target
+ disk = 'fa fa-hdd-o', // Hard disk, disks
+ server = 'fa fa-server', // Server, Portal
+ filter = 'fa fa-filter', // Filter
+ lineChart = 'fa fa-line-chart', // Line chart
+ signOut = 'fa fa-sign-out', // Sign Out
+ health = 'fa fa-heartbeat', // Health
+ circle = 'fa fa-circle', // Circle
+ bell = 'fa fa-bell', // Notification
+ tag = 'fa fa-tag', // Tag, Badge
+ leftArrow = 'fa fa-angle-left', // Left facing angle
+ rightArrow = 'fa fa-angle-right', // Right facing angle
+ leftArrowDouble = 'fa fa-angle-double-left', // Left facing Double angle
+ rightArrowDouble = 'fa fa-angle-double-right', // Left facing Double angle
+ flag = 'fa fa-flag', // OSD configuration
+ clearFilters = 'fa fa-window-close', // Clear filters, solid x
+ download = 'fa fa-download', // Download
+ upload = 'fa fa-upload', // Upload
+ close = 'fa fa-times', // Close
+ json = 'fa fa-file-code-o', // JSON file
+ text = 'fa fa-file-text', // Text file
+ wrench = 'fa fa-wrench', // Configuration Error
+ enter = 'fa fa-sign-in', // Enter
+ exit = 'fa fa-sign-out', // Exit
+ restart = 'fa fa-history', // Restart
+ deploy = 'fa fa-cube', // Deploy, Redeploy
+
+ /* Icons for special effect */
+ large = 'fa fa-lg', // icon becomes 33% larger
+ large2x = 'fa fa-2x', // icon becomes 50% larger
+ large3x = 'fa fa-3x', // icon becomes 3 times larger
+ stack = 'fa fa-stack', // To stack multiple icons
+ stack1x = 'fa fa-stack-1x', // To stack regularly sized icon
+ stack2x = 'fa fa-stack-2x', // To stack regularly sized icon
+ pulse = 'fa fa-pulse', // To have spinner rotate with 8 steps
+ spin = 'fa fa-spin', // To get any icon to rotate
+ inverse = 'fa fa-inverse' // To get an alternative icon color
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/notification-type.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/notification-type.enum.ts
new file mode 100644
index 000000000..c82929fb5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/notification-type.enum.ts
@@ -0,0 +1,5 @@
+export enum NotificationType {
+ error,
+ info,
+ success
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/unix_errno.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/unix_errno.enum.ts
new file mode 100644
index 000000000..98bcb689f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/unix_errno.enum.ts
@@ -0,0 +1,4 @@
+// http://www.virtsync.com/c-error-codes-include-errno
+export enum UnixErrno {
+ EEXIST = 17 // File exists
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/view-cache-status.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/view-cache-status.enum.ts
new file mode 100644
index 000000000..169059c44
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/view-cache-status.enum.ts
@@ -0,0 +1,6 @@
+export enum ViewCacheStatus {
+ ValueOk = 0,
+ ValueStale = 1,
+ ValueNone = 2,
+ ValueException = 3
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-builder.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-builder.spec.ts
new file mode 100644
index 000000000..188294b82
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-builder.spec.ts
@@ -0,0 +1,33 @@
+import { Validators } from '@angular/forms';
+
+import { CdFormBuilder } from './cd-form-builder';
+import { CdFormGroup } from './cd-form-group';
+
+describe('cd-form-builder', () => {
+ let service: CdFormBuilder;
+
+ beforeEach(() => {
+ service = new CdFormBuilder();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should create a nested CdFormGroup', () => {
+ const form = service.group({
+ nested: service.group({
+ a: [null],
+ b: ['sth'],
+ c: [2, [Validators.min(3)]]
+ }),
+ d: [{ e: 3 }],
+ f: [true]
+ });
+ expect(form.constructor).toBe(CdFormGroup);
+ expect(form instanceof CdFormGroup).toBeTruthy();
+ expect(form.getValue('b')).toBe('sth');
+ expect(form.getValue('d')).toEqual({ e: 3 });
+ expect(form.get('c').valid).toBeFalsy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-builder.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-builder.ts
new file mode 100644
index 000000000..9741b1e63
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-builder.ts
@@ -0,0 +1,20 @@
+import { Injectable } from '@angular/core';
+import { AbstractControlOptions, FormBuilder } from '@angular/forms';
+
+import { CdFormGroup } from './cd-form-group';
+
+/**
+ * CdFormBuilder extends FormBuilder to create an CdFormGroup based form.
+ */
+@Injectable({
+ providedIn: 'root'
+})
+export class CdFormBuilder extends FormBuilder {
+ group(
+ controlsConfig: { [key: string]: any },
+ extra: AbstractControlOptions | null = null
+ ): CdFormGroup {
+ const form = super.group(controlsConfig, extra);
+ return new CdFormGroup(form.controls, form.validator, form.asyncValidator);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-group.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-group.spec.ts
new file mode 100644
index 000000000..240da3af8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-group.spec.ts
@@ -0,0 +1,184 @@
+import { AbstractControl, FormControl, FormGroup, NgForm } from '@angular/forms';
+
+import { CdFormGroup } from './cd-form-group';
+
+describe('CdFormGroup', () => {
+ let form: CdFormGroup;
+
+ const createTestForm = (controlName: string, value: any): FormGroup =>
+ new FormGroup({
+ [controlName]: new FormControl(value)
+ });
+
+ describe('test get and getValue in nested forms', () => {
+ let formA: FormGroup;
+ let formB: FormGroup;
+ let formC: FormGroup;
+
+ beforeEach(() => {
+ formA = createTestForm('a', 'a');
+ formB = createTestForm('b', 'b');
+ formC = createTestForm('c', 'c');
+ form = new CdFormGroup({
+ formA: formA,
+ formB: formB,
+ formC: formC
+ });
+ });
+
+ it('should find controls out of every form', () => {
+ expect(form.get('a')).toBe(formA.get('a'));
+ expect(form.get('b')).toBe(formB.get('b'));
+ expect(form.get('c')).toBe(formC.get('c'));
+ });
+
+ it('should throw an error if element could be found', () => {
+ expect(() => form.get('d')).toThrowError(`Control 'd' could not be found!`);
+ expect(() => form.get('sth')).toThrowError(`Control 'sth' could not be found!`);
+ });
+ });
+
+ describe('CdFormGroup tests', () => {
+ let x: CdFormGroup, nested: CdFormGroup, a: FormControl, c: FormGroup;
+
+ beforeEach(() => {
+ a = new FormControl('a');
+ x = new CdFormGroup({
+ a: a
+ });
+ nested = new CdFormGroup({
+ lev1: new CdFormGroup({
+ lev2: new FormControl('lev2')
+ })
+ });
+ c = createTestForm('c', 'c');
+ form = new CdFormGroup({
+ nested: nested,
+ cdform: x,
+ b: new FormControl('b'),
+ formC: c
+ });
+ });
+
+ it('should return single value from "a" control in not nested form "x"', () => {
+ expect(x.get('a')).toBe(a);
+ expect(x.getValue('a')).toBe('a');
+ });
+
+ it('should return control "a" out of form "x" in nested form', () => {
+ expect(form.get('a')).toBe(a);
+ expect(form.getValue('a')).toBe('a');
+ });
+
+ it('should return value "b" that is not nested in nested form', () => {
+ expect(form.getValue('b')).toBe('b');
+ });
+
+ it('return value "c" out of normal form group "c" in nested form', () => {
+ expect(form.getValue('c')).toBe('c');
+ });
+
+ it('should return "lev2" value', () => {
+ expect(form.getValue('lev2')).toBe('lev2');
+ });
+
+ it('should nested throw an error if control could not be found', () => {
+ expect(() => form.get('d')).toThrowError(`Control 'd' could not be found!`);
+ expect(() => form.getValue('sth')).toThrowError(`Control 'sth' could not be found!`);
+ });
+ });
+
+ describe('test different values for getValue', () => {
+ beforeEach(() => {
+ form = new CdFormGroup({
+ form_undefined: createTestForm('undefined', undefined),
+ form_null: createTestForm('null', null),
+ form_emptyObject: createTestForm('emptyObject', {}),
+ form_filledObject: createTestForm('filledObject', { notEmpty: 1 }),
+ form_number0: createTestForm('number0', 0),
+ form_number1: createTestForm('number1', 1),
+ form_emptyString: createTestForm('emptyString', ''),
+ form_someString1: createTestForm('someString1', 's'),
+ form_someString2: createTestForm('someString2', 'sth'),
+ form_floating: createTestForm('floating', 0.1),
+ form_false: createTestForm('false', false),
+ form_true: createTestForm('true', true)
+ });
+ });
+
+ it('returns objects', () => {
+ expect(form.getValue('null')).toBe(null);
+ expect(form.getValue('emptyObject')).toEqual({});
+ expect(form.getValue('filledObject')).toEqual({ notEmpty: 1 });
+ });
+
+ it('returns set numbers', () => {
+ expect(form.getValue('number0')).toBe(0);
+ expect(form.getValue('number1')).toBe(1);
+ expect(form.getValue('floating')).toBe(0.1);
+ });
+
+ it('returns strings', () => {
+ expect(form.getValue('emptyString')).toBe('');
+ expect(form.getValue('someString1')).toBe('s');
+ expect(form.getValue('someString2')).toBe('sth');
+ });
+
+ it('returns booleans', () => {
+ expect(form.getValue('true')).toBe(true);
+ expect(form.getValue('false')).toBe(false);
+ });
+
+ it('returns null if control was set as undefined', () => {
+ expect(form.getValue('undefined')).toBe(null);
+ });
+
+ it('returns a falsy value for null, undefined, false and 0', () => {
+ expect(form.getValue('false')).toBeFalsy();
+ expect(form.getValue('null')).toBeFalsy();
+ expect(form.getValue('number0')).toBeFalsy();
+ });
+ });
+
+ describe('should test showError', () => {
+ let formDir: NgForm;
+ let test: AbstractControl;
+
+ beforeEach(() => {
+ formDir = new NgForm([], []);
+ form = new CdFormGroup({
+ test_form: createTestForm('test', '')
+ });
+ test = form.get('test');
+ test.setErrors({ someError: 'failed' });
+ });
+
+ it('should not show an error if not dirty and not submitted', () => {
+ expect(form.showError('test', formDir)).toBe(false);
+ });
+
+ it('should show an error if dirty', () => {
+ test.markAsDirty();
+ expect(form.showError('test', formDir)).toBe(true);
+ });
+
+ it('should show an error if submitted', () => {
+ expect(form.showError('test', <NgForm>{ submitted: true })).toBe(true);
+ });
+
+ it('should not show an error if no error exits', () => {
+ test.setErrors(null);
+ expect(form.showError('test', <NgForm>{ submitted: true })).toBe(false);
+ test.markAsDirty();
+ expect(form.showError('test', formDir)).toBe(false);
+ });
+
+ it('should not show error if the given error is not there', () => {
+ expect(form.showError('test', <NgForm>{ submitted: true }, 'someOtherError')).toBe(false);
+ });
+
+ it('should show error if the given error is there', () => {
+ expect(form.showError('test', <NgForm>{ submitted: true }, 'someError')).toBe(true);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-group.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-group.ts
new file mode 100644
index 000000000..9869f398c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-group.ts
@@ -0,0 +1,75 @@
+import {
+ AbstractControl,
+ AbstractControlOptions,
+ AsyncValidatorFn,
+ FormGroup,
+ NgForm,
+ ValidatorFn
+} from '@angular/forms';
+
+/**
+ * CdFormGroup extends FormGroup with a few new methods that will help form development.
+ */
+export class CdFormGroup extends FormGroup {
+ constructor(
+ public controls: { [key: string]: AbstractControl },
+ validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null,
+ asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null
+ ) {
+ super(controls, validatorOrOpts, asyncValidator);
+ }
+
+ /**
+ * Get a control out of any control even if its nested in other CdFormGroups or a FormGroup
+ */
+ get(controlName: string): AbstractControl {
+ const control = this._get(controlName);
+ if (!control) {
+ throw new Error(`Control '${controlName}' could not be found!`);
+ }
+ return control;
+ }
+
+ _get(controlName: string): AbstractControl {
+ return (
+ super.get(controlName) ||
+ Object.values(this.controls)
+ .filter((c) => c.get)
+ .map((form) => {
+ if (form instanceof CdFormGroup) {
+ return form._get(controlName);
+ }
+ return form.get(controlName);
+ })
+ .find((c) => Boolean(c))
+ );
+ }
+
+ /**
+ * Get the value of a control
+ */
+ getValue(controlName: string): any {
+ return this.get(controlName).value;
+ }
+
+ /**
+ * Sets a control without triggering a value changes event
+ *
+ * Very useful if a function is called through a value changes event but the value
+ * should be changed within the call.
+ */
+ silentSet(controlName: string, value: any) {
+ this.get(controlName).setValue(value, { emitEvent: false });
+ }
+
+ /**
+ * Indicates errors of the control in templates
+ */
+ showError(controlName: string, form: NgForm, errorName?: string): boolean {
+ const control = this.get(controlName);
+ return (
+ (form.submitted || control.dirty) &&
+ (errorName ? control.hasError(errorName) : control.invalid)
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form.spec.ts
new file mode 100644
index 000000000..445c31faf
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form.spec.ts
@@ -0,0 +1,32 @@
+import { CdForm, LoadingStatus } from './cd-form';
+
+describe('CdForm', () => {
+ let form: CdForm;
+
+ beforeEach(() => {
+ form = new CdForm();
+ });
+
+ describe('loading', () => {
+ it('should start in loading state', () => {
+ expect(form.loading).toBe(LoadingStatus.Loading);
+ });
+
+ it('should change to ready when calling loadingReady', () => {
+ form.loadingReady();
+ expect(form.loading).toBe(LoadingStatus.Ready);
+ });
+
+ it('should change to error state calling loadingError', () => {
+ form.loadingError();
+ expect(form.loading).toBe(LoadingStatus.Error);
+ });
+
+ it('should change to loading state calling loadingStart', () => {
+ form.loadingError();
+ expect(form.loading).toBe(LoadingStatus.Error);
+ form.loadingStart();
+ expect(form.loading).toBe(LoadingStatus.Loading);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form.ts
new file mode 100644
index 000000000..6fcb40e7d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form.ts
@@ -0,0 +1,26 @@
+export enum LoadingStatus {
+ Loading,
+ Ready,
+ Error,
+ None
+}
+
+export class CdForm {
+ loading = LoadingStatus.Loading;
+
+ loadingStart() {
+ this.loading = LoadingStatus.Loading;
+ }
+
+ loadingReady() {
+ this.loading = LoadingStatus.Ready;
+ }
+
+ loadingError() {
+ this.loading = LoadingStatus.Error;
+ }
+
+ loadingNone() {
+ this.loading = LoadingStatus.None;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-validators.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-validators.spec.ts
new file mode 100644
index 000000000..5cf90fdea
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-validators.spec.ts
@@ -0,0 +1,906 @@
+import { fakeAsync, tick } from '@angular/core/testing';
+import { FormControl, Validators } from '@angular/forms';
+
+import _ from 'lodash';
+import { of as observableOf } from 'rxjs';
+
+import { RgwBucketService } from '~/app/shared/api/rgw-bucket.service';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { FormHelper } from '~/testing/unit-test-helper';
+
+let mockBucketExists = observableOf(true);
+jest.mock('~/app/shared/api/rgw-bucket.service', () => {
+ return {
+ RgwBucketService: jest.fn().mockImplementation(() => {
+ return {
+ exists: () => mockBucketExists
+ };
+ })
+ };
+});
+
+describe('CdValidators', () => {
+ let formHelper: FormHelper;
+ let form: CdFormGroup;
+
+ const expectValid = (value: any) => formHelper.expectValidChange('x', value);
+ const expectPatternError = (value: any) => formHelper.expectErrorChange('x', value, 'pattern');
+ const updateValidity = (controlName: string) => form.get(controlName).updateValueAndValidity();
+
+ beforeEach(() => {
+ form = new CdFormGroup({
+ x: new FormControl()
+ });
+ formHelper = new FormHelper(form);
+ });
+
+ describe('email', () => {
+ beforeEach(() => {
+ form.get('x').setValidators(CdValidators.email);
+ });
+
+ it('should not error on an empty email address', () => {
+ expectValid('');
+ });
+
+ it('should not error on valid email address', () => {
+ expectValid('dashboard@ceph.com');
+ });
+
+ it('should error on invalid email address', () => {
+ formHelper.expectErrorChange('x', 'xyz', 'email');
+ });
+ });
+
+ describe('ip validator', () => {
+ describe('IPv4', () => {
+ beforeEach(() => {
+ form.get('x').setValidators(CdValidators.ip(4));
+ });
+
+ it('should not error on empty addresses', () => {
+ expectValid('');
+ });
+
+ it('should accept valid address', () => {
+ expectValid('19.117.23.141');
+ });
+
+ it('should error containing whitespace', () => {
+ expectPatternError('155.144.133.122 ');
+ expectPatternError('155. 144.133 .122');
+ expectPatternError(' 155.144.133.122');
+ });
+
+ it('should error containing invalid char', () => {
+ expectPatternError('155.144.eee.122 ');
+ expectPatternError('155.1?.133 .1&2');
+ });
+
+ it('should error containing blocks higher than 255', () => {
+ expectPatternError('155.270.133.122');
+ expectPatternError('155.144.133.290');
+ });
+ });
+
+ describe('IPv4', () => {
+ beforeEach(() => {
+ form.get('x').setValidators(CdValidators.ip(6));
+ });
+
+ it('should not error on empty IPv6 addresses', () => {
+ expectValid('');
+ });
+
+ it('should accept valid IPv6 address', () => {
+ expectValid('c4dc:1475:cb0b:24ed:3c80:468b:70cd:1a95');
+ });
+
+ it('should error on IPv6 address containing too many blocks', () => {
+ formHelper.expectErrorChange(
+ 'x',
+ 'c4dc:14753:cb0b:24ed:3c80:468b:70cd:1a95:a3f3',
+ 'pattern'
+ );
+ });
+
+ it('should error on IPv6 address containing more than 4 digits per block', () => {
+ expectPatternError('c4dc:14753:cb0b:24ed:3c80:468b:70cd:1a95');
+ });
+
+ it('should error on IPv6 address containing whitespace', () => {
+ expectPatternError('c4dc:14753:cb0b:24ed:3c80:468b:70cd:1a95 ');
+ expectPatternError('c4dc:14753 :cb0b:24ed:3c80 :468b:70cd :1a95');
+ expectPatternError(' c4dc:14753:cb0b:24ed:3c80:468b:70cd:1a95');
+ });
+
+ it('should error on IPv6 address containing invalid char', () => {
+ expectPatternError('c4dx:14753:cb0b:24ed:3c80:468b:70cd:1a95');
+ expectPatternError('c4da:14753:cb0b:24ed:3$80:468b:70cd:1a95');
+ });
+ });
+
+ it('should accept valid IPv4/6 addresses if not protocol version is given', () => {
+ const x = form.get('x');
+ x.setValidators(CdValidators.ip());
+ expectValid('19.117.23.141');
+ expectValid('c4dc:1475:cb0b:24ed:3c80:468b:70cd:1a95');
+ });
+ });
+
+ describe('uuid validator', () => {
+ const expectUuidError = (value: string) =>
+ formHelper.expectErrorChange('x', value, 'invalidUuid', true);
+ beforeEach(() => {
+ form.get('x').setValidators(CdValidators.uuid());
+ });
+
+ it('should accept empty value', () => {
+ expectValid('');
+ });
+
+ it('should accept valid version 1 uuid', () => {
+ expectValid('171af0b2-c305-11e8-a355-529269fb1459');
+ });
+
+ it('should accept valid version 4 uuid', () => {
+ expectValid('e33bbcb6-fcc3-40b1-ae81-3f81706a35d5');
+ });
+
+ it('should error on uuid containing too many blocks', () => {
+ expectUuidError('e33bbcb6-fcc3-40b1-ae81-3f81706a35d5-23d3');
+ });
+
+ it('should error on uuid containing too many chars in block', () => {
+ expectUuidError('aae33bbcb6-fcc3-40b1-ae81-3f81706a35d5');
+ });
+
+ it('should error on uuid containing invalid char', () => {
+ expectUuidError('x33bbcb6-fcc3-40b1-ae81-3f81706a35d5');
+ expectUuidError('$33bbcb6-fcc3-40b1-ae81-3f81706a35d5');
+ });
+ });
+
+ describe('number validator', () => {
+ beforeEach(() => {
+ form.get('x').setValidators(CdValidators.number());
+ });
+
+ it('should accept empty value', () => {
+ expectValid('');
+ });
+
+ it('should accept numbers', () => {
+ expectValid(42);
+ expectValid(-42);
+ expectValid('42');
+ });
+
+ it('should error on decimal numbers', () => {
+ expectPatternError(42.3);
+ expectPatternError(-42.3);
+ expectPatternError('42.3');
+ });
+
+ it('should error on chars', () => {
+ expectPatternError('char');
+ expectPatternError('42char');
+ });
+
+ it('should error on whitespaces', () => {
+ expectPatternError('42 ');
+ expectPatternError('4 2');
+ });
+ });
+
+ describe('number validator (without negative values)', () => {
+ beforeEach(() => {
+ form.get('x').setValidators(CdValidators.number(false));
+ });
+
+ it('should accept positive numbers', () => {
+ expectValid(42);
+ expectValid('42');
+ });
+
+ it('should error on negative numbers', () => {
+ expectPatternError(-42);
+ expectPatternError('-42');
+ });
+ });
+
+ describe('decimal number validator', () => {
+ beforeEach(() => {
+ form.get('x').setValidators(CdValidators.decimalNumber());
+ });
+
+ it('should accept empty value', () => {
+ expectValid('');
+ });
+
+ it('should accept numbers and decimal numbers', () => {
+ expectValid(42);
+ expectValid(-42);
+ expectValid(42.3);
+ expectValid(-42.3);
+ expectValid('42');
+ expectValid('42.3');
+ });
+
+ it('should error on chars', () => {
+ expectPatternError('42e');
+ expectPatternError('e42.3');
+ });
+
+ it('should error on whitespaces', () => {
+ expectPatternError('42.3 ');
+ expectPatternError('42 .3');
+ });
+ });
+
+ describe('decimal number validator (without negative values)', () => {
+ beforeEach(() => {
+ form.get('x').setValidators(CdValidators.decimalNumber(false));
+ });
+
+ it('should accept positive numbers and decimals', () => {
+ expectValid(42);
+ expectValid(42.3);
+ expectValid('42');
+ expectValid('42.3');
+ });
+
+ it('should error on negative numbers and decimals', () => {
+ expectPatternError(-42);
+ expectPatternError('-42');
+ expectPatternError(-42.3);
+ expectPatternError('-42.3');
+ });
+ });
+
+ describe('requiredIf', () => {
+ beforeEach(() => {
+ form = new CdFormGroup({
+ a: new FormControl(''),
+ b: new FormControl('xyz'),
+ x: new FormControl(true),
+ y: new FormControl('abc'),
+ z: new FormControl('')
+ });
+ formHelper = new FormHelper(form);
+ });
+
+ it('should not error because all conditions are fulfilled', () => {
+ formHelper.setValue('z', 'zyx');
+ const validatorFn = CdValidators.requiredIf({
+ x: true,
+ y: 'abc'
+ });
+ expect(validatorFn(form.get('z'))).toBeNull();
+ });
+
+ it('should not error because of unmet prerequisites', () => {
+ // Define prereqs that do not match the current values of the form fields.
+ const validatorFn = CdValidators.requiredIf({
+ x: false,
+ y: 'xyz'
+ });
+ // The validator must succeed because the prereqs do not match, so the
+ // validation of the 'z' control will be skipped.
+ expect(validatorFn(form.get('z'))).toBeNull();
+ });
+
+ it('should error because of an empty value', () => {
+ // Define prereqs that force the validator to validate the value of
+ // the 'z' control.
+ const validatorFn = CdValidators.requiredIf({
+ x: true,
+ y: 'abc'
+ });
+ // The validator must fail because the value of control 'z' is empty.
+ expect(validatorFn(form.get('z'))).toEqual({ required: true });
+ });
+
+ it('should not error because of unsuccessful condition', () => {
+ formHelper.setValue('z', 'zyx');
+ // Define prereqs that force the validator to validate the value of
+ // the 'z' control.
+ const validatorFn = CdValidators.requiredIf(
+ {
+ x: true,
+ z: 'zyx'
+ },
+ () => false
+ );
+ expect(validatorFn(form.get('z'))).toBeNull();
+ });
+
+ it('should error because of successful condition', () => {
+ const conditionFn = (value: string) => {
+ return value === 'abc';
+ };
+ // Define prereqs that force the validator to validate the value of
+ // the 'y' control.
+ const validatorFn = CdValidators.requiredIf(
+ {
+ x: true,
+ z: ''
+ },
+ conditionFn
+ );
+ expect(validatorFn(form.get('y'))).toEqual({ required: true });
+ });
+
+ it('should process extended prerequisites (1)', () => {
+ const validatorFn = CdValidators.requiredIf({
+ y: { op: '!empty' }
+ });
+ expect(validatorFn(form.get('z'))).toEqual({ required: true });
+ });
+
+ it('should process extended prerequisites (2)', () => {
+ const validatorFn = CdValidators.requiredIf({
+ y: { op: '!empty' }
+ });
+ expect(validatorFn(form.get('b'))).toBeNull();
+ });
+
+ it('should process extended prerequisites (3)', () => {
+ const validatorFn = CdValidators.requiredIf({
+ y: { op: 'minLength', arg1: 2 }
+ });
+ expect(validatorFn(form.get('z'))).toEqual({ required: true });
+ });
+
+ it('should process extended prerequisites (4)', () => {
+ const validatorFn = CdValidators.requiredIf({
+ z: { op: 'empty' }
+ });
+ expect(validatorFn(form.get('a'))).toEqual({ required: true });
+ });
+
+ it('should process extended prerequisites (5)', () => {
+ const validatorFn = CdValidators.requiredIf({
+ z: { op: 'empty' }
+ });
+ expect(validatorFn(form.get('y'))).toBeNull();
+ });
+
+ it('should process extended prerequisites (6)', () => {
+ const validatorFn = CdValidators.requiredIf({
+ y: { op: 'empty' }
+ });
+ expect(validatorFn(form.get('z'))).toBeNull();
+ });
+
+ it('should process extended prerequisites (7)', () => {
+ const validatorFn = CdValidators.requiredIf({
+ y: { op: 'minLength', arg1: 4 }
+ });
+ expect(validatorFn(form.get('z'))).toBeNull();
+ });
+
+ it('should process extended prerequisites (8)', () => {
+ const validatorFn = CdValidators.requiredIf({
+ x: { op: 'equal', arg1: true }
+ });
+ expect(validatorFn(form.get('z'))).toEqual({ required: true });
+ });
+
+ it('should process extended prerequisites (9)', () => {
+ const validatorFn = CdValidators.requiredIf({
+ b: { op: '!equal', arg1: 'abc' }
+ });
+ expect(validatorFn(form.get('z'))).toEqual({ required: true });
+ });
+ });
+
+ describe('custom validation', () => {
+ beforeEach(() => {
+ form = new CdFormGroup({
+ x: new FormControl(
+ 3,
+ CdValidators.custom('odd', (x: number) => x % 2 === 1)
+ ),
+ y: new FormControl(
+ 5,
+ CdValidators.custom('not-dividable-by-x', (y: number) => {
+ const x = (form && form.get('x').value) || 1;
+ return y % x !== 0;
+ })
+ )
+ });
+ formHelper = new FormHelper(form);
+ });
+
+ it('should test error and valid condition for odd x', () => {
+ formHelper.expectError('x', 'odd');
+ expectValid(4);
+ });
+
+ it('should test error and valid condition for y if its dividable by x', () => {
+ updateValidity('y');
+ formHelper.expectError('y', 'not-dividable-by-x');
+ formHelper.expectValidChange('y', 6);
+ });
+ });
+
+ describe('validate if condition', () => {
+ beforeEach(() => {
+ form = new CdFormGroup({
+ x: new FormControl(3),
+ y: new FormControl(5)
+ });
+ CdValidators.validateIf(form.get('x'), () => ((form && form.get('y').value) || 0) > 10, [
+ CdValidators.custom('min', (x: number) => x < 7),
+ CdValidators.custom('max', (x: number) => x > 12)
+ ]);
+ formHelper = new FormHelper(form);
+ });
+
+ it('should test min error', () => {
+ formHelper.setValue('y', 11);
+ updateValidity('x');
+ formHelper.expectError('x', 'min');
+ });
+
+ it('should test max error', () => {
+ formHelper.setValue('y', 11);
+ formHelper.setValue('x', 13);
+ formHelper.expectError('x', 'max');
+ });
+
+ it('should test valid number with validation', () => {
+ formHelper.setValue('y', 11);
+ formHelper.setValue('x', 12);
+ formHelper.expectValid('x');
+ });
+
+ it('should validate automatically if dependency controls are defined', () => {
+ CdValidators.validateIf(
+ form.get('x'),
+ () => ((form && form.getValue('y')) || 0) > 10,
+ [Validators.min(7), Validators.max(12)],
+ undefined,
+ [form.get('y')]
+ );
+
+ formHelper.expectValid('x');
+ formHelper.setValue('y', 13);
+ formHelper.expectError('x', 'min');
+ });
+
+ it('should always validate the permanentValidators', () => {
+ CdValidators.validateIf(
+ form.get('x'),
+ () => ((form && form.getValue('y')) || 0) > 10,
+ [Validators.min(7), Validators.max(12)],
+ [Validators.required],
+ [form.get('y')]
+ );
+
+ formHelper.expectValid('x');
+ formHelper.setValue('x', '');
+ formHelper.expectError('x', 'required');
+ });
+ });
+
+ describe('match', () => {
+ let y: FormControl;
+
+ beforeEach(() => {
+ y = new FormControl('aaa');
+ form = new CdFormGroup({
+ x: new FormControl('aaa'),
+ y: y
+ });
+ formHelper = new FormHelper(form);
+ });
+
+ it('should error when values are different', () => {
+ formHelper.setValue('y', 'aab');
+ CdValidators.match('x', 'y')(form);
+ formHelper.expectValid('x');
+ formHelper.expectError('y', 'match');
+ });
+
+ it('should not error when values are equal', () => {
+ CdValidators.match('x', 'y')(form);
+ formHelper.expectValid('x');
+ formHelper.expectValid('y');
+ });
+
+ it('should unset error when values are equal', () => {
+ y.setErrors({ match: true });
+ CdValidators.match('x', 'y')(form);
+ formHelper.expectValid('x');
+ formHelper.expectValid('y');
+ });
+
+ it('should keep other existing errors', () => {
+ y.setErrors({ match: true, notUnique: true });
+ CdValidators.match('x', 'y')(form);
+ formHelper.expectValid('x');
+ formHelper.expectError('y', 'notUnique');
+ });
+ });
+
+ describe('unique', () => {
+ beforeEach(() => {
+ form = new CdFormGroup({
+ x: new FormControl(
+ '',
+ null,
+ CdValidators.unique((value) => {
+ return observableOf('xyz' === value);
+ })
+ )
+ });
+ formHelper = new FormHelper(form);
+ });
+
+ it('should not error because of empty input', () => {
+ expectValid('');
+ });
+
+ it('should not error because of not existing input', fakeAsync(() => {
+ formHelper.setValue('x', 'abc', true);
+ tick(500);
+ formHelper.expectValid('x');
+ }));
+
+ it('should error because of already existing input', fakeAsync(() => {
+ formHelper.setValue('x', 'xyz', true);
+ tick(500);
+ formHelper.expectError('x', 'notUnique');
+ }));
+ });
+
+ describe('composeIf', () => {
+ beforeEach(() => {
+ form = new CdFormGroup({
+ x: new FormControl(true),
+ y: new FormControl('abc'),
+ z: new FormControl('')
+ });
+ formHelper = new FormHelper(form);
+ });
+
+ it('should not error because all conditions are fulfilled', () => {
+ formHelper.setValue('z', 'zyx');
+ const validatorFn = CdValidators.composeIf(
+ {
+ x: true,
+ y: 'abc'
+ },
+ [Validators.required]
+ );
+ expect(validatorFn(form.get('z'))).toBeNull();
+ });
+
+ it('should not error because of unmet prerequisites', () => {
+ // Define prereqs that do not match the current values of the form fields.
+ const validatorFn = CdValidators.composeIf(
+ {
+ x: false,
+ y: 'xyz'
+ },
+ [Validators.required]
+ );
+ // The validator must succeed because the prereqs do not match, so the
+ // validation of the 'z' control will be skipped.
+ expect(validatorFn(form.get('z'))).toBeNull();
+ });
+
+ it('should error because of an empty value', () => {
+ // Define prereqs that force the validator to validate the value of
+ // the 'z' control.
+ const validatorFn = CdValidators.composeIf(
+ {
+ x: true,
+ y: 'abc'
+ },
+ [Validators.required]
+ );
+ // The validator must fail because the value of control 'z' is empty.
+ expect(validatorFn(form.get('z'))).toEqual({ required: true });
+ });
+ });
+
+ describe('dimmlessBinary validators', () => {
+ const i18nMock = (a: string, b: { value: string }) => a.replace('{{value}}', b.value);
+
+ beforeEach(() => {
+ form = new CdFormGroup({
+ x: new FormControl('2 KiB', [CdValidators.binaryMin(1024), CdValidators.binaryMax(3072)])
+ });
+ formHelper = new FormHelper(form);
+ });
+
+ it('should not raise exception an exception for valid change', () => {
+ formHelper.expectValidChange('x', '2.5 KiB');
+ });
+
+ it('should not raise minimum error', () => {
+ formHelper.expectErrorChange('x', '0.5 KiB', 'binaryMin');
+ expect(form.get('x').getError('binaryMin')(i18nMock)).toBe(
+ 'Size has to be at least 1 KiB or more'
+ );
+ });
+
+ it('should not raise maximum error', () => {
+ formHelper.expectErrorChange('x', '4 KiB', 'binaryMax');
+ expect(form.get('x').getError('binaryMax')(i18nMock)).toBe(
+ 'Size has to be at most 3 KiB or less'
+ );
+ });
+ });
+
+ describe('passwordPolicy', () => {
+ let valid: boolean;
+ let callbackCalled: boolean;
+
+ const fakeUserService = {
+ validatePassword: () => {
+ return observableOf({ valid: valid, credits: 17, valuation: 'foo' });
+ }
+ };
+
+ beforeEach(() => {
+ callbackCalled = false;
+ form = new CdFormGroup({
+ x: new FormControl(
+ '',
+ null,
+ CdValidators.passwordPolicy(
+ fakeUserService,
+ () => 'admin',
+ () => {
+ callbackCalled = true;
+ }
+ )
+ )
+ });
+ formHelper = new FormHelper(form);
+ });
+
+ it('should not error because of empty input', () => {
+ expectValid('');
+ expect(callbackCalled).toBeTruthy();
+ });
+
+ it('should not error because password matches the policy', fakeAsync(() => {
+ valid = true;
+ formHelper.setValue('x', 'abc', true);
+ tick(500);
+ formHelper.expectValid('x');
+ }));
+
+ it('should error because password does not match the policy', fakeAsync(() => {
+ valid = false;
+ formHelper.setValue('x', 'xyz', true);
+ tick(500);
+ formHelper.expectError('x', 'passwordPolicy');
+ }));
+
+ it('should call the callback function', fakeAsync(() => {
+ formHelper.setValue('x', 'xyz', true);
+ tick(500);
+ expect(callbackCalled).toBeTruthy();
+ }));
+
+ describe('sslCert validator', () => {
+ beforeEach(() => {
+ form.get('x').setValidators(CdValidators.sslCert());
+ });
+
+ it('should not error because of empty input', () => {
+ expectValid('');
+ });
+
+ it('should accept SSL certificate', () => {
+ expectValid(
+ '-----BEGIN CERTIFICATE-----\n' +
+ 'MIIC1TCCAb2gAwIBAgIJAM33ZCMvOLVdMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV\n' +
+ '...\n' +
+ '3Ztorm2A5tFB\n' +
+ '-----END CERTIFICATE-----\n' +
+ '\n'
+ );
+ });
+
+ it('should error on invalid SSL certificate (1)', () => {
+ expectPatternError(
+ 'MIIC1TCCAb2gAwIBAgIJAM33ZCMvOLVdMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV\n' +
+ '...\n' +
+ '3Ztorm2A5tFB\n' +
+ '-----END CERTIFICATE-----\n' +
+ '\n'
+ );
+ });
+
+ it('should error on invalid SSL certificate (2)', () => {
+ expectPatternError(
+ '-----BEGIN CERTIFICATE-----\n' +
+ 'MIIC1TCCAb2gAwIBAgIJAM33ZCMvOLVdMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV\n'
+ );
+ });
+ });
+
+ describe('sslPrivKey validator', () => {
+ beforeEach(() => {
+ form.get('x').setValidators(CdValidators.sslPrivKey());
+ });
+
+ it('should not error because of empty input', () => {
+ expectValid('');
+ });
+
+ it('should accept SSL private key', () => {
+ expectValid(
+ '-----BEGIN RSA PRIVATE KEY-----\n' +
+ 'MIIEpQIBAAKCAQEA5VwkMK63D7AoGJVbVpgiV3XlEC1rwwOEpHPZW9F3ZW1fYS1O\n' +
+ '...\n' +
+ 'SA4Jbana77S7adg919vNBCLWPAeoN44lI2+B1Ub5DxSnOpBf+zKiScU=\n' +
+ '-----END RSA PRIVATE KEY-----\n' +
+ '\n'
+ );
+ });
+
+ it('should error on invalid SSL private key (1)', () => {
+ expectPatternError(
+ 'MIIEpQIBAAKCAQEA5VwkMK63D7AoGJVbVpgiV3XlEC1rwwOEpHPZW9F3ZW1fYS1O\n' +
+ '...\n' +
+ 'SA4Jbana77S7adg919vNBCLWPAeoN44lI2+B1Ub5DxSnOpBf+zKiScU=\n' +
+ '-----END RSA PRIVATE KEY-----\n' +
+ '\n'
+ );
+ });
+
+ it('should error on invalid SSL private key (2)', () => {
+ expectPatternError(
+ '-----BEGIN RSA PRIVATE KEY-----\n' +
+ 'MIIEpQIBAAKCAQEA5VwkMK63D7AoGJVbVpgiV3XlEC1rwwOEpHPZW9F3ZW1fYS1O\n' +
+ '...\n' +
+ 'SA4Jbana77S7adg919vNBCLWPAeoN44lI2+B1Ub5DxSnOpBf+zKiScU=\n'
+ );
+ });
+ });
+ });
+ describe('bucket', () => {
+ const testValidator = (name: string, valid: boolean, expectedError?: string) => {
+ formHelper.setValue('x', name, true);
+ tick();
+ if (valid) {
+ formHelper.expectValid('x');
+ } else {
+ formHelper.expectError('x', expectedError);
+ }
+ };
+
+ describe('bucketName', () => {
+ beforeEach(() => {
+ form = new CdFormGroup({
+ x: new FormControl('', null, CdValidators.bucketName())
+ });
+ formHelper = new FormHelper(form);
+ });
+
+ it('bucket name cannot be empty', fakeAsync(() => {
+ testValidator('', false, 'required');
+ }));
+
+ it('bucket names cannot be formatted as IP address', fakeAsync(() => {
+ const testIPs = ['1.1.1.01', '001.1.1.01', '127.0.0.1'];
+ for (const ip of testIPs) {
+ testValidator(ip, false, 'ipAddress');
+ }
+ }));
+
+ it('bucket name must be >= 3 characters long (1/2)', fakeAsync(() => {
+ testValidator('ab', false, 'shouldBeInRange');
+ }));
+
+ it('bucket name must be >= 3 characters long (2/2)', fakeAsync(() => {
+ testValidator('abc', true);
+ }));
+
+ it('bucket name must be <= than 63 characters long (1/2)', fakeAsync(() => {
+ testValidator(_.repeat('a', 64), false, 'shouldBeInRange');
+ }));
+
+ it('bucket name must be <= than 63 characters long (2/2)', fakeAsync(() => {
+ testValidator(_.repeat('a', 63), true);
+ }));
+
+ it('bucket names must not contain uppercase characters or underscores (1/2)', fakeAsync(() => {
+ testValidator('iAmInvalid', false, 'bucketNameInvalid');
+ }));
+
+ it('bucket names can only contain lowercase letters, numbers, periods and hyphens', fakeAsync(() => {
+ testValidator('bk@2', false, 'bucketNameInvalid');
+ }));
+
+ it('bucket names must not contain uppercase characters or underscores (2/2)', fakeAsync(() => {
+ testValidator('i_am_invalid', false, 'bucketNameInvalid');
+ }));
+
+ it('bucket names must start and end with letters or numbers', fakeAsync(() => {
+ testValidator('abcd-', false, 'lowerCaseOrNumber');
+ }));
+
+ it('bucket labels cannot be empty', fakeAsync(() => {
+ testValidator('bk.', false, 'onlyLowerCaseAndNumbers');
+ }));
+
+ it('bucket names with invalid labels (1/3)', fakeAsync(() => {
+ testValidator('abc.1def.Ghi2', false, 'bucketNameInvalid');
+ }));
+
+ it('bucket names with invalid labels (2/3)', fakeAsync(() => {
+ testValidator('abc.1_xy', false, 'bucketNameInvalid');
+ }));
+
+ it('bucket names with invalid labels (3/3)', fakeAsync(() => {
+ testValidator('abc.*def', false, 'bucketNameInvalid');
+ }));
+
+ it('bucket names must be a series of one or more labels and can contain lowercase letters, numbers, and hyphens (1/3)', fakeAsync(() => {
+ testValidator('xyz.abc', true);
+ }));
+
+ it('bucket names must be a series of one or more labels and can contain lowercase letters, numbers, and hyphens (2/3)', fakeAsync(() => {
+ testValidator('abc.1-def', true);
+ }));
+
+ it('bucket names must be a series of one or more labels and can contain lowercase letters, numbers, and hyphens (3/3)', fakeAsync(() => {
+ testValidator('abc.ghi2', true);
+ }));
+
+ it('bucket names must be unique', fakeAsync(() => {
+ testValidator('bucket-name-is-unique', true);
+ }));
+
+ it('bucket names must not contain spaces', fakeAsync(() => {
+ testValidator('bucket name with spaces', false, 'bucketNameInvalid');
+ }));
+ });
+
+ describe('bucketExistence', () => {
+ const rgwBucketService = new RgwBucketService(undefined, undefined);
+
+ beforeEach(() => {
+ form = new CdFormGroup({
+ x: new FormControl('', null, CdValidators.bucketExistence(false, rgwBucketService))
+ });
+ formHelper = new FormHelper(form);
+ });
+
+ it('bucket name cannot be empty', fakeAsync(() => {
+ testValidator('', false, 'required');
+ }));
+
+ it('bucket name should not exist but it does', fakeAsync(() => {
+ testValidator('testName', false, 'bucketNameNotAllowed');
+ }));
+
+ it('bucket name should not exist and it does not', fakeAsync(() => {
+ mockBucketExists = observableOf(false);
+ testValidator('testName', true);
+ }));
+
+ it('bucket name should exist but it does not', fakeAsync(() => {
+ form.get('x').setAsyncValidators(CdValidators.bucketExistence(true, rgwBucketService));
+ mockBucketExists = observableOf(false);
+ testValidator('testName', false, 'bucketNameNotAllowed');
+ }));
+
+ it('bucket name should exist and it does', fakeAsync(() => {
+ form.get('x').setAsyncValidators(CdValidators.bucketExistence(true, rgwBucketService));
+ mockBucketExists = observableOf(true);
+ testValidator('testName', true);
+ }));
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-validators.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-validators.ts
new file mode 100644
index 000000000..22371a50f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-validators.ts
@@ -0,0 +1,612 @@
+import {
+ AbstractControl,
+ AsyncValidatorFn,
+ ValidationErrors,
+ ValidatorFn,
+ Validators
+} from '@angular/forms';
+
+import _ from 'lodash';
+import { Observable, of as observableOf, timer as observableTimer } from 'rxjs';
+import { map, switchMapTo, take } from 'rxjs/operators';
+
+import { RgwBucketService } from '~/app/shared/api/rgw-bucket.service';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
+import { FormatterService } from '~/app/shared/services/formatter.service';
+
+export function isEmptyInputValue(value: any): boolean {
+ return value == null || value.length === 0;
+}
+
+export type existsServiceFn = (value: any) => Observable<boolean>;
+
+export class CdValidators {
+ /**
+ * Validator that performs email validation. In contrast to the Angular
+ * email validator an empty email will not be handled as invalid.
+ */
+ static email(control: AbstractControl): ValidationErrors | null {
+ // Exit immediately if value is empty.
+ if (isEmptyInputValue(control.value)) {
+ return null;
+ }
+ return Validators.email(control);
+ }
+
+ /**
+ * Validator function in order to validate IP addresses.
+ * @param {number} version determines the protocol version. It needs to be set to 4 for IPv4 and
+ * to 6 for IPv6 validation. For any other number (it's also the default case) it will return a
+ * function to validate the input string against IPv4 OR IPv6.
+ * @returns {ValidatorFn} A validator function that returns an error map containing `pattern`
+ * if the validation check fails, otherwise `null`.
+ */
+ static ip(version: number = 0): ValidatorFn {
+ // prettier-ignore
+ const ipv4Rgx =
+ /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i;
+ const ipv6Rgx = /^(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}$/i;
+
+ if (version === 4) {
+ return Validators.pattern(ipv4Rgx);
+ } else if (version === 6) {
+ return Validators.pattern(ipv6Rgx);
+ } else {
+ return Validators.pattern(new RegExp(ipv4Rgx.source + '|' + ipv6Rgx.source));
+ }
+ }
+
+ /**
+ * Validator function in order to validate numbers.
+ * @returns {ValidatorFn} A validator function that returns an error map containing `pattern`
+ * if the validation check fails, otherwise `null`.
+ */
+ static number(allowsNegative: boolean = true): ValidatorFn {
+ if (allowsNegative) {
+ return Validators.pattern(/^-?[0-9]+$/i);
+ } else {
+ return Validators.pattern(/^[0-9]+$/i);
+ }
+ }
+
+ /**
+ * Validator function in order to validate decimal numbers.
+ * @returns {ValidatorFn} A validator function that returns an error map containing `pattern`
+ * if the validation check fails, otherwise `null`.
+ */
+ static decimalNumber(allowsNegative: boolean = true): ValidatorFn {
+ if (allowsNegative) {
+ return Validators.pattern(/^-?[0-9]+(.[0-9]+)?$/i);
+ } else {
+ return Validators.pattern(/^[0-9]+(.[0-9]+)?$/i);
+ }
+ }
+
+ /**
+ * Validator that performs SSL certificate validation.
+ * @returns {ValidatorFn} A validator function that returns an error map containing `pattern`
+ * if the validation check fails, otherwise `null`.
+ */
+ static sslCert(): ValidatorFn {
+ return Validators.pattern(
+ /^-----BEGIN CERTIFICATE-----(\n|\r|\f)((.+)?((\n|\r|\f).+)*)(\n|\r|\f)-----END CERTIFICATE-----[\n\r\f]*$/
+ );
+ }
+
+ /**
+ * Validator that performs SSL private key validation.
+ * @returns {ValidatorFn} A validator function that returns an error map containing `pattern`
+ * if the validation check fails, otherwise `null`.
+ */
+ static sslPrivKey(): ValidatorFn {
+ return Validators.pattern(
+ /^-----BEGIN RSA PRIVATE KEY-----(\n|\r|\f)((.+)?((\n|\r|\f).+)*)(\n|\r|\f)-----END RSA PRIVATE KEY-----[\n\r\f]*$/
+ );
+ }
+
+ /**
+ * Validator that performs SSL certificate validation of pem format.
+ * @returns {ValidatorFn} A validator function that returns an error map containing `pattern`
+ * if the validation check fails, otherwise `null`.
+ */
+ static pemCert(): ValidatorFn {
+ return Validators.pattern(/^-----BEGIN .+-----$.+^-----END .+-----$/ms);
+ }
+
+ /**
+ * Validator that requires controls to fulfill the specified condition if
+ * the specified prerequisites matches. If the prerequisites are fulfilled,
+ * then the given function is executed and if it succeeds, the 'required'
+ * validation error will be returned, otherwise null.
+ * @param {Object} prerequisites An object containing the prerequisites.
+ * To do additional checks rather than checking for equality you can
+ * use the extended prerequisite syntax:
+ * 'field_name': { 'op': '<OPERATOR>', arg1: '<OPERATOR_ARGUMENT>' }
+ * The following operators are supported:
+ * * empty
+ * * !empty
+ * * equal
+ * * !equal
+ * * minLength
+ * ### Example
+ * ```typescript
+ * {
+ * 'generate_key': true,
+ * 'username': 'Max Mustermann'
+ * }
+ * ```
+ * ### Example - Extended prerequisites
+ * ```typescript
+ * {
+ * 'generate_key': { 'op': 'equal', 'arg1': true },
+ * 'username': { 'op': 'minLength', 'arg1': 5 }
+ * }
+ * ```
+ * Only if all prerequisites are fulfilled, then the validation of the
+ * control will be triggered.
+ * @param {Function | undefined} condition The function to be executed when all
+ * prerequisites are fulfilled. If not set, then the {@link isEmptyInputValue}
+ * function will be used by default. The control's value is used as function
+ * argument. The function must return true to set the validation error.
+ * @return {ValidatorFn} Returns the validator function.
+ */
+ static requiredIf(prerequisites: object, condition?: Function | undefined): ValidatorFn {
+ let isWatched = false;
+
+ return (control: AbstractControl): ValidationErrors | null => {
+ if (!isWatched && control.parent) {
+ Object.keys(prerequisites).forEach((key) => {
+ control.parent.get(key).valueChanges.subscribe(() => {
+ control.updateValueAndValidity({ emitEvent: false });
+ });
+ });
+
+ isWatched = true;
+ }
+
+ // Check if all prerequisites met.
+ if (
+ !Object.keys(prerequisites).every((key) => {
+ if (!control.parent) {
+ return false;
+ }
+ const value = control.parent.get(key).value;
+ const prerequisite = prerequisites[key];
+ if (_.isObjectLike(prerequisite)) {
+ let result = false;
+ switch (prerequisite['op']) {
+ case 'empty':
+ result = _.isEmpty(value);
+ break;
+ case '!empty':
+ result = !_.isEmpty(value);
+ break;
+ case 'equal':
+ result = value === prerequisite['arg1'];
+ break;
+ case '!equal':
+ result = value !== prerequisite['arg1'];
+ break;
+ case 'minLength':
+ if (_.isString(value)) {
+ result = value.length >= prerequisite['arg1'];
+ }
+ break;
+ }
+ return result;
+ }
+ return value === prerequisite;
+ })
+ ) {
+ return null;
+ }
+ const success = _.isFunction(condition)
+ ? condition.call(condition, control.value)
+ : isEmptyInputValue(control.value);
+ return success ? { required: true } : null;
+ };
+ }
+
+ /**
+ * Compose multiple validators into a single function that returns the union of
+ * the individual error maps for the provided control when the given prerequisites
+ * are fulfilled.
+ *
+ * @param {Object} prerequisites An object containing the prerequisites as
+ * key/value pairs.
+ * ### Example
+ * ```typescript
+ * {
+ * 'generate_key': true,
+ * 'username': 'Max Mustermann'
+ * }
+ * ```
+ * @param {ValidatorFn[]} validators List of validators that should be taken
+ * into action when the prerequisites are met.
+ * @return {ValidatorFn} Returns the validator function.
+ */
+ static composeIf(prerequisites: object, validators: ValidatorFn[]): ValidatorFn {
+ let isWatched = false;
+ return (control: AbstractControl): ValidationErrors | null => {
+ if (!isWatched && control.parent) {
+ Object.keys(prerequisites).forEach((key) => {
+ control.parent.get(key).valueChanges.subscribe(() => {
+ control.updateValueAndValidity({ emitEvent: false });
+ });
+ });
+ isWatched = true;
+ }
+ // Check if all prerequisites are met.
+ if (
+ !Object.keys(prerequisites).every((key) => {
+ return control.parent && control.parent.get(key).value === prerequisites[key];
+ })
+ ) {
+ return null;
+ }
+ return Validators.compose(validators)(control);
+ };
+ }
+
+ /**
+ * Custom validation by passing a name for the error and a function as error condition.
+ *
+ * @param {string} error
+ * @param {Function} condition - a truthy return value will trigger the error
+ * @returns {ValidatorFn}
+ */
+ static custom(error: string, condition: Function): ValidatorFn {
+ return (control: AbstractControl): { [key: string]: any } => {
+ const value = condition.call(this, control.value);
+ if (value) {
+ return { [error]: value };
+ }
+ return null;
+ };
+ }
+
+ /**
+ * Validate form control if condition is true with validators.
+ *
+ * @param {AbstractControl} formControl
+ * @param {Function} condition
+ * @param {ValidatorFn[]} conditionalValidators List of validators that should only be tested
+ * when the condition is met
+ * @param {ValidatorFn[]} permanentValidators List of validators that should always be tested
+ * @param {AbstractControl[]} watchControls List of controls that the condition depend on.
+ * Every time one of this controls value is updated, the validation will be triggered
+ */
+ static validateIf(
+ formControl: AbstractControl,
+ condition: Function,
+ conditionalValidators: ValidatorFn[],
+ permanentValidators: ValidatorFn[] = [],
+ watchControls: AbstractControl[] = []
+ ) {
+ conditionalValidators = conditionalValidators.concat(permanentValidators);
+
+ formControl.setValidators((control: AbstractControl): {
+ [key: string]: any;
+ } => {
+ const value = condition.call(this);
+ if (value) {
+ return Validators.compose(conditionalValidators)(control);
+ }
+ if (permanentValidators.length > 0) {
+ return Validators.compose(permanentValidators)(control);
+ }
+ return null;
+ });
+
+ watchControls.forEach((control: AbstractControl) => {
+ control.valueChanges.subscribe(() => {
+ formControl.updateValueAndValidity({ emitEvent: false });
+ });
+ });
+ }
+
+ /**
+ * Validator that requires that both specified controls have the same value.
+ * Error will be added to the `path2` control.
+ * @param {string} path1 A dot-delimited string that define the path to the control.
+ * @param {string} path2 A dot-delimited string that define the path to the control.
+ * @return {ValidatorFn} Returns a validator function that always returns `null`.
+ * If the validation fails an error map with the `match` property will be set
+ * on the `path2` control.
+ */
+ static match(path1: string, path2: string): ValidatorFn {
+ return (control: AbstractControl): { [key: string]: any } => {
+ const ctrl1 = control.get(path1);
+ const ctrl2 = control.get(path2);
+ if (!ctrl1 || !ctrl2) {
+ return null;
+ }
+ if (ctrl1.value !== ctrl2.value) {
+ ctrl2.setErrors({ match: true });
+ } else {
+ const hasError = ctrl2.hasError('match');
+ if (hasError) {
+ // Remove the 'match' error. If no more errors exists, then set
+ // the error value to 'null', otherwise the field is still marked
+ // as invalid.
+ const errors = ctrl2.errors;
+ _.unset(errors, 'match');
+ ctrl2.setErrors(_.isEmpty(_.keys(errors)) ? null : errors);
+ }
+ }
+ return null;
+ };
+ }
+
+ /**
+ * Asynchronous validator that requires the control's value to be unique.
+ * The validation is only executed after the specified delay. Every
+ * keystroke during this delay will restart the timer.
+ * @param serviceFn {existsServiceFn} The service function that is
+ * called to check whether the given value exists. It must return
+ * boolean 'true' if the given value exists, otherwise 'false'.
+ * @param serviceFnThis {any} The object to be used as the 'this' object
+ * when calling the serviceFn function. Defaults to null.
+ * @param {number|Date} dueTime The delay time to wait before the
+ * serviceFn call is executed. This is useful to prevent calls on
+ * every keystroke. Defaults to 500.
+ * @return {AsyncValidatorFn} Returns an asynchronous validator function
+ * that returns an error map with the `notUnique` property if the
+ * validation check succeeds, otherwise `null`.
+ */
+ static unique(
+ serviceFn: existsServiceFn,
+ serviceFnThis: any = null,
+ usernameFn?: Function,
+ uidField = false
+ ): AsyncValidatorFn {
+ let uName: string;
+ return (control: AbstractControl): Observable<ValidationErrors | null> => {
+ // Exit immediately if user has not interacted with the control yet
+ // or the control value is empty.
+ if (control.pristine || isEmptyInputValue(control.value)) {
+ return observableOf(null);
+ }
+ uName = control.value;
+ if (_.isFunction(usernameFn) && usernameFn() !== null && usernameFn() !== '') {
+ if (uidField) {
+ uName = `${control.value}$${usernameFn()}`;
+ } else {
+ uName = `${usernameFn()}$${control.value}`;
+ }
+ }
+
+ return observableTimer().pipe(
+ switchMapTo(serviceFn.call(serviceFnThis, uName)),
+ map((resp: boolean) => {
+ if (!resp) {
+ return null;
+ } else {
+ return { notUnique: true };
+ }
+ }),
+ take(1)
+ );
+ };
+ }
+
+ /**
+ * Validator function for UUIDs.
+ * @param required - Defines if it is mandatory to fill in the UUID
+ * @return Validator function that returns an error object containing `invalidUuid` if the
+ * validation failed, `null` otherwise.
+ */
+ static uuid(required = false): ValidatorFn {
+ const uuidRe = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
+ return (control: AbstractControl): { [key: string]: any } | null => {
+ if (control.pristine && control.untouched) {
+ return null;
+ } else if (!required && !control.value) {
+ return null;
+ } else if (uuidRe.test(control.value)) {
+ return null;
+ }
+ return { invalidUuid: 'This is not a valid UUID' };
+ };
+ }
+
+ /**
+ * A simple minimum validator vor cd-binary inputs.
+ *
+ * To use the validation message pass I18n into the function as it cannot
+ * be called in a static one.
+ */
+ static binaryMin(bytes: number): ValidatorFn {
+ return (control: AbstractControl): { [key: string]: () => string } | null => {
+ const formatterService = new FormatterService();
+ const currentBytes = new FormatterService().toBytes(control.value);
+ if (bytes <= currentBytes) {
+ return null;
+ }
+ const value = new DimlessBinaryPipe(formatterService).transform(bytes);
+ return {
+ binaryMin: () => $localize`Size has to be at least ${value} or more`
+ };
+ };
+ }
+
+ /**
+ * A simple maximum validator vor cd-binary inputs.
+ *
+ * To use the validation message pass I18n into the function as it cannot
+ * be called in a static one.
+ */
+ static binaryMax(bytes: number): ValidatorFn {
+ return (control: AbstractControl): { [key: string]: () => string } | null => {
+ const formatterService = new FormatterService();
+ const currentBytes = formatterService.toBytes(control.value);
+ if (bytes >= currentBytes) {
+ return null;
+ }
+ const value = new DimlessBinaryPipe(formatterService).transform(bytes);
+ return {
+ binaryMax: () => $localize`Size has to be at most ${value} or less`
+ };
+ };
+ }
+
+ /**
+ * Asynchronous validator that checks if the password meets the password
+ * policy.
+ * @param userServiceThis The object to be used as the 'this' object
+ * when calling the 'validatePassword' method of the 'UserService'.
+ * @param usernameFn Function to get the username that should be
+ * taken into account.
+ * @param callback Callback function that is called after the validation
+ * has been done.
+ * @return {AsyncValidatorFn} Returns an asynchronous validator function
+ * that returns an error map with the `passwordPolicy` property if the
+ * validation check fails, otherwise `null`.
+ */
+ static passwordPolicy(
+ userServiceThis: any,
+ usernameFn?: Function,
+ callback?: (valid: boolean, credits?: number, valuation?: string) => void
+ ): AsyncValidatorFn {
+ return (control: AbstractControl): Observable<ValidationErrors | null> => {
+ if (control.pristine || control.value === '') {
+ if (_.isFunction(callback)) {
+ callback(true, 0);
+ }
+ return observableOf(null);
+ }
+ let username;
+ if (_.isFunction(usernameFn)) {
+ username = usernameFn();
+ }
+ return observableTimer(500).pipe(
+ switchMapTo(_.invoke(userServiceThis, 'validatePassword', control.value, username)),
+ map((resp: { valid: boolean; credits: number; valuation: string }) => {
+ if (_.isFunction(callback)) {
+ callback(resp.valid, resp.credits, resp.valuation);
+ }
+ if (resp.valid) {
+ return null;
+ } else {
+ return { passwordPolicy: true };
+ }
+ }),
+ take(1)
+ );
+ };
+ }
+
+ /**
+ * Validate the bucket name. In general, bucket names should follow domain
+ * name constraints:
+ * - Bucket names must be unique.
+ * - Bucket names cannot be formatted as IP address.
+ * - Bucket names can be between 3 and 63 characters long.
+ * - Bucket names must not contain uppercase characters or underscores.
+ * - Bucket names must start with a lowercase letter or number.
+ * - Bucket names must be a series of one or more labels. Adjacent
+ * labels are separated by a single period (.). Bucket names can
+ * contain lowercase letters, numbers, and hyphens. Each label must
+ * start and end with a lowercase letter or a number.
+ */
+ static bucketName(): AsyncValidatorFn {
+ return (control: AbstractControl): Observable<ValidationErrors | null> => {
+ if (control.pristine || !control.value) {
+ return observableOf({ required: true });
+ }
+ const constraints = [];
+ let errorName: string;
+ // - Bucket names cannot be formatted as IP address.
+ constraints.push(() => {
+ const ipv4Rgx = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i;
+ const ipv6Rgx = /^(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}$/i;
+ const name = control.value;
+ let notIP = true;
+ if (ipv4Rgx.test(name) || ipv6Rgx.test(name)) {
+ errorName = 'ipAddress';
+ notIP = false;
+ }
+ return notIP;
+ });
+ // - Bucket names can be between 3 and 63 characters long.
+ constraints.push((name: string) => {
+ if (!_.inRange(name.length, 3, 64)) {
+ errorName = 'shouldBeInRange';
+ return false;
+ }
+ // Bucket names can only contain lowercase letters, numbers, periods and hyphens.
+ if (!/^[0-9a-z.-]+$/.test(control.value)) {
+ errorName = 'bucketNameInvalid';
+ return false;
+ }
+ return true;
+ });
+ // - Bucket names must not contain uppercase characters or underscores.
+ // - Bucket names must start with a lowercase letter or number.
+ // - Bucket names must be a series of one or more labels. Adjacent
+ // labels are separated by a single period (.). Bucket names can
+ // contain lowercase letters, numbers, and hyphens. Each label must
+ // start and end with a lowercase letter or a number.
+ constraints.push((name: string) => {
+ const labels = _.split(name, '.');
+ return _.every(labels, (label) => {
+ // Bucket names must not contain uppercase characters or underscores.
+ if (label !== _.toLower(label) || label.includes('_')) {
+ errorName = 'containsUpperCase';
+ return false;
+ }
+ // Bucket labels can contain lowercase letters, numbers, and hyphens.
+ if (!/^[0-9a-z-]+$/.test(label)) {
+ errorName = 'onlyLowerCaseAndNumbers';
+ return false;
+ }
+ // Each label must start and end with a lowercase letter or a number.
+ return _.every([0, label.length - 1], (index) => {
+ errorName = 'lowerCaseOrNumber';
+ return /[a-z]/.test(label[index]) || _.isInteger(_.parseInt(label[index]));
+ });
+ });
+ });
+ if (!_.every(constraints, (func: Function) => func(control.value))) {
+ return observableOf(
+ (() => {
+ switch (errorName) {
+ case 'onlyLowerCaseAndNumbers':
+ return { onlyLowerCaseAndNumbers: true };
+ case 'shouldBeInRange':
+ return { shouldBeInRange: true };
+ case 'ipAddress':
+ return { ipAddress: true };
+ case 'containsUpperCase':
+ return { containsUpperCase: true };
+ case 'lowerCaseOrNumber':
+ return { lowerCaseOrNumber: true };
+ default:
+ return { bucketNameInvalid: true };
+ }
+ })()
+ );
+ }
+
+ return observableOf(null);
+ };
+ }
+
+ static bucketExistence(
+ requiredExistenceResult: boolean,
+ rgwBucketService: RgwBucketService
+ ): AsyncValidatorFn {
+ return (control: AbstractControl): Observable<ValidationErrors | null> => {
+ if (control.pristine || !control.value) {
+ return observableOf({ required: true });
+ }
+ return rgwBucketService
+ .exists(control.value)
+ .pipe(
+ map((existenceResult: boolean) =>
+ existenceResult === requiredExistenceResult ? null : { bucketNameNotAllowed: true }
+ )
+ );
+ };
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/alertmanager-silence.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/alertmanager-silence.ts
new file mode 100644
index 000000000..b7b886295
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/alertmanager-silence.ts
@@ -0,0 +1,23 @@
+export class AlertmanagerSilenceMatcher {
+ name: string;
+ value: any;
+ isRegex: boolean;
+}
+
+export class AlertmanagerSilenceMatcherMatch {
+ status: string;
+ cssClass: string;
+}
+
+export class AlertmanagerSilence {
+ id?: string;
+ matchers: AlertmanagerSilenceMatcher[];
+ startsAt: string; // DateStr
+ endsAt: string; // DateStr
+ updatedAt?: string; // DateStr
+ createdBy: string;
+ comment: string;
+ status?: {
+ state: 'expired' | 'active' | 'pending';
+ };
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/breadcrumbs.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/breadcrumbs.ts
new file mode 100644
index 000000000..10e799929
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/breadcrumbs.ts
@@ -0,0 +1,59 @@
+/*
+The MIT License
+
+Copyright (c) 2017 (null) McNull https://github.com/McNull
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+ */
+
+import { ActivatedRouteSnapshot, Resolve, UrlSegment } from '@angular/router';
+
+import { Observable, of } from 'rxjs';
+
+export class BreadcrumbsResolver implements Resolve<IBreadcrumb[]> {
+ public resolve(
+ route: ActivatedRouteSnapshot
+ ): Observable<IBreadcrumb[]> | Promise<IBreadcrumb[]> | IBreadcrumb[] {
+ const data = route.routeConfig.data;
+ const path = data.path === null ? null : this.getFullPath(route);
+
+ const text =
+ typeof data.breadcrumbs === 'string'
+ ? data.breadcrumbs
+ : data.breadcrumbs.text || data.text || path;
+
+ const crumbs: IBreadcrumb[] = [{ text: text, path: path }];
+
+ return of(crumbs);
+ }
+
+ public getFullPath(route: ActivatedRouteSnapshot): string {
+ const relativePath = (segments: UrlSegment[]) =>
+ segments.reduce((a, v) => (a += '/' + v.path), '');
+ const fullPath = (routes: ActivatedRouteSnapshot[]) =>
+ routes.reduce((a, v) => (a += relativePath(v.url)), '');
+
+ return fullPath(route.pathFromRoot);
+ }
+}
+
+export interface IBreadcrumb {
+ text: string;
+ path: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-form-modal-field-config.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-form-modal-field-config.ts
new file mode 100644
index 000000000..e327be59a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-form-modal-field-config.ts
@@ -0,0 +1,32 @@
+import { ValidatorFn } from '@angular/forms';
+
+export class CdFormModalFieldConfig {
+ // --- Generic field properties ---
+ name: string;
+ // 'binary' will use cdDimlessBinary directive on input element
+ // 'select' will use select element
+ type: 'number' | 'text' | 'binary' | 'select' | 'select-badges';
+ label?: string;
+ required?: boolean;
+ value?: any;
+ errors?: { [errorName: string]: string };
+ validators: ValidatorFn[];
+
+ // --- Specific field properties ---
+ typeConfig?: {
+ [prop: string]: any;
+ // 'select':
+ // ---------
+ // placeholder?: string;
+ // options?: Array<{
+ // text: string;
+ // value: any;
+ // }>;
+ //
+ // 'select-badges':
+ // ----------------
+ // customBadges: boolean;
+ // options: Array<SelectOption>;
+ // messages: SelectMessages;
+ };
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-notification.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-notification.spec.ts
new file mode 100644
index 000000000..df6e8899b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-notification.spec.ts
@@ -0,0 +1,95 @@
+import { NotificationType } from '../enum/notification-type.enum';
+import { CdNotification, CdNotificationConfig } from './cd-notification';
+
+describe('cd-notification classes', () => {
+ const expectObject = (something: object, expected: object) => {
+ Object.keys(expected).forEach((key) => expect(something[key]).toBe(expected[key]));
+ };
+
+ // As these Models have a view methods they need to be tested
+ describe('CdNotificationConfig', () => {
+ it('should create a new config without any parameters', () => {
+ expectObject(new CdNotificationConfig(), {
+ application: 'Ceph',
+ applicationClass: 'ceph-icon',
+ message: undefined,
+ options: undefined,
+ title: undefined,
+ type: 1
+ });
+ });
+
+ it('should create a new config with parameters', () => {
+ expectObject(
+ new CdNotificationConfig(
+ NotificationType.error,
+ 'Some Alert',
+ 'Something failed',
+ undefined,
+ 'Prometheus'
+ ),
+ {
+ application: 'Prometheus',
+ applicationClass: 'prometheus-icon',
+ message: 'Something failed',
+ options: undefined,
+ title: 'Some Alert',
+ type: 0
+ }
+ );
+ });
+ });
+
+ describe('CdNotification', () => {
+ beforeEach(() => {
+ const baseTime = new Date('2022-02-22');
+ spyOn(global, 'Date').and.returnValue(baseTime);
+ });
+
+ it('should create a new config without any parameters', () => {
+ expectObject(new CdNotification(), {
+ application: 'Ceph',
+ applicationClass: 'ceph-icon',
+ iconClass: 'fa fa-info',
+ message: undefined,
+ options: undefined,
+ textClass: 'text-info',
+ timestamp: '2022-02-22T00:00:00.000Z',
+ title: undefined,
+ type: 1
+ });
+ });
+
+ it('should create a new config with parameters', () => {
+ expectObject(
+ new CdNotification(
+ new CdNotificationConfig(
+ NotificationType.error,
+ 'Some Alert',
+ 'Something failed',
+ undefined,
+ 'Prometheus'
+ )
+ ),
+ {
+ application: 'Prometheus',
+ applicationClass: 'prometheus-icon',
+ iconClass: 'fa fa-exclamation-triangle',
+ message: 'Something failed',
+ options: undefined,
+ textClass: 'text-danger',
+ timestamp: '2022-02-22T00:00:00.000Z',
+ title: 'Some Alert',
+ type: 0
+ }
+ );
+ });
+
+ it('should expect the right success classes', () => {
+ expectObject(new CdNotification(new CdNotificationConfig(NotificationType.success)), {
+ iconClass: 'fa fa-check',
+ textClass: 'text-success'
+ });
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-notification.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-notification.ts
new file mode 100644
index 000000000..c283c5d80
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-notification.ts
@@ -0,0 +1,48 @@
+import { IndividualConfig } from 'ngx-toastr';
+
+import { Icons } from '../enum/icons.enum';
+import { NotificationType } from '../enum/notification-type.enum';
+
+export class CdNotificationConfig {
+ applicationClass: string;
+ isFinishedTask = false;
+
+ private classes = {
+ Ceph: 'ceph-icon',
+ Prometheus: 'prometheus-icon'
+ };
+
+ constructor(
+ public type: NotificationType = NotificationType.info,
+ public title?: string,
+ public message?: string, // Use this for additional information only
+ public options?: any | IndividualConfig,
+ public application: string = 'Ceph'
+ ) {
+ this.applicationClass = this.classes[this.application];
+ }
+}
+
+export class CdNotification extends CdNotificationConfig {
+ timestamp: string;
+ textClass: string;
+ iconClass: string;
+ duration: number;
+ borderClass: string;
+
+ private textClasses = ['text-danger', 'text-info', 'text-success'];
+ private iconClasses = [Icons.warning, Icons.info, Icons.check];
+ private borderClasses = ['border-danger', 'border-info', 'border-success'];
+
+ constructor(private config: CdNotificationConfig = new CdNotificationConfig()) {
+ super(config.type, config.title, config.message, config.options, config.application);
+ delete this.config;
+ /* string representation of the Date object so it can be directly compared
+ with the timestamps parsed from localStorage */
+ this.timestamp = new Date().toJSON();
+ this.iconClass = this.iconClasses[this.type];
+ this.textClass = this.textClasses[this.type];
+ this.borderClass = this.borderClasses[this.type];
+ this.isFinishedTask = config.isFinishedTask;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-pwd-expiration-settings.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-pwd-expiration-settings.ts
new file mode 100644
index 000000000..53b9d14fd
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-pwd-expiration-settings.ts
@@ -0,0 +1,11 @@
+export class CdPwdExpirationSettings {
+ pwdExpirationSpan = 0;
+ pwdExpirationWarning1: number;
+ pwdExpirationWarning2: number;
+
+ constructor(settings: { [key: string]: any }) {
+ this.pwdExpirationSpan = settings.user_pwd_expiration_span;
+ this.pwdExpirationWarning1 = settings.user_pwd_expiration_warning_1;
+ this.pwdExpirationWarning2 = settings.user_pwd_expiration_warning_2;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-pwd-policy-settings.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-pwd-policy-settings.ts
new file mode 100644
index 000000000..fef570f21
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-pwd-policy-settings.ts
@@ -0,0 +1,23 @@
+export class CdPwdPolicySettings {
+ pwdPolicyEnabled: boolean;
+ pwdPolicyMinLength: number;
+ pwdPolicyCheckLengthEnabled: boolean;
+ pwdPolicyCheckOldpwdEnabled: boolean;
+ pwdPolicyCheckUsernameEnabled: boolean;
+ pwdPolicyCheckExclusionListEnabled: boolean;
+ pwdPolicyCheckRepetitiveCharsEnabled: boolean;
+ pwdPolicyCheckSequentialCharsEnabled: boolean;
+ pwdPolicyCheckComplexityEnabled: boolean;
+
+ constructor(settings: { [key: string]: any }) {
+ this.pwdPolicyEnabled = settings.pwd_policy_enabled;
+ this.pwdPolicyMinLength = settings.pwd_policy_min_length;
+ this.pwdPolicyCheckLengthEnabled = settings.pwd_policy_check_length_enabled;
+ this.pwdPolicyCheckOldpwdEnabled = settings.pwd_policy_check_oldpwd_enabled;
+ this.pwdPolicyCheckUsernameEnabled = settings.pwd_policy_check_username_enabled;
+ this.pwdPolicyCheckExclusionListEnabled = settings.pwd_policy_check_exclusion_list_enabled;
+ this.pwdPolicyCheckRepetitiveCharsEnabled = settings.pwd_policy_check_repetitive_chars_enabled;
+ this.pwdPolicyCheckSequentialCharsEnabled = settings.pwd_policy_check_sequential_chars_enabled;
+ this.pwdPolicyCheckComplexityEnabled = settings.pwd_policy_check_complexity_enabled;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-action.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-action.ts
new file mode 100644
index 000000000..70f06e506
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-action.ts
@@ -0,0 +1,44 @@
+import { CdTableSelection } from './cd-table-selection';
+
+export class CdTableAction {
+ // It's possible to assign a string
+ // or a function that returns the link if it has to be dynamic
+ // or none if it's not needed
+ routerLink?: string | Function;
+
+ preserveFragment? = false;
+
+ // This is the function that will be triggered on a click event if defined
+ click?: Function;
+
+ permission: 'create' | 'update' | 'delete' | 'read';
+
+ // The name of the action
+ name: string;
+
+ // The font awesome icon that will be used
+ icon: string;
+
+ /**
+ * You can define the condition to disable the action.
+ * By default all 'update' and 'delete' actions will only be enabled
+ * if one selection is made and no task is running on the selected item.`
+ *
+ * In some cases you might want to give the user a hint why a button is
+ * disabled. This is achieved by returning a string.
+ * */
+ disable?: (_: CdTableSelection) => boolean | string;
+
+ /**
+ * Defines if the button can become 'primary' (displayed as button and not
+ * 'hidden' in the menu). Only one button can be primary at a time. By
+ * default all 'create' actions can be the action button if no or multiple
+ * items are selected. Also, all 'update' and 'delete' actions can be the
+ * action button by default, provided only one item is selected.
+ */
+ canBePrimary?: (_: CdTableSelection) => boolean;
+
+ // In some rare cases you want to hide a action that can be used by the user for example
+ // if one action can lock the item and another action unlocks it
+ visible?: (_: CdTableSelection) => boolean;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-column-filter.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-column-filter.ts
new file mode 100644
index 000000000..ccdbe82fc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-column-filter.ts
@@ -0,0 +1,7 @@
+import { CdTableColumn } from './cd-table-column';
+
+export interface CdTableColumnFilter {
+ column: CdTableColumn;
+ options: { raw: string; formatted: string }[]; // possible options of a filter
+ value?: { raw: string; formatted: string }; // selected option
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-column-filters-change.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-column-filters-change.ts
new file mode 100644
index 000000000..17601f0ad
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-column-filters-change.ts
@@ -0,0 +1,22 @@
+import { TableColumnProp } from '@swimlane/ngx-datatable';
+
+export interface CdTableColumnFiltersChange {
+ /**
+ * Applied filters.
+ */
+ filters: {
+ name: string;
+ prop: TableColumnProp;
+ value: { raw: string; formatted: string };
+ }[];
+
+ /**
+ * Filtered data.
+ */
+ data: any[];
+
+ /**
+ * Filtered out data.
+ */
+ dataOut: any[];
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-column.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-column.ts
new file mode 100644
index 000000000..4ed5fdd58
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-column.ts
@@ -0,0 +1,38 @@
+import { TableColumn, TableColumnProp } from '@swimlane/ngx-datatable';
+
+import { CellTemplate } from '../enum/cell-template.enum';
+
+export interface CdTableColumn extends TableColumn {
+ cellTransformation?: CellTemplate;
+ isHidden?: boolean;
+ prop: TableColumnProp; // Enforces properties to get sortable columns
+ customTemplateConfig?: any; // Custom configuration used by cell templates.
+
+ /**
+ * Add a filter for the column if true.
+ *
+ * By default, options for the filter are deduced from values of the column.
+ */
+ filterable?: boolean;
+
+ /**
+ * Use these options for filter rather than deducing from values of the column.
+ *
+ * If there is a pipe function associated with the column, pipe function is applied
+ * to the options before displaying them.
+ */
+ filterOptions?: any[];
+
+ /**
+ * Default applied option, should be value in filterOptions.
+ */
+ filterInitValue?: any;
+
+ /**
+ * Specify a custom function for filtering.
+ *
+ * By default, the filter compares if values are string-equal with options. Specify
+ * a customize function if that's not desired. Return true to include a row.
+ */
+ filterPredicate?: (row: any, value: any) => boolean;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-fetch-data-context.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-fetch-data-context.ts
new file mode 100644
index 000000000..7937d82e6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-fetch-data-context.ts
@@ -0,0 +1,44 @@
+import { HttpParams } from '@angular/common/http';
+
+import { PageInfo } from './cd-table-paging';
+
+export class CdTableFetchDataContext {
+ errorConfig = {
+ resetData: true, // Force data table to show no data
+ displayError: true // Show an error panel above the data table
+ };
+
+ /**
+ * The function that should be called from within the error handler
+ * of the 'fetchData' function to display the error panel and to
+ * reset the data table to the correct state.
+ */
+ error: Function;
+ pageInfo: PageInfo = new PageInfo();
+ search = '';
+ sort = '+name';
+
+ constructor(error: () => void) {
+ this.error = error;
+ }
+
+ toParams(): HttpParams {
+ if (this.pageInfo.limit === null) {
+ this.pageInfo.limit = 0;
+ }
+ if (!this.search) {
+ this.search = '';
+ }
+ if (!this.sort || this.sort.length < 2) {
+ this.sort = '+name';
+ }
+ return new HttpParams({
+ fromObject: {
+ offset: String(this.pageInfo.offset * this.pageInfo.limit),
+ limit: String(this.pageInfo.limit),
+ search: this.search,
+ sort: this.sort
+ }
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-paging.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-paging.ts
new file mode 100644
index 000000000..3693b527d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-paging.ts
@@ -0,0 +1,20 @@
+export const PAGE_LIMIT = 10;
+
+export class PageInfo {
+ // Total number of rows in a table
+ count: number;
+
+ // Current page (current row = offset x limit or pageSize)
+ offset = 0;
+
+ // Max. number of rows fetched from the server
+ limit: number = PAGE_LIMIT;
+
+ /*
+ pageSize and limit can be decoupled if hybrid server-side and client-side
+ are used. A use-case would be to reduce the amount of queries: that is,
+ the pageSize (client-side paging) might be 10, but the back-end queries
+ could have a limit of 100. That would avoid triggering requests
+ */
+ pageSize: number = PAGE_LIMIT;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-selection.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-selection.ts
new file mode 100644
index 000000000..bbe1e5088
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-selection.ts
@@ -0,0 +1,45 @@
+export class CdTableSelection {
+ private _selected: any[] = [];
+ hasMultiSelection: boolean;
+ hasSingleSelection: boolean;
+ hasSelection: boolean;
+
+ constructor(rows?: any[]) {
+ if (rows) {
+ this._selected = rows;
+ }
+ this.update();
+ }
+
+ /**
+ * Recalculate the variables based on the current number
+ * of selected rows.
+ */
+ private update() {
+ this.hasSelection = this._selected.length > 0;
+ this.hasSingleSelection = this._selected.length === 1;
+ this.hasMultiSelection = this._selected.length > 1;
+ }
+
+ set selected(selection: any[]) {
+ this._selected = selection;
+ this.update();
+ }
+
+ get selected() {
+ return this._selected;
+ }
+
+ add(row: any) {
+ this._selected.push(row);
+ this.update();
+ }
+
+ /**
+ * Get the first selected row.
+ * @return {any | null}
+ */
+ first() {
+ return this.hasSelection ? this._selected[0] : null;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-user-config.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-user-config.ts
new file mode 100644
index 000000000..edd1af784
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-user-config.ts
@@ -0,0 +1,11 @@
+import { SortPropDir } from '@swimlane/ngx-datatable';
+
+import { CdTableColumn } from './cd-table-column';
+
+export interface CdUserConfig {
+ limit?: number;
+ offset?: number;
+ search?: string;
+ sorts?: SortPropDir[];
+ columns?: CdTableColumn[];
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cephfs-directory-models.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cephfs-directory-models.ts
new file mode 100644
index 000000000..92186aecc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/cephfs-directory-models.ts
@@ -0,0 +1,21 @@
+import { TreeStatus } from '@swimlane/ngx-datatable';
+
+export class CephfsSnapshot {
+ name: string;
+ path: string;
+ created: string;
+}
+
+export class CephfsQuotas {
+ max_bytes?: number;
+ max_files?: number;
+}
+
+export class CephfsDir {
+ name: string;
+ path: string;
+ quotas: CephfsQuotas;
+ snapshots: CephfsSnapshot[];
+ parent: string;
+ treeStatus?: TreeStatus; // Needed for table tree view
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/chart-tooltip.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/chart-tooltip.ts
new file mode 100644
index 000000000..93a259e79
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/chart-tooltip.ts
@@ -0,0 +1,115 @@
+import { ElementRef } from '@angular/core';
+
+export class ChartTooltip {
+ tooltipEl: any;
+ chartEl: any;
+ getStyleLeft: Function;
+ getStyleTop: Function;
+ customColors: Record<string, any> = {
+ backgroundColor: undefined,
+ borderColor: undefined
+ };
+ checkOffset = false;
+
+ /**
+ * Creates an instance of ChartTooltip.
+ * @param {ElementRef} chartCanvas Canvas Element
+ * @param {ElementRef} chartTooltip Tooltip Element
+ * @param {Function} getStyleLeft Function that calculates the value of Left
+ * @param {Function} getStyleTop Function that calculates the value of Top
+ * @memberof ChartTooltip
+ */
+ constructor(
+ chartCanvas: ElementRef,
+ chartTooltip: ElementRef,
+ getStyleLeft: Function,
+ getStyleTop: Function
+ ) {
+ this.chartEl = chartCanvas.nativeElement;
+ this.getStyleLeft = getStyleLeft;
+ this.getStyleTop = getStyleTop;
+ this.tooltipEl = chartTooltip.nativeElement;
+ }
+
+ /**
+ * Implementation of a ChartJS custom tooltip function.
+ *
+ * @param {any} tooltip
+ * @memberof ChartTooltip
+ */
+ customTooltips(tooltip: any) {
+ // Hide if no tooltip
+ if (tooltip.opacity === 0) {
+ this.tooltipEl.style.opacity = 0;
+ return;
+ }
+
+ // Set caret Position
+ this.tooltipEl.classList.remove('above', 'below', 'no-transform');
+ if (tooltip.yAlign) {
+ this.tooltipEl.classList.add(tooltip.yAlign);
+ } else {
+ this.tooltipEl.classList.add('no-transform');
+ }
+
+ // Set Text
+ if (tooltip.body) {
+ const titleLines = tooltip.title || [];
+ const bodyLines = tooltip.body.map((bodyItem: any) => {
+ return bodyItem.lines;
+ });
+
+ let innerHtml = '<thead>';
+
+ titleLines.forEach((title: string) => {
+ innerHtml += '<tr><th>' + this.getTitle(title) + '</th></tr>';
+ });
+ innerHtml += '</thead><tbody>';
+
+ bodyLines.forEach((body: string, i: number) => {
+ const colors = tooltip.labelColors[i];
+ let style = 'background:' + (this.customColors.backgroundColor || colors.backgroundColor);
+ style += '; border-color:' + (this.customColors.borderColor || colors.borderColor);
+ style += '; border-width: 2px';
+ const span = '<span class="chartjs-tooltip-key" style="' + style + '"></span>';
+ innerHtml += '<tr><td nowrap>' + span + this.getBody(body) + '</td></tr>';
+ });
+ innerHtml += '</tbody>';
+
+ const tableRoot = this.tooltipEl.querySelector('table');
+ tableRoot.innerHTML = innerHtml;
+ }
+
+ const positionY = this.chartEl.offsetTop;
+ const positionX = this.chartEl.offsetLeft;
+
+ // Display, position, and set styles for font
+ if (this.checkOffset) {
+ const halfWidth = tooltip.width / 2;
+ this.tooltipEl.classList.remove('transform-left');
+ this.tooltipEl.classList.remove('transform-right');
+ if (tooltip.caretX - halfWidth < 0) {
+ this.tooltipEl.classList.add('transform-left');
+ } else if (tooltip.caretX + halfWidth > this.chartEl.width) {
+ this.tooltipEl.classList.add('transform-right');
+ }
+ }
+
+ this.tooltipEl.style.left = this.getStyleLeft(tooltip, positionX);
+ this.tooltipEl.style.top = this.getStyleTop(tooltip, positionY);
+
+ this.tooltipEl.style.opacity = 1;
+ this.tooltipEl.style.fontFamily = tooltip._fontFamily;
+ this.tooltipEl.style.fontSize = tooltip.fontSize;
+ this.tooltipEl.style.fontStyle = tooltip._fontStyle;
+ this.tooltipEl.style.padding = tooltip.yPadding + 'px ' + tooltip.xPadding + 'px';
+ }
+
+ getBody(body: string) {
+ return body;
+ }
+
+ getTitle(title: string) {
+ return title;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/configuration.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/configuration.ts
new file mode 100644
index 000000000..0a8e403d7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/configuration.ts
@@ -0,0 +1,43 @@
+export enum RbdConfigurationSourceField {
+ global = 0,
+ pool = 1,
+ image = 2
+}
+
+export enum RbdConfigurationType {
+ bps,
+ iops,
+ milliseconds
+}
+
+/**
+ * This configuration can also be set on a pool level.
+ */
+export interface RbdConfigurationEntry {
+ name: string;
+ source: RbdConfigurationSourceField;
+ value: any;
+ type?: RbdConfigurationType; // Non-external field.
+ description?: string; // Non-external field.
+ displayName?: string; // Non-external field. Nice name for the UI which is added in the UI.
+}
+
+/**
+ * This object contains additional information injected into the elements retrieved by the service.
+ */
+export interface RbdConfigurationExtraField {
+ name: string;
+ displayName: string;
+ description: string;
+ type: RbdConfigurationType;
+ readOnly?: boolean;
+}
+
+/**
+ * Represents a set of data to be used for editing or creating configuration options
+ */
+export interface RbdConfigurationSection {
+ heading: string;
+ class: string;
+ options: RbdConfigurationExtraField[];
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/credentials.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/credentials.ts
new file mode 100644
index 000000000..2c2b7d76e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/credentials.ts
@@ -0,0 +1,4 @@
+export class Credentials {
+ username: string;
+ password: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/crush-node.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/crush-node.ts
new file mode 100644
index 000000000..a8c8288b6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/crush-node.ts
@@ -0,0 +1,17 @@
+export class CrushNode {
+ id: number;
+ name: string;
+ type: string;
+ type_id: number;
+ // For nodes with leafs (Buckets)
+ children?: number[]; // Holds node id's of children
+ // For non root nodes
+ pool_weights?: object;
+ // For leafs (Devices)
+ device_class?: string;
+ crush_weight?: number;
+ exists?: number;
+ primary_affinity?: number;
+ reweight?: number;
+ status?: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/crush-rule.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/crush-rule.ts
new file mode 100644
index 000000000..83c1db6b6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/crush-rule.ts
@@ -0,0 +1,18 @@
+import { CrushStep } from './crush-step';
+
+export class CrushRule {
+ max_size: number;
+ usable_size?: number;
+ min_size: number;
+ rule_id: number;
+ rule_name: string;
+ ruleset: number;
+ steps: CrushStep[];
+}
+
+export class CrushRuleConfig {
+ root: string; // The name of the node under which data should be placed.
+ name: string;
+ failure_domain: string; // The type of CRUSH nodes across which we should separate replicas.
+ device_class?: string; // The device class data should be placed on.
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/crush-step.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/crush-step.ts
new file mode 100644
index 000000000..3c46a7cd6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/crush-step.ts
@@ -0,0 +1,7 @@
+export class CrushStep {
+ op: string;
+ item_name?: string;
+ item?: number;
+ type?: string;
+ num?: number;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/daemon.interface.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/daemon.interface.ts
new file mode 100644
index 000000000..c69a27851
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/daemon.interface.ts
@@ -0,0 +1,12 @@
+export interface Daemon {
+ nodename: string;
+ container_id: string;
+ container_image_id: string;
+ container_image_name: string;
+ daemon_id: string;
+ daemon_type: string;
+ version: string;
+ status: number;
+ status_desc: string;
+ last_refresh: Date;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/devices.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/devices.ts
new file mode 100644
index 000000000..69ab3f5f3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/devices.ts
@@ -0,0 +1,25 @@
+/**
+ * Fields returned by the back-end.
+ */
+export interface CephDevice {
+ devid: string;
+ location: { host: string; dev: string }[];
+ daemons: string[];
+ life_expectancy_min?: string;
+ life_expectancy_max?: string;
+ life_expectancy_stamp?: string;
+ life_expectancy_enabled?: boolean;
+}
+
+/**
+ * Fields added by the front-end. Fields may be empty if no expectancy is provided for the
+ * CephDevice interface.
+ */
+export interface CdDevice extends CephDevice {
+ life_expectancy_weeks?: {
+ max: number;
+ min: number;
+ };
+ state?: 'good' | 'warning' | 'bad' | 'stale' | 'unknown';
+ readableDaemons?: string; // Human readable daemons (which can wrap lines inside the table cell)
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/erasure-code-profile.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/erasure-code-profile.ts
new file mode 100644
index 000000000..ea9985ccd
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/erasure-code-profile.ts
@@ -0,0 +1,17 @@
+export class ErasureCodeProfile {
+ name: string;
+ plugin: string;
+ k?: number;
+ m?: number;
+ c?: number;
+ l?: number;
+ d?: number;
+ packetsize?: number;
+ technique?: string;
+ scalar_mds?: 'jerasure' | 'isa' | 'shec';
+ 'crush-root'?: string;
+ 'crush-locality'?: string;
+ 'crush-failure-domain'?: string;
+ 'crush-device-class'?: string;
+ 'directory'?: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/executing-task.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/executing-task.ts
new file mode 100644
index 000000000..27dc5968e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/executing-task.ts
@@ -0,0 +1,6 @@
+import { Task } from './task';
+
+export class ExecutingTask extends Task {
+ begin_time: number;
+ progress: number;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/finished-task.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/finished-task.ts
new file mode 100644
index 000000000..9e7dd5f98
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/finished-task.ts
@@ -0,0 +1,15 @@
+import { Task } from './task';
+import { TaskException } from './task-exception';
+
+export class FinishedTask extends Task {
+ begin_time: string;
+ end_time: string;
+ exception: TaskException;
+ latency: number;
+ progress: number;
+ ret_value: any;
+ success: boolean;
+ duration: number;
+
+ errorMessage: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/flag.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/flag.ts
new file mode 100644
index 000000000..075decbf7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/flag.ts
@@ -0,0 +1,8 @@
+export class Flag {
+ code: 'noout' | 'noin' | 'nodown' | 'noup';
+ name: string;
+ description: string;
+ value: boolean;
+ clusterWide: boolean;
+ indeterminate: boolean;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/image-spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/image-spec.ts
new file mode 100644
index 000000000..8b56b291c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/image-spec.ts
@@ -0,0 +1,25 @@
+export class ImageSpec {
+ static fromString(imageSpec: string) {
+ const imageSpecSplited = imageSpec.split('/');
+
+ const poolName = imageSpecSplited[0];
+ const namespace = imageSpecSplited.length >= 3 ? imageSpecSplited[1] : null;
+ const imageName = imageSpecSplited.length >= 3 ? imageSpecSplited[2] : imageSpecSplited[1];
+
+ return new this(poolName, namespace, imageName);
+ }
+
+ constructor(public poolName: string, public namespace: string, public imageName: string) {}
+
+ private getNameSpace() {
+ return this.namespace ? `${this.namespace}/` : '';
+ }
+
+ toString() {
+ return `${this.poolName}/${this.getNameSpace()}${this.imageName}`;
+ }
+
+ toStringEncoded() {
+ return encodeURIComponent(`${this.poolName}/${this.getNameSpace()}${this.imageName}`);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/inventory-device-type.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/inventory-device-type.model.ts
new file mode 100644
index 000000000..2155c2d87
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/inventory-device-type.model.ts
@@ -0,0 +1,9 @@
+import { InventoryDevice } from '~/app/ceph/cluster/inventory/inventory-devices/inventory-device.model';
+
+export interface InventoryDeviceType {
+ type: string;
+ capacity: number;
+ devices: InventoryDevice[];
+ canSelect: boolean;
+ totalDevices: number;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/login-response.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/login-response.ts
new file mode 100644
index 000000000..12b4b8348
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/login-response.ts
@@ -0,0 +1,7 @@
+export class LoginResponse {
+ username: string;
+ permissions: object;
+ pwdExpirationDate: number;
+ sso: boolean;
+ pwdUpdateRequired: boolean;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/mirroring-summary.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/mirroring-summary.ts
new file mode 100644
index 000000000..5487fab0a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/mirroring-summary.ts
@@ -0,0 +1,5 @@
+export interface MirroringSummary {
+ content_data?: any;
+ site_name?: any;
+ status?: any;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/orchestrator.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/orchestrator.enum.ts
new file mode 100644
index 000000000..22101caaa
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/orchestrator.enum.ts
@@ -0,0 +1,25 @@
+export enum OrchestratorFeature {
+ HOST_LIST = 'get_hosts',
+ HOST_ADD = 'add_host',
+ HOST_REMOVE = 'remove_host',
+ HOST_LABEL_ADD = 'add_host_label',
+ HOST_LABEL_REMOVE = 'remove_host_label',
+ HOST_MAINTENANCE_ENTER = 'enter_host_maintenance',
+ HOST_MAINTENANCE_EXIT = 'exit_host_maintenance',
+ HOST_FACTS = 'get_facts',
+ HOST_DRAIN = 'drain_host',
+
+ SERVICE_LIST = 'describe_service',
+ SERVICE_CREATE = 'apply',
+ SERVICE_EDIT = 'apply',
+ SERVICE_DELETE = 'remove_service',
+ SERVICE_RELOAD = 'service_action',
+ DAEMON_LIST = 'list_daemons',
+
+ OSD_GET_REMOVE_STATUS = 'remove_osds_status',
+ OSD_CREATE = 'apply_drivegroups',
+ OSD_DELETE = 'remove_osds',
+
+ DEVICE_LIST = 'get_inventory',
+ DEVICE_BLINK_LIGHT = 'blink_device_light'
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/orchestrator.interface.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/orchestrator.interface.ts
new file mode 100644
index 000000000..4eceba8c0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/orchestrator.interface.ts
@@ -0,0 +1,9 @@
+export interface OrchestratorStatus {
+ available: boolean;
+ message: string;
+ features: {
+ [feature: string]: {
+ available: boolean;
+ };
+ };
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/osd-deployment-options.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/osd-deployment-options.ts
new file mode 100644
index 000000000..cae869efe
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/osd-deployment-options.ts
@@ -0,0 +1,24 @@
+export enum OsdDeploymentOptions {
+ COST_CAPACITY = 'cost_capacity',
+ THROUGHPUT = 'throughput_optimized',
+ IOPS = 'iops_optimized'
+}
+
+export interface DeploymentOption {
+ name: OsdDeploymentOptions;
+ title: string;
+ desc: string;
+ capacity: number;
+ available: boolean;
+ hdd_used: number;
+ used: number;
+ nvme_used: number;
+ ssd_used: number;
+}
+
+export interface DeploymentOptions {
+ options: {
+ [key in OsdDeploymentOptions]: DeploymentOption;
+ };
+ recommended_option: OsdDeploymentOptions;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/osd-settings.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/osd-settings.ts
new file mode 100644
index 000000000..b7bc10fc0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/osd-settings.ts
@@ -0,0 +1,4 @@
+export class OsdSettings {
+ nearfull_ratio: number;
+ full_ratio: number;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/permission.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/permission.spec.ts
new file mode 100644
index 000000000..fb2c90469
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/permission.spec.ts
@@ -0,0 +1,62 @@
+import { Permissions } from './permissions';
+
+describe('cd-notification classes', () => {
+ it('should show empty permissions', () => {
+ expect(new Permissions({})).toEqual({
+ cephfs: { create: false, delete: false, read: false, update: false },
+ configOpt: { create: false, delete: false, read: false, update: false },
+ grafana: { create: false, delete: false, read: false, update: false },
+ hosts: { create: false, delete: false, read: false, update: false },
+ iscsi: { create: false, delete: false, read: false, update: false },
+ log: { create: false, delete: false, read: false, update: false },
+ manager: { create: false, delete: false, read: false, update: false },
+ monitor: { create: false, delete: false, read: false, update: false },
+ nfs: { create: false, delete: false, read: false, update: false },
+ osd: { create: false, delete: false, read: false, update: false },
+ pool: { create: false, delete: false, read: false, update: false },
+ prometheus: { create: false, delete: false, read: false, update: false },
+ rbdImage: { create: false, delete: false, read: false, update: false },
+ rbdMirroring: { create: false, delete: false, read: false, update: false },
+ rgw: { create: false, delete: false, read: false, update: false },
+ user: { create: false, delete: false, read: false, update: false }
+ });
+ });
+
+ it('should show full permissions', () => {
+ const fullyGranted = {
+ cephfs: ['create', 'read', 'update', 'delete'],
+ 'config-opt': ['create', 'read', 'update', 'delete'],
+ grafana: ['create', 'read', 'update', 'delete'],
+ hosts: ['create', 'read', 'update', 'delete'],
+ iscsi: ['create', 'read', 'update', 'delete'],
+ log: ['create', 'read', 'update', 'delete'],
+ manager: ['create', 'read', 'update', 'delete'],
+ monitor: ['create', 'read', 'update', 'delete'],
+ osd: ['create', 'read', 'update', 'delete'],
+ pool: ['create', 'read', 'update', 'delete'],
+ prometheus: ['create', 'read', 'update', 'delete'],
+ 'rbd-image': ['create', 'read', 'update', 'delete'],
+ 'rbd-mirroring': ['create', 'read', 'update', 'delete'],
+ rgw: ['create', 'read', 'update', 'delete'],
+ user: ['create', 'read', 'update', 'delete']
+ };
+ expect(new Permissions(fullyGranted)).toEqual({
+ cephfs: { create: true, delete: true, read: true, update: true },
+ configOpt: { create: true, delete: true, read: true, update: true },
+ grafana: { create: true, delete: true, read: true, update: true },
+ hosts: { create: true, delete: true, read: true, update: true },
+ iscsi: { create: true, delete: true, read: true, update: true },
+ log: { create: true, delete: true, read: true, update: true },
+ manager: { create: true, delete: true, read: true, update: true },
+ monitor: { create: true, delete: true, read: true, update: true },
+ nfs: { create: false, delete: false, read: false, update: false },
+ osd: { create: true, delete: true, read: true, update: true },
+ pool: { create: true, delete: true, read: true, update: true },
+ prometheus: { create: true, delete: true, read: true, update: true },
+ rbdImage: { create: true, delete: true, read: true, update: true },
+ rbdMirroring: { create: true, delete: true, read: true, update: true },
+ rgw: { create: true, delete: true, read: true, update: true },
+ user: { create: true, delete: true, read: true, update: true }
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/permissions.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/permissions.ts
new file mode 100644
index 000000000..3f2c87ed1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/permissions.ts
@@ -0,0 +1,50 @@
+export class Permission {
+ read: boolean;
+ create: boolean;
+ update: boolean;
+ delete: boolean;
+
+ constructor(serverPermission: Array<string> = []) {
+ ['read', 'create', 'update', 'delete'].forEach(
+ (permission) => (this[permission] = serverPermission.includes(permission))
+ );
+ }
+}
+
+export class Permissions {
+ hosts: Permission;
+ configOpt: Permission;
+ pool: Permission;
+ osd: Permission;
+ monitor: Permission;
+ rbdImage: Permission;
+ iscsi: Permission;
+ rbdMirroring: Permission;
+ rgw: Permission;
+ cephfs: Permission;
+ manager: Permission;
+ log: Permission;
+ user: Permission;
+ grafana: Permission;
+ prometheus: Permission;
+ nfs: Permission;
+
+ constructor(serverPermissions: any) {
+ this.hosts = new Permission(serverPermissions['hosts']);
+ this.configOpt = new Permission(serverPermissions['config-opt']);
+ this.pool = new Permission(serverPermissions['pool']);
+ this.osd = new Permission(serverPermissions['osd']);
+ this.monitor = new Permission(serverPermissions['monitor']);
+ this.rbdImage = new Permission(serverPermissions['rbd-image']);
+ this.iscsi = new Permission(serverPermissions['iscsi']);
+ this.rbdMirroring = new Permission(serverPermissions['rbd-mirroring']);
+ this.rgw = new Permission(serverPermissions['rgw']);
+ this.cephfs = new Permission(serverPermissions['cephfs']);
+ this.manager = new Permission(serverPermissions['manager']);
+ this.log = new Permission(serverPermissions['log']);
+ this.user = new Permission(serverPermissions['user']);
+ this.grafana = new Permission(serverPermissions['grafana']);
+ this.prometheus = new Permission(serverPermissions['prometheus']);
+ this.nfs = new Permission(serverPermissions['nfs-ganesha']);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/pool-form-info.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/pool-form-info.ts
new file mode 100644
index 000000000..c5cc0bb6d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/pool-form-info.ts
@@ -0,0 +1,20 @@
+import { CrushNode } from './crush-node';
+import { CrushRule } from './crush-rule';
+import { ErasureCodeProfile } from './erasure-code-profile';
+
+export class PoolFormInfo {
+ pool_names: string[];
+ osd_count: number;
+ is_all_bluestore: boolean;
+ bluestore_compression_algorithm: string;
+ compression_algorithms: string[];
+ compression_modes: string[];
+ crush_rules_replicated: CrushRule[];
+ crush_rules_erasure: CrushRule[];
+ pg_autoscale_default_mode: string;
+ pg_autoscale_modes: string[];
+ erasure_code_profiles: ErasureCodeProfile[];
+ used_rules: { [rule_name: string]: string[] };
+ used_profiles: { [profile_name: string]: string[] };
+ nodes: CrushNode[];
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/prometheus-alerts.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/prometheus-alerts.ts
new file mode 100644
index 000000000..1239dcccd
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/prometheus-alerts.ts
@@ -0,0 +1,84 @@
+export class PrometheusAlertLabels {
+ alertname: string;
+ instance: string;
+ job: string;
+ severity: string;
+}
+
+class Annotations {
+ description: string;
+}
+
+class CommonAlertmanagerAlert {
+ labels: PrometheusAlertLabels;
+ annotations: Annotations;
+ startsAt: string; // Date string
+ endsAt: string; // Date string
+ generatorURL: string;
+}
+
+class PrometheusAlert {
+ labels: PrometheusAlertLabels;
+ annotations: Annotations;
+ state: 'pending' | 'firing';
+ activeAt: string; // Date string
+ value: number;
+}
+
+export interface PrometheusRuleGroup {
+ name: string;
+ file: string;
+ rules: PrometheusRule[];
+}
+
+export class PrometheusRule {
+ name: string; // => PrometheusAlertLabels.alertname
+ query: string;
+ duration: 10;
+ labels: {
+ severity: string; // => PrometheusAlertLabels.severity
+ };
+ annotations: Annotations;
+ alerts: PrometheusAlert[]; // Shows only active alerts
+ health: string;
+ type: string;
+ group?: string; // Added field for flattened list
+}
+
+export class AlertmanagerAlert extends CommonAlertmanagerAlert {
+ status: {
+ state: 'unprocessed' | 'active' | 'suppressed';
+ silencedBy: null | string[];
+ inhibitedBy: null | string[];
+ };
+ receivers: string[];
+ fingerprint: string;
+}
+
+export class AlertmanagerNotificationAlert extends CommonAlertmanagerAlert {
+ status: 'firing' | 'resolved';
+}
+
+export class AlertmanagerNotification {
+ status: 'firing' | 'resolved';
+ groupLabels: object;
+ commonAnnotations: object;
+ groupKey: string;
+ notified: string;
+ id: string;
+ alerts: AlertmanagerNotificationAlert[];
+ version: string;
+ receiver: string;
+ externalURL: string;
+ commonLabels: {
+ severity: string;
+ };
+}
+
+export class PrometheusCustomAlert {
+ status: 'resolved' | 'unprocessed' | 'active' | 'suppressed';
+ name: string;
+ url: string;
+ description: string;
+ fingerprint?: string | boolean;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/service.interface.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/service.interface.ts
new file mode 100644
index 000000000..dd64422e1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/service.interface.ts
@@ -0,0 +1,45 @@
+export interface CephServiceStatus {
+ container_image_id: string;
+ container_image_name: string;
+ size: number;
+ running: number;
+ last_refresh: Date;
+ created: Date;
+}
+
+// This will become handy when creating arbitrary services
+export interface CephServiceSpec {
+ service_name: string;
+ service_type: string;
+ service_id: string;
+ unmanaged: boolean;
+ status: CephServiceStatus;
+ spec: CephServiceAdditionalSpec;
+ placement: CephServicePlacement;
+}
+
+export interface CephServiceAdditionalSpec {
+ backend_service: string;
+ api_user: string;
+ api_password: string;
+ api_port: number;
+ api_secure: boolean;
+ rgw_frontend_port: number;
+ trusted_ip_list: string[];
+ virtual_ip: string;
+ frontend_port: number;
+ monitor_port: number;
+ virtual_interface_networks: string[];
+ pool: string;
+ rgw_frontend_ssl_certificate: string;
+ ssl: boolean;
+ ssl_cert: string;
+ ssl_key: string;
+}
+
+export interface CephServicePlacement {
+ count: number;
+ placement: string;
+ hosts: string[];
+ label: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/smart.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/smart.ts
new file mode 100644
index 000000000..f553652bc
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/smart.ts
@@ -0,0 +1,253 @@
+export interface SmartAttribute {
+ flags: {
+ auto_keep: boolean;
+ error_rate: boolean;
+ event_count: boolean;
+ performance: boolean;
+ prefailure: boolean;
+ string: string;
+ updated_online: boolean;
+ value: number;
+ };
+ id: number;
+ name: string;
+ raw: { string: string; value: number };
+ thresh: number;
+ value: number;
+ when_failed: string;
+ worst: number;
+}
+
+/**
+ * The error structure returned from the back-end if SMART data couldn't be
+ * retrieved.
+ */
+export interface SmartError {
+ dev: string;
+ error: string;
+ nvme_smart_health_information_add_log_error: string;
+ nvme_smart_health_information_add_log_error_code: number;
+ nvme_vendor: string;
+ smartctl_error_code: number;
+ smartctl_output: string;
+}
+
+/**
+ * Common smartctl output structure.
+ */
+interface SmartCtlOutput {
+ argv: string[];
+ build_info: string;
+ exit_status: number;
+ output: string[];
+ platform_info: string;
+ svn_revision: string;
+ version: number[];
+}
+
+/**
+ * Common smartctl device structure.
+ */
+interface SmartCtlDevice {
+ info_name: string;
+ name: string;
+ protocol: string;
+ type: string;
+}
+
+/**
+ * smartctl data structure shared among HDD/NVMe.
+ */
+interface SmartCtlBaseDataV1 {
+ device: SmartCtlDevice;
+ firmware_version: string;
+ json_format_version: number[];
+ local_time: { asctime: string; time_t: number };
+ logical_block_size: number;
+ model_name: string;
+ nvme_smart_health_information_add_log_error: string;
+ nvme_smart_health_information_add_log_error_code: number;
+ nvme_vendor: string;
+ power_cycle_count: number;
+ power_on_time: { hours: number };
+ serial_number: string;
+ smart_status: { passed: boolean; nvme?: { value: number } };
+ smartctl: SmartCtlOutput;
+ temperature: { current: number };
+ user_capacity: { blocks: number; bytes: number };
+}
+
+export interface RVWAttributes {
+ correction_algorithm_invocations: number;
+ errors_corrected_by_eccdelayed: number;
+ errors_corrected_by_eccfast: number;
+ errors_corrected_by_rereads_rewrites: number;
+ gigabytes_processed: number;
+ total_errors_corrected: number;
+ total_uncorrected_errors: number;
+}
+
+/**
+ * Result structure of `smartctl` applied on an SCSI. Returned by the back-end.
+ */
+export interface IscsiSmartDataV1 extends SmartCtlBaseDataV1 {
+ scsi_error_counter_log: {
+ read: RVWAttributes[];
+ };
+ scsi_grown_defect_list: number;
+}
+
+/**
+ * Result structure of `smartctl` applied on an HDD. Returned by the back-end.
+ */
+export interface AtaSmartDataV1 extends SmartCtlBaseDataV1 {
+ ata_sct_capabilities: {
+ data_table_supported: boolean;
+ error_recovery_control_supported: boolean;
+ feature_control_supported: boolean;
+ value: number;
+ };
+ ata_smart_attributes: {
+ revision: number;
+ table: SmartAttribute[];
+ };
+ ata_smart_data: {
+ capabilities: {
+ attribute_autosave_enabled: boolean;
+ conveyance_self_test_supported: boolean;
+ error_logging_supported: boolean;
+ exec_offline_immediate_supported: boolean;
+ gp_logging_supported: boolean;
+ offline_is_aborted_upon_new_cmd: boolean;
+ offline_surface_scan_supported: boolean;
+ selective_self_test_supported: boolean;
+ self_tests_supported: boolean;
+ values: number[];
+ };
+ offline_data_collection: {
+ completion_seconds: number;
+ status: { string: string; value: number };
+ };
+ self_test: {
+ polling_minutes: { conveyance: number; extended: number; short: number };
+ status: { passed: boolean; string: string; value: number };
+ };
+ };
+ ata_smart_error_log: { summary: { count: number; revision: number } };
+ ata_smart_selective_self_test_log: {
+ flags: { remainder_scan_enabled: boolean; value: number };
+ power_up_scan_resume_minutes: number;
+ revision: number;
+ table: {
+ lba_max: number;
+ lba_min: number;
+ status: { string: string; value: number };
+ }[];
+ };
+ ata_smart_self_test_log: { standard: { count: number; revision: number } };
+ ata_version: { major_value: number; minor_value: number; string: string };
+ in_smartctl_database: boolean;
+ interface_speed: {
+ current: {
+ bits_per_unit: number;
+ sata_value: number;
+ string: string;
+ units_per_second: number;
+ };
+ max: {
+ bits_per_unit: number;
+ sata_value: number;
+ string: string;
+ units_per_second: number;
+ };
+ };
+ model_family: string;
+ physical_block_size: number;
+ rotation_rate: number;
+ sata_version: { string: string; value: number };
+ smart_status: { passed: boolean };
+ smartctl: SmartCtlOutput;
+ wwn: { id: number; naa: number; oui: number };
+}
+
+/**
+ * Result structure of `smartctl` returned by Ceph and then back-end applied on
+ * an NVMe.
+ */
+export interface NvmeSmartDataV1 extends SmartCtlBaseDataV1 {
+ nvme_controller_id: number;
+ nvme_ieee_oui_identifier: number;
+ nvme_namespaces: {
+ capacity: { blocks: number; bytes: number };
+ eui64: { ext_id: number; oui: number };
+ formatted_lba_size: number;
+ id: number;
+ size: { blocks: number; bytes: number };
+ utilization: { blocks: number; bytes: number };
+ }[];
+ nvme_number_of_namespaces: number;
+ nvme_pci_vendor: { id: number; subsystem_id: number };
+ nvme_smart_health_information_log: {
+ available_spare: number;
+ available_spare_threshold: number;
+ controller_busy_time: number;
+ critical_comp_time: number;
+ critical_warning: number;
+ data_units_read: number;
+ data_units_written: number;
+ host_reads: number;
+ host_writes: number;
+ media_errors: number;
+ num_err_log_entries: number;
+ percentage_used: number;
+ power_cycles: number;
+ power_on_hours: number;
+ temperature: number;
+ temperature_sensors: number[];
+ unsafe_shutdowns: number;
+ warning_temp_time: number;
+ };
+ nvme_total_capacity: number;
+ nvme_unallocated_capacity: number;
+}
+
+/**
+ * The shared fields each result has after it has been processed by the front-end.
+ */
+interface SmartBasicResult {
+ device: string;
+ identifier: string;
+}
+
+/**
+ * The SMART data response structure of the back-end. Per device it will either
+ * contain the structure for a HDD, NVMe or an error.
+ */
+export interface SmartDataResponseV1 {
+ [deviceId: string]: AtaSmartDataV1 | NvmeSmartDataV1 | SmartError;
+}
+
+/**
+ * The SMART data result after it has been processed by the front-end.
+ */
+export interface SmartDataResult extends SmartBasicResult {
+ info: { [key: string]: any };
+ smart: {
+ attributes?: any;
+ data?: any;
+ nvmeData?: any;
+ scsi_error_counter_log?: any;
+ scsi_grown_defect_list?: any;
+ };
+}
+
+/**
+ * The SMART error result after is has been processed by the front-end. If SMART
+ * data couldn't be retrieved, this is the structure which is returned.
+ */
+export interface SmartErrorResult extends SmartBasicResult {
+ error: string;
+ smartctl_error_code: number;
+ smartctl_output: string;
+ userMessage: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/summary.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/summary.model.ts
new file mode 100644
index 000000000..f2854a0eb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/summary.model.ts
@@ -0,0 +1,15 @@
+import { ExecutingTask } from './executing-task';
+import { FinishedTask } from './finished-task';
+
+export class Summary {
+ executing_tasks?: ExecutingTask[];
+ filesystems?: any[];
+ finished_tasks?: FinishedTask[];
+ have_mon_connection?: boolean;
+ health_status?: string;
+ mgr_host?: string;
+ mgr_id?: string;
+ rbd_mirroring?: any;
+ rbd_pools?: any[];
+ version?: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/task-exception.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/task-exception.ts
new file mode 100644
index 000000000..ba38e4aab
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/task-exception.ts
@@ -0,0 +1,9 @@
+import { Task } from './task';
+
+export class TaskException {
+ status: number;
+ code: number;
+ component: string;
+ detail: string;
+ task: Task;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/task.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/task.ts
new file mode 100644
index 000000000..0adec5a0f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/task.ts
@@ -0,0 +1,10 @@
+export class Task {
+ constructor(name?: string, metadata?: object) {
+ this.name = name;
+ this.metadata = metadata;
+ }
+ name: string;
+ metadata: object;
+
+ description: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/wizard-steps.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/wizard-steps.ts
new file mode 100644
index 000000000..177feb486
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/wizard-steps.ts
@@ -0,0 +1,4 @@
+export interface WizardStepModel {
+ stepIndex: number;
+ isComplete: boolean;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/array.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/array.pipe.spec.ts
new file mode 100755
index 000000000..610e22c43
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/array.pipe.spec.ts
@@ -0,0 +1,21 @@
+import { ArrayPipe } from './array.pipe';
+
+describe('ArrayPipe', () => {
+ const pipe = new ArrayPipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms string to array', () => {
+ expect(pipe.transform('foo')).toStrictEqual(['foo']);
+ });
+
+ it('transforms array to array', () => {
+ expect(pipe.transform(['foo'], true)).toStrictEqual([['foo']]);
+ });
+
+ it('do not transforms array to array', () => {
+ expect(pipe.transform(['foo'])).toStrictEqual(['foo']);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/array.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/array.pipe.ts
new file mode 100755
index 000000000..f82e35316
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/array.pipe.ts
@@ -0,0 +1,26 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import _ from 'lodash';
+
+/**
+ * Convert the given value to an array.
+ */
+@Pipe({
+ name: 'array'
+})
+export class ArrayPipe implements PipeTransform {
+ /**
+ * Convert the given value into an array. If the value is already an
+ * array, then nothing happens, except the `force` flag is set.
+ * @param value The value to process.
+ * @param force Convert the specified value to an array, either it is
+ * already an array.
+ */
+ transform(value: any, force = false): any[] {
+ let result = value;
+ if (!_.isArray(value) || (_.isArray(value) && force)) {
+ result = [value];
+ }
+ return result;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean-text.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean-text.pipe.spec.ts
new file mode 100644
index 000000000..a0b8019a7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean-text.pipe.spec.ts
@@ -0,0 +1,37 @@
+import { BooleanTextPipe } from './boolean-text.pipe';
+
+describe('BooleanTextPipe', () => {
+ let pipe: BooleanTextPipe;
+
+ beforeEach(() => {
+ pipe = new BooleanTextPipe();
+ });
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms true', () => {
+ expect(pipe.transform(true)).toEqual('Yes');
+ });
+
+ it('transforms true, alternative text', () => {
+ expect(pipe.transform(true, 'foo')).toEqual('foo');
+ });
+
+ it('transforms 1', () => {
+ expect(pipe.transform(1)).toEqual('Yes');
+ });
+
+ it('transforms false', () => {
+ expect(pipe.transform(false)).toEqual('No');
+ });
+
+ it('transforms false, alternative text', () => {
+ expect(pipe.transform(false, 'foo', 'bar')).toEqual('bar');
+ });
+
+ it('transforms 0', () => {
+ expect(pipe.transform(0)).toEqual('No');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean-text.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean-text.pipe.ts
new file mode 100644
index 000000000..70432f9be
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean-text.pipe.ts
@@ -0,0 +1,14 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'booleanText'
+})
+export class BooleanTextPipe implements PipeTransform {
+ transform(
+ value: any,
+ truthyText: string = $localize`Yes`,
+ falsyText: string = $localize`No`
+ ): string {
+ return Boolean(value) ? truthyText : falsyText;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean.pipe.spec.ts
new file mode 100755
index 000000000..36c5ed021
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean.pipe.spec.ts
@@ -0,0 +1,57 @@
+import { BooleanPipe } from './boolean.pipe';
+
+describe('BooleanPipe', () => {
+ const pipe = new BooleanPipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms to false [1/4]', () => {
+ expect(pipe.transform('n')).toBe(false);
+ });
+
+ it('transforms to false [2/4]', () => {
+ expect(pipe.transform(false)).toBe(false);
+ });
+
+ it('transforms to false [3/4]', () => {
+ expect(pipe.transform('bar')).toBe(false);
+ });
+
+ it('transforms to false [4/4]', () => {
+ expect(pipe.transform(2)).toBe(false);
+ });
+
+ it('transforms to true [1/8]', () => {
+ expect(pipe.transform(true)).toBe(true);
+ });
+
+ it('transforms to true [2/8]', () => {
+ expect(pipe.transform(1)).toBe(true);
+ });
+
+ it('transforms to true [3/8]', () => {
+ expect(pipe.transform('y')).toBe(true);
+ });
+
+ it('transforms to true [4/8]', () => {
+ expect(pipe.transform('yes')).toBe(true);
+ });
+
+ it('transforms to true [5/8]', () => {
+ expect(pipe.transform('t')).toBe(true);
+ });
+
+ it('transforms to true [6/8]', () => {
+ expect(pipe.transform('true')).toBe(true);
+ });
+
+ it('transforms to true [7/8]', () => {
+ expect(pipe.transform('on')).toBe(true);
+ });
+
+ it('transforms to true [8/8]', () => {
+ expect(pipe.transform('1')).toBe(true);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean.pipe.ts
new file mode 100755
index 000000000..b94a40bc4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean.pipe.ts
@@ -0,0 +1,26 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+/**
+ * Convert the given value to a boolean value.
+ */
+@Pipe({
+ name: 'boolean'
+})
+export class BooleanPipe implements PipeTransform {
+ transform(value: any): boolean {
+ let result = false;
+ switch (value) {
+ case true:
+ case 1:
+ case 'y':
+ case 'yes':
+ case 't':
+ case 'true':
+ case 'on':
+ case '1':
+ result = true;
+ break;
+ }
+ return result;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/cd-date.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/cd-date.pipe.spec.ts
new file mode 100644
index 000000000..b67ed62c8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/cd-date.pipe.spec.ts
@@ -0,0 +1,24 @@
+import { DatePipe } from '@angular/common';
+
+import moment from 'moment';
+
+import { CdDatePipe } from './cd-date.pipe';
+
+describe('CdDatePipe', () => {
+ const datePipe = new DatePipe('en-US');
+ let pipe = new CdDatePipe(datePipe);
+
+ it('create an instance', () => {
+ pipe = new CdDatePipe(datePipe);
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms without value', () => {
+ expect(pipe.transform('')).toBe('');
+ });
+
+ it('transforms with some date', () => {
+ const result = moment(1527085564486).format('M/D/YY LTS');
+ expect(pipe.transform(1527085564486)).toBe(result);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/cd-date.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/cd-date.pipe.ts
new file mode 100644
index 000000000..911f32041
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/cd-date.pipe.ts
@@ -0,0 +1,20 @@
+import { DatePipe } from '@angular/common';
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'cdDate'
+})
+export class CdDatePipe implements PipeTransform {
+ constructor(private datePipe: DatePipe) {}
+
+ transform(value: any): any {
+ if (value === null || value === '') {
+ return '';
+ }
+ return (
+ this.datePipe.transform(value, 'shortDate') +
+ ' ' +
+ this.datePipe.transform(value, 'mediumTime')
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-release-name.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-release-name.pipe.spec.ts
new file mode 100644
index 000000000..3e1f1f7ca
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-release-name.pipe.spec.ts
@@ -0,0 +1,28 @@
+import { CephReleaseNamePipe } from './ceph-release-name.pipe';
+
+describe('CephReleaseNamePipe', () => {
+ const pipe = new CephReleaseNamePipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('recognizes a stable release', () => {
+ const value =
+ 'ceph version 13.2.1 \
+ (5533ecdc0fda920179d7ad84e0aa65a127b20d77) mimic (stable)';
+ expect(pipe.transform(value)).toBe('mimic');
+ });
+
+ it('recognizes a development release as the main branch', () => {
+ const value =
+ 'ceph version 13.1.0-534-g23d3751b89 \
+ (23d3751b897b31d2bda57aeaf01acb5ff3c4a9cd) nautilus (dev)';
+ expect(pipe.transform(value)).toBe('main');
+ });
+
+ it('transforms with wrong version format', () => {
+ const value = 'foo';
+ expect(pipe.transform(value)).toBe('foo');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-release-name.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-release-name.pipe.ts
new file mode 100644
index 000000000..c63c794a9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-release-name.pipe.ts
@@ -0,0 +1,24 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'cephReleaseName'
+})
+export class CephReleaseNamePipe implements PipeTransform {
+ transform(value: any): any {
+ // Expect "ceph version 13.1.0-419-g251e2515b5
+ // (251e2515b563856349498c6caf34e7a282f62937) nautilus (dev)"
+ const result = /ceph version\s+[^ ]+\s+\(.+\)\s+(.+)\s+\((.+)\)/.exec(value);
+ if (result) {
+ if (result[2] === 'dev') {
+ // Assume this is actually main
+ return 'main';
+ } else {
+ // Return the "nautilus" part
+ return result[1];
+ }
+ } else {
+ // Unexpected format, pass it through
+ return value;
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-short-version.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-short-version.pipe.spec.ts
new file mode 100644
index 000000000..0242839df
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-short-version.pipe.spec.ts
@@ -0,0 +1,21 @@
+import { CephShortVersionPipe } from './ceph-short-version.pipe';
+
+describe('CephShortVersionPipe', () => {
+ const pipe = new CephShortVersionPipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms with correct version format', () => {
+ const value =
+ 'ceph version 13.1.0-534-g23d3751b89 \
+ (23d3751b897b31d2bda57aeaf01acb5ff3c4a9cd) nautilus (dev)';
+ expect(pipe.transform(value)).toBe('13.1.0-534-g23d3751b89');
+ });
+
+ it('transforms with wrong version format', () => {
+ const value = 'foo';
+ expect(pipe.transform(value)).toBe('foo');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-short-version.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-short-version.pipe.ts
new file mode 100644
index 000000000..03e75dfb3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-short-version.pipe.ts
@@ -0,0 +1,18 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'cephShortVersion'
+})
+export class CephShortVersionPipe implements PipeTransform {
+ transform(value: any): any {
+ // Expect "ceph version 1.2.3-g9asdasd (as98d7a0s8d7)"
+ const result = /ceph version\s+([^ ]+)\s+\(.+\)/.exec(value);
+ if (result) {
+ // Return the "1.2.3-g9asdasd" part
+ return result[1];
+ } else {
+ // Unexpected format, pass it through
+ return value;
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless-binary-per-second.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless-binary-per-second.pipe.ts
new file mode 100644
index 000000000..21b596317
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless-binary-per-second.pipe.ts
@@ -0,0 +1,24 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import { FormatterService } from '../services/formatter.service';
+
+@Pipe({
+ name: 'dimlessBinaryPerSecond'
+})
+export class DimlessBinaryPerSecondPipe implements PipeTransform {
+ constructor(private formatter: FormatterService) {}
+
+ transform(value: any): any {
+ return this.formatter.format_number(value, 1024, [
+ 'B/s',
+ 'kB/s',
+ 'MB/s',
+ 'GB/s',
+ 'TB/s',
+ 'PB/s',
+ 'EB/s',
+ 'ZB/s',
+ 'YB/s'
+ ]);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless-binary.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless-binary.pipe.spec.ts
new file mode 100644
index 000000000..caf51f578
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless-binary.pipe.spec.ts
@@ -0,0 +1,56 @@
+import { FormatterService } from '../services/formatter.service';
+import { DimlessBinaryPipe } from './dimless-binary.pipe';
+
+describe('DimlessBinaryPipe', () => {
+ const formatterService = new FormatterService();
+ const pipe = new DimlessBinaryPipe(formatterService);
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms 1024^0', () => {
+ const value = Math.pow(1024, 0);
+ expect(pipe.transform(value)).toBe('1 B');
+ });
+
+ it('transforms 1024^1', () => {
+ const value = Math.pow(1024, 1);
+ expect(pipe.transform(value)).toBe('1 KiB');
+ });
+
+ it('transforms 1024^2', () => {
+ const value = Math.pow(1024, 2);
+ expect(pipe.transform(value)).toBe('1 MiB');
+ });
+
+ it('transforms 1024^3', () => {
+ const value = Math.pow(1024, 3);
+ expect(pipe.transform(value)).toBe('1 GiB');
+ });
+
+ it('transforms 1024^4', () => {
+ const value = Math.pow(1024, 4);
+ expect(pipe.transform(value)).toBe('1 TiB');
+ });
+
+ it('transforms 1024^5', () => {
+ const value = Math.pow(1024, 5);
+ expect(pipe.transform(value)).toBe('1 PiB');
+ });
+
+ it('transforms 1024^6', () => {
+ const value = Math.pow(1024, 6);
+ expect(pipe.transform(value)).toBe('1 EiB');
+ });
+
+ it('transforms 1024^7', () => {
+ const value = Math.pow(1024, 7);
+ expect(pipe.transform(value)).toBe('1 ZiB');
+ });
+
+ it('transforms 1024^8', () => {
+ const value = Math.pow(1024, 8);
+ expect(pipe.transform(value)).toBe('1 YiB');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless-binary.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless-binary.pipe.ts
new file mode 100644
index 000000000..cf5d2cdec
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless-binary.pipe.ts
@@ -0,0 +1,24 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import { FormatterService } from '../services/formatter.service';
+
+@Pipe({
+ name: 'dimlessBinary'
+})
+export class DimlessBinaryPipe implements PipeTransform {
+ constructor(private formatter: FormatterService) {}
+
+ transform(value: any): any {
+ return this.formatter.format_number(value, 1024, [
+ 'B',
+ 'KiB',
+ 'MiB',
+ 'GiB',
+ 'TiB',
+ 'PiB',
+ 'EiB',
+ 'ZiB',
+ 'YiB'
+ ]);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.spec.ts
new file mode 100644
index 000000000..8d01678f7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.spec.ts
@@ -0,0 +1,56 @@
+import { FormatterService } from '../services/formatter.service';
+import { DimlessPipe } from './dimless.pipe';
+
+describe('DimlessPipe', () => {
+ const formatterService = new FormatterService();
+ const pipe = new DimlessPipe(formatterService);
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms 1000^0', () => {
+ const value = Math.pow(1000, 0);
+ expect(pipe.transform(value)).toBe('1');
+ });
+
+ it('transforms 1000^1', () => {
+ const value = Math.pow(1000, 1);
+ expect(pipe.transform(value)).toBe('1 k');
+ });
+
+ it('transforms 1000^2', () => {
+ const value = Math.pow(1000, 2);
+ expect(pipe.transform(value)).toBe('1 M');
+ });
+
+ it('transforms 1000^3', () => {
+ const value = Math.pow(1000, 3);
+ expect(pipe.transform(value)).toBe('1 G');
+ });
+
+ it('transforms 1000^4', () => {
+ const value = Math.pow(1000, 4);
+ expect(pipe.transform(value)).toBe('1 T');
+ });
+
+ it('transforms 1000^5', () => {
+ const value = Math.pow(1000, 5);
+ expect(pipe.transform(value)).toBe('1 P');
+ });
+
+ it('transforms 1000^6', () => {
+ const value = Math.pow(1000, 6);
+ expect(pipe.transform(value)).toBe('1 E');
+ });
+
+ it('transforms 1000^7', () => {
+ const value = Math.pow(1000, 7);
+ expect(pipe.transform(value)).toBe('1 Z');
+ });
+
+ it('transforms 1000^8', () => {
+ const value = Math.pow(1000, 8);
+ expect(pipe.transform(value)).toBe('1 Y');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.ts
new file mode 100644
index 000000000..1be11590d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.ts
@@ -0,0 +1,14 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import { FormatterService } from '../services/formatter.service';
+
+@Pipe({
+ name: 'dimless'
+})
+export class DimlessPipe implements PipeTransform {
+ constructor(private formatter: FormatterService) {}
+
+ transform(value: any): any {
+ return this.formatter.format_number(value, 1000, ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/duration.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/duration.pipe.spec.ts
new file mode 100644
index 000000000..1b0e22578
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/duration.pipe.spec.ts
@@ -0,0 +1,17 @@
+import { DurationPipe } from './duration.pipe';
+
+describe('DurationPipe', () => {
+ const pipe = new DurationPipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms seconds into a human readable duration', () => {
+ expect(pipe.transform(0)).toBe('1 second');
+ expect(pipe.transform(6)).toBe('6 seconds');
+ expect(pipe.transform(60)).toBe('1 minute');
+ expect(pipe.transform(600)).toBe('10 minutes');
+ expect(pipe.transform(6000)).toBe('1 hour 40 minutes');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/duration.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/duration.pipe.ts
new file mode 100644
index 000000000..4675fc0f6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/duration.pipe.ts
@@ -0,0 +1,37 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'duration',
+ pure: false
+})
+export class DurationPipe implements PipeTransform {
+ /**
+ * Translates seconds into human readable format of seconds, minutes, hours, days, and years
+ * source: https://stackoverflow.com/a/34270811
+ *
+ * @param {number} seconds The number of seconds to be processed
+ * @return {string} The phrase describing the the amount of time
+ */
+ transform(seconds: number): string {
+ const levels = [
+ [`${Math.floor(seconds / 31536000)}`, 'years'],
+ [`${Math.floor((seconds % 31536000) / 86400)}`, 'days'],
+ [`${Math.floor((seconds % 86400) / 3600)}`, 'hours'],
+ [`${Math.floor((seconds % 3600) / 60)}`, 'minutes'],
+ [`${Math.floor(seconds % 60)}`, 'seconds']
+ ];
+ let returntext = '';
+
+ for (let i = 0, max = levels.length; i < max; i++) {
+ if (levels[i][0] === '0') {
+ continue;
+ }
+ returntext +=
+ ' ' +
+ levels[i][0] +
+ ' ' +
+ (levels[i][0] === '1' ? levels[i][1].substr(0, levels[i][1].length - 1) : levels[i][1]);
+ }
+ return returntext.trim() || '1 second';
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/empty.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/empty.pipe.spec.ts
new file mode 100644
index 000000000..e73420f6a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/empty.pipe.spec.ts
@@ -0,0 +1,18 @@
+import { EmptyPipe } from './empty.pipe';
+
+describe('EmptyPipe', () => {
+ const pipe = new EmptyPipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms with empty value', () => {
+ expect(pipe.transform(undefined)).toBe('-');
+ });
+
+ it('transforms with some value', () => {
+ const value = 'foo';
+ expect(pipe.transform(value)).toBe('foo');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/empty.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/empty.pipe.ts
new file mode 100644
index 000000000..fb753e8d9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/empty.pipe.ts
@@ -0,0 +1,12 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import _ from 'lodash';
+
+@Pipe({
+ name: 'empty'
+})
+export class EmptyPipe implements PipeTransform {
+ transform(value: any): any {
+ return _.isUndefined(value) || _.isNull(value) ? '-' : value;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/encode-uri.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/encode-uri.pipe.spec.ts
new file mode 100644
index 000000000..a43674093
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/encode-uri.pipe.spec.ts
@@ -0,0 +1,13 @@
+import { EncodeUriPipe } from './encode-uri.pipe';
+
+describe('EncodeUriPipe', () => {
+ it('create an instance', () => {
+ const pipe = new EncodeUriPipe();
+ expect(pipe).toBeTruthy();
+ });
+
+ it('should transforms the value', () => {
+ const pipe = new EncodeUriPipe();
+ expect(pipe.transform('rbd/name')).toBe('rbd%2Fname');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/encode-uri.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/encode-uri.pipe.ts
new file mode 100644
index 000000000..48fbf1668
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/encode-uri.pipe.ts
@@ -0,0 +1,10 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'encodeUri'
+})
+export class EncodeUriPipe implements PipeTransform {
+ transform(value: any): any {
+ return encodeURIComponent(value);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/filter.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/filter.pipe.spec.ts
new file mode 100644
index 000000000..58d7ff95f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/filter.pipe.spec.ts
@@ -0,0 +1,54 @@
+import { FilterPipe } from './filter.pipe';
+
+describe('FilterPipe', () => {
+ const pipe = new FilterPipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('filter words with "foo"', () => {
+ const value = ['foo', 'bar', 'foobar'];
+ const filters = [
+ {
+ value: 'foo',
+ applyFilter: (row: any[], val: any) => {
+ return row.indexOf(val) !== -1;
+ }
+ }
+ ];
+ expect(pipe.transform(value, filters)).toEqual(['foo', 'foobar']);
+ });
+
+ it('filter words with "foo" and "bar"', () => {
+ const value = ['foo', 'bar', 'foobar'];
+ const filters = [
+ {
+ value: 'foo',
+ applyFilter: (row: any[], val: any) => {
+ return row.indexOf(val) !== -1;
+ }
+ },
+ {
+ value: 'bar',
+ applyFilter: (row: any[], val: any) => {
+ return row.indexOf(val) !== -1;
+ }
+ }
+ ];
+ expect(pipe.transform(value, filters)).toEqual(['foobar']);
+ });
+
+ it('filter with no value', () => {
+ const value = ['foo', 'bar', 'foobar'];
+ const filters = [
+ {
+ value: '',
+ applyFilter: () => {
+ return false;
+ }
+ }
+ ];
+ expect(pipe.transform(value, filters)).toEqual(['foo', 'bar', 'foobar']);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/filter.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/filter.pipe.ts
new file mode 100644
index 000000000..313ac4c0d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/filter.pipe.ts
@@ -0,0 +1,25 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'filter'
+})
+export class FilterPipe implements PipeTransform {
+ transform(value: any, args?: any): any {
+ return value.filter((row: any) => {
+ let result = true;
+
+ args.forEach((filter: any): boolean | void => {
+ if (!filter.value) {
+ return undefined;
+ }
+
+ result = result && filter.applyFilter(row, filter.value);
+ if (!result) {
+ return result;
+ }
+ });
+
+ return result;
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-color.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-color.pipe.spec.ts
new file mode 100644
index 000000000..f5e937ce3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-color.pipe.spec.ts
@@ -0,0 +1,47 @@
+import { CssHelper } from '~/app/shared/classes/css-helper';
+import { HealthColorPipe } from '~/app/shared/pipes/health-color.pipe';
+
+class CssHelperStub extends CssHelper {
+ propertyValue(propertyName: string) {
+ if (propertyName === 'health-color-healthy') {
+ return 'fakeGreen';
+ }
+ if (propertyName === 'health-color-warning') {
+ return 'fakeOrange';
+ }
+ if (propertyName === 'health-color-error') {
+ return 'fakeRed';
+ }
+ return '';
+ }
+}
+
+describe('HealthColorPipe', () => {
+ const pipe = new HealthColorPipe(new CssHelperStub());
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms "HEALTH_OK"', () => {
+ expect(pipe.transform('HEALTH_OK')).toEqual({
+ color: 'fakeGreen'
+ });
+ });
+
+ it('transforms "HEALTH_WARN"', () => {
+ expect(pipe.transform('HEALTH_WARN')).toEqual({
+ color: 'fakeOrange'
+ });
+ });
+
+ it('transforms "HEALTH_ERR"', () => {
+ expect(pipe.transform('HEALTH_ERR')).toEqual({
+ color: 'fakeRed'
+ });
+ });
+
+ it('transforms others', () => {
+ expect(pipe.transform('abc')).toBe(null);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-color.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-color.pipe.ts
new file mode 100644
index 000000000..d046fa15a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-color.pipe.ts
@@ -0,0 +1,17 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import { CssHelper } from '~/app/shared/classes/css-helper';
+import { HealthColor } from '~/app/shared/enum/health-color.enum';
+
+@Pipe({
+ name: 'healthColor'
+})
+export class HealthColorPipe implements PipeTransform {
+ constructor(private cssHelper: CssHelper) {}
+
+ transform(value: any): any {
+ return Object.keys(HealthColor).includes(value as HealthColor)
+ ? { color: this.cssHelper.propertyValue(HealthColor[value]) }
+ : null;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iops.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iops.pipe.spec.ts
new file mode 100644
index 000000000..dac353ddf
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iops.pipe.spec.ts
@@ -0,0 +1,8 @@
+import { IopsPipe } from './iops.pipe';
+
+describe('IopsPipe', () => {
+ it('create an instance', () => {
+ const pipe = new IopsPipe();
+ expect(pipe).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iops.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iops.pipe.ts
new file mode 100644
index 000000000..9644801f8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iops.pipe.ts
@@ -0,0 +1,10 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'iops'
+})
+export class IopsPipe implements PipeTransform {
+ transform(value: any): any {
+ return `${value} IOPS`;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iscsi-backstore.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iscsi-backstore.pipe.spec.ts
new file mode 100644
index 000000000..c82e37554
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iscsi-backstore.pipe.spec.ts
@@ -0,0 +1,17 @@
+import { IscsiBackstorePipe } from './iscsi-backstore.pipe';
+
+describe('IscsiBackstorePipe', () => {
+ const pipe = new IscsiBackstorePipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms "user:rbd"', () => {
+ expect(pipe.transform('user:rbd')).toBe('user:rbd (tcmu-runner)');
+ });
+
+ it('transforms "other"', () => {
+ expect(pipe.transform('other')).toBe('other');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iscsi-backstore.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iscsi-backstore.pipe.ts
new file mode 100644
index 000000000..19a0d66c1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iscsi-backstore.pipe.ts
@@ -0,0 +1,15 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'iscsiBackstore'
+})
+export class IscsiBackstorePipe implements PipeTransform {
+ transform(value: any): any {
+ switch (value) {
+ case 'user:rbd':
+ return 'user:rbd (tcmu-runner)';
+ default:
+ return value;
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/join.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/join.pipe.spec.ts
new file mode 100644
index 000000000..01bccbc2d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/join.pipe.spec.ts
@@ -0,0 +1,13 @@
+import { JoinPipe } from './join.pipe';
+
+describe('ListPipe', () => {
+ const pipe = new JoinPipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms "[1,2,3]"', () => {
+ expect(pipe.transform([1, 2, 3])).toBe('1, 2, 3');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/join.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/join.pipe.ts
new file mode 100644
index 000000000..68610846e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/join.pipe.ts
@@ -0,0 +1,10 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'join'
+})
+export class JoinPipe implements PipeTransform {
+ transform(value: Array<any>): string {
+ return value.join(', ');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/log-priority.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/log-priority.pipe.spec.ts
new file mode 100644
index 000000000..45d677c2a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/log-priority.pipe.spec.ts
@@ -0,0 +1,32 @@
+import { LogPriorityPipe } from './log-priority.pipe';
+
+describe('LogPriorityPipe', () => {
+ const pipe = new LogPriorityPipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms "INF"', () => {
+ const value = '[INF]';
+ const result = 'info';
+ expect(pipe.transform(value)).toEqual(result);
+ });
+
+ it('transforms "WRN"', () => {
+ const value = '[WRN]';
+ const result = 'warn';
+ expect(pipe.transform(value)).toEqual(result);
+ });
+
+ it('transforms "ERR"', () => {
+ const value = '[ERR]';
+ const result = 'err';
+ expect(pipe.transform(value)).toEqual(result);
+ });
+
+ it('transforms others', () => {
+ const value = '[foo]';
+ expect(pipe.transform(value)).toBe('');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/log-priority.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/log-priority.pipe.ts
new file mode 100644
index 000000000..0c51c867b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/log-priority.pipe.ts
@@ -0,0 +1,20 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'logPriority'
+})
+export class LogPriorityPipe implements PipeTransform {
+ transform(value: any): any {
+ if (value === '[DBG]') {
+ return 'debug';
+ } else if (value === '[INF]') {
+ return 'info';
+ } else if (value === '[WRN]') {
+ return 'warn';
+ } else if (value === '[ERR]') {
+ return 'err';
+ } else {
+ return ''; // Inherit
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/map.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/map.pipe.spec.ts
new file mode 100644
index 000000000..337d5c37b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/map.pipe.spec.ts
@@ -0,0 +1,25 @@
+import { MapPipe } from './map.pipe';
+
+describe('MapPipe', () => {
+ const pipe = new MapPipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('map value [1]', () => {
+ expect(pipe.transform('foo')).toBe('foo');
+ });
+
+ it('map value [2]', () => {
+ expect(pipe.transform('foo', { '-1': 'disabled', 0: 'unlimited' })).toBe('foo');
+ });
+
+ it('map value [3]', () => {
+ expect(pipe.transform(-1, { '-1': 'disabled', 0: 'unlimited' })).toBe('disabled');
+ });
+
+ it('map value [4]', () => {
+ expect(pipe.transform(0, { '-1': 'disabled', 0: 'unlimited' })).toBe('unlimited');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/map.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/map.pipe.ts
new file mode 100644
index 000000000..1c0839d08
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/map.pipe.ts
@@ -0,0 +1,15 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import _ from 'lodash';
+
+@Pipe({
+ name: 'map'
+})
+export class MapPipe implements PipeTransform {
+ transform(value: string | number, map?: object): any {
+ if (!_.isPlainObject(map)) {
+ return value;
+ }
+ return _.get(map, value, value);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/milliseconds.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/milliseconds.pipe.spec.ts
new file mode 100644
index 000000000..cea4bb13f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/milliseconds.pipe.spec.ts
@@ -0,0 +1,8 @@
+import { MillisecondsPipe } from './milliseconds.pipe';
+
+describe('MillisecondsPipe', () => {
+ it('create an instance', () => {
+ const pipe = new MillisecondsPipe();
+ expect(pipe).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/milliseconds.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/milliseconds.pipe.ts
new file mode 100644
index 000000000..b0dc68604
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/milliseconds.pipe.ts
@@ -0,0 +1,10 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'milliseconds'
+})
+export class MillisecondsPipe implements PipeTransform {
+ transform(value: any): any {
+ return `${value} ms`;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/not-available.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/not-available.pipe.spec.ts
new file mode 100644
index 000000000..06279a5ea
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/not-available.pipe.spec.ts
@@ -0,0 +1,30 @@
+import { NotAvailablePipe } from './not-available.pipe';
+
+describe('NotAvailablePipe', () => {
+ let pipe: NotAvailablePipe;
+
+ beforeEach(() => {
+ pipe = new NotAvailablePipe();
+ });
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms not available (1)', () => {
+ expect(pipe.transform('')).toBe('n/a');
+ });
+
+ it('transforms not available (2)', () => {
+ expect(pipe.transform('', 'Unknown')).toBe('Unknown');
+ });
+
+ it('transform not necessary (1)', () => {
+ expect(pipe.transform(0)).toBe(0);
+ expect(pipe.transform(1)).toBe(1);
+ });
+
+ it('transform not necessary (2)', () => {
+ expect(pipe.transform('foo')).toBe('foo');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/not-available.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/not-available.pipe.ts
new file mode 100644
index 000000000..9d0222724
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/not-available.pipe.ts
@@ -0,0 +1,15 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import _ from 'lodash';
+
+@Pipe({
+ name: 'notAvailable'
+})
+export class NotAvailablePipe implements PipeTransform {
+ transform(value: any, text?: string): any {
+ if (value === '') {
+ return _.defaultTo(text, $localize`n/a`);
+ }
+ return value;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ordinal.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ordinal.pipe.spec.ts
new file mode 100644
index 000000000..7e1cdbc8d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ordinal.pipe.spec.ts
@@ -0,0 +1,8 @@
+import { OrdinalPipe } from './ordinal.pipe';
+
+describe('OrdinalPipe', () => {
+ it('create an instance', () => {
+ const pipe = new OrdinalPipe();
+ expect(pipe).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ordinal.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ordinal.pipe.ts
new file mode 100644
index 000000000..da89a0240
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ordinal.pipe.ts
@@ -0,0 +1,25 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'ordinal'
+})
+export class OrdinalPipe implements PipeTransform {
+ transform(value: any): any {
+ const num = parseInt(value, 10);
+ if (isNaN(num)) {
+ return value;
+ }
+ return (
+ value +
+ (Math.floor(num / 10) === 1
+ ? 'th'
+ : num % 10 === 1
+ ? 'st'
+ : num % 10 === 2
+ ? 'nd'
+ : num % 10 === 3
+ ? 'rd'
+ : 'th')
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/pipes.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/pipes.module.ts
new file mode 100755
index 000000000..508a29e98
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/pipes.module.ts
@@ -0,0 +1,125 @@
+import { CommonModule, DatePipe } from '@angular/common';
+import { NgModule } from '@angular/core';
+
+import { ArrayPipe } from './array.pipe';
+import { BooleanTextPipe } from './boolean-text.pipe';
+import { BooleanPipe } from './boolean.pipe';
+import { CdDatePipe } from './cd-date.pipe';
+import { CephReleaseNamePipe } from './ceph-release-name.pipe';
+import { CephShortVersionPipe } from './ceph-short-version.pipe';
+import { DimlessBinaryPerSecondPipe } from './dimless-binary-per-second.pipe';
+import { DimlessBinaryPipe } from './dimless-binary.pipe';
+import { DimlessPipe } from './dimless.pipe';
+import { DurationPipe } from './duration.pipe';
+import { EmptyPipe } from './empty.pipe';
+import { EncodeUriPipe } from './encode-uri.pipe';
+import { FilterPipe } from './filter.pipe';
+import { HealthColorPipe } from './health-color.pipe';
+import { IopsPipe } from './iops.pipe';
+import { IscsiBackstorePipe } from './iscsi-backstore.pipe';
+import { JoinPipe } from './join.pipe';
+import { LogPriorityPipe } from './log-priority.pipe';
+import { MapPipe } from './map.pipe';
+import { MillisecondsPipe } from './milliseconds.pipe';
+import { NotAvailablePipe } from './not-available.pipe';
+import { OrdinalPipe } from './ordinal.pipe';
+import { RbdConfigurationSourcePipe } from './rbd-configuration-source.pipe';
+import { RelativeDatePipe } from './relative-date.pipe';
+import { RoundPipe } from './round.pipe';
+import { SanitizeHtmlPipe } from './sanitize-html.pipe';
+import { SearchHighlightPipe } from './search-highlight.pipe';
+import { TruncatePipe } from './truncate.pipe';
+import { UpperFirstPipe } from './upper-first.pipe';
+
+@NgModule({
+ imports: [CommonModule],
+ declarations: [
+ ArrayPipe,
+ BooleanPipe,
+ BooleanTextPipe,
+ DimlessBinaryPipe,
+ DimlessBinaryPerSecondPipe,
+ HealthColorPipe,
+ DimlessPipe,
+ CephShortVersionPipe,
+ CephReleaseNamePipe,
+ RelativeDatePipe,
+ IscsiBackstorePipe,
+ JoinPipe,
+ LogPriorityPipe,
+ FilterPipe,
+ CdDatePipe,
+ EmptyPipe,
+ EncodeUriPipe,
+ RoundPipe,
+ OrdinalPipe,
+ MillisecondsPipe,
+ NotAvailablePipe,
+ IopsPipe,
+ UpperFirstPipe,
+ RbdConfigurationSourcePipe,
+ DurationPipe,
+ MapPipe,
+ TruncatePipe,
+ SanitizeHtmlPipe,
+ SearchHighlightPipe
+ ],
+ exports: [
+ ArrayPipe,
+ BooleanPipe,
+ BooleanTextPipe,
+ DimlessBinaryPipe,
+ DimlessBinaryPerSecondPipe,
+ HealthColorPipe,
+ DimlessPipe,
+ CephShortVersionPipe,
+ CephReleaseNamePipe,
+ RelativeDatePipe,
+ IscsiBackstorePipe,
+ JoinPipe,
+ LogPriorityPipe,
+ FilterPipe,
+ CdDatePipe,
+ EmptyPipe,
+ EncodeUriPipe,
+ RoundPipe,
+ OrdinalPipe,
+ MillisecondsPipe,
+ NotAvailablePipe,
+ IopsPipe,
+ UpperFirstPipe,
+ RbdConfigurationSourcePipe,
+ DurationPipe,
+ MapPipe,
+ TruncatePipe,
+ SanitizeHtmlPipe,
+ SearchHighlightPipe
+ ],
+ providers: [
+ ArrayPipe,
+ BooleanPipe,
+ BooleanTextPipe,
+ DatePipe,
+ CephShortVersionPipe,
+ CephReleaseNamePipe,
+ DimlessBinaryPipe,
+ DimlessBinaryPerSecondPipe,
+ DimlessPipe,
+ RelativeDatePipe,
+ IscsiBackstorePipe,
+ JoinPipe,
+ LogPriorityPipe,
+ CdDatePipe,
+ EmptyPipe,
+ EncodeUriPipe,
+ OrdinalPipe,
+ IopsPipe,
+ MillisecondsPipe,
+ NotAvailablePipe,
+ UpperFirstPipe,
+ MapPipe,
+ TruncatePipe,
+ SanitizeHtmlPipe
+ ]
+})
+export class PipesModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/rbd-configuration-source.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/rbd-configuration-source.pipe.spec.ts
new file mode 100644
index 000000000..9c0346bd6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/rbd-configuration-source.pipe.spec.ts
@@ -0,0 +1,22 @@
+import { RbdConfigurationSourcePipe } from './rbd-configuration-source.pipe';
+
+describe('RbdConfigurationSourcePipePipe', () => {
+ let pipe: RbdConfigurationSourcePipe;
+
+ beforeEach(() => {
+ pipe = new RbdConfigurationSourcePipe();
+ });
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('should transform correctly', () => {
+ expect(pipe.transform('foo')).not.toBeDefined();
+ expect(pipe.transform(-1)).not.toBeDefined();
+ expect(pipe.transform(0)).toBe('global');
+ expect(pipe.transform(1)).toBe('pool');
+ expect(pipe.transform(2)).toBe('image');
+ expect(pipe.transform(-3)).not.toBeDefined();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/rbd-configuration-source.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/rbd-configuration-source.pipe.ts
new file mode 100644
index 000000000..bb42d3f1c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/rbd-configuration-source.pipe.ts
@@ -0,0 +1,15 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'rbdConfigurationSource'
+})
+export class RbdConfigurationSourcePipe implements PipeTransform {
+ transform(value: any): any {
+ const sourceMap = {
+ 0: 'global',
+ 1: 'pool',
+ 2: 'image'
+ };
+ return sourceMap[value];
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/relative-date.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/relative-date.pipe.spec.ts
new file mode 100644
index 000000000..a12d3c2a1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/relative-date.pipe.spec.ts
@@ -0,0 +1,44 @@
+import moment from 'moment';
+
+import { RelativeDatePipe } from './relative-date.pipe';
+
+describe('RelativeDatePipe', () => {
+ const pipe = new RelativeDatePipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms date into a human readable relative time (1)', () => {
+ const date: Date = moment().subtract(130, 'seconds').toDate();
+ expect(pipe.transform(date)).toBe('2 minutes ago');
+ });
+
+ it('transforms date into a human readable relative time (2)', () => {
+ const date: Date = moment().subtract(65, 'minutes').toDate();
+ expect(pipe.transform(date)).toBe('An hour ago');
+ });
+
+ it('transforms date into a human readable relative time (3)', () => {
+ const date: string = moment().subtract(130, 'minutes').toISOString();
+ expect(pipe.transform(date)).toBe('2 hours ago');
+ });
+
+ it('transforms date into a human readable relative time (4)', () => {
+ const date: string = moment().subtract(30, 'seconds').toISOString();
+ expect(pipe.transform(date, false)).toBe('a few seconds ago');
+ });
+
+ it('transforms date into a human readable relative time (5)', () => {
+ const date: number = moment().subtract(3, 'days').unix();
+ expect(pipe.transform(date)).toBe('3 days ago');
+ });
+
+ it('invalid input (1)', () => {
+ expect(pipe.transform('')).toBe('');
+ });
+
+ it('invalid input (2)', () => {
+ expect(pipe.transform('2011-10-10T10:20:90')).toBe('');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/relative-date.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/relative-date.pipe.ts
new file mode 100644
index 000000000..f802b6b2a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/relative-date.pipe.ts
@@ -0,0 +1,57 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import _ from 'lodash';
+import moment from 'moment';
+
+moment.updateLocale('en', {
+ relativeTime: {
+ future: $localize`in %s`,
+ past: $localize`%s ago`,
+ s: $localize`a few seconds`,
+ ss: $localize`%d seconds`,
+ m: $localize`a minute`,
+ mm: $localize`%d minutes`,
+ h: $localize`an hour`,
+ hh: $localize`%d hours`,
+ d: $localize`a day`,
+ dd: $localize`%d days`,
+ w: $localize`a week`,
+ ww: $localize`%d weeks`,
+ M: $localize`a month`,
+ MM: $localize`%d months`,
+ y: $localize`a year`,
+ yy: $localize`%d years`
+ }
+});
+
+@Pipe({
+ name: 'relativeDate',
+ pure: false
+})
+export class RelativeDatePipe implements PipeTransform {
+ /**
+ * Convert a time into a human readable form, e.g. '2 minutes ago'.
+ * @param {Date | string | number} value The date to convert, should be
+ * an ISO8601 string, an Unix timestamp (seconds) or Date object.
+ * @param {boolean} upperFirst Set to `true` to start the sentence
+ * upper case. Defaults to `true`.
+ * @return {string} The time in human readable form or an empty string
+ * on failure (e.g. invalid input).
+ */
+ transform(value: Date | string | number, upperFirst = true): string {
+ let date: moment.Moment;
+ if (_.isNumber(value)) {
+ date = moment.unix(value);
+ } else {
+ date = moment(value);
+ }
+ if (!date.isValid()) {
+ return '';
+ }
+ let relativeDate: string = date.fromNow();
+ if (upperFirst) {
+ relativeDate = _.upperFirst(relativeDate);
+ }
+ return relativeDate;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/round.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/round.pipe.spec.ts
new file mode 100644
index 000000000..602045263
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/round.pipe.spec.ts
@@ -0,0 +1,13 @@
+import { RoundPipe } from './round.pipe';
+
+describe('RoundPipe', () => {
+ const pipe = new RoundPipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms "1500"', () => {
+ expect(pipe.transform(1.52, 1)).toEqual(1.5);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/round.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/round.pipe.ts
new file mode 100644
index 000000000..077831ac2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/round.pipe.ts
@@ -0,0 +1,12 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import _ from 'lodash';
+
+@Pipe({
+ name: 'round'
+})
+export class RoundPipe implements PipeTransform {
+ transform(value: any, precision: number): any {
+ return _.round(value, precision);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/sanitize-html.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/sanitize-html.pipe.spec.ts
new file mode 100644
index 000000000..719f32ee5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/sanitize-html.pipe.spec.ts
@@ -0,0 +1,26 @@
+import { TestBed } from '@angular/core/testing';
+import { DomSanitizer } from '@angular/platform-browser';
+
+import { SanitizeHtmlPipe } from '~/app/shared/pipes/sanitize-html.pipe';
+import { configureTestBed } from '~/testing/unit-test-helper';
+
+describe('SanitizeHtmlPipe', () => {
+ let pipe: SanitizeHtmlPipe;
+ let domSanitizer: DomSanitizer;
+
+ configureTestBed({
+ providers: [DomSanitizer]
+ });
+
+ beforeEach(() => {
+ domSanitizer = TestBed.inject(DomSanitizer);
+ pipe = new SanitizeHtmlPipe(domSanitizer);
+ });
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ // There is no way to inject a working DomSanitizer in unit tests,
+ // so it is not possible to test the `transform` method.
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/sanitize-html.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/sanitize-html.pipe.ts
new file mode 100644
index 000000000..f6a8b0c9e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/sanitize-html.pipe.ts
@@ -0,0 +1,13 @@
+import { Pipe, PipeTransform, SecurityContext } from '@angular/core';
+import { DomSanitizer, SafeValue } from '@angular/platform-browser';
+
+@Pipe({
+ name: 'sanitizeHtml'
+})
+export class SanitizeHtmlPipe implements PipeTransform {
+ constructor(private domSanitizer: DomSanitizer) {}
+
+ transform(value: SafeValue | string | null): string | null {
+ return this.domSanitizer.sanitize(SecurityContext.HTML, value);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/search-highlight.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/search-highlight.pipe.spec.ts
new file mode 100644
index 000000000..73f8e55ed
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/search-highlight.pipe.spec.ts
@@ -0,0 +1,41 @@
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { SearchHighlightPipe } from './search-highlight.pipe';
+
+describe('SearchHighlightPipe', () => {
+ let pipe: SearchHighlightPipe;
+
+ configureTestBed({
+ providers: [SearchHighlightPipe]
+ });
+
+ beforeEach(() => {
+ pipe = TestBed.inject(SearchHighlightPipe);
+ });
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms with a matching keyword ', () => {
+ const value = 'overall HEALTH_WARN Dashboard debug mode is enabled';
+ const args = 'Dashboard';
+ const expected = 'overall HEALTH_WARN <mark>Dashboard</mark> debug mode is enabled';
+
+ expect(pipe.transform(value, args)).toEqual(expected);
+ });
+
+ it('transforms with a matching keyword having regex character', () => {
+ const value = 'loreum ipsum .? dolor sit amet';
+ const args = '.?';
+ const expected = 'loreum ipsum <mark>.?</mark> dolor sit amet';
+
+ expect(pipe.transform(value, args)).toEqual(expected);
+ });
+
+ it('transforms with empty search keyword', () => {
+ const value = 'overall HEALTH_WARN Dashboard debug mode is enabled';
+ expect(pipe.transform(value, '')).toBe(value);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/search-highlight.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/search-highlight.pipe.ts
new file mode 100644
index 000000000..c00cc46c6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/search-highlight.pipe.ts
@@ -0,0 +1,26 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'searchHighlight'
+})
+export class SearchHighlightPipe implements PipeTransform {
+ transform(value: string, args: string): string {
+ if (!args) {
+ return value;
+ }
+ args = this.escapeRegExp(args);
+ const regex = new RegExp(args, 'gi');
+ const match = value.match(regex);
+
+ if (!match) {
+ return value;
+ }
+
+ return value.replace(regex, '<mark>$&</mark>');
+ }
+
+ private escapeRegExp(str: string) {
+ // $& means the whole matched string
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/truncate.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/truncate.pipe.spec.ts
new file mode 100644
index 000000000..cc0b2fc70
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/truncate.pipe.spec.ts
@@ -0,0 +1,21 @@
+import { TruncatePipe } from './truncate.pipe';
+
+describe('TruncatePipe', () => {
+ const pipe = new TruncatePipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('should truncate string (1)', () => {
+ expect(pipe.transform('fsdfdsfs asdasd', 5, '')).toEqual('fsdfd');
+ });
+
+ it('should truncate string (2)', () => {
+ expect(pipe.transform('fsdfdsfs asdasd', 10, '...')).toEqual('fsdfdsf...');
+ });
+
+ it('should not truncate number', () => {
+ expect(pipe.transform(2, 6, '...')).toBe(2);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/truncate.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/truncate.pipe.ts
new file mode 100644
index 000000000..ff49c6386
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/truncate.pipe.ts
@@ -0,0 +1,16 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import _ from 'lodash';
+
+@Pipe({
+ name: 'truncate'
+})
+export class TruncatePipe implements PipeTransform {
+ transform(value: any, length: number, omission?: string): any {
+ if (!_.isString(value)) {
+ return value;
+ }
+ omission = _.defaultTo(omission, '');
+ return _.truncate(value, { length, omission });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/upper-first.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/upper-first.pipe.spec.ts
new file mode 100644
index 000000000..072baa04b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/upper-first.pipe.spec.ts
@@ -0,0 +1,17 @@
+import { UpperFirstPipe } from './upper-first.pipe';
+
+describe('UpperFirstPipe', () => {
+ const pipe = new UpperFirstPipe();
+
+ it('create an instance', () => {
+ expect(pipe).toBeTruthy();
+ });
+
+ it('transforms "foo"', () => {
+ expect(pipe.transform('foo')).toEqual('Foo');
+ });
+
+ it('transforms "BAR"', () => {
+ expect(pipe.transform('BAR')).toEqual('BAR');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/upper-first.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/upper-first.pipe.ts
new file mode 100644
index 000000000..b73b1bc20
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/upper-first.pipe.ts
@@ -0,0 +1,12 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import _ from 'lodash';
+
+@Pipe({
+ name: 'upperFirst'
+})
+export class UpperFirstPipe implements PipeTransform {
+ transform(value: string): string {
+ return _.upperFirst(value);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/rxjs/operators/page-visibilty.operator.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/rxjs/operators/page-visibilty.operator.ts
new file mode 100644
index 000000000..22644dcf2
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/rxjs/operators/page-visibilty.operator.ts
@@ -0,0 +1,20 @@
+import { fromEvent, Observable, partition } from 'rxjs';
+import { repeatWhen, shareReplay, takeUntil } from 'rxjs/operators';
+
+export function whenPageVisible() {
+ const visibilitychange$ = fromEvent(document, 'visibilitychange').pipe(
+ shareReplay({ refCount: true, bufferSize: 1 })
+ );
+
+ const [pageVisible$, pageHidden$] = partition(
+ visibilitychange$,
+ () => document.visibilityState === 'visible'
+ );
+
+ return function <T>(source: Observable<T>) {
+ return source.pipe(
+ takeUntil(pageHidden$),
+ repeatWhen(() => pageVisible$)
+ );
+ };
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/api-interceptor.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/api-interceptor.service.spec.ts
new file mode 100644
index 000000000..ba7c30f49
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/api-interceptor.service.spec.ts
@@ -0,0 +1,227 @@
+import { HttpClient, HttpErrorResponse } from '@angular/common/http';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { Router } from '@angular/router';
+
+import { ToastrService } from 'ngx-toastr';
+
+import { AppModule } from '~/app/app.module';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { NotificationType } from '../enum/notification-type.enum';
+import { CdNotification, CdNotificationConfig } from '../models/cd-notification';
+import { ApiInterceptorService } from './api-interceptor.service';
+import { NotificationService } from './notification.service';
+
+describe('ApiInterceptorService', () => {
+ let notificationService: NotificationService;
+ let httpTesting: HttpTestingController;
+ let httpClient: HttpClient;
+ let router: Router;
+ const url = 'api/xyz';
+
+ const httpError = (error: any, errorOpts: object, done = (_resp: any): any => undefined) => {
+ httpClient.get(url).subscribe(
+ () => true,
+ (resp) => {
+ // Error must have been forwarded by the interceptor.
+ expect(resp instanceof HttpErrorResponse).toBeTruthy();
+ done(resp);
+ }
+ );
+ httpTesting.expectOne(url).error(error, errorOpts);
+ };
+
+ const runRouterTest = (errorOpts: object, expectedCallParams: any[]) => {
+ httpError(new ErrorEvent('abc'), errorOpts);
+ httpTesting.verify();
+ expect(router.navigate).toHaveBeenCalledWith(...expectedCallParams);
+ };
+
+ const runNotificationTest = (
+ error: any,
+ errorOpts: object,
+ expectedCallParams: CdNotification
+ ) => {
+ httpError(error, errorOpts);
+ httpTesting.verify();
+ expect(notificationService.show).toHaveBeenCalled();
+ expect(notificationService.save).toHaveBeenCalledWith(expectedCallParams);
+ };
+
+ const createCdNotification = (
+ type: NotificationType,
+ title?: string,
+ message?: string,
+ options?: any,
+ application?: string
+ ) => {
+ return new CdNotification(new CdNotificationConfig(type, title, message, options, application));
+ };
+
+ configureTestBed({
+ imports: [AppModule, HttpClientTestingModule],
+ providers: [
+ NotificationService,
+ {
+ provide: ToastrService,
+ useValue: {
+ error: () => true
+ }
+ }
+ ]
+ });
+
+ beforeEach(() => {
+ const baseTime = new Date('2022-02-22');
+ spyOn(global, 'Date').and.returnValue(baseTime);
+
+ httpClient = TestBed.inject(HttpClient);
+ httpTesting = TestBed.inject(HttpTestingController);
+
+ notificationService = TestBed.inject(NotificationService);
+ spyOn(notificationService, 'show').and.callThrough();
+ spyOn(notificationService, 'save');
+
+ router = TestBed.inject(Router);
+ spyOn(router, 'navigate');
+ });
+
+ it('should be created', () => {
+ const service = TestBed.inject(ApiInterceptorService);
+ expect(service).toBeTruthy();
+ });
+
+ describe('test different error behaviours', () => {
+ beforeEach(() => {
+ spyOn(window, 'setTimeout').and.callFake((fn) => fn());
+ });
+
+ it('should redirect 401', () => {
+ runRouterTest(
+ {
+ status: 401
+ },
+ [['/login']]
+ );
+ });
+
+ it('should redirect 403', () => {
+ runRouterTest(
+ {
+ status: 403
+ },
+ [['error'], {'state': {'header': 'Access Denied', 'icon': 'fa fa-lock', 'message': 'Sorry, you don’t have permission to view this page or resource.', 'source': 'forbidden'}}] // prettier-ignore
+ );
+ });
+
+ it('should show notification (error string)', () => {
+ runNotificationTest(
+ 'foobar',
+ {
+ status: 500,
+ statusText: 'Foo Bar'
+ },
+ createCdNotification(0, '500 - Foo Bar', 'foobar')
+ );
+ });
+
+ it('should show notification (error object, triggered from backend)', () => {
+ runNotificationTest(
+ { detail: 'abc' },
+ {
+ status: 504,
+ statusText: 'AAA bbb CCC'
+ },
+ createCdNotification(0, '504 - AAA bbb CCC', 'abc')
+ );
+ });
+
+ it('should show notification (error object with unknown keys)', () => {
+ runNotificationTest(
+ { type: 'error' },
+ {
+ status: 0,
+ statusText: 'Unknown Error',
+ message: 'Http failure response for (unknown url): 0 Unknown Error',
+ name: 'HttpErrorResponse',
+ ok: false,
+ url: null
+ },
+ createCdNotification(
+ 0,
+ '0 - Unknown Error',
+ 'Http failure response for api/xyz: 0 Unknown Error'
+ )
+ );
+ });
+
+ it('should show notification (undefined error)', () => {
+ runNotificationTest(
+ undefined,
+ {
+ status: 502
+ },
+ createCdNotification(0, '502 - Unknown Error', 'Http failure response for api/xyz: 502 ')
+ );
+ });
+
+ it('should show 400 notification', () => {
+ spyOn(notificationService, 'notifyTask');
+ httpError({ task: { name: 'mytask', metadata: { component: 'foobar' } } }, { status: 400 });
+ httpTesting.verify();
+ expect(notificationService.show).toHaveBeenCalledTimes(0);
+ expect(notificationService.notifyTask).toHaveBeenCalledWith({
+ exception: { task: { metadata: { component: 'foobar' }, name: 'mytask' } },
+ metadata: { component: 'foobar' },
+ name: 'mytask',
+ success: false
+ });
+ });
+ });
+
+ describe('interceptor error handling', () => {
+ const expectSaveToHaveBeenCalled = (called: boolean) => {
+ tick(510);
+ if (called) {
+ expect(notificationService.save).toHaveBeenCalled();
+ } else {
+ expect(notificationService.save).not.toHaveBeenCalled();
+ }
+ };
+
+ it('should show default behaviour', fakeAsync(() => {
+ httpError(undefined, { status: 500 });
+ expectSaveToHaveBeenCalled(true);
+ }));
+
+ it('should prevent the default behaviour with preventDefault', fakeAsync(() => {
+ httpError(undefined, { status: 500 }, (resp) => resp.preventDefault());
+ expectSaveToHaveBeenCalled(false);
+ }));
+
+ it('should be able to use preventDefault with 400 errors', fakeAsync(() => {
+ httpError(
+ { task: { name: 'someName', metadata: { component: 'someComponent' } } },
+ { status: 400 },
+ (resp) => resp.preventDefault()
+ );
+ expectSaveToHaveBeenCalled(false);
+ }));
+
+ it('should prevent the default behaviour by status code', fakeAsync(() => {
+ httpError(undefined, { status: 500 }, (resp) => resp.ignoreStatusCode(500));
+ expectSaveToHaveBeenCalled(false);
+ }));
+
+ it('should use different application icon (default Ceph) in error message', fakeAsync(() => {
+ const msg = 'Cannot connect to Alertmanager';
+ httpError(undefined, { status: 500 }, (resp) => {
+ (resp.application = 'Prometheus'), (resp.message = msg);
+ });
+ expectSaveToHaveBeenCalled(true);
+ expect(notificationService.save).toHaveBeenCalledWith(
+ createCdNotification(0, '500 - Unknown Error', msg, undefined, 'Prometheus')
+ );
+ }));
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/api-interceptor.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/api-interceptor.service.ts
new file mode 100644
index 000000000..fb7a9f733
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/api-interceptor.service.ts
@@ -0,0 +1,133 @@
+import {
+ HttpErrorResponse,
+ HttpEvent,
+ HttpHandler,
+ HttpInterceptor,
+ HttpRequest
+} from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { Router } from '@angular/router';
+
+import _ from 'lodash';
+import { Observable, throwError as observableThrowError } from 'rxjs';
+import { catchError } from 'rxjs/operators';
+
+import { CdHelperClass } from '~/app/shared/classes/cd-helper.class';
+import { NotificationType } from '../enum/notification-type.enum';
+import { CdNotificationConfig } from '../models/cd-notification';
+import { FinishedTask } from '../models/finished-task';
+import { AuthStorageService } from './auth-storage.service';
+import { NotificationService } from './notification.service';
+
+export class CdHttpErrorResponse extends HttpErrorResponse {
+ preventDefault: Function;
+ ignoreStatusCode: Function;
+}
+
+@Injectable({
+ providedIn: 'root'
+})
+export class ApiInterceptorService implements HttpInterceptor {
+ constructor(
+ private router: Router,
+ private authStorageService: AuthStorageService,
+ public notificationService: NotificationService
+ ) {}
+
+ intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
+ const acceptHeader = request.headers.get('Accept');
+ let reqWithVersion: HttpRequest<any>;
+ if (acceptHeader && acceptHeader.startsWith('application/vnd.ceph.api.v')) {
+ reqWithVersion = request.clone();
+ } else {
+ reqWithVersion = request.clone({
+ setHeaders: {
+ Accept: CdHelperClass.cdVersionHeader('1', '0')
+ }
+ });
+ }
+ return next.handle(reqWithVersion).pipe(
+ catchError((resp: CdHttpErrorResponse) => {
+ if (resp instanceof HttpErrorResponse) {
+ let timeoutId: number;
+ switch (resp.status) {
+ case 400:
+ const finishedTask = new FinishedTask();
+
+ const task = resp.error.task;
+ if (_.isPlainObject(task)) {
+ task.metadata.component = task.metadata.component || resp.error.component;
+
+ finishedTask.name = task.name;
+ finishedTask.metadata = task.metadata;
+ } else {
+ finishedTask.metadata = resp.error;
+ }
+
+ finishedTask.success = false;
+ finishedTask.exception = resp.error;
+ timeoutId = this.notificationService.notifyTask(finishedTask);
+ break;
+ case 401:
+ this.authStorageService.remove();
+ this.router.navigate(['/login']);
+ break;
+ case 403:
+ this.router.navigate(['error'], {
+ state: {
+ message: $localize`Sorry, you don’t have permission to view this page or resource.`,
+ header: $localize`Access Denied`,
+ icon: 'fa fa-lock',
+ source: 'forbidden'
+ }
+ });
+ break;
+ default:
+ timeoutId = this.prepareNotification(resp);
+ }
+
+ /**
+ * Decorated preventDefault method (in case error previously had
+ * preventDefault method defined). If called, it will prevent a
+ * notification to be shown.
+ */
+ resp.preventDefault = () => {
+ this.notificationService.cancel(timeoutId);
+ };
+
+ /**
+ * If called, it will prevent a notification for the specific status code.
+ * @param {number} status The status code to be ignored.
+ */
+ resp.ignoreStatusCode = function (status: number) {
+ if (this.status === status) {
+ this.preventDefault();
+ }
+ };
+ }
+ // Return the error to the method that called it.
+ return observableThrowError(resp);
+ })
+ );
+ }
+
+ private prepareNotification(resp: any): number {
+ return this.notificationService.show(() => {
+ let message = '';
+ if (_.isPlainObject(resp.error) && _.isString(resp.error.detail)) {
+ message = resp.error.detail; // Error was triggered by the backend.
+ } else if (_.isString(resp.error)) {
+ message = resp.error;
+ } else if (_.isString(resp.message)) {
+ message = resp.message;
+ }
+ return new CdNotificationConfig(
+ NotificationType.error,
+ `${resp.status} - ${resp.statusText}`,
+ message,
+ undefined,
+ resp['application']
+ );
+ });
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-guard.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-guard.service.spec.ts
new file mode 100644
index 000000000..22a6e8139
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-guard.service.spec.ts
@@ -0,0 +1,54 @@
+import { Component, NgZone } from '@angular/core';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { ActivatedRouteSnapshot, Router, RouterStateSnapshot, Routes } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { AuthGuardService } from './auth-guard.service';
+import { AuthStorageService } from './auth-storage.service';
+
+describe('AuthGuardService', () => {
+ let service: AuthGuardService;
+ let authStorageService: AuthStorageService;
+ let ngZone: NgZone;
+ let route: ActivatedRouteSnapshot;
+ let state: RouterStateSnapshot;
+
+ @Component({ selector: 'cd-login', template: '' })
+ class LoginComponent {}
+
+ const routes: Routes = [{ path: 'login', component: LoginComponent }];
+
+ configureTestBed({
+ imports: [RouterTestingModule.withRoutes(routes)],
+ providers: [AuthGuardService, AuthStorageService],
+ declarations: [LoginComponent]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(AuthGuardService);
+ authStorageService = TestBed.inject(AuthStorageService);
+ ngZone = TestBed.inject(NgZone);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should allow the user if loggedIn', () => {
+ route = null;
+ state = { url: '/', root: null };
+ spyOn(authStorageService, 'isLoggedIn').and.returnValue(true);
+ expect(service.canActivate(route, state)).toBe(true);
+ });
+
+ it('should prevent user if not loggedIn and redirect to login page', fakeAsync(() => {
+ const router = TestBed.inject(Router);
+ state = { url: '/pool', root: null };
+ ngZone.run(() => {
+ expect(service.canActivate(route, state)).toBe(false);
+ });
+ tick();
+ expect(router.url).toBe('/login?returnUrl=%2Fpool');
+ }));
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-guard.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-guard.service.ts
new file mode 100644
index 000000000..61c06c81d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-guard.service.ts
@@ -0,0 +1,29 @@
+import { Injectable } from '@angular/core';
+import {
+ ActivatedRouteSnapshot,
+ CanActivate,
+ CanActivateChild,
+ Router,
+ RouterStateSnapshot
+} from '@angular/router';
+
+import { AuthStorageService } from './auth-storage.service';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class AuthGuardService implements CanActivate, CanActivateChild {
+ constructor(private router: Router, private authStorageService: AuthStorageService) {}
+
+ canActivate(_route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
+ if (this.authStorageService.isLoggedIn()) {
+ return true;
+ }
+ this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
+ return false;
+ }
+
+ canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
+ return this.canActivate(childRoute, state);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-storage.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-storage.service.spec.ts
new file mode 100644
index 000000000..f202c095f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-storage.service.spec.ts
@@ -0,0 +1,47 @@
+import { AuthStorageService } from './auth-storage.service';
+
+describe('AuthStorageService', () => {
+ let service: AuthStorageService;
+ const username = 'foobar';
+
+ beforeEach(() => {
+ service = new AuthStorageService();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should store username', () => {
+ service.set(username, '');
+ expect(localStorage.getItem('dashboard_username')).toBe(username);
+ });
+
+ it('should remove username', () => {
+ service.set(username, '');
+ service.remove();
+ expect(localStorage.getItem('dashboard_username')).toBe(null);
+ });
+
+ it('should be loggedIn', () => {
+ service.set(username, '');
+ expect(service.isLoggedIn()).toBe(true);
+ });
+
+ it('should not be loggedIn', () => {
+ service.remove();
+ expect(service.isLoggedIn()).toBe(false);
+ });
+
+ it('should be SSO', () => {
+ service.set(username, {}, true);
+ expect(localStorage.getItem('sso')).toBe('true');
+ expect(service.isSSO()).toBe(true);
+ });
+
+ it('should not be SSO', () => {
+ service.set(username);
+ expect(localStorage.getItem('sso')).toBe('false');
+ expect(service.isSSO()).toBe(false);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-storage.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-storage.service.ts
new file mode 100644
index 000000000..15e21f9ed
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-storage.service.ts
@@ -0,0 +1,59 @@
+import { Injectable } from '@angular/core';
+
+import { BehaviorSubject } from 'rxjs';
+
+import { Permissions } from '../models/permissions';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class AuthStorageService {
+ isPwdDisplayedSource = new BehaviorSubject(false);
+ isPwdDisplayed$ = this.isPwdDisplayedSource.asObservable();
+
+ set(
+ username: string,
+ permissions = {},
+ sso = false,
+ pwdExpirationDate: number = null,
+ pwdUpdateRequired: boolean = false
+ ) {
+ localStorage.setItem('dashboard_username', username);
+ localStorage.setItem('dashboard_permissions', JSON.stringify(new Permissions(permissions)));
+ localStorage.setItem('user_pwd_expiration_date', String(pwdExpirationDate));
+ localStorage.setItem('user_pwd_update_required', String(pwdUpdateRequired));
+ localStorage.setItem('sso', String(sso));
+ }
+
+ remove() {
+ localStorage.removeItem('dashboard_username');
+ localStorage.removeItem('user_pwd_expiration_data');
+ localStorage.removeItem('user_pwd_update_required');
+ }
+
+ isLoggedIn() {
+ return localStorage.getItem('dashboard_username') !== null;
+ }
+
+ getUsername() {
+ return localStorage.getItem('dashboard_username');
+ }
+
+ getPermissions(): Permissions {
+ return JSON.parse(
+ localStorage.getItem('dashboard_permissions') || JSON.stringify(new Permissions({}))
+ );
+ }
+
+ getPwdExpirationDate(): number {
+ return Number(localStorage.getItem('user_pwd_expiration_date'));
+ }
+
+ getPwdUpdateRequired(): boolean {
+ return localStorage.getItem('user_pwd_update_required') === 'true';
+ }
+
+ isSSO() {
+ return localStorage.getItem('sso') === 'true';
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/cd-table-server-side.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/cd-table-server-side.service.spec.ts
new file mode 100644
index 000000000..dbe7bb452
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/cd-table-server-side.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { CdTableServerSideService } from './cd-table-server-side.service';
+
+describe('CdTableServerSideService', () => {
+ let service: CdTableServerSideService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(CdTableServerSideService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/cd-table-server-side.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/cd-table-server-side.service.ts
new file mode 100644
index 000000000..56bf807a6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/cd-table-server-side.service.ts
@@ -0,0 +1,14 @@
+import { HttpResponse } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class CdTableServerSideService {
+ /* tslint:disable:no-empty */
+ constructor() {}
+
+ static getCount(resp: HttpResponse<any>): number {
+ return Number(resp.headers?.get('X-Total-Count'));
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/change-password-guard.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/change-password-guard.service.spec.ts
new file mode 100644
index 000000000..12800d112
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/change-password-guard.service.spec.ts
@@ -0,0 +1,68 @@
+import { Component, NgZone } from '@angular/core';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { ActivatedRouteSnapshot, Router, RouterStateSnapshot, Routes } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { AuthStorageService } from './auth-storage.service';
+import { ChangePasswordGuardService } from './change-password-guard.service';
+
+describe('ChangePasswordGuardService', () => {
+ let service: ChangePasswordGuardService;
+ let authStorageService: AuthStorageService;
+ let ngZone: NgZone;
+ let route: ActivatedRouteSnapshot;
+ let state: RouterStateSnapshot;
+
+ @Component({ selector: 'cd-login-password-form', template: '' })
+ class LoginPasswordFormComponent {}
+
+ const routes: Routes = [{ path: 'login-change-password', component: LoginPasswordFormComponent }];
+
+ configureTestBed({
+ imports: [RouterTestingModule.withRoutes(routes)],
+ providers: [ChangePasswordGuardService, AuthStorageService],
+ declarations: [LoginPasswordFormComponent]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(ChangePasswordGuardService);
+ authStorageService = TestBed.inject(AuthStorageService);
+ ngZone = TestBed.inject(NgZone);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should do nothing (not logged in)', () => {
+ spyOn(authStorageService, 'isLoggedIn').and.returnValue(false);
+ expect(service.canActivate(route, state)).toBeTruthy();
+ });
+
+ it('should do nothing (SSO enabled)', () => {
+ spyOn(authStorageService, 'isLoggedIn').and.returnValue(true);
+ spyOn(authStorageService, 'isSSO').and.returnValue(true);
+ expect(service.canActivate(route, state)).toBeTruthy();
+ });
+
+ it('should do nothing (no update pwd required)', () => {
+ spyOn(authStorageService, 'isLoggedIn').and.returnValue(true);
+ spyOn(authStorageService, 'getPwdUpdateRequired').and.returnValue(false);
+ expect(service.canActivate(route, state)).toBeTruthy();
+ });
+
+ it('should redirect to change password page by preserving the query params', fakeAsync(() => {
+ route = null;
+ state = { url: '/host', root: null };
+ spyOn(authStorageService, 'isLoggedIn').and.returnValue(true);
+ spyOn(authStorageService, 'isSSO').and.returnValue(false);
+ spyOn(authStorageService, 'getPwdUpdateRequired').and.returnValue(true);
+ const router = TestBed.inject(Router);
+ ngZone.run(() => {
+ expect(service.canActivate(route, state)).toBeFalsy();
+ });
+ tick();
+ expect(router.url).toBe('/login-change-password?returnUrl=%2Fhost');
+ }));
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/change-password-guard.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/change-password-guard.service.ts
new file mode 100644
index 000000000..d97160f92
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/change-password-guard.service.ts
@@ -0,0 +1,42 @@
+import { Injectable } from '@angular/core';
+import {
+ ActivatedRouteSnapshot,
+ CanActivate,
+ CanActivateChild,
+ Router,
+ RouterStateSnapshot
+} from '@angular/router';
+
+import { AuthStorageService } from './auth-storage.service';
+
+/**
+ * This service guard checks if a user must be redirected to a special
+ * page at '/login-change-password' to set a new password.
+ */
+@Injectable({
+ providedIn: 'root'
+})
+export class ChangePasswordGuardService implements CanActivate, CanActivateChild {
+ constructor(private router: Router, private authStorageService: AuthStorageService) {}
+
+ canActivate(_route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
+ // Redirect to '/login-change-password' when the following constraints
+ // are fulfilled:
+ // - The user must be logged in.
+ // - SSO must be disabled.
+ // - The flag 'User must change password at next logon' must be set.
+ if (
+ this.authStorageService.isLoggedIn() &&
+ !this.authStorageService.isSSO() &&
+ this.authStorageService.getPwdUpdateRequired()
+ ) {
+ this.router.navigate(['/login-change-password'], { queryParams: { returnUrl: state.url } });
+ return false;
+ }
+ return true;
+ }
+
+ canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
+ return this.canActivate(childRoute, state);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/device.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/device.service.spec.ts
new file mode 100644
index 000000000..00524317e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/device.service.spec.ts
@@ -0,0 +1,92 @@
+import { TestBed } from '@angular/core/testing';
+
+import moment from 'moment';
+
+import { CdDevice } from '../models/devices';
+import { DeviceService } from './device.service';
+
+describe('DeviceService', () => {
+ let service: DeviceService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(DeviceService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ describe('should test getDevices pipe', () => {
+ let now: jasmine.Spy = null;
+
+ const newDevice = (data: object): CdDevice => {
+ const device: CdDevice = {
+ devid: '',
+ location: [{ host: '', dev: '' }],
+ daemons: []
+ };
+ Object.assign(device, data);
+ return device;
+ };
+
+ beforeEach(() => {
+ // Mock 'moment.now()' to simplify testing by enabling testing with fixed dates.
+ now = spyOn(moment, 'now').and.returnValue(
+ moment('2019-10-01T00:00:00.00000+0100').valueOf()
+ );
+ });
+
+ afterEach(() => {
+ expect(now).toHaveBeenCalled();
+ });
+
+ it('should return status "good" for life expectancy > 6 weeks', () => {
+ const preparedDevice = service.calculateAdditionalData(
+ newDevice({
+ life_expectancy_min: '2019-11-14T01:00:00.000000+0100',
+ life_expectancy_max: '0.000000',
+ life_expectancy_stamp: '2019-10-01T02:08:48.627312+0100'
+ })
+ );
+ expect(preparedDevice.life_expectancy_weeks).toEqual({ max: null, min: 6 });
+ expect(preparedDevice.state).toBe('good');
+ });
+
+ it('should return status "warning" for life expectancy <= 4 weeks', () => {
+ const preparedDevice = service.calculateAdditionalData(
+ newDevice({
+ life_expectancy_min: '2019-10-14T01:00:00.000000+0100',
+ life_expectancy_max: '2019-11-14T01:00:00.000000+0100',
+ life_expectancy_stamp: '2019-10-01T00:00:00.00000+0100'
+ })
+ );
+ expect(preparedDevice.life_expectancy_weeks).toEqual({ max: 6, min: 2 });
+ expect(preparedDevice.state).toBe('warning');
+ });
+
+ it('should return status "bad" for life expectancy <= 2 weeks', () => {
+ const preparedDevice = service.calculateAdditionalData(
+ newDevice({
+ life_expectancy_min: '0.000000',
+ life_expectancy_max: '2019-10-12T01:00:00.000000+0100',
+ life_expectancy_stamp: '2019-10-01T00:00:00.00000+0100'
+ })
+ );
+ expect(preparedDevice.life_expectancy_weeks).toEqual({ max: 2, min: null });
+ expect(preparedDevice.state).toBe('bad');
+ });
+
+ it('should return status "stale" for time stamp that is older than a week', () => {
+ const preparedDevice = service.calculateAdditionalData(
+ newDevice({
+ life_expectancy_min: '0.000000',
+ life_expectancy_max: '0.000000',
+ life_expectancy_stamp: '2019-09-21T00:00:00.00000+0100'
+ })
+ );
+ expect(preparedDevice.life_expectancy_weeks).toEqual({ max: null, min: null });
+ expect(preparedDevice.state).toBe('stale');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/device.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/device.service.ts
new file mode 100644
index 000000000..b433f235b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/device.service.ts
@@ -0,0 +1,57 @@
+import { Injectable } from '@angular/core';
+
+import moment from 'moment';
+
+import { CdDevice } from '../models/devices';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class DeviceService {
+ /**
+ * Calculates additional data and appends them as new attributes to the given device.
+ */
+ calculateAdditionalData(device: CdDevice): CdDevice {
+ if (!device.life_expectancy_min || !device.life_expectancy_max) {
+ device.state = 'unknown';
+ return device;
+ }
+ const hasDate = (float: string): boolean => !!Number.parseFloat(float);
+ const weeks = (isoDate1: string, isoDate2: string): number =>
+ !isoDate1 || !isoDate2 || !hasDate(isoDate1) || !hasDate(isoDate2)
+ ? null
+ : moment.duration(moment(isoDate1).diff(moment(isoDate2))).asWeeks();
+
+ const ageOfStamp = moment
+ .duration(moment(moment.now()).diff(moment(device.life_expectancy_stamp)))
+ .asWeeks();
+ const max = weeks(device.life_expectancy_max, device.life_expectancy_stamp);
+ const min = weeks(device.life_expectancy_min, device.life_expectancy_stamp);
+
+ if (ageOfStamp > 1) {
+ device.state = 'stale';
+ } else if (max !== null && max <= 2) {
+ device.state = 'bad';
+ } else if (min !== null && min <= 4) {
+ device.state = 'warning';
+ } else {
+ device.state = 'good';
+ }
+
+ device.life_expectancy_weeks = {
+ max: max !== null ? Math.round(max) : null,
+ min: min !== null ? Math.round(min) : null
+ };
+
+ return device;
+ }
+
+ readable(device: CdDevice): CdDevice {
+ device.readableDaemons = device.daemons.join(' ');
+ return device;
+ }
+
+ prepareDevice(device: CdDevice): CdDevice {
+ return this.readable(this.calculateAdditionalData(device));
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.spec.ts
new file mode 100644
index 000000000..7c3bf24dd
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.spec.ts
@@ -0,0 +1,75 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { Subscriber } from 'rxjs';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { SharedModule } from '../shared.module';
+import { DocService } from './doc.service';
+
+describe('DocService', () => {
+ let service: DocService;
+
+ configureTestBed({ imports: [HttpClientTestingModule, SharedModule] });
+
+ beforeEach(() => {
+ service = TestBed.inject(DocService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should return full URL', () => {
+ expect(service.urlGenerator('iscsi', 'foo')).toBe(
+ 'https://docs.ceph.com/en/foo/mgr/dashboard/#enabling-iscsi-management'
+ );
+ });
+
+ it('should return latest version URL for master', () => {
+ expect(service.urlGenerator('orch', 'master')).toBe(
+ 'https://docs.ceph.com/en/latest/mgr/orchestrator'
+ );
+ });
+
+ describe('Name of the group', () => {
+ let result: string;
+ let i: number;
+
+ const nextSummary = (newData: any) => service['releaseDataSource'].next(newData);
+
+ const callback = (response: string) => {
+ i++;
+ result = response;
+ };
+
+ beforeEach(() => {
+ i = 0;
+ result = undefined;
+ nextSummary(undefined);
+ });
+
+ it('should call subscribeOnce without releaseName', () => {
+ const subscriber = service.subscribeOnce('prometheus', callback);
+
+ expect(subscriber).toEqual(jasmine.any(Subscriber));
+ expect(i).toBe(0);
+ expect(result).toEqual(undefined);
+ });
+
+ it('should call subscribeOnce with releaseName', () => {
+ const subscriber = service.subscribeOnce('prometheus', callback);
+
+ expect(subscriber).toEqual(jasmine.any(Subscriber));
+ expect(i).toBe(0);
+ expect(result).toEqual(undefined);
+
+ nextSummary('foo');
+ expect(result).toEqual(
+ 'https://docs.ceph.com/en/foo/mgr/dashboard/#enabling-prometheus-alerting'
+ );
+ expect(i).toBe(1);
+ expect(subscriber.closed).toBe(true);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.ts
new file mode 100644
index 000000000..4cbb4cf18
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.ts
@@ -0,0 +1,65 @@
+import { Injectable } from '@angular/core';
+
+import { BehaviorSubject, Subscription } from 'rxjs';
+import { filter, first, map } from 'rxjs/operators';
+
+import { CephReleaseNamePipe } from '../pipes/ceph-release-name.pipe';
+import { SummaryService } from './summary.service';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class DocService {
+ private releaseDataSource = new BehaviorSubject<string>(null);
+ releaseData$ = this.releaseDataSource.asObservable();
+
+ constructor(
+ private summaryservice: SummaryService,
+ private cephReleaseNamePipe: CephReleaseNamePipe
+ ) {
+ this.summaryservice.subscribeOnce((summary) => {
+ const releaseName = this.cephReleaseNamePipe.transform(summary.version);
+ this.releaseDataSource.next(releaseName);
+ });
+ }
+
+ urlGenerator(section: string, release = 'master'): string {
+ const docVersion = release === 'master' ? 'latest' : release;
+ const domain = `https://docs.ceph.com/en/${docVersion}/`;
+ const domainCeph = `https://ceph.io/`;
+
+ const sections = {
+ iscsi: `${domain}mgr/dashboard/#enabling-iscsi-management`,
+ prometheus: `${domain}mgr/dashboard/#enabling-prometheus-alerting`,
+ 'nfs-ganesha': `${domain}mgr/dashboard/#configuring-nfs-ganesha-in-the-dashboard`,
+ 'rgw-nfs': `${domain}radosgw/nfs`,
+ rgw: `${domain}mgr/dashboard/#enabling-the-object-gateway-management-frontend`,
+ dashboard: `${domain}mgr/dashboard`,
+ grafana: `${domain}mgr/dashboard/#enabling-the-embedding-of-grafana-dashboards`,
+ orch: `${domain}mgr/orchestrator`,
+ pgs: `${domainCeph}pgcalc`,
+ help: `${domainCeph}help/`,
+ security: `${domainCeph}security/`,
+ trademarks: `${domainCeph}legal-page/trademarks/`,
+ 'dashboard-landing-page-status': `${domain}mgr/dashboard/#dashboard-landing-page-status`,
+ 'dashboard-landing-page-performance': `${domain}mgr/dashboard/#dashboard-landing-page-performance`,
+ 'dashboard-landing-page-capacity': `${domain}mgr/dashboard/#dashboard-landing-page-capacity`
+ };
+
+ return sections[section];
+ }
+
+ subscribeOnce(
+ section: string,
+ next: (release: string) => void,
+ error?: (error: any) => void
+ ): Subscription {
+ return this.releaseData$
+ .pipe(
+ filter((value) => !!value),
+ map((release) => this.urlGenerator(section, release)),
+ first()
+ )
+ .subscribe(next, error);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/favicon.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/favicon.service.spec.ts
new file mode 100644
index 000000000..0c9e619ea
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/favicon.service.spec.ts
@@ -0,0 +1,23 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { CssHelper } from '~/app/shared/classes/css-helper';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { FaviconService } from './favicon.service';
+
+describe('FaviconService', () => {
+ let service: FaviconService;
+
+ configureTestBed({
+ imports: [HttpClientTestingModule],
+ providers: [FaviconService, CssHelper]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(FaviconService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/favicon.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/favicon.service.ts
new file mode 100644
index 000000000..87ce8fcad
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/favicon.service.ts
@@ -0,0 +1,79 @@
+import { DOCUMENT } from '@angular/common';
+import { Inject, Injectable, OnDestroy } from '@angular/core';
+
+import { Subscription } from 'rxjs';
+
+import { CssHelper } from '~/app/shared/classes/css-helper';
+import { HealthColor } from '~/app/shared/enum/health-color.enum';
+import { SummaryService } from './summary.service';
+
+@Injectable()
+export class FaviconService implements OnDestroy {
+ sub: Subscription;
+ oldStatus: string;
+ url: string;
+
+ constructor(
+ @Inject(DOCUMENT) private document: HTMLDocument,
+ private summaryService: SummaryService,
+ private cssHelper: CssHelper
+ ) {}
+
+ init() {
+ this.url = this.document.getElementById('cdFavicon')?.getAttribute('href');
+
+ this.sub = this.summaryService.subscribe((summary) => {
+ this.changeIcon(summary.health_status);
+ });
+ }
+
+ changeIcon(status?: string) {
+ if (status === this.oldStatus) {
+ return;
+ }
+
+ this.oldStatus = status;
+
+ const favicon = this.document.getElementById('cdFavicon');
+ const faviconSize = 16;
+ const radius = faviconSize / 4;
+
+ const canvas = this.document.createElement('canvas');
+ canvas.width = faviconSize;
+ canvas.height = faviconSize;
+
+ const context = canvas.getContext('2d');
+ const img = this.document.createElement('img');
+ img.src = this.url;
+
+ img.onload = () => {
+ // Draw Original Favicon as Background
+ context.drawImage(img, 0, 0, faviconSize, faviconSize);
+
+ if (Object.keys(HealthColor).includes(status as HealthColor)) {
+ // Cut notification circle area
+ context.save();
+ context.globalCompositeOperation = 'destination-out';
+ context.beginPath();
+ context.arc(canvas.width - radius, radius, radius + 2, 0, 2 * Math.PI);
+ context.fill();
+ context.restore();
+
+ // Draw Notification Circle
+ context.beginPath();
+ context.arc(canvas.width - radius, radius, radius, 0, 2 * Math.PI);
+
+ context.fillStyle = this.cssHelper.propertyValue(HealthColor[status]);
+ context.fill();
+ }
+
+ // Replace favicon
+ favicon.setAttribute('href', canvas.toDataURL('image/png'));
+ };
+ }
+
+ ngOnDestroy() {
+ this.changeIcon();
+ this.sub?.unsubscribe();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles-guard.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles-guard.service.spec.ts
new file mode 100644
index 000000000..883139986
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles-guard.service.spec.ts
@@ -0,0 +1,72 @@
+import { Component, NgZone } from '@angular/core';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { ActivatedRouteSnapshot, Router, Routes } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { of as observableOf } from 'rxjs';
+
+import { DashboardNotFoundError } from '~/app/core/error/error';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { FeatureTogglesGuardService } from './feature-toggles-guard.service';
+import { FeatureTogglesService } from './feature-toggles.service';
+
+describe('FeatureTogglesGuardService', () => {
+ let service: FeatureTogglesGuardService;
+ let fakeFeatureTogglesService: FeatureTogglesService;
+ let router: Router;
+ let ngZone: NgZone;
+
+ @Component({ selector: 'cd-cephfs', template: '' })
+ class CephfsComponent {}
+
+ @Component({ selector: 'cd-404', template: '' })
+ class NotFoundComponent {}
+
+ const routes: Routes = [
+ { path: 'cephfs', component: CephfsComponent },
+ { path: '404', component: NotFoundComponent }
+ ];
+
+ configureTestBed({
+ imports: [RouterTestingModule.withRoutes(routes)],
+ providers: [
+ { provide: FeatureTogglesService, useValue: { get: null } },
+ FeatureTogglesGuardService
+ ],
+ declarations: [CephfsComponent, NotFoundComponent]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(FeatureTogglesGuardService);
+ fakeFeatureTogglesService = TestBed.inject(FeatureTogglesService);
+ ngZone = TestBed.inject(NgZone);
+ router = TestBed.inject(Router);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ function testCanActivate(path: string, feature_toggles_map: object) {
+ let result: boolean;
+ spyOn(fakeFeatureTogglesService, 'get').and.returnValue(observableOf(feature_toggles_map));
+
+ ngZone.run(() => {
+ service
+ .canActivate(<ActivatedRouteSnapshot>{ routeConfig: { path: path } })
+ .subscribe((val) => (result = val));
+ });
+ tick();
+
+ return result;
+ }
+
+ it('should allow the feature if enabled', fakeAsync(() => {
+ expect(testCanActivate('cephfs', { cephfs: true })).toBe(true);
+ expect(router.url).toBe('/');
+ }));
+
+ it('should throw error if disable', fakeAsync(() => {
+ expect(() => testCanActivate('cephfs', { cephfs: false })).toThrowError(DashboardNotFoundError);
+ }));
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles-guard.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles-guard.service.ts
new file mode 100644
index 000000000..ad94f2689
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles-guard.service.ts
@@ -0,0 +1,30 @@
+import { Injectable } from '@angular/core';
+import { ActivatedRouteSnapshot, CanActivate, CanActivateChild } from '@angular/router';
+
+import { map } from 'rxjs/operators';
+
+import { DashboardNotFoundError } from '~/app/core/error/error';
+import { FeatureTogglesMap, FeatureTogglesService } from './feature-toggles.service';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class FeatureTogglesGuardService implements CanActivate, CanActivateChild {
+ constructor(private featureToggles: FeatureTogglesService) {}
+
+ canActivate(route: ActivatedRouteSnapshot) {
+ return this.featureToggles.get().pipe(
+ map((enabledFeatures: FeatureTogglesMap) => {
+ if (enabledFeatures[route.routeConfig.path] === false) {
+ throw new DashboardNotFoundError();
+ return false;
+ }
+ return true;
+ })
+ );
+ }
+
+ canActivateChild(route: ActivatedRouteSnapshot) {
+ return this.canActivate(route.parent);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles.service.spec.ts
new file mode 100644
index 000000000..ddb888851
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles.service.spec.ts
@@ -0,0 +1,54 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { discardPeriodicTasks, fakeAsync, TestBed, tick } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { FeatureTogglesService } from './feature-toggles.service';
+
+describe('FeatureTogglesService', () => {
+ let httpTesting: HttpTestingController;
+ let service: FeatureTogglesService;
+
+ configureTestBed({
+ providers: [FeatureTogglesService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(FeatureTogglesService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should fetch HTTP endpoint once and only once', fakeAsync(() => {
+ const mockFeatureTogglesMap = [
+ {
+ rbd: true,
+ mirroring: true,
+ iscsi: true,
+ cephfs: true,
+ rgw: true
+ }
+ ];
+
+ service
+ .get()
+ .subscribe((featureTogglesMap) => expect(featureTogglesMap).toEqual(mockFeatureTogglesMap));
+ tick();
+
+ // Second subscription shouldn't trigger a new HTTP request
+ service
+ .get()
+ .subscribe((featureTogglesMap) => expect(featureTogglesMap).toEqual(mockFeatureTogglesMap));
+
+ const req = httpTesting.expectOne(service.API_URL);
+ req.flush(mockFeatureTogglesMap);
+ discardPeriodicTasks();
+ }));
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles.service.ts
new file mode 100644
index 000000000..bb7f2a0d6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles.service.ts
@@ -0,0 +1,37 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { Observable } from 'rxjs';
+
+import { TimerService } from './timer.service';
+
+export class FeatureTogglesMap {
+ rbd = true;
+ mirroring = true;
+ iscsi = true;
+ cephfs = true;
+ rgw = true;
+ nfs = true;
+}
+export type Features = keyof FeatureTogglesMap;
+export type FeatureTogglesMap$ = Observable<FeatureTogglesMap>;
+
+@Injectable({
+ providedIn: 'root'
+})
+export class FeatureTogglesService {
+ readonly API_URL: string = 'api/feature_toggles';
+ readonly REFRESH_INTERVAL: number = 30000;
+ private featureToggleMap$: FeatureTogglesMap$;
+
+ constructor(private http: HttpClient, private timerService: TimerService) {
+ this.featureToggleMap$ = this.timerService.get(
+ () => this.http.get<FeatureTogglesMap>(this.API_URL),
+ this.REFRESH_INTERVAL
+ );
+ }
+
+ get(): FeatureTogglesMap$ {
+ return this.featureToggleMap$;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.spec.ts
new file mode 100644
index 000000000..359c6028a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.spec.ts
@@ -0,0 +1,90 @@
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { DimlessBinaryPipe } from '../pipes/dimless-binary.pipe';
+import { DimlessPipe } from '../pipes/dimless.pipe';
+import { FormatterService } from './formatter.service';
+
+describe('FormatterService', () => {
+ let service: FormatterService;
+ let dimlessBinaryPipe: DimlessBinaryPipe;
+ let dimlessPipe: DimlessPipe;
+
+ const convertToBytesAndBack = (value: string, newValue?: string) => {
+ expect(dimlessBinaryPipe.transform(service.toBytes(value))).toBe(newValue || value);
+ };
+
+ configureTestBed({
+ providers: [FormatterService, DimlessBinaryPipe]
+ });
+
+ beforeEach(() => {
+ service = new FormatterService();
+ dimlessBinaryPipe = new DimlessBinaryPipe(service);
+ dimlessPipe = new DimlessPipe(service);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ describe('format_number', () => {
+ const formats = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
+
+ it('should return minus for unsupported values', () => {
+ expect(service.format_number(service, 1024, formats)).toBe('-');
+ expect(service.format_number(undefined, 1024, formats)).toBe('-');
+ expect(service.format_number(null, 1024, formats)).toBe('-');
+ });
+
+ it('should test some values', () => {
+ expect(service.format_number('0', 1024, formats)).toBe('0 B');
+ expect(service.format_number('0.1', 1024, formats)).toBe('0.1 B');
+ expect(service.format_number('1.2', 1024, formats)).toBe('1.2 B');
+ expect(service.format_number('1', 1024, formats)).toBe('1 B');
+ expect(service.format_number('1024', 1024, formats)).toBe('1 KiB');
+ expect(service.format_number(23.45678 * Math.pow(1024, 3), 1024, formats)).toBe('23.5 GiB');
+ expect(service.format_number(23.45678 * Math.pow(1024, 3), 1024, formats, 2)).toBe(
+ '23.46 GiB'
+ );
+ });
+
+ it('should test some dimless values', () => {
+ expect(dimlessPipe.transform(0.6)).toBe('0.6');
+ expect(dimlessPipe.transform(1000.608)).toBe('1 k');
+ expect(dimlessPipe.transform(1e10)).toBe('10 G');
+ expect(dimlessPipe.transform(2.37e16)).toBe('23.7 P');
+ });
+ });
+
+ describe('toBytes', () => {
+ it('should not convert wrong values', () => {
+ expect(service.toBytes('10xyz')).toBeNull();
+ expect(service.toBytes('1.1.1KiB')).toBeNull();
+ expect(service.toBytes('1.1 KiloByte')).toBeNull();
+ expect(service.toBytes('1.1 kib')).toBeNull();
+ expect(service.toBytes('1.kib')).toBeNull();
+ expect(service.toBytes('1 ki')).toBeNull();
+ expect(service.toBytes(undefined)).toBeNull();
+ expect(service.toBytes('')).toBeNull();
+ expect(service.toBytes('-')).toBeNull();
+ expect(service.toBytes(null)).toBeNull();
+ });
+
+ it('should convert values to bytes', () => {
+ expect(service.toBytes('4815162342')).toBe(4815162342);
+ expect(service.toBytes('100M')).toBe(104857600);
+ expect(service.toBytes('100 M')).toBe(104857600);
+ expect(service.toBytes('100 mIb')).toBe(104857600);
+ expect(service.toBytes('100 mb')).toBe(104857600);
+ expect(service.toBytes('100MIB')).toBe(104857600);
+ expect(service.toBytes('1.532KiB')).toBe(Math.round(1.532 * 1024));
+ expect(service.toBytes('0.000000000001TiB')).toBe(1);
+ });
+
+ it('should convert values to human readable again', () => {
+ convertToBytesAndBack('1.1 MiB');
+ convertToBytesAndBack('1.0MiB', '1 MiB');
+ convertToBytesAndBack('8.9 GiB');
+ convertToBytesAndBack('123.5 EiB');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.ts
new file mode 100644
index 000000000..a4b6d427b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.ts
@@ -0,0 +1,77 @@
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class FormatterService {
+ format_number(n: any, divisor: number, units: string[], decimals: number = 1): string {
+ if (_.isString(n)) {
+ n = Number(n);
+ }
+ if (!_.isNumber(n)) {
+ return '-';
+ }
+ let unit = n < 1 ? 0 : Math.floor(Math.log(n) / Math.log(divisor));
+ unit = unit >= units.length ? units.length - 1 : unit;
+ let result = _.round(n / Math.pow(divisor, unit), decimals).toString();
+ if (result === '') {
+ return '-';
+ }
+ if (units[unit] !== '') {
+ result = `${result} ${units[unit]}`;
+ }
+ return result;
+ }
+
+ /**
+ * Convert the given value into bytes.
+ * @param {string} value The value to be converted, e.g. 1024B, 10M, 300KiB or 1ZB.
+ * @param error_value The value returned in case the regular expression did not match. Defaults to
+ * null.
+ * @returns Returns the given value in bytes without any unit appended or the defined error value
+ * in case xof an error.
+ */
+ toBytes(value: string, error_value: number = null): number | null {
+ const base = 1024;
+ const units = ['b', 'k', 'm', 'g', 't', 'p', 'e', 'z', 'y'];
+ const m = RegExp('^(\\d+(.\\d+)?) ?([' + units.join('') + ']?(b|ib|B/s)?)?$', 'i').exec(value);
+ if (m === null) {
+ return error_value;
+ }
+ let bytes = parseFloat(m[1]);
+ if (_.isString(m[3])) {
+ bytes = bytes * Math.pow(base, units.indexOf(m[3].toLowerCase()[0]));
+ }
+ return Math.round(bytes);
+ }
+
+ /**
+ * Converts `x ms` to `x` (currently) or `0` if the conversion fails
+ */
+ toMilliseconds(value: string): number {
+ const pattern = /^\s*(\d+)\s*(ms)?\s*$/i;
+ const testResult = pattern.exec(value);
+
+ if (testResult !== null) {
+ return +testResult[1];
+ }
+
+ return 0;
+ }
+
+ /**
+ * Converts `x IOPS` to `x` (currently) or `0` if the conversion fails
+ */
+ toIops(value: string): number {
+ const pattern = /^\s*(\d+)\s*(IOPS)?\s*$/i;
+ const testResult = pattern.exec(value);
+
+ if (testResult !== null) {
+ return +testResult[1];
+ }
+
+ return 0;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/js-error-handler.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/js-error-handler.service.ts
new file mode 100644
index 000000000..de42d005e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/js-error-handler.service.ts
@@ -0,0 +1,33 @@
+import { ErrorHandler, Injectable, Injector } from '@angular/core';
+import { Router } from '@angular/router';
+
+import { DashboardError } from '~/app/core/error/error';
+import { LoggingService } from '../api/logging.service';
+
+@Injectable()
+export class JsErrorHandler implements ErrorHandler {
+ constructor(private injector: Injector, private router: Router) {}
+
+ handleError(error: any) {
+ const loggingService = this.injector.get(LoggingService);
+ const url = window.location.href;
+ const message = error && error.message;
+ const stack = error && error.stack;
+ loggingService.jsError(url, message, stack).subscribe();
+ if (error.rejection instanceof DashboardError) {
+ setTimeout(
+ () =>
+ this.router.navigate(['error'], {
+ state: {
+ message: error.rejection.message,
+ header: error.rejection.header,
+ icon: error.rejection.icon
+ }
+ }),
+ 50
+ );
+ } else {
+ throw error;
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/language.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/language.service.spec.ts
new file mode 100644
index 000000000..dacff44f0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/language.service.spec.ts
@@ -0,0 +1,34 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { LanguageService } from './language.service';
+
+describe('LanguageService', () => {
+ let service: LanguageService;
+ let httpTesting: HttpTestingController;
+
+ configureTestBed({
+ providers: [LanguageService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(LanguageService);
+ httpTesting = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpTesting.verify();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call create', () => {
+ service.getLanguages().subscribe();
+ const req = httpTesting.expectOne('ui-api/langs');
+ expect(req.request.method).toBe('GET');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/language.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/language.service.ts
new file mode 100644
index 000000000..d2705ee36
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/language.service.ts
@@ -0,0 +1,23 @@
+import { HttpClient } from '@angular/common/http';
+import { Inject, Injectable, LOCALE_ID } from '@angular/core';
+
+import { environment } from '~/environments/environment';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class LanguageService {
+ constructor(private http: HttpClient, @Inject(LOCALE_ID) protected localeId: string) {}
+
+ getLocale(): string {
+ return this.localeId || environment.default_lang;
+ }
+
+ setLocale(lang: string) {
+ document.cookie = `cd-lang=${lang}`;
+ }
+
+ getLanguages() {
+ return this.http.get<string[]>('ui-api/langs');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/modal.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/modal.service.spec.ts
new file mode 100644
index 000000000..4e5ed061d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/modal.service.spec.ts
@@ -0,0 +1,59 @@
+import { Component } from '@angular/core';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+
+import { NgbActiveModal, NgbModal, NgbModalModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { ModalService } from './modal.service';
+
+@Component({
+ template: ``
+})
+class MockComponent {
+ foo = '';
+
+ constructor(public activeModal: NgbActiveModal) {}
+}
+
+describe('ModalService', () => {
+ let service: ModalService;
+ let ngbModal: NgbModal;
+
+ configureTestBed({ declarations: [MockComponent], imports: [NgbModalModule] }, [MockComponent]);
+
+ beforeEach(() => {
+ service = TestBed.inject(ModalService);
+ ngbModal = TestBed.inject(NgbModal);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should call NgbModal.open when show is called', () => {
+ spyOn(ngbModal, 'open').and.callThrough();
+
+ const modaRef = service.show(MockComponent, { foo: 'bar' });
+
+ expect(ngbModal.open).toBeCalled();
+ expect(modaRef.componentInstance.foo).toBe('bar');
+ expect(modaRef.componentInstance.activeModal).toBeTruthy();
+ });
+
+ it('should call dismissAll and hasOpenModals', fakeAsync(() => {
+ spyOn(ngbModal, 'dismissAll').and.callThrough();
+ spyOn(ngbModal, 'hasOpenModals').and.callThrough();
+
+ expect(ngbModal.hasOpenModals()).toBeFalsy();
+
+ service.show(MockComponent, { foo: 'bar' });
+ expect(service.hasOpenModals()).toBeTruthy();
+
+ service.dismissAll();
+ tick();
+ expect(service.hasOpenModals()).toBeFalsy();
+
+ expect(ngbModal.dismissAll).toBeCalled();
+ expect(ngbModal.hasOpenModals).toBeCalled();
+ }));
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/modal.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/modal.service.ts
new file mode 100644
index 000000000..33ce8bd4d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/modal.service.ts
@@ -0,0 +1,28 @@
+import { Injectable } from '@angular/core';
+
+import { NgbModal, NgbModalOptions, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class ModalService {
+ constructor(private modal: NgbModal) {}
+
+ show(component: any, initialState?: any, options?: NgbModalOptions): NgbModalRef {
+ const modalRef = this.modal.open(component, options);
+
+ if (initialState) {
+ Object.assign(modalRef.componentInstance, initialState);
+ }
+
+ return modalRef;
+ }
+
+ dismissAll() {
+ this.modal.dismissAll();
+ }
+
+ hasOpenModals() {
+ return this.modal.hasOpenModals();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/module-status-guard.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/module-status-guard.service.spec.ts
new file mode 100644
index 000000000..532aa6c65
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/module-status-guard.service.spec.ts
@@ -0,0 +1,102 @@
+import { HttpClient } from '@angular/common/http';
+import { Component, NgZone } from '@angular/core';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { ActivatedRouteSnapshot, Router, Routes } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { of as observableOf, throwError } from 'rxjs';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { MgrModuleService } from '../api/mgr-module.service';
+import { ModuleStatusGuardService } from './module-status-guard.service';
+
+describe('ModuleStatusGuardService', () => {
+ let service: ModuleStatusGuardService;
+ let httpClient: HttpClient;
+ let router: Router;
+ let route: ActivatedRouteSnapshot;
+ let ngZone: NgZone;
+ let mgrModuleService: MgrModuleService;
+
+ @Component({ selector: 'cd-foo', template: '' })
+ class FooComponent {}
+
+ const fakeService = {
+ get: () => true
+ };
+
+ const routes: Routes = [{ path: '**', component: FooComponent }];
+
+ const testCanActivate = (
+ getResult: {},
+ activateResult: boolean,
+ urlResult: string,
+ backend = 'cephadm',
+ configOptPermission = true
+ ) => {
+ let result: boolean;
+ spyOn(httpClient, 'get').and.returnValue(observableOf(getResult));
+ const orchBackend = { orchestrator: backend };
+ const getConfigSpy = spyOn(mgrModuleService, 'getConfig');
+ configOptPermission
+ ? getConfigSpy.and.returnValue(observableOf(orchBackend))
+ : getConfigSpy.and.returnValue(throwError({}));
+ ngZone.run(() => {
+ service.canActivateChild(route).subscribe((resp) => {
+ result = resp;
+ });
+ });
+
+ tick();
+ expect(result).toBe(activateResult);
+ expect(router.url).toBe(urlResult);
+ };
+
+ configureTestBed({
+ imports: [RouterTestingModule.withRoutes(routes)],
+ providers: [ModuleStatusGuardService, { provide: HttpClient, useValue: fakeService }],
+ declarations: [FooComponent]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(ModuleStatusGuardService);
+ httpClient = TestBed.inject(HttpClient);
+ mgrModuleService = TestBed.inject(MgrModuleService);
+ router = TestBed.inject(Router);
+ route = new ActivatedRouteSnapshot();
+ route.url = [];
+ route.data = {
+ moduleStatusGuardConfig: {
+ uiApiPath: 'bar',
+ redirectTo: '/foo',
+ backend: 'rook'
+ }
+ };
+ ngZone = TestBed.inject(NgZone);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should test canActivate with status available', fakeAsync(() => {
+ route.data.moduleStatusGuardConfig.redirectTo = 'foo';
+ testCanActivate({ available: true, message: 'foo' }, true, '/');
+ }));
+
+ it('should test canActivateChild with status unavailable', fakeAsync(() => {
+ testCanActivate({ available: false, message: null }, false, '/foo');
+ }));
+
+ it('should test canActivateChild with status unavailable', fakeAsync(() => {
+ testCanActivate(null, false, '/foo');
+ }));
+
+ it('should redirect normally if the backend provided matches the current backend', fakeAsync(() => {
+ testCanActivate({ available: true, message: 'foo' }, true, '/', 'rook');
+ }));
+
+ it('should redirect to the "redirectTo" link for user without sufficient permission', fakeAsync(() => {
+ testCanActivate({ available: true, message: 'foo' }, true, '/foo', 'rook', false);
+ }));
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/module-status-guard.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/module-status-guard.service.ts
new file mode 100644
index 000000000..df6f4854e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/module-status-guard.service.ts
@@ -0,0 +1,101 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, Router } from '@angular/router';
+
+import { of as observableOf } from 'rxjs';
+import { catchError, map } from 'rxjs/operators';
+
+import { MgrModuleService } from '~/app/shared/api/mgr-module.service';
+import { Icons } from '~/app/shared/enum/icons.enum';
+
+/**
+ * This service checks if a route can be activated by executing a
+ * REST API call to '/ui-api/<uiApiPath>/status'. If the returned response
+ * states that the module is not available, then the user is redirected
+ * to the specified <redirectTo> URL path.
+ *
+ * A controller implementing this endpoint should return an object of
+ * the following form:
+ * {'available': true|false, 'message': null|string}.
+ *
+ * The configuration of this guard should look like this:
+ * const routes: Routes = [
+ * {
+ * path: 'rgw/bucket',
+ * component: RgwBucketListComponent,
+ * canActivate: [AuthGuardService, ModuleStatusGuardService],
+ * data: {
+ * moduleStatusGuardConfig: {
+ * uiApiPath: 'rgw',
+ * redirectTo: 'rgw/501'
+ * }
+ * }
+ * },
+ * ...
+ */
+@Injectable({
+ providedIn: 'root'
+})
+export class ModuleStatusGuardService implements CanActivate, CanActivateChild {
+ // TODO: Hotfix - remove ALLOWLIST'ing when a generic ErrorComponent is implemented
+ static readonly ALLOWLIST: string[] = ['501'];
+
+ constructor(
+ private http: HttpClient,
+ private router: Router,
+ private mgrModuleService: MgrModuleService
+ ) {}
+
+ canActivate(route: ActivatedRouteSnapshot) {
+ return this.doCheck(route);
+ }
+
+ canActivateChild(childRoute: ActivatedRouteSnapshot) {
+ return this.doCheck(childRoute);
+ }
+
+ private doCheck(route: ActivatedRouteSnapshot) {
+ if (route.url.length > 0 && ModuleStatusGuardService.ALLOWLIST.includes(route.url[0].path)) {
+ return observableOf(true);
+ }
+ const config = route.data['moduleStatusGuardConfig'];
+ let backendCheck = false;
+ if (config.backend) {
+ this.mgrModuleService.getConfig('orchestrator').subscribe(
+ (resp) => {
+ backendCheck = config.backend === resp['orchestrator'];
+ },
+ () => {
+ this.router.navigate([config.redirectTo]);
+ return observableOf(false);
+ }
+ );
+ }
+ return this.http.get(`ui-api/${config.uiApiPath}/status`).pipe(
+ map((resp: any) => {
+ if (!resp.available && !backendCheck) {
+ this.router.navigate([config.redirectTo || ''], {
+ state: {
+ header: config.header,
+ message: resp.message,
+ section: config.section,
+ section_info: config.section_info,
+ button_name: config.button_name,
+ button_route: config.button_route,
+ button_title: config.button_title,
+ uiConfig: config.uiConfig,
+ uiApiPath: config.uiApiPath,
+ icon: Icons.wrench,
+ component: config.component
+ }
+ });
+ }
+ return resp.available;
+ }),
+ catchError(() => {
+ this.router.navigate([config.redirectTo]);
+ return observableOf(false);
+ })
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/motd-notification.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/motd-notification.service.spec.ts
new file mode 100644
index 000000000..267e6aa57
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/motd-notification.service.spec.ts
@@ -0,0 +1,117 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { Motd } from '~/app/shared/api/motd.service';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { MotdNotificationService } from './motd-notification.service';
+
+describe('MotdNotificationService', () => {
+ let service: MotdNotificationService;
+
+ configureTestBed({
+ providers: [MotdNotificationService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(MotdNotificationService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should hide [1]', () => {
+ spyOn(service.motdSource, 'next');
+ spyOn(service.motdSource, 'getValue').and.returnValue({
+ severity: 'info',
+ expires: '',
+ message: 'foo',
+ md5: 'acbd18db4cc2f85cedef654fccc4a4d8'
+ });
+ service.hide();
+ expect(localStorage.getItem('dashboard_motd_hidden')).toBe(
+ 'info:acbd18db4cc2f85cedef654fccc4a4d8'
+ );
+ expect(sessionStorage.getItem('dashboard_motd_hidden')).toBeNull();
+ expect(service.motdSource.next).toBeCalledWith(null);
+ });
+
+ it('should hide [2]', () => {
+ spyOn(service.motdSource, 'getValue').and.returnValue({
+ severity: 'warning',
+ expires: '',
+ message: 'bar',
+ md5: '37b51d194a7513e45b56f6524f2d51f2'
+ });
+ service.hide();
+ expect(sessionStorage.getItem('dashboard_motd_hidden')).toBe(
+ 'warning:37b51d194a7513e45b56f6524f2d51f2'
+ );
+ expect(localStorage.getItem('dashboard_motd_hidden')).toBeNull();
+ });
+
+ it('should process response [1]', () => {
+ const motd: Motd = {
+ severity: 'danger',
+ expires: '',
+ message: 'foo',
+ md5: 'acbd18db4cc2f85cedef654fccc4a4d8'
+ };
+ spyOn(service.motdSource, 'next');
+ service.processResponse(motd);
+ expect(service.motdSource.next).toBeCalledWith(motd);
+ });
+
+ it('should process response [2]', () => {
+ const motd: Motd = {
+ severity: 'warning',
+ expires: '',
+ message: 'foo',
+ md5: 'acbd18db4cc2f85cedef654fccc4a4d8'
+ };
+ localStorage.setItem('dashboard_motd_hidden', 'info');
+ service.processResponse(motd);
+ expect(sessionStorage.getItem('dashboard_motd_hidden')).toBeNull();
+ expect(localStorage.getItem('dashboard_motd_hidden')).toBeNull();
+ });
+
+ it('should process response [3]', () => {
+ const motd: Motd = {
+ severity: 'info',
+ expires: '',
+ message: 'foo',
+ md5: 'acbd18db4cc2f85cedef654fccc4a4d8'
+ };
+ spyOn(service.motdSource, 'next');
+ localStorage.setItem('dashboard_motd_hidden', 'info:acbd18db4cc2f85cedef654fccc4a4d8');
+ service.processResponse(motd);
+ expect(service.motdSource.next).not.toBeCalled();
+ });
+
+ it('should process response [4]', () => {
+ const motd: Motd = {
+ severity: 'info',
+ expires: '',
+ message: 'foo',
+ md5: 'acbd18db4cc2f85cedef654fccc4a4d8'
+ };
+ spyOn(service.motdSource, 'next');
+ localStorage.setItem('dashboard_motd_hidden', 'info:37b51d194a7513e45b56f6524f2d51f2');
+ service.processResponse(motd);
+ expect(service.motdSource.next).toBeCalled();
+ });
+
+ it('should process response [5]', () => {
+ const motd: Motd = {
+ severity: 'info',
+ expires: '',
+ message: 'foo',
+ md5: 'acbd18db4cc2f85cedef654fccc4a4d8'
+ };
+ spyOn(service.motdSource, 'next');
+ localStorage.setItem('dashboard_motd_hidden', 'danger:acbd18db4cc2f85cedef654fccc4a4d8');
+ service.processResponse(motd);
+ expect(service.motdSource.next).toBeCalled();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/motd-notification.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/motd-notification.service.ts
new file mode 100644
index 000000000..d2ee89f9c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/motd-notification.service.ts
@@ -0,0 +1,84 @@
+import { Injectable, OnDestroy } from '@angular/core';
+
+import * as _ from 'lodash';
+import { BehaviorSubject, EMPTY, Observable, of, Subscription } from 'rxjs';
+import { catchError, delay, mergeMap, repeat, tap } from 'rxjs/operators';
+
+import { Motd, MotdService } from '~/app/shared/api/motd.service';
+import { whenPageVisible } from '../rxjs/operators/page-visibilty.operator';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class MotdNotificationService implements OnDestroy {
+ public motd$: Observable<Motd | null>;
+ public motdSource = new BehaviorSubject<Motd | null>(null);
+
+ private subscription: Subscription;
+ private localStorageKey = 'dashboard_motd_hidden';
+
+ constructor(private motdService: MotdService) {
+ this.motd$ = this.motdSource.asObservable();
+ // Check every 60 seconds for the latest MOTD configuration.
+ this.subscription = of(true)
+ .pipe(
+ mergeMap(() => this.motdService.get()),
+ catchError((error) => {
+ // Do not show an error notification.
+ if (_.isFunction(error.preventDefault)) {
+ error.preventDefault();
+ }
+ return EMPTY;
+ }),
+ tap((motd: Motd | null) => this.processResponse(motd)),
+ delay(60000),
+ repeat(),
+ whenPageVisible()
+ )
+ .subscribe();
+ }
+
+ ngOnDestroy(): void {
+ this.subscription.unsubscribe();
+ }
+
+ hide() {
+ // Store the severity and MD5 of the current MOTD in local or
+ // session storage to be able to show it again if the severity
+ // or message of the latest MOTD has changed.
+ const motd: Motd = this.motdSource.getValue();
+ if (motd) {
+ const value = `${motd.severity}:${motd.md5}`;
+ switch (motd.severity) {
+ case 'info':
+ localStorage.setItem(this.localStorageKey, value);
+ sessionStorage.removeItem(this.localStorageKey);
+ break;
+ case 'warning':
+ sessionStorage.setItem(this.localStorageKey, value);
+ localStorage.removeItem(this.localStorageKey);
+ break;
+ }
+ }
+ this.motdSource.next(null);
+ }
+
+ processResponse(motd: Motd | null) {
+ const value: string | null =
+ sessionStorage.getItem(this.localStorageKey) || localStorage.getItem(this.localStorageKey);
+ let visible: boolean = _.isNull(value);
+ // Force a hidden MOTD to be shown again if the severity or message
+ // has been changed.
+ if (!visible && motd) {
+ const [severity, md5] = value.split(':');
+ if (severity !== motd.severity || md5 !== motd.md5) {
+ visible = true;
+ sessionStorage.removeItem(this.localStorageKey);
+ localStorage.removeItem(this.localStorageKey);
+ }
+ }
+ if (visible) {
+ this.motdSource.next(motd);
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/ngzone-scheduler.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/ngzone-scheduler.service.ts
new file mode 100644
index 000000000..a2c6b6c95
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/ngzone-scheduler.service.ts
@@ -0,0 +1,48 @@
+import { Injectable, NgZone } from '@angular/core';
+
+import { asyncScheduler, SchedulerLike, Subscription } from 'rxjs';
+
+abstract class NgZoneScheduler implements SchedulerLike {
+ protected scheduler = asyncScheduler;
+
+ constructor(protected zone: NgZone) {}
+
+ abstract schedule(...args: any[]): Subscription;
+
+ now(): number {
+ return this.scheduler.now();
+ }
+}
+
+@Injectable({
+ providedIn: 'root'
+})
+export class LeaveNgZoneScheduler extends NgZoneScheduler {
+ constructor(zone: NgZone) {
+ super(zone);
+ }
+
+ schedule(...args: any[]): Subscription {
+ return this.zone.runOutsideAngular(() => this.scheduler.schedule.apply(this.scheduler, args));
+ }
+}
+
+@Injectable({
+ providedIn: 'root'
+})
+export class EnterNgZoneScheduler extends NgZoneScheduler {
+ constructor(zone: NgZone) {
+ super(zone);
+ }
+
+ schedule(...args: any[]): Subscription {
+ return this.zone.run(() => this.scheduler.schedule.apply(this.scheduler, args));
+ }
+}
+
+@Injectable({
+ providedIn: 'root'
+})
+export class NgZoneSchedulerService {
+ constructor(public leave: LeaveNgZoneScheduler, public enter: EnterNgZoneScheduler) {}
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/no-sso-guard.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/no-sso-guard.service.spec.ts
new file mode 100644
index 000000000..9a330cdc8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/no-sso-guard.service.spec.ts
@@ -0,0 +1,49 @@
+import { Component, NgZone } from '@angular/core';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { Routes } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { DashboardUserDeniedError } from '~/app/core/error/error';
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { AuthStorageService } from './auth-storage.service';
+import { NoSsoGuardService } from './no-sso-guard.service';
+
+describe('NoSsoGuardService', () => {
+ let service: NoSsoGuardService;
+ let authStorageService: AuthStorageService;
+ let ngZone: NgZone;
+
+ @Component({ selector: 'cd-404', template: '' })
+ class NotFoundComponent {}
+
+ const routes: Routes = [{ path: '404', component: NotFoundComponent }];
+
+ configureTestBed({
+ imports: [RouterTestingModule.withRoutes(routes)],
+ providers: [NoSsoGuardService, AuthStorageService],
+ declarations: [NotFoundComponent]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(NoSsoGuardService);
+ authStorageService = TestBed.inject(AuthStorageService);
+ ngZone = TestBed.inject(NgZone);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should allow if not logged in via SSO', () => {
+ spyOn(authStorageService, 'isSSO').and.returnValue(false);
+ expect(service.canActivate()).toBe(true);
+ });
+
+ it('should prevent if logged in via SSO', fakeAsync(() => {
+ spyOn(authStorageService, 'isSSO').and.returnValue(true);
+ ngZone.run(() => {
+ expect(() => service.canActivate()).toThrowError(DashboardUserDeniedError);
+ });
+ tick();
+ }));
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/no-sso-guard.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/no-sso-guard.service.ts
new file mode 100644
index 000000000..d4abcde0d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/no-sso-guard.service.ts
@@ -0,0 +1,28 @@
+import { Injectable } from '@angular/core';
+import { CanActivate, CanActivateChild } from '@angular/router';
+
+import { DashboardUserDeniedError } from '~/app/core/error/error';
+import { AuthStorageService } from './auth-storage.service';
+
+/**
+ * This service checks if a route can be activated if the user has not
+ * been logged in via SSO.
+ */
+@Injectable({
+ providedIn: 'root'
+})
+export class NoSsoGuardService implements CanActivate, CanActivateChild {
+ constructor(private authStorageService: AuthStorageService) {}
+
+ canActivate() {
+ if (!this.authStorageService.isSSO()) {
+ return true;
+ }
+ throw new DashboardUserDeniedError();
+ return false;
+ }
+
+ canActivateChild(): boolean {
+ return this.canActivate();
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/notification.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/notification.service.spec.ts
new file mode 100644
index 000000000..028dd90ea
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/notification.service.spec.ts
@@ -0,0 +1,285 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+
+import _ from 'lodash';
+import { ToastrService } from 'ngx-toastr';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RbdService } from '../api/rbd.service';
+import { NotificationType } from '../enum/notification-type.enum';
+import { CdNotificationConfig } from '../models/cd-notification';
+import { FinishedTask } from '../models/finished-task';
+import { CdDatePipe } from '../pipes/cd-date.pipe';
+import { NotificationService } from './notification.service';
+import { TaskMessageService } from './task-message.service';
+
+describe('NotificationService', () => {
+ let service: NotificationService;
+ const toastFakeService = {
+ error: () => true,
+ info: () => true,
+ success: () => true
+ };
+
+ configureTestBed({
+ providers: [
+ NotificationService,
+ TaskMessageService,
+ { provide: ToastrService, useValue: toastFakeService },
+ { provide: CdDatePipe, useValue: { transform: (d: any) => d } },
+ RbdService
+ ],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(NotificationService);
+ service.removeAll();
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should read empty notification list', () => {
+ localStorage.setItem('cdNotifications', '[]');
+ expect(service['dataSource'].getValue()).toEqual([]);
+ });
+
+ it('should read old notifications', fakeAsync(() => {
+ localStorage.setItem(
+ 'cdNotifications',
+ '[{"type":2,"message":"foobar","timestamp":"2018-05-24T09:41:32.726Z"}]'
+ );
+ service = new NotificationService(null, null, null);
+ expect(service['dataSource'].getValue().length).toBe(1);
+ }));
+
+ it('should cancel a notification', fakeAsync(() => {
+ const timeoutId = service.show(NotificationType.error, 'Simple test');
+ service.cancel(timeoutId);
+ tick(5000);
+ expect(service['dataSource'].getValue().length).toBe(0);
+ }));
+
+ describe('Saved notifications', () => {
+ const expectSavedNotificationToHave = (expected: object) => {
+ tick(510);
+ expect(service['dataSource'].getValue().length).toBe(1);
+ const notification = service['dataSource'].getValue()[0];
+ Object.keys(expected).forEach((key) => {
+ expect(notification[key]).toBe(expected[key]);
+ });
+ };
+
+ const addNotifications = (quantity: number) => {
+ for (let index = 0; index < quantity; index++) {
+ service.show(NotificationType.info, `${index}`);
+ tick(510);
+ }
+ };
+
+ beforeEach(() => {
+ spyOn(service, 'show').and.callThrough();
+ service.cancel((<any>service)['justShownTimeoutId']);
+ });
+
+ it('should create a success notification and save it', fakeAsync(() => {
+ service.show(new CdNotificationConfig(NotificationType.success, 'Simple test'));
+ expectSavedNotificationToHave({ type: NotificationType.success });
+ }));
+
+ it('should create an error notification and save it', fakeAsync(() => {
+ service.show(NotificationType.error, 'Simple test');
+ expectSavedNotificationToHave({ type: NotificationType.error });
+ }));
+
+ it('should create an info notification and save it', fakeAsync(() => {
+ service.show(new CdNotificationConfig(NotificationType.info, 'Simple test'));
+ expectSavedNotificationToHave({
+ type: NotificationType.info,
+ title: 'Simple test',
+ message: undefined
+ });
+ }));
+
+ it('should never have more then 10 notifications', fakeAsync(() => {
+ addNotifications(15);
+ expect(service['dataSource'].getValue().length).toBe(10);
+ }));
+
+ it('should show a success task notification, but not save it', fakeAsync(() => {
+ const task = _.assign(new FinishedTask(), {
+ success: true
+ });
+
+ service.notifyTask(task, true);
+ tick(1500);
+
+ expect(service.show).toHaveBeenCalled();
+ const notifications = service['dataSource'].getValue();
+ expect(notifications.length).toBe(0);
+ }));
+
+ it('should be able to stop notifyTask from notifying', fakeAsync(() => {
+ const task = _.assign(new FinishedTask(), {
+ success: true
+ });
+ const timeoutId = service.notifyTask(task, true);
+ service.cancel(timeoutId);
+ tick(100);
+ expect(service['dataSource'].getValue().length).toBe(0);
+ }));
+
+ it('should show a error task notification', fakeAsync(() => {
+ const task = _.assign(
+ new FinishedTask('rbd/create', {
+ pool_name: 'somePool',
+ image_name: 'someImage'
+ }),
+ {
+ success: false,
+ exception: {
+ code: 17
+ }
+ }
+ );
+ service.notifyTask(task);
+
+ tick(1500);
+
+ expect(service.show).toHaveBeenCalled();
+ const notifications = service['dataSource'].getValue();
+ expect(notifications.length).toBe(0);
+ }));
+
+ it('combines different notifications with the same title', fakeAsync(() => {
+ service.show(NotificationType.error, '502 - Bad Gateway', 'Error occurred in path a');
+ tick(60);
+ service.show(NotificationType.error, '502 - Bad Gateway', 'Error occurred in path b');
+ expectSavedNotificationToHave({
+ type: NotificationType.error,
+ title: '502 - Bad Gateway',
+ message: '<ul><li>Error occurred in path a</li><li>Error occurred in path b</li></ul>'
+ });
+ }));
+
+ it('should remove a single notification', fakeAsync(() => {
+ addNotifications(5);
+ let messages = service['dataSource'].getValue().map((notification) => notification.title);
+ expect(messages).toEqual(['4', '3', '2', '1', '0']);
+ service.remove(2);
+ messages = service['dataSource'].getValue().map((notification) => notification.title);
+ expect(messages).toEqual(['4', '3', '1', '0']);
+ }));
+
+ it('should remove all notifications', fakeAsync(() => {
+ addNotifications(5);
+ expect(service['dataSource'].getValue().length).toBe(5);
+ service.removeAll();
+ expect(service['dataSource'].getValue().length).toBe(0);
+ }));
+ });
+
+ describe('notification queue', () => {
+ const n1 = new CdNotificationConfig(NotificationType.success, 'Some success');
+ const n2 = new CdNotificationConfig(NotificationType.info, 'Some info');
+
+ const showArray = (arr: any[]) => arr.forEach((n) => service.show(n));
+
+ beforeEach(() => {
+ spyOn(service, 'save').and.stub();
+ });
+
+ it('filters out duplicated notifications on single call', fakeAsync(() => {
+ showArray([n1, n1, n2, n2]);
+ tick(510);
+ expect(service.save).toHaveBeenCalledTimes(2);
+ }));
+
+ it('filters out duplicated notifications presented in different calls', fakeAsync(() => {
+ showArray([n1, n2]);
+ showArray([n1, n2]);
+ tick(1000);
+ expect(service.save).toHaveBeenCalledTimes(2);
+ }));
+
+ it('will reset the timeout on every call', fakeAsync(() => {
+ showArray([n1, n2]);
+ tick(490);
+ showArray([n1, n2]);
+ tick(450);
+ expect(service.save).toHaveBeenCalledTimes(0);
+ tick(60);
+ expect(service.save).toHaveBeenCalledTimes(2);
+ }));
+
+ it('wont filter out duplicated notifications if timeout was reached before', fakeAsync(() => {
+ showArray([n1, n2]);
+ tick(510);
+ showArray([n1, n2]);
+ tick(510);
+ expect(service.save).toHaveBeenCalledTimes(4);
+ }));
+ });
+
+ describe('showToasty', () => {
+ let toastr: ToastrService;
+ const time = '2022-02-22T00:00:00.000Z';
+
+ beforeEach(() => {
+ const baseTime = new Date(time);
+ spyOn(global, 'Date').and.returnValue(baseTime);
+ spyOn(window, 'setTimeout').and.callFake((fn) => fn());
+
+ toastr = TestBed.inject(ToastrService);
+ // spyOn needs to know the methods before spying and can't read the array for clarification
+ ['error', 'info', 'success'].forEach((method: 'error' | 'info' | 'success') =>
+ spyOn(toastr, method).and.stub()
+ );
+ });
+
+ it('should show with only title defined', () => {
+ service.show(NotificationType.info, 'Some info');
+ expect(toastr.info).toHaveBeenCalledWith(
+ `<small class="date">${time}</small>` +
+ '<i class="float-right custom-icon ceph-icon" title="Ceph"></i>',
+ 'Some info',
+ undefined
+ );
+ });
+
+ it('should show with title and message defined', () => {
+ service.show(
+ () =>
+ new CdNotificationConfig(NotificationType.error, 'Some error', 'Some operation failed')
+ );
+ expect(toastr.error).toHaveBeenCalledWith(
+ 'Some operation failed<br>' +
+ `<small class="date">${time}</small>` +
+ '<i class="float-right custom-icon ceph-icon" title="Ceph"></i>',
+ 'Some error',
+ undefined
+ );
+ });
+
+ it('should show with title, message and application defined', () => {
+ service.show(
+ new CdNotificationConfig(
+ NotificationType.success,
+ 'Alert resolved',
+ 'Some alert resolved',
+ undefined,
+ 'Prometheus'
+ )
+ );
+ expect(toastr.success).toHaveBeenCalledWith(
+ 'Some alert resolved<br>' +
+ `<small class="date">${time}</small>` +
+ '<i class="float-right custom-icon prometheus-icon" title="Prometheus"></i>',
+ 'Alert resolved',
+ undefined
+ );
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/notification.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/notification.service.ts
new file mode 100644
index 000000000..c05dbce0f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/notification.service.ts
@@ -0,0 +1,237 @@
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+import { IndividualConfig, ToastrService } from 'ngx-toastr';
+import { BehaviorSubject, Subject } from 'rxjs';
+
+import { NotificationType } from '../enum/notification-type.enum';
+import { CdNotification, CdNotificationConfig } from '../models/cd-notification';
+import { FinishedTask } from '../models/finished-task';
+import { CdDatePipe } from '../pipes/cd-date.pipe';
+import { TaskMessageService } from './task-message.service';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class NotificationService {
+ private hideToasties = false;
+
+ // Data observable
+ private dataSource = new BehaviorSubject<CdNotification[]>([]);
+ data$ = this.dataSource.asObservable();
+
+ // Sidebar observable
+ sidebarSubject = new Subject();
+
+ private queued: CdNotificationConfig[] = [];
+ private queuedTimeoutId: number;
+ KEY = 'cdNotifications';
+
+ constructor(
+ public toastr: ToastrService,
+ private taskMessageService: TaskMessageService,
+ private cdDatePipe: CdDatePipe
+ ) {
+ const stringNotifications = localStorage.getItem(this.KEY);
+ let notifications: CdNotification[] = [];
+
+ if (_.isString(stringNotifications)) {
+ notifications = JSON.parse(stringNotifications, (_key, value) => {
+ if (_.isPlainObject(value)) {
+ return _.assign(new CdNotification(), value);
+ }
+ return value;
+ });
+ }
+
+ this.dataSource.next(notifications);
+ }
+
+ /**
+ * Removes all current saved notifications
+ */
+ removeAll() {
+ localStorage.removeItem(this.KEY);
+ this.dataSource.next([]);
+ }
+
+ /**
+ * Removes a single saved notifications
+ */
+ remove(index: number) {
+ const recent = this.dataSource.getValue();
+ recent.splice(index, 1);
+ this.dataSource.next(recent);
+ localStorage.setItem(this.KEY, JSON.stringify(recent));
+ }
+
+ /**
+ * Method used for saving a shown notification (check show() method).
+ */
+ save(notification: CdNotification) {
+ const recent = this.dataSource.getValue();
+ recent.push(notification);
+ recent.sort((a, b) => (a.timestamp > b.timestamp ? -1 : 1));
+ while (recent.length > 10) {
+ recent.pop();
+ }
+ this.dataSource.next(recent);
+ localStorage.setItem(this.KEY, JSON.stringify(recent));
+ }
+
+ /**
+ * Method for showing a notification.
+ * @param {NotificationType} type toastr type
+ * @param {string} title
+ * @param {string} [message] The message to be displayed. Note, use this field
+ * for error notifications only.
+ * @param {*} [options] toastr compatible options, used when creating a toastr
+ * @param {string} [application] Only needed if notification comes from an external application
+ * @returns The timeout ID that is set to be able to cancel the notification.
+ */
+ show(
+ type: NotificationType,
+ title: string,
+ message?: string,
+ options?: any | IndividualConfig,
+ application?: string
+ ): number;
+ show(config: CdNotificationConfig | (() => CdNotificationConfig)): number;
+ show(
+ arg: NotificationType | CdNotificationConfig | (() => CdNotificationConfig),
+ title?: string,
+ message?: string,
+ options?: any | IndividualConfig,
+ application?: string
+ ): number {
+ return window.setTimeout(() => {
+ let config: CdNotificationConfig;
+ if (_.isFunction(arg)) {
+ config = arg() as CdNotificationConfig;
+ } else if (_.isObject(arg)) {
+ config = arg as CdNotificationConfig;
+ } else {
+ config = new CdNotificationConfig(
+ arg as NotificationType,
+ title,
+ message,
+ options,
+ application
+ );
+ }
+ this.queueToShow(config);
+ }, 10);
+ }
+
+ private queueToShow(config: CdNotificationConfig) {
+ this.cancel(this.queuedTimeoutId);
+ if (!this.queued.find((c) => _.isEqual(c, config))) {
+ this.queued.push(config);
+ }
+ this.queuedTimeoutId = window.setTimeout(() => {
+ this.showQueued();
+ }, 500);
+ }
+
+ private showQueued() {
+ this.getUnifiedTitleQueue().forEach((config) => {
+ const notification = new CdNotification(config);
+
+ if (!notification.isFinishedTask) {
+ this.save(notification);
+ }
+ this.showToasty(notification);
+ });
+ }
+
+ private getUnifiedTitleQueue(): CdNotificationConfig[] {
+ return Object.values(this.queueShiftByTitle()).map((configs) => {
+ const config = configs[0];
+ if (configs.length > 1) {
+ config.message = '<ul>' + configs.map((c) => `<li>${c.message}</li>`).join('') + '</ul>';
+ }
+ return config;
+ });
+ }
+
+ private queueShiftByTitle(): { [key: string]: CdNotificationConfig[] } {
+ const byTitle: { [key: string]: CdNotificationConfig[] } = {};
+ let config: CdNotificationConfig;
+ while ((config = this.queued.shift())) {
+ if (!byTitle[config.title]) {
+ byTitle[config.title] = [];
+ }
+ byTitle[config.title].push(config);
+ }
+ return byTitle;
+ }
+
+ private showToasty(notification: CdNotification) {
+ // Exit immediately if no toasty should be displayed.
+ if (this.hideToasties) {
+ return;
+ }
+ this.toastr[['error', 'info', 'success'][notification.type]](
+ (notification.message ? notification.message + '<br>' : '') +
+ this.renderTimeAndApplicationHtml(notification),
+ notification.title,
+ notification.options
+ );
+ }
+
+ renderTimeAndApplicationHtml(notification: CdNotification): string {
+ return `<small class="date">${this.cdDatePipe.transform(
+ notification.timestamp
+ )}</small><i class="float-right custom-icon ${notification.applicationClass}" title="${
+ notification.application
+ }"></i>`;
+ }
+
+ notifyTask(finishedTask: FinishedTask, success: boolean = true): number {
+ const notification = this.finishedTaskToNotification(finishedTask, success);
+ notification.isFinishedTask = true;
+ return this.show(notification);
+ }
+
+ finishedTaskToNotification(
+ finishedTask: FinishedTask,
+ success: boolean = true
+ ): CdNotificationConfig {
+ let notification: CdNotificationConfig;
+ if (finishedTask.success && success) {
+ notification = new CdNotificationConfig(
+ NotificationType.success,
+ this.taskMessageService.getSuccessTitle(finishedTask)
+ );
+ } else {
+ notification = new CdNotificationConfig(
+ NotificationType.error,
+ this.taskMessageService.getErrorTitle(finishedTask),
+ this.taskMessageService.getErrorMessage(finishedTask)
+ );
+ }
+ notification.isFinishedTask = true;
+
+ return notification;
+ }
+
+ /**
+ * Prevent the notification from being shown.
+ * @param {number} timeoutId A number representing the ID of the timeout to be canceled.
+ */
+ cancel(timeoutId: number) {
+ window.clearTimeout(timeoutId);
+ }
+
+ /**
+ * Suspend showing the notification toasties.
+ * @param {boolean} suspend Set to ``true`` to disable/hide toasties.
+ */
+ suspendToasties(suspend: boolean) {
+ this.hideToasties = suspend;
+ }
+
+ toggleSidebar(forceClose = false) {
+ this.sidebarSubject.next(forceClose);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/password-policy.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/password-policy.service.spec.ts
new file mode 100644
index 000000000..2925b152b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/password-policy.service.spec.ts
@@ -0,0 +1,208 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { of as observableOf } from 'rxjs';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { SettingsService } from '../api/settings.service';
+import { SharedModule } from '../shared.module';
+import { PasswordPolicyService } from './password-policy.service';
+
+describe('PasswordPolicyService', () => {
+ let service: PasswordPolicyService;
+ let settingsService: SettingsService;
+
+ const helpTextHelper = {
+ get: (chk: string) => {
+ const chkTexts: { [key: string]: string } = {
+ chk_length: 'Must contain at least 10 characters',
+ chk_oldpwd: 'Must not be the same as the previous one',
+ chk_username: 'Cannot contain the username',
+ chk_exclusion_list: 'Cannot contain any configured keyword',
+ chk_repetitive: 'Cannot contain any repetitive characters e.g. "aaa"',
+ chk_sequential: 'Cannot contain any sequential characters e.g. "abc"',
+ chk_complexity:
+ 'Must consist of characters from the following groups:\n' +
+ ' * Alphabetic a-z, A-Z\n' +
+ ' * Numbers 0-9\n' +
+ ' * Special chars: !"#$%& \'()*+,-./:;<=>?@[\\]^_`{{|}}~\n' +
+ ' * Any other characters (signs)'
+ };
+ return ['Required rules for passwords:', '- ' + chkTexts[chk]].join('\n');
+ }
+ };
+
+ configureTestBed({
+ imports: [HttpClientTestingModule, SharedModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(PasswordPolicyService);
+ settingsService = TestBed.inject(SettingsService);
+ settingsService['settings'] = {};
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should not get help text', () => {
+ let helpText = '';
+ spyOn(settingsService, 'getStandardSettings').and.returnValue(
+ observableOf({
+ pwd_policy_enabled: false
+ })
+ );
+ service.getHelpText().subscribe((text) => (helpText = text));
+ expect(helpText).toBe('');
+ });
+
+ it('should get help text chk_length', () => {
+ let helpText = '';
+ const expectedHelpText = helpTextHelper.get('chk_length');
+ spyOn(settingsService, 'getStandardSettings').and.returnValue(
+ observableOf({
+ user_pwd_expiration_warning_1: 10,
+ user_pwd_expiration_warning_2: 5,
+ user_pwd_expiration_span: 90,
+ pwd_policy_enabled: true,
+ pwd_policy_min_length: 10,
+ pwd_policy_check_length_enabled: true,
+ pwd_policy_check_oldpwd_enabled: false,
+ pwd_policy_check_sequential_chars_enabled: false,
+ pwd_policy_check_complexity_enabled: false
+ })
+ );
+ service.getHelpText().subscribe((text) => (helpText = text));
+ expect(helpText).toBe(expectedHelpText);
+ });
+
+ it('should get help text chk_oldpwd', () => {
+ let helpText = '';
+ const expectedHelpText = helpTextHelper.get('chk_oldpwd');
+ spyOn(settingsService, 'getStandardSettings').and.returnValue(
+ observableOf({
+ pwd_policy_enabled: true,
+ pwd_policy_check_oldpwd_enabled: true,
+ pwd_policy_check_username_enabled: false,
+ pwd_policy_check_exclusion_list_enabled: false,
+ pwd_policy_check_complexity_enabled: false
+ })
+ );
+ service.getHelpText().subscribe((text) => (helpText = text));
+ expect(helpText).toBe(expectedHelpText);
+ });
+
+ it('should get help text chk_username', () => {
+ let helpText = '';
+ const expectedHelpText = helpTextHelper.get('chk_username');
+ spyOn(settingsService, 'getStandardSettings').and.returnValue(
+ observableOf({
+ pwd_policy_enabled: true,
+ pwd_policy_check_oldpwd_enabled: false,
+ pwd_policy_check_username_enabled: true,
+ pwd_policy_check_exclusion_list_enabled: false
+ })
+ );
+ service.getHelpText().subscribe((text) => (helpText = text));
+ expect(helpText).toBe(expectedHelpText);
+ });
+
+ it('should get help text chk_exclusion_list', () => {
+ let helpText = '';
+ const expectedHelpText = helpTextHelper.get('chk_exclusion_list');
+ spyOn(settingsService, 'getStandardSettings').and.returnValue(
+ observableOf({
+ pwd_policy_enabled: true,
+ pwd_policy_check_username_enabled: false,
+ pwd_policy_check_exclusion_list_enabled: true,
+ pwd_policy_check_repetitive_chars_enabled: false
+ })
+ );
+ service.getHelpText().subscribe((text) => (helpText = text));
+ expect(helpText).toBe(expectedHelpText);
+ });
+
+ it('should get help text chk_repetitive', () => {
+ let helpText = '';
+ const expectedHelpText = helpTextHelper.get('chk_repetitive');
+ spyOn(settingsService, 'getStandardSettings').and.returnValue(
+ observableOf({
+ user_pwd_expiration_warning_1: 10,
+ pwd_policy_enabled: true,
+ pwd_policy_check_oldpwd_enabled: false,
+ pwd_policy_check_exclusion_list_enabled: false,
+ pwd_policy_check_repetitive_chars_enabled: true,
+ pwd_policy_check_sequential_chars_enabled: false,
+ pwd_policy_check_complexity_enabled: false
+ })
+ );
+ service.getHelpText().subscribe((text) => (helpText = text));
+ expect(helpText).toBe(expectedHelpText);
+ });
+
+ it('should get help text chk_sequential', () => {
+ let helpText = '';
+ const expectedHelpText = helpTextHelper.get('chk_sequential');
+ spyOn(settingsService, 'getStandardSettings').and.returnValue(
+ observableOf({
+ pwd_policy_enabled: true,
+ pwd_policy_min_length: 8,
+ pwd_policy_check_length_enabled: false,
+ pwd_policy_check_oldpwd_enabled: false,
+ pwd_policy_check_username_enabled: false,
+ pwd_policy_check_exclusion_list_enabled: false,
+ pwd_policy_check_repetitive_chars_enabled: false,
+ pwd_policy_check_sequential_chars_enabled: true,
+ pwd_policy_check_complexity_enabled: false
+ })
+ );
+ service.getHelpText().subscribe((text) => (helpText = text));
+ expect(helpText).toBe(expectedHelpText);
+ });
+
+ it('should get help text chk_complexity', () => {
+ let helpText = '';
+ const expectedHelpText = helpTextHelper.get('chk_complexity');
+ spyOn(settingsService, 'getStandardSettings').and.returnValue(
+ observableOf({
+ pwd_policy_enabled: true,
+ pwd_policy_min_length: 8,
+ pwd_policy_check_length_enabled: false,
+ pwd_policy_check_oldpwd_enabled: false,
+ pwd_policy_check_username_enabled: false,
+ pwd_policy_check_exclusion_list_enabled: false,
+ pwd_policy_check_repetitive_chars_enabled: false,
+ pwd_policy_check_sequential_chars_enabled: false,
+ pwd_policy_check_complexity_enabled: true
+ })
+ );
+ service.getHelpText().subscribe((text) => (helpText = text));
+ expect(helpText).toBe(expectedHelpText);
+ });
+
+ it('should get too-weak class', () => {
+ expect(service.mapCreditsToCssClass(0)).toBe('too-weak');
+ expect(service.mapCreditsToCssClass(9)).toBe('too-weak');
+ });
+
+ it('should get weak class', () => {
+ expect(service.mapCreditsToCssClass(10)).toBe('weak');
+ expect(service.mapCreditsToCssClass(14)).toBe('weak');
+ });
+
+ it('should get ok class', () => {
+ expect(service.mapCreditsToCssClass(15)).toBe('ok');
+ expect(service.mapCreditsToCssClass(19)).toBe('ok');
+ });
+
+ it('should get strong class', () => {
+ expect(service.mapCreditsToCssClass(20)).toBe('strong');
+ expect(service.mapCreditsToCssClass(24)).toBe('strong');
+ });
+
+ it('should get very-strong class', () => {
+ expect(service.mapCreditsToCssClass(25)).toBe('very-strong');
+ expect(service.mapCreditsToCssClass(30)).toBe('very-strong');
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/password-policy.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/password-policy.service.ts
new file mode 100644
index 000000000..295420c27
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/password-policy.service.ts
@@ -0,0 +1,65 @@
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+import { Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
+
+import { SettingsService } from '../api/settings.service';
+import { CdPwdPolicySettings } from '../models/cd-pwd-policy-settings';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class PasswordPolicyService {
+ constructor(private settingsService: SettingsService) {}
+
+ getHelpText(): Observable<string> {
+ return this.settingsService.getStandardSettings().pipe(
+ map((resp: { [key: string]: any }) => {
+ const settings = new CdPwdPolicySettings(resp);
+ let helpText: string[] = [];
+ if (settings.pwdPolicyEnabled) {
+ helpText.push($localize`Required rules for passwords:`);
+ const i18nHelp: { [key: string]: string } = {
+ pwdPolicyCheckLengthEnabled: $localize`Must contain at least ${settings.pwdPolicyMinLength} characters`,
+ pwdPolicyCheckOldpwdEnabled: $localize`Must not be the same as the previous one`,
+ pwdPolicyCheckUsernameEnabled: $localize`Cannot contain the username`,
+ pwdPolicyCheckExclusionListEnabled: $localize`Cannot contain any configured keyword`,
+ pwdPolicyCheckRepetitiveCharsEnabled: $localize`Cannot contain any repetitive characters e.g. "aaa"`,
+ pwdPolicyCheckSequentialCharsEnabled: $localize`Cannot contain any sequential characters e.g. "abc"`,
+ pwdPolicyCheckComplexityEnabled: $localize`Must consist of characters from the following groups:
+ * Alphabetic a-z, A-Z
+ * Numbers 0-9
+ * Special chars: !"#$%& '()*+,-./:;<=>?@[\\]^_\`{{|}}~
+ * Any other characters (signs)`
+ };
+ helpText = helpText.concat(
+ _.keys(i18nHelp)
+ .filter((key) => _.get(settings, key))
+ .map((key) => '- ' + _.get(i18nHelp, key))
+ );
+ }
+ return helpText.join('\n');
+ })
+ );
+ }
+
+ /**
+ * Helper function to map password policy credits to a CSS class.
+ * @param credits The password policy credits.
+ * @return The name of the CSS class.
+ */
+ mapCreditsToCssClass(credits: number): string {
+ let result = 'very-strong';
+ if (credits < 10) {
+ result = 'too-weak';
+ } else if (credits < 15) {
+ result = 'weak';
+ } else if (credits < 20) {
+ result = 'ok';
+ } else if (credits < 25) {
+ result = 'strong';
+ }
+ return result;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert-formatter.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert-formatter.spec.ts
new file mode 100644
index 000000000..1384637bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert-formatter.spec.ts
@@ -0,0 +1,95 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+
+import { configureTestBed, PrometheusHelper } from '~/testing/unit-test-helper';
+import { NotificationType } from '../enum/notification-type.enum';
+import { CdNotificationConfig } from '../models/cd-notification';
+import { PrometheusCustomAlert } from '../models/prometheus-alerts';
+import { SharedModule } from '../shared.module';
+import { NotificationService } from './notification.service';
+import { PrometheusAlertFormatter } from './prometheus-alert-formatter';
+
+describe('PrometheusAlertFormatter', () => {
+ let service: PrometheusAlertFormatter;
+ let notificationService: NotificationService;
+ let prometheus: PrometheusHelper;
+
+ configureTestBed({
+ imports: [ToastrModule.forRoot(), SharedModule, HttpClientTestingModule],
+ providers: [PrometheusAlertFormatter]
+ });
+
+ beforeEach(() => {
+ prometheus = new PrometheusHelper();
+ service = TestBed.inject(PrometheusAlertFormatter);
+ notificationService = TestBed.inject(NotificationService);
+ spyOn(notificationService, 'show').and.stub();
+ });
+
+ it('should create', () => {
+ expect(service).toBeTruthy();
+ });
+
+ describe('sendNotifications', () => {
+ it('should not call queue notifications with no notification', () => {
+ service.sendNotifications([]);
+ expect(notificationService.show).not.toHaveBeenCalled();
+ });
+
+ it('should call queue notifications with notifications', () => {
+ const notifications = [new CdNotificationConfig(NotificationType.success, 'test')];
+ service.sendNotifications(notifications);
+ expect(notificationService.show).toHaveBeenCalledWith(notifications[0]);
+ });
+ });
+
+ describe('convertToCustomAlert', () => {
+ it('converts PrometheusAlert', () => {
+ expect(service.convertToCustomAlerts([prometheus.createAlert('Something')])).toEqual([
+ {
+ status: 'active',
+ name: 'Something',
+ description: 'Something is active',
+ url: 'http://Something',
+ fingerprint: 'Something'
+ } as PrometheusCustomAlert
+ ]);
+ });
+
+ it('converts PrometheusNotificationAlert', () => {
+ expect(
+ service.convertToCustomAlerts([prometheus.createNotificationAlert('Something')])
+ ).toEqual([
+ {
+ fingerprint: false,
+ status: 'active',
+ name: 'Something',
+ description: 'Something is firing',
+ url: 'http://Something'
+ } as PrometheusCustomAlert
+ ]);
+ });
+ });
+
+ it('converts custom alert into notification', () => {
+ const alert: PrometheusCustomAlert = {
+ status: 'active',
+ name: 'Some alert',
+ description: 'Some alert is active',
+ url: 'http://some-alert',
+ fingerprint: '42'
+ };
+ expect(service.convertAlertToNotification(alert)).toEqual(
+ new CdNotificationConfig(
+ NotificationType.error,
+ 'Some alert (active)',
+ 'Some alert is active <a href="http://some-alert" target="_blank">' +
+ '<i class="fa fa-line-chart"></i></a>',
+ undefined,
+ 'Prometheus'
+ )
+ );
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert-formatter.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert-formatter.ts
new file mode 100644
index 000000000..96ad5f96f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert-formatter.ts
@@ -0,0 +1,74 @@
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+
+import { Icons } from '../enum/icons.enum';
+import { NotificationType } from '../enum/notification-type.enum';
+import { CdNotificationConfig } from '../models/cd-notification';
+import {
+ AlertmanagerAlert,
+ AlertmanagerNotificationAlert,
+ PrometheusCustomAlert
+} from '../models/prometheus-alerts';
+import { NotificationService } from './notification.service';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class PrometheusAlertFormatter {
+ constructor(private notificationService: NotificationService) {}
+
+ sendNotifications(notifications: CdNotificationConfig[]) {
+ notifications.forEach((n) => this.notificationService.show(n));
+ }
+
+ convertToCustomAlerts(
+ alerts: (AlertmanagerNotificationAlert | AlertmanagerAlert)[]
+ ): PrometheusCustomAlert[] {
+ return _.uniqWith(
+ alerts.map((alert) => {
+ return {
+ status: _.isObject(alert.status)
+ ? (alert as AlertmanagerAlert).status.state
+ : this.getPrometheusNotificationStatus(alert as AlertmanagerNotificationAlert),
+ name: alert.labels.alertname,
+ url: alert.generatorURL,
+ description: alert.annotations.description,
+ fingerprint: _.isObject(alert.status) && (alert as AlertmanagerAlert).fingerprint
+ };
+ }),
+ _.isEqual
+ ) as PrometheusCustomAlert[];
+ }
+
+ /*
+ * This is needed because NotificationAlerts don't use 'active'
+ */
+ private getPrometheusNotificationStatus(alert: AlertmanagerNotificationAlert): string {
+ const state = alert.status;
+ return state === 'firing' ? 'active' : state;
+ }
+
+ convertAlertToNotification(alert: PrometheusCustomAlert): CdNotificationConfig {
+ return new CdNotificationConfig(
+ this.formatType(alert.status),
+ `${alert.name} (${alert.status})`,
+ this.appendSourceLink(alert, alert.description),
+ undefined,
+ 'Prometheus'
+ );
+ }
+
+ private formatType(status: string): NotificationType {
+ const types = {
+ error: ['firing', 'active'],
+ info: ['suppressed', 'unprocessed'],
+ success: ['resolved']
+ };
+ return NotificationType[_.findKey(types, (type) => type.includes(status))];
+ }
+
+ private appendSourceLink(alert: PrometheusCustomAlert, message: string): string {
+ return `${message} <a href="${alert.url}" target="_blank"><i class="${Icons.lineChart}"></i></a>`;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert.service.spec.ts
new file mode 100644
index 000000000..aa3160b30
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert.service.spec.ts
@@ -0,0 +1,214 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+import { Observable, of } from 'rxjs';
+
+import { configureTestBed, PrometheusHelper } from '~/testing/unit-test-helper';
+import { PrometheusService } from '../api/prometheus.service';
+import { NotificationType } from '../enum/notification-type.enum';
+import { CdNotificationConfig } from '../models/cd-notification';
+import { AlertmanagerAlert } from '../models/prometheus-alerts';
+import { SharedModule } from '../shared.module';
+import { NotificationService } from './notification.service';
+import { PrometheusAlertFormatter } from './prometheus-alert-formatter';
+import { PrometheusAlertService } from './prometheus-alert.service';
+
+describe('PrometheusAlertService', () => {
+ let service: PrometheusAlertService;
+ let notificationService: NotificationService;
+ let alerts: AlertmanagerAlert[];
+ let prometheusService: PrometheusService;
+ let prometheus: PrometheusHelper;
+
+ configureTestBed({
+ imports: [ToastrModule.forRoot(), SharedModule, HttpClientTestingModule],
+ providers: [PrometheusAlertService, PrometheusAlertFormatter]
+ });
+
+ beforeEach(() => {
+ prometheus = new PrometheusHelper();
+ });
+
+ it('should create', () => {
+ expect(TestBed.inject(PrometheusAlertService)).toBeTruthy();
+ });
+
+ describe('test failing status codes and verify disabling of the alertmanager', () => {
+ const isDisabledByStatusCode = (statusCode: number, expectedStatus: boolean, done: any) => {
+ service = TestBed.inject(PrometheusAlertService);
+ prometheusService = TestBed.inject(PrometheusService);
+ spyOn(prometheusService, 'ifAlertmanagerConfigured').and.callFake((fn) => fn());
+ spyOn(prometheusService, 'getAlerts').and.returnValue(
+ new Observable((observer: any) => observer.error({ status: statusCode, error: {} }))
+ );
+ const disableFn = spyOn(prometheusService, 'disableAlertmanagerConfig').and.callFake(() => {
+ expect(expectedStatus).toBe(true);
+ done();
+ });
+
+ if (!expectedStatus) {
+ expect(disableFn).not.toHaveBeenCalled();
+ done();
+ }
+
+ service.getAlerts();
+ };
+
+ it('disables on 504 error which is thrown if the mgr failed', (done) => {
+ isDisabledByStatusCode(504, true, done);
+ });
+
+ it('disables on 404 error which is thrown if the external api cannot be reached', (done) => {
+ isDisabledByStatusCode(404, true, done);
+ });
+
+ it('does not disable on 400 error which is thrown if the external api receives unexpected data', (done) => {
+ isDisabledByStatusCode(400, false, done);
+ });
+ });
+
+ it('should flatten the response of getRules()', () => {
+ service = TestBed.inject(PrometheusAlertService);
+ prometheusService = TestBed.inject(PrometheusService);
+
+ spyOn(service['prometheusService'], 'ifPrometheusConfigured').and.callFake((fn) => fn());
+ spyOn(prometheusService, 'getRules').and.returnValue(
+ of({
+ groups: [
+ {
+ name: 'group1',
+ rules: [{ name: 'nearly_full', type: 'alerting' }]
+ },
+ {
+ name: 'test',
+ rules: [
+ { name: 'load_0', type: 'alerting' },
+ { name: 'load_1', type: 'alerting' },
+ { name: 'load_2', type: 'alerting' }
+ ]
+ }
+ ]
+ })
+ );
+
+ service.getRules();
+
+ expect(service.rules as any).toEqual([
+ { name: 'nearly_full', type: 'alerting', group: 'group1' },
+ { name: 'load_0', type: 'alerting', group: 'test' },
+ { name: 'load_1', type: 'alerting', group: 'test' },
+ { name: 'load_2', type: 'alerting', group: 'test' }
+ ]);
+ });
+
+ describe('refresh', () => {
+ beforeEach(() => {
+ service = TestBed.inject(PrometheusAlertService);
+ service['alerts'] = [];
+ service['canAlertsBeNotified'] = false;
+
+ spyOn(window, 'setTimeout').and.callFake((fn: Function) => fn());
+
+ notificationService = TestBed.inject(NotificationService);
+ spyOn(notificationService, 'show').and.stub();
+
+ prometheusService = TestBed.inject(PrometheusService);
+ spyOn(prometheusService, 'ifAlertmanagerConfigured').and.callFake((fn) => fn());
+ spyOn(prometheusService, 'getAlerts').and.callFake(() => of(alerts));
+
+ alerts = [prometheus.createAlert('alert0')];
+ service.refresh();
+ });
+
+ it('should not notify on first call', () => {
+ expect(notificationService.show).not.toHaveBeenCalled();
+ });
+
+ it('should not notify with no change', () => {
+ service.refresh();
+ expect(notificationService.show).not.toHaveBeenCalled();
+ });
+
+ it('should notify on alert change', () => {
+ alerts = [prometheus.createAlert('alert0', 'resolved')];
+ service.refresh();
+ expect(notificationService.show).toHaveBeenCalledWith(
+ new CdNotificationConfig(
+ NotificationType.success,
+ 'alert0 (resolved)',
+ 'alert0 is resolved ' + prometheus.createLink('http://alert0'),
+ undefined,
+ 'Prometheus'
+ )
+ );
+ });
+
+ it('should not notify on change to suppressed', () => {
+ alerts = [prometheus.createAlert('alert0', 'suppressed')];
+ service.refresh();
+ expect(notificationService.show).not.toHaveBeenCalled();
+ });
+
+ it('should notify on a new alert', () => {
+ alerts = [prometheus.createAlert('alert1'), prometheus.createAlert('alert0')];
+ service.refresh();
+ expect(notificationService.show).toHaveBeenCalledTimes(1);
+ expect(notificationService.show).toHaveBeenCalledWith(
+ new CdNotificationConfig(
+ NotificationType.error,
+ 'alert1 (active)',
+ 'alert1 is active ' + prometheus.createLink('http://alert1'),
+ undefined,
+ 'Prometheus'
+ )
+ );
+ });
+
+ it('should notify a resolved alert if it is not there anymore', () => {
+ alerts = [];
+ service.refresh();
+ expect(notificationService.show).toHaveBeenCalledTimes(1);
+ expect(notificationService.show).toHaveBeenCalledWith(
+ new CdNotificationConfig(
+ NotificationType.success,
+ 'alert0 (resolved)',
+ 'alert0 is active ' + prometheus.createLink('http://alert0'),
+ undefined,
+ 'Prometheus'
+ )
+ );
+ });
+
+ it('should call multiple times for multiple changes', () => {
+ const alert1 = prometheus.createAlert('alert1');
+ alerts.push(alert1);
+ service.refresh();
+ alerts = [alert1, prometheus.createAlert('alert2')];
+ service.refresh();
+ expect(notificationService.show).toHaveBeenCalledTimes(2);
+ });
+ });
+
+ describe('alert badge', () => {
+ beforeEach(() => {
+ service = TestBed.inject(PrometheusAlertService);
+
+ prometheusService = TestBed.inject(PrometheusService);
+ spyOn(prometheusService, 'ifAlertmanagerConfigured').and.callFake((fn) => fn());
+ spyOn(prometheusService, 'getAlerts').and.callFake(() => of(alerts));
+
+ alerts = [
+ prometheus.createAlert('alert0', 'active'),
+ prometheus.createAlert('alert1', 'suppressed'),
+ prometheus.createAlert('alert2', 'suppressed')
+ ];
+ service.refresh();
+ });
+
+ it('should count active alerts', () => {
+ service.refresh();
+ expect(service.activeAlerts).toBe(1);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert.service.ts
new file mode 100644
index 000000000..6223808fb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert.service.ts
@@ -0,0 +1,100 @@
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+
+import { PrometheusService } from '../api/prometheus.service';
+import {
+ AlertmanagerAlert,
+ PrometheusCustomAlert,
+ PrometheusRule
+} from '../models/prometheus-alerts';
+import { PrometheusAlertFormatter } from './prometheus-alert-formatter';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class PrometheusAlertService {
+ private canAlertsBeNotified = false;
+ alerts: AlertmanagerAlert[] = [];
+ rules: PrometheusRule[] = [];
+ activeAlerts: number;
+
+ constructor(
+ private alertFormatter: PrometheusAlertFormatter,
+ private prometheusService: PrometheusService
+ ) {}
+
+ getAlerts() {
+ this.prometheusService.ifAlertmanagerConfigured(() => {
+ this.prometheusService.getAlerts().subscribe(
+ (alerts) => this.handleAlerts(alerts),
+ (resp) => {
+ if ([404, 504].includes(resp.status)) {
+ this.prometheusService.disableAlertmanagerConfig();
+ }
+ }
+ );
+ });
+ }
+
+ getRules() {
+ this.prometheusService.ifPrometheusConfigured(() => {
+ this.prometheusService.getRules('alerting').subscribe((groups) => {
+ this.rules = groups['groups'].reduce((acc, group) => {
+ return acc.concat(
+ group.rules.map((rule) => {
+ rule.group = group.name;
+ return rule;
+ })
+ );
+ }, []);
+ });
+ });
+ }
+
+ refresh() {
+ this.getAlerts();
+ this.getRules();
+ }
+
+ private handleAlerts(alerts: AlertmanagerAlert[]) {
+ if (this.canAlertsBeNotified) {
+ this.notifyOnAlertChanges(alerts, this.alerts);
+ }
+ this.activeAlerts = _.reduce<AlertmanagerAlert, number>(
+ this.alerts,
+ (result, alert) => (alert.status.state === 'active' ? ++result : result),
+ 0
+ );
+ this.alerts = alerts;
+ this.canAlertsBeNotified = true;
+ }
+
+ private notifyOnAlertChanges(alerts: AlertmanagerAlert[], oldAlerts: AlertmanagerAlert[]) {
+ const changedAlerts = this.getChangedAlerts(
+ this.alertFormatter.convertToCustomAlerts(alerts),
+ this.alertFormatter.convertToCustomAlerts(oldAlerts)
+ );
+ const suppressedFiltered = _.filter(changedAlerts, (alert) => {
+ return alert.status !== 'suppressed';
+ });
+ const notifications = suppressedFiltered.map((alert) =>
+ this.alertFormatter.convertAlertToNotification(alert)
+ );
+ this.alertFormatter.sendNotifications(notifications);
+ }
+
+ private getChangedAlerts(alerts: PrometheusCustomAlert[], oldAlerts: PrometheusCustomAlert[]) {
+ const updatedAndNew = _.differenceWith(alerts, oldAlerts, _.isEqual);
+ return updatedAndNew.concat(this.getVanishedAlerts(alerts, oldAlerts));
+ }
+
+ private getVanishedAlerts(alerts: PrometheusCustomAlert[], oldAlerts: PrometheusCustomAlert[]) {
+ return _.differenceWith(oldAlerts, alerts, (a, b) => a.fingerprint === b.fingerprint).map(
+ (alert) => {
+ alert.status = 'resolved';
+ return alert;
+ }
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-notification.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-notification.service.spec.ts
new file mode 100644
index 000000000..4fb2bbbb9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-notification.service.spec.ts
@@ -0,0 +1,227 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+
+import { ToastrModule, ToastrService } from 'ngx-toastr';
+import { of, throwError } from 'rxjs';
+
+import { configureTestBed, PrometheusHelper } from '~/testing/unit-test-helper';
+import { PrometheusService } from '../api/prometheus.service';
+import { NotificationType } from '../enum/notification-type.enum';
+import { CdNotificationConfig } from '../models/cd-notification';
+import { AlertmanagerNotification } from '../models/prometheus-alerts';
+import { SharedModule } from '../shared.module';
+import { NotificationService } from './notification.service';
+import { PrometheusAlertFormatter } from './prometheus-alert-formatter';
+import { PrometheusNotificationService } from './prometheus-notification.service';
+
+describe('PrometheusNotificationService', () => {
+ let service: PrometheusNotificationService;
+ let notificationService: NotificationService;
+ let notifications: AlertmanagerNotification[];
+ let prometheusService: PrometheusService;
+ let prometheus: PrometheusHelper;
+ let shown: CdNotificationConfig[];
+ let getNotificationSinceMock: Function;
+
+ const toastFakeService = {
+ error: () => true,
+ info: () => true,
+ success: () => true
+ };
+
+ configureTestBed({
+ imports: [ToastrModule.forRoot(), SharedModule, HttpClientTestingModule],
+ providers: [
+ PrometheusNotificationService,
+ PrometheusAlertFormatter,
+ { provide: ToastrService, useValue: toastFakeService }
+ ]
+ });
+
+ beforeEach(() => {
+ prometheus = new PrometheusHelper();
+
+ service = TestBed.inject(PrometheusNotificationService);
+ service['notifications'] = [];
+
+ notificationService = TestBed.inject(NotificationService);
+ shown = [];
+ spyOn(notificationService, 'show').and.callThrough();
+ spyOn(notificationService, 'save').and.callFake((n) => shown.push(n));
+
+ spyOn(window, 'setTimeout').and.callFake((fn: Function) => fn());
+
+ prometheusService = TestBed.inject(PrometheusService);
+ getNotificationSinceMock = () => of(notifications);
+ spyOn(prometheusService, 'getNotifications').and.callFake(() => getNotificationSinceMock());
+
+ notifications = [prometheus.createNotification()];
+ });
+
+ it('should create', () => {
+ expect(service).toBeTruthy();
+ });
+
+ describe('getLastNotification', () => {
+ it('returns an empty object on the first call', () => {
+ service.refresh();
+ expect(prometheusService.getNotifications).toHaveBeenCalledWith(undefined);
+ expect(service['notifications'].length).toBe(1);
+ });
+
+ it('returns last notification on any other call', () => {
+ service.refresh();
+ notifications = [prometheus.createNotification(1, 'resolved')];
+ service.refresh();
+ expect(prometheusService.getNotifications).toHaveBeenCalledWith(service['notifications'][0]);
+ expect(service['notifications'].length).toBe(2);
+
+ notifications = [prometheus.createNotification(2)];
+ service.refresh();
+ notifications = [prometheus.createNotification(3, 'resolved')];
+ service.refresh();
+ expect(prometheusService.getNotifications).toHaveBeenCalledWith(service['notifications'][2]);
+ expect(service['notifications'].length).toBe(4);
+ });
+ });
+
+ it('notifies not on the first call', () => {
+ service.refresh();
+ expect(notificationService.save).not.toHaveBeenCalled();
+ });
+
+ it('notifies should not call the api again if it failed once', () => {
+ getNotificationSinceMock = () => throwError(new Error('Test error'));
+ service.refresh();
+ expect(prometheusService.getNotifications).toHaveBeenCalledTimes(1);
+ expect(service['backendFailure']).toBe(true);
+ service.refresh();
+ expect(prometheusService.getNotifications).toHaveBeenCalledTimes(1);
+ service['backendFailure'] = false;
+ });
+
+ describe('looks of fired notifications', () => {
+ const asyncRefresh = () => {
+ service.refresh();
+ tick(20);
+ };
+
+ const expectShown = (expected: object[]) => {
+ tick(500);
+ expect(shown.length).toBe(expected.length);
+ expected.forEach((e, i) =>
+ Object.keys(e).forEach((key) => expect(shown[i][key]).toEqual(expected[i][key]))
+ );
+ };
+
+ beforeEach(() => {
+ service.refresh();
+ });
+
+ it('notifies on the second call', () => {
+ service.refresh();
+ expect(notificationService.show).toHaveBeenCalledTimes(1);
+ });
+
+ it('notify looks on single notification with single alert like', fakeAsync(() => {
+ asyncRefresh();
+ expectShown([
+ new CdNotificationConfig(
+ NotificationType.error,
+ 'alert0 (active)',
+ 'alert0 is firing ' + prometheus.createLink('http://alert0'),
+ undefined,
+ 'Prometheus'
+ )
+ ]);
+ }));
+
+ it('raises multiple pop overs for a single notification with multiple alerts', fakeAsync(() => {
+ asyncRefresh();
+ notifications[0].alerts.push(prometheus.createNotificationAlert('alert1', 'resolved'));
+ asyncRefresh();
+ expectShown([
+ new CdNotificationConfig(
+ NotificationType.error,
+ 'alert0 (active)',
+ 'alert0 is firing ' + prometheus.createLink('http://alert0'),
+ undefined,
+ 'Prometheus'
+ ),
+ new CdNotificationConfig(
+ NotificationType.success,
+ 'alert1 (resolved)',
+ 'alert1 is resolved ' + prometheus.createLink('http://alert1'),
+ undefined,
+ 'Prometheus'
+ )
+ ]);
+ }));
+
+ it('should raise multiple notifications if they do not look like each other', fakeAsync(() => {
+ notifications[0].alerts.push(prometheus.createNotificationAlert('alert1'));
+ notifications.push(prometheus.createNotification());
+ notifications[1].alerts.push(prometheus.createNotificationAlert('alert2'));
+ asyncRefresh();
+ expectShown([
+ new CdNotificationConfig(
+ NotificationType.error,
+ 'alert0 (active)',
+ 'alert0 is firing ' + prometheus.createLink('http://alert0'),
+ undefined,
+ 'Prometheus'
+ ),
+ new CdNotificationConfig(
+ NotificationType.error,
+ 'alert1 (active)',
+ 'alert1 is firing ' + prometheus.createLink('http://alert1'),
+ undefined,
+ 'Prometheus'
+ ),
+ new CdNotificationConfig(
+ NotificationType.error,
+ 'alert2 (active)',
+ 'alert2 is firing ' + prometheus.createLink('http://alert2'),
+ undefined,
+ 'Prometheus'
+ )
+ ]);
+ }));
+
+ it('only shows toasties if it got new data', () => {
+ service.refresh();
+ expect(notificationService.save).toHaveBeenCalledTimes(1);
+ notifications = [];
+ service.refresh();
+ service.refresh();
+ expect(notificationService.save).toHaveBeenCalledTimes(1);
+ notifications = [prometheus.createNotification()];
+ service.refresh();
+ expect(notificationService.save).toHaveBeenCalledTimes(2);
+ service.refresh();
+ expect(notificationService.save).toHaveBeenCalledTimes(3);
+ });
+
+ it('filters out duplicated and non user visible changes in notifications', fakeAsync(() => {
+ asyncRefresh();
+ // Return 2 notifications with 3 duplicated alerts and 1 non visible changed alert
+ const secondAlert = prometheus.createNotificationAlert('alert0');
+ secondAlert.endsAt = new Date().toString(); // Should be ignored as it's not visible
+ notifications[0].alerts.push(secondAlert);
+ notifications.push(prometheus.createNotification());
+ notifications[1].alerts.push(prometheus.createNotificationAlert('alert0'));
+ notifications[1].notified = 'by somebody else';
+ asyncRefresh();
+
+ expectShown([
+ new CdNotificationConfig(
+ NotificationType.error,
+ 'alert0 (active)',
+ 'alert0 is firing ' + prometheus.createLink('http://alert0'),
+ undefined,
+ 'Prometheus'
+ )
+ ]);
+ }));
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-notification.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-notification.service.ts
new file mode 100644
index 000000000..ab94c686e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-notification.service.ts
@@ -0,0 +1,51 @@
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+
+import { PrometheusService } from '../api/prometheus.service';
+import { CdNotificationConfig } from '../models/cd-notification';
+import { AlertmanagerNotification } from '../models/prometheus-alerts';
+import { PrometheusAlertFormatter } from './prometheus-alert-formatter';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class PrometheusNotificationService {
+ private notifications: AlertmanagerNotification[];
+ private backendFailure = false;
+
+ constructor(
+ private alertFormatter: PrometheusAlertFormatter,
+ private prometheusService: PrometheusService
+ ) {
+ this.notifications = [];
+ }
+
+ refresh() {
+ if (this.backendFailure) {
+ return;
+ }
+ this.prometheusService.getNotifications(_.last(this.notifications)).subscribe(
+ (notifications) => this.handleNotifications(notifications),
+ () => (this.backendFailure = true)
+ );
+ }
+
+ private handleNotifications(notifications: AlertmanagerNotification[]) {
+ if (notifications.length === 0) {
+ return;
+ }
+ if (this.notifications.length > 0) {
+ this.alertFormatter.sendNotifications(
+ _.flatten(notifications.map((notification) => this.formatNotification(notification)))
+ );
+ }
+ this.notifications = this.notifications.concat(notifications);
+ }
+
+ private formatNotification(notification: AlertmanagerNotification): CdNotificationConfig[] {
+ return this.alertFormatter
+ .convertToCustomAlerts(notification.alerts)
+ .map((alert) => this.alertFormatter.convertAlertToNotification(alert));
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-silence-matcher.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-silence-matcher.service.spec.ts
new file mode 100644
index 000000000..92ff6baa7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-silence-matcher.service.spec.ts
@@ -0,0 +1,133 @@
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed, PrometheusHelper } from '~/testing/unit-test-helper';
+import { PrometheusRule } from '../models/prometheus-alerts';
+import { SharedModule } from '../shared.module';
+import { PrometheusSilenceMatcherService } from './prometheus-silence-matcher.service';
+
+describe('PrometheusSilenceMatcherService', () => {
+ let service: PrometheusSilenceMatcherService;
+ let prometheus: PrometheusHelper;
+ let rules: PrometheusRule[];
+
+ configureTestBed({
+ imports: [SharedModule]
+ });
+
+ const addMatcher = (name: string, value: any) => ({
+ name: name,
+ value: value,
+ isRegex: false
+ });
+
+ beforeEach(() => {
+ prometheus = new PrometheusHelper();
+ service = TestBed.inject(PrometheusSilenceMatcherService);
+ rules = [
+ prometheus.createRule('alert0', 'someSeverity', [prometheus.createAlert('alert0')]),
+ prometheus.createRule('alert1', 'someSeverity', []),
+ prometheus.createRule('alert2', 'someOtherSeverity', [prometheus.createAlert('alert2')])
+ ];
+ });
+
+ it('should create', () => {
+ expect(service).toBeTruthy();
+ });
+
+ describe('test rule matching with one matcher', () => {
+ const expectSingleMatch = (
+ name: string,
+ value: any,
+ helpText: string,
+ successClass: boolean
+ ) => {
+ const match = service.singleMatch(addMatcher(name, value), rules);
+ expect(match.status).toBe(helpText);
+ expect(match.cssClass).toBe(successClass ? 'has-success' : 'has-warning');
+ };
+
+ it('should match no rule and no alert', () => {
+ expectSingleMatch(
+ 'alertname',
+ 'alert',
+ 'Your matcher seems to match no currently defined rule or active alert.',
+ false
+ );
+ });
+
+ it('should match a rule with no alert', () => {
+ expectSingleMatch('alertname', 'alert1', 'Matches 1 rule with no active alerts.', false);
+ });
+
+ it('should match a rule and an alert', () => {
+ expectSingleMatch('alertname', 'alert0', 'Matches 1 rule with 1 active alert.', true);
+ });
+
+ it('should match multiple rules and an alert', () => {
+ expectSingleMatch('severity', 'someSeverity', 'Matches 2 rules with 1 active alert.', true);
+ });
+
+ it('should match multiple rules and multiple alerts', () => {
+ expectSingleMatch('job', 'someJob', 'Matches 2 rules with 2 active alerts.', true);
+ });
+
+ it('should return any match if regex is checked', () => {
+ const match = service.singleMatch(
+ {
+ name: 'severity',
+ value: 'someSeverity',
+ isRegex: true
+ },
+ rules
+ );
+ expect(match).toBeFalsy();
+ });
+ });
+
+ describe('test rule matching with multiple matcher', () => {
+ const expectMultiMatch = (matchers: any[], helpText: string, successClass: boolean) => {
+ const match = service.multiMatch(matchers, rules);
+ expect(match.status).toBe(helpText);
+ expect(match.cssClass).toBe(successClass ? 'has-success' : 'has-warning');
+ };
+
+ it('should match no rule and no alert', () => {
+ expectMultiMatch(
+ [addMatcher('alertname', 'alert0'), addMatcher('job', 'ceph')],
+ 'Your matcher seems to match no currently defined rule or active alert.',
+ false
+ );
+ });
+
+ it('should match a rule with no alert', () => {
+ expectMultiMatch(
+ [addMatcher('severity', 'someSeverity'), addMatcher('alertname', 'alert1')],
+ 'Matches 1 rule with no active alerts.',
+ false
+ );
+ });
+
+ it('should match a rule and an alert', () => {
+ expectMultiMatch(
+ [addMatcher('instance', 'someInstance'), addMatcher('alertname', 'alert0')],
+ 'Matches 1 rule with 1 active alert.',
+ true
+ );
+ });
+
+ it('should return any match if regex is checked', () => {
+ const match = service.multiMatch(
+ [
+ addMatcher('instance', 'someInstance'),
+ {
+ name: 'severity',
+ value: 'someSeverity',
+ isRegex: true
+ }
+ ],
+ rules
+ );
+ expect(match).toBeFalsy();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-silence-matcher.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-silence-matcher.service.ts
new file mode 100644
index 000000000..7aec6d1d3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-silence-matcher.service.ts
@@ -0,0 +1,78 @@
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+
+import {
+ AlertmanagerSilenceMatcher,
+ AlertmanagerSilenceMatcherMatch
+} from '../models/alertmanager-silence';
+import { PrometheusRule } from '../models/prometheus-alerts';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class PrometheusSilenceMatcherService {
+ private valueAttributePath = {
+ alertname: 'name',
+ instance: 'alerts.0.labels.instance',
+ job: 'alerts.0.labels.job',
+ severity: 'labels.severity'
+ };
+
+ singleMatch(
+ matcher: AlertmanagerSilenceMatcher,
+ rules: PrometheusRule[]
+ ): AlertmanagerSilenceMatcherMatch {
+ return this.multiMatch([matcher], rules);
+ }
+
+ multiMatch(
+ matchers: AlertmanagerSilenceMatcher[],
+ rules: PrometheusRule[]
+ ): AlertmanagerSilenceMatcherMatch {
+ if (matchers.some((matcher) => matcher.isRegex)) {
+ return undefined;
+ }
+ matchers.forEach((matcher) => {
+ rules = this.getMatchedRules(matcher, rules);
+ });
+ return this.describeMatch(rules);
+ }
+
+ private getMatchedRules(
+ matcher: AlertmanagerSilenceMatcher,
+ rules: PrometheusRule[]
+ ): PrometheusRule[] {
+ const attributePath = this.getAttributePath(matcher.name);
+ return rules.filter((r) => _.get(r, attributePath) === matcher.value);
+ }
+
+ private describeMatch(rules: PrometheusRule[]): AlertmanagerSilenceMatcherMatch {
+ let alerts = 0;
+ rules.forEach((r) => (alerts += r.alerts.length));
+ return {
+ status: this.getMatchText(rules.length, alerts),
+ cssClass: alerts ? 'has-success' : 'has-warning'
+ };
+ }
+
+ getAttributePath(name: string): string {
+ return this.valueAttributePath[name];
+ }
+
+ private getMatchText(rules: number, alerts: number): string {
+ const msg = {
+ noRule: $localize`Your matcher seems to match no currently defined rule or active alert.`,
+ noAlerts: $localize`no active alerts`,
+ alert: $localize`1 active alert`,
+ alerts: $localize`${alerts} active alerts`,
+ rule: $localize`Matches 1 rule`,
+ rules: $localize`Matches ${rules} rules`
+ };
+
+ const rule = rules > 1 ? msg.rules : msg.rule;
+ const alert = alerts ? (alerts > 1 ? msg.alerts : msg.alert) : msg.noAlerts;
+
+ return rules ? $localize`${rule} with ${alert}.` : msg.noRule;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/rbd-configuration.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/rbd-configuration.service.spec.ts
new file mode 100644
index 000000000..b119f5d63
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/rbd-configuration.service.spec.ts
@@ -0,0 +1,45 @@
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RbdConfigurationType } from '../models/configuration';
+import { RbdConfigurationService } from './rbd-configuration.service';
+
+describe('RbdConfigurationService', () => {
+ let service: RbdConfigurationService;
+
+ configureTestBed({
+ providers: [RbdConfigurationService]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(RbdConfigurationService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should filter config options', () => {
+ const result = service.getOptionByName('rbd_qos_write_iops_burst');
+ expect(result).toEqual({
+ name: 'rbd_qos_write_iops_burst',
+ displayName: 'Write IOPS Burst',
+ description: 'The desired burst limit of write operations.',
+ type: RbdConfigurationType.iops
+ });
+ });
+
+ it('should return the display name', () => {
+ const displayName = service.getDisplayName('rbd_qos_write_iops_burst');
+ expect(displayName).toBe('Write IOPS Burst');
+ });
+
+ it('should return the description', () => {
+ const description = service.getDescription('rbd_qos_write_iops_burst');
+ expect(description).toBe('The desired burst limit of write operations.');
+ });
+
+ it('should have a class for each section', () => {
+ service.sections.forEach((section) => expect(section.class).toBeTruthy());
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/rbd-configuration.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/rbd-configuration.service.ts
new file mode 100644
index 000000000..4499718e1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/rbd-configuration.service.ts
@@ -0,0 +1,144 @@
+import { Injectable } from '@angular/core';
+
+import {
+ RbdConfigurationExtraField,
+ RbdConfigurationSection,
+ RbdConfigurationType
+} from '../models/configuration';
+
+/**
+ * Define here which options should be made available under which section heading.
+ * The display name and description needs to be added manually as long as Ceph does not provide
+ * this information.
+ */
+@Injectable({
+ providedIn: 'root'
+})
+export class RbdConfigurationService {
+ readonly sections: RbdConfigurationSection[];
+
+ constructor() {
+ this.sections = [
+ {
+ heading: $localize`Quality of Service`,
+ class: 'quality-of-service',
+ options: [
+ {
+ name: 'rbd_qos_bps_limit',
+ displayName: $localize`BPS Limit`,
+ description: $localize`The desired limit of IO bytes per second.`,
+ type: RbdConfigurationType.bps
+ },
+ {
+ name: 'rbd_qos_iops_limit',
+ displayName: $localize`IOPS Limit`,
+ description: $localize`The desired limit of IO operations per second.`,
+ type: RbdConfigurationType.iops
+ },
+ {
+ name: 'rbd_qos_read_bps_limit',
+ displayName: $localize`Read BPS Limit`,
+ description: $localize`The desired limit of read bytes per second.`,
+ type: RbdConfigurationType.bps
+ },
+ {
+ name: 'rbd_qos_read_iops_limit',
+ displayName: $localize`Read IOPS Limit`,
+ description: $localize`The desired limit of read operations per second.`,
+ type: RbdConfigurationType.iops
+ },
+ {
+ name: 'rbd_qos_write_bps_limit',
+ displayName: $localize`Write BPS Limit`,
+ description: $localize`The desired limit of write bytes per second.`,
+ type: RbdConfigurationType.bps
+ },
+ {
+ name: 'rbd_qos_write_iops_limit',
+ displayName: $localize`Write IOPS Limit`,
+ description: $localize`The desired limit of write operations per second.`,
+ type: RbdConfigurationType.iops
+ },
+ {
+ name: 'rbd_qos_bps_burst',
+ displayName: $localize`BPS Burst`,
+ description: $localize`The desired burst limit of IO bytes.`,
+ type: RbdConfigurationType.bps
+ },
+ {
+ name: 'rbd_qos_iops_burst',
+ displayName: $localize`IOPS Burst`,
+ description: $localize`The desired burst limit of IO operations.`,
+ type: RbdConfigurationType.iops
+ },
+ {
+ name: 'rbd_qos_read_bps_burst',
+ displayName: $localize`Read BPS Burst`,
+ description: $localize`The desired burst limit of read bytes.`,
+ type: RbdConfigurationType.bps
+ },
+ {
+ name: 'rbd_qos_read_iops_burst',
+ displayName: $localize`Read IOPS Burst`,
+ description: $localize`The desired burst limit of read operations.`,
+ type: RbdConfigurationType.iops
+ },
+ {
+ name: 'rbd_qos_write_bps_burst',
+ displayName: $localize`Write BPS Burst`,
+ description: $localize`The desired burst limit of write bytes.`,
+ type: RbdConfigurationType.bps
+ },
+ {
+ name: 'rbd_qos_write_iops_burst',
+ displayName: $localize`Write IOPS Burst`,
+ description: $localize`The desired burst limit of write operations.`,
+ type: RbdConfigurationType.iops
+ }
+ ] as RbdConfigurationExtraField[]
+ }
+ ];
+ }
+
+ private static getOptionsFromSections(sections: RbdConfigurationSection[]) {
+ return sections.map((section) => section.options).reduce((a, b) => a.concat(b));
+ }
+
+ private filterConfigOptionsByName(configName: string) {
+ return RbdConfigurationService.getOptionsFromSections(this.sections).filter(
+ (option) => option.name === configName
+ );
+ }
+
+ private getOptionValueByName(configName: string, fieldName: string, defaultValue = '') {
+ const configOptions = this.filterConfigOptionsByName(configName);
+ return configOptions.length === 1 ? configOptions.pop()[fieldName] : defaultValue;
+ }
+
+ getWritableSections() {
+ return this.sections.map((section) => {
+ section.options = section.options.filter((o) => !o.readOnly);
+ return section;
+ });
+ }
+
+ getOptionFields() {
+ return RbdConfigurationService.getOptionsFromSections(this.sections);
+ }
+
+ getWritableOptionFields() {
+ return RbdConfigurationService.getOptionsFromSections(this.getWritableSections());
+ }
+
+ getOptionByName(optionName: string): RbdConfigurationExtraField {
+ return this.filterConfigOptionsByName(optionName).pop();
+ }
+
+ getDisplayName(configName: string): string {
+ return this.getOptionValueByName(configName, 'displayName');
+ }
+
+ getDescription(configName: string): string {
+ return this.getOptionValueByName(configName, 'description');
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/refresh-interval.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/refresh-interval.service.spec.ts
new file mode 100644
index 000000000..c26d6389b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/refresh-interval.service.spec.ts
@@ -0,0 +1,52 @@
+import { NgZone } from '@angular/core';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RefreshIntervalService } from './refresh-interval.service';
+
+describe('RefreshIntervalService', () => {
+ let service: RefreshIntervalService;
+
+ configureTestBed({
+ providers: [RefreshIntervalService]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(RefreshIntervalService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should initial private interval time right', () => {
+ sessionStorage.setItem('dashboard_interval', '10000');
+ const ngZone = TestBed.inject(NgZone);
+ service = new RefreshIntervalService(ngZone);
+ expect(service.getRefreshInterval()).toBe(10000);
+ });
+
+ describe('setRefreshInterval', () => {
+ let notifyCount: number;
+
+ it('should send notification to component at correct interval time when interval changed', fakeAsync(() => {
+ service.intervalData$.subscribe(() => {
+ notifyCount++;
+ });
+
+ notifyCount = 0;
+ service.setRefreshInterval(10000);
+ tick(10000);
+ expect(service.getRefreshInterval()).toBe(10000);
+ expect(notifyCount).toBe(1);
+
+ notifyCount = 0;
+ service.setRefreshInterval(30000);
+ tick(30000);
+ expect(service.getRefreshInterval()).toBe(30000);
+ expect(notifyCount).toBe(1);
+
+ service.ngOnDestroy();
+ }));
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/refresh-interval.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/refresh-interval.service.ts
new file mode 100644
index 000000000..03aa3b8a5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/refresh-interval.service.ts
@@ -0,0 +1,46 @@
+import { Injectable, NgZone, OnDestroy } from '@angular/core';
+
+import { BehaviorSubject, interval, Subscription } from 'rxjs';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class RefreshIntervalService implements OnDestroy {
+ private intervalTime: number;
+ // Observable sources
+ private intervalDataSource = new BehaviorSubject(null);
+ private intervalSubscription: Subscription;
+ // Observable streams
+ intervalData$ = this.intervalDataSource.asObservable();
+
+ constructor(private ngZone: NgZone) {
+ const initialInterval = parseInt(sessionStorage.getItem('dashboard_interval'), 10) || 5000;
+ this.setRefreshInterval(initialInterval);
+ }
+
+ setRefreshInterval(newInterval: number) {
+ this.intervalTime = newInterval;
+ sessionStorage.setItem('dashboard_interval', newInterval.toString());
+
+ if (this.intervalSubscription) {
+ this.intervalSubscription.unsubscribe();
+ }
+ this.ngZone.runOutsideAngular(() => {
+ this.intervalSubscription = interval(this.intervalTime).subscribe(() =>
+ this.ngZone.run(() => {
+ this.intervalDataSource.next(this.intervalTime);
+ })
+ );
+ });
+ }
+
+ getRefreshInterval() {
+ return this.intervalTime;
+ }
+
+ ngOnDestroy() {
+ if (this.intervalSubscription) {
+ this.intervalSubscription.unsubscribe();
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/summary.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/summary.service.spec.ts
new file mode 100644
index 000000000..5369a578d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/summary.service.spec.ts
@@ -0,0 +1,179 @@
+import { HttpClient } from '@angular/common/http';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { of as observableOf, Subscriber, Subscription } from 'rxjs';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { ExecutingTask } from '../models/executing-task';
+import { Summary } from '../models/summary.model';
+import { AuthStorageService } from './auth-storage.service';
+import { SummaryService } from './summary.service';
+
+describe('SummaryService', () => {
+ let summaryService: SummaryService;
+ let authStorageService: AuthStorageService;
+ let subs: Subscription;
+
+ const summary: Summary = {
+ executing_tasks: [],
+ health_status: 'HEALTH_OK',
+ mgr_id: 'x',
+ rbd_mirroring: { errors: 0, warnings: 0 },
+ rbd_pools: [],
+ have_mon_connection: true,
+ finished_tasks: [],
+ filesystems: [{ id: 1, name: 'cephfs_a' }]
+ };
+
+ const httpClientSpy = {
+ get: () => observableOf(summary)
+ };
+
+ const nextSummary = (newData: any) => summaryService['summaryDataSource'].next(newData);
+
+ configureTestBed({
+ imports: [RouterTestingModule],
+ providers: [
+ SummaryService,
+ AuthStorageService,
+ { provide: HttpClient, useValue: httpClientSpy }
+ ]
+ });
+
+ beforeEach(() => {
+ summaryService = TestBed.inject(SummaryService);
+ authStorageService = TestBed.inject(AuthStorageService);
+ });
+
+ it('should be created', () => {
+ expect(summaryService).toBeTruthy();
+ });
+
+ it('should call refresh', fakeAsync(() => {
+ authStorageService.set('foobar', undefined, undefined);
+ const calledWith: any[] = [];
+ subs = new Subscription();
+ subs.add(summaryService.startPolling());
+ tick();
+ subs.add(
+ summaryService.subscribe((data) => {
+ calledWith.push(data);
+ })
+ );
+ expect(calledWith).toEqual([summary]);
+ subs.add(summaryService.refresh());
+ expect(calledWith).toEqual([summary, summary]);
+ tick(summaryService.REFRESH_INTERVAL * 2);
+ expect(calledWith.length).toEqual(4);
+ subs.unsubscribe();
+ }));
+
+ describe('Should test subscribe without initial value', () => {
+ let result: Summary;
+ let i: number;
+
+ const callback = (response: Summary) => {
+ i++;
+ result = response;
+ };
+
+ beforeEach(() => {
+ i = 0;
+ result = undefined;
+ nextSummary(undefined);
+ });
+
+ it('should call subscribeOnce', () => {
+ const subscriber = summaryService.subscribeOnce(callback);
+
+ expect(subscriber).toEqual(jasmine.any(Subscriber));
+ expect(i).toBe(0);
+ expect(result).toEqual(undefined);
+
+ nextSummary(undefined);
+ expect(i).toBe(0);
+ expect(result).toEqual(undefined);
+ expect(subscriber.closed).toBe(false);
+
+ nextSummary(summary);
+ expect(result).toEqual(summary);
+ expect(i).toBe(1);
+ expect(subscriber.closed).toBe(true);
+
+ nextSummary(summary);
+ expect(result).toEqual(summary);
+ expect(i).toBe(1);
+ });
+
+ it('should call subscribe', () => {
+ const subscriber = summaryService.subscribe(callback);
+
+ expect(subscriber).toEqual(jasmine.any(Subscriber));
+ expect(i).toBe(0);
+ expect(result).toEqual(undefined);
+
+ nextSummary(undefined);
+ expect(i).toBe(0);
+ expect(result).toEqual(undefined);
+ expect(subscriber.closed).toBe(false);
+
+ nextSummary(summary);
+ expect(result).toEqual(summary);
+ expect(i).toBe(1);
+ expect(subscriber.closed).toBe(false);
+
+ nextSummary(summary);
+ expect(result).toEqual(summary);
+ expect(i).toBe(2);
+ expect(subscriber.closed).toBe(false);
+ });
+ });
+
+ describe('Should test methods after first refresh', () => {
+ beforeEach(() => {
+ authStorageService.set('foobar', undefined, undefined);
+ summaryService.refresh();
+ });
+
+ it('should call addRunningTask', () => {
+ summaryService.addRunningTask(
+ new ExecutingTask('rbd/delete', {
+ pool_name: 'somePool',
+ image_name: 'someImage'
+ })
+ );
+ let result: any;
+ summaryService.subscribeOnce((response) => {
+ result = response;
+ });
+
+ expect(result.executing_tasks.length).toBe(1);
+ expect(result.executing_tasks[0]).toEqual({
+ metadata: { image_name: 'someImage', pool_name: 'somePool' },
+ name: 'rbd/delete'
+ });
+ });
+
+ it('should call addRunningTask with duplicate task', () => {
+ let result: any;
+ summaryService.subscribe((response) => {
+ result = response;
+ });
+
+ const exec_task = new ExecutingTask('rbd/delete', {
+ pool_name: 'somePool',
+ image_name: 'someImage'
+ });
+
+ result.executing_tasks = [exec_task];
+ nextSummary(result);
+
+ expect(result.executing_tasks.length).toBe(1);
+
+ summaryService.addRunningTask(exec_task);
+
+ expect(result.executing_tasks.length).toBe(1);
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/summary.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/summary.service.ts
new file mode 100644
index 000000000..f8282ae97
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/summary.service.ts
@@ -0,0 +1,89 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+import { BehaviorSubject, Observable, Subscription } from 'rxjs';
+import { filter, first } from 'rxjs/operators';
+
+import { ExecutingTask } from '../models/executing-task';
+import { Summary } from '../models/summary.model';
+import { TimerService } from './timer.service';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class SummaryService {
+ readonly REFRESH_INTERVAL = 5000;
+ // Observable sources
+ private summaryDataSource = new BehaviorSubject<Summary>(null);
+ // Observable streams
+ summaryData$ = this.summaryDataSource.asObservable();
+
+ constructor(private http: HttpClient, private timerService: TimerService) {}
+
+ startPolling(): Subscription {
+ return this.timerService
+ .get(() => this.retrieveSummaryObservable(), this.REFRESH_INTERVAL)
+ .subscribe(this.retrieveSummaryObserver());
+ }
+
+ refresh(): Subscription {
+ return this.retrieveSummaryObservable().subscribe(this.retrieveSummaryObserver());
+ }
+
+ private retrieveSummaryObservable(): Observable<Summary> {
+ return this.http.get<Summary>('api/summary');
+ }
+
+ private retrieveSummaryObserver(): (data: Summary) => void {
+ return (data: Summary) => {
+ this.summaryDataSource.next(data);
+ };
+ }
+
+ /**
+ * Subscribes to the summaryData and receive only the first, non undefined, value.
+ */
+ subscribeOnce(next: (summary: Summary) => void, error?: (error: any) => void): Subscription {
+ return this.summaryData$
+ .pipe(
+ filter((value) => !!value),
+ first()
+ )
+ .subscribe(next, error);
+ }
+
+ /**
+ * Subscribes to the summaryData,
+ * which is updated periodically or when a new task is created.
+ * Will receive only non undefined values.
+ */
+ subscribe(next: (summary: Summary) => void, error?: (error: any) => void): Subscription {
+ return this.summaryData$.pipe(filter((value) => !!value)).subscribe(next, error);
+ }
+
+ /**
+ * Inserts a newly created task to the local list of executing tasks.
+ * After that, it will automatically push that new information
+ * to all subscribers.
+ */
+ addRunningTask(task: ExecutingTask) {
+ const current = this.summaryDataSource.getValue();
+ if (!current) {
+ return;
+ }
+
+ if (_.isArray(current.executing_tasks)) {
+ const exists = current.executing_tasks.find((element: any) => {
+ return element.name === task.name && _.isEqual(element.metadata, task.metadata);
+ });
+ if (!exists) {
+ current.executing_tasks.push(task);
+ }
+ } else {
+ current.executing_tasks = [task];
+ }
+
+ this.summaryDataSource.next(current);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.spec.ts
new file mode 100644
index 000000000..66aad3cff
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.spec.ts
@@ -0,0 +1,133 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { of } from 'rxjs';
+
+import { configureTestBed, expectItemTasks } from '~/testing/unit-test-helper';
+import { RbdService } from '../api/rbd.service';
+import { ExecutingTask } from '../models/executing-task';
+import { SummaryService } from './summary.service';
+import { TaskListService } from './task-list.service';
+import { TaskMessageService } from './task-message.service';
+
+describe('TaskListService', () => {
+ let service: TaskListService;
+ let summaryService: SummaryService;
+ let taskMessageService: TaskMessageService;
+
+ let list: any[];
+ let apiResp: any;
+ let tasks: any[];
+
+ const addItem = (name: string) => {
+ apiResp.push({ name: name });
+ };
+
+ configureTestBed({
+ providers: [TaskListService, TaskMessageService, SummaryService, RbdService],
+ imports: [HttpClientTestingModule, RouterTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(TaskListService);
+ summaryService = TestBed.inject(SummaryService);
+ taskMessageService = TestBed.inject(TaskMessageService);
+ summaryService['summaryDataSource'].next({ executing_tasks: [] });
+
+ taskMessageService.messages['test/create'] = taskMessageService.messages['rbd/create'];
+ taskMessageService.messages['test/edit'] = taskMessageService.messages['rbd/edit'];
+ taskMessageService.messages['test/delete'] = taskMessageService.messages['rbd/delete'];
+
+ tasks = [];
+ apiResp = [];
+ list = [];
+ addItem('a');
+ addItem('b');
+ addItem('c');
+
+ service.init(
+ () => of(apiResp),
+ undefined,
+ (updatedList) => (list = updatedList),
+ () => true,
+ (task) => task.name.startsWith('test'),
+ (item, task) => item.name === task.metadata['name'],
+ {
+ default: (metadata: object) => ({ name: metadata['name'] })
+ }
+ );
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ const addTask = (name: string, itemName: string, progress?: number) => {
+ const task = new ExecutingTask();
+ task.name = name;
+ task.progress = progress;
+ task.metadata = { name: itemName };
+ tasks.push(task);
+ summaryService.addRunningTask(task);
+ };
+
+ it('gets all items without any executing items', () => {
+ expect(list.length).toBe(3);
+ expect(list.every((item) => !item.cdExecuting)).toBeTruthy();
+ });
+
+ it('gets an item from a task during creation', () => {
+ addTask('test/create', 'd');
+ expect(list.length).toBe(4);
+ expectItemTasks(list[3], 'Creating');
+ });
+
+ it('shows progress of current task if any above 0', () => {
+ addTask('test/edit', 'd', 97);
+ addTask('test/edit', 'e', 0);
+ expect(list.length).toBe(5);
+ expectItemTasks(list[3], 'Updating', 97);
+ expectItemTasks(list[4], 'Updating');
+ });
+
+ it('gets all items with one executing items', () => {
+ addTask('test/create', 'a');
+ expect(list.length).toBe(3);
+ expectItemTasks(list[0], 'Creating');
+ expectItemTasks(list[1], undefined);
+ expectItemTasks(list[2], undefined);
+ });
+
+ it('gets all items with multiple executing items', () => {
+ addTask('test/create', 'a');
+ addTask('test/edit', 'a');
+ addTask('test/delete', 'a');
+ addTask('test/edit', 'b');
+ addTask('test/delete', 'b');
+ addTask('test/delete', 'c');
+ expect(list.length).toBe(3);
+ expectItemTasks(list[0], 'Creating..., Updating..., Deleting');
+ expectItemTasks(list[1], 'Updating..., Deleting');
+ expectItemTasks(list[2], 'Deleting');
+ });
+
+ it('gets all items with multiple executing tasks (not only item tasks', () => {
+ addTask('rbd/create', 'a');
+ addTask('rbd/edit', 'a');
+ addTask('test/delete', 'a');
+ addTask('test/edit', 'b');
+ addTask('rbd/delete', 'b');
+ addTask('rbd/delete', 'c');
+ expect(list.length).toBe(3);
+ expectItemTasks(list[0], 'Deleting');
+ expectItemTasks(list[1], 'Updating');
+ expectItemTasks(list[2], undefined);
+ });
+
+ it('should call ngOnDestroy', () => {
+ expect(service.summaryDataSubscription.closed).toBeFalsy();
+ service.ngOnDestroy();
+ expect(service.summaryDataSubscription.closed).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.ts
new file mode 100644
index 000000000..321454753
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.ts
@@ -0,0 +1,111 @@
+import { Injectable, OnDestroy } from '@angular/core';
+
+import { Observable, Subscription } from 'rxjs';
+
+import { ExecutingTask } from '../models/executing-task';
+import { Summary } from '../models/summary.model';
+import { SummaryService } from './summary.service';
+import { TaskMessageService } from './task-message.service';
+
+@Injectable()
+export class TaskListService implements OnDestroy {
+ summaryDataSubscription: Subscription;
+
+ getUpdate: (context?: any) => Observable<object>;
+ preProcessing: (_: any) => any[];
+ setList: (_: any[]) => void;
+ onFetchError: (error: any) => void;
+ taskFilter: (task: ExecutingTask) => boolean;
+ itemFilter: (item: any, task: ExecutingTask) => boolean;
+ builders: object;
+ summary: Summary;
+
+ constructor(
+ private taskMessageService: TaskMessageService,
+ private summaryService: SummaryService
+ ) {}
+
+ /**
+ * @param {() => Observable<object>} getUpdate Method that calls the api and
+ * returns that without subscribing.
+ * @param {(_: any) => any[]} preProcessing Method executed before merging
+ * Tasks with Items
+ * @param {(_: any[]) => void} setList Method used to update array of item in the component.
+ * @param {(error: any) => void} onFetchError Method called when there were
+ * problems while fetching data.
+ * @param {(task: ExecutingTask) => boolean} taskFilter callback used in tasks_array.filter()
+ * @param {(item, task: ExecutingTask) => boolean} itemFilter callback used in
+ * items_array.filter()
+ * @param {object} builders
+ * object with builders for each type of task.
+ * You can also use a 'default' one.
+ * @memberof TaskListService
+ */
+ init(
+ getUpdate: (context?: any) => Observable<object>,
+ preProcessing: (_: any) => any[],
+ setList: (_: any[]) => void,
+ onFetchError: (error: any) => void,
+ taskFilter: (task: ExecutingTask) => boolean,
+ itemFilter: (item: any, task: ExecutingTask) => boolean,
+ builders: object
+ ) {
+ this.getUpdate = getUpdate;
+ this.preProcessing = preProcessing;
+ this.setList = setList;
+ this.onFetchError = onFetchError;
+ this.taskFilter = taskFilter;
+ this.itemFilter = itemFilter;
+ this.builders = builders || {};
+
+ this.summaryDataSubscription = this.summaryService.subscribe((summary) => {
+ this.summary = summary;
+ this.fetch();
+ }, this.onFetchError);
+ }
+
+ fetch(context: any = null) {
+ this.getUpdate(context).subscribe((resp: any) => {
+ this.updateData(resp, this.summary?.['executing_tasks'].filter(this.taskFilter));
+ }, this.onFetchError);
+ }
+
+ private updateData(resp: any, tasks: ExecutingTask[]) {
+ const data: any[] = this.preProcessing ? this.preProcessing(resp) : resp;
+ this.addMissing(data, tasks);
+ data.forEach((item) => {
+ const executingTasks = tasks.filter((task) => this.itemFilter(item, task));
+ item.cdExecuting = this.getTaskAction(executingTasks);
+ });
+ this.setList(data);
+ }
+
+ private addMissing(data: any[], tasks: ExecutingTask[]) {
+ const defaultBuilder = this.builders['default'];
+ tasks?.forEach((task) => {
+ const existing = data.find((item) => this.itemFilter(item, task));
+ const builder = this.builders[task.name];
+ if (!existing && (builder || defaultBuilder)) {
+ data.push(builder ? builder(task.metadata) : defaultBuilder(task.metadata));
+ }
+ });
+ }
+
+ private getTaskAction(tasks: ExecutingTask[]): string {
+ if (tasks.length === 0) {
+ return undefined;
+ }
+ return tasks
+ .map((task) => {
+ const progress = task.progress ? ` ${task.progress}%` : '';
+ return this.taskMessageService.getRunningText(task) + '...' + progress;
+ })
+ .join(', ');
+ }
+
+ ngOnDestroy() {
+ if (this.summaryDataSubscription) {
+ this.summaryDataSubscription.unsubscribe();
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-manager.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-manager.service.spec.ts
new file mode 100644
index 000000000..117b60c7e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-manager.service.spec.ts
@@ -0,0 +1,72 @@
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+
+import _ from 'lodash';
+import { BehaviorSubject } from 'rxjs';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { SummaryService } from './summary.service';
+import { TaskManagerService } from './task-manager.service';
+
+const summary: Record<string, any> = {
+ executing_tasks: [],
+ health_status: 'HEALTH_OK',
+ mgr_id: 'x',
+ rbd_mirroring: { errors: 0, warnings: 0 },
+ rbd_pools: [],
+ have_mon_connection: true,
+ finished_tasks: [{ name: 'foo', metadata: {} }],
+ filesystems: [{ id: 1, name: 'cephfs_a' }]
+};
+
+export class SummaryServiceMock {
+ summaryDataSource = new BehaviorSubject(summary);
+ summaryData$ = this.summaryDataSource.asObservable();
+
+ refresh() {
+ this.summaryDataSource.next(summary);
+ }
+ subscribe(call: any) {
+ return this.summaryData$.subscribe(call);
+ }
+}
+
+describe('TaskManagerService', () => {
+ let taskManagerService: TaskManagerService;
+ let summaryService: any;
+ let called: boolean;
+
+ configureTestBed({
+ providers: [TaskManagerService, { provide: SummaryService, useClass: SummaryServiceMock }]
+ });
+
+ beforeEach(() => {
+ taskManagerService = TestBed.inject(TaskManagerService);
+ summaryService = TestBed.inject(SummaryService);
+ called = false;
+ taskManagerService.subscribe('foo', {}, () => (called = true));
+ });
+
+ it('should be created', () => {
+ expect(taskManagerService).toBeTruthy();
+ });
+
+ it('should subscribe and be notified when task is finished', fakeAsync(() => {
+ expect(taskManagerService.subscriptions.length).toBe(1);
+ summaryService.refresh();
+ tick();
+ taskManagerService.init(summaryService);
+ expect(called).toEqual(true);
+ expect(taskManagerService.subscriptions).toEqual([]);
+ }));
+
+ it('should subscribe and process executing taks', fakeAsync(() => {
+ const original_subscriptions = _.cloneDeep(taskManagerService.subscriptions);
+ _.assign(summary, {
+ executing_tasks: [{ name: 'foo', metadata: {} }],
+ finished_tasks: []
+ });
+ summaryService.refresh();
+ tick();
+ expect(taskManagerService.subscriptions).toEqual(original_subscriptions);
+ }));
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-manager.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-manager.service.ts
new file mode 100644
index 000000000..0310a7826
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-manager.service.ts
@@ -0,0 +1,59 @@
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+
+import { ExecutingTask } from '../models/executing-task';
+import { FinishedTask } from '../models/finished-task';
+import { Task } from '../models/task';
+import { SummaryService } from './summary.service';
+
+class TaskSubscription {
+ name: string;
+ metadata: object;
+ onTaskFinished: (finishedTask: FinishedTask) => any;
+
+ constructor(name: string, metadata: object, onTaskFinished: any) {
+ this.name = name;
+ this.metadata = metadata;
+ this.onTaskFinished = onTaskFinished;
+ }
+}
+
+@Injectable({
+ providedIn: 'root'
+})
+export class TaskManagerService {
+ subscriptions: Array<TaskSubscription> = [];
+
+ init(summaryService: SummaryService) {
+ return summaryService.subscribe((summary) => {
+ const executingTasks = summary.executing_tasks;
+ const finishedTasks = summary.finished_tasks;
+ const newSubscriptions: Array<TaskSubscription> = [];
+ for (const subscription of this.subscriptions) {
+ const finishedTask = <FinishedTask>this._getTask(subscription, finishedTasks);
+ const executingTask = <ExecutingTask>this._getTask(subscription, executingTasks);
+ if (finishedTask !== null && executingTask === null) {
+ subscription.onTaskFinished(finishedTask);
+ }
+ if (executingTask !== null) {
+ newSubscriptions.push(subscription);
+ }
+ this.subscriptions = newSubscriptions;
+ }
+ });
+ }
+
+ subscribe(name: string, metadata: object, onTaskFinished: (finishedTask: FinishedTask) => any) {
+ this.subscriptions.push(new TaskSubscription(name, metadata, onTaskFinished));
+ }
+
+ private _getTask(subscription: TaskSubscription, tasks: Array<Task>): Task {
+ for (const task of tasks) {
+ if (task.name === subscription.name && _.isEqual(task.metadata, subscription.metadata)) {
+ return task;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.spec.ts
new file mode 100644
index 000000000..a529656a0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.spec.ts
@@ -0,0 +1,312 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+
+import _ from 'lodash';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { RbdService } from '../api/rbd.service';
+import { FinishedTask } from '../models/finished-task';
+import { TaskException } from '../models/task-exception';
+import { TaskMessageOperation, TaskMessageService } from './task-message.service';
+
+describe('TaskManagerMessageService', () => {
+ let service: TaskMessageService;
+ let finishedTask: FinishedTask;
+
+ configureTestBed({
+ providers: [TaskMessageService, RbdService],
+ imports: [HttpClientTestingModule]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(TaskMessageService);
+ finishedTask = new FinishedTask();
+ finishedTask.duration = 30;
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should get default description', () => {
+ expect(service.getErrorTitle(finishedTask)).toBe('Failed to execute unknown task');
+ });
+
+ it('should get default running message', () => {
+ expect(service.getRunningTitle(finishedTask)).toBe('Executing unknown task');
+ });
+
+ it('should get default running message with a set component', () => {
+ finishedTask.metadata = { component: 'rbd' };
+ expect(service.getRunningTitle(finishedTask)).toBe('Executing RBD');
+ });
+
+ it('should getSuccessMessage', () => {
+ expect(service.getSuccessTitle(finishedTask)).toBe('Executed unknown task');
+ });
+
+ describe('defined tasks messages', () => {
+ let defaultMsg: string;
+ const testMessages = (operation: TaskMessageOperation, involves: string) => {
+ expect(service.getRunningTitle(finishedTask)).toBe(operation.running + ' ' + involves);
+ expect(service.getErrorTitle(finishedTask)).toBe(
+ 'Failed to ' + operation.failure + ' ' + involves
+ );
+ expect(service.getSuccessTitle(finishedTask)).toBe(`${operation.success} ${involves}`);
+ };
+
+ const testCreate = (involves: string) => {
+ testMessages(new TaskMessageOperation('Creating', 'create', 'Created'), involves);
+ };
+
+ const testUpdate = (involves: string) => {
+ testMessages(new TaskMessageOperation('Updating', 'update', 'Updated'), involves);
+ };
+
+ const testDelete = (involves: string) => {
+ testMessages(new TaskMessageOperation('Deleting', 'delete', 'Deleted'), involves);
+ };
+
+ const testImport = (involves: string) => {
+ testMessages(new TaskMessageOperation('Importing', 'import', 'Imported'), involves);
+ };
+
+ const testErrorCode = (code: number, msg: string) => {
+ finishedTask.exception = _.assign(new TaskException(), {
+ code: code
+ });
+ expect(service.getErrorMessage(finishedTask)).toBe(msg);
+ };
+
+ describe('pool tasks', () => {
+ beforeEach(() => {
+ const metadata = {
+ pool_name: 'somePool'
+ };
+ defaultMsg = `pool '${metadata.pool_name}'`;
+ finishedTask.metadata = metadata;
+ });
+
+ it('tests pool/create messages', () => {
+ finishedTask.name = 'pool/create';
+ testCreate(defaultMsg);
+ testErrorCode(17, `Name is already used by ${defaultMsg}.`);
+ });
+
+ it('tests pool/edit messages', () => {
+ finishedTask.name = 'pool/edit';
+ testUpdate(defaultMsg);
+ testErrorCode(17, `Name is already used by ${defaultMsg}.`);
+ });
+
+ it('tests pool/delete messages', () => {
+ finishedTask.name = 'pool/delete';
+ testDelete(defaultMsg);
+ });
+ });
+
+ describe('erasure code profile tasks', () => {
+ beforeEach(() => {
+ const metadata = {
+ name: 'someEcpName'
+ };
+ defaultMsg = `erasure code profile '${metadata.name}'`;
+ finishedTask.metadata = metadata;
+ });
+
+ it('tests ecp/create messages', () => {
+ finishedTask.name = 'ecp/create';
+ testCreate(defaultMsg);
+ testErrorCode(17, `Name is already used by ${defaultMsg}.`);
+ });
+
+ it('tests ecp/delete messages', () => {
+ finishedTask.name = 'ecp/delete';
+ testDelete(defaultMsg);
+ });
+ });
+
+ describe('crush rule tasks', () => {
+ beforeEach(() => {
+ const metadata = {
+ name: 'someRuleName'
+ };
+ defaultMsg = `crush rule '${metadata.name}'`;
+ finishedTask.metadata = metadata;
+ });
+
+ it('tests crushRule/create messages', () => {
+ finishedTask.name = 'crushRule/create';
+ testCreate(defaultMsg);
+ testErrorCode(17, `Name is already used by ${defaultMsg}.`);
+ });
+
+ it('tests crushRule/delete messages', () => {
+ finishedTask.name = 'crushRule/delete';
+ testDelete(defaultMsg);
+ });
+ });
+
+ describe('rbd tasks', () => {
+ let metadata: Record<string, any>;
+ let childMsg: string;
+ let destinationMsg: string;
+ let snapMsg: string;
+
+ beforeEach(() => {
+ metadata = {
+ pool_name: 'somePool',
+ image_name: 'someImage',
+ image_id: '12345',
+ image_spec: 'somePool/someImage',
+ image_id_spec: 'somePool/12345',
+ snapshot_name: 'someSnapShot',
+ dest_pool_name: 'someDestinationPool',
+ dest_image_name: 'someDestinationImage',
+ child_pool_name: 'someChildPool',
+ child_image_name: 'someChildImage',
+ new_image_name: 'someImage2'
+ };
+ defaultMsg = `RBD '${metadata.pool_name}/${metadata.image_name}'`;
+ childMsg = `RBD '${metadata.child_pool_name}/${metadata.child_image_name}'`;
+ destinationMsg = `RBD '${metadata.dest_pool_name}/${metadata.dest_image_name}'`;
+ snapMsg = `RBD snapshot '${metadata.pool_name}/${metadata.image_name}@${metadata.snapshot_name}'`;
+ finishedTask.metadata = metadata;
+ });
+
+ it('tests rbd/create messages', () => {
+ finishedTask.name = 'rbd/create';
+ testCreate(defaultMsg);
+ testErrorCode(17, `Name is already used by ${defaultMsg}.`);
+ });
+
+ it('tests rbd/edit messages', () => {
+ finishedTask.name = 'rbd/edit';
+ testUpdate(defaultMsg);
+ testErrorCode(17, `Name is already used by ${defaultMsg}.`);
+ });
+
+ it('tests rbd/delete messages', () => {
+ finishedTask.name = 'rbd/delete';
+ testDelete(defaultMsg);
+ testErrorCode(16, `${defaultMsg} is busy.`);
+ testErrorCode(39, `${defaultMsg} contains snapshots.`);
+ });
+
+ it('tests rbd/clone messages', () => {
+ finishedTask.name = 'rbd/clone';
+ testMessages(new TaskMessageOperation('Cloning', 'clone', 'Cloned'), childMsg);
+ testErrorCode(17, `Name is already used by ${childMsg}.`);
+ testErrorCode(22, `Snapshot of ${childMsg} must be protected.`);
+ });
+
+ it('tests rbd/copy messages', () => {
+ finishedTask.name = 'rbd/copy';
+ testMessages(new TaskMessageOperation('Copying', 'copy', 'Copied'), destinationMsg);
+ testErrorCode(17, `Name is already used by ${destinationMsg}.`);
+ });
+
+ it('tests rbd/flatten messages', () => {
+ finishedTask.name = 'rbd/flatten';
+ testMessages(new TaskMessageOperation('Flattening', 'flatten', 'Flattened'), defaultMsg);
+ });
+
+ it('tests rbd/snap/create messages', () => {
+ finishedTask.name = 'rbd/snap/create';
+ testCreate(snapMsg);
+ testErrorCode(17, `Name is already used by ${snapMsg}.`);
+ });
+
+ it('tests rbd/snap/edit messages', () => {
+ finishedTask.name = 'rbd/snap/edit';
+ testUpdate(snapMsg);
+ testErrorCode(16, `Cannot unprotect ${snapMsg} because it contains child images.`);
+ });
+
+ it('tests rbd/snap/delete messages', () => {
+ finishedTask.name = 'rbd/snap/delete';
+ testDelete(snapMsg);
+ testErrorCode(16, `Cannot delete ${snapMsg} because it's protected.`);
+ });
+
+ it('tests rbd/snap/rollback messages', () => {
+ finishedTask.name = 'rbd/snap/rollback';
+ testMessages(new TaskMessageOperation('Rolling back', 'rollback', 'Rolled back'), snapMsg);
+ });
+
+ it('tests rbd/trash/move messages', () => {
+ finishedTask.name = 'rbd/trash/move';
+ testMessages(
+ new TaskMessageOperation('Moving', 'move', 'Moved'),
+ `image '${metadata.image_spec}' to trash`
+ );
+ testErrorCode(2, `Could not find image.`);
+ });
+
+ it('tests rbd/trash/restore messages', () => {
+ finishedTask.name = 'rbd/trash/restore';
+ testMessages(
+ new TaskMessageOperation('Restoring', 'restore', 'Restored'),
+ `image '${metadata.image_id_spec}' into '${metadata.new_image_name}'`
+ );
+ testErrorCode(17, `Image name '${metadata.new_image_name}' is already in use.`);
+ });
+
+ it('tests rbd/trash/remove messages', () => {
+ finishedTask.name = 'rbd/trash/remove';
+ testDelete(`image '${metadata.image_id_spec}'`);
+ });
+
+ it('tests rbd/trash/purge messages', () => {
+ finishedTask.name = 'rbd/trash/purge';
+ testMessages(
+ new TaskMessageOperation('Purging', 'purge', 'Purged'),
+ `images from '${metadata.pool_name}'`
+ );
+ });
+ });
+ describe('rbd tasks', () => {
+ let metadata;
+ let modeMsg: string;
+ let peerMsg: string;
+
+ beforeEach(() => {
+ metadata = {
+ pool_name: 'somePool'
+ };
+ modeMsg = `mirror mode for pool '${metadata.pool_name}'`;
+ peerMsg = `mirror peer for pool '${metadata.pool_name}'`;
+ finishedTask.metadata = metadata;
+ });
+ it('tests rbd/mirroring/site_name/edit messages', () => {
+ finishedTask.name = 'rbd/mirroring/site_name/edit';
+ testUpdate('mirroring site name');
+ });
+ it('tests rbd/mirroring/bootstrap/create messages', () => {
+ finishedTask.name = 'rbd/mirroring/bootstrap/create';
+ testCreate('bootstrap token');
+ });
+ it('tests rbd/mirroring/bootstrap/import messages', () => {
+ finishedTask.name = 'rbd/mirroring/bootstrap/import';
+ testImport('bootstrap token');
+ });
+ it('tests rbd/mirroring/pool/edit messages', () => {
+ finishedTask.name = 'rbd/mirroring/pool/edit';
+ testUpdate(modeMsg);
+ testErrorCode(16, 'Cannot disable mirroring because it contains a peer.');
+ });
+ it('tests rbd/mirroring/peer/edit messages', () => {
+ finishedTask.name = 'rbd/mirroring/peer/edit';
+ testUpdate(peerMsg);
+ });
+ it('tests rbd/mirroring/peer/add messages', () => {
+ finishedTask.name = 'rbd/mirroring/peer/add';
+ testCreate(peerMsg);
+ });
+ it('tests rbd/mirroring/peer/delete messages', () => {
+ finishedTask.name = 'rbd/mirroring/peer/delete';
+ testDelete(peerMsg);
+ });
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.ts
new file mode 100644
index 000000000..5adabe211
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.ts
@@ -0,0 +1,424 @@
+import { Injectable } from '@angular/core';
+
+import { Components } from '../enum/components.enum';
+import { FinishedTask } from '../models/finished-task';
+import { ImageSpec } from '../models/image-spec';
+import { Task } from '../models/task';
+
+export class TaskMessageOperation {
+ running: string;
+ failure: string;
+ success: string;
+
+ constructor(running: string, failure: string, success: string) {
+ this.running = running;
+ this.failure = failure;
+ this.success = success;
+ }
+}
+
+class TaskMessage {
+ operation: TaskMessageOperation;
+ involves: (object: any) => string;
+ errors: (metadata: any) => object;
+
+ failure(metadata: any): string {
+ return $localize`Failed to ${this.operation.failure} ${this.involves(metadata)}`;
+ }
+
+ running(metadata: any): string {
+ return `${this.operation.running} ${this.involves(metadata)}`;
+ }
+
+ success(metadata: any): string {
+ return `${this.operation.success} ${this.involves(metadata)}`;
+ }
+
+ constructor(
+ operation: TaskMessageOperation,
+ involves: (metadata: any) => string,
+ errors?: (metadata: any) => object
+ ) {
+ this.operation = operation;
+ this.involves = involves;
+ this.errors = errors || (() => ({}));
+ }
+}
+
+@Injectable({
+ providedIn: 'root'
+})
+export class TaskMessageService {
+ defaultMessage = this.newTaskMessage(
+ new TaskMessageOperation($localize`Executing`, $localize`execute`, $localize`Executed`),
+ (metadata) => {
+ return (
+ (metadata && (Components[metadata.component] || metadata.component)) ||
+ $localize`unknown task`
+ );
+ },
+ () => {
+ return {};
+ }
+ );
+
+ commonOperations = {
+ create: new TaskMessageOperation($localize`Creating`, $localize`create`, $localize`Created`),
+ update: new TaskMessageOperation($localize`Updating`, $localize`update`, $localize`Updated`),
+ delete: new TaskMessageOperation($localize`Deleting`, $localize`delete`, $localize`Deleted`),
+ add: new TaskMessageOperation($localize`Adding`, $localize`add`, $localize`Added`),
+ remove: new TaskMessageOperation($localize`Removing`, $localize`remove`, $localize`Removed`),
+ import: new TaskMessageOperation($localize`Importing`, $localize`import`, $localize`Imported`)
+ };
+
+ rbd = {
+ default: (metadata: any) => $localize`RBD '${metadata.image_spec}'`,
+ create: (metadata: any) => {
+ const id = new ImageSpec(
+ metadata.pool_name,
+ metadata.namespace,
+ metadata.image_name
+ ).toString();
+ return $localize`RBD '${id}'`;
+ },
+ child: (metadata: any) => {
+ const id = new ImageSpec(
+ metadata.child_pool_name,
+ metadata.child_namespace,
+ metadata.child_image_name
+ ).toString();
+ return $localize`RBD '${id}'`;
+ },
+ destination: (metadata: any) => {
+ const id = new ImageSpec(
+ metadata.dest_pool_name,
+ metadata.dest_namespace,
+ metadata.dest_image_name
+ ).toString();
+ return $localize`RBD '${id}'`;
+ },
+ snapshot: (metadata: any) =>
+ $localize`RBD snapshot '${metadata.image_spec}@${metadata.snapshot_name}'`
+ };
+
+ rbd_mirroring = {
+ site_name: () => $localize`mirroring site name`,
+ bootstrap: () => $localize`bootstrap token`,
+ pool: (metadata: any) => $localize`mirror mode for pool '${metadata.pool_name}'`,
+ pool_peer: (metadata: any) => $localize`mirror peer for pool '${metadata.pool_name}'`
+ };
+
+ grafana = {
+ update_dashboards: () => $localize`all dashboards`
+ };
+
+ messages = {
+ // Host tasks
+ 'host/add': this.newTaskMessage(this.commonOperations.add, (metadata) => this.host(metadata)),
+ 'host/remove': this.newTaskMessage(this.commonOperations.remove, (metadata) =>
+ this.host(metadata)
+ ),
+ 'host/identify_device': this.newTaskMessage(
+ new TaskMessageOperation($localize`Identifying`, $localize`identify`, $localize`Identified`),
+ (metadata) => $localize`device '${metadata.device}' on host '${metadata.hostname}'`
+ ),
+ // OSD tasks
+ 'osd/create': this.newTaskMessage(
+ this.commonOperations.create,
+ (metadata) => $localize`OSDs (DriveGroups: ${metadata.tracking_id})`
+ ),
+ 'osd/delete': this.newTaskMessage(this.commonOperations.delete, (metadata) =>
+ this.osd(metadata)
+ ),
+ // Pool tasks
+ 'pool/create': this.newTaskMessage(
+ this.commonOperations.create,
+ (metadata) => this.pool(metadata),
+ (metadata) => ({
+ '17': $localize`Name is already used by ${this.pool(metadata)}.`
+ })
+ ),
+ 'pool/edit': this.newTaskMessage(
+ this.commonOperations.update,
+ (metadata) => this.pool(metadata),
+ (metadata) => ({
+ '17': $localize`Name is already used by ${this.pool(metadata)}.`
+ })
+ ),
+ 'pool/delete': this.newTaskMessage(this.commonOperations.delete, (metadata) =>
+ this.pool(metadata)
+ ),
+ // Erasure code profile tasks
+ 'ecp/create': this.newTaskMessage(
+ this.commonOperations.create,
+ (metadata) => this.ecp(metadata),
+ (metadata) => ({
+ '17': $localize`Name is already used by ${this.ecp(metadata)}.`
+ })
+ ),
+ 'ecp/delete': this.newTaskMessage(this.commonOperations.delete, (metadata) =>
+ this.ecp(metadata)
+ ),
+ // Crush rule tasks
+ 'crushRule/create': this.newTaskMessage(
+ this.commonOperations.create,
+ (metadata) => this.crushRule(metadata),
+ (metadata) => ({
+ '17': $localize`Name is already used by ${this.crushRule(metadata)}.`
+ })
+ ),
+ 'crushRule/delete': this.newTaskMessage(this.commonOperations.delete, (metadata) =>
+ this.crushRule(metadata)
+ ),
+ // RBD tasks
+ 'rbd/create': this.newTaskMessage(
+ this.commonOperations.create,
+ this.rbd.create,
+ (metadata) => ({
+ '17': $localize`Name is already used by ${this.rbd.create(metadata)}.`
+ })
+ ),
+ 'rbd/edit': this.newTaskMessage(this.commonOperations.update, this.rbd.default, (metadata) => ({
+ '17': $localize`Name is already used by ${this.rbd.default(metadata)}.`
+ })),
+ 'rbd/delete': this.newTaskMessage(
+ this.commonOperations.delete,
+ this.rbd.default,
+ (metadata) => ({
+ '16': $localize`${this.rbd.default(metadata)} is busy.`,
+ '39': $localize`${this.rbd.default(metadata)} contains snapshots.`
+ })
+ ),
+ 'rbd/clone': this.newTaskMessage(
+ new TaskMessageOperation($localize`Cloning`, $localize`clone`, $localize`Cloned`),
+ this.rbd.child,
+ (metadata) => ({
+ '17': $localize`Name is already used by ${this.rbd.child(metadata)}.`,
+ '22': $localize`Snapshot of ${this.rbd.child(metadata)} must be protected.`
+ })
+ ),
+ 'rbd/copy': this.newTaskMessage(
+ new TaskMessageOperation($localize`Copying`, $localize`copy`, $localize`Copied`),
+ this.rbd.destination,
+ (metadata) => ({
+ '17': $localize`Name is already used by ${this.rbd.destination(metadata)}.`
+ })
+ ),
+ 'rbd/flatten': this.newTaskMessage(
+ new TaskMessageOperation($localize`Flattening`, $localize`flatten`, $localize`Flattened`),
+ this.rbd.default
+ ),
+ // RBD snapshot tasks
+ 'rbd/snap/create': this.newTaskMessage(
+ this.commonOperations.create,
+ this.rbd.snapshot,
+ (metadata) => ({
+ '17': $localize`Name is already used by ${this.rbd.snapshot(metadata)}.`
+ })
+ ),
+ 'rbd/snap/edit': this.newTaskMessage(
+ this.commonOperations.update,
+ this.rbd.snapshot,
+ (metadata) => ({
+ '16': $localize`Cannot unprotect ${this.rbd.snapshot(
+ metadata
+ )} because it contains child images.`
+ })
+ ),
+ 'rbd/snap/delete': this.newTaskMessage(
+ this.commonOperations.delete,
+ this.rbd.snapshot,
+ (metadata) => ({
+ '16': $localize`Cannot delete ${this.rbd.snapshot(metadata)} because it's protected.`
+ })
+ ),
+ 'rbd/snap/rollback': this.newTaskMessage(
+ new TaskMessageOperation(
+ $localize`Rolling back`,
+ $localize`rollback`,
+ $localize`Rolled back`
+ ),
+ this.rbd.snapshot
+ ),
+ // RBD trash tasks
+ 'rbd/trash/move': this.newTaskMessage(
+ new TaskMessageOperation($localize`Moving`, $localize`move`, $localize`Moved`),
+ (metadata) => $localize`image '${metadata.image_spec}' to trash`,
+ () => ({
+ 2: $localize`Could not find image.`
+ })
+ ),
+ 'rbd/trash/restore': this.newTaskMessage(
+ new TaskMessageOperation($localize`Restoring`, $localize`restore`, $localize`Restored`),
+ (metadata) => $localize`image '${metadata.image_id_spec}' into '${metadata.new_image_name}'`,
+ (metadata) => ({
+ 17: $localize`Image name '${metadata.new_image_name}' is already in use.`
+ })
+ ),
+ 'rbd/trash/remove': this.newTaskMessage(
+ new TaskMessageOperation($localize`Deleting`, $localize`delete`, $localize`Deleted`),
+ (metadata) => $localize`image '${metadata.image_id_spec}'`
+ ),
+ 'rbd/trash/purge': this.newTaskMessage(
+ new TaskMessageOperation($localize`Purging`, $localize`purge`, $localize`Purged`),
+ (metadata) => {
+ let message = $localize`all pools`;
+ if (metadata.pool_name) {
+ message = `'${metadata.pool_name}'`;
+ }
+ return $localize`images from ${message}`;
+ }
+ ),
+ // RBD mirroring tasks
+ 'rbd/mirroring/site_name/edit': this.newTaskMessage(
+ this.commonOperations.update,
+ this.rbd_mirroring.site_name,
+ () => ({})
+ ),
+ 'rbd/mirroring/bootstrap/create': this.newTaskMessage(
+ this.commonOperations.create,
+ this.rbd_mirroring.bootstrap,
+ () => ({})
+ ),
+ 'rbd/mirroring/bootstrap/import': this.newTaskMessage(
+ this.commonOperations.import,
+ this.rbd_mirroring.bootstrap,
+ () => ({})
+ ),
+ 'rbd/mirroring/pool/edit': this.newTaskMessage(
+ this.commonOperations.update,
+ this.rbd_mirroring.pool,
+ () => ({
+ 16: $localize`Cannot disable mirroring because it contains a peer.`
+ })
+ ),
+ 'rbd/mirroring/peer/add': this.newTaskMessage(
+ this.commonOperations.create,
+ this.rbd_mirroring.pool_peer,
+ () => ({})
+ ),
+ 'rbd/mirroring/peer/edit': this.newTaskMessage(
+ this.commonOperations.update,
+ this.rbd_mirroring.pool_peer,
+ () => ({})
+ ),
+ 'rbd/mirroring/peer/delete': this.newTaskMessage(
+ this.commonOperations.delete,
+ this.rbd_mirroring.pool_peer,
+ () => ({})
+ ),
+ // iSCSI target tasks
+ 'iscsi/target/create': this.newTaskMessage(this.commonOperations.create, (metadata) =>
+ this.iscsiTarget(metadata)
+ ),
+ 'iscsi/target/edit': this.newTaskMessage(this.commonOperations.update, (metadata) =>
+ this.iscsiTarget(metadata)
+ ),
+ 'iscsi/target/delete': this.newTaskMessage(this.commonOperations.delete, (metadata) =>
+ this.iscsiTarget(metadata)
+ ),
+ 'nfs/create': this.newTaskMessage(this.commonOperations.create, (metadata) =>
+ this.nfs(metadata)
+ ),
+ 'nfs/edit': this.newTaskMessage(this.commonOperations.update, (metadata) => this.nfs(metadata)),
+ 'nfs/delete': this.newTaskMessage(this.commonOperations.delete, (metadata) =>
+ this.nfs(metadata)
+ ),
+ // Grafana tasks
+ 'grafana/dashboards/update': this.newTaskMessage(
+ this.commonOperations.update,
+ this.grafana.update_dashboards,
+ () => ({})
+ ),
+ // Service tasks
+ 'service/create': this.newTaskMessage(this.commonOperations.create, (metadata) =>
+ this.service(metadata)
+ ),
+ 'service/edit': this.newTaskMessage(this.commonOperations.update, (metadata) =>
+ this.service(metadata)
+ ),
+ 'service/delete': this.newTaskMessage(this.commonOperations.delete, (metadata) =>
+ this.service(metadata)
+ )
+ };
+
+ newTaskMessage(
+ operation: TaskMessageOperation,
+ involves: (metadata: any) => string,
+ errors?: (metadata: any) => object
+ ) {
+ return new TaskMessage(operation, involves, errors);
+ }
+
+ host(metadata: any) {
+ return $localize`host '${metadata.hostname}'`;
+ }
+
+ osd(metadata: any) {
+ return $localize`OSD '${metadata.svc_id}'`;
+ }
+
+ pool(metadata: any) {
+ return $localize`pool '${metadata.pool_name}'`;
+ }
+
+ ecp(metadata: any) {
+ return $localize`erasure code profile '${metadata.name}'`;
+ }
+
+ crushRule(metadata: any) {
+ return $localize`crush rule '${metadata.name}'`;
+ }
+
+ iscsiTarget(metadata: any) {
+ return $localize`target '${metadata.target_iqn}'`;
+ }
+
+ nfs(metadata: any) {
+ return $localize`NFS '${metadata.cluster_id}\:${
+ metadata.export_id ? metadata.export_id : metadata.path
+ }'`;
+ }
+
+ service(metadata: any) {
+ return $localize`Service '${metadata.service_name}'`;
+ }
+
+ _getTaskTitle(task: Task) {
+ if (task.name && task.name.startsWith('progress/')) {
+ // we don't fill the failure string because, at least for now, all
+ // progress module tasks will be considered successful
+ return this.newTaskMessage(
+ new TaskMessageOperation(
+ task.name.replace('progress/', ''),
+ '',
+ task.name.replace('progress/', '')
+ ),
+ (_metadata) => ''
+ );
+ }
+ return this.messages[task.name] || this.defaultMessage;
+ }
+
+ getSuccessTitle(task: FinishedTask) {
+ return this._getTaskTitle(task).success(task.metadata);
+ }
+
+ getErrorMessage(task: FinishedTask) {
+ return (
+ this._getTaskTitle(task).errors(task.metadata)[task.exception.code] || task.exception.detail
+ );
+ }
+
+ getErrorTitle(task: Task) {
+ return this._getTaskTitle(task).failure(task.metadata);
+ }
+
+ getRunningTitle(task: Task) {
+ return this._getTaskTitle(task).running(task.metadata);
+ }
+
+ getRunningText(task: Task) {
+ return this._getTaskTitle(task).operation.running;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-wrapper.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-wrapper.service.spec.ts
new file mode 100644
index 000000000..e81962211
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-wrapper.service.spec.ts
@@ -0,0 +1,98 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { inject, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastrModule } from 'ngx-toastr';
+import { Observable } from 'rxjs';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { FinishedTask } from '../models/finished-task';
+import { SharedModule } from '../shared.module';
+import { NotificationService } from './notification.service';
+import { SummaryService } from './summary.service';
+import { TaskManagerService } from './task-manager.service';
+import { TaskWrapperService } from './task-wrapper.service';
+
+describe('TaskWrapperService', () => {
+ let service: TaskWrapperService;
+
+ configureTestBed({
+ imports: [HttpClientTestingModule, ToastrModule.forRoot(), SharedModule, RouterTestingModule],
+ providers: [TaskWrapperService]
+ });
+
+ beforeEach(inject([TaskWrapperService], (wrapper: TaskWrapperService) => {
+ service = wrapper;
+ }));
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ describe('wrapTaskAroundCall', () => {
+ let notify: NotificationService;
+ let passed: boolean;
+ let summaryService: SummaryService;
+
+ const fakeCall = (status?: number) =>
+ new Observable((observer) => {
+ if (!status) {
+ observer.error({ error: 'failed' });
+ }
+ observer.next({ status: status });
+ observer.complete();
+ });
+
+ const callWrapTaskAroundCall = (status: number, name: string) => {
+ return service.wrapTaskAroundCall({
+ task: new FinishedTask(name, { sth: 'else' }),
+ call: fakeCall(status)
+ });
+ };
+
+ beforeEach(() => {
+ passed = false;
+ notify = TestBed.inject(NotificationService);
+ summaryService = TestBed.inject(SummaryService);
+ spyOn(notify, 'show');
+ spyOn(notify, 'notifyTask').and.stub();
+ spyOn(service, '_handleExecutingTasks').and.callThrough();
+ spyOn(summaryService, 'addRunningTask').and.callThrough();
+ });
+
+ it('should simulate a synchronous task', () => {
+ callWrapTaskAroundCall(200, 'sync').subscribe({ complete: () => (passed = true) });
+ expect(service._handleExecutingTasks).not.toHaveBeenCalled();
+ expect(passed).toBeTruthy();
+ expect(summaryService.addRunningTask).not.toHaveBeenCalled();
+ });
+
+ it('should simulate a asynchronous task', () => {
+ callWrapTaskAroundCall(202, 'async').subscribe({ complete: () => (passed = true) });
+ expect(service._handleExecutingTasks).toHaveBeenCalled();
+ expect(passed).toBeTruthy();
+ expect(summaryService.addRunningTask).toHaveBeenCalledTimes(1);
+ });
+
+ it('should call notifyTask if asynchronous task would have been finished', () => {
+ const taskManager = TestBed.inject(TaskManagerService);
+ spyOn(taskManager, 'subscribe').and.callFake((_name, _metadata, onTaskFinished) => {
+ onTaskFinished();
+ });
+ callWrapTaskAroundCall(202, 'async').subscribe({ complete: () => (passed = true) });
+ expect(notify.notifyTask).toHaveBeenCalled();
+ });
+
+ it('should simulate a task failure', () => {
+ callWrapTaskAroundCall(null, 'async').subscribe({ error: () => (passed = true) });
+ expect(service._handleExecutingTasks).not.toHaveBeenCalled();
+ expect(passed).toBeTruthy();
+ expect(summaryService.addRunningTask).not.toHaveBeenCalled();
+ /**
+ * A notification will be raised by the API interceptor.
+ * This resolves this bug https://tracker.ceph.com/issues/25139
+ */
+ expect(notify.notifyTask).not.toHaveBeenCalled();
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-wrapper.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-wrapper.service.ts
new file mode 100644
index 000000000..721e1edcd
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-wrapper.service.ts
@@ -0,0 +1,68 @@
+import { Injectable } from '@angular/core';
+
+import { Observable, Subscriber } from 'rxjs';
+
+import { NotificationType } from '../enum/notification-type.enum';
+import { CdNotificationConfig } from '../models/cd-notification';
+import { ExecutingTask } from '../models/executing-task';
+import { FinishedTask } from '../models/finished-task';
+import { NotificationService } from './notification.service';
+import { SummaryService } from './summary.service';
+import { TaskManagerService } from './task-manager.service';
+import { TaskMessageService } from './task-message.service';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class TaskWrapperService {
+ constructor(
+ private notificationService: NotificationService,
+ private summaryService: SummaryService,
+ private taskMessageService: TaskMessageService,
+ private taskManagerService: TaskManagerService
+ ) {}
+
+ wrapTaskAroundCall({ task, call }: { task: FinishedTask; call: Observable<any> }) {
+ return new Observable((observer: Subscriber<any>) => {
+ call.subscribe(
+ (resp) => {
+ if (resp.status === 202) {
+ this._handleExecutingTasks(task);
+ } else {
+ this.summaryService.refresh();
+ task.success = true;
+ this.notificationService.notifyTask(task);
+ }
+ },
+ (resp) => {
+ task.success = false;
+ task.exception = resp.error;
+ observer.error(resp);
+ },
+ () => {
+ observer.complete();
+ }
+ );
+ });
+ }
+
+ _handleExecutingTasks(task: FinishedTask) {
+ const notification = new CdNotificationConfig(
+ NotificationType.info,
+ this.taskMessageService.getRunningTitle(task)
+ );
+ notification.isFinishedTask = true;
+ this.notificationService.show(notification);
+
+ const executingTask = new ExecutingTask(task.name, task.metadata);
+ this.summaryService.addRunningTask(executingTask);
+
+ this.taskManagerService.subscribe(
+ executingTask.name,
+ executingTask.metadata,
+ (asyncTask: FinishedTask) => {
+ this.notificationService.notifyTask(asyncTask);
+ }
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/telemetry-notification.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/telemetry-notification.service.spec.ts
new file mode 100644
index 000000000..ea1f910e1
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/telemetry-notification.service.spec.ts
@@ -0,0 +1,33 @@
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { TelemetryNotificationService } from './telemetry-notification.service';
+
+describe('TelemetryNotificationService', () => {
+ let service: TelemetryNotificationService;
+
+ configureTestBed({
+ providers: [TelemetryNotificationService]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(TelemetryNotificationService);
+ spyOn(service.update, 'emit');
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should set notification visibility to true', () => {
+ service.setVisibility(true);
+ expect(service.visible).toBe(true);
+ expect(service.update.emit).toHaveBeenCalledWith(true);
+ });
+
+ it('should set notification visibility to false', () => {
+ service.setVisibility(false);
+ expect(service.visible).toBe(false);
+ expect(service.update.emit).toHaveBeenCalledWith(false);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/telemetry-notification.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/telemetry-notification.service.ts
new file mode 100644
index 000000000..fcb2e0264
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/telemetry-notification.service.ts
@@ -0,0 +1,16 @@
+import { EventEmitter, Injectable, Output } from '@angular/core';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class TelemetryNotificationService {
+ visible = false;
+
+ @Output()
+ update: EventEmitter<boolean> = new EventEmitter<boolean>();
+
+ setVisibility(visible: boolean) {
+ this.visible = visible;
+ this.update.emit(visible);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/text-to-download.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/text-to-download.service.spec.ts
new file mode 100644
index 000000000..f9ff4d29d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/text-to-download.service.spec.ts
@@ -0,0 +1,20 @@
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { TextToDownloadService } from './text-to-download.service';
+
+describe('TextToDownloadService', () => {
+ let service: TextToDownloadService;
+
+ configureTestBed({
+ providers: [TextToDownloadService]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(TextToDownloadService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/text-to-download.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/text-to-download.service.ts
new file mode 100644
index 000000000..6e63287ea
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/text-to-download.service.ts
@@ -0,0 +1,12 @@
+import { Injectable } from '@angular/core';
+
+import { saveAs } from 'file-saver';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class TextToDownloadService {
+ download(downloadText: string, filename?: string) {
+ saveAs(new Blob([downloadText]), filename);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/time-diff.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/time-diff.service.spec.ts
new file mode 100644
index 000000000..52be82b09
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/time-diff.service.spec.ts
@@ -0,0 +1,71 @@
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { TimeDiffService } from './time-diff.service';
+
+describe('TimeDiffService', () => {
+ let service: TimeDiffService;
+ const baseTime = new Date('2022-02-22T00:00:00');
+
+ configureTestBed({
+ providers: [TimeDiffService]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(TimeDiffService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('calculates a new date that happens after the given date', () => {
+ expect(service.calculateDate(new Date('2022-02-28T04:05:00'), '2h')).toEqual(
+ new Date('2022-02-28T06:05:00')
+ );
+ expect(service.calculateDate(baseTime, '15m')).toEqual(new Date('2022-02-22T00:15'));
+ expect(service.calculateDate(baseTime, '5d 23h')).toEqual(new Date('2022-02-27T23:00'));
+ });
+
+ it('calculates a new date that happens before the given date', () => {
+ expect(service.calculateDate(new Date('2022-02-22T02:00:00'), '2h', true)).toEqual(baseTime);
+ });
+
+ it('calculates the difference of two dates', () => {
+ expect(
+ service.calculateDuration(new Date('2022-02-22T00:45:00'), new Date('2022-02-22T02:00:00'))
+ ).toBe('1h 15m');
+ expect(service.calculateDuration(baseTime, new Date('2022-02-28T04:05:00'))).toBe('6d 4h 5m');
+ });
+
+ it('should return an empty string if time diff is less then a minute', () => {
+ const ts = 1568361327000;
+ expect(service.calculateDuration(new Date(ts), new Date(ts + 120))).toBe('');
+ });
+
+ describe('testing duration calculation in detail', () => {
+ const minutes = 60 * 1000;
+ const hours = 60 * minutes;
+ const days = 24 * hours;
+
+ it('should allow different writings', () => {
+ const expectDurationToBeMs = (duration: string, ms: number) =>
+ expect(service['getDurationMs'](duration)).toBe(ms);
+ expectDurationToBeMs('2h', 2 * hours);
+ expectDurationToBeMs('4 Days', 4 * days);
+ expectDurationToBeMs('3 minutes', 3 * minutes);
+ expectDurationToBeMs('4 Days 2h 3 minutes', 4 * days + 2 * hours + 3 * minutes);
+ expectDurationToBeMs('5d3h120m', 5 * days + 5 * hours);
+ });
+
+ it('should create duration string from ms', () => {
+ const expectMsToBeDuration = (ms: number, duration: string) =>
+ expect(service['getDuration'](ms)).toBe(duration);
+ expectMsToBeDuration(2 * hours, '2h');
+ expectMsToBeDuration(4 * days, '4d');
+ expectMsToBeDuration(3 * minutes, '3m');
+ expectMsToBeDuration(4 * days + 2 * hours + 3 * minutes, '4d 2h 3m');
+ expectMsToBeDuration(service['getDurationMs']('5d3h120m'), '5d 5h');
+ });
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/time-diff.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/time-diff.service.ts
new file mode 100644
index 000000000..37477658c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/time-diff.service.ts
@@ -0,0 +1,55 @@
+import { Injectable } from '@angular/core';
+
+import _ from 'lodash';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class TimeDiffService {
+ calculateDuration(startDate: Date, endDate: Date): string {
+ const startTime = +startDate;
+ const endTime = +endDate;
+ const duration = this.getDuration(Math.abs(startTime - endTime));
+ if (startTime > endTime) {
+ return '-' + duration;
+ }
+ return duration;
+ }
+
+ /**
+ * Get the duration in the format '[Nd] [Nh] [Nm]', e.g. '2d 1h 15m'.
+ * @param ms The time in milliseconds.
+ * @return The duration. An empty string is returned if the duration is
+ * less than a minute.
+ */
+ private getDuration(ms: number): string {
+ const date = new Date(ms);
+ const h = date.getUTCHours();
+ const m = date.getUTCMinutes();
+ const d = Math.floor(ms / (24 * 3600 * 1000));
+
+ const format = (n: number, s: string) => (n ? n + s : n);
+ return [format(d, 'd'), format(h, 'h'), format(m, 'm')].filter((x) => x).join(' ');
+ }
+
+ calculateDate(date: Date, duration: string, reverse?: boolean): Date {
+ const time = +date;
+ if (_.isNaN(time)) {
+ return undefined;
+ }
+ const diff = this.getDurationMs(duration) * (reverse ? -1 : 1);
+ return new Date(time + diff);
+ }
+
+ private getDurationMs(duration: string): number {
+ const d = this.getNumbersFromString(duration, 'd');
+ const h = this.getNumbersFromString(duration, 'h');
+ const m = this.getNumbersFromString(duration, 'm');
+ return ((d * 24 + h) * 60 + m) * 60000;
+ }
+
+ private getNumbersFromString(duration: string, prefix: string): number {
+ const match = duration.match(new RegExp(`[0-9 ]+${prefix}`, 'i'));
+ return match ? parseInt(match[0], 10) : 0;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/timer.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/timer.service.spec.ts
new file mode 100644
index 000000000..10b528e3a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/timer.service.spec.ts
@@ -0,0 +1,68 @@
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+
+import { of, Subscription } from 'rxjs';
+
+import { configureTestBed } from '~/testing/unit-test-helper';
+import { TimerService } from './timer.service';
+
+describe('TimerService', () => {
+ let service: TimerService;
+ let subs: Subscription;
+ let receivedData: any[];
+ const next = () => of(true);
+ const observer = (data: boolean) => {
+ receivedData.push(data);
+ };
+
+ configureTestBed({
+ providers: [TimerService]
+ });
+
+ beforeEach(() => {
+ service = TestBed.inject(TimerService);
+ receivedData = [];
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should not emit any value when no subscribers', fakeAsync(() => {
+ subs = service.get(next).subscribe(observer);
+ tick(service.DEFAULT_REFRESH_INTERVAL);
+ expect(receivedData.length).toEqual(2);
+
+ subs.unsubscribe();
+
+ tick(service.DEFAULT_REFRESH_INTERVAL);
+ expect(receivedData.length).toEqual(2);
+ }));
+
+ it('should emit value with no dueTime and no refresh interval', fakeAsync(() => {
+ subs = service.get(next, null, null).subscribe(observer);
+ tick(service.DEFAULT_REFRESH_INTERVAL);
+ expect(receivedData.length).toEqual(1);
+ expect(receivedData).toEqual([true]);
+
+ subs.unsubscribe();
+ }));
+
+ it('should emit expected values when refresh interval + no dueTime', fakeAsync(() => {
+ subs = service.get(next).subscribe(observer);
+ tick(service.DEFAULT_REFRESH_INTERVAL * 2);
+ expect(receivedData.length).toEqual(3);
+ expect(receivedData).toEqual([true, true, true]);
+
+ subs.unsubscribe();
+ }));
+
+ it('should emit expected values when dueTime equal to refresh interval', fakeAsync(() => {
+ const dueTime = 1000;
+ subs = service.get(next, service.DEFAULT_REFRESH_INTERVAL, dueTime).subscribe(observer);
+ tick(service.DEFAULT_REFRESH_INTERVAL * 2);
+ expect(receivedData.length).toEqual(2);
+ expect(receivedData).toEqual([true, true]);
+
+ subs.unsubscribe();
+ }));
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/timer.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/timer.service.ts
new file mode 100644
index 000000000..716b71096
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/timer.service.ts
@@ -0,0 +1,29 @@
+import { Injectable } from '@angular/core';
+
+import { Observable, timer } from 'rxjs';
+import { observeOn, shareReplay, switchMap } from 'rxjs/operators';
+
+import { whenPageVisible } from '../rxjs/operators/page-visibilty.operator';
+import { NgZoneSchedulerService } from './ngzone-scheduler.service';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class TimerService {
+ readonly DEFAULT_REFRESH_INTERVAL = 5000;
+ readonly DEFAULT_DUE_TIME = 0;
+ constructor(private ngZone: NgZoneSchedulerService) {}
+
+ get(
+ next: () => Observable<any>,
+ refreshInterval: number = this.DEFAULT_REFRESH_INTERVAL,
+ dueTime: number = this.DEFAULT_DUE_TIME
+ ): Observable<any> {
+ return timer(dueTime, refreshInterval, this.ngZone.leave).pipe(
+ observeOn(this.ngZone.enter),
+ switchMap(next),
+ shareReplay({ refCount: true, bufferSize: 1 }),
+ whenPageVisible()
+ );
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/url-builder.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/url-builder.service.spec.ts
new file mode 100644
index 000000000..bc8b54ca3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/url-builder.service.spec.ts
@@ -0,0 +1,37 @@
+import { URLVerbs } from '../constants/app.constants';
+import { URLBuilderService } from './url-builder.service';
+
+describe('URLBuilderService', () => {
+ const BASE = 'pool';
+ const urlBuilder = new URLBuilderService(BASE);
+
+ it('get base', () => {
+ expect(urlBuilder.base).toBe(BASE);
+ });
+
+ it('build absolute URL', () => {
+ expect(URLBuilderService.buildURL(true, urlBuilder.base, URLVerbs.CREATE)).toBe(
+ `/${urlBuilder.base}/${URLVerbs.CREATE}`
+ );
+ });
+
+ it('build relative URL', () => {
+ expect(URLBuilderService.buildURL(false, urlBuilder.base, URLVerbs.CREATE)).toBe(
+ `${urlBuilder.base}/${URLVerbs.CREATE}`
+ );
+ });
+
+ it('get Create URL', () => {
+ expect(urlBuilder.getCreate()).toBe(`/${urlBuilder.base}/${URLVerbs.CREATE}`);
+ });
+
+ it('get Create From URL', () => {
+ const id = 'someId';
+ expect(urlBuilder.getCreateFrom(id)).toBe(`/${urlBuilder.base}/${URLVerbs.CREATE}/${id}`);
+ });
+
+ it('get Edit URL with item', () => {
+ const item = 'test_pool';
+ expect(urlBuilder.getEdit(item)).toBe(`/${urlBuilder.base}/${URLVerbs.EDIT}/${item}`);
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/url-builder.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/url-builder.service.ts
new file mode 100644
index 000000000..b06f307ad
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/url-builder.service.ts
@@ -0,0 +1,50 @@
+import { Location } from '@angular/common';
+
+import { URLVerbs } from '../constants/app.constants';
+
+export class URLBuilderService {
+ constructor(readonly base: string) {}
+
+ private static concatURLSegments(segments: string[]): string {
+ return segments.reduce(Location.joinWithSlash);
+ }
+
+ static buildURL(absolute: boolean, ...segments: string[]): string {
+ return URLBuilderService.concatURLSegments([...(absolute ? ['/'] : []), ...segments]);
+ }
+
+ private getURL(verb: URLVerbs, absolute = true, ...segments: string[]): string {
+ return URLBuilderService.buildURL(absolute, this.base, verb, ...segments);
+ }
+
+ getCreate(absolute = true): string {
+ return this.getURL(URLVerbs.CREATE, absolute);
+ }
+
+ getCreateFrom(item: string, absolute = true): string {
+ return this.getURL(URLVerbs.CREATE, absolute, item);
+ }
+
+ getDelete(absolute = true): string {
+ return this.getURL(URLVerbs.DELETE, absolute);
+ }
+
+ getEdit(item: string, absolute = true): string {
+ return this.getURL(URLVerbs.EDIT, absolute, item);
+ }
+ getUpdate(item: string, absolute = true): string {
+ return this.getURL(URLVerbs.UPDATE, absolute, item);
+ }
+
+ getAdd(absolute = true): string {
+ return this.getURL(URLVerbs.ADD, absolute);
+ }
+ getRemove(absolute = true): string {
+ return this.getURL(URLVerbs.REMOVE, absolute);
+ }
+
+ // Prometheus wording
+ getRecreate(item: string, absolute = true): string {
+ return this.getURL(URLVerbs.RECREATE, absolute, item);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/wizard-steps.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/wizard-steps.service.spec.ts
new file mode 100644
index 000000000..47c214975
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/wizard-steps.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { WizardStepsService } from './wizard-steps.service';
+
+describe('WizardStepsService', () => {
+ let service: WizardStepsService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(WizardStepsService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/wizard-steps.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/wizard-steps.service.ts
new file mode 100644
index 000000000..e0fb2be94
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/wizard-steps.service.ts
@@ -0,0 +1,58 @@
+import { Injectable } from '@angular/core';
+
+import { BehaviorSubject, Observable } from 'rxjs';
+
+import { WizardStepModel } from '~/app/shared/models/wizard-steps';
+
+const initialStep = [{ stepIndex: 1, isComplete: false }];
+
+@Injectable({
+ providedIn: 'root'
+})
+export class WizardStepsService {
+ steps$: BehaviorSubject<WizardStepModel[]>;
+ currentStep$: BehaviorSubject<WizardStepModel> = new BehaviorSubject<WizardStepModel>(null);
+
+ constructor() {
+ this.steps$ = new BehaviorSubject<WizardStepModel[]>(initialStep);
+ this.currentStep$.next(this.steps$.value[0]);
+ }
+
+ setTotalSteps(step: number) {
+ const steps: WizardStepModel[] = [];
+ for (let i = 1; i <= step; i++) {
+ steps.push({ stepIndex: i, isComplete: false });
+ }
+ this.steps$ = new BehaviorSubject<WizardStepModel[]>(steps);
+ }
+
+ setCurrentStep(step: WizardStepModel): void {
+ this.currentStep$.next(step);
+ }
+
+ getCurrentStep(): Observable<WizardStepModel> {
+ return this.currentStep$.asObservable();
+ }
+
+ getSteps(): Observable<WizardStepModel[]> {
+ return this.steps$.asObservable();
+ }
+
+ moveToNextStep(): void {
+ const index = this.currentStep$.value.stepIndex;
+ this.currentStep$.next(this.steps$.value[index]);
+ }
+
+ moveToPreviousStep(): void {
+ const index = this.currentStep$.value.stepIndex - 1;
+ this.currentStep$.next(this.steps$.value[index - 1]);
+ }
+
+ isLastStep(): boolean {
+ return this.currentStep$.value.stepIndex === this.steps$.value.length;
+ }
+
+ isFirstStep(): boolean {
+ return this.currentStep$.value?.stepIndex - 1 === 0;
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/shared.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/shared.module.ts
new file mode 100644
index 000000000..905721fa4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/shared.module.ts
@@ -0,0 +1,19 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+
+import { CssHelper } from '~/app/shared/classes/css-helper';
+import { ComponentsModule } from './components/components.module';
+import { DataTableModule } from './datatable/datatable.module';
+import { DirectivesModule } from './directives/directives.module';
+import { PipesModule } from './pipes/pipes.module';
+import { AuthGuardService } from './services/auth-guard.service';
+import { AuthStorageService } from './services/auth-storage.service';
+import { FormatterService } from './services/formatter.service';
+
+@NgModule({
+ imports: [CommonModule, PipesModule, ComponentsModule, DataTableModule, DirectivesModule],
+ declarations: [],
+ exports: [ComponentsModule, PipesModule, DataTableModule, DirectivesModule],
+ providers: [AuthStorageService, AuthGuardService, FormatterService, CssHelper]
+})
+export class SharedModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/assets/.gitkeep b/src/pybind/mgr/dashboard/frontend/src/assets/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/assets/.gitkeep
diff --git a/src/pybind/mgr/dashboard/frontend/src/assets/Ceph_Ceph_Logo_with_text_red_white.svg b/src/pybind/mgr/dashboard/frontend/src/assets/Ceph_Ceph_Logo_with_text_red_white.svg
new file mode 100644
index 000000000..a5b0602eb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/assets/Ceph_Ceph_Logo_with_text_red_white.svg
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="Ceph_Ceph_Logo_red_white.svg"
+ inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
+ xml:space="preserve"
+ id="svg3023"
+ height="84.821152"
+ width="309.90601"
+ version="1.1"><sodipodi:namedview
+ inkscape:window-maximized="1"
+ inkscape:window-y="1080"
+ inkscape:window-x="3840"
+ inkscape:snap-grids="true"
+ inkscape:document-rotation="0"
+ inkscape:current-layer="svg3023"
+ inkscape:cy="40.664131"
+ inkscape:cx="174.44199"
+ inkscape:zoom="4"
+ fit-margin-bottom="0"
+ fit-margin-right="0"
+ fit-margin-left="0"
+ fit-margin-top="0"
+ showgrid="true"
+ id="namedview18"
+ inkscape:window-height="1051"
+ inkscape:window-width="1920"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0"
+ guidetolerance="10"
+ gridtolerance="10"
+ objecttolerance="10"
+ borderopacity="1"
+ bordercolor="#666666"
+ pagecolor="#000000"><inkscape:grid
+ id="grid12"
+ type="xygrid" /></sodipodi:namedview><metadata
+ id="metadata3029"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3027" /><g
+ transform="matrix(1.2645281,0,0,1.2645281,-331.87054,-100.71194)"
+ id="g7238"><path
+ inkscape:connector-curvature="0"
+ d="m 381.9911,121.40232 c 0,8.86025 -0.7935,11.31 -2.92775,13.4477 -1.26475,1.26514 -3.24375,2.13379 -6.963,2.13379 l -13.05023,0 c -4.19238,0 -6.72071,-0.7124 -8.46338,-2.45019 -2.76562,-2.77005 -3.55664,-6.0923 -3.55664,-18.9038 0,-12.8135 0.79102,-16.137245 3.55664,-18.90387 1.74267,-1.73975 4.271,-2.449625 8.46338,-2.449625 l 12.97361,0 c 3.87262,0 5.61237,0.787625 6.95799,2.13475 2.05525,2.055125 2.84863,4.902875 2.84863,12.888625 l -7.98725,0 c -0.16013,-5.53612 -0.47562,-6.48338 -0.95162,-6.9585 -0.47563,-0.47363 -1.10701,-0.71138 -2.92588,-0.71138 l -9.88712,0 c -2.45073,0 -3.08353,0.23775 -3.63627,0.7915 -0.79101,0.78863 -1.1875,2.2925 -1.1875,13.2085 0,10.91263 0.39649,12.4165 1.1875,13.2075 0.55274,0.55375 1.18554,0.7915 3.63627,0.7915 l 9.96437,0 c 1.74162,0 2.53563,-0.15775 3.08537,-0.71137 0.55475,-0.55525 0.87213,-2.13775 0.87213,-7.51513 l 7.99075,0"
+ id="path3049-5"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
+ inkscape:connector-curvature="0"
+ d="m 395.91147,111.75232 19.45601,0 c 0,-7.19625 -0.476,-8.77875 -1.18363,-9.49112 -0.478,-0.47363 -1.1875,-0.78863 -3.63763,-0.78863 l -9.81099,0 c -2.45076,0 -3.08351,0.23738 -3.71738,0.86863 -0.71238,0.71387 -1.02537,2.13387 -1.10638,9.41112 z m 0,6.5665 c 0.081,8.38225 0.55225,10.04338 1.1875,10.67625 0.63376,0.63375 1.1855,0.7925 3.63626,0.7925 l 11.07324,0 c 1.82076,0 2.37538,-0.3165 2.851,-0.7925 0.54988,-0.55375 0.70801,-1.5025 0.87013,-5.29887 l 7.98537,0 c -0.15724,6.64262 -0.791,9.01612 -2.92775,11.15382 -1.34325,1.34473 -3.16212,2.13379 -6.95799,2.13379 l -13.84088,0 c -4.19287,0 -6.72363,-0.7124 -8.46388,-2.45019 -2.77049,-2.77005 -3.55662,-6.0923 -3.55662,-18.9038 0,-12.8135 0.78613,-16.137245 3.55662,-18.90387 1.74025,-1.73975 4.27101,-2.449625 8.46388,-2.449625 l 11.70462,0 c 4.19438,0 6.88138,0.787625 8.46588,2.370125 2.76512,2.7685 3.55612,6.09225 3.55612,18.58838 l 0,2.13525 c 0,0.62987 -0.23637,0.94875 -0.95075,0.94875 l -26.65275,0"
+ id="path3051-2"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
+ inkscape:connector-curvature="0"
+ d="m 455.71123,128.68007 c -0.71038,0.711 -1.74313,1.02738 -4.34813,1.02738 l -6.17338,0 c -2.53174,0 -4.73137,-0.71388 -7.75137,-2.25 -0.18412,-0.0937 -0.35987,-0.18113 -0.55275,-0.27875 l 0,-23.25637 c 3.165,-1.58113 5.37838,-2.37113 7.99075,-2.37113 l 6.48675,0 c 2.605,0 3.63775,0.31637 4.34813,1.02738 1.18512,1.185 1.50249,3.47749 1.50249,13.05124 0,9.57275 -0.31737,11.86275 -1.50249,13.05025 z m -2.37688,-34.487745 -5.76913,0 c -3.562,0 -5.30124,0.793875 -10.67962,5.222625 l 0,-5.138625 -8.22463,0 0,52.149875 c 2.96238,0 8.22463,0 8.22463,0 l 0,-14.5025 c 5.37838,4.34771 7.11762,5.13872 10.67962,5.13872 l 5.76913,0 c 4.59225,0 6.88475,-0.79101 8.7035,-2.60741 2.29162,-2.29494 3.401,-5.53756 3.401,-18.82518 0,-13.28863 -1.10938,-16.533755 -3.401,-18.824755 -1.81875,-1.818875 -4.11125,-2.61275 -8.7035,-2.61275"
+ id="path3053-7"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
+ inkscape:connector-curvature="0"
+ d="m 504.98885,96.64645 c -1.5825,-1.5825 -3.6375,-2.454125 -7.35625,-2.454125 l -6.72125,0 c -3.56,0 -5.29875,0.793875 -10.68,5.222625 l 0,-16.27875 c -2.5525,-1.401375 -5.2175,-2.42875 -8.16625,-3.061125 -0.0212,0.001 -0.037,0.01375 -0.0589,0.021 l 0,56.887735 8.22512,0 0,-33.06148 c 0.6025,-0.30126 1.165,-0.56351 1.7075,-0.80713 2.30875,-1.03662 4.16875,-1.564 6.28125,-1.564 l 5.5375,0 c 2.7675,0 3.55875,0.31638 4.42875,1.1875 0.79125,0.79 1.10625,2.05375 1.10625,4.11138 l 0,30.13373 8.23,0 0,-30.68749 c 0,-5.93262 -0.8725,-7.988745 -2.53375,-9.64987"
+ id="path3055-0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><path
+ inkscape:connector-curvature="0"
+ id="path3043-5"
+ d="M 43.19186,0 C 37.36219,0 31.70629,1.141324 26.37804,3.39468 21.23468,5.571233 16.61428,8.684145 12.65087,12.650872 8.68303,16.615226 5.56986,21.235109 3.3922,26.376813 1.13908,31.706162 0,37.366518 0,43.193098 c 0,3.32935 0.37705,6.64748 1.13073,9.86362 0.73215,3.12905 1.81822,6.1817 3.22891,9.07187 2.60102,5.32555 6.81748,10.63499 11.58571,14.60924 3.1098,-1.70006 4.87424,-3.57439 5.24913,-5.57944 0.3612,-1.9259 -0.48432,-4.0003 -2.6623,-6.52213 -5.16814,-5.92976 -8.01412,-13.54295 -8.01412,-21.44316 0,-18.015755 14.65559,-32.676271 32.6738,-32.676271 0.0308,0 0.14845,0.0025 0.14845,0.0025 0,0 0.11535,-0.0025 0.14475,-0.0025 18.01758,0 32.67503,14.660516 32.67503,32.676271 0,7.90021 -2.84531,15.51346 -8.01164,21.44067 -2.16191,2.50521 -3.02941,4.66768 -2.65365,6.61121 0.38972,2.0072 2.15042,3.8552 5.23306,5.49533 4.77471,-3.9752 8.98849,-9.28404 11.58942,-14.61172 1.41251,-2.89017 2.49856,-5.94282 3.23014,-9.07187 0.75139,-3.21614 1.13321,-6.53427 1.13321,-9.86362 0,-5.82658 -1.14257,-11.486936 -3.39592,-16.816285 C 81.10817,21.235109 77.99288,16.615226 74.02852,12.650872 70.06329,8.684145 65.44312,5.571233 60.30133,3.39468 54.9724,1.141324 49.31472,0 43.48506,0 L 43.3366,0 43.19186,0 Z m -0.0161,17.469488 c -1.2167,0 -2.43464,0.0826 -3.62355,0.253612 -3.51067,0.500394 -6.95483,1.753604 -9.96012,3.628497 -2.86856,1.78859 -5.42084,4.190352 -7.37823,6.946476 -2.02335,2.84876 -3.47542,6.160065 -4.19387,9.574135 -0.78068,3.70308 -0.73174,7.60532 0.14227,11.28385 0.80411,3.3832 2.32825,6.64075 4.40789,9.41825 0.55734,0.74822 1.18117,1.43073 1.83961,2.15385 0.21932,0.23815 0.44287,0.48311 0.66805,0.73362 0.006,0.008 0.0128,0.0119 0.0172,0.0185 0.0263,0.0266 0.0614,0.0596 0.0953,0.10018 2.29215,2.66356 3.4553,5.53278 3.4553,8.52381 0,4.52017 -2.51013,8.66702 -6.45904,10.79148 2.29705,1.27489 4.71435,2.33969 7.19637,3.17199 0.82454,0.27617 1.66303,0.52855 2.50394,0.75341 0.50254,-0.31575 2.21572,-1.59095 3.89078,-3.90686 1.60181,-2.21297 3.48965,-5.88375 3.38973,-10.80013 -0.0587,-2.95889 -0.65446,-5.84073 -1.76538,-8.56091 -1.10357,-2.69684 -2.68426,-5.16818 -4.70357,-7.34236 l -0.009,-0.0161 c -0.15122,-0.17261 -0.29697,-0.34443 -0.4466,-0.51466 -0.76111,-0.88281 -1.54703,-1.79373 -2.17735,-2.86024 -0.77165,-1.31115 -1.33423,-2.68927 -1.66765,-4.0986 -0.51868,-2.17655 -0.54614,-4.48642 -0.0865,-6.67801 0.42898,-2.01504 1.28202,-3.96792 2.47797,-5.65121 1.15796,-1.631028 2.66974,-3.054071 4.3683,-4.113449 1.77252,-1.106091 3.8069,-1.84649 5.8776,-2.140233 0.69928,-0.100552 1.42303,-0.152167 2.14766,-0.152167 l 0.15463,0 0.15588,0 c 0.72613,0 1.44862,0.05161 2.15013,0.152167 2.07189,0.293743 4.10574,1.034142 5.87636,2.140233 1.69888,1.059378 3.20816,2.482421 4.36706,4.113449 1.19628,1.68329 2.05272,3.63617 2.47797,5.65121 0.46088,2.19159 0.43084,4.50146 -0.0841,6.67801 -0.33469,1.40933 -0.8969,2.78745 -1.67012,4.0986 -0.62716,1.06651 -1.41399,1.97743 -2.17488,2.86024 -0.14996,0.17023 -0.29692,0.34205 -0.44537,0.51466 l -0.0124,0.0161 c -2.01591,2.17418 -3.59885,4.64552 -4.70232,7.34236 -1.11164,2.72018 -1.7048,5.60202 -1.76662,8.56091 -0.0986,4.91638 1.78857,8.58716 3.39221,10.80013 1.67165,2.31591 3.38632,3.59111 3.88828,3.90686 0.84031,-0.22486 1.68344,-0.47724 2.50767,-0.75341 2.48201,-0.8323 4.89961,-1.8971 7.19761,-3.17199 -3.95326,-2.12446 -6.46275,-6.27131 -6.46275,-10.79148 0,-2.9505 1.12948,-5.73844 3.45282,-8.51886 0.0319,-0.0442 0.0689,-0.0786 0.0953,-0.10512 0.008,-0.007 0.0133,-0.0127 0.021,-0.0185 0.22574,-0.25051 0.44787,-0.49547 0.66435,-0.73362 0.66096,-0.72312 1.28257,-1.40563 1.84085,-2.15385 2.08241,-2.7775 3.6041,-6.03505 4.41035,-9.41825 0.87158,-3.67853 0.92134,-7.58077 0.1435,-11.28384 -0.72129,-3.41408 -2.17301,-6.725384 -4.1951,-9.574144 C 62.50747,25.54196 59.95551,23.140198 57.08696,21.351608 54.08135,19.476714 50.63753,18.223505 47.12559,17.723112 45.93826,17.552091 44.71783,17.4695 43.50081,17.4695 l -0.15464,0 -0.17074,0 z m 0.16206,17.60557 c -4.70109,0 -8.52752,3.8257 -8.52752,8.52877 0,4.70227 3.82643,8.52752 8.52752,8.52752 4.70108,0 8.52629,-3.82525 8.52629,-8.52752 0,-4.70307 -3.82521,-8.52877 -8.52629,-8.52877 z"
+ style="fill:#f0424d;fill-opacity:1;fill-rule:nonzero;stroke:none" /></svg>
diff --git a/src/pybind/mgr/dashboard/frontend/src/assets/Ceph_Ceph_Logo_with_text_white.svg b/src/pybind/mgr/dashboard/frontend/src/assets/Ceph_Ceph_Logo_with_text_white.svg
new file mode 100644
index 000000000..35bcc8c0a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/assets/Ceph_Ceph_Logo_with_text_white.svg
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="Ceph_Ceph_Logo_white.svg"
+ inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
+ xml:space="preserve"
+ id="svg3023"
+ height="84.821152"
+ width="309.90601"
+ version="1.1"><sodipodi:namedview
+ inkscape:window-maximized="1"
+ inkscape:window-y="1080"
+ inkscape:window-x="3840"
+ inkscape:snap-grids="true"
+ inkscape:document-rotation="0"
+ inkscape:current-layer="svg3023"
+ inkscape:cy="40.664131"
+ inkscape:cx="174.44199"
+ inkscape:zoom="4"
+ fit-margin-bottom="0"
+ fit-margin-right="0"
+ fit-margin-left="0"
+ fit-margin-top="0"
+ showgrid="true"
+ id="namedview18"
+ inkscape:window-height="1051"
+ inkscape:window-width="1920"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0"
+ guidetolerance="10"
+ gridtolerance="10"
+ objecttolerance="10"
+ borderopacity="1"
+ bordercolor="#666666"
+ pagecolor="#000000"><inkscape:grid
+ id="grid12"
+ type="xygrid" /></sodipodi:namedview><metadata
+ id="metadata3029"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3027" /><g
+ transform="matrix(1.2645281,0,0,1.2645281,-331.87054,-100.71194)"
+ id="g7238"><path
+ inkscape:connector-curvature="0"
+ d="m 381.9911,121.40232 c 0,8.86025 -0.7935,11.31 -2.92775,13.4477 -1.26475,1.26514 -3.24375,2.13379 -6.963,2.13379 l -13.05023,0 c -4.19238,0 -6.72071,-0.7124 -8.46338,-2.45019 -2.76562,-2.77005 -3.55664,-6.0923 -3.55664,-18.9038 0,-12.8135 0.79102,-16.137245 3.55664,-18.90387 1.74267,-1.73975 4.271,-2.449625 8.46338,-2.449625 l 12.97361,0 c 3.87262,0 5.61237,0.787625 6.95799,2.13475 2.05525,2.055125 2.84863,4.902875 2.84863,12.888625 l -7.98725,0 c -0.16013,-5.53612 -0.47562,-6.48338 -0.95162,-6.9585 -0.47563,-0.47363 -1.10701,-0.71138 -2.92588,-0.71138 l -9.88712,0 c -2.45073,0 -3.08353,0.23775 -3.63627,0.7915 -0.79101,0.78863 -1.1875,2.2925 -1.1875,13.2085 0,10.91263 0.39649,12.4165 1.1875,13.2075 0.55274,0.55375 1.18554,0.7915 3.63627,0.7915 l 9.96437,0 c 1.74162,0 2.53563,-0.15775 3.08537,-0.71137 0.55475,-0.55525 0.87213,-2.13775 0.87213,-7.51513 l 7.99075,0"
+ id="path3049-5"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
+ inkscape:connector-curvature="0"
+ d="m 395.91147,111.75232 19.45601,0 c 0,-7.19625 -0.476,-8.77875 -1.18363,-9.49112 -0.478,-0.47363 -1.1875,-0.78863 -3.63763,-0.78863 l -9.81099,0 c -2.45076,0 -3.08351,0.23738 -3.71738,0.86863 -0.71238,0.71387 -1.02537,2.13387 -1.10638,9.41112 z m 0,6.5665 c 0.081,8.38225 0.55225,10.04338 1.1875,10.67625 0.63376,0.63375 1.1855,0.7925 3.63626,0.7925 l 11.07324,0 c 1.82076,0 2.37538,-0.3165 2.851,-0.7925 0.54988,-0.55375 0.70801,-1.5025 0.87013,-5.29887 l 7.98537,0 c -0.15724,6.64262 -0.791,9.01612 -2.92775,11.15382 -1.34325,1.34473 -3.16212,2.13379 -6.95799,2.13379 l -13.84088,0 c -4.19287,0 -6.72363,-0.7124 -8.46388,-2.45019 -2.77049,-2.77005 -3.55662,-6.0923 -3.55662,-18.9038 0,-12.8135 0.78613,-16.137245 3.55662,-18.90387 1.74025,-1.73975 4.27101,-2.449625 8.46388,-2.449625 l 11.70462,0 c 4.19438,0 6.88138,0.787625 8.46588,2.370125 2.76512,2.7685 3.55612,6.09225 3.55612,18.58838 l 0,2.13525 c 0,0.62987 -0.23637,0.94875 -0.95075,0.94875 l -26.65275,0"
+ id="path3051-2"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
+ inkscape:connector-curvature="0"
+ d="m 455.71123,128.68007 c -0.71038,0.711 -1.74313,1.02738 -4.34813,1.02738 l -6.17338,0 c -2.53174,0 -4.73137,-0.71388 -7.75137,-2.25 -0.18412,-0.0937 -0.35987,-0.18113 -0.55275,-0.27875 l 0,-23.25637 c 3.165,-1.58113 5.37838,-2.37113 7.99075,-2.37113 l 6.48675,0 c 2.605,0 3.63775,0.31637 4.34813,1.02738 1.18512,1.185 1.50249,3.47749 1.50249,13.05124 0,9.57275 -0.31737,11.86275 -1.50249,13.05025 z m -2.37688,-34.487745 -5.76913,0 c -3.562,0 -5.30124,0.793875 -10.67962,5.222625 l 0,-5.138625 -8.22463,0 0,52.149875 c 2.96238,0 8.22463,0 8.22463,0 l 0,-14.5025 c 5.37838,4.34771 7.11762,5.13872 10.67962,5.13872 l 5.76913,0 c 4.59225,0 6.88475,-0.79101 8.7035,-2.60741 2.29162,-2.29494 3.401,-5.53756 3.401,-18.82518 0,-13.28863 -1.10938,-16.533755 -3.401,-18.824755 -1.81875,-1.818875 -4.11125,-2.61275 -8.7035,-2.61275"
+ id="path3053-7"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
+ inkscape:connector-curvature="0"
+ d="m 504.98885,96.64645 c -1.5825,-1.5825 -3.6375,-2.454125 -7.35625,-2.454125 l -6.72125,0 c -3.56,0 -5.29875,0.793875 -10.68,5.222625 l 0,-16.27875 c -2.5525,-1.401375 -5.2175,-2.42875 -8.16625,-3.061125 -0.0212,0.001 -0.037,0.01375 -0.0589,0.021 l 0,56.887735 8.22512,0 0,-33.06148 c 0.6025,-0.30126 1.165,-0.56351 1.7075,-0.80713 2.30875,-1.03662 4.16875,-1.564 6.28125,-1.564 l 5.5375,0 c 2.7675,0 3.55875,0.31638 4.42875,1.1875 0.79125,0.79 1.10625,2.05375 1.10625,4.11138 l 0,30.13373 8.23,0 0,-30.68749 c 0,-5.93262 -0.8725,-7.988745 -2.53375,-9.64987"
+ id="path3055-0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><path
+ inkscape:connector-curvature="0"
+ id="path3043-5"
+ d="M 43.19186,0 C 37.36219,0 31.70629,1.141324 26.37804,3.39468 21.23468,5.571233 16.61428,8.684145 12.65087,12.650872 8.68303,16.615226 5.56986,21.235109 3.3922,26.376813 1.13908,31.706162 0,37.366518 0,43.193098 c 0,3.32935 0.37705,6.64748 1.13073,9.86362 0.73215,3.12905 1.81822,6.1817 3.22891,9.07187 2.60102,5.32555 6.81748,10.63499 11.58571,14.60924 3.1098,-1.70006 4.87424,-3.57439 5.24913,-5.57944 0.3612,-1.9259 -0.48432,-4.0003 -2.6623,-6.52213 -5.16814,-5.92976 -8.01412,-13.54295 -8.01412,-21.44316 0,-18.015755 14.65559,-32.676271 32.6738,-32.676271 0.0308,0 0.14845,0.0025 0.14845,0.0025 0,0 0.11535,-0.0025 0.14475,-0.0025 18.01758,0 32.67503,14.660516 32.67503,32.676271 0,7.90021 -2.84531,15.51346 -8.01164,21.44067 -2.16191,2.50521 -3.02941,4.66768 -2.65365,6.61121 0.38972,2.0072 2.15042,3.8552 5.23306,5.49533 4.77471,-3.9752 8.98849,-9.28404 11.58942,-14.61172 1.41251,-2.89017 2.49856,-5.94282 3.23014,-9.07187 0.75139,-3.21614 1.13321,-6.53427 1.13321,-9.86362 0,-5.82658 -1.14257,-11.486936 -3.39592,-16.816285 C 81.10817,21.235109 77.99288,16.615226 74.02852,12.650872 70.06329,8.684145 65.44312,5.571233 60.30133,3.39468 54.9724,1.141324 49.31472,0 43.48506,0 L 43.3366,0 43.19186,0 Z m -0.0161,17.469488 c -1.2167,0 -2.43464,0.0826 -3.62355,0.253612 -3.51067,0.500394 -6.95483,1.753604 -9.96012,3.628497 -2.86856,1.78859 -5.42084,4.190352 -7.37823,6.946476 -2.02335,2.84876 -3.47542,6.160065 -4.19387,9.574135 -0.78068,3.70308 -0.73174,7.60532 0.14227,11.28385 0.80411,3.3832 2.32825,6.64075 4.40789,9.41825 0.55734,0.74822 1.18117,1.43073 1.83961,2.15385 0.21932,0.23815 0.44287,0.48311 0.66805,0.73362 0.006,0.008 0.0128,0.0119 0.0172,0.0185 0.0263,0.0266 0.0614,0.0596 0.0953,0.10018 2.29215,2.66356 3.4553,5.53278 3.4553,8.52381 0,4.52017 -2.51013,8.66702 -6.45904,10.79148 2.29705,1.27489 4.71435,2.33969 7.19637,3.17199 0.82454,0.27617 1.66303,0.52855 2.50394,0.75341 0.50254,-0.31575 2.21572,-1.59095 3.89078,-3.90686 1.60181,-2.21297 3.48965,-5.88375 3.38973,-10.80013 -0.0587,-2.95889 -0.65446,-5.84073 -1.76538,-8.56091 -1.10357,-2.69684 -2.68426,-5.16818 -4.70357,-7.34236 l -0.009,-0.0161 c -0.15122,-0.17261 -0.29697,-0.34443 -0.4466,-0.51466 -0.76111,-0.88281 -1.54703,-1.79373 -2.17735,-2.86024 -0.77165,-1.31115 -1.33423,-2.68927 -1.66765,-4.0986 -0.51868,-2.17655 -0.54614,-4.48642 -0.0865,-6.67801 0.42898,-2.01504 1.28202,-3.96792 2.47797,-5.65121 1.15796,-1.631028 2.66974,-3.054071 4.3683,-4.113449 1.77252,-1.106091 3.8069,-1.84649 5.8776,-2.140233 0.69928,-0.100552 1.42303,-0.152167 2.14766,-0.152167 l 0.15463,0 0.15588,0 c 0.72613,0 1.44862,0.05161 2.15013,0.152167 2.07189,0.293743 4.10574,1.034142 5.87636,2.140233 1.69888,1.059378 3.20816,2.482421 4.36706,4.113449 1.19628,1.68329 2.05272,3.63617 2.47797,5.65121 0.46088,2.19159 0.43084,4.50146 -0.0841,6.67801 -0.33469,1.40933 -0.8969,2.78745 -1.67012,4.0986 -0.62716,1.06651 -1.41399,1.97743 -2.17488,2.86024 -0.14996,0.17023 -0.29692,0.34205 -0.44537,0.51466 l -0.0124,0.0161 c -2.01591,2.17418 -3.59885,4.64552 -4.70232,7.34236 -1.11164,2.72018 -1.7048,5.60202 -1.76662,8.56091 -0.0986,4.91638 1.78857,8.58716 3.39221,10.80013 1.67165,2.31591 3.38632,3.59111 3.88828,3.90686 0.84031,-0.22486 1.68344,-0.47724 2.50767,-0.75341 2.48201,-0.8323 4.89961,-1.8971 7.19761,-3.17199 -3.95326,-2.12446 -6.46275,-6.27131 -6.46275,-10.79148 0,-2.9505 1.12948,-5.73844 3.45282,-8.51886 0.0319,-0.0442 0.0689,-0.0786 0.0953,-0.10512 0.008,-0.007 0.0133,-0.0127 0.021,-0.0185 0.22574,-0.25051 0.44787,-0.49547 0.66435,-0.73362 0.66096,-0.72312 1.28257,-1.40563 1.84085,-2.15385 2.08241,-2.7775 3.6041,-6.03505 4.41035,-9.41825 0.87158,-3.67853 0.92134,-7.58077 0.1435,-11.28384 -0.72129,-3.41408 -2.17301,-6.725384 -4.1951,-9.574144 C 62.50747,25.54196 59.95551,23.140198 57.08696,21.351608 54.08135,19.476714 50.63753,18.223505 47.12559,17.723112 45.93826,17.552091 44.71783,17.4695 43.50081,17.4695 l -0.15464,0 -0.17074,0 z m 0.16206,17.60557 c -4.70109,0 -8.52752,3.8257 -8.52752,8.52877 0,4.70227 3.82643,8.52752 8.52752,8.52752 4.70108,0 8.52629,-3.82525 8.52629,-8.52752 0,-4.70307 -3.82521,-8.52877 -8.52629,-8.52877 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /></svg>
diff --git a/src/pybind/mgr/dashboard/frontend/src/assets/Ceph_Logo.svg b/src/pybind/mgr/dashboard/frontend/src/assets/Ceph_Logo.svg
new file mode 100644
index 000000000..9426c300d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/assets/Ceph_Logo.svg
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="Ceph_Logo.svg"
+ inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
+ id="svg27"
+ version="1.1"
+ viewBox="0 0 22.93428 22.4424"
+ height="22.4424mm"
+ width="22.93428mm">
+ <defs
+ id="defs21">
+ <color-profile
+ xlink:href="file:///usr/share/color/icc/krita/sRGB-elle-V2-g10.icc"
+ name="sRGB-elle-V2-g10.icc"
+ id="color-profile35" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-maximized="1"
+ inkscape:window-y="1080"
+ inkscape:window-x="3840"
+ inkscape:window-height="1051"
+ inkscape:window-width="1920"
+ fit-margin-bottom="0"
+ fit-margin-right="0"
+ fit-margin-left="0"
+ fit-margin-top="0"
+ showgrid="false"
+ inkscape:document-rotation="0"
+ inkscape:current-layer="layer1"
+ inkscape:document-units="mm"
+ inkscape:cy="39.499381"
+ inkscape:cx="29.58201"
+ inkscape:zoom="5.6"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base" />
+ <metadata
+ id="metadata24">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ transform="translate(-111.75311,-212.54075)"
+ id="layer1"
+ inkscape:groupmode="layer"
+ inkscape:label="Ebene 1">
+ <path
+ style="fill:#f0424d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.264583"
+ d="m 123.18096,212.54075 c -1.54244,0 -3.03889,0.30198 -4.44866,0.89818 -1.36085,0.57588 -2.58333,1.3995 -3.63198,2.44903 -1.04982,1.04891 -1.87352,2.27125 -2.44969,3.63166 -0.59614,1.41006 -0.89752,2.90769 -0.89752,4.44931 0,0.88089 0.0998,1.75881 0.29917,2.60975 0.19372,0.82789 0.48107,1.63557 0.85432,2.40026 0.68819,1.40905 1.80379,2.81384 3.06538,3.86536 0.82281,-0.4498 1.28965,-0.94572 1.38884,-1.47622 0.0956,-0.50956 -0.12815,-1.05842 -0.7044,-1.72565 -1.36741,-1.56892 -2.12041,-3.58324 -2.12041,-5.6735 0,-4.76667 3.87763,-8.6456 8.64495,-8.6456 0.008,0 0.0393,6.6e-4 0.0393,6.6e-4 0,0 0.0305,-6.6e-4 0.0383,-6.6e-4 4.76715,0 8.64527,3.87893 8.64527,8.6456 0,2.09026 -0.75283,4.1046 -2.11975,5.67284 -0.57201,0.66284 -0.80153,1.23499 -0.70211,1.74922 0.10311,0.53107 0.56896,1.02002 1.38458,1.45397 1.26331,-1.05177 2.3782,-2.4564 3.06637,-3.86602 0.37372,-0.76469 0.66107,-1.57237 0.85464,-2.40026 0.1988,-0.85094 0.29983,-1.72886 0.29983,-2.60975 0,-1.54162 -0.30231,-3.03925 -0.89851,-4.44931 -0.57588,-1.36041 -1.40013,-2.58275 -2.44904,-3.63166 -1.04913,-1.04953 -2.27155,-1.87315 -3.63198,-2.44903 -1.40995,-0.5962 -2.90688,-0.89818 -4.44931,-0.89818 h -0.0393 z m -0.004,4.62214 c -0.32192,0 -0.64417,0.0219 -0.95873,0.0671 -0.92883,0.1324 -1.8401,0.46397 -2.63525,0.96004 -0.75897,0.47323 -1.43426,1.1087 -1.95215,1.83792 -0.53535,0.75374 -0.91954,1.62985 -1.10963,2.53316 -0.20655,0.97977 -0.19361,2.01224 0.0376,2.98552 0.21276,0.89514 0.61602,1.75703 1.16626,2.49191 0.14746,0.19797 0.31251,0.37855 0.48673,0.56987 0.058,0.063 0.11717,0.12782 0.17675,0.19411 0.002,0.002 0.003,0.003 0.005,0.005 0.007,0.007 0.0162,0.0158 0.0252,0.0265 0.60646,0.70473 0.91421,1.46388 0.91421,2.25525 0,1.19597 -0.66414,2.29315 -1.70895,2.85525 0.60776,0.33731 1.24734,0.61904 1.90404,0.83925 0.21816,0.0731 0.44001,0.13985 0.6625,0.19934 0.13296,-0.0835 0.58624,-0.42093 1.02943,-1.03369 0.42381,-0.58551 0.92331,-1.55674 0.89687,-2.85753 -0.0155,-0.78287 -0.17316,-1.54536 -0.46709,-2.26507 -0.29199,-0.71355 -0.71021,-1.36743 -1.24449,-1.94268 l -0.002,-0.004 c -0.04,-0.0456 -0.0786,-0.0911 -0.11816,-0.13613 -0.20138,-0.23358 -0.40932,-0.47459 -0.57609,-0.75677 -0.20417,-0.34691 -0.35302,-0.71154 -0.44123,-1.08442 -0.13724,-0.57588 -0.1445,-1.18703 -0.0229,-1.76689 0.1135,-0.53315 0.3392,-1.04985 0.65563,-1.49522 0.30638,-0.43154 0.70637,-0.80806 1.15578,-1.08835 0.46898,-0.29265 1.00724,-0.48855 1.55511,-0.56627 0.18502,-0.0266 0.37651,-0.0403 0.56824,-0.0403 h 0.0409 0.0412 c 0.19212,0 0.38328,0.0137 0.56889,0.0403 0.54819,0.0777 1.08631,0.27362 1.55479,0.56627 0.44949,0.28029 0.84882,0.65681 1.15545,1.08835 0.31651,0.44537 0.54311,0.96207 0.65563,1.49522 0.12194,0.57986 0.11399,1.19101 -0.0222,1.76689 -0.0886,0.37288 -0.23731,0.73751 -0.44189,1.08442 -0.16594,0.28218 -0.37412,0.52319 -0.57544,0.75677 -0.0397,0.045 -0.0786,0.0905 -0.11783,0.13617 l -0.003,0.004 c -0.53338,0.57525 -0.9522,1.22913 -1.24416,1.94267 -0.29412,0.71971 -0.45106,1.4822 -0.46742,2.26507 -0.0261,1.30079 0.47323,2.27202 0.89753,2.85754 0.44229,0.61275 0.89596,0.95014 1.02877,1.03369 0.22233,-0.0595 0.44541,-0.12627 0.66349,-0.19934 0.6567,-0.22022 1.29635,-0.50194 1.90436,-0.83926 -1.04596,-0.5621 -1.70993,-1.65928 -1.70993,-2.85524 0,-0.78066 0.29884,-1.5183 0.91356,-2.25395 0.008,-0.0117 0.0182,-0.0208 0.0252,-0.0278 0.002,-0.002 0.004,-0.003 0.006,-0.005 0.0597,-0.0663 0.1185,-0.1311 0.17577,-0.19411 0.17488,-0.19132 0.33935,-0.3719 0.48706,-0.56987 0.55097,-0.73488 0.95359,-1.59677 1.16691,-2.49191 0.2306,-0.97328 0.24377,-2.00575 0.038,-2.98552 -0.19086,-0.90335 -0.57496,-1.77946 -1.10998,-2.5332 -0.51797,-0.72922 -1.19318,-1.36469 -1.95215,-1.83792 -0.79523,-0.49606 -1.70641,-0.82764 -2.63561,-0.96004 -0.31415,-0.0452 -0.63706,-0.0671 -0.95906,-0.0671 h -0.0409 -0.0452 z m 0.0429,4.65814 c -1.24383,0 -2.25624,1.01222 -2.25624,2.25657 0,1.24414 1.01241,2.25624 2.25624,2.25624 1.24382,0 2.25591,-1.0121 2.25591,-2.25624 0,-1.24435 -1.01209,-2.25657 -2.25591,-2.25657 z"
+ id="path3043-5"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/src/pybind/mgr/dashboard/frontend/src/assets/ceph_background.gif b/src/pybind/mgr/dashboard/frontend/src/assets/ceph_background.gif
new file mode 100644
index 000000000..0f7426ee0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/assets/ceph_background.gif
Binary files differ
diff --git a/src/pybind/mgr/dashboard/frontend/src/assets/loading.gif b/src/pybind/mgr/dashboard/frontend/src/assets/loading.gif
new file mode 100755
index 000000000..8fb88dea3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/assets/loading.gif
Binary files differ
diff --git a/src/pybind/mgr/dashboard/frontend/src/assets/logo-mini.png b/src/pybind/mgr/dashboard/frontend/src/assets/logo-mini.png
new file mode 100644
index 000000000..b3446a894
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/assets/logo-mini.png
Binary files differ
diff --git a/src/pybind/mgr/dashboard/frontend/src/assets/prometheus_logo.svg b/src/pybind/mgr/dashboard/frontend/src/assets/prometheus_logo.svg
new file mode 100644
index 000000000..5c51f66d9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/assets/prometheus_logo.svg
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ width="115.333px"
+ height="114px"
+ viewBox="0 0 115.333 114"
+ enable-background="new 0 0 115.333 114"
+ xml:space="preserve"
+ sodipodi:docname="prometheus_logo_orange.svg"
+ inkscape:version="0.92.1 r15371"><metadata
+ id="metadata4495"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs4493" /><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1484"
+ inkscape:window-height="886"
+ id="namedview4491"
+ showgrid="false"
+ inkscape:zoom="5.2784901"
+ inkscape:cx="60.603667"
+ inkscape:cy="60.329656"
+ inkscape:window-x="54"
+ inkscape:window-y="7"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="Layer_1" /><g
+ id="Layer_2" /><path
+ style="fill:#e6522c;fill-opacity:1"
+ inkscape:connector-curvature="0"
+ id="path4486"
+ d="M 56.667,0.667 C 25.372,0.667 0,26.036 0,57.332 c 0,31.295 25.372,56.666 56.667,56.666 31.295,0 56.666,-25.371 56.666,-56.666 0,-31.296 -25.372,-56.665 -56.666,-56.665 z m 0,106.055 c -8.904,0 -16.123,-5.948 -16.123,-13.283 H 72.79 c 0,7.334 -7.219,13.283 -16.123,13.283 z M 83.297,89.04 H 30.034 V 79.382 H 83.298 V 89.04 Z M 83.106,74.411 H 30.186 C 30.01,74.208 29.83,74.008 29.66,73.802 24.208,67.182 22.924,63.726 21.677,60.204 c -0.021,-0.116 6.611,1.355 11.314,2.413 0,0 2.42,0.56 5.958,1.205 -3.397,-3.982 -5.414,-9.044 -5.414,-14.218 0,-11.359 8.712,-21.285 5.569,-29.308 3.059,0.249 6.331,6.456 6.552,16.161 3.252,-4.494 4.613,-12.701 4.613,-17.733 0,-5.21 3.433,-11.262 6.867,-11.469 -3.061,5.045 0.793,9.37 4.219,20.099 1.285,4.03 1.121,10.812 2.113,15.113 C 63.797,33.534 65.333,20.5 71,16 c -2.5,5.667 0.37,12.758 2.333,16.167 3.167,5.5 5.087,9.667 5.087,17.548 0,5.284 -1.951,10.259 -5.242,14.148 3.742,-0.702 6.326,-1.335 6.326,-1.335 l 12.152,-2.371 c 10e-4,-10e-4 -1.765,7.261 -8.55,14.254 z" /></svg> \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/src/environments/environment.tpl.ts b/src/pybind/mgr/dashboard/frontend/src/environments/environment.tpl.ts
new file mode 100644
index 000000000..421ae5e5c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/environments/environment.tpl.ts
@@ -0,0 +1,10 @@
+// The file contents for the current environment will overwrite these during build.
+// The build system defaults to the dev environment which uses `environment.ts`, but if you do
+// `ng build --env=prod` then `environment.prod.ts` will be used instead.
+// The list of which env maps to which file can be found in `.angular-cli.json`.
+
+export const environment = {
+ default_lang: '{DEFAULT_LANG}',
+ production: '{PRODUCTION}',
+ year: '{COPYRIGHT_YEAR}'
+};
diff --git a/src/pybind/mgr/dashboard/frontend/src/favicon.ico b/src/pybind/mgr/dashboard/frontend/src/favicon.ico
new file mode 100644
index 000000000..90e538ba7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/favicon.ico
Binary files differ
diff --git a/src/pybind/mgr/dashboard/frontend/src/index.html b/src/pybind/mgr/dashboard/frontend/src/index.html
new file mode 100644
index 000000000..183202cfe
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/index.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>Ceph</title>
+
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+ <link rel="icon" type="image/x-icon" id="cdFavicon" href="favicon.ico">
+</head>
+<body>
+ <noscript>
+ <div class="noscript container"
+ ng-if="false">
+ <div class="jumbotron alert alert-danger">
+ <h2 i18n>JavaScript required!</h2>
+ <p i18n>A browser with JavaScript enabled is required in order to use this service.</p>
+ <p i18n>When using Internet Explorer, please check your security settings and add this address to your trusted sites.</p>
+ </div>
+ </div>
+ </noscript>
+
+ <cd-root></cd-root>
+</body>
+</html>
diff --git a/src/pybind/mgr/dashboard/frontend/src/jestGlobalMocks.ts b/src/pybind/mgr/dashboard/frontend/src/jestGlobalMocks.ts
new file mode 100644
index 000000000..cb2d8c64f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/jestGlobalMocks.ts
@@ -0,0 +1,7 @@
+Object.defineProperty(window, 'getComputedStyle', {
+ value: () => ({
+ getPropertyValue: () => {
+ return '';
+ }
+ })
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.cs.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.cs.xlf
new file mode 100644
index 000000000..b391c54df
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.cs.xlf
@@ -0,0 +1,14162 @@
+<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en-US" datatype="plaintext" original="ng2.template" target-language="cs">
+ <body>
+ <trans-unit id="ngb.alert.close" datatype="html">
+ <source>Close</source>
+ <target>Zavřít</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/alert/alert.ts</context>
+ <context context-type="linenumber">58,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.slide-number" datatype="html">
+ <source> Slide <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> of <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">114,118</context>
+ </context-group>
+ <note priority="1" from="description">Currently selected slide number read by screen reader</note>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.previous" datatype="html">
+ <source>Previous</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">132,134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.next" datatype="html">
+ <source>Next</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">147,152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-month" datatype="html">
+ <source>Select month</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">44,49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">49,50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-year" datatype="html">
+ <source>Select year</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">59,63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.previous-month" datatype="html">
+ <source>Previous month</source>
+ <target>Předchozí měsíc</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">24,27</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">35,36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.next-month" datatype="html">
+ <source>Next month</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">47,50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">60,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first" datatype="html">
+ <source>««</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">182,183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous" datatype="html">
+ <source>«</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">186,190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next" datatype="html">
+ <source>»</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">194,195</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last" datatype="html">
+ <source>»»</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">201,204</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first-aria" datatype="html">
+ <source>First</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">208,209</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous-aria" datatype="html">
+ <source>Previous</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">215,216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next-aria" datatype="html">
+ <source>Next</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">226,228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last-aria" datatype="html">
+ <source>Last</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.progressbar.value" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="; } /** *"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/progressbar/progressbar.ts</context>
+ <context context-type="linenumber">32,38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.HH" datatype="html">
+ <source>HH</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">40,41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.hours" datatype="html">
+ <source>Hours</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.MM" datatype="html">
+ <source>MM</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">51,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.minutes" datatype="html">
+ <source>Minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-hours" datatype="html">
+ <source>Increment hours</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">63,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-hours" datatype="html">
+ <source>Decrement hours</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">69,70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-minutes" datatype="html">
+ <source>Increment minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">76,78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-minutes" datatype="html">
+ <source>Decrement minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">82,84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.SS" datatype="html">
+ <source>SS</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.seconds" datatype="html">
+ <source>Seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">92,93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-seconds" datatype="html">
+ <source>Increment seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">100,101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-seconds" datatype="html">
+ <source>Decrement seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">106,110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.AM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">115,121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.PM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="t() meridian: b"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">123,131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.toast.close-aria" datatype="html">
+ <source>Close</source>
+ <target>Zavřít</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/toast/toast.ts</context>
+ <context context-type="linenumber">78,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8835b9e49a3348b0a2f2162c21118af1f4bee45a" datatype="html">
+ <source>Must be greater than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbddac59563c8c126e3fe28691e4e247614fcbd1" datatype="html">
+ <source>Must be less than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5" datatype="html">
+ <source>Overview</source>
+ <target>Přehled</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbd2045d5c37e4bb39a3c0fb62ea1ddf70a12838" datatype="html">
+ <source>Targets</source>
+ <target>Cíle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a674ab267d1934bf395f87ca1503fd474296893f" datatype="html">
+ <source>iSCSI Topology</source>
+ <target>Topologie iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8953033926734869941" datatype="html">
+ <source>Name</source>
+ <target>Název</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6603000223840533819" datatype="html">
+ <source>Current</source>
+ <target>Stávající</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5607669932062416162" datatype="html">
+ <source>Default</source>
+ <target>Výchozí</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6803e31b7395d94934e091a49a9524026b59b018" datatype="html">
+ <source>Discovery Authentication</source>
+ <target>Ověřování pro objevování</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e08a77594f3d89311cdf6da5090044270909c194" datatype="html">
+ <source>User</source>
+ <target>Uživatele</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">381</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7cbdabcece469fab89cfa687ab152bca18b97498" datatype="html">
+ <source>This field is required.</source>
+ <target>Tuto kolonku je třeba vyplnit.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">368</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">423</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">481</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">291</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">343</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">407</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">490</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">516</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">556</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">573</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">590</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">647</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">672</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">299</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">195</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">520</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">614</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">651</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f717bad2da5944a2567a52f971ccc6806db85805" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">28,29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">85,86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c32ef07f8803a223a83ed17024b38e8d82292407" datatype="html">
+ <source>Password</source>
+ <target>Heslo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">403</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">581</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="001e1836299d8d3b84eaebe2fa051325beab3f00" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">61,62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">118,119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff40391de7a1944ea95091e4045cc34c4979b736" datatype="html">
+ <source>Mutual User</source>
+ <target>Uživatel pro vzájemné ověření</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cf73dbebe99b737c4d288788182fc356e3c93d3" datatype="html">
+ <source>Mutual Password</source>
+ <target>Heslo pro vzájemné ověření</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594987303599690088" datatype="html">
+ <source>Updated discovery authentication</source>
+ <target>Aktualizováno ověřování pro objevování</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb127ea03835b3230f0ed981c7080e2ccb879621" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <note priority="1" from="description">form title</note>
+ </trans-unit>
+ <trans-unit id="1406c2fb12a20c1528b19bcc5e24a6a2386167f3" datatype="html">
+ <source>Target IQN</source>
+ <target>IQN cíle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5fe42339be910372fa689f559155631862d218e8" datatype="html">
+ <source>IQN has wrong pattern.</source>
+ <target>IQN nemá správný formát.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="050a7ff057d1e895357540406b6be5652b4d1c71" datatype="html">
+ <source>An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'</source>
+ <target>IQN má následující formu zápisu „iqn.$rok-$měsíc.$adresaObráceně:$určenýNázev'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8ada4b53396d8366db00a435acc61d53d857047" datatype="html">
+ <source>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</source>
+ <target>Například: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e" datatype="html">
+ <source>More information</source>
+ <target>Další informace</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9b1aa85dfc6849196e64060db02c5410de69b7a1" datatype="html">
+ <source>This target has modified advanced settings.</source>
+ <target>Tento cíl má změněná pokročilá nastavení.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6990ad8d6182662e864495ac31c3758cda1c7a28" datatype="html">
+ <source>Portals</source>
+ <target>Portály</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a3ac2b4137d723fd9878cd357c2012ff6c07973" datatype="html">
+ <source>Add portal</source>
+ <target>Přidat portál</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3638c01b6c34066438909713ec96087c813fc7e" datatype="html">
+ <source>At least <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> gateways are required.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b73f7f5060fb22a1e9ec462b1bb02493fa3ab866" datatype="html">
+ <source>Images</source>
+ <target>Obrazy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">495</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">629</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9aff25be088f0efe3eaaf62edf2bff41cc41a617" datatype="html">
+ <source>Backstore: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e3484cae8b118c576ca2815bf9c9406c2eb2cae3" datatype="html">
+ <source>This image has modified settings.</source>
+ <target>Tento obraz má změněná nastavení.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1dff11e0820b6722ab240169f1232d70a54beaaa" datatype="html">
+ <source>Duplicated LUN numbers.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bf2dccf92ccff6e3b091792bf4205595406e1bfb" datatype="html">
+ <source>Duplicated WWN.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="808038f912fdc7f0e03f82d4afd3bf9178527fc8" datatype="html">
+ <source>Add image</source>
+ <target>Přidat obraz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">656</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66c5fb27f52e75b70ca4b670b9b15a2a51cf9543" datatype="html">
+ <source>ACL authentication</source>
+ <target>ACL ověřování</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="137fbf154ecad4d580354db0858b76faea7e4686" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">227,228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">287,288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="361771c32dd2254d77fd3fbf006b008983fe5907" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">262,263</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">323,324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f494bd31f095f6dcc656ce87ec2dcf07a2e9b30c" datatype="html">
+ <source>Initiators</source>
+ <target>Iniciátory</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">335</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">588</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e98239d8a6be1100119ff4b5630c822b82786740" datatype="html">
+ <source>Initiator</source>
+ <target>Iniciátor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2c5059d8cda15d8d03e2cce30f2d139623d9a91" datatype="html">
+ <source>Client IQN</source>
+ <target>IQN klienta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="107d5aabce23d900f0a80e6ddc1c10e29aa0bed8" datatype="html">
+ <source>Initiator IQN needs to be unique.</source>
+ <target>Je třeba, aby se IQN iniciátoru neopakovalo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e7cad911fa524e512d9744b16358b7ee6791385" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">394,395</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">452,453</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7f2c186d181206d0d2b1ff74819081a010f10bf" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">427,428</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">485,486</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d1878d5fc761cbe9614bfd87047a740c82a6951" datatype="html">
+ <source>Initiator belongs to a group. Images will be configure in the group.</source>
+ <target>Iniciátor spadá do skupiny. Obrazy budou nastaveny ve skupině.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">515</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0de67b9d97fafbf200f9451e8388ee8128a56ac" datatype="html">
+ <source>No items added.</source>
+ <target>Nepřidány žádné položky.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">671</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d565e47726158e428ecdc952fc9233b9b7d7f049" datatype="html">
+ <source>Add initiator</source>
+ <target>Přidat iniciátor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">616</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c22ba03540aa3217da059f45e7eab138b51a96e2" datatype="html">
+ <source>Groups</source>
+ <target>Skupiny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c90059afafb7e160384d9f512797c95bb95c6dc" datatype="html">
+ <source>Group</source>
+ <target>Skupina</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cff1428d10d59d14e45edec3c735a27b5482db59" datatype="html">
+ <source>Name</source>
+ <target>Název</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">576</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3084948274cff4f56d0f431af47240e9cf02fcc7" datatype="html">
+ <source>Add group</source>
+ <target>Přidat skupinu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">676</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6634268061646442252" datatype="html">
+ <source>There are no portals available.</source>
+ <target>Nejsou k dispozici žádné portály.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4587015892789840153" datatype="html">
+ <source>There are no images available.</source>
+ <target>Nejsou k dispozici žádné obrazy.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7896905042057267575" datatype="html">
+ <source>There are no images available. Please make sure you add an image to the target.</source>
+ <target>Nejsou k dispozici žádné obrazy. Ověřte, že jste cíli přidali obraz.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6765423558085969805" datatype="html">
+ <source>There are no initiators available. Please make sure you add an initiator to the target.</source>
+ <target>Nejsou k dispozici žádné iniciátory. Ověřte, že jste cíli přidali iniciátor.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2539932200265667453" datatype="html">
+ <source>target</source>
+ <target>cíl</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="051dcc342cfa5c1eaf187a2001aaa162379a160c" datatype="html">
+ <source>Configure</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e515f954730279c31d5301f02479666d6264e8b" datatype="html">
+ <source>Changing these parameters from their default values is usually not necessary.</source>
+ <target>Měnit tyto parametry z jejich výchozích hodnot obvykle není potřeba.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e2591df099ddac796cda401c5f282da779d45f2" datatype="html">
+ <source>Identifier</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62480a4859976427cf18fc8ef41d3a438eda0412" datatype="html">
+ <source>lun</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8afc9eb4405e0aa554b2ba14140ef790cdecc040" datatype="html">
+ <source>wwn</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
+ <source>Settings</source>
+ <target>Nastavení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69a47cbabcc51ca942606e1d8da0ec11f98a2690" datatype="html">
+ <source>Backstore</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="339878da255ab55447c43afef8d9b2f9753bf5f6" datatype="html">
+ <source>Advanced Settings</source>
+ <target>Pokročilá nastavení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="332227f088a4877b3c11f5fb3ae8bc812c470fae" datatype="html">
+ <source>iSCSI Targets not available</source>
+ <target>iSCSI cíl není k dispozici</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7fba666f1fff0182e570f12133fb3d622d9ea6" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the iSCSI Targets management functionality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3b301d0044f62c92af0da53d7aaca52a436a547d" datatype="html">
+ <source>Available information:</source>
+ <target>Informace k dispozici:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8414a5cb9d71cc1b21b10e4a9d1f2dad558f3361" datatype="html">
+ <source>Discovery authentication</source>
+ <target>Ověřování pro objevování</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4854396465510517671" datatype="html">
+ <source>Target</source>
+ <target>Cíl</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4093869278527257288" datatype="html">
+ <source>Portals</source>
+ <target>Portály</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="414887388288176527" datatype="html">
+ <source>Images</source>
+ <target>Obrazy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="798573158169239055" datatype="html">
+ <source># Sessions</source>
+ <target>Počet relací</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="646929398175374220" datatype="html">
+ <source>Unavailable gateway(s)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2350612272163013640" datatype="html">
+ <source>Target has active sessions</source>
+ <target>Cíl má aktivní relace</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4782410538666829801" datatype="html">
+ <source>iSCSI target</source>
+ <target>iSCSI cíl</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">227</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8a9910cd114c1deb9af74f6f99b4173403965bf2" datatype="html">
+ <source>Gateways</source>
+ <target>Brány</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911214550882917183" datatype="html">
+ <source>State</source>
+ <target>Stav</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4121862424558610140" datatype="html">
+ <source># Targets</source>
+ <target>Počet cílů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101197021456818771" datatype="html">
+ <source>Pool</source>
+ <target>Fond</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3012906865384504293" datatype="html">
+ <source>Image</source>
+ <target>Obraz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2699995524827665158" datatype="html">
+ <source>Backstore</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3559214740809905405" datatype="html">
+ <source>Read Bytes</source>
+ <target>Bajtů čtení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1580583760095064067" datatype="html">
+ <source>Write Bytes</source>
+ <target>Bajtů zápis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7225917547116479918" datatype="html">
+ <source>Read Ops</source>
+ <target>Operací/s čtení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6417507714454914481" datatype="html">
+ <source>Write Ops</source>
+ <target>Operací/s zápis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="257147267065394003" datatype="html">
+ <source>A/O Since</source>
+ <target>A/O od</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ecbc084370a732fc3cde1966a60af78d71424ab4" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603e9cc3ef2aab57f2b0a00e465b23b9cabefd9c" datatype="html">
+ <source>To create a bootstrap token which can be imported by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Generate<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="660f97cd3188f8a04bd03b79e703fec72c6df04c" datatype="html">
+ <source>Site Name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2fecea01ce1d44114ee45144eff6d47a5016a74f" datatype="html">
+ <source>Name...</source>
+ <target>Název…</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92899fa68e8ca108912163ff58edc8540e453787" datatype="html">
+ <source>Pools</source>
+ <target>Fondy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c2a1dc72cffaf7ab3dc5599bf77b0a7fcad2b20" datatype="html">
+ <source>At least one pool is required.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b258b258b4cc475ceb2871305b61756b0134f4a" datatype="html">
+ <source>Generate</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1edc1fc6cfbbb22353050ad6788508b3ed584f53" datatype="html">
+ <source>Token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff785f5596aef34a93b9b4d1023e95c62eef5740" datatype="html">
+ <source>Generated token...</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8" datatype="html">
+ <source>Close</source>
+ <target>Zavřít</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5467a6bb0e7fade6def7499400d5e2a7d8d3da20" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bb7aee0dec5164f45c0aa2f35f2fb2149d2c1d2" datatype="html">
+ <source>To import a bootstrap token which was created by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, provide the generated token, and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Import<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9200e09686136a1d42adfb89c12fbfef2deea125" datatype="html">
+ <source>Direction</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9761484679958da8d12841a4efa5964d33fae575" datatype="html">
+ <source>The token is invalid.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2381859602529023966" datatype="html">
+ <source>Instance</source>
+ <target>Instance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8040881171107393560" datatype="html">
+ <source>ID</source>
+ <target>Identif.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1605455101862010019" datatype="html">
+ <source>Hostname</source>
+ <target>Název stroje</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2724055831234181057" datatype="html">
+ <source>Version</source>
+ <target>Verze</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2041675390931385838" datatype="html">
+ <source>Health</source>
+ <target>Zdraví</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87bd96249f8afc23f5301cddb57b1464a98e71a" datatype="html">
+ <source>Edit site name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cfff72c667274c12eb1ff71eadc25871c10c42dc" datatype="html">
+ <source>Edit the site name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">13,14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66db799d67958d4b0765181d072df62e2d1c16f5" datatype="html">
+ <source>Issues</source>
+ <target>problémy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef06d69259e587e28d52372455f44c7153cda7e7" datatype="html">
+ <source>Syncing</source>
+ <target>Synchronizuje se</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0b0901877d837d3fda16ba161eb74368d1c75b7a" datatype="html">
+ <source>Ready</source>
+ <target>Připraveno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5833626790712999947" datatype="html">
+ <source>Issue</source>
+ <target>Problém</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3419681791450150574" datatype="html">
+ <source>Progress</source>
+ <target>Ukazatel postupu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4902817035128594900" datatype="html">
+ <source>Description</source>
+ <target>Popis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40b7acea5b43f45e0bbd1efeba5200af4687981d" datatype="html">
+ <source>Site Name:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e24f9e2d42104ffc01599db4d566d1cc518f9e6" datatype="html">
+ <source>Daemons</source>
+ <target>Procesy služeb</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6450386891540681425" datatype="html">
+ <source>Edit Site Name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4645993115976933405" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4130053543590533787" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4057c56d63a7e9b140b1d01871a9229a5f30eb27" datatype="html">
+ <source>Edit pool mirror mode</source>
+ <target>Upravit režim zrcadlení fondu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e1f367f5feaab38f6637dd1f967c848b447dea2d" datatype="html">
+ <source>To edit the mirror mode for pool  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, select a new mode from the list and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37e10df2d9c0c25ef04ac112c9c9a7723e8efae0" datatype="html">
+ <source>Mode</source>
+ <target>Režim</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">426</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32ca348ef926b0a6a7a780b8b64c3a8239895cec" datatype="html">
+ <source>Peer clusters must be removed prior to disabling mirror.</source>
+ <target>Před vypnutím zrcadlení je třeba odebrat klastry-protějšky.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5769292297914455214" datatype="html">
+ <source>Disabled</source>
+ <target>Vypnuto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ddcb416c1c0aa1f54acf5beef1de81813e76fa6" datatype="html">
+ <source>{VAR_SELECT, select, edit {Edit} other {Add}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3aa7c3a4f7b0cf7c2e60fc71ea1e3b4c3efa3558" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> pool mirror peer</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="59ca65ece457429d90104ede4674965f62edbabe" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> the pool mirror peer attributes for pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Submit<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d3cc964811f852a168f4a2d5daa59068abc5cf53" datatype="html">
+ <source>Cluster Name</source>
+ <target>Název klastru</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b631721fc56cb7fb1cbd07b802a487c5753f6a2d" datatype="html">
+ <source>The cluster name is not valid.</source>
+ <target>Název klastru není platný</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca6deafa31bf421f85094807982aee4bcb20a3ae" datatype="html">
+ <source>CephX ID</source>
+ <target>CephX identif.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7539188a568c3d553cbde1bacaf32310c4264e24" datatype="html">
+ <source>CephX ID...</source>
+ <target>CephX identif. …</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1c45b594b0fba22fc64e80c793a7ffe005fdb0e" datatype="html">
+ <source>The CephX ID is not valid.</source>
+ <target>CephX identif. není platný.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20861576fcfce773c918c782cd4f5adf32382921" datatype="html">
+ <source>Monitor Addresses</source>
+ <target>Adresy monitorů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fa28eeed2b4bd4ccbe6e9349a1c2b3cb1c5de70a" datatype="html">
+ <source>Comma-delimited addresses...</source>
+ <target>Čárkou oddělované adresy…</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dc016c82fd85848d5c1b2fd0e8469ee2027d9c16" datatype="html">
+ <source>The monitory address is not valid.</source>
+ <target>Adresa monitoru není platná.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0ac55b83dc6739e62bc655cfe375b67c93e7f4a" datatype="html">
+ <source>CephX Key</source>
+ <target>CephX klíč</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f53434bcb95bd86f1df9c8e22966f757614fc4ad" datatype="html">
+ <source>Base64-encoded key...</source>
+ <target>Klíč v base64 kódování…</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4cd83164cd4f66b4abc2863f9ce6f599d789e4ca" datatype="html">
+ <source>CephX key must be base64 encoded.</source>
+ <target>Je třeba, aby CephX klíč byl v kódování base64.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6407712033679505505" datatype="html">
+ <source>Edit Mode</source>
+ <target>Upravit režim</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054237897979907103" datatype="html">
+ <source>Add Peer</source>
+ <target>Přidat protějšek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="899134641637789371" datatype="html">
+ <source>Edit Peer</source>
+ <target>Upravit protějšek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7393680121674824053" datatype="html">
+ <source>Delete Peer</source>
+ <target>Smazat protějšek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1713271461473302108" datatype="html">
+ <source>Mode</source>
+ <target>Režim</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1061297288634362831" datatype="html">
+ <source>Leader</source>
+ <target>Vedoucí</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8517494870558773093" datatype="html">
+ <source># Local</source>
+ <target>Počet místních</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4953753699491987394" datatype="html">
+ <source># Remote</source>
+ <target>Počet vzdálených</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1715982232168082172" datatype="html">
+ <source>mirror peer</source>
+ <target>zrcadlit protějšek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff92fbdec9fdd5054493eeda0d7ee8b450f83e72" datatype="html">
+ <source>RBD Configuration</source>
+ <target>Nastavení RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b62d9efc8eb3b589904f6cb96a0406bbda55673a" datatype="html">
+ <source>Remove the local configuration value. The parent configuration value will be inherited and used instead.</source>
+ <target>Odebrat hodnotu místnímu nastavení. Namísto ní bude použita hodnota nadřazeného nastavení.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80d769fd863fe44fab689636a078466bfdbd1f20" datatype="html">
+ <source>The minimum value is 0</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5decb3917d46a9ac6e5813699801becb7c3c1455" datatype="html">
+ <source>Global</source>
+ <target>Globální</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f9ba9bb9faa8284bcadb1cdbc6aaf969e9c4bb" datatype="html">
+ <source>Image</source>
+ <target>Obraz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70fcca5a99575cffef3ff8cbd5e69f06ffd0f1c" datatype="html">
+ <source>Pool</source>
+ <target>Fond</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176659033176029418" datatype="html">
+ <source>Key</source>
+ <target>Klíč</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9155608366859514313" datatype="html">
+ <source>Source</source>
+ <target>Zdroj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6555318547274416232" datatype="html">
+ <source>Value</source>
+ <target>Hodnota</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f6e8f6094b180eaf1f11bc0ffe383f1cdcd059e" datatype="html">
+ <source>Only available for RBD images with <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> enabled</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f8b2bb476981727ab34ed40fde1218361f92c45" datatype="html">
+ <source>Details</source>
+ <target>Podrobnosti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03cc5b14b0a20d075e9009ff021f4f1660ba348a" datatype="html">
+ <source>Data Pool</source>
+ <target>Datový fond</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b051734b0ee9021991c91b3ed4e81c244322462" datatype="html">
+ <source>Created</source>
+ <target>Vytvořeno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7faaaa08f56427999f3be41df1093ce4089bbd75" datatype="html">
+ <source>Size</source>
+ <target>Velikost</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="afdb601c16162f2c798b16a2920955f1cc6a20aa" datatype="html">
+ <source>Objects</source>
+ <target>Objekty</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ceac8e132384322ec778ba760875a6c6897d3e42" datatype="html">
+ <source>Object size</source>
+ <target>Velikost objektu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cdb1fea93d77c07950c0c76c6e0ad79ebbef084" datatype="html">
+ <source>Features</source>
+ <target>Funkce</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65771c9a73b9aa609d592fc96a64801a8f40bd" datatype="html">
+ <source>Provisioned</source>
+ <target>Poskytováno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84a36cb75660b736773fe36ffa3d54f0f0fe363e" datatype="html">
+ <source>N/A</source>
+ <target>neaplikovatelné</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c009342a4e8381f64341d0bb61c2e4685f5a4b" datatype="html">
+ <source>Total provisioned</source>
+ <target>Celkem poskytováno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f6bf8a43ae415f527ac961ea62471b983aaa97b" datatype="html">
+ <source>Striping unit</source>
+ <target>Proužkovací jednotka</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db710e8a8f011923f2d15d713fbae49c38b02b26" datatype="html">
+ <source>Striping count</source>
+ <target>Počet proužkování</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a4c2a9e76634ff14a60d52a718296f722d47c67" datatype="html">
+ <source>Parent</source>
+ <target>Nadřazené</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a209e68d78ffc2cc9c53d2e76158624efab71ad" datatype="html">
+ <source>Block name prefix</source>
+ <target>Předpona názvu bloku</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5704ec2049d007c5f5fb495a5d8b607e68d58081" datatype="html">
+ <source>Order</source>
+ <target>Pořadí</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="984cb6ad70f150a401b4daf841bd3cd957412699" datatype="html">
+ <source>Format Version</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f21b1d17b6c5042bb5805516eee37fde33739dd8" datatype="html">
+ <source>Snapshots</source>
+ <target>Zachycené stavy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4a41f824a35ba01d5bd7be61aa06b3e8145209d0" datatype="html">
+ <source>Configuration</source>
+ <target>Nastavení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3cc9c2ae277393b3946b38c088dabff671b1ee1b" datatype="html">
+ <source>Performance</source>
+ <target>Výkonnost</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935bb9cb0e4340fc74d33caa3b70d9d143fcad87" datatype="html">
+ <source>Information can not be displayed for RBD in status 'Removing'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58e58f1a8786da9031a05e6770c5dafce82badf5" datatype="html">
+ <source>This setting overrides the global value</source>
+ <target>Toto nastavení přebije globální hodnotu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36b46714164964c6258b08ed0a25f57d8a950f92" datatype="html">
+ <source>This is the global value. No value for this option has been set for this image.</source>
+ <target>Toto je globální hodnota. Pro tento obraz nebyla u této volby nastavena žádná hodnota.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6547c9c4d5f62942ac4b1fe459cf9a03d4dbf5a0" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> from</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0e9ecf29a4fa5b057bd8052e0d801b3fde6a30bf" datatype="html">
+ <source>'/' and '@' are not allowed.</source>
+ <target>„/“ a „@“ nejsou dovoleny.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="94516fa213706c67ce5a5b5765681d7fb032033a" datatype="html">
+ <source>Loading...</source>
+ <target>Načítání…</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">209</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">452</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b99417c4dd46286ffd37c8d2e987c8b512ec7052" datatype="html">
+ <source>-- No rbd pools available --</source>
+ <target>-- Žádné rbd fondy k dispozici --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef83ec9c304a89d45650e580dcdc2978c37b3a83" datatype="html">
+ <source>-- Select a pool --</source>
+ <target>-- Vybrat fond --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d649904466254d13df1fbf2d255f0bbc6553d213" datatype="html">
+ <source>-- No namespaces available --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e22d7bb4d2d561e0832ee0b9a3da2468a080c4f0" datatype="html">
+ <source>-- Select a namespace --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49449943d8cbf59d8c401c8bd2e76f92e207cc5f" datatype="html">
+ <source>Use a dedicated data pool</source>
+ <target>Použít vyhrazený datový fond</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa5b3c5ea5af14d09b2eb098039af9f1f77be010" datatype="html">
+ <source>You need more than one pool with the rbd application label use to use a dedicated data pool.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="870aee0dd31a9643bf62007beb8f1ae1deb34d42" datatype="html">
+ <source>Data pool</source>
+ <target>Datový fond</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3792ca829d9b9f687e1f5d7733d30e9bb0bfec47" datatype="html">
+ <source>Dedicated pool that stores the object-data of the RBD.</source>
+ <target>Vyhrazený fond který uchovává objektová data RBD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151c80ea931037cd92e854442927f8a0f6ae7795" datatype="html">
+ <source>-- No data pools available --</source>
+ <target>-- Žádné fondy k dispozici --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0016bd458baa88284a658ce9eeda42d8ad88d2c" datatype="html">
+ <source>e.g., 10GiB</source>
+ <target>např. 10 GiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">206</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a88bbee20570aaf9615332fb27020627044874d" datatype="html">
+ <source>You have to increase the size.</source>
+ <target>Je třeba zvětšit.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cfe07dac5b4ee1c464eb24225ddeb4f1d24076a" datatype="html">
+ <source>Advanced...</source>
+ <target>Pokročilé…</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bc2e854e111ecf2bd7db170da5e3c2ed08181d88" datatype="html">
+ <source>Advanced</source>
+ <target>Pokročilé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3562a3778695a5f9c0445660e35301f0a39aaf73" datatype="html">
+ <source>Striping</source>
+ <target>Proužkování</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef3c3f3b5f562a5cdbe0ee2874287db1534b5958" datatype="html">
+ <source>Stripe unit</source>
+ <target>Jednotka proužku</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84471be1049006edecbcaef1a32ae0893c229c50" datatype="html">
+ <source>-- Select stripe unit --</source>
+ <target>-- Vybrat jednotku proužku --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">289</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d32c5c54c8581c774a7f467fbd4e329b15a74fa" datatype="html">
+ <source>This field is required because stripe count is defined!</source>
+ <target>Tuto kolonku je třeba vyplnit, protože je definován počet proužků!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bbf9040be7c5491d4a03f2185708f43a6582a3b" datatype="html">
+ <source>Stripe unit is greater than object size.</source>
+ <target>Jednotka proužku je vyšší než velikost objektu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a682f49f9b761591661276d7c6f550e641a130a4" datatype="html">
+ <source>Stripe count</source>
+ <target>Počet proužků</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="baa74031990c5370008ba622d0a250f0929097f4" datatype="html">
+ <source>This field is required because stripe unit is defined!</source>
+ <target>Tuto kolonku je třeba vyplnit, protože je definována jednotka proužku!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cd2ada6d5ecbd5cbf89eae0a1f5326efedac0dbc" datatype="html">
+ <source>Stripe count must be greater than 0.</source>
+ <target>Je třeba, aby počet proužků byl větší než nula.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4341718109173132593" datatype="html">
+ <source>RBD</source>
+ <target>RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1359455778569887786" datatype="html">
+ <source>Deep flatten</source>
+ <target>Hluboké zploštění</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58519213655664125" datatype="html">
+ <source>Layering</source>
+ <target>Vrstvení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844531889615887801" datatype="html">
+ <source>Exclusive lock</source>
+ <target>Výhradní zámek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4585281635594103106" datatype="html">
+ <source>Object map (requires exclusive-lock)</source>
+ <target>Mapa objektů (vyžaduje výhradní zámek)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240933649452133654" datatype="html">
+ <source>Journaling (requires exclusive-lock)</source>
+ <target>Žurnálování (vyžaduje výhradní zámek)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3713046526850391848" datatype="html">
+ <source>Fast diff (interlocked with object-map)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19f1e825536efbf7492723a7c2d01ad23a4e994b" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1774b9915b0e302d02cad0b9321ad5f1a83247a8" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c9f1026c1235f4d76ace47449e806efd181ab332" datatype="html">
+ <source>Deleting this image will also delete all its snapshots.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55f864597e84d9bf88769e1fbfda1d64452430c9" datatype="html">
+ <source>The following snapshots are currently protected and will be removed:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2e362ec498c4c9112dc47a3cb7d7250ca8e71790" datatype="html">
+ <source>RBD in status 'Removing'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3294686077659093992" datatype="html">
+ <source>Namespace</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45739481977493163" datatype="html">
+ <source>Size</source>
+ <target>Velikost</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7531602241051125940" datatype="html">
+ <source>Objects</source>
+ <target>Objekty</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1194977199378511591" datatype="html">
+ <source>Object size</source>
+ <target>Velikost objektu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">226</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="178418048502923560" datatype="html">
+ <source>Provisioned</source>
+ <target>Poskytováno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7638291694671392137" datatype="html">
+ <source>Total provisioned</source>
+ <target>Celkem poskytováno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8621797738551294959" datatype="html">
+ <source>Parent</source>
+ <target>Nadřazené</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616639680594151867" datatype="html">
+ <source>This RBD has cloned snapshots. Please delete related RBDs before deleting this RBD.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2900827028308925059" datatype="html">
+ <source>This RBD image has an invalid name and can't be managed by ceph.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1796389652493657142" datatype="html">
+ <source>Action not possible for an RBD in status 'Removing'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">476</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c07d24bb422aa8e5e568df1c5709083f0a9c8f1" datatype="html">
+ <source>Create Namespace</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cca6c0485f96d3a9610d0339cb1275a5f2c3f46" datatype="html">
+ <source>Namespace already exists.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4641528557519966449" datatype="html">
+ <source>Created namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6809428596104996786" datatype="html">
+ <source>Total images</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1346311774128536550" datatype="html">
+ <source>Deleted namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7605466414392298530" datatype="html">
+ <source>Namespace contains images</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576483965711201552" datatype="html">
+ <source>RBD Snapshot</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3473055924346204357" datatype="html">
+ <source>Parent image must support Layering</source>
+ <target>Je třeba, aby nadřazený obraz podporoval vrstvy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1152535233999495900" datatype="html">
+ <source>Snapshot must be protected in order to clone.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c5331983af566d4ac6a1024d15a3511786a4aa6" datatype="html">
+ <source>You are about to rollback</source>
+ <target>Chystáte se vrátit zpět</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6240400332778072187" datatype="html">
+ <source>PROTECTED</source>
+ <target>CHRÁNĚNO</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9101667614062185213" datatype="html">
+ <source>UNPROTECTED</source>
+ <target>NECHRÁNĚNO</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4207916966377787111" datatype="html">
+ <source>Created</source>
+ <target>Vytvořeno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587768621777516124" datatype="html">
+ <source>RBD snapshot rollback</source>
+ <target>Vrácení zachyceného stavu RBD zpět</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">305</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2711198699676132148" datatype="html">
+ <source>Rollback</source>
+ <target>Vrácení zpět</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3330476395115957823" datatype="html">
+ <source>RBD snapshot</source>
+ <target>Zachycený stav RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">322</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3a7e364a88ea4673199dfa98bc73e6dbe09dfac" datatype="html">
+ <source>Namespaces</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aba82bfd8e177d35b76cad7cd43941f8e5e5acac" datatype="html">
+ <source>Trash</source>
+ <target>Koš</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5e7f4b1ca49e8d217bd0e12c6f7d6b6a2ade2c18" datatype="html">
+ <source>Overall Performance</source>
+ <target>Celková výkonnost</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c0408946a6d67185947f455f15cc201d0d78e6" datatype="html">
+ <source>Purge Trash</source>
+ <target>Vysypat koš</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c96a761dc55a21882c132c929583a424c9b8cf4" datatype="html">
+ <source>Expired at</source>
+ <target>Platnost skončila v</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="661041e3fcff4d3e75c561e038ca2504cf2cc643" datatype="html">
+ <source>Protected until</source>
+ <target>Chráněno do</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee3b2322a1d3277f7e3fdb8a5141ac42bcf350b" datatype="html">
+ <source>This image is protected until <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5611592591303869712" datatype="html">
+ <source>Status</source>
+ <target>Stav</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">213</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">285</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2155633476201267204" datatype="html">
+ <source>Deleted At</source>
+ <target>Smazáno v</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0b5d789d42c0e69348e5fe0037fcbf5b5fbbdcc" datatype="html">
+ <source>Move an image to trash</source>
+ <target>Přesunout obraz do koše</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ad22c1d4aab3b8946603cea62de266d5129ca10" datatype="html">
+ <source>This image contains snapshot(s), which will prevent it from being removed after moved to trash.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">15,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d4a5f5698bc8118b2e120b9bb72eff339094dd0" datatype="html">
+ <source>To move <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> to trash, click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Move<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Optionally, you can pick an expiration date.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">19,20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f27d390844aad53b4240360e928156c5f0d326" datatype="html">
+ <source>Protection expires at</source>
+ <target>Platnost ochrany skončí v</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da166e9a0d27322f6ba8916d71ecc0f9905bb4b1" datatype="html">
+ <source>NOT PROTECTED</source>
+ <target>NECHRÁNĚNO</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1506e5f2ca22cad14502ec7a20fb6113ace145d" datatype="html">
+ <source>Wrong date format. Please use &quot;YYYY-MM-DD HH:mm:ss&quot;.</source>
+ <target>Chybný formát data. Použijte „RRRR-MM-DD HH:mm:ss“.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa7ea0bb7495281e0b3258467ac7d90a1e44a1a1" datatype="html">
+ <source>Protection has already expired. Please pick a future date or leave it empty.</source>
+ <target>Platnost ochrany už skončila. Zvolte budoucí datum nebo nevyplňujte.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d8613436532acac2b97d17de28b50f93e6bd0222" datatype="html">
+ <source>To purge, select  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>All<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>  or one pool and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Purge<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55a4f598a4894b7fd5cb88f0ffd3c37ad009dd70" datatype="html">
+ <source>Pool:</source>
+ <target>Fond:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d43dd2b9f7797e4cf3a604695bb33e4479108516" datatype="html">
+ <source>Pool name...</source>
+ <target>Název fondu…</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dfc3c34e182ea73c5d784ff7c8135f087992dac1" datatype="html">
+ <source>All</source>
+ <target>Vše</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0e7c7ed1d51a0c205c815048bc9f79e24ee6db2" datatype="html">
+ <source>Restore Image</source>
+ <target>Obnovit obraz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3bc4aaf0dce75dc5e01ee5c825a652dc8aea8f0" datatype="html">
+ <source>To restore  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>,  type the image's new name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Restore<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41307dd56fea669eed72e12a6c23af275f6bfd82" datatype="html">
+ <source>New Name</source>
+ <target>Nový název</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3625859417927520024" datatype="html">
+ <source>id</source>
+ <target>identif.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6537904131139019667" datatype="html">
+ <source>type</source>
+ <target>typ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8901220148451863928" datatype="html">
+ <source>state</source>
+ <target>stav</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7925190601961269841" datatype="html">
+ <source>version</source>
+ <target>verze</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6641024648411549335" datatype="html">
+ <source>Host</source>
+ <target>Stroj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773272191572353800" datatype="html">
+ <source>root</source>
+ <target>kořen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6364513948635353490" datatype="html">
+ <source>Evicted client '<x id="PH" equiv-text="clientId"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c1e17956453ad772dbe82d6946f62748c692f3e" datatype="html">
+ <source>Ranks</source>
+ <target>Hodnocení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b24e0b0b1629d2e8a51b9da7c75d6e6379f4bc4" datatype="html">
+ <source>Standbys</source>
+ <target>Pohotovosti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="50df62325726db950523a5be1c78b8905fcc25d4" datatype="html">
+ <source>MDS performance counters</source>
+ <target>čítače výkonnosti MDS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4578796959376778578" datatype="html">
+ <source>Standby daemons</source>
+ <target>Procesy služeb v pohotovosti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="665219418211496660" datatype="html">
+ <source>Rank</source>
+ <target>Hodnocení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5445409664838149993" datatype="html">
+ <source>Daemon</source>
+ <target>Proces služby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5306473977542913614" datatype="html">
+ <source>Activity</source>
+ <target>Aktivita</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3998441303515229547" datatype="html">
+ <source>Dentries</source>
+ <target>Struktury složek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7877631502958415163" datatype="html">
+ <source>Inodes</source>
+ <target>I-uzlů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6129397096478256985" datatype="html">
+ <source>Dirs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3011876564696453148" datatype="html">
+ <source>Caps</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8650499415827640724" datatype="html">
+ <source>Type</source>
+ <target>Typ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="142654590491855672" datatype="html">
+ <source>Usage</source>
+ <target>Využití</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">326</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb8293aa8161433778762ae025ffd5e7c85795e" datatype="html">
+ <source>Quotas</source>
+ <target>Kvóty</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">540</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66785722678644243" datatype="html">
+ <source>Origin</source>
+ <target>Původ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8911059720204770105" datatype="html">
+ <source>Path</source>
+ <target>Popis umístění</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6111756909052789805" datatype="html">
+ <source>Cannot create snapshots for files/folders in the subvolume <x id="PH" equiv-text="folders[2]"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7503263437025060215" datatype="html">
+ <source>Max size</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6763343019307619111" datatype="html">
+ <source>Max files</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327403486214540377" datatype="html">
+ <source>The inherited <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> is the maximum value to be used.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">434,437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3768927257183755959" datatype="html">
+ <source>Save</source>
+ <target>Uložit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">440</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6328794256834621774" datatype="html">
+ <source><x id="PH" equiv-text="action"/> CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> quota for '<x id="PH_2" equiv-text="path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">446</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9130352375983418123" datatype="html">
+ <source>size</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6889473896134264260" datatype="html">
+ <source>files</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2244434638607433133" datatype="html">
+ <source><x id="PH" equiv-text="this.getQuotaName()"/> quota <x id="PH_1" equiv-text="value"/> from '<x id="PH_2" equiv-text="path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">460</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6960117167304061503" datatype="html">
+ <source>Value has to be at least 0 or more</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">484</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6740501370117796629" datatype="html">
+ <source>Value has to be at most <x id="PH" equiv-text="maxValue"/> or less</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7239750919884229270" datatype="html">
+ <source>Updated</source>
+ <target>Aktualizováno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">499</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8885980874806414253" datatype="html">
+ <source>in order to inherit <x id="PH" equiv-text="quotaValue"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4182949309891923991" datatype="html">
+ <source>which isn't used because of the inheritance of <x id="PH" equiv-text="quotaValue"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7421970649864638435" datatype="html">
+ <source>in order to have no quota on the directory</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6730229976797004508" datatype="html">
+ <source><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">530,533</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="827679535246546876" datatype="html">
+ <source>Create Snapshot</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">542</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">552</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4747656362969857823" datatype="html">
+ <source>Please enter the name of the snapshot.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3667696812078358068" datatype="html">
+ <source>Created snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="753342836137587734" datatype="html">
+ <source>CephFs Snapshot</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">670</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2774104291801979963" datatype="html">
+ <source>Deleted snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">683</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4816216590591222133" datatype="html">
+ <source>Enabled</source>
+ <target>Zapnuto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ffe39df9d88c972792bd8688b215392deb8313d" datatype="html">
+ <source>Clients</source>
+ <target>Klienti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e213942c6354b9cbe7a650f0f1499bfc1000fb6" datatype="html">
+ <source>Directories</source>
+ <target>Složky</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fbbaf5cb02ed419e79a27072478f716a4666a99d" datatype="html">
+ <source>Performance Details</source>
+ <target>Podrobnosti o výkonnosti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0" datatype="html">
+ <source>Description</source>
+ <target>Popis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ad112ce9bcd55dfd137792a86afe1b5a5b13cf8" datatype="html">
+ <source>Long description</source>
+ <target>Podrobnější popis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="26fb5f81b3581f06b9210defb0e71dc69a67e819" datatype="html">
+ <source>Current values</source>
+ <target>Stávající hodnoty</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7cee38a2259526c519f878e71b964f41db4348" datatype="html">
+ <source>Default</source>
+ <target>Výchozí</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33e1c1d9fc05ca3f62fcc8a1170fc31ebae4229c" datatype="html">
+ <source>Daemon default</source>
+ <target>Výchozí pro proces služby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f61c6867295f3b53d23557021f2f4e0aa1d0b8fc" datatype="html">
+ <source>Type</source>
+ <target>Typ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9abcd7c82643d60c22733470463f74e4a54bc069" datatype="html">
+ <source>Min</source>
+ <target>Min</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3ced4d162a0a55ee233a187ce7208ba5e922418" datatype="html">
+ <source>Max</source>
+ <target>Max</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="920617c6a1a4805e53bcb5af6a9c76f8387e89c6" datatype="html">
+ <source>Flags</source>
+ <target>Příznaky</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5" datatype="html">
+ <source>Services</source>
+ <target>Služby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6834fa6b43d1ecbdf147c48dd9c4d72f1484571d" datatype="html">
+ <source>Source</source>
+ <target>Zdroj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a446fb0eb11fbffcac805ece5a2d306d24e733d8" datatype="html">
+ <source>Level</source>
+ <target>Úroveň</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39f2fb094e9b2eda13163fa3f3a31594cf9c1307" datatype="html">
+ <source>Can be updated at runtime (editable)</source>
+ <target>Je možné aktualizovat za provozu (upravitelné)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
+ <source>Tags</source>
+ <target>Štítky</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ab0089ef47af61ca1d137bc908b96c290dfd9287" datatype="html">
+ <source>Enum values</source>
+ <target>Vyčíslit hodnoty</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="819476f1264f1659f38e86f6abb542141b184832" datatype="html">
+ <source>See also</source>
+ <target>Viz také</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="543199344025799954" datatype="html">
+ <source>The value can be updated at runtime.</source>
+ <target>Hodnotu je možné aktualizovat za chodu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1718354829128482129" datatype="html">
+ <source>Daemons/clients do not pull this value from the
+ monitor config database. We disallow setting this option via 'ceph config
+ set ...'. This option should be configured via ceph.conf or via the
+ command line.</source>
+ <target>Procesy služeb / klienti nezískávají tuto hodnotu
+ z databáze nastavení monitoru. Není umožněno nastavit tuto volbu
+ prostřednictvím „ceph config set …'. Tato volba by měla být nastavena
+ z příkazového řádku.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">15,18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2345189734548717257" datatype="html">
+ <source>Option takes effect only during daemon startup.</source>
+ <target>Volba se uplatní pouze při spouštění procesu služby.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5523310713159993513" datatype="html">
+ <source>Option only affects cluster creation.</source>
+ <target>Volba ovlivní pouze vytváření klastru.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1064479086902933123" datatype="html">
+ <source>Option only affects daemon creation.</source>
+ <target>Volba ovlivní pouze vytvoření procesu služby.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="809b0c848932a41318f77a2aace904ef429c13f4" datatype="html">
+ <source>Values</source>
+ <target>Hodnoty</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5894f7158499fdb89527af50c9f1cf7d4c95cad6" datatype="html">
+ <source>-- Default --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="514f6e12d035a6d9b00de6b3e55c18b73488da07" datatype="html">
+ <source>true</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="774f5e6a183dea08393789b6f72e86afad729419" datatype="html">
+ <source>false</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="82029b6db704c56a2aa3e82ac555b8655356b077" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ed8b3967a7326b81b191c9f490006e6a6777a9a" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2337058106409853613" datatype="html">
+ <source>Updated config option <x id="PH" equiv-text="request.name"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3733215288982610673" datatype="html">
+ <source>Level</source>
+ <target>Úroveň</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2218082343053095278" datatype="html">
+ <source>Service</source>
+ <target>Služba</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3553216189604488439" datatype="html">
+ <source>Modified</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844248428439297756" datatype="html">
+ <source>Current value</source>
+ <target>Stávající hodnota</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208877297843037352" datatype="html">
+ <source>Editable</source>
+ <target>Upravitelné</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b266042bac4c3a2eff4834e40fb9dc4767a709" datatype="html">
+ <source>Cluster Resources</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="099b441d49333b3c6d30b36dc0a4763e64c78920" datatype="html">
+ <source>Hosts</source>
+ <target>Stroje</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57e6e608ece53a26f6d509c90ed4f83e467741af" datatype="html">
+ <source>Storage Capacity</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19ece2cb2b9097c0f75af8e62b4b3b25d399a006" datatype="html">
+ <source>Number of devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b161e3d25fd1b42a781f4e923a58a94925988ddf" datatype="html">
+ <source>Raw capacity</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb6f3e2a26f3a6f2bc33f91adcd60502dbe5adac" datatype="html">
+ <source>CPUs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58d4a9814864741040bc5905b6a368836e683f76" datatype="html">
+ <source>Memory</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dbb81e566a861d4aa0a094366e4083e50863ee92" datatype="html">
+ <source>Host Details</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="453dc2810080a744223faac6da2b3ee9ed63a583" datatype="html">
+ <source>Welcome to <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1eec874e1928ca53baa9914781ce203b5f72b0c" datatype="html">
+ <source>Please expand your cluster first</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2195fd96b0a00f560449b50bd032e6d9b357730" datatype="html">
+ <source>Expand Cluster</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb075d0450deb6f381616f7da4b9244ced843053" datatype="html">
+ <source>Skip</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55b6ce65571b8893440a4fc92776570f8fe7cc97" datatype="html">
+ <source>Add Hosts</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="162f763675c24b557a60eba0758558222369e0c7" datatype="html">
+ <source>Create OSDs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fef7a7b8db05c351c5287db48488abca530bdb54" datatype="html">
+ <source>Create Services</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="176873b4533ddeabf95992cbd7b91b9d01c6d557" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ed90ec4409b9f6b552982d96f89db27259e763c" datatype="html">
+ <source>You are about to skip the cluster expansion process. You’ll need to <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>navigate through the menu to add hosts and services.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">90,91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d1dcf2a9146caac0581329acf94806ec69a89a5" datatype="html">
+ <source>Are you sure you want to continue?</source>
+ <target>Opravdu chcete pokračovat?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6759205696902713848" datatype="html">
+ <source>Warning</source>
+ <target>Varování</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">357</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6962699013778688473" datatype="html">
+ <source>Continue</source>
+ <target>Pokračovat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6156560100092571435" datatype="html">
+ <source>Cluster expansion skipped by user</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520085823873354736" datatype="html">
+ <source>Cluster expansion was successful</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176230351113290618" datatype="html">
+ <source>Expand Cluster</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="738de688b22fba5d0dc7a5e549996838dddad0ee" datatype="html">
+ <source>CRUSH map viewer</source>
+ <target>prohlížeč CRUSH mapy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/crushmap/crushmap.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e24569eca61d598c8b01defbbbb1fa8bd5222bc" datatype="html">
+ <source>Devices</source>
+ <target>Zařízení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17137bac47e1e020d139256ded0006a671966e73" datatype="html">
+ <source>Physical Disks</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="deba10b7279a589d01e919ea11f43c79ca1773e3" datatype="html">
+ <source>Device health</source>
+ <target>Stav zařízení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d87fc20ea8e5f0f0500ba5d5061b345be78ec5e" datatype="html">
+ <source>No hostname found.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9a541ec1a4319fffc16ad3b3ab2c2b6d251a829d" datatype="html">
+ <source>Hostname</source>
+ <target>Název stroje</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee6875e67b53cac30a02b57cf76e485f7e60caf4" datatype="html">
+ <source>To add multiple hosts at once, you can enter:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a8370b19ccf673fb28fa9db36a08f9901887cc7" datatype="html">
+ <source>a comma-separated list of hostnames <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-01,example-02,example-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="68f2c05396ec8a5f59e8da42d1f6c7310fa8c37c" datatype="html">
+ <source>a range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e00b9bba448e79add37740e53dc953fbb89f9c5" datatype="html">
+ <source>a comma separated range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b3f5e5291541678f7afa49d28fad5ca848a8061" datatype="html">
+ <source>The chosen hostname is already in use.</source>
+ <target>Zvolený název stroje už je používán.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="42365f623c57973d1d13d2038e8a2d4c02fb9b9f" datatype="html">
+ <source>Network address</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3859bdca1ae89e611e214c205fccf0147b4d0f6b" datatype="html">
+ <source>The value is not a valid IP address.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2af7efecfae8d7fed3b07f718a623eca1ad8163f" datatype="html">
+ <source>Labels</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9da2afd4fa358b66d4d95fe7e8f4b659a7144e" datatype="html">
+ <source>Maintenance Mode</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="468785112451259935" datatype="html">
+ <source>There are no labels.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4664081995078497865" datatype="html">
+ <source>Filter or add labels</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4897817053917542646" datatype="html">
+ <source>Add label</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">313</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1187321380561233505" datatype="html">
+ <source>host</source>
+ <target>stroj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40661476cb24c89d8b06614998e31d5fbe84eeb6" datatype="html">
+ <source>Hosts List</source>
+ <target>Seznam strojů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b7a4e1e5a316f8547af1d6d2311a5cec8c5c1d87" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ msg }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6e8e8844e9e7a7b626a4699c08b6c0c81297a7b" datatype="html">
+ <source>Data will be available only if Orchestrator is available.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4baf526199fed59071adf555271791283adc408" datatype="html">
+ <source>SSD, NVMEs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="22d5531d79f0d7269a0a752e56a848807dd37095" datatype="html">
+ <source>Flash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4025065730478477779" datatype="html">
+ <source>The feature is disabled because the selected host is not managed by Orchestrator.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7143579180750436311" datatype="html">
+ <source>Services</source>
+ <target>Služby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="546766753072101168" datatype="html">
+ <source>Labels</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1141886420788473147" datatype="html">
+ <source>Model</source>
+ <target>Model</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4027647877328291519" datatype="html">
+ <source>CPUs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2445398473573060226" datatype="html">
+ <source>Cores</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1656823484917332451" datatype="html">
+ <source>Total Memory</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1939212557812454069" datatype="html">
+ <source>Raw Capacity</source>
+ <target>Holá kapacita</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5579687933271468638" datatype="html">
+ <source>HDDs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1889285841762768492" datatype="html">
+ <source>Flash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1578709829957887527" datatype="html">
+ <source>NICs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4723031838495967601" datatype="html">
+ <source>Edit Host: <x id="PH" equiv-text="host.hostname"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6004907173026319041" datatype="html">
+ <source>Edit Host</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5618131051466022401" datatype="html">
+ <source>Updated Host &quot;<x id="PH" equiv-text="host.hostname"/>&quot;</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1701954433367210342" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; moved to maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3108406586869160854" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; cannot be put into maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1737753151350322492" datatype="html">
+ <source><x id="PH" equiv-text="error.error['detail']"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4054533801359952167" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; has exited maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5837599005212786659" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; stopped draining</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1357236071975782353" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; started draining</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5658400717636093668" datatype="html">
+ <source>Identify</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6966707768479328825" datatype="html">
+ <source>Device path</source>
+ <target>Popis umístění zařízení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3955868613858648955" datatype="html">
+ <source>Available</source>
+ <target>K dispozici</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="158816374076721379" datatype="html">
+ <source>Vendor</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6024104799101504292" datatype="html">
+ <source>OSDs</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3422162477846071958" datatype="html">
+ <source>Identify device <x id="PH" equiv-text="device"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4910073658089977244" datatype="html">
+ <source>Please enter the duration how long to blink the LED.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5764931367607989415" datatype="html">
+ <source>1 minute</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809466133764752509" datatype="html">
+ <source>2 minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">235</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1487672983218679675" datatype="html">
+ <source>5 minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603584938775296395" datatype="html">
+ <source>10 minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6648333117195452824" datatype="html">
+ <source>15 minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6560281329999108838" datatype="html">
+ <source>Execute</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6901229416977800100" datatype="html">
+ <source>Identifying '<x id="PH" equiv-text="device"/>' started on host '<x id="PH_1" equiv-text="hostname"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d556ab48a65722b400e497f61737f553ee0f89e2" datatype="html">
+ <source>Cluster Logs</source>
+ <target>Záznamy událostí v klastra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5f966baffd188be0e8adc2d7067b86e55fc9b9de" datatype="html">
+ <source>Audit Logs</source>
+ <target>Auditní záznamy událostí</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4193c9eb868aeec119b78a14795241e0aa5e8b60" datatype="html">
+ <source>Priority:</source>
+ <target>Priorita:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d78ca51eab260ce3fd917d39190d64df5229b6e" datatype="html">
+ <source>Keyword:</source>
+ <target>Klíčové slovo:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="05fa0bded36de6e73a1fa44838b627349dace044" datatype="html">
+ <source>Date:</source>
+ <target>Datum:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a400388de1899b1917138cf7e5286376f72847" datatype="html">
+ <source>Time range:</source>
+ <target>Časový rozsah:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="de0478286b8b5a939db54e9e5282405364ad2d61" datatype="html">
+ <source>No log entries found. Please try to select different filter options.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7479674d91142b785b9547a87e5fb51cb16108" datatype="html">
+ <source>Reset filter.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="31a9c2870a934b594d1390146c489f76440859ea" datatype="html">
+ <source>Edit Manager module</source>
+ <target>Upravit modul správy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="46e09b8290d3d0afdb6baa2021395b0570606a31" datatype="html">
+ <source>The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</source>
+ <target>Zadaná hodnota není platné UUID, např.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7aacd038b39cfd347107d01d1dc27f5cb3e0951c" datatype="html">
+ <source>The entered value needs to be a valid IP address.</source>
+ <target>Je třeba, aby zadaná hodnota byla platnou IP adresou.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f19106149f4b07a0d721f9d317afed393cb7bd93" datatype="html">
+ <source>The entered value is too high! It must be lower or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d33c40ef9a6c3bf0888df831b25e41e65f9d15b" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eae7086660cf1e38c7194a2c49ff52cc656f90f5" datatype="html">
+ <source>The entered value needs to be a number.</source>
+ <target>Je třeba, aby zadaná hodnota byla číslo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">194</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a73376e04b4fb3a20734c8c39743fba32e6676ce" datatype="html">
+ <source>The entered value needs to be a number or decimal.</source>
+ <target>Je třeba, aby zadaná hodnota byla číslo nebo desítkové.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1898719236268328097" datatype="html">
+ <source>Updated options for module '<x id="PH" equiv-text="this.moduleName"/>'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4186041075388034600" datatype="html">
+ <source>Always-On</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7585826646011739428" datatype="html">
+ <source>Edit</source>
+ <target>Upravit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2180291763949669799" datatype="html">
+ <source>Enable</source>
+ <target>Zapnout</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9187855490716817910" datatype="html">
+ <source>Disable</source>
+ <target>Vypnout</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1600086764852993170" datatype="html">
+ <source>This Manager module is always on.</source>
+ <target>Modul Zpráva je vždy zapnutý.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3895296744591223546" datatype="html">
+ <source>Reconnecting, please wait ...</source>
+ <target>Opětovné připojování, čekejte…</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81b97b8ea996ad1e4f9fca8415021850214884b1" datatype="html">
+ <source>Status</source>
+ <target>Stav</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57ec6032f5618d4a9f16eb950ad23d2ce7c24b54" datatype="html">
+ <source>Cluster ID</source>
+ <target>Identif. kastru</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67d7facc3fec5f8a49ab9ba0a245872184264ce5" datatype="html">
+ <source>monmap modified</source>
+ <target>mapa monitorů změněna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4906731aaf2b94b4f547646c9bfe58bb77951b6" datatype="html">
+ <source>monmap epoch</source>
+ <target>monmap epocha</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd4ee06ffdc46d9dfbd0c0c4f81399021c680056" datatype="html">
+ <source>quorum con</source>
+ <target>kvórum spojení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1176c7db8a8276ccb44cc3d42e2c28d9fa6c6596" datatype="html">
+ <source>quorum mon</source>
+ <target>kvórum monitor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="530ef677a09d681b3ab68cb0760494b3ae72a77c" datatype="html">
+ <source>required con</source>
+ <target>vyžadováno spojení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a91558e0d506c32021c31843f8f168899fc65cbf" datatype="html">
+ <source>required mon</source>
+ <target>vyžadováno monitorů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3abe9eac5bcd94a54c8da93b312e085ec512e74" datatype="html">
+ <source>In Quorum</source>
+ <target>V kvóru</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba4b748a676e1f217ce1e736fb7ec1215e677bae" datatype="html">
+ <source>Not In Quorum</source>
+ <target>Není v kvóru</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3517477838460618200" datatype="html">
+ <source>Public Address</source>
+ <target>Veřejná adresa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6949358970125514744" datatype="html">
+ <source>Open Sessions</source>
+ <target>Otevřené relace</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4383e9662ea19839c7499b2128d43a195e564317" datatype="html">
+ <source>OSD creation preview</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="366225c51e0b00bcb1c55795a0dc5e81c455f84e" datatype="html">
+ <source>DriveGroups</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91853167141c37b58868f3b0421383dd72fa8a01" datatype="html">
+ <source>Attributes (OSD map)</source>
+ <target>Atributy (OSD mapa)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f721a500a68c357e8f2a01e60510f6a01e4ba529" datatype="html">
+ <source>Metadata</source>
+ <target>Metadata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97842f379e1d4157ac3ab0661b90c352e7cb72d5" datatype="html">
+ <source>Metadata not available</source>
+ <target>Metadata nejsou k dispozici</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24e28e19c5703d7c6be44f4eb595a6a43b618ed" datatype="html">
+ <source>Performance counter</source>
+ <target>Výkonnostní čítač</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ccb4f84edc0b4e76415bb3f9b73d725b06683af3" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ name }}"/> devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60cb3d01e5ddf266ecb4271007a1c3d0f3efdc22" datatype="html">
+ <source>The primary storage devices. These devices contain all OSD data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b432e04886d0d1fd84f740477383051f85addcf2" datatype="html">
+ <source>Write-Ahead-Log devices. These devices are used for BlueStore’s internal journal. It is only useful to use a WAL device if the device is faster than the primary device (e.g. NVME devices or SSDs). If there is only a small amount of fast storage available (e.g., less than a gigabyte), we recommend using it as a WAL device.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87e181ab9e8393aa5ed759dd3d53836e32c8ffe" datatype="html">
+ <source>DB devices can be used for storing BlueStore’s internal metadata. It is only helpful to provision a DB device if it is faster than the primary device (e.g. NVME devices or SSD).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
+ <source>Add</source>
+ <target>Přidat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="99ee4faa69cd2ea8e3678c1f557c0ff1f05aae46" datatype="html">
+ <source>Clear</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e0fd3c7af0630f93befa6234a693a32a61084e0" datatype="html">
+ <source>Raw capacity: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1961811273151129466" datatype="html">
+ <source>No available devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617271647728055571" datatype="html">
+ <source>Please add primary devices first</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6368751795251107516" datatype="html">
+ <source>Add devices by using filters</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8edc89137d0d8c5667a2f03230beafae45e58429" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eba28e1805b18f7c8ae2e4bc15dcf063b10b3822" datatype="html">
+ <source>At least one of these filters must be applied in order to proceed:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="93389aa2fe2bea50bf89554ee51b28f87ee2fb50" datatype="html">
+ <source>Number of devices: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Raw capacity: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">29,30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6b27c16ddf33b855412c82069dca8120bd3a68a" datatype="html">
+ <source>Individual OSD Flags</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dba0ed9ba355a3bd3296c0bef3bb518744a51a89" datatype="html">
+ <source>Cluster-wide</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e2a3f211cea2cbadb29b6df93e544440b6b68d3e" datatype="html">
+ <source>Restore previous selection</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1683654169791509804" datatype="html">
+ <source>No Up</source>
+ <target>Počet aktivních</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5754783193519044074" datatype="html">
+ <source>OSDs are not allowed to start</source>
+ <target>OSD není dovoleno spuštění</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4413588319909369773" datatype="html">
+ <source>No Down</source>
+ <target>Počet neaktivních</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1348746748821823470" datatype="html">
+ <source>OSD failure reports are being ignored, such that the monitors will not mark OSDs down</source>
+ <target>Hlášení o selhání OSD jsou ignorovány, jako například že monitory OSD neoznačí jako nedostupné</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="301172600132606646" datatype="html">
+ <source>No In</source>
+ <target>Počet do</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4114057962148673377" datatype="html">
+ <source>OSDs that were previously marked out will not be marked back in when they start</source>
+ <target>OSD které byly dříve odznačeny nebudou označeny nazpět když spustí</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5236523991485603657" datatype="html">
+ <source>No Out</source>
+ <target>Počet ven</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1798160169020638994" datatype="html">
+ <source>OSDs will not automatically be marked out after the configured interval</source>
+ <target>OSD nebudou automaticky odznačeny po nastaveném intervalu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3225813593817914267" datatype="html">
+ <source>The flag has been enabled for the entire cluster.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1941050626944682985" datatype="html">
+ <source>Updated OSD Flags</source>
+ <target>Aktualizovány OSD příznaky</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ef50ba2514414f799d4c8fc36067a251904ba81" datatype="html">
+ <source>Cluster-wide OSD Flags</source>
+ <target>Příznaky OSD pro celý klastr</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9042260521669277115" datatype="html">
+ <source>Pause</source>
+ <target>Pozastavit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6015425610572318971" datatype="html">
+ <source>Pauses reads and writes</source>
+ <target>Pozastavit čtení a zápisy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314873595759611676" datatype="html">
+ <source>No Scrub</source>
+ <target>Žádná kontrola</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773570234687653570" datatype="html">
+ <source>Scrubbing is disabled</source>
+ <target>Kontrola je vypnutá</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5999821123886006899" datatype="html">
+ <source>No Deep Scrub</source>
+ <target>Žádná hloubková kontrola</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5362685148875251772" datatype="html">
+ <source>Deep Scrubbing is disabled</source>
+ <target>Hloubková kontrola je vypnutá</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5001752039592388485" datatype="html">
+ <source>No Backfill</source>
+ <target>Žádné zasypávání</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4851280330655956778" datatype="html">
+ <source>Backfilling of PGs is suspended</source>
+ <target>Zasypávání skupin umístění je pozastaveno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5994953210305546559" datatype="html">
+ <source>No Rebalance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3698980403470604587" datatype="html">
+ <source>OSD will choose not to backfill unless PG is also degraded</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4334886823145076432" datatype="html">
+ <source>No Recover</source>
+ <target>Žádné obnovení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8465994741155792816" datatype="html">
+ <source>Recovery of PGs is suspended</source>
+ <target>Obnovování skupin umístění je pozastaveno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4052740759486923001" datatype="html">
+ <source>Bitwise Sort</source>
+ <target>Bitové třídění</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2330377428425572488" datatype="html">
+ <source>Use bitwise sort</source>
+ <target>Třídit podle bitů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8943478424576832224" datatype="html">
+ <source>Purged Snapdirs</source>
+ <target>Vyčištěné složky zachycených stavů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7553321860087551262" datatype="html">
+ <source>OSDs have converted snapsets</source>
+ <target>OSD mají převedené sady zachycených stavů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6509988280998256208" datatype="html">
+ <source>Recovery Deletes</source>
+ <target>Smazáno při zotavování</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="451760144355116641" datatype="html">
+ <source>Deletes performed during recovery instead of peering</source>
+ <target>Mazání provedená při obnovování namísto peeringu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="87832369463084597" datatype="html">
+ <source>PG Log Hard Limit</source>
+ <target>Nepřekročitelný limit záznamu událostí PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9135782750879343185" datatype="html">
+ <source>Puts a hard limit on pg log length</source>
+ <target>Zapne nepřekročitelný limit na délku záznamu událostí v pg</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="formTitle" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <note priority="1" from="description">Example: Create Pool</note>
+ <note priority="1" from="meaning">form title</note>
+ </trans-unit>
+ <trans-unit id="43ecf6bee2aebc07b0aad6dc1fe13e38d14687fa" datatype="html">
+ <source>Shared devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7a1c376f6f1b37de4c318ff2106255ba6c0f5b0b" datatype="html">
+ <source>WAL slots</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73811a6f37b63e6b0e491e221bfa21e9dea8a87a" datatype="html">
+ <source>How many OSDs per WAL device.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c67a7ac4762ef1cc855056c6b4daab93e53a0a5" datatype="html">
+ <source>Specify 0 to let Orchestrator backend decide it.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bda9362e06e6c67341b4a8425b0d29d6b84464b" datatype="html">
+ <source>Value should be greater than or equal to 0</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="324c2b10152b9dd908222bb0b71f61beb60a30c5" datatype="html">
+ <source>DB slots</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c23cf12ef9c76f37fc7a4b7ae3e00fb0f68b6e26" datatype="html">
+ <source>How many OSDs per DB device.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8255877266497322342" datatype="html">
+ <source>Encryption</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b49d7877d24112d4bdfce9256edf61a007fae888" datatype="html">
+ <source>OSDs List</source>
+ <target>Seznam OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="172ada0fcf6490b24a897517e9f4299215873ff8" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD(s) <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be marked <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">59,60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="262a49e60d5f6ed9825582ccf3d5ae39daa1da60" datatype="html">
+ <source>The <x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> not safe to be <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>! <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71,72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="74bd20d5f558d14cb2fa41ae863cf09c47d02018" datatype="html">
+ <source>{VAR_SELECT, select, true {OSD is} other {OSDs are}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0e217fd717c5b1f5c17f00c5b174de855acbef0" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">74,75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8cf121660bed7098516a1efe85831d6f415a9411" datatype="html">
+ <source>Preserve OSD ID(s) for replacement.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4435645098786961170" datatype="html">
+ <source>out</source>
+ <target>ven</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136018875175606726" datatype="html">
+ <source>in</source>
+ <target>dovnitř</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1301930865667956193" datatype="html">
+ <source>down</source>
+ <target>nedostupné</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1226060325201042854" datatype="html">
+ <source>Mark</source>
+ <target>Značka</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1256299033316818951" datatype="html">
+ <source>OSD lost</source>
+ <target>OSD ztraceno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2795727560928976873" datatype="html">
+ <source>marked lost</source>
+ <target>označeno jako ztracené</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7685933846431786388" datatype="html">
+ <source>Purge</source>
+ <target>Vyčistit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5941516286393808546" datatype="html">
+ <source>OSD</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3416443212235382421" datatype="html">
+ <source>purged</source>
+ <target>vyčištěno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9191368063029792986" datatype="html">
+ <source>destroy</source>
+ <target>zlikvidovat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4425946029386289247" datatype="html">
+ <source>destroyed</source>
+ <target>zlikvidováno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2870788902465061969" datatype="html">
+ <source>Flags</source>
+ <target>Příznaky</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8995035642420075344" datatype="html">
+ <source>Recovery Priority</source>
+ <target>Priorita zotavování</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3601135996773579607" datatype="html">
+ <source>PG scrub</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136079353894161076" datatype="html">
+ <source>Device class</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6382718875453721838" datatype="html">
+ <source>PGs</source>
+ <target>skupiny umístění</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3660230483843323377" datatype="html">
+ <source>Read bytes</source>
+ <target>Přečteno bajtů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">329</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3909578649547040612" datatype="html">
+ <source>Write bytes</source>
+ <target>Zapsáno bajtů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3182358405280886750" datatype="html">
+ <source>Read ops</source>
+ <target>Operací/s čtení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171292502535561083" datatype="html">
+ <source>Write ops</source>
+ <target>Operací/s zápis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6706824709967518168" datatype="html">
+ <source>Edit OSD: <x id="PH" equiv-text="selectedOsd.id"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">451</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1125148356983553148" datatype="html">
+ <source>Edit OSD</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="970212458427610374" datatype="html">
+ <source>Updated OSD '<x id="PH" equiv-text="selectedOsd.id"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">466</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7554728686176829307" datatype="html">
+ <source>Mark OSD <x id="PH" equiv-text="markAction"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="478122291463667978" datatype="html">
+ <source>Mark <x id="PH" equiv-text="markAction"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">502</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2456043080471762298" datatype="html">
+ <source>delete</source>
+ <target>smazat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">530</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="588230151780724018" datatype="html">
+ <source>deleted</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">532</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1ef1c12ddcee305353623919ef02778569f5454" datatype="html">
+ <source>Advanced configuration options</source>
+ <target>Pokročilé volby nastavení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7771252117308888928" datatype="html">
+ <source>PG scrub options</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1797901277775175680" datatype="html">
+ <source>Updated PG scrub options</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c35f9c5f268a514b970cc55e9a5dc4bed0988e7f" datatype="html">
+ <source>OSD Recovery Priority</source>
+ <target>Priorita obnovení OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74af38005e8a8914e45af2ec412e11ceafef8b6" datatype="html">
+ <source>Priority</source>
+ <target>Priorita</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f48f04b379bfba133825747adfd238d511412e" datatype="html">
+ <source>Customize priority values</source>
+ <target>Přizpůsobit hodnoty priority</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aa19de2a2b54cbda39e9c62917b23044c087776" datatype="html">
+ <source>This field is required!</source>
+ <target>Tuto kolonku je třeba vyplnit!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">406</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b699e94bf376491bd50b70a98531071c737eaf40" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="98fe13e7ad6c2b80375d204b47858ded83f80e15" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423a3c111be47fc5a1bfe46ceb58c81c84db691" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3234179038052466481" datatype="html">
+ <source>Max Backfills</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847070960491384020" datatype="html">
+ <source>Recovery Max Active</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2088615724570210504" datatype="html">
+ <source>Recovery Max Single Start</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8627094894361422565" datatype="html">
+ <source>Recovery Sleep</source>
+ <target>Uspání zotavení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7590013429208346303" datatype="html">
+ <source>Custom</source>
+ <target>Uživatelsky určené</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4937275625032609020" datatype="html">
+ <source>Updated OSD recovery speed priority '<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">227,229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5251a4355cece3075db43f15d69a24a0f8485707" datatype="html">
+ <source>Reweight OSD: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67650b2998db48201b2c6176cbfef51e7211ccaa" datatype="html">
+ <source>The value needs to be between 0 and 1.</source>
+ <target>Je třeba, aby hodnota byla mezi 0 a 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f077ceb52c967a8fe2de9ef0a9d65d72badf186" datatype="html">
+ <source>OSDs <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/>Scrub</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b73a34ba65b3073e3560dce828a16d7fd3c0f4" datatype="html">
+ <source>{VAR_SELECT, select, true {Deep } other {}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c00119503aad4012b77049eee41293338f67756c" datatype="html">
+ <source>You are about to apply a <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/>scrub to the OSD(s): <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fad3dc421817a16dd6c46c1a0c36de619a8d776e" datatype="html">
+ <source>{VAR_SELECT, select, true {deep } other {}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1086427836866943370" datatype="html">
+ <source><x id="PH" equiv-text="operation"/> was initialized in the following OSD(s): <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts</context>
+ <context context-type="linenumber">42,44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47c97aa28f64b11fa5842795fdd02c8c0863c97b" datatype="html">
+ <source>To see all active Prometheus alerts, please provide the URL to the API of Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6343323763459782070" datatype="html">
+ <source>Create Silence</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1895957424873987405" datatype="html">
+ <source>Job</source>
+ <target>Úloha</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491474782694268231" datatype="html">
+ <source>Severity</source>
+ <target>Závažnost</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3326877877555410533" datatype="html">
+ <source>Started</source>
+ <target>Zahájeno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2375260419993138758" datatype="html">
+ <source>URL</source>
+ <target>URL adresa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="880ad4df5a2051a437321443d69c9a866699e5ad" datatype="html">
+ <source>Active Alerts</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9fe218829514884cdd0ca2300573a4e0428c324f" datatype="html">
+ <source>Alerts</source>
+ <target>Výstrahy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa0c44aa1e5727061baa91e954f77e2f5f9a37c9" datatype="html">
+ <source>Silences</source>
+ <target>Ticha</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85c737325f5e59517e2d08a71de6d77788aabc95" datatype="html">
+ <source>To see all configured Prometheus alerts, please provide the URL to the API of Prometheus as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623978917681527907" datatype="html">
+ <source>Group</source>
+ <target>Skupina</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7410432243549869948" datatype="html">
+ <source>Duration</source>
+ <target>Trvání</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4109205891084963566" datatype="html">
+ <source>Query</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28f86ffd419b869711aa13f5e5ff54be6d70731c" datatype="html">
+ <source>Edit</source>
+ <target>Upravit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="826b25211922a1b46436589233cb6f1a163d89b7" datatype="html">
+ <source>Delete</source>
+ <target>Smazat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">279</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">341</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">441</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3ba06aba047605af8ea1718ec1ba153b7db12a2" datatype="html">
+ <source>Editing a silence will expire the old silence and recreate it as a new silence</source>
+ <target>Úprava ticha skončí platnost původního ticha a znovu ho vytvoří jako nové ticho</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a20424156b8816671f61879f0574a4f27d7b16b9" datatype="html">
+ <source>Creator</source>
+ <target>Tvůrce</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5a5d7ee2acbfa9c91ab7f41d26bda9ff0cafe42f" datatype="html">
+ <source>Comment</source>
+ <target>Komentář</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c11aad490b2d53fdae30b3807beabf79306752c" datatype="html">
+ <source>Start time</source>
+ <target>Čas začátku</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32856b1e8e339b747b21e313e2fe65a51fd450bb" datatype="html">
+ <source>If the start time lies in the past the creation time will be used</source>
+ <target>Pokud čas začátku leží v minulosti, bude namísto něj použit okamžik vytvoření</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a02ea1d4e7424ca989929da5e598f379940fdbf2" datatype="html">
+ <source>Duration</source>
+ <target>Trvání</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f4e35e36f4d3c62e2c17df41730b6dee4afc4b9" datatype="html">
+ <source>End time</source>
+ <target>Čas konce</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="992123459137d45c15df5548bc9682aad835c04b" datatype="html">
+ <source>Matchers</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e023166c55833d5a13f4143e3dbe372befe1b4e" datatype="html">
+ <source>A silence requires at least one matcher</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef765bd80c4806c51c891908c07a24bc76f019eb" datatype="html">
+ <source>Add matcher</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754178820914251524" datatype="html">
+ <source>silence</source>
+ <target>ticho</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8714559758543060819" datatype="html">
+ <source>Attribute name</source>
+ <target>Název atributu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1338733395833138319" datatype="html">
+ <source>Regular expression</source>
+ <target>Regulární výraz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35819898450851998" datatype="html">
+ <source>Please add your Prometheus host to the dashboard configuration and refresh the page</source>
+ <target>Přidejte hostitele s Prometheus do nastavení přehledu a znovu načtete stránku</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f2f4cb9d876ff9d34fc082c1ac642d3cb98c360" datatype="html">
+ <source>To enable Silences, please provide the URL to the API of the Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7448808151142843482" datatype="html">
+ <source>Created by</source>
+ <target>Vytvořil(a)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4734349318830134239" datatype="html">
+ <source>Ends</source>
+ <target>Končí</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1233087251567318644" datatype="html">
+ <source>Silence</source>
+ <target>Ticho</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="78af6a5e6e4d305557054b64d10f9f9446d8043d" datatype="html">
+ <source>{VAR_SELECT, select, true {Edit} other {Add}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2404fa8e80946d0ce3d0ae369b51cb26ec28d42" datatype="html">
+ <source><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/> Matcher</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c25e04f554875dc2625a78ba0fc56c6010cd0d3" datatype="html">
+ <source>-- Select an attribute to match against --</source>
+ <target>-- Vyberte atribut vůči kterému hledat shodu --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5049e204c14c648691ac775a64fb504467aeb549" datatype="html">
+ <source>Value</source>
+ <target>Hodnota</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="77fc5c63497fc031ddc97645484e3d94ad27766c" datatype="html">
+ <source>Use regular expression</source>
+ <target>Použít regulární výraz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5518753745858598442" datatype="html">
+ <source>no spec</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1186363766752354382" datatype="html">
+ <source>unmanaged</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5246585784774990516" datatype="html">
+ <source>count:<x id="PH" equiv-text="count"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001661117318762535" datatype="html">
+ <source>label:<x id="PH" equiv-text="label"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cb3aa7e9fea1d445a1a9d7797ab17e6ac6fe13b" datatype="html">
+ <source>Service Events</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3474944817987674409" datatype="html">
+ <source>Daemon type</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3136939605470297323" datatype="html">
+ <source>Daemon ID</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8171022601808215887" datatype="html">
+ <source>Container ID</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8859473568390700297" datatype="html">
+ <source>Container Image name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5623167616584404899" datatype="html">
+ <source>Container Image ID</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="335348913532561915" datatype="html">
+ <source>Last Refreshed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3022087209429182774" datatype="html">
+ <source>Daemon Events</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">140</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8604852007710946848" datatype="html">
+ <source>Service Name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="613875387304159316" datatype="html">
+ <source>Service Type</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907644935670421963" datatype="html">
+ <source>Service Events</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3214a1f3a4c3e89a848b4ec59adeeda3b913c396" datatype="html">
+ <source>-- Select a service type --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f32579a9fd19d93c083175284ee3426d78751c33" datatype="html">
+ <source>Backend Service</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2937074aed12b8158e929c58747a8216433b72b" datatype="html">
+ <source>-- No service available --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19fb4480d95a5539db4e9c7b516d414774e61110" datatype="html">
+ <source>-- Select an existing RGW service --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2798cc1e152b1ec07fd8daf94a2a073d1ba1ebcc" datatype="html">
+ <source>Id</source>
+ <target>Identif.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d5156b9d9a79d162c353c4aa9bc6840ad5c6257" datatype="html">
+ <source>The value does not match the pattern <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&lt;service_id&gt;[.&lt;realm_name&gt;.&lt;zone_name&gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83d5d7edd8a0be253c4e93ad4c3efe86d9ac520f" datatype="html">
+ <source>Unmanaged</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c15fa461935e0f600bc5d1660af1da67f024fc2a" datatype="html">
+ <source>Placement</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="863226cffd5b66a6fee9810a9282a5006d6ef576" datatype="html">
+ <source>Label</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06412bce0f4fe4311193e9763666089bf9d980da" datatype="html">
+ <source>Count</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f193722f1e788f14a823b89ac1794c3ba934f9f" datatype="html">
+ <source>Only that number of daemons will be created.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee1a29cc658e4fa891be762d7bae96139b57c8f4" datatype="html">
+ <source>The value must be at least 1.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">369</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cb2741a46e3560f6bc6dfd99d385e86b08b26d72" datatype="html">
+ <source>Port</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a23ed3598cca5285606675b6cb2536a56b411ade" datatype="html">
+ <source>The value cannot exceed 65535.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">404</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d8ebdc326e6b9ff35feee3f762b7ab39c02d78f" datatype="html">
+ <source>-- No pools available --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84b675705324741b954615fedf2417d4d873b0b6" datatype="html">
+ <source>Trusted IPs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b543e7c787cc48c2938cbce2d14c6afea5a598df" datatype="html">
+ <source>Comma separated list of IP addresses.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1039ea40da18a6453d9c1adc72a35aed099029d0" datatype="html">
+ <source>Please add the <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> IP addresses here, otherwise the iSCSI gateways can't be reached.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6265b64c17a1e19775769489bfd0b152fa1f3ba1" datatype="html">
+ <source>Virtual IP</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61893fde6e9e05a6b91619d501edaa7962b438ff" datatype="html">
+ <source>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">333</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ece04ddf7e96f445415ebd90d93c455e03e8cf53" datatype="html">
+ <source>Frontend Port</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">352</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae6fd97454d184b374984c9ff808176ece54f0dd" datatype="html">
+ <source>The port used to access the ingress service.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1261eacf161f75efc9dfea84dd97b4a466b89aa1" datatype="html">
+ <source>Monitor Port</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4df6281ed630ba96f09790a46a7fe0ec0e666bb6" datatype="html">
+ <source>The port used by haproxy for load balancer status.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ce24ae1d792ed2846ba57e7ed6397a802caeff5" datatype="html">
+ <source>CIDR Networks</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">414</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7c13184af0c09e3bad77daa5f4869138708d26b2" datatype="html">
+ <source>A list of networks to identify which network interface to use for the virtual IP address.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8fe73a4787b8068b2ba61f54ab7e0f9af2ea1fc9" datatype="html">
+ <source>Version</source>
+ <target>Verze</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a6855d17f6b9820bb9709870efdcc7da99552d3" datatype="html">
+ <source>-- Select SNMP version --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">442</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a7369891e88cd613e45a39b55a282c97776d05f5" datatype="html">
+ <source>Destination</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f09a5d334a73a4b5ba031d7fa65151cad5ec7133" datatype="html">
+ <source>Must be of the format hostname:port.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b68c79ffe3af1db88180454fbc2fa880a51ccf52" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>hostname:port<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">470</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c90ad98a026d781ab729911873767e549d78f99" datatype="html">
+ <source>Engine Id</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">478</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d39d015ebd667fb6bddf08bb0e5b3faa6cf044c" datatype="html">
+ <source>Unique identifier for the device (in hex).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">480</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514cda7dc49062c5c532427245ce47c4954bc32" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b2d628c51192ade0044212b409c758c20f9c021" datatype="html">
+ <source>Auth Protocol</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc8bb2315a5101770a752b18e03b5c730539397c" datatype="html">
+ <source>-- Select auth protocol --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">508</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6777f99fd13e03874afe26ba7289dc9fc211af04" datatype="html">
+ <source>Privacy Protocol</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70512b7c13bce85b3928920b29fafbd59a853383" datatype="html">
+ <source>-- Select privacy protocol --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b48c81465d14465b95826b99e05acfabef1814c6" datatype="html">
+ <source>Credentials</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">541</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4ea0163c25c818aab982072b1b8d5ab585e9a5a" datatype="html">
+ <source>SNMP Community</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">547</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="08c74dc9762957593b91f6eb5d65efdfc975bf48" datatype="html">
+ <source>Username</source>
+ <target>Uživatelské jméno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="948758e1412bb2ecdb98e3a4f1cbb6d7458456f2" datatype="html">
+ <source>Encryption</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">598</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e65610b5d940367f1ff6b57772b96e94e35fe202" datatype="html">
+ <source>SSL</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">624</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e37e0d06148c7708e88b4a1eb412babbe1a4afc" datatype="html">
+ <source>Certificate</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">634</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="295ae4f632322098deca8a3ddfbc7aeaabb5423b" datatype="html">
+ <source>The SSL certificate in PEM format.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">635</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464272c069fe56f6c50f41f426a25b2a42c95ba5" datatype="html">
+ <source>Invalid SSL certificate.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">650</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0596d06bf1f8a15d4bfe56226971ecdd78013b1f" datatype="html">
+ <source>Private key</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">659</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ded15dc55104994c0230189f34dff84a4955aafb" datatype="html">
+ <source>The SSL private key in PEM format.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">660</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19bdc1597d815b456793ff87c89af4257a85a103" datatype="html">
+ <source>Invalid SSL private key.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">675</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3356018487523380058" datatype="html">
+ <source>service</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2412938991511187011" datatype="html">
+ <source>There are no hosts.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2594503755408511486" datatype="html">
+ <source>Filter hosts</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5869780110608474933" datatype="html">
+ <source>Placement</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2956098160626271284" datatype="html">
+ <source>Running</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="013f48ee777d2e53e2bcba36e1a99fcbb7ef8cb6" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report configuration</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a09b723a928774bff707973c99999dcf3d84a349" datatype="html">
+ <source>The telemetry module sends anonymous data about this Ceph cluster back to the Ceph developers to help understand how Ceph is used and what problems users may be experiencing.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> This data is visualized on <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>public dashboards<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> that allow the community to quickly see summary statistics on how many clusters are reporting, their total capacity and OSD count, and version distribution trends.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> The data being reported does <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>not<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> contain any sensitive data like pool names, object names, object contents, hostnames, or device serial numbers. It contains counters and statistics on how the cluster has been deployed, the version of Ceph, the distribution of the hosts and other parameters which help the project to gain a better understanding of the way Ceph is used. The data is sent secured to <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> and <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (device report).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">14,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c95505b5a74151a0c235b19b9c41db7983205ba7" datatype="html">
+ <source>Deactivate</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19" datatype="html">
+ <source>Channels</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e25b17c0b4ef361b6a05aaec2bbd2b7e86680458" datatype="html">
+ <source>The telemetry report is broken down into several &quot;channels&quot;, each with a different type of information that can be configured below.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">32,33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380ab580741bec31346978e7cab8062d6970408d" datatype="html">
+ <source>Basic</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd898057f0add35258a5fb5c90d792c5e2147452" datatype="html">
+ <source>Includes basic information about the cluster:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da213e9ba8a86b453d04f794f58c9803f7b062b1" datatype="html">
+ <source>Capacity of the cluster</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d5fe31d9e13239bdd223d0bbd289a1b1903e86" datatype="html">
+ <source>Number of monitors, managers, OSDs, MDSs, object gateways, or other daemons</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a3eb7834b4baf412f8863d14883972897d9acb7" datatype="html">
+ <source>Software version currently being used</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34881ae65482ffa74ccb4043fb2622e48ed146d5" datatype="html">
+ <source>Number and types of RADOS pools and CephFS file systems</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="696f8f5ea7a9cf6125b9a3af160981fda363552d" datatype="html">
+ <source>Names of configuration options that have been changed from their default (but not their values)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34292940316300d09abe5e675d452fae199f626b" datatype="html">
+ <source>Crash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7620e332b7dea1e832158e85847255eb4d9e6bbc" datatype="html">
+ <source>Includes information about daemon crashes:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1aa4306a6e840fe35b70c9b07d38ce85f281cfa" datatype="html">
+ <source>Type of daemon</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4f2cbedb4b14b68bc9f390e3391445c1b6682da" datatype="html">
+ <source>Version of the daemon</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d62603cdc75645ea873fc8f7f69c32b5f4a2aa9" datatype="html">
+ <source>Operating system (OS distribution, kernel version)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84facf84a73631d66e9a4e0bc1c40097b9d14742" datatype="html">
+ <source>Stack trace identifying where in the Ceph code the crash occurred</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea64d4177bd648e1a20c92669e6857762b811d8c" datatype="html">
+ <source>Device</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4bc37bcbbcea881a269b4063b3d93dec8ee67d5" datatype="html">
+ <source>Includes information about device metrics like anonymized SMART metrics.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37de70e8ba539187d0171a38dad2a63c323096eb" datatype="html">
+ <source>Ident</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b126025440f118cd02ce78362d61a5001c27617" datatype="html">
+ <source>Includes user-provided identifying information about the cluster:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62c6e9aecff7e04ef7d36fdee4ab4fb285a7a2b5" datatype="html">
+ <source>Contact Information</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61ba9a84051b3f470122e59cf5a746552b378269" datatype="html">
+ <source>Submitting any contact information is completely optional and disabled by default.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34746fb1c7f3d2194d99652bdff89e6e14c9c4f4" datatype="html">
+ <source>Contact</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="632cac1e025b77b2d77fed16ad22a410ddacab9e" datatype="html">
+ <source>My first Ceph cluster</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3a58c8a81b9ffda26a154eae25a422c9f7de37b" datatype="html">
+ <source>Organization</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e8fda44e2c5bb51860f26cd9c2730f9ae1db9869" datatype="html">
+ <source>Organization name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d49310535abb3792d8c9c991dd0d990d73d29af" datatype="html">
+ <source>Interval</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91317562c9dfefbdd5973faf11d217f571d073c7" datatype="html">
+ <source>The module compiles and sends a new report every 24 hours by default. You can adjust this interval by setting a different number of hours.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">185,186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a12cf4cf71ef3161a024382ab542cf0eba094504" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to 8.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a92e437fac14b4010c4515b31c55a311d026a57f" datatype="html">
+ <source>Proxy</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6de03357358c7eff62aca486508bb5c2046e0669" datatype="html">
+ <source>If the cluster cannot directly connect to the configured telemetry endpoint (default telemetry.ceph.com), you can configure a HTTP/HTTPS proxy server by e.g. adding https://10.0.0.1:8080</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5687a733af051bfca97dbffba282e39fbb9b8c8f" datatype="html">
+ <source>You can also include a user:pass if needed e.g. https://ceph:telemetry@10.0.0.1:8080</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e6430c68df43ea65e4145972b01186fba40f26a" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Note:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> By clicking 'Next' you will first see a preview of the report content before you can activate the automatic submission of your data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">219,220</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d8d878f8d60905e1306c225716305a331b784c8" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report preview</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e23d0064b6474f309c74e1c928cc0920f479d9a5" datatype="html">
+ <source>Report ID <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">249,252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4060e92658964e356a0992a900c8aa811c2cfec0" datatype="html">
+ <source>A randomized UUID to identify a particular cluster over the course of several telemetry reports.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60900bc663571f852a04950a123508b106d97204" datatype="html">
+ <source>Report preview <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">267,270</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3de417f739c336284c42904552e81e8d852daecc" datatype="html">
+ <source>The actual telemetry data that will be submitted.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="933a2b6f087670ff42c95876e6ecfb2faa3e3867" datatype="html">
+ <source>I agree to my telemetry data being submitted under the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Community Data License Agreement - Sharing - Version 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">304</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8293060085588842566" datatype="html">
+ <source>The Telemetry module has been configured and activated successfully.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5380636888677486786" datatype="html">
+ <source>An Error occurred while updating the Telemetry module configuration. Please Try again</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2bcd3296d2850de762fb943060b7e086a893181" datatype="html">
+ <source>Health</source>
+ <target>Zdraví</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61e0f26d843eec0b33ff475e111b0c2f7a80b835" datatype="html">
+ <source>Statistics</source>
+ <target>Statistiky</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73caac4265ea7314ff061e5a1d78a6361a6dd3b8" datatype="html">
+ <source>Cluster Status</source>
+ <target>Stav klastru</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="624f596cc3320f5e0a0d7c7346c364e5af9bdd8c" datatype="html">
+ <source>Monitors</source>
+ <target>Monitory</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9183778f2c6473d7ccb080f651caa01faaf70c" datatype="html">
+ <source>OSDs</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c34287a0423968dac8a41463b80855a0ff789403" datatype="html">
+ <source>Managers</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="946ac5dea9921dc09d7b0a63b89535371f283b19" datatype="html">
+ <source>Object Gateways</source>
+ <target>Objektové brány</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff03fa5bcf37c4da46ad736c1f7d03f959e8ba9a" datatype="html">
+ <source>Metadata Servers</source>
+ <target>Metadata servery</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d817609ba4993eba859409ab71e566168f4d5f5a" datatype="html">
+ <source>iSCSI Gateways</source>
+ <target>iSCSI brány</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ce9dfdc6dccb28dc75a78c704e09dc18fb02dcfa" datatype="html">
+ <source>Capacity</source>
+ <target>Kapacita</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f383269db2d32cccee9e936fe549dccb9fdbf4" datatype="html">
+ <source>Raw Capacity</source>
+ <target>Holá kapacita</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498a109c6e9e94f1966de01aa0326f7f0ac6fb52" datatype="html">
+ <source>PG Status</source>
+ <target>Stav skupiny umístění</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5f8a813f91a11af99132e4beafc136cfc13d73b" datatype="html">
+ <source>PGs per OSD</source>
+ <target>Skupin umístění na OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32efd1c3f70e3c5244239de97a2cc95d98534a14" datatype="html">
+ <source>Client Read/Write</source>
+ <target>Čtení/zápis klienta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="52213660b2454d139ada3079a42ec6caf3c3c01e" datatype="html">
+ <source>Client Throughput</source>
+ <target>Propustnost klienta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="275485415092cbae3a9f3cbb786ebe283cacfdd5" datatype="html">
+ <source>Recovery Throughput</source>
+ <target>Propustnost zotavení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35416fcdf9cb33d2b299d3f2028c390454b55d02" datatype="html">
+ <source>Scrubbing</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="44ecac93d67c6a671198091c2270354f80322327" datatype="html">
+ <source><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> See <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>Logs<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for more details.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520247697658334435" datatype="html">
+ <source>Reads</source>
+ <target>Čtení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5947645586591788199" datatype="html">
+ <source>/s</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7527163811128350993" datatype="html">
+ <source>Writes</source>
+ <target>Zápisy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7684088941299429132" datatype="html">
+ <source>IOPS</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81585474102700882" datatype="html">
+ <source>Used</source>
+ <target>Použito</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">179</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8695656831075719969" datatype="html">
+ <source>Avail.</source>
+ <target>K dispozici</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6352596107300820129" datatype="html">
+ <source>Clean</source>
+ <target>Čisté</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4016774570903735270" datatype="html">
+ <source>Working</source>
+ <target>Pracující</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4467323362722952678" datatype="html">
+ <source>Unknown</source>
+ <target>Neznámé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">218</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7790772795962334429" datatype="html">
+ <source>Healthy</source>
+ <target>Zdravé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4708847204147472247" datatype="html">
+ <source>Misplaced</source>
+ <target>Chybně umístěno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3120522496446378904" datatype="html">
+ <source>Degraded</source>
+ <target>Degradováno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8047698491745405137" datatype="html">
+ <source>Unfound</source>
+ <target>Odnalezeno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81117556780777231" datatype="html">
+ <source>objects</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795e8a00db46b750113d5db93e8d97e2b3079894" datatype="html">
+ <source>For an overview of <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/> widgets click <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">21,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16bd21c1b48036d54c6a595f5cff2540cfba7f60" datatype="html">
+ <source>here</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8515973702474791807" datatype="html">
+ <source>up</source>
+ <target>aktivní</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4223604072115719661" datatype="html">
+ <source>no filesystems</source>
+ <target>žádné souborové systémy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2078241808113697591" datatype="html">
+ <source>active</source>
+ <target>aktivní</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3232506912392089107" datatype="html">
+ <source>standby</source>
+ <target>v pohotovosti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576716133013765863" datatype="html">
+ <source>standby daemons</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3629620351427988554" datatype="html">
+ <source>active daemon</source>
+ <target>aktivní proces služby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5954854563228355745" datatype="html">
+ <source>standbyReplay</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7329683463736701292" datatype="html">
+ <source>n/a</source>
+ <target>neaplikovatelné</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/not-available.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8271970016544066882" datatype="html">
+ <source><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (quorum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mon-summary.pipe.ts</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6489441800790477240" datatype="html">
+ <source>total</source>
+ <target>celkem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5965118847182332588" datatype="html">
+ <source>near full</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="268166731974484199" datatype="html">
+ <source>full</source>
+ <target>plné</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47116253e36f4e38a97ba41b2d3122c6c15ab904" datatype="html">
+ <source>Clients (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5159814115056353668" datatype="html">
+ <source>Addresses</source>
+ <target>Adresy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1811797298582428088" datatype="html">
+ <source>Access Type</source>
+ <target>Typ přístupu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3575940435199094878" datatype="html">
+ <source>Squash</source>
+ <target>Squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2944102521023817891" datatype="html">
+ <source>Cluster</source>
+ <target>Klastr</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91772203889648189" datatype="html">
+ <source>NFS Protocol</source>
+ <target>NFS protokol</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907766170797643122" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1032539711043211945" datatype="html">
+ <source>Transport</source>
+ <target>Transport</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2489852208080013495" datatype="html">
+ <source>Storage Backend</source>
+ <target>Podpůrná vrstva úložiště</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8440421106569981118" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4095248496892792741" datatype="html">
+ <source>CephFS User</source>
+ <target>CephFS uživatel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2535727951299201687" datatype="html">
+ <source>CephFS Filesystem</source>
+ <target>Souborový systém CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2169401160512036026" datatype="html">
+ <source>Security Label</source>
+ <target>Štítek zabezpečení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3671149880069127721" datatype="html">
+ <source>Object Gateway</source>
+ <target>Objektová brána</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1643028261508790" datatype="html">
+ <source>Object Gateway User</source>
+ <target>Uživatel objektové brány</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2dae0bda66f6a349444951c0379c28cda47d6d1" datatype="html">
+ <source>Any client can access</source>
+ <target>Přistupovat může libovolný klient</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7882f2edb1d4139800b276b6b0bbf5ae0b2234ef" datatype="html">
+ <source>Addresses</source>
+ <target>Adresy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f3f74c0f6925826cb2188576391c0da01a23f0" datatype="html">
+ <source>Must contain one or more comma-separated values</source>
+ <target>Je třeba, aby obsahovalo jednu nebo více čárkou oddělovaných hodnot</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb5b2073697f3f4378c44a49b7524934c9268f4" datatype="html">
+ <source>For example:</source>
+ <target>Například:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f969c655b3fbe4fba7e277caf4cd2c459f9fca5" datatype="html">
+ <source>Access Type</source>
+ <target>Typ přístupu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28952831a284cfe2b4fc39ca610e80b52598905a" datatype="html">
+ <source>Squash</source>
+ <target>Squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0660ae339068979854ade34a96546980723dede3" datatype="html">
+ <source>Add clients</source>
+ <target>Přidat klienty</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8571141481686087364" datatype="html">
+ <source>(inherited from global config)</source>
+ <target>(převzato z globálního nastavení)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3563954518111128118" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- Vyberte typ přístupu --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3802199399355755843" datatype="html">
+ <source>inherited from global config</source>
+ <target>převzato z globálního nastavení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8729531250118136719" datatype="html">
+ <source>-- Select what kind of user id squashing is performed --</source>
+ <target>-- Vyberte jaký druh squashování identifikátor uživatele je prováděn --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4d1dd59b039ad818d9da7e29a773e10e41d9821" datatype="html">
+ <source>Cluster</source>
+ <target>Klastr</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="625f8f0f3e5b7c92651606d77484ff3d07b3c12b" datatype="html">
+ <source>This is the ID of an NFS Service.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="135b91a2d908d5814b782695470a6a786c99d9d2" datatype="html">
+ <source>-- No cluster available --</source>
+ <target>-- Žádný klastr k dispozici --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c501dba379f566885919240ea277b5bc10c14d18" datatype="html">
+ <source>-- Select the cluster --</source>
+ <target>-- Vyberte klastr --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7bd3ad665c398c7fe97230ab59e67370653a82" datatype="html">
+ <source>This field is required. To create a new NFS cluster, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>add a new NFS Service<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">41,43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3f6ba7fe84d6508705cdfe234f0fcc8ff85c9cf" datatype="html">
+ <source>Storage Backend</source>
+ <target>Podpůrná vrstva úložiště</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6fee356d1db954255a56d8169405a89595246b9" datatype="html">
+ <source>-- Select the storage backend --</source>
+ <target>-- Vyberte podpůrnou vrstvu úložiště --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3c2793dd2ef56954f872142d5ec1becb84c0fe1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="796e42bec8a6996607cf1f3e80235b86d695804a" datatype="html">
+ <source>Volume</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee3ba0ab5f0ccd597b3e44021c71e9aaad14df0a" datatype="html">
+ <source>-- No CephFS filesystem available --</source>
+ <target>-- Žádný souborový systém CephFS k dispozici --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="764c57812558b1ae66c5eec95d7efd2b1bf761e3" datatype="html">
+ <source>-- Select the CephFS filesystem --</source>
+ <target>-- Vyberte CephFS souborový systém --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="957512d0321f73e9f115bce1bd823fa635170c41" datatype="html">
+ <source>Security Label</source>
+ <target>Štítek zabezpečení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="65ce0fa4da1ed55e658aeb31d1644a29f06bb342" datatype="html">
+ <source>Enable security label</source>
+ <target>Zapnout štítek zabezpečení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e808f804130c7b6ff719509cbc06ebb27393a48" datatype="html">
+ <source>CephFS Path</source>
+ <target>Popis umístění CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1338c2f83e49ea7f2fc04e9fe90c5d330b7a10f" datatype="html">
+ <source>A path in a CephFS file system.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ecc0107badb6625466aaa3f975b5c05276f432f" datatype="html">
+ <source>Path need to start with a '/' and can be followed by a word</source>
+ <target>Je třeba, aby popis umístění začínal na „/“, za kterým následuje slovo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f9d8bd873c34c5ab2d4d0cf995fe5183ab25f6e" datatype="html">
+ <source>The path does not exist in the selected volume.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd197d7773cef10f368f08c53b47979c3df1f22d" datatype="html">
+ <source>Bucket</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ca90b4b16347ef7017967915e8624472976c85c" datatype="html">
+ <source>The bucket does not exist or is not in the default realm (if multiple realms are configured). To continue, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>create a new bucket<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bee6900143996c0e908a10564532eba3da0b30fb" datatype="html">
+ <source>NFS Protocol</source>
+ <target>NFS protokol</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5043c0921e709935ab026bb3253ffe1f159fca1" datatype="html">
+ <source>NFSv4</source>
+ <target>NFSv4</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d2c39708a32910f89701dd7e1cfb9ec1c195768" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1f8be2ae25947bec0b84c2338201580ea053f34e" datatype="html">
+ <source>The position that this <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> export occupies in the <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo FS<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (it must be unique).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">241,242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3af55f7fd5b1d9e5a53e030c80116dc635bfb9f" datatype="html">
+ <source>By using different Pseudo options, the same Path may be exported multiple times.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5eb719aa900fed3f9d4a1d74bcc158f07f67f684" datatype="html">
+ <source>The pseudo is already in use by another export.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddf98fcdeeb17643db020d54f42b5e56b5f9a52a" datatype="html">
+ <source>Pseudo needs to start with a '/' and can't contain any of the following: &gt;, &lt;, |, &amp;, ( or ).</source>
+ <target>Je třeba, aby Pseudo začínalo na „/“ a a nemůže obsahovat nic z následujícího: &gt;, &lt;, |, &amp;, ( nebo ).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="27eb35c4b4ac08781a7253a2ab40f8f7d957ba51" datatype="html">
+ <source>-- No access type available --</source>
+ <target>-- Žádný typ přístupu k dispozici --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">280</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="509ce016c9110a54028dafd741f15ceacbe74b5a" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- Vyberte typ přístupu --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67ce207d0b7eada1fe3d3187a39ba0c07be76b6c" datatype="html">
+ <source>The Object Gateway NFS backend has a number of limitations which will seriously affect applications writing to the share. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> for details before enabling write access.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">293,296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4deda03573eaaff77e63f6a238a1f0ca7816950a" datatype="html">
+ <source>-- No squash available --</source>
+ <target>-- Žádné squash k dispozici --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">321</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a0e82a4da88e7fdf270444f838d45849676e9d4b" datatype="html">
+ <source>--Select what kind of user id squashing is performed --</source>
+ <target>-- Vyberte jaký druh squashování identifikátor uživatele je prováděn --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d01b7c3f7f06712c53d054cfbe4f53d446b038e8" datatype="html">
+ <source>Transport Protocol</source>
+ <target>Transportní protokol</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2a6ad6e8bc315f07911722c05767ac79c136d99" datatype="html">
+ <source>UDP</source>
+ <target>UDP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">349</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c030f11e0aae9b24d2c048c57f29f590be621df" datatype="html">
+ <source>TCP</source>
+ <target>TCP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">359</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f84d7fd4d52eb5b2229b632ef5119dac63d5597" datatype="html">
+ <source>No user id squashing is performed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">378</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb1d148107e36852325106a518385b1b0de28835" datatype="html">
+ <source>uid 0 and gid 0 are squashed to the Anonymous_Uid and Anonymous_Gid gid 0 in alt_groups lists is also squashed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">382</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1309d6f67955799863337b201413faa61a175ddb" datatype="html">
+ <source>uid 0 and gid of any value are squashed to the Anonymous_Uid and Anonymous_Gid alt_groups lists is discarded.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85f23d5c9b57dc78dda4150d13aa3b99e985350b" datatype="html">
+ <source>All users are squashed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2691935247101074756" datatype="html">
+ <source>NFS export</source>
+ <target>NFS export</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8727258243239498387" datatype="html">
+ <source><x id="PH" equiv-text="fsalItem.descr"/> backend is not available. <x id="PH_1" equiv-text="errorMessage"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2772848515253260635" datatype="html">
+ <source>Error while retrieving paths.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5239928491238988595" datatype="html">
+ <source>Error while retrieving bucket names.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="734c9905951a774870497c5aaae8e3ee833b6196" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2190548d236ca5f7bc7ab2bca334b860c5ff2ad4" datatype="html">
+ <source>Object Gateway</source>
+ <target>Objektová brána</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca53d681a9892d6fdbb57ee9676582186515e961" datatype="html">
+ <source>Performance counters not available</source>
+ <target>Výkonnostní čítače nejsou k dispozici</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="490e15ecc922965b6d8194754c87c5583aa071f3" datatype="html">
+ <source>The name can only consist of alphanumeric characters, dashes and underscores.</source>
+ <target>Název může být tvořen pouze písmeny a číslicemi, dále ještě spojovníky a podtržítky.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9edc2b494e660618af3e5225f68d40b7ca67629c" datatype="html">
+ <source>The chosen erasure code profile name is already in use.</source>
+ <target>Zvolený název pro profil mazacího kódu je už používán.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35a4206db3105ed03e0dd799e1642b75b78123e8" datatype="html">
+ <source>Root</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf425784c7073c7e7f7c1bb90c2c19db7e751db2" datatype="html">
+ <source>Failure domain type</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72396a9565cf644d1fe1b21b790c4243ee270986" datatype="html">
+ <source>Device class</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d80e0c07bfea1b693a33ef2245007de92a6780" datatype="html">
+ <source>Let Ceph decide</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101611937243846632" datatype="html">
+ <source>Crush Rule</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef9ff0e6227947b48dfab4ac39ade04af758913b" datatype="html">
+ <source>Plugin</source>
+ <target>Zásuvný modul</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd69b31bce8f630eac1d4762b0bbcf72ce19d193" datatype="html">
+ <source>Data chunks (k)</source>
+ <target>Shluky dat (k)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0d26a6172d32cb81218fe2103c54a818cbc1189" datatype="html">
+ <source>Must be equal to or greater than 2.</source>
+ <target>Je třeba, aby bylo 2 a více.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ba6f4800642eba4e8b056aa7167554c3afa8db0" datatype="html">
+ <source>Chunks (k+m) have exceeded the available OSDs of <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="86fca2f788ce986eef835cd7ef8dfc9ae22447a4" datatype="html">
+ <source>For an equal distribution k has to be a multiple of (k+m)/l.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8dd4bc172f1adc4afadaec291e465b082909148d" datatype="html">
+ <source>K has to be equal to or greater than m in order to recover data correctly through c.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2e5b0e6d0dba31c59f946392699a0a6c4dd9b83" datatype="html">
+ <source>Distribution factor: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dab3a299ead121169b8e08ed618c3b6a2f66691b" datatype="html">
+ <source>Coding chunks (m)</source>
+ <target>Shluky kódování (m)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e2773e5bd4948193f18f2361d663ecc3988c656" datatype="html">
+ <source>Must be equal to or greater than 1.</source>
+ <target>Je třeba, aby bylo 1 a více.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">146</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cde4c945a49a260c0a47bcc7cd956846930a5f7" datatype="html">
+ <source>Durability estimator (c)</source>
+ <target>Odhadování odolnosti (c)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ec9ff9931f8ea1201792d6a01bf9a47b283d692" datatype="html">
+ <source>C has to be equal to or lower than m as m defines the amount of chunks that can be used.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35594fe66657ea07b5b5f560927f78e81a229996" datatype="html">
+ <source>Helper chunks (d)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0c250a8d281291273ed3504ade19ca6537e4d9a" datatype="html">
+ <source>Set d manually or use the plugin's default calculation that maximizes d.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4304a5cd95742db0f81c3bdf29aa96bf3b0ca13d" datatype="html">
+ <source>D is automatically updated on k and m changes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06a67d52427b12df2b3d439be0e1342ac72aeb5c" datatype="html">
+ <source>D can be set from <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> to <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4f8831d3bd6401e87710c4e3ee844f5efbf5de3" datatype="html">
+ <source>D can only be set to <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5d7aacffce2c6032c3ae9ef4d1b3847a926440b" datatype="html">
+ <source>D has to be greater than k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fd745d614884edc23c7ac9ad8aba9655f3793ac2" datatype="html">
+ <source>D has to be lower than k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">199</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af668c2a095a979ea2b4e43cd82c2120ab56c21c" datatype="html">
+ <source>Locality (l)</source>
+ <target>Umístění (l)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="200fea08b63ae8d60cdbf33ffd2636159e87dc1e" datatype="html">
+ <source>Can't split up chunks (k+m) correctly with the current locality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319ac5d692d11da686782159bd70e0b705c228ed" datatype="html">
+ <source>Locality groups: <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">230</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d455a110bf6d2235e314e295ce1dfeee93d3dff2" datatype="html">
+ <source>Crush failure domain</source>
+ <target>Doména selhání crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74a495f041f7dd102eee5c0bbc9e03083b538ae" datatype="html">
+ <source>Crush Locality</source>
+ <target>Lokalita crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2f14a73f7a6e94479f67423cc51102da8d6f524" datatype="html">
+ <source>None</source>
+ <target>Žádné</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="363a99d62822b92913a4cce196d47f32c1258e2f" datatype="html">
+ <source>Scalar mds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2981733b912b693a9dd9d915d6d34f4692cc874a" datatype="html">
+ <source>Technique</source>
+ <target>Technika</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0098b6e47b04ec817361f384ce81d454ba5c0bb" datatype="html">
+ <source>Packetsize</source>
+ <target>Velikostpaketu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0252cd81ca54d0a2f69ec9ccf4248e73df5aa4a" datatype="html">
+ <source>Crush root</source>
+ <target>Kořen crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">351</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1548d5c76f0406ddd1ba3c557e1e6db22e95b340" datatype="html">
+ <source>Crush device class</source>
+ <target>Třída crush zařízení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3f657ffa19dc6ac504b83c86209709522dcf065" datatype="html">
+ <source>Available OSDs: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03d84645f6e019c5a43909bbf2ea1696ee88332c" datatype="html">
+ <source>Directory</source>
+ <target>Složka</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1354845268685595937" datatype="html">
+ <source>EC Profile</source>
+ <target>EC profil</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3938a411d76796f8ae73b72ea4c77661207453bd" datatype="html">
+ <source>Cache Tiers Details</source>
+ <target>Podrobnosti o stupních mezipaměti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="991790413700941336" datatype="html">
+ <source>Cache Mode</source>
+ <target>Režim mezipaměti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9133265273798382582" datatype="html">
+ <source>Min Evict Age</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7172092927403263656" datatype="html">
+ <source>Min Flush Age</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8096695869347792608" datatype="html">
+ <source>Target Max Bytes</source>
+ <target>Nejvýše bajtů cíle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8854126142886240282" datatype="html">
+ <source>Target Max Objects</source>
+ <target>Nejvýše objektů cíle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617215542453015899" datatype="html">
+ <source>No applications added</source>
+ <target>Nebyla přidána žádná aplikace</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4895689494338215646" datatype="html">
+ <source>Applications limit reached</source>
+ <target>Dosažen limit aplikací</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7322343326526084293" datatype="html">
+ <source>A pool can only have up to four applications definitions.</source>
+ <target>Fond může mít nejvýše čtyři definice aplikací.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1393735257943344790" datatype="html">
+ <source>Allowed characters '_a-zA-Z0-9'</source>
+ <target>Použitelné znaky „_a-zA-Z0-9“</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5520683885127790121" datatype="html">
+ <source>Maximum length is 128 characters</source>
+ <target>Nejvyšší délka je 128 znaků</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587418377972855060" datatype="html">
+ <source>Filter or add applications'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5188881899285829380" datatype="html">
+ <source>Add application</source>
+ <target>Přidat aplikaci</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16e113230b6b0d3165e076300880542bac7c8138" datatype="html">
+ <source>The chosen Ceph pool name is already in use.</source>
+ <target>Zvolený název pro Ceph fond je už používán.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c75b132bef7b29fa5171768303c4b96e34ccaf68" datatype="html">
+ <source>It's not possible to create an RBD pool with '/' in the name. Please change the name or remove 'rbd' from the applications list.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">34,35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="171dc6d5c6bc4615d99778b0088cae80fd00bd10" datatype="html">
+ <source>Pool name can only contain letters, numbers, '.', '-', '_' or '/'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b85c657469e5ec8231c3de99b22f437bc01ffde5" datatype="html">
+ <source>Pool type</source>
+ <target>Typ fondul</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="526c5443254c3b126eedb264840ffe827727bfd3" datatype="html">
+ <source>-- Select a pool type --</source>
+ <target>-- Vybrat typ fondu --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abfbe47b630929d93c7343dc154599c2e59330a" datatype="html">
+ <source>PG Autoscale</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0aa21053410a94aa61d16985a4e95fd65523430d" datatype="html">
+ <source>Placement groups</source>
+ <target>Skupiny umístění</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6301f1391d726f8f450bb358058534db19541ca9" datatype="html">
+ <source>At least one placement group is needed!</source>
+ <target>Je třeba alespoň jedné skupiny umístění!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba9469a1ce6ed36e039c1f67247c8c81a5c71449" datatype="html">
+ <source>Your cluster can't handle this many PGs. Please recalculate the PG amount needed.</source>
+ <target>Váš klastr nemůže obsloužit tolik skupin umístění. Přepočítejte potřebné množství skupin umístění.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80ac68cd883369dac20688bc32b4cb33291b5e50" datatype="html">
+ <source>Calculation help</source>
+ <target>Nápověda k výpočtu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fccbd60493df26705d957ed6c02a3c447894678f" datatype="html">
+ <source>The current PGs settings were calculated for you, you should make sure the values suit your needs before submit.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">116,117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a43b2695131b48b76cebba676aba98a2bee17515" datatype="html">
+ <source>Replicated size</source>
+ <target>Replikovaná velikost</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bff144a4c4dc63b0e18fff2617d61a7ebdf2b6c" datatype="html">
+ <source>Minimum: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9c54b41f6d58a74e5d0aa3429ed0c87a482551" datatype="html">
+ <source>Maximum: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="452cf71ec44ee77428656936a6627eaf2dd3b47f" datatype="html">
+ <source>The size specified is out of range. A value from <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> to <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/> is usable.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">144,145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dda6196ffab88c1825f44a565c7b34e246e7e12f" datatype="html">
+ <source>A size of 1 will not create a replication of the object. The 'Replicated size' includes the object itself.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">148,149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c870fb00256b8a5b9cb9cd1a124e6390b9bc639" datatype="html">
+ <source>EC Overwrites</source>
+ <target>EC přebití</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f1abafaeb40ce52355ddcc24686e3cd17b64e08a" datatype="html">
+ <source>Applications</source>
+ <target>Aplikace</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9308b82fc183f710df60909f49cfc73aa5e076" datatype="html">
+ <source>CRUSH</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9de7dde00e2139cc4bd03b1837afbe72ad15a1ff" datatype="html">
+ <source>Erasure code profile</source>
+ <target>Profil mazacího kódu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39b4620e6bd444e0a57a0a5c03fa8c96d7fe5235" datatype="html">
+ <source>-- No erasure code profile available --</source>
+ <target>-- Žádný profil mazacího kódu --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498561757390d5528b263ce450d5f38efb00266d" datatype="html">
+ <source>-- Select an erasure code profile --</source>
+ <target>-- Vyberte profil mazacího kódu --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="616a2532fbaace94934f5943e381b63e2623f004" datatype="html">
+ <source>This profile can't be deleted as it is in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="994363f08f9fbfa3b3994ff7b35c6904fdff18d8" datatype="html">
+ <source>Profile</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="023d6f718770d2ea4ab8cabe26b0ec27ef967ec2" datatype="html">
+ <source>Used by pools</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">387</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1061ba5ee07a5c6af09e09330dbc29201baf2aa" datatype="html">
+ <source>Profile is not in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33150f22ce5348aa6c499bd092c3f4f3695d62cc" datatype="html">
+ <source>Crush ruleset</source>
+ <target>Sada pravidel crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">293</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">303</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c69b0bcd4698aa845d32c4c4ad488492552cb469" datatype="html">
+ <source>A new crush ruleset will be implicitly created.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="896e9987db5e9bb279e6deed5d2dff28c242ef66" datatype="html">
+ <source>There are no rules.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73a6b31116b3cc322af951daa0bafdc169e6c42e" datatype="html">
+ <source>-- Select a crush rule --</source>
+ <target>-- Vybrat crush pravidlo --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7d4894e770f8853050b1f6dd55bdd77a51a8ac6" datatype="html">
+ <source>Placement and
+ replication strategies or distribution policies that allow to
+ specify how CRUSH places data replicas.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">328,330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea91d648f92002bc9f96d9b26b735c83ca0b53c6" datatype="html">
+ <source>This rule can't be deleted as it is in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">346</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92da80699921e89fb19372e25b8d0f3b9fa427fc" datatype="html">
+ <source>Crush rule</source>
+ <target>Crush pravidlo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">365</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5489e9f96835f469f6f728a00d8efa88ea5bc940" datatype="html">
+ <source>Crush steps</source>
+ <target>Crush kroky</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc5f5496a9e50fe69e1a09784f28d94944108294" datatype="html">
+ <source>Rule is not in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="104a0e6900d1d1b0c8cf9e5947e36edb352583fc" datatype="html">
+ <source>The rule can't be used in the current cluster as it has too few OSDs to meet the minimum required OSD by this rule.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">409,410</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2208d63d5940ce656006a220102b1eb2b5e553da" datatype="html">
+ <source>Compression</source>
+ <target>Komprese</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">420</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c6f25c47da62ec597c6057a36ddfc3209811ec5" datatype="html">
+ <source>Algorithm</source>
+ <target>Algoritmus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">444</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4903231d42089325a28892c0fde1aed46b733ae6" datatype="html">
+ <source>-- No erasure compression algorithm available --</source>
+ <target>-- Žádný algoritmus komprese mazání --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d68ddb254275f8f44221e9ad6d8ceeb59ca46a6" datatype="html">
+ <source>Minimum blob size</source>
+ <target>Minimální velikost blobu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">468</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb2f176df80647137cbb02bbeb29e5dec707a400" datatype="html">
+ <source>e.g., 128KiB</source>
+ <target>např. 128 KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">477</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b7f6e53a4521c6eb3ced4c007fdd4cf80bb7707" datatype="html">
+ <source>Value should be greater than 0</source>
+ <target>Hodnota by měla být vyšší než nula</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">482</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">506</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8db98ab14b4e207ec763dfdefbc2dae367aab1cc" datatype="html">
+ <source>Value should be less than the maximum blob size</source>
+ <target>Hodnota by měla být nižší než maximální velikost blobu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151efb127a9a4dd25259a0b2055442318a141f5b" datatype="html">
+ <source>Maximum blob size</source>
+ <target>Nejvyšší velikost blobu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c656f0e346bbadf46eb1a5d20d0307a3bd20ba8" datatype="html">
+ <source>e.g., 512KiB</source>
+ <target>např. 512 KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65a24eee8a026f3b1113fe9e157e9a0dd69486" datatype="html">
+ <source>Value should be greater than the minimum blob size</source>
+ <target>Hodnota by měla být vyšší než nejnižší velikost blobu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">509</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="261ba09c4a59de83f48f52a23fd328da37e61ff4" datatype="html">
+ <source>Ratio</source>
+ <target>Poměr</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">517</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1430457a9c3c66366e51d76bf10396014c576be" datatype="html">
+ <source>Compression ratio</source>
+ <target>Kompresní poměr</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">528</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae5ce6de352cde949998fb10754459c3a4eb183b" datatype="html">
+ <source>Value should be between 0.0 and 1.0</source>
+ <target>Hodnota by měla být z rozmezí 0.0 až 1.0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d99b34162c9c34f10d0ccd8dbae83d8569c2db77" datatype="html">
+ <source>Max bytes</source>
+ <target>Nejvýše bajtů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">546</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1d14a18879c62f3f4ed705318b7164a1160e249" datatype="html">
+ <source>Leave it blank or specify 0 to disable this quota.</source>
+ <target>Pro vypnutí této kvóty nevyplňujte nebo zadejte 0 (nulu).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">572</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7565b131562ff6c5f769fdbd239a772154abdd97" datatype="html">
+ <source>A valid quota should be greater than 0.</source>
+ <target>Platná kvóta by měla být vyšší než 0 (nula).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">550</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">574</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b8bf35b66f09a301eef92ffc3cb2fd259df67ce9" datatype="html">
+ <source>Max objects</source>
+ <target>Nejvýše objektů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">570</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="95f348167622d832c5ae532b6944635c8e2ae5cb" datatype="html">
+ <source>The value should be greater or equal to 0</source>
+ <target>Hodnota by měla být vyšší nebo rovna 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">586</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1088629182722162774" datatype="html">
+ <source>pool</source>
+ <target>fond</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6215593782779198370" datatype="html">
+ <source>erasure code profile</source>
+ <target>profil mazacího kódu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4390273881304618317" datatype="html">
+ <source>crush rule</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">721</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d8a7c8aea58294a3c57c23af0468ddf0ba0c9c7" datatype="html">
+ <source>Pools List</source>
+ <target>Seznam fondů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9055665654201606988" datatype="html">
+ <source>Data Protection</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6658000829978978023" datatype="html">
+ <source>Applications</source>
+ <target>Aplikace</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5232365108332422324" datatype="html">
+ <source>PG Status</source>
+ <target>Stav skupiny umístění</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1669788723782899084" datatype="html">
+ <source>Crush Ruleset</source>
+ <target>Sada crush pravidel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7961062124768120122" datatype="html">
+ <source>Pool deletion is disabled by the mon_allow_pool_delete configuration setting.</source>
+ <target>Smazání fondu je vypnuto nastavením mon_allow_pool_delete configuration.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c" datatype="html">
+ <source>ID</source>
+ <target>Identif.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee5132a8da30e0b7f9f5c70dbc91928d17dd909" datatype="html">
+ <source>Owner</source>
+ <target>Vlastník</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c51963a9c553b29427ef783bbb69fa6634fa8c" datatype="html">
+ <source>Index type</source>
+ <target>Typ rejstříku</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e6f950a32eaea32ec7e192f9ca3d3dfe469d4ba" datatype="html">
+ <source>Placement rule</source>
+ <target>Pravidlo umístění</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6972d213e31c4ea4f887e60db99d9881bc8fcd3e" datatype="html">
+ <source>Marker</source>
+ <target>Označovač</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47b02acd2d3254d1ace1926f840523f154ebef71" datatype="html">
+ <source>Maximum marker</source>
+ <target>Nejvyšší označovač</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="092fa3a7df9168b14d3f83a77a4035e92b92ce15" datatype="html">
+ <source>Master version</source>
+ <target>Hlavní verze</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97434cc5001d407f90c7447a12d9e8e6848a2aa3" datatype="html">
+ <source>Modification time</source>
+ <target>Okamžik úpravy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90fe2e41e7fde38453ce4e619efeea9bc6adea9c" datatype="html">
+ <source>Zonegroup</source>
+ <target>Skupinazóny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="efeade5060b3add63863c24871f0830fb16b7e6d" datatype="html">
+ <source>Versioning</source>
+ <target>Verzování</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62a923f047ca49e7a4782629e91fea1ba32db68f" datatype="html">
+ <source>MFA Delete</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="649a410bd0ace333d067d8fa22f12bdbdb43533b" datatype="html">
+ <source>Bucket quota</source>
+ <target>Kvóta nádoby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">567</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f50a33d3c339f8f4a465141f8caa5d2d8c005251" datatype="html">
+ <source>Enabled</source>
+ <target>Zapnuto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">579</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cef1595d040e77cbb4466e60382028d4c2040cac" datatype="html">
+ <source>Maximum size</source>
+ <target>Nejvyšší velikost</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa6fb95c355f172bda303de1ce2f38c251a149cf" datatype="html">
+ <source>Unlimited</source>
+ <target>Neomezeno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee862a800364b4d11f9b8cb9955a28a60f840a45" datatype="html">
+ <source>Maximum objects</source>
+ <target>Nejvýše objektů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b84370895ab9eb44672f57146fa05c5947f1c0c" datatype="html">
+ <source>Locking</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c3d9d2296f7886e8289b9f623323803deacfc6" datatype="html">
+ <source>Days</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f44bdf9ab00a973bbe482e9fc450e3f67e60c0d" datatype="html">
+ <source>Bucket names can only contain lowercase letters, numbers, periods and hyphens.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eabb4db920d9f9b2480cf438468b86e1bea02a9b" datatype="html">
+ <source>The chosen name is already in use.</source>
+ <target>Zvolený název už je používán.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b06de7f834c622197e68b66a2abe893040b174c4" datatype="html">
+ <source>Bucket names must not contain uppercase characters or underscores.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abacf4af2f66d3af08c5ebe502b21b1f42ac649" datatype="html">
+ <source>Each label must start and end with a lowercase letter or a number.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a7f52e6813e0535026f61a2d6e8adc8a1d006a" datatype="html">
+ <source>Bucket names cannot be formatted as IP address.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2a2460396d35e14e7acfb4e060196a0679bdcff" datatype="html">
+ <source>Bucket labels cannot be empty and can only contain lowercase letters, numbers and hyphens.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf5c849977e0be2dbfc862d044edd323bfd9fb77" datatype="html">
+ <source>Bucket names must be 3 to 63 characters long.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e4c918357c7445fbf19a203e5f0f0ece1960b3b" datatype="html">
+ <source>-- Select a user --</source>
+ <target>-- Vybrat uživatele --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4aab1f837bc8ec222e4f25922465d1c5929a1fc" datatype="html">
+ <source>Placement target</source>
+ <target>Cíl umístění</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bae0a7fc2c9c1fde7d937a8a1a3c7e6825cf7d1" datatype="html">
+ <source>-- Select a placement target --</source>
+ <target>-- Vybrat cíl umístění --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="016d24e069e7d505a090fb8243e5cd43b35dc39b" datatype="html">
+ <source>Enables versioning for the objects in the bucket.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">151</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e6775ffd06878aa145c07359f28557f01ede04f" datatype="html">
+ <source>Multi-Factor Authentication</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29e8a5d4fb767d4ad0c762c81c6264cec4c0ba97" datatype="html">
+ <source>Delete enabled</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40fbc3ac8c1ea4ecfe62247e91f1f999ad5baf76" datatype="html">
+ <source>Enables MFA (multi-factor authentication) Delete, which requires additional authentication for changing the bucket versioning state.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24c93a8c13db46defa06ed7b5e026a3edb52b91" datatype="html">
+ <source>Token Serial Number</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6d9536c2af2e5e9a228c3e3e1809dc1fefe0149" datatype="html">
+ <source>Token PIN</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f038d51ab1645f15b0cd58f195c72a7eeebd4729" datatype="html">
+ <source>Enables locking for the objects in the bucket. Locking can only be enabled while creating a bucket.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9af1b4baa2dd8ed2bfc3cc756b12a2271c2dd793" datatype="html">
+ <source>Compliance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="edd600fa489d1b4a4448dce694ed932e52ce8fda" datatype="html">
+ <source>Governance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="218c7d6d318c51e7105309aaeb0baec9d19e4efb" datatype="html">
+ <source>The number of days that you want to specify for the default retention period that will be applied to new objects placed in this bucket.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">264</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="289b101ec12427b3ca819df9e43cc3b14fae2cc4" datatype="html">
+ <source>The entered value must be a positive integer.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48d8247c1ba2ea156109bf286c5f6dd26b4be760" datatype="html">
+ <source>Retention Days must be a positive integer.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4349284625269221231" datatype="html">
+ <source>bucket</source>
+ <target>nádoba</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6161088322338624846" datatype="html">
+ <source>Updated Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218632328857697292" datatype="html">
+ <source>Created Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c338bae89822d7eefbc9a887c458a7d8a98e55e" datatype="html">
+ <source>No Limit</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3715596725146409911" datatype="html">
+ <source>Owner</source>
+ <target>Vlastník</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5545511293826600258" datatype="html">
+ <source>Used Capacity</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1925090152473969054" datatype="html">
+ <source>Capacity Limit %</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8713861779825116442" datatype="html">
+ <source>Object Limit %</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5913880066213114620" datatype="html">
+ <source>buckets</source>
+ <target>nádoby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eeba399c4dae8d4890c27b7a2cd2dc28fcf8b5f9" datatype="html">
+ <source>Performance Counters</source>
+ <target>Výkonnostní čítače</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="479488ab6e91ecb375484edc78bee3d13467f33f" datatype="html">
+ <source>Daemons List</source>
+ <target>Seznam procesů služeb</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca2dee83bb58290d93fb0d17ee8bc9f095a4576f" datatype="html">
+ <source>Sync Performance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4378147649219625174" datatype="html">
+ <source>Zone</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6148052126949932311" datatype="html">
+ <source>Zone Group</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3840481991104643295" datatype="html">
+ <source>Realm</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1221ca97d19eaa9a7bc0c5243d5fc5befe1d2314" datatype="html">
+ <source>-- Select a type --</source>
+ <target>-- Vybrat typ --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1b8990332af18f1c5159a6061ca889bcbb28432" datatype="html">
+ <source>Permission</source>
+ <target>Oprávnění</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a08c589f82f69d892307288da14190ae1dd583d5" datatype="html">
+ <source>-- Select a permission --</source>
+ <target>-- Vybrat oprávnění --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7345972049922682356" datatype="html">
+ <source>capability</source>
+ <target>schopnost</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a94e6b2b5b834d92cceb90037d51ad6165c8b619" datatype="html">
+ <source>Tenant</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
+ <source>User ID</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b760f123248930122fc7e7b6b6bf94e376e959c8" datatype="html">
+ <source>Full name</source>
+ <target>Celé jméno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69b6ac577a19acc39fc0c22342092f327fff2529" datatype="html">
+ <source>Email address</source>
+ <target>E-mailová adresa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92f3f203270a29b3001871153f02c063484a1574" datatype="html">
+ <source>Suspended</source>
+ <target>Pozastaveno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011e20c5bbe51602d459a860fbf29b599b55edd" datatype="html">
+ <source>System</source>
+ <target>Systém</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db18a2772988415466a7f75dc42663ce78c9c1d3" datatype="html">
+ <source>Maximum buckets</source>
+ <target>Nejvýše nádob</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c4c62e8ba24601be5cfe7dc5d32c24bbbd4b53c" datatype="html">
+ <source>Subusers</source>
+ <target>Dílčí uživatelé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17bb3082e6fe5003203ef992a3714172334631a1" datatype="html">
+ <source>Capabilities</source>
+ <target>Schopnosti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32f8a0570373cacb9c56cf227502483a29d605bc" datatype="html">
+ <source>MFAs(Id)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36ad38f9c1a1485e09b67778a28af84553290ffb" datatype="html">
+ <source>User quota</source>
+ <target>Kvóta uživatele</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">473</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0bcd5ef19af0f1b814141ca8c57df623d8270088" datatype="html">
+ <source>Keys</source>
+ <target>Klíče</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2aba1e87039819aca3b70faa9aa848c12bf139ca" datatype="html">
+ <source>Show</source>
+ <target>Zobrazit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">395</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5248717555542428023" datatype="html">
+ <source>Username</source>
+ <target>Uživatelské jméno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240806681889331244" datatype="html">
+ <source>Unlimited</source>
+ <target>Neomezeno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db4e1a734518691b128ef40b939cc673f01d03a6" datatype="html">
+ <source>The value is not valid.</source>
+ <target>Hodnota není platná.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">617</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6aaf5d2a304167272ac73e3b1d1c162e16c77858" datatype="html">
+ <source>The chosen user ID is already in use.</source>
+ <target>Zvolený identif. uživatele už je používán.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="025be1d01b2f6cbd09e772a1d3de02fab0678b26" datatype="html">
+ <source>Show Tenant</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6af106b0d759fd2882e645604675c4494abfcd5b" datatype="html">
+ <source>The chosen user ID exists in this tenant.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="df441e80db2157f9d272b75de724ba4a82b96b57" datatype="html">
+ <source>This is not a valid email address.</source>
+ <target>Toto není platná e-mailová adresa.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca271adf154956b8fcb28f4f50a37acb3057ff7c" datatype="html">
+ <source>The chosen email address is already in use.</source>
+ <target>Zvolená e-mailová adresa už je používána.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="030197cebe938edf35422e92fe14183d06eb670b" datatype="html">
+ <source>Max. buckets</source>
+ <target>Nejvýše nádob</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f39256070bfc0714020dfee08895421fc1527014" datatype="html">
+ <source>Disabled</source>
+ <target>Vypnuto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c05002b0ac2040f1aede5e727e0ffd06eda819" datatype="html">
+ <source>Custom</source>
+ <target>Uživatelsky určené</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28872515cb81d197a3a1733fa546d3e0f0dd6c67" datatype="html">
+ <source>The entered value must be &gt;= 1.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="583a219c524155c2314eb06ee29162bb315272a3" datatype="html">
+ <source>S3 key</source>
+ <target>S3 klíč</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c217ee914725a37e9dd2336c721c8e63e9666bdc" datatype="html">
+ <source>Auto-generate key</source>
+ <target>Automaticky vytvořit klíč</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f1c1c0f2bce4c9f92d1a2061e8161cb0006c31a" datatype="html">
+ <source>Access key</source>
+ <target>Přístupový klíč</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b864acb67296a9819c1db0069c4c47d8b5ce8f44" datatype="html">
+ <source>Secret key</source>
+ <target>Tajný klíč</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="128d6efb51d9ddc7c0cc695a2deeca5b9523f6e4" datatype="html">
+ <source>There are no subusers.</source>
+ <target>Nejsou zde žádní dílčí uživatelé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fd6dfb8ecb982dbc3affb2c2d5414c4f5b6abd2" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">294,295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67c746c1ba9dab4351fedc4c7cba4e6d6b0dbc47" datatype="html">
+ <source>S3</source>
+ <target>S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d6819038d608623503918fb2553f53d68231ec3a" datatype="html">
+ <source>There are no keys.</source>
+ <target>Nejsou zde žádné klíče.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">377</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc1c1a7140ff6b815a95b65ee2780fdbe1b2b7a1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">356,357</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6ddb5e991a3ecd2659fb520bc5acc81b67e08ddd" datatype="html">
+ <source>Swift</source>
+ <target>Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">371</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d01eccdda47fc907c5be35bcb16d2dcd02b0270" datatype="html">
+ <source>There are no capabilities.</source>
+ <target>Nejsou zde žádné schopnosti.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5a451c4ea65a4046f0b49d489a7013abf0b5861" datatype="html">
+ <source>All capabilities are already added.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">456</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="043e2ec0036ceadd926fd5e3f93cd6f3565f3648" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">461,462</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6146e13ceca5fa5cc17b771b282fe5955f3d19fa" datatype="html">
+ <source>Unlimited size</source>
+ <target>Neomezená velikost</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">595</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6db8aa7c99fdce18edb33dde57729acede2b308" datatype="html">
+ <source>Max. size</source>
+ <target>Nejvyšší velikost</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">511</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">605</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc630b2093e880fffa19df99d5cd8b87605037f8" datatype="html">
+ <source>Unlimited objects</source>
+ <target>Neomezené objekty</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cda5a993d06f0bb10048be9d3aba6555aa9f356" datatype="html">
+ <source>Max. objects</source>
+ <target>Nejvýše objektů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">642</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="623ac50f37a26caec6fd7cd519b653e3315cba25" datatype="html">
+ <source>The entered value must be &gt;= 0.</source>
+ <target>Je třeba, aby zadaná hodnota byla 0 a vyšší.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">654</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="123010868147850959" datatype="html">
+ <source>user</source>
+ <target>uživatel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8368421344177343441" datatype="html">
+ <source>subuser</source>
+ <target>dílčí uživatel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4662015204945271252" datatype="html">
+ <source>S3 Key</source>
+ <target>S3 klíč</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9103468069826049692" datatype="html">
+ <source>Updated Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="884841609901737584" datatype="html">
+ <source>Created Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4363143805416924501" datatype="html">
+ <source>Tenant</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8301535046747035390" datatype="html">
+ <source>Full name</source>
+ <target>Celé jméno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3967269098753656610" datatype="html">
+ <source>Email address</source>
+ <target>E-mailová adresa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5851424994801012357" datatype="html">
+ <source>Suspended</source>
+ <target>Pozastaveno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208300173682032371" datatype="html">
+ <source>Max. buckets</source>
+ <target>Nejvýše nádob</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1670306451865226564" datatype="html">
+ <source>users</source>
+ <target>uživatelé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c614babd1950adb2be75df4e2c9747286d6adc" datatype="html">
+ <source>-- Select a username --</source>
+ <target>-- Vybrat uživatelské jméno --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2841767821d6b66238c34d07e413b0af67aee92" datatype="html">
+ <source>Subuser</source>
+ <target>Dílčí uživatel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd59fc25a7bd98cff3e75117c09697c8a007a514" datatype="html">
+ <source>The chosen subuser ID is already in use.</source>
+ <target>Zvolený identifikátor dílčího uživatele už je používán.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d386c357ebcbc04ed05c4babd5a03626f9b1674" datatype="html">
+ <source>read, write</source>
+ <target>číst, zapisovat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84e3e3f9a4f31a039b648c97debf95fcb20f4c4a" datatype="html">
+ <source>full</source>
+ <target>plné</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6bf81d032a2316464f9df2f0d2f3d753f89f0d3" datatype="html">
+ <source>Swift key</source>
+ <target>Swift klíč</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e0c12685d50d47448ceed9423977ef39775c037" datatype="html">
+ <source>Auto-generate secret</source>
+ <target>Automaticky vytvořit tajemství</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5091031285775138345" datatype="html">
+ <source>Subuser</source>
+ <target>Dílčí uživatel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8453697749389230205" datatype="html">
+ <source>Swift Key</source>
+ <target>Swift klíč</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ac54c18c1b520e948095c83a3a1025f02ce6dcc6" datatype="html">
+ <source>Neither hostname nor OSD ID given</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4533150758393178756" datatype="html">
+ <source>Device ID</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1291053608320944146" datatype="html">
+ <source>State of Health</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29167121133682512" datatype="html">
+ <source>Good</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8767957606064036733" datatype="html">
+ <source>Bad</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8052456228079338924" datatype="html">
+ <source>Stale</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6223439643831041743" datatype="html">
+ <source>Life Expectancy</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3144481541623761279" datatype="html">
+ <source>Prediction Creation Date</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="264574868375698540" datatype="html">
+ <source>Device Name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1419569261746199221" datatype="html">
+ <source>Daemons</source>
+ <target>Procesy služeb</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f635b3cb0600409a2ad44a5bd1863c699e6a01c" datatype="html">
+ <source>Failed to retrieve SMART data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a8a3f354bd640299068edd912f4bb5325264f250" datatype="html">
+ <source>The data received has the JSON format version 2.x and is currently incompatible with the dashboard.</source>
+ <target>Data obdržena v JSON formátu verze 2.x, což je v tuto chvíli nekompatibilní s přehledem.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="04f8a3c7e8ac610e6581960162cc15f55a16696a" datatype="html">
+ <source>No SMART data available.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a185c9b97513b3882604ea9bab60edbfac945c15" datatype="html">
+ <source>SMART overall-health self-assessment test result</source>
+ <target>výsledek SMART testu samoposouzení celkového stavu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="290e4c9ad42dc6e9176656c864a5faed8053f406" datatype="html">
+ <source>unknown</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a03d3c2e459f8f8fa7202c0fce465d6165f9e2b" datatype="html">
+ <source>passed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41435d5a5692c8e412c74deaee95d99dbd3617e1" datatype="html">
+ <source>failed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddd5dd6d930030096ea617f62c82b648a0dd9484" datatype="html">
+ <source>Device Information</source>
+ <target>Informace o zařízení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e149c483d88cfcff11d1c5db85e84af7c3149c4" datatype="html">
+ <source>No device information available for this device.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20cb12827cbe559a7b1da6fdae96041b3b5c3c55" datatype="html">
+ <source>SMART</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380295f37caea93701d071485a38ef0bdba57133" datatype="html">
+ <source>No SMART data available for this device.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5758c3f16f8749f0f4e2a787f02e8b4da246102f" datatype="html">
+ <source>SMART data is loading.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5363861031080361352" datatype="html">
+ <source>Smartctl has received an unknown argument (error code <x id="PH" equiv-text="smartData.smartctl_error_code"/>). You may be using an incompatible version of smartmontools. Version &gt;= 7.0 of smartmontools is required to successfully retrieve data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">61,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5085718566932809950" datatype="html">
+ <source>An error with error code <x id="PH" equiv-text="smartData.smartctl_error_code"/> occurred.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2091295268977103253" datatype="html">
+ <source>Raw</source>
+ <target>Nezpracované</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5963653123239768443" datatype="html">
+ <source>Threshold</source>
+ <target>Práh</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2893124970059125090" datatype="html">
+ <source>When Failed</source>
+ <target>Když se nezdařilo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5614367840516299633" datatype="html">
+ <source>Worst</source>
+ <target>Nejhorší</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d06ae77f9ec46a4cdd49e7e76c73a411aaf2ee38" datatype="html">
+ <source>Please set a new password.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8b5b3566e88438f51bd5f6caf6c090ed565ba5ed" datatype="html">
+ <source>You will be redirected to the login page afterwards.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cf42e491adc166a337a960eb84d03c0c3f677c8" datatype="html">
+ <source>The old and new passwords must be different.</source>
+ <target>Je třeba, aby původní a nové heslo nebyly stejné</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90163a3d3746819aef42e829f4446331232f3b66" datatype="html">
+ <source>Password confirmation doesn't match the new password.</source>
+ <target>Kontrolní zadání nového hesla se neshoduje.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0070e83d11da39d6f4bb95065c2675db1610b419" datatype="html">
+ <source>Username is required</source>
+ <target>Je třeba vyplnit uživatelské jméno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e20f8b8a4706526c9024cc2f39d568345d100dc" datatype="html">
+ <source>Password is required</source>
+ <target>Je třeba vyplnit heslo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f093d9574ab746b231504bd2cbb65f04bd7b00db" datatype="html">
+ <source>Log in</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5590086849807274701" datatype="html">
+ <source>Scope</source>
+ <target>Rozsah</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327592562693301723" datatype="html">
+ <source>Read</source>
+ <target>Čtení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5674286808255988565" datatype="html">
+ <source>Create</source>
+ <target>Vytvořit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4021752662928002901" datatype="html">
+ <source>Update</source>
+ <target>Aktualizovat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022070615528435141" datatype="html">
+ <source>Delete</source>
+ <target>Smazat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ea5c4d8942c00752dcc72e72949c5d9832f6399" datatype="html">
+ <source>Description...</source>
+ <target>Popis…</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70f45880fce6ac5d8e468e25e82aefbba8098cfe" datatype="html">
+ <source>Permissions</source>
+ <target>Oprávnění</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="122114774689391224" datatype="html">
+ <source>role</source>
+ <target>role</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616102757855967475" datatype="html">
+ <source>All</source>
+ <target>Vše</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4416727401284087008" datatype="html">
+ <source>Created role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3472946357042916911" datatype="html">
+ <source>Updated role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="373024661645814027" datatype="html">
+ <source>System Role</source>
+ <target>Systémová role</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753648234171918096" datatype="html">
+ <source>Deleted role '<x id="PH" equiv-text="role"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1674202514578558795" datatype="html">
+ <source>New name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4857700187193019038" datatype="html">
+ <source>Clone Role</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="748631939386170157" datatype="html">
+ <source>Cloned role '<x id="PH" equiv-text="values['newName']"/>' from '<x id="PH_1" equiv-text="name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="195c31a2f970e790231a6bb94a5e8ca0167406d9" datatype="html">
+ <source>The username already exists.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f3bdcce4b2e8c37cd7f0f6c92ef8cff34b039b8" datatype="html">
+ <source>Confirm password</source>
+ <target>Potvrzení zadání hesla</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cbb979e63ba50e0ca3adfa09cbdcaefd0853fca1" datatype="html">
+ <source>Password confirmation doesn't match the password.</source>
+ <target>Zadání hesla se neshodují.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="96621f9ed2e4ae5204564e583d2c816bedead571" datatype="html">
+ <source>Password expiration date</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48932db3801fe9d5d72a60a3e656bffd17c1c5d9" datatype="html">
+ <source>Password expiration date...</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc" datatype="html">
+ <source>Email</source>
+ <target>E-mail</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d0ec081dd61eb4f43aea269077bbe38eae87b7f9" datatype="html">
+ <source>Invalid email.</source>
+ <target>Neplatný e-mail.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9610487cbeb5796d34d8601b5ac0c0a65f9e1d19" datatype="html">
+ <source>Roles</source>
+ <target>Role</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8913c216dd506e20e412e144381d8d2a65a84359" datatype="html">
+ <source>User must change password at next logon</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0051a3479d3ba79135c16dc8cc017950a2cce821" datatype="html">
+ <source>You are about to remove &quot;user read / update&quot; permissions from your own user.</source>
+ <target>Chystáte se odebrat oprávnění „uživatel číst/aktualizovat“ svému vlastnímu účtu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af4bf9fcb256853f14cf947eb1deb8d7f176d3f9" datatype="html">
+ <source>If you continue, you will no longer be able to add or remove roles from any user.</source>
+ <target>Pokud budete pokračovat, nebudete nadále schopní přidávat nebo nebo odebírat role žádnému z uživatelů.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314291969883771319" datatype="html">
+ <source>There are no roles.</source>
+ <target>Nejsou zde žádné role.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4306072924538089180" datatype="html">
+ <source>Created user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1349763489797682899" datatype="html">
+ <source>Update user</source>
+ <target>Aktualizovat uživatele</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8688396456017237992" datatype="html">
+ <source>You were automatically logged out because your roles have been changed.</source>
+ <target>Byli jste automaticky odhlášeni protože vaše role byly změněny.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2335813072344088607" datatype="html">
+ <source>Updated user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4768749765465246664" datatype="html">
+ <source>Email</source>
+ <target>E-mail</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795890916060309463" datatype="html">
+ <source>Roles</source>
+ <target>Role</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6877445485286599988" datatype="html">
+ <source>Password expiration date</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="705657168061753072" datatype="html">
+ <source>Deleted user '<x id="PH" equiv-text="username"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="405819296611088743" datatype="html">
+ <source>Failed to delete user '<x id="PH" equiv-text="username"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8935387756949610047" datatype="html">
+ <source>You are currently logged in as '<x id="PH" equiv-text="username"/>'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0eb15f32b2b92d7f3103ef3ff032621888a8dc32" datatype="html">
+ <source>Old password</source>
+ <target>Původní heslo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229" datatype="html">
+ <source>New password</source>
+ <target>Nové heslo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ede41f01c781b168a783cfcefc6fb67d48780d9b" datatype="html">
+ <source>Confirm new password</source>
+ <target>Zopakování zadání nového hesla</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809196861118879526" datatype="html">
+ <source>password</source>
+ <target>heslo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623124197136601291" datatype="html">
+ <source>Updated user password&quot;</source>
+ <target>Aktualizované heslo uživatele&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be" datatype="html">
+ <source>Users</source>
+ <target>Uživatelé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ced3246fa3db31be0f7da06648463f29ba378fbe" datatype="html">
+ <source>Selected Object Gateway:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c53062af97ebda2a03f905698f58e524ecf8b968" datatype="html">
+ <source>Select Object Gateway</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="235c355afdcbf72953a15d7fc8d0d9e7a6619f46" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Page not Found<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aee9d027170f84774f2980537556f5099369b82" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for. The page you requested may have been changed or moved.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">22,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2b46fe9a975c6531af77fee858ccd37327980f7" datatype="html">
+ <source>Please consult the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>documentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> on how to configure and enable the <x id="INTERPOLATION" equiv-text="{{ section_info }}"/> management functionality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">26,27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9d57ca7cab78c6f0d27e0d890cb8cf1515e4e30a" datatype="html">
+ <source>Go To Dashboard</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6578397717654172779" datatype="html">
+ <source>Page Not Found</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8185335715884155108" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for.
+ The page you requested may have been changed or moved.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="143318366100741906" datatype="html">
+ <source>Access Denied</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5384670299771400832" datatype="html">
+ <source>Sorry, you don’t have permission to view this page or resource.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2424411274809083521" datatype="html">
+ <source>User Denied</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7645004872908092358" datatype="html">
+ <source>Sorry, the user does not exist in Ceph.
+ You'll be logged out from the Identity Provider when you retry logging in.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">24,25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f286db6ac9482dbf567bc491d49a6eade444895a" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7911416166208830577" datatype="html">
+ <source>Help</source>
+ <target>Nápověda</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8878700331247603166" datatype="html">
+ <source>Security</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8642696205489749843" datatype="html">
+ <source>Trademarks</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1481ecd21e760ac919a24e26cf790acd82e40199" datatype="html">
+ <source>Dashboard Settings</source>
+ <target>Nastavení přehledu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a79aab4ef674bf3f6532292107c0054302236e0f" datatype="html">
+ <source>User management</source>
+ <target>Správa uživatelů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="197e0246502ca64d0de0df0d5c2deec51d41ff45" datatype="html">
+ <source>Telemetry configuration</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85b79c9064aed1ead31ace985f31aa1363f6bdaf" datatype="html">
+ <source>Help</source>
+ <target>Nápověda</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06638e0f01d82c0786f63aa9832fbe7866b86087" datatype="html">
+ <source>documentation</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e351b40b3869a5c7d19c3d4918cb1ac7aaab95c4" datatype="html">
+ <source>API</source>
+ <target>Aplikační program. rozhraní</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a" datatype="html">
+ <source>About</source>
+ <target>O aplikaci</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="049dfd9fe6c78914ad58cf89ac6a631fca28ec74" datatype="html">
+ <source>Logged in user</source>
+ <target>Přihlášený uživatel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5022c5ae3ae921c07bf5f881e9b026b4a6708a7" datatype="html">
+ <source>Signed in as <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9" datatype="html">
+ <source>Change password</source>
+ <target>Změnit heslo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d22c795daf43877a5f708dca2bccd549eb0471d" datatype="html">
+ <source>Sign out</source>
+ <target>Odhlásit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319e0745bcbc132451569294fa2fa21bf10f555a" datatype="html">
+ <source>Toggle navigation</source>
+ <target>Zobrazit/skrýt navigaci</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f65253954b66e929a8b4d5ecaf61f9129f8cec64" datatype="html">
+ <source>Dashboard</source>
+ <target>Přehled</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c95898abff46bfac3ed6eb2afef74597e60b15c" datatype="html">
+ <source>CRUSH map</source>
+ <target>CRUSH mapa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7b2bc4b86de6e96d353f6bf2b4d793ea3a19ba0" datatype="html">
+ <source>Manager Modules</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb3d5aefff38a814b76da74371cbf02c0789a1ef" datatype="html">
+ <source>Logs</source>
+ <target>Záznamy událostí</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17fc3efe5f9fa4e0289c900cb6202265215a1a27" datatype="html">
+ <source>Monitoring</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f5d0c10614e8a34f0e2dad33a0568277c50cf69" datatype="html">
+ <source>Block</source>
+ <target>Blok</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3c2562ba992127203dcfd014010b03cb7b8113c6" datatype="html">
+ <source>Mirroring</source>
+ <target>Zrcadlení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="811c241d56601b91ef26735b770e64428089b950" datatype="html">
+ <source>iSCSI</source>
+ <target>iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a24eabd99ea5af20f5f94c4484649cd30370042b" datatype="html">
+ <source>NFS</source>
+ <target>NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5276fc60d54d667116babb723641b21281d37271" datatype="html">
+ <source>File Systems</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9515520496da83179d8b08132f00f575512a1f40" datatype="html">
+ <source>Buckets</source>
+ <target>Nádoby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a23e992f6c6e169a38b2b7338b4e5e803b52e0d" datatype="html">
+ <source>Tasks and Notifications</source>
+ <target>Úlohy a oznámení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1390461972315002349" datatype="html">
+ <source>The name of the node under which data should be placed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6575341202068728510" datatype="html">
+ <source>The type of CRUSH nodes across which we should separate replicas.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3874278445824365480" datatype="html">
+ <source>The device class data should be placed on.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="675628105428950215" datatype="html">
+ <source>Each object is split in data-chunks parts, each stored on a different OSD.</source>
+ <target>Každý objekt je rozdělen v částech shluků dat, každé uložené na jiném OSD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5128168460056151476" datatype="html">
+ <source>Compute coding chunks for each object and store them on different OSDs.
+ The number of coding chunks is also the number of OSDs that can be down without losing data.</source>
+ <target>Počítat kódovací shluky pro každý objekt a ukládat je na různých OSD.
+ Počet kódovacích shluků je také počet OSD, které mohou vypadnou, aniž dojde ke ztrátě dat.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">18,19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8826111293169381132" datatype="html">
+ <source>The jerasure plugin is the most generic and flexible plugin,
+ it is also the default for Ceph erasure coded pools.</source>
+ <target>Zásuvný modul jerasure je nejobecnější a nejpřizpůsobivější,
+ je také výchozí pro Ceph fondy kódované mazáním.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">23,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1331133460856304156" datatype="html">
+ <source>The more flexible technique is reed_sol_van : it is enough to set k
+ and m. The cauchy_good technique can be faster but you need to chose the packetsize
+ carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents
+ in the sense that they can only be configured with m=2.</source>
+ <target>Přizpůsobivější technikou je reed_sol_van: postačí nastvit k
+ a m. Technika cauchy_good technique může být rychlejší, ale je třeba pečlivě nastavit velikost
+ paketu. Všechny z reed_sol_r6_op, liberation, blaum_roth, liber8tion jsou ekvivalenty RAID6
+ v tom smyslu, že je možné je nastavit pouze s m=2.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">25,28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4577912952562931806" datatype="html">
+ <source>The encoding will be done on packets of bytes size at a time.
+ Choosing the right packet size is difficult.
+ The jerasure documentation contains extensive information on this topic.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">29,31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6471646852539810855" datatype="html">
+ <source>With the jerasure plugin, when an erasure coded object is stored on
+ multiple OSDs, recovering from the loss of one OSD requires reading from all the others.
+ For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading
+ from the eleven others to repair.
+
+ The lrc erasure code plugin creates local parity chunks to be able to recover using
+ less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create
+ an additional parity chunk for every four OSDs. When a single OSD is lost, it can be
+ recovered with only four OSDs instead of eleven.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">34,42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2619235086723330982" datatype="html">
+ <source>Group the coding and data chunks into sets of size locality. For instance,
+ for k=4 and m=2, when locality=3 two groups of three are created. Each set can
+ be recovered without reading chunks from another set.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">43,45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3298836762557512588" datatype="html">
+ <source>The type of the crush bucket in which each set of chunks defined
+ by l will be stored. For instance, if it is set to rack, each group of l chunks will be
+ placed in a different rack. It is used to create a CRUSH rule step such as step choose
+ rack. If it is not set, no such grouping is done.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">46,49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9162461669419243962" datatype="html">
+ <source>The isa plugin encapsulates the ISA library. It only runs on Intel processors.</source>
+ <target>Zásuvný modul isa obaluje knihovnu ISA. Funguje pouze na procesorech Intel.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2389282202903059852" datatype="html">
+ <source>The ISA plugin comes in two Reed Solomon forms.
+ If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.</source>
+ <target>Zásuvný modul ISA přichází ve dvou Reed Solomon podobách.
+ Pokud je nastaveno reed_sol_van, je to Vandermonde, pokud je nastaveno Cauchy, je Cauchy.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">53,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7319555444402547739" datatype="html">
+ <source>The shec plugin encapsulates the multiple SHEC library.
+ It allows ceph to recover data more efficiently than Reed Solomon codes.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">57,58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7723217930035575928" datatype="html">
+ <source>The number of parity chunks each of which includes each data chunk in its
+ calculation range. The number is used as a durability estimator. For instance, if c=2,
+ 2 OSDs can be down without losing data.</source>
+ <target>Počet paritních shluků, ze kterých každý obsahuje každý shluk dat ve svém
+ výpočetním rozsahu. Číslo je použito pro odhad odolnosti. Například, pokud c=2,
+ 2 OSD mohou vypadnou aniž by byla ztracena data.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">59,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2054101840892270818" datatype="html">
+ <source>CLAY (short for coupled-layer) codes are erasure codes designed to
+ bring about significant savings in terms of network bandwidth and disk IO when a failed
+ node/OSD/rack is being repaired.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">64,66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491096236680229427" datatype="html">
+ <source>Number of OSDs requested to send data during recovery of a single chunk.
+ d needs to be chosen such that k+1 &lt;= d &lt;= k+m-1. The larger the d, the better
+ the savings.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">67,69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2625895656705896729" datatype="html">
+ <source>scalar_mds specifies the plugin that is used as a building block
+ in the layered construction. It can be one of jerasure, isa, shec.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">70,71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6639141182731628232" datatype="html">
+ <source>technique specifies the technique that will be picked
+ within the 'scalar_mds' plugin specified. Supported techniques
+ are 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good', 'liber8tion' for jerasure, 'reed_sol_van',
+ 'cauchy' for isa and 'single', 'multiple' for shec.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">72,76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8172892264673403098" datatype="html">
+ <source>The name of the crush bucket used for the first step of the CRUSH rule.
+ For instance step take default.</source>
+ <target>Název crush nádoby sloužící jako první krok CRUSH pravidla.
+ Například krok vzít výchozí.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">80,81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1654284403437084515" datatype="html">
+ <source>Ensure that no two chunks are in a bucket with the same failure
+ domain. For instance, if the failure domain is host no two chunks will be stored on the same
+ host. It is used to create a CRUSH rule step such as step chooseleaf host.</source>
+ <target>Zajistit, aby žádné dva shluky nebyly v nádobě nacházejícící se ve stejné
+ doméně selhání. Například, pokud doména selhání je hostitel, žádné dva shluky nebudou uloženy na stejném hostiteli
+ Je použito pro vytvoření kroku CRUSH pravidla jako krok chooseleaf hostitele.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">83,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7737703816676512224" datatype="html">
+ <source>Restrict placement to devices of a specific class
+ (e.g., ssd or hdd), using the crush device class names in the CRUSH map.</source>
+ <target>Omezit umístění na zařízení určité třídy
+ (např., ssd nebo hdd), pomocí názvu crush třídy zařízení v CRUSH mapě.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9049698214199657456" datatype="html">
+ <source>Set the directory name from which the erasure code plugin is loaded.</source>
+ <target>Nastavit složku ze které načítat zásuvný modul mazacího kódu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5514060020564877279" datatype="html">
+ <source>Allows all operations</source>
+ <target>Umožnit všechny operace</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4265406815683383218" datatype="html">
+ <source>Allows only operations that do not modify the server</source>
+ <target>Umožnit pouze operace které neupraví server</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="990071930378308183" datatype="html">
+ <source>Allows no access at all</source>
+ <target>Neumožnit vůbec žádný přístup</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7286983657616285612" datatype="html">
+ <source>Please specify a filesystem volume.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8321762156640395170" datatype="html">
+ <source>The feature is disabled because Orchestrator is not available.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6718394293315494787" datatype="html">
+ <source>The Orchestrator backend doesn't support this feature.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5569418400096331461" datatype="html">
+ <source>-- Select the priority --</source>
+ <target>-- Vyberte prioritu --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="802458941707537739" datatype="html">
+ <source>Low</source>
+ <target>Nízká</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8063651736083474594" datatype="html">
+ <source>High</source>
+ <target>Vysoká</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1717753935149218245" datatype="html">
+ <source>The user list data might be stale. If needed, you can manually reload it.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/list-with-details.class.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7077550143229856452" datatype="html">
+ <source>Retrieving data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8231424898988217966" datatype="html">
+ <source>Retrieving data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2357645764289315007" datatype="html">
+ <source>Please wait...</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="232824565824302482" datatype="html">
+ <source>Displaying previously cached data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8721257977793603730" datatype="html">
+ <source>Displaying previously cached data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6731313206654246255" datatype="html">
+ <source>Could not load data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3359748695862553898" datatype="html">
+ <source>Could not load data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4836577225879717660" datatype="html">
+ <source>Please check the cluster health.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1519954996184640001" datatype="html">
+ <source>Error</source>
+ <target>Chyba</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5037437391296624618" datatype="html">
+ <source>Information</source>
+ <target>Informace</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4648900870671159218" datatype="html">
+ <source>Success</source>
+ <target>Úspěch</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3425367071066107827" datatype="html">
+ <source>Danger</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c947210e2d162b6225083d18820ab602f58cd2d" datatype="html">
+ <source>Remove the custom configuration value. The default configuration will be inherited and used instead.</source>
+ <target>Odebrat uživatelsky určenou hodnotu nastavení. Namísto toho bude převzato a použito výchozí nastavení.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="454ee9cb60b00446a8fb147fd2cc5eb836320586" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fc8a22825131e028336f60ef909ccbd96059703" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4dd200b7f9e19048cf90516843b40964f2af3fe9" datatype="html">
+ <source>Copy to Clipboard</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6110699a3562eeb15371063c0cf7f6bfd88a0209" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>?</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="549859e511ba5af0ea03fcaa620c472f08038969" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected items?</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="54839ebc827b73c9dc4e1df731c6d36a85036af7" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/>?</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2be8b7f04f0104d3fad90d079d8202b74f758b9a" datatype="html">
+ <source>Yes, I am sure.</source>
+ <target>Ano, opravdu to chci.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4523728183000855476" datatype="html">
+ <source>documentation</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/doc/doc.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3099741642167775297" datatype="html">
+ <source>Download</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/download-button/download-button.component.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1417693714872528491" datatype="html">
+ <source>This field is required.</source>
+ <target>Tuto kolonku je třeba vyplnit.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5321335688371682440" datatype="html">
+ <source>An error occurred.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5109325fb160b543f71a51e7511c00575057431" datatype="html">
+ <source>Loading panel data...</source>
+ <target>Načítání údajů panelu…</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a21acde005f80ceadb1391be1e7ff8b6d18188a0" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the monitoring functionality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a0ed4bd7b7add2a6febf7adf58d8cde5e421418" datatype="html">
+ <source>Grafana Dashboard doesn't exist. Please refer to <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to add dashboards to Grafana.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e11830040bd64804a0555de76f291d5832772d4" datatype="html">
+ <source>Grafana Time Picker</source>
+ <target>Volič čas Grafana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="238c1ba845dd7330e8088165275919a1debf1ca3" datatype="html">
+ <source>Reset Settings</source>
+ <target>Resetovat nastavení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7888499255176013171" datatype="html">
+ <source>Last 5 minutes</source>
+ <target>Uplynulých 5 minut</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6892361549797455305" datatype="html">
+ <source>Last 15 minutes</source>
+ <target>Uplynulých 15 minut</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2653641162607195423" datatype="html">
+ <source>Last 30 minutes</source>
+ <target>Uplynulých 30 minut</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4117793269024790392" datatype="html">
+ <source>Last 1 hour (Default)</source>
+ <target>Uplynulá 1 hodina (výchozí)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2645733658763754077" datatype="html">
+ <source>Last 3 hours</source>
+ <target>Uplynulé 3 hodiny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7360078715633936807" datatype="html">
+ <source>Last 6 hours</source>
+ <target>Uplynulých 6 hodin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5055313582241816303" datatype="html">
+ <source>Last 12 hours</source>
+ <target>Uplynulých 12 hodin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9186529157286281693" datatype="html">
+ <source>Last 24 hours</source>
+ <target>Uplynulých 24 hodin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4498682414491138092" datatype="html">
+ <source>Yesterday</source>
+ <target>Včera</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="929003859318769922" datatype="html">
+ <source>Today so far</source>
+ <target>Dnes doposud</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5525943133564968818" datatype="html">
+ <source>Day before yesterday</source>
+ <target>Včerejšek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6168755117727892817" datatype="html">
+ <source>Last 2 days</source>
+ <target>Uplynulé 2 dny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7574807704224200535" datatype="html">
+ <source>This day last week</source>
+ <target>Tento den minulý týden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4420128118950221234" datatype="html">
+ <source>Previous week</source>
+ <target>Předchozí týden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4063965603321223683" datatype="html">
+ <source>This week so far</source>
+ <target>Tento týden doposud</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4873149362496451858" datatype="html">
+ <source>Last 7 days</source>
+ <target>Uplynulých 7 dnů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8586908745456864217" datatype="html">
+ <source>Previous month</source>
+ <target>Předchozí měsíc</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1647573304710886499" datatype="html">
+ <source>This month so far</source>
+ <target>Tento měsíc doposud</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2949150997160654358" datatype="html">
+ <source>Last 30 days</source>
+ <target>Uplynulých 30 dnů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7469939859049484736" datatype="html">
+ <source>Last 90 days</source>
+ <target>Uplynulých 90 dnů</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847501198811458781" datatype="html">
+ <source>Last 6 months</source>
+ <target>Uplynulých 6 měsíců</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7447583558445881102" datatype="html">
+ <source>Last 1 year</source>
+ <target>Uplynulý 1 rok</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="100513227838842152" datatype="html">
+ <source>Previous year</source>
+ <target>Předchozí rok</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3650872673621947074" datatype="html">
+ <source>This year so far</source>
+ <target>Tento rok doposud</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1262816694819959075" datatype="html">
+ <source>Last 2 years</source>
+ <target>Uplynulé 2 roky</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7878813844917362690" datatype="html">
+ <source>Last 5 years</source>
+ <target>Uplynulých 5 let</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3fb5709e10166cbc85970cbff103db227dbeb813" datatype="html">
+ <source>Select a Language</source>
+ <target>Vyberte jazyk</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/language-selector/language-selector.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e52e9143145e1db5146258de81eae018a407b31" datatype="html">
+ <source>Clear notifications</source>
+ <target>Vyčistit oznámení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0b07bb6b7ff21ede439dd04eaf8872d1ecb84d8" datatype="html">
+ <source>Remove notification</source>
+ <target>Odebrat oznámení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e17a1d75189da843f541f7764f188f2b19a97df2" datatype="html">
+ <source>Duration:</source>
+ <target>Trvání:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d4b37c6675c5b436a54c43d6716eec835e1aa7f" datatype="html">
+ <source>There are no notifications.</source>
+ <target>Nejsou zde žádná oznámení.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b20e42ac4354d449f2718428b5390933eef0c1b9" datatype="html">
+ <source>The feature is not supported in the current Orchestrator.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a437b8f93cf826817c04a4277edb1ae3a93a1ab" datatype="html">
+ <source>Orchestrator is not available. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the functionality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">7,9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20b3d45b0c08a2951a9974fa20505e4de95250c9" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>less than 1<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day. Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">9,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f34088c155e40ffb23770a465a65868ce772b2" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day(s). Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8d1785038d461ec66b5799db21864182b35900a" datatype="html">
+ <source>Refresh</source>
+ <target>Načíst znovu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/refresh-selector/refresh-selector.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3417247046175131869" datatype="html">
+ <source>No items selected.</source>
+ <target>Nevybrány žádné položky.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1034353870189672674" datatype="html">
+ <source>Deselect item to select again</source>
+ <target>Aby položku bylo možné znovu vybrat, je třeba nejprve zrušit její výběr</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4879298070255432995" datatype="html">
+ <source>Selection limit reached</source>
+ <target>Dosažen limit výběru</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001227209911602786" datatype="html">
+ <source>Filter tags</source>
+ <target>Filtrovat štítky</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="791789583719406586" datatype="html">
+ <source>Add badge</source>
+ <target>Přidat odznak</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="699988676752930063" datatype="html">
+ <source>There are no items available.</source>
+ <target>Nejsou k dispozici žádné položky.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6702323d3760e3db0e2e785d567469d18beb120" datatype="html">
+ <source>The Ceph community needs your help to continue improving: please <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>Activate<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> the <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Telemetry<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> module.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.html</context>
+ <context context-type="linenumber">8,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8770134622386151776" datatype="html">
+ <source>Telemetry activation reminder muted</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8352450862052130357" datatype="html">
+ <source>You can activate the module on the Telemetry configuration page (&lt;b&gt;Dashboard Settings&lt;/b&gt; -&gt; &lt;b&gt;Telemetry configuration&lt;/b&gt;) at any time.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bc9e5365a581105ce37cf47d1d74e4ad9eb75ce" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e634c306cab9e8879c3392593714c1ceab85437d" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3249513483374643425" datatype="html">
+ <source>Add</source>
+ <target>Přidat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4359847060009771702" datatype="html">
+ <source>Set</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935187492052582731" datatype="html">
+ <source>Submit</source>
+ <target>Odeslat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4814285799071780083" datatype="html">
+ <source>Remove</source>
+ <target>Odebrat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8363450564548681668" datatype="html">
+ <source>Unset</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2159130950882492111" datatype="html">
+ <source>Cancel</source>
+ <target>Storno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1295614462098694869" datatype="html">
+ <source>Preview</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2354817630223808522" datatype="html">
+ <source>Move</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3885497195825665706" datatype="html">
+ <source>Next</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8890553633144307762" datatype="html">
+ <source>Back</source>
+ <target>Zpět</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5834780181397311898" datatype="html">
+ <source>Clone</source>
+ <target>Klonovat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4323470180912194028" datatype="html">
+ <source>Copy</source>
+ <target>Kopírovat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2131301778880826094" datatype="html">
+ <source>Deep Scrub</source>
+ <target>Hloubková kontrola</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1704447209800801558" datatype="html">
+ <source>Destroy</source>
+ <target>Zlikvidovat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8343007008325027187" datatype="html">
+ <source>Evict</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="408179081163888126" datatype="html">
+ <source>Flatten</source>
+ <target>Zploštit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="318900679147387932" datatype="html">
+ <source>Mark Down</source>
+ <target>Označit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5275142643521766706" datatype="html">
+ <source>Mark In</source>
+ <target>Označit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6973272903386150199" datatype="html">
+ <source>Mark Lost</source>
+ <target>Označit ztracené</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1962653792210847411" datatype="html">
+ <source>Mark Out</source>
+ <target>Odznačit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4424610588915076517" datatype="html">
+ <source>Protect</source>
+ <target>Ochránit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6041115344061899387" datatype="html">
+ <source>Rename</source>
+ <target>Přejmenovat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">164</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6770769801335635194" datatype="html">
+ <source>Restore</source>
+ <target>Obnovit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2003230525878010676" datatype="html">
+ <source>Reweight</source>
+ <target>Znovu vyvážit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5430834128563178593" datatype="html">
+ <source>Scrub</source>
+ <target>Kontrola</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8461842260159597706" datatype="html">
+ <source>Show</source>
+ <target>Zobrazit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5655608100705734230" datatype="html">
+ <source>Move to Trash</source>
+ <target>Přesunout do koše</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4622393909937403117" datatype="html">
+ <source>Unprotect</source>
+ <target>Zrušit ochranu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1230154438678955604" datatype="html">
+ <source>Change</source>
+ <target>Změnit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8450843381175865415" datatype="html">
+ <source>Enter Maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1610181371597502589" datatype="html">
+ <source>Exit Maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="676511611419004737" datatype="html">
+ <source>Start Drain</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7170653322511987983" datatype="html">
+ <source>Stop Drain</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5528551262937858942" datatype="html">
+ <source>Recreate</source>
+ <target>Znovuvytvořit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2502364444688691031" datatype="html">
+ <source>Expire</source>
+ <target>Ukončit platnost</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6381490568322624964" datatype="html">
+ <source>Deleted</source>
+ <target>Smazáno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="231679111972850796" datatype="html">
+ <source>Added</source>
+ <target>Přidáno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5406093358072761930" datatype="html">
+ <source>Removed</source>
+ <target>Odebráno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3008573030448240863" datatype="html">
+ <source>Edited</source>
+ <target>Upraveno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4381944803872489731" datatype="html">
+ <source>Canceled</source>
+ <target>Zrušeno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754993936947658096" datatype="html">
+ <source>Previewed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6001163963116907226" datatype="html">
+ <source>Moved</source>
+ <target>Přesunuto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4932744777596632840" datatype="html">
+ <source>Cloned</source>
+ <target>Naklonováno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2115592966120408375" datatype="html">
+ <source>Copied</source>
+ <target>Zkopírováno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7937474560394832586" datatype="html">
+ <source>Deep Scrubbed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6321562733889197649" datatype="html">
+ <source>Destroyed</source>
+ <target>Zlikvidováno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7460162290177581995" datatype="html">
+ <source>Flattened</source>
+ <target>Zploštěno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3662010055028969035" datatype="html">
+ <source>Marked Down</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5880434235404894589" datatype="html">
+ <source>Marked In</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="266997194072682078" datatype="html">
+ <source>Marked Lost</source>
+ <target>Označeno jako ztracené</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">250</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4010544044592534535" datatype="html">
+ <source>Marked Out</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4776304093333411035" datatype="html">
+ <source>Protected</source>
+ <target>Chráněno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2700903921419382511" datatype="html">
+ <source>Purged</source>
+ <target>Vyčištěno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5488667333459350160" datatype="html">
+ <source>Renamed</source>
+ <target>Přejmenováno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8044659850000829751" datatype="html">
+ <source>Restored</source>
+ <target>Obnoveno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559472082694466366" datatype="html">
+ <source>Reweighted</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022271525067453676" datatype="html">
+ <source>Rolled back</source>
+ <target>Vzato zpět</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2483217756816388123" datatype="html">
+ <source>Scrubbed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7200036055090632378" datatype="html">
+ <source>Showed</source>
+ <target>Zobrazeno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7609648817347881129" datatype="html">
+ <source>Moved to Trash</source>
+ <target>Přesunout do koše</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7810326403606456469" datatype="html">
+ <source>Unprotected</source>
+ <target>Ochrana zrušena</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5620774899056099259" datatype="html">
+ <source>Recreated</source>
+ <target>Znovu vytvořeno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464749780222721589" datatype="html">
+ <source>Expired</source>
+ <target>Platnost skončila</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">266</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e5e23363e949f7dcbaf034bdb141a561132a10e" datatype="html">
+ <source>Clear filters</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80cc9a12d4bf6fe454ed94b379eeaf915f920bb7" datatype="html">
+ <source>selected</source>
+ <target>vybráno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <note priority="1" from="description">X selected</note>
+ </trans-unit>
+ <trans-unit id="0cb77511a9a148e05b9adf36cc07269956fbb29d" datatype="html">
+ <source>found</source>
+ <target>nalezeno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <note priority="1" from="description">X found</note>
+ </trans-unit>
+ <trans-unit id="79347388740c50b7ac97e144c2494bb62912f312" datatype="html">
+ <source>total</source>
+ <target>celkem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <note priority="1" from="description">X total</note>
+ </trans-unit>
+ <trans-unit id="2a3dab422cc892db037db8632bb84a6bf496e2d1" datatype="html">
+ <source>Expand/Collapse Row</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4047162422391207122" datatype="html">
+ <source>Failed to load data.</source>
+ <target>Data se nepodařilo načíst</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.ts</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="709331713250198508" datatype="html">
+ <source>Loading form data...</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3850344644863430180" datatype="html">
+ <source>Form data could not be loaded.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4626760504772708998" datatype="html">
+ <source>Size has to be at least <x id="PH" equiv-text="value"/> or more</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">428</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2880361802894657892" datatype="html">
+ <source>Size has to be at most <x id="PH" equiv-text="value"/> or less</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2807800733729323332" datatype="html">
+ <source>Yes</source>
+ <target>Ano</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3542042671420335679" datatype="html">
+ <source>No</source>
+ <target>Ne</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7789266940050748913" datatype="html">
+ <source>in %s</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565573880632900017" datatype="html">
+ <source>%s ago</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="220300059326988179" datatype="html">
+ <source>a few seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2761143993878941513" datatype="html">
+ <source>%d seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7094767962693903153" datatype="html">
+ <source>a minute</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7597613755904774250" datatype="html">
+ <source>%d minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2757762976030115752" datatype="html">
+ <source>an hour</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9118454901758656303" datatype="html">
+ <source>%d hours</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7435193742089920080" datatype="html">
+ <source>a day</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1821334622562842480" datatype="html">
+ <source>%d days</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7375306199026780379" datatype="html">
+ <source>a week</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7272688256541915488" datatype="html">
+ <source>%d weeks</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5761124614324704118" datatype="html">
+ <source>a month</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="352195662913351589" datatype="html">
+ <source>%d months</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7562153591649199139" datatype="html">
+ <source>a year</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5424759741855527370" datatype="html">
+ <source>%d years</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7738182956549158907" datatype="html">
+ <source>Required rules for passwords:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8839765875053270528" datatype="html">
+ <source>Must contain at least <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> characters</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3098731108593590794" datatype="html">
+ <source>Must not be the same as the previous one</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9150236741862848105" datatype="html">
+ <source>Cannot contain the username</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6395043854518867543" datatype="html">
+ <source>Cannot contain any configured keyword</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="907558624910601703" datatype="html">
+ <source>Cannot contain any repetitive characters e.g. &quot;aaa&quot;</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514384270734082343" datatype="html">
+ <source>Cannot contain any sequential characters e.g. &quot;abc&quot;</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4119354814383293871" datatype="html">
+ <source>Must consist of characters from the following groups:
+ * Alphabetic a-z, A-Z
+ * Numbers 0-9
+ * Special chars: !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * Any other characters (signs)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">30,34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8649061117624699581" datatype="html">
+ <source>Your matcher seems to match no currently defined rule or active alert.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7122912874364762704" datatype="html">
+ <source>no active alerts</source>
+ <target>žádné aktivní výstrahy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7388215679576832341" datatype="html">
+ <source>1 active alert</source>
+ <target>Jedna aktivní výstraha</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3112400568960537267" datatype="html">
+ <source><x id="PH" equiv-text="alerts"/> active alerts</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6264717417287230743" datatype="html">
+ <source>Matches 1 rule</source>
+ <target>Odpovídá jednomu pravidlu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054663176394183966" datatype="html">
+ <source>Matches <x id="PH" equiv-text="rules"/> rules</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6674225401121099210" datatype="html">
+ <source><x id="PH" equiv-text="rule"/> with <x id="PH_1" equiv-text="alert"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5659908877047925719" datatype="html">
+ <source>Quality of Service</source>
+ <target>Kvalita služby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1277565045885499475" datatype="html">
+ <source>BPS Limit</source>
+ <target>Limit BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2289210323987692906" datatype="html">
+ <source>The desired limit of IO bytes per second.</source>
+ <target>Požadovaný limit vst./výstup. bajtů za sekundu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753589939879013605" datatype="html">
+ <source>IOPS Limit</source>
+ <target>Limit vst/výstup. operací / s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2213985059444278522" datatype="html">
+ <source>The desired limit of IO operations per second.</source>
+ <target>Požadovaný limit vst./výstup. operací za sekundu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2487530611825582289" datatype="html">
+ <source>Read BPS Limit</source>
+ <target>Limit BPS čtení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8071352270469595250" datatype="html">
+ <source>The desired limit of read bytes per second.</source>
+ <target>Požadovaný limit čtení bajtů za sekundu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1632513758247239690" datatype="html">
+ <source>Read IOPS Limit</source>
+ <target>Limit IOPS čtení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2361786794607418566" datatype="html">
+ <source>The desired limit of read operations per second.</source>
+ <target>Požadovaný limit operací čtení za sekundu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="894600353504285551" datatype="html">
+ <source>Write BPS Limit</source>
+ <target>Limit BPS zápisu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911437671369366025" datatype="html">
+ <source>The desired limit of write bytes per second.</source>
+ <target>Požadovaný limit zápisu bajtů za sekundu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2947346368707443195" datatype="html">
+ <source>Write IOPS Limit</source>
+ <target>Limit IOPS zápisu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5506349527983391356" datatype="html">
+ <source>The desired limit of write operations per second.</source>
+ <target>Požadovaný limit operací čtení za sekundu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559424229658244943" datatype="html">
+ <source>BPS Burst</source>
+ <target>BPS dávka</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3454058701331860330" datatype="html">
+ <source>The desired burst limit of IO bytes.</source>
+ <target>Požadovaný limit dávky bajtů vstup/výstupu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171005761926448741" datatype="html">
+ <source>IOPS Burst</source>
+ <target>IOPS dávka</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4939532784700485729" datatype="html">
+ <source>The desired burst limit of IO operations.</source>
+ <target>Požadovaný limit dávky vst./výstup. operací.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6273492199526646930" datatype="html">
+ <source>Read BPS Burst</source>
+ <target>Dávka BPS čtení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3105467595643777520" datatype="html">
+ <source>The desired burst limit of read bytes.</source>
+ <target>Požadovaný limit dávky bajtů čtení.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2170715106679765467" datatype="html">
+ <source>Read IOPS Burst</source>
+ <target>Dávka IOPS čtení</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6234106755510510672" datatype="html">
+ <source>The desired burst limit of read operations.</source>
+ <target>Požadovaný limit dávky čtení bajtů.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="228509518172572466" datatype="html">
+ <source>Write BPS Burst</source>
+ <target>Dávka BPS zápisu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7803279807796571240" datatype="html">
+ <source>The desired burst limit of write bytes.</source>
+ <target>Požadovaný limit bajtů dávky zápisu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9125474584914848055" datatype="html">
+ <source>Write IOPS Burst</source>
+ <target>Dávka IOPS zápisu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5839129348567326667" datatype="html">
+ <source>The desired burst limit of write operations.</source>
+ <target>Požadovaný limit dávky operace zápisu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="614961883076556986" datatype="html">
+ <source>Failed to <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="489145301781720653" datatype="html">
+ <source>Executing</source>
+ <target>Vykonává se</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4238828029954346941" datatype="html">
+ <source>execute</source>
+ <target>vykonat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7196604637389554584" datatype="html">
+ <source>Executed</source>
+ <target>Vykonáno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4418441687454700644" datatype="html">
+ <source>unknown task</source>
+ <target>neznámý úkol</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8667665916832796867" datatype="html">
+ <source>Creating</source>
+ <target>Vytváří se</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6031236679730054907" datatype="html">
+ <source>create</source>
+ <target>vytvořit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5593033420216313122" datatype="html">
+ <source>Updating</source>
+ <target>Aktualizuje se</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6100869651653026893" datatype="html">
+ <source>update</source>
+ <target>aktualizovat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3141301060598402455" datatype="html">
+ <source>Deleting</source>
+ <target>Maže se</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3420504288275541125" datatype="html">
+ <source>Adding</source>
+ <target>Přidávání</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1059784693423848532" datatype="html">
+ <source>add</source>
+ <target>přidat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594819887188505274" datatype="html">
+ <source>Removing</source>
+ <target>Odebírání</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2123171795960509943" datatype="html">
+ <source>remove</source>
+ <target>odebrat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1946427188770321847" datatype="html">
+ <source>Importing</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8495827411619139669" datatype="html">
+ <source>import</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218459863491436562" datatype="html">
+ <source>Imported</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6534993668932538712" datatype="html">
+ <source>RBD '<x id="PH" equiv-text="metadata.image_spec"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8237287859948228705" datatype="html">
+ <source>RBD snapshot '<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2328067975897167268" datatype="html">
+ <source>mirroring site name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4433460322631470833" datatype="html">
+ <source>bootstrap token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7044591639782280183" datatype="html">
+ <source>mirror mode for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7109746474198366468" datatype="html">
+ <source>mirror peer for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6201476020617351396" datatype="html">
+ <source>all dashboards</source>
+ <target>všechny přehledy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7268953097700363232" datatype="html">
+ <source>Identifying</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4337678035264231187" datatype="html">
+ <source>identify</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7257219307556106552" datatype="html">
+ <source>Identified</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6002370161381995023" datatype="html">
+ <source>device '<x id="PH" equiv-text="metadata.device"/>' on host '<x id="PH_1" equiv-text="metadata.hostname"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5580298273054260850" datatype="html">
+ <source>OSDs (DriveGroups: <x id="PH" equiv-text="metadata.tracking_id"/>)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2182125722527364040" datatype="html">
+ <source>Name is already used by <x id="PH" equiv-text="this.pool(metadata)"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">182</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7892856315477304281" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> is busy.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4690045751984117407" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> contains snapshots.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="562148565853868662" datatype="html">
+ <source>Cloning</source>
+ <target>Klonuje se</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1197352830433807469" datatype="html">
+ <source>clone</source>
+ <target>klonovat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1692004144561317867" datatype="html">
+ <source>Snapshot of <x id="PH" equiv-text="this.rbd.child(metadata)"/> must be protected.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8531200838331320284" datatype="html">
+ <source>Copying</source>
+ <target>Kopíruje se</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6862265996781523030" datatype="html">
+ <source>copy</source>
+ <target>zkopírovat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3556912098733712857" datatype="html">
+ <source>Flattening</source>
+ <target>Zploštění</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2488773646187451754" datatype="html">
+ <source>flatten</source>
+ <target>zploštit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="704305783678486635" datatype="html">
+ <source>Cannot unprotect <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> because it contains child images.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">223,225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101271773452792348" datatype="html">
+ <source>Cannot delete <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/> because it's protected.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5143010940199748580" datatype="html">
+ <source>Rolling back</source>
+ <target>Bere se zpět</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1315686250907089544" datatype="html">
+ <source>rollback</source>
+ <target>vzít zpět</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5010267418211867946" datatype="html">
+ <source>Moving</source>
+ <target>Přesouvá se</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4366763205960752449" datatype="html">
+ <source>move</source>
+ <target>přesunout</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="695867152524584829" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_spec"/>' to trash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423442774536615202" datatype="html">
+ <source>Could not find image.</source>
+ <target>Obraz se nedaří najít.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2622324641113512527" datatype="html">
+ <source>Restoring</source>
+ <target>Obnovuje se</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3347932678307141902" datatype="html">
+ <source>restore</source>
+ <target>obnovit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7488038030362249932" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>' into '<x id="PH_1" equiv-text="metadata.new_image_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565688512490959949" datatype="html">
+ <source>Image name '<x id="PH" equiv-text="metadata.new_image_name"/>' is already in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6331051389974655106" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8245559899946787147" datatype="html">
+ <source>Purging</source>
+ <target>Čistí se</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7879437654311684252" datatype="html">
+ <source>purge</source>
+ <target>vyčistit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1440427157062670480" datatype="html">
+ <source>all pools</source>
+ <target>všechny fondy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8677740163708263843" datatype="html">
+ <source>images from <x id="PH" equiv-text="message"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011237345035114219" datatype="html">
+ <source>Cannot disable mirroring because it contains a peer.</source>
+ <target>Zrcadlení nelze vypnout protože obsahuje protějšek.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">292</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7391584598242145869" datatype="html">
+ <source>host '<x id="PH" equiv-text="metadata.hostname"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6964302691596180722" datatype="html">
+ <source>OSD '<x id="PH" equiv-text="metadata.svc_id"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="488305686602466689" datatype="html">
+ <source>pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5921392748828575278" datatype="html">
+ <source>erasure code profile '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2423915105798557698" datatype="html">
+ <source>crush rule '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">370</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8273044996643438592" datatype="html">
+ <source>target '<x id="PH" equiv-text="metadata.target_iqn"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5474643443735437364" datatype="html">
+ <source>NFS '<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">378,380</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2235495382025026939" datatype="html">
+ <source>Service '<x id="PH" equiv-text="metadata.service_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ </body>
+ </file>
+</xliff> \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.de-DE.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.de-DE.xlf
new file mode 100644
index 000000000..09c85f3ba
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.de-DE.xlf
@@ -0,0 +1,14885 @@
+<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en-US" datatype="plaintext" original="ng2.template" target-language="de-DE">
+ <body>
+ <trans-unit id="ngb.alert.close" datatype="html">
+ <source>Close</source>
+ <target>Schließen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/alert/alert.ts</context>
+ <context context-type="linenumber">58,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.slide-number" datatype="html">
+ <source> Slide <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> of <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </source>
+ <target> Folie <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> von <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">114,118</context>
+ </context-group>
+ <note priority="1" from="description">Currently selected slide number read by screen reader</note>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.previous" datatype="html">
+ <source>Previous</source>
+ <target>Zurück</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">132,134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.next" datatype="html">
+ <source>Next</source>
+ <target>Weiter</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">147,152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-month" datatype="html">
+ <source>Select month</source>
+ <target>Monat wählen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">44,49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">49,50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-year" datatype="html">
+ <source>Select year</source>
+ <target>Jahr wählen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">59,63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.previous-month" datatype="html">
+ <source>Previous month</source>
+ <target>Vormonat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">24,27</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">35,36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.next-month" datatype="html">
+ <source>Next month</source>
+ <target>Folgemonat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">47,50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">60,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first" datatype="html">
+ <source>««</source>
+ <target>««</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">182,183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous" datatype="html">
+ <source>«</source>
+ <target>«</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">186,190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next" datatype="html">
+ <source>»</source>
+ <target>»</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">194,195</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last" datatype="html">
+ <source>»»</source>
+ <target>»»</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">201,204</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first-aria" datatype="html">
+ <source>First</source>
+ <target>Erste(r/s)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">208,209</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous-aria" datatype="html">
+ <source>Previous</source>
+ <target>Zurück</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">215,216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next-aria" datatype="html">
+ <source>Next</source>
+ <target>Weiter</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">226,228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last-aria" datatype="html">
+ <source>Last</source>
+ <target>Letzte(r/s)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.progressbar.value" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="; } /** *"/></source>
+ <target><x id="INTERPOLATION" equiv-text="; } /** *"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/progressbar/progressbar.ts</context>
+ <context context-type="linenumber">32,38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.HH" datatype="html">
+ <source>HH</source>
+ <target>HH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">40,41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.hours" datatype="html">
+ <source>Hours</source>
+ <target>Stunden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.MM" datatype="html">
+ <source>MM</source>
+ <target>MM</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">51,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.minutes" datatype="html">
+ <source>Minutes</source>
+ <target>Minuten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-hours" datatype="html">
+ <source>Increment hours</source>
+ <target>Stunden erhöhen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">63,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-hours" datatype="html">
+ <source>Decrement hours</source>
+ <target>Stunden verringern</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">69,70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-minutes" datatype="html">
+ <source>Increment minutes</source>
+ <target>Minuten erhöhen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">76,78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-minutes" datatype="html">
+ <source>Decrement minutes</source>
+ <target>Minuten verringern</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">82,84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.SS" datatype="html">
+ <source>SS</source>
+ <target>SS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.seconds" datatype="html">
+ <source>Seconds</source>
+ <target>Sekunden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">92,93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-seconds" datatype="html">
+ <source>Increment seconds</source>
+ <target>Sekunden erhöhen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">100,101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-seconds" datatype="html">
+ <source>Decrement seconds</source>
+ <target>Sekunden verringern</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">106,110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.AM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></source>
+ <target><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">115,121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.PM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="t() meridian: b"/></source>
+ <target><x id="INTERPOLATION" equiv-text="t() meridian: b"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">123,131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.toast.close-aria" datatype="html">
+ <source>Close</source>
+ <target>Schließen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/toast/toast.ts</context>
+ <context context-type="linenumber">78,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8835b9e49a3348b0a2f2162c21118af1f4bee45a" datatype="html">
+ <source>Must be greater than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>.</source>
+ <target>Muss größer oder gleich <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/> sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbddac59563c8c126e3fe28691e4e247614fcbd1" datatype="html">
+ <source>Must be less than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>.</source>
+ <target>Muss kleiner oder gleich <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/> sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5" datatype="html">
+ <source>Overview</source>
+ <target>Übersicht</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbd2045d5c37e4bb39a3c0fb62ea1ddf70a12838" datatype="html">
+ <source>Targets</source>
+ <target>Ziele</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a674ab267d1934bf395f87ca1503fd474296893f" datatype="html">
+ <source>iSCSI Topology</source>
+ <target>iSCSI-Topologie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8953033926734869941" datatype="html">
+ <source>Name</source>
+ <target>Name</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6603000223840533819" datatype="html">
+ <source>Current</source>
+ <target>Aktuell</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5607669932062416162" datatype="html">
+ <source>Default</source>
+ <target>Standard</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6803e31b7395d94934e091a49a9524026b59b018" datatype="html">
+ <source>Discovery Authentication</source>
+ <target>Ermittlungsauthentifizierung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e08a77594f3d89311cdf6da5090044270909c194" datatype="html">
+ <source>User</source>
+ <target>Benutzer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">381</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7cbdabcece469fab89cfa687ab152bca18b97498" datatype="html">
+ <source>This field is required.</source>
+ <target>Dies ist ein Pflichtfeld.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">368</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">423</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">481</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">291</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">343</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">407</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">490</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">516</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">556</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">573</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">590</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">647</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">672</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">299</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">195</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">520</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">614</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">651</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f717bad2da5944a2567a52f971ccc6806db85805" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>Benutzernamen müssen zwischen 8 und 64 Zeichen lang sein und dürfen die alphanumerischen Zeichen '.', '@', '-', '_' oder ':' enthalten.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">28,29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">85,86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c32ef07f8803a223a83ed17024b38e8d82292407" datatype="html">
+ <source>Password</source>
+ <target>Passwort</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">403</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">581</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="001e1836299d8d3b84eaebe2fa051325beab3f00" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>Passwörter müssen zwischen 12 und 16 Zeichen lang sein und dürfen die alphanumerischen Zeichen '@', '-', '_' oder '/' enthalten.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">61,62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">118,119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff40391de7a1944ea95091e4045cc34c4979b736" datatype="html">
+ <source>Mutual User</source>
+ <target>Gemeinsamer Benutzer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cf73dbebe99b737c4d288788182fc356e3c93d3" datatype="html">
+ <source>Mutual Password</source>
+ <target>Gemeinsames Passwort</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594987303599690088" datatype="html">
+ <source>Updated discovery authentication</source>
+ <target> Ermittlungsauthentifizierung aktualisiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb127ea03835b3230f0ed981c7080e2ccb879621" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <note priority="1" from="description">form title</note>
+ </trans-unit>
+ <trans-unit id="1406c2fb12a20c1528b19bcc5e24a6a2386167f3" datatype="html">
+ <source>Target IQN</source>
+ <target>Ziel-IQN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5fe42339be910372fa689f559155631862d218e8" datatype="html">
+ <source>IQN has wrong pattern.</source>
+ <target>IQN hat ein fehlerhaftes Muster.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="050a7ff057d1e895357540406b6be5652b4d1c71" datatype="html">
+ <source>An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'</source>
+ <target>Eine IQN hat die folgende Notation 'iqn.$jahr-$monat.$umkehradresse:$definierterName'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8ada4b53396d8366db00a435acc61d53d857047" datatype="html">
+ <source>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</source>
+ <target>Zum Beispiel: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e" datatype="html">
+ <source>More information</source>
+ <target>Weitere Informationen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9b1aa85dfc6849196e64060db02c5410de69b7a1" datatype="html">
+ <source>This target has modified advanced settings.</source>
+ <target>Erweiterte Einstellungen bei diesem Ziel wurden geändert.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6990ad8d6182662e864495ac31c3758cda1c7a28" datatype="html">
+ <source>Portals</source>
+ <target>Portale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a3ac2b4137d723fd9878cd357c2012ff6c07973" datatype="html">
+ <source>Add portal</source>
+ <target>Portal hinzufügen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3638c01b6c34066438909713ec96087c813fc7e" datatype="html">
+ <source>At least <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> gateways are required.</source>
+ <target>Mindestens <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> Gateways sind erforderlich.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b73f7f5060fb22a1e9ec462b1bb02493fa3ab866" datatype="html">
+ <source>Images</source>
+ <target>Images</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">495</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">629</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9aff25be088f0efe3eaaf62edf2bff41cc41a617" datatype="html">
+ <source>Backstore: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </source>
+ <target>Backstore: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e3484cae8b118c576ca2815bf9c9406c2eb2cae3" datatype="html">
+ <source>This image has modified settings.</source>
+ <target>Einstellungen bei diesem Image wurden geändert.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1dff11e0820b6722ab240169f1232d70a54beaaa" datatype="html">
+ <source>Duplicated LUN numbers.</source>
+ <target>Doppelte LUN-Nummern.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bf2dccf92ccff6e3b091792bf4205595406e1bfb" datatype="html">
+ <source>Duplicated WWN.</source>
+ <target>Doppelte WWN.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="808038f912fdc7f0e03f82d4afd3bf9178527fc8" datatype="html">
+ <source>Add image</source>
+ <target>Image hinzufügen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">656</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66c5fb27f52e75b70ca4b670b9b15a2a51cf9543" datatype="html">
+ <source>ACL authentication</source>
+ <target>ACL-Authentifizierung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="137fbf154ecad4d580354db0858b76faea7e4686" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>Benutzernamen müssen zwischen 8 und 64 Zeichen lang sein und dürfen die alphanumerischen Zeichen '.', '@', '-', '_' oder ':' enthalten.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">227,228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">287,288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="361771c32dd2254d77fd3fbf006b008983fe5907" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>Passwörter müssen zwischen 12 und 16 Zeichen lang sein und dürfen die alphanumerischen Zeichen '@', '-', '_' oder '/' enthalten.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">262,263</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">323,324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f494bd31f095f6dcc656ce87ec2dcf07a2e9b30c" datatype="html">
+ <source>Initiators</source>
+ <target>Initiatoren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">335</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">588</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e98239d8a6be1100119ff4b5630c822b82786740" datatype="html">
+ <source>Initiator</source>
+ <target>Initiator</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2c5059d8cda15d8d03e2cce30f2d139623d9a91" datatype="html">
+ <source>Client IQN</source>
+ <target>Client-IQN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="107d5aabce23d900f0a80e6ddc1c10e29aa0bed8" datatype="html">
+ <source>Initiator IQN needs to be unique.</source>
+ <target>Initiator-IQN muss eindeutig sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e7cad911fa524e512d9744b16358b7ee6791385" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>Benutzernamen müssen zwischen 8 und 64 Zeichen lang sein und dürfen die alphanumerischen Zeichen '.', '@', '-', '_' oder ':' enthalten.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">394,395</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">452,453</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7f2c186d181206d0d2b1ff74819081a010f10bf" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>Passwörter müssen zwischen 12 und 16 Zeichen lang sein und dürfen die alphanumerischen Zeichen '@', '-', '_' oder '/' enthalten.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">427,428</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">485,486</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d1878d5fc761cbe9614bfd87047a740c82a6951" datatype="html">
+ <source>Initiator belongs to a group. Images will be configure in the group.</source>
+ <target>Der Initiator gehört zu einer Gruppe. Images werden in der Gruppe konfiguriert.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">515</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0de67b9d97fafbf200f9451e8388ee8128a56ac" datatype="html">
+ <source>No items added.</source>
+ <target>Keine Elemente hinzugefügt.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">671</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d565e47726158e428ecdc952fc9233b9b7d7f049" datatype="html">
+ <source>Add initiator</source>
+ <target>Initiator hinzufügen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">616</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c22ba03540aa3217da059f45e7eab138b51a96e2" datatype="html">
+ <source>Groups</source>
+ <target>Gruppen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c90059afafb7e160384d9f512797c95bb95c6dc" datatype="html">
+ <source>Group</source>
+ <target>Gruppe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cff1428d10d59d14e45edec3c735a27b5482db59" datatype="html">
+ <source>Name</source>
+ <target>Name</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">576</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3084948274cff4f56d0f431af47240e9cf02fcc7" datatype="html">
+ <source>Add group</source>
+ <target>Gruppe hinzufügen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">676</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6634268061646442252" datatype="html">
+ <source>There are no portals available.</source>
+ <target>Keine Portale verfügbar.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4587015892789840153" datatype="html">
+ <source>There are no images available.</source>
+ <target>Keine Images verfügbar.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7896905042057267575" datatype="html">
+ <source>There are no images available. Please make sure you add an image to the target.</source>
+ <target>Keine Images verfügbar. Fügen Sie dem Ziel ein Image hinzu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6765423558085969805" datatype="html">
+ <source>There are no initiators available. Please make sure you add an initiator to the target.</source>
+ <target>Keine Initiatoren verfügen. Fügen Sie dem Ziel einen Initiator hinzu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2539932200265667453" datatype="html">
+ <source>target</source>
+ <target>Ziel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="051dcc342cfa5c1eaf187a2001aaa162379a160c" datatype="html">
+ <source>Configure</source>
+ <target>Konfigurieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e515f954730279c31d5301f02479666d6264e8b" datatype="html">
+ <source>Changing these parameters from their default values is usually not necessary.</source>
+ <target>Eine Änderung dieser Parameter von ihren Standardwerten ist in der Regel nicht erforderlich.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e2591df099ddac796cda401c5f282da779d45f2" datatype="html">
+ <source>Identifier</source>
+ <target>Bezeichner</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62480a4859976427cf18fc8ef41d3a438eda0412" datatype="html">
+ <source>lun</source>
+ <target>LUN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8afc9eb4405e0aa554b2ba14140ef790cdecc040" datatype="html">
+ <source>wwn</source>
+ <target>WWN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
+ <source>Settings</source>
+ <target>Einstellungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69a47cbabcc51ca942606e1d8da0ec11f98a2690" datatype="html">
+ <source>Backstore</source>
+ <target>Backstore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="339878da255ab55447c43afef8d9b2f9753bf5f6" datatype="html">
+ <source>Advanced Settings</source>
+ <target>Erweiterte Einstellungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="332227f088a4877b3c11f5fb3ae8bc812c470fae" datatype="html">
+ <source>iSCSI Targets not available</source>
+ <target>iSCSI-Ziele nicht verfügbar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7fba666f1fff0182e570f12133fb3d622d9ea6" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the iSCSI Targets management functionality.</source>
+ <target>Lesen Sie <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> zum Konfigurieren und Aktivieren der Verwaltungsfunktion für iSCSI-Ziele.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3b301d0044f62c92af0da53d7aaca52a436a547d" datatype="html">
+ <source>Available information:</source>
+ <target>Verfügbare Informationen:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8414a5cb9d71cc1b21b10e4a9d1f2dad558f3361" datatype="html">
+ <source>Discovery authentication</source>
+ <target>Ermittlungsauthentifizierung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4854396465510517671" datatype="html">
+ <source>Target</source>
+ <target>Ziel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4093869278527257288" datatype="html">
+ <source>Portals</source>
+ <target>Portale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="414887388288176527" datatype="html">
+ <source>Images</source>
+ <target>Images</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="798573158169239055" datatype="html">
+ <source># Sessions</source>
+ <target># Sitzungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="646929398175374220" datatype="html">
+ <source>Unavailable gateway(s)</source>
+ <target>Nicht verfügbare(s) Gateway(s)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2350612272163013640" datatype="html">
+ <source>Target has active sessions</source>
+ <target>Ziel hat aktive Verbindungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4782410538666829801" datatype="html">
+ <source>iSCSI target</source>
+ <target>iSCSI target</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">227</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8a9910cd114c1deb9af74f6f99b4173403965bf2" datatype="html">
+ <source>Gateways</source>
+ <target>Gateways</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911214550882917183" datatype="html">
+ <source>State</source>
+ <target>Status</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4121862424558610140" datatype="html">
+ <source># Targets</source>
+ <target># Ziele</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101197021456818771" datatype="html">
+ <source>Pool</source>
+ <target>Pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3012906865384504293" datatype="html">
+ <source>Image</source>
+ <target>Image</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2699995524827665158" datatype="html">
+ <source>Backstore</source>
+ <target>Backstore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3559214740809905405" datatype="html">
+ <source>Read Bytes</source>
+ <target>Bytes für Lesevorgang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1580583760095064067" datatype="html">
+ <source>Write Bytes</source>
+ <target>Bytes für Schreibvorgang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7225917547116479918" datatype="html">
+ <source>Read Ops</source>
+ <target>Lesevorgänge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6417507714454914481" datatype="html">
+ <source>Write Ops</source>
+ <target>Schreibvorgänge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="257147267065394003" datatype="html">
+ <source>A/O Since</source>
+ <target>A/O seit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ecbc084370a732fc3cde1966a60af78d71424ab4" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>Bootstrap-Token erstellen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603e9cc3ef2aab57f2b0a00e465b23b9cabefd9c" datatype="html">
+ <source>To create a bootstrap token which can be imported by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Generate<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Um ein Bootstrap-Token zu erstellen, das von einem Peer-Site-Cluster importiert werden kann, geben Sie den Namen der lokalen Site an, wählen Sie, für welche Pools die Spiegelung aktiviert sein soll und klicken Sie auf   <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Erzeugen<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="660f97cd3188f8a04bd03b79e703fec72c6df04c" datatype="html">
+ <source>Site Name</source>
+ <target>Site-Name</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2fecea01ce1d44114ee45144eff6d47a5016a74f" datatype="html">
+ <source>Name...</source>
+ <target>Name...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92899fa68e8ca108912163ff58edc8540e453787" datatype="html">
+ <source>Pools</source>
+ <target>Pools</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c2a1dc72cffaf7ab3dc5599bf77b0a7fcad2b20" datatype="html">
+ <source>At least one pool is required.</source>
+ <target>Mindestens ein Pool ist erforderlich.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b258b258b4cc475ceb2871305b61756b0134f4a" datatype="html">
+ <source>Generate</source>
+ <target>Erzeugen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1edc1fc6cfbbb22353050ad6788508b3ed584f53" datatype="html">
+ <source>Token</source>
+ <target>Token</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff785f5596aef34a93b9b4d1023e95c62eef5740" datatype="html">
+ <source>Generated token...</source>
+ <target>Erzeugtes Token...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8" datatype="html">
+ <source>Close</source>
+ <target>Schließen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5467a6bb0e7fade6def7499400d5e2a7d8d3da20" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>Bootstrap-Token importieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bb7aee0dec5164f45c0aa2f35f2fb2149d2c1d2" datatype="html">
+ <source>To import a bootstrap token which was created by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, provide the generated token, and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Import<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Um ein Bootstrap-Token zu importieren, das von einem Peer-Site-Cluster erstellt wurde, geben Sie den Namen der lokalen Site an, wählen Sie, für welche Pools die Spiegelung aktiviert sein soll, geben Sie das generierte Token an und klicken Sie auf <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Importieren<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9200e09686136a1d42adfb89c12fbfef2deea125" datatype="html">
+ <source>Direction</source>
+ <target>Richtung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9761484679958da8d12841a4efa5964d33fae575" datatype="html">
+ <source>The token is invalid.</source>
+ <target>Der Token ist ungültig.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2381859602529023966" datatype="html">
+ <source>Instance</source>
+ <target>Instanz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8040881171107393560" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1605455101862010019" datatype="html">
+ <source>Hostname</source>
+ <target>Hostname</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2724055831234181057" datatype="html">
+ <source>Version</source>
+ <target>Version</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2041675390931385838" datatype="html">
+ <source>Health</source>
+ <target>Integrität</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87bd96249f8afc23f5301cddb57b1464a98e71a" datatype="html">
+ <source>Edit site name</source>
+ <target>Site-Namen bearbeiten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cfff72c667274c12eb1ff71eadc25871c10c42dc" datatype="html">
+ <source>Edit the site name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Bearbeiten Sie den Site-Namen und klicken Sie auf  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Aktualisieren<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">13,14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66db799d67958d4b0765181d072df62e2d1c16f5" datatype="html">
+ <source>Issues</source>
+ <target>Probleme</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef06d69259e587e28d52372455f44c7153cda7e7" datatype="html">
+ <source>Syncing</source>
+ <target>Wird synchronisiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0b0901877d837d3fda16ba161eb74368d1c75b7a" datatype="html">
+ <source>Ready</source>
+ <target>Fertig</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5833626790712999947" datatype="html">
+ <source>Issue</source>
+ <target>Problem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3419681791450150574" datatype="html">
+ <source>Progress</source>
+ <target>Fortschritt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4902817035128594900" datatype="html">
+ <source>Description</source>
+ <target>Beschreibung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40b7acea5b43f45e0bbd1efeba5200af4687981d" datatype="html">
+ <source>Site Name:</source>
+ <target>Site-Name:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e24f9e2d42104ffc01599db4d566d1cc518f9e6" datatype="html">
+ <source>Daemons</source>
+ <target>Daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6450386891540681425" datatype="html">
+ <source>Edit Site Name</source>
+ <target>Site-Namen bearbeiten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4645993115976933405" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>Bootstrap-Token erstellen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4130053543590533787" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>Bootstrap-Token importieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4057c56d63a7e9b140b1d01871a9229a5f30eb27" datatype="html">
+ <source>Edit pool mirror mode</source>
+ <target>Spiegelungsmodus für Pool bearbeiten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e1f367f5feaab38f6637dd1f967c848b447dea2d" datatype="html">
+ <source>To edit the mirror mode for pool  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, select a new mode from the list and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Wählen Sie zum Bearbeiten des Spiegelungsmodus für den Pool  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> einen neuen Modus aus der Liste und klicken Sie auf   <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Aktualisieren<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37e10df2d9c0c25ef04ac112c9c9a7723e8efae0" datatype="html">
+ <source>Mode</source>
+ <target>Modus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">426</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32ca348ef926b0a6a7a780b8b64c3a8239895cec" datatype="html">
+ <source>Peer clusters must be removed prior to disabling mirror.</source>
+ <target>Vor dem Deaktivieren der Spiegelung müssen Peer-Cluster entfernt werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5769292297914455214" datatype="html">
+ <source>Disabled</source>
+ <target>Deaktiviert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ddcb416c1c0aa1f54acf5beef1de81813e76fa6" datatype="html">
+ <source>{VAR_SELECT, select, edit {Edit} other {Add}}</source>
+ <target>{VAR_SELECT, select, edit {bearbeiten} other {hinzufügen} }</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3aa7c3a4f7b0cf7c2e60fc71ea1e3b4c3efa3558" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> pool mirror peer</source>
+ <target>Peer für Poolspiegelung <x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="59ca65ece457429d90104ede4674965f62edbabe" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> the pool mirror peer attributes for pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Submit<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Sie können die Pool-Spiegelungs-Peer-Attribute für Pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> <x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> und dann auf <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Absenden<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> klicken.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d3cc964811f852a168f4a2d5daa59068abc5cf53" datatype="html">
+ <source>Cluster Name</source>
+ <target>Clustername</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b631721fc56cb7fb1cbd07b802a487c5753f6a2d" datatype="html">
+ <source>The cluster name is not valid.</source>
+ <target>Der Clustername ist ungültig.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca6deafa31bf421f85094807982aee4bcb20a3ae" datatype="html">
+ <source>CephX ID</source>
+ <target>CephX-ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7539188a568c3d553cbde1bacaf32310c4264e24" datatype="html">
+ <source>CephX ID...</source>
+ <target>CephX-ID...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1c45b594b0fba22fc64e80c793a7ffe005fdb0e" datatype="html">
+ <source>The CephX ID is not valid.</source>
+ <target>Die CephX ID ist ungültig.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20861576fcfce773c918c782cd4f5adf32382921" datatype="html">
+ <source>Monitor Addresses</source>
+ <target>Adressen der Monitore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fa28eeed2b4bd4ccbe6e9349a1c2b3cb1c5de70a" datatype="html">
+ <source>Comma-delimited addresses...</source>
+ <target>Kommagetrennte Adressen...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dc016c82fd85848d5c1b2fd0e8469ee2027d9c16" datatype="html">
+ <source>The monitory address is not valid.</source>
+ <target>Die Anrede ist ungültig.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0ac55b83dc6739e62bc655cfe375b67c93e7f4a" datatype="html">
+ <source>CephX Key</source>
+ <target>CephX-Schlüssel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f53434bcb95bd86f1df9c8e22966f757614fc4ad" datatype="html">
+ <source>Base64-encoded key...</source>
+ <target>Base64-codierter Schlüssel...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4cd83164cd4f66b4abc2863f9ce6f599d789e4ca" datatype="html">
+ <source>CephX key must be base64 encoded.</source>
+ <target>CephX-Schlüssel muss base64-codiert sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6407712033679505505" datatype="html">
+ <source>Edit Mode</source>
+ <target>Bearbeitungsmodus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054237897979907103" datatype="html">
+ <source>Add Peer</source>
+ <target>Peer hinzufügen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="899134641637789371" datatype="html">
+ <source>Edit Peer</source>
+ <target>Peer bearbeiten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7393680121674824053" datatype="html">
+ <source>Delete Peer</source>
+ <target>Peer löschen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1713271461473302108" datatype="html">
+ <source>Mode</source>
+ <target>Modus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1061297288634362831" datatype="html">
+ <source>Leader</source>
+ <target>Leader</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8517494870558773093" datatype="html">
+ <source># Local</source>
+ <target># lokal</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4953753699491987394" datatype="html">
+ <source># Remote</source>
+ <target># remote</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1715982232168082172" datatype="html">
+ <source>mirror peer</source>
+ <target>Peer spiegeln</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff92fbdec9fdd5054493eeda0d7ee8b450f83e72" datatype="html">
+ <source>RBD Configuration</source>
+ <target>RBD-Konfiguration</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b62d9efc8eb3b589904f6cb96a0406bbda55673a" datatype="html">
+ <source>Remove the local configuration value. The parent configuration value will be inherited and used instead.</source>
+ <target>Entfernen Sie den lokalen Konfigurationswert. Stattdessen wird der übergeordnete Konfigurationswert übernommen und verwendet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80d769fd863fe44fab689636a078466bfdbd1f20" datatype="html">
+ <source>The minimum value is 0</source>
+ <target>Der Mindestwert lautet 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5decb3917d46a9ac6e5813699801becb7c3c1455" datatype="html">
+ <source>Global</source>
+ <target>Global</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f9ba9bb9faa8284bcadb1cdbc6aaf969e9c4bb" datatype="html">
+ <source>Image</source>
+ <target>Image</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70fcca5a99575cffef3ff8cbd5e69f06ffd0f1c" datatype="html">
+ <source>Pool</source>
+ <target>Pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176659033176029418" datatype="html">
+ <source>Key</source>
+ <target>Schlüssel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9155608366859514313" datatype="html">
+ <source>Source</source>
+ <target>Quelle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6555318547274416232" datatype="html">
+ <source>Value</source>
+ <target>Wert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f6e8f6094b180eaf1f11bc0ffe383f1cdcd059e" datatype="html">
+ <source>Only available for RBD images with <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> enabled</source>
+ <target>Nur für RBD-Images verfügbar, bei denen <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> aktiviert ist</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f8b2bb476981727ab34ed40fde1218361f92c45" datatype="html">
+ <source>Details</source>
+ <target>Details</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03cc5b14b0a20d075e9009ff021f4f1660ba348a" datatype="html">
+ <source>Data Pool</source>
+ <target>Datenpool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b051734b0ee9021991c91b3ed4e81c244322462" datatype="html">
+ <source>Created</source>
+ <target>Erstellt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7faaaa08f56427999f3be41df1093ce4089bbd75" datatype="html">
+ <source>Size</source>
+ <target>Größe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="afdb601c16162f2c798b16a2920955f1cc6a20aa" datatype="html">
+ <source>Objects</source>
+ <target>Objekte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ceac8e132384322ec778ba760875a6c6897d3e42" datatype="html">
+ <source>Object size</source>
+ <target>Objektgröße</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cdb1fea93d77c07950c0c76c6e0ad79ebbef084" datatype="html">
+ <source>Features</source>
+ <target>Funktionen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65771c9a73b9aa609d592fc96a64801a8f40bd" datatype="html">
+ <source>Provisioned</source>
+ <target>Bereitgestellt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84a36cb75660b736773fe36ffa3d54f0f0fe363e" datatype="html">
+ <source>N/A</source>
+ <target>n. v.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c009342a4e8381f64341d0bb61c2e4685f5a4b" datatype="html">
+ <source>Total provisioned</source>
+ <target>Bereitgestellt gesamt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f6bf8a43ae415f527ac961ea62471b983aaa97b" datatype="html">
+ <source>Striping unit</source>
+ <target>Striping-Einheit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db710e8a8f011923f2d15d713fbae49c38b02b26" datatype="html">
+ <source>Striping count</source>
+ <target>Striping-Anzahl</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a4c2a9e76634ff14a60d52a718296f722d47c67" datatype="html">
+ <source>Parent</source>
+ <target>Übergeordnet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a209e68d78ffc2cc9c53d2e76158624efab71ad" datatype="html">
+ <source>Block name prefix</source>
+ <target>Präfix für Blockname</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5704ec2049d007c5f5fb495a5d8b607e68d58081" datatype="html">
+ <source>Order</source>
+ <target>Reihenfolge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="984cb6ad70f150a401b4daf841bd3cd957412699" datatype="html">
+ <source>Format Version</source>
+ <target>Formatversion</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f21b1d17b6c5042bb5805516eee37fde33739dd8" datatype="html">
+ <source>Snapshots</source>
+ <target>Snapshots</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4a41f824a35ba01d5bd7be61aa06b3e8145209d0" datatype="html">
+ <source>Configuration</source>
+ <target>Konfiguration</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3cc9c2ae277393b3946b38c088dabff671b1ee1b" datatype="html">
+ <source>Performance</source>
+ <target>Leistung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935bb9cb0e4340fc74d33caa3b70d9d143fcad87" datatype="html">
+ <source>Information can not be displayed for RBD in status 'Removing'.</source>
+ <target>Die Information kann nicht für RBD mit dem Status 'Entfernen' angezeigt werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58e58f1a8786da9031a05e6770c5dafce82badf5" datatype="html">
+ <source>This setting overrides the global value</source>
+ <target>Diese Einstellung überschreibt den globalen Wert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36b46714164964c6258b08ed0a25f57d8a950f92" datatype="html">
+ <source>This is the global value. No value for this option has been set for this image.</source>
+ <target>Dies ist der globale Wert. Kein Wert für diese Option wurde für dieses Image festgelegt.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6547c9c4d5f62942ac4b1fe459cf9a03d4dbf5a0" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> from</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> von</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0e9ecf29a4fa5b057bd8052e0d801b3fde6a30bf" datatype="html">
+ <source>'/' and '@' are not allowed.</source>
+ <target>'/' und '@' sind nicht zulässig.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="94516fa213706c67ce5a5b5765681d7fb032033a" datatype="html">
+ <source>Loading...</source>
+ <target>Laden...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">209</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">452</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b99417c4dd46286ffd37c8d2e987c8b512ec7052" datatype="html">
+ <source>-- No rbd pools available --</source>
+ <target>-- Keine rbd-Pools verfügbar --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef83ec9c304a89d45650e580dcdc2978c37b3a83" datatype="html">
+ <source>-- Select a pool --</source>
+ <target>-- Pool auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d649904466254d13df1fbf2d255f0bbc6553d213" datatype="html">
+ <source>-- No namespaces available --</source>
+ <target>-- Keine Namensräume verfügbar --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e22d7bb4d2d561e0832ee0b9a3da2468a080c4f0" datatype="html">
+ <source>-- Select a namespace --</source>
+ <target>-- Namensraum auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49449943d8cbf59d8c401c8bd2e76f92e207cc5f" datatype="html">
+ <source>Use a dedicated data pool</source>
+ <target>Dedizierten Datenpool verwenden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa5b3c5ea5af14d09b2eb098039af9f1f77be010" datatype="html">
+ <source>You need more than one pool with the rbd application label use to use a dedicated data pool.</source>
+ <target>Es ist mehr als ein Pool mit RBD-Anwendungslabel erforderlich, um einen dedizierten Datenpool zu verwenden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="870aee0dd31a9643bf62007beb8f1ae1deb34d42" datatype="html">
+ <source>Data pool</source>
+ <target>Datenpool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3792ca829d9b9f687e1f5d7733d30e9bb0bfec47" datatype="html">
+ <source>Dedicated pool that stores the object-data of the RBD.</source>
+ <target>Dedizierter Pool zur Speicherung von RBD-Objektdaten.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151c80ea931037cd92e854442927f8a0f6ae7795" datatype="html">
+ <source>-- No data pools available --</source>
+ <target>-- Keine Datenpools verfügbar --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0016bd458baa88284a658ce9eeda42d8ad88d2c" datatype="html">
+ <source>e.g., 10GiB</source>
+ <target>z. B. 10GiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">206</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a88bbee20570aaf9615332fb27020627044874d" datatype="html">
+ <source>You have to increase the size.</source>
+ <target>Sie müssen die Größe erhöhen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cfe07dac5b4ee1c464eb24225ddeb4f1d24076a" datatype="html">
+ <source>Advanced...</source>
+ <target>Erweitert...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bc2e854e111ecf2bd7db170da5e3c2ed08181d88" datatype="html">
+ <source>Advanced</source>
+ <target>Erweitert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3562a3778695a5f9c0445660e35301f0a39aaf73" datatype="html">
+ <source>Striping</source>
+ <target>Striping</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef3c3f3b5f562a5cdbe0ee2874287db1534b5958" datatype="html">
+ <source>Stripe unit</source>
+ <target>Stripe-Einheit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84471be1049006edecbcaef1a32ae0893c229c50" datatype="html">
+ <source>-- Select stripe unit --</source>
+ <target>-- Stripe-Einheit auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">289</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d32c5c54c8581c774a7f467fbd4e329b15a74fa" datatype="html">
+ <source>This field is required because stripe count is defined!</source>
+ <target>Dies ist ein Pflichtfeld, da eine Stripe-Anzahl definiert wurde!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bbf9040be7c5491d4a03f2185708f43a6582a3b" datatype="html">
+ <source>Stripe unit is greater than object size.</source>
+ <target>Die Stripe-Einheit ist größer als die Objektgröße.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a682f49f9b761591661276d7c6f550e641a130a4" datatype="html">
+ <source>Stripe count</source>
+ <target>Stripe-Anzahl</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="baa74031990c5370008ba622d0a250f0929097f4" datatype="html">
+ <source>This field is required because stripe unit is defined!</source>
+ <target>Dies ist ein Pflichtfeld, da eine Stripe-Einheit definiert wurde!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cd2ada6d5ecbd5cbf89eae0a1f5326efedac0dbc" datatype="html">
+ <source>Stripe count must be greater than 0.</source>
+ <target>Die Stripe-Anzahl muss größer als 0 sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4341718109173132593" datatype="html">
+ <source>RBD</source>
+ <target>RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1359455778569887786" datatype="html">
+ <source>Deep flatten</source>
+ <target>Umfassende Vereinfachung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58519213655664125" datatype="html">
+ <source>Layering</source>
+ <target>Schichtung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844531889615887801" datatype="html">
+ <source>Exclusive lock</source>
+ <target>Exklusive Sperre</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4585281635594103106" datatype="html">
+ <source>Object map (requires exclusive-lock)</source>
+ <target>Objektzuordnung (erfordert exklusive Sperre)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240933649452133654" datatype="html">
+ <source>Journaling (requires exclusive-lock)</source>
+ <target>Journaling (erfordert exklusive Sperre)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3713046526850391848" datatype="html">
+ <source>Fast diff (interlocked with object-map)</source>
+ <target>Fast diff (erfordert object-map)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19f1e825536efbf7492723a7c2d01ad23a4e994b" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1774b9915b0e302d02cad0b9321ad5f1a83247a8" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c9f1026c1235f4d76ace47449e806efd181ab332" datatype="html">
+ <source>Deleting this image will also delete all its snapshots.</source>
+ <target>Durch das Löschen dieses Images werden auch alle zugehörigen Snapshots gelöscht.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55f864597e84d9bf88769e1fbfda1d64452430c9" datatype="html">
+ <source>The following snapshots are currently protected and will be removed:</source>
+ <target>Folgende Snapshots sind derzeit geschützt und werden entfernt:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2e362ec498c4c9112dc47a3cb7d7250ca8e71790" datatype="html">
+ <source>RBD in status 'Removing'</source>
+ <target>RBD mit Status 'Entfernen'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3294686077659093992" datatype="html">
+ <source>Namespace</source>
+ <target>Namensraum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45739481977493163" datatype="html">
+ <source>Size</source>
+ <target>Größe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7531602241051125940" datatype="html">
+ <source>Objects</source>
+ <target>Objekte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1194977199378511591" datatype="html">
+ <source>Object size</source>
+ <target>Objektgröße</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">226</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="178418048502923560" datatype="html">
+ <source>Provisioned</source>
+ <target>Bereitgestellt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7638291694671392137" datatype="html">
+ <source>Total provisioned</source>
+ <target>Bereitgestellt gesamt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8621797738551294959" datatype="html">
+ <source>Parent</source>
+ <target>Übergeordnet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616639680594151867" datatype="html">
+ <source>This RBD has cloned snapshots. Please delete related RBDs before deleting this RBD.</source>
+ <target>Es gibt geklonte Snapshots zu diesem RBD. Bitte löschen Sie die zugehörigen RBDs bevor Sie dieses RBD löschen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2900827028308925059" datatype="html">
+ <source>This RBD image has an invalid name and can't be managed by ceph.</source>
+ <target>Dieses RBD-Image hat einen ungültigen Namen und kann nicht von ceph verwaltet werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1796389652493657142" datatype="html">
+ <source>Action not possible for an RBD in status 'Removing'</source>
+ <target>Aktion für ein RBD mit dem Status 'Entfernen' nicht möglich.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">476</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c07d24bb422aa8e5e568df1c5709083f0a9c8f1" datatype="html">
+ <source>Create Namespace</source>
+ <target>Namensraum anlegen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cca6c0485f96d3a9610d0339cb1275a5f2c3f46" datatype="html">
+ <source>Namespace already exists.</source>
+ <target>Namensraum existiert bereits.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4641528557519966449" datatype="html">
+ <source>Created namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <target>Namensraum '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>' erstellt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6809428596104996786" datatype="html">
+ <source>Total images</source>
+ <target>Images insgesamt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1346311774128536550" datatype="html">
+ <source>Deleted namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <target>Namensraum '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>' gelöscht</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7605466414392298530" datatype="html">
+ <source>Namespace contains images</source>
+ <target>Namensraum enthält Images</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576483965711201552" datatype="html">
+ <source>RBD Snapshot</source>
+ <target>RBD Snapshot</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3473055924346204357" datatype="html">
+ <source>Parent image must support Layering</source>
+ <target>Das übergeordnete Image muss Layering unterstützen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1152535233999495900" datatype="html">
+ <source>Snapshot must be protected in order to clone.</source>
+ <target>Snapshot muss geschützt sein, um zu klonen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c5331983af566d4ac6a1024d15a3511786a4aa6" datatype="html">
+ <source>You are about to rollback</source>
+ <target>Sie sind dabei, ein Rollback durchzuführen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6240400332778072187" datatype="html">
+ <source>PROTECTED</source>
+ <target>GESCHÜTZT</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9101667614062185213" datatype="html">
+ <source>UNPROTECTED</source>
+ <target>NICHT GESCHÜTZT</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4207916966377787111" datatype="html">
+ <source>Created</source>
+ <target>Erstellt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587768621777516124" datatype="html">
+ <source>RBD snapshot rollback</source>
+ <target>Rollback für RBD-Snapshot</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">305</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2711198699676132148" datatype="html">
+ <source>Rollback</source>
+ <target>Rollback</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3330476395115957823" datatype="html">
+ <source>RBD snapshot</source>
+ <target>RBD-Snapshot</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">322</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3a7e364a88ea4673199dfa98bc73e6dbe09dfac" datatype="html">
+ <source>Namespaces</source>
+ <target>Namensräume</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aba82bfd8e177d35b76cad7cd43941f8e5e5acac" datatype="html">
+ <source>Trash</source>
+ <target>Papierkorb</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5e7f4b1ca49e8d217bd0e12c6f7d6b6a2ade2c18" datatype="html">
+ <source>Overall Performance</source>
+ <target>Gesamtleistung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c0408946a6d67185947f455f15cc201d0d78e6" datatype="html">
+ <source>Purge Trash</source>
+ <target>Papierkorb bereinigen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c96a761dc55a21882c132c929583a424c9b8cf4" datatype="html">
+ <source>Expired at</source>
+ <target>Abgelaufen am</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="661041e3fcff4d3e75c561e038ca2504cf2cc643" datatype="html">
+ <source>Protected until</source>
+ <target>Geschützt bis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee3b2322a1d3277f7e3fdb8a5141ac42bcf350b" datatype="html">
+ <source>This image is protected until <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</source>
+ <target>Dieses Image ist geschützt bis <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5611592591303869712" datatype="html">
+ <source>Status</source>
+ <target>Status</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">213</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">285</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2155633476201267204" datatype="html">
+ <source>Deleted At</source>
+ <target>Gelöscht am</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0b5d789d42c0e69348e5fe0037fcbf5b5fbbdcc" datatype="html">
+ <source>Move an image to trash</source>
+ <target>Image in Papierkorb verschieben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ad22c1d4aab3b8946603cea62de266d5129ca10" datatype="html">
+ <source>This image contains snapshot(s), which will prevent it from being removed after moved to trash.</source>
+ <target>Dieses Image enthält einen oder mehrere Snapshots, dadurch wird das endgültige Löschen aus dem Papierkorb verhindert.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">15,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d4a5f5698bc8118b2e120b9bb72eff339094dd0" datatype="html">
+ <source>To move <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> to trash, click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Move<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Optionally, you can pick an expiration date.</source>
+ <target>Um <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> in den Papierkorb zu verschieben, klicken Sie auf <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Verschieben<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Optional können Sie ein Ablaufdatum auswählen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">19,20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f27d390844aad53b4240360e928156c5f0d326" datatype="html">
+ <source>Protection expires at</source>
+ <target>Schutz läuft ab am</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da166e9a0d27322f6ba8916d71ecc0f9905bb4b1" datatype="html">
+ <source>NOT PROTECTED</source>
+ <target>NICHT GESCHÜTZT</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1506e5f2ca22cad14502ec7a20fb6113ace145d" datatype="html">
+ <source>Wrong date format. Please use &quot;YYYY-MM-DD HH:mm:ss&quot;.</source>
+ <target>Falsches Datumsformat. Verwenden Sie &quot;TT.MM.JJJJ HH:mm:ss&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa7ea0bb7495281e0b3258467ac7d90a1e44a1a1" datatype="html">
+ <source>Protection has already expired. Please pick a future date or leave it empty.</source>
+ <target>Schutz ist bereits abgelaufen. Wählen Sie ein künftiges Datum aus oder lassen Sie es leer.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d8613436532acac2b97d17de28b50f93e6bd0222" datatype="html">
+ <source>To purge, select  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>All<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>  or one pool and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Purge<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </source>
+ <target>Zum Bereinigen wählen Sie   <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Alle<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>  oder einen Pool und klicken auf   <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Bereinigen<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55a4f598a4894b7fd5cb88f0ffd3c37ad009dd70" datatype="html">
+ <source>Pool:</source>
+ <target>Pool:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d43dd2b9f7797e4cf3a604695bb33e4479108516" datatype="html">
+ <source>Pool name...</source>
+ <target>Poolname...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dfc3c34e182ea73c5d784ff7c8135f087992dac1" datatype="html">
+ <source>All</source>
+ <target>Alle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0e7c7ed1d51a0c205c815048bc9f79e24ee6db2" datatype="html">
+ <source>Restore Image</source>
+ <target>Image wiederherstellen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3bc4aaf0dce75dc5e01ee5c825a652dc8aea8f0" datatype="html">
+ <source>To restore  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>,  type the image's new name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Restore<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Um  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> wiederherzustellen,  geben Sie den neuen Namen des Images ein und klicken Sie auf  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Wiederherstellen<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41307dd56fea669eed72e12a6c23af275f6bfd82" datatype="html">
+ <source>New Name</source>
+ <target>Neuer Name</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3625859417927520024" datatype="html">
+ <source>id</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6537904131139019667" datatype="html">
+ <source>type</source>
+ <target>Typ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8901220148451863928" datatype="html">
+ <source>state</source>
+ <target>Zustand</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7925190601961269841" datatype="html">
+ <source>version</source>
+ <target>Version</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6641024648411549335" datatype="html">
+ <source>Host</source>
+ <target>Host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773272191572353800" datatype="html">
+ <source>root</source>
+ <target>Stamm</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6364513948635353490" datatype="html">
+ <source>Evicted client '<x id="PH" equiv-text="clientId"/>'</source>
+ <target>Vertriebener Client '<x id="PH" equiv-text="clientId"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c1e17956453ad772dbe82d6946f62748c692f3e" datatype="html">
+ <source>Ranks</source>
+ <target>Ränge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b24e0b0b1629d2e8a51b9da7c75d6e6379f4bc4" datatype="html">
+ <source>Standbys</source>
+ <target>Standbys</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="50df62325726db950523a5be1c78b8905fcc25d4" datatype="html">
+ <source>MDS performance counters</source>
+ <target>MDS Leistungsindikatoren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4578796959376778578" datatype="html">
+ <source>Standby daemons</source>
+ <target>Standby-Daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="665219418211496660" datatype="html">
+ <source>Rank</source>
+ <target>Rang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5445409664838149993" datatype="html">
+ <source>Daemon</source>
+ <target>Daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5306473977542913614" datatype="html">
+ <source>Activity</source>
+ <target>Aktivität</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3998441303515229547" datatype="html">
+ <source>Dentries</source>
+ <target>Dentries</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7877631502958415163" datatype="html">
+ <source>Inodes</source>
+ <target>Inodes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6129397096478256985" datatype="html">
+ <source>Dirs</source>
+ <target>Dirs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3011876564696453148" datatype="html">
+ <source>Caps</source>
+ <target>Caps</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8650499415827640724" datatype="html">
+ <source>Type</source>
+ <target>Typ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="142654590491855672" datatype="html">
+ <source>Usage</source>
+ <target>Nutzung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">326</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb8293aa8161433778762ae025ffd5e7c85795e" datatype="html">
+ <source>Quotas</source>
+ <target>Kontingente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">540</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66785722678644243" datatype="html">
+ <source>Origin</source>
+ <target>Ursprung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8911059720204770105" datatype="html">
+ <source>Path</source>
+ <target>Pfad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6111756909052789805" datatype="html">
+ <source>Cannot create snapshots for files/folders in the subvolume <x id="PH" equiv-text="folders[2]"/></source>
+ <target>Kann keine Snapshots für Dateien/Ordner in Subvolume <x id="PH" equiv-text="folders[2]"/> erstellen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7503263437025060215" datatype="html">
+ <source>Max size</source>
+ <target>Max. Größe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6763343019307619111" datatype="html">
+ <source>Max files</source>
+ <target>Max. Dateien</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327403486214540377" datatype="html">
+ <source>The inherited <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> is the maximum value to be used.</source>
+ <target>Der übernommene Wert <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> ist der maximal zulässige Wert.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">434,437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3768927257183755959" datatype="html">
+ <source>Save</source>
+ <target>Speichern</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">440</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6328794256834621774" datatype="html">
+ <source><x id="PH" equiv-text="action"/> CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> quota for '<x id="PH_2" equiv-text="path"/>'</source>
+ <target>CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> Kontingent für '<x id="PH_2" equiv-text="path"/>' <x id="PH" equiv-text="action"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">446</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9130352375983418123" datatype="html">
+ <source>size</source>
+ <target>Größe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6889473896134264260" datatype="html">
+ <source>files</source>
+ <target>Dateien</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2244434638607433133" datatype="html">
+ <source><x id="PH" equiv-text="this.getQuotaName()"/> quota <x id="PH_1" equiv-text="value"/> from '<x id="PH_2" equiv-text="path"/>'</source>
+ <target><x id="PH" equiv-text="this.getQuotaName()"/> Kontingent <x id="PH_1" equiv-text="value"/> von '<x id="PH_2" equiv-text="path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">460</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6960117167304061503" datatype="html">
+ <source>Value has to be at least 0 or more</source>
+ <target>Wert muss mindestens 0 oder mehr sein</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">484</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6740501370117796629" datatype="html">
+ <source>Value has to be at most <x id="PH" equiv-text="maxValue"/> or less</source>
+ <target>Wert muss höchstens <x id="PH" equiv-text="maxValue"/> oder weniger sein</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7239750919884229270" datatype="html">
+ <source>Updated</source>
+ <target>Aktualisiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">499</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8885980874806414253" datatype="html">
+ <source>in order to inherit <x id="PH" equiv-text="quotaValue"/></source>
+ <target>um <x id="PH" equiv-text="quotaValue"/> zu übernehmen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4182949309891923991" datatype="html">
+ <source>which isn't used because of the inheritance of <x id="PH" equiv-text="quotaValue"/></source>
+ <target>wird aufgrund der Übernahme von <x id="PH" equiv-text="quotaValue"/> nicht verwendet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7421970649864638435" datatype="html">
+ <source>in order to have no quota on the directory</source>
+ <target>um kein Kontingent für das Verzeichnis zu definieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6730229976797004508" datatype="html">
+ <source><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</source>
+ <target><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">530,533</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="827679535246546876" datatype="html">
+ <source>Create Snapshot</source>
+ <target>Snapshot anlegen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">542</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">552</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4747656362969857823" datatype="html">
+ <source>Please enter the name of the snapshot.</source>
+ <target>Bitte geben Sie den Namen des Snapshot ein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3667696812078358068" datatype="html">
+ <source>Created snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <target>Snapshot '<x id="PH" equiv-text="name"/>' für '<x id="PH_1" equiv-text="path"/>' erstellt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="753342836137587734" datatype="html">
+ <source>CephFs Snapshot</source>
+ <target>CephFs Snapshot</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">670</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2774104291801979963" datatype="html">
+ <source>Deleted snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <target>Snapshot '<x id="PH" equiv-text="name"/>' für '<x id="PH_1" equiv-text="path"/>' gelöscht</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">683</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4816216590591222133" datatype="html">
+ <source>Enabled</source>
+ <target>Aktiv</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ffe39df9d88c972792bd8688b215392deb8313d" datatype="html">
+ <source>Clients</source>
+ <target>Clients</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e213942c6354b9cbe7a650f0f1499bfc1000fb6" datatype="html">
+ <source>Directories</source>
+ <target>Verzeichnisse</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fbbaf5cb02ed419e79a27072478f716a4666a99d" datatype="html">
+ <source>Performance Details</source>
+ <target>Leistungsdetails</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0" datatype="html">
+ <source>Description</source>
+ <target>Beschreibung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ad112ce9bcd55dfd137792a86afe1b5a5b13cf8" datatype="html">
+ <source>Long description</source>
+ <target>Detaillierte Beschreibung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="26fb5f81b3581f06b9210defb0e71dc69a67e819" datatype="html">
+ <source>Current values</source>
+ <target>Aktuelle Werte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7cee38a2259526c519f878e71b964f41db4348" datatype="html">
+ <source>Default</source>
+ <target>Standard</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33e1c1d9fc05ca3f62fcc8a1170fc31ebae4229c" datatype="html">
+ <source>Daemon default</source>
+ <target>Daemon-Standard</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f61c6867295f3b53d23557021f2f4e0aa1d0b8fc" datatype="html">
+ <source>Type</source>
+ <target>Typ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9abcd7c82643d60c22733470463f74e4a54bc069" datatype="html">
+ <source>Min</source>
+ <target>Min.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3ced4d162a0a55ee233a187ce7208ba5e922418" datatype="html">
+ <source>Max</source>
+ <target>Max.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="920617c6a1a4805e53bcb5af6a9c76f8387e89c6" datatype="html">
+ <source>Flags</source>
+ <target>Flags</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5" datatype="html">
+ <source>Services</source>
+ <target>Dienste</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6834fa6b43d1ecbdf147c48dd9c4d72f1484571d" datatype="html">
+ <source>Source</source>
+ <target>Quelle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a446fb0eb11fbffcac805ece5a2d306d24e733d8" datatype="html">
+ <source>Level</source>
+ <target>Level</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39f2fb094e9b2eda13163fa3f3a31594cf9c1307" datatype="html">
+ <source>Can be updated at runtime (editable)</source>
+ <target>Kann zur Laufzeit aktualisiert werden (bearbeitbar)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
+ <source>Tags</source>
+ <target>Tags</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ab0089ef47af61ca1d137bc908b96c290dfd9287" datatype="html">
+ <source>Enum values</source>
+ <target>Auflistungswerte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="819476f1264f1659f38e86f6abb542141b184832" datatype="html">
+ <source>See also</source>
+ <target>Siehe auch</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="543199344025799954" datatype="html">
+ <source>The value can be updated at runtime.</source>
+ <target>Der Wert kann zur Laufzeit aktualisiert werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1718354829128482129" datatype="html">
+ <source>Daemons/clients do not pull this value from the
+ monitor config database. We disallow setting this option via 'ceph config
+ set ...'. This option should be configured via ceph.conf or via the
+ command line.</source>
+ <target>Daemons/Clients rufen diesen Wert nicht aus der
+ Datenbank 'monitor config' ab. Es ist nicht zulässig, diese Option über 'ceph config
+ set ...' festzulegen. Diese Option sollte über 'ceph.conf' oder an der
+ Befehlszeile konfiguriert werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">15,18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2345189734548717257" datatype="html">
+ <source>Option takes effect only during daemon startup.</source>
+ <target>Die Option wird nur während des Daemon-Starts wirksam.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5523310713159993513" datatype="html">
+ <source>Option only affects cluster creation.</source>
+ <target>Die Option wirkt sich nur auf die Cluster-Erstellung aus.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1064479086902933123" datatype="html">
+ <source>Option only affects daemon creation.</source>
+ <target>Die Option wirkt sich nur auf die Daemon-Erstellung aus.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="809b0c848932a41318f77a2aace904ef429c13f4" datatype="html">
+ <source>Values</source>
+ <target>Werte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5894f7158499fdb89527af50c9f1cf7d4c95cad6" datatype="html">
+ <source>-- Default --</source>
+ <target>-- Standard --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="514f6e12d035a6d9b00de6b3e55c18b73488da07" datatype="html">
+ <source>true</source>
+ <target>wahr</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="774f5e6a183dea08393789b6f72e86afad729419" datatype="html">
+ <source>false</source>
+ <target>falsch</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="82029b6db704c56a2aa3e82ac555b8655356b077" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>.</source>
+ <target>Der eingegebene Wert ist zu groß! Er darf nicht größer als <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/> sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ed8b3967a7326b81b191c9f490006e6a6777a9a" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>.</source>
+ <target>Der eingegebene Wert ist zu niedrig! Er darf nicht kleiner als <x id="INTERPOLATION" equiv-text="{{ minValue }}"/> sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2337058106409853613" datatype="html">
+ <source>Updated config option <x id="PH" equiv-text="request.name"/></source>
+ <target>Aktualisierte Konfigurationsoption <x id="PH" equiv-text="request.name"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3733215288982610673" datatype="html">
+ <source>Level</source>
+ <target>Level</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2218082343053095278" datatype="html">
+ <source>Service</source>
+ <target>Dienst</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3553216189604488439" datatype="html">
+ <source>Modified</source>
+ <target>Geändert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844248428439297756" datatype="html">
+ <source>Current value</source>
+ <target>Aktueller Wert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208877297843037352" datatype="html">
+ <source>Editable</source>
+ <target>Editierbar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b266042bac4c3a2eff4834e40fb9dc4767a709" datatype="html">
+ <source>Cluster Resources</source>
+ <target>Cluster-Ressourcen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="099b441d49333b3c6d30b36dc0a4763e64c78920" datatype="html">
+ <source>Hosts</source>
+ <target>Hosts</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57e6e608ece53a26f6d509c90ed4f83e467741af" datatype="html">
+ <source>Storage Capacity</source>
+ <target>Speicherkapazität</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19ece2cb2b9097c0f75af8e62b4b3b25d399a006" datatype="html">
+ <source>Number of devices</source>
+ <target>Anzahl der Laufwerke</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b161e3d25fd1b42a781f4e923a58a94925988ddf" datatype="html">
+ <source>Raw capacity</source>
+ <target>Rohkapazität</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb6f3e2a26f3a6f2bc33f91adcd60502dbe5adac" datatype="html">
+ <source>CPUs</source>
+ <target>CPUs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58d4a9814864741040bc5905b6a368836e683f76" datatype="html">
+ <source>Memory</source>
+ <target>Speicher</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dbb81e566a861d4aa0a094366e4083e50863ee92" datatype="html">
+ <source>Host Details</source>
+ <target>Host-Details</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="453dc2810080a744223faac6da2b3ee9ed63a583" datatype="html">
+ <source>Welcome to <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></source>
+ <target>Willkommen bei <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1eec874e1928ca53baa9914781ce203b5f72b0c" datatype="html">
+ <source>Please expand your cluster first</source>
+ <target>Erweitern Sie zuerst Ihren Cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2195fd96b0a00f560449b50bd032e6d9b357730" datatype="html">
+ <source>Expand Cluster</source>
+ <target>Cluster erweitern</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb075d0450deb6f381616f7da4b9244ced843053" datatype="html">
+ <source>Skip</source>
+ <target>Abbrechen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55b6ce65571b8893440a4fc92776570f8fe7cc97" datatype="html">
+ <source>Add Hosts</source>
+ <target>Hosts hinzufügen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="162f763675c24b557a60eba0758558222369e0c7" datatype="html">
+ <source>Create OSDs</source>
+ <target>OSDs erstellen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fef7a7b8db05c351c5287db48488abca530bdb54" datatype="html">
+ <source>Create Services</source>
+ <target>Dienste erstellen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="176873b4533ddeabf95992cbd7b91b9d01c6d557" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ed90ec4409b9f6b552982d96f89db27259e763c" datatype="html">
+ <source>You are about to skip the cluster expansion process. You’ll need to <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>navigate through the menu to add hosts and services.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>Sie sind dabei, den Cluster-Erweiterungsprozess abzubrechen. Sie müssen <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>durch das Menü navigieren, um Hosts und Dienste hinzuzufügen<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">90,91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d1dcf2a9146caac0581329acf94806ec69a89a5" datatype="html">
+ <source>Are you sure you want to continue?</source>
+ <target>Möchten Sie den Vorgang wirklich fortsetzen?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6759205696902713848" datatype="html">
+ <source>Warning</source>
+ <target>Warnung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">357</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6962699013778688473" datatype="html">
+ <source>Continue</source>
+ <target>Fortfahren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6156560100092571435" datatype="html">
+ <source>Cluster expansion skipped by user</source>
+ <target>Cluster-Erweiterung von Benutzer abgebrochen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520085823873354736" datatype="html">
+ <source>Cluster expansion was successful</source>
+ <target>Cluster-Erweiterung war erfolgreich</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176230351113290618" datatype="html">
+ <source>Expand Cluster</source>
+ <target>Cluster erweitern</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="738de688b22fba5d0dc7a5e549996838dddad0ee" datatype="html">
+ <source>CRUSH map viewer</source>
+ <target>CRUSH-Betrachter</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/crushmap/crushmap.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e24569eca61d598c8b01defbbbb1fa8bd5222bc" datatype="html">
+ <source>Devices</source>
+ <target>Laufwerke</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17137bac47e1e020d139256ded0006a671966e73" datatype="html">
+ <source>Physical Disks</source>
+ <target>Physikalische Laufwerke</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="deba10b7279a589d01e919ea11f43c79ca1773e3" datatype="html">
+ <source>Device health</source>
+ <target>Laufwerkszustand</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d87fc20ea8e5f0f0500ba5d5061b345be78ec5e" datatype="html">
+ <source>No hostname found.</source>
+ <target>Hostname nicht gefunden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9a541ec1a4319fffc16ad3b3ab2c2b6d251a829d" datatype="html">
+ <source>Hostname</source>
+ <target>Hostname</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee6875e67b53cac30a02b57cf76e485f7e60caf4" datatype="html">
+ <source>To add multiple hosts at once, you can enter:</source>
+ <target>Um mehrere Hosts auf einmal hinzuzufügen, können Sie Folgendes eingeben:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a8370b19ccf673fb28fa9db36a08f9901887cc7" datatype="html">
+ <source>a comma-separated list of hostnames <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-01,example-02,example-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <target>eine kommagetrennte Liste der Hostnamen <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(z.B.: Beispiel-01,Beispiel-02,Beispiel-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="68f2c05396ec8a5f59e8da42d1f6c7310fa8c37c" datatype="html">
+ <source>a range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <target>eine Bereichsangabe<x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(z.B.: Beispiel-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e00b9bba448e79add37740e53dc953fbb89f9c5" datatype="html">
+ <source>a comma separated range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></source>
+ <target>eine kommagetrennte Bereichsangabe <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(z.B.: Beispiel-[01-05].lab.com,Beispiel2-[1-4].lab.com,Beispiel3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b3f5e5291541678f7afa49d28fad5ca848a8061" datatype="html">
+ <source>The chosen hostname is already in use.</source>
+ <target>Der ausgewählte Hostname wird bereits verwendet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="42365f623c57973d1d13d2038e8a2d4c02fb9b9f" datatype="html">
+ <source>Network address</source>
+ <target>Netzwerk-Adresse</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3859bdca1ae89e611e214c205fccf0147b4d0f6b" datatype="html">
+ <source>The value is not a valid IP address.</source>
+ <target>Der Wert ist keine gültige IP-Adresse.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2af7efecfae8d7fed3b07f718a623eca1ad8163f" datatype="html">
+ <source>Labels</source>
+ <target>Labels</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9da2afd4fa358b66d4d95fe7e8f4b659a7144e" datatype="html">
+ <source>Maintenance Mode</source>
+ <target>Wartungs-Modus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="468785112451259935" datatype="html">
+ <source>There are no labels.</source>
+ <target>Keine Labels vorhanden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4664081995078497865" datatype="html">
+ <source>Filter or add labels</source>
+ <target>Labels filtern oder hinzufügen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4897817053917542646" datatype="html">
+ <source>Add label</source>
+ <target>Label hinzufügen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">313</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1187321380561233505" datatype="html">
+ <source>host</source>
+ <target>Host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40661476cb24c89d8b06614998e31d5fbe84eeb6" datatype="html">
+ <source>Hosts List</source>
+ <target>Liste mit Hosts</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b7a4e1e5a316f8547af1d6d2311a5cec8c5c1d87" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ msg }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ msg }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6e8e8844e9e7a7b626a4699c08b6c0c81297a7b" datatype="html">
+ <source>Data will be available only if Orchestrator is available.</source>
+ <target>Daten sind nur verfügbar, wenn Orchestrator verfügbar ist.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4baf526199fed59071adf555271791283adc408" datatype="html">
+ <source>SSD, NVMEs</source>
+ <target>SSD, NVMEs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="22d5531d79f0d7269a0a752e56a848807dd37095" datatype="html">
+ <source>Flash</source>
+ <target>Flash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4025065730478477779" datatype="html">
+ <source>The feature is disabled because the selected host is not managed by Orchestrator.</source>
+ <target>Die Funktion ist deaktiviert, da der ausgewählte Host nicht von Orchestrator verwaltet wird.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7143579180750436311" datatype="html">
+ <source>Services</source>
+ <target>Dienste</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="546766753072101168" datatype="html">
+ <source>Labels</source>
+ <target>Labels</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1141886420788473147" datatype="html">
+ <source>Model</source>
+ <target>Modell</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4027647877328291519" datatype="html">
+ <source>CPUs</source>
+ <target>CPUs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2445398473573060226" datatype="html">
+ <source>Cores</source>
+ <target>Cores</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1656823484917332451" datatype="html">
+ <source>Total Memory</source>
+ <target>Gesamtspeicher</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1939212557812454069" datatype="html">
+ <source>Raw Capacity</source>
+ <target>Rohkapazität</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5579687933271468638" datatype="html">
+ <source>HDDs</source>
+ <target>HDDs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1889285841762768492" datatype="html">
+ <source>Flash</source>
+ <target>Flash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1578709829957887527" datatype="html">
+ <source>NICs</source>
+ <target>NICs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4723031838495967601" datatype="html">
+ <source>Edit Host: <x id="PH" equiv-text="host.hostname"/></source>
+ <target>Host bearbeiten: <x id="PH" equiv-text="host.hostname"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6004907173026319041" datatype="html">
+ <source>Edit Host</source>
+ <target>Host bearbeiten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5618131051466022401" datatype="html">
+ <source>Updated Host &quot;<x id="PH" equiv-text="host.hostname"/>&quot;</source>
+ <target>Aktualisierter Host &amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1701954433367210342" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; moved to maintenance</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; in die Wartung verschoben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3108406586869160854" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; cannot be put into maintenance</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; kann nicht in die Wartung verschoben werden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1737753151350322492" datatype="html">
+ <source><x id="PH" equiv-text="error.error['detail']"/></source>
+ <target><x id="PH" equiv-text="error.error['detail']"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4054533801359952167" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; has exited maintenance</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; hat die Wartung verlassen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5837599005212786659" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; stopped draining</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host['hostname']"/>&amp;quot; Entleerung gestoppt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1357236071975782353" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; started draining</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host['hostname']"/>&amp;quot; Entleerung gestartet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5658400717636093668" datatype="html">
+ <source>Identify</source>
+ <target>Identifizieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6966707768479328825" datatype="html">
+ <source>Device path</source>
+ <target>Laufwerkspfad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3955868613858648955" datatype="html">
+ <source>Available</source>
+ <target>Verfügbar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="158816374076721379" datatype="html">
+ <source>Vendor</source>
+ <target>Anbieter</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6024104799101504292" datatype="html">
+ <source>OSDs</source>
+ <target>OSDs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3422162477846071958" datatype="html">
+ <source>Identify device <x id="PH" equiv-text="device"/></source>
+ <target>Laufwerk <x id="PH" equiv-text="device"/> identifizieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4910073658089977244" datatype="html">
+ <source>Please enter the duration how long to blink the LED.</source>
+ <target>Bitte geben Sie die gewünschte Dauer zum Blinken der LED ein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5764931367607989415" datatype="html">
+ <source>1 minute</source>
+ <target>1 Minute</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809466133764752509" datatype="html">
+ <source>2 minutes</source>
+ <target>2 Minuten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">235</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1487672983218679675" datatype="html">
+ <source>5 minutes</source>
+ <target>5 Minuten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603584938775296395" datatype="html">
+ <source>10 minutes</source>
+ <target>10 Minuten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6648333117195452824" datatype="html">
+ <source>15 minutes</source>
+ <target>15 Minuten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6560281329999108838" datatype="html">
+ <source>Execute</source>
+ <target>Ausführen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6901229416977800100" datatype="html">
+ <source>Identifying '<x id="PH" equiv-text="device"/>' started on host '<x id="PH_1" equiv-text="hostname"/>'</source>
+ <target>Identifikation von '<x id="PH" equiv-text="device"/>' auf Host '<x id="PH_1" equiv-text="hostname"/>' gestartet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d556ab48a65722b400e497f61737f553ee0f89e2" datatype="html">
+ <source>Cluster Logs</source>
+ <target>Clusterprotokolle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5f966baffd188be0e8adc2d7067b86e55fc9b9de" datatype="html">
+ <source>Audit Logs</source>
+ <target>Revisionsprotokoll</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4193c9eb868aeec119b78a14795241e0aa5e8b60" datatype="html">
+ <source>Priority:</source>
+ <target>Priorität:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d78ca51eab260ce3fd917d39190d64df5229b6e" datatype="html">
+ <source>Keyword:</source>
+ <target>Schlüsselwort:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="05fa0bded36de6e73a1fa44838b627349dace044" datatype="html">
+ <source>Date:</source>
+ <target>Datum:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a400388de1899b1917138cf7e5286376f72847" datatype="html">
+ <source>Time range:</source>
+ <target>Zeitraum:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="de0478286b8b5a939db54e9e5282405364ad2d61" datatype="html">
+ <source>No log entries found. Please try to select different filter options.</source>
+ <target>Keine Log-Einträge gefunden. Bitte versuche es mit anderen Filtern.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7479674d91142b785b9547a87e5fb51cb16108" datatype="html">
+ <source>Reset filter.</source>
+ <target>Filter zurücksetzen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="31a9c2870a934b594d1390146c489f76440859ea" datatype="html">
+ <source>Edit Manager module</source>
+ <target>Manager-Modul bearbeiten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="46e09b8290d3d0afdb6baa2021395b0570606a31" datatype="html">
+ <source>The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</source>
+ <target>Der eingegebene Wert ist kein gültiger UUID, z. B.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7aacd038b39cfd347107d01d1dc27f5cb3e0951c" datatype="html">
+ <source>The entered value needs to be a valid IP address.</source>
+ <target>Der eingegebene Wert muss eine gültige IP-Adresse sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f19106149f4b07a0d721f9d317afed393cb7bd93" datatype="html">
+ <source>The entered value is too high! It must be lower or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>.</source>
+ <target>Der eingegebene Wert ist zu hoch! Er muss kleiner als <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/> sein oder diesem Wert entsprechen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d33c40ef9a6c3bf0888df831b25e41e65f9d15b" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>.</source>
+ <target>Der eingegebene Wert ist zu niedrig! Er muss größer als <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/> sein oder diesem Wert entsprechen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eae7086660cf1e38c7194a2c49ff52cc656f90f5" datatype="html">
+ <source>The entered value needs to be a number.</source>
+ <target>Der eingegebene Wert muss eine Zahl sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">194</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a73376e04b4fb3a20734c8c39743fba32e6676ce" datatype="html">
+ <source>The entered value needs to be a number or decimal.</source>
+ <target>Der eingegebene Wert muss eine Zahl oder Dezimalzahl sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1898719236268328097" datatype="html">
+ <source>Updated options for module '<x id="PH" equiv-text="this.moduleName"/>'.</source>
+ <target>Aktualisierte Optionen für Modul '<x id="PH" equiv-text="this.moduleName"/>'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4186041075388034600" datatype="html">
+ <source>Always-On</source>
+ <target>Dauerhaft aktiv</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7585826646011739428" datatype="html">
+ <source>Edit</source>
+ <target>Bearbeiten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2180291763949669799" datatype="html">
+ <source>Enable</source>
+ <target>Aktivieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9187855490716817910" datatype="html">
+ <source>Disable</source>
+ <target>Deakivieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1600086764852993170" datatype="html">
+ <source>This Manager module is always on.</source>
+ <target>Dieses Manager-Modul ist dauerhaft aktiv.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3895296744591223546" datatype="html">
+ <source>Reconnecting, please wait ...</source>
+ <target>Verbindung wird erneut hergestellt, bitte warten ...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81b97b8ea996ad1e4f9fca8415021850214884b1" datatype="html">
+ <source>Status</source>
+ <target>Status</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57ec6032f5618d4a9f16eb950ad23d2ce7c24b54" datatype="html">
+ <source>Cluster ID</source>
+ <target>Cluster-ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67d7facc3fec5f8a49ab9ba0a245872184264ce5" datatype="html">
+ <source>monmap modified</source>
+ <target>Monmap geändert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4906731aaf2b94b4f547646c9bfe58bb77951b6" datatype="html">
+ <source>monmap epoch</source>
+ <target>Monmap-Epoche</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd4ee06ffdc46d9dfbd0c0c4f81399021c680056" datatype="html">
+ <source>quorum con</source>
+ <target>quorum con</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1176c7db8a8276ccb44cc3d42e2c28d9fa6c6596" datatype="html">
+ <source>quorum mon</source>
+ <target>quorum mon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="530ef677a09d681b3ab68cb0760494b3ae72a77c" datatype="html">
+ <source>required con</source>
+ <target>erforderliche Verbindung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a91558e0d506c32021c31843f8f168899fc65cbf" datatype="html">
+ <source>required mon</source>
+ <target>erforderliche Überwachung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3abe9eac5bcd94a54c8da93b312e085ec512e74" datatype="html">
+ <source>In Quorum</source>
+ <target>In Quorum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba4b748a676e1f217ce1e736fb7ec1215e677bae" datatype="html">
+ <source>Not In Quorum</source>
+ <target>Nicht in Quorum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3517477838460618200" datatype="html">
+ <source>Public Address</source>
+ <target>Öffentliche Adresse</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6949358970125514744" datatype="html">
+ <source>Open Sessions</source>
+ <target>Aktive Sitzungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4383e9662ea19839c7499b2128d43a195e564317" datatype="html">
+ <source>OSD creation preview</source>
+ <target>Vorschau der OSD-Erstellung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="366225c51e0b00bcb1c55795a0dc5e81c455f84e" datatype="html">
+ <source>DriveGroups</source>
+ <target>DriveGroups</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91853167141c37b58868f3b0421383dd72fa8a01" datatype="html">
+ <source>Attributes (OSD map)</source>
+ <target>Attribute (OSD-Zuordnung)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f721a500a68c357e8f2a01e60510f6a01e4ba529" datatype="html">
+ <source>Metadata</source>
+ <target>Metadaten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97842f379e1d4157ac3ab0661b90c352e7cb72d5" datatype="html">
+ <source>Metadata not available</source>
+ <target>Metadaten nicht verfügbar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24e28e19c5703d7c6be44f4eb595a6a43b618ed" datatype="html">
+ <source>Performance counter</source>
+ <target>Leistungsindikator</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ccb4f84edc0b4e76415bb3f9b73d725b06683af3" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ name }}"/> devices</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ name }}"/> Laufwerke</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60cb3d01e5ddf266ecb4271007a1c3d0f3efdc22" datatype="html">
+ <source>The primary storage devices. These devices contain all OSD data.</source>
+ <target>Die primären Speicherlaufwerke. Diese Laufwerke enthalten alle OSD-Daten.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b432e04886d0d1fd84f740477383051f85addcf2" datatype="html">
+ <source>Write-Ahead-Log devices. These devices are used for BlueStore’s internal journal. It is only useful to use a WAL device if the device is faster than the primary device (e.g. NVME devices or SSDs). If there is only a small amount of fast storage available (e.g., less than a gigabyte), we recommend using it as a WAL device.</source>
+ <target>Festplatten für das Write-Ahead-Log. Diese Festplatten werden für das interne BlueStore-Journal verwendet. Eine separate WAL-Festplatte ist nur dann hilfreich, wenn sie schneller als die primäre Festplatte ist (z.B. NVME- oder SSD-Festplatten). Wenn nur geringer Speicherplatz auf schnellen Festplatten verfügbar ist (z.B. weniger als ein Gigabyte), wird empfohlen, diese für das WAL zu verwenden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87e181ab9e8393aa5ed759dd3d53836e32c8ffe" datatype="html">
+ <source>DB devices can be used for storing BlueStore’s internal metadata. It is only helpful to provision a DB device if it is faster than the primary device (e.g. NVME devices or SSD).</source>
+ <target>DB-Festplatten können für das Speichern der internen BlueStore-Metadaten verwendet werden. Eine separate DB-Festplatte ist nur dann hilfreich, wenn sie schneller als die primäre Festplatte ist (z.B. NVME- oder SSD-Festplatten).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
+ <source>Add</source>
+ <target>Hinzufügen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="99ee4faa69cd2ea8e3678c1f557c0ff1f05aae46" datatype="html">
+ <source>Clear</source>
+ <target>Löschen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e0fd3c7af0630f93befa6234a693a32a61084e0" datatype="html">
+ <source>Raw capacity: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></source>
+ <target>Rohkapazität: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1961811273151129466" datatype="html">
+ <source>No available devices</source>
+ <target>Keine verfügbaren Geräte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617271647728055571" datatype="html">
+ <source>Please add primary devices first</source>
+ <target>Bitte fügen Sie zuerst primäre Geräte hinzu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6368751795251107516" datatype="html">
+ <source>Add devices by using filters</source>
+ <target>Füge Geräte mithilfe von Filtern hinzu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8edc89137d0d8c5667a2f03230beafae45e58429" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> devices</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> Laufwerke</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eba28e1805b18f7c8ae2e4bc15dcf063b10b3822" datatype="html">
+ <source>At least one of these filters must be applied in order to proceed:</source>
+ <target>Zum Fortfahren muss mindestens einer dieser Filter angewendet werden:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="93389aa2fe2bea50bf89554ee51b28f87ee2fb50" datatype="html">
+ <source>Number of devices: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Raw capacity: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</source>
+ <target>Anzahl der Laufwerke: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Rohkapazität: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">29,30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6b27c16ddf33b855412c82069dca8120bd3a68a" datatype="html">
+ <source>Individual OSD Flags</source>
+ <target>Einzelne OSD-Flags</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dba0ed9ba355a3bd3296c0bef3bb518744a51a89" datatype="html">
+ <source>Cluster-wide</source>
+ <target>Clusterweit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e2a3f211cea2cbadb29b6df93e544440b6b68d3e" datatype="html">
+ <source>Restore previous selection</source>
+ <target>Voherige Auswahl wiederherstellen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1683654169791509804" datatype="html">
+ <source>No Up</source>
+ <target>Kein Up-Vorgang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5754783193519044074" datatype="html">
+ <source>OSDs are not allowed to start</source>
+ <target>OSDs dürfen nicht gestartet werden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4413588319909369773" datatype="html">
+ <source>No Down</source>
+ <target>Kein Down-Vorgang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1348746748821823470" datatype="html">
+ <source>OSD failure reports are being ignored, such that the monitors will not mark OSDs down</source>
+ <target>OSD-Fehlerberichte werden ignoriert, sodass die Monitore die OSDs nicht als ausgefallen markieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="301172600132606646" datatype="html">
+ <source>No In</source>
+ <target>Kein In-Vorgang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4114057962148673377" datatype="html">
+ <source>OSDs that were previously marked out will not be marked back in when they start</source>
+ <target>OSDs, die zuvor als 'out' markiert wurden, werden beim Start nicht wieder markiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5236523991485603657" datatype="html">
+ <source>No Out</source>
+ <target>Kein Out-Vorgang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1798160169020638994" datatype="html">
+ <source>OSDs will not automatically be marked out after the configured interval</source>
+ <target>OSDs werden nach dem konfigurierten Intervall nicht automatisch als 'out' markiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3225813593817914267" datatype="html">
+ <source>The flag has been enabled for the entire cluster.</source>
+ <target>Das Flag wurde für den gesamten Cluster aktiviert.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1941050626944682985" datatype="html">
+ <source>Updated OSD Flags</source>
+ <target>Aktualisierte OSD-Flags</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ef50ba2514414f799d4c8fc36067a251904ba81" datatype="html">
+ <source>Cluster-wide OSD Flags</source>
+ <target>Clusterweite OSD-Flags</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9042260521669277115" datatype="html">
+ <source>Pause</source>
+ <target>Pause</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6015425610572318971" datatype="html">
+ <source>Pauses reads and writes</source>
+ <target>Hält Lese- und Schreibvorgänge an</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314873595759611676" datatype="html">
+ <source>No Scrub</source>
+ <target>Kein Scrub</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773570234687653570" datatype="html">
+ <source>Scrubbing is disabled</source>
+ <target>Scrubbing ist deaktiviert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5999821123886006899" datatype="html">
+ <source>No Deep Scrub</source>
+ <target>Kein umfassender Scrub</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5362685148875251772" datatype="html">
+ <source>Deep Scrubbing is disabled</source>
+ <target>Umfassendes Scrubbing ist deaktiviert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5001752039592388485" datatype="html">
+ <source>No Backfill</source>
+ <target>Kein Abgleich</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4851280330655956778" datatype="html">
+ <source>Backfilling of PGs is suspended</source>
+ <target>Abgleich der Platzierungsgruppen ist ausgesetzt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5994953210305546559" datatype="html">
+ <source>No Rebalance</source>
+ <target>Kein Ausgleich</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3698980403470604587" datatype="html">
+ <source>OSD will choose not to backfill unless PG is also degraded</source>
+ <target>OSD wird keinen Abgleich durchführen, es sei denn, Platzierungsgruppe ist ebenfalls degradiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4334886823145076432" datatype="html">
+ <source>No Recover</source>
+ <target>Keine Wiederherstellung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8465994741155792816" datatype="html">
+ <source>Recovery of PGs is suspended</source>
+ <target>Wiederherstellung der Platzierungsgruppen ist ausgesetzt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4052740759486923001" datatype="html">
+ <source>Bitwise Sort</source>
+ <target>Bitweise Sortierung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2330377428425572488" datatype="html">
+ <source>Use bitwise sort</source>
+ <target>Bitweise Sortierung verwenden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8943478424576832224" datatype="html">
+ <source>Purged Snapdirs</source>
+ <target>Bereinigte Snapdirs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7553321860087551262" datatype="html">
+ <source>OSDs have converted snapsets</source>
+ <target>OSDs besitzen konvertierte Snapsets</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6509988280998256208" datatype="html">
+ <source>Recovery Deletes</source>
+ <target>Löschvorgänge bei Wiederherstellungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="451760144355116641" datatype="html">
+ <source>Deletes performed during recovery instead of peering</source>
+ <target>Bei der Wiederherstellung anstelle des Peerings durchgeführte Löschvorgänge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="87832369463084597" datatype="html">
+ <source>PG Log Hard Limit</source>
+ <target>Hardlimit für Platzierungsgruppen-Protokoll</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9135782750879343185" datatype="html">
+ <source>Puts a hard limit on pg log length</source>
+ <target>Legt ein Hardlimit für die Platzierungsgruppen-Protokolllänge fest</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="formTitle" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <note priority="1" from="description">Example: Create Pool</note>
+ <note priority="1" from="meaning">form title</note>
+ </trans-unit>
+ <trans-unit id="43ecf6bee2aebc07b0aad6dc1fe13e38d14687fa" datatype="html">
+ <source>Shared devices</source>
+ <target>Geteilte Laufwerke</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7a1c376f6f1b37de4c318ff2106255ba6c0f5b0b" datatype="html">
+ <source>WAL slots</source>
+ <target>WAL Slots</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73811a6f37b63e6b0e491e221bfa21e9dea8a87a" datatype="html">
+ <source>How many OSDs per WAL device.</source>
+ <target>Wie viele OSDs pro WAL-Laufwerk.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c67a7ac4762ef1cc855056c6b4daab93e53a0a5" datatype="html">
+ <source>Specify 0 to let Orchestrator backend decide it.</source>
+ <target>Geben Sie 0 an, um das Orchestrator-Backend entscheiden zu lassen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bda9362e06e6c67341b4a8425b0d29d6b84464b" datatype="html">
+ <source>Value should be greater than or equal to 0</source>
+ <target>Der Wert sollte größer als oder gleich 0 sein</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="324c2b10152b9dd908222bb0b71f61beb60a30c5" datatype="html">
+ <source>DB slots</source>
+ <target>DB Slots</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c23cf12ef9c76f37fc7a4b7ae3e00fb0f68b6e26" datatype="html">
+ <source>How many OSDs per DB device.</source>
+ <target>Wie viele OSDs pro DB-Laufwerk.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8255877266497322342" datatype="html">
+ <source>Encryption</source>
+ <target>Verschlüsselung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b49d7877d24112d4bdfce9256edf61a007fae888" datatype="html">
+ <source>OSDs List</source>
+ <target>OSD-Liste</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="172ada0fcf6490b24a897517e9f4299215873ff8" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD(s) <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be marked <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <target><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD(s) <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> werden als <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> markiert, wenn Sie fortfahren.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">59,60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="262a49e60d5f6ed9825582ccf3d5ae39daa1da60" datatype="html">
+ <source>The <x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> not safe to be <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>! <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></source>
+ <target><x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> nicht sicher <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>! <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71,72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="74bd20d5f558d14cb2fa41ae863cf09c47d02018" datatype="html">
+ <source>{VAR_SELECT, select, true {OSD is} other {OSDs are}}</source>
+ <target>{VAR_SELECT, select, true {OSD kann} other {OSDs können} }</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0e217fd717c5b1f5c17f00c5b174de855acbef0" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <target><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> wird <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>, wenn Sie fortfahren.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">74,75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8cf121660bed7098516a1efe85831d6f415a9411" datatype="html">
+ <source>Preserve OSD ID(s) for replacement.</source>
+ <target>Bewahren Sie die OSD ID(s) für den Austausch auf.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4435645098786961170" datatype="html">
+ <source>out</source>
+ <target>aus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136018875175606726" datatype="html">
+ <source>in</source>
+ <target>ein</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1301930865667956193" datatype="html">
+ <source>down</source>
+ <target>ausgefallen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1226060325201042854" datatype="html">
+ <source>Mark</source>
+ <target>Markieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1256299033316818951" datatype="html">
+ <source>OSD lost</source>
+ <target>OSD verloren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2795727560928976873" datatype="html">
+ <source>marked lost</source>
+ <target>markierter Verlust</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7685933846431786388" datatype="html">
+ <source>Purge</source>
+ <target>Bereinigen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5941516286393808546" datatype="html">
+ <source>OSD</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3416443212235382421" datatype="html">
+ <source>purged</source>
+ <target>bereinigt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9191368063029792986" datatype="html">
+ <source>destroy</source>
+ <target>vernichten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4425946029386289247" datatype="html">
+ <source>destroyed</source>
+ <target>vernichtet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2870788902465061969" datatype="html">
+ <source>Flags</source>
+ <target>Flags</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8995035642420075344" datatype="html">
+ <source>Recovery Priority</source>
+ <target>Wiederherstellungspriorität</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3601135996773579607" datatype="html">
+ <source>PG scrub</source>
+ <target>PG Scrub</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136079353894161076" datatype="html">
+ <source>Device class</source>
+ <target>Geräte-Klasse</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6382718875453721838" datatype="html">
+ <source>PGs</source>
+ <target>Platzierungsgruppen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3660230483843323377" datatype="html">
+ <source>Read bytes</source>
+ <target>Bytes einlesen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">329</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3909578649547040612" datatype="html">
+ <source>Write bytes</source>
+ <target>Bytes schreiben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3182358405280886750" datatype="html">
+ <source>Read ops</source>
+ <target>Lesevorgänge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171292502535561083" datatype="html">
+ <source>Write ops</source>
+ <target>Schreibvorgänge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6706824709967518168" datatype="html">
+ <source>Edit OSD: <x id="PH" equiv-text="selectedOsd.id"/></source>
+ <target>Editiere OSD: <x id="PH" equiv-text="selectedOsd.id"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">451</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1125148356983553148" datatype="html">
+ <source>Edit OSD</source>
+ <target>Editiere OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="970212458427610374" datatype="html">
+ <source>Updated OSD '<x id="PH" equiv-text="selectedOsd.id"/>'</source>
+ <target>Aktualisierter OSD '<x id="PH" equiv-text="selectedOsd.id"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">466</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7554728686176829307" datatype="html">
+ <source>Mark OSD <x id="PH" equiv-text="markAction"/></source>
+ <target>Markiere OSD <x id="PH" equiv-text="markAction"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="478122291463667978" datatype="html">
+ <source>Mark <x id="PH" equiv-text="markAction"/></source>
+ <target>Markiere <x id="PH" equiv-text="markAction"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">502</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2456043080471762298" datatype="html">
+ <source>delete</source>
+ <target>löschen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">530</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="588230151780724018" datatype="html">
+ <source>deleted</source>
+ <target>gelöscht</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">532</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1ef1c12ddcee305353623919ef02778569f5454" datatype="html">
+ <source>Advanced configuration options</source>
+ <target>Erweiterte Konfigurationsoptionen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7771252117308888928" datatype="html">
+ <source>PG scrub options</source>
+ <target>PG Scrub-Optionen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1797901277775175680" datatype="html">
+ <source>Updated PG scrub options</source>
+ <target>Aktualisierte PG Scrub-Optionen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c35f9c5f268a514b970cc55e9a5dc4bed0988e7f" datatype="html">
+ <source>OSD Recovery Priority</source>
+ <target>OSD-Wiederherstellungspriorität</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74af38005e8a8914e45af2ec412e11ceafef8b6" datatype="html">
+ <source>Priority</source>
+ <target>Priorität</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f48f04b379bfba133825747adfd238d511412e" datatype="html">
+ <source>Customize priority values</source>
+ <target>Prioritätswerte anpassen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aa19de2a2b54cbda39e9c62917b23044c087776" datatype="html">
+ <source>This field is required!</source>
+ <target>Dies ist ein Pflichtfeld!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">406</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b699e94bf376491bd50b70a98531071c737eaf40" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="98fe13e7ad6c2b80375d204b47858ded83f80e15" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>.</source>
+ <target>Der eingegebene Wert ist zu groß! Er darf nicht größer als <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/> sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423a3c111be47fc5a1bfe46ceb58c81c84db691" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>.</source>
+ <target>Der eingegebene Wert ist zu niedrig! Er darf nicht kleiner als <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/> sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3234179038052466481" datatype="html">
+ <source>Max Backfills</source>
+ <target>Max. Abgleiche</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847070960491384020" datatype="html">
+ <source>Recovery Max Active</source>
+ <target>Wiederherstellung, max. aktiv</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2088615724570210504" datatype="html">
+ <source>Recovery Max Single Start</source>
+ <target>Wiederherstellung, max. - einzelner Start</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8627094894361422565" datatype="html">
+ <source>Recovery Sleep</source>
+ <target>Wiederherstellung - Inaktivität</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7590013429208346303" datatype="html">
+ <source>Custom</source>
+ <target>Benutzerdefiniert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4937275625032609020" datatype="html">
+ <source>Updated OSD recovery speed priority '<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>'</source>
+ <target>Priorität für OSD-Wiederherstellungsgeschwindigkeit '<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>' aktualisiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">227,229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5251a4355cece3075db43f15d69a24a0f8485707" datatype="html">
+ <source>Reweight OSD: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></source>
+ <target>OSD neu gewichten: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67650b2998db48201b2c6176cbfef51e7211ccaa" datatype="html">
+ <source>The value needs to be between 0 and 1.</source>
+ <target>Der Wert muss zwischen 0 und 1 liegen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f077ceb52c967a8fe2de9ef0a9d65d72badf186" datatype="html">
+ <source>OSDs <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/>Scrub</source>
+ <target><x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/> OSD-Scrub</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b73a34ba65b3073e3560dce828a16d7fd3c0f4" datatype="html">
+ <source>{VAR_SELECT, select, true {Deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {Umfassender} other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c00119503aad4012b77049eee41293338f67756c" datatype="html">
+ <source>You are about to apply a <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/>scrub to the OSD(s): <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <target>Sie sind dabei, einen <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/> Scrub auf OSD(s) <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>anzuwenden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fad3dc421817a16dd6c46c1a0c36de619a8d776e" datatype="html">
+ <source>{VAR_SELECT, select, true {deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {umfassenden} other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1086427836866943370" datatype="html">
+ <source><x id="PH" equiv-text="operation"/> was initialized in the following OSD(s): <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></source>
+ <target><x id="PH" equiv-text="operation"/> wurde in den folgenden OSD(s) initialisiert: <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts</context>
+ <context context-type="linenumber">42,44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47c97aa28f64b11fa5842795fdd02c8c0863c97b" datatype="html">
+ <source>To see all active Prometheus alerts, please provide the URL to the API of Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>Um jeden aktiven Prometheus-Alarm zu sehen, geben Sie die URL zur API des Prometheus Alertmanagers an, wie in der <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> beschrieben.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6343323763459782070" datatype="html">
+ <source>Create Silence</source>
+ <target>Stummschaltung erstellen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1895957424873987405" datatype="html">
+ <source>Job</source>
+ <target>Job</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491474782694268231" datatype="html">
+ <source>Severity</source>
+ <target>Gewichtung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3326877877555410533" datatype="html">
+ <source>Started</source>
+ <target>Gestartet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2375260419993138758" datatype="html">
+ <source>URL</source>
+ <target>URL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="880ad4df5a2051a437321443d69c9a866699e5ad" datatype="html">
+ <source>Active Alerts</source>
+ <target>Aktive Warnungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9fe218829514884cdd0ca2300573a4e0428c324f" datatype="html">
+ <source>Alerts</source>
+ <target>Warnungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa0c44aa1e5727061baa91e954f77e2f5f9a37c9" datatype="html">
+ <source>Silences</source>
+ <target>Stummschaltungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85c737325f5e59517e2d08a71de6d77788aabc95" datatype="html">
+ <source>To see all configured Prometheus alerts, please provide the URL to the API of Prometheus as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>Um jeden konfigurierten Prometheus-Alarm zu sehen, geben Sie die URL zur Prometheus-API an, wie in der <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> beschrieben.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623978917681527907" datatype="html">
+ <source>Group</source>
+ <target>Gruppe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7410432243549869948" datatype="html">
+ <source>Duration</source>
+ <target>Dauer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4109205891084963566" datatype="html">
+ <source>Query</source>
+ <target>Abfrage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28f86ffd419b869711aa13f5e5ff54be6d70731c" datatype="html">
+ <source>Edit</source>
+ <target>Bearbeiten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="826b25211922a1b46436589233cb6f1a163d89b7" datatype="html">
+ <source>Delete</source>
+ <target>Löschen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">279</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">341</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">441</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3ba06aba047605af8ea1718ec1ba153b7db12a2" datatype="html">
+ <source>Editing a silence will expire the old silence and recreate it as a new silence</source>
+ <target>Das Bearbeiten einer Stummschaltung löscht die vorherige und legt eine neue Stummschaltung an.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a20424156b8816671f61879f0574a4f27d7b16b9" datatype="html">
+ <source>Creator</source>
+ <target>Ersteller</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5a5d7ee2acbfa9c91ab7f41d26bda9ff0cafe42f" datatype="html">
+ <source>Comment</source>
+ <target>Kommentar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c11aad490b2d53fdae30b3807beabf79306752c" datatype="html">
+ <source>Start time</source>
+ <target>Startzeit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32856b1e8e339b747b21e313e2fe65a51fd450bb" datatype="html">
+ <source>If the start time lies in the past the creation time will be used</source>
+ <target>Wenn die Startzeit in der Vergangenheit liegt, wird die Erstellungszeit verwendet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a02ea1d4e7424ca989929da5e598f379940fdbf2" datatype="html">
+ <source>Duration</source>
+ <target>Dauer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f4e35e36f4d3c62e2c17df41730b6dee4afc4b9" datatype="html">
+ <source>End time</source>
+ <target>Ende</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="992123459137d45c15df5548bc9682aad835c04b" datatype="html">
+ <source>Matchers</source>
+ <target>Matchers</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e023166c55833d5a13f4143e3dbe372befe1b4e" datatype="html">
+ <source>A silence requires at least one matcher</source>
+ <target>Für eine Stummschaltung ist mindestens ein Matcher erforderlich</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef765bd80c4806c51c891908c07a24bc76f019eb" datatype="html">
+ <source>Add matcher</source>
+ <target>Matcher hinzufügen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754178820914251524" datatype="html">
+ <source>silence</source>
+ <target>Stummschaltung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8714559758543060819" datatype="html">
+ <source>Attribute name</source>
+ <target>Attributname</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1338733395833138319" datatype="html">
+ <source>Regular expression</source>
+ <target>Regulärer Ausdruck</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35819898450851998" datatype="html">
+ <source>Please add your Prometheus host to the dashboard configuration and refresh the page</source>
+ <target>Bitte fügen Sie Ihren Prometheus-Host zur Dashboard-Konfiguration hinzu und aktualisieren die Seite</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f2f4cb9d876ff9d34fc082c1ac642d3cb98c360" datatype="html">
+ <source>To enable Silences, please provide the URL to the API of the Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>Um Stummschaltungen zu aktivieren, geben Sie die URL zur API des Prometheus Alertmanagers an, wie in der <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> beschrieben.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7448808151142843482" datatype="html">
+ <source>Created by</source>
+ <target>Erstellt von</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4734349318830134239" datatype="html">
+ <source>Ends</source>
+ <target>Endet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1233087251567318644" datatype="html">
+ <source>Silence</source>
+ <target>Stummschaltung </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="78af6a5e6e4d305557054b64d10f9f9446d8043d" datatype="html">
+ <source>{VAR_SELECT, select, true {Edit} other {Add}}</source>
+ <target>{VAR_SELECT, select, true {bearbeiten} other {hinzufügen} }</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2404fa8e80946d0ce3d0ae369b51cb26ec28d42" datatype="html">
+ <source><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/> Matcher</source>
+ <target>Matcher <x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c25e04f554875dc2625a78ba0fc56c6010cd0d3" datatype="html">
+ <source>-- Select an attribute to match against --</source>
+ <target>-- Wählen Sie das zu vergleichende Attribut --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5049e204c14c648691ac775a64fb504467aeb549" datatype="html">
+ <source>Value</source>
+ <target>Wert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="77fc5c63497fc031ddc97645484e3d94ad27766c" datatype="html">
+ <source>Use regular expression</source>
+ <target>Regulären Ausdruck verwenden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5518753745858598442" datatype="html">
+ <source>no spec</source>
+ <target>No Spez.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1186363766752354382" datatype="html">
+ <source>unmanaged</source>
+ <target>nicht verwaltet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5246585784774990516" datatype="html">
+ <source>count:<x id="PH" equiv-text="count"/></source>
+ <target>Anzahl:<x id="PH" equiv-text="count"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001661117318762535" datatype="html">
+ <source>label:<x id="PH" equiv-text="label"/></source>
+ <target>Label:<x id="PH" equiv-text="label"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cb3aa7e9fea1d445a1a9d7797ab17e6ac6fe13b" datatype="html">
+ <source>Service Events</source>
+ <target>Dienst-Ereignisse</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3474944817987674409" datatype="html">
+ <source>Daemon type</source>
+ <target>Daemon-Typ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3136939605470297323" datatype="html">
+ <source>Daemon ID</source>
+ <target>Daemon-ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8171022601808215887" datatype="html">
+ <source>Container ID</source>
+ <target>Container-ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8859473568390700297" datatype="html">
+ <source>Container Image name</source>
+ <target>Container-Imagename</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5623167616584404899" datatype="html">
+ <source>Container Image ID</source>
+ <target>Container-Image-ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="335348913532561915" datatype="html">
+ <source>Last Refreshed</source>
+ <target>Zuletzt aktualisiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3022087209429182774" datatype="html">
+ <source>Daemon Events</source>
+ <target>Daemon-Ereignisse</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">140</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8604852007710946848" datatype="html">
+ <source>Service Name</source>
+ <target>Dienst-Name</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="613875387304159316" datatype="html">
+ <source>Service Type</source>
+ <target>Diensttyp</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907644935670421963" datatype="html">
+ <source>Service Events</source>
+ <target>Dienst-Ereignisse</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3214a1f3a4c3e89a848b4ec59adeeda3b913c396" datatype="html">
+ <source>-- Select a service type --</source>
+ <target>-- Diensttyp auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f32579a9fd19d93c083175284ee3426d78751c33" datatype="html">
+ <source>Backend Service</source>
+ <target>Backend-Dienst</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2937074aed12b8158e929c58747a8216433b72b" datatype="html">
+ <source>-- No service available --</source>
+ <target>-- Kein Dienst verfügbar --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19fb4480d95a5539db4e9c7b516d414774e61110" datatype="html">
+ <source>-- Select an existing RGW service --</source>
+ <target>-- Einen vorhandenen RGW-Dienst auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2798cc1e152b1ec07fd8daf94a2a073d1ba1ebcc" datatype="html">
+ <source>Id</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d5156b9d9a79d162c353c4aa9bc6840ad5c6257" datatype="html">
+ <source>The value does not match the pattern <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&lt;service_id&gt;[.&lt;realm_name&gt;.&lt;zone_name&gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <target>Der Wert stimmt nicht mit dem Muster <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&amp;lt;service_id&amp;gt;[.&amp;lt;realm_name&amp;gt;.&amp;lt;zone_name&amp;gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> überein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83d5d7edd8a0be253c4e93ad4c3efe86d9ac520f" datatype="html">
+ <source>Unmanaged</source>
+ <target>Nicht verwaltet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c15fa461935e0f600bc5d1660af1da67f024fc2a" datatype="html">
+ <source>Placement</source>
+ <target>Platzierung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="863226cffd5b66a6fee9810a9282a5006d6ef576" datatype="html">
+ <source>Label</source>
+ <target>Label</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06412bce0f4fe4311193e9763666089bf9d980da" datatype="html">
+ <source>Count</source>
+ <target>Anzahl</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f193722f1e788f14a823b89ac1794c3ba934f9f" datatype="html">
+ <source>Only that number of daemons will be created.</source>
+ <target>Es wird nur diese Anzahl an Daemons erstellt.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee1a29cc658e4fa891be762d7bae96139b57c8f4" datatype="html">
+ <source>The value must be at least 1.</source>
+ <target>Der Wert muss mindestens 1 sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">369</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cb2741a46e3560f6bc6dfd99d385e86b08b26d72" datatype="html">
+ <source>Port</source>
+ <target>Port</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a23ed3598cca5285606675b6cb2536a56b411ade" datatype="html">
+ <source>The value cannot exceed 65535.</source>
+ <target>Der Wert darf 65535 nicht überschreiten.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">404</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d8ebdc326e6b9ff35feee3f762b7ab39c02d78f" datatype="html">
+ <source>-- No pools available --</source>
+ <target>-- Keine Pools verfügbar --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84b675705324741b954615fedf2417d4d873b0b6" datatype="html">
+ <source>Trusted IPs</source>
+ <target>Gesicherte IPs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b543e7c787cc48c2938cbce2d14c6afea5a598df" datatype="html">
+ <source>Comma separated list of IP addresses.</source>
+ <target>Kommagetrennte Liste der IP-Adressen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1039ea40da18a6453d9c1adc72a35aed099029d0" datatype="html">
+ <source>Please add the <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> IP addresses here, otherwise the iSCSI gateways can't be reached.</source>
+ <target>Bitte fügen Sie die IP-Adressen des <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> hier hinzu, andernfalls können die iSCSI-Gateways nicht erreicht werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6265b64c17a1e19775769489bfd0b152fa1f3ba1" datatype="html">
+ <source>Virtual IP</source>
+ <target>Virtuelle IP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61893fde6e9e05a6b91619d501edaa7962b438ff" datatype="html">
+ <source>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</source>
+ <target>Die virtuelle IP-Adresse und das Subnetz (in CIDR-Notation), über die der Eintrittsdienst verfügbar ist.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">333</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ece04ddf7e96f445415ebd90d93c455e03e8cf53" datatype="html">
+ <source>Frontend Port</source>
+ <target>Frontend-Port</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">352</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae6fd97454d184b374984c9ff808176ece54f0dd" datatype="html">
+ <source>The port used to access the ingress service.</source>
+ <target>Der verwendete Port, um auf den Eintrittsdienst zuzugreifen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1261eacf161f75efc9dfea84dd97b4a466b89aa1" datatype="html">
+ <source>Monitor Port</source>
+ <target>Monitor-Port</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4df6281ed630ba96f09790a46a7fe0ec0e666bb6" datatype="html">
+ <source>The port used by haproxy for load balancer status.</source>
+ <target>Der von Haproxy für den Lastausgleicher-Status verwendete Port.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ce24ae1d792ed2846ba57e7ed6397a802caeff5" datatype="html">
+ <source>CIDR Networks</source>
+ <target>CIDR-Netzwerke</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">414</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7c13184af0c09e3bad77daa5f4869138708d26b2" datatype="html">
+ <source>A list of networks to identify which network interface to use for the virtual IP address.</source>
+ <target>Eine Liste von Netzwerken, die angibt, welche Netzwerkschnittstelle für die virtuelle IP-Adresse zu verwenden ist.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8fe73a4787b8068b2ba61f54ab7e0f9af2ea1fc9" datatype="html">
+ <source>Version</source>
+ <target>Version</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a6855d17f6b9820bb9709870efdcc7da99552d3" datatype="html">
+ <source>-- Select SNMP version --</source>
+ <target>-- SNMP-Version auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">442</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a7369891e88cd613e45a39b55a282c97776d05f5" datatype="html">
+ <source>Destination</source>
+ <target>Zielort</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f09a5d334a73a4b5ba031d7fa65151cad5ec7133" datatype="html">
+ <source>Must be of the format hostname:port.</source>
+ <target>Muss im folgenden Format sein: hostname:port.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b68c79ffe3af1db88180454fbc2fa880a51ccf52" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>hostname:port<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>Der Wert entspricht nicht dem Muster: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>hostname:port<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">470</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c90ad98a026d781ab729911873767e549d78f99" datatype="html">
+ <source>Engine Id</source>
+ <target>Engine-ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">478</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d39d015ebd667fb6bddf08bb0e5b3faa6cf044c" datatype="html">
+ <source>Unique identifier for the device (in hex).</source>
+ <target>Eindeutiger Bezeichner für das Laufwerk (in hex).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">480</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514cda7dc49062c5c532427245ce47c4954bc32" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>Der Wert entspricht nicht dem Muster: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>muss in hexadezimal sein und die Länge eine Vielfaches von 2 mit einem Mindestwert = 10 und einem Maximalwert = 64.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b2d628c51192ade0044212b409c758c20f9c021" datatype="html">
+ <source>Auth Protocol</source>
+ <target>Auth.-Protokoll</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc8bb2315a5101770a752b18e03b5c730539397c" datatype="html">
+ <source>-- Select auth protocol --</source>
+ <target>-- Auth.-Protokoll auswählen--</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">508</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6777f99fd13e03874afe26ba7289dc9fc211af04" datatype="html">
+ <source>Privacy Protocol</source>
+ <target>Datenschutz-Protokoll</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70512b7c13bce85b3928920b29fafbd59a853383" datatype="html">
+ <source>-- Select privacy protocol --</source>
+ <target>-- Datenschutzprotokoll auswählen--</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b48c81465d14465b95826b99e05acfabef1814c6" datatype="html">
+ <source>Credentials</source>
+ <target>Anmeldedaten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">541</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4ea0163c25c818aab982072b1b8d5ab585e9a5a" datatype="html">
+ <source>SNMP Community</source>
+ <target>SNMP-Community</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">547</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="08c74dc9762957593b91f6eb5d65efdfc975bf48" datatype="html">
+ <source>Username</source>
+ <target>Benutzername</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="948758e1412bb2ecdb98e3a4f1cbb6d7458456f2" datatype="html">
+ <source>Encryption</source>
+ <target>Verschlüsselung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">598</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e65610b5d940367f1ff6b57772b96e94e35fe202" datatype="html">
+ <source>SSL</source>
+ <target>SSL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">624</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e37e0d06148c7708e88b4a1eb412babbe1a4afc" datatype="html">
+ <source>Certificate</source>
+ <target>Zertifikat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">634</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="295ae4f632322098deca8a3ddfbc7aeaabb5423b" datatype="html">
+ <source>The SSL certificate in PEM format.</source>
+ <target>Das SSL-Zertifikat im PEM-Format.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">635</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464272c069fe56f6c50f41f426a25b2a42c95ba5" datatype="html">
+ <source>Invalid SSL certificate.</source>
+ <target>Ungültiges SSL-Zertifikat.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">650</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0596d06bf1f8a15d4bfe56226971ecdd78013b1f" datatype="html">
+ <source>Private key</source>
+ <target>Privater Schlüssel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">659</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ded15dc55104994c0230189f34dff84a4955aafb" datatype="html">
+ <source>The SSL private key in PEM format.</source>
+ <target>Der private SSL-Schlüssel im PEM-Format.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">660</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19bdc1597d815b456793ff87c89af4257a85a103" datatype="html">
+ <source>Invalid SSL private key.</source>
+ <target>Ungültiger privater SSL-Schlüssel.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">675</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3356018487523380058" datatype="html">
+ <source>service</source>
+ <target>Dienst</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2412938991511187011" datatype="html">
+ <source>There are no hosts.</source>
+ <target>Es gibt keine Hosts.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2594503755408511486" datatype="html">
+ <source>Filter hosts</source>
+ <target>Hosts filtern</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5869780110608474933" datatype="html">
+ <source>Placement</source>
+ <target>Platzierung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2956098160626271284" datatype="html">
+ <source>Running</source>
+ <target>Ausgeführt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="013f48ee777d2e53e2bcba36e1a99fcbb7ef8cb6" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report configuration</source>
+ <target>Schritt <x id="INTERPOLATION" equiv-text="{{ step }}"/> von 2: Konfiguration Telemetriebericht</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a09b723a928774bff707973c99999dcf3d84a349" datatype="html">
+ <source>The telemetry module sends anonymous data about this Ceph cluster back to the Ceph developers to help understand how Ceph is used and what problems users may be experiencing.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> This data is visualized on <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>public dashboards<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> that allow the community to quickly see summary statistics on how many clusters are reporting, their total capacity and OSD count, and version distribution trends.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> The data being reported does <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>not<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> contain any sensitive data like pool names, object names, object contents, hostnames, or device serial numbers. It contains counters and statistics on how the cluster has been deployed, the version of Ceph, the distribution of the hosts and other parameters which help the project to gain a better understanding of the way Ceph is used. The data is sent secured to <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> and <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (device report).</source>
+ <target>Das Telemetriemodul übermittelt anonyme Daten zu diesem Ceph-Cluster an die Ceph-Entwickler, um zu verdeutlichen, wie Ceph verwendet wird und welche Probleme Benutzer möglicherweise haben.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Diese Daten werden in <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>öffentlichen Dashboards<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> visualisiert. So erhält die Community schnell eine zusammenfassende Statistik dazu, wie viele Cluster Berichte zur Verfügung stellen, wie hoch die Gesamtkapazität und die OSD-Anzahl ist und welche Trends zur Versionsbereitstellung vorliegen.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/>Die Daten in den Berichten umfassen <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>keine<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> vertraulichen Informationen wie Pool- oder Objektnamen, Objektinhalte, Hostnamen oder Laufwerksseriennummern. Sie enthalten Indikatoren und Statistiken dazu, wie der Cluster bereitgestellt wurde, zur Ceph-Version, zur Bereitstellung der Hosts und anderen Parametern, die im Projekt zu einem besseren Verständnis der Verwendung von Ceph führen. Die Daten werden gesichert an <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> und <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (Laufwerksbericht) gesendet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">14,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c95505b5a74151a0c235b19b9c41db7983205ba7" datatype="html">
+ <source>Deactivate</source>
+ <target>Deaktivieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19" datatype="html">
+ <source>Channels</source>
+ <target>Kanäle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e25b17c0b4ef361b6a05aaec2bbd2b7e86680458" datatype="html">
+ <source>The telemetry report is broken down into several &quot;channels&quot;, each with a different type of information that can be configured below.</source>
+ <target>Der Telemetriebericht ist in mehrere &quot;Kanäle&quot; unterteilt, die jeweils eine andere Art von Informationen enthalten, die unten konfiguriert werden können.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">32,33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380ab580741bec31346978e7cab8062d6970408d" datatype="html">
+ <source>Basic</source>
+ <target>Grundlegend</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd898057f0add35258a5fb5c90d792c5e2147452" datatype="html">
+ <source>Includes basic information about the cluster:</source>
+ <target>Enthält grundlegende Informationen zum Cluster:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da213e9ba8a86b453d04f794f58c9803f7b062b1" datatype="html">
+ <source>Capacity of the cluster</source>
+ <target>Kapazität des Clusters</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d5fe31d9e13239bdd223d0bbd289a1b1903e86" datatype="html">
+ <source>Number of monitors, managers, OSDs, MDSs, object gateways, or other daemons</source>
+ <target>Anzahl der Monitore, Manager, OSDs, MDSs, Objektgateways oder anderer Daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a3eb7834b4baf412f8863d14883972897d9acb7" datatype="html">
+ <source>Software version currently being used</source>
+ <target>Derzeit verwendete Softwareversion</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34881ae65482ffa74ccb4043fb2622e48ed146d5" datatype="html">
+ <source>Number and types of RADOS pools and CephFS file systems</source>
+ <target>Anzahl und Typen der RADOS-Pools und CephFS-Dateisysteme</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="696f8f5ea7a9cf6125b9a3af160981fda363552d" datatype="html">
+ <source>Names of configuration options that have been changed from their default (but not their values)</source>
+ <target>Namen der Konfigurationsoptionen, deren Standardeinstellungen geändert wurden (aber nicht ihre Werte)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34292940316300d09abe5e675d452fae199f626b" datatype="html">
+ <source>Crash</source>
+ <target>Absturz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7620e332b7dea1e832158e85847255eb4d9e6bbc" datatype="html">
+ <source>Includes information about daemon crashes:</source>
+ <target>Enthält Informationen zu Daemonabstürzen:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1aa4306a6e840fe35b70c9b07d38ce85f281cfa" datatype="html">
+ <source>Type of daemon</source>
+ <target>Daemontyp</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4f2cbedb4b14b68bc9f390e3391445c1b6682da" datatype="html">
+ <source>Version of the daemon</source>
+ <target>Daemonversion</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d62603cdc75645ea873fc8f7f69c32b5f4a2aa9" datatype="html">
+ <source>Operating system (OS distribution, kernel version)</source>
+ <target>Betriebssystem (Bereitstellung des Betriebssystems, Kernelversion)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84facf84a73631d66e9a4e0bc1c40097b9d14742" datatype="html">
+ <source>Stack trace identifying where in the Ceph code the crash occurred</source>
+ <target>Stacktrace mit Identifikation, wo im Ceph-Code der Absturz auftrat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea64d4177bd648e1a20c92669e6857762b811d8c" datatype="html">
+ <source>Device</source>
+ <target>Laufwerk</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4bc37bcbbcea881a269b4063b3d93dec8ee67d5" datatype="html">
+ <source>Includes information about device metrics like anonymized SMART metrics.</source>
+ <target>Enthält Informationen über Laufwerksmetriken wie anonymisierte SMART-Metriken.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37de70e8ba539187d0171a38dad2a63c323096eb" datatype="html">
+ <source>Ident</source>
+ <target>Ident</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b126025440f118cd02ce78362d61a5001c27617" datatype="html">
+ <source>Includes user-provided identifying information about the cluster:</source>
+ <target>Enthält vom Benutzer bereitgestellte identifizierende Informationen zum Cluster:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62c6e9aecff7e04ef7d36fdee4ab4fb285a7a2b5" datatype="html">
+ <source>Contact Information</source>
+ <target>Kontaktinformationen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61ba9a84051b3f470122e59cf5a746552b378269" datatype="html">
+ <source>Submitting any contact information is completely optional and disabled by default.</source>
+ <target>Das Senden von Kontaktinformationen ist vollständig optional und standardmäßig deaktiviert.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34746fb1c7f3d2194d99652bdff89e6e14c9c4f4" datatype="html">
+ <source>Contact</source>
+ <target>Kontakt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="632cac1e025b77b2d77fed16ad22a410ddacab9e" datatype="html">
+ <source>My first Ceph cluster</source>
+ <target>Mein erster Ceph-Cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3a58c8a81b9ffda26a154eae25a422c9f7de37b" datatype="html">
+ <source>Organization</source>
+ <target>Organisation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e8fda44e2c5bb51860f26cd9c2730f9ae1db9869" datatype="html">
+ <source>Organization name</source>
+ <target>Organisationsname</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d49310535abb3792d8c9c991dd0d990d73d29af" datatype="html">
+ <source>Interval</source>
+ <target>Intervall</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91317562c9dfefbdd5973faf11d217f571d073c7" datatype="html">
+ <source>The module compiles and sends a new report every 24 hours by default. You can adjust this interval by setting a different number of hours.</source>
+ <target>Das Modul erstellt und sendet standardmäßig alle 24 Stunden einen neuen Bericht. Sie können dieses Intervall anpassen, indem Sie eine andere Anzahl von Stunden einstellen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">185,186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a12cf4cf71ef3161a024382ab542cf0eba094504" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to 8.</source>
+ <target>Der eingegebene Wert ist zu niedrig. Er muss größer als 8 sein oder diesem Wert entsprechen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a92e437fac14b4010c4515b31c55a311d026a57f" datatype="html">
+ <source>Proxy</source>
+ <target>Proxy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6de03357358c7eff62aca486508bb5c2046e0669" datatype="html">
+ <source>If the cluster cannot directly connect to the configured telemetry endpoint (default telemetry.ceph.com), you can configure a HTTP/HTTPS proxy server by e.g. adding https://10.0.0.1:8080</source>
+ <target>Wenn der Cluster keine direkte Verbindung mit dem konfigurierten Telemetrie-Endpunkt (standardmäßig telemetry.ceph.com) herstellen kann, können Sie einen HTTP/HTTPS-Proxyserver konfigurieren, indem Sie beispielsweise https://10.0.0.1:8080 hinzufügen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5687a733af051bfca97dbffba282e39fbb9b8c8f" datatype="html">
+ <source>You can also include a user:pass if needed e.g. https://ceph:telemetry@10.0.0.1:8080</source>
+ <target>Sie können bei Bedarf auch einen user:pass hinzufügen, z. B. https://ceph:telemetry@10.0.0.1:8080</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e6430c68df43ea65e4145972b01186fba40f26a" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Note:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> By clicking 'Next' you will first see a preview of the report content before you can activate the automatic submission of your data.</source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Hinweis:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> Wenn Sie auf &quot;Weiter&quot; klicken, sehen Sie zunächst eine Vorschau auf den Berichtsinhalt, bevor Sie die automatische Übermittlung Ihrer Daten aktivieren können.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">219,220</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d8d878f8d60905e1306c225716305a331b784c8" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report preview</source>
+ <target>Schritt <x id="INTERPOLATION" equiv-text="{{ step }}"/> von 2: Vorschau Telemetriebericht</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e23d0064b6474f309c74e1c928cc0920f479d9a5" datatype="html">
+ <source>Report ID <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <target>Berichts-ID <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">249,252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4060e92658964e356a0992a900c8aa811c2cfec0" datatype="html">
+ <source>A randomized UUID to identify a particular cluster over the course of several telemetry reports.</source>
+ <target>Eine UUID nach dem Zufallsprinzip zur Identifizierung eines bestimmten Clusters im Verlauf mehrerer Telemetrieberichte.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60900bc663571f852a04950a123508b106d97204" datatype="html">
+ <source>Report preview <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <target>Berichtsvorschau <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">267,270</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3de417f739c336284c42904552e81e8d852daecc" datatype="html">
+ <source>The actual telemetry data that will be submitted.</source>
+ <target>Die tatsächlichen Telemetriedaten, die übermittelt werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="933a2b6f087670ff42c95876e6ecfb2faa3e3867" datatype="html">
+ <source>I agree to my telemetry data being submitted under the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Community Data License Agreement - Sharing - Version 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></source>
+ <target>Ich bin damit einverstanden, dass meine Telemetriedaten im Rahmen der <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Community-Datenlizenzvereinbarung - Freigabe - Version 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> übermittelt werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">304</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8293060085588842566" datatype="html">
+ <source>The Telemetry module has been configured and activated successfully.</source>
+ <target>Das Telemetriemodul wurde erfolgreich konfiguriert und aktiviert.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5380636888677486786" datatype="html">
+ <source>An Error occurred while updating the Telemetry module configuration. Please Try again</source>
+ <target>Während der Aktualisierung der Telemetriemodul-Konfiguration ist ein Fehler aufgetreten. Versuchen Sie es erneut.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2bcd3296d2850de762fb943060b7e086a893181" datatype="html">
+ <source>Health</source>
+ <target>Integrität</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61e0f26d843eec0b33ff475e111b0c2f7a80b835" datatype="html">
+ <source>Statistics</source>
+ <target>Statistiken</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73caac4265ea7314ff061e5a1d78a6361a6dd3b8" datatype="html">
+ <source>Cluster Status</source>
+ <target>Clusterstatus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="624f596cc3320f5e0a0d7c7346c364e5af9bdd8c" datatype="html">
+ <source>Monitors</source>
+ <target>Monitore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9183778f2c6473d7ccb080f651caa01faaf70c" datatype="html">
+ <source>OSDs</source>
+ <target>OSDs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c34287a0423968dac8a41463b80855a0ff789403" datatype="html">
+ <source>Managers</source>
+ <target>Manager</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="946ac5dea9921dc09d7b0a63b89535371f283b19" datatype="html">
+ <source>Object Gateways</source>
+ <target>Objektgateways</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff03fa5bcf37c4da46ad736c1f7d03f959e8ba9a" datatype="html">
+ <source>Metadata Servers</source>
+ <target>Metadatenserver</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d817609ba4993eba859409ab71e566168f4d5f5a" datatype="html">
+ <source>iSCSI Gateways</source>
+ <target>iSCSI-Gateways</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ce9dfdc6dccb28dc75a78c704e09dc18fb02dcfa" datatype="html">
+ <source>Capacity</source>
+ <target>Kapazität</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f383269db2d32cccee9e936fe549dccb9fdbf4" datatype="html">
+ <source>Raw Capacity</source>
+ <target>Rohkapazität</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498a109c6e9e94f1966de01aa0326f7f0ac6fb52" datatype="html">
+ <source>PG Status</source>
+ <target>Platzierungsgruppenstatus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5f8a813f91a11af99132e4beafc136cfc13d73b" datatype="html">
+ <source>PGs per OSD</source>
+ <target>Platzierungsgruppen pro OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32efd1c3f70e3c5244239de97a2cc95d98534a14" datatype="html">
+ <source>Client Read/Write</source>
+ <target>Client-Lese-/Schreibvorgänge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="52213660b2454d139ada3079a42ec6caf3c3c01e" datatype="html">
+ <source>Client Throughput</source>
+ <target>Clientdurchsatz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="275485415092cbae3a9f3cbb786ebe283cacfdd5" datatype="html">
+ <source>Recovery Throughput</source>
+ <target>Wiederherstellungsdurchsatz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35416fcdf9cb33d2b299d3f2028c390454b55d02" datatype="html">
+ <source>Scrubbing</source>
+ <target>Scrubbing</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="44ecac93d67c6a671198091c2270354f80322327" datatype="html">
+ <source><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> See <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>Logs<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for more details.</source>
+ <target><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> Weitere Details finden Sie in den <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>Protokollen<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520247697658334435" datatype="html">
+ <source>Reads</source>
+ <target>Lesen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5947645586591788199" datatype="html">
+ <source>/s</source>
+ <target>/s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7527163811128350993" datatype="html">
+ <source>Writes</source>
+ <target>Schreiben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7684088941299429132" datatype="html">
+ <source>IOPS</source>
+ <target>IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81585474102700882" datatype="html">
+ <source>Used</source>
+ <target>Verwendet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">179</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8695656831075719969" datatype="html">
+ <source>Avail.</source>
+ <target>Verf.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6352596107300820129" datatype="html">
+ <source>Clean</source>
+ <target>Fehlerfrei</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4016774570903735270" datatype="html">
+ <source>Working</source>
+ <target>In Bearbeitung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4467323362722952678" datatype="html">
+ <source>Unknown</source>
+ <target>Unbekannt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">218</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7790772795962334429" datatype="html">
+ <source>Healthy</source>
+ <target>Fehlerfrei</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4708847204147472247" datatype="html">
+ <source>Misplaced</source>
+ <target>Fehlplatziert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3120522496446378904" datatype="html">
+ <source>Degraded</source>
+ <target>Unvollständig</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8047698491745405137" datatype="html">
+ <source>Unfound</source>
+ <target>Nicht gefunden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81117556780777231" datatype="html">
+ <source>objects</source>
+ <target>Objekte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795e8a00db46b750113d5db93e8d97e2b3079894" datatype="html">
+ <source>For an overview of <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/> widgets click <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></source>
+ <target>Für einen Überblick über die <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/> Widgets klicken Sie<x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">21,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16bd21c1b48036d54c6a595f5cff2540cfba7f60" datatype="html">
+ <source>here</source>
+ <target>hier</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8515973702474791807" datatype="html">
+ <source>up</source>
+ <target>aktiv</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4223604072115719661" datatype="html">
+ <source>no filesystems</source>
+ <target>keine Dateisysteme</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2078241808113697591" datatype="html">
+ <source>active</source>
+ <target>aktiv</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3232506912392089107" datatype="html">
+ <source>standby</source>
+ <target>Standby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576716133013765863" datatype="html">
+ <source>standby daemons</source>
+ <target>Standby-Daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3629620351427988554" datatype="html">
+ <source>active daemon</source>
+ <target>aktiver Daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5954854563228355745" datatype="html">
+ <source>standbyReplay</source>
+ <target>standbyReplay</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7329683463736701292" datatype="html">
+ <source>n/a</source>
+ <target>n. v.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/not-available.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8271970016544066882" datatype="html">
+ <source><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (quorum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</source>
+ <target><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (Quorum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mon-summary.pipe.ts</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6489441800790477240" datatype="html">
+ <source>total</source>
+ <target>insgesamt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5965118847182332588" datatype="html">
+ <source>near full</source>
+ <target>nahezu voll</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="268166731974484199" datatype="html">
+ <source>full</source>
+ <target>voll</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47116253e36f4e38a97ba41b2d3122c6c15ab904" datatype="html">
+ <source>Clients (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</source>
+ <target>Clients (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5159814115056353668" datatype="html">
+ <source>Addresses</source>
+ <target>Adressen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1811797298582428088" datatype="html">
+ <source>Access Type</source>
+ <target>Zugriffstyp</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3575940435199094878" datatype="html">
+ <source>Squash</source>
+ <target>Squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2944102521023817891" datatype="html">
+ <source>Cluster</source>
+ <target>Cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91772203889648189" datatype="html">
+ <source>NFS Protocol</source>
+ <target>NFS-Protokoll</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907766170797643122" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1032539711043211945" datatype="html">
+ <source>Transport</source>
+ <target>Transport</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2489852208080013495" datatype="html">
+ <source>Storage Backend</source>
+ <target>Speicher-Back-End</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8440421106569981118" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4095248496892792741" datatype="html">
+ <source>CephFS User</source>
+ <target>CephFS-Benutzer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2535727951299201687" datatype="html">
+ <source>CephFS Filesystem</source>
+ <target>CephFS-Dateisystem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2169401160512036026" datatype="html">
+ <source>Security Label</source>
+ <target>Sicherheitsbezeichnung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3671149880069127721" datatype="html">
+ <source>Object Gateway</source>
+ <target>Objektgateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1643028261508790" datatype="html">
+ <source>Object Gateway User</source>
+ <target>Objektgatewaybenutzer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2dae0bda66f6a349444951c0379c28cda47d6d1" datatype="html">
+ <source>Any client can access</source>
+ <target>Jeder Client hat Zugriff</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7882f2edb1d4139800b276b6b0bbf5ae0b2234ef" datatype="html">
+ <source>Addresses</source>
+ <target>Adressen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f3f74c0f6925826cb2188576391c0da01a23f0" datatype="html">
+ <source>Must contain one or more comma-separated values</source>
+ <target>Muss mindestens einen kommagetrennten Wert enthalten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb5b2073697f3f4378c44a49b7524934c9268f4" datatype="html">
+ <source>For example:</source>
+ <target>Beispielsweise:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f969c655b3fbe4fba7e277caf4cd2c459f9fca5" datatype="html">
+ <source>Access Type</source>
+ <target>Zugriffstyp</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28952831a284cfe2b4fc39ca610e80b52598905a" datatype="html">
+ <source>Squash</source>
+ <target>Squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0660ae339068979854ade34a96546980723dede3" datatype="html">
+ <source>Add clients</source>
+ <target>Clients hinzufügen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8571141481686087364" datatype="html">
+ <source>(inherited from global config)</source>
+ <target>(aus globaler Konfiguration übernommen)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3563954518111128118" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- Zugriffstyp auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3802199399355755843" datatype="html">
+ <source>inherited from global config</source>
+ <target>aus globaler Konfiguration übernommen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8729531250118136719" datatype="html">
+ <source>-- Select what kind of user id squashing is performed --</source>
+ <target>-- Durchzuführende Benutzer-ID-Squashing-Art auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4d1dd59b039ad818d9da7e29a773e10e41d9821" datatype="html">
+ <source>Cluster</source>
+ <target>Cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="625f8f0f3e5b7c92651606d77484ff3d07b3c12b" datatype="html">
+ <source>This is the ID of an NFS Service.</source>
+ <target>Dies ist die ID eines NFS-Dienstes.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="135b91a2d908d5814b782695470a6a786c99d9d2" datatype="html">
+ <source>-- No cluster available --</source>
+ <target>-- Kein Cluster verfügbar --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c501dba379f566885919240ea277b5bc10c14d18" datatype="html">
+ <source>-- Select the cluster --</source>
+ <target>-- Cluster auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7bd3ad665c398c7fe97230ab59e67370653a82" datatype="html">
+ <source>This field is required. To create a new NFS cluster, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>add a new NFS Service<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <target>Dies ist ein Pflichtfeld. Um einen neuen NFS-Cluster zu erstellen, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>fügen Sie einen neuen NFS-Dienst<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> hinzu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">41,43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3f6ba7fe84d6508705cdfe234f0fcc8ff85c9cf" datatype="html">
+ <source>Storage Backend</source>
+ <target>Speicher-Back-End</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6fee356d1db954255a56d8169405a89595246b9" datatype="html">
+ <source>-- Select the storage backend --</source>
+ <target>-- Speicher-Back-End auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3c2793dd2ef56954f872142d5ec1becb84c0fe1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="796e42bec8a6996607cf1f3e80235b86d695804a" datatype="html">
+ <source>Volume</source>
+ <target>Volume</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee3ba0ab5f0ccd597b3e44021c71e9aaad14df0a" datatype="html">
+ <source>-- No CephFS filesystem available --</source>
+ <target>-- Kein CephFS-Dateisystem verfügbar --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="764c57812558b1ae66c5eec95d7efd2b1bf761e3" datatype="html">
+ <source>-- Select the CephFS filesystem --</source>
+ <target>-- CephFS-Dateisystem auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="957512d0321f73e9f115bce1bd823fa635170c41" datatype="html">
+ <source>Security Label</source>
+ <target>Sicherheitsbezeichnung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="65ce0fa4da1ed55e658aeb31d1644a29f06bb342" datatype="html">
+ <source>Enable security label</source>
+ <target>Sicherheitsbezeichnung aktivieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e808f804130c7b6ff719509cbc06ebb27393a48" datatype="html">
+ <source>CephFS Path</source>
+ <target>CephFS-Pfad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1338c2f83e49ea7f2fc04e9fe90c5d330b7a10f" datatype="html">
+ <source>A path in a CephFS file system.</source>
+ <target>Ein Pfad in einem CephFS-Dateisystem.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ecc0107badb6625466aaa3f975b5c05276f432f" datatype="html">
+ <source>Path need to start with a '/' and can be followed by a word</source>
+ <target>Pfad muss mit einem '/' beginnen und kann von einem Wort gefolgt werden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f9d8bd873c34c5ab2d4d0cf995fe5183ab25f6e" datatype="html">
+ <source>The path does not exist in the selected volume.</source>
+ <target>Der Pfad existiert im ausgewählten Volume nicht.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd197d7773cef10f368f08c53b47979c3df1f22d" datatype="html">
+ <source>Bucket</source>
+ <target>Bucket</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ca90b4b16347ef7017967915e8624472976c85c" datatype="html">
+ <source>The bucket does not exist or is not in the default realm (if multiple realms are configured). To continue, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>create a new bucket<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <target>Der Bucket ist nicht vorhanden oder nicht im Standardbereich (wenn mehrere Bereiche konfiguriert sind). <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>Erstellen Sie einen neuen Bucket<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>, um fortzufahren.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bee6900143996c0e908a10564532eba3da0b30fb" datatype="html">
+ <source>NFS Protocol</source>
+ <target>NFS-Protokoll</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5043c0921e709935ab026bb3253ffe1f159fca1" datatype="html">
+ <source>NFSv4</source>
+ <target>NFSv4</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d2c39708a32910f89701dd7e1cfb9ec1c195768" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1f8be2ae25947bec0b84c2338201580ea053f34e" datatype="html">
+ <source>The position that this <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> export occupies in the <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo FS<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (it must be unique).</source>
+ <target>Die Position dieses <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>-Exports auf dem <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo-Dateisystem<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (muss eindeutig sein).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">241,242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3af55f7fd5b1d9e5a53e030c80116dc635bfb9f" datatype="html">
+ <source>By using different Pseudo options, the same Path may be exported multiple times.</source>
+ <target>Wenn unterschiedliche Pseudo-Optionen verwendet werden, wird derselbe Pfad möglicherweise mehrfach exportiert.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5eb719aa900fed3f9d4a1d74bcc158f07f67f684" datatype="html">
+ <source>The pseudo is already in use by another export.</source>
+ <target>Pseudo wird bereits von einem anderen Export verwendet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddf98fcdeeb17643db020d54f42b5e56b5f9a52a" datatype="html">
+ <source>Pseudo needs to start with a '/' and can't contain any of the following: &gt;, &lt;, |, &amp;, ( or ).</source>
+ <target>Pseudo muss mit einem '/' beginnen und darf folgende Zeichen nicht enthalten: &gt;, &lt;, |, &amp;, ( oder ).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="27eb35c4b4ac08781a7253a2ab40f8f7d957ba51" datatype="html">
+ <source>-- No access type available --</source>
+ <target>-- Kein Zugriffstyp verfügbar --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">280</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="509ce016c9110a54028dafd741f15ceacbe74b5a" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- Zugriffstyp auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67ce207d0b7eada1fe3d3187a39ba0c07be76b6c" datatype="html">
+ <source>The Object Gateway NFS backend has a number of limitations which will seriously affect applications writing to the share. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> for details before enabling write access.</source>
+ <target>Das NFS-Backend für das Objektgateway besitzt eine Reihe von Einschränkungen, die Schreibvorgänge von Anwendungen auf diese Freigabe ernsthaft beeinträchtigen. Bitte konsultieren Sie die <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> für weitere Informationen, bevor Sie den Schreibzugriff aktivieren.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">293,296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4deda03573eaaff77e63f6a238a1f0ca7816950a" datatype="html">
+ <source>-- No squash available --</source>
+ <target>-- Kein Squash verfügbar --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">321</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a0e82a4da88e7fdf270444f838d45849676e9d4b" datatype="html">
+ <source>--Select what kind of user id squashing is performed --</source>
+ <target>-- Durchzuführende Benutzer-ID-Squashing-Art auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d01b7c3f7f06712c53d054cfbe4f53d446b038e8" datatype="html">
+ <source>Transport Protocol</source>
+ <target>Transportprotokoll</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2a6ad6e8bc315f07911722c05767ac79c136d99" datatype="html">
+ <source>UDP</source>
+ <target>UDP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">349</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c030f11e0aae9b24d2c048c57f29f590be621df" datatype="html">
+ <source>TCP</source>
+ <target>TCP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">359</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f84d7fd4d52eb5b2229b632ef5119dac63d5597" datatype="html">
+ <source>No user id squashing is performed.</source>
+ <target>Kein Benutzer-ID-Squashing wird durchgeführt.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">378</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb1d148107e36852325106a518385b1b0de28835" datatype="html">
+ <source>uid 0 and gid 0 are squashed to the Anonymous_Uid and Anonymous_Gid gid 0 in alt_groups lists is also squashed.</source>
+ <target>uid 0 und gid 0 werden zu Anonymous_Uid und Anonymous_Gid gid gesquashed. 0 in alt_groups-Listen wird auch gesquashed.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">382</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1309d6f67955799863337b201413faa61a175ddb" datatype="html">
+ <source>uid 0 and gid of any value are squashed to the Anonymous_Uid and Anonymous_Gid alt_groups lists is discarded.</source>
+ <target>uid 0 und gid sämtlicher Werte werden zu Anonymous_Uid und Anonymous_Gid gesquashed, alt_groups-Listen werden verworfen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85f23d5c9b57dc78dda4150d13aa3b99e985350b" datatype="html">
+ <source>All users are squashed.</source>
+ <target>Alle Benutzer werden gesquashed.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2691935247101074756" datatype="html">
+ <source>NFS export</source>
+ <target>NFS-Export</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8727258243239498387" datatype="html">
+ <source><x id="PH" equiv-text="fsalItem.descr"/> backend is not available. <x id="PH_1" equiv-text="errorMessage"/></source>
+ <target><x id="PH" equiv-text="fsalItem.descr"/> Backend ist nicht verfügbar. <x id="PH_1" equiv-text="errorMessage"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2772848515253260635" datatype="html">
+ <source>Error while retrieving paths.</source>
+ <target>Fehler beim Abrufen der Pfade.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5239928491238988595" datatype="html">
+ <source>Error while retrieving bucket names.</source>
+ <target>Fehler beim Abrufen der Bucket-Namen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="734c9905951a774870497c5aaae8e3ee833b6196" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2190548d236ca5f7bc7ab2bca334b860c5ff2ad4" datatype="html">
+ <source>Object Gateway</source>
+ <target>Objektgateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca53d681a9892d6fdbb57ee9676582186515e961" datatype="html">
+ <source>Performance counters not available</source>
+ <target>Leistungsindikatoren nicht verfügbar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="490e15ecc922965b6d8194754c87c5583aa071f3" datatype="html">
+ <source>The name can only consist of alphanumeric characters, dashes and underscores.</source>
+ <target>Der Name darf nur alphanumerische Zeichen, Bindestriche und Unterstriche enthalten.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9edc2b494e660618af3e5225f68d40b7ca67629c" datatype="html">
+ <source>The chosen erasure code profile name is already in use.</source>
+ <target>Der ausgewählte Erasure-Coding-Profilname wird bereits verwendet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35a4206db3105ed03e0dd799e1642b75b78123e8" datatype="html">
+ <source>Root</source>
+ <target>Stamm</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf425784c7073c7e7f7c1bb90c2c19db7e751db2" datatype="html">
+ <source>Failure domain type</source>
+ <target>Ausfalldomänen-Typ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72396a9565cf644d1fe1b21b790c4243ee270986" datatype="html">
+ <source>Device class</source>
+ <target>Geräte-Klasse</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d80e0c07bfea1b693a33ef2245007de92a6780" datatype="html">
+ <source>Let Ceph decide</source>
+ <target>Ceph entscheiden lassen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101611937243846632" datatype="html">
+ <source>Crush Rule</source>
+ <target>Crush-Regel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef9ff0e6227947b48dfab4ac39ade04af758913b" datatype="html">
+ <source>Plugin</source>
+ <target>Plugin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd69b31bce8f630eac1d4762b0bbcf72ce19d193" datatype="html">
+ <source>Data chunks (k)</source>
+ <target>Datenblöcke (k)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0d26a6172d32cb81218fe2103c54a818cbc1189" datatype="html">
+ <source>Must be equal to or greater than 2.</source>
+ <target>Muss größer oder gleich 2 sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ba6f4800642eba4e8b056aa7167554c3afa8db0" datatype="html">
+ <source>Chunks (k+m) have exceeded the available OSDs of <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>.</source>
+ <target>Blöcke (k+m) haben die verfügbaren <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/> OSDs überschritten.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="86fca2f788ce986eef835cd7ef8dfc9ae22447a4" datatype="html">
+ <source>For an equal distribution k has to be a multiple of (k+m)/l.</source>
+ <target>Für eine gleichmäßige Verteilung muss k ein Vielfaches von (k+m)/l sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8dd4bc172f1adc4afadaec291e465b082909148d" datatype="html">
+ <source>K has to be equal to or greater than m in order to recover data correctly through c.</source>
+ <target>k muss gleich oder größer als m sein, damit die Daten über c korrekt wiederhergestellt werden können.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2e5b0e6d0dba31c59f946392699a0a6c4dd9b83" datatype="html">
+ <source>Distribution factor: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></source>
+ <target>Verteilungsfaktor: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dab3a299ead121169b8e08ed618c3b6a2f66691b" datatype="html">
+ <source>Coding chunks (m)</source>
+ <target>Datenblöcke für die Codierung (m)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e2773e5bd4948193f18f2361d663ecc3988c656" datatype="html">
+ <source>Must be equal to or greater than 1.</source>
+ <target>Muss größer oder gleich 1 sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">146</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cde4c945a49a260c0a47bcc7cd956846930a5f7" datatype="html">
+ <source>Durability estimator (c)</source>
+ <target>Dauerhaftigkeitsschätzung (c)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ec9ff9931f8ea1201792d6a01bf9a47b283d692" datatype="html">
+ <source>C has to be equal to or lower than m as m defines the amount of chunks that can be used.</source>
+ <target>c muss gleich oder kleiner als m sein, da m die Anzahl der Blöcke definiert, die verwendet werden können.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35594fe66657ea07b5b5f560927f78e81a229996" datatype="html">
+ <source>Helper chunks (d)</source>
+ <target>Helper-Blöcke (d)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0c250a8d281291273ed3504ade19ca6537e4d9a" datatype="html">
+ <source>Set d manually or use the plugin's default calculation that maximizes d.</source>
+ <target>Stellen Sie d manuell ein oder verwenden Sie die Standardberechnung des Moduls, die d maximiert.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4304a5cd95742db0f81c3bdf29aa96bf3b0ca13d" datatype="html">
+ <source>D is automatically updated on k and m changes</source>
+ <target>d wird bei Änderungen von k und m automatisch aktualisiert.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06a67d52427b12df2b3d439be0e1342ac72aeb5c" datatype="html">
+ <source>D can be set from <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> to <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></source>
+ <target>D kann von <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> auf <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/>gesetzt werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4f8831d3bd6401e87710c4e3ee844f5efbf5de3" datatype="html">
+ <source>D can only be set to <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></source>
+ <target>D kann nur auf <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/> gesetzt werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5d7aacffce2c6032c3ae9ef4d1b3847a926440b" datatype="html">
+ <source>D has to be greater than k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>).</source>
+ <target>D muss größer als k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>) sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fd745d614884edc23c7ac9ad8aba9655f3793ac2" datatype="html">
+ <source>D has to be lower than k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>).</source>
+ <target>D muss niedriger als k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>) sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">199</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af668c2a095a979ea2b4e43cd82c2120ab56c21c" datatype="html">
+ <source>Locality (l)</source>
+ <target>Standort (l)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="200fea08b63ae8d60cdbf33ffd2636159e87dc1e" datatype="html">
+ <source>Can't split up chunks (k+m) correctly with the current locality.</source>
+ <target>Blöcke (k+m) können mit dem aktuellen Standort nicht korrekt aufgeteilt werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319ac5d692d11da686782159bd70e0b705c228ed" datatype="html">
+ <source>Locality groups: <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></source>
+ <target>Standortgruppen: <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">230</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d455a110bf6d2235e314e295ce1dfeee93d3dff2" datatype="html">
+ <source>Crush failure domain</source>
+ <target>Crush-Ausfalldomäne</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74a495f041f7dd102eee5c0bbc9e03083b538ae" datatype="html">
+ <source>Crush Locality</source>
+ <target>Crush-Standort</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2f14a73f7a6e94479f67423cc51102da8d6f524" datatype="html">
+ <source>None</source>
+ <target>Keine</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="363a99d62822b92913a4cce196d47f32c1258e2f" datatype="html">
+ <source>Scalar mds</source>
+ <target>Skalar-MDS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2981733b912b693a9dd9d915d6d34f4692cc874a" datatype="html">
+ <source>Technique</source>
+ <target>Technik</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0098b6e47b04ec817361f384ce81d454ba5c0bb" datatype="html">
+ <source>Packetsize</source>
+ <target>Paketgröße</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0252cd81ca54d0a2f69ec9ccf4248e73df5aa4a" datatype="html">
+ <source>Crush root</source>
+ <target>Crush-Stamm</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">351</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1548d5c76f0406ddd1ba3c557e1e6db22e95b340" datatype="html">
+ <source>Crush device class</source>
+ <target>Crush-Geräteklasse</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3f657ffa19dc6ac504b83c86209709522dcf065" datatype="html">
+ <source>Available OSDs: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></source>
+ <target>Verfügbare OSDs: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03d84645f6e019c5a43909bbf2ea1696ee88332c" datatype="html">
+ <source>Directory</source>
+ <target>Verzeichnis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1354845268685595937" datatype="html">
+ <source>EC Profile</source>
+ <target>EC-Profil</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3938a411d76796f8ae73b72ea4c77661207453bd" datatype="html">
+ <source>Cache Tiers Details</source>
+ <target>Details zu den Cache-Ebenen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="991790413700941336" datatype="html">
+ <source>Cache Mode</source>
+ <target>Cache-Modus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9133265273798382582" datatype="html">
+ <source>Min Evict Age</source>
+ <target>Min. Alter für Vertreibung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7172092927403263656" datatype="html">
+ <source>Min Flush Age</source>
+ <target>Min. Alter für Leerung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8096695869347792608" datatype="html">
+ <source>Target Max Bytes</source>
+ <target>Max. Bytes für Ziel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8854126142886240282" datatype="html">
+ <source>Target Max Objects</source>
+ <target>Max. Objekte für Ziel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617215542453015899" datatype="html">
+ <source>No applications added</source>
+ <target>Keine Anwendungen hinzugefügt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4895689494338215646" datatype="html">
+ <source>Applications limit reached</source>
+ <target>Anwendungslimit erreicht</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7322343326526084293" datatype="html">
+ <source>A pool can only have up to four applications definitions.</source>
+ <target>Ein Pool kann nur bis zu vier Anwendungsdefinitionen aufweisen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1393735257943344790" datatype="html">
+ <source>Allowed characters '_a-zA-Z0-9'</source>
+ <target>Zulässige Zeichen '_a-zA-Z0-9'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5520683885127790121" datatype="html">
+ <source>Maximum length is 128 characters</source>
+ <target>Maximale Länge beträgt 128 Zeichen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587418377972855060" datatype="html">
+ <source>Filter or add applications'</source>
+ <target>Anwendungen filtern oder hinzufügen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5188881899285829380" datatype="html">
+ <source>Add application</source>
+ <target>Anwendung hinzufügen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16e113230b6b0d3165e076300880542bac7c8138" datatype="html">
+ <source>The chosen Ceph pool name is already in use.</source>
+ <target>Der ausgewählte Poolname wird bereits verwendet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c75b132bef7b29fa5171768303c4b96e34ccaf68" datatype="html">
+ <source>It's not possible to create an RBD pool with '/' in the name. Please change the name or remove 'rbd' from the applications list.</source>
+ <target>Es ist nicht möglich, einen RBD-Pool mit '/' im Namen zu erstellen. Bitte ändern Sie entweder den Namen oder entfernen 'rbd' aus der Anwendungsliste.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">34,35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="171dc6d5c6bc4615d99778b0088cae80fd00bd10" datatype="html">
+ <source>Pool name can only contain letters, numbers, '.', '-', '_' or '/'.</source>
+ <target>Der Pool-Name darf nur aus Buchstaben, Ziffern, '.', '-', '_' oder '/' bestehen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b85c657469e5ec8231c3de99b22f437bc01ffde5" datatype="html">
+ <source>Pool type</source>
+ <target>Pooltyp</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="526c5443254c3b126eedb264840ffe827727bfd3" datatype="html">
+ <source>-- Select a pool type --</source>
+ <target>-- Pooltyp auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abfbe47b630929d93c7343dc154599c2e59330a" datatype="html">
+ <source>PG Autoscale</source>
+ <target>PG Autoskalierung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0aa21053410a94aa61d16985a4e95fd65523430d" datatype="html">
+ <source>Placement groups</source>
+ <target>Platzierungsgruppen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6301f1391d726f8f450bb358058534db19541ca9" datatype="html">
+ <source>At least one placement group is needed!</source>
+ <target>Es wird mindestens eine Platzierungsgruppe benötigt.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba9469a1ce6ed36e039c1f67247c8c81a5c71449" datatype="html">
+ <source>Your cluster can't handle this many PGs. Please recalculate the PG amount needed.</source>
+ <target>Ihr Cluster kann nicht so viele Platzierungsgruppen verarbeiten. Berechnen Sie die benötigte Anzahl an Platzierungsgruppen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80ac68cd883369dac20688bc32b4cb33291b5e50" datatype="html">
+ <source>Calculation help</source>
+ <target>Hilfe zur Berechnung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fccbd60493df26705d957ed6c02a3c447894678f" datatype="html">
+ <source>The current PGs settings were calculated for you, you should make sure the values suit your needs before submit.</source>
+ <target>Die aktuellen Einstellungen für die Platzierungsgruppen wurden für Sie berechnet. Stellen Sie vor dem Senden sicher, dass die Werte Ihren Anforderungen entsprechen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">116,117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a43b2695131b48b76cebba676aba98a2bee17515" datatype="html">
+ <source>Replicated size</source>
+ <target>Reproduzierte Größe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bff144a4c4dc63b0e18fff2617d61a7ebdf2b6c" datatype="html">
+ <source>Minimum: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></source>
+ <target>Minimum: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9c54b41f6d58a74e5d0aa3429ed0c87a482551" datatype="html">
+ <source>Maximum: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></source>
+ <target>Maximum: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="452cf71ec44ee77428656936a6627eaf2dd3b47f" datatype="html">
+ <source>The size specified is out of range. A value from <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> to <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/> is usable.</source>
+ <target>Die spezifizierte Größe liegt außerhalb des Bereichs. Es ist ein Wert von <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> bis <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/> zu verwenden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">144,145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dda6196ffab88c1825f44a565c7b34e246e7e12f" datatype="html">
+ <source>A size of 1 will not create a replication of the object. The 'Replicated size' includes the object itself.</source>
+ <target>Eine Größe von 1 erzeugt keine Reproduktion des Objekts. Die 'Reproduzierte Größe' beinhaltet das Objekt selbst.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">148,149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c870fb00256b8a5b9cb9cd1a124e6390b9bc639" datatype="html">
+ <source>EC Overwrites</source>
+ <target>EC-Überschreibungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f1abafaeb40ce52355ddcc24686e3cd17b64e08a" datatype="html">
+ <source>Applications</source>
+ <target>Anwendungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9308b82fc183f710df60909f49cfc73aa5e076" datatype="html">
+ <source>CRUSH</source>
+ <target>CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9de7dde00e2139cc4bd03b1837afbe72ad15a1ff" datatype="html">
+ <source>Erasure code profile</source>
+ <target>Erasure-Coding-Profil</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39b4620e6bd444e0a57a0a5c03fa8c96d7fe5235" datatype="html">
+ <source>-- No erasure code profile available --</source>
+ <target>-- Kein Erasure-Coding-Profil verfügbar --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498561757390d5528b263ce450d5f38efb00266d" datatype="html">
+ <source>-- Select an erasure code profile --</source>
+ <target>-- Erasure-Coding-Profil auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="616a2532fbaace94934f5943e381b63e2623f004" datatype="html">
+ <source>This profile can't be deleted as it is in use.</source>
+ <target>Dieses Profil kann nicht gelöscht werden, da es verwendet wird.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="994363f08f9fbfa3b3994ff7b35c6904fdff18d8" datatype="html">
+ <source>Profile</source>
+ <target>Profil</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="023d6f718770d2ea4ab8cabe26b0ec27ef967ec2" datatype="html">
+ <source>Used by pools</source>
+ <target>In Verwendung durch Pools</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">387</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1061ba5ee07a5c6af09e09330dbc29201baf2aa" datatype="html">
+ <source>Profile is not in use.</source>
+ <target>Profil wird nicht verwendet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33150f22ce5348aa6c499bd092c3f4f3695d62cc" datatype="html">
+ <source>Crush ruleset</source>
+ <target>Crush-Regelsatz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">293</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">303</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c69b0bcd4698aa845d32c4c4ad488492552cb469" datatype="html">
+ <source>A new crush ruleset will be implicitly created.</source>
+ <target>Ein neuer CRUSH Regelsatz wird implizit erstellt.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="896e9987db5e9bb279e6deed5d2dff28c242ef66" datatype="html">
+ <source>There are no rules.</source>
+ <target>Keine Regeln vorhanden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73a6b31116b3cc322af951daa0bafdc169e6c42e" datatype="html">
+ <source>-- Select a crush rule --</source>
+ <target>-- Crush-Regel auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7d4894e770f8853050b1f6dd55bdd77a51a8ac6" datatype="html">
+ <source>Placement and
+ replication strategies or distribution policies that allow to
+ specify how CRUSH places data replicas.</source>
+ <target>Platzierung und
+ Reproduktionsstrategien oder Verteilungsrichtlinien, mit denen festgelegt
+ werden kann, wie CRUSH Daten-Replikas platziert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">328,330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea91d648f92002bc9f96d9b26b735c83ca0b53c6" datatype="html">
+ <source>This rule can't be deleted as it is in use.</source>
+ <target>Diese Regel kann nicht entfernt werden, weil sie noch verwendet wird.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">346</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92da80699921e89fb19372e25b8d0f3b9fa427fc" datatype="html">
+ <source>Crush rule</source>
+ <target>Crush-Regel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">365</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5489e9f96835f469f6f728a00d8efa88ea5bc940" datatype="html">
+ <source>Crush steps</source>
+ <target>Crush-Schritte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc5f5496a9e50fe69e1a09784f28d94944108294" datatype="html">
+ <source>Rule is not in use.</source>
+ <target>Regel wird nicht verwendet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="104a0e6900d1d1b0c8cf9e5947e36edb352583fc" datatype="html">
+ <source>The rule can't be used in the current cluster as it has too few OSDs to meet the minimum required OSD by this rule.</source>
+ <target>Die Regel kann im aktuellen Cluster nicht verwendet werden, da zu wenige OSDs existieren, um das von dieser Regel geforderte OSD-Minimum zu erfüllen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">409,410</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2208d63d5940ce656006a220102b1eb2b5e553da" datatype="html">
+ <source>Compression</source>
+ <target>Komprimierung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">420</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c6f25c47da62ec597c6057a36ddfc3209811ec5" datatype="html">
+ <source>Algorithm</source>
+ <target>Algorithmus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">444</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4903231d42089325a28892c0fde1aed46b733ae6" datatype="html">
+ <source>-- No erasure compression algorithm available --</source>
+ <target>-- Kein Komprimierungsalgorithmus für Erasure-Coding verfügbar --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d68ddb254275f8f44221e9ad6d8ceeb59ca46a6" datatype="html">
+ <source>Minimum blob size</source>
+ <target>Minimale Blobgröße</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">468</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb2f176df80647137cbb02bbeb29e5dec707a400" datatype="html">
+ <source>e.g., 128KiB</source>
+ <target>z. B. 128KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">477</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b7f6e53a4521c6eb3ced4c007fdd4cf80bb7707" datatype="html">
+ <source>Value should be greater than 0</source>
+ <target>Wert sollte größer als 0 sein</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">482</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">506</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8db98ab14b4e207ec763dfdefbc2dae367aab1cc" datatype="html">
+ <source>Value should be less than the maximum blob size</source>
+ <target>Wert sollte niedriger als die maximale Blobgröße sein</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151efb127a9a4dd25259a0b2055442318a141f5b" datatype="html">
+ <source>Maximum blob size</source>
+ <target>Maximale Blobgröße</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c656f0e346bbadf46eb1a5d20d0307a3bd20ba8" datatype="html">
+ <source>e.g., 512KiB</source>
+ <target>z. B. 512KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65a24eee8a026f3b1113fe9e157e9a0dd69486" datatype="html">
+ <source>Value should be greater than the minimum blob size</source>
+ <target>Wert sollte größer als die minimale Blobgröße sein</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">509</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="261ba09c4a59de83f48f52a23fd328da37e61ff4" datatype="html">
+ <source>Ratio</source>
+ <target>Verhältnis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">517</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1430457a9c3c66366e51d76bf10396014c576be" datatype="html">
+ <source>Compression ratio</source>
+ <target>Komprimierungsverhältnis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">528</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae5ce6de352cde949998fb10754459c3a4eb183b" datatype="html">
+ <source>Value should be between 0.0 and 1.0</source>
+ <target>Wert sollte zwischen 0,0 und 1,0 liegen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d99b34162c9c34f10d0ccd8dbae83d8569c2db77" datatype="html">
+ <source>Max bytes</source>
+ <target>Max. Bytes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">546</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1d14a18879c62f3f4ed705318b7164a1160e249" datatype="html">
+ <source>Leave it blank or specify 0 to disable this quota.</source>
+ <target>Lassen Sie das Feld leer oder geben Sie 0 an, um dieses Quota zu deaktivieren.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">572</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7565b131562ff6c5f769fdbd239a772154abdd97" datatype="html">
+ <source>A valid quota should be greater than 0.</source>
+ <target>Ein gültiges Kontingent sollte größer als 0 sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">550</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">574</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b8bf35b66f09a301eef92ffc3cb2fd259df67ce9" datatype="html">
+ <source>Max objects</source>
+ <target>Max. Objekte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">570</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="95f348167622d832c5ae532b6944635c8e2ae5cb" datatype="html">
+ <source>The value should be greater or equal to 0</source>
+ <target>Der Wert sollte größer als oder gleich 0 sein</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">586</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1088629182722162774" datatype="html">
+ <source>pool</source>
+ <target>Pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6215593782779198370" datatype="html">
+ <source>erasure code profile</source>
+ <target>Erasure-Coding-Profil</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4390273881304618317" datatype="html">
+ <source>crush rule</source>
+ <target>Crush-Regel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">721</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d8a7c8aea58294a3c57c23af0468ddf0ba0c9c7" datatype="html">
+ <source>Pools List</source>
+ <target>Pool-Liste</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9055665654201606988" datatype="html">
+ <source>Data Protection</source>
+ <target>Datenschutz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6658000829978978023" datatype="html">
+ <source>Applications</source>
+ <target>Anwendungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5232365108332422324" datatype="html">
+ <source>PG Status</source>
+ <target>Platzierungsgruppenstatus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1669788723782899084" datatype="html">
+ <source>Crush Ruleset</source>
+ <target>Crush-Regelsatz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7961062124768120122" datatype="html">
+ <source>Pool deletion is disabled by the mon_allow_pool_delete configuration setting.</source>
+ <target>Das Löschen des Pools ist durch die Konfigurationsoption mon_allow_pool_delete deaktiviert.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee5132a8da30e0b7f9f5c70dbc91928d17dd909" datatype="html">
+ <source>Owner</source>
+ <target>Inhaber</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c51963a9c553b29427ef783bbb69fa6634fa8c" datatype="html">
+ <source>Index type</source>
+ <target>Indextyp</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e6f950a32eaea32ec7e192f9ca3d3dfe469d4ba" datatype="html">
+ <source>Placement rule</source>
+ <target>Platzierungsregel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6972d213e31c4ea4f887e60db99d9881bc8fcd3e" datatype="html">
+ <source>Marker</source>
+ <target>Marker</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47b02acd2d3254d1ace1926f840523f154ebef71" datatype="html">
+ <source>Maximum marker</source>
+ <target>Maximum für Marker</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="092fa3a7df9168b14d3f83a77a4035e92b92ce15" datatype="html">
+ <source>Master version</source>
+ <target>Masterversion</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97434cc5001d407f90c7447a12d9e8e6848a2aa3" datatype="html">
+ <source>Modification time</source>
+ <target>Änderungszeit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90fe2e41e7fde38453ce4e619efeea9bc6adea9c" datatype="html">
+ <source>Zonegroup</source>
+ <target>Zonengruppe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="efeade5060b3add63863c24871f0830fb16b7e6d" datatype="html">
+ <source>Versioning</source>
+ <target>Versionierung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62a923f047ca49e7a4782629e91fea1ba32db68f" datatype="html">
+ <source>MFA Delete</source>
+ <target>MFA-Löschung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="649a410bd0ace333d067d8fa22f12bdbdb43533b" datatype="html">
+ <source>Bucket quota</source>
+ <target>Bucket-Quote</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">567</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f50a33d3c339f8f4a465141f8caa5d2d8c005251" datatype="html">
+ <source>Enabled</source>
+ <target>Aktiv</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">579</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cef1595d040e77cbb4466e60382028d4c2040cac" datatype="html">
+ <source>Maximum size</source>
+ <target>Maximale Größe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa6fb95c355f172bda303de1ce2f38c251a149cf" datatype="html">
+ <source>Unlimited</source>
+ <target>Unbegrenzt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee862a800364b4d11f9b8cb9955a28a60f840a45" datatype="html">
+ <source>Maximum objects</source>
+ <target>Maximale Objekte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b84370895ab9eb44672f57146fa05c5947f1c0c" datatype="html">
+ <source>Locking</source>
+ <target>Sperren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c3d9d2296f7886e8289b9f623323803deacfc6" datatype="html">
+ <source>Days</source>
+ <target>Tage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f44bdf9ab00a973bbe482e9fc450e3f67e60c0d" datatype="html">
+ <source>Bucket names can only contain lowercase letters, numbers, periods and hyphens.</source>
+ <target>Bucket-Namen dürfen nur Kleinbuchstaben, Zahlen, Punkte und Bindestriche enthalten.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eabb4db920d9f9b2480cf438468b86e1bea02a9b" datatype="html">
+ <source>The chosen name is already in use.</source>
+ <target>Der ausgewählte Name wird bereits verwendet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b06de7f834c622197e68b66a2abe893040b174c4" datatype="html">
+ <source>Bucket names must not contain uppercase characters or underscores.</source>
+ <target>Bucket-Namen dürfen keine Großbuchstaben oder Unterstriche enthalten.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abacf4af2f66d3af08c5ebe502b21b1f42ac649" datatype="html">
+ <source>Each label must start and end with a lowercase letter or a number.</source>
+ <target>Jedes Label muss mit einem Kleinbuchstaben oder einer Zahl beginnen und enden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a7f52e6813e0535026f61a2d6e8adc8a1d006a" datatype="html">
+ <source>Bucket names cannot be formatted as IP address.</source>
+ <target>Bucket-Namen können nicht als IP-Adressen formatiert werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2a2460396d35e14e7acfb4e060196a0679bdcff" datatype="html">
+ <source>Bucket labels cannot be empty and can only contain lowercase letters, numbers and hyphens.</source>
+ <target>Bucket-Labels dürfen nicht leer sein und dürfen nur Kleinbuchstaben, Zahlen, Punkte und Bindestriche enthalten.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf5c849977e0be2dbfc862d044edd323bfd9fb77" datatype="html">
+ <source>Bucket names must be 3 to 63 characters long.</source>
+ <target>Bucket-Namen müssen zwischen 3 und 63 Zeichen lang sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e4c918357c7445fbf19a203e5f0f0ece1960b3b" datatype="html">
+ <source>-- Select a user --</source>
+ <target>-- Benutzer auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4aab1f837bc8ec222e4f25922465d1c5929a1fc" datatype="html">
+ <source>Placement target</source>
+ <target>Platzierungsziel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bae0a7fc2c9c1fde7d937a8a1a3c7e6825cf7d1" datatype="html">
+ <source>-- Select a placement target --</source>
+ <target>-- Platzierungsziel wählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="016d24e069e7d505a090fb8243e5cd43b35dc39b" datatype="html">
+ <source>Enables versioning for the objects in the bucket.</source>
+ <target>Aktiviert die Versionierung der Objekte im Bucket.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">151</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e6775ffd06878aa145c07359f28557f01ede04f" datatype="html">
+ <source>Multi-Factor Authentication</source>
+ <target>Multi-Faktor-Authentifizierung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29e8a5d4fb767d4ad0c762c81c6264cec4c0ba97" datatype="html">
+ <source>Delete enabled</source>
+ <target>Löschen aktiviert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40fbc3ac8c1ea4ecfe62247e91f1f999ad5baf76" datatype="html">
+ <source>Enables MFA (multi-factor authentication) Delete, which requires additional authentication for changing the bucket versioning state.</source>
+ <target>Aktiviert die MFA-Löschung (Multi-Faktor-Authentifizierung), wofür eine zusätzliche Authentifizierung zum Ändern des Bucket-Versionsstatus erforderlich ist.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24c93a8c13db46defa06ed7b5e026a3edb52b91" datatype="html">
+ <source>Token Serial Number</source>
+ <target>Token Seriennummer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6d9536c2af2e5e9a228c3e3e1809dc1fefe0149" datatype="html">
+ <source>Token PIN</source>
+ <target>Token PIN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f038d51ab1645f15b0cd58f195c72a7eeebd4729" datatype="html">
+ <source>Enables locking for the objects in the bucket. Locking can only be enabled while creating a bucket.</source>
+ <target>Aktiviert die Sperrung für die Objekte im Bucket. Die Sperrung kann nur beim Erstellen eines Buckets aktiviert werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9af1b4baa2dd8ed2bfc3cc756b12a2271c2dd793" datatype="html">
+ <source>Compliance</source>
+ <target> Konformität</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="edd600fa489d1b4a4448dce694ed932e52ce8fda" datatype="html">
+ <source>Governance</source>
+ <target>Regelung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="218c7d6d318c51e7105309aaeb0baec9d19e4efb" datatype="html">
+ <source>The number of days that you want to specify for the default retention period that will be applied to new objects placed in this bucket.</source>
+ <target>Die Anzahl der Tage, die Sie für die Standardaufbewahrungszeit angeben möchten und die auf neue Objekte in diesem Bereich angewendet wird.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">264</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="289b101ec12427b3ca819df9e43cc3b14fae2cc4" datatype="html">
+ <source>The entered value must be a positive integer.</source>
+ <target>Der eingegebene Wert muss eine positive ganze Zahl sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48d8247c1ba2ea156109bf286c5f6dd26b4be760" datatype="html">
+ <source>Retention Days must be a positive integer.</source>
+ <target>Der eingegebene Wert für Aufbewahrungstage muss eine positive ganze Zahl sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4349284625269221231" datatype="html">
+ <source>bucket</source>
+ <target>Bucket</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6161088322338624846" datatype="html">
+ <source>Updated Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'.</source>
+ <target>Objektgateway-Bucket '<x id="PH" equiv-text="values.bid"/>' wurde aktualisiert.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218632328857697292" datatype="html">
+ <source>Created Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'</source>
+ <target>Objektgateway-Bucket '<x id="PH" equiv-text="values.bid"/>' wurde erstellt.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c338bae89822d7eefbc9a887c458a7d8a98e55e" datatype="html">
+ <source>No Limit</source>
+ <target>Kein Limit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3715596725146409911" datatype="html">
+ <source>Owner</source>
+ <target>Inhaber</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5545511293826600258" datatype="html">
+ <source>Used Capacity</source>
+ <target>Verwendete Kapazität</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1925090152473969054" datatype="html">
+ <source>Capacity Limit %</source>
+ <target>Kapazitätslimit %</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8713861779825116442" datatype="html">
+ <source>Object Limit %</source>
+ <target>Objektlimit %</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5913880066213114620" datatype="html">
+ <source>buckets</source>
+ <target>Buckets</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eeba399c4dae8d4890c27b7a2cd2dc28fcf8b5f9" datatype="html">
+ <source>Performance Counters</source>
+ <target>Leistungsindikatoren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="479488ab6e91ecb375484edc78bee3d13467f33f" datatype="html">
+ <source>Daemons List</source>
+ <target>Liste der Daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca2dee83bb58290d93fb0d17ee8bc9f095a4576f" datatype="html">
+ <source>Sync Performance</source>
+ <target>Synchronisierungsleistung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4378147649219625174" datatype="html">
+ <source>Zone</source>
+ <target>Zone</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6148052126949932311" datatype="html">
+ <source>Zone Group</source>
+ <target>Zonen-Gruppe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3840481991104643295" datatype="html">
+ <source>Realm</source>
+ <target>Bereich</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1221ca97d19eaa9a7bc0c5243d5fc5befe1d2314" datatype="html">
+ <source>-- Select a type --</source>
+ <target>-- Typ auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1b8990332af18f1c5159a6061ca889bcbb28432" datatype="html">
+ <source>Permission</source>
+ <target>Berechtigung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a08c589f82f69d892307288da14190ae1dd583d5" datatype="html">
+ <source>-- Select a permission --</source>
+ <target>-- Berechtigung auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7345972049922682356" datatype="html">
+ <source>capability</source>
+ <target>Befähigung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a94e6b2b5b834d92cceb90037d51ad6165c8b619" datatype="html">
+ <source>Tenant</source>
+ <target>Mandant</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
+ <source>User ID</source>
+ <target>Benutzer-ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b760f123248930122fc7e7b6b6bf94e376e959c8" datatype="html">
+ <source>Full name</source>
+ <target>Vollständiger Name</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69b6ac577a19acc39fc0c22342092f327fff2529" datatype="html">
+ <source>Email address</source>
+ <target>E-Mail-Adresse</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92f3f203270a29b3001871153f02c063484a1574" datatype="html">
+ <source>Suspended</source>
+ <target>Angehalten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011e20c5bbe51602d459a860fbf29b599b55edd" datatype="html">
+ <source>System</source>
+ <target>System</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db18a2772988415466a7f75dc42663ce78c9c1d3" datatype="html">
+ <source>Maximum buckets</source>
+ <target>Maximale Buckets</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c4c62e8ba24601be5cfe7dc5d32c24bbbd4b53c" datatype="html">
+ <source>Subusers</source>
+ <target>Unterbenutzer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17bb3082e6fe5003203ef992a3714172334631a1" datatype="html">
+ <source>Capabilities</source>
+ <target>Befähigungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32f8a0570373cacb9c56cf227502483a29d605bc" datatype="html">
+ <source>MFAs(Id)</source>
+ <target>MFAs(Id)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36ad38f9c1a1485e09b67778a28af84553290ffb" datatype="html">
+ <source>User quota</source>
+ <target>Benutzerquote</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">473</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0bcd5ef19af0f1b814141ca8c57df623d8270088" datatype="html">
+ <source>Keys</source>
+ <target>Schlüssel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2aba1e87039819aca3b70faa9aa848c12bf139ca" datatype="html">
+ <source>Show</source>
+ <target>Anzeigen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">395</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5248717555542428023" datatype="html">
+ <source>Username</source>
+ <target>Benutzername</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240806681889331244" datatype="html">
+ <source>Unlimited</source>
+ <target>Unbegrenzt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db4e1a734518691b128ef40b939cc673f01d03a6" datatype="html">
+ <source>The value is not valid.</source>
+ <target>Der Wert ist ungültig.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">617</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6aaf5d2a304167272ac73e3b1d1c162e16c77858" datatype="html">
+ <source>The chosen user ID is already in use.</source>
+ <target>Die ausgewählte Benutzer-ID wird bereits verwendet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="025be1d01b2f6cbd09e772a1d3de02fab0678b26" datatype="html">
+ <source>Show Tenant</source>
+ <target>Mandant anzeigen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6af106b0d759fd2882e645604675c4494abfcd5b" datatype="html">
+ <source>The chosen user ID exists in this tenant.</source>
+ <target>Die gewählte Benutzer-ID ist in diesem Mandanten vorhanden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="df441e80db2157f9d272b75de724ba4a82b96b57" datatype="html">
+ <source>This is not a valid email address.</source>
+ <target>Dies ist keine gültige E-Mail-Adresse.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca271adf154956b8fcb28f4f50a37acb3057ff7c" datatype="html">
+ <source>The chosen email address is already in use.</source>
+ <target>Die ausgewählte E-Mail-Adresse wird bereits verwendet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="030197cebe938edf35422e92fe14183d06eb670b" datatype="html">
+ <source>Max. buckets</source>
+ <target>Max. Buckets</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f39256070bfc0714020dfee08895421fc1527014" datatype="html">
+ <source>Disabled</source>
+ <target>Deaktiviert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c05002b0ac2040f1aede5e727e0ffd06eda819" datatype="html">
+ <source>Custom</source>
+ <target>Benutzerdefiniert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28872515cb81d197a3a1733fa546d3e0f0dd6c67" datatype="html">
+ <source>The entered value must be &gt;= 1.</source>
+ <target>Der eingegebene Wert muss &gt;= 1 sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="583a219c524155c2314eb06ee29162bb315272a3" datatype="html">
+ <source>S3 key</source>
+ <target>S3-Schlüssel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c217ee914725a37e9dd2336c721c8e63e9666bdc" datatype="html">
+ <source>Auto-generate key</source>
+ <target>Schlüssel automatisch generieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f1c1c0f2bce4c9f92d1a2061e8161cb0006c31a" datatype="html">
+ <source>Access key</source>
+ <target>Zugriffsschlüssel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b864acb67296a9819c1db0069c4c47d8b5ce8f44" datatype="html">
+ <source>Secret key</source>
+ <target>Geheimer Schlüssel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="128d6efb51d9ddc7c0cc695a2deeca5b9523f6e4" datatype="html">
+ <source>There are no subusers.</source>
+ <target>Keine Unterbenutzer vorhanden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fd6dfb8ecb982dbc3affb2c2d5414c4f5b6abd2" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">294,295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67c746c1ba9dab4351fedc4c7cba4e6d6b0dbc47" datatype="html">
+ <source>S3</source>
+ <target>S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d6819038d608623503918fb2553f53d68231ec3a" datatype="html">
+ <source>There are no keys.</source>
+ <target>Keine Schlüssel vorhanden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">377</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc1c1a7140ff6b815a95b65ee2780fdbe1b2b7a1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">356,357</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6ddb5e991a3ecd2659fb520bc5acc81b67e08ddd" datatype="html">
+ <source>Swift</source>
+ <target>Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">371</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d01eccdda47fc907c5be35bcb16d2dcd02b0270" datatype="html">
+ <source>There are no capabilities.</source>
+ <target>Keine Befähigungen vorhanden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5a451c4ea65a4046f0b49d489a7013abf0b5861" datatype="html">
+ <source>All capabilities are already added.</source>
+ <target>Alle Befähigungen sind bereits hinzugefügt.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">456</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="043e2ec0036ceadd926fd5e3f93cd6f3565f3648" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">461,462</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6146e13ceca5fa5cc17b771b282fe5955f3d19fa" datatype="html">
+ <source>Unlimited size</source>
+ <target>Unbegrenzte Größe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">595</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6db8aa7c99fdce18edb33dde57729acede2b308" datatype="html">
+ <source>Max. size</source>
+ <target>Max. Größe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">511</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">605</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc630b2093e880fffa19df99d5cd8b87605037f8" datatype="html">
+ <source>Unlimited objects</source>
+ <target>Unbegrenzte Objekte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cda5a993d06f0bb10048be9d3aba6555aa9f356" datatype="html">
+ <source>Max. objects</source>
+ <target>Max. Objekte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">642</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="623ac50f37a26caec6fd7cd519b653e3315cba25" datatype="html">
+ <source>The entered value must be &gt;= 0.</source>
+ <target>Der eingegebene Wert muss &gt;=0 sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">654</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="123010868147850959" datatype="html">
+ <source>user</source>
+ <target>Benutzer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8368421344177343441" datatype="html">
+ <source>subuser</source>
+ <target>Unterbenutzer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4662015204945271252" datatype="html">
+ <source>S3 Key</source>
+ <target>S3-Schlüssel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9103468069826049692" datatype="html">
+ <source>Updated Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <target>Objektgateway-Benutzer '<x id="PH" equiv-text="uid"/>' wurde aktualisiert.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="884841609901737584" datatype="html">
+ <source>Created Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <target>Objektgateway-Benutzer '<x id="PH" equiv-text="uid"/>' wurde erstellt.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4363143805416924501" datatype="html">
+ <source>Tenant</source>
+ <target>Mandant</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8301535046747035390" datatype="html">
+ <source>Full name</source>
+ <target>Vollständiger Name</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3967269098753656610" datatype="html">
+ <source>Email address</source>
+ <target>E-Mail-Adresse</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5851424994801012357" datatype="html">
+ <source>Suspended</source>
+ <target>Angehalten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208300173682032371" datatype="html">
+ <source>Max. buckets</source>
+ <target>Max. Buckets</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1670306451865226564" datatype="html">
+ <source>users</source>
+ <target>Benutzer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c614babd1950adb2be75df4e2c9747286d6adc" datatype="html">
+ <source>-- Select a username --</source>
+ <target>-- Benutzername auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2841767821d6b66238c34d07e413b0af67aee92" datatype="html">
+ <source>Subuser</source>
+ <target>Unterbenutzer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd59fc25a7bd98cff3e75117c09697c8a007a514" datatype="html">
+ <source>The chosen subuser ID is already in use.</source>
+ <target>Die ausgewählte Unterbenutzer-ID wird bereits verwendet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d386c357ebcbc04ed05c4babd5a03626f9b1674" datatype="html">
+ <source>read, write</source>
+ <target>lesen, schreiben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84e3e3f9a4f31a039b648c97debf95fcb20f4c4a" datatype="html">
+ <source>full</source>
+ <target>voll</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6bf81d032a2316464f9df2f0d2f3d753f89f0d3" datatype="html">
+ <source>Swift key</source>
+ <target>Swift-Schlüssel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e0c12685d50d47448ceed9423977ef39775c037" datatype="html">
+ <source>Auto-generate secret</source>
+ <target>Geheimnis automatisch generieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5091031285775138345" datatype="html">
+ <source>Subuser</source>
+ <target>Unterbenutzer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8453697749389230205" datatype="html">
+ <source>Swift Key</source>
+ <target>Swift-Schlüssel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ac54c18c1b520e948095c83a3a1025f02ce6dcc6" datatype="html">
+ <source>Neither hostname nor OSD ID given</source>
+ <target>Weder Hostname noch OSD ID angegeben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4533150758393178756" datatype="html">
+ <source>Device ID</source>
+ <target>Laufwerks-ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1291053608320944146" datatype="html">
+ <source>State of Health</source>
+ <target>Integritätszustand</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29167121133682512" datatype="html">
+ <source>Good</source>
+ <target>Gut</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8767957606064036733" datatype="html">
+ <source>Bad</source>
+ <target>Schlecht</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8052456228079338924" datatype="html">
+ <source>Stale</source>
+ <target>Veraltet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6223439643831041743" datatype="html">
+ <source>Life Expectancy</source>
+ <target>Lebenserwartung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3144481541623761279" datatype="html">
+ <source>Prediction Creation Date</source>
+ <target>Prognoseerstellungsdatum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="264574868375698540" datatype="html">
+ <source>Device Name</source>
+ <target>Laufwerksname</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1419569261746199221" datatype="html">
+ <source>Daemons</source>
+ <target>Daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f635b3cb0600409a2ad44a5bd1863c699e6a01c" datatype="html">
+ <source>Failed to retrieve SMART data.</source>
+ <target>SMART-Daten konnten nicht abgerufen werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a8a3f354bd640299068edd912f4bb5325264f250" datatype="html">
+ <source>The data received has the JSON format version 2.x and is currently incompatible with the dashboard.</source>
+ <target>Die empfangenen Daten sind in der JSON-Formatversion 2.x und daher nicht kompatibel mit dem Dashboard.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="04f8a3c7e8ac610e6581960162cc15f55a16696a" datatype="html">
+ <source>No SMART data available.</source>
+ <target>Keine SMART-Daten verfügbar.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a185c9b97513b3882604ea9bab60edbfac945c15" datatype="html">
+ <source>SMART overall-health self-assessment test result</source>
+ <target>SMART-Selbsteinschätzungs-Testeregbnis zur Allgemeinintegrität</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="290e4c9ad42dc6e9176656c864a5faed8053f406" datatype="html">
+ <source>unknown</source>
+ <target>unbekannt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a03d3c2e459f8f8fa7202c0fce465d6165f9e2b" datatype="html">
+ <source>passed</source>
+ <target>bestanden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41435d5a5692c8e412c74deaee95d99dbd3617e1" datatype="html">
+ <source>failed</source>
+ <target>fehlgeschlagen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddd5dd6d930030096ea617f62c82b648a0dd9484" datatype="html">
+ <source>Device Information</source>
+ <target>Laufwerksinformationen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e149c483d88cfcff11d1c5db85e84af7c3149c4" datatype="html">
+ <source>No device information available for this device.</source>
+ <target>Für dieses Laufwerk sind keine Laufwerksinformationen verfügbar.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20cb12827cbe559a7b1da6fdae96041b3b5c3c55" datatype="html">
+ <source>SMART</source>
+ <target>SMART</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380295f37caea93701d071485a38ef0bdba57133" datatype="html">
+ <source>No SMART data available for this device.</source>
+ <target>Keine SMART-Daten für dieses Laufwerk verfügbar.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5758c3f16f8749f0f4e2a787f02e8b4da246102f" datatype="html">
+ <source>SMART data is loading.</source>
+ <target>SMART-Daten werden geladen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5363861031080361352" datatype="html">
+ <source>Smartctl has received an unknown argument (error code <x id="PH" equiv-text="smartData.smartctl_error_code"/>). You may be using an incompatible version of smartmontools. Version &gt;= 7.0 of smartmontools is required to successfully retrieve data.</source>
+ <target>Smartctl hat ein unbekanntes Argument (Fehlercode <x id="PH" equiv-text="smartData.smartctl_error_code"/>) erhalten. Sie verwenden möglicherweise eine inkompatible Version von smartmontools. Die Version &amp;gt;= 7.0 von smartmontools ist erforderlich, um Daten erfolgreich abzurufen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">61,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5085718566932809950" datatype="html">
+ <source>An error with error code <x id="PH" equiv-text="smartData.smartctl_error_code"/> occurred.</source>
+ <target>Ein Fehler mit dem Fehlercode <x id="PH" equiv-text="smartData.smartctl_error_code"/> ist aufgetreten.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2091295268977103253" datatype="html">
+ <source>Raw</source>
+ <target>Brutto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5963653123239768443" datatype="html">
+ <source>Threshold</source>
+ <target>Grenzwert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2893124970059125090" datatype="html">
+ <source>When Failed</source>
+ <target>Bei Fehlschlag</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5614367840516299633" datatype="html">
+ <source>Worst</source>
+ <target>Schlimmste</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d06ae77f9ec46a4cdd49e7e76c73a411aaf2ee38" datatype="html">
+ <source>Please set a new password.</source>
+ <target>Bitte legen Sie ein neues Passwort fest.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8b5b3566e88438f51bd5f6caf6c090ed565ba5ed" datatype="html">
+ <source>You will be redirected to the login page afterwards.</source>
+ <target>Sie werden anschließend auf die Login-Seite weitergeleitet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cf42e491adc166a337a960eb84d03c0c3f677c8" datatype="html">
+ <source>The old and new passwords must be different.</source>
+ <target>Das alte und neue Passwort müssen unterschiedlich sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90163a3d3746819aef42e829f4446331232f3b66" datatype="html">
+ <source>Password confirmation doesn't match the new password.</source>
+ <target>Passwortbestätigung stimmt nicht mit dem neuen Passwort überein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0070e83d11da39d6f4bb95065c2675db1610b419" datatype="html">
+ <source>Username is required</source>
+ <target>Benutzername ist erforderlich</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e20f8b8a4706526c9024cc2f39d568345d100dc" datatype="html">
+ <source>Password is required</source>
+ <target>Passwort ist erforderlich</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f093d9574ab746b231504bd2cbb65f04bd7b00db" datatype="html">
+ <source>Log in</source>
+ <target>Anmelden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5590086849807274701" datatype="html">
+ <source>Scope</source>
+ <target>Bereich</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327592562693301723" datatype="html">
+ <source>Read</source>
+ <target>Lesen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5674286808255988565" datatype="html">
+ <source>Create</source>
+ <target>Erstelle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4021752662928002901" datatype="html">
+ <source>Update</source>
+ <target>Aktualisiere</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022070615528435141" datatype="html">
+ <source>Delete</source>
+ <target>Löschen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ea5c4d8942c00752dcc72e72949c5d9832f6399" datatype="html">
+ <source>Description...</source>
+ <target>Beschreibung...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70f45880fce6ac5d8e468e25e82aefbba8098cfe" datatype="html">
+ <source>Permissions</source>
+ <target>Berechtigungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="122114774689391224" datatype="html">
+ <source>role</source>
+ <target>Rolle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616102757855967475" datatype="html">
+ <source>All</source>
+ <target>Alle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4416727401284087008" datatype="html">
+ <source>Created role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <target>Rolle '<x id="PH" equiv-text="roleFormModel.name"/>' erstellt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3472946357042916911" datatype="html">
+ <source>Updated role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <target>Rolle '<x id="PH" equiv-text="roleFormModel.name"/>' aktualisiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="373024661645814027" datatype="html">
+ <source>System Role</source>
+ <target>Systemrolle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753648234171918096" datatype="html">
+ <source>Deleted role '<x id="PH" equiv-text="role"/>'</source>
+ <target>Rolle '<x id="PH" equiv-text="role"/>' gelöscht</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1674202514578558795" datatype="html">
+ <source>New name</source>
+ <target>Neuer Name</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4857700187193019038" datatype="html">
+ <source>Clone Role</source>
+ <target>Rolle klonen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="748631939386170157" datatype="html">
+ <source>Cloned role '<x id="PH" equiv-text="values['newName']"/>' from '<x id="PH_1" equiv-text="name"/>'</source>
+ <target>Rolle '<x id="PH" equiv-text="values['newName']"/>' von '<x id="PH_1" equiv-text="name"/>' geklont</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="195c31a2f970e790231a6bb94a5e8ca0167406d9" datatype="html">
+ <source>The username already exists.</source>
+ <target>Der Benutzername existiert bereits.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f3bdcce4b2e8c37cd7f0f6c92ef8cff34b039b8" datatype="html">
+ <source>Confirm password</source>
+ <target>Passwort bestätigen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cbb979e63ba50e0ca3adfa09cbdcaefd0853fca1" datatype="html">
+ <source>Password confirmation doesn't match the password.</source>
+ <target>Passwortbestätigung stimmt nicht mit dem Passwort überein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="96621f9ed2e4ae5204564e583d2c816bedead571" datatype="html">
+ <source>Password expiration date</source>
+ <target>Ablaufdatum des Passworts</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48932db3801fe9d5d72a60a3e656bffd17c1c5d9" datatype="html">
+ <source>Password expiration date...</source>
+ <target>Ablaufdatum des Passworts...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc" datatype="html">
+ <source>Email</source>
+ <target>E-Mail-Adresse</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d0ec081dd61eb4f43aea269077bbe38eae87b7f9" datatype="html">
+ <source>Invalid email.</source>
+ <target>Ungültige E-Mail-Adresse.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9610487cbeb5796d34d8601b5ac0c0a65f9e1d19" datatype="html">
+ <source>Roles</source>
+ <target>Rollen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8913c216dd506e20e412e144381d8d2a65a84359" datatype="html">
+ <source>User must change password at next logon</source>
+ <target>Benutzer muss das Passwort bei der nächsten Anmeldung ändern</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0051a3479d3ba79135c16dc8cc017950a2cce821" datatype="html">
+ <source>You are about to remove &quot;user read / update&quot; permissions from your own user.</source>
+ <target>Sie sind dabei, die Lese-/Aktualisierungsberechtigungen für Benutzer von Ihrem eigenen Benutzer zu entfernen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af4bf9fcb256853f14cf947eb1deb8d7f176d3f9" datatype="html">
+ <source>If you continue, you will no longer be able to add or remove roles from any user.</source>
+ <target>Wenn Sie den Vorgang fortsetzen, können Sie Benutzerrollen nicht mehr hinzufügen oder entfernen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314291969883771319" datatype="html">
+ <source>There are no roles.</source>
+ <target>Keine Rollen vorhanden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4306072924538089180" datatype="html">
+ <source>Created user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <target>Benutzer '<x id="PH" equiv-text="userFormModel.username"/>' erstellt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1349763489797682899" datatype="html">
+ <source>Update user</source>
+ <target>Benutzer aktualisieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8688396456017237992" datatype="html">
+ <source>You were automatically logged out because your roles have been changed.</source>
+ <target>Sie wurden automatisch abgemeldet, da Ihre Rollen geändert wurden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2335813072344088607" datatype="html">
+ <source>Updated user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <target>Benutzer '<x id="PH" equiv-text="userFormModel.username"/>' aktualisiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4768749765465246664" datatype="html">
+ <source>Email</source>
+ <target>E-Mail-Adresse</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795890916060309463" datatype="html">
+ <source>Roles</source>
+ <target>Rollen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6877445485286599988" datatype="html">
+ <source>Password expiration date</source>
+ <target>Ablaufdatum des Passworts</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="705657168061753072" datatype="html">
+ <source>Deleted user '<x id="PH" equiv-text="username"/>'</source>
+ <target>Benutzer '<x id="PH" equiv-text="username"/>' gelöscht</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="405819296611088743" datatype="html">
+ <source>Failed to delete user '<x id="PH" equiv-text="username"/>'</source>
+ <target>Fehler beim Löschen von Benutzer '<x id="PH" equiv-text="username"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8935387756949610047" datatype="html">
+ <source>You are currently logged in as '<x id="PH" equiv-text="username"/>'.</source>
+ <target>Sie sind aktuell als '<x id="PH" equiv-text="username"/>' angemeldet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0eb15f32b2b92d7f3103ef3ff032621888a8dc32" datatype="html">
+ <source>Old password</source>
+ <target>Altes Passwort</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229" datatype="html">
+ <source>New password</source>
+ <target>Neues Passwort</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ede41f01c781b168a783cfcefc6fb67d48780d9b" datatype="html">
+ <source>Confirm new password</source>
+ <target>Neues Passwort bestätigen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809196861118879526" datatype="html">
+ <source>password</source>
+ <target>Passwort</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623124197136601291" datatype="html">
+ <source>Updated user password&quot;</source>
+ <target>Benutzerpasswort aktualisiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be" datatype="html">
+ <source>Users</source>
+ <target>Benutzer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ced3246fa3db31be0f7da06648463f29ba378fbe" datatype="html">
+ <source>Selected Object Gateway:</source>
+ <target>Ausgewähltes Objektgateway:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c53062af97ebda2a03f905698f58e524ecf8b968" datatype="html">
+ <source>Select Object Gateway</source>
+ <target>Objektgateway auswählen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="235c355afdcbf72953a15d7fc8d0d9e7a6619f46" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Page not Found<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Seite nicht gefunden<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aee9d027170f84774f2980537556f5099369b82" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for. The page you requested may have been changed or moved.</source>
+ <target>Leider konnte der gewünschte Inhalt nicht gefunden werden. Die angeforderte Seite wurde vielleicht geändert oder verschoben.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">22,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2b46fe9a975c6531af77fee858ccd37327980f7" datatype="html">
+ <source>Please consult the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>documentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> on how to configure and enable the <x id="INTERPOLATION" equiv-text="{{ section_info }}"/> management functionality.</source>
+ <target>Lesen Sie die <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>Dokumentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> zum Konfigurieren und Aktivieren der <x id="INTERPOLATION" equiv-text="{{ section_info }}"/> Verwaltungsfunktion.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">26,27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9d57ca7cab78c6f0d27e0d890cb8cf1515e4e30a" datatype="html">
+ <source>Go To Dashboard</source>
+ <target>Dashboard öffnen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6578397717654172779" datatype="html">
+ <source>Page Not Found</source>
+ <target>Seite nicht gefunden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8185335715884155108" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for.
+ The page you requested may have been changed or moved.</source>
+ <target>Leider konnte der gewünschte Inhalt nicht gefunden werden.
+Die angeforderte Seite wurde vielleicht geändert oder verschoben.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="143318366100741906" datatype="html">
+ <source>Access Denied</source>
+ <target>Zugang verweigert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5384670299771400832" datatype="html">
+ <source>Sorry, you don’t have permission to view this page or resource.</source>
+ <target>Sie haben leider keine Berechtigung sich diese Seite oder Resource anzusehen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2424411274809083521" datatype="html">
+ <source>User Denied</source>
+ <target>Benutzer abgelehnt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7645004872908092358" datatype="html">
+ <source>Sorry, the user does not exist in Ceph.
+ You'll be logged out from the Identity Provider when you retry logging in.</source>
+ <target>Der Benutzer ist in Ceph leider nicht enthalten.
+Sie werden vom Identitätsanbieter abgemeldet, wenn Sie versuchen, sich erneut anzumelden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">24,25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f286db6ac9482dbf567bc491d49a6eade444895a" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7911416166208830577" datatype="html">
+ <source>Help</source>
+ <target>Hilfe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8878700331247603166" datatype="html">
+ <source>Security</source>
+ <target>Sicherheit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8642696205489749843" datatype="html">
+ <source>Trademarks</source>
+ <target>Marken</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1481ecd21e760ac919a24e26cf790acd82e40199" datatype="html">
+ <source>Dashboard Settings</source>
+ <target>Dashboard-Einstellungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a79aab4ef674bf3f6532292107c0054302236e0f" datatype="html">
+ <source>User management</source>
+ <target>Benutzerverwaltung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="197e0246502ca64d0de0df0d5c2deec51d41ff45" datatype="html">
+ <source>Telemetry configuration</source>
+ <target>Telemetriekonfiguration</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85b79c9064aed1ead31ace985f31aa1363f6bdaf" datatype="html">
+ <source>Help</source>
+ <target>Hilfe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06638e0f01d82c0786f63aa9832fbe7866b86087" datatype="html">
+ <source>documentation</source>
+ <target>Dokumentation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e351b40b3869a5c7d19c3d4918cb1ac7aaab95c4" datatype="html">
+ <source>API</source>
+ <target>API</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a" datatype="html">
+ <source>About</source>
+ <target>Über</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="049dfd9fe6c78914ad58cf89ac6a631fca28ec74" datatype="html">
+ <source>Logged in user</source>
+ <target>Angemeldeter Benutzer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5022c5ae3ae921c07bf5f881e9b026b4a6708a7" datatype="html">
+ <source>Signed in as <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>Angemeldet als <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9" datatype="html">
+ <source>Change password</source>
+ <target>Passwort ändern</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d22c795daf43877a5f708dca2bccd549eb0471d" datatype="html">
+ <source>Sign out</source>
+ <target>Abmelden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319e0745bcbc132451569294fa2fa21bf10f555a" datatype="html">
+ <source>Toggle navigation</source>
+ <target>Navigation umschalten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f65253954b66e929a8b4d5ecaf61f9129f8cec64" datatype="html">
+ <source>Dashboard</source>
+ <target>Dashboard</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c95898abff46bfac3ed6eb2afef74597e60b15c" datatype="html">
+ <source>CRUSH map</source>
+ <target>CRUSH-Zuordnung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7b2bc4b86de6e96d353f6bf2b4d793ea3a19ba0" datatype="html">
+ <source>Manager Modules</source>
+ <target>Manager-Module</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb3d5aefff38a814b76da74371cbf02c0789a1ef" datatype="html">
+ <source>Logs</source>
+ <target>Protokolle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17fc3efe5f9fa4e0289c900cb6202265215a1a27" datatype="html">
+ <source>Monitoring</source>
+ <target>Überwachung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f5d0c10614e8a34f0e2dad33a0568277c50cf69" datatype="html">
+ <source>Block</source>
+ <target>Block</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3c2562ba992127203dcfd014010b03cb7b8113c6" datatype="html">
+ <source>Mirroring</source>
+ <target>Spiegelung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="811c241d56601b91ef26735b770e64428089b950" datatype="html">
+ <source>iSCSI</source>
+ <target>iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a24eabd99ea5af20f5f94c4484649cd30370042b" datatype="html">
+ <source>NFS</source>
+ <target>NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5276fc60d54d667116babb723641b21281d37271" datatype="html">
+ <source>File Systems</source>
+ <target>Dateisysteme</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9515520496da83179d8b08132f00f575512a1f40" datatype="html">
+ <source>Buckets</source>
+ <target>Buckets</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a23e992f6c6e169a38b2b7338b4e5e803b52e0d" datatype="html">
+ <source>Tasks and Notifications</source>
+ <target>Aufträge und Benachrichtigungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1390461972315002349" datatype="html">
+ <source>The name of the node under which data should be placed.</source>
+ <target>Der Name des Knotens, unter dem die Daten abgelegt werden sollen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6575341202068728510" datatype="html">
+ <source>The type of CRUSH nodes across which we should separate replicas.</source>
+ <target>Der Typ der CRUSH-Knoten, über die Replikas getrennt werden sollen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3874278445824365480" datatype="html">
+ <source>The device class data should be placed on.</source>
+ <target>Die Laufwerkklasse, auf der Daten abgelegt werden sollen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="675628105428950215" datatype="html">
+ <source>Each object is split in data-chunks parts, each stored on a different OSD.</source>
+ <target>Jedes Objekt wird in Datenblöcke aufgeteilt und jeweils auf einem anderen OSD gespeichert.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5128168460056151476" datatype="html">
+ <source>Compute coding chunks for each object and store them on different OSDs.
+ The number of coding chunks is also the number of OSDs that can be down without losing data.</source>
+ <target>Berechnen Sie Codierungsdatenblöcke für jedes Objekt und speichern Sie sie auf unterschiedlichen OSDs.
+ Die Anzahl der Codierungsdatenblöcke entspricht auch der Anzahl der OSDs, die ausfallen können, ohne dass Daten verloren gehen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">18,19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8826111293169381132" datatype="html">
+ <source>The jerasure plugin is the most generic and flexible plugin,
+ it is also the default for Ceph erasure coded pools.</source>
+ <target>Das jerasure-Modul ist das allgemeinste und flexibelste Modul
+ und fungiert auch als der Standard für Ceph-Pools mit Löschcodierung.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">23,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1331133460856304156" datatype="html">
+ <source>The more flexible technique is reed_sol_van : it is enough to set k
+ and m. The cauchy_good technique can be faster but you need to chose the packetsize
+ carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents
+ in the sense that they can only be configured with m=2.</source>
+ <target>Die flexiblere Technik ist 'reed_sol_van :', wobei es ausreicht, k
+ und m festzulegen. Die Technik 'cauchy_good' kann schneller sein. Sie müssen jedoch die Paketgröße sorgfältig
+ auswählen. Sämtliche 'reed_sol_r6_op'-, 'liberation'-, 'blaum_roth'- und 'liber8tion'-Vorgänge sind dahingehend RAID6-Entsprechungen,
+ dass sie nur mit 'm=2' konfiguriert werden können.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">25,28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4577912952562931806" datatype="html">
+ <source>The encoding will be done on packets of bytes size at a time.
+ Choosing the right packet size is difficult.
+ The jerasure documentation contains extensive information on this topic.</source>
+ <target>Die Kodierung wird jeweils für Pakete von Bytegröße durchgeführt.
+ Die Wahl der richtigen Packungsgröße ist schwierig.
+ Die jerasure-Dokumentation enthält umfangreiche Informationen zu diesem Thema.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">29,31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6471646852539810855" datatype="html">
+ <source>With the jerasure plugin, when an erasure coded object is stored on
+ multiple OSDs, recovering from the loss of one OSD requires reading from all the others.
+ For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading
+ from the eleven others to repair.
+
+ The lrc erasure code plugin creates local parity chunks to be able to recover using
+ less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create
+ an additional parity chunk for every four OSDs. When a single OSD is lost, it can be
+ recovered with only four OSDs instead of eleven.</source>
+ <target>Bei Verwendung des Jerasure-Moduls, wenn ein Objekt mit Löschcodierung auf mehreren OSDs gespeichert ist,
+ müssen alle anderen OSDs gelesen werden, um die verloren gegangenen Daten eines OSDs wiederherzustellen.
+ Wenn jerasure beispielsweise mit 'k=8' und 'm=4' konfiguriert ist,
+ müssen bei Verlust eines OSDs zum Reparieren die elf anderen gelesen werden.
+
+ Das lrc-Löschcode-Modul erstellt lokale Paritätsdatenblöcke, um die Wiederherstellung mit weniger OSDs auszuführen.
+ Wenn lrc beispielsweise mit 'k=8', 'm=4' und 'l=4' konfiguriert ist, wird ein zusätzlicher Paritätsdatenblock für jeweils vier OSDs erstellt.
+ Geht ein einzelnes OSD verloren, kann es mit nur vier OSDs anstelle
+ von elf wiederhergestellt werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">34,42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2619235086723330982" datatype="html">
+ <source>Group the coding and data chunks into sets of size locality. For instance,
+ for k=4 and m=2, when locality=3 two groups of three are created. Each set can
+ be recovered without reading chunks from another set.</source>
+ <target>Gruppieren Sie die Codierungs- und Datenblöcke in Sätze entsprechend dem Speicherort.
+ Beispielsweise werden für 'k=4' und 'm=2', wenn der Speicherort '3' entspricht, zwei Dreiergruppen erstellt.
+ Jeder Satz kann wiederhergestellt werden, ohne dass Datenblöcke aus einem anderen Satz gelesen werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">43,45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3298836762557512588" datatype="html">
+ <source>The type of the crush bucket in which each set of chunks defined
+ by l will be stored. For instance, if it is set to rack, each group of l chunks will be
+ placed in a different rack. It is used to create a CRUSH rule step such as step choose
+ rack. If it is not set, no such grouping is done.</source>
+ <target>Der Typ des Crush-Buckets, in dem jeder durch l definierte Satz von Datenblöcken gespeichert wird.
+ Wenn er beispielsweise auf 'rack' festgelegt ist, wird jede Gruppe an l-Datenblöcken in einem anderen Rack platziert.
+ Er wird zum Erstellen eines CRUSH-Regelschritts verwendet, beispielsweise für einen Schritt zum Auswählen des Racks.
+ Wenn er nicht festgelegt ist, wird keine solche Gruppierung vorgenommen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">46,49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9162461669419243962" datatype="html">
+ <source>The isa plugin encapsulates the ISA library. It only runs on Intel processors.</source>
+ <target>Das isa-Modul kapselt die ISA-Bibliothek und wird nur auf Intel-Prozessoren ausgeführt.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2389282202903059852" datatype="html">
+ <source>The ISA plugin comes in two Reed Solomon forms.
+ If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.</source>
+ <target>Das ISA-Modul wird in zwei Reed Solomon-Formularen bereitgestellt.
+ Wenn 'reed_sol_van' festgelegt ist, entspricht dies Vandermonde. Ist 'cauchy' festgelegt, entspricht dies 'Cauchy'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">53,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7319555444402547739" datatype="html">
+ <source>The shec plugin encapsulates the multiple SHEC library.
+ It allows ceph to recover data more efficiently than Reed Solomon codes.</source>
+ <target>Das shec-Modul kapselt die SHEC-Mehrfachbibliothek.
+ Dadurch kann ceph Daten effizienter wiederherstellen als Reed Solomon-Codes.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">57,58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7723217930035575928" datatype="html">
+ <source>The number of parity chunks each of which includes each data chunk in its
+ calculation range. The number is used as a durability estimator. For instance, if c=2,
+ 2 OSDs can be down without losing data.</source>
+ <target>Die Anzahl der Paritätsdatenblöcke, von denen jeder jeden Datenblock in seinem Berechnungsbereich enthält.
+ Die Anzahl wird als eine Dauerhaftigkeitsschätzung verwendet. Wenn beispielsweise 'c=2' vorliegt,
+ können 2 OSDs ausfallen, ohne dass Daten verloren gehen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">59,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2054101840892270818" datatype="html">
+ <source>CLAY (short for coupled-layer) codes are erasure codes designed to
+ bring about significant savings in terms of network bandwidth and disk IO when a failed
+ node/OSD/rack is being repaired.</source>
+ <target>CLAY Codes (kurz für Coupled Layer) sind Löschcodes für
+ erhebliche Einsparungen in Bezug auf Netzwerkbandbreite und Festplatten-IO, wenn ein ausgefallener
+  Knoten/OSD/Rack repariert wird.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">64,66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491096236680229427" datatype="html">
+ <source>Number of OSDs requested to send data during recovery of a single chunk.
+ d needs to be chosen such that k+1 &lt;= d &lt;= k+m-1. The larger the d, the better
+ the savings.</source>
+ <target>Anzahl der OSDs, die während der Wiederherstellung eines einzelnen Blocks zum Senden von Daten aufgefordert werden.
+ d muss so gewählt werden, dass k+1 &lt;= d &lt;= k+m-1. Je größer d ist, desto höher
+  die Einsparungen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">67,69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2625895656705896729" datatype="html">
+ <source>scalar_mds specifies the plugin that is used as a building block
+ in the layered construction. It can be one of jerasure, isa, shec.</source>
+ <target>scalar_mds gibt das Modul an, das als Baustein
+ in der geschichteten Konstruktion verwendet wird. Es kann jerasure, isa oder shec sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">70,71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6639141182731628232" datatype="html">
+ <source>technique specifies the technique that will be picked
+ within the 'scalar_mds' plugin specified. Supported techniques
+ are 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good', 'liber8tion' for jerasure, 'reed_sol_van',
+ 'cauchy' for isa and 'single', 'multiple' for shec.</source>
+ <target>technique gibt die Technik an, die innerhalb des Moduls
+ 'scalar_mds' angegeben ist. Unterstützte Techniken
+ sind 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good', 'liber8tion' for jerasure, 'reed_sol_van',
+ 'cauchy' für isa und 'single', 'multiple' für shec.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">72,76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8172892264673403098" datatype="html">
+ <source>The name of the crush bucket used for the first step of the CRUSH rule.
+ For instance step take default.</source>
+ <target>Der Name des für den ersten Schritt der CRUSH-Regel verwendeten Crush-Buckets.
+ Beispielsweise 'step take default'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">80,81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1654284403437084515" datatype="html">
+ <source>Ensure that no two chunks are in a bucket with the same failure
+ domain. For instance, if the failure domain is host no two chunks will be stored on the same
+ host. It is used to create a CRUSH rule step such as step chooseleaf host.</source>
+ <target>Stellen Sie sicher, dass sich keine zwei Datenblöcke in einem Bucket mit derselben Ausfalldomäne befinden.
+ Wenn die Ausfalldomäne beispielsweise als Host fungiert, werden keine zwei Datenblöcke auf demselben Host gespeichert.
+ Er wird zum Erstellen eines CRUSH-Regelschritts verwendet, beispielsweise 'step chooseleaf host'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">83,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7737703816676512224" datatype="html">
+ <source>Restrict placement to devices of a specific class
+ (e.g., ssd or hdd), using the crush device class names in the CRUSH map.</source>
+ <target>Schränken Sie mithilfe der Klassennamen für Crush-Geräte in der CRUSH-Zuordnung die Platzierung
+ auf Geräte einer bestimmten Klasse (z. B. SSD oder HDD) ein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9049698214199657456" datatype="html">
+ <source>Set the directory name from which the erasure code plugin is loaded.</source>
+ <target>Legen Sie den Verzeichnisnamen fest, über den das Löschcode-Modul geladen wird.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5514060020564877279" datatype="html">
+ <source>Allows all operations</source>
+ <target>Lässt alle Vorgänge zu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4265406815683383218" datatype="html">
+ <source>Allows only operations that do not modify the server</source>
+ <target>Lässt nur Vorgänge zu, die den Server nicht ändern</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="990071930378308183" datatype="html">
+ <source>Allows no access at all</source>
+ <target>Lässt überhaupt keinen Zugriff zu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7286983657616285612" datatype="html">
+ <source>Please specify a filesystem volume.</source>
+ <target>Bitte spezifizieren Sie ein Dateisystem-Volume.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8321762156640395170" datatype="html">
+ <source>The feature is disabled because Orchestrator is not available.</source>
+ <target>Diese Funktion ist deaktiviert, da Orchestrator nicht verfügbar ist.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6718394293315494787" datatype="html">
+ <source>The Orchestrator backend doesn't support this feature.</source>
+ <target>Das Orchestrator-Backend unterstützt diese Funktion nicht.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5569418400096331461" datatype="html">
+ <source>-- Select the priority --</source>
+ <target>-- Priorität auswählen --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="802458941707537739" datatype="html">
+ <source>Low</source>
+ <target>Niedrig</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8063651736083474594" datatype="html">
+ <source>High</source>
+ <target>Hoch</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1717753935149218245" datatype="html">
+ <source>The user list data might be stale. If needed, you can manually reload it.</source>
+ <target>Die Daten der Benutzerliste könnten veraltet sein. Bei Bedarf können Sie sie manuell neu laden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/list-with-details.class.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7077550143229856452" datatype="html">
+ <source>Retrieving data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>Daten für <x id="PH" equiv-text="statusFor"/> werden abgerufen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8231424898988217966" datatype="html">
+ <source>Retrieving data.</source>
+ <target>Daten werden abgerufen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2357645764289315007" datatype="html">
+ <source>Please wait...</source>
+ <target>Bitte warten...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="232824565824302482" datatype="html">
+ <source>Displaying previously cached data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>Zuvor zwischengespeicherte Daten für <x id="PH" equiv-text="statusFor"/> werden angezeigt.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8721257977793603730" datatype="html">
+ <source>Displaying previously cached data.</source>
+ <target>Zuvor zwischengespeicherte Daten werden angezeigt.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6731313206654246255" datatype="html">
+ <source>Could not load data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>Konnte Daten für <x id="PH" equiv-text="statusFor"/> nicht laden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3359748695862553898" datatype="html">
+ <source>Could not load data.</source>
+ <target>Konnte Daten nicht laden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4836577225879717660" datatype="html">
+ <source>Please check the cluster health.</source>
+ <target>Prüfen Sie die Clusterintegrität.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1519954996184640001" datatype="html">
+ <source>Error</source>
+ <target>Fehler</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5037437391296624618" datatype="html">
+ <source>Information</source>
+ <target>Informationen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4648900870671159218" datatype="html">
+ <source>Success</source>
+ <target>Erfolg</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3425367071066107827" datatype="html">
+ <source>Danger</source>
+ <target>Gefahr</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c947210e2d162b6225083d18820ab602f58cd2d" datatype="html">
+ <source>Remove the custom configuration value. The default configuration will be inherited and used instead.</source>
+ <target>Entfernen Sie den aktuellen Konfigurationswert. Stattdessen wird der Standard-Konfigurationswert übernommen und verwendet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="454ee9cb60b00446a8fb147fd2cc5eb836320586" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>.</source>
+ <target>Der eingegebene Wert ist zu groß! Er darf nicht größer als <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/> sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fc8a22825131e028336f60ef909ccbd96059703" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>.</source>
+ <target>Der eingegebene Wert ist zu niedrig! Er darf nicht kleiner als <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/> sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4dd200b7f9e19048cf90516843b40964f2af3fe9" datatype="html">
+ <source>Copy to Clipboard</source>
+ <target>In Zwischenablage kopieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6110699a3562eeb15371063c0cf7f6bfd88a0209" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>?</source>
+ <target>Möchten Sie wirklich <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="549859e511ba5af0ea03fcaa620c472f08038969" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected items?</source>
+ <target>Möchten Sie die gewählten Einträge wirklich <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/>?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="54839ebc827b73c9dc4e1df731c6d36a85036af7" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/>?</source>
+ <target>Möchten Sie die gewählten <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/> wirklich <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/>?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2be8b7f04f0104d3fad90d079d8202b74f758b9a" datatype="html">
+ <source>Yes, I am sure.</source>
+ <target>Ja, ich bin sicher.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4523728183000855476" datatype="html">
+ <source>documentation</source>
+ <target>Dokumentation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/doc/doc.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3099741642167775297" datatype="html">
+ <source>Download</source>
+ <target>Herunterladen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/download-button/download-button.component.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1417693714872528491" datatype="html">
+ <source>This field is required.</source>
+ <target>Dies ist ein Pflichtfeld.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5321335688371682440" datatype="html">
+ <source>An error occurred.</source>
+ <target>Ein Fehler ist aufgetreten.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5109325fb160b543f71a51e7511c00575057431" datatype="html">
+ <source>Loading panel data...</source>
+ <target>Bereichsdaten werden geladen...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a21acde005f80ceadb1391be1e7ff8b6d18188a0" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the monitoring functionality.</source>
+ <target>Lesen Sie <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> zum Konfigurieren und Aktivieren der Überwachungsfunktion.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a0ed4bd7b7add2a6febf7adf58d8cde5e421418" datatype="html">
+ <source>Grafana Dashboard doesn't exist. Please refer to <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to add dashboards to Grafana.</source>
+ <target>Das Grafana-Dashboard ist nicht vorhanden. In der <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> wird beschrieben, wie Grafana-Dashboards hinzugefügt werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e11830040bd64804a0555de76f291d5832772d4" datatype="html">
+ <source>Grafana Time Picker</source>
+ <target>Grafana-Zeitauswahl</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="238c1ba845dd7330e8088165275919a1debf1ca3" datatype="html">
+ <source>Reset Settings</source>
+ <target>Einstellungen für Zurücksetzungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7888499255176013171" datatype="html">
+ <source>Last 5 minutes</source>
+ <target>Letzte 5 Minuten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6892361549797455305" datatype="html">
+ <source>Last 15 minutes</source>
+ <target>Letzte 15 Minuten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2653641162607195423" datatype="html">
+ <source>Last 30 minutes</source>
+ <target>Letzte 30 Minuten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4117793269024790392" datatype="html">
+ <source>Last 1 hour (Default)</source>
+ <target>Letzte Stunde (Standard)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2645733658763754077" datatype="html">
+ <source>Last 3 hours</source>
+ <target>Letzte 3 Stunden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7360078715633936807" datatype="html">
+ <source>Last 6 hours</source>
+ <target>Letzte 6 Stunden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5055313582241816303" datatype="html">
+ <source>Last 12 hours</source>
+ <target>Letzte 12 Stunden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9186529157286281693" datatype="html">
+ <source>Last 24 hours</source>
+ <target>Letzte 24 Stunden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4498682414491138092" datatype="html">
+ <source>Yesterday</source>
+ <target>Gestern</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="929003859318769922" datatype="html">
+ <source>Today so far</source>
+ <target>Heute bisher</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5525943133564968818" datatype="html">
+ <source>Day before yesterday</source>
+ <target>Vorgestern</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6168755117727892817" datatype="html">
+ <source>Last 2 days</source>
+ <target>Letzte 2 Tage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7574807704224200535" datatype="html">
+ <source>This day last week</source>
+ <target>Dieser Tag letzte Woche</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4420128118950221234" datatype="html">
+ <source>Previous week</source>
+ <target>Vorwoche</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4063965603321223683" datatype="html">
+ <source>This week so far</source>
+ <target>Diese Woche bisher</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4873149362496451858" datatype="html">
+ <source>Last 7 days</source>
+ <target>Letzte 7 Tage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8586908745456864217" datatype="html">
+ <source>Previous month</source>
+ <target>Vormonat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1647573304710886499" datatype="html">
+ <source>This month so far</source>
+ <target>Dieser Monat bisher</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2949150997160654358" datatype="html">
+ <source>Last 30 days</source>
+ <target>Letzte 30 Tage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7469939859049484736" datatype="html">
+ <source>Last 90 days</source>
+ <target>Letzte 90 Tage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847501198811458781" datatype="html">
+ <source>Last 6 months</source>
+ <target>Letzte 6 Monate</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7447583558445881102" datatype="html">
+ <source>Last 1 year</source>
+ <target>Letztes Jahr</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="100513227838842152" datatype="html">
+ <source>Previous year</source>
+ <target>Vorjahr</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3650872673621947074" datatype="html">
+ <source>This year so far</source>
+ <target>Dieses Jahr bisher</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1262816694819959075" datatype="html">
+ <source>Last 2 years</source>
+ <target>Letzte 2 Jahre</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7878813844917362690" datatype="html">
+ <source>Last 5 years</source>
+ <target>Letzte 5 Jahre</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3fb5709e10166cbc85970cbff103db227dbeb813" datatype="html">
+ <source>Select a Language</source>
+ <target>Sprache auswählen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/language-selector/language-selector.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e52e9143145e1db5146258de81eae018a407b31" datatype="html">
+ <source>Clear notifications</source>
+ <target>Benachrichtigungen löschen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0b07bb6b7ff21ede439dd04eaf8872d1ecb84d8" datatype="html">
+ <source>Remove notification</source>
+ <target>Benachrichtigungen entfernen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e17a1d75189da843f541f7764f188f2b19a97df2" datatype="html">
+ <source>Duration:</source>
+ <target>Dauer:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d4b37c6675c5b436a54c43d6716eec835e1aa7f" datatype="html">
+ <source>There are no notifications.</source>
+ <target>Es sind keine Benachrichtigungen verfügbar.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b20e42ac4354d449f2718428b5390933eef0c1b9" datatype="html">
+ <source>The feature is not supported in the current Orchestrator.</source>
+ <target>Diese Funktion wird im aktuellen Orchestrator nicht unterstützt.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a437b8f93cf826817c04a4277edb1ae3a93a1ab" datatype="html">
+ <source>Orchestrator is not available. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the functionality.</source>
+ <target>Orchestrator ist nicht verfügbar. Lesen Sie <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> zum Konfigurieren und Aktivieren der Funktion.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">7,9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20b3d45b0c08a2951a9974fa20505e4de95250c9" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>less than 1<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day. Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <target>Das Passwort läuft in<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>weniger als 1 <x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>Tag ab. Klicken Sie<x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>hier<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>, um es jetzt zu ändern.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">9,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f34088c155e40ffb23770a465a65868ce772b2" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day(s). Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <target>Das Passwort läuft in<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> Tag(en) ab. Klicken Sie <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>hier<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>, um es jetzt zu ändern.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8d1785038d461ec66b5799db21864182b35900a" datatype="html">
+ <source>Refresh</source>
+ <target>Aktualisieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/refresh-selector/refresh-selector.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3417247046175131869" datatype="html">
+ <source>No items selected.</source>
+ <target>Keine Elemente ausgewählt.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1034353870189672674" datatype="html">
+ <source>Deselect item to select again</source>
+ <target>Elementauswahl zum erneuten Auswählen aufheben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4879298070255432995" datatype="html">
+ <source>Selection limit reached</source>
+ <target>Auswahllimit erreicht</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001227209911602786" datatype="html">
+ <source>Filter tags</source>
+ <target>Tags filtern</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="791789583719406586" datatype="html">
+ <source>Add badge</source>
+ <target>Badge hinzufügen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="699988676752930063" datatype="html">
+ <source>There are no items available.</source>
+ <target>Keine Elemente verfügbar.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6702323d3760e3db0e2e785d567469d18beb120" datatype="html">
+ <source>The Ceph community needs your help to continue improving: please <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>Activate<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> the <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Telemetry<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> module.</source>
+ <target>Die Ceph-Community braucht Ihre Unterstützung für weitere Optimierung: Bitte <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>aktivieren<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> Sie das <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Telemetrie-<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>Modul.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.html</context>
+ <context context-type="linenumber">8,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8770134622386151776" datatype="html">
+ <source>Telemetry activation reminder muted</source>
+ <target>Erinnerung an Telemetrieaktivierung stummgeschaltet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8352450862052130357" datatype="html">
+ <source>You can activate the module on the Telemetry configuration page (&lt;b&gt;Dashboard Settings&lt;/b&gt; -&gt; &lt;b&gt;Telemetry configuration&lt;/b&gt;) at any time.</source>
+ <target>Sie können das Modul jederzeit auf der Telemetriekonfigurationsseite (&lt;b&gt;Dashboard-Einstellungen&lt;/b&gt;-&gt;&lt;b&gt;Telemetriekonfiguration&lt;/b&gt;) aktivieren.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bc9e5365a581105ce37cf47d1d74e4ad9eb75ce" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e634c306cab9e8879c3392593714c1ceab85437d" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3249513483374643425" datatype="html">
+ <source>Add</source>
+ <target>Hinzufügen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4359847060009771702" datatype="html">
+ <source>Set</source>
+ <target>Einstellen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935187492052582731" datatype="html">
+ <source>Submit</source>
+ <target>Absenden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4814285799071780083" datatype="html">
+ <source>Remove</source>
+ <target>Entfernen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8363450564548681668" datatype="html">
+ <source>Unset</source>
+ <target>Einstellung aufheben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2159130950882492111" datatype="html">
+ <source>Cancel</source>
+ <target>Abbrechen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1295614462098694869" datatype="html">
+ <source>Preview</source>
+ <target>Vorschau</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2354817630223808522" datatype="html">
+ <source>Move</source>
+ <target>Verschieben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3885497195825665706" datatype="html">
+ <source>Next</source>
+ <target>Weiter</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8890553633144307762" datatype="html">
+ <source>Back</source>
+ <target>Zurück</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5834780181397311898" datatype="html">
+ <source>Clone</source>
+ <target>Klonen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4323470180912194028" datatype="html">
+ <source>Copy</source>
+ <target>Kopieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2131301778880826094" datatype="html">
+ <source>Deep Scrub</source>
+ <target>Umfassender Scrub</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1704447209800801558" datatype="html">
+ <source>Destroy</source>
+ <target>Vernichten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8343007008325027187" datatype="html">
+ <source>Evict</source>
+ <target>Vertreiben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="408179081163888126" datatype="html">
+ <source>Flatten</source>
+ <target>Vereinfachen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="318900679147387932" datatype="html">
+ <source>Mark Down</source>
+ <target>Als ausgefallen markieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5275142643521766706" datatype="html">
+ <source>Mark In</source>
+ <target>Mit Befehl 'In' markieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6973272903386150199" datatype="html">
+ <source>Mark Lost</source>
+ <target>Als verloren markieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1962653792210847411" datatype="html">
+ <source>Mark Out</source>
+ <target>Mit Befehl 'Out' markieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4424610588915076517" datatype="html">
+ <source>Protect</source>
+ <target>Schützen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6041115344061899387" datatype="html">
+ <source>Rename</source>
+ <target>Umbenennen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">164</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6770769801335635194" datatype="html">
+ <source>Restore</source>
+ <target>Wiederherstellen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2003230525878010676" datatype="html">
+ <source>Reweight</source>
+ <target>Neu gewichten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5430834128563178593" datatype="html">
+ <source>Scrub</source>
+ <target>Scrub</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8461842260159597706" datatype="html">
+ <source>Show</source>
+ <target>Anzeigen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5655608100705734230" datatype="html">
+ <source>Move to Trash</source>
+ <target>In Papierkorb verschieben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4622393909937403117" datatype="html">
+ <source>Unprotect</source>
+ <target>Schutz aufheben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1230154438678955604" datatype="html">
+ <source>Change</source>
+ <target>Ändern</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8450843381175865415" datatype="html">
+ <source>Enter Maintenance</source>
+ <target>Wartung beginnen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1610181371597502589" datatype="html">
+ <source>Exit Maintenance</source>
+ <target>Wartung verlassen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="676511611419004737" datatype="html">
+ <source>Start Drain</source>
+ <target>Entleeren starten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7170653322511987983" datatype="html">
+ <source>Stop Drain</source>
+ <target>Entleeren stoppen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5528551262937858942" datatype="html">
+ <source>Recreate</source>
+ <target>Wiederherstellen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2502364444688691031" datatype="html">
+ <source>Expire</source>
+ <target>Ablaufen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6381490568322624964" datatype="html">
+ <source>Deleted</source>
+ <target>Gelöscht</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="231679111972850796" datatype="html">
+ <source>Added</source>
+ <target>Hinzugefügt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5406093358072761930" datatype="html">
+ <source>Removed</source>
+ <target>Entfernt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3008573030448240863" datatype="html">
+ <source>Edited</source>
+ <target>Bearbeitet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4381944803872489731" datatype="html">
+ <source>Canceled</source>
+ <target>Abgebrochen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754993936947658096" datatype="html">
+ <source>Previewed</source>
+ <target>Vorschau angezeigt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6001163963116907226" datatype="html">
+ <source>Moved</source>
+ <target>Verschoben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4932744777596632840" datatype="html">
+ <source>Cloned</source>
+ <target>Geklont</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2115592966120408375" datatype="html">
+ <source>Copied</source>
+ <target>Kopiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7937474560394832586" datatype="html">
+ <source>Deep Scrubbed</source>
+ <target>Umfassender Scrub</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6321562733889197649" datatype="html">
+ <source>Destroyed</source>
+ <target>Vernichtet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7460162290177581995" datatype="html">
+ <source>Flattened</source>
+ <target>Vereinfacht</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3662010055028969035" datatype="html">
+ <source>Marked Down</source>
+ <target>Als ausgefallen markiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5880434235404894589" datatype="html">
+ <source>Marked In</source>
+ <target>Markiert in</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="266997194072682078" datatype="html">
+ <source>Marked Lost</source>
+ <target>Als verloren markieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">250</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4010544044592534535" datatype="html">
+ <source>Marked Out</source>
+ <target>Als ausgefallen markiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4776304093333411035" datatype="html">
+ <source>Protected</source>
+ <target>Geschützt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2700903921419382511" datatype="html">
+ <source>Purged</source>
+ <target>Bereinigt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5488667333459350160" datatype="html">
+ <source>Renamed</source>
+ <target>Umbenannt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8044659850000829751" datatype="html">
+ <source>Restored</source>
+ <target>Wiederhergestellt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559472082694466366" datatype="html">
+ <source>Reweighted</source>
+ <target>Neu gewichtet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022271525067453676" datatype="html">
+ <source>Rolled back</source>
+ <target>Rollback wurde ausgeführt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2483217756816388123" datatype="html">
+ <source>Scrubbed</source>
+ <target>Scrub</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7200036055090632378" datatype="html">
+ <source>Showed</source>
+ <target>Angezeigt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7609648817347881129" datatype="html">
+ <source>Moved to Trash</source>
+ <target>In den Papierkorb verschoben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7810326403606456469" datatype="html">
+ <source>Unprotected</source>
+ <target>Schutz aufgehoben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5620774899056099259" datatype="html">
+ <source>Recreated</source>
+ <target>Wiederhergestellt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464749780222721589" datatype="html">
+ <source>Expired</source>
+ <target>Abgelaufen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">266</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e5e23363e949f7dcbaf034bdb141a561132a10e" datatype="html">
+ <source>Clear filters</source>
+ <target>Filter löschen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80cc9a12d4bf6fe454ed94b379eeaf915f920bb7" datatype="html">
+ <source>selected</source>
+ <target>ausgewählt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <note priority="1" from="description">X selected</note>
+ </trans-unit>
+ <trans-unit id="0cb77511a9a148e05b9adf36cc07269956fbb29d" datatype="html">
+ <source>found</source>
+ <target>gefunden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <note priority="1" from="description">X found</note>
+ </trans-unit>
+ <trans-unit id="79347388740c50b7ac97e144c2494bb62912f312" datatype="html">
+ <source>total</source>
+ <target>insgesamt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <note priority="1" from="description">X total</note>
+ </trans-unit>
+ <trans-unit id="2a3dab422cc892db037db8632bb84a6bf496e2d1" datatype="html">
+ <source>Expand/Collapse Row</source>
+ <target>Zeile erweitern/reduzieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4047162422391207122" datatype="html">
+ <source>Failed to load data.</source>
+ <target>Daten konnten nicht geladen werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.ts</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="709331713250198508" datatype="html">
+ <source>Loading form data...</source>
+ <target>Formulardaten werden geladen...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3850344644863430180" datatype="html">
+ <source>Form data could not be loaded.</source>
+ <target>Formulardaten konnten nicht geladen werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4626760504772708998" datatype="html">
+ <source>Size has to be at least <x id="PH" equiv-text="value"/> or more</source>
+ <target>Größe muss mindestens <x id="PH" equiv-text="value"/> oder mehr sein</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">428</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2880361802894657892" datatype="html">
+ <source>Size has to be at most <x id="PH" equiv-text="value"/> or less</source>
+ <target>Größe muss mindestens <x id="PH" equiv-text="value"/> oder weniger sein</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2807800733729323332" datatype="html">
+ <source>Yes</source>
+ <target>Ja</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3542042671420335679" datatype="html">
+ <source>No</source>
+ <target>Nein</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7789266940050748913" datatype="html">
+ <source>in %s</source>
+ <target>in %s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565573880632900017" datatype="html">
+ <source>%s ago</source>
+ <target>vor %s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="220300059326988179" datatype="html">
+ <source>a few seconds</source>
+ <target>einigen Sekunden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2761143993878941513" datatype="html">
+ <source>%d seconds</source>
+ <target>%d Sekunden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7094767962693903153" datatype="html">
+ <source>a minute</source>
+ <target>einer Minute</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7597613755904774250" datatype="html">
+ <source>%d minutes</source>
+ <target>%d Minuten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2757762976030115752" datatype="html">
+ <source>an hour</source>
+ <target>einer Stunde</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9118454901758656303" datatype="html">
+ <source>%d hours</source>
+ <target>%d Stunden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7435193742089920080" datatype="html">
+ <source>a day</source>
+ <target>einem Tag</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1821334622562842480" datatype="html">
+ <source>%d days</source>
+ <target>%d Tagen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7375306199026780379" datatype="html">
+ <source>a week</source>
+ <target>einer Woche</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7272688256541915488" datatype="html">
+ <source>%d weeks</source>
+ <target>%d Wochen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5761124614324704118" datatype="html">
+ <source>a month</source>
+ <target>einem Monat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="352195662913351589" datatype="html">
+ <source>%d months</source>
+ <target>%d Monaten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7562153591649199139" datatype="html">
+ <source>a year</source>
+ <target>einem Jahr</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5424759741855527370" datatype="html">
+ <source>%d years</source>
+ <target>%d Jahren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7738182956549158907" datatype="html">
+ <source>Required rules for passwords:</source>
+ <target>Erforderliche Regeln für Passwörter:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8839765875053270528" datatype="html">
+ <source>Must contain at least <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> characters</source>
+ <target>Muss mindestens <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> Zeichen enthalten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3098731108593590794" datatype="html">
+ <source>Must not be the same as the previous one</source>
+ <target>Darf nicht identisch zum vorherigen sein</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9150236741862848105" datatype="html">
+ <source>Cannot contain the username</source>
+ <target>Darf nicht den Benutzernamen enthalten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6395043854518867543" datatype="html">
+ <source>Cannot contain any configured keyword</source>
+ <target>Darf keine der konfigurierten Schlüsselwörter enthalten</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="907558624910601703" datatype="html">
+ <source>Cannot contain any repetitive characters e.g. &quot;aaa&quot;</source>
+ <target>Zeichen dürfen sich nicht wiederholen, z.B. &quot;aaa&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514384270734082343" datatype="html">
+ <source>Cannot contain any sequential characters e.g. &quot;abc&quot;</source>
+ <target>Es dürfen keine aufeinander folgenden Zeichen enthalten sein, z.B. &quot;abc&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4119354814383293871" datatype="html">
+ <source>Must consist of characters from the following groups:
+ * Alphabetic a-z, A-Z
+ * Numbers 0-9
+ * Special chars: !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * Any other characters (signs)</source>
+ <target>Muss aus Zeichen aus den folgenden Gruppen bestehen:
+ * Alphabetisch a-z, A-Z
+ * Ziffern 0-9
+ * Sonderzeichen: !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * Andere Zeichen (Symbole)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">30,34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8649061117624699581" datatype="html">
+ <source>Your matcher seems to match no currently defined rule or active alert.</source>
+ <target>Ihr Matcher scheint mit keiner aktuell definierten Regel oder aktiven Warnung übereinzustimmen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7122912874364762704" datatype="html">
+ <source>no active alerts</source>
+ <target>keine aktiven Warnungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7388215679576832341" datatype="html">
+ <source>1 active alert</source>
+ <target>1 aktive Warnung</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3112400568960537267" datatype="html">
+ <source><x id="PH" equiv-text="alerts"/> active alerts</source>
+ <target><x id="PH" equiv-text="alerts"/> aktive Warnungen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6264717417287230743" datatype="html">
+ <source>Matches 1 rule</source>
+ <target>Stimmt mit 1 Regel überein</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054663176394183966" datatype="html">
+ <source>Matches <x id="PH" equiv-text="rules"/> rules</source>
+ <target>Stimmt mit <x id="PH" equiv-text="rules"/> Regeln überein</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6674225401121099210" datatype="html">
+ <source><x id="PH" equiv-text="rule"/> with <x id="PH_1" equiv-text="alert"/>.</source>
+ <target><x id="PH" equiv-text="rule"/> mit <x id="PH_1" equiv-text="alert"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5659908877047925719" datatype="html">
+ <source>Quality of Service</source>
+ <target>Quality of Service</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1277565045885499475" datatype="html">
+ <source>BPS Limit</source>
+ <target>BPS-Limit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2289210323987692906" datatype="html">
+ <source>The desired limit of IO bytes per second.</source>
+ <target>Das gewünschte Limit der E/A-Bytes pro Sekunde.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753589939879013605" datatype="html">
+ <source>IOPS Limit</source>
+ <target>IOPS-Limit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2213985059444278522" datatype="html">
+ <source>The desired limit of IO operations per second.</source>
+ <target>Das gewünschte Limit der E/A-Vorgänge pro Sekunde.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2487530611825582289" datatype="html">
+ <source>Read BPS Limit</source>
+ <target>BPS-Limit für Lesevorgänge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8071352270469595250" datatype="html">
+ <source>The desired limit of read bytes per second.</source>
+ <target>Das gewünschte Limit der gelesenen Bytes pro Sekunde.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1632513758247239690" datatype="html">
+ <source>Read IOPS Limit</source>
+ <target>IOPS-Limit für Lesevorgänge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2361786794607418566" datatype="html">
+ <source>The desired limit of read operations per second.</source>
+ <target>Das gewünschte Limit für Lesevorgänge pro Sekunde.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="894600353504285551" datatype="html">
+ <source>Write BPS Limit</source>
+ <target>BPS-Limit für Schreibvorgänge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911437671369366025" datatype="html">
+ <source>The desired limit of write bytes per second.</source>
+ <target>Das gewünschte Limit der geschriebenen Bytes pro Sekunde.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2947346368707443195" datatype="html">
+ <source>Write IOPS Limit</source>
+ <target>IOPS-Limit für Schreibvorgänge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5506349527983391356" datatype="html">
+ <source>The desired limit of write operations per second.</source>
+ <target>Das gewünschte Limit für Schreibvorgänge pro Sekunde.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559424229658244943" datatype="html">
+ <source>BPS Burst</source>
+ <target>BPS-Block</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3454058701331860330" datatype="html">
+ <source>The desired burst limit of IO bytes.</source>
+ <target>Das gewünschte Blocklimit der E/A-Bytes.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171005761926448741" datatype="html">
+ <source>IOPS Burst</source>
+ <target>IOPS-Block</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4939532784700485729" datatype="html">
+ <source>The desired burst limit of IO operations.</source>
+ <target>Das gewünschte Blocklimit der E/A-Vorgänge.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6273492199526646930" datatype="html">
+ <source>Read BPS Burst</source>
+ <target>BPS-Block für Lesevorgänge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3105467595643777520" datatype="html">
+ <source>The desired burst limit of read bytes.</source>
+ <target>Das gewünschte Blocklimit der gelesenen Bytes.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2170715106679765467" datatype="html">
+ <source>Read IOPS Burst</source>
+ <target>IOPS-Block für Lesevorgänge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6234106755510510672" datatype="html">
+ <source>The desired burst limit of read operations.</source>
+ <target>Das gewünschte Blocklimit der Lesevorgänge.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="228509518172572466" datatype="html">
+ <source>Write BPS Burst</source>
+ <target>BPS-Block für Schreibvorgänge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7803279807796571240" datatype="html">
+ <source>The desired burst limit of write bytes.</source>
+ <target>Das gewünschte Blocklimit der geschriebenen Bytes.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9125474584914848055" datatype="html">
+ <source>Write IOPS Burst</source>
+ <target>IOPS-Block für Schreibvorgänge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5839129348567326667" datatype="html">
+ <source>The desired burst limit of write operations.</source>
+ <target>Das gewünschte Blocklimit der Schreibvorgänge.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="614961883076556986" datatype="html">
+ <source>Failed to <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></source>
+ <target>Fehler bei <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="489145301781720653" datatype="html">
+ <source>Executing</source>
+ <target>Wird ausgeführt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4238828029954346941" datatype="html">
+ <source>execute</source>
+ <target>ausführen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7196604637389554584" datatype="html">
+ <source>Executed</source>
+ <target>Ausgeführt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4418441687454700644" datatype="html">
+ <source>unknown task</source>
+ <target>Unbekannte Aufgabe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8667665916832796867" datatype="html">
+ <source>Creating</source>
+ <target>Wird erstellt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6031236679730054907" datatype="html">
+ <source>create</source>
+ <target>erstellen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5593033420216313122" datatype="html">
+ <source>Updating</source>
+ <target>Wird aktualisiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6100869651653026893" datatype="html">
+ <source>update</source>
+ <target>aktualisieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3141301060598402455" datatype="html">
+ <source>Deleting</source>
+ <target>Wird gelöscht</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3420504288275541125" datatype="html">
+ <source>Adding</source>
+ <target>Füge hinzu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1059784693423848532" datatype="html">
+ <source>add</source>
+ <target>hinzufügen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594819887188505274" datatype="html">
+ <source>Removing</source>
+ <target>Entferne</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2123171795960509943" datatype="html">
+ <source>remove</source>
+ <target>entfernen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1946427188770321847" datatype="html">
+ <source>Importing</source>
+ <target>Importiere</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8495827411619139669" datatype="html">
+ <source>import</source>
+ <target>importieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218459863491436562" datatype="html">
+ <source>Imported</source>
+ <target>Importiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6534993668932538712" datatype="html">
+ <source>RBD '<x id="PH" equiv-text="metadata.image_spec"/>'</source>
+ <target>RBD '<x id="PH" equiv-text="metadata.image_spec"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8237287859948228705" datatype="html">
+ <source>RBD snapshot '<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>'</source>
+ <target>RBD Snapshot '<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2328067975897167268" datatype="html">
+ <source>mirroring site name</source>
+ <target>Spiegelung des Site-Namens</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4433460322631470833" datatype="html">
+ <source>bootstrap token</source>
+ <target>Bootstrap-Token</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7044591639782280183" datatype="html">
+ <source>mirror mode for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>Spiegelungsmodus für Pool '<x id="PH" equiv-text="metadata.pool_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7109746474198366468" datatype="html">
+ <source>mirror peer for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>Peer für '<x id="PH" equiv-text="metadata.pool_name"/>' spiegeln</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6201476020617351396" datatype="html">
+ <source>all dashboards</source>
+ <target>Alle Dashboards</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7268953097700363232" datatype="html">
+ <source>Identifying</source>
+ <target>Identifiziere</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4337678035264231187" datatype="html">
+ <source>identify</source>
+ <target>identifizieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7257219307556106552" datatype="html">
+ <source>Identified</source>
+ <target>Identifiziert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6002370161381995023" datatype="html">
+ <source>device '<x id="PH" equiv-text="metadata.device"/>' on host '<x id="PH_1" equiv-text="metadata.hostname"/>'</source>
+ <target>Laufwerk '<x id="PH" equiv-text="metadata.device"/>' auf Host '<x id="PH_1" equiv-text="metadata.hostname"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5580298273054260850" datatype="html">
+ <source>OSDs (DriveGroups: <x id="PH" equiv-text="metadata.tracking_id"/>)</source>
+ <target>OSDs (DriveGroups: <x id="PH" equiv-text="metadata.tracking_id"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2182125722527364040" datatype="html">
+ <source>Name is already used by <x id="PH" equiv-text="this.pool(metadata)"/>.</source>
+ <target>Name wird bereits von <x id="PH" equiv-text="this.pool(metadata)"/> verwendet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">182</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7892856315477304281" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> is busy.</source>
+ <target><x id="PH" equiv-text="this.rbd.default(metadata)"/> ist beschäftigt.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4690045751984117407" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> contains snapshots.</source>
+ <target><x id="PH" equiv-text="this.rbd.default(metadata)"/> enthält Snapshots.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="562148565853868662" datatype="html">
+ <source>Cloning</source>
+ <target>Wird geklont</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1197352830433807469" datatype="html">
+ <source>clone</source>
+ <target>klonen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1692004144561317867" datatype="html">
+ <source>Snapshot of <x id="PH" equiv-text="this.rbd.child(metadata)"/> must be protected.</source>
+ <target>Snapshot von <x id="PH" equiv-text="this.rbd.child(metadata)"/> muss geschützt sein.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8531200838331320284" datatype="html">
+ <source>Copying</source>
+ <target>Wird kopiert</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6862265996781523030" datatype="html">
+ <source>copy</source>
+ <target>kopieren</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3556912098733712857" datatype="html">
+ <source>Flattening</source>
+ <target>Wird vereinfacht</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2488773646187451754" datatype="html">
+ <source>flatten</source>
+ <target>vereinfachen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="704305783678486635" datatype="html">
+ <source>Cannot unprotect <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> because it contains child images.</source>
+ <target>Der Schutz von <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> kann aufgrund untergeordneter Images nicht aufgehoben werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">223,225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101271773452792348" datatype="html">
+ <source>Cannot delete <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/> because it's protected.</source>
+ <target><x id="PH" equiv-text="this.rbd.snapshot(metadata)"/> kann nicht gelöscht werden, da es geschützt ist.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5143010940199748580" datatype="html">
+ <source>Rolling back</source>
+ <target>Rollback wird ausgeführt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1315686250907089544" datatype="html">
+ <source>rollback</source>
+ <target>Rollback</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5010267418211867946" datatype="html">
+ <source>Moving</source>
+ <target>Wird verschoben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4366763205960752449" datatype="html">
+ <source>move</source>
+ <target>verschieben</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="695867152524584829" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_spec"/>' to trash</source>
+ <target>Image '<x id="PH" equiv-text="metadata.image_spec"/>' in den Papierkorb</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423442774536615202" datatype="html">
+ <source>Could not find image.</source>
+ <target>Image konnte nicht gefunden werden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2622324641113512527" datatype="html">
+ <source>Restoring</source>
+ <target>Wird wiederhergestellt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3347932678307141902" datatype="html">
+ <source>restore</source>
+ <target>wiederherstellen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7488038030362249932" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>' into '<x id="PH_1" equiv-text="metadata.new_image_name"/>'</source>
+ <target>Image '<x id="PH" equiv-text="metadata.image_id_spec"/>' in '<x id="PH_1" equiv-text="metadata.new_image_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565688512490959949" datatype="html">
+ <source>Image name '<x id="PH" equiv-text="metadata.new_image_name"/>' is already in use.</source>
+ <target>Imagename '<x id="PH" equiv-text="metadata.new_image_name"/>' wird bereits verwendet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6331051389974655106" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>'</source>
+ <target>Image '<x id="PH" equiv-text="metadata.image_id_spec"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8245559899946787147" datatype="html">
+ <source>Purging</source>
+ <target>Wird bereinigt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7879437654311684252" datatype="html">
+ <source>purge</source>
+ <target>bereinigen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1440427157062670480" datatype="html">
+ <source>all pools</source>
+ <target>alle Pools</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8677740163708263843" datatype="html">
+ <source>images from <x id="PH" equiv-text="message"/></source>
+ <target>Images von<x id="PH" equiv-text="message"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011237345035114219" datatype="html">
+ <source>Cannot disable mirroring because it contains a peer.</source>
+ <target>Spiegelung kann nicht deaktiviert werden, da sie einen Peer enthält.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">292</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7391584598242145869" datatype="html">
+ <source>host '<x id="PH" equiv-text="metadata.hostname"/>'</source>
+ <target>Host '<x id="PH" equiv-text="metadata.hostname"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6964302691596180722" datatype="html">
+ <source>OSD '<x id="PH" equiv-text="metadata.svc_id"/>'</source>
+ <target>OSD '<x id="PH" equiv-text="metadata.svc_id"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="488305686602466689" datatype="html">
+ <source>pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>Pool '<x id="PH" equiv-text="metadata.pool_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5921392748828575278" datatype="html">
+ <source>erasure code profile '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <target>Löschcode-Profil '<x id="PH" equiv-text="metadata.name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2423915105798557698" datatype="html">
+ <source>crush rule '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <target>Crush-Regel '<x id="PH" equiv-text="metadata.name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">370</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8273044996643438592" datatype="html">
+ <source>target '<x id="PH" equiv-text="metadata.target_iqn"/>'</source>
+ <target>Ziel '<x id="PH" equiv-text="metadata.target_iqn"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5474643443735437364" datatype="html">
+ <source>NFS '<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>'</source>
+ <target>NFS '<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">378,380</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2235495382025026939" datatype="html">
+ <source>Service '<x id="PH" equiv-text="metadata.service_name"/>'</source>
+ <target>Dienst '<x id="PH" equiv-text="metadata.service_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ </body>
+ </file>
+</xliff> \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.es-ES.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.es-ES.xlf
new file mode 100644
index 000000000..661596a2f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.es-ES.xlf
@@ -0,0 +1,14886 @@
+<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en-US" datatype="plaintext" original="ng2.template" target-language="es-ES">
+ <body>
+ <trans-unit id="ngb.alert.close" datatype="html">
+ <source>Close</source>
+ <target>Cerrar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/alert/alert.ts</context>
+ <context context-type="linenumber">58,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.slide-number" datatype="html">
+ <source> Slide <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> of <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </source>
+ <target> Diapositiva <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> de <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">114,118</context>
+ </context-group>
+ <note priority="1" from="description">Currently selected slide number read by screen reader</note>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.previous" datatype="html">
+ <source>Previous</source>
+ <target>Anterior</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">132,134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.next" datatype="html">
+ <source>Next</source>
+ <target>Siguiente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">147,152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-month" datatype="html">
+ <source>Select month</source>
+ <target>Seleccionar mes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">44,49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">49,50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-year" datatype="html">
+ <source>Select year</source>
+ <target>Seleccionar año</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">59,63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.previous-month" datatype="html">
+ <source>Previous month</source>
+ <target>El mes pasado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">24,27</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">35,36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.next-month" datatype="html">
+ <source>Next month</source>
+ <target>El próximo mes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">47,50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">60,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first" datatype="html">
+ <source>««</source>
+ <target>««</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">182,183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous" datatype="html">
+ <source>«</source>
+ <target>«</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">186,190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next" datatype="html">
+ <source>»</source>
+ <target>»</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">194,195</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last" datatype="html">
+ <source>»»</source>
+ <target>»»</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">201,204</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first-aria" datatype="html">
+ <source>First</source>
+ <target>Primer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">208,209</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous-aria" datatype="html">
+ <source>Previous</source>
+ <target>Anterior</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">215,216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next-aria" datatype="html">
+ <source>Next</source>
+ <target>Siguiente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">226,228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last-aria" datatype="html">
+ <source>Last</source>
+ <target>Último</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.progressbar.value" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="; } /** *"/></source>
+ <target><x id="INTERPOLATION" equiv-text="; } /** *"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/progressbar/progressbar.ts</context>
+ <context context-type="linenumber">32,38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.HH" datatype="html">
+ <source>HH</source>
+ <target>HH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">40,41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.hours" datatype="html">
+ <source>Hours</source>
+ <target>Horas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.MM" datatype="html">
+ <source>MM</source>
+ <target>MM</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">51,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.minutes" datatype="html">
+ <source>Minutes</source>
+ <target>Minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-hours" datatype="html">
+ <source>Increment hours</source>
+ <target>Añadir horas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">63,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-hours" datatype="html">
+ <source>Decrement hours</source>
+ <target>Eliminar horas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">69,70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-minutes" datatype="html">
+ <source>Increment minutes</source>
+ <target>Añadir minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">76,78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-minutes" datatype="html">
+ <source>Decrement minutes</source>
+ <target>Eliminar minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">82,84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.SS" datatype="html">
+ <source>SS</source>
+ <target>SS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.seconds" datatype="html">
+ <source>Seconds</source>
+ <target>Segundos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">92,93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-seconds" datatype="html">
+ <source>Increment seconds</source>
+ <target>Añadir segundos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">100,101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-seconds" datatype="html">
+ <source>Decrement seconds</source>
+ <target>Eliminar segundos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">106,110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.AM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></source>
+ <target><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">115,121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.PM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="t() meridian: b"/></source>
+ <target><x id="INTERPOLATION" equiv-text="t() meridian: b"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">123,131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.toast.close-aria" datatype="html">
+ <source>Close</source>
+ <target>Cerrar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/toast/toast.ts</context>
+ <context context-type="linenumber">78,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8835b9e49a3348b0a2f2162c21118af1f4bee45a" datatype="html">
+ <source>Must be greater than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>.</source>
+ <target>Debe ser mayor o igual que <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbddac59563c8c126e3fe28691e4e247614fcbd1" datatype="html">
+ <source>Must be less than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>.</source>
+ <target>Debe ser menor o igual que <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5" datatype="html">
+ <source>Overview</source>
+ <target>Resumen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbd2045d5c37e4bb39a3c0fb62ea1ddf70a12838" datatype="html">
+ <source>Targets</source>
+ <target>Destinos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a674ab267d1934bf395f87ca1503fd474296893f" datatype="html">
+ <source>iSCSI Topology</source>
+ <target>Topología iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8953033926734869941" datatype="html">
+ <source>Name</source>
+ <target>Nombre</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6603000223840533819" datatype="html">
+ <source>Current</source>
+ <target>Actual</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5607669932062416162" datatype="html">
+ <source>Default</source>
+ <target>Opción por defecto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6803e31b7395d94934e091a49a9524026b59b018" datatype="html">
+ <source>Discovery Authentication</source>
+ <target>Autenticación de descubrimiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e08a77594f3d89311cdf6da5090044270909c194" datatype="html">
+ <source>User</source>
+ <target>Usuario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">381</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7cbdabcece469fab89cfa687ab152bca18b97498" datatype="html">
+ <source>This field is required.</source>
+ <target>Este campo es obligatorio.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">368</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">423</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">481</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">291</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">343</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">407</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">490</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">516</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">556</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">573</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">590</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">647</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">672</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">299</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">195</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">520</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">614</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">651</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f717bad2da5944a2567a52f971ccc6806db85805" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>Los nombres de usuario deben tener una longitud de entre 8 y 64 caracteres y puede incluir letras, números y los caracteres: &quot;.&quot;, &quot;,&quot;, &quot;@&quot;, &quot;-&quot;, &quot;_&quot; o &quot;:&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">28,29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">85,86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c32ef07f8803a223a83ed17024b38e8d82292407" datatype="html">
+ <source>Password</source>
+ <target>Contraseña</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">403</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">581</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="001e1836299d8d3b84eaebe2fa051325beab3f00" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>Las contraseñas deben tener una longitud de entre 12 y 16 caracteres y pueden incluir letras, números y los caracteres: &quot;@&quot;, &quot;-&quot;, &quot;_&quot; o &quot;/&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">61,62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">118,119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff40391de7a1944ea95091e4045cc34c4979b736" datatype="html">
+ <source>Mutual User</source>
+ <target>Usuario mutuo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cf73dbebe99b737c4d288788182fc356e3c93d3" datatype="html">
+ <source>Mutual Password</source>
+ <target>Contraseña mutua</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594987303599690088" datatype="html">
+ <source>Updated discovery authentication</source>
+ <target>Autenticación de descubrimiento actualizada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb127ea03835b3230f0ed981c7080e2ccb879621" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <note priority="1" from="description">form title</note>
+ </trans-unit>
+ <trans-unit id="1406c2fb12a20c1528b19bcc5e24a6a2386167f3" datatype="html">
+ <source>Target IQN</source>
+ <target>IQN de destino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5fe42339be910372fa689f559155631862d218e8" datatype="html">
+ <source>IQN has wrong pattern.</source>
+ <target>El IQN tiene un patrón erróneo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="050a7ff057d1e895357540406b6be5652b4d1c71" datatype="html">
+ <source>An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'</source>
+ <target>Los IQN tienen esta notación: iqn.$year-$month.$reversedAddress:$definedName</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8ada4b53396d8366db00a435acc61d53d857047" datatype="html">
+ <source>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</source>
+ <target>Por ejemplo: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e" datatype="html">
+ <source>More information</source>
+ <target>Más información</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9b1aa85dfc6849196e64060db02c5410de69b7a1" datatype="html">
+ <source>This target has modified advanced settings.</source>
+ <target>Este destino tiene ajustes avanzados modificados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6990ad8d6182662e864495ac31c3758cda1c7a28" datatype="html">
+ <source>Portals</source>
+ <target>Portales</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a3ac2b4137d723fd9878cd357c2012ff6c07973" datatype="html">
+ <source>Add portal</source>
+ <target>Añadir portal</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3638c01b6c34066438909713ec96087c813fc7e" datatype="html">
+ <source>At least <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> gateways are required.</source>
+ <target>Se necesitan al menos <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> puertas de enlace.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b73f7f5060fb22a1e9ec462b1bb02493fa3ab866" datatype="html">
+ <source>Images</source>
+ <target>Imágenes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">495</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">629</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9aff25be088f0efe3eaaf62edf2bff41cc41a617" datatype="html">
+ <source>Backstore: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </source>
+ <target>Almacén: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e3484cae8b118c576ca2815bf9c9406c2eb2cae3" datatype="html">
+ <source>This image has modified settings.</source>
+ <target>Esta imagen tiene ajustes modificados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1dff11e0820b6722ab240169f1232d70a54beaaa" datatype="html">
+ <source>Duplicated LUN numbers.</source>
+ <target>Números de LUN duplicados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bf2dccf92ccff6e3b091792bf4205595406e1bfb" datatype="html">
+ <source>Duplicated WWN.</source>
+ <target>WWN duplicado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="808038f912fdc7f0e03f82d4afd3bf9178527fc8" datatype="html">
+ <source>Add image</source>
+ <target>Añadir imagen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">656</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66c5fb27f52e75b70ca4b670b9b15a2a51cf9543" datatype="html">
+ <source>ACL authentication</source>
+ <target>Autenticación de ACL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="137fbf154ecad4d580354db0858b76faea7e4686" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>Los nombres de usuario deben tener una longitud de entre 8 y 64 caracteres y puede incluir letras, números y los caracteres: &quot;.&quot;, &quot;@&quot;, &quot;-&quot;, &quot;_&quot; o &quot;:&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">227,228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">287,288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="361771c32dd2254d77fd3fbf006b008983fe5907" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>Las contraseñas deben tener una longitud de entre 12 y 16 caracteres y pueden incluir letras, números y los caracteres: &quot;@&quot;, &quot;-&quot;, &quot;_&quot; o &quot;/&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">262,263</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">323,324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f494bd31f095f6dcc656ce87ec2dcf07a2e9b30c" datatype="html">
+ <source>Initiators</source>
+ <target>Iniciadores</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">335</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">588</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e98239d8a6be1100119ff4b5630c822b82786740" datatype="html">
+ <source>Initiator</source>
+ <target>Iniciador</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2c5059d8cda15d8d03e2cce30f2d139623d9a91" datatype="html">
+ <source>Client IQN</source>
+ <target>IQN del cliente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="107d5aabce23d900f0a80e6ddc1c10e29aa0bed8" datatype="html">
+ <source>Initiator IQN needs to be unique.</source>
+ <target>El IQN del iniciador debe ser exclusivo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e7cad911fa524e512d9744b16358b7ee6791385" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>Los nombres de usuario deben tener una longitud de entre 8 y 64 caracteres y puede incluir letras, números y los caracteres: &quot;.&quot;, &quot;@&quot;, &quot;-&quot;, &quot;_&quot; o &quot;:&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">394,395</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">452,453</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7f2c186d181206d0d2b1ff74819081a010f10bf" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>Las contraseñas deben tener una longitud de entre 12 y 16 caracteres y pueden incluir letras, números y los caracteres: &quot;@&quot;, &quot;-&quot;, &quot;_&quot; o &quot;/&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">427,428</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">485,486</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d1878d5fc761cbe9614bfd87047a740c82a6951" datatype="html">
+ <source>Initiator belongs to a group. Images will be configure in the group.</source>
+ <target>El iniciador pertenece a un grupo. Las imágenes se configurarán en el grupo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">515</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0de67b9d97fafbf200f9451e8388ee8128a56ac" datatype="html">
+ <source>No items added.</source>
+ <target>No se ha añadido ningún elemento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">671</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d565e47726158e428ecdc952fc9233b9b7d7f049" datatype="html">
+ <source>Add initiator</source>
+ <target>Añadir iniciador</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">616</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c22ba03540aa3217da059f45e7eab138b51a96e2" datatype="html">
+ <source>Groups</source>
+ <target>Grupos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c90059afafb7e160384d9f512797c95bb95c6dc" datatype="html">
+ <source>Group</source>
+ <target>Grupo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cff1428d10d59d14e45edec3c735a27b5482db59" datatype="html">
+ <source>Name</source>
+ <target>Nombre</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">576</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3084948274cff4f56d0f431af47240e9cf02fcc7" datatype="html">
+ <source>Add group</source>
+ <target>Añadir grupo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">676</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6634268061646442252" datatype="html">
+ <source>There are no portals available.</source>
+ <target>No hay ningún portal disponible.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4587015892789840153" datatype="html">
+ <source>There are no images available.</source>
+ <target>No hay ninguna imagen disponible.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7896905042057267575" datatype="html">
+ <source>There are no images available. Please make sure you add an image to the target.</source>
+ <target>No hay ninguna imagen disponible. Asegúrese de añadir una imagen al destino.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6765423558085969805" datatype="html">
+ <source>There are no initiators available. Please make sure you add an initiator to the target.</source>
+ <target>No hay ningún iniciador disponible. Asegúrese de añadir un iniciador al destino.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2539932200265667453" datatype="html">
+ <source>target</source>
+ <target>destino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="051dcc342cfa5c1eaf187a2001aaa162379a160c" datatype="html">
+ <source>Configure</source>
+ <target>Configurar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e515f954730279c31d5301f02479666d6264e8b" datatype="html">
+ <source>Changing these parameters from their default values is usually not necessary.</source>
+ <target>Normalmente no es necesario cambiar los valores por defecto de estos parámetros.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e2591df099ddac796cda401c5f282da779d45f2" datatype="html">
+ <source>Identifier</source>
+ <target>Identificador</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62480a4859976427cf18fc8ef41d3a438eda0412" datatype="html">
+ <source>lun</source>
+ <target>lun</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8afc9eb4405e0aa554b2ba14140ef790cdecc040" datatype="html">
+ <source>wwn</source>
+ <target>wwn</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
+ <source>Settings</source>
+ <target>Ajustes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69a47cbabcc51ca942606e1d8da0ec11f98a2690" datatype="html">
+ <source>Backstore</source>
+ <target>Almacén</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="339878da255ab55447c43afef8d9b2f9753bf5f6" datatype="html">
+ <source>Advanced Settings</source>
+ <target>Ajustes avanzados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="332227f088a4877b3c11f5fb3ae8bc812c470fae" datatype="html">
+ <source>iSCSI Targets not available</source>
+ <target>Destinos iSCSI no disponibles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7fba666f1fff0182e570f12133fb3d622d9ea6" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the iSCSI Targets management functionality.</source>
+ <target>Consulte <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> para obtener información sobre cómo configurar y habilitar la función de gestión de destinos iSCSI.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3b301d0044f62c92af0da53d7aaca52a436a547d" datatype="html">
+ <source>Available information:</source>
+ <target>Información disponible:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8414a5cb9d71cc1b21b10e4a9d1f2dad558f3361" datatype="html">
+ <source>Discovery authentication</source>
+ <target>Autenticación de descubrimiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4854396465510517671" datatype="html">
+ <source>Target</source>
+ <target>Destino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4093869278527257288" datatype="html">
+ <source>Portals</source>
+ <target>Portales</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="414887388288176527" datatype="html">
+ <source>Images</source>
+ <target>Imágenes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="798573158169239055" datatype="html">
+ <source># Sessions</source>
+ <target>N.º de sesiones</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="646929398175374220" datatype="html">
+ <source>Unavailable gateway(s)</source>
+ <target>Puertas de enlace no disponibles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2350612272163013640" datatype="html">
+ <source>Target has active sessions</source>
+ <target>El destino tiene sesiones activas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4782410538666829801" datatype="html">
+ <source>iSCSI target</source>
+ <target>Destino iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">227</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8a9910cd114c1deb9af74f6f99b4173403965bf2" datatype="html">
+ <source>Gateways</source>
+ <target>Puertas de enlace</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911214550882917183" datatype="html">
+ <source>State</source>
+ <target>Estado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4121862424558610140" datatype="html">
+ <source># Targets</source>
+ <target>N.º de destinos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101197021456818771" datatype="html">
+ <source>Pool</source>
+ <target>Repositorio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3012906865384504293" datatype="html">
+ <source>Image</source>
+ <target>Imagen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2699995524827665158" datatype="html">
+ <source>Backstore</source>
+ <target>Almacén</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3559214740809905405" datatype="html">
+ <source>Read Bytes</source>
+ <target>Bytes de lectura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1580583760095064067" datatype="html">
+ <source>Write Bytes</source>
+ <target>Bytes de escritura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7225917547116479918" datatype="html">
+ <source>Read Ops</source>
+ <target>Operaciones de lectura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6417507714454914481" datatype="html">
+ <source>Write Ops</source>
+ <target>Operaciones de escritura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="257147267065394003" datatype="html">
+ <source>A/O Since</source>
+ <target>A/O desde</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ecbc084370a732fc3cde1966a60af78d71424ab4" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>Crear testigo de arranque</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603e9cc3ef2aab57f2b0a00e465b23b9cabefd9c" datatype="html">
+ <source>To create a bootstrap token which can be imported by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Generate<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Para crear un testigo de arranque que un clúster de sitio de pares pueda importar, proporcione el nombre del sitio local, seleccione los repositorios en los que la duplicación estará habilitada y haga clic en <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Generar<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="660f97cd3188f8a04bd03b79e703fec72c6df04c" datatype="html">
+ <source>Site Name</source>
+ <target>Nombre del sitio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2fecea01ce1d44114ee45144eff6d47a5016a74f" datatype="html">
+ <source>Name...</source>
+ <target>Nombre...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92899fa68e8ca108912163ff58edc8540e453787" datatype="html">
+ <source>Pools</source>
+ <target>Repositorios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c2a1dc72cffaf7ab3dc5599bf77b0a7fcad2b20" datatype="html">
+ <source>At least one pool is required.</source>
+ <target>Se necesita al menos un repositorio.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b258b258b4cc475ceb2871305b61756b0134f4a" datatype="html">
+ <source>Generate</source>
+ <target>Generar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1edc1fc6cfbbb22353050ad6788508b3ed584f53" datatype="html">
+ <source>Token</source>
+ <target>Testigo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff785f5596aef34a93b9b4d1023e95c62eef5740" datatype="html">
+ <source>Generated token...</source>
+ <target>Testigo generado...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8" datatype="html">
+ <source>Close</source>
+ <target>Cerrar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5467a6bb0e7fade6def7499400d5e2a7d8d3da20" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>Importar testigo de arranque</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bb7aee0dec5164f45c0aa2f35f2fb2149d2c1d2" datatype="html">
+ <source>To import a bootstrap token which was created by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, provide the generated token, and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Import<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Para importar un testigo de arranque que haya creado un clúster de sitio de pares, proporcione el nombre del sitio local, seleccione los repositorios en los que la duplicación estará habilitada, proporcione el testigo generado y haga clic en <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Importar<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9200e09686136a1d42adfb89c12fbfef2deea125" datatype="html">
+ <source>Direction</source>
+ <target>Dirección</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9761484679958da8d12841a4efa5964d33fae575" datatype="html">
+ <source>The token is invalid.</source>
+ <target>El testigo no es válido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2381859602529023966" datatype="html">
+ <source>Instance</source>
+ <target>Instancia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8040881171107393560" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1605455101862010019" datatype="html">
+ <source>Hostname</source>
+ <target>Nombre de host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2724055831234181057" datatype="html">
+ <source>Version</source>
+ <target>Versión</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2041675390931385838" datatype="html">
+ <source>Health</source>
+ <target>Estado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87bd96249f8afc23f5301cddb57b1464a98e71a" datatype="html">
+ <source>Edit site name</source>
+ <target>Editar nombre del sitio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cfff72c667274c12eb1ff71eadc25871c10c42dc" datatype="html">
+ <source>Edit the site name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Edite el nombre del sitio y haga clic en <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Actualizar<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">13,14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66db799d67958d4b0765181d072df62e2d1c16f5" datatype="html">
+ <source>Issues</source>
+ <target>Problemas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef06d69259e587e28d52372455f44c7153cda7e7" datatype="html">
+ <source>Syncing</source>
+ <target>Sincronizando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0b0901877d837d3fda16ba161eb74368d1c75b7a" datatype="html">
+ <source>Ready</source>
+ <target>Listo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5833626790712999947" datatype="html">
+ <source>Issue</source>
+ <target>Problema</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3419681791450150574" datatype="html">
+ <source>Progress</source>
+ <target>Progreso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4902817035128594900" datatype="html">
+ <source>Description</source>
+ <target>Descripción</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40b7acea5b43f45e0bbd1efeba5200af4687981d" datatype="html">
+ <source>Site Name:</source>
+ <target>Nombre del sitio:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e24f9e2d42104ffc01599db4d566d1cc518f9e6" datatype="html">
+ <source>Daemons</source>
+ <target>Daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6450386891540681425" datatype="html">
+ <source>Edit Site Name</source>
+ <target>Editar nombre del sitio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4645993115976933405" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>Crear testigo de arranque</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4130053543590533787" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>Importar testigo de arranque</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4057c56d63a7e9b140b1d01871a9229a5f30eb27" datatype="html">
+ <source>Edit pool mirror mode</source>
+ <target>Editar modo de duplicación de repositorio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e1f367f5feaab38f6637dd1f967c848b447dea2d" datatype="html">
+ <source>To edit the mirror mode for pool  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, select a new mode from the list and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Para editar el modo de duplicación del repositorio <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, seleccione un modo nuevo en la lista y haga clic en <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Actualizar<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37e10df2d9c0c25ef04ac112c9c9a7723e8efae0" datatype="html">
+ <source>Mode</source>
+ <target>Modo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">426</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32ca348ef926b0a6a7a780b8b64c3a8239895cec" datatype="html">
+ <source>Peer clusters must be removed prior to disabling mirror.</source>
+ <target>Los clústeres de par deben eliminarse antes de inhabilitar la duplicación.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5769292297914455214" datatype="html">
+ <source>Disabled</source>
+ <target>Inhabilitado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ddcb416c1c0aa1f54acf5beef1de81813e76fa6" datatype="html">
+ <source>{VAR_SELECT, select, edit {Edit} other {Add}}</source>
+ <target>{VAR_SELECT, select, edit {Editar} other {Añadir}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3aa7c3a4f7b0cf7c2e60fc71ea1e3b4c3efa3558" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> pool mirror peer</source>
+ <target><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> par de duplicación del repositorio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="59ca65ece457429d90104ede4674965f62edbabe" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> the pool mirror peer attributes for pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Submit<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> los atributos del par de duplicación del repositorio para el repositorio <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> y haga clic en <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Enviar<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d3cc964811f852a168f4a2d5daa59068abc5cf53" datatype="html">
+ <source>Cluster Name</source>
+ <target>Nombre del clúster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b631721fc56cb7fb1cbd07b802a487c5753f6a2d" datatype="html">
+ <source>The cluster name is not valid.</source>
+ <target>El nombre del clúster no es válido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca6deafa31bf421f85094807982aee4bcb20a3ae" datatype="html">
+ <source>CephX ID</source>
+ <target>ID de CephX</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7539188a568c3d553cbde1bacaf32310c4264e24" datatype="html">
+ <source>CephX ID...</source>
+ <target>ID de CephX...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1c45b594b0fba22fc64e80c793a7ffe005fdb0e" datatype="html">
+ <source>The CephX ID is not valid.</source>
+ <target>El ID de CephX no es válido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20861576fcfce773c918c782cd4f5adf32382921" datatype="html">
+ <source>Monitor Addresses</source>
+ <target>Direcciones de monitores</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fa28eeed2b4bd4ccbe6e9349a1c2b3cb1c5de70a" datatype="html">
+ <source>Comma-delimited addresses...</source>
+ <target>Direcciones delimitadas por comas...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dc016c82fd85848d5c1b2fd0e8469ee2027d9c16" datatype="html">
+ <source>The monitory address is not valid.</source>
+ <target>La dirección del monitor no es válida.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0ac55b83dc6739e62bc655cfe375b67c93e7f4a" datatype="html">
+ <source>CephX Key</source>
+ <target>Clave de CephX</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f53434bcb95bd86f1df9c8e22966f757614fc4ad" datatype="html">
+ <source>Base64-encoded key...</source>
+ <target>Clave con cifrado base64...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4cd83164cd4f66b4abc2863f9ce6f599d789e4ca" datatype="html">
+ <source>CephX key must be base64 encoded.</source>
+ <target>La clave de CephX debe tener cifrado base64</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6407712033679505505" datatype="html">
+ <source>Edit Mode</source>
+ <target>Editar modo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054237897979907103" datatype="html">
+ <source>Add Peer</source>
+ <target>Añadir par</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="899134641637789371" datatype="html">
+ <source>Edit Peer</source>
+ <target>Editar par</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7393680121674824053" datatype="html">
+ <source>Delete Peer</source>
+ <target>Suprimir par</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1713271461473302108" datatype="html">
+ <source>Mode</source>
+ <target>Modo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1061297288634362831" datatype="html">
+ <source>Leader</source>
+ <target>Líder</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8517494870558773093" datatype="html">
+ <source># Local</source>
+ <target>N.º locales</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4953753699491987394" datatype="html">
+ <source># Remote</source>
+ <target>N.º remotos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1715982232168082172" datatype="html">
+ <source>mirror peer</source>
+ <target>duplicar par</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff92fbdec9fdd5054493eeda0d7ee8b450f83e72" datatype="html">
+ <source>RBD Configuration</source>
+ <target>Configuración de RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b62d9efc8eb3b589904f6cb96a0406bbda55673a" datatype="html">
+ <source>Remove the local configuration value. The parent configuration value will be inherited and used instead.</source>
+ <target>Elimina el valor de configuración local. Se heredará y usará en su lugar el valor de configuración padre.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80d769fd863fe44fab689636a078466bfdbd1f20" datatype="html">
+ <source>The minimum value is 0</source>
+ <target>El valor mínimo es 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5decb3917d46a9ac6e5813699801becb7c3c1455" datatype="html">
+ <source>Global</source>
+ <target>Global</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f9ba9bb9faa8284bcadb1cdbc6aaf969e9c4bb" datatype="html">
+ <source>Image</source>
+ <target>Imagen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70fcca5a99575cffef3ff8cbd5e69f06ffd0f1c" datatype="html">
+ <source>Pool</source>
+ <target>Repositorio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176659033176029418" datatype="html">
+ <source>Key</source>
+ <target>Clave</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9155608366859514313" datatype="html">
+ <source>Source</source>
+ <target>Origen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6555318547274416232" datatype="html">
+ <source>Value</source>
+ <target>Valor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f6e8f6094b180eaf1f11bc0ffe383f1cdcd059e" datatype="html">
+ <source>Only available for RBD images with <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> enabled</source>
+ <target>Solo disponible para imágenes RBD con <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> habilitado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f8b2bb476981727ab34ed40fde1218361f92c45" datatype="html">
+ <source>Details</source>
+ <target>Detalles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03cc5b14b0a20d075e9009ff021f4f1660ba348a" datatype="html">
+ <source>Data Pool</source>
+ <target>Repositorio de datos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b051734b0ee9021991c91b3ed4e81c244322462" datatype="html">
+ <source>Created</source>
+ <target>Creados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7faaaa08f56427999f3be41df1093ce4089bbd75" datatype="html">
+ <source>Size</source>
+ <target>Tamaño</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="afdb601c16162f2c798b16a2920955f1cc6a20aa" datatype="html">
+ <source>Objects</source>
+ <target>Objetos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ceac8e132384322ec778ba760875a6c6897d3e42" datatype="html">
+ <source>Object size</source>
+ <target>Tamaño del objeto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cdb1fea93d77c07950c0c76c6e0ad79ebbef084" datatype="html">
+ <source>Features</source>
+ <target>Características</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65771c9a73b9aa609d592fc96a64801a8f40bd" datatype="html">
+ <source>Provisioned</source>
+ <target>Aprovisionados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84a36cb75660b736773fe36ffa3d54f0f0fe363e" datatype="html">
+ <source>N/A</source>
+ <target>N/D</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c009342a4e8381f64341d0bb61c2e4685f5a4b" datatype="html">
+ <source>Total provisioned</source>
+ <target>Total aprovisionado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f6bf8a43ae415f527ac961ea62471b983aaa97b" datatype="html">
+ <source>Striping unit</source>
+ <target>Unidad de repartición</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db710e8a8f011923f2d15d713fbae49c38b02b26" datatype="html">
+ <source>Striping count</source>
+ <target>Recuento de repartición</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a4c2a9e76634ff14a60d52a718296f722d47c67" datatype="html">
+ <source>Parent</source>
+ <target>Padre</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a209e68d78ffc2cc9c53d2e76158624efab71ad" datatype="html">
+ <source>Block name prefix</source>
+ <target>Prefijo de nombre de bloque</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5704ec2049d007c5f5fb495a5d8b607e68d58081" datatype="html">
+ <source>Order</source>
+ <target>Orden</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="984cb6ad70f150a401b4daf841bd3cd957412699" datatype="html">
+ <source>Format Version</source>
+ <target>Versión de formato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f21b1d17b6c5042bb5805516eee37fde33739dd8" datatype="html">
+ <source>Snapshots</source>
+ <target>Instantáneas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4a41f824a35ba01d5bd7be61aa06b3e8145209d0" datatype="html">
+ <source>Configuration</source>
+ <target>Configuración</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3cc9c2ae277393b3946b38c088dabff671b1ee1b" datatype="html">
+ <source>Performance</source>
+ <target>Rendimiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935bb9cb0e4340fc74d33caa3b70d9d143fcad87" datatype="html">
+ <source>Information can not be displayed for RBD in status 'Removing'.</source>
+ <target>No se puede mostrar la información para el RBD con el estado Eliminando. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58e58f1a8786da9031a05e6770c5dafce82badf5" datatype="html">
+ <source>This setting overrides the global value</source>
+ <target>Este ajuste sustituye al valor global</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36b46714164964c6258b08ed0a25f57d8a950f92" datatype="html">
+ <source>This is the global value. No value for this option has been set for this image.</source>
+ <target>Este es el valor global. No se ha definido ningún valor para esta opción para esta imagen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6547c9c4d5f62942ac4b1fe459cf9a03d4dbf5a0" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> from</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> de</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0e9ecf29a4fa5b057bd8052e0d801b3fde6a30bf" datatype="html">
+ <source>'/' and '@' are not allowed.</source>
+ <target>No se permiten los caracteres &quot;/&quot; ni &quot;@&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="94516fa213706c67ce5a5b5765681d7fb032033a" datatype="html">
+ <source>Loading...</source>
+ <target>Cargando...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">209</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">452</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b99417c4dd46286ffd37c8d2e987c8b512ec7052" datatype="html">
+ <source>-- No rbd pools available --</source>
+ <target>-- No hay ningún repositorio RBD disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef83ec9c304a89d45650e580dcdc2978c37b3a83" datatype="html">
+ <source>-- Select a pool --</source>
+ <target>-- Seleccione un repositorio --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d649904466254d13df1fbf2d255f0bbc6553d213" datatype="html">
+ <source>-- No namespaces available --</source>
+ <target>-- No hay ningún espacio de nombres disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e22d7bb4d2d561e0832ee0b9a3da2468a080c4f0" datatype="html">
+ <source>-- Select a namespace --</source>
+ <target>-- Seleccione un espacio de nombres --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49449943d8cbf59d8c401c8bd2e76f92e207cc5f" datatype="html">
+ <source>Use a dedicated data pool</source>
+ <target>Usar un repositorio dedicado para datos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa5b3c5ea5af14d09b2eb098039af9f1f77be010" datatype="html">
+ <source>You need more than one pool with the rbd application label use to use a dedicated data pool.</source>
+ <target>Necesita más de un repositorio con la etiqueta de aplicación RBD para usar un repositorio de datos dedicado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="870aee0dd31a9643bf62007beb8f1ae1deb34d42" datatype="html">
+ <source>Data pool</source>
+ <target>Repositorio de datos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3792ca829d9b9f687e1f5d7733d30e9bb0bfec47" datatype="html">
+ <source>Dedicated pool that stores the object-data of the RBD.</source>
+ <target>Repositorio dedicado para almacenar los datos de objeto de RBD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151c80ea931037cd92e854442927f8a0f6ae7795" datatype="html">
+ <source>-- No data pools available --</source>
+ <target>-- No hay ningún repositorio de datos disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0016bd458baa88284a658ce9eeda42d8ad88d2c" datatype="html">
+ <source>e.g., 10GiB</source>
+ <target>ej.: 10 GiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">206</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a88bbee20570aaf9615332fb27020627044874d" datatype="html">
+ <source>You have to increase the size.</source>
+ <target>Debe aumentar el tamaño.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cfe07dac5b4ee1c464eb24225ddeb4f1d24076a" datatype="html">
+ <source>Advanced...</source>
+ <target>Avanzado...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bc2e854e111ecf2bd7db170da5e3c2ed08181d88" datatype="html">
+ <source>Advanced</source>
+ <target>Avanzado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3562a3778695a5f9c0445660e35301f0a39aaf73" datatype="html">
+ <source>Striping</source>
+ <target>Repartición</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef3c3f3b5f562a5cdbe0ee2874287db1534b5958" datatype="html">
+ <source>Stripe unit</source>
+ <target>Unidad de repartición</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84471be1049006edecbcaef1a32ae0893c229c50" datatype="html">
+ <source>-- Select stripe unit --</source>
+ <target>-- Seleccione la unidad de repartición --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">289</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d32c5c54c8581c774a7f467fbd4e329b15a74fa" datatype="html">
+ <source>This field is required because stripe count is defined!</source>
+ <target>Este campo es obligatorio porque se ha definido el recuento de repartición.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bbf9040be7c5491d4a03f2185708f43a6582a3b" datatype="html">
+ <source>Stripe unit is greater than object size.</source>
+ <target>La unidad de repartición es mayor que el tamaño del objeto.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a682f49f9b761591661276d7c6f550e641a130a4" datatype="html">
+ <source>Stripe count</source>
+ <target>Recuento de repartición</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="baa74031990c5370008ba622d0a250f0929097f4" datatype="html">
+ <source>This field is required because stripe unit is defined!</source>
+ <target>Este campo es obligatorio porque se ha definido la unidad de repartición.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cd2ada6d5ecbd5cbf89eae0a1f5326efedac0dbc" datatype="html">
+ <source>Stripe count must be greater than 0.</source>
+ <target>El recuento de repartición debe ser mayor que 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4341718109173132593" datatype="html">
+ <source>RBD</source>
+ <target>RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1359455778569887786" datatype="html">
+ <source>Deep flatten</source>
+ <target>Aplanamiento profundo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58519213655664125" datatype="html">
+ <source>Layering</source>
+ <target>En capas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844531889615887801" datatype="html">
+ <source>Exclusive lock</source>
+ <target>Bloqueo exclusivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4585281635594103106" datatype="html">
+ <source>Object map (requires exclusive-lock)</source>
+ <target>Mapa de objetos (requiere bloqueo exclusivo)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240933649452133654" datatype="html">
+ <source>Journaling (requires exclusive-lock)</source>
+ <target>En diario (requiere bloqueo exclusivo)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3713046526850391848" datatype="html">
+ <source>Fast diff (interlocked with object-map)</source>
+ <target>Diferencias rápidas (interbloqueo con mapa de objetos)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19f1e825536efbf7492723a7c2d01ad23a4e994b" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1774b9915b0e302d02cad0b9321ad5f1a83247a8" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c9f1026c1235f4d76ace47449e806efd181ab332" datatype="html">
+ <source>Deleting this image will also delete all its snapshots.</source>
+ <target>Si se suprime esta imagen, también se suprimirán todas sus instantáneas.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55f864597e84d9bf88769e1fbfda1d64452430c9" datatype="html">
+ <source>The following snapshots are currently protected and will be removed:</source>
+ <target>Las instantáneas siguientes están protegidas actualmente y se eliminarán:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2e362ec498c4c9112dc47a3cb7d7250ca8e71790" datatype="html">
+ <source>RBD in status 'Removing'</source>
+ <target>RBD con el estado Eliminando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3294686077659093992" datatype="html">
+ <source>Namespace</source>
+ <target>Espacio de nombres</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45739481977493163" datatype="html">
+ <source>Size</source>
+ <target>Tamaño</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7531602241051125940" datatype="html">
+ <source>Objects</source>
+ <target>Objetos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1194977199378511591" datatype="html">
+ <source>Object size</source>
+ <target>Tamaño del objeto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">226</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="178418048502923560" datatype="html">
+ <source>Provisioned</source>
+ <target>Aprovisionados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7638291694671392137" datatype="html">
+ <source>Total provisioned</source>
+ <target>Total aprovisionado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8621797738551294959" datatype="html">
+ <source>Parent</source>
+ <target>Padre</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616639680594151867" datatype="html">
+ <source>This RBD has cloned snapshots. Please delete related RBDs before deleting this RBD.</source>
+ <target>Este RBD tiene instantáneas clonadas. Suprima los RBD relacionados antes de suprimir este RBD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2900827028308925059" datatype="html">
+ <source>This RBD image has an invalid name and can't be managed by ceph.</source>
+ <target>Esta imagen RBD tiene un nombre no válido y no se puede gestionar con ceph.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1796389652493657142" datatype="html">
+ <source>Action not possible for an RBD in status 'Removing'</source>
+ <target>Acción no disponible para un RBD con el estado Eliminando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">476</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c07d24bb422aa8e5e568df1c5709083f0a9c8f1" datatype="html">
+ <source>Create Namespace</source>
+ <target>Crear espacio de nombres</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cca6c0485f96d3a9610d0339cb1275a5f2c3f46" datatype="html">
+ <source>Namespace already exists.</source>
+ <target>El espacio de nombres ya existe.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4641528557519966449" datatype="html">
+ <source>Created namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <target>Espacio de nombres <x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/> creado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6809428596104996786" datatype="html">
+ <source>Total images</source>
+ <target>Número total de imágenes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1346311774128536550" datatype="html">
+ <source>Deleted namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <target>Espacio de nombres <x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/> suprimido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7605466414392298530" datatype="html">
+ <source>Namespace contains images</source>
+ <target>El espacio de nombres contiene imágenes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576483965711201552" datatype="html">
+ <source>RBD Snapshot</source>
+ <target>Instantánea de RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3473055924346204357" datatype="html">
+ <source>Parent image must support Layering</source>
+ <target>La imagen padre debe admite la disposición en capas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1152535233999495900" datatype="html">
+ <source>Snapshot must be protected in order to clone.</source>
+ <target>Para poder clonarse, la instantánea debe estar protegida.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c5331983af566d4ac6a1024d15a3511786a4aa6" datatype="html">
+ <source>You are about to rollback</source>
+ <target>Se dispone a revertir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6240400332778072187" datatype="html">
+ <source>PROTECTED</source>
+ <target>CON PROTECCIÓN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9101667614062185213" datatype="html">
+ <source>UNPROTECTED</source>
+ <target>SIN PROTECCIÓN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4207916966377787111" datatype="html">
+ <source>Created</source>
+ <target>Creados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587768621777516124" datatype="html">
+ <source>RBD snapshot rollback</source>
+ <target>Reversión de instantánea RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">305</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2711198699676132148" datatype="html">
+ <source>Rollback</source>
+ <target>Revertir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3330476395115957823" datatype="html">
+ <source>RBD snapshot</source>
+ <target>Instantánea RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">322</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3a7e364a88ea4673199dfa98bc73e6dbe09dfac" datatype="html">
+ <source>Namespaces</source>
+ <target>Espacios de nombres</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aba82bfd8e177d35b76cad7cd43941f8e5e5acac" datatype="html">
+ <source>Trash</source>
+ <target>Papelera</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5e7f4b1ca49e8d217bd0e12c6f7d6b6a2ade2c18" datatype="html">
+ <source>Overall Performance</source>
+ <target>Rendimiento general</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c0408946a6d67185947f455f15cc201d0d78e6" datatype="html">
+ <source>Purge Trash</source>
+ <target>Vaciar papelera</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c96a761dc55a21882c132c929583a424c9b8cf4" datatype="html">
+ <source>Expired at</source>
+ <target>Caducó a las</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="661041e3fcff4d3e75c561e038ca2504cf2cc643" datatype="html">
+ <source>Protected until</source>
+ <target>Protección hasta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee3b2322a1d3277f7e3fdb8a5141ac42bcf350b" datatype="html">
+ <source>This image is protected until <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</source>
+ <target>Esta imagen está protegida hasta el <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5611592591303869712" datatype="html">
+ <source>Status</source>
+ <target>Estado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">213</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">285</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2155633476201267204" datatype="html">
+ <source>Deleted At</source>
+ <target>Suprimido a las</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0b5d789d42c0e69348e5fe0037fcbf5b5fbbdcc" datatype="html">
+ <source>Move an image to trash</source>
+ <target>Mover una imagen a la papelera</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ad22c1d4aab3b8946603cea62de266d5129ca10" datatype="html">
+ <source>This image contains snapshot(s), which will prevent it from being removed after moved to trash.</source>
+ <target>Esta imagen contiene instantáneas, lo que impedirá que se elimine después de moverla a la papelera.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">15,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d4a5f5698bc8118b2e120b9bb72eff339094dd0" datatype="html">
+ <source>To move <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> to trash, click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Move<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Optionally, you can pick an expiration date.</source>
+ <target>Para mover <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> a la papelera, haga clic en <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Mover<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Opcionalmente, puede seleccionar una fecha de caducidad.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">19,20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f27d390844aad53b4240360e928156c5f0d326" datatype="html">
+ <source>Protection expires at</source>
+ <target>La protección caduca a las</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da166e9a0d27322f6ba8916d71ecc0f9905bb4b1" datatype="html">
+ <source>NOT PROTECTED</source>
+ <target>SIN PROTECCIÓN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1506e5f2ca22cad14502ec7a20fb6113ace145d" datatype="html">
+ <source>Wrong date format. Please use &quot;YYYY-MM-DD HH:mm:ss&quot;.</source>
+ <target>Formato de fecha erróneo. Use el formato &quot;AAAA-MM-DD HH:mm:ss&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa7ea0bb7495281e0b3258467ac7d90a1e44a1a1" datatype="html">
+ <source>Protection has already expired. Please pick a future date or leave it empty.</source>
+ <target>La protección ya ha caducado. Seleccione una fecha del futuro o deje el campo vacío.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d8613436532acac2b97d17de28b50f93e6bd0222" datatype="html">
+ <source>To purge, select  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>All<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>  or one pool and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Purge<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </source>
+ <target>Para limpiar, seleccione <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Todo<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> o seleccione un repositorio y haga clic en <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Limpiar<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55a4f598a4894b7fd5cb88f0ffd3c37ad009dd70" datatype="html">
+ <source>Pool:</source>
+ <target>Repositorio:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d43dd2b9f7797e4cf3a604695bb33e4479108516" datatype="html">
+ <source>Pool name...</source>
+ <target>Nombre del repositorio...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dfc3c34e182ea73c5d784ff7c8135f087992dac1" datatype="html">
+ <source>All</source>
+ <target>todos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0e7c7ed1d51a0c205c815048bc9f79e24ee6db2" datatype="html">
+ <source>Restore Image</source>
+ <target>Restaurar imágenes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3bc4aaf0dce75dc5e01ee5c825a652dc8aea8f0" datatype="html">
+ <source>To restore  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>,  type the image's new name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Restore<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Para restaurar <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, escriba el nombre nuevo de la imagen y haga clic en <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Restaurar<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41307dd56fea669eed72e12a6c23af275f6bfd82" datatype="html">
+ <source>New Name</source>
+ <target>Nombre nuevo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3625859417927520024" datatype="html">
+ <source>id</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6537904131139019667" datatype="html">
+ <source>type</source>
+ <target>tipo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8901220148451863928" datatype="html">
+ <source>state</source>
+ <target>estado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7925190601961269841" datatype="html">
+ <source>version</source>
+ <target>versión</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6641024648411549335" datatype="html">
+ <source>Host</source>
+ <target>Host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773272191572353800" datatype="html">
+ <source>root</source>
+ <target>raíz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6364513948635353490" datatype="html">
+ <source>Evicted client '<x id="PH" equiv-text="clientId"/>'</source>
+ <target>Cliente <x id="PH" equiv-text="clientId"/> expulsado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c1e17956453ad772dbe82d6946f62748c692f3e" datatype="html">
+ <source>Ranks</source>
+ <target>Clasificaciones</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b24e0b0b1629d2e8a51b9da7c75d6e6379f4bc4" datatype="html">
+ <source>Standbys</source>
+ <target>Reservas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="50df62325726db950523a5be1c78b8905fcc25d4" datatype="html">
+ <source>MDS performance counters</source>
+ <target>Contadores de rendimiento de MDS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4578796959376778578" datatype="html">
+ <source>Standby daemons</source>
+ <target>Daemons de reserva</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="665219418211496660" datatype="html">
+ <source>Rank</source>
+ <target>Clasificación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5445409664838149993" datatype="html">
+ <source>Daemon</source>
+ <target>Daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5306473977542913614" datatype="html">
+ <source>Activity</source>
+ <target>Actividad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3998441303515229547" datatype="html">
+ <source>Dentries</source>
+ <target>Dentries</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7877631502958415163" datatype="html">
+ <source>Inodes</source>
+ <target>Inodos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6129397096478256985" datatype="html">
+ <source>Dirs</source>
+ <target>Directorios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3011876564696453148" datatype="html">
+ <source>Caps</source>
+ <target>Capacidades</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8650499415827640724" datatype="html">
+ <source>Type</source>
+ <target>Tipo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="142654590491855672" datatype="html">
+ <source>Usage</source>
+ <target>Uso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">326</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb8293aa8161433778762ae025ffd5e7c85795e" datatype="html">
+ <source>Quotas</source>
+ <target>Cuotas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">540</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66785722678644243" datatype="html">
+ <source>Origin</source>
+ <target>Origen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8911059720204770105" datatype="html">
+ <source>Path</source>
+ <target>Ruta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6111756909052789805" datatype="html">
+ <source>Cannot create snapshots for files/folders in the subvolume <x id="PH" equiv-text="folders[2]"/></source>
+ <target>No es posible crear instantáneas para los archivos/carpetas del subvolumen <x id="PH" equiv-text="folders[2]"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7503263437025060215" datatype="html">
+ <source>Max size</source>
+ <target>Tamaño máximo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6763343019307619111" datatype="html">
+ <source>Max files</source>
+ <target>Número máximo de archivos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327403486214540377" datatype="html">
+ <source>The inherited <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> is the maximum value to be used.</source>
+ <target>El elemento <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> heredado es el valor máximo que se puede usar.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">434,437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3768927257183755959" datatype="html">
+ <source>Save</source>
+ <target>Guardar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">440</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6328794256834621774" datatype="html">
+ <source><x id="PH" equiv-text="action"/> CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> quota for '<x id="PH_2" equiv-text="path"/>'</source>
+ <target>Cuota <x id="PH_1" equiv-text="this.getQuotaName()"/> de <x id="PH" equiv-text="action"/> CephFS para <x id="PH_2" equiv-text="path"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">446</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9130352375983418123" datatype="html">
+ <source>size</source>
+ <target>tamaño</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6889473896134264260" datatype="html">
+ <source>files</source>
+ <target>archivos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2244434638607433133" datatype="html">
+ <source><x id="PH" equiv-text="this.getQuotaName()"/> quota <x id="PH_1" equiv-text="value"/> from '<x id="PH_2" equiv-text="path"/>'</source>
+ <target>Cuota <x id="PH" equiv-text="this.getQuotaName()"/> <x id="PH_1" equiv-text="value"/> de <x id="PH_2" equiv-text="path"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">460</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6960117167304061503" datatype="html">
+ <source>Value has to be at least 0 or more</source>
+ <target>El valor debe ser 0 o más como mínimo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">484</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6740501370117796629" datatype="html">
+ <source>Value has to be at most <x id="PH" equiv-text="maxValue"/> or less</source>
+ <target>El valor debe ser <x id="PH" equiv-text="maxValue"/> o menos como máximo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7239750919884229270" datatype="html">
+ <source>Updated</source>
+ <target>Actualizado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">499</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8885980874806414253" datatype="html">
+ <source>in order to inherit <x id="PH" equiv-text="quotaValue"/></source>
+ <target>para poder heredar <x id="PH" equiv-text="quotaValue"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4182949309891923991" datatype="html">
+ <source>which isn't used because of the inheritance of <x id="PH" equiv-text="quotaValue"/></source>
+ <target>que no se usa porque se hereda <x id="PH" equiv-text="quotaValue"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7421970649864638435" datatype="html">
+ <source>in order to have no quota on the directory</source>
+ <target>para no tener cuota en el directorio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6730229976797004508" datatype="html">
+ <source><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</source>
+ <target><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">530,533</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="827679535246546876" datatype="html">
+ <source>Create Snapshot</source>
+ <target>Crear instantánea</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">542</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">552</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4747656362969857823" datatype="html">
+ <source>Please enter the name of the snapshot.</source>
+ <target>Indique el nombre de la instantánea</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3667696812078358068" datatype="html">
+ <source>Created snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <target>Instantánea <x id="PH" equiv-text="name"/> creada para <x id="PH_1" equiv-text="path"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="753342836137587734" datatype="html">
+ <source>CephFs Snapshot</source>
+ <target>Instantánea de CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">670</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2774104291801979963" datatype="html">
+ <source>Deleted snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <target>Instantánea <x id="PH" equiv-text="name"/> suprimida para <x id="PH_1" equiv-text="path"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">683</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4816216590591222133" datatype="html">
+ <source>Enabled</source>
+ <target>Habilitado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ffe39df9d88c972792bd8688b215392deb8313d" datatype="html">
+ <source>Clients</source>
+ <target>Clientes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e213942c6354b9cbe7a650f0f1499bfc1000fb6" datatype="html">
+ <source>Directories</source>
+ <target>Directorios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fbbaf5cb02ed419e79a27072478f716a4666a99d" datatype="html">
+ <source>Performance Details</source>
+ <target>Detalles de rendimiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0" datatype="html">
+ <source>Description</source>
+ <target>Descripción</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ad112ce9bcd55dfd137792a86afe1b5a5b13cf8" datatype="html">
+ <source>Long description</source>
+ <target>Descripción larga</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="26fb5f81b3581f06b9210defb0e71dc69a67e819" datatype="html">
+ <source>Current values</source>
+ <target>Valores actuales</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7cee38a2259526c519f878e71b964f41db4348" datatype="html">
+ <source>Default</source>
+ <target>Opción por defecto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33e1c1d9fc05ca3f62fcc8a1170fc31ebae4229c" datatype="html">
+ <source>Daemon default</source>
+ <target>Daemon por defecto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f61c6867295f3b53d23557021f2f4e0aa1d0b8fc" datatype="html">
+ <source>Type</source>
+ <target>Tipo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9abcd7c82643d60c22733470463f74e4a54bc069" datatype="html">
+ <source>Min</source>
+ <target>Mín.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3ced4d162a0a55ee233a187ce7208ba5e922418" datatype="html">
+ <source>Max</source>
+ <target>Máx.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="920617c6a1a4805e53bcb5af6a9c76f8387e89c6" datatype="html">
+ <source>Flags</source>
+ <target>Indicadores</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5" datatype="html">
+ <source>Services</source>
+ <target>Servicios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6834fa6b43d1ecbdf147c48dd9c4d72f1484571d" datatype="html">
+ <source>Source</source>
+ <target>Origen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a446fb0eb11fbffcac805ece5a2d306d24e733d8" datatype="html">
+ <source>Level</source>
+ <target>Nivel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39f2fb094e9b2eda13163fa3f3a31594cf9c1307" datatype="html">
+ <source>Can be updated at runtime (editable)</source>
+ <target>Se puede actualizar en el tiempo de ejecución (editable)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
+ <source>Tags</source>
+ <target>Etiquetas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ab0089ef47af61ca1d137bc908b96c290dfd9287" datatype="html">
+ <source>Enum values</source>
+ <target>Valores Enum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="819476f1264f1659f38e86f6abb542141b184832" datatype="html">
+ <source>See also</source>
+ <target>Véase también</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="543199344025799954" datatype="html">
+ <source>The value can be updated at runtime.</source>
+ <target>El valor se puede actualizar en el tiempo de ejecución.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1718354829128482129" datatype="html">
+ <source>Daemons/clients do not pull this value from the
+ monitor config database. We disallow setting this option via 'ceph config
+ set ...'. This option should be configured via ceph.conf or via the
+ command line.</source>
+ <target>Los daemons/clientes no extraen este valor de la
+ base de datos de configuración del monitor. No se recomienda definir esta opción con &quot;ceph config
+ set ...&quot;. Esta opción se debe configurar mediante ceph.conf o a través
+ de la línea de comandos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">15,18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2345189734548717257" datatype="html">
+ <source>Option takes effect only during daemon startup.</source>
+ <target>La opción solo surte efecto durante el inicio del daemon.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5523310713159993513" datatype="html">
+ <source>Option only affects cluster creation.</source>
+ <target>La opción solo afecta a la creación del clúster.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1064479086902933123" datatype="html">
+ <source>Option only affects daemon creation.</source>
+ <target>La opción solo afecta a la creación del daemon.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="809b0c848932a41318f77a2aace904ef429c13f4" datatype="html">
+ <source>Values</source>
+ <target>Valores</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5894f7158499fdb89527af50c9f1cf7d4c95cad6" datatype="html">
+ <source>-- Default --</source>
+ <target>-- Por defecto --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="514f6e12d035a6d9b00de6b3e55c18b73488da07" datatype="html">
+ <source>true</source>
+ <target>verdadero</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="774f5e6a183dea08393789b6f72e86afad729419" datatype="html">
+ <source>false</source>
+ <target>falso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="82029b6db704c56a2aa3e82ac555b8655356b077" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>.</source>
+ <target>El valor introducido es demasiado alto. No debe ser mayor que <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ed8b3967a7326b81b191c9f490006e6a6777a9a" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>.</source>
+ <target>El valor introducido es demasiado bajo. No debe ser menor que <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2337058106409853613" datatype="html">
+ <source>Updated config option <x id="PH" equiv-text="request.name"/></source>
+ <target>Opción de configuración <x id="PH" equiv-text="request.name"/> actualizada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3733215288982610673" datatype="html">
+ <source>Level</source>
+ <target>Nivel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2218082343053095278" datatype="html">
+ <source>Service</source>
+ <target>Servicio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3553216189604488439" datatype="html">
+ <source>Modified</source>
+ <target>Modificado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844248428439297756" datatype="html">
+ <source>Current value</source>
+ <target>Valor actual</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208877297843037352" datatype="html">
+ <source>Editable</source>
+ <target>Editable</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b266042bac4c3a2eff4834e40fb9dc4767a709" datatype="html">
+ <source>Cluster Resources</source>
+ <target>Recursos de clúster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="099b441d49333b3c6d30b36dc0a4763e64c78920" datatype="html">
+ <source>Hosts</source>
+ <target>Hosts</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57e6e608ece53a26f6d509c90ed4f83e467741af" datatype="html">
+ <source>Storage Capacity</source>
+ <target>Capacidad de almacenamiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19ece2cb2b9097c0f75af8e62b4b3b25d399a006" datatype="html">
+ <source>Number of devices</source>
+ <target>Número de dispositivos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b161e3d25fd1b42a781f4e923a58a94925988ddf" datatype="html">
+ <source>Raw capacity</source>
+ <target>Capacidad en bruto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb6f3e2a26f3a6f2bc33f91adcd60502dbe5adac" datatype="html">
+ <source>CPUs</source>
+ <target>CPUs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58d4a9814864741040bc5905b6a368836e683f76" datatype="html">
+ <source>Memory</source>
+ <target>Memoria</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dbb81e566a861d4aa0a094366e4083e50863ee92" datatype="html">
+ <source>Host Details</source>
+ <target>Detalles del host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="453dc2810080a744223faac6da2b3ee9ed63a583" datatype="html">
+ <source>Welcome to <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></source>
+ <target>Le damos la bienvenida a <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1eec874e1928ca53baa9914781ce203b5f72b0c" datatype="html">
+ <source>Please expand your cluster first</source>
+ <target>Primero, expanda el clúster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2195fd96b0a00f560449b50bd032e6d9b357730" datatype="html">
+ <source>Expand Cluster</source>
+ <target>Expandir clúster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb075d0450deb6f381616f7da4b9244ced843053" datatype="html">
+ <source>Skip</source>
+ <target>Omitir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55b6ce65571b8893440a4fc92776570f8fe7cc97" datatype="html">
+ <source>Add Hosts</source>
+ <target>Añadir hosts</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="162f763675c24b557a60eba0758558222369e0c7" datatype="html">
+ <source>Create OSDs</source>
+ <target>Crear OSDs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fef7a7b8db05c351c5287db48488abca530bdb54" datatype="html">
+ <source>Create Services</source>
+ <target>Crear servicios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="176873b4533ddeabf95992cbd7b91b9d01c6d557" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ed90ec4409b9f6b552982d96f89db27259e763c" datatype="html">
+ <source>You are about to skip the cluster expansion process. You’ll need to <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>navigate through the menu to add hosts and services.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>Va a omitir el proceso de expansión del clúster. Debe <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>desplazarse por los menús para añadir hosts y servicios.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">90,91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d1dcf2a9146caac0581329acf94806ec69a89a5" datatype="html">
+ <source>Are you sure you want to continue?</source>
+ <target>¿Seguro que desea continuar?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6759205696902713848" datatype="html">
+ <source>Warning</source>
+ <target>Advertencia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">357</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6962699013778688473" datatype="html">
+ <source>Continue</source>
+ <target>Continuar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6156560100092571435" datatype="html">
+ <source>Cluster expansion skipped by user</source>
+ <target>Expansión del clúster omitida por el usuario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520085823873354736" datatype="html">
+ <source>Cluster expansion was successful</source>
+ <target>El clúster se ha expandido correctamente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176230351113290618" datatype="html">
+ <source>Expand Cluster</source>
+ <target>Expandir clúster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="738de688b22fba5d0dc7a5e549996838dddad0ee" datatype="html">
+ <source>CRUSH map viewer</source>
+ <target>Visor del mapa de CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/crushmap/crushmap.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e24569eca61d598c8b01defbbbb1fa8bd5222bc" datatype="html">
+ <source>Devices</source>
+ <target>Dispositivos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17137bac47e1e020d139256ded0006a671966e73" datatype="html">
+ <source>Physical Disks</source>
+ <target>Discos físicos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="deba10b7279a589d01e919ea11f43c79ca1773e3" datatype="html">
+ <source>Device health</source>
+ <target>Estado del dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d87fc20ea8e5f0f0500ba5d5061b345be78ec5e" datatype="html">
+ <source>No hostname found.</source>
+ <target>No se encuentra ningún nombre de host.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9a541ec1a4319fffc16ad3b3ab2c2b6d251a829d" datatype="html">
+ <source>Hostname</source>
+ <target>Nombre de host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee6875e67b53cac30a02b57cf76e485f7e60caf4" datatype="html">
+ <source>To add multiple hosts at once, you can enter:</source>
+ <target>Para añadir varios hosts a la vez, puede introducir:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a8370b19ccf673fb28fa9db36a08f9901887cc7" datatype="html">
+ <source>a comma-separated list of hostnames <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-01,example-02,example-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <target>una lista separada por comas de nombres de host <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(por ejemplo: ejemplo-01,ejemplo-02,ejemplo-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="68f2c05396ec8a5f59e8da42d1f6c7310fa8c37c" datatype="html">
+ <source>a range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <target>una expresión de intervalo <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(por ejemplo: ejemplo-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e00b9bba448e79add37740e53dc953fbb89f9c5" datatype="html">
+ <source>a comma separated range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></source>
+ <target>una expresión de intervalo separada por comas <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(por ejemplo: ejemplo-[01-05].lab.com,ejemplo2-[1-4].lab.com,ejemplo3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b3f5e5291541678f7afa49d28fad5ca848a8061" datatype="html">
+ <source>The chosen hostname is already in use.</source>
+ <target>El nombre de host que ha elegido ya está en uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="42365f623c57973d1d13d2038e8a2d4c02fb9b9f" datatype="html">
+ <source>Network address</source>
+ <target>Dirección de red</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3859bdca1ae89e611e214c205fccf0147b4d0f6b" datatype="html">
+ <source>The value is not a valid IP address.</source>
+ <target>El valor no es una dirección IP válida.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2af7efecfae8d7fed3b07f718a623eca1ad8163f" datatype="html">
+ <source>Labels</source>
+ <target>Etiquetas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9da2afd4fa358b66d4d95fe7e8f4b659a7144e" datatype="html">
+ <source>Maintenance Mode</source>
+ <target>Modo de mantenimiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="468785112451259935" datatype="html">
+ <source>There are no labels.</source>
+ <target>No hay etiquetas.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4664081995078497865" datatype="html">
+ <source>Filter or add labels</source>
+ <target>Filtrar o añadir etiquetas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4897817053917542646" datatype="html">
+ <source>Add label</source>
+ <target>Añadir etiqueta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">313</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1187321380561233505" datatype="html">
+ <source>host</source>
+ <target>host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40661476cb24c89d8b06614998e31d5fbe84eeb6" datatype="html">
+ <source>Hosts List</source>
+ <target>Lista de hosts</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b7a4e1e5a316f8547af1d6d2311a5cec8c5c1d87" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ msg }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ msg }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6e8e8844e9e7a7b626a4699c08b6c0c81297a7b" datatype="html">
+ <source>Data will be available only if Orchestrator is available.</source>
+ <target>Los datos solo estarán disponibles si Orchestrator está disponible.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4baf526199fed59071adf555271791283adc408" datatype="html">
+ <source>SSD, NVMEs</source>
+ <target>SSD, NVMEs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="22d5531d79f0d7269a0a752e56a848807dd37095" datatype="html">
+ <source>Flash</source>
+ <target>Flash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4025065730478477779" datatype="html">
+ <source>The feature is disabled because the selected host is not managed by Orchestrator.</source>
+ <target>La función está inhabilitada porque el host seleccionado no se gestiona con Orchestrator.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7143579180750436311" datatype="html">
+ <source>Services</source>
+ <target>Servicios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="546766753072101168" datatype="html">
+ <source>Labels</source>
+ <target>Etiquetas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1141886420788473147" datatype="html">
+ <source>Model</source>
+ <target>Modelo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4027647877328291519" datatype="html">
+ <source>CPUs</source>
+ <target>CPUs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2445398473573060226" datatype="html">
+ <source>Cores</source>
+ <target>Núcleos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1656823484917332451" datatype="html">
+ <source>Total Memory</source>
+ <target>Memoria total</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1939212557812454069" datatype="html">
+ <source>Raw Capacity</source>
+ <target>Capacidad en bruto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5579687933271468638" datatype="html">
+ <source>HDDs</source>
+ <target>Discos duros</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1889285841762768492" datatype="html">
+ <source>Flash</source>
+ <target>Flash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1578709829957887527" datatype="html">
+ <source>NICs</source>
+ <target>Tarjetas NIC</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4723031838495967601" datatype="html">
+ <source>Edit Host: <x id="PH" equiv-text="host.hostname"/></source>
+ <target>Editar host: <x id="PH" equiv-text="host.hostname"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6004907173026319041" datatype="html">
+ <source>Edit Host</source>
+ <target>Editar host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5618131051466022401" datatype="html">
+ <source>Updated Host &quot;<x id="PH" equiv-text="host.hostname"/>&quot;</source>
+ <target>Host actualizado <x id="PH" equiv-text="host.hostname"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1701954433367210342" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; moved to maintenance</source>
+ <target><x id="PH" equiv-text="host.hostname"/> movido a mantenimiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3108406586869160854" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; cannot be put into maintenance</source>
+ <target><x id="PH" equiv-text="host.hostname"/> no se puede poner en mantenimiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1737753151350322492" datatype="html">
+ <source><x id="PH" equiv-text="error.error['detail']"/></source>
+ <target><x id="PH" equiv-text="error.error['detail']"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4054533801359952167" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; has exited maintenance</source>
+ <target><x id="PH" equiv-text="host.hostname"/> ha salido del mantenimiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5837599005212786659" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; stopped draining</source>
+ <target><x id="PH" equiv-text="host['hostname']"/> ha detenido el vaciado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1357236071975782353" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; started draining</source>
+ <target><x id="PH" equiv-text="host['hostname']"/> ha iniciado el vaciado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5658400717636093668" datatype="html">
+ <source>Identify</source>
+ <target>Identificar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6966707768479328825" datatype="html">
+ <source>Device path</source>
+ <target>Vía del dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3955868613858648955" datatype="html">
+ <source>Available</source>
+ <target>Disponible</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="158816374076721379" datatype="html">
+ <source>Vendor</source>
+ <target>Proveedor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6024104799101504292" datatype="html">
+ <source>OSDs</source>
+ <target>OSDs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3422162477846071958" datatype="html">
+ <source>Identify device <x id="PH" equiv-text="device"/></source>
+ <target>Identificar dispositivo <x id="PH" equiv-text="device"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4910073658089977244" datatype="html">
+ <source>Please enter the duration how long to blink the LED.</source>
+ <target>Indique cuánto tiempo parpadeará la luz LED.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5764931367607989415" datatype="html">
+ <source>1 minute</source>
+ <target>1 minuto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809466133764752509" datatype="html">
+ <source>2 minutes</source>
+ <target>2 minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">235</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1487672983218679675" datatype="html">
+ <source>5 minutes</source>
+ <target>5 minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603584938775296395" datatype="html">
+ <source>10 minutes</source>
+ <target>10 minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6648333117195452824" datatype="html">
+ <source>15 minutes</source>
+ <target>15 minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6560281329999108838" datatype="html">
+ <source>Execute</source>
+ <target>Ejecutar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6901229416977800100" datatype="html">
+ <source>Identifying '<x id="PH" equiv-text="device"/>' started on host '<x id="PH_1" equiv-text="hostname"/>'</source>
+ <target>Se ha iniciado la identificación de <x id="PH" equiv-text="device"/> en el host <x id="PH_1" equiv-text="hostname"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d556ab48a65722b400e497f61737f553ee0f89e2" datatype="html">
+ <source>Cluster Logs</source>
+ <target>Registros del clúster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5f966baffd188be0e8adc2d7067b86e55fc9b9de" datatype="html">
+ <source>Audit Logs</source>
+ <target>Registros de auditoría</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4193c9eb868aeec119b78a14795241e0aa5e8b60" datatype="html">
+ <source>Priority:</source>
+ <target>Prioridad:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d78ca51eab260ce3fd917d39190d64df5229b6e" datatype="html">
+ <source>Keyword:</source>
+ <target>Palabra clave:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="05fa0bded36de6e73a1fa44838b627349dace044" datatype="html">
+ <source>Date:</source>
+ <target>Fecha:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a400388de1899b1917138cf7e5286376f72847" datatype="html">
+ <source>Time range:</source>
+ <target>Intervalo temporal:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="de0478286b8b5a939db54e9e5282405364ad2d61" datatype="html">
+ <source>No log entries found. Please try to select different filter options.</source>
+ <target>No se encuentra ninguna entrada de registro. Seleccione opciones de filtro distintas.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7479674d91142b785b9547a87e5fb51cb16108" datatype="html">
+ <source>Reset filter.</source>
+ <target>Restablecer filtro.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="31a9c2870a934b594d1390146c489f76440859ea" datatype="html">
+ <source>Edit Manager module</source>
+ <target>Módulo del gestor de edición</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="46e09b8290d3d0afdb6baa2021395b0570606a31" datatype="html">
+ <source>The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</source>
+ <target>El valor introducido no es un UUID válido, por ejemplo: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7aacd038b39cfd347107d01d1dc27f5cb3e0951c" datatype="html">
+ <source>The entered value needs to be a valid IP address.</source>
+ <target>El valor introducido debe ser una dirección IP válida.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f19106149f4b07a0d721f9d317afed393cb7bd93" datatype="html">
+ <source>The entered value is too high! It must be lower or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>.</source>
+ <target>El valor introducido es demasiado alto. Debe ser menor o igual que <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d33c40ef9a6c3bf0888df831b25e41e65f9d15b" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>.</source>
+ <target>El valor introducido es demasiado bajo. Debe ser mayor o igual que <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eae7086660cf1e38c7194a2c49ff52cc656f90f5" datatype="html">
+ <source>The entered value needs to be a number.</source>
+ <target>El valor introducido debe ser un número.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">194</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a73376e04b4fb3a20734c8c39743fba32e6676ce" datatype="html">
+ <source>The entered value needs to be a number or decimal.</source>
+ <target>El valor introducido debe ser un número o un decimal.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1898719236268328097" datatype="html">
+ <source>Updated options for module '<x id="PH" equiv-text="this.moduleName"/>'.</source>
+ <target>Opciones actualizadas para el módulo <x id="PH" equiv-text="this.moduleName"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4186041075388034600" datatype="html">
+ <source>Always-On</source>
+ <target>Siempre activo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7585826646011739428" datatype="html">
+ <source>Edit</source>
+ <target>Editar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2180291763949669799" datatype="html">
+ <source>Enable</source>
+ <target>Habilitar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9187855490716817910" datatype="html">
+ <source>Disable</source>
+ <target>Inhabilitar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1600086764852993170" datatype="html">
+ <source>This Manager module is always on.</source>
+ <target>Este módulo de gestor siempre está activo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3895296744591223546" datatype="html">
+ <source>Reconnecting, please wait ...</source>
+ <target>Conectando de nuevo. Espere...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81b97b8ea996ad1e4f9fca8415021850214884b1" datatype="html">
+ <source>Status</source>
+ <target>Estado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57ec6032f5618d4a9f16eb950ad23d2ce7c24b54" datatype="html">
+ <source>Cluster ID</source>
+ <target>ID de clúster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67d7facc3fec5f8a49ab9ba0a245872184264ce5" datatype="html">
+ <source>monmap modified</source>
+ <target>Mapa de supervisión modificado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4906731aaf2b94b4f547646c9bfe58bb77951b6" datatype="html">
+ <source>monmap epoch</source>
+ <target>Época de mapa de supervisión</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd4ee06ffdc46d9dfbd0c0c4f81399021c680056" datatype="html">
+ <source>quorum con</source>
+ <target>quórum de con</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1176c7db8a8276ccb44cc3d42e2c28d9fa6c6596" datatype="html">
+ <source>quorum mon</source>
+ <target>quórum de mon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="530ef677a09d681b3ab68cb0760494b3ae72a77c" datatype="html">
+ <source>required con</source>
+ <target>con requerido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a91558e0d506c32021c31843f8f168899fc65cbf" datatype="html">
+ <source>required mon</source>
+ <target>mon requerido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3abe9eac5bcd94a54c8da93b312e085ec512e74" datatype="html">
+ <source>In Quorum</source>
+ <target>Con quórum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba4b748a676e1f217ce1e736fb7ec1215e677bae" datatype="html">
+ <source>Not In Quorum</source>
+ <target>Sin quórum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3517477838460618200" datatype="html">
+ <source>Public Address</source>
+ <target>Dirección pública</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6949358970125514744" datatype="html">
+ <source>Open Sessions</source>
+ <target>Sesiones abiertas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4383e9662ea19839c7499b2128d43a195e564317" datatype="html">
+ <source>OSD creation preview</source>
+ <target>Vista previa de creación de OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="366225c51e0b00bcb1c55795a0dc5e81c455f84e" datatype="html">
+ <source>DriveGroups</source>
+ <target>DriveGroups</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91853167141c37b58868f3b0421383dd72fa8a01" datatype="html">
+ <source>Attributes (OSD map)</source>
+ <target>Atributos (mapa de OSD)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f721a500a68c357e8f2a01e60510f6a01e4ba529" datatype="html">
+ <source>Metadata</source>
+ <target>Metadatos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97842f379e1d4157ac3ab0661b90c352e7cb72d5" datatype="html">
+ <source>Metadata not available</source>
+ <target>Los metadatos no están disponibles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24e28e19c5703d7c6be44f4eb595a6a43b618ed" datatype="html">
+ <source>Performance counter</source>
+ <target>Contandor de rendimiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ccb4f84edc0b4e76415bb3f9b73d725b06683af3" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ name }}"/> devices</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ name }}"/> dispositivos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60cb3d01e5ddf266ecb4271007a1c3d0f3efdc22" datatype="html">
+ <source>The primary storage devices. These devices contain all OSD data.</source>
+ <target>Los dispositivos de almacenamiento primarios. Estos dispositivos contienen todos los datos de OSD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b432e04886d0d1fd84f740477383051f85addcf2" datatype="html">
+ <source>Write-Ahead-Log devices. These devices are used for BlueStore’s internal journal. It is only useful to use a WAL device if the device is faster than the primary device (e.g. NVME devices or SSDs). If there is only a small amount of fast storage available (e.g., less than a gigabyte), we recommend using it as a WAL device.</source>
+ <target>Dispositivos WAL (Write-Ahead-Log, escritura anticipada en registro). Estos dispositivos se usan para el diario interno de BlueStore. Usar un dispositivo WAL solo resulta útil si el dispositivo es más rápido que el dispositivo primario (p. ej., dispositivos NVME o SSD). Si solo hay una pequeña cantidad de espacio de almacenamiento rápido disponible (p. ej., menos de un gigabyte), se recomienda usarlo como dispositivo WAL.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87e181ab9e8393aa5ed759dd3d53836e32c8ffe" datatype="html">
+ <source>DB devices can be used for storing BlueStore’s internal metadata. It is only helpful to provision a DB device if it is faster than the primary device (e.g. NVME devices or SSD).</source>
+ <target>Los dispositivos de base de datos se pueden usar para almacenar metadatos internos de BlueStore. Aprovisionar un dispositivo de BD solo resulta útil si es más rápido que el dispositivo primario (p. ej. dispositivos NVME o SSD).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
+ <source>Add</source>
+ <target>Añadir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="99ee4faa69cd2ea8e3678c1f557c0ff1f05aae46" datatype="html">
+ <source>Clear</source>
+ <target>Borrar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e0fd3c7af0630f93befa6234a693a32a61084e0" datatype="html">
+ <source>Raw capacity: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></source>
+ <target>Capacidad en bruto: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1961811273151129466" datatype="html">
+ <source>No available devices</source>
+ <target>No hay dispositivos disponibles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617271647728055571" datatype="html">
+ <source>Please add primary devices first</source>
+ <target>Añada primero dispositivos primarios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6368751795251107516" datatype="html">
+ <source>Add devices by using filters</source>
+ <target>Añada dispositivos usando filtros</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8edc89137d0d8c5667a2f03230beafae45e58429" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> devices</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> dispositivos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eba28e1805b18f7c8ae2e4bc15dcf063b10b3822" datatype="html">
+ <source>At least one of these filters must be applied in order to proceed:</source>
+ <target>Se debe aplicar al menos uno de estos filtros para poder continuar:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="93389aa2fe2bea50bf89554ee51b28f87ee2fb50" datatype="html">
+ <source>Number of devices: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Raw capacity: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</source>
+ <target>Número de dispositivos: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Capacidad en bruto: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">29,30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6b27c16ddf33b855412c82069dca8120bd3a68a" datatype="html">
+ <source>Individual OSD Flags</source>
+ <target>Indicadores de OSD individuales</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dba0ed9ba355a3bd3296c0bef3bb518744a51a89" datatype="html">
+ <source>Cluster-wide</source>
+ <target>En todo el clúster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e2a3f211cea2cbadb29b6df93e544440b6b68d3e" datatype="html">
+ <source>Restore previous selection</source>
+ <target>Restaurar selección anterior</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1683654169791509804" datatype="html">
+ <source>No Up</source>
+ <target>No activar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5754783193519044074" datatype="html">
+ <source>OSDs are not allowed to start</source>
+ <target>No se permite que los OSD se inicien</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4413588319909369773" datatype="html">
+ <source>No Down</source>
+ <target>No desactivar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1348746748821823470" datatype="html">
+ <source>OSD failure reports are being ignored, such that the monitors will not mark OSDs down</source>
+ <target>Se ignoran los informes de error de OSD, de forma que los monitores no desactivarán los OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="301172600132606646" datatype="html">
+ <source>No In</source>
+ <target>No incluir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4114057962148673377" datatype="html">
+ <source>OSDs that were previously marked out will not be marked back in when they start</source>
+ <target>Los OSD que se excluyeron anteriormente no se volverán a incluir cuando se inicien</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5236523991485603657" datatype="html">
+ <source>No Out</source>
+ <target>No excluir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1798160169020638994" datatype="html">
+ <source>OSDs will not automatically be marked out after the configured interval</source>
+ <target>Los OSD no se excluirán automáticamente después del intervalo configurado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3225813593817914267" datatype="html">
+ <source>The flag has been enabled for the entire cluster.</source>
+ <target>El indicador se ha habilitado para todo el clúster.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1941050626944682985" datatype="html">
+ <source>Updated OSD Flags</source>
+ <target>Indicadores de OSD actualizados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ef50ba2514414f799d4c8fc36067a251904ba81" datatype="html">
+ <source>Cluster-wide OSD Flags</source>
+ <target>Indicadores OSD de todo el clúster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9042260521669277115" datatype="html">
+ <source>Pause</source>
+ <target>Pausa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6015425610572318971" datatype="html">
+ <source>Pauses reads and writes</source>
+ <target>Pone en pausa las lecturas y escrituras</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314873595759611676" datatype="html">
+ <source>No Scrub</source>
+ <target>No depurar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773570234687653570" datatype="html">
+ <source>Scrubbing is disabled</source>
+ <target>La depuración está inhabilitada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5999821123886006899" datatype="html">
+ <source>No Deep Scrub</source>
+ <target>No depuración profunda</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5362685148875251772" datatype="html">
+ <source>Deep Scrubbing is disabled</source>
+ <target>La depuración profunda está inhabilitada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5001752039592388485" datatype="html">
+ <source>No Backfill</source>
+ <target>No reponer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4851280330655956778" datatype="html">
+ <source>Backfilling of PGs is suspended</source>
+ <target>La reposición de grupos de colocación se suspende</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5994953210305546559" datatype="html">
+ <source>No Rebalance</source>
+ <target>Sin reequilibrar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3698980403470604587" datatype="html">
+ <source>OSD will choose not to backfill unless PG is also degraded</source>
+ <target>El OSD optará por no reponerse a no ser que el grupo de colocación también se baje de nivel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4334886823145076432" datatype="html">
+ <source>No Recover</source>
+ <target>No recuperar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8465994741155792816" datatype="html">
+ <source>Recovery of PGs is suspended</source>
+ <target>La recuperación de los grupos de colocación se suspende</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4052740759486923001" datatype="html">
+ <source>Bitwise Sort</source>
+ <target>Orden bit a bit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2330377428425572488" datatype="html">
+ <source>Use bitwise sort</source>
+ <target>Usar orden bit a bit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8943478424576832224" datatype="html">
+ <source>Purged Snapdirs</source>
+ <target>Snapdir limpiados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7553321860087551262" datatype="html">
+ <source>OSDs have converted snapsets</source>
+ <target>Los OSD tienen snapset convertidos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6509988280998256208" datatype="html">
+ <source>Recovery Deletes</source>
+ <target>Supresiones de recuperación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="451760144355116641" datatype="html">
+ <source>Deletes performed during recovery instead of peering</source>
+ <target>Supresiones realizadas durante la recuperación, en lugar de emparejamientos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="87832369463084597" datatype="html">
+ <source>PG Log Hard Limit</source>
+ <target>Límite estricto de registro del grupo de colocación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9135782750879343185" datatype="html">
+ <source>Puts a hard limit on pg log length</source>
+ <target>Establece un límite estricto para la longitud del registro del grupo de colocación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="formTitle" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <note priority="1" from="description">Example: Create Pool</note>
+ <note priority="1" from="meaning">form title</note>
+ </trans-unit>
+ <trans-unit id="43ecf6bee2aebc07b0aad6dc1fe13e38d14687fa" datatype="html">
+ <source>Shared devices</source>
+ <target>Dispositivos compartidos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7a1c376f6f1b37de4c318ff2106255ba6c0f5b0b" datatype="html">
+ <source>WAL slots</source>
+ <target>Ranuras para WAL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73811a6f37b63e6b0e491e221bfa21e9dea8a87a" datatype="html">
+ <source>How many OSDs per WAL device.</source>
+ <target>Indica el número de OSD por dispositivo WAL.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c67a7ac4762ef1cc855056c6b4daab93e53a0a5" datatype="html">
+ <source>Specify 0 to let Orchestrator backend decide it.</source>
+ <target>Especifique 0 para dejar que el motor de Orchestrator lo decida.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bda9362e06e6c67341b4a8425b0d29d6b84464b" datatype="html">
+ <source>Value should be greater than or equal to 0</source>
+ <target>El valor debe ser mayor o igual que 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="324c2b10152b9dd908222bb0b71f61beb60a30c5" datatype="html">
+ <source>DB slots</source>
+ <target>Ranuras para BD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c23cf12ef9c76f37fc7a4b7ae3e00fb0f68b6e26" datatype="html">
+ <source>How many OSDs per DB device.</source>
+ <target>Indica el número de OSD por dispositivo BD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8255877266497322342" datatype="html">
+ <source>Encryption</source>
+ <target>Cifrado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b49d7877d24112d4bdfce9256edf61a007fae888" datatype="html">
+ <source>OSDs List</source>
+ <target>Lista de OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="172ada0fcf6490b24a897517e9f4299215873ff8" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD(s) <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be marked <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <target>Si continúa, los <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> se marcarán como <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">59,60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="262a49e60d5f6ed9825582ccf3d5ae39daa1da60" datatype="html">
+ <source>The <x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> not safe to be <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>! <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></source>
+ <target>No es eguro que <x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>. <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71,72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="74bd20d5f558d14cb2fa41ae863cf09c47d02018" datatype="html">
+ <source>{VAR_SELECT, select, true {OSD is} other {OSDs are}}</source>
+ <target>{VAR_SELECT, select, true {el OSD sea} other {los OSD sean}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0e217fd717c5b1f5c17f00c5b174de855acbef0" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <target>Si continúa, el <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">74,75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8cf121660bed7098516a1efe85831d6f415a9411" datatype="html">
+ <source>Preserve OSD ID(s) for replacement.</source>
+ <target>Conservar ID(s) de OSD para sustitución.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4435645098786961170" datatype="html">
+ <source>out</source>
+ <target>excluir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136018875175606726" datatype="html">
+ <source>in</source>
+ <target>Incluir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1301930865667956193" datatype="html">
+ <source>down</source>
+ <target>desactivar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1226060325201042854" datatype="html">
+ <source>Mark</source>
+ <target>Marcar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1256299033316818951" datatype="html">
+ <source>OSD lost</source>
+ <target>OSD perdido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2795727560928976873" datatype="html">
+ <source>marked lost</source>
+ <target>marcado como perdido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7685933846431786388" datatype="html">
+ <source>Purge</source>
+ <target>Limpiar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5941516286393808546" datatype="html">
+ <source>OSD</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3416443212235382421" datatype="html">
+ <source>purged</source>
+ <target>limpiado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9191368063029792986" datatype="html">
+ <source>destroy</source>
+ <target>destruir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4425946029386289247" datatype="html">
+ <source>destroyed</source>
+ <target>destruido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2870788902465061969" datatype="html">
+ <source>Flags</source>
+ <target>Indicadores</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8995035642420075344" datatype="html">
+ <source>Recovery Priority</source>
+ <target>Prioridad de recuperación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3601135996773579607" datatype="html">
+ <source>PG scrub</source>
+ <target>Depuración de grupo de colocación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136079353894161076" datatype="html">
+ <source>Device class</source>
+ <target>Clase de dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6382718875453721838" datatype="html">
+ <source>PGs</source>
+ <target>Grupos de colocación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3660230483843323377" datatype="html">
+ <source>Read bytes</source>
+ <target>Bytes de lectura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">329</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3909578649547040612" datatype="html">
+ <source>Write bytes</source>
+ <target>Bytes de escritura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3182358405280886750" datatype="html">
+ <source>Read ops</source>
+ <target>Operaciones de lectura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171292502535561083" datatype="html">
+ <source>Write ops</source>
+ <target>Operaciones de escritura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6706824709967518168" datatype="html">
+ <source>Edit OSD: <x id="PH" equiv-text="selectedOsd.id"/></source>
+ <target>Editar OSD: <x id="PH" equiv-text="selectedOsd.id"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">451</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1125148356983553148" datatype="html">
+ <source>Edit OSD</source>
+ <target>Editar OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="970212458427610374" datatype="html">
+ <source>Updated OSD '<x id="PH" equiv-text="selectedOsd.id"/>'</source>
+ <target>OSD <x id="PH" equiv-text="selectedOsd.id"/> actualizado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">466</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7554728686176829307" datatype="html">
+ <source>Mark OSD <x id="PH" equiv-text="markAction"/></source>
+ <target>Marcar OSD <x id="PH" equiv-text="markAction"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="478122291463667978" datatype="html">
+ <source>Mark <x id="PH" equiv-text="markAction"/></source>
+ <target>Marcar <x id="PH" equiv-text="markAction"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">502</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2456043080471762298" datatype="html">
+ <source>delete</source>
+ <target>suprimir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">530</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="588230151780724018" datatype="html">
+ <source>deleted</source>
+ <target>suprimido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">532</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1ef1c12ddcee305353623919ef02778569f5454" datatype="html">
+ <source>Advanced configuration options</source>
+ <target>Opciones de configuración avanzadas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7771252117308888928" datatype="html">
+ <source>PG scrub options</source>
+ <target>Opciones de depuración de grupo de colocación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1797901277775175680" datatype="html">
+ <source>Updated PG scrub options</source>
+ <target>Opciones de depuración de grupo de colocación actualizadas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c35f9c5f268a514b970cc55e9a5dc4bed0988e7f" datatype="html">
+ <source>OSD Recovery Priority</source>
+ <target>Prioridad de recuperación de OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74af38005e8a8914e45af2ec412e11ceafef8b6" datatype="html">
+ <source>Priority</source>
+ <target>Prioridad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f48f04b379bfba133825747adfd238d511412e" datatype="html">
+ <source>Customize priority values</source>
+ <target>Personalizar valores de prioridad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aa19de2a2b54cbda39e9c62917b23044c087776" datatype="html">
+ <source>This field is required!</source>
+ <target>Este campo es obligatorio.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">406</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b699e94bf376491bd50b70a98531071c737eaf40" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="98fe13e7ad6c2b80375d204b47858ded83f80e15" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>.</source>
+ <target>El valor introducido es demasiado alto. No debe ser mayor que <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423a3c111be47fc5a1bfe46ceb58c81c84db691" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>.</source>
+ <target>El valor introducido es demasiado bajo. No debe ser menor que <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3234179038052466481" datatype="html">
+ <source>Max Backfills</source>
+ <target>Número máximo de reposiciones</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847070960491384020" datatype="html">
+ <source>Recovery Max Active</source>
+ <target>Máximo de recuperaciones activas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2088615724570210504" datatype="html">
+ <source>Recovery Max Single Start</source>
+ <target>Máximo de recuperaciones de inicio único</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8627094894361422565" datatype="html">
+ <source>Recovery Sleep</source>
+ <target>Reposo de recuperación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7590013429208346303" datatype="html">
+ <source>Custom</source>
+ <target>Personalizar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4937275625032609020" datatype="html">
+ <source>Updated OSD recovery speed priority '<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>'</source>
+ <target>Prioridad de velocidad de recuperación de OSD actualizada <x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">227,229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5251a4355cece3075db43f15d69a24a0f8485707" datatype="html">
+ <source>Reweight OSD: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></source>
+ <target>Reequilibrar peso de OSD: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67650b2998db48201b2c6176cbfef51e7211ccaa" datatype="html">
+ <source>The value needs to be between 0 and 1.</source>
+ <target>El valor debe estar entre 0 y 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f077ceb52c967a8fe2de9ef0a9d65d72badf186" datatype="html">
+ <source>OSDs <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/>Scrub</source>
+ <target>Depuración de <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/>OSDs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b73a34ba65b3073e3560dce828a16d7fd3c0f4" datatype="html">
+ <source>{VAR_SELECT, select, true {Deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {Profundo } other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c00119503aad4012b77049eee41293338f67756c" datatype="html">
+ <source>You are about to apply a <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/>scrub to the OSD(s): <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <target>Va a aplicar una <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/>depuración a los OSD: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fad3dc421817a16dd6c46c1a0c36de619a8d776e" datatype="html">
+ <source>{VAR_SELECT, select, true {deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {profundo } other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1086427836866943370" datatype="html">
+ <source><x id="PH" equiv-text="operation"/> was initialized in the following OSD(s): <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></source>
+ <target><x id="PH" equiv-text="operation"/> se ha inicializado en los OSD siguientes: <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts</context>
+ <context context-type="linenumber">42,44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47c97aa28f64b11fa5842795fdd02c8c0863c97b" datatype="html">
+ <source>To see all active Prometheus alerts, please provide the URL to the API of Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>Para ver todas las alertas activas de Prometheus, proporcione la URL a la API del gestor de alertas de Prometheus, como se describe en <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6343323763459782070" datatype="html">
+ <source>Create Silence</source>
+ <target>Crear silencio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1895957424873987405" datatype="html">
+ <source>Job</source>
+ <target>Trabajo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491474782694268231" datatype="html">
+ <source>Severity</source>
+ <target>Gravedad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3326877877555410533" datatype="html">
+ <source>Started</source>
+ <target>Iniciado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2375260419993138758" datatype="html">
+ <source>URL</source>
+ <target>URL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="880ad4df5a2051a437321443d69c9a866699e5ad" datatype="html">
+ <source>Active Alerts</source>
+ <target>Alertas activas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9fe218829514884cdd0ca2300573a4e0428c324f" datatype="html">
+ <source>Alerts</source>
+ <target>Alertas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa0c44aa1e5727061baa91e954f77e2f5f9a37c9" datatype="html">
+ <source>Silences</source>
+ <target>Silencios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85c737325f5e59517e2d08a71de6d77788aabc95" datatype="html">
+ <source>To see all configured Prometheus alerts, please provide the URL to the API of Prometheus as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>Para ver todas las alertas configuradas de Prometheus, proporcione la URL a la API de Prometheus, como se describe en <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623978917681527907" datatype="html">
+ <source>Group</source>
+ <target>Grupo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7410432243549869948" datatype="html">
+ <source>Duration</source>
+ <target>Duración</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4109205891084963566" datatype="html">
+ <source>Query</source>
+ <target>Consulta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28f86ffd419b869711aa13f5e5ff54be6d70731c" datatype="html">
+ <source>Edit</source>
+ <target>Editar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="826b25211922a1b46436589233cb6f1a163d89b7" datatype="html">
+ <source>Delete</source>
+ <target>Suprimir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">279</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">341</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">441</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3ba06aba047605af8ea1718ec1ba153b7db12a2" datatype="html">
+ <source>Editing a silence will expire the old silence and recreate it as a new silence</source>
+ <target>Si se edita un silencio, el silencio anterior caducará y se volverá a crear como silencio nuevo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a20424156b8816671f61879f0574a4f27d7b16b9" datatype="html">
+ <source>Creator</source>
+ <target>Creador</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5a5d7ee2acbfa9c91ab7f41d26bda9ff0cafe42f" datatype="html">
+ <source>Comment</source>
+ <target>Comentario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c11aad490b2d53fdae30b3807beabf79306752c" datatype="html">
+ <source>Start time</source>
+ <target>Hora de inicio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32856b1e8e339b747b21e313e2fe65a51fd450bb" datatype="html">
+ <source>If the start time lies in the past the creation time will be used</source>
+ <target>Si la hora de inicio queda en el pasado, se usará la hora de creación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a02ea1d4e7424ca989929da5e598f379940fdbf2" datatype="html">
+ <source>Duration</source>
+ <target>Duración</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f4e35e36f4d3c62e2c17df41730b6dee4afc4b9" datatype="html">
+ <source>End time</source>
+ <target>Hora de finalización</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="992123459137d45c15df5548bc9682aad835c04b" datatype="html">
+ <source>Matchers</source>
+ <target>Buscadores de coincidencias</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e023166c55833d5a13f4143e3dbe372befe1b4e" datatype="html">
+ <source>A silence requires at least one matcher</source>
+ <target>Un silencio requiere al menos un buscador de coincidencias</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef765bd80c4806c51c891908c07a24bc76f019eb" datatype="html">
+ <source>Add matcher</source>
+ <target>Añadir buscador de coincidencias</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754178820914251524" datatype="html">
+ <source>silence</source>
+ <target>silencio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8714559758543060819" datatype="html">
+ <source>Attribute name</source>
+ <target>Nombre del atributo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1338733395833138319" datatype="html">
+ <source>Regular expression</source>
+ <target>Expresión regular</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35819898450851998" datatype="html">
+ <source>Please add your Prometheus host to the dashboard configuration and refresh the page</source>
+ <target>Añada su host de Prometheus a la configuración de la consola y actualice la página</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f2f4cb9d876ff9d34fc082c1ac642d3cb98c360" datatype="html">
+ <source>To enable Silences, please provide the URL to the API of the Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>Para habilitar los silencios, proporcione la URL a la API del gestor de alertas de Prometheus, como se describe en <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7448808151142843482" datatype="html">
+ <source>Created by</source>
+ <target>Creado por</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4734349318830134239" datatype="html">
+ <source>Ends</source>
+ <target>Finaliza el</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1233087251567318644" datatype="html">
+ <source>Silence</source>
+ <target>Silencio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="78af6a5e6e4d305557054b64d10f9f9446d8043d" datatype="html">
+ <source>{VAR_SELECT, select, true {Edit} other {Add}}</source>
+ <target>{VAR_SELECT, select, true {Editar} other {Añadir}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2404fa8e80946d0ce3d0ae369b51cb26ec28d42" datatype="html">
+ <source><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/> Matcher</source>
+ <target><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/> buscador de coincidencias</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c25e04f554875dc2625a78ba0fc56c6010cd0d3" datatype="html">
+ <source>-- Select an attribute to match against --</source>
+ <target>-- Seleccione un atributo con el que deba coincidir --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5049e204c14c648691ac775a64fb504467aeb549" datatype="html">
+ <source>Value</source>
+ <target>Valor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="77fc5c63497fc031ddc97645484e3d94ad27766c" datatype="html">
+ <source>Use regular expression</source>
+ <target>Usar expresión regular</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5518753745858598442" datatype="html">
+ <source>no spec</source>
+ <target>sin especificar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1186363766752354382" datatype="html">
+ <source>unmanaged</source>
+ <target>sin gestionar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5246585784774990516" datatype="html">
+ <source>count:<x id="PH" equiv-text="count"/></source>
+ <target>recuento:<x id="PH" equiv-text="count"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001661117318762535" datatype="html">
+ <source>label:<x id="PH" equiv-text="label"/></source>
+ <target>etiqueta:<x id="PH" equiv-text="label"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cb3aa7e9fea1d445a1a9d7797ab17e6ac6fe13b" datatype="html">
+ <source>Service Events</source>
+ <target>Eventos de servicio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3474944817987674409" datatype="html">
+ <source>Daemon type</source>
+ <target>Tipo de daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3136939605470297323" datatype="html">
+ <source>Daemon ID</source>
+ <target>ID de daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8171022601808215887" datatype="html">
+ <source>Container ID</source>
+ <target>ID de contenedor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8859473568390700297" datatype="html">
+ <source>Container Image name</source>
+ <target>Nombre de la imagen de contenedor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5623167616584404899" datatype="html">
+ <source>Container Image ID</source>
+ <target>ID de imagen de contenedor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="335348913532561915" datatype="html">
+ <source>Last Refreshed</source>
+ <target>Última actualización</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3022087209429182774" datatype="html">
+ <source>Daemon Events</source>
+ <target>Eventos de daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">140</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8604852007710946848" datatype="html">
+ <source>Service Name</source>
+ <target>Nombre del servicio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="613875387304159316" datatype="html">
+ <source>Service Type</source>
+ <target>Tipo de servicio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907644935670421963" datatype="html">
+ <source>Service Events</source>
+ <target>Eventos de servicio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3214a1f3a4c3e89a848b4ec59adeeda3b913c396" datatype="html">
+ <source>-- Select a service type --</source>
+ <target>-- Seleccione un tipo de servicio --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f32579a9fd19d93c083175284ee3426d78751c33" datatype="html">
+ <source>Backend Service</source>
+ <target>Servicio de motor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2937074aed12b8158e929c58747a8216433b72b" datatype="html">
+ <source>-- No service available --</source>
+ <target>-- No hay ningún servicio disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19fb4480d95a5539db4e9c7b516d414774e61110" datatype="html">
+ <source>-- Select an existing RGW service --</source>
+ <target>-- Seleccione un servicio RGW existente --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2798cc1e152b1ec07fd8daf94a2a073d1ba1ebcc" datatype="html">
+ <source>Id</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d5156b9d9a79d162c353c4aa9bc6840ad5c6257" datatype="html">
+ <source>The value does not match the pattern <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&lt;service_id&gt;[.&lt;realm_name&gt;.&lt;zone_name&gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <target>El valor no coincide con el patrón <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&amp;lt;id_servicio&amp;gt;[.&amp;lt;nombre_dominio&amp;gt;.&amp;lt;nombre_zona&amp;gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83d5d7edd8a0be253c4e93ad4c3efe86d9ac520f" datatype="html">
+ <source>Unmanaged</source>
+ <target>Sin gestionar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c15fa461935e0f600bc5d1660af1da67f024fc2a" datatype="html">
+ <source>Placement</source>
+ <target>Colocación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="863226cffd5b66a6fee9810a9282a5006d6ef576" datatype="html">
+ <source>Label</source>
+ <target>Etiqueta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06412bce0f4fe4311193e9763666089bf9d980da" datatype="html">
+ <source>Count</source>
+ <target>Recuento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f193722f1e788f14a823b89ac1794c3ba934f9f" datatype="html">
+ <source>Only that number of daemons will be created.</source>
+ <target>Solo se creará ese número de daemons.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee1a29cc658e4fa891be762d7bae96139b57c8f4" datatype="html">
+ <source>The value must be at least 1.</source>
+ <target>El valor debe ser al menos 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">369</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cb2741a46e3560f6bc6dfd99d385e86b08b26d72" datatype="html">
+ <source>Port</source>
+ <target>Puerto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a23ed3598cca5285606675b6cb2536a56b411ade" datatype="html">
+ <source>The value cannot exceed 65535.</source>
+ <target>El valor no puede ser superior a 65535.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">404</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d8ebdc326e6b9ff35feee3f762b7ab39c02d78f" datatype="html">
+ <source>-- No pools available --</source>
+ <target>-- No hay repositorios disponibles --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84b675705324741b954615fedf2417d4d873b0b6" datatype="html">
+ <source>Trusted IPs</source>
+ <target>IPs de confianza</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b543e7c787cc48c2938cbce2d14c6afea5a598df" datatype="html">
+ <source>Comma separated list of IP addresses.</source>
+ <target>Lista separada por comas de direcciones IP.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1039ea40da18a6453d9c1adc72a35aed099029d0" datatype="html">
+ <source>Please add the <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> IP addresses here, otherwise the iSCSI gateways can't be reached.</source>
+ <target>Añada aquí las direcciones IP de <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> o no se podrá acceder a las puertas de enlace iSCSI.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6265b64c17a1e19775769489bfd0b152fa1f3ba1" datatype="html">
+ <source>Virtual IP</source>
+ <target>IP virtual</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61893fde6e9e05a6b91619d501edaa7962b438ff" datatype="html">
+ <source>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</source>
+ <target>La dirección IP virtual y la subred (en notación CIDR) donde estará disponible el servicio de ingreso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">333</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ece04ddf7e96f445415ebd90d93c455e03e8cf53" datatype="html">
+ <source>Frontend Port</source>
+ <target>Puerto de interfaz de usuario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">352</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae6fd97454d184b374984c9ff808176ece54f0dd" datatype="html">
+ <source>The port used to access the ingress service.</source>
+ <target>El puerto usado para acceder al servicio de ingreso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1261eacf161f75efc9dfea84dd97b4a466b89aa1" datatype="html">
+ <source>Monitor Port</source>
+ <target>Puerto de monitor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4df6281ed630ba96f09790a46a7fe0ec0e666bb6" datatype="html">
+ <source>The port used by haproxy for load balancer status.</source>
+ <target>El puerto usado por haproxy para cargar el estado del equilibrador.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ce24ae1d792ed2846ba57e7ed6397a802caeff5" datatype="html">
+ <source>CIDR Networks</source>
+ <target>Redes CIDR</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">414</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7c13184af0c09e3bad77daa5f4869138708d26b2" datatype="html">
+ <source>A list of networks to identify which network interface to use for the virtual IP address.</source>
+ <target>Lista de redes para identificar qué interfaz de red se usará para la dirección IP virtual.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8fe73a4787b8068b2ba61f54ab7e0f9af2ea1fc9" datatype="html">
+ <source>Version</source>
+ <target>Versión</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a6855d17f6b9820bb9709870efdcc7da99552d3" datatype="html">
+ <source>-- Select SNMP version --</source>
+ <target>-- Seleccione la versión de SNMP --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">442</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a7369891e88cd613e45a39b55a282c97776d05f5" datatype="html">
+ <source>Destination</source>
+ <target>Destino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f09a5d334a73a4b5ba031d7fa65151cad5ec7133" datatype="html">
+ <source>Must be of the format hostname:port.</source>
+ <target>Debe tener el formato nombrehost:puerto.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b68c79ffe3af1db88180454fbc2fa880a51ccf52" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>hostname:port<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>El valor no coincide con el patrón: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>nombrehost:puerto<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">470</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c90ad98a026d781ab729911873767e549d78f99" datatype="html">
+ <source>Engine Id</source>
+ <target>ID de motor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">478</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d39d015ebd667fb6bddf08bb0e5b3faa6cf044c" datatype="html">
+ <source>Unique identifier for the device (in hex).</source>
+ <target>Identificador exclusivo del dispositivo (hexadecimal).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">480</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514cda7dc49062c5c532427245ce47c4954bc32" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>El valor no coincide con el patrón: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>debe ser hexadecimal y su longitud debe ser un múltiplo de 2 con un valor mínimo = 10 y máximo = 64.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b2d628c51192ade0044212b409c758c20f9c021" datatype="html">
+ <source>Auth Protocol</source>
+ <target>Protocolo de autenticación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc8bb2315a5101770a752b18e03b5c730539397c" datatype="html">
+ <source>-- Select auth protocol --</source>
+ <target>-- Seleccione el protocolo de autenticación --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">508</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6777f99fd13e03874afe26ba7289dc9fc211af04" datatype="html">
+ <source>Privacy Protocol</source>
+ <target>Protocolo de privacidad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70512b7c13bce85b3928920b29fafbd59a853383" datatype="html">
+ <source>-- Select privacy protocol --</source>
+ <target>-- Seleccione el protocolo de privacidad --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b48c81465d14465b95826b99e05acfabef1814c6" datatype="html">
+ <source>Credentials</source>
+ <target>Credenciales</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">541</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4ea0163c25c818aab982072b1b8d5ab585e9a5a" datatype="html">
+ <source>SNMP Community</source>
+ <target>Comunidad SNMP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">547</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="08c74dc9762957593b91f6eb5d65efdfc975bf48" datatype="html">
+ <source>Username</source>
+ <target>Nombre de usuario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="948758e1412bb2ecdb98e3a4f1cbb6d7458456f2" datatype="html">
+ <source>Encryption</source>
+ <target>Cifrado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">598</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e65610b5d940367f1ff6b57772b96e94e35fe202" datatype="html">
+ <source>SSL</source>
+ <target>SSL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">624</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e37e0d06148c7708e88b4a1eb412babbe1a4afc" datatype="html">
+ <source>Certificate</source>
+ <target>Certificado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">634</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="295ae4f632322098deca8a3ddfbc7aeaabb5423b" datatype="html">
+ <source>The SSL certificate in PEM format.</source>
+ <target>El certificado SSL en formato PEM.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">635</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464272c069fe56f6c50f41f426a25b2a42c95ba5" datatype="html">
+ <source>Invalid SSL certificate.</source>
+ <target>Certificado SSL no válido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">650</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0596d06bf1f8a15d4bfe56226971ecdd78013b1f" datatype="html">
+ <source>Private key</source>
+ <target>Clave privada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">659</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ded15dc55104994c0230189f34dff84a4955aafb" datatype="html">
+ <source>The SSL private key in PEM format.</source>
+ <target>La clave privada SSL en formato PEM.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">660</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19bdc1597d815b456793ff87c89af4257a85a103" datatype="html">
+ <source>Invalid SSL private key.</source>
+ <target>Clave privada SSL no válida.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">675</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3356018487523380058" datatype="html">
+ <source>service</source>
+ <target>servicio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2412938991511187011" datatype="html">
+ <source>There are no hosts.</source>
+ <target>No hay ningún host.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2594503755408511486" datatype="html">
+ <source>Filter hosts</source>
+ <target>Filtrar hosts</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5869780110608474933" datatype="html">
+ <source>Placement</source>
+ <target>Colocación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2956098160626271284" datatype="html">
+ <source>Running</source>
+ <target>En ejecución</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="013f48ee777d2e53e2bcba36e1a99fcbb7ef8cb6" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report configuration</source>
+ <target>Paso <x id="INTERPOLATION" equiv-text="{{ step }}"/> de 2: configuración de informe de telemetría</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a09b723a928774bff707973c99999dcf3d84a349" datatype="html">
+ <source>The telemetry module sends anonymous data about this Ceph cluster back to the Ceph developers to help understand how Ceph is used and what problems users may be experiencing.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> This data is visualized on <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>public dashboards<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> that allow the community to quickly see summary statistics on how many clusters are reporting, their total capacity and OSD count, and version distribution trends.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> The data being reported does <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>not<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> contain any sensitive data like pool names, object names, object contents, hostnames, or device serial numbers. It contains counters and statistics on how the cluster has been deployed, the version of Ceph, the distribution of the hosts and other parameters which help the project to gain a better understanding of the way Ceph is used. The data is sent secured to <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> and <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (device report).</source>
+ <target>El módulo de telemetría envía datos anónimos sobre este clúster de Ceph a los desarrolladores de Ceph para que les ayuden a comprender cómo se usa Ceph y qué problemas pueden experimentar los usuarios.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Los datos se muestran en <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>consolas públicas<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> que permiten a la comunidad ver rápidamente un resumen de las estadísticas sobre cuántos clústeres envían información, su capacidad total y el número de OSD y las tendencias de distribución de la versión.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>No<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> se informa sobre ningún dato sensible como nombres de repositorio, nombres de objetos, contenidos de objetos, nombres de host o números de serie de dispositivos. Los datos contienen recuentos y estadísticas sobre cómo se ha distribuido el clúster, la versión de Ceph, la distribución de los host y otros parámetros que ayudan al proyecto a entender mejor cómo se usa Ceph. Los datos se envían de forma segura a <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> y <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (informe de dispositivo).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">14,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c95505b5a74151a0c235b19b9c41db7983205ba7" datatype="html">
+ <source>Deactivate</source>
+ <target>Desactivar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19" datatype="html">
+ <source>Channels</source>
+ <target>Canales</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e25b17c0b4ef361b6a05aaec2bbd2b7e86680458" datatype="html">
+ <source>The telemetry report is broken down into several &quot;channels&quot;, each with a different type of information that can be configured below.</source>
+ <target>El informe de telemetría se divide en numerosos &quot;canales&quot;. Cada uno ofrece un tipo distinto de información que se puede configurar abajo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">32,33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380ab580741bec31346978e7cab8062d6970408d" datatype="html">
+ <source>Basic</source>
+ <target>Básica</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd898057f0add35258a5fb5c90d792c5e2147452" datatype="html">
+ <source>Includes basic information about the cluster:</source>
+ <target>Incluye información básica sobre el clúster:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da213e9ba8a86b453d04f794f58c9803f7b062b1" datatype="html">
+ <source>Capacity of the cluster</source>
+ <target>Capacidad del clúster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d5fe31d9e13239bdd223d0bbd289a1b1903e86" datatype="html">
+ <source>Number of monitors, managers, OSDs, MDSs, object gateways, or other daemons</source>
+ <target>El número de monitores, gestores, OSD, MDS, puertas de enlace de objetos u otros daemons.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a3eb7834b4baf412f8863d14883972897d9acb7" datatype="html">
+ <source>Software version currently being used</source>
+ <target>Versión del software que se usa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34881ae65482ffa74ccb4043fb2622e48ed146d5" datatype="html">
+ <source>Number and types of RADOS pools and CephFS file systems</source>
+ <target>Número y tipos de repositorios RADOS y sistemas de archivos CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="696f8f5ea7a9cf6125b9a3af160981fda363552d" datatype="html">
+ <source>Names of configuration options that have been changed from their default (but not their values)</source>
+ <target>Nombres de las opciones de configuración que se han cambiado desde las opciones por defecto (pero no sus valores)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34292940316300d09abe5e675d452fae199f626b" datatype="html">
+ <source>Crash</source>
+ <target>Detención por fallo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7620e332b7dea1e832158e85847255eb4d9e6bbc" datatype="html">
+ <source>Includes information about daemon crashes:</source>
+ <target>Incluye información sobre las detenciones por fallo del daemon:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1aa4306a6e840fe35b70c9b07d38ce85f281cfa" datatype="html">
+ <source>Type of daemon</source>
+ <target>Tipo de daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4f2cbedb4b14b68bc9f390e3391445c1b6682da" datatype="html">
+ <source>Version of the daemon</source>
+ <target>Versión del daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d62603cdc75645ea873fc8f7f69c32b5f4a2aa9" datatype="html">
+ <source>Operating system (OS distribution, kernel version)</source>
+ <target>Sistema operativo (distribución de SO, versión del núcleo)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84facf84a73631d66e9a4e0bc1c40097b9d14742" datatype="html">
+ <source>Stack trace identifying where in the Ceph code the crash occurred</source>
+ <target>Seguimiento de pila donde se identifica en qué lugar del código de Ceph se ha producido la detención por fallo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea64d4177bd648e1a20c92669e6857762b811d8c" datatype="html">
+ <source>Device</source>
+ <target>Dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4bc37bcbbcea881a269b4063b3d93dec8ee67d5" datatype="html">
+ <source>Includes information about device metrics like anonymized SMART metrics.</source>
+ <target>Incluye información sobre las métricas del dispositivo como métricas SMART anonimizadas.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37de70e8ba539187d0171a38dad2a63c323096eb" datatype="html">
+ <source>Ident</source>
+ <target>Identificación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b126025440f118cd02ce78362d61a5001c27617" datatype="html">
+ <source>Includes user-provided identifying information about the cluster:</source>
+ <target>Incluye información de identificación proporcionada por el usuario sobre el clúster:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62c6e9aecff7e04ef7d36fdee4ab4fb285a7a2b5" datatype="html">
+ <source>Contact Information</source>
+ <target>Información de contacto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61ba9a84051b3f470122e59cf5a746552b378269" datatype="html">
+ <source>Submitting any contact information is completely optional and disabled by default.</source>
+ <target>Enviar cualquier información de contacto es completamente opcional y la función está inhabilitada por defecto.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34746fb1c7f3d2194d99652bdff89e6e14c9c4f4" datatype="html">
+ <source>Contact</source>
+ <target>Contacto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="632cac1e025b77b2d77fed16ad22a410ddacab9e" datatype="html">
+ <source>My first Ceph cluster</source>
+ <target>Mi primer clúster de Ceph</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3a58c8a81b9ffda26a154eae25a422c9f7de37b" datatype="html">
+ <source>Organization</source>
+ <target>Organización</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e8fda44e2c5bb51860f26cd9c2730f9ae1db9869" datatype="html">
+ <source>Organization name</source>
+ <target>Nombre de la organización</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d49310535abb3792d8c9c991dd0d990d73d29af" datatype="html">
+ <source>Interval</source>
+ <target>Intervalo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91317562c9dfefbdd5973faf11d217f571d073c7" datatype="html">
+ <source>The module compiles and sends a new report every 24 hours by default. You can adjust this interval by setting a different number of hours.</source>
+ <target>El módulo compila y envía un informe nuevo cada 24 horas por defecto. Puede ajustar este intervalo definiendo otro número de horas.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">185,186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a12cf4cf71ef3161a024382ab542cf0eba094504" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to 8.</source>
+ <target>El valor introducido es muy bajo. Debe ser mayor o igual que 8.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a92e437fac14b4010c4515b31c55a311d026a57f" datatype="html">
+ <source>Proxy</source>
+ <target>Proxy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6de03357358c7eff62aca486508bb5c2046e0669" datatype="html">
+ <source>If the cluster cannot directly connect to the configured telemetry endpoint (default telemetry.ceph.com), you can configure a HTTP/HTTPS proxy server by e.g. adding https://10.0.0.1:8080</source>
+ <target>Si el clúster no se puede conectar directamente con el puesto final de telemetría configurado (telemetry.ceph.com por defecto), puede configurar un servidor de proxy HTTP/HTTPS, por ejemplo, añadiendo https://10.0.0.1:8080</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5687a733af051bfca97dbffba282e39fbb9b8c8f" datatype="html">
+ <source>You can also include a user:pass if needed e.g. https://ceph:telemetry@10.0.0.1:8080</source>
+ <target>También puede incluir un user:pass si fuera necesario, por ejemplo, https://ceph:telemetry@10.0.0.1:8080</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e6430c68df43ea65e4145972b01186fba40f26a" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Note:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> By clicking 'Next' you will first see a preview of the report content before you can activate the automatic submission of your data.</source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Nota:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> al hacer clic en Siguiente, verá una vista previa del contenido del informe y podrá activar el envío automático de los datos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">219,220</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d8d878f8d60905e1306c225716305a331b784c8" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report preview</source>
+ <target>Paso <x id="INTERPOLATION" equiv-text="{{ step }}"/> de 2: vista previa del informe de telemetría</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e23d0064b6474f309c74e1c928cc0920f479d9a5" datatype="html">
+ <source>Report ID <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <target>ID de informe <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">249,252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4060e92658964e356a0992a900c8aa811c2cfec0" datatype="html">
+ <source>A randomized UUID to identify a particular cluster over the course of several telemetry reports.</source>
+ <target>Un UUID aleatorizado para identificar un clúster concreto durante varios informes de telemetría.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60900bc663571f852a04950a123508b106d97204" datatype="html">
+ <source>Report preview <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <target>Vista previa del informe <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">267,270</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3de417f739c336284c42904552e81e8d852daecc" datatype="html">
+ <source>The actual telemetry data that will be submitted.</source>
+ <target>Los datos de telemetría reales que se enviarán.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="933a2b6f087670ff42c95876e6ecfb2faa3e3867" datatype="html">
+ <source>I agree to my telemetry data being submitted under the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Community Data License Agreement - Sharing - Version 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></source>
+ <target>Acepto que mis datos de telemetría se envíen bajo la licencia <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Community Data License Agreement - Sharing - versión 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">304</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8293060085588842566" datatype="html">
+ <source>The Telemetry module has been configured and activated successfully.</source>
+ <target>El módulo de telemetría se ha configurado y activado correctamente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5380636888677486786" datatype="html">
+ <source>An Error occurred while updating the Telemetry module configuration. Please Try again</source>
+ <target>Error al actualizar la configuración del módulo de telemetría. Vuelva a intentarlo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2bcd3296d2850de762fb943060b7e086a893181" datatype="html">
+ <source>Health</source>
+ <target>Estado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61e0f26d843eec0b33ff475e111b0c2f7a80b835" datatype="html">
+ <source>Statistics</source>
+ <target>Estadísticas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73caac4265ea7314ff061e5a1d78a6361a6dd3b8" datatype="html">
+ <source>Cluster Status</source>
+ <target>Estado del clúster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="624f596cc3320f5e0a0d7c7346c364e5af9bdd8c" datatype="html">
+ <source>Monitors</source>
+ <target>Monitores</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9183778f2c6473d7ccb080f651caa01faaf70c" datatype="html">
+ <source>OSDs</source>
+ <target>OSDs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c34287a0423968dac8a41463b80855a0ff789403" datatype="html">
+ <source>Managers</source>
+ <target>Gestores</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="946ac5dea9921dc09d7b0a63b89535371f283b19" datatype="html">
+ <source>Object Gateways</source>
+ <target>Instancias de Object Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff03fa5bcf37c4da46ad736c1f7d03f959e8ba9a" datatype="html">
+ <source>Metadata Servers</source>
+ <target>Servidores de metadatos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d817609ba4993eba859409ab71e566168f4d5f5a" datatype="html">
+ <source>iSCSI Gateways</source>
+ <target>Puertas de enlace iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ce9dfdc6dccb28dc75a78c704e09dc18fb02dcfa" datatype="html">
+ <source>Capacity</source>
+ <target>Capacidad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f383269db2d32cccee9e936fe549dccb9fdbf4" datatype="html">
+ <source>Raw Capacity</source>
+ <target>Capacidad en bruto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498a109c6e9e94f1966de01aa0326f7f0ac6fb52" datatype="html">
+ <source>PG Status</source>
+ <target>Estado del grupo de colocación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5f8a813f91a11af99132e4beafc136cfc13d73b" datatype="html">
+ <source>PGs per OSD</source>
+ <target>Grupos de colocación por OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32efd1c3f70e3c5244239de97a2cc95d98534a14" datatype="html">
+ <source>Client Read/Write</source>
+ <target>Lectura/escritura de cliente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="52213660b2454d139ada3079a42ec6caf3c3c01e" datatype="html">
+ <source>Client Throughput</source>
+ <target>Rendimiento del cliente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="275485415092cbae3a9f3cbb786ebe283cacfdd5" datatype="html">
+ <source>Recovery Throughput</source>
+ <target>Rendimiento de recuperación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35416fcdf9cb33d2b299d3f2028c390454b55d02" datatype="html">
+ <source>Scrubbing</source>
+ <target>Depuración</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="44ecac93d67c6a671198091c2270354f80322327" datatype="html">
+ <source><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> See <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>Logs<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for more details.</source>
+ <target><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> Consulte los <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>registros<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> para obtener más detalles.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520247697658334435" datatype="html">
+ <source>Reads</source>
+ <target>Lecturas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5947645586591788199" datatype="html">
+ <source>/s</source>
+ <target>/s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7527163811128350993" datatype="html">
+ <source>Writes</source>
+ <target>Escrituras</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7684088941299429132" datatype="html">
+ <source>IOPS</source>
+ <target>E/S por segundo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81585474102700882" datatype="html">
+ <source>Used</source>
+ <target>Usado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">179</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8695656831075719969" datatype="html">
+ <source>Avail.</source>
+ <target>Dispon.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6352596107300820129" datatype="html">
+ <source>Clean</source>
+ <target>Limpio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4016774570903735270" datatype="html">
+ <source>Working</source>
+ <target>En curso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4467323362722952678" datatype="html">
+ <source>Unknown</source>
+ <target>Desconocido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">218</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7790772795962334429" datatype="html">
+ <source>Healthy</source>
+ <target>En buen estado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4708847204147472247" datatype="html">
+ <source>Misplaced</source>
+ <target>Mal colocado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3120522496446378904" datatype="html">
+ <source>Degraded</source>
+ <target>Degradado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8047698491745405137" datatype="html">
+ <source>Unfound</source>
+ <target>No se encuentra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81117556780777231" datatype="html">
+ <source>objects</source>
+ <target>objetos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795e8a00db46b750113d5db93e8d97e2b3079894" datatype="html">
+ <source>For an overview of <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/> widgets click <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></source>
+ <target>Para ver un resumen de los widgets de <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/>, haga clic <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">21,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16bd21c1b48036d54c6a595f5cff2540cfba7f60" datatype="html">
+ <source>here</source>
+ <target>aquí</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8515973702474791807" datatype="html">
+ <source>up</source>
+ <target>activo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4223604072115719661" datatype="html">
+ <source>no filesystems</source>
+ <target>sin sistemas de archivos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2078241808113697591" datatype="html">
+ <source>active</source>
+ <target>activo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3232506912392089107" datatype="html">
+ <source>standby</source>
+ <target>reserva</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576716133013765863" datatype="html">
+ <source>standby daemons</source>
+ <target>daemons en reserva</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3629620351427988554" datatype="html">
+ <source>active daemon</source>
+ <target>daemon activo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5954854563228355745" datatype="html">
+ <source>standbyReplay</source>
+ <target>standbyReplay</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7329683463736701292" datatype="html">
+ <source>n/a</source>
+ <target>n/d</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/not-available.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8271970016544066882" datatype="html">
+ <source><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (quorum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</source>
+ <target><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (quórum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mon-summary.pipe.ts</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6489441800790477240" datatype="html">
+ <source>total</source>
+ <target>total</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5965118847182332588" datatype="html">
+ <source>near full</source>
+ <target>casi lleno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="268166731974484199" datatype="html">
+ <source>full</source>
+ <target>todos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47116253e36f4e38a97ba41b2d3122c6c15ab904" datatype="html">
+ <source>Clients (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</source>
+ <target>Clientes (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5159814115056353668" datatype="html">
+ <source>Addresses</source>
+ <target>Destinatarios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1811797298582428088" datatype="html">
+ <source>Access Type</source>
+ <target>Tipo de acceso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3575940435199094878" datatype="html">
+ <source>Squash</source>
+ <target>Reducir privilegios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2944102521023817891" datatype="html">
+ <source>Cluster</source>
+ <target>Clúster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91772203889648189" datatype="html">
+ <source>NFS Protocol</source>
+ <target>Protocolo NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907766170797643122" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1032539711043211945" datatype="html">
+ <source>Transport</source>
+ <target>Transportar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2489852208080013495" datatype="html">
+ <source>Storage Backend</source>
+ <target>Motor de almacenamiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8440421106569981118" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4095248496892792741" datatype="html">
+ <source>CephFS User</source>
+ <target>Usuario de CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2535727951299201687" datatype="html">
+ <source>CephFS Filesystem</source>
+ <target>Sistemas de archivos CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2169401160512036026" datatype="html">
+ <source>Security Label</source>
+ <target>Etiqueta de seguridad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3671149880069127721" datatype="html">
+ <source>Object Gateway</source>
+ <target>Object Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1643028261508790" datatype="html">
+ <source>Object Gateway User</source>
+ <target>Usuario de Object Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2dae0bda66f6a349444951c0379c28cda47d6d1" datatype="html">
+ <source>Any client can access</source>
+ <target>Cualquier cliente puede acceder</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7882f2edb1d4139800b276b6b0bbf5ae0b2234ef" datatype="html">
+ <source>Addresses</source>
+ <target>Destinatarios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f3f74c0f6925826cb2188576391c0da01a23f0" datatype="html">
+ <source>Must contain one or more comma-separated values</source>
+ <target>Debe contener uno o varios valores separados por comas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb5b2073697f3f4378c44a49b7524934c9268f4" datatype="html">
+ <source>For example:</source>
+ <target>Por ejemplo:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f969c655b3fbe4fba7e277caf4cd2c459f9fca5" datatype="html">
+ <source>Access Type</source>
+ <target>Tipo de acceso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28952831a284cfe2b4fc39ca610e80b52598905a" datatype="html">
+ <source>Squash</source>
+ <target>Reducir privilegios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0660ae339068979854ade34a96546980723dede3" datatype="html">
+ <source>Add clients</source>
+ <target>Añadir clientes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8571141481686087364" datatype="html">
+ <source>(inherited from global config)</source>
+ <target>(se hereda de la configuración global)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3563954518111128118" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- Seleccione el tipo de acceso --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3802199399355755843" datatype="html">
+ <source>inherited from global config</source>
+ <target>se hereda de la configuración global</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8729531250118136719" datatype="html">
+ <source>-- Select what kind of user id squashing is performed --</source>
+ <target>-- Seleccione el tipo de reducción de privilegios de ID de usuario que se va a realizar --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4d1dd59b039ad818d9da7e29a773e10e41d9821" datatype="html">
+ <source>Cluster</source>
+ <target>Clúster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="625f8f0f3e5b7c92651606d77484ff3d07b3c12b" datatype="html">
+ <source>This is the ID of an NFS Service.</source>
+ <target>Este es el ID de un servicio NFS.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="135b91a2d908d5814b782695470a6a786c99d9d2" datatype="html">
+ <source>-- No cluster available --</source>
+ <target>-- No hay ningún clúster disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c501dba379f566885919240ea277b5bc10c14d18" datatype="html">
+ <source>-- Select the cluster --</source>
+ <target>-- Seleccione el clúster --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7bd3ad665c398c7fe97230ab59e67370653a82" datatype="html">
+ <source>This field is required. To create a new NFS cluster, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>add a new NFS Service<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <target>Este campo es obligatorio. Para crear un clúster NFS nuevo, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>añada un nuevo servicio NFS<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">41,43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3f6ba7fe84d6508705cdfe234f0fcc8ff85c9cf" datatype="html">
+ <source>Storage Backend</source>
+ <target>Motor de almacenamiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6fee356d1db954255a56d8169405a89595246b9" datatype="html">
+ <source>-- Select the storage backend --</source>
+ <target>-- Seleccione el motor de almacenamiento --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3c2793dd2ef56954f872142d5ec1becb84c0fe1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="796e42bec8a6996607cf1f3e80235b86d695804a" datatype="html">
+ <source>Volume</source>
+ <target>Volumen</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee3ba0ab5f0ccd597b3e44021c71e9aaad14df0a" datatype="html">
+ <source>-- No CephFS filesystem available --</source>
+ <target>-- No hay ningún sistema de archivos CephFS disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="764c57812558b1ae66c5eec95d7efd2b1bf761e3" datatype="html">
+ <source>-- Select the CephFS filesystem --</source>
+ <target>-- Seleccione el sistema de archivos CephFS --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="957512d0321f73e9f115bce1bd823fa635170c41" datatype="html">
+ <source>Security Label</source>
+ <target>Etiqueta de seguridad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="65ce0fa4da1ed55e658aeb31d1644a29f06bb342" datatype="html">
+ <source>Enable security label</source>
+ <target>Habilitar etiqueta de seguridad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e808f804130c7b6ff719509cbc06ebb27393a48" datatype="html">
+ <source>CephFS Path</source>
+ <target>Ruta de CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1338c2f83e49ea7f2fc04e9fe90c5d330b7a10f" datatype="html">
+ <source>A path in a CephFS file system.</source>
+ <target>Una vía de un sistema de archivos CephFS.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ecc0107badb6625466aaa3f975b5c05276f432f" datatype="html">
+ <source>Path need to start with a '/' and can be followed by a word</source>
+ <target>La ruta debe empezar por &quot;/&quot; y puede ir seguida de una palabra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f9d8bd873c34c5ab2d4d0cf995fe5183ab25f6e" datatype="html">
+ <source>The path does not exist in the selected volume.</source>
+ <target>La vía no existe en el volumen seleccionado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd197d7773cef10f368f08c53b47979c3df1f22d" datatype="html">
+ <source>Bucket</source>
+ <target>Papelera</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ca90b4b16347ef7017967915e8624472976c85c" datatype="html">
+ <source>The bucket does not exist or is not in the default realm (if multiple realms are configured). To continue, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>create a new bucket<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <target>La papelera no existe o no está en el dominio por defecto (si hay varios dominios configurados). Para continuar, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>cree una papelera nueva<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bee6900143996c0e908a10564532eba3da0b30fb" datatype="html">
+ <source>NFS Protocol</source>
+ <target>Protocolo NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5043c0921e709935ab026bb3253ffe1f159fca1" datatype="html">
+ <source>NFSv4</source>
+ <target>NFSv4</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d2c39708a32910f89701dd7e1cfb9ec1c195768" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1f8be2ae25947bec0b84c2338201580ea053f34e" datatype="html">
+ <source>The position that this <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> export occupies in the <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo FS<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (it must be unique).</source>
+ <target>La posición que esta exportación <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> ocupa en <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo FS<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (debe ser exclusivo).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">241,242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3af55f7fd5b1d9e5a53e030c80116dc635bfb9f" datatype="html">
+ <source>By using different Pseudo options, the same Path may be exported multiple times.</source>
+ <target>Al usar distintas opciones de Pseudo, la misma Ruta se puede exportar varias veces.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5eb719aa900fed3f9d4a1d74bcc158f07f67f684" datatype="html">
+ <source>The pseudo is already in use by another export.</source>
+ <target>Pseudo ya está en uso en otra exportación.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddf98fcdeeb17643db020d54f42b5e56b5f9a52a" datatype="html">
+ <source>Pseudo needs to start with a '/' and can't contain any of the following: &gt;, &lt;, |, &amp;, ( or ).</source>
+ <target>Pseudo debe empezar con &quot;/&quot; y no puede incluir estos caracteres: &gt;, &lt;, |, &amp;, ( ni ).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="27eb35c4b4ac08781a7253a2ab40f8f7d957ba51" datatype="html">
+ <source>-- No access type available --</source>
+ <target>-- No hay ningún tipo de acceso disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">280</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="509ce016c9110a54028dafd741f15ceacbe74b5a" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- Seleccione el tipo de acceso --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67ce207d0b7eada1fe3d3187a39ba0c07be76b6c" datatype="html">
+ <source>The Object Gateway NFS backend has a number of limitations which will seriously affect applications writing to the share. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> for details before enabling write access.</source>
+ <target>El motor de Object Gateway NFS tiene varias limitaciones que afectan seriamente a las aplicaciones que escriben en el recurso compartido. Consulte <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> para obtener más información antes de habilitar el acceso de escritura.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">293,296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4deda03573eaaff77e63f6a238a1f0ca7816950a" datatype="html">
+ <source>-- No squash available --</source>
+ <target>-- No hay ninguna reducción de privilegios disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">321</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a0e82a4da88e7fdf270444f838d45849676e9d4b" datatype="html">
+ <source>--Select what kind of user id squashing is performed --</source>
+ <target>-- Seleccione el tipo de reducción de privilegios de ID de usuario que se va a realizar --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d01b7c3f7f06712c53d054cfbe4f53d446b038e8" datatype="html">
+ <source>Transport Protocol</source>
+ <target>Protocolo de transporte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2a6ad6e8bc315f07911722c05767ac79c136d99" datatype="html">
+ <source>UDP</source>
+ <target>UDP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">349</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c030f11e0aae9b24d2c048c57f29f590be621df" datatype="html">
+ <source>TCP</source>
+ <target>TCP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">359</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f84d7fd4d52eb5b2229b632ef5119dac63d5597" datatype="html">
+ <source>No user id squashing is performed.</source>
+ <target>No se realiza ninguna reducción de privilegios de ID de usuario.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">378</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb1d148107e36852325106a518385b1b0de28835" datatype="html">
+ <source>uid 0 and gid 0 are squashed to the Anonymous_Uid and Anonymous_Gid gid 0 in alt_groups lists is also squashed.</source>
+ <target>Los privilegios de uid 0 y gid 0 se reducen a Anonymous_Uid. Los privilegios de Anonymous_Gid gid 0 también se reducen en las listas alt_groups.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">382</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1309d6f67955799863337b201413faa61a175ddb" datatype="html">
+ <source>uid 0 and gid of any value are squashed to the Anonymous_Uid and Anonymous_Gid alt_groups lists is discarded.</source>
+ <target>Los privilegios de uid 0 y gid de cualquier valor se reducen a Anonymous_Uid. Las listas alt_groups de Anonymous_Gid se descartan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85f23d5c9b57dc78dda4150d13aa3b99e985350b" datatype="html">
+ <source>All users are squashed.</source>
+ <target>Se reducen los privilegios de todos los usuarios.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2691935247101074756" datatype="html">
+ <source>NFS export</source>
+ <target>Exportación de NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8727258243239498387" datatype="html">
+ <source><x id="PH" equiv-text="fsalItem.descr"/> backend is not available. <x id="PH_1" equiv-text="errorMessage"/></source>
+ <target>El motor de <x id="PH" equiv-text="fsalItem.descr"/> no está disponible. <x id="PH_1" equiv-text="errorMessage"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2772848515253260635" datatype="html">
+ <source>Error while retrieving paths.</source>
+ <target>Error al recuperar las vías.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5239928491238988595" datatype="html">
+ <source>Error while retrieving bucket names.</source>
+ <target>Error al recuperar los nombres de papeleras.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="734c9905951a774870497c5aaae8e3ee833b6196" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2190548d236ca5f7bc7ab2bca334b860c5ff2ad4" datatype="html">
+ <source>Object Gateway</source>
+ <target>Object Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca53d681a9892d6fdbb57ee9676582186515e961" datatype="html">
+ <source>Performance counters not available</source>
+ <target>Los contadores de rendimiento no están disponibles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="490e15ecc922965b6d8194754c87c5583aa071f3" datatype="html">
+ <source>The name can only consist of alphanumeric characters, dashes and underscores.</source>
+ <target>El nombre solo puede tener caracteres alfanuméricos, guiones y guiones bajos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9edc2b494e660618af3e5225f68d40b7ca67629c" datatype="html">
+ <source>The chosen erasure code profile name is already in use.</source>
+ <target>El nombre del perfil de código de borrado que ha elegido ya está en uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35a4206db3105ed03e0dd799e1642b75b78123e8" datatype="html">
+ <source>Root</source>
+ <target>Raíz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf425784c7073c7e7f7c1bb90c2c19db7e751db2" datatype="html">
+ <source>Failure domain type</source>
+ <target>Tipo de dominio de error</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72396a9565cf644d1fe1b21b790c4243ee270986" datatype="html">
+ <source>Device class</source>
+ <target>Clase de dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d80e0c07bfea1b693a33ef2245007de92a6780" datatype="html">
+ <source>Let Ceph decide</source>
+ <target>Dejar que Ceph decida</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101611937243846632" datatype="html">
+ <source>Crush Rule</source>
+ <target>Regla de CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef9ff0e6227947b48dfab4ac39ade04af758913b" datatype="html">
+ <source>Plugin</source>
+ <target>Complemento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd69b31bce8f630eac1d4762b0bbcf72ce19d193" datatype="html">
+ <source>Data chunks (k)</source>
+ <target>Porciones de datos (k)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0d26a6172d32cb81218fe2103c54a818cbc1189" datatype="html">
+ <source>Must be equal to or greater than 2.</source>
+ <target>Debe ser igual o mayor que 2.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ba6f4800642eba4e8b056aa7167554c3afa8db0" datatype="html">
+ <source>Chunks (k+m) have exceeded the available OSDs of <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>.</source>
+ <target>Las pociones (k+m) han superado el número disponible de OSDs de <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="86fca2f788ce986eef835cd7ef8dfc9ae22447a4" datatype="html">
+ <source>For an equal distribution k has to be a multiple of (k+m)/l.</source>
+ <target>Para que la distribución sea uniforme, k debe ser un múltiplo de (k+m)/l.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8dd4bc172f1adc4afadaec291e465b082909148d" datatype="html">
+ <source>K has to be equal to or greater than m in order to recover data correctly through c.</source>
+ <target>K tiene que ser igual o mayor que m para poder recuperar datos correctamente mediante c.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2e5b0e6d0dba31c59f946392699a0a6c4dd9b83" datatype="html">
+ <source>Distribution factor: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></source>
+ <target>Factor de distribución: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dab3a299ead121169b8e08ed618c3b6a2f66691b" datatype="html">
+ <source>Coding chunks (m)</source>
+ <target>Porciones de código (m)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e2773e5bd4948193f18f2361d663ecc3988c656" datatype="html">
+ <source>Must be equal to or greater than 1.</source>
+ <target>Debe ser igual o mayor que 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">146</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cde4c945a49a260c0a47bcc7cd956846930a5f7" datatype="html">
+ <source>Durability estimator (c)</source>
+ <target>Estimador de durabilidad (c)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ec9ff9931f8ea1201792d6a01bf9a47b283d692" datatype="html">
+ <source>C has to be equal to or lower than m as m defines the amount of chunks that can be used.</source>
+ <target>C tiene que ser igual o menor que m, porque m define el número de porciones que se pueden usar.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35594fe66657ea07b5b5f560927f78e81a229996" datatype="html">
+ <source>Helper chunks (d)</source>
+ <target>Porciones de Ayudante (d)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0c250a8d281291273ed3504ade19ca6537e4d9a" datatype="html">
+ <source>Set d manually or use the plugin's default calculation that maximizes d.</source>
+ <target>Defina d manualmente o use el cálculo por defecto del complemento que maximiza d.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4304a5cd95742db0f81c3bdf29aa96bf3b0ca13d" datatype="html">
+ <source>D is automatically updated on k and m changes</source>
+ <target>D se actualiza automáticamente cuando k y m cambian.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06a67d52427b12df2b3d439be0e1342ac72aeb5c" datatype="html">
+ <source>D can be set from <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> to <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></source>
+ <target>D se puede definir de <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> a <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4f8831d3bd6401e87710c4e3ee844f5efbf5de3" datatype="html">
+ <source>D can only be set to <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></source>
+ <target>D solo se puede definir como <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5d7aacffce2c6032c3ae9ef4d1b3847a926440b" datatype="html">
+ <source>D has to be greater than k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>).</source>
+ <target>D tiene que ser mayor que k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fd745d614884edc23c7ac9ad8aba9655f3793ac2" datatype="html">
+ <source>D has to be lower than k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>).</source>
+ <target>D tiene que ser menor que k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">199</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af668c2a095a979ea2b4e43cd82c2120ab56c21c" datatype="html">
+ <source>Locality (l)</source>
+ <target>Localización (l)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="200fea08b63ae8d60cdbf33ffd2636159e87dc1e" datatype="html">
+ <source>Can't split up chunks (k+m) correctly with the current locality.</source>
+ <target>Con la localidad actual, no es posible dividir las porciones (k+m) correctamente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319ac5d692d11da686782159bd70e0b705c228ed" datatype="html">
+ <source>Locality groups: <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></source>
+ <target>Grupos de localidad :<x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">230</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d455a110bf6d2235e314e295ce1dfeee93d3dff2" datatype="html">
+ <source>Crush failure domain</source>
+ <target>Dominio de error de CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74a495f041f7dd102eee5c0bbc9e03083b538ae" datatype="html">
+ <source>Crush Locality</source>
+ <target>Localización de CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2f14a73f7a6e94479f67423cc51102da8d6f524" datatype="html">
+ <source>None</source>
+ <target>Ninguna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="363a99d62822b92913a4cce196d47f32c1258e2f" datatype="html">
+ <source>Scalar mds</source>
+ <target>MDS escalar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2981733b912b693a9dd9d915d6d34f4692cc874a" datatype="html">
+ <source>Technique</source>
+ <target>Técnica</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0098b6e47b04ec817361f384ce81d454ba5c0bb" datatype="html">
+ <source>Packetsize</source>
+ <target>Tamaño del paquete</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0252cd81ca54d0a2f69ec9ccf4248e73df5aa4a" datatype="html">
+ <source>Crush root</source>
+ <target>Raíz de CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">351</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1548d5c76f0406ddd1ba3c557e1e6db22e95b340" datatype="html">
+ <source>Crush device class</source>
+ <target>Clase de dispositivo de CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3f657ffa19dc6ac504b83c86209709522dcf065" datatype="html">
+ <source>Available OSDs: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></source>
+ <target>OSD disponibles: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03d84645f6e019c5a43909bbf2ea1696ee88332c" datatype="html">
+ <source>Directory</source>
+ <target>Directorio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1354845268685595937" datatype="html">
+ <source>EC Profile</source>
+ <target>Perfil de código de borrado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3938a411d76796f8ae73b72ea4c77661207453bd" datatype="html">
+ <source>Cache Tiers Details</source>
+ <target>Detalles de niveles de caché</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="991790413700941336" datatype="html">
+ <source>Cache Mode</source>
+ <target>Modo de caché</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9133265273798382582" datatype="html">
+ <source>Min Evict Age</source>
+ <target>Antigüedad mínima de expulsión</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7172092927403263656" datatype="html">
+ <source>Min Flush Age</source>
+ <target>Antigüedad mínima de vaciado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8096695869347792608" datatype="html">
+ <source>Target Max Bytes</source>
+ <target>Número máximo de bytes de destino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8854126142886240282" datatype="html">
+ <source>Target Max Objects</source>
+ <target>Número máximo de objetos de destino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617215542453015899" datatype="html">
+ <source>No applications added</source>
+ <target>No se ha añadido ninguna aplicación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4895689494338215646" datatype="html">
+ <source>Applications limit reached</source>
+ <target>Se ha alcanzado el límite de aplicaciones</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7322343326526084293" datatype="html">
+ <source>A pool can only have up to four applications definitions.</source>
+ <target>Un repositorio solo puede tener hasta cuatro definiciones de aplicaciones.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1393735257943344790" datatype="html">
+ <source>Allowed characters '_a-zA-Z0-9'</source>
+ <target>Caracteres permitidos: _, a-z, A-Z y 0-9</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5520683885127790121" datatype="html">
+ <source>Maximum length is 128 characters</source>
+ <target>La longitud máxima es 128 caracteres</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587418377972855060" datatype="html">
+ <source>Filter or add applications'</source>
+ <target>Filtrar o añadir aplicaciones</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5188881899285829380" datatype="html">
+ <source>Add application</source>
+ <target>Añadir aplicación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16e113230b6b0d3165e076300880542bac7c8138" datatype="html">
+ <source>The chosen Ceph pool name is already in use.</source>
+ <target>El nombre del repositorio de Ceph que ha elegido ya está en uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c75b132bef7b29fa5171768303c4b96e34ccaf68" datatype="html">
+ <source>It's not possible to create an RBD pool with '/' in the name. Please change the name or remove 'rbd' from the applications list.</source>
+ <target>No es posible crear un repositorio RBD si incluye el carácter &quot;/&quot; en el nombre. Cambie el nombre o elimine &quot;rbd&quot; de la lista de aplicaciones.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">34,35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="171dc6d5c6bc4615d99778b0088cae80fd00bd10" datatype="html">
+ <source>Pool name can only contain letters, numbers, '.', '-', '_' or '/'.</source>
+ <target>El nombre del repositorio solo puede contener letras, números y estos caracteres: &quot;.&quot;, &quot;-&quot;, &quot;_&quot; y &quot;/&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b85c657469e5ec8231c3de99b22f437bc01ffde5" datatype="html">
+ <source>Pool type</source>
+ <target>Tipo de repositorio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="526c5443254c3b126eedb264840ffe827727bfd3" datatype="html">
+ <source>-- Select a pool type --</source>
+ <target>-- Seleccione un tipo de repositorio --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abfbe47b630929d93c7343dc154599c2e59330a" datatype="html">
+ <source>PG Autoscale</source>
+ <target>Autoescala de grupo de colocación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0aa21053410a94aa61d16985a4e95fd65523430d" datatype="html">
+ <source>Placement groups</source>
+ <target>Grupos de colocación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6301f1391d726f8f450bb358058534db19541ca9" datatype="html">
+ <source>At least one placement group is needed!</source>
+ <target>Se necesita al menos un grupo de colocación.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba9469a1ce6ed36e039c1f67247c8c81a5c71449" datatype="html">
+ <source>Your cluster can't handle this many PGs. Please recalculate the PG amount needed.</source>
+ <target>El clúster no puede gestionar tantos grupos de colocación. Vuelva a calcular la cantidad que necesita.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80ac68cd883369dac20688bc32b4cb33291b5e50" datatype="html">
+ <source>Calculation help</source>
+ <target>Ayuda para el cálculo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fccbd60493df26705d957ed6c02a3c447894678f" datatype="html">
+ <source>The current PGs settings were calculated for you, you should make sure the values suit your needs before submit.</source>
+ <target>Se ha calculado automáticamente la configuración de los grupos de colocación actuales. Asegúrese de que los valores se ajustan a sus necesidades antes de enviar.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">116,117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a43b2695131b48b76cebba676aba98a2bee17515" datatype="html">
+ <source>Replicated size</source>
+ <target>Tamaño replicado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bff144a4c4dc63b0e18fff2617d61a7ebdf2b6c" datatype="html">
+ <source>Minimum: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></source>
+ <target>Mínimo: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9c54b41f6d58a74e5d0aa3429ed0c87a482551" datatype="html">
+ <source>Maximum: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></source>
+ <target>Máximo: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="452cf71ec44ee77428656936a6627eaf2dd3b47f" datatype="html">
+ <source>The size specified is out of range. A value from <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> to <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/> is usable.</source>
+ <target>El tamaño especificado está fuera del intervalo. Se puede usar un valor entre <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> y <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">144,145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dda6196ffab88c1825f44a565c7b34e246e7e12f" datatype="html">
+ <source>A size of 1 will not create a replication of the object. The 'Replicated size' includes the object itself.</source>
+ <target>El tamaño 1 no creará una réplica del objeto. El valor de Tamaño replicado incluye el propio objeto.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">148,149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c870fb00256b8a5b9cb9cd1a124e6390b9bc639" datatype="html">
+ <source>EC Overwrites</source>
+ <target>Sustituciones de códigos de borrado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f1abafaeb40ce52355ddcc24686e3cd17b64e08a" datatype="html">
+ <source>Applications</source>
+ <target>Aplicaciones</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9308b82fc183f710df60909f49cfc73aa5e076" datatype="html">
+ <source>CRUSH</source>
+ <target>CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9de7dde00e2139cc4bd03b1837afbe72ad15a1ff" datatype="html">
+ <source>Erasure code profile</source>
+ <target>Perfil de código de borrado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39b4620e6bd444e0a57a0a5c03fa8c96d7fe5235" datatype="html">
+ <source>-- No erasure code profile available --</source>
+ <target>-- No hay ningún perfil de código de borrado disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498561757390d5528b263ce450d5f38efb00266d" datatype="html">
+ <source>-- Select an erasure code profile --</source>
+ <target>-- Seleccione un perfil de código de borrado --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="616a2532fbaace94934f5943e381b63e2623f004" datatype="html">
+ <source>This profile can't be deleted as it is in use.</source>
+ <target>El perfil no se puede suprimir porque está en uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="994363f08f9fbfa3b3994ff7b35c6904fdff18d8" datatype="html">
+ <source>Profile</source>
+ <target>Perfil</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="023d6f718770d2ea4ab8cabe26b0ec27ef967ec2" datatype="html">
+ <source>Used by pools</source>
+ <target>Usado por repositorios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">387</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1061ba5ee07a5c6af09e09330dbc29201baf2aa" datatype="html">
+ <source>Profile is not in use.</source>
+ <target>El perfil no está en uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33150f22ce5348aa6c499bd092c3f4f3695d62cc" datatype="html">
+ <source>Crush ruleset</source>
+ <target>Conjunto de reglas de CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">293</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">303</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c69b0bcd4698aa845d32c4c4ad488492552cb469" datatype="html">
+ <source>A new crush ruleset will be implicitly created.</source>
+ <target>Se creará implícitamente un conjunto de reglas de CRUSH nuevo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="896e9987db5e9bb279e6deed5d2dff28c242ef66" datatype="html">
+ <source>There are no rules.</source>
+ <target>No hay ninguna regla.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73a6b31116b3cc322af951daa0bafdc169e6c42e" datatype="html">
+ <source>-- Select a crush rule --</source>
+ <target>-- Seleccione una regla de CRUSH --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7d4894e770f8853050b1f6dd55bdd77a51a8ac6" datatype="html">
+ <source>Placement and
+ replication strategies or distribution policies that allow to
+ specify how CRUSH places data replicas.</source>
+ <target>Estrategias de
+ colocación y réplica o directivas de distribución que permiten
+ especificar cómo coloca CRUSH las réplicas de datos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">328,330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea91d648f92002bc9f96d9b26b735c83ca0b53c6" datatype="html">
+ <source>This rule can't be deleted as it is in use.</source>
+ <target>Esta regla no se puede suprimir porque está en uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">346</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92da80699921e89fb19372e25b8d0f3b9fa427fc" datatype="html">
+ <source>Crush rule</source>
+ <target>Regla de CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">365</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5489e9f96835f469f6f728a00d8efa88ea5bc940" datatype="html">
+ <source>Crush steps</source>
+ <target>Pasos de CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc5f5496a9e50fe69e1a09784f28d94944108294" datatype="html">
+ <source>Rule is not in use.</source>
+ <target>La regla no está en uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="104a0e6900d1d1b0c8cf9e5947e36edb352583fc" datatype="html">
+ <source>The rule can't be used in the current cluster as it has too few OSDs to meet the minimum required OSD by this rule.</source>
+ <target>No es posible usar la regla en el clúster actual porque no tiene suficientes OSD para cumplir el mínimo de OSDs requerido por la regla.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">409,410</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2208d63d5940ce656006a220102b1eb2b5e553da" datatype="html">
+ <source>Compression</source>
+ <target>Compresión</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">420</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c6f25c47da62ec597c6057a36ddfc3209811ec5" datatype="html">
+ <source>Algorithm</source>
+ <target>Algoritmo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">444</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4903231d42089325a28892c0fde1aed46b733ae6" datatype="html">
+ <source>-- No erasure compression algorithm available --</source>
+ <target>-- No hay ningún algoritmo de compresión de borrado disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d68ddb254275f8f44221e9ad6d8ceeb59ca46a6" datatype="html">
+ <source>Minimum blob size</source>
+ <target>Tamaño de Blob mínimo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">468</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb2f176df80647137cbb02bbeb29e5dec707a400" datatype="html">
+ <source>e.g., 128KiB</source>
+ <target>p. ej. 128 KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">477</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b7f6e53a4521c6eb3ced4c007fdd4cf80bb7707" datatype="html">
+ <source>Value should be greater than 0</source>
+ <target>El valor debe ser mayor que 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">482</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">506</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8db98ab14b4e207ec763dfdefbc2dae367aab1cc" datatype="html">
+ <source>Value should be less than the maximum blob size</source>
+ <target>El valor debe ser menor que el tamaño de Blob máximo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151efb127a9a4dd25259a0b2055442318a141f5b" datatype="html">
+ <source>Maximum blob size</source>
+ <target>Tamaño de Blob máximo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c656f0e346bbadf46eb1a5d20d0307a3bd20ba8" datatype="html">
+ <source>e.g., 512KiB</source>
+ <target>p. ej. 512 KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65a24eee8a026f3b1113fe9e157e9a0dd69486" datatype="html">
+ <source>Value should be greater than the minimum blob size</source>
+ <target>El valor debe ser mayor que el tamaño de Blob mínimo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">509</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="261ba09c4a59de83f48f52a23fd328da37e61ff4" datatype="html">
+ <source>Ratio</source>
+ <target>Relación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">517</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1430457a9c3c66366e51d76bf10396014c576be" datatype="html">
+ <source>Compression ratio</source>
+ <target>Relación de compresión</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">528</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae5ce6de352cde949998fb10754459c3a4eb183b" datatype="html">
+ <source>Value should be between 0.0 and 1.0</source>
+ <target>El valor debe estar entre 0,0 y 1,0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d99b34162c9c34f10d0ccd8dbae83d8569c2db77" datatype="html">
+ <source>Max bytes</source>
+ <target>Número máximo de bytes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">546</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1d14a18879c62f3f4ed705318b7164a1160e249" datatype="html">
+ <source>Leave it blank or specify 0 to disable this quota.</source>
+ <target>Para inhabilitar esta cuota, deje el campo en blanco o especifique 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">572</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7565b131562ff6c5f769fdbd239a772154abdd97" datatype="html">
+ <source>A valid quota should be greater than 0.</source>
+ <target>Una cuota válida debe ser mayor que 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">550</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">574</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b8bf35b66f09a301eef92ffc3cb2fd259df67ce9" datatype="html">
+ <source>Max objects</source>
+ <target>Número máximo de objetos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">570</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="95f348167622d832c5ae532b6944635c8e2ae5cb" datatype="html">
+ <source>The value should be greater or equal to 0</source>
+ <target>El valor debe ser mayor o igual que 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">586</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1088629182722162774" datatype="html">
+ <source>pool</source>
+ <target>repositorio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6215593782779198370" datatype="html">
+ <source>erasure code profile</source>
+ <target>perfil de código de borrado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4390273881304618317" datatype="html">
+ <source>crush rule</source>
+ <target>regla de CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">721</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d8a7c8aea58294a3c57c23af0468ddf0ba0c9c7" datatype="html">
+ <source>Pools List</source>
+ <target>Lista de repositorios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9055665654201606988" datatype="html">
+ <source>Data Protection</source>
+ <target>Protección de datos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6658000829978978023" datatype="html">
+ <source>Applications</source>
+ <target>Aplicaciones</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5232365108332422324" datatype="html">
+ <source>PG Status</source>
+ <target>Estado del grupo de colocación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1669788723782899084" datatype="html">
+ <source>Crush Ruleset</source>
+ <target>Conjunto de reglas de CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7961062124768120122" datatype="html">
+ <source>Pool deletion is disabled by the mon_allow_pool_delete configuration setting.</source>
+ <target>El valor de configuración mon_allow_pool_delete inhabilita la supresión del repositorio.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee5132a8da30e0b7f9f5c70dbc91928d17dd909" datatype="html">
+ <source>Owner</source>
+ <target>Propietario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c51963a9c553b29427ef783bbb69fa6634fa8c" datatype="html">
+ <source>Index type</source>
+ <target>Tipo de índice</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e6f950a32eaea32ec7e192f9ca3d3dfe469d4ba" datatype="html">
+ <source>Placement rule</source>
+ <target>Regla de colocación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6972d213e31c4ea4f887e60db99d9881bc8fcd3e" datatype="html">
+ <source>Marker</source>
+ <target>Marcador</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47b02acd2d3254d1ace1926f840523f154ebef71" datatype="html">
+ <source>Maximum marker</source>
+ <target>Marcador máximo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="092fa3a7df9168b14d3f83a77a4035e92b92ce15" datatype="html">
+ <source>Master version</source>
+ <target>Versión maestra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97434cc5001d407f90c7447a12d9e8e6848a2aa3" datatype="html">
+ <source>Modification time</source>
+ <target>Hora de modificación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90fe2e41e7fde38453ce4e619efeea9bc6adea9c" datatype="html">
+ <source>Zonegroup</source>
+ <target>Grupo de zona</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="efeade5060b3add63863c24871f0830fb16b7e6d" datatype="html">
+ <source>Versioning</source>
+ <target>Control de versiones</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62a923f047ca49e7a4782629e91fea1ba32db68f" datatype="html">
+ <source>MFA Delete</source>
+ <target>Supresión de MFA</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="649a410bd0ace333d067d8fa22f12bdbdb43533b" datatype="html">
+ <source>Bucket quota</source>
+ <target>Cuota de papelera</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">567</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f50a33d3c339f8f4a465141f8caa5d2d8c005251" datatype="html">
+ <source>Enabled</source>
+ <target>Habilitado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">579</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cef1595d040e77cbb4466e60382028d4c2040cac" datatype="html">
+ <source>Maximum size</source>
+ <target>Tamaño máximo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa6fb95c355f172bda303de1ce2f38c251a149cf" datatype="html">
+ <source>Unlimited</source>
+ <target>Sin límite</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee862a800364b4d11f9b8cb9955a28a60f840a45" datatype="html">
+ <source>Maximum objects</source>
+ <target>Número máximo de objetos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b84370895ab9eb44672f57146fa05c5947f1c0c" datatype="html">
+ <source>Locking</source>
+ <target>Bloqueo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c3d9d2296f7886e8289b9f623323803deacfc6" datatype="html">
+ <source>Days</source>
+ <target>Días</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f44bdf9ab00a973bbe482e9fc450e3f67e60c0d" datatype="html">
+ <source>Bucket names can only contain lowercase letters, numbers, periods and hyphens.</source>
+ <target>Los nombres de papeleras solo pueden incluir minúsculas, números, puntos y guiones.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eabb4db920d9f9b2480cf438468b86e1bea02a9b" datatype="html">
+ <source>The chosen name is already in use.</source>
+ <target>El nombre que ha elegido ya está en uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b06de7f834c622197e68b66a2abe893040b174c4" datatype="html">
+ <source>Bucket names must not contain uppercase characters or underscores.</source>
+ <target>Los nombres de papeleras no deben incluir mayúsculas ni guiones bajos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abacf4af2f66d3af08c5ebe502b21b1f42ac649" datatype="html">
+ <source>Each label must start and end with a lowercase letter or a number.</source>
+ <target>Las etiquetas deben empezar y terminar con una minúscula o un número.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a7f52e6813e0535026f61a2d6e8adc8a1d006a" datatype="html">
+ <source>Bucket names cannot be formatted as IP address.</source>
+ <target>Los nombres de papeleras no pueden tener formato de dirección IP.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2a2460396d35e14e7acfb4e060196a0679bdcff" datatype="html">
+ <source>Bucket labels cannot be empty and can only contain lowercase letters, numbers and hyphens.</source>
+ <target>Las etiquetas de papelera no pueden estar vacías y solo pueden incluir minúsculas, números y guiones.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf5c849977e0be2dbfc862d044edd323bfd9fb77" datatype="html">
+ <source>Bucket names must be 3 to 63 characters long.</source>
+ <target>Los nombres de papeleras deben tener entre 3 y 63 caracteres.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e4c918357c7445fbf19a203e5f0f0ece1960b3b" datatype="html">
+ <source>-- Select a user --</source>
+ <target>-- Seleccione un usuario --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4aab1f837bc8ec222e4f25922465d1c5929a1fc" datatype="html">
+ <source>Placement target</source>
+ <target>Destino de colocación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bae0a7fc2c9c1fde7d937a8a1a3c7e6825cf7d1" datatype="html">
+ <source>-- Select a placement target --</source>
+ <target>-- Seleccione un destino de colocación --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="016d24e069e7d505a090fb8243e5cd43b35dc39b" datatype="html">
+ <source>Enables versioning for the objects in the bucket.</source>
+ <target>Habilita el control de versiones de los objetos de la papelera.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">151</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e6775ffd06878aa145c07359f28557f01ede04f" datatype="html">
+ <source>Multi-Factor Authentication</source>
+ <target>Autenticación multifactor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29e8a5d4fb767d4ad0c762c81c6264cec4c0ba97" datatype="html">
+ <source>Delete enabled</source>
+ <target>Suprimir habilitado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40fbc3ac8c1ea4ecfe62247e91f1f999ad5baf76" datatype="html">
+ <source>Enables MFA (multi-factor authentication) Delete, which requires additional authentication for changing the bucket versioning state.</source>
+ <target>Habilita la supresión de autenticación multifactor (MFA), lo que requiere autenticación adicional para cambiar el estado del control de versiones de la papelera.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24c93a8c13db46defa06ed7b5e026a3edb52b91" datatype="html">
+ <source>Token Serial Number</source>
+ <target>Número de serie del testigo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6d9536c2af2e5e9a228c3e3e1809dc1fefe0149" datatype="html">
+ <source>Token PIN</source>
+ <target>PIN del testigo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f038d51ab1645f15b0cd58f195c72a7eeebd4729" datatype="html">
+ <source>Enables locking for the objects in the bucket. Locking can only be enabled while creating a bucket.</source>
+ <target>Habilita el bloqueo de los objetos de la papelera. El bloqueo solo se puede habilitar mientras se crea una papelera.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9af1b4baa2dd8ed2bfc3cc756b12a2271c2dd793" datatype="html">
+ <source>Compliance</source>
+ <target>Cumplimiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="edd600fa489d1b4a4448dce694ed932e52ce8fda" datatype="html">
+ <source>Governance</source>
+ <target>Gobernanza</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="218c7d6d318c51e7105309aaeb0baec9d19e4efb" datatype="html">
+ <source>The number of days that you want to specify for the default retention period that will be applied to new objects placed in this bucket.</source>
+ <target>El número de días que desea especificar para el período de retención por defecto que se aplicará a los nuevos objetos colocados en esta papelera.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">264</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="289b101ec12427b3ca819df9e43cc3b14fae2cc4" datatype="html">
+ <source>The entered value must be a positive integer.</source>
+ <target>Se debe introducir un valor entero positivo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48d8247c1ba2ea156109bf286c5f6dd26b4be760" datatype="html">
+ <source>Retention Days must be a positive integer.</source>
+ <target>El valor de Días de retención debe ser un número entero positivo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4349284625269221231" datatype="html">
+ <source>bucket</source>
+ <target>papelera</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6161088322338624846" datatype="html">
+ <source>Updated Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'.</source>
+ <target>Papelera de Object Gateway <x id="PH" equiv-text="values.bid"/> actualizada.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218632328857697292" datatype="html">
+ <source>Created Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'</source>
+ <target>Papelera de Object Gateway <x id="PH" equiv-text="values.bid"/> creada.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c338bae89822d7eefbc9a887c458a7d8a98e55e" datatype="html">
+ <source>No Limit</source>
+ <target>Sin límite</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3715596725146409911" datatype="html">
+ <source>Owner</source>
+ <target>Propietario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5545511293826600258" datatype="html">
+ <source>Used Capacity</source>
+ <target>Capacidad usada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1925090152473969054" datatype="html">
+ <source>Capacity Limit %</source>
+ <target>% de límite de capacidad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8713861779825116442" datatype="html">
+ <source>Object Limit %</source>
+ <target>% de límite de objeto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5913880066213114620" datatype="html">
+ <source>buckets</source>
+ <target>papeleras</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eeba399c4dae8d4890c27b7a2cd2dc28fcf8b5f9" datatype="html">
+ <source>Performance Counters</source>
+ <target>Contadores de rendimiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="479488ab6e91ecb375484edc78bee3d13467f33f" datatype="html">
+ <source>Daemons List</source>
+ <target>Lista de daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca2dee83bb58290d93fb0d17ee8bc9f095a4576f" datatype="html">
+ <source>Sync Performance</source>
+ <target>Sincronizar rendimiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4378147649219625174" datatype="html">
+ <source>Zone</source>
+ <target>Zona</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6148052126949932311" datatype="html">
+ <source>Zone Group</source>
+ <target>Grupo de zonas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3840481991104643295" datatype="html">
+ <source>Realm</source>
+ <target>Dominio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1221ca97d19eaa9a7bc0c5243d5fc5befe1d2314" datatype="html">
+ <source>-- Select a type --</source>
+ <target>-- Seleccione un tipo --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1b8990332af18f1c5159a6061ca889bcbb28432" datatype="html">
+ <source>Permission</source>
+ <target>Permiso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a08c589f82f69d892307288da14190ae1dd583d5" datatype="html">
+ <source>-- Select a permission --</source>
+ <target>-- Seleccione un permiso --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7345972049922682356" datatype="html">
+ <source>capability</source>
+ <target>capacidad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a94e6b2b5b834d92cceb90037d51ad6165c8b619" datatype="html">
+ <source>Tenant</source>
+ <target>Inquilino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
+ <source>User ID</source>
+ <target>ID de usuario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b760f123248930122fc7e7b6b6bf94e376e959c8" datatype="html">
+ <source>Full name</source>
+ <target>Nombre completo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69b6ac577a19acc39fc0c22342092f327fff2529" datatype="html">
+ <source>Email address</source>
+ <target>Dirección de correo electrónico</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92f3f203270a29b3001871153f02c063484a1574" datatype="html">
+ <source>Suspended</source>
+ <target>Suspendido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011e20c5bbe51602d459a860fbf29b599b55edd" datatype="html">
+ <source>System</source>
+ <target>Sistema</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db18a2772988415466a7f75dc42663ce78c9c1d3" datatype="html">
+ <source>Maximum buckets</source>
+ <target>Número máximo de papeleras</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c4c62e8ba24601be5cfe7dc5d32c24bbbd4b53c" datatype="html">
+ <source>Subusers</source>
+ <target>Subusuarios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17bb3082e6fe5003203ef992a3714172334631a1" datatype="html">
+ <source>Capabilities</source>
+ <target>Capacidades</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32f8a0570373cacb9c56cf227502483a29d605bc" datatype="html">
+ <source>MFAs(Id)</source>
+ <target>MFAs(Id)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36ad38f9c1a1485e09b67778a28af84553290ffb" datatype="html">
+ <source>User quota</source>
+ <target>Cuota de usuario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">473</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0bcd5ef19af0f1b814141ca8c57df623d8270088" datatype="html">
+ <source>Keys</source>
+ <target>Claves</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2aba1e87039819aca3b70faa9aa848c12bf139ca" datatype="html">
+ <source>Show</source>
+ <target>Mostrar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">395</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5248717555542428023" datatype="html">
+ <source>Username</source>
+ <target>Nombre de usuario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240806681889331244" datatype="html">
+ <source>Unlimited</source>
+ <target>Sin límite</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db4e1a734518691b128ef40b939cc673f01d03a6" datatype="html">
+ <source>The value is not valid.</source>
+ <target>El valor no es válido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">617</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6aaf5d2a304167272ac73e3b1d1c162e16c77858" datatype="html">
+ <source>The chosen user ID is already in use.</source>
+ <target>El ID de usuario que ha elegido ya está en uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="025be1d01b2f6cbd09e772a1d3de02fab0678b26" datatype="html">
+ <source>Show Tenant</source>
+ <target>Mostrar inquilino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6af106b0d759fd2882e645604675c4494abfcd5b" datatype="html">
+ <source>The chosen user ID exists in this tenant.</source>
+ <target>El ID de usuario seleccionado no existe en este inquilino.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="df441e80db2157f9d272b75de724ba4a82b96b57" datatype="html">
+ <source>This is not a valid email address.</source>
+ <target>Esta dirección no es válida.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca271adf154956b8fcb28f4f50a37acb3057ff7c" datatype="html">
+ <source>The chosen email address is already in use.</source>
+ <target>La dirección de correo electrónico que ha elegido ya está en uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="030197cebe938edf35422e92fe14183d06eb670b" datatype="html">
+ <source>Max. buckets</source>
+ <target>Máx. papeleras</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f39256070bfc0714020dfee08895421fc1527014" datatype="html">
+ <source>Disabled</source>
+ <target>Inhabilitado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c05002b0ac2040f1aede5e727e0ffd06eda819" datatype="html">
+ <source>Custom</source>
+ <target>Personalizar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28872515cb81d197a3a1733fa546d3e0f0dd6c67" datatype="html">
+ <source>The entered value must be &gt;= 1.</source>
+ <target>El valor introducido debe ser mayor o igual que 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="583a219c524155c2314eb06ee29162bb315272a3" datatype="html">
+ <source>S3 key</source>
+ <target>Clave S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c217ee914725a37e9dd2336c721c8e63e9666bdc" datatype="html">
+ <source>Auto-generate key</source>
+ <target>Autogenerar clave</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f1c1c0f2bce4c9f92d1a2061e8161cb0006c31a" datatype="html">
+ <source>Access key</source>
+ <target>Clave de acceso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b864acb67296a9819c1db0069c4c47d8b5ce8f44" datatype="html">
+ <source>Secret key</source>
+ <target>Clave secreta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="128d6efb51d9ddc7c0cc695a2deeca5b9523f6e4" datatype="html">
+ <source>There are no subusers.</source>
+ <target>No hay ningún subusuario.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fd6dfb8ecb982dbc3affb2c2d5414c4f5b6abd2" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">294,295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67c746c1ba9dab4351fedc4c7cba4e6d6b0dbc47" datatype="html">
+ <source>S3</source>
+ <target>S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d6819038d608623503918fb2553f53d68231ec3a" datatype="html">
+ <source>There are no keys.</source>
+ <target>No hay ninguna clave.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">377</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc1c1a7140ff6b815a95b65ee2780fdbe1b2b7a1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">356,357</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6ddb5e991a3ecd2659fb520bc5acc81b67e08ddd" datatype="html">
+ <source>Swift</source>
+ <target>Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">371</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d01eccdda47fc907c5be35bcb16d2dcd02b0270" datatype="html">
+ <source>There are no capabilities.</source>
+ <target>No hay ninguna capacidad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5a451c4ea65a4046f0b49d489a7013abf0b5861" datatype="html">
+ <source>All capabilities are already added.</source>
+ <target>Ya se han añadido todas las capacidades.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">456</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="043e2ec0036ceadd926fd5e3f93cd6f3565f3648" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">461,462</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6146e13ceca5fa5cc17b771b282fe5955f3d19fa" datatype="html">
+ <source>Unlimited size</source>
+ <target>Tamaño ilimitado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">595</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6db8aa7c99fdce18edb33dde57729acede2b308" datatype="html">
+ <source>Max. size</source>
+ <target>Tamaño máx.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">511</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">605</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc630b2093e880fffa19df99d5cd8b87605037f8" datatype="html">
+ <source>Unlimited objects</source>
+ <target>Objetos ilimitados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cda5a993d06f0bb10048be9d3aba6555aa9f356" datatype="html">
+ <source>Max. objects</source>
+ <target>Objetos máx.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">642</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="623ac50f37a26caec6fd7cd519b653e3315cba25" datatype="html">
+ <source>The entered value must be &gt;= 0.</source>
+ <target>El valor introducido debe ser mayor o igual que 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">654</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="123010868147850959" datatype="html">
+ <source>user</source>
+ <target>usuario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8368421344177343441" datatype="html">
+ <source>subuser</source>
+ <target>subusuario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4662015204945271252" datatype="html">
+ <source>S3 Key</source>
+ <target>Clave S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9103468069826049692" datatype="html">
+ <source>Updated Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <target>Usuario de Object Gateway <x id="PH" equiv-text="uid"/> actualizado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="884841609901737584" datatype="html">
+ <source>Created Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <target>Usuario de Object Gateway <x id="PH" equiv-text="uid"/> creado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4363143805416924501" datatype="html">
+ <source>Tenant</source>
+ <target>Inquilino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8301535046747035390" datatype="html">
+ <source>Full name</source>
+ <target>Nombre completo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3967269098753656610" datatype="html">
+ <source>Email address</source>
+ <target>Dirección de correo electrónico</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5851424994801012357" datatype="html">
+ <source>Suspended</source>
+ <target>Suspendido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208300173682032371" datatype="html">
+ <source>Max. buckets</source>
+ <target>Máx. papeleras</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1670306451865226564" datatype="html">
+ <source>users</source>
+ <target>usuarios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c614babd1950adb2be75df4e2c9747286d6adc" datatype="html">
+ <source>-- Select a username --</source>
+ <target>-- Seleccione un nombre de usuario --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2841767821d6b66238c34d07e413b0af67aee92" datatype="html">
+ <source>Subuser</source>
+ <target>Subusuario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd59fc25a7bd98cff3e75117c09697c8a007a514" datatype="html">
+ <source>The chosen subuser ID is already in use.</source>
+ <target>El ID de subusuario que ha elegido ya está en uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d386c357ebcbc04ed05c4babd5a03626f9b1674" datatype="html">
+ <source>read, write</source>
+ <target>lectura, escritura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84e3e3f9a4f31a039b648c97debf95fcb20f4c4a" datatype="html">
+ <source>full</source>
+ <target>todos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6bf81d032a2316464f9df2f0d2f3d753f89f0d3" datatype="html">
+ <source>Swift key</source>
+ <target>Clave Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e0c12685d50d47448ceed9423977ef39775c037" datatype="html">
+ <source>Auto-generate secret</source>
+ <target>Autogenerar secreto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5091031285775138345" datatype="html">
+ <source>Subuser</source>
+ <target>Subusuario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8453697749389230205" datatype="html">
+ <source>Swift Key</source>
+ <target>Clave Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ac54c18c1b520e948095c83a3a1025f02ce6dcc6" datatype="html">
+ <source>Neither hostname nor OSD ID given</source>
+ <target>No se ha indicado ni el nombre de host ni el ID de OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4533150758393178756" datatype="html">
+ <source>Device ID</source>
+ <target>ID de dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1291053608320944146" datatype="html">
+ <source>State of Health</source>
+ <target>Estado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29167121133682512" datatype="html">
+ <source>Good</source>
+ <target>Bueno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8767957606064036733" datatype="html">
+ <source>Bad</source>
+ <target>Malo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8052456228079338924" datatype="html">
+ <source>Stale</source>
+ <target>Inactivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6223439643831041743" datatype="html">
+ <source>Life Expectancy</source>
+ <target>Esperanza de vida</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3144481541623761279" datatype="html">
+ <source>Prediction Creation Date</source>
+ <target>Fecha de creación de predicción</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="264574868375698540" datatype="html">
+ <source>Device Name</source>
+ <target>Nombre del dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1419569261746199221" datatype="html">
+ <source>Daemons</source>
+ <target>Daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f635b3cb0600409a2ad44a5bd1863c699e6a01c" datatype="html">
+ <source>Failed to retrieve SMART data.</source>
+ <target>Error al leer los datos SMART.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a8a3f354bd640299068edd912f4bb5325264f250" datatype="html">
+ <source>The data received has the JSON format version 2.x and is currently incompatible with the dashboard.</source>
+ <target>Los datos recibidos tiene formato JSON versión 2.x y, actualmente, no es compatible con la consola.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="04f8a3c7e8ac610e6581960162cc15f55a16696a" datatype="html">
+ <source>No SMART data available.</source>
+ <target>No hay datos SMART disponibles.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a185c9b97513b3882604ea9bab60edbfac945c15" datatype="html">
+ <source>SMART overall-health self-assessment test result</source>
+ <target>Resultado de la prueba de autoevaluación de estado general de SMART</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="290e4c9ad42dc6e9176656c864a5faed8053f406" datatype="html">
+ <source>unknown</source>
+ <target>desconocido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a03d3c2e459f8f8fa7202c0fce465d6165f9e2b" datatype="html">
+ <source>passed</source>
+ <target>aprobado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41435d5a5692c8e412c74deaee95d99dbd3617e1" datatype="html">
+ <source>failed</source>
+ <target>con error</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddd5dd6d930030096ea617f62c82b648a0dd9484" datatype="html">
+ <source>Device Information</source>
+ <target>Información del dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e149c483d88cfcff11d1c5db85e84af7c3149c4" datatype="html">
+ <source>No device information available for this device.</source>
+ <target>No hay información de dispositivo disponible para este dispositivo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20cb12827cbe559a7b1da6fdae96041b3b5c3c55" datatype="html">
+ <source>SMART</source>
+ <target>SMART</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380295f37caea93701d071485a38ef0bdba57133" datatype="html">
+ <source>No SMART data available for this device.</source>
+ <target>No hay datos SMART disponibles para este dispositivo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5758c3f16f8749f0f4e2a787f02e8b4da246102f" datatype="html">
+ <source>SMART data is loading.</source>
+ <target>Los datos SMART se están cargando.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5363861031080361352" datatype="html">
+ <source>Smartctl has received an unknown argument (error code <x id="PH" equiv-text="smartData.smartctl_error_code"/>). You may be using an incompatible version of smartmontools. Version &gt;= 7.0 of smartmontools is required to successfully retrieve data.</source>
+ <target>Smartctl ha recibido un argumento desconocido (código de error <x id="PH" equiv-text="smartData.smartctl_error_code"/>). Puede que esté usando una versión no compatible de smartmontools. Se requiere la versión 7.0 o una posterior de smartmontools para poder recuperar datos correctamente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">61,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5085718566932809950" datatype="html">
+ <source>An error with error code <x id="PH" equiv-text="smartData.smartctl_error_code"/> occurred.</source>
+ <target>Error con el código <x id="PH" equiv-text="smartData.smartctl_error_code"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2091295268977103253" datatype="html">
+ <source>Raw</source>
+ <target>Bruto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5963653123239768443" datatype="html">
+ <source>Threshold</source>
+ <target>Umbral</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2893124970059125090" datatype="html">
+ <source>When Failed</source>
+ <target>Cuando se produce un error</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5614367840516299633" datatype="html">
+ <source>Worst</source>
+ <target>Peor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d06ae77f9ec46a4cdd49e7e76c73a411aaf2ee38" datatype="html">
+ <source>Please set a new password.</source>
+ <target>Defina una contraseña nueva.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8b5b3566e88438f51bd5f6caf6c090ed565ba5ed" datatype="html">
+ <source>You will be redirected to the login page afterwards.</source>
+ <target>Después se le redirigirá a la página de entrada.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cf42e491adc166a337a960eb84d03c0c3f677c8" datatype="html">
+ <source>The old and new passwords must be different.</source>
+ <target>Las contraseñas antigua y la nueva deben ser diferentes.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90163a3d3746819aef42e829f4446331232f3b66" datatype="html">
+ <source>Password confirmation doesn't match the new password.</source>
+ <target>La contraseña de confirmación no coincide con la contraseña nueva.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0070e83d11da39d6f4bb95065c2675db1610b419" datatype="html">
+ <source>Username is required</source>
+ <target>El nombre de usuario es obligatorio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e20f8b8a4706526c9024cc2f39d568345d100dc" datatype="html">
+ <source>Password is required</source>
+ <target>La contraseña es obligatoria</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f093d9574ab746b231504bd2cbb65f04bd7b00db" datatype="html">
+ <source>Log in</source>
+ <target>Entrar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5590086849807274701" datatype="html">
+ <source>Scope</source>
+ <target>Ámbito</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327592562693301723" datatype="html">
+ <source>Read</source>
+ <target>Lectura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5674286808255988565" datatype="html">
+ <source>Create</source>
+ <target>Crear</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4021752662928002901" datatype="html">
+ <source>Update</source>
+ <target>Actualizar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022070615528435141" datatype="html">
+ <source>Delete</source>
+ <target>Suprimir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ea5c4d8942c00752dcc72e72949c5d9832f6399" datatype="html">
+ <source>Description...</source>
+ <target>Descripción...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70f45880fce6ac5d8e468e25e82aefbba8098cfe" datatype="html">
+ <source>Permissions</source>
+ <target>Permisos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="122114774689391224" datatype="html">
+ <source>role</source>
+ <target>función</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616102757855967475" datatype="html">
+ <source>All</source>
+ <target>todos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4416727401284087008" datatype="html">
+ <source>Created role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <target>Función <x id="PH" equiv-text="roleFormModel.name"/> creada.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3472946357042916911" datatype="html">
+ <source>Updated role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <target>Función <x id="PH" equiv-text="roleFormModel.name"/> actualizada.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="373024661645814027" datatype="html">
+ <source>System Role</source>
+ <target>Función del sistema</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753648234171918096" datatype="html">
+ <source>Deleted role '<x id="PH" equiv-text="role"/>'</source>
+ <target>Función <x id="PH" equiv-text="role"/> suprimida.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1674202514578558795" datatype="html">
+ <source>New name</source>
+ <target>Nombre nuevo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4857700187193019038" datatype="html">
+ <source>Clone Role</source>
+ <target>Clonar función</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="748631939386170157" datatype="html">
+ <source>Cloned role '<x id="PH" equiv-text="values['newName']"/>' from '<x id="PH_1" equiv-text="name"/>'</source>
+ <target>Función <x id="PH" equiv-text="values['newName']"/> clonada de <x id="PH_1" equiv-text="name"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="195c31a2f970e790231a6bb94a5e8ca0167406d9" datatype="html">
+ <source>The username already exists.</source>
+ <target>El nombre de usuario ya existe.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f3bdcce4b2e8c37cd7f0f6c92ef8cff34b039b8" datatype="html">
+ <source>Confirm password</source>
+ <target>Confirmar contraseña</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cbb979e63ba50e0ca3adfa09cbdcaefd0853fca1" datatype="html">
+ <source>Password confirmation doesn't match the password.</source>
+ <target>Las contraseñas no coinciden.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="96621f9ed2e4ae5204564e583d2c816bedead571" datatype="html">
+ <source>Password expiration date</source>
+ <target>Fecha de caducidad de la contraseña</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48932db3801fe9d5d72a60a3e656bffd17c1c5d9" datatype="html">
+ <source>Password expiration date...</source>
+ <target>Fecha de caducidad de la contraseña...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc" datatype="html">
+ <source>Email</source>
+ <target>Correo electrónico</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d0ec081dd61eb4f43aea269077bbe38eae87b7f9" datatype="html">
+ <source>Invalid email.</source>
+ <target>Correo electrónico no válido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9610487cbeb5796d34d8601b5ac0c0a65f9e1d19" datatype="html">
+ <source>Roles</source>
+ <target>Funciones</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8913c216dd506e20e412e144381d8d2a65a84359" datatype="html">
+ <source>User must change password at next logon</source>
+ <target>El usuario debe cambiar la contraseña la próxima vez que entre</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0051a3479d3ba79135c16dc8cc017950a2cce821" datatype="html">
+ <source>You are about to remove &quot;user read / update&quot; permissions from your own user.</source>
+ <target>Se dispone a eliminar los permisos &quot;lectura/actualización de usuario&quot; de su propio usuario.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af4bf9fcb256853f14cf947eb1deb8d7f176d3f9" datatype="html">
+ <source>If you continue, you will no longer be able to add or remove roles from any user.</source>
+ <target>Si continúa, no podrá añadir ni eliminar funciones en ningún usuario.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314291969883771319" datatype="html">
+ <source>There are no roles.</source>
+ <target>No hay ninguna función.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4306072924538089180" datatype="html">
+ <source>Created user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <target>Usuario <x id="PH" equiv-text="userFormModel.username"/> creado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1349763489797682899" datatype="html">
+ <source>Update user</source>
+ <target>Actualizar usuario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8688396456017237992" datatype="html">
+ <source>You were automatically logged out because your roles have been changed.</source>
+ <target>La sesión se ha cerrado automáticamente porque sus funciones han cambiado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2335813072344088607" datatype="html">
+ <source>Updated user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <target>Usuario <x id="PH" equiv-text="userFormModel.username"/> actualizado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4768749765465246664" datatype="html">
+ <source>Email</source>
+ <target>Correo electrónico</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795890916060309463" datatype="html">
+ <source>Roles</source>
+ <target>Funciones</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6877445485286599988" datatype="html">
+ <source>Password expiration date</source>
+ <target>Fecha de caducidad de la contraseña</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="705657168061753072" datatype="html">
+ <source>Deleted user '<x id="PH" equiv-text="username"/>'</source>
+ <target>Usuario <x id="PH" equiv-text="username"/> suprimido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="405819296611088743" datatype="html">
+ <source>Failed to delete user '<x id="PH" equiv-text="username"/>'</source>
+ <target>Error al suprimir el usuario <x id="PH" equiv-text="username"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8935387756949610047" datatype="html">
+ <source>You are currently logged in as '<x id="PH" equiv-text="username"/>'.</source>
+ <target>Ha entrado como <x id="PH" equiv-text="username"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0eb15f32b2b92d7f3103ef3ff032621888a8dc32" datatype="html">
+ <source>Old password</source>
+ <target>Contraseña anterior</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229" datatype="html">
+ <source>New password</source>
+ <target>Contraseña nueva</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ede41f01c781b168a783cfcefc6fb67d48780d9b" datatype="html">
+ <source>Confirm new password</source>
+ <target>Confirmar contraseña nueva</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809196861118879526" datatype="html">
+ <source>password</source>
+ <target>contraseña</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623124197136601291" datatype="html">
+ <source>Updated user password&quot;</source>
+ <target>Contraseña de usuario actualizada&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be" datatype="html">
+ <source>Users</source>
+ <target>Usuarios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ced3246fa3db31be0f7da06648463f29ba378fbe" datatype="html">
+ <source>Selected Object Gateway:</source>
+ <target>Object Gateway seleccionado:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c53062af97ebda2a03f905698f58e524ecf8b968" datatype="html">
+ <source>Select Object Gateway</source>
+ <target>Seleccionar Object Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="235c355afdcbf72953a15d7fc8d0d9e7a6619f46" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Page not Found<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Página no encontrada<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aee9d027170f84774f2980537556f5099369b82" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for. The page you requested may have been changed or moved.</source>
+ <target>No se encuentra lo que busca. Puede que la página que ha solicitado haya cambiado o se haya movido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">22,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2b46fe9a975c6531af77fee858ccd37327980f7" datatype="html">
+ <source>Please consult the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>documentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> on how to configure and enable the <x id="INTERPOLATION" equiv-text="{{ section_info }}"/> management functionality.</source>
+ <target>Consulte en la <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>documentación<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> cómo configurar y habilitar la <x id="INTERPOLATION" equiv-text="{{ section_info }}"/> función de gestión.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">26,27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9d57ca7cab78c6f0d27e0d890cb8cf1515e4e30a" datatype="html">
+ <source>Go To Dashboard</source>
+ <target>Ir a la consola</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6578397717654172779" datatype="html">
+ <source>Page Not Found</source>
+ <target>Página no encontrada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8185335715884155108" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for.
+ The page you requested may have been changed or moved.</source>
+ <target>No se encuentra lo que busca.
+  Puede que la página que ha solicitado haya cambiado o se haya movido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="143318366100741906" datatype="html">
+ <source>Access Denied</source>
+ <target>Acceso denegado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5384670299771400832" datatype="html">
+ <source>Sorry, you don’t have permission to view this page or resource.</source>
+ <target>No tiene permiso para ver esta página o recurso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2424411274809083521" datatype="html">
+ <source>User Denied</source>
+ <target>Usuario denegado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7645004872908092358" datatype="html">
+ <source>Sorry, the user does not exist in Ceph.
+ You'll be logged out from the Identity Provider when you retry logging in.</source>
+ <target>El usuario no existe en Ceph.
+ Saldrá del proveedor de identidades cuando intente entrar de nuevo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">24,25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f286db6ac9482dbf567bc491d49a6eade444895a" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7911416166208830577" datatype="html">
+ <source>Help</source>
+ <target>Ayuda</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8878700331247603166" datatype="html">
+ <source>Security</source>
+ <target>Seguridad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8642696205489749843" datatype="html">
+ <source>Trademarks</source>
+ <target>Marcas comerciales</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1481ecd21e760ac919a24e26cf790acd82e40199" datatype="html">
+ <source>Dashboard Settings</source>
+ <target>Ajustes de la consola</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a79aab4ef674bf3f6532292107c0054302236e0f" datatype="html">
+ <source>User management</source>
+ <target>Gestión del usuario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="197e0246502ca64d0de0df0d5c2deec51d41ff45" datatype="html">
+ <source>Telemetry configuration</source>
+ <target>Configuración de telemetría</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85b79c9064aed1ead31ace985f31aa1363f6bdaf" datatype="html">
+ <source>Help</source>
+ <target>Ayuda</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06638e0f01d82c0786f63aa9832fbe7866b86087" datatype="html">
+ <source>documentation</source>
+ <target>documentación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e351b40b3869a5c7d19c3d4918cb1ac7aaab95c4" datatype="html">
+ <source>API</source>
+ <target>API</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a" datatype="html">
+ <source>About</source>
+ <target>Acerca de</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="049dfd9fe6c78914ad58cf89ac6a631fca28ec74" datatype="html">
+ <source>Logged in user</source>
+ <target>Usuario que ha entrado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5022c5ae3ae921c07bf5f881e9b026b4a6708a7" datatype="html">
+ <source>Signed in as <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>Ha entrado como <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9" datatype="html">
+ <source>Change password</source>
+ <target>Cambiar contraseña</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d22c795daf43877a5f708dca2bccd549eb0471d" datatype="html">
+ <source>Sign out</source>
+ <target>Salir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319e0745bcbc132451569294fa2fa21bf10f555a" datatype="html">
+ <source>Toggle navigation</source>
+ <target>Alternar navegación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f65253954b66e929a8b4d5ecaf61f9129f8cec64" datatype="html">
+ <source>Dashboard</source>
+ <target>Consola</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c95898abff46bfac3ed6eb2afef74597e60b15c" datatype="html">
+ <source>CRUSH map</source>
+ <target>Mapa de CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7b2bc4b86de6e96d353f6bf2b4d793ea3a19ba0" datatype="html">
+ <source>Manager Modules</source>
+ <target>Módulos de gestor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb3d5aefff38a814b76da74371cbf02c0789a1ef" datatype="html">
+ <source>Logs</source>
+ <target>Registros</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17fc3efe5f9fa4e0289c900cb6202265215a1a27" datatype="html">
+ <source>Monitoring</source>
+ <target>Supervisión</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f5d0c10614e8a34f0e2dad33a0568277c50cf69" datatype="html">
+ <source>Block</source>
+ <target>Bloque</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3c2562ba992127203dcfd014010b03cb7b8113c6" datatype="html">
+ <source>Mirroring</source>
+ <target>Duplicación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="811c241d56601b91ef26735b770e64428089b950" datatype="html">
+ <source>iSCSI</source>
+ <target>iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a24eabd99ea5af20f5f94c4484649cd30370042b" datatype="html">
+ <source>NFS</source>
+ <target>NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5276fc60d54d667116babb723641b21281d37271" datatype="html">
+ <source>File Systems</source>
+ <target>Sistemas de archivos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9515520496da83179d8b08132f00f575512a1f40" datatype="html">
+ <source>Buckets</source>
+ <target>Papeleras</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a23e992f6c6e169a38b2b7338b4e5e803b52e0d" datatype="html">
+ <source>Tasks and Notifications</source>
+ <target>Tareas y notificaciones</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1390461972315002349" datatype="html">
+ <source>The name of the node under which data should be placed.</source>
+ <target>El nombre del nodo en el que se deben colocar los datos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6575341202068728510" datatype="html">
+ <source>The type of CRUSH nodes across which we should separate replicas.</source>
+ <target>El tipo de nodos CRUSH entre los que se deben separar las réplicas.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3874278445824365480" datatype="html">
+ <source>The device class data should be placed on.</source>
+ <target>La clase de dispositivo en la que se deben colocar los datos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="675628105428950215" datatype="html">
+ <source>Each object is split in data-chunks parts, each stored on a different OSD.</source>
+ <target>Cada objeto se divide en porciones de datos, cada una almacenada en un OSD distinto.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5128168460056151476" datatype="html">
+ <source>Compute coding chunks for each object and store them on different OSDs.
+ The number of coding chunks is also the number of OSDs that can be down without losing data.</source>
+ <target>Calcula las porciones de código para cada objeto y las almacena en distintos OSD.
+ El número de porciones de código es también el número de OSD que pueden estar inactivos sin que se pierdan datos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">18,19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8826111293169381132" datatype="html">
+ <source>The jerasure plugin is the most generic and flexible plugin,
+ it is also the default for Ceph erasure coded pools.</source>
+ <target>El complemento jerasure es el más genérico y flexible,
+ y también el complemento por defecto para los repositorios de código de borrado de Ceph.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">23,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1331133460856304156" datatype="html">
+ <source>The more flexible technique is reed_sol_van : it is enough to set k
+ and m. The cauchy_good technique can be faster but you need to chose the packetsize
+ carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents
+ in the sense that they can only be configured with m=2.</source>
+ <target>La técnica más flexible es reed_sol_van: basta con definir k y m.
+ La técnica cauchy_good puede ser más rápida, pero hay que elegir con cuidado el tamaño
+ del paquete. reed_sol_r6_op, liberation, blaum_roth y liber8tion son todas equivalentes a RAID6
+ en el sentido de que solo se pueden configurar con m=2.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">25,28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4577912952562931806" datatype="html">
+ <source>The encoding will be done on packets of bytes size at a time.
+ Choosing the right packet size is difficult.
+ The jerasure documentation contains extensive information on this topic.</source>
+ <target>La codificación se realizará según el tamaño de los paquetes de bytes de uno en uno.
+ Elegir el tamaño correcto es difícil.
+ La documentación de jerasure incluye información completa sobre el tema.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">29,31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6471646852539810855" datatype="html">
+ <source>With the jerasure plugin, when an erasure coded object is stored on
+ multiple OSDs, recovering from the loss of one OSD requires reading from all the others.
+ For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading
+ from the eleven others to repair.
+
+ The lrc erasure code plugin creates local parity chunks to be able to recover using
+ less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create
+ an additional parity chunk for every four OSDs. When a single OSD is lost, it can be
+ recovered with only four OSDs instead of eleven.</source>
+ <target>Con el complemento jerasure, cuando un objeto de código de borrado se almacena
+ en varios OSD, para recuperarse de la pérdida de un OSD es necesario leer de todos los demás.
+ Por ejemplo, si jerasure está configurado con k=8 y m=4, cuando se pierde un OSD es necesario leer
+ de los otros once para repararlo.
+
+ El complemento de código de borrado lrc crea porciones de paridad local para poder realizar la recuperación con
+ menos OSDs. Por ejemplo, is lrc está configurado con k=8, m=4 y l=4, creará
+ una porción de paridad adicional para cada cuatro OSDs. Si se pierde un solo OSD, se puede recuperar
+ solo con cuatro OSD, en lugar de con once.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">34,42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2619235086723330982" datatype="html">
+ <source>Group the coding and data chunks into sets of size locality. For instance,
+ for k=4 and m=2, when locality=3 two groups of three are created. Each set can
+ be recovered without reading chunks from another set.</source>
+ <target>Agrupa las porciones de código y de datos en localizaciones de conjuntos de tamaño. Por ejemplo,
+ para k=4 y m=2, si locality=3, se crean dos grupos de tres. Cada conjunto
+ se puede recuperar sin leer porciones de otro conjunto.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">43,45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3298836762557512588" datatype="html">
+ <source>The type of the crush bucket in which each set of chunks defined
+ by l will be stored. For instance, if it is set to rack, each group of l chunks will be
+ placed in a different rack. It is used to create a CRUSH rule step such as step choose
+ rack. If it is not set, no such grouping is done.</source>
+ <target>El tipo de papelera de CRUSH en el que se almacenará cada
+ conjunto de porciones definido por l. Por ejemplo, si se define como bastidor, cada grupo de l porciones
+ se colocará en un bastidor distinto. Se usa para crear un paso de regla de CRUSH, por ejemplo, &quot;step choose
+ rack&quot;. Si no se define, no se realiza este tipo de agrupamiento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">46,49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9162461669419243962" datatype="html">
+ <source>The isa plugin encapsulates the ISA library. It only runs on Intel processors.</source>
+ <target>El complemento isa encapsula la biblioteca ISA. Solo funciona en procesadores Intel.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2389282202903059852" datatype="html">
+ <source>The ISA plugin comes in two Reed Solomon forms.
+ If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.</source>
+ <target>El complemento ISA viene en dos formatos de Reed Solomon.
+ Si se define reed_sol_van, se trata de Vandermonde; si se define cauchy, se trata de Cauchy.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">53,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7319555444402547739" datatype="html">
+ <source>The shec plugin encapsulates the multiple SHEC library.
+ It allows ceph to recover data more efficiently than Reed Solomon codes.</source>
+ <target>El complemento shec encapsula las distintas bibliotecas SHEC.
+ Permite a Ceph recuperar datos de forma más eficiente que los códigos de Reed Solomon.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">57,58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7723217930035575928" datatype="html">
+ <source>The number of parity chunks each of which includes each data chunk in its
+ calculation range. The number is used as a durability estimator. For instance, if c=2,
+ 2 OSDs can be down without losing data.</source>
+ <target>El número de porciones de paridad. Cada uno de ellas incluye cada porción de datos
+ en su intervalo de cálculo. El número se usa como estimador de durabilidad. Por ejemplo, si c=2,
+ 2 OSD pueden estar inactivos sin que se pierdan datos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">59,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2054101840892270818" datatype="html">
+ <source>CLAY (short for coupled-layer) codes are erasure codes designed to
+ bring about significant savings in terms of network bandwidth and disk IO when a failed
+ node/OSD/rack is being repaired.</source>
+ <target>Los códigos CLAY (abreviación de coupled-layer, capa emparejada) son códigos de borrado diseñados
+ para ahorrar de forma significativa ancho de banda de red y E/S de disco cuando se repara
+ un nodo/OSD/bastidor que falla.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">64,66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491096236680229427" datatype="html">
+ <source>Number of OSDs requested to send data during recovery of a single chunk.
+ d needs to be chosen such that k+1 &lt;= d &lt;= k+m-1. The larger the d, the better
+ the savings.</source>
+ <target>El número de OSD a los que se ha pedido que envíen datos durante la recuperación de una sola porción.
+ El valor de d debe cumplir que k+1 &lt;= d &lt;= k+m-1. Cuanto mayor sea el valor de d, más
+ se ahorrará.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">67,69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2625895656705896729" datatype="html">
+ <source>scalar_mds specifies the plugin that is used as a building block
+ in the layered construction. It can be one of jerasure, isa, shec.</source>
+ <target>scalar_mds especifica el complemento que se usa como bloque
+ de construcción en la construcción a capas. Puede ser jerasure, isa o shec.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">70,71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6639141182731628232" datatype="html">
+ <source>technique specifies the technique that will be picked
+ within the 'scalar_mds' plugin specified. Supported techniques
+ are 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good', 'liber8tion' for jerasure, 'reed_sol_van',
+ 'cauchy' for isa and 'single', 'multiple' for shec.</source>
+ <target>technique especifica la técnica que se seleccionará
+ en el complemento &quot;scalar_mds&quot; especificado.
+Las técnicas admitidas son:
+ &quot;reed_sol_van&quot;, &quot;reed_sol_r6_op&quot;, &quot;cauchy_orig&quot;,
+ &quot;cauchy_good&quot; o &quot;liber8tion&quot; para jerasure; &quot;reed_sol_van&quot; o
+ &quot;cauchy&quot; para isa y &quot;single&quot; o &quot;multiple&quot; para shec.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">72,76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8172892264673403098" datatype="html">
+ <source>The name of the crush bucket used for the first step of the CRUSH rule.
+ For instance step take default.</source>
+ <target>El nombre de la papelera de CRUSH usado para el primer paso de la regla de CRUSH.
+ Por ejemplo, &quot;step take default&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">80,81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1654284403437084515" datatype="html">
+ <source>Ensure that no two chunks are in a bucket with the same failure
+ domain. For instance, if the failure domain is host no two chunks will be stored on the same
+ host. It is used to create a CRUSH rule step such as step chooseleaf host.</source>
+ <target>Asegúrese de que no hay dos porciones en una papelera con el mismo
+ dominio de error. Por ejemplo, si el dominio de error es host, no debe haber dos porciones almacenadas en el mismo
+ host. Se usa para crear un paso de regla de CRUSH, por ejemplo, &quot;step chooseleaf host&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">83,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7737703816676512224" datatype="html">
+ <source>Restrict placement to devices of a specific class
+ (e.g., ssd or hdd), using the crush device class names in the CRUSH map.</source>
+ <target>Restringe la colocación a dispositivos de una clase concreta
+ (p.ej., ssd o hdd) usando los nombre de clase de dispositivo CRUSH en el mapa de CRUSH.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9049698214199657456" datatype="html">
+ <source>Set the directory name from which the erasure code plugin is loaded.</source>
+ <target>Define el nombre de directorio del que se cargará el complemento de código de borrado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5514060020564877279" datatype="html">
+ <source>Allows all operations</source>
+ <target>Permite todas las operaciones</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4265406815683383218" datatype="html">
+ <source>Allows only operations that do not modify the server</source>
+ <target>Permite solo las operaciones que no modifican el servidor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="990071930378308183" datatype="html">
+ <source>Allows no access at all</source>
+ <target>No permite ningún tipo de acceso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7286983657616285612" datatype="html">
+ <source>Please specify a filesystem volume.</source>
+ <target>Especifique un volumen del sistema de archivos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8321762156640395170" datatype="html">
+ <source>The feature is disabled because Orchestrator is not available.</source>
+ <target>La función está inhabilitada porque Orchestrator no está disponible.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6718394293315494787" datatype="html">
+ <source>The Orchestrator backend doesn't support this feature.</source>
+ <target>El motor de Orchestrator no admite esta función.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5569418400096331461" datatype="html">
+ <source>-- Select the priority --</source>
+ <target>-- Seleccione la prioridad --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="802458941707537739" datatype="html">
+ <source>Low</source>
+ <target>Baja</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8063651736083474594" datatype="html">
+ <source>High</source>
+ <target>Alta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1717753935149218245" datatype="html">
+ <source>The user list data might be stale. If needed, you can manually reload it.</source>
+ <target>Puede que los datos de la lista de usuarios estén inactivos. Si fuera necesario, puede volver a cargarlos manualmente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/list-with-details.class.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7077550143229856452" datatype="html">
+ <source>Retrieving data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>Recuperando datos de <x id="PH" equiv-text="statusFor"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8231424898988217966" datatype="html">
+ <source>Retrieving data.</source>
+ <target>Recuperando datos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2357645764289315007" datatype="html">
+ <source>Please wait...</source>
+ <target>Espere...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="232824565824302482" datatype="html">
+ <source>Displaying previously cached data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>Mostrando datos guardados anteriormente en caché de <x id="PH" equiv-text="statusFor"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8721257977793603730" datatype="html">
+ <source>Displaying previously cached data.</source>
+ <target>Mostrando datos guardados anteriormente en caché.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6731313206654246255" datatype="html">
+ <source>Could not load data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>No es posible cargar los datos de <x id="PH" equiv-text="statusFor"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3359748695862553898" datatype="html">
+ <source>Could not load data.</source>
+ <target>No es posible cargar los datos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4836577225879717660" datatype="html">
+ <source>Please check the cluster health.</source>
+ <target>Consulte el estado del clúster.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1519954996184640001" datatype="html">
+ <source>Error</source>
+ <target>Error</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5037437391296624618" datatype="html">
+ <source>Information</source>
+ <target>Información</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4648900870671159218" datatype="html">
+ <source>Success</source>
+ <target>Correcto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3425367071066107827" datatype="html">
+ <source>Danger</source>
+ <target>Peligro</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c947210e2d162b6225083d18820ab602f58cd2d" datatype="html">
+ <source>Remove the custom configuration value. The default configuration will be inherited and used instead.</source>
+ <target>Elimina el valor de configuración personalizado. Se heredará y usará en su lugar la configuración por defecto.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="454ee9cb60b00446a8fb147fd2cc5eb836320586" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>.</source>
+ <target>El valor introducido es demasiado alto. No debe ser mayor que <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fc8a22825131e028336f60ef909ccbd96059703" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>.</source>
+ <target>El valor introducido es demasiado bajo. No debe ser menor que <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4dd200b7f9e19048cf90516843b40964f2af3fe9" datatype="html">
+ <source>Copy to Clipboard</source>
+ <target>Copiar al portapapeles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6110699a3562eeb15371063c0cf7f6bfd88a0209" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>?</source>
+ <target>¿Seguro que desea <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="549859e511ba5af0ea03fcaa620c472f08038969" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected items?</source>
+ <target>¿Seguro que desea <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> los elementos seleccionados?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="54839ebc827b73c9dc4e1df731c6d36a85036af7" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/>?</source>
+ <target>¿Seguro que desea <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> el elemento <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/> seleccionado?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2be8b7f04f0104d3fad90d079d8202b74f758b9a" datatype="html">
+ <source>Yes, I am sure.</source>
+ <target>Sí, seguro.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4523728183000855476" datatype="html">
+ <source>documentation</source>
+ <target>documentación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/doc/doc.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3099741642167775297" datatype="html">
+ <source>Download</source>
+ <target>Descargar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/download-button/download-button.component.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1417693714872528491" datatype="html">
+ <source>This field is required.</source>
+ <target>Este campo es obligatorio.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5321335688371682440" datatype="html">
+ <source>An error occurred.</source>
+ <target>Error.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5109325fb160b543f71a51e7511c00575057431" datatype="html">
+ <source>Loading panel data...</source>
+ <target>Cargando datos del panel...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a21acde005f80ceadb1391be1e7ff8b6d18188a0" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the monitoring functionality.</source>
+ <target>Consulte <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> para obtener información sobre cómo configurar y habilitar la función de supervisión.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a0ed4bd7b7add2a6febf7adf58d8cde5e421418" datatype="html">
+ <source>Grafana Dashboard doesn't exist. Please refer to <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to add dashboards to Grafana.</source>
+ <target>La consola de Grafana no existe. Consulte <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> para obtener información sobre cómo añadir consolas a Grafana.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e11830040bd64804a0555de76f291d5832772d4" datatype="html">
+ <source>Grafana Time Picker</source>
+ <target>Selector de hora de Grafana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="238c1ba845dd7330e8088165275919a1debf1ca3" datatype="html">
+ <source>Reset Settings</source>
+ <target>Restablecer ajustes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7888499255176013171" datatype="html">
+ <source>Last 5 minutes</source>
+ <target>Últimos 5 minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6892361549797455305" datatype="html">
+ <source>Last 15 minutes</source>
+ <target>Últimos 15 minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2653641162607195423" datatype="html">
+ <source>Last 30 minutes</source>
+ <target>Últimos 30 minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4117793269024790392" datatype="html">
+ <source>Last 1 hour (Default)</source>
+ <target>Última hora (opción por defecto)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2645733658763754077" datatype="html">
+ <source>Last 3 hours</source>
+ <target>Últimas 3 horas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7360078715633936807" datatype="html">
+ <source>Last 6 hours</source>
+ <target>Últimas 6 horas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5055313582241816303" datatype="html">
+ <source>Last 12 hours</source>
+ <target>Últimas 12 horas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9186529157286281693" datatype="html">
+ <source>Last 24 hours</source>
+ <target>Últimas 24 horas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4498682414491138092" datatype="html">
+ <source>Yesterday</source>
+ <target>Ayer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="929003859318769922" datatype="html">
+ <source>Today so far</source>
+ <target>Hoy hasta ahora</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5525943133564968818" datatype="html">
+ <source>Day before yesterday</source>
+ <target>Anteayer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6168755117727892817" datatype="html">
+ <source>Last 2 days</source>
+ <target>Los últimos 2 días</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7574807704224200535" datatype="html">
+ <source>This day last week</source>
+ <target>Este día la semana pasada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4420128118950221234" datatype="html">
+ <source>Previous week</source>
+ <target>La semana pasada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4063965603321223683" datatype="html">
+ <source>This week so far</source>
+ <target>Esta semana hasta ahora</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4873149362496451858" datatype="html">
+ <source>Last 7 days</source>
+ <target>Los últimos 7 días</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8586908745456864217" datatype="html">
+ <source>Previous month</source>
+ <target>El mes pasado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1647573304710886499" datatype="html">
+ <source>This month so far</source>
+ <target>Este mes hasta ahora</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2949150997160654358" datatype="html">
+ <source>Last 30 days</source>
+ <target>Los últimos 30 días</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7469939859049484736" datatype="html">
+ <source>Last 90 days</source>
+ <target>Los últimos 90 días</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847501198811458781" datatype="html">
+ <source>Last 6 months</source>
+ <target>Los últimos 6 meses</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7447583558445881102" datatype="html">
+ <source>Last 1 year</source>
+ <target>El último año</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="100513227838842152" datatype="html">
+ <source>Previous year</source>
+ <target>El año pasado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3650872673621947074" datatype="html">
+ <source>This year so far</source>
+ <target>Este año hasta ahora</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1262816694819959075" datatype="html">
+ <source>Last 2 years</source>
+ <target>Los últimos 2 años</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7878813844917362690" datatype="html">
+ <source>Last 5 years</source>
+ <target>Los últimos 5 años</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3fb5709e10166cbc85970cbff103db227dbeb813" datatype="html">
+ <source>Select a Language</source>
+ <target>Seleccione un idioma</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/language-selector/language-selector.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e52e9143145e1db5146258de81eae018a407b31" datatype="html">
+ <source>Clear notifications</source>
+ <target>Borrar notificaciones</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0b07bb6b7ff21ede439dd04eaf8872d1ecb84d8" datatype="html">
+ <source>Remove notification</source>
+ <target>Eliminar notificación</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e17a1d75189da843f541f7764f188f2b19a97df2" datatype="html">
+ <source>Duration:</source>
+ <target>Duración:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d4b37c6675c5b436a54c43d6716eec835e1aa7f" datatype="html">
+ <source>There are no notifications.</source>
+ <target>No hay notificaciones.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b20e42ac4354d449f2718428b5390933eef0c1b9" datatype="html">
+ <source>The feature is not supported in the current Orchestrator.</source>
+ <target>La función no se admite en la instancia actual de Orchestrator.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a437b8f93cf826817c04a4277edb1ae3a93a1ab" datatype="html">
+ <source>Orchestrator is not available. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the functionality.</source>
+ <target>Orchestrator no está disponible. Consulte <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> para obtener información sobre cómo configurar y habilitar la función.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">7,9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20b3d45b0c08a2951a9974fa20505e4de95250c9" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>less than 1<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day. Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <target>Su contraseña caduca en <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>menos de 1<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> día. Haga clic <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>aquí<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> para cambiarla ahora.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">9,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f34088c155e40ffb23770a465a65868ce772b2" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day(s). Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <target>Su contraseña caduca en <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> días. Haga clic <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>aquí<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> para cambiarla ahora.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8d1785038d461ec66b5799db21864182b35900a" datatype="html">
+ <source>Refresh</source>
+ <target>Actualizar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/refresh-selector/refresh-selector.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3417247046175131869" datatype="html">
+ <source>No items selected.</source>
+ <target>No se ha seleccionado ningún elemento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1034353870189672674" datatype="html">
+ <source>Deselect item to select again</source>
+ <target>Deseleccione el elemento para volver a seleccionarlo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4879298070255432995" datatype="html">
+ <source>Selection limit reached</source>
+ <target>Se ha alcanzado el límite de selección</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001227209911602786" datatype="html">
+ <source>Filter tags</source>
+ <target>Filtrar etiquetas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="791789583719406586" datatype="html">
+ <source>Add badge</source>
+ <target>Añadir insignia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="699988676752930063" datatype="html">
+ <source>There are no items available.</source>
+ <target>No hay ningún elemento disponible.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6702323d3760e3db0e2e785d567469d18beb120" datatype="html">
+ <source>The Ceph community needs your help to continue improving: please <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>Activate<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> the <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Telemetry<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> module.</source>
+ <target>La comunidad de Ceph necesita su ayuda para seguir mejorando: <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>active<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> el módulo <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Telemetría<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.html</context>
+ <context context-type="linenumber">8,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8770134622386151776" datatype="html">
+ <source>Telemetry activation reminder muted</source>
+ <target>Recordatorio de activación de telemetría silenciado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8352450862052130357" datatype="html">
+ <source>You can activate the module on the Telemetry configuration page (&lt;b&gt;Dashboard Settings&lt;/b&gt; -&gt; &lt;b&gt;Telemetry configuration&lt;/b&gt;) at any time.</source>
+ <target>Puede activar el módulo en la página de configuración de telemetría (&lt;b&gt;Ajustes de la consola&lt;/b&gt; &gt; &lt;b&gt;Configuración de telemetría&lt;/b&gt;) en cualquier momento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bc9e5365a581105ce37cf47d1d74e4ad9eb75ce" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e634c306cab9e8879c3392593714c1ceab85437d" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3249513483374643425" datatype="html">
+ <source>Add</source>
+ <target>Añadir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4359847060009771702" datatype="html">
+ <source>Set</source>
+ <target>Definir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935187492052582731" datatype="html">
+ <source>Submit</source>
+ <target>Enviar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4814285799071780083" datatype="html">
+ <source>Remove</source>
+ <target>Eliminar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8363450564548681668" datatype="html">
+ <source>Unset</source>
+ <target>Anular definición</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2159130950882492111" datatype="html">
+ <source>Cancel</source>
+ <target>Cancelar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1295614462098694869" datatype="html">
+ <source>Preview</source>
+ <target>Vista previa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2354817630223808522" datatype="html">
+ <source>Move</source>
+ <target>Mover</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3885497195825665706" datatype="html">
+ <source>Next</source>
+ <target>Siguiente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8890553633144307762" datatype="html">
+ <source>Back</source>
+ <target>Atrás</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5834780181397311898" datatype="html">
+ <source>Clone</source>
+ <target>Clonar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4323470180912194028" datatype="html">
+ <source>Copy</source>
+ <target>Copiar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2131301778880826094" datatype="html">
+ <source>Deep Scrub</source>
+ <target>Depuración profunda</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1704447209800801558" datatype="html">
+ <source>Destroy</source>
+ <target>Destruir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8343007008325027187" datatype="html">
+ <source>Evict</source>
+ <target>Expulsar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="408179081163888126" datatype="html">
+ <source>Flatten</source>
+ <target>Aplanar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="318900679147387932" datatype="html">
+ <source>Mark Down</source>
+ <target>Marcar para desactivar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5275142643521766706" datatype="html">
+ <source>Mark In</source>
+ <target>Marcar para incluir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6973272903386150199" datatype="html">
+ <source>Mark Lost</source>
+ <target>Marcar como perdido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1962653792210847411" datatype="html">
+ <source>Mark Out</source>
+ <target>Marcar para excluir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4424610588915076517" datatype="html">
+ <source>Protect</source>
+ <target>Proteger</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6041115344061899387" datatype="html">
+ <source>Rename</source>
+ <target>Renombrar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">164</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6770769801335635194" datatype="html">
+ <source>Restore</source>
+ <target>Restaurar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2003230525878010676" datatype="html">
+ <source>Reweight</source>
+ <target>Reequilibrar peso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5430834128563178593" datatype="html">
+ <source>Scrub</source>
+ <target>Depuración</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8461842260159597706" datatype="html">
+ <source>Show</source>
+ <target>Mostrar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5655608100705734230" datatype="html">
+ <source>Move to Trash</source>
+ <target>Mover a la papelera</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4622393909937403117" datatype="html">
+ <source>Unprotect</source>
+ <target>Desproteger</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1230154438678955604" datatype="html">
+ <source>Change</source>
+ <target>Cambiar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8450843381175865415" datatype="html">
+ <source>Enter Maintenance</source>
+ <target>Entrar en mantenimiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1610181371597502589" datatype="html">
+ <source>Exit Maintenance</source>
+ <target>Salir de mantenimiento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="676511611419004737" datatype="html">
+ <source>Start Drain</source>
+ <target>Iniciar vaciado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7170653322511987983" datatype="html">
+ <source>Stop Drain</source>
+ <target>Detener vaciado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5528551262937858942" datatype="html">
+ <source>Recreate</source>
+ <target>Volver a crear</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2502364444688691031" datatype="html">
+ <source>Expire</source>
+ <target>Caducar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6381490568322624964" datatype="html">
+ <source>Deleted</source>
+ <target>Suprimido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="231679111972850796" datatype="html">
+ <source>Added</source>
+ <target>Añadido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5406093358072761930" datatype="html">
+ <source>Removed</source>
+ <target>Eliminado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3008573030448240863" datatype="html">
+ <source>Edited</source>
+ <target>Editado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4381944803872489731" datatype="html">
+ <source>Canceled</source>
+ <target>Cancelado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754993936947658096" datatype="html">
+ <source>Previewed</source>
+ <target>En vista previa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6001163963116907226" datatype="html">
+ <source>Moved</source>
+ <target>Movido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4932744777596632840" datatype="html">
+ <source>Cloned</source>
+ <target>Clonado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2115592966120408375" datatype="html">
+ <source>Copied</source>
+ <target>Copiado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7937474560394832586" datatype="html">
+ <source>Deep Scrubbed</source>
+ <target>Depurado en profundidad</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6321562733889197649" datatype="html">
+ <source>Destroyed</source>
+ <target>Destruido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7460162290177581995" datatype="html">
+ <source>Flattened</source>
+ <target>Aplanado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3662010055028969035" datatype="html">
+ <source>Marked Down</source>
+ <target>Marcado como desactivado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5880434235404894589" datatype="html">
+ <source>Marked In</source>
+ <target>Marcado para incluir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="266997194072682078" datatype="html">
+ <source>Marked Lost</source>
+ <target>Marcado como perdido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">250</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4010544044592534535" datatype="html">
+ <source>Marked Out</source>
+ <target>Marcado para excluir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4776304093333411035" datatype="html">
+ <source>Protected</source>
+ <target>Protegido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2700903921419382511" datatype="html">
+ <source>Purged</source>
+ <target>Limpiado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5488667333459350160" datatype="html">
+ <source>Renamed</source>
+ <target>Renombrado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8044659850000829751" datatype="html">
+ <source>Restored</source>
+ <target>Restaurado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559472082694466366" datatype="html">
+ <source>Reweighted</source>
+ <target>Peso reequilibrado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022271525067453676" datatype="html">
+ <source>Rolled back</source>
+ <target>Revertido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2483217756816388123" datatype="html">
+ <source>Scrubbed</source>
+ <target>Depurado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7200036055090632378" datatype="html">
+ <source>Showed</source>
+ <target>Mostrado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7609648817347881129" datatype="html">
+ <source>Moved to Trash</source>
+ <target>Movido a la papelera</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7810326403606456469" datatype="html">
+ <source>Unprotected</source>
+ <target>Desprotegido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5620774899056099259" datatype="html">
+ <source>Recreated</source>
+ <target>Vuelto a crear</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464749780222721589" datatype="html">
+ <source>Expired</source>
+ <target>Caducado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">266</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e5e23363e949f7dcbaf034bdb141a561132a10e" datatype="html">
+ <source>Clear filters</source>
+ <target>Borrar filtros</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80cc9a12d4bf6fe454ed94b379eeaf915f920bb7" datatype="html">
+ <source>selected</source>
+ <target>seleccionados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <note priority="1" from="description">X selected</note>
+ </trans-unit>
+ <trans-unit id="0cb77511a9a148e05b9adf36cc07269956fbb29d" datatype="html">
+ <source>found</source>
+ <target>encontrados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <note priority="1" from="description">X found</note>
+ </trans-unit>
+ <trans-unit id="79347388740c50b7ac97e144c2494bb62912f312" datatype="html">
+ <source>total</source>
+ <target>total</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <note priority="1" from="description">X total</note>
+ </trans-unit>
+ <trans-unit id="2a3dab422cc892db037db8632bb84a6bf496e2d1" datatype="html">
+ <source>Expand/Collapse Row</source>
+ <target>Expandir o contraer fila</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4047162422391207122" datatype="html">
+ <source>Failed to load data.</source>
+ <target>Error al cargar los datos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.ts</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="709331713250198508" datatype="html">
+ <source>Loading form data...</source>
+ <target>Cargando datos de formulario...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3850344644863430180" datatype="html">
+ <source>Form data could not be loaded.</source>
+ <target>No es posible cargar los datos de formulario.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4626760504772708998" datatype="html">
+ <source>Size has to be at least <x id="PH" equiv-text="value"/> or more</source>
+ <target>El tamaño debe ser de <x id="PH" equiv-text="value"/> o más</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">428</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2880361802894657892" datatype="html">
+ <source>Size has to be at most <x id="PH" equiv-text="value"/> or less</source>
+ <target>El tamaño debe ser de <x id="PH" equiv-text="value"/> o menos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2807800733729323332" datatype="html">
+ <source>Yes</source>
+ <target>Sí</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3542042671420335679" datatype="html">
+ <source>No</source>
+ <target>No</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7789266940050748913" datatype="html">
+ <source>in %s</source>
+ <target>en %s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565573880632900017" datatype="html">
+ <source>%s ago</source>
+ <target>hace %s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="220300059326988179" datatype="html">
+ <source>a few seconds</source>
+ <target>unos segundos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2761143993878941513" datatype="html">
+ <source>%d seconds</source>
+ <target>%d segundos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7094767962693903153" datatype="html">
+ <source>a minute</source>
+ <target>un minuto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7597613755904774250" datatype="html">
+ <source>%d minutes</source>
+ <target>%d minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2757762976030115752" datatype="html">
+ <source>an hour</source>
+ <target>una hora</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9118454901758656303" datatype="html">
+ <source>%d hours</source>
+ <target>%d horas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7435193742089920080" datatype="html">
+ <source>a day</source>
+ <target>un día</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1821334622562842480" datatype="html">
+ <source>%d days</source>
+ <target>%d días</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7375306199026780379" datatype="html">
+ <source>a week</source>
+ <target>una semana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7272688256541915488" datatype="html">
+ <source>%d weeks</source>
+ <target>%d semanas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5761124614324704118" datatype="html">
+ <source>a month</source>
+ <target>un mes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="352195662913351589" datatype="html">
+ <source>%d months</source>
+ <target>%d meses</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7562153591649199139" datatype="html">
+ <source>a year</source>
+ <target>un año</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5424759741855527370" datatype="html">
+ <source>%d years</source>
+ <target>%d años</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7738182956549158907" datatype="html">
+ <source>Required rules for passwords:</source>
+ <target>Reglas requeridas para las contraseñas:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8839765875053270528" datatype="html">
+ <source>Must contain at least <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> characters</source>
+ <target>Debe tener al menos <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> caracteres</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3098731108593590794" datatype="html">
+ <source>Must not be the same as the previous one</source>
+ <target>No debe ser igual que la anterior</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9150236741862848105" datatype="html">
+ <source>Cannot contain the username</source>
+ <target>No puede contener el nombre de usuario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6395043854518867543" datatype="html">
+ <source>Cannot contain any configured keyword</source>
+ <target>No puede contener ninguna palabra clave configurada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="907558624910601703" datatype="html">
+ <source>Cannot contain any repetitive characters e.g. &quot;aaa&quot;</source>
+ <target>No puede contener ningún carácter repetido (p. ej., &quot;aaa&quot;)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514384270734082343" datatype="html">
+ <source>Cannot contain any sequential characters e.g. &quot;abc&quot;</source>
+ <target>No puede contener ninguna secuencia de caracteres (p. ej., &quot;abc&quot;)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4119354814383293871" datatype="html">
+ <source>Must consist of characters from the following groups:
+ * Alphabetic a-z, A-Z
+ * Numbers 0-9
+ * Special chars: !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * Any other characters (signs)</source>
+ <target>Debe incluir carecteres de los grupos siguientes:
+ * Letras (a-z, A-Z)
+ * Números (0-9)
+ * Caracteres especiales (!&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~)
+ * Cualquier otro caracter (signos)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">30,34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8649061117624699581" datatype="html">
+ <source>Your matcher seems to match no currently defined rule or active alert.</source>
+ <target>Parece que el buscador de coincidencias no encuentra ninguna regla definida ni alerta activa que coincida.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7122912874364762704" datatype="html">
+ <source>no active alerts</source>
+ <target>no hay alertas activas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7388215679576832341" datatype="html">
+ <source>1 active alert</source>
+ <target>1 alerta activa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3112400568960537267" datatype="html">
+ <source><x id="PH" equiv-text="alerts"/> active alerts</source>
+ <target><x id="PH" equiv-text="alerts"/> alertas activas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6264717417287230743" datatype="html">
+ <source>Matches 1 rule</source>
+ <target>Coincide con una regla</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054663176394183966" datatype="html">
+ <source>Matches <x id="PH" equiv-text="rules"/> rules</source>
+ <target>Coincide con <x id="PH" equiv-text="rules"/> reglas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6674225401121099210" datatype="html">
+ <source><x id="PH" equiv-text="rule"/> with <x id="PH_1" equiv-text="alert"/>.</source>
+ <target><x id="PH" equiv-text="rule"/> con <x id="PH_1" equiv-text="alert"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5659908877047925719" datatype="html">
+ <source>Quality of Service</source>
+ <target>Calidad del servicio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1277565045885499475" datatype="html">
+ <source>BPS Limit</source>
+ <target>Límite de BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2289210323987692906" datatype="html">
+ <source>The desired limit of IO bytes per second.</source>
+ <target>El límite deseado de bytes de E/S por segundo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753589939879013605" datatype="html">
+ <source>IOPS Limit</source>
+ <target>Límite de IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2213985059444278522" datatype="html">
+ <source>The desired limit of IO operations per second.</source>
+ <target>El límite deseado de operaciones de E/S por segundo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2487530611825582289" datatype="html">
+ <source>Read BPS Limit</source>
+ <target>Límite de BPS de lectura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8071352270469595250" datatype="html">
+ <source>The desired limit of read bytes per second.</source>
+ <target>El límite deseado de bytes de lectura por segundo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1632513758247239690" datatype="html">
+ <source>Read IOPS Limit</source>
+ <target>Límite de IOPS de lectura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2361786794607418566" datatype="html">
+ <source>The desired limit of read operations per second.</source>
+ <target>El límite deseado de operaciones de lectura por segundo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="894600353504285551" datatype="html">
+ <source>Write BPS Limit</source>
+ <target>Límite de BPS de escritura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911437671369366025" datatype="html">
+ <source>The desired limit of write bytes per second.</source>
+ <target>El límite deseado de bytes de escritura por segundo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2947346368707443195" datatype="html">
+ <source>Write IOPS Limit</source>
+ <target>Límite de IOPS de escritura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5506349527983391356" datatype="html">
+ <source>The desired limit of write operations per second.</source>
+ <target>El límite deseado de operaciones de escritura por segundo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559424229658244943" datatype="html">
+ <source>BPS Burst</source>
+ <target>Ráfaga de BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3454058701331860330" datatype="html">
+ <source>The desired burst limit of IO bytes.</source>
+ <target>El límite deseado de ráfaga de bytes de E/S.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171005761926448741" datatype="html">
+ <source>IOPS Burst</source>
+ <target>Ráfaga de IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4939532784700485729" datatype="html">
+ <source>The desired burst limit of IO operations.</source>
+ <target>El límite deseado de ráfaga de operaciones de E/S.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6273492199526646930" datatype="html">
+ <source>Read BPS Burst</source>
+ <target>Ráfaga de BPS de lectura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3105467595643777520" datatype="html">
+ <source>The desired burst limit of read bytes.</source>
+ <target>El límite deseado de ráfaga de bytes de lectura.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2170715106679765467" datatype="html">
+ <source>Read IOPS Burst</source>
+ <target>Ráfaga de IOPS de lectura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6234106755510510672" datatype="html">
+ <source>The desired burst limit of read operations.</source>
+ <target>El límite deseado de ráfaga de operaciones de lectura.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="228509518172572466" datatype="html">
+ <source>Write BPS Burst</source>
+ <target>Ráfaga de BPS de escritura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7803279807796571240" datatype="html">
+ <source>The desired burst limit of write bytes.</source>
+ <target>El límite deseado de ráfaga de bytes de escritura.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9125474584914848055" datatype="html">
+ <source>Write IOPS Burst</source>
+ <target>Ráfaga de IOPS de escritura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5839129348567326667" datatype="html">
+ <source>The desired burst limit of write operations.</source>
+ <target>El límite deseado de ráfaga de operaciones de escritura.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="614961883076556986" datatype="html">
+ <source>Failed to <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></source>
+ <target>Error al <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="489145301781720653" datatype="html">
+ <source>Executing</source>
+ <target>Ejecutando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4238828029954346941" datatype="html">
+ <source>execute</source>
+ <target>ejecutar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7196604637389554584" datatype="html">
+ <source>Executed</source>
+ <target>Ejecutado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4418441687454700644" datatype="html">
+ <source>unknown task</source>
+ <target>tarea desconocida</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8667665916832796867" datatype="html">
+ <source>Creating</source>
+ <target>Creando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6031236679730054907" datatype="html">
+ <source>create</source>
+ <target>crear</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5593033420216313122" datatype="html">
+ <source>Updating</source>
+ <target>Actualizando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6100869651653026893" datatype="html">
+ <source>update</source>
+ <target>actualizar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3141301060598402455" datatype="html">
+ <source>Deleting</source>
+ <target>Suprimiendo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3420504288275541125" datatype="html">
+ <source>Adding</source>
+ <target>Añadiendo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1059784693423848532" datatype="html">
+ <source>add</source>
+ <target>añadir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594819887188505274" datatype="html">
+ <source>Removing</source>
+ <target>Eliminando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2123171795960509943" datatype="html">
+ <source>remove</source>
+ <target>eliminar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1946427188770321847" datatype="html">
+ <source>Importing</source>
+ <target>Importando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8495827411619139669" datatype="html">
+ <source>import</source>
+ <target>importar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218459863491436562" datatype="html">
+ <source>Imported</source>
+ <target>Importado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6534993668932538712" datatype="html">
+ <source>RBD '<x id="PH" equiv-text="metadata.image_spec"/>'</source>
+ <target>RBD <x id="PH" equiv-text="metadata.image_spec"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8237287859948228705" datatype="html">
+ <source>RBD snapshot '<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>'</source>
+ <target>Instantánea de RBD <x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2328067975897167268" datatype="html">
+ <source>mirroring site name</source>
+ <target>duplicando nombre del sitio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4433460322631470833" datatype="html">
+ <source>bootstrap token</source>
+ <target>testigo de arranque</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7044591639782280183" datatype="html">
+ <source>mirror mode for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>modo de duplicación para el repositorio <x id="PH" equiv-text="metadata.pool_name"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7109746474198366468" datatype="html">
+ <source>mirror peer for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>par de duplicación para el repositorio <x id="PH" equiv-text="metadata.pool_name"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6201476020617351396" datatype="html">
+ <source>all dashboards</source>
+ <target>todas las consolas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7268953097700363232" datatype="html">
+ <source>Identifying</source>
+ <target>Identificando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4337678035264231187" datatype="html">
+ <source>identify</source>
+ <target>identificar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7257219307556106552" datatype="html">
+ <source>Identified</source>
+ <target>Identificado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6002370161381995023" datatype="html">
+ <source>device '<x id="PH" equiv-text="metadata.device"/>' on host '<x id="PH_1" equiv-text="metadata.hostname"/>'</source>
+ <target>dispositivo <x id="PH" equiv-text="metadata.device"/> en el host <x id="PH_1" equiv-text="metadata.hostname"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5580298273054260850" datatype="html">
+ <source>OSDs (DriveGroups: <x id="PH" equiv-text="metadata.tracking_id"/>)</source>
+ <target>OSDs (DriveGroups: <x id="PH" equiv-text="metadata.tracking_id"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2182125722527364040" datatype="html">
+ <source>Name is already used by <x id="PH" equiv-text="this.pool(metadata)"/>.</source>
+ <target><x id="PH" equiv-text="this.pool(metadata)"/> ya está usando el nombre.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">182</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7892856315477304281" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> is busy.</source>
+ <target><x id="PH" equiv-text="this.rbd.default(metadata)"/> está ocupado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4690045751984117407" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> contains snapshots.</source>
+ <target><x id="PH" equiv-text="this.rbd.default(metadata)"/> contiene instantáneas.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="562148565853868662" datatype="html">
+ <source>Cloning</source>
+ <target>Clonando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1197352830433807469" datatype="html">
+ <source>clone</source>
+ <target>clonar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1692004144561317867" datatype="html">
+ <source>Snapshot of <x id="PH" equiv-text="this.rbd.child(metadata)"/> must be protected.</source>
+ <target>La instantánea de <x id="PH" equiv-text="this.rbd.child(metadata)"/> debe protegerse.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8531200838331320284" datatype="html">
+ <source>Copying</source>
+ <target>Copiando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6862265996781523030" datatype="html">
+ <source>copy</source>
+ <target>copiar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3556912098733712857" datatype="html">
+ <source>Flattening</source>
+ <target>Aplanando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2488773646187451754" datatype="html">
+ <source>flatten</source>
+ <target>aplanar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="704305783678486635" datatype="html">
+ <source>Cannot unprotect <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> because it contains child images.</source>
+ <target>No es posible anular la protección de <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> porque contiene imágenes hijas.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">223,225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101271773452792348" datatype="html">
+ <source>Cannot delete <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/> because it's protected.</source>
+ <target>No es posible suprimir <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/> porque está protegido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5143010940199748580" datatype="html">
+ <source>Rolling back</source>
+ <target>Revirtiendo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1315686250907089544" datatype="html">
+ <source>rollback</source>
+ <target>revertir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5010267418211867946" datatype="html">
+ <source>Moving</source>
+ <target>Moviendo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4366763205960752449" datatype="html">
+ <source>move</source>
+ <target>mover</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="695867152524584829" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_spec"/>' to trash</source>
+ <target>la imagen <x id="PH" equiv-text="metadata.image_spec"/> a la papelera</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423442774536615202" datatype="html">
+ <source>Could not find image.</source>
+ <target>No se encuentra la imagen.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2622324641113512527" datatype="html">
+ <source>Restoring</source>
+ <target>Restaurando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3347932678307141902" datatype="html">
+ <source>restore</source>
+ <target>restaurar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7488038030362249932" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>' into '<x id="PH_1" equiv-text="metadata.new_image_name"/>'</source>
+ <target>la imagen <x id="PH" equiv-text="metadata.image_id_spec"/> en <x id="PH_1" equiv-text="metadata.new_image_name"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565688512490959949" datatype="html">
+ <source>Image name '<x id="PH" equiv-text="metadata.new_image_name"/>' is already in use.</source>
+ <target>El nombre de imagen <x id="PH" equiv-text="metadata.new_image_name"/> ya está en uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6331051389974655106" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>'</source>
+ <target>imagen <x id="PH" equiv-text="metadata.image_id_spec"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8245559899946787147" datatype="html">
+ <source>Purging</source>
+ <target>Limpiando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7879437654311684252" datatype="html">
+ <source>purge</source>
+ <target>limpiar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1440427157062670480" datatype="html">
+ <source>all pools</source>
+ <target>todos los repositorios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8677740163708263843" datatype="html">
+ <source>images from <x id="PH" equiv-text="message"/></source>
+ <target>imágenes de <x id="PH" equiv-text="message"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011237345035114219" datatype="html">
+ <source>Cannot disable mirroring because it contains a peer.</source>
+ <target>No es posible inhabilitar la duplicación porque contiene un par</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">292</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7391584598242145869" datatype="html">
+ <source>host '<x id="PH" equiv-text="metadata.hostname"/>'</source>
+ <target>host <x id="PH" equiv-text="metadata.hostname"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6964302691596180722" datatype="html">
+ <source>OSD '<x id="PH" equiv-text="metadata.svc_id"/>'</source>
+ <target>OSD <x id="PH" equiv-text="metadata.svc_id"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="488305686602466689" datatype="html">
+ <source>pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>repositorio <x id="PH" equiv-text="metadata.pool_name"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5921392748828575278" datatype="html">
+ <source>erasure code profile '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <target>perfil de código de borrado <x id="PH" equiv-text="metadata.name"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2423915105798557698" datatype="html">
+ <source>crush rule '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <target>reglas de CRUSH <x id="PH" equiv-text="metadata.name"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">370</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8273044996643438592" datatype="html">
+ <source>target '<x id="PH" equiv-text="metadata.target_iqn"/>'</source>
+ <target>destino <x id="PH" equiv-text="metadata.target_iqn"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5474643443735437364" datatype="html">
+ <source>NFS '<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>'</source>
+ <target>NFS &quot;<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">378,380</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2235495382025026939" datatype="html">
+ <source>Service '<x id="PH" equiv-text="metadata.service_name"/>'</source>
+ <target>Servicio <x id="PH" equiv-text="metadata.service_name"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ </body>
+ </file>
+</xliff> \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.fr-FR.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.fr-FR.xlf
new file mode 100644
index 000000000..5077d68c5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.fr-FR.xlf
@@ -0,0 +1,14885 @@
+<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en-US" datatype="plaintext" original="ng2.template" target-language="fr-FR">
+ <body>
+ <trans-unit id="ngb.alert.close" datatype="html">
+ <source>Close</source>
+ <target>Fermer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/alert/alert.ts</context>
+ <context context-type="linenumber">58,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.slide-number" datatype="html">
+ <source> Slide <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> of <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </source>
+ <target> Diapositive<x id="INTERPOLATION" equiv-text="OnHover$ = new"/> sur <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">114,118</context>
+ </context-group>
+ <note priority="1" from="description">Currently selected slide number read by screen reader</note>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.previous" datatype="html">
+ <source>Previous</source>
+ <target>Précédent</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">132,134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.next" datatype="html">
+ <source>Next</source>
+ <target>Suivant</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">147,152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-month" datatype="html">
+ <source>Select month</source>
+ <target>Sélectionnez un mois</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">44,49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">49,50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-year" datatype="html">
+ <source>Select year</source>
+ <target>Sélectionnez une année</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">59,63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.previous-month" datatype="html">
+ <source>Previous month</source>
+ <target>Le mois dernier</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">24,27</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">35,36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.next-month" datatype="html">
+ <source>Next month</source>
+ <target>Mois suivant</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">47,50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">60,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first" datatype="html">
+ <source>««</source>
+ <target>««</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">182,183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous" datatype="html">
+ <source>«</source>
+ <target>«</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">186,190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next" datatype="html">
+ <source>»</source>
+ <target>»</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">194,195</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last" datatype="html">
+ <source>»»</source>
+ <target>»»</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">201,204</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first-aria" datatype="html">
+ <source>First</source>
+ <target>Premier</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">208,209</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous-aria" datatype="html">
+ <source>Previous</source>
+ <target>Précédent</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">215,216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next-aria" datatype="html">
+ <source>Next</source>
+ <target>Suivant</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">226,228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last-aria" datatype="html">
+ <source>Last</source>
+ <target>Dernier</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.progressbar.value" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="; } /** *"/></source>
+ <target><x id="INTERPOLATION" equiv-text="; } /** *"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/progressbar/progressbar.ts</context>
+ <context context-type="linenumber">32,38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.HH" datatype="html">
+ <source>HH</source>
+ <target>HH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">40,41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.hours" datatype="html">
+ <source>Hours</source>
+ <target>Heures</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.MM" datatype="html">
+ <source>MM</source>
+ <target>MM</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">51,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.minutes" datatype="html">
+ <source>Minutes</source>
+ <target>Minutes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-hours" datatype="html">
+ <source>Increment hours</source>
+ <target>Incrémenter les heures</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">63,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-hours" datatype="html">
+ <source>Decrement hours</source>
+ <target>Décrémenter les heures</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">69,70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-minutes" datatype="html">
+ <source>Increment minutes</source>
+ <target>Incrémenter les minutes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">76,78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-minutes" datatype="html">
+ <source>Decrement minutes</source>
+ <target>Décrémenter les minutes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">82,84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.SS" datatype="html">
+ <source>SS</source>
+ <target>SS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.seconds" datatype="html">
+ <source>Seconds</source>
+ <target>Secondes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">92,93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-seconds" datatype="html">
+ <source>Increment seconds</source>
+ <target>Incrémenter les secondes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">100,101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-seconds" datatype="html">
+ <source>Decrement seconds</source>
+ <target>Décrémenter les secondes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">106,110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.AM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></source>
+ <target><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">115,121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.PM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="t() meridian: b"/></source>
+ <target><x id="INTERPOLATION" equiv-text="t() meridian: b"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">123,131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.toast.close-aria" datatype="html">
+ <source>Close</source>
+ <target>Fermer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/toast/toast.ts</context>
+ <context context-type="linenumber">78,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8835b9e49a3348b0a2f2162c21118af1f4bee45a" datatype="html">
+ <source>Must be greater than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>.</source>
+ <target>Doit être supérieur ou égal à <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbddac59563c8c126e3fe28691e4e247614fcbd1" datatype="html">
+ <source>Must be less than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>.</source>
+ <target>Doit être inférieur ou égal à <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5" datatype="html">
+ <source>Overview</source>
+ <target>Présentation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbd2045d5c37e4bb39a3c0fb62ea1ddf70a12838" datatype="html">
+ <source>Targets</source>
+ <target>Cibles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a674ab267d1934bf395f87ca1503fd474296893f" datatype="html">
+ <source>iSCSI Topology</source>
+ <target>Topologie iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8953033926734869941" datatype="html">
+ <source>Name</source>
+ <target>Nom</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6603000223840533819" datatype="html">
+ <source>Current</source>
+ <target>Actuel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5607669932062416162" datatype="html">
+ <source>Default</source>
+ <target>Valeur par défaut</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6803e31b7395d94934e091a49a9524026b59b018" datatype="html">
+ <source>Discovery Authentication</source>
+ <target>Authentification de la découverte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e08a77594f3d89311cdf6da5090044270909c194" datatype="html">
+ <source>User</source>
+ <target>Utilisateur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">381</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7cbdabcece469fab89cfa687ab152bca18b97498" datatype="html">
+ <source>This field is required.</source>
+ <target>Ce champ est obligatoire.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">368</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">423</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">481</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">291</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">343</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">407</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">490</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">516</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">556</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">573</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">590</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">647</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">672</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">299</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">195</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">520</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">614</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">651</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f717bad2da5944a2567a52f971ccc6806db85805" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>Les noms d'utilisateur doivent avoir une longueur comprise entre 8 et 64 caractères et peuvent contenir des caractères alphanumériques : '.', '@', '-', '_' ou ':'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">28,29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">85,86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c32ef07f8803a223a83ed17024b38e8d82292407" datatype="html">
+ <source>Password</source>
+ <target>Mot de passe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">403</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">581</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="001e1836299d8d3b84eaebe2fa051325beab3f00" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>Les mots de passe doivent avoir une longueur comprise entre 12 et 16 caractères et peuvent contenir des caractères alphanumériques : '@', '-', '_' ou '/'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">61,62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">118,119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff40391de7a1944ea95091e4045cc34c4979b736" datatype="html">
+ <source>Mutual User</source>
+ <target>Utilisateur commun</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cf73dbebe99b737c4d288788182fc356e3c93d3" datatype="html">
+ <source>Mutual Password</source>
+ <target>Mot de passe commun</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594987303599690088" datatype="html">
+ <source>Updated discovery authentication</source>
+ <target>Authentification de la découverte mise à jour</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb127ea03835b3230f0ed981c7080e2ccb879621" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <note priority="1" from="description">form title</note>
+ </trans-unit>
+ <trans-unit id="1406c2fb12a20c1528b19bcc5e24a6a2386167f3" datatype="html">
+ <source>Target IQN</source>
+ <target>IQN cible</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5fe42339be910372fa689f559155631862d218e8" datatype="html">
+ <source>IQN has wrong pattern.</source>
+ <target>Modèle IQN incorrect.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="050a7ff057d1e895357540406b6be5652b4d1c71" datatype="html">
+ <source>An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'</source>
+ <target>Un IQN est associé à la notation 'iqn.$year-$month.$reversedAddress:$definedName'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8ada4b53396d8366db00a435acc61d53d857047" datatype="html">
+ <source>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</source>
+ <target>Par exemple : iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e" datatype="html">
+ <source>More information</source>
+ <target>Plus d'informations</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9b1aa85dfc6849196e64060db02c5410de69b7a1" datatype="html">
+ <source>This target has modified advanced settings.</source>
+ <target>Des paramètres avancés de cette cible ont été modifiés.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6990ad8d6182662e864495ac31c3758cda1c7a28" datatype="html">
+ <source>Portals</source>
+ <target>Portails</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a3ac2b4137d723fd9878cd357c2012ff6c07973" datatype="html">
+ <source>Add portal</source>
+ <target>Ajouter un portail</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3638c01b6c34066438909713ec96087c813fc7e" datatype="html">
+ <source>At least <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> gateways are required.</source>
+ <target>Au moins <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> passerelles sont obligatoires.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b73f7f5060fb22a1e9ec462b1bb02493fa3ab866" datatype="html">
+ <source>Images</source>
+ <target>Images</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">495</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">629</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9aff25be088f0efe3eaaf62edf2bff41cc41a617" datatype="html">
+ <source>Backstore: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </source>
+ <target>Backstore : <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e3484cae8b118c576ca2815bf9c9406c2eb2cae3" datatype="html">
+ <source>This image has modified settings.</source>
+ <target>Des paramètres avancés de cette image ont été modifiés.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1dff11e0820b6722ab240169f1232d70a54beaaa" datatype="html">
+ <source>Duplicated LUN numbers.</source>
+ <target>Numéros LUN en double.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bf2dccf92ccff6e3b091792bf4205595406e1bfb" datatype="html">
+ <source>Duplicated WWN.</source>
+ <target>WWN en double.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="808038f912fdc7f0e03f82d4afd3bf9178527fc8" datatype="html">
+ <source>Add image</source>
+ <target>Ajouter une image</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">656</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66c5fb27f52e75b70ca4b670b9b15a2a51cf9543" datatype="html">
+ <source>ACL authentication</source>
+ <target>Authentification ACL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="137fbf154ecad4d580354db0858b76faea7e4686" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>Les noms d'utilisateur doivent avoir une longueur comprise entre 8 à 64 caractères et peuvent contenir des caractères alphanumériques : '.', '@', '-', '_' ou ':'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">227,228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">287,288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="361771c32dd2254d77fd3fbf006b008983fe5907" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>Les mots de passe doivent avoir une longueur comprise entre 12 et 16 caractères et peuvent contenir des caractères alphanumériques : '@', '-', '_' ou '/'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">262,263</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">323,324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f494bd31f095f6dcc656ce87ec2dcf07a2e9b30c" datatype="html">
+ <source>Initiators</source>
+ <target>Initiateurs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">335</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">588</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e98239d8a6be1100119ff4b5630c822b82786740" datatype="html">
+ <source>Initiator</source>
+ <target>Initiateur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2c5059d8cda15d8d03e2cce30f2d139623d9a91" datatype="html">
+ <source>Client IQN</source>
+ <target>IQN client</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="107d5aabce23d900f0a80e6ddc1c10e29aa0bed8" datatype="html">
+ <source>Initiator IQN needs to be unique.</source>
+ <target>L'IQN de l'initiateur doit être unique.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e7cad911fa524e512d9744b16358b7ee6791385" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>Les noms d'utilisateur doivent avoir une longueur comprise entre 8 et 64 caractères et peuvent contenir des caractères alphanumériques : '.', '@', '-', '_' ou ':'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">394,395</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">452,453</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7f2c186d181206d0d2b1ff74819081a010f10bf" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>Les mots de passe doivent avoir une longueur comprise entre 12 et 16 caractères et peuvent contenir des caractères alphanumériques '@', '-', '_' ou '/'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">427,428</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">485,486</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d1878d5fc761cbe9614bfd87047a740c82a6951" datatype="html">
+ <source>Initiator belongs to a group. Images will be configure in the group.</source>
+ <target>L'initiateur appartient à un groupe dans lequel les images seront configurées.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">515</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0de67b9d97fafbf200f9451e8388ee8128a56ac" datatype="html">
+ <source>No items added.</source>
+ <target>Aucun élément ajouté.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">671</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d565e47726158e428ecdc952fc9233b9b7d7f049" datatype="html">
+ <source>Add initiator</source>
+ <target>Ajouter un initiateur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">616</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c22ba03540aa3217da059f45e7eab138b51a96e2" datatype="html">
+ <source>Groups</source>
+ <target>Groupes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c90059afafb7e160384d9f512797c95bb95c6dc" datatype="html">
+ <source>Group</source>
+ <target>Groupe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cff1428d10d59d14e45edec3c735a27b5482db59" datatype="html">
+ <source>Name</source>
+ <target>Nom</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">576</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3084948274cff4f56d0f431af47240e9cf02fcc7" datatype="html">
+ <source>Add group</source>
+ <target>Ajouter un groupe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">676</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6634268061646442252" datatype="html">
+ <source>There are no portals available.</source>
+ <target>Il n'y a aucun portail disponible.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4587015892789840153" datatype="html">
+ <source>There are no images available.</source>
+ <target>Il n'y a aucune image disponible.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7896905042057267575" datatype="html">
+ <source>There are no images available. Please make sure you add an image to the target.</source>
+ <target>Il n'y a aucune image disponible. Veillez à ajouter une image à la cible.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6765423558085969805" datatype="html">
+ <source>There are no initiators available. Please make sure you add an initiator to the target.</source>
+ <target>Il n'y a aucun initiateur disponible. Veillez à ajouter un initiateur à la cible.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2539932200265667453" datatype="html">
+ <source>target</source>
+ <target>cible</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="051dcc342cfa5c1eaf187a2001aaa162379a160c" datatype="html">
+ <source>Configure</source>
+ <target>Configurer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e515f954730279c31d5301f02479666d6264e8b" datatype="html">
+ <source>Changing these parameters from their default values is usually not necessary.</source>
+ <target>Il n'est généralement pas nécessaire de modifier ces paramètres par défaut.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e2591df099ddac796cda401c5f282da779d45f2" datatype="html">
+ <source>Identifier</source>
+ <target>Identifiant</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62480a4859976427cf18fc8ef41d3a438eda0412" datatype="html">
+ <source>lun</source>
+ <target>lun</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8afc9eb4405e0aa554b2ba14140ef790cdecc040" datatype="html">
+ <source>wwn</source>
+ <target>wwn</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
+ <source>Settings</source>
+ <target>Paramètres</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69a47cbabcc51ca942606e1d8da0ec11f98a2690" datatype="html">
+ <source>Backstore</source>
+ <target>Backstore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="339878da255ab55447c43afef8d9b2f9753bf5f6" datatype="html">
+ <source>Advanced Settings</source>
+ <target>Paramètres avancés</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="332227f088a4877b3c11f5fb3ae8bc812c470fae" datatype="html">
+ <source>iSCSI Targets not available</source>
+ <target>Cibles iSCSI non disponibles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7fba666f1fff0182e570f12133fb3d622d9ea6" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the iSCSI Targets management functionality.</source>
+ <target>Veuillez consulter <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> pour apprendre comment configurer et activer la fonctionnalité de gestion des cibles iSCSI.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3b301d0044f62c92af0da53d7aaca52a436a547d" datatype="html">
+ <source>Available information:</source>
+ <target>Informations disponibles :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8414a5cb9d71cc1b21b10e4a9d1f2dad558f3361" datatype="html">
+ <source>Discovery authentication</source>
+ <target>Authentification de la découverte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4854396465510517671" datatype="html">
+ <source>Target</source>
+ <target>Cible</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4093869278527257288" datatype="html">
+ <source>Portals</source>
+ <target>Portails</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="414887388288176527" datatype="html">
+ <source>Images</source>
+ <target>Images</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="798573158169239055" datatype="html">
+ <source># Sessions</source>
+ <target>Nbre de sessions</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="646929398175374220" datatype="html">
+ <source>Unavailable gateway(s)</source>
+ <target>Passerelle(s) non disponible(s)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2350612272163013640" datatype="html">
+ <source>Target has active sessions</source>
+ <target>La cible comporte des sessions actives</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4782410538666829801" datatype="html">
+ <source>iSCSI target</source>
+ <target>Cible iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">227</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8a9910cd114c1deb9af74f6f99b4173403965bf2" datatype="html">
+ <source>Gateways</source>
+ <target>Passerelles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911214550882917183" datatype="html">
+ <source>State</source>
+ <target>État</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4121862424558610140" datatype="html">
+ <source># Targets</source>
+ <target>Nbre de cibles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101197021456818771" datatype="html">
+ <source>Pool</source>
+ <target>Réserve</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3012906865384504293" datatype="html">
+ <source>Image</source>
+ <target>Image</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2699995524827665158" datatype="html">
+ <source>Backstore</source>
+ <target>Backstore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3559214740809905405" datatype="html">
+ <source>Read Bytes</source>
+ <target>Octets de lecture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1580583760095064067" datatype="html">
+ <source>Write Bytes</source>
+ <target>Octets d'écriture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7225917547116479918" datatype="html">
+ <source>Read Ops</source>
+ <target>Opérations de lecture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6417507714454914481" datatype="html">
+ <source>Write Ops</source>
+ <target>Opérations d'écriture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="257147267065394003" datatype="html">
+ <source>A/O Since</source>
+ <target>A/O depuis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ecbc084370a732fc3cde1966a60af78d71424ab4" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>Créer un jeton Bootstrap</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603e9cc3ef2aab57f2b0a00e465b23b9cabefd9c" datatype="html">
+ <source>To create a bootstrap token which can be imported by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Generate<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Pour créer un jeton Bootstrap pouvant être importé par une grappe de sites homologues, indiquez le nom du site local, sélectionnez les réserves pour lesquelles la mise en miroir sera activée, puis cliquez sur  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Générer<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="660f97cd3188f8a04bd03b79e703fec72c6df04c" datatype="html">
+ <source>Site Name</source>
+ <target>Nom du site</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2fecea01ce1d44114ee45144eff6d47a5016a74f" datatype="html">
+ <source>Name...</source>
+ <target>Nom...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92899fa68e8ca108912163ff58edc8540e453787" datatype="html">
+ <source>Pools</source>
+ <target>Réserves</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c2a1dc72cffaf7ab3dc5599bf77b0a7fcad2b20" datatype="html">
+ <source>At least one pool is required.</source>
+ <target>Au moins une réserve est requise.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b258b258b4cc475ceb2871305b61756b0134f4a" datatype="html">
+ <source>Generate</source>
+ <target>Générer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1edc1fc6cfbbb22353050ad6788508b3ed584f53" datatype="html">
+ <source>Token</source>
+ <target>Jeton</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff785f5596aef34a93b9b4d1023e95c62eef5740" datatype="html">
+ <source>Generated token...</source>
+ <target>Jeton généré...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8" datatype="html">
+ <source>Close</source>
+ <target>Fermer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5467a6bb0e7fade6def7499400d5e2a7d8d3da20" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>Importer un jeton Bootstrap</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bb7aee0dec5164f45c0aa2f35f2fb2149d2c1d2" datatype="html">
+ <source>To import a bootstrap token which was created by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, provide the generated token, and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Import<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Pour importer un jeton Bootstrap pouvant être créé par une grappe de sites homologues, indiquez le nom du site local, sélectionnez les réserves pour lesquelles la mise en miroir sera activée, indiquez le jeton généré, puis cliquez sur <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Importer<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9200e09686136a1d42adfb89c12fbfef2deea125" datatype="html">
+ <source>Direction</source>
+ <target>Direction</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9761484679958da8d12841a4efa5964d33fae575" datatype="html">
+ <source>The token is invalid.</source>
+ <target>Le jeton n'est pas valide.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2381859602529023966" datatype="html">
+ <source>Instance</source>
+ <target>Instance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8040881171107393560" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1605455101862010019" datatype="html">
+ <source>Hostname</source>
+ <target>Nom d'hôte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2724055831234181057" datatype="html">
+ <source>Version</source>
+ <target>Version</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2041675390931385838" datatype="html">
+ <source>Health</source>
+ <target>Santé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87bd96249f8afc23f5301cddb57b1464a98e71a" datatype="html">
+ <source>Edit site name</source>
+ <target>Modifier le nom du site</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cfff72c667274c12eb1ff71eadc25871c10c42dc" datatype="html">
+ <source>Edit the site name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Modifiez le nom du site, puis cliquez sur <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Mettre à jour<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">13,14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66db799d67958d4b0765181d072df62e2d1c16f5" datatype="html">
+ <source>Issues</source>
+ <target>Problèmes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef06d69259e587e28d52372455f44c7153cda7e7" datatype="html">
+ <source>Syncing</source>
+ <target>Synchronisation en cours</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0b0901877d837d3fda16ba161eb74368d1c75b7a" datatype="html">
+ <source>Ready</source>
+ <target>Prêt</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5833626790712999947" datatype="html">
+ <source>Issue</source>
+ <target>Problème</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3419681791450150574" datatype="html">
+ <source>Progress</source>
+ <target>Avancement</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4902817035128594900" datatype="html">
+ <source>Description</source>
+ <target>Description</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40b7acea5b43f45e0bbd1efeba5200af4687981d" datatype="html">
+ <source>Site Name:</source>
+ <target>Nom du site :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e24f9e2d42104ffc01599db4d566d1cc518f9e6" datatype="html">
+ <source>Daemons</source>
+ <target>Daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6450386891540681425" datatype="html">
+ <source>Edit Site Name</source>
+ <target>Modifier le nom du site</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4645993115976933405" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>Créer un jeton Bootstrap</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4130053543590533787" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>Importer un jeton Bootstrap</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4057c56d63a7e9b140b1d01871a9229a5f30eb27" datatype="html">
+ <source>Edit pool mirror mode</source>
+ <target>Modifier le mode de mise en miroir de la réserve</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e1f367f5feaab38f6637dd1f967c848b447dea2d" datatype="html">
+ <source>To edit the mirror mode for pool  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, select a new mode from the list and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Pour modifier le mode de mise en miroir de la réserve  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, sélectionnez un nouveau mode dans la liste, puis cliquez sur  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Mettre à jour<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37e10df2d9c0c25ef04ac112c9c9a7723e8efae0" datatype="html">
+ <source>Mode</source>
+ <target>Mode</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">426</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32ca348ef926b0a6a7a780b8b64c3a8239895cec" datatype="html">
+ <source>Peer clusters must be removed prior to disabling mirror.</source>
+ <target>Les grappes d'homologues doivent être supprimées avant de désactiver la mise en miroir.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5769292297914455214" datatype="html">
+ <source>Disabled</source>
+ <target>Désactivé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ddcb416c1c0aa1f54acf5beef1de81813e76fa6" datatype="html">
+ <source>{VAR_SELECT, select, edit {Edit} other {Add}}</source>
+ <target>{VAR_SELECT, select, edit {Modifier} other {Ajouter}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3aa7c3a4f7b0cf7c2e60fc71ea1e3b4c3efa3558" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> pool mirror peer</source>
+ <target>Homologue de mise en miroir de la réserve <x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="59ca65ece457429d90104ede4674965f62edbabe" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> the pool mirror peer attributes for pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Submit<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> les attributs de mise en miroir de la réserve <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, puis cliquez sur <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Soumettre<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d3cc964811f852a168f4a2d5daa59068abc5cf53" datatype="html">
+ <source>Cluster Name</source>
+ <target>Nom de grappe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b631721fc56cb7fb1cbd07b802a487c5753f6a2d" datatype="html">
+ <source>The cluster name is not valid.</source>
+ <target>Le nom de grappe n'est pas valide.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca6deafa31bf421f85094807982aee4bcb20a3ae" datatype="html">
+ <source>CephX ID</source>
+ <target>ID CephX</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7539188a568c3d553cbde1bacaf32310c4264e24" datatype="html">
+ <source>CephX ID...</source>
+ <target>ID CephX...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1c45b594b0fba22fc64e80c793a7ffe005fdb0e" datatype="html">
+ <source>The CephX ID is not valid.</source>
+ <target>L'ID CephX n'est pas valide.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20861576fcfce773c918c782cd4f5adf32382921" datatype="html">
+ <source>Monitor Addresses</source>
+ <target>Adresses du moniteur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fa28eeed2b4bd4ccbe6e9349a1c2b3cb1c5de70a" datatype="html">
+ <source>Comma-delimited addresses...</source>
+ <target>Adresses séparées par une virgule...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dc016c82fd85848d5c1b2fd0e8469ee2027d9c16" datatype="html">
+ <source>The monitory address is not valid.</source>
+ <target>L'adresse du moniteur n'est pas valide.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0ac55b83dc6739e62bc655cfe375b67c93e7f4a" datatype="html">
+ <source>CephX Key</source>
+ <target>Clé CephX</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f53434bcb95bd86f1df9c8e22966f757614fc4ad" datatype="html">
+ <source>Base64-encoded key...</source>
+ <target>Clé Base64...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4cd83164cd4f66b4abc2863f9ce6f599d789e4ca" datatype="html">
+ <source>CephX key must be base64 encoded.</source>
+ <target>La clé CephX doit être codée en base64.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6407712033679505505" datatype="html">
+ <source>Edit Mode</source>
+ <target>Mode d'édition</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054237897979907103" datatype="html">
+ <source>Add Peer</source>
+ <target>Ajouter un homologue</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="899134641637789371" datatype="html">
+ <source>Edit Peer</source>
+ <target>Modifier un homologue</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7393680121674824053" datatype="html">
+ <source>Delete Peer</source>
+ <target>Supprimer un homologue</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1713271461473302108" datatype="html">
+ <source>Mode</source>
+ <target>Mode</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1061297288634362831" datatype="html">
+ <source>Leader</source>
+ <target>Leader</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8517494870558773093" datatype="html">
+ <source># Local</source>
+ <target>nb en local</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4953753699491987394" datatype="html">
+ <source># Remote</source>
+ <target>nb à distance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1715982232168082172" datatype="html">
+ <source>mirror peer</source>
+ <target>mettre en miroir l'homologue</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff92fbdec9fdd5054493eeda0d7ee8b450f83e72" datatype="html">
+ <source>RBD Configuration</source>
+ <target>Configuration RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b62d9efc8eb3b589904f6cb96a0406bbda55673a" datatype="html">
+ <source>Remove the local configuration value. The parent configuration value will be inherited and used instead.</source>
+ <target>Supprimez la valeur de configuration locale. La valeur de configuration parent sera héritée et utilisée à la place.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80d769fd863fe44fab689636a078466bfdbd1f20" datatype="html">
+ <source>The minimum value is 0</source>
+ <target>La valeur minimale est de 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5decb3917d46a9ac6e5813699801becb7c3c1455" datatype="html">
+ <source>Global</source>
+ <target>Global</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f9ba9bb9faa8284bcadb1cdbc6aaf969e9c4bb" datatype="html">
+ <source>Image</source>
+ <target>Image</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70fcca5a99575cffef3ff8cbd5e69f06ffd0f1c" datatype="html">
+ <source>Pool</source>
+ <target>Réserve</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176659033176029418" datatype="html">
+ <source>Key</source>
+ <target>Clé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9155608366859514313" datatype="html">
+ <source>Source</source>
+ <target>Source</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6555318547274416232" datatype="html">
+ <source>Value</source>
+ <target>Valeur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f6e8f6094b180eaf1f11bc0ffe383f1cdcd059e" datatype="html">
+ <source>Only available for RBD images with <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> enabled</source>
+ <target>Uniquement disponible pour les images RBD avec la fonction <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> activée</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f8b2bb476981727ab34ed40fde1218361f92c45" datatype="html">
+ <source>Details</source>
+ <target>Détails</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03cc5b14b0a20d075e9009ff021f4f1660ba348a" datatype="html">
+ <source>Data Pool</source>
+ <target>Réserve de données</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b051734b0ee9021991c91b3ed4e81c244322462" datatype="html">
+ <source>Created</source>
+ <target>Créé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7faaaa08f56427999f3be41df1093ce4089bbd75" datatype="html">
+ <source>Size</source>
+ <target>Taille</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="afdb601c16162f2c798b16a2920955f1cc6a20aa" datatype="html">
+ <source>Objects</source>
+ <target>Objets</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ceac8e132384322ec778ba760875a6c6897d3e42" datatype="html">
+ <source>Object size</source>
+ <target>Taille de l'objet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cdb1fea93d77c07950c0c76c6e0ad79ebbef084" datatype="html">
+ <source>Features</source>
+ <target>Fonctionnalités</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65771c9a73b9aa609d592fc96a64801a8f40bd" datatype="html">
+ <source>Provisioned</source>
+ <target>Provisionné</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84a36cb75660b736773fe36ffa3d54f0f0fe363e" datatype="html">
+ <source>N/A</source>
+ <target>N/A</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c009342a4e8381f64341d0bb61c2e4685f5a4b" datatype="html">
+ <source>Total provisioned</source>
+ <target>Provisionnement total</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f6bf8a43ae415f527ac961ea62471b983aaa97b" datatype="html">
+ <source>Striping unit</source>
+ <target>Unité de segmentation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db710e8a8f011923f2d15d713fbae49c38b02b26" datatype="html">
+ <source>Striping count</source>
+ <target>Nombre de segmentations</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a4c2a9e76634ff14a60d52a718296f722d47c67" datatype="html">
+ <source>Parent</source>
+ <target>Parent</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a209e68d78ffc2cc9c53d2e76158624efab71ad" datatype="html">
+ <source>Block name prefix</source>
+ <target>Préfixe du nom de bloc</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5704ec2049d007c5f5fb495a5d8b607e68d58081" datatype="html">
+ <source>Order</source>
+ <target>Tri</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="984cb6ad70f150a401b4daf841bd3cd957412699" datatype="html">
+ <source>Format Version</source>
+ <target>Version du format</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f21b1d17b6c5042bb5805516eee37fde33739dd8" datatype="html">
+ <source>Snapshots</source>
+ <target>Instantanés</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4a41f824a35ba01d5bd7be61aa06b3e8145209d0" datatype="html">
+ <source>Configuration</source>
+ <target>Configuration</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3cc9c2ae277393b3946b38c088dabff671b1ee1b" datatype="html">
+ <source>Performance</source>
+ <target>Performance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935bb9cb0e4340fc74d33caa3b70d9d143fcad87" datatype="html">
+ <source>Information can not be displayed for RBD in status 'Removing'.</source>
+ <target>Les informations ne peuvent pas être affichées pour les RBD ayant le statut 'En cours de suppression'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58e58f1a8786da9031a05e6770c5dafce82badf5" datatype="html">
+ <source>This setting overrides the global value</source>
+ <target>Ce paramètre remplace la valeur globale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36b46714164964c6258b08ed0a25f57d8a950f92" datatype="html">
+ <source>This is the global value. No value for this option has been set for this image.</source>
+ <target>Il s'agit de la valeur globale. Aucune valeur de cette option n'a été définie pour cette image.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6547c9c4d5f62942ac4b1fe459cf9a03d4dbf5a0" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> from</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> à partir de</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0e9ecf29a4fa5b057bd8052e0d801b3fde6a30bf" datatype="html">
+ <source>'/' and '@' are not allowed.</source>
+ <target>Les caractères '/' et '@' ne sont pas autorisés.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="94516fa213706c67ce5a5b5765681d7fb032033a" datatype="html">
+ <source>Loading...</source>
+ <target>Chargement...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">209</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">452</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b99417c4dd46286ffd37c8d2e987c8b512ec7052" datatype="html">
+ <source>-- No rbd pools available --</source>
+ <target>-- Aucune réserve RBD disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef83ec9c304a89d45650e580dcdc2978c37b3a83" datatype="html">
+ <source>-- Select a pool --</source>
+ <target>-- Sélectionnez une réserve --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d649904466254d13df1fbf2d255f0bbc6553d213" datatype="html">
+ <source>-- No namespaces available --</source>
+ <target>-- Aucun espace de noms disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e22d7bb4d2d561e0832ee0b9a3da2468a080c4f0" datatype="html">
+ <source>-- Select a namespace --</source>
+ <target>-- Sélectionnez un espace de noms --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49449943d8cbf59d8c401c8bd2e76f92e207cc5f" datatype="html">
+ <source>Use a dedicated data pool</source>
+ <target>Utiliser une réserve de données dédiée</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa5b3c5ea5af14d09b2eb098039af9f1f77be010" datatype="html">
+ <source>You need more than one pool with the rbd application label use to use a dedicated data pool.</source>
+ <target>Vous devez avoir plusieurs réserves utilisant le libellé de l'application rbd pour utiliser une réserve de données dédiée.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="870aee0dd31a9643bf62007beb8f1ae1deb34d42" datatype="html">
+ <source>Data pool</source>
+ <target>Réserve de données</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3792ca829d9b9f687e1f5d7733d30e9bb0bfec47" datatype="html">
+ <source>Dedicated pool that stores the object-data of the RBD.</source>
+ <target>Réserve dédiée qui stocke les données objet du RBD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151c80ea931037cd92e854442927f8a0f6ae7795" datatype="html">
+ <source>-- No data pools available --</source>
+ <target>-- Aucune réserve de données disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0016bd458baa88284a658ce9eeda42d8ad88d2c" datatype="html">
+ <source>e.g., 10GiB</source>
+ <target>par exemple, 10 Gio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">206</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a88bbee20570aaf9615332fb27020627044874d" datatype="html">
+ <source>You have to increase the size.</source>
+ <target>Vous devez augmenter la taille.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cfe07dac5b4ee1c464eb24225ddeb4f1d24076a" datatype="html">
+ <source>Advanced...</source>
+ <target>Avancé...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bc2e854e111ecf2bd7db170da5e3c2ed08181d88" datatype="html">
+ <source>Advanced</source>
+ <target>Avancé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3562a3778695a5f9c0445660e35301f0a39aaf73" datatype="html">
+ <source>Striping</source>
+ <target>Segmentation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef3c3f3b5f562a5cdbe0ee2874287db1534b5958" datatype="html">
+ <source>Stripe unit</source>
+ <target>Unité de segmentation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84471be1049006edecbcaef1a32ae0893c229c50" datatype="html">
+ <source>-- Select stripe unit --</source>
+ <target>-- Sélectionnez une unité de segmentation --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">289</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d32c5c54c8581c774a7f467fbd4e329b15a74fa" datatype="html">
+ <source>This field is required because stripe count is defined!</source>
+ <target>Ce champ est obligatoire, car le nombre de segments est défini.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bbf9040be7c5491d4a03f2185708f43a6582a3b" datatype="html">
+ <source>Stripe unit is greater than object size.</source>
+ <target>L'unité de segmentation est supérieure à la taille de l'objet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a682f49f9b761591661276d7c6f550e641a130a4" datatype="html">
+ <source>Stripe count</source>
+ <target>Nombre de segments</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="baa74031990c5370008ba622d0a250f0929097f4" datatype="html">
+ <source>This field is required because stripe unit is defined!</source>
+ <target>Ce champ est obligatoire, car l'unité de segmentation est définie.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cd2ada6d5ecbd5cbf89eae0a1f5326efedac0dbc" datatype="html">
+ <source>Stripe count must be greater than 0.</source>
+ <target>Le nombre de segments doit être supérieur à 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4341718109173132593" datatype="html">
+ <source>RBD</source>
+ <target>RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1359455778569887786" datatype="html">
+ <source>Deep flatten</source>
+ <target>Aplatissement en profondeur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58519213655664125" datatype="html">
+ <source>Layering</source>
+ <target>Superposition</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844531889615887801" datatype="html">
+ <source>Exclusive lock</source>
+ <target>Verrou exclusif</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4585281635594103106" datatype="html">
+ <source>Object map (requires exclusive-lock)</source>
+ <target>Assignation d'objet (nécessite exclusive-lock)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240933649452133654" datatype="html">
+ <source>Journaling (requires exclusive-lock)</source>
+ <target>Journalisation (nécessite exclusive-lock)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3713046526850391848" datatype="html">
+ <source>Fast diff (interlocked with object-map)</source>
+ <target>Fast diff (interverrouillage avec object-map)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19f1e825536efbf7492723a7c2d01ad23a4e994b" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1774b9915b0e302d02cad0b9321ad5f1a83247a8" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c9f1026c1235f4d76ace47449e806efd181ab332" datatype="html">
+ <source>Deleting this image will also delete all its snapshots.</source>
+ <target>La suppression de cette image entraînera également la suppression de ses instantanés.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55f864597e84d9bf88769e1fbfda1d64452430c9" datatype="html">
+ <source>The following snapshots are currently protected and will be removed:</source>
+ <target>Les instantanés suivants sont actuellement protégés et seront supprimés :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2e362ec498c4c9112dc47a3cb7d7250ca8e71790" datatype="html">
+ <source>RBD in status 'Removing'</source>
+ <target>RBD ayant le statut 'En cours de suppression'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3294686077659093992" datatype="html">
+ <source>Namespace</source>
+ <target>Espace de noms</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45739481977493163" datatype="html">
+ <source>Size</source>
+ <target>Taille</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7531602241051125940" datatype="html">
+ <source>Objects</source>
+ <target>Objets</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1194977199378511591" datatype="html">
+ <source>Object size</source>
+ <target>Taille de l'objet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">226</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="178418048502923560" datatype="html">
+ <source>Provisioned</source>
+ <target>Provisionné</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7638291694671392137" datatype="html">
+ <source>Total provisioned</source>
+ <target>Provisionnement total</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8621797738551294959" datatype="html">
+ <source>Parent</source>
+ <target>Parent</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616639680594151867" datatype="html">
+ <source>This RBD has cloned snapshots. Please delete related RBDs before deleting this RBD.</source>
+ <target>Ce RBD comporte des instantanés clonés. Supprimez les RBD associés avant de supprimer ce RBD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2900827028308925059" datatype="html">
+ <source>This RBD image has an invalid name and can't be managed by ceph.</source>
+ <target>Le nom de cette image RBD n'est pas valide. Cette image ne peut pas être gérée par ceph.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1796389652493657142" datatype="html">
+ <source>Action not possible for an RBD in status 'Removing'</source>
+ <target>Action impossible sur un RBD ayant le statut 'En cours de suppression'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">476</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c07d24bb422aa8e5e568df1c5709083f0a9c8f1" datatype="html">
+ <source>Create Namespace</source>
+ <target>Créer un espace de noms</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cca6c0485f96d3a9610d0339cb1275a5f2c3f46" datatype="html">
+ <source>Namespace already exists.</source>
+ <target>L'espace de noms existe déjà.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4641528557519966449" datatype="html">
+ <source>Created namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <target>Espace de noms créé '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6809428596104996786" datatype="html">
+ <source>Total images</source>
+ <target>Nbre total d'images</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1346311774128536550" datatype="html">
+ <source>Deleted namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <target>Espace de noms supprimé '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7605466414392298530" datatype="html">
+ <source>Namespace contains images</source>
+ <target>L'espace de noms contient des images</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576483965711201552" datatype="html">
+ <source>RBD Snapshot</source>
+ <target>Instantané RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3473055924346204357" datatype="html">
+ <source>Parent image must support Layering</source>
+ <target>L'image parent doit prendre en charge la superposition</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1152535233999495900" datatype="html">
+ <source>Snapshot must be protected in order to clone.</source>
+ <target>L'instantané doit être protégé pour pouvoir être cloné.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c5331983af566d4ac6a1024d15a3511786a4aa6" datatype="html">
+ <source>You are about to rollback</source>
+ <target>Vous êtes sur le point de revenir à l'état initial</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6240400332778072187" datatype="html">
+ <source>PROTECTED</source>
+ <target>PROTÉGÉ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9101667614062185213" datatype="html">
+ <source>UNPROTECTED</source>
+ <target>NON PROTÉGÉ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4207916966377787111" datatype="html">
+ <source>Created</source>
+ <target>Créé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587768621777516124" datatype="html">
+ <source>RBD snapshot rollback</source>
+ <target>Retour à l'état initial de l'instantané RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">305</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2711198699676132148" datatype="html">
+ <source>Rollback</source>
+ <target>Revenir à l'état initial</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3330476395115957823" datatype="html">
+ <source>RBD snapshot</source>
+ <target>Intantané RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">322</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3a7e364a88ea4673199dfa98bc73e6dbe09dfac" datatype="html">
+ <source>Namespaces</source>
+ <target>Espaces de noms</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aba82bfd8e177d35b76cad7cd43941f8e5e5acac" datatype="html">
+ <source>Trash</source>
+ <target>Corbeille</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5e7f4b1ca49e8d217bd0e12c6f7d6b6a2ade2c18" datatype="html">
+ <source>Overall Performance</source>
+ <target>Performance globale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c0408946a6d67185947f455f15cc201d0d78e6" datatype="html">
+ <source>Purge Trash</source>
+ <target>Vider la corbeille</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c96a761dc55a21882c132c929583a424c9b8cf4" datatype="html">
+ <source>Expired at</source>
+ <target>Expiration le </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="661041e3fcff4d3e75c561e038ca2504cf2cc643" datatype="html">
+ <source>Protected until</source>
+ <target>Protection jusqu'au</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee3b2322a1d3277f7e3fdb8a5141ac42bcf350b" datatype="html">
+ <source>This image is protected until <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</source>
+ <target>Cette image est protégée jusqu'au <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5611592591303869712" datatype="html">
+ <source>Status</source>
+ <target>Statut</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">213</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">285</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2155633476201267204" datatype="html">
+ <source>Deleted At</source>
+ <target>Supprimé le</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0b5d789d42c0e69348e5fe0037fcbf5b5fbbdcc" datatype="html">
+ <source>Move an image to trash</source>
+ <target>Déplacer une image vers la corbeille</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ad22c1d4aab3b8946603cea62de266d5129ca10" datatype="html">
+ <source>This image contains snapshot(s), which will prevent it from being removed after moved to trash.</source>
+ <target>Cette image contient un ou plusieurs instantanés, ce qui l'empêchera d'être supprimée après avoir été déplacée vers la corbeille.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">15,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d4a5f5698bc8118b2e120b9bb72eff339094dd0" datatype="html">
+ <source>To move <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> to trash, click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Move<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Optionally, you can pick an expiration date.</source>
+ <target>Pour déplacer <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> vers la corbeille, cliquez sur <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Déplacer<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Vous pouvez éventuellement sélectionner une date d'expiration.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">19,20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f27d390844aad53b4240360e928156c5f0d326" datatype="html">
+ <source>Protection expires at</source>
+ <target>La protection expire le </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da166e9a0d27322f6ba8916d71ecc0f9905bb4b1" datatype="html">
+ <source>NOT PROTECTED</source>
+ <target>NON PROTÉGÉ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1506e5f2ca22cad14502ec7a20fb6113ace145d" datatype="html">
+ <source>Wrong date format. Please use &quot;YYYY-MM-DD HH:mm:ss&quot;.</source>
+ <target>Format de date incorrect. Veuillez utiliser &quot;AAAA-MM-JJ HH:mm:ss&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa7ea0bb7495281e0b3258467ac7d90a1e44a1a1" datatype="html">
+ <source>Protection has already expired. Please pick a future date or leave it empty.</source>
+ <target>La protection a déjà expiré. Veuillez sélectionner une date ultérieure ou laisser le champ vide.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d8613436532acac2b97d17de28b50f93e6bd0222" datatype="html">
+ <source>To purge, select  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>All<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>  or one pool and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Purge<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </source>
+ <target>Pour purger, sélectionnez  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Tout<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>  ou une réserve, puis cliquez sur  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Purger<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55a4f598a4894b7fd5cb88f0ffd3c37ad009dd70" datatype="html">
+ <source>Pool:</source>
+ <target>Réserve :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d43dd2b9f7797e4cf3a604695bb33e4479108516" datatype="html">
+ <source>Pool name...</source>
+ <target>Nom de la réserve...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dfc3c34e182ea73c5d784ff7c8135f087992dac1" datatype="html">
+ <source>All</source>
+ <target>Tout</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0e7c7ed1d51a0c205c815048bc9f79e24ee6db2" datatype="html">
+ <source>Restore Image</source>
+ <target>Restaurer l'image</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3bc4aaf0dce75dc5e01ee5c825a652dc8aea8f0" datatype="html">
+ <source>To restore  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>,  type the image's new name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Restore<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Pour restaurer  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>,  entrez le nouveau nom de l'image, puis cliquez sur  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Restaurer<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41307dd56fea669eed72e12a6c23af275f6bfd82" datatype="html">
+ <source>New Name</source>
+ <target>Nouveau nom</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3625859417927520024" datatype="html">
+ <source>id</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6537904131139019667" datatype="html">
+ <source>type</source>
+ <target>type</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8901220148451863928" datatype="html">
+ <source>state</source>
+ <target>état</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7925190601961269841" datatype="html">
+ <source>version</source>
+ <target>version</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6641024648411549335" datatype="html">
+ <source>Host</source>
+ <target>Hôte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773272191572353800" datatype="html">
+ <source>root</source>
+ <target>racine</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6364513948635353490" datatype="html">
+ <source>Evicted client '<x id="PH" equiv-text="clientId"/>'</source>
+ <target>Client '<x id="PH" equiv-text="clientId"/>' évincé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c1e17956453ad772dbe82d6946f62748c692f3e" datatype="html">
+ <source>Ranks</source>
+ <target>Rangs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b24e0b0b1629d2e8a51b9da7c75d6e6379f4bc4" datatype="html">
+ <source>Standbys</source>
+ <target>Veilles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="50df62325726db950523a5be1c78b8905fcc25d4" datatype="html">
+ <source>MDS performance counters</source>
+ <target>Compteurs de performance MDS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4578796959376778578" datatype="html">
+ <source>Standby daemons</source>
+ <target>Daemons en veille</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="665219418211496660" datatype="html">
+ <source>Rank</source>
+ <target>Rang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5445409664838149993" datatype="html">
+ <source>Daemon</source>
+ <target>Daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5306473977542913614" datatype="html">
+ <source>Activity</source>
+ <target>Activité</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3998441303515229547" datatype="html">
+ <source>Dentries</source>
+ <target>Dentries</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7877631502958415163" datatype="html">
+ <source>Inodes</source>
+ <target>Inodes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6129397096478256985" datatype="html">
+ <source>Dirs</source>
+ <target>Répertoires</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3011876564696453148" datatype="html">
+ <source>Caps</source>
+ <target>Capacités</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8650499415827640724" datatype="html">
+ <source>Type</source>
+ <target>Type</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="142654590491855672" datatype="html">
+ <source>Usage</source>
+ <target>Utilisation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">326</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb8293aa8161433778762ae025ffd5e7c85795e" datatype="html">
+ <source>Quotas</source>
+ <target>Quotas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">540</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66785722678644243" datatype="html">
+ <source>Origin</source>
+ <target>Origine</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8911059720204770105" datatype="html">
+ <source>Path</source>
+ <target>Chemin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6111756909052789805" datatype="html">
+ <source>Cannot create snapshots for files/folders in the subvolume <x id="PH" equiv-text="folders[2]"/></source>
+ <target>Impossible de créer des instantanés pour les fichiers/dossiers du sous-volume <x id="PH" equiv-text="folders[2]"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7503263437025060215" datatype="html">
+ <source>Max size</source>
+ <target>Taille max.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6763343019307619111" datatype="html">
+ <source>Max files</source>
+ <target>Nbre max. de fichiers</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327403486214540377" datatype="html">
+ <source>The inherited <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> is the maximum value to be used.</source>
+ <target>La valeur <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> héritée est la valeur maximale à utiliser.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">434,437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3768927257183755959" datatype="html">
+ <source>Save</source>
+ <target>Sauvegarder</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">440</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6328794256834621774" datatype="html">
+ <source><x id="PH" equiv-text="action"/> CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> quota for '<x id="PH_2" equiv-text="path"/>'</source>
+ <target>Quota <x id="PH" equiv-text="action"/> CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> pour '<x id="PH_2" equiv-text="path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">446</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9130352375983418123" datatype="html">
+ <source>size</source>
+ <target>taille</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6889473896134264260" datatype="html">
+ <source>files</source>
+ <target>fichiers</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2244434638607433133" datatype="html">
+ <source><x id="PH" equiv-text="this.getQuotaName()"/> quota <x id="PH_1" equiv-text="value"/> from '<x id="PH_2" equiv-text="path"/>'</source>
+ <target><x id="PH" equiv-text="this.getQuotaName()"/> quota <x id="PH_1" equiv-text="value"/> à partir de '<x id="PH_2" equiv-text="path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">460</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6960117167304061503" datatype="html">
+ <source>Value has to be at least 0 or more</source>
+ <target>La valeur doit être au minimum égale à 0 ou supérieure</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">484</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6740501370117796629" datatype="html">
+ <source>Value has to be at most <x id="PH" equiv-text="maxValue"/> or less</source>
+ <target>La valeur doit être au maximum égale à <x id="PH" equiv-text="maxValue"/> ou inférieure</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7239750919884229270" datatype="html">
+ <source>Updated</source>
+ <target>Mis à jour</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">499</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8885980874806414253" datatype="html">
+ <source>in order to inherit <x id="PH" equiv-text="quotaValue"/></source>
+ <target>pour hériter <x id="PH" equiv-text="quotaValue"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4182949309891923991" datatype="html">
+ <source>which isn't used because of the inheritance of <x id="PH" equiv-text="quotaValue"/></source>
+ <target>inutilisé(e) en raison de l'héritage de la fonction <x id="PH" equiv-text="quotaValue"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7421970649864638435" datatype="html">
+ <source>in order to have no quota on the directory</source>
+ <target>pour ne pas avoir de quota sur le répertoire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6730229976797004508" datatype="html">
+ <source><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</source>
+ <target><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">530,533</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="827679535246546876" datatype="html">
+ <source>Create Snapshot</source>
+ <target>Créer un instantané</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">542</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">552</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4747656362969857823" datatype="html">
+ <source>Please enter the name of the snapshot.</source>
+ <target>Entrez le nom de l'instantané.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3667696812078358068" datatype="html">
+ <source>Created snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <target>Instantané '<x id="PH" equiv-text="name"/>' créé pour '<x id="PH_1" equiv-text="path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="753342836137587734" datatype="html">
+ <source>CephFs Snapshot</source>
+ <target>Instantané CephFs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">670</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2774104291801979963" datatype="html">
+ <source>Deleted snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <target>Instantané '<x id="PH" equiv-text="name"/>' supprimé pour '<x id="PH_1" equiv-text="path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">683</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4816216590591222133" datatype="html">
+ <source>Enabled</source>
+ <target>Activé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ffe39df9d88c972792bd8688b215392deb8313d" datatype="html">
+ <source>Clients</source>
+ <target>Clients</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e213942c6354b9cbe7a650f0f1499bfc1000fb6" datatype="html">
+ <source>Directories</source>
+ <target>Répertoires</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fbbaf5cb02ed419e79a27072478f716a4666a99d" datatype="html">
+ <source>Performance Details</source>
+ <target>Détails des performances</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0" datatype="html">
+ <source>Description</source>
+ <target>Description</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ad112ce9bcd55dfd137792a86afe1b5a5b13cf8" datatype="html">
+ <source>Long description</source>
+ <target>Description longue</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="26fb5f81b3581f06b9210defb0e71dc69a67e819" datatype="html">
+ <source>Current values</source>
+ <target>Valeurs actuelles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7cee38a2259526c519f878e71b964f41db4348" datatype="html">
+ <source>Default</source>
+ <target>Valeur par défaut</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33e1c1d9fc05ca3f62fcc8a1170fc31ebae4229c" datatype="html">
+ <source>Daemon default</source>
+ <target>Valeur par défaut du daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f61c6867295f3b53d23557021f2f4e0aa1d0b8fc" datatype="html">
+ <source>Type</source>
+ <target>Type</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9abcd7c82643d60c22733470463f74e4a54bc069" datatype="html">
+ <source>Min</source>
+ <target>Minimum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3ced4d162a0a55ee233a187ce7208ba5e922418" datatype="html">
+ <source>Max</source>
+ <target>Maximum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="920617c6a1a4805e53bcb5af6a9c76f8387e89c6" datatype="html">
+ <source>Flags</source>
+ <target>Drapeaux</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5" datatype="html">
+ <source>Services</source>
+ <target>Services</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6834fa6b43d1ecbdf147c48dd9c4d72f1484571d" datatype="html">
+ <source>Source</source>
+ <target>Source</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a446fb0eb11fbffcac805ece5a2d306d24e733d8" datatype="html">
+ <source>Level</source>
+ <target>Niveau</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39f2fb094e9b2eda13163fa3f3a31594cf9c1307" datatype="html">
+ <source>Can be updated at runtime (editable)</source>
+ <target>Mise à jour possible lors de l'exécution (modifiable)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
+ <source>Tags</source>
+ <target>Balises</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ab0089ef47af61ca1d137bc908b96c290dfd9287" datatype="html">
+ <source>Enum values</source>
+ <target>Valeurs d'énumération</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="819476f1264f1659f38e86f6abb542141b184832" datatype="html">
+ <source>See also</source>
+ <target>Voir aussi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="543199344025799954" datatype="html">
+ <source>The value can be updated at runtime.</source>
+ <target>La valeur peut être mise à jour au moment de l'exécution.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1718354829128482129" datatype="html">
+ <source>Daemons/clients do not pull this value from the
+ monitor config database. We disallow setting this option via 'ceph config
+ set ...'. This option should be configured via ceph.conf or via the
+ command line.</source>
+ <target>Les daemons/clients ne tirent pas cette valeur de
+  la base de données de configuration de Monitor. Nous n'autorisons pas le réglage de cette option via 'ceph config
+  set ...'. Cette option doit être configurée via ceph.conf ou via
+  la ligne de commande.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">15,18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2345189734548717257" datatype="html">
+ <source>Option takes effect only during daemon startup.</source>
+ <target>L'option ne prend effet qu'au démarrage du daemon.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5523310713159993513" datatype="html">
+ <source>Option only affects cluster creation.</source>
+ <target>L'option n'affecte que la création des grappes.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1064479086902933123" datatype="html">
+ <source>Option only affects daemon creation.</source>
+ <target>L'option n'affecte que la création des daemons.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="809b0c848932a41318f77a2aace904ef429c13f4" datatype="html">
+ <source>Values</source>
+ <target>Valeurs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5894f7158499fdb89527af50c9f1cf7d4c95cad6" datatype="html">
+ <source>-- Default --</source>
+ <target>-- Valeur par défaut --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="514f6e12d035a6d9b00de6b3e55c18b73488da07" datatype="html">
+ <source>true</source>
+ <target>vrai</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="774f5e6a183dea08393789b6f72e86afad729419" datatype="html">
+ <source>false</source>
+ <target>faux</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="82029b6db704c56a2aa3e82ac555b8655356b077" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>.</source>
+ <target>La valeur saisie est trop élevée ! Elle ne doit pas être supérieure à <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ed8b3967a7326b81b191c9f490006e6a6777a9a" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>.</source>
+ <target>La valeur saisie est trop basse ! Elle ne doit pas être inférieure à <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2337058106409853613" datatype="html">
+ <source>Updated config option <x id="PH" equiv-text="request.name"/></source>
+ <target>Option de configuration <x id="PH" equiv-text="request.name"/> mise à jour</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3733215288982610673" datatype="html">
+ <source>Level</source>
+ <target>Niveau</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2218082343053095278" datatype="html">
+ <source>Service</source>
+ <target>Service</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3553216189604488439" datatype="html">
+ <source>Modified</source>
+ <target>Modifié</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844248428439297756" datatype="html">
+ <source>Current value</source>
+ <target>Valeur actuelle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208877297843037352" datatype="html">
+ <source>Editable</source>
+ <target>Modifiable</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b266042bac4c3a2eff4834e40fb9dc4767a709" datatype="html">
+ <source>Cluster Resources</source>
+ <target>Ressources de la grappe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="099b441d49333b3c6d30b36dc0a4763e64c78920" datatype="html">
+ <source>Hosts</source>
+ <target>Serveurs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57e6e608ece53a26f6d509c90ed4f83e467741af" datatype="html">
+ <source>Storage Capacity</source>
+ <target>Capacité de stockage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19ece2cb2b9097c0f75af8e62b4b3b25d399a006" datatype="html">
+ <source>Number of devices</source>
+ <target>Nombre de périphériques</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b161e3d25fd1b42a781f4e923a58a94925988ddf" datatype="html">
+ <source>Raw capacity</source>
+ <target>Capacité brute</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb6f3e2a26f3a6f2bc33f91adcd60502dbe5adac" datatype="html">
+ <source>CPUs</source>
+ <target>Processeurs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58d4a9814864741040bc5905b6a368836e683f76" datatype="html">
+ <source>Memory</source>
+ <target>Mémoire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dbb81e566a861d4aa0a094366e4083e50863ee92" datatype="html">
+ <source>Host Details</source>
+ <target>Détails de l'hôte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="453dc2810080a744223faac6da2b3ee9ed63a583" datatype="html">
+ <source>Welcome to <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></source>
+ <target>Bienvenue dans <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1eec874e1928ca53baa9914781ce203b5f72b0c" datatype="html">
+ <source>Please expand your cluster first</source>
+ <target>Veuillez d'abord développer votre grappe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2195fd96b0a00f560449b50bd032e6d9b357730" datatype="html">
+ <source>Expand Cluster</source>
+ <target>Développer la grappe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb075d0450deb6f381616f7da4b9244ced843053" datatype="html">
+ <source>Skip</source>
+ <target>Passer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55b6ce65571b8893440a4fc92776570f8fe7cc97" datatype="html">
+ <source>Add Hosts</source>
+ <target>Ajouter des hôtes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="162f763675c24b557a60eba0758558222369e0c7" datatype="html">
+ <source>Create OSDs</source>
+ <target>Créer des OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fef7a7b8db05c351c5287db48488abca530bdb54" datatype="html">
+ <source>Create Services</source>
+ <target>Créer des services</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="176873b4533ddeabf95992cbd7b91b9d01c6d557" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ed90ec4409b9f6b552982d96f89db27259e763c" datatype="html">
+ <source>You are about to skip the cluster expansion process. You’ll need to <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>navigate through the menu to add hosts and services.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>Vous êtes sur le point de passer le processus d'expansion de la grappe. Vous devrez <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>naviguer dans le menu pour ajouter des hôtes et des services.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">90,91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d1dcf2a9146caac0581329acf94806ec69a89a5" datatype="html">
+ <source>Are you sure you want to continue?</source>
+ <target>Voulez-vous vraiment continuer ?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6759205696902713848" datatype="html">
+ <source>Warning</source>
+ <target>Avertissement</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">357</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6962699013778688473" datatype="html">
+ <source>Continue</source>
+ <target>Continuer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6156560100092571435" datatype="html">
+ <source>Cluster expansion skipped by user</source>
+ <target>Étape d'expansion de la grappe passée par l'utilisateur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520085823873354736" datatype="html">
+ <source>Cluster expansion was successful</source>
+ <target>La grappe a été étendue</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176230351113290618" datatype="html">
+ <source>Expand Cluster</source>
+ <target>Développer la grappe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="738de688b22fba5d0dc7a5e549996838dddad0ee" datatype="html">
+ <source>CRUSH map viewer</source>
+ <target>Visionneuse de carte CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/crushmap/crushmap.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e24569eca61d598c8b01defbbbb1fa8bd5222bc" datatype="html">
+ <source>Devices</source>
+ <target>Périphériques</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17137bac47e1e020d139256ded0006a671966e73" datatype="html">
+ <source>Physical Disks</source>
+ <target>Disques physiques</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="deba10b7279a589d01e919ea11f43c79ca1773e3" datatype="html">
+ <source>Device health</source>
+ <target>Santé du périphérique</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d87fc20ea8e5f0f0500ba5d5061b345be78ec5e" datatype="html">
+ <source>No hostname found.</source>
+ <target>Aucun nom d'hôte trouvé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9a541ec1a4319fffc16ad3b3ab2c2b6d251a829d" datatype="html">
+ <source>Hostname</source>
+ <target>Nom d'hôte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee6875e67b53cac30a02b57cf76e485f7e60caf4" datatype="html">
+ <source>To add multiple hosts at once, you can enter:</source>
+ <target>Pour ajouter plusieurs hôtes simultanément, vous pouvez saisir :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a8370b19ccf673fb28fa9db36a08f9901887cc7" datatype="html">
+ <source>a comma-separated list of hostnames <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-01,example-02,example-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <target>une liste de noms d'hôtes séparés par des virgules <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(par exemple : exemple-01,exemple-02,exemple-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="68f2c05396ec8a5f59e8da42d1f6c7310fa8c37c" datatype="html">
+ <source>a range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <target>une expression de plage <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(par exemple : exemple-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e00b9bba448e79add37740e53dc953fbb89f9c5" datatype="html">
+ <source>a comma separated range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></source>
+ <target>une expression de plage séparée par des virgules <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(par exemple : exemple-[01-05].lab.com,exemple2-[1-4].lab.com,exemple3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b3f5e5291541678f7afa49d28fad5ca848a8061" datatype="html">
+ <source>The chosen hostname is already in use.</source>
+ <target>Le nom d'hôte sélectionné est déjà utilisé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="42365f623c57973d1d13d2038e8a2d4c02fb9b9f" datatype="html">
+ <source>Network address</source>
+ <target>Adresse réseau</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3859bdca1ae89e611e214c205fccf0147b4d0f6b" datatype="html">
+ <source>The value is not a valid IP address.</source>
+ <target>La valeur n'est pas une adresse IP valide.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2af7efecfae8d7fed3b07f718a623eca1ad8163f" datatype="html">
+ <source>Labels</source>
+ <target>Libellés</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9da2afd4fa358b66d4d95fe7e8f4b659a7144e" datatype="html">
+ <source>Maintenance Mode</source>
+ <target>Mode Maintenance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="468785112451259935" datatype="html">
+ <source>There are no labels.</source>
+ <target>Il n'y a aucun libellé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4664081995078497865" datatype="html">
+ <source>Filter or add labels</source>
+ <target>Filtrer ou ajouter des libellés</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4897817053917542646" datatype="html">
+ <source>Add label</source>
+ <target>Ajouter un libellé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">313</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1187321380561233505" datatype="html">
+ <source>host</source>
+ <target>hôte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40661476cb24c89d8b06614998e31d5fbe84eeb6" datatype="html">
+ <source>Hosts List</source>
+ <target>Liste d'hôtes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b7a4e1e5a316f8547af1d6d2311a5cec8c5c1d87" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ msg }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ msg }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6e8e8844e9e7a7b626a4699c08b6c0c81297a7b" datatype="html">
+ <source>Data will be available only if Orchestrator is available.</source>
+ <target>Les données ne seront disponibles que si l'orchestrateur est disponible.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4baf526199fed59071adf555271791283adc408" datatype="html">
+ <source>SSD, NVMEs</source>
+ <target>SSD, NVME</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="22d5531d79f0d7269a0a752e56a848807dd37095" datatype="html">
+ <source>Flash</source>
+ <target>Flash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4025065730478477779" datatype="html">
+ <source>The feature is disabled because the selected host is not managed by Orchestrator.</source>
+ <target>La fonction est désactivée, car l'hôte sélectionné n'est pas géré par l'orchestrateur.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7143579180750436311" datatype="html">
+ <source>Services</source>
+ <target>Services</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="546766753072101168" datatype="html">
+ <source>Labels</source>
+ <target>Libellés</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1141886420788473147" datatype="html">
+ <source>Model</source>
+ <target>Modèle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4027647877328291519" datatype="html">
+ <source>CPUs</source>
+ <target>Processeurs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2445398473573060226" datatype="html">
+ <source>Cores</source>
+ <target>Coeurs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1656823484917332451" datatype="html">
+ <source>Total Memory</source>
+ <target>Mémoire totale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1939212557812454069" datatype="html">
+ <source>Raw Capacity</source>
+ <target>Capacité brute</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5579687933271468638" datatype="html">
+ <source>HDDs</source>
+ <target>Disques durs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1889285841762768492" datatype="html">
+ <source>Flash</source>
+ <target>Flash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1578709829957887527" datatype="html">
+ <source>NICs</source>
+ <target>Cartes d'interface réseau</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4723031838495967601" datatype="html">
+ <source>Edit Host: <x id="PH" equiv-text="host.hostname"/></source>
+ <target>Modifier l'hôte : <x id="PH" equiv-text="host.hostname"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6004907173026319041" datatype="html">
+ <source>Edit Host</source>
+ <target>Modifier l'hôte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5618131051466022401" datatype="html">
+ <source>Updated Host &quot;<x id="PH" equiv-text="host.hostname"/>&quot;</source>
+ <target>Hôte mis à jour &amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1701954433367210342" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; moved to maintenance</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; déplacé(e) vers la maintenance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3108406586869160854" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; cannot be put into maintenance</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; ne peut pas être placé en maintenance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1737753151350322492" datatype="html">
+ <source><x id="PH" equiv-text="error.error['detail']"/></source>
+ <target><x id="PH" equiv-text="error.error['detail']"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4054533801359952167" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; has exited maintenance</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; a quitté la maintenance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5837599005212786659" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; stopped draining</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host['hostname']"/>&amp;quot; a cessé de se vider</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1357236071975782353" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; started draining</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host['hostname']"/>&amp;quot; a commencé à se vider</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5658400717636093668" datatype="html">
+ <source>Identify</source>
+ <target>Identifier</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6966707768479328825" datatype="html">
+ <source>Device path</source>
+ <target>Chemin du périphérique</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3955868613858648955" datatype="html">
+ <source>Available</source>
+ <target>Disponible</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="158816374076721379" datatype="html">
+ <source>Vendor</source>
+ <target>Fournisseur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6024104799101504292" datatype="html">
+ <source>OSDs</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3422162477846071958" datatype="html">
+ <source>Identify device <x id="PH" equiv-text="device"/></source>
+ <target>Identifier le périphérique <x id="PH" equiv-text="device"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4910073658089977244" datatype="html">
+ <source>Please enter the duration how long to blink the LED.</source>
+ <target>Entrez la durée de clignotement de la LED.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5764931367607989415" datatype="html">
+ <source>1 minute</source>
+ <target>1 minute</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809466133764752509" datatype="html">
+ <source>2 minutes</source>
+ <target>2 minutes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">235</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1487672983218679675" datatype="html">
+ <source>5 minutes</source>
+ <target>5 minutes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603584938775296395" datatype="html">
+ <source>10 minutes</source>
+ <target>10 minutes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6648333117195452824" datatype="html">
+ <source>15 minutes</source>
+ <target>15 minutes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6560281329999108838" datatype="html">
+ <source>Execute</source>
+ <target>Exécuter</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6901229416977800100" datatype="html">
+ <source>Identifying '<x id="PH" equiv-text="device"/>' started on host '<x id="PH_1" equiv-text="hostname"/>'</source>
+ <target>L'identification de '<x id="PH" equiv-text="device"/>' a démarré sur l'hôte '<x id="PH_1" equiv-text="hostname"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d556ab48a65722b400e497f61737f553ee0f89e2" datatype="html">
+ <source>Cluster Logs</source>
+ <target>Journaux de grappes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5f966baffd188be0e8adc2d7067b86e55fc9b9de" datatype="html">
+ <source>Audit Logs</source>
+ <target>Journaux d'audit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4193c9eb868aeec119b78a14795241e0aa5e8b60" datatype="html">
+ <source>Priority:</source>
+ <target>Priorité :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d78ca51eab260ce3fd917d39190d64df5229b6e" datatype="html">
+ <source>Keyword:</source>
+ <target>Mot clé :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="05fa0bded36de6e73a1fa44838b627349dace044" datatype="html">
+ <source>Date:</source>
+ <target>Date :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a400388de1899b1917138cf7e5286376f72847" datatype="html">
+ <source>Time range:</source>
+ <target>Période :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="de0478286b8b5a939db54e9e5282405364ad2d61" datatype="html">
+ <source>No log entries found. Please try to select different filter options.</source>
+ <target>Aucune entrée de journal n'a été trouvée. Essayez de sélectionner d'autres options de filtrage.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7479674d91142b785b9547a87e5fb51cb16108" datatype="html">
+ <source>Reset filter.</source>
+ <target>Réinitialisez le filtre.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="31a9c2870a934b594d1390146c489f76440859ea" datatype="html">
+ <source>Edit Manager module</source>
+ <target>Modifier le module Manager</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="46e09b8290d3d0afdb6baa2021395b0570606a31" datatype="html">
+ <source>The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</source>
+ <target>La valeur entrée n'est pas un UUID valide, par exemple : 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7aacd038b39cfd347107d01d1dc27f5cb3e0951c" datatype="html">
+ <source>The entered value needs to be a valid IP address.</source>
+ <target>La valeur entrée doit être une adresse IP valide.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f19106149f4b07a0d721f9d317afed393cb7bd93" datatype="html">
+ <source>The entered value is too high! It must be lower or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>.</source>
+ <target>La valeur saisie est trop élevée ! Elle doit être inférieure ou égale à <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d33c40ef9a6c3bf0888df831b25e41e65f9d15b" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>.</source>
+ <target>La valeur saisie est trop basse ! Elle doit être supérieure ou égale à <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eae7086660cf1e38c7194a2c49ff52cc656f90f5" datatype="html">
+ <source>The entered value needs to be a number.</source>
+ <target>La valeur entrée doit être un nombre.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">194</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a73376e04b4fb3a20734c8c39743fba32e6676ce" datatype="html">
+ <source>The entered value needs to be a number or decimal.</source>
+ <target>La valeur entrée doit être un nombre ou une valeur décimale.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1898719236268328097" datatype="html">
+ <source>Updated options for module '<x id="PH" equiv-text="this.moduleName"/>'.</source>
+ <target>Options mises à jour pour le module '<x id="PH" equiv-text="this.moduleName"/>'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4186041075388034600" datatype="html">
+ <source>Always-On</source>
+ <target>Toujours actif</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7585826646011739428" datatype="html">
+ <source>Edit</source>
+ <target>Modifier</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2180291763949669799" datatype="html">
+ <source>Enable</source>
+ <target>Activer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9187855490716817910" datatype="html">
+ <source>Disable</source>
+ <target>Désactiver</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1600086764852993170" datatype="html">
+ <source>This Manager module is always on.</source>
+ <target>Ce module Manager est toujours actif.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3895296744591223546" datatype="html">
+ <source>Reconnecting, please wait ...</source>
+ <target>Reconnexion en cours… Veuillez patienter.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81b97b8ea996ad1e4f9fca8415021850214884b1" datatype="html">
+ <source>Status</source>
+ <target>Statut</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57ec6032f5618d4a9f16eb950ad23d2ce7c24b54" datatype="html">
+ <source>Cluster ID</source>
+ <target>ID de grappe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67d7facc3fec5f8a49ab9ba0a245872184264ce5" datatype="html">
+ <source>monmap modified</source>
+ <target>monmap modifié</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4906731aaf2b94b4f547646c9bfe58bb77951b6" datatype="html">
+ <source>monmap epoch</source>
+ <target>monmap epoch</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd4ee06ffdc46d9dfbd0c0c4f81399021c680056" datatype="html">
+ <source>quorum con</source>
+ <target>quorum con</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1176c7db8a8276ccb44cc3d42e2c28d9fa6c6596" datatype="html">
+ <source>quorum mon</source>
+ <target>quorum mon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="530ef677a09d681b3ab68cb0760494b3ae72a77c" datatype="html">
+ <source>required con</source>
+ <target>required con</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a91558e0d506c32021c31843f8f168899fc65cbf" datatype="html">
+ <source>required mon</source>
+ <target>required mon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3abe9eac5bcd94a54c8da93b312e085ec512e74" datatype="html">
+ <source>In Quorum</source>
+ <target>Dans le quorum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba4b748a676e1f217ce1e736fb7ec1215e677bae" datatype="html">
+ <source>Not In Quorum</source>
+ <target>Hors quorum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3517477838460618200" datatype="html">
+ <source>Public Address</source>
+ <target>Adresse publique</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6949358970125514744" datatype="html">
+ <source>Open Sessions</source>
+ <target>Sessions ouvertes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4383e9662ea19839c7499b2128d43a195e564317" datatype="html">
+ <source>OSD creation preview</source>
+ <target>Aperçu de la création OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="366225c51e0b00bcb1c55795a0dc5e81c455f84e" datatype="html">
+ <source>DriveGroups</source>
+ <target>DriveGroups</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91853167141c37b58868f3b0421383dd72fa8a01" datatype="html">
+ <source>Attributes (OSD map)</source>
+ <target>Attributs (carte OSD)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f721a500a68c357e8f2a01e60510f6a01e4ba529" datatype="html">
+ <source>Metadata</source>
+ <target>Métadonnées</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97842f379e1d4157ac3ab0661b90c352e7cb72d5" datatype="html">
+ <source>Metadata not available</source>
+ <target>Métadonnées non disponibles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24e28e19c5703d7c6be44f4eb595a6a43b618ed" datatype="html">
+ <source>Performance counter</source>
+ <target>Compteur de performance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ccb4f84edc0b4e76415bb3f9b73d725b06683af3" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ name }}"/> devices</source>
+ <target>Périphériques <x id="INTERPOLATION" equiv-text="{{ name }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60cb3d01e5ddf266ecb4271007a1c3d0f3efdc22" datatype="html">
+ <source>The primary storage devices. These devices contain all OSD data.</source>
+ <target>Périphériques de stockage primaires. Ces périphériques contiennent toutes les données OSD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b432e04886d0d1fd84f740477383051f85addcf2" datatype="html">
+ <source>Write-Ahead-Log devices. These devices are used for BlueStore’s internal journal. It is only useful to use a WAL device if the device is faster than the primary device (e.g. NVME devices or SSDs). If there is only a small amount of fast storage available (e.g., less than a gigabyte), we recommend using it as a WAL device.</source>
+ <target>Périphériques Write-Ahead-Log. Ces périphériques sont utilisés pour le journal interne de BlueStore. Un périphérique WAL n'est utile que s'il est plus rapide que le périphérique primaire (par exemple, périphériques NVME ou SSD). Si la quantité d'espace de stockage rapide disponible est limitée (par exemple, moins d'un gigaoctet), nous recommandons de l'utiliser en tant que périphérique WAL.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87e181ab9e8393aa5ed759dd3d53836e32c8ffe" datatype="html">
+ <source>DB devices can be used for storing BlueStore’s internal metadata. It is only helpful to provision a DB device if it is faster than the primary device (e.g. NVME devices or SSD).</source>
+ <target>Les périphériques DB peuvent être utilisés pour stocker les métadonnées internes de BlueStore. Le provisioning d'un périphérique DB n'est utile que s'il est plus rapide que le périphérique primaire (par exemple, périphériques NVME ou SSD).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
+ <source>Add</source>
+ <target>Ajouter</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="99ee4faa69cd2ea8e3678c1f557c0ff1f05aae46" datatype="html">
+ <source>Clear</source>
+ <target>Effacer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e0fd3c7af0630f93befa6234a693a32a61084e0" datatype="html">
+ <source>Raw capacity: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></source>
+ <target>Capacité brute : <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1961811273151129466" datatype="html">
+ <source>No available devices</source>
+ <target>Aucun périphérique disponible</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617271647728055571" datatype="html">
+ <source>Please add primary devices first</source>
+ <target>Ajoutez d'abord les périphériques primaires</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6368751795251107516" datatype="html">
+ <source>Add devices by using filters</source>
+ <target>Ajouter des périphériques à l'aide de filtres</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8edc89137d0d8c5667a2f03230beafae45e58429" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> devices</source>
+ <target>Périphériques <x id="INTERPOLATION" equiv-text="{{ deviceType }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eba28e1805b18f7c8ae2e4bc15dcf063b10b3822" datatype="html">
+ <source>At least one of these filters must be applied in order to proceed:</source>
+ <target>Au moins un de ces filtres doit être appliqué pour pouvoir continuer :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="93389aa2fe2bea50bf89554ee51b28f87ee2fb50" datatype="html">
+ <source>Number of devices: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Raw capacity: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</source>
+ <target>Nombre de périphériques : <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Capacité brute : <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">29,30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6b27c16ddf33b855412c82069dca8120bd3a68a" datatype="html">
+ <source>Individual OSD Flags</source>
+ <target>Drapeaux OSD individuels</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dba0ed9ba355a3bd3296c0bef3bb518744a51a89" datatype="html">
+ <source>Cluster-wide</source>
+ <target>À l'échelle de la grappe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e2a3f211cea2cbadb29b6df93e544440b6b68d3e" datatype="html">
+ <source>Restore previous selection</source>
+ <target>Restaurer la sélection précédente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1683654169791509804" datatype="html">
+ <source>No Up</source>
+ <target>Pas démarrés</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5754783193519044074" datatype="html">
+ <source>OSDs are not allowed to start</source>
+ <target>Les OSD ne sont pas autorisés à démarrer.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4413588319909369773" datatype="html">
+ <source>No Down</source>
+ <target>Pas arrêtés</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1348746748821823470" datatype="html">
+ <source>OSD failure reports are being ignored, such that the monitors will not mark OSDs down</source>
+ <target>Les rapports de défaillance des OSD sont ignorés, de sorte que les moniteurs ne marquent pas les OSD comme étant arrêtés.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="301172600132606646" datatype="html">
+ <source>No In</source>
+ <target>Pas rentrés</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4114057962148673377" datatype="html">
+ <source>OSDs that were previously marked out will not be marked back in when they start</source>
+ <target>Les OSD qui ont été marqués comme sortis ne seront pas marqués comme rentrés à leur démarrage.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5236523991485603657" datatype="html">
+ <source>No Out</source>
+ <target>Pas sortis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1798160169020638994" datatype="html">
+ <source>OSDs will not automatically be marked out after the configured interval</source>
+ <target>Les OSD ne seront pas marqués automatiquement comme sortis après l'intervalle configuré.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3225813593817914267" datatype="html">
+ <source>The flag has been enabled for the entire cluster.</source>
+ <target>Le drapeau a été activé pour toute la grappe.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1941050626944682985" datatype="html">
+ <source>Updated OSD Flags</source>
+ <target>Drapeaux OSD mis à jour</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ef50ba2514414f799d4c8fc36067a251904ba81" datatype="html">
+ <source>Cluster-wide OSD Flags</source>
+ <target>Drapeaux OSD à l'échelle de la grappe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9042260521669277115" datatype="html">
+ <source>Pause</source>
+ <target>Pause</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6015425610572318971" datatype="html">
+ <source>Pauses reads and writes</source>
+ <target>Met en pause les lectures et écritures</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314873595759611676" datatype="html">
+ <source>No Scrub</source>
+ <target>Pas de nettoyage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773570234687653570" datatype="html">
+ <source>Scrubbing is disabled</source>
+ <target>Nettoyage désactivé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5999821123886006899" datatype="html">
+ <source>No Deep Scrub</source>
+ <target>Pas de nettoyage en profondeur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5362685148875251772" datatype="html">
+ <source>Deep Scrubbing is disabled</source>
+ <target>Le nettoyage en profondeur est désactivé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5001752039592388485" datatype="html">
+ <source>No Backfill</source>
+ <target>Pas de renvoi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4851280330655956778" datatype="html">
+ <source>Backfilling of PGs is suspended</source>
+ <target>Le renvoi des groupes de placements est suspendu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5994953210305546559" datatype="html">
+ <source>No Rebalance</source>
+ <target>Pas de rééquilibrage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3698980403470604587" datatype="html">
+ <source>OSD will choose not to backfill unless PG is also degraded</source>
+ <target>L'OSD choisira de n'effectuer un renvoi que si un groupe de placements est également détérioré</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4334886823145076432" datatype="html">
+ <source>No Recover</source>
+ <target>Pas de récupération</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8465994741155792816" datatype="html">
+ <source>Recovery of PGs is suspended</source>
+ <target>La récupération des groupes de placements est suspendue</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4052740759486923001" datatype="html">
+ <source>Bitwise Sort</source>
+ <target>Tri au niveau du bit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2330377428425572488" datatype="html">
+ <source>Use bitwise sort</source>
+ <target>Utiliser le tri au niveau du bit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8943478424576832224" datatype="html">
+ <source>Purged Snapdirs</source>
+ <target>Variables snapdir purgées</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7553321860087551262" datatype="html">
+ <source>OSDs have converted snapsets</source>
+ <target>Les OSD ont converti les variables snapset</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6509988280998256208" datatype="html">
+ <source>Recovery Deletes</source>
+ <target>Suppressions des récupérations</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="451760144355116641" datatype="html">
+ <source>Deletes performed during recovery instead of peering</source>
+ <target>Suppressions effectuées pendant la restauration et non l'homologation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="87832369463084597" datatype="html">
+ <source>PG Log Hard Limit</source>
+ <target>Limite stricte de journalisation des groupes de placements</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9135782750879343185" datatype="html">
+ <source>Puts a hard limit on pg log length</source>
+ <target>Impose une limite stricte à la longueur du journal des groupes de placements</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="formTitle" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <note priority="1" from="description">Example: Create Pool</note>
+ <note priority="1" from="meaning">form title</note>
+ </trans-unit>
+ <trans-unit id="43ecf6bee2aebc07b0aad6dc1fe13e38d14687fa" datatype="html">
+ <source>Shared devices</source>
+ <target>Périphériques partagés</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7a1c376f6f1b37de4c318ff2106255ba6c0f5b0b" datatype="html">
+ <source>WAL slots</source>
+ <target>Connecteurs WAL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73811a6f37b63e6b0e491e221bfa21e9dea8a87a" datatype="html">
+ <source>How many OSDs per WAL device.</source>
+ <target>Nombre de périphériques OSD par périphérique WAL.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c67a7ac4762ef1cc855056c6b4daab93e53a0a5" datatype="html">
+ <source>Specify 0 to let Orchestrator backend decide it.</source>
+ <target>Indiquez 0 pour laisser le backend de l'orchestrateur en décider.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bda9362e06e6c67341b4a8425b0d29d6b84464b" datatype="html">
+ <source>Value should be greater than or equal to 0</source>
+ <target>La valeur doit être supérieure ou égale à 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="324c2b10152b9dd908222bb0b71f61beb60a30c5" datatype="html">
+ <source>DB slots</source>
+ <target>Connecteurs DB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c23cf12ef9c76f37fc7a4b7ae3e00fb0f68b6e26" datatype="html">
+ <source>How many OSDs per DB device.</source>
+ <target>Nombre de périphériques OSD par périphérique DB.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8255877266497322342" datatype="html">
+ <source>Encryption</source>
+ <target>Chiffrement</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b49d7877d24112d4bdfce9256edf61a007fae888" datatype="html">
+ <source>OSDs List</source>
+ <target>Liste des OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="172ada0fcf6490b24a897517e9f4299215873ff8" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD(s) <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be marked <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <target><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Les OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> seront marqués en tant que <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> si vous continuez.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">59,60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="262a49e60d5f6ed9825582ccf3d5ae39daa1da60" datatype="html">
+ <source>The <x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> not safe to be <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>! <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></source>
+ <target>Pour des raisons de sécurité, il est déconseillé de définir <x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> sur <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/> ! <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71,72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="74bd20d5f558d14cb2fa41ae863cf09c47d02018" datatype="html">
+ <source>{VAR_SELECT, select, true {OSD is} other {OSDs are}}</source>
+ <target>{VAR_SELECT, select, true {l'OSD est} other {les OSD sont}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0e217fd717c5b1f5c17f00c5b174de855acbef0" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <target><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>L'OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> sera <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> si vous continuez.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">74,75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8cf121660bed7098516a1efe85831d6f415a9411" datatype="html">
+ <source>Preserve OSD ID(s) for replacement.</source>
+ <target>Conserver le(s) ID OSD pour le remplacement.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4435645098786961170" datatype="html">
+ <source>out</source>
+ <target>sorti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136018875175606726" datatype="html">
+ <source>in</source>
+ <target>rentré</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1301930865667956193" datatype="html">
+ <source>down</source>
+ <target>arrêté</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1226060325201042854" datatype="html">
+ <source>Mark</source>
+ <target>Marquer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1256299033316818951" datatype="html">
+ <source>OSD lost</source>
+ <target>OSD perdu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2795727560928976873" datatype="html">
+ <source>marked lost</source>
+ <target>marqué comme perdu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7685933846431786388" datatype="html">
+ <source>Purge</source>
+ <target>Purger</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5941516286393808546" datatype="html">
+ <source>OSD</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3416443212235382421" datatype="html">
+ <source>purged</source>
+ <target>purgé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9191368063029792986" datatype="html">
+ <source>destroy</source>
+ <target>détruire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4425946029386289247" datatype="html">
+ <source>destroyed</source>
+ <target>détruit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2870788902465061969" datatype="html">
+ <source>Flags</source>
+ <target>Drapeaux</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8995035642420075344" datatype="html">
+ <source>Recovery Priority</source>
+ <target>Priorité de récupération</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3601135996773579607" datatype="html">
+ <source>PG scrub</source>
+ <target>Nettoyage du groupe de placements</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136079353894161076" datatype="html">
+ <source>Device class</source>
+ <target>Classe de périphérique</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6382718875453721838" datatype="html">
+ <source>PGs</source>
+ <target>Groupes de placements</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3660230483843323377" datatype="html">
+ <source>Read bytes</source>
+ <target>Octets de lecture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">329</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3909578649547040612" datatype="html">
+ <source>Write bytes</source>
+ <target>Octets d'écriture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3182358405280886750" datatype="html">
+ <source>Read ops</source>
+ <target>Opérations de lecture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171292502535561083" datatype="html">
+ <source>Write ops</source>
+ <target>Opérations d'écriture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6706824709967518168" datatype="html">
+ <source>Edit OSD: <x id="PH" equiv-text="selectedOsd.id"/></source>
+ <target>Modifier l'OSD : <x id="PH" equiv-text="selectedOsd.id"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">451</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1125148356983553148" datatype="html">
+ <source>Edit OSD</source>
+ <target>Modifier l'OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="970212458427610374" datatype="html">
+ <source>Updated OSD '<x id="PH" equiv-text="selectedOsd.id"/>'</source>
+ <target>OSD '<x id="PH" equiv-text="selectedOsd.id"/>' mis à jour</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">466</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7554728686176829307" datatype="html">
+ <source>Mark OSD <x id="PH" equiv-text="markAction"/></source>
+ <target>Marquer l'OSD en tant que <x id="PH" equiv-text="markAction"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="478122291463667978" datatype="html">
+ <source>Mark <x id="PH" equiv-text="markAction"/></source>
+ <target>Marquer <x id="PH" equiv-text="markAction"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">502</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2456043080471762298" datatype="html">
+ <source>delete</source>
+ <target>supprimer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">530</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="588230151780724018" datatype="html">
+ <source>deleted</source>
+ <target>supprimé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">532</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1ef1c12ddcee305353623919ef02778569f5454" datatype="html">
+ <source>Advanced configuration options</source>
+ <target>Options de configuration avancées</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7771252117308888928" datatype="html">
+ <source>PG scrub options</source>
+ <target>Options de nettoyage du groupe de placements</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1797901277775175680" datatype="html">
+ <source>Updated PG scrub options</source>
+ <target>Options de nettoyage du groupe de placements mises à jour</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c35f9c5f268a514b970cc55e9a5dc4bed0988e7f" datatype="html">
+ <source>OSD Recovery Priority</source>
+ <target>Priorité de récupération des OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74af38005e8a8914e45af2ec412e11ceafef8b6" datatype="html">
+ <source>Priority</source>
+ <target>Priorité</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f48f04b379bfba133825747adfd238d511412e" datatype="html">
+ <source>Customize priority values</source>
+ <target>Personnaliser les valeurs de priorité</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aa19de2a2b54cbda39e9c62917b23044c087776" datatype="html">
+ <source>This field is required!</source>
+ <target>Ce champ est obligatoire !</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">406</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b699e94bf376491bd50b70a98531071c737eaf40" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="98fe13e7ad6c2b80375d204b47858ded83f80e15" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>.</source>
+ <target>La valeur saisie est trop élevée ! Elle ne doit pas être supérieure à <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423a3c111be47fc5a1bfe46ceb58c81c84db691" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>.</source>
+ <target>La valeur saisie est trop basse ! Elle ne doit pas être inférieure à <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3234179038052466481" datatype="html">
+ <source>Max Backfills</source>
+ <target>Nbre max. de renvois</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847070960491384020" datatype="html">
+ <source>Recovery Max Active</source>
+ <target>Nombre maximum de récupérations actives</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2088615724570210504" datatype="html">
+ <source>Recovery Max Single Start</source>
+ <target>Nombre maximum de démarrages uniques de récupérations</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8627094894361422565" datatype="html">
+ <source>Recovery Sleep</source>
+ <target>Mise en veille de la récupération</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7590013429208346303" datatype="html">
+ <source>Custom</source>
+ <target>Personnalisé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4937275625032609020" datatype="html">
+ <source>Updated OSD recovery speed priority '<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>'</source>
+ <target>Priorité mise à jour de la vitesse de récupération de l'OSD '<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">227,229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5251a4355cece3075db43f15d69a24a0f8485707" datatype="html">
+ <source>Reweight OSD: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></source>
+ <target>Réévaluer l'OSD : <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67650b2998db48201b2c6176cbfef51e7211ccaa" datatype="html">
+ <source>The value needs to be between 0 and 1.</source>
+ <target>La valeur doit être comprise entre 0 et 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f077ceb52c967a8fe2de9ef0a9d65d72badf186" datatype="html">
+ <source>OSDs <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/>Scrub</source>
+ <target>Nettoyage <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/> des OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b73a34ba65b3073e3560dce828a16d7fd3c0f4" datatype="html">
+ <source>{VAR_SELECT, select, true {Deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {En profondeur} other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c00119503aad4012b77049eee41293338f67756c" datatype="html">
+ <source>You are about to apply a <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/>scrub to the OSD(s): <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <target>Vous êtes sur le point d'appliquer un nettoyage <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/> aux OSD : <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fad3dc421817a16dd6c46c1a0c36de619a8d776e" datatype="html">
+ <source>{VAR_SELECT, select, true {deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {en profondeur} other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1086427836866943370" datatype="html">
+ <source><x id="PH" equiv-text="operation"/> was initialized in the following OSD(s): <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></source>
+ <target><x id="PH" equiv-text="operation"/> a été initialisé dans le ou les OSD suivant(s) : <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts</context>
+ <context context-type="linenumber">42,44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47c97aa28f64b11fa5842795fdd02c8c0863c97b" datatype="html">
+ <source>To see all active Prometheus alerts, please provide the URL to the API of Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>Pour afficher toutes les alertes actives de Prometheus, veuillez fournir l'URL de l'API du gestionnaire d'alertes de Prometheus, comme décrit dans <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6343323763459782070" datatype="html">
+ <source>Create Silence</source>
+ <target>Créer un silence</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1895957424873987405" datatype="html">
+ <source>Job</source>
+ <target>Travail</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491474782694268231" datatype="html">
+ <source>Severity</source>
+ <target>Gravité</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3326877877555410533" datatype="html">
+ <source>Started</source>
+ <target>Démarré</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2375260419993138758" datatype="html">
+ <source>URL</source>
+ <target>URL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="880ad4df5a2051a437321443d69c9a866699e5ad" datatype="html">
+ <source>Active Alerts</source>
+ <target>Alertes actives</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9fe218829514884cdd0ca2300573a4e0428c324f" datatype="html">
+ <source>Alerts</source>
+ <target>Alertes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa0c44aa1e5727061baa91e954f77e2f5f9a37c9" datatype="html">
+ <source>Silences</source>
+ <target>Silences</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85c737325f5e59517e2d08a71de6d77788aabc95" datatype="html">
+ <source>To see all configured Prometheus alerts, please provide the URL to the API of Prometheus as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>Pour afficher toutes les alertes configurées de Prometheus, veuillez fournir l'URL de l'API de Prometheus, comme décrit dans <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623978917681527907" datatype="html">
+ <source>Group</source>
+ <target>Groupe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7410432243549869948" datatype="html">
+ <source>Duration</source>
+ <target>Durée</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4109205891084963566" datatype="html">
+ <source>Query</source>
+ <target>Requête</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28f86ffd419b869711aa13f5e5ff54be6d70731c" datatype="html">
+ <source>Edit</source>
+ <target>Modifier</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="826b25211922a1b46436589233cb6f1a163d89b7" datatype="html">
+ <source>Delete</source>
+ <target>Supprimer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">279</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">341</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">441</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3ba06aba047605af8ea1718ec1ba153b7db12a2" datatype="html">
+ <source>Editing a silence will expire the old silence and recreate it as a new silence</source>
+ <target>La modification d'un silence fera expirer l'ancien silence et le recréera comme un nouveau silence.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a20424156b8816671f61879f0574a4f27d7b16b9" datatype="html">
+ <source>Creator</source>
+ <target>Créateur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5a5d7ee2acbfa9c91ab7f41d26bda9ff0cafe42f" datatype="html">
+ <source>Comment</source>
+ <target>Commentaire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c11aad490b2d53fdae30b3807beabf79306752c" datatype="html">
+ <source>Start time</source>
+ <target>Heure de début</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32856b1e8e339b747b21e313e2fe65a51fd450bb" datatype="html">
+ <source>If the start time lies in the past the creation time will be used</source>
+ <target>Si l'heure de début se situe dans le passé, l'heure de création est utilisée.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a02ea1d4e7424ca989929da5e598f379940fdbf2" datatype="html">
+ <source>Duration</source>
+ <target>Durée</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f4e35e36f4d3c62e2c17df41730b6dee4afc4b9" datatype="html">
+ <source>End time</source>
+ <target>Heur de fin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="992123459137d45c15df5548bc9682aad835c04b" datatype="html">
+ <source>Matchers</source>
+ <target>Comparateurs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e023166c55833d5a13f4143e3dbe372befe1b4e" datatype="html">
+ <source>A silence requires at least one matcher</source>
+ <target>Un silence nécessite au moins un comparateur.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef765bd80c4806c51c891908c07a24bc76f019eb" datatype="html">
+ <source>Add matcher</source>
+ <target>Ajouter un comparateur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754178820914251524" datatype="html">
+ <source>silence</source>
+ <target>silence</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8714559758543060819" datatype="html">
+ <source>Attribute name</source>
+ <target>Nom de l'attribut</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1338733395833138319" datatype="html">
+ <source>Regular expression</source>
+ <target>Expression régulière</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35819898450851998" datatype="html">
+ <source>Please add your Prometheus host to the dashboard configuration and refresh the page</source>
+ <target>Ajoutez votre hôte Prometheus à la configuration du tableau de bord et rafraîchissez la page</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f2f4cb9d876ff9d34fc082c1ac642d3cb98c360" datatype="html">
+ <source>To enable Silences, please provide the URL to the API of the Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>Pour activer les silences, veuillez fournir l'URL de l'API du gestionnaire d'alertes de Prometheus, tel que décrit dans <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7448808151142843482" datatype="html">
+ <source>Created by</source>
+ <target>Auteur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4734349318830134239" datatype="html">
+ <source>Ends</source>
+ <target>Fin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1233087251567318644" datatype="html">
+ <source>Silence</source>
+ <target>Silence</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="78af6a5e6e4d305557054b64d10f9f9446d8043d" datatype="html">
+ <source>{VAR_SELECT, select, true {Edit} other {Add}}</source>
+ <target>{VAR_SELECT, select, true {Modifier} other {Ajouter}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2404fa8e80946d0ce3d0ae369b51cb26ec28d42" datatype="html">
+ <source><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/> Matcher</source>
+ <target>Comparateur <x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c25e04f554875dc2625a78ba0fc56c6010cd0d3" datatype="html">
+ <source>-- Select an attribute to match against --</source>
+ <target>-- Sélectionnez un attribut à comparer --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5049e204c14c648691ac775a64fb504467aeb549" datatype="html">
+ <source>Value</source>
+ <target>Valeur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="77fc5c63497fc031ddc97645484e3d94ad27766c" datatype="html">
+ <source>Use regular expression</source>
+ <target>Utilisez une expression régulière</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5518753745858598442" datatype="html">
+ <source>no spec</source>
+ <target>aucune spécification</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1186363766752354382" datatype="html">
+ <source>unmanaged</source>
+ <target>non géré(e)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5246585784774990516" datatype="html">
+ <source>count:<x id="PH" equiv-text="count"/></source>
+ <target>nombre :<x id="PH" equiv-text="count"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001661117318762535" datatype="html">
+ <source>label:<x id="PH" equiv-text="label"/></source>
+ <target>libellé :<x id="PH" equiv-text="label"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cb3aa7e9fea1d445a1a9d7797ab17e6ac6fe13b" datatype="html">
+ <source>Service Events</source>
+ <target>Événements de service</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3474944817987674409" datatype="html">
+ <source>Daemon type</source>
+ <target>Type de daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3136939605470297323" datatype="html">
+ <source>Daemon ID</source>
+ <target>ID du daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8171022601808215887" datatype="html">
+ <source>Container ID</source>
+ <target>ID du conteneur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8859473568390700297" datatype="html">
+ <source>Container Image name</source>
+ <target>Nom de l'image de conteneur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5623167616584404899" datatype="html">
+ <source>Container Image ID</source>
+ <target>ID de l'image de conteneur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="335348913532561915" datatype="html">
+ <source>Last Refreshed</source>
+ <target>Dernier rafraîchissement</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3022087209429182774" datatype="html">
+ <source>Daemon Events</source>
+ <target>Événements du daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">140</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8604852007710946848" datatype="html">
+ <source>Service Name</source>
+ <target>Nom du service</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="613875387304159316" datatype="html">
+ <source>Service Type</source>
+ <target>Type de service</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907644935670421963" datatype="html">
+ <source>Service Events</source>
+ <target>Événements de service</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3214a1f3a4c3e89a848b4ec59adeeda3b913c396" datatype="html">
+ <source>-- Select a service type --</source>
+ <target>-- Sélectionnez un type de service --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f32579a9fd19d93c083175284ee3426d78751c33" datatype="html">
+ <source>Backend Service</source>
+ <target>Service Backend</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2937074aed12b8158e929c58747a8216433b72b" datatype="html">
+ <source>-- No service available --</source>
+ <target>-- Aucun service disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19fb4480d95a5539db4e9c7b516d414774e61110" datatype="html">
+ <source>-- Select an existing RGW service --</source>
+ <target>-- Sélectionnez un service RGW existant --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2798cc1e152b1ec07fd8daf94a2a073d1ba1ebcc" datatype="html">
+ <source>Id</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d5156b9d9a79d162c353c4aa9bc6840ad5c6257" datatype="html">
+ <source>The value does not match the pattern <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&lt;service_id&gt;[.&lt;realm_name&gt;.&lt;zone_name&gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <target>La valeur ne correspond pas au modèle <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&amp;lt;service_id&amp;gt;[.&amp;lt;nom_domaine&amp;gt;.&amp;lt;nom_zone&amp;gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83d5d7edd8a0be253c4e93ad4c3efe86d9ac520f" datatype="html">
+ <source>Unmanaged</source>
+ <target>Non géré(e)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c15fa461935e0f600bc5d1660af1da67f024fc2a" datatype="html">
+ <source>Placement</source>
+ <target>Placement</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="863226cffd5b66a6fee9810a9282a5006d6ef576" datatype="html">
+ <source>Label</source>
+ <target>Libellé </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06412bce0f4fe4311193e9763666089bf9d980da" datatype="html">
+ <source>Count</source>
+ <target>Nombre</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f193722f1e788f14a823b89ac1794c3ba934f9f" datatype="html">
+ <source>Only that number of daemons will be created.</source>
+ <target>Seul ce nombre de daemon sera créé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee1a29cc658e4fa891be762d7bae96139b57c8f4" datatype="html">
+ <source>The value must be at least 1.</source>
+ <target>La valeur doit être au moins égale à 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">369</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cb2741a46e3560f6bc6dfd99d385e86b08b26d72" datatype="html">
+ <source>Port</source>
+ <target>Port</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a23ed3598cca5285606675b6cb2536a56b411ade" datatype="html">
+ <source>The value cannot exceed 65535.</source>
+ <target>La valeur ne peut pas dépasser 65535.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">404</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d8ebdc326e6b9ff35feee3f762b7ab39c02d78f" datatype="html">
+ <source>-- No pools available --</source>
+ <target>-- Aucune réserve disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84b675705324741b954615fedf2417d4d873b0b6" datatype="html">
+ <source>Trusted IPs</source>
+ <target>Adresses IP approuvées</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b543e7c787cc48c2938cbce2d14c6afea5a598df" datatype="html">
+ <source>Comma separated list of IP addresses.</source>
+ <target>Liste d'adresses IP séparées par des virgules.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1039ea40da18a6453d9c1adc72a35aed099029d0" datatype="html">
+ <source>Please add the <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> IP addresses here, otherwise the iSCSI gateways can't be reached.</source>
+ <target>Veuillez ajouter les adresses IP de <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> ici, car sinon les passerelles iSCSI ne seront pas joignables.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6265b64c17a1e19775769489bfd0b152fa1f3ba1" datatype="html">
+ <source>Virtual IP</source>
+ <target>Adresse IP virtuelle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61893fde6e9e05a6b91619d501edaa7962b438ff" datatype="html">
+ <source>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</source>
+ <target>Adresse IP virtuelle et sous-réseau (en notation CIDR) dans lequel le service d'entrée sera disponible.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">333</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ece04ddf7e96f445415ebd90d93c455e03e8cf53" datatype="html">
+ <source>Frontend Port</source>
+ <target>Port Frontend</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">352</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae6fd97454d184b374984c9ff808176ece54f0dd" datatype="html">
+ <source>The port used to access the ingress service.</source>
+ <target>Port utilisé pour accéder au service d'entrée.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1261eacf161f75efc9dfea84dd97b4a466b89aa1" datatype="html">
+ <source>Monitor Port</source>
+ <target>Port du moniteur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4df6281ed630ba96f09790a46a7fe0ec0e666bb6" datatype="html">
+ <source>The port used by haproxy for load balancer status.</source>
+ <target>Port utilisé par haproxy pour le statut de l'équilibreur de charge.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ce24ae1d792ed2846ba57e7ed6397a802caeff5" datatype="html">
+ <source>CIDR Networks</source>
+ <target>Réseaux CIDR</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">414</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7c13184af0c09e3bad77daa5f4869138708d26b2" datatype="html">
+ <source>A list of networks to identify which network interface to use for the virtual IP address.</source>
+ <target>Liste de réseaux permettant d'identifier l'interface réseau à utiliser pour l'adresse IP virtuelle.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8fe73a4787b8068b2ba61f54ab7e0f9af2ea1fc9" datatype="html">
+ <source>Version</source>
+ <target>Version</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a6855d17f6b9820bb9709870efdcc7da99552d3" datatype="html">
+ <source>-- Select SNMP version --</source>
+ <target>-- Sélectionnez la version SNMP --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">442</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a7369891e88cd613e45a39b55a282c97776d05f5" datatype="html">
+ <source>Destination</source>
+ <target>Destination</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f09a5d334a73a4b5ba031d7fa65151cad5ec7133" datatype="html">
+ <source>Must be of the format hostname:port.</source>
+ <target>Doit être au format nomhôte:port.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b68c79ffe3af1db88180454fbc2fa880a51ccf52" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>hostname:port<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>La valeur ne correspond pas au modèle : <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>nomhôte:port.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">470</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c90ad98a026d781ab729911873767e549d78f99" datatype="html">
+ <source>Engine Id</source>
+ <target>ID du moteur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">478</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d39d015ebd667fb6bddf08bb0e5b3faa6cf044c" datatype="html">
+ <source>Unique identifier for the device (in hex).</source>
+ <target>Identifiant unique du périphérique (en valeur hexadécimale).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">480</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514cda7dc49062c5c532427245ce47c4954bc32" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>La valeur ne correspond pas au modèle : <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Doit être une valeur hexadécimale et sa longueur doit être un multiple de 2 avec une valeur minimale de 10 et une valeur maximale de 64.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b2d628c51192ade0044212b409c758c20f9c021" datatype="html">
+ <source>Auth Protocol</source>
+ <target>Protocole d'authentification</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc8bb2315a5101770a752b18e03b5c730539397c" datatype="html">
+ <source>-- Select auth protocol --</source>
+ <target>-- Sélectionnez un protocole d'authentification --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">508</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6777f99fd13e03874afe26ba7289dc9fc211af04" datatype="html">
+ <source>Privacy Protocol</source>
+ <target>Protocole de confidentialité</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70512b7c13bce85b3928920b29fafbd59a853383" datatype="html">
+ <source>-- Select privacy protocol --</source>
+ <target>-- Sélectionnez un protocole de confidentialité --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b48c81465d14465b95826b99e05acfabef1814c6" datatype="html">
+ <source>Credentials</source>
+ <target>Informations d'identification</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">541</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4ea0163c25c818aab982072b1b8d5ab585e9a5a" datatype="html">
+ <source>SNMP Community</source>
+ <target>Communauté SNMP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">547</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="08c74dc9762957593b91f6eb5d65efdfc975bf48" datatype="html">
+ <source>Username</source>
+ <target>Nom d'utilisateur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="948758e1412bb2ecdb98e3a4f1cbb6d7458456f2" datatype="html">
+ <source>Encryption</source>
+ <target>Chiffrement</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">598</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e65610b5d940367f1ff6b57772b96e94e35fe202" datatype="html">
+ <source>SSL</source>
+ <target>SSL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">624</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e37e0d06148c7708e88b4a1eb412babbe1a4afc" datatype="html">
+ <source>Certificate</source>
+ <target>Certificat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">634</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="295ae4f632322098deca8a3ddfbc7aeaabb5423b" datatype="html">
+ <source>The SSL certificate in PEM format.</source>
+ <target>Certificat SSL au format PEM.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">635</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464272c069fe56f6c50f41f426a25b2a42c95ba5" datatype="html">
+ <source>Invalid SSL certificate.</source>
+ <target>Certificat SSL non valide.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">650</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0596d06bf1f8a15d4bfe56226971ecdd78013b1f" datatype="html">
+ <source>Private key</source>
+ <target>Clé privée</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">659</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ded15dc55104994c0230189f34dff84a4955aafb" datatype="html">
+ <source>The SSL private key in PEM format.</source>
+ <target>Clé privée SSL au format PEM.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">660</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19bdc1597d815b456793ff87c89af4257a85a103" datatype="html">
+ <source>Invalid SSL private key.</source>
+ <target>Clé privée SSL non valide.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">675</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3356018487523380058" datatype="html">
+ <source>service</source>
+ <target>service</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2412938991511187011" datatype="html">
+ <source>There are no hosts.</source>
+ <target>Il n'y a pas d'hôtes.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2594503755408511486" datatype="html">
+ <source>Filter hosts</source>
+ <target>Filtrer les hôtes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5869780110608474933" datatype="html">
+ <source>Placement</source>
+ <target>Placement</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2956098160626271284" datatype="html">
+ <source>Running</source>
+ <target>En cours d'exécution</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="013f48ee777d2e53e2bcba36e1a99fcbb7ef8cb6" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report configuration</source>
+ <target>Étape <x id="INTERPOLATION" equiv-text="{{ step }}"/> sur 2 : configuration du rapport de télémétrie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a09b723a928774bff707973c99999dcf3d84a349" datatype="html">
+ <source>The telemetry module sends anonymous data about this Ceph cluster back to the Ceph developers to help understand how Ceph is used and what problems users may be experiencing.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> This data is visualized on <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>public dashboards<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> that allow the community to quickly see summary statistics on how many clusters are reporting, their total capacity and OSD count, and version distribution trends.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> The data being reported does <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>not<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> contain any sensitive data like pool names, object names, object contents, hostnames, or device serial numbers. It contains counters and statistics on how the cluster has been deployed, the version of Ceph, the distribution of the hosts and other parameters which help the project to gain a better understanding of the way Ceph is used. The data is sent secured to <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> and <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (device report).</source>
+ <target>Le module de télémétrie renvoie des données anonymes sur cette grappe Ceph aux développeurs de Ceph afin de les aider à comprendre comment Ceph est utilisé et quels problèmes les utilisateurs peuvent rencontrer.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Ces données sont visualisées sur <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>des tableaux de bord publics<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> qui permettent à la communauté de consulter rapidement un résumé des statistiques sur le nombre de grappes signalées dans le rapport, leur capacité totale et le nombre d'OSD, ainsi que les tendances de distribution des versions.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Les données rapportées ne contiennent <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>pas<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> de données sensibles comme les noms de réserves, les noms d'objets, le contenu des objets, les noms d'hôtes ou les numéros de série des périphériques. Elles contiennent des compteurs et des statistiques sur la façon dont la grappe a été déployée, la version de Ceph, la distribution des hôtes et d'autres paramètres qui aident à mieux comprendre la façon dont Ceph est utilisé dans le cadre du projet. Les données sont envoyées de manière sécurisée à <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> et <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (rapport du périphérique).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">14,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c95505b5a74151a0c235b19b9c41db7983205ba7" datatype="html">
+ <source>Deactivate</source>
+ <target>Désactiver</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19" datatype="html">
+ <source>Channels</source>
+ <target>Canaux</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e25b17c0b4ef361b6a05aaec2bbd2b7e86680458" datatype="html">
+ <source>The telemetry report is broken down into several &quot;channels&quot;, each with a different type of information that can be configured below.</source>
+ <target>Le rapport de télémétrie est divisé en plusieurs &quot;canaux&quot;, chacun ayant un type d'information différent pouvant être configuré ci-dessous.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">32,33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380ab580741bec31346978e7cab8062d6970408d" datatype="html">
+ <source>Basic</source>
+ <target>Informations de base</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd898057f0add35258a5fb5c90d792c5e2147452" datatype="html">
+ <source>Includes basic information about the cluster:</source>
+ <target>Contient des informations de base sur la grappe :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da213e9ba8a86b453d04f794f58c9803f7b062b1" datatype="html">
+ <source>Capacity of the cluster</source>
+ <target>Capacité de la grappe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d5fe31d9e13239bdd223d0bbd289a1b1903e86" datatype="html">
+ <source>Number of monitors, managers, OSDs, MDSs, object gateways, or other daemons</source>
+ <target>Nombre de moniteurs, de gestionnaires, d'OSD, de MDS, de passerelles Object Gateway ou d'autres daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a3eb7834b4baf412f8863d14883972897d9acb7" datatype="html">
+ <source>Software version currently being used</source>
+ <target>Version du logiciel actuellement utilisée</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34881ae65482ffa74ccb4043fb2622e48ed146d5" datatype="html">
+ <source>Number and types of RADOS pools and CephFS file systems</source>
+ <target>Nombre et types de réserves RADOS et systèmes de fichiers CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="696f8f5ea7a9cf6125b9a3af160981fda363552d" datatype="html">
+ <source>Names of configuration options that have been changed from their default (but not their values)</source>
+ <target>Noms des options de configuration qui ont été modifiées par rapport à leur valeur par défaut (mais pas leurs valeurs)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34292940316300d09abe5e675d452fae199f626b" datatype="html">
+ <source>Crash</source>
+ <target>Incident</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7620e332b7dea1e832158e85847255eb4d9e6bbc" datatype="html">
+ <source>Includes information about daemon crashes:</source>
+ <target>Contient des informations sur les incidents avec le daemon :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1aa4306a6e840fe35b70c9b07d38ce85f281cfa" datatype="html">
+ <source>Type of daemon</source>
+ <target>Type de daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4f2cbedb4b14b68bc9f390e3391445c1b6682da" datatype="html">
+ <source>Version of the daemon</source>
+ <target>Version du daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d62603cdc75645ea873fc8f7f69c32b5f4a2aa9" datatype="html">
+ <source>Operating system (OS distribution, kernel version)</source>
+ <target>Système d'exploitation (distribution OS, version du kernel)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84facf84a73631d66e9a4e0bc1c40097b9d14742" datatype="html">
+ <source>Stack trace identifying where in the Ceph code the crash occurred</source>
+ <target>Trace de la pile identifiant l'endroit où s'est produit l'incident dans le code Ceph</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea64d4177bd648e1a20c92669e6857762b811d8c" datatype="html">
+ <source>Device</source>
+ <target>Périphérique</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4bc37bcbbcea881a269b4063b3d93dec8ee67d5" datatype="html">
+ <source>Includes information about device metrics like anonymized SMART metrics.</source>
+ <target>Comprend des informations sur les mesures des périphériques comme des mesures SMART anonymisées.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37de70e8ba539187d0171a38dad2a63c323096eb" datatype="html">
+ <source>Ident</source>
+ <target>Identification</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b126025440f118cd02ce78362d61a5001c27617" datatype="html">
+ <source>Includes user-provided identifying information about the cluster:</source>
+ <target>Comprend des informations d'identification fournies par l'utilisateur concernant la grappe :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62c6e9aecff7e04ef7d36fdee4ab4fb285a7a2b5" datatype="html">
+ <source>Contact Information</source>
+ <target>Coordonnées</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61ba9a84051b3f470122e59cf5a746552b378269" datatype="html">
+ <source>Submitting any contact information is completely optional and disabled by default.</source>
+ <target>L'envoi de coordonnés est entièrement facultatif et désactivé par défaut.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34746fb1c7f3d2194d99652bdff89e6e14c9c4f4" datatype="html">
+ <source>Contact</source>
+ <target>Contact</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="632cac1e025b77b2d77fed16ad22a410ddacab9e" datatype="html">
+ <source>My first Ceph cluster</source>
+ <target>Ma première grappe Ceph</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3a58c8a81b9ffda26a154eae25a422c9f7de37b" datatype="html">
+ <source>Organization</source>
+ <target>Organisation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e8fda44e2c5bb51860f26cd9c2730f9ae1db9869" datatype="html">
+ <source>Organization name</source>
+ <target>Nom de l'organisation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d49310535abb3792d8c9c991dd0d990d73d29af" datatype="html">
+ <source>Interval</source>
+ <target>Intervalle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91317562c9dfefbdd5973faf11d217f571d073c7" datatype="html">
+ <source>The module compiles and sends a new report every 24 hours by default. You can adjust this interval by setting a different number of hours.</source>
+ <target>Par défaut, le module compile et envoie un nouveau rapport toutes les 24 heures. Vous pouvez ajuster cet intervalle en définissant un nombre d'heures différent.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">185,186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a12cf4cf71ef3161a024382ab542cf0eba094504" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to 8.</source>
+ <target>La valeur entrée est trop basse ! Elle doit être supérieure ou égale à 8.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a92e437fac14b4010c4515b31c55a311d026a57f" datatype="html">
+ <source>Proxy</source>
+ <target>Proxy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6de03357358c7eff62aca486508bb5c2046e0669" datatype="html">
+ <source>If the cluster cannot directly connect to the configured telemetry endpoint (default telemetry.ceph.com), you can configure a HTTP/HTTPS proxy server by e.g. adding https://10.0.0.1:8080</source>
+ <target>Si la grappe ne peut pas se connecter directement au noeud d'extrémité de télémétrie configuré (par défaut telemetry.ceph.com), vous pouvez configurer un serveur proxy HTTP/HTTPS en ajoutant, par exemple, https://10.0.0.1:8080.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5687a733af051bfca97dbffba282e39fbb9b8c8f" datatype="html">
+ <source>You can also include a user:pass if needed e.g. https://ceph:telemetry@10.0.0.1:8080</source>
+ <target>Vous pouvez également inclure un user:pass si nécessaire, par exemple https://ceph:telemetry@10.0.0.1:8080</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e6430c68df43ea65e4145972b01186fba40f26a" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Note:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> By clicking 'Next' you will first see a preview of the report content before you can activate the automatic submission of your data.</source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Remarque :<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> en cliquant sur 'Suivant', vous verrez d'abord un aperçu du contenu du rapport avant de pouvoir activer l'envoi automatique de vos données.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">219,220</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d8d878f8d60905e1306c225716305a331b784c8" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report preview</source>
+ <target>Étape <x id="INTERPOLATION" equiv-text="{{ step }}"/> sur 2 : aperçu du rapport de télémétrie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e23d0064b6474f309c74e1c928cc0920f479d9a5" datatype="html">
+ <source>Report ID <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <target>ID du rapport <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">249,252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4060e92658964e356a0992a900c8aa811c2cfec0" datatype="html">
+ <source>A randomized UUID to identify a particular cluster over the course of several telemetry reports.</source>
+ <target>UUID randomisé permettant d'identifier une grappe en particulier au cours de plusieurs rapports de télémétrie.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60900bc663571f852a04950a123508b106d97204" datatype="html">
+ <source>Report preview <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <target>Aperçu du rapport <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">267,270</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3de417f739c336284c42904552e81e8d852daecc" datatype="html">
+ <source>The actual telemetry data that will be submitted.</source>
+ <target>Données de télémétrie qui seront réellement soumises.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="933a2b6f087670ff42c95876e6ecfb2faa3e3867" datatype="html">
+ <source>I agree to my telemetry data being submitted under the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Community Data License Agreement - Sharing - Version 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></source>
+ <target>J'accepte que mes données de télémétrie soient soumises dans le cadre de l'<x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Accord de licence visant à partager les données de la communauté - Version 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">304</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8293060085588842566" datatype="html">
+ <source>The Telemetry module has been configured and activated successfully.</source>
+ <target>Le module de télémétrie a été configuré et activé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5380636888677486786" datatype="html">
+ <source>An Error occurred while updating the Telemetry module configuration. Please Try again</source>
+ <target>Une erreur s'est produite lors de la mise à jour de la configuration du module de télémétrie. Veuillez réessayer.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2bcd3296d2850de762fb943060b7e086a893181" datatype="html">
+ <source>Health</source>
+ <target>Santé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61e0f26d843eec0b33ff475e111b0c2f7a80b835" datatype="html">
+ <source>Statistics</source>
+ <target>Statistiques</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73caac4265ea7314ff061e5a1d78a6361a6dd3b8" datatype="html">
+ <source>Cluster Status</source>
+ <target>Statut de la grappe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="624f596cc3320f5e0a0d7c7346c364e5af9bdd8c" datatype="html">
+ <source>Monitors</source>
+ <target>Moniteurs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9183778f2c6473d7ccb080f651caa01faaf70c" datatype="html">
+ <source>OSDs</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c34287a0423968dac8a41463b80855a0ff789403" datatype="html">
+ <source>Managers</source>
+ <target>Gestionnaires</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="946ac5dea9921dc09d7b0a63b89535371f283b19" datatype="html">
+ <source>Object Gateways</source>
+ <target>Passerelles Object Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff03fa5bcf37c4da46ad736c1f7d03f959e8ba9a" datatype="html">
+ <source>Metadata Servers</source>
+ <target>Serveurs de métadonnées</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d817609ba4993eba859409ab71e566168f4d5f5a" datatype="html">
+ <source>iSCSI Gateways</source>
+ <target>Passerelles iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ce9dfdc6dccb28dc75a78c704e09dc18fb02dcfa" datatype="html">
+ <source>Capacity</source>
+ <target>Capacité</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f383269db2d32cccee9e936fe549dccb9fdbf4" datatype="html">
+ <source>Raw Capacity</source>
+ <target>Capacité brute</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498a109c6e9e94f1966de01aa0326f7f0ac6fb52" datatype="html">
+ <source>PG Status</source>
+ <target>Statut du groupe de placements</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5f8a813f91a11af99132e4beafc136cfc13d73b" datatype="html">
+ <source>PGs per OSD</source>
+ <target>Groupes de placements par OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32efd1c3f70e3c5244239de97a2cc95d98534a14" datatype="html">
+ <source>Client Read/Write</source>
+ <target>Lectures/Écritures client</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="52213660b2454d139ada3079a42ec6caf3c3c01e" datatype="html">
+ <source>Client Throughput</source>
+ <target>Débit client</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="275485415092cbae3a9f3cbb786ebe283cacfdd5" datatype="html">
+ <source>Recovery Throughput</source>
+ <target>Débit de récupération</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35416fcdf9cb33d2b299d3f2028c390454b55d02" datatype="html">
+ <source>Scrubbing</source>
+ <target>Nettoyage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="44ecac93d67c6a671198091c2270354f80322327" datatype="html">
+ <source><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> See <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>Logs<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for more details.</source>
+ <target><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> Consultez les <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>journaux<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> pour plus de détails.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520247697658334435" datatype="html">
+ <source>Reads</source>
+ <target>Lectures</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5947645586591788199" datatype="html">
+ <source>/s</source>
+ <target>/s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7527163811128350993" datatype="html">
+ <source>Writes</source>
+ <target>Écritures</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7684088941299429132" datatype="html">
+ <source>IOPS</source>
+ <target>IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81585474102700882" datatype="html">
+ <source>Used</source>
+ <target>Utilisé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">179</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8695656831075719969" datatype="html">
+ <source>Avail.</source>
+ <target>Dispo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6352596107300820129" datatype="html">
+ <source>Clean</source>
+ <target>Nettoyé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4016774570903735270" datatype="html">
+ <source>Working</source>
+ <target>En cours</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4467323362722952678" datatype="html">
+ <source>Unknown</source>
+ <target>Inconnu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">218</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7790772795962334429" datatype="html">
+ <source>Healthy</source>
+ <target>Sain</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4708847204147472247" datatype="html">
+ <source>Misplaced</source>
+ <target>Mal placé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3120522496446378904" datatype="html">
+ <source>Degraded</source>
+ <target>Détérioré</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8047698491745405137" datatype="html">
+ <source>Unfound</source>
+ <target>Introuvable</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81117556780777231" datatype="html">
+ <source>objects</source>
+ <target>objets</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795e8a00db46b750113d5db93e8d97e2b3079894" datatype="html">
+ <source>For an overview of <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/> widgets click <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></source>
+ <target>Pour avoir un aperçu des widgets <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/>, cliquez <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">21,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16bd21c1b48036d54c6a595f5cff2540cfba7f60" datatype="html">
+ <source>here</source>
+ <target>ici</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8515973702474791807" datatype="html">
+ <source>up</source>
+ <target>opérationnel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4223604072115719661" datatype="html">
+ <source>no filesystems</source>
+ <target>aucun système de fichiers</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2078241808113697591" datatype="html">
+ <source>active</source>
+ <target>actif</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3232506912392089107" datatype="html">
+ <source>standby</source>
+ <target>veille</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576716133013765863" datatype="html">
+ <source>standby daemons</source>
+ <target>daemons en veille</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3629620351427988554" datatype="html">
+ <source>active daemon</source>
+ <target>daemon actif</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5954854563228355745" datatype="html">
+ <source>standbyReplay</source>
+ <target>standbyReplay</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7329683463736701292" datatype="html">
+ <source>n/a</source>
+ <target>n/a</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/not-available.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8271970016544066882" datatype="html">
+ <source><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (quorum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</source>
+ <target><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (quorum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mon-summary.pipe.ts</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6489441800790477240" datatype="html">
+ <source>total</source>
+ <target>total</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5965118847182332588" datatype="html">
+ <source>near full</source>
+ <target>presque plein(e)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="268166731974484199" datatype="html">
+ <source>full</source>
+ <target>complet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47116253e36f4e38a97ba41b2d3122c6c15ab904" datatype="html">
+ <source>Clients (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</source>
+ <target>Clients (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5159814115056353668" datatype="html">
+ <source>Addresses</source>
+ <target>Adresses</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1811797298582428088" datatype="html">
+ <source>Access Type</source>
+ <target>Type d'accès</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3575940435199094878" datatype="html">
+ <source>Squash</source>
+ <target>Écraser</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2944102521023817891" datatype="html">
+ <source>Cluster</source>
+ <target>Grappe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91772203889648189" datatype="html">
+ <source>NFS Protocol</source>
+ <target>Protocole NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907766170797643122" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1032539711043211945" datatype="html">
+ <source>Transport</source>
+ <target>Transport</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2489852208080013495" datatype="html">
+ <source>Storage Backend</source>
+ <target>Backend de stockage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8440421106569981118" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4095248496892792741" datatype="html">
+ <source>CephFS User</source>
+ <target>Utilisateur CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2535727951299201687" datatype="html">
+ <source>CephFS Filesystem</source>
+ <target>Système de fichiers CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2169401160512036026" datatype="html">
+ <source>Security Label</source>
+ <target>Libellé de sécurité</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3671149880069127721" datatype="html">
+ <source>Object Gateway</source>
+ <target>Object Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1643028261508790" datatype="html">
+ <source>Object Gateway User</source>
+ <target>Utilisateur Object Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2dae0bda66f6a349444951c0379c28cda47d6d1" datatype="html">
+ <source>Any client can access</source>
+ <target>Accès possible par tous les clients</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7882f2edb1d4139800b276b6b0bbf5ae0b2234ef" datatype="html">
+ <source>Addresses</source>
+ <target>Adresses</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f3f74c0f6925826cb2188576391c0da01a23f0" datatype="html">
+ <source>Must contain one or more comma-separated values</source>
+ <target>Doit contenir une ou plusieurs valeurs séparées par une virgule</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb5b2073697f3f4378c44a49b7524934c9268f4" datatype="html">
+ <source>For example:</source>
+ <target>Par exemple :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f969c655b3fbe4fba7e277caf4cd2c459f9fca5" datatype="html">
+ <source>Access Type</source>
+ <target>Type d'accès</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28952831a284cfe2b4fc39ca610e80b52598905a" datatype="html">
+ <source>Squash</source>
+ <target>Écraser</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0660ae339068979854ade34a96546980723dede3" datatype="html">
+ <source>Add clients</source>
+ <target>Ajouter des clients</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8571141481686087364" datatype="html">
+ <source>(inherited from global config)</source>
+ <target>(hérité de la configuration globale)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3563954518111128118" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- Sélectionnez le type d'accès --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3802199399355755843" datatype="html">
+ <source>inherited from global config</source>
+ <target>hérité de la configuration globale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8729531250118136719" datatype="html">
+ <source>-- Select what kind of user id squashing is performed --</source>
+ <target>-- Sélectionnez le type d'écrasement d'ID utilisateur effectué --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4d1dd59b039ad818d9da7e29a773e10e41d9821" datatype="html">
+ <source>Cluster</source>
+ <target>Grappe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="625f8f0f3e5b7c92651606d77484ff3d07b3c12b" datatype="html">
+ <source>This is the ID of an NFS Service.</source>
+ <target>Il s'agit de l'ID d'un service NFS.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="135b91a2d908d5814b782695470a6a786c99d9d2" datatype="html">
+ <source>-- No cluster available --</source>
+ <target>-- Aucune grappe disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c501dba379f566885919240ea277b5bc10c14d18" datatype="html">
+ <source>-- Select the cluster --</source>
+ <target>-- Sélectionnez la grappe --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7bd3ad665c398c7fe97230ab59e67370653a82" datatype="html">
+ <source>This field is required. To create a new NFS cluster, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>add a new NFS Service<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <target>Ce champ est obligatoire. Pour créer une nouvelle grappe NFS, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>ajoutez un nouveau service NFS<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">41,43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3f6ba7fe84d6508705cdfe234f0fcc8ff85c9cf" datatype="html">
+ <source>Storage Backend</source>
+ <target>Backend de stockage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6fee356d1db954255a56d8169405a89595246b9" datatype="html">
+ <source>-- Select the storage backend --</source>
+ <target>-- Sélectionnez le backend de stockage --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3c2793dd2ef56954f872142d5ec1becb84c0fe1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="796e42bec8a6996607cf1f3e80235b86d695804a" datatype="html">
+ <source>Volume</source>
+ <target>Volume</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee3ba0ab5f0ccd597b3e44021c71e9aaad14df0a" datatype="html">
+ <source>-- No CephFS filesystem available --</source>
+ <target>-- Aucun système de fichiers CephFS disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="764c57812558b1ae66c5eec95d7efd2b1bf761e3" datatype="html">
+ <source>-- Select the CephFS filesystem --</source>
+ <target>-- Sélectionnez le système de fichiers CephFS --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="957512d0321f73e9f115bce1bd823fa635170c41" datatype="html">
+ <source>Security Label</source>
+ <target>Libellé de sécurité</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="65ce0fa4da1ed55e658aeb31d1644a29f06bb342" datatype="html">
+ <source>Enable security label</source>
+ <target>Activer le libellé de sécurité</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e808f804130c7b6ff719509cbc06ebb27393a48" datatype="html">
+ <source>CephFS Path</source>
+ <target>Chemin CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1338c2f83e49ea7f2fc04e9fe90c5d330b7a10f" datatype="html">
+ <source>A path in a CephFS file system.</source>
+ <target>Chemin dans un système de fichiers CephFS.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ecc0107badb6625466aaa3f975b5c05276f432f" datatype="html">
+ <source>Path need to start with a '/' and can be followed by a word</source>
+ <target>Le chemin doit commencer par '/' et peut être suivi d'un mot</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f9d8bd873c34c5ab2d4d0cf995fe5183ab25f6e" datatype="html">
+ <source>The path does not exist in the selected volume.</source>
+ <target>Le chemin n'existe pas dans le volume sélectionné.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd197d7773cef10f368f08c53b47979c3df1f22d" datatype="html">
+ <source>Bucket</source>
+ <target>Compartiment</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ca90b4b16347ef7017967915e8624472976c85c" datatype="html">
+ <source>The bucket does not exist or is not in the default realm (if multiple realms are configured). To continue, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>create a new bucket<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <target>Le compartiment n'existe pas ou n'est pas dans le domaine par défaut (si plusieurs domaines sont configurés). Pour continuer, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>créez un nouveau compartiment<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bee6900143996c0e908a10564532eba3da0b30fb" datatype="html">
+ <source>NFS Protocol</source>
+ <target>Protocole NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5043c0921e709935ab026bb3253ffe1f159fca1" datatype="html">
+ <source>NFSv4</source>
+ <target>NFSv4</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d2c39708a32910f89701dd7e1cfb9ec1c195768" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1f8be2ae25947bec0b84c2338201580ea053f34e" datatype="html">
+ <source>The position that this <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> export occupies in the <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo FS<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (it must be unique).</source>
+ <target>Position que cette exportation <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> occupe dans le <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>système de fichiers des pseudos<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (doit être unique).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">241,242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3af55f7fd5b1d9e5a53e030c80116dc635bfb9f" datatype="html">
+ <source>By using different Pseudo options, the same Path may be exported multiple times.</source>
+ <target>En utilisant différentes options de pseudo, il est possible d'exporter plusieurs fois le même chemin.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5eb719aa900fed3f9d4a1d74bcc158f07f67f684" datatype="html">
+ <source>The pseudo is already in use by another export.</source>
+ <target>Le pseudo est déjà utilisé par une autre exportation.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddf98fcdeeb17643db020d54f42b5e56b5f9a52a" datatype="html">
+ <source>Pseudo needs to start with a '/' and can't contain any of the following: &gt;, &lt;, |, &amp;, ( or ).</source>
+ <target>Le pseudo doit commencer par un '/' et ne peut contenir aucun des caractères suivants : &gt;, &lt;, |, &amp;, ( ou ).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="27eb35c4b4ac08781a7253a2ab40f8f7d957ba51" datatype="html">
+ <source>-- No access type available --</source>
+ <target>-- Aucun type d'accès disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">280</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="509ce016c9110a54028dafd741f15ceacbe74b5a" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- Sélectionnez le type d'accès --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67ce207d0b7eada1fe3d3187a39ba0c07be76b6c" datatype="html">
+ <source>The Object Gateway NFS backend has a number of limitations which will seriously affect applications writing to the share. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> for details before enabling write access.</source>
+ <target>Le backend NFS Object Gateway est associé à plusieurs limitations qui affecteront sérieusement l'écriture des applications dans le partage. Veuillez consulter <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> pour plus de détails avant d'activer l'accès en écriture. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">293,296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4deda03573eaaff77e63f6a238a1f0ca7816950a" datatype="html">
+ <source>-- No squash available --</source>
+ <target>-- Aucun écrasement disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">321</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a0e82a4da88e7fdf270444f838d45849676e9d4b" datatype="html">
+ <source>--Select what kind of user id squashing is performed --</source>
+ <target>-- Sélectionnez le type d'écrasement d'ID utilisateur effectué --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d01b7c3f7f06712c53d054cfbe4f53d446b038e8" datatype="html">
+ <source>Transport Protocol</source>
+ <target>Protocole de transport</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2a6ad6e8bc315f07911722c05767ac79c136d99" datatype="html">
+ <source>UDP</source>
+ <target>UDP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">349</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c030f11e0aae9b24d2c048c57f29f590be621df" datatype="html">
+ <source>TCP</source>
+ <target>TCP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">359</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f84d7fd4d52eb5b2229b632ef5119dac63d5597" datatype="html">
+ <source>No user id squashing is performed.</source>
+ <target>Aucun écrasement d'ID utilisateur n'est effectué.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">378</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb1d148107e36852325106a518385b1b0de28835" datatype="html">
+ <source>uid 0 and gid 0 are squashed to the Anonymous_Uid and Anonymous_Gid gid 0 in alt_groups lists is also squashed.</source>
+ <target>L'uid 0 et le gid 0 sont écrasés et remplacés par Anonymous_Uid et Anonymous_Gid ; le gid 0 dans les listes alt_groups est également écrasé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">382</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1309d6f67955799863337b201413faa61a175ddb" datatype="html">
+ <source>uid 0 and gid of any value are squashed to the Anonymous_Uid and Anonymous_Gid alt_groups lists is discarded.</source>
+ <target>L'uid 0 et le gid de n'importe quelle valeur sont écrasés et remplacés par Anonymous_Uid et Anonymous_Gid. Les listes alt_groups sont rejetées.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85f23d5c9b57dc78dda4150d13aa3b99e985350b" datatype="html">
+ <source>All users are squashed.</source>
+ <target>Tous les utilisateurs sont écrasés.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2691935247101074756" datatype="html">
+ <source>NFS export</source>
+ <target>Export NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8727258243239498387" datatype="html">
+ <source><x id="PH" equiv-text="fsalItem.descr"/> backend is not available. <x id="PH_1" equiv-text="errorMessage"/></source>
+ <target> <x id="PH" equiv-text="fsalItem.descr"/>Le backend est indisponible. <x id="PH_1" equiv-text="errorMessage"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2772848515253260635" datatype="html">
+ <source>Error while retrieving paths.</source>
+ <target>Erreur lors de la récupération des chemins.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5239928491238988595" datatype="html">
+ <source>Error while retrieving bucket names.</source>
+ <target>Erreur lors de la récupération des noms de compartiments.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="734c9905951a774870497c5aaae8e3ee833b6196" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2190548d236ca5f7bc7ab2bca334b860c5ff2ad4" datatype="html">
+ <source>Object Gateway</source>
+ <target>Object Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca53d681a9892d6fdbb57ee9676582186515e961" datatype="html">
+ <source>Performance counters not available</source>
+ <target>Compteurs de performance non disponibles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="490e15ecc922965b6d8194754c87c5583aa071f3" datatype="html">
+ <source>The name can only consist of alphanumeric characters, dashes and underscores.</source>
+ <target>Le nom doit être exclusivement composé de caractères alphanumériques, de tirets et de traits de soulignement.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9edc2b494e660618af3e5225f68d40b7ca67629c" datatype="html">
+ <source>The chosen erasure code profile name is already in use.</source>
+ <target>Le nom de profil du code d'effacement sélectionné est déjà utilisé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35a4206db3105ed03e0dd799e1642b75b78123e8" datatype="html">
+ <source>Root</source>
+ <target>Racine</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf425784c7073c7e7f7c1bb90c2c19db7e751db2" datatype="html">
+ <source>Failure domain type</source>
+ <target>Type de domaine de défaillance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72396a9565cf644d1fe1b21b790c4243ee270986" datatype="html">
+ <source>Device class</source>
+ <target>Classe de périphérique</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d80e0c07bfea1b693a33ef2245007de92a6780" datatype="html">
+ <source>Let Ceph decide</source>
+ <target>Laisser Ceph décider</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101611937243846632" datatype="html">
+ <source>Crush Rule</source>
+ <target>Règle Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef9ff0e6227947b48dfab4ac39ade04af758913b" datatype="html">
+ <source>Plugin</source>
+ <target>Plug-in</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd69b31bce8f630eac1d4762b0bbcf72ce19d193" datatype="html">
+ <source>Data chunks (k)</source>
+ <target>Blocs de données (k)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0d26a6172d32cb81218fe2103c54a818cbc1189" datatype="html">
+ <source>Must be equal to or greater than 2.</source>
+ <target>Doit être égal ou supérieur à 2.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ba6f4800642eba4e8b056aa7167554c3afa8db0" datatype="html">
+ <source>Chunks (k+m) have exceeded the available OSDs of <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>.</source>
+ <target>Les blocs (k+m) ont dépassé les OSD disponibles de <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="86fca2f788ce986eef835cd7ef8dfc9ae22447a4" datatype="html">
+ <source>For an equal distribution k has to be a multiple of (k+m)/l.</source>
+ <target>Pour une distribution égale, k doit être un multiple de (k+m)/l.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8dd4bc172f1adc4afadaec291e465b082909148d" datatype="html">
+ <source>K has to be equal to or greater than m in order to recover data correctly through c.</source>
+ <target>k doit être égal ou supérieur à m pour que les données puissent être récupérées correctement par le biais de c.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2e5b0e6d0dba31c59f946392699a0a6c4dd9b83" datatype="html">
+ <source>Distribution factor: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></source>
+ <target>Facteur de distribution : <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dab3a299ead121169b8e08ed618c3b6a2f66691b" datatype="html">
+ <source>Coding chunks (m)</source>
+ <target>Blocs de codage (m)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e2773e5bd4948193f18f2361d663ecc3988c656" datatype="html">
+ <source>Must be equal to or greater than 1.</source>
+ <target>Doit être égal ou supérieur à 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">146</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cde4c945a49a260c0a47bcc7cd956846930a5f7" datatype="html">
+ <source>Durability estimator (c)</source>
+ <target>Estimateur de durabilité (c)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ec9ff9931f8ea1201792d6a01bf9a47b283d692" datatype="html">
+ <source>C has to be equal to or lower than m as m defines the amount of chunks that can be used.</source>
+ <target>c doit être égal ou inférieur à m, car m définit la quantité de blocs pouvant être utilisés.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35594fe66657ea07b5b5f560927f78e81a229996" datatype="html">
+ <source>Helper chunks (d)</source>
+ <target>Blocs de programme auxiliaire (d)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0c250a8d281291273ed3504ade19ca6537e4d9a" datatype="html">
+ <source>Set d manually or use the plugin's default calculation that maximizes d.</source>
+ <target>Définissez d manuellement ou utilisez le calcul par défaut du plug-in qui optiimise d.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4304a5cd95742db0f81c3bdf29aa96bf3b0ca13d" datatype="html">
+ <source>D is automatically updated on k and m changes</source>
+ <target>d est automatiquement mis à jour lorsque k et m changent</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06a67d52427b12df2b3d439be0e1342ac72aeb5c" datatype="html">
+ <source>D can be set from <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> to <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></source>
+ <target>D peut être défini à partir de <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> sur <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4f8831d3bd6401e87710c4e3ee844f5efbf5de3" datatype="html">
+ <source>D can only be set to <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></source>
+ <target>D peut uniquement être défini sur <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5d7aacffce2c6032c3ae9ef4d1b3847a926440b" datatype="html">
+ <source>D has to be greater than k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>).</source>
+ <target>D doit être supérieur à k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fd745d614884edc23c7ac9ad8aba9655f3793ac2" datatype="html">
+ <source>D has to be lower than k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>).</source>
+ <target>D doit être inférieur à k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">199</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af668c2a095a979ea2b4e43cd82c2120ab56c21c" datatype="html">
+ <source>Locality (l)</source>
+ <target>Localité (l)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="200fea08b63ae8d60cdbf33ffd2636159e87dc1e" datatype="html">
+ <source>Can't split up chunks (k+m) correctly with the current locality.</source>
+ <target>Impossible de répartir correctement les blocs (k+m) avec la localité actuelle.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319ac5d692d11da686782159bd70e0b705c228ed" datatype="html">
+ <source>Locality groups: <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></source>
+ <target>Groupes de localité : <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">230</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d455a110bf6d2235e314e295ce1dfeee93d3dff2" datatype="html">
+ <source>Crush failure domain</source>
+ <target>Domaine de défaillance Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74a495f041f7dd102eee5c0bbc9e03083b538ae" datatype="html">
+ <source>Crush Locality</source>
+ <target>Localité Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2f14a73f7a6e94479f67423cc51102da8d6f524" datatype="html">
+ <source>None</source>
+ <target>Aucun</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="363a99d62822b92913a4cce196d47f32c1258e2f" datatype="html">
+ <source>Scalar mds</source>
+ <target>MDS scalaire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2981733b912b693a9dd9d915d6d34f4692cc874a" datatype="html">
+ <source>Technique</source>
+ <target>Technique</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0098b6e47b04ec817361f384ce81d454ba5c0bb" datatype="html">
+ <source>Packetsize</source>
+ <target>Taille de paquet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0252cd81ca54d0a2f69ec9ccf4248e73df5aa4a" datatype="html">
+ <source>Crush root</source>
+ <target>Racine Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">351</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1548d5c76f0406ddd1ba3c557e1e6db22e95b340" datatype="html">
+ <source>Crush device class</source>
+ <target>Classe de périphérique Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3f657ffa19dc6ac504b83c86209709522dcf065" datatype="html">
+ <source>Available OSDs: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></source>
+ <target>OSD disponibles : <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03d84645f6e019c5a43909bbf2ea1696ee88332c" datatype="html">
+ <source>Directory</source>
+ <target>Répertoire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1354845268685595937" datatype="html">
+ <source>EC Profile</source>
+ <target>Profil du code d'effacement</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3938a411d76796f8ae73b72ea4c77661207453bd" datatype="html">
+ <source>Cache Tiers Details</source>
+ <target>Détails des niveaux de mise en cache</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="991790413700941336" datatype="html">
+ <source>Cache Mode</source>
+ <target>Mode cache</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9133265273798382582" datatype="html">
+ <source>Min Evict Age</source>
+ <target>Âge min. évinc.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7172092927403263656" datatype="html">
+ <source>Min Flush Age</source>
+ <target>Âge vidage min.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8096695869347792608" datatype="html">
+ <source>Target Max Bytes</source>
+ <target>Nombre max d'octets cibles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8854126142886240282" datatype="html">
+ <source>Target Max Objects</source>
+ <target>Nombre max. d'objets cibles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617215542453015899" datatype="html">
+ <source>No applications added</source>
+ <target>Aucune application ajoutée</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4895689494338215646" datatype="html">
+ <source>Applications limit reached</source>
+ <target>Limite d'applications atteinte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7322343326526084293" datatype="html">
+ <source>A pool can only have up to four applications definitions.</source>
+ <target>Une réserve peut avoir quatre définitions d'application maximum.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1393735257943344790" datatype="html">
+ <source>Allowed characters '_a-zA-Z0-9'</source>
+ <target>Caractères autorisés '_a-zA-Z0-9'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5520683885127790121" datatype="html">
+ <source>Maximum length is 128 characters</source>
+ <target>La longueur maximale est de 128 caractères.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587418377972855060" datatype="html">
+ <source>Filter or add applications'</source>
+ <target>Filtrer ou ajouter des applications'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5188881899285829380" datatype="html">
+ <source>Add application</source>
+ <target>Ajouter une application</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16e113230b6b0d3165e076300880542bac7c8138" datatype="html">
+ <source>The chosen Ceph pool name is already in use.</source>
+ <target>Le nom de réserve Ceph sélectionné est déjà utilisé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c75b132bef7b29fa5171768303c4b96e34ccaf68" datatype="html">
+ <source>It's not possible to create an RBD pool with '/' in the name. Please change the name or remove 'rbd' from the applications list.</source>
+ <target>Il n'est pas possible de créer une réserve RBD dont le nom contient '/'. Veuillez modifier son nom ou supprimer 'rbd' de la liste des applications.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">34,35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="171dc6d5c6bc4615d99778b0088cae80fd00bd10" datatype="html">
+ <source>Pool name can only contain letters, numbers, '.', '-', '_' or '/'.</source>
+ <target>Le nom de la réserve ne peut contenir que des lettres, des chiffres, '.', '-', '_' ou '/'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b85c657469e5ec8231c3de99b22f437bc01ffde5" datatype="html">
+ <source>Pool type</source>
+ <target>Type de réserve</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="526c5443254c3b126eedb264840ffe827727bfd3" datatype="html">
+ <source>-- Select a pool type --</source>
+ <target>-- Sélectionner un type de réserve --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abfbe47b630929d93c7343dc154599c2e59330a" datatype="html">
+ <source>PG Autoscale</source>
+ <target>Mise à l’échelle automatique des groupes de placements</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0aa21053410a94aa61d16985a4e95fd65523430d" datatype="html">
+ <source>Placement groups</source>
+ <target>Groupes de placements</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6301f1391d726f8f450bb358058534db19541ca9" datatype="html">
+ <source>At least one placement group is needed!</source>
+ <target>Au moins un groupe de placements est nécessaire.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba9469a1ce6ed36e039c1f67247c8c81a5c71449" datatype="html">
+ <source>Your cluster can't handle this many PGs. Please recalculate the PG amount needed.</source>
+ <target>Votre grappe ne peut pas gérer autant de groupes de placements. Veuillez recalculer le nombre de groupes de placements nécessaires.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80ac68cd883369dac20688bc32b4cb33291b5e50" datatype="html">
+ <source>Calculation help</source>
+ <target>Aide au calcul</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fccbd60493df26705d957ed6c02a3c447894678f" datatype="html">
+ <source>The current PGs settings were calculated for you, you should make sure the values suit your needs before submit.</source>
+ <target>Les paramètres actuels des groupes de placement ont été calculés pour vous. Vous devez vérifier que les valeurs correspondent à vos besoins avant de les soumettre.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">116,117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a43b2695131b48b76cebba676aba98a2bee17515" datatype="html">
+ <source>Replicated size</source>
+ <target>Taille de réplication</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bff144a4c4dc63b0e18fff2617d61a7ebdf2b6c" datatype="html">
+ <source>Minimum: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></source>
+ <target>Minimum : <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9c54b41f6d58a74e5d0aa3429ed0c87a482551" datatype="html">
+ <source>Maximum: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></source>
+ <target>Maximum : <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="452cf71ec44ee77428656936a6627eaf2dd3b47f" datatype="html">
+ <source>The size specified is out of range. A value from <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> to <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/> is usable.</source>
+ <target>La taille spécifiée se trouve en dehors de la plage. Vous devez utiliser une valeur comprise entre <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> et <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">144,145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dda6196ffab88c1825f44a565c7b34e246e7e12f" datatype="html">
+ <source>A size of 1 will not create a replication of the object. The 'Replicated size' includes the object itself.</source>
+ <target>Une taille de 1 ne créera pas de réplication de l'objet. La 'taille répliquée' comprend l'objet proprement dit.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">148,149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c870fb00256b8a5b9cb9cd1a124e6390b9bc639" datatype="html">
+ <source>EC Overwrites</source>
+ <target>Écrasements de code d'effacement</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f1abafaeb40ce52355ddcc24686e3cd17b64e08a" datatype="html">
+ <source>Applications</source>
+ <target>Applications</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9308b82fc183f710df60909f49cfc73aa5e076" datatype="html">
+ <source>CRUSH</source>
+ <target>CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9de7dde00e2139cc4bd03b1837afbe72ad15a1ff" datatype="html">
+ <source>Erasure code profile</source>
+ <target>Profil de code d'effacement</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39b4620e6bd444e0a57a0a5c03fa8c96d7fe5235" datatype="html">
+ <source>-- No erasure code profile available --</source>
+ <target>-- Aucun profil de code d'effacement n'est disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498561757390d5528b263ce450d5f38efb00266d" datatype="html">
+ <source>-- Select an erasure code profile --</source>
+ <target>-- Sélectionner un profil de code d'effacement --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="616a2532fbaace94934f5943e381b63e2623f004" datatype="html">
+ <source>This profile can't be deleted as it is in use.</source>
+ <target>Ce profil ne peut pas être supprimé, car il est en cours d'utilisation.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="994363f08f9fbfa3b3994ff7b35c6904fdff18d8" datatype="html">
+ <source>Profile</source>
+ <target>Profil</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="023d6f718770d2ea4ab8cabe26b0ec27ef967ec2" datatype="html">
+ <source>Used by pools</source>
+ <target>Utilisé par les réserves</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">387</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1061ba5ee07a5c6af09e09330dbc29201baf2aa" datatype="html">
+ <source>Profile is not in use.</source>
+ <target>Le profil n'est pas en cours d'utilisation.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33150f22ce5348aa6c499bd092c3f4f3695d62cc" datatype="html">
+ <source>Crush ruleset</source>
+ <target>Jeu de règles Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">293</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">303</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c69b0bcd4698aa845d32c4c4ad488492552cb469" datatype="html">
+ <source>A new crush ruleset will be implicitly created.</source>
+ <target>Un nouveau jeu de règles Crush sera créé implicitement.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="896e9987db5e9bb279e6deed5d2dff28c242ef66" datatype="html">
+ <source>There are no rules.</source>
+ <target>Il n'y a pas de règles.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73a6b31116b3cc322af951daa0bafdc169e6c42e" datatype="html">
+ <source>-- Select a crush rule --</source>
+ <target>-- Sélectionner une règle Crush --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7d4894e770f8853050b1f6dd55bdd77a51a8ac6" datatype="html">
+ <source>Placement and
+ replication strategies or distribution policies that allow to
+ specify how CRUSH places data replicas.</source>
+ <target>Stratégies de placement et
+de réplication ou politiques de distribution qui permettent de
+spécifier comment CRUSH place les répliques de données.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">328,330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea91d648f92002bc9f96d9b26b735c83ca0b53c6" datatype="html">
+ <source>This rule can't be deleted as it is in use.</source>
+ <target>Cette règle ne peut pas être supprimée, car elle est en cours d'utilisation.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">346</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92da80699921e89fb19372e25b8d0f3b9fa427fc" datatype="html">
+ <source>Crush rule</source>
+ <target>Règle Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">365</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5489e9f96835f469f6f728a00d8efa88ea5bc940" datatype="html">
+ <source>Crush steps</source>
+ <target>Étapes Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc5f5496a9e50fe69e1a09784f28d94944108294" datatype="html">
+ <source>Rule is not in use.</source>
+ <target>La règle n'est pas en cours d'utilisation.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="104a0e6900d1d1b0c8cf9e5947e36edb352583fc" datatype="html">
+ <source>The rule can't be used in the current cluster as it has too few OSDs to meet the minimum required OSD by this rule.</source>
+ <target>La règle ne peut pas être utilisée dans la grappe actuelle, car elle contient un nombre d'OSD inférieur au minimum requis par cette règle.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">409,410</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2208d63d5940ce656006a220102b1eb2b5e553da" datatype="html">
+ <source>Compression</source>
+ <target>Compression</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">420</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c6f25c47da62ec597c6057a36ddfc3209811ec5" datatype="html">
+ <source>Algorithm</source>
+ <target>Algorithme</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">444</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4903231d42089325a28892c0fde1aed46b733ae6" datatype="html">
+ <source>-- No erasure compression algorithm available --</source>
+ <target>-- Aucun algorithme de compression d'effacement n'est disponible --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d68ddb254275f8f44221e9ad6d8ceeb59ca46a6" datatype="html">
+ <source>Minimum blob size</source>
+ <target>Taille de blob minimale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">468</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb2f176df80647137cbb02bbeb29e5dec707a400" datatype="html">
+ <source>e.g., 128KiB</source>
+ <target>par ex. 128 Kio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">477</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b7f6e53a4521c6eb3ced4c007fdd4cf80bb7707" datatype="html">
+ <source>Value should be greater than 0</source>
+ <target>La valeur doit être supérieure à 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">482</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">506</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8db98ab14b4e207ec763dfdefbc2dae367aab1cc" datatype="html">
+ <source>Value should be less than the maximum blob size</source>
+ <target>La valeur doit être inférieure à la taille de blob maximale.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151efb127a9a4dd25259a0b2055442318a141f5b" datatype="html">
+ <source>Maximum blob size</source>
+ <target>Taille de blob maximale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c656f0e346bbadf46eb1a5d20d0307a3bd20ba8" datatype="html">
+ <source>e.g., 512KiB</source>
+ <target>par ex., 512 Kio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65a24eee8a026f3b1113fe9e157e9a0dd69486" datatype="html">
+ <source>Value should be greater than the minimum blob size</source>
+ <target>La valeur doit être supérieure à la taille de blob minimale.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">509</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="261ba09c4a59de83f48f52a23fd328da37e61ff4" datatype="html">
+ <source>Ratio</source>
+ <target>Rapport</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">517</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1430457a9c3c66366e51d76bf10396014c576be" datatype="html">
+ <source>Compression ratio</source>
+ <target>Rapport de compression</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">528</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae5ce6de352cde949998fb10754459c3a4eb183b" datatype="html">
+ <source>Value should be between 0.0 and 1.0</source>
+ <target>La valeur doit se situer entre 0,0 et 1,0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d99b34162c9c34f10d0ccd8dbae83d8569c2db77" datatype="html">
+ <source>Max bytes</source>
+ <target>Nombre max. d'octets</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">546</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1d14a18879c62f3f4ed705318b7164a1160e249" datatype="html">
+ <source>Leave it blank or specify 0 to disable this quota.</source>
+ <target>Laissez le champ vide ou indiquez 0 pour désactiver ce quota.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">572</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7565b131562ff6c5f769fdbd239a772154abdd97" datatype="html">
+ <source>A valid quota should be greater than 0.</source>
+ <target>Un quota valide doit être supérieur à 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">550</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">574</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b8bf35b66f09a301eef92ffc3cb2fd259df67ce9" datatype="html">
+ <source>Max objects</source>
+ <target>Nombre max. d'objets</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">570</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="95f348167622d832c5ae532b6944635c8e2ae5cb" datatype="html">
+ <source>The value should be greater or equal to 0</source>
+ <target>La valeur doit être supérieure ou égale à 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">586</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1088629182722162774" datatype="html">
+ <source>pool</source>
+ <target>réserve</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6215593782779198370" datatype="html">
+ <source>erasure code profile</source>
+ <target>profil de code d'effacement</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4390273881304618317" datatype="html">
+ <source>crush rule</source>
+ <target>règle Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">721</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d8a7c8aea58294a3c57c23af0468ddf0ba0c9c7" datatype="html">
+ <source>Pools List</source>
+ <target>Liste des réserves</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9055665654201606988" datatype="html">
+ <source>Data Protection</source>
+ <target>Protection des données</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6658000829978978023" datatype="html">
+ <source>Applications</source>
+ <target>Applications</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5232365108332422324" datatype="html">
+ <source>PG Status</source>
+ <target>Statut du groupe de placements</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1669788723782899084" datatype="html">
+ <source>Crush Ruleset</source>
+ <target>Jeu de règles Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7961062124768120122" datatype="html">
+ <source>Pool deletion is disabled by the mon_allow_pool_delete configuration setting.</source>
+ <target>La suppression de réserve est désactivée par le paramètre de configuration mon_allow_pool_delete. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee5132a8da30e0b7f9f5c70dbc91928d17dd909" datatype="html">
+ <source>Owner</source>
+ <target>Propriétaire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c51963a9c553b29427ef783bbb69fa6634fa8c" datatype="html">
+ <source>Index type</source>
+ <target>Type d'index</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e6f950a32eaea32ec7e192f9ca3d3dfe469d4ba" datatype="html">
+ <source>Placement rule</source>
+ <target>Règle de placement</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6972d213e31c4ea4f887e60db99d9881bc8fcd3e" datatype="html">
+ <source>Marker</source>
+ <target>Marqueur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47b02acd2d3254d1ace1926f840523f154ebef71" datatype="html">
+ <source>Maximum marker</source>
+ <target>Marqueur maximum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="092fa3a7df9168b14d3f83a77a4035e92b92ce15" datatype="html">
+ <source>Master version</source>
+ <target>Version principale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97434cc5001d407f90c7447a12d9e8e6848a2aa3" datatype="html">
+ <source>Modification time</source>
+ <target>Date de modification</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90fe2e41e7fde38453ce4e619efeea9bc6adea9c" datatype="html">
+ <source>Zonegroup</source>
+ <target>Groupe de zones</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="efeade5060b3add63863c24871f0830fb16b7e6d" datatype="html">
+ <source>Versioning</source>
+ <target>Contrôle des versions</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62a923f047ca49e7a4782629e91fea1ba32db68f" datatype="html">
+ <source>MFA Delete</source>
+ <target>Suppression MFA</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="649a410bd0ace333d067d8fa22f12bdbdb43533b" datatype="html">
+ <source>Bucket quota</source>
+ <target>Quota de compartiments</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">567</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f50a33d3c339f8f4a465141f8caa5d2d8c005251" datatype="html">
+ <source>Enabled</source>
+ <target>Activé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">579</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cef1595d040e77cbb4466e60382028d4c2040cac" datatype="html">
+ <source>Maximum size</source>
+ <target>Taille maximale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa6fb95c355f172bda303de1ce2f38c251a149cf" datatype="html">
+ <source>Unlimited</source>
+ <target>Illimité</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee862a800364b4d11f9b8cb9955a28a60f840a45" datatype="html">
+ <source>Maximum objects</source>
+ <target>Nombre maximal d'objets</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b84370895ab9eb44672f57146fa05c5947f1c0c" datatype="html">
+ <source>Locking</source>
+ <target>Verrouillage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c3d9d2296f7886e8289b9f623323803deacfc6" datatype="html">
+ <source>Days</source>
+ <target>Jours</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f44bdf9ab00a973bbe482e9fc450e3f67e60c0d" datatype="html">
+ <source>Bucket names can only contain lowercase letters, numbers, periods and hyphens.</source>
+ <target>Les noms de compartiments ne peuvent contenir que des minuscules, des chiffres, des points et des traits d'union.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eabb4db920d9f9b2480cf438468b86e1bea02a9b" datatype="html">
+ <source>The chosen name is already in use.</source>
+ <target>Le nom sélectionné est déjà en cours d'utilisation.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b06de7f834c622197e68b66a2abe893040b174c4" datatype="html">
+ <source>Bucket names must not contain uppercase characters or underscores.</source>
+ <target>Les noms de compartiments ne doivent pas contenir de majuscules ni de caractères de soulignement.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abacf4af2f66d3af08c5ebe502b21b1f42ac649" datatype="html">
+ <source>Each label must start and end with a lowercase letter or a number.</source>
+ <target>Chaque libellé doit commencer et se terminer par une minuscule ou un chiffre.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a7f52e6813e0535026f61a2d6e8adc8a1d006a" datatype="html">
+ <source>Bucket names cannot be formatted as IP address.</source>
+ <target>Les noms de compartiments ne peuvent pas avoir le format d'une adresse IP.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2a2460396d35e14e7acfb4e060196a0679bdcff" datatype="html">
+ <source>Bucket labels cannot be empty and can only contain lowercase letters, numbers and hyphens.</source>
+ <target>Les étiquettes des compartiments ne peuvent pas être vides et ne peuvent contenir que des minuscules, des chiffres et des traits d'union.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf5c849977e0be2dbfc862d044edd323bfd9fb77" datatype="html">
+ <source>Bucket names must be 3 to 63 characters long.</source>
+ <target>Les noms de compartiments doivent être compris entre 3 et 63 caractères.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e4c918357c7445fbf19a203e5f0f0ece1960b3b" datatype="html">
+ <source>-- Select a user --</source>
+ <target>-- Sélectionner un utilisateur --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4aab1f837bc8ec222e4f25922465d1c5929a1fc" datatype="html">
+ <source>Placement target</source>
+ <target>Cible de placement</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bae0a7fc2c9c1fde7d937a8a1a3c7e6825cf7d1" datatype="html">
+ <source>-- Select a placement target --</source>
+ <target>-- Sélectionner une cible de placement --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="016d24e069e7d505a090fb8243e5cd43b35dc39b" datatype="html">
+ <source>Enables versioning for the objects in the bucket.</source>
+ <target>Active le contrôle des versions pour les objets du compartiment.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">151</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e6775ffd06878aa145c07359f28557f01ede04f" datatype="html">
+ <source>Multi-Factor Authentication</source>
+ <target>Authentification multi-critères</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29e8a5d4fb767d4ad0c762c81c6264cec4c0ba97" datatype="html">
+ <source>Delete enabled</source>
+ <target>Suppression activée</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40fbc3ac8c1ea4ecfe62247e91f1f999ad5baf76" datatype="html">
+ <source>Enables MFA (multi-factor authentication) Delete, which requires additional authentication for changing the bucket versioning state.</source>
+ <target>Active la suppression MFA (authentification multi-critères), qui nécessite une authentification supplémentaire pour modifier l'état du contrôle des versions du compartiment.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24c93a8c13db46defa06ed7b5e026a3edb52b91" datatype="html">
+ <source>Token Serial Number</source>
+ <target>Numéro de série du jeton</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6d9536c2af2e5e9a228c3e3e1809dc1fefe0149" datatype="html">
+ <source>Token PIN</source>
+ <target>Code PIN du jeton</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f038d51ab1645f15b0cd58f195c72a7eeebd4729" datatype="html">
+ <source>Enables locking for the objects in the bucket. Locking can only be enabled while creating a bucket.</source>
+ <target>Active le verrouillage pour les objets du compartiment. Le verrouillage peut uniquement être activé lors de la création d'un compartiment.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9af1b4baa2dd8ed2bfc3cc756b12a2271c2dd793" datatype="html">
+ <source>Compliance</source>
+ <target>Conformité</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="edd600fa489d1b4a4448dce694ed932e52ce8fda" datatype="html">
+ <source>Governance</source>
+ <target>Gouvernance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="218c7d6d318c51e7105309aaeb0baec9d19e4efb" datatype="html">
+ <source>The number of days that you want to specify for the default retention period that will be applied to new objects placed in this bucket.</source>
+ <target>Nombre de jours que vous souhaitez spécifier pour la période de conservation par défaut à appliquer aux nouveaux objets placés dans ce compartiment.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">264</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="289b101ec12427b3ca819df9e43cc3b14fae2cc4" datatype="html">
+ <source>The entered value must be a positive integer.</source>
+ <target>La valeur entrée doit être un entier positif.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48d8247c1ba2ea156109bf286c5f6dd26b4be760" datatype="html">
+ <source>Retention Days must be a positive integer.</source>
+ <target>Le nombre de jours de conservation doit être un entier positif.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4349284625269221231" datatype="html">
+ <source>bucket</source>
+ <target>compartiment</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6161088322338624846" datatype="html">
+ <source>Updated Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'.</source>
+ <target>Compartiment Object Gateway '<x id="PH" equiv-text="values.bid"/>' mis à jour.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218632328857697292" datatype="html">
+ <source>Created Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'</source>
+ <target>Compartiment Object Gateway '<x id="PH" equiv-text="values.bid"/>' créé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c338bae89822d7eefbc9a887c458a7d8a98e55e" datatype="html">
+ <source>No Limit</source>
+ <target>Aucune limite</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3715596725146409911" datatype="html">
+ <source>Owner</source>
+ <target>Propriétaire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5545511293826600258" datatype="html">
+ <source>Used Capacity</source>
+ <target>Capacité utilisée</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1925090152473969054" datatype="html">
+ <source>Capacity Limit %</source>
+ <target>% limite de capacité</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8713861779825116442" datatype="html">
+ <source>Object Limit %</source>
+ <target>% limite d'objet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5913880066213114620" datatype="html">
+ <source>buckets</source>
+ <target>compartiments</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eeba399c4dae8d4890c27b7a2cd2dc28fcf8b5f9" datatype="html">
+ <source>Performance Counters</source>
+ <target>Compteurs de performance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="479488ab6e91ecb375484edc78bee3d13467f33f" datatype="html">
+ <source>Daemons List</source>
+ <target>Liste de daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca2dee83bb58290d93fb0d17ee8bc9f095a4576f" datatype="html">
+ <source>Sync Performance</source>
+ <target>Performance de synchronisation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4378147649219625174" datatype="html">
+ <source>Zone</source>
+ <target>Zone</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6148052126949932311" datatype="html">
+ <source>Zone Group</source>
+ <target>Groupe de zone</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3840481991104643295" datatype="html">
+ <source>Realm</source>
+ <target>Domaine</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1221ca97d19eaa9a7bc0c5243d5fc5befe1d2314" datatype="html">
+ <source>-- Select a type --</source>
+ <target>-- Sélectionner un type --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1b8990332af18f1c5159a6061ca889bcbb28432" datatype="html">
+ <source>Permission</source>
+ <target>Autorisation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a08c589f82f69d892307288da14190ae1dd583d5" datatype="html">
+ <source>-- Select a permission --</source>
+ <target>-- Sélectionner une autorisation --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7345972049922682356" datatype="html">
+ <source>capability</source>
+ <target>fonctionnalité</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a94e6b2b5b834d92cceb90037d51ad6165c8b619" datatype="html">
+ <source>Tenant</source>
+ <target>Locataire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
+ <source>User ID</source>
+ <target>ID utilisateur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b760f123248930122fc7e7b6b6bf94e376e959c8" datatype="html">
+ <source>Full name</source>
+ <target>Nom complet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69b6ac577a19acc39fc0c22342092f327fff2529" datatype="html">
+ <source>Email address</source>
+ <target>Adresse électronique</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92f3f203270a29b3001871153f02c063484a1574" datatype="html">
+ <source>Suspended</source>
+ <target>Suspendu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011e20c5bbe51602d459a860fbf29b599b55edd" datatype="html">
+ <source>System</source>
+ <target>Système</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db18a2772988415466a7f75dc42663ce78c9c1d3" datatype="html">
+ <source>Maximum buckets</source>
+ <target>Nombre maximal de compartiments</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c4c62e8ba24601be5cfe7dc5d32c24bbbd4b53c" datatype="html">
+ <source>Subusers</source>
+ <target>Utilisateurs secondaires</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17bb3082e6fe5003203ef992a3714172334631a1" datatype="html">
+ <source>Capabilities</source>
+ <target>Fonctionnalités</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32f8a0570373cacb9c56cf227502483a29d605bc" datatype="html">
+ <source>MFAs(Id)</source>
+ <target>MFA (ID)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36ad38f9c1a1485e09b67778a28af84553290ffb" datatype="html">
+ <source>User quota</source>
+ <target>Quota utilisateur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">473</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0bcd5ef19af0f1b814141ca8c57df623d8270088" datatype="html">
+ <source>Keys</source>
+ <target>Clés</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2aba1e87039819aca3b70faa9aa848c12bf139ca" datatype="html">
+ <source>Show</source>
+ <target>Afficher</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">395</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5248717555542428023" datatype="html">
+ <source>Username</source>
+ <target>Nom d'utilisateur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240806681889331244" datatype="html">
+ <source>Unlimited</source>
+ <target>Illimité</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db4e1a734518691b128ef40b939cc673f01d03a6" datatype="html">
+ <source>The value is not valid.</source>
+ <target>La valeur n'est pas valide.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">617</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6aaf5d2a304167272ac73e3b1d1c162e16c77858" datatype="html">
+ <source>The chosen user ID is already in use.</source>
+ <target>L'ID utilisateur spécifié est déjà utilisé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="025be1d01b2f6cbd09e772a1d3de02fab0678b26" datatype="html">
+ <source>Show Tenant</source>
+ <target>Afficher le locataire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6af106b0d759fd2882e645604675c4494abfcd5b" datatype="html">
+ <source>The chosen user ID exists in this tenant.</source>
+ <target>L'ID utilisateur choisi existe dans ce locataire.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="df441e80db2157f9d272b75de724ba4a82b96b57" datatype="html">
+ <source>This is not a valid email address.</source>
+ <target>Ceci n'est pas une adresse électronique valide.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca271adf154956b8fcb28f4f50a37acb3057ff7c" datatype="html">
+ <source>The chosen email address is already in use.</source>
+ <target>L'adresse électronique spécifiée est déjà utilisée.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="030197cebe938edf35422e92fe14183d06eb670b" datatype="html">
+ <source>Max. buckets</source>
+ <target>Nombre max. de compartiments</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f39256070bfc0714020dfee08895421fc1527014" datatype="html">
+ <source>Disabled</source>
+ <target>Désactivé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c05002b0ac2040f1aede5e727e0ffd06eda819" datatype="html">
+ <source>Custom</source>
+ <target>Personnalisé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28872515cb81d197a3a1733fa546d3e0f0dd6c67" datatype="html">
+ <source>The entered value must be &gt;= 1.</source>
+ <target>La valeur entrée doit être &gt;= 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="583a219c524155c2314eb06ee29162bb315272a3" datatype="html">
+ <source>S3 key</source>
+ <target>Clé S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c217ee914725a37e9dd2336c721c8e63e9666bdc" datatype="html">
+ <source>Auto-generate key</source>
+ <target>Générer automatiquement la clé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f1c1c0f2bce4c9f92d1a2061e8161cb0006c31a" datatype="html">
+ <source>Access key</source>
+ <target>Clé d'accès</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b864acb67296a9819c1db0069c4c47d8b5ce8f44" datatype="html">
+ <source>Secret key</source>
+ <target>Clé secrète</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="128d6efb51d9ddc7c0cc695a2deeca5b9523f6e4" datatype="html">
+ <source>There are no subusers.</source>
+ <target>Il n'y a aucun utilisateur secondaire.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fd6dfb8ecb982dbc3affb2c2d5414c4f5b6abd2" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">294,295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67c746c1ba9dab4351fedc4c7cba4e6d6b0dbc47" datatype="html">
+ <source>S3</source>
+ <target>S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d6819038d608623503918fb2553f53d68231ec3a" datatype="html">
+ <source>There are no keys.</source>
+ <target>Il n'y a pas de clé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">377</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc1c1a7140ff6b815a95b65ee2780fdbe1b2b7a1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">356,357</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6ddb5e991a3ecd2659fb520bc5acc81b67e08ddd" datatype="html">
+ <source>Swift</source>
+ <target>Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">371</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d01eccdda47fc907c5be35bcb16d2dcd02b0270" datatype="html">
+ <source>There are no capabilities.</source>
+ <target>Il n'y a aucune fonctionnalité.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5a451c4ea65a4046f0b49d489a7013abf0b5861" datatype="html">
+ <source>All capabilities are already added.</source>
+ <target>Toutes les fonctionnalités ont déjà été ajoutées.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">456</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="043e2ec0036ceadd926fd5e3f93cd6f3565f3648" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">461,462</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6146e13ceca5fa5cc17b771b282fe5955f3d19fa" datatype="html">
+ <source>Unlimited size</source>
+ <target>Taille illimitée</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">595</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6db8aa7c99fdce18edb33dde57729acede2b308" datatype="html">
+ <source>Max. size</source>
+ <target>Taille max.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">511</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">605</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc630b2093e880fffa19df99d5cd8b87605037f8" datatype="html">
+ <source>Unlimited objects</source>
+ <target>Objets illimités</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cda5a993d06f0bb10048be9d3aba6555aa9f356" datatype="html">
+ <source>Max. objects</source>
+ <target>Nombre max. d'objets</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">642</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="623ac50f37a26caec6fd7cd519b653e3315cba25" datatype="html">
+ <source>The entered value must be &gt;= 0.</source>
+ <target>La valeur saisie doit être &gt;= 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">654</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="123010868147850959" datatype="html">
+ <source>user</source>
+ <target>utilisateur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8368421344177343441" datatype="html">
+ <source>subuser</source>
+ <target>utilisateur secondaire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4662015204945271252" datatype="html">
+ <source>S3 Key</source>
+ <target>Clé S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9103468069826049692" datatype="html">
+ <source>Updated Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <target>Utilisateur Object Gateway '<x id="PH" equiv-text="uid"/>' mis à jour.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="884841609901737584" datatype="html">
+ <source>Created Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <target>Utilisateur Object Gateway '<x id="PH" equiv-text="uid"/>' créé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4363143805416924501" datatype="html">
+ <source>Tenant</source>
+ <target>Locataire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8301535046747035390" datatype="html">
+ <source>Full name</source>
+ <target>Nom complet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3967269098753656610" datatype="html">
+ <source>Email address</source>
+ <target>Adresse électronique</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5851424994801012357" datatype="html">
+ <source>Suspended</source>
+ <target>Suspendu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208300173682032371" datatype="html">
+ <source>Max. buckets</source>
+ <target>Nombre max. de compartiments</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1670306451865226564" datatype="html">
+ <source>users</source>
+ <target>utilisateurs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c614babd1950adb2be75df4e2c9747286d6adc" datatype="html">
+ <source>-- Select a username --</source>
+ <target>-- Sélectionner un nom d'utilisateur --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2841767821d6b66238c34d07e413b0af67aee92" datatype="html">
+ <source>Subuser</source>
+ <target>Utilisateur secondaire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd59fc25a7bd98cff3e75117c09697c8a007a514" datatype="html">
+ <source>The chosen subuser ID is already in use.</source>
+ <target>L'ID d'utilisateur secondaire sélectionné est déjà utilisé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d386c357ebcbc04ed05c4babd5a03626f9b1674" datatype="html">
+ <source>read, write</source>
+ <target>lire, écrire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84e3e3f9a4f31a039b648c97debf95fcb20f4c4a" datatype="html">
+ <source>full</source>
+ <target>complet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6bf81d032a2316464f9df2f0d2f3d753f89f0d3" datatype="html">
+ <source>Swift key</source>
+ <target>Clé Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e0c12685d50d47448ceed9423977ef39775c037" datatype="html">
+ <source>Auto-generate secret</source>
+ <target>Générer automatiquement le secret</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5091031285775138345" datatype="html">
+ <source>Subuser</source>
+ <target>Utilisateur secondaire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8453697749389230205" datatype="html">
+ <source>Swift Key</source>
+ <target>Clé Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ac54c18c1b520e948095c83a3a1025f02ce6dcc6" datatype="html">
+ <source>Neither hostname nor OSD ID given</source>
+ <target>Ni le nom d'hôte ni l'ID OSD ne sont indiqués.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4533150758393178756" datatype="html">
+ <source>Device ID</source>
+ <target>ID du périphérique</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1291053608320944146" datatype="html">
+ <source>State of Health</source>
+ <target>État de santé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29167121133682512" datatype="html">
+ <source>Good</source>
+ <target>Bon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8767957606064036733" datatype="html">
+ <source>Bad</source>
+ <target>Mauvais</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8052456228079338924" datatype="html">
+ <source>Stale</source>
+ <target>Obsolète</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6223439643831041743" datatype="html">
+ <source>Life Expectancy</source>
+ <target>Espérance de vie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3144481541623761279" datatype="html">
+ <source>Prediction Creation Date</source>
+ <target>Date de création de la prédiction</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="264574868375698540" datatype="html">
+ <source>Device Name</source>
+ <target>Nom du périphérique</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1419569261746199221" datatype="html">
+ <source>Daemons</source>
+ <target>Daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f635b3cb0600409a2ad44a5bd1863c699e6a01c" datatype="html">
+ <source>Failed to retrieve SMART data.</source>
+ <target>Échec de récupération des données SMART.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a8a3f354bd640299068edd912f4bb5325264f250" datatype="html">
+ <source>The data received has the JSON format version 2.x and is currently incompatible with the dashboard.</source>
+ <target>Les données reçues sont au format JSON version 2.x et ne sont actuellement pas prises en charge par le tableau de bord.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="04f8a3c7e8ac610e6581960162cc15f55a16696a" datatype="html">
+ <source>No SMART data available.</source>
+ <target>Aucune donnée SMART n'est disponible.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a185c9b97513b3882604ea9bab60edbfac945c15" datatype="html">
+ <source>SMART overall-health self-assessment test result</source>
+ <target>résultat du test d'auto-évaluation de santé globale SMART</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="290e4c9ad42dc6e9176656c864a5faed8053f406" datatype="html">
+ <source>unknown</source>
+ <target>inconnu(e)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a03d3c2e459f8f8fa7202c0fce465d6165f9e2b" datatype="html">
+ <source>passed</source>
+ <target>réussite</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41435d5a5692c8e412c74deaee95d99dbd3617e1" datatype="html">
+ <source>failed</source>
+ <target>échec</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddd5dd6d930030096ea617f62c82b648a0dd9484" datatype="html">
+ <source>Device Information</source>
+ <target>Informations sur le périphérique</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e149c483d88cfcff11d1c5db85e84af7c3149c4" datatype="html">
+ <source>No device information available for this device.</source>
+ <target>Aucune information n'est disponible pour ce périphérique.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20cb12827cbe559a7b1da6fdae96041b3b5c3c55" datatype="html">
+ <source>SMART</source>
+ <target>SMART</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380295f37caea93701d071485a38ef0bdba57133" datatype="html">
+ <source>No SMART data available for this device.</source>
+ <target>Aucune donnée SMART n'est disponible pour ce périphérique.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5758c3f16f8749f0f4e2a787f02e8b4da246102f" datatype="html">
+ <source>SMART data is loading.</source>
+ <target>Les données SMART sont en cours de chargement.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5363861031080361352" datatype="html">
+ <source>Smartctl has received an unknown argument (error code <x id="PH" equiv-text="smartData.smartctl_error_code"/>). You may be using an incompatible version of smartmontools. Version &gt;= 7.0 of smartmontools is required to successfully retrieve data.</source>
+ <target>Smartctl a reçu un argument inconnu (code d'erreur <x id="PH" equiv-text="smartData.smartctl_error_code"/>). Vous utilisez peut-être une version incompatible de smartmontools. La version &amp;gt;= 7.0 de smartmontools est nécessaire pour pouvoir récupérer les données.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">61,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5085718566932809950" datatype="html">
+ <source>An error with error code <x id="PH" equiv-text="smartData.smartctl_error_code"/> occurred.</source>
+ <target>Une erreur s'est produite avec le code d'erreur <x id="PH" equiv-text="smartData.smartctl_error_code"/> .</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2091295268977103253" datatype="html">
+ <source>Raw</source>
+ <target>Brut</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5963653123239768443" datatype="html">
+ <source>Threshold</source>
+ <target>Seuil</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2893124970059125090" datatype="html">
+ <source>When Failed</source>
+ <target>En cas d'échec</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5614367840516299633" datatype="html">
+ <source>Worst</source>
+ <target>Pire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d06ae77f9ec46a4cdd49e7e76c73a411aaf2ee38" datatype="html">
+ <source>Please set a new password.</source>
+ <target>Veuillez définir un nouveau mot de passe.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8b5b3566e88438f51bd5f6caf6c090ed565ba5ed" datatype="html">
+ <source>You will be redirected to the login page afterwards.</source>
+ <target>Vous serez ensuite redirigé vers la page de connexion.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cf42e491adc166a337a960eb84d03c0c3f677c8" datatype="html">
+ <source>The old and new passwords must be different.</source>
+ <target>L'ancien et le nouveau mot de passe doivent être différents.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90163a3d3746819aef42e829f4446331232f3b66" datatype="html">
+ <source>Password confirmation doesn't match the new password.</source>
+ <target>Le mot de passe de confirmation ne correspond pas au nouveau mot de passe.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0070e83d11da39d6f4bb95065c2675db1610b419" datatype="html">
+ <source>Username is required</source>
+ <target>Le nom d'utilisateur est obligatoire.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e20f8b8a4706526c9024cc2f39d568345d100dc" datatype="html">
+ <source>Password is required</source>
+ <target>Le mot de passe est obligatoire.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f093d9574ab746b231504bd2cbb65f04bd7b00db" datatype="html">
+ <source>Log in</source>
+ <target>Connexion</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5590086849807274701" datatype="html">
+ <source>Scope</source>
+ <target>Périmètre</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327592562693301723" datatype="html">
+ <source>Read</source>
+ <target>Lecture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5674286808255988565" datatype="html">
+ <source>Create</source>
+ <target>Créer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4021752662928002901" datatype="html">
+ <source>Update</source>
+ <target>Mise à jour</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022070615528435141" datatype="html">
+ <source>Delete</source>
+ <target>Supprimer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ea5c4d8942c00752dcc72e72949c5d9832f6399" datatype="html">
+ <source>Description...</source>
+ <target>Description...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70f45880fce6ac5d8e468e25e82aefbba8098cfe" datatype="html">
+ <source>Permissions</source>
+ <target>Autorisations</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="122114774689391224" datatype="html">
+ <source>role</source>
+ <target>rôle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616102757855967475" datatype="html">
+ <source>All</source>
+ <target>Tout</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4416727401284087008" datatype="html">
+ <source>Created role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <target>Rôle '<x id="PH" equiv-text="roleFormModel.name"/>' créé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3472946357042916911" datatype="html">
+ <source>Updated role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <target>Rôle '<x id="PH" equiv-text="roleFormModel.name"/>' mis à jour</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="373024661645814027" datatype="html">
+ <source>System Role</source>
+ <target>Rôle système</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753648234171918096" datatype="html">
+ <source>Deleted role '<x id="PH" equiv-text="role"/>'</source>
+ <target>Rôle '<x id="PH" equiv-text="role"/>' supprimé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1674202514578558795" datatype="html">
+ <source>New name</source>
+ <target>Nouveau nom</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4857700187193019038" datatype="html">
+ <source>Clone Role</source>
+ <target>Cloner le rôle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="748631939386170157" datatype="html">
+ <source>Cloned role '<x id="PH" equiv-text="values['newName']"/>' from '<x id="PH_1" equiv-text="name"/>'</source>
+ <target>Rôle '<x id="PH" equiv-text="values['newName']"/>' cloné à partir de '<x id="PH_1" equiv-text="name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="195c31a2f970e790231a6bb94a5e8ca0167406d9" datatype="html">
+ <source>The username already exists.</source>
+ <target>Le nom d'utilisateur existe déjà.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f3bdcce4b2e8c37cd7f0f6c92ef8cff34b039b8" datatype="html">
+ <source>Confirm password</source>
+ <target>Confirmer le mot de passe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cbb979e63ba50e0ca3adfa09cbdcaefd0853fca1" datatype="html">
+ <source>Password confirmation doesn't match the password.</source>
+ <target>Le mot de passe de confirmation ne correspond pas au mot de passe.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="96621f9ed2e4ae5204564e583d2c816bedead571" datatype="html">
+ <source>Password expiration date</source>
+ <target>Date d'expiration du mot de passe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48932db3801fe9d5d72a60a3e656bffd17c1c5d9" datatype="html">
+ <source>Password expiration date...</source>
+ <target>Date d'expiration du mot de passe...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc" datatype="html">
+ <source>Email</source>
+ <target>Adresse électronique</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d0ec081dd61eb4f43aea269077bbe38eae87b7f9" datatype="html">
+ <source>Invalid email.</source>
+ <target>L'adresse électronique n'est pas valide.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9610487cbeb5796d34d8601b5ac0c0a65f9e1d19" datatype="html">
+ <source>Roles</source>
+ <target>Rôles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8913c216dd506e20e412e144381d8d2a65a84359" datatype="html">
+ <source>User must change password at next logon</source>
+ <target>L'utilisateur doit changer le mot de passe à la prochaine connexion</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0051a3479d3ba79135c16dc8cc017950a2cce821" datatype="html">
+ <source>You are about to remove &quot;user read / update&quot; permissions from your own user.</source>
+ <target>Vous êtes sur le point de supprimer les autorisations &quot;lecture/mise à jour utilisateur&quot; de votre propre utilisateur.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af4bf9fcb256853f14cf947eb1deb8d7f176d3f9" datatype="html">
+ <source>If you continue, you will no longer be able to add or remove roles from any user.</source>
+ <target>Si vous continuez, vous ne serez plus en mesure d'ajouter ni de supprimer des rôles pour n'importe quel utilisateur.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314291969883771319" datatype="html">
+ <source>There are no roles.</source>
+ <target>Il n'existe aucun rôle.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4306072924538089180" datatype="html">
+ <source>Created user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <target>Utilisateur '<x id="PH" equiv-text="userFormModel.username"/>' créé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1349763489797682899" datatype="html">
+ <source>Update user</source>
+ <target>Mettre à jour l'utilisateur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8688396456017237992" datatype="html">
+ <source>You were automatically logged out because your roles have been changed.</source>
+ <target>Vous avez été automatiquement déconnecté, car vos rôles ont changé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2335813072344088607" datatype="html">
+ <source>Updated user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <target>Utilisateur '<x id="PH" equiv-text="userFormModel.username"/>' mis à jour</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4768749765465246664" datatype="html">
+ <source>Email</source>
+ <target>Adresse électronique</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795890916060309463" datatype="html">
+ <source>Roles</source>
+ <target>Rôles</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6877445485286599988" datatype="html">
+ <source>Password expiration date</source>
+ <target>Date d'expiration du mot de passe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="705657168061753072" datatype="html">
+ <source>Deleted user '<x id="PH" equiv-text="username"/>'</source>
+ <target>Utilisateur '<x id="PH" equiv-text="username"/>' supprimé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="405819296611088743" datatype="html">
+ <source>Failed to delete user '<x id="PH" equiv-text="username"/>'</source>
+ <target>Échec de la suppression de l'utilisateur '<x id="PH" equiv-text="username"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8935387756949610047" datatype="html">
+ <source>You are currently logged in as '<x id="PH" equiv-text="username"/>'.</source>
+ <target>Vous êtes actuellement connecté en tant que '<x id="PH" equiv-text="username"/>'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0eb15f32b2b92d7f3103ef3ff032621888a8dc32" datatype="html">
+ <source>Old password</source>
+ <target>Ancien mot de passe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229" datatype="html">
+ <source>New password</source>
+ <target>Nouveau mot de passe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ede41f01c781b168a783cfcefc6fb67d48780d9b" datatype="html">
+ <source>Confirm new password</source>
+ <target>Confirmer le nouveau mot de passe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809196861118879526" datatype="html">
+ <source>password</source>
+ <target>mot de passe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623124197136601291" datatype="html">
+ <source>Updated user password&quot;</source>
+ <target>Mot de passe utilisateur mis à jour*</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be" datatype="html">
+ <source>Users</source>
+ <target>Utilisateurs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ced3246fa3db31be0f7da06648463f29ba378fbe" datatype="html">
+ <source>Selected Object Gateway:</source>
+ <target>Passerelle Object Gateway sélectionnée :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c53062af97ebda2a03f905698f58e524ecf8b968" datatype="html">
+ <source>Select Object Gateway</source>
+ <target>Sélectionner une passerelle Object Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="235c355afdcbf72953a15d7fc8d0d9e7a6619f46" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Page not Found<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Page introuvable<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aee9d027170f84774f2980537556f5099369b82" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for. The page you requested may have been changed or moved.</source>
+ <target>Désolés, nous n'avons pas pu trouver ce que vous cherchiez. La page que vous avez demandée a peut-être été modifiée ou déplacée.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">22,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2b46fe9a975c6531af77fee858ccd37327980f7" datatype="html">
+ <source>Please consult the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>documentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> on how to configure and enable the <x id="INTERPOLATION" equiv-text="{{ section_info }}"/> management functionality.</source>
+ <target>Veuillez consulter la <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>documentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> pour apprendre comment configurer et activer la fonctionnalité de gestion <x id="INTERPOLATION" equiv-text="{{ section_info }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">26,27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9d57ca7cab78c6f0d27e0d890cb8cf1515e4e30a" datatype="html">
+ <source>Go To Dashboard</source>
+ <target>Accéder au tableau de bord</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6578397717654172779" datatype="html">
+ <source>Page Not Found</source>
+ <target>Page introuvable</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8185335715884155108" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for.
+ The page you requested may have been changed or moved.</source>
+ <target>Désolés, nous n'avons pas pu trouver ce que vous cherchiez.
+ La page que vous avez demandée a peut-être été modifiée ou déplacée.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="143318366100741906" datatype="html">
+ <source>Access Denied</source>
+ <target>Accès refusé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5384670299771400832" datatype="html">
+ <source>Sorry, you don’t have permission to view this page or resource.</source>
+ <target>Désolé, vous n'êtes pas autorisé à consulter cette page ou cette ressource.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2424411274809083521" datatype="html">
+ <source>User Denied</source>
+ <target>Utilisateur refusé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7645004872908092358" datatype="html">
+ <source>Sorry, the user does not exist in Ceph.
+ You'll be logged out from the Identity Provider when you retry logging in.</source>
+ <target>Désolé, l'utilisateur n'existe pas dans Ceph.
+ Vous serez déconnecté du fournisseur d'identité lorsque vous réessaierez de vous connecter.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">24,25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f286db6ac9482dbf567bc491d49a6eade444895a" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7911416166208830577" datatype="html">
+ <source>Help</source>
+ <target>Aide</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8878700331247603166" datatype="html">
+ <source>Security</source>
+ <target>Sécurité</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8642696205489749843" datatype="html">
+ <source>Trademarks</source>
+ <target>Marques commerciales</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1481ecd21e760ac919a24e26cf790acd82e40199" datatype="html">
+ <source>Dashboard Settings</source>
+ <target>Paramètres du tableau de bord</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a79aab4ef674bf3f6532292107c0054302236e0f" datatype="html">
+ <source>User management</source>
+ <target>Gestion des utilisateurs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="197e0246502ca64d0de0df0d5c2deec51d41ff45" datatype="html">
+ <source>Telemetry configuration</source>
+ <target>Configuration de la télémétrie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85b79c9064aed1ead31ace985f31aa1363f6bdaf" datatype="html">
+ <source>Help</source>
+ <target>Aide</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06638e0f01d82c0786f63aa9832fbe7866b86087" datatype="html">
+ <source>documentation</source>
+ <target>documentation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e351b40b3869a5c7d19c3d4918cb1ac7aaab95c4" datatype="html">
+ <source>API</source>
+ <target>API</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a" datatype="html">
+ <source>About</source>
+ <target>À propos de</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="049dfd9fe6c78914ad58cf89ac6a631fca28ec74" datatype="html">
+ <source>Logged in user</source>
+ <target>Utilisateur connecté</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5022c5ae3ae921c07bf5f881e9b026b4a6708a7" datatype="html">
+ <source>Signed in as <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>Connecté en tant que <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9" datatype="html">
+ <source>Change password</source>
+ <target>Changer le mot de passe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d22c795daf43877a5f708dca2bccd549eb0471d" datatype="html">
+ <source>Sign out</source>
+ <target>Se déconnecter</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319e0745bcbc132451569294fa2fa21bf10f555a" datatype="html">
+ <source>Toggle navigation</source>
+ <target>Activer/Désactiver la navigation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f65253954b66e929a8b4d5ecaf61f9129f8cec64" datatype="html">
+ <source>Dashboard</source>
+ <target>Tableau de bord</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c95898abff46bfac3ed6eb2afef74597e60b15c" datatype="html">
+ <source>CRUSH map</source>
+ <target>Carte CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7b2bc4b86de6e96d353f6bf2b4d793ea3a19ba0" datatype="html">
+ <source>Manager Modules</source>
+ <target>Modules Manager</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb3d5aefff38a814b76da74371cbf02c0789a1ef" datatype="html">
+ <source>Logs</source>
+ <target>Journaux</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17fc3efe5f9fa4e0289c900cb6202265215a1a27" datatype="html">
+ <source>Monitoring</source>
+ <target>Surveillance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f5d0c10614e8a34f0e2dad33a0568277c50cf69" datatype="html">
+ <source>Block</source>
+ <target>Bloc</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3c2562ba992127203dcfd014010b03cb7b8113c6" datatype="html">
+ <source>Mirroring</source>
+ <target>Mise en miroir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="811c241d56601b91ef26735b770e64428089b950" datatype="html">
+ <source>iSCSI</source>
+ <target>iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a24eabd99ea5af20f5f94c4484649cd30370042b" datatype="html">
+ <source>NFS</source>
+ <target>NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5276fc60d54d667116babb723641b21281d37271" datatype="html">
+ <source>File Systems</source>
+ <target>Systèmes de fichiers</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9515520496da83179d8b08132f00f575512a1f40" datatype="html">
+ <source>Buckets</source>
+ <target>Compartiments</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a23e992f6c6e169a38b2b7338b4e5e803b52e0d" datatype="html">
+ <source>Tasks and Notifications</source>
+ <target>Tâches et notifications</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1390461972315002349" datatype="html">
+ <source>The name of the node under which data should be placed.</source>
+ <target>Nom du nœud sous lequel les données doivent être placées.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6575341202068728510" datatype="html">
+ <source>The type of CRUSH nodes across which we should separate replicas.</source>
+ <target>Type de nœuds CRUSH entre lesquels les répliques doivent être séparées.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3874278445824365480" datatype="html">
+ <source>The device class data should be placed on.</source>
+ <target>Périphérique sur lequel les données de classe doivent être placées.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="675628105428950215" datatype="html">
+ <source>Each object is split in data-chunks parts, each stored on a different OSD.</source>
+ <target>Chaque objet est divisé en parties de blocs de données, chacune étant stockée sur un OSD différent.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5128168460056151476" datatype="html">
+ <source>Compute coding chunks for each object and store them on different OSDs.
+ The number of coding chunks is also the number of OSDs that can be down without losing data.</source>
+ <target>Calculez des blocs de codage pour chaque objet et stockez-les sur différents OSD.
+ Le nombre de blocs de codage correspond également au nombre d'OSD qui peuvent être arrêtés sans perdre de données.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">18,19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8826111293169381132" datatype="html">
+ <source>The jerasure plugin is the most generic and flexible plugin,
+ it is also the default for Ceph erasure coded pools.</source>
+ <target>Le plug-in jerasure est le plug-in le plus générique et le plus flexible,
+  c'est aussi la valeur par défaut des réserves codées à effacement Ceph.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">23,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1331133460856304156" datatype="html">
+ <source>The more flexible technique is reed_sol_van : it is enough to set k
+ and m. The cauchy_good technique can be faster but you need to chose the packetsize
+ carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents
+ in the sense that they can only be configured with m=2.</source>
+ <target>La technique la plus flexible est reed_sol_van_van : il suffit de définir k
+ et m. La technique cauchy_good peut être plus rapide, mais vous devez choisir la taille du paquet
+ avec précaution. reed_sol_r6_op, liberation, blaum_roth et liber8tion sont des équivalents RAID6
+ en ce sens qu'ils ne peuvent être configurés qu'avec m=2.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">25,28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4577912952562931806" datatype="html">
+ <source>The encoding will be done on packets of bytes size at a time.
+ Choosing the right packet size is difficult.
+ The jerasure documentation contains extensive information on this topic.</source>
+ <target>L'encodage se fera sur des paquets de taille d'octets.
+ Choisir la bonne taille de paquet est difficile.
+ La documentation de jerasure contient de nombreuses informations à ce sujet.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">29,31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6471646852539810855" datatype="html">
+ <source>With the jerasure plugin, when an erasure coded object is stored on
+ multiple OSDs, recovering from the loss of one OSD requires reading from all the others.
+ For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading
+ from the eleven others to repair.
+
+ The lrc erasure code plugin creates local parity chunks to be able to recover using
+ less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create
+ an additional parity chunk for every four OSDs. When a single OSD is lost, it can be
+ recovered with only four OSDs instead of eleven.</source>
+ <target>Avec le plug-in jerasure, lorsqu'un objet codé à effacement est stocké sur
+ plusieurs OSD, la récupération à la suite de la perte d'un OSD nécessite la lecture de tous les autres.
+ Par exemple, si jerasure est configuré avec k=8 et m=4, la perte d'un OSD nécessite de lire
+ les onze autres pour pouvoir effectuer une réparation.
+
+ Le plug-in de code d'effacement lrc crée des blocs de parité locale pour permettre la récupération avec
+ moins d'OSD. Par exemple, si lrc est configuré avec k=8, m=4 et l=4,
+ un bloc de parité supplémentaire est créé pour chaque groupe de quatre OSD. Lorsqu'un seul OSD est perdu, il peut être
+ récupéré avec seulement quatre OSD au lieu de onze.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">34,42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2619235086723330982" datatype="html">
+ <source>Group the coding and data chunks into sets of size locality. For instance,
+ for k=4 and m=2, when locality=3 two groups of three are created. Each set can
+ be recovered without reading chunks from another set.</source>
+ <target>Regroupez les blocs de données et de codage en ensembles de localité de taille. Par exemple,
+ pour k=4 et m=2, lorsque locality=3, deux groupes de trois sont créés. Chaque ensemble peut
+ être récupéré sans lire les blocs d'un autre jeu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">43,45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3298836762557512588" datatype="html">
+ <source>The type of the crush bucket in which each set of chunks defined
+ by l will be stored. For instance, if it is set to rack, each group of l chunks will be
+ placed in a different rack. It is used to create a CRUSH rule step such as step choose
+ rack. If it is not set, no such grouping is done.</source>
+ <target>Type de compartiment Crush dans lequel chaque ensemble de blocs défini
+ par I sera stocké. Par exemple, s'il est réglé sur rack, chaque groupe de blocs I sera
+ placé dans un rack différent. Il est utilisé pour créer une étape de la règle CRUSH telle que l'étape de choix
+ d'un rack. S'il n'est pas défini, aucun regroupement de ce type n'est effectué.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">46,49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9162461669419243962" datatype="html">
+ <source>The isa plugin encapsulates the ISA library. It only runs on Intel processors.</source>
+ <target>Le plug-in isa encapsule la bibliothèque ISA. Il ne fonctionne qu'avec des processeurs Intel.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2389282202903059852" datatype="html">
+ <source>The ISA plugin comes in two Reed Solomon forms.
+ If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.</source>
+ <target>Le plug-in ISA se présente sous deux formes Reed Solomon.
+ Si reed_sol_van est défini, il équivaut à Vandermonde. Si cauchy est configuré, il équivaut à Cauchy.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">53,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7319555444402547739" datatype="html">
+ <source>The shec plugin encapsulates the multiple SHEC library.
+ It allows ceph to recover data more efficiently than Reed Solomon codes.</source>
+ <target>Le plug-in shec encapsule la bibliothèque SHEC multiple.
+ Il permet à Ceph de récupérer les données plus efficacement qu'avec les codes Reed Solomon.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">57,58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7723217930035575928" datatype="html">
+ <source>The number of parity chunks each of which includes each data chunk in its
+ calculation range. The number is used as a durability estimator. For instance, if c=2,
+ 2 OSDs can be down without losing data.</source>
+ <target>Nombre de blocs de parité, chacun incluant chaque bloc de données dans sa
+ plage de calcul. Ce nombre est utilisé comme estimateur de durabilité. Par exemple, si c=2,
+ 2 OSD peuvent être arrêtés sans perte de données.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">59,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2054101840892270818" datatype="html">
+ <source>CLAY (short for coupled-layer) codes are erasure codes designed to
+ bring about significant savings in terms of network bandwidth and disk IO when a failed
+ node/OSD/rack is being repaired.</source>
+ <target>Les codes CLAY (abréviation de &quot;coupled-layer&quot;, à savoir couche couplée ) sont des codes d'effacement conçus pour
+ réaliser des économies significatives de bande passante réseau et d'entrées/sorties disque en cas de
+ réparation d'un nœud/OSD/rack défectueux.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">64,66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491096236680229427" datatype="html">
+ <source>Number of OSDs requested to send data during recovery of a single chunk.
+ d needs to be chosen such that k+1 &lt;= d &lt;= k+m-1. The larger the d, the better
+ the savings.</source>
+ <target>Nombre d'OSD demandés pour envoyer des données lors de la récupération d'un bloc unique.
+ d doit être choisi de sorte que k+1 &lt;= d &lt;= k+m-1. Plus d est élevé,
+ plus les économies sont importantes.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">67,69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2625895656705896729" datatype="html">
+ <source>scalar_mds specifies the plugin that is used as a building block
+ in the layered construction. It can be one of jerasure, isa, shec.</source>
+ <target>scalar_mds spécifie le plug-in utilisé comme bloc pour la construction
+ en couches. Il peut s'agir de jerasure, isa, shec.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">70,71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6639141182731628232" datatype="html">
+ <source>technique specifies the technique that will be picked
+ within the 'scalar_mds' plugin specified. Supported techniques
+ are 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good', 'liber8tion' for jerasure, 'reed_sol_van',
+ 'cauchy' for isa and 'single', 'multiple' for shec.</source>
+ <target>technique spécifie la technique qui sera sélectionnée
+ dans le plug-in 'scalar_mds' indiqué. Les techniques prises
+ en charge sont 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good' et 'liber8tion' pour jerasure, 'reed_sol_van' et
+ 'cauchy' pour isa, et 'single' et 'multiple' pour shec.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">72,76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8172892264673403098" datatype="html">
+ <source>The name of the crush bucket used for the first step of the CRUSH rule.
+ For instance step take default.</source>
+ <target>Nom du compartiment crush utilisé pour la première étape de la règle CRUSH.
+ Par exemple, l'étape de définition des valeurs par défaut.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">80,81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1654284403437084515" datatype="html">
+ <source>Ensure that no two chunks are in a bucket with the same failure
+ domain. For instance, if the failure domain is host no two chunks will be stored on the same
+ host. It is used to create a CRUSH rule step such as step chooseleaf host.</source>
+ <target>Vérifiez qu'il n'existe pas deux blocs dans un compartiment avec le même domaine de
+ défaillance. Par exemple, si le domaine de défaillance est un hôte, deux blocs ne seront pas stockés sur le même
+ hôte. Cette option est utilisée pour créer une étape de la règle CRUSH telle que chooseleaf host.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">83,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7737703816676512224" datatype="html">
+ <source>Restrict placement to devices of a specific class
+ (e.g., ssd or hdd), using the crush device class names in the CRUSH map.</source>
+ <target>Restreindre le placement aux périphériques d'une classe spécifique
+ (par exemple, ssd ou hdd), en utilisant les noms des classes de périphériques crush dans la carte CRUSH.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9049698214199657456" datatype="html">
+ <source>Set the directory name from which the erasure code plugin is loaded.</source>
+ <target>Définissez le nom du répertoire à partir duquel le plug-in de code d'effacement est chargé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5514060020564877279" datatype="html">
+ <source>Allows all operations</source>
+ <target>Autoriser toutes les opérations</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4265406815683383218" datatype="html">
+ <source>Allows only operations that do not modify the server</source>
+ <target>Autorise uniquement les opérations qui ne modifient pas le serveur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="990071930378308183" datatype="html">
+ <source>Allows no access at all</source>
+ <target>N'autorise aucun accès</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7286983657616285612" datatype="html">
+ <source>Please specify a filesystem volume.</source>
+ <target>Veuillez spécifier un volume de système de fichiers.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8321762156640395170" datatype="html">
+ <source>The feature is disabled because Orchestrator is not available.</source>
+ <target>La fonction est désactivée car l'orchestrateur n'est pas disponible.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6718394293315494787" datatype="html">
+ <source>The Orchestrator backend doesn't support this feature.</source>
+ <target>Le backend de l'orchestrateur ne prend pas en charge cette fonctionnalité.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5569418400096331461" datatype="html">
+ <source>-- Select the priority --</source>
+ <target>-- Sélectionner la priorité --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="802458941707537739" datatype="html">
+ <source>Low</source>
+ <target>Faible</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8063651736083474594" datatype="html">
+ <source>High</source>
+ <target>Élevée</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1717753935149218245" datatype="html">
+ <source>The user list data might be stale. If needed, you can manually reload it.</source>
+ <target>Les données de liste d'utilisateurs sont peut-être obsolètes. Si nécessaire, vous pouvez les recharger manuellement.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/list-with-details.class.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7077550143229856452" datatype="html">
+ <source>Retrieving data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>Récupération des données pour <x id="PH" equiv-text="statusFor"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8231424898988217966" datatype="html">
+ <source>Retrieving data.</source>
+ <target>Récupération des données</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2357645764289315007" datatype="html">
+ <source>Please wait...</source>
+ <target>Veuillez patienter...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="232824565824302482" datatype="html">
+ <source>Displaying previously cached data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>Affichage des données précédemment mises en cache pour <x id="PH" equiv-text="statusFor"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8721257977793603730" datatype="html">
+ <source>Displaying previously cached data.</source>
+ <target>Affichage des données précédemment mises en cache.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6731313206654246255" datatype="html">
+ <source>Could not load data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>Impossible de charger les données pour <x id="PH" equiv-text="statusFor"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3359748695862553898" datatype="html">
+ <source>Could not load data.</source>
+ <target>Impossible de charger les données.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4836577225879717660" datatype="html">
+ <source>Please check the cluster health.</source>
+ <target>Veuillez vérifier l'état de santé de la grappe.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1519954996184640001" datatype="html">
+ <source>Error</source>
+ <target>Erreur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5037437391296624618" datatype="html">
+ <source>Information</source>
+ <target>Informations</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4648900870671159218" datatype="html">
+ <source>Success</source>
+ <target>Réussite</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3425367071066107827" datatype="html">
+ <source>Danger</source>
+ <target>Danger</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c947210e2d162b6225083d18820ab602f58cd2d" datatype="html">
+ <source>Remove the custom configuration value. The default configuration will be inherited and used instead.</source>
+ <target>Supprimez la valeur de configuration personnalisée. La configuration par défaut sera héritée et utilisée à la place.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="454ee9cb60b00446a8fb147fd2cc5eb836320586" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>.</source>
+ <target>La valeur saisie est trop élevée ! Elle ne doit pas être supérieure à <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fc8a22825131e028336f60ef909ccbd96059703" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>.</source>
+ <target>La valeur saisie est trop basse ! Elle ne doit pas être inférieure à <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4dd200b7f9e19048cf90516843b40964f2af3fe9" datatype="html">
+ <source>Copy to Clipboard</source>
+ <target>Copier dans le presse-papiers</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6110699a3562eeb15371063c0cf7f6bfd88a0209" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>?</source>
+ <target>Voulez-vous vraiment <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> ?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="549859e511ba5af0ea03fcaa620c472f08038969" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected items?</source>
+ <target>Voulez-vous vraiment <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> les éléments sélectionnés ?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="54839ebc827b73c9dc4e1df731c6d36a85036af7" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/>?</source>
+ <target>Voulez-vous vraiment <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> le/la/les <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/> sélectionné(e)(s) ?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2be8b7f04f0104d3fad90d079d8202b74f758b9a" datatype="html">
+ <source>Yes, I am sure.</source>
+ <target>Oui.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4523728183000855476" datatype="html">
+ <source>documentation</source>
+ <target>documentation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/doc/doc.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3099741642167775297" datatype="html">
+ <source>Download</source>
+ <target>Télécharger</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/download-button/download-button.component.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1417693714872528491" datatype="html">
+ <source>This field is required.</source>
+ <target>Ce champ est obligatoire.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5321335688371682440" datatype="html">
+ <source>An error occurred.</source>
+ <target>Une erreur s'est produite.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5109325fb160b543f71a51e7511c00575057431" datatype="html">
+ <source>Loading panel data...</source>
+ <target>Chargement des données du panneau...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a21acde005f80ceadb1391be1e7ff8b6d18188a0" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the monitoring functionality.</source>
+ <target>Veuillez consulter <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> pour apprendre comment configurer et activer la fonctionnalité de surveillance.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a0ed4bd7b7add2a6febf7adf58d8cde5e421418" datatype="html">
+ <source>Grafana Dashboard doesn't exist. Please refer to <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to add dashboards to Grafana.</source>
+ <target>Le tableau de bord Grafana n'existe pas. Veuillez consulter <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> pour apprendre comment ajouter des tableaux de bord à Grafana.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e11830040bd64804a0555de76f291d5832772d4" datatype="html">
+ <source>Grafana Time Picker</source>
+ <target>Sélecteur d'heure Grafana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="238c1ba845dd7330e8088165275919a1debf1ca3" datatype="html">
+ <source>Reset Settings</source>
+ <target>Réinitialiser les paramètres</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7888499255176013171" datatype="html">
+ <source>Last 5 minutes</source>
+ <target>Les 5 dernières minutes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6892361549797455305" datatype="html">
+ <source>Last 15 minutes</source>
+ <target>Les 15 dernières minutes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2653641162607195423" datatype="html">
+ <source>Last 30 minutes</source>
+ <target>Les 30 dernières minutes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4117793269024790392" datatype="html">
+ <source>Last 1 hour (Default)</source>
+ <target>La dernière heure (par défaut)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2645733658763754077" datatype="html">
+ <source>Last 3 hours</source>
+ <target>Les 3 dernières heures</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7360078715633936807" datatype="html">
+ <source>Last 6 hours</source>
+ <target>Les 6 dernières heures</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5055313582241816303" datatype="html">
+ <source>Last 12 hours</source>
+ <target>Les 12 dernières heures</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9186529157286281693" datatype="html">
+ <source>Last 24 hours</source>
+ <target>Les 24 dernières heures</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4498682414491138092" datatype="html">
+ <source>Yesterday</source>
+ <target>Hier</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="929003859318769922" datatype="html">
+ <source>Today so far</source>
+ <target>Depuis le début de la journée</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5525943133564968818" datatype="html">
+ <source>Day before yesterday</source>
+ <target>Avant-hier</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6168755117727892817" datatype="html">
+ <source>Last 2 days</source>
+ <target>Les 2 derniers jours</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7574807704224200535" datatype="html">
+ <source>This day last week</source>
+ <target>Il y a huit jours</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4420128118950221234" datatype="html">
+ <source>Previous week</source>
+ <target>La semaine dernière</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4063965603321223683" datatype="html">
+ <source>This week so far</source>
+ <target>Depuis le début de la semaine</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4873149362496451858" datatype="html">
+ <source>Last 7 days</source>
+ <target>Les 7 derniers jours</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8586908745456864217" datatype="html">
+ <source>Previous month</source>
+ <target>Le mois dernier</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1647573304710886499" datatype="html">
+ <source>This month so far</source>
+ <target>Depuis le début du mois</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2949150997160654358" datatype="html">
+ <source>Last 30 days</source>
+ <target>Les 30 derniers jours</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7469939859049484736" datatype="html">
+ <source>Last 90 days</source>
+ <target>Les 90 derniers jours</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847501198811458781" datatype="html">
+ <source>Last 6 months</source>
+ <target>Les 6 derniers mois</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7447583558445881102" datatype="html">
+ <source>Last 1 year</source>
+ <target>L'année écoulée</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="100513227838842152" datatype="html">
+ <source>Previous year</source>
+ <target>L'année dernière</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3650872673621947074" datatype="html">
+ <source>This year so far</source>
+ <target>Depuis le début de l'année</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1262816694819959075" datatype="html">
+ <source>Last 2 years</source>
+ <target>Les 2 dernières années</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7878813844917362690" datatype="html">
+ <source>Last 5 years</source>
+ <target>Les 5 dernières années</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3fb5709e10166cbc85970cbff103db227dbeb813" datatype="html">
+ <source>Select a Language</source>
+ <target>Sélectionner une langue</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/language-selector/language-selector.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e52e9143145e1db5146258de81eae018a407b31" datatype="html">
+ <source>Clear notifications</source>
+ <target>Effacer les notifications</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0b07bb6b7ff21ede439dd04eaf8872d1ecb84d8" datatype="html">
+ <source>Remove notification</source>
+ <target>Supprimer la notification</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e17a1d75189da843f541f7764f188f2b19a97df2" datatype="html">
+ <source>Duration:</source>
+ <target>Durée :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d4b37c6675c5b436a54c43d6716eec835e1aa7f" datatype="html">
+ <source>There are no notifications.</source>
+ <target>Il n'y a aucune notification.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b20e42ac4354d449f2718428b5390933eef0c1b9" datatype="html">
+ <source>The feature is not supported in the current Orchestrator.</source>
+ <target>La fonctionnalité n'est pas prise en charge dans l'orchestrateur actuel.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a437b8f93cf826817c04a4277edb1ae3a93a1ab" datatype="html">
+ <source>Orchestrator is not available. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the functionality.</source>
+ <target>L'orchestrateur n'est pas disponible. Veuillez consulter <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> pour découvrir comment configurer et activer cette fonctionnalité.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">7,9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20b3d45b0c08a2951a9974fa20505e4de95250c9" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>less than 1<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day. Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <target>Votre mot de passe expirera dans <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>moins de 1<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>jour. Cliquez <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>ici<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> pour le modifier maintenant.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">9,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f34088c155e40ffb23770a465a65868ce772b2" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day(s). Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <target>Votre mot de passe expirera dans <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> jour(s). Cliquez <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>ici<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> pour le modifier maintenant.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8d1785038d461ec66b5799db21864182b35900a" datatype="html">
+ <source>Refresh</source>
+ <target> Rafraîchir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/refresh-selector/refresh-selector.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3417247046175131869" datatype="html">
+ <source>No items selected.</source>
+ <target>Aucun élément sélectionné.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1034353870189672674" datatype="html">
+ <source>Deselect item to select again</source>
+ <target>Désélectionnez l'élément pour le sélectionner à nouveau.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4879298070255432995" datatype="html">
+ <source>Selection limit reached</source>
+ <target>Limite de sélection atteinte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001227209911602786" datatype="html">
+ <source>Filter tags</source>
+ <target>Balises de filtre</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="791789583719406586" datatype="html">
+ <source>Add badge</source>
+ <target>Ajouter un badge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="699988676752930063" datatype="html">
+ <source>There are no items available.</source>
+ <target>Aucun élément disponible.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6702323d3760e3db0e2e785d567469d18beb120" datatype="html">
+ <source>The Ceph community needs your help to continue improving: please <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>Activate<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> the <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Telemetry<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> module.</source>
+ <target>La communauté Ceph a besoin de votre aide pour continuer à s'améliorer : veuillez <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>Activer<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> le module <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Télémétrie<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.html</context>
+ <context context-type="linenumber">8,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8770134622386151776" datatype="html">
+ <source>Telemetry activation reminder muted</source>
+ <target>Rappel d'activation de la télémétrie rendu muet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8352450862052130357" datatype="html">
+ <source>You can activate the module on the Telemetry configuration page (&lt;b&gt;Dashboard Settings&lt;/b&gt; -&gt; &lt;b&gt;Telemetry configuration&lt;/b&gt;) at any time.</source>
+ <target>Vous pouvez activer le module à tout moment sur la page de configuration de la télémétrie (&lt;b&gt;Paramètres du tableau de bord&lt;/b&gt; -&gt; &lt;b&gt;Configuration de la télémétrie&lt;/b&gt;).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bc9e5365a581105ce37cf47d1d74e4ad9eb75ce" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e634c306cab9e8879c3392593714c1ceab85437d" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3249513483374643425" datatype="html">
+ <source>Add</source>
+ <target>Ajouter</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4359847060009771702" datatype="html">
+ <source>Set</source>
+ <target>Définir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935187492052582731" datatype="html">
+ <source>Submit</source>
+ <target>Soumettre</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4814285799071780083" datatype="html">
+ <source>Remove</source>
+ <target>Supprimer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8363450564548681668" datatype="html">
+ <source>Unset</source>
+ <target>Annuler la définition</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2159130950882492111" datatype="html">
+ <source>Cancel</source>
+ <target>Annuler</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1295614462098694869" datatype="html">
+ <source>Preview</source>
+ <target>Aperçu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2354817630223808522" datatype="html">
+ <source>Move</source>
+ <target>Déplacer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3885497195825665706" datatype="html">
+ <source>Next</source>
+ <target>Suivant</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8890553633144307762" datatype="html">
+ <source>Back</source>
+ <target>Retour</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5834780181397311898" datatype="html">
+ <source>Clone</source>
+ <target>Cloner</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4323470180912194028" datatype="html">
+ <source>Copy</source>
+ <target>Copier</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2131301778880826094" datatype="html">
+ <source>Deep Scrub</source>
+ <target>Nettoyage en profondeur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1704447209800801558" datatype="html">
+ <source>Destroy</source>
+ <target>Détruire</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8343007008325027187" datatype="html">
+ <source>Evict</source>
+ <target>Évincer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="408179081163888126" datatype="html">
+ <source>Flatten</source>
+ <target>Aplatir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="318900679147387932" datatype="html">
+ <source>Mark Down</source>
+ <target>Marquer comme arrêté</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5275142643521766706" datatype="html">
+ <source>Mark In</source>
+ <target>Marquer comme rentré</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6973272903386150199" datatype="html">
+ <source>Mark Lost</source>
+ <target>Marquer comme perdu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1962653792210847411" datatype="html">
+ <source>Mark Out</source>
+ <target>Marquer comme sorti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4424610588915076517" datatype="html">
+ <source>Protect</source>
+ <target>Protéger</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6041115344061899387" datatype="html">
+ <source>Rename</source>
+ <target>Renommer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">164</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6770769801335635194" datatype="html">
+ <source>Restore</source>
+ <target>Restaurer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2003230525878010676" datatype="html">
+ <source>Reweight</source>
+ <target>Réévaluer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5430834128563178593" datatype="html">
+ <source>Scrub</source>
+ <target>Nettoyer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8461842260159597706" datatype="html">
+ <source>Show</source>
+ <target>Afficher</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5655608100705734230" datatype="html">
+ <source>Move to Trash</source>
+ <target>Déplacer vers la corbeille</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4622393909937403117" datatype="html">
+ <source>Unprotect</source>
+ <target>Annuler la protection</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1230154438678955604" datatype="html">
+ <source>Change</source>
+ <target>Modifier</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8450843381175865415" datatype="html">
+ <source>Enter Maintenance</source>
+ <target>Accéder à la maintenance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1610181371597502589" datatype="html">
+ <source>Exit Maintenance</source>
+ <target>Quitter la maintenance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="676511611419004737" datatype="html">
+ <source>Start Drain</source>
+ <target>Commencer le vidage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7170653322511987983" datatype="html">
+ <source>Stop Drain</source>
+ <target>Arrêter le vidage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5528551262937858942" datatype="html">
+ <source>Recreate</source>
+ <target>Recréer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2502364444688691031" datatype="html">
+ <source>Expire</source>
+ <target>Expirer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6381490568322624964" datatype="html">
+ <source>Deleted</source>
+ <target>Supprimé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="231679111972850796" datatype="html">
+ <source>Added</source>
+ <target>Ajouté</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5406093358072761930" datatype="html">
+ <source>Removed</source>
+ <target>Supprimé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3008573030448240863" datatype="html">
+ <source>Edited</source>
+ <target>Modifié</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4381944803872489731" datatype="html">
+ <source>Canceled</source>
+ <target>Annulé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754993936947658096" datatype="html">
+ <source>Previewed</source>
+ <target>Prévisualisation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6001163963116907226" datatype="html">
+ <source>Moved</source>
+ <target>Déplacé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4932744777596632840" datatype="html">
+ <source>Cloned</source>
+ <target>Cloné</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2115592966120408375" datatype="html">
+ <source>Copied</source>
+ <target>Copié</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7937474560394832586" datatype="html">
+ <source>Deep Scrubbed</source>
+ <target>Nettoyé en profondeur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6321562733889197649" datatype="html">
+ <source>Destroyed</source>
+ <target>Détruit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7460162290177581995" datatype="html">
+ <source>Flattened</source>
+ <target>Applati</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3662010055028969035" datatype="html">
+ <source>Marked Down</source>
+ <target>Marqué comme arrêté</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5880434235404894589" datatype="html">
+ <source>Marked In</source>
+ <target>Marqué comme rentré</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="266997194072682078" datatype="html">
+ <source>Marked Lost</source>
+ <target>Marqué comme perdu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">250</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4010544044592534535" datatype="html">
+ <source>Marked Out</source>
+ <target>Marqué comme sorti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4776304093333411035" datatype="html">
+ <source>Protected</source>
+ <target>Protégé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2700903921419382511" datatype="html">
+ <source>Purged</source>
+ <target>Purgé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5488667333459350160" datatype="html">
+ <source>Renamed</source>
+ <target>Renommé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8044659850000829751" datatype="html">
+ <source>Restored</source>
+ <target>Restauré</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559472082694466366" datatype="html">
+ <source>Reweighted</source>
+ <target>Réévalué</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022271525067453676" datatype="html">
+ <source>Rolled back</source>
+ <target>Rétabli à l'état initial</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2483217756816388123" datatype="html">
+ <source>Scrubbed</source>
+ <target>Nettoyé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7200036055090632378" datatype="html">
+ <source>Showed</source>
+ <target>Affiché</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7609648817347881129" datatype="html">
+ <source>Moved to Trash</source>
+ <target>Déplacé vers la corbeille</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7810326403606456469" datatype="html">
+ <source>Unprotected</source>
+ <target>Non protégé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5620774899056099259" datatype="html">
+ <source>Recreated</source>
+ <target>Recréé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464749780222721589" datatype="html">
+ <source>Expired</source>
+ <target>Expiré</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">266</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e5e23363e949f7dcbaf034bdb141a561132a10e" datatype="html">
+ <source>Clear filters</source>
+ <target>Effacer les filtres</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80cc9a12d4bf6fe454ed94b379eeaf915f920bb7" datatype="html">
+ <source>selected</source>
+ <target>sélectionné(e)(s)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <note priority="1" from="description">X selected</note>
+ </trans-unit>
+ <trans-unit id="0cb77511a9a148e05b9adf36cc07269956fbb29d" datatype="html">
+ <source>found</source>
+ <target>trouvé(e)(s)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <note priority="1" from="description">X found</note>
+ </trans-unit>
+ <trans-unit id="79347388740c50b7ac97e144c2494bb62912f312" datatype="html">
+ <source>total</source>
+ <target>total</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <note priority="1" from="description">X total</note>
+ </trans-unit>
+ <trans-unit id="2a3dab422cc892db037db8632bb84a6bf496e2d1" datatype="html">
+ <source>Expand/Collapse Row</source>
+ <target>Agrandir/réduire la ligne</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4047162422391207122" datatype="html">
+ <source>Failed to load data.</source>
+ <target>Échec du chargement des données.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.ts</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="709331713250198508" datatype="html">
+ <source>Loading form data...</source>
+ <target>Chargement des données du formulaire...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3850344644863430180" datatype="html">
+ <source>Form data could not be loaded.</source>
+ <target>Les données du formulaire n'ont pas pu être chargées...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4626760504772708998" datatype="html">
+ <source>Size has to be at least <x id="PH" equiv-text="value"/> or more</source>
+ <target>La taille doit être d'au minimum de <x id="PH" equiv-text="value"/> ou plus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">428</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2880361802894657892" datatype="html">
+ <source>Size has to be at most <x id="PH" equiv-text="value"/> or less</source>
+ <target>La taille doit être d'au maximum de <x id="PH" equiv-text="value"/> ou moins</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2807800733729323332" datatype="html">
+ <source>Yes</source>
+ <target>Oui</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3542042671420335679" datatype="html">
+ <source>No</source>
+ <target>Non</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7789266940050748913" datatype="html">
+ <source>in %s</source>
+ <target>dans %s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565573880632900017" datatype="html">
+ <source>%s ago</source>
+ <target>Il y a %s </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="220300059326988179" datatype="html">
+ <source>a few seconds</source>
+ <target>quelques secondes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2761143993878941513" datatype="html">
+ <source>%d seconds</source>
+ <target>%d secondes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7094767962693903153" datatype="html">
+ <source>a minute</source>
+ <target>une minute</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7597613755904774250" datatype="html">
+ <source>%d minutes</source>
+ <target>%d minutes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2757762976030115752" datatype="html">
+ <source>an hour</source>
+ <target>une heure</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9118454901758656303" datatype="html">
+ <source>%d hours</source>
+ <target>%d heures</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7435193742089920080" datatype="html">
+ <source>a day</source>
+ <target>un jour</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1821334622562842480" datatype="html">
+ <source>%d days</source>
+ <target>%d jours</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7375306199026780379" datatype="html">
+ <source>a week</source>
+ <target>une semaine</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7272688256541915488" datatype="html">
+ <source>%d weeks</source>
+ <target>%d semaines</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5761124614324704118" datatype="html">
+ <source>a month</source>
+ <target>un mois</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="352195662913351589" datatype="html">
+ <source>%d months</source>
+ <target>%d mois</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7562153591649199139" datatype="html">
+ <source>a year</source>
+ <target>une année</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5424759741855527370" datatype="html">
+ <source>%d years</source>
+ <target>%d années</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7738182956549158907" datatype="html">
+ <source>Required rules for passwords:</source>
+ <target>Règles requises pour les mots de passe :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8839765875053270528" datatype="html">
+ <source>Must contain at least <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> characters</source>
+ <target>Doit contenir au moins <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> caractères</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3098731108593590794" datatype="html">
+ <source>Must not be the same as the previous one</source>
+ <target>Doit être différent du précédent</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9150236741862848105" datatype="html">
+ <source>Cannot contain the username</source>
+ <target>Ne peut pas contenir le nom d'utilisateur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6395043854518867543" datatype="html">
+ <source>Cannot contain any configured keyword</source>
+ <target>Ne peut contenir aucun mot clé configuré</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="907558624910601703" datatype="html">
+ <source>Cannot contain any repetitive characters e.g. &quot;aaa&quot;</source>
+ <target>Ne peut contenir aucun caractère répétitif (par ex. &quot;aaa&quot;)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514384270734082343" datatype="html">
+ <source>Cannot contain any sequential characters e.g. &quot;abc&quot;</source>
+ <target>Ne peut pas contenir des caractères consécutifs (par ex. &quot;abc&quot;)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4119354814383293871" datatype="html">
+ <source>Must consist of characters from the following groups:
+ * Alphabetic a-z, A-Z
+ * Numbers 0-9
+ * Special chars: !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * Any other characters (signs)</source>
+ <target>Doit être composé de caractères des groupes suivants :
+* alphabétiques a-z, A-Z
+* chiffres de 0 à 9
+* caractères spéciaux : !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+* tout autre caractère (signes)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">30,34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8649061117624699581" datatype="html">
+ <source>Your matcher seems to match no currently defined rule or active alert.</source>
+ <target>Votre comparateur semble ne correspondre à aucune règle actuellement définie ni alerte active.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7122912874364762704" datatype="html">
+ <source>no active alerts</source>
+ <target>aucune alerte active</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7388215679576832341" datatype="html">
+ <source>1 active alert</source>
+ <target>1 alerte active</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3112400568960537267" datatype="html">
+ <source><x id="PH" equiv-text="alerts"/> active alerts</source>
+ <target><x id="PH" equiv-text="alerts"/> alertes actives</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6264717417287230743" datatype="html">
+ <source>Matches 1 rule</source>
+ <target>Correspond à 1 règle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054663176394183966" datatype="html">
+ <source>Matches <x id="PH" equiv-text="rules"/> rules</source>
+ <target>Correspond aux règles <x id="PH" equiv-text="rules"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6674225401121099210" datatype="html">
+ <source><x id="PH" equiv-text="rule"/> with <x id="PH_1" equiv-text="alert"/>.</source>
+ <target><x id="PH" equiv-text="rule"/> avec<x id="PH_1" equiv-text="alert"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5659908877047925719" datatype="html">
+ <source>Quality of Service</source>
+ <target>Qualité de service</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1277565045885499475" datatype="html">
+ <source>BPS Limit</source>
+ <target>Limite de bits/s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2289210323987692906" datatype="html">
+ <source>The desired limit of IO bytes per second.</source>
+ <target>Limite souhaitée d'octets E/S par seconde.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753589939879013605" datatype="html">
+ <source>IOPS Limit</source>
+ <target>Limite E/S par seconde</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2213985059444278522" datatype="html">
+ <source>The desired limit of IO operations per second.</source>
+ <target>Limite souhaitée d'opérations E/S par seconde.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2487530611825582289" datatype="html">
+ <source>Read BPS Limit</source>
+ <target>Limite de bits/s en lecture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8071352270469595250" datatype="html">
+ <source>The desired limit of read bytes per second.</source>
+ <target>Limite souhaitée de lecture d'octets par seconde.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1632513758247239690" datatype="html">
+ <source>Read IOPS Limit</source>
+ <target>Limite E/S par seconde en lecture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2361786794607418566" datatype="html">
+ <source>The desired limit of read operations per second.</source>
+ <target>Limite souhaitée d'opérations de lecture par seconde.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="894600353504285551" datatype="html">
+ <source>Write BPS Limit</source>
+ <target>Limite de bits/s en écriture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911437671369366025" datatype="html">
+ <source>The desired limit of write bytes per second.</source>
+ <target>Limite souhaitée d'écriture d'octets par seconde.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2947346368707443195" datatype="html">
+ <source>Write IOPS Limit</source>
+ <target>Limite E/S par seconde en écriture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5506349527983391356" datatype="html">
+ <source>The desired limit of write operations per second.</source>
+ <target>Limite souhaitée d'opérations d'écriture par seconde.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559424229658244943" datatype="html">
+ <source>BPS Burst</source>
+ <target>Rafale de bits/s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3454058701331860330" datatype="html">
+ <source>The desired burst limit of IO bytes.</source>
+ <target>Limite de rafale d'octets en E/S souhaitée.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171005761926448741" datatype="html">
+ <source>IOPS Burst</source>
+ <target>Rafale E/S par seconde</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4939532784700485729" datatype="html">
+ <source>The desired burst limit of IO operations.</source>
+ <target>Limite de rafale d'opérations E/S souhaitée.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6273492199526646930" datatype="html">
+ <source>Read BPS Burst</source>
+ <target>Rafale E/S par seconde en lecture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3105467595643777520" datatype="html">
+ <source>The desired burst limit of read bytes.</source>
+ <target>Limite de rafale d'octets lus par seconde.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2170715106679765467" datatype="html">
+ <source>Read IOPS Burst</source>
+ <target>Rafale E/S par seconde en lecture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6234106755510510672" datatype="html">
+ <source>The desired burst limit of read operations.</source>
+ <target>Limite de rafale d'opérations de lecture.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="228509518172572466" datatype="html">
+ <source>Write BPS Burst</source>
+ <target>Rafale E/S par seconde en écriture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7803279807796571240" datatype="html">
+ <source>The desired burst limit of write bytes.</source>
+ <target>Limite de rafale d'octets écrits souhaitée.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9125474584914848055" datatype="html">
+ <source>Write IOPS Burst</source>
+ <target>Rafale d'E/S par seconde en écriture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5839129348567326667" datatype="html">
+ <source>The desired burst limit of write operations.</source>
+ <target>Limite de rafale d'opérations d'écriture souhaitée.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="614961883076556986" datatype="html">
+ <source>Failed to <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></source>
+ <target>Échec de <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="489145301781720653" datatype="html">
+ <source>Executing</source>
+ <target>En cours d'exécution</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4238828029954346941" datatype="html">
+ <source>execute</source>
+ <target>exécuter</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7196604637389554584" datatype="html">
+ <source>Executed</source>
+ <target>Exécuté</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4418441687454700644" datatype="html">
+ <source>unknown task</source>
+ <target>tâche inconnue</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8667665916832796867" datatype="html">
+ <source>Creating</source>
+ <target>En cours de création</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6031236679730054907" datatype="html">
+ <source>create</source>
+ <target>créer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5593033420216313122" datatype="html">
+ <source>Updating</source>
+ <target>En cours de mise à jour</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6100869651653026893" datatype="html">
+ <source>update</source>
+ <target>mettre à jour</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3141301060598402455" datatype="html">
+ <source>Deleting</source>
+ <target>En cours de suppression</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3420504288275541125" datatype="html">
+ <source>Adding</source>
+ <target>En cours d'ajout</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1059784693423848532" datatype="html">
+ <source>add</source>
+ <target>ajouter</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594819887188505274" datatype="html">
+ <source>Removing</source>
+ <target>En cours de suppression</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2123171795960509943" datatype="html">
+ <source>remove</source>
+ <target>supprimer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1946427188770321847" datatype="html">
+ <source>Importing</source>
+ <target>En cours d'importation</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8495827411619139669" datatype="html">
+ <source>import</source>
+ <target>importer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218459863491436562" datatype="html">
+ <source>Imported</source>
+ <target>Importé</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6534993668932538712" datatype="html">
+ <source>RBD '<x id="PH" equiv-text="metadata.image_spec"/>'</source>
+ <target>RBD '<x id="PH" equiv-text="metadata.image_spec"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8237287859948228705" datatype="html">
+ <source>RBD snapshot '<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>'</source>
+ <target>Intantané RBD '<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2328067975897167268" datatype="html">
+ <source>mirroring site name</source>
+ <target>nom du site de mise en miroir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4433460322631470833" datatype="html">
+ <source>bootstrap token</source>
+ <target>Jeton Bootstrap</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7044591639782280183" datatype="html">
+ <source>mirror mode for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>mode de mise en miroir de la réserve '<x id="PH" equiv-text="metadata.pool_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7109746474198366468" datatype="html">
+ <source>mirror peer for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>mettre en miroir l'homologue de la réserve '<x id="PH" equiv-text="metadata.pool_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6201476020617351396" datatype="html">
+ <source>all dashboards</source>
+ <target>tous les tableaux de bord</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7268953097700363232" datatype="html">
+ <source>Identifying</source>
+ <target>En cours d'identification</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4337678035264231187" datatype="html">
+ <source>identify</source>
+ <target>identifier</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7257219307556106552" datatype="html">
+ <source>Identified</source>
+ <target>Identifié</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6002370161381995023" datatype="html">
+ <source>device '<x id="PH" equiv-text="metadata.device"/>' on host '<x id="PH_1" equiv-text="metadata.hostname"/>'</source>
+ <target>périphérique '<x id="PH" equiv-text="metadata.device"/>' sur l'hôte '<x id="PH_1" equiv-text="metadata.hostname"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5580298273054260850" datatype="html">
+ <source>OSDs (DriveGroups: <x id="PH" equiv-text="metadata.tracking_id"/>)</source>
+ <target>OSD (DriveGroups : <x id="PH" equiv-text="metadata.tracking_id"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2182125722527364040" datatype="html">
+ <source>Name is already used by <x id="PH" equiv-text="this.pool(metadata)"/>.</source>
+ <target>Ce nom est déjà utilisé par <x id="PH" equiv-text="this.pool(metadata)"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">182</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7892856315477304281" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> is busy.</source>
+ <target><x id="PH" equiv-text="this.rbd.default(metadata)"/> est occupé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4690045751984117407" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> contains snapshots.</source>
+ <target><x id="PH" equiv-text="this.rbd.default(metadata)"/> contient des instantanés.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="562148565853868662" datatype="html">
+ <source>Cloning</source>
+ <target>Clonage en cours</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1197352830433807469" datatype="html">
+ <source>clone</source>
+ <target>cloner</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1692004144561317867" datatype="html">
+ <source>Snapshot of <x id="PH" equiv-text="this.rbd.child(metadata)"/> must be protected.</source>
+ <target>L'instantané de <x id="PH" equiv-text="this.rbd.child(metadata)"/> doit être protégé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8531200838331320284" datatype="html">
+ <source>Copying</source>
+ <target>En cours de copie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6862265996781523030" datatype="html">
+ <source>copy</source>
+ <target>copie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3556912098733712857" datatype="html">
+ <source>Flattening</source>
+ <target>Aplatissement</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2488773646187451754" datatype="html">
+ <source>flatten</source>
+ <target>aplatir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="704305783678486635" datatype="html">
+ <source>Cannot unprotect <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> because it contains child images.</source>
+ <target>Impossible d'annuler la protection de <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/>, car elle contient des images enfant.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">223,225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101271773452792348" datatype="html">
+ <source>Cannot delete <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/> because it's protected.</source>
+ <target>Impossible de supprimer <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/>, car il/elle est protégé(e).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5143010940199748580" datatype="html">
+ <source>Rolling back</source>
+ <target>Retour à l'état initial</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1315686250907089544" datatype="html">
+ <source>rollback</source>
+ <target>rétablir l'état initial</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5010267418211867946" datatype="html">
+ <source>Moving</source>
+ <target>En cours de déplacement</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4366763205960752449" datatype="html">
+ <source>move</source>
+ <target>déplacer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="695867152524584829" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_spec"/>' to trash</source>
+ <target>image '<x id="PH" equiv-text="metadata.image_spec"/>' déplacée dans la corbeille</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423442774536615202" datatype="html">
+ <source>Could not find image.</source>
+ <target>Impossible de trouver l'image.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2622324641113512527" datatype="html">
+ <source>Restoring</source>
+ <target>En cours de restauration.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3347932678307141902" datatype="html">
+ <source>restore</source>
+ <target>restaurer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7488038030362249932" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>' into '<x id="PH_1" equiv-text="metadata.new_image_name"/>'</source>
+ <target>image '<x id="PH" equiv-text="metadata.image_id_spec"/>' dans '<x id="PH_1" equiv-text="metadata.new_image_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565688512490959949" datatype="html">
+ <source>Image name '<x id="PH" equiv-text="metadata.new_image_name"/>' is already in use.</source>
+ <target>Le nom d'image '<x id="PH" equiv-text="metadata.new_image_name"/>' est déjà utilisé.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6331051389974655106" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>'</source>
+ <target>image '<x id="PH" equiv-text="metadata.image_id_spec"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8245559899946787147" datatype="html">
+ <source>Purging</source>
+ <target>En cours de purge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7879437654311684252" datatype="html">
+ <source>purge</source>
+ <target>purger</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1440427157062670480" datatype="html">
+ <source>all pools</source>
+ <target>toutes les réserves</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8677740163708263843" datatype="html">
+ <source>images from <x id="PH" equiv-text="message"/></source>
+ <target>images provenant de <x id="PH" equiv-text="message"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011237345035114219" datatype="html">
+ <source>Cannot disable mirroring because it contains a peer.</source>
+ <target>Impossible de désactiver la mise en miroir, car l'élément contient un homologue.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">292</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7391584598242145869" datatype="html">
+ <source>host '<x id="PH" equiv-text="metadata.hostname"/>'</source>
+ <target>hôte '<x id="PH" equiv-text="metadata.hostname"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6964302691596180722" datatype="html">
+ <source>OSD '<x id="PH" equiv-text="metadata.svc_id"/>'</source>
+ <target>OSD '<x id="PH" equiv-text="metadata.svc_id"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="488305686602466689" datatype="html">
+ <source>pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>réserve '<x id="PH" equiv-text="metadata.pool_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5921392748828575278" datatype="html">
+ <source>erasure code profile '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <target>profil du code d'effacement '<x id="PH" equiv-text="metadata.name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2423915105798557698" datatype="html">
+ <source>crush rule '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <target>règle crush '<x id="PH" equiv-text="metadata.name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">370</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8273044996643438592" datatype="html">
+ <source>target '<x id="PH" equiv-text="metadata.target_iqn"/>'</source>
+ <target>cible '<x id="PH" equiv-text="metadata.target_iqn"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5474643443735437364" datatype="html">
+ <source>NFS '<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>'</source>
+ <target>NFS '<x id="PH" equiv-text="metadata.cluster_id"/> :<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">378,380</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2235495382025026939" datatype="html">
+ <source>Service '<x id="PH" equiv-text="metadata.service_name"/>'</source>
+ <target>Service '<x id="PH" equiv-text="metadata.service_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ </body>
+ </file>
+</xliff> \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.id-ID.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.id-ID.xlf
new file mode 100644
index 000000000..4c258636d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.id-ID.xlf
@@ -0,0 +1,14069 @@
+<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en-US" datatype="plaintext" original="ng2.template" target-language="id-ID">
+ <body>
+ <trans-unit id="ngb.alert.close" datatype="html">
+ <source>Close</source>
+ <target>Tutup</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/alert/alert.ts</context>
+ <context context-type="linenumber">58,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.slide-number" datatype="html">
+ <source> Slide <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> of <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">114,118</context>
+ </context-group>
+ <note priority="1" from="description">Currently selected slide number read by screen reader</note>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.previous" datatype="html">
+ <source>Previous</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">132,134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.next" datatype="html">
+ <source>Next</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">147,152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-month" datatype="html">
+ <source>Select month</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">44,49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">49,50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-year" datatype="html">
+ <source>Select year</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">59,63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.previous-month" datatype="html">
+ <source>Previous month</source>
+ <target>Bulan lalu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">24,27</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">35,36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.next-month" datatype="html">
+ <source>Next month</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">47,50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">60,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first" datatype="html">
+ <source>««</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">182,183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous" datatype="html">
+ <source>«</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">186,190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next" datatype="html">
+ <source>»</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">194,195</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last" datatype="html">
+ <source>»»</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">201,204</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first-aria" datatype="html">
+ <source>First</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">208,209</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous-aria" datatype="html">
+ <source>Previous</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">215,216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next-aria" datatype="html">
+ <source>Next</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">226,228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last-aria" datatype="html">
+ <source>Last</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.progressbar.value" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="; } /** *"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/progressbar/progressbar.ts</context>
+ <context context-type="linenumber">32,38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.HH" datatype="html">
+ <source>HH</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">40,41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.hours" datatype="html">
+ <source>Hours</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.MM" datatype="html">
+ <source>MM</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">51,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.minutes" datatype="html">
+ <source>Minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-hours" datatype="html">
+ <source>Increment hours</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">63,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-hours" datatype="html">
+ <source>Decrement hours</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">69,70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-minutes" datatype="html">
+ <source>Increment minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">76,78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-minutes" datatype="html">
+ <source>Decrement minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">82,84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.SS" datatype="html">
+ <source>SS</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.seconds" datatype="html">
+ <source>Seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">92,93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-seconds" datatype="html">
+ <source>Increment seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">100,101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-seconds" datatype="html">
+ <source>Decrement seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">106,110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.AM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">115,121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.PM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="t() meridian: b"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">123,131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.toast.close-aria" datatype="html">
+ <source>Close</source>
+ <target>Tutup</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/toast/toast.ts</context>
+ <context context-type="linenumber">78,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8835b9e49a3348b0a2f2162c21118af1f4bee45a" datatype="html">
+ <source>Must be greater than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbddac59563c8c126e3fe28691e4e247614fcbd1" datatype="html">
+ <source>Must be less than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5" datatype="html">
+ <source>Overview</source>
+ <target>Ikhtisar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbd2045d5c37e4bb39a3c0fb62ea1ddf70a12838" datatype="html">
+ <source>Targets</source>
+ <target>Target</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a674ab267d1934bf395f87ca1503fd474296893f" datatype="html">
+ <source>iSCSI Topology</source>
+ <target>Topologi iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8953033926734869941" datatype="html">
+ <source>Name</source>
+ <target>Nama</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6603000223840533819" datatype="html">
+ <source>Current</source>
+ <target>Terkini</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5607669932062416162" datatype="html">
+ <source>Default</source>
+ <target>Bawaan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6803e31b7395d94934e091a49a9524026b59b018" datatype="html">
+ <source>Discovery Authentication</source>
+ <target>Otentikasi Discovery</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e08a77594f3d89311cdf6da5090044270909c194" datatype="html">
+ <source>User</source>
+ <target>Pengguna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">381</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7cbdabcece469fab89cfa687ab152bca18b97498" datatype="html">
+ <source>This field is required.</source>
+ <target>Isian ini tidak boleh kosong.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">368</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">423</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">481</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">291</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">343</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">407</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">490</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">516</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">556</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">573</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">590</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">647</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">672</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">299</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">195</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">520</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">614</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">651</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f717bad2da5944a2567a52f971ccc6806db85805" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">28,29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">85,86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c32ef07f8803a223a83ed17024b38e8d82292407" datatype="html">
+ <source>Password</source>
+ <target>Kata sandi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">403</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">581</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="001e1836299d8d3b84eaebe2fa051325beab3f00" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">61,62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">118,119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff40391de7a1944ea95091e4045cc34c4979b736" datatype="html">
+ <source>Mutual User</source>
+ <target>Pengguna Bersama</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cf73dbebe99b737c4d288788182fc356e3c93d3" datatype="html">
+ <source>Mutual Password</source>
+ <target>Kata sandi bersama</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594987303599690088" datatype="html">
+ <source>Updated discovery authentication</source>
+ <target>Otentikasi penemuan telah diperbarui</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb127ea03835b3230f0ed981c7080e2ccb879621" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <note priority="1" from="description">form title</note>
+ </trans-unit>
+ <trans-unit id="1406c2fb12a20c1528b19bcc5e24a6a2386167f3" datatype="html">
+ <source>Target IQN</source>
+ <target>Target IQN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5fe42339be910372fa689f559155631862d218e8" datatype="html">
+ <source>IQN has wrong pattern.</source>
+ <target>Pola IQN salah.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="050a7ff057d1e895357540406b6be5652b4d1c71" datatype="html">
+ <source>An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'</source>
+ <target>Suatu IQN memiliki notasi seperti ini 'iqn.$tahun-$bulan.$reversedAddress:$definedName'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8ada4b53396d8366db00a435acc61d53d857047" datatype="html">
+ <source>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</source>
+ <target>Contoh: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e" datatype="html">
+ <source>More information</source>
+ <target>Informasi lainnya</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9b1aa85dfc6849196e64060db02c5410de69b7a1" datatype="html">
+ <source>This target has modified advanced settings.</source>
+ <target>Pengaturan lanjutan target ini telah dimodifikasi.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6990ad8d6182662e864495ac31c3758cda1c7a28" datatype="html">
+ <source>Portals</source>
+ <target>Portal</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a3ac2b4137d723fd9878cd357c2012ff6c07973" datatype="html">
+ <source>Add portal</source>
+ <target>Tambahkan portal</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3638c01b6c34066438909713ec96087c813fc7e" datatype="html">
+ <source>At least <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> gateways are required.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b73f7f5060fb22a1e9ec462b1bb02493fa3ab866" datatype="html">
+ <source>Images</source>
+ <target>Image</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">495</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">629</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9aff25be088f0efe3eaaf62edf2bff41cc41a617" datatype="html">
+ <source>Backstore: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e3484cae8b118c576ca2815bf9c9406c2eb2cae3" datatype="html">
+ <source>This image has modified settings.</source>
+ <target>Pengaturan Image ini telah dimodifikasi.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1dff11e0820b6722ab240169f1232d70a54beaaa" datatype="html">
+ <source>Duplicated LUN numbers.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bf2dccf92ccff6e3b091792bf4205595406e1bfb" datatype="html">
+ <source>Duplicated WWN.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="808038f912fdc7f0e03f82d4afd3bf9178527fc8" datatype="html">
+ <source>Add image</source>
+ <target>Tambahkan image</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">656</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66c5fb27f52e75b70ca4b670b9b15a2a51cf9543" datatype="html">
+ <source>ACL authentication</source>
+ <target>Otentikasi ACL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="137fbf154ecad4d580354db0858b76faea7e4686" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">227,228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">287,288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="361771c32dd2254d77fd3fbf006b008983fe5907" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">262,263</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">323,324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f494bd31f095f6dcc656ce87ec2dcf07a2e9b30c" datatype="html">
+ <source>Initiators</source>
+ <target>Inisiator</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">335</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">588</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e98239d8a6be1100119ff4b5630c822b82786740" datatype="html">
+ <source>Initiator</source>
+ <target>Inisiator</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2c5059d8cda15d8d03e2cce30f2d139623d9a91" datatype="html">
+ <source>Client IQN</source>
+ <target>Klien IQN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="107d5aabce23d900f0a80e6ddc1c10e29aa0bed8" datatype="html">
+ <source>Initiator IQN needs to be unique.</source>
+ <target>Inisiator IQN harus unik.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e7cad911fa524e512d9744b16358b7ee6791385" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">394,395</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">452,453</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7f2c186d181206d0d2b1ff74819081a010f10bf" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">427,428</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">485,486</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d1878d5fc761cbe9614bfd87047a740c82a6951" datatype="html">
+ <source>Initiator belongs to a group. Images will be configure in the group.</source>
+ <target>Inisiator termasuk ke dalam grup. Image akan dikonfigurasi di dalam grup.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">515</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0de67b9d97fafbf200f9451e8388ee8128a56ac" datatype="html">
+ <source>No items added.</source>
+ <target>Tidak ada yang ditambahkan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">671</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d565e47726158e428ecdc952fc9233b9b7d7f049" datatype="html">
+ <source>Add initiator</source>
+ <target>Tambahkan inisiator</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">616</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c22ba03540aa3217da059f45e7eab138b51a96e2" datatype="html">
+ <source>Groups</source>
+ <target>Grup</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c90059afafb7e160384d9f512797c95bb95c6dc" datatype="html">
+ <source>Group</source>
+ <target>Grup</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cff1428d10d59d14e45edec3c735a27b5482db59" datatype="html">
+ <source>Name</source>
+ <target>Nama</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">576</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3084948274cff4f56d0f431af47240e9cf02fcc7" datatype="html">
+ <source>Add group</source>
+ <target>Tambahkan grup</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">676</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6634268061646442252" datatype="html">
+ <source>There are no portals available.</source>
+ <target>Tidak ada portal yang tersedia.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4587015892789840153" datatype="html">
+ <source>There are no images available.</source>
+ <target>Tidak ada image yang tersedia.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7896905042057267575" datatype="html">
+ <source>There are no images available. Please make sure you add an image to the target.</source>
+ <target>Tidak ada image yang tersedia. Mohon pastikan Anda telah menambahkan image ke target.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6765423558085969805" datatype="html">
+ <source>There are no initiators available. Please make sure you add an initiator to the target.</source>
+ <target>Tidak ada inisiator tersedia. Mohon pastikan Anda telah menambahkan inisiator ke target.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2539932200265667453" datatype="html">
+ <source>target</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="051dcc342cfa5c1eaf187a2001aaa162379a160c" datatype="html">
+ <source>Configure</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e515f954730279c31d5301f02479666d6264e8b" datatype="html">
+ <source>Changing these parameters from their default values is usually not necessary.</source>
+ <target>Mengganti parameter ini dari nilai bawaan biasanya tidak diperlukan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e2591df099ddac796cda401c5f282da779d45f2" datatype="html">
+ <source>Identifier</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62480a4859976427cf18fc8ef41d3a438eda0412" datatype="html">
+ <source>lun</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8afc9eb4405e0aa554b2ba14140ef790cdecc040" datatype="html">
+ <source>wwn</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
+ <source>Settings</source>
+ <target>Pengaturan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69a47cbabcc51ca942606e1d8da0ec11f98a2690" datatype="html">
+ <source>Backstore</source>
+ <target>Backstore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="339878da255ab55447c43afef8d9b2f9753bf5f6" datatype="html">
+ <source>Advanced Settings</source>
+ <target>Pengaturan Lanjut</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="332227f088a4877b3c11f5fb3ae8bc812c470fae" datatype="html">
+ <source>iSCSI Targets not available</source>
+ <target>iSCSI Target tidak tersedia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7fba666f1fff0182e570f12133fb3d622d9ea6" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the iSCSI Targets management functionality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3b301d0044f62c92af0da53d7aaca52a436a547d" datatype="html">
+ <source>Available information:</source>
+ <target>Informasi tersedia:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8414a5cb9d71cc1b21b10e4a9d1f2dad558f3361" datatype="html">
+ <source>Discovery authentication</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4854396465510517671" datatype="html">
+ <source>Target</source>
+ <target>Target</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4093869278527257288" datatype="html">
+ <source>Portals</source>
+ <target>Portal</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="414887388288176527" datatype="html">
+ <source>Images</source>
+ <target>Image</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="798573158169239055" datatype="html">
+ <source># Sessions</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="646929398175374220" datatype="html">
+ <source>Unavailable gateway(s)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2350612272163013640" datatype="html">
+ <source>Target has active sessions</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4782410538666829801" datatype="html">
+ <source>iSCSI target</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">227</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8a9910cd114c1deb9af74f6f99b4173403965bf2" datatype="html">
+ <source>Gateways</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911214550882917183" datatype="html">
+ <source>State</source>
+ <target>Keadaan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4121862424558610140" datatype="html">
+ <source># Targets</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101197021456818771" datatype="html">
+ <source>Pool</source>
+ <target>Pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3012906865384504293" datatype="html">
+ <source>Image</source>
+ <target>Image</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2699995524827665158" datatype="html">
+ <source>Backstore</source>
+ <target>Backstore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3559214740809905405" datatype="html">
+ <source>Read Bytes</source>
+ <target>Baca Bytes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1580583760095064067" datatype="html">
+ <source>Write Bytes</source>
+ <target>Tulis Bytes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7225917547116479918" datatype="html">
+ <source>Read Ops</source>
+ <target>Ops Baca</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6417507714454914481" datatype="html">
+ <source>Write Ops</source>
+ <target>Ops Tulis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="257147267065394003" datatype="html">
+ <source>A/O Since</source>
+ <target>A/O Sejak</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ecbc084370a732fc3cde1966a60af78d71424ab4" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603e9cc3ef2aab57f2b0a00e465b23b9cabefd9c" datatype="html">
+ <source>To create a bootstrap token which can be imported by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Generate<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="660f97cd3188f8a04bd03b79e703fec72c6df04c" datatype="html">
+ <source>Site Name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2fecea01ce1d44114ee45144eff6d47a5016a74f" datatype="html">
+ <source>Name...</source>
+ <target>Nama...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92899fa68e8ca108912163ff58edc8540e453787" datatype="html">
+ <source>Pools</source>
+ <target>Pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c2a1dc72cffaf7ab3dc5599bf77b0a7fcad2b20" datatype="html">
+ <source>At least one pool is required.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b258b258b4cc475ceb2871305b61756b0134f4a" datatype="html">
+ <source>Generate</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1edc1fc6cfbbb22353050ad6788508b3ed584f53" datatype="html">
+ <source>Token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff785f5596aef34a93b9b4d1023e95c62eef5740" datatype="html">
+ <source>Generated token...</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8" datatype="html">
+ <source>Close</source>
+ <target>Tutup</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5467a6bb0e7fade6def7499400d5e2a7d8d3da20" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bb7aee0dec5164f45c0aa2f35f2fb2149d2c1d2" datatype="html">
+ <source>To import a bootstrap token which was created by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, provide the generated token, and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Import<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9200e09686136a1d42adfb89c12fbfef2deea125" datatype="html">
+ <source>Direction</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9761484679958da8d12841a4efa5964d33fae575" datatype="html">
+ <source>The token is invalid.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2381859602529023966" datatype="html">
+ <source>Instance</source>
+ <target>Instance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8040881171107393560" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1605455101862010019" datatype="html">
+ <source>Hostname</source>
+ <target>Nama hos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2724055831234181057" datatype="html">
+ <source>Version</source>
+ <target>Versi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2041675390931385838" datatype="html">
+ <source>Health</source>
+ <target>Kesehatan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87bd96249f8afc23f5301cddb57b1464a98e71a" datatype="html">
+ <source>Edit site name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cfff72c667274c12eb1ff71eadc25871c10c42dc" datatype="html">
+ <source>Edit the site name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">13,14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66db799d67958d4b0765181d072df62e2d1c16f5" datatype="html">
+ <source>Issues</source>
+ <target>Masalah</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef06d69259e587e28d52372455f44c7153cda7e7" datatype="html">
+ <source>Syncing</source>
+ <target>Menyinkronkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0b0901877d837d3fda16ba161eb74368d1c75b7a" datatype="html">
+ <source>Ready</source>
+ <target>Siap</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5833626790712999947" datatype="html">
+ <source>Issue</source>
+ <target>Isu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3419681791450150574" datatype="html">
+ <source>Progress</source>
+ <target>Kemajuan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4902817035128594900" datatype="html">
+ <source>Description</source>
+ <target>Deskripsi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40b7acea5b43f45e0bbd1efeba5200af4687981d" datatype="html">
+ <source>Site Name:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e24f9e2d42104ffc01599db4d566d1cc518f9e6" datatype="html">
+ <source>Daemons</source>
+ <target>Daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6450386891540681425" datatype="html">
+ <source>Edit Site Name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4645993115976933405" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4130053543590533787" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4057c56d63a7e9b140b1d01871a9229a5f30eb27" datatype="html">
+ <source>Edit pool mirror mode</source>
+ <target>Edit mode pencerminan pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e1f367f5feaab38f6637dd1f967c848b447dea2d" datatype="html">
+ <source>To edit the mirror mode for pool  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, select a new mode from the list and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37e10df2d9c0c25ef04ac112c9c9a7723e8efae0" datatype="html">
+ <source>Mode</source>
+ <target>Mode</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">426</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32ca348ef926b0a6a7a780b8b64c3a8239895cec" datatype="html">
+ <source>Peer clusters must be removed prior to disabling mirror.</source>
+ <target>Klaster mitra harus dihapus sebelum menonaktfikan pencerminan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5769292297914455214" datatype="html">
+ <source>Disabled</source>
+ <target>Dimatikan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ddcb416c1c0aa1f54acf5beef1de81813e76fa6" datatype="html">
+ <source>{VAR_SELECT, select, edit {Edit} other {Add}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3aa7c3a4f7b0cf7c2e60fc71ea1e3b4c3efa3558" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> pool mirror peer</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="59ca65ece457429d90104ede4674965f62edbabe" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> the pool mirror peer attributes for pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Submit<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d3cc964811f852a168f4a2d5daa59068abc5cf53" datatype="html">
+ <source>Cluster Name</source>
+ <target>Nama Klaster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b631721fc56cb7fb1cbd07b802a487c5753f6a2d" datatype="html">
+ <source>The cluster name is not valid.</source>
+ <target>Nama klaster tidak valid.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca6deafa31bf421f85094807982aee4bcb20a3ae" datatype="html">
+ <source>CephX ID</source>
+ <target>CephX ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7539188a568c3d553cbde1bacaf32310c4264e24" datatype="html">
+ <source>CephX ID...</source>
+ <target>CephX ID...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1c45b594b0fba22fc64e80c793a7ffe005fdb0e" datatype="html">
+ <source>The CephX ID is not valid.</source>
+ <target>CephX ID tidak valid.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20861576fcfce773c918c782cd4f5adf32382921" datatype="html">
+ <source>Monitor Addresses</source>
+ <target>Alamat Monitor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fa28eeed2b4bd4ccbe6e9349a1c2b3cb1c5de70a" datatype="html">
+ <source>Comma-delimited addresses...</source>
+ <target>Alamat dengan pemisah-koma...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dc016c82fd85848d5c1b2fd0e8469ee2027d9c16" datatype="html">
+ <source>The monitory address is not valid.</source>
+ <target>Alamat monitor tidak valid.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0ac55b83dc6739e62bc655cfe375b67c93e7f4a" datatype="html">
+ <source>CephX Key</source>
+ <target>CephX Key</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f53434bcb95bd86f1df9c8e22966f757614fc4ad" datatype="html">
+ <source>Base64-encoded key...</source>
+ <target>Base64-encoded key...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4cd83164cd4f66b4abc2863f9ce6f599d789e4ca" datatype="html">
+ <source>CephX key must be base64 encoded.</source>
+ <target>Kunci CephX harus base64 encoded.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6407712033679505505" datatype="html">
+ <source>Edit Mode</source>
+ <target>Mode Edit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054237897979907103" datatype="html">
+ <source>Add Peer</source>
+ <target>Tambahkan Mitra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="899134641637789371" datatype="html">
+ <source>Edit Peer</source>
+ <target>Edit Mitra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7393680121674824053" datatype="html">
+ <source>Delete Peer</source>
+ <target>Hapus Mitra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1713271461473302108" datatype="html">
+ <source>Mode</source>
+ <target>Mode</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1061297288634362831" datatype="html">
+ <source>Leader</source>
+ <target>Pemimpin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8517494870558773093" datatype="html">
+ <source># Local</source>
+ <target># Lokal</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4953753699491987394" datatype="html">
+ <source># Remote</source>
+ <target># Jauh</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1715982232168082172" datatype="html">
+ <source>mirror peer</source>
+ <target>mitra pencerminan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff92fbdec9fdd5054493eeda0d7ee8b450f83e72" datatype="html">
+ <source>RBD Configuration</source>
+ <target>Konfigurasi RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b62d9efc8eb3b589904f6cb96a0406bbda55673a" datatype="html">
+ <source>Remove the local configuration value. The parent configuration value will be inherited and used instead.</source>
+ <target>Menghapus nilai konfigurasi lokal. Nilai konfigurasi induk akan diturun dan digunakan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80d769fd863fe44fab689636a078466bfdbd1f20" datatype="html">
+ <source>The minimum value is 0</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5decb3917d46a9ac6e5813699801becb7c3c1455" datatype="html">
+ <source>Global</source>
+ <target>Global</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f9ba9bb9faa8284bcadb1cdbc6aaf969e9c4bb" datatype="html">
+ <source>Image</source>
+ <target>Image</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70fcca5a99575cffef3ff8cbd5e69f06ffd0f1c" datatype="html">
+ <source>Pool</source>
+ <target>Pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176659033176029418" datatype="html">
+ <source>Key</source>
+ <target>Kunci</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9155608366859514313" datatype="html">
+ <source>Source</source>
+ <target>Sumber</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6555318547274416232" datatype="html">
+ <source>Value</source>
+ <target>Nilai</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f6e8f6094b180eaf1f11bc0ffe383f1cdcd059e" datatype="html">
+ <source>Only available for RBD images with <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> enabled</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f8b2bb476981727ab34ed40fde1218361f92c45" datatype="html">
+ <source>Details</source>
+ <target>Detail</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03cc5b14b0a20d075e9009ff021f4f1660ba348a" datatype="html">
+ <source>Data Pool</source>
+ <target>Pool Data</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b051734b0ee9021991c91b3ed4e81c244322462" datatype="html">
+ <source>Created</source>
+ <target>Dibuat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7faaaa08f56427999f3be41df1093ce4089bbd75" datatype="html">
+ <source>Size</source>
+ <target>Ukuran</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="afdb601c16162f2c798b16a2920955f1cc6a20aa" datatype="html">
+ <source>Objects</source>
+ <target>Objek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ceac8e132384322ec778ba760875a6c6897d3e42" datatype="html">
+ <source>Object size</source>
+ <target>Ukuran objek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cdb1fea93d77c07950c0c76c6e0ad79ebbef084" datatype="html">
+ <source>Features</source>
+ <target>Fitur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65771c9a73b9aa609d592fc96a64801a8f40bd" datatype="html">
+ <source>Provisioned</source>
+ <target>Disiapkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84a36cb75660b736773fe36ffa3d54f0f0fe363e" datatype="html">
+ <source>N/A</source>
+ <target>N/A</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c009342a4e8381f64341d0bb61c2e4685f5a4b" datatype="html">
+ <source>Total provisioned</source>
+ <target>Total disiapkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f6bf8a43ae415f527ac961ea62471b983aaa97b" datatype="html">
+ <source>Striping unit</source>
+ <target>Unit setrip</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db710e8a8f011923f2d15d713fbae49c38b02b26" datatype="html">
+ <source>Striping count</source>
+ <target>Jumlah setrip</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a4c2a9e76634ff14a60d52a718296f722d47c67" datatype="html">
+ <source>Parent</source>
+ <target>Induk</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a209e68d78ffc2cc9c53d2e76158624efab71ad" datatype="html">
+ <source>Block name prefix</source>
+ <target>Awalan nama blok</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5704ec2049d007c5f5fb495a5d8b607e68d58081" datatype="html">
+ <source>Order</source>
+ <target>Urutan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="984cb6ad70f150a401b4daf841bd3cd957412699" datatype="html">
+ <source>Format Version</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f21b1d17b6c5042bb5805516eee37fde33739dd8" datatype="html">
+ <source>Snapshots</source>
+ <target>Snapshot</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4a41f824a35ba01d5bd7be61aa06b3e8145209d0" datatype="html">
+ <source>Configuration</source>
+ <target>Konfigurasi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3cc9c2ae277393b3946b38c088dabff671b1ee1b" datatype="html">
+ <source>Performance</source>
+ <target>Kinerja</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935bb9cb0e4340fc74d33caa3b70d9d143fcad87" datatype="html">
+ <source>Information can not be displayed for RBD in status 'Removing'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58e58f1a8786da9031a05e6770c5dafce82badf5" datatype="html">
+ <source>This setting overrides the global value</source>
+ <target>Pengaturan ini akan membatalkan nilai global</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36b46714164964c6258b08ed0a25f57d8a950f92" datatype="html">
+ <source>This is the global value. No value for this option has been set for this image.</source>
+ <target>Ini adalah nilai global. Tidak ada nilai yang diset untuk image ini.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6547c9c4d5f62942ac4b1fe459cf9a03d4dbf5a0" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> from</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0e9ecf29a4fa5b057bd8052e0d801b3fde6a30bf" datatype="html">
+ <source>'/' and '@' are not allowed.</source>
+ <target>'/' dan '@' tidak diperbolehkan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="94516fa213706c67ce5a5b5765681d7fb032033a" datatype="html">
+ <source>Loading...</source>
+ <target>Memuat...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">209</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">452</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b99417c4dd46286ffd37c8d2e987c8b512ec7052" datatype="html">
+ <source>-- No rbd pools available --</source>
+ <target>-- Tidak ada pool rbd tersedia --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef83ec9c304a89d45650e580dcdc2978c37b3a83" datatype="html">
+ <source>-- Select a pool --</source>
+ <target>-- Pilih pool --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d649904466254d13df1fbf2d255f0bbc6553d213" datatype="html">
+ <source>-- No namespaces available --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e22d7bb4d2d561e0832ee0b9a3da2468a080c4f0" datatype="html">
+ <source>-- Select a namespace --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49449943d8cbf59d8c401c8bd2e76f92e207cc5f" datatype="html">
+ <source>Use a dedicated data pool</source>
+ <target>Gunakan pool data terdedikasi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa5b3c5ea5af14d09b2eb098039af9f1f77be010" datatype="html">
+ <source>You need more than one pool with the rbd application label use to use a dedicated data pool.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="870aee0dd31a9643bf62007beb8f1ae1deb34d42" datatype="html">
+ <source>Data pool</source>
+ <target>Pool data</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3792ca829d9b9f687e1f5d7733d30e9bb0bfec47" datatype="html">
+ <source>Dedicated pool that stores the object-data of the RBD.</source>
+ <target>Pool terdedikasi yang menyimpan data-objek dari RBD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151c80ea931037cd92e854442927f8a0f6ae7795" datatype="html">
+ <source>-- No data pools available --</source>
+ <target>-- Tidak ada pool data tersedia --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0016bd458baa88284a658ce9eeda42d8ad88d2c" datatype="html">
+ <source>e.g., 10GiB</source>
+ <target>cth. 10GiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">206</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a88bbee20570aaf9615332fb27020627044874d" datatype="html">
+ <source>You have to increase the size.</source>
+ <target>Anda harus menaikkan ukuran.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cfe07dac5b4ee1c464eb24225ddeb4f1d24076a" datatype="html">
+ <source>Advanced...</source>
+ <target>Tingkat lanjut...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bc2e854e111ecf2bd7db170da5e3c2ed08181d88" datatype="html">
+ <source>Advanced</source>
+ <target>Tingkat lanjut</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3562a3778695a5f9c0445660e35301f0a39aaf73" datatype="html">
+ <source>Striping</source>
+ <target>Setrip</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef3c3f3b5f562a5cdbe0ee2874287db1534b5958" datatype="html">
+ <source>Stripe unit</source>
+ <target>Unit setrip</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84471be1049006edecbcaef1a32ae0893c229c50" datatype="html">
+ <source>-- Select stripe unit --</source>
+ <target>-- Pilih ukuran setrip --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">289</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d32c5c54c8581c774a7f467fbd4e329b15a74fa" datatype="html">
+ <source>This field is required because stripe count is defined!</source>
+ <target>Isian ini harus diisi karena jumlah setrip telah ditentukan!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bbf9040be7c5491d4a03f2185708f43a6582a3b" datatype="html">
+ <source>Stripe unit is greater than object size.</source>
+ <target>Unit setrip lebih besar dari ukuran objek.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a682f49f9b761591661276d7c6f550e641a130a4" datatype="html">
+ <source>Stripe count</source>
+ <target>Jumlah setrip</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="baa74031990c5370008ba622d0a250f0929097f4" datatype="html">
+ <source>This field is required because stripe unit is defined!</source>
+ <target>Isian wajib diisi karena unit setrip didefinisikan!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cd2ada6d5ecbd5cbf89eae0a1f5326efedac0dbc" datatype="html">
+ <source>Stripe count must be greater than 0.</source>
+ <target>Jumlah setrip harus lebih besar dari 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4341718109173132593" datatype="html">
+ <source>RBD</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1359455778569887786" datatype="html">
+ <source>Deep flatten</source>
+ <target>Perataan mendalam</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58519213655664125" datatype="html">
+ <source>Layering</source>
+ <target>Lapisan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844531889615887801" datatype="html">
+ <source>Exclusive lock</source>
+ <target>Kunci eksklusif</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4585281635594103106" datatype="html">
+ <source>Object map (requires exclusive-lock)</source>
+ <target>Peta objek (butuh kunci-eksklusif)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240933649452133654" datatype="html">
+ <source>Journaling (requires exclusive-lock)</source>
+ <target>Penjurnalan (membutuhkan kunci-eksklusif)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3713046526850391848" datatype="html">
+ <source>Fast diff (interlocked with object-map)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19f1e825536efbf7492723a7c2d01ad23a4e994b" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1774b9915b0e302d02cad0b9321ad5f1a83247a8" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c9f1026c1235f4d76ace47449e806efd181ab332" datatype="html">
+ <source>Deleting this image will also delete all its snapshots.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55f864597e84d9bf88769e1fbfda1d64452430c9" datatype="html">
+ <source>The following snapshots are currently protected and will be removed:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2e362ec498c4c9112dc47a3cb7d7250ca8e71790" datatype="html">
+ <source>RBD in status 'Removing'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3294686077659093992" datatype="html">
+ <source>Namespace</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45739481977493163" datatype="html">
+ <source>Size</source>
+ <target>Ukuran</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7531602241051125940" datatype="html">
+ <source>Objects</source>
+ <target>Objek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1194977199378511591" datatype="html">
+ <source>Object size</source>
+ <target>Ukuran objek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">226</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="178418048502923560" datatype="html">
+ <source>Provisioned</source>
+ <target>Disiapkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7638291694671392137" datatype="html">
+ <source>Total provisioned</source>
+ <target>Total disiapkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8621797738551294959" datatype="html">
+ <source>Parent</source>
+ <target>Induk</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616639680594151867" datatype="html">
+ <source>This RBD has cloned snapshots. Please delete related RBDs before deleting this RBD.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2900827028308925059" datatype="html">
+ <source>This RBD image has an invalid name and can't be managed by ceph.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1796389652493657142" datatype="html">
+ <source>Action not possible for an RBD in status 'Removing'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">476</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c07d24bb422aa8e5e568df1c5709083f0a9c8f1" datatype="html">
+ <source>Create Namespace</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cca6c0485f96d3a9610d0339cb1275a5f2c3f46" datatype="html">
+ <source>Namespace already exists.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4641528557519966449" datatype="html">
+ <source>Created namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6809428596104996786" datatype="html">
+ <source>Total images</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1346311774128536550" datatype="html">
+ <source>Deleted namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7605466414392298530" datatype="html">
+ <source>Namespace contains images</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576483965711201552" datatype="html">
+ <source>RBD Snapshot</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3473055924346204357" datatype="html">
+ <source>Parent image must support Layering</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1152535233999495900" datatype="html">
+ <source>Snapshot must be protected in order to clone.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c5331983af566d4ac6a1024d15a3511786a4aa6" datatype="html">
+ <source>You are about to rollback</source>
+ <target>Anda akan mengembalikan semula</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6240400332778072187" datatype="html">
+ <source>PROTECTED</source>
+ <target>DIPROTEKSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9101667614062185213" datatype="html">
+ <source>UNPROTECTED</source>
+ <target>TIDAK DIPROTEKSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4207916966377787111" datatype="html">
+ <source>Created</source>
+ <target>Dibuat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587768621777516124" datatype="html">
+ <source>RBD snapshot rollback</source>
+ <target>Kembalikan snapshot RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">305</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2711198699676132148" datatype="html">
+ <source>Rollback</source>
+ <target>Kembalikan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3330476395115957823" datatype="html">
+ <source>RBD snapshot</source>
+ <target>Snapshot RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">322</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3a7e364a88ea4673199dfa98bc73e6dbe09dfac" datatype="html">
+ <source>Namespaces</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aba82bfd8e177d35b76cad7cd43941f8e5e5acac" datatype="html">
+ <source>Trash</source>
+ <target>Tempat sampah</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5e7f4b1ca49e8d217bd0e12c6f7d6b6a2ade2c18" datatype="html">
+ <source>Overall Performance</source>
+ <target>Performa Keseluruhan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c0408946a6d67185947f455f15cc201d0d78e6" datatype="html">
+ <source>Purge Trash</source>
+ <target>Kosongkan Tempah Sampah</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c96a761dc55a21882c132c929583a424c9b8cf4" datatype="html">
+ <source>Expired at</source>
+ <target>Kedaluwarsa pada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="661041e3fcff4d3e75c561e038ca2504cf2cc643" datatype="html">
+ <source>Protected until</source>
+ <target>Diproteksi hingga</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee3b2322a1d3277f7e3fdb8a5141ac42bcf350b" datatype="html">
+ <source>This image is protected until <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5611592591303869712" datatype="html">
+ <source>Status</source>
+ <target>Status</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">213</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">285</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2155633476201267204" datatype="html">
+ <source>Deleted At</source>
+ <target>Dihapus pada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0b5d789d42c0e69348e5fe0037fcbf5b5fbbdcc" datatype="html">
+ <source>Move an image to trash</source>
+ <target>Pindahkan image ke tempat sampah</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ad22c1d4aab3b8946603cea62de266d5129ca10" datatype="html">
+ <source>This image contains snapshot(s), which will prevent it from being removed after moved to trash.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">15,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d4a5f5698bc8118b2e120b9bb72eff339094dd0" datatype="html">
+ <source>To move <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> to trash, click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Move<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Optionally, you can pick an expiration date.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">19,20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f27d390844aad53b4240360e928156c5f0d326" datatype="html">
+ <source>Protection expires at</source>
+ <target>Proteksi berakhir pada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da166e9a0d27322f6ba8916d71ecc0f9905bb4b1" datatype="html">
+ <source>NOT PROTECTED</source>
+ <target>TIDAK DIPROTEKSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1506e5f2ca22cad14502ec7a20fb6113ace145d" datatype="html">
+ <source>Wrong date format. Please use &quot;YYYY-MM-DD HH:mm:ss&quot;.</source>
+ <target>Format tanggal salah. Mohon gunakan &quot;TTTT-BB-HH JJ:mm:dd&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa7ea0bb7495281e0b3258467ac7d90a1e44a1a1" datatype="html">
+ <source>Protection has already expired. Please pick a future date or leave it empty.</source>
+ <target>Proteksi telah kedaluarsa. Mohon pilih tanggal masa mendatang atau kosongkan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d8613436532acac2b97d17de28b50f93e6bd0222" datatype="html">
+ <source>To purge, select  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>All<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>  or one pool and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Purge<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55a4f598a4894b7fd5cb88f0ffd3c37ad009dd70" datatype="html">
+ <source>Pool:</source>
+ <target>Pool:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d43dd2b9f7797e4cf3a604695bb33e4479108516" datatype="html">
+ <source>Pool name...</source>
+ <target>Nama Pool...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dfc3c34e182ea73c5d784ff7c8135f087992dac1" datatype="html">
+ <source>All</source>
+ <target>Semua</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0e7c7ed1d51a0c205c815048bc9f79e24ee6db2" datatype="html">
+ <source>Restore Image</source>
+ <target>Pulihkan Image</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3bc4aaf0dce75dc5e01ee5c825a652dc8aea8f0" datatype="html">
+ <source>To restore  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>,  type the image's new name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Restore<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41307dd56fea669eed72e12a6c23af275f6bfd82" datatype="html">
+ <source>New Name</source>
+ <target>Nama Baru</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3625859417927520024" datatype="html">
+ <source>id</source>
+ <target>id</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6537904131139019667" datatype="html">
+ <source>type</source>
+ <target>tipe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8901220148451863928" datatype="html">
+ <source>state</source>
+ <target>keadaan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7925190601961269841" datatype="html">
+ <source>version</source>
+ <target>versi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6641024648411549335" datatype="html">
+ <source>Host</source>
+ <target>Hos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773272191572353800" datatype="html">
+ <source>root</source>
+ <target>induk</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6364513948635353490" datatype="html">
+ <source>Evicted client '<x id="PH" equiv-text="clientId"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c1e17956453ad772dbe82d6946f62748c692f3e" datatype="html">
+ <source>Ranks</source>
+ <target>Peringkat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b24e0b0b1629d2e8a51b9da7c75d6e6379f4bc4" datatype="html">
+ <source>Standbys</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="50df62325726db950523a5be1c78b8905fcc25d4" datatype="html">
+ <source>MDS performance counters</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4578796959376778578" datatype="html">
+ <source>Standby daemons</source>
+ <target>Daemon siaga</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="665219418211496660" datatype="html">
+ <source>Rank</source>
+ <target>Peringkat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5445409664838149993" datatype="html">
+ <source>Daemon</source>
+ <target>Daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5306473977542913614" datatype="html">
+ <source>Activity</source>
+ <target>Aktivitas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3998441303515229547" datatype="html">
+ <source>Dentries</source>
+ <target>Dentries</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7877631502958415163" datatype="html">
+ <source>Inodes</source>
+ <target>Inode</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6129397096478256985" datatype="html">
+ <source>Dirs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3011876564696453148" datatype="html">
+ <source>Caps</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8650499415827640724" datatype="html">
+ <source>Type</source>
+ <target>Tipe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="142654590491855672" datatype="html">
+ <source>Usage</source>
+ <target>Penggunaan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">326</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb8293aa8161433778762ae025ffd5e7c85795e" datatype="html">
+ <source>Quotas</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">540</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66785722678644243" datatype="html">
+ <source>Origin</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8911059720204770105" datatype="html">
+ <source>Path</source>
+ <target>Path</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6111756909052789805" datatype="html">
+ <source>Cannot create snapshots for files/folders in the subvolume <x id="PH" equiv-text="folders[2]"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7503263437025060215" datatype="html">
+ <source>Max size</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6763343019307619111" datatype="html">
+ <source>Max files</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327403486214540377" datatype="html">
+ <source>The inherited <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> is the maximum value to be used.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">434,437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3768927257183755959" datatype="html">
+ <source>Save</source>
+ <target>Simpan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">440</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6328794256834621774" datatype="html">
+ <source><x id="PH" equiv-text="action"/> CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> quota for '<x id="PH_2" equiv-text="path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">446</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9130352375983418123" datatype="html">
+ <source>size</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6889473896134264260" datatype="html">
+ <source>files</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2244434638607433133" datatype="html">
+ <source><x id="PH" equiv-text="this.getQuotaName()"/> quota <x id="PH_1" equiv-text="value"/> from '<x id="PH_2" equiv-text="path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">460</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6960117167304061503" datatype="html">
+ <source>Value has to be at least 0 or more</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">484</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6740501370117796629" datatype="html">
+ <source>Value has to be at most <x id="PH" equiv-text="maxValue"/> or less</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7239750919884229270" datatype="html">
+ <source>Updated</source>
+ <target>Diperbarui</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">499</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8885980874806414253" datatype="html">
+ <source>in order to inherit <x id="PH" equiv-text="quotaValue"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4182949309891923991" datatype="html">
+ <source>which isn't used because of the inheritance of <x id="PH" equiv-text="quotaValue"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7421970649864638435" datatype="html">
+ <source>in order to have no quota on the directory</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6730229976797004508" datatype="html">
+ <source><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">530,533</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="827679535246546876" datatype="html">
+ <source>Create Snapshot</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">542</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">552</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4747656362969857823" datatype="html">
+ <source>Please enter the name of the snapshot.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3667696812078358068" datatype="html">
+ <source>Created snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="753342836137587734" datatype="html">
+ <source>CephFs Snapshot</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">670</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2774104291801979963" datatype="html">
+ <source>Deleted snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">683</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4816216590591222133" datatype="html">
+ <source>Enabled</source>
+ <target>Diaktifkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ffe39df9d88c972792bd8688b215392deb8313d" datatype="html">
+ <source>Clients</source>
+ <target>Klien</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e213942c6354b9cbe7a650f0f1499bfc1000fb6" datatype="html">
+ <source>Directories</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fbbaf5cb02ed419e79a27072478f716a4666a99d" datatype="html">
+ <source>Performance Details</source>
+ <target>Detail Performa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0" datatype="html">
+ <source>Description</source>
+ <target>Deskripsi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ad112ce9bcd55dfd137792a86afe1b5a5b13cf8" datatype="html">
+ <source>Long description</source>
+ <target>Deskripsi lengkap</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="26fb5f81b3581f06b9210defb0e71dc69a67e819" datatype="html">
+ <source>Current values</source>
+ <target>Nilai saat ini</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7cee38a2259526c519f878e71b964f41db4348" datatype="html">
+ <source>Default</source>
+ <target>Bawaan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33e1c1d9fc05ca3f62fcc8a1170fc31ebae4229c" datatype="html">
+ <source>Daemon default</source>
+ <target>Daemon bawaan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f61c6867295f3b53d23557021f2f4e0aa1d0b8fc" datatype="html">
+ <source>Type</source>
+ <target>Tipe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9abcd7c82643d60c22733470463f74e4a54bc069" datatype="html">
+ <source>Min</source>
+ <target>Min</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3ced4d162a0a55ee233a187ce7208ba5e922418" datatype="html">
+ <source>Max</source>
+ <target>Maks</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="920617c6a1a4805e53bcb5af6a9c76f8387e89c6" datatype="html">
+ <source>Flags</source>
+ <target>Flag</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5" datatype="html">
+ <source>Services</source>
+ <target>Layanan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6834fa6b43d1ecbdf147c48dd9c4d72f1484571d" datatype="html">
+ <source>Source</source>
+ <target>Sumber</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a446fb0eb11fbffcac805ece5a2d306d24e733d8" datatype="html">
+ <source>Level</source>
+ <target>Level</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39f2fb094e9b2eda13163fa3f3a31594cf9c1307" datatype="html">
+ <source>Can be updated at runtime (editable)</source>
+ <target>Boleh diperbarui saat dijalankan (bisa diedit)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
+ <source>Tags</source>
+ <target>Tag</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ab0089ef47af61ca1d137bc908b96c290dfd9287" datatype="html">
+ <source>Enum values</source>
+ <target>Nilai Enum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="819476f1264f1659f38e86f6abb542141b184832" datatype="html">
+ <source>See also</source>
+ <target>Lihat juga</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="543199344025799954" datatype="html">
+ <source>The value can be updated at runtime.</source>
+ <target>Nilai dapat diperbarui saat runtime.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1718354829128482129" datatype="html">
+ <source>Daemons/clients do not pull this value from the
+ monitor config database. We disallow setting this option via 'ceph config
+ set ...'. This option should be configured via ceph.conf or via the
+ command line.</source>
+ <target>Daemon/klien tidak dapat mengambil nilai dari
+basis data konfigurasi monitor. Kami tidak mengizinkan mengubah ini dari 'ceph config
+set ...'. Pilihan ini harus dikonfigurasi melalui ceph.conf atau CLI.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">15,18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2345189734548717257" datatype="html">
+ <source>Option takes effect only during daemon startup.</source>
+ <target>Pilihan hanya dapat bekerja selama daemon dimulai.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5523310713159993513" datatype="html">
+ <source>Option only affects cluster creation.</source>
+ <target>Pilihan hanya berpengaruh pada pembuatan klaster.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1064479086902933123" datatype="html">
+ <source>Option only affects daemon creation.</source>
+ <target>Pilihan hanya berpengaruh pada pembuatan daemon.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="809b0c848932a41318f77a2aace904ef429c13f4" datatype="html">
+ <source>Values</source>
+ <target>Nilai</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5894f7158499fdb89527af50c9f1cf7d4c95cad6" datatype="html">
+ <source>-- Default --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="514f6e12d035a6d9b00de6b3e55c18b73488da07" datatype="html">
+ <source>true</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="774f5e6a183dea08393789b6f72e86afad729419" datatype="html">
+ <source>false</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="82029b6db704c56a2aa3e82ac555b8655356b077" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ed8b3967a7326b81b191c9f490006e6a6777a9a" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2337058106409853613" datatype="html">
+ <source>Updated config option <x id="PH" equiv-text="request.name"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3733215288982610673" datatype="html">
+ <source>Level</source>
+ <target>Level</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2218082343053095278" datatype="html">
+ <source>Service</source>
+ <target>Layanan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3553216189604488439" datatype="html">
+ <source>Modified</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844248428439297756" datatype="html">
+ <source>Current value</source>
+ <target>Nilai saat ini</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208877297843037352" datatype="html">
+ <source>Editable</source>
+ <target>Dapat diedit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b266042bac4c3a2eff4834e40fb9dc4767a709" datatype="html">
+ <source>Cluster Resources</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="099b441d49333b3c6d30b36dc0a4763e64c78920" datatype="html">
+ <source>Hosts</source>
+ <target>Hos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57e6e608ece53a26f6d509c90ed4f83e467741af" datatype="html">
+ <source>Storage Capacity</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19ece2cb2b9097c0f75af8e62b4b3b25d399a006" datatype="html">
+ <source>Number of devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b161e3d25fd1b42a781f4e923a58a94925988ddf" datatype="html">
+ <source>Raw capacity</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb6f3e2a26f3a6f2bc33f91adcd60502dbe5adac" datatype="html">
+ <source>CPUs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58d4a9814864741040bc5905b6a368836e683f76" datatype="html">
+ <source>Memory</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dbb81e566a861d4aa0a094366e4083e50863ee92" datatype="html">
+ <source>Host Details</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="453dc2810080a744223faac6da2b3ee9ed63a583" datatype="html">
+ <source>Welcome to <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1eec874e1928ca53baa9914781ce203b5f72b0c" datatype="html">
+ <source>Please expand your cluster first</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2195fd96b0a00f560449b50bd032e6d9b357730" datatype="html">
+ <source>Expand Cluster</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb075d0450deb6f381616f7da4b9244ced843053" datatype="html">
+ <source>Skip</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55b6ce65571b8893440a4fc92776570f8fe7cc97" datatype="html">
+ <source>Add Hosts</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="162f763675c24b557a60eba0758558222369e0c7" datatype="html">
+ <source>Create OSDs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fef7a7b8db05c351c5287db48488abca530bdb54" datatype="html">
+ <source>Create Services</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="176873b4533ddeabf95992cbd7b91b9d01c6d557" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ed90ec4409b9f6b552982d96f89db27259e763c" datatype="html">
+ <source>You are about to skip the cluster expansion process. You’ll need to <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>navigate through the menu to add hosts and services.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">90,91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d1dcf2a9146caac0581329acf94806ec69a89a5" datatype="html">
+ <source>Are you sure you want to continue?</source>
+ <target>Anda yakin ingin melanjutkan?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6759205696902713848" datatype="html">
+ <source>Warning</source>
+ <target>Peringatan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">357</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6962699013778688473" datatype="html">
+ <source>Continue</source>
+ <target>Lanjutkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6156560100092571435" datatype="html">
+ <source>Cluster expansion skipped by user</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520085823873354736" datatype="html">
+ <source>Cluster expansion was successful</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176230351113290618" datatype="html">
+ <source>Expand Cluster</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="738de688b22fba5d0dc7a5e549996838dddad0ee" datatype="html">
+ <source>CRUSH map viewer</source>
+ <target>Penampil peta CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/crushmap/crushmap.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e24569eca61d598c8b01defbbbb1fa8bd5222bc" datatype="html">
+ <source>Devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17137bac47e1e020d139256ded0006a671966e73" datatype="html">
+ <source>Physical Disks</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="deba10b7279a589d01e919ea11f43c79ca1773e3" datatype="html">
+ <source>Device health</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d87fc20ea8e5f0f0500ba5d5061b345be78ec5e" datatype="html">
+ <source>No hostname found.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9a541ec1a4319fffc16ad3b3ab2c2b6d251a829d" datatype="html">
+ <source>Hostname</source>
+ <target>Nama hos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee6875e67b53cac30a02b57cf76e485f7e60caf4" datatype="html">
+ <source>To add multiple hosts at once, you can enter:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a8370b19ccf673fb28fa9db36a08f9901887cc7" datatype="html">
+ <source>a comma-separated list of hostnames <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-01,example-02,example-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="68f2c05396ec8a5f59e8da42d1f6c7310fa8c37c" datatype="html">
+ <source>a range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e00b9bba448e79add37740e53dc953fbb89f9c5" datatype="html">
+ <source>a comma separated range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b3f5e5291541678f7afa49d28fad5ca848a8061" datatype="html">
+ <source>The chosen hostname is already in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="42365f623c57973d1d13d2038e8a2d4c02fb9b9f" datatype="html">
+ <source>Network address</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3859bdca1ae89e611e214c205fccf0147b4d0f6b" datatype="html">
+ <source>The value is not a valid IP address.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2af7efecfae8d7fed3b07f718a623eca1ad8163f" datatype="html">
+ <source>Labels</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9da2afd4fa358b66d4d95fe7e8f4b659a7144e" datatype="html">
+ <source>Maintenance Mode</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="468785112451259935" datatype="html">
+ <source>There are no labels.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4664081995078497865" datatype="html">
+ <source>Filter or add labels</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4897817053917542646" datatype="html">
+ <source>Add label</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">313</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1187321380561233505" datatype="html">
+ <source>host</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40661476cb24c89d8b06614998e31d5fbe84eeb6" datatype="html">
+ <source>Hosts List</source>
+ <target>Daftar Hos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b7a4e1e5a316f8547af1d6d2311a5cec8c5c1d87" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ msg }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6e8e8844e9e7a7b626a4699c08b6c0c81297a7b" datatype="html">
+ <source>Data will be available only if Orchestrator is available.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4baf526199fed59071adf555271791283adc408" datatype="html">
+ <source>SSD, NVMEs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="22d5531d79f0d7269a0a752e56a848807dd37095" datatype="html">
+ <source>Flash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4025065730478477779" datatype="html">
+ <source>The feature is disabled because the selected host is not managed by Orchestrator.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7143579180750436311" datatype="html">
+ <source>Services</source>
+ <target>Layanan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="546766753072101168" datatype="html">
+ <source>Labels</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1141886420788473147" datatype="html">
+ <source>Model</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4027647877328291519" datatype="html">
+ <source>CPUs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2445398473573060226" datatype="html">
+ <source>Cores</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1656823484917332451" datatype="html">
+ <source>Total Memory</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1939212557812454069" datatype="html">
+ <source>Raw Capacity</source>
+ <target>Kapasitas mentah</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5579687933271468638" datatype="html">
+ <source>HDDs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1889285841762768492" datatype="html">
+ <source>Flash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1578709829957887527" datatype="html">
+ <source>NICs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4723031838495967601" datatype="html">
+ <source>Edit Host: <x id="PH" equiv-text="host.hostname"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6004907173026319041" datatype="html">
+ <source>Edit Host</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5618131051466022401" datatype="html">
+ <source>Updated Host &quot;<x id="PH" equiv-text="host.hostname"/>&quot;</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1701954433367210342" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; moved to maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3108406586869160854" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; cannot be put into maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1737753151350322492" datatype="html">
+ <source><x id="PH" equiv-text="error.error['detail']"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4054533801359952167" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; has exited maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5837599005212786659" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; stopped draining</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1357236071975782353" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; started draining</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5658400717636093668" datatype="html">
+ <source>Identify</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6966707768479328825" datatype="html">
+ <source>Device path</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3955868613858648955" datatype="html">
+ <source>Available</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="158816374076721379" datatype="html">
+ <source>Vendor</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6024104799101504292" datatype="html">
+ <source>OSDs</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3422162477846071958" datatype="html">
+ <source>Identify device <x id="PH" equiv-text="device"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4910073658089977244" datatype="html">
+ <source>Please enter the duration how long to blink the LED.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5764931367607989415" datatype="html">
+ <source>1 minute</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809466133764752509" datatype="html">
+ <source>2 minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">235</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1487672983218679675" datatype="html">
+ <source>5 minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603584938775296395" datatype="html">
+ <source>10 minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6648333117195452824" datatype="html">
+ <source>15 minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6560281329999108838" datatype="html">
+ <source>Execute</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6901229416977800100" datatype="html">
+ <source>Identifying '<x id="PH" equiv-text="device"/>' started on host '<x id="PH_1" equiv-text="hostname"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d556ab48a65722b400e497f61737f553ee0f89e2" datatype="html">
+ <source>Cluster Logs</source>
+ <target>Log Klaster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5f966baffd188be0e8adc2d7067b86e55fc9b9de" datatype="html">
+ <source>Audit Logs</source>
+ <target>Log Audit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4193c9eb868aeec119b78a14795241e0aa5e8b60" datatype="html">
+ <source>Priority:</source>
+ <target>Prioritas:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d78ca51eab260ce3fd917d39190d64df5229b6e" datatype="html">
+ <source>Keyword:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="05fa0bded36de6e73a1fa44838b627349dace044" datatype="html">
+ <source>Date:</source>
+ <target>Tanggal:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a400388de1899b1917138cf7e5286376f72847" datatype="html">
+ <source>Time range:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="de0478286b8b5a939db54e9e5282405364ad2d61" datatype="html">
+ <source>No log entries found. Please try to select different filter options.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7479674d91142b785b9547a87e5fb51cb16108" datatype="html">
+ <source>Reset filter.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="31a9c2870a934b594d1390146c489f76440859ea" datatype="html">
+ <source>Edit Manager module</source>
+ <target>Edit modul Ceph Manajer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="46e09b8290d3d0afdb6baa2021395b0570606a31" datatype="html">
+ <source>The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</source>
+ <target>Nilai yang dimasukkan bukan UUID yang valid, cth: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7aacd038b39cfd347107d01d1dc27f5cb3e0951c" datatype="html">
+ <source>The entered value needs to be a valid IP address.</source>
+ <target>Nilai yang dimasukkan harus alamat IP yang valid.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f19106149f4b07a0d721f9d317afed393cb7bd93" datatype="html">
+ <source>The entered value is too high! It must be lower or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d33c40ef9a6c3bf0888df831b25e41e65f9d15b" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eae7086660cf1e38c7194a2c49ff52cc656f90f5" datatype="html">
+ <source>The entered value needs to be a number.</source>
+ <target>Nilai yang dimasukkan harus berupa angka.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">194</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a73376e04b4fb3a20734c8c39743fba32e6676ce" datatype="html">
+ <source>The entered value needs to be a number or decimal.</source>
+ <target>Nilai yang dimasukkan harus berupa angka atau desimal.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1898719236268328097" datatype="html">
+ <source>Updated options for module '<x id="PH" equiv-text="this.moduleName"/>'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4186041075388034600" datatype="html">
+ <source>Always-On</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7585826646011739428" datatype="html">
+ <source>Edit</source>
+ <target>Edit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2180291763949669799" datatype="html">
+ <source>Enable</source>
+ <target>Aktifkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9187855490716817910" datatype="html">
+ <source>Disable</source>
+ <target>Nonaktifkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1600086764852993170" datatype="html">
+ <source>This Manager module is always on.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3895296744591223546" datatype="html">
+ <source>Reconnecting, please wait ...</source>
+ <target>Menghubungkan kembali, mohon tunggu...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81b97b8ea996ad1e4f9fca8415021850214884b1" datatype="html">
+ <source>Status</source>
+ <target>Status</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57ec6032f5618d4a9f16eb950ad23d2ce7c24b54" datatype="html">
+ <source>Cluster ID</source>
+ <target>ID Klaster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67d7facc3fec5f8a49ab9ba0a245872184264ce5" datatype="html">
+ <source>monmap modified</source>
+ <target>monmap diubah</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4906731aaf2b94b4f547646c9bfe58bb77951b6" datatype="html">
+ <source>monmap epoch</source>
+ <target>monmap epoch</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd4ee06ffdc46d9dfbd0c0c4f81399021c680056" datatype="html">
+ <source>quorum con</source>
+ <target>kuorum con</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1176c7db8a8276ccb44cc3d42e2c28d9fa6c6596" datatype="html">
+ <source>quorum mon</source>
+ <target>kuorum mon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="530ef677a09d681b3ab68cb0760494b3ae72a77c" datatype="html">
+ <source>required con</source>
+ <target>con yang dibutuhkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a91558e0d506c32021c31843f8f168899fc65cbf" datatype="html">
+ <source>required mon</source>
+ <target>mon yang dibutuhkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3abe9eac5bcd94a54c8da93b312e085ec512e74" datatype="html">
+ <source>In Quorum</source>
+ <target>Memenuhi Kuorum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba4b748a676e1f217ce1e736fb7ec1215e677bae" datatype="html">
+ <source>Not In Quorum</source>
+ <target>Tidak dalam Kuorum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3517477838460618200" datatype="html">
+ <source>Public Address</source>
+ <target>Alamat Publik</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6949358970125514744" datatype="html">
+ <source>Open Sessions</source>
+ <target>Buka Sesi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4383e9662ea19839c7499b2128d43a195e564317" datatype="html">
+ <source>OSD creation preview</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="366225c51e0b00bcb1c55795a0dc5e81c455f84e" datatype="html">
+ <source>DriveGroups</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91853167141c37b58868f3b0421383dd72fa8a01" datatype="html">
+ <source>Attributes (OSD map)</source>
+ <target>Atribut (peta OSD)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f721a500a68c357e8f2a01e60510f6a01e4ba529" datatype="html">
+ <source>Metadata</source>
+ <target>Metadata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97842f379e1d4157ac3ab0661b90c352e7cb72d5" datatype="html">
+ <source>Metadata not available</source>
+ <target>Metadata tidak tersedia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24e28e19c5703d7c6be44f4eb595a6a43b618ed" datatype="html">
+ <source>Performance counter</source>
+ <target>Penghitung kinerja</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ccb4f84edc0b4e76415bb3f9b73d725b06683af3" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ name }}"/> devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60cb3d01e5ddf266ecb4271007a1c3d0f3efdc22" datatype="html">
+ <source>The primary storage devices. These devices contain all OSD data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b432e04886d0d1fd84f740477383051f85addcf2" datatype="html">
+ <source>Write-Ahead-Log devices. These devices are used for BlueStore’s internal journal. It is only useful to use a WAL device if the device is faster than the primary device (e.g. NVME devices or SSDs). If there is only a small amount of fast storage available (e.g., less than a gigabyte), we recommend using it as a WAL device.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87e181ab9e8393aa5ed759dd3d53836e32c8ffe" datatype="html">
+ <source>DB devices can be used for storing BlueStore’s internal metadata. It is only helpful to provision a DB device if it is faster than the primary device (e.g. NVME devices or SSD).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
+ <source>Add</source>
+ <target>Tambah</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="99ee4faa69cd2ea8e3678c1f557c0ff1f05aae46" datatype="html">
+ <source>Clear</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e0fd3c7af0630f93befa6234a693a32a61084e0" datatype="html">
+ <source>Raw capacity: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1961811273151129466" datatype="html">
+ <source>No available devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617271647728055571" datatype="html">
+ <source>Please add primary devices first</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6368751795251107516" datatype="html">
+ <source>Add devices by using filters</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8edc89137d0d8c5667a2f03230beafae45e58429" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eba28e1805b18f7c8ae2e4bc15dcf063b10b3822" datatype="html">
+ <source>At least one of these filters must be applied in order to proceed:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="93389aa2fe2bea50bf89554ee51b28f87ee2fb50" datatype="html">
+ <source>Number of devices: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Raw capacity: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">29,30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6b27c16ddf33b855412c82069dca8120bd3a68a" datatype="html">
+ <source>Individual OSD Flags</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dba0ed9ba355a3bd3296c0bef3bb518744a51a89" datatype="html">
+ <source>Cluster-wide</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e2a3f211cea2cbadb29b6df93e544440b6b68d3e" datatype="html">
+ <source>Restore previous selection</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1683654169791509804" datatype="html">
+ <source>No Up</source>
+ <target>Tidak Nyala</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5754783193519044074" datatype="html">
+ <source>OSDs are not allowed to start</source>
+ <target>OSD tidak diizinkan menyala</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4413588319909369773" datatype="html">
+ <source>No Down</source>
+ <target>Tidak Mati</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1348746748821823470" datatype="html">
+ <source>OSD failure reports are being ignored, such that the monitors will not mark OSDs down</source>
+ <target>Laporan kegagalan OSD sedang diabaikan sehingga monitor tidak akan menandai OSD mati</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="301172600132606646" datatype="html">
+ <source>No In</source>
+ <target>Tidak boleh Masuk</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4114057962148673377" datatype="html">
+ <source>OSDs that were previously marked out will not be marked back in when they start</source>
+ <target>OSD yang telah ditandai keluar tidak akan ditandai masuk saat mereka menyala</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5236523991485603657" datatype="html">
+ <source>No Out</source>
+ <target>Tidak boleh Keluar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1798160169020638994" datatype="html">
+ <source>OSDs will not automatically be marked out after the configured interval</source>
+ <target>OSD tidak akan otomatis ditandai keluar setelah interval dikonfigurasi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3225813593817914267" datatype="html">
+ <source>The flag has been enabled for the entire cluster.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1941050626944682985" datatype="html">
+ <source>Updated OSD Flags</source>
+ <target>Flag OSD diperbarui</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ef50ba2514414f799d4c8fc36067a251904ba81" datatype="html">
+ <source>Cluster-wide OSD Flags</source>
+ <target>Flag OSD Klaster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9042260521669277115" datatype="html">
+ <source>Pause</source>
+ <target>Jeda</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6015425610572318971" datatype="html">
+ <source>Pauses reads and writes</source>
+ <target>Jeda baca dan tulis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314873595759611676" datatype="html">
+ <source>No Scrub</source>
+ <target>Nonaktifkan Scrub</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773570234687653570" datatype="html">
+ <source>Scrubbing is disabled</source>
+ <target>Scrubbing dinonaktifkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5999821123886006899" datatype="html">
+ <source>No Deep Scrub</source>
+ <target>Nonaktifkan Deep Scrub</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5362685148875251772" datatype="html">
+ <source>Deep Scrubbing is disabled</source>
+ <target>Deep Scrubing dinonaktifkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5001752039592388485" datatype="html">
+ <source>No Backfill</source>
+ <target>Tidak ada Penambalan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4851280330655956778" datatype="html">
+ <source>Backfilling of PGs is suspended</source>
+ <target>Penambalan PG dihentikan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5994953210305546559" datatype="html">
+ <source>No Rebalance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3698980403470604587" datatype="html">
+ <source>OSD will choose not to backfill unless PG is also degraded</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4334886823145076432" datatype="html">
+ <source>No Recover</source>
+ <target>Tidak ada Pemulihan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8465994741155792816" datatype="html">
+ <source>Recovery of PGs is suspended</source>
+ <target>Pemulihan PG dihentikan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4052740759486923001" datatype="html">
+ <source>Bitwise Sort</source>
+ <target>Urutan Bitwise</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2330377428425572488" datatype="html">
+ <source>Use bitwise sort</source>
+ <target>Gunakan urutan bitwise</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8943478424576832224" datatype="html">
+ <source>Purged Snapdirs</source>
+ <target>Buang Snapdirs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7553321860087551262" datatype="html">
+ <source>OSDs have converted snapsets</source>
+ <target>OSD memiliki snapset yang dikonversi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6509988280998256208" datatype="html">
+ <source>Recovery Deletes</source>
+ <target>Pulihkan yang telah dihapus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="451760144355116641" datatype="html">
+ <source>Deletes performed during recovery instead of peering</source>
+ <target>Penghapusan dilakukan saat pemulihan bukan saat bermitra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="87832369463084597" datatype="html">
+ <source>PG Log Hard Limit</source>
+ <target>Batas Maks Log PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9135782750879343185" datatype="html">
+ <source>Puts a hard limit on pg log length</source>
+ <target>Taruh batas maks pada panjang log pg</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="formTitle" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <note priority="1" from="description">Example: Create Pool</note>
+ <note priority="1" from="meaning">form title</note>
+ </trans-unit>
+ <trans-unit id="43ecf6bee2aebc07b0aad6dc1fe13e38d14687fa" datatype="html">
+ <source>Shared devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7a1c376f6f1b37de4c318ff2106255ba6c0f5b0b" datatype="html">
+ <source>WAL slots</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73811a6f37b63e6b0e491e221bfa21e9dea8a87a" datatype="html">
+ <source>How many OSDs per WAL device.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c67a7ac4762ef1cc855056c6b4daab93e53a0a5" datatype="html">
+ <source>Specify 0 to let Orchestrator backend decide it.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bda9362e06e6c67341b4a8425b0d29d6b84464b" datatype="html">
+ <source>Value should be greater than or equal to 0</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="324c2b10152b9dd908222bb0b71f61beb60a30c5" datatype="html">
+ <source>DB slots</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c23cf12ef9c76f37fc7a4b7ae3e00fb0f68b6e26" datatype="html">
+ <source>How many OSDs per DB device.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8255877266497322342" datatype="html">
+ <source>Encryption</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b49d7877d24112d4bdfce9256edf61a007fae888" datatype="html">
+ <source>OSDs List</source>
+ <target>Daftar OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="172ada0fcf6490b24a897517e9f4299215873ff8" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD(s) <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be marked <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">59,60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="262a49e60d5f6ed9825582ccf3d5ae39daa1da60" datatype="html">
+ <source>The <x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> not safe to be <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>! <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71,72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="74bd20d5f558d14cb2fa41ae863cf09c47d02018" datatype="html">
+ <source>{VAR_SELECT, select, true {OSD is} other {OSDs are}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0e217fd717c5b1f5c17f00c5b174de855acbef0" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">74,75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8cf121660bed7098516a1efe85831d6f415a9411" datatype="html">
+ <source>Preserve OSD ID(s) for replacement.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4435645098786961170" datatype="html">
+ <source>out</source>
+ <target>keluar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136018875175606726" datatype="html">
+ <source>in</source>
+ <target>masuk</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1301930865667956193" datatype="html">
+ <source>down</source>
+ <target>gugur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1226060325201042854" datatype="html">
+ <source>Mark</source>
+ <target>Tandai</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1256299033316818951" datatype="html">
+ <source>OSD lost</source>
+ <target>OSD hilang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2795727560928976873" datatype="html">
+ <source>marked lost</source>
+ <target>ditandai hilang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7685933846431786388" datatype="html">
+ <source>Purge</source>
+ <target>Buang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5941516286393808546" datatype="html">
+ <source>OSD</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3416443212235382421" datatype="html">
+ <source>purged</source>
+ <target>dibuang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9191368063029792986" datatype="html">
+ <source>destroy</source>
+ <target>hancurkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4425946029386289247" datatype="html">
+ <source>destroyed</source>
+ <target>dihancurkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2870788902465061969" datatype="html">
+ <source>Flags</source>
+ <target>Flag</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8995035642420075344" datatype="html">
+ <source>Recovery Priority</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3601135996773579607" datatype="html">
+ <source>PG scrub</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136079353894161076" datatype="html">
+ <source>Device class</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6382718875453721838" datatype="html">
+ <source>PGs</source>
+ <target>PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3660230483843323377" datatype="html">
+ <source>Read bytes</source>
+ <target>Bita baca</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">329</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3909578649547040612" datatype="html">
+ <source>Write bytes</source>
+ <target>Bita tulis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3182358405280886750" datatype="html">
+ <source>Read ops</source>
+ <target>Ops baca</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171292502535561083" datatype="html">
+ <source>Write ops</source>
+ <target>Ops tulis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6706824709967518168" datatype="html">
+ <source>Edit OSD: <x id="PH" equiv-text="selectedOsd.id"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">451</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1125148356983553148" datatype="html">
+ <source>Edit OSD</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="970212458427610374" datatype="html">
+ <source>Updated OSD '<x id="PH" equiv-text="selectedOsd.id"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">466</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7554728686176829307" datatype="html">
+ <source>Mark OSD <x id="PH" equiv-text="markAction"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="478122291463667978" datatype="html">
+ <source>Mark <x id="PH" equiv-text="markAction"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">502</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2456043080471762298" datatype="html">
+ <source>delete</source>
+ <target>hapus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">530</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="588230151780724018" datatype="html">
+ <source>deleted</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">532</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1ef1c12ddcee305353623919ef02778569f5454" datatype="html">
+ <source>Advanced configuration options</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7771252117308888928" datatype="html">
+ <source>PG scrub options</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1797901277775175680" datatype="html">
+ <source>Updated PG scrub options</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c35f9c5f268a514b970cc55e9a5dc4bed0988e7f" datatype="html">
+ <source>OSD Recovery Priority</source>
+ <target>Prioritas pemulihan OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74af38005e8a8914e45af2ec412e11ceafef8b6" datatype="html">
+ <source>Priority</source>
+ <target>Prioritas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f48f04b379bfba133825747adfd238d511412e" datatype="html">
+ <source>Customize priority values</source>
+ <target>Ubah nilai prioritas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aa19de2a2b54cbda39e9c62917b23044c087776" datatype="html">
+ <source>This field is required!</source>
+ <target>Isian ini harus diisi!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">406</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b699e94bf376491bd50b70a98531071c737eaf40" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="98fe13e7ad6c2b80375d204b47858ded83f80e15" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423a3c111be47fc5a1bfe46ceb58c81c84db691" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3234179038052466481" datatype="html">
+ <source>Max Backfills</source>
+ <target>Maks Penambalan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847070960491384020" datatype="html">
+ <source>Recovery Max Active</source>
+ <target>Maks Pemulihan Aktif</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2088615724570210504" datatype="html">
+ <source>Recovery Max Single Start</source>
+ <target>Maks Menjalankan Pemulihan Tunggal</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8627094894361422565" datatype="html">
+ <source>Recovery Sleep</source>
+ <target>Jeda Pemulihan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7590013429208346303" datatype="html">
+ <source>Custom</source>
+ <target>Ubahsuai</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4937275625032609020" datatype="html">
+ <source>Updated OSD recovery speed priority '<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">227,229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5251a4355cece3075db43f15d69a24a0f8485707" datatype="html">
+ <source>Reweight OSD: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67650b2998db48201b2c6176cbfef51e7211ccaa" datatype="html">
+ <source>The value needs to be between 0 and 1.</source>
+ <target>Nilai harus antara 0 dan 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f077ceb52c967a8fe2de9ef0a9d65d72badf186" datatype="html">
+ <source>OSDs <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/>Scrub</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b73a34ba65b3073e3560dce828a16d7fd3c0f4" datatype="html">
+ <source>{VAR_SELECT, select, true {Deep } other {}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c00119503aad4012b77049eee41293338f67756c" datatype="html">
+ <source>You are about to apply a <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/>scrub to the OSD(s): <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fad3dc421817a16dd6c46c1a0c36de619a8d776e" datatype="html">
+ <source>{VAR_SELECT, select, true {deep } other {}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1086427836866943370" datatype="html">
+ <source><x id="PH" equiv-text="operation"/> was initialized in the following OSD(s): <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts</context>
+ <context context-type="linenumber">42,44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47c97aa28f64b11fa5842795fdd02c8c0863c97b" datatype="html">
+ <source>To see all active Prometheus alerts, please provide the URL to the API of Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6343323763459782070" datatype="html">
+ <source>Create Silence</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1895957424873987405" datatype="html">
+ <source>Job</source>
+ <target>Tugas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491474782694268231" datatype="html">
+ <source>Severity</source>
+ <target>Keparahan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3326877877555410533" datatype="html">
+ <source>Started</source>
+ <target>Dimulai</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2375260419993138758" datatype="html">
+ <source>URL</source>
+ <target>URL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="880ad4df5a2051a437321443d69c9a866699e5ad" datatype="html">
+ <source>Active Alerts</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9fe218829514884cdd0ca2300573a4e0428c324f" datatype="html">
+ <source>Alerts</source>
+ <target>Peringatan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa0c44aa1e5727061baa91e954f77e2f5f9a37c9" datatype="html">
+ <source>Silences</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85c737325f5e59517e2d08a71de6d77788aabc95" datatype="html">
+ <source>To see all configured Prometheus alerts, please provide the URL to the API of Prometheus as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623978917681527907" datatype="html">
+ <source>Group</source>
+ <target>Grup</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7410432243549869948" datatype="html">
+ <source>Duration</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4109205891084963566" datatype="html">
+ <source>Query</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28f86ffd419b869711aa13f5e5ff54be6d70731c" datatype="html">
+ <source>Edit</source>
+ <target>Edit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="826b25211922a1b46436589233cb6f1a163d89b7" datatype="html">
+ <source>Delete</source>
+ <target>Hapus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">279</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">341</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">441</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3ba06aba047605af8ea1718ec1ba153b7db12a2" datatype="html">
+ <source>Editing a silence will expire the old silence and recreate it as a new silence</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a20424156b8816671f61879f0574a4f27d7b16b9" datatype="html">
+ <source>Creator</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5a5d7ee2acbfa9c91ab7f41d26bda9ff0cafe42f" datatype="html">
+ <source>Comment</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c11aad490b2d53fdae30b3807beabf79306752c" datatype="html">
+ <source>Start time</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32856b1e8e339b747b21e313e2fe65a51fd450bb" datatype="html">
+ <source>If the start time lies in the past the creation time will be used</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a02ea1d4e7424ca989929da5e598f379940fdbf2" datatype="html">
+ <source>Duration</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f4e35e36f4d3c62e2c17df41730b6dee4afc4b9" datatype="html">
+ <source>End time</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="992123459137d45c15df5548bc9682aad835c04b" datatype="html">
+ <source>Matchers</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e023166c55833d5a13f4143e3dbe372befe1b4e" datatype="html">
+ <source>A silence requires at least one matcher</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef765bd80c4806c51c891908c07a24bc76f019eb" datatype="html">
+ <source>Add matcher</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754178820914251524" datatype="html">
+ <source>silence</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8714559758543060819" datatype="html">
+ <source>Attribute name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1338733395833138319" datatype="html">
+ <source>Regular expression</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35819898450851998" datatype="html">
+ <source>Please add your Prometheus host to the dashboard configuration and refresh the page</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f2f4cb9d876ff9d34fc082c1ac642d3cb98c360" datatype="html">
+ <source>To enable Silences, please provide the URL to the API of the Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7448808151142843482" datatype="html">
+ <source>Created by</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4734349318830134239" datatype="html">
+ <source>Ends</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1233087251567318644" datatype="html">
+ <source>Silence</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="78af6a5e6e4d305557054b64d10f9f9446d8043d" datatype="html">
+ <source>{VAR_SELECT, select, true {Edit} other {Add}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2404fa8e80946d0ce3d0ae369b51cb26ec28d42" datatype="html">
+ <source><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/> Matcher</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c25e04f554875dc2625a78ba0fc56c6010cd0d3" datatype="html">
+ <source>-- Select an attribute to match against --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5049e204c14c648691ac775a64fb504467aeb549" datatype="html">
+ <source>Value</source>
+ <target>Nilai</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="77fc5c63497fc031ddc97645484e3d94ad27766c" datatype="html">
+ <source>Use regular expression</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5518753745858598442" datatype="html">
+ <source>no spec</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1186363766752354382" datatype="html">
+ <source>unmanaged</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5246585784774990516" datatype="html">
+ <source>count:<x id="PH" equiv-text="count"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001661117318762535" datatype="html">
+ <source>label:<x id="PH" equiv-text="label"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cb3aa7e9fea1d445a1a9d7797ab17e6ac6fe13b" datatype="html">
+ <source>Service Events</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3474944817987674409" datatype="html">
+ <source>Daemon type</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3136939605470297323" datatype="html">
+ <source>Daemon ID</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8171022601808215887" datatype="html">
+ <source>Container ID</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8859473568390700297" datatype="html">
+ <source>Container Image name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5623167616584404899" datatype="html">
+ <source>Container Image ID</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="335348913532561915" datatype="html">
+ <source>Last Refreshed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3022087209429182774" datatype="html">
+ <source>Daemon Events</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">140</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8604852007710946848" datatype="html">
+ <source>Service Name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="613875387304159316" datatype="html">
+ <source>Service Type</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907644935670421963" datatype="html">
+ <source>Service Events</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3214a1f3a4c3e89a848b4ec59adeeda3b913c396" datatype="html">
+ <source>-- Select a service type --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f32579a9fd19d93c083175284ee3426d78751c33" datatype="html">
+ <source>Backend Service</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2937074aed12b8158e929c58747a8216433b72b" datatype="html">
+ <source>-- No service available --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19fb4480d95a5539db4e9c7b516d414774e61110" datatype="html">
+ <source>-- Select an existing RGW service --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2798cc1e152b1ec07fd8daf94a2a073d1ba1ebcc" datatype="html">
+ <source>Id</source>
+ <target>Id</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d5156b9d9a79d162c353c4aa9bc6840ad5c6257" datatype="html">
+ <source>The value does not match the pattern <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&lt;service_id&gt;[.&lt;realm_name&gt;.&lt;zone_name&gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83d5d7edd8a0be253c4e93ad4c3efe86d9ac520f" datatype="html">
+ <source>Unmanaged</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c15fa461935e0f600bc5d1660af1da67f024fc2a" datatype="html">
+ <source>Placement</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="863226cffd5b66a6fee9810a9282a5006d6ef576" datatype="html">
+ <source>Label</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06412bce0f4fe4311193e9763666089bf9d980da" datatype="html">
+ <source>Count</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f193722f1e788f14a823b89ac1794c3ba934f9f" datatype="html">
+ <source>Only that number of daemons will be created.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee1a29cc658e4fa891be762d7bae96139b57c8f4" datatype="html">
+ <source>The value must be at least 1.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">369</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cb2741a46e3560f6bc6dfd99d385e86b08b26d72" datatype="html">
+ <source>Port</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a23ed3598cca5285606675b6cb2536a56b411ade" datatype="html">
+ <source>The value cannot exceed 65535.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">404</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d8ebdc326e6b9ff35feee3f762b7ab39c02d78f" datatype="html">
+ <source>-- No pools available --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84b675705324741b954615fedf2417d4d873b0b6" datatype="html">
+ <source>Trusted IPs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b543e7c787cc48c2938cbce2d14c6afea5a598df" datatype="html">
+ <source>Comma separated list of IP addresses.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1039ea40da18a6453d9c1adc72a35aed099029d0" datatype="html">
+ <source>Please add the <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> IP addresses here, otherwise the iSCSI gateways can't be reached.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6265b64c17a1e19775769489bfd0b152fa1f3ba1" datatype="html">
+ <source>Virtual IP</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61893fde6e9e05a6b91619d501edaa7962b438ff" datatype="html">
+ <source>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">333</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ece04ddf7e96f445415ebd90d93c455e03e8cf53" datatype="html">
+ <source>Frontend Port</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">352</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae6fd97454d184b374984c9ff808176ece54f0dd" datatype="html">
+ <source>The port used to access the ingress service.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1261eacf161f75efc9dfea84dd97b4a466b89aa1" datatype="html">
+ <source>Monitor Port</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4df6281ed630ba96f09790a46a7fe0ec0e666bb6" datatype="html">
+ <source>The port used by haproxy for load balancer status.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ce24ae1d792ed2846ba57e7ed6397a802caeff5" datatype="html">
+ <source>CIDR Networks</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">414</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7c13184af0c09e3bad77daa5f4869138708d26b2" datatype="html">
+ <source>A list of networks to identify which network interface to use for the virtual IP address.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8fe73a4787b8068b2ba61f54ab7e0f9af2ea1fc9" datatype="html">
+ <source>Version</source>
+ <target>Versi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a6855d17f6b9820bb9709870efdcc7da99552d3" datatype="html">
+ <source>-- Select SNMP version --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">442</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a7369891e88cd613e45a39b55a282c97776d05f5" datatype="html">
+ <source>Destination</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f09a5d334a73a4b5ba031d7fa65151cad5ec7133" datatype="html">
+ <source>Must be of the format hostname:port.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b68c79ffe3af1db88180454fbc2fa880a51ccf52" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>hostname:port<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">470</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c90ad98a026d781ab729911873767e549d78f99" datatype="html">
+ <source>Engine Id</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">478</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d39d015ebd667fb6bddf08bb0e5b3faa6cf044c" datatype="html">
+ <source>Unique identifier for the device (in hex).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">480</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514cda7dc49062c5c532427245ce47c4954bc32" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b2d628c51192ade0044212b409c758c20f9c021" datatype="html">
+ <source>Auth Protocol</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc8bb2315a5101770a752b18e03b5c730539397c" datatype="html">
+ <source>-- Select auth protocol --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">508</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6777f99fd13e03874afe26ba7289dc9fc211af04" datatype="html">
+ <source>Privacy Protocol</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70512b7c13bce85b3928920b29fafbd59a853383" datatype="html">
+ <source>-- Select privacy protocol --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b48c81465d14465b95826b99e05acfabef1814c6" datatype="html">
+ <source>Credentials</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">541</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4ea0163c25c818aab982072b1b8d5ab585e9a5a" datatype="html">
+ <source>SNMP Community</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">547</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="08c74dc9762957593b91f6eb5d65efdfc975bf48" datatype="html">
+ <source>Username</source>
+ <target>Nama pengguna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="948758e1412bb2ecdb98e3a4f1cbb6d7458456f2" datatype="html">
+ <source>Encryption</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">598</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e65610b5d940367f1ff6b57772b96e94e35fe202" datatype="html">
+ <source>SSL</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">624</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e37e0d06148c7708e88b4a1eb412babbe1a4afc" datatype="html">
+ <source>Certificate</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">634</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="295ae4f632322098deca8a3ddfbc7aeaabb5423b" datatype="html">
+ <source>The SSL certificate in PEM format.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">635</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464272c069fe56f6c50f41f426a25b2a42c95ba5" datatype="html">
+ <source>Invalid SSL certificate.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">650</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0596d06bf1f8a15d4bfe56226971ecdd78013b1f" datatype="html">
+ <source>Private key</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">659</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ded15dc55104994c0230189f34dff84a4955aafb" datatype="html">
+ <source>The SSL private key in PEM format.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">660</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19bdc1597d815b456793ff87c89af4257a85a103" datatype="html">
+ <source>Invalid SSL private key.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">675</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3356018487523380058" datatype="html">
+ <source>service</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2412938991511187011" datatype="html">
+ <source>There are no hosts.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2594503755408511486" datatype="html">
+ <source>Filter hosts</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5869780110608474933" datatype="html">
+ <source>Placement</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2956098160626271284" datatype="html">
+ <source>Running</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="013f48ee777d2e53e2bcba36e1a99fcbb7ef8cb6" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report configuration</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a09b723a928774bff707973c99999dcf3d84a349" datatype="html">
+ <source>The telemetry module sends anonymous data about this Ceph cluster back to the Ceph developers to help understand how Ceph is used and what problems users may be experiencing.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> This data is visualized on <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>public dashboards<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> that allow the community to quickly see summary statistics on how many clusters are reporting, their total capacity and OSD count, and version distribution trends.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> The data being reported does <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>not<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> contain any sensitive data like pool names, object names, object contents, hostnames, or device serial numbers. It contains counters and statistics on how the cluster has been deployed, the version of Ceph, the distribution of the hosts and other parameters which help the project to gain a better understanding of the way Ceph is used. The data is sent secured to <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> and <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (device report).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">14,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c95505b5a74151a0c235b19b9c41db7983205ba7" datatype="html">
+ <source>Deactivate</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19" datatype="html">
+ <source>Channels</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e25b17c0b4ef361b6a05aaec2bbd2b7e86680458" datatype="html">
+ <source>The telemetry report is broken down into several &quot;channels&quot;, each with a different type of information that can be configured below.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">32,33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380ab580741bec31346978e7cab8062d6970408d" datatype="html">
+ <source>Basic</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd898057f0add35258a5fb5c90d792c5e2147452" datatype="html">
+ <source>Includes basic information about the cluster:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da213e9ba8a86b453d04f794f58c9803f7b062b1" datatype="html">
+ <source>Capacity of the cluster</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d5fe31d9e13239bdd223d0bbd289a1b1903e86" datatype="html">
+ <source>Number of monitors, managers, OSDs, MDSs, object gateways, or other daemons</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a3eb7834b4baf412f8863d14883972897d9acb7" datatype="html">
+ <source>Software version currently being used</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34881ae65482ffa74ccb4043fb2622e48ed146d5" datatype="html">
+ <source>Number and types of RADOS pools and CephFS file systems</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="696f8f5ea7a9cf6125b9a3af160981fda363552d" datatype="html">
+ <source>Names of configuration options that have been changed from their default (but not their values)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34292940316300d09abe5e675d452fae199f626b" datatype="html">
+ <source>Crash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7620e332b7dea1e832158e85847255eb4d9e6bbc" datatype="html">
+ <source>Includes information about daemon crashes:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1aa4306a6e840fe35b70c9b07d38ce85f281cfa" datatype="html">
+ <source>Type of daemon</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4f2cbedb4b14b68bc9f390e3391445c1b6682da" datatype="html">
+ <source>Version of the daemon</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d62603cdc75645ea873fc8f7f69c32b5f4a2aa9" datatype="html">
+ <source>Operating system (OS distribution, kernel version)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84facf84a73631d66e9a4e0bc1c40097b9d14742" datatype="html">
+ <source>Stack trace identifying where in the Ceph code the crash occurred</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea64d4177bd648e1a20c92669e6857762b811d8c" datatype="html">
+ <source>Device</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4bc37bcbbcea881a269b4063b3d93dec8ee67d5" datatype="html">
+ <source>Includes information about device metrics like anonymized SMART metrics.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37de70e8ba539187d0171a38dad2a63c323096eb" datatype="html">
+ <source>Ident</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b126025440f118cd02ce78362d61a5001c27617" datatype="html">
+ <source>Includes user-provided identifying information about the cluster:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62c6e9aecff7e04ef7d36fdee4ab4fb285a7a2b5" datatype="html">
+ <source>Contact Information</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61ba9a84051b3f470122e59cf5a746552b378269" datatype="html">
+ <source>Submitting any contact information is completely optional and disabled by default.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34746fb1c7f3d2194d99652bdff89e6e14c9c4f4" datatype="html">
+ <source>Contact</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="632cac1e025b77b2d77fed16ad22a410ddacab9e" datatype="html">
+ <source>My first Ceph cluster</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3a58c8a81b9ffda26a154eae25a422c9f7de37b" datatype="html">
+ <source>Organization</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e8fda44e2c5bb51860f26cd9c2730f9ae1db9869" datatype="html">
+ <source>Organization name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d49310535abb3792d8c9c991dd0d990d73d29af" datatype="html">
+ <source>Interval</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91317562c9dfefbdd5973faf11d217f571d073c7" datatype="html">
+ <source>The module compiles and sends a new report every 24 hours by default. You can adjust this interval by setting a different number of hours.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">185,186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a12cf4cf71ef3161a024382ab542cf0eba094504" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to 8.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a92e437fac14b4010c4515b31c55a311d026a57f" datatype="html">
+ <source>Proxy</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6de03357358c7eff62aca486508bb5c2046e0669" datatype="html">
+ <source>If the cluster cannot directly connect to the configured telemetry endpoint (default telemetry.ceph.com), you can configure a HTTP/HTTPS proxy server by e.g. adding https://10.0.0.1:8080</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5687a733af051bfca97dbffba282e39fbb9b8c8f" datatype="html">
+ <source>You can also include a user:pass if needed e.g. https://ceph:telemetry@10.0.0.1:8080</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e6430c68df43ea65e4145972b01186fba40f26a" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Note:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> By clicking 'Next' you will first see a preview of the report content before you can activate the automatic submission of your data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">219,220</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d8d878f8d60905e1306c225716305a331b784c8" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report preview</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e23d0064b6474f309c74e1c928cc0920f479d9a5" datatype="html">
+ <source>Report ID <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">249,252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4060e92658964e356a0992a900c8aa811c2cfec0" datatype="html">
+ <source>A randomized UUID to identify a particular cluster over the course of several telemetry reports.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60900bc663571f852a04950a123508b106d97204" datatype="html">
+ <source>Report preview <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">267,270</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3de417f739c336284c42904552e81e8d852daecc" datatype="html">
+ <source>The actual telemetry data that will be submitted.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="933a2b6f087670ff42c95876e6ecfb2faa3e3867" datatype="html">
+ <source>I agree to my telemetry data being submitted under the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Community Data License Agreement - Sharing - Version 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">304</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8293060085588842566" datatype="html">
+ <source>The Telemetry module has been configured and activated successfully.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5380636888677486786" datatype="html">
+ <source>An Error occurred while updating the Telemetry module configuration. Please Try again</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2bcd3296d2850de762fb943060b7e086a893181" datatype="html">
+ <source>Health</source>
+ <target>Kesehatan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61e0f26d843eec0b33ff475e111b0c2f7a80b835" datatype="html">
+ <source>Statistics</source>
+ <target>Statistik </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73caac4265ea7314ff061e5a1d78a6361a6dd3b8" datatype="html">
+ <source>Cluster Status</source>
+ <target>Status Klaster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="624f596cc3320f5e0a0d7c7346c364e5af9bdd8c" datatype="html">
+ <source>Monitors</source>
+ <target>Monitor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9183778f2c6473d7ccb080f651caa01faaf70c" datatype="html">
+ <source>OSDs</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c34287a0423968dac8a41463b80855a0ff789403" datatype="html">
+ <source>Managers</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="946ac5dea9921dc09d7b0a63b89535371f283b19" datatype="html">
+ <source>Object Gateways</source>
+ <target>Gerbang Objek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff03fa5bcf37c4da46ad736c1f7d03f959e8ba9a" datatype="html">
+ <source>Metadata Servers</source>
+ <target>Server Metadata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d817609ba4993eba859409ab71e566168f4d5f5a" datatype="html">
+ <source>iSCSI Gateways</source>
+ <target>Gateway iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ce9dfdc6dccb28dc75a78c704e09dc18fb02dcfa" datatype="html">
+ <source>Capacity</source>
+ <target>Kapasitas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f383269db2d32cccee9e936fe549dccb9fdbf4" datatype="html">
+ <source>Raw Capacity</source>
+ <target>Kapasitas mentah</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498a109c6e9e94f1966de01aa0326f7f0ac6fb52" datatype="html">
+ <source>PG Status</source>
+ <target>Status PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5f8a813f91a11af99132e4beafc136cfc13d73b" datatype="html">
+ <source>PGs per OSD</source>
+ <target>PG per OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32efd1c3f70e3c5244239de97a2cc95d98534a14" datatype="html">
+ <source>Client Read/Write</source>
+ <target>Baca/Tulis Klien</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="52213660b2454d139ada3079a42ec6caf3c3c01e" datatype="html">
+ <source>Client Throughput</source>
+ <target>Throughput Pengguna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="275485415092cbae3a9f3cbb786ebe283cacfdd5" datatype="html">
+ <source>Recovery Throughput</source>
+ <target>Throughput Pemulihan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35416fcdf9cb33d2b299d3f2028c390454b55d02" datatype="html">
+ <source>Scrubbing</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="44ecac93d67c6a671198091c2270354f80322327" datatype="html">
+ <source><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> See <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>Logs<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for more details.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520247697658334435" datatype="html">
+ <source>Reads</source>
+ <target>Baca</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5947645586591788199" datatype="html">
+ <source>/s</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7527163811128350993" datatype="html">
+ <source>Writes</source>
+ <target>Tulis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7684088941299429132" datatype="html">
+ <source>IOPS</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81585474102700882" datatype="html">
+ <source>Used</source>
+ <target>Terpakai</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">179</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8695656831075719969" datatype="html">
+ <source>Avail.</source>
+ <target>Tersedia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6352596107300820129" datatype="html">
+ <source>Clean</source>
+ <target>Bersih</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4016774570903735270" datatype="html">
+ <source>Working</source>
+ <target>Bekerja</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4467323362722952678" datatype="html">
+ <source>Unknown</source>
+ <target>Tidak diketahui</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">218</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7790772795962334429" datatype="html">
+ <source>Healthy</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4708847204147472247" datatype="html">
+ <source>Misplaced</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3120522496446378904" datatype="html">
+ <source>Degraded</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8047698491745405137" datatype="html">
+ <source>Unfound</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81117556780777231" datatype="html">
+ <source>objects</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795e8a00db46b750113d5db93e8d97e2b3079894" datatype="html">
+ <source>For an overview of <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/> widgets click <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">21,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16bd21c1b48036d54c6a595f5cff2540cfba7f60" datatype="html">
+ <source>here</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8515973702474791807" datatype="html">
+ <source>up</source>
+ <target>nyala</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4223604072115719661" datatype="html">
+ <source>no filesystems</source>
+ <target>tidak ada filesistem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2078241808113697591" datatype="html">
+ <source>active</source>
+ <target>aktif</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3232506912392089107" datatype="html">
+ <source>standby</source>
+ <target>siaga</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576716133013765863" datatype="html">
+ <source>standby daemons</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3629620351427988554" datatype="html">
+ <source>active daemon</source>
+ <target>daemon aktif</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5954854563228355745" datatype="html">
+ <source>standbyReplay</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7329683463736701292" datatype="html">
+ <source>n/a</source>
+ <target>n/a</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/not-available.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8271970016544066882" datatype="html">
+ <source><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (quorum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mon-summary.pipe.ts</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6489441800790477240" datatype="html">
+ <source>total</source>
+ <target>total</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5965118847182332588" datatype="html">
+ <source>near full</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="268166731974484199" datatype="html">
+ <source>full</source>
+ <target>penuh</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47116253e36f4e38a97ba41b2d3122c6c15ab904" datatype="html">
+ <source>Clients (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5159814115056353668" datatype="html">
+ <source>Addresses</source>
+ <target>Alamat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1811797298582428088" datatype="html">
+ <source>Access Type</source>
+ <target>Tipe Akses</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3575940435199094878" datatype="html">
+ <source>Squash</source>
+ <target>Squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2944102521023817891" datatype="html">
+ <source>Cluster</source>
+ <target>Klaster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91772203889648189" datatype="html">
+ <source>NFS Protocol</source>
+ <target>Protokol NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907766170797643122" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1032539711043211945" datatype="html">
+ <source>Transport</source>
+ <target>Transport</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2489852208080013495" datatype="html">
+ <source>Storage Backend</source>
+ <target>Backend Penyimpanan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8440421106569981118" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4095248496892792741" datatype="html">
+ <source>CephFS User</source>
+ <target>Pengguna CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2535727951299201687" datatype="html">
+ <source>CephFS Filesystem</source>
+ <target>Filesistem CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2169401160512036026" datatype="html">
+ <source>Security Label</source>
+ <target>Label Keamanan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3671149880069127721" datatype="html">
+ <source>Object Gateway</source>
+ <target>Gerbang Objek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1643028261508790" datatype="html">
+ <source>Object Gateway User</source>
+ <target>Pengguna Gerbang Objek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2dae0bda66f6a349444951c0379c28cda47d6d1" datatype="html">
+ <source>Any client can access</source>
+ <target>Semua klien dapat mengakses</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7882f2edb1d4139800b276b6b0bbf5ae0b2234ef" datatype="html">
+ <source>Addresses</source>
+ <target>Alamat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f3f74c0f6925826cb2188576391c0da01a23f0" datatype="html">
+ <source>Must contain one or more comma-separated values</source>
+ <target>Harus mengandung satu atau lebih nilai yang dipisahkan koma</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb5b2073697f3f4378c44a49b7524934c9268f4" datatype="html">
+ <source>For example:</source>
+ <target>Contoh:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f969c655b3fbe4fba7e277caf4cd2c459f9fca5" datatype="html">
+ <source>Access Type</source>
+ <target>Tipe Akses</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28952831a284cfe2b4fc39ca610e80b52598905a" datatype="html">
+ <source>Squash</source>
+ <target>Squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0660ae339068979854ade34a96546980723dede3" datatype="html">
+ <source>Add clients</source>
+ <target>Tambah klien</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8571141481686087364" datatype="html">
+ <source>(inherited from global config)</source>
+ <target>(diturunkan dari konfig global)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3563954518111128118" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- Pilih tipe akses --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3802199399355755843" datatype="html">
+ <source>inherited from global config</source>
+ <target>diturunkan dari konfig global</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8729531250118136719" datatype="html">
+ <source>-- Select what kind of user id squashing is performed --</source>
+ <target>-- Pilih jenis squashing id pengguna yang akan dilakukan --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4d1dd59b039ad818d9da7e29a773e10e41d9821" datatype="html">
+ <source>Cluster</source>
+ <target>Klaster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="625f8f0f3e5b7c92651606d77484ff3d07b3c12b" datatype="html">
+ <source>This is the ID of an NFS Service.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="135b91a2d908d5814b782695470a6a786c99d9d2" datatype="html">
+ <source>-- No cluster available --</source>
+ <target>-- Klaster tidak tersedia --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c501dba379f566885919240ea277b5bc10c14d18" datatype="html">
+ <source>-- Select the cluster --</source>
+ <target>-- Pilih klaster --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7bd3ad665c398c7fe97230ab59e67370653a82" datatype="html">
+ <source>This field is required. To create a new NFS cluster, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>add a new NFS Service<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">41,43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3f6ba7fe84d6508705cdfe234f0fcc8ff85c9cf" datatype="html">
+ <source>Storage Backend</source>
+ <target>Backend Penyimpanan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6fee356d1db954255a56d8169405a89595246b9" datatype="html">
+ <source>-- Select the storage backend --</source>
+ <target>-- Pilih backend penyimpanan --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3c2793dd2ef56954f872142d5ec1becb84c0fe1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="796e42bec8a6996607cf1f3e80235b86d695804a" datatype="html">
+ <source>Volume</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee3ba0ab5f0ccd597b3e44021c71e9aaad14df0a" datatype="html">
+ <source>-- No CephFS filesystem available --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="764c57812558b1ae66c5eec95d7efd2b1bf761e3" datatype="html">
+ <source>-- Select the CephFS filesystem --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="957512d0321f73e9f115bce1bd823fa635170c41" datatype="html">
+ <source>Security Label</source>
+ <target>Label Keamanan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="65ce0fa4da1ed55e658aeb31d1644a29f06bb342" datatype="html">
+ <source>Enable security label</source>
+ <target>Aktifkan label keamanan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e808f804130c7b6ff719509cbc06ebb27393a48" datatype="html">
+ <source>CephFS Path</source>
+ <target>CephFS Path</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1338c2f83e49ea7f2fc04e9fe90c5d330b7a10f" datatype="html">
+ <source>A path in a CephFS file system.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ecc0107badb6625466aaa3f975b5c05276f432f" datatype="html">
+ <source>Path need to start with a '/' and can be followed by a word</source>
+ <target>Lintasan atau path harus dimulai dengan '/' dan diikuti dengan kata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f9d8bd873c34c5ab2d4d0cf995fe5183ab25f6e" datatype="html">
+ <source>The path does not exist in the selected volume.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd197d7773cef10f368f08c53b47979c3df1f22d" datatype="html">
+ <source>Bucket</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ca90b4b16347ef7017967915e8624472976c85c" datatype="html">
+ <source>The bucket does not exist or is not in the default realm (if multiple realms are configured). To continue, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>create a new bucket<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bee6900143996c0e908a10564532eba3da0b30fb" datatype="html">
+ <source>NFS Protocol</source>
+ <target>Protokol NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5043c0921e709935ab026bb3253ffe1f159fca1" datatype="html">
+ <source>NFSv4</source>
+ <target>NFSv4</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d2c39708a32910f89701dd7e1cfb9ec1c195768" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1f8be2ae25947bec0b84c2338201580ea053f34e" datatype="html">
+ <source>The position that this <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> export occupies in the <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo FS<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (it must be unique).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">241,242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3af55f7fd5b1d9e5a53e030c80116dc635bfb9f" datatype="html">
+ <source>By using different Pseudo options, the same Path may be exported multiple times.</source>
+ <target>Dengan menggunakan opsi Pseudo yang berbeda, Path yang sama akan diekspor beberapa kali.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5eb719aa900fed3f9d4a1d74bcc158f07f67f684" datatype="html">
+ <source>The pseudo is already in use by another export.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddf98fcdeeb17643db020d54f42b5e56b5f9a52a" datatype="html">
+ <source>Pseudo needs to start with a '/' and can't contain any of the following: &gt;, &lt;, |, &amp;, ( or ).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="27eb35c4b4ac08781a7253a2ab40f8f7d957ba51" datatype="html">
+ <source>-- No access type available --</source>
+ <target>-- Tipe akses tidak tersedia --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">280</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="509ce016c9110a54028dafd741f15ceacbe74b5a" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- Pilih tipe akses --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67ce207d0b7eada1fe3d3187a39ba0c07be76b6c" datatype="html">
+ <source>The Object Gateway NFS backend has a number of limitations which will seriously affect applications writing to the share. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> for details before enabling write access.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">293,296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4deda03573eaaff77e63f6a238a1f0ca7816950a" datatype="html">
+ <source>-- No squash available --</source>
+ <target>-- Squash tidak tersedia --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">321</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a0e82a4da88e7fdf270444f838d45849676e9d4b" datatype="html">
+ <source>--Select what kind of user id squashing is performed --</source>
+ <target>-- Pilih jenis squashing id pengguna yang akan dilakukan --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d01b7c3f7f06712c53d054cfbe4f53d446b038e8" datatype="html">
+ <source>Transport Protocol</source>
+ <target>Protokol Transport</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2a6ad6e8bc315f07911722c05767ac79c136d99" datatype="html">
+ <source>UDP</source>
+ <target>UDP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">349</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c030f11e0aae9b24d2c048c57f29f590be621df" datatype="html">
+ <source>TCP</source>
+ <target>TCP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">359</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f84d7fd4d52eb5b2229b632ef5119dac63d5597" datatype="html">
+ <source>No user id squashing is performed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">378</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb1d148107e36852325106a518385b1b0de28835" datatype="html">
+ <source>uid 0 and gid 0 are squashed to the Anonymous_Uid and Anonymous_Gid gid 0 in alt_groups lists is also squashed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">382</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1309d6f67955799863337b201413faa61a175ddb" datatype="html">
+ <source>uid 0 and gid of any value are squashed to the Anonymous_Uid and Anonymous_Gid alt_groups lists is discarded.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85f23d5c9b57dc78dda4150d13aa3b99e985350b" datatype="html">
+ <source>All users are squashed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2691935247101074756" datatype="html">
+ <source>NFS export</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8727258243239498387" datatype="html">
+ <source><x id="PH" equiv-text="fsalItem.descr"/> backend is not available. <x id="PH_1" equiv-text="errorMessage"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2772848515253260635" datatype="html">
+ <source>Error while retrieving paths.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5239928491238988595" datatype="html">
+ <source>Error while retrieving bucket names.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="734c9905951a774870497c5aaae8e3ee833b6196" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2190548d236ca5f7bc7ab2bca334b860c5ff2ad4" datatype="html">
+ <source>Object Gateway</source>
+ <target>Gerbang Objek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca53d681a9892d6fdbb57ee9676582186515e961" datatype="html">
+ <source>Performance counters not available</source>
+ <target>Penghitung kinerja tidak tersedia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="490e15ecc922965b6d8194754c87c5583aa071f3" datatype="html">
+ <source>The name can only consist of alphanumeric characters, dashes and underscores.</source>
+ <target>Nama hanya boleh terdiri dari alfanumerik, tanda hubung, dan garis bawah.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9edc2b494e660618af3e5225f68d40b7ca67629c" datatype="html">
+ <source>The chosen erasure code profile name is already in use.</source>
+ <target>Nama profil erasure code sudah digunakan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35a4206db3105ed03e0dd799e1642b75b78123e8" datatype="html">
+ <source>Root</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf425784c7073c7e7f7c1bb90c2c19db7e751db2" datatype="html">
+ <source>Failure domain type</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72396a9565cf644d1fe1b21b790c4243ee270986" datatype="html">
+ <source>Device class</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d80e0c07bfea1b693a33ef2245007de92a6780" datatype="html">
+ <source>Let Ceph decide</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101611937243846632" datatype="html">
+ <source>Crush Rule</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef9ff0e6227947b48dfab4ac39ade04af758913b" datatype="html">
+ <source>Plugin</source>
+ <target>Plugin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd69b31bce8f630eac1d4762b0bbcf72ce19d193" datatype="html">
+ <source>Data chunks (k)</source>
+ <target>Pecahan data (k)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0d26a6172d32cb81218fe2103c54a818cbc1189" datatype="html">
+ <source>Must be equal to or greater than 2.</source>
+ <target>Harus sama dengan atau lebih dari 2.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ba6f4800642eba4e8b056aa7167554c3afa8db0" datatype="html">
+ <source>Chunks (k+m) have exceeded the available OSDs of <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="86fca2f788ce986eef835cd7ef8dfc9ae22447a4" datatype="html">
+ <source>For an equal distribution k has to be a multiple of (k+m)/l.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8dd4bc172f1adc4afadaec291e465b082909148d" datatype="html">
+ <source>K has to be equal to or greater than m in order to recover data correctly through c.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2e5b0e6d0dba31c59f946392699a0a6c4dd9b83" datatype="html">
+ <source>Distribution factor: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dab3a299ead121169b8e08ed618c3b6a2f66691b" datatype="html">
+ <source>Coding chunks (m)</source>
+ <target>Pecahan Coding (m)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e2773e5bd4948193f18f2361d663ecc3988c656" datatype="html">
+ <source>Must be equal to or greater than 1.</source>
+ <target>Harus sama dengan atau lebih dari 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">146</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cde4c945a49a260c0a47bcc7cd956846930a5f7" datatype="html">
+ <source>Durability estimator (c)</source>
+ <target>Penduga daya tahan (c)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ec9ff9931f8ea1201792d6a01bf9a47b283d692" datatype="html">
+ <source>C has to be equal to or lower than m as m defines the amount of chunks that can be used.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35594fe66657ea07b5b5f560927f78e81a229996" datatype="html">
+ <source>Helper chunks (d)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0c250a8d281291273ed3504ade19ca6537e4d9a" datatype="html">
+ <source>Set d manually or use the plugin's default calculation that maximizes d.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4304a5cd95742db0f81c3bdf29aa96bf3b0ca13d" datatype="html">
+ <source>D is automatically updated on k and m changes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06a67d52427b12df2b3d439be0e1342ac72aeb5c" datatype="html">
+ <source>D can be set from <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> to <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4f8831d3bd6401e87710c4e3ee844f5efbf5de3" datatype="html">
+ <source>D can only be set to <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5d7aacffce2c6032c3ae9ef4d1b3847a926440b" datatype="html">
+ <source>D has to be greater than k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fd745d614884edc23c7ac9ad8aba9655f3793ac2" datatype="html">
+ <source>D has to be lower than k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">199</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af668c2a095a979ea2b4e43cd82c2120ab56c21c" datatype="html">
+ <source>Locality (l)</source>
+ <target>Lokalitas (l)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="200fea08b63ae8d60cdbf33ffd2636159e87dc1e" datatype="html">
+ <source>Can't split up chunks (k+m) correctly with the current locality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319ac5d692d11da686782159bd70e0b705c228ed" datatype="html">
+ <source>Locality groups: <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">230</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d455a110bf6d2235e314e295ce1dfeee93d3dff2" datatype="html">
+ <source>Crush failure domain</source>
+ <target>Domain kegagalan Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74a495f041f7dd102eee5c0bbc9e03083b538ae" datatype="html">
+ <source>Crush Locality</source>
+ <target>Lokalitas Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2f14a73f7a6e94479f67423cc51102da8d6f524" datatype="html">
+ <source>None</source>
+ <target>Tidak ada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="363a99d62822b92913a4cce196d47f32c1258e2f" datatype="html">
+ <source>Scalar mds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2981733b912b693a9dd9d915d6d34f4692cc874a" datatype="html">
+ <source>Technique</source>
+ <target>Teknik</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0098b6e47b04ec817361f384ce81d454ba5c0bb" datatype="html">
+ <source>Packetsize</source>
+ <target>Ukuran paket</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0252cd81ca54d0a2f69ec9ccf4248e73df5aa4a" datatype="html">
+ <source>Crush root</source>
+ <target>Crush root</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">351</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1548d5c76f0406ddd1ba3c557e1e6db22e95b340" datatype="html">
+ <source>Crush device class</source>
+ <target>Kelas perangkat Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3f657ffa19dc6ac504b83c86209709522dcf065" datatype="html">
+ <source>Available OSDs: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03d84645f6e019c5a43909bbf2ea1696ee88332c" datatype="html">
+ <source>Directory</source>
+ <target>Direktori</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1354845268685595937" datatype="html">
+ <source>EC Profile</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3938a411d76796f8ae73b72ea4c77661207453bd" datatype="html">
+ <source>Cache Tiers Details</source>
+ <target>Detil Cache Bertingkat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="991790413700941336" datatype="html">
+ <source>Cache Mode</source>
+ <target>Mode Cache</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9133265273798382582" datatype="html">
+ <source>Min Evict Age</source>
+ <target>Min Waktu Usir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7172092927403263656" datatype="html">
+ <source>Min Flush Age</source>
+ <target>Min Waktu Buang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8096695869347792608" datatype="html">
+ <source>Target Max Bytes</source>
+ <target>Target Maks Bita</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8854126142886240282" datatype="html">
+ <source>Target Max Objects</source>
+ <target>Target Maks Objek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617215542453015899" datatype="html">
+ <source>No applications added</source>
+ <target>Tidak ada aplikasi ditambahkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4895689494338215646" datatype="html">
+ <source>Applications limit reached</source>
+ <target>Batas aplikasi tercapai</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7322343326526084293" datatype="html">
+ <source>A pool can only have up to four applications definitions.</source>
+ <target>Sebuah pool hanya dapat memiliki empat definisi aplikasi.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1393735257943344790" datatype="html">
+ <source>Allowed characters '_a-zA-Z0-9'</source>
+ <target>Karakter diperbolehkan '_a-zA-Z0-9'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5520683885127790121" datatype="html">
+ <source>Maximum length is 128 characters</source>
+ <target>Panjang maksimum 128 karakter</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587418377972855060" datatype="html">
+ <source>Filter or add applications'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5188881899285829380" datatype="html">
+ <source>Add application</source>
+ <target>Tambah aplikasi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16e113230b6b0d3165e076300880542bac7c8138" datatype="html">
+ <source>The chosen Ceph pool name is already in use.</source>
+ <target>Nama pool Ceph yang dipilih sudah digunakan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c75b132bef7b29fa5171768303c4b96e34ccaf68" datatype="html">
+ <source>It's not possible to create an RBD pool with '/' in the name. Please change the name or remove 'rbd' from the applications list.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">34,35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="171dc6d5c6bc4615d99778b0088cae80fd00bd10" datatype="html">
+ <source>Pool name can only contain letters, numbers, '.', '-', '_' or '/'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b85c657469e5ec8231c3de99b22f437bc01ffde5" datatype="html">
+ <source>Pool type</source>
+ <target>Jenis pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="526c5443254c3b126eedb264840ffe827727bfd3" datatype="html">
+ <source>-- Select a pool type --</source>
+ <target>-- Pilih jenis pool --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abfbe47b630929d93c7343dc154599c2e59330a" datatype="html">
+ <source>PG Autoscale</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0aa21053410a94aa61d16985a4e95fd65523430d" datatype="html">
+ <source>Placement groups</source>
+ <target>Grup penempatan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6301f1391d726f8f450bb358058534db19541ca9" datatype="html">
+ <source>At least one placement group is needed!</source>
+ <target>Dibutuhkan setidaknya satu grup penempatan!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba9469a1ce6ed36e039c1f67247c8c81a5c71449" datatype="html">
+ <source>Your cluster can't handle this many PGs. Please recalculate the PG amount needed.</source>
+ <target>Klaster Anda tidak dapat menangani PG sebanyak ini. Mohon hitung ulang jumlah PG yang dibutuhkan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80ac68cd883369dac20688bc32b4cb33291b5e50" datatype="html">
+ <source>Calculation help</source>
+ <target>Bantuan penghitungan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fccbd60493df26705d957ed6c02a3c447894678f" datatype="html">
+ <source>The current PGs settings were calculated for you, you should make sure the values suit your needs before submit.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">116,117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a43b2695131b48b76cebba676aba98a2bee17515" datatype="html">
+ <source>Replicated size</source>
+ <target>Jumlah replikasi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bff144a4c4dc63b0e18fff2617d61a7ebdf2b6c" datatype="html">
+ <source>Minimum: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9c54b41f6d58a74e5d0aa3429ed0c87a482551" datatype="html">
+ <source>Maximum: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="452cf71ec44ee77428656936a6627eaf2dd3b47f" datatype="html">
+ <source>The size specified is out of range. A value from <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> to <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/> is usable.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">144,145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dda6196ffab88c1825f44a565c7b34e246e7e12f" datatype="html">
+ <source>A size of 1 will not create a replication of the object. The 'Replicated size' includes the object itself.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">148,149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c870fb00256b8a5b9cb9cd1a124e6390b9bc639" datatype="html">
+ <source>EC Overwrites</source>
+ <target>EC Overwrites</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f1abafaeb40ce52355ddcc24686e3cd17b64e08a" datatype="html">
+ <source>Applications</source>
+ <target>Aplikasi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9308b82fc183f710df60909f49cfc73aa5e076" datatype="html">
+ <source>CRUSH</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9de7dde00e2139cc4bd03b1837afbe72ad15a1ff" datatype="html">
+ <source>Erasure code profile</source>
+ <target>Profil erasure code</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39b4620e6bd444e0a57a0a5c03fa8c96d7fe5235" datatype="html">
+ <source>-- No erasure code profile available --</source>
+ <target>-- Tidak ada profil erasure code --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498561757390d5528b263ce450d5f38efb00266d" datatype="html">
+ <source>-- Select an erasure code profile --</source>
+ <target>-- Pilih profil erasure code --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="616a2532fbaace94934f5943e381b63e2623f004" datatype="html">
+ <source>This profile can't be deleted as it is in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="994363f08f9fbfa3b3994ff7b35c6904fdff18d8" datatype="html">
+ <source>Profile</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="023d6f718770d2ea4ab8cabe26b0ec27ef967ec2" datatype="html">
+ <source>Used by pools</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">387</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1061ba5ee07a5c6af09e09330dbc29201baf2aa" datatype="html">
+ <source>Profile is not in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33150f22ce5348aa6c499bd092c3f4f3695d62cc" datatype="html">
+ <source>Crush ruleset</source>
+ <target>Aturan CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">293</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">303</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c69b0bcd4698aa845d32c4c4ad488492552cb469" datatype="html">
+ <source>A new crush ruleset will be implicitly created.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="896e9987db5e9bb279e6deed5d2dff28c242ef66" datatype="html">
+ <source>There are no rules.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73a6b31116b3cc322af951daa0bafdc169e6c42e" datatype="html">
+ <source>-- Select a crush rule --</source>
+ <target>-- Pilih aturan crush --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7d4894e770f8853050b1f6dd55bdd77a51a8ac6" datatype="html">
+ <source>Placement and
+ replication strategies or distribution policies that allow to
+ specify how CRUSH places data replicas.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">328,330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea91d648f92002bc9f96d9b26b735c83ca0b53c6" datatype="html">
+ <source>This rule can't be deleted as it is in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">346</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92da80699921e89fb19372e25b8d0f3b9fa427fc" datatype="html">
+ <source>Crush rule</source>
+ <target>Aturan crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">365</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5489e9f96835f469f6f728a00d8efa88ea5bc940" datatype="html">
+ <source>Crush steps</source>
+ <target>Crush steps</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc5f5496a9e50fe69e1a09784f28d94944108294" datatype="html">
+ <source>Rule is not in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="104a0e6900d1d1b0c8cf9e5947e36edb352583fc" datatype="html">
+ <source>The rule can't be used in the current cluster as it has too few OSDs to meet the minimum required OSD by this rule.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">409,410</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2208d63d5940ce656006a220102b1eb2b5e553da" datatype="html">
+ <source>Compression</source>
+ <target>Kompresi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">420</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c6f25c47da62ec597c6057a36ddfc3209811ec5" datatype="html">
+ <source>Algorithm</source>
+ <target>Algoritma</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">444</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4903231d42089325a28892c0fde1aed46b733ae6" datatype="html">
+ <source>-- No erasure compression algorithm available --</source>
+ <target>-- Tidak ada algoritma pengompresian erasure --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d68ddb254275f8f44221e9ad6d8ceeb59ca46a6" datatype="html">
+ <source>Minimum blob size</source>
+ <target>Ukuran blob minimum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">468</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb2f176df80647137cbb02bbeb29e5dec707a400" datatype="html">
+ <source>e.g., 128KiB</source>
+ <target>cth. 128KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">477</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b7f6e53a4521c6eb3ced4c007fdd4cf80bb7707" datatype="html">
+ <source>Value should be greater than 0</source>
+ <target>Nilai harus lebih besar dari 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">482</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">506</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8db98ab14b4e207ec763dfdefbc2dae367aab1cc" datatype="html">
+ <source>Value should be less than the maximum blob size</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151efb127a9a4dd25259a0b2055442318a141f5b" datatype="html">
+ <source>Maximum blob size</source>
+ <target>Ukuran maksimum blob</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c656f0e346bbadf46eb1a5d20d0307a3bd20ba8" datatype="html">
+ <source>e.g., 512KiB</source>
+ <target>cth. 512KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65a24eee8a026f3b1113fe9e157e9a0dd69486" datatype="html">
+ <source>Value should be greater than the minimum blob size</source>
+ <target>Nilai harus lebih besar dari ukuran minimum blob</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">509</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="261ba09c4a59de83f48f52a23fd328da37e61ff4" datatype="html">
+ <source>Ratio</source>
+ <target>Rasio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">517</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1430457a9c3c66366e51d76bf10396014c576be" datatype="html">
+ <source>Compression ratio</source>
+ <target>Rasio kompresi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">528</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae5ce6de352cde949998fb10754459c3a4eb183b" datatype="html">
+ <source>Value should be between 0.0 and 1.0</source>
+ <target>Nilai harus antara 0.0 dan 1.0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d99b34162c9c34f10d0ccd8dbae83d8569c2db77" datatype="html">
+ <source>Max bytes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">546</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1d14a18879c62f3f4ed705318b7164a1160e249" datatype="html">
+ <source>Leave it blank or specify 0 to disable this quota.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">572</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7565b131562ff6c5f769fdbd239a772154abdd97" datatype="html">
+ <source>A valid quota should be greater than 0.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">550</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">574</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b8bf35b66f09a301eef92ffc3cb2fd259df67ce9" datatype="html">
+ <source>Max objects</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">570</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="95f348167622d832c5ae532b6944635c8e2ae5cb" datatype="html">
+ <source>The value should be greater or equal to 0</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">586</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1088629182722162774" datatype="html">
+ <source>pool</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6215593782779198370" datatype="html">
+ <source>erasure code profile</source>
+ <target>profil erasure code</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4390273881304618317" datatype="html">
+ <source>crush rule</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">721</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d8a7c8aea58294a3c57c23af0468ddf0ba0c9c7" datatype="html">
+ <source>Pools List</source>
+ <target>Daftar pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9055665654201606988" datatype="html">
+ <source>Data Protection</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6658000829978978023" datatype="html">
+ <source>Applications</source>
+ <target>Aplikasi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5232365108332422324" datatype="html">
+ <source>PG Status</source>
+ <target>Status PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1669788723782899084" datatype="html">
+ <source>Crush Ruleset</source>
+ <target>Aturan Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7961062124768120122" datatype="html">
+ <source>Pool deletion is disabled by the mon_allow_pool_delete configuration setting.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee5132a8da30e0b7f9f5c70dbc91928d17dd909" datatype="html">
+ <source>Owner</source>
+ <target>Pemilik</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c51963a9c553b29427ef783bbb69fa6634fa8c" datatype="html">
+ <source>Index type</source>
+ <target>Jenis indeks</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e6f950a32eaea32ec7e192f9ca3d3dfe469d4ba" datatype="html">
+ <source>Placement rule</source>
+ <target>Aturan penempatan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6972d213e31c4ea4f887e60db99d9881bc8fcd3e" datatype="html">
+ <source>Marker</source>
+ <target>Penanda</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47b02acd2d3254d1ace1926f840523f154ebef71" datatype="html">
+ <source>Maximum marker</source>
+ <target>Penanda maksimum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="092fa3a7df9168b14d3f83a77a4035e92b92ce15" datatype="html">
+ <source>Master version</source>
+ <target>Versi Master</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97434cc5001d407f90c7447a12d9e8e6848a2aa3" datatype="html">
+ <source>Modification time</source>
+ <target>Modifikasi waktu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90fe2e41e7fde38453ce4e619efeea9bc6adea9c" datatype="html">
+ <source>Zonegroup</source>
+ <target>Zona grup</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="efeade5060b3add63863c24871f0830fb16b7e6d" datatype="html">
+ <source>Versioning</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62a923f047ca49e7a4782629e91fea1ba32db68f" datatype="html">
+ <source>MFA Delete</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="649a410bd0ace333d067d8fa22f12bdbdb43533b" datatype="html">
+ <source>Bucket quota</source>
+ <target>Kuota Buket</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">567</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f50a33d3c339f8f4a465141f8caa5d2d8c005251" datatype="html">
+ <source>Enabled</source>
+ <target>Diaktifkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">579</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cef1595d040e77cbb4466e60382028d4c2040cac" datatype="html">
+ <source>Maximum size</source>
+ <target>Ukuran maksimum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa6fb95c355f172bda303de1ce2f38c251a149cf" datatype="html">
+ <source>Unlimited</source>
+ <target>Tak terbatas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee862a800364b4d11f9b8cb9955a28a60f840a45" datatype="html">
+ <source>Maximum objects</source>
+ <target>Objek maksimum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b84370895ab9eb44672f57146fa05c5947f1c0c" datatype="html">
+ <source>Locking</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c3d9d2296f7886e8289b9f623323803deacfc6" datatype="html">
+ <source>Days</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f44bdf9ab00a973bbe482e9fc450e3f67e60c0d" datatype="html">
+ <source>Bucket names can only contain lowercase letters, numbers, periods and hyphens.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eabb4db920d9f9b2480cf438468b86e1bea02a9b" datatype="html">
+ <source>The chosen name is already in use.</source>
+ <target>Nama yang dipilih sudah digunakan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b06de7f834c622197e68b66a2abe893040b174c4" datatype="html">
+ <source>Bucket names must not contain uppercase characters or underscores.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abacf4af2f66d3af08c5ebe502b21b1f42ac649" datatype="html">
+ <source>Each label must start and end with a lowercase letter or a number.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a7f52e6813e0535026f61a2d6e8adc8a1d006a" datatype="html">
+ <source>Bucket names cannot be formatted as IP address.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2a2460396d35e14e7acfb4e060196a0679bdcff" datatype="html">
+ <source>Bucket labels cannot be empty and can only contain lowercase letters, numbers and hyphens.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf5c849977e0be2dbfc862d044edd323bfd9fb77" datatype="html">
+ <source>Bucket names must be 3 to 63 characters long.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e4c918357c7445fbf19a203e5f0f0ece1960b3b" datatype="html">
+ <source>-- Select a user --</source>
+ <target>-- Pilih pengguna --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4aab1f837bc8ec222e4f25922465d1c5929a1fc" datatype="html">
+ <source>Placement target</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bae0a7fc2c9c1fde7d937a8a1a3c7e6825cf7d1" datatype="html">
+ <source>-- Select a placement target --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="016d24e069e7d505a090fb8243e5cd43b35dc39b" datatype="html">
+ <source>Enables versioning for the objects in the bucket.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">151</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e6775ffd06878aa145c07359f28557f01ede04f" datatype="html">
+ <source>Multi-Factor Authentication</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29e8a5d4fb767d4ad0c762c81c6264cec4c0ba97" datatype="html">
+ <source>Delete enabled</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40fbc3ac8c1ea4ecfe62247e91f1f999ad5baf76" datatype="html">
+ <source>Enables MFA (multi-factor authentication) Delete, which requires additional authentication for changing the bucket versioning state.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24c93a8c13db46defa06ed7b5e026a3edb52b91" datatype="html">
+ <source>Token Serial Number</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6d9536c2af2e5e9a228c3e3e1809dc1fefe0149" datatype="html">
+ <source>Token PIN</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f038d51ab1645f15b0cd58f195c72a7eeebd4729" datatype="html">
+ <source>Enables locking for the objects in the bucket. Locking can only be enabled while creating a bucket.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9af1b4baa2dd8ed2bfc3cc756b12a2271c2dd793" datatype="html">
+ <source>Compliance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="edd600fa489d1b4a4448dce694ed932e52ce8fda" datatype="html">
+ <source>Governance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="218c7d6d318c51e7105309aaeb0baec9d19e4efb" datatype="html">
+ <source>The number of days that you want to specify for the default retention period that will be applied to new objects placed in this bucket.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">264</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="289b101ec12427b3ca819df9e43cc3b14fae2cc4" datatype="html">
+ <source>The entered value must be a positive integer.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48d8247c1ba2ea156109bf286c5f6dd26b4be760" datatype="html">
+ <source>Retention Days must be a positive integer.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4349284625269221231" datatype="html">
+ <source>bucket</source>
+ <target>buket</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6161088322338624846" datatype="html">
+ <source>Updated Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218632328857697292" datatype="html">
+ <source>Created Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c338bae89822d7eefbc9a887c458a7d8a98e55e" datatype="html">
+ <source>No Limit</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3715596725146409911" datatype="html">
+ <source>Owner</source>
+ <target>Pemilik</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5545511293826600258" datatype="html">
+ <source>Used Capacity</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1925090152473969054" datatype="html">
+ <source>Capacity Limit %</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8713861779825116442" datatype="html">
+ <source>Object Limit %</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5913880066213114620" datatype="html">
+ <source>buckets</source>
+ <target>buket</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eeba399c4dae8d4890c27b7a2cd2dc28fcf8b5f9" datatype="html">
+ <source>Performance Counters</source>
+ <target>Penghitung Performa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="479488ab6e91ecb375484edc78bee3d13467f33f" datatype="html">
+ <source>Daemons List</source>
+ <target>Daftar Daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca2dee83bb58290d93fb0d17ee8bc9f095a4576f" datatype="html">
+ <source>Sync Performance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4378147649219625174" datatype="html">
+ <source>Zone</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6148052126949932311" datatype="html">
+ <source>Zone Group</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3840481991104643295" datatype="html">
+ <source>Realm</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1221ca97d19eaa9a7bc0c5243d5fc5befe1d2314" datatype="html">
+ <source>-- Select a type --</source>
+ <target>-- Pilih tipe --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1b8990332af18f1c5159a6061ca889bcbb28432" datatype="html">
+ <source>Permission</source>
+ <target>Izin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a08c589f82f69d892307288da14190ae1dd583d5" datatype="html">
+ <source>-- Select a permission --</source>
+ <target>-- Pilih izin --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7345972049922682356" datatype="html">
+ <source>capability</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a94e6b2b5b834d92cceb90037d51ad6165c8b619" datatype="html">
+ <source>Tenant</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
+ <source>User ID</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b760f123248930122fc7e7b6b6bf94e376e959c8" datatype="html">
+ <source>Full name</source>
+ <target>Nama lengkap</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69b6ac577a19acc39fc0c22342092f327fff2529" datatype="html">
+ <source>Email address</source>
+ <target>Alamat email</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92f3f203270a29b3001871153f02c063484a1574" datatype="html">
+ <source>Suspended</source>
+ <target>Dihentikan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011e20c5bbe51602d459a860fbf29b599b55edd" datatype="html">
+ <source>System</source>
+ <target>Sistem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db18a2772988415466a7f75dc42663ce78c9c1d3" datatype="html">
+ <source>Maximum buckets</source>
+ <target>Buket maksimum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c4c62e8ba24601be5cfe7dc5d32c24bbbd4b53c" datatype="html">
+ <source>Subusers</source>
+ <target>Subpengguna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17bb3082e6fe5003203ef992a3714172334631a1" datatype="html">
+ <source>Capabilities</source>
+ <target>Kemampuan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32f8a0570373cacb9c56cf227502483a29d605bc" datatype="html">
+ <source>MFAs(Id)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36ad38f9c1a1485e09b67778a28af84553290ffb" datatype="html">
+ <source>User quota</source>
+ <target>Kuota pengguna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">473</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0bcd5ef19af0f1b814141ca8c57df623d8270088" datatype="html">
+ <source>Keys</source>
+ <target>Kunci</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2aba1e87039819aca3b70faa9aa848c12bf139ca" datatype="html">
+ <source>Show</source>
+ <target>Tampilkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">395</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5248717555542428023" datatype="html">
+ <source>Username</source>
+ <target>Nama pengguna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240806681889331244" datatype="html">
+ <source>Unlimited</source>
+ <target>Tak terbatas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db4e1a734518691b128ef40b939cc673f01d03a6" datatype="html">
+ <source>The value is not valid.</source>
+ <target>Nilai tidak valid.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">617</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6aaf5d2a304167272ac73e3b1d1c162e16c77858" datatype="html">
+ <source>The chosen user ID is already in use.</source>
+ <target>ID pengguna yang dipilih sudah digunakan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="025be1d01b2f6cbd09e772a1d3de02fab0678b26" datatype="html">
+ <source>Show Tenant</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6af106b0d759fd2882e645604675c4494abfcd5b" datatype="html">
+ <source>The chosen user ID exists in this tenant.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="df441e80db2157f9d272b75de724ba4a82b96b57" datatype="html">
+ <source>This is not a valid email address.</source>
+ <target>Ini bukan alamat email yang valid.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca271adf154956b8fcb28f4f50a37acb3057ff7c" datatype="html">
+ <source>The chosen email address is already in use.</source>
+ <target>Alamat email yang dipilih sudah digunakan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="030197cebe938edf35422e92fe14183d06eb670b" datatype="html">
+ <source>Max. buckets</source>
+ <target>Maks. buket</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f39256070bfc0714020dfee08895421fc1527014" datatype="html">
+ <source>Disabled</source>
+ <target>Dimatikan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c05002b0ac2040f1aede5e727e0ffd06eda819" datatype="html">
+ <source>Custom</source>
+ <target>Ubahsuai</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28872515cb81d197a3a1733fa546d3e0f0dd6c67" datatype="html">
+ <source>The entered value must be &gt;= 1.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="583a219c524155c2314eb06ee29162bb315272a3" datatype="html">
+ <source>S3 key</source>
+ <target>Kunci S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c217ee914725a37e9dd2336c721c8e63e9666bdc" datatype="html">
+ <source>Auto-generate key</source>
+ <target>Kunci otomatis-dibuat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f1c1c0f2bce4c9f92d1a2061e8161cb0006c31a" datatype="html">
+ <source>Access key</source>
+ <target>Kunci akses</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b864acb67296a9819c1db0069c4c47d8b5ce8f44" datatype="html">
+ <source>Secret key</source>
+ <target>Kunci rahasia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="128d6efb51d9ddc7c0cc695a2deeca5b9523f6e4" datatype="html">
+ <source>There are no subusers.</source>
+ <target>Tidak ada sub-pengguna.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fd6dfb8ecb982dbc3affb2c2d5414c4f5b6abd2" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">294,295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67c746c1ba9dab4351fedc4c7cba4e6d6b0dbc47" datatype="html">
+ <source>S3</source>
+ <target>S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d6819038d608623503918fb2553f53d68231ec3a" datatype="html">
+ <source>There are no keys.</source>
+ <target>Kunci tidak ditemukan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">377</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc1c1a7140ff6b815a95b65ee2780fdbe1b2b7a1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">356,357</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6ddb5e991a3ecd2659fb520bc5acc81b67e08ddd" datatype="html">
+ <source>Swift</source>
+ <target>Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">371</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d01eccdda47fc907c5be35bcb16d2dcd02b0270" datatype="html">
+ <source>There are no capabilities.</source>
+ <target>Kemampuan tidak ada.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5a451c4ea65a4046f0b49d489a7013abf0b5861" datatype="html">
+ <source>All capabilities are already added.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">456</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="043e2ec0036ceadd926fd5e3f93cd6f3565f3648" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">461,462</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6146e13ceca5fa5cc17b771b282fe5955f3d19fa" datatype="html">
+ <source>Unlimited size</source>
+ <target>Ukuran tak terbatas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">595</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6db8aa7c99fdce18edb33dde57729acede2b308" datatype="html">
+ <source>Max. size</source>
+ <target>Ukuran maks.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">511</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">605</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc630b2093e880fffa19df99d5cd8b87605037f8" datatype="html">
+ <source>Unlimited objects</source>
+ <target>Objek tak terbatas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cda5a993d06f0bb10048be9d3aba6555aa9f356" datatype="html">
+ <source>Max. objects</source>
+ <target>Objek maks.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">642</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="623ac50f37a26caec6fd7cd519b653e3315cba25" datatype="html">
+ <source>The entered value must be &gt;= 0.</source>
+ <target>Nilai yang dimasukkan harus &gt;= 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">654</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="123010868147850959" datatype="html">
+ <source>user</source>
+ <target>pengguna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8368421344177343441" datatype="html">
+ <source>subuser</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4662015204945271252" datatype="html">
+ <source>S3 Key</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9103468069826049692" datatype="html">
+ <source>Updated Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="884841609901737584" datatype="html">
+ <source>Created Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4363143805416924501" datatype="html">
+ <source>Tenant</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8301535046747035390" datatype="html">
+ <source>Full name</source>
+ <target>Nama lengkap</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3967269098753656610" datatype="html">
+ <source>Email address</source>
+ <target>Alamat email</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5851424994801012357" datatype="html">
+ <source>Suspended</source>
+ <target>Dihentikan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208300173682032371" datatype="html">
+ <source>Max. buckets</source>
+ <target>Maks. buket</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1670306451865226564" datatype="html">
+ <source>users</source>
+ <target>pengguna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c614babd1950adb2be75df4e2c9747286d6adc" datatype="html">
+ <source>-- Select a username --</source>
+ <target>-- Pilih nama pengguna --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2841767821d6b66238c34d07e413b0af67aee92" datatype="html">
+ <source>Subuser</source>
+ <target>Subpengguna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd59fc25a7bd98cff3e75117c09697c8a007a514" datatype="html">
+ <source>The chosen subuser ID is already in use.</source>
+ <target>ID subpengguna sudah digunakan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d386c357ebcbc04ed05c4babd5a03626f9b1674" datatype="html">
+ <source>read, write</source>
+ <target>baca, tulis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84e3e3f9a4f31a039b648c97debf95fcb20f4c4a" datatype="html">
+ <source>full</source>
+ <target>penuh</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6bf81d032a2316464f9df2f0d2f3d753f89f0d3" datatype="html">
+ <source>Swift key</source>
+ <target>Kunci Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e0c12685d50d47448ceed9423977ef39775c037" datatype="html">
+ <source>Auto-generate secret</source>
+ <target>Sandi otomatis-dibuat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5091031285775138345" datatype="html">
+ <source>Subuser</source>
+ <target>Subpengguna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8453697749389230205" datatype="html">
+ <source>Swift Key</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ac54c18c1b520e948095c83a3a1025f02ce6dcc6" datatype="html">
+ <source>Neither hostname nor OSD ID given</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4533150758393178756" datatype="html">
+ <source>Device ID</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1291053608320944146" datatype="html">
+ <source>State of Health</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29167121133682512" datatype="html">
+ <source>Good</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8767957606064036733" datatype="html">
+ <source>Bad</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8052456228079338924" datatype="html">
+ <source>Stale</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6223439643831041743" datatype="html">
+ <source>Life Expectancy</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3144481541623761279" datatype="html">
+ <source>Prediction Creation Date</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="264574868375698540" datatype="html">
+ <source>Device Name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1419569261746199221" datatype="html">
+ <source>Daemons</source>
+ <target>Daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f635b3cb0600409a2ad44a5bd1863c699e6a01c" datatype="html">
+ <source>Failed to retrieve SMART data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a8a3f354bd640299068edd912f4bb5325264f250" datatype="html">
+ <source>The data received has the JSON format version 2.x and is currently incompatible with the dashboard.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="04f8a3c7e8ac610e6581960162cc15f55a16696a" datatype="html">
+ <source>No SMART data available.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a185c9b97513b3882604ea9bab60edbfac945c15" datatype="html">
+ <source>SMART overall-health self-assessment test result</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="290e4c9ad42dc6e9176656c864a5faed8053f406" datatype="html">
+ <source>unknown</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a03d3c2e459f8f8fa7202c0fce465d6165f9e2b" datatype="html">
+ <source>passed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41435d5a5692c8e412c74deaee95d99dbd3617e1" datatype="html">
+ <source>failed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddd5dd6d930030096ea617f62c82b648a0dd9484" datatype="html">
+ <source>Device Information</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e149c483d88cfcff11d1c5db85e84af7c3149c4" datatype="html">
+ <source>No device information available for this device.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20cb12827cbe559a7b1da6fdae96041b3b5c3c55" datatype="html">
+ <source>SMART</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380295f37caea93701d071485a38ef0bdba57133" datatype="html">
+ <source>No SMART data available for this device.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5758c3f16f8749f0f4e2a787f02e8b4da246102f" datatype="html">
+ <source>SMART data is loading.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5363861031080361352" datatype="html">
+ <source>Smartctl has received an unknown argument (error code <x id="PH" equiv-text="smartData.smartctl_error_code"/>). You may be using an incompatible version of smartmontools. Version &gt;= 7.0 of smartmontools is required to successfully retrieve data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">61,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5085718566932809950" datatype="html">
+ <source>An error with error code <x id="PH" equiv-text="smartData.smartctl_error_code"/> occurred.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2091295268977103253" datatype="html">
+ <source>Raw</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5963653123239768443" datatype="html">
+ <source>Threshold</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2893124970059125090" datatype="html">
+ <source>When Failed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5614367840516299633" datatype="html">
+ <source>Worst</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d06ae77f9ec46a4cdd49e7e76c73a411aaf2ee38" datatype="html">
+ <source>Please set a new password.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8b5b3566e88438f51bd5f6caf6c090ed565ba5ed" datatype="html">
+ <source>You will be redirected to the login page afterwards.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cf42e491adc166a337a960eb84d03c0c3f677c8" datatype="html">
+ <source>The old and new passwords must be different.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90163a3d3746819aef42e829f4446331232f3b66" datatype="html">
+ <source>Password confirmation doesn't match the new password.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0070e83d11da39d6f4bb95065c2675db1610b419" datatype="html">
+ <source>Username is required</source>
+ <target>Nama pengguna harus diisi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e20f8b8a4706526c9024cc2f39d568345d100dc" datatype="html">
+ <source>Password is required</source>
+ <target>Kata sandi harus diisi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f093d9574ab746b231504bd2cbb65f04bd7b00db" datatype="html">
+ <source>Log in</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5590086849807274701" datatype="html">
+ <source>Scope</source>
+ <target>Cakupan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327592562693301723" datatype="html">
+ <source>Read</source>
+ <target>Baca</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5674286808255988565" datatype="html">
+ <source>Create</source>
+ <target>Buat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4021752662928002901" datatype="html">
+ <source>Update</source>
+ <target>Perbarui</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022070615528435141" datatype="html">
+ <source>Delete</source>
+ <target>Hapus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ea5c4d8942c00752dcc72e72949c5d9832f6399" datatype="html">
+ <source>Description...</source>
+ <target>Deskripsi...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70f45880fce6ac5d8e468e25e82aefbba8098cfe" datatype="html">
+ <source>Permissions</source>
+ <target>Izin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="122114774689391224" datatype="html">
+ <source>role</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616102757855967475" datatype="html">
+ <source>All</source>
+ <target>Semua</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4416727401284087008" datatype="html">
+ <source>Created role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3472946357042916911" datatype="html">
+ <source>Updated role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="373024661645814027" datatype="html">
+ <source>System Role</source>
+ <target>Peran Sistem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753648234171918096" datatype="html">
+ <source>Deleted role '<x id="PH" equiv-text="role"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1674202514578558795" datatype="html">
+ <source>New name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4857700187193019038" datatype="html">
+ <source>Clone Role</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="748631939386170157" datatype="html">
+ <source>Cloned role '<x id="PH" equiv-text="values['newName']"/>' from '<x id="PH_1" equiv-text="name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="195c31a2f970e790231a6bb94a5e8ca0167406d9" datatype="html">
+ <source>The username already exists.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f3bdcce4b2e8c37cd7f0f6c92ef8cff34b039b8" datatype="html">
+ <source>Confirm password</source>
+ <target>Konfirmasi kata sandi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cbb979e63ba50e0ca3adfa09cbdcaefd0853fca1" datatype="html">
+ <source>Password confirmation doesn't match the password.</source>
+ <target>Konfirmasi kata sandi tidak sesuai dengan kata sandi.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="96621f9ed2e4ae5204564e583d2c816bedead571" datatype="html">
+ <source>Password expiration date</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48932db3801fe9d5d72a60a3e656bffd17c1c5d9" datatype="html">
+ <source>Password expiration date...</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc" datatype="html">
+ <source>Email</source>
+ <target>Email</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d0ec081dd61eb4f43aea269077bbe38eae87b7f9" datatype="html">
+ <source>Invalid email.</source>
+ <target>Email tidak valid.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9610487cbeb5796d34d8601b5ac0c0a65f9e1d19" datatype="html">
+ <source>Roles</source>
+ <target>Peran</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8913c216dd506e20e412e144381d8d2a65a84359" datatype="html">
+ <source>User must change password at next logon</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0051a3479d3ba79135c16dc8cc017950a2cce821" datatype="html">
+ <source>You are about to remove &quot;user read / update&quot; permissions from your own user.</source>
+ <target>Anda akan menghapus izin &quot;pengguna baca / perbarui&quot; dari diri Anda sendiri.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af4bf9fcb256853f14cf947eb1deb8d7f176d3f9" datatype="html">
+ <source>If you continue, you will no longer be able to add or remove roles from any user.</source>
+ <target>Jika melanjutkan, Anda tidak akan lagi dapat menambahkan atau menghapus peran dari pengguna manapun.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314291969883771319" datatype="html">
+ <source>There are no roles.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4306072924538089180" datatype="html">
+ <source>Created user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1349763489797682899" datatype="html">
+ <source>Update user</source>
+ <target>Perbarui pengguna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8688396456017237992" datatype="html">
+ <source>You were automatically logged out because your roles have been changed.</source>
+ <target>Anda dikeluarkan otomatis karena peran Anda telah berubah.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2335813072344088607" datatype="html">
+ <source>Updated user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4768749765465246664" datatype="html">
+ <source>Email</source>
+ <target>Email</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795890916060309463" datatype="html">
+ <source>Roles</source>
+ <target>Peran</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6877445485286599988" datatype="html">
+ <source>Password expiration date</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="705657168061753072" datatype="html">
+ <source>Deleted user '<x id="PH" equiv-text="username"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="405819296611088743" datatype="html">
+ <source>Failed to delete user '<x id="PH" equiv-text="username"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8935387756949610047" datatype="html">
+ <source>You are currently logged in as '<x id="PH" equiv-text="username"/>'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0eb15f32b2b92d7f3103ef3ff032621888a8dc32" datatype="html">
+ <source>Old password</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229" datatype="html">
+ <source>New password</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ede41f01c781b168a783cfcefc6fb67d48780d9b" datatype="html">
+ <source>Confirm new password</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809196861118879526" datatype="html">
+ <source>password</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623124197136601291" datatype="html">
+ <source>Updated user password&quot;</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be" datatype="html">
+ <source>Users</source>
+ <target>Pengguna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ced3246fa3db31be0f7da06648463f29ba378fbe" datatype="html">
+ <source>Selected Object Gateway:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c53062af97ebda2a03f905698f58e524ecf8b968" datatype="html">
+ <source>Select Object Gateway</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="235c355afdcbf72953a15d7fc8d0d9e7a6619f46" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Page not Found<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aee9d027170f84774f2980537556f5099369b82" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for. The page you requested may have been changed or moved.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">22,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2b46fe9a975c6531af77fee858ccd37327980f7" datatype="html">
+ <source>Please consult the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>documentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> on how to configure and enable the <x id="INTERPOLATION" equiv-text="{{ section_info }}"/> management functionality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">26,27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9d57ca7cab78c6f0d27e0d890cb8cf1515e4e30a" datatype="html">
+ <source>Go To Dashboard</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6578397717654172779" datatype="html">
+ <source>Page Not Found</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8185335715884155108" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for.
+ The page you requested may have been changed or moved.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="143318366100741906" datatype="html">
+ <source>Access Denied</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5384670299771400832" datatype="html">
+ <source>Sorry, you don’t have permission to view this page or resource.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2424411274809083521" datatype="html">
+ <source>User Denied</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7645004872908092358" datatype="html">
+ <source>Sorry, the user does not exist in Ceph.
+ You'll be logged out from the Identity Provider when you retry logging in.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">24,25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f286db6ac9482dbf567bc491d49a6eade444895a" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7911416166208830577" datatype="html">
+ <source>Help</source>
+ <target>Bantuan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8878700331247603166" datatype="html">
+ <source>Security</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8642696205489749843" datatype="html">
+ <source>Trademarks</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1481ecd21e760ac919a24e26cf790acd82e40199" datatype="html">
+ <source>Dashboard Settings</source>
+ <target>Pengaturan Dasbor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a79aab4ef674bf3f6532292107c0054302236e0f" datatype="html">
+ <source>User management</source>
+ <target>Manajemen Pengguna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="197e0246502ca64d0de0df0d5c2deec51d41ff45" datatype="html">
+ <source>Telemetry configuration</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85b79c9064aed1ead31ace985f31aa1363f6bdaf" datatype="html">
+ <source>Help</source>
+ <target>Bantuan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06638e0f01d82c0786f63aa9832fbe7866b86087" datatype="html">
+ <source>documentation</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e351b40b3869a5c7d19c3d4918cb1ac7aaab95c4" datatype="html">
+ <source>API</source>
+ <target>API</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a" datatype="html">
+ <source>About</source>
+ <target>Tentang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="049dfd9fe6c78914ad58cf89ac6a631fca28ec74" datatype="html">
+ <source>Logged in user</source>
+ <target>Pengguna masuk</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5022c5ae3ae921c07bf5f881e9b026b4a6708a7" datatype="html">
+ <source>Signed in as <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9" datatype="html">
+ <source>Change password</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d22c795daf43877a5f708dca2bccd549eb0471d" datatype="html">
+ <source>Sign out</source>
+ <target>Keluar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319e0745bcbc132451569294fa2fa21bf10f555a" datatype="html">
+ <source>Toggle navigation</source>
+ <target>Pengalih navigasi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f65253954b66e929a8b4d5ecaf61f9129f8cec64" datatype="html">
+ <source>Dashboard</source>
+ <target>Dasbor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c95898abff46bfac3ed6eb2afef74597e60b15c" datatype="html">
+ <source>CRUSH map</source>
+ <target>peta CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7b2bc4b86de6e96d353f6bf2b4d793ea3a19ba0" datatype="html">
+ <source>Manager Modules</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb3d5aefff38a814b76da74371cbf02c0789a1ef" datatype="html">
+ <source>Logs</source>
+ <target>Log</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17fc3efe5f9fa4e0289c900cb6202265215a1a27" datatype="html">
+ <source>Monitoring</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f5d0c10614e8a34f0e2dad33a0568277c50cf69" datatype="html">
+ <source>Block</source>
+ <target>Blok</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3c2562ba992127203dcfd014010b03cb7b8113c6" datatype="html">
+ <source>Mirroring</source>
+ <target>Pencerminan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="811c241d56601b91ef26735b770e64428089b950" datatype="html">
+ <source>iSCSI</source>
+ <target>iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a24eabd99ea5af20f5f94c4484649cd30370042b" datatype="html">
+ <source>NFS</source>
+ <target>NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5276fc60d54d667116babb723641b21281d37271" datatype="html">
+ <source>File Systems</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9515520496da83179d8b08132f00f575512a1f40" datatype="html">
+ <source>Buckets</source>
+ <target>Buket</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a23e992f6c6e169a38b2b7338b4e5e803b52e0d" datatype="html">
+ <source>Tasks and Notifications</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1390461972315002349" datatype="html">
+ <source>The name of the node under which data should be placed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6575341202068728510" datatype="html">
+ <source>The type of CRUSH nodes across which we should separate replicas.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3874278445824365480" datatype="html">
+ <source>The device class data should be placed on.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="675628105428950215" datatype="html">
+ <source>Each object is split in data-chunks parts, each stored on a different OSD.</source>
+ <target>Tiap objek dipecah dalam pecahan-data, masing-masing disimpan pada OSD yang berbeda.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5128168460056151476" datatype="html">
+ <source>Compute coding chunks for each object and store them on different OSDs.
+ The number of coding chunks is also the number of OSDs that can be down without losing data.</source>
+ <target>Hitung pecahan coding untuk tiap objek dan simpan pada OSD yang berbeda.
+Jumlah pecahan data juga menjadi jumlah OSD yang diperbolehkan mati tanpa kehilangan data.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">18,19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8826111293169381132" datatype="html">
+ <source>The jerasure plugin is the most generic and flexible plugin,
+ it is also the default for Ceph erasure coded pools.</source>
+ <target>Plugin jerasure merupakan plugin paling umum dan fleksibel,
+serta merupakan plugin bawaan Ceph untuk pool erasure code.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">23,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1331133460856304156" datatype="html">
+ <source>The more flexible technique is reed_sol_van : it is enough to set k
+ and m. The cauchy_good technique can be faster but you need to chose the packetsize
+ carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents
+ in the sense that they can only be configured with m=2.</source>
+ <target>Teknik yang lebih fleksibel yaitu reed_sol_van : cukup mengeset k
+dan m. Teknik cauchy_good bisa lebih cepat, namun Anda harus memilih ukuran paket
+dengan seksama. Semua reed_sol_r6_op, liberation, blaum_roth, liber8tion setara dengan RAID6
+dalam hal mereka hanya bisa diatur dengan m=2.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">25,28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4577912952562931806" datatype="html">
+ <source>The encoding will be done on packets of bytes size at a time.
+ Choosing the right packet size is difficult.
+ The jerasure documentation contains extensive information on this topic.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">29,31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6471646852539810855" datatype="html">
+ <source>With the jerasure plugin, when an erasure coded object is stored on
+ multiple OSDs, recovering from the loss of one OSD requires reading from all the others.
+ For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading
+ from the eleven others to repair.
+
+ The lrc erasure code plugin creates local parity chunks to be able to recover using
+ less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create
+ an additional parity chunk for every four OSDs. When a single OSD is lost, it can be
+ recovered with only four OSDs instead of eleven.</source>
+ <target>Pada plugin jerasure, saat objek dengan erasure code disimpan pada
+banyak OSD, pemulihan dari OSD yang hilang membutuhkan akses dari OSD lainnya.
+Contoh, saat jerasure dikonfigurasi dengan k=8 dan m=4, saat satu OSD mati, maka pemulihan akan membutuhkan pembacaan dari tujuh OSD lainnya.
+
+Plugin lrc erasure code membuat pecahan paritas lokal agar dapat memulihkan
+dengan OSD yang lebih sedikit. Contoh, jika lrc dikonfigurasi dengan k=8, m=4, dan l=4, maka lrc akan
+membuat pecahan paritas tambahan tiap empat OSD. Saat satu OSD mati, maka pemulihan dapat dilakukan hanya dengan 4 OSD, alih-alih 7 OSD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">34,42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2619235086723330982" datatype="html">
+ <source>Group the coding and data chunks into sets of size locality. For instance,
+ for k=4 and m=2, when locality=3 two groups of three are created. Each set can
+ be recovered without reading chunks from another set.</source>
+ <target>Kelompokkan pecahan data dan coding ke dalam ukuran lokalitas. Controh
+untuk k=4 dan m=2, saat lokalitas=3 dua grup dari tiga akan dibuat. Setiap set akan
+dipulihkan tanpa membaca pecahan dari set lainnya.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">43,45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3298836762557512588" datatype="html">
+ <source>The type of the crush bucket in which each set of chunks defined
+ by l will be stored. For instance, if it is set to rack, each group of l chunks will be
+ placed in a different rack. It is used to create a CRUSH rule step such as step choose
+ rack. If it is not set, no such grouping is done.</source>
+ <target>Tipe buket crush setiap set pecahan yang didefinisikan oleh l
+akan disimpan. Contoh, jika diset pada rak, tiap grup pecahan l akan
+ditempatkan pada rak berbeda. Ini akan digunakan pada aturan step CRUSH yaitu
+memilih tiap rak. Jika tidak diset, tidak akan ada pengelompokkan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">46,49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9162461669419243962" datatype="html">
+ <source>The isa plugin encapsulates the ISA library. It only runs on Intel processors.</source>
+ <target>Plugin isa menghimpun perpustakaan ISA. Hanya dapat berjalan pada prosesor Intel.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2389282202903059852" datatype="html">
+ <source>The ISA plugin comes in two Reed Solomon forms.
+ If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.</source>
+ <target>Plugin ISA memiliki dua jenis Reed Solomon.
+Jika reed_sol_van diset, maka menjadi Vandermonde, jika cauchy diset, maka menjadi Cauchy.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">53,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7319555444402547739" datatype="html">
+ <source>The shec plugin encapsulates the multiple SHEC library.
+ It allows ceph to recover data more efficiently than Reed Solomon codes.</source>
+ <target>Plugin shec mengenkapsulasi banyak pustaka SHEC.
+Hal ini agar ceph dapat dipulihkan dengan lebih efisien dari kode Reed Solomon.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">57,58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7723217930035575928" datatype="html">
+ <source>The number of parity chunks each of which includes each data chunk in its
+ calculation range. The number is used as a durability estimator. For instance, if c=2,
+ 2 OSDs can be down without losing data.</source>
+ <target>Jumlah potongan paritas yang masing-masing mencakup setiap potongan data
+dalam rentang perhitungannya. Nilai ini digunakan untuk perkiraan daya tahan. Contoh, jika c=2,
+2 OSD dapat mati tanpa kehilangan data.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">59,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2054101840892270818" datatype="html">
+ <source>CLAY (short for coupled-layer) codes are erasure codes designed to
+ bring about significant savings in terms of network bandwidth and disk IO when a failed
+ node/OSD/rack is being repaired.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">64,66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491096236680229427" datatype="html">
+ <source>Number of OSDs requested to send data during recovery of a single chunk.
+ d needs to be chosen such that k+1 &lt;= d &lt;= k+m-1. The larger the d, the better
+ the savings.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">67,69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2625895656705896729" datatype="html">
+ <source>scalar_mds specifies the plugin that is used as a building block
+ in the layered construction. It can be one of jerasure, isa, shec.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">70,71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6639141182731628232" datatype="html">
+ <source>technique specifies the technique that will be picked
+ within the 'scalar_mds' plugin specified. Supported techniques
+ are 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good', 'liber8tion' for jerasure, 'reed_sol_van',
+ 'cauchy' for isa and 'single', 'multiple' for shec.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">72,76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8172892264673403098" datatype="html">
+ <source>The name of the crush bucket used for the first step of the CRUSH rule.
+ For instance step take default.</source>
+ <target>Nama buket crush digunakan sebagai langkah pertama dari aturan CRUSH.
+Contoh diambil langkah bawaan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">80,81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1654284403437084515" datatype="html">
+ <source>Ensure that no two chunks are in a bucket with the same failure
+ domain. For instance, if the failure domain is host no two chunks will be stored on the same
+ host. It is used to create a CRUSH rule step such as step chooseleaf host.</source>
+ <target>Memastikan tidak ada pecahan data berada pada buket dengan domain kegagalan
+yang sama. Contoh, saat domain gagal adalah hos, maka tidak ada pecahan data yang akan disimpan
+pada hos yang sama. Aturan CRUSH seperti step chooseleaf hos akan digunakan untuk hal tersebut.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">83,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7737703816676512224" datatype="html">
+ <source>Restrict placement to devices of a specific class
+ (e.g., ssd or hdd), using the crush device class names in the CRUSH map.</source>
+ <target>Batasi penempatan ke perangkat dengan kelas tertentu
+(cth. ssd atau hdd), menggunakan nama kelas perangkat crush pada peta CRUSH.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9049698214199657456" datatype="html">
+ <source>Set the directory name from which the erasure code plugin is loaded.</source>
+ <target>Set nama direktori empat plugin erasure code akan dimuat.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5514060020564877279" datatype="html">
+ <source>Allows all operations</source>
+ <target>Izinkan semua operasi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4265406815683383218" datatype="html">
+ <source>Allows only operations that do not modify the server</source>
+ <target>Izinkan hanya untuk operasi yang tidak mengubah server</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="990071930378308183" datatype="html">
+ <source>Allows no access at all</source>
+ <target>Tidak diizinkan untuk semua hal</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7286983657616285612" datatype="html">
+ <source>Please specify a filesystem volume.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8321762156640395170" datatype="html">
+ <source>The feature is disabled because Orchestrator is not available.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6718394293315494787" datatype="html">
+ <source>The Orchestrator backend doesn't support this feature.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5569418400096331461" datatype="html">
+ <source>-- Select the priority --</source>
+ <target>-- Pilih prioritas --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="802458941707537739" datatype="html">
+ <source>Low</source>
+ <target>Rendah</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8063651736083474594" datatype="html">
+ <source>High</source>
+ <target>Tinggi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1717753935149218245" datatype="html">
+ <source>The user list data might be stale. If needed, you can manually reload it.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/list-with-details.class.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7077550143229856452" datatype="html">
+ <source>Retrieving data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8231424898988217966" datatype="html">
+ <source>Retrieving data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2357645764289315007" datatype="html">
+ <source>Please wait...</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="232824565824302482" datatype="html">
+ <source>Displaying previously cached data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8721257977793603730" datatype="html">
+ <source>Displaying previously cached data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6731313206654246255" datatype="html">
+ <source>Could not load data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3359748695862553898" datatype="html">
+ <source>Could not load data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4836577225879717660" datatype="html">
+ <source>Please check the cluster health.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1519954996184640001" datatype="html">
+ <source>Error</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5037437391296624618" datatype="html">
+ <source>Information</source>
+ <target>Informasi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4648900870671159218" datatype="html">
+ <source>Success</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3425367071066107827" datatype="html">
+ <source>Danger</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c947210e2d162b6225083d18820ab602f58cd2d" datatype="html">
+ <source>Remove the custom configuration value. The default configuration will be inherited and used instead.</source>
+ <target>Hapus nilai kustom konfigurasi. Konfigurasi bawaan akan digunakan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="454ee9cb60b00446a8fb147fd2cc5eb836320586" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fc8a22825131e028336f60ef909ccbd96059703" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4dd200b7f9e19048cf90516843b40964f2af3fe9" datatype="html">
+ <source>Copy to Clipboard</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6110699a3562eeb15371063c0cf7f6bfd88a0209" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>?</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="549859e511ba5af0ea03fcaa620c472f08038969" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected items?</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="54839ebc827b73c9dc4e1df731c6d36a85036af7" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/>?</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2be8b7f04f0104d3fad90d079d8202b74f758b9a" datatype="html">
+ <source>Yes, I am sure.</source>
+ <target>Ya, saya yakin.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4523728183000855476" datatype="html">
+ <source>documentation</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/doc/doc.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3099741642167775297" datatype="html">
+ <source>Download</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/download-button/download-button.component.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1417693714872528491" datatype="html">
+ <source>This field is required.</source>
+ <target>Isian ini tidak boleh kosong.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5321335688371682440" datatype="html">
+ <source>An error occurred.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5109325fb160b543f71a51e7511c00575057431" datatype="html">
+ <source>Loading panel data...</source>
+ <target>Memuat data panel...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a21acde005f80ceadb1391be1e7ff8b6d18188a0" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the monitoring functionality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a0ed4bd7b7add2a6febf7adf58d8cde5e421418" datatype="html">
+ <source>Grafana Dashboard doesn't exist. Please refer to <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to add dashboards to Grafana.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e11830040bd64804a0555de76f291d5832772d4" datatype="html">
+ <source>Grafana Time Picker</source>
+ <target>Pemilih Waktu Grafana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="238c1ba845dd7330e8088165275919a1debf1ca3" datatype="html">
+ <source>Reset Settings</source>
+ <target>Reset Pengaturan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7888499255176013171" datatype="html">
+ <source>Last 5 minutes</source>
+ <target>5 menit terakhir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6892361549797455305" datatype="html">
+ <source>Last 15 minutes</source>
+ <target>15 menit terakhir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2653641162607195423" datatype="html">
+ <source>Last 30 minutes</source>
+ <target>30 menit terakhir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4117793269024790392" datatype="html">
+ <source>Last 1 hour (Default)</source>
+ <target>1 Jam Terakhir (Bawaan)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2645733658763754077" datatype="html">
+ <source>Last 3 hours</source>
+ <target>3 jam terakhir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7360078715633936807" datatype="html">
+ <source>Last 6 hours</source>
+ <target>6 jam terakhir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5055313582241816303" datatype="html">
+ <source>Last 12 hours</source>
+ <target>12 jam terakhir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9186529157286281693" datatype="html">
+ <source>Last 24 hours</source>
+ <target>24 jam terakhir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4498682414491138092" datatype="html">
+ <source>Yesterday</source>
+ <target>Kemarin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="929003859318769922" datatype="html">
+ <source>Today so far</source>
+ <target>Sejauh hari ini</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5525943133564968818" datatype="html">
+ <source>Day before yesterday</source>
+ <target>Kemarin dulu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6168755117727892817" datatype="html">
+ <source>Last 2 days</source>
+ <target>2 hari terakhir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7574807704224200535" datatype="html">
+ <source>This day last week</source>
+ <target>Hari ini minggu lalu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4420128118950221234" datatype="html">
+ <source>Previous week</source>
+ <target>Minggu lalu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4063965603321223683" datatype="html">
+ <source>This week so far</source>
+ <target>Sejauh minggu ini</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4873149362496451858" datatype="html">
+ <source>Last 7 days</source>
+ <target>7 hari terakhir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8586908745456864217" datatype="html">
+ <source>Previous month</source>
+ <target>Bulan lalu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1647573304710886499" datatype="html">
+ <source>This month so far</source>
+ <target>Sejauh bulan ini</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2949150997160654358" datatype="html">
+ <source>Last 30 days</source>
+ <target>30 hari terakhir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7469939859049484736" datatype="html">
+ <source>Last 90 days</source>
+ <target>90 hari terakhir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847501198811458781" datatype="html">
+ <source>Last 6 months</source>
+ <target>6 bulan terakhir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7447583558445881102" datatype="html">
+ <source>Last 1 year</source>
+ <target>1 tahun terakhir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="100513227838842152" datatype="html">
+ <source>Previous year</source>
+ <target>Tahun lalu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3650872673621947074" datatype="html">
+ <source>This year so far</source>
+ <target>Sejauh tahun ini</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1262816694819959075" datatype="html">
+ <source>Last 2 years</source>
+ <target>2 tahun terakhir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7878813844917362690" datatype="html">
+ <source>Last 5 years</source>
+ <target>5 tahun terakhir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3fb5709e10166cbc85970cbff103db227dbeb813" datatype="html">
+ <source>Select a Language</source>
+ <target>Pilih bahasa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/language-selector/language-selector.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e52e9143145e1db5146258de81eae018a407b31" datatype="html">
+ <source>Clear notifications</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0b07bb6b7ff21ede439dd04eaf8872d1ecb84d8" datatype="html">
+ <source>Remove notification</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e17a1d75189da843f541f7764f188f2b19a97df2" datatype="html">
+ <source>Duration:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d4b37c6675c5b436a54c43d6716eec835e1aa7f" datatype="html">
+ <source>There are no notifications.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b20e42ac4354d449f2718428b5390933eef0c1b9" datatype="html">
+ <source>The feature is not supported in the current Orchestrator.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a437b8f93cf826817c04a4277edb1ae3a93a1ab" datatype="html">
+ <source>Orchestrator is not available. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the functionality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">7,9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20b3d45b0c08a2951a9974fa20505e4de95250c9" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>less than 1<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day. Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">9,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f34088c155e40ffb23770a465a65868ce772b2" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day(s). Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8d1785038d461ec66b5799db21864182b35900a" datatype="html">
+ <source>Refresh</source>
+ <target>Segarkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/refresh-selector/refresh-selector.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3417247046175131869" datatype="html">
+ <source>No items selected.</source>
+ <target>Tidak ada yang dipilih.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1034353870189672674" datatype="html">
+ <source>Deselect item to select again</source>
+ <target>Batalkan memilih untuk memilih ulang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4879298070255432995" datatype="html">
+ <source>Selection limit reached</source>
+ <target>Batas pemilihan tercapai</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001227209911602786" datatype="html">
+ <source>Filter tags</source>
+ <target>Tanda penyaringan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="791789583719406586" datatype="html">
+ <source>Add badge</source>
+ <target>Tambahkan lencana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="699988676752930063" datatype="html">
+ <source>There are no items available.</source>
+ <target>Tidak ada yang tersedia.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6702323d3760e3db0e2e785d567469d18beb120" datatype="html">
+ <source>The Ceph community needs your help to continue improving: please <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>Activate<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> the <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Telemetry<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> module.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.html</context>
+ <context context-type="linenumber">8,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8770134622386151776" datatype="html">
+ <source>Telemetry activation reminder muted</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8352450862052130357" datatype="html">
+ <source>You can activate the module on the Telemetry configuration page (&lt;b&gt;Dashboard Settings&lt;/b&gt; -&gt; &lt;b&gt;Telemetry configuration&lt;/b&gt;) at any time.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bc9e5365a581105ce37cf47d1d74e4ad9eb75ce" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e634c306cab9e8879c3392593714c1ceab85437d" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3249513483374643425" datatype="html">
+ <source>Add</source>
+ <target>Tambah</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4359847060009771702" datatype="html">
+ <source>Set</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935187492052582731" datatype="html">
+ <source>Submit</source>
+ <target>Kirim</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4814285799071780083" datatype="html">
+ <source>Remove</source>
+ <target>Hapus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8363450564548681668" datatype="html">
+ <source>Unset</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2159130950882492111" datatype="html">
+ <source>Cancel</source>
+ <target>Batal</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1295614462098694869" datatype="html">
+ <source>Preview</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2354817630223808522" datatype="html">
+ <source>Move</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3885497195825665706" datatype="html">
+ <source>Next</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8890553633144307762" datatype="html">
+ <source>Back</source>
+ <target>Kembali</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5834780181397311898" datatype="html">
+ <source>Clone</source>
+ <target>Klon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4323470180912194028" datatype="html">
+ <source>Copy</source>
+ <target>Salin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2131301778880826094" datatype="html">
+ <source>Deep Scrub</source>
+ <target>Deep Scrub</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1704447209800801558" datatype="html">
+ <source>Destroy</source>
+ <target>Hancurkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8343007008325027187" datatype="html">
+ <source>Evict</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="408179081163888126" datatype="html">
+ <source>Flatten</source>
+ <target>Ratakan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="318900679147387932" datatype="html">
+ <source>Mark Down</source>
+ <target>Tandai Gugur</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5275142643521766706" datatype="html">
+ <source>Mark In</source>
+ <target>Tandai Masuk</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6973272903386150199" datatype="html">
+ <source>Mark Lost</source>
+ <target>Tandai Hilang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1962653792210847411" datatype="html">
+ <source>Mark Out</source>
+ <target>Tandai Keluar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4424610588915076517" datatype="html">
+ <source>Protect</source>
+ <target>Proteksi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6041115344061899387" datatype="html">
+ <source>Rename</source>
+ <target>Ubah nama</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">164</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6770769801335635194" datatype="html">
+ <source>Restore</source>
+ <target>Pulihkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2003230525878010676" datatype="html">
+ <source>Reweight</source>
+ <target>Ubah bobot</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5430834128563178593" datatype="html">
+ <source>Scrub</source>
+ <target>Scrub</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8461842260159597706" datatype="html">
+ <source>Show</source>
+ <target>Tampilkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5655608100705734230" datatype="html">
+ <source>Move to Trash</source>
+ <target>Pindahkan ke Tempat Sampah</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4622393909937403117" datatype="html">
+ <source>Unprotect</source>
+ <target>Tidak diproteksi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1230154438678955604" datatype="html">
+ <source>Change</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8450843381175865415" datatype="html">
+ <source>Enter Maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1610181371597502589" datatype="html">
+ <source>Exit Maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="676511611419004737" datatype="html">
+ <source>Start Drain</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7170653322511987983" datatype="html">
+ <source>Stop Drain</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5528551262937858942" datatype="html">
+ <source>Recreate</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2502364444688691031" datatype="html">
+ <source>Expire</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6381490568322624964" datatype="html">
+ <source>Deleted</source>
+ <target>Dihapus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="231679111972850796" datatype="html">
+ <source>Added</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5406093358072761930" datatype="html">
+ <source>Removed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3008573030448240863" datatype="html">
+ <source>Edited</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4381944803872489731" datatype="html">
+ <source>Canceled</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754993936947658096" datatype="html">
+ <source>Previewed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6001163963116907226" datatype="html">
+ <source>Moved</source>
+ <target>dipindahkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4932744777596632840" datatype="html">
+ <source>Cloned</source>
+ <target>Diklon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2115592966120408375" datatype="html">
+ <source>Copied</source>
+ <target>Disalin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7937474560394832586" datatype="html">
+ <source>Deep Scrubbed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6321562733889197649" datatype="html">
+ <source>Destroyed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7460162290177581995" datatype="html">
+ <source>Flattened</source>
+ <target>Diratakan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3662010055028969035" datatype="html">
+ <source>Marked Down</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5880434235404894589" datatype="html">
+ <source>Marked In</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="266997194072682078" datatype="html">
+ <source>Marked Lost</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">250</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4010544044592534535" datatype="html">
+ <source>Marked Out</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4776304093333411035" datatype="html">
+ <source>Protected</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2700903921419382511" datatype="html">
+ <source>Purged</source>
+ <target>Dibuang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5488667333459350160" datatype="html">
+ <source>Renamed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8044659850000829751" datatype="html">
+ <source>Restored</source>
+ <target>Dipulihkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559472082694466366" datatype="html">
+ <source>Reweighted</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022271525067453676" datatype="html">
+ <source>Rolled back</source>
+ <target>Dikembalikan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2483217756816388123" datatype="html">
+ <source>Scrubbed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7200036055090632378" datatype="html">
+ <source>Showed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7609648817347881129" datatype="html">
+ <source>Moved to Trash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7810326403606456469" datatype="html">
+ <source>Unprotected</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5620774899056099259" datatype="html">
+ <source>Recreated</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464749780222721589" datatype="html">
+ <source>Expired</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">266</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e5e23363e949f7dcbaf034bdb141a561132a10e" datatype="html">
+ <source>Clear filters</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80cc9a12d4bf6fe454ed94b379eeaf915f920bb7" datatype="html">
+ <source>selected</source>
+ <target>dipilih</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <note priority="1" from="description">X selected</note>
+ </trans-unit>
+ <trans-unit id="0cb77511a9a148e05b9adf36cc07269956fbb29d" datatype="html">
+ <source>found</source>
+ <target>ditemukan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <note priority="1" from="description">X found</note>
+ </trans-unit>
+ <trans-unit id="79347388740c50b7ac97e144c2494bb62912f312" datatype="html">
+ <source>total</source>
+ <target>total</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <note priority="1" from="description">X total</note>
+ </trans-unit>
+ <trans-unit id="2a3dab422cc892db037db8632bb84a6bf496e2d1" datatype="html">
+ <source>Expand/Collapse Row</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4047162422391207122" datatype="html">
+ <source>Failed to load data.</source>
+ <target>Gagal memuat data.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.ts</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="709331713250198508" datatype="html">
+ <source>Loading form data...</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3850344644863430180" datatype="html">
+ <source>Form data could not be loaded.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4626760504772708998" datatype="html">
+ <source>Size has to be at least <x id="PH" equiv-text="value"/> or more</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">428</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2880361802894657892" datatype="html">
+ <source>Size has to be at most <x id="PH" equiv-text="value"/> or less</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2807800733729323332" datatype="html">
+ <source>Yes</source>
+ <target>Ya</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3542042671420335679" datatype="html">
+ <source>No</source>
+ <target>Tidak</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7789266940050748913" datatype="html">
+ <source>in %s</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565573880632900017" datatype="html">
+ <source>%s ago</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="220300059326988179" datatype="html">
+ <source>a few seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2761143993878941513" datatype="html">
+ <source>%d seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7094767962693903153" datatype="html">
+ <source>a minute</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7597613755904774250" datatype="html">
+ <source>%d minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2757762976030115752" datatype="html">
+ <source>an hour</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9118454901758656303" datatype="html">
+ <source>%d hours</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7435193742089920080" datatype="html">
+ <source>a day</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1821334622562842480" datatype="html">
+ <source>%d days</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7375306199026780379" datatype="html">
+ <source>a week</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7272688256541915488" datatype="html">
+ <source>%d weeks</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5761124614324704118" datatype="html">
+ <source>a month</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="352195662913351589" datatype="html">
+ <source>%d months</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7562153591649199139" datatype="html">
+ <source>a year</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5424759741855527370" datatype="html">
+ <source>%d years</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7738182956549158907" datatype="html">
+ <source>Required rules for passwords:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8839765875053270528" datatype="html">
+ <source>Must contain at least <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> characters</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3098731108593590794" datatype="html">
+ <source>Must not be the same as the previous one</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9150236741862848105" datatype="html">
+ <source>Cannot contain the username</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6395043854518867543" datatype="html">
+ <source>Cannot contain any configured keyword</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="907558624910601703" datatype="html">
+ <source>Cannot contain any repetitive characters e.g. &quot;aaa&quot;</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514384270734082343" datatype="html">
+ <source>Cannot contain any sequential characters e.g. &quot;abc&quot;</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4119354814383293871" datatype="html">
+ <source>Must consist of characters from the following groups:
+ * Alphabetic a-z, A-Z
+ * Numbers 0-9
+ * Special chars: !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * Any other characters (signs)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">30,34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8649061117624699581" datatype="html">
+ <source>Your matcher seems to match no currently defined rule or active alert.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7122912874364762704" datatype="html">
+ <source>no active alerts</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7388215679576832341" datatype="html">
+ <source>1 active alert</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3112400568960537267" datatype="html">
+ <source><x id="PH" equiv-text="alerts"/> active alerts</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6264717417287230743" datatype="html">
+ <source>Matches 1 rule</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054663176394183966" datatype="html">
+ <source>Matches <x id="PH" equiv-text="rules"/> rules</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6674225401121099210" datatype="html">
+ <source><x id="PH" equiv-text="rule"/> with <x id="PH_1" equiv-text="alert"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5659908877047925719" datatype="html">
+ <source>Quality of Service</source>
+ <target>Kualitas Layanan atau QoS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1277565045885499475" datatype="html">
+ <source>BPS Limit</source>
+ <target>Limit BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2289210323987692906" datatype="html">
+ <source>The desired limit of IO bytes per second.</source>
+ <target>Limit IO bytes per detik yang diinginkan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753589939879013605" datatype="html">
+ <source>IOPS Limit</source>
+ <target>Limit IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2213985059444278522" datatype="html">
+ <source>The desired limit of IO operations per second.</source>
+ <target>Limit operasi IO per detik yang diinginkan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2487530611825582289" datatype="html">
+ <source>Read BPS Limit</source>
+ <target>Limit Baca BPS </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8071352270469595250" datatype="html">
+ <source>The desired limit of read bytes per second.</source>
+ <target>Limit byte baca per detik yang diinginkan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1632513758247239690" datatype="html">
+ <source>Read IOPS Limit</source>
+ <target>Limit IOPS Baca</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2361786794607418566" datatype="html">
+ <source>The desired limit of read operations per second.</source>
+ <target>Limit operasi baca per detik yang diinginkan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="894600353504285551" datatype="html">
+ <source>Write BPS Limit</source>
+ <target>Limit Tulis BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911437671369366025" datatype="html">
+ <source>The desired limit of write bytes per second.</source>
+ <target>Limit tulis byte per detik yang diinginkan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2947346368707443195" datatype="html">
+ <source>Write IOPS Limit</source>
+ <target>Limit IOPS Tulis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5506349527983391356" datatype="html">
+ <source>The desired limit of write operations per second.</source>
+ <target>Limit operasi tulis per detik yang diinginkan.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559424229658244943" datatype="html">
+ <source>BPS Burst</source>
+ <target>Letupan BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3454058701331860330" datatype="html">
+ <source>The desired burst limit of IO bytes.</source>
+ <target>Limit yang diinginkan untuk letupan atau burst dari IO byte.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171005761926448741" datatype="html">
+ <source>IOPS Burst</source>
+ <target>Letupan IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4939532784700485729" datatype="html">
+ <source>The desired burst limit of IO operations.</source>
+ <target>Limit yang diinginkan untuk letupan atau burst operasi IO.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6273492199526646930" datatype="html">
+ <source>Read BPS Burst</source>
+ <target>Letupan Baca BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3105467595643777520" datatype="html">
+ <source>The desired burst limit of read bytes.</source>
+ <target>Limit yang diinginkan untuk letupan atau burst dari baca byte.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2170715106679765467" datatype="html">
+ <source>Read IOPS Burst</source>
+ <target>Letupan IOPS Baca</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6234106755510510672" datatype="html">
+ <source>The desired burst limit of read operations.</source>
+ <target>Limit yang diinginkan untuk letupan atau burst operasi baca.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="228509518172572466" datatype="html">
+ <source>Write BPS Burst</source>
+ <target>Letupan BPS Tulis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7803279807796571240" datatype="html">
+ <source>The desired burst limit of write bytes.</source>
+ <target>Limit yang diinginkan untuk letupan atau burst dari tulis byte.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9125474584914848055" datatype="html">
+ <source>Write IOPS Burst</source>
+ <target>Letupan IOPS Tulis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5839129348567326667" datatype="html">
+ <source>The desired burst limit of write operations.</source>
+ <target>Limit yang diinginkan untuk letupan atau burst dari operasi baca.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="614961883076556986" datatype="html">
+ <source>Failed to <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="489145301781720653" datatype="html">
+ <source>Executing</source>
+ <target>Mengeksekusi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4238828029954346941" datatype="html">
+ <source>execute</source>
+ <target>eksekusi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7196604637389554584" datatype="html">
+ <source>Executed</source>
+ <target>Dieksekusi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4418441687454700644" datatype="html">
+ <source>unknown task</source>
+ <target>tugas tak diketahui</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8667665916832796867" datatype="html">
+ <source>Creating</source>
+ <target>Membuat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6031236679730054907" datatype="html">
+ <source>create</source>
+ <target>buat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5593033420216313122" datatype="html">
+ <source>Updating</source>
+ <target>Memperbarui</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6100869651653026893" datatype="html">
+ <source>update</source>
+ <target>perbarui</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3141301060598402455" datatype="html">
+ <source>Deleting</source>
+ <target>Menghapus</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3420504288275541125" datatype="html">
+ <source>Adding</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1059784693423848532" datatype="html">
+ <source>add</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594819887188505274" datatype="html">
+ <source>Removing</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2123171795960509943" datatype="html">
+ <source>remove</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1946427188770321847" datatype="html">
+ <source>Importing</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8495827411619139669" datatype="html">
+ <source>import</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218459863491436562" datatype="html">
+ <source>Imported</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6534993668932538712" datatype="html">
+ <source>RBD '<x id="PH" equiv-text="metadata.image_spec"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8237287859948228705" datatype="html">
+ <source>RBD snapshot '<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2328067975897167268" datatype="html">
+ <source>mirroring site name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4433460322631470833" datatype="html">
+ <source>bootstrap token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7044591639782280183" datatype="html">
+ <source>mirror mode for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7109746474198366468" datatype="html">
+ <source>mirror peer for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6201476020617351396" datatype="html">
+ <source>all dashboards</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7268953097700363232" datatype="html">
+ <source>Identifying</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4337678035264231187" datatype="html">
+ <source>identify</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7257219307556106552" datatype="html">
+ <source>Identified</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6002370161381995023" datatype="html">
+ <source>device '<x id="PH" equiv-text="metadata.device"/>' on host '<x id="PH_1" equiv-text="metadata.hostname"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5580298273054260850" datatype="html">
+ <source>OSDs (DriveGroups: <x id="PH" equiv-text="metadata.tracking_id"/>)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2182125722527364040" datatype="html">
+ <source>Name is already used by <x id="PH" equiv-text="this.pool(metadata)"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">182</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7892856315477304281" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> is busy.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4690045751984117407" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> contains snapshots.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="562148565853868662" datatype="html">
+ <source>Cloning</source>
+ <target>Pengklonan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1197352830433807469" datatype="html">
+ <source>clone</source>
+ <target>klon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1692004144561317867" datatype="html">
+ <source>Snapshot of <x id="PH" equiv-text="this.rbd.child(metadata)"/> must be protected.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8531200838331320284" datatype="html">
+ <source>Copying</source>
+ <target>Menyalin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6862265996781523030" datatype="html">
+ <source>copy</source>
+ <target>salin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3556912098733712857" datatype="html">
+ <source>Flattening</source>
+ <target>Meratakan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2488773646187451754" datatype="html">
+ <source>flatten</source>
+ <target>ratakan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="704305783678486635" datatype="html">
+ <source>Cannot unprotect <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> because it contains child images.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">223,225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101271773452792348" datatype="html">
+ <source>Cannot delete <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/> because it's protected.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5143010940199748580" datatype="html">
+ <source>Rolling back</source>
+ <target>Mengembalikan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1315686250907089544" datatype="html">
+ <source>rollback</source>
+ <target>kembalikan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5010267418211867946" datatype="html">
+ <source>Moving</source>
+ <target>Memindahkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4366763205960752449" datatype="html">
+ <source>move</source>
+ <target>pindah</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="695867152524584829" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_spec"/>' to trash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423442774536615202" datatype="html">
+ <source>Could not find image.</source>
+ <target>Tidak dapat menemukan image.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2622324641113512527" datatype="html">
+ <source>Restoring</source>
+ <target>Memulihkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3347932678307141902" datatype="html">
+ <source>restore</source>
+ <target>pulihkan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7488038030362249932" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>' into '<x id="PH_1" equiv-text="metadata.new_image_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565688512490959949" datatype="html">
+ <source>Image name '<x id="PH" equiv-text="metadata.new_image_name"/>' is already in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6331051389974655106" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8245559899946787147" datatype="html">
+ <source>Purging</source>
+ <target>Membuang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7879437654311684252" datatype="html">
+ <source>purge</source>
+ <target>buang</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1440427157062670480" datatype="html">
+ <source>all pools</source>
+ <target>semua pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8677740163708263843" datatype="html">
+ <source>images from <x id="PH" equiv-text="message"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011237345035114219" datatype="html">
+ <source>Cannot disable mirroring because it contains a peer.</source>
+ <target>Gagal menonaktifkan pencerminan karena sedang bermitra.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">292</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7391584598242145869" datatype="html">
+ <source>host '<x id="PH" equiv-text="metadata.hostname"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6964302691596180722" datatype="html">
+ <source>OSD '<x id="PH" equiv-text="metadata.svc_id"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="488305686602466689" datatype="html">
+ <source>pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5921392748828575278" datatype="html">
+ <source>erasure code profile '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2423915105798557698" datatype="html">
+ <source>crush rule '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">370</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8273044996643438592" datatype="html">
+ <source>target '<x id="PH" equiv-text="metadata.target_iqn"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5474643443735437364" datatype="html">
+ <source>NFS '<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">378,380</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2235495382025026939" datatype="html">
+ <source>Service '<x id="PH" equiv-text="metadata.service_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ </body>
+ </file>
+</xliff> \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.it-IT.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.it-IT.xlf
new file mode 100644
index 000000000..2ee6f5329
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.it-IT.xlf
@@ -0,0 +1,14885 @@
+<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en-US" datatype="plaintext" original="ng2.template" target-language="it-IT">
+ <body>
+ <trans-unit id="ngb.alert.close" datatype="html">
+ <source>Close</source>
+ <target>Chiudi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/alert/alert.ts</context>
+ <context context-type="linenumber">58,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.slide-number" datatype="html">
+ <source> Slide <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> of <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </source>
+ <target> Slide <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> di <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">114,118</context>
+ </context-group>
+ <note priority="1" from="description">Currently selected slide number read by screen reader</note>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.previous" datatype="html">
+ <source>Previous</source>
+ <target>Precedente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">132,134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.next" datatype="html">
+ <source>Next</source>
+ <target>Successiva</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">147,152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-month" datatype="html">
+ <source>Select month</source>
+ <target>Seleziona mese</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">44,49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">49,50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-year" datatype="html">
+ <source>Select year</source>
+ <target>Seleziona anno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">59,63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.previous-month" datatype="html">
+ <source>Previous month</source>
+ <target>Mese precedente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">24,27</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">35,36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.next-month" datatype="html">
+ <source>Next month</source>
+ <target>Mese successivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">47,50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">60,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first" datatype="html">
+ <source>««</source>
+ <target>««</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">182,183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous" datatype="html">
+ <source>«</source>
+ <target>«</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">186,190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next" datatype="html">
+ <source>»</source>
+ <target>»</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">194,195</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last" datatype="html">
+ <source>»»</source>
+ <target>»»</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">201,204</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first-aria" datatype="html">
+ <source>First</source>
+ <target>Primo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">208,209</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous-aria" datatype="html">
+ <source>Previous</source>
+ <target>Precedente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">215,216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next-aria" datatype="html">
+ <source>Next</source>
+ <target>Successivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">226,228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last-aria" datatype="html">
+ <source>Last</source>
+ <target>Ultimo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.progressbar.value" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="; } /** *"/></source>
+ <target><x id="INTERPOLATION" equiv-text="; } /** *"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/progressbar/progressbar.ts</context>
+ <context context-type="linenumber">32,38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.HH" datatype="html">
+ <source>HH</source>
+ <target>HH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">40,41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.hours" datatype="html">
+ <source>Hours</source>
+ <target>Ore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.MM" datatype="html">
+ <source>MM</source>
+ <target>MM</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">51,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.minutes" datatype="html">
+ <source>Minutes</source>
+ <target>Minuti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-hours" datatype="html">
+ <source>Increment hours</source>
+ <target>Incremento ore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">63,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-hours" datatype="html">
+ <source>Decrement hours</source>
+ <target>Decremento ore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">69,70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-minutes" datatype="html">
+ <source>Increment minutes</source>
+ <target>Incremento minuti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">76,78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-minutes" datatype="html">
+ <source>Decrement minutes</source>
+ <target>Decremento minuti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">82,84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.SS" datatype="html">
+ <source>SS</source>
+ <target>SS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.seconds" datatype="html">
+ <source>Seconds</source>
+ <target>Secondi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">92,93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-seconds" datatype="html">
+ <source>Increment seconds</source>
+ <target>Incremento secondi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">100,101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-seconds" datatype="html">
+ <source>Decrement seconds</source>
+ <target>Decremento secondi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">106,110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.AM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></source>
+ <target><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">115,121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.PM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="t() meridian: b"/></source>
+ <target><x id="INTERPOLATION" equiv-text="t() meridian: b"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">123,131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.toast.close-aria" datatype="html">
+ <source>Close</source>
+ <target>Chiudi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/toast/toast.ts</context>
+ <context context-type="linenumber">78,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8835b9e49a3348b0a2f2162c21118af1f4bee45a" datatype="html">
+ <source>Must be greater than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>.</source>
+ <target>Deve essere superiore o uguale a <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbddac59563c8c126e3fe28691e4e247614fcbd1" datatype="html">
+ <source>Must be less than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>.</source>
+ <target>Deve essere inferiore o uguale a <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5" datatype="html">
+ <source>Overview</source>
+ <target>Panoramica</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbd2045d5c37e4bb39a3c0fb62ea1ddf70a12838" datatype="html">
+ <source>Targets</source>
+ <target>Destinazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a674ab267d1934bf395f87ca1503fd474296893f" datatype="html">
+ <source>iSCSI Topology</source>
+ <target>Topologia iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8953033926734869941" datatype="html">
+ <source>Name</source>
+ <target>Nome</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6603000223840533819" datatype="html">
+ <source>Current</source>
+ <target>Attuale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5607669932062416162" datatype="html">
+ <source>Default</source>
+ <target>Default</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6803e31b7395d94934e091a49a9524026b59b018" datatype="html">
+ <source>Discovery Authentication</source>
+ <target>Autenticazione rilevazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e08a77594f3d89311cdf6da5090044270909c194" datatype="html">
+ <source>User</source>
+ <target>Utente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">381</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7cbdabcece469fab89cfa687ab152bca18b97498" datatype="html">
+ <source>This field is required.</source>
+ <target>Questo campo è obbligatorio.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">368</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">423</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">481</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">291</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">343</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">407</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">490</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">516</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">556</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">573</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">590</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">647</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">672</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">299</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">195</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">520</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">614</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">651</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f717bad2da5944a2567a52f971ccc6806db85805" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>I nomi utente devono avere una lunghezza compresa tra 8 e 64 caratteri e possono contenere caratteri alfanumerici: '.', '@', '-', '_' o ':'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">28,29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">85,86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c32ef07f8803a223a83ed17024b38e8d82292407" datatype="html">
+ <source>Password</source>
+ <target>Password</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">403</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">581</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="001e1836299d8d3b84eaebe2fa051325beab3f00" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>Le password devono avere una lunghezza compresa tra 12 e 16 caratteri e possono contenere caratteri alfanumerici: '@', '-', '_' o '/'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">61,62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">118,119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff40391de7a1944ea95091e4045cc34c4979b736" datatype="html">
+ <source>Mutual User</source>
+ <target>Utente reciproco</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cf73dbebe99b737c4d288788182fc356e3c93d3" datatype="html">
+ <source>Mutual Password</source>
+ <target>Password reciproca</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594987303599690088" datatype="html">
+ <source>Updated discovery authentication</source>
+ <target>Autenticazione rilevazione aggiornata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb127ea03835b3230f0ed981c7080e2ccb879621" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <note priority="1" from="description">form title</note>
+ </trans-unit>
+ <trans-unit id="1406c2fb12a20c1528b19bcc5e24a6a2386167f3" datatype="html">
+ <source>Target IQN</source>
+ <target>IQN di destinazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5fe42339be910372fa689f559155631862d218e8" datatype="html">
+ <source>IQN has wrong pattern.</source>
+ <target>IQN contiene un modello errato.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="050a7ff057d1e895357540406b6be5652b4d1c71" datatype="html">
+ <source>An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'</source>
+ <target>Un IQN contiene la notazione seguente 'iqn.$year-$month.$reversedAddress:$definedName'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8ada4b53396d8366db00a435acc61d53d857047" datatype="html">
+ <source>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</source>
+ <target>Ad esempio: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e" datatype="html">
+ <source>More information</source>
+ <target>Ulteriori informazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9b1aa85dfc6849196e64060db02c5410de69b7a1" datatype="html">
+ <source>This target has modified advanced settings.</source>
+ <target>Questa destinazione contiene impostazioni avanzate modificate.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6990ad8d6182662e864495ac31c3758cda1c7a28" datatype="html">
+ <source>Portals</source>
+ <target>Portali</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a3ac2b4137d723fd9878cd357c2012ff6c07973" datatype="html">
+ <source>Add portal</source>
+ <target>Aggiungi portale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3638c01b6c34066438909713ec96087c813fc7e" datatype="html">
+ <source>At least <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> gateways are required.</source>
+ <target>Specificare almeno <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> gateway.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b73f7f5060fb22a1e9ec462b1bb02493fa3ab866" datatype="html">
+ <source>Images</source>
+ <target>Immagini</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">495</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">629</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9aff25be088f0efe3eaaf62edf2bff41cc41a617" datatype="html">
+ <source>Backstore: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </source>
+ <target>Backstore: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e3484cae8b118c576ca2815bf9c9406c2eb2cae3" datatype="html">
+ <source>This image has modified settings.</source>
+ <target>Questa immagine contiene impostazioni modificate.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1dff11e0820b6722ab240169f1232d70a54beaaa" datatype="html">
+ <source>Duplicated LUN numbers.</source>
+ <target>Numeri LUN duplicati.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bf2dccf92ccff6e3b091792bf4205595406e1bfb" datatype="html">
+ <source>Duplicated WWN.</source>
+ <target>WWN duplicati.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="808038f912fdc7f0e03f82d4afd3bf9178527fc8" datatype="html">
+ <source>Add image</source>
+ <target>Aggiungi immagine</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">656</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66c5fb27f52e75b70ca4b670b9b15a2a51cf9543" datatype="html">
+ <source>ACL authentication</source>
+ <target>Autenticazione ACL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="137fbf154ecad4d580354db0858b76faea7e4686" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>I nomi utente devono avere una lunghezza compresa tra 8 e 64 caratteri e possono contenere caratteri alfanumerici: '.', '@', '-', '_' o ':'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">227,228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">287,288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="361771c32dd2254d77fd3fbf006b008983fe5907" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>Le password devono avere una lunghezza compresa tra 12 e 16 caratteri e possono contenere caratteri alfanumerici: '@', '-', '_' o '/'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">262,263</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">323,324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f494bd31f095f6dcc656ce87ec2dcf07a2e9b30c" datatype="html">
+ <source>Initiators</source>
+ <target>Iniziatori</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">335</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">588</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e98239d8a6be1100119ff4b5630c822b82786740" datatype="html">
+ <source>Initiator</source>
+ <target>Iniziatore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2c5059d8cda15d8d03e2cce30f2d139623d9a91" datatype="html">
+ <source>Client IQN</source>
+ <target>IQN client</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="107d5aabce23d900f0a80e6ddc1c10e29aa0bed8" datatype="html">
+ <source>Initiator IQN needs to be unique.</source>
+ <target>L'IQN dell'iniziatore deve essere univoco.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e7cad911fa524e512d9744b16358b7ee6791385" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>I nomi utente devono avere una lunghezza compresa tra 8 e 64 caratteri e possono contenere caratteri alfanumerici: '.', '@', '-', '_' o ':'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">394,395</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">452,453</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7f2c186d181206d0d2b1ff74819081a010f10bf" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>Le password devono avere una lunghezza compresa tra 12 e 16 caratteri e possono contenere caratteri alfanumerici: '@', '-', '_' o '/'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">427,428</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">485,486</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d1878d5fc761cbe9614bfd87047a740c82a6951" datatype="html">
+ <source>Initiator belongs to a group. Images will be configure in the group.</source>
+ <target>L'iniziatore appartiene a un gruppo. Le immagini verranno configurate nel gruppo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">515</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0de67b9d97fafbf200f9451e8388ee8128a56ac" datatype="html">
+ <source>No items added.</source>
+ <target>Nessun elemento aggiunto.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">671</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d565e47726158e428ecdc952fc9233b9b7d7f049" datatype="html">
+ <source>Add initiator</source>
+ <target>Aggiungi iniziatore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">616</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c22ba03540aa3217da059f45e7eab138b51a96e2" datatype="html">
+ <source>Groups</source>
+ <target>Gruppi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c90059afafb7e160384d9f512797c95bb95c6dc" datatype="html">
+ <source>Group</source>
+ <target>Gruppo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cff1428d10d59d14e45edec3c735a27b5482db59" datatype="html">
+ <source>Name</source>
+ <target>Nome</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">576</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3084948274cff4f56d0f431af47240e9cf02fcc7" datatype="html">
+ <source>Add group</source>
+ <target>Aggiungi gruppo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">676</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6634268061646442252" datatype="html">
+ <source>There are no portals available.</source>
+ <target>Nessun portale disponibile.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4587015892789840153" datatype="html">
+ <source>There are no images available.</source>
+ <target>Nessuna immagine disponibile.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7896905042057267575" datatype="html">
+ <source>There are no images available. Please make sure you add an image to the target.</source>
+ <target>Nessuna immagine disponibile. Assicurarsi di aggiungere un'immagine alla destinazione.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6765423558085969805" datatype="html">
+ <source>There are no initiators available. Please make sure you add an initiator to the target.</source>
+ <target>Nessun iniziatore disponibile. Assicurarsi di aggiungere un iniziatore alla destinazione.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2539932200265667453" datatype="html">
+ <source>target</source>
+ <target>destinazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="051dcc342cfa5c1eaf187a2001aaa162379a160c" datatype="html">
+ <source>Configure</source>
+ <target>Configura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e515f954730279c31d5301f02479666d6264e8b" datatype="html">
+ <source>Changing these parameters from their default values is usually not necessary.</source>
+ <target>Di solito non è necessario modificare questi parametri rispetto ai valori di default.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e2591df099ddac796cda401c5f282da779d45f2" datatype="html">
+ <source>Identifier</source>
+ <target>Identificatore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62480a4859976427cf18fc8ef41d3a438eda0412" datatype="html">
+ <source>lun</source>
+ <target>lun</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8afc9eb4405e0aa554b2ba14140ef790cdecc040" datatype="html">
+ <source>wwn</source>
+ <target>wwn</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
+ <source>Settings</source>
+ <target>Impostazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69a47cbabcc51ca942606e1d8da0ec11f98a2690" datatype="html">
+ <source>Backstore</source>
+ <target>Backstore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="339878da255ab55447c43afef8d9b2f9753bf5f6" datatype="html">
+ <source>Advanced Settings</source>
+ <target>Impostazioni avanzate</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="332227f088a4877b3c11f5fb3ae8bc812c470fae" datatype="html">
+ <source>iSCSI Targets not available</source>
+ <target>Destinazioni iSCSI non disponibili</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7fba666f1fff0182e570f12133fb3d622d9ea6" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the iSCSI Targets management functionality.</source>
+ <target>Per informazioni su come configurare e abilitare la funzionalità di gestione delle destinazioni iSCSI, consultare <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3b301d0044f62c92af0da53d7aaca52a436a547d" datatype="html">
+ <source>Available information:</source>
+ <target>Informazioni disponibili:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8414a5cb9d71cc1b21b10e4a9d1f2dad558f3361" datatype="html">
+ <source>Discovery authentication</source>
+ <target>Autenticazione rilevazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4854396465510517671" datatype="html">
+ <source>Target</source>
+ <target>Destinazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4093869278527257288" datatype="html">
+ <source>Portals</source>
+ <target>Portali</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="414887388288176527" datatype="html">
+ <source>Images</source>
+ <target>Immagini</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="798573158169239055" datatype="html">
+ <source># Sessions</source>
+ <target>N. sessioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="646929398175374220" datatype="html">
+ <source>Unavailable gateway(s)</source>
+ <target>Gateway non disponibili</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2350612272163013640" datatype="html">
+ <source>Target has active sessions</source>
+ <target>La destinazione contiene sessioni attive</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4782410538666829801" datatype="html">
+ <source>iSCSI target</source>
+ <target>Destinazione iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">227</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8a9910cd114c1deb9af74f6f99b4173403965bf2" datatype="html">
+ <source>Gateways</source>
+ <target>Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911214550882917183" datatype="html">
+ <source>State</source>
+ <target>Stato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4121862424558610140" datatype="html">
+ <source># Targets</source>
+ <target>N. destinazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101197021456818771" datatype="html">
+ <source>Pool</source>
+ <target>Pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3012906865384504293" datatype="html">
+ <source>Image</source>
+ <target>Immagine</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2699995524827665158" datatype="html">
+ <source>Backstore</source>
+ <target>Backstore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3559214740809905405" datatype="html">
+ <source>Read Bytes</source>
+ <target>Byte letti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1580583760095064067" datatype="html">
+ <source>Write Bytes</source>
+ <target>Byte scritti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7225917547116479918" datatype="html">
+ <source>Read Ops</source>
+ <target>Operazioni di lettura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6417507714454914481" datatype="html">
+ <source>Write Ops</source>
+ <target>Operazioni di scrittura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="257147267065394003" datatype="html">
+ <source>A/O Since</source>
+ <target>A/O da</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ecbc084370a732fc3cde1966a60af78d71424ab4" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>Crea token di bootstrap</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603e9cc3ef2aab57f2b0a00e465b23b9cabefd9c" datatype="html">
+ <source>To create a bootstrap token which can be imported by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Generate<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Per creare un token di bootstrap che può essere importato da un cluster di un sito peer, fornire il nome del sito locale, selezionare i pool che avranno abilitata la creazione di copie speculari e fare clic su <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Genera<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="660f97cd3188f8a04bd03b79e703fec72c6df04c" datatype="html">
+ <source>Site Name</source>
+ <target>Nome sito</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2fecea01ce1d44114ee45144eff6d47a5016a74f" datatype="html">
+ <source>Name...</source>
+ <target>Nome...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92899fa68e8ca108912163ff58edc8540e453787" datatype="html">
+ <source>Pools</source>
+ <target>Pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c2a1dc72cffaf7ab3dc5599bf77b0a7fcad2b20" datatype="html">
+ <source>At least one pool is required.</source>
+ <target>È richiesto almeno un pool.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b258b258b4cc475ceb2871305b61756b0134f4a" datatype="html">
+ <source>Generate</source>
+ <target>Genera</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1edc1fc6cfbbb22353050ad6788508b3ed584f53" datatype="html">
+ <source>Token</source>
+ <target>Token</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff785f5596aef34a93b9b4d1023e95c62eef5740" datatype="html">
+ <source>Generated token...</source>
+ <target>Token generato...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8" datatype="html">
+ <source>Close</source>
+ <target>Chiudi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5467a6bb0e7fade6def7499400d5e2a7d8d3da20" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>Importa token di bootstrap</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bb7aee0dec5164f45c0aa2f35f2fb2149d2c1d2" datatype="html">
+ <source>To import a bootstrap token which was created by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, provide the generated token, and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Import<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Per importare un token di bootstrap creato da un cluster di un sito peer, fornire il nome del sito locale, selezionare i pool che avranno abilitata la creazione di copie speculari, specificare il token generato e fare clic su <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Importa<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9200e09686136a1d42adfb89c12fbfef2deea125" datatype="html">
+ <source>Direction</source>
+ <target>Direzione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9761484679958da8d12841a4efa5964d33fae575" datatype="html">
+ <source>The token is invalid.</source>
+ <target>Il token non è valido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2381859602529023966" datatype="html">
+ <source>Instance</source>
+ <target>Istanza</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8040881171107393560" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1605455101862010019" datatype="html">
+ <source>Hostname</source>
+ <target>Nome host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2724055831234181057" datatype="html">
+ <source>Version</source>
+ <target>Versione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2041675390931385838" datatype="html">
+ <source>Health</source>
+ <target>Integrità</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87bd96249f8afc23f5301cddb57b1464a98e71a" datatype="html">
+ <source>Edit site name</source>
+ <target>Modifica nome sito</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cfff72c667274c12eb1ff71eadc25871c10c42dc" datatype="html">
+ <source>Edit the site name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Modificare il nome del sito e fare clic su <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Aggiorna<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">13,14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66db799d67958d4b0765181d072df62e2d1c16f5" datatype="html">
+ <source>Issues</source>
+ <target>Problemi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef06d69259e587e28d52372455f44c7153cda7e7" datatype="html">
+ <source>Syncing</source>
+ <target>Sincronizzazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0b0901877d837d3fda16ba161eb74368d1c75b7a" datatype="html">
+ <source>Ready</source>
+ <target>Pronto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5833626790712999947" datatype="html">
+ <source>Issue</source>
+ <target>Problema</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3419681791450150574" datatype="html">
+ <source>Progress</source>
+ <target>Avanzamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4902817035128594900" datatype="html">
+ <source>Description</source>
+ <target>Descrizione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40b7acea5b43f45e0bbd1efeba5200af4687981d" datatype="html">
+ <source>Site Name:</source>
+ <target>Nome sito:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e24f9e2d42104ffc01599db4d566d1cc518f9e6" datatype="html">
+ <source>Daemons</source>
+ <target>Daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6450386891540681425" datatype="html">
+ <source>Edit Site Name</source>
+ <target>Modifica nome sito</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4645993115976933405" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>Crea token di bootstrap</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4130053543590533787" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>Importa token di bootstrap</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4057c56d63a7e9b140b1d01871a9229a5f30eb27" datatype="html">
+ <source>Edit pool mirror mode</source>
+ <target>Modifica modalità di copia speculare per il pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e1f367f5feaab38f6637dd1f967c848b447dea2d" datatype="html">
+ <source>To edit the mirror mode for pool  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, select a new mode from the list and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Per modificare la modalità di copia speculare per il pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, selezionare una nuova modalità dall'elenco e fare clic su <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Aggiorna<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37e10df2d9c0c25ef04ac112c9c9a7723e8efae0" datatype="html">
+ <source>Mode</source>
+ <target>Modalità</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">426</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32ca348ef926b0a6a7a780b8b64c3a8239895cec" datatype="html">
+ <source>Peer clusters must be removed prior to disabling mirror.</source>
+ <target>È necessario rimuovere i cluster peer prima di disabilitare la copia speculare.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5769292297914455214" datatype="html">
+ <source>Disabled</source>
+ <target>Disabilitato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ddcb416c1c0aa1f54acf5beef1de81813e76fa6" datatype="html">
+ <source>{VAR_SELECT, select, edit {Edit} other {Add}}</source>
+ <target>{VAR_SELECT, select, edit {Modificare} other {Aggiungere}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3aa7c3a4f7b0cf7c2e60fc71ea1e3b4c3efa3558" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> pool mirror peer</source>
+ <target><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> peer copia speculare del pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="59ca65ece457429d90104ede4674965f62edbabe" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> the pool mirror peer attributes for pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Submit<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> gli attributi del peer copia speculare del pool per il pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> e fare clic su <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Invia<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d3cc964811f852a168f4a2d5daa59068abc5cf53" datatype="html">
+ <source>Cluster Name</source>
+ <target>Nome cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b631721fc56cb7fb1cbd07b802a487c5753f6a2d" datatype="html">
+ <source>The cluster name is not valid.</source>
+ <target>Il nome del cluster non è valido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca6deafa31bf421f85094807982aee4bcb20a3ae" datatype="html">
+ <source>CephX ID</source>
+ <target>ID CephX</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7539188a568c3d553cbde1bacaf32310c4264e24" datatype="html">
+ <source>CephX ID...</source>
+ <target>ID CephX...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1c45b594b0fba22fc64e80c793a7ffe005fdb0e" datatype="html">
+ <source>The CephX ID is not valid.</source>
+ <target>L'ID CephX non è valido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20861576fcfce773c918c782cd4f5adf32382921" datatype="html">
+ <source>Monitor Addresses</source>
+ <target>Indirizzi dei monitor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fa28eeed2b4bd4ccbe6e9349a1c2b3cb1c5de70a" datatype="html">
+ <source>Comma-delimited addresses...</source>
+ <target>Indirizzi con valori delimitati da virgole...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dc016c82fd85848d5c1b2fd0e8469ee2027d9c16" datatype="html">
+ <source>The monitory address is not valid.</source>
+ <target>L'indirizzo del monitor non è valido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0ac55b83dc6739e62bc655cfe375b67c93e7f4a" datatype="html">
+ <source>CephX Key</source>
+ <target>Chiave CephX</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f53434bcb95bd86f1df9c8e22966f757614fc4ad" datatype="html">
+ <source>Base64-encoded key...</source>
+ <target>Chiave con codifica Base64...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4cd83164cd4f66b4abc2863f9ce6f599d789e4ca" datatype="html">
+ <source>CephX key must be base64 encoded.</source>
+ <target>La chiave CephX deve essere con codifica Base64.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6407712033679505505" datatype="html">
+ <source>Edit Mode</source>
+ <target>Modalità di modifica</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054237897979907103" datatype="html">
+ <source>Add Peer</source>
+ <target>Aggiungi peer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="899134641637789371" datatype="html">
+ <source>Edit Peer</source>
+ <target>Modifica peer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7393680121674824053" datatype="html">
+ <source>Delete Peer</source>
+ <target>Elimina peer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1713271461473302108" datatype="html">
+ <source>Mode</source>
+ <target>Modalità</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1061297288634362831" datatype="html">
+ <source>Leader</source>
+ <target>Sequenza iniziale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8517494870558773093" datatype="html">
+ <source># Local</source>
+ <target>N. locale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4953753699491987394" datatype="html">
+ <source># Remote</source>
+ <target>N. remoto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1715982232168082172" datatype="html">
+ <source>mirror peer</source>
+ <target>peer copia speculare</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff92fbdec9fdd5054493eeda0d7ee8b450f83e72" datatype="html">
+ <source>RBD Configuration</source>
+ <target>Configurazione RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b62d9efc8eb3b589904f6cb96a0406bbda55673a" datatype="html">
+ <source>Remove the local configuration value. The parent configuration value will be inherited and used instead.</source>
+ <target>Rimuovere il valore della configurazione locale. Al suo posto verrà ereditato e utilizzato il valore della configurazione superiore.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80d769fd863fe44fab689636a078466bfdbd1f20" datatype="html">
+ <source>The minimum value is 0</source>
+ <target>Il valore minimo è 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5decb3917d46a9ac6e5813699801becb7c3c1455" datatype="html">
+ <source>Global</source>
+ <target>Globale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f9ba9bb9faa8284bcadb1cdbc6aaf969e9c4bb" datatype="html">
+ <source>Image</source>
+ <target>Immagine</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70fcca5a99575cffef3ff8cbd5e69f06ffd0f1c" datatype="html">
+ <source>Pool</source>
+ <target>Pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176659033176029418" datatype="html">
+ <source>Key</source>
+ <target>Chiave</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9155608366859514313" datatype="html">
+ <source>Source</source>
+ <target>Origine</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6555318547274416232" datatype="html">
+ <source>Value</source>
+ <target>Valore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f6e8f6094b180eaf1f11bc0ffe383f1cdcd059e" datatype="html">
+ <source>Only available for RBD images with <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> enabled</source>
+ <target>Disponibile solo per le immagini RBD con l'opzione <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> abilitata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f8b2bb476981727ab34ed40fde1218361f92c45" datatype="html">
+ <source>Details</source>
+ <target>Dettagli</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03cc5b14b0a20d075e9009ff021f4f1660ba348a" datatype="html">
+ <source>Data Pool</source>
+ <target>Pool di dati</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b051734b0ee9021991c91b3ed4e81c244322462" datatype="html">
+ <source>Created</source>
+ <target>Creato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7faaaa08f56427999f3be41df1093ce4089bbd75" datatype="html">
+ <source>Size</source>
+ <target>Dimensioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="afdb601c16162f2c798b16a2920955f1cc6a20aa" datatype="html">
+ <source>Objects</source>
+ <target>Oggetti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ceac8e132384322ec778ba760875a6c6897d3e42" datatype="html">
+ <source>Object size</source>
+ <target>Dimensioni oggetto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cdb1fea93d77c07950c0c76c6e0ad79ebbef084" datatype="html">
+ <source>Features</source>
+ <target>Funzioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65771c9a73b9aa609d592fc96a64801a8f40bd" datatype="html">
+ <source>Provisioned</source>
+ <target>Soggetto al provisioning</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84a36cb75660b736773fe36ffa3d54f0f0fe363e" datatype="html">
+ <source>N/A</source>
+ <target>N/D</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c009342a4e8381f64341d0bb61c2e4685f5a4b" datatype="html">
+ <source>Total provisioned</source>
+ <target>Totale soggetto al provisioning</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f6bf8a43ae415f527ac961ea62471b983aaa97b" datatype="html">
+ <source>Striping unit</source>
+ <target>Unità di striping</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db710e8a8f011923f2d15d713fbae49c38b02b26" datatype="html">
+ <source>Striping count</source>
+ <target>Conteggio di striping</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a4c2a9e76634ff14a60d52a718296f722d47c67" datatype="html">
+ <source>Parent</source>
+ <target>Superiore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a209e68d78ffc2cc9c53d2e76158624efab71ad" datatype="html">
+ <source>Block name prefix</source>
+ <target>Prefisso nome blocco</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5704ec2049d007c5f5fb495a5d8b607e68d58081" datatype="html">
+ <source>Order</source>
+ <target>Ordine</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="984cb6ad70f150a401b4daf841bd3cd957412699" datatype="html">
+ <source>Format Version</source>
+ <target>Versione formato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f21b1d17b6c5042bb5805516eee37fde33739dd8" datatype="html">
+ <source>Snapshots</source>
+ <target>Snapshot</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4a41f824a35ba01d5bd7be61aa06b3e8145209d0" datatype="html">
+ <source>Configuration</source>
+ <target>Configurazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3cc9c2ae277393b3946b38c088dabff671b1ee1b" datatype="html">
+ <source>Performance</source>
+ <target>Prestazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935bb9cb0e4340fc74d33caa3b70d9d143fcad87" datatype="html">
+ <source>Information can not be displayed for RBD in status 'Removing'.</source>
+ <target>Impossibile visualizzare le informazioni per RBD con stato 'In rimozione'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58e58f1a8786da9031a05e6770c5dafce82badf5" datatype="html">
+ <source>This setting overrides the global value</source>
+ <target>Questa impostazione sostituisce il valore globale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36b46714164964c6258b08ed0a25f57d8a950f92" datatype="html">
+ <source>This is the global value. No value for this option has been set for this image.</source>
+ <target>Questo è il valore globale. Nessun valore per tale opzione è stato impostato per questa immagine.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6547c9c4d5f62942ac4b1fe459cf9a03d4dbf5a0" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> from</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> da</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0e9ecf29a4fa5b057bd8052e0d801b3fde6a30bf" datatype="html">
+ <source>'/' and '@' are not allowed.</source>
+ <target>'/' e '@' non sono consentiti.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="94516fa213706c67ce5a5b5765681d7fb032033a" datatype="html">
+ <source>Loading...</source>
+ <target>Caricamento in corso...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">209</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">452</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b99417c4dd46286ffd37c8d2e987c8b512ec7052" datatype="html">
+ <source>-- No rbd pools available --</source>
+ <target>-- Nessun pool rbd disponibile --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef83ec9c304a89d45650e580dcdc2978c37b3a83" datatype="html">
+ <source>-- Select a pool --</source>
+ <target>-- Selezionare un pool --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d649904466254d13df1fbf2d255f0bbc6553d213" datatype="html">
+ <source>-- No namespaces available --</source>
+ <target>-- Nessuno spazio dei nomi disponibile --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e22d7bb4d2d561e0832ee0b9a3da2468a080c4f0" datatype="html">
+ <source>-- Select a namespace --</source>
+ <target>-- Selezionare uno spazio dei nomi --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49449943d8cbf59d8c401c8bd2e76f92e207cc5f" datatype="html">
+ <source>Use a dedicated data pool</source>
+ <target>Utilizza un pool di dati dedicato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa5b3c5ea5af14d09b2eb098039af9f1f77be010" datatype="html">
+ <source>You need more than one pool with the rbd application label use to use a dedicated data pool.</source>
+ <target>Per utilizzare un pool di dati dedicato, è richiesto più di un pool con l'uso dell'etichetta applicazione RBD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="870aee0dd31a9643bf62007beb8f1ae1deb34d42" datatype="html">
+ <source>Data pool</source>
+ <target>Pool di dati</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3792ca829d9b9f687e1f5d7733d30e9bb0bfec47" datatype="html">
+ <source>Dedicated pool that stores the object-data of the RBD.</source>
+ <target>Pool dedicato che archivia i dati oggetto dell'RBD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151c80ea931037cd92e854442927f8a0f6ae7795" datatype="html">
+ <source>-- No data pools available --</source>
+ <target>-- Nessun pool di dati disponibile --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0016bd458baa88284a658ce9eeda42d8ad88d2c" datatype="html">
+ <source>e.g., 10GiB</source>
+ <target>ad es. 10 GiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">206</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a88bbee20570aaf9615332fb27020627044874d" datatype="html">
+ <source>You have to increase the size.</source>
+ <target>È necessario aumentare le dimensioni.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cfe07dac5b4ee1c464eb24225ddeb4f1d24076a" datatype="html">
+ <source>Advanced...</source>
+ <target>Avanzate...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bc2e854e111ecf2bd7db170da5e3c2ed08181d88" datatype="html">
+ <source>Advanced</source>
+ <target>Avanzate</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3562a3778695a5f9c0445660e35301f0a39aaf73" datatype="html">
+ <source>Striping</source>
+ <target>Striping</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef3c3f3b5f562a5cdbe0ee2874287db1534b5958" datatype="html">
+ <source>Stripe unit</source>
+ <target>Unità di striping</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84471be1049006edecbcaef1a32ae0893c229c50" datatype="html">
+ <source>-- Select stripe unit --</source>
+ <target>-- Selezionare l'unità di striping --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">289</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d32c5c54c8581c774a7f467fbd4e329b15a74fa" datatype="html">
+ <source>This field is required because stripe count is defined!</source>
+ <target>Questo campo è obbligatorio perché è specificato il numero di striping.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bbf9040be7c5491d4a03f2185708f43a6582a3b" datatype="html">
+ <source>Stripe unit is greater than object size.</source>
+ <target>L'unità di striping è maggiore delle dimensioni dell'oggetto.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a682f49f9b761591661276d7c6f550e641a130a4" datatype="html">
+ <source>Stripe count</source>
+ <target>Numero di striping</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="baa74031990c5370008ba622d0a250f0929097f4" datatype="html">
+ <source>This field is required because stripe unit is defined!</source>
+ <target>Questo campo è obbligatorio perché è specificata l'unità di striping.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cd2ada6d5ecbd5cbf89eae0a1f5326efedac0dbc" datatype="html">
+ <source>Stripe count must be greater than 0.</source>
+ <target>Il numero di striping deve essere maggiore di 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4341718109173132593" datatype="html">
+ <source>RBD</source>
+ <target>RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1359455778569887786" datatype="html">
+ <source>Deep flatten</source>
+ <target>Appiattimento profondo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58519213655664125" datatype="html">
+ <source>Layering</source>
+ <target>Su livelli</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844531889615887801" datatype="html">
+ <source>Exclusive lock</source>
+ <target>Blocco esclusivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4585281635594103106" datatype="html">
+ <source>Object map (requires exclusive-lock)</source>
+ <target>Mappa oggetti (richiede il blocco esclusivo)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240933649452133654" datatype="html">
+ <source>Journaling (requires exclusive-lock)</source>
+ <target>Journaling (richiede il blocco esclusivo)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3713046526850391848" datatype="html">
+ <source>Fast diff (interlocked with object-map)</source>
+ <target>Fast diff (con interlock con la mappa oggetti)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19f1e825536efbf7492723a7c2d01ad23a4e994b" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1774b9915b0e302d02cad0b9321ad5f1a83247a8" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c9f1026c1235f4d76ace47449e806efd181ab332" datatype="html">
+ <source>Deleting this image will also delete all its snapshots.</source>
+ <target>Se questa immagine viene eliminata, verranno eliminate anche tutte le sue snapshot.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55f864597e84d9bf88769e1fbfda1d64452430c9" datatype="html">
+ <source>The following snapshots are currently protected and will be removed:</source>
+ <target>Le snapshot seguenti sono al momento protette e verranno rimosse:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2e362ec498c4c9112dc47a3cb7d7250ca8e71790" datatype="html">
+ <source>RBD in status 'Removing'</source>
+ <target>RBD con stato 'In rimozione'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3294686077659093992" datatype="html">
+ <source>Namespace</source>
+ <target>Spazio dei nomi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45739481977493163" datatype="html">
+ <source>Size</source>
+ <target>Dimensioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7531602241051125940" datatype="html">
+ <source>Objects</source>
+ <target>Oggetti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1194977199378511591" datatype="html">
+ <source>Object size</source>
+ <target>Dimensioni oggetto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">226</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="178418048502923560" datatype="html">
+ <source>Provisioned</source>
+ <target>Soggetto al provisioning</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7638291694671392137" datatype="html">
+ <source>Total provisioned</source>
+ <target>Totale soggetto al provisioning</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8621797738551294959" datatype="html">
+ <source>Parent</source>
+ <target>Superiore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616639680594151867" datatype="html">
+ <source>This RBD has cloned snapshots. Please delete related RBDs before deleting this RBD.</source>
+ <target>Questo RBD contiene snapshot clonate. Prima di eliminare questo RBD, eliminare gli RBD correlati.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2900827028308925059" datatype="html">
+ <source>This RBD image has an invalid name and can't be managed by ceph.</source>
+ <target>Questa immagine RBD ha un nome non valido e non può essere gestita da ceph.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1796389652493657142" datatype="html">
+ <source>Action not possible for an RBD in status 'Removing'</source>
+ <target>Azione non possibile per RBD con stato 'In rimozione'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">476</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c07d24bb422aa8e5e568df1c5709083f0a9c8f1" datatype="html">
+ <source>Create Namespace</source>
+ <target>Crea spazio dei nomi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cca6c0485f96d3a9610d0339cb1275a5f2c3f46" datatype="html">
+ <source>Namespace already exists.</source>
+ <target>Spazio dei nomi già esistente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4641528557519966449" datatype="html">
+ <source>Created namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <target>Spazio dei nomi '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>' creato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6809428596104996786" datatype="html">
+ <source>Total images</source>
+ <target>Totale immagini</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1346311774128536550" datatype="html">
+ <source>Deleted namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <target>Spazio dei nomi '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>' eliminato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7605466414392298530" datatype="html">
+ <source>Namespace contains images</source>
+ <target>Lo spazio dei nomi contiene immagini</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576483965711201552" datatype="html">
+ <source>RBD Snapshot</source>
+ <target>Snapshot RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3473055924346204357" datatype="html">
+ <source>Parent image must support Layering</source>
+ <target>L'immagine superiore deve supportare la stratificazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1152535233999495900" datatype="html">
+ <source>Snapshot must be protected in order to clone.</source>
+ <target>Per poterne effettuare la clonazione, la snapshot deve essere protetta.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c5331983af566d4ac6a1024d15a3511786a4aa6" datatype="html">
+ <source>You are about to rollback</source>
+ <target>Si sta per eseguire il rollback</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6240400332778072187" datatype="html">
+ <source>PROTECTED</source>
+ <target>CON PROTEZIONE</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9101667614062185213" datatype="html">
+ <source>UNPROTECTED</source>
+ <target>SENZA PROTEZIONE</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4207916966377787111" datatype="html">
+ <source>Created</source>
+ <target>Creato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587768621777516124" datatype="html">
+ <source>RBD snapshot rollback</source>
+ <target>Rollback snapshot RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">305</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2711198699676132148" datatype="html">
+ <source>Rollback</source>
+ <target>Esegui rollback</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3330476395115957823" datatype="html">
+ <source>RBD snapshot</source>
+ <target>Snapshot RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">322</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3a7e364a88ea4673199dfa98bc73e6dbe09dfac" datatype="html">
+ <source>Namespaces</source>
+ <target>Spazi dei nomi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aba82bfd8e177d35b76cad7cd43941f8e5e5acac" datatype="html">
+ <source>Trash</source>
+ <target>Cestino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5e7f4b1ca49e8d217bd0e12c6f7d6b6a2ade2c18" datatype="html">
+ <source>Overall Performance</source>
+ <target>Prestazioni complessive</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c0408946a6d67185947f455f15cc201d0d78e6" datatype="html">
+ <source>Purge Trash</source>
+ <target>Elimina definitivamente contenuto del cestino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c96a761dc55a21882c132c929583a424c9b8cf4" datatype="html">
+ <source>Expired at</source>
+ <target>Protezione scaduta in data/ora</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="661041e3fcff4d3e75c561e038ca2504cf2cc643" datatype="html">
+ <source>Protected until</source>
+ <target>Data/Ora scadenza protezione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee3b2322a1d3277f7e3fdb8a5141ac42bcf350b" datatype="html">
+ <source>This image is protected until <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</source>
+ <target>Questa immagine è protetta fino al <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5611592591303869712" datatype="html">
+ <source>Status</source>
+ <target>Stato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">213</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">285</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2155633476201267204" datatype="html">
+ <source>Deleted At</source>
+ <target>Eliminato alle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0b5d789d42c0e69348e5fe0037fcbf5b5fbbdcc" datatype="html">
+ <source>Move an image to trash</source>
+ <target>Sposta un'immagine nel cestino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ad22c1d4aab3b8946603cea62de266d5129ca10" datatype="html">
+ <source>This image contains snapshot(s), which will prevent it from being removed after moved to trash.</source>
+ <target>Questa immagine contiene una o più snapshot e non sarà possibile rimuoverla dopo averla spostata nel cestino.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">15,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d4a5f5698bc8118b2e120b9bb72eff339094dd0" datatype="html">
+ <source>To move <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> to trash, click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Move<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Optionally, you can pick an expiration date.</source>
+ <target>Per spostare <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> nel cestino, fare clic su <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Sposta<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Facoltativamente, è possibile scegliere una data di scadenza.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">19,20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f27d390844aad53b4240360e928156c5f0d326" datatype="html">
+ <source>Protection expires at</source>
+ <target>Data/Ora scadenza protezione:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da166e9a0d27322f6ba8916d71ecc0f9905bb4b1" datatype="html">
+ <source>NOT PROTECTED</source>
+ <target>NON PROTETTO</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1506e5f2ca22cad14502ec7a20fb6113ace145d" datatype="html">
+ <source>Wrong date format. Please use &quot;YYYY-MM-DD HH:mm:ss&quot;.</source>
+ <target>Formato data errato. Utilizzare &quot;AAAA-MM-GG HH:mm:ss&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa7ea0bb7495281e0b3258467ac7d90a1e44a1a1" datatype="html">
+ <source>Protection has already expired. Please pick a future date or leave it empty.</source>
+ <target>La protezione è già scaduta. Selezionare una data futura o lasciarla vuota.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d8613436532acac2b97d17de28b50f93e6bd0222" datatype="html">
+ <source>To purge, select  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>All<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>  or one pool and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Purge<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </source>
+ <target>Per eseguire l'eliminazione definitiva, selezionare <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Tutti<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> oppure un solo pool e fare clic su <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Elimina definitivamente<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55a4f598a4894b7fd5cb88f0ffd3c37ad009dd70" datatype="html">
+ <source>Pool:</source>
+ <target>Pool:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d43dd2b9f7797e4cf3a604695bb33e4479108516" datatype="html">
+ <source>Pool name...</source>
+ <target>Nome pool...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dfc3c34e182ea73c5d784ff7c8135f087992dac1" datatype="html">
+ <source>All</source>
+ <target>tutti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0e7c7ed1d51a0c205c815048bc9f79e24ee6db2" datatype="html">
+ <source>Restore Image</source>
+ <target>Ripristina immagine</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3bc4aaf0dce75dc5e01ee5c825a652dc8aea8f0" datatype="html">
+ <source>To restore  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>,  type the image's new name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Restore<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Per ripristinare <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, digitare il nuovo nome dell'immagine e fare clic su <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Ripristina<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41307dd56fea669eed72e12a6c23af275f6bfd82" datatype="html">
+ <source>New Name</source>
+ <target>Nuovo nome</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3625859417927520024" datatype="html">
+ <source>id</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6537904131139019667" datatype="html">
+ <source>type</source>
+ <target>tipo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8901220148451863928" datatype="html">
+ <source>state</source>
+ <target>stato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7925190601961269841" datatype="html">
+ <source>version</source>
+ <target>versione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6641024648411549335" datatype="html">
+ <source>Host</source>
+ <target>Host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773272191572353800" datatype="html">
+ <source>root</source>
+ <target>radice</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6364513948635353490" datatype="html">
+ <source>Evicted client '<x id="PH" equiv-text="clientId"/>'</source>
+ <target>Client '<x id="PH" equiv-text="clientId"/>' rimosso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c1e17956453ad772dbe82d6946f62748c692f3e" datatype="html">
+ <source>Ranks</source>
+ <target>Classificazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b24e0b0b1629d2e8a51b9da7c75d6e6379f4bc4" datatype="html">
+ <source>Standbys</source>
+ <target>Standby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="50df62325726db950523a5be1c78b8905fcc25d4" datatype="html">
+ <source>MDS performance counters</source>
+ <target>Contatore delle prestazioni MDS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4578796959376778578" datatype="html">
+ <source>Standby daemons</source>
+ <target>Daemon in standby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="665219418211496660" datatype="html">
+ <source>Rank</source>
+ <target>Classificazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5445409664838149993" datatype="html">
+ <source>Daemon</source>
+ <target>Daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5306473977542913614" datatype="html">
+ <source>Activity</source>
+ <target>Attività</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3998441303515229547" datatype="html">
+ <source>Dentries</source>
+ <target>Dentry</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7877631502958415163" datatype="html">
+ <source>Inodes</source>
+ <target>Inode</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6129397096478256985" datatype="html">
+ <source>Dirs</source>
+ <target>Dir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3011876564696453148" datatype="html">
+ <source>Caps</source>
+ <target>Maiusc</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8650499415827640724" datatype="html">
+ <source>Type</source>
+ <target>Tipo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="142654590491855672" datatype="html">
+ <source>Usage</source>
+ <target>Utilizzo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">326</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb8293aa8161433778762ae025ffd5e7c85795e" datatype="html">
+ <source>Quotas</source>
+ <target>Quote</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">540</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66785722678644243" datatype="html">
+ <source>Origin</source>
+ <target>Origine</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8911059720204770105" datatype="html">
+ <source>Path</source>
+ <target>Percorso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6111756909052789805" datatype="html">
+ <source>Cannot create snapshots for files/folders in the subvolume <x id="PH" equiv-text="folders[2]"/></source>
+ <target>Impossibile creare snapshot per file/cartelle nel sottovolume <x id="PH" equiv-text="folders[2]"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7503263437025060215" datatype="html">
+ <source>Max size</source>
+ <target>Dimensioni massime</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6763343019307619111" datatype="html">
+ <source>Max files</source>
+ <target>Numero massimo di file</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327403486214540377" datatype="html">
+ <source>The inherited <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> is the maximum value to be used.</source>
+ <target>Il valore <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> ereditato è il valore massimo da utilizzare.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">434,437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3768927257183755959" datatype="html">
+ <source>Save</source>
+ <target>Salva</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">440</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6328794256834621774" datatype="html">
+ <source><x id="PH" equiv-text="action"/> CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> quota for '<x id="PH_2" equiv-text="path"/>'</source>
+ <target>Quota <x id="PH" equiv-text="action"/> CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> per '<x id="PH_2" equiv-text="path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">446</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9130352375983418123" datatype="html">
+ <source>size</source>
+ <target>dimensioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6889473896134264260" datatype="html">
+ <source>files</source>
+ <target>file</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2244434638607433133" datatype="html">
+ <source><x id="PH" equiv-text="this.getQuotaName()"/> quota <x id="PH_1" equiv-text="value"/> from '<x id="PH_2" equiv-text="path"/>'</source>
+ <target>Quota <x id="PH" equiv-text="this.getQuotaName()"/> <x id="PH_1" equiv-text="value"/> da '<x id="PH_2" equiv-text="path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">460</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6960117167304061503" datatype="html">
+ <source>Value has to be at least 0 or more</source>
+ <target>Il valore non può essere minore di 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">484</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6740501370117796629" datatype="html">
+ <source>Value has to be at most <x id="PH" equiv-text="maxValue"/> or less</source>
+ <target>Il valore non può essere maggiore di <x id="PH" equiv-text="maxValue"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7239750919884229270" datatype="html">
+ <source>Updated</source>
+ <target>Aggiornato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">499</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8885980874806414253" datatype="html">
+ <source>in order to inherit <x id="PH" equiv-text="quotaValue"/></source>
+ <target>per poter ereditare <x id="PH" equiv-text="quotaValue"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4182949309891923991" datatype="html">
+ <source>which isn't used because of the inheritance of <x id="PH" equiv-text="quotaValue"/></source>
+ <target>che non è utilizzato a causa dell'ereditarietà di <x id="PH" equiv-text="quotaValue"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7421970649864638435" datatype="html">
+ <source>in order to have no quota on the directory</source>
+ <target>per non avere alcuna quota nella directory</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6730229976797004508" datatype="html">
+ <source><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</source>
+ <target><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">530,533</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="827679535246546876" datatype="html">
+ <source>Create Snapshot</source>
+ <target>Crea snapshot</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">542</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">552</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4747656362969857823" datatype="html">
+ <source>Please enter the name of the snapshot.</source>
+ <target>Immettere il nome della snapshot.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3667696812078358068" datatype="html">
+ <source>Created snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <target>Snapshot '<x id="PH" equiv-text="name"/>' creata per '<x id="PH_1" equiv-text="path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="753342836137587734" datatype="html">
+ <source>CephFs Snapshot</source>
+ <target>Snapshot CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">670</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2774104291801979963" datatype="html">
+ <source>Deleted snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <target>Snapshot '<x id="PH" equiv-text="name"/>' eliminata per '<x id="PH_1" equiv-text="path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">683</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4816216590591222133" datatype="html">
+ <source>Enabled</source>
+ <target>Abilitato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ffe39df9d88c972792bd8688b215392deb8313d" datatype="html">
+ <source>Clients</source>
+ <target>Client</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e213942c6354b9cbe7a650f0f1499bfc1000fb6" datatype="html">
+ <source>Directories</source>
+ <target>Directory</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fbbaf5cb02ed419e79a27072478f716a4666a99d" datatype="html">
+ <source>Performance Details</source>
+ <target>Dettagli sulle prestazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0" datatype="html">
+ <source>Description</source>
+ <target>Descrizione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ad112ce9bcd55dfd137792a86afe1b5a5b13cf8" datatype="html">
+ <source>Long description</source>
+ <target>Descrizione lunga</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="26fb5f81b3581f06b9210defb0e71dc69a67e819" datatype="html">
+ <source>Current values</source>
+ <target>Valori attuali</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7cee38a2259526c519f878e71b964f41db4348" datatype="html">
+ <source>Default</source>
+ <target>Default</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33e1c1d9fc05ca3f62fcc8a1170fc31ebae4229c" datatype="html">
+ <source>Daemon default</source>
+ <target>Default del daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f61c6867295f3b53d23557021f2f4e0aa1d0b8fc" datatype="html">
+ <source>Type</source>
+ <target>Tipo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9abcd7c82643d60c22733470463f74e4a54bc069" datatype="html">
+ <source>Min</source>
+ <target>Minimo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3ced4d162a0a55ee233a187ce7208ba5e922418" datatype="html">
+ <source>Max</source>
+ <target>Massimo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="920617c6a1a4805e53bcb5af6a9c76f8387e89c6" datatype="html">
+ <source>Flags</source>
+ <target>Flag</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5" datatype="html">
+ <source>Services</source>
+ <target>Servizi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6834fa6b43d1ecbdf147c48dd9c4d72f1484571d" datatype="html">
+ <source>Source</source>
+ <target>Origine</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a446fb0eb11fbffcac805ece5a2d306d24e733d8" datatype="html">
+ <source>Level</source>
+ <target>Livello</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39f2fb094e9b2eda13163fa3f3a31594cf9c1307" datatype="html">
+ <source>Can be updated at runtime (editable)</source>
+ <target>Può essere aggiornato al runtime (modificabile)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
+ <source>Tags</source>
+ <target>Tag</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ab0089ef47af61ca1d137bc908b96c290dfd9287" datatype="html">
+ <source>Enum values</source>
+ <target>Valori di enumerazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="819476f1264f1659f38e86f6abb542141b184832" datatype="html">
+ <source>See also</source>
+ <target>Vedere anche</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="543199344025799954" datatype="html">
+ <source>The value can be updated at runtime.</source>
+ <target>È possibile aggiornare il valore al runtime.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1718354829128482129" datatype="html">
+ <source>Daemons/clients do not pull this value from the
+ monitor config database. We disallow setting this option via 'ceph config
+ set ...'. This option should be configured via ceph.conf or via the
+ command line.</source>
+ <target>I daemon/client non estraggono questo valore dal
+ database della configurazione di monitoraggio. Non è consentito impostare questa opzione tramite 'ceph config
+ set ...'. È necessario configurarla tramite ceph.conf o dalla
+ riga di comando.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">15,18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2345189734548717257" datatype="html">
+ <source>Option takes effect only during daemon startup.</source>
+ <target>L'opzione diventa attiva solo all'avvio del daemon.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5523310713159993513" datatype="html">
+ <source>Option only affects cluster creation.</source>
+ <target>L'opzione interessa solo la creazione del cluster.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1064479086902933123" datatype="html">
+ <source>Option only affects daemon creation.</source>
+ <target>L'opzione interessa solo la creazione del daemon.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="809b0c848932a41318f77a2aace904ef429c13f4" datatype="html">
+ <source>Values</source>
+ <target>Valori</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5894f7158499fdb89527af50c9f1cf7d4c95cad6" datatype="html">
+ <source>-- Default --</source>
+ <target>-- Default --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="514f6e12d035a6d9b00de6b3e55c18b73488da07" datatype="html">
+ <source>true</source>
+ <target>vero</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="774f5e6a183dea08393789b6f72e86afad729419" datatype="html">
+ <source>false</source>
+ <target>falso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="82029b6db704c56a2aa3e82ac555b8655356b077" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>.</source>
+ <target>Il valore immesso è troppo alto. Non deve essere maggiore di <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ed8b3967a7326b81b191c9f490006e6a6777a9a" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>.</source>
+ <target>Il valore immesso è troppo basso. Non deve essere minore di <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2337058106409853613" datatype="html">
+ <source>Updated config option <x id="PH" equiv-text="request.name"/></source>
+ <target>Opzione di configurazione <x id="PH" equiv-text="request.name"/> aggiornata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3733215288982610673" datatype="html">
+ <source>Level</source>
+ <target>Livello</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2218082343053095278" datatype="html">
+ <source>Service</source>
+ <target>Servizio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3553216189604488439" datatype="html">
+ <source>Modified</source>
+ <target>Modificato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844248428439297756" datatype="html">
+ <source>Current value</source>
+ <target>Valore attuale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208877297843037352" datatype="html">
+ <source>Editable</source>
+ <target>Modificabile</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b266042bac4c3a2eff4834e40fb9dc4767a709" datatype="html">
+ <source>Cluster Resources</source>
+ <target>Risorse del cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="099b441d49333b3c6d30b36dc0a4763e64c78920" datatype="html">
+ <source>Hosts</source>
+ <target>Host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57e6e608ece53a26f6d509c90ed4f83e467741af" datatype="html">
+ <source>Storage Capacity</source>
+ <target>Capacità di storage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19ece2cb2b9097c0f75af8e62b4b3b25d399a006" datatype="html">
+ <source>Number of devices</source>
+ <target>Numero di dispositivi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b161e3d25fd1b42a781f4e923a58a94925988ddf" datatype="html">
+ <source>Raw capacity</source>
+ <target>Capacità di base</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb6f3e2a26f3a6f2bc33f91adcd60502dbe5adac" datatype="html">
+ <source>CPUs</source>
+ <target>CPU</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58d4a9814864741040bc5905b6a368836e683f76" datatype="html">
+ <source>Memory</source>
+ <target>Memoria</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dbb81e566a861d4aa0a094366e4083e50863ee92" datatype="html">
+ <source>Host Details</source>
+ <target>Dettagli dell'host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="453dc2810080a744223faac6da2b3ee9ed63a583" datatype="html">
+ <source>Welcome to <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></source>
+ <target>Benvenuto in <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1eec874e1928ca53baa9914781ce203b5f72b0c" datatype="html">
+ <source>Please expand your cluster first</source>
+ <target>Espandere innanzitutto il cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2195fd96b0a00f560449b50bd032e6d9b357730" datatype="html">
+ <source>Expand Cluster</source>
+ <target>Espandi cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb075d0450deb6f381616f7da4b9244ced843053" datatype="html">
+ <source>Skip</source>
+ <target>Ignora</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55b6ce65571b8893440a4fc92776570f8fe7cc97" datatype="html">
+ <source>Add Hosts</source>
+ <target>Aggiungi host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="162f763675c24b557a60eba0758558222369e0c7" datatype="html">
+ <source>Create OSDs</source>
+ <target>Crea OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fef7a7b8db05c351c5287db48488abca530bdb54" datatype="html">
+ <source>Create Services</source>
+ <target>Crea servizi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="176873b4533ddeabf95992cbd7b91b9d01c6d557" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ed90ec4409b9f6b552982d96f89db27259e763c" datatype="html">
+ <source>You are about to skip the cluster expansion process. You’ll need to <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>navigate through the menu to add hosts and services.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>Si sta per ignorare la procedura di espansione del cluster. Sarà necessario <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>navigare nel menu per aggiungere host e servizi<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">90,91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d1dcf2a9146caac0581329acf94806ec69a89a5" datatype="html">
+ <source>Are you sure you want to continue?</source>
+ <target>Continuare?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6759205696902713848" datatype="html">
+ <source>Warning</source>
+ <target>Avviso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">357</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6962699013778688473" datatype="html">
+ <source>Continue</source>
+ <target>Continua</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6156560100092571435" datatype="html">
+ <source>Cluster expansion skipped by user</source>
+ <target>Espansione del cluster ignorata dall'utente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520085823873354736" datatype="html">
+ <source>Cluster expansion was successful</source>
+ <target>Espansione del cluster riuscita</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176230351113290618" datatype="html">
+ <source>Expand Cluster</source>
+ <target>Espandi cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="738de688b22fba5d0dc7a5e549996838dddad0ee" datatype="html">
+ <source>CRUSH map viewer</source>
+ <target>Visualizzatore mappa CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/crushmap/crushmap.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e24569eca61d598c8b01defbbbb1fa8bd5222bc" datatype="html">
+ <source>Devices</source>
+ <target>Dispositivi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17137bac47e1e020d139256ded0006a671966e73" datatype="html">
+ <source>Physical Disks</source>
+ <target>Dischi fisici</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="deba10b7279a589d01e919ea11f43c79ca1773e3" datatype="html">
+ <source>Device health</source>
+ <target>Integrità dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d87fc20ea8e5f0f0500ba5d5061b345be78ec5e" datatype="html">
+ <source>No hostname found.</source>
+ <target>Nessun nome host trovato.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9a541ec1a4319fffc16ad3b3ab2c2b6d251a829d" datatype="html">
+ <source>Hostname</source>
+ <target>Nome host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee6875e67b53cac30a02b57cf76e485f7e60caf4" datatype="html">
+ <source>To add multiple hosts at once, you can enter:</source>
+ <target>Per aggiungere più host contemporaneamente, è possibile immettere:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a8370b19ccf673fb28fa9db36a08f9901887cc7" datatype="html">
+ <source>a comma-separated list of hostnames <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-01,example-02,example-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <target>un elenco di nomi host separati da virgole <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(ad es. esempio-01,esempio-02,esempio-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="68f2c05396ec8a5f59e8da42d1f6c7310fa8c37c" datatype="html">
+ <source>a range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <target>un'espressione di intervallo <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(ad es. esempio-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e00b9bba448e79add37740e53dc953fbb89f9c5" datatype="html">
+ <source>a comma separated range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></source>
+ <target>un elenco di espressioni di intervallo separate da virgole <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(ad es. esempio-[01-05].lab.com,esempio2-[1-4].lab.com,esempio3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b3f5e5291541678f7afa49d28fad5ca848a8061" datatype="html">
+ <source>The chosen hostname is already in use.</source>
+ <target>Il nome host selezionato è già in uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="42365f623c57973d1d13d2038e8a2d4c02fb9b9f" datatype="html">
+ <source>Network address</source>
+ <target>Indirizzo di rete</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3859bdca1ae89e611e214c205fccf0147b4d0f6b" datatype="html">
+ <source>The value is not a valid IP address.</source>
+ <target>Il valore non è un indirizzo IP valido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2af7efecfae8d7fed3b07f718a623eca1ad8163f" datatype="html">
+ <source>Labels</source>
+ <target>Etichette</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9da2afd4fa358b66d4d95fe7e8f4b659a7144e" datatype="html">
+ <source>Maintenance Mode</source>
+ <target>Modalità manutenzione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="468785112451259935" datatype="html">
+ <source>There are no labels.</source>
+ <target>Nessuna etichetta presente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4664081995078497865" datatype="html">
+ <source>Filter or add labels</source>
+ <target>Filtra o aggiungi etichette</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4897817053917542646" datatype="html">
+ <source>Add label</source>
+ <target>Aggiungi etichetta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">313</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1187321380561233505" datatype="html">
+ <source>host</source>
+ <target>host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40661476cb24c89d8b06614998e31d5fbe84eeb6" datatype="html">
+ <source>Hosts List</source>
+ <target>Elenco degli host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b7a4e1e5a316f8547af1d6d2311a5cec8c5c1d87" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ msg }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ msg }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6e8e8844e9e7a7b626a4699c08b6c0c81297a7b" datatype="html">
+ <source>Data will be available only if Orchestrator is available.</source>
+ <target>I dati saranno disponibili solo se è disponibile Orchestrator.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4baf526199fed59071adf555271791283adc408" datatype="html">
+ <source>SSD, NVMEs</source>
+ <target>SSD, NVME</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="22d5531d79f0d7269a0a752e56a848807dd37095" datatype="html">
+ <source>Flash</source>
+ <target>Flash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4025065730478477779" datatype="html">
+ <source>The feature is disabled because the selected host is not managed by Orchestrator.</source>
+ <target>La funzione è disabilitata perché l'host selezionato non è gestito da Orchestrator.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7143579180750436311" datatype="html">
+ <source>Services</source>
+ <target>Servizi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="546766753072101168" datatype="html">
+ <source>Labels</source>
+ <target>Etichette</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1141886420788473147" datatype="html">
+ <source>Model</source>
+ <target>Modello</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4027647877328291519" datatype="html">
+ <source>CPUs</source>
+ <target>CPU</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2445398473573060226" datatype="html">
+ <source>Cores</source>
+ <target>Core</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1656823484917332451" datatype="html">
+ <source>Total Memory</source>
+ <target>Memoria totale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1939212557812454069" datatype="html">
+ <source>Raw Capacity</source>
+ <target>Capacità di base</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5579687933271468638" datatype="html">
+ <source>HDDs</source>
+ <target>HDD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1889285841762768492" datatype="html">
+ <source>Flash</source>
+ <target>Flash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1578709829957887527" datatype="html">
+ <source>NICs</source>
+ <target>NIC</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4723031838495967601" datatype="html">
+ <source>Edit Host: <x id="PH" equiv-text="host.hostname"/></source>
+ <target>Modifica host: <x id="PH" equiv-text="host.hostname"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6004907173026319041" datatype="html">
+ <source>Edit Host</source>
+ <target>Modifica host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5618131051466022401" datatype="html">
+ <source>Updated Host &quot;<x id="PH" equiv-text="host.hostname"/>&quot;</source>
+ <target>Host &amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot aggiornato;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1701954433367210342" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; moved to maintenance</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; spostato in manutenzione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3108406586869160854" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; cannot be put into maintenance</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; non può essere spostato in manutenzione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1737753151350322492" datatype="html">
+ <source><x id="PH" equiv-text="error.error['detail']"/></source>
+ <target><x id="PH" equiv-text="error.error['detail']"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4054533801359952167" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; has exited maintenance</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; non è più in manutenzione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5837599005212786659" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; stopped draining</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host['hostname']"/>&amp;quot; ha interrotto lo svuotamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1357236071975782353" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; started draining</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host['hostname']"/>&amp;quot; ha iniziato lo svuotamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5658400717636093668" datatype="html">
+ <source>Identify</source>
+ <target>Identifica</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6966707768479328825" datatype="html">
+ <source>Device path</source>
+ <target>Percorso dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3955868613858648955" datatype="html">
+ <source>Available</source>
+ <target>Disponibile</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="158816374076721379" datatype="html">
+ <source>Vendor</source>
+ <target>Produttore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6024104799101504292" datatype="html">
+ <source>OSDs</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3422162477846071958" datatype="html">
+ <source>Identify device <x id="PH" equiv-text="device"/></source>
+ <target>Identifica dispositivo <x id="PH" equiv-text="device"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4910073658089977244" datatype="html">
+ <source>Please enter the duration how long to blink the LED.</source>
+ <target>Specificare per quanto tempo far lampeggiare il LED.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5764931367607989415" datatype="html">
+ <source>1 minute</source>
+ <target>1 minuto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809466133764752509" datatype="html">
+ <source>2 minutes</source>
+ <target>2 minuti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">235</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1487672983218679675" datatype="html">
+ <source>5 minutes</source>
+ <target>5 minuti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603584938775296395" datatype="html">
+ <source>10 minutes</source>
+ <target>10 minuti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6648333117195452824" datatype="html">
+ <source>15 minutes</source>
+ <target>15 minuti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6560281329999108838" datatype="html">
+ <source>Execute</source>
+ <target>Esegui</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6901229416977800100" datatype="html">
+ <source>Identifying '<x id="PH" equiv-text="device"/>' started on host '<x id="PH_1" equiv-text="hostname"/>'</source>
+ <target>Identificazione di '<x id="PH" equiv-text="device"/>' avviata sull'host '<x id="PH_1" equiv-text="hostname"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d556ab48a65722b400e497f61737f553ee0f89e2" datatype="html">
+ <source>Cluster Logs</source>
+ <target>Log del cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5f966baffd188be0e8adc2d7067b86e55fc9b9de" datatype="html">
+ <source>Audit Logs</source>
+ <target>Log di controllo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4193c9eb868aeec119b78a14795241e0aa5e8b60" datatype="html">
+ <source>Priority:</source>
+ <target>Livello di priorità:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d78ca51eab260ce3fd917d39190d64df5229b6e" datatype="html">
+ <source>Keyword:</source>
+ <target>Parola chiave:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="05fa0bded36de6e73a1fa44838b627349dace044" datatype="html">
+ <source>Date:</source>
+ <target>Data:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a400388de1899b1917138cf7e5286376f72847" datatype="html">
+ <source>Time range:</source>
+ <target>Intervallo di tempo:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="de0478286b8b5a939db54e9e5282405364ad2d61" datatype="html">
+ <source>No log entries found. Please try to select different filter options.</source>
+ <target>Nessuna voce di log trovata. Provare a selezionare opzioni di filtro diverse.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7479674d91142b785b9547a87e5fb51cb16108" datatype="html">
+ <source>Reset filter.</source>
+ <target>Ripristinare il filtro.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="31a9c2870a934b594d1390146c489f76440859ea" datatype="html">
+ <source>Edit Manager module</source>
+ <target>Modifica modulo Manager</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="46e09b8290d3d0afdb6baa2021395b0570606a31" datatype="html">
+ <source>The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</source>
+ <target>Il valore immesso non è un UUID valido, ad es.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7aacd038b39cfd347107d01d1dc27f5cb3e0951c" datatype="html">
+ <source>The entered value needs to be a valid IP address.</source>
+ <target>Il valore immesso deve essere un indirizzo IP valido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f19106149f4b07a0d721f9d317afed393cb7bd93" datatype="html">
+ <source>The entered value is too high! It must be lower or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>.</source>
+ <target>Il valore immesso è troppo alto. Deve essere minore di o uguale a <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d33c40ef9a6c3bf0888df831b25e41e65f9d15b" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>.</source>
+ <target>Il valore immesso è troppo basso. Deve essere maggiore di o uguale a <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eae7086660cf1e38c7194a2c49ff52cc656f90f5" datatype="html">
+ <source>The entered value needs to be a number.</source>
+ <target>Il valore immesso deve essere un numero.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">194</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a73376e04b4fb3a20734c8c39743fba32e6676ce" datatype="html">
+ <source>The entered value needs to be a number or decimal.</source>
+ <target>Il valore immesso deve essere un numero o un decimale.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1898719236268328097" datatype="html">
+ <source>Updated options for module '<x id="PH" equiv-text="this.moduleName"/>'.</source>
+ <target>Opzioni aggiornate per il modulo '<x id="PH" equiv-text="this.moduleName"/>'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4186041075388034600" datatype="html">
+ <source>Always-On</source>
+ <target>Sempre attivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7585826646011739428" datatype="html">
+ <source>Edit</source>
+ <target>Modifica</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2180291763949669799" datatype="html">
+ <source>Enable</source>
+ <target>Abilita</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9187855490716817910" datatype="html">
+ <source>Disable</source>
+ <target>Disabilita</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1600086764852993170" datatype="html">
+ <source>This Manager module is always on.</source>
+ <target>Questo modulo Manager è sempre attivo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3895296744591223546" datatype="html">
+ <source>Reconnecting, please wait ...</source>
+ <target>Riconnessione in corso. Attendere...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81b97b8ea996ad1e4f9fca8415021850214884b1" datatype="html">
+ <source>Status</source>
+ <target>Stato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57ec6032f5618d4a9f16eb950ad23d2ce7c24b54" datatype="html">
+ <source>Cluster ID</source>
+ <target>ID cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67d7facc3fec5f8a49ab9ba0a245872184264ce5" datatype="html">
+ <source>monmap modified</source>
+ <target>mappa mon modificata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4906731aaf2b94b4f547646c9bfe58bb77951b6" datatype="html">
+ <source>monmap epoch</source>
+ <target>epoca mappa mon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd4ee06ffdc46d9dfbd0c0c4f81399021c680056" datatype="html">
+ <source>quorum con</source>
+ <target>quorum con</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1176c7db8a8276ccb44cc3d42e2c28d9fa6c6596" datatype="html">
+ <source>quorum mon</source>
+ <target>quorum mon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="530ef677a09d681b3ab68cb0760494b3ae72a77c" datatype="html">
+ <source>required con</source>
+ <target>con richiesta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a91558e0d506c32021c31843f8f168899fc65cbf" datatype="html">
+ <source>required mon</source>
+ <target>mon richiesto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3abe9eac5bcd94a54c8da93b312e085ec512e74" datatype="html">
+ <source>In Quorum</source>
+ <target>Nel quorum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba4b748a676e1f217ce1e736fb7ec1215e677bae" datatype="html">
+ <source>Not In Quorum</source>
+ <target>Non nel quorum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3517477838460618200" datatype="html">
+ <source>Public Address</source>
+ <target>Indirizzo pubblico</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6949358970125514744" datatype="html">
+ <source>Open Sessions</source>
+ <target>Sessioni aperte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4383e9662ea19839c7499b2128d43a195e564317" datatype="html">
+ <source>OSD creation preview</source>
+ <target>Anteprima creazione OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="366225c51e0b00bcb1c55795a0dc5e81c455f84e" datatype="html">
+ <source>DriveGroups</source>
+ <target>DriveGroups</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91853167141c37b58868f3b0421383dd72fa8a01" datatype="html">
+ <source>Attributes (OSD map)</source>
+ <target>Attributi (mappa OSD)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f721a500a68c357e8f2a01e60510f6a01e4ba529" datatype="html">
+ <source>Metadata</source>
+ <target>Metadati</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97842f379e1d4157ac3ab0661b90c352e7cb72d5" datatype="html">
+ <source>Metadata not available</source>
+ <target>Metadati non disponibili</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24e28e19c5703d7c6be44f4eb595a6a43b618ed" datatype="html">
+ <source>Performance counter</source>
+ <target>Contatore delle prestazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ccb4f84edc0b4e76415bb3f9b73d725b06683af3" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ name }}"/> devices</source>
+ <target>Dispositivi <x id="INTERPOLATION" equiv-text="{{ name }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60cb3d01e5ddf266ecb4271007a1c3d0f3efdc22" datatype="html">
+ <source>The primary storage devices. These devices contain all OSD data.</source>
+ <target>Dispositivi primari di memorizzazione. Questi dispositivi contengono tutti i dati degli OSD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b432e04886d0d1fd84f740477383051f85addcf2" datatype="html">
+ <source>Write-Ahead-Log devices. These devices are used for BlueStore’s internal journal. It is only useful to use a WAL device if the device is faster than the primary device (e.g. NVME devices or SSDs). If there is only a small amount of fast storage available (e.g., less than a gigabyte), we recommend using it as a WAL device.</source>
+ <target>Dispositivi WAL. Questi dispositivi sono utilizzati per il journal interno di BlueStore. È utile avere un dispositivo di questo tipo solo se più veloce del dispositivo primario (ad es. dischi NVME o SSD). Se si ha a disposizione poco spazio di archiviazione veloce (ad es. meno di un gigabyte), si consiglia di utilizzarlo come dispositivo WAL.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87e181ab9e8393aa5ed759dd3d53836e32c8ffe" datatype="html">
+ <source>DB devices can be used for storing BlueStore’s internal metadata. It is only helpful to provision a DB device if it is faster than the primary device (e.g. NVME devices or SSD).</source>
+ <target>I dispositivi DB possono essere utilizzati per archiviare i metadati interni di BlueStore. È utile avere un dispositivo DB dedicato solo se è più veloce del dispositivo primario (ad es. dischi NVME o SSD).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
+ <source>Add</source>
+ <target>Aggiungi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="99ee4faa69cd2ea8e3678c1f557c0ff1f05aae46" datatype="html">
+ <source>Clear</source>
+ <target>Annulla</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e0fd3c7af0630f93befa6234a693a32a61084e0" datatype="html">
+ <source>Raw capacity: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></source>
+ <target>Capacità di base: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1961811273151129466" datatype="html">
+ <source>No available devices</source>
+ <target>Nessun dispositivo disponibile</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617271647728055571" datatype="html">
+ <source>Please add primary devices first</source>
+ <target>Aggiungere innanzitutto i dispositivi primari</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6368751795251107516" datatype="html">
+ <source>Add devices by using filters</source>
+ <target>Aggiungere i dispositivi utilizzando i filtri</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8edc89137d0d8c5667a2f03230beafae45e58429" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> devices</source>
+ <target>Dispositivi <x id="INTERPOLATION" equiv-text="{{ deviceType }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eba28e1805b18f7c8ae2e4bc15dcf063b10b3822" datatype="html">
+ <source>At least one of these filters must be applied in order to proceed:</source>
+ <target>Per continuare, occorre applicare almeno uno di questi filtri:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="93389aa2fe2bea50bf89554ee51b28f87ee2fb50" datatype="html">
+ <source>Number of devices: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Raw capacity: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</source>
+ <target>Numero di dispositivi: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Capacità di base: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">29,30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6b27c16ddf33b855412c82069dca8120bd3a68a" datatype="html">
+ <source>Individual OSD Flags</source>
+ <target>Flag OSD singoli</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dba0ed9ba355a3bd3296c0bef3bb518744a51a89" datatype="html">
+ <source>Cluster-wide</source>
+ <target>A livello di cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e2a3f211cea2cbadb29b6df93e544440b6b68d3e" datatype="html">
+ <source>Restore previous selection</source>
+ <target>Ripristina selezione precedente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1683654169791509804" datatype="html">
+ <source>No Up</source>
+ <target>Nessuno attivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5754783193519044074" datatype="html">
+ <source>OSDs are not allowed to start</source>
+ <target>Non è consentito l'avvio degli OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4413588319909369773" datatype="html">
+ <source>No Down</source>
+ <target>Nessuno declassato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1348746748821823470" datatype="html">
+ <source>OSD failure reports are being ignored, such that the monitors will not mark OSDs down</source>
+ <target>I rapporti di errore degli OSD vengono ignorati in modo che i monitor non declassino gli OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="301172600132606646" datatype="html">
+ <source>No In</source>
+ <target>Nessuno attivato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4114057962148673377" datatype="html">
+ <source>OSDs that were previously marked out will not be marked back in when they start</source>
+ <target>Gli OSD che sono stati contrassegnati come disattivati in precedenza non verranno contrassegnati nuovamente come attivati all'avvio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5236523991485603657" datatype="html">
+ <source>No Out</source>
+ <target>Nessuno disattivato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1798160169020638994" datatype="html">
+ <source>OSDs will not automatically be marked out after the configured interval</source>
+ <target>Gli OSD non verranno automaticamente contrassegnati come disattivati dopo l'intervallo configurato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3225813593817914267" datatype="html">
+ <source>The flag has been enabled for the entire cluster.</source>
+ <target>Il flag è stato abilitato per l'intero cluster.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1941050626944682985" datatype="html">
+ <source>Updated OSD Flags</source>
+ <target>Flag OSD aggiornati</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ef50ba2514414f799d4c8fc36067a251904ba81" datatype="html">
+ <source>Cluster-wide OSD Flags</source>
+ <target>Flag OSD a livello di cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9042260521669277115" datatype="html">
+ <source>Pause</source>
+ <target>Sospendi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6015425610572318971" datatype="html">
+ <source>Pauses reads and writes</source>
+ <target>Sospende le operazioni di lettura e scrittura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314873595759611676" datatype="html">
+ <source>No Scrub</source>
+ <target>Nessuna pulitura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773570234687653570" datatype="html">
+ <source>Scrubbing is disabled</source>
+ <target>Pulitura disabilitata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5999821123886006899" datatype="html">
+ <source>No Deep Scrub</source>
+ <target>Nessuna pulitura approfondita</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5362685148875251772" datatype="html">
+ <source>Deep Scrubbing is disabled</source>
+ <target>Pulitura approfondita disabilitata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5001752039592388485" datatype="html">
+ <source>No Backfill</source>
+ <target>Nessuna operazione di recupero informazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4851280330655956778" datatype="html">
+ <source>Backfilling of PGs is suspended</source>
+ <target>Recupero informazioni sui gruppi di posizionamento sospeso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5994953210305546559" datatype="html">
+ <source>No Rebalance</source>
+ <target>Nessun ribilanciamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3698980403470604587" datatype="html">
+ <source>OSD will choose not to backfill unless PG is also degraded</source>
+ <target>L'OSD sceglierà di non recuperare le informazioni a meno che non sia danneggiato anche il gruppo di posizionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4334886823145076432" datatype="html">
+ <source>No Recover</source>
+ <target>Nessun recupero</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8465994741155792816" datatype="html">
+ <source>Recovery of PGs is suspended</source>
+ <target>Recupero dei gruppi di posizionamento sospeso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4052740759486923001" datatype="html">
+ <source>Bitwise Sort</source>
+ <target>Ordinamento bitwise</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2330377428425572488" datatype="html">
+ <source>Use bitwise sort</source>
+ <target>Usa ordinamento bitwise</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8943478424576832224" datatype="html">
+ <source>Purged Snapdirs</source>
+ <target>Snapdir eliminate definitivamente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7553321860087551262" datatype="html">
+ <source>OSDs have converted snapsets</source>
+ <target>Gli OSD contengono set di snap convertiti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6509988280998256208" datatype="html">
+ <source>Recovery Deletes</source>
+ <target>Eliminazioni recuperi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="451760144355116641" datatype="html">
+ <source>Deletes performed during recovery instead of peering</source>
+ <target>Eliminazioni eseguite durante il recupero invece del peering</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="87832369463084597" datatype="html">
+ <source>PG Log Hard Limit</source>
+ <target>Limite rigido log gruppo di posizionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9135782750879343185" datatype="html">
+ <source>Puts a hard limit on pg log length</source>
+ <target>Inserisce un limite rigido per la lunghezza del log del gruppo di posizionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="formTitle" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <note priority="1" from="description">Example: Create Pool</note>
+ <note priority="1" from="meaning">form title</note>
+ </trans-unit>
+ <trans-unit id="43ecf6bee2aebc07b0aad6dc1fe13e38d14687fa" datatype="html">
+ <source>Shared devices</source>
+ <target>Dispositivi condivisi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7a1c376f6f1b37de4c318ff2106255ba6c0f5b0b" datatype="html">
+ <source>WAL slots</source>
+ <target>Slot per WAL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73811a6f37b63e6b0e491e221bfa21e9dea8a87a" datatype="html">
+ <source>How many OSDs per WAL device.</source>
+ <target>Numero di OSD per dispositivo WAL.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c67a7ac4762ef1cc855056c6b4daab93e53a0a5" datatype="html">
+ <source>Specify 0 to let Orchestrator backend decide it.</source>
+ <target>Immettere 0 per lasciare decidere al backend di Orchestrator.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bda9362e06e6c67341b4a8425b0d29d6b84464b" datatype="html">
+ <source>Value should be greater than or equal to 0</source>
+ <target>Il valore deve essere maggiore o uguale a 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="324c2b10152b9dd908222bb0b71f61beb60a30c5" datatype="html">
+ <source>DB slots</source>
+ <target>Slot per DB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c23cf12ef9c76f37fc7a4b7ae3e00fb0f68b6e26" datatype="html">
+ <source>How many OSDs per DB device.</source>
+ <target>Numero di OSD per dispositivo DB.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8255877266497322342" datatype="html">
+ <source>Encryption</source>
+ <target>Crittografia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b49d7877d24112d4bdfce9256edf61a007fae888" datatype="html">
+ <source>OSDs List</source>
+ <target>Elenco degli OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="172ada0fcf6490b24a897517e9f4299215873ff8" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD(s) <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be marked <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <target><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Gli OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> verranno contrassegnati <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> se si procede.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">59,60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="262a49e60d5f6ed9825582ccf3d5ae39daa1da60" datatype="html">
+ <source>The <x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> not safe to be <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>! <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></source>
+ <target><x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> come <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/> <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71,72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="74bd20d5f558d14cb2fa41ae863cf09c47d02018" datatype="html">
+ <source>{VAR_SELECT, select, true {OSD is} other {OSDs are}}</source>
+ <target>{VAR_SELECT, select, true {L'OSD non è sicuro} other {Gli OSD non sono sicuri}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0e217fd717c5b1f5c17f00c5b174de855acbef0" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <target><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>L'OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> verrà <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> se si procede.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">74,75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8cf121660bed7098516a1efe85831d6f415a9411" datatype="html">
+ <source>Preserve OSD ID(s) for replacement.</source>
+ <target>Conservare gli ID dell'OSD per la sostituzione.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4435645098786961170" datatype="html">
+ <source>out</source>
+ <target>disattivato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136018875175606726" datatype="html">
+ <source>in</source>
+ <target>attivato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1301930865667956193" datatype="html">
+ <source>down</source>
+ <target>declassato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1226060325201042854" datatype="html">
+ <source>Mark</source>
+ <target>Contrassegna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1256299033316818951" datatype="html">
+ <source>OSD lost</source>
+ <target>OSD perso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2795727560928976873" datatype="html">
+ <source>marked lost</source>
+ <target>contrassegnato come perso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7685933846431786388" datatype="html">
+ <source>Purge</source>
+ <target>Elimina definitivamente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5941516286393808546" datatype="html">
+ <source>OSD</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3416443212235382421" datatype="html">
+ <source>purged</source>
+ <target>eliminato definitivamente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9191368063029792986" datatype="html">
+ <source>destroy</source>
+ <target>elimina definitivamente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4425946029386289247" datatype="html">
+ <source>destroyed</source>
+ <target>eliminato definitivamente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2870788902465061969" datatype="html">
+ <source>Flags</source>
+ <target>Flag</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8995035642420075344" datatype="html">
+ <source>Recovery Priority</source>
+ <target>Priorità di recupero</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3601135996773579607" datatype="html">
+ <source>PG scrub</source>
+ <target>Pulitura gruppo di posizionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136079353894161076" datatype="html">
+ <source>Device class</source>
+ <target>Classe dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6382718875453721838" datatype="html">
+ <source>PGs</source>
+ <target>Gruppi di posizionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3660230483843323377" datatype="html">
+ <source>Read bytes</source>
+ <target>Byte letti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">329</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3909578649547040612" datatype="html">
+ <source>Write bytes</source>
+ <target>Byte scritti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3182358405280886750" datatype="html">
+ <source>Read ops</source>
+ <target>Operazioni di lettura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171292502535561083" datatype="html">
+ <source>Write ops</source>
+ <target>Operazioni di scrittura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6706824709967518168" datatype="html">
+ <source>Edit OSD: <x id="PH" equiv-text="selectedOsd.id"/></source>
+ <target>Modifica OSD: <x id="PH" equiv-text="selectedOsd.id"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">451</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1125148356983553148" datatype="html">
+ <source>Edit OSD</source>
+ <target>Modifica OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="970212458427610374" datatype="html">
+ <source>Updated OSD '<x id="PH" equiv-text="selectedOsd.id"/>'</source>
+ <target>OSD '<x id="PH" equiv-text="selectedOsd.id"/>' aggiornato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">466</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7554728686176829307" datatype="html">
+ <source>Mark OSD <x id="PH" equiv-text="markAction"/></source>
+ <target>Contrassegna OSD <x id="PH" equiv-text="markAction"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="478122291463667978" datatype="html">
+ <source>Mark <x id="PH" equiv-text="markAction"/></source>
+ <target>Contrassegna <x id="PH" equiv-text="markAction"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">502</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2456043080471762298" datatype="html">
+ <source>delete</source>
+ <target>elimina</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">530</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="588230151780724018" datatype="html">
+ <source>deleted</source>
+ <target>eliminato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">532</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1ef1c12ddcee305353623919ef02778569f5454" datatype="html">
+ <source>Advanced configuration options</source>
+ <target>Opzioni di configurazione avanzate</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7771252117308888928" datatype="html">
+ <source>PG scrub options</source>
+ <target>Opzioni di pulitura gruppo di posizionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1797901277775175680" datatype="html">
+ <source>Updated PG scrub options</source>
+ <target>Opzioni di pulitura gruppo di posizionamento aggiornate</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c35f9c5f268a514b970cc55e9a5dc4bed0988e7f" datatype="html">
+ <source>OSD Recovery Priority</source>
+ <target>Priorità di recupero OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74af38005e8a8914e45af2ec412e11ceafef8b6" datatype="html">
+ <source>Priority</source>
+ <target>Livello di priorità</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f48f04b379bfba133825747adfd238d511412e" datatype="html">
+ <source>Customize priority values</source>
+ <target>Personalizza valori di priorità</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aa19de2a2b54cbda39e9c62917b23044c087776" datatype="html">
+ <source>This field is required!</source>
+ <target>Questo campo è obbligatorio.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">406</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b699e94bf376491bd50b70a98531071c737eaf40" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="98fe13e7ad6c2b80375d204b47858ded83f80e15" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>.</source>
+ <target>Il valore immesso è troppo alto. Non deve essere maggiore di <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423a3c111be47fc5a1bfe46ceb58c81c84db691" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>.</source>
+ <target>Il valore immesso è troppo basso. Non deve essere minore di <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3234179038052466481" datatype="html">
+ <source>Max Backfills</source>
+ <target>Numero massimo di recuperi informazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847070960491384020" datatype="html">
+ <source>Recovery Max Active</source>
+ <target>Numero massimo di recuperi attivi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2088615724570210504" datatype="html">
+ <source>Recovery Max Single Start</source>
+ <target>Avvio singolo numero massimo di recuperi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8627094894361422565" datatype="html">
+ <source>Recovery Sleep</source>
+ <target>Sospensione recupero</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7590013429208346303" datatype="html">
+ <source>Custom</source>
+ <target>Personalizzato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4937275625032609020" datatype="html">
+ <source>Updated OSD recovery speed priority '<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>'</source>
+ <target>Priorità della velocità di recupero dell'OSD '<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>' aggiornata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">227,229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5251a4355cece3075db43f15d69a24a0f8485707" datatype="html">
+ <source>Reweight OSD: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></source>
+ <target>Ripesa OSD: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67650b2998db48201b2c6176cbfef51e7211ccaa" datatype="html">
+ <source>The value needs to be between 0 and 1.</source>
+ <target>Il valore deve essere compreso tra 0 e 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f077ceb52c967a8fe2de9ef0a9d65d72badf186" datatype="html">
+ <source>OSDs <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/>Scrub</source>
+ <target>Pulitura <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/> degli OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b73a34ba65b3073e3560dce828a16d7fd3c0f4" datatype="html">
+ <source>{VAR_SELECT, select, true {Deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {approfondita} other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c00119503aad4012b77049eee41293338f67756c" datatype="html">
+ <source>You are about to apply a <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/>scrub to the OSD(s): <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <target>Si sta per eseguire la pulitura <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/> degli OSD: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fad3dc421817a16dd6c46c1a0c36de619a8d776e" datatype="html">
+ <source>{VAR_SELECT, select, true {deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {approfondita} other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1086427836866943370" datatype="html">
+ <source><x id="PH" equiv-text="operation"/> was initialized in the following OSD(s): <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></source>
+ <target><x id="PH" equiv-text="operation"/> è stato inizializzato negli OSD seguenti: <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts</context>
+ <context context-type="linenumber">42,44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47c97aa28f64b11fa5842795fdd02c8c0863c97b" datatype="html">
+ <source>To see all active Prometheus alerts, please provide the URL to the API of Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>Per visualizzare tutti gli avvisi attivi di Prometheus, specificare l'URL dell'API della gestione avvisi di Prometheus come descritto in <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6343323763459782070" datatype="html">
+ <source>Create Silence</source>
+ <target>Crea silenziamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1895957424873987405" datatype="html">
+ <source>Job</source>
+ <target>Lavoro</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491474782694268231" datatype="html">
+ <source>Severity</source>
+ <target>Gravità</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3326877877555410533" datatype="html">
+ <source>Started</source>
+ <target>Avviato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2375260419993138758" datatype="html">
+ <source>URL</source>
+ <target>URL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="880ad4df5a2051a437321443d69c9a866699e5ad" datatype="html">
+ <source>Active Alerts</source>
+ <target>Avvisi attivi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9fe218829514884cdd0ca2300573a4e0428c324f" datatype="html">
+ <source>Alerts</source>
+ <target>Avvisi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa0c44aa1e5727061baa91e954f77e2f5f9a37c9" datatype="html">
+ <source>Silences</source>
+ <target>Silenziamenti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85c737325f5e59517e2d08a71de6d77788aabc95" datatype="html">
+ <source>To see all configured Prometheus alerts, please provide the URL to the API of Prometheus as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>Per visualizzare tutti gli avvisi configurati di Prometheus, specificare l'URL dell'API di Prometheus come descritto in <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623978917681527907" datatype="html">
+ <source>Group</source>
+ <target>Gruppo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7410432243549869948" datatype="html">
+ <source>Duration</source>
+ <target>Durata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4109205891084963566" datatype="html">
+ <source>Query</source>
+ <target>Interrogazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28f86ffd419b869711aa13f5e5ff54be6d70731c" datatype="html">
+ <source>Edit</source>
+ <target>Modifica</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="826b25211922a1b46436589233cb6f1a163d89b7" datatype="html">
+ <source>Delete</source>
+ <target>Elimina</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">279</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">341</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">441</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3ba06aba047605af8ea1718ec1ba153b7db12a2" datatype="html">
+ <source>Editing a silence will expire the old silence and recreate it as a new silence</source>
+ <target>Se un silenziamento viene modificato, il silenziamento precedente scadrà e verrà ricreato come nuovo silenziamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a20424156b8816671f61879f0574a4f27d7b16b9" datatype="html">
+ <source>Creator</source>
+ <target>Creatore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5a5d7ee2acbfa9c91ab7f41d26bda9ff0cafe42f" datatype="html">
+ <source>Comment</source>
+ <target>Commento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c11aad490b2d53fdae30b3807beabf79306752c" datatype="html">
+ <source>Start time</source>
+ <target>Ora di inizio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32856b1e8e339b747b21e313e2fe65a51fd450bb" datatype="html">
+ <source>If the start time lies in the past the creation time will be used</source>
+ <target>Se l'ora di inizio è nel passato, verrà utilizzata l'ora di creazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a02ea1d4e7424ca989929da5e598f379940fdbf2" datatype="html">
+ <source>Duration</source>
+ <target>Durata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f4e35e36f4d3c62e2c17df41730b6dee4afc4b9" datatype="html">
+ <source>End time</source>
+ <target>Ora di fine</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="992123459137d45c15df5548bc9682aad835c04b" datatype="html">
+ <source>Matchers</source>
+ <target>Matcher</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e023166c55833d5a13f4143e3dbe372befe1b4e" datatype="html">
+ <source>A silence requires at least one matcher</source>
+ <target>Per un silenziamento è necessario almeno un matcher</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef765bd80c4806c51c891908c07a24bc76f019eb" datatype="html">
+ <source>Add matcher</source>
+ <target>Aggiungi matcher</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754178820914251524" datatype="html">
+ <source>silence</source>
+ <target>silenziamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8714559758543060819" datatype="html">
+ <source>Attribute name</source>
+ <target>Nome attributo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1338733395833138319" datatype="html">
+ <source>Regular expression</source>
+ <target>Espressione regolare</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35819898450851998" datatype="html">
+ <source>Please add your Prometheus host to the dashboard configuration and refresh the page</source>
+ <target>Aggiungere l'host Prometheus alla configurazione del dashboard e aggiornare la pagina</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f2f4cb9d876ff9d34fc082c1ac642d3cb98c360" datatype="html">
+ <source>To enable Silences, please provide the URL to the API of the Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>Per abilitare la funzione di silenziamento, specificare l'URL dell'API della gestione avvisi di Prometheus come descritto in <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7448808151142843482" datatype="html">
+ <source>Created by</source>
+ <target>Creato da</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4734349318830134239" datatype="html">
+ <source>Ends</source>
+ <target>Finisce</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1233087251567318644" datatype="html">
+ <source>Silence</source>
+ <target>Silenziamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="78af6a5e6e4d305557054b64d10f9f9446d8043d" datatype="html">
+ <source>{VAR_SELECT, select, true {Edit} other {Add}}</source>
+ <target>{VAR_SELECT, select, true {Modifica} other {Aggiungi}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2404fa8e80946d0ce3d0ae369b51cb26ec28d42" datatype="html">
+ <source><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/> Matcher</source>
+ <target><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/> matcher</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c25e04f554875dc2625a78ba0fc56c6010cd0d3" datatype="html">
+ <source>-- Select an attribute to match against --</source>
+ <target>-- Selezionare un attributo per la corrispondenza --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5049e204c14c648691ac775a64fb504467aeb549" datatype="html">
+ <source>Value</source>
+ <target>Valore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="77fc5c63497fc031ddc97645484e3d94ad27766c" datatype="html">
+ <source>Use regular expression</source>
+ <target>Usa espressione regolare</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5518753745858598442" datatype="html">
+ <source>no spec</source>
+ <target>nessuna spec.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1186363766752354382" datatype="html">
+ <source>unmanaged</source>
+ <target>non gestito</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5246585784774990516" datatype="html">
+ <source>count:<x id="PH" equiv-text="count"/></source>
+ <target>conteggio:<x id="PH" equiv-text="count"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001661117318762535" datatype="html">
+ <source>label:<x id="PH" equiv-text="label"/></source>
+ <target>etichetta:<x id="PH" equiv-text="label"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cb3aa7e9fea1d445a1a9d7797ab17e6ac6fe13b" datatype="html">
+ <source>Service Events</source>
+ <target>Eventi del servizio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3474944817987674409" datatype="html">
+ <source>Daemon type</source>
+ <target>Tipo di daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3136939605470297323" datatype="html">
+ <source>Daemon ID</source>
+ <target>ID daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8171022601808215887" datatype="html">
+ <source>Container ID</source>
+ <target>ID container</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8859473568390700297" datatype="html">
+ <source>Container Image name</source>
+ <target>Nome immagine container</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5623167616584404899" datatype="html">
+ <source>Container Image ID</source>
+ <target>ID immagine container</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="335348913532561915" datatype="html">
+ <source>Last Refreshed</source>
+ <target>Ultimo aggiornamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3022087209429182774" datatype="html">
+ <source>Daemon Events</source>
+ <target>Eventi del daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">140</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8604852007710946848" datatype="html">
+ <source>Service Name</source>
+ <target>Nome del servizio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="613875387304159316" datatype="html">
+ <source>Service Type</source>
+ <target>Tipo di servizio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907644935670421963" datatype="html">
+ <source>Service Events</source>
+ <target>Eventi del servizio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3214a1f3a4c3e89a848b4ec59adeeda3b913c396" datatype="html">
+ <source>-- Select a service type --</source>
+ <target>-- Selezionare un tipo di servizio --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f32579a9fd19d93c083175284ee3426d78751c33" datatype="html">
+ <source>Backend Service</source>
+ <target>Servizio backend</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2937074aed12b8158e929c58747a8216433b72b" datatype="html">
+ <source>-- No service available --</source>
+ <target>-- Nessun servizio disponibile --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19fb4480d95a5539db4e9c7b516d414774e61110" datatype="html">
+ <source>-- Select an existing RGW service --</source>
+ <target>-- Selezionare un servizio RGW esistente --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2798cc1e152b1ec07fd8daf94a2a073d1ba1ebcc" datatype="html">
+ <source>Id</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d5156b9d9a79d162c353c4aa9bc6840ad5c6257" datatype="html">
+ <source>The value does not match the pattern <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&lt;service_id&gt;[.&lt;realm_name&gt;.&lt;zone_name&gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <target>Il valore non corrisponde al modello <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&amp;lt;service_id&amp;gt;[.&amp;lt;realm_name&amp;gt;.&amp;lt;zone_name&amp;gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83d5d7edd8a0be253c4e93ad4c3efe86d9ac520f" datatype="html">
+ <source>Unmanaged</source>
+ <target>Non gestito</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c15fa461935e0f600bc5d1660af1da67f024fc2a" datatype="html">
+ <source>Placement</source>
+ <target>Posizionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="863226cffd5b66a6fee9810a9282a5006d6ef576" datatype="html">
+ <source>Label</source>
+ <target>Etichetta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06412bce0f4fe4311193e9763666089bf9d980da" datatype="html">
+ <source>Count</source>
+ <target>Conteggio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f193722f1e788f14a823b89ac1794c3ba934f9f" datatype="html">
+ <source>Only that number of daemons will be created.</source>
+ <target>Verrà creato solo quel numero di daemon.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee1a29cc658e4fa891be762d7bae96139b57c8f4" datatype="html">
+ <source>The value must be at least 1.</source>
+ <target>Il valore deve essere almeno 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">369</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cb2741a46e3560f6bc6dfd99d385e86b08b26d72" datatype="html">
+ <source>Port</source>
+ <target>Porta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a23ed3598cca5285606675b6cb2536a56b411ade" datatype="html">
+ <source>The value cannot exceed 65535.</source>
+ <target>Il valore non può superare 65535.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">404</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d8ebdc326e6b9ff35feee3f762b7ab39c02d78f" datatype="html">
+ <source>-- No pools available --</source>
+ <target>-- Nessun pool disponibile --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84b675705324741b954615fedf2417d4d873b0b6" datatype="html">
+ <source>Trusted IPs</source>
+ <target>Indirizzi IP attendibili</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b543e7c787cc48c2938cbce2d14c6afea5a598df" datatype="html">
+ <source>Comma separated list of IP addresses.</source>
+ <target>Elenco di indirizzi IP separati da virgole.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1039ea40da18a6453d9c1adc72a35aed099029d0" datatype="html">
+ <source>Please add the <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> IP addresses here, otherwise the iSCSI gateways can't be reached.</source>
+ <target>Aggiungere qui gli indirizzi IP di <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/>, senza i quali non è possibile raggiungere i gateway iSCSI.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6265b64c17a1e19775769489bfd0b152fa1f3ba1" datatype="html">
+ <source>Virtual IP</source>
+ <target>IP virtuale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61893fde6e9e05a6b91619d501edaa7962b438ff" datatype="html">
+ <source>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</source>
+ <target>L'indirizzo IP virtuale e la subnet (in notazione CIDR) in cui sarà disponibile il servizio in ingresso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">333</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ece04ddf7e96f445415ebd90d93c455e03e8cf53" datatype="html">
+ <source>Frontend Port</source>
+ <target>Porta del front-end</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">352</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae6fd97454d184b374984c9ff808176ece54f0dd" datatype="html">
+ <source>The port used to access the ingress service.</source>
+ <target>La porta utilizzata per accedere al servizio in ingresso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1261eacf161f75efc9dfea84dd97b4a466b89aa1" datatype="html">
+ <source>Monitor Port</source>
+ <target>Porta del monitor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4df6281ed630ba96f09790a46a7fe0ec0e666bb6" datatype="html">
+ <source>The port used by haproxy for load balancer status.</source>
+ <target>La porta utilizzata da haproxy per lo stato del servizio di bilanciamento del carico.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ce24ae1d792ed2846ba57e7ed6397a802caeff5" datatype="html">
+ <source>CIDR Networks</source>
+ <target>Reti CIDR</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">414</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7c13184af0c09e3bad77daa5f4869138708d26b2" datatype="html">
+ <source>A list of networks to identify which network interface to use for the virtual IP address.</source>
+ <target>Un elenco di reti per identificare l'interfaccia di rete da utilizzare per l'indirizzo IP virtuale.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8fe73a4787b8068b2ba61f54ab7e0f9af2ea1fc9" datatype="html">
+ <source>Version</source>
+ <target>Versione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a6855d17f6b9820bb9709870efdcc7da99552d3" datatype="html">
+ <source>-- Select SNMP version --</source>
+ <target>-- Selezionare la versione SNMP --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">442</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a7369891e88cd613e45a39b55a282c97776d05f5" datatype="html">
+ <source>Destination</source>
+ <target>Destinazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f09a5d334a73a4b5ba031d7fa65151cad5ec7133" datatype="html">
+ <source>Must be of the format hostname:port.</source>
+ <target>Deve essere nel formato nome host:porta.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b68c79ffe3af1db88180454fbc2fa880a51ccf52" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>hostname:port<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>Il valore non corrisponde al modello: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>nome host:porta<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">470</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c90ad98a026d781ab729911873767e549d78f99" datatype="html">
+ <source>Engine Id</source>
+ <target>ID motore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">478</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d39d015ebd667fb6bddf08bb0e5b3faa6cf044c" datatype="html">
+ <source>Unique identifier for the device (in hex).</source>
+ <target>Identificatore univoco del dispositivo (in esadecimale).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">480</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514cda7dc49062c5c532427245ce47c4954bc32" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>Il valore non corrisponde al modello: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>deve essere di tipo esadecimale e la sua lunghezza deve essere un multiplo di 2 con valore minimo = 10 e valore massimo = 64<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b2d628c51192ade0044212b409c758c20f9c021" datatype="html">
+ <source>Auth Protocol</source>
+ <target>Protocollo di autenticazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc8bb2315a5101770a752b18e03b5c730539397c" datatype="html">
+ <source>-- Select auth protocol --</source>
+ <target>-- Selezionare il protocollo di autenticazione --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">508</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6777f99fd13e03874afe26ba7289dc9fc211af04" datatype="html">
+ <source>Privacy Protocol</source>
+ <target>Protocollo di privacy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70512b7c13bce85b3928920b29fafbd59a853383" datatype="html">
+ <source>-- Select privacy protocol --</source>
+ <target>-- Selezionare il protocollo di privacy --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b48c81465d14465b95826b99e05acfabef1814c6" datatype="html">
+ <source>Credentials</source>
+ <target>Credenziali</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">541</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4ea0163c25c818aab982072b1b8d5ab585e9a5a" datatype="html">
+ <source>SNMP Community</source>
+ <target>Community SNMP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">547</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="08c74dc9762957593b91f6eb5d65efdfc975bf48" datatype="html">
+ <source>Username</source>
+ <target>Nome utente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="948758e1412bb2ecdb98e3a4f1cbb6d7458456f2" datatype="html">
+ <source>Encryption</source>
+ <target>Crittografia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">598</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e65610b5d940367f1ff6b57772b96e94e35fe202" datatype="html">
+ <source>SSL</source>
+ <target>SSL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">624</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e37e0d06148c7708e88b4a1eb412babbe1a4afc" datatype="html">
+ <source>Certificate</source>
+ <target>Certificato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">634</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="295ae4f632322098deca8a3ddfbc7aeaabb5423b" datatype="html">
+ <source>The SSL certificate in PEM format.</source>
+ <target>Il certificato SSL in formato PEM.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">635</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464272c069fe56f6c50f41f426a25b2a42c95ba5" datatype="html">
+ <source>Invalid SSL certificate.</source>
+ <target>Certificato SSL non valido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">650</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0596d06bf1f8a15d4bfe56226971ecdd78013b1f" datatype="html">
+ <source>Private key</source>
+ <target>Chiave privata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">659</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ded15dc55104994c0230189f34dff84a4955aafb" datatype="html">
+ <source>The SSL private key in PEM format.</source>
+ <target>La chiave privata SSL in formato PEM.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">660</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19bdc1597d815b456793ff87c89af4257a85a103" datatype="html">
+ <source>Invalid SSL private key.</source>
+ <target>Chiave privata SSL non valida.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">675</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3356018487523380058" datatype="html">
+ <source>service</source>
+ <target>servizio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2412938991511187011" datatype="html">
+ <source>There are no hosts.</source>
+ <target>Nessun host presente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2594503755408511486" datatype="html">
+ <source>Filter hosts</source>
+ <target>Filtra host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5869780110608474933" datatype="html">
+ <source>Placement</source>
+ <target>Posizionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2956098160626271284" datatype="html">
+ <source>Running</source>
+ <target>In esecuzione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="013f48ee777d2e53e2bcba36e1a99fcbb7ef8cb6" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report configuration</source>
+ <target>Passaggio <x id="INTERPOLATION" equiv-text="{{ step }}"/> di 2: configurazione del rapporto di telemetria</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a09b723a928774bff707973c99999dcf3d84a349" datatype="html">
+ <source>The telemetry module sends anonymous data about this Ceph cluster back to the Ceph developers to help understand how Ceph is used and what problems users may be experiencing.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> This data is visualized on <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>public dashboards<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> that allow the community to quickly see summary statistics on how many clusters are reporting, their total capacity and OSD count, and version distribution trends.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> The data being reported does <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>not<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> contain any sensitive data like pool names, object names, object contents, hostnames, or device serial numbers. It contains counters and statistics on how the cluster has been deployed, the version of Ceph, the distribution of the hosts and other parameters which help the project to gain a better understanding of the way Ceph is used. The data is sent secured to <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> and <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (device report).</source>
+ <target>Il modulo di telemetria invia dati anonimi su questo cluster Ceph agli sviluppatori Ceph per analizzare in che modo viene utilizzato Ceph e quali problemi potrebbero riscontrare gli utenti.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Questi dati sono visualizzati su <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>dashboard pubblici<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> che consentono alla comunità di visualizzare rapidamente le statistiche di riepilogo sul numero di cluster che generano rapporti, la loro capacità totale e il numero di OSD e i trend di distribuzione delle versioni.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> I dati oggetto dei rapporti <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>non<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> sono dati sensibili come nomi di pool, nomi di oggetto, contenuti degli oggetti, nomi host o numeri di serie del dispositivo. Sono invece dati relativi a contatori e statistiche sulla modalità di distribuzione del cluster, sulla versione di Ceph, sulla distribuzione degli host e su altri parametri che consentono di comprendere meglio la modalità di utilizzo di Ceph. I dati vengono inviati in modalità protetta a <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> e <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (rapporto dispositivo).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">14,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c95505b5a74151a0c235b19b9c41db7983205ba7" datatype="html">
+ <source>Deactivate</source>
+ <target>Disattiva</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19" datatype="html">
+ <source>Channels</source>
+ <target>Canali</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e25b17c0b4ef361b6a05aaec2bbd2b7e86680458" datatype="html">
+ <source>The telemetry report is broken down into several &quot;channels&quot;, each with a different type of information that can be configured below.</source>
+ <target>Il rapporto di telemetria è suddiviso in più &quot;canali&quot;, ognuno con un tipo diverso di informazioni che è possibile configurare di seguito.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">32,33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380ab580741bec31346978e7cab8062d6970408d" datatype="html">
+ <source>Basic</source>
+ <target>Base</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd898057f0add35258a5fb5c90d792c5e2147452" datatype="html">
+ <source>Includes basic information about the cluster:</source>
+ <target>Include informazioni di base sul cluster:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da213e9ba8a86b453d04f794f58c9803f7b062b1" datatype="html">
+ <source>Capacity of the cluster</source>
+ <target>Capacità del cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d5fe31d9e13239bdd223d0bbd289a1b1903e86" datatype="html">
+ <source>Number of monitors, managers, OSDs, MDSs, object gateways, or other daemons</source>
+ <target>Numero di monitor, manager, OSD, MDS, gateway di oggetto o altri daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a3eb7834b4baf412f8863d14883972897d9acb7" datatype="html">
+ <source>Software version currently being used</source>
+ <target>Versione del software attualmente in uso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34881ae65482ffa74ccb4043fb2622e48ed146d5" datatype="html">
+ <source>Number and types of RADOS pools and CephFS file systems</source>
+ <target>Numero e tipi di pool RADOS e file system CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="696f8f5ea7a9cf6125b9a3af160981fda363552d" datatype="html">
+ <source>Names of configuration options that have been changed from their default (but not their values)</source>
+ <target>Nomi di opzioni di configurazione modificati rispetto al default (ad eccezione dei valori)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34292940316300d09abe5e675d452fae199f626b" datatype="html">
+ <source>Crash</source>
+ <target>Arresto anomalo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7620e332b7dea1e832158e85847255eb4d9e6bbc" datatype="html">
+ <source>Includes information about daemon crashes:</source>
+ <target>Include informazioni sugli arresti anomali del daemon:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1aa4306a6e840fe35b70c9b07d38ce85f281cfa" datatype="html">
+ <source>Type of daemon</source>
+ <target>Tipo di daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4f2cbedb4b14b68bc9f390e3391445c1b6682da" datatype="html">
+ <source>Version of the daemon</source>
+ <target>Versione del daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d62603cdc75645ea873fc8f7f69c32b5f4a2aa9" datatype="html">
+ <source>Operating system (OS distribution, kernel version)</source>
+ <target>Sistema operativo (versione kernel e distribuzione del sistema operativo)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84facf84a73631d66e9a4e0bc1c40097b9d14742" datatype="html">
+ <source>Stack trace identifying where in the Ceph code the crash occurred</source>
+ <target>Traccia dello stack che identifica il punto in cui si è verificato l'arresto anomalo nel codice Ceph</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea64d4177bd648e1a20c92669e6857762b811d8c" datatype="html">
+ <source>Device</source>
+ <target>Dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4bc37bcbbcea881a269b4063b3d93dec8ee67d5" datatype="html">
+ <source>Includes information about device metrics like anonymized SMART metrics.</source>
+ <target>Include informazioni sulle metriche del dispositivo, come le metriche SMART rese anonime.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37de70e8ba539187d0171a38dad2a63c323096eb" datatype="html">
+ <source>Ident</source>
+ <target>Rientro</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b126025440f118cd02ce78362d61a5001c27617" datatype="html">
+ <source>Includes user-provided identifying information about the cluster:</source>
+ <target>Include informazioni di identificazione fornite dall'utente sul cluster:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62c6e9aecff7e04ef7d36fdee4ab4fb285a7a2b5" datatype="html">
+ <source>Contact Information</source>
+ <target>Informazioni di contatto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61ba9a84051b3f470122e59cf5a746552b378269" datatype="html">
+ <source>Submitting any contact information is completely optional and disabled by default.</source>
+ <target>L'invio delle informazioni di contatto è facoltativo e disabilitato per default.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34746fb1c7f3d2194d99652bdff89e6e14c9c4f4" datatype="html">
+ <source>Contact</source>
+ <target>Contatto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="632cac1e025b77b2d77fed16ad22a410ddacab9e" datatype="html">
+ <source>My first Ceph cluster</source>
+ <target>Primo cluster Ceph personale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3a58c8a81b9ffda26a154eae25a422c9f7de37b" datatype="html">
+ <source>Organization</source>
+ <target>Organizzazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e8fda44e2c5bb51860f26cd9c2730f9ae1db9869" datatype="html">
+ <source>Organization name</source>
+ <target>Nome dell'organizzazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d49310535abb3792d8c9c991dd0d990d73d29af" datatype="html">
+ <source>Interval</source>
+ <target>Intervallo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91317562c9dfefbdd5973faf11d217f571d073c7" datatype="html">
+ <source>The module compiles and sends a new report every 24 hours by default. You can adjust this interval by setting a different number of hours.</source>
+ <target>Per default, il modulo compila e invia un nuovo rapporto ogni 24 ore. È possibile modificare questo intervallo impostando un numero diverso di ore.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">185,186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a12cf4cf71ef3161a024382ab542cf0eba094504" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to 8.</source>
+ <target>Il valore immesso è troppo basso. Deve essere maggiore di o uguale a 8.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a92e437fac14b4010c4515b31c55a311d026a57f" datatype="html">
+ <source>Proxy</source>
+ <target>Proxy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6de03357358c7eff62aca486508bb5c2046e0669" datatype="html">
+ <source>If the cluster cannot directly connect to the configured telemetry endpoint (default telemetry.ceph.com), you can configure a HTTP/HTTPS proxy server by e.g. adding https://10.0.0.1:8080</source>
+ <target>Se il cluster non è in grado di connettersi direttamente all'endpoint di telemetria configurato (per default, telemetry.ceph.com), è possibile configurare un server proxy HTTP/HTTPS aggiungendo ad esempio https://10.0.0.1:8080</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5687a733af051bfca97dbffba282e39fbb9b8c8f" datatype="html">
+ <source>You can also include a user:pass if needed e.g. https://ceph:telemetry@10.0.0.1:8080</source>
+ <target>Se necessario, è inoltre possibile includere un user:pass, come https://ceph:telemetry@10.0.0.1:8080</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e6430c68df43ea65e4145972b01186fba40f26a" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Note:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> By clicking 'Next' you will first see a preview of the report content before you can activate the automatic submission of your data.</source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Nota:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> facendo clic su 'Avanti' verrà visualizzata un'anteprima del contenuto del rapporto e sarà poi possibile attivare l'invio automatico dei propri dati.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">219,220</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d8d878f8d60905e1306c225716305a331b784c8" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report preview</source>
+ <target>Passaggio <x id="INTERPOLATION" equiv-text="{{ step }}"/> di 2: anteprima del rapporto di telemetria</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e23d0064b6474f309c74e1c928cc0920f479d9a5" datatype="html">
+ <source>Report ID <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <target>ID rapporto <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">249,252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4060e92658964e356a0992a900c8aa811c2cfec0" datatype="html">
+ <source>A randomized UUID to identify a particular cluster over the course of several telemetry reports.</source>
+ <target>Un UUID casuale per identificare un determinato cluster nel corso di diversi rapporti di telemetria.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60900bc663571f852a04950a123508b106d97204" datatype="html">
+ <source>Report preview <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <target>Anteprima del rapporto <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">267,270</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3de417f739c336284c42904552e81e8d852daecc" datatype="html">
+ <source>The actual telemetry data that will be submitted.</source>
+ <target>I dati di telemetria effettivi che verranno inviati.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="933a2b6f087670ff42c95876e6ecfb2faa3e3867" datatype="html">
+ <source>I agree to my telemetry data being submitted under the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Community Data License Agreement - Sharing - Version 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></source>
+ <target>Acconsento all'invio dei dati di telemetria ai sensi del <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Community Data License Agreement - Sharing - Versione 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">304</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8293060085588842566" datatype="html">
+ <source>The Telemetry module has been configured and activated successfully.</source>
+ <target>Il modulo di telemetria è stato configurato e attivato correttamente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5380636888677486786" datatype="html">
+ <source>An Error occurred while updating the Telemetry module configuration. Please Try again</source>
+ <target>Si è verificato un errore durante l'aggiornamento della configurazione del modulo di telemetria. Riprovare</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2bcd3296d2850de762fb943060b7e086a893181" datatype="html">
+ <source>Health</source>
+ <target>Integrità</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61e0f26d843eec0b33ff475e111b0c2f7a80b835" datatype="html">
+ <source>Statistics</source>
+ <target>Statistiche</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73caac4265ea7314ff061e5a1d78a6361a6dd3b8" datatype="html">
+ <source>Cluster Status</source>
+ <target>Stato del cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="624f596cc3320f5e0a0d7c7346c364e5af9bdd8c" datatype="html">
+ <source>Monitors</source>
+ <target>Monitor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9183778f2c6473d7ccb080f651caa01faaf70c" datatype="html">
+ <source>OSDs</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c34287a0423968dac8a41463b80855a0ff789403" datatype="html">
+ <source>Managers</source>
+ <target>Manager</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="946ac5dea9921dc09d7b0a63b89535371f283b19" datatype="html">
+ <source>Object Gateways</source>
+ <target>Object Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff03fa5bcf37c4da46ad736c1f7d03f959e8ba9a" datatype="html">
+ <source>Metadata Servers</source>
+ <target>Server di metadati</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d817609ba4993eba859409ab71e566168f4d5f5a" datatype="html">
+ <source>iSCSI Gateways</source>
+ <target>iSCSI Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ce9dfdc6dccb28dc75a78c704e09dc18fb02dcfa" datatype="html">
+ <source>Capacity</source>
+ <target>Capacità</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f383269db2d32cccee9e936fe549dccb9fdbf4" datatype="html">
+ <source>Raw Capacity</source>
+ <target>Capacità di base</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498a109c6e9e94f1966de01aa0326f7f0ac6fb52" datatype="html">
+ <source>PG Status</source>
+ <target>Stato gruppo di posizionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5f8a813f91a11af99132e4beafc136cfc13d73b" datatype="html">
+ <source>PGs per OSD</source>
+ <target>Gruppi di posizionamento per OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32efd1c3f70e3c5244239de97a2cc95d98534a14" datatype="html">
+ <source>Client Read/Write</source>
+ <target>Lettura/Scrittura client</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="52213660b2454d139ada3079a42ec6caf3c3c01e" datatype="html">
+ <source>Client Throughput</source>
+ <target>Velocità effettiva client</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="275485415092cbae3a9f3cbb786ebe283cacfdd5" datatype="html">
+ <source>Recovery Throughput</source>
+ <target>Velocità effettiva di recupero</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35416fcdf9cb33d2b299d3f2028c390454b55d02" datatype="html">
+ <source>Scrubbing</source>
+ <target>Pulitura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="44ecac93d67c6a671198091c2270354f80322327" datatype="html">
+ <source><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> See <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>Logs<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for more details.</source>
+ <target><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> Vedere <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>Log<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> per ulteriori informazioni.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520247697658334435" datatype="html">
+ <source>Reads</source>
+ <target>Letture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5947645586591788199" datatype="html">
+ <source>/s</source>
+ <target>/s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7527163811128350993" datatype="html">
+ <source>Writes</source>
+ <target>Scritture</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7684088941299429132" datatype="html">
+ <source>IOPS</source>
+ <target>IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81585474102700882" datatype="html">
+ <source>Used</source>
+ <target>Utilizzato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">179</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8695656831075719969" datatype="html">
+ <source>Avail.</source>
+ <target>Dispon.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6352596107300820129" datatype="html">
+ <source>Clean</source>
+ <target>Pulisci</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4016774570903735270" datatype="html">
+ <source>Working</source>
+ <target>In funzione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4467323362722952678" datatype="html">
+ <source>Unknown</source>
+ <target>Sconosciuto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">218</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7790772795962334429" datatype="html">
+ <source>Healthy</source>
+ <target>Integro</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4708847204147472247" datatype="html">
+ <source>Misplaced</source>
+ <target>Posizione errata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3120522496446378904" datatype="html">
+ <source>Degraded</source>
+ <target>Danneggiato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8047698491745405137" datatype="html">
+ <source>Unfound</source>
+ <target>Non trovato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81117556780777231" datatype="html">
+ <source>objects</source>
+ <target>oggetti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795e8a00db46b750113d5db93e8d97e2b3079894" datatype="html">
+ <source>For an overview of <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/> widgets click <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></source>
+ <target>Per una panoramica dei <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/> widget fare clic <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">21,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16bd21c1b48036d54c6a595f5cff2540cfba7f60" datatype="html">
+ <source>here</source>
+ <target>qui</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8515973702474791807" datatype="html">
+ <source>up</source>
+ <target>attivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4223604072115719661" datatype="html">
+ <source>no filesystems</source>
+ <target>nessun file system</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2078241808113697591" datatype="html">
+ <source>active</source>
+ <target>attivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3232506912392089107" datatype="html">
+ <source>standby</source>
+ <target>standby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576716133013765863" datatype="html">
+ <source>standby daemons</source>
+ <target>daemon in standby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3629620351427988554" datatype="html">
+ <source>active daemon</source>
+ <target>daemon attivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5954854563228355745" datatype="html">
+ <source>standbyReplay</source>
+ <target>standbyReplay</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7329683463736701292" datatype="html">
+ <source>n/a</source>
+ <target>n/d</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/not-available.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8271970016544066882" datatype="html">
+ <source><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (quorum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</source>
+ <target><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (quorum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mon-summary.pipe.ts</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6489441800790477240" datatype="html">
+ <source>total</source>
+ <target>totale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5965118847182332588" datatype="html">
+ <source>near full</source>
+ <target>quasi pieno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="268166731974484199" datatype="html">
+ <source>full</source>
+ <target>pieno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47116253e36f4e38a97ba41b2d3122c6c15ab904" datatype="html">
+ <source>Clients (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</source>
+ <target>Client (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5159814115056353668" datatype="html">
+ <source>Addresses</source>
+ <target>Indirizzi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1811797298582428088" datatype="html">
+ <source>Access Type</source>
+ <target>Tipo di accesso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3575940435199094878" datatype="html">
+ <source>Squash</source>
+ <target>Esegui squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2944102521023817891" datatype="html">
+ <source>Cluster</source>
+ <target>Cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91772203889648189" datatype="html">
+ <source>NFS Protocol</source>
+ <target>Protocollo NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907766170797643122" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1032539711043211945" datatype="html">
+ <source>Transport</source>
+ <target>Trasporto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2489852208080013495" datatype="html">
+ <source>Storage Backend</source>
+ <target>Backend di storage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8440421106569981118" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4095248496892792741" datatype="html">
+ <source>CephFS User</source>
+ <target>Utente CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2535727951299201687" datatype="html">
+ <source>CephFS Filesystem</source>
+ <target>File system CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2169401160512036026" datatype="html">
+ <source>Security Label</source>
+ <target>Etichetta di sicurezza</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3671149880069127721" datatype="html">
+ <source>Object Gateway</source>
+ <target>Object Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1643028261508790" datatype="html">
+ <source>Object Gateway User</source>
+ <target>Utente Object Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2dae0bda66f6a349444951c0379c28cda47d6d1" datatype="html">
+ <source>Any client can access</source>
+ <target>Può accedere qualsiasi client</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7882f2edb1d4139800b276b6b0bbf5ae0b2234ef" datatype="html">
+ <source>Addresses</source>
+ <target>Indirizzi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f3f74c0f6925826cb2188576391c0da01a23f0" datatype="html">
+ <source>Must contain one or more comma-separated values</source>
+ <target>Deve contenere uno o più valori delimitati da virgole</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb5b2073697f3f4378c44a49b7524934c9268f4" datatype="html">
+ <source>For example:</source>
+ <target>Ad esempio:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f969c655b3fbe4fba7e277caf4cd2c459f9fca5" datatype="html">
+ <source>Access Type</source>
+ <target>Tipo di accesso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28952831a284cfe2b4fc39ca610e80b52598905a" datatype="html">
+ <source>Squash</source>
+ <target>Esegui squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0660ae339068979854ade34a96546980723dede3" datatype="html">
+ <source>Add clients</source>
+ <target>Aggiungi client</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8571141481686087364" datatype="html">
+ <source>(inherited from global config)</source>
+ <target>(ereditato dalla configurazione globale)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3563954518111128118" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- Selezionare il tipo di accesso --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3802199399355755843" datatype="html">
+ <source>inherited from global config</source>
+ <target>ereditato dalla configurazione globale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8729531250118136719" datatype="html">
+ <source>-- Select what kind of user id squashing is performed --</source>
+ <target>-- Selezionare il tipo di squash dell'ID utente che viene eseguito --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4d1dd59b039ad818d9da7e29a773e10e41d9821" datatype="html">
+ <source>Cluster</source>
+ <target>Cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="625f8f0f3e5b7c92651606d77484ff3d07b3c12b" datatype="html">
+ <source>This is the ID of an NFS Service.</source>
+ <target>Questo è l'ID di un servizio NFS.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="135b91a2d908d5814b782695470a6a786c99d9d2" datatype="html">
+ <source>-- No cluster available --</source>
+ <target>-- Nessun cluster disponibile --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c501dba379f566885919240ea277b5bc10c14d18" datatype="html">
+ <source>-- Select the cluster --</source>
+ <target>-- Selezionare il cluster --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7bd3ad665c398c7fe97230ab59e67370653a82" datatype="html">
+ <source>This field is required. To create a new NFS cluster, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>add a new NFS Service<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <target>Questo campo è obbligatorio. Per creare un nuovo cluster NFS, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>aggiungere un nuovo servizio NFS<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">41,43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3f6ba7fe84d6508705cdfe234f0fcc8ff85c9cf" datatype="html">
+ <source>Storage Backend</source>
+ <target>Backend di storage</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6fee356d1db954255a56d8169405a89595246b9" datatype="html">
+ <source>-- Select the storage backend --</source>
+ <target>-- Selezionare il backend di storage --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3c2793dd2ef56954f872142d5ec1becb84c0fe1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="796e42bec8a6996607cf1f3e80235b86d695804a" datatype="html">
+ <source>Volume</source>
+ <target>Volume</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee3ba0ab5f0ccd597b3e44021c71e9aaad14df0a" datatype="html">
+ <source>-- No CephFS filesystem available --</source>
+ <target>-- Nessun file system CephFS disponibile --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="764c57812558b1ae66c5eec95d7efd2b1bf761e3" datatype="html">
+ <source>-- Select the CephFS filesystem --</source>
+ <target>-- Selezionare il file system CephFS --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="957512d0321f73e9f115bce1bd823fa635170c41" datatype="html">
+ <source>Security Label</source>
+ <target>Etichetta di sicurezza</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="65ce0fa4da1ed55e658aeb31d1644a29f06bb342" datatype="html">
+ <source>Enable security label</source>
+ <target>Abilita etichetta di sicurezza</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e808f804130c7b6ff719509cbc06ebb27393a48" datatype="html">
+ <source>CephFS Path</source>
+ <target>Percorso CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1338c2f83e49ea7f2fc04e9fe90c5d330b7a10f" datatype="html">
+ <source>A path in a CephFS file system.</source>
+ <target>Un percorso nel file system CephFS.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ecc0107badb6625466aaa3f975b5c05276f432f" datatype="html">
+ <source>Path need to start with a '/' and can be followed by a word</source>
+ <target>Il percorso deve iniziare con una barra '/' e può essere seguito da una parola</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f9d8bd873c34c5ab2d4d0cf995fe5183ab25f6e" datatype="html">
+ <source>The path does not exist in the selected volume.</source>
+ <target>Il percorso non esiste nel volume selezionato.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd197d7773cef10f368f08c53b47979c3df1f22d" datatype="html">
+ <source>Bucket</source>
+ <target>Compartimento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ca90b4b16347ef7017967915e8624472976c85c" datatype="html">
+ <source>The bucket does not exist or is not in the default realm (if multiple realms are configured). To continue, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>create a new bucket<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <target>Il compartimento non esiste o non si trova nell'area di autenticazione di default (se sono configurate più aree di autenticazione). Per continuare, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>creare un nuovo compartimento<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bee6900143996c0e908a10564532eba3da0b30fb" datatype="html">
+ <source>NFS Protocol</source>
+ <target>Protocollo NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5043c0921e709935ab026bb3253ffe1f159fca1" datatype="html">
+ <source>NFSv4</source>
+ <target>NFSv4</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d2c39708a32910f89701dd7e1cfb9ec1c195768" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1f8be2ae25947bec0b84c2338201580ea053f34e" datatype="html">
+ <source>The position that this <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> export occupies in the <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo FS<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (it must be unique).</source>
+ <target>La posizione occupata da questa esportazione <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> nello <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo FS<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (deve essere univoca).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">241,242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3af55f7fd5b1d9e5a53e030c80116dc635bfb9f" datatype="html">
+ <source>By using different Pseudo options, the same Path may be exported multiple times.</source>
+ <target>Utilizzando diverse opzioni Pseudo, è possibile esportare più volte lo stesso percorso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5eb719aa900fed3f9d4a1d74bcc158f07f67f684" datatype="html">
+ <source>The pseudo is already in use by another export.</source>
+ <target>Lo pseudo è già utilizzato da un'altra esportazione.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddf98fcdeeb17643db020d54f42b5e56b5f9a52a" datatype="html">
+ <source>Pseudo needs to start with a '/' and can't contain any of the following: &gt;, &lt;, |, &amp;, ( or ).</source>
+ <target>Lo Pseudo deve iniziare con una barra '/' e non può contenere nessuno dei caratteri seguenti: &gt;, &lt;, |, &amp;, ( o ).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="27eb35c4b4ac08781a7253a2ab40f8f7d957ba51" datatype="html">
+ <source>-- No access type available --</source>
+ <target>-- Nessun tipo di accesso disponibile --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">280</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="509ce016c9110a54028dafd741f15ceacbe74b5a" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- Selezionare il tipo di accesso --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67ce207d0b7eada1fe3d3187a39ba0c07be76b6c" datatype="html">
+ <source>The Object Gateway NFS backend has a number of limitations which will seriously affect applications writing to the share. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> for details before enabling write access.</source>
+ <target>Il backend NFS di Object Gateway dispone di una serie di limitazioni che influiranno gravemente sulle applicazioni che scrivono sulla condivisione. Consultare <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> per i dettagli prima di abilitare l'accesso in scrittura.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">293,296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4deda03573eaaff77e63f6a238a1f0ca7816950a" datatype="html">
+ <source>-- No squash available --</source>
+ <target>-- Nessuno squash disponibile --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">321</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a0e82a4da88e7fdf270444f838d45849676e9d4b" datatype="html">
+ <source>--Select what kind of user id squashing is performed --</source>
+ <target>--Selezionare il tipo di squash dell'ID utente da eseguire --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d01b7c3f7f06712c53d054cfbe4f53d446b038e8" datatype="html">
+ <source>Transport Protocol</source>
+ <target>Protocollo di trasporto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2a6ad6e8bc315f07911722c05767ac79c136d99" datatype="html">
+ <source>UDP</source>
+ <target>UDP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">349</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c030f11e0aae9b24d2c048c57f29f590be621df" datatype="html">
+ <source>TCP</source>
+ <target>TCP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">359</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f84d7fd4d52eb5b2229b632ef5119dac63d5597" datatype="html">
+ <source>No user id squashing is performed.</source>
+ <target>Non viene eseguito alcuno squash dell'ID utente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">378</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb1d148107e36852325106a518385b1b0de28835" datatype="html">
+ <source>uid 0 and gid 0 are squashed to the Anonymous_Uid and Anonymous_Gid gid 0 in alt_groups lists is also squashed.</source>
+ <target>Viene eseguito lo squash di uid 0 e gid 0 in Anonymous_Uid e inoltre viene eseguito lo squash di Anonymous_Gid gid 0 negli elenchi alt_groups.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">382</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1309d6f67955799863337b201413faa61a175ddb" datatype="html">
+ <source>uid 0 and gid of any value are squashed to the Anonymous_Uid and Anonymous_Gid alt_groups lists is discarded.</source>
+ <target>Viene eseguito lo squash di uid 0 e gid di qualsiasi valore in Anonymous_Uid e vengono scartati gli elenchi alt_groups Anonymous_Gid.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85f23d5c9b57dc78dda4150d13aa3b99e985350b" datatype="html">
+ <source>All users are squashed.</source>
+ <target>Viene eseguito lo squash di tutti gli utenti.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2691935247101074756" datatype="html">
+ <source>NFS export</source>
+ <target>Esportazione NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8727258243239498387" datatype="html">
+ <source><x id="PH" equiv-text="fsalItem.descr"/> backend is not available. <x id="PH_1" equiv-text="errorMessage"/></source>
+ <target><x id="PH" equiv-text="fsalItem.descr"/> backend non disponibile. <x id="PH_1" equiv-text="errorMessage"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2772848515253260635" datatype="html">
+ <source>Error while retrieving paths.</source>
+ <target>Errore durante il recupero dei percorsi.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5239928491238988595" datatype="html">
+ <source>Error while retrieving bucket names.</source>
+ <target>Errore durante il recupero dei nomi dei compartimenti.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="734c9905951a774870497c5aaae8e3ee833b6196" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2190548d236ca5f7bc7ab2bca334b860c5ff2ad4" datatype="html">
+ <source>Object Gateway</source>
+ <target>Object Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca53d681a9892d6fdbb57ee9676582186515e961" datatype="html">
+ <source>Performance counters not available</source>
+ <target>Contatori delle prestazioni non disponibili</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="490e15ecc922965b6d8194754c87c5583aa071f3" datatype="html">
+ <source>The name can only consist of alphanumeric characters, dashes and underscores.</source>
+ <target>Il nome può contenere solo caratteri alfanumerici, trattini e caratteri di sottolineatura.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9edc2b494e660618af3e5225f68d40b7ca67629c" datatype="html">
+ <source>The chosen erasure code profile name is already in use.</source>
+ <target>Il nome del profilo del codice di cancellazione selezionato è già in uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35a4206db3105ed03e0dd799e1642b75b78123e8" datatype="html">
+ <source>Root</source>
+ <target>Radice</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf425784c7073c7e7f7c1bb90c2c19db7e751db2" datatype="html">
+ <source>Failure domain type</source>
+ <target>Tipo dominio di errore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72396a9565cf644d1fe1b21b790c4243ee270986" datatype="html">
+ <source>Device class</source>
+ <target>Classe dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d80e0c07bfea1b693a33ef2245007de92a6780" datatype="html">
+ <source>Let Ceph decide</source>
+ <target>Lascia decidere a Ceph</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101611937243846632" datatype="html">
+ <source>Crush Rule</source>
+ <target>Regola Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef9ff0e6227947b48dfab4ac39ade04af758913b" datatype="html">
+ <source>Plugin</source>
+ <target>Plug-in</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd69b31bce8f630eac1d4762b0bbcf72ce19d193" datatype="html">
+ <source>Data chunks (k)</source>
+ <target>Porzioni di dati (k)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0d26a6172d32cb81218fe2103c54a818cbc1189" datatype="html">
+ <source>Must be equal to or greater than 2.</source>
+ <target>Deve essere uguale a o maggiore di 2.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ba6f4800642eba4e8b056aa7167554c3afa8db0" datatype="html">
+ <source>Chunks (k+m) have exceeded the available OSDs of <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>.</source>
+ <target>Le porzioni (k+m) hanno superato gli OSD disponibili di <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="86fca2f788ce986eef835cd7ef8dfc9ae22447a4" datatype="html">
+ <source>For an equal distribution k has to be a multiple of (k+m)/l.</source>
+ <target>Per una distribuzione equa, k deve essere un multiplo di (k+m)/l.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8dd4bc172f1adc4afadaec291e465b082909148d" datatype="html">
+ <source>K has to be equal to or greater than m in order to recover data correctly through c.</source>
+ <target>K deve essere uguale o superiore a m per il recupero corretto dei dati tramite c.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2e5b0e6d0dba31c59f946392699a0a6c4dd9b83" datatype="html">
+ <source>Distribution factor: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></source>
+ <target>Fattore di distribuzione: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dab3a299ead121169b8e08ed618c3b6a2f66691b" datatype="html">
+ <source>Coding chunks (m)</source>
+ <target>Porzioni di codice (m)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e2773e5bd4948193f18f2361d663ecc3988c656" datatype="html">
+ <source>Must be equal to or greater than 1.</source>
+ <target>Deve essere uguale a o maggiore di 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">146</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cde4c945a49a260c0a47bcc7cd956846930a5f7" datatype="html">
+ <source>Durability estimator (c)</source>
+ <target>Strumento di stima della durata (c)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ec9ff9931f8ea1201792d6a01bf9a47b283d692" datatype="html">
+ <source>C has to be equal to or lower than m as m defines the amount of chunks that can be used.</source>
+ <target>C deve essere uguale o inferiore a m, dal momento che m definisce il numero di porzioni che è possibile utilizzare.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35594fe66657ea07b5b5f560927f78e81a229996" datatype="html">
+ <source>Helper chunks (d)</source>
+ <target>Porzioni helper (d)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0c250a8d281291273ed3504ade19ca6537e4d9a" datatype="html">
+ <source>Set d manually or use the plugin's default calculation that maximizes d.</source>
+ <target>Impostare d manualmente o utilizzare il calcolo di default del plug-in che massimizza d.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4304a5cd95742db0f81c3bdf29aa96bf3b0ca13d" datatype="html">
+ <source>D is automatically updated on k and m changes</source>
+ <target>D viene aggiornato automaticamente su k e m cambia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06a67d52427b12df2b3d439be0e1342ac72aeb5c" datatype="html">
+ <source>D can be set from <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> to <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></source>
+ <target>È possibile impostare d su un intervallo compreso tra <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> e <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4f8831d3bd6401e87710c4e3ee844f5efbf5de3" datatype="html">
+ <source>D can only be set to <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></source>
+ <target>È possibile impostare d solo su <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5d7aacffce2c6032c3ae9ef4d1b3847a926440b" datatype="html">
+ <source>D has to be greater than k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>).</source>
+ <target>D deve essere superiore a k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fd745d614884edc23c7ac9ad8aba9655f3793ac2" datatype="html">
+ <source>D has to be lower than k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>).</source>
+ <target>D deve essere inferiore a k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">199</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af668c2a095a979ea2b4e43cd82c2120ab56c21c" datatype="html">
+ <source>Locality (l)</source>
+ <target>Località (l)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="200fea08b63ae8d60cdbf33ffd2636159e87dc1e" datatype="html">
+ <source>Can't split up chunks (k+m) correctly with the current locality.</source>
+ <target>Impossibile suddividere correttamente le porzioni (k+m) con la località corrente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319ac5d692d11da686782159bd70e0b705c228ed" datatype="html">
+ <source>Locality groups: <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></source>
+ <target>Gruppi di località: <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">230</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d455a110bf6d2235e314e295ce1dfeee93d3dff2" datatype="html">
+ <source>Crush failure domain</source>
+ <target>Dominio di errore Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74a495f041f7dd102eee5c0bbc9e03083b538ae" datatype="html">
+ <source>Crush Locality</source>
+ <target>Località Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2f14a73f7a6e94479f67423cc51102da8d6f524" datatype="html">
+ <source>None</source>
+ <target>Nessuno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="363a99d62822b92913a4cce196d47f32c1258e2f" datatype="html">
+ <source>Scalar mds</source>
+ <target>Mds scalari</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2981733b912b693a9dd9d915d6d34f4692cc874a" datatype="html">
+ <source>Technique</source>
+ <target>Tecnica</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0098b6e47b04ec817361f384ce81d454ba5c0bb" datatype="html">
+ <source>Packetsize</source>
+ <target>Dimensioni del pacchetto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0252cd81ca54d0a2f69ec9ccf4248e73df5aa4a" datatype="html">
+ <source>Crush root</source>
+ <target>Radice Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">351</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1548d5c76f0406ddd1ba3c557e1e6db22e95b340" datatype="html">
+ <source>Crush device class</source>
+ <target>Classe dispositivo Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3f657ffa19dc6ac504b83c86209709522dcf065" datatype="html">
+ <source>Available OSDs: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></source>
+ <target>OSD disponibili: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03d84645f6e019c5a43909bbf2ea1696ee88332c" datatype="html">
+ <source>Directory</source>
+ <target>Directory</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1354845268685595937" datatype="html">
+ <source>EC Profile</source>
+ <target>Profilo codice di cancellazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3938a411d76796f8ae73b72ea4c77661207453bd" datatype="html">
+ <source>Cache Tiers Details</source>
+ <target>Dettagli livelli cache</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="991790413700941336" datatype="html">
+ <source>Cache Mode</source>
+ <target>Modalità cache</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9133265273798382582" datatype="html">
+ <source>Min Evict Age</source>
+ <target>Numero minimo di giorni per la rimozione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7172092927403263656" datatype="html">
+ <source>Min Flush Age</source>
+ <target>Numero minimo di giorni per la cancellazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8096695869347792608" datatype="html">
+ <source>Target Max Bytes</source>
+ <target>Numero massimo di byte di destinazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8854126142886240282" datatype="html">
+ <source>Target Max Objects</source>
+ <target>Numero massimo di oggetti di destinazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617215542453015899" datatype="html">
+ <source>No applications added</source>
+ <target>Nessuna applicazione aggiunta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4895689494338215646" datatype="html">
+ <source>Applications limit reached</source>
+ <target>Il limite di applicazioni è stato raggiunto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7322343326526084293" datatype="html">
+ <source>A pool can only have up to four applications definitions.</source>
+ <target>Un pool può contenere solo fino a quattro definizioni delle applicazioni.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1393735257943344790" datatype="html">
+ <source>Allowed characters '_a-zA-Z0-9'</source>
+ <target>Caratteri consentiti '_a-zA-Z0-9'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5520683885127790121" datatype="html">
+ <source>Maximum length is 128 characters</source>
+ <target>La lunghezza massima è di 128 caratteri</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587418377972855060" datatype="html">
+ <source>Filter or add applications'</source>
+ <target>Filtra o aggiungi applicazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5188881899285829380" datatype="html">
+ <source>Add application</source>
+ <target>Aggiungi applicazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16e113230b6b0d3165e076300880542bac7c8138" datatype="html">
+ <source>The chosen Ceph pool name is already in use.</source>
+ <target>Il nome del pool Ceph scelto è già in uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c75b132bef7b29fa5171768303c4b96e34ccaf68" datatype="html">
+ <source>It's not possible to create an RBD pool with '/' in the name. Please change the name or remove 'rbd' from the applications list.</source>
+ <target>Non è possibile creare un pool RBD che contiene '/' nel nome. Modificare il nome o rimuovere 'rbd' dall'elenco delle applicazioni.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">34,35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="171dc6d5c6bc4615d99778b0088cae80fd00bd10" datatype="html">
+ <source>Pool name can only contain letters, numbers, '.', '-', '_' or '/'.</source>
+ <target>Il nome del pool può contenere soltanto lettere, numeri, '.', '-', '_' o '/'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b85c657469e5ec8231c3de99b22f437bc01ffde5" datatype="html">
+ <source>Pool type</source>
+ <target>Tipo di pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="526c5443254c3b126eedb264840ffe827727bfd3" datatype="html">
+ <source>-- Select a pool type --</source>
+ <target>-- Selezionare un tipo di pool --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abfbe47b630929d93c7343dc154599c2e59330a" datatype="html">
+ <source>PG Autoscale</source>
+ <target>Ridimensionamento automatico gruppo di posizionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0aa21053410a94aa61d16985a4e95fd65523430d" datatype="html">
+ <source>Placement groups</source>
+ <target>Gruppi di posizionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6301f1391d726f8f450bb358058534db19541ca9" datatype="html">
+ <source>At least one placement group is needed!</source>
+ <target>È necessario almeno un gruppo di posizionamento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba9469a1ce6ed36e039c1f67247c8c81a5c71449" datatype="html">
+ <source>Your cluster can't handle this many PGs. Please recalculate the PG amount needed.</source>
+ <target>Il cluster non può gestire questo numero di gruppi di posizionamento. Ricalcolare il numero di gruppi di posizionamento necessari.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80ac68cd883369dac20688bc32b4cb33291b5e50" datatype="html">
+ <source>Calculation help</source>
+ <target>Guida per il calcolo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fccbd60493df26705d957ed6c02a3c447894678f" datatype="html">
+ <source>The current PGs settings were calculated for you, you should make sure the values suit your needs before submit.</source>
+ <target>Sono state calcolate le impostazioni dei gruppi di posizionamento attuali; prima di inviare, assicurarsi che i valori soddisfino le proprie esigenze.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">116,117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a43b2695131b48b76cebba676aba98a2bee17515" datatype="html">
+ <source>Replicated size</source>
+ <target>Dimensioni replicate</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bff144a4c4dc63b0e18fff2617d61a7ebdf2b6c" datatype="html">
+ <source>Minimum: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></source>
+ <target>Minimo: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9c54b41f6d58a74e5d0aa3429ed0c87a482551" datatype="html">
+ <source>Maximum: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></source>
+ <target>Massimo: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="452cf71ec44ee77428656936a6627eaf2dd3b47f" datatype="html">
+ <source>The size specified is out of range. A value from <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> to <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/> is usable.</source>
+ <target>Le dimensioni specificate non sono comprese nell'intervallo. È possibile utilizzare un valore nell'intervallo da <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> a <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">144,145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dda6196ffab88c1825f44a565c7b34e246e7e12f" datatype="html">
+ <source>A size of 1 will not create a replication of the object. The 'Replicated size' includes the object itself.</source>
+ <target>Una dimensione pari a 1 non creerà una replica dell'oggetto. La 'Dimensione replicata' include l'oggetto stesso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">148,149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c870fb00256b8a5b9cb9cd1a124e6390b9bc639" datatype="html">
+ <source>EC Overwrites</source>
+ <target>Sovrascritture codice di cancellazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f1abafaeb40ce52355ddcc24686e3cd17b64e08a" datatype="html">
+ <source>Applications</source>
+ <target>Applicazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9308b82fc183f710df60909f49cfc73aa5e076" datatype="html">
+ <source>CRUSH</source>
+ <target>CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9de7dde00e2139cc4bd03b1837afbe72ad15a1ff" datatype="html">
+ <source>Erasure code profile</source>
+ <target>Profilo del codice di cancellazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39b4620e6bd444e0a57a0a5c03fa8c96d7fe5235" datatype="html">
+ <source>-- No erasure code profile available --</source>
+ <target>-- Nessun profilo del codice di cancellazione disponibile --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498561757390d5528b263ce450d5f38efb00266d" datatype="html">
+ <source>-- Select an erasure code profile --</source>
+ <target>-- Selezionare un profilo del codice di cancellazione --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="616a2532fbaace94934f5943e381b63e2623f004" datatype="html">
+ <source>This profile can't be deleted as it is in use.</source>
+ <target>Non è possibile eliminare questo profilo poiché è in uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="994363f08f9fbfa3b3994ff7b35c6904fdff18d8" datatype="html">
+ <source>Profile</source>
+ <target>Profilo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="023d6f718770d2ea4ab8cabe26b0ec27ef967ec2" datatype="html">
+ <source>Used by pools</source>
+ <target>In uso dai pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">387</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1061ba5ee07a5c6af09e09330dbc29201baf2aa" datatype="html">
+ <source>Profile is not in use.</source>
+ <target>Il profilo non è in uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33150f22ce5348aa6c499bd092c3f4f3695d62cc" datatype="html">
+ <source>Crush ruleset</source>
+ <target>Set di regole Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">293</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">303</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c69b0bcd4698aa845d32c4c4ad488492552cb469" datatype="html">
+ <source>A new crush ruleset will be implicitly created.</source>
+ <target>Un nuovo set di regole Crush verrà creato in modo implicito.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="896e9987db5e9bb279e6deed5d2dff28c242ef66" datatype="html">
+ <source>There are no rules.</source>
+ <target>Nessuna regola presente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73a6b31116b3cc322af951daa0bafdc169e6c42e" datatype="html">
+ <source>-- Select a crush rule --</source>
+ <target>-- Selezionare una regola Crush --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7d4894e770f8853050b1f6dd55bdd77a51a8ac6" datatype="html">
+ <source>Placement and
+ replication strategies or distribution policies that allow to
+ specify how CRUSH places data replicas.</source>
+ <target>Le strategie di
+ posizionamento e replica o i criteri di distribuzione che consentono
+ di specificare in che modo CRUSH posiziona le repliche di dati.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">328,330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea91d648f92002bc9f96d9b26b735c83ca0b53c6" datatype="html">
+ <source>This rule can't be deleted as it is in use.</source>
+ <target>Non è possibile eliminare questa regola poiché è in uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">346</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92da80699921e89fb19372e25b8d0f3b9fa427fc" datatype="html">
+ <source>Crush rule</source>
+ <target>Regola Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">365</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5489e9f96835f469f6f728a00d8efa88ea5bc940" datatype="html">
+ <source>Crush steps</source>
+ <target>Passaggi Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc5f5496a9e50fe69e1a09784f28d94944108294" datatype="html">
+ <source>Rule is not in use.</source>
+ <target>La regola non è in uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="104a0e6900d1d1b0c8cf9e5947e36edb352583fc" datatype="html">
+ <source>The rule can't be used in the current cluster as it has too few OSDs to meet the minimum required OSD by this rule.</source>
+ <target>Non è possibile utilizzare la regola nel cluster attuale perché il numero degli OSD che contiene è troppo basso e non soddisfa il numero minimo di OSD richiesto da questa regola.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">409,410</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2208d63d5940ce656006a220102b1eb2b5e553da" datatype="html">
+ <source>Compression</source>
+ <target>Compressione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">420</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c6f25c47da62ec597c6057a36ddfc3209811ec5" datatype="html">
+ <source>Algorithm</source>
+ <target>Algoritmo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">444</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4903231d42089325a28892c0fde1aed46b733ae6" datatype="html">
+ <source>-- No erasure compression algorithm available --</source>
+ <target>-- Nessun algoritmo di compressione della cancellazione disponibile --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d68ddb254275f8f44221e9ad6d8ceeb59ca46a6" datatype="html">
+ <source>Minimum blob size</source>
+ <target>Dimensioni minime del blob</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">468</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb2f176df80647137cbb02bbeb29e5dec707a400" datatype="html">
+ <source>e.g., 128KiB</source>
+ <target>ad es. 128 KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">477</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b7f6e53a4521c6eb3ced4c007fdd4cf80bb7707" datatype="html">
+ <source>Value should be greater than 0</source>
+ <target>Il valore deve essere maggiore di 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">482</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">506</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8db98ab14b4e207ec763dfdefbc2dae367aab1cc" datatype="html">
+ <source>Value should be less than the maximum blob size</source>
+ <target>Il valore deve essere minore delle dimensioni massime del blob</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151efb127a9a4dd25259a0b2055442318a141f5b" datatype="html">
+ <source>Maximum blob size</source>
+ <target>Dimensioni massime del blob</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c656f0e346bbadf46eb1a5d20d0307a3bd20ba8" datatype="html">
+ <source>e.g., 512KiB</source>
+ <target>ad es. 512 KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65a24eee8a026f3b1113fe9e157e9a0dd69486" datatype="html">
+ <source>Value should be greater than the minimum blob size</source>
+ <target>Il valore deve essere maggiore delle dimensioni minime del blob</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">509</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="261ba09c4a59de83f48f52a23fd328da37e61ff4" datatype="html">
+ <source>Ratio</source>
+ <target>Rapporto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">517</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1430457a9c3c66366e51d76bf10396014c576be" datatype="html">
+ <source>Compression ratio</source>
+ <target>Rapporto di compressione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">528</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae5ce6de352cde949998fb10754459c3a4eb183b" datatype="html">
+ <source>Value should be between 0.0 and 1.0</source>
+ <target>Il valore deve essere compreso tra 0,0 e 1,0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d99b34162c9c34f10d0ccd8dbae83d8569c2db77" datatype="html">
+ <source>Max bytes</source>
+ <target>Numero massimo di byte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">546</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1d14a18879c62f3f4ed705318b7164a1160e249" datatype="html">
+ <source>Leave it blank or specify 0 to disable this quota.</source>
+ <target>Lasciare vuoto o inserire 0 per disabilitare questa quota.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">572</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7565b131562ff6c5f769fdbd239a772154abdd97" datatype="html">
+ <source>A valid quota should be greater than 0.</source>
+ <target>Una quota valida deve essere maggiore di 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">550</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">574</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b8bf35b66f09a301eef92ffc3cb2fd259df67ce9" datatype="html">
+ <source>Max objects</source>
+ <target>Numero massimo di oggetti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">570</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="95f348167622d832c5ae532b6944635c8e2ae5cb" datatype="html">
+ <source>The value should be greater or equal to 0</source>
+ <target>Il valore deve essere maggiore di o uguale a 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">586</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1088629182722162774" datatype="html">
+ <source>pool</source>
+ <target>pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6215593782779198370" datatype="html">
+ <source>erasure code profile</source>
+ <target>profilo del codice di cancellazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4390273881304618317" datatype="html">
+ <source>crush rule</source>
+ <target>regola crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">721</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d8a7c8aea58294a3c57c23af0468ddf0ba0c9c7" datatype="html">
+ <source>Pools List</source>
+ <target>Elenco dei pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9055665654201606988" datatype="html">
+ <source>Data Protection</source>
+ <target>Protezione dati</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6658000829978978023" datatype="html">
+ <source>Applications</source>
+ <target>Applicazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5232365108332422324" datatype="html">
+ <source>PG Status</source>
+ <target>Stato gruppo di posizionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1669788723782899084" datatype="html">
+ <source>Crush Ruleset</source>
+ <target>Set di regole Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7961062124768120122" datatype="html">
+ <source>Pool deletion is disabled by the mon_allow_pool_delete configuration setting.</source>
+ <target>L'eliminazione del pool è disabilitata dall'impostazione di configurazione mon_allow_pool_delete.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee5132a8da30e0b7f9f5c70dbc91928d17dd909" datatype="html">
+ <source>Owner</source>
+ <target>Proprietario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c51963a9c553b29427ef783bbb69fa6634fa8c" datatype="html">
+ <source>Index type</source>
+ <target>Tipo di indice</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e6f950a32eaea32ec7e192f9ca3d3dfe469d4ba" datatype="html">
+ <source>Placement rule</source>
+ <target>Regola di posizionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6972d213e31c4ea4f887e60db99d9881bc8fcd3e" datatype="html">
+ <source>Marker</source>
+ <target>Marker</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47b02acd2d3254d1ace1926f840523f154ebef71" datatype="html">
+ <source>Maximum marker</source>
+ <target>Marker massimo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="092fa3a7df9168b14d3f83a77a4035e92b92ce15" datatype="html">
+ <source>Master version</source>
+ <target>Versione master</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97434cc5001d407f90c7447a12d9e8e6848a2aa3" datatype="html">
+ <source>Modification time</source>
+ <target>Ora di modifica</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90fe2e41e7fde38453ce4e619efeea9bc6adea9c" datatype="html">
+ <source>Zonegroup</source>
+ <target>Gruppo di zone</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="efeade5060b3add63863c24871f0830fb16b7e6d" datatype="html">
+ <source>Versioning</source>
+ <target>Controllo versioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62a923f047ca49e7a4782629e91fea1ba32db68f" datatype="html">
+ <source>MFA Delete</source>
+ <target>Eliminazione MFA</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="649a410bd0ace333d067d8fa22f12bdbdb43533b" datatype="html">
+ <source>Bucket quota</source>
+ <target>Quota compartimento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">567</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f50a33d3c339f8f4a465141f8caa5d2d8c005251" datatype="html">
+ <source>Enabled</source>
+ <target>Abilitato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">579</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cef1595d040e77cbb4466e60382028d4c2040cac" datatype="html">
+ <source>Maximum size</source>
+ <target>Dimensioni massime</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa6fb95c355f172bda303de1ce2f38c251a149cf" datatype="html">
+ <source>Unlimited</source>
+ <target>Illimitato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee862a800364b4d11f9b8cb9955a28a60f840a45" datatype="html">
+ <source>Maximum objects</source>
+ <target>Numero massimo di oggetti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b84370895ab9eb44672f57146fa05c5947f1c0c" datatype="html">
+ <source>Locking</source>
+ <target>Blocco</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c3d9d2296f7886e8289b9f623323803deacfc6" datatype="html">
+ <source>Days</source>
+ <target>Giorni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f44bdf9ab00a973bbe482e9fc450e3f67e60c0d" datatype="html">
+ <source>Bucket names can only contain lowercase letters, numbers, periods and hyphens.</source>
+ <target>I nomi dei compartimenti possono contenere solo lettere minuscole, numeri, punti e trattini.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eabb4db920d9f9b2480cf438468b86e1bea02a9b" datatype="html">
+ <source>The chosen name is already in use.</source>
+ <target>Il nome scelto è già in uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b06de7f834c622197e68b66a2abe893040b174c4" datatype="html">
+ <source>Bucket names must not contain uppercase characters or underscores.</source>
+ <target>I nomi dei compartimenti non devono contenere caratteri maiuscoli o caratteri di sottolineatura.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abacf4af2f66d3af08c5ebe502b21b1f42ac649" datatype="html">
+ <source>Each label must start and end with a lowercase letter or a number.</source>
+ <target>Ogni etichetta deve iniziare e terminare con una lettera minuscola o un numero.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a7f52e6813e0535026f61a2d6e8adc8a1d006a" datatype="html">
+ <source>Bucket names cannot be formatted as IP address.</source>
+ <target>I nomi dei compartimenti non possono essere formattati come indirizzi IP.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2a2460396d35e14e7acfb4e060196a0679bdcff" datatype="html">
+ <source>Bucket labels cannot be empty and can only contain lowercase letters, numbers and hyphens.</source>
+ <target>Le etichette dei compartimenti non devono essere vuote e possono contenere solo lettere minuscole, numeri e trattini.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf5c849977e0be2dbfc862d044edd323bfd9fb77" datatype="html">
+ <source>Bucket names must be 3 to 63 characters long.</source>
+ <target>I nomi dei compartimenti devono avere una lunghezza compresa tra 3 e 63 caratteri.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e4c918357c7445fbf19a203e5f0f0ece1960b3b" datatype="html">
+ <source>-- Select a user --</source>
+ <target>-- Selezionare un utente --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4aab1f837bc8ec222e4f25922465d1c5929a1fc" datatype="html">
+ <source>Placement target</source>
+ <target>Destinazione di posizionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bae0a7fc2c9c1fde7d937a8a1a3c7e6825cf7d1" datatype="html">
+ <source>-- Select a placement target --</source>
+ <target>-- Selezionare una destinazione di posizionamento --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="016d24e069e7d505a090fb8243e5cd43b35dc39b" datatype="html">
+ <source>Enables versioning for the objects in the bucket.</source>
+ <target>Abilita il controllo versioni per gli oggetti nel compartimento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">151</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e6775ffd06878aa145c07359f28557f01ede04f" datatype="html">
+ <source>Multi-Factor Authentication</source>
+ <target>Autenticazione a più fattori</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29e8a5d4fb767d4ad0c762c81c6264cec4c0ba97" datatype="html">
+ <source>Delete enabled</source>
+ <target>Eliminazione abilitata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40fbc3ac8c1ea4ecfe62247e91f1f999ad5baf76" datatype="html">
+ <source>Enables MFA (multi-factor authentication) Delete, which requires additional authentication for changing the bucket versioning state.</source>
+ <target>Abilita l'eliminazione dell'autenticazione a più fattori (MFA, Multi-Factor Authentication), che richiede un'ulteriore autenticazione per la modifica dello stato del controllo versioni del compartimento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24c93a8c13db46defa06ed7b5e026a3edb52b91" datatype="html">
+ <source>Token Serial Number</source>
+ <target>Numero di serie token</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6d9536c2af2e5e9a228c3e3e1809dc1fefe0149" datatype="html">
+ <source>Token PIN</source>
+ <target>PIN token</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f038d51ab1645f15b0cd58f195c72a7eeebd4729" datatype="html">
+ <source>Enables locking for the objects in the bucket. Locking can only be enabled while creating a bucket.</source>
+ <target>Abilita il blocco per gli oggetti nel compartimento. La funzione di blocco può essere abilitata soltanto durante la creazione di un compartimento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9af1b4baa2dd8ed2bfc3cc756b12a2271c2dd793" datatype="html">
+ <source>Compliance</source>
+ <target>Conformità</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="edd600fa489d1b4a4448dce694ed932e52ce8fda" datatype="html">
+ <source>Governance</source>
+ <target>Governance</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="218c7d6d318c51e7105309aaeb0baec9d19e4efb" datatype="html">
+ <source>The number of days that you want to specify for the default retention period that will be applied to new objects placed in this bucket.</source>
+ <target>Il numero di giorni che si desidera specificare come periodo di conservazione di default e che verrà applicato ai nuovi oggetti inseriti in questo compartimento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">264</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="289b101ec12427b3ca819df9e43cc3b14fae2cc4" datatype="html">
+ <source>The entered value must be a positive integer.</source>
+ <target>Il valore immesso deve essere un numero intero positivo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48d8247c1ba2ea156109bf286c5f6dd26b4be760" datatype="html">
+ <source>Retention Days must be a positive integer.</source>
+ <target>Il valore dei giorni di conservazione deve essere un numero intero positivo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4349284625269221231" datatype="html">
+ <source>bucket</source>
+ <target>compartimento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6161088322338624846" datatype="html">
+ <source>Updated Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'.</source>
+ <target>Compartimento Object Gateway '<x id="PH" equiv-text="values.bid"/>' aggiornato.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218632328857697292" datatype="html">
+ <source>Created Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'</source>
+ <target>Compartimento Object Gateway '<x id="PH" equiv-text="values.bid"/>' creato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c338bae89822d7eefbc9a887c458a7d8a98e55e" datatype="html">
+ <source>No Limit</source>
+ <target>Nessun limite</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3715596725146409911" datatype="html">
+ <source>Owner</source>
+ <target>Proprietario</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5545511293826600258" datatype="html">
+ <source>Used Capacity</source>
+ <target>Capacità utilizzata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1925090152473969054" datatype="html">
+ <source>Capacity Limit %</source>
+ <target>% limite capacità</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8713861779825116442" datatype="html">
+ <source>Object Limit %</source>
+ <target>% limite oggetto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5913880066213114620" datatype="html">
+ <source>buckets</source>
+ <target>compartimenti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eeba399c4dae8d4890c27b7a2cd2dc28fcf8b5f9" datatype="html">
+ <source>Performance Counters</source>
+ <target>Contatori delle prestazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="479488ab6e91ecb375484edc78bee3d13467f33f" datatype="html">
+ <source>Daemons List</source>
+ <target>Elenco dei daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca2dee83bb58290d93fb0d17ee8bc9f095a4576f" datatype="html">
+ <source>Sync Performance</source>
+ <target>Sincronizza prestazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4378147649219625174" datatype="html">
+ <source>Zone</source>
+ <target>Zona</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6148052126949932311" datatype="html">
+ <source>Zone Group</source>
+ <target>Gruppo di zone</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3840481991104643295" datatype="html">
+ <source>Realm</source>
+ <target>Area di autenticazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1221ca97d19eaa9a7bc0c5243d5fc5befe1d2314" datatype="html">
+ <source>-- Select a type --</source>
+ <target>-- Selezionare un tipo --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1b8990332af18f1c5159a6061ca889bcbb28432" datatype="html">
+ <source>Permission</source>
+ <target>Autorizzazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a08c589f82f69d892307288da14190ae1dd583d5" datatype="html">
+ <source>-- Select a permission --</source>
+ <target>-- Selezionare un'autorizzazione --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7345972049922682356" datatype="html">
+ <source>capability</source>
+ <target>funzionalità</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a94e6b2b5b834d92cceb90037d51ad6165c8b619" datatype="html">
+ <source>Tenant</source>
+ <target>Tenant</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
+ <source>User ID</source>
+ <target>ID utente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b760f123248930122fc7e7b6b6bf94e376e959c8" datatype="html">
+ <source>Full name</source>
+ <target>Nome completo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69b6ac577a19acc39fc0c22342092f327fff2529" datatype="html">
+ <source>Email address</source>
+ <target>Indirizzo e-mail</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92f3f203270a29b3001871153f02c063484a1574" datatype="html">
+ <source>Suspended</source>
+ <target>Sospeso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011e20c5bbe51602d459a860fbf29b599b55edd" datatype="html">
+ <source>System</source>
+ <target>Sistema</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db18a2772988415466a7f75dc42663ce78c9c1d3" datatype="html">
+ <source>Maximum buckets</source>
+ <target>Numero massimo di compartimenti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c4c62e8ba24601be5cfe7dc5d32c24bbbd4b53c" datatype="html">
+ <source>Subusers</source>
+ <target>Sottoutenti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17bb3082e6fe5003203ef992a3714172334631a1" datatype="html">
+ <source>Capabilities</source>
+ <target>Funzionalità</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32f8a0570373cacb9c56cf227502483a29d605bc" datatype="html">
+ <source>MFAs(Id)</source>
+ <target>MFA (ID)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36ad38f9c1a1485e09b67778a28af84553290ffb" datatype="html">
+ <source>User quota</source>
+ <target>Quota utente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">473</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0bcd5ef19af0f1b814141ca8c57df623d8270088" datatype="html">
+ <source>Keys</source>
+ <target>Chiavi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2aba1e87039819aca3b70faa9aa848c12bf139ca" datatype="html">
+ <source>Show</source>
+ <target>Mostra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">395</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5248717555542428023" datatype="html">
+ <source>Username</source>
+ <target>Nome utente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240806681889331244" datatype="html">
+ <source>Unlimited</source>
+ <target>Illimitato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db4e1a734518691b128ef40b939cc673f01d03a6" datatype="html">
+ <source>The value is not valid.</source>
+ <target>Il valore non è valido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">617</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6aaf5d2a304167272ac73e3b1d1c162e16c77858" datatype="html">
+ <source>The chosen user ID is already in use.</source>
+ <target>L'ID utente scelto è già in uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="025be1d01b2f6cbd09e772a1d3de02fab0678b26" datatype="html">
+ <source>Show Tenant</source>
+ <target>Mostra tenant</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6af106b0d759fd2882e645604675c4494abfcd5b" datatype="html">
+ <source>The chosen user ID exists in this tenant.</source>
+ <target>L'ID utente scelto esiste in questo tenant.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="df441e80db2157f9d272b75de724ba4a82b96b57" datatype="html">
+ <source>This is not a valid email address.</source>
+ <target>Non è un indirizzo e-mail valido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca271adf154956b8fcb28f4f50a37acb3057ff7c" datatype="html">
+ <source>The chosen email address is already in use.</source>
+ <target>L'indirizzo e-mail scelto è già in uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="030197cebe938edf35422e92fe14183d06eb670b" datatype="html">
+ <source>Max. buckets</source>
+ <target>Numero massimo di compartimenti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f39256070bfc0714020dfee08895421fc1527014" datatype="html">
+ <source>Disabled</source>
+ <target>Disabilitato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c05002b0ac2040f1aede5e727e0ffd06eda819" datatype="html">
+ <source>Custom</source>
+ <target>Personalizzato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28872515cb81d197a3a1733fa546d3e0f0dd6c67" datatype="html">
+ <source>The entered value must be &gt;= 1.</source>
+ <target>Il valore immesso deve essere &gt;=1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="583a219c524155c2314eb06ee29162bb315272a3" datatype="html">
+ <source>S3 key</source>
+ <target>Chiave S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c217ee914725a37e9dd2336c721c8e63e9666bdc" datatype="html">
+ <source>Auto-generate key</source>
+ <target>Generazione automatica chiave</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f1c1c0f2bce4c9f92d1a2061e8161cb0006c31a" datatype="html">
+ <source>Access key</source>
+ <target>Chiave di accesso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b864acb67296a9819c1db0069c4c47d8b5ce8f44" datatype="html">
+ <source>Secret key</source>
+ <target>Chiave segreta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="128d6efb51d9ddc7c0cc695a2deeca5b9523f6e4" datatype="html">
+ <source>There are no subusers.</source>
+ <target>Nessun sottoutente esistente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fd6dfb8ecb982dbc3affb2c2d5414c4f5b6abd2" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">294,295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67c746c1ba9dab4351fedc4c7cba4e6d6b0dbc47" datatype="html">
+ <source>S3</source>
+ <target>S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d6819038d608623503918fb2553f53d68231ec3a" datatype="html">
+ <source>There are no keys.</source>
+ <target>Nessuna chiave esistente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">377</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc1c1a7140ff6b815a95b65ee2780fdbe1b2b7a1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">356,357</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6ddb5e991a3ecd2659fb520bc5acc81b67e08ddd" datatype="html">
+ <source>Swift</source>
+ <target>Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">371</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d01eccdda47fc907c5be35bcb16d2dcd02b0270" datatype="html">
+ <source>There are no capabilities.</source>
+ <target>Nessuna funzionalità esistente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5a451c4ea65a4046f0b49d489a7013abf0b5861" datatype="html">
+ <source>All capabilities are already added.</source>
+ <target>Tutte le funzionalità sono già state aggiunte.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">456</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="043e2ec0036ceadd926fd5e3f93cd6f3565f3648" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">461,462</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6146e13ceca5fa5cc17b771b282fe5955f3d19fa" datatype="html">
+ <source>Unlimited size</source>
+ <target>Dimensioni illimitate</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">595</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6db8aa7c99fdce18edb33dde57729acede2b308" datatype="html">
+ <source>Max. size</source>
+ <target>Dimensioni massime</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">511</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">605</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc630b2093e880fffa19df99d5cd8b87605037f8" datatype="html">
+ <source>Unlimited objects</source>
+ <target>Oggetti illimitati</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cda5a993d06f0bb10048be9d3aba6555aa9f356" datatype="html">
+ <source>Max. objects</source>
+ <target>Numero massimo di oggetti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">642</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="623ac50f37a26caec6fd7cd519b653e3315cba25" datatype="html">
+ <source>The entered value must be &gt;= 0.</source>
+ <target>Il valore immesso deve essere &gt;=0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">654</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="123010868147850959" datatype="html">
+ <source>user</source>
+ <target>utente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8368421344177343441" datatype="html">
+ <source>subuser</source>
+ <target>sottoutente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4662015204945271252" datatype="html">
+ <source>S3 Key</source>
+ <target>Chiave S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9103468069826049692" datatype="html">
+ <source>Updated Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <target>Utente Object Gateway '<x id="PH" equiv-text="uid"/>' aggiornato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="884841609901737584" datatype="html">
+ <source>Created Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <target>Utente Object Gateway '<x id="PH" equiv-text="uid"/>' creato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4363143805416924501" datatype="html">
+ <source>Tenant</source>
+ <target>Tenant</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8301535046747035390" datatype="html">
+ <source>Full name</source>
+ <target>Nome completo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3967269098753656610" datatype="html">
+ <source>Email address</source>
+ <target>Indirizzo e-mail</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5851424994801012357" datatype="html">
+ <source>Suspended</source>
+ <target>Sospeso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208300173682032371" datatype="html">
+ <source>Max. buckets</source>
+ <target>Numero massimo di compartimenti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1670306451865226564" datatype="html">
+ <source>users</source>
+ <target>utenti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c614babd1950adb2be75df4e2c9747286d6adc" datatype="html">
+ <source>-- Select a username --</source>
+ <target>-- Selezionare un nome utente --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2841767821d6b66238c34d07e413b0af67aee92" datatype="html">
+ <source>Subuser</source>
+ <target>Sottoutente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd59fc25a7bd98cff3e75117c09697c8a007a514" datatype="html">
+ <source>The chosen subuser ID is already in use.</source>
+ <target>L'ID del sottoutente scelto è già in uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d386c357ebcbc04ed05c4babd5a03626f9b1674" datatype="html">
+ <source>read, write</source>
+ <target>lettura, scrittura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84e3e3f9a4f31a039b648c97debf95fcb20f4c4a" datatype="html">
+ <source>full</source>
+ <target>pieno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6bf81d032a2316464f9df2f0d2f3d753f89f0d3" datatype="html">
+ <source>Swift key</source>
+ <target>Chiave Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e0c12685d50d47448ceed9423977ef39775c037" datatype="html">
+ <source>Auto-generate secret</source>
+ <target>Generazione automatica segreto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5091031285775138345" datatype="html">
+ <source>Subuser</source>
+ <target>Sottoutente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8453697749389230205" datatype="html">
+ <source>Swift Key</source>
+ <target>Chiave Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ac54c18c1b520e948095c83a3a1025f02ce6dcc6" datatype="html">
+ <source>Neither hostname nor OSD ID given</source>
+ <target>Nome host o ID OSD non forniti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4533150758393178756" datatype="html">
+ <source>Device ID</source>
+ <target>ID dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1291053608320944146" datatype="html">
+ <source>State of Health</source>
+ <target>Stato di integrità</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29167121133682512" datatype="html">
+ <source>Good</source>
+ <target>Buono</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8767957606064036733" datatype="html">
+ <source>Bad</source>
+ <target>Cattivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8052456228079338924" datatype="html">
+ <source>Stale</source>
+ <target>Non aggiornato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6223439643831041743" datatype="html">
+ <source>Life Expectancy</source>
+ <target>Aspettativa di vita</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3144481541623761279" datatype="html">
+ <source>Prediction Creation Date</source>
+ <target>Data di creazione stimata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="264574868375698540" datatype="html">
+ <source>Device Name</source>
+ <target>Nome dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1419569261746199221" datatype="html">
+ <source>Daemons</source>
+ <target>Daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f635b3cb0600409a2ad44a5bd1863c699e6a01c" datatype="html">
+ <source>Failed to retrieve SMART data.</source>
+ <target>Non è stato possibile recuperare i dati SMART.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a8a3f354bd640299068edd912f4bb5325264f250" datatype="html">
+ <source>The data received has the JSON format version 2.x and is currently incompatible with the dashboard.</source>
+ <target>I dati ricevuti sono in formato JSON versione 2.x, che al momento la dashboard non supporta.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="04f8a3c7e8ac610e6581960162cc15f55a16696a" datatype="html">
+ <source>No SMART data available.</source>
+ <target>Nessun dato SMART disponibile.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a185c9b97513b3882604ea9bab60edbfac945c15" datatype="html">
+ <source>SMART overall-health self-assessment test result</source>
+ <target>Risultato test di autovalutazione dell'integrità generale SMART</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="290e4c9ad42dc6e9176656c864a5faed8053f406" datatype="html">
+ <source>unknown</source>
+ <target>sconosciuto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a03d3c2e459f8f8fa7202c0fce465d6165f9e2b" datatype="html">
+ <source>passed</source>
+ <target>superato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41435d5a5692c8e412c74deaee95d99dbd3617e1" datatype="html">
+ <source>failed</source>
+ <target>non superato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddd5dd6d930030096ea617f62c82b648a0dd9484" datatype="html">
+ <source>Device Information</source>
+ <target>Informazioni dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e149c483d88cfcff11d1c5db85e84af7c3149c4" datatype="html">
+ <source>No device information available for this device.</source>
+ <target>Informazioni dispositivo non disponibili per questo dispositivo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20cb12827cbe559a7b1da6fdae96041b3b5c3c55" datatype="html">
+ <source>SMART</source>
+ <target>SMART</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380295f37caea93701d071485a38ef0bdba57133" datatype="html">
+ <source>No SMART data available for this device.</source>
+ <target>Dati SMART non disponibili per questo dispositivo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5758c3f16f8749f0f4e2a787f02e8b4da246102f" datatype="html">
+ <source>SMART data is loading.</source>
+ <target>Caricamento dati SMART in corso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5363861031080361352" datatype="html">
+ <source>Smartctl has received an unknown argument (error code <x id="PH" equiv-text="smartData.smartctl_error_code"/>). You may be using an incompatible version of smartmontools. Version &gt;= 7.0 of smartmontools is required to successfully retrieve data.</source>
+ <target>Smartctl ha ricevuto un argomento sconosciuto (codice di errore <x id="PH" equiv-text="smartData.smartctl_error_code"/>). La versione di smartmontools in uso potrebbe non essere compatibile. Per recuperare i dati correttamente, è necessaria la versione &amp;gt;= 7.0 di smartmontools.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">61,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5085718566932809950" datatype="html">
+ <source>An error with error code <x id="PH" equiv-text="smartData.smartctl_error_code"/> occurred.</source>
+ <target>Si è verificato un errore con codice di errore <x id="PH" equiv-text="smartData.smartctl_error_code"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2091295268977103253" datatype="html">
+ <source>Raw</source>
+ <target>Non elaborato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5963653123239768443" datatype="html">
+ <source>Threshold</source>
+ <target>Soglia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2893124970059125090" datatype="html">
+ <source>When Failed</source>
+ <target>In caso di errore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5614367840516299633" datatype="html">
+ <source>Worst</source>
+ <target>Peggiore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d06ae77f9ec46a4cdd49e7e76c73a411aaf2ee38" datatype="html">
+ <source>Please set a new password.</source>
+ <target>Impostare una nuova password.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8b5b3566e88438f51bd5f6caf6c090ed565ba5ed" datatype="html">
+ <source>You will be redirected to the login page afterwards.</source>
+ <target>Si verrà poi reindirizzati alla pagina di login.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cf42e491adc166a337a960eb84d03c0c3f677c8" datatype="html">
+ <source>The old and new passwords must be different.</source>
+ <target>La vecchia e la nuova password devono essere diverse.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90163a3d3746819aef42e829f4446331232f3b66" datatype="html">
+ <source>Password confirmation doesn't match the new password.</source>
+ <target>La password di conferma non corrisponde alla nuova password.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0070e83d11da39d6f4bb95065c2675db1610b419" datatype="html">
+ <source>Username is required</source>
+ <target>Il nome utente è obbligatorio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e20f8b8a4706526c9024cc2f39d568345d100dc" datatype="html">
+ <source>Password is required</source>
+ <target>La password è obbligatoria</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f093d9574ab746b231504bd2cbb65f04bd7b00db" datatype="html">
+ <source>Log in</source>
+ <target>Accedi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5590086849807274701" datatype="html">
+ <source>Scope</source>
+ <target>Ambito</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327592562693301723" datatype="html">
+ <source>Read</source>
+ <target>Lettura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5674286808255988565" datatype="html">
+ <source>Create</source>
+ <target>Crea</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4021752662928002901" datatype="html">
+ <source>Update</source>
+ <target>Aggiorna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022070615528435141" datatype="html">
+ <source>Delete</source>
+ <target>Elimina</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ea5c4d8942c00752dcc72e72949c5d9832f6399" datatype="html">
+ <source>Description...</source>
+ <target>Descrizione...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70f45880fce6ac5d8e468e25e82aefbba8098cfe" datatype="html">
+ <source>Permissions</source>
+ <target>Autorizzazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="122114774689391224" datatype="html">
+ <source>role</source>
+ <target>ruolo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616102757855967475" datatype="html">
+ <source>All</source>
+ <target>tutti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4416727401284087008" datatype="html">
+ <source>Created role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <target>Ruolo '<x id="PH" equiv-text="roleFormModel.name"/>' creato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3472946357042916911" datatype="html">
+ <source>Updated role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <target>Ruolo '<x id="PH" equiv-text="roleFormModel.name"/>' aggiornato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="373024661645814027" datatype="html">
+ <source>System Role</source>
+ <target>Ruolo di sistema</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753648234171918096" datatype="html">
+ <source>Deleted role '<x id="PH" equiv-text="role"/>'</source>
+ <target>Ruolo '<x id="PH" equiv-text="role"/>' eliminato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1674202514578558795" datatype="html">
+ <source>New name</source>
+ <target>Nuovo nome</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4857700187193019038" datatype="html">
+ <source>Clone Role</source>
+ <target>Clona ruolo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="748631939386170157" datatype="html">
+ <source>Cloned role '<x id="PH" equiv-text="values['newName']"/>' from '<x id="PH_1" equiv-text="name"/>'</source>
+ <target>Ruolo '<x id="PH" equiv-text="values['newName']"/>' clonato da '<x id="PH_1" equiv-text="name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="195c31a2f970e790231a6bb94a5e8ca0167406d9" datatype="html">
+ <source>The username already exists.</source>
+ <target>Nome utente già esistente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f3bdcce4b2e8c37cd7f0f6c92ef8cff34b039b8" datatype="html">
+ <source>Confirm password</source>
+ <target>Conferma password</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cbb979e63ba50e0ca3adfa09cbdcaefd0853fca1" datatype="html">
+ <source>Password confirmation doesn't match the password.</source>
+ <target>La password di conferma non corrisponde alla password.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="96621f9ed2e4ae5204564e583d2c816bedead571" datatype="html">
+ <source>Password expiration date</source>
+ <target>Data di scadenza password</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48932db3801fe9d5d72a60a3e656bffd17c1c5d9" datatype="html">
+ <source>Password expiration date...</source>
+ <target>Data di scadenza password...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc" datatype="html">
+ <source>Email</source>
+ <target>E-mail</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d0ec081dd61eb4f43aea269077bbe38eae87b7f9" datatype="html">
+ <source>Invalid email.</source>
+ <target>E-mail non valida.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9610487cbeb5796d34d8601b5ac0c0a65f9e1d19" datatype="html">
+ <source>Roles</source>
+ <target>Ruoli</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8913c216dd506e20e412e144381d8d2a65a84359" datatype="html">
+ <source>User must change password at next logon</source>
+ <target>L'utente deve modificare la password al prossimo accesso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0051a3479d3ba79135c16dc8cc017950a2cce821" datatype="html">
+ <source>You are about to remove &quot;user read / update&quot; permissions from your own user.</source>
+ <target>Si stanno per rimuovere le autorizzazioni di &quot;lettura/aggiornamento utente&quot; dal proprio utente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af4bf9fcb256853f14cf947eb1deb8d7f176d3f9" datatype="html">
+ <source>If you continue, you will no longer be able to add or remove roles from any user.</source>
+ <target>Se si continua, non sarà più possibile aggiungere o rimuovere ruoli da qualsiasi utente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314291969883771319" datatype="html">
+ <source>There are no roles.</source>
+ <target>Nessun ruolo presente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4306072924538089180" datatype="html">
+ <source>Created user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <target>Utente '<x id="PH" equiv-text="userFormModel.username"/>' creato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1349763489797682899" datatype="html">
+ <source>Update user</source>
+ <target>Aggiorna utente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8688396456017237992" datatype="html">
+ <source>You were automatically logged out because your roles have been changed.</source>
+ <target>Si è stati automaticamente disconnessi perché i ruoli sono stati modificati.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2335813072344088607" datatype="html">
+ <source>Updated user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <target>Utente '<x id="PH" equiv-text="userFormModel.username"/>' aggiornato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4768749765465246664" datatype="html">
+ <source>Email</source>
+ <target>E-mail</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795890916060309463" datatype="html">
+ <source>Roles</source>
+ <target>Ruoli</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6877445485286599988" datatype="html">
+ <source>Password expiration date</source>
+ <target>Data di scadenza password</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="705657168061753072" datatype="html">
+ <source>Deleted user '<x id="PH" equiv-text="username"/>'</source>
+ <target>Utente '<x id="PH" equiv-text="username"/>' eliminato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="405819296611088743" datatype="html">
+ <source>Failed to delete user '<x id="PH" equiv-text="username"/>'</source>
+ <target>Impossibile creare l'utente '<x id="PH" equiv-text="username"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8935387756949610047" datatype="html">
+ <source>You are currently logged in as '<x id="PH" equiv-text="username"/>'.</source>
+ <target>Si è attualmente connessi come '<x id="PH" equiv-text="username"/>'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0eb15f32b2b92d7f3103ef3ff032621888a8dc32" datatype="html">
+ <source>Old password</source>
+ <target>Vecchia password</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229" datatype="html">
+ <source>New password</source>
+ <target>Nuova password</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ede41f01c781b168a783cfcefc6fb67d48780d9b" datatype="html">
+ <source>Confirm new password</source>
+ <target>Conferma nuova password</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809196861118879526" datatype="html">
+ <source>password</source>
+ <target>password</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623124197136601291" datatype="html">
+ <source>Updated user password&quot;</source>
+ <target>Password utente aggiornata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be" datatype="html">
+ <source>Users</source>
+ <target>Utenti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ced3246fa3db31be0f7da06648463f29ba378fbe" datatype="html">
+ <source>Selected Object Gateway:</source>
+ <target>Object Gateway selezionato:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c53062af97ebda2a03f905698f58e524ecf8b968" datatype="html">
+ <source>Select Object Gateway</source>
+ <target>Seleziona Object Gateway</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="235c355afdcbf72953a15d7fc8d0d9e7a6619f46" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Page not Found<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Pagina non trovata<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aee9d027170f84774f2980537556f5099369b82" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for. The page you requested may have been changed or moved.</source>
+ <target>Non è stato possibile trovare l'elemento cercato. La pagina richiesta potrebbe essere stata modificata o spostata.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">22,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2b46fe9a975c6531af77fee858ccd37327980f7" datatype="html">
+ <source>Please consult the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>documentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> on how to configure and enable the <x id="INTERPOLATION" equiv-text="{{ section_info }}"/> management functionality.</source>
+ <target>Consultare la <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>documentazione<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> su come configurare e abilitare la funzionalità di gestione di <x id="INTERPOLATION" equiv-text="{{ section_info }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">26,27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9d57ca7cab78c6f0d27e0d890cb8cf1515e4e30a" datatype="html">
+ <source>Go To Dashboard</source>
+ <target>Passa al dashboard</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6578397717654172779" datatype="html">
+ <source>Page Not Found</source>
+ <target>Pagina non trovata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8185335715884155108" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for.
+ The page you requested may have been changed or moved.</source>
+ <target>Non è stato possibile trovare l'elemento cercato.
+ La pagina richiesta potrebbe essere stata modificata o spostata.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="143318366100741906" datatype="html">
+ <source>Access Denied</source>
+ <target>Accesso negato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5384670299771400832" datatype="html">
+ <source>Sorry, you don’t have permission to view this page or resource.</source>
+ <target>Non si dispone dell'autorizzazione per visualizzare questa pagina o risorsa.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2424411274809083521" datatype="html">
+ <source>User Denied</source>
+ <target>Utente negato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7645004872908092358" datatype="html">
+ <source>Sorry, the user does not exist in Ceph.
+ You'll be logged out from the Identity Provider when you retry logging in.</source>
+ <target>L'utente non esiste in Ceph.
+ Si viene disconnessi dal provider di identità quando si riprova a eseguire il login..</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">24,25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f286db6ac9482dbf567bc491d49a6eade444895a" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7911416166208830577" datatype="html">
+ <source>Help</source>
+ <target>Guida</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8878700331247603166" datatype="html">
+ <source>Security</source>
+ <target>Sicurezza</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8642696205489749843" datatype="html">
+ <source>Trademarks</source>
+ <target>Marchi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1481ecd21e760ac919a24e26cf790acd82e40199" datatype="html">
+ <source>Dashboard Settings</source>
+ <target>Impostazioni del dashboard</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a79aab4ef674bf3f6532292107c0054302236e0f" datatype="html">
+ <source>User management</source>
+ <target>Gestione utenti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="197e0246502ca64d0de0df0d5c2deec51d41ff45" datatype="html">
+ <source>Telemetry configuration</source>
+ <target>Configurazione telemetria</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85b79c9064aed1ead31ace985f31aa1363f6bdaf" datatype="html">
+ <source>Help</source>
+ <target>Guida</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06638e0f01d82c0786f63aa9832fbe7866b86087" datatype="html">
+ <source>documentation</source>
+ <target>documentazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e351b40b3869a5c7d19c3d4918cb1ac7aaab95c4" datatype="html">
+ <source>API</source>
+ <target>API</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a" datatype="html">
+ <source>About</source>
+ <target>Informazioni su</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="049dfd9fe6c78914ad58cf89ac6a631fca28ec74" datatype="html">
+ <source>Logged in user</source>
+ <target>Utente connesso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5022c5ae3ae921c07bf5f881e9b026b4a6708a7" datatype="html">
+ <source>Signed in as <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>Connesso come <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9" datatype="html">
+ <source>Change password</source>
+ <target>Modifica password</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d22c795daf43877a5f708dca2bccd549eb0471d" datatype="html">
+ <source>Sign out</source>
+ <target>Disconnetti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319e0745bcbc132451569294fa2fa21bf10f555a" datatype="html">
+ <source>Toggle navigation</source>
+ <target>Attiva/Disattiva barra di navigazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f65253954b66e929a8b4d5ecaf61f9129f8cec64" datatype="html">
+ <source>Dashboard</source>
+ <target>Dashboard</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c95898abff46bfac3ed6eb2afef74597e60b15c" datatype="html">
+ <source>CRUSH map</source>
+ <target>Mappa CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7b2bc4b86de6e96d353f6bf2b4d793ea3a19ba0" datatype="html">
+ <source>Manager Modules</source>
+ <target>Moduli Manager</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb3d5aefff38a814b76da74371cbf02c0789a1ef" datatype="html">
+ <source>Logs</source>
+ <target>Log</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17fc3efe5f9fa4e0289c900cb6202265215a1a27" datatype="html">
+ <source>Monitoring</source>
+ <target>Monitoraggio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f5d0c10614e8a34f0e2dad33a0568277c50cf69" datatype="html">
+ <source>Block</source>
+ <target>Blocco</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3c2562ba992127203dcfd014010b03cb7b8113c6" datatype="html">
+ <source>Mirroring</source>
+ <target>Esecuzione di copia speculare</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="811c241d56601b91ef26735b770e64428089b950" datatype="html">
+ <source>iSCSI</source>
+ <target>iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a24eabd99ea5af20f5f94c4484649cd30370042b" datatype="html">
+ <source>NFS</source>
+ <target>NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5276fc60d54d667116babb723641b21281d37271" datatype="html">
+ <source>File Systems</source>
+ <target>File system</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9515520496da83179d8b08132f00f575512a1f40" datatype="html">
+ <source>Buckets</source>
+ <target>Compartimenti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a23e992f6c6e169a38b2b7338b4e5e803b52e0d" datatype="html">
+ <source>Tasks and Notifications</source>
+ <target>Task e notifiche</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1390461972315002349" datatype="html">
+ <source>The name of the node under which data should be placed.</source>
+ <target>Il nome del nodo in cui posizionare i dati.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6575341202068728510" datatype="html">
+ <source>The type of CRUSH nodes across which we should separate replicas.</source>
+ <target>Il tipo di nodi CRUSH su cui separare le repliche.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3874278445824365480" datatype="html">
+ <source>The device class data should be placed on.</source>
+ <target>Il dispositivo su cui posizionare i dati di classe.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="675628105428950215" datatype="html">
+ <source>Each object is split in data-chunks parts, each stored on a different OSD.</source>
+ <target>Ogni oggetto è suddiviso in porzioni di dati, ciascuna delle quali è memorizzata su un diverso OSD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5128168460056151476" datatype="html">
+ <source>Compute coding chunks for each object and store them on different OSDs.
+ The number of coding chunks is also the number of OSDs that can be down without losing data.</source>
+ <target>Calcola le porzioni di codice relative a ciascun oggetto e le memorizza su diversi OSD.
+ Il numero di porzioni di codice è anche il numero degli OSD che è possibile declassare senza perdere i dati.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">18,19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8826111293169381132" datatype="html">
+ <source>The jerasure plugin is the most generic and flexible plugin,
+ it is also the default for Ceph erasure coded pools.</source>
+ <target>Il plug-in jerasure è il plug-in più generico e flessibile,
+ ed è anche il plug-in di default dei pool con codice di cancellazione di Ceph.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">23,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1331133460856304156" datatype="html">
+ <source>The more flexible technique is reed_sol_van : it is enough to set k
+ and m. The cauchy_good technique can be faster but you need to chose the packetsize
+ carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents
+ in the sense that they can only be configured with m=2.</source>
+ <target>La tecnica più flessibile è reed_sol_van: è sufficiente impostare k
+ e m. La tecnica cauchy_good può essere più rapida, ma occorre selezionare attentamente le dimensioni del
+ pacchetto. reed_sol_r6_op, liberation, blaum_roth, liber8tion sono tutti equivalenti a RAID6,
+ nel senso che è possibile configurarli solo con m=2.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">25,28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4577912952562931806" datatype="html">
+ <source>The encoding will be done on packets of bytes size at a time.
+ Choosing the right packet size is difficult.
+ The jerasure documentation contains extensive information on this topic.</source>
+ <target>La codifica viene eseguita su pacchetti di dimensioni in byte, uno alla volta.
+ È difficile scegliere le dimensioni del pacchetto corrette.
+ La documentazione su jerasure fornisce informazioni esaustive su questo argomento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">29,31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6471646852539810855" datatype="html">
+ <source>With the jerasure plugin, when an erasure coded object is stored on
+ multiple OSDs, recovering from the loss of one OSD requires reading from all the others.
+ For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading
+ from the eleven others to repair.
+
+ The lrc erasure code plugin creates local parity chunks to be able to recover using
+ less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create
+ an additional parity chunk for every four OSDs. When a single OSD is lost, it can be
+ recovered with only four OSDs instead of eleven.</source>
+ <target>Con il plug-in di jerasure, quando un oggetto con codice di cancellazione viene memorizzato su
+ più OSD, il recupero dalla perdita di un OSD richiede la lettura di tutti gli altri.
+ Ad esempio, se jerasure è configurato con k=8 e m=4, la perdita di un OSD richiede la lettura
+ degli altri undici per il ripristino.
+
+ Il plug-in del codice di cancellazione lrc crea porzioni di parità locali per poter eseguire il recupero utilizzando un
+ minor numero di OSD. Ad esempio, se lrc è configurato con k=8, m=4 e l=4, crea
+ una porzione di parità aggiuntiva ogni quattro OSD. Quando si perde un singolo OSD, è possibile
+ recuperarlo solo con quattro OSD invece che con undici.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">34,42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2619235086723330982" datatype="html">
+ <source>Group the coding and data chunks into sets of size locality. For instance,
+ for k=4 and m=2, when locality=3 two groups of three are created. Each set can
+ be recovered without reading chunks from another set.</source>
+ <target>Raggruppa le porzioni di codice e dati in set di località dimensione. Ad esempio,
+ per k=4 e m=2, se località=3 vengono creati due gruppi su tre. È possibile recuperare ciascun set
+ senza leggere le porzioni di un altro set.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">43,45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3298836762557512588" datatype="html">
+ <source>The type of the crush bucket in which each set of chunks defined
+ by l will be stored. For instance, if it is set to rack, each group of l chunks will be
+ placed in a different rack. It is used to create a CRUSH rule step such as step choose
+ rack. If it is not set, no such grouping is done.</source>
+ <target>Il tipo di compartimento Crush in cui viene memorizzato ciascun set di porzioni definito
+ dall'utente. Ad esempio, se è impostato su rack, ciascun gruppo di porzioni viene
+ posizionato in un diverso rack. Viene utilizzato per creare un passaggio della regola CRUSH, come il passaggio choose
+ rack. Se non è impostato, il raggruppamento non viene eseguito.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">46,49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9162461669419243962" datatype="html">
+ <source>The isa plugin encapsulates the ISA library. It only runs on Intel processors.</source>
+ <target>Il plug-in ISA incapsula la libreria ISA. Viene eseguito solo su processori Intel.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2389282202903059852" datatype="html">
+ <source>The ISA plugin comes in two Reed Solomon forms.
+ If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.</source>
+ <target>Il plug-in ISA è disponibile in due formati Reed Solomon.
+ Se è impostato reed_sol_van, il formato è Vandermonde, se è impostato cauchy, il formato è Cauchy.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">53,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7319555444402547739" datatype="html">
+ <source>The shec plugin encapsulates the multiple SHEC library.
+ It allows ceph to recover data more efficiently than Reed Solomon codes.</source>
+ <target>Il plug-in shec incapsula la libreria SHEC multipla.
+ Consente a Ceph di recuperare i dati in modo più efficiente rispetto ai codici Reed Solomon.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">57,58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7723217930035575928" datatype="html">
+ <source>The number of parity chunks each of which includes each data chunk in its
+ calculation range. The number is used as a durability estimator. For instance, if c=2,
+ 2 OSDs can be down without losing data.</source>
+ <target>Il numero di porzioni di parità, ciascuna delle quali include le singole porzioni di dati
+ nell'intervallo di calcolo. Il numero viene utilizzato come strumento di stima della durata. Ad esempio, se c=2,
+ è possibile disattivare 2 OSD senza perdere i dati.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">59,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2054101840892270818" datatype="html">
+ <source>CLAY (short for coupled-layer) codes are erasure codes designed to
+ bring about significant savings in terms of network bandwidth and disk IO when a failed
+ node/OSD/rack is being repaired.</source>
+ <target>I codici CLAY (abbreviazione di Coupled-Layer, strati associati) sono codici di cancellazione progettati per
+ consentire notevoli risparmi in termini di larghezza di banda di rete e I/O su disco in caso di
+ riparazione di un nodo/OSD/rack con errori.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">64,66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491096236680229427" datatype="html">
+ <source>Number of OSDs requested to send data during recovery of a single chunk.
+ d needs to be chosen such that k+1 &lt;= d &lt;= k+m-1. The larger the d, the better
+ the savings.</source>
+ <target>Numero di OSD richiesto per l'invio dei dati durante il recupero di una singola porzione.
+ Occorre scegliere per d un valore equivalente a k+1 &lt;= d &lt;= k+m-1. Maggiore è il valore di d, maggiori
+ saranno i risparmi.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">67,69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2625895656705896729" datatype="html">
+ <source>scalar_mds specifies the plugin that is used as a building block
+ in the layered construction. It can be one of jerasure, isa, shec.</source>
+ <target>scalar_mds consente di specificare il plug-in utilizzato come blocco predefinito
+ nella struttura a strati. Può essere uno tra jerasure, isa, shec.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">70,71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6639141182731628232" datatype="html">
+ <source>technique specifies the technique that will be picked
+ within the 'scalar_mds' plugin specified. Supported techniques
+ are 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good', 'liber8tion' for jerasure, 'reed_sol_van',
+ 'cauchy' for isa and 'single', 'multiple' for shec.</source>
+ <target>technique consente di specificare la tecnica scelta
+ all'interno del plug-in 'scalar_mds' specificato. Le tecniche supportate
+ sono 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good', 'liber8tion' per jerasure, 'reed_sol_van',
+ 'cauchy' per isa e 'single', 'multiple' per shec.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">72,76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8172892264673403098" datatype="html">
+ <source>The name of the crush bucket used for the first step of the CRUSH rule.
+ For instance step take default.</source>
+ <target>Il nome del compartimento Crush utilizzato per il primo passaggio della regola CRUSH.
+ Ad esempio il passaggio take default.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">80,81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1654284403437084515" datatype="html">
+ <source>Ensure that no two chunks are in a bucket with the same failure
+ domain. For instance, if the failure domain is host no two chunks will be stored on the same
+ host. It is used to create a CRUSH rule step such as step chooseleaf host.</source>
+ <target>Assicurarsi che non esistano due porzioni in un compartimento con lo stesso dominio
+ di errore. Ad esempio, se il dominio di errore è l'host, non verranno memorizzate due porzioni sullo stesso
+ host. Viene utilizzato per creare un passaggio della regola CRUSH, come il passaggio chooseleaf host.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">83,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7737703816676512224" datatype="html">
+ <source>Restrict placement to devices of a specific class
+ (e.g., ssd or hdd), using the crush device class names in the CRUSH map.</source>
+ <target>Limitare il posizionamento ai dispositivi di una classe specifica
+ (ad es. ssd o hdd) usando i nomi delle classi di dispositivi Crush nella mappa CRUSH.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9049698214199657456" datatype="html">
+ <source>Set the directory name from which the erasure code plugin is loaded.</source>
+ <target>Impostare il nome della directory da cui viene caricato il plug-in del codice di cancellazione.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5514060020564877279" datatype="html">
+ <source>Allows all operations</source>
+ <target>Consente tutte le operazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4265406815683383218" datatype="html">
+ <source>Allows only operations that do not modify the server</source>
+ <target>Consente solo le operazioni che non modificano il server</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="990071930378308183" datatype="html">
+ <source>Allows no access at all</source>
+ <target>Non consente alcun accesso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7286983657616285612" datatype="html">
+ <source>Please specify a filesystem volume.</source>
+ <target>Specificare un volume del file system.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8321762156640395170" datatype="html">
+ <source>The feature is disabled because Orchestrator is not available.</source>
+ <target>La funzione è disabilitata perché Orchestrator non è disponibile.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6718394293315494787" datatype="html">
+ <source>The Orchestrator backend doesn't support this feature.</source>
+ <target>Il backend di Orchestrator non supporta questa funzione.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5569418400096331461" datatype="html">
+ <source>-- Select the priority --</source>
+ <target>-- Selezionare il livello di priorità --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="802458941707537739" datatype="html">
+ <source>Low</source>
+ <target>Bassa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8063651736083474594" datatype="html">
+ <source>High</source>
+ <target>Alta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1717753935149218245" datatype="html">
+ <source>The user list data might be stale. If needed, you can manually reload it.</source>
+ <target>I dati dell'elenco degli utenti potrebbero non essere aggiornati. Se necessario, è possibile ricaricarli manualmente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/list-with-details.class.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7077550143229856452" datatype="html">
+ <source>Retrieving data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>Recupero dei dati per <x id="PH" equiv-text="statusFor"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8231424898988217966" datatype="html">
+ <source>Retrieving data.</source>
+ <target>Recupero dei dati in corso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2357645764289315007" datatype="html">
+ <source>Please wait...</source>
+ <target>Attendere...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="232824565824302482" datatype="html">
+ <source>Displaying previously cached data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>Visualizzazione dei dati presenti in cache per <x id="PH" equiv-text="statusFor"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8721257977793603730" datatype="html">
+ <source>Displaying previously cached data.</source>
+ <target>Visualizzazione dei dati presenti in cache.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6731313206654246255" datatype="html">
+ <source>Could not load data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>Impossibile caricare i dati per <x id="PH" equiv-text="statusFor"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3359748695862553898" datatype="html">
+ <source>Could not load data.</source>
+ <target>Impossibile caricare i dati.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4836577225879717660" datatype="html">
+ <source>Please check the cluster health.</source>
+ <target>Verificare l'integrità del cluster.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1519954996184640001" datatype="html">
+ <source>Error</source>
+ <target>Errore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5037437391296624618" datatype="html">
+ <source>Information</source>
+ <target>Informazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4648900870671159218" datatype="html">
+ <source>Success</source>
+ <target>Operazione riuscita</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3425367071066107827" datatype="html">
+ <source>Danger</source>
+ <target>Pericolo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c947210e2d162b6225083d18820ab602f58cd2d" datatype="html">
+ <source>Remove the custom configuration value. The default configuration will be inherited and used instead.</source>
+ <target>Rimuovere il valore della configurazione personalizzata. Al suo posto verrà utilizzato il valore di default.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="454ee9cb60b00446a8fb147fd2cc5eb836320586" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>.</source>
+ <target>Il valore immesso è troppo alto. Non deve essere maggiore di <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fc8a22825131e028336f60ef909ccbd96059703" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>.</source>
+ <target>Il valore immesso è troppo basso. Non deve essere minore di <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4dd200b7f9e19048cf90516843b40964f2af3fe9" datatype="html">
+ <source>Copy to Clipboard</source>
+ <target>Copia negli appunti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6110699a3562eeb15371063c0cf7f6bfd88a0209" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>?</source>
+ <target>Si desidera <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="549859e511ba5af0ea03fcaa620c472f08038969" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected items?</source>
+ <target>Si desidera <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> gli elementi selezionati?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="54839ebc827b73c9dc4e1df731c6d36a85036af7" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/>?</source>
+ <target>Si desidera <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> l'elemento <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/> selezionato?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2be8b7f04f0104d3fad90d079d8202b74f758b9a" datatype="html">
+ <source>Yes, I am sure.</source>
+ <target>Sì.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4523728183000855476" datatype="html">
+ <source>documentation</source>
+ <target>documentazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/doc/doc.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3099741642167775297" datatype="html">
+ <source>Download</source>
+ <target>Effettua download</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/download-button/download-button.component.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1417693714872528491" datatype="html">
+ <source>This field is required.</source>
+ <target>Questo campo è obbligatorio.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5321335688371682440" datatype="html">
+ <source>An error occurred.</source>
+ <target>Si è verificato un errore.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5109325fb160b543f71a51e7511c00575057431" datatype="html">
+ <source>Loading panel data...</source>
+ <target>Caricamento dati pannello in corso...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a21acde005f80ceadb1391be1e7ff8b6d18188a0" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the monitoring functionality.</source>
+ <target>Consultare <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> per informazioni su come configurare e abilitare la funzionalità di monitoraggio.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a0ed4bd7b7add2a6febf7adf58d8cde5e421418" datatype="html">
+ <source>Grafana Dashboard doesn't exist. Please refer to <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to add dashboards to Grafana.</source>
+ <target>Il dashboard di Grafana non esiste. Consultare <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> per informazioni su come aggiungere dashboard a Grafana.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e11830040bd64804a0555de76f291d5832772d4" datatype="html">
+ <source>Grafana Time Picker</source>
+ <target>Impostazione orario di Grafana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="238c1ba845dd7330e8088165275919a1debf1ca3" datatype="html">
+ <source>Reset Settings</source>
+ <target>Ripristina impostazioni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7888499255176013171" datatype="html">
+ <source>Last 5 minutes</source>
+ <target>Ultimi 5 minuti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6892361549797455305" datatype="html">
+ <source>Last 15 minutes</source>
+ <target>Ultimi 15 minuti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2653641162607195423" datatype="html">
+ <source>Last 30 minutes</source>
+ <target>Ultimi 30 minuti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4117793269024790392" datatype="html">
+ <source>Last 1 hour (Default)</source>
+ <target>Ultima ora (Default)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2645733658763754077" datatype="html">
+ <source>Last 3 hours</source>
+ <target>Ultime 3 ore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7360078715633936807" datatype="html">
+ <source>Last 6 hours</source>
+ <target>Ultime 6 ore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5055313582241816303" datatype="html">
+ <source>Last 12 hours</source>
+ <target>Ultime 12 ore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9186529157286281693" datatype="html">
+ <source>Last 24 hours</source>
+ <target>Ultime 24 ore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4498682414491138092" datatype="html">
+ <source>Yesterday</source>
+ <target>Ieri</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="929003859318769922" datatype="html">
+ <source>Today so far</source>
+ <target>Fino a oggi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5525943133564968818" datatype="html">
+ <source>Day before yesterday</source>
+ <target>Giorno prima di ieri</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6168755117727892817" datatype="html">
+ <source>Last 2 days</source>
+ <target>Ultimi 2 giorni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7574807704224200535" datatype="html">
+ <source>This day last week</source>
+ <target>Questo giorno della scorsa settimana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4420128118950221234" datatype="html">
+ <source>Previous week</source>
+ <target>Settimana precedente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4063965603321223683" datatype="html">
+ <source>This week so far</source>
+ <target>Fino a questa settimana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4873149362496451858" datatype="html">
+ <source>Last 7 days</source>
+ <target>Ultimi 7 giorni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8586908745456864217" datatype="html">
+ <source>Previous month</source>
+ <target>Mese precedente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1647573304710886499" datatype="html">
+ <source>This month so far</source>
+ <target>Fino a questo mese</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2949150997160654358" datatype="html">
+ <source>Last 30 days</source>
+ <target>Ultimi 30 giorni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7469939859049484736" datatype="html">
+ <source>Last 90 days</source>
+ <target>Ultimi 90 giorni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847501198811458781" datatype="html">
+ <source>Last 6 months</source>
+ <target>Ultimi 6 mesi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7447583558445881102" datatype="html">
+ <source>Last 1 year</source>
+ <target>Ultimo anno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="100513227838842152" datatype="html">
+ <source>Previous year</source>
+ <target>Anno precedente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3650872673621947074" datatype="html">
+ <source>This year so far</source>
+ <target>Fino a quest'anno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1262816694819959075" datatype="html">
+ <source>Last 2 years</source>
+ <target>Ultimi 2 anni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7878813844917362690" datatype="html">
+ <source>Last 5 years</source>
+ <target>Ultimi 5 anni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3fb5709e10166cbc85970cbff103db227dbeb813" datatype="html">
+ <source>Select a Language</source>
+ <target>Selezionare una lingua</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/language-selector/language-selector.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e52e9143145e1db5146258de81eae018a407b31" datatype="html">
+ <source>Clear notifications</source>
+ <target>Annulla notifiche</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0b07bb6b7ff21ede439dd04eaf8872d1ecb84d8" datatype="html">
+ <source>Remove notification</source>
+ <target>Rimuovi notifica</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e17a1d75189da843f541f7764f188f2b19a97df2" datatype="html">
+ <source>Duration:</source>
+ <target>Durata:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d4b37c6675c5b436a54c43d6716eec835e1aa7f" datatype="html">
+ <source>There are no notifications.</source>
+ <target>Nessuna notifica presente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b20e42ac4354d449f2718428b5390933eef0c1b9" datatype="html">
+ <source>The feature is not supported in the current Orchestrator.</source>
+ <target>La funzione non è supportata nell'Orchestrator corrente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a437b8f93cf826817c04a4277edb1ae3a93a1ab" datatype="html">
+ <source>Orchestrator is not available. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the functionality.</source>
+ <target>Orchestrator non è disponibile. Consultare <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> per informazioni su come configurare e abilitare la funzionalità.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">7,9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20b3d45b0c08a2951a9974fa20505e4de95250c9" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>less than 1<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day. Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <target>La password scade tra <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>meno di 1<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> giorno. Fare clic <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>qui<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> per modificarla adesso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">9,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f34088c155e40ffb23770a465a65868ce772b2" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day(s). Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <target>La password scade tra <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> giorno/i. Fare clic <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>qui<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> per modificarla adesso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8d1785038d461ec66b5799db21864182b35900a" datatype="html">
+ <source>Refresh</source>
+ <target>Aggiorna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/refresh-selector/refresh-selector.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3417247046175131869" datatype="html">
+ <source>No items selected.</source>
+ <target>Nessun elemento selezionato.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1034353870189672674" datatype="html">
+ <source>Deselect item to select again</source>
+ <target>Deselezionare l'elemento per selezionare di nuovo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4879298070255432995" datatype="html">
+ <source>Selection limit reached</source>
+ <target>Raggiunto il limite per la selezione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001227209911602786" datatype="html">
+ <source>Filter tags</source>
+ <target>Filtra tag</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="791789583719406586" datatype="html">
+ <source>Add badge</source>
+ <target>Aggiungi badge</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="699988676752930063" datatype="html">
+ <source>There are no items available.</source>
+ <target>Nessun elemento disponibile.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6702323d3760e3db0e2e785d567469d18beb120" datatype="html">
+ <source>The Ceph community needs your help to continue improving: please <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>Activate<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> the <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Telemetry<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> module.</source>
+ <target>La comunità Ceph ha bisogno del tuo aiuto per continuare a migliorare: ti invitiamo ad <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>Attivare<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> il modulo di <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Telemetria<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.html</context>
+ <context context-type="linenumber">8,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8770134622386151776" datatype="html">
+ <source>Telemetry activation reminder muted</source>
+ <target>Audio del promemoria di attivazione telemetria disattivato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8352450862052130357" datatype="html">
+ <source>You can activate the module on the Telemetry configuration page (&lt;b&gt;Dashboard Settings&lt;/b&gt; -&gt; &lt;b&gt;Telemetry configuration&lt;/b&gt;) at any time.</source>
+ <target>È possibile attivare il modulo nella pagina Configurazione telemetria (&lt;b&gt;Impostazioni dashboard&lt;/b&gt; -&gt; &lt;b&gt;Configurazione telemetria&lt;/b&gt;) in qualsiasi momento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bc9e5365a581105ce37cf47d1d74e4ad9eb75ce" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e634c306cab9e8879c3392593714c1ceab85437d" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3249513483374643425" datatype="html">
+ <source>Add</source>
+ <target>Aggiungi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4359847060009771702" datatype="html">
+ <source>Set</source>
+ <target>Imposta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935187492052582731" datatype="html">
+ <source>Submit</source>
+ <target>Invia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4814285799071780083" datatype="html">
+ <source>Remove</source>
+ <target>Rimuovi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8363450564548681668" datatype="html">
+ <source>Unset</source>
+ <target>Annulla impostazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2159130950882492111" datatype="html">
+ <source>Cancel</source>
+ <target>Annulla</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1295614462098694869" datatype="html">
+ <source>Preview</source>
+ <target>Anteprima</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2354817630223808522" datatype="html">
+ <source>Move</source>
+ <target>Sposta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3885497195825665706" datatype="html">
+ <source>Next</source>
+ <target>Avanti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8890553633144307762" datatype="html">
+ <source>Back</source>
+ <target>Indietro</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5834780181397311898" datatype="html">
+ <source>Clone</source>
+ <target>Clona</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4323470180912194028" datatype="html">
+ <source>Copy</source>
+ <target>Copia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2131301778880826094" datatype="html">
+ <source>Deep Scrub</source>
+ <target>Pulitura approfondita</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1704447209800801558" datatype="html">
+ <source>Destroy</source>
+ <target>Elimina definitivamente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8343007008325027187" datatype="html">
+ <source>Evict</source>
+ <target>Rimuovi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="408179081163888126" datatype="html">
+ <source>Flatten</source>
+ <target>Appiattisci</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="318900679147387932" datatype="html">
+ <source>Mark Down</source>
+ <target>Declassa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5275142643521766706" datatype="html">
+ <source>Mark In</source>
+ <target>Attiva</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6973272903386150199" datatype="html">
+ <source>Mark Lost</source>
+ <target>Contrassegna come perso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1962653792210847411" datatype="html">
+ <source>Mark Out</source>
+ <target>Disattiva</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4424610588915076517" datatype="html">
+ <source>Protect</source>
+ <target>Proteggi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6041115344061899387" datatype="html">
+ <source>Rename</source>
+ <target>Rinomina</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">164</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6770769801335635194" datatype="html">
+ <source>Restore</source>
+ <target>Ripristina</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2003230525878010676" datatype="html">
+ <source>Reweight</source>
+ <target>Ripesa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5430834128563178593" datatype="html">
+ <source>Scrub</source>
+ <target>Pulitura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8461842260159597706" datatype="html">
+ <source>Show</source>
+ <target>Mostra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5655608100705734230" datatype="html">
+ <source>Move to Trash</source>
+ <target>Sposta nel cestino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4622393909937403117" datatype="html">
+ <source>Unprotect</source>
+ <target>Rimuovi protezione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1230154438678955604" datatype="html">
+ <source>Change</source>
+ <target>Modifica</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8450843381175865415" datatype="html">
+ <source>Enter Maintenance</source>
+ <target>Entra in manutenzione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1610181371597502589" datatype="html">
+ <source>Exit Maintenance</source>
+ <target>Esci dalla manutenzione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="676511611419004737" datatype="html">
+ <source>Start Drain</source>
+ <target>Avvia svuotamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7170653322511987983" datatype="html">
+ <source>Stop Drain</source>
+ <target>Arresta svuotamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5528551262937858942" datatype="html">
+ <source>Recreate</source>
+ <target>Ricrea</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2502364444688691031" datatype="html">
+ <source>Expire</source>
+ <target>Scadenza</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6381490568322624964" datatype="html">
+ <source>Deleted</source>
+ <target>Eliminato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="231679111972850796" datatype="html">
+ <source>Added</source>
+ <target>Aggiunto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5406093358072761930" datatype="html">
+ <source>Removed</source>
+ <target>Rimosso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3008573030448240863" datatype="html">
+ <source>Edited</source>
+ <target>Modificato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4381944803872489731" datatype="html">
+ <source>Canceled</source>
+ <target>Annullato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754993936947658096" datatype="html">
+ <source>Previewed</source>
+ <target>Visualizzato in anteprima</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6001163963116907226" datatype="html">
+ <source>Moved</source>
+ <target>Spostato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4932744777596632840" datatype="html">
+ <source>Cloned</source>
+ <target>Clonato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2115592966120408375" datatype="html">
+ <source>Copied</source>
+ <target>Copiato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7937474560394832586" datatype="html">
+ <source>Deep Scrubbed</source>
+ <target>Pulito approfonditamente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6321562733889197649" datatype="html">
+ <source>Destroyed</source>
+ <target>Eliminato definitivamente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7460162290177581995" datatype="html">
+ <source>Flattened</source>
+ <target>Appiattito</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3662010055028969035" datatype="html">
+ <source>Marked Down</source>
+ <target>Declassato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5880434235404894589" datatype="html">
+ <source>Marked In</source>
+ <target>Attivato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="266997194072682078" datatype="html">
+ <source>Marked Lost</source>
+ <target>Contrassegnato come perso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">250</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4010544044592534535" datatype="html">
+ <source>Marked Out</source>
+ <target>Disattivato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4776304093333411035" datatype="html">
+ <source>Protected</source>
+ <target>Con protezione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2700903921419382511" datatype="html">
+ <source>Purged</source>
+ <target>Eliminato definitivamente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5488667333459350160" datatype="html">
+ <source>Renamed</source>
+ <target>Rinominato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8044659850000829751" datatype="html">
+ <source>Restored</source>
+ <target>Ripristinato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559472082694466366" datatype="html">
+ <source>Reweighted</source>
+ <target>Ripesato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022271525067453676" datatype="html">
+ <source>Rolled back</source>
+ <target>Rollback eseguito</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2483217756816388123" datatype="html">
+ <source>Scrubbed</source>
+ <target>Pulito</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7200036055090632378" datatype="html">
+ <source>Showed</source>
+ <target>Mostrato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7609648817347881129" datatype="html">
+ <source>Moved to Trash</source>
+ <target>Spostato nel cestino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7810326403606456469" datatype="html">
+ <source>Unprotected</source>
+ <target>Senza protezione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5620774899056099259" datatype="html">
+ <source>Recreated</source>
+ <target>Ricreato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464749780222721589" datatype="html">
+ <source>Expired</source>
+ <target>Scaduto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">266</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e5e23363e949f7dcbaf034bdb141a561132a10e" datatype="html">
+ <source>Clear filters</source>
+ <target>Annulla filtri</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80cc9a12d4bf6fe454ed94b379eeaf915f920bb7" datatype="html">
+ <source>selected</source>
+ <target>selezionato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <note priority="1" from="description">X selected</note>
+ </trans-unit>
+ <trans-unit id="0cb77511a9a148e05b9adf36cc07269956fbb29d" datatype="html">
+ <source>found</source>
+ <target>trovato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <note priority="1" from="description">X found</note>
+ </trans-unit>
+ <trans-unit id="79347388740c50b7ac97e144c2494bb62912f312" datatype="html">
+ <source>total</source>
+ <target>totale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <note priority="1" from="description">X total</note>
+ </trans-unit>
+ <trans-unit id="2a3dab422cc892db037db8632bb84a6bf496e2d1" datatype="html">
+ <source>Expand/Collapse Row</source>
+ <target>Espandi/Comprimi riga</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4047162422391207122" datatype="html">
+ <source>Failed to load data.</source>
+ <target>Non è stato possibile caricare i dati.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.ts</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="709331713250198508" datatype="html">
+ <source>Loading form data...</source>
+ <target>Caricamento dei dati del modulo in corso...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3850344644863430180" datatype="html">
+ <source>Form data could not be loaded.</source>
+ <target>Impossibile caricare i dati del modulo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4626760504772708998" datatype="html">
+ <source>Size has to be at least <x id="PH" equiv-text="value"/> or more</source>
+ <target>La dimensione deve essere non superiore a <x id="PH" equiv-text="value"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">428</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2880361802894657892" datatype="html">
+ <source>Size has to be at most <x id="PH" equiv-text="value"/> or less</source>
+ <target>La dimensione deve essere non superiore a <x id="PH" equiv-text="value"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2807800733729323332" datatype="html">
+ <source>Yes</source>
+ <target>Sì</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3542042671420335679" datatype="html">
+ <source>No</source>
+ <target>No</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7789266940050748913" datatype="html">
+ <source>in %s</source>
+ <target>entro %s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565573880632900017" datatype="html">
+ <source>%s ago</source>
+ <target>%s fa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="220300059326988179" datatype="html">
+ <source>a few seconds</source>
+ <target>pochi secondi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2761143993878941513" datatype="html">
+ <source>%d seconds</source>
+ <target>%d secondi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7094767962693903153" datatype="html">
+ <source>a minute</source>
+ <target>un minuto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7597613755904774250" datatype="html">
+ <source>%d minutes</source>
+ <target>%d minuti</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2757762976030115752" datatype="html">
+ <source>an hour</source>
+ <target>un'ora</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9118454901758656303" datatype="html">
+ <source>%d hours</source>
+ <target>%d ore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7435193742089920080" datatype="html">
+ <source>a day</source>
+ <target>un giorno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1821334622562842480" datatype="html">
+ <source>%d days</source>
+ <target>%d giorni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7375306199026780379" datatype="html">
+ <source>a week</source>
+ <target>una settimana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7272688256541915488" datatype="html">
+ <source>%d weeks</source>
+ <target>%d settimane</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5761124614324704118" datatype="html">
+ <source>a month</source>
+ <target>un mese</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="352195662913351589" datatype="html">
+ <source>%d months</source>
+ <target>%d mesi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7562153591649199139" datatype="html">
+ <source>a year</source>
+ <target>un anno</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5424759741855527370" datatype="html">
+ <source>%d years</source>
+ <target>%d anni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7738182956549158907" datatype="html">
+ <source>Required rules for passwords:</source>
+ <target>Regole obbligatorie per le password:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8839765875053270528" datatype="html">
+ <source>Must contain at least <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> characters</source>
+ <target>Deve contenere almeno <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> caratteri</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3098731108593590794" datatype="html">
+ <source>Must not be the same as the previous one</source>
+ <target>Non deve essere uguale alla precedente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9150236741862848105" datatype="html">
+ <source>Cannot contain the username</source>
+ <target>Non può contenere il nome utente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6395043854518867543" datatype="html">
+ <source>Cannot contain any configured keyword</source>
+ <target>Non può contenere nessuna tra le parole chiave configurate</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="907558624910601703" datatype="html">
+ <source>Cannot contain any repetitive characters e.g. &quot;aaa&quot;</source>
+ <target>Non può contenere caratteri ripetuti ad es. &quot;aaa&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514384270734082343" datatype="html">
+ <source>Cannot contain any sequential characters e.g. &quot;abc&quot;</source>
+ <target>Non può contenere caratteri in sequenza ad es. &quot;abc&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4119354814383293871" datatype="html">
+ <source>Must consist of characters from the following groups:
+ * Alphabetic a-z, A-Z
+ * Numbers 0-9
+ * Special chars: !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * Any other characters (signs)</source>
+ <target>Deve contenere caratteri dei gruppi seguenti:
+ * Lettere alfabetiche: a-z, A-Z
+ * Numeri: 0-9
+ * Caratteri speciali: !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * Altri caratteri (simboli)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">30,34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8649061117624699581" datatype="html">
+ <source>Your matcher seems to match no currently defined rule or active alert.</source>
+ <target>Sembra che il matcher non trovi nessuna corrispondenza con la regola attualmente definita o con l'avviso attivo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7122912874364762704" datatype="html">
+ <source>no active alerts</source>
+ <target>nessun avviso attivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7388215679576832341" datatype="html">
+ <source>1 active alert</source>
+ <target>1 avviso attivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3112400568960537267" datatype="html">
+ <source><x id="PH" equiv-text="alerts"/> active alerts</source>
+ <target><x id="PH" equiv-text="alerts"/> avvisi attivi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6264717417287230743" datatype="html">
+ <source>Matches 1 rule</source>
+ <target>Corrispondenza con 1 regola</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054663176394183966" datatype="html">
+ <source>Matches <x id="PH" equiv-text="rules"/> rules</source>
+ <target>Corrispondenza con <x id="PH" equiv-text="rules"/> regole</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6674225401121099210" datatype="html">
+ <source><x id="PH" equiv-text="rule"/> with <x id="PH_1" equiv-text="alert"/>.</source>
+ <target><x id="PH" equiv-text="rule"/> con <x id="PH_1" equiv-text="alert"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5659908877047925719" datatype="html">
+ <source>Quality of Service</source>
+ <target>Qualità di servizio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1277565045885499475" datatype="html">
+ <source>BPS Limit</source>
+ <target>Limite di BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2289210323987692906" datatype="html">
+ <source>The desired limit of IO bytes per second.</source>
+ <target>Il limite desiderato di byte I/O al secondo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753589939879013605" datatype="html">
+ <source>IOPS Limit</source>
+ <target>Limite di IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2213985059444278522" datatype="html">
+ <source>The desired limit of IO operations per second.</source>
+ <target>Il limite desiderato di operazioni I/O al secondo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2487530611825582289" datatype="html">
+ <source>Read BPS Limit</source>
+ <target>Limite BPS in lettura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8071352270469595250" datatype="html">
+ <source>The desired limit of read bytes per second.</source>
+ <target>Il limite desiderato di byte letti al secondo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1632513758247239690" datatype="html">
+ <source>Read IOPS Limit</source>
+ <target>Limite di IOPS in lettura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2361786794607418566" datatype="html">
+ <source>The desired limit of read operations per second.</source>
+ <target>Il limite desiderato di operazioni di lettura al secondo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="894600353504285551" datatype="html">
+ <source>Write BPS Limit</source>
+ <target>Limite di BPS in scrittura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911437671369366025" datatype="html">
+ <source>The desired limit of write bytes per second.</source>
+ <target>Il limite desiderato di byte scritti al secondo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2947346368707443195" datatype="html">
+ <source>Write IOPS Limit</source>
+ <target>Limite di IOPS in scrittura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5506349527983391356" datatype="html">
+ <source>The desired limit of write operations per second.</source>
+ <target>Il limite desiderato di operazioni di scrittura al secondo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559424229658244943" datatype="html">
+ <source>BPS Burst</source>
+ <target>Burst BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3454058701331860330" datatype="html">
+ <source>The desired burst limit of IO bytes.</source>
+ <target>Il limite desiderato di burst dei byte di I/O.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171005761926448741" datatype="html">
+ <source>IOPS Burst</source>
+ <target>Burst IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4939532784700485729" datatype="html">
+ <source>The desired burst limit of IO operations.</source>
+ <target>Il limite desiderato di burst delle operazioni di I/O.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6273492199526646930" datatype="html">
+ <source>Read BPS Burst</source>
+ <target>Burst BPS in lettura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3105467595643777520" datatype="html">
+ <source>The desired burst limit of read bytes.</source>
+ <target>Il limite desiderato di burst dei byte letti.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2170715106679765467" datatype="html">
+ <source>Read IOPS Burst</source>
+ <target>Burst IOPS in lettura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6234106755510510672" datatype="html">
+ <source>The desired burst limit of read operations.</source>
+ <target>Il limite desiderato di burst delle operazioni di lettura.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="228509518172572466" datatype="html">
+ <source>Write BPS Burst</source>
+ <target>Burst BPS in scrittura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7803279807796571240" datatype="html">
+ <source>The desired burst limit of write bytes.</source>
+ <target>Il limite desiderato di burst dei byte scritti.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9125474584914848055" datatype="html">
+ <source>Write IOPS Burst</source>
+ <target>Burst di IOPS in scrittura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5839129348567326667" datatype="html">
+ <source>The desired burst limit of write operations.</source>
+ <target>Il limite desiderato di burst delle operazioni di scrittura.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="614961883076556986" datatype="html">
+ <source>Failed to <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></source>
+ <target>Impossibile <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="489145301781720653" datatype="html">
+ <source>Executing</source>
+ <target>In esecuzione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4238828029954346941" datatype="html">
+ <source>execute</source>
+ <target>esegui</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7196604637389554584" datatype="html">
+ <source>Executed</source>
+ <target>Eseguito</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4418441687454700644" datatype="html">
+ <source>unknown task</source>
+ <target>task sconosciuto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8667665916832796867" datatype="html">
+ <source>Creating</source>
+ <target>Creazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6031236679730054907" datatype="html">
+ <source>create</source>
+ <target>crea</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5593033420216313122" datatype="html">
+ <source>Updating</source>
+ <target>Aggiornamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6100869651653026893" datatype="html">
+ <source>update</source>
+ <target>aggiorna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3141301060598402455" datatype="html">
+ <source>Deleting</source>
+ <target>Eliminazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3420504288275541125" datatype="html">
+ <source>Adding</source>
+ <target>Aggiunta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1059784693423848532" datatype="html">
+ <source>add</source>
+ <target>aggiungi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594819887188505274" datatype="html">
+ <source>Removing</source>
+ <target>In rimozione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2123171795960509943" datatype="html">
+ <source>remove</source>
+ <target>rimuovi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1946427188770321847" datatype="html">
+ <source>Importing</source>
+ <target>Importazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8495827411619139669" datatype="html">
+ <source>import</source>
+ <target>importa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218459863491436562" datatype="html">
+ <source>Imported</source>
+ <target>Importato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6534993668932538712" datatype="html">
+ <source>RBD '<x id="PH" equiv-text="metadata.image_spec"/>'</source>
+ <target>RBD '<x id="PH" equiv-text="metadata.image_spec"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8237287859948228705" datatype="html">
+ <source>RBD snapshot '<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>'</source>
+ <target>snapshot RBD '<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2328067975897167268" datatype="html">
+ <source>mirroring site name</source>
+ <target>nome sito copia speculare</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4433460322631470833" datatype="html">
+ <source>bootstrap token</source>
+ <target>token di bootstrap</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7044591639782280183" datatype="html">
+ <source>mirror mode for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>modalità di copia speculare per il pool '<x id="PH" equiv-text="metadata.pool_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7109746474198366468" datatype="html">
+ <source>mirror peer for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>peer della copia speculare per il pool '<x id="PH" equiv-text="metadata.pool_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6201476020617351396" datatype="html">
+ <source>all dashboards</source>
+ <target>tutti i dashboard</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7268953097700363232" datatype="html">
+ <source>Identifying</source>
+ <target>Identificazione</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4337678035264231187" datatype="html">
+ <source>identify</source>
+ <target>identifica</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7257219307556106552" datatype="html">
+ <source>Identified</source>
+ <target>Identificato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6002370161381995023" datatype="html">
+ <source>device '<x id="PH" equiv-text="metadata.device"/>' on host '<x id="PH_1" equiv-text="metadata.hostname"/>'</source>
+ <target>dispositivo '<x id="PH" equiv-text="metadata.device"/>' sull'host '<x id="PH_1" equiv-text="metadata.hostname"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5580298273054260850" datatype="html">
+ <source>OSDs (DriveGroups: <x id="PH" equiv-text="metadata.tracking_id"/>)</source>
+ <target>OSD (DriveGroup: <x id="PH" equiv-text="metadata.tracking_id"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2182125722527364040" datatype="html">
+ <source>Name is already used by <x id="PH" equiv-text="this.pool(metadata)"/>.</source>
+ <target>Il nome è già utilizzato da <x id="PH" equiv-text="this.pool(metadata)"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">182</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7892856315477304281" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> is busy.</source>
+ <target><x id="PH" equiv-text="this.rbd.default(metadata)"/> è occupato.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4690045751984117407" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> contains snapshots.</source>
+ <target><x id="PH" equiv-text="this.rbd.default(metadata)"/> contiene snapshot.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="562148565853868662" datatype="html">
+ <source>Cloning</source>
+ <target>Clonazione in corso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1197352830433807469" datatype="html">
+ <source>clone</source>
+ <target>clona</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1692004144561317867" datatype="html">
+ <source>Snapshot of <x id="PH" equiv-text="this.rbd.child(metadata)"/> must be protected.</source>
+ <target>La snapshot di <x id="PH" equiv-text="this.rbd.child(metadata)"/> deve essere protetta.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8531200838331320284" datatype="html">
+ <source>Copying</source>
+ <target>Copia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6862265996781523030" datatype="html">
+ <source>copy</source>
+ <target>copia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3556912098733712857" datatype="html">
+ <source>Flattening</source>
+ <target>Appiattimento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2488773646187451754" datatype="html">
+ <source>flatten</source>
+ <target>appiattisci</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="704305783678486635" datatype="html">
+ <source>Cannot unprotect <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> because it contains child images.</source>
+ <target>Impossibile rimuovere la protezione da <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> perché contiene immagini secondarie.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">223,225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101271773452792348" datatype="html">
+ <source>Cannot delete <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/> because it's protected.</source>
+ <target>Impossibile eliminare <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/> perché è protetto.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5143010940199748580" datatype="html">
+ <source>Rolling back</source>
+ <target>Rollback</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1315686250907089544" datatype="html">
+ <source>rollback</source>
+ <target>esegui rollback</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5010267418211867946" datatype="html">
+ <source>Moving</source>
+ <target>Spostamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4366763205960752449" datatype="html">
+ <source>move</source>
+ <target>sposta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="695867152524584829" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_spec"/>' to trash</source>
+ <target>immagine '<x id="PH" equiv-text="metadata.image_spec"/>' nel cestino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423442774536615202" datatype="html">
+ <source>Could not find image.</source>
+ <target>Impossibile trovare l'immagine.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2622324641113512527" datatype="html">
+ <source>Restoring</source>
+ <target>Ripristino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3347932678307141902" datatype="html">
+ <source>restore</source>
+ <target>ripristina</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7488038030362249932" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>' into '<x id="PH_1" equiv-text="metadata.new_image_name"/>'</source>
+ <target>immagine '<x id="PH" equiv-text="metadata.image_id_spec"/>' in '<x id="PH_1" equiv-text="metadata.new_image_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565688512490959949" datatype="html">
+ <source>Image name '<x id="PH" equiv-text="metadata.new_image_name"/>' is already in use.</source>
+ <target>Il nome immagine '<x id="PH" equiv-text="metadata.new_image_name"/>' è già in uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6331051389974655106" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>'</source>
+ <target>immagine '<x id="PH" equiv-text="metadata.image_id_spec"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8245559899946787147" datatype="html">
+ <source>Purging</source>
+ <target>Eliminazione definitiva</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7879437654311684252" datatype="html">
+ <source>purge</source>
+ <target>elimina definitivamente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1440427157062670480" datatype="html">
+ <source>all pools</source>
+ <target>tutti i pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8677740163708263843" datatype="html">
+ <source>images from <x id="PH" equiv-text="message"/></source>
+ <target>immagini da <x id="PH" equiv-text="message"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011237345035114219" datatype="html">
+ <source>Cannot disable mirroring because it contains a peer.</source>
+ <target>Impossibile disabilitare l'esecuzione della copia speculare perché contiene un peer.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">292</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7391584598242145869" datatype="html">
+ <source>host '<x id="PH" equiv-text="metadata.hostname"/>'</source>
+ <target>host '<x id="PH" equiv-text="metadata.hostname"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6964302691596180722" datatype="html">
+ <source>OSD '<x id="PH" equiv-text="metadata.svc_id"/>'</source>
+ <target>OSD '<x id="PH" equiv-text="metadata.svc_id"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="488305686602466689" datatype="html">
+ <source>pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>pool '<x id="PH" equiv-text="metadata.pool_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5921392748828575278" datatype="html">
+ <source>erasure code profile '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <target>profilo del codice di cancellazione '<x id="PH" equiv-text="metadata.name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2423915105798557698" datatype="html">
+ <source>crush rule '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <target>regola Crush '<x id="PH" equiv-text="metadata.name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">370</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8273044996643438592" datatype="html">
+ <source>target '<x id="PH" equiv-text="metadata.target_iqn"/>'</source>
+ <target>destinazione '<x id="PH" equiv-text="metadata.target_iqn"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5474643443735437364" datatype="html">
+ <source>NFS '<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>'</source>
+ <target>NFS '<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">378,380</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2235495382025026939" datatype="html">
+ <source>Service '<x id="PH" equiv-text="metadata.service_name"/>'</source>
+ <target>Servizio '<x id="PH" equiv-text="metadata.service_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ </body>
+ </file>
+</xliff> \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.ja-JP.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.ja-JP.xlf
new file mode 100644
index 000000000..35d75861b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.ja-JP.xlf
@@ -0,0 +1,14882 @@
+<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en-US" datatype="plaintext" original="ng2.template" target-language="ja-JP">
+ <body>
+ <trans-unit id="ngb.alert.close" datatype="html">
+ <source>Close</source>
+ <target>閉じる</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/alert/alert.ts</context>
+ <context context-type="linenumber">58,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.slide-number" datatype="html">
+ <source> Slide <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> of <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </source>
+ <target> スライド<x id="INTERPOLATION" equiv-text="OnHover$ = new"/>/<x id="INTERPOLATION_1" equiv-text="; private _pa"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">114,118</context>
+ </context-group>
+ <note priority="1" from="description">Currently selected slide number read by screen reader</note>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.previous" datatype="html">
+ <source>Previous</source>
+ <target>前へ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">132,134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.next" datatype="html">
+ <source>Next</source>
+ <target>次へ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">147,152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-month" datatype="html">
+ <source>Select month</source>
+ <target>月を選択</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">44,49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">49,50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-year" datatype="html">
+ <source>Select year</source>
+ <target>年を選択</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">59,63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.previous-month" datatype="html">
+ <source>Previous month</source>
+ <target>前月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">24,27</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">35,36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.next-month" datatype="html">
+ <source>Next month</source>
+ <target>来月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">47,50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">60,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first" datatype="html">
+ <source>««</source>
+ <target>««</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">182,183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous" datatype="html">
+ <source>«</source>
+ <target>«</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">186,190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next" datatype="html">
+ <source>»</source>
+ <target>»</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">194,195</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last" datatype="html">
+ <source>»»</source>
+ <target>»»</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">201,204</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first-aria" datatype="html">
+ <source>First</source>
+ <target>最初へ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">208,209</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous-aria" datatype="html">
+ <source>Previous</source>
+ <target>前へ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">215,216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next-aria" datatype="html">
+ <source>Next</source>
+ <target>次へ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">226,228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last-aria" datatype="html">
+ <source>Last</source>
+ <target>最後へ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.progressbar.value" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="; } /** *"/></source>
+ <target><x id="INTERPOLATION" equiv-text="; } /** *"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/progressbar/progressbar.ts</context>
+ <context context-type="linenumber">32,38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.HH" datatype="html">
+ <source>HH</source>
+ <target>HH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">40,41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.hours" datatype="html">
+ <source>Hours</source>
+ <target>時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.MM" datatype="html">
+ <source>MM</source>
+ <target>MM</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">51,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.minutes" datatype="html">
+ <source>Minutes</source>
+ <target>分</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-hours" datatype="html">
+ <source>Increment hours</source>
+ <target>時間を増やす</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">63,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-hours" datatype="html">
+ <source>Decrement hours</source>
+ <target>時間を減らす</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">69,70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-minutes" datatype="html">
+ <source>Increment minutes</source>
+ <target>分を増やす</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">76,78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-minutes" datatype="html">
+ <source>Decrement minutes</source>
+ <target>分を減らす</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">82,84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.SS" datatype="html">
+ <source>SS</source>
+ <target>SS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.seconds" datatype="html">
+ <source>Seconds</source>
+ <target>秒</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">92,93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-seconds" datatype="html">
+ <source>Increment seconds</source>
+ <target>秒を増やす</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">100,101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-seconds" datatype="html">
+ <source>Decrement seconds</source>
+ <target>秒を減らす</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">106,110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.AM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></source>
+ <target><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">115,121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.PM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="t() meridian: b"/></source>
+ <target><x id="INTERPOLATION" equiv-text="t() meridian: b"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">123,131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.toast.close-aria" datatype="html">
+ <source>Close</source>
+ <target>閉じる</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/toast/toast.ts</context>
+ <context context-type="linenumber">78,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8835b9e49a3348b0a2f2162c21118af1f4bee45a" datatype="html">
+ <source>Must be greater than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>.</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>以上である必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbddac59563c8c126e3fe28691e4e247614fcbd1" datatype="html">
+ <source>Must be less than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>.</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>以下である必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5" datatype="html">
+ <source>Overview</source>
+ <target>概要</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbd2045d5c37e4bb39a3c0fb62ea1ddf70a12838" datatype="html">
+ <source>Targets</source>
+ <target>ターゲット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a674ab267d1934bf395f87ca1503fd474296893f" datatype="html">
+ <source>iSCSI Topology</source>
+ <target>iSCSIトポロジ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8953033926734869941" datatype="html">
+ <source>Name</source>
+ <target>名前</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6603000223840533819" datatype="html">
+ <source>Current</source>
+ <target>現在</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5607669932062416162" datatype="html">
+ <source>Default</source>
+ <target>デフォルト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6803e31b7395d94934e091a49a9524026b59b018" datatype="html">
+ <source>Discovery Authentication</source>
+ <target>検出認証</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e08a77594f3d89311cdf6da5090044270909c194" datatype="html">
+ <source>User</source>
+ <target>ユーザ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">381</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7cbdabcece469fab89cfa687ab152bca18b97498" datatype="html">
+ <source>This field is required.</source>
+ <target>このフィールドは必須です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">368</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">423</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">481</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">291</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">343</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">407</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">490</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">516</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">556</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">573</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">590</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">647</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">672</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">299</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">195</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">520</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">614</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">651</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f717bad2da5944a2567a52f971ccc6806db85805" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>ユーザ名の長さは8〜64文字で、英数字、「.」、「@」、「-」、「_」、または「:」を含めることができます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">28,29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">85,86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c32ef07f8803a223a83ed17024b38e8d82292407" datatype="html">
+ <source>Password</source>
+ <target>パスワード</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">403</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">581</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="001e1836299d8d3b84eaebe2fa051325beab3f00" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>パスワードの長さは12〜16文字で、英数字、「@」、「-」、「_」、または「/」を含めることができます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">61,62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">118,119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff40391de7a1944ea95091e4045cc34c4979b736" datatype="html">
+ <source>Mutual User</source>
+ <target>相互ユーザ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cf73dbebe99b737c4d288788182fc356e3c93d3" datatype="html">
+ <source>Mutual Password</source>
+ <target>相互パスワード</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594987303599690088" datatype="html">
+ <source>Updated discovery authentication</source>
+ <target>検出認証を更新しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb127ea03835b3230f0ed981c7080e2ccb879621" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <note priority="1" from="description">form title</note>
+ </trans-unit>
+ <trans-unit id="1406c2fb12a20c1528b19bcc5e24a6a2386167f3" datatype="html">
+ <source>Target IQN</source>
+ <target>ターゲットIQN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5fe42339be910372fa689f559155631862d218e8" datatype="html">
+ <source>IQN has wrong pattern.</source>
+ <target>IQNのパターンが正しくありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="050a7ff057d1e895357540406b6be5652b4d1c71" datatype="html">
+ <source>An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'</source>
+ <target>IQNは「iqn.$year-$month.$reversedAddress:$definedName」という形式で表記されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8ada4b53396d8366db00a435acc61d53d857047" datatype="html">
+ <source>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</source>
+ <target>例: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e" datatype="html">
+ <source>More information</source>
+ <target>詳細情報</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9b1aa85dfc6849196e64060db02c5410de69b7a1" datatype="html">
+ <source>This target has modified advanced settings.</source>
+ <target>このターゲットの詳細設定は変更されています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6990ad8d6182662e864495ac31c3758cda1c7a28" datatype="html">
+ <source>Portals</source>
+ <target>ポータル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a3ac2b4137d723fd9878cd357c2012ff6c07973" datatype="html">
+ <source>Add portal</source>
+ <target>ポータルの追加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3638c01b6c34066438909713ec96087c813fc7e" datatype="html">
+ <source>At least <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> gateways are required.</source>
+ <target>少なくとも<x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/>台のゲートウェイが必要です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b73f7f5060fb22a1e9ec462b1bb02493fa3ab866" datatype="html">
+ <source>Images</source>
+ <target>イメージ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">495</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">629</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9aff25be088f0efe3eaaf62edf2bff41cc41a617" datatype="html">
+ <source>Backstore: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </source>
+ <target>バックストア: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e3484cae8b118c576ca2815bf9c9406c2eb2cae3" datatype="html">
+ <source>This image has modified settings.</source>
+ <target>このイメージの設定は変更されています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1dff11e0820b6722ab240169f1232d70a54beaaa" datatype="html">
+ <source>Duplicated LUN numbers.</source>
+ <target>重複したLUN番号。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bf2dccf92ccff6e3b091792bf4205595406e1bfb" datatype="html">
+ <source>Duplicated WWN.</source>
+ <target>重複したWWN。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="808038f912fdc7f0e03f82d4afd3bf9178527fc8" datatype="html">
+ <source>Add image</source>
+ <target>イメージの追加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">656</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66c5fb27f52e75b70ca4b670b9b15a2a51cf9543" datatype="html">
+ <source>ACL authentication</source>
+ <target>ACL認証</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="137fbf154ecad4d580354db0858b76faea7e4686" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>ユーザ名の長さは8〜64文字で、英数字、「.」、「@」、「-」、「_」、または「:」を含めることができます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">227,228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">287,288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="361771c32dd2254d77fd3fbf006b008983fe5907" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>パスワードの長さは12〜16文字で、英数字、「@」、「-」、「_」、または「/」を含めることができます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">262,263</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">323,324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f494bd31f095f6dcc656ce87ec2dcf07a2e9b30c" datatype="html">
+ <source>Initiators</source>
+ <target>イニシエータ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">335</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">588</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e98239d8a6be1100119ff4b5630c822b82786740" datatype="html">
+ <source>Initiator</source>
+ <target>イニシエータ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2c5059d8cda15d8d03e2cce30f2d139623d9a91" datatype="html">
+ <source>Client IQN</source>
+ <target>クライアントIQN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="107d5aabce23d900f0a80e6ddc1c10e29aa0bed8" datatype="html">
+ <source>Initiator IQN needs to be unique.</source>
+ <target>イニシエータIQNは一意である必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e7cad911fa524e512d9744b16358b7ee6791385" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>ユーザ名の長さは8〜64文字で、英数字、「.」、「@」、「-」、「_」、または「:」を含めることができます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">394,395</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">452,453</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7f2c186d181206d0d2b1ff74819081a010f10bf" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>パスワードの長さは12〜16文字で、英数字、「@」、「-」、「_」、または「/」を含めることができます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">427,428</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">485,486</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d1878d5fc761cbe9614bfd87047a740c82a6951" datatype="html">
+ <source>Initiator belongs to a group. Images will be configure in the group.</source>
+ <target>イニシエータはいずれかのグループに属します。イメージはそのグループ内で設定されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">515</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0de67b9d97fafbf200f9451e8388ee8128a56ac" datatype="html">
+ <source>No items added.</source>
+ <target>アイテムが追加されていません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">671</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d565e47726158e428ecdc952fc9233b9b7d7f049" datatype="html">
+ <source>Add initiator</source>
+ <target>イニシエータの追加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">616</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c22ba03540aa3217da059f45e7eab138b51a96e2" datatype="html">
+ <source>Groups</source>
+ <target>グループ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c90059afafb7e160384d9f512797c95bb95c6dc" datatype="html">
+ <source>Group</source>
+ <target>グループ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cff1428d10d59d14e45edec3c735a27b5482db59" datatype="html">
+ <source>Name</source>
+ <target>名前</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">576</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3084948274cff4f56d0f431af47240e9cf02fcc7" datatype="html">
+ <source>Add group</source>
+ <target>グループの追加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">676</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6634268061646442252" datatype="html">
+ <source>There are no portals available.</source>
+ <target>使用可能なポータルはありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4587015892789840153" datatype="html">
+ <source>There are no images available.</source>
+ <target>使用可能なイメージはありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7896905042057267575" datatype="html">
+ <source>There are no images available. Please make sure you add an image to the target.</source>
+ <target>使用可能なイメージはありません。ターゲットにイメージを追加したことを確認してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6765423558085969805" datatype="html">
+ <source>There are no initiators available. Please make sure you add an initiator to the target.</source>
+ <target>使用可能なイニシエータはありません。ターゲットにイニシエータを追加したことを確認してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2539932200265667453" datatype="html">
+ <source>target</source>
+ <target>ターゲット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="051dcc342cfa5c1eaf187a2001aaa162379a160c" datatype="html">
+ <source>Configure</source>
+ <target>設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e515f954730279c31d5301f02479666d6264e8b" datatype="html">
+ <source>Changing these parameters from their default values is usually not necessary.</source>
+ <target>通常はこれらのパラメータをデフォルト値から変更する必要はありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e2591df099ddac796cda401c5f282da779d45f2" datatype="html">
+ <source>Identifier</source>
+ <target>識別子</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62480a4859976427cf18fc8ef41d3a438eda0412" datatype="html">
+ <source>lun</source>
+ <target>LUN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8afc9eb4405e0aa554b2ba14140ef790cdecc040" datatype="html">
+ <source>wwn</source>
+ <target>WWN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
+ <source>Settings</source>
+ <target>設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69a47cbabcc51ca942606e1d8da0ec11f98a2690" datatype="html">
+ <source>Backstore</source>
+ <target>バックストア</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="339878da255ab55447c43afef8d9b2f9753bf5f6" datatype="html">
+ <source>Advanced Settings</source>
+ <target>詳細設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="332227f088a4877b3c11f5fb3ae8bc812c470fae" datatype="html">
+ <source>iSCSI Targets not available</source>
+ <target>使用可能なiSCSIターゲットがありません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7fba666f1fff0182e570f12133fb3d622d9ea6" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the iSCSI Targets management functionality.</source>
+ <target>iSCSIターゲットの管理機能を設定および有効化する方法については、<x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>を参照してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3b301d0044f62c92af0da53d7aaca52a436a547d" datatype="html">
+ <source>Available information:</source>
+ <target>取得可能な情報:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8414a5cb9d71cc1b21b10e4a9d1f2dad558f3361" datatype="html">
+ <source>Discovery authentication</source>
+ <target>検出認証</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4854396465510517671" datatype="html">
+ <source>Target</source>
+ <target>ターゲット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4093869278527257288" datatype="html">
+ <source>Portals</source>
+ <target>ポータル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="414887388288176527" datatype="html">
+ <source>Images</source>
+ <target>イメージ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="798573158169239055" datatype="html">
+ <source># Sessions</source>
+ <target>セッション数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="646929398175374220" datatype="html">
+ <source>Unavailable gateway(s)</source>
+ <target>使用できないゲートウェイ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2350612272163013640" datatype="html">
+ <source>Target has active sessions</source>
+ <target>ターゲットにはアクティブなセッションがあります</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4782410538666829801" datatype="html">
+ <source>iSCSI target</source>
+ <target>iSCSIターゲット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">227</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8a9910cd114c1deb9af74f6f99b4173403965bf2" datatype="html">
+ <source>Gateways</source>
+ <target>ゲートウェイ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911214550882917183" datatype="html">
+ <source>State</source>
+ <target>状態</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4121862424558610140" datatype="html">
+ <source># Targets</source>
+ <target>ターゲット数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101197021456818771" datatype="html">
+ <source>Pool</source>
+ <target>プール</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3012906865384504293" datatype="html">
+ <source>Image</source>
+ <target>イメージ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2699995524827665158" datatype="html">
+ <source>Backstore</source>
+ <target>バックストア</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3559214740809905405" datatype="html">
+ <source>Read Bytes</source>
+ <target>読み取りバイト数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1580583760095064067" datatype="html">
+ <source>Write Bytes</source>
+ <target>書き込みバイト数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7225917547116479918" datatype="html">
+ <source>Read Ops</source>
+ <target>読み取り操作数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6417507714454914481" datatype="html">
+ <source>Write Ops</source>
+ <target>書き込み操作数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="257147267065394003" datatype="html">
+ <source>A/O Since</source>
+ <target>次の日付以降のA/O</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ecbc084370a732fc3cde1966a60af78d71424ab4" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>ブートストラップトークンの作成</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603e9cc3ef2aab57f2b0a00e465b23b9cabefd9c" datatype="html">
+ <source>To create a bootstrap token which can be imported by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Generate<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>ピアサイトクラスタでインポートできるブートストラップトークンを作成するには、ローカルサイトの名前を入力し、ミラーリングを有効にするプールを選択して、<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>[生成]<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>をクリックします。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="660f97cd3188f8a04bd03b79e703fec72c6df04c" datatype="html">
+ <source>Site Name</source>
+ <target>サイト名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2fecea01ce1d44114ee45144eff6d47a5016a74f" datatype="html">
+ <source>Name...</source>
+ <target>名前...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92899fa68e8ca108912163ff58edc8540e453787" datatype="html">
+ <source>Pools</source>
+ <target>プール</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c2a1dc72cffaf7ab3dc5599bf77b0a7fcad2b20" datatype="html">
+ <source>At least one pool is required.</source>
+ <target>少なくとも1つのプールが必要です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b258b258b4cc475ceb2871305b61756b0134f4a" datatype="html">
+ <source>Generate</source>
+ <target>生成</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1edc1fc6cfbbb22353050ad6788508b3ed584f53" datatype="html">
+ <source>Token</source>
+ <target>トークン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff785f5596aef34a93b9b4d1023e95c62eef5740" datatype="html">
+ <source>Generated token...</source>
+ <target>生成されたトークン...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8" datatype="html">
+ <source>Close</source>
+ <target>閉じる</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5467a6bb0e7fade6def7499400d5e2a7d8d3da20" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>ブートストラップトークンのインポート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bb7aee0dec5164f45c0aa2f35f2fb2149d2c1d2" datatype="html">
+ <source>To import a bootstrap token which was created by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, provide the generated token, and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Import<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>ピアサイトクラスタで作成されたブートストラップトークンをインポートするには、ローカルサイトの名前を入力し、ミラーリングを有効にするプールを選択して、<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>[インポート]<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>をクリックします。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9200e09686136a1d42adfb89c12fbfef2deea125" datatype="html">
+ <source>Direction</source>
+ <target>方向</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9761484679958da8d12841a4efa5964d33fae575" datatype="html">
+ <source>The token is invalid.</source>
+ <target>トークンは無効です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2381859602529023966" datatype="html">
+ <source>Instance</source>
+ <target>インスタンス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8040881171107393560" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1605455101862010019" datatype="html">
+ <source>Hostname</source>
+ <target>ホスト名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2724055831234181057" datatype="html">
+ <source>Version</source>
+ <target>バージョン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2041675390931385838" datatype="html">
+ <source>Health</source>
+ <target>ヘルス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87bd96249f8afc23f5301cddb57b1464a98e71a" datatype="html">
+ <source>Edit site name</source>
+ <target>サイト名の編集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cfff72c667274c12eb1ff71eadc25871c10c42dc" datatype="html">
+ <source>Edit the site name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>サイト名を編集し、<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>[更新]<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>をクリックします。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">13,14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66db799d67958d4b0765181d072df62e2d1c16f5" datatype="html">
+ <source>Issues</source>
+ <target>問題</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef06d69259e587e28d52372455f44c7153cda7e7" datatype="html">
+ <source>Syncing</source>
+ <target>同期中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0b0901877d837d3fda16ba161eb74368d1c75b7a" datatype="html">
+ <source>Ready</source>
+ <target>準備完了</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5833626790712999947" datatype="html">
+ <source>Issue</source>
+ <target>問題</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3419681791450150574" datatype="html">
+ <source>Progress</source>
+ <target>進捗</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4902817035128594900" datatype="html">
+ <source>Description</source>
+ <target>説明</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40b7acea5b43f45e0bbd1efeba5200af4687981d" datatype="html">
+ <source>Site Name:</source>
+ <target>サイト名:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e24f9e2d42104ffc01599db4d566d1cc518f9e6" datatype="html">
+ <source>Daemons</source>
+ <target>デーモン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6450386891540681425" datatype="html">
+ <source>Edit Site Name</source>
+ <target>サイト名の編集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4645993115976933405" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>ブートストラップトークンの作成</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4130053543590533787" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>ブートストラップトークンのインポート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4057c56d63a7e9b140b1d01871a9229a5f30eb27" datatype="html">
+ <source>Edit pool mirror mode</source>
+ <target>プールのミラーモードの編集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e1f367f5feaab38f6637dd1f967c848b447dea2d" datatype="html">
+ <source>To edit the mirror mode for pool  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, select a new mode from the list and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>プール<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>のミラーモードを編集するには、リストから新しいモードを選択して、<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>[更新]<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>をクリックします。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37e10df2d9c0c25ef04ac112c9c9a7723e8efae0" datatype="html">
+ <source>Mode</source>
+ <target>モード</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">426</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32ca348ef926b0a6a7a780b8b64c3a8239895cec" datatype="html">
+ <source>Peer clusters must be removed prior to disabling mirror.</source>
+ <target>ミラーを無効にする前に、ピアクラスタを削除する必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5769292297914455214" datatype="html">
+ <source>Disabled</source>
+ <target>無効化済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ddcb416c1c0aa1f54acf5beef1de81813e76fa6" datatype="html">
+ <source>{VAR_SELECT, select, edit {Edit} other {Add}}</source>
+ <target>{VAR_SELECT, select, edit {Edit} other {Add}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3aa7c3a4f7b0cf7c2e60fc71ea1e3b4c3efa3558" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> pool mirror peer</source>
+ <target><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/>プールミラーピア</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="59ca65ece457429d90104ede4674965f62edbabe" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> the pool mirror peer attributes for pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Submit<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/>プール<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>のプールミラーピア属性、および<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>[送信]<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>をクリックします。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d3cc964811f852a168f4a2d5daa59068abc5cf53" datatype="html">
+ <source>Cluster Name</source>
+ <target>クラスタ名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b631721fc56cb7fb1cbd07b802a487c5753f6a2d" datatype="html">
+ <source>The cluster name is not valid.</source>
+ <target>このクラスタ名は無効です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca6deafa31bf421f85094807982aee4bcb20a3ae" datatype="html">
+ <source>CephX ID</source>
+ <target>CephX ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7539188a568c3d553cbde1bacaf32310c4264e24" datatype="html">
+ <source>CephX ID...</source>
+ <target>CephX ID...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1c45b594b0fba22fc64e80c793a7ffe005fdb0e" datatype="html">
+ <source>The CephX ID is not valid.</source>
+ <target>このCephX IDは無効です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20861576fcfce773c918c782cd4f5adf32382921" datatype="html">
+ <source>Monitor Addresses</source>
+ <target>モニターアドレス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fa28eeed2b4bd4ccbe6e9349a1c2b3cb1c5de70a" datatype="html">
+ <source>Comma-delimited addresses...</source>
+ <target>カンマ区切りアドレス...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dc016c82fd85848d5c1b2fd0e8469ee2027d9c16" datatype="html">
+ <source>The monitory address is not valid.</source>
+ <target>この警告アドレスは無効です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0ac55b83dc6739e62bc655cfe375b67c93e7f4a" datatype="html">
+ <source>CephX Key</source>
+ <target>CephXキー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f53434bcb95bd86f1df9c8e22966f757614fc4ad" datatype="html">
+ <source>Base64-encoded key...</source>
+ <target>Base64エンコード化済みキー...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4cd83164cd4f66b4abc2863f9ce6f599d789e4ca" datatype="html">
+ <source>CephX key must be base64 encoded.</source>
+ <target>CephXキーはbase64でエンコードされている必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6407712033679505505" datatype="html">
+ <source>Edit Mode</source>
+ <target>モードの編集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054237897979907103" datatype="html">
+ <source>Add Peer</source>
+ <target>ピアの追加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="899134641637789371" datatype="html">
+ <source>Edit Peer</source>
+ <target>ピアの編集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7393680121674824053" datatype="html">
+ <source>Delete Peer</source>
+ <target>ピアの削除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1713271461473302108" datatype="html">
+ <source>Mode</source>
+ <target>モード</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1061297288634362831" datatype="html">
+ <source>Leader</source>
+ <target>リーダー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8517494870558773093" datatype="html">
+ <source># Local</source>
+ <target>#ローカル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4953753699491987394" datatype="html">
+ <source># Remote</source>
+ <target>#リモート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1715982232168082172" datatype="html">
+ <source>mirror peer</source>
+ <target>ミラーピア</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff92fbdec9fdd5054493eeda0d7ee8b450f83e72" datatype="html">
+ <source>RBD Configuration</source>
+ <target>RBD設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b62d9efc8eb3b589904f6cb96a0406bbda55673a" datatype="html">
+ <source>Remove the local configuration value. The parent configuration value will be inherited and used instead.</source>
+ <target>ローカル設定値を削除します。親設定値が継承されて代わりに使用されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80d769fd863fe44fab689636a078466bfdbd1f20" datatype="html">
+ <source>The minimum value is 0</source>
+ <target>最小値は0です</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5decb3917d46a9ac6e5813699801becb7c3c1455" datatype="html">
+ <source>Global</source>
+ <target>グローバル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f9ba9bb9faa8284bcadb1cdbc6aaf969e9c4bb" datatype="html">
+ <source>Image</source>
+ <target>イメージ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70fcca5a99575cffef3ff8cbd5e69f06ffd0f1c" datatype="html">
+ <source>Pool</source>
+ <target>プール</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176659033176029418" datatype="html">
+ <source>Key</source>
+ <target>キー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9155608366859514313" datatype="html">
+ <source>Source</source>
+ <target>ソース</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6555318547274416232" datatype="html">
+ <source>Value</source>
+ <target>値</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f6e8f6094b180eaf1f11bc0ffe383f1cdcd059e" datatype="html">
+ <source>Only available for RBD images with <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> enabled</source>
+ <target><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>高速差分<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>が有効になっているRBDイメージのみに使用できます</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f8b2bb476981727ab34ed40fde1218361f92c45" datatype="html">
+ <source>Details</source>
+ <target>詳細</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03cc5b14b0a20d075e9009ff021f4f1660ba348a" datatype="html">
+ <source>Data Pool</source>
+ <target>データプール</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b051734b0ee9021991c91b3ed4e81c244322462" datatype="html">
+ <source>Created</source>
+ <target>作成済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7faaaa08f56427999f3be41df1093ce4089bbd75" datatype="html">
+ <source>Size</source>
+ <target>サイズ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="afdb601c16162f2c798b16a2920955f1cc6a20aa" datatype="html">
+ <source>Objects</source>
+ <target>オブジェクト数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ceac8e132384322ec778ba760875a6c6897d3e42" datatype="html">
+ <source>Object size</source>
+ <target>オブジェクトサイズ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cdb1fea93d77c07950c0c76c6e0ad79ebbef084" datatype="html">
+ <source>Features</source>
+ <target>機能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65771c9a73b9aa609d592fc96a64801a8f40bd" datatype="html">
+ <source>Provisioned</source>
+ <target>プロビジョニング済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84a36cb75660b736773fe36ffa3d54f0f0fe363e" datatype="html">
+ <source>N/A</source>
+ <target>なし</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c009342a4e8381f64341d0bb61c2e4685f5a4b" datatype="html">
+ <source>Total provisioned</source>
+ <target>プロビジョニング済み合計</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f6bf8a43ae415f527ac961ea62471b983aaa97b" datatype="html">
+ <source>Striping unit</source>
+ <target>ストライピング単位</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db710e8a8f011923f2d15d713fbae49c38b02b26" datatype="html">
+ <source>Striping count</source>
+ <target>ストライピング数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a4c2a9e76634ff14a60d52a718296f722d47c67" datatype="html">
+ <source>Parent</source>
+ <target>親</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a209e68d78ffc2cc9c53d2e76158624efab71ad" datatype="html">
+ <source>Block name prefix</source>
+ <target>ブロック名のプレフィックス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5704ec2049d007c5f5fb495a5d8b607e68d58081" datatype="html">
+ <source>Order</source>
+ <target>順番</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="984cb6ad70f150a401b4daf841bd3cd957412699" datatype="html">
+ <source>Format Version</source>
+ <target>フォーマットバージョン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f21b1d17b6c5042bb5805516eee37fde33739dd8" datatype="html">
+ <source>Snapshots</source>
+ <target>スナップショット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4a41f824a35ba01d5bd7be61aa06b3e8145209d0" datatype="html">
+ <source>Configuration</source>
+ <target>設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3cc9c2ae277393b3946b38c088dabff671b1ee1b" datatype="html">
+ <source>Performance</source>
+ <target>パフォーマンス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935bb9cb0e4340fc74d33caa3b70d9d143fcad87" datatype="html">
+ <source>Information can not be displayed for RBD in status 'Removing'.</source>
+ <target>ステータス「削除中」のRBDの情報は表示できません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58e58f1a8786da9031a05e6770c5dafce82badf5" datatype="html">
+ <source>This setting overrides the global value</source>
+ <target>この設定はグローバル値よりも優先されます</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36b46714164964c6258b08ed0a25f57d8a950f92" datatype="html">
+ <source>This is the global value. No value for this option has been set for this image.</source>
+ <target>これはグローバル値です。このイメージについて、このオプションの値は設定されていません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6547c9c4d5f62942ac4b1fe459cf9a03d4dbf5a0" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> from</source>
+ <target>以下からの<x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0e9ecf29a4fa5b057bd8052e0d801b3fde6a30bf" datatype="html">
+ <source>'/' and '@' are not allowed.</source>
+ <target>「/」と「@」は使用できません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="94516fa213706c67ce5a5b5765681d7fb032033a" datatype="html">
+ <source>Loading...</source>
+ <target>読み込んでいます...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">209</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">452</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b99417c4dd46286ffd37c8d2e987c8b512ec7052" datatype="html">
+ <source>-- No rbd pools available --</source>
+ <target>-- 使用可能なrbdプールがありません --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef83ec9c304a89d45650e580dcdc2978c37b3a83" datatype="html">
+ <source>-- Select a pool --</source>
+ <target>-- プールを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d649904466254d13df1fbf2d255f0bbc6553d213" datatype="html">
+ <source>-- No namespaces available --</source>
+ <target>-- 使用可能なネームスペースがありません --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e22d7bb4d2d561e0832ee0b9a3da2468a080c4f0" datatype="html">
+ <source>-- Select a namespace --</source>
+ <target>-- ネームスペースを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49449943d8cbf59d8c401c8bd2e76f92e207cc5f" datatype="html">
+ <source>Use a dedicated data pool</source>
+ <target>専用のデータプールを使用してください</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa5b3c5ea5af14d09b2eb098039af9f1f77be010" datatype="html">
+ <source>You need more than one pool with the rbd application label use to use a dedicated data pool.</source>
+ <target>専用のデータプールを使用するには、rbdアプリケーションラベルを使用する複数のプールが必要です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="870aee0dd31a9643bf62007beb8f1ae1deb34d42" datatype="html">
+ <source>Data pool</source>
+ <target>データプール</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3792ca829d9b9f687e1f5d7733d30e9bb0bfec47" datatype="html">
+ <source>Dedicated pool that stores the object-data of the RBD.</source>
+ <target>RBDのオブジェクトデータを保管するための専用プール</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151c80ea931037cd92e854442927f8a0f6ae7795" datatype="html">
+ <source>-- No data pools available --</source>
+ <target>-- 使用可能なデータプールがありません --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0016bd458baa88284a658ce9eeda42d8ad88d2c" datatype="html">
+ <source>e.g., 10GiB</source>
+ <target>例: 10GiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">206</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a88bbee20570aaf9615332fb27020627044874d" datatype="html">
+ <source>You have to increase the size.</source>
+ <target>サイズを大きくする必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cfe07dac5b4ee1c464eb24225ddeb4f1d24076a" datatype="html">
+ <source>Advanced...</source>
+ <target>詳細...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bc2e854e111ecf2bd7db170da5e3c2ed08181d88" datatype="html">
+ <source>Advanced</source>
+ <target>詳細</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3562a3778695a5f9c0445660e35301f0a39aaf73" datatype="html">
+ <source>Striping</source>
+ <target>ストライピング</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef3c3f3b5f562a5cdbe0ee2874287db1534b5958" datatype="html">
+ <source>Stripe unit</source>
+ <target>ストライプ単位</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84471be1049006edecbcaef1a32ae0893c229c50" datatype="html">
+ <source>-- Select stripe unit --</source>
+ <target>-- ストライプ単位を選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">289</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d32c5c54c8581c774a7f467fbd4e329b15a74fa" datatype="html">
+ <source>This field is required because stripe count is defined!</source>
+ <target>ストライプ数が定義されているため、このフィールドは必須です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bbf9040be7c5491d4a03f2185708f43a6582a3b" datatype="html">
+ <source>Stripe unit is greater than object size.</source>
+ <target>ストライプ単位がオブジェクトサイズより大きいです。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a682f49f9b761591661276d7c6f550e641a130a4" datatype="html">
+ <source>Stripe count</source>
+ <target>ストライプ数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="baa74031990c5370008ba622d0a250f0929097f4" datatype="html">
+ <source>This field is required because stripe unit is defined!</source>
+ <target>ストライプ単位が定義されているため、このフィールドは必須です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cd2ada6d5ecbd5cbf89eae0a1f5326efedac0dbc" datatype="html">
+ <source>Stripe count must be greater than 0.</source>
+ <target>ストライプ数は0より大きい必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4341718109173132593" datatype="html">
+ <source>RBD</source>
+ <target>RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1359455778569887786" datatype="html">
+ <source>Deep flatten</source>
+ <target>ディープフラット化</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58519213655664125" datatype="html">
+ <source>Layering</source>
+ <target>階層化</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844531889615887801" datatype="html">
+ <source>Exclusive lock</source>
+ <target>排他ロック</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4585281635594103106" datatype="html">
+ <source>Object map (requires exclusive-lock)</source>
+ <target>オブジェクトマップ(排他ロックが必要)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240933649452133654" datatype="html">
+ <source>Journaling (requires exclusive-lock)</source>
+ <target>ジャーナリング(排他ロックが必要)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3713046526850391848" datatype="html">
+ <source>Fast diff (interlocked with object-map)</source>
+ <target>高速差分(オブジェクトマップと連動)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19f1e825536efbf7492723a7c2d01ad23a4e994b" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1774b9915b0e302d02cad0b9321ad5f1a83247a8" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c9f1026c1235f4d76ace47449e806efd181ab332" datatype="html">
+ <source>Deleting this image will also delete all its snapshots.</source>
+ <target>このイメージを削除すると、そのすべてのスナップショットも削除されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55f864597e84d9bf88769e1fbfda1d64452430c9" datatype="html">
+ <source>The following snapshots are currently protected and will be removed:</source>
+ <target>次のスナップショットは現在保護されており、削除されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2e362ec498c4c9112dc47a3cb7d7250ca8e71790" datatype="html">
+ <source>RBD in status 'Removing'</source>
+ <target>ステータス「削除中」のRBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3294686077659093992" datatype="html">
+ <source>Namespace</source>
+ <target>ネームスペース</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45739481977493163" datatype="html">
+ <source>Size</source>
+ <target>サイズ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7531602241051125940" datatype="html">
+ <source>Objects</source>
+ <target>オブジェクト数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1194977199378511591" datatype="html">
+ <source>Object size</source>
+ <target>オブジェクトサイズ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">226</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="178418048502923560" datatype="html">
+ <source>Provisioned</source>
+ <target>プロビジョニング済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7638291694671392137" datatype="html">
+ <source>Total provisioned</source>
+ <target>プロビジョニング済み合計</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8621797738551294959" datatype="html">
+ <source>Parent</source>
+ <target>親</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616639680594151867" datatype="html">
+ <source>This RBD has cloned snapshots. Please delete related RBDs before deleting this RBD.</source>
+ <target>このRBDはスナップショットのクローンを作成しました。このRBDを削除する前に関連するRBDを削除してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2900827028308925059" datatype="html">
+ <source>This RBD image has an invalid name and can't be managed by ceph.</source>
+ <target>このRBDイメージの名前は無効であり、cephで管理できません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1796389652493657142" datatype="html">
+ <source>Action not possible for an RBD in status 'Removing'</source>
+ <target>ステータスが「削除中」のRBDではアクションを実行できません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">476</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c07d24bb422aa8e5e568df1c5709083f0a9c8f1" datatype="html">
+ <source>Create Namespace</source>
+ <target>ネームスペースの作成</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cca6c0485f96d3a9610d0339cb1275a5f2c3f46" datatype="html">
+ <source>Namespace already exists.</source>
+ <target>ネームスペースはすでに存在します。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4641528557519966449" datatype="html">
+ <source>Created namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <target>ネームスペース「<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>」を作成しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6809428596104996786" datatype="html">
+ <source>Total images</source>
+ <target>合計イメージ数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1346311774128536550" datatype="html">
+ <source>Deleted namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <target>ネームスペース「<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>」を削除しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7605466414392298530" datatype="html">
+ <source>Namespace contains images</source>
+ <target>ネームスペースにはイメージが含まれています</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576483965711201552" datatype="html">
+ <source>RBD Snapshot</source>
+ <target>RBDスナップショット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3473055924346204357" datatype="html">
+ <source>Parent image must support Layering</source>
+ <target>親イメージは階層化をサポートしている必要があります</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1152535233999495900" datatype="html">
+ <source>Snapshot must be protected in order to clone.</source>
+ <target>クローンを作成するには、スナップショットを保護する必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c5331983af566d4ac6a1024d15a3511786a4aa6" datatype="html">
+ <source>You are about to rollback</source>
+ <target>ロールバックしようとしています</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6240400332778072187" datatype="html">
+ <source>PROTECTED</source>
+ <target>保護済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9101667614062185213" datatype="html">
+ <source>UNPROTECTED</source>
+ <target>未保護</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4207916966377787111" datatype="html">
+ <source>Created</source>
+ <target>作成済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587768621777516124" datatype="html">
+ <source>RBD snapshot rollback</source>
+ <target>RBDスナップショットのロールバック</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">305</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2711198699676132148" datatype="html">
+ <source>Rollback</source>
+ <target>ロールバック</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3330476395115957823" datatype="html">
+ <source>RBD snapshot</source>
+ <target>RBDスナップショット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">322</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3a7e364a88ea4673199dfa98bc73e6dbe09dfac" datatype="html">
+ <source>Namespaces</source>
+ <target>ネームスペース</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aba82bfd8e177d35b76cad7cd43941f8e5e5acac" datatype="html">
+ <source>Trash</source>
+ <target>ごみ箱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5e7f4b1ca49e8d217bd0e12c6f7d6b6a2ade2c18" datatype="html">
+ <source>Overall Performance</source>
+ <target>全体的なパフォーマンス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c0408946a6d67185947f455f15cc201d0d78e6" datatype="html">
+ <source>Purge Trash</source>
+ <target>ごみ箱を空にする</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c96a761dc55a21882c132c929583a424c9b8cf4" datatype="html">
+ <source>Expired at</source>
+ <target>失効日</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="661041e3fcff4d3e75c561e038ca2504cf2cc643" datatype="html">
+ <source>Protected until</source>
+ <target>保護の終了日</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee3b2322a1d3277f7e3fdb8a5141ac42bcf350b" datatype="html">
+ <source>This image is protected until <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</source>
+ <target>このイメージは<x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>まで保護されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5611592591303869712" datatype="html">
+ <source>Status</source>
+ <target>ステータス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">213</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">285</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2155633476201267204" datatype="html">
+ <source>Deleted At</source>
+ <target>削除日時</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0b5d789d42c0e69348e5fe0037fcbf5b5fbbdcc" datatype="html">
+ <source>Move an image to trash</source>
+ <target>イメージをごみ箱に移動する</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ad22c1d4aab3b8946603cea62de266d5129ca10" datatype="html">
+ <source>This image contains snapshot(s), which will prevent it from being removed after moved to trash.</source>
+ <target>このイメージにはスナップショットが含まれているため、ごみ箱に移動した後にイメージが削除されることはありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">15,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d4a5f5698bc8118b2e120b9bb72eff339094dd0" datatype="html">
+ <source>To move <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> to trash, click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Move<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Optionally, you can pick an expiration date.</source>
+ <target><x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>をごみ箱に移動するには、<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>[移動]<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>をクリックします。希望に応じて、失効日を選択できます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">19,20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f27d390844aad53b4240360e928156c5f0d326" datatype="html">
+ <source>Protection expires at</source>
+ <target>保護の失効日</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da166e9a0d27322f6ba8916d71ecc0f9905bb4b1" datatype="html">
+ <source>NOT PROTECTED</source>
+ <target>保護されていません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1506e5f2ca22cad14502ec7a20fb6113ace145d" datatype="html">
+ <source>Wrong date format. Please use &quot;YYYY-MM-DD HH:mm:ss&quot;.</source>
+ <target>日付の形式が正しくありません。「YYYY-MM-DD HH:mm:ss」という形式を使用してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa7ea0bb7495281e0b3258467ac7d90a1e44a1a1" datatype="html">
+ <source>Protection has already expired. Please pick a future date or leave it empty.</source>
+ <target>保護はすでに失効しています。将来の日付を選択するか、日付を空白のままにしてください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d8613436532acac2b97d17de28b50f93e6bd0222" datatype="html">
+ <source>To purge, select  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>All<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>  or one pool and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Purge<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </source>
+ <target>空にするには、<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>すべて<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>または1つのプールを選択して、<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>[消去]<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>をクリックします。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55a4f598a4894b7fd5cb88f0ffd3c37ad009dd70" datatype="html">
+ <source>Pool:</source>
+ <target>プール:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d43dd2b9f7797e4cf3a604695bb33e4479108516" datatype="html">
+ <source>Pool name...</source>
+ <target>プール名...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dfc3c34e182ea73c5d784ff7c8135f087992dac1" datatype="html">
+ <source>All</source>
+ <target>すべて</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0e7c7ed1d51a0c205c815048bc9f79e24ee6db2" datatype="html">
+ <source>Restore Image</source>
+ <target>イメージの復元</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3bc4aaf0dce75dc5e01ee5c825a652dc8aea8f0" datatype="html">
+ <source>To restore  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>,  type the image's new name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Restore<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target><x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>を復元するには、イメージの新しい名前を入力して、<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>[復元]<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>をクリックします。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41307dd56fea669eed72e12a6c23af275f6bfd82" datatype="html">
+ <source>New Name</source>
+ <target>新しい名前</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3625859417927520024" datatype="html">
+ <source>id</source>
+ <target>id</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6537904131139019667" datatype="html">
+ <source>type</source>
+ <target>タイプ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8901220148451863928" datatype="html">
+ <source>state</source>
+ <target>状態</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7925190601961269841" datatype="html">
+ <source>version</source>
+ <target>バージョン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6641024648411549335" datatype="html">
+ <source>Host</source>
+ <target>ホスト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773272191572353800" datatype="html">
+ <source>root</source>
+ <target>ルート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6364513948635353490" datatype="html">
+ <source>Evicted client '<x id="PH" equiv-text="clientId"/>'</source>
+ <target>クライアント「<x id="PH" equiv-text="clientId"/>」を削除しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c1e17956453ad772dbe82d6946f62748c692f3e" datatype="html">
+ <source>Ranks</source>
+ <target>ランク</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b24e0b0b1629d2e8a51b9da7c75d6e6379f4bc4" datatype="html">
+ <source>Standbys</source>
+ <target>スタンバイ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="50df62325726db950523a5be1c78b8905fcc25d4" datatype="html">
+ <source>MDS performance counters</source>
+ <target>MDSパフォーマンスカウンタ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4578796959376778578" datatype="html">
+ <source>Standby daemons</source>
+ <target>スタンバイデーモン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="665219418211496660" datatype="html">
+ <source>Rank</source>
+ <target>ランク</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5445409664838149993" datatype="html">
+ <source>Daemon</source>
+ <target>デーモン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5306473977542913614" datatype="html">
+ <source>Activity</source>
+ <target>アクティビティ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3998441303515229547" datatype="html">
+ <source>Dentries</source>
+ <target>dエントリ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7877631502958415163" datatype="html">
+ <source>Inodes</source>
+ <target>iノード</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6129397096478256985" datatype="html">
+ <source>Dirs</source>
+ <target>ディレクトリ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3011876564696453148" datatype="html">
+ <source>Caps</source>
+ <target>大文字</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8650499415827640724" datatype="html">
+ <source>Type</source>
+ <target>タイプ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="142654590491855672" datatype="html">
+ <source>Usage</source>
+ <target>使用量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">326</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb8293aa8161433778762ae025ffd5e7c85795e" datatype="html">
+ <source>Quotas</source>
+ <target>クォータ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">540</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66785722678644243" datatype="html">
+ <source>Origin</source>
+ <target>元</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8911059720204770105" datatype="html">
+ <source>Path</source>
+ <target>パス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6111756909052789805" datatype="html">
+ <source>Cannot create snapshots for files/folders in the subvolume <x id="PH" equiv-text="folders[2]"/></source>
+ <target>サブボリューム<x id="PH" equiv-text="folders[2]"/>にファイル/フォルダのスナップショットを作成できません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7503263437025060215" datatype="html">
+ <source>Max size</source>
+ <target>最大サイズ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6763343019307619111" datatype="html">
+ <source>Max files</source>
+ <target>最大ファイル数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327403486214540377" datatype="html">
+ <source>The inherited <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> is the maximum value to be used.</source>
+ <target>継承された<x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/>は使用される最大値です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">434,437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3768927257183755959" datatype="html">
+ <source>Save</source>
+ <target>保存</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">440</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6328794256834621774" datatype="html">
+ <source><x id="PH" equiv-text="action"/> CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> quota for '<x id="PH_2" equiv-text="path"/>'</source>
+ <target>「<x id="PH_2" equiv-text="path"/>」の<x id="PH" equiv-text="action"/>CephFS<x id="PH_1" equiv-text="this.getQuotaName()"/>クオータ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">446</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9130352375983418123" datatype="html">
+ <source>size</source>
+ <target>サイズ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6889473896134264260" datatype="html">
+ <source>files</source>
+ <target>ファイル数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2244434638607433133" datatype="html">
+ <source><x id="PH" equiv-text="this.getQuotaName()"/> quota <x id="PH_1" equiv-text="value"/> from '<x id="PH_2" equiv-text="path"/>'</source>
+ <target>「<x id="PH_2" equiv-text="path"/>」からの<x id="PH" equiv-text="this.getQuotaName()"/>クォータ<x id="PH_1" equiv-text="value"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">460</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6960117167304061503" datatype="html">
+ <source>Value has to be at least 0 or more</source>
+ <target>値は少なくとも0以上である必要があります</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">484</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6740501370117796629" datatype="html">
+ <source>Value has to be at most <x id="PH" equiv-text="maxValue"/> or less</source>
+ <target>値は<x id="PH" equiv-text="maxValue"/>以下にする必要があります</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7239750919884229270" datatype="html">
+ <source>Updated</source>
+ <target>更新済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">499</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8885980874806414253" datatype="html">
+ <source>in order to inherit <x id="PH" equiv-text="quotaValue"/></source>
+ <target><x id="PH" equiv-text="quotaValue"/>を継承するため</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4182949309891923991" datatype="html">
+ <source>which isn't used because of the inheritance of <x id="PH" equiv-text="quotaValue"/></source>
+ <target><x id="PH" equiv-text="quotaValue"/>を継承するため使用されていません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7421970649864638435" datatype="html">
+ <source>in order to have no quota on the directory</source>
+ <target>ディレクトリにクォータがないようにするため</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6730229976797004508" datatype="html">
+ <source><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</source>
+ <target><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">530,533</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="827679535246546876" datatype="html">
+ <source>Create Snapshot</source>
+ <target>スナップショットの作成</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">542</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">552</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4747656362969857823" datatype="html">
+ <source>Please enter the name of the snapshot.</source>
+ <target>スナップショットの名前を入力してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3667696812078358068" datatype="html">
+ <source>Created snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <target>「<x id="PH_1" equiv-text="path"/>」のスナップショット「<x id="PH" equiv-text="name"/>」を作成しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="753342836137587734" datatype="html">
+ <source>CephFs Snapshot</source>
+ <target>CephFSスナップショット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">670</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2774104291801979963" datatype="html">
+ <source>Deleted snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <target>「<x id="PH_1" equiv-text="path"/>」のスナップショット「<x id="PH" equiv-text="name"/>」を削除しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">683</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4816216590591222133" datatype="html">
+ <source>Enabled</source>
+ <target>有効化済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ffe39df9d88c972792bd8688b215392deb8313d" datatype="html">
+ <source>Clients</source>
+ <target>クライアント</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e213942c6354b9cbe7a650f0f1499bfc1000fb6" datatype="html">
+ <source>Directories</source>
+ <target>ディレクトリ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fbbaf5cb02ed419e79a27072478f716a4666a99d" datatype="html">
+ <source>Performance Details</source>
+ <target>パフォーマンスの詳細</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0" datatype="html">
+ <source>Description</source>
+ <target>説明</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ad112ce9bcd55dfd137792a86afe1b5a5b13cf8" datatype="html">
+ <source>Long description</source>
+ <target>長い説明</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="26fb5f81b3581f06b9210defb0e71dc69a67e819" datatype="html">
+ <source>Current values</source>
+ <target>現行値</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7cee38a2259526c519f878e71b964f41db4348" datatype="html">
+ <source>Default</source>
+ <target>デフォルト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33e1c1d9fc05ca3f62fcc8a1170fc31ebae4229c" datatype="html">
+ <source>Daemon default</source>
+ <target>デーモンのデフォルト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f61c6867295f3b53d23557021f2f4e0aa1d0b8fc" datatype="html">
+ <source>Type</source>
+ <target>タイプ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9abcd7c82643d60c22733470463f74e4a54bc069" datatype="html">
+ <source>Min</source>
+ <target>最小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3ced4d162a0a55ee233a187ce7208ba5e922418" datatype="html">
+ <source>Max</source>
+ <target>最大</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="920617c6a1a4805e53bcb5af6a9c76f8387e89c6" datatype="html">
+ <source>Flags</source>
+ <target>フラグ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5" datatype="html">
+ <source>Services</source>
+ <target>サービス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6834fa6b43d1ecbdf147c48dd9c4d72f1484571d" datatype="html">
+ <source>Source</source>
+ <target>ソース</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a446fb0eb11fbffcac805ece5a2d306d24e733d8" datatype="html">
+ <source>Level</source>
+ <target>レベル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39f2fb094e9b2eda13163fa3f3a31594cf9c1307" datatype="html">
+ <source>Can be updated at runtime (editable)</source>
+ <target>実行時に更新できます(編集可能)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
+ <source>Tags</source>
+ <target>タグ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ab0089ef47af61ca1d137bc908b96c290dfd9287" datatype="html">
+ <source>Enum values</source>
+ <target>列挙値</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="819476f1264f1659f38e86f6abb542141b184832" datatype="html">
+ <source>See also</source>
+ <target>関連項目</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="543199344025799954" datatype="html">
+ <source>The value can be updated at runtime.</source>
+ <target>この値は実行時に更新できます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1718354829128482129" datatype="html">
+ <source>Daemons/clients do not pull this value from the
+ monitor config database. We disallow setting this option via 'ceph config
+ set ...'. This option should be configured via ceph.conf or via the
+ command line.</source>
+ <target>デーモン/クライアントはこの値をモニター設定データベースから取得しません。
+このオプションを「ceph config set ...」を通じて設定することは禁止されています。
+このオプションは、ceph.confまたはコマンドラインを通じて
+設定する必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">15,18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2345189734548717257" datatype="html">
+ <source>Option takes effect only during daemon startup.</source>
+ <target>オプションはデーモン始動時のみに有効になります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5523310713159993513" datatype="html">
+ <source>Option only affects cluster creation.</source>
+ <target>オプションはクラスタの作成のみに適用されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1064479086902933123" datatype="html">
+ <source>Option only affects daemon creation.</source>
+ <target>オプションはデーモンの作成のみに適用されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="809b0c848932a41318f77a2aace904ef429c13f4" datatype="html">
+ <source>Values</source>
+ <target>値</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5894f7158499fdb89527af50c9f1cf7d4c95cad6" datatype="html">
+ <source>-- Default --</source>
+ <target>-- デフォルト --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="514f6e12d035a6d9b00de6b3e55c18b73488da07" datatype="html">
+ <source>true</source>
+ <target>true</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="774f5e6a183dea08393789b6f72e86afad729419" datatype="html">
+ <source>false</source>
+ <target>false</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="82029b6db704c56a2aa3e82ac555b8655356b077" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>.</source>
+ <target>入力された値は大きすぎます。<x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>より大きい値を入力することはできません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ed8b3967a7326b81b191c9f490006e6a6777a9a" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>.</source>
+ <target>入力された値は小さすぎます。<x id="INTERPOLATION" equiv-text="{{ minValue }}"/>より小さい値を入力することはできません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2337058106409853613" datatype="html">
+ <source>Updated config option <x id="PH" equiv-text="request.name"/></source>
+ <target>設定オプション<x id="PH" equiv-text="request.name"/>を更新しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3733215288982610673" datatype="html">
+ <source>Level</source>
+ <target>レベル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2218082343053095278" datatype="html">
+ <source>Service</source>
+ <target>サービス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3553216189604488439" datatype="html">
+ <source>Modified</source>
+ <target>変更済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844248428439297756" datatype="html">
+ <source>Current value</source>
+ <target>現行値</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208877297843037352" datatype="html">
+ <source>Editable</source>
+ <target>編集可能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b266042bac4c3a2eff4834e40fb9dc4767a709" datatype="html">
+ <source>Cluster Resources</source>
+ <target>クラスタリソース</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="099b441d49333b3c6d30b36dc0a4763e64c78920" datatype="html">
+ <source>Hosts</source>
+ <target>ホスト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57e6e608ece53a26f6d509c90ed4f83e467741af" datatype="html">
+ <source>Storage Capacity</source>
+ <target>ストレージ容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19ece2cb2b9097c0f75af8e62b4b3b25d399a006" datatype="html">
+ <source>Number of devices</source>
+ <target>デバイスの数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b161e3d25fd1b42a781f4e923a58a94925988ddf" datatype="html">
+ <source>Raw capacity</source>
+ <target>未フォーマット時の容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb6f3e2a26f3a6f2bc33f91adcd60502dbe5adac" datatype="html">
+ <source>CPUs</source>
+ <target>CPU</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58d4a9814864741040bc5905b6a368836e683f76" datatype="html">
+ <source>Memory</source>
+ <target>メモリ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dbb81e566a861d4aa0a094366e4083e50863ee92" datatype="html">
+ <source>Host Details</source>
+ <target>ホストの詳細</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="453dc2810080a744223faac6da2b3ee9ed63a583" datatype="html">
+ <source>Welcome to <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/>へようこそ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1eec874e1928ca53baa9914781ce203b5f72b0c" datatype="html">
+ <source>Please expand your cluster first</source>
+ <target>最初にクラスタを拡張してください</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2195fd96b0a00f560449b50bd032e6d9b357730" datatype="html">
+ <source>Expand Cluster</source>
+ <target>クラスタを拡張</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb075d0450deb6f381616f7da4b9244ced843053" datatype="html">
+ <source>Skip</source>
+ <target>スキップ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55b6ce65571b8893440a4fc92776570f8fe7cc97" datatype="html">
+ <source>Add Hosts</source>
+ <target>ホストを追加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="162f763675c24b557a60eba0758558222369e0c7" datatype="html">
+ <source>Create OSDs</source>
+ <target>OSDを作成する</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fef7a7b8db05c351c5287db48488abca530bdb54" datatype="html">
+ <source>Create Services</source>
+ <target>サービスを作成</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="176873b4533ddeabf95992cbd7b91b9d01c6d557" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ed90ec4409b9f6b552982d96f89db27259e763c" datatype="html">
+ <source>You are about to skip the cluster expansion process. You’ll need to <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>navigate through the menu to add hosts and services.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>クラスタ拡張プロセスをスキップしようとしています。<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>メニュー内を移動して、ホストとサービスを追加する<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">90,91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d1dcf2a9146caac0581329acf94806ec69a89a5" datatype="html">
+ <source>Are you sure you want to continue?</source>
+ <target>続行してもよろしいですか?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6759205696902713848" datatype="html">
+ <source>Warning</source>
+ <target>警告</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">357</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6962699013778688473" datatype="html">
+ <source>Continue</source>
+ <target>続行</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6156560100092571435" datatype="html">
+ <source>Cluster expansion skipped by user</source>
+ <target>クラスタ拡張がユーザによってスキップされました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520085823873354736" datatype="html">
+ <source>Cluster expansion was successful</source>
+ <target>クラスタ拡張に成功しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176230351113290618" datatype="html">
+ <source>Expand Cluster</source>
+ <target>クラスタを拡張</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="738de688b22fba5d0dc7a5e549996838dddad0ee" datatype="html">
+ <source>CRUSH map viewer</source>
+ <target>CRUSHマップビューア</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/crushmap/crushmap.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e24569eca61d598c8b01defbbbb1fa8bd5222bc" datatype="html">
+ <source>Devices</source>
+ <target>デバイス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17137bac47e1e020d139256ded0006a671966e73" datatype="html">
+ <source>Physical Disks</source>
+ <target>物理ディスク</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="deba10b7279a589d01e919ea11f43c79ca1773e3" datatype="html">
+ <source>Device health</source>
+ <target>デバイスヘルス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d87fc20ea8e5f0f0500ba5d5061b345be78ec5e" datatype="html">
+ <source>No hostname found.</source>
+ <target>ホスト名が見つかりません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9a541ec1a4319fffc16ad3b3ab2c2b6d251a829d" datatype="html">
+ <source>Hostname</source>
+ <target>ホスト名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee6875e67b53cac30a02b57cf76e485f7e60caf4" datatype="html">
+ <source>To add multiple hosts at once, you can enter:</source>
+ <target>一度に複数のホストを追加するには、次のように入力します。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a8370b19ccf673fb28fa9db36a08f9901887cc7" datatype="html">
+ <source>a comma-separated list of hostnames <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-01,example-02,example-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <target>ホスト名のカンマ区切りリスト<x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(例: example-01,example-02,example-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>、</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="68f2c05396ec8a5f59e8da42d1f6c7310fa8c37c" datatype="html">
+ <source>a range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <target>範囲式<x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(例: example-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>、</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e00b9bba448e79add37740e53dc953fbb89f9c5" datatype="html">
+ <source>a comma separated range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></source>
+ <target>カンマ区切りの範囲式<x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(例: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b3f5e5291541678f7afa49d28fad5ca848a8061" datatype="html">
+ <source>The chosen hostname is already in use.</source>
+ <target>選択されたホスト名はすでに使用されています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="42365f623c57973d1d13d2038e8a2d4c02fb9b9f" datatype="html">
+ <source>Network address</source>
+ <target>ネットワークアドレス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3859bdca1ae89e611e214c205fccf0147b4d0f6b" datatype="html">
+ <source>The value is not a valid IP address.</source>
+ <target>値は有効なIPアドレスではありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2af7efecfae8d7fed3b07f718a623eca1ad8163f" datatype="html">
+ <source>Labels</source>
+ <target>ラベル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9da2afd4fa358b66d4d95fe7e8f4b659a7144e" datatype="html">
+ <source>Maintenance Mode</source>
+ <target>保守モード</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="468785112451259935" datatype="html">
+ <source>There are no labels.</source>
+ <target>ラベルはありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4664081995078497865" datatype="html">
+ <source>Filter or add labels</source>
+ <target>ラベルのフィルタリングまたは追加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4897817053917542646" datatype="html">
+ <source>Add label</source>
+ <target>ラベルの追加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">313</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1187321380561233505" datatype="html">
+ <source>host</source>
+ <target>ホスト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40661476cb24c89d8b06614998e31d5fbe84eeb6" datatype="html">
+ <source>Hosts List</source>
+ <target>ホストリスト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b7a4e1e5a316f8547af1d6d2311a5cec8c5c1d87" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ msg }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ msg }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6e8e8844e9e7a7b626a4699c08b6c0c81297a7b" datatype="html">
+ <source>Data will be available only if Orchestrator is available.</source>
+ <target>Orchestratorが利用できる場合にのみ、データが利用できます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4baf526199fed59071adf555271791283adc408" datatype="html">
+ <source>SSD, NVMEs</source>
+ <target>SSD、NVME</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="22d5531d79f0d7269a0a752e56a848807dd37095" datatype="html">
+ <source>Flash</source>
+ <target>フラッシュ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4025065730478477779" datatype="html">
+ <source>The feature is disabled because the selected host is not managed by Orchestrator.</source>
+ <target>選択したホストがOrchestratorによって管理されていないため、この機能は無効になっています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7143579180750436311" datatype="html">
+ <source>Services</source>
+ <target>サービス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="546766753072101168" datatype="html">
+ <source>Labels</source>
+ <target>ラベル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1141886420788473147" datatype="html">
+ <source>Model</source>
+ <target>モデル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4027647877328291519" datatype="html">
+ <source>CPUs</source>
+ <target>CPU</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2445398473573060226" datatype="html">
+ <source>Cores</source>
+ <target>コア</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1656823484917332451" datatype="html">
+ <source>Total Memory</source>
+ <target>合計メモリ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1939212557812454069" datatype="html">
+ <source>Raw Capacity</source>
+ <target>未フォーマット時の容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5579687933271468638" datatype="html">
+ <source>HDDs</source>
+ <target>HDD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1889285841762768492" datatype="html">
+ <source>Flash</source>
+ <target>フラッシュ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1578709829957887527" datatype="html">
+ <source>NICs</source>
+ <target>NIC</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4723031838495967601" datatype="html">
+ <source>Edit Host: <x id="PH" equiv-text="host.hostname"/></source>
+ <target>ホストの編集: <x id="PH" equiv-text="host.hostname"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6004907173026319041" datatype="html">
+ <source>Edit Host</source>
+ <target>ホストの編集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5618131051466022401" datatype="html">
+ <source>Updated Host &quot;<x id="PH" equiv-text="host.hostname"/>&quot;</source>
+ <target>ホスト「<x id="PH" equiv-text="host.hostname"/>」を更新しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1701954433367210342" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; moved to maintenance</source>
+ <target>「<x id="PH" equiv-text="host.hostname"/>」が保守に移動されました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3108406586869160854" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; cannot be put into maintenance</source>
+ <target>「<x id="PH" equiv-text="host.hostname"/>」は保守できません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1737753151350322492" datatype="html">
+ <source><x id="PH" equiv-text="error.error['detail']"/></source>
+ <target><x id="PH" equiv-text="error.error['detail']"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4054533801359952167" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; has exited maintenance</source>
+ <target>「<x id="PH" equiv-text="host.hostname"/>」は保守を終了しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5837599005212786659" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; stopped draining</source>
+ <target>「<x id="PH" equiv-text="host['hostname']"/>」はドレインを停止しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1357236071975782353" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; started draining</source>
+ <target>「<x id="PH" equiv-text="host['hostname']"/>」はドレインを開始しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5658400717636093668" datatype="html">
+ <source>Identify</source>
+ <target>識別</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6966707768479328825" datatype="html">
+ <source>Device path</source>
+ <target>デバイスパス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3955868613858648955" datatype="html">
+ <source>Available</source>
+ <target>使用可能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="158816374076721379" datatype="html">
+ <source>Vendor</source>
+ <target>ベンダー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6024104799101504292" datatype="html">
+ <source>OSDs</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3422162477846071958" datatype="html">
+ <source>Identify device <x id="PH" equiv-text="device"/></source>
+ <target>デバイス<x id="PH" equiv-text="device"/>の識別</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4910073658089977244" datatype="html">
+ <source>Please enter the duration how long to blink the LED.</source>
+ <target>LEDを点滅させる時間を入力してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5764931367607989415" datatype="html">
+ <source>1 minute</source>
+ <target>1分</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809466133764752509" datatype="html">
+ <source>2 minutes</source>
+ <target>2分</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">235</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1487672983218679675" datatype="html">
+ <source>5 minutes</source>
+ <target>5分</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603584938775296395" datatype="html">
+ <source>10 minutes</source>
+ <target>10分</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6648333117195452824" datatype="html">
+ <source>15 minutes</source>
+ <target>15分</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6560281329999108838" datatype="html">
+ <source>Execute</source>
+ <target>実行</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6901229416977800100" datatype="html">
+ <source>Identifying '<x id="PH" equiv-text="device"/>' started on host '<x id="PH_1" equiv-text="hostname"/>'</source>
+ <target>ホスト「<x id="PH" equiv-text="device"/>」の識別がホスト「<x id="PH_1" equiv-text="hostname"/>」で開始されました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d556ab48a65722b400e497f61737f553ee0f89e2" datatype="html">
+ <source>Cluster Logs</source>
+ <target>クラスタログ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5f966baffd188be0e8adc2d7067b86e55fc9b9de" datatype="html">
+ <source>Audit Logs</source>
+ <target>監査ログ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4193c9eb868aeec119b78a14795241e0aa5e8b60" datatype="html">
+ <source>Priority:</source>
+ <target>優先度:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d78ca51eab260ce3fd917d39190d64df5229b6e" datatype="html">
+ <source>Keyword:</source>
+ <target>キーワード:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="05fa0bded36de6e73a1fa44838b627349dace044" datatype="html">
+ <source>Date:</source>
+ <target>日付:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a400388de1899b1917138cf7e5286376f72847" datatype="html">
+ <source>Time range:</source>
+ <target>時刻の範囲:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="de0478286b8b5a939db54e9e5282405364ad2d61" datatype="html">
+ <source>No log entries found. Please try to select different filter options.</source>
+ <target>ログエントリが見つかりません。別のフィルタオプションを選択してみてください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7479674d91142b785b9547a87e5fb51cb16108" datatype="html">
+ <source>Reset filter.</source>
+ <target>フィルタをリセットします。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="31a9c2870a934b594d1390146c489f76440859ea" datatype="html">
+ <source>Edit Manager module</source>
+ <target>マネージャモジュールの編集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="46e09b8290d3d0afdb6baa2021395b0570606a31" datatype="html">
+ <source>The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</source>
+ <target>入力された値は有効なUUIDではありません(有効なUUIDの例: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7aacd038b39cfd347107d01d1dc27f5cb3e0951c" datatype="html">
+ <source>The entered value needs to be a valid IP address.</source>
+ <target>有効なIPアドレスを入力する必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f19106149f4b07a0d721f9d317afed393cb7bd93" datatype="html">
+ <source>The entered value is too high! It must be lower or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>.</source>
+ <target>入力された値は大きすぎます。<x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>以下の値を入力する必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d33c40ef9a6c3bf0888df831b25e41e65f9d15b" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>.</source>
+ <target>入力された値は小さすぎます。<x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>以上の値を入力する必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eae7086660cf1e38c7194a2c49ff52cc656f90f5" datatype="html">
+ <source>The entered value needs to be a number.</source>
+ <target>数字を入力する必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">194</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a73376e04b4fb3a20734c8c39743fba32e6676ce" datatype="html">
+ <source>The entered value needs to be a number or decimal.</source>
+ <target>数字または小数を入力する必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1898719236268328097" datatype="html">
+ <source>Updated options for module '<x id="PH" equiv-text="this.moduleName"/>'.</source>
+ <target>モジュール「<x id="PH" equiv-text="this.moduleName"/>」のオプションを更新しました。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4186041075388034600" datatype="html">
+ <source>Always-On</source>
+ <target>常にオン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7585826646011739428" datatype="html">
+ <source>Edit</source>
+ <target>編集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2180291763949669799" datatype="html">
+ <source>Enable</source>
+ <target>有効化</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9187855490716817910" datatype="html">
+ <source>Disable</source>
+ <target>無効化</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1600086764852993170" datatype="html">
+ <source>This Manager module is always on.</source>
+ <target>このマネージャモジュールは常にオンになっています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3895296744591223546" datatype="html">
+ <source>Reconnecting, please wait ...</source>
+ <target>再接続していますので、しばらくお待ちください...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81b97b8ea996ad1e4f9fca8415021850214884b1" datatype="html">
+ <source>Status</source>
+ <target>ステータス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57ec6032f5618d4a9f16eb950ad23d2ce7c24b54" datatype="html">
+ <source>Cluster ID</source>
+ <target>クラスタID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67d7facc3fec5f8a49ab9ba0a245872184264ce5" datatype="html">
+ <source>monmap modified</source>
+ <target>monmapが変更されました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4906731aaf2b94b4f547646c9bfe58bb77951b6" datatype="html">
+ <source>monmap epoch</source>
+ <target>monmapエポック</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd4ee06ffdc46d9dfbd0c0c4f81399021c680056" datatype="html">
+ <source>quorum con</source>
+ <target>定数con</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1176c7db8a8276ccb44cc3d42e2c28d9fa6c6596" datatype="html">
+ <source>quorum mon</source>
+ <target>定数mon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="530ef677a09d681b3ab68cb0760494b3ae72a77c" datatype="html">
+ <source>required con</source>
+ <target>必須のcon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a91558e0d506c32021c31843f8f168899fc65cbf" datatype="html">
+ <source>required mon</source>
+ <target>必須のmon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3abe9eac5bcd94a54c8da93b312e085ec512e74" datatype="html">
+ <source>In Quorum</source>
+ <target>定数内</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba4b748a676e1f217ce1e736fb7ec1215e677bae" datatype="html">
+ <source>Not In Quorum</source>
+ <target>非定数内</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3517477838460618200" datatype="html">
+ <source>Public Address</source>
+ <target>パブリックアドレス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6949358970125514744" datatype="html">
+ <source>Open Sessions</source>
+ <target>セッションの開始</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4383e9662ea19839c7499b2128d43a195e564317" datatype="html">
+ <source>OSD creation preview</source>
+ <target>OSD作成プレビュー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="366225c51e0b00bcb1c55795a0dc5e81c455f84e" datatype="html">
+ <source>DriveGroups</source>
+ <target>DriveGroups</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91853167141c37b58868f3b0421383dd72fa8a01" datatype="html">
+ <source>Attributes (OSD map)</source>
+ <target>属性(OSDマップ)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f721a500a68c357e8f2a01e60510f6a01e4ba529" datatype="html">
+ <source>Metadata</source>
+ <target>メタデータ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97842f379e1d4157ac3ab0661b90c352e7cb72d5" datatype="html">
+ <source>Metadata not available</source>
+ <target>メタデータを使用できません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24e28e19c5703d7c6be44f4eb595a6a43b618ed" datatype="html">
+ <source>Performance counter</source>
+ <target>パフォーマンスカウンタ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ccb4f84edc0b4e76415bb3f9b73d725b06683af3" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ name }}"/> devices</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ name }}"/>デバイス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60cb3d01e5ddf266ecb4271007a1c3d0f3efdc22" datatype="html">
+ <source>The primary storage devices. These devices contain all OSD data.</source>
+ <target>プライマリストレージデバイス。これらのデバイスにはすべてのOSDデータが含まれています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b432e04886d0d1fd84f740477383051f85addcf2" datatype="html">
+ <source>Write-Ahead-Log devices. These devices are used for BlueStore’s internal journal. It is only useful to use a WAL device if the device is faster than the primary device (e.g. NVME devices or SSDs). If there is only a small amount of fast storage available (e.g., less than a gigabyte), we recommend using it as a WAL device.</source>
+ <target>Write-Ahead-Logデバイス。これらのデバイスは、BlueStoreの内部ジャーナルに使用されます。WALデバイスを使用するのは、デバイスがプライマリデバイス(NVMEデバイスやSSDなど)より高速である場合にのみ役立ちます。使用可能な高速ストレージが少量(ギガバイト未満など)の場合は、WALデバイスとして使用することをお勧めします。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87e181ab9e8393aa5ed759dd3d53836e32c8ffe" datatype="html">
+ <source>DB devices can be used for storing BlueStore’s internal metadata. It is only helpful to provision a DB device if it is faster than the primary device (e.g. NVME devices or SSD).</source>
+ <target>DBデバイスは、BlueStoreの内部メタデータの保存に使用できます。DBデバイスのプロビジョニングは、プライマリデバイス(NVMEデバイスやSSDなど)より高速である場合にのみ役立ちます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
+ <source>Add</source>
+ <target>追加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="99ee4faa69cd2ea8e3678c1f557c0ff1f05aae46" datatype="html">
+ <source>Clear</source>
+ <target>クリア</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e0fd3c7af0630f93befa6234a693a32a61084e0" datatype="html">
+ <source>Raw capacity: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></source>
+ <target>未フォーマット時の容量: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1961811273151129466" datatype="html">
+ <source>No available devices</source>
+ <target>利用可能なデバイスがありません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617271647728055571" datatype="html">
+ <source>Please add primary devices first</source>
+ <target>最初にプライマリデバイスを追加してください</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6368751795251107516" datatype="html">
+ <source>Add devices by using filters</source>
+ <target>フィルタを使用してデバイスを追加します</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8edc89137d0d8c5667a2f03230beafae45e58429" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> devices</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/>デバイス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eba28e1805b18f7c8ae2e4bc15dcf063b10b3822" datatype="html">
+ <source>At least one of these filters must be applied in order to proceed:</source>
+ <target>続行するには、これらのフィルタの少なくとも1つを適用する必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="93389aa2fe2bea50bf89554ee51b28f87ee2fb50" datatype="html">
+ <source>Number of devices: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Raw capacity: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</source>
+ <target>デバイス数: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>。未フォーマット時の容量: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">29,30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6b27c16ddf33b855412c82069dca8120bd3a68a" datatype="html">
+ <source>Individual OSD Flags</source>
+ <target>個々のOSDフラグ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dba0ed9ba355a3bd3296c0bef3bb518744a51a89" datatype="html">
+ <source>Cluster-wide</source>
+ <target>クラスタ全体</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e2a3f211cea2cbadb29b6df93e544440b6b68d3e" datatype="html">
+ <source>Restore previous selection</source>
+ <target>以前の選択の復元</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1683654169791509804" datatype="html">
+ <source>No Up</source>
+ <target>アップなし</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5754783193519044074" datatype="html">
+ <source>OSDs are not allowed to start</source>
+ <target>OSDを始動することは許可されていません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4413588319909369773" datatype="html">
+ <source>No Down</source>
+ <target>ダウンなし</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1348746748821823470" datatype="html">
+ <source>OSD failure reports are being ignored, such that the monitors will not mark OSDs down</source>
+ <target>OSDの障害レポートは無視されているため、OSDはモニターによってダウンとしてマークされません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="301172600132606646" datatype="html">
+ <source>No In</source>
+ <target>インなし</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4114057962148673377" datatype="html">
+ <source>OSDs that were previously marked out will not be marked back in when they start</source>
+ <target>以前にアウトとしてマークされたOSDは、それらの始動時にインとしてマークされることはありません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5236523991485603657" datatype="html">
+ <source>No Out</source>
+ <target>アウトなし</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1798160169020638994" datatype="html">
+ <source>OSDs will not automatically be marked out after the configured interval</source>
+ <target>OSDは、設定済みの間隔が経過した後に自動的にアウトとしてマークされません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3225813593817914267" datatype="html">
+ <source>The flag has been enabled for the entire cluster.</source>
+ <target>フラグはクラスタ全体で有効になっています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1941050626944682985" datatype="html">
+ <source>Updated OSD Flags</source>
+ <target>OSDフラグを更新しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ef50ba2514414f799d4c8fc36067a251904ba81" datatype="html">
+ <source>Cluster-wide OSD Flags</source>
+ <target>クラスタ全体のOSDフラグ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9042260521669277115" datatype="html">
+ <source>Pause</source>
+ <target>一時停止</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6015425610572318971" datatype="html">
+ <source>Pauses reads and writes</source>
+ <target>読み取りと書き込みを一時停止します</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314873595759611676" datatype="html">
+ <source>No Scrub</source>
+ <target>スクラブなし</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773570234687653570" datatype="html">
+ <source>Scrubbing is disabled</source>
+ <target>スクラブ処理は無効化されています</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5999821123886006899" datatype="html">
+ <source>No Deep Scrub</source>
+ <target>ディープスクラブなし</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5362685148875251772" datatype="html">
+ <source>Deep Scrubbing is disabled</source>
+ <target>ディープスクラブ処理は無効化されています</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5001752039592388485" datatype="html">
+ <source>No Backfill</source>
+ <target>バックフィルなし</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4851280330655956778" datatype="html">
+ <source>Backfilling of PGs is suspended</source>
+ <target>配置グループのバックフィルは中断されています</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5994953210305546559" datatype="html">
+ <source>No Rebalance</source>
+ <target>リバランスなし</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3698980403470604587" datatype="html">
+ <source>OSD will choose not to backfill unless PG is also degraded</source>
+ <target>配置グループも降格されない限り、OSDはバックフィルを選択しません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4334886823145076432" datatype="html">
+ <source>No Recover</source>
+ <target>回復なし</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8465994741155792816" datatype="html">
+ <source>Recovery of PGs is suspended</source>
+ <target>配置グループの回復は中断されています</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4052740759486923001" datatype="html">
+ <source>Bitwise Sort</source>
+ <target>ビット単位のソート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2330377428425572488" datatype="html">
+ <source>Use bitwise sort</source>
+ <target>ビット単位のソートを使用する</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8943478424576832224" datatype="html">
+ <source>Purged Snapdirs</source>
+ <target>消去されたスナップディレクトリ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7553321860087551262" datatype="html">
+ <source>OSDs have converted snapsets</source>
+ <target>OSDによってスナップセットが変換されました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6509988280998256208" datatype="html">
+ <source>Recovery Deletes</source>
+ <target>回復の削除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="451760144355116641" datatype="html">
+ <source>Deletes performed during recovery instead of peering</source>
+ <target>ピアリングの代わりに回復時に削除が実行されました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="87832369463084597" datatype="html">
+ <source>PG Log Hard Limit</source>
+ <target>配置グループログのハード制限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9135782750879343185" datatype="html">
+ <source>Puts a hard limit on pg log length</source>
+ <target>配置グループログ長のハード制限を適用します</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="formTitle" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <note priority="1" from="description">Example: Create Pool</note>
+ <note priority="1" from="meaning">form title</note>
+ </trans-unit>
+ <trans-unit id="43ecf6bee2aebc07b0aad6dc1fe13e38d14687fa" datatype="html">
+ <source>Shared devices</source>
+ <target>共有デバイス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7a1c376f6f1b37de4c318ff2106255ba6c0f5b0b" datatype="html">
+ <source>WAL slots</source>
+ <target>WALスロット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73811a6f37b63e6b0e491e221bfa21e9dea8a87a" datatype="html">
+ <source>How many OSDs per WAL device.</source>
+ <target>WALデバイスごとのOSDの数。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c67a7ac4762ef1cc855056c6b4daab93e53a0a5" datatype="html">
+ <source>Specify 0 to let Orchestrator backend decide it.</source>
+ <target>Orchestratorバックエンドに決定させるには、0を指定してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bda9362e06e6c67341b4a8425b0d29d6b84464b" datatype="html">
+ <source>Value should be greater than or equal to 0</source>
+ <target>値は0以上である必要があります</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="324c2b10152b9dd908222bb0b71f61beb60a30c5" datatype="html">
+ <source>DB slots</source>
+ <target>DBスロット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c23cf12ef9c76f37fc7a4b7ae3e00fb0f68b6e26" datatype="html">
+ <source>How many OSDs per DB device.</source>
+ <target>DBデバイスごとのOSDの数。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8255877266497322342" datatype="html">
+ <source>Encryption</source>
+ <target>暗号化</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b49d7877d24112d4bdfce9256edf61a007fae888" datatype="html">
+ <source>OSDs List</source>
+ <target>OSDリスト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="172ada0fcf6490b24a897517e9f4299215873ff8" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD(s) <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be marked <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <target>続行した場合、<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD<x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>は<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>とマークされます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">59,60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="262a49e60d5f6ed9825582ccf3d5ae39daa1da60" datatype="html">
+ <source>The <x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> not safe to be <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>! <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></source>
+ <target><x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/>を安全に<x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>することはできません。<x id="INTERPOLATION_1" equiv-text="{{ message }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71,72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="74bd20d5f558d14cb2fa41ae863cf09c47d02018" datatype="html">
+ <source>{VAR_SELECT, select, true {OSD is} other {OSDs are}}</source>
+ <target>{VAR_SELECT, select, true {OSD is} other {OSDs are}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0e217fd717c5b1f5c17f00c5b174de855acbef0" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <target>続行した場合は、<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD<x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>は<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">74,75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8cf121660bed7098516a1efe85831d6f415a9411" datatype="html">
+ <source>Preserve OSD ID(s) for replacement.</source>
+ <target>交換用にOSD IDを保持します。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4435645098786961170" datatype="html">
+ <source>out</source>
+ <target>アウト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136018875175606726" datatype="html">
+ <source>in</source>
+ <target>イン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1301930865667956193" datatype="html">
+ <source>down</source>
+ <target>ダウン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1226060325201042854" datatype="html">
+ <source>Mark</source>
+ <target>マーク</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1256299033316818951" datatype="html">
+ <source>OSD lost</source>
+ <target>喪失したOSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2795727560928976873" datatype="html">
+ <source>marked lost</source>
+ <target>喪失としてマーク済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7685933846431786388" datatype="html">
+ <source>Purge</source>
+ <target>消去</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5941516286393808546" datatype="html">
+ <source>OSD</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3416443212235382421" datatype="html">
+ <source>purged</source>
+ <target>消去済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9191368063029792986" datatype="html">
+ <source>destroy</source>
+ <target>破棄</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4425946029386289247" datatype="html">
+ <source>destroyed</source>
+ <target>破棄済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2870788902465061969" datatype="html">
+ <source>Flags</source>
+ <target>フラグ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8995035642420075344" datatype="html">
+ <source>Recovery Priority</source>
+ <target>回復優先度</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3601135996773579607" datatype="html">
+ <source>PG scrub</source>
+ <target>配置グループスクラブ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136079353894161076" datatype="html">
+ <source>Device class</source>
+ <target>デバイスクラス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6382718875453721838" datatype="html">
+ <source>PGs</source>
+ <target>配置グループ数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3660230483843323377" datatype="html">
+ <source>Read bytes</source>
+ <target>読み取りバイト数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">329</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3909578649547040612" datatype="html">
+ <source>Write bytes</source>
+ <target>書き込みバイト数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3182358405280886750" datatype="html">
+ <source>Read ops</source>
+ <target>読み取り操作数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171292502535561083" datatype="html">
+ <source>Write ops</source>
+ <target>書き込み操作数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6706824709967518168" datatype="html">
+ <source>Edit OSD: <x id="PH" equiv-text="selectedOsd.id"/></source>
+ <target>OSDの編集: <x id="PH" equiv-text="selectedOsd.id"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">451</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1125148356983553148" datatype="html">
+ <source>Edit OSD</source>
+ <target>OSDの編集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="970212458427610374" datatype="html">
+ <source>Updated OSD '<x id="PH" equiv-text="selectedOsd.id"/>'</source>
+ <target>OSD「<x id="PH" equiv-text="selectedOsd.id"/>」を更新しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">466</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7554728686176829307" datatype="html">
+ <source>Mark OSD <x id="PH" equiv-text="markAction"/></source>
+ <target>OSD<x id="PH" equiv-text="markAction"/>をマーク</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="478122291463667978" datatype="html">
+ <source>Mark <x id="PH" equiv-text="markAction"/></source>
+ <target><x id="PH" equiv-text="markAction"/>をマーク</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">502</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2456043080471762298" datatype="html">
+ <source>delete</source>
+ <target>削除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">530</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="588230151780724018" datatype="html">
+ <source>deleted</source>
+ <target>削除済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">532</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1ef1c12ddcee305353623919ef02778569f5454" datatype="html">
+ <source>Advanced configuration options</source>
+ <target>高度な設定オプション</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7771252117308888928" datatype="html">
+ <source>PG scrub options</source>
+ <target>配置グループスクラブオプション</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1797901277775175680" datatype="html">
+ <source>Updated PG scrub options</source>
+ <target>配置グループスクラブオプションを更新しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c35f9c5f268a514b970cc55e9a5dc4bed0988e7f" datatype="html">
+ <source>OSD Recovery Priority</source>
+ <target>OSD回復優先度</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74af38005e8a8914e45af2ec412e11ceafef8b6" datatype="html">
+ <source>Priority</source>
+ <target>優先度</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f48f04b379bfba133825747adfd238d511412e" datatype="html">
+ <source>Customize priority values</source>
+ <target>優先度値のカスタマイズ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aa19de2a2b54cbda39e9c62917b23044c087776" datatype="html">
+ <source>This field is required!</source>
+ <target>このフィールドは必須です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">406</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b699e94bf376491bd50b70a98531071c737eaf40" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="98fe13e7ad6c2b80375d204b47858ded83f80e15" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>.</source>
+ <target>入力された値は大きすぎます。<x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>より大きい値を入力することはできません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423a3c111be47fc5a1bfe46ceb58c81c84db691" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>.</source>
+ <target>入力された値は小さすぎます。<x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>より小さい値を入力することはできません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3234179038052466481" datatype="html">
+ <source>Max Backfills</source>
+ <target>最大バックフィル数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847070960491384020" datatype="html">
+ <source>Recovery Max Active</source>
+ <target>回復最大アクティブ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2088615724570210504" datatype="html">
+ <source>Recovery Max Single Start</source>
+ <target>回復最大単一始動</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8627094894361422565" datatype="html">
+ <source>Recovery Sleep</source>
+ <target>回復スリープ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7590013429208346303" datatype="html">
+ <source>Custom</source>
+ <target>カスタム</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4937275625032609020" datatype="html">
+ <source>Updated OSD recovery speed priority '<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>'</source>
+ <target>OSDの回復速度優先度「<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>」を更新しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">227,229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5251a4355cece3075db43f15d69a24a0f8485707" datatype="html">
+ <source>Reweight OSD: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></source>
+ <target>再重みづけOSD: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67650b2998db48201b2c6176cbfef51e7211ccaa" datatype="html">
+ <source>The value needs to be between 0 and 1.</source>
+ <target>値は0と1の間である必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f077ceb52c967a8fe2de9ef0a9d65d72badf186" datatype="html">
+ <source>OSDs <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/>Scrub</source>
+ <target>OSD <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/>スクラブ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b73a34ba65b3073e3560dce828a16d7fd3c0f4" datatype="html">
+ <source>{VAR_SELECT, select, true {Deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {Deep } other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c00119503aad4012b77049eee41293338f67756c" datatype="html">
+ <source>You are about to apply a <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/>scrub to the OSD(s): <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <target><x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/>スクラブをOSD <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>に適用しようとしています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fad3dc421817a16dd6c46c1a0c36de619a8d776e" datatype="html">
+ <source>{VAR_SELECT, select, true {deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {deep } other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1086427836866943370" datatype="html">
+ <source><x id="PH" equiv-text="operation"/> was initialized in the following OSD(s): <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></source>
+ <target><x id="PH" equiv-text="operation"/>は次のOSDで初期化されました: <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts</context>
+ <context context-type="linenumber">42,44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47c97aa28f64b11fa5842795fdd02c8c0863c97b" datatype="html">
+ <source>To see all active Prometheus alerts, please provide the URL to the API of Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>すべてのアクティブなPrometheusアラートを表示するには、<x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>の説明に従って、PrometheusのAlertmanagerのAPIにURLを提供してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6343323763459782070" datatype="html">
+ <source>Create Silence</source>
+ <target>サイレンスの作成</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1895957424873987405" datatype="html">
+ <source>Job</source>
+ <target>ジョブ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491474782694268231" datatype="html">
+ <source>Severity</source>
+ <target>重大度</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3326877877555410533" datatype="html">
+ <source>Started</source>
+ <target>始動済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2375260419993138758" datatype="html">
+ <source>URL</source>
+ <target>URL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="880ad4df5a2051a437321443d69c9a866699e5ad" datatype="html">
+ <source>Active Alerts</source>
+ <target>有効なアラート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9fe218829514884cdd0ca2300573a4e0428c324f" datatype="html">
+ <source>Alerts</source>
+ <target>アラート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa0c44aa1e5727061baa91e954f77e2f5f9a37c9" datatype="html">
+ <source>Silences</source>
+ <target>サイレンス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85c737325f5e59517e2d08a71de6d77788aabc95" datatype="html">
+ <source>To see all configured Prometheus alerts, please provide the URL to the API of Prometheus as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>すべての設定済みのPrometheusアラートを表示するには、<x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>の説明に従って、PrometheusのAPIにURLを提供してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623978917681527907" datatype="html">
+ <source>Group</source>
+ <target>グループ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7410432243549869948" datatype="html">
+ <source>Duration</source>
+ <target>期間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4109205891084963566" datatype="html">
+ <source>Query</source>
+ <target>クエリ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28f86ffd419b869711aa13f5e5ff54be6d70731c" datatype="html">
+ <source>Edit</source>
+ <target>編集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="826b25211922a1b46436589233cb6f1a163d89b7" datatype="html">
+ <source>Delete</source>
+ <target>削除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">279</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">341</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">441</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3ba06aba047605af8ea1718ec1ba153b7db12a2" datatype="html">
+ <source>Editing a silence will expire the old silence and recreate it as a new silence</source>
+ <target>サイレンスを編集すると、古いサイレンスが期限切れになり、新しいサイレンスとして再作成されます</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a20424156b8816671f61879f0574a4f27d7b16b9" datatype="html">
+ <source>Creator</source>
+ <target>作成者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5a5d7ee2acbfa9c91ab7f41d26bda9ff0cafe42f" datatype="html">
+ <source>Comment</source>
+ <target>コメント</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c11aad490b2d53fdae30b3807beabf79306752c" datatype="html">
+ <source>Start time</source>
+ <target>開始時刻</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32856b1e8e339b747b21e313e2fe65a51fd450bb" datatype="html">
+ <source>If the start time lies in the past the creation time will be used</source>
+ <target>開始時刻が過去の場合は作成時刻が使用されます</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a02ea1d4e7424ca989929da5e598f379940fdbf2" datatype="html">
+ <source>Duration</source>
+ <target>期間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f4e35e36f4d3c62e2c17df41730b6dee4afc4b9" datatype="html">
+ <source>End time</source>
+ <target>終了時刻</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="992123459137d45c15df5548bc9682aad835c04b" datatype="html">
+ <source>Matchers</source>
+ <target>マッチャー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e023166c55833d5a13f4143e3dbe372befe1b4e" datatype="html">
+ <source>A silence requires at least one matcher</source>
+ <target>サイレンスには少なくとも1つのマッチャーが必要です</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef765bd80c4806c51c891908c07a24bc76f019eb" datatype="html">
+ <source>Add matcher</source>
+ <target>マッチャーの追加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754178820914251524" datatype="html">
+ <source>silence</source>
+ <target>サイレンス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8714559758543060819" datatype="html">
+ <source>Attribute name</source>
+ <target>属性名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1338733395833138319" datatype="html">
+ <source>Regular expression</source>
+ <target>正規表現</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35819898450851998" datatype="html">
+ <source>Please add your Prometheus host to the dashboard configuration and refresh the page</source>
+ <target>ダッシュボード設定にPrometheusホストを追加して、ページを更新してください</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f2f4cb9d876ff9d34fc082c1ac642d3cb98c360" datatype="html">
+ <source>To enable Silences, please provide the URL to the API of the Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>サイレンスを有効にするには、<x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>の説明に従ってPrometheusのAlertmanagerのAPIにURLを提供してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7448808151142843482" datatype="html">
+ <source>Created by</source>
+ <target>作成者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4734349318830134239" datatype="html">
+ <source>Ends</source>
+ <target>終了</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1233087251567318644" datatype="html">
+ <source>Silence</source>
+ <target>サイレンス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="78af6a5e6e4d305557054b64d10f9f9446d8043d" datatype="html">
+ <source>{VAR_SELECT, select, true {Edit} other {Add}}</source>
+ <target>{VAR_SELECT, select, true {Edit} other {Add}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2404fa8e80946d0ce3d0ae369b51cb26ec28d42" datatype="html">
+ <source><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/> Matcher</source>
+ <target><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/>マッチャー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c25e04f554875dc2625a78ba0fc56c6010cd0d3" datatype="html">
+ <source>-- Select an attribute to match against --</source>
+ <target>-- 一致する属性を選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5049e204c14c648691ac775a64fb504467aeb549" datatype="html">
+ <source>Value</source>
+ <target>値</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="77fc5c63497fc031ddc97645484e3d94ad27766c" datatype="html">
+ <source>Use regular expression</source>
+ <target>正規表現を使う</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5518753745858598442" datatype="html">
+ <source>no spec</source>
+ <target>仕様なし</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1186363766752354382" datatype="html">
+ <source>unmanaged</source>
+ <target>管理対象外</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5246585784774990516" datatype="html">
+ <source>count:<x id="PH" equiv-text="count"/></source>
+ <target>カウント: <x id="PH" equiv-text="count"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001661117318762535" datatype="html">
+ <source>label:<x id="PH" equiv-text="label"/></source>
+ <target>ラベル: <x id="PH" equiv-text="label"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cb3aa7e9fea1d445a1a9d7797ab17e6ac6fe13b" datatype="html">
+ <source>Service Events</source>
+ <target>サービスイベント</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3474944817987674409" datatype="html">
+ <source>Daemon type</source>
+ <target>デーモンタイプ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3136939605470297323" datatype="html">
+ <source>Daemon ID</source>
+ <target>デーモンID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8171022601808215887" datatype="html">
+ <source>Container ID</source>
+ <target>コンテナID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8859473568390700297" datatype="html">
+ <source>Container Image name</source>
+ <target>コンテナイメージ名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5623167616584404899" datatype="html">
+ <source>Container Image ID</source>
+ <target>コンテナイメージID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="335348913532561915" datatype="html">
+ <source>Last Refreshed</source>
+ <target>最終更新日時</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3022087209429182774" datatype="html">
+ <source>Daemon Events</source>
+ <target>デーモンイベント</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">140</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8604852007710946848" datatype="html">
+ <source>Service Name</source>
+ <target>サービス名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="613875387304159316" datatype="html">
+ <source>Service Type</source>
+ <target>サービスタイプ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907644935670421963" datatype="html">
+ <source>Service Events</source>
+ <target>サービスイベント</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3214a1f3a4c3e89a848b4ec59adeeda3b913c396" datatype="html">
+ <source>-- Select a service type --</source>
+ <target>-- サービスタイプを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f32579a9fd19d93c083175284ee3426d78751c33" datatype="html">
+ <source>Backend Service</source>
+ <target>バックエンドサービス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2937074aed12b8158e929c58747a8216433b72b" datatype="html">
+ <source>-- No service available --</source>
+ <target>-- 使用可能なサービスがありません --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19fb4480d95a5539db4e9c7b516d414774e61110" datatype="html">
+ <source>-- Select an existing RGW service --</source>
+ <target>-- 既存のRGWサービスを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2798cc1e152b1ec07fd8daf94a2a073d1ba1ebcc" datatype="html">
+ <source>Id</source>
+ <target>Id</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d5156b9d9a79d162c353c4aa9bc6840ad5c6257" datatype="html">
+ <source>The value does not match the pattern <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&lt;service_id&gt;[.&lt;realm_name&gt;.&lt;zone_name&gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <target>値がパターン<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&amp;lt;service_id&amp;gt;[.&amp;lt;realm_name&amp;gt;.&amp;lt;zone_name&amp;gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>と一致しません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83d5d7edd8a0be253c4e93ad4c3efe86d9ac520f" datatype="html">
+ <source>Unmanaged</source>
+ <target>管理対象外</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c15fa461935e0f600bc5d1660af1da67f024fc2a" datatype="html">
+ <source>Placement</source>
+ <target>配置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="863226cffd5b66a6fee9810a9282a5006d6ef576" datatype="html">
+ <source>Label</source>
+ <target>ラベル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06412bce0f4fe4311193e9763666089bf9d980da" datatype="html">
+ <source>Count</source>
+ <target>カウント</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f193722f1e788f14a823b89ac1794c3ba934f9f" datatype="html">
+ <source>Only that number of daemons will be created.</source>
+ <target>その数のデーモンのみが作成されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee1a29cc658e4fa891be762d7bae96139b57c8f4" datatype="html">
+ <source>The value must be at least 1.</source>
+ <target>値は1以上にする必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">369</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cb2741a46e3560f6bc6dfd99d385e86b08b26d72" datatype="html">
+ <source>Port</source>
+ <target>ポート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a23ed3598cca5285606675b6cb2536a56b411ade" datatype="html">
+ <source>The value cannot exceed 65535.</source>
+ <target>値は65535を超えることはできません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">404</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d8ebdc326e6b9ff35feee3f762b7ab39c02d78f" datatype="html">
+ <source>-- No pools available --</source>
+ <target>-- 使用可能なポートがありません --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84b675705324741b954615fedf2417d4d873b0b6" datatype="html">
+ <source>Trusted IPs</source>
+ <target>信頼されたIP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b543e7c787cc48c2938cbce2d14c6afea5a598df" datatype="html">
+ <source>Comma separated list of IP addresses.</source>
+ <target>IPアドレスのカンマ区切りリスト。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1039ea40da18a6453d9c1adc72a35aed099029d0" datatype="html">
+ <source>Please add the <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> IP addresses here, otherwise the iSCSI gateways can't be reached.</source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> IPアドレスをここに追加してください。追加しないと、iSCSIゲートウェイに到達できません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6265b64c17a1e19775769489bfd0b152fa1f3ba1" datatype="html">
+ <source>Virtual IP</source>
+ <target>仮想IP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61893fde6e9e05a6b91619d501edaa7962b438ff" datatype="html">
+ <source>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</source>
+ <target>入力サービスが使用可能になる仮想IPアドレスとサブネット(CIDR表記)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">333</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ece04ddf7e96f445415ebd90d93c455e03e8cf53" datatype="html">
+ <source>Frontend Port</source>
+ <target>フロントエンドポート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">352</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae6fd97454d184b374984c9ff808176ece54f0dd" datatype="html">
+ <source>The port used to access the ingress service.</source>
+ <target>入力サービスへのアクセスに使用されるポート。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1261eacf161f75efc9dfea84dd97b4a466b89aa1" datatype="html">
+ <source>Monitor Port</source>
+ <target>モニターポート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4df6281ed630ba96f09790a46a7fe0ec0e666bb6" datatype="html">
+ <source>The port used by haproxy for load balancer status.</source>
+ <target>ロードバランサの状態のためにhaproxyが使用するポート。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ce24ae1d792ed2846ba57e7ed6397a802caeff5" datatype="html">
+ <source>CIDR Networks</source>
+ <target>CIDRネットワーク</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">414</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7c13184af0c09e3bad77daa5f4869138708d26b2" datatype="html">
+ <source>A list of networks to identify which network interface to use for the virtual IP address.</source>
+ <target>仮想IPアドレスに使用するネットワークインターフェイスを識別するためのネットワークのリスト。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8fe73a4787b8068b2ba61f54ab7e0f9af2ea1fc9" datatype="html">
+ <source>Version</source>
+ <target>バージョン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a6855d17f6b9820bb9709870efdcc7da99552d3" datatype="html">
+ <source>-- Select SNMP version --</source>
+ <target>-- SNMPバージョンを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">442</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a7369891e88cd613e45a39b55a282c97776d05f5" datatype="html">
+ <source>Destination</source>
+ <target>宛先</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f09a5d334a73a4b5ba031d7fa65151cad5ec7133" datatype="html">
+ <source>Must be of the format hostname:port.</source>
+ <target>hostname:portの形式にする必要があります</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b68c79ffe3af1db88180454fbc2fa880a51ccf52" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>hostname:port<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>値がパターン<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>hostname:port<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>と一致しません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">470</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c90ad98a026d781ab729911873767e549d78f99" datatype="html">
+ <source>Engine Id</source>
+ <target>エンジンID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">478</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d39d015ebd667fb6bddf08bb0e5b3faa6cf044c" datatype="html">
+ <source>Unique identifier for the device (in hex).</source>
+ <target>デバイスの固有の識別子(16進数)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">480</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514cda7dc49062c5c532427245ce47c4954bc32" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>値がパターン<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>と一致しません。16進数で指定し、長さは2の倍数で、最小値は10および最大値は64にする必要があります。<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b2d628c51192ade0044212b409c758c20f9c021" datatype="html">
+ <source>Auth Protocol</source>
+ <target>認証プロトコル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc8bb2315a5101770a752b18e03b5c730539397c" datatype="html">
+ <source>-- Select auth protocol --</source>
+ <target>-- 認証プロトコルを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">508</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6777f99fd13e03874afe26ba7289dc9fc211af04" datatype="html">
+ <source>Privacy Protocol</source>
+ <target>プライバシープロトコル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70512b7c13bce85b3928920b29fafbd59a853383" datatype="html">
+ <source>-- Select privacy protocol --</source>
+ <target>-- プライバシープロトコルを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b48c81465d14465b95826b99e05acfabef1814c6" datatype="html">
+ <source>Credentials</source>
+ <target>資格情報</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">541</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4ea0163c25c818aab982072b1b8d5ab585e9a5a" datatype="html">
+ <source>SNMP Community</source>
+ <target>SNMPコミュニティ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">547</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="08c74dc9762957593b91f6eb5d65efdfc975bf48" datatype="html">
+ <source>Username</source>
+ <target>ユーザ名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="948758e1412bb2ecdb98e3a4f1cbb6d7458456f2" datatype="html">
+ <source>Encryption</source>
+ <target>暗号化</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">598</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e65610b5d940367f1ff6b57772b96e94e35fe202" datatype="html">
+ <source>SSL</source>
+ <target>SSL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">624</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e37e0d06148c7708e88b4a1eb412babbe1a4afc" datatype="html">
+ <source>Certificate</source>
+ <target>証明書</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">634</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="295ae4f632322098deca8a3ddfbc7aeaabb5423b" datatype="html">
+ <source>The SSL certificate in PEM format.</source>
+ <target>PEM形式のSSL証明書。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">635</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464272c069fe56f6c50f41f426a25b2a42c95ba5" datatype="html">
+ <source>Invalid SSL certificate.</source>
+ <target>SSL証明書が無効です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">650</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0596d06bf1f8a15d4bfe56226971ecdd78013b1f" datatype="html">
+ <source>Private key</source>
+ <target>秘密鍵</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">659</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ded15dc55104994c0230189f34dff84a4955aafb" datatype="html">
+ <source>The SSL private key in PEM format.</source>
+ <target>PEM形式のSSL秘密鍵。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">660</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19bdc1597d815b456793ff87c89af4257a85a103" datatype="html">
+ <source>Invalid SSL private key.</source>
+ <target>SSL秘密鍵が無効です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">675</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3356018487523380058" datatype="html">
+ <source>service</source>
+ <target>サービス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2412938991511187011" datatype="html">
+ <source>There are no hosts.</source>
+ <target>ホストはありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2594503755408511486" datatype="html">
+ <source>Filter hosts</source>
+ <target>ホストのフィルタリング</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5869780110608474933" datatype="html">
+ <source>Placement</source>
+ <target>配置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2956098160626271284" datatype="html">
+ <source>Running</source>
+ <target>実行中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="013f48ee777d2e53e2bcba36e1a99fcbb7ef8cb6" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report configuration</source>
+ <target>ステップ<x id="INTERPOLATION" equiv-text="{{ step }}"/>/2: テレメトリレポートの設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a09b723a928774bff707973c99999dcf3d84a349" datatype="html">
+ <source>The telemetry module sends anonymous data about this Ceph cluster back to the Ceph developers to help understand how Ceph is used and what problems users may be experiencing.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> This data is visualized on <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>public dashboards<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> that allow the community to quickly see summary statistics on how many clusters are reporting, their total capacity and OSD count, and version distribution trends.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> The data being reported does <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>not<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> contain any sensitive data like pool names, object names, object contents, hostnames, or device serial numbers. It contains counters and statistics on how the cluster has been deployed, the version of Ceph, the distribution of the hosts and other parameters which help the project to gain a better understanding of the way Ceph is used. The data is sent secured to <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> and <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (device report).</source>
+ <target>テレメトリモジュールは、このCephクラスタに関する匿名データをCeph開発者に送信します。これは、Cephの使用方法とユーザが直面している可能性のある問題を理解するのに役立ちます。<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/>このデータは、<x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>パブリックダッシュボード<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>に視覚化され、これにより、コミュニティは、報告しているクラスタの数、合計容量、OSD数、バージョン配布トレンドに関するサマリ統計をすばやく確認できます。<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/>報告されるデータにはプール名、オブジェクト名、オブジェクトの内容、ホスト名、デバイスのシリアル番号などの機密データは含まれて<x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>いません<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/>。これには、クラスタの展開方法、Cephのバージョン、ホストの分布、およびプロジェクトがCephの使用方法をよりよく理解するのに役立つその他のパラメータに関するカウンタと統計が含まれています。データは<x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/>と<x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/>(デバイスレポート)にセキュリティ保護されて送信されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">14,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c95505b5a74151a0c235b19b9c41db7983205ba7" datatype="html">
+ <source>Deactivate</source>
+ <target>無効にする</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19" datatype="html">
+ <source>Channels</source>
+ <target>チャネル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e25b17c0b4ef361b6a05aaec2bbd2b7e86680458" datatype="html">
+ <source>The telemetry report is broken down into several &quot;channels&quot;, each with a different type of information that can be configured below.</source>
+ <target>テレメトリレポートはいくつかの「チャネル」に分割され、それぞれに以下で設定可能な異なるタイプの情報が含まれています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">32,33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380ab580741bec31346978e7cab8062d6970408d" datatype="html">
+ <source>Basic</source>
+ <target>基本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd898057f0add35258a5fb5c90d792c5e2147452" datatype="html">
+ <source>Includes basic information about the cluster:</source>
+ <target>クラスタに関する基本情報が含まれます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da213e9ba8a86b453d04f794f58c9803f7b062b1" datatype="html">
+ <source>Capacity of the cluster</source>
+ <target>クラスタの容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d5fe31d9e13239bdd223d0bbd289a1b1903e86" datatype="html">
+ <source>Number of monitors, managers, OSDs, MDSs, object gateways, or other daemons</source>
+ <target>モニター、マネージャ、OSD、MDS、オブジェクトゲートウェイ、またはその他のデーモンの数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a3eb7834b4baf412f8863d14883972897d9acb7" datatype="html">
+ <source>Software version currently being used</source>
+ <target>現在使用されているソフトウェアバージョン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34881ae65482ffa74ccb4043fb2622e48ed146d5" datatype="html">
+ <source>Number and types of RADOS pools and CephFS file systems</source>
+ <target>RADOSプールおよびCephFSファイルシステムの数とタイプ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="696f8f5ea7a9cf6125b9a3af160981fda363552d" datatype="html">
+ <source>Names of configuration options that have been changed from their default (but not their values)</source>
+ <target>デフォルトから変更された設定オプションの名前(値ではない)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34292940316300d09abe5e675d452fae199f626b" datatype="html">
+ <source>Crash</source>
+ <target>クラッシュ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7620e332b7dea1e832158e85847255eb4d9e6bbc" datatype="html">
+ <source>Includes information about daemon crashes:</source>
+ <target>デーモンクラッシュに関する情報が含まれます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1aa4306a6e840fe35b70c9b07d38ce85f281cfa" datatype="html">
+ <source>Type of daemon</source>
+ <target>デーモンのタイプ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4f2cbedb4b14b68bc9f390e3391445c1b6682da" datatype="html">
+ <source>Version of the daemon</source>
+ <target>デーモンのバージョン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d62603cdc75645ea873fc8f7f69c32b5f4a2aa9" datatype="html">
+ <source>Operating system (OS distribution, kernel version)</source>
+ <target>オペレーティングシステム(OS配布、カーネルバージョン)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84facf84a73631d66e9a4e0bc1c40097b9d14742" datatype="html">
+ <source>Stack trace identifying where in the Ceph code the crash occurred</source>
+ <target>Cephコードのどこでクラッシュが発生したかを特定するスタックトレース</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea64d4177bd648e1a20c92669e6857762b811d8c" datatype="html">
+ <source>Device</source>
+ <target>デバイス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4bc37bcbbcea881a269b4063b3d93dec8ee67d5" datatype="html">
+ <source>Includes information about device metrics like anonymized SMART metrics.</source>
+ <target>匿名化されたSMARTメトリックなどのデバイスメトリックに関する情報が含まれます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37de70e8ba539187d0171a38dad2a63c323096eb" datatype="html">
+ <source>Ident</source>
+ <target>Ident</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b126025440f118cd02ce78362d61a5001c27617" datatype="html">
+ <source>Includes user-provided identifying information about the cluster:</source>
+ <target>クラスタに関するユーザ提供の識別情報が含まれます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62c6e9aecff7e04ef7d36fdee4ab4fb285a7a2b5" datatype="html">
+ <source>Contact Information</source>
+ <target>連絡先データ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61ba9a84051b3f470122e59cf5a746552b378269" datatype="html">
+ <source>Submitting any contact information is completely optional and disabled by default.</source>
+ <target>連絡先データの送信は完全にオプションで、デフォルトで無効になっています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34746fb1c7f3d2194d99652bdff89e6e14c9c4f4" datatype="html">
+ <source>Contact</source>
+ <target>連絡先</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="632cac1e025b77b2d77fed16ad22a410ddacab9e" datatype="html">
+ <source>My first Ceph cluster</source>
+ <target>初のCephクラスタ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3a58c8a81b9ffda26a154eae25a422c9f7de37b" datatype="html">
+ <source>Organization</source>
+ <target>組織</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e8fda44e2c5bb51860f26cd9c2730f9ae1db9869" datatype="html">
+ <source>Organization name</source>
+ <target>組織名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d49310535abb3792d8c9c991dd0d990d73d29af" datatype="html">
+ <source>Interval</source>
+ <target>間隔</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91317562c9dfefbdd5973faf11d217f571d073c7" datatype="html">
+ <source>The module compiles and sends a new report every 24 hours by default. You can adjust this interval by setting a different number of hours.</source>
+ <target>モジュールは、デフォルトで24時間ごとに新しいレポートをコンパイルして送信します。別の時間数を設定することで、この間隔を調整できます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">185,186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a12cf4cf71ef3161a024382ab542cf0eba094504" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to 8.</source>
+ <target>入力された値は小さすぎます。8以上の値を入力する必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a92e437fac14b4010c4515b31c55a311d026a57f" datatype="html">
+ <source>Proxy</source>
+ <target>プロキシ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6de03357358c7eff62aca486508bb5c2046e0669" datatype="html">
+ <source>If the cluster cannot directly connect to the configured telemetry endpoint (default telemetry.ceph.com), you can configure a HTTP/HTTPS proxy server by e.g. adding https://10.0.0.1:8080</source>
+ <target>クラスタが設定済みのテレメトリエンドポイント(デフォルトのtelemetry.ceph.com)に直接接続できない場合、https://10.0.0.1:8080を追加するなどして、HTTP/HTTPSプロキシサーバを設定できます</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5687a733af051bfca97dbffba282e39fbb9b8c8f" datatype="html">
+ <source>You can also include a user:pass if needed e.g. https://ceph:telemetry@10.0.0.1:8080</source>
+ <target>必要に応じてuser:passを含めることもできます。例: https://ceph:telemetry@10.0.0.1:8080</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e6430c68df43ea65e4145972b01186fba40f26a" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Note:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> By clicking 'Next' you will first see a preview of the report content before you can activate the automatic submission of your data.</source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>メモ:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> [次へ]をクリックすると、データの自動送信を有効にする前に、最初にレポートコンテンツのプレビューが表示されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">219,220</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d8d878f8d60905e1306c225716305a331b784c8" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report preview</source>
+ <target>ステップ<x id="INTERPOLATION" equiv-text="{{ step }}"/>/2: テレメトリレポートのプレビュー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e23d0064b6474f309c74e1c928cc0920f479d9a5" datatype="html">
+ <source>Report ID <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <target>レポートID <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">249,252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4060e92658964e356a0992a900c8aa811c2cfec0" datatype="html">
+ <source>A randomized UUID to identify a particular cluster over the course of several telemetry reports.</source>
+ <target>いくつかのテレメトリレポートの過程で特定のクラスタを識別するためのランダム化されたUUID。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60900bc663571f852a04950a123508b106d97204" datatype="html">
+ <source>Report preview <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <target>レポートプレビュー <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">267,270</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3de417f739c336284c42904552e81e8d852daecc" datatype="html">
+ <source>The actual telemetry data that will be submitted.</source>
+ <target>送信される実際のテレメトリデータ。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="933a2b6f087670ff42c95876e6ecfb2faa3e3867" datatype="html">
+ <source>I agree to my telemetry data being submitted under the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Community Data License Agreement - Sharing - Version 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></source>
+ <target><x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Community Data License Agreement - Sharing - Version 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>に基づいて送信されるテレメトリデータに同意します</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">304</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8293060085588842566" datatype="html">
+ <source>The Telemetry module has been configured and activated successfully.</source>
+ <target>テレメトリモジュールが設定され、正常に有効化されました。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5380636888677486786" datatype="html">
+ <source>An Error occurred while updating the Telemetry module configuration. Please Try again</source>
+ <target>テレメトリ モジュール設定の更新中にエラーが発生しました。 もう一度お試しください</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2bcd3296d2850de762fb943060b7e086a893181" datatype="html">
+ <source>Health</source>
+ <target>ヘルス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61e0f26d843eec0b33ff475e111b0c2f7a80b835" datatype="html">
+ <source>Statistics</source>
+ <target>統計情報</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73caac4265ea7314ff061e5a1d78a6361a6dd3b8" datatype="html">
+ <source>Cluster Status</source>
+ <target>クラスタのステータス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="624f596cc3320f5e0a0d7c7346c364e5af9bdd8c" datatype="html">
+ <source>Monitors</source>
+ <target>モニター</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9183778f2c6473d7ccb080f651caa01faaf70c" datatype="html">
+ <source>OSDs</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c34287a0423968dac8a41463b80855a0ff789403" datatype="html">
+ <source>Managers</source>
+ <target>マネージャ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="946ac5dea9921dc09d7b0a63b89535371f283b19" datatype="html">
+ <source>Object Gateways</source>
+ <target>オブジェクトゲートウェイ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff03fa5bcf37c4da46ad736c1f7d03f959e8ba9a" datatype="html">
+ <source>Metadata Servers</source>
+ <target>メタデータサーバ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d817609ba4993eba859409ab71e566168f4d5f5a" datatype="html">
+ <source>iSCSI Gateways</source>
+ <target>iSCSIゲートウェイ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ce9dfdc6dccb28dc75a78c704e09dc18fb02dcfa" datatype="html">
+ <source>Capacity</source>
+ <target>容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f383269db2d32cccee9e936fe549dccb9fdbf4" datatype="html">
+ <source>Raw Capacity</source>
+ <target>未フォーマット時の容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498a109c6e9e94f1966de01aa0326f7f0ac6fb52" datatype="html">
+ <source>PG Status</source>
+ <target>配置グループのステータス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5f8a813f91a11af99132e4beafc136cfc13d73b" datatype="html">
+ <source>PGs per OSD</source>
+ <target>OSDあたりの配置グループ数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32efd1c3f70e3c5244239de97a2cc95d98534a14" datatype="html">
+ <source>Client Read/Write</source>
+ <target>クライアントの読み取り/書き込み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="52213660b2454d139ada3079a42ec6caf3c3c01e" datatype="html">
+ <source>Client Throughput</source>
+ <target>クライアントのスループット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="275485415092cbae3a9f3cbb786ebe283cacfdd5" datatype="html">
+ <source>Recovery Throughput</source>
+ <target>回復スループット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35416fcdf9cb33d2b299d3f2028c390454b55d02" datatype="html">
+ <source>Scrubbing</source>
+ <target>スクラビング</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="44ecac93d67c6a671198091c2270354f80322327" datatype="html">
+ <source><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> See <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>Logs<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for more details.</source>
+ <target><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/>詳細については、「<x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>ログ<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>」を参照してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520247697658334435" datatype="html">
+ <source>Reads</source>
+ <target>読み取り回数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5947645586591788199" datatype="html">
+ <source>/s</source>
+ <target>/s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7527163811128350993" datatype="html">
+ <source>Writes</source>
+ <target>書き込み回数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7684088941299429132" datatype="html">
+ <source>IOPS</source>
+ <target>IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81585474102700882" datatype="html">
+ <source>Used</source>
+ <target>使用済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">179</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8695656831075719969" datatype="html">
+ <source>Avail.</source>
+ <target>使用可能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6352596107300820129" datatype="html">
+ <source>Clean</source>
+ <target>クリーン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4016774570903735270" datatype="html">
+ <source>Working</source>
+ <target>動作中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4467323362722952678" datatype="html">
+ <source>Unknown</source>
+ <target>不明</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">218</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7790772795962334429" datatype="html">
+ <source>Healthy</source>
+ <target>正常</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4708847204147472247" datatype="html">
+ <source>Misplaced</source>
+ <target>誤配置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3120522496446378904" datatype="html">
+ <source>Degraded</source>
+ <target>降格</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8047698491745405137" datatype="html">
+ <source>Unfound</source>
+ <target>見つからない</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81117556780777231" datatype="html">
+ <source>objects</source>
+ <target>オブジェクト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795e8a00db46b750113d5db93e8d97e2b3079894" datatype="html">
+ <source>For an overview of <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/> widgets click <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/>ウィジェットの概要については、<x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>をクリックしてください</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">21,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16bd21c1b48036d54c6a595f5cff2540cfba7f60" datatype="html">
+ <source>here</source>
+ <target>ここ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8515973702474791807" datatype="html">
+ <source>up</source>
+ <target>アップ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4223604072115719661" datatype="html">
+ <source>no filesystems</source>
+ <target>ファイルシステムがありません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2078241808113697591" datatype="html">
+ <source>active</source>
+ <target>アクティブ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3232506912392089107" datatype="html">
+ <source>standby</source>
+ <target>スタンバイ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576716133013765863" datatype="html">
+ <source>standby daemons</source>
+ <target>スタンバイデーモン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3629620351427988554" datatype="html">
+ <source>active daemon</source>
+ <target>アクティブデーモン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5954854563228355745" datatype="html">
+ <source>standbyReplay</source>
+ <target>standbyReplay</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7329683463736701292" datatype="html">
+ <source>n/a</source>
+ <target>なし</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/not-available.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8271970016544066882" datatype="html">
+ <source><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (quorum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</source>
+ <target><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (定数<x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mon-summary.pipe.ts</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6489441800790477240" datatype="html">
+ <source>total</source>
+ <target>合計</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5965118847182332588" datatype="html">
+ <source>near full</source>
+ <target>ほぼフル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="268166731974484199" datatype="html">
+ <source>full</source>
+ <target>フル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47116253e36f4e38a97ba41b2d3122c6c15ab904" datatype="html">
+ <source>Clients (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</source>
+ <target>クライアント(<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5159814115056353668" datatype="html">
+ <source>Addresses</source>
+ <target>アドレス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1811797298582428088" datatype="html">
+ <source>Access Type</source>
+ <target>アクセスタイプ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3575940435199094878" datatype="html">
+ <source>Squash</source>
+ <target>スカッシュ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2944102521023817891" datatype="html">
+ <source>Cluster</source>
+ <target>クラスタ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91772203889648189" datatype="html">
+ <source>NFS Protocol</source>
+ <target>NFSプロトコル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907766170797643122" datatype="html">
+ <source>Pseudo</source>
+ <target>疑似</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1032539711043211945" datatype="html">
+ <source>Transport</source>
+ <target>トランスポート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2489852208080013495" datatype="html">
+ <source>Storage Backend</source>
+ <target>ストレージバックエンド</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8440421106569981118" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4095248496892792741" datatype="html">
+ <source>CephFS User</source>
+ <target>CephFSユーザ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2535727951299201687" datatype="html">
+ <source>CephFS Filesystem</source>
+ <target>CephFSファイルシステム</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2169401160512036026" datatype="html">
+ <source>Security Label</source>
+ <target>セキュリティラベル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3671149880069127721" datatype="html">
+ <source>Object Gateway</source>
+ <target>オブジェクトゲートウェイ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1643028261508790" datatype="html">
+ <source>Object Gateway User</source>
+ <target>オブジェクトゲートウェイユーザ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2dae0bda66f6a349444951c0379c28cda47d6d1" datatype="html">
+ <source>Any client can access</source>
+ <target>任意のクライアントからアクセスできます</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7882f2edb1d4139800b276b6b0bbf5ae0b2234ef" datatype="html">
+ <source>Addresses</source>
+ <target>アドレス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f3f74c0f6925826cb2188576391c0da01a23f0" datatype="html">
+ <source>Must contain one or more comma-separated values</source>
+ <target>1つ以上のカンマ区切り値を含んでいる必要があります</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb5b2073697f3f4378c44a49b7524934c9268f4" datatype="html">
+ <source>For example:</source>
+ <target>例:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f969c655b3fbe4fba7e277caf4cd2c459f9fca5" datatype="html">
+ <source>Access Type</source>
+ <target>アクセスタイプ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28952831a284cfe2b4fc39ca610e80b52598905a" datatype="html">
+ <source>Squash</source>
+ <target>スカッシュ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0660ae339068979854ade34a96546980723dede3" datatype="html">
+ <source>Add clients</source>
+ <target>クライアントの追加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8571141481686087364" datatype="html">
+ <source>(inherited from global config)</source>
+ <target>(グローバル設定から継承)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3563954518111128118" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- アクセスタイプを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3802199399355755843" datatype="html">
+ <source>inherited from global config</source>
+ <target>グローバル設定から継承されました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8729531250118136719" datatype="html">
+ <source>-- Select what kind of user id squashing is performed --</source>
+ <target>-- 実行されるユーザIDスカッシュ操作を選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4d1dd59b039ad818d9da7e29a773e10e41d9821" datatype="html">
+ <source>Cluster</source>
+ <target>クラスタ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="625f8f0f3e5b7c92651606d77484ff3d07b3c12b" datatype="html">
+ <source>This is the ID of an NFS Service.</source>
+ <target>これはNFSサービスのIDです。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="135b91a2d908d5814b782695470a6a786c99d9d2" datatype="html">
+ <source>-- No cluster available --</source>
+ <target>-- 使用可能なクラスタがありません --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c501dba379f566885919240ea277b5bc10c14d18" datatype="html">
+ <source>-- Select the cluster --</source>
+ <target>-- クラスタを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7bd3ad665c398c7fe97230ab59e67370653a82" datatype="html">
+ <source>This field is required. To create a new NFS cluster, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>add a new NFS Service<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <target>このフィールドは必須です。 新しいNFSクラスタを作成するには、<x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>新しいNFSサービスを追加します<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">41,43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3f6ba7fe84d6508705cdfe234f0fcc8ff85c9cf" datatype="html">
+ <source>Storage Backend</source>
+ <target>ストレージバックエンド</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6fee356d1db954255a56d8169405a89595246b9" datatype="html">
+ <source>-- Select the storage backend --</source>
+ <target>-- ストレージバックエンドを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3c2793dd2ef56954f872142d5ec1becb84c0fe1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="796e42bec8a6996607cf1f3e80235b86d695804a" datatype="html">
+ <source>Volume</source>
+ <target>ボリューム</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee3ba0ab5f0ccd597b3e44021c71e9aaad14df0a" datatype="html">
+ <source>-- No CephFS filesystem available --</source>
+ <target>-- 利用可能なCephFSファイルシステムがありません --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="764c57812558b1ae66c5eec95d7efd2b1bf761e3" datatype="html">
+ <source>-- Select the CephFS filesystem --</source>
+ <target>-- CephFSファイルシステムを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="957512d0321f73e9f115bce1bd823fa635170c41" datatype="html">
+ <source>Security Label</source>
+ <target>セキュリティラベル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="65ce0fa4da1ed55e658aeb31d1644a29f06bb342" datatype="html">
+ <source>Enable security label</source>
+ <target>セキュリティラベルの有効化</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e808f804130c7b6ff719509cbc06ebb27393a48" datatype="html">
+ <source>CephFS Path</source>
+ <target>CephFSパス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1338c2f83e49ea7f2fc04e9fe90c5d330b7a10f" datatype="html">
+ <source>A path in a CephFS file system.</source>
+ <target>CephFSファイルシステム内のパス。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ecc0107badb6625466aaa3f975b5c05276f432f" datatype="html">
+ <source>Path need to start with a '/' and can be followed by a word</source>
+ <target>パスは「/」で始まる必要があり、その後ろに1つの単語を配置できます</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f9d8bd873c34c5ab2d4d0cf995fe5183ab25f6e" datatype="html">
+ <source>The path does not exist in the selected volume.</source>
+ <target>パスは選択したボリュームに存在しません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd197d7773cef10f368f08c53b47979c3df1f22d" datatype="html">
+ <source>Bucket</source>
+ <target>バケット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ca90b4b16347ef7017967915e8624472976c85c" datatype="html">
+ <source>The bucket does not exist or is not in the default realm (if multiple realms are configured). To continue, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>create a new bucket<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <target>バケットが存在しないか、デフォルトレルムにありません(複数のレルムが設定されている場合)。 続行するには、<x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>新しいバケットを作成します<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bee6900143996c0e908a10564532eba3da0b30fb" datatype="html">
+ <source>NFS Protocol</source>
+ <target>NFSプロトコル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5043c0921e709935ab026bb3253ffe1f159fca1" datatype="html">
+ <source>NFSv4</source>
+ <target>NFSv4</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d2c39708a32910f89701dd7e1cfb9ec1c195768" datatype="html">
+ <source>Pseudo</source>
+ <target>疑似</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1f8be2ae25947bec0b84c2338201580ea053f34e" datatype="html">
+ <source>The position that this <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> export occupies in the <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo FS<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (it must be unique).</source>
+ <target>この<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>エクスポートが<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo FS<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>内で占有する位置(この位置は一意である必要があります)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">241,242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3af55f7fd5b1d9e5a53e030c80116dc635bfb9f" datatype="html">
+ <source>By using different Pseudo options, the same Path may be exported multiple times.</source>
+ <target>異なる[疑似]オプションを使用することで、同じパスを複数回エクスポートできます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5eb719aa900fed3f9d4a1d74bcc158f07f67f684" datatype="html">
+ <source>The pseudo is already in use by another export.</source>
+ <target>疑似はすでに別のエクスポートによって使用されています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddf98fcdeeb17643db020d54f42b5e56b5f9a52a" datatype="html">
+ <source>Pseudo needs to start with a '/' and can't contain any of the following: &gt;, &lt;, |, &amp;, ( or ).</source>
+ <target>擬似は「/」で始まる必要があり、&gt;、&lt;、|、&amp;、(または)のいずれも含めることはできません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="27eb35c4b4ac08781a7253a2ab40f8f7d957ba51" datatype="html">
+ <source>-- No access type available --</source>
+ <target>-- 使用可能なアクセスタイプがありません --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">280</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="509ce016c9110a54028dafd741f15ceacbe74b5a" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- アクセスタイプを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67ce207d0b7eada1fe3d3187a39ba0c07be76b6c" datatype="html">
+ <source>The Object Gateway NFS backend has a number of limitations which will seriously affect applications writing to the share. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> for details before enabling write access.</source>
+ <target>オブジェクトゲートウェイNFSバックエンドには、共有に書き込むアプリケーションに重大な影響を及ぼすいくつかの制限があります。 書き込みアクセスを有効にする前に、<x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>で詳細を確認してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">293,296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4deda03573eaaff77e63f6a238a1f0ca7816950a" datatype="html">
+ <source>-- No squash available --</source>
+ <target>-- 使用可能なスカッシュがありません --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">321</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a0e82a4da88e7fdf270444f838d45849676e9d4b" datatype="html">
+ <source>--Select what kind of user id squashing is performed --</source>
+ <target>-- 実行されるユーザIDスカッシュ操作の種類を選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d01b7c3f7f06712c53d054cfbe4f53d446b038e8" datatype="html">
+ <source>Transport Protocol</source>
+ <target>トランスポートプロトコル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2a6ad6e8bc315f07911722c05767ac79c136d99" datatype="html">
+ <source>UDP</source>
+ <target>UDP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">349</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c030f11e0aae9b24d2c048c57f29f590be621df" datatype="html">
+ <source>TCP</source>
+ <target>TCP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">359</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f84d7fd4d52eb5b2229b632ef5119dac63d5597" datatype="html">
+ <source>No user id squashing is performed.</source>
+ <target>実行されるユーザIDスカッシュ操作はありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">378</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb1d148107e36852325106a518385b1b0de28835" datatype="html">
+ <source>uid 0 and gid 0 are squashed to the Anonymous_Uid and Anonymous_Gid gid 0 in alt_groups lists is also squashed.</source>
+ <target>uid 0とgid 0は、alt_groupsリストのAnonymous UIDおよびAnonymous GID gid 0にスカッシュ操作されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">382</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1309d6f67955799863337b201413faa61a175ddb" datatype="html">
+ <source>uid 0 and gid of any value are squashed to the Anonymous_Uid and Anonymous_Gid alt_groups lists is discarded.</source>
+ <target>任意の値のuid 0とgidはAnonymous_Uidにスカッシュ操作され、Anonymous_Gid alt_groupsリストは破棄されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85f23d5c9b57dc78dda4150d13aa3b99e985350b" datatype="html">
+ <source>All users are squashed.</source>
+ <target>すべてのユーザがスカッシュ操作されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2691935247101074756" datatype="html">
+ <source>NFS export</source>
+ <target>NFSエクスポート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8727258243239498387" datatype="html">
+ <source><x id="PH" equiv-text="fsalItem.descr"/> backend is not available. <x id="PH_1" equiv-text="errorMessage"/></source>
+ <target><x id="PH" equiv-text="fsalItem.descr"/>バックエンドは使用できません。<x id="PH_1" equiv-text="errorMessage"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2772848515253260635" datatype="html">
+ <source>Error while retrieving paths.</source>
+ <target>パスの取得中にエラーが発生しました。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5239928491238988595" datatype="html">
+ <source>Error while retrieving bucket names.</source>
+ <target>バケット名の取得中にエラーが発生しました。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="734c9905951a774870497c5aaae8e3ee833b6196" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2190548d236ca5f7bc7ab2bca334b860c5ff2ad4" datatype="html">
+ <source>Object Gateway</source>
+ <target>オブジェクトゲートウェイ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca53d681a9892d6fdbb57ee9676582186515e961" datatype="html">
+ <source>Performance counters not available</source>
+ <target>パフォーマンスカウンタを使用できません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="490e15ecc922965b6d8194754c87c5583aa071f3" datatype="html">
+ <source>The name can only consist of alphanumeric characters, dashes and underscores.</source>
+ <target>名前は英数字、ダッシュ、および下線のみで構成される必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9edc2b494e660618af3e5225f68d40b7ca67629c" datatype="html">
+ <source>The chosen erasure code profile name is already in use.</source>
+ <target>選択されたイレイジャコードプロファイル名はすでに使用されています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35a4206db3105ed03e0dd799e1642b75b78123e8" datatype="html">
+ <source>Root</source>
+ <target>ルート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf425784c7073c7e7f7c1bb90c2c19db7e751db2" datatype="html">
+ <source>Failure domain type</source>
+ <target>障害ドメインタイプ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72396a9565cf644d1fe1b21b790c4243ee270986" datatype="html">
+ <source>Device class</source>
+ <target>デバイスクラス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d80e0c07bfea1b693a33ef2245007de92a6780" datatype="html">
+ <source>Let Ceph decide</source>
+ <target>Cephの決定を許可する</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101611937243846632" datatype="html">
+ <source>Crush Rule</source>
+ <target>Crushルール</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef9ff0e6227947b48dfab4ac39ade04af758913b" datatype="html">
+ <source>Plugin</source>
+ <target>プラグイン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd69b31bce8f630eac1d4762b0bbcf72ce19d193" datatype="html">
+ <source>Data chunks (k)</source>
+ <target>データチャンク(k)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0d26a6172d32cb81218fe2103c54a818cbc1189" datatype="html">
+ <source>Must be equal to or greater than 2.</source>
+ <target>2以上である必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ba6f4800642eba4e8b056aa7167554c3afa8db0" datatype="html">
+ <source>Chunks (k+m) have exceeded the available OSDs of <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>.</source>
+ <target>チャンク(k+m)は、<x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>の使用可能なOSD数を超えています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="86fca2f788ce986eef835cd7ef8dfc9ae22447a4" datatype="html">
+ <source>For an equal distribution k has to be a multiple of (k+m)/l.</source>
+ <target>等分布の場合、kは(k+m)/lの倍数でなければなりません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8dd4bc172f1adc4afadaec291e465b082909148d" datatype="html">
+ <source>K has to be equal to or greater than m in order to recover data correctly through c.</source>
+ <target>cからデータを正しく復元するには、kはm以上である必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2e5b0e6d0dba31c59f946392699a0a6c4dd9b83" datatype="html">
+ <source>Distribution factor: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></source>
+ <target>分布係数: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dab3a299ead121169b8e08ed618c3b6a2f66691b" datatype="html">
+ <source>Coding chunks (m)</source>
+ <target>コーディングチャンク(m)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e2773e5bd4948193f18f2361d663ecc3988c656" datatype="html">
+ <source>Must be equal to or greater than 1.</source>
+ <target>1以上である必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">146</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cde4c945a49a260c0a47bcc7cd956846930a5f7" datatype="html">
+ <source>Durability estimator (c)</source>
+ <target>耐久性推定子(c)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ec9ff9931f8ea1201792d6a01bf9a47b283d692" datatype="html">
+ <source>C has to be equal to or lower than m as m defines the amount of chunks that can be used.</source>
+ <target>mは使用可能なチャンクの量を定義するため、Cはm以下である必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35594fe66657ea07b5b5f560927f78e81a229996" datatype="html">
+ <source>Helper chunks (d)</source>
+ <target>ヘルパーチャンク(d)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0c250a8d281291273ed3504ade19ca6537e4d9a" datatype="html">
+ <source>Set d manually or use the plugin's default calculation that maximizes d.</source>
+ <target>dを手動で設定するか、dを最大化するプラグインのデフォルト計算を使用します。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4304a5cd95742db0f81c3bdf29aa96bf3b0ca13d" datatype="html">
+ <source>D is automatically updated on k and m changes</source>
+ <target>Dはkとmの変更時に自動的に更新されます</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06a67d52427b12df2b3d439be0e1342ac72aeb5c" datatype="html">
+ <source>D can be set from <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> to <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></source>
+ <target>Dは<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>~<x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/>まで設定できます</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4f8831d3bd6401e87710c4e3ee844f5efbf5de3" datatype="html">
+ <source>D can only be set to <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></source>
+ <target>Dは<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>にのみ設定できます</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5d7aacffce2c6032c3ae9ef4d1b3847a926440b" datatype="html">
+ <source>D has to be greater than k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>).</source>
+ <target>Dはk (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>)より大きい必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fd745d614884edc23c7ac9ad8aba9655f3793ac2" datatype="html">
+ <source>D has to be lower than k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>).</source>
+ <target>Dはk + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>)より低い必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">199</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af668c2a095a979ea2b4e43cd82c2120ab56c21c" datatype="html">
+ <source>Locality (l)</source>
+ <target>地域(l)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="200fea08b63ae8d60cdbf33ffd2636159e87dc1e" datatype="html">
+ <source>Can't split up chunks (k+m) correctly with the current locality.</source>
+ <target>現在の地域ではチャンク(k+m)を正しく分割できません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319ac5d692d11da686782159bd70e0b705c228ed" datatype="html">
+ <source>Locality groups: <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></source>
+ <target>地域グループ: <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">230</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d455a110bf6d2235e314e295ce1dfeee93d3dff2" datatype="html">
+ <source>Crush failure domain</source>
+ <target>Crush障害ドメイン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74a495f041f7dd102eee5c0bbc9e03083b538ae" datatype="html">
+ <source>Crush Locality</source>
+ <target>Crush地域</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2f14a73f7a6e94479f67423cc51102da8d6f524" datatype="html">
+ <source>None</source>
+ <target>なし</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="363a99d62822b92913a4cce196d47f32c1258e2f" datatype="html">
+ <source>Scalar mds</source>
+ <target>スカラmds</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2981733b912b693a9dd9d915d6d34f4692cc874a" datatype="html">
+ <source>Technique</source>
+ <target>技法</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0098b6e47b04ec817361f384ce81d454ba5c0bb" datatype="html">
+ <source>Packetsize</source>
+ <target>パケットサイズ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0252cd81ca54d0a2f69ec9ccf4248e73df5aa4a" datatype="html">
+ <source>Crush root</source>
+ <target>Crushルート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">351</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1548d5c76f0406ddd1ba3c557e1e6db22e95b340" datatype="html">
+ <source>Crush device class</source>
+ <target>Crushデバイスクラス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3f657ffa19dc6ac504b83c86209709522dcf065" datatype="html">
+ <source>Available OSDs: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></source>
+ <target>使用可能なOSD数: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03d84645f6e019c5a43909bbf2ea1696ee88332c" datatype="html">
+ <source>Directory</source>
+ <target>ディレクトリ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1354845268685595937" datatype="html">
+ <source>EC Profile</source>
+ <target>ECプロファイル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3938a411d76796f8ae73b72ea4c77661207453bd" datatype="html">
+ <source>Cache Tiers Details</source>
+ <target>キャッシュ層の詳細</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="991790413700941336" datatype="html">
+ <source>Cache Mode</source>
+ <target>キャッシュモード</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9133265273798382582" datatype="html">
+ <source>Min Evict Age</source>
+ <target>退去までの最小経過時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7172092927403263656" datatype="html">
+ <source>Min Flush Age</source>
+ <target>消去までの最小経過時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8096695869347792608" datatype="html">
+ <source>Target Max Bytes</source>
+ <target>ターゲットの最大バイト数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8854126142886240282" datatype="html">
+ <source>Target Max Objects</source>
+ <target>ターゲットの最大オブジェクト数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617215542453015899" datatype="html">
+ <source>No applications added</source>
+ <target>アプリケーションは追加されていません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4895689494338215646" datatype="html">
+ <source>Applications limit reached</source>
+ <target>アプリケーション数の上限に達しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7322343326526084293" datatype="html">
+ <source>A pool can only have up to four applications definitions.</source>
+ <target>1つのプールは最大で4つのアプリケーション定義しか保有できません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1393735257943344790" datatype="html">
+ <source>Allowed characters '_a-zA-Z0-9'</source>
+ <target>使用可能な文字「_a-zA-Z0-9」</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5520683885127790121" datatype="html">
+ <source>Maximum length is 128 characters</source>
+ <target>最大長は128文字です</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587418377972855060" datatype="html">
+ <source>Filter or add applications'</source>
+ <target>アプリケーションのフィルタリングまたは追加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5188881899285829380" datatype="html">
+ <source>Add application</source>
+ <target>アプリケーションの追加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16e113230b6b0d3165e076300880542bac7c8138" datatype="html">
+ <source>The chosen Ceph pool name is already in use.</source>
+ <target>選択されたCephプール名はすでに使用されています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c75b132bef7b29fa5171768303c4b96e34ccaf68" datatype="html">
+ <source>It's not possible to create an RBD pool with '/' in the name. Please change the name or remove 'rbd' from the applications list.</source>
+ <target>名前に「/」が含まれたRBDプールを作成することはできません。名前を変更するか、アプリケーションリストから「rbd」を削除してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">34,35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="171dc6d5c6bc4615d99778b0088cae80fd00bd10" datatype="html">
+ <source>Pool name can only contain letters, numbers, '.', '-', '_' or '/'.</source>
+ <target>プール名には、文字、数字、「.」、「-」、「_」、または「/」のみを含めることができます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b85c657469e5ec8231c3de99b22f437bc01ffde5" datatype="html">
+ <source>Pool type</source>
+ <target>プールタイプ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="526c5443254c3b126eedb264840ffe827727bfd3" datatype="html">
+ <source>-- Select a pool type --</source>
+ <target>-- プールタイプを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abfbe47b630929d93c7343dc154599c2e59330a" datatype="html">
+ <source>PG Autoscale</source>
+ <target>配置グループオートスケール</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0aa21053410a94aa61d16985a4e95fd65523430d" datatype="html">
+ <source>Placement groups</source>
+ <target>配置グループ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6301f1391d726f8f450bb358058534db19541ca9" datatype="html">
+ <source>At least one placement group is needed!</source>
+ <target>少なくとも1つの配置グループが必要です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba9469a1ce6ed36e039c1f67247c8c81a5c71449" datatype="html">
+ <source>Your cluster can't handle this many PGs. Please recalculate the PG amount needed.</source>
+ <target>ご使用のクラスタはこれだけ多数の配置グループを処理できません。必要な配置グループの数を再計算してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80ac68cd883369dac20688bc32b4cb33291b5e50" datatype="html">
+ <source>Calculation help</source>
+ <target>計算のヘルプ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fccbd60493df26705d957ed6c02a3c447894678f" datatype="html">
+ <source>The current PGs settings were calculated for you, you should make sure the values suit your needs before submit.</source>
+ <target>現在の配置グループ設定は自動的に計算されたため、送信前に、これらの値がニーズに合っていることを確認してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">116,117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a43b2695131b48b76cebba676aba98a2bee17515" datatype="html">
+ <source>Replicated size</source>
+ <target>複製されたサイズ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bff144a4c4dc63b0e18fff2617d61a7ebdf2b6c" datatype="html">
+ <source>Minimum: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></source>
+ <target>最小値: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9c54b41f6d58a74e5d0aa3429ed0c87a482551" datatype="html">
+ <source>Maximum: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></source>
+ <target>最大値: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="452cf71ec44ee77428656936a6627eaf2dd3b47f" datatype="html">
+ <source>The size specified is out of range. A value from <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> to <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/> is usable.</source>
+ <target>指定されたサイズは範囲外です。 有効な値の範囲は<x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/>~<x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/>です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">144,145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dda6196ffab88c1825f44a565c7b34e246e7e12f" datatype="html">
+ <source>A size of 1 will not create a replication of the object. The 'Replicated size' includes the object itself.</source>
+ <target>1のサイズではオブジェクトのレプリケーションは作成されません。「複製されたサイズ」にはオブジェクト自体が含まれます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">148,149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c870fb00256b8a5b9cb9cd1a124e6390b9bc639" datatype="html">
+ <source>EC Overwrites</source>
+ <target>ECの上書き</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f1abafaeb40ce52355ddcc24686e3cd17b64e08a" datatype="html">
+ <source>Applications</source>
+ <target>アプリケーション</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9308b82fc183f710df60909f49cfc73aa5e076" datatype="html">
+ <source>CRUSH</source>
+ <target>CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9de7dde00e2139cc4bd03b1837afbe72ad15a1ff" datatype="html">
+ <source>Erasure code profile</source>
+ <target>イレイジャコードプロファイル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39b4620e6bd444e0a57a0a5c03fa8c96d7fe5235" datatype="html">
+ <source>-- No erasure code profile available --</source>
+ <target>-- 使用可能なイレイジャコードプロファイルがありません --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498561757390d5528b263ce450d5f38efb00266d" datatype="html">
+ <source>-- Select an erasure code profile --</source>
+ <target>-- イレイジャコードプロファイルを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="616a2532fbaace94934f5943e381b63e2623f004" datatype="html">
+ <source>This profile can't be deleted as it is in use.</source>
+ <target>このプロファイルは使用中のため削除できません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="994363f08f9fbfa3b3994ff7b35c6904fdff18d8" datatype="html">
+ <source>Profile</source>
+ <target>プロファイル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="023d6f718770d2ea4ab8cabe26b0ec27ef967ec2" datatype="html">
+ <source>Used by pools</source>
+ <target>プールで使用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">387</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1061ba5ee07a5c6af09e09330dbc29201baf2aa" datatype="html">
+ <source>Profile is not in use.</source>
+ <target>プロファイルは使用されていません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33150f22ce5348aa6c499bd092c3f4f3695d62cc" datatype="html">
+ <source>Crush ruleset</source>
+ <target>Crushルールセット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">293</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">303</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c69b0bcd4698aa845d32c4c4ad488492552cb469" datatype="html">
+ <source>A new crush ruleset will be implicitly created.</source>
+ <target>新しいCrushルールセットが暗黙的に作成されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="896e9987db5e9bb279e6deed5d2dff28c242ef66" datatype="html">
+ <source>There are no rules.</source>
+ <target>ルールはありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73a6b31116b3cc322af951daa0bafdc169e6c42e" datatype="html">
+ <source>-- Select a crush rule --</source>
+ <target>-- Crushルールを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7d4894e770f8853050b1f6dd55bdd77a51a8ac6" datatype="html">
+ <source>Placement and
+ replication strategies or distribution policies that allow to
+ specify how CRUSH places data replicas.</source>
+ <target>CRUSHが
+データレプリカを配置する方法を指定できる配置/レプリケーション戦略
+または配布ポリシー。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">328,330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea91d648f92002bc9f96d9b26b735c83ca0b53c6" datatype="html">
+ <source>This rule can't be deleted as it is in use.</source>
+ <target>このルールは使用中のため削除できません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">346</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92da80699921e89fb19372e25b8d0f3b9fa427fc" datatype="html">
+ <source>Crush rule</source>
+ <target>Crushルール</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">365</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5489e9f96835f469f6f728a00d8efa88ea5bc940" datatype="html">
+ <source>Crush steps</source>
+ <target>Crushステップ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc5f5496a9e50fe69e1a09784f28d94944108294" datatype="html">
+ <source>Rule is not in use.</source>
+ <target>ルールは使用されていません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="104a0e6900d1d1b0c8cf9e5947e36edb352583fc" datatype="html">
+ <source>The rule can't be used in the current cluster as it has too few OSDs to meet the minimum required OSD by this rule.</source>
+ <target>このルールは、このルールで最低限必要なOSDを満たすにはOSDが少なすぎるため、現在のクラスタでは使用できません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">409,410</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2208d63d5940ce656006a220102b1eb2b5e553da" datatype="html">
+ <source>Compression</source>
+ <target>圧縮</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">420</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c6f25c47da62ec597c6057a36ddfc3209811ec5" datatype="html">
+ <source>Algorithm</source>
+ <target>アルゴリズム</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">444</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4903231d42089325a28892c0fde1aed46b733ae6" datatype="html">
+ <source>-- No erasure compression algorithm available --</source>
+ <target>-- 使用可能なイレイジャ圧縮アルゴリズムがありません --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d68ddb254275f8f44221e9ad6d8ceeb59ca46a6" datatype="html">
+ <source>Minimum blob size</source>
+ <target>最小blobサイズ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">468</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb2f176df80647137cbb02bbeb29e5dec707a400" datatype="html">
+ <source>e.g., 128KiB</source>
+ <target>例: 128KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">477</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b7f6e53a4521c6eb3ced4c007fdd4cf80bb7707" datatype="html">
+ <source>Value should be greater than 0</source>
+ <target>値は0より大きい必要があります</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">482</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">506</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8db98ab14b4e207ec763dfdefbc2dae367aab1cc" datatype="html">
+ <source>Value should be less than the maximum blob size</source>
+ <target>値は最大blobサイズより小さい必要があります</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151efb127a9a4dd25259a0b2055442318a141f5b" datatype="html">
+ <source>Maximum blob size</source>
+ <target>最大blobサイズ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c656f0e346bbadf46eb1a5d20d0307a3bd20ba8" datatype="html">
+ <source>e.g., 512KiB</source>
+ <target>例: 512KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65a24eee8a026f3b1113fe9e157e9a0dd69486" datatype="html">
+ <source>Value should be greater than the minimum blob size</source>
+ <target>値は最小blobサイズより大きい必要があります</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">509</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="261ba09c4a59de83f48f52a23fd328da37e61ff4" datatype="html">
+ <source>Ratio</source>
+ <target>率</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">517</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1430457a9c3c66366e51d76bf10396014c576be" datatype="html">
+ <source>Compression ratio</source>
+ <target>圧縮率</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">528</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae5ce6de352cde949998fb10754459c3a4eb183b" datatype="html">
+ <source>Value should be between 0.0 and 1.0</source>
+ <target>値は0.0~1.0の間である必要があります</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d99b34162c9c34f10d0ccd8dbae83d8569c2db77" datatype="html">
+ <source>Max bytes</source>
+ <target>最大バイト数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">546</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1d14a18879c62f3f4ed705318b7164a1160e249" datatype="html">
+ <source>Leave it blank or specify 0 to disable this quota.</source>
+ <target>このクォータを無効にするには、空白のままにするか、0を指定します。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">572</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7565b131562ff6c5f769fdbd239a772154abdd97" datatype="html">
+ <source>A valid quota should be greater than 0.</source>
+ <target>有効なクォータは0より大きい必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">550</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">574</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b8bf35b66f09a301eef92ffc3cb2fd259df67ce9" datatype="html">
+ <source>Max objects</source>
+ <target>最大オブジェクト数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">570</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="95f348167622d832c5ae532b6944635c8e2ae5cb" datatype="html">
+ <source>The value should be greater or equal to 0</source>
+ <target>値は0以上である必要があります</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">586</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1088629182722162774" datatype="html">
+ <source>pool</source>
+ <target>プール</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6215593782779198370" datatype="html">
+ <source>erasure code profile</source>
+ <target>イレイジャコードプロファイル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4390273881304618317" datatype="html">
+ <source>crush rule</source>
+ <target>Crushルール</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">721</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d8a7c8aea58294a3c57c23af0468ddf0ba0c9c7" datatype="html">
+ <source>Pools List</source>
+ <target>プールリスト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9055665654201606988" datatype="html">
+ <source>Data Protection</source>
+ <target>データ保護</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6658000829978978023" datatype="html">
+ <source>Applications</source>
+ <target>アプリケーション</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5232365108332422324" datatype="html">
+ <source>PG Status</source>
+ <target>配置グループのステータス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1669788723782899084" datatype="html">
+ <source>Crush Ruleset</source>
+ <target>Crushルールセット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7961062124768120122" datatype="html">
+ <source>Pool deletion is disabled by the mon_allow_pool_delete configuration setting.</source>
+ <target>プールの削除は、mon_allow_pool_delete構成設定によって無効にされています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee5132a8da30e0b7f9f5c70dbc91928d17dd909" datatype="html">
+ <source>Owner</source>
+ <target>所有者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c51963a9c553b29427ef783bbb69fa6634fa8c" datatype="html">
+ <source>Index type</source>
+ <target>インデックスタイプ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e6f950a32eaea32ec7e192f9ca3d3dfe469d4ba" datatype="html">
+ <source>Placement rule</source>
+ <target>配置ルール</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6972d213e31c4ea4f887e60db99d9881bc8fcd3e" datatype="html">
+ <source>Marker</source>
+ <target>マーカー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47b02acd2d3254d1ace1926f840523f154ebef71" datatype="html">
+ <source>Maximum marker</source>
+ <target>最大マーカー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="092fa3a7df9168b14d3f83a77a4035e92b92ce15" datatype="html">
+ <source>Master version</source>
+ <target>マスタバージョン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97434cc5001d407f90c7447a12d9e8e6848a2aa3" datatype="html">
+ <source>Modification time</source>
+ <target>変更時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90fe2e41e7fde38453ce4e619efeea9bc6adea9c" datatype="html">
+ <source>Zonegroup</source>
+ <target>ゾーングループ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="efeade5060b3add63863c24871f0830fb16b7e6d" datatype="html">
+ <source>Versioning</source>
+ <target>バージョニング</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62a923f047ca49e7a4782629e91fea1ba32db68f" datatype="html">
+ <source>MFA Delete</source>
+ <target>MFA削除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="649a410bd0ace333d067d8fa22f12bdbdb43533b" datatype="html">
+ <source>Bucket quota</source>
+ <target>バケットクォータ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">567</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f50a33d3c339f8f4a465141f8caa5d2d8c005251" datatype="html">
+ <source>Enabled</source>
+ <target>有効化済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">579</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cef1595d040e77cbb4466e60382028d4c2040cac" datatype="html">
+ <source>Maximum size</source>
+ <target>最大サイズ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa6fb95c355f172bda303de1ce2f38c251a149cf" datatype="html">
+ <source>Unlimited</source>
+ <target>無制限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee862a800364b4d11f9b8cb9955a28a60f840a45" datatype="html">
+ <source>Maximum objects</source>
+ <target>最大オブジェクト数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b84370895ab9eb44672f57146fa05c5947f1c0c" datatype="html">
+ <source>Locking</source>
+ <target>ロック</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c3d9d2296f7886e8289b9f623323803deacfc6" datatype="html">
+ <source>Days</source>
+ <target>日数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f44bdf9ab00a973bbe482e9fc450e3f67e60c0d" datatype="html">
+ <source>Bucket names can only contain lowercase letters, numbers, periods and hyphens.</source>
+ <target>バケット名には、小文字、数字、ピリオド、ハイフンのみを含めることができます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eabb4db920d9f9b2480cf438468b86e1bea02a9b" datatype="html">
+ <source>The chosen name is already in use.</source>
+ <target>選択された名前はすでに使用されています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b06de7f834c622197e68b66a2abe893040b174c4" datatype="html">
+ <source>Bucket names must not contain uppercase characters or underscores.</source>
+ <target>バケット名に大文字やアンダースコアを含めることはできません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abacf4af2f66d3af08c5ebe502b21b1f42ac649" datatype="html">
+ <source>Each label must start and end with a lowercase letter or a number.</source>
+ <target>各ラベルは、小文字または数字で始まり、小文字または数字で終わる必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a7f52e6813e0535026f61a2d6e8adc8a1d006a" datatype="html">
+ <source>Bucket names cannot be formatted as IP address.</source>
+ <target>バケット名をIPアドレスとしてフォーマットすることはできません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2a2460396d35e14e7acfb4e060196a0679bdcff" datatype="html">
+ <source>Bucket labels cannot be empty and can only contain lowercase letters, numbers and hyphens.</source>
+ <target>バケットラベルは空にすることはできず、小文字、数字、ハイフンのみを含めることができます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf5c849977e0be2dbfc862d044edd323bfd9fb77" datatype="html">
+ <source>Bucket names must be 3 to 63 characters long.</source>
+ <target>バケット名は3~63文字である必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e4c918357c7445fbf19a203e5f0f0ece1960b3b" datatype="html">
+ <source>-- Select a user --</source>
+ <target>-- ユーザを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4aab1f837bc8ec222e4f25922465d1c5929a1fc" datatype="html">
+ <source>Placement target</source>
+ <target>配置ターゲット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bae0a7fc2c9c1fde7d937a8a1a3c7e6825cf7d1" datatype="html">
+ <source>-- Select a placement target --</source>
+ <target>-- 配置ターゲットを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="016d24e069e7d505a090fb8243e5cd43b35dc39b" datatype="html">
+ <source>Enables versioning for the objects in the bucket.</source>
+ <target>バケット内のオブジェクトのバージョニングを有効にします。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">151</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e6775ffd06878aa145c07359f28557f01ede04f" datatype="html">
+ <source>Multi-Factor Authentication</source>
+ <target>多要素認証</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29e8a5d4fb767d4ad0c762c81c6264cec4c0ba97" datatype="html">
+ <source>Delete enabled</source>
+ <target>削除が有効</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40fbc3ac8c1ea4ecfe62247e91f1f999ad5baf76" datatype="html">
+ <source>Enables MFA (multi-factor authentication) Delete, which requires additional authentication for changing the bucket versioning state.</source>
+ <target>MFA(多要素認証)の削除を有効にします。これには、バケットのバージョニング状態を変更するための追加の認証が必要です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24c93a8c13db46defa06ed7b5e026a3edb52b91" datatype="html">
+ <source>Token Serial Number</source>
+ <target>トークンのシリアル番号</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6d9536c2af2e5e9a228c3e3e1809dc1fefe0149" datatype="html">
+ <source>Token PIN</source>
+ <target>トークンPIN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f038d51ab1645f15b0cd58f195c72a7eeebd4729" datatype="html">
+ <source>Enables locking for the objects in the bucket. Locking can only be enabled while creating a bucket.</source>
+ <target>バケット内のオブジェクトのロックを有効にします。バケットの作成中のみロックを有効にすることができます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9af1b4baa2dd8ed2bfc3cc756b12a2271c2dd793" datatype="html">
+ <source>Compliance</source>
+ <target>コンプライアンス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="edd600fa489d1b4a4448dce694ed932e52ce8fda" datatype="html">
+ <source>Governance</source>
+ <target>ガバナンス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="218c7d6d318c51e7105309aaeb0baec9d19e4efb" datatype="html">
+ <source>The number of days that you want to specify for the default retention period that will be applied to new objects placed in this bucket.</source>
+ <target>このバケットに配置された新しいオブジェクトに適用されるデフォルトの保持期間に指定する日数。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">264</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="289b101ec12427b3ca819df9e43cc3b14fae2cc4" datatype="html">
+ <source>The entered value must be a positive integer.</source>
+ <target>入力する値は正の整数にする必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48d8247c1ba2ea156109bf286c5f6dd26b4be760" datatype="html">
+ <source>Retention Days must be a positive integer.</source>
+ <target>保持日は正の整数である必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4349284625269221231" datatype="html">
+ <source>bucket</source>
+ <target>バケット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6161088322338624846" datatype="html">
+ <source>Updated Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'.</source>
+ <target>オブジェクトゲートウェイバケット「<x id="PH" equiv-text="values.bid"/>」を更新しました。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218632328857697292" datatype="html">
+ <source>Created Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'</source>
+ <target>オブジェクトゲートウェイバケット「<x id="PH" equiv-text="values.bid"/>」を作成しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c338bae89822d7eefbc9a887c458a7d8a98e55e" datatype="html">
+ <source>No Limit</source>
+ <target>制限なし</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3715596725146409911" datatype="html">
+ <source>Owner</source>
+ <target>所有者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5545511293826600258" datatype="html">
+ <source>Used Capacity</source>
+ <target>使用済み容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1925090152473969054" datatype="html">
+ <source>Capacity Limit %</source>
+ <target>容量制限%</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8713861779825116442" datatype="html">
+ <source>Object Limit %</source>
+ <target>オブジェクト制限%</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5913880066213114620" datatype="html">
+ <source>buckets</source>
+ <target>バケット数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eeba399c4dae8d4890c27b7a2cd2dc28fcf8b5f9" datatype="html">
+ <source>Performance Counters</source>
+ <target>パフォーマンスカウンタ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="479488ab6e91ecb375484edc78bee3d13467f33f" datatype="html">
+ <source>Daemons List</source>
+ <target>デーモンリスト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca2dee83bb58290d93fb0d17ee8bc9f095a4576f" datatype="html">
+ <source>Sync Performance</source>
+ <target>同期パフォーマンス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4378147649219625174" datatype="html">
+ <source>Zone</source>
+ <target>ゾーン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6148052126949932311" datatype="html">
+ <source>Zone Group</source>
+ <target>ゾーングループ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3840481991104643295" datatype="html">
+ <source>Realm</source>
+ <target>レルム</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1221ca97d19eaa9a7bc0c5243d5fc5befe1d2314" datatype="html">
+ <source>-- Select a type --</source>
+ <target>-- タイプを選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1b8990332af18f1c5159a6061ca889bcbb28432" datatype="html">
+ <source>Permission</source>
+ <target>許可</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a08c589f82f69d892307288da14190ae1dd583d5" datatype="html">
+ <source>-- Select a permission --</source>
+ <target>-- 許可を選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7345972049922682356" datatype="html">
+ <source>capability</source>
+ <target>機能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a94e6b2b5b834d92cceb90037d51ad6165c8b619" datatype="html">
+ <source>Tenant</source>
+ <target>テナント</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
+ <source>User ID</source>
+ <target>ユーザID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b760f123248930122fc7e7b6b6bf94e376e959c8" datatype="html">
+ <source>Full name</source>
+ <target>氏名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69b6ac577a19acc39fc0c22342092f327fff2529" datatype="html">
+ <source>Email address</source>
+ <target>電子メールアドレス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92f3f203270a29b3001871153f02c063484a1574" datatype="html">
+ <source>Suspended</source>
+ <target>中断済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011e20c5bbe51602d459a860fbf29b599b55edd" datatype="html">
+ <source>System</source>
+ <target>システム</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db18a2772988415466a7f75dc42663ce78c9c1d3" datatype="html">
+ <source>Maximum buckets</source>
+ <target>最大バケット数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c4c62e8ba24601be5cfe7dc5d32c24bbbd4b53c" datatype="html">
+ <source>Subusers</source>
+ <target>サブユーザ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17bb3082e6fe5003203ef992a3714172334631a1" datatype="html">
+ <source>Capabilities</source>
+ <target>機能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32f8a0570373cacb9c56cf227502483a29d605bc" datatype="html">
+ <source>MFAs(Id)</source>
+ <target>MFA (ID)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36ad38f9c1a1485e09b67778a28af84553290ffb" datatype="html">
+ <source>User quota</source>
+ <target>ユーザクォータ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">473</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0bcd5ef19af0f1b814141ca8c57df623d8270088" datatype="html">
+ <source>Keys</source>
+ <target>キー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2aba1e87039819aca3b70faa9aa848c12bf139ca" datatype="html">
+ <source>Show</source>
+ <target>表示</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">395</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5248717555542428023" datatype="html">
+ <source>Username</source>
+ <target>ユーザ名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240806681889331244" datatype="html">
+ <source>Unlimited</source>
+ <target>無制限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db4e1a734518691b128ef40b939cc673f01d03a6" datatype="html">
+ <source>The value is not valid.</source>
+ <target>この値は無効です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">617</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6aaf5d2a304167272ac73e3b1d1c162e16c77858" datatype="html">
+ <source>The chosen user ID is already in use.</source>
+ <target>選択されたユーザIDはすでに使用されています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="025be1d01b2f6cbd09e772a1d3de02fab0678b26" datatype="html">
+ <source>Show Tenant</source>
+ <target>テナントの表示</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6af106b0d759fd2882e645604675c4494abfcd5b" datatype="html">
+ <source>The chosen user ID exists in this tenant.</source>
+ <target>選択されたユーザIDがこのテナントに存在します。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="df441e80db2157f9d272b75de724ba4a82b96b57" datatype="html">
+ <source>This is not a valid email address.</source>
+ <target>これは有効な電子メールアドレスではありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca271adf154956b8fcb28f4f50a37acb3057ff7c" datatype="html">
+ <source>The chosen email address is already in use.</source>
+ <target>選択された電子メールアドレスはすでに使用されています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="030197cebe938edf35422e92fe14183d06eb670b" datatype="html">
+ <source>Max. buckets</source>
+ <target>最大バケット数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f39256070bfc0714020dfee08895421fc1527014" datatype="html">
+ <source>Disabled</source>
+ <target>無効化済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c05002b0ac2040f1aede5e727e0ffd06eda819" datatype="html">
+ <source>Custom</source>
+ <target>カスタム</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28872515cb81d197a3a1733fa546d3e0f0dd6c67" datatype="html">
+ <source>The entered value must be &gt;= 1.</source>
+ <target>1以上の値を入力する必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="583a219c524155c2314eb06ee29162bb315272a3" datatype="html">
+ <source>S3 key</source>
+ <target>S3キー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c217ee914725a37e9dd2336c721c8e63e9666bdc" datatype="html">
+ <source>Auto-generate key</source>
+ <target>キーの自動生成</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f1c1c0f2bce4c9f92d1a2061e8161cb0006c31a" datatype="html">
+ <source>Access key</source>
+ <target>アクセスキー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b864acb67296a9819c1db0069c4c47d8b5ce8f44" datatype="html">
+ <source>Secret key</source>
+ <target>秘密キー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="128d6efb51d9ddc7c0cc695a2deeca5b9523f6e4" datatype="html">
+ <source>There are no subusers.</source>
+ <target>サブユーザがいません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fd6dfb8ecb982dbc3affb2c2d5414c4f5b6abd2" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">294,295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67c746c1ba9dab4351fedc4c7cba4e6d6b0dbc47" datatype="html">
+ <source>S3</source>
+ <target>S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d6819038d608623503918fb2553f53d68231ec3a" datatype="html">
+ <source>There are no keys.</source>
+ <target>キーがありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">377</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc1c1a7140ff6b815a95b65ee2780fdbe1b2b7a1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">356,357</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6ddb5e991a3ecd2659fb520bc5acc81b67e08ddd" datatype="html">
+ <source>Swift</source>
+ <target>スウィフト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">371</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d01eccdda47fc907c5be35bcb16d2dcd02b0270" datatype="html">
+ <source>There are no capabilities.</source>
+ <target>機能がありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5a451c4ea65a4046f0b49d489a7013abf0b5861" datatype="html">
+ <source>All capabilities are already added.</source>
+ <target>すべての機能はすでに追加されています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">456</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="043e2ec0036ceadd926fd5e3f93cd6f3565f3648" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">461,462</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6146e13ceca5fa5cc17b771b282fe5955f3d19fa" datatype="html">
+ <source>Unlimited size</source>
+ <target>無制限のサイズ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">595</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6db8aa7c99fdce18edb33dde57729acede2b308" datatype="html">
+ <source>Max. size</source>
+ <target>最大サイズ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">511</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">605</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc630b2093e880fffa19df99d5cd8b87605037f8" datatype="html">
+ <source>Unlimited objects</source>
+ <target>無制限のオブジェクト数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cda5a993d06f0bb10048be9d3aba6555aa9f356" datatype="html">
+ <source>Max. objects</source>
+ <target>最大オブジェクト数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">642</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="623ac50f37a26caec6fd7cd519b653e3315cba25" datatype="html">
+ <source>The entered value must be &gt;= 0.</source>
+ <target>0以上の値を入力する必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">654</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="123010868147850959" datatype="html">
+ <source>user</source>
+ <target>ユーザ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8368421344177343441" datatype="html">
+ <source>subuser</source>
+ <target>サブユーザ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4662015204945271252" datatype="html">
+ <source>S3 Key</source>
+ <target>S3キー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9103468069826049692" datatype="html">
+ <source>Updated Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <target>オブジェクトゲートウェイユーザ「<x id="PH" equiv-text="uid"/>」を更新しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="884841609901737584" datatype="html">
+ <source>Created Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <target>オブジェクトゲートウェイユーザ「<x id="PH" equiv-text="uid"/>」を作成しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4363143805416924501" datatype="html">
+ <source>Tenant</source>
+ <target>テナント</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8301535046747035390" datatype="html">
+ <source>Full name</source>
+ <target>氏名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3967269098753656610" datatype="html">
+ <source>Email address</source>
+ <target>電子メールアドレス</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5851424994801012357" datatype="html">
+ <source>Suspended</source>
+ <target>中断済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208300173682032371" datatype="html">
+ <source>Max. buckets</source>
+ <target>最大バケット数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1670306451865226564" datatype="html">
+ <source>users</source>
+ <target>ユーザ数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c614babd1950adb2be75df4e2c9747286d6adc" datatype="html">
+ <source>-- Select a username --</source>
+ <target>-- ユーザ名を選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2841767821d6b66238c34d07e413b0af67aee92" datatype="html">
+ <source>Subuser</source>
+ <target>サブユーザ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd59fc25a7bd98cff3e75117c09697c8a007a514" datatype="html">
+ <source>The chosen subuser ID is already in use.</source>
+ <target>選択されたサブユーザIDはすでに使用されています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d386c357ebcbc04ed05c4babd5a03626f9b1674" datatype="html">
+ <source>read, write</source>
+ <target>読み取り、書き込み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84e3e3f9a4f31a039b648c97debf95fcb20f4c4a" datatype="html">
+ <source>full</source>
+ <target>フル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6bf81d032a2316464f9df2f0d2f3d753f89f0d3" datatype="html">
+ <source>Swift key</source>
+ <target>スウィフトキー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e0c12685d50d47448ceed9423977ef39775c037" datatype="html">
+ <source>Auto-generate secret</source>
+ <target>秘密の自動生成</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5091031285775138345" datatype="html">
+ <source>Subuser</source>
+ <target>サブユーザ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8453697749389230205" datatype="html">
+ <source>Swift Key</source>
+ <target>スウィフトキー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ac54c18c1b520e948095c83a3a1025f02ce6dcc6" datatype="html">
+ <source>Neither hostname nor OSD ID given</source>
+ <target>ホスト名もOSD IDも指定されていません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4533150758393178756" datatype="html">
+ <source>Device ID</source>
+ <target>デバイスID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1291053608320944146" datatype="html">
+ <source>State of Health</source>
+ <target>ヘルスの状態</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29167121133682512" datatype="html">
+ <source>Good</source>
+ <target>良い</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8767957606064036733" datatype="html">
+ <source>Bad</source>
+ <target>悪い</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8052456228079338924" datatype="html">
+ <source>Stale</source>
+ <target>古い</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6223439643831041743" datatype="html">
+ <source>Life Expectancy</source>
+ <target>耐用年数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3144481541623761279" datatype="html">
+ <source>Prediction Creation Date</source>
+ <target>予測作成日</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="264574868375698540" datatype="html">
+ <source>Device Name</source>
+ <target>デバイス名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1419569261746199221" datatype="html">
+ <source>Daemons</source>
+ <target>デーモン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f635b3cb0600409a2ad44a5bd1863c699e6a01c" datatype="html">
+ <source>Failed to retrieve SMART data.</source>
+ <target>SMARTデータを取得できませんでした。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a8a3f354bd640299068edd912f4bb5325264f250" datatype="html">
+ <source>The data received has the JSON format version 2.x and is currently incompatible with the dashboard.</source>
+ <target>取得したデータには、JSONフォーマットバージョン2.xがあり、現在はダッシュボードと互換性がありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="04f8a3c7e8ac610e6581960162cc15f55a16696a" datatype="html">
+ <source>No SMART data available.</source>
+ <target>利用可能なSMARTデータがありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a185c9b97513b3882604ea9bab60edbfac945c15" datatype="html">
+ <source>SMART overall-health self-assessment test result</source>
+ <target>SMART全体的なヘルス自己評価テスト結果</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="290e4c9ad42dc6e9176656c864a5faed8053f406" datatype="html">
+ <source>unknown</source>
+ <target>不明</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a03d3c2e459f8f8fa7202c0fce465d6165f9e2b" datatype="html">
+ <source>passed</source>
+ <target>成功</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41435d5a5692c8e412c74deaee95d99dbd3617e1" datatype="html">
+ <source>failed</source>
+ <target>失敗</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddd5dd6d930030096ea617f62c82b648a0dd9484" datatype="html">
+ <source>Device Information</source>
+ <target>デバイス情報</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e149c483d88cfcff11d1c5db85e84af7c3149c4" datatype="html">
+ <source>No device information available for this device.</source>
+ <target>このデバイスで利用可能なデバイス情報がありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20cb12827cbe559a7b1da6fdae96041b3b5c3c55" datatype="html">
+ <source>SMART</source>
+ <target>SMART</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380295f37caea93701d071485a38ef0bdba57133" datatype="html">
+ <source>No SMART data available for this device.</source>
+ <target>このデバイスで利用可能なSMARTデータがありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5758c3f16f8749f0f4e2a787f02e8b4da246102f" datatype="html">
+ <source>SMART data is loading.</source>
+ <target>SMARTデータをロードしています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5363861031080361352" datatype="html">
+ <source>Smartctl has received an unknown argument (error code <x id="PH" equiv-text="smartData.smartctl_error_code"/>). You may be using an incompatible version of smartmontools. Version &gt;= 7.0 of smartmontools is required to successfully retrieve data.</source>
+ <target>Smartctlが不明な引数を受け取りました(エラーコード<x id="PH" equiv-text="smartData.smartctl_error_code"/>)。互換性のないバージョンのsmartmontoolsを使用している可能性があります。データを正常に取得するには、バージョン7.0以上のsmartmontoolsが必要です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">61,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5085718566932809950" datatype="html">
+ <source>An error with error code <x id="PH" equiv-text="smartData.smartctl_error_code"/> occurred.</source>
+ <target>エラーコード<x id="PH" equiv-text="smartData.smartctl_error_code"/>のエラーが発生しました。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2091295268977103253" datatype="html">
+ <source>Raw</source>
+ <target>生</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5963653123239768443" datatype="html">
+ <source>Threshold</source>
+ <target>しきい値</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2893124970059125090" datatype="html">
+ <source>When Failed</source>
+ <target>失敗した場合</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5614367840516299633" datatype="html">
+ <source>Worst</source>
+ <target>最低</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d06ae77f9ec46a4cdd49e7e76c73a411aaf2ee38" datatype="html">
+ <source>Please set a new password.</source>
+ <target>新しいパスワードを設定してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8b5b3566e88438f51bd5f6caf6c090ed565ba5ed" datatype="html">
+ <source>You will be redirected to the login page afterwards.</source>
+ <target>その後、ログインページにリダイレクトされます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cf42e491adc166a337a960eb84d03c0c3f677c8" datatype="html">
+ <source>The old and new passwords must be different.</source>
+ <target>新しいパスワードは古いパスワードと異なる必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90163a3d3746819aef42e829f4446331232f3b66" datatype="html">
+ <source>Password confirmation doesn't match the new password.</source>
+ <target>確認入力されたパスワードが新しいパスワードと一致しません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0070e83d11da39d6f4bb95065c2675db1610b419" datatype="html">
+ <source>Username is required</source>
+ <target>ユーザ名は必須です</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e20f8b8a4706526c9024cc2f39d568345d100dc" datatype="html">
+ <source>Password is required</source>
+ <target>パスワードは必須です</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f093d9574ab746b231504bd2cbb65f04bd7b00db" datatype="html">
+ <source>Log in</source>
+ <target>ログイン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5590086849807274701" datatype="html">
+ <source>Scope</source>
+ <target>範囲</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327592562693301723" datatype="html">
+ <source>Read</source>
+ <target>読み取り</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5674286808255988565" datatype="html">
+ <source>Create</source>
+ <target>作成</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4021752662928002901" datatype="html">
+ <source>Update</source>
+ <target>更新</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022070615528435141" datatype="html">
+ <source>Delete</source>
+ <target>削除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ea5c4d8942c00752dcc72e72949c5d9832f6399" datatype="html">
+ <source>Description...</source>
+ <target>説明...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70f45880fce6ac5d8e468e25e82aefbba8098cfe" datatype="html">
+ <source>Permissions</source>
+ <target>許可</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="122114774689391224" datatype="html">
+ <source>role</source>
+ <target>役割</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616102757855967475" datatype="html">
+ <source>All</source>
+ <target>すべて</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4416727401284087008" datatype="html">
+ <source>Created role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <target>役割「<x id="PH" equiv-text="roleFormModel.name"/>」を作成しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3472946357042916911" datatype="html">
+ <source>Updated role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <target>役割「<x id="PH" equiv-text="roleFormModel.name"/>」を更新しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="373024661645814027" datatype="html">
+ <source>System Role</source>
+ <target>システム役割</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753648234171918096" datatype="html">
+ <source>Deleted role '<x id="PH" equiv-text="role"/>'</source>
+ <target>役割「<x id="PH" equiv-text="role"/>」を削除しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1674202514578558795" datatype="html">
+ <source>New name</source>
+ <target>新しい名前</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4857700187193019038" datatype="html">
+ <source>Clone Role</source>
+ <target>役割の複製</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="748631939386170157" datatype="html">
+ <source>Cloned role '<x id="PH" equiv-text="values['newName']"/>' from '<x id="PH_1" equiv-text="name"/>'</source>
+ <target>役割「<x id="PH" equiv-text="values['newName']"/>」を「<x id="PH_1" equiv-text="name"/>」から複製しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="195c31a2f970e790231a6bb94a5e8ca0167406d9" datatype="html">
+ <source>The username already exists.</source>
+ <target>ユーザ名はすでに存在します。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f3bdcce4b2e8c37cd7f0f6c92ef8cff34b039b8" datatype="html">
+ <source>Confirm password</source>
+ <target>パスワードの確認入力</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cbb979e63ba50e0ca3adfa09cbdcaefd0853fca1" datatype="html">
+ <source>Password confirmation doesn't match the password.</source>
+ <target>確認入力されたパスワードがパスワードと一致しません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="96621f9ed2e4ae5204564e583d2c816bedead571" datatype="html">
+ <source>Password expiration date</source>
+ <target>パスワードの失効日</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48932db3801fe9d5d72a60a3e656bffd17c1c5d9" datatype="html">
+ <source>Password expiration date...</source>
+ <target>パスワードの失効日...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc" datatype="html">
+ <source>Email</source>
+ <target>電子メール</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d0ec081dd61eb4f43aea269077bbe38eae87b7f9" datatype="html">
+ <source>Invalid email.</source>
+ <target>無効な電子メールです。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9610487cbeb5796d34d8601b5ac0c0a65f9e1d19" datatype="html">
+ <source>Roles</source>
+ <target>役割</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8913c216dd506e20e412e144381d8d2a65a84359" datatype="html">
+ <source>User must change password at next logon</source>
+ <target>ユーザは次回のログオン時にパスワードを変更する必要があります</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0051a3479d3ba79135c16dc8cc017950a2cce821" datatype="html">
+ <source>You are about to remove &quot;user read / update&quot; permissions from your own user.</source>
+ <target>自身のユーザから「user read / update」という許可を削除しようとしています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af4bf9fcb256853f14cf947eb1deb8d7f176d3f9" datatype="html">
+ <source>If you continue, you will no longer be able to add or remove roles from any user.</source>
+ <target>続行した場合は、どのユーザの役割も追加または削除できなくなります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314291969883771319" datatype="html">
+ <source>There are no roles.</source>
+ <target>役割はありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4306072924538089180" datatype="html">
+ <source>Created user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <target>ユーザ「<x id="PH" equiv-text="userFormModel.username"/>」を作成しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1349763489797682899" datatype="html">
+ <source>Update user</source>
+ <target>ユーザの更新</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8688396456017237992" datatype="html">
+ <source>You were automatically logged out because your roles have been changed.</source>
+ <target>このユーザの役割が変更されたため、このユーザは自動的にログアウトされました。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2335813072344088607" datatype="html">
+ <source>Updated user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <target>ユーザ「<x id="PH" equiv-text="userFormModel.username"/>」を更新しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4768749765465246664" datatype="html">
+ <source>Email</source>
+ <target>電子メール</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795890916060309463" datatype="html">
+ <source>Roles</source>
+ <target>役割</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6877445485286599988" datatype="html">
+ <source>Password expiration date</source>
+ <target>パスワードの失効日</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="705657168061753072" datatype="html">
+ <source>Deleted user '<x id="PH" equiv-text="username"/>'</source>
+ <target>ユーザ「<x id="PH" equiv-text="username"/>」を削除しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="405819296611088743" datatype="html">
+ <source>Failed to delete user '<x id="PH" equiv-text="username"/>'</source>
+ <target>ユーザ「<x id="PH" equiv-text="username"/>」を削除できませんでした</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8935387756949610047" datatype="html">
+ <source>You are currently logged in as '<x id="PH" equiv-text="username"/>'.</source>
+ <target>現在「<x id="PH" equiv-text="username"/>」としてログインしています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0eb15f32b2b92d7f3103ef3ff032621888a8dc32" datatype="html">
+ <source>Old password</source>
+ <target>古いパスワード</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229" datatype="html">
+ <source>New password</source>
+ <target>新しいパスワード</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ede41f01c781b168a783cfcefc6fb67d48780d9b" datatype="html">
+ <source>Confirm new password</source>
+ <target>新しいパスワードの確認入力</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809196861118879526" datatype="html">
+ <source>password</source>
+ <target>パスワード</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623124197136601291" datatype="html">
+ <source>Updated user password&quot;</source>
+ <target>ユーザパスワードを更新しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be" datatype="html">
+ <source>Users</source>
+ <target>ユーザ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ced3246fa3db31be0f7da06648463f29ba378fbe" datatype="html">
+ <source>Selected Object Gateway:</source>
+ <target>オブジェクトゲートウェイを選択しました:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c53062af97ebda2a03f905698f58e524ecf8b968" datatype="html">
+ <source>Select Object Gateway</source>
+ <target>オブジェクトゲートウェイを選択</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="235c355afdcbf72953a15d7fc8d0d9e7a6619f46" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Page not Found<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>ページが見つかりません<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aee9d027170f84774f2980537556f5099369b82" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for. The page you requested may have been changed or moved.</source>
+ <target>検索していた内容が見つかりませんでした。 要求したページが変更または移動された可能性があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">22,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2b46fe9a975c6531af77fee858ccd37327980f7" datatype="html">
+ <source>Please consult the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>documentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> on how to configure and enable the <x id="INTERPOLATION" equiv-text="{{ section_info }}"/> management functionality.</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ section_info }}"/>の管理機能を設定および有効化する方法に関する<x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>ドキュメント<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>を参照してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">26,27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9d57ca7cab78c6f0d27e0d890cb8cf1515e4e30a" datatype="html">
+ <source>Go To Dashboard</source>
+ <target>ダッシュボードに移動</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6578397717654172779" datatype="html">
+ <source>Page Not Found</source>
+ <target>ページが見つかりません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8185335715884155108" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for.
+ The page you requested may have been changed or moved.</source>
+ <target>検索していた内容が見つかりませんでした。
+ 要求したページが変更または移動された可能性があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="143318366100741906" datatype="html">
+ <source>Access Denied</source>
+ <target>アクセスが拒否されました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5384670299771400832" datatype="html">
+ <source>Sorry, you don’t have permission to view this page or resource.</source>
+ <target>このページまたはリソースを表示する権限がありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2424411274809083521" datatype="html">
+ <source>User Denied</source>
+ <target>ユーザが拒否されました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7645004872908092358" datatype="html">
+ <source>Sorry, the user does not exist in Ceph.
+ You'll be logged out from the Identity Provider when you retry logging in.</source>
+ <target>このユーザはCephに存在しません。
+ ログインを再試行すると、Identity Providerからログアウトされます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">24,25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f286db6ac9482dbf567bc491d49a6eade444895a" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7911416166208830577" datatype="html">
+ <source>Help</source>
+ <target>ヘルプ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8878700331247603166" datatype="html">
+ <source>Security</source>
+ <target>セキュリティ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8642696205489749843" datatype="html">
+ <source>Trademarks</source>
+ <target>商標</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1481ecd21e760ac919a24e26cf790acd82e40199" datatype="html">
+ <source>Dashboard Settings</source>
+ <target>ダッシュボード設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a79aab4ef674bf3f6532292107c0054302236e0f" datatype="html">
+ <source>User management</source>
+ <target>ユーザ管理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="197e0246502ca64d0de0df0d5c2deec51d41ff45" datatype="html">
+ <source>Telemetry configuration</source>
+ <target>テレメトリ設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85b79c9064aed1ead31ace985f31aa1363f6bdaf" datatype="html">
+ <source>Help</source>
+ <target>ヘルプ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06638e0f01d82c0786f63aa9832fbe7866b86087" datatype="html">
+ <source>documentation</source>
+ <target>ドキュメント</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e351b40b3869a5c7d19c3d4918cb1ac7aaab95c4" datatype="html">
+ <source>API</source>
+ <target>API</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a" datatype="html">
+ <source>About</source>
+ <target>バージョン情報</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="049dfd9fe6c78914ad58cf89ac6a631fca28ec74" datatype="html">
+ <source>Logged in user</source>
+ <target>ログイン済みユーザ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5022c5ae3ae921c07bf5f881e9b026b4a6708a7" datatype="html">
+ <source>Signed in as <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> としてサインイン済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9" datatype="html">
+ <source>Change password</source>
+ <target>パスワードの変更</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d22c795daf43877a5f708dca2bccd549eb0471d" datatype="html">
+ <source>Sign out</source>
+ <target>サインアウト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319e0745bcbc132451569294fa2fa21bf10f555a" datatype="html">
+ <source>Toggle navigation</source>
+ <target>ナビゲーションの切り替え</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f65253954b66e929a8b4d5ecaf61f9129f8cec64" datatype="html">
+ <source>Dashboard</source>
+ <target>ダッシュボード</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c95898abff46bfac3ed6eb2afef74597e60b15c" datatype="html">
+ <source>CRUSH map</source>
+ <target>CRUSHマップ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7b2bc4b86de6e96d353f6bf2b4d793ea3a19ba0" datatype="html">
+ <source>Manager Modules</source>
+ <target>マネージャモジュール</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb3d5aefff38a814b76da74371cbf02c0789a1ef" datatype="html">
+ <source>Logs</source>
+ <target>ログ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17fc3efe5f9fa4e0289c900cb6202265215a1a27" datatype="html">
+ <source>Monitoring</source>
+ <target>監視</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f5d0c10614e8a34f0e2dad33a0568277c50cf69" datatype="html">
+ <source>Block</source>
+ <target>ブロック</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3c2562ba992127203dcfd014010b03cb7b8113c6" datatype="html">
+ <source>Mirroring</source>
+ <target>ミラーリング</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="811c241d56601b91ef26735b770e64428089b950" datatype="html">
+ <source>iSCSI</source>
+ <target>iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a24eabd99ea5af20f5f94c4484649cd30370042b" datatype="html">
+ <source>NFS</source>
+ <target>NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5276fc60d54d667116babb723641b21281d37271" datatype="html">
+ <source>File Systems</source>
+ <target>ファイルシステム</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9515520496da83179d8b08132f00f575512a1f40" datatype="html">
+ <source>Buckets</source>
+ <target>バケット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a23e992f6c6e169a38b2b7338b4e5e803b52e0d" datatype="html">
+ <source>Tasks and Notifications</source>
+ <target>タスクと通知</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1390461972315002349" datatype="html">
+ <source>The name of the node under which data should be placed.</source>
+ <target>データを配置する必要があるノードの名前。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6575341202068728510" datatype="html">
+ <source>The type of CRUSH nodes across which we should separate replicas.</source>
+ <target>レプリカを分離する必要のあるCRUSHノードのタイプ。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3874278445824365480" datatype="html">
+ <source>The device class data should be placed on.</source>
+ <target>デバイスクラスデータを配置する必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="675628105428950215" datatype="html">
+ <source>Each object is split in data-chunks parts, each stored on a different OSD.</source>
+ <target>各オブジェクトは複数のデータチャンクパートに分割されており、それぞれのパートは異なるOSDに保管されています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5128168460056151476" datatype="html">
+ <source>Compute coding chunks for each object and store them on different OSDs.
+ The number of coding chunks is also the number of OSDs that can be down without losing data.</source>
+ <target>各オブジェクトのコーディングチャンクを計算して、これらのチャンクを別々のOSDに保管します。
+コーディングチャンクの数は、データを失うことなくダウン状態になることができるOSDの数でもあります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">18,19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8826111293169381132" datatype="html">
+ <source>The jerasure plugin is the most generic and flexible plugin,
+ it is also the default for Ceph erasure coded pools.</source>
+ <target>jerasureプラグインは最も汎用的で柔軟性の高いプラグインです。
+このプラグインは、Cephイレイジャコード化済みプール用のデフォルトでもあります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">23,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1331133460856304156" datatype="html">
+ <source>The more flexible technique is reed_sol_van : it is enough to set k
+ and m. The cauchy_good technique can be faster but you need to chose the packetsize
+ carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents
+ in the sense that they can only be configured with m=2.</source>
+ <target>さらに柔軟性の高い技法はreed_sol_vanです。kとmを
+設定するだけで十分です。
+cauchy_good技法はより高速となり得ますが、パケットサイズを慎重に選択する必要があります。
+reed_sol_r6_op、liberation、blaum_roth、liber8tionはすべて、
+m=2を使用した設定のみが可能という意味でRAID6と同等です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">25,28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4577912952562931806" datatype="html">
+ <source>The encoding will be done on packets of bytes size at a time.
+ Choosing the right packet size is difficult.
+ The jerasure documentation contains extensive information on this topic.</source>
+ <target>エンコードはバイトサイズのパケット群に対して同時に実行されます。
+適切なパケットサイズを選択することは困難です。
+jerasureのドキュメントにはこのトピックに関する詳細な情報が記載されています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">29,31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6471646852539810855" datatype="html">
+ <source>With the jerasure plugin, when an erasure coded object is stored on
+ multiple OSDs, recovering from the loss of one OSD requires reading from all the others.
+ For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading
+ from the eleven others to repair.
+
+ The lrc erasure code plugin creates local parity chunks to be able to recover using
+ less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create
+ an additional parity chunk for every four OSDs. When a single OSD is lost, it can be
+ recovered with only four OSDs instead of eleven.</source>
+ <target>jerasureプラグインを使用すると、イレイジャコード化済みオブジェクトが複数のOSDに保管されている場合は、
+1つのOSDの喪失から回復するには、他のすべてのOSDからの読み取りが必要になります。
+たとえば、k=8およびm=4を使用してjerasureが設定されている場合は、1つのOSDが失われた場合、
+修復のためには他の11個のOSDからの読み取りが必要になります。
+
+lrcイレイジャコードプラグインは、これより少ないOSDを使用した回復を可能にするために、
+ローカルパリティチャンクを作成します。たとえば、lrcがk=8、m=4、およびl=4を使用して設定されている場合は、
+lrcは、4つのOSDごとに1つの追加パリティチャンクを作成します。1つのOSDが失われた場合は、
+11個の代わりに4つのOSDのみを使用してそのOSDを回復できます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">34,42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2619235086723330982" datatype="html">
+ <source>Group the coding and data chunks into sets of size locality. For instance,
+ for k=4 and m=2, when locality=3 two groups of three are created. Each set can
+ be recovered without reading chunks from another set.</source>
+ <target>コーディングチャンクとデータチャンクをサイズ地域の複数セットにグループ分けします。
+たとえば、k=4およびm=2の場合に、[地域]=3の場合は、3つのチャンクからなるグループが2つ作成されます。
+各セットは、別のセットからチャンクを読み取ることなく回復できます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">43,45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3298836762557512588" datatype="html">
+ <source>The type of the crush bucket in which each set of chunks defined
+ by l will be stored. For instance, if it is set to rack, each group of l chunks will be
+ placed in a different rack. It is used to create a CRUSH rule step such as step choose
+ rack. If it is not set, no such grouping is done.</source>
+ <target>1によって定義されたチャンクの各セットが保管されるCrushバケットのタイプ。
+たとえば、このバケットタイプがラックに設定されている場合は、1のチャンクの各グループは異なるラックに配置されます。
+このバケットタイプを使用して、「ラックの選択」ステップなどのCRUSHルールステップが作成されます。
+このバケットタイプが設定されていない場合は、このようなグループ分けは行われません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">46,49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9162461669419243962" datatype="html">
+ <source>The isa plugin encapsulates the ISA library. It only runs on Intel processors.</source>
+ <target>isaプラグインはISAライブラリをカプセル化します。このプラグインはIntelプロセッサ上のみで動作します。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2389282202903059852" datatype="html">
+ <source>The ISA plugin comes in two Reed Solomon forms.
+ If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.</source>
+ <target>ISAプラグインは2つのリードソロモン形式で提供されています。reed_sol_vanが設定されている場合は、Vandermondeであり、cauchyが設定されている場合は、Cauchyです。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">53,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7319555444402547739" datatype="html">
+ <source>The shec plugin encapsulates the multiple SHEC library.
+ It allows ceph to recover data more efficiently than Reed Solomon codes.</source>
+ <target>shecプラグインは複数のSHECライブラリをカプセル化します。
+このプラグインを使用すると、cephはリードソロモンコードより効率的にデータを回復できます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">57,58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7723217930035575928" datatype="html">
+ <source>The number of parity chunks each of which includes each data chunk in its
+ calculation range. The number is used as a durability estimator. For instance, if c=2,
+ 2 OSDs can be down without losing data.</source>
+ <target>それぞれが各データチャンクを各自の計算範囲内に含んでいるパリティチャンクの数。
+この数は、耐久性推定子として使用されます。
+たとえば、c=2の場合は、データを失うことなく2つのOSDがダウン状態になることができます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">59,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2054101840892270818" datatype="html">
+ <source>CLAY (short for coupled-layer) codes are erasure codes designed to
+ bring about significant savings in terms of network bandwidth and disk IO when a failed
+ node/OSD/rack is being repaired.</source>
+ <target>CLAY (結合層の略)コードは、障害が発生したノード/OSD/ラックの修復時に、
+ネットワーク帯域幅とディスクIOの面で大幅な節約を実現するように設計されたイレイジャコードです。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">64,66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491096236680229427" datatype="html">
+ <source>Number of OSDs requested to send data during recovery of a single chunk.
+ d needs to be chosen such that k+1 &lt;= d &lt;= k+m-1. The larger the d, the better
+ the savings.</source>
+ <target>単一チャンクの回復中にデータの送信を要求したOSDの数。dは、k+1 &lt;= d &lt;= k+m-1
+となるように選択する必要があります。dが大きいほど、節約率が高くなります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">67,69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2625895656705896729" datatype="html">
+ <source>scalar_mds specifies the plugin that is used as a building block
+ in the layered construction. It can be one of jerasure, isa, shec.</source>
+ <target>scalar_mdsは、階層構造のビルディングブロックとして使用されるプラグイン
+を指定します。jerasure、isa、shecのいずれかになります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">70,71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6639141182731628232" datatype="html">
+ <source>technique specifies the technique that will be picked
+ within the 'scalar_mds' plugin specified. Supported techniques
+ are 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good', 'liber8tion' for jerasure, 'reed_sol_van',
+ 'cauchy' for isa and 'single', 'multiple' for shec.</source>
+ <target>テクニックは、指定された「scalar_mds」プラグイン内で
+選択されるテクニックを指定します。サポートされているテクニックは、
+jerasureの場合は「reed_sol_van」、「reed_sol_r6_op」、「cauchy_orig」、
+「cauchy_good」、「liber8tion」、isaの場合は「reed_sol_van」、
+「cauchy」、shecの場合は「single」、「multiple」です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">72,76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8172892264673403098" datatype="html">
+ <source>The name of the crush bucket used for the first step of the CRUSH rule.
+ For instance step take default.</source>
+ <target>CRUSHルールの最初のステップ(「デフォルトの使用」ステップなど)用に
+使用されるCrushバケットの名前。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">80,81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1654284403437084515" datatype="html">
+ <source>Ensure that no two chunks are in a bucket with the same failure
+ domain. For instance, if the failure domain is host no two chunks will be stored on the same
+ host. It is used to create a CRUSH rule step such as step chooseleaf host.</source>
+ <target>同じ障害ドメインの単一バケット内に2つのチャンクが配置されることを防止します。
+たとえば、障害ドメインがホストである場合は、2つのチャンクが同じホストに保管されることはありません。
+これを使用して、「リーフホストの選択」ステップなどのCRUSHルールステップが作成されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">83,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7737703816676512224" datatype="html">
+ <source>Restrict placement to devices of a specific class
+ (e.g., ssd or hdd), using the crush device class names in the CRUSH map.</source>
+ <target>CRUSHマップ内でCrushデバイスクラス名を使用して、配置先を特定クラス(ssdやhddなど)のデバイスのみに制限します。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9049698214199657456" datatype="html">
+ <source>Set the directory name from which the erasure code plugin is loaded.</source>
+ <target>イレイジャコードプラグインの読み込み元となるディレクトリ名を設定します。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5514060020564877279" datatype="html">
+ <source>Allows all operations</source>
+ <target>すべての操作を許可します</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4265406815683383218" datatype="html">
+ <source>Allows only operations that do not modify the server</source>
+ <target>サーバに変更を加えない操作のみを許可します</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="990071930378308183" datatype="html">
+ <source>Allows no access at all</source>
+ <target>アクセスを一切許可しません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7286983657616285612" datatype="html">
+ <source>Please specify a filesystem volume.</source>
+ <target>ファイルシステムのボリュームを指定してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8321762156640395170" datatype="html">
+ <source>The feature is disabled because Orchestrator is not available.</source>
+ <target>Orchestratorが使用できないため、この機能は無効になっています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6718394293315494787" datatype="html">
+ <source>The Orchestrator backend doesn't support this feature.</source>
+ <target>Orchestratorバックエンドは、この機能をサポートしていません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5569418400096331461" datatype="html">
+ <source>-- Select the priority --</source>
+ <target>-- 優先度を選択してください --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="802458941707537739" datatype="html">
+ <source>Low</source>
+ <target>低</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8063651736083474594" datatype="html">
+ <source>High</source>
+ <target>高</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1717753935149218245" datatype="html">
+ <source>The user list data might be stale. If needed, you can manually reload it.</source>
+ <target>ユーザリストのデータが古くなっている可能性があります。必要に応じて、手動で再ロードできます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/list-with-details.class.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7077550143229856452" datatype="html">
+ <source>Retrieving data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target><x id="PH" equiv-text="statusFor"/>のデータを取得しています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8231424898988217966" datatype="html">
+ <source>Retrieving data.</source>
+ <target>データを取得しています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2357645764289315007" datatype="html">
+ <source>Please wait...</source>
+ <target>しばらくお待ちください...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="232824565824302482" datatype="html">
+ <source>Displaying previously cached data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target><x id="PH" equiv-text="statusFor"/>の以前にキャッシュされたデータを表示しています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8721257977793603730" datatype="html">
+ <source>Displaying previously cached data.</source>
+ <target>以前にキャッシュされたデータを表示しています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6731313206654246255" datatype="html">
+ <source>Could not load data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target><x id="PH" equiv-text="statusFor"/>のデータをロードできませんでした。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3359748695862553898" datatype="html">
+ <source>Could not load data.</source>
+ <target>データをロードできませんでした。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4836577225879717660" datatype="html">
+ <source>Please check the cluster health.</source>
+ <target>クラスタヘルスを確認してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1519954996184640001" datatype="html">
+ <source>Error</source>
+ <target>エラー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5037437391296624618" datatype="html">
+ <source>Information</source>
+ <target>情報</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4648900870671159218" datatype="html">
+ <source>Success</source>
+ <target>成功</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3425367071066107827" datatype="html">
+ <source>Danger</source>
+ <target>危険</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c947210e2d162b6225083d18820ab602f58cd2d" datatype="html">
+ <source>Remove the custom configuration value. The default configuration will be inherited and used instead.</source>
+ <target>カスタム設定値を削除します。デフォルト設定値が継承されて代わりに使用されます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="454ee9cb60b00446a8fb147fd2cc5eb836320586" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>.</source>
+ <target>入力された値は大きすぎます。<x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>より大きい値を入力することはできません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fc8a22825131e028336f60ef909ccbd96059703" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>.</source>
+ <target>入力された値は小さすぎます。<x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>より小さい値を入力することはできません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4dd200b7f9e19048cf90516843b40964f2af3fe9" datatype="html">
+ <source>Copy to Clipboard</source>
+ <target>クリップボードにコピー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6110699a3562eeb15371063c0cf7f6bfd88a0209" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>?</source>
+ <target>本当に<x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>してもよろしいですか?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="549859e511ba5af0ea03fcaa620c472f08038969" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected items?</source>
+ <target>選択されたアイテムを本当に<x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/>してもよろしいですか?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="54839ebc827b73c9dc4e1df731c6d36a85036af7" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/>?</source>
+ <target>選択された<x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/>を本当に<x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/>してもよろしいですか?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2be8b7f04f0104d3fad90d079d8202b74f758b9a" datatype="html">
+ <source>Yes, I am sure.</source>
+ <target>はい。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4523728183000855476" datatype="html">
+ <source>documentation</source>
+ <target>ドキュメント</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/doc/doc.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3099741642167775297" datatype="html">
+ <source>Download</source>
+ <target>ダウンロード</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/download-button/download-button.component.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1417693714872528491" datatype="html">
+ <source>This field is required.</source>
+ <target>このフィールドは必須です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5321335688371682440" datatype="html">
+ <source>An error occurred.</source>
+ <target>エラーが発生しました。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5109325fb160b543f71a51e7511c00575057431" datatype="html">
+ <source>Loading panel data...</source>
+ <target>パネルデータを読み込んでいます...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a21acde005f80ceadb1391be1e7ff8b6d18188a0" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the monitoring functionality.</source>
+ <target>監視機能を設定および有効化する方法に関する<x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>を参照してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a0ed4bd7b7add2a6febf7adf58d8cde5e421418" datatype="html">
+ <source>Grafana Dashboard doesn't exist. Please refer to <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to add dashboards to Grafana.</source>
+ <target>Grafanaダッシュボードが存在していません。 Grafanaにダッシュボードを追加する方法に関する<x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>を参照してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e11830040bd64804a0555de76f291d5832772d4" datatype="html">
+ <source>Grafana Time Picker</source>
+ <target>Grafana Time Picker</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="238c1ba845dd7330e8088165275919a1debf1ca3" datatype="html">
+ <source>Reset Settings</source>
+ <target>設定のリセット</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7888499255176013171" datatype="html">
+ <source>Last 5 minutes</source>
+ <target>直前の5分間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6892361549797455305" datatype="html">
+ <source>Last 15 minutes</source>
+ <target>直前の15分間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2653641162607195423" datatype="html">
+ <source>Last 30 minutes</source>
+ <target>直前の30分間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4117793269024790392" datatype="html">
+ <source>Last 1 hour (Default)</source>
+ <target>直前の1時間(デフォルト)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2645733658763754077" datatype="html">
+ <source>Last 3 hours</source>
+ <target>直前の3時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7360078715633936807" datatype="html">
+ <source>Last 6 hours</source>
+ <target>直前の6時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5055313582241816303" datatype="html">
+ <source>Last 12 hours</source>
+ <target>直前の12時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9186529157286281693" datatype="html">
+ <source>Last 24 hours</source>
+ <target>直前の24時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4498682414491138092" datatype="html">
+ <source>Yesterday</source>
+ <target>昨日</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="929003859318769922" datatype="html">
+ <source>Today so far</source>
+ <target>本日の現時点まで</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5525943133564968818" datatype="html">
+ <source>Day before yesterday</source>
+ <target>一昨日</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6168755117727892817" datatype="html">
+ <source>Last 2 days</source>
+ <target>過去2日間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7574807704224200535" datatype="html">
+ <source>This day last week</source>
+ <target>先週の同じ曜日</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4420128118950221234" datatype="html">
+ <source>Previous week</source>
+ <target>前週</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4063965603321223683" datatype="html">
+ <source>This week so far</source>
+ <target>今週の現時点まで</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4873149362496451858" datatype="html">
+ <source>Last 7 days</source>
+ <target>過去7日間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8586908745456864217" datatype="html">
+ <source>Previous month</source>
+ <target>前月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1647573304710886499" datatype="html">
+ <source>This month so far</source>
+ <target>今月の現時点まで</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2949150997160654358" datatype="html">
+ <source>Last 30 days</source>
+ <target>過去30日間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7469939859049484736" datatype="html">
+ <source>Last 90 days</source>
+ <target>過去90日間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847501198811458781" datatype="html">
+ <source>Last 6 months</source>
+ <target>過去6カ月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7447583558445881102" datatype="html">
+ <source>Last 1 year</source>
+ <target>過去1年間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="100513227838842152" datatype="html">
+ <source>Previous year</source>
+ <target>前年</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3650872673621947074" datatype="html">
+ <source>This year so far</source>
+ <target>今年の現時点まで</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1262816694819959075" datatype="html">
+ <source>Last 2 years</source>
+ <target>過去2年間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7878813844917362690" datatype="html">
+ <source>Last 5 years</source>
+ <target>過去5年間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3fb5709e10166cbc85970cbff103db227dbeb813" datatype="html">
+ <source>Select a Language</source>
+ <target>言語の選択</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/language-selector/language-selector.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e52e9143145e1db5146258de81eae018a407b31" datatype="html">
+ <source>Clear notifications</source>
+ <target>通知のクリア</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0b07bb6b7ff21ede439dd04eaf8872d1ecb84d8" datatype="html">
+ <source>Remove notification</source>
+ <target>通知の削除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e17a1d75189da843f541f7764f188f2b19a97df2" datatype="html">
+ <source>Duration:</source>
+ <target>期間:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d4b37c6675c5b436a54c43d6716eec835e1aa7f" datatype="html">
+ <source>There are no notifications.</source>
+ <target>通知はありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b20e42ac4354d449f2718428b5390933eef0c1b9" datatype="html">
+ <source>The feature is not supported in the current Orchestrator.</source>
+ <target>この機能は、現在のOrchestratorではサポートされていません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a437b8f93cf826817c04a4277edb1ae3a93a1ab" datatype="html">
+ <source>Orchestrator is not available. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the functionality.</source>
+ <target>Orchestratorが利用できません。機能を設定および有効化する方法については<x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>を参照してください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">7,9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20b3d45b0c08a2951a9974fa20505e4de95250c9" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>less than 1<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day. Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <target>パスワードの有効期限が<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>1日以内<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>に切れます。今すぐ変更するには<x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>ここ<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>をクリックしてください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">9,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f34088c155e40ffb23770a465a65868ce772b2" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day(s). Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <target>パスワードの有効期限が<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>日以内に切れます。今すぐ変更するには<x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>ここ<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>をクリックしてください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8d1785038d461ec66b5799db21864182b35900a" datatype="html">
+ <source>Refresh</source>
+ <target>再読み込み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/refresh-selector/refresh-selector.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3417247046175131869" datatype="html">
+ <source>No items selected.</source>
+ <target>アイテムが選択されていません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1034353870189672674" datatype="html">
+ <source>Deselect item to select again</source>
+ <target>アイテムを選択解除して再選択してください</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4879298070255432995" datatype="html">
+ <source>Selection limit reached</source>
+ <target>選択の上限に達しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001227209911602786" datatype="html">
+ <source>Filter tags</source>
+ <target>タグのフィルタリング</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="791789583719406586" datatype="html">
+ <source>Add badge</source>
+ <target>バッジの追加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="699988676752930063" datatype="html">
+ <source>There are no items available.</source>
+ <target>使用可能なアイテムはありません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6702323d3760e3db0e2e785d567469d18beb120" datatype="html">
+ <source>The Ceph community needs your help to continue improving: please <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>Activate<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> the <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Telemetry<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> module.</source>
+ <target>Cephコミュニティは改善を続けるためにあなたの支援が必要です。<x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>テレメトリ<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>モジュールを<x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>有効<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>にしてください。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.html</context>
+ <context context-type="linenumber">8,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8770134622386151776" datatype="html">
+ <source>Telemetry activation reminder muted</source>
+ <target>テレメトリアクティベーションリマインダがミュートされました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8352450862052130357" datatype="html">
+ <source>You can activate the module on the Telemetry configuration page (&lt;b&gt;Dashboard Settings&lt;/b&gt; -&gt; &lt;b&gt;Telemetry configuration&lt;/b&gt;) at any time.</source>
+ <target>モジュールは、テレメトリ設定ページ([&lt;b&gt;ダッシュボード設定&lt;/b&gt;]&gt;[&lt;b&gt;テレメトリ設定&lt;/b&gt;])でいつでも有効化できます。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bc9e5365a581105ce37cf47d1d74e4ad9eb75ce" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e634c306cab9e8879c3392593714c1ceab85437d" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3249513483374643425" datatype="html">
+ <source>Add</source>
+ <target>追加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4359847060009771702" datatype="html">
+ <source>Set</source>
+ <target>設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935187492052582731" datatype="html">
+ <source>Submit</source>
+ <target>送信</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4814285799071780083" datatype="html">
+ <source>Remove</source>
+ <target>削除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8363450564548681668" datatype="html">
+ <source>Unset</source>
+ <target>設定解除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2159130950882492111" datatype="html">
+ <source>Cancel</source>
+ <target>キャンセル</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1295614462098694869" datatype="html">
+ <source>Preview</source>
+ <target>プレビュー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2354817630223808522" datatype="html">
+ <source>Move</source>
+ <target>移動</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3885497195825665706" datatype="html">
+ <source>Next</source>
+ <target>次へ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8890553633144307762" datatype="html">
+ <source>Back</source>
+ <target>戻る</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5834780181397311898" datatype="html">
+ <source>Clone</source>
+ <target>複製</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4323470180912194028" datatype="html">
+ <source>Copy</source>
+ <target>コピー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2131301778880826094" datatype="html">
+ <source>Deep Scrub</source>
+ <target>ディープスクラブ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1704447209800801558" datatype="html">
+ <source>Destroy</source>
+ <target>破棄</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8343007008325027187" datatype="html">
+ <source>Evict</source>
+ <target>削除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="408179081163888126" datatype="html">
+ <source>Flatten</source>
+ <target>フラット化</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="318900679147387932" datatype="html">
+ <source>Mark Down</source>
+ <target>ダウンとしてマーク</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5275142643521766706" datatype="html">
+ <source>Mark In</source>
+ <target>インとしてマーク</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6973272903386150199" datatype="html">
+ <source>Mark Lost</source>
+ <target>喪失としてマーク</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1962653792210847411" datatype="html">
+ <source>Mark Out</source>
+ <target>アウトとしてマーク</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4424610588915076517" datatype="html">
+ <source>Protect</source>
+ <target>保護</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6041115344061899387" datatype="html">
+ <source>Rename</source>
+ <target>名前の変更</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">164</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6770769801335635194" datatype="html">
+ <source>Restore</source>
+ <target>復元</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2003230525878010676" datatype="html">
+ <source>Reweight</source>
+ <target>再重みづけ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5430834128563178593" datatype="html">
+ <source>Scrub</source>
+ <target>スクラブ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8461842260159597706" datatype="html">
+ <source>Show</source>
+ <target>表示</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5655608100705734230" datatype="html">
+ <source>Move to Trash</source>
+ <target>ごみ箱に移動する</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4622393909937403117" datatype="html">
+ <source>Unprotect</source>
+ <target>保護解除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1230154438678955604" datatype="html">
+ <source>Change</source>
+ <target>変更</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8450843381175865415" datatype="html">
+ <source>Enter Maintenance</source>
+ <target>保守に入る</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1610181371597502589" datatype="html">
+ <source>Exit Maintenance</source>
+ <target>保守を終了する</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="676511611419004737" datatype="html">
+ <source>Start Drain</source>
+ <target>ドレインを開始</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7170653322511987983" datatype="html">
+ <source>Stop Drain</source>
+ <target>ドレインを停止</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5528551262937858942" datatype="html">
+ <source>Recreate</source>
+ <target>再作成</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2502364444688691031" datatype="html">
+ <source>Expire</source>
+ <target>期限切れ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6381490568322624964" datatype="html">
+ <source>Deleted</source>
+ <target>削除済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="231679111972850796" datatype="html">
+ <source>Added</source>
+ <target>追加済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5406093358072761930" datatype="html">
+ <source>Removed</source>
+ <target>削除済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3008573030448240863" datatype="html">
+ <source>Edited</source>
+ <target>編集済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4381944803872489731" datatype="html">
+ <source>Canceled</source>
+ <target>キャンセル済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754993936947658096" datatype="html">
+ <source>Previewed</source>
+ <target>プレビュー済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6001163963116907226" datatype="html">
+ <source>Moved</source>
+ <target>移動済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4932744777596632840" datatype="html">
+ <source>Cloned</source>
+ <target>複製済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2115592966120408375" datatype="html">
+ <source>Copied</source>
+ <target>コピー済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7937474560394832586" datatype="html">
+ <source>Deep Scrubbed</source>
+ <target>ディープスクラブ済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6321562733889197649" datatype="html">
+ <source>Destroyed</source>
+ <target>破棄済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7460162290177581995" datatype="html">
+ <source>Flattened</source>
+ <target>フラット化済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3662010055028969035" datatype="html">
+ <source>Marked Down</source>
+ <target>ダウンとしてマーク済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5880434235404894589" datatype="html">
+ <source>Marked In</source>
+ <target>インとしてマーク済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="266997194072682078" datatype="html">
+ <source>Marked Lost</source>
+ <target>喪失としてマーク済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">250</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4010544044592534535" datatype="html">
+ <source>Marked Out</source>
+ <target>アウトとしてマーク済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4776304093333411035" datatype="html">
+ <source>Protected</source>
+ <target>保護済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2700903921419382511" datatype="html">
+ <source>Purged</source>
+ <target>消去済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5488667333459350160" datatype="html">
+ <source>Renamed</source>
+ <target>名前変更済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8044659850000829751" datatype="html">
+ <source>Restored</source>
+ <target>復元済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559472082694466366" datatype="html">
+ <source>Reweighted</source>
+ <target>再重みづけ済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022271525067453676" datatype="html">
+ <source>Rolled back</source>
+ <target>ロールバック済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2483217756816388123" datatype="html">
+ <source>Scrubbed</source>
+ <target>スクラブ済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7200036055090632378" datatype="html">
+ <source>Showed</source>
+ <target>表示済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7609648817347881129" datatype="html">
+ <source>Moved to Trash</source>
+ <target>ごみ箱に移動済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7810326403606456469" datatype="html">
+ <source>Unprotected</source>
+ <target>保護解除済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5620774899056099259" datatype="html">
+ <source>Recreated</source>
+ <target>再作成済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464749780222721589" datatype="html">
+ <source>Expired</source>
+ <target>失効済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">266</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e5e23363e949f7dcbaf034bdb141a561132a10e" datatype="html">
+ <source>Clear filters</source>
+ <target>フィルタをクリア</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80cc9a12d4bf6fe454ed94b379eeaf915f920bb7" datatype="html">
+ <source>selected</source>
+ <target>選択済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <note priority="1" from="description">X selected</note>
+ </trans-unit>
+ <trans-unit id="0cb77511a9a148e05b9adf36cc07269956fbb29d" datatype="html">
+ <source>found</source>
+ <target>検出済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <note priority="1" from="description">X found</note>
+ </trans-unit>
+ <trans-unit id="79347388740c50b7ac97e144c2494bb62912f312" datatype="html">
+ <source>total</source>
+ <target>合計</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <note priority="1" from="description">X total</note>
+ </trans-unit>
+ <trans-unit id="2a3dab422cc892db037db8632bb84a6bf496e2d1" datatype="html">
+ <source>Expand/Collapse Row</source>
+ <target>行の展開/折りたたみ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4047162422391207122" datatype="html">
+ <source>Failed to load data.</source>
+ <target>データを読み込めませんでした。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.ts</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="709331713250198508" datatype="html">
+ <source>Loading form data...</source>
+ <target>フォームデータを読み込んでいます...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3850344644863430180" datatype="html">
+ <source>Form data could not be loaded.</source>
+ <target>フォームデータを読み込めませんでした。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4626760504772708998" datatype="html">
+ <source>Size has to be at least <x id="PH" equiv-text="value"/> or more</source>
+ <target>サイズは少なくとも<x id="PH" equiv-text="value"/>以上にする必要があります</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">428</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2880361802894657892" datatype="html">
+ <source>Size has to be at most <x id="PH" equiv-text="value"/> or less</source>
+ <target>サイズは少なくとも<x id="PH" equiv-text="value"/>以下にする必要があります</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2807800733729323332" datatype="html">
+ <source>Yes</source>
+ <target>はい</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3542042671420335679" datatype="html">
+ <source>No</source>
+ <target>いいえ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7789266940050748913" datatype="html">
+ <source>in %s</source>
+ <target>%s で</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565573880632900017" datatype="html">
+ <source>%s ago</source>
+ <target>%s 前</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="220300059326988179" datatype="html">
+ <source>a few seconds</source>
+ <target>数秒</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2761143993878941513" datatype="html">
+ <source>%d seconds</source>
+ <target>%d 秒</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7094767962693903153" datatype="html">
+ <source>a minute</source>
+ <target>1分</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7597613755904774250" datatype="html">
+ <source>%d minutes</source>
+ <target>%d 分</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2757762976030115752" datatype="html">
+ <source>an hour</source>
+ <target>1時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9118454901758656303" datatype="html">
+ <source>%d hours</source>
+ <target>%d 時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7435193742089920080" datatype="html">
+ <source>a day</source>
+ <target>1日</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1821334622562842480" datatype="html">
+ <source>%d days</source>
+ <target>%d 日</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7375306199026780379" datatype="html">
+ <source>a week</source>
+ <target>1週間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7272688256541915488" datatype="html">
+ <source>%d weeks</source>
+ <target>%d 週間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5761124614324704118" datatype="html">
+ <source>a month</source>
+ <target>1ヵ月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="352195662913351589" datatype="html">
+ <source>%d months</source>
+ <target>%d ヵ月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7562153591649199139" datatype="html">
+ <source>a year</source>
+ <target>1年</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5424759741855527370" datatype="html">
+ <source>%d years</source>
+ <target>%d 年</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7738182956549158907" datatype="html">
+ <source>Required rules for passwords:</source>
+ <target>パスワードに必要なルール:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8839765875053270528" datatype="html">
+ <source>Must contain at least <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> characters</source>
+ <target>少なくとも<x id="PH" equiv-text="settings.pwdPolicyMinLength"/>文字含まれている必要があります</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3098731108593590794" datatype="html">
+ <source>Must not be the same as the previous one</source>
+ <target>前のものと同じであってはなりません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9150236741862848105" datatype="html">
+ <source>Cannot contain the username</source>
+ <target>ユーザ名を含めることはできません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6395043854518867543" datatype="html">
+ <source>Cannot contain any configured keyword</source>
+ <target>設定済みのキーワードを含めることはできません</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="907558624910601703" datatype="html">
+ <source>Cannot contain any repetitive characters e.g. &quot;aaa&quot;</source>
+ <target>「aaa」などの繰り返し文字を含めることはできません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514384270734082343" datatype="html">
+ <source>Cannot contain any sequential characters e.g. &quot;abc&quot;</source>
+ <target>「abc」などの連続した文字を含めることはできません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4119354814383293871" datatype="html">
+ <source>Must consist of characters from the following groups:
+ * Alphabetic a-z, A-Z
+ * Numbers 0-9
+ * Special chars: !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * Any other characters (signs)</source>
+ <target>次のグループの文字で構成されている必要があります。
+ * アルファベットのa-z、A-Z
+ * 数字0〜9
+ * 特殊文字: !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * その他の文字(記号)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">30,34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8649061117624699581" datatype="html">
+ <source>Your matcher seems to match no currently defined rule or active alert.</source>
+ <target>マッチャーは、現在定義されているルールまたはアクティブなアラートに一致していないようです。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7122912874364762704" datatype="html">
+ <source>no active alerts</source>
+ <target>アクティブなアラートなし</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7388215679576832341" datatype="html">
+ <source>1 active alert</source>
+ <target>1件のアクティブなアラート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3112400568960537267" datatype="html">
+ <source><x id="PH" equiv-text="alerts"/> active alerts</source>
+ <target><x id="PH" equiv-text="alerts"/>件のアクティブなアラート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6264717417287230743" datatype="html">
+ <source>Matches 1 rule</source>
+ <target>1個のルールに一致</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054663176394183966" datatype="html">
+ <source>Matches <x id="PH" equiv-text="rules"/> rules</source>
+ <target><x id="PH" equiv-text="rules"/>個のルールに一致</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6674225401121099210" datatype="html">
+ <source><x id="PH" equiv-text="rule"/> with <x id="PH_1" equiv-text="alert"/>.</source>
+ <target><x id="PH" equiv-text="rule"/>と<x id="PH_1" equiv-text="alert"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5659908877047925719" datatype="html">
+ <source>Quality of Service</source>
+ <target>サービス品質</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1277565045885499475" datatype="html">
+ <source>BPS Limit</source>
+ <target>BPS制限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2289210323987692906" datatype="html">
+ <source>The desired limit of IO bytes per second.</source>
+ <target>希望する秒あたり入出力バイト数の上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753589939879013605" datatype="html">
+ <source>IOPS Limit</source>
+ <target>IOPS制限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2213985059444278522" datatype="html">
+ <source>The desired limit of IO operations per second.</source>
+ <target>希望する秒あたり入出力操作数の上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2487530611825582289" datatype="html">
+ <source>Read BPS Limit</source>
+ <target>読み取りBPS制限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8071352270469595250" datatype="html">
+ <source>The desired limit of read bytes per second.</source>
+ <target>希望する秒あたり読み取りバイト数の上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1632513758247239690" datatype="html">
+ <source>Read IOPS Limit</source>
+ <target>読み取りIOPS制限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2361786794607418566" datatype="html">
+ <source>The desired limit of read operations per second.</source>
+ <target>希望する秒あたり読み取り操作数の上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="894600353504285551" datatype="html">
+ <source>Write BPS Limit</source>
+ <target>書き込みBPS制限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911437671369366025" datatype="html">
+ <source>The desired limit of write bytes per second.</source>
+ <target>希望する秒あたり書き込みバイト数の上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2947346368707443195" datatype="html">
+ <source>Write IOPS Limit</source>
+ <target>書き込みIOPS制限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5506349527983391356" datatype="html">
+ <source>The desired limit of write operations per second.</source>
+ <target>希望する秒あたり書き込み操作数の上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559424229658244943" datatype="html">
+ <source>BPS Burst</source>
+ <target>BPSバースト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3454058701331860330" datatype="html">
+ <source>The desired burst limit of IO bytes.</source>
+ <target>希望する入出力バイト数のバースト上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171005761926448741" datatype="html">
+ <source>IOPS Burst</source>
+ <target>IOPSバースト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4939532784700485729" datatype="html">
+ <source>The desired burst limit of IO operations.</source>
+ <target>希望する入出力操作数のバースト上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6273492199526646930" datatype="html">
+ <source>Read BPS Burst</source>
+ <target>読み取りBPSバースト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3105467595643777520" datatype="html">
+ <source>The desired burst limit of read bytes.</source>
+ <target>希望する読み取りバイト数のバースト上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2170715106679765467" datatype="html">
+ <source>Read IOPS Burst</source>
+ <target>読み取りIOPSバースト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6234106755510510672" datatype="html">
+ <source>The desired burst limit of read operations.</source>
+ <target>希望する読み取り操作数のバースト上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="228509518172572466" datatype="html">
+ <source>Write BPS Burst</source>
+ <target>書き込みBPSバースト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7803279807796571240" datatype="html">
+ <source>The desired burst limit of write bytes.</source>
+ <target>希望する書き込みバイト数のバースト上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9125474584914848055" datatype="html">
+ <source>Write IOPS Burst</source>
+ <target>書き込みIOPSバースト</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5839129348567326667" datatype="html">
+ <source>The desired burst limit of write operations.</source>
+ <target>希望する書き込み操作数のバースト上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="614961883076556986" datatype="html">
+ <source>Failed to <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></source>
+ <target><x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/>に失敗しました</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="489145301781720653" datatype="html">
+ <source>Executing</source>
+ <target>実行中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4238828029954346941" datatype="html">
+ <source>execute</source>
+ <target>実行</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7196604637389554584" datatype="html">
+ <source>Executed</source>
+ <target>実行済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4418441687454700644" datatype="html">
+ <source>unknown task</source>
+ <target>不明なタスク</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8667665916832796867" datatype="html">
+ <source>Creating</source>
+ <target>作成中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6031236679730054907" datatype="html">
+ <source>create</source>
+ <target>作成</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5593033420216313122" datatype="html">
+ <source>Updating</source>
+ <target>更新中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6100869651653026893" datatype="html">
+ <source>update</source>
+ <target>更新</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3141301060598402455" datatype="html">
+ <source>Deleting</source>
+ <target>削除中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3420504288275541125" datatype="html">
+ <source>Adding</source>
+ <target>追加中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1059784693423848532" datatype="html">
+ <source>add</source>
+ <target>追加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594819887188505274" datatype="html">
+ <source>Removing</source>
+ <target>削除中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2123171795960509943" datatype="html">
+ <source>remove</source>
+ <target>削除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1946427188770321847" datatype="html">
+ <source>Importing</source>
+ <target>インポート中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8495827411619139669" datatype="html">
+ <source>import</source>
+ <target>インポート</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218459863491436562" datatype="html">
+ <source>Imported</source>
+ <target>インポート済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6534993668932538712" datatype="html">
+ <source>RBD '<x id="PH" equiv-text="metadata.image_spec"/>'</source>
+ <target>RBD「<x id="PH" equiv-text="metadata.image_spec"/>」</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8237287859948228705" datatype="html">
+ <source>RBD snapshot '<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>'</source>
+ <target>RBDスナップショット「<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>」</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2328067975897167268" datatype="html">
+ <source>mirroring site name</source>
+ <target>ミラーリングサイト名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4433460322631470833" datatype="html">
+ <source>bootstrap token</source>
+ <target>ブートストラップトークン</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7044591639782280183" datatype="html">
+ <source>mirror mode for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>プール「<x id="PH" equiv-text="metadata.pool_name"/>」のミラーモード</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7109746474198366468" datatype="html">
+ <source>mirror peer for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>プール「<x id="PH" equiv-text="metadata.pool_name"/>」のミラーピア</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6201476020617351396" datatype="html">
+ <source>all dashboards</source>
+ <target>すべてのダッシュボード</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7268953097700363232" datatype="html">
+ <source>Identifying</source>
+ <target>識別中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4337678035264231187" datatype="html">
+ <source>identify</source>
+ <target>識別</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7257219307556106552" datatype="html">
+ <source>Identified</source>
+ <target>識別済み</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6002370161381995023" datatype="html">
+ <source>device '<x id="PH" equiv-text="metadata.device"/>' on host '<x id="PH_1" equiv-text="metadata.hostname"/>'</source>
+ <target>ホスト「<x id="PH_1" equiv-text="metadata.hostname"/>」上のデバイス「<x id="PH" equiv-text="metadata.device"/>」</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5580298273054260850" datatype="html">
+ <source>OSDs (DriveGroups: <x id="PH" equiv-text="metadata.tracking_id"/>)</source>
+ <target>OSD (DriveGroups: <x id="PH" equiv-text="metadata.tracking_id"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2182125722527364040" datatype="html">
+ <source>Name is already used by <x id="PH" equiv-text="this.pool(metadata)"/>.</source>
+ <target>この名前は<x id="PH" equiv-text="this.pool(metadata)"/>によってすでに使用されています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">182</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7892856315477304281" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> is busy.</source>
+ <target><x id="PH" equiv-text="this.rbd.default(metadata)"/>はビジー状態です。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4690045751984117407" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> contains snapshots.</source>
+ <target><x id="PH" equiv-text="this.rbd.default(metadata)"/>にはスナップショットが含まれています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="562148565853868662" datatype="html">
+ <source>Cloning</source>
+ <target>複製中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1197352830433807469" datatype="html">
+ <source>clone</source>
+ <target>複製</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1692004144561317867" datatype="html">
+ <source>Snapshot of <x id="PH" equiv-text="this.rbd.child(metadata)"/> must be protected.</source>
+ <target><x id="PH" equiv-text="this.rbd.child(metadata)"/>のスナップショットは保護される必要があります。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8531200838331320284" datatype="html">
+ <source>Copying</source>
+ <target>コピー中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6862265996781523030" datatype="html">
+ <source>copy</source>
+ <target>コピー</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3556912098733712857" datatype="html">
+ <source>Flattening</source>
+ <target>フラット化中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2488773646187451754" datatype="html">
+ <source>flatten</source>
+ <target>フラット化</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="704305783678486635" datatype="html">
+ <source>Cannot unprotect <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> because it contains child images.</source>
+ <target><x id="PH" equiv-text="this.rbd.snapshot( metadata )"/>は子イメージを含んでいるため保護解除できません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">223,225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101271773452792348" datatype="html">
+ <source>Cannot delete <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/> because it's protected.</source>
+ <target>保護されているため<x id="PH" equiv-text="this.rbd.snapshot(metadata)"/>を削除できません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5143010940199748580" datatype="html">
+ <source>Rolling back</source>
+ <target>ロールバック中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1315686250907089544" datatype="html">
+ <source>rollback</source>
+ <target>ロールバック</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5010267418211867946" datatype="html">
+ <source>Moving</source>
+ <target>移動中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4366763205960752449" datatype="html">
+ <source>move</source>
+ <target>移動</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="695867152524584829" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_spec"/>' to trash</source>
+ <target>イメージ「<x id="PH" equiv-text="metadata.image_spec"/>」をごみ箱に</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423442774536615202" datatype="html">
+ <source>Could not find image.</source>
+ <target>イメージが見つかりませんでした。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2622324641113512527" datatype="html">
+ <source>Restoring</source>
+ <target>復元中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3347932678307141902" datatype="html">
+ <source>restore</source>
+ <target>復元</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7488038030362249932" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>' into '<x id="PH_1" equiv-text="metadata.new_image_name"/>'</source>
+ <target>イメージ「<x id="PH" equiv-text="metadata.image_id_spec"/>」を「<x id="PH_1" equiv-text="metadata.new_image_name"/>」に</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565688512490959949" datatype="html">
+ <source>Image name '<x id="PH" equiv-text="metadata.new_image_name"/>' is already in use.</source>
+ <target>イメージ名「<x id="PH" equiv-text="metadata.new_image_name"/>」はすでに使用されています。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6331051389974655106" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>'</source>
+ <target>イメージ「<x id="PH" equiv-text="metadata.image_id_spec"/>」</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8245559899946787147" datatype="html">
+ <source>Purging</source>
+ <target>消去中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7879437654311684252" datatype="html">
+ <source>purge</source>
+ <target>消去</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1440427157062670480" datatype="html">
+ <source>all pools</source>
+ <target>すべてのプール</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8677740163708263843" datatype="html">
+ <source>images from <x id="PH" equiv-text="message"/></source>
+ <target><x id="PH" equiv-text="message"/>からのイメージ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011237345035114219" datatype="html">
+ <source>Cannot disable mirroring because it contains a peer.</source>
+ <target>ピアを含んでいるためミラーリングを無効化できません。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">292</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7391584598242145869" datatype="html">
+ <source>host '<x id="PH" equiv-text="metadata.hostname"/>'</source>
+ <target>ホスト「<x id="PH" equiv-text="metadata.hostname"/>」</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6964302691596180722" datatype="html">
+ <source>OSD '<x id="PH" equiv-text="metadata.svc_id"/>'</source>
+ <target>OSD「<x id="PH" equiv-text="metadata.svc_id"/>」</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="488305686602466689" datatype="html">
+ <source>pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>プール「<x id="PH" equiv-text="metadata.pool_name"/>」</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5921392748828575278" datatype="html">
+ <source>erasure code profile '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <target>イレイジャコードプロファイル「<x id="PH" equiv-text="metadata.name"/>」</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2423915105798557698" datatype="html">
+ <source>crush rule '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <target>Crushルール「<x id="PH" equiv-text="metadata.name"/>」</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">370</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8273044996643438592" datatype="html">
+ <source>target '<x id="PH" equiv-text="metadata.target_iqn"/>'</source>
+ <target>ターゲット「<x id="PH" equiv-text="metadata.target_iqn"/>」</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5474643443735437364" datatype="html">
+ <source>NFS '<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>'</source>
+ <target>NFS「<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>」</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">378,380</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2235495382025026939" datatype="html">
+ <source>Service '<x id="PH" equiv-text="metadata.service_name"/>'</source>
+ <target>サービス「<x id="PH" equiv-text="metadata.service_name"/>」</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ </body>
+ </file>
+</xliff> \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.ko-KR.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.ko-KR.xlf
new file mode 100644
index 000000000..c0b16a85f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.ko-KR.xlf
@@ -0,0 +1,14562 @@
+<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en-US" datatype="plaintext" original="ng2.template" target-language="ko-KR">
+ <body>
+ <trans-unit id="ngb.alert.close" datatype="html">
+ <source>Close</source>
+ <target>닫기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/alert/alert.ts</context>
+ <context context-type="linenumber">58,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.slide-number" datatype="html">
+ <source> Slide <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> of <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">114,118</context>
+ </context-group>
+ <note priority="1" from="description">Currently selected slide number read by screen reader</note>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.previous" datatype="html">
+ <source>Previous</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">132,134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.next" datatype="html">
+ <source>Next</source>
+ <target>다음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">147,152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-month" datatype="html">
+ <source>Select month</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">44,49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">49,50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-year" datatype="html">
+ <source>Select year</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">59,63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.previous-month" datatype="html">
+ <source>Previous month</source>
+ <target>지난 달</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">24,27</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">35,36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.next-month" datatype="html">
+ <source>Next month</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">47,50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">60,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first" datatype="html">
+ <source>««</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">182,183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous" datatype="html">
+ <source>«</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">186,190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next" datatype="html">
+ <source>»</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">194,195</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last" datatype="html">
+ <source>»»</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">201,204</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first-aria" datatype="html">
+ <source>First</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">208,209</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous-aria" datatype="html">
+ <source>Previous</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">215,216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next-aria" datatype="html">
+ <source>Next</source>
+ <target>다음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">226,228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last-aria" datatype="html">
+ <source>Last</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.progressbar.value" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="; } /** *"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/progressbar/progressbar.ts</context>
+ <context context-type="linenumber">32,38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.HH" datatype="html">
+ <source>HH</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">40,41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.hours" datatype="html">
+ <source>Hours</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.MM" datatype="html">
+ <source>MM</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">51,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.minutes" datatype="html">
+ <source>Minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-hours" datatype="html">
+ <source>Increment hours</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">63,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-hours" datatype="html">
+ <source>Decrement hours</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">69,70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-minutes" datatype="html">
+ <source>Increment minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">76,78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-minutes" datatype="html">
+ <source>Decrement minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">82,84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.SS" datatype="html">
+ <source>SS</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.seconds" datatype="html">
+ <source>Seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">92,93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-seconds" datatype="html">
+ <source>Increment seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">100,101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-seconds" datatype="html">
+ <source>Decrement seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">106,110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.AM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">115,121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.PM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="t() meridian: b"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">123,131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.toast.close-aria" datatype="html">
+ <source>Close</source>
+ <target>닫기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/toast/toast.ts</context>
+ <context context-type="linenumber">78,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8835b9e49a3348b0a2f2162c21118af1f4bee45a" datatype="html">
+ <source>Must be greater than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbddac59563c8c126e3fe28691e4e247614fcbd1" datatype="html">
+ <source>Must be less than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5" datatype="html">
+ <source>Overview</source>
+ <target>개요</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbd2045d5c37e4bb39a3c0fb62ea1ddf70a12838" datatype="html">
+ <source>Targets</source>
+ <target>대상</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a674ab267d1934bf395f87ca1503fd474296893f" datatype="html">
+ <source>iSCSI Topology</source>
+ <target>iSCSI 토폴로지</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8953033926734869941" datatype="html">
+ <source>Name</source>
+ <target>이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6603000223840533819" datatype="html">
+ <source>Current</source>
+ <target>현재</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5607669932062416162" datatype="html">
+ <source>Default</source>
+ <target>기본 값</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6803e31b7395d94934e091a49a9524026b59b018" datatype="html">
+ <source>Discovery Authentication</source>
+ <target>검색 인증</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e08a77594f3d89311cdf6da5090044270909c194" datatype="html">
+ <source>User</source>
+ <target>사용자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">381</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7cbdabcece469fab89cfa687ab152bca18b97498" datatype="html">
+ <source>This field is required.</source>
+ <target>이 필드는 필수입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">368</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">423</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">481</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">291</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">343</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">407</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">490</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">516</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">556</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">573</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">590</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">647</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">672</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">299</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">195</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">520</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">614</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">651</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f717bad2da5944a2567a52f971ccc6806db85805" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>사용자 이름은 8~64자 길이여야 하며 영숫자 '.', '@', '-', '_' 또는 ':' 을 포함할 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">28,29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">85,86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c32ef07f8803a223a83ed17024b38e8d82292407" datatype="html">
+ <source>Password</source>
+ <target>비밀번호</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">403</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">581</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="001e1836299d8d3b84eaebe2fa051325beab3f00" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>비밀번호의 길이는 12~16자여야 하며 영숫자, '@', '-', '_' 또는 '/' 를 포함할 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">61,62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">118,119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff40391de7a1944ea95091e4045cc34c4979b736" datatype="html">
+ <source>Mutual User</source>
+ <target>공동 사용자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cf73dbebe99b737c4d288788182fc356e3c93d3" datatype="html">
+ <source>Mutual Password</source>
+ <target>공통 비밀번호</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594987303599690088" datatype="html">
+ <source>Updated discovery authentication</source>
+ <target>검색 인증이 업데이트 되었습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb127ea03835b3230f0ed981c7080e2ccb879621" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <note priority="1" from="description">form title</note>
+ </trans-unit>
+ <trans-unit id="1406c2fb12a20c1528b19bcc5e24a6a2386167f3" datatype="html">
+ <source>Target IQN</source>
+ <target>타겟 IQN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5fe42339be910372fa689f559155631862d218e8" datatype="html">
+ <source>IQN has wrong pattern.</source>
+ <target>IQN이 잘못된 패턴을 가지고 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="050a7ff057d1e895357540406b6be5652b4d1c71" datatype="html">
+ <source>An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'</source>
+ <target>IQN은 다음과 같은 지정규칙이 있습니다.
+'iqn.$년-$달.$뒤집어진주소:$정의된이름'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8ada4b53396d8366db00a435acc61d53d857047" datatype="html">
+ <source>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</source>
+ <target>Key
+예를들면: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e" datatype="html">
+ <source>More information</source>
+ <target>추가 정보</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9b1aa85dfc6849196e64060db02c5410de69b7a1" datatype="html">
+ <source>This target has modified advanced settings.</source>
+ <target>이 대상은 고급 설정을 수정했습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6990ad8d6182662e864495ac31c3758cda1c7a28" datatype="html">
+ <source>Portals</source>
+ <target>포털</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a3ac2b4137d723fd9878cd357c2012ff6c07973" datatype="html">
+ <source>Add portal</source>
+ <target>포털 추가</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3638c01b6c34066438909713ec96087c813fc7e" datatype="html">
+ <source>At least <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> gateways are required.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b73f7f5060fb22a1e9ec462b1bb02493fa3ab866" datatype="html">
+ <source>Images</source>
+ <target>이미지</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">495</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">629</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9aff25be088f0efe3eaaf62edf2bff41cc41a617" datatype="html">
+ <source>Backstore: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e3484cae8b118c576ca2815bf9c9406c2eb2cae3" datatype="html">
+ <source>This image has modified settings.</source>
+ <target>이 이미지는 설정을 수정 되었습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1dff11e0820b6722ab240169f1232d70a54beaaa" datatype="html">
+ <source>Duplicated LUN numbers.</source>
+ <target>중복된 LUN 번호 입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bf2dccf92ccff6e3b091792bf4205595406e1bfb" datatype="html">
+ <source>Duplicated WWN.</source>
+ <target>중복된 WWN 입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="808038f912fdc7f0e03f82d4afd3bf9178527fc8" datatype="html">
+ <source>Add image</source>
+ <target>이미지 추가</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">656</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66c5fb27f52e75b70ca4b670b9b15a2a51cf9543" datatype="html">
+ <source>ACL authentication</source>
+ <target>ACL 인증</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="137fbf154ecad4d580354db0858b76faea7e4686" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>사용자 이름은 8~64자 길이여야 하며 영숫자 '.', '@', '-', '_' 또는 ':' 을 포함할 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">227,228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">287,288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="361771c32dd2254d77fd3fbf006b008983fe5907" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>비밀번호의 길이는 12~16자여야 하며 영숫자, '@', '-', '_' 또는 '/' 를 포함할 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">262,263</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">323,324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f494bd31f095f6dcc656ce87ec2dcf07a2e9b30c" datatype="html">
+ <source>Initiators</source>
+ <target>개시자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">335</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">588</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e98239d8a6be1100119ff4b5630c822b82786740" datatype="html">
+ <source>Initiator</source>
+ <target>개시자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2c5059d8cda15d8d03e2cce30f2d139623d9a91" datatype="html">
+ <source>Client IQN</source>
+ <target>클라이언트 IQN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="107d5aabce23d900f0a80e6ddc1c10e29aa0bed8" datatype="html">
+ <source>Initiator IQN needs to be unique.</source>
+ <target>Initiator IQN은 유일해야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e7cad911fa524e512d9744b16358b7ee6791385" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>사용자 이름은 8~64자 길이여야 하며 영숫자 '.', '@', '-', '_' 또는 ':' 을 포함할 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">394,395</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">452,453</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7f2c186d181206d0d2b1ff74819081a010f10bf" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>비밀번호의 길이는 12~16자여야 하며 영숫자, '@', '-', '_' 또는 '/' 를 포함할 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">427,428</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">485,486</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d1878d5fc761cbe9614bfd87047a740c82a6951" datatype="html">
+ <source>Initiator belongs to a group. Images will be configure in the group.</source>
+ <target>개시자는 하나의 그룹에 속해야 하고, 이미지는 그룹안에서 설정합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">515</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0de67b9d97fafbf200f9451e8388ee8128a56ac" datatype="html">
+ <source>No items added.</source>
+ <target>추가된 아이템이 없음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">671</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d565e47726158e428ecdc952fc9233b9b7d7f049" datatype="html">
+ <source>Add initiator</source>
+ <target>Initiator 추가</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">616</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c22ba03540aa3217da059f45e7eab138b51a96e2" datatype="html">
+ <source>Groups</source>
+ <target>그룹</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c90059afafb7e160384d9f512797c95bb95c6dc" datatype="html">
+ <source>Group</source>
+ <target>그룹</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cff1428d10d59d14e45edec3c735a27b5482db59" datatype="html">
+ <source>Name</source>
+ <target>이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">576</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3084948274cff4f56d0f431af47240e9cf02fcc7" datatype="html">
+ <source>Add group</source>
+ <target>그룹 추가</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">676</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6634268061646442252" datatype="html">
+ <source>There are no portals available.</source>
+ <target>사용 가능한 포털이 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4587015892789840153" datatype="html">
+ <source>There are no images available.</source>
+ <target>사용 가능한 이미지가 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7896905042057267575" datatype="html">
+ <source>There are no images available. Please make sure you add an image to the target.</source>
+ <target>사용할 수 있는 이미지가 없습니다. 대상에 이미지를 추가하십시오.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6765423558085969805" datatype="html">
+ <source>There are no initiators available. Please make sure you add an initiator to the target.</source>
+ <target>사용할 수 있는 개시자가 없습니다. 대상에 개시자를 추가하십시오.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2539932200265667453" datatype="html">
+ <source>target</source>
+ <target>대상</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="051dcc342cfa5c1eaf187a2001aaa162379a160c" datatype="html">
+ <source>Configure</source>
+ <target>구성</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e515f954730279c31d5301f02479666d6264e8b" datatype="html">
+ <source>Changing these parameters from their default values is usually not necessary.</source>
+ <target>일반적으로 이러한 매개 변수를 기본값에서 변경할 필요는 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e2591df099ddac796cda401c5f282da779d45f2" datatype="html">
+ <source>Identifier</source>
+ <target>식별자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62480a4859976427cf18fc8ef41d3a438eda0412" datatype="html">
+ <source>lun</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8afc9eb4405e0aa554b2ba14140ef790cdecc040" datatype="html">
+ <source>wwn</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
+ <source>Settings</source>
+ <target>설정</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69a47cbabcc51ca942606e1d8da0ec11f98a2690" datatype="html">
+ <source>Backstore</source>
+ <target>백스토어</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="339878da255ab55447c43afef8d9b2f9753bf5f6" datatype="html">
+ <source>Advanced Settings</source>
+ <target>고급 설정</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="332227f088a4877b3c11f5fb3ae8bc812c470fae" datatype="html">
+ <source>iSCSI Targets not available</source>
+ <target>iSCSI 타겟을 사용할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7fba666f1fff0182e570f12133fb3d622d9ea6" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the iSCSI Targets management functionality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3b301d0044f62c92af0da53d7aaca52a436a547d" datatype="html">
+ <source>Available information:</source>
+ <target>사용 가능한 정보:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8414a5cb9d71cc1b21b10e4a9d1f2dad558f3361" datatype="html">
+ <source>Discovery authentication</source>
+ <target>검색 인증</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4854396465510517671" datatype="html">
+ <source>Target</source>
+ <target>대상</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4093869278527257288" datatype="html">
+ <source>Portals</source>
+ <target>포털</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="414887388288176527" datatype="html">
+ <source>Images</source>
+ <target>이미지</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="798573158169239055" datatype="html">
+ <source># Sessions</source>
+ <target># 세션</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="646929398175374220" datatype="html">
+ <source>Unavailable gateway(s)</source>
+ <target>게이트웨이를 사용할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2350612272163013640" datatype="html">
+ <source>Target has active sessions</source>
+ <target>대상에 활성 세션이 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4782410538666829801" datatype="html">
+ <source>iSCSI target</source>
+ <target>iSCSI 타겟</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">227</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8a9910cd114c1deb9af74f6f99b4173403965bf2" datatype="html">
+ <source>Gateways</source>
+ <target>게이트웨이</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911214550882917183" datatype="html">
+ <source>State</source>
+ <target>상태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4121862424558610140" datatype="html">
+ <source># Targets</source>
+ <target># 타겟</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101197021456818771" datatype="html">
+ <source>Pool</source>
+ <target>풀</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3012906865384504293" datatype="html">
+ <source>Image</source>
+ <target>이미지</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2699995524827665158" datatype="html">
+ <source>Backstore</source>
+ <target>백스토어</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3559214740809905405" datatype="html">
+ <source>Read Bytes</source>
+ <target>읽기 바이트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1580583760095064067" datatype="html">
+ <source>Write Bytes</source>
+ <target>쓰기 바이트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7225917547116479918" datatype="html">
+ <source>Read Ops</source>
+ <target>읽기 Ops</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6417507714454914481" datatype="html">
+ <source>Write Ops</source>
+ <target>쓰기 Ops</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="257147267065394003" datatype="html">
+ <source>A/O Since</source>
+ <target>A/O 이후</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ecbc084370a732fc3cde1966a60af78d71424ab4" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>부트스트랩 토큰 생성</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603e9cc3ef2aab57f2b0a00e465b23b9cabefd9c" datatype="html">
+ <source>To create a bootstrap token which can be imported by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Generate<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="660f97cd3188f8a04bd03b79e703fec72c6df04c" datatype="html">
+ <source>Site Name</source>
+ <target>사이트 이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2fecea01ce1d44114ee45144eff6d47a5016a74f" datatype="html">
+ <source>Name...</source>
+ <target>이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92899fa68e8ca108912163ff58edc8540e453787" datatype="html">
+ <source>Pools</source>
+ <target>데이터 풀</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c2a1dc72cffaf7ab3dc5599bf77b0a7fcad2b20" datatype="html">
+ <source>At least one pool is required.</source>
+ <target>하나 이상의 데이터 풀이 필요합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b258b258b4cc475ceb2871305b61756b0134f4a" datatype="html">
+ <source>Generate</source>
+ <target>생성</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1edc1fc6cfbbb22353050ad6788508b3ed584f53" datatype="html">
+ <source>Token</source>
+ <target>토큰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff785f5596aef34a93b9b4d1023e95c62eef5740" datatype="html">
+ <source>Generated token...</source>
+ <target>생성된 토큰...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8" datatype="html">
+ <source>Close</source>
+ <target>닫기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5467a6bb0e7fade6def7499400d5e2a7d8d3da20" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>부트스트랩 토큰 가져오기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bb7aee0dec5164f45c0aa2f35f2fb2149d2c1d2" datatype="html">
+ <source>To import a bootstrap token which was created by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, provide the generated token, and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Import<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9200e09686136a1d42adfb89c12fbfef2deea125" datatype="html">
+ <source>Direction</source>
+ <target>다이렉션</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9761484679958da8d12841a4efa5964d33fae575" datatype="html">
+ <source>The token is invalid.</source>
+ <target>토큰이 유효하지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2381859602529023966" datatype="html">
+ <source>Instance</source>
+ <target>인스턴스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8040881171107393560" datatype="html">
+ <source>ID</source>
+ <target>아이디</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1605455101862010019" datatype="html">
+ <source>Hostname</source>
+ <target>호스트 이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2724055831234181057" datatype="html">
+ <source>Version</source>
+ <target>버전</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2041675390931385838" datatype="html">
+ <source>Health</source>
+ <target>상태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87bd96249f8afc23f5301cddb57b1464a98e71a" datatype="html">
+ <source>Edit site name</source>
+ <target>사이트 이름 편집</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cfff72c667274c12eb1ff71eadc25871c10c42dc" datatype="html">
+ <source>Edit the site name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">13,14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66db799d67958d4b0765181d072df62e2d1c16f5" datatype="html">
+ <source>Issues</source>
+ <target>이슈</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef06d69259e587e28d52372455f44c7153cda7e7" datatype="html">
+ <source>Syncing</source>
+ <target>동기화 중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0b0901877d837d3fda16ba161eb74368d1c75b7a" datatype="html">
+ <source>Ready</source>
+ <target>준비됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5833626790712999947" datatype="html">
+ <source>Issue</source>
+ <target>이슈</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3419681791450150574" datatype="html">
+ <source>Progress</source>
+ <target>진행중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4902817035128594900" datatype="html">
+ <source>Description</source>
+ <target>설명</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40b7acea5b43f45e0bbd1efeba5200af4687981d" datatype="html">
+ <source>Site Name:</source>
+ <target>사이트 이름 :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e24f9e2d42104ffc01599db4d566d1cc518f9e6" datatype="html">
+ <source>Daemons</source>
+ <target>데몬</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6450386891540681425" datatype="html">
+ <source>Edit Site Name</source>
+ <target>사이트 이름 편집</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4645993115976933405" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>부트스트랩 토큰 생성</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4130053543590533787" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>부트스트랩 토큰 가져오기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4057c56d63a7e9b140b1d01871a9229a5f30eb27" datatype="html">
+ <source>Edit pool mirror mode</source>
+ <target>데이터 풀 미러모드 편집</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e1f367f5feaab38f6637dd1f967c848b447dea2d" datatype="html">
+ <source>To edit the mirror mode for pool  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, select a new mode from the list and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37e10df2d9c0c25ef04ac112c9c9a7723e8efae0" datatype="html">
+ <source>Mode</source>
+ <target>모드</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">426</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32ca348ef926b0a6a7a780b8b64c3a8239895cec" datatype="html">
+ <source>Peer clusters must be removed prior to disabling mirror.</source>
+ <target>미러를 사용하지 않도록 설정하려면 먼저 피어 클러스터를 제거해야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5769292297914455214" datatype="html">
+ <source>Disabled</source>
+ <target>비활성화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ddcb416c1c0aa1f54acf5beef1de81813e76fa6" datatype="html">
+ <source>{VAR_SELECT, select, edit {Edit} other {Add}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3aa7c3a4f7b0cf7c2e60fc71ea1e3b4c3efa3558" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> pool mirror peer</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="59ca65ece457429d90104ede4674965f62edbabe" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> the pool mirror peer attributes for pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Submit<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d3cc964811f852a168f4a2d5daa59068abc5cf53" datatype="html">
+ <source>Cluster Name</source>
+ <target>클러스터 이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b631721fc56cb7fb1cbd07b802a487c5753f6a2d" datatype="html">
+ <source>The cluster name is not valid.</source>
+ <target>클러스터 이름이 유효하지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca6deafa31bf421f85094807982aee4bcb20a3ae" datatype="html">
+ <source>CephX ID</source>
+ <target>CephX 아이디</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7539188a568c3d553cbde1bacaf32310c4264e24" datatype="html">
+ <source>CephX ID...</source>
+ <target>CephX 아이디...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1c45b594b0fba22fc64e80c793a7ffe005fdb0e" datatype="html">
+ <source>The CephX ID is not valid.</source>
+ <target>CephX 아이디가 유효하지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20861576fcfce773c918c782cd4f5adf32382921" datatype="html">
+ <source>Monitor Addresses</source>
+ <target>모니터 주소</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fa28eeed2b4bd4ccbe6e9349a1c2b3cb1c5de70a" datatype="html">
+ <source>Comma-delimited addresses...</source>
+ <target>콤마로 분리된 주소...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dc016c82fd85848d5c1b2fd0e8469ee2027d9c16" datatype="html">
+ <source>The monitory address is not valid.</source>
+ <target>모니터 주소가 유효하지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0ac55b83dc6739e62bc655cfe375b67c93e7f4a" datatype="html">
+ <source>CephX Key</source>
+ <target>CephX 키</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f53434bcb95bd86f1df9c8e22966f757614fc4ad" datatype="html">
+ <source>Base64-encoded key...</source>
+ <target>Base64로 인코딩 된 키 ...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4cd83164cd4f66b4abc2863f9ce6f599d789e4ca" datatype="html">
+ <source>CephX key must be base64 encoded.</source>
+ <target>CephX 키는 반드시 base64로 인코드 되어야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6407712033679505505" datatype="html">
+ <source>Edit Mode</source>
+ <target>편집 모드</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054237897979907103" datatype="html">
+ <source>Add Peer</source>
+ <target>피어 추가</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="899134641637789371" datatype="html">
+ <source>Edit Peer</source>
+ <target>피어 편집</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7393680121674824053" datatype="html">
+ <source>Delete Peer</source>
+ <target>피어 삭제</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1713271461473302108" datatype="html">
+ <source>Mode</source>
+ <target>모드</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1061297288634362831" datatype="html">
+ <source>Leader</source>
+ <target>리더</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8517494870558773093" datatype="html">
+ <source># Local</source>
+ <target># 로컬</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4953753699491987394" datatype="html">
+ <source># Remote</source>
+ <target># 원격</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1715982232168082172" datatype="html">
+ <source>mirror peer</source>
+ <target>피어 미러</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff92fbdec9fdd5054493eeda0d7ee8b450f83e72" datatype="html">
+ <source>RBD Configuration</source>
+ <target>RBD 설정</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b62d9efc8eb3b589904f6cb96a0406bbda55673a" datatype="html">
+ <source>Remove the local configuration value. The parent configuration value will be inherited and used instead.</source>
+ <target>로컬 구성 값을 제거하십시오. 상위 구성 값은 계승되고 대신 사용됩니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80d769fd863fe44fab689636a078466bfdbd1f20" datatype="html">
+ <source>The minimum value is 0</source>
+ <target>최소 값은 0 입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5decb3917d46a9ac6e5813699801becb7c3c1455" datatype="html">
+ <source>Global</source>
+ <target>글로벌</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f9ba9bb9faa8284bcadb1cdbc6aaf969e9c4bb" datatype="html">
+ <source>Image</source>
+ <target>이미지</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70fcca5a99575cffef3ff8cbd5e69f06ffd0f1c" datatype="html">
+ <source>Pool</source>
+ <target>풀</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176659033176029418" datatype="html">
+ <source>Key</source>
+ <target>키</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9155608366859514313" datatype="html">
+ <source>Source</source>
+ <target>소스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6555318547274416232" datatype="html">
+ <source>Value</source>
+ <target>값</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f6e8f6094b180eaf1f11bc0ffe383f1cdcd059e" datatype="html">
+ <source>Only available for RBD images with <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> enabled</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f8b2bb476981727ab34ed40fde1218361f92c45" datatype="html">
+ <source>Details</source>
+ <target>세부 정보</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03cc5b14b0a20d075e9009ff021f4f1660ba348a" datatype="html">
+ <source>Data Pool</source>
+ <target>데이터 풀</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b051734b0ee9021991c91b3ed4e81c244322462" datatype="html">
+ <source>Created</source>
+ <target>생성됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7faaaa08f56427999f3be41df1093ce4089bbd75" datatype="html">
+ <source>Size</source>
+ <target>크기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="afdb601c16162f2c798b16a2920955f1cc6a20aa" datatype="html">
+ <source>Objects</source>
+ <target>오브젝트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ceac8e132384322ec778ba760875a6c6897d3e42" datatype="html">
+ <source>Object size</source>
+ <target>오브젝트 크기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cdb1fea93d77c07950c0c76c6e0ad79ebbef084" datatype="html">
+ <source>Features</source>
+ <target>특징</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65771c9a73b9aa609d592fc96a64801a8f40bd" datatype="html">
+ <source>Provisioned</source>
+ <target>준비됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84a36cb75660b736773fe36ffa3d54f0f0fe363e" datatype="html">
+ <source>N/A</source>
+ <target>없음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c009342a4e8381f64341d0bb61c2e4685f5a4b" datatype="html">
+ <source>Total provisioned</source>
+ <target>프로비저닝 된 전체</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f6bf8a43ae415f527ac961ea62471b983aaa97b" datatype="html">
+ <source>Striping unit</source>
+ <target>분산 저장 단위</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db710e8a8f011923f2d15d713fbae49c38b02b26" datatype="html">
+ <source>Striping count</source>
+ <target>분산 저장 횟수</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a4c2a9e76634ff14a60d52a718296f722d47c67" datatype="html">
+ <source>Parent</source>
+ <target>상위</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a209e68d78ffc2cc9c53d2e76158624efab71ad" datatype="html">
+ <source>Block name prefix</source>
+ <target>블럭 이름 접두사</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5704ec2049d007c5f5fb495a5d8b607e68d58081" datatype="html">
+ <source>Order</source>
+ <target>순서</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="984cb6ad70f150a401b4daf841bd3cd957412699" datatype="html">
+ <source>Format Version</source>
+ <target>포맷 버전</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f21b1d17b6c5042bb5805516eee37fde33739dd8" datatype="html">
+ <source>Snapshots</source>
+ <target>스냅삿</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4a41f824a35ba01d5bd7be61aa06b3e8145209d0" datatype="html">
+ <source>Configuration</source>
+ <target>설정</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3cc9c2ae277393b3946b38c088dabff671b1ee1b" datatype="html">
+ <source>Performance</source>
+ <target>성능</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935bb9cb0e4340fc74d33caa3b70d9d143fcad87" datatype="html">
+ <source>Information can not be displayed for RBD in status 'Removing'.</source>
+ <target>'제거 중' 상태인 RBD에 대한 정보를 표시할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58e58f1a8786da9031a05e6770c5dafce82badf5" datatype="html">
+ <source>This setting overrides the global value</source>
+ <target>이 설정은 글로벌 값을 덮어씁니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36b46714164964c6258b08ed0a25f57d8a950f92" datatype="html">
+ <source>This is the global value. No value for this option has been set for this image.</source>
+ <target>이것은 글로벌 값입니다. 이 이미지에 대해 이 옵션의 값이 설정되지 않았습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6547c9c4d5f62942ac4b1fe459cf9a03d4dbf5a0" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> from</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0e9ecf29a4fa5b057bd8052e0d801b3fde6a30bf" datatype="html">
+ <source>'/' and '@' are not allowed.</source>
+ <target>'/' 와 '@' 문자는 사용불가입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="94516fa213706c67ce5a5b5765681d7fb032033a" datatype="html">
+ <source>Loading...</source>
+ <target>로딩중...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">209</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">452</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b99417c4dd46286ffd37c8d2e987c8b512ec7052" datatype="html">
+ <source>-- No rbd pools available --</source>
+ <target>-- 이용가능한 rbd 데이터 풀이 없습니다 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef83ec9c304a89d45650e580dcdc2978c37b3a83" datatype="html">
+ <source>-- Select a pool --</source>
+ <target>-- 풀 선택 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d649904466254d13df1fbf2d255f0bbc6553d213" datatype="html">
+ <source>-- No namespaces available --</source>
+ <target>-- 사용 가능한 네임 스페이스가 없습니다 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e22d7bb4d2d561e0832ee0b9a3da2468a080c4f0" datatype="html">
+ <source>-- Select a namespace --</source>
+ <target>-- 네임 스페이스를 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49449943d8cbf59d8c401c8bd2e76f92e207cc5f" datatype="html">
+ <source>Use a dedicated data pool</source>
+ <target>전용 데이터 데이터 풀을 사용하세요</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa5b3c5ea5af14d09b2eb098039af9f1f77be010" datatype="html">
+ <source>You need more than one pool with the rbd application label use to use a dedicated data pool.</source>
+ <target>전용 데이터 풀을 사용하려면 rbd 애플리케이션 라벨이 사용되는 풀이 두 개 이상 필요합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="870aee0dd31a9643bf62007beb8f1ae1deb34d42" datatype="html">
+ <source>Data pool</source>
+ <target>데이터 풀</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3792ca829d9b9f687e1f5d7733d30e9bb0bfec47" datatype="html">
+ <source>Dedicated pool that stores the object-data of the RBD.</source>
+ <target>RBD의 오브젝트 데이터를 저장하고 있는 전용 데이터 풀</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151c80ea931037cd92e854442927f8a0f6ae7795" datatype="html">
+ <source>-- No data pools available --</source>
+ <target>-- 사용 가능한 데이터 풀이 없습니다 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0016bd458baa88284a658ce9eeda42d8ad88d2c" datatype="html">
+ <source>e.g., 10GiB</source>
+ <target>예., 100 GiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">206</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a88bbee20570aaf9615332fb27020627044874d" datatype="html">
+ <source>You have to increase the size.</source>
+ <target>사이즈를 증가해야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cfe07dac5b4ee1c464eb24225ddeb4f1d24076a" datatype="html">
+ <source>Advanced...</source>
+ <target>고급 설정</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bc2e854e111ecf2bd7db170da5e3c2ed08181d88" datatype="html">
+ <source>Advanced</source>
+ <target>고급</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3562a3778695a5f9c0445660e35301f0a39aaf73" datatype="html">
+ <source>Striping</source>
+ <target>분산 저장</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef3c3f3b5f562a5cdbe0ee2874287db1534b5958" datatype="html">
+ <source>Stripe unit</source>
+ <target>분산 저장 단위</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84471be1049006edecbcaef1a32ae0893c229c50" datatype="html">
+ <source>-- Select stripe unit --</source>
+ <target>-- 분산 저장 단위를 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">289</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d32c5c54c8581c774a7f467fbd4e329b15a74fa" datatype="html">
+ <source>This field is required because stripe count is defined!</source>
+ <target>분산 저장 개수가 정의되어 있으므로 이 필드는 필수입니다!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bbf9040be7c5491d4a03f2185708f43a6582a3b" datatype="html">
+ <source>Stripe unit is greater than object size.</source>
+ <target>분산 저장 단위는 오브젝트 크기보다 커야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a682f49f9b761591661276d7c6f550e641a130a4" datatype="html">
+ <source>Stripe count</source>
+ <target>분산 저장 개수</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="baa74031990c5370008ba622d0a250f0929097f4" datatype="html">
+ <source>This field is required because stripe unit is defined!</source>
+ <target>분산 저장 단위가 정의되어 있으므로 이 필드는 필수입니다!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cd2ada6d5ecbd5cbf89eae0a1f5326efedac0dbc" datatype="html">
+ <source>Stripe count must be greater than 0.</source>
+ <target>분산 저장 개수는 반드시 0보다 커야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4341718109173132593" datatype="html">
+ <source>RBD</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1359455778569887786" datatype="html">
+ <source>Deep flatten</source>
+ <target>딥 패턴</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58519213655664125" datatype="html">
+ <source>Layering</source>
+ <target>계층화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844531889615887801" datatype="html">
+ <source>Exclusive lock</source>
+ <target>배타적인 락</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4585281635594103106" datatype="html">
+ <source>Object map (requires exclusive-lock)</source>
+ <target>오프젝트-맵(배타적인-락을 요구한다)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240933649452133654" datatype="html">
+ <source>Journaling (requires exclusive-lock)</source>
+ <target>저널링(배탁적인-락을 요구합니다.)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3713046526850391848" datatype="html">
+ <source>Fast diff (interlocked with object-map)</source>
+ <target>Fast diff (오브젝트 맵과 연동 필요)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19f1e825536efbf7492723a7c2d01ad23a4e994b" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1774b9915b0e302d02cad0b9321ad5f1a83247a8" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c9f1026c1235f4d76ace47449e806efd181ab332" datatype="html">
+ <source>Deleting this image will also delete all its snapshots.</source>
+ <target>이 이미지를 삭제하면 모든 스냅샷도 삭제됩니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55f864597e84d9bf88769e1fbfda1d64452430c9" datatype="html">
+ <source>The following snapshots are currently protected and will be removed:</source>
+ <target>다음 스냅샷이 현재 보호되고 있으며 제거됩니다. :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2e362ec498c4c9112dc47a3cb7d7250ca8e71790" datatype="html">
+ <source>RBD in status 'Removing'</source>
+ <target>RBD가 '제거 중' 상태입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3294686077659093992" datatype="html">
+ <source>Namespace</source>
+ <target>네임 스페이스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45739481977493163" datatype="html">
+ <source>Size</source>
+ <target>크기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7531602241051125940" datatype="html">
+ <source>Objects</source>
+ <target>오브젝트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1194977199378511591" datatype="html">
+ <source>Object size</source>
+ <target>오브젝트 크기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">226</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="178418048502923560" datatype="html">
+ <source>Provisioned</source>
+ <target>준비됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7638291694671392137" datatype="html">
+ <source>Total provisioned</source>
+ <target>프로비저닝 된 전체</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8621797738551294959" datatype="html">
+ <source>Parent</source>
+ <target>상위</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616639680594151867" datatype="html">
+ <source>This RBD has cloned snapshots. Please delete related RBDs before deleting this RBD.</source>
+ <target>이 RBD에는 스냅샷이 복제되었습니다. 이 RBD를 삭제하기 전에 관련 RBD를 삭제하십시오.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2900827028308925059" datatype="html">
+ <source>This RBD image has an invalid name and can't be managed by ceph.</source>
+ <target>이 RBD 이미지의 이름이 잘못되어 ceph로 관리할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1796389652493657142" datatype="html">
+ <source>Action not possible for an RBD in status 'Removing'</source>
+ <target>'제거 중' 상태인 RBD에 대해 작업을 수행할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">476</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c07d24bb422aa8e5e568df1c5709083f0a9c8f1" datatype="html">
+ <source>Create Namespace</source>
+ <target>네임 스페이스 생성</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cca6c0485f96d3a9610d0339cb1275a5f2c3f46" datatype="html">
+ <source>Namespace already exists.</source>
+ <target>네임 스페이스가 이미 존재 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4641528557519966449" datatype="html">
+ <source>Created namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6809428596104996786" datatype="html">
+ <source>Total images</source>
+ <target>전체 이미지</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1346311774128536550" datatype="html">
+ <source>Deleted namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7605466414392298530" datatype="html">
+ <source>Namespace contains images</source>
+ <target>네임 스페이스에 이미지가 포함되어 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576483965711201552" datatype="html">
+ <source>RBD Snapshot</source>
+ <target>RBD 스냅샷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3473055924346204357" datatype="html">
+ <source>Parent image must support Layering</source>
+ <target>상위 이미지는 계층화를 지원해야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1152535233999495900" datatype="html">
+ <source>Snapshot must be protected in order to clone.</source>
+ <target>복제하려면 스냅샷을 보호해야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c5331983af566d4ac6a1024d15a3511786a4aa6" datatype="html">
+ <source>You are about to rollback</source>
+ <target>되돌리려고 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6240400332778072187" datatype="html">
+ <source>PROTECTED</source>
+ <target>보호됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9101667614062185213" datatype="html">
+ <source>UNPROTECTED</source>
+ <target>보호되지 않음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4207916966377787111" datatype="html">
+ <source>Created</source>
+ <target>생성됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587768621777516124" datatype="html">
+ <source>RBD snapshot rollback</source>
+ <target>RBD 스냅샷 되돌리기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">305</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2711198699676132148" datatype="html">
+ <source>Rollback</source>
+ <target>롤백</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3330476395115957823" datatype="html">
+ <source>RBD snapshot</source>
+ <target>RBD 스냅샷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">322</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3a7e364a88ea4673199dfa98bc73e6dbe09dfac" datatype="html">
+ <source>Namespaces</source>
+ <target>네임 스페이스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aba82bfd8e177d35b76cad7cd43941f8e5e5acac" datatype="html">
+ <source>Trash</source>
+ <target>휴지통</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5e7f4b1ca49e8d217bd0e12c6f7d6b6a2ade2c18" datatype="html">
+ <source>Overall Performance</source>
+ <target>통합 성능</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c0408946a6d67185947f455f15cc201d0d78e6" datatype="html">
+ <source>Purge Trash</source>
+ <target>휴지통 비우기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c96a761dc55a21882c132c929583a424c9b8cf4" datatype="html">
+ <source>Expired at</source>
+ <target>만료됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="661041e3fcff4d3e75c561e038ca2504cf2cc643" datatype="html">
+ <source>Protected until</source>
+ <target>보호됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee3b2322a1d3277f7e3fdb8a5141ac42bcf350b" datatype="html">
+ <source>This image is protected until <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5611592591303869712" datatype="html">
+ <source>Status</source>
+ <target>상태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">213</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">285</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2155633476201267204" datatype="html">
+ <source>Deleted At</source>
+ <target>삭제됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0b5d789d42c0e69348e5fe0037fcbf5b5fbbdcc" datatype="html">
+ <source>Move an image to trash</source>
+ <target>이미지를 휴지통에 이동</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ad22c1d4aab3b8946603cea62de266d5129ca10" datatype="html">
+ <source>This image contains snapshot(s), which will prevent it from being removed after moved to trash.</source>
+ <target>이 이미지에는 스냅샷이 포함되어 있어 휴지통으로 이동한 후 제거되지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">15,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d4a5f5698bc8118b2e120b9bb72eff339094dd0" datatype="html">
+ <source>To move <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> to trash, click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Move<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Optionally, you can pick an expiration date.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">19,20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f27d390844aad53b4240360e928156c5f0d326" datatype="html">
+ <source>Protection expires at</source>
+ <target>보호가 만료되는 </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da166e9a0d27322f6ba8916d71ecc0f9905bb4b1" datatype="html">
+ <source>NOT PROTECTED</source>
+ <target>보호되지 않음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1506e5f2ca22cad14502ec7a20fb6113ace145d" datatype="html">
+ <source>Wrong date format. Please use &quot;YYYY-MM-DD HH:mm:ss&quot;.</source>
+ <target>날짜 형식 오류. &quot;YYYY-MM-DD HH:mm:ss&quot; 형식으로 지정하세요.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa7ea0bb7495281e0b3258467ac7d90a1e44a1a1" datatype="html">
+ <source>Protection has already expired. Please pick a future date or leave it empty.</source>
+ <target>보호가 이미 만료되었습니다. 날짜를 선택하거나 비워 두십시오.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d8613436532acac2b97d17de28b50f93e6bd0222" datatype="html">
+ <source>To purge, select  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>All<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>  or one pool and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Purge<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55a4f598a4894b7fd5cb88f0ffd3c37ad009dd70" datatype="html">
+ <source>Pool:</source>
+ <target>데이터 풀 :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d43dd2b9f7797e4cf3a604695bb33e4479108516" datatype="html">
+ <source>Pool name...</source>
+ <target>데이터 풀 이름 :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dfc3c34e182ea73c5d784ff7c8135f087992dac1" datatype="html">
+ <source>All</source>
+ <target>전체</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0e7c7ed1d51a0c205c815048bc9f79e24ee6db2" datatype="html">
+ <source>Restore Image</source>
+ <target>이미지 복구</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3bc4aaf0dce75dc5e01ee5c825a652dc8aea8f0" datatype="html">
+ <source>To restore  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>,  type the image's new name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Restore<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41307dd56fea669eed72e12a6c23af275f6bfd82" datatype="html">
+ <source>New Name</source>
+ <target>새로운 이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3625859417927520024" datatype="html">
+ <source>id</source>
+ <target>아이디</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6537904131139019667" datatype="html">
+ <source>type</source>
+ <target>형태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8901220148451863928" datatype="html">
+ <source>state</source>
+ <target>상태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7925190601961269841" datatype="html">
+ <source>version</source>
+ <target>버전</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6641024648411549335" datatype="html">
+ <source>Host</source>
+ <target>호스트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773272191572353800" datatype="html">
+ <source>root</source>
+ <target>루트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6364513948635353490" datatype="html">
+ <source>Evicted client '<x id="PH" equiv-text="clientId"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c1e17956453ad772dbe82d6946f62748c692f3e" datatype="html">
+ <source>Ranks</source>
+ <target>순위</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b24e0b0b1629d2e8a51b9da7c75d6e6379f4bc4" datatype="html">
+ <source>Standbys</source>
+ <target>대기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="50df62325726db950523a5be1c78b8905fcc25d4" datatype="html">
+ <source>MDS performance counters</source>
+ <target>MDS 성능 카운터</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4578796959376778578" datatype="html">
+ <source>Standby daemons</source>
+ <target>대기 중인 데몬</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="665219418211496660" datatype="html">
+ <source>Rank</source>
+ <target>순위</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5445409664838149993" datatype="html">
+ <source>Daemon</source>
+ <target>데몬</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5306473977542913614" datatype="html">
+ <source>Activity</source>
+ <target>활동</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3998441303515229547" datatype="html">
+ <source>Dentries</source>
+ <target>덴트리들</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7877631502958415163" datatype="html">
+ <source>Inodes</source>
+ <target>아이노드들</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6129397096478256985" datatype="html">
+ <source>Dirs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3011876564696453148" datatype="html">
+ <source>Caps</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8650499415827640724" datatype="html">
+ <source>Type</source>
+ <target>형태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="142654590491855672" datatype="html">
+ <source>Usage</source>
+ <target>사용량</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">326</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb8293aa8161433778762ae025ffd5e7c85795e" datatype="html">
+ <source>Quotas</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">540</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66785722678644243" datatype="html">
+ <source>Origin</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8911059720204770105" datatype="html">
+ <source>Path</source>
+ <target>경로</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6111756909052789805" datatype="html">
+ <source>Cannot create snapshots for files/folders in the subvolume <x id="PH" equiv-text="folders[2]"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7503263437025060215" datatype="html">
+ <source>Max size</source>
+ <target>최대 크기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6763343019307619111" datatype="html">
+ <source>Max files</source>
+ <target>최대 파일</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327403486214540377" datatype="html">
+ <source>The inherited <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> is the maximum value to be used.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">434,437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3768927257183755959" datatype="html">
+ <source>Save</source>
+ <target>저장하기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">440</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6328794256834621774" datatype="html">
+ <source><x id="PH" equiv-text="action"/> CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> quota for '<x id="PH_2" equiv-text="path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">446</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9130352375983418123" datatype="html">
+ <source>size</source>
+ <target>크기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6889473896134264260" datatype="html">
+ <source>files</source>
+ <target>파일</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2244434638607433133" datatype="html">
+ <source><x id="PH" equiv-text="this.getQuotaName()"/> quota <x id="PH_1" equiv-text="value"/> from '<x id="PH_2" equiv-text="path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">460</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6960117167304061503" datatype="html">
+ <source>Value has to be at least 0 or more</source>
+ <target>값은 0 이상 이어야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">484</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6740501370117796629" datatype="html">
+ <source>Value has to be at most <x id="PH" equiv-text="maxValue"/> or less</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7239750919884229270" datatype="html">
+ <source>Updated</source>
+ <target>업데이트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">499</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8885980874806414253" datatype="html">
+ <source>in order to inherit <x id="PH" equiv-text="quotaValue"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4182949309891923991" datatype="html">
+ <source>which isn't used because of the inheritance of <x id="PH" equiv-text="quotaValue"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7421970649864638435" datatype="html">
+ <source>in order to have no quota on the directory</source>
+ <target>디렉토리에 할당량이 없도록 하기 위해서</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6730229976797004508" datatype="html">
+ <source><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">530,533</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="827679535246546876" datatype="html">
+ <source>Create Snapshot</source>
+ <target>스냅샷 생성</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">542</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">552</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4747656362969857823" datatype="html">
+ <source>Please enter the name of the snapshot.</source>
+ <target>스냅샷 이름을 입력하세요.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3667696812078358068" datatype="html">
+ <source>Created snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="753342836137587734" datatype="html">
+ <source>CephFs Snapshot</source>
+ <target>CephFs 스냅샷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">670</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2774104291801979963" datatype="html">
+ <source>Deleted snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">683</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4816216590591222133" datatype="html">
+ <source>Enabled</source>
+ <target>활성화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ffe39df9d88c972792bd8688b215392deb8313d" datatype="html">
+ <source>Clients</source>
+ <target>클라이언트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e213942c6354b9cbe7a650f0f1499bfc1000fb6" datatype="html">
+ <source>Directories</source>
+ <target>디렉토리</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fbbaf5cb02ed419e79a27072478f716a4666a99d" datatype="html">
+ <source>Performance Details</source>
+ <target>성능 세부정보</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0" datatype="html">
+ <source>Description</source>
+ <target>설명</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ad112ce9bcd55dfd137792a86afe1b5a5b13cf8" datatype="html">
+ <source>Long description</source>
+ <target>자세한 설명</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="26fb5f81b3581f06b9210defb0e71dc69a67e819" datatype="html">
+ <source>Current values</source>
+ <target>현재 값</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7cee38a2259526c519f878e71b964f41db4348" datatype="html">
+ <source>Default</source>
+ <target>기본값</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33e1c1d9fc05ca3f62fcc8a1170fc31ebae4229c" datatype="html">
+ <source>Daemon default</source>
+ <target>데몬 기본 값</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f61c6867295f3b53d23557021f2f4e0aa1d0b8fc" datatype="html">
+ <source>Type</source>
+ <target>형태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9abcd7c82643d60c22733470463f74e4a54bc069" datatype="html">
+ <source>Min</source>
+ <target>최소</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3ced4d162a0a55ee233a187ce7208ba5e922418" datatype="html">
+ <source>Max</source>
+ <target>최대</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="920617c6a1a4805e53bcb5af6a9c76f8387e89c6" datatype="html">
+ <source>Flags</source>
+ <target>플래그</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5" datatype="html">
+ <source>Services</source>
+ <target>서비스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6834fa6b43d1ecbdf147c48dd9c4d72f1484571d" datatype="html">
+ <source>Source</source>
+ <target>소스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a446fb0eb11fbffcac805ece5a2d306d24e733d8" datatype="html">
+ <source>Level</source>
+ <target>레벨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39f2fb094e9b2eda13163fa3f3a31594cf9c1307" datatype="html">
+ <source>Can be updated at runtime (editable)</source>
+ <target>운영 중에 업데이트 가능 (편집 가능)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
+ <source>Tags</source>
+ <target>태그</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ab0089ef47af61ca1d137bc908b96c290dfd9287" datatype="html">
+ <source>Enum values</source>
+ <target>열거형 값</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="819476f1264f1659f38e86f6abb542141b184832" datatype="html">
+ <source>See also</source>
+ <target>더보기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="543199344025799954" datatype="html">
+ <source>The value can be updated at runtime.</source>
+ <target>이 값은 운영 중에 업데이트 할 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1718354829128482129" datatype="html">
+ <source>Daemons/clients do not pull this value from the
+ monitor config database. We disallow setting this option via 'ceph config
+ set ...'. This option should be configured via ceph.conf or via the
+ command line.</source>
+ <target>데몬/클라이언트는 모니터 구성 데이터베이스에서이 값을 가져 오지 않습니다. 'ceph config set ...'을 통해 옵션을 설정할 수 없습니다. 이 옵션은 ceph.conf 또는 명령어를 통해 구성해야합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">15,18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2345189734548717257" datatype="html">
+ <source>Option takes effect only during daemon startup.</source>
+ <target>옵션은 데몬 시작 시에만 적용됩니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5523310713159993513" datatype="html">
+ <source>Option only affects cluster creation.</source>
+ <target>옵션은 클러스터 생성할 때만 영향을 줍니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1064479086902933123" datatype="html">
+ <source>Option only affects daemon creation.</source>
+ <target>옵션은 데몬 생성에만 영향을 줍니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="809b0c848932a41318f77a2aace904ef429c13f4" datatype="html">
+ <source>Values</source>
+ <target>값</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5894f7158499fdb89527af50c9f1cf7d4c95cad6" datatype="html">
+ <source>-- Default --</source>
+ <target>-- 기본 값 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="514f6e12d035a6d9b00de6b3e55c18b73488da07" datatype="html">
+ <source>true</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="774f5e6a183dea08393789b6f72e86afad729419" datatype="html">
+ <source>false</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="82029b6db704c56a2aa3e82ac555b8655356b077" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ed8b3967a7326b81b191c9f490006e6a6777a9a" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2337058106409853613" datatype="html">
+ <source>Updated config option <x id="PH" equiv-text="request.name"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3733215288982610673" datatype="html">
+ <source>Level</source>
+ <target>레벨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2218082343053095278" datatype="html">
+ <source>Service</source>
+ <target>서비스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3553216189604488439" datatype="html">
+ <source>Modified</source>
+ <target>수정됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844248428439297756" datatype="html">
+ <source>Current value</source>
+ <target>현재 값</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208877297843037352" datatype="html">
+ <source>Editable</source>
+ <target>편집 가능</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b266042bac4c3a2eff4834e40fb9dc4767a709" datatype="html">
+ <source>Cluster Resources</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="099b441d49333b3c6d30b36dc0a4763e64c78920" datatype="html">
+ <source>Hosts</source>
+ <target>호스트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57e6e608ece53a26f6d509c90ed4f83e467741af" datatype="html">
+ <source>Storage Capacity</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19ece2cb2b9097c0f75af8e62b4b3b25d399a006" datatype="html">
+ <source>Number of devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b161e3d25fd1b42a781f4e923a58a94925988ddf" datatype="html">
+ <source>Raw capacity</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb6f3e2a26f3a6f2bc33f91adcd60502dbe5adac" datatype="html">
+ <source>CPUs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58d4a9814864741040bc5905b6a368836e683f76" datatype="html">
+ <source>Memory</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dbb81e566a861d4aa0a094366e4083e50863ee92" datatype="html">
+ <source>Host Details</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="453dc2810080a744223faac6da2b3ee9ed63a583" datatype="html">
+ <source>Welcome to <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1eec874e1928ca53baa9914781ce203b5f72b0c" datatype="html">
+ <source>Please expand your cluster first</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2195fd96b0a00f560449b50bd032e6d9b357730" datatype="html">
+ <source>Expand Cluster</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb075d0450deb6f381616f7da4b9244ced843053" datatype="html">
+ <source>Skip</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55b6ce65571b8893440a4fc92776570f8fe7cc97" datatype="html">
+ <source>Add Hosts</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="162f763675c24b557a60eba0758558222369e0c7" datatype="html">
+ <source>Create OSDs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fef7a7b8db05c351c5287db48488abca530bdb54" datatype="html">
+ <source>Create Services</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="176873b4533ddeabf95992cbd7b91b9d01c6d557" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ed90ec4409b9f6b552982d96f89db27259e763c" datatype="html">
+ <source>You are about to skip the cluster expansion process. You’ll need to <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>navigate through the menu to add hosts and services.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">90,91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d1dcf2a9146caac0581329acf94806ec69a89a5" datatype="html">
+ <source>Are you sure you want to continue?</source>
+ <target>계속 하시겠습니까?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6759205696902713848" datatype="html">
+ <source>Warning</source>
+ <target>경고</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">357</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6962699013778688473" datatype="html">
+ <source>Continue</source>
+ <target>계속</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6156560100092571435" datatype="html">
+ <source>Cluster expansion skipped by user</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520085823873354736" datatype="html">
+ <source>Cluster expansion was successful</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176230351113290618" datatype="html">
+ <source>Expand Cluster</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="738de688b22fba5d0dc7a5e549996838dddad0ee" datatype="html">
+ <source>CRUSH map viewer</source>
+ <target>크러쉬 맵 보기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/crushmap/crushmap.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e24569eca61d598c8b01defbbbb1fa8bd5222bc" datatype="html">
+ <source>Devices</source>
+ <target>장치</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17137bac47e1e020d139256ded0006a671966e73" datatype="html">
+ <source>Physical Disks</source>
+ <target>물리 디스크</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="deba10b7279a589d01e919ea11f43c79ca1773e3" datatype="html">
+ <source>Device health</source>
+ <target>장치 상태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d87fc20ea8e5f0f0500ba5d5061b345be78ec5e" datatype="html">
+ <source>No hostname found.</source>
+ <target>호스트 이름을 찾을 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9a541ec1a4319fffc16ad3b3ab2c2b6d251a829d" datatype="html">
+ <source>Hostname</source>
+ <target>호스트 이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee6875e67b53cac30a02b57cf76e485f7e60caf4" datatype="html">
+ <source>To add multiple hosts at once, you can enter:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a8370b19ccf673fb28fa9db36a08f9901887cc7" datatype="html">
+ <source>a comma-separated list of hostnames <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-01,example-02,example-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="68f2c05396ec8a5f59e8da42d1f6c7310fa8c37c" datatype="html">
+ <source>a range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e00b9bba448e79add37740e53dc953fbb89f9c5" datatype="html">
+ <source>a comma separated range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b3f5e5291541678f7afa49d28fad5ca848a8061" datatype="html">
+ <source>The chosen hostname is already in use.</source>
+ <target>호스트 이름이 사용중입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="42365f623c57973d1d13d2038e8a2d4c02fb9b9f" datatype="html">
+ <source>Network address</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3859bdca1ae89e611e214c205fccf0147b4d0f6b" datatype="html">
+ <source>The value is not a valid IP address.</source>
+ <target>유효하지 않은 IP 입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2af7efecfae8d7fed3b07f718a623eca1ad8163f" datatype="html">
+ <source>Labels</source>
+ <target>라벨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9da2afd4fa358b66d4d95fe7e8f4b659a7144e" datatype="html">
+ <source>Maintenance Mode</source>
+ <target>유지보수 모드</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="468785112451259935" datatype="html">
+ <source>There are no labels.</source>
+ <target>라벨이 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4664081995078497865" datatype="html">
+ <source>Filter or add labels</source>
+ <target>필터 또는 라벨 추가</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4897817053917542646" datatype="html">
+ <source>Add label</source>
+ <target>라벨 추가</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">313</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1187321380561233505" datatype="html">
+ <source>host</source>
+ <target>호스트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40661476cb24c89d8b06614998e31d5fbe84eeb6" datatype="html">
+ <source>Hosts List</source>
+ <target>호스트 목록</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b7a4e1e5a316f8547af1d6d2311a5cec8c5c1d87" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ msg }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6e8e8844e9e7a7b626a4699c08b6c0c81297a7b" datatype="html">
+ <source>Data will be available only if Orchestrator is available.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4baf526199fed59071adf555271791283adc408" datatype="html">
+ <source>SSD, NVMEs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="22d5531d79f0d7269a0a752e56a848807dd37095" datatype="html">
+ <source>Flash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4025065730478477779" datatype="html">
+ <source>The feature is disabled because the selected host is not managed by Orchestrator.</source>
+ <target>선택한 호스트가 Orchestrator에서 관리되지 않기 때문에 이 기능을 사용할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7143579180750436311" datatype="html">
+ <source>Services</source>
+ <target>서비스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="546766753072101168" datatype="html">
+ <source>Labels</source>
+ <target>라벨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1141886420788473147" datatype="html">
+ <source>Model</source>
+ <target>모델</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4027647877328291519" datatype="html">
+ <source>CPUs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2445398473573060226" datatype="html">
+ <source>Cores</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1656823484917332451" datatype="html">
+ <source>Total Memory</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1939212557812454069" datatype="html">
+ <source>Raw Capacity</source>
+ <target>물리 용량</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5579687933271468638" datatype="html">
+ <source>HDDs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1889285841762768492" datatype="html">
+ <source>Flash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1578709829957887527" datatype="html">
+ <source>NICs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4723031838495967601" datatype="html">
+ <source>Edit Host: <x id="PH" equiv-text="host.hostname"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6004907173026319041" datatype="html">
+ <source>Edit Host</source>
+ <target>호스트 편집</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5618131051466022401" datatype="html">
+ <source>Updated Host &quot;<x id="PH" equiv-text="host.hostname"/>&quot;</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1701954433367210342" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; moved to maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3108406586869160854" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; cannot be put into maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1737753151350322492" datatype="html">
+ <source><x id="PH" equiv-text="error.error['detail']"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4054533801359952167" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; has exited maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5837599005212786659" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; stopped draining</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1357236071975782353" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; started draining</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5658400717636093668" datatype="html">
+ <source>Identify</source>
+ <target>식별자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6966707768479328825" datatype="html">
+ <source>Device path</source>
+ <target>장치 경로</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3955868613858648955" datatype="html">
+ <source>Available</source>
+ <target>사용 가능</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="158816374076721379" datatype="html">
+ <source>Vendor</source>
+ <target>벤더</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6024104799101504292" datatype="html">
+ <source>OSDs</source>
+ <target>스토리지 디바이스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3422162477846071958" datatype="html">
+ <source>Identify device <x id="PH" equiv-text="device"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4910073658089977244" datatype="html">
+ <source>Please enter the duration how long to blink the LED.</source>
+ <target>LED를 깜박일 기간을 입력하십시오.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5764931367607989415" datatype="html">
+ <source>1 minute</source>
+ <target>1분</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809466133764752509" datatype="html">
+ <source>2 minutes</source>
+ <target>2분</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">235</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1487672983218679675" datatype="html">
+ <source>5 minutes</source>
+ <target>5분</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603584938775296395" datatype="html">
+ <source>10 minutes</source>
+ <target>10분</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6648333117195452824" datatype="html">
+ <source>15 minutes</source>
+ <target>15분</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6560281329999108838" datatype="html">
+ <source>Execute</source>
+ <target>실행</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6901229416977800100" datatype="html">
+ <source>Identifying '<x id="PH" equiv-text="device"/>' started on host '<x id="PH_1" equiv-text="hostname"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d556ab48a65722b400e497f61737f553ee0f89e2" datatype="html">
+ <source>Cluster Logs</source>
+ <target>클러스터 로그</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5f966baffd188be0e8adc2d7067b86e55fc9b9de" datatype="html">
+ <source>Audit Logs</source>
+ <target>감사 로그</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4193c9eb868aeec119b78a14795241e0aa5e8b60" datatype="html">
+ <source>Priority:</source>
+ <target>우선순위:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d78ca51eab260ce3fd917d39190d64df5229b6e" datatype="html">
+ <source>Keyword:</source>
+ <target>키워드:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="05fa0bded36de6e73a1fa44838b627349dace044" datatype="html">
+ <source>Date:</source>
+ <target>날짜:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a400388de1899b1917138cf7e5286376f72847" datatype="html">
+ <source>Time range:</source>
+ <target>시간 범위:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="de0478286b8b5a939db54e9e5282405364ad2d61" datatype="html">
+ <source>No log entries found. Please try to select different filter options.</source>
+ <target>로그 항목을 찾을 수 없습니다. 다른 필터 옵션을 선택하십시오.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7479674d91142b785b9547a87e5fb51cb16108" datatype="html">
+ <source>Reset filter.</source>
+ <target>필터 초기화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="31a9c2870a934b594d1390146c489f76440859ea" datatype="html">
+ <source>Edit Manager module</source>
+ <target>관리 모듈 편집</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="46e09b8290d3d0afdb6baa2021395b0570606a31" datatype="html">
+ <source>The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</source>
+ <target>입력된 값이 유효한 UUID가 아닙니다, 예 : 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7aacd038b39cfd347107d01d1dc27f5cb3e0951c" datatype="html">
+ <source>The entered value needs to be a valid IP address.</source>
+ <target>입력된 값은 유효한 IP 주소여야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f19106149f4b07a0d721f9d317afed393cb7bd93" datatype="html">
+ <source>The entered value is too high! It must be lower or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d33c40ef9a6c3bf0888df831b25e41e65f9d15b" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eae7086660cf1e38c7194a2c49ff52cc656f90f5" datatype="html">
+ <source>The entered value needs to be a number.</source>
+ <target>입력한 값은 숫자여야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">194</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a73376e04b4fb3a20734c8c39743fba32e6676ce" datatype="html">
+ <source>The entered value needs to be a number or decimal.</source>
+ <target>입력 된 값은 숫자 또는 십진수여야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1898719236268328097" datatype="html">
+ <source>Updated options for module '<x id="PH" equiv-text="this.moduleName"/>'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4186041075388034600" datatype="html">
+ <source>Always-On</source>
+ <target>항상</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7585826646011739428" datatype="html">
+ <source>Edit</source>
+ <target>편집</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2180291763949669799" datatype="html">
+ <source>Enable</source>
+ <target>활성화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9187855490716817910" datatype="html">
+ <source>Disable</source>
+ <target>비활성화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1600086764852993170" datatype="html">
+ <source>This Manager module is always on.</source>
+ <target>이 매니저 모듈은 항상 켜져 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3895296744591223546" datatype="html">
+ <source>Reconnecting, please wait ...</source>
+ <target>다시 연결 중 입니다. 잠시 기다려주세요.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81b97b8ea996ad1e4f9fca8415021850214884b1" datatype="html">
+ <source>Status</source>
+ <target>상태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57ec6032f5618d4a9f16eb950ad23d2ce7c24b54" datatype="html">
+ <source>Cluster ID</source>
+ <target>클러스터 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67d7facc3fec5f8a49ab9ba0a245872184264ce5" datatype="html">
+ <source>monmap modified</source>
+ <target>몬맵 변경 시간</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4906731aaf2b94b4f547646c9bfe58bb77951b6" datatype="html">
+ <source>monmap epoch</source>
+ <target>몬맵 변경 번호</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd4ee06ffdc46d9dfbd0c0c4f81399021c680056" datatype="html">
+ <source>quorum con</source>
+ <target>Quorum 일치 번호</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1176c7db8a8276ccb44cc3d42e2c28d9fa6c6596" datatype="html">
+ <source>quorum mon</source>
+ <target>Quorum 모니터 상태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="530ef677a09d681b3ab68cb0760494b3ae72a77c" datatype="html">
+ <source>required con</source>
+ <target>요구 일치 번호</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a91558e0d506c32021c31843f8f168899fc65cbf" datatype="html">
+ <source>required mon</source>
+ <target>요구 모니터 상태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3abe9eac5bcd94a54c8da93b312e085ec512e74" datatype="html">
+ <source>In Quorum</source>
+ <target>Quorum에 포함</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba4b748a676e1f217ce1e736fb7ec1215e677bae" datatype="html">
+ <source>Not In Quorum</source>
+ <target>Quorum에 미포함</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3517477838460618200" datatype="html">
+ <source>Public Address</source>
+ <target>Public 주소</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6949358970125514744" datatype="html">
+ <source>Open Sessions</source>
+ <target>활성화 세션</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4383e9662ea19839c7499b2128d43a195e564317" datatype="html">
+ <source>OSD creation preview</source>
+ <target>스토리지 디바이스 생성 미리 보기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="366225c51e0b00bcb1c55795a0dc5e81c455f84e" datatype="html">
+ <source>DriveGroups</source>
+ <target>드라이브 그룹</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91853167141c37b58868f3b0421383dd72fa8a01" datatype="html">
+ <source>Attributes (OSD map)</source>
+ <target>속성 (스토리지 디바이스 맵)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f721a500a68c357e8f2a01e60510f6a01e4ba529" datatype="html">
+ <source>Metadata</source>
+ <target>메타 데이터</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97842f379e1d4157ac3ab0661b90c352e7cb72d5" datatype="html">
+ <source>Metadata not available</source>
+ <target>메타 데이터를 사용할 수 없음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24e28e19c5703d7c6be44f4eb595a6a43b618ed" datatype="html">
+ <source>Performance counter</source>
+ <target>성능 카운터</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ccb4f84edc0b4e76415bb3f9b73d725b06683af3" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ name }}"/> devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60cb3d01e5ddf266ecb4271007a1c3d0f3efdc22" datatype="html">
+ <source>The primary storage devices. These devices contain all OSD data.</source>
+ <target>주 저장 장치입니다. 이러한 장치에는 모든 스토리지 디바이스 데이터가 포함되어 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b432e04886d0d1fd84f740477383051f85addcf2" datatype="html">
+ <source>Write-Ahead-Log devices. These devices are used for BlueStore’s internal journal. It is only useful to use a WAL device if the device is faster than the primary device (e.g. NVME devices or SSDs). If there is only a small amount of fast storage available (e.g., less than a gigabyte), we recommend using it as a WAL device.</source>
+ <target>미리 쓰기 로그 장치입니다. 이러한 장치는 BlueStore의 내부 저널에 사용됩니다. WAL 디바이스는 디바이스가 기본 디바이스(예: NVME 디바이스 또는 SSD)보다 빠른 경우에만 유용합니다. SSD). 사용 가능한 고속 스토리지가 소량(예: 1기가바이트 미만)뿐이라면 WAL 장치로 사용하는 것이 좋습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87e181ab9e8393aa5ed759dd3d53836e32c8ffe" datatype="html">
+ <source>DB devices can be used for storing BlueStore’s internal metadata. It is only helpful to provision a DB device if it is faster than the primary device (e.g. NVME devices or SSD).</source>
+ <target>DB 장치는 BlueStore의 내부 메타데이터를 저장하는 데 사용할 수 있습니다. DB 디바이스가 기본 디바이스(예: NVME 디바이스 또는 SSD)보다 빠른 경우에만 프로비저닝하는 것이 유용합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
+ <source>Add</source>
+ <target>추가</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="99ee4faa69cd2ea8e3678c1f557c0ff1f05aae46" datatype="html">
+ <source>Clear</source>
+ <target>초기화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e0fd3c7af0630f93befa6234a693a32a61084e0" datatype="html">
+ <source>Raw capacity: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1961811273151129466" datatype="html">
+ <source>No available devices</source>
+ <target>사용 가능한 장치가 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617271647728055571" datatype="html">
+ <source>Please add primary devices first</source>
+ <target>먼저 기본 장치를 추가하세요.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6368751795251107516" datatype="html">
+ <source>Add devices by using filters</source>
+ <target>필터를 사용하여 장치를 추가합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8edc89137d0d8c5667a2f03230beafae45e58429" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eba28e1805b18f7c8ae2e4bc15dcf063b10b3822" datatype="html">
+ <source>At least one of these filters must be applied in order to proceed:</source>
+ <target>계속 하려면 다음 필터 중 하나 이상을 적용해야 합니다 :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="93389aa2fe2bea50bf89554ee51b28f87ee2fb50" datatype="html">
+ <source>Number of devices: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Raw capacity: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">29,30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6b27c16ddf33b855412c82069dca8120bd3a68a" datatype="html">
+ <source>Individual OSD Flags</source>
+ <target>개별 스토리지 디바이스 플래그</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dba0ed9ba355a3bd3296c0bef3bb518744a51a89" datatype="html">
+ <source>Cluster-wide</source>
+ <target>클러스터</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e2a3f211cea2cbadb29b6df93e544440b6b68d3e" datatype="html">
+ <source>Restore previous selection</source>
+ <target>이전 선택 복원</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1683654169791509804" datatype="html">
+ <source>No Up</source>
+ <target>살아나지 않는</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5754783193519044074" datatype="html">
+ <source>OSDs are not allowed to start</source>
+ <target>스토리지 디바이스를 시작할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4413588319909369773" datatype="html">
+ <source>No Down</source>
+ <target>죽일 수 없는</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1348746748821823470" datatype="html">
+ <source>OSD failure reports are being ignored, such that the monitors will not mark OSDs down</source>
+ <target>모니터가 스토리지 디바이스들의 다운을 표시하지 않도록 스토리지 디바이스 장애 보고서가 무시되고 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="301172600132606646" datatype="html">
+ <source>No In</source>
+ <target>들어올 수 없는</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4114057962148673377" datatype="html">
+ <source>OSDs that were previously marked out will not be marked back in when they start</source>
+ <target>이전에 마크 아웃 된 스토리지 디바이스는 시작 시 다시 표시되지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5236523991485603657" datatype="html">
+ <source>No Out</source>
+ <target>나갈 수 없는</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1798160169020638994" datatype="html">
+ <source>OSDs will not automatically be marked out after the configured interval</source>
+ <target>구성된 간격 후에는 스토리지 디바이스가 자동으로 표시되지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3225813593817914267" datatype="html">
+ <source>The flag has been enabled for the entire cluster.</source>
+ <target>전체 클러스터에 대해 플래그가 사용되도록 설정되었습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1941050626944682985" datatype="html">
+ <source>Updated OSD Flags</source>
+ <target>업데이트 된 스토리지 디바이스 플래그</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ef50ba2514414f799d4c8fc36067a251904ba81" datatype="html">
+ <source>Cluster-wide OSD Flags</source>
+ <target>클러스터 수준의 스토리지 디바이스 플래그</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9042260521669277115" datatype="html">
+ <source>Pause</source>
+ <target>정지</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6015425610572318971" datatype="html">
+ <source>Pauses reads and writes</source>
+ <target>읽기/쓰기 정지</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314873595759611676" datatype="html">
+ <source>No Scrub</source>
+ <target>빠른 데이터 정리 안함</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773570234687653570" datatype="html">
+ <source>Scrubbing is disabled</source>
+ <target>빠른 데이터 정리 비활성화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5999821123886006899" datatype="html">
+ <source>No Deep Scrub</source>
+ <target>데이터 정리 안함</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5362685148875251772" datatype="html">
+ <source>Deep Scrubbing is disabled</source>
+ <target>데이터 정리 비활성화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5001752039592388485" datatype="html">
+ <source>No Backfill</source>
+ <target>Backfill 안함</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4851280330655956778" datatype="html">
+ <source>Backfilling of PGs is suspended</source>
+ <target>PG의 Backfill이 일시중지 되었습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5994953210305546559" datatype="html">
+ <source>No Rebalance</source>
+ <target>재조정 안함</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3698980403470604587" datatype="html">
+ <source>OSD will choose not to backfill unless PG is also degraded</source>
+ <target>PG가 저하되지 않는 한 스토리지 디바이스는 backfill을 선택하지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4334886823145076432" datatype="html">
+ <source>No Recover</source>
+ <target>복구 되지 않음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8465994741155792816" datatype="html">
+ <source>Recovery of PGs is suspended</source>
+ <target>PG의 복구가 일시중지 되었습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4052740759486923001" datatype="html">
+ <source>Bitwise Sort</source>
+ <target>비트 단위 정렬</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2330377428425572488" datatype="html">
+ <source>Use bitwise sort</source>
+ <target>비트 단위 정렬을 사용하세요.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8943478424576832224" datatype="html">
+ <source>Purged Snapdirs</source>
+ <target>완전히 삭제된 스냅 디렉토리</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7553321860087551262" datatype="html">
+ <source>OSDs have converted snapsets</source>
+ <target>스토리지 디바이스가 변화된 스냅셋을 가지고 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6509988280998256208" datatype="html">
+ <source>Recovery Deletes</source>
+ <target>복구 삭제</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="451760144355116641" datatype="html">
+ <source>Deletes performed during recovery instead of peering</source>
+ <target>피어링 대신 복구 중에 수행된 작업 삭제</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="87832369463084597" datatype="html">
+ <source>PG Log Hard Limit</source>
+ <target>PG 로그 하드 제한</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9135782750879343185" datatype="html">
+ <source>Puts a hard limit on pg log length</source>
+ <target>PG 로그 길이에 하드 제한을 넣으세요</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="formTitle" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <note priority="1" from="description">Example: Create Pool</note>
+ <note priority="1" from="meaning">form title</note>
+ </trans-unit>
+ <trans-unit id="43ecf6bee2aebc07b0aad6dc1fe13e38d14687fa" datatype="html">
+ <source>Shared devices</source>
+ <target>공유 디바이스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7a1c376f6f1b37de4c318ff2106255ba6c0f5b0b" datatype="html">
+ <source>WAL slots</source>
+ <target>WAL 슬롯</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73811a6f37b63e6b0e491e221bfa21e9dea8a87a" datatype="html">
+ <source>How many OSDs per WAL device.</source>
+ <target>WAL 디바이스 별 스토리지 디바이스 수</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c67a7ac4762ef1cc855056c6b4daab93e53a0a5" datatype="html">
+ <source>Specify 0 to let Orchestrator backend decide it.</source>
+ <target>Orchestrator 백엔드에서 결정하도록 하려면 0을 설정하십시오.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bda9362e06e6c67341b4a8425b0d29d6b84464b" datatype="html">
+ <source>Value should be greater than or equal to 0</source>
+ <target>값은 0보다 크거나 같아야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="324c2b10152b9dd908222bb0b71f61beb60a30c5" datatype="html">
+ <source>DB slots</source>
+ <target>DB 슬롯</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c23cf12ef9c76f37fc7a4b7ae3e00fb0f68b6e26" datatype="html">
+ <source>How many OSDs per DB device.</source>
+ <target>DB 디바이스 별 스토리지 디바이스 수</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8255877266497322342" datatype="html">
+ <source>Encryption</source>
+ <target>암호화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b49d7877d24112d4bdfce9256edf61a007fae888" datatype="html">
+ <source>OSDs List</source>
+ <target>스토리지 디바이스 목록</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="172ada0fcf6490b24a897517e9f4299215873ff8" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD(s) <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be marked <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">59,60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="262a49e60d5f6ed9825582ccf3d5ae39daa1da60" datatype="html">
+ <source>The <x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> not safe to be <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>! <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71,72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="74bd20d5f558d14cb2fa41ae863cf09c47d02018" datatype="html">
+ <source>{VAR_SELECT, select, true {OSD is} other {OSDs are}}</source>
+ <target>{VAR_SELECT, select, true {} other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0e217fd717c5b1f5c17f00c5b174de855acbef0" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">74,75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8cf121660bed7098516a1efe85831d6f415a9411" datatype="html">
+ <source>Preserve OSD ID(s) for replacement.</source>
+ <target>교체할 스토리지 디바이스 아이디를 보존합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4435645098786961170" datatype="html">
+ <source>out</source>
+ <target>아웃</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136018875175606726" datatype="html">
+ <source>in</source>
+ <target>인</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1301930865667956193" datatype="html">
+ <source>down</source>
+ <target>다운</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1226060325201042854" datatype="html">
+ <source>Mark</source>
+ <target>표시</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1256299033316818951" datatype="html">
+ <source>OSD lost</source>
+ <target>스토리지 디바이스 손실</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2795727560928976873" datatype="html">
+ <source>marked lost</source>
+ <target>손실 표시</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7685933846431786388" datatype="html">
+ <source>Purge</source>
+ <target>완전히 제거</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5941516286393808546" datatype="html">
+ <source>OSD</source>
+ <target>스토리지 디바이스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3416443212235382421" datatype="html">
+ <source>purged</source>
+ <target>완전히 제거됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9191368063029792986" datatype="html">
+ <source>destroy</source>
+ <target>파기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4425946029386289247" datatype="html">
+ <source>destroyed</source>
+ <target>파기됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2870788902465061969" datatype="html">
+ <source>Flags</source>
+ <target>플래그</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8995035642420075344" datatype="html">
+ <source>Recovery Priority</source>
+ <target>복구 우선 순위</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3601135996773579607" datatype="html">
+ <source>PG scrub</source>
+ <target>빠른 PG 데이터 정리</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136079353894161076" datatype="html">
+ <source>Device class</source>
+ <target>장치 클래스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6382718875453721838" datatype="html">
+ <source>PGs</source>
+ <target>PGs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3660230483843323377" datatype="html">
+ <source>Read bytes</source>
+ <target>읽은 바이트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">329</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3909578649547040612" datatype="html">
+ <source>Write bytes</source>
+ <target>쓰여진 바이트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3182358405280886750" datatype="html">
+ <source>Read ops</source>
+ <target>읽기 ops</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171292502535561083" datatype="html">
+ <source>Write ops</source>
+ <target>쓰기 ops</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6706824709967518168" datatype="html">
+ <source>Edit OSD: <x id="PH" equiv-text="selectedOsd.id"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">451</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1125148356983553148" datatype="html">
+ <source>Edit OSD</source>
+ <target>스토리지 디바이스 편집</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="970212458427610374" datatype="html">
+ <source>Updated OSD '<x id="PH" equiv-text="selectedOsd.id"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">466</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7554728686176829307" datatype="html">
+ <source>Mark OSD <x id="PH" equiv-text="markAction"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="478122291463667978" datatype="html">
+ <source>Mark <x id="PH" equiv-text="markAction"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">502</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2456043080471762298" datatype="html">
+ <source>delete</source>
+ <target>삭제</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">530</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="588230151780724018" datatype="html">
+ <source>deleted</source>
+ <target>삭제됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">532</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1ef1c12ddcee305353623919ef02778569f5454" datatype="html">
+ <source>Advanced configuration options</source>
+ <target>고급 설정 옵션</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7771252117308888928" datatype="html">
+ <source>PG scrub options</source>
+ <target>PG 빠른 데이터 정리 옵션</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1797901277775175680" datatype="html">
+ <source>Updated PG scrub options</source>
+ <target>PG 빠른 데이터 정리 옵션 업데이트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c35f9c5f268a514b970cc55e9a5dc4bed0988e7f" datatype="html">
+ <source>OSD Recovery Priority</source>
+ <target>스토리지 디바이스 복구 우선 순위</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74af38005e8a8914e45af2ec412e11ceafef8b6" datatype="html">
+ <source>Priority</source>
+ <target>우선 순위</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f48f04b379bfba133825747adfd238d511412e" datatype="html">
+ <source>Customize priority values</source>
+ <target>우선 순위 값 사용자 설정</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aa19de2a2b54cbda39e9c62917b23044c087776" datatype="html">
+ <source>This field is required!</source>
+ <target>이 필드는 필수입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">406</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b699e94bf376491bd50b70a98531071c737eaf40" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="98fe13e7ad6c2b80375d204b47858ded83f80e15" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423a3c111be47fc5a1bfe46ceb58c81c84db691" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3234179038052466481" datatype="html">
+ <source>Max Backfills</source>
+ <target>최대 Backfills</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847070960491384020" datatype="html">
+ <source>Recovery Max Active</source>
+ <target>최대 활성화 복구</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2088615724570210504" datatype="html">
+ <source>Recovery Max Single Start</source>
+ <target>최대 단일 시작 복구</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8627094894361422565" datatype="html">
+ <source>Recovery Sleep</source>
+ <target>잠자기 복구</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7590013429208346303" datatype="html">
+ <source>Custom</source>
+ <target>사용자 설정</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4937275625032609020" datatype="html">
+ <source>Updated OSD recovery speed priority '<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">227,229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5251a4355cece3075db43f15d69a24a0f8485707" datatype="html">
+ <source>Reweight OSD: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67650b2998db48201b2c6176cbfef51e7211ccaa" datatype="html">
+ <source>The value needs to be between 0 and 1.</source>
+ <target>값은 0과 1 사이어야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f077ceb52c967a8fe2de9ef0a9d65d72badf186" datatype="html">
+ <source>OSDs <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/>Scrub</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b73a34ba65b3073e3560dce828a16d7fd3c0f4" datatype="html">
+ <source>{VAR_SELECT, select, true {Deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {} other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c00119503aad4012b77049eee41293338f67756c" datatype="html">
+ <source>You are about to apply a <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/>scrub to the OSD(s): <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fad3dc421817a16dd6c46c1a0c36de619a8d776e" datatype="html">
+ <source>{VAR_SELECT, select, true {deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {} other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1086427836866943370" datatype="html">
+ <source><x id="PH" equiv-text="operation"/> was initialized in the following OSD(s): <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts</context>
+ <context context-type="linenumber">42,44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47c97aa28f64b11fa5842795fdd02c8c0863c97b" datatype="html">
+ <source>To see all active Prometheus alerts, please provide the URL to the API of Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6343323763459782070" datatype="html">
+ <source>Create Silence</source>
+ <target>Silence 생성</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1895957424873987405" datatype="html">
+ <source>Job</source>
+ <target>작업</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491474782694268231" datatype="html">
+ <source>Severity</source>
+ <target>심각도</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3326877877555410533" datatype="html">
+ <source>Started</source>
+ <target>시작됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2375260419993138758" datatype="html">
+ <source>URL</source>
+ <target>URL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="880ad4df5a2051a437321443d69c9a866699e5ad" datatype="html">
+ <source>Active Alerts</source>
+ <target>활성화 된 경고</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9fe218829514884cdd0ca2300573a4e0428c324f" datatype="html">
+ <source>Alerts</source>
+ <target>경고</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa0c44aa1e5727061baa91e954f77e2f5f9a37c9" datatype="html">
+ <source>Silences</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85c737325f5e59517e2d08a71de6d77788aabc95" datatype="html">
+ <source>To see all configured Prometheus alerts, please provide the URL to the API of Prometheus as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623978917681527907" datatype="html">
+ <source>Group</source>
+ <target>그룹</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7410432243549869948" datatype="html">
+ <source>Duration</source>
+ <target>기간</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4109205891084963566" datatype="html">
+ <source>Query</source>
+ <target>쿼리</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28f86ffd419b869711aa13f5e5ff54be6d70731c" datatype="html">
+ <source>Edit</source>
+ <target>편집</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="826b25211922a1b46436589233cb6f1a163d89b7" datatype="html">
+ <source>Delete</source>
+ <target>삭제</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">279</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">341</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">441</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3ba06aba047605af8ea1718ec1ba153b7db12a2" datatype="html">
+ <source>Editing a silence will expire the old silence and recreate it as a new silence</source>
+ <target>Silence를 편집하면 이전의 Silence이 만료되고 새로운 Silence가 다시 생성됩니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a20424156b8816671f61879f0574a4f27d7b16b9" datatype="html">
+ <source>Creator</source>
+ <target>생성자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5a5d7ee2acbfa9c91ab7f41d26bda9ff0cafe42f" datatype="html">
+ <source>Comment</source>
+ <target>설명</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c11aad490b2d53fdae30b3807beabf79306752c" datatype="html">
+ <source>Start time</source>
+ <target>시작 시간</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32856b1e8e339b747b21e313e2fe65a51fd450bb" datatype="html">
+ <source>If the start time lies in the past the creation time will be used</source>
+ <target>시작 시간이 과거인 경우 작성 시간이 사용됩니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a02ea1d4e7424ca989929da5e598f379940fdbf2" datatype="html">
+ <source>Duration</source>
+ <target>기간</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f4e35e36f4d3c62e2c17df41730b6dee4afc4b9" datatype="html">
+ <source>End time</source>
+ <target>종료 시간</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="992123459137d45c15df5548bc9682aad835c04b" datatype="html">
+ <source>Matchers</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e023166c55833d5a13f4143e3dbe372befe1b4e" datatype="html">
+ <source>A silence requires at least one matcher</source>
+ <target>Silence는 하나 이상의 Matcher가 필요합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef765bd80c4806c51c891908c07a24bc76f019eb" datatype="html">
+ <source>Add matcher</source>
+ <target>Matcher 생성</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754178820914251524" datatype="html">
+ <source>silence</source>
+ <target>Silence</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8714559758543060819" datatype="html">
+ <source>Attribute name</source>
+ <target>속성 이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1338733395833138319" datatype="html">
+ <source>Regular expression</source>
+ <target>정규 표현식</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35819898450851998" datatype="html">
+ <source>Please add your Prometheus host to the dashboard configuration and refresh the page</source>
+ <target>Prometheus 호스트를 대시보드 구성에 추가하고 페이지를 새로 고치십시오.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f2f4cb9d876ff9d34fc082c1ac642d3cb98c360" datatype="html">
+ <source>To enable Silences, please provide the URL to the API of the Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7448808151142843482" datatype="html">
+ <source>Created by</source>
+ <target>생성자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4734349318830134239" datatype="html">
+ <source>Ends</source>
+ <target>종료</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1233087251567318644" datatype="html">
+ <source>Silence</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="78af6a5e6e4d305557054b64d10f9f9446d8043d" datatype="html">
+ <source>{VAR_SELECT, select, true {Edit} other {Add}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2404fa8e80946d0ce3d0ae369b51cb26ec28d42" datatype="html">
+ <source><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/> Matcher</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c25e04f554875dc2625a78ba0fc56c6010cd0d3" datatype="html">
+ <source>-- Select an attribute to match against --</source>
+ <target>-- 속성을 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5049e204c14c648691ac775a64fb504467aeb549" datatype="html">
+ <source>Value</source>
+ <target>값</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="77fc5c63497fc031ddc97645484e3d94ad27766c" datatype="html">
+ <source>Use regular expression</source>
+ <target>정규식을 사용하세요.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5518753745858598442" datatype="html">
+ <source>no spec</source>
+ <target>사양 없음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1186363766752354382" datatype="html">
+ <source>unmanaged</source>
+ <target>관리되지 않음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5246585784774990516" datatype="html">
+ <source>count:<x id="PH" equiv-text="count"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001661117318762535" datatype="html">
+ <source>label:<x id="PH" equiv-text="label"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cb3aa7e9fea1d445a1a9d7797ab17e6ac6fe13b" datatype="html">
+ <source>Service Events</source>
+ <target>서비스 이벤트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3474944817987674409" datatype="html">
+ <source>Daemon type</source>
+ <target>데몬 형태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3136939605470297323" datatype="html">
+ <source>Daemon ID</source>
+ <target>데몬 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8171022601808215887" datatype="html">
+ <source>Container ID</source>
+ <target>컨테이너 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8859473568390700297" datatype="html">
+ <source>Container Image name</source>
+ <target>컨테이너 이미지 이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5623167616584404899" datatype="html">
+ <source>Container Image ID</source>
+ <target>컨테이너 이미지 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="335348913532561915" datatype="html">
+ <source>Last Refreshed</source>
+ <target>최근 새로고침</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3022087209429182774" datatype="html">
+ <source>Daemon Events</source>
+ <target>데몬 이벤트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">140</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8604852007710946848" datatype="html">
+ <source>Service Name</source>
+ <target>서비스 이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="613875387304159316" datatype="html">
+ <source>Service Type</source>
+ <target>서비스 형태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907644935670421963" datatype="html">
+ <source>Service Events</source>
+ <target>서비스 이벤트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3214a1f3a4c3e89a848b4ec59adeeda3b913c396" datatype="html">
+ <source>-- Select a service type --</source>
+ <target>-- 서비스 타입을 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f32579a9fd19d93c083175284ee3426d78751c33" datatype="html">
+ <source>Backend Service</source>
+ <target>백엔드 서비스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2937074aed12b8158e929c58747a8216433b72b" datatype="html">
+ <source>-- No service available --</source>
+ <target>-- 사용 가능한 서비스가 없습니다 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19fb4480d95a5539db4e9c7b516d414774e61110" datatype="html">
+ <source>-- Select an existing RGW service --</source>
+ <target>-- RGW 서비스를 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2798cc1e152b1ec07fd8daf94a2a073d1ba1ebcc" datatype="html">
+ <source>Id</source>
+ <target>아이디</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d5156b9d9a79d162c353c4aa9bc6840ad5c6257" datatype="html">
+ <source>The value does not match the pattern <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&lt;service_id&gt;[.&lt;realm_name&gt;.&lt;zone_name&gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83d5d7edd8a0be253c4e93ad4c3efe86d9ac520f" datatype="html">
+ <source>Unmanaged</source>
+ <target>관리되지 않음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c15fa461935e0f600bc5d1660af1da67f024fc2a" datatype="html">
+ <source>Placement</source>
+ <target>배치</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="863226cffd5b66a6fee9810a9282a5006d6ef576" datatype="html">
+ <source>Label</source>
+ <target>라벨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06412bce0f4fe4311193e9763666089bf9d980da" datatype="html">
+ <source>Count</source>
+ <target>개수</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f193722f1e788f14a823b89ac1794c3ba934f9f" datatype="html">
+ <source>Only that number of daemons will be created.</source>
+ <target>해당 개수의 데몬만 생성됩니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee1a29cc658e4fa891be762d7bae96139b57c8f4" datatype="html">
+ <source>The value must be at least 1.</source>
+ <target>값은 1 이상이어야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">369</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cb2741a46e3560f6bc6dfd99d385e86b08b26d72" datatype="html">
+ <source>Port</source>
+ <target>포트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a23ed3598cca5285606675b6cb2536a56b411ade" datatype="html">
+ <source>The value cannot exceed 65535.</source>
+ <target>값은 65535를 초과할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">404</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d8ebdc326e6b9ff35feee3f762b7ab39c02d78f" datatype="html">
+ <source>-- No pools available --</source>
+ <target>-- 사용 가능한 풀이 없습니다 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84b675705324741b954615fedf2417d4d873b0b6" datatype="html">
+ <source>Trusted IPs</source>
+ <target>신뢰된 IP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b543e7c787cc48c2938cbce2d14c6afea5a598df" datatype="html">
+ <source>Comma separated list of IP addresses.</source>
+ <target>쉼표로 구분된 IP 주소 목록입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1039ea40da18a6453d9c1adc72a35aed099029d0" datatype="html">
+ <source>Please add the <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> IP addresses here, otherwise the iSCSI gateways can't be reached.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6265b64c17a1e19775769489bfd0b152fa1f3ba1" datatype="html">
+ <source>Virtual IP</source>
+ <target>가상 IP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61893fde6e9e05a6b91619d501edaa7962b438ff" datatype="html">
+ <source>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</source>
+ <target>수신 서비스를 사용할 수 있는 가상 IP 주소 및 서브넷(CIDR 표기법)입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">333</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ece04ddf7e96f445415ebd90d93c455e03e8cf53" datatype="html">
+ <source>Frontend Port</source>
+ <target>프론트엔드 포트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">352</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae6fd97454d184b374984c9ff808176ece54f0dd" datatype="html">
+ <source>The port used to access the ingress service.</source>
+ <target>수신 서비스에 접근하는 데 사용 되는 포트입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1261eacf161f75efc9dfea84dd97b4a466b89aa1" datatype="html">
+ <source>Monitor Port</source>
+ <target>모니터 포트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4df6281ed630ba96f09790a46a7fe0ec0e666bb6" datatype="html">
+ <source>The port used by haproxy for load balancer status.</source>
+ <target>HA 프록시가 로드 밸런서 상태에서 사용하는 포트입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ce24ae1d792ed2846ba57e7ed6397a802caeff5" datatype="html">
+ <source>CIDR Networks</source>
+ <target>CIDR 네트워크</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">414</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7c13184af0c09e3bad77daa5f4869138708d26b2" datatype="html">
+ <source>A list of networks to identify which network interface to use for the virtual IP address.</source>
+ <target>가상 IP 주소에 사용할 네트워크 인터페이스를 식별하는 네트워크 목록입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8fe73a4787b8068b2ba61f54ab7e0f9af2ea1fc9" datatype="html">
+ <source>Version</source>
+ <target>버전</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a6855d17f6b9820bb9709870efdcc7da99552d3" datatype="html">
+ <source>-- Select SNMP version --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">442</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a7369891e88cd613e45a39b55a282c97776d05f5" datatype="html">
+ <source>Destination</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f09a5d334a73a4b5ba031d7fa65151cad5ec7133" datatype="html">
+ <source>Must be of the format hostname:port.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b68c79ffe3af1db88180454fbc2fa880a51ccf52" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>hostname:port<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">470</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c90ad98a026d781ab729911873767e549d78f99" datatype="html">
+ <source>Engine Id</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">478</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d39d015ebd667fb6bddf08bb0e5b3faa6cf044c" datatype="html">
+ <source>Unique identifier for the device (in hex).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">480</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514cda7dc49062c5c532427245ce47c4954bc32" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b2d628c51192ade0044212b409c758c20f9c021" datatype="html">
+ <source>Auth Protocol</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc8bb2315a5101770a752b18e03b5c730539397c" datatype="html">
+ <source>-- Select auth protocol --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">508</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6777f99fd13e03874afe26ba7289dc9fc211af04" datatype="html">
+ <source>Privacy Protocol</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70512b7c13bce85b3928920b29fafbd59a853383" datatype="html">
+ <source>-- Select privacy protocol --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b48c81465d14465b95826b99e05acfabef1814c6" datatype="html">
+ <source>Credentials</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">541</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4ea0163c25c818aab982072b1b8d5ab585e9a5a" datatype="html">
+ <source>SNMP Community</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">547</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="08c74dc9762957593b91f6eb5d65efdfc975bf48" datatype="html">
+ <source>Username</source>
+ <target>사용자 이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="948758e1412bb2ecdb98e3a4f1cbb6d7458456f2" datatype="html">
+ <source>Encryption</source>
+ <target>암호화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">598</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e65610b5d940367f1ff6b57772b96e94e35fe202" datatype="html">
+ <source>SSL</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">624</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e37e0d06148c7708e88b4a1eb412babbe1a4afc" datatype="html">
+ <source>Certificate</source>
+ <target>인증서</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">634</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="295ae4f632322098deca8a3ddfbc7aeaabb5423b" datatype="html">
+ <source>The SSL certificate in PEM format.</source>
+ <target>PEM 형식의 SSL 인증서입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">635</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464272c069fe56f6c50f41f426a25b2a42c95ba5" datatype="html">
+ <source>Invalid SSL certificate.</source>
+ <target>유효하지 않은 SSL 인증서 입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">650</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0596d06bf1f8a15d4bfe56226971ecdd78013b1f" datatype="html">
+ <source>Private key</source>
+ <target>개인 키</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">659</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ded15dc55104994c0230189f34dff84a4955aafb" datatype="html">
+ <source>The SSL private key in PEM format.</source>
+ <target>PEM 형식의 SSL 개인 키입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">660</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19bdc1597d815b456793ff87c89af4257a85a103" datatype="html">
+ <source>Invalid SSL private key.</source>
+ <target>유효하지 않은 SSL 개인 키입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">675</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3356018487523380058" datatype="html">
+ <source>service</source>
+ <target>서비스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2412938991511187011" datatype="html">
+ <source>There are no hosts.</source>
+ <target>호스트가 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2594503755408511486" datatype="html">
+ <source>Filter hosts</source>
+ <target>호스트 필터</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5869780110608474933" datatype="html">
+ <source>Placement</source>
+ <target>배치</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2956098160626271284" datatype="html">
+ <source>Running</source>
+ <target>실행중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="013f48ee777d2e53e2bcba36e1a99fcbb7ef8cb6" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report configuration</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a09b723a928774bff707973c99999dcf3d84a349" datatype="html">
+ <source>The telemetry module sends anonymous data about this Ceph cluster back to the Ceph developers to help understand how Ceph is used and what problems users may be experiencing.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> This data is visualized on <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>public dashboards<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> that allow the community to quickly see summary statistics on how many clusters are reporting, their total capacity and OSD count, and version distribution trends.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> The data being reported does <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>not<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> contain any sensitive data like pool names, object names, object contents, hostnames, or device serial numbers. It contains counters and statistics on how the cluster has been deployed, the version of Ceph, the distribution of the hosts and other parameters which help the project to gain a better understanding of the way Ceph is used. The data is sent secured to <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> and <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (device report).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">14,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c95505b5a74151a0c235b19b9c41db7983205ba7" datatype="html">
+ <source>Deactivate</source>
+ <target>비활성화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19" datatype="html">
+ <source>Channels</source>
+ <target>채널</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e25b17c0b4ef361b6a05aaec2bbd2b7e86680458" datatype="html">
+ <source>The telemetry report is broken down into several &quot;channels&quot;, each with a different type of information that can be configured below.</source>
+ <target>원격 분석 보고서는 여러 &quot;채널&quot;로 구분되며, 각 채널은 아래에서 구성할 수 있는 서로 다른 유형의 정보를 가집니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">32,33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380ab580741bec31346978e7cab8062d6970408d" datatype="html">
+ <source>Basic</source>
+ <target>기본</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd898057f0add35258a5fb5c90d792c5e2147452" datatype="html">
+ <source>Includes basic information about the cluster:</source>
+ <target>클러스터에 대한 기본 정보를 포함합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da213e9ba8a86b453d04f794f58c9803f7b062b1" datatype="html">
+ <source>Capacity of the cluster</source>
+ <target>클러스터 용량</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d5fe31d9e13239bdd223d0bbd289a1b1903e86" datatype="html">
+ <source>Number of monitors, managers, OSDs, MDSs, object gateways, or other daemons</source>
+ <target>모니터, 관리자, OSD, MDS, object 게이트웨이 또는 기타 데몬 수입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a3eb7834b4baf412f8863d14883972897d9acb7" datatype="html">
+ <source>Software version currently being used</source>
+ <target>현재 사용 중인 소프트웨어 버전입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34881ae65482ffa74ccb4043fb2622e48ed146d5" datatype="html">
+ <source>Number and types of RADOS pools and CephFS file systems</source>
+ <target>RADOS 풀 및 CephFS 파일 시스템의 수와 유형입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="696f8f5ea7a9cf6125b9a3af160981fda363552d" datatype="html">
+ <source>Names of configuration options that have been changed from their default (but not their values)</source>
+ <target>기본값에서 변경된 구성 옵션의 이름입니다(값은 아님).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34292940316300d09abe5e675d452fae199f626b" datatype="html">
+ <source>Crash</source>
+ <target>충돌</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7620e332b7dea1e832158e85847255eb4d9e6bbc" datatype="html">
+ <source>Includes information about daemon crashes:</source>
+ <target>데몬 충돌에 대한 정보를 포함합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1aa4306a6e840fe35b70c9b07d38ce85f281cfa" datatype="html">
+ <source>Type of daemon</source>
+ <target>데몬 타입</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4f2cbedb4b14b68bc9f390e3391445c1b6682da" datatype="html">
+ <source>Version of the daemon</source>
+ <target>데몬 버전</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d62603cdc75645ea873fc8f7f69c32b5f4a2aa9" datatype="html">
+ <source>Operating system (OS distribution, kernel version)</source>
+ <target>운영 체제(OS 배포, 커널 버전)입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84facf84a73631d66e9a4e0bc1c40097b9d14742" datatype="html">
+ <source>Stack trace identifying where in the Ceph code the crash occurred</source>
+ <target>Ceph 코드에서 충돌이 발생한 위치를 나타내는 스택 추적입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea64d4177bd648e1a20c92669e6857762b811d8c" datatype="html">
+ <source>Device</source>
+ <target>디바이스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4bc37bcbbcea881a269b4063b3d93dec8ee67d5" datatype="html">
+ <source>Includes information about device metrics like anonymized SMART metrics.</source>
+ <target>익명화 된 SMART 메트릭과 같은 장치 메트릭에 대한 정보를 포함합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37de70e8ba539187d0171a38dad2a63c323096eb" datatype="html">
+ <source>Ident</source>
+ <target>식별자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b126025440f118cd02ce78362d61a5001c27617" datatype="html">
+ <source>Includes user-provided identifying information about the cluster:</source>
+ <target>클러스터에 대해 사용자가 제공한 식별 정보를 포함합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62c6e9aecff7e04ef7d36fdee4ab4fb285a7a2b5" datatype="html">
+ <source>Contact Information</source>
+ <target>연락처 정보</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61ba9a84051b3f470122e59cf5a746552b378269" datatype="html">
+ <source>Submitting any contact information is completely optional and disabled by default.</source>
+ <target>연락처 정보 제출은 선택 사항이며 기본적으로 비활성화 되어 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34746fb1c7f3d2194d99652bdff89e6e14c9c4f4" datatype="html">
+ <source>Contact</source>
+ <target>연락처</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="632cac1e025b77b2d77fed16ad22a410ddacab9e" datatype="html">
+ <source>My first Ceph cluster</source>
+ <target>첫 번째 Glue 클러스터</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3a58c8a81b9ffda26a154eae25a422c9f7de37b" datatype="html">
+ <source>Organization</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e8fda44e2c5bb51860f26cd9c2730f9ae1db9869" datatype="html">
+ <source>Organization name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d49310535abb3792d8c9c991dd0d990d73d29af" datatype="html">
+ <source>Interval</source>
+ <target>주기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91317562c9dfefbdd5973faf11d217f571d073c7" datatype="html">
+ <source>The module compiles and sends a new report every 24 hours by default. You can adjust this interval by setting a different number of hours.</source>
+ <target>모듈은 기본적으로 24시간마다 새 보고서를 컴파일하고 전송합니다. 시간을 설정하여 간격을 조정할 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">185,186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a12cf4cf71ef3161a024382ab542cf0eba094504" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to 8.</source>
+ <target>입력한 값이 너무 낮습니다. 8보다 크거나 같아야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a92e437fac14b4010c4515b31c55a311d026a57f" datatype="html">
+ <source>Proxy</source>
+ <target>프록시</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6de03357358c7eff62aca486508bb5c2046e0669" datatype="html">
+ <source>If the cluster cannot directly connect to the configured telemetry endpoint (default telemetry.ceph.com), you can configure a HTTP/HTTPS proxy server by e.g. adding https://10.0.0.1:8080</source>
+ <target>클러스터가 구성된 원격 분석 끝점(기본값 telemetry.ceph.com)에 직접 연결할 수 없는 경우, 예를 들어 https://10.0.0.1:8080을 추가하여 HTTP/HTTPS 프록시 서버를 구성할 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5687a733af051bfca97dbffba282e39fbb9b8c8f" datatype="html">
+ <source>You can also include a user:pass if needed e.g. https://ceph:telemetry@10.0.0.1:8080</source>
+ <target>필요한 경우 user:pass를 포함할 수도 있습니다(예: https://ceph:telemetry@10.0.1:8080).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e6430c68df43ea65e4145972b01186fba40f26a" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Note:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> By clicking 'Next' you will first see a preview of the report content before you can activate the automatic submission of your data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">219,220</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d8d878f8d60905e1306c225716305a331b784c8" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report preview</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e23d0064b6474f309c74e1c928cc0920f479d9a5" datatype="html">
+ <source>Report ID <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">249,252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4060e92658964e356a0992a900c8aa811c2cfec0" datatype="html">
+ <source>A randomized UUID to identify a particular cluster over the course of several telemetry reports.</source>
+ <target>여러 원격 분석 보고서 과정에서 특정 클러스터를 식별하기 위한 임의의 UUID입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60900bc663571f852a04950a123508b106d97204" datatype="html">
+ <source>Report preview <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">267,270</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3de417f739c336284c42904552e81e8d852daecc" datatype="html">
+ <source>The actual telemetry data that will be submitted.</source>
+ <target>제출될 실제 원격 측정 데이터입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="933a2b6f087670ff42c95876e6ecfb2faa3e3867" datatype="html">
+ <source>I agree to my telemetry data being submitted under the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Community Data License Agreement - Sharing - Version 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">304</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8293060085588842566" datatype="html">
+ <source>The Telemetry module has been configured and activated successfully.</source>
+ <target>원격 측정 모듈이 구성 및 활성화되었습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5380636888677486786" datatype="html">
+ <source>An Error occurred while updating the Telemetry module configuration. Please Try again</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2bcd3296d2850de762fb943060b7e086a893181" datatype="html">
+ <source>Health</source>
+ <target>클러스터 상태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61e0f26d843eec0b33ff475e111b0c2f7a80b835" datatype="html">
+ <source>Statistics</source>
+ <target>통계</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73caac4265ea7314ff061e5a1d78a6361a6dd3b8" datatype="html">
+ <source>Cluster Status</source>
+ <target>클러스터 상태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="624f596cc3320f5e0a0d7c7346c364e5af9bdd8c" datatype="html">
+ <source>Monitors</source>
+ <target>모니터</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9183778f2c6473d7ccb080f651caa01faaf70c" datatype="html">
+ <source>OSDs</source>
+ <target>스토리지 디바이스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c34287a0423968dac8a41463b80855a0ff789403" datatype="html">
+ <source>Managers</source>
+ <target>매니저</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="946ac5dea9921dc09d7b0a63b89535371f283b19" datatype="html">
+ <source>Object Gateways</source>
+ <target>오브젝트 게이트웨이</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff03fa5bcf37c4da46ad736c1f7d03f959e8ba9a" datatype="html">
+ <source>Metadata Servers</source>
+ <target>메타 데이터 서버</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d817609ba4993eba859409ab71e566168f4d5f5a" datatype="html">
+ <source>iSCSI Gateways</source>
+ <target>iSCSI 게이트웨이</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ce9dfdc6dccb28dc75a78c704e09dc18fb02dcfa" datatype="html">
+ <source>Capacity</source>
+ <target>용량</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f383269db2d32cccee9e936fe549dccb9fdbf4" datatype="html">
+ <source>Raw Capacity</source>
+ <target>물리 용량</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498a109c6e9e94f1966de01aa0326f7f0ac6fb52" datatype="html">
+ <source>PG Status</source>
+ <target>PG 상태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5f8a813f91a11af99132e4beafc136cfc13d73b" datatype="html">
+ <source>PGs per OSD</source>
+ <target>스토리지 디바이스 별 PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32efd1c3f70e3c5244239de97a2cc95d98534a14" datatype="html">
+ <source>Client Read/Write</source>
+ <target>클라이언트 읽기/쓰기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="52213660b2454d139ada3079a42ec6caf3c3c01e" datatype="html">
+ <source>Client Throughput</source>
+ <target>클라이언트 처리량</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="275485415092cbae3a9f3cbb786ebe283cacfdd5" datatype="html">
+ <source>Recovery Throughput</source>
+ <target>복구 처리량</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35416fcdf9cb33d2b299d3f2028c390454b55d02" datatype="html">
+ <source>Scrubbing</source>
+ <target>빠른 데이터 정리 중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="44ecac93d67c6a671198091c2270354f80322327" datatype="html">
+ <source><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> See <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>Logs<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for more details.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520247697658334435" datatype="html">
+ <source>Reads</source>
+ <target>읽기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5947645586591788199" datatype="html">
+ <source>/s</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7527163811128350993" datatype="html">
+ <source>Writes</source>
+ <target>쓰기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7684088941299429132" datatype="html">
+ <source>IOPS</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81585474102700882" datatype="html">
+ <source>Used</source>
+ <target>사용</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">179</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8695656831075719969" datatype="html">
+ <source>Avail.</source>
+ <target>사용 가능</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6352596107300820129" datatype="html">
+ <source>Clean</source>
+ <target>정상</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4016774570903735270" datatype="html">
+ <source>Working</source>
+ <target>동작 중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4467323362722952678" datatype="html">
+ <source>Unknown</source>
+ <target>알려지지 않음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">218</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7790772795962334429" datatype="html">
+ <source>Healthy</source>
+ <target>정상</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4708847204147472247" datatype="html">
+ <source>Misplaced</source>
+ <target>잘못 배치됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3120522496446378904" datatype="html">
+ <source>Degraded</source>
+ <target>유실됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8047698491745405137" datatype="html">
+ <source>Unfound</source>
+ <target>찾을 수 없음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81117556780777231" datatype="html">
+ <source>objects</source>
+ <target>오브젝트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795e8a00db46b750113d5db93e8d97e2b3079894" datatype="html">
+ <source>For an overview of <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/> widgets click <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">21,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16bd21c1b48036d54c6a595f5cff2540cfba7f60" datatype="html">
+ <source>here</source>
+ <target>여기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8515973702474791807" datatype="html">
+ <source>up</source>
+ <target>정상</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4223604072115719661" datatype="html">
+ <source>no filesystems</source>
+ <target>파일 시스템 없음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2078241808113697591" datatype="html">
+ <source>active</source>
+ <target>활성</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3232506912392089107" datatype="html">
+ <source>standby</source>
+ <target>대기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576716133013765863" datatype="html">
+ <source>standby daemons</source>
+ <target>대기중인 데몬</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3629620351427988554" datatype="html">
+ <source>active daemon</source>
+ <target>활성화된 데몬</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5954854563228355745" datatype="html">
+ <source>standbyReplay</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7329683463736701292" datatype="html">
+ <source>n/a</source>
+ <target>없음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/not-available.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8271970016544066882" datatype="html">
+ <source><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (quorum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mon-summary.pipe.ts</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6489441800790477240" datatype="html">
+ <source>total</source>
+ <target>전체</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5965118847182332588" datatype="html">
+ <source>near full</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="268166731974484199" datatype="html">
+ <source>full</source>
+ <target>가득참</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47116253e36f4e38a97ba41b2d3122c6c15ab904" datatype="html">
+ <source>Clients (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5159814115056353668" datatype="html">
+ <source>Addresses</source>
+ <target>주소</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1811797298582428088" datatype="html">
+ <source>Access Type</source>
+ <target>접근 형태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3575940435199094878" datatype="html">
+ <source>Squash</source>
+ <target>Squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2944102521023817891" datatype="html">
+ <source>Cluster</source>
+ <target>클러스터</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91772203889648189" datatype="html">
+ <source>NFS Protocol</source>
+ <target>NFS 프로토콜</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907766170797643122" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1032539711043211945" datatype="html">
+ <source>Transport</source>
+ <target>전송</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2489852208080013495" datatype="html">
+ <source>Storage Backend</source>
+ <target>스토리지 백엔드</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8440421106569981118" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4095248496892792741" datatype="html">
+ <source>CephFS User</source>
+ <target>CephFS 사용자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2535727951299201687" datatype="html">
+ <source>CephFS Filesystem</source>
+ <target>CephFS 파일시스템</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2169401160512036026" datatype="html">
+ <source>Security Label</source>
+ <target>보안 레이블</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3671149880069127721" datatype="html">
+ <source>Object Gateway</source>
+ <target>오브젝트 게이트웨이</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1643028261508790" datatype="html">
+ <source>Object Gateway User</source>
+ <target>오브젝트 게이트웨이 사용자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2dae0bda66f6a349444951c0379c28cda47d6d1" datatype="html">
+ <source>Any client can access</source>
+ <target>모든 클라이언트 접근 가능</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7882f2edb1d4139800b276b6b0bbf5ae0b2234ef" datatype="html">
+ <source>Addresses</source>
+ <target>주소</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f3f74c0f6925826cb2188576391c0da01a23f0" datatype="html">
+ <source>Must contain one or more comma-separated values</source>
+ <target>쉼표로 구분된 값을 하나 이상 포함해야 합니다.
+ </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb5b2073697f3f4378c44a49b7524934c9268f4" datatype="html">
+ <source>For example:</source>
+ <target>예를들면:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f969c655b3fbe4fba7e277caf4cd2c459f9fca5" datatype="html">
+ <source>Access Type</source>
+ <target>접근형태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28952831a284cfe2b4fc39ca610e80b52598905a" datatype="html">
+ <source>Squash</source>
+ <target>Squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0660ae339068979854ade34a96546980723dede3" datatype="html">
+ <source>Add clients</source>
+ <target>클라이언트 추가</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8571141481686087364" datatype="html">
+ <source>(inherited from global config)</source>
+ <target>(글로벌 구성에서 상속)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3563954518111128118" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- 접근 형태를 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3802199399355755843" datatype="html">
+ <source>inherited from global config</source>
+ <target>글로벌 구성에서 상속</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8729531250118136719" datatype="html">
+ <source>-- Select what kind of user id squashing is performed --</source>
+ <target>- 어떤 종류의 사용자 ID 스쿼시가 수행되는지 선택하세요 -</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4d1dd59b039ad818d9da7e29a773e10e41d9821" datatype="html">
+ <source>Cluster</source>
+ <target>클러스터</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="625f8f0f3e5b7c92651606d77484ff3d07b3c12b" datatype="html">
+ <source>This is the ID of an NFS Service.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="135b91a2d908d5814b782695470a6a786c99d9d2" datatype="html">
+ <source>-- No cluster available --</source>
+ <target>-- 사용가능 클러스터가 없습니다 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c501dba379f566885919240ea277b5bc10c14d18" datatype="html">
+ <source>-- Select the cluster --</source>
+ <target>-- 클러스터를 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7bd3ad665c398c7fe97230ab59e67370653a82" datatype="html">
+ <source>This field is required. To create a new NFS cluster, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>add a new NFS Service<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">41,43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3f6ba7fe84d6508705cdfe234f0fcc8ff85c9cf" datatype="html">
+ <source>Storage Backend</source>
+ <target>스토리지 백엔드</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6fee356d1db954255a56d8169405a89595246b9" datatype="html">
+ <source>-- Select the storage backend --</source>
+ <target>-- 스토리지 백엔드를 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3c2793dd2ef56954f872142d5ec1becb84c0fe1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="796e42bec8a6996607cf1f3e80235b86d695804a" datatype="html">
+ <source>Volume</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee3ba0ab5f0ccd597b3e44021c71e9aaad14df0a" datatype="html">
+ <source>-- No CephFS filesystem available --</source>
+ <target>-- 사용 가능한 CephFS 파일 시스템이 없습니다 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="764c57812558b1ae66c5eec95d7efd2b1bf761e3" datatype="html">
+ <source>-- Select the CephFS filesystem --</source>
+ <target>-- CephFS 파일 시스템을 선택 하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="957512d0321f73e9f115bce1bd823fa635170c41" datatype="html">
+ <source>Security Label</source>
+ <target>보안 라벨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="65ce0fa4da1ed55e658aeb31d1644a29f06bb342" datatype="html">
+ <source>Enable security label</source>
+ <target>보안 라벨 활성화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e808f804130c7b6ff719509cbc06ebb27393a48" datatype="html">
+ <source>CephFS Path</source>
+ <target>CephFS 경로</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1338c2f83e49ea7f2fc04e9fe90c5d330b7a10f" datatype="html">
+ <source>A path in a CephFS file system.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ecc0107badb6625466aaa3f975b5c05276f432f" datatype="html">
+ <source>Path need to start with a '/' and can be followed by a word</source>
+ <target>경로는 '/'로 시작해야하며 그 뒤에 단어가 올 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f9d8bd873c34c5ab2d4d0cf995fe5183ab25f6e" datatype="html">
+ <source>The path does not exist in the selected volume.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd197d7773cef10f368f08c53b47979c3df1f22d" datatype="html">
+ <source>Bucket</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ca90b4b16347ef7017967915e8624472976c85c" datatype="html">
+ <source>The bucket does not exist or is not in the default realm (if multiple realms are configured). To continue, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>create a new bucket<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bee6900143996c0e908a10564532eba3da0b30fb" datatype="html">
+ <source>NFS Protocol</source>
+ <target>NFS 프로토콜</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5043c0921e709935ab026bb3253ffe1f159fca1" datatype="html">
+ <source>NFSv4</source>
+ <target>NFSv4</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d2c39708a32910f89701dd7e1cfb9ec1c195768" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1f8be2ae25947bec0b84c2338201580ea053f34e" datatype="html">
+ <source>The position that this <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> export occupies in the <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo FS<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (it must be unique).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">241,242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3af55f7fd5b1d9e5a53e030c80116dc635bfb9f" datatype="html">
+ <source>By using different Pseudo options, the same Path may be exported multiple times.</source>
+ <target>다른 Pseudo 옵션을 사용하면, 동일한 경로를 여러 번 내보낼 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5eb719aa900fed3f9d4a1d74bcc158f07f67f684" datatype="html">
+ <source>The pseudo is already in use by another export.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddf98fcdeeb17643db020d54f42b5e56b5f9a52a" datatype="html">
+ <source>Pseudo needs to start with a '/' and can't contain any of the following: &gt;, &lt;, |, &amp;, ( or ).</source>
+ <target>Pseudo는 '/'로 시작해야 하며 다음 문자를 포함할 수 없습니다. : &gt;, &lt;, |, &amp;, .</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="27eb35c4b4ac08781a7253a2ab40f8f7d957ba51" datatype="html">
+ <source>-- No access type available --</source>
+ <target>-- 사용가능한 접근 형태가 없습니다 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">280</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="509ce016c9110a54028dafd741f15ceacbe74b5a" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- 접근 형태를 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67ce207d0b7eada1fe3d3187a39ba0c07be76b6c" datatype="html">
+ <source>The Object Gateway NFS backend has a number of limitations which will seriously affect applications writing to the share. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> for details before enabling write access.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">293,296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4deda03573eaaff77e63f6a238a1f0ca7816950a" datatype="html">
+ <source>-- No squash available --</source>
+ <target>-- 사용 가능한 squash가 없습니다. --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">321</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a0e82a4da88e7fdf270444f838d45849676e9d4b" datatype="html">
+ <source>--Select what kind of user id squashing is performed --</source>
+ <target>-- 어떤 종류의 사용자 ID squash가 수행되는지 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d01b7c3f7f06712c53d054cfbe4f53d446b038e8" datatype="html">
+ <source>Transport Protocol</source>
+ <target>전송 프로토콜</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2a6ad6e8bc315f07911722c05767ac79c136d99" datatype="html">
+ <source>UDP</source>
+ <target>UDP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">349</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c030f11e0aae9b24d2c048c57f29f590be621df" datatype="html">
+ <source>TCP</source>
+ <target>TCP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">359</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f84d7fd4d52eb5b2229b632ef5119dac63d5597" datatype="html">
+ <source>No user id squashing is performed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">378</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb1d148107e36852325106a518385b1b0de28835" datatype="html">
+ <source>uid 0 and gid 0 are squashed to the Anonymous_Uid and Anonymous_Gid gid 0 in alt_groups lists is also squashed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">382</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1309d6f67955799863337b201413faa61a175ddb" datatype="html">
+ <source>uid 0 and gid of any value are squashed to the Anonymous_Uid and Anonymous_Gid alt_groups lists is discarded.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85f23d5c9b57dc78dda4150d13aa3b99e985350b" datatype="html">
+ <source>All users are squashed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2691935247101074756" datatype="html">
+ <source>NFS export</source>
+ <target>NFS 내보내기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8727258243239498387" datatype="html">
+ <source><x id="PH" equiv-text="fsalItem.descr"/> backend is not available. <x id="PH_1" equiv-text="errorMessage"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2772848515253260635" datatype="html">
+ <source>Error while retrieving paths.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5239928491238988595" datatype="html">
+ <source>Error while retrieving bucket names.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="734c9905951a774870497c5aaae8e3ee833b6196" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2190548d236ca5f7bc7ab2bca334b860c5ff2ad4" datatype="html">
+ <source>Object Gateway</source>
+ <target>오브젝트 게이트웨이</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca53d681a9892d6fdbb57ee9676582186515e961" datatype="html">
+ <source>Performance counters not available</source>
+ <target>성능 카운터를 사용 할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="490e15ecc922965b6d8194754c87c5583aa071f3" datatype="html">
+ <source>The name can only consist of alphanumeric characters, dashes and underscores.</source>
+ <target>이름은 영숫자, 대시 및 밑줄로만 구성 될 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9edc2b494e660618af3e5225f68d40b7ca67629c" datatype="html">
+ <source>The chosen erasure code profile name is already in use.</source>
+ <target>선택한 Erasure Code 프로필 이름이 이미 사용 중입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35a4206db3105ed03e0dd799e1642b75b78123e8" datatype="html">
+ <source>Root</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf425784c7073c7e7f7c1bb90c2c19db7e751db2" datatype="html">
+ <source>Failure domain type</source>
+ <target>도메인 유형 실패</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72396a9565cf644d1fe1b21b790c4243ee270986" datatype="html">
+ <source>Device class</source>
+ <target>장치 클래스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d80e0c07bfea1b693a33ef2245007de92a6780" datatype="html">
+ <source>Let Ceph decide</source>
+ <target>자동 설정</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101611937243846632" datatype="html">
+ <source>Crush Rule</source>
+ <target>크러쉬 규칙</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef9ff0e6227947b48dfab4ac39ade04af758913b" datatype="html">
+ <source>Plugin</source>
+ <target>플러그인</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd69b31bce8f630eac1d4762b0bbcf72ce19d193" datatype="html">
+ <source>Data chunks (k)</source>
+ <target>데이터 덩어리 (k)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0d26a6172d32cb81218fe2103c54a818cbc1189" datatype="html">
+ <source>Must be equal to or greater than 2.</source>
+ <target>반드시 2보다 크거나 같아야합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ba6f4800642eba4e8b056aa7167554c3afa8db0" datatype="html">
+ <source>Chunks (k+m) have exceeded the available OSDs of <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="86fca2f788ce986eef835cd7ef8dfc9ae22447a4" datatype="html">
+ <source>For an equal distribution k has to be a multiple of (k+m)/l.</source>
+ <target>균등 분포의 경우 k는 (k+m)/l의 배수여야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8dd4bc172f1adc4afadaec291e465b082909148d" datatype="html">
+ <source>K has to be equal to or greater than m in order to recover data correctly through c.</source>
+ <target>c를 통해 데이터를 올바르게 복구하려면 K가 m보다 크거나 같아야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2e5b0e6d0dba31c59f946392699a0a6c4dd9b83" datatype="html">
+ <source>Distribution factor: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dab3a299ead121169b8e08ed618c3b6a2f66691b" datatype="html">
+ <source>Coding chunks (m)</source>
+ <target>코딩 덩어리 (m)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e2773e5bd4948193f18f2361d663ecc3988c656" datatype="html">
+ <source>Must be equal to or greater than 1.</source>
+ <target>반드시 1보다 크거나 같아야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">146</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cde4c945a49a260c0a47bcc7cd956846930a5f7" datatype="html">
+ <source>Durability estimator (c)</source>
+ <target>내구성 평가(c)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ec9ff9931f8ea1201792d6a01bf9a47b283d692" datatype="html">
+ <source>C has to be equal to or lower than m as m defines the amount of chunks that can be used.</source>
+ <target>C는 사용할 수 있는 덩어리의 양을 정의하는 mas보다 작거나 같아야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35594fe66657ea07b5b5f560927f78e81a229996" datatype="html">
+ <source>Helper chunks (d)</source>
+ <target>도우미 덩어리 (d)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0c250a8d281291273ed3504ade19ca6537e4d9a" datatype="html">
+ <source>Set d manually or use the plugin's default calculation that maximizes d.</source>
+ <target>수동으로 설정하거나 d를 최대화하는 플러그인의 기본 계산을 사용합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4304a5cd95742db0f81c3bdf29aa96bf3b0ca13d" datatype="html">
+ <source>D is automatically updated on k and m changes</source>
+ <target>K 및 m 변경 시 D가 자동으로 업데이트 됩니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06a67d52427b12df2b3d439be0e1342ac72aeb5c" datatype="html">
+ <source>D can be set from <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> to <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4f8831d3bd6401e87710c4e3ee844f5efbf5de3" datatype="html">
+ <source>D can only be set to <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5d7aacffce2c6032c3ae9ef4d1b3847a926440b" datatype="html">
+ <source>D has to be greater than k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fd745d614884edc23c7ac9ad8aba9655f3793ac2" datatype="html">
+ <source>D has to be lower than k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">199</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af668c2a095a979ea2b4e43cd82c2120ab56c21c" datatype="html">
+ <source>Locality (l)</source>
+ <target>지역 (l)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="200fea08b63ae8d60cdbf33ffd2636159e87dc1e" datatype="html">
+ <source>Can't split up chunks (k+m) correctly with the current locality.</source>
+ <target>현재 위치에서 덩어리(k+m)를 올바르게 분할할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319ac5d692d11da686782159bd70e0b705c228ed" datatype="html">
+ <source>Locality groups: <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">230</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d455a110bf6d2235e314e295ce1dfeee93d3dff2" datatype="html">
+ <source>Crush failure domain</source>
+ <target>크러쉬 실패 도메인</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74a495f041f7dd102eee5c0bbc9e03083b538ae" datatype="html">
+ <source>Crush Locality</source>
+ <target>크러쉬 지역</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2f14a73f7a6e94479f67423cc51102da8d6f524" datatype="html">
+ <source>None</source>
+ <target>없음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="363a99d62822b92913a4cce196d47f32c1258e2f" datatype="html">
+ <source>Scalar mds</source>
+ <target>스칼라 mds</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2981733b912b693a9dd9d915d6d34f4692cc874a" datatype="html">
+ <source>Technique</source>
+ <target>기술</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0098b6e47b04ec817361f384ce81d454ba5c0bb" datatype="html">
+ <source>Packetsize</source>
+ <target>패킷 크기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0252cd81ca54d0a2f69ec9ccf4248e73df5aa4a" datatype="html">
+ <source>Crush root</source>
+ <target>크러쉬 루트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">351</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1548d5c76f0406ddd1ba3c557e1e6db22e95b340" datatype="html">
+ <source>Crush device class</source>
+ <target>크러쉬 장치 클래스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3f657ffa19dc6ac504b83c86209709522dcf065" datatype="html">
+ <source>Available OSDs: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03d84645f6e019c5a43909bbf2ea1696ee88332c" datatype="html">
+ <source>Directory</source>
+ <target>디렉토리</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1354845268685595937" datatype="html">
+ <source>EC Profile</source>
+ <target>EC 프로필</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3938a411d76796f8ae73b72ea4c77661207453bd" datatype="html">
+ <source>Cache Tiers Details</source>
+ <target>캐시 계층 상세설명</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="991790413700941336" datatype="html">
+ <source>Cache Mode</source>
+ <target>캐시 모드</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9133265273798382582" datatype="html">
+ <source>Min Evict Age</source>
+ <target>최소 Evict Age</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7172092927403263656" datatype="html">
+ <source>Min Flush Age</source>
+ <target>최소 Flush Age</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8096695869347792608" datatype="html">
+ <source>Target Max Bytes</source>
+ <target>목표 최대 바이트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8854126142886240282" datatype="html">
+ <source>Target Max Objects</source>
+ <target>목표 최대 오브젝트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617215542453015899" datatype="html">
+ <source>No applications added</source>
+ <target>추가된 응용프로그램이 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4895689494338215646" datatype="html">
+ <source>Applications limit reached</source>
+ <target>응용프로그램 제한에 도달했습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7322343326526084293" datatype="html">
+ <source>A pool can only have up to four applications definitions.</source>
+ <target>하나의 데이터 풀은 오직 네개의 응용프로그램 정의를 가질 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1393735257943344790" datatype="html">
+ <source>Allowed characters '_a-zA-Z0-9'</source>
+ <target> '_a-zA-Z0-9' 문자만 사용 가능합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5520683885127790121" datatype="html">
+ <source>Maximum length is 128 characters</source>
+ <target>최대 길이는 128 문자 입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587418377972855060" datatype="html">
+ <source>Filter or add applications'</source>
+ <target>응용 프로그램을 필터링 하거나 추가합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5188881899285829380" datatype="html">
+ <source>Add application</source>
+ <target>응용프로그램 추가</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16e113230b6b0d3165e076300880542bac7c8138" datatype="html">
+ <source>The chosen Ceph pool name is already in use.</source>
+ <target>선택한 Ceph 데이터 풀 이름이 이미 사용중입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c75b132bef7b29fa5171768303c4b96e34ccaf68" datatype="html">
+ <source>It's not possible to create an RBD pool with '/' in the name. Please change the name or remove 'rbd' from the applications list.</source>
+ <target>이름에 '/'을(를) 사용하여 RBD 데이터 풀을 만들 수 없습니다. 이름을 변경하거나 응용 프로그램 목록에서 'rbd'를 제거하십시오.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">34,35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="171dc6d5c6bc4615d99778b0088cae80fd00bd10" datatype="html">
+ <source>Pool name can only contain letters, numbers, '.', '-', '_' or '/'.</source>
+ <target>데이터 풀 이름에는 문자, 숫자, '.', '-', '_' 또는 '/' 만 사용할 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b85c657469e5ec8231c3de99b22f437bc01ffde5" datatype="html">
+ <source>Pool type</source>
+ <target>데이터 풀 형태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="526c5443254c3b126eedb264840ffe827727bfd3" datatype="html">
+ <source>-- Select a pool type --</source>
+ <target>-- 데이터 풀 형태를 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abfbe47b630929d93c7343dc154599c2e59330a" datatype="html">
+ <source>PG Autoscale</source>
+ <target>PG 오토스케일</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0aa21053410a94aa61d16985a4e95fd65523430d" datatype="html">
+ <source>Placement groups</source>
+ <target>배치 그룹</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6301f1391d726f8f450bb358058534db19541ca9" datatype="html">
+ <source>At least one placement group is needed!</source>
+ <target>적어도 하나의 배치 그룹이 필요합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba9469a1ce6ed36e039c1f67247c8c81a5c71449" datatype="html">
+ <source>Your cluster can't handle this many PGs. Please recalculate the PG amount needed.</source>
+ <target>클러스터에서 이렇게 많은 PG를 처리할 수 없습니다. 필요한 PG 금액을 다시 계산해 주세요.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80ac68cd883369dac20688bc32b4cb33291b5e50" datatype="html">
+ <source>Calculation help</source>
+ <target>계산 도움말</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fccbd60493df26705d957ed6c02a3c447894678f" datatype="html">
+ <source>The current PGs settings were calculated for you, you should make sure the values suit your needs before submit.</source>
+ <target>현재 PG 설정이 계산 되었으므로 제출하기 전에 해당 값이 필요한지 확인해야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">116,117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a43b2695131b48b76cebba676aba98a2bee17515" datatype="html">
+ <source>Replicated size</source>
+ <target>복제 크기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bff144a4c4dc63b0e18fff2617d61a7ebdf2b6c" datatype="html">
+ <source>Minimum: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9c54b41f6d58a74e5d0aa3429ed0c87a482551" datatype="html">
+ <source>Maximum: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="452cf71ec44ee77428656936a6627eaf2dd3b47f" datatype="html">
+ <source>The size specified is out of range. A value from <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> to <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/> is usable.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">144,145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dda6196ffab88c1825f44a565c7b34e246e7e12f" datatype="html">
+ <source>A size of 1 will not create a replication of the object. The 'Replicated size' includes the object itself.</source>
+ <target>크기가 1이면 개체의 복제가 생성되지 않습니다. '복제된 크기'에는 개체 자체가 포함됩니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">148,149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c870fb00256b8a5b9cb9cd1a124e6390b9bc639" datatype="html">
+ <source>EC Overwrites</source>
+ <target>EC 덮어쓰기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f1abafaeb40ce52355ddcc24686e3cd17b64e08a" datatype="html">
+ <source>Applications</source>
+ <target>응용 프로그램</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9308b82fc183f710df60909f49cfc73aa5e076" datatype="html">
+ <source>CRUSH</source>
+ <target>크러쉬</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9de7dde00e2139cc4bd03b1837afbe72ad15a1ff" datatype="html">
+ <source>Erasure code profile</source>
+ <target>Erasure Code 프로필</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39b4620e6bd444e0a57a0a5c03fa8c96d7fe5235" datatype="html">
+ <source>-- No erasure code profile available --</source>
+ <target>-- 사용가능한 Erasure Code 프로필이 없습니다 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498561757390d5528b263ce450d5f38efb00266d" datatype="html">
+ <source>-- Select an erasure code profile --</source>
+ <target>-- Erasure Code 프로필을 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="616a2532fbaace94934f5943e381b63e2623f004" datatype="html">
+ <source>This profile can't be deleted as it is in use.</source>
+ <target>이 프로필은 사용 중입니다. 삭제할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="994363f08f9fbfa3b3994ff7b35c6904fdff18d8" datatype="html">
+ <source>Profile</source>
+ <target>프로필</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="023d6f718770d2ea4ab8cabe26b0ec27ef967ec2" datatype="html">
+ <source>Used by pools</source>
+ <target>데이터 풀에서 사용됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">387</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1061ba5ee07a5c6af09e09330dbc29201baf2aa" datatype="html">
+ <source>Profile is not in use.</source>
+ <target>프로필이 사용 중이 아닙니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33150f22ce5348aa6c499bd092c3f4f3695d62cc" datatype="html">
+ <source>Crush ruleset</source>
+ <target>크러쉬 규칙</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">293</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">303</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c69b0bcd4698aa845d32c4c4ad488492552cb469" datatype="html">
+ <source>A new crush ruleset will be implicitly created.</source>
+ <target>새로운 크러쉬 규칙이 자동으로 생성됩니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="896e9987db5e9bb279e6deed5d2dff28c242ef66" datatype="html">
+ <source>There are no rules.</source>
+ <target>규칙이 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73a6b31116b3cc322af951daa0bafdc169e6c42e" datatype="html">
+ <source>-- Select a crush rule --</source>
+ <target>-- 크러쉬 룰을 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7d4894e770f8853050b1f6dd55bdd77a51a8ac6" datatype="html">
+ <source>Placement and
+ replication strategies or distribution policies that allow to
+ specify how CRUSH places data replicas.</source>
+ <target>다음을 허용하는 배치 및 복제 전략 또는 배포 정책입니다.
+CRUSH에서 데이터 복제본을 배치하는 방법을 지정합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">328,330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea91d648f92002bc9f96d9b26b735c83ca0b53c6" datatype="html">
+ <source>This rule can't be deleted as it is in use.</source>
+ <target>이 규칙은 사용 중입니다. 삭제할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">346</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92da80699921e89fb19372e25b8d0f3b9fa427fc" datatype="html">
+ <source>Crush rule</source>
+ <target>크러쉬 규칙</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">365</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5489e9f96835f469f6f728a00d8efa88ea5bc940" datatype="html">
+ <source>Crush steps</source>
+ <target>크러쉬 단계</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc5f5496a9e50fe69e1a09784f28d94944108294" datatype="html">
+ <source>Rule is not in use.</source>
+ <target>규칙이 사용 중이 아닙니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="104a0e6900d1d1b0c8cf9e5947e36edb352583fc" datatype="html">
+ <source>The rule can't be used in the current cluster as it has too few OSDs to meet the minimum required OSD by this rule.</source>
+ <target>스토리지 디바이스가 너무 적어서 이 규칙에 필요한 최소 스토리지 디바이스를 충족할 수 없으므로 현재 클러스터에서 규칙을 사용할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">409,410</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2208d63d5940ce656006a220102b1eb2b5e553da" datatype="html">
+ <source>Compression</source>
+ <target>압축</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">420</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c6f25c47da62ec597c6057a36ddfc3209811ec5" datatype="html">
+ <source>Algorithm</source>
+ <target>알고리즘</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">444</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4903231d42089325a28892c0fde1aed46b733ae6" datatype="html">
+ <source>-- No erasure compression algorithm available --</source>
+ <target>-- 이용가능한 Erasure 압축알고리즘이 없습니다 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d68ddb254275f8f44221e9ad6d8ceeb59ca46a6" datatype="html">
+ <source>Minimum blob size</source>
+ <target>최소 blob 크기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">468</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb2f176df80647137cbb02bbeb29e5dec707a400" datatype="html">
+ <source>e.g., 128KiB</source>
+ <target>예) 128KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">477</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b7f6e53a4521c6eb3ced4c007fdd4cf80bb7707" datatype="html">
+ <source>Value should be greater than 0</source>
+ <target>값은 0보다 커야합니다</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">482</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">506</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8db98ab14b4e207ec763dfdefbc2dae367aab1cc" datatype="html">
+ <source>Value should be less than the maximum blob size</source>
+ <target>값은 최대 blob 크기보다 작아야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151efb127a9a4dd25259a0b2055442318a141f5b" datatype="html">
+ <source>Maximum blob size</source>
+ <target>최대 blob 크기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c656f0e346bbadf46eb1a5d20d0307a3bd20ba8" datatype="html">
+ <source>e.g., 512KiB</source>
+ <target>예) 512KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65a24eee8a026f3b1113fe9e157e9a0dd69486" datatype="html">
+ <source>Value should be greater than the minimum blob size</source>
+ <target>값은 최소 blob 크기보다 커야 합니다</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">509</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="261ba09c4a59de83f48f52a23fd328da37e61ff4" datatype="html">
+ <source>Ratio</source>
+ <target>비율</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">517</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1430457a9c3c66366e51d76bf10396014c576be" datatype="html">
+ <source>Compression ratio</source>
+ <target>압축율</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">528</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae5ce6de352cde949998fb10754459c3a4eb183b" datatype="html">
+ <source>Value should be between 0.0 and 1.0</source>
+ <target>값은 0.0과 1.0 사이 여야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d99b34162c9c34f10d0ccd8dbae83d8569c2db77" datatype="html">
+ <source>Max bytes</source>
+ <target>최대 바이트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">546</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1d14a18879c62f3f4ed705318b7164a1160e249" datatype="html">
+ <source>Leave it blank or specify 0 to disable this quota.</source>
+ <target>이 할당량을 사용하지 않으려면 비워 두거나 0을 지정하십시오.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">572</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7565b131562ff6c5f769fdbd239a772154abdd97" datatype="html">
+ <source>A valid quota should be greater than 0.</source>
+ <target>유효한 할당량은 0보다 커야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">550</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">574</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b8bf35b66f09a301eef92ffc3cb2fd259df67ce9" datatype="html">
+ <source>Max objects</source>
+ <target>최대 오브젝트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">570</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="95f348167622d832c5ae532b6944635c8e2ae5cb" datatype="html">
+ <source>The value should be greater or equal to 0</source>
+ <target>값은 0보다 크거나 같아야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">586</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1088629182722162774" datatype="html">
+ <source>pool</source>
+ <target>데이터 풀</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6215593782779198370" datatype="html">
+ <source>erasure code profile</source>
+ <target>Erasure code 프로필</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4390273881304618317" datatype="html">
+ <source>crush rule</source>
+ <target>크러쉬 규칙</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">721</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d8a7c8aea58294a3c57c23af0468ddf0ba0c9c7" datatype="html">
+ <source>Pools List</source>
+ <target>데이터 풀 목록</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9055665654201606988" datatype="html">
+ <source>Data Protection</source>
+ <target>데이터 보호</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6658000829978978023" datatype="html">
+ <source>Applications</source>
+ <target>응용 프로그램</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5232365108332422324" datatype="html">
+ <source>PG Status</source>
+ <target>PG 상태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1669788723782899084" datatype="html">
+ <source>Crush Ruleset</source>
+ <target>크러쉬 규칙</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7961062124768120122" datatype="html">
+ <source>Pool deletion is disabled by the mon_allow_pool_delete configuration setting.</source>
+ <target>mon_allow_pool_delete 구성 설정에 의해 데이터 풀 삭제가 비활성화되었습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c" datatype="html">
+ <source>ID</source>
+ <target>아이디</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee5132a8da30e0b7f9f5c70dbc91928d17dd909" datatype="html">
+ <source>Owner</source>
+ <target>소유자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c51963a9c553b29427ef783bbb69fa6634fa8c" datatype="html">
+ <source>Index type</source>
+ <target>색인 형식</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e6f950a32eaea32ec7e192f9ca3d3dfe469d4ba" datatype="html">
+ <source>Placement rule</source>
+ <target>배치 규칙</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6972d213e31c4ea4f887e60db99d9881bc8fcd3e" datatype="html">
+ <source>Marker</source>
+ <target>표시</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47b02acd2d3254d1ace1926f840523f154ebef71" datatype="html">
+ <source>Maximum marker</source>
+ <target>최대 표시</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="092fa3a7df9168b14d3f83a77a4035e92b92ce15" datatype="html">
+ <source>Master version</source>
+ <target>마스터 버전</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97434cc5001d407f90c7447a12d9e8e6848a2aa3" datatype="html">
+ <source>Modification time</source>
+ <target>수정된 시간</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90fe2e41e7fde38453ce4e619efeea9bc6adea9c" datatype="html">
+ <source>Zonegroup</source>
+ <target>제로 그룹</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="efeade5060b3add63863c24871f0830fb16b7e6d" datatype="html">
+ <source>Versioning</source>
+ <target>버전 관리</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62a923f047ca49e7a4782629e91fea1ba32db68f" datatype="html">
+ <source>MFA Delete</source>
+ <target>MFA 삭제</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="649a410bd0ace333d067d8fa22f12bdbdb43533b" datatype="html">
+ <source>Bucket quota</source>
+ <target>버킷 할당량</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">567</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f50a33d3c339f8f4a465141f8caa5d2d8c005251" datatype="html">
+ <source>Enabled</source>
+ <target>활성화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">579</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cef1595d040e77cbb4466e60382028d4c2040cac" datatype="html">
+ <source>Maximum size</source>
+ <target>최대 크기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa6fb95c355f172bda303de1ce2f38c251a149cf" datatype="html">
+ <source>Unlimited</source>
+ <target>무제한</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee862a800364b4d11f9b8cb9955a28a60f840a45" datatype="html">
+ <source>Maximum objects</source>
+ <target>최대 객체</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b84370895ab9eb44672f57146fa05c5947f1c0c" datatype="html">
+ <source>Locking</source>
+ <target>잠금</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c3d9d2296f7886e8289b9f623323803deacfc6" datatype="html">
+ <source>Days</source>
+ <target>날짜</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f44bdf9ab00a973bbe482e9fc450e3f67e60c0d" datatype="html">
+ <source>Bucket names can only contain lowercase letters, numbers, periods and hyphens.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eabb4db920d9f9b2480cf438468b86e1bea02a9b" datatype="html">
+ <source>The chosen name is already in use.</source>
+ <target>선택한 이름이 이미 사용중입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b06de7f834c622197e68b66a2abe893040b174c4" datatype="html">
+ <source>Bucket names must not contain uppercase characters or underscores.</source>
+ <target>버킷 이름에는 대문자 또는 밑줄을 사용할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abacf4af2f66d3af08c5ebe502b21b1f42ac649" datatype="html">
+ <source>Each label must start and end with a lowercase letter or a number.</source>
+ <target>각 라벨은 소문자 또는 숫자로 시작하고 끝나야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a7f52e6813e0535026f61a2d6e8adc8a1d006a" datatype="html">
+ <source>Bucket names cannot be formatted as IP address.</source>
+ <target>버킷 이름의 형식은 IP 주소로 지정할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2a2460396d35e14e7acfb4e060196a0679bdcff" datatype="html">
+ <source>Bucket labels cannot be empty and can only contain lowercase letters, numbers and hyphens.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf5c849977e0be2dbfc862d044edd323bfd9fb77" datatype="html">
+ <source>Bucket names must be 3 to 63 characters long.</source>
+ <target>버킷 이름은 3자에서 63자 사이여야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e4c918357c7445fbf19a203e5f0f0ece1960b3b" datatype="html">
+ <source>-- Select a user --</source>
+ <target>-- 사용자를 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4aab1f837bc8ec222e4f25922465d1c5929a1fc" datatype="html">
+ <source>Placement target</source>
+ <target>배치 대상</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bae0a7fc2c9c1fde7d937a8a1a3c7e6825cf7d1" datatype="html">
+ <source>-- Select a placement target --</source>
+ <target>-- 배치 대상을 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="016d24e069e7d505a090fb8243e5cd43b35dc39b" datatype="html">
+ <source>Enables versioning for the objects in the bucket.</source>
+ <target>버킷의 개체에 대한 버전 관리를 사용하도록 설정합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">151</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e6775ffd06878aa145c07359f28557f01ede04f" datatype="html">
+ <source>Multi-Factor Authentication</source>
+ <target>다중 인증</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29e8a5d4fb767d4ad0c762c81c6264cec4c0ba97" datatype="html">
+ <source>Delete enabled</source>
+ <target>삭제 활성화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40fbc3ac8c1ea4ecfe62247e91f1f999ad5baf76" datatype="html">
+ <source>Enables MFA (multi-factor authentication) Delete, which requires additional authentication for changing the bucket versioning state.</source>
+ <target>버킷 버전 상태를 변경하기 위해 추가 인증이 필요한 MFA(다중 인증) 삭제를 사용하도록 설정합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24c93a8c13db46defa06ed7b5e026a3edb52b91" datatype="html">
+ <source>Token Serial Number</source>
+ <target>토큰 시리얼 번호</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6d9536c2af2e5e9a228c3e3e1809dc1fefe0149" datatype="html">
+ <source>Token PIN</source>
+ <target>토큰 PIN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f038d51ab1645f15b0cd58f195c72a7eeebd4729" datatype="html">
+ <source>Enables locking for the objects in the bucket. Locking can only be enabled while creating a bucket.</source>
+ <target>버킷의 개체에 대해 잠금을 활성화합니다. 잠금은 버킷을 만드는 동안에만 사용할 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9af1b4baa2dd8ed2bfc3cc756b12a2271c2dd793" datatype="html">
+ <source>Compliance</source>
+ <target>준수</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="edd600fa489d1b4a4448dce694ed932e52ce8fda" datatype="html">
+ <source>Governance</source>
+ <target>관리</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="218c7d6d318c51e7105309aaeb0baec9d19e4efb" datatype="html">
+ <source>The number of days that you want to specify for the default retention period that will be applied to new objects placed in this bucket.</source>
+ <target>이 버킷에 배치된 새 개체에 적용할 기본 보존 기간(일)입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">264</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="289b101ec12427b3ca819df9e43cc3b14fae2cc4" datatype="html">
+ <source>The entered value must be a positive integer.</source>
+ <target>입력한 값은 양의 정수여야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48d8247c1ba2ea156109bf286c5f6dd26b4be760" datatype="html">
+ <source>Retention Days must be a positive integer.</source>
+ <target>보존 일수는 양의 정수여야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4349284625269221231" datatype="html">
+ <source>bucket</source>
+ <target>버킷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6161088322338624846" datatype="html">
+ <source>Updated Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218632328857697292" datatype="html">
+ <source>Created Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c338bae89822d7eefbc9a887c458a7d8a98e55e" datatype="html">
+ <source>No Limit</source>
+ <target>제한 없음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3715596725146409911" datatype="html">
+ <source>Owner</source>
+ <target>소유자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5545511293826600258" datatype="html">
+ <source>Used Capacity</source>
+ <target>사용된 용량</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1925090152473969054" datatype="html">
+ <source>Capacity Limit %</source>
+ <target>용량 제한 %</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8713861779825116442" datatype="html">
+ <source>Object Limit %</source>
+ <target>오브젝트 제한 %</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5913880066213114620" datatype="html">
+ <source>buckets</source>
+ <target>버킷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eeba399c4dae8d4890c27b7a2cd2dc28fcf8b5f9" datatype="html">
+ <source>Performance Counters</source>
+ <target>성능 카운터</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="479488ab6e91ecb375484edc78bee3d13467f33f" datatype="html">
+ <source>Daemons List</source>
+ <target>데몬 목록</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca2dee83bb58290d93fb0d17ee8bc9f095a4576f" datatype="html">
+ <source>Sync Performance</source>
+ <target>성능 동기화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4378147649219625174" datatype="html">
+ <source>Zone</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6148052126949932311" datatype="html">
+ <source>Zone Group</source>
+ <target>Zone 그룹</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3840481991104643295" datatype="html">
+ <source>Realm</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1221ca97d19eaa9a7bc0c5243d5fc5befe1d2314" datatype="html">
+ <source>-- Select a type --</source>
+ <target>-- 형태를 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1b8990332af18f1c5159a6061ca889bcbb28432" datatype="html">
+ <source>Permission</source>
+ <target>권한</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a08c589f82f69d892307288da14190ae1dd583d5" datatype="html">
+ <source>-- Select a permission --</source>
+ <target>-- 권한을 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7345972049922682356" datatype="html">
+ <source>capability</source>
+ <target>기능</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a94e6b2b5b834d92cceb90037d51ad6165c8b619" datatype="html">
+ <source>Tenant</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
+ <source>User ID</source>
+ <target>사용자 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b760f123248930122fc7e7b6b6bf94e376e959c8" datatype="html">
+ <source>Full name</source>
+ <target>이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69b6ac577a19acc39fc0c22342092f327fff2529" datatype="html">
+ <source>Email address</source>
+ <target>이메일 주소</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92f3f203270a29b3001871153f02c063484a1574" datatype="html">
+ <source>Suspended</source>
+ <target>일시 정지됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011e20c5bbe51602d459a860fbf29b599b55edd" datatype="html">
+ <source>System</source>
+ <target>시스템</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db18a2772988415466a7f75dc42663ce78c9c1d3" datatype="html">
+ <source>Maximum buckets</source>
+ <target>최대 버킷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c4c62e8ba24601be5cfe7dc5d32c24bbbd4b53c" datatype="html">
+ <source>Subusers</source>
+ <target>보조 사용자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17bb3082e6fe5003203ef992a3714172334631a1" datatype="html">
+ <source>Capabilities</source>
+ <target>기능</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32f8a0570373cacb9c56cf227502483a29d605bc" datatype="html">
+ <source>MFAs(Id)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36ad38f9c1a1485e09b67778a28af84553290ffb" datatype="html">
+ <source>User quota</source>
+ <target>사용자 할당량</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">473</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0bcd5ef19af0f1b814141ca8c57df623d8270088" datatype="html">
+ <source>Keys</source>
+ <target>키</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2aba1e87039819aca3b70faa9aa848c12bf139ca" datatype="html">
+ <source>Show</source>
+ <target>보기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">395</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5248717555542428023" datatype="html">
+ <source>Username</source>
+ <target>사용자 이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240806681889331244" datatype="html">
+ <source>Unlimited</source>
+ <target>무제한</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db4e1a734518691b128ef40b939cc673f01d03a6" datatype="html">
+ <source>The value is not valid.</source>
+ <target>값이 유효하지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">617</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6aaf5d2a304167272ac73e3b1d1c162e16c77858" datatype="html">
+ <source>The chosen user ID is already in use.</source>
+ <target>선택된 사용자 아이디가 이미 사용 중입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="025be1d01b2f6cbd09e772a1d3de02fab0678b26" datatype="html">
+ <source>Show Tenant</source>
+ <target>Tenant 보기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6af106b0d759fd2882e645604675c4494abfcd5b" datatype="html">
+ <source>The chosen user ID exists in this tenant.</source>
+ <target>선택한 사용자 ID가 이 tenant에 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="df441e80db2157f9d272b75de724ba4a82b96b57" datatype="html">
+ <source>This is not a valid email address.</source>
+ <target>이메일 주소가 유효하지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca271adf154956b8fcb28f4f50a37acb3057ff7c" datatype="html">
+ <source>The chosen email address is already in use.</source>
+ <target>선택한 이메일 주소가 이미 사용 중입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="030197cebe938edf35422e92fe14183d06eb670b" datatype="html">
+ <source>Max. buckets</source>
+ <target>최대 버킷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f39256070bfc0714020dfee08895421fc1527014" datatype="html">
+ <source>Disabled</source>
+ <target>비활성화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c05002b0ac2040f1aede5e727e0ffd06eda819" datatype="html">
+ <source>Custom</source>
+ <target>사용자 설정</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28872515cb81d197a3a1733fa546d3e0f0dd6c67" datatype="html">
+ <source>The entered value must be &gt;= 1.</source>
+ <target>입력한 값은 1 이상 이어야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="583a219c524155c2314eb06ee29162bb315272a3" datatype="html">
+ <source>S3 key</source>
+ <target>S3 키</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c217ee914725a37e9dd2336c721c8e63e9666bdc" datatype="html">
+ <source>Auto-generate key</source>
+ <target>자동 생성된 키</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f1c1c0f2bce4c9f92d1a2061e8161cb0006c31a" datatype="html">
+ <source>Access key</source>
+ <target>접근 키</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b864acb67296a9819c1db0069c4c47d8b5ce8f44" datatype="html">
+ <source>Secret key</source>
+ <target>비밀 키</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="128d6efb51d9ddc7c0cc695a2deeca5b9523f6e4" datatype="html">
+ <source>There are no subusers.</source>
+ <target>보조 사용자가 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fd6dfb8ecb982dbc3affb2c2d5414c4f5b6abd2" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">294,295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67c746c1ba9dab4351fedc4c7cba4e6d6b0dbc47" datatype="html">
+ <source>S3</source>
+ <target>S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d6819038d608623503918fb2553f53d68231ec3a" datatype="html">
+ <source>There are no keys.</source>
+ <target>키가 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">377</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc1c1a7140ff6b815a95b65ee2780fdbe1b2b7a1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">356,357</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6ddb5e991a3ecd2659fb520bc5acc81b67e08ddd" datatype="html">
+ <source>Swift</source>
+ <target>스위프트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">371</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d01eccdda47fc907c5be35bcb16d2dcd02b0270" datatype="html">
+ <source>There are no capabilities.</source>
+ <target>기능이 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5a451c4ea65a4046f0b49d489a7013abf0b5861" datatype="html">
+ <source>All capabilities are already added.</source>
+ <target>모든 기능이 이미 추가 되었습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">456</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="043e2ec0036ceadd926fd5e3f93cd6f3565f3648" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">461,462</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6146e13ceca5fa5cc17b771b282fe5955f3d19fa" datatype="html">
+ <source>Unlimited size</source>
+ <target>무제한 크기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">595</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6db8aa7c99fdce18edb33dde57729acede2b308" datatype="html">
+ <source>Max. size</source>
+ <target>최대 크기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">511</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">605</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc630b2093e880fffa19df99d5cd8b87605037f8" datatype="html">
+ <source>Unlimited objects</source>
+ <target>무제한 오브젝트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cda5a993d06f0bb10048be9d3aba6555aa9f356" datatype="html">
+ <source>Max. objects</source>
+ <target>최대 오브젝트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">642</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="623ac50f37a26caec6fd7cd519b653e3315cba25" datatype="html">
+ <source>The entered value must be &gt;= 0.</source>
+ <target>입력된 값은 0 이상 이어야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">654</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="123010868147850959" datatype="html">
+ <source>user</source>
+ <target>사용자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8368421344177343441" datatype="html">
+ <source>subuser</source>
+ <target>보조 사용자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4662015204945271252" datatype="html">
+ <source>S3 Key</source>
+ <target>S3 키</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9103468069826049692" datatype="html">
+ <source>Updated Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="884841609901737584" datatype="html">
+ <source>Created Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4363143805416924501" datatype="html">
+ <source>Tenant</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8301535046747035390" datatype="html">
+ <source>Full name</source>
+ <target>이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3967269098753656610" datatype="html">
+ <source>Email address</source>
+ <target>이메일 주소</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5851424994801012357" datatype="html">
+ <source>Suspended</source>
+ <target>일시 중단</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208300173682032371" datatype="html">
+ <source>Max. buckets</source>
+ <target>최대 버킷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1670306451865226564" datatype="html">
+ <source>users</source>
+ <target>사용자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c614babd1950adb2be75df4e2c9747286d6adc" datatype="html">
+ <source>-- Select a username --</source>
+ <target>-- 사용자명을 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2841767821d6b66238c34d07e413b0af67aee92" datatype="html">
+ <source>Subuser</source>
+ <target>보조 사용자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd59fc25a7bd98cff3e75117c09697c8a007a514" datatype="html">
+ <source>The chosen subuser ID is already in use.</source>
+ <target>선택한 보조 사용자 아이디가 이미 사용중입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d386c357ebcbc04ed05c4babd5a03626f9b1674" datatype="html">
+ <source>read, write</source>
+ <target>읽기, 쓰기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84e3e3f9a4f31a039b648c97debf95fcb20f4c4a" datatype="html">
+ <source>full</source>
+ <target>가득참</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6bf81d032a2316464f9df2f0d2f3d753f89f0d3" datatype="html">
+ <source>Swift key</source>
+ <target>스위프트 키</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e0c12685d50d47448ceed9423977ef39775c037" datatype="html">
+ <source>Auto-generate secret</source>
+ <target>자동 생성된 암호</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5091031285775138345" datatype="html">
+ <source>Subuser</source>
+ <target>보조 사용자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8453697749389230205" datatype="html">
+ <source>Swift Key</source>
+ <target>스위프트 키</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ac54c18c1b520e948095c83a3a1025f02ce6dcc6" datatype="html">
+ <source>Neither hostname nor OSD ID given</source>
+ <target>호스트 이름 또는 스토리지 디바이스 아이디가 지정되지 않았습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4533150758393178756" datatype="html">
+ <source>Device ID</source>
+ <target>장치 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1291053608320944146" datatype="html">
+ <source>State of Health</source>
+ <target>상태</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29167121133682512" datatype="html">
+ <source>Good</source>
+ <target>좋음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8767957606064036733" datatype="html">
+ <source>Bad</source>
+ <target>나쁨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8052456228079338924" datatype="html">
+ <source>Stale</source>
+ <target>오래됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6223439643831041743" datatype="html">
+ <source>Life Expectancy</source>
+ <target>기대 수명</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3144481541623761279" datatype="html">
+ <source>Prediction Creation Date</source>
+ <target>예측 작성 날짜</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="264574868375698540" datatype="html">
+ <source>Device Name</source>
+ <target>장치 이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1419569261746199221" datatype="html">
+ <source>Daemons</source>
+ <target>데몬</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f635b3cb0600409a2ad44a5bd1863c699e6a01c" datatype="html">
+ <source>Failed to retrieve SMART data.</source>
+ <target>SMART 데이터를 가져오지 못했습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a8a3f354bd640299068edd912f4bb5325264f250" datatype="html">
+ <source>The data received has the JSON format version 2.x and is currently incompatible with the dashboard.</source>
+ <target>수신된 데이터는 JSON 형식 버전 2.x이며 현재 대시보드와 호환되지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="04f8a3c7e8ac610e6581960162cc15f55a16696a" datatype="html">
+ <source>No SMART data available.</source>
+ <target>SMART 데이터를 사용할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a185c9b97513b3882604ea9bab60edbfac945c15" datatype="html">
+ <source>SMART overall-health self-assessment test result</source>
+ <target>SMART의 전반적인 상태 자가 평가 테스트 결과입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="290e4c9ad42dc6e9176656c864a5faed8053f406" datatype="html">
+ <source>unknown</source>
+ <target>알려지지 않음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a03d3c2e459f8f8fa7202c0fce465d6165f9e2b" datatype="html">
+ <source>passed</source>
+ <target>통과됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41435d5a5692c8e412c74deaee95d99dbd3617e1" datatype="html">
+ <source>failed</source>
+ <target>실패함</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddd5dd6d930030096ea617f62c82b648a0dd9484" datatype="html">
+ <source>Device Information</source>
+ <target>장치 정보</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e149c483d88cfcff11d1c5db85e84af7c3149c4" datatype="html">
+ <source>No device information available for this device.</source>
+ <target>이 장치에 사용할 수 있는 장치 정보가 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20cb12827cbe559a7b1da6fdae96041b3b5c3c55" datatype="html">
+ <source>SMART</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380295f37caea93701d071485a38ef0bdba57133" datatype="html">
+ <source>No SMART data available for this device.</source>
+ <target>이 장치에 사용할 수 있는 SMART 데이터가 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5758c3f16f8749f0f4e2a787f02e8b4da246102f" datatype="html">
+ <source>SMART data is loading.</source>
+ <target>SMART 데이터를 불러 오고 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5363861031080361352" datatype="html">
+ <source>Smartctl has received an unknown argument (error code <x id="PH" equiv-text="smartData.smartctl_error_code"/>). You may be using an incompatible version of smartmontools. Version &gt;= 7.0 of smartmontools is required to successfully retrieve data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">61,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5085718566932809950" datatype="html">
+ <source>An error with error code <x id="PH" equiv-text="smartData.smartctl_error_code"/> occurred.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2091295268977103253" datatype="html">
+ <source>Raw</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5963653123239768443" datatype="html">
+ <source>Threshold</source>
+ <target>임계치</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2893124970059125090" datatype="html">
+ <source>When Failed</source>
+ <target>실패 했을 때</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5614367840516299633" datatype="html">
+ <source>Worst</source>
+ <target>최악의 경우</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d06ae77f9ec46a4cdd49e7e76c73a411aaf2ee38" datatype="html">
+ <source>Please set a new password.</source>
+ <target>새로운 비밀번호를 입력하세요.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8b5b3566e88438f51bd5f6caf6c090ed565ba5ed" datatype="html">
+ <source>You will be redirected to the login page afterwards.</source>
+ <target>다음에는 로그인 페이지로 연결됩니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cf42e491adc166a337a960eb84d03c0c3f677c8" datatype="html">
+ <source>The old and new passwords must be different.</source>
+ <target>기존 비밀번호와 새로운 비밀번호는 같지 않아야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90163a3d3746819aef42e829f4446331232f3b66" datatype="html">
+ <source>Password confirmation doesn't match the new password.</source>
+ <target>새로운 비밀번호가 일치하지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0070e83d11da39d6f4bb95065c2675db1610b419" datatype="html">
+ <source>Username is required</source>
+ <target>사용자 이름이 필요합니다</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e20f8b8a4706526c9024cc2f39d568345d100dc" datatype="html">
+ <source>Password is required</source>
+ <target>비밀번호가 필요합니다</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f093d9574ab746b231504bd2cbb65f04bd7b00db" datatype="html">
+ <source>Log in</source>
+ <target>로그인</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5590086849807274701" datatype="html">
+ <source>Scope</source>
+ <target>범위</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327592562693301723" datatype="html">
+ <source>Read</source>
+ <target>읽기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5674286808255988565" datatype="html">
+ <source>Create</source>
+ <target>생성</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4021752662928002901" datatype="html">
+ <source>Update</source>
+ <target>업데이트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022070615528435141" datatype="html">
+ <source>Delete</source>
+ <target>삭제</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ea5c4d8942c00752dcc72e72949c5d9832f6399" datatype="html">
+ <source>Description...</source>
+ <target>세부 설명</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70f45880fce6ac5d8e468e25e82aefbba8098cfe" datatype="html">
+ <source>Permissions</source>
+ <target>권한</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="122114774689391224" datatype="html">
+ <source>role</source>
+ <target>규칙</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616102757855967475" datatype="html">
+ <source>All</source>
+ <target>전체</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4416727401284087008" datatype="html">
+ <source>Created role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3472946357042916911" datatype="html">
+ <source>Updated role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="373024661645814027" datatype="html">
+ <source>System Role</source>
+ <target>시스템 규칙</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753648234171918096" datatype="html">
+ <source>Deleted role '<x id="PH" equiv-text="role"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1674202514578558795" datatype="html">
+ <source>New name</source>
+ <target>새로운 이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4857700187193019038" datatype="html">
+ <source>Clone Role</source>
+ <target>규칙 복제</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="748631939386170157" datatype="html">
+ <source>Cloned role '<x id="PH" equiv-text="values['newName']"/>' from '<x id="PH_1" equiv-text="name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="195c31a2f970e790231a6bb94a5e8ca0167406d9" datatype="html">
+ <source>The username already exists.</source>
+ <target>존재하는 사용자 이름 입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f3bdcce4b2e8c37cd7f0f6c92ef8cff34b039b8" datatype="html">
+ <source>Confirm password</source>
+ <target>비밀번호 확인</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cbb979e63ba50e0ca3adfa09cbdcaefd0853fca1" datatype="html">
+ <source>Password confirmation doesn't match the password.</source>
+ <target>비밀번호 확인이 일치하지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="96621f9ed2e4ae5204564e583d2c816bedead571" datatype="html">
+ <source>Password expiration date</source>
+ <target>비밀번호 만료일</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48932db3801fe9d5d72a60a3e656bffd17c1c5d9" datatype="html">
+ <source>Password expiration date...</source>
+ <target>비밀번호 만료일</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc" datatype="html">
+ <source>Email</source>
+ <target>이메일</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d0ec081dd61eb4f43aea269077bbe38eae87b7f9" datatype="html">
+ <source>Invalid email.</source>
+ <target>유효하지 않은 이메일</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9610487cbeb5796d34d8601b5ac0c0a65f9e1d19" datatype="html">
+ <source>Roles</source>
+ <target>역할</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8913c216dd506e20e412e144381d8d2a65a84359" datatype="html">
+ <source>User must change password at next logon</source>
+ <target>사용자는 다음 로그온 시 비밀번호를 변경해야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0051a3479d3ba79135c16dc8cc017950a2cce821" datatype="html">
+ <source>You are about to remove &quot;user read / update&quot; permissions from your own user.</source>
+ <target>사용자 자신의 사용자로부터 &quot;사용자 읽기/업데이트&quot; 권한을 제거하려고 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af4bf9fcb256853f14cf947eb1deb8d7f176d3f9" datatype="html">
+ <source>If you continue, you will no longer be able to add or remove roles from any user.</source>
+ <target>계속할 경우 더 이상 사용자로부터 역할을 추가하거나 제거할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314291969883771319" datatype="html">
+ <source>There are no roles.</source>
+ <target>역할이 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4306072924538089180" datatype="html">
+ <source>Created user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1349763489797682899" datatype="html">
+ <source>Update user</source>
+ <target>사용자 업데이트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8688396456017237992" datatype="html">
+ <source>You were automatically logged out because your roles have been changed.</source>
+ <target>역할이 변경되어 자동으로 로그아웃 되었습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2335813072344088607" datatype="html">
+ <source>Updated user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4768749765465246664" datatype="html">
+ <source>Email</source>
+ <target>이메일</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795890916060309463" datatype="html">
+ <source>Roles</source>
+ <target>역할</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6877445485286599988" datatype="html">
+ <source>Password expiration date</source>
+ <target>비밀번호 만료일</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="705657168061753072" datatype="html">
+ <source>Deleted user '<x id="PH" equiv-text="username"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="405819296611088743" datatype="html">
+ <source>Failed to delete user '<x id="PH" equiv-text="username"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8935387756949610047" datatype="html">
+ <source>You are currently logged in as '<x id="PH" equiv-text="username"/>'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0eb15f32b2b92d7f3103ef3ff032621888a8dc32" datatype="html">
+ <source>Old password</source>
+ <target>기존 비밀번호</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229" datatype="html">
+ <source>New password</source>
+ <target>새로운 비밀번호</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ede41f01c781b168a783cfcefc6fb67d48780d9b" datatype="html">
+ <source>Confirm new password</source>
+ <target>새로운 비밀번호 확인</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809196861118879526" datatype="html">
+ <source>password</source>
+ <target>비밀번호</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623124197136601291" datatype="html">
+ <source>Updated user password&quot;</source>
+ <target>비밀번호가 업데이트되었습니다</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be" datatype="html">
+ <source>Users</source>
+ <target>사용자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ced3246fa3db31be0f7da06648463f29ba378fbe" datatype="html">
+ <source>Selected Object Gateway:</source>
+ <target>선택한 오브젝트 게이트웨이:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c53062af97ebda2a03f905698f58e524ecf8b968" datatype="html">
+ <source>Select Object Gateway</source>
+ <target>오브젝트 게이트웨이 선택</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="235c355afdcbf72953a15d7fc8d0d9e7a6619f46" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Page not Found<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aee9d027170f84774f2980537556f5099369b82" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for. The page you requested may have been changed or moved.</source>
+ <target>죄송합니다, 페이지를 찾을 수 없습니다. 요청한 페이지가 변경되거나 이동 되었을 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">22,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2b46fe9a975c6531af77fee858ccd37327980f7" datatype="html">
+ <source>Please consult the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>documentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> on how to configure and enable the <x id="INTERPOLATION" equiv-text="{{ section_info }}"/> management functionality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">26,27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9d57ca7cab78c6f0d27e0d890cb8cf1515e4e30a" datatype="html">
+ <source>Go To Dashboard</source>
+ <target>대시보드로 이동</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6578397717654172779" datatype="html">
+ <source>Page Not Found</source>
+ <target>페이지를 찾을 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8185335715884155108" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for.
+ The page you requested may have been changed or moved.</source>
+ <target>죄송합니다, 찾으시는 것을 찾을 수 없습니다.
+요청한 페이지가 변경되거나 이동 되었을 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="143318366100741906" datatype="html">
+ <source>Access Denied</source>
+ <target>접근 거부</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5384670299771400832" datatype="html">
+ <source>Sorry, you don’t have permission to view this page or resource.</source>
+ <target>죄송합니다. 이 페이지 또는 리소스를 볼 수 있는 권한이 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2424411274809083521" datatype="html">
+ <source>User Denied</source>
+ <target>사용자가 거부되었습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7645004872908092358" datatype="html">
+ <source>Sorry, the user does not exist in Ceph.
+ You'll be logged out from the Identity Provider when you retry logging in.</source>
+ <target>죄송합니다. 사용자가 Ceph에 없습니다.
+로그인을 다시 시도하면 ID 제공자에서 로그아웃됩니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">24,25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f286db6ac9482dbf567bc491d49a6eade444895a" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7911416166208830577" datatype="html">
+ <source>Help</source>
+ <target>도움말</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8878700331247603166" datatype="html">
+ <source>Security</source>
+ <target>보안</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8642696205489749843" datatype="html">
+ <source>Trademarks</source>
+ <target>상표</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1481ecd21e760ac919a24e26cf790acd82e40199" datatype="html">
+ <source>Dashboard Settings</source>
+ <target>대시보드 설정</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a79aab4ef674bf3f6532292107c0054302236e0f" datatype="html">
+ <source>User management</source>
+ <target>사용자 관리</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="197e0246502ca64d0de0df0d5c2deec51d41ff45" datatype="html">
+ <source>Telemetry configuration</source>
+ <target>원격 분석 구성</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85b79c9064aed1ead31ace985f31aa1363f6bdaf" datatype="html">
+ <source>Help</source>
+ <target>도움말</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06638e0f01d82c0786f63aa9832fbe7866b86087" datatype="html">
+ <source>documentation</source>
+ <target>문서</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e351b40b3869a5c7d19c3d4918cb1ac7aaab95c4" datatype="html">
+ <source>API</source>
+ <target>API</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a" datatype="html">
+ <source>About</source>
+ <target>정보</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="049dfd9fe6c78914ad58cf89ac6a631fca28ec74" datatype="html">
+ <source>Logged in user</source>
+ <target>로그인된 사용자</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5022c5ae3ae921c07bf5f881e9b026b4a6708a7" datatype="html">
+ <source>Signed in as <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9" datatype="html">
+ <source>Change password</source>
+ <target>비밀번호 변경</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d22c795daf43877a5f708dca2bccd549eb0471d" datatype="html">
+ <source>Sign out</source>
+ <target>로그아웃</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319e0745bcbc132451569294fa2fa21bf10f555a" datatype="html">
+ <source>Toggle navigation</source>
+ <target>내비게이션 전환</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f65253954b66e929a8b4d5ecaf61f9129f8cec64" datatype="html">
+ <source>Dashboard</source>
+ <target>대시보드</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c95898abff46bfac3ed6eb2afef74597e60b15c" datatype="html">
+ <source>CRUSH map</source>
+ <target>크러쉬 맵</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7b2bc4b86de6e96d353f6bf2b4d793ea3a19ba0" datatype="html">
+ <source>Manager Modules</source>
+ <target>매니저 모듈</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb3d5aefff38a814b76da74371cbf02c0789a1ef" datatype="html">
+ <source>Logs</source>
+ <target>로그</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17fc3efe5f9fa4e0289c900cb6202265215a1a27" datatype="html">
+ <source>Monitoring</source>
+ <target>모니터링</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f5d0c10614e8a34f0e2dad33a0568277c50cf69" datatype="html">
+ <source>Block</source>
+ <target>블럭 디바이스</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3c2562ba992127203dcfd014010b03cb7b8113c6" datatype="html">
+ <source>Mirroring</source>
+ <target>미러링</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="811c241d56601b91ef26735b770e64428089b950" datatype="html">
+ <source>iSCSI</source>
+ <target>iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a24eabd99ea5af20f5f94c4484649cd30370042b" datatype="html">
+ <source>NFS</source>
+ <target>NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5276fc60d54d667116babb723641b21281d37271" datatype="html">
+ <source>File Systems</source>
+ <target>파일 시스템</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9515520496da83179d8b08132f00f575512a1f40" datatype="html">
+ <source>Buckets</source>
+ <target>버킷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a23e992f6c6e169a38b2b7338b4e5e803b52e0d" datatype="html">
+ <source>Tasks and Notifications</source>
+ <target>작업 및 알림</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1390461972315002349" datatype="html">
+ <source>The name of the node under which data should be placed.</source>
+ <target>데이터를 배치할 노드의 이름입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6575341202068728510" datatype="html">
+ <source>The type of CRUSH nodes across which we should separate replicas.</source>
+ <target>복제본을 분리해야 하는 CRUSH 노드의 유형입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3874278445824365480" datatype="html">
+ <source>The device class data should be placed on.</source>
+ <target>장치 클래스 데이터를 배치해야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="675628105428950215" datatype="html">
+ <source>Each object is split in data-chunks parts, each stored on a different OSD.</source>
+ <target>각각의 오브젝트들은 데이터-덩어리 부분들로 분리되어, 각기 다른 스토리지 디바이스에 보관됩니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5128168460056151476" datatype="html">
+ <source>Compute coding chunks for each object and store them on different OSDs.
+ The number of coding chunks is also the number of OSDs that can be down without losing data.</source>
+ <target>각 오브젝트들에 대한 코딩 덩어리를 계산하고 서로 다른 스토리지 디바이스에 저장합니다.
+코딩된 덩어리의 수는 데이터 손실없이 작동 중지 될 수 있는 스토리지 디바이스의 숫자이기도합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">18,19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8826111293169381132" datatype="html">
+ <source>The jerasure plugin is the most generic and flexible plugin,
+ it is also the default for Ceph erasure coded pools.</source>
+ <target>Jerasure 플러그인은 가장 일반적이고 유연한 플러그인으로,
+또한 Ceph erasure 코드 데이터 풀의 기본값입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">23,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1331133460856304156" datatype="html">
+ <source>The more flexible technique is reed_sol_van : it is enough to set k
+ and m. The cauchy_good technique can be faster but you need to chose the packetsize
+ carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents
+ in the sense that they can only be configured with m=2.</source>
+ <target>보다 유연한 기술은 reed_sol_van입니다 : k와 m을 설정하면 충분합니다.
+cauchy_good 기술은 빠를 수 있지만 패킷크기를 주의깊게 선택해야합니다.
+reed_sol_r6_op, liberation, blaum_roth, liber8tion은 모두 m = 2로만 구성 할 수 있다는 점에서 RAID-6에 해당합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">25,28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4577912952562931806" datatype="html">
+ <source>The encoding will be done on packets of bytes size at a time.
+ Choosing the right packet size is difficult.
+ The jerasure documentation contains extensive information on this topic.</source>
+ <target>인코딩은 한 번에 바이트 크기의 패킷에 대해 수행됩니다.
+올바른 패킷 크기를 선택하는 것은 어렵습니다.
+삭제 문서에는 이 항목에 대한 자세한 정보가 포함되어 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">29,31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6471646852539810855" datatype="html">
+ <source>With the jerasure plugin, when an erasure coded object is stored on
+ multiple OSDs, recovering from the loss of one OSD requires reading from all the others.
+ For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading
+ from the eleven others to repair.
+
+ The lrc erasure code plugin creates local parity chunks to be able to recover using
+ less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create
+ an additional parity chunk for every four OSDs. When a single OSD is lost, it can be
+ recovered with only four OSDs instead of eleven.</source>
+ <target>jerasure 플러그인을 사용하면 삭제 된 코딩 된 객체가 여러 스토리지 디바이스에 저장 될 때 하나의 스토리지 디바이스가 손실되는 것을 복구하려면 다른 모든 스토리지 디바이스를 읽어야합니다. 예를 들어 jerasure가 k = 8 및 m = 4로 구성되어있는 경우 하나의 스토리지 디바이스를 잃어 버리면 11 명의 다른 사람들이 수리해야합니다.
+lrc erasure code plugin은 적은 양의 스토리지 디바이스를 사용하여 복구 할 수 있도록 로컬 패리티 덩어리를 만듭니다. 예를 들어, lrc가 k = 8, m = 4 및 l = 4로 구성된 경우 4 개의 스토리지 디바이스 마다 추가 패리티 덩어리가 생성됩니다. 단일 스토리지 디바이스가 손실되면 11 개 대신 4 개의 스토리지 디바이스만으로 복구 할 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">34,42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2619235086723330982" datatype="html">
+ <source>Group the coding and data chunks into sets of size locality. For instance,
+ for k=4 and m=2, when locality=3 two groups of three are created. Each set can
+ be recovered without reading chunks from another set.</source>
+ <target>코딩 및 데이터 청크를 크기 지역 집합으로 그룹화합니다. 예를 들어, k = 4 및 m = 2에 대해, 지역성 = 3 일 때 두 개의 세 그룹이 생성됩니다. 각 세트는 다른 세트의 청크를 읽지 않고도 복구 될 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">43,45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3298836762557512588" datatype="html">
+ <source>The type of the crush bucket in which each set of chunks defined
+ by l will be stored. For instance, if it is set to rack, each group of l chunks will be
+ placed in a different rack. It is used to create a CRUSH rule step such as step choose
+ rack. If it is not set, no such grouping is done.</source>
+ <target>l로 정의 된 각 청크 집합이 저장되는 크러시 버킷의 유형입니다. 예를 들어 랙으로 설정하면 l 개의 청크 그룹이 각각 다른 랙에 배치됩니다.
+랙 선택 단계와 같은 CRUSH 규칙 단계를 만드는 데 사용됩니다. 설정되어 있지 않으면, 그러한 그룹화가 수행되지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">46,49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9162461669419243962" datatype="html">
+ <source>The isa plugin encapsulates the ISA library. It only runs on Intel processors.</source>
+ <target>isa 플러그인은 ISA 라이브러리를 캡슐화합니다. 인텔 프로세서에서만 실행됩니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2389282202903059852" datatype="html">
+ <source>The ISA plugin comes in two Reed Solomon forms.
+ If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.</source>
+ <target>ISA 플러그인은 두 개의 리드 솔로몬 형식으로 제공됩니다.
+reed_sol_van이 설정되면 Vandermonde, cauchy가 설정되면 Cauchy입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">53,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7319555444402547739" datatype="html">
+ <source>The shec plugin encapsulates the multiple SHEC library.
+ It allows ceph to recover data more efficiently than Reed Solomon codes.</source>
+ <target>shec plugin은 다중 SHEC 라이브러리를 캡슐화합니다.
+ ceph가 리드 솔로몬 코드보다 더 효율적으로 데이터를 복구 할 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">57,58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7723217930035575928" datatype="html">
+ <source>The number of parity chunks each of which includes each data chunk in its
+ calculation range. The number is used as a durability estimator. For instance, if c=2,
+ 2 OSDs can be down without losing data.</source>
+ <target>각 데이터 덩어리가 계산 범위에 포함되는 패리티 덩어리의 수입니다. 이 수치는 내구성 측정기로 사용됩니다. 예를 들어, c = 2 인 경우 2 개의 스토리지 디바이스가 데이터 손실없이 중단 될 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">59,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2054101840892270818" datatype="html">
+ <source>CLAY (short for coupled-layer) codes are erasure codes designed to
+ bring about significant savings in terms of network bandwidth and disk IO when a failed
+ node/OSD/rack is being repaired.</source>
+ <target>CLY(커플링 레이어) 코드는 다음을 위해 설계된 삭제 코드입니다.
+장애가 발생한 경우 네트워크 대역폭 및 디스크 IO 측면에서 상당한 절감 효과를 가져옵니다.
+노드/스토리지 디바이스/랙을 복구하는 중입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">64,66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491096236680229427" datatype="html">
+ <source>Number of OSDs requested to send data during recovery of a single chunk.
+ d needs to be chosen such that k+1 &lt;= d &lt;= k+m-1. The larger the d, the better
+ the savings.</source>
+ <target>단일 덩어리를 복구하는 동안 데이터를 전송하도록 요청된 스토리지 디바이스 수입니다.
+d는 k+1 = d = k+m-1로 선택해야 합니다. d가 클수록 절감 효과가 좋습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">67,69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2625895656705896729" datatype="html">
+ <source>scalar_mds specifies the plugin that is used as a building block
+ in the layered construction. It can be one of jerasure, isa, shec.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">70,71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6639141182731628232" datatype="html">
+ <source>technique specifies the technique that will be picked
+ within the 'scalar_mds' plugin specified. Supported techniques
+ are 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good', 'liber8tion' for jerasure, 'reed_sol_van',
+ 'cauchy' for isa and 'single', 'multiple' for shec.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">72,76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8172892264673403098" datatype="html">
+ <source>The name of the crush bucket used for the first step of the CRUSH rule.
+ For instance step take default.</source>
+ <target>CRUSH 규칙의 첫 번째 단계에 사용 된 크러시 버킷의 이름입니다. 예를 들어 step은 기본값을 취합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">80,81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1654284403437084515" datatype="html">
+ <source>Ensure that no two chunks are in a bucket with the same failure
+ domain. For instance, if the failure domain is host no two chunks will be stored on the same
+ host. It is used to create a CRUSH rule step such as step chooseleaf host.</source>
+ <target>동일한 실패 도메인을 가진 양동이에 두 개의 청크가 없는지 확인하십시오. 예를 들어 실패 도메인이 호스트 인 경우 두 개의 청크가 동일한 호스트에 저장되지 않습니다. 이 단계는 리프 호스트를 선택하는 단계와 같은 CRUSH 규칙 단계를 만드는 데 사용됩니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">83,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7737703816676512224" datatype="html">
+ <source>Restrict placement to devices of a specific class
+ (e.g., ssd or hdd), using the crush device class names in the CRUSH map.</source>
+ <target>CRUSH지도에서 크래시 장치 클래스 이름을 사용하여 특정 클래스 (예 : ssd 또는 hdd)의 장치로 배치를 제한합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9049698214199657456" datatype="html">
+ <source>Set the directory name from which the erasure code plugin is loaded.</source>
+ <target>Erasure Code 플러그인을 불러오는 디렉토리 이름을 설정하십시오.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5514060020564877279" datatype="html">
+ <source>Allows all operations</source>
+ <target>모든 작업 허용</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4265406815683383218" datatype="html">
+ <source>Allows only operations that do not modify the server</source>
+ <target>서버를 수정하지 않는 작업만 허용합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="990071930378308183" datatype="html">
+ <source>Allows no access at all</source>
+ <target>접근을 허용하지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7286983657616285612" datatype="html">
+ <source>Please specify a filesystem volume.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8321762156640395170" datatype="html">
+ <source>The feature is disabled because Orchestrator is not available.</source>
+ <target>Orchestrator를 사용할 수 없으므로 기능이 비활성화됩니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6718394293315494787" datatype="html">
+ <source>The Orchestrator backend doesn't support this feature.</source>
+ <target>Orchestrator 백엔드는 이 기능을 지원하지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5569418400096331461" datatype="html">
+ <source>-- Select the priority --</source>
+ <target>-- 우선순위를 선택하세요 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="802458941707537739" datatype="html">
+ <source>Low</source>
+ <target>낮음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8063651736083474594" datatype="html">
+ <source>High</source>
+ <target>높음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1717753935149218245" datatype="html">
+ <source>The user list data might be stale. If needed, you can manually reload it.</source>
+ <target>사용자 목록 데이터가 오래되었을 수 있습니다. 필요한 경우 수동으로 다시 불러올 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/list-with-details.class.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7077550143229856452" datatype="html">
+ <source>Retrieving data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8231424898988217966" datatype="html">
+ <source>Retrieving data.</source>
+ <target>데이터를 검색하는 중입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2357645764289315007" datatype="html">
+ <source>Please wait...</source>
+ <target>잠시만 기다려 주세요...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="232824565824302482" datatype="html">
+ <source>Displaying previously cached data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8721257977793603730" datatype="html">
+ <source>Displaying previously cached data.</source>
+ <target>이전에 캐시 된 데이터를 표시합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6731313206654246255" datatype="html">
+ <source>Could not load data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3359748695862553898" datatype="html">
+ <source>Could not load data.</source>
+ <target>데이터를 불러올 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4836577225879717660" datatype="html">
+ <source>Please check the cluster health.</source>
+ <target>클러스터 상태를 확인하세요.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1519954996184640001" datatype="html">
+ <source>Error</source>
+ <target>오류</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5037437391296624618" datatype="html">
+ <source>Information</source>
+ <target>정보</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4648900870671159218" datatype="html">
+ <source>Success</source>
+ <target>성공</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3425367071066107827" datatype="html">
+ <source>Danger</source>
+ <target>위험</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c947210e2d162b6225083d18820ab602f58cd2d" datatype="html">
+ <source>Remove the custom configuration value. The default configuration will be inherited and used instead.</source>
+ <target>사용자 지정 구성 값을 제거합니다. 기본 구성이 사용됩니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="454ee9cb60b00446a8fb147fd2cc5eb836320586" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fc8a22825131e028336f60ef909ccbd96059703" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4dd200b7f9e19048cf90516843b40964f2af3fe9" datatype="html">
+ <source>Copy to Clipboard</source>
+ <target>클립보드에 복사하기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6110699a3562eeb15371063c0cf7f6bfd88a0209" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>?</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="549859e511ba5af0ea03fcaa620c472f08038969" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected items?</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="54839ebc827b73c9dc4e1df731c6d36a85036af7" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/>?</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2be8b7f04f0104d3fad90d079d8202b74f758b9a" datatype="html">
+ <source>Yes, I am sure.</source>
+ <target>예, 확실합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4523728183000855476" datatype="html">
+ <source>documentation</source>
+ <target>문서</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/doc/doc.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3099741642167775297" datatype="html">
+ <source>Download</source>
+ <target>다운로드</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/download-button/download-button.component.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1417693714872528491" datatype="html">
+ <source>This field is required.</source>
+ <target>이 필드는 필수입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5321335688371682440" datatype="html">
+ <source>An error occurred.</source>
+ <target>오류가 발생했습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5109325fb160b543f71a51e7511c00575057431" datatype="html">
+ <source>Loading panel data...</source>
+ <target>패널 데이터 로딩 중...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a21acde005f80ceadb1391be1e7ff8b6d18188a0" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the monitoring functionality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a0ed4bd7b7add2a6febf7adf58d8cde5e421418" datatype="html">
+ <source>Grafana Dashboard doesn't exist. Please refer to <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to add dashboards to Grafana.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e11830040bd64804a0555de76f291d5832772d4" datatype="html">
+ <source>Grafana Time Picker</source>
+ <target>Grafana 시간 선택 도구</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="238c1ba845dd7330e8088165275919a1debf1ca3" datatype="html">
+ <source>Reset Settings</source>
+ <target>설정 초기화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7888499255176013171" datatype="html">
+ <source>Last 5 minutes</source>
+ <target>지난 15분</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6892361549797455305" datatype="html">
+ <source>Last 15 minutes</source>
+ <target>지난 15분</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2653641162607195423" datatype="html">
+ <source>Last 30 minutes</source>
+ <target>지난 30분</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4117793269024790392" datatype="html">
+ <source>Last 1 hour (Default)</source>
+ <target>지난 1시간 (기본)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2645733658763754077" datatype="html">
+ <source>Last 3 hours</source>
+ <target>지난 3시간</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7360078715633936807" datatype="html">
+ <source>Last 6 hours</source>
+ <target>지난 6시간</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5055313582241816303" datatype="html">
+ <source>Last 12 hours</source>
+ <target>지난 12시간</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9186529157286281693" datatype="html">
+ <source>Last 24 hours</source>
+ <target>지난 24시간</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4498682414491138092" datatype="html">
+ <source>Yesterday</source>
+ <target>어제</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="929003859318769922" datatype="html">
+ <source>Today so far</source>
+ <target>오늘 지금까지</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5525943133564968818" datatype="html">
+ <source>Day before yesterday</source>
+ <target>그저께</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6168755117727892817" datatype="html">
+ <source>Last 2 days</source>
+ <target>지난 2일</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7574807704224200535" datatype="html">
+ <source>This day last week</source>
+ <target>이번 주 마지막날</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4420128118950221234" datatype="html">
+ <source>Previous week</source>
+ <target>지난 주</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4063965603321223683" datatype="html">
+ <source>This week so far</source>
+ <target>이번주 지금까지</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4873149362496451858" datatype="html">
+ <source>Last 7 days</source>
+ <target>지난 7일</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8586908745456864217" datatype="html">
+ <source>Previous month</source>
+ <target>지난 달</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1647573304710886499" datatype="html">
+ <source>This month so far</source>
+ <target>이번 달 지금까지</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2949150997160654358" datatype="html">
+ <source>Last 30 days</source>
+ <target>지난 30일</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7469939859049484736" datatype="html">
+ <source>Last 90 days</source>
+ <target>지난 90일</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847501198811458781" datatype="html">
+ <source>Last 6 months</source>
+ <target>지난 6개월</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7447583558445881102" datatype="html">
+ <source>Last 1 year</source>
+ <target>지난 1년</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="100513227838842152" datatype="html">
+ <source>Previous year</source>
+ <target>작년</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3650872673621947074" datatype="html">
+ <source>This year so far</source>
+ <target>이번 년도 지금까지</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1262816694819959075" datatype="html">
+ <source>Last 2 years</source>
+ <target>지난 2년</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7878813844917362690" datatype="html">
+ <source>Last 5 years</source>
+ <target>지난 5년</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3fb5709e10166cbc85970cbff103db227dbeb813" datatype="html">
+ <source>Select a Language</source>
+ <target>언어 선택</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/language-selector/language-selector.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e52e9143145e1db5146258de81eae018a407b31" datatype="html">
+ <source>Clear notifications</source>
+ <target>알림 초기화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0b07bb6b7ff21ede439dd04eaf8872d1ecb84d8" datatype="html">
+ <source>Remove notification</source>
+ <target>알림 제거</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e17a1d75189da843f541f7764f188f2b19a97df2" datatype="html">
+ <source>Duration:</source>
+ <target>기간 :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d4b37c6675c5b436a54c43d6716eec835e1aa7f" datatype="html">
+ <source>There are no notifications.</source>
+ <target>알림이 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b20e42ac4354d449f2718428b5390933eef0c1b9" datatype="html">
+ <source>The feature is not supported in the current Orchestrator.</source>
+ <target>이 기능은 현재 Orchestrator에서 지원되지 않습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a437b8f93cf826817c04a4277edb1ae3a93a1ab" datatype="html">
+ <source>Orchestrator is not available. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the functionality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">7,9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20b3d45b0c08a2951a9974fa20505e4de95250c9" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>less than 1<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day. Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">9,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f34088c155e40ffb23770a465a65868ce772b2" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day(s). Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8d1785038d461ec66b5799db21864182b35900a" datatype="html">
+ <source>Refresh</source>
+ <target>새로고침</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/refresh-selector/refresh-selector.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3417247046175131869" datatype="html">
+ <source>No items selected.</source>
+ <target>선택된 아이템이 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1034353870189672674" datatype="html">
+ <source>Deselect item to select again</source>
+ <target>다시 선택하기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4879298070255432995" datatype="html">
+ <source>Selection limit reached</source>
+ <target>선택 한계에 도달함</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001227209911602786" datatype="html">
+ <source>Filter tags</source>
+ <target>필터 태그</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="791789583719406586" datatype="html">
+ <source>Add badge</source>
+ <target>배지 추가</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="699988676752930063" datatype="html">
+ <source>There are no items available.</source>
+ <target>사용가능한 아이템이 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6702323d3760e3db0e2e785d567469d18beb120" datatype="html">
+ <source>The Ceph community needs your help to continue improving: please <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>Activate<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> the <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Telemetry<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> module.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.html</context>
+ <context context-type="linenumber">8,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8770134622386151776" datatype="html">
+ <source>Telemetry activation reminder muted</source>
+ <target>원격 분석 활성화 알림이 음소거되었습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8352450862052130357" datatype="html">
+ <source>You can activate the module on the Telemetry configuration page (&lt;b&gt;Dashboard Settings&lt;/b&gt; -&gt; &lt;b&gt;Telemetry configuration&lt;/b&gt;) at any time.</source>
+ <target>언제든지 원격 분석 구성 페이지(&lt;b&gt; 대시보드 설정 &lt;/b&gt;-&gt; &lt;b&gt;원격 분석 구성&lt;/b&gt;)에서 모듈을 활성화 할 수 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bc9e5365a581105ce37cf47d1d74e4ad9eb75ce" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e634c306cab9e8879c3392593714c1ceab85437d" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3249513483374643425" datatype="html">
+ <source>Add</source>
+ <target>추가</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4359847060009771702" datatype="html">
+ <source>Set</source>
+ <target>설정</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935187492052582731" datatype="html">
+ <source>Submit</source>
+ <target>제출</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4814285799071780083" datatype="html">
+ <source>Remove</source>
+ <target>제거</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8363450564548681668" datatype="html">
+ <source>Unset</source>
+ <target>설정 해제</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2159130950882492111" datatype="html">
+ <source>Cancel</source>
+ <target>취소</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1295614462098694869" datatype="html">
+ <source>Preview</source>
+ <target>미리보기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2354817630223808522" datatype="html">
+ <source>Move</source>
+ <target>이동</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3885497195825665706" datatype="html">
+ <source>Next</source>
+ <target>다음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8890553633144307762" datatype="html">
+ <source>Back</source>
+ <target>뒤로</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5834780181397311898" datatype="html">
+ <source>Clone</source>
+ <target>복제</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4323470180912194028" datatype="html">
+ <source>Copy</source>
+ <target>복사</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2131301778880826094" datatype="html">
+ <source>Deep Scrub</source>
+ <target>데이터 정리</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1704447209800801558" datatype="html">
+ <source>Destroy</source>
+ <target>파기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8343007008325027187" datatype="html">
+ <source>Evict</source>
+ <target>퇴출</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="408179081163888126" datatype="html">
+ <source>Flatten</source>
+ <target>평평함</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="318900679147387932" datatype="html">
+ <source>Mark Down</source>
+ <target>다운 표시</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5275142643521766706" datatype="html">
+ <source>Mark In</source>
+ <target>인 표시</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6973272903386150199" datatype="html">
+ <source>Mark Lost</source>
+ <target>손실 표시</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1962653792210847411" datatype="html">
+ <source>Mark Out</source>
+ <target>아웃 표시</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4424610588915076517" datatype="html">
+ <source>Protect</source>
+ <target>보호</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6041115344061899387" datatype="html">
+ <source>Rename</source>
+ <target>이름변경</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">164</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6770769801335635194" datatype="html">
+ <source>Restore</source>
+ <target>복구</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2003230525878010676" datatype="html">
+ <source>Reweight</source>
+ <target>가중치 조정</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5430834128563178593" datatype="html">
+ <source>Scrub</source>
+ <target>빠른 데이터 정리</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8461842260159597706" datatype="html">
+ <source>Show</source>
+ <target>보기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5655608100705734230" datatype="html">
+ <source>Move to Trash</source>
+ <target>휴지통으로 옮기기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4622393909937403117" datatype="html">
+ <source>Unprotect</source>
+ <target>보호되지 않음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1230154438678955604" datatype="html">
+ <source>Change</source>
+ <target>변경</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8450843381175865415" datatype="html">
+ <source>Enter Maintenance</source>
+ <target>유지보수 모드 설정</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1610181371597502589" datatype="html">
+ <source>Exit Maintenance</source>
+ <target>유지보수 모드 해제</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="676511611419004737" datatype="html">
+ <source>Start Drain</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7170653322511987983" datatype="html">
+ <source>Stop Drain</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5528551262937858942" datatype="html">
+ <source>Recreate</source>
+ <target>재생성</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2502364444688691031" datatype="html">
+ <source>Expire</source>
+ <target>만료</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6381490568322624964" datatype="html">
+ <source>Deleted</source>
+ <target>삭제됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="231679111972850796" datatype="html">
+ <source>Added</source>
+ <target>추가됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5406093358072761930" datatype="html">
+ <source>Removed</source>
+ <target>제거됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3008573030448240863" datatype="html">
+ <source>Edited</source>
+ <target>수정됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4381944803872489731" datatype="html">
+ <source>Canceled</source>
+ <target>취소됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754993936947658096" datatype="html">
+ <source>Previewed</source>
+ <target>미리보기됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6001163963116907226" datatype="html">
+ <source>Moved</source>
+ <target>옮겨짐</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4932744777596632840" datatype="html">
+ <source>Cloned</source>
+ <target>복제됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2115592966120408375" datatype="html">
+ <source>Copied</source>
+ <target>복사됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7937474560394832586" datatype="html">
+ <source>Deep Scrubbed</source>
+ <target>데이터 정리 완료</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6321562733889197649" datatype="html">
+ <source>Destroyed</source>
+ <target>파기됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7460162290177581995" datatype="html">
+ <source>Flattened</source>
+ <target>평평하게 됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3662010055028969035" datatype="html">
+ <source>Marked Down</source>
+ <target>다운 표시됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5880434235404894589" datatype="html">
+ <source>Marked In</source>
+ <target>인 표시됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="266997194072682078" datatype="html">
+ <source>Marked Lost</source>
+ <target>손실 표시됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">250</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4010544044592534535" datatype="html">
+ <source>Marked Out</source>
+ <target>아웃 표시됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4776304093333411035" datatype="html">
+ <source>Protected</source>
+ <target>보호됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2700903921419382511" datatype="html">
+ <source>Purged</source>
+ <target>완전 삭제됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5488667333459350160" datatype="html">
+ <source>Renamed</source>
+ <target>이름 변경됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8044659850000829751" datatype="html">
+ <source>Restored</source>
+ <target>복구됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559472082694466366" datatype="html">
+ <source>Reweighted</source>
+ <target>가중치가 조정됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022271525067453676" datatype="html">
+ <source>Rolled back</source>
+ <target>롤백됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2483217756816388123" datatype="html">
+ <source>Scrubbed</source>
+ <target>빠른 데이터 정리 완료</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7200036055090632378" datatype="html">
+ <source>Showed</source>
+ <target>보기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7609648817347881129" datatype="html">
+ <source>Moved to Trash</source>
+ <target>휴지통으로 옮겨짐</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7810326403606456469" datatype="html">
+ <source>Unprotected</source>
+ <target>보호되지 않음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5620774899056099259" datatype="html">
+ <source>Recreated</source>
+ <target>재생성됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464749780222721589" datatype="html">
+ <source>Expired</source>
+ <target>만료됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">266</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e5e23363e949f7dcbaf034bdb141a561132a10e" datatype="html">
+ <source>Clear filters</source>
+ <target>필터 초기화</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80cc9a12d4bf6fe454ed94b379eeaf915f920bb7" datatype="html">
+ <source>selected</source>
+ <target>선택됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <note priority="1" from="description">X selected</note>
+ </trans-unit>
+ <trans-unit id="0cb77511a9a148e05b9adf36cc07269956fbb29d" datatype="html">
+ <source>found</source>
+ <target>발견됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <note priority="1" from="description">X found</note>
+ </trans-unit>
+ <trans-unit id="79347388740c50b7ac97e144c2494bb62912f312" datatype="html">
+ <source>total</source>
+ <target>전체</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <note priority="1" from="description">X total</note>
+ </trans-unit>
+ <trans-unit id="2a3dab422cc892db037db8632bb84a6bf496e2d1" datatype="html">
+ <source>Expand/Collapse Row</source>
+ <target>행 확장/축소</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4047162422391207122" datatype="html">
+ <source>Failed to load data.</source>
+ <target>데이터 로딩 실패</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.ts</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="709331713250198508" datatype="html">
+ <source>Loading form data...</source>
+ <target>데이터 양식을 불러오고 있습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3850344644863430180" datatype="html">
+ <source>Form data could not be loaded.</source>
+ <target>데이터 양식을 불러올 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4626760504772708998" datatype="html">
+ <source>Size has to be at least <x id="PH" equiv-text="value"/> or more</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">428</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2880361802894657892" datatype="html">
+ <source>Size has to be at most <x id="PH" equiv-text="value"/> or less</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2807800733729323332" datatype="html">
+ <source>Yes</source>
+ <target>예</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3542042671420335679" datatype="html">
+ <source>No</source>
+ <target>아니오</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7789266940050748913" datatype="html">
+ <source>in %s</source>
+ <target>%s 안에</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565573880632900017" datatype="html">
+ <source>%s ago</source>
+ <target>%s 전에</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="220300059326988179" datatype="html">
+ <source>a few seconds</source>
+ <target>몇 초</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2761143993878941513" datatype="html">
+ <source>%d seconds</source>
+ <target>%d 초</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7094767962693903153" datatype="html">
+ <source>a minute</source>
+ <target>1분</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7597613755904774250" datatype="html">
+ <source>%d minutes</source>
+ <target>%d 분</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2757762976030115752" datatype="html">
+ <source>an hour</source>
+ <target>1시간</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9118454901758656303" datatype="html">
+ <source>%d hours</source>
+ <target>%d 시간</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7435193742089920080" datatype="html">
+ <source>a day</source>
+ <target>하루</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1821334622562842480" datatype="html">
+ <source>%d days</source>
+ <target>%d 일</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7375306199026780379" datatype="html">
+ <source>a week</source>
+ <target>1주</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7272688256541915488" datatype="html">
+ <source>%d weeks</source>
+ <target>%d 주</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5761124614324704118" datatype="html">
+ <source>a month</source>
+ <target>한달</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="352195662913351589" datatype="html">
+ <source>%d months</source>
+ <target>%d 달</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7562153591649199139" datatype="html">
+ <source>a year</source>
+ <target>1년</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5424759741855527370" datatype="html">
+ <source>%d years</source>
+ <target>%d 년</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7738182956549158907" datatype="html">
+ <source>Required rules for passwords:</source>
+ <target>비밀번호에 필요한 규칙은 다음과 같습니다 :</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8839765875053270528" datatype="html">
+ <source>Must contain at least <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> characters</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3098731108593590794" datatype="html">
+ <source>Must not be the same as the previous one</source>
+ <target>기존과 동일하지 않아야 합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9150236741862848105" datatype="html">
+ <source>Cannot contain the username</source>
+ <target>사용자 이름을 포함할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6395043854518867543" datatype="html">
+ <source>Cannot contain any configured keyword</source>
+ <target>구성된 키워드를 포함할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="907558624910601703" datatype="html">
+ <source>Cannot contain any repetitive characters e.g. &quot;aaa&quot;</source>
+ <target>반복 문자를 포함할 수 없습니다 (예: aaa).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514384270734082343" datatype="html">
+ <source>Cannot contain any sequential characters e.g. &quot;abc&quot;</source>
+ <target>연속 문자를 포함할 수 없습니다 (예: abc).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4119354814383293871" datatype="html">
+ <source>Must consist of characters from the following groups:
+ * Alphabetic a-z, A-Z
+ * Numbers 0-9
+ * Special chars: !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * Any other characters (signs)</source>
+ <target>다음 그룹의 문자로 구성되어야 합니다.
+* 알파벳 a-z, A-Z입니다.
+* 0-9번입니다.
+* 특수 문자: !&quot;#$%&amp;'()*+,-./;=?@[\]^_`{{|}}~
+* 기타 문자(부호)입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">30,34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8649061117624699581" datatype="html">
+ <source>Your matcher seems to match no currently defined rule or active alert.</source>
+ <target>항목이 현재 정의된 규칙이나 활성화 된 경고와 일치하지 않는 것 같습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7122912874364762704" datatype="html">
+ <source>no active alerts</source>
+ <target>활성화 된 경고 없음</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7388215679576832341" datatype="html">
+ <source>1 active alert</source>
+ <target>1개의 경고가 활성화 됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3112400568960537267" datatype="html">
+ <source><x id="PH" equiv-text="alerts"/> active alerts</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6264717417287230743" datatype="html">
+ <source>Matches 1 rule</source>
+ <target>1개의 규칙이 일치합니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054663176394183966" datatype="html">
+ <source>Matches <x id="PH" equiv-text="rules"/> rules</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6674225401121099210" datatype="html">
+ <source><x id="PH" equiv-text="rule"/> with <x id="PH_1" equiv-text="alert"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5659908877047925719" datatype="html">
+ <source>Quality of Service</source>
+ <target>서비스 양</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1277565045885499475" datatype="html">
+ <source>BPS Limit</source>
+ <target>BPS 제한</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2289210323987692906" datatype="html">
+ <source>The desired limit of IO bytes per second.</source>
+ <target>원하는 초당 IO 바이트 수 제한입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753589939879013605" datatype="html">
+ <source>IOPS Limit</source>
+ <target>IOPS 제한</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2213985059444278522" datatype="html">
+ <source>The desired limit of IO operations per second.</source>
+ <target>원하는 초당 IO 작업 제한입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2487530611825582289" datatype="html">
+ <source>Read BPS Limit</source>
+ <target>읽기 BPS 제한</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8071352270469595250" datatype="html">
+ <source>The desired limit of read bytes per second.</source>
+ <target>원하는 초당 읽기 바이스 수 제한입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1632513758247239690" datatype="html">
+ <source>Read IOPS Limit</source>
+ <target>읽기 IOPS 제한</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2361786794607418566" datatype="html">
+ <source>The desired limit of read operations per second.</source>
+ <target>원하는 초당 읽기 작업 제한입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="894600353504285551" datatype="html">
+ <source>Write BPS Limit</source>
+ <target>쓰기 BPS 제한</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911437671369366025" datatype="html">
+ <source>The desired limit of write bytes per second.</source>
+ <target>원하는 초당 쓰기 바이트 수 제한입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2947346368707443195" datatype="html">
+ <source>Write IOPS Limit</source>
+ <target>쓰기 IOPS 제한</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5506349527983391356" datatype="html">
+ <source>The desired limit of write operations per second.</source>
+ <target>원하는 초당 쓰기 작업 제한입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559424229658244943" datatype="html">
+ <source>BPS Burst</source>
+ <target>BPS 버스트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3454058701331860330" datatype="html">
+ <source>The desired burst limit of IO bytes.</source>
+ <target>원하는 버스트 IO 바이트 한도 입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171005761926448741" datatype="html">
+ <source>IOPS Burst</source>
+ <target>IOPS 버스트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4939532784700485729" datatype="html">
+ <source>The desired burst limit of IO operations.</source>
+ <target>원하는 IO 작업의 버스트 제한입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6273492199526646930" datatype="html">
+ <source>Read BPS Burst</source>
+ <target>읽기 BPS 버스트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3105467595643777520" datatype="html">
+ <source>The desired burst limit of read bytes.</source>
+ <target>원하는 읽기 버스트 제한입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2170715106679765467" datatype="html">
+ <source>Read IOPS Burst</source>
+ <target>읽기 IOPS 버스트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6234106755510510672" datatype="html">
+ <source>The desired burst limit of read operations.</source>
+ <target>원하는 읽기 작업의 버스트 제한입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="228509518172572466" datatype="html">
+ <source>Write BPS Burst</source>
+ <target>쓰기 BPS 버스트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7803279807796571240" datatype="html">
+ <source>The desired burst limit of write bytes.</source>
+ <target>쓰기 바이트의 원하는 버스트 제한입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9125474584914848055" datatype="html">
+ <source>Write IOPS Burst</source>
+ <target>쓰기 IOPS 버스트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5839129348567326667" datatype="html">
+ <source>The desired burst limit of write operations.</source>
+ <target>쓰기 바이트의 원하는 버스트 제한입니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="614961883076556986" datatype="html">
+ <source>Failed to <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="489145301781720653" datatype="html">
+ <source>Executing</source>
+ <target>실행중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4238828029954346941" datatype="html">
+ <source>execute</source>
+ <target>실행</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7196604637389554584" datatype="html">
+ <source>Executed</source>
+ <target>실행됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4418441687454700644" datatype="html">
+ <source>unknown task</source>
+ <target>알려지지 않는 작업</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8667665916832796867" datatype="html">
+ <source>Creating</source>
+ <target>생성하는 중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6031236679730054907" datatype="html">
+ <source>create</source>
+ <target>생성</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5593033420216313122" datatype="html">
+ <source>Updating</source>
+ <target>업데이트 중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6100869651653026893" datatype="html">
+ <source>update</source>
+ <target>업데이트</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3141301060598402455" datatype="html">
+ <source>Deleting</source>
+ <target>삭제 중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3420504288275541125" datatype="html">
+ <source>Adding</source>
+ <target>추가 중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1059784693423848532" datatype="html">
+ <source>add</source>
+ <target>추가</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594819887188505274" datatype="html">
+ <source>Removing</source>
+ <target>제거 중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2123171795960509943" datatype="html">
+ <source>remove</source>
+ <target>제거</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1946427188770321847" datatype="html">
+ <source>Importing</source>
+ <target>가져오는 중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8495827411619139669" datatype="html">
+ <source>import</source>
+ <target>가져오기</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218459863491436562" datatype="html">
+ <source>Imported</source>
+ <target>가져옴</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6534993668932538712" datatype="html">
+ <source>RBD '<x id="PH" equiv-text="metadata.image_spec"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8237287859948228705" datatype="html">
+ <source>RBD snapshot '<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2328067975897167268" datatype="html">
+ <source>mirroring site name</source>
+ <target>미러링 사이트 이름</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4433460322631470833" datatype="html">
+ <source>bootstrap token</source>
+ <target>부트스트랩 토큰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7044591639782280183" datatype="html">
+ <source>mirror mode for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7109746474198366468" datatype="html">
+ <source>mirror peer for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6201476020617351396" datatype="html">
+ <source>all dashboards</source>
+ <target>모든 대시보드</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7268953097700363232" datatype="html">
+ <source>Identifying</source>
+ <target>식별하는중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4337678035264231187" datatype="html">
+ <source>identify</source>
+ <target>식별</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7257219307556106552" datatype="html">
+ <source>Identified</source>
+ <target>식별됨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6002370161381995023" datatype="html">
+ <source>device '<x id="PH" equiv-text="metadata.device"/>' on host '<x id="PH_1" equiv-text="metadata.hostname"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5580298273054260850" datatype="html">
+ <source>OSDs (DriveGroups: <x id="PH" equiv-text="metadata.tracking_id"/>)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2182125722527364040" datatype="html">
+ <source>Name is already used by <x id="PH" equiv-text="this.pool(metadata)"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">182</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7892856315477304281" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> is busy.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4690045751984117407" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> contains snapshots.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="562148565853868662" datatype="html">
+ <source>Cloning</source>
+ <target>복제중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1197352830433807469" datatype="html">
+ <source>clone</source>
+ <target>복제</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1692004144561317867" datatype="html">
+ <source>Snapshot of <x id="PH" equiv-text="this.rbd.child(metadata)"/> must be protected.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8531200838331320284" datatype="html">
+ <source>Copying</source>
+ <target>복사중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6862265996781523030" datatype="html">
+ <source>copy</source>
+ <target>복사</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3556912098733712857" datatype="html">
+ <source>Flattening</source>
+ <target>평평하게 하는 중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2488773646187451754" datatype="html">
+ <source>flatten</source>
+ <target>평평함</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="704305783678486635" datatype="html">
+ <source>Cannot unprotect <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> because it contains child images.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">223,225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101271773452792348" datatype="html">
+ <source>Cannot delete <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/> because it's protected.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5143010940199748580" datatype="html">
+ <source>Rolling back</source>
+ <target>롤백 중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1315686250907089544" datatype="html">
+ <source>rollback</source>
+ <target>롤백</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5010267418211867946" datatype="html">
+ <source>Moving</source>
+ <target>이동 중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4366763205960752449" datatype="html">
+ <source>move</source>
+ <target>이동</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="695867152524584829" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_spec"/>' to trash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423442774536615202" datatype="html">
+ <source>Could not find image.</source>
+ <target>이미지를 찾을 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2622324641113512527" datatype="html">
+ <source>Restoring</source>
+ <target>복구중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3347932678307141902" datatype="html">
+ <source>restore</source>
+ <target>복구</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7488038030362249932" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>' into '<x id="PH_1" equiv-text="metadata.new_image_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565688512490959949" datatype="html">
+ <source>Image name '<x id="PH" equiv-text="metadata.new_image_name"/>' is already in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6331051389974655106" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8245559899946787147" datatype="html">
+ <source>Purging</source>
+ <target>완전히 삭제 하는중</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7879437654311684252" datatype="html">
+ <source>purge</source>
+ <target>완전히 삭제</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1440427157062670480" datatype="html">
+ <source>all pools</source>
+ <target>모든 데이터 풀</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8677740163708263843" datatype="html">
+ <source>images from <x id="PH" equiv-text="message"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011237345035114219" datatype="html">
+ <source>Cannot disable mirroring because it contains a peer.</source>
+ <target>피어가 포함되어 있기 때문에 미러링을 비활성화 할 수 없습니다.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">292</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7391584598242145869" datatype="html">
+ <source>host '<x id="PH" equiv-text="metadata.hostname"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6964302691596180722" datatype="html">
+ <source>OSD '<x id="PH" equiv-text="metadata.svc_id"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="488305686602466689" datatype="html">
+ <source>pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5921392748828575278" datatype="html">
+ <source>erasure code profile '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2423915105798557698" datatype="html">
+ <source>crush rule '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">370</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8273044996643438592" datatype="html">
+ <source>target '<x id="PH" equiv-text="metadata.target_iqn"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5474643443735437364" datatype="html">
+ <source>NFS '<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">378,380</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2235495382025026939" datatype="html">
+ <source>Service '<x id="PH" equiv-text="metadata.service_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ </body>
+ </file>
+</xliff> \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.pl-PL.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.pl-PL.xlf
new file mode 100644
index 000000000..ef890df78
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.pl-PL.xlf
@@ -0,0 +1,14066 @@
+<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en-US" datatype="plaintext" original="ng2.template" target-language="pl-PL">
+ <body>
+ <trans-unit id="ngb.alert.close" datatype="html">
+ <source>Close</source>
+ <target>Zamknij</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/alert/alert.ts</context>
+ <context context-type="linenumber">58,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.slide-number" datatype="html">
+ <source> Slide <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> of <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">114,118</context>
+ </context-group>
+ <note priority="1" from="description">Currently selected slide number read by screen reader</note>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.previous" datatype="html">
+ <source>Previous</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">132,134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.next" datatype="html">
+ <source>Next</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">147,152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-month" datatype="html">
+ <source>Select month</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">44,49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">49,50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-year" datatype="html">
+ <source>Select year</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">59,63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.previous-month" datatype="html">
+ <source>Previous month</source>
+ <target>Poprzedniego miesiąca</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">24,27</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">35,36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.next-month" datatype="html">
+ <source>Next month</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">47,50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">60,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first" datatype="html">
+ <source>««</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">182,183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous" datatype="html">
+ <source>«</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">186,190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next" datatype="html">
+ <source>»</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">194,195</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last" datatype="html">
+ <source>»»</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">201,204</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first-aria" datatype="html">
+ <source>First</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">208,209</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous-aria" datatype="html">
+ <source>Previous</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">215,216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next-aria" datatype="html">
+ <source>Next</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">226,228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last-aria" datatype="html">
+ <source>Last</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.progressbar.value" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="; } /** *"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/progressbar/progressbar.ts</context>
+ <context context-type="linenumber">32,38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.HH" datatype="html">
+ <source>HH</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">40,41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.hours" datatype="html">
+ <source>Hours</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.MM" datatype="html">
+ <source>MM</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">51,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.minutes" datatype="html">
+ <source>Minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-hours" datatype="html">
+ <source>Increment hours</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">63,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-hours" datatype="html">
+ <source>Decrement hours</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">69,70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-minutes" datatype="html">
+ <source>Increment minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">76,78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-minutes" datatype="html">
+ <source>Decrement minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">82,84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.SS" datatype="html">
+ <source>SS</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.seconds" datatype="html">
+ <source>Seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">92,93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-seconds" datatype="html">
+ <source>Increment seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">100,101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-seconds" datatype="html">
+ <source>Decrement seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">106,110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.AM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">115,121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.PM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="t() meridian: b"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">123,131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.toast.close-aria" datatype="html">
+ <source>Close</source>
+ <target>Zamknij</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/toast/toast.ts</context>
+ <context context-type="linenumber">78,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8835b9e49a3348b0a2f2162c21118af1f4bee45a" datatype="html">
+ <source>Must be greater than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbddac59563c8c126e3fe28691e4e247614fcbd1" datatype="html">
+ <source>Must be less than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5" datatype="html">
+ <source>Overview</source>
+ <target>Przegląd</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbd2045d5c37e4bb39a3c0fb62ea1ddf70a12838" datatype="html">
+ <source>Targets</source>
+ <target>Obiekty docelowe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a674ab267d1934bf395f87ca1503fd474296893f" datatype="html">
+ <source>iSCSI Topology</source>
+ <target>Topologia iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8953033926734869941" datatype="html">
+ <source>Name</source>
+ <target>Nazwa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6603000223840533819" datatype="html">
+ <source>Current</source>
+ <target>Obecny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5607669932062416162" datatype="html">
+ <source>Default</source>
+ <target>Domyślna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6803e31b7395d94934e091a49a9524026b59b018" datatype="html">
+ <source>Discovery Authentication</source>
+ <target>Uwierzytelnianie wykrywania</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e08a77594f3d89311cdf6da5090044270909c194" datatype="html">
+ <source>User</source>
+ <target>Użytkownik</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">381</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7cbdabcece469fab89cfa687ab152bca18b97498" datatype="html">
+ <source>This field is required.</source>
+ <target>Pole jest wymagane.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">368</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">423</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">481</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">291</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">343</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">407</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">490</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">516</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">556</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">573</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">590</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">647</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">672</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">299</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">195</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">520</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">614</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">651</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f717bad2da5944a2567a52f971ccc6806db85805" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">28,29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">85,86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c32ef07f8803a223a83ed17024b38e8d82292407" datatype="html">
+ <source>Password</source>
+ <target>Hasło</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">403</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">581</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="001e1836299d8d3b84eaebe2fa051325beab3f00" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">61,62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">118,119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff40391de7a1944ea95091e4045cc34c4979b736" datatype="html">
+ <source>Mutual User</source>
+ <target>Wspólny użytkownik </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cf73dbebe99b737c4d288788182fc356e3c93d3" datatype="html">
+ <source>Mutual Password</source>
+ <target>Wspólne hasło</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594987303599690088" datatype="html">
+ <source>Updated discovery authentication</source>
+ <target>Zaktualizowane uwierzytelnianie wykrywania</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb127ea03835b3230f0ed981c7080e2ccb879621" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <note priority="1" from="description">form title</note>
+ </trans-unit>
+ <trans-unit id="1406c2fb12a20c1528b19bcc5e24a6a2386167f3" datatype="html">
+ <source>Target IQN</source>
+ <target>Nazwa IQN obiektu docelowego iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5fe42339be910372fa689f559155631862d218e8" datatype="html">
+ <source>IQN has wrong pattern.</source>
+ <target>Błędna składnia nazwy IQN.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="050a7ff057d1e895357540406b6be5652b4d1c71" datatype="html">
+ <source>An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'</source>
+ <target>IQN ma następującą notację „iqn. $ Rok-$ miesiąc. $ odwróconyAdres: $ zdefiniowanaNazwa”</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8ada4b53396d8366db00a435acc61d53d857047" datatype="html">
+ <source>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</source>
+ <target>Na przykład: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e" datatype="html">
+ <source>More information</source>
+ <target>Więcej informacji</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9b1aa85dfc6849196e64060db02c5410de69b7a1" datatype="html">
+ <source>This target has modified advanced settings.</source>
+ <target>Ten obiekt docelowy zmodyfikował zaawansowane ustawienia.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6990ad8d6182662e864495ac31c3758cda1c7a28" datatype="html">
+ <source>Portals</source>
+ <target>Portale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a3ac2b4137d723fd9878cd357c2012ff6c07973" datatype="html">
+ <source>Add portal</source>
+ <target>Dodaj portal</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3638c01b6c34066438909713ec96087c813fc7e" datatype="html">
+ <source>At least <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> gateways are required.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b73f7f5060fb22a1e9ec462b1bb02493fa3ab866" datatype="html">
+ <source>Images</source>
+ <target>Obrazy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">495</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">629</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9aff25be088f0efe3eaaf62edf2bff41cc41a617" datatype="html">
+ <source>Backstore: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e3484cae8b118c576ca2815bf9c9406c2eb2cae3" datatype="html">
+ <source>This image has modified settings.</source>
+ <target>Ten obraz zmodyfikował ustawienia. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1dff11e0820b6722ab240169f1232d70a54beaaa" datatype="html">
+ <source>Duplicated LUN numbers.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bf2dccf92ccff6e3b091792bf4205595406e1bfb" datatype="html">
+ <source>Duplicated WWN.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="808038f912fdc7f0e03f82d4afd3bf9178527fc8" datatype="html">
+ <source>Add image</source>
+ <target>Dodaj obraz.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">656</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66c5fb27f52e75b70ca4b670b9b15a2a51cf9543" datatype="html">
+ <source>ACL authentication</source>
+ <target>Uwierzytelnianie ACL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="137fbf154ecad4d580354db0858b76faea7e4686" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">227,228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">287,288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="361771c32dd2254d77fd3fbf006b008983fe5907" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">262,263</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">323,324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f494bd31f095f6dcc656ce87ec2dcf07a2e9b30c" datatype="html">
+ <source>Initiators</source>
+ <target>Inicjatory iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">335</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">588</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e98239d8a6be1100119ff4b5630c822b82786740" datatype="html">
+ <source>Initiator</source>
+ <target>Inicjator iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2c5059d8cda15d8d03e2cce30f2d139623d9a91" datatype="html">
+ <source>Client IQN</source>
+ <target>Klient IQN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="107d5aabce23d900f0a80e6ddc1c10e29aa0bed8" datatype="html">
+ <source>Initiator IQN needs to be unique.</source>
+ <target>Inicjator IQN powinien być unikalny.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e7cad911fa524e512d9744b16358b7ee6791385" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">394,395</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">452,453</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7f2c186d181206d0d2b1ff74819081a010f10bf" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">427,428</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">485,486</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d1878d5fc761cbe9614bfd87047a740c82a6951" datatype="html">
+ <source>Initiator belongs to a group. Images will be configure in the group.</source>
+ <target>Inicjator iSCSI należą do grupy. Obrazy będą skonfigurowane w grupie. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">515</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0de67b9d97fafbf200f9451e8388ee8128a56ac" datatype="html">
+ <source>No items added.</source>
+ <target>Brak dodanych pozycji.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">671</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d565e47726158e428ecdc952fc9233b9b7d7f049" datatype="html">
+ <source>Add initiator</source>
+ <target>Dodaj inicjator iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">616</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c22ba03540aa3217da059f45e7eab138b51a96e2" datatype="html">
+ <source>Groups</source>
+ <target>Grupy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c90059afafb7e160384d9f512797c95bb95c6dc" datatype="html">
+ <source>Group</source>
+ <target>Grupa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cff1428d10d59d14e45edec3c735a27b5482db59" datatype="html">
+ <source>Name</source>
+ <target>Nazwa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">576</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3084948274cff4f56d0f431af47240e9cf02fcc7" datatype="html">
+ <source>Add group</source>
+ <target>Dodaj grupę</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">676</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6634268061646442252" datatype="html">
+ <source>There are no portals available.</source>
+ <target>Brak dostępnych portali.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4587015892789840153" datatype="html">
+ <source>There are no images available.</source>
+ <target>Nie ma dostępnych obrazów. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7896905042057267575" datatype="html">
+ <source>There are no images available. Please make sure you add an image to the target.</source>
+ <target>Nie ma dostępnych obrazów. Proszę się upewnić, że dodajesz obraz do obiektu docelowego. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6765423558085969805" datatype="html">
+ <source>There are no initiators available. Please make sure you add an initiator to the target.</source>
+ <target>Nie ma dostępnych inicjatorów iSCSI. Proszę upewnić się, że dodajesz inicjator iSCSI do obiektu docelowego.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2539932200265667453" datatype="html">
+ <source>target</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="051dcc342cfa5c1eaf187a2001aaa162379a160c" datatype="html">
+ <source>Configure</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e515f954730279c31d5301f02479666d6264e8b" datatype="html">
+ <source>Changing these parameters from their default values is usually not necessary.</source>
+ <target>Zmiana tych parametrów z domyślnych wartości przeważnie nie jest potrzebna.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e2591df099ddac796cda401c5f282da779d45f2" datatype="html">
+ <source>Identifier</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62480a4859976427cf18fc8ef41d3a438eda0412" datatype="html">
+ <source>lun</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8afc9eb4405e0aa554b2ba14140ef790cdecc040" datatype="html">
+ <source>wwn</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
+ <source>Settings</source>
+ <target>Ustawienia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69a47cbabcc51ca942606e1d8da0ec11f98a2690" datatype="html">
+ <source>Backstore</source>
+ <target>Tylny koniec przechowywania</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="339878da255ab55447c43afef8d9b2f9753bf5f6" datatype="html">
+ <source>Advanced Settings</source>
+ <target>Ustawienia zaawansowane</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="332227f088a4877b3c11f5fb3ae8bc812c470fae" datatype="html">
+ <source>iSCSI Targets not available</source>
+ <target>obiekty docelowe iSCSI niedostępne </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7fba666f1fff0182e570f12133fb3d622d9ea6" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the iSCSI Targets management functionality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3b301d0044f62c92af0da53d7aaca52a436a547d" datatype="html">
+ <source>Available information:</source>
+ <target>Dostępne informacje: </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8414a5cb9d71cc1b21b10e4a9d1f2dad558f3361" datatype="html">
+ <source>Discovery authentication</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4854396465510517671" datatype="html">
+ <source>Target</source>
+ <target>obiekt docelowy iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4093869278527257288" datatype="html">
+ <source>Portals</source>
+ <target>Portale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="414887388288176527" datatype="html">
+ <source>Images</source>
+ <target>Obrazy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="798573158169239055" datatype="html">
+ <source># Sessions</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="646929398175374220" datatype="html">
+ <source>Unavailable gateway(s)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2350612272163013640" datatype="html">
+ <source>Target has active sessions</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4782410538666829801" datatype="html">
+ <source>iSCSI target</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">227</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8a9910cd114c1deb9af74f6f99b4173403965bf2" datatype="html">
+ <source>Gateways</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911214550882917183" datatype="html">
+ <source>State</source>
+ <target>Stan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4121862424558610140" datatype="html">
+ <source># Targets</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101197021456818771" datatype="html">
+ <source>Pool</source>
+ <target>Pul</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3012906865384504293" datatype="html">
+ <source>Image</source>
+ <target>Obraz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2699995524827665158" datatype="html">
+ <source>Backstore</source>
+ <target>Tylny koniec przechowywania</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3559214740809905405" datatype="html">
+ <source>Read Bytes</source>
+ <target>Odczyt bajtów </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1580583760095064067" datatype="html">
+ <source>Write Bytes</source>
+ <target>Zapis bajtów</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7225917547116479918" datatype="html">
+ <source>Read Ops</source>
+ <target>Odczyt Ops</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6417507714454914481" datatype="html">
+ <source>Write Ops</source>
+ <target>Zapis Ops</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="257147267065394003" datatype="html">
+ <source>A/O Since</source>
+ <target>A/O Od</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ecbc084370a732fc3cde1966a60af78d71424ab4" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603e9cc3ef2aab57f2b0a00e465b23b9cabefd9c" datatype="html">
+ <source>To create a bootstrap token which can be imported by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Generate<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="660f97cd3188f8a04bd03b79e703fec72c6df04c" datatype="html">
+ <source>Site Name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2fecea01ce1d44114ee45144eff6d47a5016a74f" datatype="html">
+ <source>Name...</source>
+ <target>Nazwa...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92899fa68e8ca108912163ff58edc8540e453787" datatype="html">
+ <source>Pools</source>
+ <target>Pule</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c2a1dc72cffaf7ab3dc5599bf77b0a7fcad2b20" datatype="html">
+ <source>At least one pool is required.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b258b258b4cc475ceb2871305b61756b0134f4a" datatype="html">
+ <source>Generate</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1edc1fc6cfbbb22353050ad6788508b3ed584f53" datatype="html">
+ <source>Token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff785f5596aef34a93b9b4d1023e95c62eef5740" datatype="html">
+ <source>Generated token...</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8" datatype="html">
+ <source>Close</source>
+ <target>Zamknij</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5467a6bb0e7fade6def7499400d5e2a7d8d3da20" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bb7aee0dec5164f45c0aa2f35f2fb2149d2c1d2" datatype="html">
+ <source>To import a bootstrap token which was created by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, provide the generated token, and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Import<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9200e09686136a1d42adfb89c12fbfef2deea125" datatype="html">
+ <source>Direction</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9761484679958da8d12841a4efa5964d33fae575" datatype="html">
+ <source>The token is invalid.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2381859602529023966" datatype="html">
+ <source>Instance</source>
+ <target>Instancja</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8040881171107393560" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1605455101862010019" datatype="html">
+ <source>Hostname</source>
+ <target>Nazwa hosta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2724055831234181057" datatype="html">
+ <source>Version</source>
+ <target>Wersja</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2041675390931385838" datatype="html">
+ <source>Health</source>
+ <target>Zdrowie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87bd96249f8afc23f5301cddb57b1464a98e71a" datatype="html">
+ <source>Edit site name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cfff72c667274c12eb1ff71eadc25871c10c42dc" datatype="html">
+ <source>Edit the site name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">13,14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66db799d67958d4b0765181d072df62e2d1c16f5" datatype="html">
+ <source>Issues</source>
+ <target>Zagadnienia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef06d69259e587e28d52372455f44c7153cda7e7" datatype="html">
+ <source>Syncing</source>
+ <target>Synchronizacja</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0b0901877d837d3fda16ba161eb74368d1c75b7a" datatype="html">
+ <source>Ready</source>
+ <target>Gotowy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5833626790712999947" datatype="html">
+ <source>Issue</source>
+ <target>Zagadnienie </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3419681791450150574" datatype="html">
+ <source>Progress</source>
+ <target>Progres</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4902817035128594900" datatype="html">
+ <source>Description</source>
+ <target>Opis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40b7acea5b43f45e0bbd1efeba5200af4687981d" datatype="html">
+ <source>Site Name:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e24f9e2d42104ffc01599db4d566d1cc518f9e6" datatype="html">
+ <source>Daemons</source>
+ <target>Demony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6450386891540681425" datatype="html">
+ <source>Edit Site Name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4645993115976933405" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4130053543590533787" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4057c56d63a7e9b140b1d01871a9229a5f30eb27" datatype="html">
+ <source>Edit pool mirror mode</source>
+ <target>Tryb edycji lustrzanego pula</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e1f367f5feaab38f6637dd1f967c848b447dea2d" datatype="html">
+ <source>To edit the mirror mode for pool  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, select a new mode from the list and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37e10df2d9c0c25ef04ac112c9c9a7723e8efae0" datatype="html">
+ <source>Mode</source>
+ <target>Tryb</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">426</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32ca348ef926b0a6a7a780b8b64c3a8239895cec" datatype="html">
+ <source>Peer clusters must be removed prior to disabling mirror.</source>
+ <target>Sparowany klaster musi być usunięty przed wyłączeniem lustra. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5769292297914455214" datatype="html">
+ <source>Disabled</source>
+ <target>Wyłączony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ddcb416c1c0aa1f54acf5beef1de81813e76fa6" datatype="html">
+ <source>{VAR_SELECT, select, edit {Edit} other {Add}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3aa7c3a4f7b0cf7c2e60fc71ea1e3b4c3efa3558" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> pool mirror peer</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="59ca65ece457429d90104ede4674965f62edbabe" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> the pool mirror peer attributes for pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Submit<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d3cc964811f852a168f4a2d5daa59068abc5cf53" datatype="html">
+ <source>Cluster Name</source>
+ <target>Nazwa Klastra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b631721fc56cb7fb1cbd07b802a487c5753f6a2d" datatype="html">
+ <source>The cluster name is not valid.</source>
+ <target>Nazwa klastra jest niepoprawna </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca6deafa31bf421f85094807982aee4bcb20a3ae" datatype="html">
+ <source>CephX ID</source>
+ <target>CephX ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7539188a568c3d553cbde1bacaf32310c4264e24" datatype="html">
+ <source>CephX ID...</source>
+ <target>CephX ID...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1c45b594b0fba22fc64e80c793a7ffe005fdb0e" datatype="html">
+ <source>The CephX ID is not valid.</source>
+ <target>ID CephX nie jest poprawne.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20861576fcfce773c918c782cd4f5adf32382921" datatype="html">
+ <source>Monitor Addresses</source>
+ <target>Adres monitora </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fa28eeed2b4bd4ccbe6e9349a1c2b3cb1c5de70a" datatype="html">
+ <source>Comma-delimited addresses...</source>
+ <target>Adresy rozdzielane przecinkami... </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dc016c82fd85848d5c1b2fd0e8469ee2027d9c16" datatype="html">
+ <source>The monitory address is not valid.</source>
+ <target>Adres monitora nie jest poprawny.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0ac55b83dc6739e62bc655cfe375b67c93e7f4a" datatype="html">
+ <source>CephX Key</source>
+ <target>Klucz CephX</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f53434bcb95bd86f1df9c8e22966f757614fc4ad" datatype="html">
+ <source>Base64-encoded key...</source>
+ <target>Klucz zakodowany w Base64...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4cd83164cd4f66b4abc2863f9ce6f599d789e4ca" datatype="html">
+ <source>CephX key must be base64 encoded.</source>
+ <target>Klucz CephX musi być zakodowany w Base64/</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6407712033679505505" datatype="html">
+ <source>Edit Mode</source>
+ <target>Tryb Edycji</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054237897979907103" datatype="html">
+ <source>Add Peer</source>
+ <target>Dodaj parowanie </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="899134641637789371" datatype="html">
+ <source>Edit Peer</source>
+ <target>Edytuj parowanie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7393680121674824053" datatype="html">
+ <source>Delete Peer</source>
+ <target>Usuń parowanie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1713271461473302108" datatype="html">
+ <source>Mode</source>
+ <target>Tryb</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1061297288634362831" datatype="html">
+ <source>Leader</source>
+ <target>Lider</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8517494870558773093" datatype="html">
+ <source># Local</source>
+ <target># Lokalny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4953753699491987394" datatype="html">
+ <source># Remote</source>
+ <target># Zdalny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1715982232168082172" datatype="html">
+ <source>mirror peer</source>
+ <target>lustrzane parowanie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff92fbdec9fdd5054493eeda0d7ee8b450f83e72" datatype="html">
+ <source>RBD Configuration</source>
+ <target>Konfiguracja RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b62d9efc8eb3b589904f6cb96a0406bbda55673a" datatype="html">
+ <source>Remove the local configuration value. The parent configuration value will be inherited and used instead.</source>
+ <target>Usuń wartość konfiguracji lokalnej. Wartość konfiguracji rodzica będzie odziedziczona i zostanie użyta zamiast tej.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80d769fd863fe44fab689636a078466bfdbd1f20" datatype="html">
+ <source>The minimum value is 0</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5decb3917d46a9ac6e5813699801becb7c3c1455" datatype="html">
+ <source>Global</source>
+ <target>Globalne</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f9ba9bb9faa8284bcadb1cdbc6aaf969e9c4bb" datatype="html">
+ <source>Image</source>
+ <target>Obraz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70fcca5a99575cffef3ff8cbd5e69f06ffd0f1c" datatype="html">
+ <source>Pool</source>
+ <target>Pul</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176659033176029418" datatype="html">
+ <source>Key</source>
+ <target>Klucz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9155608366859514313" datatype="html">
+ <source>Source</source>
+ <target>Źródło </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6555318547274416232" datatype="html">
+ <source>Value</source>
+ <target>Wartość</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f6e8f6094b180eaf1f11bc0ffe383f1cdcd059e" datatype="html">
+ <source>Only available for RBD images with <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> enabled</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f8b2bb476981727ab34ed40fde1218361f92c45" datatype="html">
+ <source>Details</source>
+ <target>Szczegóły</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03cc5b14b0a20d075e9009ff021f4f1660ba348a" datatype="html">
+ <source>Data Pool</source>
+ <target>Dane pula</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b051734b0ee9021991c91b3ed4e81c244322462" datatype="html">
+ <source>Created</source>
+ <target>Utworzony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7faaaa08f56427999f3be41df1093ce4089bbd75" datatype="html">
+ <source>Size</source>
+ <target>Rozmiar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="afdb601c16162f2c798b16a2920955f1cc6a20aa" datatype="html">
+ <source>Objects</source>
+ <target>Obiekty</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ceac8e132384322ec778ba760875a6c6897d3e42" datatype="html">
+ <source>Object size</source>
+ <target>Rozmiar obiektu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cdb1fea93d77c07950c0c76c6e0ad79ebbef084" datatype="html">
+ <source>Features</source>
+ <target>Funkcje</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65771c9a73b9aa609d592fc96a64801a8f40bd" datatype="html">
+ <source>Provisioned</source>
+ <target>Zaopatrzony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84a36cb75660b736773fe36ffa3d54f0f0fe363e" datatype="html">
+ <source>N/A</source>
+ <target>Niedostępny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c009342a4e8381f64341d0bb61c2e4685f5a4b" datatype="html">
+ <source>Total provisioned</source>
+ <target>Całkowite rezerwy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f6bf8a43ae415f527ac961ea62471b983aaa97b" datatype="html">
+ <source>Striping unit</source>
+ <target>Jednostka maskowana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db710e8a8f011923f2d15d713fbae49c38b02b26" datatype="html">
+ <source>Striping count</source>
+ <target>Licznik maskowania</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a4c2a9e76634ff14a60d52a718296f722d47c67" datatype="html">
+ <source>Parent</source>
+ <target>Rodzic</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a209e68d78ffc2cc9c53d2e76158624efab71ad" datatype="html">
+ <source>Block name prefix</source>
+ <target>Prefiks nazwy bloku</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5704ec2049d007c5f5fb495a5d8b607e68d58081" datatype="html">
+ <source>Order</source>
+ <target>Zamówienie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="984cb6ad70f150a401b4daf841bd3cd957412699" datatype="html">
+ <source>Format Version</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f21b1d17b6c5042bb5805516eee37fde33739dd8" datatype="html">
+ <source>Snapshots</source>
+ <target>Migawki</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4a41f824a35ba01d5bd7be61aa06b3e8145209d0" datatype="html">
+ <source>Configuration</source>
+ <target>Konfiguracja</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3cc9c2ae277393b3946b38c088dabff671b1ee1b" datatype="html">
+ <source>Performance</source>
+ <target>Wydajność</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935bb9cb0e4340fc74d33caa3b70d9d143fcad87" datatype="html">
+ <source>Information can not be displayed for RBD in status 'Removing'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58e58f1a8786da9031a05e6770c5dafce82badf5" datatype="html">
+ <source>This setting overrides the global value</source>
+ <target>To ustawienie zastępuję wartość globalną.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36b46714164964c6258b08ed0a25f57d8a950f92" datatype="html">
+ <source>This is the global value. No value for this option has been set for this image.</source>
+ <target>To jest globalna wartość. Dla tego obrazu nie ustawiono żadnej wartości dla tej opcji.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6547c9c4d5f62942ac4b1fe459cf9a03d4dbf5a0" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> from</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0e9ecf29a4fa5b057bd8052e0d801b3fde6a30bf" datatype="html">
+ <source>'/' and '@' are not allowed.</source>
+ <target>'/' and '@' nie są dozwolone.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="94516fa213706c67ce5a5b5765681d7fb032033a" datatype="html">
+ <source>Loading...</source>
+ <target>Ładowanie...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">209</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">452</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b99417c4dd46286ffd37c8d2e987c8b512ec7052" datatype="html">
+ <source>-- No rbd pools available --</source>
+ <target>-- Brak dostępnych rbd puli -- </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef83ec9c304a89d45650e580dcdc2978c37b3a83" datatype="html">
+ <source>-- Select a pool --</source>
+ <target>-- Wybierz pul --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d649904466254d13df1fbf2d255f0bbc6553d213" datatype="html">
+ <source>-- No namespaces available --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e22d7bb4d2d561e0832ee0b9a3da2468a080c4f0" datatype="html">
+ <source>-- Select a namespace --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49449943d8cbf59d8c401c8bd2e76f92e207cc5f" datatype="html">
+ <source>Use a dedicated data pool</source>
+ <target>Użyj dedykowanych danych pul </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa5b3c5ea5af14d09b2eb098039af9f1f77be010" datatype="html">
+ <source>You need more than one pool with the rbd application label use to use a dedicated data pool.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="870aee0dd31a9643bf62007beb8f1ae1deb34d42" datatype="html">
+ <source>Data pool</source>
+ <target>Dane pul</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3792ca829d9b9f687e1f5d7733d30e9bb0bfec47" datatype="html">
+ <source>Dedicated pool that stores the object-data of the RBD.</source>
+ <target>Dedykowany pul, który przechowuje dane obiektowe z RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151c80ea931037cd92e854442927f8a0f6ae7795" datatype="html">
+ <source>-- No data pools available --</source>
+ <target>-- Brak danych puli -- </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0016bd458baa88284a658ce9eeda42d8ad88d2c" datatype="html">
+ <source>e.g., 10GiB</source>
+ <target>np. 10 GiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">206</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a88bbee20570aaf9615332fb27020627044874d" datatype="html">
+ <source>You have to increase the size.</source>
+ <target>Musisz zwiększyć rozmiar.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cfe07dac5b4ee1c464eb24225ddeb4f1d24076a" datatype="html">
+ <source>Advanced...</source>
+ <target>Zaawansowane...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bc2e854e111ecf2bd7db170da5e3c2ed08181d88" datatype="html">
+ <source>Advanced</source>
+ <target>Zaawansowane</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3562a3778695a5f9c0445660e35301f0a39aaf73" datatype="html">
+ <source>Striping</source>
+ <target>Maskowanie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef3c3f3b5f562a5cdbe0ee2874287db1534b5958" datatype="html">
+ <source>Stripe unit</source>
+ <target>Jednostka pasków</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84471be1049006edecbcaef1a32ae0893c229c50" datatype="html">
+ <source>-- Select stripe unit --</source>
+ <target>-- Wybierz jednostkę pasków -- </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">289</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d32c5c54c8581c774a7f467fbd4e329b15a74fa" datatype="html">
+ <source>This field is required because stripe count is defined!</source>
+ <target>Pole jest wymagane, ponieważ licznik pasków jest zdefiniowany. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bbf9040be7c5491d4a03f2185708f43a6582a3b" datatype="html">
+ <source>Stripe unit is greater than object size.</source>
+ <target>Jednostka pasków jest większa niż rozmiar obiektu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a682f49f9b761591661276d7c6f550e641a130a4" datatype="html">
+ <source>Stripe count</source>
+ <target>Licznik pasków </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="baa74031990c5370008ba622d0a250f0929097f4" datatype="html">
+ <source>This field is required because stripe unit is defined!</source>
+ <target>Pole jest wymagane, ponieważ jednostka pasków jest zdefiniowana! </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cd2ada6d5ecbd5cbf89eae0a1f5326efedac0dbc" datatype="html">
+ <source>Stripe count must be greater than 0.</source>
+ <target>Licznik pasków musi być większy od 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4341718109173132593" datatype="html">
+ <source>RBD</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1359455778569887786" datatype="html">
+ <source>Deep flatten</source>
+ <target>Głębokie spłaszczenie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58519213655664125" datatype="html">
+ <source>Layering</source>
+ <target>Warstwowanie </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844531889615887801" datatype="html">
+ <source>Exclusive lock</source>
+ <target>Wyłączna blokada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4585281635594103106" datatype="html">
+ <source>Object map (requires exclusive-lock)</source>
+ <target>Mapa obiektów (wymaga wyłącznej blokady)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240933649452133654" datatype="html">
+ <source>Journaling (requires exclusive-lock)</source>
+ <target>Kronikowanie (wymaga wyłącznej blokady)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3713046526850391848" datatype="html">
+ <source>Fast diff (interlocked with object-map)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19f1e825536efbf7492723a7c2d01ad23a4e994b" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1774b9915b0e302d02cad0b9321ad5f1a83247a8" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c9f1026c1235f4d76ace47449e806efd181ab332" datatype="html">
+ <source>Deleting this image will also delete all its snapshots.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55f864597e84d9bf88769e1fbfda1d64452430c9" datatype="html">
+ <source>The following snapshots are currently protected and will be removed:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2e362ec498c4c9112dc47a3cb7d7250ca8e71790" datatype="html">
+ <source>RBD in status 'Removing'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3294686077659093992" datatype="html">
+ <source>Namespace</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45739481977493163" datatype="html">
+ <source>Size</source>
+ <target>Rozmiar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7531602241051125940" datatype="html">
+ <source>Objects</source>
+ <target>Obiekty</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1194977199378511591" datatype="html">
+ <source>Object size</source>
+ <target>Rozmiar obiektu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">226</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="178418048502923560" datatype="html">
+ <source>Provisioned</source>
+ <target>Zaopatrzony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7638291694671392137" datatype="html">
+ <source>Total provisioned</source>
+ <target>Całkowite rezerwy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8621797738551294959" datatype="html">
+ <source>Parent</source>
+ <target>Rodzic</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616639680594151867" datatype="html">
+ <source>This RBD has cloned snapshots. Please delete related RBDs before deleting this RBD.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2900827028308925059" datatype="html">
+ <source>This RBD image has an invalid name and can't be managed by ceph.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1796389652493657142" datatype="html">
+ <source>Action not possible for an RBD in status 'Removing'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">476</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c07d24bb422aa8e5e568df1c5709083f0a9c8f1" datatype="html">
+ <source>Create Namespace</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cca6c0485f96d3a9610d0339cb1275a5f2c3f46" datatype="html">
+ <source>Namespace already exists.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4641528557519966449" datatype="html">
+ <source>Created namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6809428596104996786" datatype="html">
+ <source>Total images</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1346311774128536550" datatype="html">
+ <source>Deleted namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7605466414392298530" datatype="html">
+ <source>Namespace contains images</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576483965711201552" datatype="html">
+ <source>RBD Snapshot</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3473055924346204357" datatype="html">
+ <source>Parent image must support Layering</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1152535233999495900" datatype="html">
+ <source>Snapshot must be protected in order to clone.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c5331983af566d4ac6a1024d15a3511786a4aa6" datatype="html">
+ <source>You are about to rollback</source>
+ <target>Zaraz się wycofasz. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6240400332778072187" datatype="html">
+ <source>PROTECTED</source>
+ <target>ZABEZPIECZONE</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9101667614062185213" datatype="html">
+ <source>UNPROTECTED</source>
+ <target>NIEZABEZPIECZONY </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4207916966377787111" datatype="html">
+ <source>Created</source>
+ <target>Utworzony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587768621777516124" datatype="html">
+ <source>RBD snapshot rollback</source>
+ <target>Wycofywanie migawek RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">305</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2711198699676132148" datatype="html">
+ <source>Rollback</source>
+ <target>Wycofanie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3330476395115957823" datatype="html">
+ <source>RBD snapshot</source>
+ <target>migawka RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">322</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3a7e364a88ea4673199dfa98bc73e6dbe09dfac" datatype="html">
+ <source>Namespaces</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aba82bfd8e177d35b76cad7cd43941f8e5e5acac" datatype="html">
+ <source>Trash</source>
+ <target>Kosz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5e7f4b1ca49e8d217bd0e12c6f7d6b6a2ade2c18" datatype="html">
+ <source>Overall Performance</source>
+ <target>Całkowita wydajność</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c0408946a6d67185947f455f15cc201d0d78e6" datatype="html">
+ <source>Purge Trash</source>
+ <target>Usuń Śmieci</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c96a761dc55a21882c132c929583a424c9b8cf4" datatype="html">
+ <source>Expired at</source>
+ <target>Wygasły w</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="661041e3fcff4d3e75c561e038ca2504cf2cc643" datatype="html">
+ <source>Protected until</source>
+ <target>Zabezpieczony do</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee3b2322a1d3277f7e3fdb8a5141ac42bcf350b" datatype="html">
+ <source>This image is protected until <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5611592591303869712" datatype="html">
+ <source>Status</source>
+ <target>Status</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">213</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">285</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2155633476201267204" datatype="html">
+ <source>Deleted At</source>
+ <target>Usunięty o </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0b5d789d42c0e69348e5fe0037fcbf5b5fbbdcc" datatype="html">
+ <source>Move an image to trash</source>
+ <target>Przenieś obraz do kosza</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ad22c1d4aab3b8946603cea62de266d5129ca10" datatype="html">
+ <source>This image contains snapshot(s), which will prevent it from being removed after moved to trash.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">15,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d4a5f5698bc8118b2e120b9bb72eff339094dd0" datatype="html">
+ <source>To move <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> to trash, click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Move<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Optionally, you can pick an expiration date.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">19,20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f27d390844aad53b4240360e928156c5f0d326" datatype="html">
+ <source>Protection expires at</source>
+ <target>Zabezpieczenie wygasa w </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da166e9a0d27322f6ba8916d71ecc0f9905bb4b1" datatype="html">
+ <source>NOT PROTECTED</source>
+ <target>NIEZABEZPIECZONY </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1506e5f2ca22cad14502ec7a20fb6113ace145d" datatype="html">
+ <source>Wrong date format. Please use &quot;YYYY-MM-DD HH:mm:ss&quot;.</source>
+ <target>Zły format daty. Proszę używać &quot;RRRR-MM-DD GG:mm:ss&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa7ea0bb7495281e0b3258467ac7d90a1e44a1a1" datatype="html">
+ <source>Protection has already expired. Please pick a future date or leave it empty.</source>
+ <target>Ochrona już wygasła. Proszę wybrać przyszłą datę lub zostawić pustą.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d8613436532acac2b97d17de28b50f93e6bd0222" datatype="html">
+ <source>To purge, select  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>All<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>  or one pool and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Purge<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55a4f598a4894b7fd5cb88f0ffd3c37ad009dd70" datatype="html">
+ <source>Pool:</source>
+ <target>Pul:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d43dd2b9f7797e4cf3a604695bb33e4479108516" datatype="html">
+ <source>Pool name...</source>
+ <target>Nazwa pula</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dfc3c34e182ea73c5d784ff7c8135f087992dac1" datatype="html">
+ <source>All</source>
+ <target>Wszystkie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0e7c7ed1d51a0c205c815048bc9f79e24ee6db2" datatype="html">
+ <source>Restore Image</source>
+ <target>Przywróć obraz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3bc4aaf0dce75dc5e01ee5c825a652dc8aea8f0" datatype="html">
+ <source>To restore  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>,  type the image's new name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Restore<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41307dd56fea669eed72e12a6c23af275f6bfd82" datatype="html">
+ <source>New Name</source>
+ <target>Nowa Nazwa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3625859417927520024" datatype="html">
+ <source>id</source>
+ <target>id</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6537904131139019667" datatype="html">
+ <source>type</source>
+ <target>typ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8901220148451863928" datatype="html">
+ <source>state</source>
+ <target>stan</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7925190601961269841" datatype="html">
+ <source>version</source>
+ <target>wersja</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6641024648411549335" datatype="html">
+ <source>Host</source>
+ <target>Host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773272191572353800" datatype="html">
+ <source>root</source>
+ <target>administrator</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6364513948635353490" datatype="html">
+ <source>Evicted client '<x id="PH" equiv-text="clientId"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c1e17956453ad772dbe82d6946f62748c692f3e" datatype="html">
+ <source>Ranks</source>
+ <target>Szeregi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b24e0b0b1629d2e8a51b9da7c75d6e6379f4bc4" datatype="html">
+ <source>Standbys</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="50df62325726db950523a5be1c78b8905fcc25d4" datatype="html">
+ <source>MDS performance counters</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4578796959376778578" datatype="html">
+ <source>Standby daemons</source>
+ <target>Czuwanie demona </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="665219418211496660" datatype="html">
+ <source>Rank</source>
+ <target>Ranga</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5445409664838149993" datatype="html">
+ <source>Daemon</source>
+ <target>Demon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5306473977542913614" datatype="html">
+ <source>Activity</source>
+ <target>Aktywność</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3998441303515229547" datatype="html">
+ <source>Dentries</source>
+ <target>centrale</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7877631502958415163" datatype="html">
+ <source>Inodes</source>
+ <target>i-węzły</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6129397096478256985" datatype="html">
+ <source>Dirs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3011876564696453148" datatype="html">
+ <source>Caps</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8650499415827640724" datatype="html">
+ <source>Type</source>
+ <target>Typ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="142654590491855672" datatype="html">
+ <source>Usage</source>
+ <target>Użycie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">326</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb8293aa8161433778762ae025ffd5e7c85795e" datatype="html">
+ <source>Quotas</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">540</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66785722678644243" datatype="html">
+ <source>Origin</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8911059720204770105" datatype="html">
+ <source>Path</source>
+ <target>Ścieżka</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6111756909052789805" datatype="html">
+ <source>Cannot create snapshots for files/folders in the subvolume <x id="PH" equiv-text="folders[2]"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7503263437025060215" datatype="html">
+ <source>Max size</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6763343019307619111" datatype="html">
+ <source>Max files</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327403486214540377" datatype="html">
+ <source>The inherited <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> is the maximum value to be used.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">434,437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3768927257183755959" datatype="html">
+ <source>Save</source>
+ <target>Zapisz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">440</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6328794256834621774" datatype="html">
+ <source><x id="PH" equiv-text="action"/> CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> quota for '<x id="PH_2" equiv-text="path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">446</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9130352375983418123" datatype="html">
+ <source>size</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6889473896134264260" datatype="html">
+ <source>files</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2244434638607433133" datatype="html">
+ <source><x id="PH" equiv-text="this.getQuotaName()"/> quota <x id="PH_1" equiv-text="value"/> from '<x id="PH_2" equiv-text="path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">460</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6960117167304061503" datatype="html">
+ <source>Value has to be at least 0 or more</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">484</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6740501370117796629" datatype="html">
+ <source>Value has to be at most <x id="PH" equiv-text="maxValue"/> or less</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7239750919884229270" datatype="html">
+ <source>Updated</source>
+ <target>Zaktualizowany</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">499</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8885980874806414253" datatype="html">
+ <source>in order to inherit <x id="PH" equiv-text="quotaValue"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4182949309891923991" datatype="html">
+ <source>which isn't used because of the inheritance of <x id="PH" equiv-text="quotaValue"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7421970649864638435" datatype="html">
+ <source>in order to have no quota on the directory</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6730229976797004508" datatype="html">
+ <source><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">530,533</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="827679535246546876" datatype="html">
+ <source>Create Snapshot</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">542</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">552</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4747656362969857823" datatype="html">
+ <source>Please enter the name of the snapshot.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3667696812078358068" datatype="html">
+ <source>Created snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="753342836137587734" datatype="html">
+ <source>CephFs Snapshot</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">670</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2774104291801979963" datatype="html">
+ <source>Deleted snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">683</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4816216590591222133" datatype="html">
+ <source>Enabled</source>
+ <target>Uaktywniony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ffe39df9d88c972792bd8688b215392deb8313d" datatype="html">
+ <source>Clients</source>
+ <target>Klienci</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e213942c6354b9cbe7a650f0f1499bfc1000fb6" datatype="html">
+ <source>Directories</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fbbaf5cb02ed419e79a27072478f716a4666a99d" datatype="html">
+ <source>Performance Details</source>
+ <target>Szczegóły wydajności</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0" datatype="html">
+ <source>Description</source>
+ <target>Opis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ad112ce9bcd55dfd137792a86afe1b5a5b13cf8" datatype="html">
+ <source>Long description</source>
+ <target>Długi opis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="26fb5f81b3581f06b9210defb0e71dc69a67e819" datatype="html">
+ <source>Current values</source>
+ <target>Obecne wartości </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7cee38a2259526c519f878e71b964f41db4348" datatype="html">
+ <source>Default</source>
+ <target>Domyślna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33e1c1d9fc05ca3f62fcc8a1170fc31ebae4229c" datatype="html">
+ <source>Daemon default</source>
+ <target>Domyślny demon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f61c6867295f3b53d23557021f2f4e0aa1d0b8fc" datatype="html">
+ <source>Type</source>
+ <target>Typ</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9abcd7c82643d60c22733470463f74e4a54bc069" datatype="html">
+ <source>Min</source>
+ <target>Min</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3ced4d162a0a55ee233a187ce7208ba5e922418" datatype="html">
+ <source>Max</source>
+ <target>Max</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="920617c6a1a4805e53bcb5af6a9c76f8387e89c6" datatype="html">
+ <source>Flags</source>
+ <target>Flagi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5" datatype="html">
+ <source>Services</source>
+ <target>Usługi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6834fa6b43d1ecbdf147c48dd9c4d72f1484571d" datatype="html">
+ <source>Source</source>
+ <target>Źródło </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a446fb0eb11fbffcac805ece5a2d306d24e733d8" datatype="html">
+ <source>Level</source>
+ <target>Poziom</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39f2fb094e9b2eda13163fa3f3a31594cf9c1307" datatype="html">
+ <source>Can be updated at runtime (editable)</source>
+ <target>Może być aktualizowany w czasie wykonywania (edytowalny)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
+ <source>Tags</source>
+ <target>Tagi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ab0089ef47af61ca1d137bc908b96c290dfd9287" datatype="html">
+ <source>Enum values</source>
+ <target>Wartości enumerowane </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="819476f1264f1659f38e86f6abb542141b184832" datatype="html">
+ <source>See also</source>
+ <target>Zobacz także </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="543199344025799954" datatype="html">
+ <source>The value can be updated at runtime.</source>
+ <target>Wartość może być zaktualizowana w czasie wykonywania . </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1718354829128482129" datatype="html">
+ <source>Daemons/clients do not pull this value from the
+ monitor config database. We disallow setting this option via 'ceph config
+ set ...'. This option should be configured via ceph.conf or via the
+ command line.</source>
+ <target>Demony/klienci nie pobierają tej wartości z
+bazy danych skonfigurowanego monitora. Nie zezwalamy na ustawienie tej opcji przez 'konfiguracje ceph
+ustaw.. '. Ta opcja powinna być skonfigurowana przez ceph.conf albo przez
+terminal.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">15,18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2345189734548717257" datatype="html">
+ <source>Option takes effect only during daemon startup.</source>
+ <target>Opcja działa tylko podczas startu demona.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5523310713159993513" datatype="html">
+ <source>Option only affects cluster creation.</source>
+ <target>Opcja dotyczy tylko tworzenia klastra.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1064479086902933123" datatype="html">
+ <source>Option only affects daemon creation.</source>
+ <target>Opcja tylko wpływa na tworzenie demona.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="809b0c848932a41318f77a2aace904ef429c13f4" datatype="html">
+ <source>Values</source>
+ <target>Wartości</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5894f7158499fdb89527af50c9f1cf7d4c95cad6" datatype="html">
+ <source>-- Default --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="514f6e12d035a6d9b00de6b3e55c18b73488da07" datatype="html">
+ <source>true</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="774f5e6a183dea08393789b6f72e86afad729419" datatype="html">
+ <source>false</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="82029b6db704c56a2aa3e82ac555b8655356b077" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ed8b3967a7326b81b191c9f490006e6a6777a9a" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2337058106409853613" datatype="html">
+ <source>Updated config option <x id="PH" equiv-text="request.name"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3733215288982610673" datatype="html">
+ <source>Level</source>
+ <target>Poziom</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2218082343053095278" datatype="html">
+ <source>Service</source>
+ <target>Usługa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3553216189604488439" datatype="html">
+ <source>Modified</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844248428439297756" datatype="html">
+ <source>Current value</source>
+ <target>Obecna wartość</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208877297843037352" datatype="html">
+ <source>Editable</source>
+ <target>Edytowalny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b266042bac4c3a2eff4834e40fb9dc4767a709" datatype="html">
+ <source>Cluster Resources</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="099b441d49333b3c6d30b36dc0a4763e64c78920" datatype="html">
+ <source>Hosts</source>
+ <target>Hosty</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57e6e608ece53a26f6d509c90ed4f83e467741af" datatype="html">
+ <source>Storage Capacity</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19ece2cb2b9097c0f75af8e62b4b3b25d399a006" datatype="html">
+ <source>Number of devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b161e3d25fd1b42a781f4e923a58a94925988ddf" datatype="html">
+ <source>Raw capacity</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb6f3e2a26f3a6f2bc33f91adcd60502dbe5adac" datatype="html">
+ <source>CPUs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58d4a9814864741040bc5905b6a368836e683f76" datatype="html">
+ <source>Memory</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dbb81e566a861d4aa0a094366e4083e50863ee92" datatype="html">
+ <source>Host Details</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="453dc2810080a744223faac6da2b3ee9ed63a583" datatype="html">
+ <source>Welcome to <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1eec874e1928ca53baa9914781ce203b5f72b0c" datatype="html">
+ <source>Please expand your cluster first</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2195fd96b0a00f560449b50bd032e6d9b357730" datatype="html">
+ <source>Expand Cluster</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb075d0450deb6f381616f7da4b9244ced843053" datatype="html">
+ <source>Skip</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55b6ce65571b8893440a4fc92776570f8fe7cc97" datatype="html">
+ <source>Add Hosts</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="162f763675c24b557a60eba0758558222369e0c7" datatype="html">
+ <source>Create OSDs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fef7a7b8db05c351c5287db48488abca530bdb54" datatype="html">
+ <source>Create Services</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="176873b4533ddeabf95992cbd7b91b9d01c6d557" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ed90ec4409b9f6b552982d96f89db27259e763c" datatype="html">
+ <source>You are about to skip the cluster expansion process. You’ll need to <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>navigate through the menu to add hosts and services.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">90,91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d1dcf2a9146caac0581329acf94806ec69a89a5" datatype="html">
+ <source>Are you sure you want to continue?</source>
+ <target>Jesteś pewny, że chcesz kontynuować? </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6759205696902713848" datatype="html">
+ <source>Warning</source>
+ <target>Ostrzeżenie </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">357</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6962699013778688473" datatype="html">
+ <source>Continue</source>
+ <target>Kontynuuj </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6156560100092571435" datatype="html">
+ <source>Cluster expansion skipped by user</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520085823873354736" datatype="html">
+ <source>Cluster expansion was successful</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176230351113290618" datatype="html">
+ <source>Expand Cluster</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="738de688b22fba5d0dc7a5e549996838dddad0ee" datatype="html">
+ <source>CRUSH map viewer</source>
+ <target>widok CRUSH mapy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/crushmap/crushmap.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e24569eca61d598c8b01defbbbb1fa8bd5222bc" datatype="html">
+ <source>Devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17137bac47e1e020d139256ded0006a671966e73" datatype="html">
+ <source>Physical Disks</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="deba10b7279a589d01e919ea11f43c79ca1773e3" datatype="html">
+ <source>Device health</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d87fc20ea8e5f0f0500ba5d5061b345be78ec5e" datatype="html">
+ <source>No hostname found.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9a541ec1a4319fffc16ad3b3ab2c2b6d251a829d" datatype="html">
+ <source>Hostname</source>
+ <target>Nazwa hosta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee6875e67b53cac30a02b57cf76e485f7e60caf4" datatype="html">
+ <source>To add multiple hosts at once, you can enter:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a8370b19ccf673fb28fa9db36a08f9901887cc7" datatype="html">
+ <source>a comma-separated list of hostnames <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-01,example-02,example-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="68f2c05396ec8a5f59e8da42d1f6c7310fa8c37c" datatype="html">
+ <source>a range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e00b9bba448e79add37740e53dc953fbb89f9c5" datatype="html">
+ <source>a comma separated range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b3f5e5291541678f7afa49d28fad5ca848a8061" datatype="html">
+ <source>The chosen hostname is already in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="42365f623c57973d1d13d2038e8a2d4c02fb9b9f" datatype="html">
+ <source>Network address</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3859bdca1ae89e611e214c205fccf0147b4d0f6b" datatype="html">
+ <source>The value is not a valid IP address.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2af7efecfae8d7fed3b07f718a623eca1ad8163f" datatype="html">
+ <source>Labels</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9da2afd4fa358b66d4d95fe7e8f4b659a7144e" datatype="html">
+ <source>Maintenance Mode</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="468785112451259935" datatype="html">
+ <source>There are no labels.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4664081995078497865" datatype="html">
+ <source>Filter or add labels</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4897817053917542646" datatype="html">
+ <source>Add label</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">313</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1187321380561233505" datatype="html">
+ <source>host</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40661476cb24c89d8b06614998e31d5fbe84eeb6" datatype="html">
+ <source>Hosts List</source>
+ <target>Lista hostów</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b7a4e1e5a316f8547af1d6d2311a5cec8c5c1d87" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ msg }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6e8e8844e9e7a7b626a4699c08b6c0c81297a7b" datatype="html">
+ <source>Data will be available only if Orchestrator is available.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4baf526199fed59071adf555271791283adc408" datatype="html">
+ <source>SSD, NVMEs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="22d5531d79f0d7269a0a752e56a848807dd37095" datatype="html">
+ <source>Flash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4025065730478477779" datatype="html">
+ <source>The feature is disabled because the selected host is not managed by Orchestrator.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7143579180750436311" datatype="html">
+ <source>Services</source>
+ <target>Usługi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="546766753072101168" datatype="html">
+ <source>Labels</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1141886420788473147" datatype="html">
+ <source>Model</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4027647877328291519" datatype="html">
+ <source>CPUs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2445398473573060226" datatype="html">
+ <source>Cores</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1656823484917332451" datatype="html">
+ <source>Total Memory</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1939212557812454069" datatype="html">
+ <source>Raw Capacity</source>
+ <target>Pojemność rzędu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5579687933271468638" datatype="html">
+ <source>HDDs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1889285841762768492" datatype="html">
+ <source>Flash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1578709829957887527" datatype="html">
+ <source>NICs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4723031838495967601" datatype="html">
+ <source>Edit Host: <x id="PH" equiv-text="host.hostname"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6004907173026319041" datatype="html">
+ <source>Edit Host</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5618131051466022401" datatype="html">
+ <source>Updated Host &quot;<x id="PH" equiv-text="host.hostname"/>&quot;</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1701954433367210342" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; moved to maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3108406586869160854" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; cannot be put into maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1737753151350322492" datatype="html">
+ <source><x id="PH" equiv-text="error.error['detail']"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4054533801359952167" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; has exited maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5837599005212786659" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; stopped draining</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1357236071975782353" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; started draining</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5658400717636093668" datatype="html">
+ <source>Identify</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6966707768479328825" datatype="html">
+ <source>Device path</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3955868613858648955" datatype="html">
+ <source>Available</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="158816374076721379" datatype="html">
+ <source>Vendor</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6024104799101504292" datatype="html">
+ <source>OSDs</source>
+ <target>OSD-ki</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3422162477846071958" datatype="html">
+ <source>Identify device <x id="PH" equiv-text="device"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4910073658089977244" datatype="html">
+ <source>Please enter the duration how long to blink the LED.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5764931367607989415" datatype="html">
+ <source>1 minute</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809466133764752509" datatype="html">
+ <source>2 minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">235</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1487672983218679675" datatype="html">
+ <source>5 minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603584938775296395" datatype="html">
+ <source>10 minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6648333117195452824" datatype="html">
+ <source>15 minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6560281329999108838" datatype="html">
+ <source>Execute</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6901229416977800100" datatype="html">
+ <source>Identifying '<x id="PH" equiv-text="device"/>' started on host '<x id="PH_1" equiv-text="hostname"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d556ab48a65722b400e497f61737f553ee0f89e2" datatype="html">
+ <source>Cluster Logs</source>
+ <target>Logi z klastra </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5f966baffd188be0e8adc2d7067b86e55fc9b9de" datatype="html">
+ <source>Audit Logs</source>
+ <target>Audyt logów</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4193c9eb868aeec119b78a14795241e0aa5e8b60" datatype="html">
+ <source>Priority:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d78ca51eab260ce3fd917d39190d64df5229b6e" datatype="html">
+ <source>Keyword:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="05fa0bded36de6e73a1fa44838b627349dace044" datatype="html">
+ <source>Date:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a400388de1899b1917138cf7e5286376f72847" datatype="html">
+ <source>Time range:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="de0478286b8b5a939db54e9e5282405364ad2d61" datatype="html">
+ <source>No log entries found. Please try to select different filter options.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7479674d91142b785b9547a87e5fb51cb16108" datatype="html">
+ <source>Reset filter.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="31a9c2870a934b594d1390146c489f76440859ea" datatype="html">
+ <source>Edit Manager module</source>
+ <target>Edytuj moduł zarządzania</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="46e09b8290d3d0afdb6baa2021395b0570606a31" datatype="html">
+ <source>The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</source>
+ <target>Wpisana wartość nie jest poprawnym UUID, np. 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7aacd038b39cfd347107d01d1dc27f5cb3e0951c" datatype="html">
+ <source>The entered value needs to be a valid IP address.</source>
+ <target>Wpisana wartość musi być poprawnym adresem IP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f19106149f4b07a0d721f9d317afed393cb7bd93" datatype="html">
+ <source>The entered value is too high! It must be lower or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d33c40ef9a6c3bf0888df831b25e41e65f9d15b" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eae7086660cf1e38c7194a2c49ff52cc656f90f5" datatype="html">
+ <source>The entered value needs to be a number.</source>
+ <target>Podana wartość musi być liczbą</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">194</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a73376e04b4fb3a20734c8c39743fba32e6676ce" datatype="html">
+ <source>The entered value needs to be a number or decimal.</source>
+ <target>Podana wartość musi być liczbą albo dziesiętną.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1898719236268328097" datatype="html">
+ <source>Updated options for module '<x id="PH" equiv-text="this.moduleName"/>'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4186041075388034600" datatype="html">
+ <source>Always-On</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7585826646011739428" datatype="html">
+ <source>Edit</source>
+ <target>Edytuj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2180291763949669799" datatype="html">
+ <source>Enable</source>
+ <target>Włączyć</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9187855490716817910" datatype="html">
+ <source>Disable</source>
+ <target>Wyłączyć</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1600086764852993170" datatype="html">
+ <source>This Manager module is always on.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3895296744591223546" datatype="html">
+ <source>Reconnecting, please wait ...</source>
+ <target>Ponowne łączenie, proszę czekać</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81b97b8ea996ad1e4f9fca8415021850214884b1" datatype="html">
+ <source>Status</source>
+ <target>Status</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57ec6032f5618d4a9f16eb950ad23d2ce7c24b54" datatype="html">
+ <source>Cluster ID</source>
+ <target>Klaster ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67d7facc3fec5f8a49ab9ba0a245872184264ce5" datatype="html">
+ <source>monmap modified</source>
+ <target>Zmodyfikowana monmapa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4906731aaf2b94b4f547646c9bfe58bb77951b6" datatype="html">
+ <source>monmap epoch</source>
+ <target>epoka monmap</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd4ee06ffdc46d9dfbd0c0c4f81399021c680056" datatype="html">
+ <source>quorum con</source>
+ <target>kworum con</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1176c7db8a8276ccb44cc3d42e2c28d9fa6c6596" datatype="html">
+ <source>quorum mon</source>
+ <target>kworum mon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="530ef677a09d681b3ab68cb0760494b3ae72a77c" datatype="html">
+ <source>required con</source>
+ <target>wymagany con</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a91558e0d506c32021c31843f8f168899fc65cbf" datatype="html">
+ <source>required mon</source>
+ <target>Wymagane mon </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3abe9eac5bcd94a54c8da93b312e085ec512e74" datatype="html">
+ <source>In Quorum</source>
+ <target>W kworum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba4b748a676e1f217ce1e736fb7ec1215e677bae" datatype="html">
+ <source>Not In Quorum</source>
+ <target>Nie w kworum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3517477838460618200" datatype="html">
+ <source>Public Address</source>
+ <target>Adres publiczny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6949358970125514744" datatype="html">
+ <source>Open Sessions</source>
+ <target>Otwarte sesje</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4383e9662ea19839c7499b2128d43a195e564317" datatype="html">
+ <source>OSD creation preview</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="366225c51e0b00bcb1c55795a0dc5e81c455f84e" datatype="html">
+ <source>DriveGroups</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91853167141c37b58868f3b0421383dd72fa8a01" datatype="html">
+ <source>Attributes (OSD map)</source>
+ <target>Atrybuty (mapa OSD-ków)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f721a500a68c357e8f2a01e60510f6a01e4ba529" datatype="html">
+ <source>Metadata</source>
+ <target>Metadane</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97842f379e1d4157ac3ab0661b90c352e7cb72d5" datatype="html">
+ <source>Metadata not available</source>
+ <target>Niedostępne metadane</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24e28e19c5703d7c6be44f4eb595a6a43b618ed" datatype="html">
+ <source>Performance counter</source>
+ <target>Licznik wydajności</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ccb4f84edc0b4e76415bb3f9b73d725b06683af3" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ name }}"/> devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60cb3d01e5ddf266ecb4271007a1c3d0f3efdc22" datatype="html">
+ <source>The primary storage devices. These devices contain all OSD data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b432e04886d0d1fd84f740477383051f85addcf2" datatype="html">
+ <source>Write-Ahead-Log devices. These devices are used for BlueStore’s internal journal. It is only useful to use a WAL device if the device is faster than the primary device (e.g. NVME devices or SSDs). If there is only a small amount of fast storage available (e.g., less than a gigabyte), we recommend using it as a WAL device.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87e181ab9e8393aa5ed759dd3d53836e32c8ffe" datatype="html">
+ <source>DB devices can be used for storing BlueStore’s internal metadata. It is only helpful to provision a DB device if it is faster than the primary device (e.g. NVME devices or SSD).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
+ <source>Add</source>
+ <target>Dodaj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="99ee4faa69cd2ea8e3678c1f557c0ff1f05aae46" datatype="html">
+ <source>Clear</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e0fd3c7af0630f93befa6234a693a32a61084e0" datatype="html">
+ <source>Raw capacity: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1961811273151129466" datatype="html">
+ <source>No available devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617271647728055571" datatype="html">
+ <source>Please add primary devices first</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6368751795251107516" datatype="html">
+ <source>Add devices by using filters</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8edc89137d0d8c5667a2f03230beafae45e58429" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eba28e1805b18f7c8ae2e4bc15dcf063b10b3822" datatype="html">
+ <source>At least one of these filters must be applied in order to proceed:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="93389aa2fe2bea50bf89554ee51b28f87ee2fb50" datatype="html">
+ <source>Number of devices: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Raw capacity: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">29,30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6b27c16ddf33b855412c82069dca8120bd3a68a" datatype="html">
+ <source>Individual OSD Flags</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dba0ed9ba355a3bd3296c0bef3bb518744a51a89" datatype="html">
+ <source>Cluster-wide</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e2a3f211cea2cbadb29b6df93e544440b6b68d3e" datatype="html">
+ <source>Restore previous selection</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1683654169791509804" datatype="html">
+ <source>No Up</source>
+ <target>Nie powstały </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5754783193519044074" datatype="html">
+ <source>OSDs are not allowed to start</source>
+ <target>OSD-ki nie mogą startować</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4413588319909369773" datatype="html">
+ <source>No Down</source>
+ <target>Nie upadły</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1348746748821823470" datatype="html">
+ <source>OSD failure reports are being ignored, such that the monitors will not mark OSDs down</source>
+ <target>Raport z niepowodzenia OSD jest ignorowany, także monitory nie oznaczą OSD jako upadłego. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="301172600132606646" datatype="html">
+ <source>No In</source>
+ <target>Nie w </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4114057962148673377" datatype="html">
+ <source>OSDs that were previously marked out will not be marked back in when they start</source>
+ <target>OSD-ki, które zostały oznaczone jako poza, nie będą oznaczone ponownie jako w gdy zostaną uruchomion</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5236523991485603657" datatype="html">
+ <source>No Out</source>
+ <target>Nie poza</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1798160169020638994" datatype="html">
+ <source>OSDs will not automatically be marked out after the configured interval</source>
+ <target>OSD-ki nie będą automatycznie oznaczone jako poza po konfiguracji interwału</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3225813593817914267" datatype="html">
+ <source>The flag has been enabled for the entire cluster.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1941050626944682985" datatype="html">
+ <source>Updated OSD Flags</source>
+ <target>Zaktualizowane flagi OSD-ków</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ef50ba2514414f799d4c8fc36067a251904ba81" datatype="html">
+ <source>Cluster-wide OSD Flags</source>
+ <target>Flagi OSD w całym klastrze</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9042260521669277115" datatype="html">
+ <source>Pause</source>
+ <target>Pauza </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6015425610572318971" datatype="html">
+ <source>Pauses reads and writes</source>
+ <target>Pauzuje czytanie i zapisywanie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314873595759611676" datatype="html">
+ <source>No Scrub</source>
+ <target>Nie szoruj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773570234687653570" datatype="html">
+ <source>Scrubbing is disabled</source>
+ <target>Szorowanie jest wyłączone</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5999821123886006899" datatype="html">
+ <source>No Deep Scrub</source>
+ <target>Nie ma głębokiego szorowania</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5362685148875251772" datatype="html">
+ <source>Deep Scrubbing is disabled</source>
+ <target>Głębokie szorowanie jest wyłączone</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5001752039592388485" datatype="html">
+ <source>No Backfill</source>
+ <target>Brak zasypywania</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4851280330655956778" datatype="html">
+ <source>Backfilling of PGs is suspended</source>
+ <target>Zasypywanie PG jest zawieszone</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5994953210305546559" datatype="html">
+ <source>No Rebalance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3698980403470604587" datatype="html">
+ <source>OSD will choose not to backfill unless PG is also degraded</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4334886823145076432" datatype="html">
+ <source>No Recover</source>
+ <target>Nie przywrócono</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8465994741155792816" datatype="html">
+ <source>Recovery of PGs is suspended</source>
+ <target>Przywrócenie PGy jest zawieszone </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4052740759486923001" datatype="html">
+ <source>Bitwise Sort</source>
+ <target>Sortuj bitowo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2330377428425572488" datatype="html">
+ <source>Use bitwise sort</source>
+ <target>Użyj sortowania bitowego</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8943478424576832224" datatype="html">
+ <source>Purged Snapdirs</source>
+ <target>Usuń snap katalogi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7553321860087551262" datatype="html">
+ <source>OSDs have converted snapsets</source>
+ <target>OSD-ki zmieniły snapsety</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6509988280998256208" datatype="html">
+ <source>Recovery Deletes</source>
+ <target>Odzyskaj usunięte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="451760144355116641" datatype="html">
+ <source>Deletes performed during recovery instead of peering</source>
+ <target>Podczas zdrowienia zastosowano usunięcie zamiast parowania</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="87832369463084597" datatype="html">
+ <source>PG Log Hard Limit</source>
+ <target>Twardy limit logów PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9135782750879343185" datatype="html">
+ <source>Puts a hard limit on pg log length</source>
+ <target>Ustawia twardy limit na długość logów PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="formTitle" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <note priority="1" from="description">Example: Create Pool</note>
+ <note priority="1" from="meaning">form title</note>
+ </trans-unit>
+ <trans-unit id="43ecf6bee2aebc07b0aad6dc1fe13e38d14687fa" datatype="html">
+ <source>Shared devices</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7a1c376f6f1b37de4c318ff2106255ba6c0f5b0b" datatype="html">
+ <source>WAL slots</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73811a6f37b63e6b0e491e221bfa21e9dea8a87a" datatype="html">
+ <source>How many OSDs per WAL device.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c67a7ac4762ef1cc855056c6b4daab93e53a0a5" datatype="html">
+ <source>Specify 0 to let Orchestrator backend decide it.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bda9362e06e6c67341b4a8425b0d29d6b84464b" datatype="html">
+ <source>Value should be greater than or equal to 0</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="324c2b10152b9dd908222bb0b71f61beb60a30c5" datatype="html">
+ <source>DB slots</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c23cf12ef9c76f37fc7a4b7ae3e00fb0f68b6e26" datatype="html">
+ <source>How many OSDs per DB device.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8255877266497322342" datatype="html">
+ <source>Encryption</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b49d7877d24112d4bdfce9256edf61a007fae888" datatype="html">
+ <source>OSDs List</source>
+ <target>Lista OSD-ków </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="172ada0fcf6490b24a897517e9f4299215873ff8" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD(s) <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be marked <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">59,60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="262a49e60d5f6ed9825582ccf3d5ae39daa1da60" datatype="html">
+ <source>The <x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> not safe to be <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>! <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71,72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="74bd20d5f558d14cb2fa41ae863cf09c47d02018" datatype="html">
+ <source>{VAR_SELECT, select, true {OSD is} other {OSDs are}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0e217fd717c5b1f5c17f00c5b174de855acbef0" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">74,75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8cf121660bed7098516a1efe85831d6f415a9411" datatype="html">
+ <source>Preserve OSD ID(s) for replacement.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4435645098786961170" datatype="html">
+ <source>out</source>
+ <target>poza</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136018875175606726" datatype="html">
+ <source>in</source>
+ <target>w</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1301930865667956193" datatype="html">
+ <source>down</source>
+ <target>upadły</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1226060325201042854" datatype="html">
+ <source>Mark</source>
+ <target>Zaznacz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1256299033316818951" datatype="html">
+ <source>OSD lost</source>
+ <target>Stracony OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2795727560928976873" datatype="html">
+ <source>marked lost</source>
+ <target>Zaznaczony jako stracony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7685933846431786388" datatype="html">
+ <source>Purge</source>
+ <target>Czyść</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5941516286393808546" datatype="html">
+ <source>OSD</source>
+ <target>OSD-ik</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3416443212235382421" datatype="html">
+ <source>purged</source>
+ <target>Oczyszczony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9191368063029792986" datatype="html">
+ <source>destroy</source>
+ <target>Zniszcz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4425946029386289247" datatype="html">
+ <source>destroyed</source>
+ <target>Zniszczony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2870788902465061969" datatype="html">
+ <source>Flags</source>
+ <target>Flagi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8995035642420075344" datatype="html">
+ <source>Recovery Priority</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3601135996773579607" datatype="html">
+ <source>PG scrub</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136079353894161076" datatype="html">
+ <source>Device class</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6382718875453721838" datatype="html">
+ <source>PGs</source>
+ <target>PG-y</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3660230483843323377" datatype="html">
+ <source>Read bytes</source>
+ <target>Czytanie bajtów</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">329</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3909578649547040612" datatype="html">
+ <source>Write bytes</source>
+ <target>Zapis bajtów </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3182358405280886750" datatype="html">
+ <source>Read ops</source>
+ <target>Czytanie ops</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171292502535561083" datatype="html">
+ <source>Write ops</source>
+ <target>Zapis ops</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6706824709967518168" datatype="html">
+ <source>Edit OSD: <x id="PH" equiv-text="selectedOsd.id"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">451</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1125148356983553148" datatype="html">
+ <source>Edit OSD</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="970212458427610374" datatype="html">
+ <source>Updated OSD '<x id="PH" equiv-text="selectedOsd.id"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">466</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7554728686176829307" datatype="html">
+ <source>Mark OSD <x id="PH" equiv-text="markAction"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="478122291463667978" datatype="html">
+ <source>Mark <x id="PH" equiv-text="markAction"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">502</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2456043080471762298" datatype="html">
+ <source>delete</source>
+ <target>Usuń</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">530</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="588230151780724018" datatype="html">
+ <source>deleted</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">532</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1ef1c12ddcee305353623919ef02778569f5454" datatype="html">
+ <source>Advanced configuration options</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7771252117308888928" datatype="html">
+ <source>PG scrub options</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1797901277775175680" datatype="html">
+ <source>Updated PG scrub options</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c35f9c5f268a514b970cc55e9a5dc4bed0988e7f" datatype="html">
+ <source>OSD Recovery Priority</source>
+ <target>Priorytet odzyskiwania OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74af38005e8a8914e45af2ec412e11ceafef8b6" datatype="html">
+ <source>Priority</source>
+ <target>Priorytet</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f48f04b379bfba133825747adfd238d511412e" datatype="html">
+ <source>Customize priority values</source>
+ <target>Dostosuj wartości priorytetowe</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aa19de2a2b54cbda39e9c62917b23044c087776" datatype="html">
+ <source>This field is required!</source>
+ <target>To pole jest wymagane.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">406</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b699e94bf376491bd50b70a98531071c737eaf40" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="98fe13e7ad6c2b80375d204b47858ded83f80e15" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423a3c111be47fc5a1bfe46ceb58c81c84db691" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3234179038052466481" datatype="html">
+ <source>Max Backfills</source>
+ <target>Max zasypywanie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847070960491384020" datatype="html">
+ <source>Recovery Max Active</source>
+ <target>Max aktywność wyzdrowienia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2088615724570210504" datatype="html">
+ <source>Recovery Max Single Start</source>
+ <target>Max pojedynczy start wyzdrowienia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8627094894361422565" datatype="html">
+ <source>Recovery Sleep</source>
+ <target>Uśpienie wyzdrowienia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7590013429208346303" datatype="html">
+ <source>Custom</source>
+ <target>Zwyczaj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4937275625032609020" datatype="html">
+ <source>Updated OSD recovery speed priority '<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">227,229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5251a4355cece3075db43f15d69a24a0f8485707" datatype="html">
+ <source>Reweight OSD: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67650b2998db48201b2c6176cbfef51e7211ccaa" datatype="html">
+ <source>The value needs to be between 0 and 1.</source>
+ <target>Wartość powinna być pomiędzy 0 a 1. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f077ceb52c967a8fe2de9ef0a9d65d72badf186" datatype="html">
+ <source>OSDs <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/>Scrub</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b73a34ba65b3073e3560dce828a16d7fd3c0f4" datatype="html">
+ <source>{VAR_SELECT, select, true {Deep } other {}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c00119503aad4012b77049eee41293338f67756c" datatype="html">
+ <source>You are about to apply a <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/>scrub to the OSD(s): <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fad3dc421817a16dd6c46c1a0c36de619a8d776e" datatype="html">
+ <source>{VAR_SELECT, select, true {deep } other {}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1086427836866943370" datatype="html">
+ <source><x id="PH" equiv-text="operation"/> was initialized in the following OSD(s): <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts</context>
+ <context context-type="linenumber">42,44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47c97aa28f64b11fa5842795fdd02c8c0863c97b" datatype="html">
+ <source>To see all active Prometheus alerts, please provide the URL to the API of Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6343323763459782070" datatype="html">
+ <source>Create Silence</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1895957424873987405" datatype="html">
+ <source>Job</source>
+ <target>Praca</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491474782694268231" datatype="html">
+ <source>Severity</source>
+ <target>surowość</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3326877877555410533" datatype="html">
+ <source>Started</source>
+ <target>Wystartowany</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2375260419993138758" datatype="html">
+ <source>URL</source>
+ <target>URL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="880ad4df5a2051a437321443d69c9a866699e5ad" datatype="html">
+ <source>Active Alerts</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9fe218829514884cdd0ca2300573a4e0428c324f" datatype="html">
+ <source>Alerts</source>
+ <target>Powiadomienia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa0c44aa1e5727061baa91e954f77e2f5f9a37c9" datatype="html">
+ <source>Silences</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85c737325f5e59517e2d08a71de6d77788aabc95" datatype="html">
+ <source>To see all configured Prometheus alerts, please provide the URL to the API of Prometheus as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623978917681527907" datatype="html">
+ <source>Group</source>
+ <target>Grupa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7410432243549869948" datatype="html">
+ <source>Duration</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4109205891084963566" datatype="html">
+ <source>Query</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28f86ffd419b869711aa13f5e5ff54be6d70731c" datatype="html">
+ <source>Edit</source>
+ <target>Edytuj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="826b25211922a1b46436589233cb6f1a163d89b7" datatype="html">
+ <source>Delete</source>
+ <target>Usuń</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">279</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">341</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">441</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3ba06aba047605af8ea1718ec1ba153b7db12a2" datatype="html">
+ <source>Editing a silence will expire the old silence and recreate it as a new silence</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a20424156b8816671f61879f0574a4f27d7b16b9" datatype="html">
+ <source>Creator</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5a5d7ee2acbfa9c91ab7f41d26bda9ff0cafe42f" datatype="html">
+ <source>Comment</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c11aad490b2d53fdae30b3807beabf79306752c" datatype="html">
+ <source>Start time</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32856b1e8e339b747b21e313e2fe65a51fd450bb" datatype="html">
+ <source>If the start time lies in the past the creation time will be used</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a02ea1d4e7424ca989929da5e598f379940fdbf2" datatype="html">
+ <source>Duration</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f4e35e36f4d3c62e2c17df41730b6dee4afc4b9" datatype="html">
+ <source>End time</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="992123459137d45c15df5548bc9682aad835c04b" datatype="html">
+ <source>Matchers</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e023166c55833d5a13f4143e3dbe372befe1b4e" datatype="html">
+ <source>A silence requires at least one matcher</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef765bd80c4806c51c891908c07a24bc76f019eb" datatype="html">
+ <source>Add matcher</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754178820914251524" datatype="html">
+ <source>silence</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8714559758543060819" datatype="html">
+ <source>Attribute name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1338733395833138319" datatype="html">
+ <source>Regular expression</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35819898450851998" datatype="html">
+ <source>Please add your Prometheus host to the dashboard configuration and refresh the page</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f2f4cb9d876ff9d34fc082c1ac642d3cb98c360" datatype="html">
+ <source>To enable Silences, please provide the URL to the API of the Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7448808151142843482" datatype="html">
+ <source>Created by</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4734349318830134239" datatype="html">
+ <source>Ends</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1233087251567318644" datatype="html">
+ <source>Silence</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="78af6a5e6e4d305557054b64d10f9f9446d8043d" datatype="html">
+ <source>{VAR_SELECT, select, true {Edit} other {Add}}</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2404fa8e80946d0ce3d0ae369b51cb26ec28d42" datatype="html">
+ <source><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/> Matcher</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c25e04f554875dc2625a78ba0fc56c6010cd0d3" datatype="html">
+ <source>-- Select an attribute to match against --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5049e204c14c648691ac775a64fb504467aeb549" datatype="html">
+ <source>Value</source>
+ <target>Wartość</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="77fc5c63497fc031ddc97645484e3d94ad27766c" datatype="html">
+ <source>Use regular expression</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5518753745858598442" datatype="html">
+ <source>no spec</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1186363766752354382" datatype="html">
+ <source>unmanaged</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5246585784774990516" datatype="html">
+ <source>count:<x id="PH" equiv-text="count"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001661117318762535" datatype="html">
+ <source>label:<x id="PH" equiv-text="label"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cb3aa7e9fea1d445a1a9d7797ab17e6ac6fe13b" datatype="html">
+ <source>Service Events</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3474944817987674409" datatype="html">
+ <source>Daemon type</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3136939605470297323" datatype="html">
+ <source>Daemon ID</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8171022601808215887" datatype="html">
+ <source>Container ID</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8859473568390700297" datatype="html">
+ <source>Container Image name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5623167616584404899" datatype="html">
+ <source>Container Image ID</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="335348913532561915" datatype="html">
+ <source>Last Refreshed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3022087209429182774" datatype="html">
+ <source>Daemon Events</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">140</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8604852007710946848" datatype="html">
+ <source>Service Name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="613875387304159316" datatype="html">
+ <source>Service Type</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907644935670421963" datatype="html">
+ <source>Service Events</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3214a1f3a4c3e89a848b4ec59adeeda3b913c396" datatype="html">
+ <source>-- Select a service type --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f32579a9fd19d93c083175284ee3426d78751c33" datatype="html">
+ <source>Backend Service</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2937074aed12b8158e929c58747a8216433b72b" datatype="html">
+ <source>-- No service available --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19fb4480d95a5539db4e9c7b516d414774e61110" datatype="html">
+ <source>-- Select an existing RGW service --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2798cc1e152b1ec07fd8daf94a2a073d1ba1ebcc" datatype="html">
+ <source>Id</source>
+ <target>Number ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d5156b9d9a79d162c353c4aa9bc6840ad5c6257" datatype="html">
+ <source>The value does not match the pattern <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&lt;service_id&gt;[.&lt;realm_name&gt;.&lt;zone_name&gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83d5d7edd8a0be253c4e93ad4c3efe86d9ac520f" datatype="html">
+ <source>Unmanaged</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c15fa461935e0f600bc5d1660af1da67f024fc2a" datatype="html">
+ <source>Placement</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="863226cffd5b66a6fee9810a9282a5006d6ef576" datatype="html">
+ <source>Label</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06412bce0f4fe4311193e9763666089bf9d980da" datatype="html">
+ <source>Count</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f193722f1e788f14a823b89ac1794c3ba934f9f" datatype="html">
+ <source>Only that number of daemons will be created.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee1a29cc658e4fa891be762d7bae96139b57c8f4" datatype="html">
+ <source>The value must be at least 1.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">369</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cb2741a46e3560f6bc6dfd99d385e86b08b26d72" datatype="html">
+ <source>Port</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a23ed3598cca5285606675b6cb2536a56b411ade" datatype="html">
+ <source>The value cannot exceed 65535.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">404</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d8ebdc326e6b9ff35feee3f762b7ab39c02d78f" datatype="html">
+ <source>-- No pools available --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84b675705324741b954615fedf2417d4d873b0b6" datatype="html">
+ <source>Trusted IPs</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b543e7c787cc48c2938cbce2d14c6afea5a598df" datatype="html">
+ <source>Comma separated list of IP addresses.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1039ea40da18a6453d9c1adc72a35aed099029d0" datatype="html">
+ <source>Please add the <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> IP addresses here, otherwise the iSCSI gateways can't be reached.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6265b64c17a1e19775769489bfd0b152fa1f3ba1" datatype="html">
+ <source>Virtual IP</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61893fde6e9e05a6b91619d501edaa7962b438ff" datatype="html">
+ <source>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">333</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ece04ddf7e96f445415ebd90d93c455e03e8cf53" datatype="html">
+ <source>Frontend Port</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">352</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae6fd97454d184b374984c9ff808176ece54f0dd" datatype="html">
+ <source>The port used to access the ingress service.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1261eacf161f75efc9dfea84dd97b4a466b89aa1" datatype="html">
+ <source>Monitor Port</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4df6281ed630ba96f09790a46a7fe0ec0e666bb6" datatype="html">
+ <source>The port used by haproxy for load balancer status.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ce24ae1d792ed2846ba57e7ed6397a802caeff5" datatype="html">
+ <source>CIDR Networks</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">414</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7c13184af0c09e3bad77daa5f4869138708d26b2" datatype="html">
+ <source>A list of networks to identify which network interface to use for the virtual IP address.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8fe73a4787b8068b2ba61f54ab7e0f9af2ea1fc9" datatype="html">
+ <source>Version</source>
+ <target>Wersja</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a6855d17f6b9820bb9709870efdcc7da99552d3" datatype="html">
+ <source>-- Select SNMP version --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">442</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a7369891e88cd613e45a39b55a282c97776d05f5" datatype="html">
+ <source>Destination</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f09a5d334a73a4b5ba031d7fa65151cad5ec7133" datatype="html">
+ <source>Must be of the format hostname:port.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b68c79ffe3af1db88180454fbc2fa880a51ccf52" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>hostname:port<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">470</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c90ad98a026d781ab729911873767e549d78f99" datatype="html">
+ <source>Engine Id</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">478</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d39d015ebd667fb6bddf08bb0e5b3faa6cf044c" datatype="html">
+ <source>Unique identifier for the device (in hex).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">480</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514cda7dc49062c5c532427245ce47c4954bc32" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b2d628c51192ade0044212b409c758c20f9c021" datatype="html">
+ <source>Auth Protocol</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc8bb2315a5101770a752b18e03b5c730539397c" datatype="html">
+ <source>-- Select auth protocol --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">508</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6777f99fd13e03874afe26ba7289dc9fc211af04" datatype="html">
+ <source>Privacy Protocol</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70512b7c13bce85b3928920b29fafbd59a853383" datatype="html">
+ <source>-- Select privacy protocol --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b48c81465d14465b95826b99e05acfabef1814c6" datatype="html">
+ <source>Credentials</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">541</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4ea0163c25c818aab982072b1b8d5ab585e9a5a" datatype="html">
+ <source>SNMP Community</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">547</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="08c74dc9762957593b91f6eb5d65efdfc975bf48" datatype="html">
+ <source>Username</source>
+ <target>Nazwa użytkownika</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="948758e1412bb2ecdb98e3a4f1cbb6d7458456f2" datatype="html">
+ <source>Encryption</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">598</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e65610b5d940367f1ff6b57772b96e94e35fe202" datatype="html">
+ <source>SSL</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">624</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e37e0d06148c7708e88b4a1eb412babbe1a4afc" datatype="html">
+ <source>Certificate</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">634</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="295ae4f632322098deca8a3ddfbc7aeaabb5423b" datatype="html">
+ <source>The SSL certificate in PEM format.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">635</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464272c069fe56f6c50f41f426a25b2a42c95ba5" datatype="html">
+ <source>Invalid SSL certificate.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">650</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0596d06bf1f8a15d4bfe56226971ecdd78013b1f" datatype="html">
+ <source>Private key</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">659</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ded15dc55104994c0230189f34dff84a4955aafb" datatype="html">
+ <source>The SSL private key in PEM format.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">660</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19bdc1597d815b456793ff87c89af4257a85a103" datatype="html">
+ <source>Invalid SSL private key.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">675</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3356018487523380058" datatype="html">
+ <source>service</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2412938991511187011" datatype="html">
+ <source>There are no hosts.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2594503755408511486" datatype="html">
+ <source>Filter hosts</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5869780110608474933" datatype="html">
+ <source>Placement</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2956098160626271284" datatype="html">
+ <source>Running</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="013f48ee777d2e53e2bcba36e1a99fcbb7ef8cb6" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report configuration</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a09b723a928774bff707973c99999dcf3d84a349" datatype="html">
+ <source>The telemetry module sends anonymous data about this Ceph cluster back to the Ceph developers to help understand how Ceph is used and what problems users may be experiencing.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> This data is visualized on <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>public dashboards<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> that allow the community to quickly see summary statistics on how many clusters are reporting, their total capacity and OSD count, and version distribution trends.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> The data being reported does <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>not<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> contain any sensitive data like pool names, object names, object contents, hostnames, or device serial numbers. It contains counters and statistics on how the cluster has been deployed, the version of Ceph, the distribution of the hosts and other parameters which help the project to gain a better understanding of the way Ceph is used. The data is sent secured to <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> and <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (device report).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">14,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c95505b5a74151a0c235b19b9c41db7983205ba7" datatype="html">
+ <source>Deactivate</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19" datatype="html">
+ <source>Channels</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e25b17c0b4ef361b6a05aaec2bbd2b7e86680458" datatype="html">
+ <source>The telemetry report is broken down into several &quot;channels&quot;, each with a different type of information that can be configured below.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">32,33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380ab580741bec31346978e7cab8062d6970408d" datatype="html">
+ <source>Basic</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd898057f0add35258a5fb5c90d792c5e2147452" datatype="html">
+ <source>Includes basic information about the cluster:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da213e9ba8a86b453d04f794f58c9803f7b062b1" datatype="html">
+ <source>Capacity of the cluster</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d5fe31d9e13239bdd223d0bbd289a1b1903e86" datatype="html">
+ <source>Number of monitors, managers, OSDs, MDSs, object gateways, or other daemons</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a3eb7834b4baf412f8863d14883972897d9acb7" datatype="html">
+ <source>Software version currently being used</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34881ae65482ffa74ccb4043fb2622e48ed146d5" datatype="html">
+ <source>Number and types of RADOS pools and CephFS file systems</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="696f8f5ea7a9cf6125b9a3af160981fda363552d" datatype="html">
+ <source>Names of configuration options that have been changed from their default (but not their values)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34292940316300d09abe5e675d452fae199f626b" datatype="html">
+ <source>Crash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7620e332b7dea1e832158e85847255eb4d9e6bbc" datatype="html">
+ <source>Includes information about daemon crashes:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1aa4306a6e840fe35b70c9b07d38ce85f281cfa" datatype="html">
+ <source>Type of daemon</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4f2cbedb4b14b68bc9f390e3391445c1b6682da" datatype="html">
+ <source>Version of the daemon</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d62603cdc75645ea873fc8f7f69c32b5f4a2aa9" datatype="html">
+ <source>Operating system (OS distribution, kernel version)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84facf84a73631d66e9a4e0bc1c40097b9d14742" datatype="html">
+ <source>Stack trace identifying where in the Ceph code the crash occurred</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea64d4177bd648e1a20c92669e6857762b811d8c" datatype="html">
+ <source>Device</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4bc37bcbbcea881a269b4063b3d93dec8ee67d5" datatype="html">
+ <source>Includes information about device metrics like anonymized SMART metrics.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37de70e8ba539187d0171a38dad2a63c323096eb" datatype="html">
+ <source>Ident</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b126025440f118cd02ce78362d61a5001c27617" datatype="html">
+ <source>Includes user-provided identifying information about the cluster:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62c6e9aecff7e04ef7d36fdee4ab4fb285a7a2b5" datatype="html">
+ <source>Contact Information</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61ba9a84051b3f470122e59cf5a746552b378269" datatype="html">
+ <source>Submitting any contact information is completely optional and disabled by default.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34746fb1c7f3d2194d99652bdff89e6e14c9c4f4" datatype="html">
+ <source>Contact</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="632cac1e025b77b2d77fed16ad22a410ddacab9e" datatype="html">
+ <source>My first Ceph cluster</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3a58c8a81b9ffda26a154eae25a422c9f7de37b" datatype="html">
+ <source>Organization</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e8fda44e2c5bb51860f26cd9c2730f9ae1db9869" datatype="html">
+ <source>Organization name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d49310535abb3792d8c9c991dd0d990d73d29af" datatype="html">
+ <source>Interval</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91317562c9dfefbdd5973faf11d217f571d073c7" datatype="html">
+ <source>The module compiles and sends a new report every 24 hours by default. You can adjust this interval by setting a different number of hours.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">185,186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a12cf4cf71ef3161a024382ab542cf0eba094504" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to 8.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a92e437fac14b4010c4515b31c55a311d026a57f" datatype="html">
+ <source>Proxy</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6de03357358c7eff62aca486508bb5c2046e0669" datatype="html">
+ <source>If the cluster cannot directly connect to the configured telemetry endpoint (default telemetry.ceph.com), you can configure a HTTP/HTTPS proxy server by e.g. adding https://10.0.0.1:8080</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5687a733af051bfca97dbffba282e39fbb9b8c8f" datatype="html">
+ <source>You can also include a user:pass if needed e.g. https://ceph:telemetry@10.0.0.1:8080</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e6430c68df43ea65e4145972b01186fba40f26a" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Note:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> By clicking 'Next' you will first see a preview of the report content before you can activate the automatic submission of your data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">219,220</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d8d878f8d60905e1306c225716305a331b784c8" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report preview</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e23d0064b6474f309c74e1c928cc0920f479d9a5" datatype="html">
+ <source>Report ID <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">249,252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4060e92658964e356a0992a900c8aa811c2cfec0" datatype="html">
+ <source>A randomized UUID to identify a particular cluster over the course of several telemetry reports.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60900bc663571f852a04950a123508b106d97204" datatype="html">
+ <source>Report preview <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">267,270</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3de417f739c336284c42904552e81e8d852daecc" datatype="html">
+ <source>The actual telemetry data that will be submitted.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="933a2b6f087670ff42c95876e6ecfb2faa3e3867" datatype="html">
+ <source>I agree to my telemetry data being submitted under the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Community Data License Agreement - Sharing - Version 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">304</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8293060085588842566" datatype="html">
+ <source>The Telemetry module has been configured and activated successfully.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5380636888677486786" datatype="html">
+ <source>An Error occurred while updating the Telemetry module configuration. Please Try again</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2bcd3296d2850de762fb943060b7e086a893181" datatype="html">
+ <source>Health</source>
+ <target>Zdrowie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61e0f26d843eec0b33ff475e111b0c2f7a80b835" datatype="html">
+ <source>Statistics</source>
+ <target>Statystyki</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73caac4265ea7314ff061e5a1d78a6361a6dd3b8" datatype="html">
+ <source>Cluster Status</source>
+ <target>Status klastra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="624f596cc3320f5e0a0d7c7346c364e5af9bdd8c" datatype="html">
+ <source>Monitors</source>
+ <target>Monitory</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9183778f2c6473d7ccb080f651caa01faaf70c" datatype="html">
+ <source>OSDs</source>
+ <target>OSD-ki</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c34287a0423968dac8a41463b80855a0ff789403" datatype="html">
+ <source>Managers</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="946ac5dea9921dc09d7b0a63b89535371f283b19" datatype="html">
+ <source>Object Gateways</source>
+ <target>Obiekty bram </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff03fa5bcf37c4da46ad736c1f7d03f959e8ba9a" datatype="html">
+ <source>Metadata Servers</source>
+ <target>Serwery metadanych</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d817609ba4993eba859409ab71e566168f4d5f5a" datatype="html">
+ <source>iSCSI Gateways</source>
+ <target>Bramy iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ce9dfdc6dccb28dc75a78c704e09dc18fb02dcfa" datatype="html">
+ <source>Capacity</source>
+ <target>Pojemność</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f383269db2d32cccee9e936fe549dccb9fdbf4" datatype="html">
+ <source>Raw Capacity</source>
+ <target>Pojemność rzędu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498a109c6e9e94f1966de01aa0326f7f0ac6fb52" datatype="html">
+ <source>PG Status</source>
+ <target>Status PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5f8a813f91a11af99132e4beafc136cfc13d73b" datatype="html">
+ <source>PGs per OSD</source>
+ <target>PG-y na OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32efd1c3f70e3c5244239de97a2cc95d98534a14" datatype="html">
+ <source>Client Read/Write</source>
+ <target>Odczyt/Zapis klienta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="52213660b2454d139ada3079a42ec6caf3c3c01e" datatype="html">
+ <source>Client Throughput</source>
+ <target>Przepustowość klienta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="275485415092cbae3a9f3cbb786ebe283cacfdd5" datatype="html">
+ <source>Recovery Throughput</source>
+ <target>Przepustowość odzyskiwania</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35416fcdf9cb33d2b299d3f2028c390454b55d02" datatype="html">
+ <source>Scrubbing</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="44ecac93d67c6a671198091c2270354f80322327" datatype="html">
+ <source><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> See <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>Logs<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for more details.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520247697658334435" datatype="html">
+ <source>Reads</source>
+ <target>Czyta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5947645586591788199" datatype="html">
+ <source>/s</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7527163811128350993" datatype="html">
+ <source>Writes</source>
+ <target>Pisze</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7684088941299429132" datatype="html">
+ <source>IOPS</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81585474102700882" datatype="html">
+ <source>Used</source>
+ <target>Użyty</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">179</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8695656831075719969" datatype="html">
+ <source>Avail.</source>
+ <target>Dostępny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6352596107300820129" datatype="html">
+ <source>Clean</source>
+ <target>Czyść</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4016774570903735270" datatype="html">
+ <source>Working</source>
+ <target>Działający</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4467323362722952678" datatype="html">
+ <source>Unknown</source>
+ <target>Nieznany</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">218</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7790772795962334429" datatype="html">
+ <source>Healthy</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4708847204147472247" datatype="html">
+ <source>Misplaced</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3120522496446378904" datatype="html">
+ <source>Degraded</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8047698491745405137" datatype="html">
+ <source>Unfound</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81117556780777231" datatype="html">
+ <source>objects</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795e8a00db46b750113d5db93e8d97e2b3079894" datatype="html">
+ <source>For an overview of <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/> widgets click <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">21,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16bd21c1b48036d54c6a595f5cff2540cfba7f60" datatype="html">
+ <source>here</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8515973702474791807" datatype="html">
+ <source>up</source>
+ <target>Podniesiony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4223604072115719661" datatype="html">
+ <source>no filesystems</source>
+ <target>brak systemów plików</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2078241808113697591" datatype="html">
+ <source>active</source>
+ <target>aktywny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3232506912392089107" datatype="html">
+ <source>standby</source>
+ <target>Rezerwa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576716133013765863" datatype="html">
+ <source>standby daemons</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3629620351427988554" datatype="html">
+ <source>active daemon</source>
+ <target>aktywny demon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5954854563228355745" datatype="html">
+ <source>standbyReplay</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7329683463736701292" datatype="html">
+ <source>n/a</source>
+ <target>niedostępny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/not-available.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8271970016544066882" datatype="html">
+ <source><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (quorum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mon-summary.pipe.ts</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6489441800790477240" datatype="html">
+ <source>total</source>
+ <target>Razem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5965118847182332588" datatype="html">
+ <source>near full</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="268166731974484199" datatype="html">
+ <source>full</source>
+ <target>pełny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47116253e36f4e38a97ba41b2d3122c6c15ab904" datatype="html">
+ <source>Clients (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5159814115056353668" datatype="html">
+ <source>Addresses</source>
+ <target>Adresy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1811797298582428088" datatype="html">
+ <source>Access Type</source>
+ <target>Typ dostępu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3575940435199094878" datatype="html">
+ <source>Squash</source>
+ <target>Squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2944102521023817891" datatype="html">
+ <source>Cluster</source>
+ <target>Klaster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91772203889648189" datatype="html">
+ <source>NFS Protocol</source>
+ <target>Protokół NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907766170797643122" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1032539711043211945" datatype="html">
+ <source>Transport</source>
+ <target>Transport</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2489852208080013495" datatype="html">
+ <source>Storage Backend</source>
+ <target>Pamięć Podręczna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8440421106569981118" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4095248496892792741" datatype="html">
+ <source>CephFS User</source>
+ <target>Użytkownik CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2535727951299201687" datatype="html">
+ <source>CephFS Filesystem</source>
+ <target>system plików CephFS </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2169401160512036026" datatype="html">
+ <source>Security Label</source>
+ <target>Etykieta bezpieczeństwa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3671149880069127721" datatype="html">
+ <source>Object Gateway</source>
+ <target>Dostęp obiektowy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1643028261508790" datatype="html">
+ <source>Object Gateway User</source>
+ <target>Użytkownik dostępu obiektowego</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2dae0bda66f6a349444951c0379c28cda47d6d1" datatype="html">
+ <source>Any client can access</source>
+ <target>Każdy klient ma dostęp</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7882f2edb1d4139800b276b6b0bbf5ae0b2234ef" datatype="html">
+ <source>Addresses</source>
+ <target>Adresy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f3f74c0f6925826cb2188576391c0da01a23f0" datatype="html">
+ <source>Must contain one or more comma-separated values</source>
+ <target>Musi zawierać jedną albo więcej ,rozdzielonych przecinkiem, wartości </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb5b2073697f3f4378c44a49b7524934c9268f4" datatype="html">
+ <source>For example:</source>
+ <target>Na przykład: </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f969c655b3fbe4fba7e277caf4cd2c459f9fca5" datatype="html">
+ <source>Access Type</source>
+ <target>Typ dostępu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28952831a284cfe2b4fc39ca610e80b52598905a" datatype="html">
+ <source>Squash</source>
+ <target>Squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0660ae339068979854ade34a96546980723dede3" datatype="html">
+ <source>Add clients</source>
+ <target>Dodaj klientów </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8571141481686087364" datatype="html">
+ <source>(inherited from global config)</source>
+ <target>(Odziedziczyło z globalnej konfiguracji)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3563954518111128118" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- Wybierz typ dostępu --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3802199399355755843" datatype="html">
+ <source>inherited from global config</source>
+ <target>Odziedziczyło z globalnej konfiguracji</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8729531250118136719" datatype="html">
+ <source>-- Select what kind of user id squashing is performed --</source>
+ <target>-- Wybierz, jakiego rodzaju identyfikacja użytkownika ma być przeprowadzana -- </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4d1dd59b039ad818d9da7e29a773e10e41d9821" datatype="html">
+ <source>Cluster</source>
+ <target>Klaster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="625f8f0f3e5b7c92651606d77484ff3d07b3c12b" datatype="html">
+ <source>This is the ID of an NFS Service.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="135b91a2d908d5814b782695470a6a786c99d9d2" datatype="html">
+ <source>-- No cluster available --</source>
+ <target>-- Brak dostępnego klastra -- </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c501dba379f566885919240ea277b5bc10c14d18" datatype="html">
+ <source>-- Select the cluster --</source>
+ <target>-- Wybierz klaster --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7bd3ad665c398c7fe97230ab59e67370653a82" datatype="html">
+ <source>This field is required. To create a new NFS cluster, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>add a new NFS Service<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">41,43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3f6ba7fe84d6508705cdfe234f0fcc8ff85c9cf" datatype="html">
+ <source>Storage Backend</source>
+ <target>Pamięć Podręczna</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6fee356d1db954255a56d8169405a89595246b9" datatype="html">
+ <source>-- Select the storage backend --</source>
+ <target>-- Wybierz pamięć podręczną -- </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3c2793dd2ef56954f872142d5ec1becb84c0fe1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="796e42bec8a6996607cf1f3e80235b86d695804a" datatype="html">
+ <source>Volume</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee3ba0ab5f0ccd597b3e44021c71e9aaad14df0a" datatype="html">
+ <source>-- No CephFS filesystem available --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="764c57812558b1ae66c5eec95d7efd2b1bf761e3" datatype="html">
+ <source>-- Select the CephFS filesystem --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="957512d0321f73e9f115bce1bd823fa635170c41" datatype="html">
+ <source>Security Label</source>
+ <target>Etykieta bezpieczeństwa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="65ce0fa4da1ed55e658aeb31d1644a29f06bb342" datatype="html">
+ <source>Enable security label</source>
+ <target>Uruchom etykietę bezpieczeństwa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e808f804130c7b6ff719509cbc06ebb27393a48" datatype="html">
+ <source>CephFS Path</source>
+ <target>Ścieżka CephFS </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1338c2f83e49ea7f2fc04e9fe90c5d330b7a10f" datatype="html">
+ <source>A path in a CephFS file system.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ecc0107badb6625466aaa3f975b5c05276f432f" datatype="html">
+ <source>Path need to start with a '/' and can be followed by a word</source>
+ <target>Ścieżka powinna zaczynać się z '/' i następne może być słowo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f9d8bd873c34c5ab2d4d0cf995fe5183ab25f6e" datatype="html">
+ <source>The path does not exist in the selected volume.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd197d7773cef10f368f08c53b47979c3df1f22d" datatype="html">
+ <source>Bucket</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ca90b4b16347ef7017967915e8624472976c85c" datatype="html">
+ <source>The bucket does not exist or is not in the default realm (if multiple realms are configured). To continue, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>create a new bucket<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bee6900143996c0e908a10564532eba3da0b30fb" datatype="html">
+ <source>NFS Protocol</source>
+ <target>Protokół NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5043c0921e709935ab026bb3253ffe1f159fca1" datatype="html">
+ <source>NFSv4</source>
+ <target>NFSv4</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d2c39708a32910f89701dd7e1cfb9ec1c195768" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1f8be2ae25947bec0b84c2338201580ea053f34e" datatype="html">
+ <source>The position that this <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> export occupies in the <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo FS<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (it must be unique).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">241,242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3af55f7fd5b1d9e5a53e030c80116dc635bfb9f" datatype="html">
+ <source>By using different Pseudo options, the same Path may be exported multiple times.</source>
+ <target>Używając różnych opcji Pseudo, ta sama Ścieżka może być wyeksportowana kilka razy.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5eb719aa900fed3f9d4a1d74bcc158f07f67f684" datatype="html">
+ <source>The pseudo is already in use by another export.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddf98fcdeeb17643db020d54f42b5e56b5f9a52a" datatype="html">
+ <source>Pseudo needs to start with a '/' and can't contain any of the following: &gt;, &lt;, |, &amp;, ( or ).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="27eb35c4b4ac08781a7253a2ab40f8f7d957ba51" datatype="html">
+ <source>-- No access type available --</source>
+ <target>-- Brak dostępnych typów dostępu --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">280</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="509ce016c9110a54028dafd741f15ceacbe74b5a" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- Wybierz typ dostępu --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67ce207d0b7eada1fe3d3187a39ba0c07be76b6c" datatype="html">
+ <source>The Object Gateway NFS backend has a number of limitations which will seriously affect applications writing to the share. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> for details before enabling write access.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">293,296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4deda03573eaaff77e63f6a238a1f0ca7816950a" datatype="html">
+ <source>-- No squash available --</source>
+ <target>- Brak squasha -</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">321</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a0e82a4da88e7fdf270444f838d45849676e9d4b" datatype="html">
+ <source>--Select what kind of user id squashing is performed --</source>
+ <target>-- Wybierz, jakiego rodzaju identyfikacja użytkownika ma być przeprowadzana --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d01b7c3f7f06712c53d054cfbe4f53d446b038e8" datatype="html">
+ <source>Transport Protocol</source>
+ <target>Protokół Transportu </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2a6ad6e8bc315f07911722c05767ac79c136d99" datatype="html">
+ <source>UDP</source>
+ <target>UDP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">349</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c030f11e0aae9b24d2c048c57f29f590be621df" datatype="html">
+ <source>TCP</source>
+ <target>TCP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">359</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f84d7fd4d52eb5b2229b632ef5119dac63d5597" datatype="html">
+ <source>No user id squashing is performed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">378</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb1d148107e36852325106a518385b1b0de28835" datatype="html">
+ <source>uid 0 and gid 0 are squashed to the Anonymous_Uid and Anonymous_Gid gid 0 in alt_groups lists is also squashed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">382</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1309d6f67955799863337b201413faa61a175ddb" datatype="html">
+ <source>uid 0 and gid of any value are squashed to the Anonymous_Uid and Anonymous_Gid alt_groups lists is discarded.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85f23d5c9b57dc78dda4150d13aa3b99e985350b" datatype="html">
+ <source>All users are squashed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2691935247101074756" datatype="html">
+ <source>NFS export</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8727258243239498387" datatype="html">
+ <source><x id="PH" equiv-text="fsalItem.descr"/> backend is not available. <x id="PH_1" equiv-text="errorMessage"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2772848515253260635" datatype="html">
+ <source>Error while retrieving paths.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5239928491238988595" datatype="html">
+ <source>Error while retrieving bucket names.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="734c9905951a774870497c5aaae8e3ee833b6196" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2190548d236ca5f7bc7ab2bca334b860c5ff2ad4" datatype="html">
+ <source>Object Gateway</source>
+ <target>Dostęp obiektowy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca53d681a9892d6fdbb57ee9676582186515e961" datatype="html">
+ <source>Performance counters not available</source>
+ <target>Liczniki wydajności nie są dostępne</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="490e15ecc922965b6d8194754c87c5583aa071f3" datatype="html">
+ <source>The name can only consist of alphanumeric characters, dashes and underscores.</source>
+ <target>Nazwa może składać się z alfanumerycznych znaków, kresek i podkreśleń.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9edc2b494e660618af3e5225f68d40b7ca67629c" datatype="html">
+ <source>The chosen erasure code profile name is already in use.</source>
+ <target>Wybrana nazwa profilu kodu kasowania jest już używana.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35a4206db3105ed03e0dd799e1642b75b78123e8" datatype="html">
+ <source>Root</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf425784c7073c7e7f7c1bb90c2c19db7e751db2" datatype="html">
+ <source>Failure domain type</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72396a9565cf644d1fe1b21b790c4243ee270986" datatype="html">
+ <source>Device class</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d80e0c07bfea1b693a33ef2245007de92a6780" datatype="html">
+ <source>Let Ceph decide</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101611937243846632" datatype="html">
+ <source>Crush Rule</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef9ff0e6227947b48dfab4ac39ade04af758913b" datatype="html">
+ <source>Plugin</source>
+ <target>Wtyczka</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd69b31bce8f630eac1d4762b0bbcf72ce19d193" datatype="html">
+ <source>Data chunks (k)</source>
+ <target>Ramka danych (k)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0d26a6172d32cb81218fe2103c54a818cbc1189" datatype="html">
+ <source>Must be equal to or greater than 2.</source>
+ <target>Musi być większa bądź równa 2.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ba6f4800642eba4e8b056aa7167554c3afa8db0" datatype="html">
+ <source>Chunks (k+m) have exceeded the available OSDs of <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="86fca2f788ce986eef835cd7ef8dfc9ae22447a4" datatype="html">
+ <source>For an equal distribution k has to be a multiple of (k+m)/l.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8dd4bc172f1adc4afadaec291e465b082909148d" datatype="html">
+ <source>K has to be equal to or greater than m in order to recover data correctly through c.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2e5b0e6d0dba31c59f946392699a0a6c4dd9b83" datatype="html">
+ <source>Distribution factor: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dab3a299ead121169b8e08ed618c3b6a2f66691b" datatype="html">
+ <source>Coding chunks (m)</source>
+ <target>Kodowanie kawałka (m)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e2773e5bd4948193f18f2361d663ecc3988c656" datatype="html">
+ <source>Must be equal to or greater than 1.</source>
+ <target>Musi być większa bądź równa 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">146</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cde4c945a49a260c0a47bcc7cd956846930a5f7" datatype="html">
+ <source>Durability estimator (c)</source>
+ <target>Estymator trwałości (c)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ec9ff9931f8ea1201792d6a01bf9a47b283d692" datatype="html">
+ <source>C has to be equal to or lower than m as m defines the amount of chunks that can be used.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35594fe66657ea07b5b5f560927f78e81a229996" datatype="html">
+ <source>Helper chunks (d)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0c250a8d281291273ed3504ade19ca6537e4d9a" datatype="html">
+ <source>Set d manually or use the plugin's default calculation that maximizes d.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4304a5cd95742db0f81c3bdf29aa96bf3b0ca13d" datatype="html">
+ <source>D is automatically updated on k and m changes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06a67d52427b12df2b3d439be0e1342ac72aeb5c" datatype="html">
+ <source>D can be set from <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> to <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4f8831d3bd6401e87710c4e3ee844f5efbf5de3" datatype="html">
+ <source>D can only be set to <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5d7aacffce2c6032c3ae9ef4d1b3847a926440b" datatype="html">
+ <source>D has to be greater than k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fd745d614884edc23c7ac9ad8aba9655f3793ac2" datatype="html">
+ <source>D has to be lower than k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>).</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">199</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af668c2a095a979ea2b4e43cd82c2120ab56c21c" datatype="html">
+ <source>Locality (l)</source>
+ <target>Lokalność (l)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="200fea08b63ae8d60cdbf33ffd2636159e87dc1e" datatype="html">
+ <source>Can't split up chunks (k+m) correctly with the current locality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319ac5d692d11da686782159bd70e0b705c228ed" datatype="html">
+ <source>Locality groups: <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">230</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d455a110bf6d2235e314e295ce1dfeee93d3dff2" datatype="html">
+ <source>Crush failure domain</source>
+ <target>Domena niepowodzenia Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74a495f041f7dd102eee5c0bbc9e03083b538ae" datatype="html">
+ <source>Crush Locality</source>
+ <target>Lokalność Crusha</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2f14a73f7a6e94479f67423cc51102da8d6f524" datatype="html">
+ <source>None</source>
+ <target>Nic</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="363a99d62822b92913a4cce196d47f32c1258e2f" datatype="html">
+ <source>Scalar mds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2981733b912b693a9dd9d915d6d34f4692cc874a" datatype="html">
+ <source>Technique</source>
+ <target>Technika</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0098b6e47b04ec817361f384ce81d454ba5c0bb" datatype="html">
+ <source>Packetsize</source>
+ <target>Rozmiar pakietu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0252cd81ca54d0a2f69ec9ccf4248e73df5aa4a" datatype="html">
+ <source>Crush root</source>
+ <target>korzeń Crusha</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">351</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1548d5c76f0406ddd1ba3c557e1e6db22e95b340" datatype="html">
+ <source>Crush device class</source>
+ <target>urządzenie klasy Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3f657ffa19dc6ac504b83c86209709522dcf065" datatype="html">
+ <source>Available OSDs: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03d84645f6e019c5a43909bbf2ea1696ee88332c" datatype="html">
+ <source>Directory</source>
+ <target>Katalog</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1354845268685595937" datatype="html">
+ <source>EC Profile</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3938a411d76796f8ae73b72ea4c77661207453bd" datatype="html">
+ <source>Cache Tiers Details</source>
+ <target>Szczegóły poziomów pamięci podręcznej</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="991790413700941336" datatype="html">
+ <source>Cache Mode</source>
+ <target>Tryb pamięci podręcznej</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9133265273798382582" datatype="html">
+ <source>Min Evict Age</source>
+ <target>Min wiek eksmisji</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7172092927403263656" datatype="html">
+ <source>Min Flush Age</source>
+ <target>Min wiek wyrównania </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8096695869347792608" datatype="html">
+ <source>Target Max Bytes</source>
+ <target>Max bajtów obiektu docelowego </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8854126142886240282" datatype="html">
+ <source>Target Max Objects</source>
+ <target>Max obiektów docelowych</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617215542453015899" datatype="html">
+ <source>No applications added</source>
+ <target>Nie dodano żadnego zastosowania</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4895689494338215646" datatype="html">
+ <source>Applications limit reached</source>
+ <target>Osiągnięto limit zastosowań </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7322343326526084293" datatype="html">
+ <source>A pool can only have up to four applications definitions.</source>
+ <target>Pul może mieć maksymalnie 4 definicje aplikacji. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1393735257943344790" datatype="html">
+ <source>Allowed characters '_a-zA-Z0-9'</source>
+ <target>Dozwolone znaki '_a-zA-Z0-9'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5520683885127790121" datatype="html">
+ <source>Maximum length is 128 characters</source>
+ <target>Maksymalna długość wynosi 128 znaków</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587418377972855060" datatype="html">
+ <source>Filter or add applications'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5188881899285829380" datatype="html">
+ <source>Add application</source>
+ <target>Dodaj zastosowanie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16e113230b6b0d3165e076300880542bac7c8138" datatype="html">
+ <source>The chosen Ceph pool name is already in use.</source>
+ <target>Wybrana nazwa Ceph pula jest już użyta.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c75b132bef7b29fa5171768303c4b96e34ccaf68" datatype="html">
+ <source>It's not possible to create an RBD pool with '/' in the name. Please change the name or remove 'rbd' from the applications list.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">34,35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="171dc6d5c6bc4615d99778b0088cae80fd00bd10" datatype="html">
+ <source>Pool name can only contain letters, numbers, '.', '-', '_' or '/'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b85c657469e5ec8231c3de99b22f437bc01ffde5" datatype="html">
+ <source>Pool type</source>
+ <target>Typ pula</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="526c5443254c3b126eedb264840ffe827727bfd3" datatype="html">
+ <source>-- Select a pool type --</source>
+ <target>-- Wybierz typ pula --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abfbe47b630929d93c7343dc154599c2e59330a" datatype="html">
+ <source>PG Autoscale</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0aa21053410a94aa61d16985a4e95fd65523430d" datatype="html">
+ <source>Placement groups</source>
+ <target>Grupa umieszczenia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6301f1391d726f8f450bb358058534db19541ca9" datatype="html">
+ <source>At least one placement group is needed!</source>
+ <target>Przynajmniej jedna grupa umieszczenia jest wymagana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba9469a1ce6ed36e039c1f67247c8c81a5c71449" datatype="html">
+ <source>Your cluster can't handle this many PGs. Please recalculate the PG amount needed.</source>
+ <target>Twój klaster nie obsługuje tylu PG. Skalkuluj proszę potrzebną ilość PG.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80ac68cd883369dac20688bc32b4cb33291b5e50" datatype="html">
+ <source>Calculation help</source>
+ <target>Pomoc obliczeniowa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fccbd60493df26705d957ed6c02a3c447894678f" datatype="html">
+ <source>The current PGs settings were calculated for you, you should make sure the values suit your needs before submit.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">116,117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a43b2695131b48b76cebba676aba98a2bee17515" datatype="html">
+ <source>Replicated size</source>
+ <target>Replikowany rozmiar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bff144a4c4dc63b0e18fff2617d61a7ebdf2b6c" datatype="html">
+ <source>Minimum: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9c54b41f6d58a74e5d0aa3429ed0c87a482551" datatype="html">
+ <source>Maximum: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="452cf71ec44ee77428656936a6627eaf2dd3b47f" datatype="html">
+ <source>The size specified is out of range. A value from <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> to <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/> is usable.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">144,145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dda6196ffab88c1825f44a565c7b34e246e7e12f" datatype="html">
+ <source>A size of 1 will not create a replication of the object. The 'Replicated size' includes the object itself.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">148,149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c870fb00256b8a5b9cb9cd1a124e6390b9bc639" datatype="html">
+ <source>EC Overwrites</source>
+ <target>EC Nadpisuje</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f1abafaeb40ce52355ddcc24686e3cd17b64e08a" datatype="html">
+ <source>Applications</source>
+ <target>Zastosowania</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9308b82fc183f710df60909f49cfc73aa5e076" datatype="html">
+ <source>CRUSH</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9de7dde00e2139cc4bd03b1837afbe72ad15a1ff" datatype="html">
+ <source>Erasure code profile</source>
+ <target>Skasuj profil kodu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39b4620e6bd444e0a57a0a5c03fa8c96d7fe5235" datatype="html">
+ <source>-- No erasure code profile available --</source>
+ <target>-- Brak profilu kasowania --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498561757390d5528b263ce450d5f38efb00266d" datatype="html">
+ <source>-- Select an erasure code profile --</source>
+ <target>-- Wybierz profil kodu wymazywania --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="616a2532fbaace94934f5943e381b63e2623f004" datatype="html">
+ <source>This profile can't be deleted as it is in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="994363f08f9fbfa3b3994ff7b35c6904fdff18d8" datatype="html">
+ <source>Profile</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="023d6f718770d2ea4ab8cabe26b0ec27ef967ec2" datatype="html">
+ <source>Used by pools</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">387</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1061ba5ee07a5c6af09e09330dbc29201baf2aa" datatype="html">
+ <source>Profile is not in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33150f22ce5348aa6c499bd092c3f4f3695d62cc" datatype="html">
+ <source>Crush ruleset</source>
+ <target>zbiór zasad Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">293</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">303</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c69b0bcd4698aa845d32c4c4ad488492552cb469" datatype="html">
+ <source>A new crush ruleset will be implicitly created.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="896e9987db5e9bb279e6deed5d2dff28c242ef66" datatype="html">
+ <source>There are no rules.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73a6b31116b3cc322af951daa0bafdc169e6c42e" datatype="html">
+ <source>-- Select a crush rule --</source>
+ <target>-- Wybierz zasadę Crush --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7d4894e770f8853050b1f6dd55bdd77a51a8ac6" datatype="html">
+ <source>Placement and
+ replication strategies or distribution policies that allow to
+ specify how CRUSH places data replicas.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">328,330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea91d648f92002bc9f96d9b26b735c83ca0b53c6" datatype="html">
+ <source>This rule can't be deleted as it is in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">346</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92da80699921e89fb19372e25b8d0f3b9fa427fc" datatype="html">
+ <source>Crush rule</source>
+ <target>zasada Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">365</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5489e9f96835f469f6f728a00d8efa88ea5bc940" datatype="html">
+ <source>Crush steps</source>
+ <target>Kroki Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc5f5496a9e50fe69e1a09784f28d94944108294" datatype="html">
+ <source>Rule is not in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="104a0e6900d1d1b0c8cf9e5947e36edb352583fc" datatype="html">
+ <source>The rule can't be used in the current cluster as it has too few OSDs to meet the minimum required OSD by this rule.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">409,410</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2208d63d5940ce656006a220102b1eb2b5e553da" datatype="html">
+ <source>Compression</source>
+ <target>Kompresja</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">420</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c6f25c47da62ec597c6057a36ddfc3209811ec5" datatype="html">
+ <source>Algorithm</source>
+ <target>Algorytm</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">444</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4903231d42089325a28892c0fde1aed46b733ae6" datatype="html">
+ <source>-- No erasure compression algorithm available --</source>
+ <target>-- Brak algorytmu kompresji wymazywania --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d68ddb254275f8f44221e9ad6d8ceeb59ca46a6" datatype="html">
+ <source>Minimum blob size</source>
+ <target>Minimalny rozmiar blob</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">468</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb2f176df80647137cbb02bbeb29e5dec707a400" datatype="html">
+ <source>e.g., 128KiB</source>
+ <target>np. 128 KB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">477</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b7f6e53a4521c6eb3ced4c007fdd4cf80bb7707" datatype="html">
+ <source>Value should be greater than 0</source>
+ <target>Wartość powinna być większa niż 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">482</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">506</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8db98ab14b4e207ec763dfdefbc2dae367aab1cc" datatype="html">
+ <source>Value should be less than the maximum blob size</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151efb127a9a4dd25259a0b2055442318a141f5b" datatype="html">
+ <source>Maximum blob size</source>
+ <target>Maksymalny rozmiar blob</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c656f0e346bbadf46eb1a5d20d0307a3bd20ba8" datatype="html">
+ <source>e.g., 512KiB</source>
+ <target>np. 512 KB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65a24eee8a026f3b1113fe9e157e9a0dd69486" datatype="html">
+ <source>Value should be greater than the minimum blob size</source>
+ <target>Wartość powinna być większa niż minimalny rozmiar blob</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">509</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="261ba09c4a59de83f48f52a23fd328da37e61ff4" datatype="html">
+ <source>Ratio</source>
+ <target>Stosunek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">517</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1430457a9c3c66366e51d76bf10396014c576be" datatype="html">
+ <source>Compression ratio</source>
+ <target>Skompresowany stosunek</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">528</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae5ce6de352cde949998fb10754459c3a4eb183b" datatype="html">
+ <source>Value should be between 0.0 and 1.0</source>
+ <target>Wartość powinna być pomiędzy 0.0, a 1.0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d99b34162c9c34f10d0ccd8dbae83d8569c2db77" datatype="html">
+ <source>Max bytes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">546</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1d14a18879c62f3f4ed705318b7164a1160e249" datatype="html">
+ <source>Leave it blank or specify 0 to disable this quota.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">572</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7565b131562ff6c5f769fdbd239a772154abdd97" datatype="html">
+ <source>A valid quota should be greater than 0.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">550</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">574</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b8bf35b66f09a301eef92ffc3cb2fd259df67ce9" datatype="html">
+ <source>Max objects</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">570</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="95f348167622d832c5ae532b6944635c8e2ae5cb" datatype="html">
+ <source>The value should be greater or equal to 0</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">586</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1088629182722162774" datatype="html">
+ <source>pool</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6215593782779198370" datatype="html">
+ <source>erasure code profile</source>
+ <target>skasuj profil kodu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4390273881304618317" datatype="html">
+ <source>crush rule</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">721</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d8a7c8aea58294a3c57c23af0468ddf0ba0c9c7" datatype="html">
+ <source>Pools List</source>
+ <target>Lista puli</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9055665654201606988" datatype="html">
+ <source>Data Protection</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6658000829978978023" datatype="html">
+ <source>Applications</source>
+ <target>Zastosowania</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5232365108332422324" datatype="html">
+ <source>PG Status</source>
+ <target>Status PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1669788723782899084" datatype="html">
+ <source>Crush Ruleset</source>
+ <target>Zbiór zasad Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7961062124768120122" datatype="html">
+ <source>Pool deletion is disabled by the mon_allow_pool_delete configuration setting.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee5132a8da30e0b7f9f5c70dbc91928d17dd909" datatype="html">
+ <source>Owner</source>
+ <target>Właściciel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c51963a9c553b29427ef783bbb69fa6634fa8c" datatype="html">
+ <source>Index type</source>
+ <target>Typ indeksu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e6f950a32eaea32ec7e192f9ca3d3dfe469d4ba" datatype="html">
+ <source>Placement rule</source>
+ <target>Zasada umieszczania</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6972d213e31c4ea4f887e60db99d9881bc8fcd3e" datatype="html">
+ <source>Marker</source>
+ <target>Znacznik</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47b02acd2d3254d1ace1926f840523f154ebef71" datatype="html">
+ <source>Maximum marker</source>
+ <target>Maksymalny znacznik</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="092fa3a7df9168b14d3f83a77a4035e92b92ce15" datatype="html">
+ <source>Master version</source>
+ <target>Główna wersja</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97434cc5001d407f90c7447a12d9e8e6848a2aa3" datatype="html">
+ <source>Modification time</source>
+ <target>Czas modyfikacji</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90fe2e41e7fde38453ce4e619efeea9bc6adea9c" datatype="html">
+ <source>Zonegroup</source>
+ <target>Strefa </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="efeade5060b3add63863c24871f0830fb16b7e6d" datatype="html">
+ <source>Versioning</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62a923f047ca49e7a4782629e91fea1ba32db68f" datatype="html">
+ <source>MFA Delete</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="649a410bd0ace333d067d8fa22f12bdbdb43533b" datatype="html">
+ <source>Bucket quota</source>
+ <target>kontyngent wiadra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">567</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f50a33d3c339f8f4a465141f8caa5d2d8c005251" datatype="html">
+ <source>Enabled</source>
+ <target>Uaktywniony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">579</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cef1595d040e77cbb4466e60382028d4c2040cac" datatype="html">
+ <source>Maximum size</source>
+ <target>Maksymalny rozmiar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa6fb95c355f172bda303de1ce2f38c251a149cf" datatype="html">
+ <source>Unlimited</source>
+ <target>Nielimitowany</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee862a800364b4d11f9b8cb9955a28a60f840a45" datatype="html">
+ <source>Maximum objects</source>
+ <target>Maksimum obiektów</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b84370895ab9eb44672f57146fa05c5947f1c0c" datatype="html">
+ <source>Locking</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c3d9d2296f7886e8289b9f623323803deacfc6" datatype="html">
+ <source>Days</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f44bdf9ab00a973bbe482e9fc450e3f67e60c0d" datatype="html">
+ <source>Bucket names can only contain lowercase letters, numbers, periods and hyphens.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eabb4db920d9f9b2480cf438468b86e1bea02a9b" datatype="html">
+ <source>The chosen name is already in use.</source>
+ <target>Wybrana nazwa już jest użyta.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b06de7f834c622197e68b66a2abe893040b174c4" datatype="html">
+ <source>Bucket names must not contain uppercase characters or underscores.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abacf4af2f66d3af08c5ebe502b21b1f42ac649" datatype="html">
+ <source>Each label must start and end with a lowercase letter or a number.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a7f52e6813e0535026f61a2d6e8adc8a1d006a" datatype="html">
+ <source>Bucket names cannot be formatted as IP address.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2a2460396d35e14e7acfb4e060196a0679bdcff" datatype="html">
+ <source>Bucket labels cannot be empty and can only contain lowercase letters, numbers and hyphens.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf5c849977e0be2dbfc862d044edd323bfd9fb77" datatype="html">
+ <source>Bucket names must be 3 to 63 characters long.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e4c918357c7445fbf19a203e5f0f0ece1960b3b" datatype="html">
+ <source>-- Select a user --</source>
+ <target>-- Wybierz użytkownika -- </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4aab1f837bc8ec222e4f25922465d1c5929a1fc" datatype="html">
+ <source>Placement target</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bae0a7fc2c9c1fde7d937a8a1a3c7e6825cf7d1" datatype="html">
+ <source>-- Select a placement target --</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="016d24e069e7d505a090fb8243e5cd43b35dc39b" datatype="html">
+ <source>Enables versioning for the objects in the bucket.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">151</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e6775ffd06878aa145c07359f28557f01ede04f" datatype="html">
+ <source>Multi-Factor Authentication</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29e8a5d4fb767d4ad0c762c81c6264cec4c0ba97" datatype="html">
+ <source>Delete enabled</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40fbc3ac8c1ea4ecfe62247e91f1f999ad5baf76" datatype="html">
+ <source>Enables MFA (multi-factor authentication) Delete, which requires additional authentication for changing the bucket versioning state.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24c93a8c13db46defa06ed7b5e026a3edb52b91" datatype="html">
+ <source>Token Serial Number</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6d9536c2af2e5e9a228c3e3e1809dc1fefe0149" datatype="html">
+ <source>Token PIN</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f038d51ab1645f15b0cd58f195c72a7eeebd4729" datatype="html">
+ <source>Enables locking for the objects in the bucket. Locking can only be enabled while creating a bucket.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9af1b4baa2dd8ed2bfc3cc756b12a2271c2dd793" datatype="html">
+ <source>Compliance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="edd600fa489d1b4a4448dce694ed932e52ce8fda" datatype="html">
+ <source>Governance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="218c7d6d318c51e7105309aaeb0baec9d19e4efb" datatype="html">
+ <source>The number of days that you want to specify for the default retention period that will be applied to new objects placed in this bucket.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">264</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="289b101ec12427b3ca819df9e43cc3b14fae2cc4" datatype="html">
+ <source>The entered value must be a positive integer.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48d8247c1ba2ea156109bf286c5f6dd26b4be760" datatype="html">
+ <source>Retention Days must be a positive integer.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4349284625269221231" datatype="html">
+ <source>bucket</source>
+ <target>wiadro</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6161088322338624846" datatype="html">
+ <source>Updated Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218632328857697292" datatype="html">
+ <source>Created Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c338bae89822d7eefbc9a887c458a7d8a98e55e" datatype="html">
+ <source>No Limit</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3715596725146409911" datatype="html">
+ <source>Owner</source>
+ <target>Właściciel</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5545511293826600258" datatype="html">
+ <source>Used Capacity</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1925090152473969054" datatype="html">
+ <source>Capacity Limit %</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8713861779825116442" datatype="html">
+ <source>Object Limit %</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5913880066213114620" datatype="html">
+ <source>buckets</source>
+ <target>Wiadra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eeba399c4dae8d4890c27b7a2cd2dc28fcf8b5f9" datatype="html">
+ <source>Performance Counters</source>
+ <target>Liczniki wydajności</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="479488ab6e91ecb375484edc78bee3d13467f33f" datatype="html">
+ <source>Daemons List</source>
+ <target>Lista demonów</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca2dee83bb58290d93fb0d17ee8bc9f095a4576f" datatype="html">
+ <source>Sync Performance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4378147649219625174" datatype="html">
+ <source>Zone</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6148052126949932311" datatype="html">
+ <source>Zone Group</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3840481991104643295" datatype="html">
+ <source>Realm</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1221ca97d19eaa9a7bc0c5243d5fc5befe1d2314" datatype="html">
+ <source>-- Select a type --</source>
+ <target>-- wybierz typ --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1b8990332af18f1c5159a6061ca889bcbb28432" datatype="html">
+ <source>Permission</source>
+ <target>Pozwolenie </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a08c589f82f69d892307288da14190ae1dd583d5" datatype="html">
+ <source>-- Select a permission --</source>
+ <target>-- Wybierz pozwolenie --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7345972049922682356" datatype="html">
+ <source>capability</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a94e6b2b5b834d92cceb90037d51ad6165c8b619" datatype="html">
+ <source>Tenant</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
+ <source>User ID</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b760f123248930122fc7e7b6b6bf94e376e959c8" datatype="html">
+ <source>Full name</source>
+ <target>Pełne imię </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69b6ac577a19acc39fc0c22342092f327fff2529" datatype="html">
+ <source>Email address</source>
+ <target>Adres email</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92f3f203270a29b3001871153f02c063484a1574" datatype="html">
+ <source>Suspended</source>
+ <target>Zawieszony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011e20c5bbe51602d459a860fbf29b599b55edd" datatype="html">
+ <source>System</source>
+ <target>System</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db18a2772988415466a7f75dc42663ce78c9c1d3" datatype="html">
+ <source>Maximum buckets</source>
+ <target>Maksimum wiader</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c4c62e8ba24601be5cfe7dc5d32c24bbbd4b53c" datatype="html">
+ <source>Subusers</source>
+ <target>pod-użytkownicy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17bb3082e6fe5003203ef992a3714172334631a1" datatype="html">
+ <source>Capabilities</source>
+ <target>Zdolności</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32f8a0570373cacb9c56cf227502483a29d605bc" datatype="html">
+ <source>MFAs(Id)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36ad38f9c1a1485e09b67778a28af84553290ffb" datatype="html">
+ <source>User quota</source>
+ <target>Limit użytkownika</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">473</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0bcd5ef19af0f1b814141ca8c57df623d8270088" datatype="html">
+ <source>Keys</source>
+ <target>Klucze</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2aba1e87039819aca3b70faa9aa848c12bf139ca" datatype="html">
+ <source>Show</source>
+ <target>Pokaż</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">395</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5248717555542428023" datatype="html">
+ <source>Username</source>
+ <target>Nazwa użytkownika</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240806681889331244" datatype="html">
+ <source>Unlimited</source>
+ <target>Nielimitowany</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db4e1a734518691b128ef40b939cc673f01d03a6" datatype="html">
+ <source>The value is not valid.</source>
+ <target>Wartość nie jest poprawna.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">617</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6aaf5d2a304167272ac73e3b1d1c162e16c77858" datatype="html">
+ <source>The chosen user ID is already in use.</source>
+ <target>Wybrane ID użytkownika jest już użyte.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="025be1d01b2f6cbd09e772a1d3de02fab0678b26" datatype="html">
+ <source>Show Tenant</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6af106b0d759fd2882e645604675c4494abfcd5b" datatype="html">
+ <source>The chosen user ID exists in this tenant.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="df441e80db2157f9d272b75de724ba4a82b96b57" datatype="html">
+ <source>This is not a valid email address.</source>
+ <target>Ten adres email nie jest poprawny.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca271adf154956b8fcb28f4f50a37acb3057ff7c" datatype="html">
+ <source>The chosen email address is already in use.</source>
+ <target>Wybrany adres email jest już użyty.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="030197cebe938edf35422e92fe14183d06eb670b" datatype="html">
+ <source>Max. buckets</source>
+ <target>Max. wiader </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f39256070bfc0714020dfee08895421fc1527014" datatype="html">
+ <source>Disabled</source>
+ <target>Wyłączony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c05002b0ac2040f1aede5e727e0ffd06eda819" datatype="html">
+ <source>Custom</source>
+ <target>Zwyczaj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28872515cb81d197a3a1733fa546d3e0f0dd6c67" datatype="html">
+ <source>The entered value must be &gt;= 1.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="583a219c524155c2314eb06ee29162bb315272a3" datatype="html">
+ <source>S3 key</source>
+ <target>klucz S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c217ee914725a37e9dd2336c721c8e63e9666bdc" datatype="html">
+ <source>Auto-generate key</source>
+ <target>Auto-generowany klucz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f1c1c0f2bce4c9f92d1a2061e8161cb0006c31a" datatype="html">
+ <source>Access key</source>
+ <target>Klucz dostępu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b864acb67296a9819c1db0069c4c47d8b5ce8f44" datatype="html">
+ <source>Secret key</source>
+ <target>Tajny klucz </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="128d6efb51d9ddc7c0cc695a2deeca5b9523f6e4" datatype="html">
+ <source>There are no subusers.</source>
+ <target>Nie ma pod-użytkowników.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fd6dfb8ecb982dbc3affb2c2d5414c4f5b6abd2" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">294,295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67c746c1ba9dab4351fedc4c7cba4e6d6b0dbc47" datatype="html">
+ <source>S3</source>
+ <target>S3 (prosty serwis przechowywania) </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d6819038d608623503918fb2553f53d68231ec3a" datatype="html">
+ <source>There are no keys.</source>
+ <target>Nie ma kluczy.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">377</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc1c1a7140ff6b815a95b65ee2780fdbe1b2b7a1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">356,357</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6ddb5e991a3ecd2659fb520bc5acc81b67e08ddd" datatype="html">
+ <source>Swift</source>
+ <target>Szybki</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">371</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d01eccdda47fc907c5be35bcb16d2dcd02b0270" datatype="html">
+ <source>There are no capabilities.</source>
+ <target>Nie ma zdolności. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5a451c4ea65a4046f0b49d489a7013abf0b5861" datatype="html">
+ <source>All capabilities are already added.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">456</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="043e2ec0036ceadd926fd5e3f93cd6f3565f3648" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">461,462</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6146e13ceca5fa5cc17b771b282fe5955f3d19fa" datatype="html">
+ <source>Unlimited size</source>
+ <target>Nielimitowany rozmiar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">595</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6db8aa7c99fdce18edb33dde57729acede2b308" datatype="html">
+ <source>Max. size</source>
+ <target>Max. rozmiar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">511</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">605</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc630b2093e880fffa19df99d5cd8b87605037f8" datatype="html">
+ <source>Unlimited objects</source>
+ <target>Nielimitowane obiekty</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cda5a993d06f0bb10048be9d3aba6555aa9f356" datatype="html">
+ <source>Max. objects</source>
+ <target>Max. obiektów</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">642</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="623ac50f37a26caec6fd7cd519b653e3315cba25" datatype="html">
+ <source>The entered value must be &gt;= 0.</source>
+ <target>Podana wartość musi być &gt;= 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">654</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="123010868147850959" datatype="html">
+ <source>user</source>
+ <target>użytkownik</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8368421344177343441" datatype="html">
+ <source>subuser</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4662015204945271252" datatype="html">
+ <source>S3 Key</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9103468069826049692" datatype="html">
+ <source>Updated Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="884841609901737584" datatype="html">
+ <source>Created Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4363143805416924501" datatype="html">
+ <source>Tenant</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8301535046747035390" datatype="html">
+ <source>Full name</source>
+ <target>Pełne imię </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3967269098753656610" datatype="html">
+ <source>Email address</source>
+ <target>Adres email</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5851424994801012357" datatype="html">
+ <source>Suspended</source>
+ <target>Zawieszony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208300173682032371" datatype="html">
+ <source>Max. buckets</source>
+ <target>Max. wiader </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1670306451865226564" datatype="html">
+ <source>users</source>
+ <target>użytkownicy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c614babd1950adb2be75df4e2c9747286d6adc" datatype="html">
+ <source>-- Select a username --</source>
+ <target>-- Wybierz nazwę użytkownika -- </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2841767821d6b66238c34d07e413b0af67aee92" datatype="html">
+ <source>Subuser</source>
+ <target>pod-użytkownik</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd59fc25a7bd98cff3e75117c09697c8a007a514" datatype="html">
+ <source>The chosen subuser ID is already in use.</source>
+ <target>Wybrane ID pod-użytkownika jest już użyte.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d386c357ebcbc04ed05c4babd5a03626f9b1674" datatype="html">
+ <source>read, write</source>
+ <target>odczyt, zapis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84e3e3f9a4f31a039b648c97debf95fcb20f4c4a" datatype="html">
+ <source>full</source>
+ <target>pełny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6bf81d032a2316464f9df2f0d2f3d753f89f0d3" datatype="html">
+ <source>Swift key</source>
+ <target>Szybki klucz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e0c12685d50d47448ceed9423977ef39775c037" datatype="html">
+ <source>Auto-generate secret</source>
+ <target>Auto-generowany sekret</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5091031285775138345" datatype="html">
+ <source>Subuser</source>
+ <target>pod-użytkownik</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8453697749389230205" datatype="html">
+ <source>Swift Key</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ac54c18c1b520e948095c83a3a1025f02ce6dcc6" datatype="html">
+ <source>Neither hostname nor OSD ID given</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4533150758393178756" datatype="html">
+ <source>Device ID</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1291053608320944146" datatype="html">
+ <source>State of Health</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29167121133682512" datatype="html">
+ <source>Good</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8767957606064036733" datatype="html">
+ <source>Bad</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8052456228079338924" datatype="html">
+ <source>Stale</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6223439643831041743" datatype="html">
+ <source>Life Expectancy</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3144481541623761279" datatype="html">
+ <source>Prediction Creation Date</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="264574868375698540" datatype="html">
+ <source>Device Name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1419569261746199221" datatype="html">
+ <source>Daemons</source>
+ <target>Demony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f635b3cb0600409a2ad44a5bd1863c699e6a01c" datatype="html">
+ <source>Failed to retrieve SMART data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a8a3f354bd640299068edd912f4bb5325264f250" datatype="html">
+ <source>The data received has the JSON format version 2.x and is currently incompatible with the dashboard.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="04f8a3c7e8ac610e6581960162cc15f55a16696a" datatype="html">
+ <source>No SMART data available.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a185c9b97513b3882604ea9bab60edbfac945c15" datatype="html">
+ <source>SMART overall-health self-assessment test result</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="290e4c9ad42dc6e9176656c864a5faed8053f406" datatype="html">
+ <source>unknown</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a03d3c2e459f8f8fa7202c0fce465d6165f9e2b" datatype="html">
+ <source>passed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41435d5a5692c8e412c74deaee95d99dbd3617e1" datatype="html">
+ <source>failed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddd5dd6d930030096ea617f62c82b648a0dd9484" datatype="html">
+ <source>Device Information</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e149c483d88cfcff11d1c5db85e84af7c3149c4" datatype="html">
+ <source>No device information available for this device.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20cb12827cbe559a7b1da6fdae96041b3b5c3c55" datatype="html">
+ <source>SMART</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380295f37caea93701d071485a38ef0bdba57133" datatype="html">
+ <source>No SMART data available for this device.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5758c3f16f8749f0f4e2a787f02e8b4da246102f" datatype="html">
+ <source>SMART data is loading.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5363861031080361352" datatype="html">
+ <source>Smartctl has received an unknown argument (error code <x id="PH" equiv-text="smartData.smartctl_error_code"/>). You may be using an incompatible version of smartmontools. Version &gt;= 7.0 of smartmontools is required to successfully retrieve data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">61,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5085718566932809950" datatype="html">
+ <source>An error with error code <x id="PH" equiv-text="smartData.smartctl_error_code"/> occurred.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2091295268977103253" datatype="html">
+ <source>Raw</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5963653123239768443" datatype="html">
+ <source>Threshold</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2893124970059125090" datatype="html">
+ <source>When Failed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5614367840516299633" datatype="html">
+ <source>Worst</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d06ae77f9ec46a4cdd49e7e76c73a411aaf2ee38" datatype="html">
+ <source>Please set a new password.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8b5b3566e88438f51bd5f6caf6c090ed565ba5ed" datatype="html">
+ <source>You will be redirected to the login page afterwards.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cf42e491adc166a337a960eb84d03c0c3f677c8" datatype="html">
+ <source>The old and new passwords must be different.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90163a3d3746819aef42e829f4446331232f3b66" datatype="html">
+ <source>Password confirmation doesn't match the new password.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0070e83d11da39d6f4bb95065c2675db1610b419" datatype="html">
+ <source>Username is required</source>
+ <target>Nazwa użytkownika jest wymagana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e20f8b8a4706526c9024cc2f39d568345d100dc" datatype="html">
+ <source>Password is required</source>
+ <target>Hasło jest wymagane.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f093d9574ab746b231504bd2cbb65f04bd7b00db" datatype="html">
+ <source>Log in</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5590086849807274701" datatype="html">
+ <source>Scope</source>
+ <target>Zakres</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327592562693301723" datatype="html">
+ <source>Read</source>
+ <target>Czytaj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5674286808255988565" datatype="html">
+ <source>Create</source>
+ <target>Stwórz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4021752662928002901" datatype="html">
+ <source>Update</source>
+ <target>Zaktualizuj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022070615528435141" datatype="html">
+ <source>Delete</source>
+ <target>Usuń</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ea5c4d8942c00752dcc72e72949c5d9832f6399" datatype="html">
+ <source>Description...</source>
+ <target>Opis...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70f45880fce6ac5d8e468e25e82aefbba8098cfe" datatype="html">
+ <source>Permissions</source>
+ <target>Pozwolenia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="122114774689391224" datatype="html">
+ <source>role</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616102757855967475" datatype="html">
+ <source>All</source>
+ <target>Wszystkie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4416727401284087008" datatype="html">
+ <source>Created role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3472946357042916911" datatype="html">
+ <source>Updated role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="373024661645814027" datatype="html">
+ <source>System Role</source>
+ <target>System roli </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753648234171918096" datatype="html">
+ <source>Deleted role '<x id="PH" equiv-text="role"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1674202514578558795" datatype="html">
+ <source>New name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4857700187193019038" datatype="html">
+ <source>Clone Role</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="748631939386170157" datatype="html">
+ <source>Cloned role '<x id="PH" equiv-text="values['newName']"/>' from '<x id="PH_1" equiv-text="name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="195c31a2f970e790231a6bb94a5e8ca0167406d9" datatype="html">
+ <source>The username already exists.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f3bdcce4b2e8c37cd7f0f6c92ef8cff34b039b8" datatype="html">
+ <source>Confirm password</source>
+ <target>Potwierdź hasło</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cbb979e63ba50e0ca3adfa09cbdcaefd0853fca1" datatype="html">
+ <source>Password confirmation doesn't match the password.</source>
+ <target>Potwierdzające hasło nie pokrywa się z hasłem.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="96621f9ed2e4ae5204564e583d2c816bedead571" datatype="html">
+ <source>Password expiration date</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48932db3801fe9d5d72a60a3e656bffd17c1c5d9" datatype="html">
+ <source>Password expiration date...</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc" datatype="html">
+ <source>Email</source>
+ <target>Email</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d0ec081dd61eb4f43aea269077bbe38eae87b7f9" datatype="html">
+ <source>Invalid email.</source>
+ <target>Niepoprawny email.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9610487cbeb5796d34d8601b5ac0c0a65f9e1d19" datatype="html">
+ <source>Roles</source>
+ <target>Role</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8913c216dd506e20e412e144381d8d2a65a84359" datatype="html">
+ <source>User must change password at next logon</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0051a3479d3ba79135c16dc8cc017950a2cce821" datatype="html">
+ <source>You are about to remove &quot;user read / update&quot; permissions from your own user.</source>
+ <target>Zamierzasz usunąć uprawnienia „odczytu / aktualizacji użytkownika” od własnego użytkownika.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af4bf9fcb256853f14cf947eb1deb8d7f176d3f9" datatype="html">
+ <source>If you continue, you will no longer be able to add or remove roles from any user.</source>
+ <target>Jeśli kontynuujesz, nie będziesz mógł dodawać albo usuwać role od użytkowników.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314291969883771319" datatype="html">
+ <source>There are no roles.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4306072924538089180" datatype="html">
+ <source>Created user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1349763489797682899" datatype="html">
+ <source>Update user</source>
+ <target>Zaktualizuj użytkownika</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8688396456017237992" datatype="html">
+ <source>You were automatically logged out because your roles have been changed.</source>
+ <target>Zostałeś automatycznie wylogowany, ponieważ zostały zmienione twoje role.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2335813072344088607" datatype="html">
+ <source>Updated user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4768749765465246664" datatype="html">
+ <source>Email</source>
+ <target>Email</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795890916060309463" datatype="html">
+ <source>Roles</source>
+ <target>Role</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6877445485286599988" datatype="html">
+ <source>Password expiration date</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="705657168061753072" datatype="html">
+ <source>Deleted user '<x id="PH" equiv-text="username"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="405819296611088743" datatype="html">
+ <source>Failed to delete user '<x id="PH" equiv-text="username"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8935387756949610047" datatype="html">
+ <source>You are currently logged in as '<x id="PH" equiv-text="username"/>'.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0eb15f32b2b92d7f3103ef3ff032621888a8dc32" datatype="html">
+ <source>Old password</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229" datatype="html">
+ <source>New password</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ede41f01c781b168a783cfcefc6fb67d48780d9b" datatype="html">
+ <source>Confirm new password</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809196861118879526" datatype="html">
+ <source>password</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623124197136601291" datatype="html">
+ <source>Updated user password&quot;</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be" datatype="html">
+ <source>Users</source>
+ <target>Użytkownicy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ced3246fa3db31be0f7da06648463f29ba378fbe" datatype="html">
+ <source>Selected Object Gateway:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c53062af97ebda2a03f905698f58e524ecf8b968" datatype="html">
+ <source>Select Object Gateway</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="235c355afdcbf72953a15d7fc8d0d9e7a6619f46" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Page not Found<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aee9d027170f84774f2980537556f5099369b82" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for. The page you requested may have been changed or moved.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">22,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2b46fe9a975c6531af77fee858ccd37327980f7" datatype="html">
+ <source>Please consult the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>documentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> on how to configure and enable the <x id="INTERPOLATION" equiv-text="{{ section_info }}"/> management functionality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">26,27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9d57ca7cab78c6f0d27e0d890cb8cf1515e4e30a" datatype="html">
+ <source>Go To Dashboard</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6578397717654172779" datatype="html">
+ <source>Page Not Found</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8185335715884155108" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for.
+ The page you requested may have been changed or moved.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="143318366100741906" datatype="html">
+ <source>Access Denied</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5384670299771400832" datatype="html">
+ <source>Sorry, you don’t have permission to view this page or resource.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2424411274809083521" datatype="html">
+ <source>User Denied</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7645004872908092358" datatype="html">
+ <source>Sorry, the user does not exist in Ceph.
+ You'll be logged out from the Identity Provider when you retry logging in.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">24,25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f286db6ac9482dbf567bc491d49a6eade444895a" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7911416166208830577" datatype="html">
+ <source>Help</source>
+ <target>Pomoc</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8878700331247603166" datatype="html">
+ <source>Security</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8642696205489749843" datatype="html">
+ <source>Trademarks</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1481ecd21e760ac919a24e26cf790acd82e40199" datatype="html">
+ <source>Dashboard Settings</source>
+ <target>Ustawienia Pulpitu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a79aab4ef674bf3f6532292107c0054302236e0f" datatype="html">
+ <source>User management</source>
+ <target>Zarządzanie użytkownikami</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="197e0246502ca64d0de0df0d5c2deec51d41ff45" datatype="html">
+ <source>Telemetry configuration</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85b79c9064aed1ead31ace985f31aa1363f6bdaf" datatype="html">
+ <source>Help</source>
+ <target>Pomoc</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06638e0f01d82c0786f63aa9832fbe7866b86087" datatype="html">
+ <source>documentation</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e351b40b3869a5c7d19c3d4918cb1ac7aaab95c4" datatype="html">
+ <source>API</source>
+ <target>Interfejs API</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a" datatype="html">
+ <source>About</source>
+ <target>O</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="049dfd9fe6c78914ad58cf89ac6a631fca28ec74" datatype="html">
+ <source>Logged in user</source>
+ <target>Zalogowany użytkownik</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5022c5ae3ae921c07bf5f881e9b026b4a6708a7" datatype="html">
+ <source>Signed in as <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9" datatype="html">
+ <source>Change password</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d22c795daf43877a5f708dca2bccd549eb0471d" datatype="html">
+ <source>Sign out</source>
+ <target>Wyloguj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319e0745bcbc132451569294fa2fa21bf10f555a" datatype="html">
+ <source>Toggle navigation</source>
+ <target>Rozwiń</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f65253954b66e929a8b4d5ecaf61f9129f8cec64" datatype="html">
+ <source>Dashboard</source>
+ <target>Pulpit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c95898abff46bfac3ed6eb2afef74597e60b15c" datatype="html">
+ <source>CRUSH map</source>
+ <target>CRUSH mapa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7b2bc4b86de6e96d353f6bf2b4d793ea3a19ba0" datatype="html">
+ <source>Manager Modules</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb3d5aefff38a814b76da74371cbf02c0789a1ef" datatype="html">
+ <source>Logs</source>
+ <target>Logi</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17fc3efe5f9fa4e0289c900cb6202265215a1a27" datatype="html">
+ <source>Monitoring</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f5d0c10614e8a34f0e2dad33a0568277c50cf69" datatype="html">
+ <source>Block</source>
+ <target>Dostęp blokowy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3c2562ba992127203dcfd014010b03cb7b8113c6" datatype="html">
+ <source>Mirroring</source>
+ <target>Kopia lustrzana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="811c241d56601b91ef26735b770e64428089b950" datatype="html">
+ <source>iSCSI</source>
+ <target>iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a24eabd99ea5af20f5f94c4484649cd30370042b" datatype="html">
+ <source>NFS</source>
+ <target>Sieciowy system plików NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5276fc60d54d667116babb723641b21281d37271" datatype="html">
+ <source>File Systems</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9515520496da83179d8b08132f00f575512a1f40" datatype="html">
+ <source>Buckets</source>
+ <target>Wiadra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a23e992f6c6e169a38b2b7338b4e5e803b52e0d" datatype="html">
+ <source>Tasks and Notifications</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1390461972315002349" datatype="html">
+ <source>The name of the node under which data should be placed.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6575341202068728510" datatype="html">
+ <source>The type of CRUSH nodes across which we should separate replicas.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3874278445824365480" datatype="html">
+ <source>The device class data should be placed on.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="675628105428950215" datatype="html">
+ <source>Each object is split in data-chunks parts, each stored on a different OSD.</source>
+ <target>Każdy obiekt jest podzielony na części fragmentów danych, każdy jest przechowywany na innym OSD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5128168460056151476" datatype="html">
+ <source>Compute coding chunks for each object and store them on different OSDs.
+ The number of coding chunks is also the number of OSDs that can be down without losing data.</source>
+ <target>Oblicz porcje kodu dla każdego obiektu i przechowuj je na różnych OSD.
+ Liczba fragmentów kodujących to również liczba OSD, które mogą zostać wyłączone bez utraty danych.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">18,19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8826111293169381132" datatype="html">
+ <source>The jerasure plugin is the most generic and flexible plugin,
+ it is also the default for Ceph erasure coded pools.</source>
+ <target>Wtyczka jerasure jest najbardziej uniwersalną i elastyczną wtyczką,
+ jest to również domyślne ustawienie dla pui kodowanych przez Ceph.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">23,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1331133460856304156" datatype="html">
+ <source>The more flexible technique is reed_sol_van : it is enough to set k
+ and m. The cauchy_good technique can be faster but you need to chose the packetsize
+ carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents
+ in the sense that they can only be configured with m=2.</source>
+ <target>Bardziej elastyczną techniką jest reed_sol_van: wystarczy ustawić k
+ oraz m. Technika cauchy_good może być szybsza, ale musisz wybrać rozmiar pakietu
+ ostrożnie. Wszystkie reed_sol_r6_op, liberation, blaum_roth, liber8tion są odpowiednikami RAID6
+ w tym sensie, że mogą być skonfigurowane tylko z m = 2.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">25,28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4577912952562931806" datatype="html">
+ <source>The encoding will be done on packets of bytes size at a time.
+ Choosing the right packet size is difficult.
+ The jerasure documentation contains extensive information on this topic.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">29,31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6471646852539810855" datatype="html">
+ <source>With the jerasure plugin, when an erasure coded object is stored on
+ multiple OSDs, recovering from the loss of one OSD requires reading from all the others.
+ For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading
+ from the eleven others to repair.
+
+ The lrc erasure code plugin creates local parity chunks to be able to recover using
+ less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create
+ an additional parity chunk for every four OSDs. When a single OSD is lost, it can be
+ recovered with only four OSDs instead of eleven.</source>
+ <target>Z wtyczką jerasure, gdy obiekt zakodowany przy użyciu skasowania jest przechowywany na
+ wielu OSD-kach, odzyskiwanie po utracie jednego OSD wymaga odczytu ze wszystkich pozostałych.
+ Na przykład, jeśli konfiguracja skryptu ma wartość k = 8 ,m = 4 i l=4, utrata jednego OSD wymaga odczytu
+ od jedenastu innych do naprawy.
+
+ Wtyczka kodu wymazywania lrc tworzy fragmenty o parzystości lokalnej, aby móc je odzyskać
+ mniej OSD. Na przykład, jeśli lrc jest skonfigurowane z k = 8, m = 4 i l = 4, zostanie utworzony
+ dodatkowy fragment parzystości na każde cztery OSD. Gdy jeden OSD zostanie utracone, może to być
+ odzyskane tylko z czterema OSD zamiast jedenastu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">34,42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2619235086723330982" datatype="html">
+ <source>Group the coding and data chunks into sets of size locality. For instance,
+ for k=4 and m=2, when locality=3 two groups of three are created. Each set can
+ be recovered without reading chunks from another set.</source>
+ <target>Grupuj fragmenty kodu i danych w zestawy lokalizacji wielkości. Na przykład,
+ dla k = 4 i m = 2, gdy lokalność = 3 tworzone są dwie grupy po trzy. Każdy zestaw może
+ odzyskać bez czytania kawałków z innego zestawu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">43,45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3298836762557512588" datatype="html">
+ <source>The type of the crush bucket in which each set of chunks defined
+ by l will be stored. For instance, if it is set to rack, each group of l chunks will be
+ placed in a different rack. It is used to create a CRUSH rule step such as step choose
+ rack. If it is not set, no such grouping is done.</source>
+ <target>Typ wiadra CRUSH, w którym zdefiniowano każdy zestaw porcji
+ przez l zostaną zapisane. Na przykład, jeśli jest ustawiony na rack, każda grupa l porcji będzie
+ umieszczona w innym raku. Służy do utworzenia kroku reguły CRUSH, takiego jak krok wyboru
+ racka. Jeśli nie jest ustawiony, nie ma takiego grupowania.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">46,49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9162461669419243962" datatype="html">
+ <source>The isa plugin encapsulates the ISA library. It only runs on Intel processors.</source>
+ <target>Wtyczka isa zawiera bibliotekę ISA. Działa tylko na procesorach Intel.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2389282202903059852" datatype="html">
+ <source>The ISA plugin comes in two Reed Solomon forms.
+ If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.</source>
+ <target>Wtyczka ISA jest dostępna w dwóch formach Reed Solomon.
+ Jeśli ustawiono reed_sol_van, jest to Vandermonde, jeśli ustawiono cauchy, to jest to Cauchy.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">53,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7319555444402547739" datatype="html">
+ <source>The shec plugin encapsulates the multiple SHEC library.
+ It allows ceph to recover data more efficiently than Reed Solomon codes.</source>
+ <target>Wtyczka shec zawiera wiele bibliotek SHEC.
+ Pozwala ceph odzyskać dane bardziej efektywnie niż kody Reeda Solomona.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">57,58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7723217930035575928" datatype="html">
+ <source>The number of parity chunks each of which includes each data chunk in its
+ calculation range. The number is used as a durability estimator. For instance, if c=2,
+ 2 OSDs can be down without losing data.</source>
+ <target>Liczba kawałków parzystości, z których każdy zawiera każdą porcję danych w swoim zakresie obliczeń. Liczba jest używana jako estymator trwałości. Na przykład, jeśli c = 2,
+ 2 OSD można wyłączyć bez utraty danych.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">59,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2054101840892270818" datatype="html">
+ <source>CLAY (short for coupled-layer) codes are erasure codes designed to
+ bring about significant savings in terms of network bandwidth and disk IO when a failed
+ node/OSD/rack is being repaired.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">64,66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491096236680229427" datatype="html">
+ <source>Number of OSDs requested to send data during recovery of a single chunk.
+ d needs to be chosen such that k+1 &lt;= d &lt;= k+m-1. The larger the d, the better
+ the savings.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">67,69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2625895656705896729" datatype="html">
+ <source>scalar_mds specifies the plugin that is used as a building block
+ in the layered construction. It can be one of jerasure, isa, shec.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">70,71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6639141182731628232" datatype="html">
+ <source>technique specifies the technique that will be picked
+ within the 'scalar_mds' plugin specified. Supported techniques
+ are 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good', 'liber8tion' for jerasure, 'reed_sol_van',
+ 'cauchy' for isa and 'single', 'multiple' for shec.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">72,76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8172892264673403098" datatype="html">
+ <source>The name of the crush bucket used for the first step of the CRUSH rule.
+ For instance step take default.</source>
+ <target>Nazwa wiadra crush jest użyte do pierwszego kroku reguły CRUSH.
+Na przykład krok jest domyślny.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">80,81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1654284403437084515" datatype="html">
+ <source>Ensure that no two chunks are in a bucket with the same failure
+ domain. For instance, if the failure domain is host no two chunks will be stored on the same
+ host. It is used to create a CRUSH rule step such as step chooseleaf host.</source>
+ <target>Upewnij się, że żadne dwie porcje nie znajdują się w wiadrze z tą samą awarią
+ domeny. Na przykład, jeśli domena awarii jest hostem, nie zostaną na niej zapisane dwie porcje
+ hosta. Służy do utworzenia kroku reguły CRUSH, takiego jak krok wyboru hosta.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">83,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7737703816676512224" datatype="html">
+ <source>Restrict placement to devices of a specific class
+ (e.g., ssd or hdd), using the crush device class names in the CRUSH map.</source>
+ <target>Ogranicz umieszczanie do urządzeń określonej klasy
+ (np. ssd lub hdd), używając nazw klas urządzeń zgniatających na mapie CRUSH.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9049698214199657456" datatype="html">
+ <source>Set the directory name from which the erasure code plugin is loaded.</source>
+ <target>Ustaw nazwę katalogu, z którego ładowana jest wtyczka kodu kasowania.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5514060020564877279" datatype="html">
+ <source>Allows all operations</source>
+ <target>Dozwolone są wszystkie operacje</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4265406815683383218" datatype="html">
+ <source>Allows only operations that do not modify the server</source>
+ <target>Dozwolone są operacje, które nie modyfikują serweru</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="990071930378308183" datatype="html">
+ <source>Allows no access at all</source>
+ <target>Brak dostępu w ogóle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7286983657616285612" datatype="html">
+ <source>Please specify a filesystem volume.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8321762156640395170" datatype="html">
+ <source>The feature is disabled because Orchestrator is not available.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6718394293315494787" datatype="html">
+ <source>The Orchestrator backend doesn't support this feature.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5569418400096331461" datatype="html">
+ <source>-- Select the priority --</source>
+ <target>-- wybierz priorytet -- </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="802458941707537739" datatype="html">
+ <source>Low</source>
+ <target>Niski</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8063651736083474594" datatype="html">
+ <source>High</source>
+ <target>Wysoki</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1717753935149218245" datatype="html">
+ <source>The user list data might be stale. If needed, you can manually reload it.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/list-with-details.class.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7077550143229856452" datatype="html">
+ <source>Retrieving data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8231424898988217966" datatype="html">
+ <source>Retrieving data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2357645764289315007" datatype="html">
+ <source>Please wait...</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="232824565824302482" datatype="html">
+ <source>Displaying previously cached data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8721257977793603730" datatype="html">
+ <source>Displaying previously cached data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6731313206654246255" datatype="html">
+ <source>Could not load data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3359748695862553898" datatype="html">
+ <source>Could not load data.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4836577225879717660" datatype="html">
+ <source>Please check the cluster health.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1519954996184640001" datatype="html">
+ <source>Error</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5037437391296624618" datatype="html">
+ <source>Information</source>
+ <target>Informacja</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4648900870671159218" datatype="html">
+ <source>Success</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3425367071066107827" datatype="html">
+ <source>Danger</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c947210e2d162b6225083d18820ab602f58cd2d" datatype="html">
+ <source>Remove the custom configuration value. The default configuration will be inherited and used instead.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="454ee9cb60b00446a8fb147fd2cc5eb836320586" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fc8a22825131e028336f60ef909ccbd96059703" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4dd200b7f9e19048cf90516843b40964f2af3fe9" datatype="html">
+ <source>Copy to Clipboard</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6110699a3562eeb15371063c0cf7f6bfd88a0209" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>?</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="549859e511ba5af0ea03fcaa620c472f08038969" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected items?</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="54839ebc827b73c9dc4e1df731c6d36a85036af7" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/>?</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2be8b7f04f0104d3fad90d079d8202b74f758b9a" datatype="html">
+ <source>Yes, I am sure.</source>
+ <target>Tak, jestem pewny.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4523728183000855476" datatype="html">
+ <source>documentation</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/doc/doc.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3099741642167775297" datatype="html">
+ <source>Download</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/download-button/download-button.component.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1417693714872528491" datatype="html">
+ <source>This field is required.</source>
+ <target>Pole jest wymagane.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5321335688371682440" datatype="html">
+ <source>An error occurred.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5109325fb160b543f71a51e7511c00575057431" datatype="html">
+ <source>Loading panel data...</source>
+ <target>Trwa ładowanie danych...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a21acde005f80ceadb1391be1e7ff8b6d18188a0" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the monitoring functionality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a0ed4bd7b7add2a6febf7adf58d8cde5e421418" datatype="html">
+ <source>Grafana Dashboard doesn't exist. Please refer to <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to add dashboards to Grafana.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e11830040bd64804a0555de76f291d5832772d4" datatype="html">
+ <source>Grafana Time Picker</source>
+ <target>Wybór czasu Grafana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="238c1ba845dd7330e8088165275919a1debf1ca3" datatype="html">
+ <source>Reset Settings</source>
+ <target>Zresetuj ustawienia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7888499255176013171" datatype="html">
+ <source>Last 5 minutes</source>
+ <target>Ostatnie 5 minut</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6892361549797455305" datatype="html">
+ <source>Last 15 minutes</source>
+ <target>Ostatnie 15 minut</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2653641162607195423" datatype="html">
+ <source>Last 30 minutes</source>
+ <target>Ostatnie 30 minut</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4117793269024790392" datatype="html">
+ <source>Last 1 hour (Default)</source>
+ <target>Ostatnia 1 godzina (domyślnie)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2645733658763754077" datatype="html">
+ <source>Last 3 hours</source>
+ <target>Ostatnie 3 godziny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7360078715633936807" datatype="html">
+ <source>Last 6 hours</source>
+ <target>Ostatnie 6 godzin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5055313582241816303" datatype="html">
+ <source>Last 12 hours</source>
+ <target>Ostatnie 12 godzin</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9186529157286281693" datatype="html">
+ <source>Last 24 hours</source>
+ <target>Ostatnie 24 godziny</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4498682414491138092" datatype="html">
+ <source>Yesterday</source>
+ <target>Wczoraj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="929003859318769922" datatype="html">
+ <source>Today so far</source>
+ <target>Do tej pory dzisiaj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5525943133564968818" datatype="html">
+ <source>Day before yesterday</source>
+ <target>Przedwczoraj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6168755117727892817" datatype="html">
+ <source>Last 2 days</source>
+ <target>Ostatnie 2 dni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7574807704224200535" datatype="html">
+ <source>This day last week</source>
+ <target>Tego dnia tydzień temu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4420128118950221234" datatype="html">
+ <source>Previous week</source>
+ <target>Poprzedni tydzień</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4063965603321223683" datatype="html">
+ <source>This week so far</source>
+ <target>Do tej pory w tym tygodniu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4873149362496451858" datatype="html">
+ <source>Last 7 days</source>
+ <target>Ostatnie 7 dni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8586908745456864217" datatype="html">
+ <source>Previous month</source>
+ <target>Poprzedniego miesiąca</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1647573304710886499" datatype="html">
+ <source>This month so far</source>
+ <target>Do tej pory w tym miesiącu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2949150997160654358" datatype="html">
+ <source>Last 30 days</source>
+ <target>Ostatnie 30 dni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7469939859049484736" datatype="html">
+ <source>Last 90 days</source>
+ <target>Ostatnie 90 dni</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847501198811458781" datatype="html">
+ <source>Last 6 months</source>
+ <target>Ostatnie 6 miesięcy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7447583558445881102" datatype="html">
+ <source>Last 1 year</source>
+ <target>Ostatni 1 rok</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="100513227838842152" datatype="html">
+ <source>Previous year</source>
+ <target>Poprzedniego roku</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3650872673621947074" datatype="html">
+ <source>This year so far</source>
+ <target>Do tej pory bieżącego roku</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1262816694819959075" datatype="html">
+ <source>Last 2 years</source>
+ <target>Ostatnie 2 lata</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7878813844917362690" datatype="html">
+ <source>Last 5 years</source>
+ <target>Ostatnie 5 lat</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3fb5709e10166cbc85970cbff103db227dbeb813" datatype="html">
+ <source>Select a Language</source>
+ <target>Wybierz język</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/language-selector/language-selector.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e52e9143145e1db5146258de81eae018a407b31" datatype="html">
+ <source>Clear notifications</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0b07bb6b7ff21ede439dd04eaf8872d1ecb84d8" datatype="html">
+ <source>Remove notification</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e17a1d75189da843f541f7764f188f2b19a97df2" datatype="html">
+ <source>Duration:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d4b37c6675c5b436a54c43d6716eec835e1aa7f" datatype="html">
+ <source>There are no notifications.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b20e42ac4354d449f2718428b5390933eef0c1b9" datatype="html">
+ <source>The feature is not supported in the current Orchestrator.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a437b8f93cf826817c04a4277edb1ae3a93a1ab" datatype="html">
+ <source>Orchestrator is not available. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the functionality.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">7,9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20b3d45b0c08a2951a9974fa20505e4de95250c9" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>less than 1<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day. Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">9,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f34088c155e40ffb23770a465a65868ce772b2" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day(s). Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8d1785038d461ec66b5799db21864182b35900a" datatype="html">
+ <source>Refresh</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/refresh-selector/refresh-selector.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3417247046175131869" datatype="html">
+ <source>No items selected.</source>
+ <target>Nie wybrano żadnej pozycji</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1034353870189672674" datatype="html">
+ <source>Deselect item to select again</source>
+ <target>Odznacz pozycję, żeby wybrać ponownie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4879298070255432995" datatype="html">
+ <source>Selection limit reached</source>
+ <target>Osiągnięto limit wyboru. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001227209911602786" datatype="html">
+ <source>Filter tags</source>
+ <target>Filtr tagów.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="791789583719406586" datatype="html">
+ <source>Add badge</source>
+ <target>Dodaj odznakę</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="699988676752930063" datatype="html">
+ <source>There are no items available.</source>
+ <target>Brak dostępnych pozycji.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6702323d3760e3db0e2e785d567469d18beb120" datatype="html">
+ <source>The Ceph community needs your help to continue improving: please <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>Activate<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> the <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Telemetry<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> module.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.html</context>
+ <context context-type="linenumber">8,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8770134622386151776" datatype="html">
+ <source>Telemetry activation reminder muted</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8352450862052130357" datatype="html">
+ <source>You can activate the module on the Telemetry configuration page (&lt;b&gt;Dashboard Settings&lt;/b&gt; -&gt; &lt;b&gt;Telemetry configuration&lt;/b&gt;) at any time.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bc9e5365a581105ce37cf47d1d74e4ad9eb75ce" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e634c306cab9e8879c3392593714c1ceab85437d" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3249513483374643425" datatype="html">
+ <source>Add</source>
+ <target>Dodaj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4359847060009771702" datatype="html">
+ <source>Set</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935187492052582731" datatype="html">
+ <source>Submit</source>
+ <target>Zatwierdź</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4814285799071780083" datatype="html">
+ <source>Remove</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8363450564548681668" datatype="html">
+ <source>Unset</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2159130950882492111" datatype="html">
+ <source>Cancel</source>
+ <target>Anuluj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1295614462098694869" datatype="html">
+ <source>Preview</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2354817630223808522" datatype="html">
+ <source>Move</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3885497195825665706" datatype="html">
+ <source>Next</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8890553633144307762" datatype="html">
+ <source>Back</source>
+ <target>Wstecz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5834780181397311898" datatype="html">
+ <source>Clone</source>
+ <target>Sklonuj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4323470180912194028" datatype="html">
+ <source>Copy</source>
+ <target>Kopia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2131301778880826094" datatype="html">
+ <source>Deep Scrub</source>
+ <target>Szoruj głęboko</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1704447209800801558" datatype="html">
+ <source>Destroy</source>
+ <target>Zniszcz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8343007008325027187" datatype="html">
+ <source>Evict</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="408179081163888126" datatype="html">
+ <source>Flatten</source>
+ <target>Spłaszcz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="318900679147387932" datatype="html">
+ <source>Mark Down</source>
+ <target>zaznacz jako upadły</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5275142643521766706" datatype="html">
+ <source>Mark In</source>
+ <target>Zaznacz jako w </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6973272903386150199" datatype="html">
+ <source>Mark Lost</source>
+ <target>Zaznacz jako stracony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1962653792210847411" datatype="html">
+ <source>Mark Out</source>
+ <target>Zaznacz jako poza</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4424610588915076517" datatype="html">
+ <source>Protect</source>
+ <target>Zabezpiecz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6041115344061899387" datatype="html">
+ <source>Rename</source>
+ <target>Zmień nazwę</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">164</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6770769801335635194" datatype="html">
+ <source>Restore</source>
+ <target>Przywróć</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2003230525878010676" datatype="html">
+ <source>Reweight</source>
+ <target>Ponowne ważenie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5430834128563178593" datatype="html">
+ <source>Scrub</source>
+ <target>Szoruj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8461842260159597706" datatype="html">
+ <source>Show</source>
+ <target>Pokaż</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5655608100705734230" datatype="html">
+ <source>Move to Trash</source>
+ <target>Przenieś do kosza</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4622393909937403117" datatype="html">
+ <source>Unprotect</source>
+ <target>Odbezpiecz </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1230154438678955604" datatype="html">
+ <source>Change</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8450843381175865415" datatype="html">
+ <source>Enter Maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1610181371597502589" datatype="html">
+ <source>Exit Maintenance</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="676511611419004737" datatype="html">
+ <source>Start Drain</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7170653322511987983" datatype="html">
+ <source>Stop Drain</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5528551262937858942" datatype="html">
+ <source>Recreate</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2502364444688691031" datatype="html">
+ <source>Expire</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6381490568322624964" datatype="html">
+ <source>Deleted</source>
+ <target>Usunięty</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="231679111972850796" datatype="html">
+ <source>Added</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5406093358072761930" datatype="html">
+ <source>Removed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3008573030448240863" datatype="html">
+ <source>Edited</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4381944803872489731" datatype="html">
+ <source>Canceled</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754993936947658096" datatype="html">
+ <source>Previewed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6001163963116907226" datatype="html">
+ <source>Moved</source>
+ <target>Przeniesiono</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4932744777596632840" datatype="html">
+ <source>Cloned</source>
+ <target>Sklonowano</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2115592966120408375" datatype="html">
+ <source>Copied</source>
+ <target>Skopiowano </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7937474560394832586" datatype="html">
+ <source>Deep Scrubbed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6321562733889197649" datatype="html">
+ <source>Destroyed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7460162290177581995" datatype="html">
+ <source>Flattened</source>
+ <target>Spłaszczony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3662010055028969035" datatype="html">
+ <source>Marked Down</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5880434235404894589" datatype="html">
+ <source>Marked In</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="266997194072682078" datatype="html">
+ <source>Marked Lost</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">250</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4010544044592534535" datatype="html">
+ <source>Marked Out</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4776304093333411035" datatype="html">
+ <source>Protected</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2700903921419382511" datatype="html">
+ <source>Purged</source>
+ <target>Oczyszczony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5488667333459350160" datatype="html">
+ <source>Renamed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8044659850000829751" datatype="html">
+ <source>Restored</source>
+ <target>Przywrócony</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559472082694466366" datatype="html">
+ <source>Reweighted</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022271525067453676" datatype="html">
+ <source>Rolled back</source>
+ <target>Wycofaj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2483217756816388123" datatype="html">
+ <source>Scrubbed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7200036055090632378" datatype="html">
+ <source>Showed</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7609648817347881129" datatype="html">
+ <source>Moved to Trash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7810326403606456469" datatype="html">
+ <source>Unprotected</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5620774899056099259" datatype="html">
+ <source>Recreated</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464749780222721589" datatype="html">
+ <source>Expired</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">266</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e5e23363e949f7dcbaf034bdb141a561132a10e" datatype="html">
+ <source>Clear filters</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80cc9a12d4bf6fe454ed94b379eeaf915f920bb7" datatype="html">
+ <source>selected</source>
+ <target>Wybrane</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <note priority="1" from="description">X selected</note>
+ </trans-unit>
+ <trans-unit id="0cb77511a9a148e05b9adf36cc07269956fbb29d" datatype="html">
+ <source>found</source>
+ <target>Znaleziono</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <note priority="1" from="description">X found</note>
+ </trans-unit>
+ <trans-unit id="79347388740c50b7ac97e144c2494bb62912f312" datatype="html">
+ <source>total</source>
+ <target>Razem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <note priority="1" from="description">X total</note>
+ </trans-unit>
+ <trans-unit id="2a3dab422cc892db037db8632bb84a6bf496e2d1" datatype="html">
+ <source>Expand/Collapse Row</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4047162422391207122" datatype="html">
+ <source>Failed to load data.</source>
+ <target>Błąd wczytywania danych.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.ts</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="709331713250198508" datatype="html">
+ <source>Loading form data...</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3850344644863430180" datatype="html">
+ <source>Form data could not be loaded.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4626760504772708998" datatype="html">
+ <source>Size has to be at least <x id="PH" equiv-text="value"/> or more</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">428</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2880361802894657892" datatype="html">
+ <source>Size has to be at most <x id="PH" equiv-text="value"/> or less</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2807800733729323332" datatype="html">
+ <source>Yes</source>
+ <target>Tak</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3542042671420335679" datatype="html">
+ <source>No</source>
+ <target>Nie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7789266940050748913" datatype="html">
+ <source>in %s</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565573880632900017" datatype="html">
+ <source>%s ago</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="220300059326988179" datatype="html">
+ <source>a few seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2761143993878941513" datatype="html">
+ <source>%d seconds</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7094767962693903153" datatype="html">
+ <source>a minute</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7597613755904774250" datatype="html">
+ <source>%d minutes</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2757762976030115752" datatype="html">
+ <source>an hour</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9118454901758656303" datatype="html">
+ <source>%d hours</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7435193742089920080" datatype="html">
+ <source>a day</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1821334622562842480" datatype="html">
+ <source>%d days</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7375306199026780379" datatype="html">
+ <source>a week</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7272688256541915488" datatype="html">
+ <source>%d weeks</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5761124614324704118" datatype="html">
+ <source>a month</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="352195662913351589" datatype="html">
+ <source>%d months</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7562153591649199139" datatype="html">
+ <source>a year</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5424759741855527370" datatype="html">
+ <source>%d years</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7738182956549158907" datatype="html">
+ <source>Required rules for passwords:</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8839765875053270528" datatype="html">
+ <source>Must contain at least <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> characters</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3098731108593590794" datatype="html">
+ <source>Must not be the same as the previous one</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9150236741862848105" datatype="html">
+ <source>Cannot contain the username</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6395043854518867543" datatype="html">
+ <source>Cannot contain any configured keyword</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="907558624910601703" datatype="html">
+ <source>Cannot contain any repetitive characters e.g. &quot;aaa&quot;</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514384270734082343" datatype="html">
+ <source>Cannot contain any sequential characters e.g. &quot;abc&quot;</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4119354814383293871" datatype="html">
+ <source>Must consist of characters from the following groups:
+ * Alphabetic a-z, A-Z
+ * Numbers 0-9
+ * Special chars: !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * Any other characters (signs)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">30,34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8649061117624699581" datatype="html">
+ <source>Your matcher seems to match no currently defined rule or active alert.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7122912874364762704" datatype="html">
+ <source>no active alerts</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7388215679576832341" datatype="html">
+ <source>1 active alert</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3112400568960537267" datatype="html">
+ <source><x id="PH" equiv-text="alerts"/> active alerts</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6264717417287230743" datatype="html">
+ <source>Matches 1 rule</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054663176394183966" datatype="html">
+ <source>Matches <x id="PH" equiv-text="rules"/> rules</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6674225401121099210" datatype="html">
+ <source><x id="PH" equiv-text="rule"/> with <x id="PH_1" equiv-text="alert"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5659908877047925719" datatype="html">
+ <source>Quality of Service</source>
+ <target>Jakość serwisu</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1277565045885499475" datatype="html">
+ <source>BPS Limit</source>
+ <target>Limit BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2289210323987692906" datatype="html">
+ <source>The desired limit of IO bytes per second.</source>
+ <target>Pożądany limit IO bajtów na sekundę.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753589939879013605" datatype="html">
+ <source>IOPS Limit</source>
+ <target>Limit IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2213985059444278522" datatype="html">
+ <source>The desired limit of IO operations per second.</source>
+ <target>Pożądany limit operacji IO na sekundę.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2487530611825582289" datatype="html">
+ <source>Read BPS Limit</source>
+ <target>limit odczytu BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8071352270469595250" datatype="html">
+ <source>The desired limit of read bytes per second.</source>
+ <target>Pożądany limit odczytu bajtów na sekundę.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1632513758247239690" datatype="html">
+ <source>Read IOPS Limit</source>
+ <target>limit odczytu IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2361786794607418566" datatype="html">
+ <source>The desired limit of read operations per second.</source>
+ <target>Pożądany limit operacji odczytu na sekundę.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="894600353504285551" datatype="html">
+ <source>Write BPS Limit</source>
+ <target>Limit zapisu BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911437671369366025" datatype="html">
+ <source>The desired limit of write bytes per second.</source>
+ <target>Pożądany limit zapisu bajtów na sekundę.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2947346368707443195" datatype="html">
+ <source>Write IOPS Limit</source>
+ <target>Limit zapisu IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5506349527983391356" datatype="html">
+ <source>The desired limit of write operations per second.</source>
+ <target>Pożądany limit operacji zapisu na sekundę.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559424229658244943" datatype="html">
+ <source>BPS Burst</source>
+ <target>Wiązka BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3454058701331860330" datatype="html">
+ <source>The desired burst limit of IO bytes.</source>
+ <target>Żądana granica serii IO bajtów.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171005761926448741" datatype="html">
+ <source>IOPS Burst</source>
+ <target>Wiązka IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4939532784700485729" datatype="html">
+ <source>The desired burst limit of IO operations.</source>
+ <target>Żądana granica serii operacji IO.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6273492199526646930" datatype="html">
+ <source>Read BPS Burst</source>
+ <target>Odczyt wiązki BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3105467595643777520" datatype="html">
+ <source>The desired burst limit of read bytes.</source>
+ <target>Żądana granica serii odczytanych bajtów.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2170715106679765467" datatype="html">
+ <source>Read IOPS Burst</source>
+ <target>Odczyt wiązki IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6234106755510510672" datatype="html">
+ <source>The desired burst limit of read operations.</source>
+ <target> Żądana granica serii operacji odczytu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="228509518172572466" datatype="html">
+ <source>Write BPS Burst</source>
+ <target>Zapis wiązki BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7803279807796571240" datatype="html">
+ <source>The desired burst limit of write bytes.</source>
+ <target>Żądana granica serii bajtów zapisu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9125474584914848055" datatype="html">
+ <source>Write IOPS Burst</source>
+ <target>Zapis wiązki IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5839129348567326667" datatype="html">
+ <source>The desired burst limit of write operations.</source>
+ <target>Żądana granica serii operacji zapisu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="614961883076556986" datatype="html">
+ <source>Failed to <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="489145301781720653" datatype="html">
+ <source>Executing</source>
+ <target>Wykonywanie </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4238828029954346941" datatype="html">
+ <source>execute</source>
+ <target>Wykonaj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7196604637389554584" datatype="html">
+ <source>Executed</source>
+ <target>Wykonany</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4418441687454700644" datatype="html">
+ <source>unknown task</source>
+ <target>Nieznane zadanie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8667665916832796867" datatype="html">
+ <source>Creating</source>
+ <target>Tworzenie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6031236679730054907" datatype="html">
+ <source>create</source>
+ <target>Utwórz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5593033420216313122" datatype="html">
+ <source>Updating</source>
+ <target>Aktualizowanie </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6100869651653026893" datatype="html">
+ <source>update</source>
+ <target>Zaktualizuj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3141301060598402455" datatype="html">
+ <source>Deleting</source>
+ <target>Usuwanie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3420504288275541125" datatype="html">
+ <source>Adding</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1059784693423848532" datatype="html">
+ <source>add</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594819887188505274" datatype="html">
+ <source>Removing</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2123171795960509943" datatype="html">
+ <source>remove</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1946427188770321847" datatype="html">
+ <source>Importing</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8495827411619139669" datatype="html">
+ <source>import</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218459863491436562" datatype="html">
+ <source>Imported</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6534993668932538712" datatype="html">
+ <source>RBD '<x id="PH" equiv-text="metadata.image_spec"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8237287859948228705" datatype="html">
+ <source>RBD snapshot '<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2328067975897167268" datatype="html">
+ <source>mirroring site name</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4433460322631470833" datatype="html">
+ <source>bootstrap token</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7044591639782280183" datatype="html">
+ <source>mirror mode for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7109746474198366468" datatype="html">
+ <source>mirror peer for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6201476020617351396" datatype="html">
+ <source>all dashboards</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7268953097700363232" datatype="html">
+ <source>Identifying</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4337678035264231187" datatype="html">
+ <source>identify</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7257219307556106552" datatype="html">
+ <source>Identified</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6002370161381995023" datatype="html">
+ <source>device '<x id="PH" equiv-text="metadata.device"/>' on host '<x id="PH_1" equiv-text="metadata.hostname"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5580298273054260850" datatype="html">
+ <source>OSDs (DriveGroups: <x id="PH" equiv-text="metadata.tracking_id"/>)</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2182125722527364040" datatype="html">
+ <source>Name is already used by <x id="PH" equiv-text="this.pool(metadata)"/>.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">182</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7892856315477304281" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> is busy.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4690045751984117407" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> contains snapshots.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="562148565853868662" datatype="html">
+ <source>Cloning</source>
+ <target>Klonowanie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1197352830433807469" datatype="html">
+ <source>clone</source>
+ <target>Sklonuj </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1692004144561317867" datatype="html">
+ <source>Snapshot of <x id="PH" equiv-text="this.rbd.child(metadata)"/> must be protected.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8531200838331320284" datatype="html">
+ <source>Copying</source>
+ <target>Kopiowanie </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6862265996781523030" datatype="html">
+ <source>copy</source>
+ <target>Kopiuj</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3556912098733712857" datatype="html">
+ <source>Flattening</source>
+ <target>Spłaszczanie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2488773646187451754" datatype="html">
+ <source>flatten</source>
+ <target>Spłaszcz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="704305783678486635" datatype="html">
+ <source>Cannot unprotect <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> because it contains child images.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">223,225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101271773452792348" datatype="html">
+ <source>Cannot delete <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/> because it's protected.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5143010940199748580" datatype="html">
+ <source>Rolling back</source>
+ <target>Wycofywanie </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1315686250907089544" datatype="html">
+ <source>rollback</source>
+ <target>Wycofanie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5010267418211867946" datatype="html">
+ <source>Moving</source>
+ <target>Przenoszenie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4366763205960752449" datatype="html">
+ <source>move</source>
+ <target>Przenieś</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="695867152524584829" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_spec"/>' to trash</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423442774536615202" datatype="html">
+ <source>Could not find image.</source>
+ <target>Nie znaleziono obrazu.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2622324641113512527" datatype="html">
+ <source>Restoring</source>
+ <target>Przywracanie</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3347932678307141902" datatype="html">
+ <source>restore</source>
+ <target>Przywróć </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7488038030362249932" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>' into '<x id="PH_1" equiv-text="metadata.new_image_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565688512490959949" datatype="html">
+ <source>Image name '<x id="PH" equiv-text="metadata.new_image_name"/>' is already in use.</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6331051389974655106" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8245559899946787147" datatype="html">
+ <source>Purging</source>
+ <target>oczyszczać</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7879437654311684252" datatype="html">
+ <source>purge</source>
+ <target>oczyść</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1440427157062670480" datatype="html">
+ <source>all pools</source>
+ <target>Wszystkie pule</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8677740163708263843" datatype="html">
+ <source>images from <x id="PH" equiv-text="message"/></source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011237345035114219" datatype="html">
+ <source>Cannot disable mirroring because it contains a peer.</source>
+ <target>Nie można wyłączyć lustrzenia ponieważ zawiera parowanie.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">292</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7391584598242145869" datatype="html">
+ <source>host '<x id="PH" equiv-text="metadata.hostname"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6964302691596180722" datatype="html">
+ <source>OSD '<x id="PH" equiv-text="metadata.svc_id"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="488305686602466689" datatype="html">
+ <source>pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5921392748828575278" datatype="html">
+ <source>erasure code profile '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2423915105798557698" datatype="html">
+ <source>crush rule '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">370</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8273044996643438592" datatype="html">
+ <source>target '<x id="PH" equiv-text="metadata.target_iqn"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5474643443735437364" datatype="html">
+ <source>NFS '<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">378,380</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2235495382025026939" datatype="html">
+ <source>Service '<x id="PH" equiv-text="metadata.service_name"/>'</source>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ </body>
+ </file>
+</xliff> \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.pt-BR.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.pt-BR.xlf
new file mode 100644
index 000000000..ca6309f42
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.pt-BR.xlf
@@ -0,0 +1,14885 @@
+<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en-US" datatype="plaintext" original="ng2.template" target-language="pt-BR">
+ <body>
+ <trans-unit id="ngb.alert.close" datatype="html">
+ <source>Close</source>
+ <target>Fechar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/alert/alert.ts</context>
+ <context context-type="linenumber">58,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.slide-number" datatype="html">
+ <source> Slide <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> of <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </source>
+ <target> Slide <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> de <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">114,118</context>
+ </context-group>
+ <note priority="1" from="description">Currently selected slide number read by screen reader</note>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.previous" datatype="html">
+ <source>Previous</source>
+ <target>Anterior</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">132,134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.next" datatype="html">
+ <source>Next</source>
+ <target>Avançar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">147,152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-month" datatype="html">
+ <source>Select month</source>
+ <target>Selecionar mês</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">44,49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">49,50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-year" datatype="html">
+ <source>Select year</source>
+ <target>Selecionar ano</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">59,63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.previous-month" datatype="html">
+ <source>Previous month</source>
+ <target>Mês anterior</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">24,27</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">35,36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.next-month" datatype="html">
+ <source>Next month</source>
+ <target>Mês seguinte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">47,50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">60,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first" datatype="html">
+ <source>««</source>
+ <target>««</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">182,183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous" datatype="html">
+ <source>«</source>
+ <target>«</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">186,190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next" datatype="html">
+ <source>»</source>
+ <target>»</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">194,195</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last" datatype="html">
+ <source>»»</source>
+ <target>»»</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">201,204</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first-aria" datatype="html">
+ <source>First</source>
+ <target>Primeiro</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">208,209</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous-aria" datatype="html">
+ <source>Previous</source>
+ <target>Anterior</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">215,216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next-aria" datatype="html">
+ <source>Next</source>
+ <target>Avançar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">226,228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last-aria" datatype="html">
+ <source>Last</source>
+ <target>Último</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.progressbar.value" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="; } /** *"/></source>
+ <target><x id="INTERPOLATION" equiv-text="; } /** *"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/progressbar/progressbar.ts</context>
+ <context context-type="linenumber">32,38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.HH" datatype="html">
+ <source>HH</source>
+ <target>HH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">40,41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.hours" datatype="html">
+ <source>Hours</source>
+ <target>Horas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.MM" datatype="html">
+ <source>MM</source>
+ <target>MM</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">51,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.minutes" datatype="html">
+ <source>Minutes</source>
+ <target>Minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-hours" datatype="html">
+ <source>Increment hours</source>
+ <target>Incrementar horas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">63,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-hours" datatype="html">
+ <source>Decrement hours</source>
+ <target>Decrementar horas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">69,70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-minutes" datatype="html">
+ <source>Increment minutes</source>
+ <target>Incrementar minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">76,78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-minutes" datatype="html">
+ <source>Decrement minutes</source>
+ <target>Decrementar minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">82,84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.SS" datatype="html">
+ <source>SS</source>
+ <target>SS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.seconds" datatype="html">
+ <source>Seconds</source>
+ <target>Segundos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">92,93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-seconds" datatype="html">
+ <source>Increment seconds</source>
+ <target>Incrementar segundos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">100,101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-seconds" datatype="html">
+ <source>Decrement seconds</source>
+ <target>Decrementar segundos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">106,110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.AM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></source>
+ <target><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">115,121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.PM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="t() meridian: b"/></source>
+ <target><x id="INTERPOLATION" equiv-text="t() meridian: b"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">123,131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.toast.close-aria" datatype="html">
+ <source>Close</source>
+ <target>Fechar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/toast/toast.ts</context>
+ <context context-type="linenumber">78,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8835b9e49a3348b0a2f2162c21118af1f4bee45a" datatype="html">
+ <source>Must be greater than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>.</source>
+ <target>Deve ser maior do que ou igual a <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbddac59563c8c126e3fe28691e4e247614fcbd1" datatype="html">
+ <source>Must be less than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>.</source>
+ <target>Deve ser menor do que ou igual a <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5" datatype="html">
+ <source>Overview</source>
+ <target>Visão geral</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbd2045d5c37e4bb39a3c0fb62ea1ddf70a12838" datatype="html">
+ <source>Targets</source>
+ <target>Destinos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a674ab267d1934bf395f87ca1503fd474296893f" datatype="html">
+ <source>iSCSI Topology</source>
+ <target>Topologia iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8953033926734869941" datatype="html">
+ <source>Name</source>
+ <target>Nome</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6603000223840533819" datatype="html">
+ <source>Current</source>
+ <target>Atual</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5607669932062416162" datatype="html">
+ <source>Default</source>
+ <target>Padrão</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6803e31b7395d94934e091a49a9524026b59b018" datatype="html">
+ <source>Discovery Authentication</source>
+ <target>Autenticação de Descoberta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e08a77594f3d89311cdf6da5090044270909c194" datatype="html">
+ <source>User</source>
+ <target>Usuário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">381</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7cbdabcece469fab89cfa687ab152bca18b97498" datatype="html">
+ <source>This field is required.</source>
+ <target>Este campo é obrigatório.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">368</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">423</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">481</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">291</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">343</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">407</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">490</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">516</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">556</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">573</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">590</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">647</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">672</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">299</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">195</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">520</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">614</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">651</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f717bad2da5944a2567a52f971ccc6806db85805" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>Os nomes de usuário devem ter entre 8 e 64 caracteres e podem incluir caracteres alfanuméricos: '.', '@', '-', '_' ou ':'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">28,29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">85,86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c32ef07f8803a223a83ed17024b38e8d82292407" datatype="html">
+ <source>Password</source>
+ <target>Senha</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">403</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">581</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="001e1836299d8d3b84eaebe2fa051325beab3f00" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>As senhas devem ter entre 12 e 16 caracteres e podem incluir caracteres alfanuméricos: '@', '-', '_' ou '/'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">61,62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">118,119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff40391de7a1944ea95091e4045cc34c4979b736" datatype="html">
+ <source>Mutual User</source>
+ <target>Usuário Mútuo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cf73dbebe99b737c4d288788182fc356e3c93d3" datatype="html">
+ <source>Mutual Password</source>
+ <target>Senha Mútua</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594987303599690088" datatype="html">
+ <source>Updated discovery authentication</source>
+ <target>Autenticação de descoberta atualizada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb127ea03835b3230f0ed981c7080e2ccb879621" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <note priority="1" from="description">form title</note>
+ </trans-unit>
+ <trans-unit id="1406c2fb12a20c1528b19bcc5e24a6a2386167f3" datatype="html">
+ <source>Target IQN</source>
+ <target>IQN de Destino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5fe42339be910372fa689f559155631862d218e8" datatype="html">
+ <source>IQN has wrong pattern.</source>
+ <target>IQN tem padrão incorreto.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="050a7ff057d1e895357540406b6be5652b4d1c71" datatype="html">
+ <source>An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'</source>
+ <target>Um IQN tem a seguinte notação 'iqn.$year-$month.$reversedAddress:$definedName'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8ada4b53396d8366db00a435acc61d53d857047" datatype="html">
+ <source>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</source>
+ <target>Por exemplo: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e" datatype="html">
+ <source>More information</source>
+ <target>Mais informações</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9b1aa85dfc6849196e64060db02c5410de69b7a1" datatype="html">
+ <source>This target has modified advanced settings.</source>
+ <target>Este destino tem configurações avançadas modificadas.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6990ad8d6182662e864495ac31c3758cda1c7a28" datatype="html">
+ <source>Portals</source>
+ <target>Portais</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a3ac2b4137d723fd9878cd357c2012ff6c07973" datatype="html">
+ <source>Add portal</source>
+ <target>Adicionar portal</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3638c01b6c34066438909713ec96087c813fc7e" datatype="html">
+ <source>At least <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> gateways are required.</source>
+ <target>Pelo menos <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> gateways são necessários.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b73f7f5060fb22a1e9ec462b1bb02493fa3ab866" datatype="html">
+ <source>Images</source>
+ <target>Imagens</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">495</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">629</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9aff25be088f0efe3eaaf62edf2bff41cc41a617" datatype="html">
+ <source>Backstore: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </source>
+ <target>Backstore: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e3484cae8b118c576ca2815bf9c9406c2eb2cae3" datatype="html">
+ <source>This image has modified settings.</source>
+ <target>Esta imagem tem configurações modificadas.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1dff11e0820b6722ab240169f1232d70a54beaaa" datatype="html">
+ <source>Duplicated LUN numbers.</source>
+ <target>Números LUN duplicados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bf2dccf92ccff6e3b091792bf4205595406e1bfb" datatype="html">
+ <source>Duplicated WWN.</source>
+ <target>WWN duplicado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="808038f912fdc7f0e03f82d4afd3bf9178527fc8" datatype="html">
+ <source>Add image</source>
+ <target>Adicionar imagem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">656</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66c5fb27f52e75b70ca4b670b9b15a2a51cf9543" datatype="html">
+ <source>ACL authentication</source>
+ <target>Autenticação ACL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="137fbf154ecad4d580354db0858b76faea7e4686" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>Os nomes de usuário devem ter entre 8 e 64 caracteres e podem incluir caracteres alfanuméricos: '.', '@', '-', '_' ou ':'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">227,228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">287,288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="361771c32dd2254d77fd3fbf006b008983fe5907" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>As senhas devem ter entre 12 e 16 caracteres e podem incluir caracteres alfanuméricos: '@', '-', '_' ou '/'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">262,263</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">323,324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f494bd31f095f6dcc656ce87ec2dcf07a2e9b30c" datatype="html">
+ <source>Initiators</source>
+ <target>Iniciadores</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">335</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">588</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e98239d8a6be1100119ff4b5630c822b82786740" datatype="html">
+ <source>Initiator</source>
+ <target>Iniciador</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2c5059d8cda15d8d03e2cce30f2d139623d9a91" datatype="html">
+ <source>Client IQN</source>
+ <target>IQN do Cliente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="107d5aabce23d900f0a80e6ddc1c10e29aa0bed8" datatype="html">
+ <source>Initiator IQN needs to be unique.</source>
+ <target>O IQN do Iniciador precisa ser exclusivo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e7cad911fa524e512d9744b16358b7ee6791385" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>Os nomes de usuário devem ter entre 8 e 64 caracteres e podem incluir caracteres alfanuméricos: '.', '@', '-', '_' ou ':'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">394,395</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">452,453</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7f2c186d181206d0d2b1ff74819081a010f10bf" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>As senhas devem ter entre 12 e 16 caracteres e podem incluir caracteres alfanuméricos: '@', '-', '_' ou '/'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">427,428</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">485,486</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d1878d5fc761cbe9614bfd87047a740c82a6951" datatype="html">
+ <source>Initiator belongs to a group. Images will be configure in the group.</source>
+ <target>O iniciador pertence a um grupo. As imagens serão configuradas no grupo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">515</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0de67b9d97fafbf200f9451e8388ee8128a56ac" datatype="html">
+ <source>No items added.</source>
+ <target>Nenhum item adicionado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">671</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d565e47726158e428ecdc952fc9233b9b7d7f049" datatype="html">
+ <source>Add initiator</source>
+ <target>Adicionar iniciador</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">616</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c22ba03540aa3217da059f45e7eab138b51a96e2" datatype="html">
+ <source>Groups</source>
+ <target>Grupos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c90059afafb7e160384d9f512797c95bb95c6dc" datatype="html">
+ <source>Group</source>
+ <target>Grupo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cff1428d10d59d14e45edec3c735a27b5482db59" datatype="html">
+ <source>Name</source>
+ <target>Nome</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">576</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3084948274cff4f56d0f431af47240e9cf02fcc7" datatype="html">
+ <source>Add group</source>
+ <target>Adicionar grupo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">676</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6634268061646442252" datatype="html">
+ <source>There are no portals available.</source>
+ <target>Não há portais disponíveis.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4587015892789840153" datatype="html">
+ <source>There are no images available.</source>
+ <target>Não há imagens disponíveis.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7896905042057267575" datatype="html">
+ <source>There are no images available. Please make sure you add an image to the target.</source>
+ <target>Não há imagens disponíveis. Adicione uma imagem ao destino.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6765423558085969805" datatype="html">
+ <source>There are no initiators available. Please make sure you add an initiator to the target.</source>
+ <target>Não há iniciadores disponíveis. Adicione um iniciador ao destino.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2539932200265667453" datatype="html">
+ <source>target</source>
+ <target>destino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="051dcc342cfa5c1eaf187a2001aaa162379a160c" datatype="html">
+ <source>Configure</source>
+ <target>Configurar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e515f954730279c31d5301f02479666d6264e8b" datatype="html">
+ <source>Changing these parameters from their default values is usually not necessary.</source>
+ <target>Não costuma ser necessário mudar o valor padrão destes parâmetros.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e2591df099ddac796cda401c5f282da779d45f2" datatype="html">
+ <source>Identifier</source>
+ <target>Identificador</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62480a4859976427cf18fc8ef41d3a438eda0412" datatype="html">
+ <source>lun</source>
+ <target>lun</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8afc9eb4405e0aa554b2ba14140ef790cdecc040" datatype="html">
+ <source>wwn</source>
+ <target>wwn</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
+ <source>Settings</source>
+ <target>Configurações</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69a47cbabcc51ca942606e1d8da0ec11f98a2690" datatype="html">
+ <source>Backstore</source>
+ <target>Backstore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="339878da255ab55447c43afef8d9b2f9753bf5f6" datatype="html">
+ <source>Advanced Settings</source>
+ <target>Configurações Avançadas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="332227f088a4877b3c11f5fb3ae8bc812c470fae" datatype="html">
+ <source>iSCSI Targets not available</source>
+ <target>Destinos iSCSI não disponíveis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7fba666f1fff0182e570f12133fb3d622d9ea6" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the iSCSI Targets management functionality.</source>
+ <target>Consulte <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> sobre como configurar e habilitar a funcionalidade de gerenciamento de Destinos iSCSI.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3b301d0044f62c92af0da53d7aaca52a436a547d" datatype="html">
+ <source>Available information:</source>
+ <target>Informações disponíveis:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8414a5cb9d71cc1b21b10e4a9d1f2dad558f3361" datatype="html">
+ <source>Discovery authentication</source>
+ <target>Autenticação de descoberta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4854396465510517671" datatype="html">
+ <source>Target</source>
+ <target>Destino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4093869278527257288" datatype="html">
+ <source>Portals</source>
+ <target>Portais</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="414887388288176527" datatype="html">
+ <source>Images</source>
+ <target>Imagens</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="798573158169239055" datatype="html">
+ <source># Sessions</source>
+ <target>Nº de Sessões</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="646929398175374220" datatype="html">
+ <source>Unavailable gateway(s)</source>
+ <target>Gateway(s) não disponível(is)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2350612272163013640" datatype="html">
+ <source>Target has active sessions</source>
+ <target>O destino tem sessões ativas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4782410538666829801" datatype="html">
+ <source>iSCSI target</source>
+ <target>Destino iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">227</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8a9910cd114c1deb9af74f6f99b4173403965bf2" datatype="html">
+ <source>Gateways</source>
+ <target>Gateways</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911214550882917183" datatype="html">
+ <source>State</source>
+ <target>Estado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4121862424558610140" datatype="html">
+ <source># Targets</source>
+ <target>Nº de Destinos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101197021456818771" datatype="html">
+ <source>Pool</source>
+ <target>Pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3012906865384504293" datatype="html">
+ <source>Image</source>
+ <target>Imagem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2699995524827665158" datatype="html">
+ <source>Backstore</source>
+ <target>Backstore</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3559214740809905405" datatype="html">
+ <source>Read Bytes</source>
+ <target>Bytes de Leitura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1580583760095064067" datatype="html">
+ <source>Write Bytes</source>
+ <target>Bytes de Gravação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7225917547116479918" datatype="html">
+ <source>Read Ops</source>
+ <target>Op. de Leitura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6417507714454914481" datatype="html">
+ <source>Write Ops</source>
+ <target>Op. de Gravação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="257147267065394003" datatype="html">
+ <source>A/O Since</source>
+ <target>A/O Desde</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ecbc084370a732fc3cde1966a60af78d71424ab4" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>Criar Token de Boot</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603e9cc3ef2aab57f2b0a00e465b23b9cabefd9c" datatype="html">
+ <source>To create a bootstrap token which can be imported by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Generate<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Para criar um token de boot que possa ser importado por um cluster de site de peer, informe o nome do site local, selecione os pools que terão o espelhamento habilitado e clique em <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Gerar<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="660f97cd3188f8a04bd03b79e703fec72c6df04c" datatype="html">
+ <source>Site Name</source>
+ <target>Nome do Site</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2fecea01ce1d44114ee45144eff6d47a5016a74f" datatype="html">
+ <source>Name...</source>
+ <target>Nome...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92899fa68e8ca108912163ff58edc8540e453787" datatype="html">
+ <source>Pools</source>
+ <target>Pools</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c2a1dc72cffaf7ab3dc5599bf77b0a7fcad2b20" datatype="html">
+ <source>At least one pool is required.</source>
+ <target>Pelo menos um pool é necessário.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b258b258b4cc475ceb2871305b61756b0134f4a" datatype="html">
+ <source>Generate</source>
+ <target>Gerar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1edc1fc6cfbbb22353050ad6788508b3ed584f53" datatype="html">
+ <source>Token</source>
+ <target>Token</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff785f5596aef34a93b9b4d1023e95c62eef5740" datatype="html">
+ <source>Generated token...</source>
+ <target>Token gerado...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8" datatype="html">
+ <source>Close</source>
+ <target>Fechar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5467a6bb0e7fade6def7499400d5e2a7d8d3da20" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>Importar Token de Boot</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bb7aee0dec5164f45c0aa2f35f2fb2149d2c1d2" datatype="html">
+ <source>To import a bootstrap token which was created by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, provide the generated token, and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Import<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Para importar um token de boot que foi criado por um cluster de site de peer, informe o nome do site local, selecione os pools que terão o espelhamento habilitado, insira o token gerado e clique em <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Importar<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9200e09686136a1d42adfb89c12fbfef2deea125" datatype="html">
+ <source>Direction</source>
+ <target>Direção</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9761484679958da8d12841a4efa5964d33fae575" datatype="html">
+ <source>The token is invalid.</source>
+ <target>O token é inválido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2381859602529023966" datatype="html">
+ <source>Instance</source>
+ <target>Instância</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8040881171107393560" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1605455101862010019" datatype="html">
+ <source>Hostname</source>
+ <target>Nome de host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2724055831234181057" datatype="html">
+ <source>Version</source>
+ <target>Versão</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2041675390931385838" datatype="html">
+ <source>Health</source>
+ <target>Saúde</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87bd96249f8afc23f5301cddb57b1464a98e71a" datatype="html">
+ <source>Edit site name</source>
+ <target>Editar nome do site</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cfff72c667274c12eb1ff71eadc25871c10c42dc" datatype="html">
+ <source>Edit the site name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Edite o nome do site e clique em <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Atualizar<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">13,14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66db799d67958d4b0765181d072df62e2d1c16f5" datatype="html">
+ <source>Issues</source>
+ <target>Problemas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef06d69259e587e28d52372455f44c7153cda7e7" datatype="html">
+ <source>Syncing</source>
+ <target>Sincronizando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0b0901877d837d3fda16ba161eb74368d1c75b7a" datatype="html">
+ <source>Ready</source>
+ <target>Pronto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5833626790712999947" datatype="html">
+ <source>Issue</source>
+ <target>Problema</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3419681791450150574" datatype="html">
+ <source>Progress</source>
+ <target>Andamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4902817035128594900" datatype="html">
+ <source>Description</source>
+ <target>Descrição</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40b7acea5b43f45e0bbd1efeba5200af4687981d" datatype="html">
+ <source>Site Name:</source>
+ <target>Nome do Site:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e24f9e2d42104ffc01599db4d566d1cc518f9e6" datatype="html">
+ <source>Daemons</source>
+ <target>Daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6450386891540681425" datatype="html">
+ <source>Edit Site Name</source>
+ <target>Editar Nome do Site</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4645993115976933405" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>Criar Token de Boot</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4130053543590533787" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>Importar Token de Boot</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4057c56d63a7e9b140b1d01871a9229a5f30eb27" datatype="html">
+ <source>Edit pool mirror mode</source>
+ <target>Editar modo de espelho do pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e1f367f5feaab38f6637dd1f967c848b447dea2d" datatype="html">
+ <source>To edit the mirror mode for pool  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, select a new mode from the list and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Para editar o modo de espelho do pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, selecione um novo modo na lista e clique em <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Atualizar<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37e10df2d9c0c25ef04ac112c9c9a7723e8efae0" datatype="html">
+ <source>Mode</source>
+ <target>Modo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">426</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32ca348ef926b0a6a7a780b8b64c3a8239895cec" datatype="html">
+ <source>Peer clusters must be removed prior to disabling mirror.</source>
+ <target>Clusters de peer devem ser removidos antes de desabilitar o espelho.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5769292297914455214" datatype="html">
+ <source>Disabled</source>
+ <target>Desabilitado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ddcb416c1c0aa1f54acf5beef1de81813e76fa6" datatype="html">
+ <source>{VAR_SELECT, select, edit {Edit} other {Add}}</source>
+ <target>{VAR_SELECT, select, edit {Editar} other {Adicionar}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3aa7c3a4f7b0cf7c2e60fc71ea1e3b4c3efa3558" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> pool mirror peer</source>
+ <target><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> peer de espelho do pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="59ca65ece457429d90104ede4674965f62edbabe" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> the pool mirror peer attributes for pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Submit<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> os atributos do peer de espelho do pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> e clicar em <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Enviar<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d3cc964811f852a168f4a2d5daa59068abc5cf53" datatype="html">
+ <source>Cluster Name</source>
+ <target>Nome do Cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b631721fc56cb7fb1cbd07b802a487c5753f6a2d" datatype="html">
+ <source>The cluster name is not valid.</source>
+ <target>O nome do cluster não é válido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca6deafa31bf421f85094807982aee4bcb20a3ae" datatype="html">
+ <source>CephX ID</source>
+ <target>ID do CephX</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7539188a568c3d553cbde1bacaf32310c4264e24" datatype="html">
+ <source>CephX ID...</source>
+ <target>ID do CephX...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1c45b594b0fba22fc64e80c793a7ffe005fdb0e" datatype="html">
+ <source>The CephX ID is not valid.</source>
+ <target>O ID do CephX não é válido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20861576fcfce773c918c782cd4f5adf32382921" datatype="html">
+ <source>Monitor Addresses</source>
+ <target>Endereços do Monitor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fa28eeed2b4bd4ccbe6e9349a1c2b3cb1c5de70a" datatype="html">
+ <source>Comma-delimited addresses...</source>
+ <target>Endereços delimitados por vírgula...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dc016c82fd85848d5c1b2fd0e8469ee2027d9c16" datatype="html">
+ <source>The monitory address is not valid.</source>
+ <target>O endereço de monitoria não é válido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0ac55b83dc6739e62bc655cfe375b67c93e7f4a" datatype="html">
+ <source>CephX Key</source>
+ <target>Chave do CephX</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f53434bcb95bd86f1df9c8e22966f757614fc4ad" datatype="html">
+ <source>Base64-encoded key...</source>
+ <target>Chave codificada com base64...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4cd83164cd4f66b4abc2863f9ce6f599d789e4ca" datatype="html">
+ <source>CephX key must be base64 encoded.</source>
+ <target>A chave do CephX deve ser codificada com base64.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6407712033679505505" datatype="html">
+ <source>Edit Mode</source>
+ <target>Modo de Edição</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054237897979907103" datatype="html">
+ <source>Add Peer</source>
+ <target>Adicionar Peer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="899134641637789371" datatype="html">
+ <source>Edit Peer</source>
+ <target>Editar Peer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7393680121674824053" datatype="html">
+ <source>Delete Peer</source>
+ <target>Excluir Peer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1713271461473302108" datatype="html">
+ <source>Mode</source>
+ <target>Modo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1061297288634362831" datatype="html">
+ <source>Leader</source>
+ <target>Leader</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8517494870558773093" datatype="html">
+ <source># Local</source>
+ <target>Nº Local</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4953753699491987394" datatype="html">
+ <source># Remote</source>
+ <target>Nº Remoto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1715982232168082172" datatype="html">
+ <source>mirror peer</source>
+ <target>espelhar peer</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff92fbdec9fdd5054493eeda0d7ee8b450f83e72" datatype="html">
+ <source>RBD Configuration</source>
+ <target>Configuração de RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b62d9efc8eb3b589904f6cb96a0406bbda55673a" datatype="html">
+ <source>Remove the local configuration value. The parent configuration value will be inherited and used instead.</source>
+ <target>Remova o valor de configuração local. No lugar dele, o valor de configuração pai será herdado e usado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80d769fd863fe44fab689636a078466bfdbd1f20" datatype="html">
+ <source>The minimum value is 0</source>
+ <target>O valor mínimo é 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5decb3917d46a9ac6e5813699801becb7c3c1455" datatype="html">
+ <source>Global</source>
+ <target>Global</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f9ba9bb9faa8284bcadb1cdbc6aaf969e9c4bb" datatype="html">
+ <source>Image</source>
+ <target>Imagem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70fcca5a99575cffef3ff8cbd5e69f06ffd0f1c" datatype="html">
+ <source>Pool</source>
+ <target>Pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176659033176029418" datatype="html">
+ <source>Key</source>
+ <target>Chave</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9155608366859514313" datatype="html">
+ <source>Source</source>
+ <target>Origem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6555318547274416232" datatype="html">
+ <source>Value</source>
+ <target>Valor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f6e8f6094b180eaf1f11bc0ffe383f1cdcd059e" datatype="html">
+ <source>Only available for RBD images with <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> enabled</source>
+ <target>Disponível apenas para imagens RBD com <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> habilitado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f8b2bb476981727ab34ed40fde1218361f92c45" datatype="html">
+ <source>Details</source>
+ <target>Detalhes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03cc5b14b0a20d075e9009ff021f4f1660ba348a" datatype="html">
+ <source>Data Pool</source>
+ <target>Pool de Dados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b051734b0ee9021991c91b3ed4e81c244322462" datatype="html">
+ <source>Created</source>
+ <target>Criado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7faaaa08f56427999f3be41df1093ce4089bbd75" datatype="html">
+ <source>Size</source>
+ <target>Tamanho</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="afdb601c16162f2c798b16a2920955f1cc6a20aa" datatype="html">
+ <source>Objects</source>
+ <target>Objetos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ceac8e132384322ec778ba760875a6c6897d3e42" datatype="html">
+ <source>Object size</source>
+ <target>Tamanho do objeto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cdb1fea93d77c07950c0c76c6e0ad79ebbef084" datatype="html">
+ <source>Features</source>
+ <target>Recursos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65771c9a73b9aa609d592fc96a64801a8f40bd" datatype="html">
+ <source>Provisioned</source>
+ <target>Aprovisionado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84a36cb75660b736773fe36ffa3d54f0f0fe363e" datatype="html">
+ <source>N/A</source>
+ <target>N/A</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c009342a4e8381f64341d0bb61c2e4685f5a4b" datatype="html">
+ <source>Total provisioned</source>
+ <target>Total aprovisionado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f6bf8a43ae415f527ac961ea62471b983aaa97b" datatype="html">
+ <source>Striping unit</source>
+ <target>Unidade de distribuição</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db710e8a8f011923f2d15d713fbae49c38b02b26" datatype="html">
+ <source>Striping count</source>
+ <target>Total de distribuições</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a4c2a9e76634ff14a60d52a718296f722d47c67" datatype="html">
+ <source>Parent</source>
+ <target>Pai</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a209e68d78ffc2cc9c53d2e76158624efab71ad" datatype="html">
+ <source>Block name prefix</source>
+ <target>Prefixo do nome do bloco</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5704ec2049d007c5f5fb495a5d8b607e68d58081" datatype="html">
+ <source>Order</source>
+ <target>Ordem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="984cb6ad70f150a401b4daf841bd3cd957412699" datatype="html">
+ <source>Format Version</source>
+ <target>Versão do Formato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f21b1d17b6c5042bb5805516eee37fde33739dd8" datatype="html">
+ <source>Snapshots</source>
+ <target>Instantâneos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4a41f824a35ba01d5bd7be61aa06b3e8145209d0" datatype="html">
+ <source>Configuration</source>
+ <target>Configuração</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3cc9c2ae277393b3946b38c088dabff671b1ee1b" datatype="html">
+ <source>Performance</source>
+ <target>Desempenho</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935bb9cb0e4340fc74d33caa3b70d9d143fcad87" datatype="html">
+ <source>Information can not be displayed for RBD in status 'Removing'.</source>
+ <target>Não é possível exibir informações para RBD com status 'Removendo'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58e58f1a8786da9031a05e6770c5dafce82badf5" datatype="html">
+ <source>This setting overrides the global value</source>
+ <target>Esta configuração substitui o valor global</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36b46714164964c6258b08ed0a25f57d8a950f92" datatype="html">
+ <source>This is the global value. No value for this option has been set for this image.</source>
+ <target>Este é o valor global. Nenhum valor para esta opção foi definido para esta imagem.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6547c9c4d5f62942ac4b1fe459cf9a03d4dbf5a0" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> from</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> de</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0e9ecf29a4fa5b057bd8052e0d801b3fde6a30bf" datatype="html">
+ <source>'/' and '@' are not allowed.</source>
+ <target>'/' e '@' não são permitidos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="94516fa213706c67ce5a5b5765681d7fb032033a" datatype="html">
+ <source>Loading...</source>
+ <target>Carregando...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">209</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">452</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b99417c4dd46286ffd37c8d2e987c8b512ec7052" datatype="html">
+ <source>-- No rbd pools available --</source>
+ <target>-- Não há pools de RBD disponíveis --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef83ec9c304a89d45650e580dcdc2978c37b3a83" datatype="html">
+ <source>-- Select a pool --</source>
+ <target>-- Selecionar pool --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d649904466254d13df1fbf2d255f0bbc6553d213" datatype="html">
+ <source>-- No namespaces available --</source>
+ <target>-- Sem namespaces disponíveis --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e22d7bb4d2d561e0832ee0b9a3da2468a080c4f0" datatype="html">
+ <source>-- Select a namespace --</source>
+ <target>-- Selecionar namespace --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49449943d8cbf59d8c401c8bd2e76f92e207cc5f" datatype="html">
+ <source>Use a dedicated data pool</source>
+ <target>Usar pool de dados dedicado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa5b3c5ea5af14d09b2eb098039af9f1f77be010" datatype="html">
+ <source>You need more than one pool with the rbd application label use to use a dedicated data pool.</source>
+ <target>Você precisa mais do que um pool com o uso do rótulo de aplicativo rbd para utilizar um pool de dados dedicado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="870aee0dd31a9643bf62007beb8f1ae1deb34d42" datatype="html">
+ <source>Data pool</source>
+ <target>Pool de dados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3792ca829d9b9f687e1f5d7733d30e9bb0bfec47" datatype="html">
+ <source>Dedicated pool that stores the object-data of the RBD.</source>
+ <target>Pool dedicado que armazena os dados de objetos do RBD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151c80ea931037cd92e854442927f8a0f6ae7795" datatype="html">
+ <source>-- No data pools available --</source>
+ <target>-- Não há pools de dados disponíveis --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0016bd458baa88284a658ce9eeda42d8ad88d2c" datatype="html">
+ <source>e.g., 10GiB</source>
+ <target>ex. 10 GiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">206</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a88bbee20570aaf9615332fb27020627044874d" datatype="html">
+ <source>You have to increase the size.</source>
+ <target>Você precisa aumentar o tamanho.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cfe07dac5b4ee1c464eb24225ddeb4f1d24076a" datatype="html">
+ <source>Advanced...</source>
+ <target>Avançado...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bc2e854e111ecf2bd7db170da5e3c2ed08181d88" datatype="html">
+ <source>Advanced</source>
+ <target>Avançado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3562a3778695a5f9c0445660e35301f0a39aaf73" datatype="html">
+ <source>Striping</source>
+ <target>Distribuição</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef3c3f3b5f562a5cdbe0ee2874287db1534b5958" datatype="html">
+ <source>Stripe unit</source>
+ <target>Unidade de distribuição</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84471be1049006edecbcaef1a32ae0893c229c50" datatype="html">
+ <source>-- Select stripe unit --</source>
+ <target>-- Selecionar unidade de distribuição --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">289</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d32c5c54c8581c774a7f467fbd4e329b15a74fa" datatype="html">
+ <source>This field is required because stripe count is defined!</source>
+ <target>Este campo é obrigatório porque o total de distribuições foi definido!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bbf9040be7c5491d4a03f2185708f43a6582a3b" datatype="html">
+ <source>Stripe unit is greater than object size.</source>
+ <target>A unidade de distribuição é maior do que o tamanho do objeto.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a682f49f9b761591661276d7c6f550e641a130a4" datatype="html">
+ <source>Stripe count</source>
+ <target>Total de distribuições</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="baa74031990c5370008ba622d0a250f0929097f4" datatype="html">
+ <source>This field is required because stripe unit is defined!</source>
+ <target>Este campo é obrigatório porque a unidade de distribuição foi definida!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cd2ada6d5ecbd5cbf89eae0a1f5326efedac0dbc" datatype="html">
+ <source>Stripe count must be greater than 0.</source>
+ <target>O total de distribuições deve ser maior do que 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4341718109173132593" datatype="html">
+ <source>RBD</source>
+ <target>RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1359455778569887786" datatype="html">
+ <source>Deep flatten</source>
+ <target>Nivelamento profundo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58519213655664125" datatype="html">
+ <source>Layering</source>
+ <target>Disposição em camadas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844531889615887801" datatype="html">
+ <source>Exclusive lock</source>
+ <target>Bloqueio exclusivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4585281635594103106" datatype="html">
+ <source>Object map (requires exclusive-lock)</source>
+ <target>Mapa de objetos (requer bloqueio exclusivo)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240933649452133654" datatype="html">
+ <source>Journaling (requires exclusive-lock)</source>
+ <target>Registro em diário (requer bloqueio exclusivo)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3713046526850391848" datatype="html">
+ <source>Fast diff (interlocked with object-map)</source>
+ <target>Diff rápido (interligado com o mapa de objetos)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19f1e825536efbf7492723a7c2d01ad23a4e994b" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1774b9915b0e302d02cad0b9321ad5f1a83247a8" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c9f1026c1235f4d76ace47449e806efd181ab332" datatype="html">
+ <source>Deleting this image will also delete all its snapshots.</source>
+ <target>A exclusão desta imagem também excluirá todos os seus instantâneos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55f864597e84d9bf88769e1fbfda1d64452430c9" datatype="html">
+ <source>The following snapshots are currently protected and will be removed:</source>
+ <target>Os seguintes instantâneos estão protegidos e serão removidos:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2e362ec498c4c9112dc47a3cb7d7250ca8e71790" datatype="html">
+ <source>RBD in status 'Removing'</source>
+ <target>RBD com status 'Removendo'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3294686077659093992" datatype="html">
+ <source>Namespace</source>
+ <target>Namespace</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45739481977493163" datatype="html">
+ <source>Size</source>
+ <target>Tamanho</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7531602241051125940" datatype="html">
+ <source>Objects</source>
+ <target>Objetos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1194977199378511591" datatype="html">
+ <source>Object size</source>
+ <target>Tamanho do objeto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">226</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="178418048502923560" datatype="html">
+ <source>Provisioned</source>
+ <target>Aprovisionado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7638291694671392137" datatype="html">
+ <source>Total provisioned</source>
+ <target>Total aprovisionado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8621797738551294959" datatype="html">
+ <source>Parent</source>
+ <target>Pai</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616639680594151867" datatype="html">
+ <source>This RBD has cloned snapshots. Please delete related RBDs before deleting this RBD.</source>
+ <target>Este RBD tem instantâneos clonados. Exclua os RBDs relacionados antes de excluir esse RBD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2900827028308925059" datatype="html">
+ <source>This RBD image has an invalid name and can't be managed by ceph.</source>
+ <target>Esta imagem RBD tem um nome inválido e não pode ser gerenciada pelo ceph.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1796389652493657142" datatype="html">
+ <source>Action not possible for an RBD in status 'Removing'</source>
+ <target>A ação não é possível para um RBD com status 'Removendo'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">476</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c07d24bb422aa8e5e568df1c5709083f0a9c8f1" datatype="html">
+ <source>Create Namespace</source>
+ <target>Criar Namespace</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cca6c0485f96d3a9610d0339cb1275a5f2c3f46" datatype="html">
+ <source>Namespace already exists.</source>
+ <target>Namespace já existe.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4641528557519966449" datatype="html">
+ <source>Created namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <target>Namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>' criado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6809428596104996786" datatype="html">
+ <source>Total images</source>
+ <target>Total de imagens</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1346311774128536550" datatype="html">
+ <source>Deleted namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <target>Namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>' excluído</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7605466414392298530" datatype="html">
+ <source>Namespace contains images</source>
+ <target>Namespace contém imagens</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576483965711201552" datatype="html">
+ <source>RBD Snapshot</source>
+ <target>Instantâneo do RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3473055924346204357" datatype="html">
+ <source>Parent image must support Layering</source>
+ <target>A imagem pai deve suportar Disposição em Camadas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1152535233999495900" datatype="html">
+ <source>Snapshot must be protected in order to clone.</source>
+ <target>O instantâneo deve ser protegido para ser feita a clonagem.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c5331983af566d4ac6a1024d15a3511786a4aa6" datatype="html">
+ <source>You are about to rollback</source>
+ <target>Você está prestes a fazer rollback</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6240400332778072187" datatype="html">
+ <source>PROTECTED</source>
+ <target>PROTEGIDO</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9101667614062185213" datatype="html">
+ <source>UNPROTECTED</source>
+ <target>NÃO PROTEGIDO</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4207916966377787111" datatype="html">
+ <source>Created</source>
+ <target>Criado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587768621777516124" datatype="html">
+ <source>RBD snapshot rollback</source>
+ <target>Rollback de instantâneo do RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">305</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2711198699676132148" datatype="html">
+ <source>Rollback</source>
+ <target>Fazer Rollback</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3330476395115957823" datatype="html">
+ <source>RBD snapshot</source>
+ <target>Instantâneo do RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">322</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3a7e364a88ea4673199dfa98bc73e6dbe09dfac" datatype="html">
+ <source>Namespaces</source>
+ <target>Namespaces</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aba82bfd8e177d35b76cad7cd43941f8e5e5acac" datatype="html">
+ <source>Trash</source>
+ <target>Lixo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5e7f4b1ca49e8d217bd0e12c6f7d6b6a2ade2c18" datatype="html">
+ <source>Overall Performance</source>
+ <target>Desempenho Geral</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c0408946a6d67185947f455f15cc201d0d78e6" datatype="html">
+ <source>Purge Trash</source>
+ <target>Purgar Lixo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c96a761dc55a21882c132c929583a424c9b8cf4" datatype="html">
+ <source>Expired at</source>
+ <target>Venceu em</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="661041e3fcff4d3e75c561e038ca2504cf2cc643" datatype="html">
+ <source>Protected until</source>
+ <target>Protegido até</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee3b2322a1d3277f7e3fdb8a5141ac42bcf350b" datatype="html">
+ <source>This image is protected until <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</source>
+ <target>Esta imagem está protegida até <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5611592591303869712" datatype="html">
+ <source>Status</source>
+ <target>Status</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">213</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">285</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2155633476201267204" datatype="html">
+ <source>Deleted At</source>
+ <target>Excluído à(s)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0b5d789d42c0e69348e5fe0037fcbf5b5fbbdcc" datatype="html">
+ <source>Move an image to trash</source>
+ <target>Mover imagem para o lixo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ad22c1d4aab3b8946603cea62de266d5129ca10" datatype="html">
+ <source>This image contains snapshot(s), which will prevent it from being removed after moved to trash.</source>
+ <target>Esta imagem contém instantâneos, o que a impedirá de ser removida depois de enviada para o lixo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">15,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d4a5f5698bc8118b2e120b9bb72eff339094dd0" datatype="html">
+ <source>To move <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> to trash, click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Move<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Optionally, you can pick an expiration date.</source>
+ <target>Para mover <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> para o lixo, clique em <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Mover<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Se preferir, escolha uma data de vencimento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">19,20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f27d390844aad53b4240360e928156c5f0d326" datatype="html">
+ <source>Protection expires at</source>
+ <target>Vencimento da proteção em</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da166e9a0d27322f6ba8916d71ecc0f9905bb4b1" datatype="html">
+ <source>NOT PROTECTED</source>
+ <target>NÃO PROTEGIDO</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1506e5f2ca22cad14502ec7a20fb6113ace145d" datatype="html">
+ <source>Wrong date format. Please use &quot;YYYY-MM-DD HH:mm:ss&quot;.</source>
+ <target>Formato de data incorreto. Use &quot;AAAA-MM-DD HH:mm:ss&quot;.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa7ea0bb7495281e0b3258467ac7d90a1e44a1a1" datatype="html">
+ <source>Protection has already expired. Please pick a future date or leave it empty.</source>
+ <target>A proteção já venceu. Escolha uma data no futuro ou deixe-a vazia.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d8613436532acac2b97d17de28b50f93e6bd0222" datatype="html">
+ <source>To purge, select  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>All<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>  or one pool and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Purge<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </source>
+ <target>Para purgar, selecione <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Tudo<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> ou um pool e clique em <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Purgar<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55a4f598a4894b7fd5cb88f0ffd3c37ad009dd70" datatype="html">
+ <source>Pool:</source>
+ <target>Pool:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d43dd2b9f7797e4cf3a604695bb33e4479108516" datatype="html">
+ <source>Pool name...</source>
+ <target>Nome do pool...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dfc3c34e182ea73c5d784ff7c8135f087992dac1" datatype="html">
+ <source>All</source>
+ <target>Tudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0e7c7ed1d51a0c205c815048bc9f79e24ee6db2" datatype="html">
+ <source>Restore Image</source>
+ <target>Restaurar Imagem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3bc4aaf0dce75dc5e01ee5c825a652dc8aea8f0" datatype="html">
+ <source>To restore  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>,  type the image's new name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Restore<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>Para restaurar <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, digite o novo nome da imagem e clique em <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Restaurar<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41307dd56fea669eed72e12a6c23af275f6bfd82" datatype="html">
+ <source>New Name</source>
+ <target>Novo Nome</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3625859417927520024" datatype="html">
+ <source>id</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6537904131139019667" datatype="html">
+ <source>type</source>
+ <target>tipo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8901220148451863928" datatype="html">
+ <source>state</source>
+ <target>estado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7925190601961269841" datatype="html">
+ <source>version</source>
+ <target>versão</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6641024648411549335" datatype="html">
+ <source>Host</source>
+ <target>Host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773272191572353800" datatype="html">
+ <source>root</source>
+ <target>raiz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6364513948635353490" datatype="html">
+ <source>Evicted client '<x id="PH" equiv-text="clientId"/>'</source>
+ <target>Cliente '<x id="PH" equiv-text="clientId"/>' expulso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c1e17956453ad772dbe82d6946f62748c692f3e" datatype="html">
+ <source>Ranks</source>
+ <target>Posições</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b24e0b0b1629d2e8a51b9da7c75d6e6379f4bc4" datatype="html">
+ <source>Standbys</source>
+ <target>Standbys</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="50df62325726db950523a5be1c78b8905fcc25d4" datatype="html">
+ <source>MDS performance counters</source>
+ <target>Contadores de desempenho MDS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4578796959376778578" datatype="html">
+ <source>Standby daemons</source>
+ <target>Daemons de standby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="665219418211496660" datatype="html">
+ <source>Rank</source>
+ <target>Posição</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5445409664838149993" datatype="html">
+ <source>Daemon</source>
+ <target>Daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5306473977542913614" datatype="html">
+ <source>Activity</source>
+ <target>Atividade</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3998441303515229547" datatype="html">
+ <source>Dentries</source>
+ <target>Dentries</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7877631502958415163" datatype="html">
+ <source>Inodes</source>
+ <target>Inodes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6129397096478256985" datatype="html">
+ <source>Dirs</source>
+ <target>Diretórios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3011876564696453148" datatype="html">
+ <source>Caps</source>
+ <target>Recursos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8650499415827640724" datatype="html">
+ <source>Type</source>
+ <target>Tipo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="142654590491855672" datatype="html">
+ <source>Usage</source>
+ <target>Uso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">326</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb8293aa8161433778762ae025ffd5e7c85795e" datatype="html">
+ <source>Quotas</source>
+ <target>Cotas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">540</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66785722678644243" datatype="html">
+ <source>Origin</source>
+ <target>Origem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8911059720204770105" datatype="html">
+ <source>Path</source>
+ <target>Caminho</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6111756909052789805" datatype="html">
+ <source>Cannot create snapshots for files/folders in the subvolume <x id="PH" equiv-text="folders[2]"/></source>
+ <target>Não é possível criar instantâneos para arquivos/pastas no subvolume <x id="PH" equiv-text="folders[2]"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7503263437025060215" datatype="html">
+ <source>Max size</source>
+ <target>Tamanho máx.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6763343019307619111" datatype="html">
+ <source>Max files</source>
+ <target>Máx. de arquivos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327403486214540377" datatype="html">
+ <source>The inherited <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> is the maximum value to be used.</source>
+ <target>O <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> herdado é o valor máximo que será usado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">434,437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3768927257183755959" datatype="html">
+ <source>Save</source>
+ <target>Salvar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">440</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6328794256834621774" datatype="html">
+ <source><x id="PH" equiv-text="action"/> CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> quota for '<x id="PH_2" equiv-text="path"/>'</source>
+ <target><x id="PH" equiv-text="action"/> Cota <x id="PH_1" equiv-text="this.getQuotaName()"/> do CephFS para '<x id="PH_2" equiv-text="path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">446</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9130352375983418123" datatype="html">
+ <source>size</source>
+ <target>tamanho</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6889473896134264260" datatype="html">
+ <source>files</source>
+ <target>arquivos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2244434638607433133" datatype="html">
+ <source><x id="PH" equiv-text="this.getQuotaName()"/> quota <x id="PH_1" equiv-text="value"/> from '<x id="PH_2" equiv-text="path"/>'</source>
+ <target><x id="PH" equiv-text="this.getQuotaName()"/> cota <x id="PH_1" equiv-text="value"/> de '<x id="PH_2" equiv-text="path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">460</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6960117167304061503" datatype="html">
+ <source>Value has to be at least 0 or more</source>
+ <target>O valor deve ser no mínimo 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">484</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6740501370117796629" datatype="html">
+ <source>Value has to be at most <x id="PH" equiv-text="maxValue"/> or less</source>
+ <target>O valor deve ser no máximo <x id="PH" equiv-text="maxValue"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7239750919884229270" datatype="html">
+ <source>Updated</source>
+ <target>Atualizado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">499</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8885980874806414253" datatype="html">
+ <source>in order to inherit <x id="PH" equiv-text="quotaValue"/></source>
+ <target>para herdar <x id="PH" equiv-text="quotaValue"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4182949309891923991" datatype="html">
+ <source>which isn't used because of the inheritance of <x id="PH" equiv-text="quotaValue"/></source>
+ <target>que não é usado por causa da herança de <x id="PH" equiv-text="quotaValue"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7421970649864638435" datatype="html">
+ <source>in order to have no quota on the directory</source>
+ <target>para não ter cota no diretório</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6730229976797004508" datatype="html">
+ <source><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</source>
+ <target><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">530,533</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="827679535246546876" datatype="html">
+ <source>Create Snapshot</source>
+ <target>Criar Instantâneo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">542</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">552</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4747656362969857823" datatype="html">
+ <source>Please enter the name of the snapshot.</source>
+ <target>Insira o nome do instantâneo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3667696812078358068" datatype="html">
+ <source>Created snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <target>Instantâneo '<x id="PH" equiv-text="name"/>' criado para '<x id="PH_1" equiv-text="path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="753342836137587734" datatype="html">
+ <source>CephFs Snapshot</source>
+ <target>Instantâneo do CephFs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">670</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2774104291801979963" datatype="html">
+ <source>Deleted snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <target>Instantâneo '<x id="PH" equiv-text="name"/>' excluído para '<x id="PH_1" equiv-text="path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">683</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4816216590591222133" datatype="html">
+ <source>Enabled</source>
+ <target>Habilitado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ffe39df9d88c972792bd8688b215392deb8313d" datatype="html">
+ <source>Clients</source>
+ <target>Clientes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e213942c6354b9cbe7a650f0f1499bfc1000fb6" datatype="html">
+ <source>Directories</source>
+ <target>Diretórios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fbbaf5cb02ed419e79a27072478f716a4666a99d" datatype="html">
+ <source>Performance Details</source>
+ <target>Detalhes de Desempenho</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0" datatype="html">
+ <source>Description</source>
+ <target>Descrição</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ad112ce9bcd55dfd137792a86afe1b5a5b13cf8" datatype="html">
+ <source>Long description</source>
+ <target>Descrição extensa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="26fb5f81b3581f06b9210defb0e71dc69a67e819" datatype="html">
+ <source>Current values</source>
+ <target>Valores atuais</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7cee38a2259526c519f878e71b964f41db4348" datatype="html">
+ <source>Default</source>
+ <target>Padrão</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33e1c1d9fc05ca3f62fcc8a1170fc31ebae4229c" datatype="html">
+ <source>Daemon default</source>
+ <target>Padrão do daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f61c6867295f3b53d23557021f2f4e0aa1d0b8fc" datatype="html">
+ <source>Type</source>
+ <target>Tipo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9abcd7c82643d60c22733470463f74e4a54bc069" datatype="html">
+ <source>Min</source>
+ <target>Mín.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3ced4d162a0a55ee233a187ce7208ba5e922418" datatype="html">
+ <source>Max</source>
+ <target>Máx.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="920617c6a1a4805e53bcb5af6a9c76f8387e89c6" datatype="html">
+ <source>Flags</source>
+ <target>Flags</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5" datatype="html">
+ <source>Services</source>
+ <target>Serviços</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6834fa6b43d1ecbdf147c48dd9c4d72f1484571d" datatype="html">
+ <source>Source</source>
+ <target>Origem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a446fb0eb11fbffcac805ece5a2d306d24e733d8" datatype="html">
+ <source>Level</source>
+ <target>Nível</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39f2fb094e9b2eda13163fa3f3a31594cf9c1307" datatype="html">
+ <source>Can be updated at runtime (editable)</source>
+ <target>Pode ser atualizado em tempo de execução (editável)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
+ <source>Tags</source>
+ <target>Tags</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ab0089ef47af61ca1d137bc908b96c290dfd9287" datatype="html">
+ <source>Enum values</source>
+ <target>Valores de enum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="819476f1264f1659f38e86f6abb542141b184832" datatype="html">
+ <source>See also</source>
+ <target>Consulte também</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="543199344025799954" datatype="html">
+ <source>The value can be updated at runtime.</source>
+ <target>É possível atualizar o valor em temo de execução.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1718354829128482129" datatype="html">
+ <source>Daemons/clients do not pull this value from the
+ monitor config database. We disallow setting this option via 'ceph config
+ set ...'. This option should be configured via ceph.conf or via the
+ command line.</source>
+ <target>Daemons/clientes não extraem este valor do
+ banco de dados de configuração do monitor. A configuração desta opção não é permitida por meio de 'ceph config
+ set ...'. Essa opção deve ser configurada por meio do ceph.conf ou da
+ linha de comando.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">15,18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2345189734548717257" datatype="html">
+ <source>Option takes effect only during daemon startup.</source>
+ <target>A opção entra em vigor apenas durante a inicialização do daemon.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5523310713159993513" datatype="html">
+ <source>Option only affects cluster creation.</source>
+ <target>A opção afeta apenas a criação do cluster.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1064479086902933123" datatype="html">
+ <source>Option only affects daemon creation.</source>
+ <target>A opção afeta apenas a criação do daemon.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="809b0c848932a41318f77a2aace904ef429c13f4" datatype="html">
+ <source>Values</source>
+ <target>Valores</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5894f7158499fdb89527af50c9f1cf7d4c95cad6" datatype="html">
+ <source>-- Default --</source>
+ <target>-- Padrão --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="514f6e12d035a6d9b00de6b3e55c18b73488da07" datatype="html">
+ <source>true</source>
+ <target>verdadeiro</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="774f5e6a183dea08393789b6f72e86afad729419" datatype="html">
+ <source>false</source>
+ <target>falso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="82029b6db704c56a2aa3e82ac555b8655356b077" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>.</source>
+ <target>O valor inserido é muito alto! Ele não deve ser maior do que <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ed8b3967a7326b81b191c9f490006e6a6777a9a" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>.</source>
+ <target>O valor inserido é muito baixo! Ele não deve ser menor do que <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2337058106409853613" datatype="html">
+ <source>Updated config option <x id="PH" equiv-text="request.name"/></source>
+ <target>Opção de configuração <x id="PH" equiv-text="request.name"/> atualizada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3733215288982610673" datatype="html">
+ <source>Level</source>
+ <target>Nível</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2218082343053095278" datatype="html">
+ <source>Service</source>
+ <target>Serviço</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3553216189604488439" datatype="html">
+ <source>Modified</source>
+ <target>Modificado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844248428439297756" datatype="html">
+ <source>Current value</source>
+ <target>Valor atual</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208877297843037352" datatype="html">
+ <source>Editable</source>
+ <target>Editável</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b266042bac4c3a2eff4834e40fb9dc4767a709" datatype="html">
+ <source>Cluster Resources</source>
+ <target>Recursos de Cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="099b441d49333b3c6d30b36dc0a4763e64c78920" datatype="html">
+ <source>Hosts</source>
+ <target>Hosts</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57e6e608ece53a26f6d509c90ed4f83e467741af" datatype="html">
+ <source>Storage Capacity</source>
+ <target>Capacidade de Armazenamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19ece2cb2b9097c0f75af8e62b4b3b25d399a006" datatype="html">
+ <source>Number of devices</source>
+ <target>Número de dispositivos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b161e3d25fd1b42a781f4e923a58a94925988ddf" datatype="html">
+ <source>Raw capacity</source>
+ <target>Capacidade bruta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb6f3e2a26f3a6f2bc33f91adcd60502dbe5adac" datatype="html">
+ <source>CPUs</source>
+ <target>CPUs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58d4a9814864741040bc5905b6a368836e683f76" datatype="html">
+ <source>Memory</source>
+ <target>Memória</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dbb81e566a861d4aa0a094366e4083e50863ee92" datatype="html">
+ <source>Host Details</source>
+ <target>Detalhes do Host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="453dc2810080a744223faac6da2b3ee9ed63a583" datatype="html">
+ <source>Welcome to <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></source>
+ <target>Boas-vindas ao <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1eec874e1928ca53baa9914781ce203b5f72b0c" datatype="html">
+ <source>Please expand your cluster first</source>
+ <target>Expanda seu cluster primeiro</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2195fd96b0a00f560449b50bd032e6d9b357730" datatype="html">
+ <source>Expand Cluster</source>
+ <target>Expandir Cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb075d0450deb6f381616f7da4b9244ced843053" datatype="html">
+ <source>Skip</source>
+ <target>Ignorar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55b6ce65571b8893440a4fc92776570f8fe7cc97" datatype="html">
+ <source>Add Hosts</source>
+ <target>Adicionar Hosts</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="162f763675c24b557a60eba0758558222369e0c7" datatype="html">
+ <source>Create OSDs</source>
+ <target>Criar OSDs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fef7a7b8db05c351c5287db48488abca530bdb54" datatype="html">
+ <source>Create Services</source>
+ <target>Criar Serviços</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="176873b4533ddeabf95992cbd7b91b9d01c6d557" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ed90ec4409b9f6b552982d96f89db27259e763c" datatype="html">
+ <source>You are about to skip the cluster expansion process. You’ll need to <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>navigate through the menu to add hosts and services.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>Você está prestes a ignorar o processo de expansão do cluster. Será necessário <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>navegar pelo menu para adicionar hosts e serviços.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">90,91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d1dcf2a9146caac0581329acf94806ec69a89a5" datatype="html">
+ <source>Are you sure you want to continue?</source>
+ <target>Deseja realmente continuar?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6759205696902713848" datatype="html">
+ <source>Warning</source>
+ <target>Aviso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">357</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6962699013778688473" datatype="html">
+ <source>Continue</source>
+ <target>Continuar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6156560100092571435" datatype="html">
+ <source>Cluster expansion skipped by user</source>
+ <target>Expansão do cluster ignorada pelo usuário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520085823873354736" datatype="html">
+ <source>Cluster expansion was successful</source>
+ <target>Expansão do cluster bem-sucedida</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176230351113290618" datatype="html">
+ <source>Expand Cluster</source>
+ <target>Expandir Cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="738de688b22fba5d0dc7a5e549996838dddad0ee" datatype="html">
+ <source>CRUSH map viewer</source>
+ <target>Visualizador de mapa CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/crushmap/crushmap.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e24569eca61d598c8b01defbbbb1fa8bd5222bc" datatype="html">
+ <source>Devices</source>
+ <target>Dispositivos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17137bac47e1e020d139256ded0006a671966e73" datatype="html">
+ <source>Physical Disks</source>
+ <target>Discos Físicos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="deba10b7279a589d01e919ea11f43c79ca1773e3" datatype="html">
+ <source>Device health</source>
+ <target>Saúde do dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d87fc20ea8e5f0f0500ba5d5061b345be78ec5e" datatype="html">
+ <source>No hostname found.</source>
+ <target>Nenhum nome de host encontrado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9a541ec1a4319fffc16ad3b3ab2c2b6d251a829d" datatype="html">
+ <source>Hostname</source>
+ <target>Nome de host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee6875e67b53cac30a02b57cf76e485f7e60caf4" datatype="html">
+ <source>To add multiple hosts at once, you can enter:</source>
+ <target>Para adicionar vários hosts de uma vez, você pode inserir:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a8370b19ccf673fb28fa9db36a08f9901887cc7" datatype="html">
+ <source>a comma-separated list of hostnames <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-01,example-02,example-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <target>uma lista de nomes de host separados por vírgula <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(ex.: example-01,example-02,example-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="68f2c05396ec8a5f59e8da42d1f6c7310fa8c37c" datatype="html">
+ <source>a range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <target>uma expressão de faixa <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(ex.: example-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e00b9bba448e79add37740e53dc953fbb89f9c5" datatype="html">
+ <source>a comma separated range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></source>
+ <target>uma expressão de faixas separadas por vírgula <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(ex.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b3f5e5291541678f7afa49d28fad5ca848a8061" datatype="html">
+ <source>The chosen hostname is already in use.</source>
+ <target>O nome de host escolhido já está em uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="42365f623c57973d1d13d2038e8a2d4c02fb9b9f" datatype="html">
+ <source>Network address</source>
+ <target>Endereço da rede</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3859bdca1ae89e611e214c205fccf0147b4d0f6b" datatype="html">
+ <source>The value is not a valid IP address.</source>
+ <target>O valor não é um endereço IP válido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2af7efecfae8d7fed3b07f718a623eca1ad8163f" datatype="html">
+ <source>Labels</source>
+ <target>Rótulos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9da2afd4fa358b66d4d95fe7e8f4b659a7144e" datatype="html">
+ <source>Maintenance Mode</source>
+ <target>Modo de Manutenção</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="468785112451259935" datatype="html">
+ <source>There are no labels.</source>
+ <target>Não há rótulos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4664081995078497865" datatype="html">
+ <source>Filter or add labels</source>
+ <target>Filtrar ou adicionar rótulos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4897817053917542646" datatype="html">
+ <source>Add label</source>
+ <target>Adicionar rótulo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">313</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1187321380561233505" datatype="html">
+ <source>host</source>
+ <target>host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40661476cb24c89d8b06614998e31d5fbe84eeb6" datatype="html">
+ <source>Hosts List</source>
+ <target>Lista de Hosts</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b7a4e1e5a316f8547af1d6d2311a5cec8c5c1d87" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ msg }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ msg }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6e8e8844e9e7a7b626a4699c08b6c0c81297a7b" datatype="html">
+ <source>Data will be available only if Orchestrator is available.</source>
+ <target>Os dados estarão disponíveis apenas se o Orchestrator estiver disponível.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4baf526199fed59071adf555271791283adc408" datatype="html">
+ <source>SSD, NVMEs</source>
+ <target>SSD, NVMEs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="22d5531d79f0d7269a0a752e56a848807dd37095" datatype="html">
+ <source>Flash</source>
+ <target>Flash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4025065730478477779" datatype="html">
+ <source>The feature is disabled because the selected host is not managed by Orchestrator.</source>
+ <target>O recurso está desabilitado porque o host selecionado não é gerenciado pelo Orchestrator.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7143579180750436311" datatype="html">
+ <source>Services</source>
+ <target>Serviços</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="546766753072101168" datatype="html">
+ <source>Labels</source>
+ <target>Rótulos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1141886420788473147" datatype="html">
+ <source>Model</source>
+ <target>Modelo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4027647877328291519" datatype="html">
+ <source>CPUs</source>
+ <target>CPUs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2445398473573060226" datatype="html">
+ <source>Cores</source>
+ <target>Núcleos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1656823484917332451" datatype="html">
+ <source>Total Memory</source>
+ <target>Memória Total</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1939212557812454069" datatype="html">
+ <source>Raw Capacity</source>
+ <target>Capacidade Bruta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5579687933271468638" datatype="html">
+ <source>HDDs</source>
+ <target>HDDs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1889285841762768492" datatype="html">
+ <source>Flash</source>
+ <target>Flash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1578709829957887527" datatype="html">
+ <source>NICs</source>
+ <target>NICs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4723031838495967601" datatype="html">
+ <source>Edit Host: <x id="PH" equiv-text="host.hostname"/></source>
+ <target>Editar Host: <x id="PH" equiv-text="host.hostname"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6004907173026319041" datatype="html">
+ <source>Edit Host</source>
+ <target>Editar Host</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5618131051466022401" datatype="html">
+ <source>Updated Host &quot;<x id="PH" equiv-text="host.hostname"/>&quot;</source>
+ <target>Host Atualizado &amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1701954433367210342" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; moved to maintenance</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; movido para manutenção</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3108406586869160854" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; cannot be put into maintenance</source>
+ <target>Não é possível colocar &amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; em manutenção</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1737753151350322492" datatype="html">
+ <source><x id="PH" equiv-text="error.error['detail']"/></source>
+ <target><x id="PH" equiv-text="error.error['detail']"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4054533801359952167" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; has exited maintenance</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; saiu da manutenção</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5837599005212786659" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; stopped draining</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host['hostname']"/>&amp;quot; parou a drenagem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1357236071975782353" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; started draining</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host['hostname']"/>&amp;quot; iniciou a drenagem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5658400717636093668" datatype="html">
+ <source>Identify</source>
+ <target>Identificar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6966707768479328825" datatype="html">
+ <source>Device path</source>
+ <target>Caminho do dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3955868613858648955" datatype="html">
+ <source>Available</source>
+ <target>Disponível</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="158816374076721379" datatype="html">
+ <source>Vendor</source>
+ <target>Fornecedor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6024104799101504292" datatype="html">
+ <source>OSDs</source>
+ <target>OSDs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3422162477846071958" datatype="html">
+ <source>Identify device <x id="PH" equiv-text="device"/></source>
+ <target>Identificar o dispositivo <x id="PH" equiv-text="device"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4910073658089977244" datatype="html">
+ <source>Please enter the duration how long to blink the LED.</source>
+ <target>Informe por quanto tempo o LED deve ficar piscando.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5764931367607989415" datatype="html">
+ <source>1 minute</source>
+ <target>1 minuto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809466133764752509" datatype="html">
+ <source>2 minutes</source>
+ <target>2 minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">235</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1487672983218679675" datatype="html">
+ <source>5 minutes</source>
+ <target>5 minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603584938775296395" datatype="html">
+ <source>10 minutes</source>
+ <target>10 minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6648333117195452824" datatype="html">
+ <source>15 minutes</source>
+ <target>15 minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6560281329999108838" datatype="html">
+ <source>Execute</source>
+ <target>Executar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6901229416977800100" datatype="html">
+ <source>Identifying '<x id="PH" equiv-text="device"/>' started on host '<x id="PH_1" equiv-text="hostname"/>'</source>
+ <target>Identificação de '<x id="PH" equiv-text="device"/>' iniciada no host '<x id="PH_1" equiv-text="hostname"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d556ab48a65722b400e497f61737f553ee0f89e2" datatype="html">
+ <source>Cluster Logs</source>
+ <target>Registros do Cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5f966baffd188be0e8adc2d7067b86e55fc9b9de" datatype="html">
+ <source>Audit Logs</source>
+ <target>Registros de Auditoria</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4193c9eb868aeec119b78a14795241e0aa5e8b60" datatype="html">
+ <source>Priority:</source>
+ <target>Prioridade:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d78ca51eab260ce3fd917d39190d64df5229b6e" datatype="html">
+ <source>Keyword:</source>
+ <target>Palavra-chave:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="05fa0bded36de6e73a1fa44838b627349dace044" datatype="html">
+ <source>Date:</source>
+ <target>Data:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a400388de1899b1917138cf7e5286376f72847" datatype="html">
+ <source>Time range:</source>
+ <target>Faixa de horários:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="de0478286b8b5a939db54e9e5282405364ad2d61" datatype="html">
+ <source>No log entries found. Please try to select different filter options.</source>
+ <target>Nenhuma entrada de registro encontrada. Tente selecionar outras opções de filtro.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7479674d91142b785b9547a87e5fb51cb16108" datatype="html">
+ <source>Reset filter.</source>
+ <target>Redefinir filtro.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="31a9c2870a934b594d1390146c489f76440859ea" datatype="html">
+ <source>Edit Manager module</source>
+ <target>Editar módulo do gerenciador</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="46e09b8290d3d0afdb6baa2021395b0570606a31" datatype="html">
+ <source>The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</source>
+ <target>O valor inserido não é um UUID válido. Ex.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7aacd038b39cfd347107d01d1dc27f5cb3e0951c" datatype="html">
+ <source>The entered value needs to be a valid IP address.</source>
+ <target>O valor inserido precisa ser um endereço IP válido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f19106149f4b07a0d721f9d317afed393cb7bd93" datatype="html">
+ <source>The entered value is too high! It must be lower or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>.</source>
+ <target>O valor inserido é muito alto! Ele deve ser menor do que ou igual a <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d33c40ef9a6c3bf0888df831b25e41e65f9d15b" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>.</source>
+ <target>O valor inserido é muito baixo! Ele deve ser maior do que ou igual a <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eae7086660cf1e38c7194a2c49ff52cc656f90f5" datatype="html">
+ <source>The entered value needs to be a number.</source>
+ <target>O valor inserido precisa ser um número.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">194</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a73376e04b4fb3a20734c8c39743fba32e6676ce" datatype="html">
+ <source>The entered value needs to be a number or decimal.</source>
+ <target>O valor inserido precisa ser um número ou decimal.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1898719236268328097" datatype="html">
+ <source>Updated options for module '<x id="PH" equiv-text="this.moduleName"/>'.</source>
+ <target>Opções atualizadas para o módulo '<x id="PH" equiv-text="this.moduleName"/>'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4186041075388034600" datatype="html">
+ <source>Always-On</source>
+ <target>Sempre ativado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7585826646011739428" datatype="html">
+ <source>Edit</source>
+ <target>Editar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2180291763949669799" datatype="html">
+ <source>Enable</source>
+ <target>Habilitar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9187855490716817910" datatype="html">
+ <source>Disable</source>
+ <target>Desabilitar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1600086764852993170" datatype="html">
+ <source>This Manager module is always on.</source>
+ <target>Este módulo do Gerenciador está sempre ativado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3895296744591223546" datatype="html">
+ <source>Reconnecting, please wait ...</source>
+ <target>Reconectando, aguarde...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81b97b8ea996ad1e4f9fca8415021850214884b1" datatype="html">
+ <source>Status</source>
+ <target>Status</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57ec6032f5618d4a9f16eb950ad23d2ce7c24b54" datatype="html">
+ <source>Cluster ID</source>
+ <target>ID do Cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67d7facc3fec5f8a49ab9ba0a245872184264ce5" datatype="html">
+ <source>monmap modified</source>
+ <target>monmap modificado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4906731aaf2b94b4f547646c9bfe58bb77951b6" datatype="html">
+ <source>monmap epoch</source>
+ <target>época de monmap</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd4ee06ffdc46d9dfbd0c0c4f81399021c680056" datatype="html">
+ <source>quorum con</source>
+ <target>quorum con</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1176c7db8a8276ccb44cc3d42e2c28d9fa6c6596" datatype="html">
+ <source>quorum mon</source>
+ <target>quorum mon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="530ef677a09d681b3ab68cb0760494b3ae72a77c" datatype="html">
+ <source>required con</source>
+ <target>con obrigatório</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a91558e0d506c32021c31843f8f168899fc65cbf" datatype="html">
+ <source>required mon</source>
+ <target>mon obrigatório</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3abe9eac5bcd94a54c8da93b312e085ec512e74" datatype="html">
+ <source>In Quorum</source>
+ <target>No Quorum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba4b748a676e1f217ce1e736fb7ec1215e677bae" datatype="html">
+ <source>Not In Quorum</source>
+ <target>Não está no Quorum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3517477838460618200" datatype="html">
+ <source>Public Address</source>
+ <target>Endereço Público</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6949358970125514744" datatype="html">
+ <source>Open Sessions</source>
+ <target>Sessões Abertas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4383e9662ea19839c7499b2128d43a195e564317" datatype="html">
+ <source>OSD creation preview</source>
+ <target>Visualização da criação do OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="366225c51e0b00bcb1c55795a0dc5e81c455f84e" datatype="html">
+ <source>DriveGroups</source>
+ <target>DriveGroups</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91853167141c37b58868f3b0421383dd72fa8a01" datatype="html">
+ <source>Attributes (OSD map)</source>
+ <target>Atributos (mapa OSD)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f721a500a68c357e8f2a01e60510f6a01e4ba529" datatype="html">
+ <source>Metadata</source>
+ <target>Metadados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97842f379e1d4157ac3ab0661b90c352e7cb72d5" datatype="html">
+ <source>Metadata not available</source>
+ <target>Metadados não disponíveis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24e28e19c5703d7c6be44f4eb595a6a43b618ed" datatype="html">
+ <source>Performance counter</source>
+ <target>Contador de desempenho</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ccb4f84edc0b4e76415bb3f9b73d725b06683af3" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ name }}"/> devices</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ name }}"/> dispositivos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60cb3d01e5ddf266ecb4271007a1c3d0f3efdc22" datatype="html">
+ <source>The primary storage devices. These devices contain all OSD data.</source>
+ <target>Os dispositivos de armazenamento principais. Esses dispositivos contêm todos os dados de OSD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b432e04886d0d1fd84f740477383051f85addcf2" datatype="html">
+ <source>Write-Ahead-Log devices. These devices are used for BlueStore’s internal journal. It is only useful to use a WAL device if the device is faster than the primary device (e.g. NVME devices or SSDs). If there is only a small amount of fast storage available (e.g., less than a gigabyte), we recommend using it as a WAL device.</source>
+ <target>Dispositivos Write-Ahead-Log. Esses dispositivos são usados no diário interno do BlueStore. Apenas será útil usar um dispositivo WAL se ele for mais rápido do que o dispositivo principal (por exemplo, dispositivos NVME ou SSDs). Se houver apenas um pequeno volume de armazenamento rápido disponível (por exemplo, menos do que um gigabyte), recomendamos usá-lo como dispositivo WAL.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87e181ab9e8393aa5ed759dd3d53836e32c8ffe" datatype="html">
+ <source>DB devices can be used for storing BlueStore’s internal metadata. It is only helpful to provision a DB device if it is faster than the primary device (e.g. NVME devices or SSD).</source>
+ <target>É possível usar dispositivos de BD para armazenar metadados internos do BlueStore. A provisão de um dispositivo de BD será útil apenas se ele for mais rápido do que o dispositivo principal (ex. dispositivos NVME ou SSD).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
+ <source>Add</source>
+ <target>Adicionar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="99ee4faa69cd2ea8e3678c1f557c0ff1f05aae46" datatype="html">
+ <source>Clear</source>
+ <target>Limpar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e0fd3c7af0630f93befa6234a693a32a61084e0" datatype="html">
+ <source>Raw capacity: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></source>
+ <target>Capacidade bruta: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1961811273151129466" datatype="html">
+ <source>No available devices</source>
+ <target>Sem dispositivos disponíveis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617271647728055571" datatype="html">
+ <source>Please add primary devices first</source>
+ <target>Adicione primeiro os dispositivos principais</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6368751795251107516" datatype="html">
+ <source>Add devices by using filters</source>
+ <target>Adicionar dispositivos usando filtros</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8edc89137d0d8c5667a2f03230beafae45e58429" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> devices</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> dispositivos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eba28e1805b18f7c8ae2e4bc15dcf063b10b3822" datatype="html">
+ <source>At least one of these filters must be applied in order to proceed:</source>
+ <target>Pelo menos um destes filtros deve ser aplicado para continuar:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="93389aa2fe2bea50bf89554ee51b28f87ee2fb50" datatype="html">
+ <source>Number of devices: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Raw capacity: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</source>
+ <target>Número de dispositivos: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Capacidade bruta: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">29,30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6b27c16ddf33b855412c82069dca8120bd3a68a" datatype="html">
+ <source>Individual OSD Flags</source>
+ <target>Flags OSD Individuais</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dba0ed9ba355a3bd3296c0bef3bb518744a51a89" datatype="html">
+ <source>Cluster-wide</source>
+ <target>Todo o cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e2a3f211cea2cbadb29b6df93e544440b6b68d3e" datatype="html">
+ <source>Restore previous selection</source>
+ <target>Restaurar seleção anterior</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1683654169791509804" datatype="html">
+ <source>No Up</source>
+ <target>Não Ativo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5754783193519044074" datatype="html">
+ <source>OSDs are not allowed to start</source>
+ <target>Os OSDs não podem ser iniciados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4413588319909369773" datatype="html">
+ <source>No Down</source>
+ <target>Não Inativo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1348746748821823470" datatype="html">
+ <source>OSD failure reports are being ignored, such that the monitors will not mark OSDs down</source>
+ <target>Os relatórios de falha de OSD estão sendo ignorados, portanto, os monitores não marcarão os OSDs como inativos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="301172600132606646" datatype="html">
+ <source>No In</source>
+ <target>Não Entrada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4114057962148673377" datatype="html">
+ <source>OSDs that were previously marked out will not be marked back in when they start</source>
+ <target>Os OSDs que já foram marcados como saída não serão remarcados como entrada ao serem iniciados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5236523991485603657" datatype="html">
+ <source>No Out</source>
+ <target>Não Saída</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1798160169020638994" datatype="html">
+ <source>OSDs will not automatically be marked out after the configured interval</source>
+ <target>Os OSDs não serão automaticamente marcados como saída após o intervalo configurado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3225813593817914267" datatype="html">
+ <source>The flag has been enabled for the entire cluster.</source>
+ <target>A flag foi habilitada no cluster inteiro.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1941050626944682985" datatype="html">
+ <source>Updated OSD Flags</source>
+ <target>Flags OSD Atualizadas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ef50ba2514414f799d4c8fc36067a251904ba81" datatype="html">
+ <source>Cluster-wide OSD Flags</source>
+ <target>Flags OSD de todo o Cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9042260521669277115" datatype="html">
+ <source>Pause</source>
+ <target>Pausar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6015425610572318971" datatype="html">
+ <source>Pauses reads and writes</source>
+ <target>Pausa leituras e gravações</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314873595759611676" datatype="html">
+ <source>No Scrub</source>
+ <target>Sem Remoção</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773570234687653570" datatype="html">
+ <source>Scrubbing is disabled</source>
+ <target>Remoção desabilitada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5999821123886006899" datatype="html">
+ <source>No Deep Scrub</source>
+ <target>Sem Remoção Profunda</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5362685148875251772" datatype="html">
+ <source>Deep Scrubbing is disabled</source>
+ <target>Remoção Profunda desabilitada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5001752039592388485" datatype="html">
+ <source>No Backfill</source>
+ <target>Sem Provisionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4851280330655956778" datatype="html">
+ <source>Backfilling of PGs is suspended</source>
+ <target>Provisionamento de PGs suspenso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5994953210305546559" datatype="html">
+ <source>No Rebalance</source>
+ <target>Sem Rebalanceamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3698980403470604587" datatype="html">
+ <source>OSD will choose not to backfill unless PG is also degraded</source>
+ <target>O OSD não fará o provisionamento, a menos que o PG também seja prejudicado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4334886823145076432" datatype="html">
+ <source>No Recover</source>
+ <target>Sem Recuperação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8465994741155792816" datatype="html">
+ <source>Recovery of PGs is suspended</source>
+ <target>Recuperação de PGs suspensa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4052740759486923001" datatype="html">
+ <source>Bitwise Sort</source>
+ <target>Classificação Bit a Bit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2330377428425572488" datatype="html">
+ <source>Use bitwise sort</source>
+ <target>Usar classificação bit a bit</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8943478424576832224" datatype="html">
+ <source>Purged Snapdirs</source>
+ <target>Snapdirs Purgados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7553321860087551262" datatype="html">
+ <source>OSDs have converted snapsets</source>
+ <target>OSDs converteram snapsets</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6509988280998256208" datatype="html">
+ <source>Recovery Deletes</source>
+ <target>Exclusões de Recuperação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="451760144355116641" datatype="html">
+ <source>Deletes performed during recovery instead of peering</source>
+ <target>Exclusões realizadas durante a recuperação, e não o emparelhamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="87832369463084597" datatype="html">
+ <source>PG Log Hard Limit</source>
+ <target>Limite Físico do Registro de PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9135782750879343185" datatype="html">
+ <source>Puts a hard limit on pg log length</source>
+ <target>Atribui um limite físico ao tamanho do registro de PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="formTitle" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <note priority="1" from="description">Example: Create Pool</note>
+ <note priority="1" from="meaning">form title</note>
+ </trans-unit>
+ <trans-unit id="43ecf6bee2aebc07b0aad6dc1fe13e38d14687fa" datatype="html">
+ <source>Shared devices</source>
+ <target>Dispositivos compartilhados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7a1c376f6f1b37de4c318ff2106255ba6c0f5b0b" datatype="html">
+ <source>WAL slots</source>
+ <target>Slots WAL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73811a6f37b63e6b0e491e221bfa21e9dea8a87a" datatype="html">
+ <source>How many OSDs per WAL device.</source>
+ <target>Quantos OSDs por dispositivo WAL.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c67a7ac4762ef1cc855056c6b4daab93e53a0a5" datatype="html">
+ <source>Specify 0 to let Orchestrator backend decide it.</source>
+ <target>Especifique 0 para que o backbend do Orchestrator tome essa decisão.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bda9362e06e6c67341b4a8425b0d29d6b84464b" datatype="html">
+ <source>Value should be greater than or equal to 0</source>
+ <target>O valor deve ser maior do que ou igual a 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="324c2b10152b9dd908222bb0b71f61beb60a30c5" datatype="html">
+ <source>DB slots</source>
+ <target>Slots do BD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c23cf12ef9c76f37fc7a4b7ae3e00fb0f68b6e26" datatype="html">
+ <source>How many OSDs per DB device.</source>
+ <target>Quantos OSDs por dispositivo de BD.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8255877266497322342" datatype="html">
+ <source>Encryption</source>
+ <target>Criptografia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b49d7877d24112d4bdfce9256edf61a007fae888" datatype="html">
+ <source>OSDs List</source>
+ <target>Lista de OSDs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="172ada0fcf6490b24a897517e9f4299215873ff8" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD(s) <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be marked <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <target><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD(s) <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> será(ão) marcado(s) <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> se você continuar.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">59,60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="262a49e60d5f6ed9825582ccf3d5ae39daa1da60" datatype="html">
+ <source>The <x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> not safe to be <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>! <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></source>
+ <target>O(s) <x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> inseguro(s) para ser <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>! <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71,72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="74bd20d5f558d14cb2fa41ae863cf09c47d02018" datatype="html">
+ <source>{VAR_SELECT, select, true {OSD is} other {OSDs are}}</source>
+ <target>{VAR_SELECT, select, true {OSD é} other {OSDs são}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0e217fd717c5b1f5c17f00c5b174de855acbef0" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <target><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> será <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> se você continuar.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">74,75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8cf121660bed7098516a1efe85831d6f415a9411" datatype="html">
+ <source>Preserve OSD ID(s) for replacement.</source>
+ <target>Preserve o(s) ID(s) do OSD para substituição.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4435645098786961170" datatype="html">
+ <source>out</source>
+ <target>saída</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136018875175606726" datatype="html">
+ <source>in</source>
+ <target>entrada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1301930865667956193" datatype="html">
+ <source>down</source>
+ <target>inativo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1226060325201042854" datatype="html">
+ <source>Mark</source>
+ <target>Marcar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1256299033316818951" datatype="html">
+ <source>OSD lost</source>
+ <target>OSD perdido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2795727560928976873" datatype="html">
+ <source>marked lost</source>
+ <target>marcado como perdido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7685933846431786388" datatype="html">
+ <source>Purge</source>
+ <target>Purgar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5941516286393808546" datatype="html">
+ <source>OSD</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3416443212235382421" datatype="html">
+ <source>purged</source>
+ <target>purgado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9191368063029792986" datatype="html">
+ <source>destroy</source>
+ <target>destruir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4425946029386289247" datatype="html">
+ <source>destroyed</source>
+ <target>destruído</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2870788902465061969" datatype="html">
+ <source>Flags</source>
+ <target>Flags</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8995035642420075344" datatype="html">
+ <source>Recovery Priority</source>
+ <target>Prioridade de Recuperação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3601135996773579607" datatype="html">
+ <source>PG scrub</source>
+ <target>Remoção do PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136079353894161076" datatype="html">
+ <source>Device class</source>
+ <target>Classe do dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6382718875453721838" datatype="html">
+ <source>PGs</source>
+ <target>PGs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3660230483843323377" datatype="html">
+ <source>Read bytes</source>
+ <target>Bytes de leitura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">329</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3909578649547040612" datatype="html">
+ <source>Write bytes</source>
+ <target>Bytes de gravação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3182358405280886750" datatype="html">
+ <source>Read ops</source>
+ <target>Op. de leitura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171292502535561083" datatype="html">
+ <source>Write ops</source>
+ <target>Op. de gravação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6706824709967518168" datatype="html">
+ <source>Edit OSD: <x id="PH" equiv-text="selectedOsd.id"/></source>
+ <target>Editar OSD: <x id="PH" equiv-text="selectedOsd.id"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">451</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1125148356983553148" datatype="html">
+ <source>Edit OSD</source>
+ <target>Editar OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="970212458427610374" datatype="html">
+ <source>Updated OSD '<x id="PH" equiv-text="selectedOsd.id"/>'</source>
+ <target>OSD '<x id="PH" equiv-text="selectedOsd.id"/>' atualizado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">466</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7554728686176829307" datatype="html">
+ <source>Mark OSD <x id="PH" equiv-text="markAction"/></source>
+ <target>Marcar OSD <x id="PH" equiv-text="markAction"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="478122291463667978" datatype="html">
+ <source>Mark <x id="PH" equiv-text="markAction"/></source>
+ <target>Marcar <x id="PH" equiv-text="markAction"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">502</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2456043080471762298" datatype="html">
+ <source>delete</source>
+ <target>excluir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">530</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="588230151780724018" datatype="html">
+ <source>deleted</source>
+ <target>excluído</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">532</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1ef1c12ddcee305353623919ef02778569f5454" datatype="html">
+ <source>Advanced configuration options</source>
+ <target>Opções de configuração avançada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7771252117308888928" datatype="html">
+ <source>PG scrub options</source>
+ <target>Opções de remoção do PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1797901277775175680" datatype="html">
+ <source>Updated PG scrub options</source>
+ <target>Opções de remoção do PG atualizadas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c35f9c5f268a514b970cc55e9a5dc4bed0988e7f" datatype="html">
+ <source>OSD Recovery Priority</source>
+ <target>Prioridade de Recuperação de OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74af38005e8a8914e45af2ec412e11ceafef8b6" datatype="html">
+ <source>Priority</source>
+ <target>Prioridade</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f48f04b379bfba133825747adfd238d511412e" datatype="html">
+ <source>Customize priority values</source>
+ <target>Personalizar valores de prioridade</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aa19de2a2b54cbda39e9c62917b23044c087776" datatype="html">
+ <source>This field is required!</source>
+ <target>Este campo é obrigatório!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">406</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b699e94bf376491bd50b70a98531071c737eaf40" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="98fe13e7ad6c2b80375d204b47858ded83f80e15" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>.</source>
+ <target>O valor inserido é muito alto! Ele não deve ser maior do que <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423a3c111be47fc5a1bfe46ceb58c81c84db691" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>.</source>
+ <target>O valor inserido é muito baixo! Ele não deve ser menor do que <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3234179038052466481" datatype="html">
+ <source>Max Backfills</source>
+ <target>Máx. de Provisionamentos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847070960491384020" datatype="html">
+ <source>Recovery Max Active</source>
+ <target>Máx. Recuperação Ativo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2088615724570210504" datatype="html">
+ <source>Recovery Max Single Start</source>
+ <target>Máx. Recuperação Inicialização Única</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8627094894361422565" datatype="html">
+ <source>Recovery Sleep</source>
+ <target>Suspensão de Recuperação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7590013429208346303" datatype="html">
+ <source>Custom</source>
+ <target>Personalizado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4937275625032609020" datatype="html">
+ <source>Updated OSD recovery speed priority '<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>'</source>
+ <target>Prioridade de velocidade de recuperação de OSD '<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>' atualizada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">227,229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5251a4355cece3075db43f15d69a24a0f8485707" datatype="html">
+ <source>Reweight OSD: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></source>
+ <target>Reponderar OSD: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67650b2998db48201b2c6176cbfef51e7211ccaa" datatype="html">
+ <source>The value needs to be between 0 and 1.</source>
+ <target>O valor precisa ser entre 0 e 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f077ceb52c967a8fe2de9ef0a9d65d72badf186" datatype="html">
+ <source>OSDs <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/>Scrub</source>
+ <target>Remoção <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/> de OSDs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b73a34ba65b3073e3560dce828a16d7fd3c0f4" datatype="html">
+ <source>{VAR_SELECT, select, true {Deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {Profunda } other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c00119503aad4012b77049eee41293338f67756c" datatype="html">
+ <source>You are about to apply a <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/>scrub to the OSD(s): <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <target>Você está prestes a aplicar uma remoção <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/> ao(s) OSD(s): <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fad3dc421817a16dd6c46c1a0c36de619a8d776e" datatype="html">
+ <source>{VAR_SELECT, select, true {deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {profunda } other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1086427836866943370" datatype="html">
+ <source><x id="PH" equiv-text="operation"/> was initialized in the following OSD(s): <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></source>
+ <target><x id="PH" equiv-text="operation"/> foi inicializado no(s) seguinte(s) OSD(s): <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts</context>
+ <context context-type="linenumber">42,44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47c97aa28f64b11fa5842795fdd02c8c0863c97b" datatype="html">
+ <source>To see all active Prometheus alerts, please provide the URL to the API of Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>Para ver todos os alertas ativos do Prometheus, insira o URL para a API do Alertmanager do Prometheus conforme descrito em <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6343323763459782070" datatype="html">
+ <source>Create Silence</source>
+ <target>Criar Silêncio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1895957424873987405" datatype="html">
+ <source>Job</source>
+ <target>Tarefa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491474782694268231" datatype="html">
+ <source>Severity</source>
+ <target>Gravidade</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3326877877555410533" datatype="html">
+ <source>Started</source>
+ <target>Iniciado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2375260419993138758" datatype="html">
+ <source>URL</source>
+ <target>URL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="880ad4df5a2051a437321443d69c9a866699e5ad" datatype="html">
+ <source>Active Alerts</source>
+ <target>Alertas Ativos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9fe218829514884cdd0ca2300573a4e0428c324f" datatype="html">
+ <source>Alerts</source>
+ <target>Alertas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa0c44aa1e5727061baa91e954f77e2f5f9a37c9" datatype="html">
+ <source>Silences</source>
+ <target>Silêncios</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85c737325f5e59517e2d08a71de6d77788aabc95" datatype="html">
+ <source>To see all configured Prometheus alerts, please provide the URL to the API of Prometheus as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>Para ver todos os alertas configurados do Prometheus, insira o URL para a API do Prometheus conforme descrito em <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623978917681527907" datatype="html">
+ <source>Group</source>
+ <target>Grupo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7410432243549869948" datatype="html">
+ <source>Duration</source>
+ <target>Duração</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4109205891084963566" datatype="html">
+ <source>Query</source>
+ <target>Consulta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28f86ffd419b869711aa13f5e5ff54be6d70731c" datatype="html">
+ <source>Edit</source>
+ <target>Editar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="826b25211922a1b46436589233cb6f1a163d89b7" datatype="html">
+ <source>Delete</source>
+ <target>Excluir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">279</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">341</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">441</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3ba06aba047605af8ea1718ec1ba153b7db12a2" datatype="html">
+ <source>Editing a silence will expire the old silence and recreate it as a new silence</source>
+ <target>A edição de um silêncio expira o silêncio anterior e o recria como um novo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a20424156b8816671f61879f0574a4f27d7b16b9" datatype="html">
+ <source>Creator</source>
+ <target>Criador</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5a5d7ee2acbfa9c91ab7f41d26bda9ff0cafe42f" datatype="html">
+ <source>Comment</source>
+ <target>Comentário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c11aad490b2d53fdae30b3807beabf79306752c" datatype="html">
+ <source>Start time</source>
+ <target>Horário de início</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32856b1e8e339b747b21e313e2fe65a51fd450bb" datatype="html">
+ <source>If the start time lies in the past the creation time will be used</source>
+ <target>Se o horário de início estiver no passado, o horário de criação será usado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a02ea1d4e7424ca989929da5e598f379940fdbf2" datatype="html">
+ <source>Duration</source>
+ <target>Duração</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f4e35e36f4d3c62e2c17df41730b6dee4afc4b9" datatype="html">
+ <source>End time</source>
+ <target>Horário de término</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="992123459137d45c15df5548bc9682aad835c04b" datatype="html">
+ <source>Matchers</source>
+ <target>Correspondentes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e023166c55833d5a13f4143e3dbe372befe1b4e" datatype="html">
+ <source>A silence requires at least one matcher</source>
+ <target>Um silêncio requer pelo menos um correspondente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef765bd80c4806c51c891908c07a24bc76f019eb" datatype="html">
+ <source>Add matcher</source>
+ <target>Adicionar correspondente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754178820914251524" datatype="html">
+ <source>silence</source>
+ <target>silêncio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8714559758543060819" datatype="html">
+ <source>Attribute name</source>
+ <target>Nome do atributo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1338733395833138319" datatype="html">
+ <source>Regular expression</source>
+ <target>Expressão regular</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35819898450851998" datatype="html">
+ <source>Please add your Prometheus host to the dashboard configuration and refresh the page</source>
+ <target>Adicione seu host do Prometheus à configuração do painel de controle e atualize a página</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f2f4cb9d876ff9d34fc082c1ac642d3cb98c360" datatype="html">
+ <source>To enable Silences, please provide the URL to the API of the Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>Para habilitar Silêncios, insira o URL para a API do Alertmanager do Prometheus conforme descrito em <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7448808151142843482" datatype="html">
+ <source>Created by</source>
+ <target>Criado por</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4734349318830134239" datatype="html">
+ <source>Ends</source>
+ <target>Termina em</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1233087251567318644" datatype="html">
+ <source>Silence</source>
+ <target>Silêncio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="78af6a5e6e4d305557054b64d10f9f9446d8043d" datatype="html">
+ <source>{VAR_SELECT, select, true {Edit} other {Add}}</source>
+ <target>{VAR_SELECT, select, true {Editar} other {Adicionar}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2404fa8e80946d0ce3d0ae369b51cb26ec28d42" datatype="html">
+ <source><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/> Matcher</source>
+ <target><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/> Correspondente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c25e04f554875dc2625a78ba0fc56c6010cd0d3" datatype="html">
+ <source>-- Select an attribute to match against --</source>
+ <target>-- Selecionar atributo para correspondência --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5049e204c14c648691ac775a64fb504467aeb549" datatype="html">
+ <source>Value</source>
+ <target>Valor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="77fc5c63497fc031ddc97645484e3d94ad27766c" datatype="html">
+ <source>Use regular expression</source>
+ <target>Usar expressão regular</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5518753745858598442" datatype="html">
+ <source>no spec</source>
+ <target>sem especificação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1186363766752354382" datatype="html">
+ <source>unmanaged</source>
+ <target>não gerenciado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5246585784774990516" datatype="html">
+ <source>count:<x id="PH" equiv-text="count"/></source>
+ <target>total:<x id="PH" equiv-text="count"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001661117318762535" datatype="html">
+ <source>label:<x id="PH" equiv-text="label"/></source>
+ <target>rótulo:<x id="PH" equiv-text="label"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cb3aa7e9fea1d445a1a9d7797ab17e6ac6fe13b" datatype="html">
+ <source>Service Events</source>
+ <target>Eventos de Serviço</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3474944817987674409" datatype="html">
+ <source>Daemon type</source>
+ <target>Tipo de daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3136939605470297323" datatype="html">
+ <source>Daemon ID</source>
+ <target>ID do Daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8171022601808215887" datatype="html">
+ <source>Container ID</source>
+ <target>ID do Container</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8859473568390700297" datatype="html">
+ <source>Container Image name</source>
+ <target>Nome da Imagem do container</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5623167616584404899" datatype="html">
+ <source>Container Image ID</source>
+ <target>ID da Imagem do Container</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="335348913532561915" datatype="html">
+ <source>Last Refreshed</source>
+ <target>Última Atualização</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3022087209429182774" datatype="html">
+ <source>Daemon Events</source>
+ <target>Eventos de Daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">140</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8604852007710946848" datatype="html">
+ <source>Service Name</source>
+ <target>Nome do Serviço</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="613875387304159316" datatype="html">
+ <source>Service Type</source>
+ <target>Tipo de Serviço</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907644935670421963" datatype="html">
+ <source>Service Events</source>
+ <target>Eventos de Serviço</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3214a1f3a4c3e89a848b4ec59adeeda3b913c396" datatype="html">
+ <source>-- Select a service type --</source>
+ <target>-- Selecionar um tipo de serviço --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f32579a9fd19d93c083175284ee3426d78751c33" datatype="html">
+ <source>Backend Service</source>
+ <target>Serviço de Backend</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2937074aed12b8158e929c58747a8216433b72b" datatype="html">
+ <source>-- No service available --</source>
+ <target>-- Nenhum serviço disponível --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19fb4480d95a5539db4e9c7b516d414774e61110" datatype="html">
+ <source>-- Select an existing RGW service --</source>
+ <target>-- Selecionar serviço RGW existente --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2798cc1e152b1ec07fd8daf94a2a073d1ba1ebcc" datatype="html">
+ <source>Id</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d5156b9d9a79d162c353c4aa9bc6840ad5c6257" datatype="html">
+ <source>The value does not match the pattern <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&lt;service_id&gt;[.&lt;realm_name&gt;.&lt;zone_name&gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <target>O valor não corresponde ao padrão <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&amp;lt;service_id&amp;gt;[.&amp;lt;realm_name&amp;gt;.&amp;lt;zone_name&amp;gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83d5d7edd8a0be253c4e93ad4c3efe86d9ac520f" datatype="html">
+ <source>Unmanaged</source>
+ <target>Não gerenciado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c15fa461935e0f600bc5d1660af1da67f024fc2a" datatype="html">
+ <source>Placement</source>
+ <target>Posicionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="863226cffd5b66a6fee9810a9282a5006d6ef576" datatype="html">
+ <source>Label</source>
+ <target>Rótulo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06412bce0f4fe4311193e9763666089bf9d980da" datatype="html">
+ <source>Count</source>
+ <target>Total</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f193722f1e788f14a823b89ac1794c3ba934f9f" datatype="html">
+ <source>Only that number of daemons will be created.</source>
+ <target>Apenas este número de daemons será criado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee1a29cc658e4fa891be762d7bae96139b57c8f4" datatype="html">
+ <source>The value must be at least 1.</source>
+ <target>O valor deve ser no mínimo 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">369</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cb2741a46e3560f6bc6dfd99d385e86b08b26d72" datatype="html">
+ <source>Port</source>
+ <target>Porta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a23ed3598cca5285606675b6cb2536a56b411ade" datatype="html">
+ <source>The value cannot exceed 65535.</source>
+ <target>O valor não pode exceder 65535.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">404</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d8ebdc326e6b9ff35feee3f762b7ab39c02d78f" datatype="html">
+ <source>-- No pools available --</source>
+ <target>-- Nenhum pool disponível --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84b675705324741b954615fedf2417d4d873b0b6" datatype="html">
+ <source>Trusted IPs</source>
+ <target>IPs Confiáveis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b543e7c787cc48c2938cbce2d14c6afea5a598df" datatype="html">
+ <source>Comma separated list of IP addresses.</source>
+ <target>Lista de endereços IP separados por vírgula.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1039ea40da18a6453d9c1adc72a35aed099029d0" datatype="html">
+ <source>Please add the <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> IP addresses here, otherwise the iSCSI gateways can't be reached.</source>
+ <target>Adicione os endereços IP do <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> aqui; do contrário, os gateways iSCSI não poderão ser acessados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6265b64c17a1e19775769489bfd0b152fa1f3ba1" datatype="html">
+ <source>Virtual IP</source>
+ <target>IP Virtual</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61893fde6e9e05a6b91619d501edaa7962b438ff" datatype="html">
+ <source>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</source>
+ <target>O endereço IP virtual e a sub-rede (na notação CIDR) em que o serviço de entrada estará disponível.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">333</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ece04ddf7e96f445415ebd90d93c455e03e8cf53" datatype="html">
+ <source>Frontend Port</source>
+ <target>Porta de Front-end</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">352</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae6fd97454d184b374984c9ff808176ece54f0dd" datatype="html">
+ <source>The port used to access the ingress service.</source>
+ <target>A porta usada para acessar o serviço de entrada.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1261eacf161f75efc9dfea84dd97b4a466b89aa1" datatype="html">
+ <source>Monitor Port</source>
+ <target>Porta do Monitor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4df6281ed630ba96f09790a46a7fe0ec0e666bb6" datatype="html">
+ <source>The port used by haproxy for load balancer status.</source>
+ <target>A porta usada pelo haproxy para status do balanceador de carga.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ce24ae1d792ed2846ba57e7ed6397a802caeff5" datatype="html">
+ <source>CIDR Networks</source>
+ <target>Redes CIDR</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">414</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7c13184af0c09e3bad77daa5f4869138708d26b2" datatype="html">
+ <source>A list of networks to identify which network interface to use for the virtual IP address.</source>
+ <target>Uma lista de redes para identificar a interface de rede que será usada para o endereço IP virtual.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8fe73a4787b8068b2ba61f54ab7e0f9af2ea1fc9" datatype="html">
+ <source>Version</source>
+ <target>Versão</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a6855d17f6b9820bb9709870efdcc7da99552d3" datatype="html">
+ <source>-- Select SNMP version --</source>
+ <target>-- Selecionar versão SNMP --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">442</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a7369891e88cd613e45a39b55a282c97776d05f5" datatype="html">
+ <source>Destination</source>
+ <target>Destino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f09a5d334a73a4b5ba031d7fa65151cad5ec7133" datatype="html">
+ <source>Must be of the format hostname:port.</source>
+ <target>Deve estar no formato nomedehost:porta.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b68c79ffe3af1db88180454fbc2fa880a51ccf52" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>hostname:port<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>O valor não corresponde ao padrão: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>nomedehost:porta<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">470</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c90ad98a026d781ab729911873767e549d78f99" datatype="html">
+ <source>Engine Id</source>
+ <target>ID do Mecanismo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">478</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d39d015ebd667fb6bddf08bb0e5b3faa6cf044c" datatype="html">
+ <source>Unique identifier for the device (in hex).</source>
+ <target>Identificador Exclusivo do dispositivo (em hexadecimal).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">480</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514cda7dc49062c5c532427245ce47c4954bc32" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>O valor não corresponde ao padrão: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Deve ser hexadecimal, e o tamanho deve ser múltiplo de 2 com valor mínimo = 10 e valor máximo = 64.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b2d628c51192ade0044212b409c758c20f9c021" datatype="html">
+ <source>Auth Protocol</source>
+ <target>Protocolo Auth</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc8bb2315a5101770a752b18e03b5c730539397c" datatype="html">
+ <source>-- Select auth protocol --</source>
+ <target>-- Selecionar protocolo auth --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">508</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6777f99fd13e03874afe26ba7289dc9fc211af04" datatype="html">
+ <source>Privacy Protocol</source>
+ <target>Protocolo de Privacidade</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70512b7c13bce85b3928920b29fafbd59a853383" datatype="html">
+ <source>-- Select privacy protocol --</source>
+ <target>-- Selecionar protocolo de privacidade --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b48c81465d14465b95826b99e05acfabef1814c6" datatype="html">
+ <source>Credentials</source>
+ <target>Crendenciais</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">541</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4ea0163c25c818aab982072b1b8d5ab585e9a5a" datatype="html">
+ <source>SNMP Community</source>
+ <target>Comunidade SNMP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">547</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="08c74dc9762957593b91f6eb5d65efdfc975bf48" datatype="html">
+ <source>Username</source>
+ <target>Nome de usuário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="948758e1412bb2ecdb98e3a4f1cbb6d7458456f2" datatype="html">
+ <source>Encryption</source>
+ <target>Criptografia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">598</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e65610b5d940367f1ff6b57772b96e94e35fe202" datatype="html">
+ <source>SSL</source>
+ <target>SSL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">624</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e37e0d06148c7708e88b4a1eb412babbe1a4afc" datatype="html">
+ <source>Certificate</source>
+ <target>Certificado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">634</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="295ae4f632322098deca8a3ddfbc7aeaabb5423b" datatype="html">
+ <source>The SSL certificate in PEM format.</source>
+ <target>O certificado SSL no formato PEM.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">635</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464272c069fe56f6c50f41f426a25b2a42c95ba5" datatype="html">
+ <source>Invalid SSL certificate.</source>
+ <target>Certificado SSL inválido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">650</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0596d06bf1f8a15d4bfe56226971ecdd78013b1f" datatype="html">
+ <source>Private key</source>
+ <target>Chave privada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">659</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ded15dc55104994c0230189f34dff84a4955aafb" datatype="html">
+ <source>The SSL private key in PEM format.</source>
+ <target>A chave privada SSL no formato PEM.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">660</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19bdc1597d815b456793ff87c89af4257a85a103" datatype="html">
+ <source>Invalid SSL private key.</source>
+ <target>Chave privada SSL inválida.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">675</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3356018487523380058" datatype="html">
+ <source>service</source>
+ <target>serviço</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2412938991511187011" datatype="html">
+ <source>There are no hosts.</source>
+ <target>Não há hosts.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2594503755408511486" datatype="html">
+ <source>Filter hosts</source>
+ <target>Filtrar hosts</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5869780110608474933" datatype="html">
+ <source>Placement</source>
+ <target>Posicionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2956098160626271284" datatype="html">
+ <source>Running</source>
+ <target>Em Execução</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="013f48ee777d2e53e2bcba36e1a99fcbb7ef8cb6" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report configuration</source>
+ <target>Etapa <x id="INTERPOLATION" equiv-text="{{ step }}"/> de 2: Configuração do relatório de telemetria</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a09b723a928774bff707973c99999dcf3d84a349" datatype="html">
+ <source>The telemetry module sends anonymous data about this Ceph cluster back to the Ceph developers to help understand how Ceph is used and what problems users may be experiencing.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> This data is visualized on <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>public dashboards<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> that allow the community to quickly see summary statistics on how many clusters are reporting, their total capacity and OSD count, and version distribution trends.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> The data being reported does <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>not<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> contain any sensitive data like pool names, object names, object contents, hostnames, or device serial numbers. It contains counters and statistics on how the cluster has been deployed, the version of Ceph, the distribution of the hosts and other parameters which help the project to gain a better understanding of the way Ceph is used. The data is sent secured to <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> and <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (device report).</source>
+ <target>O módulo de telemetria envia dados anônimos sobre este cluster do Ceph aos desenvolvedores do Ceph para ajudar a entender como o Ceph é usado e quais problemas os usuários podem estar enfrentando.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Esses dados são visualizados em <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>painéis de controle públicos<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> que permitem que a comunidade veja rapidamente um resumo das estatísticas de quantos clusters estão gerando relatórios, a capacidade total e a contagem de OSD deles, e as tendências de distribuição.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Os dados relatados <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>não<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> incluem informações confidenciais, como nomes de pools, nomes de objetos, conteúdo de objetos, nomes de host ou números de série de dispositivos. Eles incluem contadores e estatísticas sobre como o cluster foi implantado, a versão do Ceph, a distribuição dos hosts e outros parâmetros que ajudam o projeto a ter uma compreensão melhor do modo como o Ceph é usado. Os dados são enviados de forma protegida para <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> e <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (relatório do dispositivo).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">14,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c95505b5a74151a0c235b19b9c41db7983205ba7" datatype="html">
+ <source>Deactivate</source>
+ <target>Desativar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19" datatype="html">
+ <source>Channels</source>
+ <target>Canais</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e25b17c0b4ef361b6a05aaec2bbd2b7e86680458" datatype="html">
+ <source>The telemetry report is broken down into several &quot;channels&quot;, each with a different type of information that can be configured below.</source>
+ <target>O relatório de telemetria é dividido em vários &quot;canais&quot;, cada um com um tipo diferente de informações, que podem ser configuradas abaixo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">32,33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380ab580741bec31346978e7cab8062d6970408d" datatype="html">
+ <source>Basic</source>
+ <target>Básico</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd898057f0add35258a5fb5c90d792c5e2147452" datatype="html">
+ <source>Includes basic information about the cluster:</source>
+ <target>Inclui informações básicas sobre o cluster:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da213e9ba8a86b453d04f794f58c9803f7b062b1" datatype="html">
+ <source>Capacity of the cluster</source>
+ <target>Capacidade do cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d5fe31d9e13239bdd223d0bbd289a1b1903e86" datatype="html">
+ <source>Number of monitors, managers, OSDs, MDSs, object gateways, or other daemons</source>
+ <target>Número de monitores, gerenciadores, OSDs, MDSs, gateways de objetos ou outros daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a3eb7834b4baf412f8863d14883972897d9acb7" datatype="html">
+ <source>Software version currently being used</source>
+ <target>Versão do software que está em uso no momento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34881ae65482ffa74ccb4043fb2622e48ed146d5" datatype="html">
+ <source>Number and types of RADOS pools and CephFS file systems</source>
+ <target>Número e tipos de pools RADOS e sistemas de arquivos CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="696f8f5ea7a9cf6125b9a3af160981fda363552d" datatype="html">
+ <source>Names of configuration options that have been changed from their default (but not their values)</source>
+ <target>Nomes das opções de configuração que foram alteradas do padrão (mas sem os valores)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34292940316300d09abe5e675d452fae199f626b" datatype="html">
+ <source>Crash</source>
+ <target>Falha</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7620e332b7dea1e832158e85847255eb4d9e6bbc" datatype="html">
+ <source>Includes information about daemon crashes:</source>
+ <target>Inclui informações sobre falhas nos daemons:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1aa4306a6e840fe35b70c9b07d38ce85f281cfa" datatype="html">
+ <source>Type of daemon</source>
+ <target>Tipo de daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4f2cbedb4b14b68bc9f390e3391445c1b6682da" datatype="html">
+ <source>Version of the daemon</source>
+ <target>Versão do daemon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d62603cdc75645ea873fc8f7f69c32b5f4a2aa9" datatype="html">
+ <source>Operating system (OS distribution, kernel version)</source>
+ <target>Sistema operacional (distribuição do OS, versão do kernel)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84facf84a73631d66e9a4e0bc1c40097b9d14742" datatype="html">
+ <source>Stack trace identifying where in the Ceph code the crash occurred</source>
+ <target>Rastreamento de pilha que identifica onde houve falha no código do Ceph</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea64d4177bd648e1a20c92669e6857762b811d8c" datatype="html">
+ <source>Device</source>
+ <target>Dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4bc37bcbbcea881a269b4063b3d93dec8ee67d5" datatype="html">
+ <source>Includes information about device metrics like anonymized SMART metrics.</source>
+ <target>Inclui informações sobre as métricas do dispositivo, como as métricas SMART anônimas.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37de70e8ba539187d0171a38dad2a63c323096eb" datatype="html">
+ <source>Ident</source>
+ <target>Identif.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b126025440f118cd02ce78362d61a5001c27617" datatype="html">
+ <source>Includes user-provided identifying information about the cluster:</source>
+ <target>Inclui informações de identificação sobre o cluster fornecidas pelo usuário.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62c6e9aecff7e04ef7d36fdee4ab4fb285a7a2b5" datatype="html">
+ <source>Contact Information</source>
+ <target>Informações de contato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61ba9a84051b3f470122e59cf5a746552b378269" datatype="html">
+ <source>Submitting any contact information is completely optional and disabled by default.</source>
+ <target>O envio de qualquer informação de contato é completamente opcional e, por padrão, está desabilitado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34746fb1c7f3d2194d99652bdff89e6e14c9c4f4" datatype="html">
+ <source>Contact</source>
+ <target>Contato</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="632cac1e025b77b2d77fed16ad22a410ddacab9e" datatype="html">
+ <source>My first Ceph cluster</source>
+ <target>Meu primeiro cluster do Ceph</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3a58c8a81b9ffda26a154eae25a422c9f7de37b" datatype="html">
+ <source>Organization</source>
+ <target>Organização</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e8fda44e2c5bb51860f26cd9c2730f9ae1db9869" datatype="html">
+ <source>Organization name</source>
+ <target>Nome da organização</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d49310535abb3792d8c9c991dd0d990d73d29af" datatype="html">
+ <source>Interval</source>
+ <target>Intervalo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91317562c9dfefbdd5973faf11d217f571d073c7" datatype="html">
+ <source>The module compiles and sends a new report every 24 hours by default. You can adjust this interval by setting a different number of hours.</source>
+ <target>Por padrão, o módulo compila e envia um novo relatório a cada 24 horas. Você pode ajustar esse intervalo definindo um número diferente de horas.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">185,186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a12cf4cf71ef3161a024382ab542cf0eba094504" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to 8.</source>
+ <target>O valor inserido é muito baixo. Ele deve ser maior do que ou igual a 8.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a92e437fac14b4010c4515b31c55a311d026a57f" datatype="html">
+ <source>Proxy</source>
+ <target>Proxy</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6de03357358c7eff62aca486508bb5c2046e0669" datatype="html">
+ <source>If the cluster cannot directly connect to the configured telemetry endpoint (default telemetry.ceph.com), you can configure a HTTP/HTTPS proxy server by e.g. adding https://10.0.0.1:8080</source>
+ <target>Se o cluster não puder conectar-se diretamente ao endpoint de telemetria configurado (telemetry.ceph.com padrão), você poderá configurar um servidor proxy HTTP/HTTPS ao adicionar https://10.0.0.1:8080, por exemplo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5687a733af051bfca97dbffba282e39fbb9b8c8f" datatype="html">
+ <source>You can also include a user:pass if needed e.g. https://ceph:telemetry@10.0.0.1:8080</source>
+ <target>É possível incluir usuário:senha, se necessário. Por exemplo, https://ceph:telemetry@10.0.0.1:8080</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e6430c68df43ea65e4145972b01186fba40f26a" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Note:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> By clicking 'Next' you will first see a preview of the report content before you can activate the automatic submission of your data.</source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Nota:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> Ao clicar em 'Avançar', primeiro aparece uma visualização do conteúdo do relatório antes que você possa ativar o envio automático dos seus dados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">219,220</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d8d878f8d60905e1306c225716305a331b784c8" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report preview</source>
+ <target>Etapa <x id="INTERPOLATION" equiv-text="{{ step }}"/> de 2: Visualização do relatório de telemetria</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e23d0064b6474f309c74e1c928cc0920f479d9a5" datatype="html">
+ <source>Report ID <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <target>ID do Relatório <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">249,252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4060e92658964e356a0992a900c8aa811c2cfec0" datatype="html">
+ <source>A randomized UUID to identify a particular cluster over the course of several telemetry reports.</source>
+ <target>Um UUID aleatório para identificar determinado cluster durante o andamento de vários relatórios de telemetria.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60900bc663571f852a04950a123508b106d97204" datatype="html">
+ <source>Report preview <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <target>Visualização do relatório <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">267,270</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3de417f739c336284c42904552e81e8d852daecc" datatype="html">
+ <source>The actual telemetry data that will be submitted.</source>
+ <target>Os dados reais de telemetria que serão enviados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="933a2b6f087670ff42c95876e6ecfb2faa3e3867" datatype="html">
+ <source>I agree to my telemetry data being submitted under the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Community Data License Agreement - Sharing - Version 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></source>
+ <target>Concordo com o envio dos meus dados de telemetria conforme previsto no <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Contrato de Licença de Dados da Comunidade - Compartilhamento - Versão 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">304</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8293060085588842566" datatype="html">
+ <source>The Telemetry module has been configured and activated successfully.</source>
+ <target>O módulo Telemetria foi configurado e ativado com êxito.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5380636888677486786" datatype="html">
+ <source>An Error occurred while updating the Telemetry module configuration. Please Try again</source>
+ <target>Erro ao atualizar a configuração do módulo Telemetria. Tente novamente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2bcd3296d2850de762fb943060b7e086a893181" datatype="html">
+ <source>Health</source>
+ <target>Saúde</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61e0f26d843eec0b33ff475e111b0c2f7a80b835" datatype="html">
+ <source>Statistics</source>
+ <target>Estatísticas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73caac4265ea7314ff061e5a1d78a6361a6dd3b8" datatype="html">
+ <source>Cluster Status</source>
+ <target>Status do Cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="624f596cc3320f5e0a0d7c7346c364e5af9bdd8c" datatype="html">
+ <source>Monitors</source>
+ <target>Monitores</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9183778f2c6473d7ccb080f651caa01faaf70c" datatype="html">
+ <source>OSDs</source>
+ <target>OSDs</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c34287a0423968dac8a41463b80855a0ff789403" datatype="html">
+ <source>Managers</source>
+ <target>Gerenciadores</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="946ac5dea9921dc09d7b0a63b89535371f283b19" datatype="html">
+ <source>Object Gateways</source>
+ <target>Gateways de Objetos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff03fa5bcf37c4da46ad736c1f7d03f959e8ba9a" datatype="html">
+ <source>Metadata Servers</source>
+ <target>Servidores de Metadados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d817609ba4993eba859409ab71e566168f4d5f5a" datatype="html">
+ <source>iSCSI Gateways</source>
+ <target>Gateways iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ce9dfdc6dccb28dc75a78c704e09dc18fb02dcfa" datatype="html">
+ <source>Capacity</source>
+ <target>Capacidade</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f383269db2d32cccee9e936fe549dccb9fdbf4" datatype="html">
+ <source>Raw Capacity</source>
+ <target>Capacidade Bruta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498a109c6e9e94f1966de01aa0326f7f0ac6fb52" datatype="html">
+ <source>PG Status</source>
+ <target>Status do PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5f8a813f91a11af99132e4beafc136cfc13d73b" datatype="html">
+ <source>PGs per OSD</source>
+ <target>PGs por OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32efd1c3f70e3c5244239de97a2cc95d98534a14" datatype="html">
+ <source>Client Read/Write</source>
+ <target>Leitura/Gravação do Cliente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="52213660b2454d139ada3079a42ec6caf3c3c01e" datatype="html">
+ <source>Client Throughput</source>
+ <target>Throughput do Cliente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="275485415092cbae3a9f3cbb786ebe283cacfdd5" datatype="html">
+ <source>Recovery Throughput</source>
+ <target>Throughput de Recuperação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35416fcdf9cb33d2b299d3f2028c390454b55d02" datatype="html">
+ <source>Scrubbing</source>
+ <target>Removendo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="44ecac93d67c6a671198091c2270354f80322327" datatype="html">
+ <source><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> See <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>Logs<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for more details.</source>
+ <target><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> Consulte os <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>Registros<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> para obter mais detalhes.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520247697658334435" datatype="html">
+ <source>Reads</source>
+ <target>Leituras</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5947645586591788199" datatype="html">
+ <source>/s</source>
+ <target>/s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7527163811128350993" datatype="html">
+ <source>Writes</source>
+ <target>Gravações</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7684088941299429132" datatype="html">
+ <source>IOPS</source>
+ <target>IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81585474102700882" datatype="html">
+ <source>Used</source>
+ <target>Usado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">179</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8695656831075719969" datatype="html">
+ <source>Avail.</source>
+ <target>Disp.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6352596107300820129" datatype="html">
+ <source>Clean</source>
+ <target>Limpar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4016774570903735270" datatype="html">
+ <source>Working</source>
+ <target>Em funcionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4467323362722952678" datatype="html">
+ <source>Unknown</source>
+ <target>Desconhecido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">218</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7790772795962334429" datatype="html">
+ <source>Healthy</source>
+ <target>Saudável</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4708847204147472247" datatype="html">
+ <source>Misplaced</source>
+ <target>Mal posicionado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3120522496446378904" datatype="html">
+ <source>Degraded</source>
+ <target>Degradado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8047698491745405137" datatype="html">
+ <source>Unfound</source>
+ <target>Não encontrado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81117556780777231" datatype="html">
+ <source>objects</source>
+ <target>objetos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795e8a00db46b750113d5db93e8d97e2b3079894" datatype="html">
+ <source>For an overview of <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/> widgets click <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></source>
+ <target>Para uma visão geral dos widgets de <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/>, clique <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">21,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16bd21c1b48036d54c6a595f5cff2540cfba7f60" datatype="html">
+ <source>here</source>
+ <target>aqui</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8515973702474791807" datatype="html">
+ <source>up</source>
+ <target>ativo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4223604072115719661" datatype="html">
+ <source>no filesystems</source>
+ <target>sem sistemas de arquivos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2078241808113697591" datatype="html">
+ <source>active</source>
+ <target>ativo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3232506912392089107" datatype="html">
+ <source>standby</source>
+ <target>standby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576716133013765863" datatype="html">
+ <source>standby daemons</source>
+ <target>daemons de standby</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3629620351427988554" datatype="html">
+ <source>active daemon</source>
+ <target>daemon ativo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5954854563228355745" datatype="html">
+ <source>standbyReplay</source>
+ <target>standbyReplay</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7329683463736701292" datatype="html">
+ <source>n/a</source>
+ <target>n/a</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/not-available.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8271970016544066882" datatype="html">
+ <source><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (quorum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</source>
+ <target><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (quorum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mon-summary.pipe.ts</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6489441800790477240" datatype="html">
+ <source>total</source>
+ <target>total</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5965118847182332588" datatype="html">
+ <source>near full</source>
+ <target>quase cheio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="268166731974484199" datatype="html">
+ <source>full</source>
+ <target>completo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47116253e36f4e38a97ba41b2d3122c6c15ab904" datatype="html">
+ <source>Clients (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</source>
+ <target>Clientes (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5159814115056353668" datatype="html">
+ <source>Addresses</source>
+ <target>Endereços</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1811797298582428088" datatype="html">
+ <source>Access Type</source>
+ <target>Tipo de Acesso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3575940435199094878" datatype="html">
+ <source>Squash</source>
+ <target>Executar Squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2944102521023817891" datatype="html">
+ <source>Cluster</source>
+ <target>Cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91772203889648189" datatype="html">
+ <source>NFS Protocol</source>
+ <target>Protocolo NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907766170797643122" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1032539711043211945" datatype="html">
+ <source>Transport</source>
+ <target>Transporte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2489852208080013495" datatype="html">
+ <source>Storage Backend</source>
+ <target>Backend de Armazenamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8440421106569981118" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4095248496892792741" datatype="html">
+ <source>CephFS User</source>
+ <target>Usuário do CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2535727951299201687" datatype="html">
+ <source>CephFS Filesystem</source>
+ <target>Sistema de Arquivos do CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2169401160512036026" datatype="html">
+ <source>Security Label</source>
+ <target>Rótulo de Segurança</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3671149880069127721" datatype="html">
+ <source>Object Gateway</source>
+ <target>Gateway de Objetos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1643028261508790" datatype="html">
+ <source>Object Gateway User</source>
+ <target>Usuário do Gateway de Objetos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2dae0bda66f6a349444951c0379c28cda47d6d1" datatype="html">
+ <source>Any client can access</source>
+ <target>Qualquer cliente pode acessar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7882f2edb1d4139800b276b6b0bbf5ae0b2234ef" datatype="html">
+ <source>Addresses</source>
+ <target>Endereços</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f3f74c0f6925826cb2188576391c0da01a23f0" datatype="html">
+ <source>Must contain one or more comma-separated values</source>
+ <target>Deve conter um ou mais valores separados por vírgula</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb5b2073697f3f4378c44a49b7524934c9268f4" datatype="html">
+ <source>For example:</source>
+ <target>Por exemplo:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f969c655b3fbe4fba7e277caf4cd2c459f9fca5" datatype="html">
+ <source>Access Type</source>
+ <target>Tipo de Acesso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28952831a284cfe2b4fc39ca610e80b52598905a" datatype="html">
+ <source>Squash</source>
+ <target>Executar Squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0660ae339068979854ade34a96546980723dede3" datatype="html">
+ <source>Add clients</source>
+ <target>Adicionar clientes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8571141481686087364" datatype="html">
+ <source>(inherited from global config)</source>
+ <target>(herdado da configuração global)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3563954518111128118" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- Selecionar tipo de acesso --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3802199399355755843" datatype="html">
+ <source>inherited from global config</source>
+ <target>herdado da configuração global</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8729531250118136719" datatype="html">
+ <source>-- Select what kind of user id squashing is performed --</source>
+ <target>-- Selecionar que tipo de squash de ID de usuário será executado --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4d1dd59b039ad818d9da7e29a773e10e41d9821" datatype="html">
+ <source>Cluster</source>
+ <target>Cluster</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="625f8f0f3e5b7c92651606d77484ff3d07b3c12b" datatype="html">
+ <source>This is the ID of an NFS Service.</source>
+ <target>Este é o ID de um Serviço NFS.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="135b91a2d908d5814b782695470a6a786c99d9d2" datatype="html">
+ <source>-- No cluster available --</source>
+ <target>-- Não há clusters disponíveis --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c501dba379f566885919240ea277b5bc10c14d18" datatype="html">
+ <source>-- Select the cluster --</source>
+ <target>-- Selecionar cluster --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7bd3ad665c398c7fe97230ab59e67370653a82" datatype="html">
+ <source>This field is required. To create a new NFS cluster, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>add a new NFS Service<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <target>Este campo é obrigatório. Para criar um cluster NFS, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>adicione um novo Serviço NFS<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">41,43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3f6ba7fe84d6508705cdfe234f0fcc8ff85c9cf" datatype="html">
+ <source>Storage Backend</source>
+ <target>Backend de Armazenamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6fee356d1db954255a56d8169405a89595246b9" datatype="html">
+ <source>-- Select the storage backend --</source>
+ <target>-- Selecionar backend de armazenamento --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3c2793dd2ef56954f872142d5ec1becb84c0fe1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="796e42bec8a6996607cf1f3e80235b86d695804a" datatype="html">
+ <source>Volume</source>
+ <target>Volume</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee3ba0ab5f0ccd597b3e44021c71e9aaad14df0a" datatype="html">
+ <source>-- No CephFS filesystem available --</source>
+ <target>-- Sem sistema de arquivos CephFS disponível --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="764c57812558b1ae66c5eec95d7efd2b1bf761e3" datatype="html">
+ <source>-- Select the CephFS filesystem --</source>
+ <target>-- Selecionar sistema de arquivos CephFS --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="957512d0321f73e9f115bce1bd823fa635170c41" datatype="html">
+ <source>Security Label</source>
+ <target>Rótulo de Segurança</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="65ce0fa4da1ed55e658aeb31d1644a29f06bb342" datatype="html">
+ <source>Enable security label</source>
+ <target>Habilitar rótulo de segurança</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e808f804130c7b6ff719509cbc06ebb27393a48" datatype="html">
+ <source>CephFS Path</source>
+ <target>Caminho do CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1338c2f83e49ea7f2fc04e9fe90c5d330b7a10f" datatype="html">
+ <source>A path in a CephFS file system.</source>
+ <target>Um caminho em um sistema de arquivos CephFS.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ecc0107badb6625466aaa3f975b5c05276f432f" datatype="html">
+ <source>Path need to start with a '/' and can be followed by a word</source>
+ <target>O caminho precisa começar com '/' e pode ser seguido de uma palavra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f9d8bd873c34c5ab2d4d0cf995fe5183ab25f6e" datatype="html">
+ <source>The path does not exist in the selected volume.</source>
+ <target>O caminho não existe no volume selecionado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd197d7773cef10f368f08c53b47979c3df1f22d" datatype="html">
+ <source>Bucket</source>
+ <target>Compartimento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ca90b4b16347ef7017967915e8624472976c85c" datatype="html">
+ <source>The bucket does not exist or is not in the default realm (if multiple realms are configured). To continue, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>create a new bucket<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <target>O compartimento não existe ou não está no domínio padrão (em caso de vários domínios configurados). Para continuar, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>crie um novo compartimento<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bee6900143996c0e908a10564532eba3da0b30fb" datatype="html">
+ <source>NFS Protocol</source>
+ <target>Protocolo NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5043c0921e709935ab026bb3253ffe1f159fca1" datatype="html">
+ <source>NFSv4</source>
+ <target>NFSv4</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d2c39708a32910f89701dd7e1cfb9ec1c195768" datatype="html">
+ <source>Pseudo</source>
+ <target>Pseudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1f8be2ae25947bec0b84c2338201580ea053f34e" datatype="html">
+ <source>The position that this <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> export occupies in the <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo FS<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (it must be unique).</source>
+ <target>A posição que esta exportação do <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> ocupa no <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo FS<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (deve ser exclusiva).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">241,242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3af55f7fd5b1d9e5a53e030c80116dc635bfb9f" datatype="html">
+ <source>By using different Pseudo options, the same Path may be exported multiple times.</source>
+ <target>Ao usar opções diferentes de Pseudo, o mesmo Caminho pode ser exportado várias vezes.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5eb719aa900fed3f9d4a1d74bcc158f07f67f684" datatype="html">
+ <source>The pseudo is already in use by another export.</source>
+ <target>O pseudo já está em uso por outra exportação.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddf98fcdeeb17643db020d54f42b5e56b5f9a52a" datatype="html">
+ <source>Pseudo needs to start with a '/' and can't contain any of the following: &gt;, &lt;, |, &amp;, ( or ).</source>
+ <target>O Pseudo precisa começar com '/' e não pode conter nenhum destes caracteres: &gt;, &lt;, |, &amp;, ( ou ).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="27eb35c4b4ac08781a7253a2ab40f8f7d957ba51" datatype="html">
+ <source>-- No access type available --</source>
+ <target>-- Não há tipos de acesso disponíveis --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">280</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="509ce016c9110a54028dafd741f15ceacbe74b5a" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- Selecionar tipo de acesso --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67ce207d0b7eada1fe3d3187a39ba0c07be76b6c" datatype="html">
+ <source>The Object Gateway NFS backend has a number of limitations which will seriously affect applications writing to the share. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> for details before enabling write access.</source>
+ <target>O backend do NFS do Gateway de Objetos tem várias limitações que afetarão gravemente os aplicativos gravados no compartilhamento. Consulte <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> para obter detalhes antes de habilitar o acesso de gravação.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">293,296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4deda03573eaaff77e63f6a238a1f0ca7816950a" datatype="html">
+ <source>-- No squash available --</source>
+ <target>-- Não há squashes disponíveis --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">321</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a0e82a4da88e7fdf270444f838d45849676e9d4b" datatype="html">
+ <source>--Select what kind of user id squashing is performed --</source>
+ <target>--Selecionar que tipo de squash de ID de usuário será executado --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d01b7c3f7f06712c53d054cfbe4f53d446b038e8" datatype="html">
+ <source>Transport Protocol</source>
+ <target>Protocolo de Transporte</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2a6ad6e8bc315f07911722c05767ac79c136d99" datatype="html">
+ <source>UDP</source>
+ <target>UDP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">349</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c030f11e0aae9b24d2c048c57f29f590be621df" datatype="html">
+ <source>TCP</source>
+ <target>TCP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">359</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f84d7fd4d52eb5b2229b632ef5119dac63d5597" datatype="html">
+ <source>No user id squashing is performed.</source>
+ <target>Nenhum squash de ID de usuário foi executado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">378</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb1d148107e36852325106a518385b1b0de28835" datatype="html">
+ <source>uid 0 and gid 0 are squashed to the Anonymous_Uid and Anonymous_Gid gid 0 in alt_groups lists is also squashed.</source>
+ <target>É executado o squash de uid 0 e gid 0 para Anonymous_Uid e Anonymous_Gid, e é executado o squash também de gid 0 nas listas alt_groups.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">382</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1309d6f67955799863337b201413faa61a175ddb" datatype="html">
+ <source>uid 0 and gid of any value are squashed to the Anonymous_Uid and Anonymous_Gid alt_groups lists is discarded.</source>
+ <target>É executado o squash de uid 0 e gid de qualquer valor para Anonymous_Uid e Anonymous_Gid, as listas alt_groups são descartadas.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85f23d5c9b57dc78dda4150d13aa3b99e985350b" datatype="html">
+ <source>All users are squashed.</source>
+ <target>É executado o squash de todos os usuários.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2691935247101074756" datatype="html">
+ <source>NFS export</source>
+ <target>Exportação do NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8727258243239498387" datatype="html">
+ <source><x id="PH" equiv-text="fsalItem.descr"/> backend is not available. <x id="PH_1" equiv-text="errorMessage"/></source>
+ <target>Backend <x id="PH" equiv-text="fsalItem.descr"/> não está disponível. <x id="PH_1" equiv-text="errorMessage"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2772848515253260635" datatype="html">
+ <source>Error while retrieving paths.</source>
+ <target>Erro ao recuperar caminhos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5239928491238988595" datatype="html">
+ <source>Error while retrieving bucket names.</source>
+ <target>Erro ao recuperar nomes de compartimentos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="734c9905951a774870497c5aaae8e3ee833b6196" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2190548d236ca5f7bc7ab2bca334b860c5ff2ad4" datatype="html">
+ <source>Object Gateway</source>
+ <target>Gateway de Objetos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca53d681a9892d6fdbb57ee9676582186515e961" datatype="html">
+ <source>Performance counters not available</source>
+ <target>Contadores de desempenho não disponíveis</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="490e15ecc922965b6d8194754c87c5583aa071f3" datatype="html">
+ <source>The name can only consist of alphanumeric characters, dashes and underscores.</source>
+ <target>O nome pode conter apenas caracteres alfanuméricos, traços e sublinhados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9edc2b494e660618af3e5225f68d40b7ca67629c" datatype="html">
+ <source>The chosen erasure code profile name is already in use.</source>
+ <target>O nome do perfil de código de eliminação escolhido já está em uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35a4206db3105ed03e0dd799e1642b75b78123e8" datatype="html">
+ <source>Root</source>
+ <target>Raiz</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf425784c7073c7e7f7c1bb90c2c19db7e751db2" datatype="html">
+ <source>Failure domain type</source>
+ <target>Tipo de domínio de falha</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72396a9565cf644d1fe1b21b790c4243ee270986" datatype="html">
+ <source>Device class</source>
+ <target>Classe do dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d80e0c07bfea1b693a33ef2245007de92a6780" datatype="html">
+ <source>Let Ceph decide</source>
+ <target>Permitir que o Ceph decida</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101611937243846632" datatype="html">
+ <source>Crush Rule</source>
+ <target>Regra de Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef9ff0e6227947b48dfab4ac39ade04af758913b" datatype="html">
+ <source>Plugin</source>
+ <target>Plug-in</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd69b31bce8f630eac1d4762b0bbcf72ce19d193" datatype="html">
+ <source>Data chunks (k)</source>
+ <target>Pacotes de dados (k)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0d26a6172d32cb81218fe2103c54a818cbc1189" datatype="html">
+ <source>Must be equal to or greater than 2.</source>
+ <target>Deve ser igual ou maior do que 2.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ba6f4800642eba4e8b056aa7167554c3afa8db0" datatype="html">
+ <source>Chunks (k+m) have exceeded the available OSDs of <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>.</source>
+ <target>Os pacotes (k+m) excederam os OSDs disponíveis de <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="86fca2f788ce986eef835cd7ef8dfc9ae22447a4" datatype="html">
+ <source>For an equal distribution k has to be a multiple of (k+m)/l.</source>
+ <target>Para uma distribuição igual, k deve ser múltiplo de (k+m)/l.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8dd4bc172f1adc4afadaec291e465b082909148d" datatype="html">
+ <source>K has to be equal to or greater than m in order to recover data correctly through c.</source>
+ <target>K deve ser igual a ou maior do que m para recuperar os dados corretamente por c.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2e5b0e6d0dba31c59f946392699a0a6c4dd9b83" datatype="html">
+ <source>Distribution factor: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></source>
+ <target>Fator de distribuição: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dab3a299ead121169b8e08ed618c3b6a2f66691b" datatype="html">
+ <source>Coding chunks (m)</source>
+ <target>Pacotes de codificação (m)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e2773e5bd4948193f18f2361d663ecc3988c656" datatype="html">
+ <source>Must be equal to or greater than 1.</source>
+ <target>Deve ser igual ou maior do que 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">146</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cde4c945a49a260c0a47bcc7cd956846930a5f7" datatype="html">
+ <source>Durability estimator (c)</source>
+ <target>Estimador de durabilidade (c)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ec9ff9931f8ea1201792d6a01bf9a47b283d692" datatype="html">
+ <source>C has to be equal to or lower than m as m defines the amount of chunks that can be used.</source>
+ <target>C deve ser igual a ou menor do que m, já que m define a quantidade de pacotes que pode ser usada.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35594fe66657ea07b5b5f560927f78e81a229996" datatype="html">
+ <source>Helper chunks (d)</source>
+ <target>Pacotes do ajudante (d)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0c250a8d281291273ed3504ade19ca6537e4d9a" datatype="html">
+ <source>Set d manually or use the plugin's default calculation that maximizes d.</source>
+ <target>Defina d manualmente ou use o cálculo padrão do plug-in que maximiza d.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4304a5cd95742db0f81c3bdf29aa96bf3b0ca13d" datatype="html">
+ <source>D is automatically updated on k and m changes</source>
+ <target>D é automaticamente atualizado com base nas alterações de k e m</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06a67d52427b12df2b3d439be0e1342ac72aeb5c" datatype="html">
+ <source>D can be set from <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> to <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></source>
+ <target>D pode ser definido de <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> para <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4f8831d3bd6401e87710c4e3ee844f5efbf5de3" datatype="html">
+ <source>D can only be set to <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></source>
+ <target>D só pode ser definido como <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5d7aacffce2c6032c3ae9ef4d1b3847a926440b" datatype="html">
+ <source>D has to be greater than k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>).</source>
+ <target>D deve ser maior do que k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fd745d614884edc23c7ac9ad8aba9655f3793ac2" datatype="html">
+ <source>D has to be lower than k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>).</source>
+ <target>D deve ser menor do que k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>).</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">199</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af668c2a095a979ea2b4e43cd82c2120ab56c21c" datatype="html">
+ <source>Locality (l)</source>
+ <target>Localidade (l)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="200fea08b63ae8d60cdbf33ffd2636159e87dc1e" datatype="html">
+ <source>Can't split up chunks (k+m) correctly with the current locality.</source>
+ <target>Impossível dividir os pacotes (k+m) corretamente com a localidade atual.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319ac5d692d11da686782159bd70e0b705c228ed" datatype="html">
+ <source>Locality groups: <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></source>
+ <target>Grupos de localidades: <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">230</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d455a110bf6d2235e314e295ce1dfeee93d3dff2" datatype="html">
+ <source>Crush failure domain</source>
+ <target>Domínio de falha do Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74a495f041f7dd102eee5c0bbc9e03083b538ae" datatype="html">
+ <source>Crush Locality</source>
+ <target>Localidade do Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2f14a73f7a6e94479f67423cc51102da8d6f524" datatype="html">
+ <source>None</source>
+ <target>Nenhum</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="363a99d62822b92913a4cce196d47f32c1258e2f" datatype="html">
+ <source>Scalar mds</source>
+ <target>Mds escalar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2981733b912b693a9dd9d915d6d34f4692cc874a" datatype="html">
+ <source>Technique</source>
+ <target>Técnica</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0098b6e47b04ec817361f384ce81d454ba5c0bb" datatype="html">
+ <source>Packetsize</source>
+ <target>Tamanho do pacote</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0252cd81ca54d0a2f69ec9ccf4248e73df5aa4a" datatype="html">
+ <source>Crush root</source>
+ <target>Raiz do Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">351</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1548d5c76f0406ddd1ba3c557e1e6db22e95b340" datatype="html">
+ <source>Crush device class</source>
+ <target>Classe do dispositivo do Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3f657ffa19dc6ac504b83c86209709522dcf065" datatype="html">
+ <source>Available OSDs: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></source>
+ <target>OSDs disponíveis: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03d84645f6e019c5a43909bbf2ea1696ee88332c" datatype="html">
+ <source>Directory</source>
+ <target>Diretório</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1354845268685595937" datatype="html">
+ <source>EC Profile</source>
+ <target>Perfil EC</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3938a411d76796f8ae73b72ea4c77661207453bd" datatype="html">
+ <source>Cache Tiers Details</source>
+ <target>Detalhes das Camadas do Cache</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="991790413700941336" datatype="html">
+ <source>Cache Mode</source>
+ <target>Modo de Cache</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9133265273798382582" datatype="html">
+ <source>Min Evict Age</source>
+ <target>Tempo Mín. Expulsão</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7172092927403263656" datatype="html">
+ <source>Min Flush Age</source>
+ <target>Tempo Mín. Descarregamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8096695869347792608" datatype="html">
+ <source>Target Max Bytes</source>
+ <target>Máx. de Bytes de Destino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8854126142886240282" datatype="html">
+ <source>Target Max Objects</source>
+ <target>Máx. de Objetos de Destino</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617215542453015899" datatype="html">
+ <source>No applications added</source>
+ <target>Nenhum aplicativo adicionado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4895689494338215646" datatype="html">
+ <source>Applications limit reached</source>
+ <target>Limite de aplicativos atingido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7322343326526084293" datatype="html">
+ <source>A pool can only have up to four applications definitions.</source>
+ <target>Um pool apenas pode ter até quatro definições de aplicativos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1393735257943344790" datatype="html">
+ <source>Allowed characters '_a-zA-Z0-9'</source>
+ <target>Caracteres permitidos: '_a-zA-Z0-9'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5520683885127790121" datatype="html">
+ <source>Maximum length is 128 characters</source>
+ <target>Tamanho máximo de 128 caracteres</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587418377972855060" datatype="html">
+ <source>Filter or add applications'</source>
+ <target>Filtrar ou adicionar aplicativos'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5188881899285829380" datatype="html">
+ <source>Add application</source>
+ <target>Adicionar aplicativo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16e113230b6b0d3165e076300880542bac7c8138" datatype="html">
+ <source>The chosen Ceph pool name is already in use.</source>
+ <target>O nome do pool do Ceph escolhido já está em uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c75b132bef7b29fa5171768303c4b96e34ccaf68" datatype="html">
+ <source>It's not possible to create an RBD pool with '/' in the name. Please change the name or remove 'rbd' from the applications list.</source>
+ <target>Não é possível criar um pool de RBD com '/' no nome. Altere o nome ou remova o 'rbd' da lista de aplicativos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">34,35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="171dc6d5c6bc4615d99778b0088cae80fd00bd10" datatype="html">
+ <source>Pool name can only contain letters, numbers, '.', '-', '_' or '/'.</source>
+ <target>O nome do pool pode conter apenas letras, números, '.', '-', '_' ou '/'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b85c657469e5ec8231c3de99b22f437bc01ffde5" datatype="html">
+ <source>Pool type</source>
+ <target>Tipo de pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="526c5443254c3b126eedb264840ffe827727bfd3" datatype="html">
+ <source>-- Select a pool type --</source>
+ <target>-- Selecionar tipo de pool --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abfbe47b630929d93c7343dc154599c2e59330a" datatype="html">
+ <source>PG Autoscale</source>
+ <target>Dimensionamento Automático de PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0aa21053410a94aa61d16985a4e95fd65523430d" datatype="html">
+ <source>Placement groups</source>
+ <target>Grupos de posicionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6301f1391d726f8f450bb358058534db19541ca9" datatype="html">
+ <source>At least one placement group is needed!</source>
+ <target>Pelo menos um grupo de posicionamento é necessário!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba9469a1ce6ed36e039c1f67247c8c81a5c71449" datatype="html">
+ <source>Your cluster can't handle this many PGs. Please recalculate the PG amount needed.</source>
+ <target>Seu cluster não pode processar tantos PGs. Recalcule a quantidade de PG necessária.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80ac68cd883369dac20688bc32b4cb33291b5e50" datatype="html">
+ <source>Calculation help</source>
+ <target>Ajuda no cálculo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fccbd60493df26705d957ed6c02a3c447894678f" datatype="html">
+ <source>The current PGs settings were calculated for you, you should make sure the values suit your needs before submit.</source>
+ <target>As configurações dos PGs atuais foram calculadas para você. Verifique se os valores estão de acordo com as suas necessidades antes de enviar.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">116,117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a43b2695131b48b76cebba676aba98a2bee17515" datatype="html">
+ <source>Replicated size</source>
+ <target>Tamanho replicado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bff144a4c4dc63b0e18fff2617d61a7ebdf2b6c" datatype="html">
+ <source>Minimum: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></source>
+ <target>Mínimo: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9c54b41f6d58a74e5d0aa3429ed0c87a482551" datatype="html">
+ <source>Maximum: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></source>
+ <target>Máximo: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="452cf71ec44ee77428656936a6627eaf2dd3b47f" datatype="html">
+ <source>The size specified is out of range. A value from <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> to <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/> is usable.</source>
+ <target>O tamanho especificado está fora da faixa. É possível usar um valor de <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> a <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">144,145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dda6196ffab88c1825f44a565c7b34e246e7e12f" datatype="html">
+ <source>A size of 1 will not create a replication of the object. The 'Replicated size' includes the object itself.</source>
+ <target>Um tamanho de 1 não criará uma replicação do objeto. O 'Tamanho replicado' inclui o próprio objeto.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">148,149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c870fb00256b8a5b9cb9cd1a124e6390b9bc639" datatype="html">
+ <source>EC Overwrites</source>
+ <target>Sobregravações de EC</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f1abafaeb40ce52355ddcc24686e3cd17b64e08a" datatype="html">
+ <source>Applications</source>
+ <target>Aplicativos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9308b82fc183f710df60909f49cfc73aa5e076" datatype="html">
+ <source>CRUSH</source>
+ <target>CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9de7dde00e2139cc4bd03b1837afbe72ad15a1ff" datatype="html">
+ <source>Erasure code profile</source>
+ <target>Perfil do código de eliminação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39b4620e6bd444e0a57a0a5c03fa8c96d7fe5235" datatype="html">
+ <source>-- No erasure code profile available --</source>
+ <target>-- Não há perfis de código de eliminação disponíveis --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498561757390d5528b263ce450d5f38efb00266d" datatype="html">
+ <source>-- Select an erasure code profile --</source>
+ <target>-- Selecionar perfil do código de eliminação --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="616a2532fbaace94934f5943e381b63e2623f004" datatype="html">
+ <source>This profile can't be deleted as it is in use.</source>
+ <target>Não é possível excluir este perfil porque ele está em uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="994363f08f9fbfa3b3994ff7b35c6904fdff18d8" datatype="html">
+ <source>Profile</source>
+ <target>Perfil</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="023d6f718770d2ea4ab8cabe26b0ec27ef967ec2" datatype="html">
+ <source>Used by pools</source>
+ <target>Usado por pools</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">387</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1061ba5ee07a5c6af09e09330dbc29201baf2aa" datatype="html">
+ <source>Profile is not in use.</source>
+ <target>Perfil não está em uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33150f22ce5348aa6c499bd092c3f4f3695d62cc" datatype="html">
+ <source>Crush ruleset</source>
+ <target>Conjunto de regras do Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">293</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">303</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c69b0bcd4698aa845d32c4c4ad488492552cb469" datatype="html">
+ <source>A new crush ruleset will be implicitly created.</source>
+ <target>Um novo conjunto de regras de crush será criado implicitamente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="896e9987db5e9bb279e6deed5d2dff28c242ef66" datatype="html">
+ <source>There are no rules.</source>
+ <target>Não há regras.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73a6b31116b3cc322af951daa0bafdc169e6c42e" datatype="html">
+ <source>-- Select a crush rule --</source>
+ <target>-- Selecionar regra de crush --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7d4894e770f8853050b1f6dd55bdd77a51a8ac6" datatype="html">
+ <source>Placement and
+ replication strategies or distribution policies that allow to
+ specify how CRUSH places data replicas.</source>
+ <target>Estratégias de
+ posicionamento e replicação ou políticas de distribuição que permitem
+ especificar como o CRUSH posiciona as réplicas de dados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">328,330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea91d648f92002bc9f96d9b26b735c83ca0b53c6" datatype="html">
+ <source>This rule can't be deleted as it is in use.</source>
+ <target>Não é possível excluir esta regra porque ela está em uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">346</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92da80699921e89fb19372e25b8d0f3b9fa427fc" datatype="html">
+ <source>Crush rule</source>
+ <target>Regra de Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">365</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5489e9f96835f469f6f728a00d8efa88ea5bc940" datatype="html">
+ <source>Crush steps</source>
+ <target>Etapas do Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc5f5496a9e50fe69e1a09784f28d94944108294" datatype="html">
+ <source>Rule is not in use.</source>
+ <target>Regra não está em uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="104a0e6900d1d1b0c8cf9e5947e36edb352583fc" datatype="html">
+ <source>The rule can't be used in the current cluster as it has too few OSDs to meet the minimum required OSD by this rule.</source>
+ <target>A regra não pode ser usada no cluster atual porque ele tem menos OSDs do que o mínimo exigido por essa regra.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">409,410</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2208d63d5940ce656006a220102b1eb2b5e553da" datatype="html">
+ <source>Compression</source>
+ <target>Compactação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">420</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c6f25c47da62ec597c6057a36ddfc3209811ec5" datatype="html">
+ <source>Algorithm</source>
+ <target>Algoritmo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">444</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4903231d42089325a28892c0fde1aed46b733ae6" datatype="html">
+ <source>-- No erasure compression algorithm available --</source>
+ <target>-- Não há algoritmos de compactação de eliminação disponíveis --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d68ddb254275f8f44221e9ad6d8ceeb59ca46a6" datatype="html">
+ <source>Minimum blob size</source>
+ <target>Tamanho mínimo do blob</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">468</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb2f176df80647137cbb02bbeb29e5dec707a400" datatype="html">
+ <source>e.g., 128KiB</source>
+ <target>ex. 128 KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">477</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b7f6e53a4521c6eb3ced4c007fdd4cf80bb7707" datatype="html">
+ <source>Value should be greater than 0</source>
+ <target>O valor deve ser maior do que 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">482</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">506</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8db98ab14b4e207ec763dfdefbc2dae367aab1cc" datatype="html">
+ <source>Value should be less than the maximum blob size</source>
+ <target>O valor deve ser menor do que o tamanho máximo do blob</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151efb127a9a4dd25259a0b2055442318a141f5b" datatype="html">
+ <source>Maximum blob size</source>
+ <target>Tamanho máximo do blob</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c656f0e346bbadf46eb1a5d20d0307a3bd20ba8" datatype="html">
+ <source>e.g., 512KiB</source>
+ <target>ex. 512 KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65a24eee8a026f3b1113fe9e157e9a0dd69486" datatype="html">
+ <source>Value should be greater than the minimum blob size</source>
+ <target>O valor deve ser maior do que o tamanho mínimo do blob</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">509</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="261ba09c4a59de83f48f52a23fd328da37e61ff4" datatype="html">
+ <source>Ratio</source>
+ <target>Taxa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">517</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1430457a9c3c66366e51d76bf10396014c576be" datatype="html">
+ <source>Compression ratio</source>
+ <target>Taxa de compactação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">528</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae5ce6de352cde949998fb10754459c3a4eb183b" datatype="html">
+ <source>Value should be between 0.0 and 1.0</source>
+ <target>O valor deve ser entre 0.0 e 1.0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d99b34162c9c34f10d0ccd8dbae83d8569c2db77" datatype="html">
+ <source>Max bytes</source>
+ <target>Máx. de bytes</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">546</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1d14a18879c62f3f4ed705318b7164a1160e249" datatype="html">
+ <source>Leave it blank or specify 0 to disable this quota.</source>
+ <target>Deixe-a em branco ou especifique 0 para desabilitar esta cota.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">572</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7565b131562ff6c5f769fdbd239a772154abdd97" datatype="html">
+ <source>A valid quota should be greater than 0.</source>
+ <target>Uma cota válida deve ser maior do que 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">550</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">574</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b8bf35b66f09a301eef92ffc3cb2fd259df67ce9" datatype="html">
+ <source>Max objects</source>
+ <target>Máx. de objetos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">570</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="95f348167622d832c5ae532b6944635c8e2ae5cb" datatype="html">
+ <source>The value should be greater or equal to 0</source>
+ <target>O valor deve ser maior do que ou igual a 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">586</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1088629182722162774" datatype="html">
+ <source>pool</source>
+ <target>pool</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6215593782779198370" datatype="html">
+ <source>erasure code profile</source>
+ <target>perfil de código de eliminação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4390273881304618317" datatype="html">
+ <source>crush rule</source>
+ <target>regra de crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">721</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d8a7c8aea58294a3c57c23af0468ddf0ba0c9c7" datatype="html">
+ <source>Pools List</source>
+ <target>Lista de Pools</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9055665654201606988" datatype="html">
+ <source>Data Protection</source>
+ <target>Proteção de Dados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6658000829978978023" datatype="html">
+ <source>Applications</source>
+ <target>Aplicativos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5232365108332422324" datatype="html">
+ <source>PG Status</source>
+ <target>Status do PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1669788723782899084" datatype="html">
+ <source>Crush Ruleset</source>
+ <target>Conjunto de Regras do Crush</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7961062124768120122" datatype="html">
+ <source>Pool deletion is disabled by the mon_allow_pool_delete configuration setting.</source>
+ <target>A exclusão de pool foi desabilitada pela configuração mon_allow_pool_delete.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee5132a8da30e0b7f9f5c70dbc91928d17dd909" datatype="html">
+ <source>Owner</source>
+ <target>Proprietário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c51963a9c553b29427ef783bbb69fa6634fa8c" datatype="html">
+ <source>Index type</source>
+ <target>Tipo de índice</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e6f950a32eaea32ec7e192f9ca3d3dfe469d4ba" datatype="html">
+ <source>Placement rule</source>
+ <target>Regra de posicionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6972d213e31c4ea4f887e60db99d9881bc8fcd3e" datatype="html">
+ <source>Marker</source>
+ <target>Marcador</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47b02acd2d3254d1ace1926f840523f154ebef71" datatype="html">
+ <source>Maximum marker</source>
+ <target>Marcador máximo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="092fa3a7df9168b14d3f83a77a4035e92b92ce15" datatype="html">
+ <source>Master version</source>
+ <target>Versão master</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97434cc5001d407f90c7447a12d9e8e6848a2aa3" datatype="html">
+ <source>Modification time</source>
+ <target>Horário da modificação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90fe2e41e7fde38453ce4e619efeea9bc6adea9c" datatype="html">
+ <source>Zonegroup</source>
+ <target>Grupo de zonas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="efeade5060b3add63863c24871f0830fb16b7e6d" datatype="html">
+ <source>Versioning</source>
+ <target>Controle de versão</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62a923f047ca49e7a4782629e91fea1ba32db68f" datatype="html">
+ <source>MFA Delete</source>
+ <target>Exclusão da MFA</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="649a410bd0ace333d067d8fa22f12bdbdb43533b" datatype="html">
+ <source>Bucket quota</source>
+ <target>Cota do compartimento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">567</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f50a33d3c339f8f4a465141f8caa5d2d8c005251" datatype="html">
+ <source>Enabled</source>
+ <target>Habilitado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">579</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cef1595d040e77cbb4466e60382028d4c2040cac" datatype="html">
+ <source>Maximum size</source>
+ <target>Tamanho máximo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa6fb95c355f172bda303de1ce2f38c251a149cf" datatype="html">
+ <source>Unlimited</source>
+ <target>Ilimitado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee862a800364b4d11f9b8cb9955a28a60f840a45" datatype="html">
+ <source>Maximum objects</source>
+ <target>Máximo de objetos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b84370895ab9eb44672f57146fa05c5947f1c0c" datatype="html">
+ <source>Locking</source>
+ <target>Bloqueio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c3d9d2296f7886e8289b9f623323803deacfc6" datatype="html">
+ <source>Days</source>
+ <target>Dias</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f44bdf9ab00a973bbe482e9fc450e3f67e60c0d" datatype="html">
+ <source>Bucket names can only contain lowercase letters, numbers, periods and hyphens.</source>
+ <target>Os nomes de compartimentos podem conter apenas letras minúsculas, números, pontos e hifens.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eabb4db920d9f9b2480cf438468b86e1bea02a9b" datatype="html">
+ <source>The chosen name is already in use.</source>
+ <target>O nome escolhido já está em uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b06de7f834c622197e68b66a2abe893040b174c4" datatype="html">
+ <source>Bucket names must not contain uppercase characters or underscores.</source>
+ <target>Os nomes de compartimentos não devem conter caracteres maiúsculos ou sublinhados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abacf4af2f66d3af08c5ebe502b21b1f42ac649" datatype="html">
+ <source>Each label must start and end with a lowercase letter or a number.</source>
+ <target>Cada rótulo deve começar e terminar com uma letra minúscula ou um número.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a7f52e6813e0535026f61a2d6e8adc8a1d006a" datatype="html">
+ <source>Bucket names cannot be formatted as IP address.</source>
+ <target>Não é possível formatar nomes de compartimentos como endereço IP.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2a2460396d35e14e7acfb4e060196a0679bdcff" datatype="html">
+ <source>Bucket labels cannot be empty and can only contain lowercase letters, numbers and hyphens.</source>
+ <target>Os rótulos de compartimentos não podem ficar vazios e só podem conter letras minúsculas, números e hifens.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf5c849977e0be2dbfc862d044edd323bfd9fb77" datatype="html">
+ <source>Bucket names must be 3 to 63 characters long.</source>
+ <target>Os nomes de compartimentos devem ter de 3 a 63 caracteres.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e4c918357c7445fbf19a203e5f0f0ece1960b3b" datatype="html">
+ <source>-- Select a user --</source>
+ <target>-- Selecionar usuário --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4aab1f837bc8ec222e4f25922465d1c5929a1fc" datatype="html">
+ <source>Placement target</source>
+ <target>Destino de posicionamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bae0a7fc2c9c1fde7d937a8a1a3c7e6825cf7d1" datatype="html">
+ <source>-- Select a placement target --</source>
+ <target>-- Selecionar destino de posicionamento --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="016d24e069e7d505a090fb8243e5cd43b35dc39b" datatype="html">
+ <source>Enables versioning for the objects in the bucket.</source>
+ <target>Habilita o controle de versão dos objetos no compartimento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">151</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e6775ffd06878aa145c07359f28557f01ede04f" datatype="html">
+ <source>Multi-Factor Authentication</source>
+ <target>Autenticação Multifator</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29e8a5d4fb767d4ad0c762c81c6264cec4c0ba97" datatype="html">
+ <source>Delete enabled</source>
+ <target>Exclusão habilitada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40fbc3ac8c1ea4ecfe62247e91f1f999ad5baf76" datatype="html">
+ <source>Enables MFA (multi-factor authentication) Delete, which requires additional authentication for changing the bucket versioning state.</source>
+ <target>Habilita a Exclusão da MFA (autenticação multifator), que exige autenticação adicional para alterar o estado do controle de versão do compartimento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24c93a8c13db46defa06ed7b5e026a3edb52b91" datatype="html">
+ <source>Token Serial Number</source>
+ <target>Número de Série do Token</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6d9536c2af2e5e9a228c3e3e1809dc1fefe0149" datatype="html">
+ <source>Token PIN</source>
+ <target>PIN do Token</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f038d51ab1645f15b0cd58f195c72a7eeebd4729" datatype="html">
+ <source>Enables locking for the objects in the bucket. Locking can only be enabled while creating a bucket.</source>
+ <target>Habilita o bloqueio dos objetos no compartimento. O bloqueio apenas pode ser habilitado ao criar um compartimento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9af1b4baa2dd8ed2bfc3cc756b12a2271c2dd793" datatype="html">
+ <source>Compliance</source>
+ <target>Conformidade</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="edd600fa489d1b4a4448dce694ed932e52ce8fda" datatype="html">
+ <source>Governance</source>
+ <target>Governança</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="218c7d6d318c51e7105309aaeb0baec9d19e4efb" datatype="html">
+ <source>The number of days that you want to specify for the default retention period that will be applied to new objects placed in this bucket.</source>
+ <target>O número de dias que você deseja especificar para o período de retenção padrão que será aplicado aos novos objetos armazenados neste compartimento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">264</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="289b101ec12427b3ca819df9e43cc3b14fae2cc4" datatype="html">
+ <source>The entered value must be a positive integer.</source>
+ <target>O valor inserido deve ser um número inteiro positivo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48d8247c1ba2ea156109bf286c5f6dd26b4be760" datatype="html">
+ <source>Retention Days must be a positive integer.</source>
+ <target>Dias de Retenção deve ser um número inteiro positivo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4349284625269221231" datatype="html">
+ <source>bucket</source>
+ <target>compartimento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6161088322338624846" datatype="html">
+ <source>Updated Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'.</source>
+ <target>Compartimento do Gateway de Objetos atualizado '<x id="PH" equiv-text="values.bid"/>'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218632328857697292" datatype="html">
+ <source>Created Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'</source>
+ <target>Compartimento do Gateway de Objetos criado '<x id="PH" equiv-text="values.bid"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c338bae89822d7eefbc9a887c458a7d8a98e55e" datatype="html">
+ <source>No Limit</source>
+ <target>Sem Limite</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3715596725146409911" datatype="html">
+ <source>Owner</source>
+ <target>Proprietário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5545511293826600258" datatype="html">
+ <source>Used Capacity</source>
+ <target>Capacidade Usada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1925090152473969054" datatype="html">
+ <source>Capacity Limit %</source>
+ <target>Limite de Capacidade %</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8713861779825116442" datatype="html">
+ <source>Object Limit %</source>
+ <target>Limite de Objetos %</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5913880066213114620" datatype="html">
+ <source>buckets</source>
+ <target>compartimentos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eeba399c4dae8d4890c27b7a2cd2dc28fcf8b5f9" datatype="html">
+ <source>Performance Counters</source>
+ <target>Contadores de Desempenho</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="479488ab6e91ecb375484edc78bee3d13467f33f" datatype="html">
+ <source>Daemons List</source>
+ <target>Lista de Daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca2dee83bb58290d93fb0d17ee8bc9f095a4576f" datatype="html">
+ <source>Sync Performance</source>
+ <target>Desempenho de Sincronizaão</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4378147649219625174" datatype="html">
+ <source>Zone</source>
+ <target>Zona</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6148052126949932311" datatype="html">
+ <source>Zone Group</source>
+ <target>Grupo de Zonas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3840481991104643295" datatype="html">
+ <source>Realm</source>
+ <target>Domínio</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1221ca97d19eaa9a7bc0c5243d5fc5befe1d2314" datatype="html">
+ <source>-- Select a type --</source>
+ <target>-- Selecionar tipo --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1b8990332af18f1c5159a6061ca889bcbb28432" datatype="html">
+ <source>Permission</source>
+ <target>Permissão</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a08c589f82f69d892307288da14190ae1dd583d5" datatype="html">
+ <source>-- Select a permission --</source>
+ <target>-- Selecionar permissão --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7345972049922682356" datatype="html">
+ <source>capability</source>
+ <target>recurso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a94e6b2b5b834d92cceb90037d51ad6165c8b619" datatype="html">
+ <source>Tenant</source>
+ <target>Locatário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
+ <source>User ID</source>
+ <target>ID de Usuário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b760f123248930122fc7e7b6b6bf94e376e959c8" datatype="html">
+ <source>Full name</source>
+ <target>Nome completo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69b6ac577a19acc39fc0c22342092f327fff2529" datatype="html">
+ <source>Email address</source>
+ <target>Endereço de e-mail</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92f3f203270a29b3001871153f02c063484a1574" datatype="html">
+ <source>Suspended</source>
+ <target>Suspenso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011e20c5bbe51602d459a860fbf29b599b55edd" datatype="html">
+ <source>System</source>
+ <target>Sistema</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db18a2772988415466a7f75dc42663ce78c9c1d3" datatype="html">
+ <source>Maximum buckets</source>
+ <target>Máximo de compartimentos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c4c62e8ba24601be5cfe7dc5d32c24bbbd4b53c" datatype="html">
+ <source>Subusers</source>
+ <target>Subusuários</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17bb3082e6fe5003203ef992a3714172334631a1" datatype="html">
+ <source>Capabilities</source>
+ <target>Recursos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32f8a0570373cacb9c56cf227502483a29d605bc" datatype="html">
+ <source>MFAs(Id)</source>
+ <target>MFAs(Id)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36ad38f9c1a1485e09b67778a28af84553290ffb" datatype="html">
+ <source>User quota</source>
+ <target>Cota do usuário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">473</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0bcd5ef19af0f1b814141ca8c57df623d8270088" datatype="html">
+ <source>Keys</source>
+ <target>Chaves</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2aba1e87039819aca3b70faa9aa848c12bf139ca" datatype="html">
+ <source>Show</source>
+ <target>Mostrar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">395</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5248717555542428023" datatype="html">
+ <source>Username</source>
+ <target>Nome de usuário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240806681889331244" datatype="html">
+ <source>Unlimited</source>
+ <target>Ilimitado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db4e1a734518691b128ef40b939cc673f01d03a6" datatype="html">
+ <source>The value is not valid.</source>
+ <target>O valor não é válido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">617</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6aaf5d2a304167272ac73e3b1d1c162e16c77858" datatype="html">
+ <source>The chosen user ID is already in use.</source>
+ <target>O ID de usuário escolhido já está em uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="025be1d01b2f6cbd09e772a1d3de02fab0678b26" datatype="html">
+ <source>Show Tenant</source>
+ <target>Mostrar Locatário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6af106b0d759fd2882e645604675c4494abfcd5b" datatype="html">
+ <source>The chosen user ID exists in this tenant.</source>
+ <target>O ID de usuário escolhido neste locatário.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="df441e80db2157f9d272b75de724ba4a82b96b57" datatype="html">
+ <source>This is not a valid email address.</source>
+ <target>Este não é um endereço de e-mail válido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca271adf154956b8fcb28f4f50a37acb3057ff7c" datatype="html">
+ <source>The chosen email address is already in use.</source>
+ <target>O endereço de e-mail escolhido já está em uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="030197cebe938edf35422e92fe14183d06eb670b" datatype="html">
+ <source>Max. buckets</source>
+ <target>Máx. de compartimentos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f39256070bfc0714020dfee08895421fc1527014" datatype="html">
+ <source>Disabled</source>
+ <target>Desabilitado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c05002b0ac2040f1aede5e727e0ffd06eda819" datatype="html">
+ <source>Custom</source>
+ <target>Personalizado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28872515cb81d197a3a1733fa546d3e0f0dd6c67" datatype="html">
+ <source>The entered value must be &gt;= 1.</source>
+ <target>O valor inserido deve ser &gt;= 1.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="583a219c524155c2314eb06ee29162bb315272a3" datatype="html">
+ <source>S3 key</source>
+ <target>Chave S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c217ee914725a37e9dd2336c721c8e63e9666bdc" datatype="html">
+ <source>Auto-generate key</source>
+ <target>Gerar chave automaticamente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f1c1c0f2bce4c9f92d1a2061e8161cb0006c31a" datatype="html">
+ <source>Access key</source>
+ <target>Chave de acesso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b864acb67296a9819c1db0069c4c47d8b5ce8f44" datatype="html">
+ <source>Secret key</source>
+ <target>Chave secreta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="128d6efb51d9ddc7c0cc695a2deeca5b9523f6e4" datatype="html">
+ <source>There are no subusers.</source>
+ <target>Não há subusuários.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fd6dfb8ecb982dbc3affb2c2d5414c4f5b6abd2" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">294,295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67c746c1ba9dab4351fedc4c7cba4e6d6b0dbc47" datatype="html">
+ <source>S3</source>
+ <target>S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d6819038d608623503918fb2553f53d68231ec3a" datatype="html">
+ <source>There are no keys.</source>
+ <target>Não há chaves.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">377</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc1c1a7140ff6b815a95b65ee2780fdbe1b2b7a1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">356,357</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6ddb5e991a3ecd2659fb520bc5acc81b67e08ddd" datatype="html">
+ <source>Swift</source>
+ <target>Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">371</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d01eccdda47fc907c5be35bcb16d2dcd02b0270" datatype="html">
+ <source>There are no capabilities.</source>
+ <target>Não há recursos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5a451c4ea65a4046f0b49d489a7013abf0b5861" datatype="html">
+ <source>All capabilities are already added.</source>
+ <target>Todos os recursos já foram adicionados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">456</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="043e2ec0036ceadd926fd5e3f93cd6f3565f3648" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">461,462</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6146e13ceca5fa5cc17b771b282fe5955f3d19fa" datatype="html">
+ <source>Unlimited size</source>
+ <target>Tamanho ilimitado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">595</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6db8aa7c99fdce18edb33dde57729acede2b308" datatype="html">
+ <source>Max. size</source>
+ <target>Tamanho máx.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">511</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">605</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc630b2093e880fffa19df99d5cd8b87605037f8" datatype="html">
+ <source>Unlimited objects</source>
+ <target>Objetos ilimitados</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cda5a993d06f0bb10048be9d3aba6555aa9f356" datatype="html">
+ <source>Max. objects</source>
+ <target>Máx. de objetos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">642</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="623ac50f37a26caec6fd7cd519b653e3315cba25" datatype="html">
+ <source>The entered value must be &gt;= 0.</source>
+ <target>O valor inserido deve ser &gt;= 0.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">654</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="123010868147850959" datatype="html">
+ <source>user</source>
+ <target>usuário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8368421344177343441" datatype="html">
+ <source>subuser</source>
+ <target>subusuário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4662015204945271252" datatype="html">
+ <source>S3 Key</source>
+ <target>Chave S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9103468069826049692" datatype="html">
+ <source>Updated Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <target>Usuário do Gateway de Objetos atualizado '<x id="PH" equiv-text="uid"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="884841609901737584" datatype="html">
+ <source>Created Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <target>Usuário do Gateway de Objetos criado '<x id="PH" equiv-text="uid"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4363143805416924501" datatype="html">
+ <source>Tenant</source>
+ <target>Locatário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8301535046747035390" datatype="html">
+ <source>Full name</source>
+ <target>Nome completo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3967269098753656610" datatype="html">
+ <source>Email address</source>
+ <target>Endereço de e-mail</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5851424994801012357" datatype="html">
+ <source>Suspended</source>
+ <target>Suspenso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208300173682032371" datatype="html">
+ <source>Max. buckets</source>
+ <target>Máx. de compartimentos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1670306451865226564" datatype="html">
+ <source>users</source>
+ <target>usuários</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c614babd1950adb2be75df4e2c9747286d6adc" datatype="html">
+ <source>-- Select a username --</source>
+ <target>-- Selecionar nome de usuário --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2841767821d6b66238c34d07e413b0af67aee92" datatype="html">
+ <source>Subuser</source>
+ <target>Subusuário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd59fc25a7bd98cff3e75117c09697c8a007a514" datatype="html">
+ <source>The chosen subuser ID is already in use.</source>
+ <target>O ID de subusuário escolhido já está em uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d386c357ebcbc04ed05c4babd5a03626f9b1674" datatype="html">
+ <source>read, write</source>
+ <target>leitura, gravação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84e3e3f9a4f31a039b648c97debf95fcb20f4c4a" datatype="html">
+ <source>full</source>
+ <target>completo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6bf81d032a2316464f9df2f0d2f3d753f89f0d3" datatype="html">
+ <source>Swift key</source>
+ <target>Chave Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e0c12685d50d47448ceed9423977ef39775c037" datatype="html">
+ <source>Auto-generate secret</source>
+ <target>Gerar segredo automaticamente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5091031285775138345" datatype="html">
+ <source>Subuser</source>
+ <target>Subusuário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8453697749389230205" datatype="html">
+ <source>Swift Key</source>
+ <target>Chave Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ac54c18c1b520e948095c83a3a1025f02ce6dcc6" datatype="html">
+ <source>Neither hostname nor OSD ID given</source>
+ <target>Não foi especificado um nome de host ou um ID do OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4533150758393178756" datatype="html">
+ <source>Device ID</source>
+ <target>ID do Dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1291053608320944146" datatype="html">
+ <source>State of Health</source>
+ <target>Estado de Saúde</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29167121133682512" datatype="html">
+ <source>Good</source>
+ <target>Bom</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8767957606064036733" datatype="html">
+ <source>Bad</source>
+ <target>Ruim</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8052456228079338924" datatype="html">
+ <source>Stale</source>
+ <target>Obsoleto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6223439643831041743" datatype="html">
+ <source>Life Expectancy</source>
+ <target>Expectativa de Vida</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3144481541623761279" datatype="html">
+ <source>Prediction Creation Date</source>
+ <target>Data de Criação da Predição</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="264574868375698540" datatype="html">
+ <source>Device Name</source>
+ <target>Nome do Dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1419569261746199221" datatype="html">
+ <source>Daemons</source>
+ <target>Daemons</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f635b3cb0600409a2ad44a5bd1863c699e6a01c" datatype="html">
+ <source>Failed to retrieve SMART data.</source>
+ <target>Falha ao recuperar os dados SMART.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a8a3f354bd640299068edd912f4bb5325264f250" datatype="html">
+ <source>The data received has the JSON format version 2.x and is currently incompatible with the dashboard.</source>
+ <target>Os dados recebidos têm o formato JSON versão 2.x e são incompatíveis com o painel de controle no momento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="04f8a3c7e8ac610e6581960162cc15f55a16696a" datatype="html">
+ <source>No SMART data available.</source>
+ <target>Sem dados SMART disponíveis.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a185c9b97513b3882604ea9bab60edbfac945c15" datatype="html">
+ <source>SMART overall-health self-assessment test result</source>
+ <target>Resultado do teste de autoavaliação da saúde geral do SMART</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="290e4c9ad42dc6e9176656c864a5faed8053f406" datatype="html">
+ <source>unknown</source>
+ <target>desconhecido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a03d3c2e459f8f8fa7202c0fce465d6165f9e2b" datatype="html">
+ <source>passed</source>
+ <target>aprovado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41435d5a5692c8e412c74deaee95d99dbd3617e1" datatype="html">
+ <source>failed</source>
+ <target>reprovado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddd5dd6d930030096ea617f62c82b648a0dd9484" datatype="html">
+ <source>Device Information</source>
+ <target>Informações do Dispositivo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e149c483d88cfcff11d1c5db85e84af7c3149c4" datatype="html">
+ <source>No device information available for this device.</source>
+ <target>Sem informações disponíveis para este dispositivo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20cb12827cbe559a7b1da6fdae96041b3b5c3c55" datatype="html">
+ <source>SMART</source>
+ <target>SMART</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380295f37caea93701d071485a38ef0bdba57133" datatype="html">
+ <source>No SMART data available for this device.</source>
+ <target>Sem dados SMART disponíveis para este dispositivo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5758c3f16f8749f0f4e2a787f02e8b4da246102f" datatype="html">
+ <source>SMART data is loading.</source>
+ <target>Carregando dados SMART.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5363861031080361352" datatype="html">
+ <source>Smartctl has received an unknown argument (error code <x id="PH" equiv-text="smartData.smartctl_error_code"/>). You may be using an incompatible version of smartmontools. Version &gt;= 7.0 of smartmontools is required to successfully retrieve data.</source>
+ <target>Smartctl recebeu um argumento desconhecido (código do erro <x id="PH" equiv-text="smartData.smartctl_error_code"/>). Talvez você use uma versão incompatível do smartmontools. A versão &amp;gt;= 7.0 do smartmontools é necessária para recuperar os dados com êxito.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">61,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5085718566932809950" datatype="html">
+ <source>An error with error code <x id="PH" equiv-text="smartData.smartctl_error_code"/> occurred.</source>
+ <target>Ocorreu um erro com o código <x id="PH" equiv-text="smartData.smartctl_error_code"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2091295268977103253" datatype="html">
+ <source>Raw</source>
+ <target>Bruto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5963653123239768443" datatype="html">
+ <source>Threshold</source>
+ <target>Limite</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2893124970059125090" datatype="html">
+ <source>When Failed</source>
+ <target>Quando Falhou</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5614367840516299633" datatype="html">
+ <source>Worst</source>
+ <target>Pior</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d06ae77f9ec46a4cdd49e7e76c73a411aaf2ee38" datatype="html">
+ <source>Please set a new password.</source>
+ <target>Defina uma senha nova.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8b5b3566e88438f51bd5f6caf6c090ed565ba5ed" datatype="html">
+ <source>You will be redirected to the login page afterwards.</source>
+ <target>Na sequência, você será redirecionado à página de login.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cf42e491adc166a337a960eb84d03c0c3f677c8" datatype="html">
+ <source>The old and new passwords must be different.</source>
+ <target>As senhas antiga e nova devem ser diferentes.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90163a3d3746819aef42e829f4446331232f3b66" datatype="html">
+ <source>Password confirmation doesn't match the new password.</source>
+ <target>A confirmação da senha não é igual à senha nova.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0070e83d11da39d6f4bb95065c2675db1610b419" datatype="html">
+ <source>Username is required</source>
+ <target>Nome de usuário é obrigatório</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e20f8b8a4706526c9024cc2f39d568345d100dc" datatype="html">
+ <source>Password is required</source>
+ <target>Senha é obrigatória</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f093d9574ab746b231504bd2cbb65f04bd7b00db" datatype="html">
+ <source>Log in</source>
+ <target>Efetuar Login</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5590086849807274701" datatype="html">
+ <source>Scope</source>
+ <target>Escopo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327592562693301723" datatype="html">
+ <source>Read</source>
+ <target>Leitura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5674286808255988565" datatype="html">
+ <source>Create</source>
+ <target>Criar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4021752662928002901" datatype="html">
+ <source>Update</source>
+ <target>Atualizar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022070615528435141" datatype="html">
+ <source>Delete</source>
+ <target>Excluir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ea5c4d8942c00752dcc72e72949c5d9832f6399" datatype="html">
+ <source>Description...</source>
+ <target>Descrição...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70f45880fce6ac5d8e468e25e82aefbba8098cfe" datatype="html">
+ <source>Permissions</source>
+ <target>Permissões</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="122114774689391224" datatype="html">
+ <source>role</source>
+ <target>função</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616102757855967475" datatype="html">
+ <source>All</source>
+ <target>Tudo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4416727401284087008" datatype="html">
+ <source>Created role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <target>Função '<x id="PH" equiv-text="roleFormModel.name"/>' criada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3472946357042916911" datatype="html">
+ <source>Updated role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <target>Função '<x id="PH" equiv-text="roleFormModel.name"/>' atualizada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="373024661645814027" datatype="html">
+ <source>System Role</source>
+ <target>Função do Sistema</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753648234171918096" datatype="html">
+ <source>Deleted role '<x id="PH" equiv-text="role"/>'</source>
+ <target>Função '<x id="PH" equiv-text="role"/>' excluída</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1674202514578558795" datatype="html">
+ <source>New name</source>
+ <target>Novo nome</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4857700187193019038" datatype="html">
+ <source>Clone Role</source>
+ <target>Clonar Função</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="748631939386170157" datatype="html">
+ <source>Cloned role '<x id="PH" equiv-text="values['newName']"/>' from '<x id="PH_1" equiv-text="name"/>'</source>
+ <target>Função '<x id="PH" equiv-text="values['newName']"/>' clonada de '<x id="PH_1" equiv-text="name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="195c31a2f970e790231a6bb94a5e8ca0167406d9" datatype="html">
+ <source>The username already exists.</source>
+ <target>O nome de usuário já existe.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f3bdcce4b2e8c37cd7f0f6c92ef8cff34b039b8" datatype="html">
+ <source>Confirm password</source>
+ <target>Confirmar senha</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cbb979e63ba50e0ca3adfa09cbdcaefd0853fca1" datatype="html">
+ <source>Password confirmation doesn't match the password.</source>
+ <target>A confirmação de senha não corresponde à senha.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="96621f9ed2e4ae5204564e583d2c816bedead571" datatype="html">
+ <source>Password expiration date</source>
+ <target>Data de vencimento da senha</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48932db3801fe9d5d72a60a3e656bffd17c1c5d9" datatype="html">
+ <source>Password expiration date...</source>
+ <target>Data de vencimento da senha...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc" datatype="html">
+ <source>Email</source>
+ <target>E-mail</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d0ec081dd61eb4f43aea269077bbe38eae87b7f9" datatype="html">
+ <source>Invalid email.</source>
+ <target>E-mail inválido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9610487cbeb5796d34d8601b5ac0c0a65f9e1d19" datatype="html">
+ <source>Roles</source>
+ <target>Funções</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8913c216dd506e20e412e144381d8d2a65a84359" datatype="html">
+ <source>User must change password at next logon</source>
+ <target>O usuário deve alterar a senha no próximo logon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0051a3479d3ba79135c16dc8cc017950a2cce821" datatype="html">
+ <source>You are about to remove &quot;user read / update&quot; permissions from your own user.</source>
+ <target>Você está prestes a remover as permissões de &quot;leitura/atualização de usuário&quot; do seu próprio usuário.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af4bf9fcb256853f14cf947eb1deb8d7f176d3f9" datatype="html">
+ <source>If you continue, you will no longer be able to add or remove roles from any user.</source>
+ <target>Se você continuar, não poderá mais adicionar ou remover funções de nenhum usuário.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314291969883771319" datatype="html">
+ <source>There are no roles.</source>
+ <target>Não há funções.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4306072924538089180" datatype="html">
+ <source>Created user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <target>Usuário '<x id="PH" equiv-text="userFormModel.username"/>' criado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1349763489797682899" datatype="html">
+ <source>Update user</source>
+ <target>Atualizar usuário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8688396456017237992" datatype="html">
+ <source>You were automatically logged out because your roles have been changed.</source>
+ <target>Você foi automaticamente desconectado porque suas funções foram alteradas.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2335813072344088607" datatype="html">
+ <source>Updated user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <target>Usuário '<x id="PH" equiv-text="userFormModel.username"/>' atualizado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4768749765465246664" datatype="html">
+ <source>Email</source>
+ <target>E-mail</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795890916060309463" datatype="html">
+ <source>Roles</source>
+ <target>Funções</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6877445485286599988" datatype="html">
+ <source>Password expiration date</source>
+ <target>Data de vencimento da senha</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="705657168061753072" datatype="html">
+ <source>Deleted user '<x id="PH" equiv-text="username"/>'</source>
+ <target>Usuário '<x id="PH" equiv-text="username"/>' excluído</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="405819296611088743" datatype="html">
+ <source>Failed to delete user '<x id="PH" equiv-text="username"/>'</source>
+ <target>Falha ao excluir o usuário '<x id="PH" equiv-text="username"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8935387756949610047" datatype="html">
+ <source>You are currently logged in as '<x id="PH" equiv-text="username"/>'.</source>
+ <target>Você efetuou login como '<x id="PH" equiv-text="username"/>'.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0eb15f32b2b92d7f3103ef3ff032621888a8dc32" datatype="html">
+ <source>Old password</source>
+ <target>Senha antiga</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229" datatype="html">
+ <source>New password</source>
+ <target>Senha nova</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ede41f01c781b168a783cfcefc6fb67d48780d9b" datatype="html">
+ <source>Confirm new password</source>
+ <target>Confirmar senha nova</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809196861118879526" datatype="html">
+ <source>password</source>
+ <target>senha</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623124197136601291" datatype="html">
+ <source>Updated user password&quot;</source>
+ <target>Senha do usuário atualizada&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be" datatype="html">
+ <source>Users</source>
+ <target>Usuários</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ced3246fa3db31be0f7da06648463f29ba378fbe" datatype="html">
+ <source>Selected Object Gateway:</source>
+ <target>Gateway de Objetos Selecionados:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c53062af97ebda2a03f905698f58e524ecf8b968" datatype="html">
+ <source>Select Object Gateway</source>
+ <target>Gateway de Objetos Selecionado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="235c355afdcbf72953a15d7fc8d0d9e7a6619f46" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Page not Found<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Página não Encontrada<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aee9d027170f84774f2980537556f5099369b82" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for. The page you requested may have been changed or moved.</source>
+ <target>Não encontramos o que você procura. A página solicitada pode ter sido alterada ou movida.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">22,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2b46fe9a975c6531af77fee858ccd37327980f7" datatype="html">
+ <source>Please consult the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>documentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> on how to configure and enable the <x id="INTERPOLATION" equiv-text="{{ section_info }}"/> management functionality.</source>
+ <target>Consulte a <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>documentação<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> sobre como configurar e habilitar a funcionalidade de gerenciamento <x id="INTERPOLATION" equiv-text="{{ section_info }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">26,27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9d57ca7cab78c6f0d27e0d890cb8cf1515e4e30a" datatype="html">
+ <source>Go To Dashboard</source>
+ <target>Ir para o Painel de Controle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6578397717654172779" datatype="html">
+ <source>Page Not Found</source>
+ <target>Página Não Encontrada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8185335715884155108" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for.
+ The page you requested may have been changed or moved.</source>
+ <target>Não encontramos o que você procura.
+ A página solicitada pode ter sido alterada ou movida.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="143318366100741906" datatype="html">
+ <source>Access Denied</source>
+ <target>Acesso Negado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5384670299771400832" datatype="html">
+ <source>Sorry, you don’t have permission to view this page or resource.</source>
+ <target>Você não tem permissão para ver esta página ou recurso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2424411274809083521" datatype="html">
+ <source>User Denied</source>
+ <target>Usuário Negado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7645004872908092358" datatype="html">
+ <source>Sorry, the user does not exist in Ceph.
+ You'll be logged out from the Identity Provider when you retry logging in.</source>
+ <target>O usuário não existe no Ceph.
+ Seu logout será efetuado do Provedor de Identidade quando você repetir o login.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">24,25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f286db6ac9482dbf567bc491d49a6eade444895a" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7911416166208830577" datatype="html">
+ <source>Help</source>
+ <target>Ajuda</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8878700331247603166" datatype="html">
+ <source>Security</source>
+ <target>Segurança</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8642696205489749843" datatype="html">
+ <source>Trademarks</source>
+ <target>Marcas Registradas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1481ecd21e760ac919a24e26cf790acd82e40199" datatype="html">
+ <source>Dashboard Settings</source>
+ <target>Configurações do Painel de Controle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a79aab4ef674bf3f6532292107c0054302236e0f" datatype="html">
+ <source>User management</source>
+ <target>Gerenciamento de usuários</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="197e0246502ca64d0de0df0d5c2deec51d41ff45" datatype="html">
+ <source>Telemetry configuration</source>
+ <target>Configuração de telemetria</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85b79c9064aed1ead31ace985f31aa1363f6bdaf" datatype="html">
+ <source>Help</source>
+ <target>Ajuda</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06638e0f01d82c0786f63aa9832fbe7866b86087" datatype="html">
+ <source>documentation</source>
+ <target>documentação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e351b40b3869a5c7d19c3d4918cb1ac7aaab95c4" datatype="html">
+ <source>API</source>
+ <target>API</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a" datatype="html">
+ <source>About</source>
+ <target>Sobre</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="049dfd9fe6c78914ad58cf89ac6a631fca28ec74" datatype="html">
+ <source>Logged in user</source>
+ <target>Usuário que efetuou login</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5022c5ae3ae921c07bf5f881e9b026b4a6708a7" datatype="html">
+ <source>Signed in as <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>Login efetuado como <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9" datatype="html">
+ <source>Change password</source>
+ <target>Alterar senha</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d22c795daf43877a5f708dca2bccd549eb0471d" datatype="html">
+ <source>Sign out</source>
+ <target>Efetuar logout</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319e0745bcbc132451569294fa2fa21bf10f555a" datatype="html">
+ <source>Toggle navigation</source>
+ <target>Alternar navegação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f65253954b66e929a8b4d5ecaf61f9129f8cec64" datatype="html">
+ <source>Dashboard</source>
+ <target>Painel de controle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c95898abff46bfac3ed6eb2afef74597e60b15c" datatype="html">
+ <source>CRUSH map</source>
+ <target>Mapa CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7b2bc4b86de6e96d353f6bf2b4d793ea3a19ba0" datatype="html">
+ <source>Manager Modules</source>
+ <target>Módulos do Gerenciador</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb3d5aefff38a814b76da74371cbf02c0789a1ef" datatype="html">
+ <source>Logs</source>
+ <target>Registros</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17fc3efe5f9fa4e0289c900cb6202265215a1a27" datatype="html">
+ <source>Monitoring</source>
+ <target>Monitoramento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f5d0c10614e8a34f0e2dad33a0568277c50cf69" datatype="html">
+ <source>Block</source>
+ <target>Bloco</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3c2562ba992127203dcfd014010b03cb7b8113c6" datatype="html">
+ <source>Mirroring</source>
+ <target>Espelhamento</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="811c241d56601b91ef26735b770e64428089b950" datatype="html">
+ <source>iSCSI</source>
+ <target>iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a24eabd99ea5af20f5f94c4484649cd30370042b" datatype="html">
+ <source>NFS</source>
+ <target>NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5276fc60d54d667116babb723641b21281d37271" datatype="html">
+ <source>File Systems</source>
+ <target>Sistemas de Arquivos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9515520496da83179d8b08132f00f575512a1f40" datatype="html">
+ <source>Buckets</source>
+ <target>Compartimentos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a23e992f6c6e169a38b2b7338b4e5e803b52e0d" datatype="html">
+ <source>Tasks and Notifications</source>
+ <target>Tarefas e Notificações</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1390461972315002349" datatype="html">
+ <source>The name of the node under which data should be placed.</source>
+ <target>O nome do nó sob o qual os dados devem ser colocados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6575341202068728510" datatype="html">
+ <source>The type of CRUSH nodes across which we should separate replicas.</source>
+ <target>O tipo de nós do CRUSH nos quais devemos separar as réplicas.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3874278445824365480" datatype="html">
+ <source>The device class data should be placed on.</source>
+ <target>A classe do dispositivo em que os dados devem ser colocados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="675628105428950215" datatype="html">
+ <source>Each object is split in data-chunks parts, each stored on a different OSD.</source>
+ <target>Cada objeto é dividido em partes de pacotes de dados, cada uma armazenada em um OSD diferente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5128168460056151476" datatype="html">
+ <source>Compute coding chunks for each object and store them on different OSDs.
+ The number of coding chunks is also the number of OSDs that can be down without losing data.</source>
+ <target>Calcule os pacotes de codificação de cada objeto e armazene-os em diferentes OSDs.
+ O número de pacotes de codificação é também o número de OSDs que podem ficar inativos sem perda de dados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">18,19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8826111293169381132" datatype="html">
+ <source>The jerasure plugin is the most generic and flexible plugin,
+ it is also the default for Ceph erasure coded pools.</source>
+ <target>O plug-in jerasure é o mais genérico e flexível,
+ além de ser o padrão para pools codificados para eliminação do Ceph.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">23,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1331133460856304156" datatype="html">
+ <source>The more flexible technique is reed_sol_van : it is enough to set k
+ and m. The cauchy_good technique can be faster but you need to chose the packetsize
+ carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents
+ in the sense that they can only be configured with m=2.</source>
+ <target>A técnica mais flexível é reed_sol_van: ela é suficiente para definir k
+ e m. A técnica cauchy_good pode ser mais rápida, mas você precisa escolher o tamanho do pacote
+ com cuidado. Todos os reed_sol_r6_op, liberation, blaum_roth e liber8tion são equivalentes ao RAID6
+ no sentido de que só podem ser configurados com m=2.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">25,28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4577912952562931806" datatype="html">
+ <source>The encoding will be done on packets of bytes size at a time.
+ Choosing the right packet size is difficult.
+ The jerasure documentation contains extensive information on this topic.</source>
+ <target>A codificação será feita em pacotes de tamanho de bytes um de cada vez.
+ A escolha do tamanho do pacote certo é difícil.
+ A documentação do jerasure contém informações completas sobre este tópico.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">29,31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6471646852539810855" datatype="html">
+ <source>With the jerasure plugin, when an erasure coded object is stored on
+ multiple OSDs, recovering from the loss of one OSD requires reading from all the others.
+ For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading
+ from the eleven others to repair.
+
+ The lrc erasure code plugin creates local parity chunks to be able to recover using
+ less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create
+ an additional parity chunk for every four OSDs. When a single OSD is lost, it can be
+ recovered with only four OSDs instead of eleven.</source>
+ <target>Com o plug-in jerasure, quando um objeto codificado para eliminação é armazenado em
+ vários OSDs, a recuperação após a perda de um OSD requer a leitura de todos os outros.
+ Por exemplo, se o jerasure for configurado com k=8 e m=4, a perda de um OSD exigirá a leitura
+ dos outros onze para fazer o reparo.
+
+ O plug-in de código de eliminação lrc cria pacotes locais de paridade para conseguir recuperar usando
+ menos OSDs. Por exemplo, se o lrc for configurado com k=8, m=4 e l=4, ele criará
+ um pacote de paridade adicional para cada quatro OSDs. Quando um único OSD é perdido, ele pode ser
+ recuperado apenas com quatro OSDs, em vez de onze.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">34,42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2619235086723330982" datatype="html">
+ <source>Group the coding and data chunks into sets of size locality. For instance,
+ for k=4 and m=2, when locality=3 two groups of three are created. Each set can
+ be recovered without reading chunks from another set.</source>
+ <target>Agrupe os pacotes de codificação e dados em conjuntos de localidades com tamanho. Por exemplo,
+ no caso de k=4 e m=2, quando locality=3, dois grupos de três são criados. Cada conjunto pode
+ ser recuperado sem a leitura dos pacotes do outro conjunto.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">43,45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3298836762557512588" datatype="html">
+ <source>The type of the crush bucket in which each set of chunks defined
+ by l will be stored. For instance, if it is set to rack, each group of l chunks will be
+ placed in a different rack. It is used to create a CRUSH rule step such as step choose
+ rack. If it is not set, no such grouping is done.</source>
+ <target>O tipo do compartimento de crush em que cada conjunto de pacotes definido
+ por l será armazenado. Por exemplo, se isso for definido como rack, cada grupo de pacotes l será
+ colocado em um rack diferente. Isso é usado para criar uma etapa da regra CRUSH, como a etapa de escolha do
+ rack. Se isso não for definido, esse tipo de agrupamento não será feito.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">46,49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9162461669419243962" datatype="html">
+ <source>The isa plugin encapsulates the ISA library. It only runs on Intel processors.</source>
+ <target>O plug-in isa encapsula a biblioteca ISA. Ele apenas é executado em processadores Intel.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2389282202903059852" datatype="html">
+ <source>The ISA plugin comes in two Reed Solomon forms.
+ If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.</source>
+ <target>O plug-in ISA vem em dois formatos de Reed Solomon.
+ Se reed_sol_van for definido, ele será Vandermonde, se cauchy for definido, ele será Cauchy.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">53,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7319555444402547739" datatype="html">
+ <source>The shec plugin encapsulates the multiple SHEC library.
+ It allows ceph to recover data more efficiently than Reed Solomon codes.</source>
+ <target>O plug-in shec encapsula a biblioteca múltipla SHEC.
+ Ele permite ao ceph recuperar dados com mais eficiência do que os códigos de Reed Solomon.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">57,58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7723217930035575928" datatype="html">
+ <source>The number of parity chunks each of which includes each data chunk in its
+ calculation range. The number is used as a durability estimator. For instance, if c=2,
+ 2 OSDs can be down without losing data.</source>
+ <target>O número de pacotes de paridade, em que cada um inclui cada pacote de dados em sua
+ faixa de cálculo. O número é usado como estimador de durabilidade. Por exemplo, se c=2,
+ 2 OSDs podem ficar inativos sem perda de dados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">59,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2054101840892270818" datatype="html">
+ <source>CLAY (short for coupled-layer) codes are erasure codes designed to
+ bring about significant savings in terms of network bandwidth and disk IO when a failed
+ node/OSD/rack is being repaired.</source>
+ <target>Códigos CLAY (abreviação de coupled-layer) são códigos de eliminação criados para
+ proporcionar economias significativas em termos de largura de banda de rede e E/S de disco, quando um
+ nó/OSD/rack está sendo reparado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">64,66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491096236680229427" datatype="html">
+ <source>Number of OSDs requested to send data during recovery of a single chunk.
+ d needs to be chosen such that k+1 &lt;= d &lt;= k+m-1. The larger the d, the better
+ the savings.</source>
+ <target>Número de OSDs solicitados para enviar dados durante a recuperação de um único pacote.
+ d precisa ser escolhido para que k+1 &lt;= d &lt;= k+m-1. Quanto maior for d, melhor será
+ a economia.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">67,69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2625895656705896729" datatype="html">
+ <source>scalar_mds specifies the plugin that is used as a building block
+ in the layered construction. It can be one of jerasure, isa, shec.</source>
+ <target>scalar_mds especifica o plug-in que é usado como bloco de construção
+ na construção em camadas. Ele pode ser jerasure, isa ou shec.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">70,71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6639141182731628232" datatype="html">
+ <source>technique specifies the technique that will be picked
+ within the 'scalar_mds' plugin specified. Supported techniques
+ are 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good', 'liber8tion' for jerasure, 'reed_sol_van',
+ 'cauchy' for isa and 'single', 'multiple' for shec.</source>
+ <target>technique especifica a técnica que será escolhida
+ no plug-in 'scalar_mds' especificado. As técnicas suportadas
+ são 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good', 'liber8tion' para jerasure, 'reed_sol_van',
+ 'cauchy' para isa e 'single', 'multiple' para shec.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">72,76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8172892264673403098" datatype="html">
+ <source>The name of the crush bucket used for the first step of the CRUSH rule.
+ For instance step take default.</source>
+ <target>O nome do compartimento de crush usado para a primeira etapa da regra CRUSH.
+ Por exemplo, a etapa assumir o padrão.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">80,81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1654284403437084515" datatype="html">
+ <source>Ensure that no two chunks are in a bucket with the same failure
+ domain. For instance, if the failure domain is host no two chunks will be stored on the same
+ host. It is used to create a CRUSH rule step such as step chooseleaf host.</source>
+ <target>Verifique se não há dois pacotes em um compartimento com o mesmo domínio de
+ falha. Por exemplo, se o domínio de falha for um host, não armazene dois pacotes no mesmo
+ host. Isso é usado para criar uma etapa da regra CRUSH, como a etapa de escolha do host folha.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">83,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7737703816676512224" datatype="html">
+ <source>Restrict placement to devices of a specific class
+ (e.g., ssd or hdd), using the crush device class names in the CRUSH map.</source>
+ <target>Restrinja o posicionamento a dispositivos de uma classe específica
+ (ex. ssd ou hdd), usando nomes de classe de dispositivo crush no mapa CRUSH.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9049698214199657456" datatype="html">
+ <source>Set the directory name from which the erasure code plugin is loaded.</source>
+ <target>Defina o nome do diretório do qual o plug-in de código de eliminação é carregado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5514060020564877279" datatype="html">
+ <source>Allows all operations</source>
+ <target>Permite todas as operações</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4265406815683383218" datatype="html">
+ <source>Allows only operations that do not modify the server</source>
+ <target>Permite apenas as operações que não modificam o servidor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="990071930378308183" datatype="html">
+ <source>Allows no access at all</source>
+ <target>Não permite nenhum tipo de acesso</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7286983657616285612" datatype="html">
+ <source>Please specify a filesystem volume.</source>
+ <target>Especifique um volume do sistema de arquivos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8321762156640395170" datatype="html">
+ <source>The feature is disabled because Orchestrator is not available.</source>
+ <target>O recurso foi desabilitado porque o Orchestrator não está disponível.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6718394293315494787" datatype="html">
+ <source>The Orchestrator backend doesn't support this feature.</source>
+ <target>O backend do Orchestrator não é compatível com este recurso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5569418400096331461" datatype="html">
+ <source>-- Select the priority --</source>
+ <target>-- Selecionar prioridade --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="802458941707537739" datatype="html">
+ <source>Low</source>
+ <target>Baixa</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8063651736083474594" datatype="html">
+ <source>High</source>
+ <target>Alta</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1717753935149218245" datatype="html">
+ <source>The user list data might be stale. If needed, you can manually reload it.</source>
+ <target>Os dados da lista de usuários podem estar obsoletos. Se necessário, é possível recarregá-los manualmente.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/list-with-details.class.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7077550143229856452" datatype="html">
+ <source>Retrieving data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>Recuperando dados para <x id="PH" equiv-text="statusFor"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8231424898988217966" datatype="html">
+ <source>Retrieving data.</source>
+ <target>Recuperando dados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2357645764289315007" datatype="html">
+ <source>Please wait...</source>
+ <target>Aguarde...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="232824565824302482" datatype="html">
+ <source>Displaying previously cached data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>Exibindo dados já armazenados em cache para <x id="PH" equiv-text="statusFor"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8721257977793603730" datatype="html">
+ <source>Displaying previously cached data.</source>
+ <target>Exibindo dados já armazenados em cache.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6731313206654246255" datatype="html">
+ <source>Could not load data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>Não foi possível carregar os dados para <x id="PH" equiv-text="statusFor"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3359748695862553898" datatype="html">
+ <source>Could not load data.</source>
+ <target>Não foi possível carregar os dados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4836577225879717660" datatype="html">
+ <source>Please check the cluster health.</source>
+ <target>Verifique a saúde do cluster.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1519954996184640001" datatype="html">
+ <source>Error</source>
+ <target>Erro</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5037437391296624618" datatype="html">
+ <source>Information</source>
+ <target>Informações</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4648900870671159218" datatype="html">
+ <source>Success</source>
+ <target>Êxito</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3425367071066107827" datatype="html">
+ <source>Danger</source>
+ <target>Perigo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c947210e2d162b6225083d18820ab602f58cd2d" datatype="html">
+ <source>Remove the custom configuration value. The default configuration will be inherited and used instead.</source>
+ <target>Remova o valor da configuração personalizada. No lugar dela, a configuração padrão será herdada e usada.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="454ee9cb60b00446a8fb147fd2cc5eb836320586" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>.</source>
+ <target>O valor inserido é muito alto! Ele não deve ser maior do que <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fc8a22825131e028336f60ef909ccbd96059703" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>.</source>
+ <target>O valor inserido é muito baixo! Ele não deve ser menor do que <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4dd200b7f9e19048cf90516843b40964f2af3fe9" datatype="html">
+ <source>Copy to Clipboard</source>
+ <target>Copiar para Área de Transferência</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6110699a3562eeb15371063c0cf7f6bfd88a0209" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>?</source>
+ <target>Deseja realmente <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="549859e511ba5af0ea03fcaa620c472f08038969" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected items?</source>
+ <target>Deseja realmente <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> os itens selecionados?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="54839ebc827b73c9dc4e1df731c6d36a85036af7" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/>?</source>
+ <target>Deseja realmente <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> o(s) <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/> selecionado(s)?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2be8b7f04f0104d3fad90d079d8202b74f758b9a" datatype="html">
+ <source>Yes, I am sure.</source>
+ <target>Sim, desejo.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4523728183000855476" datatype="html">
+ <source>documentation</source>
+ <target>documentação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/doc/doc.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3099741642167775297" datatype="html">
+ <source>Download</source>
+ <target>Fazer Download</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/download-button/download-button.component.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1417693714872528491" datatype="html">
+ <source>This field is required.</source>
+ <target>Este campo é obrigatório.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5321335688371682440" datatype="html">
+ <source>An error occurred.</source>
+ <target>Erro.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5109325fb160b543f71a51e7511c00575057431" datatype="html">
+ <source>Loading panel data...</source>
+ <target>Carregando dados do painel...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a21acde005f80ceadb1391be1e7ff8b6d18188a0" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the monitoring functionality.</source>
+ <target>Consulte <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> sobre como configurar e habilitar a funcionalidade de monitoramento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a0ed4bd7b7add2a6febf7adf58d8cde5e421418" datatype="html">
+ <source>Grafana Dashboard doesn't exist. Please refer to <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to add dashboards to Grafana.</source>
+ <target>O Painel de Controle do Grafana não existe. Consulte <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> sobre como adicionar painéis de controle ao Grafana.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e11830040bd64804a0555de76f291d5832772d4" datatype="html">
+ <source>Grafana Time Picker</source>
+ <target>Seletor de Horário do Grafana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="238c1ba845dd7330e8088165275919a1debf1ca3" datatype="html">
+ <source>Reset Settings</source>
+ <target>Redefinir Configurações</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7888499255176013171" datatype="html">
+ <source>Last 5 minutes</source>
+ <target>Últimos 5 minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6892361549797455305" datatype="html">
+ <source>Last 15 minutes</source>
+ <target>Últimos 15 minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2653641162607195423" datatype="html">
+ <source>Last 30 minutes</source>
+ <target>Últimos 30 minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4117793269024790392" datatype="html">
+ <source>Last 1 hour (Default)</source>
+ <target>Última 1 hora (Padrão)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2645733658763754077" datatype="html">
+ <source>Last 3 hours</source>
+ <target>Últimas 3 horas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7360078715633936807" datatype="html">
+ <source>Last 6 hours</source>
+ <target>Últimas 6 horas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5055313582241816303" datatype="html">
+ <source>Last 12 hours</source>
+ <target>Últimas 12 horas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9186529157286281693" datatype="html">
+ <source>Last 24 hours</source>
+ <target>Últimas 24 horas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4498682414491138092" datatype="html">
+ <source>Yesterday</source>
+ <target>Ontem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="929003859318769922" datatype="html">
+ <source>Today so far</source>
+ <target>Até agora hoje</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5525943133564968818" datatype="html">
+ <source>Day before yesterday</source>
+ <target>Antes de ontem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6168755117727892817" datatype="html">
+ <source>Last 2 days</source>
+ <target>Últimos 2 dias</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7574807704224200535" datatype="html">
+ <source>This day last week</source>
+ <target>Este dia na semana passada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4420128118950221234" datatype="html">
+ <source>Previous week</source>
+ <target>Semana anterior</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4063965603321223683" datatype="html">
+ <source>This week so far</source>
+ <target>Até agora nesta semana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4873149362496451858" datatype="html">
+ <source>Last 7 days</source>
+ <target>Últimos 7 dias</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8586908745456864217" datatype="html">
+ <source>Previous month</source>
+ <target>Mês anterior</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1647573304710886499" datatype="html">
+ <source>This month so far</source>
+ <target>Até agora neste mês</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2949150997160654358" datatype="html">
+ <source>Last 30 days</source>
+ <target>Últimos 30 dias</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7469939859049484736" datatype="html">
+ <source>Last 90 days</source>
+ <target>Últimos 90 dias</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847501198811458781" datatype="html">
+ <source>Last 6 months</source>
+ <target>Últimos 6 meses</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7447583558445881102" datatype="html">
+ <source>Last 1 year</source>
+ <target>Último ano</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="100513227838842152" datatype="html">
+ <source>Previous year</source>
+ <target>Ano anterior</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3650872673621947074" datatype="html">
+ <source>This year so far</source>
+ <target>Até agora neste ano</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1262816694819959075" datatype="html">
+ <source>Last 2 years</source>
+ <target>Últimos 2 anos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7878813844917362690" datatype="html">
+ <source>Last 5 years</source>
+ <target>Últimos 5 anos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3fb5709e10166cbc85970cbff103db227dbeb813" datatype="html">
+ <source>Select a Language</source>
+ <target>Selecionar Idioma</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/language-selector/language-selector.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e52e9143145e1db5146258de81eae018a407b31" datatype="html">
+ <source>Clear notifications</source>
+ <target>Limpar notificações</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0b07bb6b7ff21ede439dd04eaf8872d1ecb84d8" datatype="html">
+ <source>Remove notification</source>
+ <target>Remover notificação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e17a1d75189da843f541f7764f188f2b19a97df2" datatype="html">
+ <source>Duration:</source>
+ <target>Duração:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d4b37c6675c5b436a54c43d6716eec835e1aa7f" datatype="html">
+ <source>There are no notifications.</source>
+ <target>Não há notificações.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b20e42ac4354d449f2718428b5390933eef0c1b9" datatype="html">
+ <source>The feature is not supported in the current Orchestrator.</source>
+ <target>O recurso não é compatível com o Orchestrator atual.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a437b8f93cf826817c04a4277edb1ae3a93a1ab" datatype="html">
+ <source>Orchestrator is not available. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the functionality.</source>
+ <target>O Orchestrator não está disponível. Consulte <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> sobre como configurar e habilitar a funcionalidade.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">7,9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20b3d45b0c08a2951a9974fa20505e4de95250c9" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>less than 1<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day. Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <target>Sua senha expira em <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>menos de 1<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> dia. Clique <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>aqui<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> para alterá-la agora.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">9,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f34088c155e40ffb23770a465a65868ce772b2" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day(s). Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <target>Sua senha expira em <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> dia(s). Clique <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>aqui<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> para alterá-la agora.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8d1785038d461ec66b5799db21864182b35900a" datatype="html">
+ <source>Refresh</source>
+ <target>Atualizar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/refresh-selector/refresh-selector.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3417247046175131869" datatype="html">
+ <source>No items selected.</source>
+ <target>Nenhum item selecionado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1034353870189672674" datatype="html">
+ <source>Deselect item to select again</source>
+ <target>Desmarcar item para selecionar novamente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4879298070255432995" datatype="html">
+ <source>Selection limit reached</source>
+ <target>Limite de seleção atingido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001227209911602786" datatype="html">
+ <source>Filter tags</source>
+ <target>Tags de filtro</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="791789583719406586" datatype="html">
+ <source>Add badge</source>
+ <target>Adicionar selo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="699988676752930063" datatype="html">
+ <source>There are no items available.</source>
+ <target>Não há itens disponíveis.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6702323d3760e3db0e2e785d567469d18beb120" datatype="html">
+ <source>The Ceph community needs your help to continue improving: please <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>Activate<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> the <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Telemetry<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> module.</source>
+ <target>A comunidade do Ceph precisa da sua ajuda para continuar fazendo melhorias: <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>Ative<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> o módulo <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Telemetria<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.html</context>
+ <context context-type="linenumber">8,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8770134622386151776" datatype="html">
+ <source>Telemetry activation reminder muted</source>
+ <target>Lembrete de ativação da telemetria sem som</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8352450862052130357" datatype="html">
+ <source>You can activate the module on the Telemetry configuration page (&lt;b&gt;Dashboard Settings&lt;/b&gt; -&gt; &lt;b&gt;Telemetry configuration&lt;/b&gt;) at any time.</source>
+ <target>Você pode ativar o módulo na página Configuração de telemetria (&lt;b&gt;Configurações do Painel de Controle&lt;/b&gt; -&gt; &lt;b&gt;Configuração de telemetria&lt;/b&gt;) a qualquer momento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bc9e5365a581105ce37cf47d1d74e4ad9eb75ce" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e634c306cab9e8879c3392593714c1ceab85437d" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3249513483374643425" datatype="html">
+ <source>Add</source>
+ <target>Adicionar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4359847060009771702" datatype="html">
+ <source>Set</source>
+ <target>Definir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935187492052582731" datatype="html">
+ <source>Submit</source>
+ <target>Enviar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4814285799071780083" datatype="html">
+ <source>Remove</source>
+ <target>Remover</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8363450564548681668" datatype="html">
+ <source>Unset</source>
+ <target>Não definir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2159130950882492111" datatype="html">
+ <source>Cancel</source>
+ <target>Cancelar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1295614462098694869" datatype="html">
+ <source>Preview</source>
+ <target>Visualização</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2354817630223808522" datatype="html">
+ <source>Move</source>
+ <target>Mover</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3885497195825665706" datatype="html">
+ <source>Next</source>
+ <target>Avançar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8890553633144307762" datatype="html">
+ <source>Back</source>
+ <target>Voltar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5834780181397311898" datatype="html">
+ <source>Clone</source>
+ <target>Clonar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4323470180912194028" datatype="html">
+ <source>Copy</source>
+ <target>Copiar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2131301778880826094" datatype="html">
+ <source>Deep Scrub</source>
+ <target>Remoção Profunda</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1704447209800801558" datatype="html">
+ <source>Destroy</source>
+ <target>Destruir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8343007008325027187" datatype="html">
+ <source>Evict</source>
+ <target>Expulsar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="408179081163888126" datatype="html">
+ <source>Flatten</source>
+ <target>Nivelar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="318900679147387932" datatype="html">
+ <source>Mark Down</source>
+ <target>Marcar como Inativo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5275142643521766706" datatype="html">
+ <source>Mark In</source>
+ <target>Marcar como Entrada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6973272903386150199" datatype="html">
+ <source>Mark Lost</source>
+ <target>Marcar como Perdido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1962653792210847411" datatype="html">
+ <source>Mark Out</source>
+ <target>Marcar como Saída</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4424610588915076517" datatype="html">
+ <source>Protect</source>
+ <target>Proteger</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6041115344061899387" datatype="html">
+ <source>Rename</source>
+ <target>Renomear</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">164</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6770769801335635194" datatype="html">
+ <source>Restore</source>
+ <target>Restaurar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2003230525878010676" datatype="html">
+ <source>Reweight</source>
+ <target>Reponderar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5430834128563178593" datatype="html">
+ <source>Scrub</source>
+ <target>Remoção</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8461842260159597706" datatype="html">
+ <source>Show</source>
+ <target>Mostrar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5655608100705734230" datatype="html">
+ <source>Move to Trash</source>
+ <target>Mover para Lixo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4622393909937403117" datatype="html">
+ <source>Unprotect</source>
+ <target>Cancelar proteção</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1230154438678955604" datatype="html">
+ <source>Change</source>
+ <target>Alterar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8450843381175865415" datatype="html">
+ <source>Enter Maintenance</source>
+ <target>Entrar em Manutenção</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1610181371597502589" datatype="html">
+ <source>Exit Maintenance</source>
+ <target>Sair da Manutenção</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="676511611419004737" datatype="html">
+ <source>Start Drain</source>
+ <target>Iniciar Drenagem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7170653322511987983" datatype="html">
+ <source>Stop Drain</source>
+ <target>Parar Drenagem</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5528551262937858942" datatype="html">
+ <source>Recreate</source>
+ <target>Recriar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2502364444688691031" datatype="html">
+ <source>Expire</source>
+ <target>Expirar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6381490568322624964" datatype="html">
+ <source>Deleted</source>
+ <target>Excluído</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="231679111972850796" datatype="html">
+ <source>Added</source>
+ <target>Adicionado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5406093358072761930" datatype="html">
+ <source>Removed</source>
+ <target>Removido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3008573030448240863" datatype="html">
+ <source>Edited</source>
+ <target>Editado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4381944803872489731" datatype="html">
+ <source>Canceled</source>
+ <target>Cancelado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754993936947658096" datatype="html">
+ <source>Previewed</source>
+ <target>Visualizado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6001163963116907226" datatype="html">
+ <source>Moved</source>
+ <target>Movido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4932744777596632840" datatype="html">
+ <source>Cloned</source>
+ <target>Clonado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2115592966120408375" datatype="html">
+ <source>Copied</source>
+ <target>Copiado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7937474560394832586" datatype="html">
+ <source>Deep Scrubbed</source>
+ <target>Removido Profundamente</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6321562733889197649" datatype="html">
+ <source>Destroyed</source>
+ <target>Destruído</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7460162290177581995" datatype="html">
+ <source>Flattened</source>
+ <target>Nivelado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3662010055028969035" datatype="html">
+ <source>Marked Down</source>
+ <target>Marcado como Inativo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5880434235404894589" datatype="html">
+ <source>Marked In</source>
+ <target>Marcado como Entrada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="266997194072682078" datatype="html">
+ <source>Marked Lost</source>
+ <target>Marcado como Perdido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">250</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4010544044592534535" datatype="html">
+ <source>Marked Out</source>
+ <target>Marcado como Saída</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4776304093333411035" datatype="html">
+ <source>Protected</source>
+ <target>Protegido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2700903921419382511" datatype="html">
+ <source>Purged</source>
+ <target>Purgado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5488667333459350160" datatype="html">
+ <source>Renamed</source>
+ <target>Renomeado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8044659850000829751" datatype="html">
+ <source>Restored</source>
+ <target>Restaurado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559472082694466366" datatype="html">
+ <source>Reweighted</source>
+ <target>Reponderado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022271525067453676" datatype="html">
+ <source>Rolled back</source>
+ <target>Rollback feito</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2483217756816388123" datatype="html">
+ <source>Scrubbed</source>
+ <target>Removido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7200036055090632378" datatype="html">
+ <source>Showed</source>
+ <target>Exibido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7609648817347881129" datatype="html">
+ <source>Moved to Trash</source>
+ <target>Movido para Lixeira</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7810326403606456469" datatype="html">
+ <source>Unprotected</source>
+ <target>Desprotegido</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5620774899056099259" datatype="html">
+ <source>Recreated</source>
+ <target>Recriado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464749780222721589" datatype="html">
+ <source>Expired</source>
+ <target>Expirado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">266</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e5e23363e949f7dcbaf034bdb141a561132a10e" datatype="html">
+ <source>Clear filters</source>
+ <target>Limpar filtros</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80cc9a12d4bf6fe454ed94b379eeaf915f920bb7" datatype="html">
+ <source>selected</source>
+ <target>selecionado(s)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <note priority="1" from="description">X selected</note>
+ </trans-unit>
+ <trans-unit id="0cb77511a9a148e05b9adf36cc07269956fbb29d" datatype="html">
+ <source>found</source>
+ <target>encontrado(s)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <note priority="1" from="description">X found</note>
+ </trans-unit>
+ <trans-unit id="79347388740c50b7ac97e144c2494bb62912f312" datatype="html">
+ <source>total</source>
+ <target>total</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <note priority="1" from="description">X total</note>
+ </trans-unit>
+ <trans-unit id="2a3dab422cc892db037db8632bb84a6bf496e2d1" datatype="html">
+ <source>Expand/Collapse Row</source>
+ <target>Expandir/Recolher Linha</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4047162422391207122" datatype="html">
+ <source>Failed to load data.</source>
+ <target>Falha ao carregar dados.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.ts</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="709331713250198508" datatype="html">
+ <source>Loading form data...</source>
+ <target>Carregando dados do formulário...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3850344644863430180" datatype="html">
+ <source>Form data could not be loaded.</source>
+ <target>Não foi possível carregar os dados do formulário.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4626760504772708998" datatype="html">
+ <source>Size has to be at least <x id="PH" equiv-text="value"/> or more</source>
+ <target>O tamanho deve ser no mínimo <x id="PH" equiv-text="value"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">428</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2880361802894657892" datatype="html">
+ <source>Size has to be at most <x id="PH" equiv-text="value"/> or less</source>
+ <target>O tamanho deve ser no máximo <x id="PH" equiv-text="value"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2807800733729323332" datatype="html">
+ <source>Yes</source>
+ <target>Sim</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3542042671420335679" datatype="html">
+ <source>No</source>
+ <target>Não</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7789266940050748913" datatype="html">
+ <source>in %s</source>
+ <target>em %s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565573880632900017" datatype="html">
+ <source>%s ago</source>
+ <target>%s atrás</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="220300059326988179" datatype="html">
+ <source>a few seconds</source>
+ <target>alguns segundos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2761143993878941513" datatype="html">
+ <source>%d seconds</source>
+ <target>%d segundos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7094767962693903153" datatype="html">
+ <source>a minute</source>
+ <target>um minuto</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7597613755904774250" datatype="html">
+ <source>%d minutes</source>
+ <target>%d minutos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2757762976030115752" datatype="html">
+ <source>an hour</source>
+ <target>uma hora</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9118454901758656303" datatype="html">
+ <source>%d hours</source>
+ <target>%d horas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7435193742089920080" datatype="html">
+ <source>a day</source>
+ <target>um dia</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1821334622562842480" datatype="html">
+ <source>%d days</source>
+ <target>%d dias</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7375306199026780379" datatype="html">
+ <source>a week</source>
+ <target>uma semana</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7272688256541915488" datatype="html">
+ <source>%d weeks</source>
+ <target>%d semanas</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5761124614324704118" datatype="html">
+ <source>a month</source>
+ <target>um mês</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="352195662913351589" datatype="html">
+ <source>%d months</source>
+ <target>%d meses</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7562153591649199139" datatype="html">
+ <source>a year</source>
+ <target>um ano</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5424759741855527370" datatype="html">
+ <source>%d years</source>
+ <target>%d anos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7738182956549158907" datatype="html">
+ <source>Required rules for passwords:</source>
+ <target>Regras exigidas para senhas:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8839765875053270528" datatype="html">
+ <source>Must contain at least <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> characters</source>
+ <target>Deve conter no mínimo <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> caracteres</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3098731108593590794" datatype="html">
+ <source>Must not be the same as the previous one</source>
+ <target>Não deve ser igual à anterior</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9150236741862848105" datatype="html">
+ <source>Cannot contain the username</source>
+ <target>Não pode conter o nome de usuário</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6395043854518867543" datatype="html">
+ <source>Cannot contain any configured keyword</source>
+ <target>Não pode conter nenhuma palavra-chave configurada</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="907558624910601703" datatype="html">
+ <source>Cannot contain any repetitive characters e.g. &quot;aaa&quot;</source>
+ <target>Não pode conter caracteres repetidos, por exemplo, &quot;aaa&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514384270734082343" datatype="html">
+ <source>Cannot contain any sequential characters e.g. &quot;abc&quot;</source>
+ <target>Não pode conter caracteres sequenciais, por exemplo, &quot;abc&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4119354814383293871" datatype="html">
+ <source>Must consist of characters from the following groups:
+ * Alphabetic a-z, A-Z
+ * Numbers 0-9
+ * Special chars: !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * Any other characters (signs)</source>
+ <target>Deve consistir em caracteres dos seguintes grupos:
+ * Alfabeto a-z, A-Z
+ * Números 0-9
+ * Caracteres especiais: !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * Qualquer outro caractere (sinais)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">30,34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8649061117624699581" datatype="html">
+ <source>Your matcher seems to match no currently defined rule or active alert.</source>
+ <target>Sua correspondência não parece seguir nenhuma regra definida ou alerta ativo no momento.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7122912874364762704" datatype="html">
+ <source>no active alerts</source>
+ <target>sem alertas ativos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7388215679576832341" datatype="html">
+ <source>1 active alert</source>
+ <target>1 alerta ativo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3112400568960537267" datatype="html">
+ <source><x id="PH" equiv-text="alerts"/> active alerts</source>
+ <target><x id="PH" equiv-text="alerts"/> alertas ativos</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6264717417287230743" datatype="html">
+ <source>Matches 1 rule</source>
+ <target>Segue 1 regra</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054663176394183966" datatype="html">
+ <source>Matches <x id="PH" equiv-text="rules"/> rules</source>
+ <target>Corresponde a <x id="PH" equiv-text="rules"/> regras</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6674225401121099210" datatype="html">
+ <source><x id="PH" equiv-text="rule"/> with <x id="PH_1" equiv-text="alert"/>.</source>
+ <target><x id="PH" equiv-text="rule"/> com <x id="PH_1" equiv-text="alert"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5659908877047925719" datatype="html">
+ <source>Quality of Service</source>
+ <target>Qualidade do Serviço</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1277565045885499475" datatype="html">
+ <source>BPS Limit</source>
+ <target>Limite de BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2289210323987692906" datatype="html">
+ <source>The desired limit of IO bytes per second.</source>
+ <target>O limite de bytes por segundo de E/S desejado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753589939879013605" datatype="html">
+ <source>IOPS Limit</source>
+ <target>Limite de IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2213985059444278522" datatype="html">
+ <source>The desired limit of IO operations per second.</source>
+ <target>O limite de operações por segundo de E/S desejado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2487530611825582289" datatype="html">
+ <source>Read BPS Limit</source>
+ <target>Limite de BPS de Leitura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8071352270469595250" datatype="html">
+ <source>The desired limit of read bytes per second.</source>
+ <target>O limite de bytes por segundo de leitura desejado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1632513758247239690" datatype="html">
+ <source>Read IOPS Limit</source>
+ <target>Limite de IOPS de Leitura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2361786794607418566" datatype="html">
+ <source>The desired limit of read operations per second.</source>
+ <target>O limite de operações por segundo de leitura desejado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="894600353504285551" datatype="html">
+ <source>Write BPS Limit</source>
+ <target>Limite de BPS de Gravação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911437671369366025" datatype="html">
+ <source>The desired limit of write bytes per second.</source>
+ <target>O limite de bytes por segundo de gravação desejado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2947346368707443195" datatype="html">
+ <source>Write IOPS Limit</source>
+ <target>Limite de IOPS de Gravação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5506349527983391356" datatype="html">
+ <source>The desired limit of write operations per second.</source>
+ <target>O limite de operações por segundo de gravação desejado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559424229658244943" datatype="html">
+ <source>BPS Burst</source>
+ <target>Intermitência de BPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3454058701331860330" datatype="html">
+ <source>The desired burst limit of IO bytes.</source>
+ <target>O limite de bytes de E/S de intermitência desejado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171005761926448741" datatype="html">
+ <source>IOPS Burst</source>
+ <target>Intermitência de IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4939532784700485729" datatype="html">
+ <source>The desired burst limit of IO operations.</source>
+ <target>O limite de operações de E/S de intermitência desejado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6273492199526646930" datatype="html">
+ <source>Read BPS Burst</source>
+ <target>Intermitência de BPS de Leitura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3105467595643777520" datatype="html">
+ <source>The desired burst limit of read bytes.</source>
+ <target>O limite de bytes de leitura de intermitência desejado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2170715106679765467" datatype="html">
+ <source>Read IOPS Burst</source>
+ <target>Intermitência de IOPS de Leitura</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6234106755510510672" datatype="html">
+ <source>The desired burst limit of read operations.</source>
+ <target>O limite de operações de leitura de intermitência desejado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="228509518172572466" datatype="html">
+ <source>Write BPS Burst</source>
+ <target>Intermitência de BPS de Gravação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7803279807796571240" datatype="html">
+ <source>The desired burst limit of write bytes.</source>
+ <target>O limite de bytes de gravação de intermitência desejado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9125474584914848055" datatype="html">
+ <source>Write IOPS Burst</source>
+ <target>Intermitência de IOPS de Gravação</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5839129348567326667" datatype="html">
+ <source>The desired burst limit of write operations.</source>
+ <target>O limite de operações de gravação de intermitência desejado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="614961883076556986" datatype="html">
+ <source>Failed to <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></source>
+ <target>Falha ao <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="489145301781720653" datatype="html">
+ <source>Executing</source>
+ <target>Executando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4238828029954346941" datatype="html">
+ <source>execute</source>
+ <target>executar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7196604637389554584" datatype="html">
+ <source>Executed</source>
+ <target>Executado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4418441687454700644" datatype="html">
+ <source>unknown task</source>
+ <target>tarefa desconhecida</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8667665916832796867" datatype="html">
+ <source>Creating</source>
+ <target>Criando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6031236679730054907" datatype="html">
+ <source>create</source>
+ <target>criar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5593033420216313122" datatype="html">
+ <source>Updating</source>
+ <target>Atualizando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6100869651653026893" datatype="html">
+ <source>update</source>
+ <target>atualizar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3141301060598402455" datatype="html">
+ <source>Deleting</source>
+ <target>Excluindo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3420504288275541125" datatype="html">
+ <source>Adding</source>
+ <target>Adicionando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1059784693423848532" datatype="html">
+ <source>add</source>
+ <target>adicionar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594819887188505274" datatype="html">
+ <source>Removing</source>
+ <target>Removendo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2123171795960509943" datatype="html">
+ <source>remove</source>
+ <target>remover</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1946427188770321847" datatype="html">
+ <source>Importing</source>
+ <target>Importando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8495827411619139669" datatype="html">
+ <source>import</source>
+ <target>importar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218459863491436562" datatype="html">
+ <source>Imported</source>
+ <target>Importado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6534993668932538712" datatype="html">
+ <source>RBD '<x id="PH" equiv-text="metadata.image_spec"/>'</source>
+ <target>RBD '<x id="PH" equiv-text="metadata.image_spec"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8237287859948228705" datatype="html">
+ <source>RBD snapshot '<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>'</source>
+ <target>Instantâneo do RBD '<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2328067975897167268" datatype="html">
+ <source>mirroring site name</source>
+ <target>espelhando nome do site</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4433460322631470833" datatype="html">
+ <source>bootstrap token</source>
+ <target>token de boot</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7044591639782280183" datatype="html">
+ <source>mirror mode for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>modo de espelho do pool '<x id="PH" equiv-text="metadata.pool_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7109746474198366468" datatype="html">
+ <source>mirror peer for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>peer de espelho do pool '<x id="PH" equiv-text="metadata.pool_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6201476020617351396" datatype="html">
+ <source>all dashboards</source>
+ <target>todos os painéis de controle</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7268953097700363232" datatype="html">
+ <source>Identifying</source>
+ <target>Identificando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4337678035264231187" datatype="html">
+ <source>identify</source>
+ <target>identificar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7257219307556106552" datatype="html">
+ <source>Identified</source>
+ <target>Identificado</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6002370161381995023" datatype="html">
+ <source>device '<x id="PH" equiv-text="metadata.device"/>' on host '<x id="PH_1" equiv-text="metadata.hostname"/>'</source>
+ <target>dispositivo '<x id="PH" equiv-text="metadata.device"/>' no host '<x id="PH_1" equiv-text="metadata.hostname"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5580298273054260850" datatype="html">
+ <source>OSDs (DriveGroups: <x id="PH" equiv-text="metadata.tracking_id"/>)</source>
+ <target>OSDs (DriveGroups: <x id="PH" equiv-text="metadata.tracking_id"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2182125722527364040" datatype="html">
+ <source>Name is already used by <x id="PH" equiv-text="this.pool(metadata)"/>.</source>
+ <target>Nome já está em uso por <x id="PH" equiv-text="this.pool(metadata)"/>.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">182</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7892856315477304281" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> is busy.</source>
+ <target><x id="PH" equiv-text="this.rbd.default(metadata)"/> está ocupado.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4690045751984117407" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> contains snapshots.</source>
+ <target><x id="PH" equiv-text="this.rbd.default(metadata)"/> contém instantâneos.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="562148565853868662" datatype="html">
+ <source>Cloning</source>
+ <target>Clonando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1197352830433807469" datatype="html">
+ <source>clone</source>
+ <target>clonar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1692004144561317867" datatype="html">
+ <source>Snapshot of <x id="PH" equiv-text="this.rbd.child(metadata)"/> must be protected.</source>
+ <target>Instantâneo de <x id="PH" equiv-text="this.rbd.child(metadata)"/> deve ser protegido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8531200838331320284" datatype="html">
+ <source>Copying</source>
+ <target>Copiando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6862265996781523030" datatype="html">
+ <source>copy</source>
+ <target>copiar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3556912098733712857" datatype="html">
+ <source>Flattening</source>
+ <target>Nivelando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2488773646187451754" datatype="html">
+ <source>flatten</source>
+ <target>nivelar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="704305783678486635" datatype="html">
+ <source>Cannot unprotect <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> because it contains child images.</source>
+ <target>Impossível cancelar a proteção de <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> porque há imagens filho.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">223,225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101271773452792348" datatype="html">
+ <source>Cannot delete <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/> because it's protected.</source>
+ <target>Impossível excluir <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/> porque está protegido.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5143010940199748580" datatype="html">
+ <source>Rolling back</source>
+ <target>Fazendo rollback</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1315686250907089544" datatype="html">
+ <source>rollback</source>
+ <target>rollback</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5010267418211867946" datatype="html">
+ <source>Moving</source>
+ <target>Movendo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4366763205960752449" datatype="html">
+ <source>move</source>
+ <target>mover</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="695867152524584829" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_spec"/>' to trash</source>
+ <target>imagem '<x id="PH" equiv-text="metadata.image_spec"/>' para jogar no lixo</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423442774536615202" datatype="html">
+ <source>Could not find image.</source>
+ <target>Imagem não encontrada.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2622324641113512527" datatype="html">
+ <source>Restoring</source>
+ <target>Restaurando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3347932678307141902" datatype="html">
+ <source>restore</source>
+ <target>restaurar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7488038030362249932" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>' into '<x id="PH_1" equiv-text="metadata.new_image_name"/>'</source>
+ <target>imagem '<x id="PH" equiv-text="metadata.image_id_spec"/>' para '<x id="PH_1" equiv-text="metadata.new_image_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565688512490959949" datatype="html">
+ <source>Image name '<x id="PH" equiv-text="metadata.new_image_name"/>' is already in use.</source>
+ <target>Nome da imagem '<x id="PH" equiv-text="metadata.new_image_name"/>' já está em uso.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6331051389974655106" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>'</source>
+ <target>imagem '<x id="PH" equiv-text="metadata.image_id_spec"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8245559899946787147" datatype="html">
+ <source>Purging</source>
+ <target>Purgando</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7879437654311684252" datatype="html">
+ <source>purge</source>
+ <target>purgar</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1440427157062670480" datatype="html">
+ <source>all pools</source>
+ <target>todos os pools</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8677740163708263843" datatype="html">
+ <source>images from <x id="PH" equiv-text="message"/></source>
+ <target>imagens de <x id="PH" equiv-text="message"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011237345035114219" datatype="html">
+ <source>Cannot disable mirroring because it contains a peer.</source>
+ <target>Impossível desabilitar espelhamento porque ele contém um peer.</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">292</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7391584598242145869" datatype="html">
+ <source>host '<x id="PH" equiv-text="metadata.hostname"/>'</source>
+ <target>host '<x id="PH" equiv-text="metadata.hostname"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6964302691596180722" datatype="html">
+ <source>OSD '<x id="PH" equiv-text="metadata.svc_id"/>'</source>
+ <target>OSD '<x id="PH" equiv-text="metadata.svc_id"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="488305686602466689" datatype="html">
+ <source>pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>pool '<x id="PH" equiv-text="metadata.pool_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5921392748828575278" datatype="html">
+ <source>erasure code profile '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <target>perfil de código de eliminação '<x id="PH" equiv-text="metadata.name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2423915105798557698" datatype="html">
+ <source>crush rule '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <target>regra de crush '<x id="PH" equiv-text="metadata.name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">370</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8273044996643438592" datatype="html">
+ <source>target '<x id="PH" equiv-text="metadata.target_iqn"/>'</source>
+ <target>destino '<x id="PH" equiv-text="metadata.target_iqn"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5474643443735437364" datatype="html">
+ <source>NFS '<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>'</source>
+ <target>NFS '<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">378,380</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2235495382025026939" datatype="html">
+ <source>Service '<x id="PH" equiv-text="metadata.service_name"/>'</source>
+ <target>Serviço '<x id="PH" equiv-text="metadata.service_name"/>'</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ </body>
+ </file>
+</xliff> \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.zh-CN.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.zh-CN.xlf
new file mode 100644
index 000000000..ae98e3770
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.zh-CN.xlf
@@ -0,0 +1,14881 @@
+<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en-US" datatype="plaintext" original="ng2.template" target-language="zh-CN">
+ <body>
+ <trans-unit id="ngb.alert.close" datatype="html">
+ <source>Close</source>
+ <target>关闭</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/alert/alert.ts</context>
+ <context context-type="linenumber">58,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.slide-number" datatype="html">
+ <source> Slide <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> of <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </source>
+ <target> 第 <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> 页(共 <x id="INTERPOLATION_1" equiv-text="; private _pa"/> 页) </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">114,118</context>
+ </context-group>
+ <note priority="1" from="description">Currently selected slide number read by screen reader</note>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.previous" datatype="html">
+ <source>Previous</source>
+ <target>上一页</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">132,134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.next" datatype="html">
+ <source>Next</source>
+ <target>下一页</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">147,152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-month" datatype="html">
+ <source>Select month</source>
+ <target>选择月份</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">44,49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">49,50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-year" datatype="html">
+ <source>Select year</source>
+ <target>选择年份</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">59,63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.previous-month" datatype="html">
+ <source>Previous month</source>
+ <target>上个月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">24,27</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">35,36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.next-month" datatype="html">
+ <source>Next month</source>
+ <target>下月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">47,50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">60,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first" datatype="html">
+ <source>««</source>
+ <target>««</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">182,183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous" datatype="html">
+ <source>«</source>
+ <target>«</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">186,190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next" datatype="html">
+ <source>»</source>
+ <target>»</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">194,195</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last" datatype="html">
+ <source>»»</source>
+ <target>»»</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">201,204</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first-aria" datatype="html">
+ <source>First</source>
+ <target>第一页</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">208,209</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous-aria" datatype="html">
+ <source>Previous</source>
+ <target>上一页</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">215,216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next-aria" datatype="html">
+ <source>Next</source>
+ <target>下一页</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">226,228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last-aria" datatype="html">
+ <source>Last</source>
+ <target>最后一页</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.progressbar.value" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="; } /** *"/></source>
+ <target><x id="INTERPOLATION" equiv-text="; } /** *"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/progressbar/progressbar.ts</context>
+ <context context-type="linenumber">32,38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.HH" datatype="html">
+ <source>HH</source>
+ <target>HH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">40,41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.hours" datatype="html">
+ <source>Hours</source>
+ <target>小时</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.MM" datatype="html">
+ <source>MM</source>
+ <target>MM</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">51,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.minutes" datatype="html">
+ <source>Minutes</source>
+ <target>分钟</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-hours" datatype="html">
+ <source>Increment hours</source>
+ <target>递增小时数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">63,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-hours" datatype="html">
+ <source>Decrement hours</source>
+ <target>递减小时数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">69,70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-minutes" datatype="html">
+ <source>Increment minutes</source>
+ <target>递增分钟数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">76,78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-minutes" datatype="html">
+ <source>Decrement minutes</source>
+ <target>递减分钟数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">82,84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.SS" datatype="html">
+ <source>SS</source>
+ <target>SS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.seconds" datatype="html">
+ <source>Seconds</source>
+ <target>秒</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">92,93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-seconds" datatype="html">
+ <source>Increment seconds</source>
+ <target>递增秒数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">100,101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-seconds" datatype="html">
+ <source>Decrement seconds</source>
+ <target>递减秒数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">106,110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.AM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></source>
+ <target><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">115,121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.PM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="t() meridian: b"/></source>
+ <target><x id="INTERPOLATION" equiv-text="t() meridian: b"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">123,131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.toast.close-aria" datatype="html">
+ <source>Close</source>
+ <target>关闭</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/toast/toast.ts</context>
+ <context context-type="linenumber">78,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8835b9e49a3348b0a2f2162c21118af1f4bee45a" datatype="html">
+ <source>Must be greater than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>.</source>
+ <target>必须大于或等于 <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbddac59563c8c126e3fe28691e4e247614fcbd1" datatype="html">
+ <source>Must be less than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>.</source>
+ <target>必须小于或等于 <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5" datatype="html">
+ <source>Overview</source>
+ <target>概览</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbd2045d5c37e4bb39a3c0fb62ea1ddf70a12838" datatype="html">
+ <source>Targets</source>
+ <target>目标</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a674ab267d1934bf395f87ca1503fd474296893f" datatype="html">
+ <source>iSCSI Topology</source>
+ <target>iSCSI 结构图</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8953033926734869941" datatype="html">
+ <source>Name</source>
+ <target>名称</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6603000223840533819" datatype="html">
+ <source>Current</source>
+ <target>当前</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5607669932062416162" datatype="html">
+ <source>Default</source>
+ <target>默认值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6803e31b7395d94934e091a49a9524026b59b018" datatype="html">
+ <source>Discovery Authentication</source>
+ <target>发现身份验证</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e08a77594f3d89311cdf6da5090044270909c194" datatype="html">
+ <source>User</source>
+ <target>用户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">381</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7cbdabcece469fab89cfa687ab152bca18b97498" datatype="html">
+ <source>This field is required.</source>
+ <target>这是必填字段!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">368</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">423</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">481</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">291</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">343</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">407</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">490</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">516</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">556</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">573</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">590</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">647</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">672</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">299</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">195</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">520</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">614</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">651</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f717bad2da5944a2567a52f971ccc6806db85805" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>用户名长度必须为 8 至 64 个字符,可以包含字母数字字符、&quot;.&quot;、&quot;@&quot;、&quot;-&quot;、&quot;_&quot; 或 &quot;:&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">28,29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">85,86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c32ef07f8803a223a83ed17024b38e8d82292407" datatype="html">
+ <source>Password</source>
+ <target>密码</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">403</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">581</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="001e1836299d8d3b84eaebe2fa051325beab3f00" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>密码长度必须为 12 至 16 个字符,可以包含字母数字字符、&quot;@&quot;、&quot;-&quot;、&quot;_&quot; 或 &quot;/&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">61,62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">118,119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff40391de7a1944ea95091e4045cc34c4979b736" datatype="html">
+ <source>Mutual User</source>
+ <target>互认证用户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cf73dbebe99b737c4d288788182fc356e3c93d3" datatype="html">
+ <source>Mutual Password</source>
+ <target>互认证密码</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594987303599690088" datatype="html">
+ <source>Updated discovery authentication</source>
+ <target>已更新发现身份验证</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb127ea03835b3230f0ed981c7080e2ccb879621" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <note priority="1" from="description">form title</note>
+ </trans-unit>
+ <trans-unit id="1406c2fb12a20c1528b19bcc5e24a6a2386167f3" datatype="html">
+ <source>Target IQN</source>
+ <target>目标 IQN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5fe42339be910372fa689f559155631862d218e8" datatype="html">
+ <source>IQN has wrong pattern.</source>
+ <target>IQN 格式错误。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="050a7ff057d1e895357540406b6be5652b4d1c71" datatype="html">
+ <source>An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'</source>
+ <target>IQN 应由以下格式构成:“iqn.$year-$month.$reversedAddress:$definedName”</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8ada4b53396d8366db00a435acc61d53d857047" datatype="html">
+ <source>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</source>
+ <target>例如:iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e" datatype="html">
+ <source>More information</source>
+ <target>更多信息</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9b1aa85dfc6849196e64060db02c5410de69b7a1" datatype="html">
+ <source>This target has modified advanced settings.</source>
+ <target>此目标的高级设置修改过。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6990ad8d6182662e864495ac31c3758cda1c7a28" datatype="html">
+ <source>Portals</source>
+ <target>端口</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a3ac2b4137d723fd9878cd357c2012ff6c07973" datatype="html">
+ <source>Add portal</source>
+ <target>添加端口</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3638c01b6c34066438909713ec96087c813fc7e" datatype="html">
+ <source>At least <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> gateways are required.</source>
+ <target>至少需要 <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> 个网关。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b73f7f5060fb22a1e9ec462b1bb02493fa3ab866" datatype="html">
+ <source>Images</source>
+ <target>映像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">495</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">629</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9aff25be088f0efe3eaaf62edf2bff41cc41a617" datatype="html">
+ <source>Backstore: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </source>
+ <target>后备存储:<x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e3484cae8b118c576ca2815bf9c9406c2eb2cae3" datatype="html">
+ <source>This image has modified settings.</source>
+ <target>此映像的设置修改过。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1dff11e0820b6722ab240169f1232d70a54beaaa" datatype="html">
+ <source>Duplicated LUN numbers.</source>
+ <target>重复的 LUN 编号。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bf2dccf92ccff6e3b091792bf4205595406e1bfb" datatype="html">
+ <source>Duplicated WWN.</source>
+ <target>重复的 WWN。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="808038f912fdc7f0e03f82d4afd3bf9178527fc8" datatype="html">
+ <source>Add image</source>
+ <target>添加映像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">656</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66c5fb27f52e75b70ca4b670b9b15a2a51cf9543" datatype="html">
+ <source>ACL authentication</source>
+ <target>ACL 身份验证</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="137fbf154ecad4d580354db0858b76faea7e4686" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>用户名长度必须为 8 至 64 个字符,可以包含字母数字字符、&quot;.&quot;、&quot;@&quot;、&quot;-&quot;、&quot;_&quot; 或 &quot;:&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">227,228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">287,288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="361771c32dd2254d77fd3fbf006b008983fe5907" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>密码长度必须为 12 至 16 个字符,可以包含字母数字字符、&quot;@&quot;、&quot;-&quot;、&quot;_&quot; 或 &quot;/&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">262,263</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">323,324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f494bd31f095f6dcc656ce87ec2dcf07a2e9b30c" datatype="html">
+ <source>Initiators</source>
+ <target>授权人</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">335</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">588</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e98239d8a6be1100119ff4b5630c822b82786740" datatype="html">
+ <source>Initiator</source>
+ <target>授权人</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2c5059d8cda15d8d03e2cce30f2d139623d9a91" datatype="html">
+ <source>Client IQN</source>
+ <target>客户端 IQN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="107d5aabce23d900f0a80e6ddc1c10e29aa0bed8" datatype="html">
+ <source>Initiator IQN needs to be unique.</source>
+ <target>授权人 IQN 必须唯一。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e7cad911fa524e512d9744b16358b7ee6791385" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>用户名长度必须为 8 至 64 个字符,可以包含字母数字字符、&quot;.&quot;、&quot;@&quot;、&quot;-&quot;、&quot;_&quot; 或 &quot;:&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">394,395</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">452,453</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7f2c186d181206d0d2b1ff74819081a010f10bf" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>密码长度必须为 12 至 16 个字符,可以包含字母数字字符、&quot;@&quot;、&quot;-&quot;、&quot;_&quot; 或 &quot;/&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">427,428</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">485,486</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d1878d5fc761cbe9614bfd87047a740c82a6951" datatype="html">
+ <source>Initiator belongs to a group. Images will be configure in the group.</source>
+ <target>授权人属于某个组。将在组中配置映像。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">515</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0de67b9d97fafbf200f9451e8388ee8128a56ac" datatype="html">
+ <source>No items added.</source>
+ <target>未添加项目。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">671</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d565e47726158e428ecdc952fc9233b9b7d7f049" datatype="html">
+ <source>Add initiator</source>
+ <target>添加授权人</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">616</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c22ba03540aa3217da059f45e7eab138b51a96e2" datatype="html">
+ <source>Groups</source>
+ <target>组</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c90059afafb7e160384d9f512797c95bb95c6dc" datatype="html">
+ <source>Group</source>
+ <target>组</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cff1428d10d59d14e45edec3c735a27b5482db59" datatype="html">
+ <source>Name</source>
+ <target>名称</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">576</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3084948274cff4f56d0f431af47240e9cf02fcc7" datatype="html">
+ <source>Add group</source>
+ <target>添加组</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">676</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6634268061646442252" datatype="html">
+ <source>There are no portals available.</source>
+ <target>没有可用的端口。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4587015892789840153" datatype="html">
+ <source>There are no images available.</source>
+ <target>没有可用的映像。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7896905042057267575" datatype="html">
+ <source>There are no images available. Please make sure you add an image to the target.</source>
+ <target>没有可用的映像。请确保为目标添加一个映像。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6765423558085969805" datatype="html">
+ <source>There are no initiators available. Please make sure you add an initiator to the target.</source>
+ <target>没有可用的授权人。请确保为目标添加一个授权人。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2539932200265667453" datatype="html">
+ <source>target</source>
+ <target>目标</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="051dcc342cfa5c1eaf187a2001aaa162379a160c" datatype="html">
+ <source>Configure</source>
+ <target>配置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e515f954730279c31d5301f02479666d6264e8b" datatype="html">
+ <source>Changing these parameters from their default values is usually not necessary.</source>
+ <target>通常无须更改这些默认参数值。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e2591df099ddac796cda401c5f282da779d45f2" datatype="html">
+ <source>Identifier</source>
+ <target>标识符</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62480a4859976427cf18fc8ef41d3a438eda0412" datatype="html">
+ <source>lun</source>
+ <target>lun</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8afc9eb4405e0aa554b2ba14140ef790cdecc040" datatype="html">
+ <source>wwn</source>
+ <target>wwn</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
+ <source>Settings</source>
+ <target>设置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69a47cbabcc51ca942606e1d8da0ec11f98a2690" datatype="html">
+ <source>Backstore</source>
+ <target>后备存储</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="339878da255ab55447c43afef8d9b2f9753bf5f6" datatype="html">
+ <source>Advanced Settings</source>
+ <target>高级设置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="332227f088a4877b3c11f5fb3ae8bc812c470fae" datatype="html">
+ <source>iSCSI Targets not available</source>
+ <target>没有可用的 iSCSI 目标</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7fba666f1fff0182e570f12133fb3d622d9ea6" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the iSCSI Targets management functionality.</source>
+ <target>请参见 <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> 了解如何配置和启用 iSCSI 目标管理功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3b301d0044f62c92af0da53d7aaca52a436a547d" datatype="html">
+ <source>Available information:</source>
+ <target>可用信息:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8414a5cb9d71cc1b21b10e4a9d1f2dad558f3361" datatype="html">
+ <source>Discovery authentication</source>
+ <target>发现身份验证</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4854396465510517671" datatype="html">
+ <source>Target</source>
+ <target>目标</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4093869278527257288" datatype="html">
+ <source>Portals</source>
+ <target>端口</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="414887388288176527" datatype="html">
+ <source>Images</source>
+ <target>映像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="798573158169239055" datatype="html">
+ <source># Sessions</source>
+ <target>会话数量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="646929398175374220" datatype="html">
+ <source>Unavailable gateway(s)</source>
+ <target>不可用的网关</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2350612272163013640" datatype="html">
+ <source>Target has active sessions</source>
+ <target>目标具有活跃会话</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4782410538666829801" datatype="html">
+ <source>iSCSI target</source>
+ <target>iSCSI 目标</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">227</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8a9910cd114c1deb9af74f6f99b4173403965bf2" datatype="html">
+ <source>Gateways</source>
+ <target>网关</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911214550882917183" datatype="html">
+ <source>State</source>
+ <target>状态</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4121862424558610140" datatype="html">
+ <source># Targets</source>
+ <target>目标数量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101197021456818771" datatype="html">
+ <source>Pool</source>
+ <target>存储池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3012906865384504293" datatype="html">
+ <source>Image</source>
+ <target>映像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2699995524827665158" datatype="html">
+ <source>Backstore</source>
+ <target>后备存储</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3559214740809905405" datatype="html">
+ <source>Read Bytes</source>
+ <target>读字节数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1580583760095064067" datatype="html">
+ <source>Write Bytes</source>
+ <target>写字节数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7225917547116479918" datatype="html">
+ <source>Read Ops</source>
+ <target>读操作数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6417507714454914481" datatype="html">
+ <source>Write Ops</source>
+ <target>写操作数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="257147267065394003" datatype="html">
+ <source>A/O Since</source>
+ <target>活动/优化开始时间</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ecbc084370a732fc3cde1966a60af78d71424ab4" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>创建引导令牌</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603e9cc3ef2aab57f2b0a00e465b23b9cabefd9c" datatype="html">
+ <source>To create a bootstrap token which can be imported by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Generate<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>要创建可由对等站点集群导入的引导令牌,请提供本地站点的名称,选择将为其启用镜像的存储池, 然后点击<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>生成<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="660f97cd3188f8a04bd03b79e703fec72c6df04c" datatype="html">
+ <source>Site Name</source>
+ <target>站点名称</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2fecea01ce1d44114ee45144eff6d47a5016a74f" datatype="html">
+ <source>Name...</source>
+ <target>名称...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92899fa68e8ca108912163ff58edc8540e453787" datatype="html">
+ <source>Pools</source>
+ <target>存储池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c2a1dc72cffaf7ab3dc5599bf77b0a7fcad2b20" datatype="html">
+ <source>At least one pool is required.</source>
+ <target>至少需指定一个存储池。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b258b258b4cc475ceb2871305b61756b0134f4a" datatype="html">
+ <source>Generate</source>
+ <target>生成</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1edc1fc6cfbbb22353050ad6788508b3ed584f53" datatype="html">
+ <source>Token</source>
+ <target>令牌</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff785f5596aef34a93b9b4d1023e95c62eef5740" datatype="html">
+ <source>Generated token...</source>
+ <target>生成的令牌...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8" datatype="html">
+ <source>Close</source>
+ <target>关闭</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5467a6bb0e7fade6def7499400d5e2a7d8d3da20" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>导入引导令牌</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bb7aee0dec5164f45c0aa2f35f2fb2149d2c1d2" datatype="html">
+ <source>To import a bootstrap token which was created by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, provide the generated token, and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Import<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>要导入由对等站点集群创建的引导令牌,请提供本地站点的名称,选择将为其启用镜像的存储池,提供生成的令牌, 然后点击<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>导入<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9200e09686136a1d42adfb89c12fbfef2deea125" datatype="html">
+ <source>Direction</source>
+ <target>方向</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9761484679958da8d12841a4efa5964d33fae575" datatype="html">
+ <source>The token is invalid.</source>
+ <target>令牌无效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2381859602529023966" datatype="html">
+ <source>Instance</source>
+ <target>实例</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8040881171107393560" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1605455101862010019" datatype="html">
+ <source>Hostname</source>
+ <target>主机名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2724055831234181057" datatype="html">
+ <source>Version</source>
+ <target>版本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2041675390931385838" datatype="html">
+ <source>Health</source>
+ <target>健康状况</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87bd96249f8afc23f5301cddb57b1464a98e71a" datatype="html">
+ <source>Edit site name</source>
+ <target>编辑站点名称</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cfff72c667274c12eb1ff71eadc25871c10c42dc" datatype="html">
+ <source>Edit the site name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>编辑站点名称并点击<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>更新<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">13,14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66db799d67958d4b0765181d072df62e2d1c16f5" datatype="html">
+ <source>Issues</source>
+ <target>问题</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef06d69259e587e28d52372455f44c7153cda7e7" datatype="html">
+ <source>Syncing</source>
+ <target>正在同步</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0b0901877d837d3fda16ba161eb74368d1c75b7a" datatype="html">
+ <source>Ready</source>
+ <target>已就绪</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5833626790712999947" datatype="html">
+ <source>Issue</source>
+ <target>问题</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3419681791450150574" datatype="html">
+ <source>Progress</source>
+ <target>进度</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4902817035128594900" datatype="html">
+ <source>Description</source>
+ <target>描述</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40b7acea5b43f45e0bbd1efeba5200af4687981d" datatype="html">
+ <source>Site Name:</source>
+ <target>站点名称:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e24f9e2d42104ffc01599db4d566d1cc518f9e6" datatype="html">
+ <source>Daemons</source>
+ <target>守护进程</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6450386891540681425" datatype="html">
+ <source>Edit Site Name</source>
+ <target>编辑站点名称</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4645993115976933405" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>创建引导令牌</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4130053543590533787" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>导入引导令牌</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4057c56d63a7e9b140b1d01871a9229a5f30eb27" datatype="html">
+ <source>Edit pool mirror mode</source>
+ <target>编辑存储池镜像模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e1f367f5feaab38f6637dd1f967c848b447dea2d" datatype="html">
+ <source>To edit the mirror mode for pool  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, select a new mode from the list and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>要编辑存储池 <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> 的镜像模式,请从列表中选择新模式,然后点击<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>更新<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37e10df2d9c0c25ef04ac112c9c9a7723e8efae0" datatype="html">
+ <source>Mode</source>
+ <target>模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">426</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32ca348ef926b0a6a7a780b8b64c3a8239895cec" datatype="html">
+ <source>Peer clusters must be removed prior to disabling mirror.</source>
+ <target>在禁用镜像功能前必须先移除同伴集群。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5769292297914455214" datatype="html">
+ <source>Disabled</source>
+ <target>已禁用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ddcb416c1c0aa1f54acf5beef1de81813e76fa6" datatype="html">
+ <source>{VAR_SELECT, select, edit {Edit} other {Add}}</source>
+ <target>{VAR_SELECT, select, edit {编辑} other {添加}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3aa7c3a4f7b0cf7c2e60fc71ea1e3b4c3efa3558" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> pool mirror peer</source>
+ <target><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/>存储池镜像对等</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="59ca65ece457429d90104ede4674965f62edbabe" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> the pool mirror peer attributes for pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Submit<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/>存储池 <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> 的存储池镜像对等属性,并点击<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>提交<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d3cc964811f852a168f4a2d5daa59068abc5cf53" datatype="html">
+ <source>Cluster Name</source>
+ <target>集群名称</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b631721fc56cb7fb1cbd07b802a487c5753f6a2d" datatype="html">
+ <source>The cluster name is not valid.</source>
+ <target>该集群名称无效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca6deafa31bf421f85094807982aee4bcb20a3ae" datatype="html">
+ <source>CephX ID</source>
+ <target>CephX ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7539188a568c3d553cbde1bacaf32310c4264e24" datatype="html">
+ <source>CephX ID...</source>
+ <target>CephX ID...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1c45b594b0fba22fc64e80c793a7ffe005fdb0e" datatype="html">
+ <source>The CephX ID is not valid.</source>
+ <target>该 CephX ID 无效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20861576fcfce773c918c782cd4f5adf32382921" datatype="html">
+ <source>Monitor Addresses</source>
+ <target>Monitor 地址</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fa28eeed2b4bd4ccbe6e9349a1c2b3cb1c5de70a" datatype="html">
+ <source>Comma-delimited addresses...</source>
+ <target>逗号分隔的地址...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dc016c82fd85848d5c1b2fd0e8469ee2027d9c16" datatype="html">
+ <source>The monitory address is not valid.</source>
+ <target>该 Monitor 地址无效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0ac55b83dc6739e62bc655cfe375b67c93e7f4a" datatype="html">
+ <source>CephX Key</source>
+ <target>CephX 密钥</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f53434bcb95bd86f1df9c8e22966f757614fc4ad" datatype="html">
+ <source>Base64-encoded key...</source>
+ <target>Base64 编码的密钥...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4cd83164cd4f66b4abc2863f9ce6f599d789e4ca" datatype="html">
+ <source>CephX key must be base64 encoded.</source>
+ <target>CephX 密钥必须为 base64 编码。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6407712033679505505" datatype="html">
+ <source>Edit Mode</source>
+ <target>编辑模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054237897979907103" datatype="html">
+ <source>Add Peer</source>
+ <target>添加对等</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="899134641637789371" datatype="html">
+ <source>Edit Peer</source>
+ <target>编辑对等</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7393680121674824053" datatype="html">
+ <source>Delete Peer</source>
+ <target>删除对等</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1713271461473302108" datatype="html">
+ <source>Mode</source>
+ <target>模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1061297288634362831" datatype="html">
+ <source>Leader</source>
+ <target>主管</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8517494870558773093" datatype="html">
+ <source># Local</source>
+ <target>本地数量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4953753699491987394" datatype="html">
+ <source># Remote</source>
+ <target>远程数量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1715982232168082172" datatype="html">
+ <source>mirror peer</source>
+ <target>镜像对等</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff92fbdec9fdd5054493eeda0d7ee8b450f83e72" datatype="html">
+ <source>RBD Configuration</source>
+ <target>RBD 配置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b62d9efc8eb3b589904f6cb96a0406bbda55673a" datatype="html">
+ <source>Remove the local configuration value. The parent configuration value will be inherited and used instead.</source>
+ <target>删除本地的配置值。将继承并改用父配置值。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80d769fd863fe44fab689636a078466bfdbd1f20" datatype="html">
+ <source>The minimum value is 0</source>
+ <target>最小值为 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5decb3917d46a9ac6e5813699801becb7c3c1455" datatype="html">
+ <source>Global</source>
+ <target>全局</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f9ba9bb9faa8284bcadb1cdbc6aaf969e9c4bb" datatype="html">
+ <source>Image</source>
+ <target>映像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70fcca5a99575cffef3ff8cbd5e69f06ffd0f1c" datatype="html">
+ <source>Pool</source>
+ <target>存储池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176659033176029418" datatype="html">
+ <source>Key</source>
+ <target>密钥</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9155608366859514313" datatype="html">
+ <source>Source</source>
+ <target>来源</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6555318547274416232" datatype="html">
+ <source>Value</source>
+ <target>值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f6e8f6094b180eaf1f11bc0ffe383f1cdcd059e" datatype="html">
+ <source>Only available for RBD images with <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> enabled</source>
+ <target>仅可用于启用了 <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> 的 RBD 映像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f8b2bb476981727ab34ed40fde1218361f92c45" datatype="html">
+ <source>Details</source>
+ <target>详细信息</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03cc5b14b0a20d075e9009ff021f4f1660ba348a" datatype="html">
+ <source>Data Pool</source>
+ <target>数据池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b051734b0ee9021991c91b3ed4e81c244322462" datatype="html">
+ <source>Created</source>
+ <target>已创建</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7faaaa08f56427999f3be41df1093ce4089bbd75" datatype="html">
+ <source>Size</source>
+ <target>容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="afdb601c16162f2c798b16a2920955f1cc6a20aa" datatype="html">
+ <source>Objects</source>
+ <target>对象数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ceac8e132384322ec778ba760875a6c6897d3e42" datatype="html">
+ <source>Object size</source>
+ <target>对象大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cdb1fea93d77c07950c0c76c6e0ad79ebbef084" datatype="html">
+ <source>Features</source>
+ <target>特性</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65771c9a73b9aa609d592fc96a64801a8f40bd" datatype="html">
+ <source>Provisioned</source>
+ <target>已供给容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84a36cb75660b736773fe36ffa3d54f0f0fe363e" datatype="html">
+ <source>N/A</source>
+ <target>不适用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c009342a4e8381f64341d0bb61c2e4685f5a4b" datatype="html">
+ <source>Total provisioned</source>
+ <target>总供给容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f6bf8a43ae415f527ac961ea62471b983aaa97b" datatype="html">
+ <source>Striping unit</source>
+ <target>条带单元大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db710e8a8f011923f2d15d713fbae49c38b02b26" datatype="html">
+ <source>Striping count</source>
+ <target>条带个数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a4c2a9e76634ff14a60d52a718296f722d47c67" datatype="html">
+ <source>Parent</source>
+ <target>父项</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a209e68d78ffc2cc9c53d2e76158624efab71ad" datatype="html">
+ <source>Block name prefix</source>
+ <target>块设备名称前缀</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5704ec2049d007c5f5fb495a5d8b607e68d58081" datatype="html">
+ <source>Order</source>
+ <target>顺序</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="984cb6ad70f150a401b4daf841bd3cd957412699" datatype="html">
+ <source>Format Version</source>
+ <target>格式版本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f21b1d17b6c5042bb5805516eee37fde33739dd8" datatype="html">
+ <source>Snapshots</source>
+ <target>快照</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4a41f824a35ba01d5bd7be61aa06b3e8145209d0" datatype="html">
+ <source>Configuration</source>
+ <target>配置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3cc9c2ae277393b3946b38c088dabff671b1ee1b" datatype="html">
+ <source>Performance</source>
+ <target>性能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935bb9cb0e4340fc74d33caa3b70d9d143fcad87" datatype="html">
+ <source>Information can not be displayed for RBD in status 'Removing'.</source>
+ <target>无法显示处于 &quot;正在删除&quot; 状态的 RBD 的信息。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58e58f1a8786da9031a05e6770c5dafce82badf5" datatype="html">
+ <source>This setting overrides the global value</source>
+ <target>此设置会覆盖全局值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36b46714164964c6258b08ed0a25f57d8a950f92" datatype="html">
+ <source>This is the global value. No value for this option has been set for this image.</source>
+ <target>该值为全局值。没有为此映像设置此选项的值。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6547c9c4d5f62942ac4b1fe459cf9a03d4dbf5a0" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> from</source>
+ <target> <x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> 从</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0e9ecf29a4fa5b057bd8052e0d801b3fde6a30bf" datatype="html">
+ <source>'/' and '@' are not allowed.</source>
+ <target>不允许使用 &quot;/&quot; 和 &quot;@&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="94516fa213706c67ce5a5b5765681d7fb032033a" datatype="html">
+ <source>Loading...</source>
+ <target>正在加载...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">209</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">452</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b99417c4dd46286ffd37c8d2e987c8b512ec7052" datatype="html">
+ <source>-- No rbd pools available --</source>
+ <target>-- 没有可用的 RBD 存储池 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef83ec9c304a89d45650e580dcdc2978c37b3a83" datatype="html">
+ <source>-- Select a pool --</source>
+ <target>-- 请选择存储池 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d649904466254d13df1fbf2d255f0bbc6553d213" datatype="html">
+ <source>-- No namespaces available --</source>
+ <target>-- 没有可用的名称空间 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e22d7bb4d2d561e0832ee0b9a3da2468a080c4f0" datatype="html">
+ <source>-- Select a namespace --</source>
+ <target>-- 请选择名称空间 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49449943d8cbf59d8c401c8bd2e76f92e207cc5f" datatype="html">
+ <source>Use a dedicated data pool</source>
+ <target>使用专用的数据池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa5b3c5ea5af14d09b2eb098039af9f1f77be010" datatype="html">
+ <source>You need more than one pool with the rbd application label use to use a dedicated data pool.</source>
+ <target>要使用专用的数据池,您需要多个使用了 RBD 应用标签的存储池。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="870aee0dd31a9643bf62007beb8f1ae1deb34d42" datatype="html">
+ <source>Data pool</source>
+ <target>数据池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3792ca829d9b9f687e1f5d7733d30e9bb0bfec47" datatype="html">
+ <source>Dedicated pool that stores the object-data of the RBD.</source>
+ <target>专用于存储 RBD 的对象数据的存储池。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151c80ea931037cd92e854442927f8a0f6ae7795" datatype="html">
+ <source>-- No data pools available --</source>
+ <target>-- 没有可用的数据池 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0016bd458baa88284a658ce9eeda42d8ad88d2c" datatype="html">
+ <source>e.g., 10GiB</source>
+ <target>例如 10GiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">206</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a88bbee20570aaf9615332fb27020627044874d" datatype="html">
+ <source>You have to increase the size.</source>
+ <target>您必须提高容量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cfe07dac5b4ee1c464eb24225ddeb4f1d24076a" datatype="html">
+ <source>Advanced...</source>
+ <target>高级...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bc2e854e111ecf2bd7db170da5e3c2ed08181d88" datatype="html">
+ <source>Advanced</source>
+ <target>高级</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3562a3778695a5f9c0445660e35301f0a39aaf73" datatype="html">
+ <source>Striping</source>
+ <target>条带</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef3c3f3b5f562a5cdbe0ee2874287db1534b5958" datatype="html">
+ <source>Stripe unit</source>
+ <target>条带单元大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84471be1049006edecbcaef1a32ae0893c229c50" datatype="html">
+ <source>-- Select stripe unit --</source>
+ <target>-- 请选择条带单元大小 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">289</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d32c5c54c8581c774a7f467fbd4e329b15a74fa" datatype="html">
+ <source>This field is required because stripe count is defined!</source>
+ <target>因为设置了条带个数,所以这是必填字段!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bbf9040be7c5491d4a03f2185708f43a6582a3b" datatype="html">
+ <source>Stripe unit is greater than object size.</source>
+ <target>条带单元大小超过了对象大小。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a682f49f9b761591661276d7c6f550e641a130a4" datatype="html">
+ <source>Stripe count</source>
+ <target>条带个数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="baa74031990c5370008ba622d0a250f0929097f4" datatype="html">
+ <source>This field is required because stripe unit is defined!</source>
+ <target>因为设置了条带单元大小,所以这是必填字段!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cd2ada6d5ecbd5cbf89eae0a1f5326efedac0dbc" datatype="html">
+ <source>Stripe count must be greater than 0.</source>
+ <target>条带个数必须大于 0。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4341718109173132593" datatype="html">
+ <source>RBD</source>
+ <target>RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1359455778569887786" datatype="html">
+ <source>Deep flatten</source>
+ <target>完全展开</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58519213655664125" datatype="html">
+ <source>Layering</source>
+ <target>分层</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844531889615887801" datatype="html">
+ <source>Exclusive lock</source>
+ <target>互斥锁</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4585281635594103106" datatype="html">
+ <source>Object map (requires exclusive-lock)</source>
+ <target>object map(需要互斥锁支持)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240933649452133654" datatype="html">
+ <source>Journaling (requires exclusive-lock)</source>
+ <target>日志(需要互斥锁支持)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3713046526850391848" datatype="html">
+ <source>Fast diff (interlocked with object-map)</source>
+ <target>Fast diff(与 object-map 互锁)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19f1e825536efbf7492723a7c2d01ad23a4e994b" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1774b9915b0e302d02cad0b9321ad5f1a83247a8" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c9f1026c1235f4d76ace47449e806efd181ab332" datatype="html">
+ <source>Deleting this image will also delete all its snapshots.</source>
+ <target>删除此映像时也会删除它的所有快照。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55f864597e84d9bf88769e1fbfda1d64452430c9" datatype="html">
+ <source>The following snapshots are currently protected and will be removed:</source>
+ <target>以下快照当前受到保护,将会被删除:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2e362ec498c4c9112dc47a3cb7d7250ca8e71790" datatype="html">
+ <source>RBD in status 'Removing'</source>
+ <target>RBD 处于 &quot;正在删除&quot; 状态</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3294686077659093992" datatype="html">
+ <source>Namespace</source>
+ <target>名称空间</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45739481977493163" datatype="html">
+ <source>Size</source>
+ <target>容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7531602241051125940" datatype="html">
+ <source>Objects</source>
+ <target>对象数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1194977199378511591" datatype="html">
+ <source>Object size</source>
+ <target>对象大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">226</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="178418048502923560" datatype="html">
+ <source>Provisioned</source>
+ <target>已供给容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7638291694671392137" datatype="html">
+ <source>Total provisioned</source>
+ <target>总供给容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8621797738551294959" datatype="html">
+ <source>Parent</source>
+ <target>父项</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616639680594151867" datatype="html">
+ <source>This RBD has cloned snapshots. Please delete related RBDs before deleting this RBD.</source>
+ <target>此 RBD 具有克隆的快照。请先删除相关 RBD,再删除此 RBD。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2900827028308925059" datatype="html">
+ <source>This RBD image has an invalid name and can't be managed by ceph.</source>
+ <target>此 RBD 映像的名称无效,无法通过 Ceph 进行管理。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1796389652493657142" datatype="html">
+ <source>Action not possible for an RBD in status 'Removing'</source>
+ <target>无法对处于 &quot;正在删除&quot; 状态的 RBD 执行操作</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">476</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c07d24bb422aa8e5e568df1c5709083f0a9c8f1" datatype="html">
+ <source>Create Namespace</source>
+ <target>创建名称空间</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cca6c0485f96d3a9610d0339cb1275a5f2c3f46" datatype="html">
+ <source>Namespace already exists.</source>
+ <target>名称空间已存在。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4641528557519966449" datatype="html">
+ <source>Created namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <target>已创建名称空间 &quot;<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6809428596104996786" datatype="html">
+ <source>Total images</source>
+ <target>映像总数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1346311774128536550" datatype="html">
+ <source>Deleted namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <target>已删除名称空间 &quot;<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7605466414392298530" datatype="html">
+ <source>Namespace contains images</source>
+ <target>名称空间包含映像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576483965711201552" datatype="html">
+ <source>RBD Snapshot</source>
+ <target>RBD 快照</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3473055924346204357" datatype="html">
+ <source>Parent image must support Layering</source>
+ <target>父映像必须支持分层</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1152535233999495900" datatype="html">
+ <source>Snapshot must be protected in order to clone.</source>
+ <target>快照必须处于受保护状态才能克隆。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c5331983af566d4ac6a1024d15a3511786a4aa6" datatype="html">
+ <source>You are about to rollback</source>
+ <target>您即将进行回滚操作</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6240400332778072187" datatype="html">
+ <source>PROTECTED</source>
+ <target>受保护</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9101667614062185213" datatype="html">
+ <source>UNPROTECTED</source>
+ <target>无保护</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4207916966377787111" datatype="html">
+ <source>Created</source>
+ <target>已创建</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587768621777516124" datatype="html">
+ <source>RBD snapshot rollback</source>
+ <target>RBD 快照回滚</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">305</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2711198699676132148" datatype="html">
+ <source>Rollback</source>
+ <target>回滚</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3330476395115957823" datatype="html">
+ <source>RBD snapshot</source>
+ <target>RBD 快照</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">322</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3a7e364a88ea4673199dfa98bc73e6dbe09dfac" datatype="html">
+ <source>Namespaces</source>
+ <target>名称空间</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aba82bfd8e177d35b76cad7cd43941f8e5e5acac" datatype="html">
+ <source>Trash</source>
+ <target>回收站</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5e7f4b1ca49e8d217bd0e12c6f7d6b6a2ade2c18" datatype="html">
+ <source>Overall Performance</source>
+ <target>总体性能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c0408946a6d67185947f455f15cc201d0d78e6" datatype="html">
+ <source>Purge Trash</source>
+ <target>清空回收站</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c96a761dc55a21882c132c929583a424c9b8cf4" datatype="html">
+ <source>Expired at</source>
+ <target>过期时间</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="661041e3fcff4d3e75c561e038ca2504cf2cc643" datatype="html">
+ <source>Protected until</source>
+ <target>保护期限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee3b2322a1d3277f7e3fdb8a5141ac42bcf350b" datatype="html">
+ <source>This image is protected until <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</source>
+ <target>此映像在 <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/> 前始终受到保护。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5611592591303869712" datatype="html">
+ <source>Status</source>
+ <target>状态</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">213</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">285</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2155633476201267204" datatype="html">
+ <source>Deleted At</source>
+ <target>删除时间</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0b5d789d42c0e69348e5fe0037fcbf5b5fbbdcc" datatype="html">
+ <source>Move an image to trash</source>
+ <target>将映像移至回收站</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ad22c1d4aab3b8946603cea62de266d5129ca10" datatype="html">
+ <source>This image contains snapshot(s), which will prevent it from being removed after moved to trash.</source>
+ <target>此映像包含快照,这将阻止映像移至回收站后被删除。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">15,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d4a5f5698bc8118b2e120b9bb72eff339094dd0" datatype="html">
+ <source>To move <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> to trash, click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Move<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Optionally, you can pick an expiration date.</source>
+ <target>要将 <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> 移至回收站,请点击<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>移动<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>。您可以视需要选择一个超期日期。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">19,20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f27d390844aad53b4240360e928156c5f0d326" datatype="html">
+ <source>Protection expires at</source>
+ <target>保护期截至</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da166e9a0d27322f6ba8916d71ecc0f9905bb4b1" datatype="html">
+ <source>NOT PROTECTED</source>
+ <target>无保护</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1506e5f2ca22cad14502ec7a20fb6113ace145d" datatype="html">
+ <source>Wrong date format. Please use &quot;YYYY-MM-DD HH:mm:ss&quot;.</source>
+ <target>日期格式有误。请使用 &quot;YYYY-MM-DD HH:mm:ss&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa7ea0bb7495281e0b3258467ac7d90a1e44a1a1" datatype="html">
+ <source>Protection has already expired. Please pick a future date or leave it empty.</source>
+ <target>保护期限已过。请选择一个将来的日期或留空。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d8613436532acac2b97d17de28b50f93e6bd0222" datatype="html">
+ <source>To purge, select  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>All<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>  or one pool and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Purge<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </source>
+ <target>要进行清除,请选择<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>所有<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>或一个存储池,然后点击<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>清除<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55a4f598a4894b7fd5cb88f0ffd3c37ad009dd70" datatype="html">
+ <source>Pool:</source>
+ <target>存储池:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d43dd2b9f7797e4cf3a604695bb33e4479108516" datatype="html">
+ <source>Pool name...</source>
+ <target>存储池名称...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dfc3c34e182ea73c5d784ff7c8135f087992dac1" datatype="html">
+ <source>All</source>
+ <target>所有</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0e7c7ed1d51a0c205c815048bc9f79e24ee6db2" datatype="html">
+ <source>Restore Image</source>
+ <target>恢复映像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3bc4aaf0dce75dc5e01ee5c825a652dc8aea8f0" datatype="html">
+ <source>To restore  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>,  type the image's new name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Restore<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>要恢复 <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>,请键入映像的新名称,然后点击<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>恢复<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41307dd56fea669eed72e12a6c23af275f6bfd82" datatype="html">
+ <source>New Name</source>
+ <target>新名称</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3625859417927520024" datatype="html">
+ <source>id</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6537904131139019667" datatype="html">
+ <source>type</source>
+ <target>类型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8901220148451863928" datatype="html">
+ <source>state</source>
+ <target>状态</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7925190601961269841" datatype="html">
+ <source>version</source>
+ <target>版本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6641024648411549335" datatype="html">
+ <source>Host</source>
+ <target>主机</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773272191572353800" datatype="html">
+ <source>root</source>
+ <target>根</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6364513948635353490" datatype="html">
+ <source>Evicted client '<x id="PH" equiv-text="clientId"/>'</source>
+ <target>已逐出客户端 &quot;<x id="PH" equiv-text="clientId"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c1e17956453ad772dbe82d6946f62748c692f3e" datatype="html">
+ <source>Ranks</source>
+ <target>排位</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b24e0b0b1629d2e8a51b9da7c75d6e6379f4bc4" datatype="html">
+ <source>Standbys</source>
+ <target>待机</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="50df62325726db950523a5be1c78b8905fcc25d4" datatype="html">
+ <source>MDS performance counters</source>
+ <target>MDS 性能计数器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4578796959376778578" datatype="html">
+ <source>Standby daemons</source>
+ <target>待机守护进程</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="665219418211496660" datatype="html">
+ <source>Rank</source>
+ <target>排位</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5445409664838149993" datatype="html">
+ <source>Daemon</source>
+ <target>守护进程</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5306473977542913614" datatype="html">
+ <source>Activity</source>
+ <target>活跃度</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3998441303515229547" datatype="html">
+ <source>Dentries</source>
+ <target>dentry</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7877631502958415163" datatype="html">
+ <source>Inodes</source>
+ <target>inode</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6129397096478256985" datatype="html">
+ <source>Dirs</source>
+ <target>目录</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3011876564696453148" datatype="html">
+ <source>Caps</source>
+ <target>功能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8650499415827640724" datatype="html">
+ <source>Type</source>
+ <target>类型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="142654590491855672" datatype="html">
+ <source>Usage</source>
+ <target>使用率</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">326</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb8293aa8161433778762ae025ffd5e7c85795e" datatype="html">
+ <source>Quotas</source>
+ <target>配额</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">540</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66785722678644243" datatype="html">
+ <source>Origin</source>
+ <target>来源</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8911059720204770105" datatype="html">
+ <source>Path</source>
+ <target>路径</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6111756909052789805" datatype="html">
+ <source>Cannot create snapshots for files/folders in the subvolume <x id="PH" equiv-text="folders[2]"/></source>
+ <target>无法创建子卷 <x id="PH" equiv-text="folders[2]"/> 中的文件/文件夹的快照</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7503263437025060215" datatype="html">
+ <source>Max size</source>
+ <target>最大大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6763343019307619111" datatype="html">
+ <source>Max files</source>
+ <target>最大文件数量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327403486214540377" datatype="html">
+ <source>The inherited <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> is the maximum value to be used.</source>
+ <target>继承的 <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> 为将使用的最大值。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">434,437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3768927257183755959" datatype="html">
+ <source>Save</source>
+ <target>保存</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">440</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6328794256834621774" datatype="html">
+ <source><x id="PH" equiv-text="action"/> CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> quota for '<x id="PH_2" equiv-text="path"/>'</source>
+ <target><x id="PH" equiv-text="action"/> &quot;<x id="PH_2" equiv-text="path"/>&quot; 的 CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> 配额 </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">446</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9130352375983418123" datatype="html">
+ <source>size</source>
+ <target>大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6889473896134264260" datatype="html">
+ <source>files</source>
+ <target>文件数量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2244434638607433133" datatype="html">
+ <source><x id="PH" equiv-text="this.getQuotaName()"/> quota <x id="PH_1" equiv-text="value"/> from '<x id="PH_2" equiv-text="path"/>'</source>
+ <target> &quot;<x id="PH_2" equiv-text="path"/>&quot; 中的 <x id="PH" equiv-text="this.getQuotaName()"/> 配额 <x id="PH_1" equiv-text="value"/> </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">460</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6960117167304061503" datatype="html">
+ <source>Value has to be at least 0 or more</source>
+ <target>值必须大于或等于 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">484</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6740501370117796629" datatype="html">
+ <source>Value has to be at most <x id="PH" equiv-text="maxValue"/> or less</source>
+ <target>值必须小于或等于 <x id="PH" equiv-text="maxValue"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7239750919884229270" datatype="html">
+ <source>Updated</source>
+ <target>已更新</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">499</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8885980874806414253" datatype="html">
+ <source>in order to inherit <x id="PH" equiv-text="quotaValue"/></source>
+ <target>以继承 <x id="PH" equiv-text="quotaValue"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4182949309891923991" datatype="html">
+ <source>which isn't used because of the inheritance of <x id="PH" equiv-text="quotaValue"/></source>
+ <target>未使用,因为继承了 <x id="PH" equiv-text="quotaValue"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7421970649864638435" datatype="html">
+ <source>in order to have no quota on the directory</source>
+ <target>为了不为目录分配配额</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6730229976797004508" datatype="html">
+ <source><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</source>
+ <target><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">530,533</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="827679535246546876" datatype="html">
+ <source>Create Snapshot</source>
+ <target>创建快照</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">542</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">552</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4747656362969857823" datatype="html">
+ <source>Please enter the name of the snapshot.</source>
+ <target>请输入快照的名称。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3667696812078358068" datatype="html">
+ <source>Created snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <target>已创建 &quot;<x id="PH_1" equiv-text="path"/>&quot; 的快照 &quot;<x id="PH" equiv-text="name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="753342836137587734" datatype="html">
+ <source>CephFs Snapshot</source>
+ <target>CephFs 快照</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">670</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2774104291801979963" datatype="html">
+ <source>Deleted snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <target>已删除 &quot;<x id="PH_1" equiv-text="path"/>&quot; 的快照 &quot;<x id="PH" equiv-text="name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">683</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4816216590591222133" datatype="html">
+ <source>Enabled</source>
+ <target>已启用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ffe39df9d88c972792bd8688b215392deb8313d" datatype="html">
+ <source>Clients</source>
+ <target>客户端</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e213942c6354b9cbe7a650f0f1499bfc1000fb6" datatype="html">
+ <source>Directories</source>
+ <target>目录</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fbbaf5cb02ed419e79a27072478f716a4666a99d" datatype="html">
+ <source>Performance Details</source>
+ <target>性能详细信息</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0" datatype="html">
+ <source>Description</source>
+ <target>描述</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ad112ce9bcd55dfd137792a86afe1b5a5b13cf8" datatype="html">
+ <source>Long description</source>
+ <target>详细描述</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="26fb5f81b3581f06b9210defb0e71dc69a67e819" datatype="html">
+ <source>Current values</source>
+ <target>当前值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7cee38a2259526c519f878e71b964f41db4348" datatype="html">
+ <source>Default</source>
+ <target>默认值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33e1c1d9fc05ca3f62fcc8a1170fc31ebae4229c" datatype="html">
+ <source>Daemon default</source>
+ <target>守护进程的默认值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f61c6867295f3b53d23557021f2f4e0aa1d0b8fc" datatype="html">
+ <source>Type</source>
+ <target>类型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9abcd7c82643d60c22733470463f74e4a54bc069" datatype="html">
+ <source>Min</source>
+ <target>下限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3ced4d162a0a55ee233a187ce7208ba5e922418" datatype="html">
+ <source>Max</source>
+ <target>上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="920617c6a1a4805e53bcb5af6a9c76f8387e89c6" datatype="html">
+ <source>Flags</source>
+ <target>标志</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5" datatype="html">
+ <source>Services</source>
+ <target>服务</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6834fa6b43d1ecbdf147c48dd9c4d72f1484571d" datatype="html">
+ <source>Source</source>
+ <target>来源</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a446fb0eb11fbffcac805ece5a2d306d24e733d8" datatype="html">
+ <source>Level</source>
+ <target>级别</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39f2fb094e9b2eda13163fa3f3a31594cf9c1307" datatype="html">
+ <source>Can be updated at runtime (editable)</source>
+ <target>可在运行时更新(可编辑)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
+ <source>Tags</source>
+ <target>标记</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ab0089ef47af61ca1d137bc908b96c290dfd9287" datatype="html">
+ <source>Enum values</source>
+ <target>枚举值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="819476f1264f1659f38e86f6abb542141b184832" datatype="html">
+ <source>See also</source>
+ <target>另请参见</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="543199344025799954" datatype="html">
+ <source>The value can be updated at runtime.</source>
+ <target>该值可在运行时更新。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1718354829128482129" datatype="html">
+ <source>Daemons/clients do not pull this value from the
+ monitor config database. We disallow setting this option via 'ceph config
+ set ...'. This option should be configured via ceph.conf or via the
+ command line.</source>
+ <target>守护进程/客户端不会从 monitor 的配置数据库提取此值。
+ 因此不能用 &quot;ceph config set ...&quot; 设置此选项,但可以通过
+ ceph.conf 或者用命令行进行配置。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">15,18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2345189734548717257" datatype="html">
+ <source>Option takes effect only during daemon startup.</source>
+ <target>选项仅会在守护进程启动期间生效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5523310713159993513" datatype="html">
+ <source>Option only affects cluster creation.</source>
+ <target>选项仅会影响集群的创建。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1064479086902933123" datatype="html">
+ <source>Option only affects daemon creation.</source>
+ <target>选项仅会影响守护进程的创建。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="809b0c848932a41318f77a2aace904ef429c13f4" datatype="html">
+ <source>Values</source>
+ <target>值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5894f7158499fdb89527af50c9f1cf7d4c95cad6" datatype="html">
+ <source>-- Default --</source>
+ <target>-- 默认值 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="514f6e12d035a6d9b00de6b3e55c18b73488da07" datatype="html">
+ <source>true</source>
+ <target>true</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="774f5e6a183dea08393789b6f72e86afad729419" datatype="html">
+ <source>false</source>
+ <target>false</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="82029b6db704c56a2aa3e82ac555b8655356b077" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>.</source>
+ <target>输入的值太大!值不得大于 <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ed8b3967a7326b81b191c9f490006e6a6777a9a" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>.</source>
+ <target>输入的值太小!值不得小于 <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2337058106409853613" datatype="html">
+ <source>Updated config option <x id="PH" equiv-text="request.name"/></source>
+ <target>已更新配置选项 <x id="PH" equiv-text="request.name"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3733215288982610673" datatype="html">
+ <source>Level</source>
+ <target>级别</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2218082343053095278" datatype="html">
+ <source>Service</source>
+ <target>服务</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3553216189604488439" datatype="html">
+ <source>Modified</source>
+ <target>已修改</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844248428439297756" datatype="html">
+ <source>Current value</source>
+ <target>当前值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208877297843037352" datatype="html">
+ <source>Editable</source>
+ <target>可编辑</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b266042bac4c3a2eff4834e40fb9dc4767a709" datatype="html">
+ <source>Cluster Resources</source>
+ <target>集群资源</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="099b441d49333b3c6d30b36dc0a4763e64c78920" datatype="html">
+ <source>Hosts</source>
+ <target>主机</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57e6e608ece53a26f6d509c90ed4f83e467741af" datatype="html">
+ <source>Storage Capacity</source>
+ <target>存储容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19ece2cb2b9097c0f75af8e62b4b3b25d399a006" datatype="html">
+ <source>Number of devices</source>
+ <target>设备数量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b161e3d25fd1b42a781f4e923a58a94925988ddf" datatype="html">
+ <source>Raw capacity</source>
+ <target>裸容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb6f3e2a26f3a6f2bc33f91adcd60502dbe5adac" datatype="html">
+ <source>CPUs</source>
+ <target>CPU</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58d4a9814864741040bc5905b6a368836e683f76" datatype="html">
+ <source>Memory</source>
+ <target>内存</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dbb81e566a861d4aa0a094366e4083e50863ee92" datatype="html">
+ <source>Host Details</source>
+ <target>主机详细信息</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="453dc2810080a744223faac6da2b3ee9ed63a583" datatype="html">
+ <source>Welcome to <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></source>
+ <target>欢迎使用 <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1eec874e1928ca53baa9914781ce203b5f72b0c" datatype="html">
+ <source>Please expand your cluster first</source>
+ <target>请先扩展您的集群</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2195fd96b0a00f560449b50bd032e6d9b357730" datatype="html">
+ <source>Expand Cluster</source>
+ <target>扩展集群</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb075d0450deb6f381616f7da4b9244ced843053" datatype="html">
+ <source>Skip</source>
+ <target>跳过</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55b6ce65571b8893440a4fc92776570f8fe7cc97" datatype="html">
+ <source>Add Hosts</source>
+ <target>添加主机</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="162f763675c24b557a60eba0758558222369e0c7" datatype="html">
+ <source>Create OSDs</source>
+ <target>创建 OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fef7a7b8db05c351c5287db48488abca530bdb54" datatype="html">
+ <source>Create Services</source>
+ <target>创建服务</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="176873b4533ddeabf95992cbd7b91b9d01c6d557" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ed90ec4409b9f6b552982d96f89db27259e763c" datatype="html">
+ <source>You are about to skip the cluster expansion process. You’ll need to <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>navigate through the menu to add hosts and services.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>您即将跳过集群扩展流程。您需要<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>在菜单中导航以添加主机和服务<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">90,91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d1dcf2a9146caac0581329acf94806ec69a89a5" datatype="html">
+ <source>Are you sure you want to continue?</source>
+ <target>确实要继续吗?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6759205696902713848" datatype="html">
+ <source>Warning</source>
+ <target>警报</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">357</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6962699013778688473" datatype="html">
+ <source>Continue</source>
+ <target>继续</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6156560100092571435" datatype="html">
+ <source>Cluster expansion skipped by user</source>
+ <target>用户已跳过集群扩展</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520085823873354736" datatype="html">
+ <source>Cluster expansion was successful</source>
+ <target>集群扩展成功</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176230351113290618" datatype="html">
+ <source>Expand Cluster</source>
+ <target>扩展集群</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="738de688b22fba5d0dc7a5e549996838dddad0ee" datatype="html">
+ <source>CRUSH map viewer</source>
+ <target>CRUSH 索引查看器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/crushmap/crushmap.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e24569eca61d598c8b01defbbbb1fa8bd5222bc" datatype="html">
+ <source>Devices</source>
+ <target>设备</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17137bac47e1e020d139256ded0006a671966e73" datatype="html">
+ <source>Physical Disks</source>
+ <target>物理磁盘</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="deba10b7279a589d01e919ea11f43c79ca1773e3" datatype="html">
+ <source>Device health</source>
+ <target>设备健康状况</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d87fc20ea8e5f0f0500ba5d5061b345be78ec5e" datatype="html">
+ <source>No hostname found.</source>
+ <target>未找到主机名。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9a541ec1a4319fffc16ad3b3ab2c2b6d251a829d" datatype="html">
+ <source>Hostname</source>
+ <target>主机名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee6875e67b53cac30a02b57cf76e485f7e60caf4" datatype="html">
+ <source>To add multiple hosts at once, you can enter:</source>
+ <target>要一次添加多个主机,您可以输入:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a8370b19ccf673fb28fa9db36a08f9901887cc7" datatype="html">
+ <source>a comma-separated list of hostnames <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-01,example-02,example-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <target>主机名称的逗号分隔列表<x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(例如:example-01,example-02,example-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="68f2c05396ec8a5f59e8da42d1f6c7310fa8c37c" datatype="html">
+ <source>a range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <target>范围表达式<x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(例如:example-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e00b9bba448e79add37740e53dc953fbb89f9c5" datatype="html">
+ <source>a comma separated range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></source>
+ <target>范围表达式的逗号分隔列表<x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(例如:example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b3f5e5291541678f7afa49d28fad5ca848a8061" datatype="html">
+ <source>The chosen hostname is already in use.</source>
+ <target>所选主机名已被使用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="42365f623c57973d1d13d2038e8a2d4c02fb9b9f" datatype="html">
+ <source>Network address</source>
+ <target>网络地址</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3859bdca1ae89e611e214c205fccf0147b4d0f6b" datatype="html">
+ <source>The value is not a valid IP address.</source>
+ <target>不合法的IP地址</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2af7efecfae8d7fed3b07f718a623eca1ad8163f" datatype="html">
+ <source>Labels</source>
+ <target>标签</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9da2afd4fa358b66d4d95fe7e8f4b659a7144e" datatype="html">
+ <source>Maintenance Mode</source>
+ <target>维护模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="468785112451259935" datatype="html">
+ <source>There are no labels.</source>
+ <target>没有标签。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4664081995078497865" datatype="html">
+ <source>Filter or add labels</source>
+ <target>过滤或添加标签</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4897817053917542646" datatype="html">
+ <source>Add label</source>
+ <target>添加标签</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">313</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1187321380561233505" datatype="html">
+ <source>host</source>
+ <target>主机</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40661476cb24c89d8b06614998e31d5fbe84eeb6" datatype="html">
+ <source>Hosts List</source>
+ <target>主机列表</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b7a4e1e5a316f8547af1d6d2311a5cec8c5c1d87" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ msg }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ msg }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6e8e8844e9e7a7b626a4699c08b6c0c81297a7b" datatype="html">
+ <source>Data will be available only if Orchestrator is available.</source>
+ <target>仅当 Orchestrator 可用时,才能获取数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4baf526199fed59071adf555271791283adc408" datatype="html">
+ <source>SSD, NVMEs</source>
+ <target>SSD、NVME</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="22d5531d79f0d7269a0a752e56a848807dd37095" datatype="html">
+ <source>Flash</source>
+ <target>闪存</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4025065730478477779" datatype="html">
+ <source>The feature is disabled because the selected host is not managed by Orchestrator.</source>
+ <target>由于所选主机并不是由 Orchestrator 管理,该功能已禁用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7143579180750436311" datatype="html">
+ <source>Services</source>
+ <target>服务</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="546766753072101168" datatype="html">
+ <source>Labels</source>
+ <target>标签</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1141886420788473147" datatype="html">
+ <source>Model</source>
+ <target>型号</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4027647877328291519" datatype="html">
+ <source>CPUs</source>
+ <target>CPU</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2445398473573060226" datatype="html">
+ <source>Cores</source>
+ <target>内核</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1656823484917332451" datatype="html">
+ <source>Total Memory</source>
+ <target>总内存</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1939212557812454069" datatype="html">
+ <source>Raw Capacity</source>
+ <target>裸容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5579687933271468638" datatype="html">
+ <source>HDDs</source>
+ <target>HDD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1889285841762768492" datatype="html">
+ <source>Flash</source>
+ <target>闪存</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1578709829957887527" datatype="html">
+ <source>NICs</source>
+ <target>NIC</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4723031838495967601" datatype="html">
+ <source>Edit Host: <x id="PH" equiv-text="host.hostname"/></source>
+ <target>编辑主机:<x id="PH" equiv-text="host.hostname"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6004907173026319041" datatype="html">
+ <source>Edit Host</source>
+ <target>编辑主机</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5618131051466022401" datatype="html">
+ <source>Updated Host &quot;<x id="PH" equiv-text="host.hostname"/>&quot;</source>
+ <target>已更新主机 &amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1701954433367210342" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; moved to maintenance</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; 已进入维护模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3108406586869160854" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; cannot be put into maintenance</source>
+ <target>无法将 &amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; 置于维护模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1737753151350322492" datatype="html">
+ <source><x id="PH" equiv-text="error.error['detail']"/></source>
+ <target><x id="PH" equiv-text="error.error['detail']"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4054533801359952167" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; has exited maintenance</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; 已退出维护模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5837599005212786659" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; stopped draining</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host['hostname']"/>&amp;quot; 已停止排空</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1357236071975782353" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; started draining</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host['hostname']"/>&amp;quot; 已开始排空</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5658400717636093668" datatype="html">
+ <source>Identify</source>
+ <target>身份</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6966707768479328825" datatype="html">
+ <source>Device path</source>
+ <target>设备路径</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3955868613858648955" datatype="html">
+ <source>Available</source>
+ <target>可用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="158816374076721379" datatype="html">
+ <source>Vendor</source>
+ <target>供应商</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6024104799101504292" datatype="html">
+ <source>OSDs</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3422162477846071958" datatype="html">
+ <source>Identify device <x id="PH" equiv-text="device"/></source>
+ <target>识别设备 <x id="PH" equiv-text="device"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4910073658089977244" datatype="html">
+ <source>Please enter the duration how long to blink the LED.</source>
+ <target>请输入 LED 闪烁的时长。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5764931367607989415" datatype="html">
+ <source>1 minute</source>
+ <target>1 分钟</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809466133764752509" datatype="html">
+ <source>2 minutes</source>
+ <target>2 分钟</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">235</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1487672983218679675" datatype="html">
+ <source>5 minutes</source>
+ <target>5 分钟</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603584938775296395" datatype="html">
+ <source>10 minutes</source>
+ <target>10 分钟</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6648333117195452824" datatype="html">
+ <source>15 minutes</source>
+ <target>15 分钟</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6560281329999108838" datatype="html">
+ <source>Execute</source>
+ <target>执行</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6901229416977800100" datatype="html">
+ <source>Identifying '<x id="PH" equiv-text="device"/>' started on host '<x id="PH_1" equiv-text="hostname"/>'</source>
+ <target>正在识别主机 &quot;<x id="PH_1" equiv-text="hostname"/>&quot; 上启动的 &quot;<x id="PH" equiv-text="device"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d556ab48a65722b400e497f61737f553ee0f89e2" datatype="html">
+ <source>Cluster Logs</source>
+ <target>集群日志</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5f966baffd188be0e8adc2d7067b86e55fc9b9de" datatype="html">
+ <source>Audit Logs</source>
+ <target>审计日志</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4193c9eb868aeec119b78a14795241e0aa5e8b60" datatype="html">
+ <source>Priority:</source>
+ <target>优先级:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d78ca51eab260ce3fd917d39190d64df5229b6e" datatype="html">
+ <source>Keyword:</source>
+ <target>关键字</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="05fa0bded36de6e73a1fa44838b627349dace044" datatype="html">
+ <source>Date:</source>
+ <target>日期</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a400388de1899b1917138cf7e5286376f72847" datatype="html">
+ <source>Time range:</source>
+ <target>时间范围:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="de0478286b8b5a939db54e9e5282405364ad2d61" datatype="html">
+ <source>No log entries found. Please try to select different filter options.</source>
+ <target>未找到任何日志条目。请尝试选择不同的过滤选项。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7479674d91142b785b9547a87e5fb51cb16108" datatype="html">
+ <source>Reset filter.</source>
+ <target>重置过滤器。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="31a9c2870a934b594d1390146c489f76440859ea" datatype="html">
+ <source>Edit Manager module</source>
+ <target>编辑 Manager 模块</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="46e09b8290d3d0afdb6baa2021395b0570606a31" datatype="html">
+ <source>The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</source>
+ <target>输入的值不是有效的 UUID,例如:67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7aacd038b39cfd347107d01d1dc27f5cb3e0951c" datatype="html">
+ <source>The entered value needs to be a valid IP address.</source>
+ <target>输入的值应该是有效的 IP 地址。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f19106149f4b07a0d721f9d317afed393cb7bd93" datatype="html">
+ <source>The entered value is too high! It must be lower or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>.</source>
+ <target>输入的值太大!值必须小于或等于 <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d33c40ef9a6c3bf0888df831b25e41e65f9d15b" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>.</source>
+ <target>输入的值太小!值必须大于或等于 <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eae7086660cf1e38c7194a2c49ff52cc656f90f5" datatype="html">
+ <source>The entered value needs to be a number.</source>
+ <target>输入的值应该是数字。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">194</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a73376e04b4fb3a20734c8c39743fba32e6676ce" datatype="html">
+ <source>The entered value needs to be a number or decimal.</source>
+ <target>输入的值应该是数字或小数。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1898719236268328097" datatype="html">
+ <source>Updated options for module '<x id="PH" equiv-text="this.moduleName"/>'.</source>
+ <target>已更新模块 &quot;<x id="PH" equiv-text="this.moduleName"/>&quot; 的选项。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4186041075388034600" datatype="html">
+ <source>Always-On</source>
+ <target>始终启用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7585826646011739428" datatype="html">
+ <source>Edit</source>
+ <target>编辑</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2180291763949669799" datatype="html">
+ <source>Enable</source>
+ <target>启用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9187855490716817910" datatype="html">
+ <source>Disable</source>
+ <target>禁用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1600086764852993170" datatype="html">
+ <source>This Manager module is always on.</source>
+ <target>此 Manager 模块始终处于启用状态。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3895296744591223546" datatype="html">
+ <source>Reconnecting, please wait ...</source>
+ <target>正在重新连接,请稍候...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81b97b8ea996ad1e4f9fca8415021850214884b1" datatype="html">
+ <source>Status</source>
+ <target>状态</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57ec6032f5618d4a9f16eb950ad23d2ce7c24b54" datatype="html">
+ <source>Cluster ID</source>
+ <target>集群 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67d7facc3fec5f8a49ab9ba0a245872184264ce5" datatype="html">
+ <source>monmap modified</source>
+ <target>monmap 修改时间</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4906731aaf2b94b4f547646c9bfe58bb77951b6" datatype="html">
+ <source>monmap epoch</source>
+ <target>monmap 版本编号</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd4ee06ffdc46d9dfbd0c0c4f81399021c680056" datatype="html">
+ <source>quorum con</source>
+ <target>仲裁 con</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1176c7db8a8276ccb44cc3d42e2c28d9fa6c6596" datatype="html">
+ <source>quorum mon</source>
+ <target>仲裁 mon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="530ef677a09d681b3ab68cb0760494b3ae72a77c" datatype="html">
+ <source>required con</source>
+ <target>所需 con</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a91558e0d506c32021c31843f8f168899fc65cbf" datatype="html">
+ <source>required mon</source>
+ <target>所需 mon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3abe9eac5bcd94a54c8da93b312e085ec512e74" datatype="html">
+ <source>In Quorum</source>
+ <target>仲裁成员</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba4b748a676e1f217ce1e736fb7ec1215e677bae" datatype="html">
+ <source>Not In Quorum</source>
+ <target>非仲裁成员</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3517477838460618200" datatype="html">
+ <source>Public Address</source>
+ <target>公用地址</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6949358970125514744" datatype="html">
+ <source>Open Sessions</source>
+ <target>活动会话</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4383e9662ea19839c7499b2128d43a195e564317" datatype="html">
+ <source>OSD creation preview</source>
+ <target>OSD 创建预览</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="366225c51e0b00bcb1c55795a0dc5e81c455f84e" datatype="html">
+ <source>DriveGroups</source>
+ <target>DriveGroup</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91853167141c37b58868f3b0421383dd72fa8a01" datatype="html">
+ <source>Attributes (OSD map)</source>
+ <target>属性(OSD 索引)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f721a500a68c357e8f2a01e60510f6a01e4ba529" datatype="html">
+ <source>Metadata</source>
+ <target>元数据</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97842f379e1d4157ac3ab0661b90c352e7cb72d5" datatype="html">
+ <source>Metadata not available</source>
+ <target>元数据不可用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24e28e19c5703d7c6be44f4eb595a6a43b618ed" datatype="html">
+ <source>Performance counter</source>
+ <target>性能计数器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ccb4f84edc0b4e76415bb3f9b73d725b06683af3" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ name }}"/> devices</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ name }}"/> 设备</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60cb3d01e5ddf266ecb4271007a1c3d0f3efdc22" datatype="html">
+ <source>The primary storage devices. These devices contain all OSD data.</source>
+ <target>主存储设备。这些设备包含所有 OSD 数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b432e04886d0d1fd84f740477383051f85addcf2" datatype="html">
+ <source>Write-Ahead-Log devices. These devices are used for BlueStore’s internal journal. It is only useful to use a WAL device if the device is faster than the primary device (e.g. NVME devices or SSDs). If there is only a small amount of fast storage available (e.g., less than a gigabyte), we recommend using it as a WAL device.</source>
+ <target>预写式日志设备。这些设备用于存储 BlueStore 的内部日志。仅当 WAL 设备速度快于主设备(例如 NVME 设备或 SSD)时,才适合使用 WAL 设备。如果可用的快速存储空间很少(例如不到 1 GB),我们建议将其用作 WAL 设备。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87e181ab9e8393aa5ed759dd3d53836e32c8ffe" datatype="html">
+ <source>DB devices can be used for storing BlueStore’s internal metadata. It is only helpful to provision a DB device if it is faster than the primary device (e.g. NVME devices or SSD).</source>
+ <target>DB 设备可用于存储 BlueStore 的内部元数据。仅当 DB 设备速度快于主设备(例如 NVME 设备或 SSD)时,才适合供给 DB 设备。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
+ <source>Add</source>
+ <target>添加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="99ee4faa69cd2ea8e3678c1f557c0ff1f05aae46" datatype="html">
+ <source>Clear</source>
+ <target>清除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e0fd3c7af0630f93befa6234a693a32a61084e0" datatype="html">
+ <source>Raw capacity: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></source>
+ <target>裸容量:<x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1961811273151129466" datatype="html">
+ <source>No available devices</source>
+ <target>没有可用的设备</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617271647728055571" datatype="html">
+ <source>Please add primary devices first</source>
+ <target>请先添加主设备</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6368751795251107516" datatype="html">
+ <source>Add devices by using filters</source>
+ <target>使用过滤器添加设备</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8edc89137d0d8c5667a2f03230beafae45e58429" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> devices</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> 设备</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eba28e1805b18f7c8ae2e4bc15dcf063b10b3822" datatype="html">
+ <source>At least one of these filters must be applied in order to proceed:</source>
+ <target>至少须应用以下过滤器之一才能继续:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="93389aa2fe2bea50bf89554ee51b28f87ee2fb50" datatype="html">
+ <source>Number of devices: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Raw capacity: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</source>
+ <target>设备数量:<x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>。裸容量:<x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">29,30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6b27c16ddf33b855412c82069dca8120bd3a68a" datatype="html">
+ <source>Individual OSD Flags</source>
+ <target>各 OSD 标志</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dba0ed9ba355a3bd3296c0bef3bb518744a51a89" datatype="html">
+ <source>Cluster-wide</source>
+ <target>集群范围</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e2a3f211cea2cbadb29b6df93e544440b6b68d3e" datatype="html">
+ <source>Restore previous selection</source>
+ <target>恢复先前的选择</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1683654169791509804" datatype="html">
+ <source>No Up</source>
+ <target>不启用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5754783193519044074" datatype="html">
+ <source>OSDs are not allowed to start</source>
+ <target>不允许启动 OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4413588319909369773" datatype="html">
+ <source>No Down</source>
+ <target>不停用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1348746748821823470" datatype="html">
+ <source>OSD failure reports are being ignored, such that the monitors will not mark OSDs down</source>
+ <target>当前不受理 OSD 故障报告,因此 monitor 不会将 OSD 标记为停用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="301172600132606646" datatype="html">
+ <source>No In</source>
+ <target>不加入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4114057962148673377" datatype="html">
+ <source>OSDs that were previously marked out will not be marked back in when they start</source>
+ <target>之前被标记为除名的 OSD 在启动后将不会被重新标记为加入集群</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5236523991485603657" datatype="html">
+ <source>No Out</source>
+ <target>不除名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1798160169020638994" datatype="html">
+ <source>OSDs will not automatically be marked out after the configured interval</source>
+ <target>发现 OSD 在配置的间隔时间后无响应时,该 OSD 将不会自动被标记为除名。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3225813593817914267" datatype="html">
+ <source>The flag has been enabled for the entire cluster.</source>
+ <target>已为整个集群启用该标志。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1941050626944682985" datatype="html">
+ <source>Updated OSD Flags</source>
+ <target>已更新 OSD 标志</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ef50ba2514414f799d4c8fc36067a251904ba81" datatype="html">
+ <source>Cluster-wide OSD Flags</source>
+ <target>集群范围的 OSD 标志</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9042260521669277115" datatype="html">
+ <source>Pause</source>
+ <target>暂停</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6015425610572318971" datatype="html">
+ <source>Pauses reads and writes</source>
+ <target>暂停读写</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314873595759611676" datatype="html">
+ <source>No Scrub</source>
+ <target>不洗刷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773570234687653570" datatype="html">
+ <source>Scrubbing is disabled</source>
+ <target>禁止洗刷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5999821123886006899" datatype="html">
+ <source>No Deep Scrub</source>
+ <target>不深层洗刷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5362685148875251772" datatype="html">
+ <source>Deep Scrubbing is disabled</source>
+ <target>禁止深层洗刷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5001752039592388485" datatype="html">
+ <source>No Backfill</source>
+ <target>不回填</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4851280330655956778" datatype="html">
+ <source>Backfilling of PGs is suspended</source>
+ <target>暂停 PG 回填</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5994953210305546559" datatype="html">
+ <source>No Rebalance</source>
+ <target>不重新平衡</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3698980403470604587" datatype="html">
+ <source>OSD will choose not to backfill unless PG is also degraded</source>
+ <target>OSD 将不选择回填,除非 PG 也已降级</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4334886823145076432" datatype="html">
+ <source>No Recover</source>
+ <target>不恢复</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8465994741155792816" datatype="html">
+ <source>Recovery of PGs is suspended</source>
+ <target>暂停 PG 恢复</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4052740759486923001" datatype="html">
+ <source>Bitwise Sort</source>
+ <target>逐位排序</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2330377428425572488" datatype="html">
+ <source>Use bitwise sort</source>
+ <target>使用逐位排序</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8943478424576832224" datatype="html">
+ <source>Purged Snapdirs</source>
+ <target>已清除 Snapdir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7553321860087551262" datatype="html">
+ <source>OSDs have converted snapsets</source>
+ <target>OSD 已转换 snapset</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6509988280998256208" datatype="html">
+ <source>Recovery Deletes</source>
+ <target>在恢复时执行删除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="451760144355116641" datatype="html">
+ <source>Deletes performed during recovery instead of peering</source>
+ <target>在恢复时而非对等互联期间执行删除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="87832369463084597" datatype="html">
+ <source>PG Log Hard Limit</source>
+ <target>PG 日志硬限制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9135782750879343185" datatype="html">
+ <source>Puts a hard limit on pg log length</source>
+ <target>为 pg 日志长度设置硬限制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="formTitle" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <note priority="1" from="description">Example: Create Pool</note>
+ <note priority="1" from="meaning">form title</note>
+ </trans-unit>
+ <trans-unit id="43ecf6bee2aebc07b0aad6dc1fe13e38d14687fa" datatype="html">
+ <source>Shared devices</source>
+ <target>共享设备</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7a1c376f6f1b37de4c318ff2106255ba6c0f5b0b" datatype="html">
+ <source>WAL slots</source>
+ <target>WAL 槽</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73811a6f37b63e6b0e491e221bfa21e9dea8a87a" datatype="html">
+ <source>How many OSDs per WAL device.</source>
+ <target>一个 WAL 设备对应的 OSD 数量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c67a7ac4762ef1cc855056c6b4daab93e53a0a5" datatype="html">
+ <source>Specify 0 to let Orchestrator backend decide it.</source>
+ <target>指定 0 可让 Orchestrator 后端决定数量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bda9362e06e6c67341b4a8425b0d29d6b84464b" datatype="html">
+ <source>Value should be greater than or equal to 0</source>
+ <target>值应大于或等于 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="324c2b10152b9dd908222bb0b71f61beb60a30c5" datatype="html">
+ <source>DB slots</source>
+ <target>DB 槽</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c23cf12ef9c76f37fc7a4b7ae3e00fb0f68b6e26" datatype="html">
+ <source>How many OSDs per DB device.</source>
+ <target>一个 DB 设备对应的 OSD 数量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8255877266497322342" datatype="html">
+ <source>Encryption</source>
+ <target>加密</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b49d7877d24112d4bdfce9256edf61a007fae888" datatype="html">
+ <source>OSDs List</source>
+ <target>OSD 列表</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="172ada0fcf6490b24a897517e9f4299215873ff8" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD(s) <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be marked <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <target>如果继续,<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> 将被标记为<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">59,60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="262a49e60d5f6ed9825582ccf3d5ae39daa1da60" datatype="html">
+ <source>The <x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> not safe to be <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>! <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></source>
+ <target><x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>是不安全操作!<x id="INTERPOLATION_1" equiv-text="{{ message }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71,72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="74bd20d5f558d14cb2fa41ae863cf09c47d02018" datatype="html">
+ <source>{VAR_SELECT, select, true {OSD is} other {OSDs are}}</source>
+ <target>{VAR_SELECT, select, true {OSD} other {OSD}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0e217fd717c5b1f5c17f00c5b174de855acbef0" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <target>如果继续,<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> 将会<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">74,75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8cf121660bed7098516a1efe85831d6f415a9411" datatype="html">
+ <source>Preserve OSD ID(s) for replacement.</source>
+ <target>保留 OSD ID 以便替换。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4435645098786961170" datatype="html">
+ <source>out</source>
+ <target>除名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136018875175606726" datatype="html">
+ <source>in</source>
+ <target>加入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1301930865667956193" datatype="html">
+ <source>down</source>
+ <target>停用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1226060325201042854" datatype="html">
+ <source>Mark</source>
+ <target>标记</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1256299033316818951" datatype="html">
+ <source>OSD lost</source>
+ <target>OSD 丢失</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2795727560928976873" datatype="html">
+ <source>marked lost</source>
+ <target>已标记为丢失</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7685933846431786388" datatype="html">
+ <source>Purge</source>
+ <target>清除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5941516286393808546" datatype="html">
+ <source>OSD</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3416443212235382421" datatype="html">
+ <source>purged</source>
+ <target>已清除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9191368063029792986" datatype="html">
+ <source>destroy</source>
+ <target>销毁</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4425946029386289247" datatype="html">
+ <source>destroyed</source>
+ <target>已销毁</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2870788902465061969" datatype="html">
+ <source>Flags</source>
+ <target>标志</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8995035642420075344" datatype="html">
+ <source>Recovery Priority</source>
+ <target>恢复优先级</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3601135996773579607" datatype="html">
+ <source>PG scrub</source>
+ <target>PG 洗刷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136079353894161076" datatype="html">
+ <source>Device class</source>
+ <target>设备类型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6382718875453721838" datatype="html">
+ <source>PGs</source>
+ <target>PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3660230483843323377" datatype="html">
+ <source>Read bytes</source>
+ <target>读字节数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">329</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3909578649547040612" datatype="html">
+ <source>Write bytes</source>
+ <target>写字节数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3182358405280886750" datatype="html">
+ <source>Read ops</source>
+ <target>读操作数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171292502535561083" datatype="html">
+ <source>Write ops</source>
+ <target>写操作数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6706824709967518168" datatype="html">
+ <source>Edit OSD: <x id="PH" equiv-text="selectedOsd.id"/></source>
+ <target>编辑 OSD:<x id="PH" equiv-text="selectedOsd.id"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">451</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1125148356983553148" datatype="html">
+ <source>Edit OSD</source>
+ <target>编辑 OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="970212458427610374" datatype="html">
+ <source>Updated OSD '<x id="PH" equiv-text="selectedOsd.id"/>'</source>
+ <target>已更新 OSD &quot;<x id="PH" equiv-text="selectedOsd.id"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">466</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7554728686176829307" datatype="html">
+ <source>Mark OSD <x id="PH" equiv-text="markAction"/></source>
+ <target>将 OSD 标记为<x id="PH" equiv-text="markAction"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="478122291463667978" datatype="html">
+ <source>Mark <x id="PH" equiv-text="markAction"/></source>
+ <target>标记为<x id="PH" equiv-text="markAction"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">502</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2456043080471762298" datatype="html">
+ <source>delete</source>
+ <target>删除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">530</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="588230151780724018" datatype="html">
+ <source>deleted</source>
+ <target>已删除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">532</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1ef1c12ddcee305353623919ef02778569f5454" datatype="html">
+ <source>Advanced configuration options</source>
+ <target>高级配置选项</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7771252117308888928" datatype="html">
+ <source>PG scrub options</source>
+ <target>PG 洗刷选项</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1797901277775175680" datatype="html">
+ <source>Updated PG scrub options</source>
+ <target>已更新 PG 洗刷选项</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c35f9c5f268a514b970cc55e9a5dc4bed0988e7f" datatype="html">
+ <source>OSD Recovery Priority</source>
+ <target>OSD 恢复优先级</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74af38005e8a8914e45af2ec412e11ceafef8b6" datatype="html">
+ <source>Priority</source>
+ <target>优先级</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f48f04b379bfba133825747adfd238d511412e" datatype="html">
+ <source>Customize priority values</source>
+ <target>自定义优先级值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aa19de2a2b54cbda39e9c62917b23044c087776" datatype="html">
+ <source>This field is required!</source>
+ <target>这是必填字段!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">406</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b699e94bf376491bd50b70a98531071c737eaf40" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="98fe13e7ad6c2b80375d204b47858ded83f80e15" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>.</source>
+ <target>输入的值太大!值不得大于 <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423a3c111be47fc5a1bfe46ceb58c81c84db691" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>.</source>
+ <target>输入的值太小!值不得小于 <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3234179038052466481" datatype="html">
+ <source>Max Backfills</source>
+ <target>最大回填量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847070960491384020" datatype="html">
+ <source>Recovery Max Active</source>
+ <target>最大活跃恢复请求数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2088615724570210504" datatype="html">
+ <source>Recovery Max Single Start</source>
+ <target>最大单次恢复操作数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8627094894361422565" datatype="html">
+ <source>Recovery Sleep</source>
+ <target>恢复/回填操作间隔睡眠时间</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7590013429208346303" datatype="html">
+ <source>Custom</source>
+ <target>自定义</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4937275625032609020" datatype="html">
+ <source>Updated OSD recovery speed priority '<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>'</source>
+ <target>已更新 OSD 恢复速度优先级 &quot;<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">227,229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5251a4355cece3075db43f15d69a24a0f8485707" datatype="html">
+ <source>Reweight OSD: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></source>
+ <target>重设 OSD 的权重:<x id="INTERPOLATION" equiv-text="{{ osdId }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67650b2998db48201b2c6176cbfef51e7211ccaa" datatype="html">
+ <source>The value needs to be between 0 and 1.</source>
+ <target>值应介于 0 到 1 之间。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f077ceb52c967a8fe2de9ef0a9d65d72badf186" datatype="html">
+ <source>OSDs <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/>Scrub</source>
+ <target>OSD <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/>洗刷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b73a34ba65b3073e3560dce828a16d7fd3c0f4" datatype="html">
+ <source>{VAR_SELECT, select, true {Deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {深层} other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c00119503aad4012b77049eee41293338f67756c" datatype="html">
+ <source>You are about to apply a <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/>scrub to the OSD(s): <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <target>您即将对以下 OSD 应用<x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/>洗刷:<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fad3dc421817a16dd6c46c1a0c36de619a8d776e" datatype="html">
+ <source>{VAR_SELECT, select, true {deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {深层} other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1086427836866943370" datatype="html">
+ <source><x id="PH" equiv-text="operation"/> was initialized in the following OSD(s): <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></source>
+ <target>已在下列 OSD 中初始化 <x id="PH" equiv-text="operation"/>:<x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts</context>
+ <context context-type="linenumber">42,44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47c97aa28f64b11fa5842795fdd02c8c0863c97b" datatype="html">
+ <source>To see all active Prometheus alerts, please provide the URL to the API of Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>要查看所有活动的 Prometheus 告警,请按 <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> 中所述向 Prometheus 告警管理器 API 提供 URL。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6343323763459782070" datatype="html">
+ <source>Create Silence</source>
+ <target>创建静默</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1895957424873987405" datatype="html">
+ <source>Job</source>
+ <target>任务</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491474782694268231" datatype="html">
+ <source>Severity</source>
+ <target>严重程度</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3326877877555410533" datatype="html">
+ <source>Started</source>
+ <target>已启动</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2375260419993138758" datatype="html">
+ <source>URL</source>
+ <target>URL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="880ad4df5a2051a437321443d69c9a866699e5ad" datatype="html">
+ <source>Active Alerts</source>
+ <target>活动告警</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9fe218829514884cdd0ca2300573a4e0428c324f" datatype="html">
+ <source>Alerts</source>
+ <target>警告</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa0c44aa1e5727061baa91e954f77e2f5f9a37c9" datatype="html">
+ <source>Silences</source>
+ <target>静默</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85c737325f5e59517e2d08a71de6d77788aabc95" datatype="html">
+ <source>To see all configured Prometheus alerts, please provide the URL to the API of Prometheus as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>要查看所有已配置的 Prometheus 告警,请按 <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> 中所述向 Prometheus 的 API 提供 URL。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623978917681527907" datatype="html">
+ <source>Group</source>
+ <target>组</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7410432243549869948" datatype="html">
+ <source>Duration</source>
+ <target>时长</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4109205891084963566" datatype="html">
+ <source>Query</source>
+ <target>查询</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28f86ffd419b869711aa13f5e5ff54be6d70731c" datatype="html">
+ <source>Edit</source>
+ <target>编辑</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="826b25211922a1b46436589233cb6f1a163d89b7" datatype="html">
+ <source>Delete</source>
+ <target>删除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">279</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">341</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">441</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3ba06aba047605af8ea1718ec1ba153b7db12a2" datatype="html">
+ <source>Editing a silence will expire the old silence and recreate it as a new silence</source>
+ <target>编辑静默将会使旧静默过期并将其重新创建为新静默</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a20424156b8816671f61879f0574a4f27d7b16b9" datatype="html">
+ <source>Creator</source>
+ <target>创建者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5a5d7ee2acbfa9c91ab7f41d26bda9ff0cafe42f" datatype="html">
+ <source>Comment</source>
+ <target>注释</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c11aad490b2d53fdae30b3807beabf79306752c" datatype="html">
+ <source>Start time</source>
+ <target>开始时间</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32856b1e8e339b747b21e313e2fe65a51fd450bb" datatype="html">
+ <source>If the start time lies in the past the creation time will be used</source>
+ <target>如果开始时间为过去时间,将使用创建时间</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a02ea1d4e7424ca989929da5e598f379940fdbf2" datatype="html">
+ <source>Duration</source>
+ <target>时长</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f4e35e36f4d3c62e2c17df41730b6dee4afc4b9" datatype="html">
+ <source>End time</source>
+ <target>结束时间</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="992123459137d45c15df5548bc9682aad835c04b" datatype="html">
+ <source>Matchers</source>
+ <target>匹配器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e023166c55833d5a13f4143e3dbe372befe1b4e" datatype="html">
+ <source>A silence requires at least one matcher</source>
+ <target>一个静默至少需要一个匹配器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef765bd80c4806c51c891908c07a24bc76f019eb" datatype="html">
+ <source>Add matcher</source>
+ <target>添加匹配器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754178820914251524" datatype="html">
+ <source>silence</source>
+ <target>静默</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8714559758543060819" datatype="html">
+ <source>Attribute name</source>
+ <target>属性名称</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1338733395833138319" datatype="html">
+ <source>Regular expression</source>
+ <target>正则表达式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35819898450851998" datatype="html">
+ <source>Please add your Prometheus host to the dashboard configuration and refresh the page</source>
+ <target>请将您的 Prometheus 主机添加到仪表盘配置中,然后刷新页面</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f2f4cb9d876ff9d34fc082c1ac642d3cb98c360" datatype="html">
+ <source>To enable Silences, please provide the URL to the API of the Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>要启用 &quot;静默&quot;,请按 <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> 中所述向 Prometheus 告警管理器 API 提供 URL。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7448808151142843482" datatype="html">
+ <source>Created by</source>
+ <target>创建者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4734349318830134239" datatype="html">
+ <source>Ends</source>
+ <target>结束</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1233087251567318644" datatype="html">
+ <source>Silence</source>
+ <target>静默</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="78af6a5e6e4d305557054b64d10f9f9446d8043d" datatype="html">
+ <source>{VAR_SELECT, select, true {Edit} other {Add}}</source>
+ <target>{VAR_SELECT, select, true {编辑} other {添加}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2404fa8e80946d0ce3d0ae369b51cb26ec28d42" datatype="html">
+ <source><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/> Matcher</source>
+ <target><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/>匹配器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c25e04f554875dc2625a78ba0fc56c6010cd0d3" datatype="html">
+ <source>-- Select an attribute to match against --</source>
+ <target>--请选择要匹配的属性--</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5049e204c14c648691ac775a64fb504467aeb549" datatype="html">
+ <source>Value</source>
+ <target>值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="77fc5c63497fc031ddc97645484e3d94ad27766c" datatype="html">
+ <source>Use regular expression</source>
+ <target>使用正则表达式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5518753745858598442" datatype="html">
+ <source>no spec</source>
+ <target>无规范</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1186363766752354382" datatype="html">
+ <source>unmanaged</source>
+ <target>非受管</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5246585784774990516" datatype="html">
+ <source>count:<x id="PH" equiv-text="count"/></source>
+ <target>计数:<x id="PH" equiv-text="count"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001661117318762535" datatype="html">
+ <source>label:<x id="PH" equiv-text="label"/></source>
+ <target>标签:<x id="PH" equiv-text="label"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cb3aa7e9fea1d445a1a9d7797ab17e6ac6fe13b" datatype="html">
+ <source>Service Events</source>
+ <target>服务事件</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3474944817987674409" datatype="html">
+ <source>Daemon type</source>
+ <target>守护进程类型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3136939605470297323" datatype="html">
+ <source>Daemon ID</source>
+ <target>守护进程 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8171022601808215887" datatype="html">
+ <source>Container ID</source>
+ <target>容器 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8859473568390700297" datatype="html">
+ <source>Container Image name</source>
+ <target>容器映像名称</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5623167616584404899" datatype="html">
+ <source>Container Image ID</source>
+ <target>容器映像 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="335348913532561915" datatype="html">
+ <source>Last Refreshed</source>
+ <target>上次刷新</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3022087209429182774" datatype="html">
+ <source>Daemon Events</source>
+ <target>守护进程事件</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">140</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8604852007710946848" datatype="html">
+ <source>Service Name</source>
+ <target>服务名称</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="613875387304159316" datatype="html">
+ <source>Service Type</source>
+ <target>服务类型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907644935670421963" datatype="html">
+ <source>Service Events</source>
+ <target>服务事件</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3214a1f3a4c3e89a848b4ec59adeeda3b913c396" datatype="html">
+ <source>-- Select a service type --</source>
+ <target>-- 请选择服务类型 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f32579a9fd19d93c083175284ee3426d78751c33" datatype="html">
+ <source>Backend Service</source>
+ <target>后端服务</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2937074aed12b8158e929c58747a8216433b72b" datatype="html">
+ <source>-- No service available --</source>
+ <target>-- 没有可用的服务 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19fb4480d95a5539db4e9c7b516d414774e61110" datatype="html">
+ <source>-- Select an existing RGW service --</source>
+ <target>-- 请选择现有 RGW 服务 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2798cc1e152b1ec07fd8daf94a2a073d1ba1ebcc" datatype="html">
+ <source>Id</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d5156b9d9a79d162c353c4aa9bc6840ad5c6257" datatype="html">
+ <source>The value does not match the pattern <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&lt;service_id&gt;[.&lt;realm_name&gt;.&lt;zone_name&gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <target>该值与模式 <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&amp;lt;service_id&amp;gt;[.&amp;lt;realm_name&amp;gt;.&amp;lt;zone_name&amp;gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> 不匹配。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83d5d7edd8a0be253c4e93ad4c3efe86d9ac520f" datatype="html">
+ <source>Unmanaged</source>
+ <target>非受管</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c15fa461935e0f600bc5d1660af1da67f024fc2a" datatype="html">
+ <source>Placement</source>
+ <target>归置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="863226cffd5b66a6fee9810a9282a5006d6ef576" datatype="html">
+ <source>Label</source>
+ <target>标签</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06412bce0f4fe4311193e9763666089bf9d980da" datatype="html">
+ <source>Count</source>
+ <target>计数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f193722f1e788f14a823b89ac1794c3ba934f9f" datatype="html">
+ <source>Only that number of daemons will be created.</source>
+ <target>系统将只创建该数量的守护进程。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee1a29cc658e4fa891be762d7bae96139b57c8f4" datatype="html">
+ <source>The value must be at least 1.</source>
+ <target>值必须至少为 1。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">369</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cb2741a46e3560f6bc6dfd99d385e86b08b26d72" datatype="html">
+ <source>Port</source>
+ <target>端口</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a23ed3598cca5285606675b6cb2536a56b411ade" datatype="html">
+ <source>The value cannot exceed 65535.</source>
+ <target>值不得超过 65535。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">404</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d8ebdc326e6b9ff35feee3f762b7ab39c02d78f" datatype="html">
+ <source>-- No pools available --</source>
+ <target>-- 没有可用的存储池 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84b675705324741b954615fedf2417d4d873b0b6" datatype="html">
+ <source>Trusted IPs</source>
+ <target>可信 IP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b543e7c787cc48c2938cbce2d14c6afea5a598df" datatype="html">
+ <source>Comma separated list of IP addresses.</source>
+ <target>IP 地址逗号分隔列表。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1039ea40da18a6453d9c1adc72a35aed099029d0" datatype="html">
+ <source>Please add the <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> IP addresses here, otherwise the iSCSI gateways can't be reached.</source>
+ <target>请在此处添加 <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> IP 地址,否则将无法连接到 iSCSI 网关。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6265b64c17a1e19775769489bfd0b152fa1f3ba1" datatype="html">
+ <source>Virtual IP</source>
+ <target>虚拟 IP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61893fde6e9e05a6b91619d501edaa7962b438ff" datatype="html">
+ <source>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</source>
+ <target>可以使用入站服务的虚拟 IP 地址和子网(采用 CIDR 表示法)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">333</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ece04ddf7e96f445415ebd90d93c455e03e8cf53" datatype="html">
+ <source>Frontend Port</source>
+ <target>前端端口</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">352</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae6fd97454d184b374984c9ff808176ece54f0dd" datatype="html">
+ <source>The port used to access the ingress service.</source>
+ <target>用于访问入站服务的端口。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1261eacf161f75efc9dfea84dd97b4a466b89aa1" datatype="html">
+ <source>Monitor Port</source>
+ <target>Monitor 端口</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4df6281ed630ba96f09790a46a7fe0ec0e666bb6" datatype="html">
+ <source>The port used by haproxy for load balancer status.</source>
+ <target>HAProxy 用于获取负载平衡器状态的端口。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ce24ae1d792ed2846ba57e7ed6397a802caeff5" datatype="html">
+ <source>CIDR Networks</source>
+ <target>CIDR 网络</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">414</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7c13184af0c09e3bad77daa5f4869138708d26b2" datatype="html">
+ <source>A list of networks to identify which network interface to use for the virtual IP address.</source>
+ <target>用于标识虚拟 IP 地址所用网络接口的网络列表。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8fe73a4787b8068b2ba61f54ab7e0f9af2ea1fc9" datatype="html">
+ <source>Version</source>
+ <target>版本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a6855d17f6b9820bb9709870efdcc7da99552d3" datatype="html">
+ <source>-- Select SNMP version --</source>
+ <target>-- 请选择 SNMP 版本 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">442</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a7369891e88cd613e45a39b55a282c97776d05f5" datatype="html">
+ <source>Destination</source>
+ <target>目标</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f09a5d334a73a4b5ba031d7fa65151cad5ec7133" datatype="html">
+ <source>Must be of the format hostname:port.</source>
+ <target>必须采用 &quot;主机名:端口&quot; 格式。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b68c79ffe3af1db88180454fbc2fa880a51ccf52" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>hostname:port<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>该值与模式<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>主机名:端口<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>不匹配</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">470</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c90ad98a026d781ab729911873767e549d78f99" datatype="html">
+ <source>Engine Id</source>
+ <target>引擎 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">478</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d39d015ebd667fb6bddf08bb0e5b3faa6cf044c" datatype="html">
+ <source>Unique identifier for the device (in hex).</source>
+ <target>设备的唯一标识符(采用十六进制)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">480</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514cda7dc49062c5c532427245ce47c4954bc32" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>该值与以下模式不匹配:<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>必须为十六进制且长度必须为 2 的倍数,最小值为 10,最大值为 64<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> 。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b2d628c51192ade0044212b409c758c20f9c021" datatype="html">
+ <source>Auth Protocol</source>
+ <target>身份验证协议</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc8bb2315a5101770a752b18e03b5c730539397c" datatype="html">
+ <source>-- Select auth protocol --</source>
+ <target>-- 请选择身份验证协议 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">508</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6777f99fd13e03874afe26ba7289dc9fc211af04" datatype="html">
+ <source>Privacy Protocol</source>
+ <target>隐私协议</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70512b7c13bce85b3928920b29fafbd59a853383" datatype="html">
+ <source>-- Select privacy protocol --</source>
+ <target>-- 请选择隐私协议 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b48c81465d14465b95826b99e05acfabef1814c6" datatype="html">
+ <source>Credentials</source>
+ <target>身份凭证</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">541</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4ea0163c25c818aab982072b1b8d5ab585e9a5a" datatype="html">
+ <source>SNMP Community</source>
+ <target>SNMP 社区</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">547</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="08c74dc9762957593b91f6eb5d65efdfc975bf48" datatype="html">
+ <source>Username</source>
+ <target>用户名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="948758e1412bb2ecdb98e3a4f1cbb6d7458456f2" datatype="html">
+ <source>Encryption</source>
+ <target>加密</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">598</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e65610b5d940367f1ff6b57772b96e94e35fe202" datatype="html">
+ <source>SSL</source>
+ <target>SSL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">624</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e37e0d06148c7708e88b4a1eb412babbe1a4afc" datatype="html">
+ <source>Certificate</source>
+ <target>证书</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">634</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="295ae4f632322098deca8a3ddfbc7aeaabb5423b" datatype="html">
+ <source>The SSL certificate in PEM format.</source>
+ <target>PEM 格式的 SSL 证书。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">635</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464272c069fe56f6c50f41f426a25b2a42c95ba5" datatype="html">
+ <source>Invalid SSL certificate.</source>
+ <target>SSL 证书无效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">650</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0596d06bf1f8a15d4bfe56226971ecdd78013b1f" datatype="html">
+ <source>Private key</source>
+ <target>私用密钥</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">659</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ded15dc55104994c0230189f34dff84a4955aafb" datatype="html">
+ <source>The SSL private key in PEM format.</source>
+ <target>PEM 格式的 SSL 私用密钥。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">660</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19bdc1597d815b456793ff87c89af4257a85a103" datatype="html">
+ <source>Invalid SSL private key.</source>
+ <target>SSL 私用密钥无效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">675</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3356018487523380058" datatype="html">
+ <source>service</source>
+ <target>服务</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2412938991511187011" datatype="html">
+ <source>There are no hosts.</source>
+ <target>没有主机。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2594503755408511486" datatype="html">
+ <source>Filter hosts</source>
+ <target>过滤主机</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5869780110608474933" datatype="html">
+ <source>Placement</source>
+ <target>归置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2956098160626271284" datatype="html">
+ <source>Running</source>
+ <target>正在运行</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="013f48ee777d2e53e2bcba36e1a99fcbb7ef8cb6" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report configuration</source>
+ <target>第 <x id="INTERPOLATION" equiv-text="{{ step }}"/> 步(共 2 步):遥测报告配置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a09b723a928774bff707973c99999dcf3d84a349" datatype="html">
+ <source>The telemetry module sends anonymous data about this Ceph cluster back to the Ceph developers to help understand how Ceph is used and what problems users may be experiencing.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> This data is visualized on <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>public dashboards<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> that allow the community to quickly see summary statistics on how many clusters are reporting, their total capacity and OSD count, and version distribution trends.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> The data being reported does <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>not<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> contain any sensitive data like pool names, object names, object contents, hostnames, or device serial numbers. It contains counters and statistics on how the cluster has been deployed, the version of Ceph, the distribution of the hosts and other parameters which help the project to gain a better understanding of the way Ceph is used. The data is sent secured to <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> and <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (device report).</source>
+ <target>遥测模块会将有关此 Ceph 集群的匿名数据发回给 Ceph 开发人员,以帮助其了解 Ceph 的使用情况,以及用户可能遇到了什么问题。<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/>这些数据直观呈现在<x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>公共仪表盘<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>上,社区可通过该仪表盘迅速了解以下汇总统计信息:所报告的集群数量,集群的总容量和 OSD 计数,以及版本分发趋势。<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/>报告的数据<x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>不<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/>包含存储池名称、对象名称、对象内容、主机名或设备序列号等任何敏感数据。它包含有关以下信息的计数器和统计数据: 集群的部署方式、Ceph 版本、主机分布,以及有助于项目更好地了解 Ceph 使用情况的其他参数。这些数据会以安全方式发送至 <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> 和 <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/>(设备报告)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">14,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c95505b5a74151a0c235b19b9c41db7983205ba7" datatype="html">
+ <source>Deactivate</source>
+ <target>停用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19" datatype="html">
+ <source>Channels</source>
+ <target>通道</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e25b17c0b4ef361b6a05aaec2bbd2b7e86680458" datatype="html">
+ <source>The telemetry report is broken down into several &quot;channels&quot;, each with a different type of information that can be configured below.</source>
+ <target>遥测报告细分为数个 &quot;通道&quot;,每个通道包含不同类型的信息,您可以在下面进行配置。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">32,33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380ab580741bec31346978e7cab8062d6970408d" datatype="html">
+ <source>Basic</source>
+ <target>基本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd898057f0add35258a5fb5c90d792c5e2147452" datatype="html">
+ <source>Includes basic information about the cluster:</source>
+ <target>包含有关集群的基本信息:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da213e9ba8a86b453d04f794f58c9803f7b062b1" datatype="html">
+ <source>Capacity of the cluster</source>
+ <target>集群容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d5fe31d9e13239bdd223d0bbd289a1b1903e86" datatype="html">
+ <source>Number of monitors, managers, OSDs, MDSs, object gateways, or other daemons</source>
+ <target>Monitor、Manager、OSD、MDS、对象网关或其他守护进程的数量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a3eb7834b4baf412f8863d14883972897d9acb7" datatype="html">
+ <source>Software version currently being used</source>
+ <target>当前所使用的软件版本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34881ae65482ffa74ccb4043fb2622e48ed146d5" datatype="html">
+ <source>Number and types of RADOS pools and CephFS file systems</source>
+ <target>RADOS 存储池和 CephFS 文件系统的数量及类型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="696f8f5ea7a9cf6125b9a3af160981fda363552d" datatype="html">
+ <source>Names of configuration options that have been changed from their default (but not their values)</source>
+ <target>默认值被更改的配置选项的名称(而不是其值)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34292940316300d09abe5e675d452fae199f626b" datatype="html">
+ <source>Crash</source>
+ <target>崩溃</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7620e332b7dea1e832158e85847255eb4d9e6bbc" datatype="html">
+ <source>Includes information about daemon crashes:</source>
+ <target>包含有关守护进程崩溃的信息:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1aa4306a6e840fe35b70c9b07d38ce85f281cfa" datatype="html">
+ <source>Type of daemon</source>
+ <target>守护进程类型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4f2cbedb4b14b68bc9f390e3391445c1b6682da" datatype="html">
+ <source>Version of the daemon</source>
+ <target>守护进程版本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d62603cdc75645ea873fc8f7f69c32b5f4a2aa9" datatype="html">
+ <source>Operating system (OS distribution, kernel version)</source>
+ <target>操作系统(操作系统发行套件、内核版本)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84facf84a73631d66e9a4e0bc1c40097b9d14742" datatype="html">
+ <source>Stack trace identifying where in the Ceph code the crash occurred</source>
+ <target>标识 Ceph 代码中发生崩溃的位置的堆栈跟踪</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea64d4177bd648e1a20c92669e6857762b811d8c" datatype="html">
+ <source>Device</source>
+ <target>设备</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4bc37bcbbcea881a269b4063b3d93dec8ee67d5" datatype="html">
+ <source>Includes information about device metrics like anonymized SMART metrics.</source>
+ <target>包含有关设备度量(如匿名 SMART 度量)的信息。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37de70e8ba539187d0171a38dad2a63c323096eb" datatype="html">
+ <source>Ident</source>
+ <target>身份</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b126025440f118cd02ce78362d61a5001c27617" datatype="html">
+ <source>Includes user-provided identifying information about the cluster:</source>
+ <target>包含用户提供的关于集群的标识信息:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62c6e9aecff7e04ef7d36fdee4ab4fb285a7a2b5" datatype="html">
+ <source>Contact Information</source>
+ <target>联系信息</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61ba9a84051b3f470122e59cf5a746552b378269" datatype="html">
+ <source>Submitting any contact information is completely optional and disabled by default.</source>
+ <target>提交任何联系信息完全是可选操作,默认已被禁用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34746fb1c7f3d2194d99652bdff89e6e14c9c4f4" datatype="html">
+ <source>Contact</source>
+ <target>联系</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="632cac1e025b77b2d77fed16ad22a410ddacab9e" datatype="html">
+ <source>My first Ceph cluster</source>
+ <target>我的首个 Ceph 集群</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3a58c8a81b9ffda26a154eae25a422c9f7de37b" datatype="html">
+ <source>Organization</source>
+ <target>组织</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e8fda44e2c5bb51860f26cd9c2730f9ae1db9869" datatype="html">
+ <source>Organization name</source>
+ <target>组织名称</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d49310535abb3792d8c9c991dd0d990d73d29af" datatype="html">
+ <source>Interval</source>
+ <target>间隔</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91317562c9dfefbdd5973faf11d217f571d073c7" datatype="html">
+ <source>The module compiles and sends a new report every 24 hours by default. You can adjust this interval by setting a different number of hours.</source>
+ <target>模块默认每 24 小时编译并发送一次新报告。您可以设置不同的小时数以调整此间隔。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">185,186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a12cf4cf71ef3161a024382ab542cf0eba094504" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to 8.</source>
+ <target>输入的值过小!值必须大于或等于 8。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a92e437fac14b4010c4515b31c55a311d026a57f" datatype="html">
+ <source>Proxy</source>
+ <target>代理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6de03357358c7eff62aca486508bb5c2046e0669" datatype="html">
+ <source>If the cluster cannot directly connect to the configured telemetry endpoint (default telemetry.ceph.com), you can configure a HTTP/HTTPS proxy server by e.g. adding https://10.0.0.1:8080</source>
+ <target>如果集群无法直接连接到配置的遥测端点(默认为 telemetry.ceph.com),您可以配置 HTTP/HTTPS 代理服务器,例如,通过添加 https://10.0.0.1:8080 来配置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5687a733af051bfca97dbffba282e39fbb9b8c8f" datatype="html">
+ <source>You can also include a user:pass if needed e.g. https://ceph:telemetry@10.0.0.1:8080</source>
+ <target>如果需要,您还可以包含 user:pass,例如 https://ceph:telemetry@10.0.0.1:8080</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e6430c68df43ea65e4145972b01186fba40f26a" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Note:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> By clicking 'Next' you will first see a preview of the report content before you can activate the automatic submission of your data.</source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>注意:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/>点击 &quot;下一步&quot; 后,您首先会看到报告内容预览,然后才能激活数据的自动提交功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">219,220</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d8d878f8d60905e1306c225716305a331b784c8" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report preview</source>
+ <target>第 <x id="INTERPOLATION" equiv-text="{{ step }}"/> 步(共 2 步):遥测报告预览</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e23d0064b6474f309c74e1c928cc0920f479d9a5" datatype="html">
+ <source>Report ID <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <target>报告 ID <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">249,252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4060e92658964e356a0992a900c8aa811c2cfec0" datatype="html">
+ <source>A randomized UUID to identify a particular cluster over the course of several telemetry reports.</source>
+ <target>随机分配的 UUID,用于在数个遥测报告中标识特定的集群。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60900bc663571f852a04950a123508b106d97204" datatype="html">
+ <source>Report preview <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <target>报告预览 <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">267,270</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3de417f739c336284c42904552e81e8d852daecc" datatype="html">
+ <source>The actual telemetry data that will be submitted.</source>
+ <target>将要提交的实际遥测数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="933a2b6f087670ff42c95876e6ecfb2faa3e3867" datatype="html">
+ <source>I agree to my telemetry data being submitted under the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Community Data License Agreement - Sharing - Version 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></source>
+ <target>我同意根据<x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>社区数据许可协议 - 共享 - 1.0 版本<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>提交我的遥测数据</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">304</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8293060085588842566" datatype="html">
+ <source>The Telemetry module has been configured and activated successfully.</source>
+ <target>已成功配置并激活遥测模块。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5380636888677486786" datatype="html">
+ <source>An Error occurred while updating the Telemetry module configuration. Please Try again</source>
+ <target>更新遥测模块配置时发生错误。请重试</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2bcd3296d2850de762fb943060b7e086a893181" datatype="html">
+ <source>Health</source>
+ <target>健康状况</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61e0f26d843eec0b33ff475e111b0c2f7a80b835" datatype="html">
+ <source>Statistics</source>
+ <target>统计数据</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73caac4265ea7314ff061e5a1d78a6361a6dd3b8" datatype="html">
+ <source>Cluster Status</source>
+ <target>集群状态</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="624f596cc3320f5e0a0d7c7346c364e5af9bdd8c" datatype="html">
+ <source>Monitors</source>
+ <target>Monitor</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9183778f2c6473d7ccb080f651caa01faaf70c" datatype="html">
+ <source>OSDs</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c34287a0423968dac8a41463b80855a0ff789403" datatype="html">
+ <source>Managers</source>
+ <target>Manager</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="946ac5dea9921dc09d7b0a63b89535371f283b19" datatype="html">
+ <source>Object Gateways</source>
+ <target>对象网关</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff03fa5bcf37c4da46ad736c1f7d03f959e8ba9a" datatype="html">
+ <source>Metadata Servers</source>
+ <target>元数据服务器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d817609ba4993eba859409ab71e566168f4d5f5a" datatype="html">
+ <source>iSCSI Gateways</source>
+ <target>iSCSI 网关</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ce9dfdc6dccb28dc75a78c704e09dc18fb02dcfa" datatype="html">
+ <source>Capacity</source>
+ <target>容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f383269db2d32cccee9e936fe549dccb9fdbf4" datatype="html">
+ <source>Raw Capacity</source>
+ <target>裸容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498a109c6e9e94f1966de01aa0326f7f0ac6fb52" datatype="html">
+ <source>PG Status</source>
+ <target>PG 状态</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5f8a813f91a11af99132e4beafc136cfc13d73b" datatype="html">
+ <source>PGs per OSD</source>
+ <target>每个 OSD 的 PG 数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32efd1c3f70e3c5244239de97a2cc95d98534a14" datatype="html">
+ <source>Client Read/Write</source>
+ <target>客户端读/写</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="52213660b2454d139ada3079a42ec6caf3c3c01e" datatype="html">
+ <source>Client Throughput</source>
+ <target>客户端吞吐量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="275485415092cbae3a9f3cbb786ebe283cacfdd5" datatype="html">
+ <source>Recovery Throughput</source>
+ <target>恢复吞吐量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35416fcdf9cb33d2b299d3f2028c390454b55d02" datatype="html">
+ <source>Scrubbing</source>
+ <target>正在洗刷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="44ecac93d67c6a671198091c2270354f80322327" datatype="html">
+ <source><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> See <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>Logs<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for more details.</source>
+ <target><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/>请参见<x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>日志<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>了解更多详情。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520247697658334435" datatype="html">
+ <source>Reads</source>
+ <target>读取次数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5947645586591788199" datatype="html">
+ <source>/s</source>
+ <target>/s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7527163811128350993" datatype="html">
+ <source>Writes</source>
+ <target>写入次数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7684088941299429132" datatype="html">
+ <source>IOPS</source>
+ <target>IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81585474102700882" datatype="html">
+ <source>Used</source>
+ <target>已使用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">179</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8695656831075719969" datatype="html">
+ <source>Avail.</source>
+ <target>可用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6352596107300820129" datatype="html">
+ <source>Clean</source>
+ <target>正常</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4016774570903735270" datatype="html">
+ <source>Working</source>
+ <target>运行中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4467323362722952678" datatype="html">
+ <source>Unknown</source>
+ <target>未知</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">218</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7790772795962334429" datatype="html">
+ <source>Healthy</source>
+ <target>运行状况良好</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4708847204147472247" datatype="html">
+ <source>Misplaced</source>
+ <target>位置不正确</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3120522496446378904" datatype="html">
+ <source>Degraded</source>
+ <target>已降级</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8047698491745405137" datatype="html">
+ <source>Unfound</source>
+ <target>未找到</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81117556780777231" datatype="html">
+ <source>objects</source>
+ <target>对象</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795e8a00db46b750113d5db93e8d97e2b3079894" datatype="html">
+ <source>For an overview of <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/> widgets click <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></source>
+ <target>有关 <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/> 控件概览,请点击<x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">21,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16bd21c1b48036d54c6a595f5cff2540cfba7f60" datatype="html">
+ <source>here</source>
+ <target>此处</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8515973702474791807" datatype="html">
+ <source>up</source>
+ <target>启用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4223604072115719661" datatype="html">
+ <source>no filesystems</source>
+ <target>无文件系统</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2078241808113697591" datatype="html">
+ <source>active</source>
+ <target>活跃</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3232506912392089107" datatype="html">
+ <source>standby</source>
+ <target>待机</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576716133013765863" datatype="html">
+ <source>standby daemons</source>
+ <target>待机守护进程</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3629620351427988554" datatype="html">
+ <source>active daemon</source>
+ <target>活跃守护进程</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5954854563228355745" datatype="html">
+ <source>standbyReplay</source>
+ <target>standbyReplay</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7329683463736701292" datatype="html">
+ <source>n/a</source>
+ <target>n/a</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/not-available.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8271970016544066882" datatype="html">
+ <source><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (quorum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</source>
+ <target><x id="PH" equiv-text="value.monmap.mons.length.toString()"/>(仲裁 <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mon-summary.pipe.ts</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6489441800790477240" datatype="html">
+ <source>total</source>
+ <target>总数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5965118847182332588" datatype="html">
+ <source>near full</source>
+ <target>将满</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="268166731974484199" datatype="html">
+ <source>full</source>
+ <target>全部</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47116253e36f4e38a97ba41b2d3122c6c15ab904" datatype="html">
+ <source>Clients (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</source>
+ <target>客户端 (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5159814115056353668" datatype="html">
+ <source>Addresses</source>
+ <target>地址</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1811797298582428088" datatype="html">
+ <source>Access Type</source>
+ <target>访问类型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3575940435199094878" datatype="html">
+ <source>Squash</source>
+ <target>Squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2944102521023817891" datatype="html">
+ <source>Cluster</source>
+ <target>集群</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91772203889648189" datatype="html">
+ <source>NFS Protocol</source>
+ <target>NFS 协议</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907766170797643122" datatype="html">
+ <source>Pseudo</source>
+ <target>伪</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1032539711043211945" datatype="html">
+ <source>Transport</source>
+ <target>传输</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2489852208080013495" datatype="html">
+ <source>Storage Backend</source>
+ <target>存储后端</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8440421106569981118" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4095248496892792741" datatype="html">
+ <source>CephFS User</source>
+ <target>CephFS 用户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2535727951299201687" datatype="html">
+ <source>CephFS Filesystem</source>
+ <target>CephFS 文件系统</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2169401160512036026" datatype="html">
+ <source>Security Label</source>
+ <target>安全标签</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3671149880069127721" datatype="html">
+ <source>Object Gateway</source>
+ <target>对象网关</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1643028261508790" datatype="html">
+ <source>Object Gateway User</source>
+ <target>对象网关用户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2dae0bda66f6a349444951c0379c28cda47d6d1" datatype="html">
+ <source>Any client can access</source>
+ <target>任何客户端均可访问</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7882f2edb1d4139800b276b6b0bbf5ae0b2234ef" datatype="html">
+ <source>Addresses</source>
+ <target>地址</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f3f74c0f6925826cb2188576391c0da01a23f0" datatype="html">
+ <source>Must contain one or more comma-separated values</source>
+ <target>必须包含一个或多个逗号分隔值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb5b2073697f3f4378c44a49b7524934c9268f4" datatype="html">
+ <source>For example:</source>
+ <target>例如:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f969c655b3fbe4fba7e277caf4cd2c459f9fca5" datatype="html">
+ <source>Access Type</source>
+ <target>访问类型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28952831a284cfe2b4fc39ca610e80b52598905a" datatype="html">
+ <source>Squash</source>
+ <target>Squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0660ae339068979854ade34a96546980723dede3" datatype="html">
+ <source>Add clients</source>
+ <target>添加客户端</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8571141481686087364" datatype="html">
+ <source>(inherited from global config)</source>
+ <target>(从全局配置继承)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3563954518111128118" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- 选择访问类型 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3802199399355755843" datatype="html">
+ <source>inherited from global config</source>
+ <target>从全局配置继承</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8729531250118136719" datatype="html">
+ <source>-- Select what kind of user id squashing is performed --</source>
+ <target>-- 请选择执行哪种类型的用户 ID 匿名访问 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4d1dd59b039ad818d9da7e29a773e10e41d9821" datatype="html">
+ <source>Cluster</source>
+ <target>集群</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="625f8f0f3e5b7c92651606d77484ff3d07b3c12b" datatype="html">
+ <source>This is the ID of an NFS Service.</source>
+ <target>这是 NFS 服务的 ID。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="135b91a2d908d5814b782695470a6a786c99d9d2" datatype="html">
+ <source>-- No cluster available --</source>
+ <target>-- 没有可用的集群 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c501dba379f566885919240ea277b5bc10c14d18" datatype="html">
+ <source>-- Select the cluster --</source>
+ <target>-- 请选择集群 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7bd3ad665c398c7fe97230ab59e67370653a82" datatype="html">
+ <source>This field is required. To create a new NFS cluster, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>add a new NFS Service<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <target>这是必填字段。要创建新 NFS 集群,请<x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>添加新 NFS 服务<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">41,43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3f6ba7fe84d6508705cdfe234f0fcc8ff85c9cf" datatype="html">
+ <source>Storage Backend</source>
+ <target>存储后端</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6fee356d1db954255a56d8169405a89595246b9" datatype="html">
+ <source>-- Select the storage backend --</source>
+ <target>-- 请选择存储后端 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3c2793dd2ef56954f872142d5ec1becb84c0fe1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="796e42bec8a6996607cf1f3e80235b86d695804a" datatype="html">
+ <source>Volume</source>
+ <target>卷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee3ba0ab5f0ccd597b3e44021c71e9aaad14df0a" datatype="html">
+ <source>-- No CephFS filesystem available --</source>
+ <target>-- 没有可用的 CephFS 文件系统 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="764c57812558b1ae66c5eec95d7efd2b1bf761e3" datatype="html">
+ <source>-- Select the CephFS filesystem --</source>
+ <target>-- 选择 CephFS 文件系统 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="957512d0321f73e9f115bce1bd823fa635170c41" datatype="html">
+ <source>Security Label</source>
+ <target>安全标签</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="65ce0fa4da1ed55e658aeb31d1644a29f06bb342" datatype="html">
+ <source>Enable security label</source>
+ <target>启用安全标签</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e808f804130c7b6ff719509cbc06ebb27393a48" datatype="html">
+ <source>CephFS Path</source>
+ <target>CephFS 路径</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1338c2f83e49ea7f2fc04e9fe90c5d330b7a10f" datatype="html">
+ <source>A path in a CephFS file system.</source>
+ <target>CephFS 文件系统中的路径。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ecc0107badb6625466aaa3f975b5c05276f432f" datatype="html">
+ <source>Path need to start with a '/' and can be followed by a word</source>
+ <target>路径需以 &quot;/&quot; 开头,后面可跟单词</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f9d8bd873c34c5ab2d4d0cf995fe5183ab25f6e" datatype="html">
+ <source>The path does not exist in the selected volume.</source>
+ <target>选定卷中不存在该路径。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd197d7773cef10f368f08c53b47979c3df1f22d" datatype="html">
+ <source>Bucket</source>
+ <target>存储桶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ca90b4b16347ef7017967915e8624472976c85c" datatype="html">
+ <source>The bucket does not exist or is not in the default realm (if multiple realms are configured). To continue, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>create a new bucket<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <target>存储桶不存在或不在默认领域中(如果配置了多个领域)。要继续,请<x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>创建新的存储桶<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bee6900143996c0e908a10564532eba3da0b30fb" datatype="html">
+ <source>NFS Protocol</source>
+ <target>NFS 协议</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5043c0921e709935ab026bb3253ffe1f159fca1" datatype="html">
+ <source>NFSv4</source>
+ <target>NFSv4</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d2c39708a32910f89701dd7e1cfb9ec1c195768" datatype="html">
+ <source>Pseudo</source>
+ <target>伪</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1f8be2ae25947bec0b84c2338201580ea053f34e" datatype="html">
+ <source>The position that this <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> export occupies in the <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo FS<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (it must be unique).</source>
+ <target>此 <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> 导出在<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>伪文件系统<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>中的位置(必须唯一)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">241,242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3af55f7fd5b1d9e5a53e030c80116dc635bfb9f" datatype="html">
+ <source>By using different Pseudo options, the same Path may be exported multiple times.</source>
+ <target>通过使用不同伪选项,可将同一路径导出多次。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5eb719aa900fed3f9d4a1d74bcc158f07f67f684" datatype="html">
+ <source>The pseudo is already in use by another export.</source>
+ <target>另一个导出中已在使用该伪代码。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddf98fcdeeb17643db020d54f42b5e56b5f9a52a" datatype="html">
+ <source>Pseudo needs to start with a '/' and can't contain any of the following: &gt;, &lt;, |, &amp;, ( or ).</source>
+ <target>伪必须以 &quot;/&quot; 开头且不能包含以下任何字符:&gt;、&lt;、|、&amp;、( 或 )。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="27eb35c4b4ac08781a7253a2ab40f8f7d957ba51" datatype="html">
+ <source>-- No access type available --</source>
+ <target>-- 没有可用的访问类型 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">280</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="509ce016c9110a54028dafd741f15ceacbe74b5a" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- 选择访问类型 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67ce207d0b7eada1fe3d3187a39ba0c07be76b6c" datatype="html">
+ <source>The Object Gateway NFS backend has a number of limitations which will seriously affect applications writing to the share. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> for details before enabling write access.</source>
+ <target>对象网关 NFS 后端存在一些限制,将会严重影响写入该共享的应用。在启用写入访问权限前,请参见 <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> 了解详细信息。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">293,296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4deda03573eaaff77e63f6a238a1f0ca7816950a" datatype="html">
+ <source>-- No squash available --</source>
+ <target>-- 没有可用的 squash --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">321</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a0e82a4da88e7fdf270444f838d45849676e9d4b" datatype="html">
+ <source>--Select what kind of user id squashing is performed --</source>
+ <target>-- 请选择执行哪种类型的用户 ID 匿名访问 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d01b7c3f7f06712c53d054cfbe4f53d446b038e8" datatype="html">
+ <source>Transport Protocol</source>
+ <target>传输协议</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2a6ad6e8bc315f07911722c05767ac79c136d99" datatype="html">
+ <source>UDP</source>
+ <target>UDP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">349</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c030f11e0aae9b24d2c048c57f29f590be621df" datatype="html">
+ <source>TCP</source>
+ <target>TCP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">359</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f84d7fd4d52eb5b2229b632ef5119dac63d5597" datatype="html">
+ <source>No user id squashing is performed.</source>
+ <target>未在执行用户 ID 匿名访问。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">378</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb1d148107e36852325106a518385b1b0de28835" datatype="html">
+ <source>uid 0 and gid 0 are squashed to the Anonymous_Uid and Anonymous_Gid gid 0 in alt_groups lists is also squashed.</source>
+ <target>uid 0 和 gid 0 会映射到 Anonymous_Uid 和 Anonymous_Gid,alt_groups 列表中的 gid 0 也会映射为匿名组。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">382</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1309d6f67955799863337b201413faa61a175ddb" datatype="html">
+ <source>uid 0 and gid of any value are squashed to the Anonymous_Uid and Anonymous_Gid alt_groups lists is discarded.</source>
+ <target>uid 0 和任意值的 gid 均会映射到 Anonymous_Uid 和 Anonymous_Gid,alt_groups 列表会被丢弃。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85f23d5c9b57dc78dda4150d13aa3b99e985350b" datatype="html">
+ <source>All users are squashed.</source>
+ <target>所有用户都作为匿名用户。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2691935247101074756" datatype="html">
+ <source>NFS export</source>
+ <target>NFS 导出</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8727258243239498387" datatype="html">
+ <source><x id="PH" equiv-text="fsalItem.descr"/> backend is not available. <x id="PH_1" equiv-text="errorMessage"/></source>
+ <target><x id="PH" equiv-text="fsalItem.descr"/> 后端不可用。<x id="PH_1" equiv-text="errorMessage"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2772848515253260635" datatype="html">
+ <source>Error while retrieving paths.</source>
+ <target>检索路径时出错。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5239928491238988595" datatype="html">
+ <source>Error while retrieving bucket names.</source>
+ <target>检索存储桶名称时出错。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="734c9905951a774870497c5aaae8e3ee833b6196" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2190548d236ca5f7bc7ab2bca334b860c5ff2ad4" datatype="html">
+ <source>Object Gateway</source>
+ <target>对象网关</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca53d681a9892d6fdbb57ee9676582186515e961" datatype="html">
+ <source>Performance counters not available</source>
+ <target>性能计数器不可用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="490e15ecc922965b6d8194754c87c5583aa071f3" datatype="html">
+ <source>The name can only consist of alphanumeric characters, dashes and underscores.</source>
+ <target>名称只能由字母、数字、短划线和下划线组成。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9edc2b494e660618af3e5225f68d40b7ca67629c" datatype="html">
+ <source>The chosen erasure code profile name is already in use.</source>
+ <target>所选纠删码配置名称已被使用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35a4206db3105ed03e0dd799e1642b75b78123e8" datatype="html">
+ <source>Root</source>
+ <target>根</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf425784c7073c7e7f7c1bb90c2c19db7e751db2" datatype="html">
+ <source>Failure domain type</source>
+ <target>故障域类型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72396a9565cf644d1fe1b21b790c4243ee270986" datatype="html">
+ <source>Device class</source>
+ <target>设备类型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d80e0c07bfea1b693a33ef2245007de92a6780" datatype="html">
+ <source>Let Ceph decide</source>
+ <target>让 Ceph 决定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101611937243846632" datatype="html">
+ <source>Crush Rule</source>
+ <target>Crush 规则</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef9ff0e6227947b48dfab4ac39ade04af758913b" datatype="html">
+ <source>Plugin</source>
+ <target>插件</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd69b31bce8f630eac1d4762b0bbcf72ce19d193" datatype="html">
+ <source>Data chunks (k)</source>
+ <target>数据块 (k)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0d26a6172d32cb81218fe2103c54a818cbc1189" datatype="html">
+ <source>Must be equal to or greater than 2.</source>
+ <target>必须大于或等于 2。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ba6f4800642eba4e8b056aa7167554c3afa8db0" datatype="html">
+ <source>Chunks (k+m) have exceeded the available OSDs of <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>.</source>
+ <target>数据块 (k+m) 已超过 <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/> 的可用 OSD 数量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="86fca2f788ce986eef835cd7ef8dfc9ae22447a4" datatype="html">
+ <source>For an equal distribution k has to be a multiple of (k+m)/l.</source>
+ <target>要实现均衡分布,k 必须为 (k+m)/l 的倍数。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8dd4bc172f1adc4afadaec291e465b082909148d" datatype="html">
+ <source>K has to be equal to or greater than m in order to recover data correctly through c.</source>
+ <target>K 必须大于或等于 m 才能通过 c 正确恢复数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2e5b0e6d0dba31c59f946392699a0a6c4dd9b83" datatype="html">
+ <source>Distribution factor: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></source>
+ <target>分布系数:<x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dab3a299ead121169b8e08ed618c3b6a2f66691b" datatype="html">
+ <source>Coding chunks (m)</source>
+ <target>编码块 (m)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e2773e5bd4948193f18f2361d663ecc3988c656" datatype="html">
+ <source>Must be equal to or greater than 1.</source>
+ <target>必须大于或等于 1。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">146</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cde4c945a49a260c0a47bcc7cd956846930a5f7" datatype="html">
+ <source>Durability estimator (c)</source>
+ <target>持久性估值 (c)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ec9ff9931f8ea1201792d6a01bf9a47b283d692" datatype="html">
+ <source>C has to be equal to or lower than m as m defines the amount of chunks that can be used.</source>
+ <target>C 必须小于或等于 m,因为 m 定义可以使用的数据块数量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35594fe66657ea07b5b5f560927f78e81a229996" datatype="html">
+ <source>Helper chunks (d)</source>
+ <target>助手块 (d)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0c250a8d281291273ed3504ade19ca6537e4d9a" datatype="html">
+ <source>Set d manually or use the plugin's default calculation that maximizes d.</source>
+ <target>手动设置 d 或使用插件的默认计算值(最大值为 d)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4304a5cd95742db0f81c3bdf29aa96bf3b0ca13d" datatype="html">
+ <source>D is automatically updated on k and m changes</source>
+ <target>D 会在 k 和 m 更改时自动更新</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06a67d52427b12df2b3d439be0e1342ac72aeb5c" datatype="html">
+ <source>D can be set from <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> to <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></source>
+ <target>D 可设置为 <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> 到 <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4f8831d3bd6401e87710c4e3ee844f5efbf5de3" datatype="html">
+ <source>D can only be set to <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></source>
+ <target>D 仅可设置为 <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5d7aacffce2c6032c3ae9ef4d1b3847a926440b" datatype="html">
+ <source>D has to be greater than k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>).</source>
+ <target>D 必须大于 k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fd745d614884edc23c7ac9ad8aba9655f3793ac2" datatype="html">
+ <source>D has to be lower than k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>).</source>
+ <target>D 必须小于 k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">199</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af668c2a095a979ea2b4e43cd82c2120ab56c21c" datatype="html">
+ <source>Locality (l)</source>
+ <target>局部性因子 (l)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="200fea08b63ae8d60cdbf33ffd2636159e87dc1e" datatype="html">
+ <source>Can't split up chunks (k+m) correctly with the current locality.</source>
+ <target>无法使用当前局部性因子正确分割 (k+m) 个数据块。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319ac5d692d11da686782159bd70e0b705c228ed" datatype="html">
+ <source>Locality groups: <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></source>
+ <target>局部性因子组:<x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">230</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d455a110bf6d2235e314e295ce1dfeee93d3dff2" datatype="html">
+ <source>Crush failure domain</source>
+ <target>CRUSH 故障域</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74a495f041f7dd102eee5c0bbc9e03083b538ae" datatype="html">
+ <source>Crush Locality</source>
+ <target>CRUSH 局部性</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2f14a73f7a6e94479f67423cc51102da8d6f524" datatype="html">
+ <source>None</source>
+ <target>无</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="363a99d62822b92913a4cce196d47f32c1258e2f" datatype="html">
+ <source>Scalar mds</source>
+ <target>Scalar mds</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2981733b912b693a9dd9d915d6d34f4692cc874a" datatype="html">
+ <source>Technique</source>
+ <target>算法</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0098b6e47b04ec817361f384ce81d454ba5c0bb" datatype="html">
+ <source>Packetsize</source>
+ <target>数据包大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0252cd81ca54d0a2f69ec9ccf4248e73df5aa4a" datatype="html">
+ <source>Crush root</source>
+ <target>CRUSH 根</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">351</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1548d5c76f0406ddd1ba3c557e1e6db22e95b340" datatype="html">
+ <source>Crush device class</source>
+ <target>CRUSH 设备类型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3f657ffa19dc6ac504b83c86209709522dcf065" datatype="html">
+ <source>Available OSDs: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></source>
+ <target>可用 OSD:<x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03d84645f6e019c5a43909bbf2ea1696ee88332c" datatype="html">
+ <source>Directory</source>
+ <target>目录</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1354845268685595937" datatype="html">
+ <source>EC Profile</source>
+ <target>EC 配置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3938a411d76796f8ae73b72ea4c77661207453bd" datatype="html">
+ <source>Cache Tiers Details</source>
+ <target>缓存层详细信息</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="991790413700941336" datatype="html">
+ <source>Cache Mode</source>
+ <target>缓存模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9133265273798382582" datatype="html">
+ <source>Min Evict Age</source>
+ <target>逐出前至少可存留的时间</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7172092927403263656" datatype="html">
+ <source>Min Flush Age</source>
+ <target>刷回前至少可存留的时间</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8096695869347792608" datatype="html">
+ <source>Target Max Bytes</source>
+ <target>目标最大字节数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8854126142886240282" datatype="html">
+ <source>Target Max Objects</source>
+ <target>目标最大对象数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617215542453015899" datatype="html">
+ <source>No applications added</source>
+ <target>未添加任何应用标记</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4895689494338215646" datatype="html">
+ <source>Applications limit reached</source>
+ <target>应用标记已达到上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7322343326526084293" datatype="html">
+ <source>A pool can only have up to four applications definitions.</source>
+ <target>一个存储池最多只能有四个应用标记定义。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1393735257943344790" datatype="html">
+ <source>Allowed characters '_a-zA-Z0-9'</source>
+ <target>可用的字符为 &quot;_a-zA-Z0-9&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5520683885127790121" datatype="html">
+ <source>Maximum length is 128 characters</source>
+ <target>长度限制为 128 个字符</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587418377972855060" datatype="html">
+ <source>Filter or add applications'</source>
+ <target>过滤或添加应用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5188881899285829380" datatype="html">
+ <source>Add application</source>
+ <target>添加应用标记</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16e113230b6b0d3165e076300880542bac7c8138" datatype="html">
+ <source>The chosen Ceph pool name is already in use.</source>
+ <target>所选 Ceph 存储池名称已被使用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c75b132bef7b29fa5171768303c4b96e34ccaf68" datatype="html">
+ <source>It's not possible to create an RBD pool with '/' in the name. Please change the name or remove 'rbd' from the applications list.</source>
+ <target>无法创建名称中包含 &quot;/&quot; 的 RBD 存储池。请更改名称或从应用列表中删除 &quot;rbd&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">34,35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="171dc6d5c6bc4615d99778b0088cae80fd00bd10" datatype="html">
+ <source>Pool name can only contain letters, numbers, '.', '-', '_' or '/'.</source>
+ <target>存储池名称只能包含字母、数字、&quot;.&quot;、&quot;-&quot;、&quot;_&quot; 或 &quot;/&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b85c657469e5ec8231c3de99b22f437bc01ffde5" datatype="html">
+ <source>Pool type</source>
+ <target>存储池类型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="526c5443254c3b126eedb264840ffe827727bfd3" datatype="html">
+ <source>-- Select a pool type --</source>
+ <target>-- 请选择存储池类型 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abfbe47b630929d93c7343dc154599c2e59330a" datatype="html">
+ <source>PG Autoscale</source>
+ <target>PG 自动伸缩</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0aa21053410a94aa61d16985a4e95fd65523430d" datatype="html">
+ <source>Placement groups</source>
+ <target>归置组</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6301f1391d726f8f450bb358058534db19541ca9" datatype="html">
+ <source>At least one placement group is needed!</source>
+ <target>至少需要一个归置组!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba9469a1ce6ed36e039c1f67247c8c81a5c71449" datatype="html">
+ <source>Your cluster can't handle this many PGs. Please recalculate the PG amount needed.</source>
+ <target>您的集群无法处理这么多的 PG。请重新计算需要的 PG 数量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80ac68cd883369dac20688bc32b4cb33291b5e50" datatype="html">
+ <source>Calculation help</source>
+ <target>在线 PG 计算器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fccbd60493df26705d957ed6c02a3c447894678f" datatype="html">
+ <source>The current PGs settings were calculated for you, you should make sure the values suit your needs before submit.</source>
+ <target>当前的 PG 设置是为您计算的,您应在提交前确保这些值符合您的需求。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">116,117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a43b2695131b48b76cebba676aba98a2bee17515" datatype="html">
+ <source>Replicated size</source>
+ <target>副本个数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bff144a4c4dc63b0e18fff2617d61a7ebdf2b6c" datatype="html">
+ <source>Minimum: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></source>
+ <target>最低:<x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9c54b41f6d58a74e5d0aa3429ed0c87a482551" datatype="html">
+ <source>Maximum: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></source>
+ <target>最高:<x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="452cf71ec44ee77428656936a6627eaf2dd3b47f" datatype="html">
+ <source>The size specified is out of range. A value from <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> to <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/> is usable.</source>
+ <target>指定的个数超出范围。请使用介于 <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> 到 <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/> 的值。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">144,145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dda6196ffab88c1825f44a565c7b34e246e7e12f" datatype="html">
+ <source>A size of 1 will not create a replication of the object. The 'Replicated size' includes the object itself.</source>
+ <target>指定个数 1 将不创建对象的副本。&quot;副本个数&quot; 包括对象本身。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">148,149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c870fb00256b8a5b9cb9cd1a124e6390b9bc639" datatype="html">
+ <source>EC Overwrites</source>
+ <target>EC 重写</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f1abafaeb40ce52355ddcc24686e3cd17b64e08a" datatype="html">
+ <source>Applications</source>
+ <target>应用标记</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9308b82fc183f710df60909f49cfc73aa5e076" datatype="html">
+ <source>CRUSH</source>
+ <target>CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9de7dde00e2139cc4bd03b1837afbe72ad15a1ff" datatype="html">
+ <source>Erasure code profile</source>
+ <target>纠删码配置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39b4620e6bd444e0a57a0a5c03fa8c96d7fe5235" datatype="html">
+ <source>-- No erasure code profile available --</source>
+ <target>-- 没有可用的纠删码配置 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498561757390d5528b263ce450d5f38efb00266d" datatype="html">
+ <source>-- Select an erasure code profile --</source>
+ <target>-- 请选择纠删码配置 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="616a2532fbaace94934f5943e381b63e2623f004" datatype="html">
+ <source>This profile can't be deleted as it is in use.</source>
+ <target>此配置正被使用,不能删除。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="994363f08f9fbfa3b3994ff7b35c6904fdff18d8" datatype="html">
+ <source>Profile</source>
+ <target>配置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="023d6f718770d2ea4ab8cabe26b0ec27ef967ec2" datatype="html">
+ <source>Used by pools</source>
+ <target>由存储池使用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">387</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1061ba5ee07a5c6af09e09330dbc29201baf2aa" datatype="html">
+ <source>Profile is not in use.</source>
+ <target>配置未被使用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33150f22ce5348aa6c499bd092c3f4f3695d62cc" datatype="html">
+ <source>Crush ruleset</source>
+ <target>CRUSH 规则集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">293</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">303</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c69b0bcd4698aa845d32c4c4ad488492552cb469" datatype="html">
+ <source>A new crush ruleset will be implicitly created.</source>
+ <target>将隐式创建一个新的 crush 规则集。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="896e9987db5e9bb279e6deed5d2dff28c242ef66" datatype="html">
+ <source>There are no rules.</source>
+ <target>没有规则。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73a6b31116b3cc322af951daa0bafdc169e6c42e" datatype="html">
+ <source>-- Select a crush rule --</source>
+ <target>-- 请选择 CRUSH 规则 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7d4894e770f8853050b1f6dd55bdd77a51a8ac6" datatype="html">
+ <source>Placement and
+ replication strategies or distribution policies that allow to
+ specify how CRUSH places data replicas.</source>
+ <target>用于指定
+ CRUSH 归置数据副本方式的
+ 归置和复制策略或分布策略。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">328,330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea91d648f92002bc9f96d9b26b735c83ca0b53c6" datatype="html">
+ <source>This rule can't be deleted as it is in use.</source>
+ <target>此规则正被使用,不能删除。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">346</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92da80699921e89fb19372e25b8d0f3b9fa427fc" datatype="html">
+ <source>Crush rule</source>
+ <target>CRUSH 规则</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">365</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5489e9f96835f469f6f728a00d8efa88ea5bc940" datatype="html">
+ <source>Crush steps</source>
+ <target>CRUSH 步骤</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc5f5496a9e50fe69e1a09784f28d94944108294" datatype="html">
+ <source>Rule is not in use.</source>
+ <target>规则未被使用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="104a0e6900d1d1b0c8cf9e5947e36edb352583fc" datatype="html">
+ <source>The rule can't be used in the current cluster as it has too few OSDs to meet the minimum required OSD by this rule.</source>
+ <target>无法在当前集群中使用该规则,因为集群的 OSD 数量太少,不满足此规则要求的最低 OSD 数量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">409,410</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2208d63d5940ce656006a220102b1eb2b5e553da" datatype="html">
+ <source>Compression</source>
+ <target>压缩</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">420</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c6f25c47da62ec597c6057a36ddfc3209811ec5" datatype="html">
+ <source>Algorithm</source>
+ <target>算法</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">444</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4903231d42089325a28892c0fde1aed46b733ae6" datatype="html">
+ <source>-- No erasure compression algorithm available --</source>
+ <target>-- 没有可用的纠删码压缩算法 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d68ddb254275f8f44221e9ad6d8ceeb59ca46a6" datatype="html">
+ <source>Minimum blob size</source>
+ <target>blob 大小下限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">468</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb2f176df80647137cbb02bbeb29e5dec707a400" datatype="html">
+ <source>e.g., 128KiB</source>
+ <target>例如 128 KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">477</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b7f6e53a4521c6eb3ced4c007fdd4cf80bb7707" datatype="html">
+ <source>Value should be greater than 0</source>
+ <target>值应大于 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">482</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">506</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8db98ab14b4e207ec763dfdefbc2dae367aab1cc" datatype="html">
+ <source>Value should be less than the maximum blob size</source>
+ <target>值应小于 blob 大小上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151efb127a9a4dd25259a0b2055442318a141f5b" datatype="html">
+ <source>Maximum blob size</source>
+ <target>blob 大小上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c656f0e346bbadf46eb1a5d20d0307a3bd20ba8" datatype="html">
+ <source>e.g., 512KiB</source>
+ <target>例如 512KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65a24eee8a026f3b1113fe9e157e9a0dd69486" datatype="html">
+ <source>Value should be greater than the minimum blob size</source>
+ <target>值应大于 blob 大小下限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">509</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="261ba09c4a59de83f48f52a23fd328da37e61ff4" datatype="html">
+ <source>Ratio</source>
+ <target>比例</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">517</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1430457a9c3c66366e51d76bf10396014c576be" datatype="html">
+ <source>Compression ratio</source>
+ <target>压缩率</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">528</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae5ce6de352cde949998fb10754459c3a4eb183b" datatype="html">
+ <source>Value should be between 0.0 and 1.0</source>
+ <target>值应介于 0.0 到 1.0 之间</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d99b34162c9c34f10d0ccd8dbae83d8569c2db77" datatype="html">
+ <source>Max bytes</source>
+ <target>最大字节数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">546</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1d14a18879c62f3f4ed705318b7164a1160e249" datatype="html">
+ <source>Leave it blank or specify 0 to disable this quota.</source>
+ <target>留空或指定 0 可禁用此配额。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">572</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7565b131562ff6c5f769fdbd239a772154abdd97" datatype="html">
+ <source>A valid quota should be greater than 0.</source>
+ <target>有效配额应大于 0。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">550</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">574</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b8bf35b66f09a301eef92ffc3cb2fd259df67ce9" datatype="html">
+ <source>Max objects</source>
+ <target>最大对象数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">570</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="95f348167622d832c5ae532b6944635c8e2ae5cb" datatype="html">
+ <source>The value should be greater or equal to 0</source>
+ <target>该值应大于或等于 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">586</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1088629182722162774" datatype="html">
+ <source>pool</source>
+ <target>存储池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6215593782779198370" datatype="html">
+ <source>erasure code profile</source>
+ <target>纠删码配置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4390273881304618317" datatype="html">
+ <source>crush rule</source>
+ <target>Crush 规则</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">721</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d8a7c8aea58294a3c57c23af0468ddf0ba0c9c7" datatype="html">
+ <source>Pools List</source>
+ <target>存储池列表</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9055665654201606988" datatype="html">
+ <source>Data Protection</source>
+ <target>数据保护</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6658000829978978023" datatype="html">
+ <source>Applications</source>
+ <target>应用标记</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5232365108332422324" datatype="html">
+ <source>PG Status</source>
+ <target>PG 状态</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1669788723782899084" datatype="html">
+ <source>Crush Ruleset</source>
+ <target>CRUSH 规则集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7961062124768120122" datatype="html">
+ <source>Pool deletion is disabled by the mon_allow_pool_delete configuration setting.</source>
+ <target>mon_allow_pool_delete 配置设置已禁用存储池删除功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee5132a8da30e0b7f9f5c70dbc91928d17dd909" datatype="html">
+ <source>Owner</source>
+ <target>所有者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c51963a9c553b29427ef783bbb69fa6634fa8c" datatype="html">
+ <source>Index type</source>
+ <target>索引类型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e6f950a32eaea32ec7e192f9ca3d3dfe469d4ba" datatype="html">
+ <source>Placement rule</source>
+ <target>归置规则</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6972d213e31c4ea4f887e60db99d9881bc8fcd3e" datatype="html">
+ <source>Marker</source>
+ <target>标记</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47b02acd2d3254d1ace1926f840523f154ebef71" datatype="html">
+ <source>Maximum marker</source>
+ <target>上限标记</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="092fa3a7df9168b14d3f83a77a4035e92b92ce15" datatype="html">
+ <source>Master version</source>
+ <target>主版本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97434cc5001d407f90c7447a12d9e8e6848a2aa3" datatype="html">
+ <source>Modification time</source>
+ <target>修改时间</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90fe2e41e7fde38453ce4e619efeea9bc6adea9c" datatype="html">
+ <source>Zonegroup</source>
+ <target>区域组</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="efeade5060b3add63863c24871f0830fb16b7e6d" datatype="html">
+ <source>Versioning</source>
+ <target>版本控制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62a923f047ca49e7a4782629e91fea1ba32db68f" datatype="html">
+ <source>MFA Delete</source>
+ <target>MFA 删除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="649a410bd0ace333d067d8fa22f12bdbdb43533b" datatype="html">
+ <source>Bucket quota</source>
+ <target>存储桶配额</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">567</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f50a33d3c339f8f4a465141f8caa5d2d8c005251" datatype="html">
+ <source>Enabled</source>
+ <target>已启用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">579</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cef1595d040e77cbb4466e60382028d4c2040cac" datatype="html">
+ <source>Maximum size</source>
+ <target>大小上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa6fb95c355f172bda303de1ce2f38c251a149cf" datatype="html">
+ <source>Unlimited</source>
+ <target>无限制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee862a800364b4d11f9b8cb9955a28a60f840a45" datatype="html">
+ <source>Maximum objects</source>
+ <target>对象数目上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b84370895ab9eb44672f57146fa05c5947f1c0c" datatype="html">
+ <source>Locking</source>
+ <target>锁定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c3d9d2296f7886e8289b9f623323803deacfc6" datatype="html">
+ <source>Days</source>
+ <target>天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f44bdf9ab00a973bbe482e9fc450e3f67e60c0d" datatype="html">
+ <source>Bucket names can only contain lowercase letters, numbers, periods and hyphens.</source>
+ <target>存储桶名称只能包含小写字母、数字、句点和连字符。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eabb4db920d9f9b2480cf438468b86e1bea02a9b" datatype="html">
+ <source>The chosen name is already in use.</source>
+ <target>所选名称已被使用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b06de7f834c622197e68b66a2abe893040b174c4" datatype="html">
+ <source>Bucket names must not contain uppercase characters or underscores.</source>
+ <target>存储桶名称不能包含大写字符或下划线。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abacf4af2f66d3af08c5ebe502b21b1f42ac649" datatype="html">
+ <source>Each label must start and end with a lowercase letter or a number.</source>
+ <target>每个标签都必须以小写字母或数字开头和结尾。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a7f52e6813e0535026f61a2d6e8adc8a1d006a" datatype="html">
+ <source>Bucket names cannot be formatted as IP address.</source>
+ <target>存储桶名称不能采用 IP 地址格式。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2a2460396d35e14e7acfb4e060196a0679bdcff" datatype="html">
+ <source>Bucket labels cannot be empty and can only contain lowercase letters, numbers and hyphens.</source>
+ <target>存储桶标签不能为空,并且只能包含小写字母、数字和连字符。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf5c849977e0be2dbfc862d044edd323bfd9fb77" datatype="html">
+ <source>Bucket names must be 3 to 63 characters long.</source>
+ <target>存储桶名称长度必须在 3 到 63 个字符之间。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e4c918357c7445fbf19a203e5f0f0ece1960b3b" datatype="html">
+ <source>-- Select a user --</source>
+ <target>-- 请选择用户 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4aab1f837bc8ec222e4f25922465d1c5929a1fc" datatype="html">
+ <source>Placement target</source>
+ <target>归置目标</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bae0a7fc2c9c1fde7d937a8a1a3c7e6825cf7d1" datatype="html">
+ <source>-- Select a placement target --</source>
+ <target>-- 选择归置目标 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="016d24e069e7d505a090fb8243e5cd43b35dc39b" datatype="html">
+ <source>Enables versioning for the objects in the bucket.</source>
+ <target>对存储桶中的对象启用版本控制。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">151</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e6775ffd06878aa145c07359f28557f01ede04f" datatype="html">
+ <source>Multi-Factor Authentication</source>
+ <target>多重身份验证</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29e8a5d4fb767d4ad0c762c81c6264cec4c0ba97" datatype="html">
+ <source>Delete enabled</source>
+ <target>启用删除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40fbc3ac8c1ea4ecfe62247e91f1f999ad5baf76" datatype="html">
+ <source>Enables MFA (multi-factor authentication) Delete, which requires additional authentication for changing the bucket versioning state.</source>
+ <target>启用 MFA(多重身份验证)删除功能,这样更改存储桶版本控制状态时将需要进行额外的身份验证。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24c93a8c13db46defa06ed7b5e026a3edb52b91" datatype="html">
+ <source>Token Serial Number</source>
+ <target>令牌序列号</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6d9536c2af2e5e9a228c3e3e1809dc1fefe0149" datatype="html">
+ <source>Token PIN</source>
+ <target>令牌 PIN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f038d51ab1645f15b0cd58f195c72a7eeebd4729" datatype="html">
+ <source>Enables locking for the objects in the bucket. Locking can only be enabled while creating a bucket.</source>
+ <target>对存储桶中的对象启用锁定功能。只有在创建存储桶时才能启用锁定功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9af1b4baa2dd8ed2bfc3cc756b12a2271c2dd793" datatype="html">
+ <source>Compliance</source>
+ <target>合规</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="edd600fa489d1b4a4448dce694ed932e52ce8fda" datatype="html">
+ <source>Governance</source>
+ <target>治理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="218c7d6d318c51e7105309aaeb0baec9d19e4efb" datatype="html">
+ <source>The number of days that you want to specify for the default retention period that will be applied to new objects placed in this bucket.</source>
+ <target>您要指定的默认保留天数,将应用于此存储桶中存放的新对象。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">264</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="289b101ec12427b3ca819df9e43cc3b14fae2cc4" datatype="html">
+ <source>The entered value must be a positive integer.</source>
+ <target>输入的值必须为正整数。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48d8247c1ba2ea156109bf286c5f6dd26b4be760" datatype="html">
+ <source>Retention Days must be a positive integer.</source>
+ <target>保留天数必须为正整数。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4349284625269221231" datatype="html">
+ <source>bucket</source>
+ <target>存储桶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6161088322338624846" datatype="html">
+ <source>Updated Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'.</source>
+ <target>已更新对象网关存储桶 &quot;<x id="PH" equiv-text="values.bid"/>&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218632328857697292" datatype="html">
+ <source>Created Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'</source>
+ <target>已创建对象网关存储桶 &quot;<x id="PH" equiv-text="values.bid"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c338bae89822d7eefbc9a887c458a7d8a98e55e" datatype="html">
+ <source>No Limit</source>
+ <target>无限制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3715596725146409911" datatype="html">
+ <source>Owner</source>
+ <target>所有者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5545511293826600258" datatype="html">
+ <source>Used Capacity</source>
+ <target>已用容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1925090152473969054" datatype="html">
+ <source>Capacity Limit %</source>
+ <target>容量上限 %</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8713861779825116442" datatype="html">
+ <source>Object Limit %</source>
+ <target>对象上限 %</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5913880066213114620" datatype="html">
+ <source>buckets</source>
+ <target>存储桶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eeba399c4dae8d4890c27b7a2cd2dc28fcf8b5f9" datatype="html">
+ <source>Performance Counters</source>
+ <target>性能计数器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="479488ab6e91ecb375484edc78bee3d13467f33f" datatype="html">
+ <source>Daemons List</source>
+ <target>守护进程列表</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca2dee83bb58290d93fb0d17ee8bc9f095a4576f" datatype="html">
+ <source>Sync Performance</source>
+ <target>同步性能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4378147649219625174" datatype="html">
+ <source>Zone</source>
+ <target>区域</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6148052126949932311" datatype="html">
+ <source>Zone Group</source>
+ <target>区域组</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3840481991104643295" datatype="html">
+ <source>Realm</source>
+ <target>领域</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1221ca97d19eaa9a7bc0c5243d5fc5befe1d2314" datatype="html">
+ <source>-- Select a type --</source>
+ <target>-- 请选择类型 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1b8990332af18f1c5159a6061ca889bcbb28432" datatype="html">
+ <source>Permission</source>
+ <target>权限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a08c589f82f69d892307288da14190ae1dd583d5" datatype="html">
+ <source>-- Select a permission --</source>
+ <target>-- 请选择权限 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7345972049922682356" datatype="html">
+ <source>capability</source>
+ <target>权限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a94e6b2b5b834d92cceb90037d51ad6165c8b619" datatype="html">
+ <source>Tenant</source>
+ <target>租户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
+ <source>User ID</source>
+ <target>用户 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b760f123248930122fc7e7b6b6bf94e376e959c8" datatype="html">
+ <source>Full name</source>
+ <target>全名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69b6ac577a19acc39fc0c22342092f327fff2529" datatype="html">
+ <source>Email address</source>
+ <target>邮箱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92f3f203270a29b3001871153f02c063484a1574" datatype="html">
+ <source>Suspended</source>
+ <target>已暂停</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011e20c5bbe51602d459a860fbf29b599b55edd" datatype="html">
+ <source>System</source>
+ <target>系统</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db18a2772988415466a7f75dc42663ce78c9c1d3" datatype="html">
+ <source>Maximum buckets</source>
+ <target>存储桶数目上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c4c62e8ba24601be5cfe7dc5d32c24bbbd4b53c" datatype="html">
+ <source>Subusers</source>
+ <target>子用户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17bb3082e6fe5003203ef992a3714172334631a1" datatype="html">
+ <source>Capabilities</source>
+ <target>权限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32f8a0570373cacb9c56cf227502483a29d605bc" datatype="html">
+ <source>MFAs(Id)</source>
+ <target>MFA (ID)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36ad38f9c1a1485e09b67778a28af84553290ffb" datatype="html">
+ <source>User quota</source>
+ <target>用户配额</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">473</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0bcd5ef19af0f1b814141ca8c57df623d8270088" datatype="html">
+ <source>Keys</source>
+ <target>密钥</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2aba1e87039819aca3b70faa9aa848c12bf139ca" datatype="html">
+ <source>Show</source>
+ <target>显示</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">395</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5248717555542428023" datatype="html">
+ <source>Username</source>
+ <target>用户名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240806681889331244" datatype="html">
+ <source>Unlimited</source>
+ <target>无限制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db4e1a734518691b128ef40b939cc673f01d03a6" datatype="html">
+ <source>The value is not valid.</source>
+ <target>该值无效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">617</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6aaf5d2a304167272ac73e3b1d1c162e16c77858" datatype="html">
+ <source>The chosen user ID is already in use.</source>
+ <target>所选用户 ID 已被使用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="025be1d01b2f6cbd09e772a1d3de02fab0678b26" datatype="html">
+ <source>Show Tenant</source>
+ <target>显示租户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6af106b0d759fd2882e645604675c4494abfcd5b" datatype="html">
+ <source>The chosen user ID exists in this tenant.</source>
+ <target>此租户中存在所选用户 ID。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="df441e80db2157f9d272b75de724ba4a82b96b57" datatype="html">
+ <source>This is not a valid email address.</source>
+ <target>这是无效的邮箱地址。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca271adf154956b8fcb28f4f50a37acb3057ff7c" datatype="html">
+ <source>The chosen email address is already in use.</source>
+ <target>此邮箱地址已被使用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="030197cebe938edf35422e92fe14183d06eb670b" datatype="html">
+ <source>Max. buckets</source>
+ <target>存储桶数目上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f39256070bfc0714020dfee08895421fc1527014" datatype="html">
+ <source>Disabled</source>
+ <target>已禁用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c05002b0ac2040f1aede5e727e0ffd06eda819" datatype="html">
+ <source>Custom</source>
+ <target>自定义</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28872515cb81d197a3a1733fa546d3e0f0dd6c67" datatype="html">
+ <source>The entered value must be &gt;= 1.</source>
+ <target>输入的值必须大于或等于 1。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="583a219c524155c2314eb06ee29162bb315272a3" datatype="html">
+ <source>S3 key</source>
+ <target>S3 密钥</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c217ee914725a37e9dd2336c721c8e63e9666bdc" datatype="html">
+ <source>Auto-generate key</source>
+ <target>自动生成密钥</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f1c1c0f2bce4c9f92d1a2061e8161cb0006c31a" datatype="html">
+ <source>Access key</source>
+ <target>访问密钥</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b864acb67296a9819c1db0069c4c47d8b5ce8f44" datatype="html">
+ <source>Secret key</source>
+ <target>秘密密钥</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="128d6efb51d9ddc7c0cc695a2deeca5b9523f6e4" datatype="html">
+ <source>There are no subusers.</source>
+ <target>没有子用户。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fd6dfb8ecb982dbc3affb2c2d5414c4f5b6abd2" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">294,295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67c746c1ba9dab4351fedc4c7cba4e6d6b0dbc47" datatype="html">
+ <source>S3</source>
+ <target>S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d6819038d608623503918fb2553f53d68231ec3a" datatype="html">
+ <source>There are no keys.</source>
+ <target>没有密钥。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">377</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc1c1a7140ff6b815a95b65ee2780fdbe1b2b7a1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">356,357</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6ddb5e991a3ecd2659fb520bc5acc81b67e08ddd" datatype="html">
+ <source>Swift</source>
+ <target>Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">371</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d01eccdda47fc907c5be35bcb16d2dcd02b0270" datatype="html">
+ <source>There are no capabilities.</source>
+ <target>没有权限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5a451c4ea65a4046f0b49d489a7013abf0b5861" datatype="html">
+ <source>All capabilities are already added.</source>
+ <target>已添加所有权限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">456</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="043e2ec0036ceadd926fd5e3f93cd6f3565f3648" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">461,462</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6146e13ceca5fa5cc17b771b282fe5955f3d19fa" datatype="html">
+ <source>Unlimited size</source>
+ <target>大小无限制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">595</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6db8aa7c99fdce18edb33dde57729acede2b308" datatype="html">
+ <source>Max. size</source>
+ <target>大小上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">511</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">605</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc630b2093e880fffa19df99d5cd8b87605037f8" datatype="html">
+ <source>Unlimited objects</source>
+ <target>对象数目无限制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cda5a993d06f0bb10048be9d3aba6555aa9f356" datatype="html">
+ <source>Max. objects</source>
+ <target>对象数目上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">642</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="623ac50f37a26caec6fd7cd519b653e3315cba25" datatype="html">
+ <source>The entered value must be &gt;= 0.</source>
+ <target>输入的值必须大于或等于 0。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">654</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="123010868147850959" datatype="html">
+ <source>user</source>
+ <target>用户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8368421344177343441" datatype="html">
+ <source>subuser</source>
+ <target>子用户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4662015204945271252" datatype="html">
+ <source>S3 Key</source>
+ <target>S3 密钥</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9103468069826049692" datatype="html">
+ <source>Updated Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <target>已更新对象网关用户 &quot;<x id="PH" equiv-text="uid"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="884841609901737584" datatype="html">
+ <source>Created Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <target>已创建对象网关用户 &quot;<x id="PH" equiv-text="uid"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4363143805416924501" datatype="html">
+ <source>Tenant</source>
+ <target>租户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8301535046747035390" datatype="html">
+ <source>Full name</source>
+ <target>全名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3967269098753656610" datatype="html">
+ <source>Email address</source>
+ <target>邮箱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5851424994801012357" datatype="html">
+ <source>Suspended</source>
+ <target>已暂停</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208300173682032371" datatype="html">
+ <source>Max. buckets</source>
+ <target>存储桶数目上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1670306451865226564" datatype="html">
+ <source>users</source>
+ <target>用户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c614babd1950adb2be75df4e2c9747286d6adc" datatype="html">
+ <source>-- Select a username --</source>
+ <target>-- 请选择用户名 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2841767821d6b66238c34d07e413b0af67aee92" datatype="html">
+ <source>Subuser</source>
+ <target>子用户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd59fc25a7bd98cff3e75117c09697c8a007a514" datatype="html">
+ <source>The chosen subuser ID is already in use.</source>
+ <target>所选子用户 ID 已被使用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d386c357ebcbc04ed05c4babd5a03626f9b1674" datatype="html">
+ <source>read, write</source>
+ <target>读写</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84e3e3f9a4f31a039b648c97debf95fcb20f4c4a" datatype="html">
+ <source>full</source>
+ <target>全部</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6bf81d032a2316464f9df2f0d2f3d753f89f0d3" datatype="html">
+ <source>Swift key</source>
+ <target>Swift 密钥</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e0c12685d50d47448ceed9423977ef39775c037" datatype="html">
+ <source>Auto-generate secret</source>
+ <target>自动生成密钥</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5091031285775138345" datatype="html">
+ <source>Subuser</source>
+ <target>子用户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8453697749389230205" datatype="html">
+ <source>Swift Key</source>
+ <target>Swift 密钥</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ac54c18c1b520e948095c83a3a1025f02ce6dcc6" datatype="html">
+ <source>Neither hostname nor OSD ID given</source>
+ <target>未提供主机名和 OSD ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4533150758393178756" datatype="html">
+ <source>Device ID</source>
+ <target>设备ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1291053608320944146" datatype="html">
+ <source>State of Health</source>
+ <target>健康状态</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29167121133682512" datatype="html">
+ <source>Good</source>
+ <target>良好</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8767957606064036733" datatype="html">
+ <source>Bad</source>
+ <target>不佳</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8052456228079338924" datatype="html">
+ <source>Stale</source>
+ <target>过时</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6223439643831041743" datatype="html">
+ <source>Life Expectancy</source>
+ <target>预计寿命</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3144481541623761279" datatype="html">
+ <source>Prediction Creation Date</source>
+ <target>预测创建日期</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="264574868375698540" datatype="html">
+ <source>Device Name</source>
+ <target>设备名称</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1419569261746199221" datatype="html">
+ <source>Daemons</source>
+ <target>守护进程</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f635b3cb0600409a2ad44a5bd1863c699e6a01c" datatype="html">
+ <source>Failed to retrieve SMART data.</source>
+ <target>无法检索 SMART 数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a8a3f354bd640299068edd912f4bb5325264f250" datatype="html">
+ <source>The data received has the JSON format version 2.x and is currently incompatible with the dashboard.</source>
+ <target>收到的数据为 JSON 2.x 版本格式,目前与仪表盘不兼容。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="04f8a3c7e8ac610e6581960162cc15f55a16696a" datatype="html">
+ <source>No SMART data available.</source>
+ <target>没有可用的 SMART 数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a185c9b97513b3882604ea9bab60edbfac945c15" datatype="html">
+ <source>SMART overall-health self-assessment test result</source>
+ <target>SMART 总体健康状况自评测试结果</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="290e4c9ad42dc6e9176656c864a5faed8053f406" datatype="html">
+ <source>unknown</source>
+ <target>未知</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a03d3c2e459f8f8fa7202c0fce465d6165f9e2b" datatype="html">
+ <source>passed</source>
+ <target>通过</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41435d5a5692c8e412c74deaee95d99dbd3617e1" datatype="html">
+ <source>failed</source>
+ <target>失败</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddd5dd6d930030096ea617f62c82b648a0dd9484" datatype="html">
+ <source>Device Information</source>
+ <target>设备信息</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e149c483d88cfcff11d1c5db85e84af7c3149c4" datatype="html">
+ <source>No device information available for this device.</source>
+ <target>未获取此设备的设备信息。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20cb12827cbe559a7b1da6fdae96041b3b5c3c55" datatype="html">
+ <source>SMART</source>
+ <target>SMART</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380295f37caea93701d071485a38ef0bdba57133" datatype="html">
+ <source>No SMART data available for this device.</source>
+ <target>未获取此设备的 SMART 数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5758c3f16f8749f0f4e2a787f02e8b4da246102f" datatype="html">
+ <source>SMART data is loading.</source>
+ <target>正在加载 SMART 数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5363861031080361352" datatype="html">
+ <source>Smartctl has received an unknown argument (error code <x id="PH" equiv-text="smartData.smartctl_error_code"/>). You may be using an incompatible version of smartmontools. Version &gt;= 7.0 of smartmontools is required to successfully retrieve data.</source>
+ <target>Smartctl 收到未知参数(错误代码 <x id="PH" equiv-text="smartData.smartctl_error_code"/>)。您使用的可能是不兼容的 smartmontools 版本。要成功检索数据,需使用 7.0 或更高版本的 smartmontools。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">61,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5085718566932809950" datatype="html">
+ <source>An error with error code <x id="PH" equiv-text="smartData.smartctl_error_code"/> occurred.</source>
+ <target>发生错误,错误代码 <x id="PH" equiv-text="smartData.smartctl_error_code"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2091295268977103253" datatype="html">
+ <source>Raw</source>
+ <target>裸容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5963653123239768443" datatype="html">
+ <source>Threshold</source>
+ <target>阈值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2893124970059125090" datatype="html">
+ <source>When Failed</source>
+ <target>失败时</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5614367840516299633" datatype="html">
+ <source>Worst</source>
+ <target>最差</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d06ae77f9ec46a4cdd49e7e76c73a411aaf2ee38" datatype="html">
+ <source>Please set a new password.</source>
+ <target>请设置一个新密码。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8b5b3566e88438f51bd5f6caf6c090ed565ba5ed" datatype="html">
+ <source>You will be redirected to the login page afterwards.</source>
+ <target>之后,您将被重定向到登录页面。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cf42e491adc166a337a960eb84d03c0c3f677c8" datatype="html">
+ <source>The old and new passwords must be different.</source>
+ <target>新旧密码必须不同。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90163a3d3746819aef42e829f4446331232f3b66" datatype="html">
+ <source>Password confirmation doesn't match the new password.</source>
+ <target>确认密码与新密码不一致。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0070e83d11da39d6f4bb95065c2675db1610b419" datatype="html">
+ <source>Username is required</source>
+ <target>必须输入用户名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e20f8b8a4706526c9024cc2f39d568345d100dc" datatype="html">
+ <source>Password is required</source>
+ <target>必须输入密码</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f093d9574ab746b231504bd2cbb65f04bd7b00db" datatype="html">
+ <source>Log in</source>
+ <target>登录</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5590086849807274701" datatype="html">
+ <source>Scope</source>
+ <target>作用范围</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327592562693301723" datatype="html">
+ <source>Read</source>
+ <target>读取</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5674286808255988565" datatype="html">
+ <source>Create</source>
+ <target>创建</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4021752662928002901" datatype="html">
+ <source>Update</source>
+ <target>更新</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022070615528435141" datatype="html">
+ <source>Delete</source>
+ <target>删除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ea5c4d8942c00752dcc72e72949c5d9832f6399" datatype="html">
+ <source>Description...</source>
+ <target>描述...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70f45880fce6ac5d8e468e25e82aefbba8098cfe" datatype="html">
+ <source>Permissions</source>
+ <target>权限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="122114774689391224" datatype="html">
+ <source>role</source>
+ <target>角色</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616102757855967475" datatype="html">
+ <source>All</source>
+ <target>所有</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4416727401284087008" datatype="html">
+ <source>Created role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <target>已创建角色 &quot;<x id="PH" equiv-text="roleFormModel.name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3472946357042916911" datatype="html">
+ <source>Updated role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <target>已更新角色 &quot;<x id="PH" equiv-text="roleFormModel.name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="373024661645814027" datatype="html">
+ <source>System Role</source>
+ <target>系统角色</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753648234171918096" datatype="html">
+ <source>Deleted role '<x id="PH" equiv-text="role"/>'</source>
+ <target>已删除角色 &quot;<x id="PH" equiv-text="role"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1674202514578558795" datatype="html">
+ <source>New name</source>
+ <target>新名称</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4857700187193019038" datatype="html">
+ <source>Clone Role</source>
+ <target>克隆角色</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="748631939386170157" datatype="html">
+ <source>Cloned role '<x id="PH" equiv-text="values['newName']"/>' from '<x id="PH_1" equiv-text="name"/>'</source>
+ <target>已从 &quot;<x id="PH_1" equiv-text="name"/>&quot; 克隆角色 &quot;<x id="PH" equiv-text="values['newName']"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="195c31a2f970e790231a6bb94a5e8ca0167406d9" datatype="html">
+ <source>The username already exists.</source>
+ <target>该用户名已存在。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f3bdcce4b2e8c37cd7f0f6c92ef8cff34b039b8" datatype="html">
+ <source>Confirm password</source>
+ <target>确认密码</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cbb979e63ba50e0ca3adfa09cbdcaefd0853fca1" datatype="html">
+ <source>Password confirmation doesn't match the password.</source>
+ <target>确认密码与之前输入的密码不一致。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="96621f9ed2e4ae5204564e583d2c816bedead571" datatype="html">
+ <source>Password expiration date</source>
+ <target>密码超期日期</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48932db3801fe9d5d72a60a3e656bffd17c1c5d9" datatype="html">
+ <source>Password expiration date...</source>
+ <target>密码超期日期...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc" datatype="html">
+ <source>Email</source>
+ <target>邮箱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d0ec081dd61eb4f43aea269077bbe38eae87b7f9" datatype="html">
+ <source>Invalid email.</source>
+ <target>邮箱无效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9610487cbeb5796d34d8601b5ac0c0a65f9e1d19" datatype="html">
+ <source>Roles</source>
+ <target>角色</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8913c216dd506e20e412e144381d8d2a65a84359" datatype="html">
+ <source>User must change password at next logon</source>
+ <target>用户下次登录时必须更改密码</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0051a3479d3ba79135c16dc8cc017950a2cce821" datatype="html">
+ <source>You are about to remove &quot;user read / update&quot; permissions from your own user.</source>
+ <target>您即将删除您自己的 &quot;用户读取/更新&quot; 权限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af4bf9fcb256853f14cf947eb1deb8d7f176d3f9" datatype="html">
+ <source>If you continue, you will no longer be able to add or remove roles from any user.</source>
+ <target>如果继续,您将再也无法为任何用户添加或删除角色。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314291969883771319" datatype="html">
+ <source>There are no roles.</source>
+ <target>没有角色。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4306072924538089180" datatype="html">
+ <source>Created user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <target>已创建用户 &quot;<x id="PH" equiv-text="userFormModel.username"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1349763489797682899" datatype="html">
+ <source>Update user</source>
+ <target>更新用户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8688396456017237992" datatype="html">
+ <source>You were automatically logged out because your roles have been changed.</source>
+ <target>您被自动登出,因为您的角色有了变动。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2335813072344088607" datatype="html">
+ <source>Updated user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <target>已更新用户 &quot;<x id="PH" equiv-text="userFormModel.username"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4768749765465246664" datatype="html">
+ <source>Email</source>
+ <target>邮箱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795890916060309463" datatype="html">
+ <source>Roles</source>
+ <target>角色</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6877445485286599988" datatype="html">
+ <source>Password expiration date</source>
+ <target>密码超期日期</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="705657168061753072" datatype="html">
+ <source>Deleted user '<x id="PH" equiv-text="username"/>'</source>
+ <target>已删除用户 &quot;<x id="PH" equiv-text="username"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="405819296611088743" datatype="html">
+ <source>Failed to delete user '<x id="PH" equiv-text="username"/>'</source>
+ <target>无法删除用户 &quot;<x id="PH" equiv-text="username"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8935387756949610047" datatype="html">
+ <source>You are currently logged in as '<x id="PH" equiv-text="username"/>'.</source>
+ <target>您当前以 &quot;<x id="PH" equiv-text="username"/>&quot; 身份登录。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0eb15f32b2b92d7f3103ef3ff032621888a8dc32" datatype="html">
+ <source>Old password</source>
+ <target>旧密码</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229" datatype="html">
+ <source>New password</source>
+ <target>新密码</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ede41f01c781b168a783cfcefc6fb67d48780d9b" datatype="html">
+ <source>Confirm new password</source>
+ <target>确认新密码</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809196861118879526" datatype="html">
+ <source>password</source>
+ <target>密码</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623124197136601291" datatype="html">
+ <source>Updated user password&quot;</source>
+ <target>已更新用户密码&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be" datatype="html">
+ <source>Users</source>
+ <target>用户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ced3246fa3db31be0f7da06648463f29ba378fbe" datatype="html">
+ <source>Selected Object Gateway:</source>
+ <target>所选对象网关:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c53062af97ebda2a03f905698f58e524ecf8b968" datatype="html">
+ <source>Select Object Gateway</source>
+ <target>选择对象网关</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="235c355afdcbf72953a15d7fc8d0d9e7a6619f46" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Page not Found<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>找不到页面<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aee9d027170f84774f2980537556f5099369b82" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for. The page you requested may have been changed or moved.</source>
+ <target>抱歉,找不到您要查找的数据。您请求的页面可能已被更改或移动。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">22,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2b46fe9a975c6531af77fee858ccd37327980f7" datatype="html">
+ <source>Please consult the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>documentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> on how to configure and enable the <x id="INTERPOLATION" equiv-text="{{ section_info }}"/> management functionality.</source>
+ <target>请参见<x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>文档<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>了解如何配置和启用 <x id="INTERPOLATION" equiv-text="{{ section_info }}"/> 管理功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">26,27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9d57ca7cab78c6f0d27e0d890cb8cf1515e4e30a" datatype="html">
+ <source>Go To Dashboard</source>
+ <target>转到仪表盘</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6578397717654172779" datatype="html">
+ <source>Page Not Found</source>
+ <target>找不到页面</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8185335715884155108" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for.
+ The page you requested may have been changed or moved.</source>
+ <target>抱歉,找不到您要查找的数据。
+您请求的页面可能已被更改或移动。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="143318366100741906" datatype="html">
+ <source>Access Denied</source>
+ <target>访问拒绝</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5384670299771400832" datatype="html">
+ <source>Sorry, you don’t have permission to view this page or resource.</source>
+ <target>抱歉,您无权限浏览页面或资源</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2424411274809083521" datatype="html">
+ <source>User Denied</source>
+ <target>已拒绝用户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7645004872908092358" datatype="html">
+ <source>Sorry, the user does not exist in Ceph.
+ You'll be logged out from the Identity Provider when you retry logging in.</source>
+ <target>抱歉,Ceph 中不存在该用户。
+当您重新尝试登录时,将会从该身份提供者中登出。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">24,25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f286db6ac9482dbf567bc491d49a6eade444895a" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7911416166208830577" datatype="html">
+ <source>Help</source>
+ <target>帮助</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8878700331247603166" datatype="html">
+ <source>Security</source>
+ <target>安全</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8642696205489749843" datatype="html">
+ <source>Trademarks</source>
+ <target>商标</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1481ecd21e760ac919a24e26cf790acd82e40199" datatype="html">
+ <source>Dashboard Settings</source>
+ <target>仪表盘设置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a79aab4ef674bf3f6532292107c0054302236e0f" datatype="html">
+ <source>User management</source>
+ <target>用户管理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="197e0246502ca64d0de0df0d5c2deec51d41ff45" datatype="html">
+ <source>Telemetry configuration</source>
+ <target>遥测配置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85b79c9064aed1ead31ace985f31aa1363f6bdaf" datatype="html">
+ <source>Help</source>
+ <target>帮助</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06638e0f01d82c0786f63aa9832fbe7866b86087" datatype="html">
+ <source>documentation</source>
+ <target>文档</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e351b40b3869a5c7d19c3d4918cb1ac7aaab95c4" datatype="html">
+ <source>API</source>
+ <target>API</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a" datatype="html">
+ <source>About</source>
+ <target>关于</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="049dfd9fe6c78914ad58cf89ac6a631fca28ec74" datatype="html">
+ <source>Logged in user</source>
+ <target>登录的用户</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5022c5ae3ae921c07bf5f881e9b026b4a6708a7" datatype="html">
+ <source>Signed in as <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>以 <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> 身份登录</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9" datatype="html">
+ <source>Change password</source>
+ <target>更改密码</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d22c795daf43877a5f708dca2bccd549eb0471d" datatype="html">
+ <source>Sign out</source>
+ <target>登出</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319e0745bcbc132451569294fa2fa21bf10f555a" datatype="html">
+ <source>Toggle navigation</source>
+ <target>切换导航</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f65253954b66e929a8b4d5ecaf61f9129f8cec64" datatype="html">
+ <source>Dashboard</source>
+ <target>仪表盘</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c95898abff46bfac3ed6eb2afef74597e60b15c" datatype="html">
+ <source>CRUSH map</source>
+ <target>CRUSH 索引</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7b2bc4b86de6e96d353f6bf2b4d793ea3a19ba0" datatype="html">
+ <source>Manager Modules</source>
+ <target>Manager 模块</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb3d5aefff38a814b76da74371cbf02c0789a1ef" datatype="html">
+ <source>Logs</source>
+ <target>日志</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17fc3efe5f9fa4e0289c900cb6202265215a1a27" datatype="html">
+ <source>Monitoring</source>
+ <target>正在监控</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f5d0c10614e8a34f0e2dad33a0568277c50cf69" datatype="html">
+ <source>Block</source>
+ <target>块设备</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3c2562ba992127203dcfd014010b03cb7b8113c6" datatype="html">
+ <source>Mirroring</source>
+ <target>镜像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="811c241d56601b91ef26735b770e64428089b950" datatype="html">
+ <source>iSCSI</source>
+ <target>iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a24eabd99ea5af20f5f94c4484649cd30370042b" datatype="html">
+ <source>NFS</source>
+ <target>NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5276fc60d54d667116babb723641b21281d37271" datatype="html">
+ <source>File Systems</source>
+ <target>文件系统</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9515520496da83179d8b08132f00f575512a1f40" datatype="html">
+ <source>Buckets</source>
+ <target>存储桶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a23e992f6c6e169a38b2b7338b4e5e803b52e0d" datatype="html">
+ <source>Tasks and Notifications</source>
+ <target>任务和通知</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1390461972315002349" datatype="html">
+ <source>The name of the node under which data should be placed.</source>
+ <target>应用于存放数据的节点的名称。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6575341202068728510" datatype="html">
+ <source>The type of CRUSH nodes across which we should separate replicas.</source>
+ <target>我们应为其分隔副本的 CRUSH 节点类型。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3874278445824365480" datatype="html">
+ <source>The device class data should be placed on.</source>
+ <target>应用于存放数据的设备类型。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="675628105428950215" datatype="html">
+ <source>Each object is split in data-chunks parts, each stored on a different OSD.</source>
+ <target>各对象都被分割为数据块,分别存储于不同的 OSD。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5128168460056151476" datatype="html">
+ <source>Compute coding chunks for each object and store them on different OSDs.
+ The number of coding chunks is also the number of OSDs that can be down without losing data.</source>
+ <target>计算各对象的编码块,并存储于不同的 OSD。
+ 编码块的数量等同于在不丢数据的前提下允许同时停用的 OSD 数量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">18,19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8826111293169381132" datatype="html">
+ <source>The jerasure plugin is the most generic and flexible plugin,
+ it is also the default for Ceph erasure coded pools.</source>
+ <target>jerasure 插件是最通用、最灵活的插件,
+ 也是 Ceph 纠删码存储池的默认插件。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">23,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1331133460856304156" datatype="html">
+ <source>The more flexible technique is reed_sol_van : it is enough to set k
+ and m. The cauchy_good technique can be faster but you need to chose the packetsize
+ carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents
+ in the sense that they can only be configured with m=2.</source>
+ <target>reed_sol_van 算法更灵活:它足以设置 k 和 m 值。
+ cauchy_good 算法更快,但您需要谨慎选择 packetsize 值。
+ reed_sol_r6_op、liberation、blaum_roth、 liber8tion 都是与 RAID6 等价的算法,
+ 只能为它们配置 m=2。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">25,28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4577912952562931806" datatype="html">
+ <source>The encoding will be done on packets of bytes size at a time.
+ Choosing the right packet size is difficult.
+ The jerasure documentation contains extensive information on this topic.</source>
+ <target>一次将对多少字节的数据包执行编码。
+ 选择合适的数据包大小很难。
+ Jerasure 文档中包含了有关此主题的详尽信息。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">29,31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6471646852539810855" datatype="html">
+ <source>With the jerasure plugin, when an erasure coded object is stored on
+ multiple OSDs, recovering from the loss of one OSD requires reading from all the others.
+ For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading
+ from the eleven others to repair.
+
+ The lrc erasure code plugin creates local parity chunks to be able to recover using
+ less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create
+ an additional parity chunk for every four OSDs. When a single OSD is lost, it can be
+ recovered with only four OSDs instead of eleven.</source>
+ <target>使用 jerasure 插件时,纠删码编码的对象存储在多个 OSD 上,
+ 丢失一个 OSD,恢复时就需要读取所有其他的 OSD。
+ 例如,如果 jerasure 的配置为 k=8 且 m=4,丢失一个 OSD 后需读取其他十一个 OSD 才能恢复。
+
+ lrc 纠删码插件创建的是局部奇偶校验块,这样只需较少的 OSD 即可恢复。
+ 例如,如果 lrc 的配置为 k=8,m=4 且 l=4,它将为每四个 OSD 创建额外的奇偶校验块。
+ 当一个 OSD 丢失时,它只需四个 OSD 即可恢复,而不需要十一个 OSD。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">34,42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2619235086723330982" datatype="html">
+ <source>Group the coding and data chunks into sets of size locality. For instance,
+ for k=4 and m=2, when locality=3 two groups of three are created. Each set can
+ be recovered without reading chunks from another set.</source>
+ <target>将编码块和数据块分组为大小为 locality 的集合。
+ 例如,当 k=4 且 m=2 时,如果设置 locality=3,将会分组为大小为三的两组。
+ 这样每个组都能自行恢复,无需从另一组读数据块。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">43,45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3298836762557512588" datatype="html">
+ <source>The type of the crush bucket in which each set of chunks defined
+ by l will be stored. For instance, if it is set to rack, each group of l chunks will be
+ placed in a different rack. It is used to create a CRUSH rule step such as step choose
+ rack. If it is not set, no such grouping is done.</source>
+ <target>由 l 定义的块集合将按哪种 crush 桶类型存储。
+ 例如,如果设置为 rack,大小为 l 块的各组将被存入不同的机架。
+ 此值用于创建类似 step choose rack 的 CRUSH 规则步骤。
+ 如果未设置,就不会这样分组。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">46,49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9162461669419243962" datatype="html">
+ <source>The isa plugin encapsulates the ISA library. It only runs on Intel processors.</source>
+ <target>isa 插件封装了 ISA 库,只能在 Intel 处理器上运行。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2389282202903059852" datatype="html">
+ <source>The ISA plugin comes in two Reed Solomon forms.
+ If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.</source>
+ <target>ISA 插件包含两种 Reed Solomon 编码形式。
+ 设置为 reed_sol_van 时表示使用 Vandermonde 算法,设置为 cauchy 时表示使用 Cauchy 算法。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">53,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7319555444402547739" datatype="html">
+ <source>The shec plugin encapsulates the multiple SHEC library.
+ It allows ceph to recover data more efficiently than Reed Solomon codes.</source>
+ <target>Shec 插件封装了 multiple SHEC 库。
+ 与 Reed Solomon 编码相比,它能使 Ceph 更高效地恢复数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">57,58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7723217930035575928" datatype="html">
+ <source>The number of parity chunks each of which includes each data chunk in its
+ calculation range. The number is used as a durability estimator. For instance, if c=2,
+ 2 OSDs can be down without losing data.</source>
+ <target>奇偶校验块数量,它们在各自的计算范围内包含了各数据块。
+ 此数值用作持久性估值。例如,假设 c=2
+ 在不丟失数据的情况下可停用 2 个 OSD。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">59,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2054101840892270818" datatype="html">
+ <source>CLAY (short for coupled-layer) codes are erasure codes designed to
+ bring about significant savings in terms of network bandwidth and disk IO when a failed
+ node/OSD/rack is being repaired.</source>
+ <target>CLAY(耦合层缩写)代码是可用于
+ 在修复故障节点/OSD/机架时显著节省
+ 网络带宽和磁盘 IO 的纠删码。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">64,66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491096236680229427" datatype="html">
+ <source>Number of OSDs requested to send data during recovery of a single chunk.
+ d needs to be chosen such that k+1 &lt;= d &lt;= k+m-1. The larger the d, the better
+ the savings.</source>
+ <target>恢复单个数据块期间请求发送数据的 ODS 数量。
+ 选择的 d 需要大于等于 k+1 且小于等于 k+m-1。d 越大,节省的越多。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">67,69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2625895656705896729" datatype="html">
+ <source>scalar_mds specifies the plugin that is used as a building block
+ in the layered construction. It can be one of jerasure, isa, shec.</source>
+ <target>scalar_mds 指定分层构造中用作构建块
+ 的插件。可以是 jerasure、isa、shec 之一。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">70,71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6639141182731628232" datatype="html">
+ <source>technique specifies the technique that will be picked
+ within the 'scalar_mds' plugin specified. Supported techniques
+ are 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good', 'liber8tion' for jerasure, 'reed_sol_van',
+ 'cauchy' for isa and 'single', 'multiple' for shec.</source>
+ <target>算法指定将会在所指定的 &quot;scalar_mds&quot; 插件中
+ 选择的算法。支持的算法有
+ &quot;reed_sol_van&quot;、&quot;reed_sol_r6_op&quot;、&quot;cauchy_orig&quot;、
+ &quot;cauchy_good&quot;、&quot;liber8tion&quot;(用于 jerasure)、&quot;reed_sol_van&quot;、
+ &quot;cauchy&quot;(用于 isa),&quot;single&quot;、&quot;multiple&quot;(用于 shec)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">72,76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8172892264673403098" datatype="html">
+ <source>The name of the crush bucket used for the first step of the CRUSH rule.
+ For instance step take default.</source>
+ <target>规则集第一步所指向的 CRUSH 桶名称,
+ 例如 step take default。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">80,81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1654284403437084515" datatype="html">
+ <source>Ensure that no two chunks are in a bucket with the same failure
+ domain. For instance, if the failure domain is host no two chunks will be stored on the same
+ host. It is used to create a CRUSH rule step such as step chooseleaf host.</source>
+ <target>确保两个编码块不会存在于同一故障域的桶中。
+ 例如,假设故障域是主机,就不会有两个编码块存储于同一主机上。
+ 此值用于创建类似 step chooseleaf host 的 CRUSH 规则步骤。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">83,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7737703816676512224" datatype="html">
+ <source>Restrict placement to devices of a specific class
+ (e.g., ssd or hdd), using the crush device class names in the CRUSH map.</source>
+ <target>使用 CRUSH 索引中的 crush 设备类型名称,
+ 将归置限制于特定类型的设备(例如,ssd 或 hdd)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9049698214199657456" datatype="html">
+ <source>Set the directory name from which the erasure code plugin is loaded.</source>
+ <target>设置从中加载纠删码插件的目录名称。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5514060020564877279" datatype="html">
+ <source>Allows all operations</source>
+ <target>允许所有操作</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4265406815683383218" datatype="html">
+ <source>Allows only operations that do not modify the server</source>
+ <target>只允许不修改服务器端数据的操作</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="990071930378308183" datatype="html">
+ <source>Allows no access at all</source>
+ <target>完全禁止访问</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7286983657616285612" datatype="html">
+ <source>Please specify a filesystem volume.</source>
+ <target>请指定文件系统卷。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8321762156640395170" datatype="html">
+ <source>The feature is disabled because Orchestrator is not available.</source>
+ <target>该功能已禁用,因为 Orchestrator 不可用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6718394293315494787" datatype="html">
+ <source>The Orchestrator backend doesn't support this feature.</source>
+ <target>Orchestrator 后端不支持此功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5569418400096331461" datatype="html">
+ <source>-- Select the priority --</source>
+ <target>-- 请选择优先级 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="802458941707537739" datatype="html">
+ <source>Low</source>
+ <target>低</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8063651736083474594" datatype="html">
+ <source>High</source>
+ <target>高</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1717753935149218245" datatype="html">
+ <source>The user list data might be stale. If needed, you can manually reload it.</source>
+ <target>用户列表数据可能已过时。如果需要,您可以手动重新加载这些数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/list-with-details.class.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7077550143229856452" datatype="html">
+ <source>Retrieving data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>正在检索 <x id="PH" equiv-text="statusFor"/> 的数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8231424898988217966" datatype="html">
+ <source>Retrieving data.</source>
+ <target>正在检索数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2357645764289315007" datatype="html">
+ <source>Please wait...</source>
+ <target>请稍候...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="232824565824302482" datatype="html">
+ <source>Displaying previously cached data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>正在显示之前缓存的 <x id="PH" equiv-text="statusFor"/> 数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8721257977793603730" datatype="html">
+ <source>Displaying previously cached data.</source>
+ <target>正在显示之前缓存的数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6731313206654246255" datatype="html">
+ <source>Could not load data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>无法加载 <x id="PH" equiv-text="statusFor"/> 的数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3359748695862553898" datatype="html">
+ <source>Could not load data.</source>
+ <target>无法加载数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4836577225879717660" datatype="html">
+ <source>Please check the cluster health.</source>
+ <target>请检查集群健康状况。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1519954996184640001" datatype="html">
+ <source>Error</source>
+ <target>错误</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5037437391296624618" datatype="html">
+ <source>Information</source>
+ <target>信息</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4648900870671159218" datatype="html">
+ <source>Success</source>
+ <target>成功</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3425367071066107827" datatype="html">
+ <source>Danger</source>
+ <target>危险</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c947210e2d162b6225083d18820ab602f58cd2d" datatype="html">
+ <source>Remove the custom configuration value. The default configuration will be inherited and used instead.</source>
+ <target>删除自定义配置值。将继承并改用默认配置。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="454ee9cb60b00446a8fb147fd2cc5eb836320586" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>.</source>
+ <target>输入的值太大!值不得大于 <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fc8a22825131e028336f60ef909ccbd96059703" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>.</source>
+ <target>输入的值太小!值不得小于 <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4dd200b7f9e19048cf90516843b40964f2af3fe9" datatype="html">
+ <source>Copy to Clipboard</source>
+ <target>复制到剪贴板</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6110699a3562eeb15371063c0cf7f6bfd88a0209" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>?</source>
+ <target>您确定要<x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>吗?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="549859e511ba5af0ea03fcaa620c472f08038969" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected items?</source>
+ <target>您确定要<x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/>所选项吗?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="54839ebc827b73c9dc4e1df731c6d36a85036af7" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/>?</source>
+ <target>您确定要<x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/>所选<x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/>吗?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2be8b7f04f0104d3fad90d079d8202b74f758b9a" datatype="html">
+ <source>Yes, I am sure.</source>
+ <target>是的,我确定。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4523728183000855476" datatype="html">
+ <source>documentation</source>
+ <target>文档</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/doc/doc.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3099741642167775297" datatype="html">
+ <source>Download</source>
+ <target>下载</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/download-button/download-button.component.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1417693714872528491" datatype="html">
+ <source>This field is required.</source>
+ <target>这是必填字段!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5321335688371682440" datatype="html">
+ <source>An error occurred.</source>
+ <target>发生错误。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5109325fb160b543f71a51e7511c00575057431" datatype="html">
+ <source>Loading panel data...</source>
+ <target>正在加载面板的相关数据...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a21acde005f80ceadb1391be1e7ff8b6d18188a0" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the monitoring functionality.</source>
+ <target>请参见 <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> 了解如何配置和启用监控功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a0ed4bd7b7add2a6febf7adf58d8cde5e421418" datatype="html">
+ <source>Grafana Dashboard doesn't exist. Please refer to <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to add dashboards to Grafana.</source>
+ <target>Grafana 仪表盘不存在。请参见 <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> 了解如何在 Grafana 中添加仪表盘。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e11830040bd64804a0555de76f291d5832772d4" datatype="html">
+ <source>Grafana Time Picker</source>
+ <target>Grafana 时间选择器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="238c1ba845dd7330e8088165275919a1debf1ca3" datatype="html">
+ <source>Reset Settings</source>
+ <target>重置设置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7888499255176013171" datatype="html">
+ <source>Last 5 minutes</source>
+ <target>过去 5 分钟</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6892361549797455305" datatype="html">
+ <source>Last 15 minutes</source>
+ <target>过去 15 分钟</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2653641162607195423" datatype="html">
+ <source>Last 30 minutes</source>
+ <target>过去 30 分钟</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4117793269024790392" datatype="html">
+ <source>Last 1 hour (Default)</source>
+ <target>过去 1 小时(默认值)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2645733658763754077" datatype="html">
+ <source>Last 3 hours</source>
+ <target>过去 3 小时</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7360078715633936807" datatype="html">
+ <source>Last 6 hours</source>
+ <target>过去 6 小时</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5055313582241816303" datatype="html">
+ <source>Last 12 hours</source>
+ <target>过去 12 小时</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9186529157286281693" datatype="html">
+ <source>Last 24 hours</source>
+ <target>过去 24 小时</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4498682414491138092" datatype="html">
+ <source>Yesterday</source>
+ <target>昨天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="929003859318769922" datatype="html">
+ <source>Today so far</source>
+ <target>今天到目前为止</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5525943133564968818" datatype="html">
+ <source>Day before yesterday</source>
+ <target>前天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6168755117727892817" datatype="html">
+ <source>Last 2 days</source>
+ <target>过去 2 天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7574807704224200535" datatype="html">
+ <source>This day last week</source>
+ <target>上周的今天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4420128118950221234" datatype="html">
+ <source>Previous week</source>
+ <target>上个星期</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4063965603321223683" datatype="html">
+ <source>This week so far</source>
+ <target>本周以来</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4873149362496451858" datatype="html">
+ <source>Last 7 days</source>
+ <target>过去 7 天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8586908745456864217" datatype="html">
+ <source>Previous month</source>
+ <target>上个月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1647573304710886499" datatype="html">
+ <source>This month so far</source>
+ <target>本月以来</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2949150997160654358" datatype="html">
+ <source>Last 30 days</source>
+ <target>过去 30 天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7469939859049484736" datatype="html">
+ <source>Last 90 days</source>
+ <target>过去 90 天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847501198811458781" datatype="html">
+ <source>Last 6 months</source>
+ <target>过去 6 个月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7447583558445881102" datatype="html">
+ <source>Last 1 year</source>
+ <target>过去 1 年</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="100513227838842152" datatype="html">
+ <source>Previous year</source>
+ <target>去年</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3650872673621947074" datatype="html">
+ <source>This year so far</source>
+ <target>今年以来</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1262816694819959075" datatype="html">
+ <source>Last 2 years</source>
+ <target>过去 2 年</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7878813844917362690" datatype="html">
+ <source>Last 5 years</source>
+ <target>过去 5 年</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3fb5709e10166cbc85970cbff103db227dbeb813" datatype="html">
+ <source>Select a Language</source>
+ <target>请选择语言</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/language-selector/language-selector.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e52e9143145e1db5146258de81eae018a407b31" datatype="html">
+ <source>Clear notifications</source>
+ <target>清除通知</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0b07bb6b7ff21ede439dd04eaf8872d1ecb84d8" datatype="html">
+ <source>Remove notification</source>
+ <target>删除通知</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e17a1d75189da843f541f7764f188f2b19a97df2" datatype="html">
+ <source>Duration:</source>
+ <target>时长:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d4b37c6675c5b436a54c43d6716eec835e1aa7f" datatype="html">
+ <source>There are no notifications.</source>
+ <target>没有通知。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b20e42ac4354d449f2718428b5390933eef0c1b9" datatype="html">
+ <source>The feature is not supported in the current Orchestrator.</source>
+ <target>当前的 Orchestrator 不支持该功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a437b8f93cf826817c04a4277edb1ae3a93a1ab" datatype="html">
+ <source>Orchestrator is not available. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the functionality.</source>
+ <target>Orchestrator 不可用。请参见 <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> 了解如何配置和启用该功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">7,9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20b3d45b0c08a2951a9974fa20505e4de95250c9" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>less than 1<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day. Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <target>您的密码将在 <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>1 天内<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>超期。请点击<x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>此处<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>立即更改。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">9,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f34088c155e40ffb23770a465a65868ce772b2" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day(s). Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <target>您的密码将在 <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> 天后超期。请点击<x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>此处<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>立即更改。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8d1785038d461ec66b5799db21864182b35900a" datatype="html">
+ <source>Refresh</source>
+ <target>刷新</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/refresh-selector/refresh-selector.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3417247046175131869" datatype="html">
+ <source>No items selected.</source>
+ <target>未选择项目。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1034353870189672674" datatype="html">
+ <source>Deselect item to select again</source>
+ <target>取消选择以重新选择</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4879298070255432995" datatype="html">
+ <source>Selection limit reached</source>
+ <target>达到选择项数上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001227209911602786" datatype="html">
+ <source>Filter tags</source>
+ <target>过滤标记</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="791789583719406586" datatype="html">
+ <source>Add badge</source>
+ <target>添加徽章</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="699988676752930063" datatype="html">
+ <source>There are no items available.</source>
+ <target>没有可用的项目。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6702323d3760e3db0e2e785d567469d18beb120" datatype="html">
+ <source>The Ceph community needs your help to continue improving: please <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>Activate<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> the <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Telemetry<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> module.</source>
+ <target>Ceph 需要您的帮助以持续改进:请<x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>激活<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/><x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>遥测<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>模块。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.html</context>
+ <context context-type="linenumber">8,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8770134622386151776" datatype="html">
+ <source>Telemetry activation reminder muted</source>
+ <target>遥测激活提醒功能已禁用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8352450862052130357" datatype="html">
+ <source>You can activate the module on the Telemetry configuration page (&lt;b&gt;Dashboard Settings&lt;/b&gt; -&gt; &lt;b&gt;Telemetry configuration&lt;/b&gt;) at any time.</source>
+ <target>您随时都可在 &quot;遥测配置&quot; 页面(&lt;b&gt;仪表盘设置&lt;/b&gt; -&gt; &lt;b&gt;遥测配置&lt;/b&gt;)中激活该模块。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bc9e5365a581105ce37cf47d1d74e4ad9eb75ce" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e634c306cab9e8879c3392593714c1ceab85437d" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3249513483374643425" datatype="html">
+ <source>Add</source>
+ <target>添加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4359847060009771702" datatype="html">
+ <source>Set</source>
+ <target>设置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935187492052582731" datatype="html">
+ <source>Submit</source>
+ <target>提交</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4814285799071780083" datatype="html">
+ <source>Remove</source>
+ <target>删除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8363450564548681668" datatype="html">
+ <source>Unset</source>
+ <target>取消设置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2159130950882492111" datatype="html">
+ <source>Cancel</source>
+ <target>取消</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1295614462098694869" datatype="html">
+ <source>Preview</source>
+ <target>预览</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2354817630223808522" datatype="html">
+ <source>Move</source>
+ <target>移动</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3885497195825665706" datatype="html">
+ <source>Next</source>
+ <target>下一步</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8890553633144307762" datatype="html">
+ <source>Back</source>
+ <target>返回</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5834780181397311898" datatype="html">
+ <source>Clone</source>
+ <target>克隆</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4323470180912194028" datatype="html">
+ <source>Copy</source>
+ <target>复制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2131301778880826094" datatype="html">
+ <source>Deep Scrub</source>
+ <target>深层洗刷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1704447209800801558" datatype="html">
+ <source>Destroy</source>
+ <target>销毁</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8343007008325027187" datatype="html">
+ <source>Evict</source>
+ <target>逐出</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="408179081163888126" datatype="html">
+ <source>Flatten</source>
+ <target>展开</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="318900679147387932" datatype="html">
+ <source>Mark Down</source>
+ <target>标记为停用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5275142643521766706" datatype="html">
+ <source>Mark In</source>
+ <target>标记为加入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6973272903386150199" datatype="html">
+ <source>Mark Lost</source>
+ <target>标记为丢失</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1962653792210847411" datatype="html">
+ <source>Mark Out</source>
+ <target>标记为除名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4424610588915076517" datatype="html">
+ <source>Protect</source>
+ <target>保护</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6041115344061899387" datatype="html">
+ <source>Rename</source>
+ <target>重命名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">164</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6770769801335635194" datatype="html">
+ <source>Restore</source>
+ <target>恢复</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2003230525878010676" datatype="html">
+ <source>Reweight</source>
+ <target>重设权重</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5430834128563178593" datatype="html">
+ <source>Scrub</source>
+ <target>洗刷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8461842260159597706" datatype="html">
+ <source>Show</source>
+ <target>显示</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5655608100705734230" datatype="html">
+ <source>Move to Trash</source>
+ <target>移至回收站</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4622393909937403117" datatype="html">
+ <source>Unprotect</source>
+ <target>解除保护</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1230154438678955604" datatype="html">
+ <source>Change</source>
+ <target>更改</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8450843381175865415" datatype="html">
+ <source>Enter Maintenance</source>
+ <target>进入维护模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1610181371597502589" datatype="html">
+ <source>Exit Maintenance</source>
+ <target>退出维护模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="676511611419004737" datatype="html">
+ <source>Start Drain</source>
+ <target>开始排空</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7170653322511987983" datatype="html">
+ <source>Stop Drain</source>
+ <target>停止排空</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5528551262937858942" datatype="html">
+ <source>Recreate</source>
+ <target>重新创建</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2502364444688691031" datatype="html">
+ <source>Expire</source>
+ <target>过期</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6381490568322624964" datatype="html">
+ <source>Deleted</source>
+ <target>已删除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="231679111972850796" datatype="html">
+ <source>Added</source>
+ <target>已添加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5406093358072761930" datatype="html">
+ <source>Removed</source>
+ <target>已删除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3008573030448240863" datatype="html">
+ <source>Edited</source>
+ <target>已编辑</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4381944803872489731" datatype="html">
+ <source>Canceled</source>
+ <target>已取消</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754993936947658096" datatype="html">
+ <source>Previewed</source>
+ <target>已预览</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6001163963116907226" datatype="html">
+ <source>Moved</source>
+ <target>已将</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4932744777596632840" datatype="html">
+ <source>Cloned</source>
+ <target>已克隆</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2115592966120408375" datatype="html">
+ <source>Copied</source>
+ <target>已复制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7937474560394832586" datatype="html">
+ <source>Deep Scrubbed</source>
+ <target>已深层洗刷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6321562733889197649" datatype="html">
+ <source>Destroyed</source>
+ <target>已销毁</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7460162290177581995" datatype="html">
+ <source>Flattened</source>
+ <target>已展开</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3662010055028969035" datatype="html">
+ <source>Marked Down</source>
+ <target>已标记为停用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5880434235404894589" datatype="html">
+ <source>Marked In</source>
+ <target>已标记为加入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="266997194072682078" datatype="html">
+ <source>Marked Lost</source>
+ <target>已标记为丢失</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">250</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4010544044592534535" datatype="html">
+ <source>Marked Out</source>
+ <target>已标记为除名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4776304093333411035" datatype="html">
+ <source>Protected</source>
+ <target>受保护</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2700903921419382511" datatype="html">
+ <source>Purged</source>
+ <target>已清除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5488667333459350160" datatype="html">
+ <source>Renamed</source>
+ <target>已重命名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8044659850000829751" datatype="html">
+ <source>Restored</source>
+ <target>已恢复</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559472082694466366" datatype="html">
+ <source>Reweighted</source>
+ <target>已重设权重</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022271525067453676" datatype="html">
+ <source>Rolled back</source>
+ <target>已回滚</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2483217756816388123" datatype="html">
+ <source>Scrubbed</source>
+ <target>已洗刷</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7200036055090632378" datatype="html">
+ <source>Showed</source>
+ <target>已显示</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7609648817347881129" datatype="html">
+ <source>Moved to Trash</source>
+ <target>已移至回收站</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7810326403606456469" datatype="html">
+ <source>Unprotected</source>
+ <target>已解除保护</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5620774899056099259" datatype="html">
+ <source>Recreated</source>
+ <target>已重新创建</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464749780222721589" datatype="html">
+ <source>Expired</source>
+ <target>已过期</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">266</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e5e23363e949f7dcbaf034bdb141a561132a10e" datatype="html">
+ <source>Clear filters</source>
+ <target>清除过滤器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80cc9a12d4bf6fe454ed94b379eeaf915f920bb7" datatype="html">
+ <source>selected</source>
+ <target>个已选中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <note priority="1" from="description">X selected</note>
+ </trans-unit>
+ <trans-unit id="0cb77511a9a148e05b9adf36cc07269956fbb29d" datatype="html">
+ <source>found</source>
+ <target>个已找到</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <note priority="1" from="description">X found</note>
+ </trans-unit>
+ <trans-unit id="79347388740c50b7ac97e144c2494bb62912f312" datatype="html">
+ <source>total</source>
+ <target>总数</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <note priority="1" from="description">X total</note>
+ </trans-unit>
+ <trans-unit id="2a3dab422cc892db037db8632bb84a6bf496e2d1" datatype="html">
+ <source>Expand/Collapse Row</source>
+ <target>展开/收起行</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4047162422391207122" datatype="html">
+ <source>Failed to load data.</source>
+ <target>无法加载数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.ts</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="709331713250198508" datatype="html">
+ <source>Loading form data...</source>
+ <target>正在加载表单数据...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3850344644863430180" datatype="html">
+ <source>Form data could not be loaded.</source>
+ <target>无法加载表单数据。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4626760504772708998" datatype="html">
+ <source>Size has to be at least <x id="PH" equiv-text="value"/> or more</source>
+ <target>大小必须大于或等于 <x id="PH" equiv-text="value"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">428</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2880361802894657892" datatype="html">
+ <source>Size has to be at most <x id="PH" equiv-text="value"/> or less</source>
+ <target>大小必须小于或等于 <x id="PH" equiv-text="value"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2807800733729323332" datatype="html">
+ <source>Yes</source>
+ <target>是</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3542042671420335679" datatype="html">
+ <source>No</source>
+ <target>否</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7789266940050748913" datatype="html">
+ <source>in %s</source>
+ <target>%s后</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565573880632900017" datatype="html">
+ <source>%s ago</source>
+ <target>%s前</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="220300059326988179" datatype="html">
+ <source>a few seconds</source>
+ <target>几秒</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2761143993878941513" datatype="html">
+ <source>%d seconds</source>
+ <target>%d 秒</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7094767962693903153" datatype="html">
+ <source>a minute</source>
+ <target>一分钟</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7597613755904774250" datatype="html">
+ <source>%d minutes</source>
+ <target>%d 分钟</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2757762976030115752" datatype="html">
+ <source>an hour</source>
+ <target>一小时</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9118454901758656303" datatype="html">
+ <source>%d hours</source>
+ <target>%d 小时</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7435193742089920080" datatype="html">
+ <source>a day</source>
+ <target>一天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1821334622562842480" datatype="html">
+ <source>%d days</source>
+ <target>%d 天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7375306199026780379" datatype="html">
+ <source>a week</source>
+ <target>一周</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7272688256541915488" datatype="html">
+ <source>%d weeks</source>
+ <target>%d 周</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5761124614324704118" datatype="html">
+ <source>a month</source>
+ <target>一个月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="352195662913351589" datatype="html">
+ <source>%d months</source>
+ <target>%d 个月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7562153591649199139" datatype="html">
+ <source>a year</source>
+ <target>一年</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5424759741855527370" datatype="html">
+ <source>%d years</source>
+ <target>%d 年</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7738182956549158907" datatype="html">
+ <source>Required rules for passwords:</source>
+ <target>密码必须遵循的规则:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8839765875053270528" datatype="html">
+ <source>Must contain at least <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> characters</source>
+ <target>必须至少包含 <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> 个字符</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3098731108593590794" datatype="html">
+ <source>Must not be the same as the previous one</source>
+ <target>不得与之前的密码相同</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9150236741862848105" datatype="html">
+ <source>Cannot contain the username</source>
+ <target>不能包含用户名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6395043854518867543" datatype="html">
+ <source>Cannot contain any configured keyword</source>
+ <target>不能包含任何配置的关键字</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="907558624910601703" datatype="html">
+ <source>Cannot contain any repetitive characters e.g. &quot;aaa&quot;</source>
+ <target>不能包含任何重复字符,例如 &quot;aaa&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514384270734082343" datatype="html">
+ <source>Cannot contain any sequential characters e.g. &quot;abc&quot;</source>
+ <target>不能包含任何顺序字符,例如 &quot;abc&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4119354814383293871" datatype="html">
+ <source>Must consist of characters from the following groups:
+ * Alphabetic a-z, A-Z
+ * Numbers 0-9
+ * Special chars: !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * Any other characters (signs)</source>
+ <target>必须包含以下类型的字符:
+ * 字母 a-z、A-Z
+ * 数字 0-9
+ * 特殊字符:!&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * 任何其他字符(符号)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">30,34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8649061117624699581" datatype="html">
+ <source>Your matcher seems to match no currently defined rule or active alert.</source>
+ <target>您的匹配器似乎与当前定义的任何规则或活动告警均不匹配。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7122912874364762704" datatype="html">
+ <source>no active alerts</source>
+ <target>没有活动告警</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7388215679576832341" datatype="html">
+ <source>1 active alert</source>
+ <target>1 条活动告警</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3112400568960537267" datatype="html">
+ <source><x id="PH" equiv-text="alerts"/> active alerts</source>
+ <target><x id="PH" equiv-text="alerts"/> 条活动告警</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6264717417287230743" datatype="html">
+ <source>Matches 1 rule</source>
+ <target>匹配 1 条规则</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054663176394183966" datatype="html">
+ <source>Matches <x id="PH" equiv-text="rules"/> rules</source>
+ <target>匹配 <x id="PH" equiv-text="rules"/> 条规则</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6674225401121099210" datatype="html">
+ <source><x id="PH" equiv-text="rule"/> with <x id="PH_1" equiv-text="alert"/>.</source>
+ <target>具有 <x id="PH_1" equiv-text="alert"/> 的 <x id="PH" equiv-text="rule"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5659908877047925719" datatype="html">
+ <source>Quality of Service</source>
+ <target>服务质量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1277565045885499475" datatype="html">
+ <source>BPS Limit</source>
+ <target>BPS 上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2289210323987692906" datatype="html">
+ <source>The desired limit of IO bytes per second.</source>
+ <target>所需的每秒 IO 字节数上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753589939879013605" datatype="html">
+ <source>IOPS Limit</source>
+ <target>IOPS 上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2213985059444278522" datatype="html">
+ <source>The desired limit of IO operations per second.</source>
+ <target>所需的每秒 IO 操作次数上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2487530611825582289" datatype="html">
+ <source>Read BPS Limit</source>
+ <target>读 BPS 上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8071352270469595250" datatype="html">
+ <source>The desired limit of read bytes per second.</source>
+ <target>所需的每秒内读取的字节数上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1632513758247239690" datatype="html">
+ <source>Read IOPS Limit</source>
+ <target>读 IOPS 上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2361786794607418566" datatype="html">
+ <source>The desired limit of read operations per second.</source>
+ <target>所需的每秒读操作次数上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="894600353504285551" datatype="html">
+ <source>Write BPS Limit</source>
+ <target>写 BPS 上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911437671369366025" datatype="html">
+ <source>The desired limit of write bytes per second.</source>
+ <target>所需的每秒内写入的字节数上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2947346368707443195" datatype="html">
+ <source>Write IOPS Limit</source>
+ <target>写 IOPS 上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5506349527983391356" datatype="html">
+ <source>The desired limit of write operations per second.</source>
+ <target>所需的每秒写操作次数上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559424229658244943" datatype="html">
+ <source>BPS Burst</source>
+ <target>BPS 突发</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3454058701331860330" datatype="html">
+ <source>The desired burst limit of IO bytes.</source>
+ <target>所需的 IO 字节数突发上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171005761926448741" datatype="html">
+ <source>IOPS Burst</source>
+ <target>IOPS 突发</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4939532784700485729" datatype="html">
+ <source>The desired burst limit of IO operations.</source>
+ <target>所需的 IO 操作次数突发上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6273492199526646930" datatype="html">
+ <source>Read BPS Burst</source>
+ <target>读 BPS 突发</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3105467595643777520" datatype="html">
+ <source>The desired burst limit of read bytes.</source>
+ <target>所需的读取的字节数突发上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2170715106679765467" datatype="html">
+ <source>Read IOPS Burst</source>
+ <target>读 IOPS 突发</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6234106755510510672" datatype="html">
+ <source>The desired burst limit of read operations.</source>
+ <target>所需的读操作次数突发上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="228509518172572466" datatype="html">
+ <source>Write BPS Burst</source>
+ <target>写 BPS 突发</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7803279807796571240" datatype="html">
+ <source>The desired burst limit of write bytes.</source>
+ <target>所需的写入的字节数突发上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9125474584914848055" datatype="html">
+ <source>Write IOPS Burst</source>
+ <target>写 IOPS 突发</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5839129348567326667" datatype="html">
+ <source>The desired burst limit of write operations.</source>
+ <target>所需的写操作次数突发上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="614961883076556986" datatype="html">
+ <source>Failed to <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></source>
+ <target>无法<x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="489145301781720653" datatype="html">
+ <source>Executing</source>
+ <target>正在执行</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4238828029954346941" datatype="html">
+ <source>execute</source>
+ <target>执行</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7196604637389554584" datatype="html">
+ <source>Executed</source>
+ <target>已执行</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4418441687454700644" datatype="html">
+ <source>unknown task</source>
+ <target>未知任务</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8667665916832796867" datatype="html">
+ <source>Creating</source>
+ <target>正在创建</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6031236679730054907" datatype="html">
+ <source>create</source>
+ <target>创建</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5593033420216313122" datatype="html">
+ <source>Updating</source>
+ <target>正在更新</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6100869651653026893" datatype="html">
+ <source>update</source>
+ <target>更新</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3141301060598402455" datatype="html">
+ <source>Deleting</source>
+ <target>正在删除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3420504288275541125" datatype="html">
+ <source>Adding</source>
+ <target>正在添加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1059784693423848532" datatype="html">
+ <source>add</source>
+ <target>添加</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594819887188505274" datatype="html">
+ <source>Removing</source>
+ <target>正在删除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2123171795960509943" datatype="html">
+ <source>remove</source>
+ <target>删除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1946427188770321847" datatype="html">
+ <source>Importing</source>
+ <target>正在导入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8495827411619139669" datatype="html">
+ <source>import</source>
+ <target>导入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218459863491436562" datatype="html">
+ <source>Imported</source>
+ <target>已导入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6534993668932538712" datatype="html">
+ <source>RBD '<x id="PH" equiv-text="metadata.image_spec"/>'</source>
+ <target>RBD &quot;<x id="PH" equiv-text="metadata.image_spec"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8237287859948228705" datatype="html">
+ <source>RBD snapshot '<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>'</source>
+ <target>RBD 快照 &quot;<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2328067975897167268" datatype="html">
+ <source>mirroring site name</source>
+ <target>镜像站点名称</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4433460322631470833" datatype="html">
+ <source>bootstrap token</source>
+ <target>引导令牌</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7044591639782280183" datatype="html">
+ <source>mirror mode for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>存储池 &quot;<x id="PH" equiv-text="metadata.pool_name"/>&quot; 的镜像模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7109746474198366468" datatype="html">
+ <source>mirror peer for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>存储池 &quot;<x id="PH" equiv-text="metadata.pool_name"/>&quot; 的镜像对等</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6201476020617351396" datatype="html">
+ <source>all dashboards</source>
+ <target>所有仪表盘</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7268953097700363232" datatype="html">
+ <source>Identifying</source>
+ <target>正在标识</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4337678035264231187" datatype="html">
+ <source>identify</source>
+ <target>标识</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7257219307556106552" datatype="html">
+ <source>Identified</source>
+ <target>已标识</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6002370161381995023" datatype="html">
+ <source>device '<x id="PH" equiv-text="metadata.device"/>' on host '<x id="PH_1" equiv-text="metadata.hostname"/>'</source>
+ <target>主机 &quot;<x id="PH_1" equiv-text="metadata.hostname"/>&quot; 上的设备 &quot;<x id="PH" equiv-text="metadata.device"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5580298273054260850" datatype="html">
+ <source>OSDs (DriveGroups: <x id="PH" equiv-text="metadata.tracking_id"/>)</source>
+ <target>OSD(DriveGroup:<x id="PH" equiv-text="metadata.tracking_id"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2182125722527364040" datatype="html">
+ <source>Name is already used by <x id="PH" equiv-text="this.pool(metadata)"/>.</source>
+ <target>该名称已被 <x id="PH" equiv-text="this.pool(metadata)"/> 使用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">182</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7892856315477304281" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> is busy.</source>
+ <target><x id="PH" equiv-text="this.rbd.default(metadata)"/> 正忙。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4690045751984117407" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> contains snapshots.</source>
+ <target><x id="PH" equiv-text="this.rbd.default(metadata)"/> 包含快照。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="562148565853868662" datatype="html">
+ <source>Cloning</source>
+ <target>正在克隆</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1197352830433807469" datatype="html">
+ <source>clone</source>
+ <target>克隆</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1692004144561317867" datatype="html">
+ <source>Snapshot of <x id="PH" equiv-text="this.rbd.child(metadata)"/> must be protected.</source>
+ <target><x id="PH" equiv-text="this.rbd.child(metadata)"/> 的快照必须受到保护。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8531200838331320284" datatype="html">
+ <source>Copying</source>
+ <target>正在复制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6862265996781523030" datatype="html">
+ <source>copy</source>
+ <target>复制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3556912098733712857" datatype="html">
+ <source>Flattening</source>
+ <target>正在展开</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2488773646187451754" datatype="html">
+ <source>flatten</source>
+ <target>展开</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="704305783678486635" datatype="html">
+ <source>Cannot unprotect <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> because it contains child images.</source>
+ <target>无法将 <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> 解除保护,因为它包含子映像。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">223,225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101271773452792348" datatype="html">
+ <source>Cannot delete <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/> because it's protected.</source>
+ <target>无法删除 <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/>,因为它受到保护。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5143010940199748580" datatype="html">
+ <source>Rolling back</source>
+ <target>正在回滚</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1315686250907089544" datatype="html">
+ <source>rollback</source>
+ <target>回滚</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5010267418211867946" datatype="html">
+ <source>Moving</source>
+ <target>正在将</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4366763205960752449" datatype="html">
+ <source>move</source>
+ <target>将</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="695867152524584829" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_spec"/>' to trash</source>
+ <target>映像 &quot;<x id="PH" equiv-text="metadata.image_spec"/>&quot; 移至回收站</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423442774536615202" datatype="html">
+ <source>Could not find image.</source>
+ <target>找不到映像。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2622324641113512527" datatype="html">
+ <source>Restoring</source>
+ <target>正在将</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3347932678307141902" datatype="html">
+ <source>restore</source>
+ <target>将</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7488038030362249932" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>' into '<x id="PH_1" equiv-text="metadata.new_image_name"/>'</source>
+ <target>映像 &quot;<x id="PH" equiv-text="metadata.image_id_spec"/>&quot; 移至 &quot;<x id="PH_1" equiv-text="metadata.new_image_name"/>&quot; 中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565688512490959949" datatype="html">
+ <source>Image name '<x id="PH" equiv-text="metadata.new_image_name"/>' is already in use.</source>
+ <target>映像名称 &quot;<x id="PH" equiv-text="metadata.new_image_name"/>&quot; 已被使用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6331051389974655106" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>'</source>
+ <target>映像 &quot;<x id="PH" equiv-text="metadata.image_id_spec"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8245559899946787147" datatype="html">
+ <source>Purging</source>
+ <target>正在清除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7879437654311684252" datatype="html">
+ <source>purge</source>
+ <target>清除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1440427157062670480" datatype="html">
+ <source>all pools</source>
+ <target>所有存储池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8677740163708263843" datatype="html">
+ <source>images from <x id="PH" equiv-text="message"/></source>
+ <target><x id="PH" equiv-text="message"/> 中的映像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011237345035114219" datatype="html">
+ <source>Cannot disable mirroring because it contains a peer.</source>
+ <target>因为它包含对等,无法禁用镜像功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">292</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7391584598242145869" datatype="html">
+ <source>host '<x id="PH" equiv-text="metadata.hostname"/>'</source>
+ <target>主机 &quot;<x id="PH" equiv-text="metadata.hostname"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6964302691596180722" datatype="html">
+ <source>OSD '<x id="PH" equiv-text="metadata.svc_id"/>'</source>
+ <target>OSD &quot;<x id="PH" equiv-text="metadata.svc_id"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="488305686602466689" datatype="html">
+ <source>pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>存储池 &quot;<x id="PH" equiv-text="metadata.pool_name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5921392748828575278" datatype="html">
+ <source>erasure code profile '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <target>纠删码配置 &quot;<x id="PH" equiv-text="metadata.name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2423915105798557698" datatype="html">
+ <source>crush rule '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <target>Crush 规则 &quot;<x id="PH" equiv-text="metadata.name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">370</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8273044996643438592" datatype="html">
+ <source>target '<x id="PH" equiv-text="metadata.target_iqn"/>'</source>
+ <target>目标 &quot;<x id="PH" equiv-text="metadata.target_iqn"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5474643443735437364" datatype="html">
+ <source>NFS '<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>'</source>
+ <target>NFS &quot;<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">378,380</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2235495382025026939" datatype="html">
+ <source>Service '<x id="PH" equiv-text="metadata.service_name"/>'</source>
+ <target>服务 &quot;<x id="PH" equiv-text="metadata.service_name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ </body>
+ </file>
+</xliff> \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.zh-TW.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.zh-TW.xlf
new file mode 100644
index 000000000..7755d924d
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.zh-TW.xlf
@@ -0,0 +1,14884 @@
+<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en-US" datatype="plaintext" original="ng2.template" target-language="zh-TW">
+ <body>
+ <trans-unit id="ngb.alert.close" datatype="html">
+ <source>Close</source>
+ <target>關閉</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/alert/alert.ts</context>
+ <context context-type="linenumber">58,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.slide-number" datatype="html">
+ <source> Slide <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> of <x id="INTERPOLATION_1" equiv-text="; private _pa"/> </source>
+ <target>第 <x id="INTERPOLATION" equiv-text="OnHover$ = new"/> 張 (共 <x id="INTERPOLATION_1" equiv-text="; private _pa"/> 張)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">114,118</context>
+ </context-group>
+ <note priority="1" from="description">Currently selected slide number read by screen reader</note>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.previous" datatype="html">
+ <source>Previous</source>
+ <target>上一張</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">132,134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.carousel.next" datatype="html">
+ <source>Next</source>
+ <target>下一張</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/carousel/carousel.ts</context>
+ <context context-type="linenumber">147,152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-month" datatype="html">
+ <source>Select month</source>
+ <target>選取月份</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">44,49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">49,50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.select-year" datatype="html">
+ <source>Select year</source>
+ <target>選取年份</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">59,63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation-select.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.previous-month" datatype="html">
+ <source>Previous month</source>
+ <target>上個月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">24,27</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">35,36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.datepicker.next-month" datatype="html">
+ <source>Next month</source>
+ <target>下個月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">47,50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/datepicker/datepicker-navigation.ts</context>
+ <context context-type="linenumber">60,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first" datatype="html">
+ <source>««</source>
+ <target>««</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">182,183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous" datatype="html">
+ <source>«</source>
+ <target>«</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">186,190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next" datatype="html">
+ <source>»</source>
+ <target>»</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">194,195</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last" datatype="html">
+ <source>»»</source>
+ <target>»»</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">201,204</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.first-aria" datatype="html">
+ <source>First</source>
+ <target>第一張</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">208,209</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.previous-aria" datatype="html">
+ <source>Previous</source>
+ <target>上一張</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">215,216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.next-aria" datatype="html">
+ <source>Next</source>
+ <target>下一張</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">226,228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.pagination.last-aria" datatype="html">
+ <source>Last</source>
+ <target>最後一張</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/pagination/pagination.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.progressbar.value" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="; } /** *"/></source>
+ <target><x id="INTERPOLATION" equiv-text="; } /** *"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/progressbar/progressbar.ts</context>
+ <context context-type="linenumber">32,38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.HH" datatype="html">
+ <source>HH</source>
+ <target>HH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">40,41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.hours" datatype="html">
+ <source>Hours</source>
+ <target>小時</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.MM" datatype="html">
+ <source>MM</source>
+ <target>MM</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">51,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.minutes" datatype="html">
+ <source>Minutes</source>
+ <target>分鐘</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-hours" datatype="html">
+ <source>Increment hours</source>
+ <target>遞增小時數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">63,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-hours" datatype="html">
+ <source>Decrement hours</source>
+ <target>遞減小時數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">69,70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-minutes" datatype="html">
+ <source>Increment minutes</source>
+ <target>遞增分鐘數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">76,78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-minutes" datatype="html">
+ <source>Decrement minutes</source>
+ <target>遞減分鐘數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">82,84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.SS" datatype="html">
+ <source>SS</source>
+ <target>SS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.seconds" datatype="html">
+ <source>Seconds</source>
+ <target>秒</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">92,93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.increment-seconds" datatype="html">
+ <source>Increment seconds</source>
+ <target>遞增秒數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">100,101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.decrement-seconds" datatype="html">
+ <source>Decrement seconds</source>
+ <target>遞減秒數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">106,110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.AM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></source>
+ <target><x id="INTERPOLATION" equiv-text="NgbTime; pr"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">115,121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.timepicker.PM" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="t() meridian: b"/></source>
+ <target><x id="INTERPOLATION" equiv-text="t() meridian: b"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/timepicker/timepicker.ts</context>
+ <context context-type="linenumber">123,131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ngb.toast.close-aria" datatype="html">
+ <source>Close</source>
+ <target>關閉</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">node_modules/src/toast/toast.ts</context>
+ <context context-type="linenumber">78,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8835b9e49a3348b0a2f2162c21118af1f4bee45a" datatype="html">
+ <source>Must be greater than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>.</source>
+ <target>必須大於或等於 <x id="INTERPOLATION" equiv-text="{{ limits['min'] }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbddac59563c8c126e3fe28691e4e247614fcbd1" datatype="html">
+ <source>Must be less than or equal to <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>.</source>
+ <target>必須小於或等於 <x id="INTERPOLATION" equiv-text="{{ limits['max'] }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-setting/iscsi-setting.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5" datatype="html">
+ <source>Overview</source>
+ <target>綜覽</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bbd2045d5c37e4bb39a3c0fb62ea1ddf70a12838" datatype="html">
+ <source>Targets</source>
+ <target>目標</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a674ab267d1934bf395f87ca1503fd474296893f" datatype="html">
+ <source>iSCSI Topology</source>
+ <target>iSCSI 拓撲</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8953033926734869941" datatype="html">
+ <source>Name</source>
+ <target>名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6603000223840533819" datatype="html">
+ <source>Current</source>
+ <target>目前</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5607669932062416162" datatype="html">
+ <source>Default</source>
+ <target>預設值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6803e31b7395d94934e091a49a9524026b59b018" datatype="html">
+ <source>Discovery Authentication</source>
+ <target>探查驗證</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e08a77594f3d89311cdf6da5090044270909c194" datatype="html">
+ <source>User</source>
+ <target>使用者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">381</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7cbdabcece469fab89cfa687ab152bca18b97498" datatype="html">
+ <source>This field is required.</source>
+ <target>此欄位為必填欄位。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">368</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">423</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">481</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">291</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">343</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">407</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">490</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">516</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">556</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">573</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">590</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">647</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">672</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">299</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">195</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">520</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">614</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">651</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f717bad2da5944a2567a52f971ccc6806db85805" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>使用者名稱長度必須為 8 至 64 個字元,可以包含英數字元、&quot;.&quot;、&quot;@&quot;、&quot;-&quot;、&quot;_&quot; 或 &quot;:&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">28,29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">85,86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c32ef07f8803a223a83ed17024b38e8d82292407" datatype="html">
+ <source>Password</source>
+ <target>密碼</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">403</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">581</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="001e1836299d8d3b84eaebe2fa051325beab3f00" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>密碼長度必須為 12 至 16 個字元,可以包含英數字元、&quot;@&quot;、&quot;-&quot;、&quot;_&quot; 或 &quot;/&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">61,62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">118,119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff40391de7a1944ea95091e4045cc34c4979b736" datatype="html">
+ <source>Mutual User</source>
+ <target>雙向驗證使用者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cf73dbebe99b737c4d288788182fc356e3c93d3" datatype="html">
+ <source>Mutual Password</source>
+ <target>雙向驗證密碼</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594987303599690088" datatype="html">
+ <source>Updated discovery authentication</source>
+ <target>已更新探查驗證</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb127ea03835b3230f0ed981c7080e2ccb879621" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <note priority="1" from="description">form title</note>
+ </trans-unit>
+ <trans-unit id="1406c2fb12a20c1528b19bcc5e24a6a2386167f3" datatype="html">
+ <source>Target IQN</source>
+ <target>目標 IQN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5fe42339be910372fa689f559155631862d218e8" datatype="html">
+ <source>IQN has wrong pattern.</source>
+ <target>IQN 模式錯誤。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="050a7ff057d1e895357540406b6be5652b4d1c71" datatype="html">
+ <source>An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'</source>
+ <target>IQN 的表示法如下:iqn.$year-$month.$reversedAddress:$definedName</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">46,47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8ada4b53396d8366db00a435acc61d53d857047" datatype="html">
+ <source>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</source>
+ <target>例如:iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e" datatype="html">
+ <source>More information</source>
+ <target>更多資訊</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9b1aa85dfc6849196e64060db02c5410de69b7a1" datatype="html">
+ <source>This target has modified advanced settings.</source>
+ <target>此目標的進階設定已修改。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6990ad8d6182662e864495ac31c3758cda1c7a28" datatype="html">
+ <source>Portals</source>
+ <target>入口網站</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a3ac2b4137d723fd9878cd357c2012ff6c07973" datatype="html">
+ <source>Add portal</source>
+ <target>新增入口網站</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3638c01b6c34066438909713ec96087c813fc7e" datatype="html">
+ <source>At least <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> gateways are required.</source>
+ <target>至少需指定 <x id="INTERPOLATION" equiv-text="{{ minimum_gateways }}"/> 個閘道。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b73f7f5060fb22a1e9ec462b1bb02493fa3ab866" datatype="html">
+ <source>Images</source>
+ <target>影像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">495</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">629</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9aff25be088f0efe3eaaf62edf2bff41cc41a617" datatype="html">
+ <source>Backstore: <x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>. </source>
+ <target>後備儲存:<x id="INTERPOLATION" equiv-text="{{ imagesSettings[image].backstore | iscsiBackstore }}"/>。 </target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e3484cae8b118c576ca2815bf9c9406c2eb2cae3" datatype="html">
+ <source>This image has modified settings.</source>
+ <target>此影像的設定已修改。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1dff11e0820b6722ab240169f1232d70a54beaaa" datatype="html">
+ <source>Duplicated LUN numbers.</source>
+ <target>重複的 LUN 編號。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bf2dccf92ccff6e3b091792bf4205595406e1bfb" datatype="html">
+ <source>Duplicated WWN.</source>
+ <target>重複的 WWN。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="808038f912fdc7f0e03f82d4afd3bf9178527fc8" datatype="html">
+ <source>Add image</source>
+ <target>新增影像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">656</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66c5fb27f52e75b70ca4b670b9b15a2a51cf9543" datatype="html">
+ <source>ACL authentication</source>
+ <target>ACL 驗證</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="137fbf154ecad4d580354db0858b76faea7e4686" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>使用者名稱長度必須為 8 至 64 個字元,可以包含英數字元、&quot;.&quot;、&quot;@&quot;、&quot;-&quot;、&quot;_&quot; 或 &quot;:&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">227,228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">287,288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="361771c32dd2254d77fd3fbf006b008983fe5907" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>密碼長度必須為 12 至 16 個字元,可以包含英數字元、&quot;@&quot;、&quot;-&quot;、&quot;_&quot; 或 &quot;/&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">262,263</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">323,324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f494bd31f095f6dcc656ce87ec2dcf07a2e9b30c" datatype="html">
+ <source>Initiators</source>
+ <target>啟動器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">335</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">588</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e98239d8a6be1100119ff4b5630c822b82786740" datatype="html">
+ <source>Initiator</source>
+ <target>啟動器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2c5059d8cda15d8d03e2cce30f2d139623d9a91" datatype="html">
+ <source>Client IQN</source>
+ <target>用戶端 IQN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="107d5aabce23d900f0a80e6ddc1c10e29aa0bed8" datatype="html">
+ <source>Initiator IQN needs to be unique.</source>
+ <target>啟動器 IQN 必須是唯一的。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e7cad911fa524e512d9744b16358b7ee6791385" datatype="html">
+ <source>User names must have a length of 8 to 64 characters and can contain alphanumeric characters, '.', '@', '-', '_' or ':'.</source>
+ <target>使用者名稱長度必須為 8 至 64 個字元,可以包含英數字元、&quot;.&quot;、&quot;@&quot;、&quot;-&quot;、&quot;_&quot; 或 &quot;:&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">394,395</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">452,453</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7f2c186d181206d0d2b1ff74819081a010f10bf" datatype="html">
+ <source>Passwords must have a length of 12 to 16 characters and can contain alphanumeric characters, '@', '-', '_' or '/'.</source>
+ <target>密碼長度必須為 12 至 16 個字元,可以包含英數字元、&quot;@&quot;、&quot;-&quot;、&quot;_&quot; 或 &quot;/&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">427,428</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">485,486</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d1878d5fc761cbe9614bfd87047a740c82a6951" datatype="html">
+ <source>Initiator belongs to a group. Images will be configure in the group.</source>
+ <target>啟動器屬於群組。影像須在群組中進行設定。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">515</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0de67b9d97fafbf200f9451e8388ee8128a56ac" datatype="html">
+ <source>No items added.</source>
+ <target>未新增項目。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">671</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d565e47726158e428ecdc952fc9233b9b7d7f049" datatype="html">
+ <source>Add initiator</source>
+ <target>新增啟動器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">616</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c22ba03540aa3217da059f45e7eab138b51a96e2" datatype="html">
+ <source>Groups</source>
+ <target>群組</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c90059afafb7e160384d9f512797c95bb95c6dc" datatype="html">
+ <source>Group</source>
+ <target>群組</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cff1428d10d59d14e45edec3c735a27b5482db59" datatype="html">
+ <source>Name</source>
+ <target>名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">576</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3084948274cff4f56d0f431af47240e9cf02fcc7" datatype="html">
+ <source>Add group</source>
+ <target>新增群組</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html</context>
+ <context context-type="linenumber">676</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6634268061646442252" datatype="html">
+ <source>There are no portals available.</source>
+ <target>沒有可用的入口網站。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4587015892789840153" datatype="html">
+ <source>There are no images available.</source>
+ <target>沒有可用的影像。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7896905042057267575" datatype="html">
+ <source>There are no images available. Please make sure you add an image to the target.</source>
+ <target>沒有可用的影像。請確定為目標新增一個影像。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6765423558085969805" datatype="html">
+ <source>There are no initiators available. Please make sure you add an initiator to the target.</source>
+ <target>沒有可用的啟動器。請確定為目標新增一個啟動器。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2539932200265667453" datatype="html">
+ <source>target</source>
+ <target>目標</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="051dcc342cfa5c1eaf187a2001aaa162379a160c" datatype="html">
+ <source>Configure</source>
+ <target>設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e515f954730279c31d5301f02479666d6264e8b" datatype="html">
+ <source>Changing these parameters from their default values is usually not necessary.</source>
+ <target>通常不需要變更這些參數的預設值。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e2591df099ddac796cda401c5f282da779d45f2" datatype="html">
+ <source>Identifier</source>
+ <target>識別碼</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62480a4859976427cf18fc8ef41d3a438eda0412" datatype="html">
+ <source>lun</source>
+ <target>lun</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8afc9eb4405e0aa554b2ba14140ef790cdecc040" datatype="html">
+ <source>wwn</source>
+ <target>wwn</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
+ <source>Settings</source>
+ <target>設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69a47cbabcc51ca942606e1d8da0ec11f98a2690" datatype="html">
+ <source>Backstore</source>
+ <target>後備儲存</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="339878da255ab55447c43afef8d9b2f9753bf5f6" datatype="html">
+ <source>Advanced Settings</source>
+ <target>進階設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="332227f088a4877b3c11f5fb3ae8bc812c470fae" datatype="html">
+ <source>iSCSI Targets not available</source>
+ <target>無法使用 iSCSI 目標</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7fba666f1fff0182e570f12133fb3d622d9ea6" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the iSCSI Targets management functionality.</source>
+ <target>請參閱 <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;iscsi&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> 以瞭解如何設定和啟用 iSCSI 目標管理功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3b301d0044f62c92af0da53d7aaca52a436a547d" datatype="html">
+ <source>Available information:</source>
+ <target>可用資訊︰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8414a5cb9d71cc1b21b10e4a9d1f2dad558f3361" datatype="html">
+ <source>Discovery authentication</source>
+ <target>探查驗證</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4854396465510517671" datatype="html">
+ <source>Target</source>
+ <target>目標</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4093869278527257288" datatype="html">
+ <source>Portals</source>
+ <target>入口網站</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="414887388288176527" datatype="html">
+ <source>Images</source>
+ <target>影像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="798573158169239055" datatype="html">
+ <source># Sessions</source>
+ <target>工作階段數量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="646929398175374220" datatype="html">
+ <source>Unavailable gateway(s)</source>
+ <target>無法使用的閘道</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2350612272163013640" datatype="html">
+ <source>Target has active sessions</source>
+ <target>目標具有使用中工作階段</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4782410538666829801" datatype="html">
+ <source>iSCSI target</source>
+ <target>iSCSI 目標</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts</context>
+ <context context-type="linenumber">227</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8a9910cd114c1deb9af74f6f99b4173403965bf2" datatype="html">
+ <source>Gateways</source>
+ <target>閘道</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911214550882917183" datatype="html">
+ <source>State</source>
+ <target>狀態</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4121862424558610140" datatype="html">
+ <source># Targets</source>
+ <target>目標數量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101197021456818771" datatype="html">
+ <source>Pool</source>
+ <target>池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3012906865384504293" datatype="html">
+ <source>Image</source>
+ <target>影像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2699995524827665158" datatype="html">
+ <source>Backstore</source>
+ <target>後備儲存</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3559214740809905405" datatype="html">
+ <source>Read Bytes</source>
+ <target>讀取位元組數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1580583760095064067" datatype="html">
+ <source>Write Bytes</source>
+ <target>寫入位元組數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7225917547116479918" datatype="html">
+ <source>Read Ops</source>
+ <target>讀取操作數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6417507714454914481" datatype="html">
+ <source>Write Ops</source>
+ <target>寫入操作數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="257147267065394003" datatype="html">
+ <source>A/O Since</source>
+ <target>使用中/最佳化開始時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/iscsi/iscsi.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ecbc084370a732fc3cde1966a60af78d71424ab4" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>建立開機記號</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603e9cc3ef2aab57f2b0a00e465b23b9cabefd9c" datatype="html">
+ <source>To create a bootstrap token which can be imported by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Generate<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>若要建立可由對等站台叢集輸入的開機記號,請提供本地站台的名稱,選取將啟用鏡像的池,然後按一下<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>產生<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="660f97cd3188f8a04bd03b79e703fec72c6df04c" datatype="html">
+ <source>Site Name</source>
+ <target>站台名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2fecea01ce1d44114ee45144eff6d47a5016a74f" datatype="html">
+ <source>Name...</source>
+ <target>名稱...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92899fa68e8ca108912163ff58edc8540e453787" datatype="html">
+ <source>Pools</source>
+ <target>池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c2a1dc72cffaf7ab3dc5599bf77b0a7fcad2b20" datatype="html">
+ <source>At least one pool is required.</source>
+ <target>至少需指定一個池。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b258b258b4cc475ceb2871305b61756b0134f4a" datatype="html">
+ <source>Generate</source>
+ <target>產生</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1edc1fc6cfbbb22353050ad6788508b3ed584f53" datatype="html">
+ <source>Token</source>
+ <target>記號</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff785f5596aef34a93b9b4d1023e95c62eef5740" datatype="html">
+ <source>Generated token...</source>
+ <target>產生的記號 ...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8" datatype="html">
+ <source>Close</source>
+ <target>關閉</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5467a6bb0e7fade6def7499400d5e2a7d8d3da20" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>輸入開機記號</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bb7aee0dec5164f45c0aa2f35f2fb2149d2c1d2" datatype="html">
+ <source>To import a bootstrap token which was created by a peer site cluster, provide the local site's name, select which pools will have mirroring enabled, provide the generated token, and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Import<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>若要輸入由對等站台叢集建立的開機記號,請提供本地站台的名稱,選取將啟用鏡像的池,提供產生的記號,然後按一下<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>輸入<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">13,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9200e09686136a1d42adfb89c12fbfef2deea125" datatype="html">
+ <source>Direction</source>
+ <target>方向</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9761484679958da8d12841a4efa5964d33fae575" datatype="html">
+ <source>The token is invalid.</source>
+ <target>該記號無效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2381859602529023966" datatype="html">
+ <source>Instance</source>
+ <target>例項</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8040881171107393560" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1605455101862010019" datatype="html">
+ <source>Hostname</source>
+ <target>主機名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2724055831234181057" datatype="html">
+ <source>Version</source>
+ <target>版本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2041675390931385838" datatype="html">
+ <source>Health</source>
+ <target>狀況</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87bd96249f8afc23f5301cddb57b1464a98e71a" datatype="html">
+ <source>Edit site name</source>
+ <target>編輯站台名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cfff72c667274c12eb1ff71eadc25871c10c42dc" datatype="html">
+ <source>Edit the site name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>編輯站台名稱並按一下<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>更新<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html</context>
+ <context context-type="linenumber">13,14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66db799d67958d4b0765181d072df62e2d1c16f5" datatype="html">
+ <source>Issues</source>
+ <target>問題</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef06d69259e587e28d52372455f44c7153cda7e7" datatype="html">
+ <source>Syncing</source>
+ <target>正在同步</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0b0901877d837d3fda16ba161eb74368d1c75b7a" datatype="html">
+ <source>Ready</source>
+ <target>準備就緒</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5833626790712999947" datatype="html">
+ <source>Issue</source>
+ <target>問題</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3419681791450150574" datatype="html">
+ <source>Progress</source>
+ <target>進度</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4902817035128594900" datatype="html">
+ <source>Description</source>
+ <target>描述</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/image-list/image-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40b7acea5b43f45e0bbd1efeba5200af4687981d" datatype="html">
+ <source>Site Name:</source>
+ <target>站台名稱:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e24f9e2d42104ffc01599db4d566d1cc518f9e6" datatype="html">
+ <source>Daemons</source>
+ <target>精靈</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6450386891540681425" datatype="html">
+ <source>Edit Site Name</source>
+ <target>編輯站台名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4645993115976933405" datatype="html">
+ <source>Create Bootstrap Token</source>
+ <target>建立開機記號</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4130053543590533787" datatype="html">
+ <source>Import Bootstrap Token</source>
+ <target>輸入開機記號</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/overview/overview.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4057c56d63a7e9b140b1d01871a9229a5f30eb27" datatype="html">
+ <source>Edit pool mirror mode</source>
+ <target>編輯池鏡像模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e1f367f5feaab38f6637dd1f967c848b447dea2d" datatype="html">
+ <source>To edit the mirror mode for pool  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>, select a new mode from the list and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Update<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>若要編輯池 <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> 的鏡像模式,請從清單中選取新模式,然後按一下<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>更新<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37e10df2d9c0c25ef04ac112c9c9a7723e8efae0" datatype="html">
+ <source>Mode</source>
+ <target>模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">426</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32ca348ef926b0a6a7a780b8b64c3a8239895cec" datatype="html">
+ <source>Peer clusters must be removed prior to disabling mirror.</source>
+ <target>在停用鏡像之前,必須先移除對等叢集。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5769292297914455214" datatype="html">
+ <source>Disabled</source>
+ <target>已停用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ddcb416c1c0aa1f54acf5beef1de81813e76fa6" datatype="html">
+ <source>{VAR_SELECT, select, edit {Edit} other {Add}}</source>
+ <target>{VAR_SELECT, select, edit {編輯} other {新增}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3aa7c3a4f7b0cf7c2e60fc71ea1e3b4c3efa3558" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> pool mirror peer</source>
+ <target><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> 池鏡像對等</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="59ca65ece457429d90104ede4674965f62edbabe" datatype="html">
+ <source><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/> the pool mirror peer attributes for pool <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> and click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Submit<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target><x id="ICU" equiv-text="{mode, select, edit {Edit} other {Add}}"/>池 <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ poolName }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> 的池鏡像對等屬性,然後按一下<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>提交<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d3cc964811f852a168f4a2d5daa59068abc5cf53" datatype="html">
+ <source>Cluster Name</source>
+ <target>叢集名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b631721fc56cb7fb1cbd07b802a487c5753f6a2d" datatype="html">
+ <source>The cluster name is not valid.</source>
+ <target>叢集名稱無效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca6deafa31bf421f85094807982aee4bcb20a3ae" datatype="html">
+ <source>CephX ID</source>
+ <target>CephX ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7539188a568c3d553cbde1bacaf32310c4264e24" datatype="html">
+ <source>CephX ID...</source>
+ <target>CephX ID...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1c45b594b0fba22fc64e80c793a7ffe005fdb0e" datatype="html">
+ <source>The CephX ID is not valid.</source>
+ <target>CephX ID 無效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20861576fcfce773c918c782cd4f5adf32382921" datatype="html">
+ <source>Monitor Addresses</source>
+ <target>監控程式位址</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fa28eeed2b4bd4ccbe6e9349a1c2b3cb1c5de70a" datatype="html">
+ <source>Comma-delimited addresses...</source>
+ <target>逗號分隔的位址...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dc016c82fd85848d5c1b2fd0e8469ee2027d9c16" datatype="html">
+ <source>The monitory address is not valid.</source>
+ <target>監控程式位址無效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0ac55b83dc6739e62bc655cfe375b67c93e7f4a" datatype="html">
+ <source>CephX Key</source>
+ <target>CephX 金鑰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f53434bcb95bd86f1df9c8e22966f757614fc4ad" datatype="html">
+ <source>Base64-encoded key...</source>
+ <target>Base64 編碼的金鑰...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4cd83164cd4f66b4abc2863f9ce6f599d789e4ca" datatype="html">
+ <source>CephX key must be base64 encoded.</source>
+ <target>CephX 金鑰必須為 Base64 編碼的金鑰。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6407712033679505505" datatype="html">
+ <source>Edit Mode</source>
+ <target>編輯模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054237897979907103" datatype="html">
+ <source>Add Peer</source>
+ <target>新增對等</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="899134641637789371" datatype="html">
+ <source>Edit Peer</source>
+ <target>編輯對等</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7393680121674824053" datatype="html">
+ <source>Delete Peer</source>
+ <target>刪除對等</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1713271461473302108" datatype="html">
+ <source>Mode</source>
+ <target>模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1061297288634362831" datatype="html">
+ <source>Leader</source>
+ <target>主管</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8517494870558773093" datatype="html">
+ <source># Local</source>
+ <target>本地數量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4953753699491987394" datatype="html">
+ <source># Remote</source>
+ <target>遠端數量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1715982232168082172" datatype="html">
+ <source>mirror peer</source>
+ <target>鏡像對等</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/mirroring/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff92fbdec9fdd5054493eeda0d7ee8b450f83e72" datatype="html">
+ <source>RBD Configuration</source>
+ <target>RBD 組態</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b62d9efc8eb3b589904f6cb96a0406bbda55673a" datatype="html">
+ <source>Remove the local configuration value. The parent configuration value will be inherited and used instead.</source>
+ <target>移除本地組態值。將繼承並使用父組態值。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80d769fd863fe44fab689636a078466bfdbd1f20" datatype="html">
+ <source>The minimum value is 0</source>
+ <target>最小值為 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5decb3917d46a9ac6e5813699801becb7c3c1455" datatype="html">
+ <source>Global</source>
+ <target>全域</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f9ba9bb9faa8284bcadb1cdbc6aaf969e9c4bb" datatype="html">
+ <source>Image</source>
+ <target>影像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70fcca5a99575cffef3ff8cbd5e69f06ffd0f1c" datatype="html">
+ <source>Pool</source>
+ <target>池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">211</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176659033176029418" datatype="html">
+ <source>Key</source>
+ <target>金鑰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9155608366859514313" datatype="html">
+ <source>Source</source>
+ <target>來源</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6555318547274416232" datatype="html">
+ <source>Value</source>
+ <target>值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f6e8f6094b180eaf1f11bc0ffe383f1cdcd059e" datatype="html">
+ <source>Only available for RBD images with <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> enabled</source>
+ <target>僅可用於啟用了 <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>fast-diff<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> 的 RBD 影像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f8b2bb476981727ab34ed40fde1218361f92c45" datatype="html">
+ <source>Details</source>
+ <target>詳細資料</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03cc5b14b0a20d075e9009ff021f4f1660ba348a" datatype="html">
+ <source>Data Pool</source>
+ <target>資料池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b051734b0ee9021991c91b3ed4e81c244322462" datatype="html">
+ <source>Created</source>
+ <target>已建立</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7faaaa08f56427999f3be41df1093ce4089bbd75" datatype="html">
+ <source>Size</source>
+ <target>大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="afdb601c16162f2c798b16a2920955f1cc6a20aa" datatype="html">
+ <source>Objects</source>
+ <target>物件</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ceac8e132384322ec778ba760875a6c6897d3e42" datatype="html">
+ <source>Object size</source>
+ <target>物件大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cdb1fea93d77c07950c0c76c6e0ad79ebbef084" datatype="html">
+ <source>Features</source>
+ <target>功能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65771c9a73b9aa609d592fc96a64801a8f40bd" datatype="html">
+ <source>Provisioned</source>
+ <target>已佈建</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84a36cb75660b736773fe36ffa3d54f0f0fe363e" datatype="html">
+ <source>N/A</source>
+ <target>無</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c009342a4e8381f64341d0bb61c2e4685f5a4b" datatype="html">
+ <source>Total provisioned</source>
+ <target>總佈建數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f6bf8a43ae415f527ac961ea62471b983aaa97b" datatype="html">
+ <source>Striping unit</source>
+ <target>分割單位</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db710e8a8f011923f2d15d713fbae49c38b02b26" datatype="html">
+ <source>Striping count</source>
+ <target>分割計數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a4c2a9e76634ff14a60d52a718296f722d47c67" datatype="html">
+ <source>Parent</source>
+ <target>父項</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a209e68d78ffc2cc9c53d2e76158624efab71ad" datatype="html">
+ <source>Block name prefix</source>
+ <target>區塊名稱字首</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5704ec2049d007c5f5fb495a5d8b607e68d58081" datatype="html">
+ <source>Order</source>
+ <target>順序</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="984cb6ad70f150a401b4daf841bd3cd957412699" datatype="html">
+ <source>Format Version</source>
+ <target>格式版本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f21b1d17b6c5042bb5805516eee37fde33739dd8" datatype="html">
+ <source>Snapshots</source>
+ <target>快照</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4a41f824a35ba01d5bd7be61aa06b3e8145209d0" datatype="html">
+ <source>Configuration</source>
+ <target>組態</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3cc9c2ae277393b3946b38c088dabff671b1ee1b" datatype="html">
+ <source>Performance</source>
+ <target>效能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935bb9cb0e4340fc74d33caa3b70d9d143fcad87" datatype="html">
+ <source>Information can not be displayed for RBD in status 'Removing'.</source>
+ <target>無法顯示處於 &quot;正在移除&quot; 狀態的 RBD 的資訊。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58e58f1a8786da9031a05e6770c5dafce82badf5" datatype="html">
+ <source>This setting overrides the global value</source>
+ <target>此設定會覆寫全域值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36b46714164964c6258b08ed0a25f57d8a950f92" datatype="html">
+ <source>This is the global value. No value for this option has been set for this image.</source>
+ <target>此值為全域值。未為此影像設定此選項的值。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-details/rbd-details.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6547c9c4d5f62942ac4b1fe459cf9a03d4dbf5a0" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> from</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> 從</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0e9ecf29a4fa5b057bd8052e0d801b3fde6a30bf" datatype="html">
+ <source>'/' and '@' are not allowed.</source>
+ <target>不允許使用 &quot;/&quot; 和 &quot;@&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="94516fa213706c67ce5a5b5765681d7fb032033a" datatype="html">
+ <source>Loading...</source>
+ <target>正在載入...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">209</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">452</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b99417c4dd46286ffd37c8d2e987c8b512ec7052" datatype="html">
+ <source>-- No rbd pools available --</source>
+ <target>-- 沒有可用的 RBD 池 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef83ec9c304a89d45650e580dcdc2978c37b3a83" datatype="html">
+ <source>-- Select a pool --</source>
+ <target>-- 選取池 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d649904466254d13df1fbf2d255f0bbc6553d213" datatype="html">
+ <source>-- No namespaces available --</source>
+ <target>-- 沒有可用的名稱空間 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e22d7bb4d2d561e0832ee0b9a3da2468a080c4f0" datatype="html">
+ <source>-- Select a namespace --</source>
+ <target>-- 選取名稱空間 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49449943d8cbf59d8c401c8bd2e76f92e207cc5f" datatype="html">
+ <source>Use a dedicated data pool</source>
+ <target>使用專屬的資料池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa5b3c5ea5af14d09b2eb098039af9f1f77be010" datatype="html">
+ <source>You need more than one pool with the rbd application label use to use a dedicated data pool.</source>
+ <target>若要使用專屬的資料池,您需要多個使用了 RBD 應用程式標籤的池。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="870aee0dd31a9643bf62007beb8f1ae1deb34d42" datatype="html">
+ <source>Data pool</source>
+ <target>資料池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3792ca829d9b9f687e1f5d7733d30e9bb0bfec47" datatype="html">
+ <source>Dedicated pool that stores the object-data of the RBD.</source>
+ <target>專用於儲存 RBD 物件資料的池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151c80ea931037cd92e854442927f8a0f6ae7795" datatype="html">
+ <source>-- No data pools available --</source>
+ <target>-- 沒有可用的資料池 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0016bd458baa88284a658ce9eeda42d8ad88d2c" datatype="html">
+ <source>e.g., 10GiB</source>
+ <target>例如 10 GiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">206</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a88bbee20570aaf9615332fb27020627044874d" datatype="html">
+ <source>You have to increase the size.</source>
+ <target>您必須增加大小。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cfe07dac5b4ee1c464eb24225ddeb4f1d24076a" datatype="html">
+ <source>Advanced...</source>
+ <target>進階...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bc2e854e111ecf2bd7db170da5e3c2ed08181d88" datatype="html">
+ <source>Advanced</source>
+ <target>進階</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3562a3778695a5f9c0445660e35301f0a39aaf73" datatype="html">
+ <source>Striping</source>
+ <target>分割</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef3c3f3b5f562a5cdbe0ee2874287db1534b5958" datatype="html">
+ <source>Stripe unit</source>
+ <target>分割單位</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84471be1049006edecbcaef1a32ae0893c229c50" datatype="html">
+ <source>-- Select stripe unit --</source>
+ <target>-- 選取分割單位 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">289</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d32c5c54c8581c774a7f467fbd4e329b15a74fa" datatype="html">
+ <source>This field is required because stripe count is defined!</source>
+ <target>由於已定義分割計數,因此必須填寫此欄位!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bbf9040be7c5491d4a03f2185708f43a6582a3b" datatype="html">
+ <source>Stripe unit is greater than object size.</source>
+ <target>分割單位大於物件大小。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a682f49f9b761591661276d7c6f550e641a130a4" datatype="html">
+ <source>Stripe count</source>
+ <target>分割計數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="baa74031990c5370008ba622d0a250f0929097f4" datatype="html">
+ <source>This field is required because stripe unit is defined!</source>
+ <target>由於已定義分割單位,因此必須填寫此欄位!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cd2ada6d5ecbd5cbf89eae0a1f5326efedac0dbc" datatype="html">
+ <source>Stripe count must be greater than 0.</source>
+ <target>分割計數必須大於 0。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.html</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4341718109173132593" datatype="html">
+ <source>RBD</source>
+ <target>RBD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1359455778569887786" datatype="html">
+ <source>Deep flatten</source>
+ <target>深層壓平</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58519213655664125" datatype="html">
+ <source>Layering</source>
+ <target>分層</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844531889615887801" datatype="html">
+ <source>Exclusive lock</source>
+ <target>獨佔鎖定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4585281635594103106" datatype="html">
+ <source>Object map (requires exclusive-lock)</source>
+ <target>物件對應 (需要獨佔鎖定)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240933649452133654" datatype="html">
+ <source>Journaling (requires exclusive-lock)</source>
+ <target>記錄 (需要獨佔鎖定)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3713046526850391848" datatype="html">
+ <source>Fast diff (interlocked with object-map)</source>
+ <target>Fast diff (與 object-map 連鎖)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-form/rbd-form.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19f1e825536efbf7492723a7c2d01ad23a4e994b" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{row.disk_usage | dimlessBinary}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1774b9915b0e302d02cad0b9321ad5f1a83247a8" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{row.total_disk_usage | dimlessBinary}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c9f1026c1235f4d76ace47449e806efd181ab332" datatype="html">
+ <source>Deleting this image will also delete all its snapshots.</source>
+ <target>刪除此影像時也會刪除它的所有快照。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55f864597e84d9bf88769e1fbfda1d64452430c9" datatype="html">
+ <source>The following snapshots are currently protected and will be removed:</source>
+ <target>以下快照目前受到保護,將會被移除:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2e362ec498c4c9112dc47a3cb7d7250ca8e71790" datatype="html">
+ <source>RBD in status 'Removing'</source>
+ <target>RBD 處於 &quot;正在移除&quot; 狀態</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3294686077659093992" datatype="html">
+ <source>Namespace</source>
+ <target>名稱空間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45739481977493163" datatype="html">
+ <source>Size</source>
+ <target>大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7531602241051125940" datatype="html">
+ <source>Objects</source>
+ <target>物件</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1194977199378511591" datatype="html">
+ <source>Object size</source>
+ <target>物件大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">226</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="178418048502923560" datatype="html">
+ <source>Provisioned</source>
+ <target>已佈建</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7638291694671392137" datatype="html">
+ <source>Total provisioned</source>
+ <target>總佈建數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8621797738551294959" datatype="html">
+ <source>Parent</source>
+ <target>父項</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616639680594151867" datatype="html">
+ <source>This RBD has cloned snapshots. Please delete related RBDs before deleting this RBD.</source>
+ <target>此 RBD 具有克隆的快照。請先刪除相關 RBD,再刪除此 RBD。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2900827028308925059" datatype="html">
+ <source>This RBD image has an invalid name and can't be managed by ceph.</source>
+ <target>此 RBD 影像的名稱無效,無法由 ceph 管理。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">467</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1796389652493657142" datatype="html">
+ <source>Action not possible for an RBD in status 'Removing'</source>
+ <target>無法對處於 &quot;正在移除&quot; 狀態的 RBD 執行動作</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-list/rbd-list.component.ts</context>
+ <context context-type="linenumber">476</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c07d24bb422aa8e5e568df1c5709083f0a9c8f1" datatype="html">
+ <source>Create Namespace</source>
+ <target>建立名稱空間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cca6c0485f96d3a9610d0339cb1275a5f2c3f46" datatype="html">
+ <source>Namespace already exists.</source>
+ <target>名稱空間已存在。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4641528557519966449" datatype="html">
+ <source>Created namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <target>已建立名稱空間 &quot;<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6809428596104996786" datatype="html">
+ <source>Total images</source>
+ <target>影像總計</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1346311774128536550" datatype="html">
+ <source>Deleted namespace '<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>'</source>
+ <target>已刪除名稱空間 &quot;<x id="PH" equiv-text="pool"/>/<x id="PH_1" equiv-text="namespace"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7605466414392298530" datatype="html">
+ <source>Namespace contains images</source>
+ <target>名稱空間包含影像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576483965711201552" datatype="html">
+ <source>RBD Snapshot</source>
+ <target>RBD 快照</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3473055924346204357" datatype="html">
+ <source>Parent image must support Layering</source>
+ <target>父影像必須支援分層</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1152535233999495900" datatype="html">
+ <source>Snapshot must be protected in order to clone.</source>
+ <target>快照必須處於受保護狀態才能複製。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c5331983af566d4ac6a1024d15a3511786a4aa6" datatype="html">
+ <source>You are about to rollback</source>
+ <target>您即將復原</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6240400332778072187" datatype="html">
+ <source>PROTECTED</source>
+ <target>受保護</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9101667614062185213" datatype="html">
+ <source>UNPROTECTED</source>
+ <target>未受保護</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">131</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4207916966377787111" datatype="html">
+ <source>Created</source>
+ <target>已建立</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587768621777516124" datatype="html">
+ <source>RBD snapshot rollback</source>
+ <target>RBD 快照復原</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">305</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2711198699676132148" datatype="html">
+ <source>Rollback</source>
+ <target>復原</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3330476395115957823" datatype="html">
+ <source>RBD snapshot</source>
+ <target>RBD 快照</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts</context>
+ <context context-type="linenumber">322</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3a7e364a88ea4673199dfa98bc73e6dbe09dfac" datatype="html">
+ <source>Namespaces</source>
+ <target>名稱空間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aba82bfd8e177d35b76cad7cd43941f8e5e5acac" datatype="html">
+ <source>Trash</source>
+ <target>垃圾桶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5e7f4b1ca49e8d217bd0e12c6f7d6b6a2ade2c18" datatype="html">
+ <source>Overall Performance</source>
+ <target>整體效能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-tabs/rbd-tabs.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c0408946a6d67185947f455f15cc201d0d78e6" datatype="html">
+ <source>Purge Trash</source>
+ <target>清除垃圾桶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5c96a761dc55a21882c132c929583a424c9b8cf4" datatype="html">
+ <source>Expired at</source>
+ <target>過期日為</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="661041e3fcff4d3e75c561e038ca2504cf2cc643" datatype="html">
+ <source>Protected until</source>
+ <target>保護過期日為</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee3b2322a1d3277f7e3fdb8a5141ac42bcf350b" datatype="html">
+ <source>This image is protected until <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/>.</source>
+ <target>此影像在 <x id="INTERPOLATION" equiv-text="{{ expiresAt | cdDate }}"/> 前一直受保護。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5611592591303869712" datatype="html">
+ <source>Status</source>
+ <target>狀態</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">213</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">285</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2155633476201267204" datatype="html">
+ <source>Deleted At</source>
+ <target>刪除位置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f0b5d789d42c0e69348e5fe0037fcbf5b5fbbdcc" datatype="html">
+ <source>Move an image to trash</source>
+ <target>將影像移至垃圾桶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ad22c1d4aab3b8946603cea62de266d5129ca10" datatype="html">
+ <source>This image contains snapshot(s), which will prevent it from being removed after moved to trash.</source>
+ <target>此影像包含快照,這將阻止影像移至垃圾桶後被移除。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">15,16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d4a5f5698bc8118b2e120b9bb72eff339094dd0" datatype="html">
+ <source>To move <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> to trash, click <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Move<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. Optionally, you can pick an expiration date.</source>
+ <target>若要將 <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpecStr }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/> 移至垃圾桶,請按一下<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>移動<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>。(選擇性) 您可以選取一個過期日期。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">19,20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f27d390844aad53b4240360e928156c5f0d326" datatype="html">
+ <source>Protection expires at</source>
+ <target>保護的過期日為</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da166e9a0d27322f6ba8916d71ecc0f9905bb4b1" datatype="html">
+ <source>NOT PROTECTED</source>
+ <target>無保護</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1506e5f2ca22cad14502ec7a20fb6113ace145d" datatype="html">
+ <source>Wrong date format. Please use &quot;YYYY-MM-DD HH:mm:ss&quot;.</source>
+ <target>日期格式錯誤。請使用 &quot;YYYY-MM-DD HH:mm:ss&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa7ea0bb7495281e0b3258467ac7d90a1e44a1a1" datatype="html">
+ <source>Protection has already expired. Please pick a future date or leave it empty.</source>
+ <target>保護已過期。請選取一個未來的日期或保留空白。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d8613436532acac2b97d17de28b50f93e6bd0222" datatype="html">
+ <source>To purge, select  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>All<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>  or one pool and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Purge<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>. </source>
+ <target>若要進行清除,請選取<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>所有<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>或一個池,然後按一下<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>清除<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55a4f598a4894b7fd5cb88f0ffd3c37ad009dd70" datatype="html">
+ <source>Pool:</source>
+ <target>池︰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d43dd2b9f7797e4cf3a604695bb33e4479108516" datatype="html">
+ <source>Pool name...</source>
+ <target>池名稱...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dfc3c34e182ea73c5d784ff7c8135f087992dac1" datatype="html">
+ <source>All</source>
+ <target>所有</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0e7c7ed1d51a0c205c815048bc9f79e24ee6db2" datatype="html">
+ <source>Restore Image</source>
+ <target>回存影像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3bc4aaf0dce75dc5e01ee5c825a652dc8aea8f0" datatype="html">
+ <source>To restore  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>,  type the image's new name and click  <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>Restore<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>.</source>
+ <target>若要回存 <x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/><x id="INTERPOLATION" equiv-text="{{ imageSpec }}"/>@<x id="INTERPOLATION_1" equiv-text="{{ imageId }}"/><x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>,請鍵入影像的新名稱并按一下<x id="START_TAG_KBD" ctype="x-kbd" equiv-text="&lt;kbd&gt;"/>回存<x id="CLOSE_TAG_KBD" ctype="x-kbd" equiv-text="&lt;/kbd&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">12,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41307dd56fea669eed72e12a6c23af275f6bfd82" datatype="html">
+ <source>New Name</source>
+ <target>新名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3625859417927520024" datatype="html">
+ <source>id</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6537904131139019667" datatype="html">
+ <source>type</source>
+ <target>類型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8901220148451863928" datatype="html">
+ <source>state</source>
+ <target>狀態</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7925190601961269841" datatype="html">
+ <source>version</source>
+ <target>版本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6641024648411549335" datatype="html">
+ <source>Host</source>
+ <target>主機</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773272191572353800" datatype="html">
+ <source>root</source>
+ <target>根</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6364513948635353490" datatype="html">
+ <source>Evicted client '<x id="PH" equiv-text="clientId"/>'</source>
+ <target>已逐出用戶端 &quot;<x id="PH" equiv-text="clientId"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c1e17956453ad772dbe82d6946f62748c692f3e" datatype="html">
+ <source>Ranks</source>
+ <target>階層</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b24e0b0b1629d2e8a51b9da7c75d6e6379f4bc4" datatype="html">
+ <source>Standbys</source>
+ <target>待命</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="50df62325726db950523a5be1c78b8905fcc25d4" datatype="html">
+ <source>MDS performance counters</source>
+ <target>MDS 效能計數器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4578796959376778578" datatype="html">
+ <source>Standby daemons</source>
+ <target>待命精靈</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="665219418211496660" datatype="html">
+ <source>Rank</source>
+ <target>階層</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5445409664838149993" datatype="html">
+ <source>Daemon</source>
+ <target>精靈</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5306473977542913614" datatype="html">
+ <source>Activity</source>
+ <target>活動</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3998441303515229547" datatype="html">
+ <source>Dentries</source>
+ <target>Dentry</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7877631502958415163" datatype="html">
+ <source>Inodes</source>
+ <target>Inode</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6129397096478256985" datatype="html">
+ <source>Dirs</source>
+ <target>目錄</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3011876564696453148" datatype="html">
+ <source>Caps</source>
+ <target>功能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8650499415827640724" datatype="html">
+ <source>Type</source>
+ <target>類型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="142654590491855672" datatype="html">
+ <source>Usage</source>
+ <target>使用率</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">326</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb8293aa8161433778762ae025ffd5e7c85795e" datatype="html">
+ <source>Quotas</source>
+ <target>定額</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">540</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="66785722678644243" datatype="html">
+ <source>Origin</source>
+ <target>來源</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8911059720204770105" datatype="html">
+ <source>Path</source>
+ <target>路徑</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6111756909052789805" datatype="html">
+ <source>Cannot create snapshots for files/folders in the subvolume <x id="PH" equiv-text="folders[2]"/></source>
+ <target>無法為子磁碟區 <x id="PH" equiv-text="folders[2]"/> 中的檔案/資料夾建立快照</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7503263437025060215" datatype="html">
+ <source>Max size</source>
+ <target>最大大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6763343019307619111" datatype="html">
+ <source>Max files</source>
+ <target>最大檔案數量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327403486214540377" datatype="html">
+ <source>The inherited <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> is the maximum value to be used.</source>
+ <target>繼承的 <x id="PH" equiv-text="this.getQuotaValueFromPathMsg( nextMax.value, nextMax.path )"/> 為將使用的最大值。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">434,437</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3768927257183755959" datatype="html">
+ <source>Save</source>
+ <target>儲存</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">440</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6328794256834621774" datatype="html">
+ <source><x id="PH" equiv-text="action"/> CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> quota for '<x id="PH_2" equiv-text="path"/>'</source>
+ <target><x id="PH" equiv-text="action"/> &quot;<x id="PH_2" equiv-text="path"/>&quot; 的 CephFS <x id="PH_1" equiv-text="this.getQuotaName()"/> 定額</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">446</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9130352375983418123" datatype="html">
+ <source>size</source>
+ <target>大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6889473896134264260" datatype="html">
+ <source>files</source>
+ <target>檔案數量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">450</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2244434638607433133" datatype="html">
+ <source><x id="PH" equiv-text="this.getQuotaName()"/> quota <x id="PH_1" equiv-text="value"/> from '<x id="PH_2" equiv-text="path"/>'</source>
+ <target>&quot;<x id="PH_2" equiv-text="path"/>&quot; 中的 <x id="PH" equiv-text="this.getQuotaName()"/> 定額 <x id="PH_1" equiv-text="value"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">460</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6960117167304061503" datatype="html">
+ <source>Value has to be at least 0 or more</source>
+ <target>值必須大於或等於 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">484</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6740501370117796629" datatype="html">
+ <source>Value has to be at most <x id="PH" equiv-text="maxValue"/> or less</source>
+ <target>值必須小於或等於 <x id="PH" equiv-text="maxValue"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7239750919884229270" datatype="html">
+ <source>Updated</source>
+ <target>已更新</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">499</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8885980874806414253" datatype="html">
+ <source>in order to inherit <x id="PH" equiv-text="quotaValue"/></source>
+ <target>以繼承 <x id="PH" equiv-text="quotaValue"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4182949309891923991" datatype="html">
+ <source>which isn't used because of the inheritance of <x id="PH" equiv-text="quotaValue"/></source>
+ <target>未使用,因為繼承了 <x id="PH" equiv-text="quotaValue"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7421970649864638435" datatype="html">
+ <source>in order to have no quota on the directory</source>
+ <target>為了不為目錄設定定額</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">525</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6730229976797004508" datatype="html">
+ <source><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>.</source>
+ <target><x id="PH" equiv-text="this.actionLabels.UNSET"/> <x id="PH_1" equiv-text="this.getQuotaValueFromPathMsg( dirValue, path )"/> <x id="PH_2" equiv-text="conclusion"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">530,533</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="827679535246546876" datatype="html">
+ <source>Create Snapshot</source>
+ <target>建立快照</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">542</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">552</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4747656362969857823" datatype="html">
+ <source>Please enter the name of the snapshot.</source>
+ <target>請輸入快照的名稱。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">543</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3667696812078358068" datatype="html">
+ <source>Created snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <target>已建立 &quot;<x id="PH_1" equiv-text="path"/>&quot; 的快照 &quot;<x id="PH" equiv-text="name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">557</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="753342836137587734" datatype="html">
+ <source>CephFs Snapshot</source>
+ <target>CephFs 快照</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">670</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2774104291801979963" datatype="html">
+ <source>Deleted snapshot '<x id="PH" equiv-text="name"/>' for '<x id="PH_1" equiv-text="path"/>'</source>
+ <target>已刪除 &quot;<x id="PH_1" equiv-text="path"/>&quot; 的快照 &quot;<x id="PH" equiv-text="name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts</context>
+ <context context-type="linenumber">683</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4816216590591222133" datatype="html">
+ <source>Enabled</source>
+ <target>已啟用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7ffe39df9d88c972792bd8688b215392deb8313d" datatype="html">
+ <source>Clients</source>
+ <target>用戶端</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e213942c6354b9cbe7a650f0f1499bfc1000fb6" datatype="html">
+ <source>Directories</source>
+ <target>目錄</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fbbaf5cb02ed419e79a27072478f716a4666a99d" datatype="html">
+ <source>Performance Details</source>
+ <target>效能詳細資料</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0" datatype="html">
+ <source>Description</source>
+ <target>描述</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ad112ce9bcd55dfd137792a86afe1b5a5b13cf8" datatype="html">
+ <source>Long description</source>
+ <target>詳細描述</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="26fb5f81b3581f06b9210defb0e71dc69a67e819" datatype="html">
+ <source>Current values</source>
+ <target>目前的值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7cee38a2259526c519f878e71b964f41db4348" datatype="html">
+ <source>Default</source>
+ <target>預設值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33e1c1d9fc05ca3f62fcc8a1170fc31ebae4229c" datatype="html">
+ <source>Daemon default</source>
+ <target>精靈預設值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f61c6867295f3b53d23557021f2f4e0aa1d0b8fc" datatype="html">
+ <source>Type</source>
+ <target>類型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9abcd7c82643d60c22733470463f74e4a54bc069" datatype="html">
+ <source>Min</source>
+ <target>最小值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c3ced4d162a0a55ee233a187ce7208ba5e922418" datatype="html">
+ <source>Max</source>
+ <target>最大值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="920617c6a1a4805e53bcb5af6a9c76f8387e89c6" datatype="html">
+ <source>Flags</source>
+ <target>旗標</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5" datatype="html">
+ <source>Services</source>
+ <target>服務</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6834fa6b43d1ecbdf147c48dd9c4d72f1484571d" datatype="html">
+ <source>Source</source>
+ <target>來源</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a446fb0eb11fbffcac805ece5a2d306d24e733d8" datatype="html">
+ <source>Level</source>
+ <target>層級</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39f2fb094e9b2eda13163fa3f3a31594cf9c1307" datatype="html">
+ <source>Can be updated at runtime (editable)</source>
+ <target>可在執行時期更新 (可編輯)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
+ <source>Tags</source>
+ <target>標記</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ab0089ef47af61ca1d137bc908b96c290dfd9287" datatype="html">
+ <source>Enum values</source>
+ <target>列舉值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="819476f1264f1659f38e86f6abb542141b184832" datatype="html">
+ <source>See also</source>
+ <target>另請參閱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="543199344025799954" datatype="html">
+ <source>The value can be updated at runtime.</source>
+ <target>該值可在執行時期更新。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1718354829128482129" datatype="html">
+ <source>Daemons/clients do not pull this value from the
+ monitor config database. We disallow setting this option via 'ceph config
+ set ...'. This option should be configured via ceph.conf or via the
+ command line.</source>
+ <target>精靈/用戶端不會從監控程式組態資料庫
+ 提取此值。我們不允許透過 &quot;ceph config set ...&quot;
+ 設定此選項。應透過 ceph.conf 或使用指令行
+ 進行設定。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">15,18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2345189734548717257" datatype="html">
+ <source>Option takes effect only during daemon startup.</source>
+ <target>該選項僅在精靈啟動期間生效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5523310713159993513" datatype="html">
+ <source>Option only affects cluster creation.</source>
+ <target>該選項僅影響叢集的建立。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1064479086902933123" datatype="html">
+ <source>Option only affects daemon creation.</source>
+ <target>該選項僅影響精靈的建立。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="809b0c848932a41318f77a2aace904ef429c13f4" datatype="html">
+ <source>Values</source>
+ <target>值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5894f7158499fdb89527af50c9f1cf7d4c95cad6" datatype="html">
+ <source>-- Default --</source>
+ <target>-- 預設值 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="514f6e12d035a6d9b00de6b3e55c18b73488da07" datatype="html">
+ <source>true</source>
+ <target>true</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="774f5e6a183dea08393789b6f72e86afad729419" datatype="html">
+ <source>false</source>
+ <target>false</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="82029b6db704c56a2aa3e82ac555b8655356b077" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>.</source>
+ <target>輸入的值過大!值不得大於 <x id="INTERPOLATION" equiv-text="{{ maxValue }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ed8b3967a7326b81b191c9f490006e6a6777a9a" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>.</source>
+ <target>輸入的值過小!值不得小於 <x id="INTERPOLATION" equiv-text="{{ minValue }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2337058106409853613" datatype="html">
+ <source>Updated config option <x id="PH" equiv-text="request.name"/></source>
+ <target>已更新組態選項 <x id="PH" equiv-text="request.name"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3733215288982610673" datatype="html">
+ <source>Level</source>
+ <target>層級</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2218082343053095278" datatype="html">
+ <source>Service</source>
+ <target>服務</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3553216189604488439" datatype="html">
+ <source>Modified</source>
+ <target>已修改</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1844248428439297756" datatype="html">
+ <source>Current value</source>
+ <target>目前的值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208877297843037352" datatype="html">
+ <source>Editable</source>
+ <target>可編輯</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/configuration/configuration.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b266042bac4c3a2eff4834e40fb9dc4767a709" datatype="html">
+ <source>Cluster Resources</source>
+ <target>叢集資源</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="099b441d49333b3c6d30b36dc0a4763e64c78920" datatype="html">
+ <source>Hosts</source>
+ <target>主機</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57e6e608ece53a26f6d509c90ed4f83e467741af" datatype="html">
+ <source>Storage Capacity</source>
+ <target>儲存容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19ece2cb2b9097c0f75af8e62b4b3b25d399a006" datatype="html">
+ <source>Number of devices</source>
+ <target>裝置數量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b161e3d25fd1b42a781f4e923a58a94925988ddf" datatype="html">
+ <source>Raw capacity</source>
+ <target>原始容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb6f3e2a26f3a6f2bc33f91adcd60502dbe5adac" datatype="html">
+ <source>CPUs</source>
+ <target>CPU</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="58d4a9814864741040bc5905b6a368836e683f76" datatype="html">
+ <source>Memory</source>
+ <target>記憶體</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dbb81e566a861d4aa0a094366e4083e50863ee92" datatype="html">
+ <source>Host Details</source>
+ <target>主機詳細資料</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster-review.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="453dc2810080a744223faac6da2b3ee9ed63a583" datatype="html">
+ <source>Welcome to <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></source>
+ <target>歡迎使用 <x id="INTERPOLATION" equiv-text="{{ projectConstants.projectName }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1eec874e1928ca53baa9914781ce203b5f72b0c" datatype="html">
+ <source>Please expand your cluster first</source>
+ <target>請先擴充您的叢集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2195fd96b0a00f560449b50bd032e6d9b357730" datatype="html">
+ <source>Expand Cluster</source>
+ <target>擴充叢集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb075d0450deb6f381616f7da4b9244ced843053" datatype="html">
+ <source>Skip</source>
+ <target>跳過</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="55b6ce65571b8893440a4fc92776570f8fe7cc97" datatype="html">
+ <source>Add Hosts</source>
+ <target>新增主機</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="162f763675c24b557a60eba0758558222369e0c7" datatype="html">
+ <source>Create OSDs</source>
+ <target>建立 OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fef7a7b8db05c351c5287db48488abca530bdb54" datatype="html">
+ <source>Create Services</source>
+ <target>建立服務</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="176873b4533ddeabf95992cbd7b91b9d01c6d557" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ showSubmitButtonLabel() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ed90ec4409b9f6b552982d96f89db27259e763c" datatype="html">
+ <source>You are about to skip the cluster expansion process. You’ll need to <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>navigate through the menu to add hosts and services.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>您即將跳過叢集擴充過程。您需要<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>在功能表中導覽以新增主機和服務<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">90,91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d1dcf2a9146caac0581329acf94806ec69a89a5" datatype="html">
+ <source>Are you sure you want to continue?</source>
+ <target>確定要繼續嗎?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6759205696902713848" datatype="html">
+ <source>Warning</source>
+ <target>警告</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">357</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6962699013778688473" datatype="html">
+ <source>Continue</source>
+ <target>繼續</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6156560100092571435" datatype="html">
+ <source>Cluster expansion skipped by user</source>
+ <target>使用者已跳過叢集擴充</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520085823873354736" datatype="html">
+ <source>Cluster expansion was successful</source>
+ <target>叢集擴充成功</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2176230351113290618" datatype="html">
+ <source>Expand Cluster</source>
+ <target>擴充叢集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/create-cluster/create-cluster.component.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="738de688b22fba5d0dc7a5e549996838dddad0ee" datatype="html">
+ <source>CRUSH map viewer</source>
+ <target>CRUSH 地圖檢視器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/crushmap/crushmap.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e24569eca61d598c8b01defbbbb1fa8bd5222bc" datatype="html">
+ <source>Devices</source>
+ <target>裝置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17137bac47e1e020d139256ded0006a671966e73" datatype="html">
+ <source>Physical Disks</source>
+ <target>實體磁碟</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="deba10b7279a589d01e919ea11f43c79ca1773e3" datatype="html">
+ <source>Device health</source>
+ <target>裝置狀況</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d87fc20ea8e5f0f0500ba5d5061b345be78ec5e" datatype="html">
+ <source>No hostname found.</source>
+ <target>找不到主機名稱。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-details/host-details.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9a541ec1a4319fffc16ad3b3ab2c2b6d251a829d" datatype="html">
+ <source>Hostname</source>
+ <target>主機名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee6875e67b53cac30a02b57cf76e485f7e60caf4" datatype="html">
+ <source>To add multiple hosts at once, you can enter:</source>
+ <target>若要一次新增多個主機,您可以輸入:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a8370b19ccf673fb28fa9db36a08f9901887cc7" datatype="html">
+ <source>a comma-separated list of hostnames <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-01,example-02,example-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <target>主機名稱的逗號分隔清單 <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(例如:example-01,example-02,example-03)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="68f2c05396ec8a5f59e8da42d1f6c7310fa8c37c" datatype="html">
+ <source>a range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</source>
+ <target>範圍運算式 <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(例如:example-[01-03].ceph)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/>,</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e00b9bba448e79add37740e53dc953fbb89f9c5" datatype="html">
+ <source>a comma separated range expression <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(e.g.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></source>
+ <target>範圍運算式的逗號分隔清單 <x id="START_TAG_SAMP" ctype="x-samp" equiv-text="&lt;samp&gt;"/>(例如:mple-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)<x id="CLOSE_TAG_SAMP" ctype="x-samp" equiv-text="&lt;/samp&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b3f5e5291541678f7afa49d28fad5ca848a8061" datatype="html">
+ <source>The chosen hostname is already in use.</source>
+ <target>所選的主機名稱已在使用中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="42365f623c57973d1d13d2038e8a2d4c02fb9b9f" datatype="html">
+ <source>Network address</source>
+ <target>網路位址</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3859bdca1ae89e611e214c205fccf0147b4d0f6b" datatype="html">
+ <source>The value is not a valid IP address.</source>
+ <target>該值不是有效的 IP 位址。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2af7efecfae8d7fed3b07f718a623eca1ad8163f" datatype="html">
+ <source>Labels</source>
+ <target>標籤</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9da2afd4fa358b66d4d95fe7e8f4b659a7144e" datatype="html">
+ <source>Maintenance Mode</source>
+ <target>維護模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="468785112451259935" datatype="html">
+ <source>There are no labels.</source>
+ <target>沒有標籤。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4664081995078497865" datatype="html">
+ <source>Filter or add labels</source>
+ <target>過濾或新增標籤</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4897817053917542646" datatype="html">
+ <source>Add label</source>
+ <target>新增標籤</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">313</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1187321380561233505" datatype="html">
+ <source>host</source>
+ <target>主機</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/host-form/host-form.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40661476cb24c89d8b06614998e31d5fbe84eeb6" datatype="html">
+ <source>Hosts List</source>
+ <target>主機清單</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b7a4e1e5a316f8547af1d6d2311a5cec8c5c1d87" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ msg }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ msg }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6e8e8844e9e7a7b626a4699c08b6c0c81297a7b" datatype="html">
+ <source>Data will be available only if Orchestrator is available.</source>
+ <target>僅當 Orchestrator 可用時,才能獲取資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4baf526199fed59071adf555271791283adc408" datatype="html">
+ <source>SSD, NVMEs</source>
+ <target>SSD、NVME</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="22d5531d79f0d7269a0a752e56a848807dd37095" datatype="html">
+ <source>Flash</source>
+ <target>快閃記憶體</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4025065730478477779" datatype="html">
+ <source>The feature is disabled because the selected host is not managed by Orchestrator.</source>
+ <target>由於所選主機并不是由 Orchestrator 管理,已停用該功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7143579180750436311" datatype="html">
+ <source>Services</source>
+ <target>服務</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">198</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="546766753072101168" datatype="html">
+ <source>Labels</source>
+ <target>標籤</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1141886420788473147" datatype="html">
+ <source>Model</source>
+ <target>型號</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4027647877328291519" datatype="html">
+ <source>CPUs</source>
+ <target>CPU</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2445398473573060226" datatype="html">
+ <source>Cores</source>
+ <target>核心</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1656823484917332451" datatype="html">
+ <source>Total Memory</source>
+ <target>總記憶體</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1939212557812454069" datatype="html">
+ <source>Raw Capacity</source>
+ <target>原始容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5579687933271468638" datatype="html">
+ <source>HDDs</source>
+ <target>HDD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1889285841762768492" datatype="html">
+ <source>Flash</source>
+ <target>快閃記憶體</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1578709829957887527" datatype="html">
+ <source>NICs</source>
+ <target>NIC</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4723031838495967601" datatype="html">
+ <source>Edit Host: <x id="PH" equiv-text="host.hostname"/></source>
+ <target>編輯主機:<x id="PH" equiv-text="host.hostname"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6004907173026319041" datatype="html">
+ <source>Edit Host</source>
+ <target>編輯主機</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">318</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5618131051466022401" datatype="html">
+ <source>Updated Host &quot;<x id="PH" equiv-text="host.hostname"/>&quot;</source>
+ <target>已更新主機 &amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1701954433367210342" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; moved to maintenance</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; 已進入維護模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">342</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3108406586869160854" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; cannot be put into maintenance</source>
+ <target>無法將 &amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; 置於維護模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">375</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1737753151350322492" datatype="html">
+ <source><x id="PH" equiv-text="error.error['detail']"/></source>
+ <target><x id="PH" equiv-text="error.error['detail']"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4054533801359952167" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host.hostname"/>&quot; has exited maintenance</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host.hostname"/>&amp;quot; 已結束維護模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5837599005212786659" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; stopped draining</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host['hostname']"/>&amp;quot; 已停止清空</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1357236071975782353" datatype="html">
+ <source>&quot;<x id="PH" equiv-text="host['hostname']"/>&quot; started draining</source>
+ <target>&amp;quot;<x id="PH" equiv-text="host['hostname']"/>&amp;quot; 已開始清空</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/hosts/hosts.component.ts</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5658400717636093668" datatype="html">
+ <source>Identify</source>
+ <target>身分</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6966707768479328825" datatype="html">
+ <source>Device path</source>
+ <target>裝置路徑</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3955868613858648955" datatype="html">
+ <source>Available</source>
+ <target>可用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="158816374076721379" datatype="html">
+ <source>Vendor</source>
+ <target>廠商</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6024104799101504292" datatype="html">
+ <source>OSDs</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3422162477846071958" datatype="html">
+ <source>Identify device <x id="PH" equiv-text="device"/></source>
+ <target>識別裝置 <x id="PH" equiv-text="device"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4910073658089977244" datatype="html">
+ <source>Please enter the duration how long to blink the LED.</source>
+ <target>請輸入 LED 閃爍的持續時間。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5764931367607989415" datatype="html">
+ <source>1 minute</source>
+ <target>1 分鐘</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809466133764752509" datatype="html">
+ <source>2 minutes</source>
+ <target>2 分鐘</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">235</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1487672983218679675" datatype="html">
+ <source>5 minutes</source>
+ <target>5 分鐘</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="603584938775296395" datatype="html">
+ <source>10 minutes</source>
+ <target>10 分鐘</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6648333117195452824" datatype="html">
+ <source>15 minutes</source>
+ <target>15 分鐘</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6560281329999108838" datatype="html">
+ <source>Execute</source>
+ <target>執行</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6901229416977800100" datatype="html">
+ <source>Identifying '<x id="PH" equiv-text="device"/>' started on host '<x id="PH_1" equiv-text="hostname"/>'</source>
+ <target>正在識別主機 &quot;<x id="PH_1" equiv-text="hostname"/>&quot; 上啟動的 &quot;<x id="PH" equiv-text="device"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d556ab48a65722b400e497f61737f553ee0f89e2" datatype="html">
+ <source>Cluster Logs</source>
+ <target>叢集記錄</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5f966baffd188be0e8adc2d7067b86e55fc9b9de" datatype="html">
+ <source>Audit Logs</source>
+ <target>稽核記錄</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4193c9eb868aeec119b78a14795241e0aa5e8b60" datatype="html">
+ <source>Priority:</source>
+ <target>優先程度:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d78ca51eab260ce3fd917d39190d64df5229b6e" datatype="html">
+ <source>Keyword:</source>
+ <target>關鍵字:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="05fa0bded36de6e73a1fa44838b627349dace044" datatype="html">
+ <source>Date:</source>
+ <target>日期:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a400388de1899b1917138cf7e5286376f72847" datatype="html">
+ <source>Time range:</source>
+ <target>時間範圍:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="de0478286b8b5a939db54e9e5282405364ad2d61" datatype="html">
+ <source>No log entries found. Please try to select different filter options.</source>
+ <target>找不到記錄項目。請嘗試選取其他過濾選項。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c7479674d91142b785b9547a87e5fb51cb16108" datatype="html">
+ <source>Reset filter.</source>
+ <target>重設過濾器。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/logs/logs.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="31a9c2870a934b594d1390146c489f76440859ea" datatype="html">
+ <source>Edit Manager module</source>
+ <target>編輯管理員模組</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="46e09b8290d3d0afdb6baa2021395b0570606a31" datatype="html">
+ <source>The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</source>
+ <target>輸入的值不是有效的 UUID,例如 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7aacd038b39cfd347107d01d1dc27f5cb3e0951c" datatype="html">
+ <source>The entered value needs to be a valid IP address.</source>
+ <target>輸入的值必須是有效的 IP 位址。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f19106149f4b07a0d721f9d317afed393cb7bd93" datatype="html">
+ <source>The entered value is too high! It must be lower or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>.</source>
+ <target>輸入的值過大!值必須小於或等於 <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.max }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d33c40ef9a6c3bf0888df831b25e41e65f9d15b" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>.</source>
+ <target>輸入的值過小!值必須大於或等於 <x id="INTERPOLATION" equiv-text="{{ moduleOption.value.min }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eae7086660cf1e38c7194a2c49ff52cc656f90f5" datatype="html">
+ <source>The entered value needs to be a number.</source>
+ <target>輸入的值必須為數字。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">194</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a73376e04b4fb3a20734c8c39743fba32e6676ce" datatype="html">
+ <source>The entered value needs to be a number or decimal.</source>
+ <target>輸入的值必須為數字或小數。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1898719236268328097" datatype="html">
+ <source>Updated options for module '<x id="PH" equiv-text="this.moduleName"/>'.</source>
+ <target>已更新模組 &quot;<x id="PH" equiv-text="this.moduleName"/>&quot; 的選項。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4186041075388034600" datatype="html">
+ <source>Always-On</source>
+ <target>永遠啟用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7585826646011739428" datatype="html">
+ <source>Edit</source>
+ <target>編輯</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2180291763949669799" datatype="html">
+ <source>Enable</source>
+ <target>啟用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9187855490716817910" datatype="html">
+ <source>Disable</source>
+ <target>停用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1600086764852993170" datatype="html">
+ <source>This Manager module is always on.</source>
+ <target>此管理員模組永遠處於啟用狀態。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3895296744591223546" datatype="html">
+ <source>Reconnecting, please wait ...</source>
+ <target>正在重新連接,請稍候...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81b97b8ea996ad1e4f9fca8415021850214884b1" datatype="html">
+ <source>Status</source>
+ <target>狀態</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="57ec6032f5618d4a9f16eb950ad23d2ce7c24b54" datatype="html">
+ <source>Cluster ID</source>
+ <target>叢集 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67d7facc3fec5f8a49ab9ba0a245872184264ce5" datatype="html">
+ <source>monmap modified</source>
+ <target>monmap 修改時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4906731aaf2b94b4f547646c9bfe58bb77951b6" datatype="html">
+ <source>monmap epoch</source>
+ <target>monmap 版本編號</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd4ee06ffdc46d9dfbd0c0c4f81399021c680056" datatype="html">
+ <source>quorum con</source>
+ <target>仲裁 con</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1176c7db8a8276ccb44cc3d42e2c28d9fa6c6596" datatype="html">
+ <source>quorum mon</source>
+ <target>仲裁 mon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="530ef677a09d681b3ab68cb0760494b3ae72a77c" datatype="html">
+ <source>required con</source>
+ <target>所需 con</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a91558e0d506c32021c31843f8f168899fc65cbf" datatype="html">
+ <source>required mon</source>
+ <target>所需 mon</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3abe9eac5bcd94a54c8da93b312e085ec512e74" datatype="html">
+ <source>In Quorum</source>
+ <target>仲裁成員</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba4b748a676e1f217ce1e736fb7ec1215e677bae" datatype="html">
+ <source>Not In Quorum</source>
+ <target>非仲裁成員</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3517477838460618200" datatype="html">
+ <source>Public Address</source>
+ <target>公用位址</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6949358970125514744" datatype="html">
+ <source>Open Sessions</source>
+ <target>開啟的工作階段</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/monitor/monitor.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4383e9662ea19839c7499b2128d43a195e564317" datatype="html">
+ <source>OSD creation preview</source>
+ <target>OSD 建立預覽</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="366225c51e0b00bcb1c55795a0dc5e81c455f84e" datatype="html">
+ <source>DriveGroups</source>
+ <target>DriveGroup</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91853167141c37b58868f3b0421383dd72fa8a01" datatype="html">
+ <source>Attributes (OSD map)</source>
+ <target>屬性 (OSD 地圖)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f721a500a68c357e8f2a01e60510f6a01e4ba529" datatype="html">
+ <source>Metadata</source>
+ <target>中繼資料</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97842f379e1d4157ac3ab0661b90c352e7cb72d5" datatype="html">
+ <source>Metadata not available</source>
+ <target>中繼資料不可用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24e28e19c5703d7c6be44f4eb595a6a43b618ed" datatype="html">
+ <source>Performance counter</source>
+ <target>效能計數器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-details/osd-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ccb4f84edc0b4e76415bb3f9b73d725b06683af3" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ name }}"/> devices</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ name }}"/> 裝置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60cb3d01e5ddf266ecb4271007a1c3d0f3efdc22" datatype="html">
+ <source>The primary storage devices. These devices contain all OSD data.</source>
+ <target>主要儲存裝置。這些裝置包含所有 OSD 資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b432e04886d0d1fd84f740477383051f85addcf2" datatype="html">
+ <source>Write-Ahead-Log devices. These devices are used for BlueStore’s internal journal. It is only useful to use a WAL device if the device is faster than the primary device (e.g. NVME devices or SSDs). If there is only a small amount of fast storage available (e.g., less than a gigabyte), we recommend using it as a WAL device.</source>
+ <target>預寫式記錄裝置。這些裝置用於儲存 BlueStore 的內部記錄。僅當 WAL 裝置速度快於主要裝置 (例如 NVME 裝置或 SSD) 時,才適合使用 WAL 裝置。如果可用的快速儲存空間很少 (例如不到 1 GB),我們建議將其做為 WAL 裝置使用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b87e181ab9e8393aa5ed759dd3d53836e32c8ffe" datatype="html">
+ <source>DB devices can be used for storing BlueStore’s internal metadata. It is only helpful to provision a DB device if it is faster than the primary device (e.g. NVME devices or SSD).</source>
+ <target>DB 裝置可用於儲存 BlueStore 的內部中繼資料。僅當 DB 裝置速度快於主要裝置 (例如 NVME 裝置或 SSD) 時,才適合佈建 DB 裝置。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
+ <source>Add</source>
+ <target>新增</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="99ee4faa69cd2ea8e3678c1f557c0ff1f05aae46" datatype="html">
+ <source>Clear</source>
+ <target>清除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e0fd3c7af0630f93befa6234a693a32a61084e0" datatype="html">
+ <source>Raw capacity: <x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></source>
+ <target>原始容量:<x id="INTERPOLATION" equiv-text="{{ capacity | dimlessBinary }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1961811273151129466" datatype="html">
+ <source>No available devices</source>
+ <target>沒有可用裝置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617271647728055571" datatype="html">
+ <source>Please add primary devices first</source>
+ <target>請先新增主要裝置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6368751795251107516" datatype="html">
+ <source>Add devices by using filters</source>
+ <target>使用過濾器新增裝置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8edc89137d0d8c5667a2f03230beafae45e58429" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> devices</source>
+ <target><x id="INTERPOLATION" equiv-text="{{ deviceType }}"/> 裝置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eba28e1805b18f7c8ae2e4bc15dcf063b10b3822" datatype="html">
+ <source>At least one of these filters must be applied in order to proceed:</source>
+ <target>至少套用以下過濾器之一才能繼續操作:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="93389aa2fe2bea50bf89554ee51b28f87ee2fb50" datatype="html">
+ <source>Number of devices: <x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>. Raw capacity: <x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>.</source>
+ <target>裝置數量:<x id="INTERPOLATION" equiv-text="{{ filteredDevices.length }}"/>。原始容量:<x id="INTERPOLATION_1" equiv-text="{{ capacity | dimlessBinary }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html</context>
+ <context context-type="linenumber">29,30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6b27c16ddf33b855412c82069dca8120bd3a68a" datatype="html">
+ <source>Individual OSD Flags</source>
+ <target>各 OSD 旗標</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dba0ed9ba355a3bd3296c0bef3bb518744a51a89" datatype="html">
+ <source>Cluster-wide</source>
+ <target>叢集範圍</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e2a3f211cea2cbadb29b6df93e544440b6b68d3e" datatype="html">
+ <source>Restore previous selection</source>
+ <target>還原之前的選擇</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1683654169791509804" datatype="html">
+ <source>No Up</source>
+ <target>禁止標示為啟動</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5754783193519044074" datatype="html">
+ <source>OSDs are not allowed to start</source>
+ <target>不允許 OSD 啟動</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4413588319909369773" datatype="html">
+ <source>No Down</source>
+ <target>禁止標示為停機</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1348746748821823470" datatype="html">
+ <source>OSD failure reports are being ignored, such that the monitors will not mark OSDs down</source>
+ <target>將會忽略 OSD 故障報告,如此監控程式便不會將 OSD 標示為停機</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="301172600132606646" datatype="html">
+ <source>No In</source>
+ <target>禁止標示為加入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4114057962148673377" datatype="html">
+ <source>OSDs that were previously marked out will not be marked back in when they start</source>
+ <target>之前標示為除名的 OSD 在啟動時將不會重新標示為加入叢集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5236523991485603657" datatype="html">
+ <source>No Out</source>
+ <target>禁止標示為除名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1798160169020638994" datatype="html">
+ <source>OSDs will not automatically be marked out after the configured interval</source>
+ <target>OSD 在設定的間隔過後將不會自動標示為除名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3225813593817914267" datatype="html">
+ <source>The flag has been enabled for the entire cluster.</source>
+ <target>已為整個叢集啟用該旗標。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1941050626944682985" datatype="html">
+ <source>Updated OSD Flags</source>
+ <target>已更新 OSD 旗標</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ef50ba2514414f799d4c8fc36067a251904ba81" datatype="html">
+ <source>Cluster-wide OSD Flags</source>
+ <target>叢集範圍的 OSD 旗標</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9042260521669277115" datatype="html">
+ <source>Pause</source>
+ <target>暫停</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6015425610572318971" datatype="html">
+ <source>Pauses reads and writes</source>
+ <target>暫停讀取和寫入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314873595759611676" datatype="html">
+ <source>No Scrub</source>
+ <target>禁止整理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5773570234687653570" datatype="html">
+ <source>Scrubbing is disabled</source>
+ <target>整理已停用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5999821123886006899" datatype="html">
+ <source>No Deep Scrub</source>
+ <target>禁止深層整理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5362685148875251772" datatype="html">
+ <source>Deep Scrubbing is disabled</source>
+ <target>深層整理已停用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5001752039592388485" datatype="html">
+ <source>No Backfill</source>
+ <target>禁止回填</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4851280330655956778" datatype="html">
+ <source>Backfilling of PGs is suspended</source>
+ <target>PG 回填已暫停</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5994953210305546559" datatype="html">
+ <source>No Rebalance</source>
+ <target>不重新平衡</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3698980403470604587" datatype="html">
+ <source>OSD will choose not to backfill unless PG is also degraded</source>
+ <target>OSD 將不選擇回填,除非 PG 也已降級</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4334886823145076432" datatype="html">
+ <source>No Recover</source>
+ <target>禁止復原</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8465994741155792816" datatype="html">
+ <source>Recovery of PGs is suspended</source>
+ <target>PG 復原已暫停</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4052740759486923001" datatype="html">
+ <source>Bitwise Sort</source>
+ <target>按位元排序</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2330377428425572488" datatype="html">
+ <source>Use bitwise sort</source>
+ <target>使用按位元排序</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8943478424576832224" datatype="html">
+ <source>Purged Snapdirs</source>
+ <target>已清除 Snapdir</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7553321860087551262" datatype="html">
+ <source>OSDs have converted snapsets</source>
+ <target>OSD 已轉換 snapset</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6509988280998256208" datatype="html">
+ <source>Recovery Deletes</source>
+ <target>復原刪除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="451760144355116641" datatype="html">
+ <source>Deletes performed during recovery instead of peering</source>
+ <target>在復原期間,而非在建立互聯時執行刪除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="87832369463084597" datatype="html">
+ <source>PG Log Hard Limit</source>
+ <target>PG 記錄硬限制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9135782750879343185" datatype="html">
+ <source>Puts a hard limit on pg log length</source>
+ <target>為 pg 記錄長度設定硬限制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="formTitle" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ action | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ resource | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ <note priority="1" from="description">Example: Create Pool</note>
+ <note priority="1" from="meaning">form title</note>
+ </trans-unit>
+ <trans-unit id="43ecf6bee2aebc07b0aad6dc1fe13e38d14687fa" datatype="html">
+ <source>Shared devices</source>
+ <target>共用裝置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7a1c376f6f1b37de4c318ff2106255ba6c0f5b0b" datatype="html">
+ <source>WAL slots</source>
+ <target>WAL 槽</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73811a6f37b63e6b0e491e221bfa21e9dea8a87a" datatype="html">
+ <source>How many OSDs per WAL device.</source>
+ <target>一部 WAL 裝置對應的 OSD 數量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c67a7ac4762ef1cc855056c6b4daab93e53a0a5" datatype="html">
+ <source>Specify 0 to let Orchestrator backend decide it.</source>
+ <target>指定 0 可讓 Orchestrator 後端決定數量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bda9362e06e6c67341b4a8425b0d29d6b84464b" datatype="html">
+ <source>Value should be greater than or equal to 0</source>
+ <target>值應大於或等於 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="324c2b10152b9dd908222bb0b71f61beb60a30c5" datatype="html">
+ <source>DB slots</source>
+ <target>DB 槽</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c23cf12ef9c76f37fc7a4b7ae3e00fb0f68b6e26" datatype="html">
+ <source>How many OSDs per DB device.</source>
+ <target>一部 DB 裝置對應的 OSD 數量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8255877266497322342" datatype="html">
+ <source>Encryption</source>
+ <target>加密</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-form/osd-form.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b49d7877d24112d4bdfce9256edf61a007fae888" datatype="html">
+ <source>OSDs List</source>
+ <target>OSD 清單</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="172ada0fcf6490b24a897517e9f4299215873ff8" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD(s) <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be marked <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <target>如果繼續,<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> 將標示為<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ markActionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">59,60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="262a49e60d5f6ed9825582ccf3d5ae39daa1da60" datatype="html">
+ <source>The <x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> not safe to be <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>! <x id="INTERPOLATION_1" equiv-text="{{ message }}"/></source>
+ <target><x id="ICU" equiv-text="{selection.hasSingleSelection, select, true {OSD is} other {OSDs are}}"/> <x id="INTERPOLATION" equiv-text="{{ actionDescription }}"/>是不安全操作!<x id="INTERPOLATION_1" equiv-text="{{ message }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71,72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="74bd20d5f558d14cb2fa41ae863cf09c47d02018" datatype="html">
+ <source>{VAR_SELECT, select, true {OSD is} other {OSDs are}}</source>
+ <target>{VAR_SELECT, select, true {OSD} other {OSD}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0e217fd717c5b1f5c17f00c5b174de855acbef0" datatype="html">
+ <source><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> will be <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> if you proceed.</source>
+ <target>如果繼續,<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>OSD <x id="INTERPOLATION" equiv-text="{{ osdIds | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> 將會<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ actionDescription }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">74,75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8cf121660bed7098516a1efe85831d6f415a9411" datatype="html">
+ <source>Preserve OSD ID(s) for replacement.</source>
+ <target>保留 OSD ID 以便取代。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4435645098786961170" datatype="html">
+ <source>out</source>
+ <target>除名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136018875175606726" datatype="html">
+ <source>in</source>
+ <target>加入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1301930865667956193" datatype="html">
+ <source>down</source>
+ <target>停機</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1226060325201042854" datatype="html">
+ <source>Mark</source>
+ <target>標示</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1256299033316818951" datatype="html">
+ <source>OSD lost</source>
+ <target>OSD 遺失</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2795727560928976873" datatype="html">
+ <source>marked lost</source>
+ <target>已標示為遺失</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7685933846431786388" datatype="html">
+ <source>Purge</source>
+ <target>清除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5941516286393808546" datatype="html">
+ <source>OSD</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">224</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3416443212235382421" datatype="html">
+ <source>purged</source>
+ <target>已清除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9191368063029792986" datatype="html">
+ <source>destroy</source>
+ <target>損毀</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">223</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4425946029386289247" datatype="html">
+ <source>destroyed</source>
+ <target>已損毀</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2870788902465061969" datatype="html">
+ <source>Flags</source>
+ <target>旗標</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">323</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8995035642420075344" datatype="html">
+ <source>Recovery Priority</source>
+ <target>復原優先程度</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3601135996773579607" datatype="html">
+ <source>PG scrub</source>
+ <target>PG 整理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7136079353894161076" datatype="html">
+ <source>Device class</source>
+ <target>裝置類別</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">300</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6382718875453721838" datatype="html">
+ <source>PGs</source>
+ <target>PG</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">312</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3660230483843323377" datatype="html">
+ <source>Read bytes</source>
+ <target>讀取位元組數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">329</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3909578649547040612" datatype="html">
+ <source>Write bytes</source>
+ <target>寫入位元組數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3182358405280886750" datatype="html">
+ <source>Read ops</source>
+ <target>讀取操作數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">183</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171292502535561083" datatype="html">
+ <source>Write ops</source>
+ <target>寫入操作數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">190</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6706824709967518168" datatype="html">
+ <source>Edit OSD: <x id="PH" equiv-text="selectedOsd.id"/></source>
+ <target>編輯 OSD:<x id="PH" equiv-text="selectedOsd.id"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">451</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1125148356983553148" datatype="html">
+ <source>Edit OSD</source>
+ <target>編輯 OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">461</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="970212458427610374" datatype="html">
+ <source>Updated OSD '<x id="PH" equiv-text="selectedOsd.id"/>'</source>
+ <target>已更新 OSD &quot;<x id="PH" equiv-text="selectedOsd.id"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">466</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7554728686176829307" datatype="html">
+ <source>Mark OSD <x id="PH" equiv-text="markAction"/></source>
+ <target>將 OSD 標示為<x id="PH" equiv-text="markAction"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="478122291463667978" datatype="html">
+ <source>Mark <x id="PH" equiv-text="markAction"/></source>
+ <target>標示為<x id="PH" equiv-text="markAction"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">502</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2456043080471762298" datatype="html">
+ <source>delete</source>
+ <target>刪除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">530</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="588230151780724018" datatype="html">
+ <source>deleted</source>
+ <target>已刪除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-list/osd-list.component.ts</context>
+ <context context-type="linenumber">532</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1ef1c12ddcee305353623919ef02778569f5454" datatype="html">
+ <source>Advanced configuration options</source>
+ <target>進階組態選項</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7771252117308888928" datatype="html">
+ <source>PG scrub options</source>
+ <target>PG 整理選項</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1797901277775175680" datatype="html">
+ <source>Updated PG scrub options</source>
+ <target>已更新 PG 整理選項</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c35f9c5f268a514b970cc55e9a5dc4bed0988e7f" datatype="html">
+ <source>OSD Recovery Priority</source>
+ <target>OSD 復原優先程度</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74af38005e8a8914e45af2ec412e11ceafef8b6" datatype="html">
+ <source>Priority</source>
+ <target>優先程度</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f48f04b379bfba133825747adfd238d511412e" datatype="html">
+ <source>Customize priority values</source>
+ <target>自訂優先程度值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aa19de2a2b54cbda39e9c62917b23044c087776" datatype="html">
+ <source>This field is required!</source>
+ <target>此欄位為必填欄位!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">406</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b699e94bf376491bd50b70a98531071c737eaf40" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ attr.value.patternHelpText }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="98fe13e7ad6c2b80375d204b47858ded83f80e15" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>.</source>
+ <target>輸入的值過大!值不得大於 <x id="INTERPOLATION" equiv-text="{{ attr.value.maxValue }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423a3c111be47fc5a1bfe46ceb58c81c84db691" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>.</source>
+ <target>輸入的值過小!值不得小於 <x id="INTERPOLATION" equiv-text="{{ attr.value.minValue }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html</context>
+ <context context-type="linenumber">80</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3234179038052466481" datatype="html">
+ <source>Max Backfills</source>
+ <target>最大回填數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847070960491384020" datatype="html">
+ <source>Recovery Max Active</source>
+ <target>處於使用中狀態的最大復原操作數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2088615724570210504" datatype="html">
+ <source>Recovery Max Single Start</source>
+ <target>單次啟動的最大復原操作數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8627094894361422565" datatype="html">
+ <source>Recovery Sleep</source>
+ <target>復原操作間隔睡眠時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7590013429208346303" datatype="html">
+ <source>Custom</source>
+ <target>自訂</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4937275625032609020" datatype="html">
+ <source>Updated OSD recovery speed priority '<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>'</source>
+ <target>已更新 OSD 復原速度優先程度 &quot;<x id="PH" equiv-text="this.osdRecvSpeedForm.getValue( 'priority' )"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts</context>
+ <context context-type="linenumber">227,229</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5251a4355cece3075db43f15d69a24a0f8485707" datatype="html">
+ <source>Reweight OSD: <x id="INTERPOLATION" equiv-text="{{ osdId }}"/></source>
+ <target>重新設定 OSD 的權數:<x id="INTERPOLATION" equiv-text="{{ osdId }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67650b2998db48201b2c6176cbfef51e7211ccaa" datatype="html">
+ <source>The value needs to be between 0 and 1.</source>
+ <target>該值必須介於 0 至 1 之間。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f077ceb52c967a8fe2de9ef0a9d65d72badf186" datatype="html">
+ <source>OSDs <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/>Scrub</source>
+ <target>OSD <x id="ICU" equiv-text="{deep, select, true {Deep } other {}}"/>整理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62b73a34ba65b3073e3560dce828a16d7fd3c0f4" datatype="html">
+ <source>{VAR_SELECT, select, true {Deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {深層} other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c00119503aad4012b77049eee41293338f67756c" datatype="html">
+ <source>You are about to apply a <x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/>scrub to the OSD(s): <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <target>您即將對以下 OSD 套用<x id="ICU" equiv-text="{deep, select, true {deep } other {}}"/>整理:<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ selected | join }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fad3dc421817a16dd6c46c1a0c36de619a8d776e" datatype="html">
+ <source>{VAR_SELECT, select, true {deep } other {}}</source>
+ <target>{VAR_SELECT, select, true {深層} other {}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1086427836866943370" datatype="html">
+ <source><x id="PH" equiv-text="operation"/> was initialized in the following OSD(s): <x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></source>
+ <target>已在下列 OSD 中啟始化 <x id="PH" equiv-text="operation"/>:<x id="PH_1" equiv-text="this.joinPipe.transform( this.selected )"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts</context>
+ <context context-type="linenumber">42,44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47c97aa28f64b11fa5842795fdd02c8c0863c97b" datatype="html">
+ <source>To see all active Prometheus alerts, please provide the URL to the API of Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>若要查看所有使用中 Prometheus 警示,請依 <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> 中所述向 Prometheus 警示管理員 API 提供 URL。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6343323763459782070" datatype="html">
+ <source>Create Silence</source>
+ <target>建立靜默</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1895957424873987405" datatype="html">
+ <source>Job</source>
+ <target>工作</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491474782694268231" datatype="html">
+ <source>Severity</source>
+ <target>嚴重性</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3326877877555410533" datatype="html">
+ <source>Started</source>
+ <target>已啟動</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2375260419993138758" datatype="html">
+ <source>URL</source>
+ <target>URL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="880ad4df5a2051a437321443d69c9a866699e5ad" datatype="html">
+ <source>Active Alerts</source>
+ <target>使用中警示</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9fe218829514884cdd0ca2300573a4e0428c324f" datatype="html">
+ <source>Alerts</source>
+ <target>警示</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa0c44aa1e5727061baa91e954f77e2f5f9a37c9" datatype="html">
+ <source>Silences</source>
+ <target>靜默</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85c737325f5e59517e2d08a71de6d77788aabc95" datatype="html">
+ <source>To see all configured Prometheus alerts, please provide the URL to the API of Prometheus as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>若要查看所有已設定 Prometheus 警示,請依 <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> 中所述向 Prometheus 的 API 提供 URL。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623978917681527907" datatype="html">
+ <source>Group</source>
+ <target>群組</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7410432243549869948" datatype="html">
+ <source>Duration</source>
+ <target>持續時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4109205891084963566" datatype="html">
+ <source>Query</source>
+ <target>查詢</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28f86ffd419b869711aa13f5e5ff54be6d70731c" datatype="html">
+ <source>Edit</source>
+ <target>編輯</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="826b25211922a1b46436589233cb6f1a163d89b7" datatype="html">
+ <source>Delete</source>
+ <target>刪除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">279</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">341</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">441</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3ba06aba047605af8ea1718ec1ba153b7db12a2" datatype="html">
+ <source>Editing a silence will expire the old silence and recreate it as a new silence</source>
+ <target>編輯靜默將會使舊靜默過期,並將其重新建立為新靜默</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a20424156b8816671f61879f0574a4f27d7b16b9" datatype="html">
+ <source>Creator</source>
+ <target>建立者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5a5d7ee2acbfa9c91ab7f41d26bda9ff0cafe42f" datatype="html">
+ <source>Comment</source>
+ <target>備註</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4c11aad490b2d53fdae30b3807beabf79306752c" datatype="html">
+ <source>Start time</source>
+ <target>開始時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32856b1e8e339b747b21e313e2fe65a51fd450bb" datatype="html">
+ <source>If the start time lies in the past the creation time will be used</source>
+ <target>如果開始時間為過去的時間,將使用建立時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a02ea1d4e7424ca989929da5e598f379940fdbf2" datatype="html">
+ <source>Duration</source>
+ <target>持續時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f4e35e36f4d3c62e2c17df41730b6dee4afc4b9" datatype="html">
+ <source>End time</source>
+ <target>結束時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="992123459137d45c15df5548bc9682aad835c04b" datatype="html">
+ <source>Matchers</source>
+ <target>比對器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3e023166c55833d5a13f4143e3dbe372befe1b4e" datatype="html">
+ <source>A silence requires at least one matcher</source>
+ <target>一個靜默至少需要一個比對器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef765bd80c4806c51c891908c07a24bc76f019eb" datatype="html">
+ <source>Add matcher</source>
+ <target>新增比對器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754178820914251524" datatype="html">
+ <source>silence</source>
+ <target>靜默</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8714559758543060819" datatype="html">
+ <source>Attribute name</source>
+ <target>屬性名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1338733395833138319" datatype="html">
+ <source>Regular expression</source>
+ <target>規則運算式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35819898450851998" datatype="html">
+ <source>Please add your Prometheus host to the dashboard configuration and refresh the page</source>
+ <target>請將您的 Prometheus 主機新增至儀表板組態中,然後重新整理頁面</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f2f4cb9d876ff9d34fc082c1ac642d3cb98c360" datatype="html">
+ <source>To enable Silences, please provide the URL to the API of the Prometheus' Alertmanager as described in the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/>.</source>
+ <target>若要啟用靜默,請依 <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;prometheus&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> 中所述向 Prometheus 警示管理員 API 提供 URL。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html</context>
+ <context context-type="linenumber">5,7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7448808151142843482" datatype="html">
+ <source>Created by</source>
+ <target>建立者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4734349318830134239" datatype="html">
+ <source>Ends</source>
+ <target>結束</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1233087251567318644" datatype="html">
+ <source>Silence</source>
+ <target>靜默</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="78af6a5e6e4d305557054b64d10f9f9446d8043d" datatype="html">
+ <source>{VAR_SELECT, select, true {Edit} other {Add}}</source>
+ <target>{VAR_SELECT, select, true {編輯} other {新增}}</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2404fa8e80946d0ce3d0ae369b51cb26ec28d42" datatype="html">
+ <source><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/> Matcher</source>
+ <target><x id="ICU" equiv-text="{editMode, select, true {Edit} other {Add}}"/>比對器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c25e04f554875dc2625a78ba0fc56c6010cd0d3" datatype="html">
+ <source>-- Select an attribute to match against --</source>
+ <target>-- 選取要比對的屬性 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5049e204c14c648691ac775a64fb504467aeb549" datatype="html">
+ <source>Value</source>
+ <target>值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="77fc5c63497fc031ddc97645484e3d94ad27766c" datatype="html">
+ <source>Use regular expression</source>
+ <target>使用規則運算式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5518753745858598442" datatype="html">
+ <source>no spec</source>
+ <target>無規格</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1186363766752354382" datatype="html">
+ <source>unmanaged</source>
+ <target>未受管理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5246585784774990516" datatype="html">
+ <source>count:<x id="PH" equiv-text="count"/></source>
+ <target>計數:<x id="PH" equiv-text="count"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001661117318762535" datatype="html">
+ <source>label:<x id="PH" equiv-text="label"/></source>
+ <target>標籤:<x id="PH" equiv-text="label"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/placement.pipe.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0cb3aa7e9fea1d445a1a9d7797ab17e6ac6fe13b" datatype="html">
+ <source>Service Events</source>
+ <target>服務事件</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3474944817987674409" datatype="html">
+ <source>Daemon type</source>
+ <target>精靈類型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3136939605470297323" datatype="html">
+ <source>Daemon ID</source>
+ <target>精靈 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8171022601808215887" datatype="html">
+ <source>Container ID</source>
+ <target>容器 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8859473568390700297" datatype="html">
+ <source>Container Image name</source>
+ <target>容器影像名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5623167616584404899" datatype="html">
+ <source>Container Image ID</source>
+ <target>容器影像 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="335348913532561915" datatype="html">
+ <source>Last Refreshed</source>
+ <target>上次重新整理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3022087209429182774" datatype="html">
+ <source>Daemon Events</source>
+ <target>精靈事件</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">140</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8604852007710946848" datatype="html">
+ <source>Service Name</source>
+ <target>服務名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="613875387304159316" datatype="html">
+ <source>Service Type</source>
+ <target>服務類型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907644935670421963" datatype="html">
+ <source>Service Events</source>
+ <target>服務事件</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3214a1f3a4c3e89a848b4ec59adeeda3b913c396" datatype="html">
+ <source>-- Select a service type --</source>
+ <target>-- 選取服務類型 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f32579a9fd19d93c083175284ee3426d78751c33" datatype="html">
+ <source>Backend Service</source>
+ <target>後端服務</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2937074aed12b8158e929c58747a8216433b72b" datatype="html">
+ <source>-- No service available --</source>
+ <target>-- 沒有可用的服務 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19fb4480d95a5539db4e9c7b516d414774e61110" datatype="html">
+ <source>-- Select an existing RGW service --</source>
+ <target>-- 選擇現有 RGW 服務 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2798cc1e152b1ec07fd8daf94a2a073d1ba1ebcc" datatype="html">
+ <source>Id</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d5156b9d9a79d162c353c4aa9bc6840ad5c6257" datatype="html">
+ <source>The value does not match the pattern <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&lt;service_id&gt;[.&lt;realm_name&gt;.&lt;zone_name&gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>.</source>
+ <target>該值與模式 <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>&amp;lt;service_id&amp;gt;[.&amp;lt;realm_name&amp;gt;.&amp;lt;zone_name&amp;gt;]<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> 不相符。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83d5d7edd8a0be253c4e93ad4c3efe86d9ac520f" datatype="html">
+ <source>Unmanaged</source>
+ <target>未受管理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c15fa461935e0f600bc5d1660af1da67f024fc2a" datatype="html">
+ <source>Placement</source>
+ <target>放置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="863226cffd5b66a6fee9810a9282a5006d6ef576" datatype="html">
+ <source>Label</source>
+ <target>標籤</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06412bce0f4fe4311193e9763666089bf9d980da" datatype="html">
+ <source>Count</source>
+ <target>計數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f193722f1e788f14a823b89ac1794c3ba934f9f" datatype="html">
+ <source>Only that number of daemons will be created.</source>
+ <target>系統將僅建立該數量的精靈。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee1a29cc658e4fa891be762d7bae96139b57c8f4" datatype="html">
+ <source>The value must be at least 1.</source>
+ <target>值必須至少為 1。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">271</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">369</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">401</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cb2741a46e3560f6bc6dfd99d385e86b08b26d72" datatype="html">
+ <source>Port</source>
+ <target>連接埠</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a23ed3598cca5285606675b6cb2536a56b411ade" datatype="html">
+ <source>The value cannot exceed 65535.</source>
+ <target>值不得超過 65535。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">372</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">404</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d8ebdc326e6b9ff35feee3f762b7ab39c02d78f" datatype="html">
+ <source>-- No pools available --</source>
+ <target>-- 沒有可用的池 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84b675705324741b954615fedf2417d4d873b0b6" datatype="html">
+ <source>Trusted IPs</source>
+ <target>可信的 IP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b543e7c787cc48c2938cbce2d14c6afea5a598df" datatype="html">
+ <source>Comma separated list of IP addresses.</source>
+ <target>IP 位址的逗號分隔清單。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">241</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1039ea40da18a6453d9c1adc72a35aed099029d0" datatype="html">
+ <source>Please add the <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> IP addresses here, otherwise the iSCSI gateways can't be reached.</source>
+ <target>請在此處新增 <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Ceph Manager<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> IP 位址,否則將無法連接至 iSCSI 閘道。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6265b64c17a1e19775769489bfd0b152fa1f3ba1" datatype="html">
+ <source>Virtual IP</source>
+ <target>虛擬 IP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">331</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61893fde6e9e05a6b91619d501edaa7962b438ff" datatype="html">
+ <source>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</source>
+ <target>可以使用輸入服務的虛擬 IP 位址和子網路 (以 CIDR 表示法表示)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">333</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ece04ddf7e96f445415ebd90d93c455e03e8cf53" datatype="html">
+ <source>Frontend Port</source>
+ <target>前端連接埠</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">352</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae6fd97454d184b374984c9ff808176ece54f0dd" datatype="html">
+ <source>The port used to access the ingress service.</source>
+ <target>用於存取輸入服務的連接埠。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1261eacf161f75efc9dfea84dd97b4a466b89aa1" datatype="html">
+ <source>Monitor Port</source>
+ <target>監控程式連接埠</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4df6281ed630ba96f09790a46a7fe0ec0e666bb6" datatype="html">
+ <source>The port used by haproxy for load balancer status.</source>
+ <target>HAProxy 用於實現負載平衡狀態的連接埠。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8ce24ae1d792ed2846ba57e7ed6397a802caeff5" datatype="html">
+ <source>CIDR Networks</source>
+ <target>CIDR 網路</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">414</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7c13184af0c09e3bad77daa5f4869138708d26b2" datatype="html">
+ <source>A list of networks to identify which network interface to use for the virtual IP address.</source>
+ <target>用於識別虛擬 IP 位址所用的網路介面的網路清單。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8fe73a4787b8068b2ba61f54ab7e0f9af2ea1fc9" datatype="html">
+ <source>Version</source>
+ <target>版本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">434</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a6855d17f6b9820bb9709870efdcc7da99552d3" datatype="html">
+ <source>-- Select SNMP version --</source>
+ <target>-- 選取 SNMP 版本 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">442</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a7369891e88cd613e45a39b55a282c97776d05f5" datatype="html">
+ <source>Destination</source>
+ <target>目標</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f09a5d334a73a4b5ba031d7fa65151cad5ec7133" datatype="html">
+ <source>Must be of the format hostname:port.</source>
+ <target>必須採用 &quot;主機名稱:連接埠&quot; 格式。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">457</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b68c79ffe3af1db88180454fbc2fa880a51ccf52" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>hostname:port<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>該值與模式<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>主機名稱:連接埠<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>不相符</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">470</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c90ad98a026d781ab729911873767e549d78f99" datatype="html">
+ <source>Engine Id</source>
+ <target>引擎 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">478</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d39d015ebd667fb6bddf08bb0e5b3faa6cf044c" datatype="html">
+ <source>Unique identifier for the device (in hex).</source>
+ <target>裝置的唯一識別碼 (以十六進位表示)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">480</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514cda7dc49062c5c532427245ce47c4954bc32" datatype="html">
+ <source>The value does not match the pattern: <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64.<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>該值與以下模式不相符:<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>必須以十六進位表示且長度必須為 2 的倍數,最小值為 10,最大值為 64<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2b2d628c51192ade0044212b409c758c20f9c021" datatype="html">
+ <source>Auth Protocol</source>
+ <target>驗證通訊協定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc8bb2315a5101770a752b18e03b5c730539397c" datatype="html">
+ <source>-- Select auth protocol --</source>
+ <target>-- 選取驗證通信協定 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">508</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6777f99fd13e03874afe26ba7289dc9fc211af04" datatype="html">
+ <source>Privacy Protocol</source>
+ <target>隱私通訊協定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">524</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70512b7c13bce85b3928920b29fafbd59a853383" datatype="html">
+ <source>-- Select privacy protocol --</source>
+ <target>-- 選取隱私通訊協定 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b48c81465d14465b95826b99e05acfabef1814c6" datatype="html">
+ <source>Credentials</source>
+ <target>身分證明</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">541</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4ea0163c25c818aab982072b1b8d5ab585e9a5a" datatype="html">
+ <source>SNMP Community</source>
+ <target>SNMP 社群</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">547</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="08c74dc9762957593b91f6eb5d65efdfc975bf48" datatype="html">
+ <source>Username</source>
+ <target>使用者名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">564</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="948758e1412bb2ecdb98e3a4f1cbb6d7458456f2" datatype="html">
+ <source>Encryption</source>
+ <target>加密</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">598</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e65610b5d940367f1ff6b57772b96e94e35fe202" datatype="html">
+ <source>SSL</source>
+ <target>SSL</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">624</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e37e0d06148c7708e88b4a1eb412babbe1a4afc" datatype="html">
+ <source>Certificate</source>
+ <target>證書</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">634</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="295ae4f632322098deca8a3ddfbc7aeaabb5423b" datatype="html">
+ <source>The SSL certificate in PEM format.</source>
+ <target>PEM 格式的 SSL 證書。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">635</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464272c069fe56f6c50f41f426a25b2a42c95ba5" datatype="html">
+ <source>Invalid SSL certificate.</source>
+ <target>SSL 證書無效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">650</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0596d06bf1f8a15d4bfe56226971ecdd78013b1f" datatype="html">
+ <source>Private key</source>
+ <target>私密金鑰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">659</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ded15dc55104994c0230189f34dff84a4955aafb" datatype="html">
+ <source>The SSL private key in PEM format.</source>
+ <target>PEM 格式的 SSL 私密金鑰。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">660</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="19bdc1597d815b456793ff87c89af4257a85a103" datatype="html">
+ <source>Invalid SSL private key.</source>
+ <target>SSL 私密金鑰無效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.html</context>
+ <context context-type="linenumber">675</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3356018487523380058" datatype="html">
+ <source>service</source>
+ <target>服務</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2412938991511187011" datatype="html">
+ <source>There are no hosts.</source>
+ <target>沒有主機。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2594503755408511486" datatype="html">
+ <source>Filter hosts</source>
+ <target>過濾主機</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/service-form/service-form.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5869780110608474933" datatype="html">
+ <source>Placement</source>
+ <target>放置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2956098160626271284" datatype="html">
+ <source>Running</source>
+ <target>執行中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/services/services.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="013f48ee777d2e53e2bcba36e1a99fcbb7ef8cb6" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report configuration</source>
+ <target>第 <x id="INTERPOLATION" equiv-text="{{ step }}"/> 步 (共 2 步):遙測報告組態</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a09b723a928774bff707973c99999dcf3d84a349" datatype="html">
+ <source>The telemetry module sends anonymous data about this Ceph cluster back to the Ceph developers to help understand how Ceph is used and what problems users may be experiencing.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> This data is visualized on <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>public dashboards<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> that allow the community to quickly see summary statistics on how many clusters are reporting, their total capacity and OSD count, and version distribution trends.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> The data being reported does <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>not<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> contain any sensitive data like pool names, object names, object contents, hostnames, or device serial numbers. It contains counters and statistics on how the cluster has been deployed, the version of Ceph, the distribution of the hosts and other parameters which help the project to gain a better understanding of the way Ceph is used. The data is sent secured to <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> and <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (device report).</source>
+ <target>遙測模組會將關於此 Ceph 叢集的匿名資料傳回給 Ceph 開發人員,以協助其瞭解 Ceph 的使用情況,以及使用者可能遇到了什麼問題。<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/>這些資料直觀呈現在<x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://telemetry-public.ceph.com/&quot;&gt;"/>公用儀表板<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>上,社群可透過該儀表板迅速瞭解以下匯總統計資訊:所報告的叢集數量,叢集的總容量和 OSD 計數,以及版本配送趨勢。<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/><x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/>報告的資料<x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>不會<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/>包含池名稱、物件名稱、物件內容、主機名稱或裝置序號等任何敏感性資料。它包含關於以下資訊的計數器和統計資料:叢集的部署方式、Ceph 版本、主機分佈,以及有助於專案更好地瞭解 Ceph 使用情況的其他參數。這些資料會以安全方式傳送至 <x id="INTERPOLATION" equiv-text="{{ sendToUrl }}"/> 和 <x id="INTERPOLATION_1" equiv-text="{{ sendToDeviceUrl }}"/> (裝置報告)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">14,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c95505b5a74151a0c235b19b9c41db7983205ba7" datatype="html">
+ <source>Deactivate</source>
+ <target>停用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19" datatype="html">
+ <source>Channels</source>
+ <target>通道</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e25b17c0b4ef361b6a05aaec2bbd2b7e86680458" datatype="html">
+ <source>The telemetry report is broken down into several &quot;channels&quot;, each with a different type of information that can be configured below.</source>
+ <target>遙測報告細分為數個 &quot;通道&quot;,每個通道包含不同類型的資訊,您可以在下方進行設定。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">32,33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380ab580741bec31346978e7cab8062d6970408d" datatype="html">
+ <source>Basic</source>
+ <target>基本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd898057f0add35258a5fb5c90d792c5e2147452" datatype="html">
+ <source>Includes basic information about the cluster:</source>
+ <target>包含關於叢集的基本資訊:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="da213e9ba8a86b453d04f794f58c9803f7b062b1" datatype="html">
+ <source>Capacity of the cluster</source>
+ <target>叢集容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d5fe31d9e13239bdd223d0bbd289a1b1903e86" datatype="html">
+ <source>Number of monitors, managers, OSDs, MDSs, object gateways, or other daemons</source>
+ <target>監控程式、管理員、OSD、MDS、物件閘道或其他精靈的數量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a3eb7834b4baf412f8863d14883972897d9acb7" datatype="html">
+ <source>Software version currently being used</source>
+ <target>目前所使用的軟體版本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34881ae65482ffa74ccb4043fb2622e48ed146d5" datatype="html">
+ <source>Number and types of RADOS pools and CephFS file systems</source>
+ <target>RADOS 池和 CephFS 檔案系統的數量及類型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="696f8f5ea7a9cf6125b9a3af160981fda363552d" datatype="html">
+ <source>Names of configuration options that have been changed from their default (but not their values)</source>
+ <target>預設值已變更的組態選項名稱 (而不是其值)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34292940316300d09abe5e675d452fae199f626b" datatype="html">
+ <source>Crash</source>
+ <target>當機</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7620e332b7dea1e832158e85847255eb4d9e6bbc" datatype="html">
+ <source>Includes information about daemon crashes:</source>
+ <target>包含關於精靈當機的資訊:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1aa4306a6e840fe35b70c9b07d38ce85f281cfa" datatype="html">
+ <source>Type of daemon</source>
+ <target>精靈類型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4f2cbedb4b14b68bc9f390e3391445c1b6682da" datatype="html">
+ <source>Version of the daemon</source>
+ <target>精靈版本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2d62603cdc75645ea873fc8f7f69c32b5f4a2aa9" datatype="html">
+ <source>Operating system (OS distribution, kernel version)</source>
+ <target>作業系統 (作業系統發行套件、內核版本)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84facf84a73631d66e9a4e0bc1c40097b9d14742" datatype="html">
+ <source>Stack trace identifying where in the Ceph code the crash occurred</source>
+ <target>識別 Ceph 代碼中發生當機的位置的堆疊追蹤</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea64d4177bd648e1a20c92669e6857762b811d8c" datatype="html">
+ <source>Device</source>
+ <target>裝置</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4bc37bcbbcea881a269b4063b3d93dec8ee67d5" datatype="html">
+ <source>Includes information about device metrics like anonymized SMART metrics.</source>
+ <target>包含關於裝置度量標準 (例如匿名 SMART 度量標準) 的資訊。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="37de70e8ba539187d0171a38dad2a63c323096eb" datatype="html">
+ <source>Ident</source>
+ <target>身分</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b126025440f118cd02ce78362d61a5001c27617" datatype="html">
+ <source>Includes user-provided identifying information about the cluster:</source>
+ <target>包含使用者提供的關於叢集的識別資訊:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62c6e9aecff7e04ef7d36fdee4ab4fb285a7a2b5" datatype="html">
+ <source>Contact Information</source>
+ <target>聯絡資訊</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61ba9a84051b3f470122e59cf5a746552b378269" datatype="html">
+ <source>Submitting any contact information is completely optional and disabled by default.</source>
+ <target>提交任何聯絡資訊完全是選擇性操作,預設已停用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="34746fb1c7f3d2194d99652bdff89e6e14c9c4f4" datatype="html">
+ <source>Contact</source>
+ <target>聯絡</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="632cac1e025b77b2d77fed16ad22a410ddacab9e" datatype="html">
+ <source>My first Ceph cluster</source>
+ <target>我的首個 Ceph 叢集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3a58c8a81b9ffda26a154eae25a422c9f7de37b" datatype="html">
+ <source>Organization</source>
+ <target>組織</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e8fda44e2c5bb51860f26cd9c2730f9ae1db9869" datatype="html">
+ <source>Organization name</source>
+ <target>組織名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7d49310535abb3792d8c9c991dd0d990d73d29af" datatype="html">
+ <source>Interval</source>
+ <target>間隔</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91317562c9dfefbdd5973faf11d217f571d073c7" datatype="html">
+ <source>The module compiles and sends a new report every 24 hours by default. You can adjust this interval by setting a different number of hours.</source>
+ <target>模組預設每 24 小時編譯並傳送一次新報告。您可以設定不同的小時數以調整此間隔。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">185,186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a12cf4cf71ef3161a024382ab542cf0eba094504" datatype="html">
+ <source>The entered value is too low! It must be greater or equal to 8.</source>
+ <target>輸入的值過小!值必須大於或等於 8。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a92e437fac14b4010c4515b31c55a311d026a57f" datatype="html">
+ <source>Proxy</source>
+ <target>代理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6de03357358c7eff62aca486508bb5c2046e0669" datatype="html">
+ <source>If the cluster cannot directly connect to the configured telemetry endpoint (default telemetry.ceph.com), you can configure a HTTP/HTTPS proxy server by e.g. adding https://10.0.0.1:8080</source>
+ <target>如果叢集無法直接連接至設定的遙測端點 (預設為 telemetry.ceph.com),您可以設定 HTTP/HTTPS 代理伺服器,例如,透過新增 https://10.0.0.1:8080 來設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5687a733af051bfca97dbffba282e39fbb9b8c8f" datatype="html">
+ <source>You can also include a user:pass if needed e.g. https://ceph:telemetry@10.0.0.1:8080</source>
+ <target>如果需要,您還可以包含 user:pass,例如 https://ceph:telemetry@10.0.0.1:8080</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e6430c68df43ea65e4145972b01186fba40f26a" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Note:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> By clicking 'Next' you will first see a preview of the report content before you can activate the automatic submission of your data.</source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>注意:<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/>按一下 &quot;下一步&quot; 後,您首先會看到報告內容預覽,然後才能啟用資料的自動提交功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">219,220</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8d8d878f8d60905e1306c225716305a331b784c8" datatype="html">
+ <source>Step <x id="INTERPOLATION" equiv-text="{{ step }}"/> of 2: Telemetry report preview</source>
+ <target>第 <x id="INTERPOLATION" equiv-text="{{ step }}"/> 步 (共 2 步):遙測報告預覽</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e23d0064b6474f309c74e1c928cc0920f479d9a5" datatype="html">
+ <source>Report ID <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <target>報告 ID <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;A randomized UUID to identify a particular cluster over the course of several telemetry reports.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">249,252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4060e92658964e356a0992a900c8aa811c2cfec0" datatype="html">
+ <source>A randomized UUID to identify a particular cluster over the course of several telemetry reports.</source>
+ <target>隨機指定的 UUID,用於在數個遙測報告中識別特定的叢集。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="60900bc663571f852a04950a123508b106d97204" datatype="html">
+ <source>Report preview <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></source>
+ <target>報告預覽 <x id="START_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;cd-helper i18n-html html=&quot;The actual telemetry data that will be submitted.&quot;&gt;"/><x id="CLOSE_TAG_CD_HELPER" ctype="x-cd_helper" equiv-text="&lt;/cd-helper&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">267,270</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3de417f739c336284c42904552e81e8d852daecc" datatype="html">
+ <source>The actual telemetry data that will be submitted.</source>
+ <target>將要提交的實際遙測資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="933a2b6f087670ff42c95876e6ecfb2faa3e3867" datatype="html">
+ <source>I agree to my telemetry data being submitted under the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>Community Data License Agreement - Sharing - Version 1.0<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></source>
+ <target>我同意依據<x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://cdla.io/sharing-1-0/&quot;&gt;"/>社群資料授權合約 - 共用 - 1.0 版本<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>提交我的遙測資料</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.html</context>
+ <context context-type="linenumber">304</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8293060085588842566" datatype="html">
+ <source>The Telemetry module has been configured and activated successfully.</source>
+ <target>已成功設定並啟用遙測模組。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5380636888677486786" datatype="html">
+ <source>An Error occurred while updating the Telemetry module configuration. Please Try again</source>
+ <target>更新遙測模組組態時發生錯誤。請重試</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/cluster/telemetry/telemetry.component.ts</context>
+ <context context-type="linenumber">232,233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2bcd3296d2850de762fb943060b7e086a893181" datatype="html">
+ <source>Health</source>
+ <target>狀況</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="61e0f26d843eec0b33ff475e111b0c2f7a80b835" datatype="html">
+ <source>Statistics</source>
+ <target>統計資料</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/dashboard/dashboard.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73caac4265ea7314ff061e5a1d78a6361a6dd3b8" datatype="html">
+ <source>Cluster Status</source>
+ <target>叢集狀態</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="624f596cc3320f5e0a0d7c7346c364e5af9bdd8c" datatype="html">
+ <source>Monitors</source>
+ <target>監控程式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9183778f2c6473d7ccb080f651caa01faaf70c" datatype="html">
+ <source>OSDs</source>
+ <target>OSD</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c34287a0423968dac8a41463b80855a0ff789403" datatype="html">
+ <source>Managers</source>
+ <target>管理員</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="946ac5dea9921dc09d7b0a63b89535371f283b19" datatype="html">
+ <source>Object Gateways</source>
+ <target>物件閘道</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff03fa5bcf37c4da46ad736c1f7d03f959e8ba9a" datatype="html">
+ <source>Metadata Servers</source>
+ <target>中繼資料伺服器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d817609ba4993eba859409ab71e566168f4d5f5a" datatype="html">
+ <source>iSCSI Gateways</source>
+ <target>iSCSI 閘道</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ce9dfdc6dccb28dc75a78c704e09dc18fb02dcfa" datatype="html">
+ <source>Capacity</source>
+ <target>容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="88f383269db2d32cccee9e936fe549dccb9fdbf4" datatype="html">
+ <source>Raw Capacity</source>
+ <target>原始容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498a109c6e9e94f1966de01aa0326f7f0ac6fb52" datatype="html">
+ <source>PG Status</source>
+ <target>PG 狀態</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5f8a813f91a11af99132e4beafc136cfc13d73b" datatype="html">
+ <source>PGs per OSD</source>
+ <target>每個 OSD 的 PG 數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32efd1c3f70e3c5244239de97a2cc95d98534a14" datatype="html">
+ <source>Client Read/Write</source>
+ <target>用戶端讀取/寫入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="52213660b2454d139ada3079a42ec6caf3c3c01e" datatype="html">
+ <source>Client Throughput</source>
+ <target>用戶端輸送量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">203</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="275485415092cbae3a9f3cbb786ebe283cacfdd5" datatype="html">
+ <source>Recovery Throughput</source>
+ <target>復原輸送量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35416fcdf9cb33d2b299d3f2028c390454b55d02" datatype="html">
+ <source>Scrubbing</source>
+ <target>正在整理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">222</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="44ecac93d67c6a671198091c2270354f80322327" datatype="html">
+ <source><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> See <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>Logs<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for more details.</source>
+ <target><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i [ngClass]=&quot;[icons.infoCircle]&quot;&gt;"/><x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/> 請參閱<x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/logs&quot;&gt;"/>記錄<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>以瞭解更多詳細資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.html</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7520247697658334435" datatype="html">
+ <source>Reads</source>
+ <target>讀取</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5947645586591788199" datatype="html">
+ <source>/s</source>
+ <target>/s</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7527163811128350993" datatype="html">
+ <source>Writes</source>
+ <target>寫入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7684088941299429132" datatype="html">
+ <source>IOPS</source>
+ <target>IOPS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81585474102700882" datatype="html">
+ <source>Used</source>
+ <target>已使用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">179</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8695656831075719969" datatype="html">
+ <source>Avail.</source>
+ <target>可用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6352596107300820129" datatype="html">
+ <source>Clean</source>
+ <target>乾淨</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4016774570903735270" datatype="html">
+ <source>Working</source>
+ <target>工作中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4467323362722952678" datatype="html">
+ <source>Unknown</source>
+ <target>未知</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">218</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7790772795962334429" datatype="html">
+ <source>Healthy</source>
+ <target>狀態良好</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4708847204147472247" datatype="html">
+ <source>Misplaced</source>
+ <target>位置不正確</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3120522496446378904" datatype="html">
+ <source>Degraded</source>
+ <target>已降級</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8047698491745405137" datatype="html">
+ <source>Unfound</source>
+ <target>未找到</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="81117556780777231" datatype="html">
+ <source>objects</source>
+ <target>物件</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/health/health.component.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795e8a00db46b750113d5db93e8d97e2b3079894" datatype="html">
+ <source>For an overview of <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/> widgets click <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></source>
+ <target>如需 <x id="INTERPOLATION" equiv-text="{{ groupTitle|lowercase }}"/> 工具集的綜覽,請按一下<x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;dashboard-landing-page-{{ groupTitle|lowercase }}&quot; docText=&quot;here&quot; i18n-docText&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">21,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16bd21c1b48036d54c6a595f5cff2540cfba7f60" datatype="html">
+ <source>here</source>
+ <target>此處</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/info-group/info-group.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8515973702474791807" datatype="html">
+ <source>up</source>
+ <target>up</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4223604072115719661" datatype="html">
+ <source>no filesystems</source>
+ <target>無檔案系統</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2078241808113697591" datatype="html">
+ <source>active</source>
+ <target>使用中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3232506912392089107" datatype="html">
+ <source>standby</source>
+ <target>待命</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8576716133013765863" datatype="html">
+ <source>standby daemons</source>
+ <target>待命精靈</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3629620351427988554" datatype="html">
+ <source>active daemon</source>
+ <target>使用中的精靈</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5954854563228355745" datatype="html">
+ <source>standbyReplay</source>
+ <target>standbyReplay</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mds-summary.pipe.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7329683463736701292" datatype="html">
+ <source>n/a</source>
+ <target>無</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mgr-summary.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/not-available.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8271970016544066882" datatype="html">
+ <source><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (quorum <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</source>
+ <target><x id="PH" equiv-text="value.monmap.mons.length.toString()"/> (仲裁 <x id="PH_1" equiv-text="value.quorum.join(', ')"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/mon-summary.pipe.ts</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6489441800790477240" datatype="html">
+ <source>total</source>
+ <target>總計</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5965118847182332588" datatype="html">
+ <source>near full</source>
+ <target>將滿</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="268166731974484199" datatype="html">
+ <source>full</source>
+ <target>已滿</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/dashboard/osd-summary.pipe.ts</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47116253e36f4e38a97ba41b2d3122c6c15ab904" datatype="html">
+ <source>Clients (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</source>
+ <target>用戶端 (<x id="INTERPOLATION" equiv-text="{{ clients.length }}"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5159814115056353668" datatype="html">
+ <source>Addresses</source>
+ <target>位址</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1811797298582428088" datatype="html">
+ <source>Access Type</source>
+ <target>存取類型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3575940435199094878" datatype="html">
+ <source>Squash</source>
+ <target>Squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2944102521023817891" datatype="html">
+ <source>Cluster</source>
+ <target>叢集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="91772203889648189" datatype="html">
+ <source>NFS Protocol</source>
+ <target>NFS 通訊協定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">48</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3907766170797643122" datatype="html">
+ <source>Pseudo</source>
+ <target>虛擬</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1032539711043211945" datatype="html">
+ <source>Transport</source>
+ <target>傳輸</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2489852208080013495" datatype="html">
+ <source>Storage Backend</source>
+ <target>儲存後端</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8440421106569981118" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4095248496892792741" datatype="html">
+ <source>CephFS User</source>
+ <target>CephFS 使用者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2535727951299201687" datatype="html">
+ <source>CephFS Filesystem</source>
+ <target>CephFS 檔案系統</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2169401160512036026" datatype="html">
+ <source>Security Label</source>
+ <target>安全標籤</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3671149880069127721" datatype="html">
+ <source>Object Gateway</source>
+ <target>物件閘道</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1643028261508790" datatype="html">
+ <source>Object Gateway User</source>
+ <target>物件閘道使用者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-details/nfs-details.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2dae0bda66f6a349444951c0379c28cda47d6d1" datatype="html">
+ <source>Any client can access</source>
+ <target>任何用戶端均可存取</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7882f2edb1d4139800b276b6b0bbf5ae0b2234ef" datatype="html">
+ <source>Addresses</source>
+ <target>位址</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5f3f74c0f6925826cb2188576391c0da01a23f0" datatype="html">
+ <source>Must contain one or more comma-separated values</source>
+ <target>必須包含一或多個逗號分隔值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8bb5b2073697f3f4378c44a49b7524934c9268f4" datatype="html">
+ <source>For example:</source>
+ <target>例如︰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8f969c655b3fbe4fba7e277caf4cd2c459f9fca5" datatype="html">
+ <source>Access Type</source>
+ <target>存取類型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">268</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28952831a284cfe2b4fc39ca610e80b52598905a" datatype="html">
+ <source>Squash</source>
+ <target>Squash</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0660ae339068979854ade34a96546980723dede3" datatype="html">
+ <source>Add clients</source>
+ <target>新增用戶端</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8571141481686087364" datatype="html">
+ <source>(inherited from global config)</source>
+ <target>(自全域組態繼承)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3563954518111128118" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- 選取存取類型 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3802199399355755843" datatype="html">
+ <source>inherited from global config</source>
+ <target>自全域組態繼承</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8729531250118136719" datatype="html">
+ <source>-- Select what kind of user id squashing is performed --</source>
+ <target>-- 選取執行哪種類型的使用者 ID 匿名存取 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f4d1dd59b039ad818d9da7e29a773e10e41d9821" datatype="html">
+ <source>Cluster</source>
+ <target>叢集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="625f8f0f3e5b7c92651606d77484ff3d07b3c12b" datatype="html">
+ <source>This is the ID of an NFS Service.</source>
+ <target>這是 NFS 服務的 ID。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="135b91a2d908d5814b782695470a6a786c99d9d2" datatype="html">
+ <source>-- No cluster available --</source>
+ <target>-- 沒有可用的叢集 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c501dba379f566885919240ea277b5bc10c14d18" datatype="html">
+ <source>-- Select the cluster --</source>
+ <target>-- 選取叢集 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ff7bd3ad665c398c7fe97230ab59e67370653a82" datatype="html">
+ <source>This field is required. To create a new NFS cluster, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>add a new NFS Service<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <target>此欄位為必填欄位。若要建立新的 NFS 叢集,請<x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;['/services', {outlets: {modal: ['create']}}]&quot; class=&quot;btn-link&quot;&gt;"/>新增新的 NFS 服務<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">41,43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b3f6ba7fe84d6508705cdfe234f0fcc8ff85c9cf" datatype="html">
+ <source>Storage Backend</source>
+ <target>儲存後端</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6fee356d1db954255a56d8169405a89595246b9" datatype="html">
+ <source>-- Select the storage backend --</source>
+ <target>-- 選取儲存後端 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a3c2793dd2ef56954f872142d5ec1becb84c0fe1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ fsalAvailabilityError }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="796e42bec8a6996607cf1f3e80235b86d695804a" datatype="html">
+ <source>Volume</source>
+ <target>磁碟區</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee3ba0ab5f0ccd597b3e44021c71e9aaad14df0a" datatype="html">
+ <source>-- No CephFS filesystem available --</source>
+ <target>-- 沒有可用的 CephFS 檔案系統 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">99</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="764c57812558b1ae66c5eec95d7efd2b1bf761e3" datatype="html">
+ <source>-- Select the CephFS filesystem --</source>
+ <target>-- 選取 CephFS 檔案系統 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="957512d0321f73e9f115bce1bd823fa635170c41" datatype="html">
+ <source>Security Label</source>
+ <target>安全標籤</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">119</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="65ce0fa4da1ed55e658aeb31d1644a29f06bb342" datatype="html">
+ <source>Enable security label</source>
+ <target>啟用安全標籤</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">130</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e808f804130c7b6ff719509cbc06ebb27393a48" datatype="html">
+ <source>CephFS Path</source>
+ <target>CephFS 路徑</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1338c2f83e49ea7f2fc04e9fe90c5d330b7a10f" datatype="html">
+ <source>A path in a CephFS file system.</source>
+ <target>CephFS 檔案系統中的路徑。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ecc0107badb6625466aaa3f975b5c05276f432f" datatype="html">
+ <source>Path need to start with a '/' and can be followed by a word</source>
+ <target>路徑必須以 &quot;/&quot; 開頭,後面可接單字</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9f9d8bd873c34c5ab2d4d0cf995fe5183ab25f6e" datatype="html">
+ <source>The path does not exist in the selected volume.</source>
+ <target>所選磁碟區中不存在該路徑。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd197d7773cef10f368f08c53b47979c3df1f22d" datatype="html">
+ <source>Bucket</source>
+ <target>桶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ca90b4b16347ef7017967915e8624472976c85c" datatype="html">
+ <source>The bucket does not exist or is not in the default realm (if multiple realms are configured). To continue, <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>create a new bucket<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
+ <target>桶不存在或不在預設領域中 (如果設定了多個領域)。若要繼續,請<x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/rgw/bucket/create&quot; class=&quot;btn-link&quot;&gt;"/>建立新桶<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">204,206</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bee6900143996c0e908a10564532eba3da0b30fb" datatype="html">
+ <source>NFS Protocol</source>
+ <target>NFS 通訊協定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5043c0921e709935ab026bb3253ffe1f159fca1" datatype="html">
+ <source>NFSv4</source>
+ <target>NFSv4</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6d2c39708a32910f89701dd7e1cfb9ec1c195768" datatype="html">
+ <source>Pseudo</source>
+ <target>虛擬</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1f8be2ae25947bec0b84c2338201580ea053f34e" datatype="html">
+ <source>The position that this <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> export occupies in the <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Pseudo FS<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> (it must be unique).</source>
+ <target>此 <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>NFS v4<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> 輸出在<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>虛擬檔案系統<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>中的位置 (必須是唯一的)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">241,242</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3af55f7fd5b1d9e5a53e030c80116dc635bfb9f" datatype="html">
+ <source>By using different Pseudo options, the same Path may be exported multiple times.</source>
+ <target>透過使用不同虛擬選項,可將同一路徑輸出多次。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5eb719aa900fed3f9d4a1d74bcc158f07f67f684" datatype="html">
+ <source>The pseudo is already in use by another export.</source>
+ <target>另一個輸出中已使用該虛擬。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddf98fcdeeb17643db020d54f42b5e56b5f9a52a" datatype="html">
+ <source>Pseudo needs to start with a '/' and can't contain any of the following: &gt;, &lt;, |, &amp;, ( or ).</source>
+ <target>虛擬必須以 &quot;/&quot; 開頭,並且不能包含以下任何字元:&gt;、&lt;、|、&amp;、( 或 )。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="27eb35c4b4ac08781a7253a2ab40f8f7d957ba51" datatype="html">
+ <source>-- No access type available --</source>
+ <target>-- 沒有可用的存取類型 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">280</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="509ce016c9110a54028dafd741f15ceacbe74b5a" datatype="html">
+ <source>-- Select the access type --</source>
+ <target>-- 選取存取類型 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67ce207d0b7eada1fe3d3187a39ba0c07be76b6c" datatype="html">
+ <source>The Object Gateway NFS backend has a number of limitations which will seriously affect applications writing to the share. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> for details before enabling write access.</source>
+ <target>物件閘道 NFS 後端存在一些限制,將會嚴重影響寫入該共用的應用程式。在啟用寫入存取權前,請參閱 <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;rgw-nfs&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> 以瞭解詳細資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">293,296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4deda03573eaaff77e63f6a238a1f0ca7816950a" datatype="html">
+ <source>-- No squash available --</source>
+ <target>-- 沒有可用的 squash --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">321</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a0e82a4da88e7fdf270444f838d45849676e9d4b" datatype="html">
+ <source>--Select what kind of user id squashing is performed --</source>
+ <target>-- 選取執行哪種類型的使用者 ID 匿名存取 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">324</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d01b7c3f7f06712c53d054cfbe4f53d446b038e8" datatype="html">
+ <source>Transport Protocol</source>
+ <target>傳輸通訊協定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">339</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d2a6ad6e8bc315f07911722c05767ac79c136d99" datatype="html">
+ <source>UDP</source>
+ <target>UDP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">349</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c030f11e0aae9b24d2c048c57f29f590be621df" datatype="html">
+ <source>TCP</source>
+ <target>TCP</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">359</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0f84d7fd4d52eb5b2229b632ef5119dac63d5597" datatype="html">
+ <source>No user id squashing is performed.</source>
+ <target>未在執行使用者 ID 匿名存取。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">378</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb1d148107e36852325106a518385b1b0de28835" datatype="html">
+ <source>uid 0 and gid 0 are squashed to the Anonymous_Uid and Anonymous_Gid gid 0 in alt_groups lists is also squashed.</source>
+ <target>uid 0 和 gid 0 對應至 Anonymous_Uid 和 Anonymous_Gid,alt_groups 清單中的 gid 0 也會進行對應。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">382</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1309d6f67955799863337b201413faa61a175ddb" datatype="html">
+ <source>uid 0 and gid of any value are squashed to the Anonymous_Uid and Anonymous_Gid alt_groups lists is discarded.</source>
+ <target>uid 0 和 gid 的任何值均會對應至 Anonymous_Uid 和 Anonymous_Gid,alt_groups 清單將被丟棄。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">386</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85f23d5c9b57dc78dda4150d13aa3b99e985350b" datatype="html">
+ <source>All users are squashed.</source>
+ <target>所有使用者都為匿名存取使用者。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.html</context>
+ <context context-type="linenumber">390</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2691935247101074756" datatype="html">
+ <source>NFS export</source>
+ <target>NFS 輸出</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.ts</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8727258243239498387" datatype="html">
+ <source><x id="PH" equiv-text="fsalItem.descr"/> backend is not available. <x id="PH_1" equiv-text="errorMessage"/></source>
+ <target><x id="PH" equiv-text="fsalItem.descr"/> 後端不可用。<x id="PH_1" equiv-text="errorMessage"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">308</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2772848515253260635" datatype="html">
+ <source>Error while retrieving paths.</source>
+ <target>擷取路徑時出錯。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">364</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5239928491238988595" datatype="html">
+ <source>Error while retrieving bucket names.</source>
+ <target>擷取桶名稱時出錯。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-form/nfs-form.component.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="734c9905951a774870497c5aaae8e3ee833b6196" datatype="html">
+ <source>CephFS</source>
+ <target>CephFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2190548d236ca5f7bc7ab2bca334b860c5ff2ad4" datatype="html">
+ <source>Object Gateway</source>
+ <target>物件閘道</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/nfs/nfs-list/nfs-list.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca53d681a9892d6fdbb57ee9676582186515e961" datatype="html">
+ <source>Performance counters not available</source>
+ <target>沒有可用的效能計數器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="490e15ecc922965b6d8194754c87c5583aa071f3" datatype="html">
+ <source>The name can only consist of alphanumeric characters, dashes and underscores.</source>
+ <target>名稱只能由英數字元、破折號和底線組成。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9edc2b494e660618af3e5225f68d40b7ca67629c" datatype="html">
+ <source>The chosen erasure code profile name is already in use.</source>
+ <target>所選的糾刪碼設定檔名稱已在使用中。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35a4206db3105ed03e0dd799e1642b75b78123e8" datatype="html">
+ <source>Root</source>
+ <target>根</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf425784c7073c7e7f7c1bb90c2c19db7e751db2" datatype="html">
+ <source>Failure domain type</source>
+ <target>故障網域類型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72396a9565cf644d1fe1b21b790c4243ee270986" datatype="html">
+ <source>Device class</source>
+ <target>裝置類別</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="72d80e0c07bfea1b693a33ef2245007de92a6780" datatype="html">
+ <source>Let Ceph decide</source>
+ <target>讓 Ceph 決定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101611937243846632" datatype="html">
+ <source>Crush Rule</source>
+ <target>Crush 規則</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ef9ff0e6227947b48dfab4ac39ade04af758913b" datatype="html">
+ <source>Plugin</source>
+ <target>外掛程式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dd69b31bce8f630eac1d4762b0bbcf72ce19d193" datatype="html">
+ <source>Data chunks (k)</source>
+ <target>資料區塊 (k)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0d26a6172d32cb81218fe2103c54a818cbc1189" datatype="html">
+ <source>Must be equal to or greater than 2.</source>
+ <target>必須大於或等於 2。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5ba6f4800642eba4e8b056aa7167554c3afa8db0" datatype="html">
+ <source>Chunks (k+m) have exceeded the available OSDs of <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/>.</source>
+ <target>區塊 (k+m) 已超過 <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/> 的可用 OSD 數量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="86fca2f788ce986eef835cd7ef8dfc9ae22447a4" datatype="html">
+ <source>For an equal distribution k has to be a multiple of (k+m)/l.</source>
+ <target>若要實現均衡分佈,k 必須為 (k+m)/l 的倍數。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8dd4bc172f1adc4afadaec291e465b082909148d" datatype="html">
+ <source>K has to be equal to or greater than m in order to recover data correctly through c.</source>
+ <target>K 必須大於或等於 m 才能透過 c 正確復原資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2e5b0e6d0dba31c59f946392699a0a6c4dd9b83" datatype="html">
+ <source>Distribution factor: <x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></source>
+ <target>分佈係數:<x id="INTERPOLATION" equiv-text="{{lrcMultiK}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dab3a299ead121169b8e08ed618c3b6a2f66691b" datatype="html">
+ <source>Coding chunks (m)</source>
+ <target>編碼區塊 (m)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e2773e5bd4948193f18f2361d663ecc3988c656" datatype="html">
+ <source>Must be equal to or greater than 1.</source>
+ <target>必須大於或等於 1。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">146</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">225</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">344</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cde4c945a49a260c0a47bcc7cd956846930a5f7" datatype="html">
+ <source>Durability estimator (c)</source>
+ <target>持久性估值 (c)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4ec9ff9931f8ea1201792d6a01bf9a47b283d692" datatype="html">
+ <source>C has to be equal to or lower than m as m defines the amount of chunks that can be used.</source>
+ <target>C 必須小於或等於 m,因為 m 定義可以使用的區塊數量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="35594fe66657ea07b5b5f560927f78e81a229996" datatype="html">
+ <source>Helper chunks (d)</source>
+ <target>輔助程式區塊 (d)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0c250a8d281291273ed3504ade19ca6537e4d9a" datatype="html">
+ <source>Set d manually or use the plugin's default calculation that maximizes d.</source>
+ <target>以手動訪視設定 d,或使用外掛程式的預設計算值 (最大值為 d)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">173</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4304a5cd95742db0f81c3bdf29aa96bf3b0ca13d" datatype="html">
+ <source>D is automatically updated on k and m changes</source>
+ <target>D 會在 k 和 m 變更時自動更新</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">184</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06a67d52427b12df2b3d439be0e1342ac72aeb5c" datatype="html">
+ <source>D can be set from <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> to <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></source>
+ <target>D 可設定為 <x id="INTERPOLATION" equiv-text="{{getDMin()}}"/> 至 <x id="INTERPOLATION_1" equiv-text="{{getDMax()}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d4f8831d3bd6401e87710c4e3ee844f5efbf5de3" datatype="html">
+ <source>D can only be set to <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></source>
+ <target>D 僅可設定為 <x id="INTERPOLATION" equiv-text="{{getDMax()}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">192</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5d7aacffce2c6032c3ae9ef4d1b3847a926440b" datatype="html">
+ <source>D has to be greater than k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>).</source>
+ <target>D 必須大於 k (<x id="INTERPOLATION" equiv-text="{{getDMin()}}"/>)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fd745d614884edc23c7ac9ad8aba9655f3793ac2" datatype="html">
+ <source>D has to be lower than k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>).</source>
+ <target>D 必須小於 k + m (<x id="INTERPOLATION" equiv-text="{{getDMax()}}"/>)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">199</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af668c2a095a979ea2b4e43cd82c2120ab56c21c" datatype="html">
+ <source>Locality (l)</source>
+ <target>本地性 (l)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="200fea08b63ae8d60cdbf33ffd2636159e87dc1e" datatype="html">
+ <source>Can't split up chunks (k+m) correctly with the current locality.</source>
+ <target>無法使用目前的本地性正確分割 (k+m) 個區塊。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319ac5d692d11da686782159bd70e0b705c228ed" datatype="html">
+ <source>Locality groups: <x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></source>
+ <target>本地性群組:<x id="INTERPOLATION" equiv-text="{{lrcGroups}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">230</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d455a110bf6d2235e314e295ce1dfeee93d3dff2" datatype="html">
+ <source>Crush failure domain</source>
+ <target>CRUSH 故障網域</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b74a495f041f7dd102eee5c0bbc9e03083b538ae" datatype="html">
+ <source>Crush Locality</source>
+ <target>CRUSH 本地性</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2f14a73f7a6e94479f67423cc51102da8d6f524" datatype="html">
+ <source>None</source>
+ <target>無</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">275</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="363a99d62822b92913a4cce196d47f32c1258e2f" datatype="html">
+ <source>Scalar mds</source>
+ <target>Scalar mds</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">288</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2981733b912b693a9dd9d915d6d34f4692cc874a" datatype="html">
+ <source>Technique</source>
+ <target>方法</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e0098b6e47b04ec817361f384ce81d454ba5c0bb" datatype="html">
+ <source>Packetsize</source>
+ <target>封包大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c0252cd81ca54d0a2f69ec9ccf4248e73df5aa4a" datatype="html">
+ <source>Crush root</source>
+ <target>CRUSH 根</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">351</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1548d5c76f0406ddd1ba3c557e1e6db22e95b340" datatype="html">
+ <source>Crush device class</source>
+ <target>CRUSH 裝置類別</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f3f657ffa19dc6ac504b83c86209709522dcf065" datatype="html">
+ <source>Available OSDs: <x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></source>
+ <target>可用 OSD:<x id="INTERPOLATION" equiv-text="{{deviceCount}}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="03d84645f6e019c5a43909bbf2ea1696ee88332c" datatype="html">
+ <source>Directory</source>
+ <target>目錄</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html</context>
+ <context context-type="linenumber">398</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1354845268685595937" datatype="html">
+ <source>EC Profile</source>
+ <target>EC 設定檔</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3938a411d76796f8ae73b72ea4c77661207453bd" datatype="html">
+ <source>Cache Tiers Details</source>
+ <target>快取層詳細資料</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="991790413700941336" datatype="html">
+ <source>Cache Mode</source>
+ <target>快取模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9133265273798382582" datatype="html">
+ <source>Min Evict Age</source>
+ <target>逐出前至少可留存的時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7172092927403263656" datatype="html">
+ <source>Min Flush Age</source>
+ <target>衝洗前至少可留存的時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8096695869347792608" datatype="html">
+ <source>Target Max Bytes</source>
+ <target>目標最大位元組數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8854126142886240282" datatype="html">
+ <source>Target Max Objects</source>
+ <target>目標最大物件數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-details/pool-details.component.ts</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3617215542453015899" datatype="html">
+ <source>No applications added</source>
+ <target>未新增應用程式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4895689494338215646" datatype="html">
+ <source>Applications limit reached</source>
+ <target>已達到應用程式上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7322343326526084293" datatype="html">
+ <source>A pool can only have up to four applications definitions.</source>
+ <target>一個池最多只能有四個應用程式定義。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1393735257943344790" datatype="html">
+ <source>Allowed characters '_a-zA-Z0-9'</source>
+ <target>允許的字元為 &quot;_a-zA-Z0-9&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5520683885127790121" datatype="html">
+ <source>Maximum length is 128 characters</source>
+ <target>最大長度為 128 個字元</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8587418377972855060" datatype="html">
+ <source>Filter or add applications'</source>
+ <target>過濾或新增應用程式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5188881899285829380" datatype="html">
+ <source>Add application</source>
+ <target>新增應用程式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form-data.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="16e113230b6b0d3165e076300880542bac7c8138" datatype="html">
+ <source>The chosen Ceph pool name is already in use.</source>
+ <target>所選的 Ceph 池名稱已在使用中。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c75b132bef7b29fa5171768303c4b96e34ccaf68" datatype="html">
+ <source>It's not possible to create an RBD pool with '/' in the name. Please change the name or remove 'rbd' from the applications list.</source>
+ <target>無法建立名稱中包含 &quot;/&quot; 的 RBD 池。請變更名稱,或從應用程式清單中移除 &quot;rbd&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">34,35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="171dc6d5c6bc4615d99778b0088cae80fd00bd10" datatype="html">
+ <source>Pool name can only contain letters, numbers, '.', '-', '_' or '/'.</source>
+ <target>池名稱只能包含字母、數字、&quot;.&quot;、&quot;-&quot;、&quot;_&quot; 或 &quot;/&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">38</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b85c657469e5ec8231c3de99b22f437bc01ffde5" datatype="html">
+ <source>Pool type</source>
+ <target>池類型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="526c5443254c3b126eedb264840ffe827727bfd3" datatype="html">
+ <source>-- Select a pool type --</source>
+ <target>-- 選取池類型 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abfbe47b630929d93c7343dc154599c2e59330a" datatype="html">
+ <source>PG Autoscale</source>
+ <target>PG 自動調整</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0aa21053410a94aa61d16985a4e95fd65523430d" datatype="html">
+ <source>Placement groups</source>
+ <target>放置群組</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6301f1391d726f8f450bb358058534db19541ca9" datatype="html">
+ <source>At least one placement group is needed!</source>
+ <target>至少需要一個放置群組!</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ba9469a1ce6ed36e039c1f67247c8c81a5c71449" datatype="html">
+ <source>Your cluster can't handle this many PGs. Please recalculate the PG amount needed.</source>
+ <target>您的叢集無法處理這麼多的 PG。請重新計算所需的 PG 數量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80ac68cd883369dac20688bc32b4cb33291b5e50" datatype="html">
+ <source>Calculation help</source>
+ <target>計算說明</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">111</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fccbd60493df26705d957ed6c02a3c447894678f" datatype="html">
+ <source>The current PGs settings were calculated for you, you should make sure the values suit your needs before submit.</source>
+ <target>目前的 PG 設定是為您計算的,您應在提交前確定這些值符合您的需求。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">116,117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a43b2695131b48b76cebba676aba98a2bee17515" datatype="html">
+ <source>Replicated size</source>
+ <target>複製大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7bff144a4c4dc63b0e18fff2617d61a7ebdf2b6c" datatype="html">
+ <source>Minimum: <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></source>
+ <target>最小:<x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a9c54b41f6d58a74e5d0aa3429ed0c87a482551" datatype="html">
+ <source>Maximum: <x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></source>
+ <target>最大:<x id="INTERPOLATION" equiv-text="{{ getMaxSize() }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">139</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="452cf71ec44ee77428656936a6627eaf2dd3b47f" datatype="html">
+ <source>The size specified is out of range. A value from <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> to <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/> is usable.</source>
+ <target>指定的大小超出範圍。請使用介於 <x id="INTERPOLATION" equiv-text="{{ getMinSize() }}"/> 至 <x id="INTERPOLATION_1" equiv-text="{{ getMaxSize() }}"/> 的值。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">144,145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="dda6196ffab88c1825f44a565c7b34e246e7e12f" datatype="html">
+ <source>A size of 1 will not create a replication of the object. The 'Replicated size' includes the object itself.</source>
+ <target>指定 1 將不會建立物件的複本。&quot;複製大小&quot; 包括物件自身。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">148,149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1c870fb00256b8a5b9cb9cd1a124e6390b9bc639" datatype="html">
+ <source>EC Overwrites</source>
+ <target>EC 覆寫</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f1abafaeb40ce52355ddcc24686e3cd17b64e08a" datatype="html">
+ <source>Applications</source>
+ <target>應用程式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb9308b82fc183f710df60909f49cfc73aa5e076" datatype="html">
+ <source>CRUSH</source>
+ <target>CRUSH</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9de7dde00e2139cc4bd03b1837afbe72ad15a1ff" datatype="html">
+ <source>Erasure code profile</source>
+ <target>糾刪碼設定檔</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">200</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="39b4620e6bd444e0a57a0a5c03fa8c96d7fe5235" datatype="html">
+ <source>-- No erasure code profile available --</source>
+ <target>-- 沒有可用的糾刪碼設定檔 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">212</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="498561757390d5528b263ce450d5f38efb00266d" datatype="html">
+ <source>-- Select an erasure code profile --</source>
+ <target>-- 選取糾刪碼設定檔 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">215</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="616a2532fbaace94934f5943e381b63e2623f004" datatype="html">
+ <source>This profile can't be deleted as it is in use.</source>
+ <target>此設定檔正在使用中,不能刪除。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="994363f08f9fbfa3b3994ff7b35c6904fdff18d8" datatype="html">
+ <source>Profile</source>
+ <target>設定檔</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="023d6f718770d2ea4ab8cabe26b0ec27ef967ec2" datatype="html">
+ <source>Used by pools</source>
+ <target>由池使用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">387</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b1061ba5ee07a5c6af09e09330dbc29201baf2aa" datatype="html">
+ <source>Profile is not in use.</source>
+ <target>設定檔未在使用中。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">272</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="33150f22ce5348aa6c499bd092c3f4f3695d62cc" datatype="html">
+ <source>Crush ruleset</source>
+ <target>CRUSH 規則集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">293</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">303</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c69b0bcd4698aa845d32c4c4ad488492552cb469" datatype="html">
+ <source>A new crush ruleset will be implicitly created.</source>
+ <target>將以隱含方式建立一個新的 CRUSH 規則集。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">296</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="896e9987db5e9bb279e6deed5d2dff28c242ef66" datatype="html">
+ <source>There are no rules.</source>
+ <target>沒有規則。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">307</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="73a6b31116b3cc322af951daa0bafdc169e6c42e" datatype="html">
+ <source>-- Select a crush rule --</source>
+ <target>-- 選取 CRUSH 規則 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">317</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7d4894e770f8853050b1f6dd55bdd77a51a8ac6" datatype="html">
+ <source>Placement and
+ replication strategies or distribution policies that allow to
+ specify how CRUSH places data replicas.</source>
+ <target>用於指定
+ CRUSH 放置資料複本方式的放置和
+ 複製策略或分佈規則。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">328,330</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ea91d648f92002bc9f96d9b26b735c83ca0b53c6" datatype="html">
+ <source>This rule can't be deleted as it is in use.</source>
+ <target>此規則正在使用中,不能刪除。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">346</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92da80699921e89fb19372e25b8d0f3b9fa427fc" datatype="html">
+ <source>Crush rule</source>
+ <target>CRUSH 規則</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">365</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5489e9f96835f469f6f728a00d8efa88ea5bc940" datatype="html">
+ <source>Crush steps</source>
+ <target>CRUSH 步驟</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">376</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc5f5496a9e50fe69e1a09784f28d94944108294" datatype="html">
+ <source>Rule is not in use.</source>
+ <target>規則未在使用中。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">391</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="104a0e6900d1d1b0c8cf9e5947e36edb352583fc" datatype="html">
+ <source>The rule can't be used in the current cluster as it has too few OSDs to meet the minimum required OSD by this rule.</source>
+ <target>目前的叢集中無法使用該規則,因為叢集的 OSD 數量太少,不符合此規則要求的最低 OSD 數量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">409,410</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2208d63d5940ce656006a220102b1eb2b5e553da" datatype="html">
+ <source>Compression</source>
+ <target>壓縮</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">420</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c6f25c47da62ec597c6057a36ddfc3209811ec5" datatype="html">
+ <source>Algorithm</source>
+ <target>演算法</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">444</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4903231d42089325a28892c0fde1aed46b733ae6" datatype="html">
+ <source>-- No erasure compression algorithm available --</source>
+ <target>-- 沒有可用的糾刪壓縮演算法 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">455</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d68ddb254275f8f44221e9ad6d8ceeb59ca46a6" datatype="html">
+ <source>Minimum blob size</source>
+ <target>Blob 大小下限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">468</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fb2f176df80647137cbb02bbeb29e5dec707a400" datatype="html">
+ <source>e.g., 128KiB</source>
+ <target>例如 128 KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">477</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1b7f6e53a4521c6eb3ced4c007fdd4cf80bb7707" datatype="html">
+ <source>Value should be greater than 0</source>
+ <target>值應大於 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">482</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">506</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8db98ab14b4e207ec763dfdefbc2dae367aab1cc" datatype="html">
+ <source>Value should be less than the maximum blob size</source>
+ <target>值應小於 blob 大小上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="151efb127a9a4dd25259a0b2055442318a141f5b" datatype="html">
+ <source>Maximum blob size</source>
+ <target>Blob 大小上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">493</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0c656f0e346bbadf46eb1a5d20d0307a3bd20ba8" datatype="html">
+ <source>e.g., 512KiB</source>
+ <target>例如 512 KiB</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a65a24eee8a026f3b1113fe9e157e9a0dd69486" datatype="html">
+ <source>Value should be greater than the minimum blob size</source>
+ <target>值應大於 blob 大小下限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">509</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="261ba09c4a59de83f48f52a23fd328da37e61ff4" datatype="html">
+ <source>Ratio</source>
+ <target>比率</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">517</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c1430457a9c3c66366e51d76bf10396014c576be" datatype="html">
+ <source>Compression ratio</source>
+ <target>壓縮率</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">528</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ae5ce6de352cde949998fb10754459c3a4eb183b" datatype="html">
+ <source>Value should be between 0.0 and 1.0</source>
+ <target>值應介於 0.0 至 1.0 之間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">531</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d99b34162c9c34f10d0ccd8dbae83d8569c2db77" datatype="html">
+ <source>Max bytes</source>
+ <target>最大位元組數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">546</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a1d14a18879c62f3f4ed705318b7164a1160e249" datatype="html">
+ <source>Leave it blank or specify 0 to disable this quota.</source>
+ <target>保留空白或指定 0 可停用此定額。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">572</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7565b131562ff6c5f769fdbd239a772154abdd97" datatype="html">
+ <source>A valid quota should be greater than 0.</source>
+ <target>有效定額應大於 0。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">550</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">574</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b8bf35b66f09a301eef92ffc3cb2fd259df67ce9" datatype="html">
+ <source>Max objects</source>
+ <target>最大物件數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">570</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="95f348167622d832c5ae532b6944635c8e2ae5cb" datatype="html">
+ <source>The value should be greater or equal to 0</source>
+ <target>該值應大於或等於 0</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.html</context>
+ <context context-type="linenumber">586</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1088629182722162774" datatype="html">
+ <source>pool</source>
+ <target>池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">118</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6215593782779198370" datatype="html">
+ <source>erasure code profile</source>
+ <target>糾刪碼設定檔</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4390273881304618317" datatype="html">
+ <source>crush rule</source>
+ <target>Crush 規則</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-form/pool-form.component.ts</context>
+ <context context-type="linenumber">721</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d8a7c8aea58294a3c57c23af0468ddf0ba0c9c7" datatype="html">
+ <source>Pools List</source>
+ <target>池清單</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9055665654201606988" datatype="html">
+ <source>Data Protection</source>
+ <target>資料保護</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6658000829978978023" datatype="html">
+ <source>Applications</source>
+ <target>應用程式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5232365108332422324" datatype="html">
+ <source>PG Status</source>
+ <target>PG 狀態</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">147</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1669788723782899084" datatype="html">
+ <source>Crush Ruleset</source>
+ <target>CRUSH 規則集</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7961062124768120122" datatype="html">
+ <source>Pool deletion is disabled by the mon_allow_pool_delete configuration setting.</source>
+ <target>mon_allow_pool_delete 組態設定已停用池刪除功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/pool/pool-list/pool-list.component.ts</context>
+ <context context-type="linenumber">319</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c" datatype="html">
+ <source>ID</source>
+ <target>ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0ee5132a8da30e0b7f9f5c70dbc91928d17dd909" datatype="html">
+ <source>Owner</source>
+ <target>擁有者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e5c51963a9c553b29427ef783bbb69fa6634fa8c" datatype="html">
+ <source>Index type</source>
+ <target>索引類型</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e6f950a32eaea32ec7e192f9ca3d3dfe469d4ba" datatype="html">
+ <source>Placement rule</source>
+ <target>放置規則</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6972d213e31c4ea4f887e60db99d9881bc8fcd3e" datatype="html">
+ <source>Marker</source>
+ <target>標記</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="47b02acd2d3254d1ace1926f840523f154ebef71" datatype="html">
+ <source>Maximum marker</source>
+ <target>最大標記數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="092fa3a7df9168b14d3f83a77a4035e92b92ce15" datatype="html">
+ <source>Master version</source>
+ <target>主版本</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="97434cc5001d407f90c7447a12d9e8e6848a2aa3" datatype="html">
+ <source>Modification time</source>
+ <target>修改時間</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90fe2e41e7fde38453ce4e619efeea9bc6adea9c" datatype="html">
+ <source>Zonegroup</source>
+ <target>區域群組</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="efeade5060b3add63863c24871f0830fb16b7e6d" datatype="html">
+ <source>Versioning</source>
+ <target>版本設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="62a923f047ca49e7a4782629e91fea1ba32db68f" datatype="html">
+ <source>MFA Delete</source>
+ <target>MFA 刪除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="649a410bd0ace333d067d8fa22f12bdbdb43533b" datatype="html">
+ <source>Bucket quota</source>
+ <target>桶定額</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">115</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">567</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f50a33d3c339f8f4a465141f8caa5d2d8c005251" datatype="html">
+ <source>Enabled</source>
+ <target>已啟用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">110</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">120</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">485</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">579</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cef1595d040e77cbb4466e60382028d4c2040cac" datatype="html">
+ <source>Maximum size</source>
+ <target>最大大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="aa6fb95c355f172bda303de1ce2f38c251a149cf" datatype="html">
+ <source>Unlimited</source>
+ <target>無限制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">124</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ee862a800364b4d11f9b8cb9955a28a60f840a45" datatype="html">
+ <source>Maximum objects</source>
+ <target>最大物件數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">135</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7b84370895ab9eb44672f57146fa05c5947f1c0c" datatype="html">
+ <source>Locking</source>
+ <target>鎖定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">219</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c3d9d2296f7886e8289b9f623323803deacfc6" datatype="html">
+ <source>Days</source>
+ <target>天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f44bdf9ab00a973bbe482e9fc450e3f67e60c0d" datatype="html">
+ <source>Bucket names can only contain lowercase letters, numbers, periods and hyphens.</source>
+ <target>桶名稱只能包含小寫字母、數字、句點以及連字號。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eabb4db920d9f9b2480cf438468b86e1bea02a9b" datatype="html">
+ <source>The chosen name is already in use.</source>
+ <target>所選的名稱已在使用中。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b06de7f834c622197e68b66a2abe893040b174c4" datatype="html">
+ <source>Bucket names must not contain uppercase characters or underscores.</source>
+ <target>桶名稱不能包含大寫字元或底線。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6abacf4af2f66d3af08c5ebe502b21b1f42ac649" datatype="html">
+ <source>Each label must start and end with a lowercase letter or a number.</source>
+ <target>每個標籤都必須以小寫字母或數字開頭和結尾。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85a7f52e6813e0535026f61a2d6e8adc8a1d006a" datatype="html">
+ <source>Bucket names cannot be formatted as IP address.</source>
+ <target>桶名稱不能採用 IP 位址格式。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f2a2460396d35e14e7acfb4e060196a0679bdcff" datatype="html">
+ <source>Bucket labels cannot be empty and can only contain lowercase letters, numbers and hyphens.</source>
+ <target>桶標籤不能為空白且只能包含小寫字母、數字及連字號。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cf5c849977e0be2dbfc862d044edd323bfd9fb77" datatype="html">
+ <source>Bucket names must be 3 to 63 characters long.</source>
+ <target>桶名稱長度必須介於 3 至 63 個字元之間。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8e4c918357c7445fbf19a203e5f0f0ece1960b3b" datatype="html">
+ <source>-- Select a user --</source>
+ <target>-- 選取使用者 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">87</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a4aab1f837bc8ec222e4f25922465d1c5929a1fc" datatype="html">
+ <source>Placement target</source>
+ <target>放置目標</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6bae0a7fc2c9c1fde7d937a8a1a3c7e6825cf7d1" datatype="html">
+ <source>-- Select a placement target --</source>
+ <target>-- 選取放置目標 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="016d24e069e7d505a090fb8243e5cd43b35dc39b" datatype="html">
+ <source>Enables versioning for the objects in the bucket.</source>
+ <target>對桶中的物件啟用版本設定。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">151</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9e6775ffd06878aa145c07359f28557f01ede04f" datatype="html">
+ <source>Multi-Factor Authentication</source>
+ <target>多因素驗證</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29e8a5d4fb767d4ad0c762c81c6264cec4c0ba97" datatype="html">
+ <source>Delete enabled</source>
+ <target>已啟用刪除功能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="40fbc3ac8c1ea4ecfe62247e91f1f999ad5baf76" datatype="html">
+ <source>Enables MFA (multi-factor authentication) Delete, which requires additional authentication for changing the bucket versioning state.</source>
+ <target>啟用 MFA (多因素驗證) 刪除功能,這樣變更桶版本設定狀態時將需要進行額外的驗證。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d24c93a8c13db46defa06ed7b5e026a3edb52b91" datatype="html">
+ <source>Token Serial Number</source>
+ <target>記號序號</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">186</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6d9536c2af2e5e9a228c3e3e1809dc1fefe0149" datatype="html">
+ <source>Token PIN</source>
+ <target>記號 PIN</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">202</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f038d51ab1645f15b0cd58f195c72a7eeebd4729" datatype="html">
+ <source>Enables locking for the objects in the bucket. Locking can only be enabled while creating a bucket.</source>
+ <target>對桶中的物件啟用鎖定功能。只有在建立桶時才能啟用鎖定功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">233</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9af1b4baa2dd8ed2bfc3cc756b12a2271c2dd793" datatype="html">
+ <source>Compliance</source>
+ <target>法規遵循</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="edd600fa489d1b4a4448dce694ed932e52ce8fda" datatype="html">
+ <source>Governance</source>
+ <target>治理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="218c7d6d318c51e7105309aaeb0baec9d19e4efb" datatype="html">
+ <source>The number of days that you want to specify for the default retention period that will be applied to new objects placed in this bucket.</source>
+ <target>您要指定的預設保留天數,將套用於此桶中存放的新物件。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">264</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="289b101ec12427b3ca819df9e43cc3b14fae2cc4" datatype="html">
+ <source>The entered value must be a positive integer.</source>
+ <target>輸入的值必須為正整數。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48d8247c1ba2ea156109bf286c5f6dd26b4be760" datatype="html">
+ <source>Retention Days must be a positive integer.</source>
+ <target>保留天數必須為正整數。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4349284625269221231" datatype="html">
+ <source>bucket</source>
+ <target>桶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6161088322338624846" datatype="html">
+ <source>Updated Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'.</source>
+ <target>已更新物件閘道桶 &quot;<x id="PH" equiv-text="values.bid"/>&quot;。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218632328857697292" datatype="html">
+ <source>Created Object Gateway bucket '<x id="PH" equiv-text="values.bid"/>'</source>
+ <target>已建立物件閘道桶 &quot;<x id="PH" equiv-text="values.bid"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9c338bae89822d7eefbc9a887c458a7d8a98e55e" datatype="html">
+ <source>No Limit</source>
+ <target>無限制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3715596725146409911" datatype="html">
+ <source>Owner</source>
+ <target>擁有者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5545511293826600258" datatype="html">
+ <source>Used Capacity</source>
+ <target>已用容量</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1925090152473969054" datatype="html">
+ <source>Capacity Limit %</source>
+ <target>容量上限 %</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8713861779825116442" datatype="html">
+ <source>Object Limit %</source>
+ <target>物件上限 %</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5913880066213114620" datatype="html">
+ <source>buckets</source>
+ <target>桶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eeba399c4dae8d4890c27b7a2cd2dc28fcf8b5f9" datatype="html">
+ <source>Performance Counters</source>
+ <target>效能計數器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="479488ab6e91ecb375484edc78bee3d13467f33f" datatype="html">
+ <source>Daemons List</source>
+ <target>精靈清單</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">6</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca2dee83bb58290d93fb0d17ee8bc9f095a4576f" datatype="html">
+ <source>Sync Performance</source>
+ <target>同步效能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4378147649219625174" datatype="html">
+ <source>Zone</source>
+ <target>區域</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6148052126949932311" datatype="html">
+ <source>Zone Group</source>
+ <target>區域群組</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3840481991104643295" datatype="html">
+ <source>Realm</source>
+ <target>領域</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1221ca97d19eaa9a7bc0c5243d5fc5befe1d2314" datatype="html">
+ <source>-- Select a type --</source>
+ <target>-- 選取類型 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d1b8990332af18f1c5159a6061ca889bcbb28432" datatype="html">
+ <source>Permission</source>
+ <target>許可權</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a08c589f82f69d892307288da14190ae1dd583d5" datatype="html">
+ <source>-- Select a permission --</source>
+ <target>-- 選取許可權 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">56</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7345972049922682356" datatype="html">
+ <source>capability</source>
+ <target>功能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a94e6b2b5b834d92cceb90037d51ad6165c8b619" datatype="html">
+ <source>Tenant</source>
+ <target>租用戶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
+ <source>User ID</source>
+ <target>使用者 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b760f123248930122fc7e7b6b6bf94e376e959c8" datatype="html">
+ <source>Full name</source>
+ <target>全名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="69b6ac577a19acc39fc0c22342092f327fff2529" datatype="html">
+ <source>Email address</source>
+ <target>電子郵件地址</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="92f3f203270a29b3001871153f02c063484a1574" datatype="html">
+ <source>Suspended</source>
+ <target>已暫停</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011e20c5bbe51602d459a860fbf29b599b55edd" datatype="html">
+ <source>System</source>
+ <target>系統</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db18a2772988415466a7f75dc42663ce78c9c1d3" datatype="html">
+ <source>Maximum buckets</source>
+ <target>最大桶數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2c4c62e8ba24601be5cfe7dc5d32c24bbbd4b53c" datatype="html">
+ <source>Subusers</source>
+ <target>子使用者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17bb3082e6fe5003203ef992a3714172334631a1" datatype="html">
+ <source>Capabilities</source>
+ <target>功能</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">409</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="32f8a0570373cacb9c56cf227502483a29d605bc" datatype="html">
+ <source>MFAs(Id)</source>
+ <target>MFA (ID)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="36ad38f9c1a1485e09b67778a28af84553290ffb" datatype="html">
+ <source>User quota</source>
+ <target>使用者定額</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">473</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0bcd5ef19af0f1b814141ca8c57df623d8270088" datatype="html">
+ <source>Keys</source>
+ <target>金鑰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">306</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2aba1e87039819aca3b70faa9aa848c12bf139ca" datatype="html">
+ <source>Show</source>
+ <target>顯示</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">334</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">395</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5248717555542428023" datatype="html">
+ <source>Username</source>
+ <target>使用者名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="240806681889331244" datatype="html">
+ <source>Unlimited</source>
+ <target>無限制</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="db4e1a734518691b128ef40b939cc673f01d03a6" datatype="html">
+ <source>The value is not valid.</source>
+ <target>該值無效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">523</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">617</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6aaf5d2a304167272ac73e3b1d1c162e16c77858" datatype="html">
+ <source>The chosen user ID is already in use.</source>
+ <target>所選的使用者 ID 已在使用中。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="025be1d01b2f6cbd09e772a1d3de02fab0678b26" datatype="html">
+ <source>Show Tenant</source>
+ <target>顯示租用戶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6af106b0d759fd2882e645604675c4494abfcd5b" datatype="html">
+ <source>The chosen user ID exists in this tenant.</source>
+ <target>此租用戶中存在所選使用者 ID。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="df441e80db2157f9d272b75de724ba4a82b96b57" datatype="html">
+ <source>This is not a valid email address.</source>
+ <target>電子郵件地址無效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">103</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ca271adf154956b8fcb28f4f50a37acb3057ff7c" datatype="html">
+ <source>The chosen email address is already in use.</source>
+ <target>所選的電子郵件地址已在使用中。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="030197cebe938edf35422e92fe14183d06eb670b" datatype="html">
+ <source>Max. buckets</source>
+ <target>最大桶數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">114</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f39256070bfc0714020dfee08895421fc1527014" datatype="html">
+ <source>Disabled</source>
+ <target>已停用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a5c05002b0ac2040f1aede5e727e0ffd06eda819" datatype="html">
+ <source>Custom</source>
+ <target>自訂</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="28872515cb81d197a3a1733fa546d3e0f0dd6c67" datatype="html">
+ <source>The entered value must be &gt;= 1.</source>
+ <target>輸入的值必須大於或等於 1。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="583a219c524155c2314eb06ee29162bb315272a3" datatype="html">
+ <source>S3 key</source>
+ <target>S3 金鑰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c217ee914725a37e9dd2336c721c8e63e9666bdc" datatype="html">
+ <source>Auto-generate key</source>
+ <target>自動產生金鑰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2f1c1c0f2bce4c9f92d1a2061e8161cb0006c31a" datatype="html">
+ <source>Access key</source>
+ <target>存取金鑰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">187</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b864acb67296a9819c1db0069c4c47d8b5ce8f44" datatype="html">
+ <source>Secret key</source>
+ <target>機密金鑰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">214</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">96</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="128d6efb51d9ddc7c0cc695a2deeca5b9523f6e4" datatype="html">
+ <source>There are no subusers.</source>
+ <target>沒有子使用者。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fd6dfb8ecb982dbc3affb2c2d5414c4f5b6abd2" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ subuserLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">294,295</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="67c746c1ba9dab4351fedc4c7cba4e6d6b0dbc47" datatype="html">
+ <source>S3</source>
+ <target>S3</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">311</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d6819038d608623503918fb2553f53d68231ec3a" datatype="html">
+ <source>There are no keys.</source>
+ <target>沒有金鑰。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">316</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">377</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc1c1a7140ff6b815a95b65ee2780fdbe1b2b7a1" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.CREATE | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ s3keyLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">356,357</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6ddb5e991a3ecd2659fb520bc5acc81b67e08ddd" datatype="html">
+ <source>Swift</source>
+ <target>Swift</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">371</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1d01eccdda47fc907c5be35bcb16d2dcd02b0270" datatype="html">
+ <source>There are no capabilities.</source>
+ <target>沒有功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">416</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f5a451c4ea65a4046f0b49d489a7013abf0b5861" datatype="html">
+ <source>All capabilities are already added.</source>
+ <target>已新增所有功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">456</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="043e2ec0036ceadd926fd5e3f93cd6f3565f3648" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ actionLabels.ADD | titlecase }}"/> <x id="INTERPOLATION_1" equiv-text="{{ capabilityLabel | upperFirst }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">461,462</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6146e13ceca5fa5cc17b771b282fe5955f3d19fa" datatype="html">
+ <source>Unlimited size</source>
+ <target>大小不限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">501</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">595</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f6db8aa7c99fdce18edb33dde57729acede2b308" datatype="html">
+ <source>Max. size</source>
+ <target>最大大小</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">511</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">605</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="fc630b2093e880fffa19df99d5cd8b87605037f8" datatype="html">
+ <source>Unlimited objects</source>
+ <target>物件數不限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">538</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">632</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6cda5a993d06f0bb10048be9d3aba6555aa9f356" datatype="html">
+ <source>Max. objects</source>
+ <target>最大物件數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">548</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">642</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="623ac50f37a26caec6fd7cd519b653e3315cba25" datatype="html">
+ <source>The entered value must be &gt;= 0.</source>
+ <target>輸入的值必須大於或等於 0。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">560</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html</context>
+ <context context-type="linenumber">654</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="123010868147850959" datatype="html">
+ <source>user</source>
+ <target>使用者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8368421344177343441" datatype="html">
+ <source>subuser</source>
+ <target>子使用者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4662015204945271252" datatype="html">
+ <source>S3 Key</source>
+ <target>S3 金鑰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts</context>
+ <context context-type="linenumber">36</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9103468069826049692" datatype="html">
+ <source>Updated Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <target>已更新物件閘道使用者 &quot;<x id="PH" equiv-text="uid"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="884841609901737584" datatype="html">
+ <source>Created Object Gateway user '<x id="PH" equiv-text="uid"/>'</source>
+ <target>已建立物件閘道使用者 &quot;<x id="PH" equiv-text="uid"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+ <context context-type="linenumber">274</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4363143805416924501" datatype="html">
+ <source>Tenant</source>
+ <target>租用戶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8301535046747035390" datatype="html">
+ <source>Full name</source>
+ <target>全名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3967269098753656610" datatype="html">
+ <source>Email address</source>
+ <target>電子郵件地址</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5851424994801012357" datatype="html">
+ <source>Suspended</source>
+ <target>已暫停</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4208300173682032371" datatype="html">
+ <source>Max. buckets</source>
+ <target>最大桶數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1670306451865226564" datatype="html">
+ <source>users</source>
+ <target>使用者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="49c614babd1950adb2be75df4e2c9747286d6adc" datatype="html">
+ <source>-- Select a username --</source>
+ <target>-- 選取使用者名稱 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b2841767821d6b66238c34d07e413b0af67aee92" datatype="html">
+ <source>Subuser</source>
+ <target>子使用者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="bd59fc25a7bd98cff3e75117c09697c8a007a514" datatype="html">
+ <source>The chosen subuser ID is already in use.</source>
+ <target>所選的子使用者 ID 已在使用中。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3d386c357ebcbc04ed05c4babd5a03626f9b1674" datatype="html">
+ <source>read, write</source>
+ <target>讀取、寫入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">62</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="84e3e3f9a4f31a039b648c97debf95fcb20f4c4a" datatype="html">
+ <source>full</source>
+ <target>完整</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b6bf81d032a2316464f9df2f0d2f3d753f89f0d3" datatype="html">
+ <source>Swift key</source>
+ <target>Swift 金鑰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">74</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e0c12685d50d47448ceed9423977ef39775c037" datatype="html">
+ <source>Auto-generate secret</source>
+ <target>自動產生機密金鑰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5091031285775138345" datatype="html">
+ <source>Subuser</source>
+ <target>子使用者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts</context>
+ <context context-type="linenumber">37</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8453697749389230205" datatype="html">
+ <source>Swift Key</source>
+ <target>Swift 金鑰</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ac54c18c1b520e948095c83a3a1025f02ce6dcc6" datatype="html">
+ <source>Neither hostname nor OSD ID given</source>
+ <target>未提供主機名稱和 OSD ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4533150758393178756" datatype="html">
+ <source>Device ID</source>
+ <target>裝置 ID</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1291053608320944146" datatype="html">
+ <source>State of Health</source>
+ <target>健康狀態</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="29167121133682512" datatype="html">
+ <source>Good</source>
+ <target>良好</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8767957606064036733" datatype="html">
+ <source>Bad</source>
+ <target>不佳</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8052456228079338924" datatype="html">
+ <source>Stale</source>
+ <target>過時</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6223439643831041743" datatype="html">
+ <source>Life Expectancy</source>
+ <target>預期壽命</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3144481541623761279" datatype="html">
+ <source>Prediction Creation Date</source>
+ <target>預測建立日期</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="264574868375698540" datatype="html">
+ <source>Device Name</source>
+ <target>裝置名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1419569261746199221" datatype="html">
+ <source>Daemons</source>
+ <target>精靈</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/device-list/device-list.component.ts</context>
+ <context context-type="linenumber">72</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4f635b3cb0600409a2ad44a5bd1863c699e6a01c" datatype="html">
+ <source>Failed to retrieve SMART data.</source>
+ <target>無法擷取 SMART 資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">4</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a8a3f354bd640299068edd912f4bb5325264f250" datatype="html">
+ <source>The data received has the JSON format version 2.x and is currently incompatible with the dashboard.</source>
+ <target>收到的資料為 JSON 2.x 版本格式,目前與儀表板不相容。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="04f8a3c7e8ac610e6581960162cc15f55a16696a" datatype="html">
+ <source>No SMART data available.</source>
+ <target>沒有可用的 SMART 資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a185c9b97513b3882604ea9bab60edbfac945c15" datatype="html">
+ <source>SMART overall-health self-assessment test result</source>
+ <target>SMART 整體狀況自評測試結果</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">43</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="290e4c9ad42dc6e9176656c864a5faed8053f406" datatype="html">
+ <source>unknown</source>
+ <target>未知</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3a03d3c2e459f8f8fa7202c0fce465d6165f9e2b" datatype="html">
+ <source>passed</source>
+ <target>通過</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="41435d5a5692c8e412c74deaee95d99dbd3617e1" datatype="html">
+ <source>failed</source>
+ <target>失敗</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ddd5dd6d930030096ea617f62c82b648a0dd9484" datatype="html">
+ <source>Device Information</source>
+ <target>裝置資訊</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">63</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6e149c483d88cfcff11d1c5db85e84af7c3149c4" datatype="html">
+ <source>No device information available for this device.</source>
+ <target>未獲取此裝置的裝置資訊。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20cb12827cbe559a7b1da6fdae96041b3b5c3c55" datatype="html">
+ <source>SMART</source>
+ <target>SMART</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="380295f37caea93701d071485a38ef0bdba57133" datatype="html">
+ <source>No SMART data available for this device.</source>
+ <target>未獲取此裝置的 SMART 資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5758c3f16f8749f0f4e2a787f02e8b4da246102f" datatype="html">
+ <source>SMART data is loading.</source>
+ <target>正在載入 SMART 資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.html</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5363861031080361352" datatype="html">
+ <source>Smartctl has received an unknown argument (error code <x id="PH" equiv-text="smartData.smartctl_error_code"/>). You may be using an incompatible version of smartmontools. Version &gt;= 7.0 of smartmontools is required to successfully retrieve data.</source>
+ <target>Smartctl 收到未知引數 (錯誤代碼 <x id="PH" equiv-text="smartData.smartctl_error_code"/>)。您使用的可能是不相容的 smartmontools 版本。若要成功擷取資料,需使用 7.0 或更新版本的 smartmontools。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">61,64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5085718566932809950" datatype="html">
+ <source>An error with error code <x id="PH" equiv-text="smartData.smartctl_error_code"/> occurred.</source>
+ <target>發生錯誤,錯誤代碼 <x id="PH" equiv-text="smartData.smartctl_error_code"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2091295268977103253" datatype="html">
+ <source>Raw</source>
+ <target>原始</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5963653123239768443" datatype="html">
+ <source>Threshold</source>
+ <target>閾值</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2893124970059125090" datatype="html">
+ <source>When Failed</source>
+ <target>失敗時</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5614367840516299633" datatype="html">
+ <source>Worst</source>
+ <target>最差</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/ceph/shared/smart-list/smart-list.component.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d06ae77f9ec46a4cdd49e7e76c73a411aaf2ee38" datatype="html">
+ <source>Please set a new password.</source>
+ <target>請設定一個新密碼。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8b5b3566e88438f51bd5f6caf6c090ed565ba5ed" datatype="html">
+ <source>You will be redirected to the login page afterwards.</source>
+ <target>之後,系統會將您重新導向至登入頁面。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1cf42e491adc166a337a960eb84d03c0c3f677c8" datatype="html">
+ <source>The old and new passwords must be different.</source>
+ <target>新舊密碼必須不同。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="90163a3d3746819aef42e829f4446331232f3b66" datatype="html">
+ <source>Password confirmation doesn't match the new password.</source>
+ <target>確認密碼與新密碼不符。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login-password-form/login-password-form.component.html</context>
+ <context context-type="linenumber">86</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0070e83d11da39d6f4bb95065c2675db1610b419" datatype="html">
+ <source>Username is required</source>
+ <target>需要提供使用者名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e20f8b8a4706526c9024cc2f39d568345d100dc" datatype="html">
+ <source>Password is required</source>
+ <target>需要提供密碼</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f093d9574ab746b231504bd2cbb65f04bd7b00db" datatype="html">
+ <source>Log in</source>
+ <target>登入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/login/login.component.html</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5590086849807274701" datatype="html">
+ <source>Scope</source>
+ <target>範圍</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2327592562693301723" datatype="html">
+ <source>Read</source>
+ <target>讀取</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5674286808255988565" datatype="html">
+ <source>Create</source>
+ <target>建立</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">126</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4021752662928002901" datatype="html">
+ <source>Update</source>
+ <target>更新</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">142</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022070615528435141" datatype="html">
+ <source>Delete</source>
+ <target>刪除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-details/role-details.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1ea5c4d8942c00752dcc72e72949c5d9832f6399" datatype="html">
+ <source>Description...</source>
+ <target>描述...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="70f45880fce6ac5d8e468e25e82aefbba8098cfe" datatype="html">
+ <source>Permissions</source>
+ <target>許可權</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.html</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="122114774689391224" datatype="html">
+ <source>role</source>
+ <target>角色</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1616102757855967475" datatype="html">
+ <source>All</source>
+ <target>所有</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4416727401284087008" datatype="html">
+ <source>Created role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <target>已建立角色 &quot;<x id="PH" equiv-text="roleFormModel.name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">282</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3472946357042916911" datatype="html">
+ <source>Updated role '<x id="PH" equiv-text="roleFormModel.name"/>'</source>
+ <target>已更新角色 &quot;<x id="PH" equiv-text="roleFormModel.name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-form/role-form.component.ts</context>
+ <context context-type="linenumber">298</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="373024661645814027" datatype="html">
+ <source>System Role</source>
+ <target>系統角色</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">100</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753648234171918096" datatype="html">
+ <source>Deleted role '<x id="PH" equiv-text="role"/>'</source>
+ <target>已刪除角色 &quot;<x id="PH" equiv-text="role"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">127</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1674202514578558795" datatype="html">
+ <source>New name</source>
+ <target>新名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4857700187193019038" datatype="html">
+ <source>Clone Role</source>
+ <target>克隆角色</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="748631939386170157" datatype="html">
+ <source>Cloned role '<x id="PH" equiv-text="values['newName']"/>' from '<x id="PH_1" equiv-text="name"/>'</source>
+ <target>已從 &quot;<x id="PH_1" equiv-text="name"/>&quot; 克隆角色 &quot;<x id="PH" equiv-text="values['newName']"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/role-list/role-list.component.ts</context>
+ <context context-type="linenumber">163</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="195c31a2f970e790231a6bb94a5e8ca0167406d9" datatype="html">
+ <source>The username already exists.</source>
+ <target>該使用者名稱已存在。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f3bdcce4b2e8c37cd7f0f6c92ef8cff34b039b8" datatype="html">
+ <source>Confirm password</source>
+ <target>確認密碼</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="cbb979e63ba50e0ca3adfa09cbdcaefd0853fca1" datatype="html">
+ <source>Password confirmation doesn't match the password.</source>
+ <target>確認的密碼與之前輸入的密碼不符。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">102</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="96621f9ed2e4ae5204564e583d2c816bedead571" datatype="html">
+ <source>Password expiration date</source>
+ <target>密碼過期日期</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="48932db3801fe9d5d72a60a3e656bffd17c1c5d9" datatype="html">
+ <source>Password expiration date...</source>
+ <target>密碼過期日期...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">136</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc" datatype="html">
+ <source>Email</source>
+ <target>電子郵件</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="d0ec081dd61eb4f43aea269077bbe38eae87b7f9" datatype="html">
+ <source>Invalid email.</source>
+ <target>電子郵件無效。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9610487cbeb5796d34d8601b5ac0c0a65f9e1d19" datatype="html">
+ <source>Roles</source>
+ <target>角色</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8913c216dd506e20e412e144381d8d2a65a84359" datatype="html">
+ <source>User must change password at next logon</source>
+ <target>使用者下次登入時必須變更密碼</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">236</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0051a3479d3ba79135c16dc8cc017950a2cce821" datatype="html">
+ <source>You are about to remove &quot;user read / update&quot; permissions from your own user.</source>
+ <target>您即將為您自己的使用者移除 &quot;使用者讀取/更新&quot; 許可權。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="af4bf9fcb256853f14cf947eb1deb8d7f176d3f9" datatype="html">
+ <source>If you continue, you will no longer be able to add or remove roles from any user.</source>
+ <target>若繼續,您將再也無法為任何使用者新增或移除角色。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.html</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8314291969883771319" datatype="html">
+ <source>There are no roles.</source>
+ <target>沒有角色。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4306072924538089180" datatype="html">
+ <source>Created user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <target>已建立使用者 &quot;<x id="PH" equiv-text="userFormModel.username"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1349763489797682899" datatype="html">
+ <source>Update user</source>
+ <target>更新使用者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">221</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8688396456017237992" datatype="html">
+ <source>You were automatically logged out because your roles have been changed.</source>
+ <target>您已被自動登出,因為您的角色發生了變更。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">277</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2335813072344088607" datatype="html">
+ <source>Updated user '<x id="PH" equiv-text="userFormModel.username"/>'</source>
+ <target>已更新使用者 &quot;<x id="PH" equiv-text="userFormModel.username"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-form/user-form.component.ts</context>
+ <context context-type="linenumber">283</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4768749765465246664" datatype="html">
+ <source>Email</source>
+ <target>電子郵件</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="795890916060309463" datatype="html">
+ <source>Roles</source>
+ <target>角色</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6877445485286599988" datatype="html">
+ <source>Password expiration date</source>
+ <target>密碼過期日期</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="705657168061753072" datatype="html">
+ <source>Deleted user '<x id="PH" equiv-text="username"/>'</source>
+ <target>已刪除使用者 &quot;<x id="PH" equiv-text="username"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="405819296611088743" datatype="html">
+ <source>Failed to delete user '<x id="PH" equiv-text="username"/>'</source>
+ <target>無法刪除使用者 &quot;<x id="PH" equiv-text="username"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8935387756949610047" datatype="html">
+ <source>You are currently logged in as '<x id="PH" equiv-text="username"/>'.</source>
+ <target>您目前是以 &quot;<x id="PH" equiv-text="username"/>&quot; 身分登入的。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-list/user-list.component.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0eb15f32b2b92d7f3103ef3ff032621888a8dc32" datatype="html">
+ <source>Old password</source>
+ <target>舊密碼</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229" datatype="html">
+ <source>New password</source>
+ <target>新密碼</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">44</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ede41f01c781b168a783cfcefc6fb67d48780d9b" datatype="html">
+ <source>Confirm new password</source>
+ <target>確認新密碼</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.html</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4809196861118879526" datatype="html">
+ <source>password</source>
+ <target>密碼</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8623124197136601291" datatype="html">
+ <source>Updated user password&quot;</source>
+ <target>已更新使用者密碼&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-password-form/user-password-form.component.ts</context>
+ <context context-type="linenumber">116</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be" datatype="html">
+ <source>Users</source>
+ <target>使用者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/auth/user-tabs/user-tabs.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="ced3246fa3db31be0f7da06648463f29ba378fbe" datatype="html">
+ <source>Selected Object Gateway:</source>
+ <target>所選物件閘道:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c53062af97ebda2a03f905698f58e524ecf8b968" datatype="html">
+ <source>Select Object Gateway</source>
+ <target>所選物件閘道</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/context/context.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="235c355afdcbf72953a15d7fc8d0d9e7a6619f46" datatype="html">
+ <source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Page not Found<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></source>
+ <target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>找不到頁面<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4aee9d027170f84774f2980537556f5099369b82" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for. The page you requested may have been changed or moved.</source>
+ <target>抱歉,我們找不到您要尋找的內容。您所要求的頁面可能已變更或已移動。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">22,23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a2b46fe9a975c6531af77fee858ccd37327980f7" datatype="html">
+ <source>Please consult the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>documentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> on how to configure and enable the <x id="INTERPOLATION" equiv-text="{{ section_info }}"/> management functionality.</source>
+ <target>請參閱<x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;{{ docUrl }}&quot;&gt;"/>文件<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>以瞭解如何設定和啟用 <x id="INTERPOLATION" equiv-text="{{ section_info }}"/> 管理功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">26,27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9d57ca7cab78c6f0d27e0d890cb8cf1515e4e30a" datatype="html">
+ <source>Go To Dashboard</source>
+ <target>移至儀表板</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.component.html</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6578397717654172779" datatype="html">
+ <source>Page Not Found</source>
+ <target>找不到頁面</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8185335715884155108" datatype="html">
+ <source>Sorry, we couldn’t find what you were looking for.
+ The page you requested may have been changed or moved.</source>
+ <target>抱歉,我們找不到您要尋找的內容。
+您所要求的頁面可能已變更或已移動。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">11,12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="143318366100741906" datatype="html">
+ <source>Access Denied</source>
+ <target>拒絕存取</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">79</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5384670299771400832" datatype="html">
+ <source>Sorry, you don’t have permission to view this page or resource.</source>
+ <target>抱歉,您無權檢視此頁面或資源。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/api-interceptor.service.ts</context>
+ <context context-type="linenumber">78</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2424411274809083521" datatype="html">
+ <source>User Denied</source>
+ <target>已拒絕使用者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7645004872908092358" datatype="html">
+ <source>Sorry, the user does not exist in Ceph.
+ You'll be logged out from the Identity Provider when you retry logging in.</source>
+ <target>抱歉,Ceph 中不存在該使用者。
+當您嘗試重新登入時,將會從該身分提供者中登出。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/error/error.ts</context>
+ <context context-type="linenumber">24,25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f286db6ac9482dbf567bc491d49a6eade444895a" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ docItem.text }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7911416166208830577" datatype="html">
+ <source>Help</source>
+ <target>說明</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8878700331247603166" datatype="html">
+ <source>Security</source>
+ <target>安全性</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8642696205489749843" datatype="html">
+ <source>Trademarks</source>
+ <target>商標</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/layouts/login-layout/login-layout.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1481ecd21e760ac919a24e26cf790acd82e40199" datatype="html">
+ <source>Dashboard Settings</source>
+ <target>儀表板設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a79aab4ef674bf3f6532292107c0054302236e0f" datatype="html">
+ <source>User management</source>
+ <target>使用者管理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="197e0246502ca64d0de0df0d5c2deec51d41ff45" datatype="html">
+ <source>Telemetry configuration</source>
+ <target>遙測組態</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/administration/administration.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="85b79c9064aed1ead31ace985f31aa1363f6bdaf" datatype="html">
+ <source>Help</source>
+ <target>說明</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="06638e0f01d82c0786f63aa9832fbe7866b86087" datatype="html">
+ <source>documentation</source>
+ <target>文件</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e351b40b3869a5c7d19c3d4918cb1ac7aaab95c4" datatype="html">
+ <source>API</source>
+ <target>API</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a" datatype="html">
+ <source>About</source>
+ <target>關於</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/dashboard-help/dashboard-help.component.html</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="049dfd9fe6c78914ad58cf89ac6a631fca28ec74" datatype="html">
+ <source>Logged in user</source>
+ <target>登入的使用者</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5022c5ae3ae921c07bf5f881e9b026b4a6708a7" datatype="html">
+ <source>Signed in as <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/></source>
+ <target>以 <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ username }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> 身分登入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9" datatype="html">
+ <source>Change password</source>
+ <target>變更密碼</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5d22c795daf43877a5f708dca2bccd549eb0471d" datatype="html">
+ <source>Sign out</source>
+ <target>登出</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/identity/identity.component.html</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="319e0745bcbc132451569294fa2fa21bf10f555a" datatype="html">
+ <source>Toggle navigation</source>
+ <target>切換導覽</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="f65253954b66e929a8b4d5ecaf61f9129f8cec64" datatype="html">
+ <source>Dashboard</source>
+ <target>儀表板</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">84</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8c95898abff46bfac3ed6eb2afef74597e60b15c" datatype="html">
+ <source>CRUSH map</source>
+ <target>CRUSH 地圖</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e7b2bc4b86de6e96d353f6bf2b4d793ea3a19ba0" datatype="html">
+ <source>Manager Modules</source>
+ <target>管理員模組</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">150</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="eb3d5aefff38a814b76da74371cbf02c0789a1ef" datatype="html">
+ <source>Logs</source>
+ <target>記錄</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="17fc3efe5f9fa4e0289c900cb6202265215a1a27" datatype="html">
+ <source>Monitoring</source>
+ <target>監控中</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7f5d0c10614e8a34f0e2dad33a0568277c50cf69" datatype="html">
+ <source>Block</source>
+ <target>區塊</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3c2562ba992127203dcfd014010b03cb7b8113c6" datatype="html">
+ <source>Mirroring</source>
+ <target>鏡像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">205</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="811c241d56601b91ef26735b770e64428089b950" datatype="html">
+ <source>iSCSI</source>
+ <target>iSCSI</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">217</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a24eabd99ea5af20f5f94c4484649cd30370042b" datatype="html">
+ <source>NFS</source>
+ <target>NFS</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5276fc60d54d667116babb723641b21281d37271" datatype="html">
+ <source>File Systems</source>
+ <target>檔案系統</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9515520496da83179d8b08132f00f575512a1f40" datatype="html">
+ <source>Buckets</source>
+ <target>桶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/navigation/navigation.component.html</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0a23e992f6c6e169a38b2b7338b4e5e803b52e0d" datatype="html">
+ <source>Tasks and Notifications</source>
+ <target>任務與通知</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">2</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/core/navigation/notifications/notifications.component.html</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1390461972315002349" datatype="html">
+ <source>The name of the node under which data should be placed.</source>
+ <target>應用於存放資料的節點名稱。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6575341202068728510" datatype="html">
+ <source>The type of CRUSH nodes across which we should separate replicas.</source>
+ <target>我們應為其分隔複本的 CRUSH 節點類型。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3874278445824365480" datatype="html">
+ <source>The device class data should be placed on.</source>
+ <target>應用於存放資料的裝置類別。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/crush-rule.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="675628105428950215" datatype="html">
+ <source>Each object is split in data-chunks parts, each stored on a different OSD.</source>
+ <target>各物件都被分割成資料區塊部分,分別儲存於不同的 OSD。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5128168460056151476" datatype="html">
+ <source>Compute coding chunks for each object and store them on different OSDs.
+ The number of coding chunks is also the number of OSDs that can be down without losing data.</source>
+ <target>運算各物件的編碼區塊并將它們儲存到不同的 OSD。
+ 編碼區塊的數量等同於在不遺失資料的前提下,可停機的 OSD 數量。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">18,19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8826111293169381132" datatype="html">
+ <source>The jerasure plugin is the most generic and flexible plugin,
+ it is also the default for Ceph erasure coded pools.</source>
+ <target>Jerasure 外掛程式是最通用、最靈活的外掛程式,
+ 也是 Ceph 糾刪碼池的預設外掛程式。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">23,24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1331133460856304156" datatype="html">
+ <source>The more flexible technique is reed_sol_van : it is enough to set k
+ and m. The cauchy_good technique can be faster but you need to chose the packetsize
+ carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents
+ in the sense that they can only be configured with m=2.</source>
+ <target>Reed_sol_van 方法更靈活︰它足以設定 k
+ 和 m。Cauchy_good 方法更快,但您需要小心選擇封包大小。
+ reed_sol_r6_op、liberation、blaum_roth、liber8tion 都是與
+ RAID6 等價的方法,只能為其設定 m=2。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">25,28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4577912952562931806" datatype="html">
+ <source>The encoding will be done on packets of bytes size at a time.
+ Choosing the right packet size is difficult.
+ The jerasure documentation contains extensive information on this topic.</source>
+ <target>一次將對多少位元組的封包進行編碼。
+ 選擇合適的封包大小很難。
+ Jerasure 文件中包含了關於此主題的詳盡資訊。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">29,31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6471646852539810855" datatype="html">
+ <source>With the jerasure plugin, when an erasure coded object is stored on
+ multiple OSDs, recovering from the loss of one OSD requires reading from all the others.
+ For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading
+ from the eleven others to repair.
+
+ The lrc erasure code plugin creates local parity chunks to be able to recover using
+ less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create
+ an additional parity chunk for every four OSDs. When a single OSD is lost, it can be
+ recovered with only four OSDs instead of eleven.</source>
+ <target>使用 jerasure 外掛程式時,若糾刪碼物件儲存於
+ 多個 OSD 上,則復原一個遺失的 OSD 時需要讀取所有其他 OSD。
+ 例如,若 jerasure 設定為 k=8 且 m=4,則遺失一個 OSD 後需讀取
+ 其他十一個 OSD 才能修復。
+
+ Lrc 糾刪碼外掛程式會建立本地同位區塊,因此只需較少的 OSD 即
+ 可復原。例如,若 lrc 設定為 k=8、m=4 且 l=4,它將為每四個 OSD
+ 建立一個額外的同位區塊。這樣,當一個 OSD 遺失時,它只需四個 OSD
+ 即可復原,而不需要十一個。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">34,42</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2619235086723330982" datatype="html">
+ <source>Group the coding and data chunks into sets of size locality. For instance,
+ for k=4 and m=2, when locality=3 two groups of three are created. Each set can
+ be recovered without reading chunks from another set.</source>
+ <target>將編碼區塊和資料區塊分組為大小為 locality 的集合。例如,
+ k=4 且 m=2 時,若 locality=3,則會建立 2 個大小為 3 的組。這樣,各組都能
+ 自行復原,而無需從另一組讀取區塊。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">43,45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3298836762557512588" datatype="html">
+ <source>The type of the crush bucket in which each set of chunks defined
+ by l will be stored. For instance, if it is set to rack, each group of l chunks will be
+ placed in a different rack. It is used to create a CRUSH rule step such as step choose
+ rack. If it is not set, no such grouping is done.</source>
+ <target>由 l 定義的區塊集將依据哪種 CRUSH 桶類型儲存。
+ 例如,若設定為機架,則各組 l 區塊將會被放置到不同的
+ 機架中。該值用於建立類似 step choose rack 的 CRUSH
+ 規則步驟。若未設定,則不會進行此類分組。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">46,49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9162461669419243962" datatype="html">
+ <source>The isa plugin encapsulates the ISA library. It only runs on Intel processors.</source>
+ <target>Isa 外掛程式封裝了 ISA 程式庫,只能在 Intel 處理器上執行。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2389282202903059852" datatype="html">
+ <source>The ISA plugin comes in two Reed Solomon forms.
+ If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.</source>
+ <target>ISA 外掛程式包含兩種 Reed Solomon 格式。
+ 若設定為 reed_sol_van,表示使用 Vandermonde。若設定為 cauchy,表示使用 Cauchy。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">53,54</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7319555444402547739" datatype="html">
+ <source>The shec plugin encapsulates the multiple SHEC library.
+ It allows ceph to recover data more efficiently than Reed Solomon codes.</source>
+ <target>Shec 外掛程式封裝了多個 SHEC 程式庫。
+ 與 Reed Solomon 代碼相比,它可讓 ceph 更有效地復原資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">57,58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7723217930035575928" datatype="html">
+ <source>The number of parity chunks each of which includes each data chunk in its
+ calculation range. The number is used as a durability estimator. For instance, if c=2,
+ 2 OSDs can be down without losing data.</source>
+ <target>同位區塊的數量,它們在各自的計算範圍內包含了
+ 各資料區塊。該數值用做持久性估值。例如,若 c=2,
+ 則在不遺失資料的前提下,可有 2 個 OSD 停機。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">59,61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2054101840892270818" datatype="html">
+ <source>CLAY (short for coupled-layer) codes are erasure codes designed to
+ bring about significant savings in terms of network bandwidth and disk IO when a failed
+ node/OSD/rack is being repaired.</source>
+ <target>CLAY (耦合層縮寫) 代碼是糾刪碼,可用於
+ 在修復故障節點/OSD/機架時大幅節省
+ 網路頻寬和磁碟 IO。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">64,66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6491096236680229427" datatype="html">
+ <source>Number of OSDs requested to send data during recovery of a single chunk.
+ d needs to be chosen such that k+1 &lt;= d &lt;= k+m-1. The larger the d, the better
+ the savings.</source>
+ <target>復原單個區塊期間申請傳送資料的 ODS 數量。
+ 選擇的 d 應大於等於 k+1 且小於等於 k+m-1。d 越大,節省的越多。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">67,69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2625895656705896729" datatype="html">
+ <source>scalar_mds specifies the plugin that is used as a building block
+ in the layered construction. It can be one of jerasure, isa, shec.</source>
+ <target>Scalar_mds 指定分層建構中做為建置組塊使用
+ 的外掛程式。可以是 jerasure、isa、shec 之一。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">70,71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6639141182731628232" datatype="html">
+ <source>technique specifies the technique that will be picked
+ within the 'scalar_mds' plugin specified. Supported techniques
+ are 'reed_sol_van', 'reed_sol_r6_op', 'cauchy_orig',
+ 'cauchy_good', 'liber8tion' for jerasure, 'reed_sol_van',
+ 'cauchy' for isa and 'single', 'multiple' for shec.</source>
+ <target>方法指定將會在所指定的 &quot;scalar_mds&quot; 外掛程式中
+ 選取的方法。支援的方法包括
+ &quot;reed_sol_van&quot;、&quot;reed_sol_r6_op&quot;、&quot;cauchy_orig&quot;、
+ &quot;cauchy_good&quot;、&quot;liber8tion” (用於 jerasure)、&quot;reed_sol_van&quot;、
+ &quot;cauchy” (用於 isa),&quot;single&quot;、&quot;multiple” (用於 shec)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">72,76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8172892264673403098" datatype="html">
+ <source>The name of the crush bucket used for the first step of the CRUSH rule.
+ For instance step take default.</source>
+ <target>CRUSH 規則的第一步所指向的 CRUSH 桶名稱。
+ 例如 step take default。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">80,81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1654284403437084515" datatype="html">
+ <source>Ensure that no two chunks are in a bucket with the same failure
+ domain. For instance, if the failure domain is host no two chunks will be stored on the same
+ host. It is used to create a CRUSH rule step such as step chooseleaf host.</source>
+ <target>確定兩個區塊不會存在於同一故障網域的桶中。
+ 例如,若故障網域為主機,則不會有兩個區塊儲存於同一主機中。
+ 該值用於建立類似 step chooseleaf host 的 CRUSH 規則步驟。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">83,85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7737703816676512224" datatype="html">
+ <source>Restrict placement to devices of a specific class
+ (e.g., ssd or hdd), using the crush device class names in the CRUSH map.</source>
+ <target>使用 CRUSH 地圖中的 crush 裝置類別名稱,
+ 將放置限制於特定類別的裝置 (例如 ssd 或 hdd)。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">87,88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9049698214199657456" datatype="html">
+ <source>Set the directory name from which the erasure code plugin is loaded.</source>
+ <target>設定糾刪碼外掛程式所在目錄的名稱。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/erasure-code-profile.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5514060020564877279" datatype="html">
+ <source>Allows all operations</source>
+ <target>允許所有操作</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4265406815683383218" datatype="html">
+ <source>Allows only operations that do not modify the server</source>
+ <target>僅允許不修改伺服器的操作</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="990071930378308183" datatype="html">
+ <source>Allows no access at all</source>
+ <target>完全禁止存取</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7286983657616285612" datatype="html">
+ <source>Please specify a filesystem volume.</source>
+ <target>請指定檔案系統磁碟區。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/nfs.service.ts</context>
+ <context context-type="linenumber">91</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8321762156640395170" datatype="html">
+ <source>The feature is disabled because Orchestrator is not available.</source>
+ <target>該功能已停用,因為 Orchestrator 不可用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6718394293315494787" datatype="html">
+ <source>The Orchestrator backend doesn't support this feature.</source>
+ <target>Orchestrator 後端不支援此功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/orchestrator.service.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5569418400096331461" datatype="html">
+ <source>-- Select the priority --</source>
+ <target>-- 選取優先程度 --</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="802458941707537739" datatype="html">
+ <source>Low</source>
+ <target>低</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8063651736083474594" datatype="html">
+ <source>High</source>
+ <target>高</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/api/osd.service.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1717753935149218245" datatype="html">
+ <source>The user list data might be stale. If needed, you can manually reload it.</source>
+ <target>使用者清單資料可能已過時。如果需要,您可以手動方式重新載入這些資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/list-with-details.class.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7077550143229856452" datatype="html">
+ <source>Retrieving data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>正在擷取 <x id="PH" equiv-text="statusFor"/> 的資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8231424898988217966" datatype="html">
+ <source>Retrieving data.</source>
+ <target>正在擷取資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2357645764289315007" datatype="html">
+ <source>Please wait...</source>
+ <target>請稍候...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="232824565824302482" datatype="html">
+ <source>Displaying previously cached data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>正在顯示之前快取的 <x id="PH" equiv-text="statusFor"/> 資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8721257977793603730" datatype="html">
+ <source>Displaying previously cached data.</source>
+ <target>正在顯示之前快取的資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6731313206654246255" datatype="html">
+ <source>Could not load data for <x id="PH" equiv-text="statusFor"/>.</source>
+ <target>無法載入 <x id="PH" equiv-text="statusFor"/> 的資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">30</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3359748695862553898" datatype="html">
+ <source>Could not load data.</source>
+ <target>無法載入資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">31</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4836577225879717660" datatype="html">
+ <source>Please check the cluster health.</source>
+ <target>請檢查叢集狀態。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/classes/table-status-view-cache.ts</context>
+ <context context-type="linenumber">33</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1519954996184640001" datatype="html">
+ <source>Error</source>
+ <target>錯誤</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5037437391296624618" datatype="html">
+ <source>Information</source>
+ <target>資訊</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">50</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4648900870671159218" datatype="html">
+ <source>Success</source>
+ <target>成功</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">55</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3425367071066107827" datatype="html">
+ <source>Danger</source>
+ <target>危險</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/alert-panel/alert-panel.component.ts</context>
+ <context context-type="linenumber">60</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6c947210e2d162b6225083d18820ab602f58cd2d" datatype="html">
+ <source>Remove the custom configuration value. The default configuration will be inherited and used instead.</source>
+ <target>移除自訂組態值。將繼承並使用預設組態。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="454ee9cb60b00446a8fb147fd2cc5eb836320586" datatype="html">
+ <source>The entered value is too high! It must not be greater than <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>.</source>
+ <target>輸入的值過大!值不得大於 <x id="INTERPOLATION" equiv-text="{{ option.maxValue }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7fc8a22825131e028336f60ef909ccbd96059703" datatype="html">
+ <source>The entered value is too low! It must not be lower than <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>.</source>
+ <target>輸入的值過小!值不得小於 <x id="INTERPOLATION" equiv-text="{{ option.minValue }}"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/config-option/config-option.component.html</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4dd200b7f9e19048cf90516843b40964f2af3fe9" datatype="html">
+ <source>Copy to Clipboard</source>
+ <target>複製到剪貼簿</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6110699a3562eeb15371063c0cf7f6bfd88a0209" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>?</source>
+ <target>您確定要<x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ itemNames[0] }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>嗎?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="549859e511ba5af0ea03fcaa620c472f08038969" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected items?</source>
+ <target>您確定要<x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/>選取的項目嗎?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="54839ebc827b73c9dc4e1df731c6d36a85036af7" datatype="html">
+ <source>Are you sure that you want to <x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/> the selected <x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/>?</source>
+ <target>您確定要<x id="INTERPOLATION" equiv-text="{{ actionDescription | lowercase }}"/>選取的<x id="INTERPOLATION_1" equiv-text="{{ itemDescription }}"/>嗎?</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2be8b7f04f0104d3fad90d079d8202b74f758b9a" datatype="html">
+ <source>Yes, I am sure.</source>
+ <target>是的,我確定。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html</context>
+ <context context-type="linenumber">39</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4523728183000855476" datatype="html">
+ <source>documentation</source>
+ <target>文件</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/doc/doc.component.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3099741642167775297" datatype="html">
+ <source>Download</source>
+ <target>下載</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/download-button/download-button.component.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1417693714872528491" datatype="html">
+ <source>This field is required.</source>
+ <target>此欄位為必填欄位。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5321335688371682440" datatype="html">
+ <source>An error occurred.</source>
+ <target>發生錯誤。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/form-modal/form-modal.component.ts</context>
+ <context context-type="linenumber">92</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c5109325fb160b543f71a51e7511c00575057431" datatype="html">
+ <source>Loading panel data...</source>
+ <target>正在載入面板資料...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="a21acde005f80ceadb1391be1e7ff8b6d18188a0" datatype="html">
+ <source>Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the monitoring functionality.</source>
+ <target>請參閱 <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> 以瞭解如何設定和啟用監控功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">7,8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6a0ed4bd7b7add2a6febf7adf58d8cde5e421418" datatype="html">
+ <source>Grafana Dashboard doesn't exist. Please refer to <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to add dashboards to Grafana.</source>
+ <target>Grafana 儀表板不存在。請參閱 <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;grafana&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> 以瞭解如何新增儀表板至 Grafana。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">12,13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4e11830040bd64804a0555de76f291d5832772d4" datatype="html">
+ <source>Grafana Time Picker</source>
+ <target>Grafana 時間選擇器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="238c1ba845dd7330e8088165275919a1debf1ca3" datatype="html">
+ <source>Reset Settings</source>
+ <target>重設設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.html</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7888499255176013171" datatype="html">
+ <source>Last 5 minutes</source>
+ <target>過去 5 分鐘</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6892361549797455305" datatype="html">
+ <source>Last 15 minutes</source>
+ <target>過去 15 分鐘</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">45</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2653641162607195423" datatype="html">
+ <source>Last 30 minutes</source>
+ <target>過去 30 分鐘</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">49</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4117793269024790392" datatype="html">
+ <source>Last 1 hour (Default)</source>
+ <target>過去 1 小時 (預設值)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2645733658763754077" datatype="html">
+ <source>Last 3 hours</source>
+ <target>過去 3 小時</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7360078715633936807" datatype="html">
+ <source>Last 6 hours</source>
+ <target>過去 6 小時</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">61</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5055313582241816303" datatype="html">
+ <source>Last 12 hours</source>
+ <target>過去 12 小時</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9186529157286281693" datatype="html">
+ <source>Last 24 hours</source>
+ <target>過去 24 小時</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4498682414491138092" datatype="html">
+ <source>Yesterday</source>
+ <target>昨天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">73</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="929003859318769922" datatype="html">
+ <source>Today so far</source>
+ <target>今天到目前為止</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5525943133564968818" datatype="html">
+ <source>Day before yesterday</source>
+ <target>前天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6168755117727892817" datatype="html">
+ <source>Last 2 days</source>
+ <target>過去 2 天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">85</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7574807704224200535" datatype="html">
+ <source>This day last week</source>
+ <target>上週的今天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4420128118950221234" datatype="html">
+ <source>Previous week</source>
+ <target>上週</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">93</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4063965603321223683" datatype="html">
+ <source>This week so far</source>
+ <target>本週目前為止</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">97</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4873149362496451858" datatype="html">
+ <source>Last 7 days</source>
+ <target>過去 7 天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8586908745456864217" datatype="html">
+ <source>Previous month</source>
+ <target>上個月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1647573304710886499" datatype="html">
+ <source>This month so far</source>
+ <target>本月目前為止</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">109</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2949150997160654358" datatype="html">
+ <source>Last 30 days</source>
+ <target>過去 30 天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">113</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7469939859049484736" datatype="html">
+ <source>Last 90 days</source>
+ <target>過去 90 天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">117</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3847501198811458781" datatype="html">
+ <source>Last 6 months</source>
+ <target>過去 6 個月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">121</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7447583558445881102" datatype="html">
+ <source>Last 1 year</source>
+ <target>過去 1 年</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">125</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="100513227838842152" datatype="html">
+ <source>Previous year</source>
+ <target>去年</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">129</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3650872673621947074" datatype="html">
+ <source>This year so far</source>
+ <target>今年目前為止</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1262816694819959075" datatype="html">
+ <source>Last 2 years</source>
+ <target>過去 2 年</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7878813844917362690" datatype="html">
+ <source>Last 5 years</source>
+ <target>過去 5 年</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/grafana/grafana.component.ts</context>
+ <context context-type="linenumber">141</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3fb5709e10166cbc85970cbff103db227dbeb813" datatype="html">
+ <source>Select a Language</source>
+ <target>選取語言</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/language-selector/language-selector.component.html</context>
+ <context context-type="linenumber">5</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7e52e9143145e1db5146258de81eae018a407b31" datatype="html">
+ <source>Clear notifications</source>
+ <target>清除通知</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">51</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b0b07bb6b7ff21ede439dd04eaf8872d1ecb84d8" datatype="html">
+ <source>Remove notification</source>
+ <target>移除通知</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e17a1d75189da843f541f7764f188f2b19a97df2" datatype="html">
+ <source>Duration:</source>
+ <target>持續時間:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">81</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="0d4b37c6675c5b436a54c43d6716eec835e1aa7f" datatype="html">
+ <source>There are no notifications.</source>
+ <target>沒有通知。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html</context>
+ <context context-type="linenumber">104</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="b20e42ac4354d449f2718428b5390933eef0c1b9" datatype="html">
+ <source>The feature is not supported in the current Orchestrator.</source>
+ <target>目前的 Orchestrator 不支援該功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">3</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1a437b8f93cf826817c04a4277edb1ae3a93a1ab" datatype="html">
+ <source>Orchestrator is not available. Please consult the <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> on how to configure and enable the functionality.</source>
+ <target>Orchestrator 不可用。請參閱 <x id="START_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;cd-doc section=&quot;orch&quot;&gt;"/><x id="CLOSE_TAG_CD_DOC" ctype="x-cd_doc" equiv-text="&lt;/cd-doc&gt;"/> 以瞭解如何設定和啟用該功能。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html</context>
+ <context context-type="linenumber">7,9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="20b3d45b0c08a2951a9974fa20505e4de95250c9" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>less than 1<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day. Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <target>您的密碼將在 <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>1 天內<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/>過期。請按一下<x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>此處<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>以立即變更。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">9,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c2f34088c155e40ffb23770a465a65868ce772b2" datatype="html">
+ <source>Your password will expire in <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> day(s). Click <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>here<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> to change it now.</source>
+ <target>您的密碼將在 <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="INTERPOLATION" equiv-text="{{ expirationDays }}"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> 天內過期。請按一下<x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/user-profile/edit&quot; class=&quot;alert-link&quot;&gt;"/>此處<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>以立即變更。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html</context>
+ <context context-type="linenumber">13,15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="c8d1785038d461ec66b5799db21864182b35900a" datatype="html">
+ <source>Refresh</source>
+ <target>重新整理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/refresh-selector/refresh-selector.component.html</context>
+ <context context-type="linenumber">7</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3417247046175131869" datatype="html">
+ <source>No items selected.</source>
+ <target>未選取項目。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1034353870189672674" datatype="html">
+ <source>Deselect item to select again</source>
+ <target>取消選取項目以再次選取</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4879298070255432995" datatype="html">
+ <source>Selection limit reached</source>
+ <target>已達到選取上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7001227209911602786" datatype="html">
+ <source>Filter tags</source>
+ <target>過濾標記</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="791789583719406586" datatype="html">
+ <source>Add badge</source>
+ <target>新增徽章</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="699988676752930063" datatype="html">
+ <source>There are no items available.</source>
+ <target>沒有可用的項目。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/select/select-messages.model.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e6702323d3760e3db0e2e785d567469d18beb120" datatype="html">
+ <source>The Ceph community needs your help to continue improving: please <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>Activate<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> the <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>Telemetry<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> module.</source>
+ <target>Ceph 需要您的幫助以持續改進:請<x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/telemetry&quot; class=&quot;btn activate-button alert-link activate-text&quot;&gt;"/>啟用<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/><x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://docs.ceph.com/en/latest/mgr/telemetry/&quot;&gt;"/>遙測<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>模組。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.html</context>
+ <context context-type="linenumber">8,11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8770134622386151776" datatype="html">
+ <source>Telemetry activation reminder muted</source>
+ <target>遙測啟用提醒功能已停用</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8352450862052130357" datatype="html">
+ <source>You can activate the module on the Telemetry configuration page (&lt;b&gt;Dashboard Settings&lt;/b&gt; -&gt; &lt;b&gt;Telemetry configuration&lt;/b&gt;) at any time.</source>
+ <target>您隨時可在 &quot;遙測組態&quot; 頁面 (&lt;b&gt;儀表板設定&lt;/b&gt; -&gt; &lt;b&gt;遙測組態&lt;/b&gt;) 中啟用該模組。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/telemetry-notification/telemetry-notification.component.ts</context>
+ <context context-type="linenumber">58,59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9bc9e5365a581105ce37cf47d1d74e4ad9eb75ce" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ step.stepIndex }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="e634c306cab9e8879c3392593714c1ceab85437d" datatype="html">
+ <source><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></source>
+ <target><x id="INTERPOLATION" equiv-text="{{ stepsTitle[i] }}"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/components/wizard/wizard.component.html</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3249513483374643425" datatype="html">
+ <source>Add</source>
+ <target>新增</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">132</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4359847060009771702" datatype="html">
+ <source>Set</source>
+ <target>設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">133</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="935187492052582731" datatype="html">
+ <source>Submit</source>
+ <target>提交</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">134</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4814285799071780083" datatype="html">
+ <source>Remove</source>
+ <target>移除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">137</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8363450564548681668" datatype="html">
+ <source>Unset</source>
+ <target>取消設定</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2159130950882492111" datatype="html">
+ <source>Cancel</source>
+ <target>取消</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">143</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1295614462098694869" datatype="html">
+ <source>Preview</source>
+ <target>預覽</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">144</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2354817630223808522" datatype="html">
+ <source>Move</source>
+ <target>移動</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3885497195825665706" datatype="html">
+ <source>Next</source>
+ <target>下一步</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">148</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8890553633144307762" datatype="html">
+ <source>Back</source>
+ <target>返回</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">149</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5834780181397311898" datatype="html">
+ <source>Clone</source>
+ <target>克隆</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">152</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4323470180912194028" datatype="html">
+ <source>Copy</source>
+ <target>複製</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">153</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2131301778880826094" datatype="html">
+ <source>Deep Scrub</source>
+ <target>深層整理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">154</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1704447209800801558" datatype="html">
+ <source>Destroy</source>
+ <target>損毀</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">155</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8343007008325027187" datatype="html">
+ <source>Evict</source>
+ <target>逐出</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="408179081163888126" datatype="html">
+ <source>Flatten</source>
+ <target>壓平</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">157</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="318900679147387932" datatype="html">
+ <source>Mark Down</source>
+ <target>標示為停機</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">158</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5275142643521766706" datatype="html">
+ <source>Mark In</source>
+ <target>標示為加入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">159</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6973272903386150199" datatype="html">
+ <source>Mark Lost</source>
+ <target>標示為遺失</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">160</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1962653792210847411" datatype="html">
+ <source>Mark Out</source>
+ <target>標示為除名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">161</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4424610588915076517" datatype="html">
+ <source>Protect</source>
+ <target>保護</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">162</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6041115344061899387" datatype="html">
+ <source>Rename</source>
+ <target>重新命名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">164</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6770769801335635194" datatype="html">
+ <source>Restore</source>
+ <target>還原</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">165</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2003230525878010676" datatype="html">
+ <source>Reweight</source>
+ <target>重新設定權數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">166</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5430834128563178593" datatype="html">
+ <source>Scrub</source>
+ <target>整理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">168</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8461842260159597706" datatype="html">
+ <source>Show</source>
+ <target>顯示</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">169</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5655608100705734230" datatype="html">
+ <source>Move to Trash</source>
+ <target>移至垃圾桶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">170</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4622393909937403117" datatype="html">
+ <source>Unprotect</source>
+ <target>取消保護</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">171</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1230154438678955604" datatype="html">
+ <source>Change</source>
+ <target>變更</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">172</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">262</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8450843381175865415" datatype="html">
+ <source>Enter Maintenance</source>
+ <target>進入維護模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">174</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1610181371597502589" datatype="html">
+ <source>Exit Maintenance</source>
+ <target>結束維護模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">175</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="676511611419004737" datatype="html">
+ <source>Start Drain</source>
+ <target>開始清空</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">176</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7170653322511987983" datatype="html">
+ <source>Stop Drain</source>
+ <target>停止清空</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">177</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5528551262937858942" datatype="html">
+ <source>Recreate</source>
+ <target>重新建立</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">180</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2502364444688691031" datatype="html">
+ <source>Expire</source>
+ <target>過期</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">181</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6381490568322624964" datatype="html">
+ <source>Deleted</source>
+ <target>已刪除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">228</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="231679111972850796" datatype="html">
+ <source>Added</source>
+ <target>已新增</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">231</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5406093358072761930" datatype="html">
+ <source>Removed</source>
+ <target>已移除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">234</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3008573030448240863" datatype="html">
+ <source>Edited</source>
+ <target>已編輯</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4381944803872489731" datatype="html">
+ <source>Canceled</source>
+ <target>已取消</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4754993936947658096" datatype="html">
+ <source>Previewed</source>
+ <target>已預覽</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6001163963116907226" datatype="html">
+ <source>Moved</source>
+ <target>已移動</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">240</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4932744777596632840" datatype="html">
+ <source>Cloned</source>
+ <target>已克隆</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">243</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2115592966120408375" datatype="html">
+ <source>Copied</source>
+ <target>已複製</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">244</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7937474560394832586" datatype="html">
+ <source>Deep Scrubbed</source>
+ <target>已深層整理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6321562733889197649" datatype="html">
+ <source>Destroyed</source>
+ <target>已損毀</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7460162290177581995" datatype="html">
+ <source>Flattened</source>
+ <target>已壓平</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">247</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3662010055028969035" datatype="html">
+ <source>Marked Down</source>
+ <target>已標示為停機</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5880434235404894589" datatype="html">
+ <source>Marked In</source>
+ <target>已標示為加入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">249</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="266997194072682078" datatype="html">
+ <source>Marked Lost</source>
+ <target>已標示為遺失</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">250</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4010544044592534535" datatype="html">
+ <source>Marked Out</source>
+ <target>已標示為除名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">251</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4776304093333411035" datatype="html">
+ <source>Protected</source>
+ <target>受保護</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2700903921419382511" datatype="html">
+ <source>Purged</source>
+ <target>已清除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5488667333459350160" datatype="html">
+ <source>Renamed</source>
+ <target>已重新命名</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">254</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8044659850000829751" datatype="html">
+ <source>Restored</source>
+ <target>已還原</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559472082694466366" datatype="html">
+ <source>Reweighted</source>
+ <target>已重新設定權數</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">256</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7022271525067453676" datatype="html">
+ <source>Rolled back</source>
+ <target>已復原</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">257</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">239</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2483217756816388123" datatype="html">
+ <source>Scrubbed</source>
+ <target>已整理</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">258</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7200036055090632378" datatype="html">
+ <source>Showed</source>
+ <target>已顯示</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7609648817347881129" datatype="html">
+ <source>Moved to Trash</source>
+ <target>已移至垃圾桶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7810326403606456469" datatype="html">
+ <source>Unprotected</source>
+ <target>已取消保護</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">261</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5620774899056099259" datatype="html">
+ <source>Recreated</source>
+ <target>已重新建立</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="464749780222721589" datatype="html">
+ <source>Expired</source>
+ <target>已過期</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/constants/app.constants.ts</context>
+ <context context-type="linenumber">266</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1e5e23363e949f7dcbaf034bdb141a561132a10e" datatype="html">
+ <source>Clear filters</source>
+ <target>清除過濾器</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="80cc9a12d4bf6fe454ed94b379eeaf915f920bb7" datatype="html">
+ <source>selected</source>
+ <target>選取的數目</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ <note priority="1" from="description">X selected</note>
+ </trans-unit>
+ <trans-unit id="0cb77511a9a148e05b9adf36cc07269956fbb29d" datatype="html">
+ <source>found</source>
+ <target>找到的數目</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <note priority="1" from="description">X found</note>
+ </trans-unit>
+ <trans-unit id="79347388740c50b7ac97e144c2494bb62912f312" datatype="html">
+ <source>total</source>
+ <target>總計</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">207</context>
+ </context-group>
+ <note priority="1" from="description">X total</note>
+ </trans-unit>
+ <trans-unit id="2a3dab422cc892db037db8632bb84a6bf496e2d1" datatype="html">
+ <source>Expand/Collapse Row</source>
+ <target>展開/摺疊列</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.html</context>
+ <context context-type="linenumber">309</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4047162422391207122" datatype="html">
+ <source>Failed to load data.</source>
+ <target>無法載入資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/datatable/table/table.component.ts</context>
+ <context context-type="linenumber">607</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="709331713250198508" datatype="html">
+ <source>Loading form data...</source>
+ <target>正在載入表單資料...</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">32</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3850344644863430180" datatype="html">
+ <source>Form data could not be loaded.</source>
+ <target>無法載入表單資料。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/directives/form-loading.directive.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4626760504772708998" datatype="html">
+ <source>Size has to be at least <x id="PH" equiv-text="value"/> or more</source>
+ <target>大小必須小於或等於 <x id="PH" equiv-text="value"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">428</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2880361802894657892" datatype="html">
+ <source>Size has to be at most <x id="PH" equiv-text="value"/> or less</source>
+ <target>大小必須小於或等於 <x id="PH" equiv-text="value"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/forms/cd-validators.ts</context>
+ <context context-type="linenumber">448</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2807800733729323332" datatype="html">
+ <source>Yes</source>
+ <target>是</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3542042671420335679" datatype="html">
+ <source>No</source>
+ <target>否</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/boolean-text.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7789266940050748913" datatype="html">
+ <source>in %s</source>
+ <target>%s內</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">8</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565573880632900017" datatype="html">
+ <source>%s ago</source>
+ <target>%s前</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">9</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="220300059326988179" datatype="html">
+ <source>a few seconds</source>
+ <target>幾秒</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">10</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2761143993878941513" datatype="html">
+ <source>%d seconds</source>
+ <target>%d 秒</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">11</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7094767962693903153" datatype="html">
+ <source>a minute</source>
+ <target>1 分鐘</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">12</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7597613755904774250" datatype="html">
+ <source>%d minutes</source>
+ <target>%d 分鐘</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">13</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2757762976030115752" datatype="html">
+ <source>an hour</source>
+ <target>1 小時</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">14</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9118454901758656303" datatype="html">
+ <source>%d hours</source>
+ <target>%d 小時</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">15</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7435193742089920080" datatype="html">
+ <source>a day</source>
+ <target>1 天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">16</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1821334622562842480" datatype="html">
+ <source>%d days</source>
+ <target>%d 天</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">17</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7375306199026780379" datatype="html">
+ <source>a week</source>
+ <target>1 週</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">18</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7272688256541915488" datatype="html">
+ <source>%d weeks</source>
+ <target>%d 週</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">19</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5761124614324704118" datatype="html">
+ <source>a month</source>
+ <target>1 個月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">20</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="352195662913351589" datatype="html">
+ <source>%d months</source>
+ <target>%d 個月</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">21</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7562153591649199139" datatype="html">
+ <source>a year</source>
+ <target>1 年</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5424759741855527370" datatype="html">
+ <source>%d years</source>
+ <target>%d 年</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/pipes/relative-date.pipe.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7738182956549158907" datatype="html">
+ <source>Required rules for passwords:</source>
+ <target>密碼必須遵循的規則:</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">22</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8839765875053270528" datatype="html">
+ <source>Must contain at least <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> characters</source>
+ <target>必須至少包含 <x id="PH" equiv-text="settings.pwdPolicyMinLength"/> 個字元</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">24</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3098731108593590794" datatype="html">
+ <source>Must not be the same as the previous one</source>
+ <target>不得與之前的密碼相同</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">25</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9150236741862848105" datatype="html">
+ <source>Cannot contain the username</source>
+ <target>不能包含使用者名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6395043854518867543" datatype="html">
+ <source>Cannot contain any configured keyword</source>
+ <target>不能包含任何設定的關鍵字</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">27</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="907558624910601703" datatype="html">
+ <source>Cannot contain any repetitive characters e.g. &quot;aaa&quot;</source>
+ <target>不能包含任何重複字元,例如 &quot;aaa&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1514384270734082343" datatype="html">
+ <source>Cannot contain any sequential characters e.g. &quot;abc&quot;</source>
+ <target>不能包含任何循序字元,例如 &quot;abc&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4119354814383293871" datatype="html">
+ <source>Must consist of characters from the following groups:
+ * Alphabetic a-z, A-Z
+ * Numbers 0-9
+ * Special chars: !&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * Any other characters (signs)</source>
+ <target>必須由以下類型的字元組成:
+ * 字母 a-z、A-Z
+ * 數字 0-9
+ * 特殊字元:!&quot;#$%&amp; '()*+,-./:;&lt;=&gt;?@[\]^_`{{|}}~
+ * 任何其他字元 (符號)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/password-policy.service.ts</context>
+ <context context-type="linenumber">30,34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8649061117624699581" datatype="html">
+ <source>Your matcher seems to match no currently defined rule or active alert.</source>
+ <target>您的比對器似乎與目前定義的任何規則或使用中警示均不相符。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7122912874364762704" datatype="html">
+ <source>no active alerts</source>
+ <target>沒有使用中警示</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7388215679576832341" datatype="html">
+ <source>1 active alert</source>
+ <target>1 則使用中警示</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3112400568960537267" datatype="html">
+ <source><x id="PH" equiv-text="alerts"/> active alerts</source>
+ <target><x id="PH" equiv-text="alerts"/> 則使用中警示</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6264717417287230743" datatype="html">
+ <source>Matches 1 rule</source>
+ <target>與 1 條規則相符</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8054663176394183966" datatype="html">
+ <source>Matches <x id="PH" equiv-text="rules"/> rules</source>
+ <target>與 <x id="PH" equiv-text="rules"/> 條規則相符</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6674225401121099210" datatype="html">
+ <source><x id="PH" equiv-text="rule"/> with <x id="PH_1" equiv-text="alert"/>.</source>
+ <target>具有 <x id="PH_1" equiv-text="alert"/> 的 <x id="PH" equiv-text="rule"/>。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/prometheus-silence-matcher.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5659908877047925719" datatype="html">
+ <source>Quality of Service</source>
+ <target>服務品質</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">23</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1277565045885499475" datatype="html">
+ <source>BPS Limit</source>
+ <target>BPS 上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">28</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2289210323987692906" datatype="html">
+ <source>The desired limit of IO bytes per second.</source>
+ <target>所需的每秒 IO 位元組數上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">29</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2753589939879013605" datatype="html">
+ <source>IOPS Limit</source>
+ <target>IOPS 上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">34</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2213985059444278522" datatype="html">
+ <source>The desired limit of IO operations per second.</source>
+ <target>所需的每秒 IO 操作次數上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">35</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2487530611825582289" datatype="html">
+ <source>Read BPS Limit</source>
+ <target>讀取 BPS 上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">40</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8071352270469595250" datatype="html">
+ <source>The desired limit of read bytes per second.</source>
+ <target>所需的每秒內讀取的位元組數上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">41</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1632513758247239690" datatype="html">
+ <source>Read IOPS Limit</source>
+ <target>讀取 IOPS 上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">46</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2361786794607418566" datatype="html">
+ <source>The desired limit of read operations per second.</source>
+ <target>所需的每秒讀取操作次數上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">47</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="894600353504285551" datatype="html">
+ <source>Write BPS Limit</source>
+ <target>寫入 BPS 上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">52</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5911437671369366025" datatype="html">
+ <source>The desired limit of write bytes per second.</source>
+ <target>所需的每秒內寫入的位元組數上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2947346368707443195" datatype="html">
+ <source>Write IOPS Limit</source>
+ <target>寫入 IOPS 上限</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">58</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5506349527983391356" datatype="html">
+ <source>The desired limit of write operations per second.</source>
+ <target>所需的每秒寫入操作次數上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">59</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4559424229658244943" datatype="html">
+ <source>BPS Burst</source>
+ <target>BPS 高載</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">64</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3454058701331860330" datatype="html">
+ <source>The desired burst limit of IO bytes.</source>
+ <target>所需的 IO 位元組數高載上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">65</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1171005761926448741" datatype="html">
+ <source>IOPS Burst</source>
+ <target>IOPS 高載</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4939532784700485729" datatype="html">
+ <source>The desired burst limit of IO operations.</source>
+ <target>所需的 IO 操作次數高載上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6273492199526646930" datatype="html">
+ <source>Read BPS Burst</source>
+ <target>讀取 BPS 高載</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">76</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3105467595643777520" datatype="html">
+ <source>The desired burst limit of read bytes.</source>
+ <target>所需的讀取的位元組數高載上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">77</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2170715106679765467" datatype="html">
+ <source>Read IOPS Burst</source>
+ <target>讀取 IOPS 高載</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6234106755510510672" datatype="html">
+ <source>The desired burst limit of read operations.</source>
+ <target>所需的讀取操作次數高載上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">83</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="228509518172572466" datatype="html">
+ <source>Write BPS Burst</source>
+ <target>寫入 BPS 高載</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">88</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7803279807796571240" datatype="html">
+ <source>The desired burst limit of write bytes.</source>
+ <target>所需的寫入的位元組數高載上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">89</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="9125474584914848055" datatype="html">
+ <source>Write IOPS Burst</source>
+ <target>寫入 IOPS 高載</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">94</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5839129348567326667" datatype="html">
+ <source>The desired burst limit of write operations.</source>
+ <target>所需的寫入操作次數高載上限。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/rbd-configuration.service.ts</context>
+ <context context-type="linenumber">95</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="614961883076556986" datatype="html">
+ <source>Failed to <x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></source>
+ <target>無法<x id="PH" equiv-text="this.operation.failure"/> <x id="PH_1" equiv-text="this.involves(metadata)"/></target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">26</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="489145301781720653" datatype="html">
+ <source>Executing</source>
+ <target>正在執行</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4238828029954346941" datatype="html">
+ <source>execute</source>
+ <target>執行</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7196604637389554584" datatype="html">
+ <source>Executed</source>
+ <target>已執行</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">53</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4418441687454700644" datatype="html">
+ <source>unknown task</source>
+ <target>未知任務</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">57</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8667665916832796867" datatype="html">
+ <source>Creating</source>
+ <target>正在建立</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6031236679730054907" datatype="html">
+ <source>create</source>
+ <target>建立</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">66</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5593033420216313122" datatype="html">
+ <source>Updating</source>
+ <target>正在更新</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6100869651653026893" datatype="html">
+ <source>update</source>
+ <target>更新</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">67</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3141301060598402455" datatype="html">
+ <source>Deleting</source>
+ <target>正在刪除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">68</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">259</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3420504288275541125" datatype="html">
+ <source>Adding</source>
+ <target>正在新增</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1059784693423848532" datatype="html">
+ <source>add</source>
+ <target>新增</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">69</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4594819887188505274" datatype="html">
+ <source>Removing</source>
+ <target>正在移除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2123171795960509943" datatype="html">
+ <source>remove</source>
+ <target>移除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">70</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1946427188770321847" datatype="html">
+ <source>Importing</source>
+ <target>正在輸入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8495827411619139669" datatype="html">
+ <source>import</source>
+ <target>輸入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6218459863491436562" datatype="html">
+ <source>Imported</source>
+ <target>已輸入</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">71</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6534993668932538712" datatype="html">
+ <source>RBD '<x id="PH" equiv-text="metadata.image_spec"/>'</source>
+ <target>RBD &quot;<x id="PH" equiv-text="metadata.image_spec"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">75</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">82</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">90</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">98</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8237287859948228705" datatype="html">
+ <source>RBD snapshot '<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>'</source>
+ <target>RBD 快照 &quot;<x id="PH" equiv-text="metadata.image_spec"/>@<x id="PH_1" equiv-text="metadata.snapshot_name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">101</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2328067975897167268" datatype="html">
+ <source>mirroring site name</source>
+ <target>鏡像站台名稱</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">105</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4433460322631470833" datatype="html">
+ <source>bootstrap token</source>
+ <target>開機記號</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">106</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7044591639782280183" datatype="html">
+ <source>mirror mode for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>池 &quot;<x id="PH" equiv-text="metadata.pool_name"/>&quot; 的鏡像模式</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">107</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7109746474198366468" datatype="html">
+ <source>mirror peer for pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>池 &quot;<x id="PH" equiv-text="metadata.pool_name"/>&quot; 的鏡像對等</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">108</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6201476020617351396" datatype="html">
+ <source>all dashboards</source>
+ <target>所有儀表板</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">112</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7268953097700363232" datatype="html">
+ <source>Identifying</source>
+ <target>正在識別</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4337678035264231187" datatype="html">
+ <source>identify</source>
+ <target>識別</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7257219307556106552" datatype="html">
+ <source>Identified</source>
+ <target>已識別</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">122</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6002370161381995023" datatype="html">
+ <source>device '<x id="PH" equiv-text="metadata.device"/>' on host '<x id="PH_1" equiv-text="metadata.hostname"/>'</source>
+ <target>主機 &quot;<x id="PH_1" equiv-text="metadata.hostname"/>&quot; 上的裝置 &quot;<x id="PH" equiv-text="metadata.device"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5580298273054260850" datatype="html">
+ <source>OSDs (DriveGroups: <x id="PH" equiv-text="metadata.tracking_id"/>)</source>
+ <target>OSD (DriveGroup:<x id="PH" equiv-text="metadata.tracking_id"/>)</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">128</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2182125722527364040" datatype="html">
+ <source>Name is already used by <x id="PH" equiv-text="this.pool(metadata)"/>.</source>
+ <target> <x id="PH" equiv-text="this.pool(metadata)"/> 已使用該名稱。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">138</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">145</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">156</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">167</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">178</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">182</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">196</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">204</context>
+ </context-group>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">216</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7892856315477304281" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> is busy.</source>
+ <target><x id="PH" equiv-text="this.rbd.default(metadata)"/> 正忙。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">188</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4690045751984117407" datatype="html">
+ <source><x id="PH" equiv-text="this.rbd.default(metadata)"/> contains snapshots.</source>
+ <target><x id="PH" equiv-text="this.rbd.default(metadata)"/> 包含快照。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">189</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="562148565853868662" datatype="html">
+ <source>Cloning</source>
+ <target>正在克隆</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1197352830433807469" datatype="html">
+ <source>clone</source>
+ <target>克隆</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">193</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1692004144561317867" datatype="html">
+ <source>Snapshot of <x id="PH" equiv-text="this.rbd.child(metadata)"/> must be protected.</source>
+ <target><x id="PH" equiv-text="this.rbd.child(metadata)"/> 的快照必須受到保護。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">197</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8531200838331320284" datatype="html">
+ <source>Copying</source>
+ <target>正在複製</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6862265996781523030" datatype="html">
+ <source>copy</source>
+ <target>複製</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">201</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3556912098733712857" datatype="html">
+ <source>Flattening</source>
+ <target>正在壓平</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2488773646187451754" datatype="html">
+ <source>flatten</source>
+ <target>壓平</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">208</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="704305783678486635" datatype="html">
+ <source>Cannot unprotect <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> because it contains child images.</source>
+ <target>無法將 <x id="PH" equiv-text="this.rbd.snapshot( metadata )"/> 取消保護,因為它包含子影像。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">223,225</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7101271773452792348" datatype="html">
+ <source>Cannot delete <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/> because it's protected.</source>
+ <target>無法刪除 <x id="PH" equiv-text="this.rbd.snapshot(metadata)"/>,因為它受到保護。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">232</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5143010940199748580" datatype="html">
+ <source>Rolling back</source>
+ <target>正在復原</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">237</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1315686250907089544" datatype="html">
+ <source>rollback</source>
+ <target>復原</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">238</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5010267418211867946" datatype="html">
+ <source>Moving</source>
+ <target>正在移動</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="4366763205960752449" datatype="html">
+ <source>move</source>
+ <target>移動</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">245</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="695867152524584829" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_spec"/>' to trash</source>
+ <target>影像 &quot;<x id="PH" equiv-text="metadata.image_spec"/>&quot; 移至垃圾桶</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">246</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5423442774536615202" datatype="html">
+ <source>Could not find image.</source>
+ <target>找不到影像。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">248</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2622324641113512527" datatype="html">
+ <source>Restoring</source>
+ <target>正在回存</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="3347932678307141902" datatype="html">
+ <source>restore</source>
+ <target>回存</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">252</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7488038030362249932" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>' into '<x id="PH_1" equiv-text="metadata.new_image_name"/>'</source>
+ <target>影像 &quot;<x id="PH" equiv-text="metadata.image_id_spec"/>&quot; 移至 &quot;<x id="PH_1" equiv-text="metadata.new_image_name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">253</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8565688512490959949" datatype="html">
+ <source>Image name '<x id="PH" equiv-text="metadata.new_image_name"/>' is already in use.</source>
+ <target>影像名稱 &quot;<x id="PH" equiv-text="metadata.new_image_name"/>&quot; 已被使用。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">255</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6331051389974655106" datatype="html">
+ <source>image '<x id="PH" equiv-text="metadata.image_id_spec"/>'</source>
+ <target>影像 &quot;<x id="PH" equiv-text="metadata.image_id_spec"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">260</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8245559899946787147" datatype="html">
+ <source>Purging</source>
+ <target>正在清除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7879437654311684252" datatype="html">
+ <source>purge</source>
+ <target>清除</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">263</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="1440427157062670480" datatype="html">
+ <source>all pools</source>
+ <target>所有池</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">265</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8677740163708263843" datatype="html">
+ <source>images from <x id="PH" equiv-text="message"/></source>
+ <target><x id="PH" equiv-text="message"/> 中的影像</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">269</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8011237345035114219" datatype="html">
+ <source>Cannot disable mirroring because it contains a peer.</source>
+ <target>無法停用鏡像,因為其包含對等。</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">292</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="7391584598242145869" datatype="html">
+ <source>host '<x id="PH" equiv-text="metadata.hostname"/>'</source>
+ <target>主機 &quot;<x id="PH" equiv-text="metadata.hostname"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">354</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="6964302691596180722" datatype="html">
+ <source>OSD '<x id="PH" equiv-text="metadata.svc_id"/>'</source>
+ <target>OSD &quot;<x id="PH" equiv-text="metadata.svc_id"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">358</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="488305686602466689" datatype="html">
+ <source>pool '<x id="PH" equiv-text="metadata.pool_name"/>'</source>
+ <target>池 &quot;<x id="PH" equiv-text="metadata.pool_name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">362</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5921392748828575278" datatype="html">
+ <source>erasure code profile '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <target>糾刪碼設定檔 &quot;<x id="PH" equiv-text="metadata.name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">366</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2423915105798557698" datatype="html">
+ <source>crush rule '<x id="PH" equiv-text="metadata.name"/>'</source>
+ <target>Crush 規則 &quot;<x id="PH" equiv-text="metadata.name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">370</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="8273044996643438592" datatype="html">
+ <source>target '<x id="PH" equiv-text="metadata.target_iqn"/>'</source>
+ <target>目標 &quot;<x id="PH" equiv-text="metadata.target_iqn"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">374</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="5474643443735437364" datatype="html">
+ <source>NFS '<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>'</source>
+ <target>NFS &quot;<x id="PH" equiv-text="metadata.cluster_id"/>:<x id="PH_1" equiv-text="metadata.export_id ? metadata.export_id : metadata.path"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">378,380</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="2235495382025026939" datatype="html">
+ <source>Service '<x id="PH" equiv-text="metadata.service_name"/>'</source>
+ <target>服務 &quot;<x id="PH" equiv-text="metadata.service_name"/>&quot;</target>
+ <context-group purpose="location">
+ <context context-type="sourcefile">src/app/shared/services/task-message.service.ts</context>
+ <context context-type="linenumber">384</context>
+ </context-group>
+ </trans-unit>
+ </body>
+ </file>
+</xliff> \ No newline at end of file
diff --git a/src/pybind/mgr/dashboard/frontend/src/main.ts b/src/pybind/mgr/dashboard/frontend/src/main.ts
new file mode 100644
index 000000000..f399daf9b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/main.ts
@@ -0,0 +1,23 @@
+import { ApplicationRef, enableProdMode, isDevMode } from '@angular/core';
+import { enableDebugTools } from '@angular/platform-browser';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+
+import { AppModule } from './app/app.module';
+import { environment } from './environments/environment';
+
+if (environment.production) {
+ enableProdMode();
+}
+
+platformBrowserDynamic()
+ .bootstrapModule(AppModule)
+ .then((moduleRef) => {
+ if (isDevMode()) {
+ // source: https://medium.com/@dmitrymogilko/profiling-angular-change-detection-c00605862b9f
+ const applicationRef = moduleRef.injector.get(ApplicationRef);
+ const componentRef = applicationRef.components[0];
+ // allows to run `ng.profiler.timeChangeDetection();`
+ enableDebugTools(componentRef);
+ }
+ })
+ .catch((err) => console.log(err));
diff --git a/src/pybind/mgr/dashboard/frontend/src/polyfills.ts b/src/pybind/mgr/dashboard/frontend/src/polyfills.ts
new file mode 100644
index 000000000..3368646d3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/polyfills.ts
@@ -0,0 +1,54 @@
+/***************************************************************************************************
+ * Load `$localize` onto the global scope - used if i18n tags appear in Angular templates.
+ */
+import '@angular/localize/init';
+/**
+ * This file includes polyfills needed by Angular and is loaded before the app.
+ * You can add your own extra polyfills to this file.
+ *
+ * This file is divided into 2 sections:
+ * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
+ * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
+ * file.
+ *
+ * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
+ * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
+ * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
+ *
+ * Learn more in https://angular.io/guide/browser-support
+ */
+
+/***************************************************************************************************
+ * BROWSER POLYFILLS
+ */
+
+/** IE10 and IE11 requires the following for NgClass support on SVG elements */
+// import 'classlist.js'; // Run `npm install --save classlist.js`.
+
+/** IE10 and IE11 requires the following for the Reflect API. */
+// import 'core-js/es6/reflect';
+
+/**
+ * Required to support Web Animations `@angular/platform-browser/animations`.
+ * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
+ **/
+// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
+
+/***************************************************************************************************
+ * Zone JS is required by Angular itself.
+ */
+import 'zone.js/dist/zone'; // Included with Angular CLI.
+
+/***************************************************************************************************
+ * APPLICATION IMPORTS
+ */
+
+/**
+ * Date, currency, decimal and percent pipes.
+ * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10
+ */
+// import 'intl'; // Run `npm install --save intl`.
+/**
+ * Need to import at least one locale-data with intl.
+ */
+// import 'intl/locale-data/jsonp/en';
diff --git a/src/pybind/mgr/dashboard/frontend/src/setupJest.ts b/src/pybind/mgr/dashboard/frontend/src/setupJest.ts
new file mode 100644
index 000000000..3f7654357
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/setupJest.ts
@@ -0,0 +1,11 @@
+import '@angular/localize/init';
+
+import 'jest-preset-angular';
+
+import './jestGlobalMocks';
+
+process.on('unhandledRejection', (error) => {
+ const stack = error['stack'] || '';
+ // Avoid potential hang on test failure when running tests in parallel.
+ throw `WARNING: unhandled rejection: ${error} ${stack}`;
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles.scss b/src/pybind/mgr/dashboard/frontend/src/styles.scss
new file mode 100644
index 000000000..099433d31
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles.scss
@@ -0,0 +1,138 @@
+/* You can add global styles to this file, and also import other style files */
+@use './src/styles/defaults' as *;
+
+// Angular2-Tree Component
+@import '~@circlon/angular-tree-component/css/angular-tree-component.css';
+
+// Fork-Awesome
+$fa-font-path: '~fork-awesome/fonts';
+$font-family-icon: 'ForkAwesome';
+
+$badge-font-size: 1rem;
+$form-feedback-font-size: 100%;
+$popover-max-width: 350px;
+$popover-font-size: 1rem;
+
+// https://getbootstrap.com/docs/4.5/layout/grid/#variables
+$grid-breakpoints: (
+ xs: 0,
+ sm: 576px,
+ md: 768px,
+ lg: 992px,
+ xl: 1200px,
+ 2xl: 1450px
+);
+
+@import '~bootstrap/scss/bootstrap';
+@import '~fork-awesome/scss/fork-awesome';
+@import 'app/ceph/dashboard/info-card/info-card-popover.scss';
+@import './src/styles/bootstrap-extends';
+
+@import './src/styles/ceph-custom/basics';
+@import './src/styles/ceph-custom/buttons';
+@import './src/styles/ceph-custom/dropdown';
+@import './src/styles/ceph-custom/forms';
+@import './src/styles/ceph-custom/grid';
+@import './src/styles/ceph-custom/icons';
+@import './src/styles/ceph-custom/navs';
+@import './src/styles/ceph-custom/toast';
+
+/* If javascript is disabled. */
+.noscript {
+ padding-top: 5em;
+}
+
+// TODO: Replace (cd-)col-form-label with something more generic.
+@include media-breakpoint-up(sm) {
+ .col-form-label {
+ text-align: right;
+ }
+}
+
+.col-form-label {
+ font-weight: 700;
+}
+
+//Displaying the password strength
+.password-strength-level {
+ flex: 100%;
+ margin-top: 2px;
+
+ .weak,
+ .ok,
+ .strong,
+ .very-strong {
+ border-radius: 0.25rem;
+ height: 13px;
+ }
+
+ .weak {
+ background: $danger;
+ width: 25%;
+ }
+
+ .ok {
+ background: $warning;
+ width: 50%;
+ }
+
+ .strong {
+ background: $success;
+ width: 75%;
+ }
+
+ .very-strong {
+ background: darken($success, 15%);
+ width: 100%;
+ }
+}
+
+// Custom badges.
+.badge-background-gray,
+.badge-hdd {
+ background-color: $gray-600;
+ color: $white;
+}
+
+.badge-background-primary,
+.badge-ssd {
+ background-color: $primary;
+ color: $white;
+}
+
+.badge-tab {
+ background-color: $gray-200;
+ color: $gray-700;
+}
+
+// angular-tree-component
+tree-root {
+ tree-viewport {
+ // Fix visual bug when tree is empty
+ min-height: 1em;
+ }
+}
+
+// Other
+tags-input .tags {
+ border: 1px solid $gray-400;
+ border-radius: 4px;
+ box-shadow: inset 0 1px 1px rgba($black, 0.09);
+}
+
+.card-header {
+ font-size: 1.3em;
+}
+
+.card-body h2:first-child {
+ margin-top: 0;
+}
+
+.disabled {
+ pointer-events: none;
+}
+
+.clickable,
+a {
+ cursor: pointer;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/_chart-tooltip.scss b/src/pybind/mgr/dashboard/frontend/src/styles/_chart-tooltip.scss
new file mode 100644
index 000000000..29e1f1cc6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/_chart-tooltip.scss
@@ -0,0 +1,59 @@
+@use './src/styles/vendor/variables' as vv;
+
+.chart-container {
+ cursor: pointer;
+ margin: auto;
+ overflow: visible;
+ position: absolute;
+}
+
+canvas {
+ user-select: none;
+}
+
+.chartjs-tooltip {
+ background: rgba(vv.$black, 0.7);
+ border-radius: 3px;
+ color: vv.$white;
+ font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif !important;
+ opacity: 0;
+ pointer-events: none;
+ position: absolute;
+
+ transform: translate(-50%, 0);
+ transition: all 0.1s ease;
+
+ &.transform-left {
+ transform: translate(-10%, 0);
+
+ &::after {
+ left: 10%;
+ }
+ }
+
+ &.transform-right {
+ transform: translate(-90%, 0);
+
+ &::after {
+ left: 90%;
+ }
+ }
+}
+
+.chartjs-tooltip::after {
+ border-color: vv.$black transparent transparent transparent;
+ border-style: solid;
+ border-width: 5px;
+ content: ' ';
+ left: 50%;
+ margin-left: -5px;
+ position: absolute;
+ top: 100%; /* At the bottom of the tooltip */
+}
+
+::ng-deep .chartjs-tooltip-key {
+ display: inline-block;
+ height: 10px;
+ margin-right: 10px;
+ width: 10px;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/bootstrap-extends.scss b/src/pybind/mgr/dashboard/frontend/src/styles/bootstrap-extends.scss
new file mode 100644
index 000000000..be304c9e4
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/bootstrap-extends.scss
@@ -0,0 +1,129 @@
+/*
+ * Include here all styles from components that extend from bootstrap.
+ * This removes the need to @import bootstrap into those component,
+ * thus reducing the final css size.
+*/
+
+cd-info-card {
+ .card {
+ @extend .pb-2;
+
+ .card-body {
+ .card-title {
+ @extend .pl-2;
+ }
+
+ .card-text {
+ @extend .pt-2;
+ }
+ }
+ }
+}
+
+.btn-toolbar cd-table-actions.btn-group {
+ @extend .mr-2;
+}
+
+cd-table {
+ .cd-datatable {
+ .datatable-footer {
+ @extend .p-2;
+
+ .datatable-pager {
+ ul {
+ @extend .pagination;
+
+ li {
+ @extend .page-item;
+
+ a {
+ @extend .page-link;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+cd-health {
+ cd-info-card {
+ @extend .d-flex;
+ @extend .flex-column;
+ @extend .mb-4;
+
+ @extend .col-12;
+ @extend .col-sm-12;
+ @extend .col-md-6;
+ @extend .col-lg-4;
+
+ &.cd-status-card {
+ @extend .col-xl-3;
+ }
+
+ &.cd-performance-card,
+ &.cd-capacity-card {
+ @extend .col-xl;
+ }
+
+ &.cd-capacity-card {
+ @extend .col-lg-3;
+ }
+
+ &.cd-performance-card {
+ @extend .col-lg-6;
+ }
+
+ &.cd-chart-card {
+ @extend .col-md-12;
+ @extend .col-lg-6;
+ @extend .col-xl-4;
+ @extend .col-2xl-3;
+ }
+ }
+}
+
+cd-logs {
+ label {
+ @extend .mr-2;
+ }
+
+ .form-inline > .form-group {
+ @extend .mr-3;
+ @extend .mb-3;
+ }
+}
+
+cd-about {
+ dl {
+ @extend .row;
+ }
+
+ dt {
+ @extend .col-4;
+ @extend .font-weight-bold;
+ }
+
+ dd {
+ @extend .col-8;
+ }
+}
+
+.cd-header,
+legend {
+ @extend .pb-1;
+ @extend .mt-4;
+ @extend .mb-4;
+ @extend .border-bottom;
+}
+
+// All '.fa' icons will have fixed width
+.fa {
+ @extend .fa-fw;
+}
+
+pre:not(cd-api-docs *) {
+ @extend .card;
+ @extend .bg-light;
+ @extend .p-2;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_basics.scss b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_basics.scss
new file mode 100644
index 000000000..3ead6efa5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_basics.scss
@@ -0,0 +1,131 @@
+@use './src/styles/vendor/variables' as vv;
+
+/* Basics */
+html {
+ background-color: vv.$body-bg;
+}
+
+html,
+body {
+ font-size: 12px;
+ height: 100%;
+ width: 100%;
+}
+
+option {
+ font-style: normal;
+ font-weight: normal;
+}
+
+mark {
+ background-color: vv.$yellow;
+ padding: 0;
+}
+
+.full-height {
+ height: 100vh;
+}
+
+.full-width {
+ width: 100vw;
+}
+
+.vertical-align {
+ align-items: center;
+ display: flex;
+}
+
+.horizontal-align {
+ display: flex;
+ justify-content: center;
+}
+
+.loading:not(cd-api-docs *) {
+ left: 50%;
+ position: absolute;
+ top: 50%;
+}
+
+.margin-right-md {
+ margin-right: 15px;
+}
+
+.no-border {
+ border: 0;
+ box-shadow: 0 0 0 !important;
+}
+
+.italic {
+ font-style: italic;
+}
+
+.bold {
+ font-weight: bold;
+}
+
+.text-right {
+ text-align: right;
+}
+
+.text-monospace {
+ font-family: monospace;
+}
+
+.text-pre-wrap {
+ white-space: pre-wrap;
+}
+
+.text-pre {
+ white-space: pre;
+}
+
+.border-danger {
+ border-left: 4px solid vv.$danger;
+}
+
+.border-info {
+ border-left: 4px solid vv.$info;
+}
+
+.border-success {
+ border-left: 4px solid vv.$success;
+}
+
+.vertical-line {
+ border-left: 1px solid vv.$gray-400;
+}
+
+.accordion {
+ .card {
+ border: 0;
+ }
+
+ .card-header {
+ border: 0;
+ border-bottom: 3px solid vv.$white;
+ padding-left: 0;
+
+ .btn:focus,
+ .btn.focus {
+ box-shadow: none;
+ }
+
+ button.dropdown-toggle {
+ position: relative;
+
+ &::after {
+ border: 0;
+ content: '\f054';
+ font-family: 'ForkAwesome';
+ font-size: 1rem;
+ position: absolute;
+ right: 20px;
+ transition: transform 0.3s ease-in-out;
+ }
+
+ &[aria-expanded='true']::after {
+ transform: rotate(90deg);
+ }
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_buttons.scss b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_buttons.scss
new file mode 100644
index 000000000..a56bf3506
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_buttons.scss
@@ -0,0 +1,80 @@
+@use './src/styles/vendor/variables' as vv;
+
+/* Reset checkbox success color */
+.was-validated .custom-control-input:valid,
+.custom-control-input.is-valid {
+ ~ .custom-control-label {
+ color: initial;
+ }
+
+ &:checked ~ .custom-control-label::before {
+ background-color: $component-active-bg;
+ border-color: $custom-control-indicator-checked-border-color;
+ }
+
+ ~ .custom-control-label::before {
+ border-color: $custom-control-indicator-border-color;
+ }
+
+ &:focus ~ .custom-control-label::before {
+ box-shadow: $custom-control-indicator-focus-box-shadow;
+ }
+
+ &:focus:not(:checked) ~ .custom-control-label::before {
+ border-color: $custom-control-indicator-focus-border-color;
+ }
+}
+
+/* Buttons */
+.btn-light {
+ background-color: vv.$white;
+ border-color: vv.$gray-400 !important;
+
+ &:hover {
+ background-color: vv.$gray-300;
+ border-color: vv.$gray-600 !important;
+ }
+
+ &:disabled {
+ background-color: vv.$gray-200;
+ border-color: vv.$gray-400 !important;
+ }
+}
+
+// We have some inputs that don't have a corresponding formControlName,
+// to be able to get the same styling and no JS errors we need use a different
+// class name
+.cd-form-control {
+ @extend .form-control;
+}
+
+.btn {
+ &,
+ &:active,
+ &.active {
+ &:focus,
+ &.focus {
+ outline: 0;
+ }
+ }
+
+ &.disabled {
+ border: 0;
+ box-shadow: none;
+ }
+}
+
+.btn-primary .badge {
+ background-color: vv.$gray-200;
+ color: vv.$primary;
+}
+
+.btn-group > .btn > i.fa,
+.cd-datatable-actions button.btn i.fa {
+ /** Add space between icon and text */
+ margin-right: 5px;
+}
+
+.card-footer button.btn:not(:first-child) {
+ margin-left: 5px;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_dropdown.scss b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_dropdown.scss
new file mode 100644
index 000000000..ee0704211
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_dropdown.scss
@@ -0,0 +1,35 @@
+@use './src/styles/vendor/variables' as vv;
+
+/* Dropdown */
+.dropdown-menu {
+ min-width: 50px;
+ z-index: 999999;
+
+ button.dropdown-item:focus {
+ outline: none;
+ }
+}
+
+.dropdown-menu > li > a {
+ cursor: pointer;
+}
+
+.dropdown-menu > li > a > i.fa {
+ /** Add space between icon and text */
+ margin-right: 5px;
+}
+
+.dropdown-menu > .active > a {
+ background-color: vv.$primary;
+ color: vv.$gray-200;
+
+ &,
+ &:hover,
+ &:focus {
+ background-color: darken(vv.$primary, 10);
+ }
+}
+
+.dataTables_wrapper .dropdown-menu > li.dropdown-divider {
+ cursor: auto;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_forms.scss b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_forms.scss
new file mode 100644
index 000000000..1d84895c0
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_forms.scss
@@ -0,0 +1,86 @@
+@use '../vendor/variables' as vv;
+
+/* Forms */
+.required::after {
+ color: vv.$danger;
+ content: '*';
+ font-size: 1.167rem;
+ padding-left: 4px;
+}
+
+.form-footer {
+ display: flex;
+ width: 100%;
+}
+
+.form-control {
+ display: table-cell;
+
+ &:focus {
+ border-color: rgba(vv.$primary, 0.8);
+ box-shadow: 0 0 3px 2px rgba(vv.$primary, 0.5);
+ outline: 0;
+ }
+}
+
+.custom-checkbox {
+ padding-top: 7px;
+}
+
+.custom-radio {
+ padding-top: 5px;
+}
+
+.cd-col-form {
+ @extend .col-12;
+ @extend .col-lg-8;
+ @extend .col-xl-6;
+}
+
+.cd-col-form-label {
+ @extend .col-form-label;
+ @extend .col-sm-4;
+ @extend .col-md-4;
+ @extend .col-lg-3;
+}
+
+.cd-col-form-input {
+ @extend .col-sm-8;
+ @extend .col-md-8;
+ @extend .col-lg-9;
+}
+
+.cd-col-form-offset {
+ @extend .offset-sm-4;
+ @extend .offset-lg-3;
+ @extend .cd-col-form-input;
+}
+
+cd-modal {
+ .modal {
+ /* stylelint-disable */
+ background-color: rgba(0, 0, 0, 0.4);
+ /* stylelint-enable */
+ display: block;
+ }
+
+ .modal-dialog {
+ max-width: 70vh;
+ }
+
+ .cd-col-form-label {
+ @extend .col-lg-4;
+ }
+
+ .cd-col-form-input {
+ @extend .col-lg-8;
+ }
+
+ .cd-col-form-offset {
+ @extend .offset-lg-4;
+ }
+}
+
+.invalid-feedback {
+ display: block;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_grid.scss b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_grid.scss
new file mode 100644
index 000000000..e4074c92c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_grid.scss
@@ -0,0 +1,6 @@
+@use '../vendor/variables' as vv;
+
+/* Grid */
+.container-fluid {
+ padding: 0 vv.$grid-gutter-width;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_icons.scss b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_icons.scss
new file mode 100644
index 000000000..282dd135c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_icons.scss
@@ -0,0 +1,16 @@
+/* Icons */
+.ceph-icon {
+ background: url('../../assets/Ceph_Logo.svg');
+}
+
+.prometheus-icon {
+ background: url('../../assets/prometheus_logo.svg');
+}
+
+.custom-icon {
+ background-clip: padding-box;
+ background-repeat: no-repeat;
+ background-size: contain;
+ margin-right: 8px;
+ padding: 10px;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_index.scss b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_index.scss
new file mode 100644
index 000000000..ec9c5b28b
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_index.scss
@@ -0,0 +1,5 @@
+@forward 'basics';
+@forward 'buttons';
+@forward 'dropdown';
+@forward 'forms';
+@forward 'icons';
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_navs.scss b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_navs.scss
new file mode 100644
index 000000000..2bad31f40
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_navs.scss
@@ -0,0 +1,5 @@
+@use '../vendor/variables' as vv;
+
+.nav-tabs {
+ margin-bottom: vv.$nav-tabs-margin-bottom;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_toast.scss b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_toast.scss
new file mode 100644
index 000000000..ac2487cbb
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_toast.scss
@@ -0,0 +1,30 @@
+@use './src/styles/vendor/variables' as vv;
+
+#toast-container {
+ margin-top: 2vw;
+
+ @media (max-width: 1600px) {
+ margin-top: 2.5vw;
+ }
+
+ @media (max-width: vv.$screen-md-max) {
+ margin-top: 9vw;
+ }
+
+ @media (max-width: 900px) {
+ margin-top: 10vw;
+ }
+
+ @media (max-width: 319px) {
+ margin-top: 11vw;
+ }
+
+ @media (max-width: 260px) {
+ margin-top: 14vw;
+ }
+}
+
+.toast-message > ul {
+ margin: 0;
+ padding-left: 1rem;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/defaults/_bootstrap-defaults.scss b/src/pybind/mgr/dashboard/frontend/src/styles/defaults/_bootstrap-defaults.scss
new file mode 100644
index 000000000..d4a3d5f86
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/defaults/_bootstrap-defaults.scss
@@ -0,0 +1,111 @@
+// Color system
+
+$white: #fff !default;
+$gray-100: #f8f9fa !default;
+$gray-200: #e9ecef !default;
+$gray-300: #dee2e6 !default;
+$gray-400: #ced4da !default;
+$gray-500: #adb5bd !default;
+$gray-600: #6c757d !default;
+$gray-700: #495057 !default;
+$gray-800: #343a40 !default;
+$gray-900: #212529 !default;
+$black: #000 !default;
+
+$blue: #007bff !default;
+$indigo: #6610f2 !default;
+$purple: #6f42c1 !default;
+$pink: #a94442 !default;
+$red: #ef5c55 !default;
+$orange: #fd7e14 !default;
+$yellow: #ffc200 !default;
+$green: #0b0 !default;
+$teal: #20c997 !default;
+$cyan: #17a2b8 !default;
+$barley-white: #fcecba !default;
+
+$primary: #2b99a8 !default;
+$secondary: #374249 !default;
+$success: $green !default;
+$info: $primary !default;
+$warning: $yellow !default;
+$danger: $red !default;
+$light: $gray-100 !default;
+$dark: #777 !default;
+
+// Extra theme colors.
+$accent: $red !default;
+$warning-dark: $orange !default;
+
+$fg-color-over-dark-bg: $white !default;
+$fg-hover-color-over-dark-bg: $gray-500 !default;
+
+$theme-colors: (
+ 'accent': $accent,
+ 'warning-dark': $warning-dark
+) !default;
+
+// Body
+$body-color-bright: $light !default;
+$body-bg: $white !default;
+$body-color: $gray-900 !default;
+$body-bg-alt: $gray-200 !default;
+
+// Health colors.
+$health-color-error: #f00 !default;
+$health-color-healthy: $green !default;
+$health-color-warning: #ffa500 !default;
+
+// Chart colors.
+$chart-color-red: #c9190b !default;
+$chart-color-blue: #06c !default;
+$chart-color-orange: #ef9234 !default;
+$chart-color-yellow: #f6d173 !default;
+$chart-color-green: #7cc674 !default;
+$chart-color-gray: #ededed !default;
+$chart-color-cyan: #73c5c5 !default;
+$chart-color-purple: #3c3d99 !default;
+$chart-color-center-text: #151515 !default;
+$chart-color-center-text-description: #72767b !default;
+$chart-color-tooltip-background: $black !default;
+$chart-danger: #c9190b !default;
+
+// Typography
+
+$font-family-sans-serif: 'Helvetica Neue', Helvetica, Arial, 'Noto Sans', sans-serif,
+ 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji' !default;
+
+// Card
+
+$card-cap-bg: $gray-100 !default;
+
+// Grid
+
+$grid-gutter-width: 30px !default;
+
+// Table
+
+$datatable-divider-color: rgba($black, 0.09) !default;
+
+// Navs
+
+$nav-tabs-margin-bottom: 1rem !default;
+
+// Tooltips
+
+$tooltip-color: $white !default;
+$tooltip-bg: $body-color !default;
+
+// Misc
+
+$screen-sm-min: 576px !default;
+$screen-md-min: 768px !default;
+$screen-lg-min: 992px !default;
+$screen-xl-min: 1200px !default;
+
+$screen-xs-max: calc(#{$screen-sm-min} - 1px) !default;
+$screen-sm-max: calc(#{$screen-md-min} - 1px) !default;
+$screen-md-max: calc(#{$screen-lg-min} - 1px) !default;
+$screen-lg-max: calc(#{$screen-xl-min} - 1px) !default;
+
+$navbar-height: 43px !default;
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/defaults/_functions.scss b/src/pybind/mgr/dashboard/frontend/src/styles/defaults/_functions.scss
new file mode 100644
index 000000000..806882b7f
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/defaults/_functions.scss
@@ -0,0 +1,5 @@
+@use 'sass:math';
+
+@function strip-unit($value) {
+ @return math.div($value, $value * 0 + 1);
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/defaults/_index.scss b/src/pybind/mgr/dashboard/frontend/src/styles/defaults/_index.scss
new file mode 100644
index 000000000..ef08983f7
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/defaults/_index.scss
@@ -0,0 +1,4 @@
+@forward '../vendor';
+
+@forward 'functions';
+@forward 'mixins';
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/defaults/_mixins.scss b/src/pybind/mgr/dashboard/frontend/src/styles/defaults/_mixins.scss
new file mode 100644
index 000000000..87c070731
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/defaults/_mixins.scss
@@ -0,0 +1,34 @@
+@use '../vendor/variables' as vv;
+@use 'functions';
+
+@mixin table-cell {
+ border: 0;
+ border-bottom: 1px solid vv.$gray-400;
+ border-left: 1px solid vv.$gray-400;
+ padding: 5px;
+}
+
+@mixin hf {
+ background-color: vv.$gray-200;
+ border-bottom: 1px solid vv.$gray-400;
+}
+
+@mixin fluid-font-size($min-vw, $max-vw, $min-font-size, $max-font-size) {
+ $u1: unit($min-vw);
+ $u2: unit($max-vw);
+ $u3: unit($min-font-size);
+ $u4: unit($max-font-size);
+
+ @if $u1 == $u2 and $u1 == $u3 and $u1 == $u4 {
+ font-size: $min-font-size;
+ @media screen and (min-width: $min-vw) {
+ font-size: calc(
+ #{$min-font-size} + #{functions.strip-unit($max-font-size - $min-font-size)} *
+ ((100vw - #{$min-vw}) / #{functions.strip-unit($max-vw - $min-vw)})
+ );
+ }
+ @media screen and (min-width: $max-vw) {
+ font-size: $max-font-size;
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/vendor/_index.scss b/src/pybind/mgr/dashboard/frontend/src/styles/vendor/_index.scss
new file mode 100644
index 000000000..fb6d03c9e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/vendor/_index.scss
@@ -0,0 +1,22 @@
+@forward 'style-overrides';
+@forward 'variables';
+
+@use 'sass:meta';
+@use 'variables';
+
+@function custom-property-name($name) {
+ @return '--' + $name;
+}
+
+@mixin define-custom-property($name, $value) {
+ #{custom-property-name($name)}: meta.inspect($value);
+}
+
+:root {
+ // Make vendor variables accessible to JS/TS code via CSS custom property definition.
+ @each $key_name, $value in meta.module-variables('variables') {
+ @if type-of($value) != 'map' {
+ @include define-custom-property($key_name, $value);
+ }
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/vendor/_style-overrides.scss b/src/pybind/mgr/dashboard/frontend/src/styles/vendor/_style-overrides.scss
new file mode 100644
index 000000000..2fbea9824
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/vendor/_style-overrides.scss
@@ -0,0 +1,4 @@
+/* Vendor specific scss
+
+Custom styles, third-party libraries, frameworks, design systems, ...
+*/
diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/vendor/_variables.scss b/src/pybind/mgr/dashboard/frontend/src/styles/vendor/_variables.scss
new file mode 100644
index 000000000..1df7a9084
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/styles/vendor/_variables.scss
@@ -0,0 +1,17 @@
+/* Vendor specific variables
+
+Example:
+$my-accent-color: #a18fff
+*/
+
+/* Bootstrap variables that are already defined can be overridden using configuration:
+https://sass-lang.com/documentation/at-rules/forward#configuring-modules
+
+Example:
+@forward '../defaults/bootstrap-defaults' with (
+ $theme-colors: (
+ 'accent': $my-accent-color
+ )
+);
+*/
+@forward '../defaults/bootstrap-defaults';
diff --git a/src/pybind/mgr/dashboard/frontend/src/testing/activated-route-stub.ts b/src/pybind/mgr/dashboard/frontend/src/testing/activated-route-stub.ts
new file mode 100644
index 000000000..e21783860
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/testing/activated-route-stub.ts
@@ -0,0 +1,26 @@
+import { ActivatedRoute } from '@angular/router';
+
+import { ReplaySubject } from 'rxjs';
+
+/**
+ * An ActivateRoute test double with a `params` observable.
+ * Use the `setParams()` method to add the next `params` value.
+ */
+export class ActivatedRouteStub extends ActivatedRoute {
+ // Use a ReplaySubject to share previous values with subscribers
+ // and pump new values into the `params` observable
+ private subject = new ReplaySubject<object>();
+
+ constructor(initialParams?: object) {
+ super();
+ this.setParams(initialParams);
+ }
+
+ /** The mock params observable */
+ readonly params = this.subject.asObservable();
+
+ /** Set the params observables's next value */
+ setParams(params?: object) {
+ this.subject.next(params);
+ }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/testing/unit-test-helper.ts b/src/pybind/mgr/dashboard/frontend/src/testing/unit-test-helper.ts
new file mode 100644
index 000000000..66033f033
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/testing/unit-test-helper.ts
@@ -0,0 +1,692 @@
+import { DebugElement, Type } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { AbstractControl } from '@angular/forms';
+import { By } from '@angular/platform-browser';
+import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
+
+import { NgbModal, NgbNav, NgbNavItem } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { configureTestSuite } from 'ng-bullet';
+import { of } from 'rxjs';
+
+import { InventoryDevice } from '~/app/ceph/cluster/inventory/inventory-devices/inventory-device.model';
+import { Pool } from '~/app/ceph/pool/pool';
+import { RgwDaemon } from '~/app/ceph/rgw/models/rgw-daemon';
+import { OrchestratorService } from '~/app/shared/api/orchestrator.service';
+import { RgwDaemonService } from '~/app/shared/api/rgw-daemon.service';
+import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdTableAction } from '~/app/shared/models/cd-table-action';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { CrushNode } from '~/app/shared/models/crush-node';
+import { CrushRule, CrushRuleConfig } from '~/app/shared/models/crush-rule';
+import { OrchestratorFeature } from '~/app/shared/models/orchestrator.enum';
+import { Permission } from '~/app/shared/models/permissions';
+import {
+ AlertmanagerAlert,
+ AlertmanagerNotification,
+ AlertmanagerNotificationAlert,
+ PrometheusRule
+} from '~/app/shared/models/prometheus-alerts';
+
+export function configureTestBed(configuration: any, entryComponents?: any) {
+ configureTestSuite(() => {
+ if (entryComponents) {
+ // Declare entryComponents without having to add them to a module
+ // This is needed since Jest doesn't yet support not declaring entryComponents
+ TestBed.configureTestingModule(configuration).overrideModule(BrowserDynamicTestingModule, {
+ set: { entryComponents: entryComponents }
+ });
+ } else {
+ TestBed.configureTestingModule(configuration);
+ }
+ });
+}
+
+export class PermissionHelper {
+ tac: TableActionsComponent;
+ permission: Permission;
+ selection: { single: object; multiple: object[] };
+
+ /**
+ * @param permission The permissions used by this test.
+ * @param selection The selection used by this test. Configure this if
+ * the table actions require a more complex selection object to perform
+ * a correct test run.
+ * Defaults to `{ single: {}, multiple: [{}, {}] }`.
+ */
+ constructor(permission: Permission, selection?: { single: object; multiple: object[] }) {
+ this.permission = permission;
+ this.selection = _.defaultTo(selection, { single: {}, multiple: [{}, {}] });
+ }
+
+ setPermissionsAndGetActions(tableActions: CdTableAction[]): any {
+ const result = {};
+ [true, false].forEach((create) => {
+ [true, false].forEach((update) => {
+ [true, false].forEach((deleteP) => {
+ this.permission.create = create;
+ this.permission.update = update;
+ this.permission.delete = deleteP;
+
+ this.tac = new TableActionsComponent();
+ this.tac.selection = new CdTableSelection();
+ this.tac.tableActions = [...tableActions];
+ this.tac.permission = this.permission;
+ this.tac.ngOnInit();
+
+ const perms = [];
+ if (create) {
+ perms.push('create');
+ }
+ if (update) {
+ perms.push('update');
+ }
+ if (deleteP) {
+ perms.push('delete');
+ }
+ const permissionText = perms.join(',');
+
+ result[permissionText !== '' ? permissionText : 'no-permissions'] = {
+ actions: this.tac.tableActions.map((action) => action.name),
+ primary: this.testScenarios()
+ };
+ });
+ });
+ });
+
+ return result;
+ }
+
+ testScenarios() {
+ const result: any = {};
+ // 'multiple selections'
+ result.multiple = this.testScenario(this.selection.multiple);
+ // 'select executing item'
+ result.executing = this.testScenario([
+ _.merge({ cdExecuting: 'someAction' }, this.selection.single)
+ ]);
+ // 'select non-executing item'
+ result.single = this.testScenario([this.selection.single]);
+ // 'no selection'
+ result.no = this.testScenario([]);
+
+ return result;
+ }
+
+ private testScenario(selection: object[]) {
+ this.setSelection(selection);
+ const action: CdTableAction = this.tac.currentAction;
+ return action ? action.name : '';
+ }
+
+ setSelection(selection: object[]) {
+ this.tac.selection.selected = selection;
+ this.tac.onSelectionChange();
+ }
+}
+
+export class FormHelper {
+ form: CdFormGroup;
+
+ constructor(form: CdFormGroup) {
+ this.form = form;
+ }
+
+ /**
+ * Changes multiple values in multiple controls
+ */
+ setMultipleValues(values: { [controlName: string]: any }, markAsDirty?: boolean) {
+ Object.keys(values).forEach((key) => {
+ this.setValue(key, values[key], markAsDirty);
+ });
+ }
+
+ /**
+ * Changes the value of a control
+ */
+ setValue(control: AbstractControl | string, value: any, markAsDirty?: boolean): AbstractControl {
+ control = this.getControl(control);
+ if (markAsDirty) {
+ control.markAsDirty();
+ }
+ control.setValue(value);
+ return control;
+ }
+
+ private getControl(control: AbstractControl | string): AbstractControl {
+ if (typeof control === 'string') {
+ return this.form.get(control);
+ }
+ return control;
+ }
+
+ /**
+ * Change the value of the control and expect the control to be valid afterwards.
+ */
+ expectValidChange(control: AbstractControl | string, value: any, markAsDirty?: boolean) {
+ this.expectValid(this.setValue(control, value, markAsDirty));
+ }
+
+ /**
+ * Expect that the given control is valid.
+ */
+ expectValid(control: AbstractControl | string) {
+ // 'isValid' would be false for disabled controls
+ expect(this.getControl(control).errors).toBe(null);
+ }
+
+ /**
+ * Change the value of the control and expect a specific error.
+ */
+ expectErrorChange(
+ control: AbstractControl | string,
+ value: any,
+ error: string,
+ markAsDirty?: boolean
+ ) {
+ this.expectError(this.setValue(control, value, markAsDirty), error);
+ }
+
+ /**
+ * Expect a specific error for the given control.
+ */
+ expectError(control: AbstractControl | string, error: string) {
+ expect(this.getControl(control).hasError(error)).toBeTruthy();
+ }
+}
+
+/**
+ * Use this to mock 'modalService.open' to make the embedded component with it's fixture usable
+ * in tests. The function gives back all needed parts including the modal reference.
+ *
+ * Please make sure to call this function *inside* your mock and return the reference at the end.
+ */
+export function modalServiceShow(componentClass: Type<any>, modalConfig: any) {
+ const modal: NgbModal = TestBed.inject(NgbModal);
+ const modalRef = modal.open(componentClass);
+ if (modalConfig) {
+ Object.assign(modalRef.componentInstance, modalConfig);
+ }
+ return modalRef;
+}
+
+export class FixtureHelper {
+ fixture: ComponentFixture<any>;
+
+ constructor(fixture?: ComponentFixture<any>) {
+ if (fixture) {
+ this.updateFixture(fixture);
+ }
+ }
+
+ updateFixture(fixture: ComponentFixture<any>) {
+ this.fixture = fixture;
+ }
+
+ /**
+ * Expect a list of id elements to be visible or not.
+ */
+ expectIdElementsVisible(ids: string[], visibility: boolean) {
+ ids.forEach((css) => {
+ this.expectElementVisible(`#${css}`, visibility);
+ });
+ }
+
+ /**
+ * Expect a specific element to be visible or not.
+ */
+ expectElementVisible(css: string, visibility: boolean) {
+ expect(visibility).toBe(Boolean(this.getElementByCss(css)));
+ }
+
+ expectFormFieldToBe(css: string, value: string) {
+ const props = this.getElementByCss(css).properties;
+ expect(props['value'] || props['checked'].toString()).toBe(value);
+ }
+
+ expectTextToBe(css: string, value: string) {
+ expect(this.getText(css)).toBe(value);
+ }
+
+ clickElement(css: string) {
+ this.getElementByCss(css).triggerEventHandler('click', null);
+ this.fixture.detectChanges();
+ }
+
+ selectElement(css: string, value: string) {
+ const nativeElement = this.getElementByCss(css).nativeElement;
+ nativeElement.value = value;
+ nativeElement.dispatchEvent(new Event('change'));
+ this.fixture.detectChanges();
+ }
+
+ getText(css: string) {
+ const e = this.getElementByCss(css);
+ return e ? e.nativeElement.textContent.trim() : null;
+ }
+
+ getTextAll(css: string) {
+ const elements = this.getElementByCssAll(css);
+ return elements.map((element) => {
+ return element ? element.nativeElement.textContent.trim() : null;
+ });
+ }
+
+ getElementByCss(css: string) {
+ this.fixture.detectChanges();
+ return this.fixture.debugElement.query(By.css(css));
+ }
+
+ getElementByCssAll(css: string) {
+ this.fixture.detectChanges();
+ return this.fixture.debugElement.queryAll(By.css(css));
+ }
+}
+
+export class PrometheusHelper {
+ createSilence(id: string) {
+ return {
+ id: id,
+ createdBy: `Creator of ${id}`,
+ comment: `A comment for ${id}`,
+ startsAt: new Date('2022-02-22T22:22:00').toISOString(),
+ endsAt: new Date('2022-02-23T22:22:00').toISOString(),
+ matchers: [
+ {
+ name: 'job',
+ value: 'someJob',
+ isRegex: true
+ }
+ ]
+ };
+ }
+
+ createRule(name: string, severity: string, alerts: any[]): PrometheusRule {
+ return {
+ name: name,
+ labels: {
+ severity: severity
+ },
+ alerts: alerts
+ } as PrometheusRule;
+ }
+
+ createAlert(name: string, state = 'active', timeMultiplier = 1): AlertmanagerAlert {
+ return {
+ fingerprint: name,
+ status: { state },
+ labels: {
+ alertname: name,
+ instance: 'someInstance',
+ job: 'someJob',
+ severity: 'someSeverity'
+ },
+ annotations: {
+ description: `${name} is ${state}`
+ },
+ generatorURL: `http://${name}`,
+ startsAt: new Date(new Date('2022-02-22').getTime() * timeMultiplier).toString()
+ } as AlertmanagerAlert;
+ }
+
+ createNotificationAlert(name: string, status = 'firing'): AlertmanagerNotificationAlert {
+ return {
+ status: status,
+ labels: {
+ alertname: name
+ },
+ annotations: {
+ description: `${name} is ${status}`
+ },
+ generatorURL: `http://${name}`
+ } as AlertmanagerNotificationAlert;
+ }
+
+ createNotification(alertNumber = 1, status = 'firing'): AlertmanagerNotification {
+ const alerts = [];
+ for (let i = 0; i < alertNumber; i++) {
+ alerts.push(this.createNotificationAlert('alert' + i, status));
+ }
+ return { alerts, status } as AlertmanagerNotification;
+ }
+
+ createLink(url: string) {
+ return `<a href="${url}" target="_blank"><i class="${Icons.lineChart}"></i></a>`;
+ }
+}
+
+export function expectItemTasks(item: any, executing: string, percentage?: number) {
+ if (executing) {
+ executing = executing + '...';
+ if (percentage) {
+ executing = `${executing} ${percentage}%`;
+ }
+ }
+ expect(item.cdExecuting).toBe(executing);
+}
+
+export class IscsiHelper {
+ static validateUser(formHelper: FormHelper, fieldName: string) {
+ formHelper.expectErrorChange(fieldName, 'short', 'pattern');
+ formHelper.expectValidChange(fieldName, 'thisIsCorrect');
+ formHelper.expectErrorChange(fieldName, '##?badChars?##', 'pattern');
+ formHelper.expectErrorChange(
+ fieldName,
+ 'thisUsernameIsWayyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyTooBig',
+ 'pattern'
+ );
+ }
+
+ static validatePassword(formHelper: FormHelper, fieldName: string) {
+ formHelper.expectErrorChange(fieldName, 'short', 'pattern');
+ formHelper.expectValidChange(fieldName, 'thisIsCorrect');
+ formHelper.expectErrorChange(fieldName, '##?badChars?##', 'pattern');
+ formHelper.expectErrorChange(fieldName, 'thisPasswordIsWayTooBig', 'pattern');
+ }
+}
+
+export class RgwHelper {
+ static readonly daemons = RgwHelper.getDaemonList();
+ static readonly DAEMON_QUERY_PARAM = `daemon_name=${RgwHelper.daemons[0].id}`;
+
+ static getDaemonList() {
+ const daemonList: RgwDaemon[] = [];
+ for (let daemonIndex = 1; daemonIndex <= 3; daemonIndex++) {
+ const rgwDaemon = new RgwDaemon();
+ rgwDaemon.id = `daemon${daemonIndex}`;
+ rgwDaemon.default = daemonIndex === 2;
+ rgwDaemon.zonegroup_name = `zonegroup${daemonIndex}`;
+ daemonList.push(rgwDaemon);
+ }
+ return daemonList;
+ }
+
+ static selectDaemon() {
+ const service = TestBed.inject(RgwDaemonService);
+ service.selectDaemon(this.daemons[0]);
+ }
+}
+
+export class Mocks {
+ static getCrushNode(
+ name: string,
+ id: number,
+ type: string,
+ type_id: number,
+ children?: number[],
+ device_class?: string
+ ): CrushNode {
+ return { name, type, type_id, id, children, device_class };
+ }
+
+ static getPool = (name: string, id: number): Pool => {
+ return _.merge(new Pool(name), {
+ pool: id,
+ type: 'replicated',
+ pg_num: 256,
+ pg_placement_num: 256,
+ pg_num_target: 256,
+ pg_placement_num_target: 256,
+ size: 3
+ });
+ };
+
+ /**
+ * Create the following test crush map:
+ * > default
+ * --> ssd-host
+ * ----> 3x osd with ssd
+ * --> mix-host
+ * ----> hdd-rack
+ * ------> 2x osd-rack with hdd
+ * ----> ssd-rack
+ * ------> 2x osd-rack with ssd
+ */
+ static getCrushMap(): CrushNode[] {
+ return [
+ // Root node
+ this.getCrushNode('default', -1, 'root', 11, [-2, -3]),
+ // SSD host
+ this.getCrushNode('ssd-host', -2, 'host', 1, [1, 0, 2]),
+ this.getCrushNode('osd.0', 0, 'osd', 0, undefined, 'ssd'),
+ this.getCrushNode('osd.1', 1, 'osd', 0, undefined, 'ssd'),
+ this.getCrushNode('osd.2', 2, 'osd', 0, undefined, 'ssd'),
+ // SSD and HDD mixed devices host
+ this.getCrushNode('mix-host', -3, 'host', 1, [-4, -5]),
+ // HDD rack
+ this.getCrushNode('hdd-rack', -4, 'rack', 3, [3, 4]),
+ this.getCrushNode('osd2.0', 3, 'osd-rack', 0, undefined, 'hdd'),
+ this.getCrushNode('osd2.1', 4, 'osd-rack', 0, undefined, 'hdd'),
+ // SSD rack
+ this.getCrushNode('ssd-rack', -5, 'rack', 3, [5, 6]),
+ this.getCrushNode('osd3.0', 5, 'osd-rack', 0, undefined, 'ssd'),
+ this.getCrushNode('osd3.1', 6, 'osd-rack', 0, undefined, 'ssd')
+ ];
+ }
+
+ /**
+ * Generates an simple crush map with multiple hosts that have OSDs with either ssd or hdd OSDs.
+ * Hosts with zero or even numbers at the end have SSD OSDs the other hosts have hdd OSDs.
+ *
+ * Host names follow the following naming convention:
+ * host.$index
+ * $index represents a number count started at 0 (like an index within an array) (same for OSDs)
+ *
+ * OSD names follow the following naming convention:
+ * osd.$hostIndex.$osdIndex
+ *
+ * The following crush map will be generated with the set defaults:
+ * > default
+ * --> host.0 (has only ssd OSDs)
+ * ----> osd.0.0
+ * ----> osd.0.1
+ * ----> osd.0.2
+ * ----> osd.0.3
+ * --> host.1 (has only hdd OSDs)
+ * ----> osd.1.0
+ * ----> osd.1.1
+ * ----> osd.1.2
+ * ----> osd.1.3
+ */
+ static generateSimpleCrushMap(hosts: number = 2, osds: number = 4): CrushNode[] {
+ const nodes = [];
+ const createOsdLeafs = (hostSuffix: number): number[] => {
+ let osdId = 0;
+ const osdIds = [];
+ const osdsInUse = hostSuffix * osds;
+ for (let o = 0; o < osds; o++) {
+ osdIds.push(osdId);
+ nodes.push(
+ this.getCrushNode(
+ `osd.${hostSuffix}.${osdId}`,
+ osdId + osdsInUse,
+ 'osd',
+ 0,
+ undefined,
+ hostSuffix % 2 === 0 ? 'ssd' : 'hdd'
+ )
+ );
+ osdId++;
+ }
+ return osdIds;
+ };
+ const createHostBuckets = (): number[] => {
+ let hostId = -2;
+ const hostIds = [];
+ for (let h = 0; h < hosts; h++) {
+ const hostSuffix = hostId * -1 - 2;
+ hostIds.push(hostId);
+ nodes.push(
+ this.getCrushNode(`host.${hostSuffix}`, hostId, 'host', 1, createOsdLeafs(hostSuffix))
+ );
+ hostId--;
+ }
+ return hostIds;
+ };
+ nodes.push(this.getCrushNode('default', -1, 'root', 11, createHostBuckets()));
+ return nodes;
+ }
+
+ static getCrushRuleConfig(
+ name: string,
+ root: string,
+ failure_domain: string,
+ device_class?: string
+ ): CrushRuleConfig {
+ return {
+ name,
+ root,
+ failure_domain,
+ device_class
+ };
+ }
+
+ static getCrushRule({
+ id = 0,
+ name = 'somePoolName',
+ min = 1,
+ max = 10,
+ type = 'replicated',
+ failureDomain = 'osd',
+ itemName = 'default' // This string also sets the device type - "default~ssd" <- ssd usage only
+ }: {
+ max?: number;
+ min?: number;
+ id?: number;
+ name?: string;
+ type?: string;
+ failureDomain?: string;
+ itemName?: string;
+ }): CrushRule {
+ const typeNumber = type === 'erasure' ? 3 : 1;
+ const rule = new CrushRule();
+ rule.max_size = max;
+ rule.min_size = min;
+ rule.rule_id = id;
+ rule.ruleset = typeNumber;
+ rule.rule_name = name;
+ rule.steps = [
+ {
+ item_name: itemName,
+ item: -1,
+ op: 'take'
+ },
+ {
+ num: 0,
+ type: failureDomain,
+ op: 'choose_firstn'
+ },
+ {
+ op: 'emit'
+ }
+ ];
+ return rule;
+ }
+
+ static getInventoryDevice(
+ hostname: string,
+ uid: string,
+ path = 'sda',
+ available = false
+ ): InventoryDevice {
+ return {
+ hostname,
+ uid,
+ path,
+ available,
+ sys_api: {
+ vendor: 'AAA',
+ model: 'aaa',
+ size: 1024,
+ rotational: 'false',
+ human_readable_size: '1 KB'
+ },
+ rejected_reasons: [''],
+ device_id: 'AAA-aaa-id0',
+ human_readable_type: 'nvme/ssd',
+ osd_ids: []
+ };
+ }
+}
+
+export class TabHelper {
+ static getNgbNav(fixture: ComponentFixture<any>) {
+ const debugElem: DebugElement = fixture.debugElement;
+ return debugElem.query(By.directive(NgbNav)).injector.get(NgbNav);
+ }
+
+ static getNgbNavItems(fixture: ComponentFixture<any>) {
+ const debugElems = this.getNgbNavItemsDebugElems(fixture);
+ return debugElems.map((de) => de.injector.get(NgbNavItem));
+ }
+
+ static getTextContents(fixture: ComponentFixture<any>) {
+ const debugElems = this.getNgbNavItemsDebugElems(fixture);
+ return debugElems.map((de) => de.nativeElement.textContent);
+ }
+
+ private static getNgbNavItemsDebugElems(fixture: ComponentFixture<any>) {
+ const debugElem: DebugElement = fixture.debugElement;
+ return debugElem.queryAll(By.directive(NgbNavItem));
+ }
+}
+
+export class OrchestratorHelper {
+ /**
+ * Mock Orchestrator status.
+ * @param available is the Orchestrator enabled?
+ * @param features A list of enabled Orchestrator features.
+ */
+ static mockStatus(available: boolean, features?: OrchestratorFeature[]) {
+ const orchStatus = { available: available, description: '', features: {} };
+ if (features) {
+ features.forEach((feature: OrchestratorFeature) => {
+ orchStatus.features[feature] = { available: true };
+ });
+ }
+ spyOn(TestBed.inject(OrchestratorService), 'status').and.callFake(() => of(orchStatus));
+ }
+}
+
+export class TableActionHelper {
+ /**
+ * Verify table action buttons, including the button disabled state and disable description.
+ *
+ * @param fixture test fixture
+ * @param tableActions table actions
+ * @param expectResult expected values. e.g. {Create: { disabled: true, disableDesc: 'not supported'}}.
+ * Expect the Create button to be disabled with 'not supported' tooltip.
+ */
+ static verifyTableActions = async (
+ fixture: ComponentFixture<any>,
+ tableActions: CdTableAction[],
+ expectResult: {
+ [action: string]: { disabled: boolean; disableDesc: string };
+ }
+ ) => {
+ // click dropdown to update all actions buttons
+ const dropDownToggle = fixture.debugElement.query(By.css('.dropdown-toggle'));
+ dropDownToggle.triggerEventHandler('click', null);
+ fixture.detectChanges();
+ await fixture.whenStable();
+
+ const tableActionElement = fixture.debugElement.query(By.directive(TableActionsComponent));
+ const toClassName = TestBed.inject(TableActionsComponent).toClassName;
+ const getActionElement = (action: CdTableAction) =>
+ tableActionElement.query(By.css(`[ngbDropdownItem].${toClassName(action)}`));
+
+ const actions = {};
+ tableActions.forEach((action) => {
+ const actionElement = getActionElement(action);
+ if (expectResult[action.name]) {
+ actions[action.name] = {
+ disabled: actionElement.classes.disabled,
+ disableDesc: actionElement.properties.title
+ };
+ }
+ });
+ expect(actions).toEqual(expectResult);
+ };
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/typings.d.ts b/src/pybind/mgr/dashboard/frontend/src/typings.d.ts
new file mode 100644
index 000000000..ef5c7bd62
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/typings.d.ts
@@ -0,0 +1,5 @@
+/* SystemJS module definition */
+declare var module: NodeModule;
+interface NodeModule {
+ id: string;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/tsconfig.app.json b/src/pybind/mgr/dashboard/frontend/tsconfig.app.json
new file mode 100644
index 000000000..f758d9820
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./out-tsc/app",
+ "types": []
+ },
+ "files": [
+ "src/main.ts",
+ "src/polyfills.ts"
+ ],
+ "include": [
+ "src/**/*.d.ts"
+ ]
+}
diff --git a/src/pybind/mgr/dashboard/frontend/tsconfig.json b/src/pybind/mgr/dashboard/frontend/tsconfig.json
new file mode 100644
index 000000000..218cffda9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/tsconfig.json
@@ -0,0 +1,42 @@
+{
+ "compileOnSave": false,
+ "compilerOptions": {
+ "downlevelIteration": true,
+ "esModuleInterop": true,
+ "importHelpers": true,
+ "outDir": "./dist/out-tsc",
+ "sourceMap": true,
+ "declaration": false,
+ "moduleResolution": "node",
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+ "noImplicitThis": true,
+ "noImplicitReturns": true,
+ "noImplicitAny": true,
+ "suppressImplicitAnyIndexErrors": true,
+ "target": "es2015",
+ "module": "es2020",
+ "baseUrl": "./",
+ "paths": {
+ "~/*": ["src/*"]
+ },
+ "typeRoots": [
+ "node_modules/@types"
+ ],
+ "lib": [
+ "es2017",
+ "dom"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true
+ },
+ "exclude": [
+ "coverage",
+ "dist",
+ "node_modules",
+ "cypress"
+ ]
+}
diff --git a/src/pybind/mgr/dashboard/frontend/tsconfig.spec.json b/src/pybind/mgr/dashboard/frontend/tsconfig.spec.json
new file mode 100644
index 000000000..e1889d6c6
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/tsconfig.spec.json
@@ -0,0 +1,21 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./out-tsc/spec",
+ "module": "commonjs",
+ "target": "es2015",
+ "types": [
+ "jest",
+ "node"
+ ],
+ "noEmit": true
+ },
+ "files": [
+ "src/polyfills.ts"
+ ],
+ "include": [
+ "src/**/*.spec.ts",
+ "src/**/*.d.ts",
+ "src/testing/*.ts"
+ ]
+}
diff --git a/src/pybind/mgr/dashboard/frontend/tslint.json b/src/pybind/mgr/dashboard/frontend/tslint.json
new file mode 100644
index 000000000..2911ef2c5
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/tslint.json
@@ -0,0 +1,118 @@
+{
+ "rulesDirectory": ["node_modules/codelyzer"],
+ "rules": {
+ "no-consecutive-blank-lines": true,
+ "arrow-return-shorthand": true,
+ "callable-types": true,
+ "class-name": true,
+ "comment-format": [true, "check-space"],
+ "curly": true,
+ "deprecation": {
+ "severity": "error"
+ },
+ "eofline": true,
+ "forin": true,
+ "import-blacklist": [true,
+ "rxjs/Rx",
+ {"@angular/core/testing": ["async"]},
+ ["(\\.{1,2}\/){2,}"] // e.g import ../../foobar
+ ],
+ "import-spacing": true,
+ "indent": [true, "spaces"],
+ "interface-over-type-literal": true,
+ "label-position": true,
+ "member-access": false,
+ "member-ordering": [
+ true,
+ {
+ "order": ["static-field", "instance-field", "static-method", "instance-method"]
+ }
+ ],
+ "no-arg": true,
+ "no-bitwise": true,
+ "no-console": [true, "debug", "info", "time", "timeEnd", "trace"],
+ "no-construct": true,
+ "no-debugger": true,
+ "no-duplicate-super": true,
+ "no-duplicate-imports": [true, { "allow-namespace-imports": true }],
+ "no-empty": [true, "allow-empty-catch"],
+ "no-empty-interface": true,
+ "no-eval": true,
+ "no-inferrable-types": [true, "ignore-params"],
+ "no-misused-new": true,
+ "no-non-null-assertion": true,
+ "no-shadowed-variable": true,
+ "no-string-literal": false,
+ "no-string-throw": true,
+ "no-switch-case-fall-through": true,
+ "no-trailing-whitespace": true,
+ "no-unnecessary-initializer": true,
+ "no-unused-expression": true,
+ "no-var-keyword": true,
+ "object-literal-sort-keys": false,
+ "one-line": [true, "check-open-brace", "check-catch", "check-else", "check-whitespace"],
+ "prefer-const": true,
+ "quotemark": [true, "single"],
+ "radix": true,
+ "triple-equals": [true, "allow-null-check"],
+ "typedef-whitespace": [
+ true,
+ {
+ "call-signature": "nospace",
+ "index-signature": "nospace",
+ "parameter": "nospace",
+ "property-declaration": "nospace",
+ "variable-declaration": "nospace"
+ }
+ ],
+ "unified-signatures": true,
+ "variable-name": [true, "check-format", "allow-snake-case", "allow-leading-underscore"],
+ "whitespace": [
+ true,
+ "check-branch",
+ "check-operator",
+ "check-separator",
+ "check-type",
+ "check-module"
+ ],
+ "directive-selector": [true, "attribute", "cd", "camelCase"],
+ "component-selector": [true, "element", "cd", "kebab-case"],
+ "no-output-on-prefix": true,
+ "no-inputs-metadata-property": true,
+ "no-outputs-metadata-property": true,
+ "no-host-metadata-property": true,
+ "no-attribute-decorator": true,
+ "no-input-rename": true,
+ "no-output-rename": true,
+ "use-lifecycle-interface": true,
+ "use-pipe-transform-interface": true,
+ "component-class-suffix": true,
+ "directive-class-suffix": true,
+ "no-forward-ref": true,
+ "no-output-native": true,
+ "ordered-imports": [
+ true,
+ {
+ "grouped-imports": true,
+ "groups": [
+ {
+ "name": "angular",
+ "match": "^@angular",
+ "order": 1
+ },
+ {
+ "name": "relative dir",
+ "match": "^(\\.|\\.\\.|~)/.*",
+ "order": 3
+ },
+ {
+ "name": "node_modules",
+ "match": ".*",
+ "order": 2
+ }
+ ]
+ }
+ ]
+ },
+ "jsRules": { "no-empty": true }
+}